Run it
Copy the script and paste it into your executor.
Svc={Pl=:(),UIS=:(),SS=:(),RS=:(),TS=:(),RepS=:(),WS=:(),MPS=:(),HS=:(),Deb=:()}
player=Svc.Pl.LocalPlayer; pGui=player:()
C={BG=.(,,),CARD_HI=.(,,),CARD_LO=.(,,),SURFACE=.(,,),ELEVATED=.(,,),BORDER=.(,,),BORDER_LIT=.(,,),ACCENT=.(,,),ACCENT_DIM=.(,,),TEXT=.(,,),TEXT2=.(,,),TEXT3=.(,,),SUCCESS=.(,,),DANGER=.(,,),HANDLE=.(,,)}
AT=.(,,)
Cfg={workspacePath=,configsPath=,categoriesPath=,soundIdsPath=,AUTO_SCAN_INTERVAL=,CROSSFADE_TIME=,CROSSFADE_TRIGGER=,TRACK_SWITCH_COOLDOWN=,CARD_WIDTH=,BASE_HEIGHT=,REVERB_EXTRA_HEIGHT=,LIST_WIDTH=,SLIDER_MIN=,SLIDER_MAX=,SNAP_VALUE=,SNAP_THRESHOLD=,SOUND_ID_CATEGORY_ID=,SOUND_ID_CATEGORY_NAME=,ORDER_PATH=,SETTINGS_PATH=,DNPATH=,SHOH=,TRH=,TPCH=,LG=,RH=,RG=,FLAGGED_PATH=}
St={currentVolume=,currentSpeed=,currentIncrement=,crossfadeEnabled=,repeatEnabled=,shuffleEnabled=,screenShakeEnabled=,lyricsEnabled=,currentTrackIndex=,isPaused=,lastTrackSwitchTime=,showingSettings=,guiOpen=,animating=,draggingWindow=,draggingProgress=,wasPlayingBeforeDrag=,listPanelOpen=,queuePanelOpen=,capturingKeybind=,isShowingNotification=,lastDisplayedTime=,draggedButton=,isDraggingToQueue=,draggedTrackIndex=,isDraggingToCategory=,categoryBeingRenamed=,expandedCategories={},selectingCategoryForTrack=,pendingTrackIndexForCategory=,hoveredCategoryIndex=,shakeIntensity=,fovIntensity=,hoveredTrackIndex=,hoveredTrackInCategory=,pendingDeleteTrackIndex=,crossfadeTriggered=,settingsActiveTab=,searchQuery=,searchActive=,notifVolume=,muteGameSounds=,pendingRenameSoundIdIndex=,scResults={},scIdx=,scBusy=,scGen=,scArtGen=,scCid=,translateEnabled=,cinematicMode=,kbPrev=.KeyCode.F6,kbPlay=.KeyCode.F7,kbNext=.KeyCode.F8,kbRepeat=,kbShuffle=,kbLyrics=,kbTranslate=,kbMute=,kbCinematic=}
Dat={trackList={},createdSounds={},queueList={},lastMp3Files={},notificationQueue={},categories={},meterBars={},soundEndedConnection=,currentTrackAnimationTween=,dragStart=,startPos=,trackOrderList={},listButtonRefs={},suppressAutoNotify={},crossfadingSounds={},activeFadeOutTween=,crossfadeCleanupGen=,currentLyrics={},lyricsFetchGen=,lastLyricIndex=-,permanentlyDeleted={},eolFired=,smoothShakeLoud=,fovLockedVal=,fovBaseline=,fovSmooth=,muteConns={},muteDescConn=,toastBarTween=,translateCache={},translatePending={},prevTrackIndex=}
UI={}
shakeVal=Svc.RepS:() .()
shakeVal.Name=;shakeVal.Value=;shakeVal.Parent=Svc.RepS;St.screenShakeEnabled=
kbVal=Svc.RepS:()
kbVal kbVal=.();kbVal.Name=;kbVal.Value=;kbVal.Parent=Svc.RepS
(n) _,k (.KeyCode:()) k.Name==n k
curKC=(kbVal.Value) .KeyCode.N
kbVal.Changed:((v) k=(v); k curKC=k )
_,n ({,,}) x=pGui:(n); x x:()
.__MCMuteCleanup (.__MCMuteCleanup);.__MCMuteCleanup=
(() f=Svc.SS:(); f _,s (f:()) s:() s:() ;f:() )
displayNamesMap=Dat.displayNamesMap {}
() (Cfg.DNPATH) ok,r=(() Svc.HS:((Cfg.DNPATH)) ); ok r displayNamesMap=r
() (Cfg.configsPath) (Cfg.configsPath) ;(() (Cfg.DNPATH,Svc.HS:(displayNamesMap)) )
flaggedInstrumental={}; () (Cfg.FLAGGED_PATH) ok,r=(() Svc.HS:((Cfg.FLAGGED_PATH)) ); ok (r)== flaggedInstrumental=r ; () (Cfg.configsPath) (Cfg.configsPath) ;(() (Cfg.FLAGGED_PATH,Svc.HS:(flaggedInstrumental)) )
()
(Cfg.configsPath) (Cfg.configsPath)
(k) St[k] St[k].Name
d={volume=St.currentVolume,speed=St.currentSpeed,increment=St.currentIncrement,crossfade=St.crossfadeEnabled,repeat_=St.repeatEnabled,shuffle=St.shuffleEnabled,shakeIntensity=St.shakeIntensity,fovIntensity=St.fovIntensity,notifVolume=St.notifVolume,mute=St.muteGameSounds,translate=St.translateEnabled,kbPrev=(),kbPlay=(),kbNext=(),kbRepeat=(),kbShuffle=(),kbLyrics=(),kbTranslate=(),kbMute=(),kbCinematic=()}
(() (Cfg.SETTINGS_PATH,Svc.HS:(d)) )
()
(Cfg.SETTINGS_PATH)
ok,d=(() Svc.HS:((Cfg.SETTINGS_PATH)) )
ok d
(d.volume)== St.currentVolume=d.volume ; (d.speed)== St.currentSpeed=d.speed
(d.increment)== St.currentIncrement=d.increment ; (d.crossfade)== St.crossfadeEnabled=d.crossfade
(d.repeat_)== St.repeatEnabled=d.repeat_ ; (d.shuffle)== St.shuffleEnabled=d.shuffle
(d.shakeIntensity)== St.shakeIntensity=d.shakeIntensity
(d.fovIntensity)== St.fovIntensity=d.fovIntensity
(d.notifVolume)== St.notifVolume=d.notifVolume ; (d.mute)== St.muteGameSounds=d.mute
(d.translate)== St.translateEnabled=d.translate
(k,def) (d[k])== kc=.KeyCode:(); _,e (kc) e.Name==d[k] St[k]=e; ;St[k]=def
(,.KeyCode.F6);(,.KeyCode.F7);(,.KeyCode.F8)
(,);(,);(,);(,);(,);(,)
(displayName)
safe=displayName:(,);safe=safe:(,):()
#safe== hex=; i=,#displayName hex=hex..string.(,displayName:(i)) ;safe=..hex:(,) ; safe
(diskBaseName) displayNamesMap[diskBaseName] diskBaseName
() () () ; (Cfg.workspacePath) (Cfg.workspacePath);(Cfg.workspacePath..,)
()
r={}
(Cfg.workspacePath)
_,p ((Cfg.workspacePath))
_np=p:(,); n=_np:() p
n n:():()
Dat.permanentlyDeleted[p]
diskBase=n:(,); displayName=(diskBase)
.(r,{Path=p,Name=displayName,FileName=n,Type=})
; r
(t) t.Type== ..(t.FileName t.DisplayName) ; t.Type== ..(t.SoundId) ; ..(t.DisplayName )
()
seen,clean={},{}
_,cat (Dat.categories)
cat.CategoryID
seen[cat.CategoryID] seen[cat.CategoryID]=cat;.(clean,cat)
ex=seen[cat.CategoryID]; _,tid (cat.TrackTIDs {}) dup=; _,et (ex.TrackTIDs {}) et==tid dup=; ; dup .(ex.TrackTIDs,tid)
.(clean,cat)
Dat.categories=clean; cd={}
_,cat (Dat.categories) .(cd,{Name=cat.Name,TrackTIDs=cat.TrackTIDs {},CategoryID=cat.CategoryID})
(Cfg.configsPath) (Cfg.configsPath) ;(Cfg.categoriesPath,Svc.HS:(cd))
()
tidToIdx={}
i,t (Dat.trackList) tidToIdx[(t)]=i
_,cat (Dat.categories)
cat.TrackTIDs cat.TrackTIDs={}
newTracks={}; seen={}
_,tid (cat.TrackTIDs) idx=tidToIdx[tid]; idx seen[idx] .(newTracks,idx);seen[idx]=
cat.Tracks=newTracks
()
(Cfg.categoriesPath)
ok,r=(() Svc.HS:((Cfg.categoriesPath)) )
ok r
Dat.categories={}; seen={}
_,cd (r)
tids=cd.TrackTIDs {}; cat={Name=cd.Name,Tracks={},TrackTIDs=tids,CategoryID=cd.CategoryID}
cd.CategoryID seen[cd.CategoryID] ex=seen[cd.CategoryID]; _,tid (tids) f=; _,et (ex.TrackTIDs) et==tid f=; ; f .(ex.TrackTIDs,tid)
.(Dat.categories,cat); cd.CategoryID seen[cd.CategoryID]=cat
(); (Cfg.configsPath) (Cfg.configsPath)
(Cfg.soundIdsPath) (() (Cfg.soundIdsPath,) )
(() (Cfg.configsPath) _,f ((Cfg.configsPath)) fn=(f:(,):() ):(); fn:() fn:() (() (f) ) )
();();();()
() (Cfg.configsPath) (Cfg.configsPath) ;(() (Cfg.ORDER_PATH,Svc.HS:(Dat.trackOrderList)) )
() (Cfg.ORDER_PATH) ok,r=(() Svc.HS:((Cfg.ORDER_PATH)) ); ok r Dat.trackOrderList=r
()
us,ul={},{}
i,t (Dat.trackList)
Dat.createdSounds[i]==
inc=; _,cat (Dat.categories) _,idx (cat.Tracks) idx==i inc=; ; inc
inc id=(t);us[id]=i;.(ul,{id=id,index=i,name=(t.DisplayName ):()})
res,placed={},{}
_,id (Dat.trackOrderList) us[id] .(res,us[id]);placed[id]=
chg=
newItems={}
_,item (ul) placed[item.id] .(newItems,item)
.(newItems,(a,b) a.name<b.name )
_,item (newItems)
inserted=
itmName=item.name
pos,id (Dat.trackOrderList)
existing=us[id] Dat.trackList[us[id]]
existing (existing.DisplayName ):()>itmName
.(Dat.trackOrderList,pos,item.id)
.(res,pos,item.index)
inserted=;chg=;
inserted .(res,item.index);.(Dat.trackOrderList,item.id);chg=
co={}
_,id (Dat.trackOrderList) us[id] .(co,id) chg=
Dat.trackOrderList=co; chg () ; res
()
sfHolder=.();sfHolder.Name=;sfHolder.Parent=Svc.SS
soundsFolder=sfHolder; sound=
reverb=.();reverb.Enabled=
distortion=.();distortion.Enabled=
equalizer=.();equalizer.Enabled=
chorus=.();chorus.Enabled=
(e,p,cn) en=;(() en=e.Enabled ); ok=(() e.Parent=p ); ok f=.(cn);f.Enabled=en;f.Parent=p; f ; e
(t) reverb=(reverb,t,);distortion=(distortion,t,);equalizer=(equalizer,t,);chorus=(chorus,t,)
(isRefresh)
mp3s=()
isRefresh
sid={}; i=#Dat.trackList,,- Dat.trackList[i].Type== .(sid,,{track=Dat.trackList[i],sound=Dat.createdSounds[i]})
osp={}; i=,#Dat.createdSounds cs=Dat.createdSounds[i]; cs Dat.trackList[i] Dat.trackList[i].Path osp[Dat.trackList[i].Path]=cs
Dat.createdSounds={};Dat.trackList={}
i,fi (mp3s)
Dat.trackList[i]={Path=fi.Path,DisplayName=fi.Name,FullName=fi.Name,FileName=fi.FileName,Type=}; s=
osp[fi.Path] s=osp[fi.Path];osp[fi.Path]=; s.Parent~=soundsFolder s.Parent=soundsFolder ;s.Volume=St.currentVolume;s.PlaybackSpeed=St.currentSpeed;s.Looped=;Dat.createdSounds[i]=s
ns=.();ns.Name=fi.Name; ok,au=(() (fi.Path,) ); ok au ns.SoundId=au;ns.Volume=St.currentVolume;ns.PlaybackSpeed=St.currentSpeed;ns.Looped=;ns.Parent=soundsFolder;Dat.createdSounds[i]=ns;s=ns (..fi.Name);ns:()
s s.SetAttribute (() s:(,fi.Path) )
_,lo (osp) lo lo.Parent==soundsFolder (() lo:() )
_,d (sid) .(Dat.trackList,d.track);.(Dat.createdSounds,d.sound)
i,fi (mp3s)
Dat.trackList[i]={Path=fi.Path,DisplayName=fi.Name,FullName=fi.Name,FileName=fi.FileName,Type=}
s=.();s.Name=fi.Name; ok,au=(() (fi.Path,) )
ok au s.SoundId=au;s.Volume=St.currentVolume;s.PlaybackSpeed=St.currentSpeed;s.Looped=;s.Parent=soundsFolder;Dat.createdSounds[i]=s (..fi.Name);s:()
Dat.lastMp3Files=mp3s; #Dat.createdSounds>
()
(Cfg.configsPath) (Cfg.configsPath)
d={}; _,t (Dat.trackList) t.Type== .(d,{SoundId=t.SoundId,Name=t.DisplayName})
(() (Cfg.soundIdsPath,Svc.HS:(d)) )
()
(Cfg.soundIdsPath) (() (Cfg.soundIdsPath,) )
ok,r=(() Svc.HS:((Cfg.soundIdsPath)) )
ok r (r)==
seen,ded={},{}
_,e (r) id=(e.SoundId ); id~= seen[id] seen[id]=;.(ded,e)
_,e (ded)
e.SoundId e.Name
ns=.();ns.Name=e.Name;ns.SoundId=..(e.SoundId);ns.Volume=St.currentVolume;ns.PlaybackSpeed=St.currentSpeed;ns.Looped=;ns.Parent=soundsFolder
.(Dat.createdSounds,ns);.(Dat.trackList,{DisplayName=e.Name,FullName=e.Name,Type=,SoundId=e.SoundId})
sic=; _,cat (Dat.categories) cat.CategoryID==Cfg.SOUND_ID_CATEGORY_ID sic=cat;
sic sic={Name=Cfg.SOUND_ID_CATEGORY_NAME,Tracks={},TrackTIDs={},CategoryID=Cfg.SOUND_ID_CATEGORY_ID};.(Dat.categories,sic)
sic.TrackTIDs sic.TrackTIDs={}
sic.TrackTIDs={}; _,t (Dat.trackList) t.Type== .(sic.TrackTIDs,(t))
()
();();();()
sound=Dat.createdSounds[St.currentTrackIndex]; sound (sound)
guardConns={}
(s)
s s:()
guardConns[s] _,c (guardConns[s]) (() c:() )
conns={}
.(conns,s:():(()
s~=sound St.isPaused ; Dat.crossfadingSounds[s]
iv=St.currentVolume; .(s.Volume-iv)> .(() s==sound St.isPaused Dat.crossfadingSounds[s] s.Volume=iv )
))
.(conns,s:():(()
s~=sound ; iv=(St.currentSpeed<=) St.currentSpeed
.(s.PlaybackSpeed-iv)> .(() s==sound s.PlaybackSpeed=iv )
))
guardConns[s]=conns
_,s (Dat.createdSounds) (s)
Dat.attachSoundGuard=attachSoundGuard
refreshPlayButton; updateMp3List; showNotification
Svc.Pl.LocalPlayer.CharacterAdded:(() .(); St.isPaused sound sound.IsPlaying (() sound:() ) )
(u) u:() u
()
ok,html=(() :() ); ok html ,
scripts={}; src html:() .(scripts,src)
#scripts== ,
i=#scripts,,-
jok,js=(() :(scripts[i]) )
jok js #js>
cid js:() #cid>= cid,
cid js:() #cid>= cid,
cid js:() #cid>= cid,
cid js:() #cid>= cid,
;.()
; ,
(rawUrl,cb)
turl=(rawUrl);cb=cb () ;()
cid,cerr=(); cid ,..(cerr )
()
ok1,rr=(() ({Url=..turl....cid,Method=,Headers={[]=}}) )
ok1 rr rr.StatusCode~= ,..(rr (rr.StatusCode) )..
ok2,td=(() Svc.HS:(rr.Body) ); ok2 td ,,
policy=(td.policy ):()
isSnipped=policy== (td.duration td.full_duration td.full_duration> td.duration<td.full_duration td.duration<=)
isSnipped
fullSecs=td.full_duration .(td.full_duration/)
fullFmt=fullSecs> .(,.(fullSecs/),fullSecs%)
,..fullFmt,td.title
scTitle=td.title ; saurl=
td.media td.media.transcodings
_,t (td.media.transcodings) t.format t.format.protocol== (t.format.mime_type ):(,,) saurl=t.url;
saurl _,t (td.media.transcodings) t.format t.format.protocol== saurl=t.url;
saurl ,
()
ok3,sr=(() ({Url=saurl....cid,Method=,Headers={[]=}}) )
ok3 sr sr.StatusCode~= ,
ok4,si=(() Svc.HS:(sr.Body) ); ok4 si si.url ,
()
ok5,resp=(() ({Url=si.url,Method=,Headers={[]=,[]=}}) )
ok5 resp ,
status=resp.StatusCode resp.status ; audioData=resp.Body resp.body
status~= status~= ,..(status)
#audioData< ,
(.(,#audioData/)..); audioData,,scTitle
(lrc)
lines={}
line (lrc ):()
m,s,rest=line:()
m s
lt=(m)*+(s)
rest rest:()
wl={}; wm,ws,wt rest:() wc=wt:() ; wc~= .(wl,{text=wc,time=(wm)*+(ws)})
#wl> p={}; _,w (wl) .(p,w.text) ;.(lines,{time=lt,text=.(p,),words=wl})
cl=rest rest:() ; cl~= cl:() .(lines,{time=lt,text=cl})
;.(lines,(a,b) a.time<b.time ); lines
lyricsOverlay=; eolTitleTween=
()
Dat.currentLyrics={};Dat.lastLyricIndex=-;Dat.eolFired=;Dat.detectedLyricsTitle=;Dat.translateCache={}
lyricsOverlay
lyricsOverlay.prev.Active=;lyricsOverlay.current.Active=;lyricsOverlay.next.Active=
lyricsOverlay.prev.Text=;lyricsOverlay.prev.TextTransparency=
lyricsOverlay.current.Text=;lyricsOverlay.current.TextTransparency=;lyricsOverlay.current.Position=.(,,,)
lyricsOverlay.next.Text=;lyricsOverlay.next.TextTransparency=;lyricsOverlay.noResults.Text=
lyricsOverlay.spinnerImg lyricsOverlay.spinnerImg.Visible=
lyricsOverlay.displayedIndices lyricsOverlay.displayedIndices.prev=;lyricsOverlay.displayedIndices.cur=;lyricsOverlay.displayedIndices.next=
eolTitleTween eolTitleTween:();eolTitleTween=
lyricsOverlay.eolTitle lyricsOverlay.eolTitle.Text=;lyricsOverlay.eolTitle.TextTransparency=;lyricsOverlay.eolTitle.Position=.(,,,)
lyricsOverlay.underline.Position=.(,,,);Svc.TS:(lyricsOverlay.underline,TweenInfo.(),{Size=.(,,,)}):()
St.cinematicMode _cinGui
_,ch (_cinGui:()) ch:() (() ch:() )
topBar=_cinGui:(); botBar=_cinGui:()
topBar topBar.Position.Y.Scale>=
retractTI=TweenInfo.(,.EasingStyle.Quad,.EasingDirection.In)
Svc.TS:(topBar,retractTI,{Position=.(,,-,)}):()
botBar Svc.TS:(botBar,retractTI,{Position=.(,,,)}):()
(url)
ok,r;ok,r=(() ({Url=url,Method=,Headers={[]=,[]=}}) )
ok r (r.StatusCode== r.status==) r.Body r.body
ok,r=(() :(url) ); ok r #r> r
ok,r=(() :():(url,) ); ok r #r> r
(url,body)
ok,r;ok,r=(() ({Url=url,Method=,Headers={[]=,[]=},Body=body}) )
ok r (r.StatusCode== r.status==) r.Body r.body
ok,r=(() .({Url=url,Method=,Headers={[]=},Body=body}) )
ok r (r.StatusCode== r.status==) r.Body r.body
(data)
ok,res;ok,res=(() .crypt.base64.(data) ); ok res #res> res
ok,res=(() crypt.(data) ); ok res #res> res
ok,res=(() crypt.base64.(data) ); ok res #res> res
chars=
out={}; i=; i<=#data
b1=data:(i); b2=(i+<=#data) data:(i+) ; b3=(i+<=#data) data:(i+) ; v=b1*+b2*+b3
out[#out+]=chars:(.(v/)%+,.(v/)%+);out[#out+]=chars:(.(v/)%+,.(v/)%+)
out[#out+]=(i+>#data) chars:(.(v/)%+,.(v/)%+);out[#out+]=(i+>#data) chars:(v%+,v%+);i=i+
; .(out)
(s)
s=s:(,):(,):(,):(, ):(, ):(, ):(, )
s=s:(, ):(, ):(, ):(, ):(, )
s=s:(,):(,):(,):(,):(,):(,)
s:()
(s) s:(,(c) .(,c:()) ):(,)
(text,cb)
text text== (text);
cached=Dat.translateCache[text]; cached (cached);
Dat.translatePending[text]
.(Dat.translatePending[text],cb);
Dat.translatePending[text]={cb}
.(()
encoded=text:(,(c) .(,c:()) )
url=..encoded
ok,resp=(() ({Url=url,Method=,Headers={[]=,[]=}}) )
result=text
ok resp (resp.StatusCode== (resp.StatusCode )==)
pok,data=(() Svc.HS:(resp.Body resp.body ) )
pok data (data)== data[] (data[])==
translated=
_,part (data[]) (part)== (part[])== translated=translated..part[]
translated~= result=translated
Dat.translateCache[text]=result
waiters=Dat.translatePending[text] {}
Dat.translatePending[text]=
_,wcb (waiters) (wcb,result)
)
(gen)
St.translateEnabled
lyr=Dat.currentLyrics; #lyr==
.(()
_,entry (lyr)
Dat.lyricsFetchGen~=gen
Dat.translateCache[entry.text]
(entry.text,() )
.()
)
(text)
lyricsOverlay ;lyricsOverlay.noResults.Text=text
lyricsOverlay.spinnerImg lyricsOverlay.spinnerImg.Visible=text~= (text:(,,) text:(,,))
St.cinematicMode _cinGui
noLyr=text:(,,) text:(,,) text:(,,) text:(,,)
hasSynced=(text== #Dat.currentLyrics>)
sg=_cinGui
topBar=sg:(); botBar=sg:()
noLyr
exitTI=TweenInfo.(,.EasingStyle.Sine,.EasingDirection.In)
topBar topBar.Position.Y.Scale>=
Svc.TS:(topBar,exitTI,{Position=.(,,-,)}):()
Svc.TS:(botBar,exitTI,{Position=.(,,,)}):()
hasSynced
inTI=TweenInfo.(,.EasingStyle.Quart,.EasingDirection.Out)
topBar topBar.Position.Y.Scale<
Svc.TS:(topBar,inTI,{Position=.(,,,)}):()
Svc.TS:(botBar,inTI,{Position=.(,,,)}):()
(name,gen)
.(()
#name<= lyricsOverlay St.lyricsEnabled () ;
(); lyricsOverlay St.lyricsEnabled ()
flaggedInstrumental[name]
lyricsOverlay St.lyricsEnabled lyricsOverlay.current.RichText=;lyricsOverlay.current.Text=;lyricsOverlay.current.TextTransparency=;(); lyricsOverlay.refreshUnderline lyricsOverlay.() ;
nameLow=name:()
isInstrumental=(
nameLow== nameLow:() nameLow:()
nameLow:() nameLow:()
nameLow:() nameLow:()
nameLow:() nameLow:()
nameLow:() nameLow:()
nameLow:() nameLow:()
nameLow:() nameLow:()
nameLow:() nameLow:()
nameLow:() nameLow:()
nameLow:() nameLow:()
)
isInstrumental
lyricsOverlay St.lyricsEnabled
lyricsOverlay.current.RichText=
lyricsOverlay.current.Text=
lyricsOverlay.current.TextTransparency=
()
lyricsOverlay.refreshUnderline lyricsOverlay.()
;
(artist,title)
title title== ; lurls={}
artist artist~= .(lurls,..(title)....(artist)..);.(lurls,..(title)....(artist));.(lurls,..(title....artist))
.(lurls,..(title))
_,url (lurls)
Dat.lyricsFetchGen~=gen
raw=(url)
raw #raw> (raw:(,)== raw:(,)==)
ok,p=(() Svc.HS:(raw) )
ok p
res=(p)== (p[]~= p {p}) {}
_,e (res)
e.instrumental==
e.syncedLyrics e.syncedLyrics~= lrc=(e.syncedLyrics); #lrc> lrc
;.()
;
sA,sT; a,t=name:(); t t~= sA=(a);sT=(t) sT=(name);sA=
result={lrc=,plain=,fpArtist=,fpTitle=,done=}
.(() lrc=(sA,sT); Dat.lyricsFetchGen~=gen ; lrc== result.done=;result.lrc= lrc result.done result.lrc=lrc;result.done= )
ti=Dat.trackList[St.currentTrackIndex]
ti ti.Type== ti.Path
.(()
w=; w< Dat.lyricsFetchGen~=gen ; s=sound; s s.TimeLength s.TimeLength> ;.();w=w+
Dat.lyricsFetchGen~=gen
dur=(sound sound.TimeLength sound.TimeLength>) sound.TimeLength
ff=;(() ff=(ti.Path) ); ff #ff< dur<
bps=#ff/dur; passes={.(,.(dur*,)),.(,.(dur*,)),.(,.(dur*,)),.(,.(dur*,))}
_,sk (passes)
Dat.lyricsFetchGen~=gen result.done
skipB=.(,.(.(sk*bps),#ff-.(.(*bps),)-)); capB=.(.(*bps),); chunk=ff:(skipB+,skipB+capB)
#chunk< ; b64=(chunk); b64 #b64==
raw=(,..b64:(,):(,):(,))
Dat.lyricsFetchGen~=gen
raw #raw> raw:(,)==
ok,d=(() Svc.HS:(raw) )
ok d d.status== d.result
ra,rt=d.result.artist,d.result.title; lf=d.result.lyrics; rp=
(lf)== rp=lf.lyrics (lf)== lf~= rp=lf
rt rt~= result.fpArtist=ra;result.fpTitle=rt; rp rp~= result.plain=rp ; fpLrc=(ra,rt); fpLrc== result.lrc=;result.done= fpLrc result.done result.lrc=fpLrc;result.done= ;
;.()
;ff=
)
waited=; result.done waited< Dat.lyricsFetchGen~=gen ;.();waited=waited+
Dat.lyricsFetchGen~=gen
result.lrc==
lyricsOverlay St.lyricsEnabled
lyricsOverlay.current.RichText=;lyricsOverlay.current.Text=
lyricsOverlay.current.TextTransparency=;()
lyricsOverlay.refreshUnderline lyricsOverlay.()
;
result.lrc Dat.currentLyrics=result.lrc; result.fpTitle result.fpTitle~= Dat.detectedLyricsTitle=(result.fpArtist result.fpArtist~= (result.fpArtist..) )..result.fpTitle result.fpTitle== result.fpTitle Dat.detectedLyricsTitle= ; lyricsOverlay () ;(gen);
pl=result.plain
pl pl==
aus={}; sA sT .(aus,..(sA....sT)) ; sT .(aus,..(sT)) ; result.fpArtist result.fpTitle .(aus,..(result.fpArtist....result.fpTitle))
_,url (aus) Dat.lyricsFetchGen~=gen ; raw=(url); raw #raw> raw:(,)== ok,d=(() Svc.HS:(raw) ); ok d d.status== (d.result)== #d.result> h=d.result[]; h.lyrics h.lyrics~= pl=h.lyrics; ;.()
Dat.lyricsFetchGen~=gen
pl pl~=
ls={}; line pl:() tr=line:(); tr~= .(ls,tr)
#ls> sound sound.TimeLength sound.TimeLength> sp=sound.TimeLength/(#ls+); td2={}; i,ln (ls) .(td2,{time=sp*i,text=ln}) ;Dat.currentLyrics=td2; lyricsOverlay () ;(gen) lyricsOverlay St.lyricsEnabled lyricsOverlay.current.Text=ls[] ;()
lyricsOverlay St.lyricsEnabled ()
lyricsOverlay St.lyricsEnabled ()
)
(pt,nt,pi,ci,ni)
lyricsOverlay
lyricsOverlay.displayedIndices lyricsOverlay.displayedIndices.prev=pi ;lyricsOverlay.displayedIndices.cur=ci ;lyricsOverlay.displayedIndices.next=ni
Svc.TS:(lyricsOverlay.prev,TweenInfo.(,.EasingStyle.Linear),{TextTransparency=}):();Svc.TS:(lyricsOverlay.next,TweenInfo.(,.EasingStyle.Linear),{TextTransparency=}):()
.(,()
lyricsOverlay.prev.Text=pt;lyricsOverlay.next.Text=nt
Svc.TS:(lyricsOverlay.prev,TweenInfo.(,.EasingStyle.Quad,.EasingDirection.Out),{TextTransparency=}):();Svc.TS:(lyricsOverlay.next,TweenInfo.(,.EasingStyle.Quad,.EasingDirection.Out),{TextTransparency=}):()
lyricsOverlay.refreshUnderline lyricsOverlay.()
)
(r,p) c=.();c.CornerRadius=.(,r);c.Parent=p
(t,col,tr,p) s=.();s.Thickness=t;s.Color=col;s.Transparency=tr;s.ApplyStrokeMode=.ApplyStrokeMode.Border;s.Parent=p; s
UI.gui=.();UI.gui.Name=;UI.gui.ResetOnSpawn=;UI.gui.IgnoreGuiInset=;UI.gui.ZIndexBehavior=.ZIndexBehavior.Global;UI.gui.Parent=pGui
UI.main=.();UI.main.Name=;UI.main.AnchorPoint=.(,);UI.main.Size=.(,Cfg.CARD_WIDTH,,Cfg.BASE_HEIGHT);UI.main.Position=.(,,,);UI.main.BackgroundColor3=C.BG;UI.main.BackgroundTransparency=;UI.main.BorderSizePixel=;UI.main.Visible=;UI.main.ZIndex=;UI.main.Parent=UI.gui;(,UI.main);(,C.BORDER_LIT,,UI.main)
mg=.();mg.Color=ColorSequence.({ColorSequenceKeypoint.(,.(,,)),ColorSequenceKeypoint.(,.(,,)),ColorSequenceKeypoint.(,.(,,))});mg.Rotation=;mg.Parent=UI.main
UI.uiScale=.();UI.uiScale.Scale=;UI.uiScale.Parent=UI.main
() ;();UI.main:():(syncShadow);UI.main:():(syncShadow)
lg=.();lg.Name=;lg.ResetOnSpawn=;lg.IgnoreGuiInset=;lg.ZIndexBehavior=.ZIndexBehavior.Global;lg.DisplayOrder=;lg.Parent=pGui;lg.Enabled=
fr=.();fr.AnchorPoint=.(,);fr.Position=.(,,,);fr.Size=.(,,,);fr.BackgroundTransparency=;fr.ZIndex=;fr.Visible=;fr.Parent=lg
pill=.();pill.AnchorPoint=.(,);pill.Position=.(,,,);pill.Size=.(,-,,);pill.BackgroundColor3=C.BG;pill.BackgroundTransparency=;pill.BorderSizePixel=;pill.ClipsDescendants=;pill.ZIndex=;pill.Parent=fr;(,pill);(,C.BORDER_LIT,,pill)
pg=.();pg.Color=ColorSequence.({ColorSequenceKeypoint.(,C.ELEVATED),ColorSequenceKeypoint.(,C.BG)});pg.Transparency=NumberSequence.({NumberSequenceKeypoint.(,),NumberSequenceKeypoint.(,)});pg.Rotation=;pg.Parent=pill
(nm,yp,sz,fs,bold) b=.();b.Name=nm;b.AnchorPoint=.(,);b.Position=.(,,,yp);b.Size=.(sz,,,bold (nm== ));b.BackgroundTransparency=;b.AutoButtonColor=;b.Font=bold .Font.GothamBold .Font.GothamMedium;b.Text=;b.RichText=bold;b.TextColor3=bold C.TEXT C.TEXT2;b.TextTransparency=bold ;b.ZIndex=;b.Parent=pill; bold b.TextScaled=; tc=.();tc.MinTextSize=;tc.MaxTextSize=fs;tc.Parent=b b.TextSize=fs;b.TextTruncate=.TextTruncate.AtEnd ; b
prevBtn=(,,,,); curBtn=(,,,,)
ul=.();ul.AnchorPoint=.(,);ul.Position=.(,,,);ul.Size=.(,,,);ul.BackgroundColor3=C.ACCENT;ul.BackgroundTransparency=;ul.BorderSizePixel=;ul.ZIndex=;ul.Parent=pill;(,ul)
ulFL=.();ulFL.Name=;ulFL.AnchorPoint=.(,);ulFL.Position=.(,,,);ulFL.Size=.(,,,);ulFL.BackgroundColor3=C.BG;ulFL.BackgroundTransparency=;ulFL.BorderSizePixel=;ulFL.ZIndex=;ulFL.Parent=ul; ulFLG=.();ulFLG.Transparency=NumberSequence.({NumberSequenceKeypoint.(,),NumberSequenceKeypoint.(,)});ulFLG.Rotation=;ulFLG.Parent=ulFL
ulFR=.();ulFR.Name=;ulFR.AnchorPoint=.(,);ulFR.Position=.(,,,);ulFR.Size=.(,,,);ulFR.BackgroundColor3=C.BG;ulFR.BackgroundTransparency=;ulFR.BorderSizePixel=;ulFR.ZIndex=;ulFR.Parent=ul; ulFRG=.();ulFRG.Transparency=NumberSequence.({NumberSequenceKeypoint.(,),NumberSequenceKeypoint.(,)});ulFRG.Rotation=;ulFRG.Parent=ulFR
nextBtn=(,,,,)
noRes=.();noRes.AnchorPoint=.(,);noRes.Position=.(,,,);noRes.Size=.(,,,);noRes.BackgroundTransparency=;noRes.Font=.Font.GothamMedium;noRes.Text=;noRes.TextColor3=C.TEXT3;noRes.TextSize=;noRes.ZIndex=;noRes.Parent=pill
spn=.();spn.AnchorPoint=.(,);spn.Position=.(,,,);spn.Size=.(,,,);spn.BackgroundTransparency=;spn.Image=;spn.ZIndex=;spn.Visible=;spn.Parent=pill
di={prev=,cur=,=}
eolTitle=.();eolTitle.Name=;eolTitle.AnchorPoint=.(,);eolTitle.Position=.(,,,);eolTitle.Size=.(,,,);eolTitle.BackgroundTransparency=;eolTitle.Font=.Font.GothamBold;eolTitle.Text=;eolTitle.TextColor3=.(,,);eolTitle.TextSize=;eolTitle.TextScaled=;eolTitle.TextTransparency=;eolTitle.ZIndex=;eolTitle.Parent=pill
eolTitleTC=.();eolTitleTC.MinTextSize=;eolTitleTC.MaxTextSize=;eolTitleTC.Parent=eolTitle
(idx) Dat.eolFired ; idx< idx>#Dat.currentLyrics ; s=sound; s s.TimeLength s.TimeLength<= ;(() s.TimePosition=.(,.(Dat.currentLyrics[idx].time,s.TimeLength-)) )
prevBtn.MouseButton1Click:(() (di.prev) );curBtn.MouseButton1Click:(() (di.cur) );nextBtn.MouseButton1Click:(() (di.next) )
prevBtn.MouseEnter:(() Dat.eolFired prevBtn.TextTransparency= );prevBtn.MouseLeave:(() prevBtn.TextTransparency=Dat.eolFired )
curBtn.MouseEnter:(() Dat.eolFired Svc.TS:(curBtn,TweenInfo.(),{TextColor3=C.ACCENT}):() );curBtn.MouseLeave:(() Dat.eolFired Svc.TS:(curBtn,TweenInfo.(),{TextColor3=C.TEXT}):() )
nextBtn.MouseEnter:(() Dat.eolFired nextBtn.TextTransparency= );nextBtn.MouseLeave:(() nextBtn.TextTransparency=Dat.eolFired )
translatePillBtn=.();translatePillBtn.Name=;translatePillBtn.AnchorPoint=.(,);translatePillBtn.Position=.(,-,,);translatePillBtn.Size=.(,,,);translatePillBtn.BackgroundTransparency=;translatePillBtn.Image=;translatePillBtn.ImageColor3=C.TEXT2;translatePillBtn.ZIndex=;translatePillBtn.Visible=;translatePillBtn.Parent=pill
flagBtn=.();flagBtn.Name=;flagBtn.AnchorPoint=.(,);flagBtn.Position=.(,-,,);flagBtn.Size=.(,,,);flagBtn.BackgroundTransparency=;flagBtn.Image=;flagBtn.ImageColor3=C.TEXT2;flagBtn.ZIndex=;flagBtn.Visible=;flagBtn.Parent=pill
flagTooltip=.();flagTooltip.AnchorPoint=.(,);flagTooltip.Size=.(,,,);flagTooltip.AutomaticSize=.AutomaticSize.X;flagTooltip.BackgroundColor3=C.ELEVATED;flagTooltip.BorderSizePixel=;flagTooltip.Visible=;flagTooltip.ZIndex=;flagTooltip.Parent=lg;(,flagTooltip)
p=.();p.PaddingLeft=.(,);p.PaddingRight=.(,);p.Parent=flagTooltip
flagTooltipLbl=.();flagTooltipLbl.Size=.(,,,);flagTooltipLbl.AutomaticSize=.AutomaticSize.X;flagTooltipLbl.BackgroundTransparency=;flagTooltipLbl.Font=.Font.GothamMedium;flagTooltipLbl.Text=;flagTooltipLbl.TextColor3=C.TEXT;flagTooltipLbl.TextSize=;flagTooltipLbl.ZIndex=;flagTooltipLbl.Parent=flagTooltip
(active)
Svc.TS:(flagBtn,TweenInfo.(),{ImageColor3=active C.ACCENT C.TEXT2}):()
flagTooltipLbl.Text=active
flagBtn.MouseEnter:(()
mp=Svc.UIS:()
flagTooltip.Position=.(mp.X+,mp.Y-)
flagTooltip.Visible=
)
flagBtn.MouseLeave:(() flagTooltip.Visible= )
Svc.UIS.InputChanged:((inp)
inp.UserInputType==.UserInputType.MouseMovement flagTooltip.Visible
mp=Svc.UIS:()
flagTooltip.Position=.(mp.X+,mp.Y-)
)
()
Svc.TS:(translatePillBtn,TweenInfo.(),{ImageColor3=St.translateEnabled C.ACCENT C.TEXT2}):()
()
trTooltip=.();trTooltip.AnchorPoint=.(,);trTooltip.Size=.(,,,);trTooltip.AutomaticSize=.AutomaticSize.X;trTooltip.BackgroundColor3=C.ELEVATED;trTooltip.BorderSizePixel=;trTooltip.Visible=;trTooltip.ZIndex=;trTooltip.Parent=lg;(,trTooltip)
p=.();p.PaddingLeft=.(,);p.PaddingRight=.(,);p.Parent=trTooltip
trTooltipLbl=.();trTooltipLbl.Size=.(,,,);trTooltipLbl.AutomaticSize=.AutomaticSize.X;trTooltipLbl.BackgroundTransparency=;trTooltipLbl.Font=.Font.GothamMedium;trTooltipLbl.Text=;trTooltipLbl.TextColor3=C.TEXT;trTooltipLbl.TextSize=;trTooltipLbl.ZIndex=;trTooltipLbl.Parent=trTooltip
translatePillBtn.MouseEnter:(() trTooltipLbl.Text=St.translateEnabled ; mp=Svc.UIS:();trTooltip.Position=.(mp.X+,mp.Y-);trTooltip.Visible= )
translatePillBtn.MouseLeave:(() trTooltip.Visible= )
Svc.UIS.InputChanged:((inp) inp.UserInputType==.UserInputType.MouseMovement trTooltip.Visible mp=Svc.UIS:();trTooltip.Position=.(mp.X+,mp.Y-) )
translatePillBtn.MouseButton1Click:(()
St.translateEnabled= St.translateEnabled;();()
Dat.translateCache={};Dat.translatePending={};Dat.lastLyricIndex=-
St.translateEnabled (Dat.lyricsFetchGen)
)
.__MCRefTranslatePill=refTranslatePillBtn
flagBtn.MouseButton1Click:(()
inf=Dat.trackList[St.currentTrackIndex]; inf
nm=inf.DisplayName
flaggedInstrumental[nm]
flaggedInstrumental[nm]=;();()
Dat.lyricsFetchGen=Dat.lyricsFetchGen+;(nm,Dat.lyricsFetchGen)
(..nm,)
flaggedInstrumental[nm]=;();()
Dat.lyricsFetchGen=Dat.lyricsFetchGen+
()
lyricsOverlay
lyricsOverlay.prev.Text=;lyricsOverlay.prev.TextTransparency=
lyricsOverlay.next.Text=;lyricsOverlay.next.TextTransparency=
lyricsOverlay.current.RichText=;lyricsOverlay.current.Text=;lyricsOverlay.current.TextTransparency=
()
lyricsOverlay.refreshUnderline lyricsOverlay.()
(..nm,)
)
lyricsOverlay={gui=lg,frame=fr,pill=pill,pillGrad=pg,prev=prevBtn,current=curBtn,=nextBtn,underline=ul,noResults=noRes,spinnerImg=spn,displayedIndices=di,eolTitle=eolTitle,flagBtn=flagBtn,updateFlagBtn=updateFlagBtn}
() txt=curBtn.Text; txt== Svc.TS:(ul,TweenInfo.(,.EasingStyle.Quad),{Size=.(,,,)}):(); ; ts=:():(txt,,.Font.GothamBold,.(.huge,.huge));Svc.TS:(ul,TweenInfo.(,.EasingStyle.Back,.EasingDirection.Out),{Size=.(,.(ts.X,pill.AbsoluteSize.X*),,)}):()
lyricsOverlay.refreshUnderline=refUL
(nm,sz,pos) f=.();f.Name=nm;f.Size=sz;f.Position=pos;f.BackgroundColor3=C.BG;f.BorderSizePixel=;f.Visible=;f.ZIndex=;f.Parent=UI.main;(,f);(,C.BORDER_LIT,,f); g=.();g.Color=ColorSequence.(C.CARD_HI,C.CARD_LO);g.Rotation=;g.Parent=f; f
UI.listPanel=(,.(,Cfg.LIST_WIDTH,,),.(,,,))
() ;();UI.listPanel:():(syncListGlow);UI.listPanel:():(syncListGlow);UI.listPanel:():(syncListGlow)
UI.listTitleBar=.();UI.listTitleBar.Size=.(,,,);UI.listTitleBar.BackgroundTransparency=;UI.listTitleBar.ClipsDescendants=;UI.listTitleBar.ZIndex=;UI.listTitleBar.Parent=UI.listPanel
UI.listTitle=.();UI.listTitle.AnchorPoint=.(,);UI.listTitle.Position=.(,,,);UI.listTitle.Size=.(,-,,);UI.listTitle.BackgroundTransparency=;UI.listTitle.Font=.Font.GothamSemibold;UI.listTitle.Text=;UI.listTitle.TextColor3=C.TEXT;UI.listTitle.TextXAlignment=.TextXAlignment.Left;UI.listTitle.TextSize=;UI.listTitle.ZIndex=;UI.listTitle.Parent=UI.listTitleBar
UI.searchIconBtn=.();UI.searchIconBtn.AnchorPoint=.(,);UI.searchIconBtn.Position=.(,-,,);UI.searchIconBtn.Size=.(,,,);UI.searchIconBtn.BackgroundColor3=C.ELEVATED;UI.searchIconBtn.AutoButtonColor=;UI.searchIconBtn.BorderSizePixel=;UI.searchIconBtn.Image=;UI.searchIconBtn.ImageColor3=C.TEXT2;UI.searchIconBtn.ScaleType=.ScaleType.Fit;UI.searchIconBtn.ZIndex=;UI.searchIconBtn.Parent=UI.listTitleBar;(,UI.searchIconBtn);(,C.BORDER_LIT,,UI.searchIconBtn)
UI.searchBox=.();UI.searchBox.Position=.(,,,);UI.searchBox.Size=.(,-,,);UI.searchBox.BackgroundColor3=C.SURFACE;UI.searchBox.BorderSizePixel=;UI.searchBox.Font=.Font.GothamMedium;UI.searchBox.PlaceholderText=;UI.searchBox.PlaceholderColor3=C.TEXT3;UI.searchBox.Text=;UI.searchBox.TextColor3=C.TEXT;UI.searchBox.TextSize=;UI.searchBox.ClearTextOnFocus=;UI.searchBox.ZIndex=;UI.searchBox.Visible=;UI.searchBox.Parent=UI.listTitleBar;(,UI.searchBox);(,C.BORDER_LIT,,UI.searchBox)
sbPad=.();sbPad.PaddingLeft=.(,);sbPad.PaddingRight=.(,);sbPad.Parent=UI.searchBox
UI.searchIconBtn.MouseButton1Click:(()
St.searchActive= St.searchActive
St.searchActive UI.searchBox.Visible=;Svc.TS:(UI.listTitleBar,TweenInfo.(,.EasingStyle.Quad),{Size=.(,,,)}):();Svc.TS:(UI.listScroll,TweenInfo.(,.EasingStyle.Quad),{Position=.(,,,),Size=.(,-,,-)}):();Svc.TS:(UI.searchIconBtn,TweenInfo.(),{ImageColor3=C.ACCENT,BackgroundColor3=C.ACCENT_DIM}):();UI.searchBox:()
UI.searchBox:();UI.searchBox.Text=;St.searchQuery=;St.searchActive=;UI.searchBox.Visible=;Svc.TS:(UI.listTitleBar,TweenInfo.(,.EasingStyle.Quad),{Size=.(,,,)}):();Svc.TS:(UI.listScroll,TweenInfo.(,.EasingStyle.Quad),{Position=.(,,,),Size=.(,-,,-)}):();Svc.TS:(UI.searchIconBtn,TweenInfo.(),{ImageColor3=C.TEXT2,BackgroundColor3=C.ELEVATED}):();()
)
UI.addCategoryBtn=.();UI.addCategoryBtn.AnchorPoint=.(,);UI.addCategoryBtn.Position=.(,-,,);UI.addCategoryBtn.Size=.(,,,);UI.addCategoryBtn.BackgroundColor3=C.ELEVATED;UI.addCategoryBtn.AutoButtonColor=;UI.addCategoryBtn.Text=;UI.addCategoryBtn.BorderSizePixel=;UI.addCategoryBtn.ZIndex=;UI.addCategoryBtn.Parent=UI.listTitleBar;(,UI.addCategoryBtn)
acStr=(,C.BORDER_LIT,,UI.addCategoryBtn); acIc=.();acIc.AnchorPoint=.(,);acIc.Position=.(,,,);acIc.Size=.(,,,);acIc.BackgroundColor3=C.ACCENT;acIc.BorderSizePixel=;acIc.ZIndex=;acIc.Parent=UI.addCategoryBtn;(,acIc)
acIcL=.();acIcL.Size=.(,,,);acIcL.BackgroundTransparency=;acIcL.Font=.Font.GothamBold;acIcL.Text=;acIcL.TextColor3=AT;acIcL.TextSize=;acIcL.ZIndex=;acIcL.Parent=acIc
acLbl=.();acLbl.AnchorPoint=.(,);acLbl.Position=.(,,,);acLbl.Size=.(,-,,);acLbl.BackgroundTransparency=;acLbl.Font=.Font.GothamMedium;acLbl.Text=;acLbl.TextColor3=C.TEXT2;acLbl.TextXAlignment=.TextXAlignment.Left;acLbl.TextSize=;acLbl.ZIndex=;acLbl.Name=;acLbl.Parent=UI.addCategoryBtn
UI.addCategoryBtn.MouseEnter:(() Svc.TS:(UI.addCategoryBtn,TweenInfo.(,.EasingStyle.Quad),{BackgroundColor3=C.ACCENT_DIM}):();acStr.Transparency=;acLbl.TextColor3=C.TEXT )
UI.addCategoryBtn.MouseLeave:(() Svc.TS:(UI.addCategoryBtn,TweenInfo.(,.EasingStyle.Quad),{BackgroundColor3=C.ELEVATED}):();acStr.Transparency=;acLbl.TextColor3=C.TEXT2 )
(parent,pos,size,zi)
sf=.();sf.Position=pos;sf.Size=size;sf.BackgroundTransparency=;sf.BorderSizePixel=;sf.ScrollBarThickness=;sf.ScrollBarImageColor3=C.ACCENT;sf.CanvasSize=.(,,,);sf.ZIndex=zi;sf.Parent=parent
ul=.();ul.Padding=.(,);ul.SortOrder=.SortOrder.LayoutOrder;ul.Parent=sf
ul:():(() sf.CanvasSize=.(,,,ul.AbsoluteContentSize.Y+) ); sf,ul
UI.listScroll,UI.listLayout=(UI.listPanel,.(,,,),.(,-,,-),)
UI.queuePanel=(,.(,Cfg.LIST_WIDTH,,),.(,-Cfg.LIST_WIDTH,,))
qtb=.();qtb.Size=.(,,,);qtb.BackgroundTransparency=;qtb.ZIndex=;qtb.Parent=UI.queuePanel; qtl=.();qtl.AnchorPoint=.(,);qtl.Position=.(,,,);qtl.Size=.(,-,,);qtl.BackgroundTransparency=;qtl.Font=.Font.GothamSemibold;qtl.Text=;qtl.TextColor3=C.TEXT;qtl.TextXAlignment=.TextXAlignment.Left;qtl.TextSize=;qtl.ZIndex=;qtl.Parent=qtb
UI.queueScroll,UI.queueLayout=(UI.queuePanel,.(,,,),.(,-,,-),)
(ax,px,py,txt) b=.();b.AnchorPoint=.(ax,);b.Position=.(px,py,,);b.Size=.(,,,);b.BackgroundColor3=C.ELEVATED;b.AutoButtonColor=;b.Font=.Font.GothamBold;b.Text=txt;b.TextSize=;b.TextColor3=C.ACCENT;b.BorderSizePixel=;b.ZIndex=;b.Parent=UI.main;(,b);(,C.BORDER_LIT,,b); b
UI.toggleListBtn=(,,-,);UI.toggleQueueBtn=(,,,)
(on) Svc.TS:(UI.main,TweenInfo.(,.EasingStyle.Quad,.EasingDirection.Out),{Size=.(,Cfg.CARD_WIDTH,,Cfg.BASE_HEIGHT+(on Cfg.REVERB_EXTRA_HEIGHT ))}):(); UI.reverbPanel UI.reverbPanel.Visible=on
UI.titleBar=.();UI.titleBar.Size=.(,,,);UI.titleBar.BackgroundTransparency=;UI.titleBar.ZIndex=;UI.titleBar.Parent=UI.main
tbord=.();tbord.AnchorPoint=.(,);tbord.Position=.(,,,);tbord.Size=.(,-,,);tbord.BackgroundColor3=C.BORDER;tbord.BorderSizePixel=0;tbord.ZIndex=2;tbord.Parent=UI.titleBar end
UI.titleLabel=Instance.new("TextLabel");UI.titleLabel.AnchorPoint=Vector2.new(0,0.5);UI.titleLabel.Position=UDim2.new(0,14,0.5,0);UI.titleLabel.Size=UDim2.new(0,200,0,20);UI.titleLabel.BackgroundTransparency=1;UI.titleLabel.Font=Enum.Font.GothamBold;UI.titleLabel.Text="music controller";UI.titleLabel.TextColor3=C.TEXT;UI.titleLabel.TextXAlignment=Enum.TextXAlignment.Left;UI.titleLabel.TextSize=14;UI.titleLabel.ZIndex=4;UI.titleLabel.Parent=UI.titleBar
UI.settingsButton=Instance.new("ImageButton");UI.settingsButton.AnchorPoint=Vector2.new(1,0.5);UI.settingsButton.Position=UDim2.new(1,-12,0.5,0);UI.settingsButton.Size=UDim2.new(0,17,0,17);UI.settingsButton.BackgroundTransparency=1;UI.settingsButton.ZIndex=4;UI.settingsButton.Image="rbxassetid://3687980595";UI.settingsButton.ImageColor3=C.TEXT2;UI.settingsButton.Parent=UI.titleBar
UI.helpButton=Instance.new("ImageButton");UI.helpButton.AnchorPoint=Vector2.new(1,0.5);UI.helpButton.Position=UDim2.new(1,-34,0.5,0);UI.helpButton.Size=UDim2.new(0,17,0,17);UI.helpButton.BackgroundTransparency=1;UI.helpButton.ZIndex=220;UI.helpButton.Image="rbxassetid://15765508905";UI.helpButton.ImageColor3=C.TEXT2;UI.helpButton.Visible=false;UI.helpButton.Parent=UI.titleBar
UI.dragArea=Instance.new("TextButton");UI.dragArea.BackgroundTransparency=1;UI.dragArea.BorderSizePixel=0;UI.dragArea.Text="";UI.dragArea.AutoButtonColor=false;UI.dragArea.Size=UDim2.new(1,0,1,0);UI.dragArea.ZIndex=3;UI.dragArea.Parent=UI.titleBar
UI.toast=Instance.new("Frame");UI.toast.AnchorPoint=Vector2.new(0.5,1);UI.toast.Position=UDim2.new(0.5,0,0,-6);UI.toast.Size=UDim2.new(0,310,0,56);UI.toast.BackgroundColor3=C.ELEVATED;UI.toast.BorderSizePixel=0;UI.toast.Visible=false;UI.toast.ZIndex=3;UI.toast.Parent=UI.main;mkC(14,UI.toast);mkS(1,C.BORDER_LIT,0.35,UI.toast)
UI.toastScale=Instance.new("UIScale");UI.toastScale.Scale=0;UI.toastScale.Parent=UI.toast
UI.toastBtn=Instance.new("TextButton");UI.toastBtn.Size=UDim2.new(1,0,1,0);UI.toastBtn.BackgroundTransparency=1;UI.toastBtn.Text="";UI.toastBtn.AutoButtonColor=false;UI.toastBtn.ZIndex=3;UI.toastBtn.Parent=UI.toast
UI.toastIconCircle=Instance.new("Frame");UI.toastIconCircle.AnchorPoint=Vector2.new(0,0.5);UI.toastIconCircle.Position=UDim2.new(0,14,0.5,0);UI.toastIconCircle.Size=UDim2.new(0,32,0,32);UI.toastIconCircle.BackgroundColor3=C.ACCENT;UI.toastIconCircle.BorderSizePixel=0;UI.toastIconCircle.ZIndex=3;UI.toastIconCircle.Parent=UI.toast;mkC(999,UI.toastIconCircle)
UI.toastPulse=Instance.new("Frame");UI.toastPulse.AnchorPoint=Vector2.new(0.5,0.5);UI.toastPulse.Position=UDim2.new(0.5,0,0.5,0);UI.toastPulse.Size=UDim2.new(1,0,1,0);UI.toastPulse.BackgroundColor3=C.TEXT;UI.toastPulse.BackgroundTransparency=1;UI.toastPulse.BorderSizePixel=0;UI.toastPulse.ZIndex=3;UI.toastPulse.Parent=UI.toastIconCircle;mkC(999,UI.toastPulse)
UI.toastIcon=Instance.new("TextLabel");UI.toastIcon.Size=UDim2.new(1,0,1,0);UI.toastIcon.BackgroundTransparency=1;UI.toastIcon.Font=Enum.Font.GothamBold;UI.toastIcon.Text="+";UI.toastIcon.TextColor3=C.BG;UI.toastIcon.TextSize=17;UI.toastIcon.ZIndex=3;UI.toastIcon.Parent=UI.toastIconCircle
UI.toastTitle=Instance.new("TextLabel");UI.toastTitle.AnchorPoint=Vector2.new(0,1);UI.toastTitle.Position=UDim2.new(0,56,0.5,-2);UI.toastTitle.Size=UDim2.new(1,-64,0,18);UI.toastTitle.BackgroundTransparency=1;UI.toastTitle.Font=Enum.Font.GothamSemibold;UI.toastTitle.Text="";UI.toastTitle.TextColor3=C.TEXT;UI.toastTitle.TextXAlignment=Enum.TextXAlignment.Left;UI.toastTitle.TextSize=13;UI.toastTitle.TextTruncate=Enum.TextTruncate.AtEnd;UI.toastTitle.ZIndex=3;UI.toastTitle.Parent=UI.toast
UI.toastSub=Instance.new("TextLabel");UI.toastSub.AnchorPoint=Vector2.new(0,0);UI.toastSub.Position=UDim2.new(0,56,0.5,2);UI.toastSub.Size=UDim2.new(1,-64,0,14);UI.toastSub.BackgroundTransparency=1;UI.toastSub.Font=Enum.Font.GothamMedium;UI.toastSub.Text="";UI.toastSub.TextColor3=C.ACCENT;UI.toastSub.TextXAlignment=Enum.TextXAlignment.Left;UI.toastSub.TextSize=11;UI.toastSub.ZIndex=3;UI.toastSub.Parent=UI.toast
UI.toastProgressTrack=Instance.new("Frame");UI.toastProgressTrack.AnchorPoint=Vector2.new(0,1);UI.toastProgressTrack.Position=UDim2.new(0,14,1,-5);UI.toastProgressTrack.Size=UDim2.new(1,-28,0,3);UI.toastProgressTrack.BackgroundColor3=C.BG;UI.toastProgressTrack.BorderSizePixel=0;UI.toastProgressTrack.ZIndex=3;UI.toastProgressTrack.Parent=UI.toast;mkC(999,UI.toastProgressTrack)
UI.toastProgressFill=Instance.new("Frame");UI.toastProgressFill.AnchorPoint=Vector2.new(0,0.5);UI.toastProgressFill.Position=UDim2.new(0,0,0.5,0);UI.toastProgressFill.Size=UDim2.new(1,0,1,0);UI.toastProgressFill.BackgroundColor3=C.ACCENT;UI.toastProgressFill.BorderSizePixel=0;UI.toastProgressFill.ZIndex=3;UI.toastProgressFill.Parent=UI.toastProgressTrack;mkC(999,UI.toastProgressFill)
UI.content=Instance.new("Frame");UI.content.Position=UDim2.new(0,14,0,40);UI.content.Size=UDim2.new(1,-28,1,-52);UI.content.BackgroundTransparency=1;UI.content.ZIndex=3;UI.content.Parent=UI.main
UI.settingsPage=Instance.new("Frame");UI.settingsPage.Position=UDim2.new(0,14,0,40);UI.settingsPage.Size=UDim2.new(1,-28,1,-52);UI.settingsPage.BackgroundTransparency=1;UI.settingsPage.ClipsDescendants=true;UI.settingsPage.ZIndex=3;UI.settingsPage.Visible=false;UI.settingsPage.Parent=UI.main
UI.settingsTabBar=Instance.new("Frame");UI.settingsTabBar.Size=UDim2.new(1,0,0,28);UI.settingsTabBar.BackgroundColor3=C.SURFACE;UI.settingsTabBar.BorderSizePixel=0;UI.settingsTabBar.ZIndex=4;UI.settingsTabBar.Parent=UI.settingsPage;mkC(9,UI.settingsTabBar);mkS(1,C.BORDER,0.15,UI.settingsTabBar)
local function mkTabBtn(nm,pos,txt,act,w) local b=Instance.new("TextButton");b.Name=nm;b.Position=pos;b.Size=UDim2.new(w or 0.333,0,1,0);b.BackgroundColor3=act and C.ELEVATED or C.SURFACE;b.AutoButtonColor=false;b.Font=act and Enum.Font.GothamSemibold or Enum.Font.GothamMedium;b.Text=txt;b.TextColor3=act and C.TEXT or C.TEXT2;b.TextSize=10;b.BorderSizePixel=0;b.ZIndex=5;b.Parent=UI.settingsTabBar;mkC(9,b);return b end
UI.settingsMainTabBtn=mkTabBtn("SettingsTabBtn",UDim2.new(0,0,0,0),"Settings",true,0.333)
UI.settingsDownloaderTabBtn=mkTabBtn("DownloaderTabBtn",UDim2.new(0.333,0,0,0),"MP3 Downloader",false,0.333)
UI.settingsScSearchTabBtn=mkTabBtn("ScSearchTabBtn",UDim2.new(0.667,0,0,0),"SC Search",false,0.334)
local tabDiv1=Instance.new("Frame");tabDiv1.AnchorPoint=Vector2.new(0.5,0.5);tabDiv1.Position=UDim2.new(0.333,0,0.5,0);tabDiv1.Size=UDim2.new(0,1,1,-8);tabDiv1.BackgroundColor3=C.BORDER;tabDiv1.BorderSizePixel=0;tabDiv1.ZIndex=6;tabDiv1.Parent=UI.settingsTabBar
local tabDiv2=Instance.new("Frame");tabDiv2.AnchorPoint=Vector2.new(0.5,0.5);tabDiv2.Position=UDim2.new(0.667,0,0.5,0);tabDiv2.Size=UDim2.new(0,1,1,-8);tabDiv2.BackgroundColor3=C.BORDER;tabDiv2.BorderSizePixel=0;tabDiv2.ZIndex=6;tabDiv2.Parent=UI.settingsTabBar
local tabInd=Instance.new("Frame");tabInd.AnchorPoint=Vector2.new(0,1);tabInd.Position=UDim2.new(0,6,1,-2);tabInd.Size=UDim2.new(0.333,-12,0,2);tabInd.BackgroundColor3=C.ACCENT;tabInd.BorderSizePixel=0;tabInd.ZIndex=6;tabInd.Parent=UI.settingsTabBar;mkC(999,tabInd)
UI.settingsMainScroll=Instance.new("ScrollingFrame");UI.settingsMainScroll.Position=UDim2.new(0,0,0,32);UI.settingsMainScroll.Size=UDim2.new(1,0,1,-32);UI.settingsMainScroll.BackgroundTransparency=1;UI.settingsMainScroll.BorderSizePixel=0;UI.settingsMainScroll.ScrollBarThickness=3;UI.settingsMainScroll.ScrollBarImageColor3=C.ACCENT;UI.settingsMainScroll.CanvasSize=UDim2.new(0,0,0,200);UI.settingsMainScroll.ScrollingDirection=Enum.ScrollingDirection.Y;UI.settingsMainScroll.ClipsDescendants=true;UI.settingsMainScroll.ZIndex=3;UI.settingsMainScroll.Visible=true;UI.settingsMainScroll.Parent=UI.settingsPage
UI.settingsDownloaderScroll=Instance.new("ScrollingFrame");UI.settingsDownloaderScroll.Position=UDim2.new(0,0,0,32);UI.settingsDownloaderScroll.Size=UDim2.new(1,0,1,-32);UI.settingsDownloaderScroll.BackgroundTransparency=1;UI.settingsDownloaderScroll.BorderSizePixel=0;UI.settingsDownloaderScroll.ScrollBarThickness=3;UI.settingsDownloaderScroll.ScrollBarImageColor3=C.ACCENT;UI.settingsDownloaderScroll.CanvasSize=UDim2.new(0,0,0,300);UI.settingsDownloaderScroll.ScrollingDirection=Enum.ScrollingDirection.Y;UI.settingsDownloaderScroll.ClipsDescendants=true;UI.settingsDownloaderScroll.ZIndex=3;UI.settingsDownloaderScroll.Visible=false;UI.settingsDownloaderScroll.Parent=UI.settingsPage
UI.settingsScSearchScroll=Instance.new("ScrollingFrame");UI.settingsScSearchScroll.Position=UDim2.new(0,0,0,32);UI.settingsScSearchScroll.Size=UDim2.new(1,0,1,-32);UI.settingsScSearchScroll.BackgroundTransparency=1;UI.settingsScSearchScroll.BorderSizePixel=0;UI.settingsScSearchScroll.ScrollBarThickness=3;UI.settingsScSearchScroll.ScrollBarImageColor3=C.ACCENT;UI.settingsScSearchScroll.CanvasSize=UDim2.new(0,0,0,400);UI.settingsScSearchScroll.ScrollingDirection=Enum.ScrollingDirection.Y;UI.settingsScSearchScroll.ClipsDescendants=true;UI.settingsScSearchScroll.ZIndex=3;UI.settingsScSearchScroll.Visible=false;UI.settingsScSearchScroll.Parent=UI.settingsPage
local resetDownloader
local function switchTab(tab)
St.settingsActiveTab=tab;local ct=TweenInfo.new(0.18,Enum.EasingStyle.Quad,Enum.EasingDirection.Out);local it=TweenInfo.new(0.22,Enum.EasingStyle.Back,Enum.EasingDirection.Out)
UI.settingsMainScroll.Visible=(tab=="main");UI.settingsDownloaderScroll.Visible=(tab=="downloader");UI.settingsScSearchScroll.Visible=(tab=="soundcloudSearch")
local function ta(btn,act) Svc.TS:Create(btn,ct,{BackgroundColor3=act and C.ELEVATED or C.SURFACE,TextColor3=act and C.TEXT or C.TEXT2}):Play() end
ta(UI.settingsMainTabBtn,tab=="main");ta(UI.settingsDownloaderTabBtn,tab=="downloader");ta(UI.settingsScSearchTabBtn,tab=="soundcloudSearch")
local indPos=tab=="main" and UDim2.new(0,6,1,-2) or tab=="downloader" and UDim2.new(0.333,6,1,-2) or UDim2.new(0.667,6,1,-2)
Svc.TS:Create(tabInd,it,{Position=indPos}):Play()
if tab=="downloader" then task.defer(function() if resetDownloader then resetDownloader() end end) end
end
UI.settingsMainTabBtn.MouseButton1Click:Connect(function() if St.settingsActiveTab~="main" then switchTab("main") end end)
UI.settingsDownloaderTabBtn.MouseButton1Click:Connect(function() if St.settingsActiveTab~="downloader" then switchTab("downloader") end end)
UI.settingsScSearchTabBtn.MouseButton1Click:Connect(function() if St.settingsActiveTab~="soundcloudSearch" then switchTab("soundcloudSearch") end end)
UI.settingsMainTabBtn.MouseEnter:Connect(function() if St.settingsActiveTab~="main" then UI.settingsMainTabBtn.TextColor3=C.TEXT end end);UI.settingsMainTabBtn.MouseLeave:Connect(function() if St.settingsActiveTab~="main" then UI.settingsMainTabBtn.TextColor3=C.TEXT2 end end)
UI.settingsDownloaderTabBtn.MouseEnter:Connect(function() if St.settingsActiveTab~="downloader" then UI.settingsDownloaderTabBtn.TextColor3=C.TEXT end end);UI.settingsDownloaderTabBtn.MouseLeave:Connect(function() if St.settingsActiveTab~="downloader" then UI.settingsDownloaderTabBtn.TextColor3=C.TEXT2 end end)
UI.settingsScSearchTabBtn.MouseEnter:Connect(function() if St.settingsActiveTab~="soundcloudSearch" then UI.settingsScSearchTabBtn.TextColor3=C.TEXT end end);UI.settingsScSearchTabBtn.MouseLeave:Connect(function() if St.settingsActiveTab~="soundcloudSearch" then UI.settingsScSearchTabBtn.TextColor3=C.TEXT2 end end)
local function mkSRow(yp,lbl,par) local row=Instance.new("Frame");row.Position=UDim2.new(0,0,0,yp);row.Size=UDim2.new(1,0,0,26);row.BackgroundTransparency=1;row.ZIndex=3;row.Parent=par;local l=Instance.new("TextLabel");l.Position=UDim2.new(0,0,0,0);l.Size=UDim2.new(0.58,0,1,0);l.BackgroundTransparency=1;l.Font=Enum.Font.Gotham;l.Text=lbl;l.TextColor3=C.TEXT2;l.TextXAlignment=Enum.TextXAlignment.Left;l.TextSize=13;l.ZIndex=3;l.Parent=row;return row end
local function mkSCtrl(par,isBox) local c;if isBox then c=Instance.new("TextBox") else c=Instance.new("TextButton");c.AutoButtonColor=false end;c.AnchorPoint=Vector2.new(1,0.5);c.Position=UDim2.new(1,0,0.5,0);c.Size=UDim2.new(0,82,0,24);c.BackgroundColor3=C.SURFACE;c.BorderSizePixel=0;c.Font=Enum.Font.GothamMedium;c.TextSize=12;c.TextColor3=C.TEXT2;c.ZIndex=3;c.Parent=par;mkC(9,c);mkS(1,C.BORDER,0.2,c);return c end
local shakeOC,crossRow,lyrRow,cinematicRow,notifRow,muteRow;local themeExp=false
local stopCinematicMode
local kbPanelExp=false
local function updSCanvas() local shx=St.screenShakeEnabled and Cfg.SHOH or 0;local thh=themeExp and Cfg.TPEH or Cfg.TPCH;local lyx=St.lyricsEnabled and 28 or 0;local kbh=kbPanelExp and (Cfg.TPCH+10*(Cfg.TRH+4)+8) or Cfg.TPCH;UI.settingsMainScroll.CanvasSize=UDim2.new(0,0,0,154+lyx+shx+thh+6+kbh+16) end
local shakeRowUI=mkSRow(8,"Screen Shake (Visualizer)",UI.settingsMainScroll);UI.shakeToggle=mkSCtrl(shakeRowUI,false);UI.shakeToggle.Text=""
local function refShake()
local ct=TweenInfo.new(0.22,Enum.EasingStyle.Quad,Enum.EasingDirection.Out);local ti=TweenInfo.new(0.18,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
if St.screenShakeEnabled then Svc.TS:Create(UI.shakeToggle,ct,{BackgroundColor3=C.ACCENT}):Play();Svc.TS:Create(UI.shakeToggle,ct,{TextColor3=AT}):Play();UI.shakeToggle.Text="on"
else Svc.TS:Create(UI.shakeToggle,ct,{BackgroundColor3=C.SURFACE}):Play();Svc.TS:Create(UI.shakeToggle,ct,{TextColor3=C.TEXT3}):Play();UI.shakeToggle.Text="off" end
local off=St.screenShakeEnabled and Cfg.SHOH or 0
if shakeOC then Svc.TS:Create(shakeOC,ti,{Size=UDim2.new(1,0,0,St.screenShakeEnabled and Cfg.SHOH or 0)}):Play() end
if crossRow then Svc.TS:Create(crossRow,ti,{Position=UDim2.new(0,0,0,40+off)}):Play() end
if lyrRow then Svc.TS:Create(lyrRow,ti,{Position=UDim2.new(0,0,0,68+off)}):Play() end
if cinematicRow then
local cv=St.lyricsEnabled and 1 or 0
Svc.TS:Create(cinematicRow,ti,{Position=UDim2.new(0,0,0,96+off),Size=UDim2.new(1,0,0,26*cv)}):Play()
end
if notifRow then Svc.TS:Create(notifRow,ti,{Position=UDim2.new(0,0,0,(St.lyricsEnabled and 124 or 96)+off)}):Play() end
if muteRow then Svc.TS:Create(muteRow,ti,{Position=UDim2.new(0,0,0,(St.lyricsEnabled and 152 or 124)+off)}):Play() end
if UI.themePanel then Svc.TS:Create(UI.themePanel,ti,{Position=UDim2.new(0,0,0,(St.lyricsEnabled and 182 or 154)+off)}):Play() end
if UI.kbPanel then local thH=themeExp and Cfg.TPEH or Cfg.TPCH;local lyx=St.lyricsEnabled and 28 or 0;Svc.TS:Create(UI.kbPanel,ti,{Position=UDim2.new(0,0,0,154+lyx+off+thH+6)}):Play() end
updSCanvas()
end
UI.shakeToggle.MouseButton1Click:Connect(function() St.screenShakeEnabled=not St.screenShakeEnabled;shakeVal.Value=St.screenShakeEnabled;refShake();saveSettings() end)
shakeVal.Changed:Connect(function(v) if St.screenShakeEnabled~=v then St.screenShakeEnabled=v;refShake() end end)
shakeOC=Instance.new("Frame");shakeOC.Position=UDim2.new(0,0,0,40);shakeOC.Size=UDim2.new(1,0,0,0);shakeOC.BackgroundTransparency=1;shakeOC.ClipsDescendants=true;shakeOC.ZIndex=3;shakeOC.Parent=UI.settingsMainScroll
local siRow=mkSRow(2,"Shake Intensity",shakeOC);UI.shakeIntensityBox=mkSCtrl(siRow,true);UI.shakeIntensityBox.Text=tostring(St.shakeIntensity);UI.shakeIntensityBox.ClearTextOnFocus=false
UI.shakeIntensityBox.Focused:Connect(function() UI.shakeIntensityBox.Text="" end);UI.shakeIntensityBox.FocusLost:Connect(function() local n=tonumber(UI.shakeIntensityBox.Text);if n and n>=0 and n<=5 then St.shakeIntensity=n;UI.shakeIntensityBox.Text=tostring(n);saveSettings() else UI.shakeIntensityBox.Text=tostring(St.shakeIntensity) end end)
local fiRow=mkSRow(30,"FOV Intensity",shakeOC);UI.fovIntensityBox=mkSCtrl(fiRow,true);UI.fovIntensityBox.Text=tostring(St.fovIntensity);UI.fovIntensityBox.ClearTextOnFocus=false
UI.fovIntensityBox.Focused:Connect(function() UI.fovIntensityBox.Text="" end);UI.fovIntensityBox.FocusLost:Connect(function() local n=tonumber(UI.fovIntensityBox.Text);if n and n>=0 and n<=5 then St.fovIntensity=n;UI.fovIntensityBox.Text=tostring(n);saveSettings() else UI.fovIntensityBox.Text=tostring(St.fovIntensity) end end)
if kbRow then end
crossRow=mkSRow(40,"Crossfade Tracks",UI.settingsMainScroll);UI.crossToggle=mkSCtrl(crossRow,false);UI.crossToggle.Text=""
local function refCross() local ct=TweenInfo.new(0.22,Enum.EasingStyle.Quad,Enum.EasingDirection.Out);if St.crossfadeEnabled then Svc.TS:Create(UI.crossToggle,ct,{BackgroundColor3=C.ACCENT}):Play();Svc.TS:Create(UI.crossToggle,ct,{TextColor3=AT}):Play();UI.crossToggle.Text="on" else Svc.TS:Create(UI.crossToggle,ct,{BackgroundColor3=C.SURFACE}):Play();Svc.TS:Create(UI.crossToggle,ct,{TextColor3=C.TEXT3}):Play();UI.crossToggle.Text="off" end end
UI.crossToggle.MouseButton1Click:Connect(function() St.crossfadeEnabled=not St.crossfadeEnabled;refCross();saveSettings() end)
lyrRow=mkSRow(68,"Show Synced Lyrics",UI.settingsMainScroll);UI.lyricsToggleBtn=mkSCtrl(lyrRow,false);UI.lyricsToggleBtn.Text="off"
local function refLyrics()
local ct=TweenInfo.new(0.22,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
if St.lyricsEnabled then Svc.TS:Create(UI.lyricsToggleBtn,ct,{BackgroundColor3=C.ACCENT}):Play();Svc.TS:Create(UI.lyricsToggleBtn,ct,{TextColor3=AT}):Play();UI.lyricsToggleBtn.Text="on"
else Svc.TS:Create(UI.lyricsToggleBtn,ct,{BackgroundColor3=C.SURFACE}):Play();Svc.TS:Create(UI.lyricsToggleBtn,ct,{TextColor3=C.TEXT3}):Play();UI.lyricsToggleBtn.Text="off" end
end
local refCinematic
local _lyricsTween=nil;local showLyricsGui,hideLyricsGui
showLyricsGui=function()
if not lyricsOverlay or not lyricsOverlay.gui or not lyricsOverlay.frame then return end
if _lyricsTween then _lyricsTween:Cancel();_lyricsTween=nil end
lyricsOverlay.gui.Enabled=true
lyricsOverlay.frame.Position=UDim2.new(0.5,0,1.3,0)
_lyricsTween=Svc.TS:Create(lyricsOverlay.frame,TweenInfo.new(0.8,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{Position=UDim2.new(0.5,0,0.87,0)})
_lyricsTween:Play()
end
hideLyricsGui=function(onDone)
if not lyricsOverlay or not lyricsOverlay.frame then return end
if _lyricsTween then _lyricsTween:Cancel();_lyricsTween=nil end
_lyricsTween=Svc.TS:Create(lyricsOverlay.frame,TweenInfo.new(0.6,Enum.EasingStyle.Quad,Enum.EasingDirection.In),{Position=UDim2.new(0.5,0,1.3,0)})
_lyricsTween.Completed:Connect(function(s)
if s==Enum.TweenStatus.Completed then
if lyricsOverlay and lyricsOverlay.gui then lyricsOverlay.gui.Enabled=false end
if onDone then onDone() end
end
end)
_lyricsTween:Play()
end
UI.lyricsToggleBtn.MouseButton1Click:Connect(function()
St.lyricsEnabled=not St.lyricsEnabled;refLyrics();saveSettings()
if St.lyricsEnabled then
local inf=Dat.trackList[St.currentTrackIndex];if inf then Dat.lyricsFetchGen=Dat.lyricsFetchGen+1;fetchLyrics(inf.DisplayName,Dat.lyricsFetchGen) end
refCinematic()
if St.cinematicMode then
if lyricsOverlay and lyricsOverlay.gui then lyricsOverlay.gui.Enabled=false end
task.defer(function() startCinematicMode() end)
else showLyricsGui() end
else
clearLyrics()
if St.cinematicMode then St.cinematicMode=false;stopCinematicMode();refCinematic();saveSettings()
else hideLyricsGui() end
end
local ti=TweenInfo.new(0.18,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
if cinematicRow then Svc.TS:Create(cinematicRow,ti,{Size=UDim2.new(1,0,0,St.lyricsEnabled and 26 or 0)}):Play() end
local off=St.screenShakeEnabled and Cfg.SHOH or 0
local extra=St.lyricsEnabled and 28 or 0
if notifRow then Svc.TS:Create(notifRow,ti,{Position=UDim2.new(0,0,0,96+extra+off)}):Play() end
if muteRow then Svc.TS:Create(muteRow,ti,{Position=UDim2.new(0,0,0,124+extra+off)}):Play() end
if UI.themePanel then Svc.TS:Create(UI.themePanel,ti,{Position=UDim2.new(0,0,0,154+extra+off)}):Play() end
if UI.kbPanel then local thH=themeExp and Cfg.TPEH or Cfg.TPCH;Svc.TS:Create(UI.kbPanel,ti,{Position=UDim2.new(0,0,0,154+extra+off+thH+6)}):Play() end
updSCanvas()
end)
cinematicRow=mkSRow(96,"Cinematic Mode",UI.settingsMainScroll)
cinematicRow.Size=UDim2.new(1,0,0,St.lyricsEnabled and 26 or 0)
cinematicRow.ClipsDescendants=true
UI.cinematicBtn=mkSCtrl(cinematicRow,false);UI.cinematicBtn.Text="off"
stopCinematicMode=function()
St.cinematicMode=false;_cinLocked=false
if not _cinGui then
if St.lyricsEnabled then showLyricsGui() end;return
end
local sg=_cinGui;_cinGui=nil
for _,ch in ipairs(sg:GetChildren()) do
if ch:IsA("TextLabel") then
Svc.TS:Create(ch,TweenInfo.new(0.35,Enum.EasingStyle.Quad),{TextTransparency=1}):Play()
end
end
local topBar=sg:FindFirstChild("TopCinBar");local botBar=sg:FindFirstChild("BotCinBar")
local exitTI=TweenInfo.new(1.2,Enum.EasingStyle.Sine,Enum.EasingDirection.In)
task.delay(0.3,function()
if topBar then Svc.TS:Create(topBar,exitTI,{Position=UDim2.new(0,0,-0.6,0)}):Play() end
if botBar then Svc.TS:Create(botBar,exitTI,{Position=UDim2.new(0,0,1.6,0)}):Play() end
end)
task.delay(1.0,function()
if St.lyricsEnabled then showLyricsGui() end
end)
task.delay(1.6,function() pcall(function() sg:Destroy() end) end)
end
local function startCinematicMode()
if not St.lyricsEnabled or not lyricsOverlay then return end
St.cinematicMode=true
if _lyricsTween then _lyricsTween:Cancel();_lyricsTween=nil end
_lyricsTween=Svc.TS:Create(lyricsOverlay.frame,TweenInfo.new(1.0,Enum.EasingStyle.Quad,Enum.EasingDirection.In),{Position=UDim2.new(0.5,0,1.3,0)})
_lyricsTween:Play()
task.delay(1.0,function()
if not St.cinematicMode then return end
lyricsOverlay.gui.Enabled=false
local sg=Instance.new("ScreenGui");sg.Name="CinematicModeGui";sg.IgnoreGuiInset=true;sg.ResetOnSpawn=false;sg.DisplayOrder=2147483646;sg.Parent=pGui;_cinGui=sg
local topBar=Instance.new("Frame");topBar.Name="TopCinBar";topBar.Size=UDim2.new(1,0,0.12,0);topBar.Position=UDim2.new(0,0,-0.12,0);topBar.BackgroundColor3=Color3.new(0,0,0);topBar.BorderSizePixel=0;topBar.ZIndex=100;topBar.Parent=sg
local botBar=Instance.new("Frame");botBar.Name="BotCinBar";botBar.Size=UDim2.new(1,0,0.12,0);botBar.Position=UDim2.new(0,0,1.12,0);botBar.AnchorPoint=Vector2.new(0,1);botBar.BackgroundColor3=Color3.new(0,0,0);botBar.BorderSizePixel=0;botBar.ZIndex=100;botBar.Parent=sg
local si=TweenInfo.new(0.9,Enum.EasingStyle.Quart,Enum.EasingDirection.Out)
Svc.TS:Create(topBar,si,{Position=UDim2.new(0,0,0,0)}):Play()
Svc.TS:Create(botBar,si,{Position=UDim2.new(0,0,1,0)}):Play()
local lastShownLine=-1
local cinConn;cinConn=Svc.RS.Heartbeat:Connect(function()
if not St.cinematicMode or not _cinGui or not _cinGui.Parent then cinConn:Disconnect();return end
local lyr=Dat.currentLyrics;if #lyr==0 then return end
local s=sound;if not s or not s.IsPlaying then return end
local pos=s.TimePosition
local ci2=0
for i,e in ipairs(lyr) do if pos>=e.time then ci2=i else break end end
if ci2==0 or ci2==lastShownLine then return end
lastShownLine=ci2
local entry=lyr[ci2];if not entry then return end
local text=St.translateEnabled and (Dat.translateCache[entry.text] or entry.text) or entry.text
for _,ch in ipairs(sg:GetChildren()) do if ch:IsA("TextLabel") then pcall(function() ch:Destroy() end) end end
local vp=Svc.WS.CurrentCamera and Svc.WS.CurrentCamera.ViewportSize or Vector2.new(1920,1080)
local xPos={0.04,0.12,0.35,0.52,0.65};local yPos={0.22,0.32,0.44,0.54,0.63}
local xi=((ci2-1)%#xPos)+1;local yi=((ci2*3)%#yPos)+1
local maxW=math.floor(vp.X*0.90);local startX=math.max(20,math.floor(xPos[xi]*vp.X))
if startX+maxW>vp.X-20 then startX=math.max(20,math.floor(vp.X-maxW-20)) end
local lbl=Instance.new("TextLabel");lbl.Size=UDim2.new(0,maxW,0,200);lbl.Position=UDim2.fromOffset(startX,math.floor(yPos[yi]*vp.Y));lbl.AnchorPoint=Vector2.new(0,0)
lbl.BackgroundTransparency=1;lbl.Font=Enum.Font.GothamBold;lbl.Text=text;lbl.TextColor3=C.TEXT;lbl.TextSize=54;lbl.RichText=false;lbl.TextXAlignment=Enum.TextXAlignment.Left;lbl.TextTransparency=1;lbl.TextStrokeTransparency=1;lbl.TextStrokeColor3=C.BG;lbl.ZIndex=101;lbl.TextWrapped=true;lbl.Parent=sg
Svc.TS:Create(lbl,TweenInfo.new(0.15),{TextTransparency=0,TextStrokeTransparency=0.4}):Play()
local lineEnd=(ci2<#lyr) and lyr[ci2+1].time or (s.TimeLength or (entry.time+3))
local dur=math.max(0.5,(lineEnd-entry.time)-0.2)
task.delay(dur,function() if lbl and lbl.Parent then local tw=Svc.TS:Create(lbl,TweenInfo.new(0.25),{TextTransparency=1,TextStrokeTransparency=1});tw.Completed:Connect(function() pcall(function() lbl:Destroy() end) end);tw:Play() end end)
end)
end)
end
refCinematic=function()
local ct=TweenInfo.new(0.22,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
if St.cinematicMode then Svc.TS:Create(UI.cinematicBtn,ct,{BackgroundColor3=C.ACCENT}):Play();Svc.TS:Create(UI.cinematicBtn,ct,{TextColor3=AT}):Play();UI.cinematicBtn.Text="on"
else Svc.TS:Create(UI.cinematicBtn,ct,{BackgroundColor3=C.SURFACE}):Play();Svc.TS:Create(UI.cinematicBtn,ct,{TextColor3=C.TEXT3}):Play();UI.cinematicBtn.Text="off" end
end
local _cinLocked=false
UI.cinematicBtn.MouseButton1Click:Connect(function()
if not St.lyricsEnabled or _cinLocked then return end
_cinLocked=true
St.cinematicMode=not St.cinematicMode;refCinematic();saveSettings()
if St.cinematicMode then
startCinematicMode()
task.delay(2.2,function() _cinLocked=false end)
else
stopCinematicMode()
task.delay(2.8,function() _cinLocked=false end)
end
end)
refCinematic()
refCross();refShake();refLyrics()
notifRow=mkSRow(96,"Notification Volume",UI.settingsMainScroll);UI.notifVolumeBox=mkSCtrl(notifRow,true);UI.notifVolumeBox.Text=tostring(St.notifVolume);UI.notifVolumeBox.ClearTextOnFocus=false
UI.notifVolumeBox.Focused:Connect(function() UI.notifVolumeBox.Text="" end);UI.notifVolumeBox.FocusLost:Connect(function() local n=tonumber(UI.notifVolumeBox.Text);if n and n>=0 and n<=1 then St.notifVolume=n;UI.notifVolumeBox.Text=tostring(n);saveSettings() else UI.notifVolumeBox.Text=tostring(St.notifVolume) end end)
muteRow=mkSRow(124,"Mute In-Game Sounds",UI.settingsMainScroll);UI.muteGameBtn=mkSCtrl(muteRow,false);UI.muteGameBtn.Text="off"
do
local savedVols={};local muteConns={};local muteDescConn=nil
local function muteOne(s) if not s or not s:IsA("Sound") then return end;if s.Parent and s.Parent.Name=="MusicControllerSounds" then return end;if savedVols[s] then return end;savedVols[s]=s.Volume;pcall(function() s.Volume=0 end);local conn=s:GetPropertyChangedSignal("Volume"):Connect(function() if St.muteGameSounds and s.Volume~=0 then pcall(function() s.Volume=0 end) end end);table.insert(muteConns,conn) end
local function muteAllNow() for _,s in ipairs(game:GetDescendants()) do if s:IsA("Sound") and (not s.Parent or s.Parent.Name~="MusicControllerSounds") then muteOne(s) end end;muteDescConn=game.DescendantAdded:Connect(function(obj) if obj:IsA("Sound") then task.defer(function() muteOne(obj) end) end end);_G.__MCMuteCleanup=function() if muteDescConn then muteDescConn:Disconnect();muteDescConn=nil end;for _,c in ipairs(muteConns) do pcall(function() c:Disconnect() end) end;muteConns={};savedVols={} end end
local function restoreAll() if muteDescConn then muteDescConn:Disconnect();muteDescConn=nil end;for _,c in ipairs(muteConns) do pcall(function() c:Disconnect() end) end;muteConns={};for s,vol in pairs(savedVols) do pcall(function() if s and s.Parent then s.Volume=vol end end) end;savedVols={};_G.__MCMuteCleanup=nil end
local function refMuteBtn() local ct=TweenInfo.new(0.22,Enum.EasingStyle.Quad,Enum.EasingDirection.Out);if St.muteGameSounds then Svc.TS:Create(UI.muteGameBtn,ct,{BackgroundColor3=C.ACCENT}):Play();Svc.TS:Create(UI.muteGameBtn,ct,{TextColor3=AT}):Play();UI.muteGameBtn.Text="on";task.spawn(muteAllNow) else Svc.TS:Create(UI.muteGameBtn,ct,{BackgroundColor3=C.SURFACE}):Play();Svc.TS:Create(UI.muteGameBtn,ct,{TextColor3=C.TEXT3}):Play();UI.muteGameBtn.Text="off";restoreAll() end end
UI.muteGameBtn.MouseButton1Click:Connect(function() St.muteGameSounds=not St.muteGameSounds;refMuteBtn();saveSettings() end);refMuteBtn()
_G.__MCRefMute=refMuteBtn
end
local function refTranslate()
if _G.__MCRefTranslatePill then _G.__MCRefTranslatePill() end
end
refTranslate()
local TCOLS={{key="ACCENT",label="Accent"},{key="ACCENT_DIM",label="Accent Dim"},{key="BG",label="Background"},{key="SURFACE",label="Surface"},{key="ELEVATED",label="Elevated"},{key="BORDER",label="Border"},{key="BORDER_LIT",label="Border Lit"},{key="TEXT",label="Text"},{key="TEXT2",label="Text Secondary"},{key="TEXT3",label="Text Muted"},{key="SUCCESS",label="Success"},{key="DANGER",label="Danger"}}
Cfg.TPEH=Cfg.TPCH+#TCOLS*(Cfg.TRH+4)+8
local function h2c3(h) h=h:gsub("^#",""):gsub("^0x","");if #h~=6 then return nil end;local r,g,b=tonumber(h:sub(1,2),16),tonumber(h:sub(3,4),16),tonumber(h:sub(5,6),16);if not(r and g and b) then return nil end;return Color3.fromRGB(r,g,b) end
local function c32h(c) return string.format("%02X%02X%02X",math.floor(c.R*255+0.5),math.floor(c.G*255+0.5),math.floor(c.B*255+0.5)) end
local function applyTheme()
if UI.main then mkS(1,C.BORDER_LIT,0.25,UI.main) end
for _,p in ipairs({UI.listPanel,UI.queuePanel}) do if p then for _,ch in ipairs(p:GetChildren()) do if ch:IsA("UIStroke") then ch.Color=C.BORDER_LIT end end end end
for _,sf in ipairs({UI.listScroll,UI.queueScroll,UI.settingsMainScroll,UI.settingsDownloaderScroll,UI.settingsScSearchScroll}) do if sf then sf.ScrollBarImageColor3=C.ACCENT end end
for _,b in ipairs({UI.toggleListBtn,UI.toggleQueueBtn}) do if b then b.BackgroundColor3=C.ELEVATED;b.TextColor3=C.ACCENT end end
if UI.addCategoryBtn then UI.addCategoryBtn.BackgroundColor3=C.ELEVATED;local lb=UI.addCategoryBtn:FindFirstChild("Label");if lb then lb.TextColor3=C.TEXT2 end end
if UI.titleLabel then UI.titleLabel.TextColor3=C.TEXT end;if UI.settingsButton then UI.settingsButton.ImageColor3=C.TEXT2 end
if UI.searchIconBtn then UI.searchIconBtn.ImageColor3=St.searchActive and C.ACCENT or C.TEXT2;UI.searchIconBtn.BackgroundColor3=St.searchActive and C.ACCENT_DIM or C.ELEVATED end
if UI.searchBox then UI.searchBox.BackgroundColor3=C.SURFACE;UI.searchBox.TextColor3=C.TEXT;UI.searchBox.PlaceholderColor3=C.TEXT3 end
if UI.currentTrackButton then UI.currentTrackButton.TextColor3=C.TEXT end;if UI.nextTrackLabel then UI.nextTrackLabel.TextColor3=C.TEXT end
if UI.playPauseBtn then if St.isPaused then UI.playPauseBtn.BackgroundColor3=C.ACCENT;UI.playPauseBtn.TextColor3=AT else UI.playPauseBtn.BackgroundColor3=C.ELEVATED;UI.playPauseBtn.TextColor3=C.TEXT end end
for _,b in ipairs({UI.prevBtn,UI.nextBtn}) do if b then b.BackgroundColor3=C.SURFACE;b.TextColor3=C.TEXT2 end end
if UI.repeatToggle then UI.repeatToggle.RefreshTheme() end;if UI.shuffleToggle then UI.shuffleToggle.RefreshTheme() end
if UI.progressBar then UI.progressBar.BackgroundColor3=C.ELEVATED end;if UI.progressFill then UI.progressFill.BackgroundColor3=C.ACCENT end
if UI.timeDisplay then UI.timeDisplay.TextColor3=C.TEXT3 end;if UI.nextTimeDisplay then UI.nextTimeDisplay.TextColor3=C.TEXT3 end
for _,b in ipairs(Dat.meterBars) do b.BackgroundColor3=C.ACCENT end
if UI.themePanel then UI.themePanel.BackgroundColor3=C.SURFACE end
if UI.settingsTabBar then UI.settingsTabBar.BackgroundColor3=C.SURFACE end;if tabInd then tabInd.BackgroundColor3=C.ACCENT end
if UI.dlButton then UI.dlButton.BackgroundColor3=C.ACCENT;UI.dlButton.TextColor3=AT end
if UI.scSearchBtn then UI.scSearchBtn.BackgroundColor3=C.ACCENT;UI.scSearchBtn.TextColor3=AT end
if UI.cinematicBtn then if St.cinematicMode then UI.cinematicBtn.BackgroundColor3=C.ACCENT;UI.cinematicBtn.TextColor3=AT else UI.cinematicBtn.BackgroundColor3=C.SURFACE;UI.cinematicBtn.TextColor3=C.TEXT3 end end
if lyricsOverlay then
lyricsOverlay.pill.BackgroundColor3=C.BG;for _,s in ipairs(lyricsOverlay.pill:GetChildren()) do if s:IsA("UIStroke") then s.Color=C.BORDER_LIT end end
if lyricsOverlay.pillGrad then lyricsOverlay.pillGrad.Color=ColorSequence.new({ColorSequenceKeypoint.new(0,C.ELEVATED),ColorSequenceKeypoint.new(1,C.BG)}) end
lyricsOverlay.prev.TextColor3=C.TEXT2;lyricsOverlay.current.TextColor3=C.TEXT;lyricsOverlay.next.TextColor3=C.TEXT2;lyricsOverlay.underline.BackgroundColor3=C.ACCENT;lyricsOverlay.noResults.TextColor3=C.TEXT3
local fl=lyricsOverlay.underline:FindFirstChild("FadeL");if fl then fl.BackgroundColor3=C.BG end;local fr2=lyricsOverlay.underline:FindFirstChild("FadeR");if fr2 then fr2.BackgroundColor3=C.BG end
end
end
UI.themePanel=Instance.new("Frame");UI.themePanel.Position=UDim2.new(0,0,0,154);UI.themePanel.Size=UDim2.new(1,0,0,Cfg.TPCH);UI.themePanel.BackgroundColor3=C.SURFACE;UI.themePanel.BorderSizePixel=0;UI.themePanel.ClipsDescendants=true;UI.themePanel.ZIndex=3;UI.themePanel.Parent=UI.settingsMainScroll;mkC(10,UI.themePanel);mkS(1,C.BORDER,0.15,UI.themePanel)
local thHdr=Instance.new("TextButton");thHdr.Size=UDim2.new(1,0,0,Cfg.TPCH);thHdr.BackgroundTransparency=1;thHdr.AutoButtonColor=false;thHdr.Font=Enum.Font.GothamMedium;thHdr.Text="";thHdr.ZIndex=4;thHdr.Parent=UI.themePanel
local thHL=Instance.new("TextLabel");thHL.AnchorPoint=Vector2.new(0,0.5);thHL.Position=UDim2.new(0,12,0.5,0);thHL.Size=UDim2.new(0.6,0,1,0);thHL.BackgroundTransparency=1;thHL.Font=Enum.Font.GothamMedium;thHL.Text="Theme Colors";thHL.TextColor3=C.TEXT2;thHL.TextXAlignment=Enum.TextXAlignment.Left;thHL.TextSize=13;thHL.ZIndex=4;thHL.Parent=thHdr
local thCh=Instance.new("TextLabel");thCh.AnchorPoint=Vector2.new(1,0.5);thCh.Position=UDim2.new(1,-12,0.5,0);thCh.Size=UDim2.new(0,20,1,0);thCh.BackgroundTransparency=1;thCh.Font=Enum.Font.GothamBold;thCh.Text="v";thCh.TextColor3=C.TEXT3;thCh.TextXAlignment=Enum.TextXAlignment.Right;thCh.TextSize=12;thCh.ZIndex=4;thCh.Parent=thHdr
local thSep=Instance.new("Frame");thSep.Position=UDim2.new(0,10,0,Cfg.TPCH-1);thSep.Size=UDim2.new(1,-20,0,1);thSep.BackgroundColor3=C.BORDER;thSep.BorderSizePixel=0;thSep.ZIndex=3;thSep.Parent=UI.themePanel
local thScr=Instance.new("ScrollingFrame");thScr.Position=UDim2.new(0,0,0,Cfg.TPCH+2);thScr.Size=UDim2.new(1,0,1,-(Cfg.TPCH+2));thScr.BackgroundTransparency=1;thScr.BorderSizePixel=0;thScr.ScrollBarThickness=3;thScr.ScrollBarImageColor3=C.ACCENT;thScr.CanvasSize=UDim2.new(0,0,0,0);thScr.ZIndex=3;thScr.Parent=UI.themePanel
local thRL=Instance.new("UIListLayout");thRL.Padding=UDim.new(0,4);thRL.SortOrder=Enum.SortOrder.LayoutOrder;thRL.Parent=thScr
local thRP=Instance.new("UIPadding");thRP.PaddingTop=UDim.new(0,4);thRP.PaddingLeft=UDim.new(0,8);thRP.PaddingRight=UDim.new(0,8);thRP.Parent=thScr
thRL:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function() thScr.CanvasSize=UDim2.new(0,0,0,thRL.AbsoluteContentSize.Y+10) end)
for i,cd in ipairs(TCOLS) do
local row=Instance.new("Frame");row.Size=UDim2.new(1,0,0,Cfg.TRH);row.BackgroundColor3=C.ELEVATED;row.BorderSizePixel=0;row.LayoutOrder=i;row.ZIndex=3;row.Parent=thScr;mkC(7,row)
local sw=Instance.new("Frame");sw.AnchorPoint=Vector2.new(0,0.5);sw.Position=UDim2.new(0,8,0.5,0);sw.Size=UDim2.new(0,16,0,16);sw.BackgroundColor3=C[cd.key];sw.BorderSizePixel=0;sw.ZIndex=4;sw.Parent=row;mkC(5,sw);mkS(1,C.BORDER,0.2,sw)
local rl=Instance.new("TextLabel");rl.AnchorPoint=Vector2.new(0,0.5);rl.Position=UDim2.new(0,32,0.5,0);rl.Size=UDim2.new(0,90,1,0);rl.BackgroundTransparency=1;rl.Font=Enum.Font.GothamMedium;rl.Text=cd.label;rl.TextColor3=C.TEXT2;rl.TextXAlignment=Enum.TextXAlignment.Left;rl.TextSize=12;rl.ZIndex=4;rl.Parent=row
local hb=Instance.new("TextBox");hb.AnchorPoint=Vector2.new(1,0.5);hb.Position=UDim2.new(1,-8,0.5,0);hb.Size=UDim2.new(0,80,0,20);hb.BackgroundColor3=C.SURFACE;hb.BorderSizePixel=0;hb.Font=Enum.Font.GothamMedium;hb.Text="#"..c32h(C[cd.key]);hb.PlaceholderText="#RRGGBB";hb.PlaceholderColor3=C.TEXT3;hb.TextColor3=C.ACCENT;hb.TextXAlignment=Enum.TextXAlignment.Center;hb.TextSize=11;hb.ClearTextOnFocus=false;hb.ZIndex=4;hb.Parent=row;mkC(6,hb);mkS(1,C.BORDER,0.25,hb)
local k=cd.key;hb.Focused:Connect(function() hb.Text=hb.Text:gsub("^#","") end)
hb.FocusLost:Connect(function() local raw=hb.Text:gsub("^#",""):gsub("%s","");local nc=h2c3(raw);if nc then C[k]=nc;sw.BackgroundColor3=nc;hb.Text="#"..c32h(nc);hb.TextColor3=C.ACCENT;applyTheme() else hb.Text="#"..c32h(C[k]);hb.TextColor3=C.DANGER;task.delay(1.2,function() hb.TextColor3=C.ACCENT end) end end)
end
local thAnim=false
thHdr.MouseButton1Click:Connect(function()
if thAnim then return end;thAnim=true;themeExp=not themeExp;thCh.Text=themeExp and "^" or "v";local th=themeExp and Cfg.TPEH or Cfg.TPCH
local ti=TweenInfo.new(0.22,Enum.EasingStyle.Quad,Enum.EasingDirection.Out)
local tw=Svc.TS:Create(UI.themePanel,ti,{Size=UDim2.new(1,0,0,th)})
tw.Completed:Connect(function() thAnim=false;updSCanvas() end);tw:Play()
if UI.kbPanel then
local shx=St.screenShakeEnabled and Cfg.SHOH or 0;local lyx=St.lyricsEnabled and 28 or 0
Svc.TS:Create(UI.kbPanel,ti,{Position=UDim2.new(0,0,0,154+lyx+shx+th+6)}):Play()
end
end)
thHdr.MouseEnter:Connect(function() thHL.TextColor3=C.TEXT end);thHdr.MouseLeave:Connect(function() thHL.TextColor3=C.TEXT2 end)
do
local KB_ROWS=10;local KBCH=Cfg.TPCH;local KBEH=KBCH+KB_ROWS*(Cfg.TRH+4)+8
local function getKbPanelY() local shx=St.screenShakeEnabled and Cfg.SHOH or 0;local lyx=St.lyricsEnabled and 28 or 0;return 154+lyx+shx+(themeExp and Cfg.TPEH or Cfg.TPCH)+6 end
UI.kbPanel=Instance.new("Frame");UI.kbPanel.Position=UDim2.new(0,0,0,getKbPanelY());UI.kbPanel.Size=UDim2.new(1,0,0,KBCH);UI.kbPanel.BackgroundColor3=C.SURFACE;UI.kbPanel.BorderSizePixel=0;UI.kbPanel.ClipsDescendants=true;UI.kbPanel.ZIndex=3;UI.kbPanel.Parent=UI.settingsMainScroll;mkC(10,UI.kbPanel);mkS(1,C.BORDER,0.15,UI.kbPanel)
local kbHdr=Instance.new("TextButton");kbHdr.Size=UDim2.new(1,0,0,KBCH);kbHdr.BackgroundTransparency=1;kbHdr.AutoButtonColor=false;kbHdr.Font=Enum.Font.GothamMedium;kbHdr.Text="";kbHdr.ZIndex=4;kbHdr.Parent=UI.kbPanel
local kbHL=Instance.new("TextLabel");kbHL.AnchorPoint=Vector2.new(0,0.5);kbHL.Position=UDim2.new(0,12,0.5,0);kbHL.Size=UDim2.new(0.6,0,1,0);kbHL.BackgroundTransparency=1;kbHL.Font=Enum.Font.GothamMedium;kbHL.Text="Keybinds";kbHL.TextColor3=C.TEXT2;kbHL.TextXAlignment=Enum.TextXAlignment.Left;kbHL.TextSize=13;kbHL.ZIndex=4;kbHL.Parent=kbHdr
local kbCh=Instance.new("TextLabel");kbCh.AnchorPoint=Vector2.new(1,0.5);kbCh.Position=UDim2.new(1,-12,0.5,0);kbCh.Size=UDim2.new(0,20,1,0);kbCh.BackgroundTransparency=1;kbCh.Font=Enum.Font.GothamBold;kbCh.Text="v";kbCh.TextColor3=C.TEXT3;kbCh.TextXAlignment=Enum.TextXAlignment.Right;kbCh.TextSize=12;kbCh.ZIndex=4;kbCh.Parent=kbHdr
local kbSep=Instance.new("Frame");kbSep.Position=UDim2.new(0,10,0,KBCH-1);kbSep.Size=UDim2.new(1,-20,0,1);kbSep.BackgroundColor3=C.BORDER;kbSep.BorderSizePixel=0;kbSep.ZIndex=3;kbSep.Parent=UI.kbPanel
local kbScr=Instance.new("ScrollingFrame");kbScr.Position=UDim2.new(0,0,0,KBCH+2);kbScr.Size=UDim2.new(1,0,1,-(KBCH+2));kbScr.BackgroundTransparency=1;kbScr.BorderSizePixel=0;kbScr.ScrollBarThickness=3;kbScr.ScrollBarImageColor3=C.ACCENT;kbScr.CanvasSize=UDim2.new(0,0,0,0);kbScr.ZIndex=3;kbScr.Parent=UI.kbPanel
local kbRL=Instance.new("UIListLayout");kbRL.Padding=UDim.new(0,4);kbRL.SortOrder=Enum.SortOrder.LayoutOrder;kbRL.Parent=kbScr
local kbRP=Instance.new("UIPadding");kbRP.PaddingTop=UDim.new(0,4);kbRP.PaddingLeft=UDim.new(0,8);kbRP.PaddingRight=UDim.new(0,8);kbRP.Parent=kbScr
kbRL:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function() kbScr.CanvasSize=UDim2.new(0,0,0,kbRL.AbsoluteContentSize.Y+10) end)
local KBDefs={
{label="Toggle Controller", field="kbToggle"},
{label="Previous Track", field="kbPrev"},
{label="Play / Pause", field="kbPlay"},
{label="Next Track", field="kbNext"},
{label="Repeat", field="kbRepeat"},
{label="Shuffle", field="kbShuffle"},
{label="Synced Lyrics", field="kbLyrics"},
{label="Translate Lyrics", field="kbTranslate"},
{label="Mute Game Sounds", field="kbMute"},
{label="Cinematic Mode", field="kbCinematic"},
}
local kbCapturing=nil
for i,kd in ipairs(KBDefs) do
local row=Instance.new("Frame");row.Size=UDim2.new(1,0,0,Cfg.TRH);row.BackgroundColor3=C.ELEVATED;row.BorderSizePixel=0;row.LayoutOrder=i;row.ZIndex=3;row.Parent=kbScr;mkC(7,row)
local rl=Instance.new("TextLabel");rl.AnchorPoint=Vector2.new(0,0.5);rl.Position=UDim2.new(0,10,0.5,0);rl.Size=UDim2.new(0.58,0,1,0);rl.BackgroundTransparency=1;rl.Font=Enum.Font.GothamMedium;rl.Text=kd.label;rl.TextColor3=C.TEXT2;rl.TextXAlignment=Enum.TextXAlignment.Left;rl.TextSize=12;rl.ZIndex=4;rl.Parent=row
local kb=Instance.new("TextButton");kb.AnchorPoint=Vector2.new(1,0.5);kb.Position=UDim2.new(1,-8,0.5,0);kb.Size=UDim2.new(0,88,0,20);kb.BackgroundColor3=C.SURFACE;kb.AutoButtonColor=false;kb.Font=Enum.Font.GothamMedium;kb.TextSize=11;kb.TextColor3=C.ACCENT;kb.BorderSizePixel=0;kb.ZIndex=4;kb.Parent=row;mkC(6,kb);mkS(1,C.BORDER,0.25,kb)
local field=kd.field
local function refreshBtn()
local kc=field=="kbToggle" and curKC or St[field]
kb.Text=kc and kc.Name or "—"
kb.TextColor3=(kbCapturing==field) and C.TEXT or C.ACCENT
kb.BackgroundColor3=(kbCapturing==field) and C.ACCENT_DIM or C.SURFACE
end
refreshBtn()
kb.MouseButton1Click:Connect(function()
if kbCapturing==field then kbCapturing=nil;refreshBtn();return end
kbCapturing=field
for _,ch in ipairs(kbScr:GetChildren()) do
if ch:IsA("Frame") then for _,cb in ipairs(ch:GetChildren()) do if cb:IsA("TextButton") then cb.BackgroundColor3=C.SURFACE;cb.TextColor3=C.ACCENT end end end
end
kb.Text="press…";kb.BackgroundColor3=C.ACCENT_DIM;kb.TextColor3=C.TEXT
end)
row.Name="KBRow_"..field
end
Svc.UIS.InputBegan:Connect(function(inp,gp)
if not kbCapturing then return end
if inp.UserInputType~=Enum.UserInputType.Keyboard then return end
local kc=inp.KeyCode;if kc==Enum.KeyCode.Unknown then return end
if kbCapturing=="kbToggle" then curKC=kc;kbVal.Value=kc.Name
else St[kbCapturing]=kc end
saveSettings()
local rowName="KBRow_"..kbCapturing;kbCapturing=nil
local r=kbScr:FindFirstChild(rowName);if r then for _,cb in ipairs(r:GetChildren()) do if cb:IsA("TextButton") then cb.Text=kc.Name;cb.BackgroundColor3=C.SURFACE;cb.TextColor3=C.ACCENT end end end
end)
local kbAnim2=false
kbHdr.MouseButton1Click:Connect(function()
if kbAnim2 then return end;kbAnim2=true;kbPanelExp=not kbPanelExp;kbCh.Text=kbPanelExp and "^" or "v"
local th2=kbPanelExp and KBEH or KBCH
local tw2=Svc.TS:Create(UI.kbPanel,TweenInfo.new(0.22,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{Size=UDim2.new(1,0,0,th2)})
tw2.Completed:Connect(function() kbAnim2=false;updSCanvas() end);tw2:Play()
end)
kbHdr.MouseEnter:Connect(function() kbHL.TextColor3=C.TEXT end);kbHdr.MouseLeave:Connect(function() kbHL.TextColor3=C.TEXT2 end)
end
do
local dlL=Instance.new("UIListLayout");dlL.Padding=UDim.new(0,9);dlL.SortOrder=Enum.SortOrder.LayoutOrder;dlL.HorizontalAlignment=Enum.HorizontalAlignment.Center;dlL.Parent=UI.settingsDownloaderScroll
dlL:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function() UI.settingsDownloaderScroll.CanvasSize=UDim2.new(0,0,0,dlL.AbsoluteContentSize.Y+20) end)
local dlPad=Instance.new("UIPadding");dlPad.PaddingBottom=UDim.new(0,8);dlPad.Parent=UI.settingsDownloaderScroll
local function dlLbl(t,lo) local l=Instance.new("TextLabel");l.Size=UDim2.new(1,0,0,13);l.BackgroundTransparency=1;l.Font=Enum.Font.GothamMedium;l.Text=t;l.TextColor3=C.TEXT2;l.TextXAlignment=Enum.TextXAlignment.Left;l.TextSize=11;l.LayoutOrder=lo;l.ZIndex=3;l.Parent=UI.settingsDownloaderScroll;local p=Instance.new("UIPadding");p.PaddingLeft=UDim.new(0,4);p.PaddingRight=UDim.new(0,4);p.Parent=l;return l end
local function dlInp(ph,lo) local b=Instance.new("TextBox");b.Size=UDim2.new(1,0,0,32);b.BackgroundColor3=C.ELEVATED;b.BorderSizePixel=0;b.Font=Enum.Font.Gotham;b.PlaceholderText=ph;b.Text="";b.TextColor3=C.TEXT;b.PlaceholderColor3=C.TEXT3;b.TextSize=12;b.ClearTextOnFocus=false;b.LayoutOrder=lo;b.ZIndex=3;b.Parent=UI.settingsDownloaderScroll;mkC(8,b);mkS(1,C.BORDER_LIT,0.45,b);local p=Instance.new("UIPadding");p.PaddingLeft=UDim.new(0,14);p.PaddingRight=UDim.new(0,14);p.Parent=b;return b end
local dsh=Instance.new("TextLabel");dsh.Size=UDim2.new(1,0,0,13);dsh.BackgroundTransparency=1;dsh.Font=Enum.Font.GothamMedium;dsh.Text="SOUNDCLOUD DOWNLOADER";dsh.TextColor3=C.TEXT3;dsh.TextXAlignment=Enum.TextXAlignment.Left;dsh.TextSize=9;dsh.LayoutOrder=1;dsh.ZIndex=3;dsh.Parent=UI.settingsDownloaderScroll;do local p=Instance.new("UIPadding");p.PaddingLeft=UDim.new(0,4);p.Parent=dsh end
local scBtn=Instance.new("TextButton");scBtn.AnchorPoint=Vector2.new(1,0.5);scBtn.Position=UDim2.new(1,-4,0.5,0);scBtn.Size=UDim2.new(0,72,0,18);scBtn.BackgroundColor3=C.ACCENT_DIM;scBtn.AutoButtonColor=false;scBtn.Font=Enum.Font.GothamSemibold;scBtn.Text="🔗 open";scBtn.TextColor3=C.ACCENT;scBtn.TextSize=10;scBtn.BorderSizePixel=0;scBtn.ZIndex=4;scBtn.Parent=dsh;mkC(5,scBtn)
scBtn.MouseEnter:Connect(function() Svc.TS:Create(scBtn,TweenInfo.new(0.12),{BackgroundColor3=C.ACCENT,TextColor3=AT}):Play() end);scBtn.MouseLeave:Connect(function() Svc.TS:Create(scBtn,TweenInfo.new(0.12),{BackgroundColor3=C.ACCENT_DIM,TextColor3=C.ACCENT}):Play() end)
scBtn.MouseButton1Click:Connect(function()
local SC_URL="https://soundcloud.com";local opened=false
if not opened then pcall(function() if typeof(open_url)=="function" then open_url(SC_URL);opened=true end end) end
if not opened then pcall(function() if typeof(OpenBrowser)=="function" then OpenBrowser(SC_URL);opened=true end end) end
if not opened then pcall(function() setclipboard(SC_URL) end);local orig=scBtn.Text;scBtn.Text="copied!";scBtn.TextColor3=C.SUCCESS;Svc.TS:Create(scBtn,TweenInfo.new(0.1),{BackgroundColor3=Color3.fromRGB(30,60,30)}):Play();task.delay(2,function() scBtn.Text=orig;scBtn.TextColor3=C.ACCENT;Svc.TS:Create(scBtn,TweenInfo.new(0.12),{BackgroundColor3=C.ACCENT_DIM}):Play() end) end
end)
local ddiv=Instance.new("Frame");ddiv.Size=UDim2.new(1,0,0,1);ddiv.BackgroundColor3=C.BORDER;ddiv.BorderSizePixel=0;ddiv.LayoutOrder=2;ddiv.ZIndex=3;ddiv.Parent=UI.settingsDownloaderScroll
UI.dlArtFrame=Instance.new("Frame");UI.dlArtFrame.Size=UDim2.new(1,0,0,172);UI.dlArtFrame.BackgroundColor3=Color3.fromRGB(8,6,4);UI.dlArtFrame.BackgroundTransparency=0;UI.dlArtFrame.BorderSizePixel=0;UI.dlArtFrame.LayoutOrder=3;UI.dlArtFrame.ZIndex=3;UI.dlArtFrame.ClipsDescendants=true;UI.dlArtFrame.Parent=UI.settingsDownloaderScroll;mkC(10,UI.dlArtFrame)
UI.dlArtImage=Instance.new("ImageLabel");UI.dlArtImage.AnchorPoint=Vector2.new(0.5,0.5);UI.dlArtImage.Position=UDim2.new(0.5,0,0.5,0);UI.dlArtImage.Size=UDim2.new(1,2,1,2);UI.dlArtImage.BackgroundTransparency=1;UI.dlArtImage.Image="";UI.dlArtImage.ScaleType=Enum.ScaleType.Crop;UI.dlArtImage.ImageTransparency=1;UI.dlArtImage.ZIndex=4;UI.dlArtImage.Parent=UI.dlArtFrame
local dlArtGrad=Instance.new("Frame");dlArtGrad.AnchorPoint=Vector2.new(0,1);dlArtGrad.Position=UDim2.new(0,0,1,0);dlArtGrad.Size=UDim2.new(1,0,0.55,0);dlArtGrad.BackgroundColor3=Color3.new(0,0,0);dlArtGrad.BackgroundTransparency=0;dlArtGrad.BorderSizePixel=0;dlArtGrad.ZIndex=5;dlArtGrad.Visible=false;dlArtGrad.Parent=UI.dlArtFrame
local dlArtGradG=Instance.new("UIGradient");dlArtGradG.Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,1),NumberSequenceKeypoint.new(1,0)});dlArtGradG.Rotation=90;dlArtGradG.Parent=dlArtGrad
UI.dlArtTitle=Instance.new("TextLabel");UI.dlArtTitle.AnchorPoint=Vector2.new(0,1);UI.dlArtTitle.Position=UDim2.new(0,10,1,-8);UI.dlArtTitle.Size=UDim2.new(1,-16,0,32);UI.dlArtTitle.BackgroundTransparency=1;UI.dlArtTitle.Font=Enum.Font.GothamBold;UI.dlArtTitle.Text="";UI.dlArtTitle.TextColor3=Color3.fromRGB(255,255,255);UI.dlArtTitle.TextXAlignment=Enum.TextXAlignment.Left;UI.dlArtTitle.TextSize=13;UI.dlArtTitle.TextTruncate=Enum.TextTruncate.AtEnd;UI.dlArtTitle.TextTransparency=1;UI.dlArtTitle.ZIndex=6;UI.dlArtTitle.Parent=UI.dlArtFrame
UI.dlArtPlaceholder=Instance.new("ImageLabel");UI.dlArtPlaceholder.AnchorPoint=Vector2.new(0.5,0.5);UI.dlArtPlaceholder.Position=UDim2.new(0.5,0,0.5,0);UI.dlArtPlaceholder.Size=UDim2.new(1,2,1,2);UI.dlArtPlaceholder.BackgroundTransparency=1;UI.dlArtPlaceholder.Image="rbxassetid://119441213053262";UI.dlArtPlaceholder.ScaleType=Enum.ScaleType.Crop;UI.dlArtPlaceholder.ImageTransparency=1;UI.dlArtPlaceholder.ZIndex=4;UI.dlArtPlaceholder.Visible=false;UI.dlArtPlaceholder.Parent=UI.dlArtFrame
UI.dlArtStatusText=Instance.new("TextLabel");UI.dlArtStatusText.AnchorPoint=Vector2.new(0.5,1);UI.dlArtStatusText.Position=UDim2.new(0.5,0,1,-8);UI.dlArtStatusText.Size=UDim2.new(1,-16,0,16);UI.dlArtStatusText.BackgroundTransparency=1;UI.dlArtStatusText.Font=Enum.Font.GothamMedium;UI.dlArtStatusText.Text="";UI.dlArtStatusText.TextColor3=Color3.fromRGB(160,140,100);UI.dlArtStatusText.TextSize=11;UI.dlArtStatusText.ZIndex=6;UI.dlArtStatusText.Parent=UI.dlArtFrame
UI.dlArtHint=Instance.new("TextLabel");UI.dlArtHint.AnchorPoint=Vector2.new(0.5,0.5);UI.dlArtHint.Position=UDim2.new(0.5,0,0.5,0);UI.dlArtHint.Size=UDim2.new(1,-24,0,36);UI.dlArtHint.BackgroundTransparency=1;UI.dlArtHint.Font=Enum.Font.GothamMedium;UI.dlArtHint.Text="paste a SoundCloud URL\nto load the album cover";UI.dlArtHint.TextColor3=Color3.fromRGB(80,65,38);UI.dlArtHint.TextSize=12;UI.dlArtHint.TextWrapped=true;UI.dlArtHint.ZIndex=4;UI.dlArtHint.Parent=UI.dlArtFrame
local dlArtFetchGen=0
local function clearDlArt()
dlArtFetchGen=dlArtFetchGen+1;UI.dlArtImage.Image=""
Svc.TS:Create(UI.dlArtImage,TweenInfo.new(0.15),{ImageTransparency=1}):Play();Svc.TS:Create(UI.dlArtTitle,TweenInfo.new(0.12),{TextTransparency=1}):Play()
dlArtGrad.Visible=false;UI.dlArtPlaceholder.Visible=false;UI.dlArtPlaceholder.ImageTransparency=1;UI.dlArtStatusText.Text="";UI.dlArtHint.Visible=true
end
local function fetchDlArt(url)
if not url or url:match("^%s*$") then clearDlArt();return end
dlArtFetchGen=dlArtFetchGen+1;local gen=dlArtFetchGen
UI.dlArtImage.Image="";UI.dlArtImage.ImageTransparency=1;UI.dlArtTitle.TextTransparency=1;dlArtGrad.Visible=false
UI.dlArtPlaceholder.Visible=true;UI.dlArtPlaceholder.ImageTransparency=0.5;UI.dlArtStatusText.Text="loading…";UI.dlArtHint.Visible=false
task.spawn(function()
local cid,cerr=getSCClientId();if not cid or gen~=dlArtFetchGen then if gen==dlArtFetchGen then UI.dlArtPlaceholder.Visible=false;UI.dlArtStatusText.Text="could not load artwork" end;return end
local ok,rr=pcall(function() return request({Url="https://api-v2.soundcloud.com/resolve?url="..stripQ(url).."&client_id="..cid,Method="GET",Headers={["Accept"]="application/json"}}) end)
if not ok or not rr or rr.StatusCode~=200 or gen~=dlArtFetchGen then if gen==dlArtFetchGen then UI.dlArtPlaceholder.Visible=false;UI.dlArtStatusText.Text="could not load artwork" end;return end
local ok2,td=pcall(function() return Svc.HS:JSONDecode(rr.Body) end)
if not ok2 or not td or gen~=dlArtFetchGen then if gen==dlArtFetchGen then UI.dlArtPlaceholder.Visible=false;UI.dlArtStatusText.Text="could not load artwork" end;return end
local artUrl=td.artwork_url or (td.user and td.user.avatar_url) or nil;local trackTitle=td.title or ""
if not artUrl then UI.dlArtPlaceholder.Visible=false;UI.dlArtStatusText.Text="no artwork found";return end
artUrl=artUrl:gsub("-large$","-t500x500"):gsub("-large%.jpg","-t500x500.jpg"):gsub("-large%.png","-t500x500.png")
local iok,imgData=pcall(function() return request({Url=artUrl,Method="GET"}) end)
if not iok or not imgData or (imgData.StatusCode~=200) or gen~=dlArtFetchGen then if gen==dlArtFetchGen then UI.dlArtPlaceholder.Visible=false;UI.dlArtStatusText.Text="artwork download failed" end;return end
local body=imgData.Body or "";if #body<100 then UI.dlArtPlaceholder.Visible=false;UI.dlArtStatusText.Text="artwork download failed";return end
local ext="jpg";if artUrl:lower():find("%.png") then ext="png" end
local tmpPath="Music Workspace/Configs/dl_art_"..gen.."."..ext
if not isfolder(Cfg.configsPath) then makefolder(Cfg.configsPath) end
local wok=pcall(function() writefile(tmpPath,body) end)
if not wok or gen~=dlArtFetchGen then if gen==dlArtFetchGen then UI.dlArtPlaceholder.Visible=false;UI.dlArtStatusText.Text="artwork save failed" end;return end
local aok,assetId=pcall(function() return getcustomasset(tmpPath) end)
if not aok or not assetId or gen~=dlArtFetchGen then if gen==dlArtFetchGen then UI.dlArtPlaceholder.Visible=false;UI.dlArtStatusText.Text="artwork load failed" end;return end
UI.dlArtImage.Image=assetId;UI.dlArtImage.ImageTransparency=1;UI.dlArtTitle.Text=trackTitle;UI.dlArtTitle.TextTransparency=1;dlArtGrad.Visible=true;UI.dlArtStatusText.Text=""
Svc.TS:Create(UI.dlArtPlaceholder,TweenInfo.new(0.25),{ImageTransparency=1}):Play();task.delay(0.25,function() UI.dlArtPlaceholder.Visible=false end)
Svc.TS:Create(UI.dlArtImage,TweenInfo.new(0.35,Enum.EasingStyle.Quad),{ImageTransparency=0}):Play()
if trackTitle~="" then Svc.TS:Create(UI.dlArtTitle,TweenInfo.new(0.25),{TextTransparency=0}):Play() end
if trackTitle~="" then UI.dlNameBox.Text=trackTitle end
end)
end
dlLbl("SoundCloud URL",4);UI.dlUrlBox=dlInp("https://soundcloud.com/artist/track-name",5);dlLbl("File Name (no extension)",6);UI.dlNameBox=dlInp("e.g. my_favorite_song",7)
UI.dlStatusPill=Instance.new("Frame");UI.dlStatusPill.Size=UDim2.new(1,0,0,28);UI.dlStatusPill.BackgroundColor3=C.SURFACE;UI.dlStatusPill.BorderSizePixel=0;UI.dlStatusPill.LayoutOrder=8;UI.dlStatusPill.ZIndex=3;UI.dlStatusPill.Parent=UI.settingsDownloaderScroll;mkC(8,UI.dlStatusPill);mkS(1,C.BORDER,0.25,UI.dlStatusPill)
local dlSD=Instance.new("Frame");dlSD.AnchorPoint=Vector2.new(0,0.5);dlSD.Position=UDim2.new(0,10,0.5,0);dlSD.Size=UDim2.new(0,6,0,6);dlSD.BackgroundColor3=C.TEXT3;dlSD.BorderSizePixel=0;dlSD.ZIndex=4;dlSD.Parent=UI.dlStatusPill;mkC(999,dlSD)
UI.dlStatusLabel=Instance.new("TextLabel");UI.dlStatusLabel.AnchorPoint=Vector2.new(0,0.5);UI.dlStatusLabel.Position=UDim2.new(0,24,0.5,0);UI.dlStatusLabel.Size=UDim2.new(1,-32,1,0);UI.dlStatusLabel.BackgroundTransparency=1;UI.dlStatusLabel.Font=Enum.Font.GothamMedium;UI.dlStatusLabel.Text="Ready to download";UI.dlStatusLabel.TextColor3=C.TEXT3;UI.dlStatusLabel.TextXAlignment=Enum.TextXAlignment.Left;UI.dlStatusLabel.TextSize=11;UI.dlStatusLabel.TextTruncate=Enum.TextTruncate.AtEnd;UI.dlStatusLabel.ZIndex=4;UI.dlStatusLabel.Parent=UI.dlStatusPill
UI.dlButton=Instance.new("TextButton");UI.dlButton.Size=UDim2.new(1,0,0,36);UI.dlButton.BackgroundColor3=C.ACCENT;UI.dlButton.AutoButtonColor=false;UI.dlButton.Font=Enum.Font.GothamSemibold;UI.dlButton.Text="⬇ Download & Add to Library";UI.dlButton.TextColor3=AT;UI.dlButton.TextSize=13;UI.dlButton.BorderSizePixel=0;UI.dlButton.LayoutOrder=9;UI.dlButton.ZIndex=3;UI.dlButton.Parent=UI.settingsDownloaderScroll;mkC(10,UI.dlButton)
UI.dlButton.MouseEnter:Connect(function() Svc.TS:Create(UI.dlButton,TweenInfo.new(0.12),{BackgroundColor3=C.BORDER_LIT}):Play() end);UI.dlButton.MouseLeave:Connect(function() Svc.TS:Create(UI.dlButton,TweenInfo.new(0.12),{BackgroundColor3=C.ACCENT}):Play() end)
local dlNote=Instance.new("TextLabel");dlNote.Size=UDim2.new(1,0,0,28);dlNote.BackgroundTransparency=1;dlNote.Font=Enum.Font.Gotham;dlNote.Text="Saves to Music Workspace/Musics/ and appears\nautomatically in your library within ~2 seconds.";dlNote.TextColor3=C.TEXT3;dlNote.TextXAlignment=Enum.TextXAlignment.Left;dlNote.TextSize=10;dlNote.TextWrapped=true;dlNote.LayoutOrder=10;dlNote.ZIndex=3;dlNote.Parent=UI.settingsDownloaderScroll
local function setDlSt(msg,col,dc) UI.dlStatusLabel.Text=msg;UI.dlStatusLabel.TextColor3=col or C.TEXT3;dlSD.BackgroundColor3=dc or col or C.TEXT3 end
local dlBusy=false
UI.dlUrlBox.FocusLost:Connect(function()
local url=UI.dlUrlBox.Text:match("^%s*(.-)%s*$")
if url~="" and url:lower():find("soundcloud.com",1,true) then fetchDlArt(url) elseif url=="" then clearDlArt();UI.dlNameBox.Text="" end
end)
UI.dlUrlBox:GetPropertyChangedSignal("Text"):Connect(function() local url=UI.dlUrlBox.Text:match("^%s*(.-)%s*$");if url=="" then UI.dlNameBox.Text="";clearDlArt() end end)
resetDownloader=function()
if dlBusy then return end
local ft=TweenInfo.new(0.18,Enum.EasingStyle.Quad)
Svc.TS:Create(UI.dlUrlBox,ft,{TextTransparency=1}):Play()
Svc.TS:Create(UI.dlNameBox,ft,{TextTransparency=1}):Play()
task.delay(0.18,function()
UI.dlUrlBox.Text="";UI.dlNameBox.Text=""
Svc.TS:Create(UI.dlUrlBox,ft,{TextTransparency=0}):Play()
Svc.TS:Create(UI.dlNameBox,ft,{TextTransparency=0}):Play()
end)
Svc.TS:Create(UI.dlButton,TweenInfo.new(0.15),{BackgroundColor3=C.ACCENT}):Play()
UI.dlButton.Text="⬇ Download & Add to Library"
setDlSt("Ready to download",C.TEXT3,C.TEXT3);clearDlArt()
end
UI.dlButton.MouseButton1Click:Connect(function()
if dlBusy then return end
local url=UI.dlUrlBox.Text:match("^%s*(.-)%s*$");if url=="" then setDlSt("⚠ Please paste a SoundCloud URL",C.DANGER);return end
if not url:lower():find("soundcloud.com",1,true) then setDlSt("⚠ Only SoundCloud links are supported",C.DANGER);return end
local nameHint=UI.dlNameBox.Text:match("^%s*(.-)%s*$");dlBusy=true
Svc.TS:Create(UI.dlButton,TweenInfo.new(0.15),{BackgroundColor3=C.ACCENT_DIM}):Play();UI.dlButton.Text="Downloading…"
task.spawn(function()
local function dlDone() Svc.TS:Create(UI.dlButton,TweenInfo.new(0.15),{BackgroundColor3=C.ACCENT}):Play();UI.dlButton.Text="⬇ Download & Add to Library";dlBusy=false end
local ad,err,scTitle=downloadSC(url,function(msg) setDlSt(msg,C.ACCENT,C.ACCENT) end)
if not ad then setDlSt("✗ "..(err or "Unknown error"),C.DANGER,C.DANGER);dlDone();return end
local name=nameHint;if name=="" then name=(scTitle and scTitle~="") and scTitle or "untitled_track";UI.dlNameBox.Text=name end
local safeName=makeSafeDiskName(name);local candidate=safeName;local counter=1
while isfile(Cfg.workspacePath.."/"..candidate..".mp3") do candidate=safeName.."_"..counter;counter=counter+1 end;safeName=candidate
local op=Cfg.workspacePath.."/"..safeName..".mp3";local newFileName=safeName..".mp3";dlDone()
setDlSt("Saving to disk…",C.ACCENT,C.ACCENT)
local wok,we=pcall(function() writefile(op,ad) end)
if not wok then setDlSt("✗ Save failed: "..tostring(we),C.DANGER,C.DANGER);return end
setDlSt("✓ "..name.." saved!",C.SUCCESS,C.SUCCESS);showNotification(name,false)
task.delay(2,function() setDlSt("Ready to download",C.TEXT3,C.TEXT3);UI.dlUrlBox.Text="";UI.dlNameBox.Text="";clearDlArt() end)
displayNamesMap[safeName]=name;saveDisplayNames();Dat.suppressAutoNotify[newFileName]=true;Dat.lastMp3Files=scanMusicFolder()
local alreadyIn=false;for _,t in ipairs(Dat.trackList) do if t.FileName==newFileName then alreadyIn=true;break end end
if not alreadyIn then
local newIdx=#Dat.trackList+1;table.insert(Dat.trackList,{Path=op,DisplayName=name,FullName=name,FileName=newFileName,Type="mp3"});table.insert(Dat.createdSounds,false)
if Dat.updateMp3List then Dat.updateMp3List() end
task.defer(function()
local ref=Dat.listButtonRefs[newFileName];local btn=ref and ref.btn
if btn and btn.Parent then
local btnY=btn.AbsolutePosition.Y-UI.listScroll.AbsolutePosition.Y+UI.listScroll.CanvasPosition.Y
local targetY=math.max(0,math.min(btnY-UI.listScroll.AbsoluteSize.Y+38,UI.listScroll.CanvasSize.Y.Offset-UI.listScroll.AbsoluteSize.Y))
UI.listScroll.CanvasPosition=Vector2.new(0,targetY)
local tw=Svc.TS:Create(btn,TweenInfo.new(0.5,Enum.EasingStyle.Sine,Enum.EasingDirection.InOut,-1,true),{BackgroundColor3=C.ACCENT});tw:Play()
local done=false;local cc;cc=btn.MouseButton1Click:Connect(function() if not done then done=true;cc:Disconnect();tw:Cancel();if btn.Parent then Svc.TS:Create(btn,TweenInfo.new(0.3),{BackgroundColor3=C.SURFACE}):Play() end end end)
task.delay(5,function() if not done then done=true;pcall(function() cc:Disconnect() end);tw:Cancel();if btn.Parent then Svc.TS:Create(btn,TweenInfo.new(0.3),{BackgroundColor3=C.SURFACE}):Play() end end end)
end
end)
task.spawn(function()
local ns=Instance.new("Sound");ns.Name=name;local ok,au=pcall(function() return getcustomasset(op) end)
if not ok or not au or au=="" then task.wait(1);ok,au=pcall(function() return getcustomasset(op) end) end
if ok and au and au~="" then ns.SoundId=au;ns.Volume=St.currentVolume;ns.PlaybackSpeed=(St.currentSpeed<=0) and 0.01 or St.currentSpeed;ns.Looped=false;ns.Parent=soundsFolder;Dat.createdSounds[newIdx]=ns;attachSoundGuard(ns);if Dat.updateMp3List then Dat.updateMp3List() end
else ns:Destroy();pcall(function() loadMusicTracks(true);rebuildCategoryIndices();saveCategories();for _,s in ipairs(Dat.createdSounds) do if s and s~=false then attachSoundGuard(s) end end;Dat.lastMp3Files=scanMusicFolder() end);if Dat.updateMp3List then Dat.updateMp3List() end end
end)
else if Dat.updateMp3List then Dat.updateMp3List() end end
end)
end)
end
do
local scSL=Instance.new("UIListLayout");scSL.Padding=UDim.new(0,9);scSL.SortOrder=Enum.SortOrder.LayoutOrder;scSL.HorizontalAlignment=Enum.HorizontalAlignment.Center;scSL.Parent=UI.settingsScSearchScroll
scSL:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function() UI.settingsScSearchScroll.CanvasSize=UDim2.new(0,0,0,scSL.AbsoluteContentSize.Y+20) end)
local scSPad=Instance.new("UIPadding");scSPad.PaddingBottom=UDim.new(0,8);scSPad.Parent=UI.settingsScSearchScroll
local scHdrRow=Instance.new("Frame");scHdrRow.Size=UDim2.new(1,0,0,13);scHdrRow.BackgroundTransparency=1;scHdrRow.LayoutOrder=1;scHdrRow.ZIndex=3;scHdrRow.Parent=UI.settingsScSearchScroll
local scHdrL=Instance.new("TextLabel");scHdrL.Size=UDim2.new(1,-4,1,0);scHdrL.Position=UDim2.new(0,4,0,0);scHdrL.BackgroundTransparency=1;scHdrL.Font=Enum.Font.GothamMedium;scHdrL.Text="SOUNDCLOUD SEARCH";scHdrL.TextColor3=C.TEXT3;scHdrL.TextXAlignment=Enum.TextXAlignment.Left;scHdrL.TextSize=9;scHdrL.ZIndex=3;scHdrL.Parent=scHdrRow
local scDivider=Instance.new("Frame");scDivider.Size=UDim2.new(1,0,0,1);scDivider.BackgroundColor3=C.BORDER;scDivider.BorderSizePixel=0;scDivider.LayoutOrder=2;scDivider.ZIndex=3;scDivider.Parent=UI.settingsScSearchScroll
local scNavRow=Instance.new("Frame");scNavRow.Size=UDim2.new(1,0,0,32);scNavRow.BackgroundTransparency=1;scNavRow.LayoutOrder=3;scNavRow.ZIndex=3;scNavRow.Parent=UI.settingsScSearchScroll
UI.scPrevBtn=Instance.new("TextButton");UI.scPrevBtn.Size=UDim2.new(0,80,1,-2);UI.scPrevBtn.AnchorPoint=Vector2.new(0,0.5);UI.scPrevBtn.Position=UDim2.new(0,0,0.5,0);UI.scPrevBtn.BackgroundColor3=C.SURFACE;UI.scPrevBtn.AutoButtonColor=false;UI.scPrevBtn.Font=Enum.Font.GothamSemibold;UI.scPrevBtn.Text="← Prev";UI.scPrevBtn.TextColor3=C.TEXT2;UI.scPrevBtn.TextSize=12;UI.scPrevBtn.BorderSizePixel=0;UI.scPrevBtn.ZIndex=3;UI.scPrevBtn.Parent=scNavRow;mkC(8,UI.scPrevBtn);mkS(1,C.BORDER,0.2,UI.scPrevBtn)
UI.scCounterLabel=Instance.new("TextLabel");UI.scCounterLabel.AnchorPoint=Vector2.new(0.5,0.5);UI.scCounterLabel.Position=UDim2.new(0.5,0,0.5,0);UI.scCounterLabel.Size=UDim2.new(0,100,1,0);UI.scCounterLabel.BackgroundTransparency=1;UI.scCounterLabel.Font=Enum.Font.GothamSemibold;UI.scCounterLabel.Text="0 / 0";UI.scCounterLabel.TextColor3=C.TEXT3;UI.scCounterLabel.TextSize=13;UI.scCounterLabel.ZIndex=3;UI.scCounterLabel.Parent=scNavRow
UI.scNextBtn=Instance.new("TextButton");UI.scNextBtn.Size=UDim2.new(0,80,1,-2);UI.scNextBtn.AnchorPoint=Vector2.new(1,0.5);UI.scNextBtn.Position=UDim2.new(1,0,0.5,0);UI.scNextBtn.BackgroundColor3=C.SURFACE;UI.scNextBtn.AutoButtonColor=false;UI.scNextBtn.Font=Enum.Font.GothamSemibold;UI.scNextBtn.Text="Next →";UI.scNextBtn.TextColor3=C.TEXT2;UI.scNextBtn.TextSize=12;UI.scNextBtn.BorderSizePixel=0;UI.scNextBtn.ZIndex=3;UI.scNextBtn.Parent=scNavRow;mkC(8,UI.scNextBtn);mkS(1,C.BORDER,0.2,UI.scNextBtn)
for _,b in ipairs({UI.scPrevBtn,UI.scNextBtn}) do
b.MouseEnter:Connect(function() if #St.scResults>0 then Svc.TS:Create(b,TweenInfo.new(0.12),{BackgroundColor3=C.ELEVATED,TextColor3=C.TEXT}):Play() end end)
b.MouseLeave:Connect(function() Svc.TS:Create(b,TweenInfo.new(0.12),{BackgroundColor3=C.SURFACE,TextColor3=C.TEXT2}):Play() end)
end
UI.scArtFrame=Instance.new("Frame");UI.scArtFrame.Size=UDim2.new(1,0,0,172);UI.scArtFrame.BackgroundColor3=Color3.fromRGB(8,6,4);UI.scArtFrame.BorderSizePixel=0;UI.scArtFrame.LayoutOrder=4;UI.scArtFrame.ZIndex=3;UI.scArtFrame.ClipsDescendants=true;UI.scArtFrame.Parent=UI.settingsScSearchScroll;mkC(10,UI.scArtFrame)
UI.scArtImage=Instance.new("ImageLabel");UI.scArtImage.AnchorPoint=Vector2.new(0.5,0.5);UI.scArtImage.Position=UDim2.new(0.5,0,0.5,0);UI.scArtImage.Size=UDim2.new(1,2,1,2);UI.scArtImage.BackgroundTransparency=1;UI.scArtImage.Image="";UI.scArtImage.ScaleType=Enum.ScaleType.Crop;UI.scArtImage.ImageTransparency=1;UI.scArtImage.ZIndex=4;UI.scArtImage.Parent=UI.scArtFrame
local scArtGrad=Instance.new("Frame");scArtGrad.AnchorPoint=Vector2.new(0,1);scArtGrad.Position=UDim2.new(0,0,1,0);scArtGrad.Size=UDim2.new(1,0,0.55,0);scArtGrad.BackgroundColor3=Color3.new(0,0,0);scArtGrad.BackgroundTransparency=0;scArtGrad.BorderSizePixel=0;scArtGrad.ZIndex=5;scArtGrad.Visible=false;scArtGrad.Parent=UI.scArtFrame
local scArtGradG=Instance.new("UIGradient");scArtGradG.Transparency=NumberSequence.new({NumberSequenceKeypoint.new(0,1),NumberSequenceKeypoint.new(1,0)});scArtGradG.Rotation=90;scArtGradG.Parent=scArtGrad
UI.scArtTitleLabel=Instance.new("TextLabel");UI.scArtTitleLabel.AnchorPoint=Vector2.new(0,1);UI.scArtTitleLabel.Position=UDim2.new(0,10,1,-8);UI.scArtTitleLabel.Size=UDim2.new(1,-16,0,32);UI.scArtTitleLabel.BackgroundTransparency=1;UI.scArtTitleLabel.Font=Enum.Font.GothamBold;UI.scArtTitleLabel.Text="";UI.scArtTitleLabel.TextColor3=Color3.fromRGB(255,255,255);UI.scArtTitleLabel.TextXAlignment=Enum.TextXAlignment.Left;UI.scArtTitleLabel.TextSize=13;UI.scArtTitleLabel.TextTruncate=Enum.TextTruncate.AtEnd;UI.scArtTitleLabel.TextTransparency=1;UI.scArtTitleLabel.ZIndex=6;UI.scArtTitleLabel.Parent=UI.scArtFrame
local scArtPlaceholder=Instance.new("ImageLabel");scArtPlaceholder.AnchorPoint=Vector2.new(0.5,0.5);scArtPlaceholder.Position=UDim2.new(0.5,0,0.5,0);scArtPlaceholder.Size=UDim2.new(1,2,1,2);scArtPlaceholder.BackgroundTransparency=1;scArtPlaceholder.Image="rbxassetid://119441213053262";scArtPlaceholder.ScaleType=Enum.ScaleType.Crop;scArtPlaceholder.ImageTransparency=1;scArtPlaceholder.ZIndex=4;scArtPlaceholder.Visible=false;scArtPlaceholder.Parent=UI.scArtFrame
UI.scArtStatus=Instance.new("TextLabel");UI.scArtStatus.AnchorPoint=Vector2.new(0.5,1);UI.scArtStatus.Position=UDim2.new(0.5,0,1,-8);UI.scArtStatus.Size=UDim2.new(1,-16,0,16);UI.scArtStatus.BackgroundTransparency=1;UI.scArtStatus.Font=Enum.Font.GothamMedium;UI.scArtStatus.Text="";UI.scArtStatus.TextColor3=Color3.fromRGB(160,140,100);UI.scArtStatus.TextSize=11;UI.scArtStatus.ZIndex=6;UI.scArtStatus.Parent=UI.scArtFrame
local scArtHint=Instance.new("TextLabel");scArtHint.AnchorPoint=Vector2.new(0.5,0.5);scArtHint.Position=UDim2.new(0.5,0,0.5,0);scArtHint.Size=UDim2.new(1,-24,0,36);scArtHint.BackgroundTransparency=1;scArtHint.Font=Enum.Font.GothamMedium;scArtHint.Text="type a song title and press Search\nto find it on SoundCloud";scArtHint.TextColor3=Color3.fromRGB(80,65,38);scArtHint.TextSize=12;scArtHint.TextWrapped=true;scArtHint.ZIndex=4;scArtHint.Parent=UI.scArtFrame
local scQLbl=Instance.new("TextLabel");scQLbl.Size=UDim2.new(1,0,0,13);scQLbl.BackgroundTransparency=1;scQLbl.Font=Enum.Font.GothamMedium;scQLbl.Text="Song Title";scQLbl.TextColor3=C.TEXT2;scQLbl.TextXAlignment=Enum.TextXAlignment.Left;scQLbl.TextSize=11;scQLbl.LayoutOrder=5;scQLbl.ZIndex=3;scQLbl.Parent=UI.settingsScSearchScroll;do local p=Instance.new("UIPadding");p.PaddingLeft=UDim.new(0,4);p.PaddingRight=UDim.new(0,4);p.Parent=scQLbl end
local scQueryRow=Instance.new("Frame");scQueryRow.Size=UDim2.new(1,0,0,32);scQueryRow.BackgroundTransparency=1;scQueryRow.LayoutOrder=6;scQueryRow.ZIndex=3;scQueryRow.Parent=UI.settingsScSearchScroll
UI.scQueryBox=Instance.new("TextBox");UI.scQueryBox.Size=UDim2.new(1,-82,1,0);UI.scQueryBox.BackgroundColor3=C.ELEVATED;UI.scQueryBox.BorderSizePixel=0;UI.scQueryBox.Font=Enum.Font.Gotham;UI.scQueryBox.PlaceholderText="e.g. Bohemian Rhapsody";UI.scQueryBox.Text="";UI.scQueryBox.TextColor3=C.TEXT;UI.scQueryBox.PlaceholderColor3=C.TEXT3;UI.scQueryBox.TextSize=12;UI.scQueryBox.ClearTextOnFocus=false;UI.scQueryBox.ZIndex=3;UI.scQueryBox.Parent=scQueryRow;mkC(8,UI.scQueryBox);mkS(1,C.BORDER_LIT,0.45,UI.scQueryBox);do local p=Instance.new("UIPadding");p.PaddingLeft=UDim.new(0,14);p.PaddingRight=UDim.new(0,8);p.Parent=UI.scQueryBox end
UI.scSearchBtn=Instance.new("TextButton");UI.scSearchBtn.AnchorPoint=Vector2.new(1,0.5);UI.scSearchBtn.Position=UDim2.new(1,0,0.5,0);UI.scSearchBtn.Size=UDim2.new(0,76,1,-2);UI.scSearchBtn.BackgroundColor3=C.ACCENT;UI.scSearchBtn.AutoButtonColor=false;UI.scSearchBtn.Font=Enum.Font.GothamSemibold;UI.scSearchBtn.Text="Search";UI.scSearchBtn.TextColor3=AT;UI.scSearchBtn.TextSize=12;UI.scSearchBtn.BorderSizePixel=0;UI.scSearchBtn.ZIndex=3;UI.scSearchBtn.Parent=scQueryRow;mkC(8,UI.scSearchBtn)
UI.scSearchBtn.MouseEnter:Connect(function() Svc.TS:Create(UI.scSearchBtn,TweenInfo.new(0.12),{BackgroundColor3=C.BORDER_LIT}):Play() end);UI.scSearchBtn.MouseLeave:Connect(function() Svc.TS:Create(UI.scSearchBtn,TweenInfo.new(0.12),{BackgroundColor3=C.ACCENT}):Play() end)
UI.scStatusPill=Instance.new("Frame");UI.scStatusPill.Size=UDim2.new(1,0,0,28);UI.scStatusPill.BackgroundColor3=C.SURFACE;UI.scStatusPill.BorderSizePixel=0;UI.scStatusPill.LayoutOrder=7;UI.scStatusPill.ZIndex=3;UI.scStatusPill.Parent=UI.settingsScSearchScroll;mkC(8,UI.scStatusPill);mkS(1,C.BORDER,0.25,UI.scStatusPill)
UI.scSDot=Instance.new("Frame");UI.scSDot.AnchorPoint=Vector2.new(0,0.5);UI.scSDot.Position=UDim2.new(0,10,0.5,0);UI.scSDot.Size=UDim2.new(0,6,0,6);UI.scSDot.BackgroundColor3=C.TEXT3;UI.scSDot.BorderSizePixel=0;UI.scSDot.ZIndex=4;UI.scSDot.Parent=UI.scStatusPill;mkC(999,UI.scSDot)
UI.scStatusLabel=Instance.new("TextLabel");UI.scStatusLabel.AnchorPoint=Vector2.new(0,0.5);UI.scStatusLabel.Position=UDim2.new(0,24,0.5,0);UI.scStatusLabel.Size=UDim2.new(1,-32,1,0);UI.scStatusLabel.BackgroundTransparency=1;UI.scStatusLabel.Font=Enum.Font.GothamMedium;UI.scStatusLabel.Text="Enter a song title to search";UI.scStatusLabel.TextColor3=C.TEXT3;UI.scStatusLabel.TextXAlignment=Enum.TextXAlignment.Left;UI.scStatusLabel.TextSize=11;UI.scStatusLabel.TextTruncate=Enum.TextTruncate.AtEnd;UI.scStatusLabel.ZIndex=4;UI.scStatusLabel.Parent=UI.scStatusPill
local scUrlLbl=Instance.new("TextLabel");scUrlLbl.Size=UDim2.new(1,0,0,13);scUrlLbl.BackgroundTransparency=1;scUrlLbl.Font=Enum.Font.GothamMedium;scUrlLbl.Text="SoundCloud URL";scUrlLbl.TextColor3=C.TEXT2;scUrlLbl.TextXAlignment=Enum.TextXAlignment.Left;scUrlLbl.TextSize=11;scUrlLbl.LayoutOrder=8;scUrlLbl.ZIndex=3;scUrlLbl.Parent=UI.settingsScSearchScroll;do local p=Instance.new("UIPadding");p.PaddingLeft=UDim.new(0,4);p.PaddingRight=UDim.new(0,4);p.Parent=scUrlLbl end
UI.scUrlRow=Instance.new("Frame");UI.scUrlRow.Size=UDim2.new(1,0,0,32);UI.scUrlRow.BackgroundTransparency=1;UI.scUrlRow.LayoutOrder=9;UI.scUrlRow.ZIndex=3;UI.scUrlRow.Parent=UI.settingsScSearchScroll
UI.scUrlBox=Instance.new("TextBox");UI.scUrlBox.Size=UDim2.new(1,-82,1,0);UI.scUrlBox.BackgroundColor3=C.ELEVATED;UI.scUrlBox.BorderSizePixel=0;UI.scUrlBox.Font=Enum.Font.Gotham;UI.scUrlBox.PlaceholderText="search result will appear here";UI.scUrlBox.Text="";UI.scUrlBox.TextColor3=C.ACCENT;UI.scUrlBox.PlaceholderColor3=C.TEXT3;UI.scUrlBox.TextSize=11;UI.scUrlBox.ClearTextOnFocus=false;UI.scUrlBox.TextEditable=false;UI.scUrlBox.TextTruncate=Enum.TextTruncate.AtEnd;UI.scUrlBox.ClipsDescendants=true;UI.scUrlBox.ZIndex=3;UI.scUrlBox.Parent=UI.scUrlRow;mkC(8,UI.scUrlBox);mkS(1,C.BORDER_LIT,0.45,UI.scUrlBox);do local p=Instance.new("UIPadding");p.PaddingLeft=UDim.new(0,10);p.PaddingRight=UDim.new(0,8);p.Parent=UI.scUrlBox end
UI.scCopyBtn=Instance.new("TextButton");UI.scCopyBtn.AnchorPoint=Vector2.new(1,0.5);UI.scCopyBtn.Position=UDim2.new(1,0,0.5,0);UI.scCopyBtn.Size=UDim2.new(0,76,1,-2);UI.scCopyBtn.BackgroundColor3=C.ELEVATED;UI.scCopyBtn.AutoButtonColor=false;UI.scCopyBtn.Font=Enum.Font.GothamSemibold;UI.scCopyBtn.Text="Copy";UI.scCopyBtn.TextColor3=C.TEXT2;UI.scCopyBtn.TextSize=12;UI.scCopyBtn.BorderSizePixel=0;UI.scCopyBtn.ZIndex=3;UI.scCopyBtn.Parent=UI.scUrlRow;mkC(8,UI.scCopyBtn);mkS(1,C.BORDER_LIT,0.3,UI.scCopyBtn)
UI.scCopyBtn.MouseEnter:Connect(function() Svc.TS:Create(UI.scCopyBtn,TweenInfo.new(0.12),{BackgroundColor3=C.ACCENT_DIM,TextColor3=C.ACCENT}):Play() end);UI.scCopyBtn.MouseLeave:Connect(function() Svc.TS:Create(UI.scCopyBtn,TweenInfo.new(0.12),{BackgroundColor3=C.ELEVATED,TextColor3=C.TEXT2}):Play() end)
UI.scCopyBtn.MouseButton1Click:Connect(function()
local url=UI.scUrlBox.Text;if url=="" then return end
pcall(function() setclipboard(url) end)
local orig=UI.scCopyBtn.Text;UI.scCopyBtn.Text="Copied!";UI.scCopyBtn.TextColor3=C.SUCCESS
Svc.TS:Create(UI.scCopyBtn,TweenInfo.new(0.1),{BackgroundColor3=Color3.fromRGB(20,50,20)}):Play()
task.delay(1.8,function() UI.scCopyBtn.Text=orig;UI.scCopyBtn.TextColor3=C.TEXT2;Svc.TS:Create(UI.scCopyBtn,TweenInfo.new(0.12),{BackgroundColor3=C.ELEVATED}):Play() end)
end)
local function scSetSt(msg,col)
UI.scStatusLabel.Text=msg;local c=col or C.TEXT3;UI.scStatusLabel.TextColor3=c;if UI.scSDot then UI.scSDot.BackgroundColor3=c end
end
local function clearScArt()
St.scArtGen=St.scArtGen+1;UI.scArtImage.Image=""
Svc.TS:Create(UI.scArtImage,TweenInfo.new(0.15),{ImageTransparency=1}):Play()
Svc.TS:Create(UI.scArtTitleLabel,TweenInfo.new(0.12),{TextTransparency=1}):Play()
scArtGrad.Visible=false;scArtPlaceholder.Visible=false;UI.scArtStatus.Text="";scArtHint.Visible=true
end
local function fetchScArtForResult(result)
if not result then clearScArt();return end
St.scArtGen=St.scArtGen+1;local gen=St.scArtGen
UI.scArtImage.Image="";UI.scArtImage.ImageTransparency=1;UI.scArtTitleLabel.TextTransparency=1
scArtGrad.Visible=false;scArtPlaceholder.Visible=true;scArtPlaceholder.ImageTransparency=0.5;UI.scArtStatus.Text="loading art…";scArtHint.Visible=false
local trackTitle=result.title or "";local artUrl=result.artwork_url or (result.user and result.user.avatar_url) or nil
if not artUrl then
scArtPlaceholder.Visible=false;UI.scArtStatus.Text="no artwork"
if trackTitle~="" then UI.scArtTitleLabel.Text=trackTitle;scArtGrad.Visible=true;Svc.TS:Create(UI.scArtTitleLabel,TweenInfo.new(0.25),{TextTransparency=0}):Play() end
return
end
artUrl=artUrl:gsub("-large$","-t500x500"):gsub("-large%.jpg","-t500x500.jpg"):gsub("-large%.png","-t500x500.png")
task.spawn(function()
local iok,imgData=pcall(function() return request({Url=artUrl,Method="GET"}) end)
if not iok or not imgData or imgData.StatusCode~=200 or gen~=St.scArtGen then
if gen==St.scArtGen then scArtPlaceholder.Visible=false;UI.scArtStatus.Text="art unavailable" end;return
end
local body=imgData.Body or "";if #body<100 then scArtPlaceholder.Visible=false;UI.scArtStatus.Text="art unavailable";return end
local ext="jpg";if artUrl:lower():find("%.png") then ext="png" end
local tmpPath="Music Workspace/Configs/sc_art_"..gen.."_"..math.floor(tick())%99999 .."."..ext
if not isfolder(Cfg.configsPath) then makefolder(Cfg.configsPath) end
local wok=pcall(function() writefile(tmpPath,body) end)
if not wok or gen~=St.scArtGen then if gen==St.scArtGen then scArtPlaceholder.Visible=false;UI.scArtStatus.Text="art save failed" end;return end
local aok,assetId=pcall(function() return getcustomasset(tmpPath) end)
if not aok or not assetId or gen~=St.scArtGen then if gen==St.scArtGen then scArtPlaceholder.Visible=false;UI.scArtStatus.Text="art load failed" end;return end
UI.scArtImage.Image=assetId;UI.scArtImage.ImageTransparency=1
if trackTitle~="" then UI.scArtTitleLabel.Text=trackTitle;scArtGrad.Visible=true;UI.scArtTitleLabel.TextTransparency=1 end
UI.scArtStatus.Text=""
Svc.TS:Create(scArtPlaceholder,TweenInfo.new(0.25),{ImageTransparency=1}):Play();task.delay(0.25,function() scArtPlaceholder.Visible=false end)
Svc.TS:Create(UI.scArtImage,TweenInfo.new(0.35,Enum.EasingStyle.Quad),{ImageTransparency=0}):Play()
if trackTitle~="" then scArtGrad.Visible=true;Svc.TS:Create(UI.scArtTitleLabel,TweenInfo.new(0.25),{TextTransparency=0}):Play() end
end)
end
local function scUpdateDisplay()
local total=#St.scResults
if total==0 then UI.scCounterLabel.Text="0 / 0";UI.scUrlBox.Text="";clearScArt();return end
local idx=St.scIdx;local result=St.scResults[idx]
UI.scCounterLabel.Text=idx.." / "..total;UI.scCounterLabel.TextColor3=C.ACCENT
UI.scUrlBox.Text=result.permalink_url or ""
local policy=(result.policy or ""):upper()
local isSnipped=policy=="SNIPPED" or (result.duration and result.full_duration and result.full_duration>0 and result.duration<result.full_duration and result.duration<=31000)
if isSnipped then scSetSt("GO+ track — 30s preview only",C.DANGER) else scSetSt("",C.TEXT3) end
fetchScArtForResult(result)
UI.scPrevBtn.TextColor3=(idx>1) and C.TEXT2 or C.TEXT3;UI.scNextBtn.TextColor3=(idx<total) and C.TEXT2 or C.TEXT3
end
local function doScSearch()
local query=UI.scQueryBox.Text:match("^%s*(.-)%s*$");if query=="" then scSetSt("Enter a song title first",C.DANGER);return end
if St.scBusy then return end;St.scBusy=true;St.scGen=St.scGen+1;local gen=St.scGen
scSetSt("Fetching client_id…",C.ACCENT);UI.scSearchBtn.Text="…";UI.scSearchBtn.BackgroundColor3=C.ACCENT_DIM
clearScArt();St.scResults={};St.scIdx=1;UI.scCounterLabel.Text="…";UI.scUrlBox.Text=""
task.spawn(function()
local cid=St.scCid
if not cid then
local newCid,err=getSCClientId()
if not newCid or gen~=St.scGen then
if gen==St.scGen then scSetSt("client_id error: "..(err or "?"),C.DANGER);UI.scSearchBtn.Text="Search";UI.scSearchBtn.BackgroundColor3=C.ACCENT;UI.scCounterLabel.Text="0 / 0" end
St.scBusy=false;return
end
St.scCid=newCid;cid=newCid
end
if gen~=St.scGen then St.scBusy=false;return end
scSetSt("Searching…",C.ACCENT)
local encQ=ue(query)
local searchUrl="https://api-v2.soundcloud.com/search/tracks?q="..encQ.."&client_id="..cid.."&limit=20&linked_partitioning=1"
local ok,resp=pcall(function() return request({Url=searchUrl,Method="GET",Headers={["Accept"]="application/json",["User-Agent"]="Mozilla/5.0"}}) end)
if gen~=St.scGen then St.scBusy=false;return end
if not ok or not resp then
St.scCid=nil;scSetSt("Retrying with fresh client_id…",C.ACCENT)
local newCid2,err2=getSCClientId()
if not newCid2 or gen~=St.scGen then
if gen==St.scGen then scSetSt("Search failed: "..(err2 or "?"),C.DANGER);UI.scSearchBtn.Text="Search";UI.scSearchBtn.BackgroundColor3=C.ACCENT;UI.scCounterLabel.Text="0 / 0" end
St.scBusy=false;return
end
St.scCid=newCid2;cid=newCid2
ok,resp=pcall(function() return request({Url="https://api-v2.soundcloud.com/search/tracks?q="..encQ.."&client_id="..cid.."&limit=20",Method="GET",Headers={["Accept"]="application/json",["User-Agent"]="Mozilla/5.0"}}) end)
if gen~=St.scGen then St.scBusy=false;return end
end
if not ok or not resp or (resp.StatusCode~=200 and resp.StatusCode~=0) then
local code=resp and tostring(resp.StatusCode) or "?";scSetSt("HTTP error "..code,C.DANGER)
UI.scSearchBtn.Text="Search";UI.scSearchBtn.BackgroundColor3=C.ACCENT;UI.scCounterLabel.Text="0 / 0";St.scBusy=false;return
end
local pok,data=pcall(function() return Svc.HS:JSONDecode(resp.Body or resp.body or "") end)
if not pok or not data then scSetSt("Parse error",C.DANGER);UI.scSearchBtn.Text="Search";UI.scSearchBtn.BackgroundColor3=C.ACCENT;UI.scCounterLabel.Text="0 / 0";St.scBusy=false;return end
if gen~=St.scGen then St.scBusy=false;return end
local collection=data.collection or {}
if #collection==0 then
scSetSt("No results found for \""..query.."\"",C.TEXT3);UI.scSearchBtn.Text="Search";UI.scSearchBtn.BackgroundColor3=C.ACCENT;UI.scCounterLabel.Text="0 / 0";clearScArt();St.scBusy=false;return
end
St.scResults=collection;St.scIdx=1
scSetSt("Found "..#collection.." result"..(#collection==1 and "" or "s"),C.SUCCESS)
UI.scSearchBtn.Text="Search";UI.scSearchBtn.BackgroundColor3=C.ACCENT
scUpdateDisplay();St.scBusy=false
end)
end
UI.scSearchBtn.MouseButton1Click:Connect(function() doScSearch() end)
local function scClearAnimated()
local ct=TweenInfo.new(0.2,Enum.EasingStyle.Quad)
Svc.TS:Create(UI.scUrlBox,ct,{TextTransparency=1}):Play()
Svc.TS:Create(UI.scCounterLabel,ct,{TextTransparency=1}):Play()
if UI.scSearchBtn then Svc.TS:Create(UI.scSearchBtn,ct,{TextTransparency=0.5}):Play() end
St.scResults={};St.scIdx=1;clearScArt()
task.delay(0.2,function()
UI.scUrlBox.Text="";UI.scCounterLabel.Text="0 / 0"
Svc.TS:Create(UI.scUrlBox,ct,{TextTransparency=0}):Play()
Svc.TS:Create(UI.scCounterLabel,ct,{TextTransparency=0}):Play()
UI.scCounterLabel.TextColor3=C.TEXT3
if UI.scSearchBtn then Svc.TS:Create(UI.scSearchBtn,ct,{TextTransparency=0}):Play() end
end)
scSetSt("Enter a song title to search",C.TEXT3)
end
UI.scQueryBox.FocusLost:Connect(function(ep)
local q=UI.scQueryBox.Text:match("^%s*(.-)%s*$")
if ep and q~="" then doScSearch()
elseif q=="" then scClearAnimated() end
end)
UI.scQueryBox:GetPropertyChangedSignal("Text"):Connect(function()
local q=UI.scQueryBox.Text:match("^%s*(.-)%s*$")
if q=="" then scClearAnimated() end
end)
UI.scPrevBtn.MouseButton1Click:Connect(function()
if #St.scResults==0 then return end
St.scIdx=St.scIdx-1;if St.scIdx<1 then St.scIdx=#St.scResults end
scUpdateDisplay()
end)
UI.scNextBtn.MouseButton1Click:Connect(function()
if #St.scResults==0 then return end
St.scIdx=St.scIdx+1;if St.scIdx>#St.scResults then St.scIdx=1 end
scUpdateDisplay()
end)
end
local function getInc() return St.currentIncrement end
local function shorten(t,m) if #t<=m then return t end;return t:sub(1,m-3).."..." end
do
local TDT=1.0;local MAX_TOASTS=3
local toastPool={}
local activeToasts={}
local function stripExt(n) return tostring(n):gsub("%.[^%.%s]+%s*$",""):gsub("%s+$","") end
local function playNotifSnd() local ns=Instance.new("Sound");ns.SoundId="rbxassetid://140172825268473";ns.Volume=St.notifVolume;ns.RollOffMode=Enum.RollOffMode.InverseTapered;ns.Parent=soundsFolder;ns:Play();Svc.Deb:AddItem(ns,6) end
local function makeToastSlot(idx)
if idx==0 then
return {frame=UI.toast,scale=UI.toastScale,title=UI.toastTitle,sub=UI.toastSub,icon=UI.toastIcon,iconCircle=UI.toastIconCircle,pulse=UI.toastPulse,btn=UI.toastBtn,progressFill=UI.toastProgressFill,dismiss=false}
end
local f=Instance.new("Frame");f.AnchorPoint=Vector2.new(0.5,1);f.Position=UDim2.new(0.5,0,0,-6);f.Size=UDim2.new(0,310,0,56);f.BackgroundColor3=C.ELEVATED;f.BorderSizePixel=0;f.Visible=false;f.ZIndex=3;f.Parent=UI.main;mkC(14,f);mkS(1,C.BORDER_LIT,0.35,f)
local sc=Instance.new("UIScale");sc.Scale=0;sc.Parent=f
local tb=Instance.new("TextButton");tb.Size=UDim2.new(1,0,1,0);tb.BackgroundTransparency=1;tb.Text="";tb.AutoButtonColor=false;tb.ZIndex=3;tb.Parent=f
local ic=Instance.new("Frame");ic.AnchorPoint=Vector2.new(0,0.5);ic.Position=UDim2.new(0,14,0.5,0);ic.Size=UDim2.new(0,32,0,32);ic.BackgroundColor3=C.ACCENT;ic.BorderSizePixel=0;ic.ZIndex=3;ic.Parent=f;mkC(999,ic)
local pu=Instance.new("Frame");pu.AnchorPoint=Vector2.new(0.5,0.5);pu.Position=UDim2.new(0.5,0,0.5,0);pu.Size=UDim2.new(1,0,1,0);pu.BackgroundColor3=C.TEXT;pu.BackgroundTransparency=1;pu.BorderSizePixel=0;pu.ZIndex=3;pu.Parent=ic;mkC(999,pu)
local il=Instance.new("TextLabel");il.Size=UDim2.new(1,0,1,0);il.BackgroundTransparency=1;il.Font=Enum.Font.GothamBold;il.Text="+";il.TextColor3=C.BG;il.TextSize=17;il.ZIndex=3;il.Parent=ic
local tt=Instance.new("TextLabel");tt.AnchorPoint=Vector2.new(0,1);tt.Position=UDim2.new(0,56,0.5,-2);tt.Size=UDim2.new(1,-64,0,18);tt.BackgroundTransparency=1;tt.Font=Enum.Font.GothamSemibold;tt.Text="";tt.TextColor3=C.TEXT;tt.TextXAlignment=Enum.TextXAlignment.Left;tt.TextSize=13;tt.TextTruncate=Enum.TextTruncate.AtEnd;tt.ZIndex=3;tt.Parent=f
local ts=Instance.new("TextLabel");ts.AnchorPoint=Vector2.new(0,0);ts.Position=UDim2.new(0,56,0.5,2);ts.Size=UDim2.new(1,-64,0,14);ts.BackgroundTransparency=1;ts.Font=Enum.Font.GothamMedium;ts.Text="";ts.TextColor3=C.ACCENT;ts.TextXAlignment=Enum.TextXAlignment.Left;ts.TextSize=11;ts.ZIndex=3;ts.Parent=f
local pt=Instance.new("Frame");pt.AnchorPoint=Vector2.new(0,1);pt.Position=UDim2.new(0,14,1,-5);pt.Size=UDim2.new(1,-28,0,3);pt.BackgroundColor3=C.BG;pt.BorderSizePixel=0;pt.ZIndex=3;pt.Parent=f;mkC(999,pt)
local pf=Instance.new("Frame");pf.Size=UDim2.new(1,0,1,0);pf.BackgroundColor3=C.ACCENT;pf.BorderSizePixel=0;pf.ZIndex=4;pf.Parent=pt;mkC(999,pf)
return {frame=f,scale=sc,title=tt,sub=ts,icon=il,iconCircle=ic,pulse=pu,btn=tb,progressFill=pf,dismiss=false}
end
for i=0,MAX_TOASTS-1 do toastPool[i]=makeToastSlot(i) end
local function getToastY(slotInStack)
return UDim2.new(0.5,0,0,-(6 + slotInStack*62))
end
local function repositionToasts(animated)
for i,slot in ipairs(activeToasts) do
local target=getToastY(i-1)
if animated then Svc.TS:Create(slot.frame,TweenInfo.new(0.18,Enum.EasingStyle.Quad),{Position=target}):Play()
else slot.frame.Position=target end
end
end
local function dismissToast(slot)
slot.dismiss=true
end
local function showNextFromQueue()
if #Dat.notificationQueue==0 then return end
if #activeToasts>=MAX_TOASTS then return end
local poolSlot=nil
for i=0,MAX_TOASTS-1 do
local inUse=false;for _,as in ipairs(activeToasts) do if as==toastPool[i] then inUse=true;break end end
if not inUse then poolSlot=toastPool[i];break end
end
if not poolSlot then return end
local n=table.remove(Dat.notificationQueue,1)
local ac=n.isRemoval and C.ACCENT_DIM or C.ACCENT
poolSlot.title.Text=stripExt(n.text);poolSlot.sub.Text=n.isRemoval and "track removed" or "track loaded";poolSlot.sub.TextColor3=ac
poolSlot.icon.Text=n.isRemoval and "−" or "+";poolSlot.iconCircle.BackgroundColor3=ac
poolSlot.progressFill.BackgroundColor3=ac;poolSlot.progressFill.Size=UDim2.new(1,0,1,0)
poolSlot.pulse.BackgroundTransparency=1;poolSlot.dismiss=false
table.insert(activeToasts,1,poolSlot)
repositionToasts(true)
poolSlot.scale.Scale=0;poolSlot.frame.Visible=true
Svc.TS:Create(poolSlot.scale,TweenInfo.new(0.18,Enum.EasingStyle.Back,Enum.EasingDirection.Out),{Scale=1}):Play()
playNotifSnd()
local cc;cc=poolSlot.btn.MouseButton1Click:Connect(function()
poolSlot.pulse.BackgroundTransparency=0
Svc.TS:Create(poolSlot.pulse,TweenInfo.new(0.5,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{BackgroundTransparency=1}):Play()
poolSlot.dismiss=true;cc:Disconnect()
end)
task.spawn(function()
local pbTween=Svc.TS:Create(poolSlot.progressFill,TweenInfo.new(TDT,Enum.EasingStyle.Linear),{Size=UDim2.new(0,0,1,0)});pbTween:Play()
local el=0;while el<TDT and not poolSlot.dismiss do task.wait(0.05);el=el+0.05 end
pbTween:Cancel()
for i=#activeToasts,1,-1 do if activeToasts[i]==poolSlot then table.remove(activeToasts,i);break end end
Svc.TS:Create(poolSlot.scale,TweenInfo.new(0.14,Enum.EasingStyle.Quad,Enum.EasingDirection.In),{Scale=0}):Play()
task.wait(0.16);poolSlot.frame.Visible=false;poolSlot.frame.Position=getToastY(0)
repositionToasts(true)
task.wait(0.05);showNextFromQueue()
end)
end
showNotification=function(msg,isRem)
local dn=stripExt(msg);table.insert(Dat.notificationQueue,{text=dn,isRemoval=isRem})
if #activeToasts<MAX_TOASTS then showNextFromQueue() end
end
end
local function fmtTime(s) if s~=s then return "0:00" end;s=math.max(0,s);return string.format("%d:%02d",math.floor(s/60),math.floor(s%60)) end
task.spawn(function() while true do task.wait(1);if UI.timeDisplayContainer then local lg={[UI.timeDisplay]=true,[UI.nextTimeDisplay]=true};for _,c in ipairs(UI.timeDisplayContainer:GetChildren()) do if c:IsA("TextLabel") and not lg[c] then c:Destroy() end end end end end)
local function animTrack(dn,fn)
if Dat.currentTrackAnimationTween then Dat.currentTrackAnimationTween:Cancel();Dat.currentTrackAnimationTween=nil;UI.currentTrackButton.TextTransparency=0;UI.nextTrackLabel.TextTransparency=1 end
Dat.trackAnimGen=(Dat.trackAnimGen or 0)+1;local mg=Dat.trackAnimGen
UI.nextTrackLabel.Text=dn;UI.tooltipText.Text=fn
local fo=Svc.TS:Create(UI.currentTrackButton,TweenInfo.new(0.25,Enum.EasingStyle.Quad),{TextTransparency=1})
local fi=Svc.TS:Create(UI.nextTrackLabel,TweenInfo.new(0.25,Enum.EasingStyle.Quad),{TextTransparency=0})
Dat.currentTrackAnimationTween=fo
fo.Completed:Connect(function(st) if Dat.trackAnimGen~=mg then return end;if st~=Enum.TweenStatus.Completed then return end;UI.currentTrackButton.Text=dn;UI.currentTrackButton.TextTransparency=0;UI.nextTrackLabel.TextTransparency=1;Dat.currentTrackAnimationTween=nil end)
fo:Play();fi:Play()
end
local function animTime(t) UI.timeDisplay.TextTransparency=0;UI.nextTimeDisplay.TextTransparency=1;UI.timeDisplay.Text=t;St.lastDisplayedTime=t end
local function updTrack(dn,fn) animTrack(dn,fn) end
local function mkSlider(par,lbl,yo,mn,mx,def,dec,giFn,sv,st2,cb)
local sf=Instance.new("Frame");sf.Size=UDim2.new(1,0,0,44);sf.Position=UDim2.new(0,0,0,yo);sf.BackgroundTransparency=1;sf.ZIndex=3;sf.Parent=par
local l=Instance.new("TextLabel");l.Position=UDim2.new(0,0,0,0);l.Size=UDim2.new(0.55,0,0,16);l.BackgroundTransparency=1;l.Font=Enum.Font.GothamMedium;l.Text=lbl;l.TextColor3=C.TEXT2;l.TextXAlignment=Enum.TextXAlignment.Left;l.TextSize=13;l.ZIndex=3;l.Parent=sf
local vb=Instance.new("TextBox");vb.AnchorPoint=Vector2.new(1,0);vb.Position=UDim2.new(1,0,0,0);vb.Size=UDim2.new(0,52,0,16);vb.BackgroundTransparency=1;vb.Font=Enum.Font.GothamMedium;vb.Text=tostring(def);vb.TextColor3=C.ACCENT;vb.TextXAlignment=Enum.TextXAlignment.Right;vb.TextSize=13;vb.ClearTextOnFocus=false;vb.ZIndex=3;vb.Parent=sf
local bar=Instance.new("Frame");bar.AnchorPoint=Vector2.new(0,0.5);bar.Position=UDim2.new(0,0,0,32);bar.Size=UDim2.new(1,0,0,4);bar.BackgroundColor3=C.ELEVATED;bar.BorderSizePixel=0;bar.ZIndex=3;bar.Parent=sf;mkC(999,bar)
local fill=Instance.new("Frame");fill.AnchorPoint=Vector2.new(0,0.5);fill.Position=UDim2.new(0,0,0.5,0);fill.Size=UDim2.new(0,0,1,0);fill.BackgroundColor3=C.ACCENT;fill.BorderSizePixel=0;fill.ZIndex=4;fill.Parent=bar;mkC(999,fill)
local hdl=Instance.new("TextButton");hdl.AnchorPoint=Vector2.new(0.5,0.5);hdl.Position=UDim2.new(0,0,0.5,0);hdl.Size=UDim2.new(0,13,0,13);hdl.BackgroundColor3=C.HANDLE;hdl.BorderSizePixel=0;hdl.Text="";hdl.AutoButtonColor=false;hdl.ZIndex=5;hdl.Parent=bar;mkC(999,hdl)
local hit=Instance.new("TextButton");hit.AnchorPoint=Vector2.new(0,0.5);hit.Position=UDim2.new(0,0,0,32);hit.Size=UDim2.new(1,0,0,24);hit.BackgroundTransparency=1;hit.BorderSizePixel=0;hit.Text="";hit.AutoButtonColor=false;hit.ZIndex=6;hit.Parent=sf
local drag=false;local cv=def;local hovering=false
local function cl01(x) return x<0 and 0 or(x>1 and 1 or x) end
local function quant(v)
local inc=giFn and giFn() or 0;if inc and inc>0 then local steps=math.floor(v/inc+0.5+1e-9);v=steps*inc;local pl=math.max(0,math.ceil(-math.log(inc)/math.log(10)+0.5));local m=10^pl;v=math.floor(v*m+0.5)/m end
if v<mn then v=mn elseif v>mx then v=mx end;return v
end
local function applyV(v,byp)
if byp then if v<mn then v=mn elseif v>mx then v=mx end
else v=quant(v);if sv~=nil and st2~=nil then local inc=giFn and giFn() or 0;local et=(inc>0) and math.min(st2,inc*0.5) or st2;if math.abs(v-sv)<=et then v=sv end end end
cv=v;local al=mx~=mn and cl01((v-mn)/(mx-mn)) or 0
if bar.AbsoluteSize.X>0 then fill.Size=UDim2.new(al,0,1,0);hdl.Position=UDim2.new(al,0,0.5,0) end
local mt=10^(dec or 0);vb.Text=tostring(math.floor(v*mt+0.5)/mt);if cb then cb(v) end
end
local function fromX(x) applyV(mn+(mx-mn)*cl01((x-hit.AbsolutePosition.X)/(hit.AbsoluteSize.X>0 and hit.AbsoluteSize.X or 1))) end
local function fromM() fromX(Svc.UIS:GetMouseLocation().X) end
hit.MouseButton1Down:Connect(function() drag=true;fromM() end);hdl.MouseButton1Down:Connect(function() drag=true;fromM() end)
Svc.UIS.InputChanged:Connect(function(inp) if drag and inp.UserInputType==Enum.UserInputType.MouseMovement then fromM() end end)
Svc.UIS.InputEnded:Connect(function(inp) if inp.UserInputType==Enum.UserInputType.MouseButton1 then drag=false end end)
vb.Focused:Connect(function() vb.Text="" end);vb.FocusLost:Connect(function() local n=tonumber(vb.Text);if n then applyV(n,true) else vb.Text=tostring(cv) end end)
hit.MouseEnter:Connect(function() hovering=true end);hit.MouseLeave:Connect(function() hovering=false end)
Svc.UIS.InputChanged:Connect(function(inp)
if not hovering then return end
if inp.UserInputType==Enum.UserInputType.MouseWheel then
local delta=inp.Position.Z
applyV(cv+delta*0.1,false)
end
end)
task.defer(function() applyV(def) end);return {SetValue=applyV,GetValue=function() return cv end,ValueBox=vb,SetHover=function(v) hovering=v end}
end
local function mkToggle(par,txt,xo,cb)
local btn=Instance.new("TextButton");btn.Size=UDim2.new(0,78,0,26);btn.Position=UDim2.new(0,xo,0,0);btn.BackgroundColor3=C.SURFACE;btn.AutoButtonColor=false;btn.Text=txt;btn.Font=Enum.Font.GothamMedium;btn.TextSize=12;btn.TextColor3=C.TEXT3;btn.BorderSizePixel=0;btn.ZIndex=3;btn.Parent=par;mkC(8,btn)
local str=mkS(1,C.BORDER,0.2,btn);local act=false
local function ref() if act then btn.BackgroundColor3=C.ACCENT;btn.TextColor3=AT;str.Transparency=1 else btn.BackgroundColor3=C.SURFACE;btn.TextColor3=C.TEXT3;str.Transparency=0.2 end end
btn.MouseButton1Click:Connect(function() act=not act;ref();if cb then cb(act) end end);ref()
return {Button=btn,GetActive=function() return act end,SetActive=function(s) act=s and true or false;ref();if cb then cb(act) end end}
end
UI.trackRow=Instance.new("Frame");UI.trackRow.Size=UDim2.new(1,0,0,68);UI.trackRow.BackgroundTransparency=1;UI.trackRow.ZIndex=3;UI.trackRow.Parent=UI.content
do local npL=Instance.new("TextLabel");npL.Position=UDim2.new(0,0,0,30);npL.Size=UDim2.new(1,-36,0,12);npL.BackgroundTransparency=1;npL.Font=Enum.Font.GothamMedium;npL.Text="NOW PLAYING";npL.TextColor3=C.TEXT3;npL.TextXAlignment=Enum.TextXAlignment.Left;npL.TextSize=9;npL.ZIndex=3;npL.Parent=UI.trackRow end
UI.trackNameContainer=Instance.new("Frame");UI.trackNameContainer.Position=UDim2.new(0,0,0,43);UI.trackNameContainer.Size=UDim2.new(1,-46,0,22);UI.trackNameContainer.BackgroundTransparency=1;UI.trackNameContainer.ClipsDescendants=true;UI.trackNameContainer.ZIndex=3;UI.trackNameContainer.Parent=UI.trackRow
UI.currentTrackButton=Instance.new("TextButton");UI.currentTrackButton.Size=UDim2.new(1,0,1,0);UI.currentTrackButton.BackgroundTransparency=1;UI.currentTrackButton.Font=Enum.Font.GothamMedium;UI.currentTrackButton.Text="";UI.currentTrackButton.TextColor3=C.TEXT;UI.currentTrackButton.TextXAlignment=Enum.TextXAlignment.Left;UI.currentTrackButton.TextSize=14;UI.currentTrackButton.AutoButtonColor=false;UI.currentTrackButton.TextTransparency=0;UI.currentTrackButton.TextTruncate=Enum.TextTruncate.AtEnd;UI.currentTrackButton.ZIndex=4;UI.currentTrackButton.Parent=UI.trackNameContainer
UI.nextTrackLabel=Instance.new("TextLabel");UI.nextTrackLabel.Size=UDim2.new(1,0,1,0);UI.nextTrackLabel.BackgroundTransparency=1;UI.nextTrackLabel.Font=Enum.Font.GothamMedium;UI.nextTrackLabel.Text="";UI.nextTrackLabel.TextColor3=C.TEXT;UI.nextTrackLabel.TextXAlignment=Enum.TextXAlignment.Left;UI.nextTrackLabel.TextSize=14;UI.nextTrackLabel.TextTransparency=1;UI.nextTrackLabel.TextTruncate=Enum.TextTruncate.AtEnd;UI.nextTrackLabel.ZIndex=3;UI.nextTrackLabel.Parent=UI.trackNameContainer
UI.tooltip=Instance.new("Frame");UI.tooltip.AnchorPoint=Vector2.new(0,1);UI.tooltip.Size=UDim2.new(0,0,0,22);UI.tooltip.AutomaticSize=Enum.AutomaticSize.X;UI.tooltip.BackgroundColor3=C.ELEVATED;UI.tooltip.BorderSizePixel=0;UI.tooltip.Visible=false;UI.tooltip.ZIndex=20;UI.tooltip.Parent=UI.main;mkC(6,UI.tooltip);mkS(1,C.BORDER_LIT,0.3,UI.tooltip)
do local tp=Instance.new("UIPadding");tp.PaddingLeft=UDim.new(0,8);tp.PaddingRight=UDim.new(0,8);tp.Parent=UI.tooltip end
UI.tooltipText=Instance.new("TextLabel");UI.tooltipText.Size=UDim2.new(0,0,1,0);UI.tooltipText.AutomaticSize=Enum.AutomaticSize.X;UI.tooltipText.BackgroundTransparency=1;UI.tooltipText.Font=Enum.Font.Gotham;UI.tooltipText.Text="";UI.tooltipText.TextColor3=C.TEXT;UI.tooltipText.TextXAlignment=Enum.TextXAlignment.Left;UI.tooltipText.TextSize=11;UI.tooltipText.TextTruncate=Enum.TextTruncate.None;UI.tooltipText.ZIndex=21;UI.tooltipText.Parent=UI.tooltip
local ctrlC=Instance.new("Frame");ctrlC.Size=UDim2.new(1,0,0,32);ctrlC.BackgroundTransparency=1;ctrlC.ZIndex=3;ctrlC.Parent=UI.trackRow
local cL=Instance.new("UIListLayout");cL.FillDirection=Enum.FillDirection.Horizontal;cL.HorizontalAlignment=Enum.HorizontalAlignment.Center;cL.VerticalAlignment=Enum.VerticalAlignment.Center;cL.SortOrder=Enum.SortOrder.LayoutOrder;cL.Padding=UDim.new(0,6);cL.Parent=ctrlC
local function mkITBtn(nm,sym,lo,cb,cw)
local btn=Instance.new("TextButton");btn.Name=nm;btn.Size=UDim2.new(0,cw or 48,0,26);btn.BackgroundColor3=C.SURFACE;btn.AutoButtonColor=false;btn.Font=Enum.Font.GothamBold;btn.Text=sym;btn.TextSize=11;btn.TextColor3=C.TEXT2;btn.BorderSizePixel=0;btn.LayoutOrder=lo;btn.ZIndex=3;btn.Parent=ctrlC;mkC(8,btn)
local str=mkS(1,C.BORDER,0.2,btn);local dot=Instance.new("Frame");dot.AnchorPoint=Vector2.new(0.5,0);dot.Position=UDim2.new(0.5,0,1,3);dot.Size=UDim2.new(0,20,0,2);dot.BackgroundColor3=C.ACCENT;dot.BackgroundTransparency=1;dot.BorderSizePixel=0;dot.ZIndex=4;dot.Parent=btn;mkC(999,dot)
local act=false
local function ref() local ct=TweenInfo.new(0.2,Enum.EasingStyle.Quad,Enum.EasingDirection.Out);if act then Svc.TS:Create(btn,ct,{BackgroundColor3=C.ACCENT}):Play();Svc.TS:Create(btn,ct,{TextColor3=AT}):Play();str.Transparency=1;dot.BackgroundTransparency=0 else Svc.TS:Create(btn,ct,{BackgroundColor3=C.SURFACE}):Play();Svc.TS:Create(btn,ct,{TextColor3=C.TEXT2}):Play();str.Transparency=0.2;dot.BackgroundTransparency=1 end end
btn.MouseButton1Click:Connect(function() act=not act;ref();if cb then cb(act) end end)
btn.MouseEnter:Connect(function() if not act then btn.TextColor3=C.TEXT end end);btn.MouseLeave:Connect(ref);ref()
return {Button=btn,Dot=dot,GetActive=function() return act end,SetActive=function(s) act=s and true or false;ref();if cb then cb(act) end end,SetActiveSilent=function(s) act=s and true or false;ref() end,RefreshTheme=function() str.Color=C.BORDER;dot.BackgroundColor3=C.ACCENT;ref() end}
end
UI.prevBtn=Instance.new("TextButton");UI.prevBtn.Size=UDim2.new(0,36,0,26);UI.prevBtn.BackgroundColor3=C.SURFACE;UI.prevBtn.AutoButtonColor=false;UI.prevBtn.Font=Enum.Font.GothamBold;UI.prevBtn.Text="<<";UI.prevBtn.TextSize=11;UI.prevBtn.TextColor3=C.TEXT2;UI.prevBtn.BorderSizePixel=0;UI.prevBtn.LayoutOrder=1;UI.prevBtn.ZIndex=3;UI.prevBtn.Parent=ctrlC;mkC(8,UI.prevBtn);mkS(1,C.BORDER,0.2,UI.prevBtn)
UI.repeatToggle=mkITBtn("RepeatButton","repeat",2,function(on) St.repeatEnabled=on;if on and UI.shuffleToggle and UI.shuffleToggle.GetActive() then UI.shuffleToggle.SetActiveSilent(false);St.shuffleEnabled=false end;saveSettings() end,48)
UI.playPauseBtn=Instance.new("TextButton");UI.playPauseBtn.Size=UDim2.new(0,88,0,28);UI.playPauseBtn.BackgroundColor3=C.ACCENT;UI.playPauseBtn.AutoButtonColor=false;UI.playPauseBtn.Font=Enum.Font.GothamSemibold;UI.playPauseBtn.TextSize=13;UI.playPauseBtn.TextColor3=AT;UI.playPauseBtn.Text="play";UI.playPauseBtn.BorderSizePixel=0;UI.playPauseBtn.LayoutOrder=3;UI.playPauseBtn.ZIndex=3;UI.playPauseBtn.Parent=ctrlC;mkC(9,UI.playPauseBtn)
UI.shuffleToggle=mkITBtn("ShuffleButton","shuffle",4,function(on) St.shuffleEnabled=on;if on and UI.repeatToggle and UI.repeatToggle.GetActive() then UI.repeatToggle.SetActiveSilent(false);St.repeatEnabled=false end;saveSettings() end,48)
UI.nextBtn=Instance.new("TextButton");UI.nextBtn.Size=UDim2.new(0,36,0,26);UI.nextBtn.BackgroundColor3=C.SURFACE;UI.nextBtn.AutoButtonColor=false;UI.nextBtn.Font=Enum.Font.GothamBold;UI.nextBtn.Text=">>";UI.nextBtn.TextSize=11;UI.nextBtn.TextColor3=C.TEXT2;UI.nextBtn.BorderSizePixel=0;UI.nextBtn.LayoutOrder=5;UI.nextBtn.ZIndex=3;UI.nextBtn.Parent=ctrlC;mkC(8,UI.nextBtn);mkS(1,C.BORDER,0.2,UI.nextBtn)
UI.meterFrame=Instance.new("Frame");UI.meterFrame.AnchorPoint=Vector2.new(1,0.5);UI.meterFrame.Position=UDim2.new(1,0,0,47);UI.meterFrame.Size=UDim2.new(0,28,0,18);UI.meterFrame.BackgroundTransparency=1;UI.meterFrame.ZIndex=5;UI.meterFrame.Parent=UI.trackRow
local function mkMBar(x) local b=Instance.new("Frame");b.AnchorPoint=Vector2.new(0.5,1);b.Position=UDim2.new(0,x,1,0);b.Size=UDim2.new(0,3,0.18,0);b.BackgroundColor3=C.ACCENT;b.BackgroundTransparency=0.5;b.BorderSizePixel=0;b.ZIndex=5;b.Parent=UI.meterFrame;mkC(999,b);table.insert(Dat.meterBars,b) end
mkMBar(5);mkMBar(13);mkMBar(21)
UI.progressBar=Instance.new("TextButton");UI.progressBar.Position=UDim2.new(0,0,0,74);UI.progressBar.Size=UDim2.new(1,0,0,5);UI.progressBar.BackgroundColor3=C.ELEVATED;UI.progressBar.BorderSizePixel=0;UI.progressBar.ZIndex=3;UI.progressBar.Text="";UI.progressBar.AutoButtonColor=false;UI.progressBar.Parent=UI.content;mkC(999,UI.progressBar)
UI.progressFill=Instance.new("Frame");UI.progressFill.AnchorPoint=Vector2.new(0,0.5);UI.progressFill.Position=UDim2.new(0,0,0.5,0);UI.progressFill.Size=UDim2.new(0,0,1,0);UI.progressFill.BackgroundColor3=C.ACCENT;UI.progressFill.BorderSizePixel=0;UI.progressFill.ZIndex=4;UI.progressFill.Parent=UI.progressBar;mkC(999,UI.progressFill)
UI.timeDisplayContainer=Instance.new("Frame");UI.timeDisplayContainer.AnchorPoint=Vector2.new(0.5,0);UI.timeDisplayContainer.Position=UDim2.new(0.5,0,1,4);UI.timeDisplayContainer.Size=UDim2.new(0,110,0,12);UI.timeDisplayContainer.BackgroundTransparency=1;UI.timeDisplayContainer.ClipsDescendants=true;UI.timeDisplayContainer.ZIndex=5;UI.timeDisplayContainer.Parent=UI.progressBar
local function mkTL(nm,tr) local l=Instance.new("TextLabel");l.Name=nm;l.AnchorPoint=Vector2.new(0.5,0);l.Position=UDim2.new(0.5,0,0,0);l.Size=UDim2.new(1,0,1,0);l.BackgroundTransparency=1;l.Font=Enum.Font.GothamMedium;l.Text="0:00 / 0:00";l.TextColor3=C.TEXT3;l.TextSize=10;l.TextTransparency=tr;l.ZIndex=6;l.Parent=UI.timeDisplayContainer;return l end
UI.timeDisplay=mkTL("TimeDisplay",0);UI.nextTimeDisplay=mkTL("NextTimeDisplay",1)
local function updProgX(x) if not sound or not sound.TimeLength or sound.TimeLength==0 then return end;local a=math.clamp((x-UI.progressBar.AbsolutePosition.X)/UI.progressBar.AbsoluteSize.X,0,1);UI.progressFill.Size=UDim2.new(a,0,1,0);pcall(function() sound.TimePosition=math.min(a*sound.TimeLength,math.max(0,sound.TimeLength-0.1)) end) end
local function updProgM() updProgX(Svc.UIS:GetMouseLocation().X) end
UI.progressBar.MouseButton1Down:Connect(function() if not sound then return end;St.draggingProgress=true;St.wasPlayingBeforeDrag=sound.IsPlaying;if sound.IsPlaying then pcall(function() sound:Pause() end) end;updProgM() end)
Svc.UIS.InputChanged:Connect(function(inp) if St.draggingProgress and inp.UserInputType==Enum.UserInputType.MouseMovement then updProgM() end end)
Svc.UIS.InputEnded:Connect(function(inp) if inp.UserInputType==Enum.UserInputType.MouseButton1 and St.draggingProgress then St.draggingProgress=false;if St.wasPlayingBeforeDrag and sound and not sound.IsPlaying then pcall(function() sound:Resume() end);if not sound.IsPlaying then sound:Play() end end end end)
do
local ptip=Instance.new("Frame");ptip.Name="ProgressTooltip";ptip.AnchorPoint=Vector2.new(0.5,1);ptip.Size=UDim2.new(0,48,0,18);ptip.BackgroundColor3=C.ELEVATED;ptip.BorderSizePixel=0;ptip.ZIndex=10;ptip.Visible=false;ptip.Parent=UI.progressBar;mkC(6,ptip);mkS(1,C.BORDER_LIT,0.3,ptip)
local ptipL=Instance.new("TextLabel");ptipL.Size=UDim2.new(1,0,1,0);ptipL.BackgroundTransparency=1;ptipL.Font=Enum.Font.GothamMedium;ptipL.Text="0:00";ptipL.TextColor3=C.TEXT;ptipL.TextSize=11;ptipL.ZIndex=11;ptipL.Parent=ptip
UI.progressBar.MouseEnter:Connect(function() if sound and sound.TimeLength and sound.TimeLength>0 then ptip.Visible=true end end)
UI.progressBar.MouseLeave:Connect(function() ptip.Visible=false end)
Svc.UIS.InputChanged:Connect(function(inp)
if inp.UserInputType~=Enum.UserInputType.MouseMovement then return end
if not ptip.Visible then return end
if not sound or not sound.TimeLength or sound.TimeLength==0 then ptip.Visible=false;return end
local mx=Svc.UIS:GetMouseLocation().X
local barX=UI.progressBar.AbsolutePosition.X;local barW=UI.progressBar.AbsoluteSize.X
local frac=math.clamp((mx-barX)/barW,0,1)
local secs=math.floor(frac*sound.TimeLength+0.5)
ptipL.Text=string.format("%d:%02d",math.floor(secs/60),secs%60)
local relX=math.clamp(mx-barX,0,barW)
ptip.Position=UDim2.new(0,relX,0,-4)
end)
end
do local sep1=Instance.new("Frame");sep1.Position=UDim2.new(0,0,0,88);sep1.Size=UDim2.new(1,0,0,1);sep1.BackgroundColor3=C.BORDER;sep1.BorderSizePixel=0;sep1.ZIndex=2;sep1.Parent=UI.content end
mkSlider(UI.content,"volume",92,Cfg.SLIDER_MIN,Cfg.SLIDER_MAX,St.currentVolume,2,getInc,Cfg.SNAP_VALUE,Cfg.SNAP_THRESHOLD,function(v) St.currentVolume=v;if sound then sound.Volume=math.max(0,v) end;saveSettings() end)
mkSlider(UI.content,"speed",140,Cfg.SLIDER_MIN,Cfg.SLIDER_MAX,St.currentSpeed,2,getInc,Cfg.SNAP_VALUE,Cfg.SNAP_THRESHOLD,function(v) St.currentSpeed=v;if sound then sound.PlaybackSpeed=(v<=0) and 0.01 or v end;saveSettings() end)
do local sep2=Instance.new("Frame");sep2.Position=UDim2.new(0,0,0,186);sep2.Size=UDim2.new(1,0,0,1);sep2.BackgroundColor3=C.BORDER;sep2.BorderSizePixel=0;sep2.ZIndex=2;sep2.Parent=UI.content end
do local fxL=Instance.new("TextLabel");fxL.Position=UDim2.new(0,0,0,191);fxL.Size=UDim2.new(1,0,0,14);fxL.BackgroundTransparency=1;fxL.Font=Enum.Font.GothamMedium;fxL.Text="EFFECTS";fxL.TextColor3=C.TEXT3;fxL.TextXAlignment=Enum.TextXAlignment.Left;fxL.TextSize=9;fxL.ZIndex=3;fxL.Parent=UI.content;end
local fxRow=Instance.new("Frame");fxRow.Position=UDim2.new(0,0,0,208);fxRow.Size=UDim2.new(1,0,0,26);fxRow.BackgroundTransparency=1;fxRow.ZIndex=3;fxRow.Parent=UI.content
mkToggle(fxRow,"reverb",0,function(on) reverb.Enabled=on;setRevPanel(on) end);mkToggle(fxRow,"distort",88,function(on) distortion.Enabled=on end)
mkToggle(fxRow,"equalizer",176,function(on) equalizer.Enabled=on end);mkToggle(fxRow,"chorus",264,function(on) chorus.Enabled=on end)
do local sep3=Instance.new("Frame");sep3.Position=UDim2.new(0,0,0,238);sep3.Size=UDim2.new(1,0,0,1);sep3.BackgroundColor3=C.BORDER;sep3.BorderSizePixel=0;sep3.ZIndex=2;sep3.Parent=UI.content end
local incRow=Instance.new("Frame");incRow.Position=UDim2.new(0,0,0,243);incRow.Size=UDim2.new(1,0,0,20);incRow.BackgroundTransparency=1;incRow.ZIndex=3;incRow.Parent=UI.content;do local incL=Instance.new("TextLabel");incL.Position=UDim2.new(0,0,0,0);incL.Size=UDim2.new(0.5,0,1,0);incL.BackgroundTransparency=1;incL.Font=Enum.Font.GothamMedium;incL.Text="increment";incL.TextColor3=C.TEXT2;incL.TextXAlignment=Enum.TextXAlignment.Left;incL.TextSize=13;incL.ZIndex=3;incL.Parent=incRow end
UI.incrementBox=Instance.new("TextBox");UI.incrementBox.AnchorPoint=Vector2.new(1,0.5);UI.incrementBox.Position=UDim2.new(1,0,0.5,0);UI.incrementBox.Size=UDim2.new(0,64,0,18);UI.incrementBox.BackgroundColor3=C.SURFACE;UI.incrementBox.BorderSizePixel=0;UI.incrementBox.Font=Enum.Font.GothamMedium;UI.incrementBox.Text=tostring(St.currentIncrement);UI.incrementBox.TextColor3=C.ACCENT;UI.incrementBox.TextXAlignment=Enum.TextXAlignment.Right;UI.incrementBox.TextSize=12;UI.incrementBox.ClearTextOnFocus=false;UI.incrementBox.ZIndex=3;UI.incrementBox.Parent=incRow;mkC(7,UI.incrementBox);mkS(1,C.BORDER,0.2,UI.incrementBox)
do local ipPad=Instance.new("UIPadding");ipPad.PaddingRight=UDim.new(0,6);ipPad.Parent=UI.incrementBox end
UI.incrementBox.Focused:Connect(function() UI.incrementBox.Text="" end)
UI.incrementBox.FocusLost:Connect(function() local n=tonumber(UI.incrementBox.Text);if n then if n<=0 then n=0.0000001 end;n=math.floor(n*1e6+0.5)/1e6;St.currentIncrement=n;UI.incrementBox.Text=tostring(n);saveSettings() else UI.incrementBox.Text=tostring(St.currentIncrement) end end)
UI.reverbPanel=Instance.new("Frame");UI.reverbPanel.Position=UDim2.new(0,0,0,267);UI.reverbPanel.Size=UDim2.new(1,0,0,140);UI.reverbPanel.BackgroundTransparency=1;UI.reverbPanel.Visible=false;UI.reverbPanel.ZIndex=3;UI.reverbPanel.Parent=UI.content
do local rvH=Instance.new("TextLabel");rvH.Position=UDim2.new(0,0,0,0);rvH.Size=UDim2.new(1,0,0,14);rvH.BackgroundTransparency=1;rvH.Font=Enum.Font.GothamMedium;rvH.Text="REVERB SETTINGS";rvH.TextColor3=C.TEXT3;rvH.TextXAlignment=Enum.TextXAlignment.Left;rvH.TextSize=9;rvH.ZIndex=3;rvH.Parent=UI.reverbPanel end
local function mkRF(lbl,prop,ord)
local row=Instance.new("Frame");row.Size=UDim2.new(1,0,0,Cfg.RH);row.Position=UDim2.new(0,0,0,18+(ord-1)*(Cfg.RH+Cfg.RG));row.BackgroundTransparency=1;row.ZIndex=3;row.Parent=UI.reverbPanel
local l=Instance.new("TextLabel");l.Position=UDim2.new(0,0,0,0);l.Size=UDim2.new(0.5,0,1,0);l.BackgroundTransparency=1;l.Font=Enum.Font.Gotham;l.Text=lbl;l.TextColor3=C.TEXT2;l.TextXAlignment=Enum.TextXAlignment.Left;l.TextSize=12;l.ZIndex=3;l.Parent=row
local b=Instance.new("TextBox");b.AnchorPoint=Vector2.new(1,0.5);b.Position=UDim2.new(1,0,0.5,0);b.Size=UDim2.new(0,72,0,Cfg.RH-2);b.BackgroundColor3=C.SURFACE;b.BorderSizePixel=0;b.Font=Enum.Font.GothamMedium;local cv=reverb[prop];b.Text=tostring(cv~=nil and cv or "");b.TextColor3=C.ACCENT;b.TextXAlignment=Enum.TextXAlignment.Right;b.TextSize=12;b.ClearTextOnFocus=false;b.ZIndex=3;b.Parent=row;mkC(6,b);mkS(1,C.BORDER,0.2,b)
local p=Instance.new("UIPadding");p.PaddingRight=UDim.new(0,5);p.Parent=b
b.Focused:Connect(function() b.Text="" end);b.FocusLost:Connect(function() local n=tonumber(b.Text);if n~=nil then reverb[prop]=n;b.Text=tostring(n) else b.Text=tostring(reverb[prop] or "") end end)
end
mkRF("DecayTime","DecayTime",1);mkRF("Density","Density",2);mkRF("Diffusion","Diffusion",3);mkRF("DryLevel","DryLevel",4);mkRF("Priority","Priority",5);mkRF("WetLevel","WetLevel",6)
do
local function mkPF(w,h) local f=Instance.new("Frame");f.AnchorPoint=Vector2.new(0.5,0.5);f.Position=UDim2.new(0.5,0,0.5,0);f.Size=UDim2.new(0,w,0,h);f.BackgroundColor3=C.SURFACE;f.BorderSizePixel=0;f.Visible=false;f.ZIndex=150;f.Parent=UI.gui;mkC(14,f);mkS(1,C.BORDER_LIT,0.25,f);return f end
local function mkPT(p,t) local l=Instance.new("TextLabel");l.Name="Title";l.Position=UDim2.new(0,16,0,12);l.Size=UDim2.new(1,-32,0,18);l.BackgroundTransparency=1;l.Font=Enum.Font.GothamSemibold;l.Text=t;l.TextColor3=C.TEXT;l.TextXAlignment=Enum.TextXAlignment.Left;l.TextSize=14;l.ZIndex=151;l.Parent=p;return l end
local function mkPI(p,ph,yp) local b=Instance.new("TextBox");b.Position=UDim2.new(0,16,0,yp);b.Size=UDim2.new(1,-32,0,30);b.BackgroundColor3=C.ELEVATED;b.BorderSizePixel=0;b.Font=Enum.Font.Gotham;b.PlaceholderText=ph;b.Text="";b.TextColor3=C.TEXT;b.PlaceholderColor3=C.TEXT3;b.TextSize=13;b.ClearTextOnFocus=true;b.ZIndex=151;b.Parent=p;mkC(8,b);mkS(1,C.BORDER,0.2,b);return b end
local function mkPB(p,t,yp,pri,lft) local b=Instance.new("TextButton");if lft then b.Position=UDim2.new(0,16,0,yp);b.Size=UDim2.new(0.5,-20,0,30) else b.Position=UDim2.new(0.5,4,0,yp);b.Size=UDim2.new(0.5,-20,0,30) end;b.BackgroundColor3=pri and C.ACCENT or C.ELEVATED;b.BorderSizePixel=0;b.Font=pri and Enum.Font.GothamSemibold or Enum.Font.Gotham;b.Text=t;b.TextColor3=pri and AT or C.TEXT2;b.TextSize=13;b.AutoButtonColor=false;b.ZIndex=151;b.Parent=p;mkC(8,b);return b end
UI.soundIdFrame=mkPF(300,128);UI.soundIdTitle=mkPT(UI.soundIdFrame,"Enter Roblox Sound ID");UI.soundIdInput=mkPI(UI.soundIdFrame,"e.g. 1234567890",38);UI.soundIdConfirm=mkPB(UI.soundIdFrame,"Confirm",82,true,true);UI.soundIdCancel=mkPB(UI.soundIdFrame,"Cancel",82,false,false)
UI.categoryRenameFrame=mkPF(300,128);UI.categoryRenameTitle=mkPT(UI.categoryRenameFrame,"Rename Category");UI.categoryRenameInput=mkPI(UI.categoryRenameFrame,"Enter new name",38);UI.categoryRenameConfirm=mkPB(UI.categoryRenameFrame,"Confirm",82,true,true);UI.categoryRenameCancel=mkPB(UI.categoryRenameFrame,"Cancel",82,false,false)
UI.categorySelectFrame=mkPF(300,300);UI.categorySelectTitle=mkPT(UI.categorySelectFrame,"Select Category")
UI.categorySelectScroll=Instance.new("ScrollingFrame");UI.categorySelectScroll.Position=UDim2.new(0,16,0,40);UI.categorySelectScroll.Size=UDim2.new(1,-32,1,-88);UI.categorySelectScroll.BackgroundTransparency=1;UI.categorySelectScroll.BorderSizePixel=0;UI.categorySelectScroll.ScrollBarThickness=3;UI.categorySelectScroll.ScrollBarImageColor3=C.ACCENT;UI.categorySelectScroll.CanvasSize=UDim2.new(0,0,0,0);UI.categorySelectScroll.ZIndex=151;UI.categorySelectScroll.Parent=UI.categorySelectFrame
UI.categorySelectLayout=Instance.new("UIListLayout");UI.categorySelectLayout.Padding=UDim.new(0,5);UI.categorySelectLayout.SortOrder=Enum.SortOrder.LayoutOrder;UI.categorySelectLayout.Parent=UI.categorySelectScroll
UI.categorySelectLayout:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function() UI.categorySelectScroll.CanvasSize=UDim2.new(0,0,0,UI.categorySelectLayout.AbsoluteContentSize.Y+6) end)
UI.categorySelectCancel=mkPB(UI.categorySelectFrame,"Cancel",-38,false,false);UI.categorySelectCancel.AnchorPoint=Vector2.new(0,1);UI.categorySelectCancel.Position=UDim2.new(0,16,1,-10);UI.categorySelectCancel.Size=UDim2.new(1,-32,0,30)
UI.deleteConfirmFrame=mkPF(320,148);UI.deleteConfirmTitle=mkPT(UI.deleteConfirmFrame,"Delete Track?")
UI.deleteConfirmMessage=Instance.new("TextLabel");UI.deleteConfirmMessage.Position=UDim2.new(0,16,0,40);UI.deleteConfirmMessage.Size=UDim2.new(1,-32,0,52);UI.deleteConfirmMessage.BackgroundTransparency=1;UI.deleteConfirmMessage.Font=Enum.Font.Gotham;UI.deleteConfirmMessage.Text='Would you like to delete (audio name)?';UI.deleteConfirmMessage.TextColor3=C.TEXT2;UI.deleteConfirmMessage.TextXAlignment=Enum.TextXAlignment.Left;UI.deleteConfirmMessage.TextYAlignment=Enum.TextYAlignment.Top;UI.deleteConfirmMessage.TextSize=13;UI.deleteConfirmMessage.TextWrapped=true;UI.deleteConfirmMessage.ZIndex=151;UI.deleteConfirmMessage.Parent=UI.deleteConfirmFrame
UI.deleteConfirmYes=mkPB(UI.deleteConfirmFrame,"Delete",108,false,true);UI.deleteConfirmNo=mkPB(UI.deleteConfirmFrame,"Cancel",108,false,false)
UI.listTooltip=Instance.new("Frame");UI.listTooltip.AnchorPoint=Vector2.new(0,1);UI.listTooltip.Size=UDim2.new(0,0,0,22);UI.listTooltip.AutomaticSize=Enum.AutomaticSize.X;UI.listTooltip.BackgroundColor3=C.ELEVATED;UI.listTooltip.BorderSizePixel=0;UI.listTooltip.Visible=false;UI.listTooltip.ZIndex=200;UI.listTooltip.Parent=UI.gui;mkC(6,UI.listTooltip);mkS(1,C.BORDER_LIT,0.3,UI.listTooltip)
do local tp=Instance.new("UIPadding");tp.PaddingLeft=UDim.new(0,8);tp.PaddingRight=UDim.new(0,8);tp.Parent=UI.listTooltip end
UI.listTooltipText=Instance.new("TextLabel");UI.listTooltipText.Size=UDim2.new(0,0,1,0);UI.listTooltipText.AutomaticSize=Enum.AutomaticSize.X;UI.listTooltipText.BackgroundTransparency=1;UI.listTooltipText.Font=Enum.Font.Gotham;UI.listTooltipText.Text="";UI.listTooltipText.TextColor3=C.TEXT;UI.listTooltipText.TextXAlignment=Enum.TextXAlignment.Left;UI.listTooltipText.TextSize=11;UI.listTooltipText.TextTruncate=Enum.TextTruncate.None;UI.listTooltipText.ZIndex=201;UI.listTooltipText.Parent=UI.listTooltip
Svc.UIS.InputChanged:Connect(function(inp)
if inp.UserInputType==Enum.UserInputType.MouseMovement and UI.listTooltip.Visible then
local mp=Svc.UIS:GetMouseLocation()
UI.listTooltip.Position=UDim2.fromOffset(mp.X+14,mp.Y-6)
end
end)
end
local setTrack;local updateMp3List
local function updateQueueList()
for _,c in ipairs(UI.queueScroll:GetChildren()) do if c:IsA("TextButton") then c:Destroy() end end
for i,item in ipairs(Dat.queueList) do
local btn=Instance.new("TextButton");btn.Size=UDim2.new(1,0,0,30);btn.BackgroundColor3=C.SURFACE;btn.AutoButtonColor=false;btn.Active=true;btn.Font=Enum.Font.Gotham;btn.Text=shorten(item.DisplayName,28);btn.TextColor3=C.TEXT2;btn.TextXAlignment=Enum.TextXAlignment.Left;btn.TextSize=12;btn.BorderSizePixel=0;btn.ZIndex=2;btn.Parent=UI.queueScroll;mkC(7,btn);mkS(1,C.BORDER,0.3,btn)
local p=Instance.new("UIPadding");p.PaddingLeft=UDim.new(0,10);p.Parent=btn;local qi=i
btn.MouseButton1Click:Connect(function() table.remove(Dat.queueList,qi);updateQueueList() end)
btn.MouseEnter:Connect(function() btn.BackgroundColor3=Color3.fromRGB(50,20,20);btn.Text="click to remove" end)
btn.MouseLeave:Connect(function() btn.BackgroundColor3=C.SURFACE;btn.Text=shorten(item.DisplayName,28) end)
end
end
local function addToQ(idx) if idx<1 or idx>#Dat.trackList then return end;local t=Dat.trackList[idx];local s=Dat.createdSounds[idx];if t and s then table.insert(Dat.queueList,{DisplayName=t.DisplayName,FullName=t.FullName or t.DisplayName,TrackIndex=idx,Sound=s});updateQueueList() end end
local function inCat(idx)
if not Dat.trackList[idx] then return false,nil end;local tid=getTID(Dat.trackList[idx])
for ci,cat in ipairs(Dat.categories) do for _,t in ipairs(cat.TrackTIDs or {}) do if t==tid then return true,ci end end end;return false,nil
end
local function remFromCat(idx)
if not Dat.trackList[idx] then return false end;local tid=getTID(Dat.trackList[idx])
for _,cat in ipairs(Dat.categories) do for i,t in ipairs(cat.TrackTIDs or {}) do if t==tid then table.remove(cat.TrackTIDs,i);rebuildCategoryIndices();saveCategories();return true end end end;return false
end
local function getSIC() for _,cat in ipairs(Dat.categories) do if cat.CategoryID==Cfg.SOUND_ID_CATEGORY_ID then return cat end end end
local function mkSIC() local e=getSIC();if e then return e end;local c={Name=Cfg.SOUND_ID_CATEGORY_NAME,Tracks={},CategoryID=Cfg.SOUND_ID_CATEGORY_ID};table.insert(Dat.categories,c);saveCategories();return c end
local function showCatSel(ti)
for _,c in ipairs(UI.categorySelectScroll:GetChildren()) do if c:IsA("TextButton") then c:Destroy() end end
if #Dat.categories==0 then local n=Instance.new("TextLabel");n.Size=UDim2.new(1,0,0,40);n.BackgroundTransparency=1;n.Font=Enum.Font.Gotham;n.Text="No categories yet.\nCreate one first!";n.TextColor3=C.TEXT2;n.TextSize=12;n.TextYAlignment=Enum.TextYAlignment.Center;n.ZIndex=151;n.Parent=UI.categorySelectScroll;UI.categorySelectFrame.Visible=true;return end
for ci,cat in ipairs(Dat.categories) do
local btn=Instance.new("TextButton");btn.Size=UDim2.new(1,0,0,30);btn.BackgroundColor3=C.ACCENT_DIM;btn.AutoButtonColor=false;btn.Font=Enum.Font.GothamMedium;btn.Text=cat.Name;btn.TextColor3=Color3.fromRGB(255,255,255);btn.TextSize=13;btn.BorderSizePixel=0;btn.ZIndex=151;btn.Parent=UI.categorySelectScroll;mkC(7,btn)
btn.MouseButton1Click:Connect(function()
local track=Dat.trackList[ti];if not track then UI.categorySelectFrame.Visible=false;return end
local tid=getTID(track);local dup=false;for _,t in ipairs(cat.TrackTIDs or {}) do if t==tid then dup=true;break end end
if not dup then
if not cat.TrackTIDs then cat.TrackTIDs={} end;table.insert(cat.TrackTIDs,tid);rebuildCategoryIndices();saveCategories()
local tb=nil;for _,ch in ipairs(UI.listScroll:GetChildren()) do if ch.Name=="Track_"..ti and ch:IsA("TextButton") then tb=ch;break end end
if tb then tb.BackgroundColor3=C.ACCENT;tb.TextColor3=AT;Svc.TS:Create(tb,TweenInfo.new(0.12,Enum.EasingStyle.Linear),{BackgroundColor3=C.ACCENT_DIM,TextTransparency=1}):Play();Svc.TS:Create(tb,TweenInfo.new(0.18,Enum.EasingStyle.Quad,Enum.EasingDirection.In,0,false,0.12),{Size=UDim2.new(1,0,0,0)}):Play();task.delay(0.32,function() updateMp3List() end)
else updateMp3List() end
end;UI.categorySelectFrame.Visible=false;St.selectingCategoryForTrack=false;St.pendingTrackIndexForCategory=nil
end)
btn.MouseEnter:Connect(function() btn.BackgroundColor3=C.ACCENT;btn.TextColor3=AT end);btn.MouseLeave:Connect(function() btn.BackgroundColor3=C.ACCENT_DIM;btn.TextColor3=Color3.fromRGB(255,255,255) end)
end;St.selectingCategoryForTrack=true;St.pendingTrackIndexForCategory=ti;UI.categorySelectFrame.Visible=true
end
updateMp3List=function()
Dat.updateMp3List=updateMp3List
local sc=UI.listScroll.CanvasPosition;Dat.listButtonRefs={}
for _,c in ipairs(UI.listScroll:GetChildren()) do if c:IsA("Frame") or c:IsA("TextButton") or c:IsA("TextLabel") then c:Destroy() end end
local lo=1;local q=St.searchQuery or ""
if q~="" then
local function mq(dn) return dn:lower():find(q,1,true)~=nil end
local chm={};for ci,cat in ipairs(Dat.categories) do for _,ti in ipairs(cat.Tracks) do local t=Dat.trackList[ti];if t and mq(t.DisplayName) then chm[ci]=true;break end end end
for ci,cat in ipairs(Dat.categories) do
if not chm[ci] then continue end
local h=Instance.new("TextButton");h.Size=UDim2.new(1,0,0,24);h.BackgroundColor3=C.ACCENT_DIM;h.AutoButtonColor=false;h.Active=false;h.Font=Enum.Font.GothamMedium;h.Text=" "..cat.Name;h.TextColor3=Color3.fromRGB(255,255,255);h.TextXAlignment=Enum.TextXAlignment.Left;h.TextSize=11;h.BorderSizePixel=0;h.LayoutOrder=lo;h.ZIndex=2;h.Parent=UI.listScroll;lo=lo+1;mkC(7,h)
for _,ti in ipairs(cat.Tracks) do
local t=Dat.trackList[ti];if not t or not mq(t.DisplayName) then continue end
local isCurrent=ti==St.currentTrackIndex
local b=Instance.new("TextButton");b.Size=UDim2.new(1,-4,0,28);b.BackgroundColor3=isCurrent and C.ACCENT_DIM or C.SURFACE;b.AutoButtonColor=false;b.Active=true;b.Font=isCurrent and Enum.Font.GothamMedium or Enum.Font.Gotham;b.Text=shorten(t.DisplayName,28);b.TextColor3=isCurrent and C.ACCENT or C.TEXT2;b.TextXAlignment=Enum.TextXAlignment.Left;b.TextSize=11;b.BorderSizePixel=0;b.LayoutOrder=lo;b.ZIndex=2;b.Parent=UI.listScroll;lo=lo+1;mkC(6,b)
if isCurrent then local str=mkS(1,C.ACCENT,1,b);if str then Svc.TS:Create(str,TweenInfo.new(0.28,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{Transparency=0.2}):Play() end else mkS(1,C.BORDER,0.4,b) end
local p=Instance.new("UIPadding");p.PaddingLeft=UDim.new(0,20);p.Parent=b;local cti=ti
if isCurrent then b.BackgroundColor3=C.SURFACE;Svc.TS:Create(b,TweenInfo.new(0.28,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{BackgroundColor3=C.ACCENT_DIM}):Play() end
b.MouseButton1Click:Connect(function()
local ctrl=Svc.UIS:IsKeyDown(Enum.KeyCode.LeftControl) or Svc.UIS:IsKeyDown(Enum.KeyCode.RightControl)
local shift=Svc.UIS:IsKeyDown(Enum.KeyCode.LeftShift) or Svc.UIS:IsKeyDown(Enum.KeyCode.RightShift)
if shift then remFromCat(cti);updateMp3List()
elseif ctrl then addToQ(cti)
else setTrack(cti,true) end
end)
b.MouseEnter:Connect(function() if not(cti==St.currentTrackIndex) then Svc.TS:Create(b,TweenInfo.new(0.12,Enum.EasingStyle.Quad),{BackgroundColor3=C.ELEVATED}):Play() end;St.hoveredTrackIndex=cti;St.hoveredTrackInCategory=true end)
b.MouseLeave:Connect(function() Svc.TS:Create(b,TweenInfo.new(0.18,Enum.EasingStyle.Quad),{BackgroundColor3=cti==St.currentTrackIndex and C.ACCENT_DIM or C.SURFACE}):Play();St.hoveredTrackIndex=nil;St.hoveredTrackInCategory=false end)
end
end
for _,i in ipairs(getOrderedUncat()) do
local t=Dat.trackList[i];if not t or not mq(t.DisplayName) then continue end
local isCurrent=i==St.currentTrackIndex
local b=Instance.new("TextButton");b.Size=UDim2.new(1,0,0,30);b.BackgroundColor3=isCurrent and C.ACCENT_DIM or C.SURFACE;b.AutoButtonColor=false;b.Active=true;b.Font=isCurrent and Enum.Font.GothamMedium or Enum.Font.Gotham;b.Text=shorten(t.DisplayName,30);b.TextColor3=isCurrent and C.ACCENT or C.TEXT2;b.TextXAlignment=Enum.TextXAlignment.Left;b.TextSize=12;b.BorderSizePixel=0;b.LayoutOrder=lo;b.ZIndex=2;b.Parent=UI.listScroll;lo=lo+1;mkC(8,b)
if isCurrent then local str=mkS(1,C.ACCENT,1,b);if str then Svc.TS:Create(str,TweenInfo.new(0.28,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{Transparency=0.2}):Play() end else mkS(1,C.BORDER,0.3,b) end
local p=Instance.new("UIPadding");p.PaddingLeft=UDim.new(0,10);p.Parent=b;local ci=i
if isCurrent then b.BackgroundColor3=C.SURFACE;Svc.TS:Create(b,TweenInfo.new(0.28,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{BackgroundColor3=C.ACCENT_DIM}):Play() end
b.MouseButton1Click:Connect(function()
local ctrl=Svc.UIS:IsKeyDown(Enum.KeyCode.LeftControl) or Svc.UIS:IsKeyDown(Enum.KeyCode.RightControl)
local shift=Svc.UIS:IsKeyDown(Enum.KeyCode.LeftShift) or Svc.UIS:IsKeyDown(Enum.KeyCode.RightShift)
if shift then showCatSel(ci) elseif ctrl then addToQ(ci)
else setTrack(ci,true) end
end)
b.MouseEnter:Connect(function() if not(ci==St.currentTrackIndex) then Svc.TS:Create(b,TweenInfo.new(0.12,Enum.EasingStyle.Quad),{BackgroundColor3=C.ELEVATED}):Play() end;St.hoveredTrackIndex=ci;St.hoveredTrackInCategory=false end)
b.MouseLeave:Connect(function() Svc.TS:Create(b,TweenInfo.new(0.18,Enum.EasingStyle.Quad),{BackgroundColor3=ci==St.currentTrackIndex and C.ACCENT_DIM or C.SURFACE}):Play();St.hoveredTrackIndex=nil;St.hoveredTrackInCategory=false end)
end
local any=false;for _,c in ipairs(UI.listScroll:GetChildren()) do if c:IsA("TextButton") or c:IsA("Frame") then any=true;break end end
if not any then local n=Instance.new("TextLabel");n.Size=UDim2.new(1,0,0,40);n.BackgroundTransparency=1;n.Font=Enum.Font.GothamMedium;n.Text='No results for "'..q..'"';n.TextColor3=C.TEXT3;n.TextSize=12;n.ZIndex=2;n.Parent=UI.listScroll end
local _c;_c=Svc.RS.Heartbeat:Connect(function() _c:Disconnect();UI.listScroll.CanvasPosition=sc end);return
end
for ci,cat in ipairs(Dat.categories) do
local TH,TG,HH,IP=28,4,30,4;local nt=#cat.Tracks;local exp=St.expandedCategories[ci];local exH=HH+IP+nt*(TH+TG)+IP;local coH=HH
local cf=Instance.new("Frame");cf.Name="Category_"..ci;cf.Size=UDim2.new(1,0,0,exp and exH or coH);cf.BackgroundTransparency=1;cf.ClipsDescendants=true;cf.LayoutOrder=lo;cf.ZIndex=2;cf.Parent=UI.listScroll;lo=lo+1
local cb2=Instance.new("TextButton");cb2.Name="CategoryButton";cb2.Position=UDim2.new(0,0,0,0);cb2.Size=UDim2.new(1,0,0,HH);cb2.BackgroundColor3=C.ACCENT_DIM;cb2.AutoButtonColor=false;cb2.Active=true;cb2.Font=Enum.Font.GothamMedium;cb2.Text=(exp and "v " or "> ")..cat.Name;cb2.TextColor3=Color3.fromRGB(255,255,255);cb2.TextXAlignment=Enum.TextXAlignment.Left;cb2.TextSize=12;cb2.BorderSizePixel=0;cb2.ZIndex=2;cb2.Parent=cf;mkC(8,cb2);mkS(1,C.BORDER_LIT,0.3,cb2)
local hp=Instance.new("UIPadding");hp.PaddingLeft=UDim.new(0,10);hp.Parent=cb2
local ic=Instance.new("Frame");ic.Name="InnerContainer";ic.Position=UDim2.new(0,0,0,HH);ic.Size=UDim2.new(1,0,0,exH-HH);ic.BackgroundTransparency=1;ic.ZIndex=2;ic.Parent=cf
local il=Instance.new("UIListLayout");il.Padding=UDim.new(0,TG);il.SortOrder=Enum.SortOrder.LayoutOrder;il.Parent=ic
local ipd=Instance.new("UIPadding");ipd.PaddingTop=UDim.new(0,IP);ipd.PaddingBottom=UDim.new(0,IP);ipd.PaddingLeft=UDim.new(0,16);ipd.Parent=ic
il:GetPropertyChangedSignal("AbsoluteContentSize"):Connect(function() if not exp then return end;cf.Size=UDim2.new(1,0,0,HH+il.AbsoluteContentSize.Y+IP*2) end)
local function updCB() cb2.Text=(St.expandedCategories[ci] and "v " or "> ")..cat.Name end
local function setExp(nexp,anim) St.expandedCategories[ci]=nexp;updCB();local th=nexp and exH or coH;if anim then Svc.TS:Create(cf,nexp and TweenInfo.new(0.22,Enum.EasingStyle.Quad,Enum.EasingDirection.Out) or TweenInfo.new(0.18,Enum.EasingStyle.Quad,Enum.EasingDirection.In),{Size=UDim2.new(1,0,0,th)}):Play() else cf.Size=UDim2.new(1,0,0,th) end end
cb2.MouseButton1Click:Connect(function() local ctrl=Svc.UIS:IsKeyDown(Enum.KeyCode.LeftControl) or Svc.UIS:IsKeyDown(Enum.KeyCode.RightControl);if ctrl then for _,ti in ipairs(cat.Tracks) do addToQ(ti) end else setExp(not St.expandedCategories[ci],true) end end)
cb2.MouseButton2Click:Connect(function() St.categoryBeingRenamed=ci;UI.categoryRenameInput.Text=cat.Name;UI.categoryRenameFrame.Visible=true;UI.categoryRenameInput:CaptureFocus() end)
cb2.MouseEnter:Connect(function() cb2.BackgroundColor3=C.ACCENT;cb2.TextColor3=AT;St.hoveredCategoryIndex=ci end)
cb2.MouseLeave:Connect(function() cb2.BackgroundColor3=C.ACCENT_DIM;cb2.TextColor3=Color3.fromRGB(255,255,255);St.hoveredCategoryIndex=nil end)
for pi,ti in ipairs(cat.Tracks) do
if ti<=#Dat.trackList then
local t=Dat.trackList[ti];local tb=Instance.new("TextButton");tb.Name="CT_"..pi;tb.Size=UDim2.new(1,-4,0,TH);tb.BackgroundColor3=C.SURFACE;tb.AutoButtonColor=false;tb.Active=true;tb.Font=Enum.Font.Gotham;tb.Text=shorten(t.DisplayName,26);tb.TextColor3=C.TEXT2;tb.TextXAlignment=Enum.TextXAlignment.Left;tb.TextSize=11;tb.BorderSizePixel=0;tb.LayoutOrder=pi;tb.ZIndex=2;tb.Parent=ic;mkC(6,tb);mkS(1,C.BORDER,0.4,tb)
local tp=Instance.new("UIPadding");tp.PaddingLeft=UDim.new(0,8);tp.Parent=tb
local ac2=Instance.new("Frame");ac2.AnchorPoint=Vector2.new(1,0.5);ac2.Position=UDim2.new(1,-4,0.5,0);ac2.Size=UDim2.new(0,38,0,20);ac2.BackgroundTransparency=1;ac2.Visible=false;ac2.ZIndex=2;ac2.Parent=tb
local catI,posI=ci,pi
local function mkCA(lbl,xp,md)
local a=Instance.new("TextButton");a.AnchorPoint=Vector2.new(0,0.5);a.Position=UDim2.new(0,xp,0.5,0);a.Size=UDim2.new(0,17,0,18);a.BackgroundColor3=C.ELEVATED;a.AutoButtonColor=false;a.Font=Enum.Font.GothamBold;a.Text=lbl;a.TextSize=9;a.TextColor3=C.ACCENT;a.BorderSizePixel=0;a.ZIndex=2;a.Parent=ac2;mkC(5,a);mkS(1,C.BORDER_LIT,0.4,a)
a.MouseEnter:Connect(function() a.BackgroundColor3=C.ACCENT;a.TextColor3=AT end);a.MouseLeave:Connect(function() a.BackgroundColor3=C.ELEVATED;a.TextColor3=C.ACCENT end)
a.MouseButton1Click:Connect(function() local thc=Dat.categories[catI];if not thc then return end;local sp=posI+md;if sp<1 or sp>#thc.Tracks then return end;thc.Tracks[posI],thc.Tracks[sp]=thc.Tracks[sp],thc.Tracks[posI];saveCategories();updateMp3List() end)
end
mkCA("↑",0,-1);mkCA("↓",20,1)
local cti=ti;local isCurrent=cti==St.currentTrackIndex
if isCurrent then tb.BackgroundColor3=C.SURFACE;Svc.TS:Create(tb,TweenInfo.new(0.28,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{BackgroundColor3=C.ACCENT_DIM}):Play();local str=mkS(1,C.ACCENT,1,tb);if str then Svc.TS:Create(str,TweenInfo.new(0.28,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{Transparency=0.2}):Play() end end
tb.MouseButton1Click:Connect(function()
local ctrl=Svc.UIS:IsKeyDown(Enum.KeyCode.LeftControl) or Svc.UIS:IsKeyDown(Enum.KeyCode.RightControl)
local shift=Svc.UIS:IsKeyDown(Enum.KeyCode.LeftShift) or Svc.UIS:IsKeyDown(Enum.KeyCode.RightShift)
if shift then remFromCat(cti);updateMp3List()
elseif ctrl then addToQ(cti)
else setTrack(cti,true) end
end)
tb.MouseEnter:Connect(function()
if not(cti==St.currentTrackIndex) then Svc.TS:Create(tb,TweenInfo.new(0.12,Enum.EasingStyle.Quad),{BackgroundColor3=C.ELEVATED}):Play() end
ac2.Visible=true;St.hoveredTrackIndex=cti;St.hoveredTrackInCategory=true
if #t.DisplayName>26 then UI.listTooltipText.Text=t.DisplayName;local mp=Svc.UIS:GetMouseLocation();UI.listTooltip.Position=UDim2.fromOffset(mp.X+14,mp.Y-6);UI.listTooltip.Visible=true end
end)
tb.MouseLeave:Connect(function() Svc.TS:Create(tb,TweenInfo.new(0.18,Enum.EasingStyle.Quad),{BackgroundColor3=cti==St.currentTrackIndex and C.ACCENT_DIM or C.SURFACE}):Play();ac2.Visible=false;St.hoveredTrackIndex=nil;St.hoveredTrackInCategory=false;UI.listTooltip.Visible=false end)
end
end
end
for _,i in ipairs(getOrderedUncat()) do
local t=Dat.trackList[i];if not t then continue end;local ref={idx=i};local isCurrent=i==St.currentTrackIndex
local btn=Instance.new("TextButton");btn.Name="Track_"..i;btn.Size=UDim2.new(1,0,0,30);btn.LayoutOrder=lo;btn.BackgroundColor3=isCurrent and C.ACCENT_DIM or C.SURFACE;btn.AutoButtonColor=false;btn.Active=true;btn.Font=isCurrent and Enum.Font.GothamMedium or Enum.Font.Gotham;btn.Text=shorten(t.DisplayName,30);btn.TextColor3=isCurrent and C.ACCENT or C.TEXT2;btn.TextXAlignment=Enum.TextXAlignment.Left;btn.TextSize=12;btn.BorderSizePixel=0;btn.ZIndex=2;btn.Parent=UI.listScroll;lo=lo+1;mkC(8,btn)
if isCurrent then local str=mkS(1,C.ACCENT,1,btn);if str then Svc.TS:Create(str,TweenInfo.new(0.28,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{Transparency=0.2}):Play() end else mkS(1,C.BORDER,0.3,btn) end
local bp2=Instance.new("UIPadding");bp2.PaddingLeft=UDim.new(0,10);bp2.Parent=btn
if t.Type=="mp3" and t.FileName then Dat.listButtonRefs[t.FileName]={btn=btn,ref=ref} end
if isCurrent then btn.BackgroundColor3=C.SURFACE;Svc.TS:Create(btn,TweenInfo.new(0.28,Enum.EasingStyle.Quad,Enum.EasingDirection.Out),{BackgroundColor3=C.ACCENT_DIM}):Play() end
local ac3=Instance.new("Frame");ac3.AnchorPoint=Vector2.new(1,0.5);ac3.Position=UDim2.new(1,-4,0.5,0);ac3.Size=UDim2.new(0,38,0,22);ac3.BackgroundTransparency=1;ac3.Visible=false;ac3.ZIndex=2;ac3.Parent=btn
local function mkArr(lbl,xp,md)
local a=Instance.new("TextButton");a.Name=lbl;a.AnchorPoint=Vector2.new(0,0.5);a.Position=UDim2.new(0,xp,0.5,0);a.Size=UDim2.new(0,17,0,20);a.BackgroundColor3=C.ELEVATED;a.AutoButtonColor=false;a.Font=Enum.Font.GothamBold;a.Text=lbl;a.TextSize=9;a.TextColor3=C.ACCENT;a.BorderSizePixel=0;a.ZIndex=2;a.Parent=ac3;mkC(5,a);mkS(1,C.BORDER_LIT,0.4,a)
a.MouseEnter:Connect(function() a.BackgroundColor3=C.ACCENT;a.TextColor3=AT end);a.MouseLeave:Connect(function() a.BackgroundColor3=C.ELEVATED;a.TextColor3=C.ACCENT end)
a.MouseButton1Click:Connect(function() local tid=getTID(t);for p,id in ipairs(Dat.trackOrderList) do if id==tid then local sp=p+md;if sp>=1 and sp<=#Dat.trackOrderList then Dat.trackOrderList[p],Dat.trackOrderList[sp]=Dat.trackOrderList[sp],Dat.trackOrderList[p];saveOrder();updateMp3List() end;return end end end)
end
mkArr("↑",0,-1);mkArr("↓",20,1)
btn.MouseButton1Down:Connect(function() local ctrl=Svc.UIS:IsKeyDown(Enum.KeyCode.LeftControl) or Svc.UIS:IsKeyDown(Enum.KeyCode.RightControl);if ctrl then St.draggedButton=btn;St.isDraggingToQueue=true;St.draggedTrackIndex=ref.idx;St.isDraggingToCategory=true end end)
btn.MouseButton1Click:Connect(function()
local ctrl=Svc.UIS:IsKeyDown(Enum.KeyCode.LeftControl) or Svc.UIS:IsKeyDown(Enum.KeyCode.RightControl)
local shift=Svc.UIS:IsKeyDown(Enum.KeyCode.LeftShift) or Svc.UIS:IsKeyDown(Enum.KeyCode.RightShift)
if shift then showCatSel(ref.idx)
elseif ctrl then addToQ(ref.idx)
else setTrack(ref.idx,true) end
end)
btn.MouseEnter:Connect(function()
if not(ref.idx==St.currentTrackIndex) then Svc.TS:Create(btn,TweenInfo.new(0.12,Enum.EasingStyle.Quad),{BackgroundColor3=C.ELEVATED}):Play() end
ac3.Visible=true;St.hoveredTrackIndex=ref.idx;St.hoveredTrackInCategory=false
if #t.DisplayName>30 then UI.listTooltipText.Text=t.DisplayName;local mp=Svc.UIS:GetMouseLocation();UI.listTooltip.Position=UDim2.fromOffset(mp.X+14,mp.Y-6);UI.listTooltip.Visible=true end
end)
btn.MouseLeave:Connect(function() Svc.TS:Create(btn,TweenInfo.new(0.18,Enum.EasingStyle.Quad),{BackgroundColor3=ref.idx==St.currentTrackIndex and C.ACCENT_DIM or C.SURFACE}):Play();ac3.Visible=false;St.hoveredTrackIndex=nil;St.hoveredTrackInCategory=false;UI.listTooltip.Visible=false end)
end
local _c;_c=Svc.RS.Heartbeat:Connect(function() _c:Disconnect();UI.listScroll.CanvasPosition=sc end)
end
Svc.UIS.InputBegan:Connect(function(inp)
if inp.KeyCode==Enum.KeyCode.Delete then
if St.hoveredCategoryIndex then table.remove(Dat.categories,St.hoveredCategoryIndex);saveCategories();updateMp3List();St.hoveredCategoryIndex=nil
elseif St.hoveredTrackIndex then local t=Dat.trackList[St.hoveredTrackIndex];if t then St.pendingDeleteTrackIndex=St.hoveredTrackIndex;UI.deleteConfirmMessage.Text='Would you like to delete "'..t.DisplayName..'"?';UI.deleteConfirmFrame.Visible=true end end
end
end)
UI.deleteConfirmNo.MouseButton1Click:Connect(function() UI.deleteConfirmFrame.Visible=false;St.pendingDeleteTrackIndex=nil end)
UI.deleteConfirmYes.MouseButton1Click:Connect(function()
if not St.pendingDeleteTrackIndex then return end;local ti=St.pendingDeleteTrackIndex;local t=Dat.trackList[ti];UI.deleteConfirmFrame.Visible=false;St.pendingDeleteTrackIndex=nil;if not t then return end
local tb=nil;for _,c in ipairs(UI.listScroll:GetChildren()) do if c.Name=="Track_"..ti and c:IsA("TextButton") then tb=c;break end end
local function doDel()
if t.Type=="soundid" then
remFromCat(ti);local s=Dat.createdSounds[ti];if s then s:Destroy() end;table.remove(Dat.trackList,ti);table.remove(Dat.createdSounds,ti);rebuildCategoryIndices();saveCategories();saveSoundIds()
elseif t.Type=="mp3" and t.Path then
Dat.permanentlyDeleted[t.Path]=true;if isfile(t.Path) then delfile(t.Path) end
for i=#Dat.lastMp3Files,1,-1 do if Dat.lastMp3Files[i].Path==t.Path then table.remove(Dat.lastMp3Files,i);break end end
local tid=getTID(t);for _,cat in ipairs(Dat.categories) do for i,ct in ipairs(cat.TrackTIDs or {}) do if ct==tid then table.remove(cat.TrackTIDs,i);break end end end
Dat.suppressAutoNotify[t.FileName or ""]=true;local s=Dat.createdSounds[ti];if s then s:Destroy() end;table.remove(Dat.trackList,ti);table.remove(Dat.createdSounds,ti);rebuildCategoryIndices();saveCategories()
end
if St.currentTrackIndex==ti then if #Dat.createdSounds>0 then St.currentTrackIndex=math.min(St.currentTrackIndex,#Dat.createdSounds);setTrack(St.currentTrackIndex,false) else St.currentTrackIndex=1;sound=nil;updTrack("no tracks loaded","no tracks loaded") end
elseif St.currentTrackIndex>ti then St.currentTrackIndex=St.currentTrackIndex-1 end
updateMp3List();showNotification(t.DisplayName,true)
end
if tb then Svc.TS:Create(tb,TweenInfo.new(0.06,Enum.EasingStyle.Linear),{BackgroundColor3=C.DANGER,TextTransparency=0.4}):Play();task.delay(0.06,doDel) else doDel() end
end)
Svc.UIS.InputEnded:Connect(function(inp)
if inp.UserInputType~=Enum.UserInputType.MouseButton1 then return end
if St.isDraggingToQueue and St.draggedButton then
local mp=Svc.UIS:GetMouseLocation();local qp=UI.queuePanel.AbsolutePosition;local qs=UI.queuePanel.AbsoluteSize
if UI.queuePanel.Visible and mp.X>=qp.X and mp.X<=qp.X+qs.X and mp.Y>=qp.Y and mp.Y<=qp.Y+qs.Y then local is=St.draggedButton.Name:match("Track_(%d+)");if is then addToQ(tonumber(is)) end end
end
if St.isDraggingToCategory and St.draggedTrackIndex then
local mp=Svc.UIS:GetMouseLocation();local dragTrack=Dat.trackList[St.draggedTrackIndex]
if dragTrack then
local dragTID=getTID(dragTrack)
for ci,cat in ipairs(Dat.categories) do for _,ch in ipairs(UI.listScroll:GetChildren()) do if ch.Name=="Category_"..ci then local cb3=ch:FindFirstChild("CategoryButton");if cb3 then local bp=cb3.AbsolutePosition;local bs=cb3.AbsoluteSize;if mp.X>=bp.X and mp.X<=bp.X+bs.X and mp.Y>=bp.Y and mp.Y<=bp.Y+bs.Y then
local dup=false;for _,t in ipairs(cat.TrackTIDs or {}) do if t==dragTID then dup=true;break end end
if not dup then if not cat.TrackTIDs then cat.TrackTIDs={} end;table.insert(cat.TrackTIDs,dragTID);rebuildCategoryIndices();saveCategories();updateMp3List() end;break end end end end end
end
end;St.draggedButton=nil;St.isDraggingToQueue=false;St.draggedTrackIndex=nil;St.isDraggingToCategory=false
end)
UI.addCategoryBtn.MouseButton1Click:Connect(function() table.insert(Dat.categories,{Name="New Category",Tracks={}});saveCategories();updateMp3List() end)
UI.categoryRenameCancel.MouseButton1Click:Connect(function() UI.categoryRenameFrame.Visible=false;St.categoryBeingRenamed=nil;St.pendingRenameSoundIdIndex=nil;UI.categoryRenameTitle.Text="Rename Category" end)
UI.categoryRenameConfirm.MouseButton1Click:Connect(function()
local newName=UI.categoryRenameInput.Text;if newName=="" then return end
if St.pendingRenameSoundIdIndex then
local idx=St.pendingRenameSoundIdIndex;local tr=Dat.trackList[idx]
if tr and tr.Type=="soundid" then tr.DisplayName=newName;tr.FullName=newName;local s=Dat.createdSounds[idx];if s then s.Name=newName end;if idx==St.currentTrackIndex then updTrack(newName,newName) end;saveSoundIds();updateMp3List() end
UI.categoryRenameFrame.Visible=false;St.pendingRenameSoundIdIndex=nil;UI.categoryRenameTitle.Text="Rename Category"
elseif St.categoryBeingRenamed then
Dat.categories[St.categoryBeingRenamed].Name=newName;saveCategories();updateMp3List();UI.categoryRenameLoads code from the internet. It downloads more code when it runs (loadstring + HttpGet), which can change after it was posted. From: soundcloud.com, api-v2.soundcloud.com, translate.googleapis.com, lrclib.net, api.audd.io.
**Features** Play, pause, skip, and go back between tracks. Adjust volume and playback speed with sliders. Enable repeat to loop a track or shuffle to randomize playback order. Tracks automatically crossfade into each other when one is ending. You can build a manual queue that plays before returning to the main list. Tracks are organized into categories you can create, rename, delete, and reorder. You can drag tracks into categories from the list panel. The script auto-scans a local folder for MP3 files and loads them. You can also add tracks using Roblox Sound IDs. Tracks can be renamed, reordered, or permanently deleted. Synced lyrics are fetched automatically from lrclib.net based on the track name, with a fallback to audio fingerprinting via audd.io. Instrumental tracks show a placeholder instead of lyrics. Lyrics can be auto-translated to English line by line. Cinematic mode adds black bars and displays lyrics in a movie-style overlay. A screen shake and FOV pulse effect reacts to the music's loudness, with adjustable intensity. You can search SoundCloud and add tracks directly from results. There is a built-in MP3 downloader tab. All other in-game sounds can be muted while m