@rel-packages/osu-beatmap-preview 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/index.js +4 -4
  2. package/dist/index.js.map +16 -11
  3. package/dist/math/difficulty.d.ts.map +1 -1
  4. package/dist/parser/async_parser.d.ts +15 -0
  5. package/dist/parser/async_parser.d.ts.map +1 -0
  6. package/dist/parser/osz_loader.d.ts +1 -0
  7. package/dist/parser/osz_loader.d.ts.map +1 -1
  8. package/dist/parser/parser.worker.d.ts +49 -0
  9. package/dist/parser/parser.worker.d.ts.map +1 -0
  10. package/dist/player/audio_controller.d.ts +1 -0
  11. package/dist/player/audio_controller.d.ts.map +1 -1
  12. package/dist/player/player.d.ts +8 -8
  13. package/dist/player/player.d.ts.map +1 -1
  14. package/dist/renderer/backend/canvas_backend.d.ts +2 -0
  15. package/dist/renderer/backend/canvas_backend.d.ts.map +1 -1
  16. package/dist/renderer/backend/render_backend.d.ts +2 -0
  17. package/dist/renderer/backend/render_backend.d.ts.map +1 -1
  18. package/dist/renderer/drawable/drawable.d.ts +48 -0
  19. package/dist/renderer/drawable/drawable.d.ts.map +1 -0
  20. package/dist/renderer/drawable/drawable_hit_circle.d.ts +15 -0
  21. package/dist/renderer/drawable/drawable_hit_circle.d.ts.map +1 -0
  22. package/dist/renderer/drawable/drawable_slider.d.ts +38 -0
  23. package/dist/renderer/drawable/drawable_slider.d.ts.map +1 -0
  24. package/dist/renderer/drawable/index.d.ts +5 -0
  25. package/dist/renderer/drawable/index.d.ts.map +1 -0
  26. package/dist/renderer/drawable/transforms.d.ts +32 -0
  27. package/dist/renderer/drawable/transforms.d.ts.map +1 -0
  28. package/dist/renderer/mania/mania_renderer.d.ts.map +1 -1
  29. package/dist/renderer/standard/standard_renderer.d.ts +11 -16
  30. package/dist/renderer/standard/standard_renderer.d.ts.map +1 -1
  31. package/dist/skin/skin_config.d.ts +11 -1
  32. package/dist/skin/skin_config.d.ts.map +1 -1
  33. package/dist/skin/skin_ini_parser.d.ts +21 -0
  34. package/dist/skin/skin_ini_parser.d.ts.map +1 -0
  35. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- var _;((V)=>{V[V.Standard=0]="Standard";V[V.Taiko=1]="Taiko";V[V.Catch=2]="Catch";V[V.Mania=3]="Mania"})(_||={});var ST;((V)=>{V[V.Auto=0]="Auto";V[V.Normal=1]="Normal";V[V.Soft=2]="Soft";V[V.Drum=3]="Drum"})(ST||={});var w={Circle:1,Slider:2,NewCombo:4,Spinner:8,ComboSkip:112,Hold:128},o={Normal:1,Whistle:2,Finish:4,Clap:8},UT=(T)=>(T.type&w.Circle)!==0,c=(T)=>(T.type&w.Slider)!==0,p=(T)=>(T.type&w.Spinner)!==0,RT=(T)=>(T.type&w.Hold)!==0,wT=(T)=>(T.type&w.NewCombo)!==0;var vT;((R)=>{R.NoOsuFiles="NO_OSU_FILES";R.DifficultyNotFound="DIFFICULTY_NOT_FOUND";R.InvalidBeatmap="INVALID_BEATMAP";R.UnsupportedMode="UNSUPPORTED_MODE";R.AudioNotLoaded="AUDIO_NOT_LOADED";R.AudioDecodeError="AUDIO_DECODE_ERROR";R.NotLoaded="NOT_LOADED";R.Unknown="UNKNOWN"})(vT||={});var uT=(T)=>({success:!0,data:T}),v=(T,I)=>({success:!1,code:T,reason:I}),SI=(T)=>{if(T.success)return T.data;throw Error(`[${T.code}] ${T.reason}`)},UI=(T)=>{return T.success},RI=(T)=>{return!T.success};var P={None:0,NoFail:1,Easy:2,TouchDevice:4,Hidden:8,HardRock:16,SuddenDeath:32,DoubleTime:64,Relax:128,HalfTime:256,Nightcore:512,Flashlight:1024,Autoplay:2048,SpunOut:4096,Autopilot:8192,Perfect:16384,FadeIn:8388608,Mirror:1073741824},mT=P.DoubleTime|P.HalfTime|P.Nightcore,AI=P.HardRock|P.Easy|mT,PI=(T)=>{let I=0,D=T.toLowerCase(),H={nf:P.NoFail,ez:P.Easy,td:P.TouchDevice,hd:P.Hidden,hr:P.HardRock,sd:P.SuddenDeath,dt:P.DoubleTime,rx:P.Relax,ht:P.HalfTime,nc:P.Nightcore,fl:P.Flashlight,at:P.Autoplay,so:P.SpunOut,ap:P.Autopilot,pf:P.Perfect,fi:P.FadeIn,mr:P.Mirror};for(let V=0;V<D.length-1;V+=2){let F=D.slice(V,V+2);if(H[F])I|=H[F]}return I},OI=(T)=>{let I=[];if(T&P.NoFail)I.push("NF");if(T&P.Easy)I.push("EZ");if(T&P.Hidden)I.push("HD");if(T&P.HardRock)I.push("HR");if(T&P.SuddenDeath)I.push("SD");if(T&P.DoubleTime)I.push("DT");if(T&P.HalfTime)I.push("HT");if(T&P.Nightcore)I.push("NC");if(T&P.Flashlight)I.push("FL");if(T&P.SpunOut)I.push("SO");if(T&P.FadeIn)I.push("FI");if(T&P.Mirror)I.push("MR");let D=I.indexOf("DT"),H=I.indexOf("NC");if(D>=0&&H>=0)I.splice(D,1);return I.join("")},n=(T)=>{if(T&(P.DoubleTime|P.Nightcore))return 1.5;if(T&P.HalfTime)return 0.75;return 1},lT=[P.HardRock|P.Easy,P.DoubleTime|P.HalfTime|P.Nightcore,P.Hidden|P.FadeIn],$I=(T,I)=>{if(T&I)return T&~I;let D=T;for(let H of lT)if(I&H)D&=~H;return D|I},K=(T,I)=>(T&I)!==0,NI=(T)=>{let I=[{name:"No Fail",acronym:"NF",value:P.NoFail},{name:"Easy",acronym:"EZ",value:P.Easy},{name:"Hidden",acronym:"HD",value:P.Hidden},{name:"Double Time",acronym:"DT",value:P.DoubleTime},{name:"Half Time",acronym:"HT",value:P.HalfTime},{name:"Nightcore",acronym:"NC",value:P.Nightcore}];switch(T){case"standard":return[...I,{name:"Hard Rock",acronym:"HR",value:P.HardRock},{name:"Flashlight",acronym:"FL",value:P.Flashlight}];case"mania":return[...I,{name:"Fade In",acronym:"FI",value:P.FadeIn},{name:"Mirror",acronym:"MR",value:P.Mirror}];case"taiko":case"catch":return[...I,{name:"Hard Rock",acronym:"HR",value:P.HardRock}];default:return I}};import xT from"jszip";class f{beatmap;section="";parse(T){this.beatmap=this.create_empty_beatmap(),this.section="";let I=T.split(`
2
- `);for(let D of I)this.parse_line(D);if(this.beatmap.ar===-1)this.beatmap.ar=this.beatmap.od;return this.beatmap}parse_info(T,I){this.beatmap=this.create_empty_beatmap(),this.section="";let D=T.split(`
3
- `);for(let H of D)if(this.parse_line(H),this.section==="Events"||this.section==="TimingPoints"||this.section==="Colours"||this.section==="HitObjects")break;if(this.beatmap.ar===-1)this.beatmap.ar=this.beatmap.od;return{filename:I,title:this.beatmap.title,artist:this.beatmap.artist,version:this.beatmap.version,mode:this.beatmap.mode,ar:this.beatmap.ar,cs:this.beatmap.cs,od:this.beatmap.od,hp:this.beatmap.hp}}create_empty_beatmap(){return{format_version:1,mode:0,title:"",title_unicode:"",artist:"",artist_unicode:"",creator:"",version:"",ar:-1,cs:5,od:5,hp:5,sv:1,tick_rate:1,timing_points:[],objects:[],circle_count:0,slider_count:0,spinner_count:0,hold_count:0}}parse_line(T){if(T.startsWith(" ")||T.startsWith("_"))return;let I=T.trim();if(I.length===0||I.startsWith("//"))return;if(I.startsWith("[")&&I.endsWith("]")){this.section=I.slice(1,-1);return}let D=I.match(/osu file format v(\d+)/);if(D){this.beatmap.format_version=parseInt(D[1]);return}switch(this.section){case"General":this.parse_general(I);break;case"Metadata":this.parse_metadata(I);break;case"Difficulty":this.parse_difficulty(I);break;case"TimingPoints":this.parse_timing_point(I);break;case"HitObjects":this.parse_hit_object(I);break}}parse_general(T){let[I,D]=this.split_property(T);if(I==="Mode")this.beatmap.mode=parseInt(D)}parse_metadata(T){let[I,D]=this.split_property(T);switch(I){case"Title":this.beatmap.title=D;break;case"TitleUnicode":this.beatmap.title_unicode=D;break;case"Artist":this.beatmap.artist=D;break;case"ArtistUnicode":this.beatmap.artist_unicode=D;break;case"Creator":this.beatmap.creator=D;break;case"Version":this.beatmap.version=D;break}}parse_difficulty(T){let[I,D]=this.split_property(T),H=parseFloat(D);switch(I){case"CircleSize":this.beatmap.cs=H;break;case"OverallDifficulty":this.beatmap.od=H;break;case"ApproachRate":this.beatmap.ar=H;break;case"HPDrainRate":this.beatmap.hp=H;break;case"SliderMultiplier":this.beatmap.sv=H;break;case"SliderTickRate":this.beatmap.tick_rate=H;break}}current_beat_length=500;parse_timing_point(T){let I=T.split(",");if(I.length<2)return;let D=parseFloat(I[0]),H=parseFloat(I[1]),V=parseInt(I[3]??"0"),F=parseInt(I[4]??"0"),S=parseInt(I[5]??"100"),U=I.length>=7?I[6].trim()!=="0":!0,R=I.length>=8?(parseInt(I[7])&1)!==0:!1,B=H<0,$=B?-100/H:1;if(!B&&H>0)this.current_beat_length=H;this.beatmap.timing_points.push({time:D,ms_per_beat:H,change:U,sample_set:V,sample_index:F,volume:S,kiai:R,velocity:$,beat_length:this.current_beat_length})}parse_hit_object(T){let I=T.split(",");if(I.length<4)return;let D=parseFloat(I[0]),H=parseFloat(I[1]),V=parseFloat(I[2]),F=parseInt(I[3]),S=parseInt(I[4]??"0"),U={time:V,type:F,hit_sound:S,end_time:V,end_pos:[D,H],combo_number:0,combo_count:0,data:{pos:[D,H]}};if(F&w.Circle)this.beatmap.circle_count++,U.data={pos:[D,H]},this.parse_extras(I,5,U);else if(F&w.Slider){if(I.length<8)return;this.beatmap.slider_count++;let R=this.parse_slider_data(I,D,H);if(U.data=R,I.length>8)U.edge_sounds=I[8].split("|").map((B)=>parseInt(B));if(I.length>9)U.edge_sets=I[9].split("|").map((B)=>{let $=B.split(":");return[parseInt($[0]),parseInt($[1])]});this.parse_extras(I,10,U)}else if(F&w.Spinner){this.beatmap.spinner_count++;let R=parseInt(I[5]);U.data={end_time:R},U.end_time=R,U.end_pos=[256,192],this.parse_extras(I,6,U)}else if(F&w.Hold){this.beatmap.hold_count++;let R=parseInt(I[5].split(":")[0]);U.data={pos:[D,H],end_time:R},U.end_time=R,this.parse_extras(I,6,U)}this.beatmap.objects.push(U)}parse_extras(T,I,D){if(I<T.length){let H=T[I];if(H&&H.includes(":")){let V=H.split(":");D.hit_sample={normal_set:parseInt(V[0]),addition_set:parseInt(V[1]),index:parseInt(V[2]),volume:parseInt(V[3]),filename:V[4]||void 0}}}}parse_slider_data(T,I,D){let H=T[5].split("|"),V=H[0],F=[];for(let R=1;R<H.length;R++){let B=H[R].split(":");F.push([parseInt(B[0]),parseInt(B[1])])}let S=parseInt(T[6]),U=parseFloat(T[7]);return{pos:[I,D],path_type:V,control_points:F,repetitions:S,distance:U}}split_property(T){let I=T.indexOf(":");if(I===-1)return[T,""];return[T.slice(0,I).trim(),T.slice(I+1).trim()]}}var i=4096,BT=(T)=>{let I=T.slice(0,i).match(/PreviewTime:\s*([+-]?\d+)/);return I?parseInt(I[1]):-1},AT=(T)=>{let I=T.slice(0,i).match(/AudioFilename:\s*(.+)/);return I?I[1].trim():null},PT=(T)=>{let I=T.slice(0,i).match(/0,0,"([^"]+)"/);return I?I[1]:null},OT=(T)=>{let I=T.slice(0,i).match(/(?:Video|1),(-?\d+),"([^"]+)"/);if(!I)return null;return{offset:parseInt(I[1]),filename:I[2]}};class h{async load_osz(T,I){let D=await xT.loadAsync(T),H=new Map;for(let[V,F]of Object.entries(D.files))if(!F.dir)H.set(V,await F.async("arraybuffer"));return this.load_from_files(H,I)}async load_from_files(T,I){let D=[...T.keys()].filter((J)=>J.toLowerCase().endsWith(".osu"));if(D.length===0)throw Error("No .osu files found in beatmap");let H=new f,V=D.map((J)=>{let Q=this.to_string(T.get(J));return H.parse_info(Q,J)}),F=this.select_difficulty(D,T,I?.difficulty),S=this.to_string(T.get(F)),U=H.parse(S),R=AT(S),B=PT(S),$=OT(S),O=new Map;for(let[J,Q]of T)if(Q instanceof ArrayBuffer)O.set(J,Q);else O.set(J,new TextEncoder().encode(Q).buffer);let N;if(R)N=this.find_file(O,R);let M;if(B){let J=this.find_file(O,B);if(J)M=new Blob([J])}let W,A;if($){let J=this.find_file(O,$.filename);if(J)W=new Blob([J]),A=$.offset}return{beatmap:U,available_difficulties:V,files:O,audio:N,background:M,video:W,audio_filename:R??void 0,background_filename:B??void 0,video_filename:$?.filename,video_offset:A}}async list_difficulties(T){let I=await xT.loadAsync(T),D=[];for(let V of Object.keys(I.files))if(V.toLowerCase().endsWith(".osu"))D.push(V);let H=[];for(let V of D){let S=(await I.files[V].async("string")).match(/Version:\s*(.+)/);H.push(S?S[1].trim():V)}return H}select_difficulty(T,I,D){if(D===void 0)return T[0];if(typeof D==="number"){if(D<0||D>=T.length)throw Error(`Difficulty index ${D} out of range (0-${T.length-1})`);return T[D]}for(let H of T){let F=this.to_string(I.get(H)).match(/Version:\s*(.+)/);if(F&&F[1].trim()===D)return H}for(let H of T)if(H.toLowerCase().includes(D.toLowerCase()))return H;throw Error(`Difficulty "${D}" not found`)}find_file(T,I){if(T.has(I))return T.get(I);let D=I.toLowerCase();for(let[H,V]of T)if(H.toLowerCase()===D)return V;return}to_string(T){if(typeof T==="string")return T;return new TextDecoder().decode(T)}}var $T=512,NT=384,yT;((F)=>{F[F.None=0]="None";F[F.Large=32]="Large";F[F.Medium=16]="Medium";F[F.Small=8]="Small";F[F.Tiny=4]="Tiny"})(yT||={});var u={offset_x:64,offset_y:48,scale:1,show_playfield:!0,playfield_color:"#ffffff",playfield_opacity:0.1,grid_level:0,grid_color:"#ffffff",grid_opacity:0.35,use_high_dpi:!0};class b{backend;skin;config;mods;beatmap;objects=[];background_image=null;constructor(T,I,D=0,H=u){this.backend=T,this.skin=I,this.mods=D,this.config={...u,...H}}set_background(T){this.background_image=T}update_config(T){this.config={...this.config,...T}}dispose(){this.objects=[]}render_playfield(T,I,D,H){if(!this.config.show_playfield)return;let{backend:V,config:F}=this,S=T??512,U=I??384,R=D??0,B=H??0;V.save(),V.set_alpha(F.playfield_opacity),V.begin_path(),V.move_to(R,B),V.line_to(R+S,B),V.line_to(R+S,B+U),V.line_to(R,B+U),V.line_to(R,B),V.stroke_path(F.playfield_color,2),V.restore()}render_grid(){if(this.config.grid_level===0)return;let{backend:T,config:I}=this,D=I.grid_level;T.save(),T.set_alpha(I.grid_opacity);for(let H=0;H<=512;H+=D)T.begin_path(),T.move_to(H,0),T.line_to(H,384),T.stroke_path(I.grid_color,H%(D*4)===0?1:0.5);for(let H=0;H<=384;H+=D)T.begin_path(),T.move_to(0,H),T.line_to(512,H),T.stroke_path(I.grid_color,H%(D*4)===0?1:0.5);T.restore()}render_background(){if(!this.background_image)return;let{backend:T}=this;T.save(),T.set_alpha(0.3);let{width:I,height:D}=T,{width:H,height:V}=this.background_image;if(H>0&&V>0){let F=Math.max(I/H,D/V),S=H*F,U=V*F,R=(I-S)/2,B=(D-U)/2;T.draw_image(this.background_image,R,B,S,U)}else T.draw_image(this.background_image,0,0,I,D);T.restore()}get_visible_objects(T,I,D){let H=[];for(let V of this.objects){let F=V.time-I,S=V.end_time+D;if(T>=F&&T<=S)H.push(V)}return H}}class a{ctx;_width=0;_height=0;_dpr=1;get width(){return this._width}get height(){return this._height}initialize(T,I=!0){this._dpr=I?window.devicePixelRatio||1:1;let D=T.clientWidth||T.width,H=T.clientHeight||T.height;T.width=D*this._dpr,T.height=H*this._dpr;let V=T.getContext("2d",{alpha:!0,desynchronized:!0});if(!V)throw Error("Failed to get 2D context");this.ctx=V,this._width=D,this._height=H,V.scale(this._dpr,this._dpr),V.imageSmoothingEnabled=!0,V.imageSmoothingQuality="high"}clear(){this.ctx.save(),this.ctx.setTransform(this._dpr,0,0,this._dpr,0,0),this.ctx.clearRect(0,0,this._width,this._height),this.ctx.restore()}dispose(){}resize(T,I){this._width=T,this._height=I,this._dpr=window.devicePixelRatio||1;let D=this.ctx.canvas;D.width=T*this._dpr,D.height=I*this._dpr,D.style.width=`${T}px`,D.style.height=`${I}px`,this.ctx.resetTransform(),this.ctx.scale(this._dpr,this._dpr),this.ctx.imageSmoothingEnabled=!0,this.ctx.imageSmoothingQuality="high"}draw_circle(T,I,D,H,V,F){let S=this.ctx;if(S.beginPath(),S.arc(T,I,D,0,Math.PI*2),H&&H!=="transparent")S.fillStyle=H,S.fill();if(V&&F&&F>0)S.strokeStyle=V,S.lineWidth=F,S.stroke()}draw_arc(T,I,D,H,V,F,S,U=!1){let R=this.ctx;R.beginPath(),R.arc(T,I,D,H,V,U),R.strokeStyle=F,R.lineWidth=S,R.stroke()}draw_rect(T,I,D,H,V){this.ctx.fillStyle=V,this.ctx.fillRect(T,I,D,H)}draw_rect_gradient(T,I,D,H,V){this.ctx.fillStyle=V,this.ctx.fillRect(T,I,D,H)}create_linear_gradient(T,I,D,H,V){let F=this.ctx.createLinearGradient(T,I,D,H);for(let S of V)F.addColorStop(S.offset,S.color);return F}draw_text(T,I,D,H,V,F="left",S="alphabetic"){let U=this.ctx;U.font=H,U.fillStyle=V,U.textAlign=F,U.textBaseline=S,U.fillText(T,I,D)}begin_path(){this.ctx.beginPath()}move_to(T,I){this.ctx.moveTo(T,I)}line_to(T,I){this.ctx.lineTo(T,I)}bezier_curve_to(T,I,D,H,V,F){this.ctx.bezierCurveTo(T,I,D,H,V,F)}quadratic_curve_to(T,I,D,H){this.ctx.quadraticCurveTo(T,I,D,H)}arc_to(T,I,D,H,V,F){this.ctx.arc(T,I,D,H,V,F)}rect(T,I,D,H){this.ctx.rect(T,I,D,H)}clip(){this.ctx.clip()}stroke_path(T,I,D="butt",H="miter"){let V=this.ctx;V.strokeStyle=T,V.lineWidth=I,V.lineCap=D,V.lineJoin=H,V.stroke()}fill_path(T){this.ctx.fillStyle=T,this.ctx.fill()}save(){this.ctx.save()}restore(){this.ctx.restore()}translate(T,I){this.ctx.translate(T,I)}scale(T,I){this.ctx.scale(T,I)}rotate(T){this.ctx.rotate(T)}set_alpha(T){this.ctx.globalAlpha=T}set_shadow(T,I){this.ctx.shadowColor=T,this.ctx.shadowBlur=I}set_composite_operation(T){this.ctx.globalCompositeOperation=T}draw_image(T,I,D,H,V){if(H!==void 0&&V!==void 0)this.ctx.drawImage(T.source,I,D,H,V);else this.ctx.drawImage(T.source,I,D)}draw_image_part(T,I,D,H,V,F,S,U,R){this.ctx.drawImage(T.source,I,D,H,V,F,S,U,R)}render_slider_to_image(T,I,D,H,V,F=1,S=1){let U=1/0,R=1/0,B=-1/0,$=-1/0;for(let Z of T){if(Z[0]<U)U=Z[0];if(Z[0]>B)B=Z[0];if(Z[1]<R)R=Z[1];if(Z[1]>$)$=Z[1]}let O=I+2;U-=O,R-=O,B+=O,$+=O;let N=Math.ceil((B-U)*V),M=Math.ceil(($-R)*V);if(N<=0||M<=0)return null;let W=document.createElement("canvas");W.width=N,W.height=M;let A=W.getContext("2d");if(!A)return null;A.save(),A.scale(V,V),A.translate(-U,-R);let J=()=>{if(A.beginPath(),T.length>0){A.moveTo(T[0][0],T[0][1]);for(let Z=1;Z<T.length;Z++)A.lineTo(T[Z][0],T[Z][1])}};A.lineCap="round",A.lineJoin="round",A.globalAlpha=S,A.strokeStyle=D,A.lineWidth=I*2,J(),A.stroke();let Q=I*0.872;if(F<1)A.globalCompositeOperation="destination-out",A.globalAlpha=1,A.lineWidth=Q*2,J(),A.stroke(),A.globalCompositeOperation="source-over";return A.globalAlpha=F,A.strokeStyle=H,A.lineWidth=Q*2,J(),A.stroke(),A.restore(),{source:W,width:N,height:M,min_x:U,min_y:R}}}var t={min:1800,mid:1200,max:450},cT=450,jT=(T,I)=>{if(T>5)return I.mid+(I.max-I.mid)*(T-5)/5;if(T<5)return I.mid+(I.mid-I.min)*(T-5)/5;return I.mid},JT=(T,I)=>{if(Math.sign(T-I.mid)===Math.sign(I.max-I.mid))return(T-I.mid)/(I.max-I.mid)*5+5;return(T-I.mid)/(I.mid-I.min)*5+5},d=(T)=>jT(T,t),MT=(T)=>400*Math.min(1,T/450),pT=(T)=>{return(1-0.7*((T-5)/5))/2},WT=(T)=>pT(T)*64;var ZT={name:"Hard Rock",acronym:"HR",apply_to_difficulty(T){T.cs=Math.min(T.cs*1.3,10),T.ar=Math.min(T.ar*1.4,10),T.od=Math.min(T.od*1.4,10),T.hp=Math.min(T.hp*1.4,10)}};var qT={name:"Easy",acronym:"EZ",apply_to_difficulty(T){T.cs*=0.5,T.ar*=0.5,T.od*=0.5,T.hp*=0.5}};var nT={name:"Double Time",acronym:"DT",get_rate_multiplier:()=>1.5},dT={name:"Nightcore",acronym:"NC",get_rate_multiplier:()=>1.5};var sT={name:"Half Time",acronym:"HT",get_rate_multiplier:()=>0.75};var _T=0.4,oT=0.3,iT={name:"Hidden",acronym:"HD"};var QT=(T)=>{if(T&(P.DoubleTime|P.Nightcore))return 1.5;if(T&P.HalfTime)return 0.75;return 1},aT=(T,I)=>{if(I&P.Easy)qT.apply_to_difficulty(T);if(I&P.HardRock)ZT.apply_to_difficulty(T)},tT=(T,I)=>{if(I===1)return T;let D=d(T)/I;return JT(D,t)},gT=(T,I,D,H,V)=>{let F={cs:T,ar:I,od:D,hp:H};aT(F,V);let S=QT(V);return F.ar=tT(F.ar,S),F};var kT=(T,I)=>[T[0]+I[0],T[1]+I[1]],C=(T,I)=>[T[0]-I[0],T[1]-I[1]],fT=(T,I)=>[T[0]*I,T[1]*I],eT=(T,I)=>[T[0]/I,T[1]/I],bI=(T,I)=>T[0]*I[0]+T[1]*I[1],z=(T)=>Math.sqrt(T[0]*T[0]+T[1]*T[1]),rI=(T)=>T[0]*T[0]+T[1]*T[1],mI=(T,I)=>z(C(T,I)),XT=(T)=>{let I=z(T);return I>0?eT(T,I):[0,0]},k=(T,I,D)=>T+(I-T)*D,r=(T,I,D)=>[k(T[0],I[0],D),k(T[1],I[1],D)],q=(T,I,D)=>Math.min(D,Math.max(I,T));var e=(T,I=0.25)=>{if(T.length<2)return[...T];let D=[];return KT(T,D,I),D},KT=(T,I,D)=>{if(TI(T,D)){if(I.length===0)I.push(T[0]);I.push(T[T.length-1]);return}let H=[],V=[];DI(T,H,V),KT(H,I,D),KT(V,I,D)},TI=(T,I)=>{if(T.length<=2)return!0;let D=T[0],H=T[T.length-1];for(let V=1;V<T.length-1;V++)if(II(T[V],D,H)>I)return!1;return!0},II=(T,I,D)=>{let H=C(D,I),V=H[0]*H[0]+H[1]*H[1];if(V===0)return z(C(T,I));let F=Math.max(0,Math.min(1,((T[0]-I[0])*H[0]+(T[1]-I[1])*H[1])/V)),S=[I[0]+F*H[0],I[1]+F*H[1]];return z(C(T,S))},DI=(T,I,D)=>{let H=T.length,V=[T];for(let F=1;F<H;F++){V[F]=[];for(let S=0;S<H-F;S++)V[F][S]=r(V[F-1][S],V[F-1][S+1],0.5)}for(let F=0;F<H;F++)I.push(V[F][0]),D.push(V[H-1-F][F])},TT=(T,I,D)=>{let H=C(I,T),V=z(H);if(V===0)return[T];let F=[H[0]/V,H[1]/V],S=kT(T,fT(F,D));return[T,S]},YT=(T,I)=>{if(T.length!==3)return e(T);let[D,H,V]=T,F=HI(D,H,V);if(!F)return TT(D,V,I);let S=z(C(D,F)),U=Math.atan2(D[1]-F[1],D[0]-F[0]),R=Math.atan2(V[1]-F[1],V[0]-F[0]),$=(H[0]-D[0])*(V[1]-D[1])-(H[1]-D[1])*(V[0]-D[0])>0,O=R-U;if($&&O<0)O+=2*Math.PI;if(!$&&O>0)O-=2*Math.PI;let N=Math.abs(O)*S,M=Math.max(2,Math.ceil(Math.abs(O)*S/4)),W=[];for(let A=0;A<=M;A++){let J=A/M,Q=U+O*J*Math.min(1,I/N);W.push([F[0]+S*Math.cos(Q),F[1]+S*Math.sin(Q)])}return W},HI=(T,I,D)=>{let H=2*(T[0]*(I[1]-D[1])+I[0]*(D[1]-T[1])+D[0]*(T[1]-I[1]));if(Math.abs(H)<0.001)return null;let V=((T[0]*T[0]+T[1]*T[1])*(I[1]-D[1])+(I[0]*I[0]+I[1]*I[1])*(D[1]-T[1])+(D[0]*D[0]+D[1]*D[1])*(T[1]-I[1]))/H,F=((T[0]*T[0]+T[1]*T[1])*(D[0]-I[0])+(I[0]*I[0]+I[1]*I[1])*(T[0]-D[0])+(D[0]*D[0]+D[1]*D[1])*(I[0]-T[0]))/H;return[V,F]},CT=(T)=>{if(T.length<2)return[...T];let I=[];for(let D=0;D<T.length-1;D++){let H=T[Math.max(0,D-1)],V=T[D],F=T[D+1],S=T[Math.min(T.length-1,D+2)],U=50;for(let R=0;R<=50;R++){let B=R/50;I.push(VI(H,V,F,S,B))}}return I},VI=(T,I,D,H,V)=>{let F=V*V,S=F*V;return[0.5*(2*I[0]+(-T[0]+D[0])*V+(2*T[0]-5*I[0]+4*D[0]-H[0])*F+(-T[0]+3*I[0]-3*D[0]+H[0])*S),0.5*(2*I[1]+(-T[1]+D[1])*V+(2*T[1]-5*I[1]+4*D[1]-H[1])*F+(-T[1]+3*I[1]-3*D[1]+H[1])*S)]};var LT={1:["#d5bc00"],2:["#ffffff","#ffffff"],3:["#ffffff","#d5bc00","#ffffff"],4:["#ffffff","#dc8dba","#dc8dba","#ffffff"],5:["#ffffff","#dc8dba","#d5bc00","#dc8dba","#ffffff"],6:["#ffffff","#dc8dba","#ffffff","#ffffff","#dc8dba","#ffffff"],7:["#ffffff","#dc8dba","#ffffff","#d5bc00","#ffffff","#dc8dba","#ffffff"],8:["#d5bc00","#ffffff","#dc8dba","#ffffff","#d5bc00","#ffffff","#dc8dba","#ffffff"],9:["#ffffff","#dc8dba","#ffffff","#dc8dba","#d5bc00","#dc8dba","#ffffff","#dc8dba","#ffffff"],10:["#ffffff","#dc8dba","#d5bc00","#dc8dba","#ffffff","#ffffff","#dc8dba","#d5bc00","#dc8dba","#ffffff"]},zT={combo_colors:["0,185,0","7, 105, 227","224, 4, 38","227, 171, 2"],circle_border_width:0.13,hit_circle_opacity:0.85,approach_circle_width:0.1,slider_body_opacity:0.8,slider_border_opacity:1,slider_tick_opacity:0.75,slider_tick_size:0.1,follow_circle_factor:1.5,follow_circle_width:4,follow_circle_opacity:0.8,follow_circle_color:"#ffffffff",follow_circle_use_combo_color:!1,slider_ball_color:"#ffffff",slider_ball_opacity:1,enable_slider_ball:!0,follow_point_width:2,spinner_size:180,spinner_center_size:10,mania_lane_width:30,mania_note_height:15,mania_hit_position:364,mania_lane_spacing:1,mania_lane_colors:LT,font_family:'"Exo 2", sans-serif',hit_animation_duration:300,hit_animation_scale:1.3,enable_hit_animations:!0,enable_follow_circle_animations:!0,enable_approach_circle:!0},IT=(T)=>{if(!T)return{...zT};return{...zT,...T,mania_lane_colors:T.mania_lane_colors?{...LT,...T.mania_lane_colors}:LT}},j=(T,I,D=1)=>{return`rgba(${T.combo_colors[I%T.combo_colors.length]},${D})`},s=(T,I,D)=>{let H=T.mania_lane_colors[I]??T.mania_lane_colors[4];return H[D%H.length]??"#ffffff"};var g=(T)=>1-Math.pow(1-T,3),GT=(T)=>384-T;class DT extends b{radius=32;preempt=1200;fade_in=600;timing_points=[];slider_cache=new Map;constructor(T,I,D=0,H=u){super(T,I,D,H)}initialize(T){this.beatmap=T,this.objects=JSON.parse(JSON.stringify(T.objects)).sort((D,H)=>D.time-H.time),this.timing_points=this.process_timing_points([...T.timing_points]),this.slider_cache.clear();let I=gT(T.cs,T.ar,0,0,this.mods);this.radius=WT(I.cs),this.preempt=d(I.ar),this.fade_in=MT(this.preempt),this.preprocess_objects()}set_mods(T){if(this.mods=T,this.beatmap)this.initialize(this.beatmap)}process_timing_points(T){if(T.length===0)return T;T[0].time=0;let I=T[0].ms_per_beat;for(let D of T)if(D.ms_per_beat<0)D.ms_per_beat=I*(-D.ms_per_beat/100);else I=D.ms_per_beat;return T.reverse()}preprocess_objects(){let T=0,I=1;for(let D of this.objects){if(wT(D))T=(T+1)%this.skin.combo_colors.length,I=1;else I++;if(D.combo_number=T,D.combo_count=I,c(D)){let H=D.data;if(K(this.mods,P.HardRock))H.pos=[H.pos[0],GT(H.pos[1])],H.control_points=H.control_points.map((S)=>[S[0],GT(S[1])]);H.computed_path=this.compute_slider_path(H);let V=this.get_timing_at(D.time),F=H.distance/(100*this.beatmap.sv)*V.ms_per_beat;H.duration=F,D.end_time=D.time+F*H.repetitions,D.end_pos=this.get_slider_position(H,D.end_time-D.time,F)}else if(p(D))D.end_pos=[256,192];else{let H=D.data;if(K(this.mods,P.HardRock))H.pos=[H.pos[0],GT(H.pos[1])];D.end_pos=H.pos}}}compute_slider_path(T){if(T.path_type==="L")return TT(T.pos,T.control_points[0],T.distance);let I=[T.pos,...T.control_points];switch(T.path_type){case"P":return YT(I,T.distance);case"C":return CT(I);default:return this.flatten_multibezier(I,T.distance)}}flatten_multibezier(T,I){let D=[],H=[T[0]];for(let F=1;F<T.length;F++){let[S,U]=[T[F-1],T[F]];if(S[0]===U[0]&&S[1]===U[1]){if(H.length>1)D.push(H);H=[U]}else H.push(U)}if(H.length>1)D.push(H);let V=[];for(let F of D){let S=e(F);V.push(...S)}return this.clamp_path_to_distance(V,I)}clamp_path_to_distance(T,I){if(T.length<2)return T;let D=[T[0]],H=0;for(let V=1;V<T.length;V++){let F=z(C(T[V],T[V-1]));if(H+F>=I){let U=(I-H)/F;D.push(r(T[V-1],T[V],U));break}H+=F,D.push(T[V])}return D}get_timing_at(T){for(let I of this.timing_points)if(I.time<=T)return I;return this.timing_points[this.timing_points.length-1]}render(T){let{backend:I,config:D}=this;this.render_background(),I.save(),I.translate(D.offset_x,D.offset_y),I.scale(D.scale,D.scale),this.render_playfield(),this.render_grid();let H=this.get_visible_objects(T,this.preempt,200);for(let V=0;V<H.length-1;V++){let F=H[V],S=H[V+1];if(!p(F)&&!p(S))this.draw_follow_point(F,S,T)}H.reverse();for(let V of H)if(c(V))this.draw_slider(V,T);else if(UT(V))this.draw_hit_circle(V,T);else if(p(V))this.draw_spinner(V,T);for(let V of H){if(!K(this.mods,P.Hidden)&&T<=V.time&&this.skin.enable_approach_circle&&(c(V)||UT(V)))this.draw_approach_circle(V,T);if(c(V)&&T>V.time&&T<=V.end_time+240)this.draw_follow_circle(V,T)}I.restore()}get_slider_body_opacity(T,I){let D=T.time-this.preempt;if(K(this.mods,P.Hidden)){let V=this.preempt*0.4,F=D+V;if(I<D)return 0;if(I<F)return q((I-D)/V,0,1);let S=T.end_time-F;return 1-q((I-F)/S,0,1)}if(I<D)return 0;let H=q((I-D)/this.fade_in,0,1);if(I>T.end_time){let V=q((I-T.end_time)/200,0,1);H=1-g(V)}return q(H,0,1)}draw_approach_circle(T,I){if(K(this.mods,P.Hidden))return;let{backend:D,skin:H,radius:V,preempt:F,fade_in:S}=this,U=T.data.pos,R=T.time-F;if(I<R||I>T.time)return;let $=1+(T.time-I)/F*3,O=V*$,N=Math.min(S*2,F),M=q((I-R)/N,0,0.9);D.set_alpha(M),D.draw_circle(U[0],U[1],O,"transparent",j(H,T.combo_number,1),V*H.approach_circle_width),D.set_alpha(1)}draw_hit_circle(T,I){let{backend:D,skin:H,radius:V,fade_in:F,preempt:S}=this,U=T.data.pos,R=T.time-S,B=240;if(I<R)return;if(I>T.end_time+240)return;let $=1,O=1;if(I<T.time)if(K(this.mods,P.Hidden)){let A=this.preempt*0.4,J=R+A,Q=this.preempt*0.3;if(I<J)$=q((I-R)/A,0,1);else $=1-q((I-J)/Q,0,1)}else $=q((I-R)/this.fade_in,0,1);else{if(K(this.mods,P.Hidden))return;if(!H.enable_hit_animations)return;let A=q((I-T.end_time)/240,0,1);O=1+(H.hit_animation_scale-1)*g(A),$=1-g(A)}if($<=0)return;let N=V*O,M=N*(1-H.circle_border_width/2),W=N*H.circle_border_width;if(D.set_alpha($*H.hit_circle_opacity),D.draw_circle(U[0],U[1],M,j(H,T.combo_number,1),"rgba(255,255,255,1)",W),I<T.time){let A=V*0.8,J=A*0.05;D.draw_text(String(T.combo_count),U[0],U[1]+J,`600 ${A}px ${H.font_family}`,"rgba(255,255,255,1)","center","middle")}D.set_alpha(1)}draw_slider(T,I){let{backend:D,skin:H,radius:V}=this,F=T.data,S=F.computed_path;if(!S||S.length<2)return;let U=this.get_slider_body_opacity(T,I);if(U<=0.01)return;let B=V*0.872,$=j(H,T.combo_number,1);if(H.slider_body_opacity<1&&H.slider_border_opacity>0)this.draw_masked_slider(T,S,$,U,H.slider_body_opacity,H.slider_border_opacity);else{D.save(),D.set_alpha(U*H.slider_border_opacity),D.begin_path(),D.move_to(S[0][0],S[0][1]);for(let A=1;A<S.length;A++)D.line_to(S[A][0],S[A][1]);D.stroke_path("rgba(255,255,255,1)",V*2,"round","round"),D.set_alpha(U*H.slider_body_opacity),D.begin_path(),D.move_to(S[0][0],S[0][1]);for(let A=1;A<S.length;A++)D.line_to(S[A][0],S[A][1]);D.stroke_path($,B*2,"round","round"),D.restore(),D.set_alpha(U)}if(this.draw_slider_ticks(T,F,S,I),F.repetitions>1)this.handle_reverse_arrows(T,F,S,I);let O=T.time-this.preempt,N=150,M=0,W=1;if(K(this.mods,P.Hidden)){let A=this.preempt*0.4,J=O+A,Q=this.preempt*0.3;if(I<O)M=0;else if(I<T.time)if(I<J)M=q((I-O)/A,0,1);else M=1-q((I-J)/Q,0,1);else if(I<T.time+N){let Z=0;if(T.time<J)Z=q((T.time-O)/A,0,1);else Z=1-q((T.time-J)/Q,0,1);let X=(I-T.time)/N;M=Z*(1-g(X)),W=1+g(X)*0.4}}else if(I<O)M=0;else if(I<T.time)M=q((I-O)/this.fade_in,0,1);else if(I<T.time+N){let A=q((T.time-O)/this.fade_in,0,1),J=(I-T.time)/N;M=A*(1-g(J)),W=1+g(J)*0.4}if(M>0){let A=F.pos,J=V*(1-H.circle_border_width/2)*W,Q=V*H.circle_border_width*W;D.set_alpha(M*H.hit_circle_opacity),D.draw_circle(A[0],A[1],J,j(H,T.combo_number,1),"rgba(255,255,255,1)",Q);let Z=V*0.8*W,X=Z*0.05;D.draw_text(String(T.combo_count),A[0],A[1]+X,`600 ${Z}px ${H.font_family}`,"rgba(255,255,255,1)","center","middle")}D.set_alpha(1)}handle_reverse_arrows(T,I,D,H){let{radius:V,preempt:F,fade_in:S}=this,U=T.time-F,R=I.duration,B=1;if(K(this.mods,P.Hidden)){let M=F*0.4,W=U+M,A=F*0.3;if(H<U)B=0;else if(H<W)B=q((H-U)/M,0,1);else B=1-q((H-W)/A,0,1)}else if(H<U)B=0;else if(H<T.time)B=q((H-U)/S,0,1);if(B<=0)return;let $=Math.max(0,H-T.time),O=Math.floor($/R);if(I.repetitions-1-O>=1){let M=O%2===0;this.draw_reverse_arrow(D,M,H,B)}if(H<T.time){if(this.draw_reverse_arrow(D,!0,H,B),I.repetitions>2)this.draw_reverse_arrow(D,!1,H,B)}}draw_masked_slider(T,I,D,H,V,F){let{backend:S,config:U,radius:R}=this,B=this.slider_cache.get(T);if(B&&Math.abs(B.scale-U.scale)<0.001){if(S.save(),U.scale!==0)S.scale(1/U.scale,1/U.scale),S.translate(-U.offset_x,-U.offset_y);let A=B.image.min_x||0,J=B.image.min_y||0,Q=Math.floor(A*U.scale+U.offset_x),Z=Math.floor(J*U.scale+U.offset_y);S.set_alpha(H),S.draw_image(B.image,Q,Z),S.restore();return}let $=S.render_slider_to_image(I,R,"white",D,U.scale,V,F);if(!$)return;if(this.slider_cache.set(T,{image:$,scale:U.scale}),S.save(),U.scale!==0)S.scale(1/U.scale,1/U.scale),S.translate(-U.offset_x,-U.offset_y);let O=$.min_x||0,N=$.min_y||0,M=Math.floor(O*U.scale+U.offset_x),W=Math.floor(N*U.scale+U.offset_y);S.set_alpha(H),S.draw_image($,M,W),S.restore()}draw_slider_ticks(T,I,D,H){let{backend:V,skin:F,radius:S,preempt:U,fade_in:R}=this;if(H>T.end_time)return;let B=this.get_timing_at(T.time),$=100*this.beatmap.sv*B.velocity,O=$/B.beat_length,N=$/this.beatmap.tick_rate,M=O*10,W=I.distance,A=this.get_path_length(D);for(let J=N;J<=W;J+=N){if(J>=W-M)break;let Z=J/W*A,X=this.get_position_at_length(D,Z),Y=1;if(K(this.mods,P.Hidden)){let G=T.time+J/W*I.duration,E=G-Math.min(1000,U*0.7),x=G-U;if(H<x||H>E)Y=0;else if(H>E-200)Y=(E-H)/200;else Y=q((H-x)/R,0,1)}else{let G=T.time-U;if(H<G)Y=0;else{let x=q((H-G)/R,0,1),y=J/W*(R*0.3),L=q((H-G-y)/(R*0.5),0,1);Y=Math.min(x,L)}let E=T.time+J/W*I.duration;if(H>E){let x=(H-E)/150;Y=Math.max(0,Y*(1-x))}}if(Y>0)V.set_alpha(Y*F.slider_tick_opacity),V.draw_circle(X[0],X[1],S*F.slider_tick_size,"rgba(255,255,255,1)","rgba(255,255,255,0.1)",1)}}get_position_at_length(T,I){let D=0;for(let H=1;H<T.length;H++){let V=z(C(T[H],T[H-1]));if(D+V>=I){let F=(I-D)/V;return r(T[H-1],T[H],F)}D+=V}return T[T.length-1]}draw_reverse_arrow(T,I,D,H){let{backend:V,radius:F}=this;if(H<=0)return;let S,U;if(I){S=T[T.length-1];let y=T[T.length-1];for(let L=T.length-2;L>=0;L--){let m=T[L][0]-S[0],l=T[L][1]-S[1];if(m*m+l*l>1){y=T[L];break}}U=XT(C(y,S))}else{S=T[0];let y=T[0];for(let L=1;L<T.length;L++){let m=T[L][0]-S[0],l=T[L][1]-S[1];if(m*m+l*l>1){y=T[L];break}}U=XT(C(y,S))}let R=300,B=35,$=250,O=D%R,N=1;if(O<B)N=1+O/B*0.3;else N=1.3-(O-B)/$*0.3;let M=F*0.6*N,W=Math.atan2(U[1],U[0]),A=Math.PI/3.5,J=M*0.8,Q=M*0.25,Z=S[0]+Math.cos(W)*Q,X=S[1]+Math.sin(W)*Q,Y=Z-Math.cos(W-A)*J,G=X-Math.sin(W-A)*J,E=Z-Math.cos(W+A)*J,x=X-Math.sin(W+A)*J;V.set_alpha(H),V.begin_path(),V.move_to(Y,G),V.line_to(Z,X),V.line_to(E,x),V.stroke_path("rgba(255,255,255,1)",3*N,"round","round"),V.set_alpha(1)}draw_follow_circle(T,I){let{backend:D,skin:H,radius:V}=this,F=T.data,S=F.duration,U=S*F.repetitions,R=Math.min(I-T.time,U),B=this.get_slider_position(F,R,S),$=240;if(I>T.end_time+240)return;let N=1+Math.sin(I*0.008)*0.08,M=1,W=100;if(R<W)M=0.5+q(R/W,0,1)*0.5;let A=H.follow_circle_opacity;if(K(this.mods,P.Hidden)){let Z=T.time-this.preempt,X=this.preempt*0.4,Y=Z+X,G=this.preempt*0.3;if(I<Y)A*=q((I-Z)/X,0,1);else{let E=q((I-Y)/G,0,1);A*=1-E}}if(I>T.end_time){let Z=q((I-T.end_time)/240,0,1);A*=1-Z,M*=1+Z*0.3}if(A<=0)return;if(H.enable_slider_ball){let Z=V*0.85,X=A*(H.slider_ball_opacity/H.follow_circle_opacity);if(I>T.end_time){let Y=q((I-T.end_time)/100,0,1);X*=1-Y}if(X>0)D.set_alpha(X),D.draw_circle(B[0],B[1],Z,j(H,T.combo_number,0.7),"rgba(255,255,255,0.9)",V*0.12)}let J=V*H.follow_circle_factor*N*M,Q=H.follow_circle_use_combo_color?j(H,T.combo_number,1):H.follow_circle_color;D.set_alpha(A),D.begin_path(),D.arc_to(B[0],B[1],J,0,Math.PI*2),D.stroke_path(Q,H.follow_circle_width),D.set_alpha(1)}get_slider_position(T,I,D){let H=T.computed_path;if(!H||H.length===0)return T.pos;let V=I%(D*2),F=V<D?V/D:2-V/D;F=q(F,0,1);let S=this.get_path_length(H),U=F*S,R=0;for(let B=1;B<H.length;B++){let $=z(C(H[B],H[B-1]));if(R+$>=U){let O=(U-R)/$;return r(H[B-1],H[B],O)}R+=$}return H[H.length-1]}get_path_length(T){let I=0;for(let D=1;D<T.length;D++)I+=z(C(T[D],T[D-1]));return I}draw_spinner(T,I){let{backend:D,skin:H}=this,V=T.time-this.preempt;if(I<V)return;let F=q((I-V)/this.fade_in,0,1);if(I>T.end_time){let O=q((I-T.end_time)/200,0,1);F=1-g(O)}if(F<=0)return;let S=256,U=192,R=T.end_time-T.time,B=q((I-T.time)/R,0,1);D.set_alpha(F);let $=H.spinner_size*(1-B);if($>5)D.begin_path(),D.arc_to(S,U,$,0,Math.PI*2),D.stroke_path("rgba(255,255,255,0.6)",4);D.draw_circle(S,U,H.spinner_size,"rgba(0,0,0,0.2)"),D.draw_circle(S,U,12,"white")}draw_follow_point(T,I,D){if(K(this.mods,P.Hidden))return;if(T.combo_number!==I.combo_number)return;let{backend:H,skin:V}=this;if(D<T.end_time||D>I.time)return;let F=T.end_pos,S=I.data.pos,U=S[0]-F[0],R=S[1]-F[1];if(Math.sqrt(U*U+R*R)<48)return;let $=I.time-T.end_time,O=(D-T.end_time)/$,N=1;if(O<0.2)N=O/0.2;if(O>0.8)N=(1-O)/0.2;if(N<=0)return;let M=q(O*1.5,0,1),W=k(F[0],S[0],Math.max(0,O-0.3)),A=k(F[1],S[1],Math.max(0,O-0.3)),J=k(F[0],S[0],M),Q=k(F[1],S[1],M);H.set_alpha(N*0.6),H.begin_path(),H.move_to(W,A),H.line_to(J,Q),H.stroke_path("rgba(255,255,255,1)",V.follow_point_width,"round","round"),H.set_alpha(1)}}var hT=11485,bT=20;class HT extends b{key_count=4;scroll_time=hT/bT;hd_coverage=0.25;fi_coverage=0.6;gradient_ratio=0.2;constructor(T,I,D=0,H=u){super(T,I,D,H);this.update_scroll_time()}initialize(T){this.beatmap=T,this.objects=[...T.objects],this.key_count=Math.floor(T.cs);for(let I of this.objects)if(RT(I))I.end_time=I.data.end_time}set_mods(T){this.mods=T,this.update_scroll_time()}update_scroll_time(){let T=QT(this.mods);this.scroll_time=hT/(bT*T)}time_to_y(T){let I=this.skin.mania_hit_position,D=T/this.scroll_time;return I-D*I}render(T){let{backend:I,config:D,skin:H,key_count:V}=this;this.render_background();let F=V*H.mania_lane_width,S=Math.floor(($T-F)/2),U=H.mania_hit_position;I.save(),I.translate(D.offset_x,D.offset_y),I.scale(D.scale,D.scale),this.render_playfield(F,NT,S),this.draw_lane_keys(T,S),this.draw_judgment_line(S),I.save(),I.begin_path(),I.rect(S,0,F,U),I.clip(),I.set_alpha(0.7),I.draw_rect(S,0,F,U,"#000000"),I.set_alpha(1);for(let R of this.objects){if(R.end_time<T)continue;if(RT(R))this.draw_hold_note(R,T,S);else this.draw_note(R,T,S)}if(K(this.mods,P.Hidden)||K(this.mods,P.FadeIn)){let R=K(this.mods,P.Hidden)?this.hd_coverage:this.fi_coverage,B=U*R,$=U*this.gradient_ratio;if(K(this.mods,P.Hidden)){let O=U-B,N=$/B,M=I.create_linear_gradient(S,O,S,U,[{offset:0,color:"rgba(0,0,0,0)"},{offset:N*0.4,color:"rgba(0,0,0,0.3)"},{offset:N*0.7,color:"rgba(0,0,0,0.75)"},{offset:N*0.9,color:"rgba(0,0,0,0.95)"},{offset:N,color:"rgba(0,0,0,1)"},{offset:1,color:"rgba(0,0,0,1)"}]);I.draw_rect_gradient(S,O,F,B,M)}else{let O=(B-$)/B,N=I.create_linear_gradient(S,0,S,B,[{offset:0,color:"rgba(0,0,0,1)"},{offset:O,color:"rgba(0,0,0,1)"},{offset:O+(1-O)*0.1,color:"rgba(0,0,0,0.95)"},{offset:O+(1-O)*0.4,color:"rgba(0,0,0,0.75)"},{offset:O+(1-O)*0.7,color:"rgba(0,0,0,0.3)"},{offset:1,color:"rgba(0,0,0,0)"}]);I.draw_rect_gradient(S,0,F,B,N)}}I.restore(),I.restore()}get_lane(T){let I=T.data.pos,D=Math.floor(I[0]*this.key_count/512);if(K(this.mods,P.Mirror))D=this.key_count-1-D;return D}draw_note(T,I,D){let{backend:H,skin:V,key_count:F}=this,S=this.get_lane(T),U=V.mania_lane_width,R=V.mania_note_height,B=V.mania_lane_spacing,$=T.time-I,O=this.time_to_y($);if(O<-R-64)return;let N=D+S*U,M=s(V,F,S);H.set_alpha(1),H.draw_rect(N+B,O-R,U-2*B,R,M)}draw_hold_note(T,I,D){let{backend:H,skin:V,key_count:F}=this,S=T.data,U=this.get_lane(T),R=V.mania_lane_width,B=V.mania_note_height,$=V.mania_lane_spacing,O=T.time-I,N=S.end_time-I,M=this.time_to_y(O),W=this.time_to_y(N),A=D+U*R,J=s(V,F,U);if(W<-64&&M<-64)return;let Q=W,X=(O<0?V.mania_hit_position:M)-Q;if(X>0)H.set_alpha(0.9),H.draw_rect(A+$,Q,R-2*$,X,J);if(O>=0)H.set_alpha(1),H.draw_rect(A+$,M-B,R-2*$,B,J);H.set_alpha(1)}draw_judgment_line(T){let{backend:I,skin:D,key_count:H}=this,V=D.mania_lane_width,F=D.mania_hit_position;I.draw_rect(T,F-1,V*H,2,"#ffffff")}draw_lane_keys(T,I){let{backend:D,skin:H,key_count:V}=this,{mania_lane_width:F,mania_hit_position:S,mania_lane_spacing:U,mania_note_height:R}=H,B=R+5,$=new Set,O=50;for(let N of this.objects)if(T>=N.time-50&&T<=N.end_time+50)$.add(this.get_lane(N));for(let N=0;N<V;N++){let M=$.has(N),W=I+N*F,A=s(H,V,N);if(D.set_alpha(0.3),D.draw_rect(W+U,S,F-2*U,B,A),M)D.set_alpha(1),D.draw_rect(W+U,S,F-2*U,B,"#ff6666")}D.set_alpha(1)}}class VT{audio_context;audio_source=null;audio_buffer=null;gain_node;start_time=0;pause_time=0;speed=1;_is_playing=!1;_duration=0;_is_loaded=!1;constructor(T){this.audio_context=T,this.gain_node=this.audio_context.createGain(),this.gain_node.connect(this.audio_context.destination)}get is_playing(){return this._is_playing}get is_loaded(){return this._is_loaded}get duration(){return this._duration}get current_time(){if(!this._is_playing)return this.pause_time;return(this.audio_context.currentTime-this.start_time)*this.speed*1000}async load(T,I=0){this.stop();try{this.audio_buffer=await this.audio_context.decodeAudioData(T.slice(0)),this._duration=this.audio_buffer.duration*1000,this.speed=n(I),this._is_loaded=!0,this.pause_time=0}catch(D){throw console.error("Failed to decode audio data",D),D}}play(T){if(!this.audio_buffer){console.warn("[AudioController] Cannot play: not loaded");return}this.stop_source();let I=T!==void 0?T/1000:this.pause_time/1000,D=this.audio_buffer.duration,H=Math.max(0,Math.min(I,D));if(H>=D){this.pause_time=D*1000;return}this.audio_source=this.audio_context.createBufferSource(),this.audio_source.buffer=this.audio_buffer,this.audio_source.playbackRate.value=this.speed,this.audio_source.connect(this.gain_node),this.audio_source.onended=()=>{if(this._is_playing)this._is_playing=!1,this.pause_time=this._duration,this.audio_source=null},this.start_time=this.audio_context.currentTime-H/this.speed,this.audio_source.start(0,H),this._is_playing=!0}pause(){if(!this._is_playing)return;this.pause_time=this.current_time,this.stop_source(),this._is_playing=!1}seek(T){let I=Math.max(0,Math.min(T,this._duration));if(this._is_playing)this.stop_source(),this._is_playing=!1,this.pause_time=I,this.play();else this.pause_time=I}stop(){this.pause(),this.pause_time=0}get_host_time(T){return this.start_time+T/1000/this.speed}stop_source(){if(this.audio_source){try{this.audio_source.onended=null,this.audio_source.stop(),this.audio_source.disconnect()}catch{}this.audio_source=null}}set_volume(T){if(this.gain_node)this.gain_node.gain.value=Math.max(0,Math.min(1,T))}set_speed(T){if(this._is_playing){let I=this.current_time;this.speed=T,this.start_time=this.audio_context.currentTime-I/1000/T}else this.speed=T;if(this.audio_source)this.audio_source.playbackRate.value=T}dispose(){this.stop(),this.audio_buffer=null,this._is_loaded=!1,this.gain_node.disconnect()}}class FT{video=null;object_url=null;_offset=0;speed=1;get element(){return this.video}get offset(){return this._offset}async load(T,I=0,D=1){this.dispose(),this._offset=I,this.speed=D,this.video=document.createElement("video"),this.video.muted=!0,this.video.loop=!1,this.video.playsInline=!0,this.object_url=URL.createObjectURL(T),this.video.src=this.object_url,await new Promise((H,V)=>{if(!this.video)return V(Error("No video element"));this.video.onloadeddata=()=>H(),this.video.onerror=()=>V(Error("Failed to load video"))}),this.video.playbackRate=D}sync(T){if(!this.video)return;let I=(T-this._offset)/1000;if(I<0){if(!this.video.paused)this.video.pause();return}if(Math.abs(this.video.currentTime-I)>0.1)this.video.currentTime=I}play(){if(this.video&&this.video.paused)this.video.play().catch(()=>{console.log("failed to play video")})}pause(){if(this.video&&!this.video.paused)this.video.pause()}seek(T){if(!this.video)return;let I=Math.max(0,(T-this._offset)/1000);this.video.currentTime=I}set_speed(T){if(this.speed=T,this.video)this.video.playbackRate=T}dispose(){if(this.video)this.video.pause(),this.video.src="",this.video=null;if(this.object_url)URL.revokeObjectURL(this.object_url),this.object_url=null}}class ET{context;gain_node;samples=new Map;volume=1;constructor(T){this.context=T,this.gain_node=T.createGain(),this.gain_node.connect(T.destination)}set_volume(T){this.volume=Math.max(0,Math.min(1,T)),this.gain_node.gain.value=this.volume}async load_samples(T){this.samples.clear();let I=[];for(let[D,H]of T)if(D.endsWith(".wav")||D.endsWith(".mp3")||D.endsWith(".ogg"))I.push(this.context.decodeAudioData(H.slice(0)).then((V)=>{let F=D.toLowerCase().replace(/\.(wav|mp3|ogg)$/,"");this.samples.set(F,V)}).catch((V)=>{console.warn(`[HitsoundController] Failed to decode ${D}:`,V)}));await Promise.all(I)}play(T,I,D,H,V=100,F,S=0){let U=this.get_set_name(T),R=this.get_set_name(I);if(F){let B=F.toLowerCase().replace(/\.(wav|mp3|ogg)$/,"");if(this.play_buffer(B,V,S))return}if(this.play_sound(U,"hitnormal",H,V,S),D&o.Whistle)this.play_sound(R,"hitwhistle",H,V,S);if(D&o.Finish)this.play_sound(R,"hitfinish",H,V,S);if(D&o.Clap)this.play_sound(R,"hitclap",H,V,S)}play_sound(T,I,D,H,V){let F=!1;if(D>1)F=this.play_buffer(`${T}-${I}${D}`,H,V);if(!F)this.play_buffer(`${T}-${I}`,H,V)}play_buffer(T,I,D){let H=this.samples.get(T);if(!H)return!1;let V=this.context.createBufferSource();V.buffer=H;let F=this.context.createGain();return F.gain.value=I/100,V.connect(F),F.connect(this.gain_node),V.start(D),!0}get_set_name(T){switch(T){case 3:return"drum";case 2:return"soft";default:return"normal"}}dispose(){this.samples.clear(),this.gain_node.disconnect()}}class rT{backend;renderer=null;audio_context;audio;hitsounds;video=null;resources=null;animation_frame=null;skin;mods;renderer_config;start_offset;volume;listeners=new Map;_raw_osu_content="";_is_loaded=!1;next_hit_object_index=0;resize_observer=null;key_handler=null;options;constructor(T){this.options=T,this.backend=T.backend??new a,this.skin=IT(T.skin),this.mods=T.mods??0,this.renderer_config={...u,...T.renderer_config},this.calculate_layout(T.canvas.width,T.canvas.height,T.playfield_scale),this.start_offset=T.start_time??-1,this.volume=T.volume??0.5,this.backend.initialize(T.canvas,this.renderer_config.use_high_dpi);let I=window.AudioContext||window.webkitAudioContext;if(this.audio_context=new I,this.audio=new VT(this.audio_context),this.hitsounds=new ET(this.audio_context),this.audio.set_volume(this.volume),this.hitsounds.set_volume(this.volume),T.auto_resize)this.setup_auto_resize();if(T.key_bindings)this.setup_key_bindings(T.key_bindings)}async load_osz(T,I){try{let H=await new h().load_osz(T,{difficulty:I});return this.resources=H,this.setup()}catch(D){let H=D instanceof Error?D.message:String(D);return this.emit("error","INVALID_BEATMAP",H),v("INVALID_BEATMAP",H)}}async load_files(T,I){try{let D=new h;this.resources=await D.load_from_files(T,{difficulty:I});for(let[H,V]of T)if(H.endsWith(".osu")){this._raw_osu_content=typeof V==="string"?V:new TextDecoder().decode(V);break}return this.setup()}catch(D){let H=D instanceof Error?D.message:String(D);return this.emit("error","INVALID_BEATMAP",H),v("INVALID_BEATMAP",H)}}async load_hitsounds(T){try{await this.hitsounds.load_samples(T)}catch(I){console.error("[BeatmapPlayer] Failed to load hitsounds:",I)}}async load_beatmap(T,I,D,H,V){return this.resources={beatmap:T,available_difficulties:[],files:new Map,audio:I,background:D,video:H,video_offset:V},this.setup()}async load_osu_content(T,I){try{let H=new f().parse(T);return this._raw_osu_content=T,this.load_beatmap(H,I)}catch(D){let H=D instanceof Error?D.message:String(D);return this.emit("error","INVALID_BEATMAP",H),v("INVALID_BEATMAP",H)}}async setup(){if(!this.resources)return v("NOT_LOADED","No resources loaded");let{beatmap:T,audio:I,video:D,video_offset:H}=this.resources,V=n(this.mods);if(I)try{await this.audio.load(I,this.mods)}catch(F){let S=F instanceof Error?F.message:String(F);return this.emit("error","AUDIO_DECODE_ERROR",S),v("AUDIO_DECODE_ERROR",S)}if(D)this.video=new FT,await this.video.load(D,H??0,V);try{this.renderer=this.create_renderer(T),this.renderer.initialize(T)}catch(F){let S=F instanceof Error?F.message:String(F);return this.emit("error","UNSUPPORTED_MODE",S),v("UNSUPPORTED_MODE",S)}if(this.start_offset<0&&this._raw_osu_content){let F=BT(this._raw_osu_content);this.start_offset=F>0?F:this.get_last_object_time()*0.42}if(this.start_offset<0)this.start_offset=0;if(this.update_hit_index(this.start_offset),this.resources?.background)try{let F=new Image;F.src=URL.createObjectURL(this.resources.background),await F.decode(),this.renderer.set_background({source:F,width:F.width,height:F.height}),this._is_loaded=!0,requestAnimationFrame(()=>this.render_frame(this.start_offset))}catch(F){console.warn("[BeatmapPlayer] Failed to load background",F)}return this._is_loaded=!0,this.emit("loaded",T,this.resources),requestAnimationFrame(()=>this.render_frame(this.start_offset)),uT(this.resources)}create_renderer(T){switch(T.mode){case 0:return new DT(this.backend,this.skin,this.mods,this.renderer_config);case 3:return new HT(this.backend,this.skin,this.mods,this.renderer_config);case 1:case 2:default:throw Error(`Unsupported game mode: ${_[T.mode]??T.mode}`)}}get_last_object_time(){if(!this.resources?.beatmap.objects.length)return 0;let T=this.resources.beatmap.objects;return T[T.length-1].end_time}async play(){if(!this.renderer||!this._is_loaded){console.warn("[BeatmapPlayer] Cannot play: not loaded");return}if(this.audio.is_playing)return;if(this.audio_context.state==="suspended")await this.audio_context.resume();this.audio.play(this.start_offset),this.video?.play(),this.start_render_loop(),this.emit("play"),this.emit("statechange",!0)}pause(){if(!this.audio.is_playing)return;this.start_offset=this.audio.current_time,this.audio.pause(),this.video?.pause(),this.stop_render_loop(),this.emit("pause"),this.emit("statechange",!1)}set_mods(T){this.mods=T;let I=n(T);if(this.renderer?.set_mods(T),this.audio.set_speed(I),this.video?.set_speed(I),this._is_loaded)requestAnimationFrame(()=>this.render_frame(this.current_time))}seek(T){this.start_offset=Math.max(0,Math.min(T,this.duration)),this.update_hit_index(this.start_offset),this.audio.seek(this.start_offset),this.video?.seek(this.start_offset),this.emit("seek",this.start_offset),this.render_frame(this.start_offset)}async set_difficulty(T){if(!this.resources)return v("NOT_LOADED","No beatmap resources loaded");let I=this.is_playing;this.stop();try{let H=await new h().load_from_files(this.resources.files,{difficulty:T});this.resources=H;let V=this.resources.available_difficulties.find((S)=>S.version===this.resources.beatmap.version)?.filename;if(V){let S=this.resources.files.get(V);if(S)this._raw_osu_content=typeof S==="string"?S:new TextDecoder().decode(S)}let F=await this.setup();if(F.success&&I)this.play();return F}catch(D){let H=D instanceof Error?D.message:String(D);return this.emit("error","INVALID_BEATMAP",H),v("INVALID_BEATMAP",H)}}update_hit_index(T){if(!this.resources?.beatmap)return;let I=this.resources.beatmap.objects;if(this.next_hit_object_index>0&&I[this.next_hit_object_index-1].time>T)this.next_hit_object_index=0;while(this.next_hit_object_index<I.length&&I[this.next_hit_object_index].time<T)this.next_hit_object_index++}stop(){this.pause(),this.start_offset=0,this.audio.seek(0),this.update_hit_index(0),this.render_frame(0)}dispose(){if(this.stop(),this.backend.dispose(),this.audio.dispose(),this.hitsounds.dispose(),this.video?.dispose(),this.renderer?.dispose(),this.listeners.clear(),this.resize_observer)this.resize_observer.disconnect(),this.resize_observer=null;if(this.key_handler)window.removeEventListener("keydown",this.key_handler),this.key_handler=null;if(this.audio_context&&this.audio_context.state!=="closed")this.audio_context.close().catch(()=>{});this.renderer=null,this.resources=null,this._is_loaded=!1,this.listeners.clear()}get current_time(){return this.audio.current_time}get duration(){return this.audio.duration||this.get_last_object_time()}get is_playing(){return this.audio.is_playing}get is_loaded(){return this._is_loaded}get mode(){if(!this.resources)return"standard";switch(this.resources.beatmap.mode){case 1:return"taiko";case 2:return"catch";case 3:return"mania";default:return"standard"}}get beatmap(){return this.resources?.beatmap??null}get available_difficulties(){return this.resources?.available_difficulties??[]}get background(){return this.resources?.background}get config(){return this.renderer_config}resize(T,I,D){if(this.backend.resize(T,I),this.calculate_layout(T,I,D),this._is_loaded)requestAnimationFrame(()=>this.render_frame(this.current_time))}update_config(T){if(this.renderer_config={...this.renderer_config,...T},this.renderer?.update_config(this.renderer_config),this._is_loaded)requestAnimationFrame(()=>this.render_frame(this.current_time))}set_skin(T){if(this.skin=IT(T),this._is_loaded&&this.resources?.beatmap)this.renderer=this.create_renderer(this.resources.beatmap),this.renderer.initialize(this.resources.beatmap),requestAnimationFrame(()=>this.render_frame(this.current_time))}setup_auto_resize(){this.resize_observer=new ResizeObserver(()=>{let I=this.options.canvas.parentElement;if(I){let D=I.getBoundingClientRect();this.resize(D.width,D.height,this.options.playfield_scale)}}),this.resize_observer.observe(this.options.canvas.parentElement||this.options.canvas)}setup_key_bindings(T){this.key_handler=(I)=>{let D={toggle_pause:T.toggle_pause??"Space",seek_forward:T.seek_forward??"ArrowRight",seek_backward:T.seek_backward??"ArrowLeft",toggle_grid:T.toggle_grid??"g"};if(I.code===D.toggle_pause)I.preventDefault(),this.toggle_pause();else if(I.code===D.seek_forward)I.preventDefault(),this.seek(this.current_time+5000);else if(I.code===D.seek_backward)I.preventDefault(),this.seek(this.current_time-5000);else if(I.code===D.toggle_grid)this.toggle_grid()},window.addEventListener("keydown",this.key_handler)}toggle_pause(){if(!this._is_loaded)return;this.is_playing?this.pause():this.play()}toggle_grid(){if(this.renderer_config.grid_level===0)this.renderer_config.grid_level=32;else this.renderer_config.grid_level=0;this.render_frame(this.current_time)}calculate_layout(T,I,D){let F=0.9;if(typeof D==="number")F=D;let S=T*F/512,U=I*F/384,R=Math.min(S,U);if(this.renderer_config.scale=R,this.renderer_config.offset_x=Math.floor((T-512*R)/2),this.renderer_config.offset_y=Math.floor((I-384*R)/2),this.renderer)this.renderer.update_config(this.renderer_config)}set_volume(T){this.volume=T,this.audio.set_volume(T),this.hitsounds.set_volume(T)}on(T,I){if(!this.listeners.has(T))this.listeners.set(T,new Set);this.listeners.get(T).add(I)}off(T,I){this.listeners.get(T)?.delete(I)}emit(T,...I){let D=this.listeners.get(T);if(D)for(let H of D)H(...I)}start_render_loop(){if(this.animation_frame!==null)return;let T=()=>{if(!this.audio.is_playing){this.animation_frame=null;return}let I=this.audio.current_time;if(this.schedule_hitsounds(),this.render_frame(I),this.video?.sync(I),this.emit("timeupdate",I,this.duration),I>=this.duration){this.emit("ended"),this.stop_render_loop(),this.emit("statechange",!1);return}this.animation_frame=requestAnimationFrame(T)};this.animation_frame=requestAnimationFrame(T)}schedule_hitsounds(){if(!this.resources?.beatmap||!this.audio.is_playing)return;let T=this.resources.beatmap.objects,I=this.audio.current_time,H=I+100;while(this.next_hit_object_index<T.length&&T[this.next_hit_object_index].time<=H){let V=T[this.next_hit_object_index];if(V.time>=I-20)this.play_hitsound(V);this.next_hit_object_index++}}play_hitsound(T){let I=this.get_timing_point(T.time),D=I.volume,H=I.sample_set,V=I.sample_set,F=I.sample_index,S=void 0;if(T.hit_sample){let R=T.hit_sample;if(R.normal_set!==0){if(H=R.normal_set,R.addition_set===0)V=H}if(R.addition_set!==0)V=R.addition_set;if(R.index!==0)F=R.index;if(R.volume!==0)D=R.volume;S=R.filename}if(H===0)H=1;if(V===0)V=H;let U=this.audio.get_host_time(T.time);this.hitsounds.play(H,V,T.hit_sound,F,D,S,U)}get_timing_point(T){let I=this.resources?.beatmap.timing_points??[];for(let D=I.length-1;D>=0;D--)if(I[D].time<=T)return I[D];return I[0]}stop_render_loop(){if(this.animation_frame!==null)cancelAnimationFrame(this.animation_frame),this.animation_frame=null}render_frame(T){this.backend.clear(),this.renderer?.render(T)}}export{C as vec2_sub,XT as vec2_normalize,fT as vec2_mul,r as vec2_lerp,rI as vec2_len_sq,z as vec2_len,bI as vec2_dot,eT as vec2_div,mI as vec2_dist,kT as vec2_add,SI as unwrap,$I as toggle_mod,uT as ok,OI as mods_to_string,PI as mods_from_string,IT as merge_skin,k as lerp,p as is_spinner,c as is_slider,UI as is_ok,wT as is_new_combo,RT as is_hold,RI as is_err,UT as is_circle,JT as inverse_difficulty_range,K as has_mod,n as get_speed_multiplier,QT as get_rate_multiplier,s as get_mania_lane_color,j as get_combo_color,NI as get_available_mods,gT as get_adjusted_difficulty,YT as flatten_perfect,TT as flatten_linear,CT as flatten_catmull,e as flatten_bezier,OT as extract_video_info,BT as extract_preview_time,PT as extract_background_filename,AT as extract_audio_filename,v as err,jT as difficulty_range,q as clamp,WT as calculate_radius,d as calculate_preempt,MT as calculate_fade_in,tT as apply_rate_to_ar,aT as apply_mods_to_difficulty,FT as VideoController,DT as StandardRenderer,mT as SpeedChangingMods,ST as SampleSet,t as PREEMPT_RANGE,cT as PREEMPT_MIN,$T as PLAYFIELD_WIDTH,NT as PLAYFIELD_HEIGHT,h as OszLoader,P as Mods,dT as ModNightcore,iT as ModHidden,ZT as ModHardRock,sT as ModHalfTime,qT as ModEasy,nT as ModDoubleTime,HT as ManiaRenderer,o as HitSoundType,w as HitObjectType,oT as HD_FADE_OUT_MULTIPLIER,_T as HD_FADE_IN_MULTIPLIER,yT as GridLevel,_ as GameMode,vT as ErrorCode,AI as DifficultyChangingMods,zT as DEFAULT_SKIN,u as DEFAULT_RENDERER_CONFIG,a as CanvasBackend,rT as BeatmapPlayer,f as BeatmapParser,b as BaseRenderer,VT as AudioController};
1
+ var r;((D)=>{D[D.Standard=0]="Standard";D[D.Taiko=1]="Taiko";D[D.Catch=2]="Catch";D[D.Mania=3]="Mania"})(r||={});var H0;((D)=>{D[D.Auto=0]="Auto";D[D.Normal=1]="Normal";D[D.Soft=2]="Soft";D[D.Drum=3]="Drum"})(H0||={});var z={Circle:1,Slider:2,NewCombo:4,Spinner:8,ComboSkip:112,Hold:128},n={Normal:1,Whistle:2,Finish:4,Clap:8},x0=(I)=>(I.type&z.Circle)!==0,D0=(I)=>(I.type&z.Slider)!==0,g=(I)=>(I.type&z.Spinner)!==0,M0=(I)=>(I.type&z.Hold)!==0,y0=(I)=>(I.type&z.NewCombo)!==0;var v0;((P)=>{P.NoOsuFiles="NO_OSU_FILES";P.DifficultyNotFound="DIFFICULTY_NOT_FOUND";P.InvalidBeatmap="INVALID_BEATMAP";P.UnsupportedMode="UNSUPPORTED_MODE";P.AudioNotLoaded="AUDIO_NOT_LOADED";P.AudioDecodeError="AUDIO_DECODE_ERROR";P.NotLoaded="NOT_LOADED";P.Unknown="UNKNOWN"})(v0||={});var w0=(I)=>({success:!0,data:I}),L=(I,T)=>({success:!1,code:I,reason:T}),SI=(I)=>{if(I.success)return I.data;throw Error(`[${I.code}] ${I.reason}`)},QI=(I)=>{return I.success},qI=(I)=>{return!I.success};var F={None:0,NoFail:1,Easy:2,TouchDevice:4,Hidden:8,HardRock:16,SuddenDeath:32,DoubleTime:64,Relax:128,HalfTime:256,Nightcore:512,Flashlight:1024,Autoplay:2048,SpunOut:4096,Autopilot:8192,Perfect:16384,FadeIn:8388608,Mirror:1073741824},l0=F.DoubleTime|F.HalfTime|F.Nightcore,ZI=F.HardRock|F.Easy|l0,XI=(I)=>{let T=0,u=I.toLowerCase(),H={nf:F.NoFail,ez:F.Easy,td:F.TouchDevice,hd:F.Hidden,hr:F.HardRock,sd:F.SuddenDeath,dt:F.DoubleTime,rx:F.Relax,ht:F.HalfTime,nc:F.Nightcore,fl:F.Flashlight,at:F.Autoplay,so:F.SpunOut,ap:F.Autopilot,pf:F.Perfect,fi:F.FadeIn,mr:F.Mirror};for(let D=0;D<u.length-1;D+=2){let M=u.slice(D,D+2);if(H[M])T|=H[M]}return T},CI=(I)=>{let T=[];if(I&F.NoFail)T.push("NF");if(I&F.Easy)T.push("EZ");if(I&F.Hidden)T.push("HD");if(I&F.HardRock)T.push("HR");if(I&F.SuddenDeath)T.push("SD");if(I&F.DoubleTime)T.push("DT");if(I&F.HalfTime)T.push("HT");if(I&F.Nightcore)T.push("NC");if(I&F.Flashlight)T.push("FL");if(I&F.SpunOut)T.push("SO");if(I&F.FadeIn)T.push("FI");if(I&F.Mirror)T.push("MR");let u=T.indexOf("DT"),H=T.indexOf("NC");if(u>=0&&H>=0)T.splice(u,1);return T.join("")},k=(I)=>{if(I&(F.DoubleTime|F.Nightcore))return 1.5;if(I&F.HalfTime)return 0.75;return 1},o0=[F.HardRock|F.Easy,F.DoubleTime|F.HalfTime|F.Nightcore,F.Hidden|F.FadeIn],WI=(I,T)=>{if(I&T)return I&~T;let u=I;for(let H of o0)if(T&H)u&=~H;return u|T},K=(I,T)=>(I&T)!==0,KI=(I)=>{let T=[{name:"No Fail",acronym:"NF",value:F.NoFail},{name:"Easy",acronym:"EZ",value:F.Easy},{name:"Hidden",acronym:"HD",value:F.Hidden},{name:"Double Time",acronym:"DT",value:F.DoubleTime},{name:"Half Time",acronym:"HT",value:F.HalfTime},{name:"Nightcore",acronym:"NC",value:F.Nightcore}];switch(I){case"standard":return[...T,{name:"Hard Rock",acronym:"HR",value:F.HardRock},{name:"Flashlight",acronym:"FL",value:F.Flashlight}];case"mania":return[...T,{name:"Fade In",acronym:"FI",value:F.FadeIn},{name:"Mirror",acronym:"MR",value:F.Mirror}];case"taiko":case"catch":return[...T,{name:"Hard Rock",acronym:"HR",value:F.HardRock}];default:return T}};import f0 from"jszip";class c{beatmap;section="";parse(I){this.beatmap=this.create_empty_beatmap(),this.section="";let T=I.split(`
2
+ `);for(let u of T)this.parse_line(u);if(this.beatmap.ar===-1)this.beatmap.ar=this.beatmap.od;return this.beatmap}parse_info(I,T){this.beatmap=this.create_empty_beatmap(),this.section="";let u=I.split(`
3
+ `);for(let H of u)if(this.parse_line(H),this.section==="Events"||this.section==="TimingPoints"||this.section==="Colours"||this.section==="HitObjects")break;if(this.beatmap.ar===-1)this.beatmap.ar=this.beatmap.od;return{filename:T,title:this.beatmap.title,artist:this.beatmap.artist,version:this.beatmap.version,mode:this.beatmap.mode,ar:this.beatmap.ar,cs:this.beatmap.cs,od:this.beatmap.od,hp:this.beatmap.hp}}create_empty_beatmap(){return{format_version:1,mode:0,title:"",title_unicode:"",artist:"",artist_unicode:"",creator:"",version:"",ar:-1,cs:5,od:5,hp:5,sv:1,tick_rate:1,timing_points:[],objects:[],circle_count:0,slider_count:0,spinner_count:0,hold_count:0}}parse_line(I){if(I.startsWith(" ")||I.startsWith("_"))return;let T=I.trim();if(T.length===0||T.startsWith("//"))return;if(T.startsWith("[")&&T.endsWith("]")){this.section=T.slice(1,-1);return}let u=T.match(/osu file format v(\d+)/);if(u){this.beatmap.format_version=parseInt(u[1]);return}switch(this.section){case"General":this.parse_general(T);break;case"Metadata":this.parse_metadata(T);break;case"Difficulty":this.parse_difficulty(T);break;case"TimingPoints":this.parse_timing_point(T);break;case"HitObjects":this.parse_hit_object(T);break}}parse_general(I){let[T,u]=this.split_property(I);if(T==="Mode")this.beatmap.mode=parseInt(u)}parse_metadata(I){let[T,u]=this.split_property(I);switch(T){case"Title":this.beatmap.title=u;break;case"TitleUnicode":this.beatmap.title_unicode=u;break;case"Artist":this.beatmap.artist=u;break;case"ArtistUnicode":this.beatmap.artist_unicode=u;break;case"Creator":this.beatmap.creator=u;break;case"Version":this.beatmap.version=u;break}}parse_difficulty(I){let[T,u]=this.split_property(I),H=parseFloat(u);switch(T){case"CircleSize":this.beatmap.cs=H;break;case"OverallDifficulty":this.beatmap.od=H;break;case"ApproachRate":this.beatmap.ar=H;break;case"HPDrainRate":this.beatmap.hp=H;break;case"SliderMultiplier":this.beatmap.sv=H;break;case"SliderTickRate":this.beatmap.tick_rate=H;break}}current_beat_length=500;parse_timing_point(I){let T=I.split(",");if(T.length<2)return;let u=parseFloat(T[0]),H=parseFloat(T[1]),D=parseInt(T[3]??"0"),M=parseInt(T[4]??"0"),V=parseInt(T[5]??"100"),B=T.length>=7?T[6].trim()!=="0":!0,P=T.length>=8?(parseInt(T[7])&1)!==0:!1,$=H<0,J=$?-100/H:1;if(!$&&H>0)this.current_beat_length=H;this.beatmap.timing_points.push({time:u,ms_per_beat:H,change:B,sample_set:D,sample_index:M,volume:V,kiai:P,velocity:J,beat_length:this.current_beat_length})}parse_hit_object(I){let T=I.split(",");if(T.length<4)return;let u=parseFloat(T[0]),H=parseFloat(T[1]),D=parseFloat(T[2]),M=parseInt(T[3]),V=parseInt(T[4]??"0"),B={time:D,type:M,hit_sound:V,end_time:D,end_pos:[u,H],combo_number:0,combo_count:0,data:{pos:[u,H]}};if(M&z.Circle)this.beatmap.circle_count++,B.data={pos:[u,H]},this.parse_extras(T,5,B);else if(M&z.Slider){if(T.length<8)return;this.beatmap.slider_count++;let P=this.parse_slider_data(T,u,H);if(B.data=P,T.length>8)B.edge_sounds=T[8].split("|").map(($)=>parseInt($));if(T.length>9)B.edge_sets=T[9].split("|").map(($)=>{let J=$.split(":");return[parseInt(J[0]),parseInt(J[1])]});this.parse_extras(T,10,B)}else if(M&z.Spinner){this.beatmap.spinner_count++;let P=parseInt(T[5]);B.data={end_time:P},B.end_time=P,B.end_pos=[256,192],this.parse_extras(T,6,B)}else if(M&z.Hold){this.beatmap.hold_count++;let P=parseInt(T[5].split(":")[0]);B.data={pos:[u,H],end_time:P},B.end_time=P,this.parse_extras(T,6,B)}this.beatmap.objects.push(B)}parse_extras(I,T,u){if(T<I.length){let H=I[T];if(H&&H.includes(":")){let D=H.split(":");u.hit_sample={normal_set:parseInt(D[0]),addition_set:parseInt(D[1]),index:parseInt(D[2]),volume:parseInt(D[3]),filename:D[4]||void 0}}}}parse_slider_data(I,T,u){let H=I[5].split("|"),D=H[0],M=[];for(let P=1;P<H.length;P++){let $=H[P].split(":");M.push([parseInt($[0]),parseInt($[1])])}let V=parseInt(I[6]),B=parseFloat(I[7]);return{pos:[T,u],path_type:D,control_points:M,repetitions:V,distance:B}}split_property(I){let T=I.indexOf(":");if(T===-1)return[I,""];return[I.slice(0,T).trim(),I.slice(T+1).trim()]}}var p=4096,V0=(I)=>{let T=I.slice(0,p).match(/PreviewTime:\s*([+-]?\d+)/);return T?parseInt(T[1]):-1},P0=(I)=>{let T=I.slice(0,p).match(/AudioFilename:\s*(.+)/);return T?T[1].trim():null},B0=(I)=>{let T=I.slice(0,p).match(/0,0,"([^"]+)"/);return T?T[1]:null},$0=(I)=>{let T=I.slice(0,p).match(/(?:Video|1),(-?\d+),"([^"]+)"/);if(!T)return null;return{offset:parseInt(T[1]),filename:T[2]}};var j0=new c,x=(I)=>{return new Promise((T,u)=>{queueMicrotask(()=>{try{T(I())}catch(H){u(H)}})})};class l{parse(I){return x(()=>j0.parse(I))}parse_info(I,T){return x(()=>j0.parse_info(I,T))}extract_audio_filename(I){return x(()=>P0(I))}extract_background_filename(I){return x(()=>B0(I))}extract_video_info(I){return x(()=>$0(I))}extract_preview_time(I){return x(()=>V0(I))}dispose(){}}var F0=null,J0=()=>{if(!F0)F0=new l;return F0};class y{parser=new l;async load_osz(I,T){let u=await f0.loadAsync(I),H=new Map;for(let[D,M]of Object.entries(u.files))if(!M.dir)H.set(D,await M.async("arraybuffer"));return this.load_from_files(H,T)}async load_from_files(I,T){let u=[...I.keys()].filter((Q)=>Q.toLowerCase().endsWith(".osu"));if(u.length===0)throw Error("No .osu files found in beatmap");let H=await Promise.all(u.map(async(Q)=>{let W=this.to_string(I.get(Q));return this.parser.parse_info(W,Q)})),D=this.select_difficulty(u,I,T?.difficulty),M=this.to_string(I.get(D)),V=await this.parser.parse(M),[B,P,$]=await Promise.all([this.parser.extract_audio_filename(M),this.parser.extract_background_filename(M),this.parser.extract_video_info(M)]),J=new Map;for(let[Q,W]of I)if(W instanceof ArrayBuffer)J.set(Q,W);else J.set(Q,new TextEncoder().encode(W).buffer);let R;if(B)R=this.find_file(J,B);let S;if(P){let Q=this.find_file(J,P);if(Q)S=new Blob([Q])}let q,C;if($){let Q=this.find_file(J,$.filename);if(Q)q=new Blob([Q]),C=$.offset}return{beatmap:V,available_difficulties:H,files:J,audio:R,background:S,video:q,audio_filename:B??void 0,background_filename:P??void 0,video_filename:$?.filename,video_offset:C}}async list_difficulties(I){let T=await f0.loadAsync(I),u=[];for(let D of Object.keys(T.files))if(D.toLowerCase().endsWith(".osu"))u.push(D);let H=[];for(let D of u){let V=(await T.files[D].async("string")).match(/Version:\s*(.+)/);H.push(V?V[1].trim():D)}return H}select_difficulty(I,T,u){if(u===void 0)return I[0];if(typeof u==="number"){if(u<0||u>=I.length)throw Error(`Difficulty index ${u} out of range (0-${I.length-1})`);return I[u]}for(let H of I){let M=this.to_string(T.get(H)).match(/Version:\s*(.+)/);if(M&&M[1].trim()===u)return H}for(let H of I)if(H.toLowerCase().includes(u.toLowerCase()))return H;throw Error(`Difficulty "${u}" not found`)}find_file(I,T){if(I.has(T))return I.get(T);let u=T.toLowerCase();for(let[H,D]of I)if(H.toLowerCase()===u)return D;return}to_string(I){if(typeof I==="string")return I;return new TextDecoder().decode(I)}}var R0=512,S0=384,g0;((M)=>{M[M.None=0]="None";M[M.Large=32]="Large";M[M.Medium=16]="Medium";M[M.Small=8]="Small";M[M.Tiny=4]="Tiny"})(g0||={});var G={offset_x:64,offset_y:48,scale:1,show_playfield:!0,playfield_color:"#ffffff",playfield_opacity:0.1,grid_level:0,grid_color:"#ffffff",grid_opacity:0.35,use_high_dpi:!0};class v{backend;skin;config;mods;beatmap;objects=[];background_image=null;constructor(I,T,u=0,H=G){this.backend=I,this.skin=T,this.mods=u,this.config={...G,...H}}set_background(I){this.background_image=I}update_config(I){this.config={...this.config,...I}}dispose(){this.objects=[]}render_playfield(I,T,u,H){if(!this.config.show_playfield)return;let{backend:D,config:M}=this,V=I??512,B=T??384,P=u??0,$=H??0;D.save(),D.set_alpha(M.playfield_opacity),D.begin_path(),D.move_to(P,$),D.line_to(P+V,$),D.line_to(P+V,$+B),D.line_to(P,$+B),D.line_to(P,$),D.stroke_path(M.playfield_color,2),D.restore()}render_grid(){if(this.config.grid_level===0)return;let{backend:I,config:T}=this,u=T.grid_level;I.save(),I.set_alpha(T.grid_opacity);for(let H=0;H<=512;H+=u)I.begin_path(),I.move_to(H,0),I.line_to(H,384),I.stroke_path(T.grid_color,H%(u*4)===0?1:0.5);for(let H=0;H<=384;H+=u)I.begin_path(),I.move_to(0,H),I.line_to(512,H),I.stroke_path(T.grid_color,H%(u*4)===0?1:0.5);I.restore()}render_background(){if(!this.background_image)return;let{backend:I}=this;I.save(),I.set_alpha(0.3);let{width:T,height:u}=I,{width:H,height:D}=this.background_image;if(H>0&&D>0){let M=Math.max(T/H,u/D),V=H*M,B=D*M,P=(T-V)/2,$=(u-B)/2;I.draw_image(this.background_image,P,$,V,B)}else I.draw_image(this.background_image,0,0,T,u);I.restore()}get_visible_objects(I,T,u){let H=[];for(let D of this.objects){let M=D.time-T,V=D.end_time+u;if(I>=M&&I<=V)H.push(D)}return H}}class o{ctx;_width=0;_height=0;_dpr=1;get width(){return this._width}get height(){return this._height}initialize(I,T=!0){this._dpr=T?window.devicePixelRatio||1:1;let u=I.clientWidth||I.width,H=I.clientHeight||I.height;I.width=u*this._dpr,I.height=H*this._dpr;let D=I.getContext("2d",{alpha:!0,desynchronized:!0});if(!D)throw Error("Failed to get 2D context");this.ctx=D,this._width=u,this._height=H,D.scale(this._dpr,this._dpr),D.imageSmoothingEnabled=!0,D.imageSmoothingQuality="high"}clear(){this.ctx.save(),this.ctx.setTransform(this._dpr,0,0,this._dpr,0,0),this.ctx.clearRect(0,0,this._width,this._height),this.ctx.restore()}dispose(){}resize(I,T){this._width=I,this._height=T,this._dpr=window.devicePixelRatio||1;let u=this.ctx.canvas;u.width=I*this._dpr,u.height=T*this._dpr,u.style.width=`${I}px`,u.style.height=`${T}px`,this.ctx.resetTransform(),this.ctx.scale(this._dpr,this._dpr),this.ctx.imageSmoothingEnabled=!0,this.ctx.imageSmoothingQuality="high"}draw_circle(I,T,u,H,D,M){let V=this.ctx;if(V.beginPath(),V.arc(I,T,u,0,Math.PI*2),H&&H!=="transparent")V.fillStyle=H,V.fill();if(D&&M&&M>0)V.strokeStyle=D,V.lineWidth=M,V.stroke()}draw_arc(I,T,u,H,D,M,V,B=!1){let P=this.ctx;P.beginPath(),P.arc(I,T,u,H,D,B),P.strokeStyle=M,P.lineWidth=V,P.stroke()}draw_rect(I,T,u,H,D){this.ctx.fillStyle=D,this.ctx.fillRect(I,T,u,H)}draw_rect_gradient(I,T,u,H,D){this.ctx.fillStyle=D,this.ctx.fillRect(I,T,u,H)}create_linear_gradient(I,T,u,H,D){let M=this.ctx.createLinearGradient(I,T,u,H);for(let V of D)M.addColorStop(V.offset,V.color);return M}draw_text(I,T,u,H,D,M="left",V="alphabetic"){let B=this.ctx;B.font=H,B.fillStyle=D,B.textAlign=M,B.textBaseline=V,B.fillText(I,T,u)}begin_path(){this.ctx.beginPath()}move_to(I,T){this.ctx.moveTo(I,T)}line_to(I,T){this.ctx.lineTo(I,T)}bezier_curve_to(I,T,u,H,D,M){this.ctx.bezierCurveTo(I,T,u,H,D,M)}quadratic_curve_to(I,T,u,H){this.ctx.quadraticCurveTo(I,T,u,H)}arc_to(I,T,u,H,D,M){this.ctx.arc(I,T,u,H,D,M)}rect(I,T,u,H){this.ctx.rect(I,T,u,H)}clip(){this.ctx.clip()}stroke_path(I,T,u="butt",H="miter"){let D=this.ctx;D.strokeStyle=I,D.lineWidth=T,D.lineCap=u,D.lineJoin=H,D.stroke()}fill_path(I){this.ctx.fillStyle=I,this.ctx.fill()}close_path(){this.ctx.closePath()}save(){this.ctx.save()}restore(){this.ctx.restore()}translate(I,T){this.ctx.translate(I,T)}scale(I,T){this.ctx.scale(I,T)}rotate(I){this.ctx.rotate(I)}set_alpha(I){this.ctx.globalAlpha=I}set_shadow(I,T){this.ctx.shadowColor=I,this.ctx.shadowBlur=T}set_composite_operation(I){this.ctx.globalCompositeOperation=I}set_blend_mode(I){let T={normal:"source-over",lighter:"lighter",multiply:"multiply",screen:"screen"};this.ctx.globalCompositeOperation=T[I]??"source-over"}draw_image(I,T,u,H,D){if(H!==void 0&&D!==void 0)this.ctx.drawImage(I.source,T,u,H,D);else this.ctx.drawImage(I.source,T,u)}draw_image_part(I,T,u,H,D,M,V,B,P){this.ctx.drawImage(I.source,T,u,H,D,M,V,B,P)}render_slider_to_image(I,T,u,H,D,M=1,V=1){let B=1/0,P=1/0,$=-1/0,J=-1/0;for(let X of I){if(X[0]<B)B=X[0];if(X[0]>$)$=X[0];if(X[1]<P)P=X[1];if(X[1]>J)J=X[1]}let R=T+2;B-=R,P-=R,$+=R,J+=R;let S=Math.ceil(($-B)*D),q=Math.ceil((J-P)*D);if(S<=0||q<=0)return null;let C=document.createElement("canvas");C.width=S,C.height=q;let Q=C.getContext("2d");if(!Q)return null;Q.save(),Q.scale(D,D),Q.translate(-B,-P);let W=()=>{if(Q.beginPath(),I.length>0){Q.moveTo(I[0][0],I[0][1]);for(let X=1;X<I.length;X++)Q.lineTo(I[X][0],I[X][1])}};Q.lineCap="round",Q.lineJoin="round",Q.globalAlpha=V,Q.strokeStyle=u,Q.lineWidth=T*2,W(),Q.stroke();let Z=T*0.872;if(M<1)Q.globalCompositeOperation="destination-out",Q.globalAlpha=1,Q.lineWidth=Z*2,W(),Q.stroke(),Q.globalCompositeOperation="source-over";return Q.globalAlpha=M,Q.strokeStyle=H,Q.lineWidth=Z*2,W(),Q.stroke(),Q.restore(),{source:C,width:S,height:q,min_x:B,min_y:P}}}var d={min:1800,mid:1200,max:450},d0=450,k0=(I,T)=>{if(I>5)return T.mid+(T.max-T.mid)*(I-5)/5;if(I<5)return T.mid+(T.mid-T.min)*(I-5)/5;return T.mid},Q0=(I,T)=>{if(Math.sign(I-T.mid)===Math.sign(T.max-T.mid))return(I-T.mid)/(T.max-T.mid)*5+5;return(I-T.mid)/(T.mid-T.min)*5+5},b=(I)=>k0(I,d),q0=(I)=>400*Math.min(1,I/450),_0=(I)=>{return(1-0.7*((I-5)/5))/2},N0=(I)=>_0(I)*64;var Z0={name:"Hard Rock",acronym:"HR",apply_to_difficulty(I){I.cs=Math.min(I.cs*1.3,10),I.ar=Math.min(I.ar*1.4,10),I.od=Math.min(I.od*1.4,10),I.hp=Math.min(I.hp*1.4,10)}};var X0={name:"Easy",acronym:"EZ",apply_to_difficulty(I){I.cs*=0.5,I.ar*=0.5,I.od*=0.5,I.hp*=0.5}};var s0={name:"Double Time",acronym:"DT",get_rate_multiplier:()=>1.5},i0={name:"Nightcore",acronym:"NC",get_rate_multiplier:()=>1.5};var t0={name:"Half Time",acronym:"HT",get_rate_multiplier:()=>0.75};var a0=0.4,e0=0.3,II={name:"Hidden",acronym:"HD"};var C0=(I)=>{if(I&(F.DoubleTime|F.Nightcore))return 1.5;if(I&F.HalfTime)return 0.75;return 1},TI=(I,T)=>{if(T&F.Easy)X0.apply_to_difficulty(I);if(T&F.HardRock)Z0.apply_to_difficulty(I)},uI=(I,T)=>{if(T===1)return I;let u=b(I)/T;return Q0(u,d)},b0=(I,T,u,H,D)=>{let M={cs:I,ar:T,od:u,hp:H};TI(M,D);let V=C0(D);return M.ar=uI(M.ar,V),M};var h0=(I,T)=>[I[0]+T[0],I[1]+T[1]],U=(I,T)=>[I[0]-T[0],I[1]-T[1]],m0=(I,T)=>[I[0]*T,I[1]*T],HI=(I,T)=>[I[0]/T,I[1]/T],_I=(I,T)=>I[0]*T[0]+I[1]*T[1],Y=(I)=>Math.sqrt(I[0]*I[0]+I[1]*I[1]),sI=(I)=>I[0]*I[0]+I[1]*I[1],iI=(I,T)=>Y(U(I,T)),tI=(I)=>{let T=Y(I);return T>0?HI(I,T):[0,0]},E=(I,T,u)=>I+(T-I)*u,w=(I,T,u)=>[E(I[0],T[0],u),E(I[1],T[1],u)],N=(I,T,u)=>Math.min(u,Math.max(T,I));var _=(I,T=0.25)=>{if(I.length<2)return[...I];let u=[];return W0(I,u,T),u},W0=(I,T,u)=>{if(DI(I,u)){if(T.length===0)T.push(I[0]);T.push(I[I.length-1]);return}let H=[],D=[];VI(I,H,D),W0(H,T,u),W0(D,T,u)},DI=(I,T)=>{if(I.length<=2)return!0;let u=I[0],H=I[I.length-1];for(let D=1;D<I.length-1;D++)if(MI(I[D],u,H)>T)return!1;return!0},MI=(I,T,u)=>{let H=U(u,T),D=H[0]*H[0]+H[1]*H[1];if(D===0)return Y(U(I,T));let M=Math.max(0,Math.min(1,((I[0]-T[0])*H[0]+(I[1]-T[1])*H[1])/D)),V=[T[0]+M*H[0],T[1]+M*H[1]];return Y(U(I,V))},VI=(I,T,u)=>{let H=I.length,D=[I];for(let M=1;M<H;M++){D[M]=[];for(let V=0;V<H-M;V++)D[M][V]=w(D[M-1][V],D[M-1][V+1],0.5)}for(let M=0;M<H;M++)T.push(D[M][0]),u.push(D[H-1-M][M])},s=(I,T,u)=>{let H=U(T,I),D=Y(H);if(D===0)return[I];let M=[H[0]/D,H[1]/D],V=h0(I,m0(M,u));return[I,V]},K0=(I,T)=>{if(I.length!==3)return _(I);let[u,H,D]=I,M=PI(u,H,D);if(!M)return s(u,D,T);let V=Y(U(u,M)),B=Math.atan2(u[1]-M[1],u[0]-M[0]),P=Math.atan2(D[1]-M[1],D[0]-M[0]),J=(H[0]-u[0])*(D[1]-u[1])-(H[1]-u[1])*(D[0]-u[0])>0,R=P-B;if(J&&R<0)R+=2*Math.PI;if(!J&&R>0)R-=2*Math.PI;let S=Math.abs(R)*V,q=Math.max(2,Math.ceil(Math.abs(R)*V/4)),C=[];for(let Q=0;Q<=q;Q++){let W=Q/q,Z=B+R*W*Math.min(1,T/S);C.push([M[0]+V*Math.cos(Z),M[1]+V*Math.sin(Z)])}return C},PI=(I,T,u)=>{let H=2*(I[0]*(T[1]-u[1])+T[0]*(u[1]-I[1])+u[0]*(I[1]-T[1]));if(Math.abs(H)<0.001)return null;let D=((I[0]*I[0]+I[1]*I[1])*(T[1]-u[1])+(T[0]*T[0]+T[1]*T[1])*(u[1]-I[1])+(u[0]*u[0]+u[1]*u[1])*(I[1]-T[1]))/H,M=((I[0]*I[0]+I[1]*I[1])*(u[0]-T[0])+(T[0]*T[0]+T[1]*T[1])*(I[0]-u[0])+(u[0]*u[0]+u[1]*u[1])*(T[0]-I[0]))/H;return[D,M]},U0=(I)=>{if(I.length<2)return[...I];let T=[];for(let u=0;u<I.length-1;u++){let H=I[Math.max(0,u-1)],D=I[u],M=I[u+1],V=I[Math.min(I.length-1,u+2)],B=50;for(let P=0;P<=50;P++){let $=P/50;T.push(BI(H,D,M,V,$))}}return T},BI=(I,T,u,H,D)=>{let M=D*D,V=M*D;return[0.5*(2*T[0]+(-I[0]+u[0])*D+(2*I[0]-5*T[0]+4*u[0]-H[0])*M+(-I[0]+3*T[0]-3*u[0]+H[0])*V),0.5*(2*T[1]+(-I[1]+u[1])*D+(2*I[1]-5*T[1]+4*u[1]-H[1])*M+(-I[1]+3*T[1]-3*u[1]+H[1])*V)]};var Y0={1:["#d5bc00"],2:["#ffffff","#ffffff"],3:["#ffffff","#d5bc00","#ffffff"],4:["#ffffff","#dc8dba","#dc8dba","#ffffff"],5:["#ffffff","#dc8dba","#d5bc00","#dc8dba","#ffffff"],6:["#ffffff","#dc8dba","#ffffff","#ffffff","#dc8dba","#ffffff"],7:["#ffffff","#dc8dba","#ffffff","#d5bc00","#ffffff","#dc8dba","#ffffff"],8:["#d5bc00","#ffffff","#dc8dba","#ffffff","#d5bc00","#ffffff","#dc8dba","#ffffff"],9:["#ffffff","#dc8dba","#ffffff","#dc8dba","#d5bc00","#dc8dba","#ffffff","#dc8dba","#ffffff"],10:["#ffffff","#dc8dba","#d5bc00","#dc8dba","#ffffff","#ffffff","#dc8dba","#d5bc00","#dc8dba","#ffffff"]},O0={combo_colors:["0,185,0","7, 105, 227","224, 4, 38","227, 171, 2"],circle_border_width:0.12,hit_circle_opacity:0.95,enable_approach_circle:!0,approach_circle_width:0.1,approach_circle_opacity:0.5,approach_circle_use_combo_color:!0,enable_glow:!1,glow_use_combo_color:!0,glow_opacity:0.3,enable_hit_explode:!0,slider_body_opacity:0.9,slider_border_opacity:1,slider_tick_opacity:0.75,slider_tick_size:0.1,follow_circle_factor:1.5,follow_circle_width:4,follow_circle_opacity:0.5,follow_circle_color:"#d3d3d3ff",follow_circle_use_combo_color:!1,slider_ball_color:"#ffffff",slider_ball_opacity:1,enable_slider_ball:!0,follow_point_width:2,spinner_size:180,spinner_center_size:10,mania_lane_width:30,mania_note_height:15,mania_hit_position:364,mania_lane_spacing:1,mania_lane_colors:Y0,font_family:'"Exo 2", sans-serif',hit_animation_duration:300,hit_animation_scale:1.3,enable_hit_animations:!0,enable_follow_circle_animations:!0},i=(I)=>{if(!I)return{...O0};return{...O0,...I,mania_lane_colors:I.mania_lane_colors?{...Y0,...I.mania_lane_colors}:Y0}},A=(I,T,u=1)=>{return`rgba(${I.combo_colors[T%I.combo_colors.length]},${u})`},h=(I,T,u)=>{let H=I.mania_lane_colors[T]??I.mania_lane_colors[4];return H[u%H.length]??"#ffffff"};var O={None:(I)=>I,Out:(I)=>1-Math.pow(1-I,2),In:(I)=>I*I,InOut:(I)=>I<0.5?2*I*I:1-Math.pow(-2*I+2,2)/2,OutCubic:(I)=>1-Math.pow(1-I,3),InCubic:(I)=>I*I*I,OutQuad:(I)=>1-Math.pow(1-I,2),InQuad:(I)=>I*I,OutQuint:(I)=>1-Math.pow(1-I,5),InQuint:(I)=>I*I*I*I*I,OutElastic:(I)=>{let T=2*Math.PI/3;return I===0?0:I===1?1:Math.pow(2,-10*I)*Math.sin((I*10-0.75)*T)+1}};class t{transforms=[];add(I,T,u,H,D,M=O.None){return this.transforms.push({property:I,start_value:T,end_value:u,start_time:H,end_time:H+D,easing:M}),this}then(){return this}get_value(I,T,u){let H=u;for(let D of this.transforms){if(D.property!==I)continue;if(T<D.start_time)continue;if(T>=D.end_time)H=D.end_value;else{let M=(T-D.start_time)/(D.end_time-D.start_time),V=D.easing(M);H=D.start_value+(D.end_value-D.start_value)*V}}return H}clear(){this.transforms=[]}}class j{backend;skin;hit_object;config;alpha=1;scale=1;rotation=0;x=0;y=0;armed_state=0;transforms=new t;life_time_start=0;life_time_end=0;constructor(I,T){this.hit_object=I,this.config=T,this.backend=T.backend,this.skin=T.skin;let u=I.data;this.x=u.pos[0],this.y=u.pos[1],this.apply_defaults()}apply_defaults(){let{hit_object:I,config:T}=this,u=I.time-T.preempt;this.life_time_start=u,this.life_time_end=I.end_time+800}is_alive(I){return I>=this.life_time_start&&I<=this.life_time_end}update(I){this.alpha=this.transforms.get_value("alpha",I,1),this.scale=this.transforms.get_value("scale",I,1),this.rotation=this.transforms.get_value("rotation",I,0),this.update_state(I)}update_state(I){if(this.armed_state===0&&I>=this.hit_object.time)this.armed_state=1,this.on_hit(I)}on_hit(I){}render_body_pass(I){}render_head_pass(I){}get start_time(){return this.hit_object.time}get end_time(){return this.hit_object.end_time}get combo_number(){return this.hit_object.combo_number??0}get combo_count(){return this.hit_object.combo_count??1}get position(){return[this.x,this.y]}}class a extends j{circle_alpha=0;circle_scale=1;approach_alpha=0;approach_scale=4;flash_alpha=0;explode_alpha=0;constructor(I,T){super(I,T)}update(I){super.update(I),this.calculate_animations(I)}calculate_animations(I){let{config:T,hit_object:u}=this,H=u.time-T.preempt,D=u.time;if(this.flash_alpha=0,this.explode_alpha=0,I<H){this.circle_alpha=0,this.circle_scale=1,this.approach_alpha=0,this.approach_scale=4;return}if(I<D){let R=N((I-H)/T.fade_in,0,1);if(K(T.mods,F.Hidden)){let S=D-T.preempt*0.4,q=T.preempt*0.3;if(I>S){let C=N((I-S)/q,0,1);R*=1-C}}this.circle_alpha=R,this.circle_scale=1,this.approach_alpha=0,this.approach_scale=1;return}let M=I-D,V=40,B=100,P=400,$=240;if(this.approach_alpha=0.9*(1-N(M/50,0,1)),this.approach_scale=1,M<V)this.flash_alpha=0.8*(M/V);else if(M<V+B)this.flash_alpha=0.8*(1-(M-V)/B);if(M<V)this.explode_alpha=M/V;else this.explode_alpha=1-N((M-V)/($*2),0,1);let J=N(M/P,0,1);this.circle_scale=1+0.4*O.OutQuad(J),this.circle_alpha=1-N(M/$,0,1)}render(I){let{backend:T,skin:u,config:H,hit_object:D}=this,{radius:M}=H,V=this.position,B=A(u,this.combo_number,1);if(this.circle_alpha<=0&&this.approach_alpha<=0&&this.flash_alpha<=0&&this.explode_alpha<=0)return;let P=M*this.circle_scale;if(this.circle_alpha>0.01){let $=M*u.circle_border_width,J=M*(1-u.circle_border_width/2);T.set_alpha(this.circle_alpha*u.hit_circle_opacity),T.draw_circle(V[0],V[1],J,B,"rgba(255,255,255,1)",$);let R=M*0.8;T.draw_text(String(this.combo_count),V[0],V[1]+R*0.05,`600 ${R}px ${u.font_family}`,"rgba(255,255,255,1)","center","middle"),T.set_alpha(1)}if(u.enable_hit_explode&&this.flash_alpha>0.01)T.save(),T.set_blend_mode("lighter"),T.set_alpha(this.flash_alpha),T.draw_circle(V[0],V[1],P,"rgba(255,255,255,1)","transparent",0),T.restore();if(u.enable_hit_explode&&this.explode_alpha>0.01)T.save(),T.set_blend_mode("lighter"),T.set_alpha(this.explode_alpha*0.15),T.draw_circle(V[0],V[1],P*1.2,B,"transparent",0),T.restore()}}var z0=240,r0=150,L0=1.3,G0=35,$I=250,FI=300;class f extends j{slider_data;path;path_length;span_duration;body_alpha=0;head_alpha=0;head_scale=1;ball_alpha=0;ball_position;follow_alpha=0;follow_scale=1;ticks=[];repeats=[];tick_distance;cached_texture=null;constructor(I,T,u,H,D){super(I,T);this.slider_data=I.data,this.path=u,this.span_duration=H,this.tick_distance=D,this.path_length=this.calculate_path_length(),this.ball_position=this.slider_data.pos,this.generate_nested_objects(),this.life_time_end=I.end_time+z0}generate_nested_objects(){this.ticks=[],this.repeats=[];let{slider_data:I,path_length:T,span_duration:u,hit_object:H,tick_distance:D}=this,M=I.repetitions;if(D<=0||T<=0)return;let B=T/u*10;for(let P=0;P<M-1;P++){let $=H.time+(P+1)*u,J=(P+1)%2;this.repeats.push({pos:this.get_position_at_progress(J),time:$,repeat_index:P,path_progress:J})}for(let P=0;P<M;P++){let $=H.time+P*u,J=P%2===1;for(let R=D;R<T;R+=D){if(R>=T-B)break;let S=R/T,q=J?1-S:S;this.ticks.push({pos:this.get_position_at_progress(S),time:$+q*u,span_index:P,path_progress:S})}}this.ticks.sort((P,$)=>P.time-$.time)}calculate_path_length(){let I=0;for(let T=1;T<this.path.length;T++)I+=Y(U(this.path[T],this.path[T-1]));return I}update(I){super.update(I),this.calculate_ball_position(I),this.calculate_opacities(I)}calculate_ball_position(I){let{hit_object:T,span_duration:u}=this,H=300,D=300,M=2.4;if(I<T.time){this.ball_alpha=0,this.follow_alpha=0,this.follow_scale=1;return}if(I<=T.end_time){let $=I-T.time,J=$%(u*2),R=J<u?J/u:2-J/u;R=N(R,0,1),this.ball_position=this.get_position_at_progress(R),this.ball_alpha=1;let S=N($/300,0,1),q=O.OutQuint(S);this.follow_alpha=q,this.follow_scale=1+1.4*q;return}let V=I-T.end_time,B=N(V/300,0,1),P=O.OutQuint(B);this.ball_alpha=1-P,this.follow_alpha=1-P,this.follow_scale=2.4-1.4*P}get_position_at_progress(I){let T=I*this.path_length;return this.get_position_at_length(T)}get_position_at_length(I){let T=0;for(let u=1;u<this.path.length;u++){let H=Y(U(this.path[u],this.path[u-1]));if(T+H>=I){let D=(I-T)/H;return w(this.path[u-1],this.path[u],D)}T+=H}return this.path[this.path.length-1]}calculate_opacities(I){let{hit_object:T,config:u}=this,H=T.time-u.preempt,D=T.time;if(I<H)this.body_alpha=0;else if(I<D)this.body_alpha=N((I-H)/u.fade_in,0,1);else if(I<=T.end_time)this.body_alpha=1;else this.body_alpha=1-N((I-T.end_time)/z0,0,1);if(I<H)this.head_alpha=0,this.head_scale=1;else if(I<D)this.head_alpha=N((I-H)/u.fade_in,0,1),this.head_scale=1;else if(I<D+r0){let M=(I-D)/r0,V=O.OutCubic(M);this.head_alpha=1-V,this.head_scale=1+V*0.5}else this.head_alpha=0;if(K(u.mods,F.Hidden)){let V=D-u.preempt+u.preempt*0.4,B=T.end_time-V;if(I>V&&B>0){let J=1-N((I-V)/B,0,1);this.body_alpha*=J}let P=D-u.preempt*0.4,$=u.preempt*0.3;if(I>P){let J=1-N((I-P)/$,0,1);this.head_alpha*=J}}}render(I){if(this.body_alpha<=0&&this.head_alpha<=0&&this.ball_alpha<=0)return;this.render_body(I),this.render_head(),this.render_ball(I)}render_body_pass(I){this.render_body(I)}render_head_pass(I){this.render_head(),this.render_reverse_arrows(I),this.render_ball(I)}render_body(I){if(this.body_alpha<=0.01||this.path.length<2)return;let{backend:T,skin:u,config:H,path:D}=this,{radius:M}=H;if(!this.cached_texture){let V=A(u,this.combo_number,1),B=u.slider_border_color??"rgba(255,255,255,1)",P=H.scale??1;this.cached_texture=T.render_slider_to_image(D,M,B,V,P,u.slider_body_opacity,u.slider_border_opacity)}if(this.cached_texture&&this.cached_texture.min_x!==void 0&&this.cached_texture.min_y!==void 0){let V=H.scale??1;T.set_alpha(this.body_alpha),T.draw_image(this.cached_texture,this.cached_texture.min_x,this.cached_texture.min_y,this.cached_texture.width/V,this.cached_texture.height/V),T.set_alpha(1)}this.render_ticks(I)}render_ticks(I){if(this.ticks.length===0)return;let{backend:T,config:u,hit_object:H}=this,{radius:D}=u,M=D*0.12,V=H.time-u.preempt,B=N((I-V)/u.preempt,0,1),P=150,$=P*4;for(let J of this.ticks){if(I>J.time)continue;if(B<J.path_progress)continue;let R=V+J.path_progress*u.preempt,S=I-R;if(S<0)continue;let q=N(S/P,0,1);q*=this.body_alpha;let C=N(S/$,0,1),W=0.5+0.5*this.ease_out_elastic_half(C),Z=M*W;if(q>0.01)T.set_alpha(q),T.draw_circle(J.pos[0],J.pos[1],Z,"rgba(255,255,255,0.8)","transparent",0)}T.set_alpha(1)}ease_out_elastic_half(I){if(I<=0)return 0;if(I>=1)return 1;let T=0.3;return Math.pow(2,-10*I)*Math.sin((I-T/4)*(2*Math.PI)/T)+1}render_reverse_arrows(I){if(this.repeats.length===0)return;let{backend:T,config:u,hit_object:H,span_duration:D}=this,{radius:M}=u,V=M*0.6;for(let B of this.repeats){let P=u.preempt;if(B.repeat_index>0)P=D*2;else P+=H.time-(H.time-u.preempt);let $=B.time-P,J=B.repeat_index%2===0;if(I<$||I>B.time+z0)continue;let R=this.body_alpha*0.9;if(B.repeat_index===0){let Z=N((I-$)/150,0,1);R*=O.OutQuint(Z)}else if(I<$)R=0;if(I>B.time){let Z=Math.min(300,D);R*=1-N((I-B.time)/Z,0,1)}if(R<=0.01)continue;let S=this.path,q;if(J){let Z=S.length-1;q=S[0];for(let X=Z;X>=0;X--)if(Math.abs(S[X][0]-B.pos[0])>0.01||Math.abs(S[X][1]-B.pos[1])>0.01){q=S[X];break}}else{q=S[S.length-1];for(let Z=0;Z<S.length;Z++)if(Math.abs(S[Z][0]-B.pos[0])>0.01||Math.abs(S[Z][1]-B.pos[1])>0.01){q=S[Z];break}}let C=Math.atan2(q[1]-B.pos[1],q[0]-B.pos[0]),Q=1;if(I<B.time){let Z=H.time-u.preempt,X=(I-Z)%FI;if(X<G0)Q=1+(L0-1)*O.Out(X/G0);else{let m=(X-G0)/$I;Q=L0-(L0-1)*O.Out(N(m,0,1))}}else{let Z=Math.min(300,D),X=N((I-B.time)/Z,0,1);Q=1+0.5*O.Out(X)}let W=V*Q;T.save(),T.set_alpha(R),T.translate(B.pos[0],B.pos[1]),T.rotate(C),T.begin_path(),T.move_to(W*0.8,0),T.line_to(-W*0.4,-W*0.5),T.line_to(-W*0.4,W*0.5),T.close_path(),T.fill_path("rgba(255,255,255,0.9)"),T.restore()}}render_head(){if(this.head_alpha<=0.01)return;let{backend:I,skin:T,config:u}=this,{radius:H}=u,D=this.slider_data.pos,M=A(T,this.combo_number,1),V=H*(1-T.circle_border_width/2)*this.head_scale,B=H*T.circle_border_width*this.head_scale;I.set_alpha(this.head_alpha*T.hit_circle_opacity),I.draw_circle(D[0],D[1],V,M,"rgba(255,255,255,1)",B);let P=H*0.8*this.head_scale;I.draw_text(String(this.combo_count),D[0],D[1]+P*0.05,`600 ${P}px ${T.font_family}`,"rgba(255,255,255,1)","center","middle"),I.set_alpha(1)}render_ball(I){if(this.ball_alpha<=0.01&&this.follow_alpha<=0.01)return;let{backend:T,skin:u,config:H}=this,{radius:D}=H,M=this.ball_position,V=A(u,this.combo_number,0.9);if(this.follow_alpha>0.01){let B=D*this.follow_scale;T.set_alpha(this.follow_alpha*u.follow_circle_opacity),T.begin_path(),T.arc_to(M[0],M[1],B,0,Math.PI*2),T.stroke_path(u.follow_circle_color,u.follow_circle_width)}if(u.enable_slider_ball&&this.ball_alpha>0.01)T.set_alpha(this.ball_alpha*u.slider_ball_opacity),T.draw_circle(M[0],M[1],D*0.85,V,"rgba(255,255,255,0.9)",D*0.1);T.set_alpha(1)}}var A0=(I)=>384-I,JI=(I)=>1-Math.pow(1-I,3);class e extends v{radius=32;preempt=1200;fade_in=600;timing_points=[];drawables=[];drawable_config;constructor(I,T,u=0,H=G){super(I,T,u,H)}initialize(I){this.beatmap=I,this.objects=JSON.parse(JSON.stringify(I.objects)).sort((u,H)=>u.time-H.time),this.timing_points=this.process_timing_points([...I.timing_points]);let T=b0(I.cs,I.ar,0,0,this.mods);this.radius=N0(T.cs),this.preempt=b(T.ar),this.fade_in=q0(this.preempt),this.preprocess_objects(),this.create_drawables()}set_mods(I){if(this.mods=I,this.beatmap)this.initialize(this.beatmap)}process_timing_points(I){if(I.length===0)return I;I[0].time=0;let T=I[0].ms_per_beat;for(let u of I)if(u.ms_per_beat<0)u.ms_per_beat=T*(-u.ms_per_beat/100);else T=u.ms_per_beat;return I.reverse()}preprocess_objects(){let I=0,T=1;for(let u of this.objects){if(y0(u))I=(I+1)%this.skin.combo_colors.length,T=1;else T++;if(u.combo_number=I,u.combo_count=T,D0(u)){let H=u.data;if(K(this.mods,F.HardRock))H.pos=[H.pos[0],A0(H.pos[1])],H.control_points=H.control_points.map((V)=>[V[0],A0(V[1])]);H.computed_path=this.compute_slider_path(H);let D=this.get_timing_at(u.time),M=H.distance/(100*this.beatmap.sv)*D.ms_per_beat;H.duration=M,u.end_time=u.time+M*H.repetitions,u.end_pos=this.get_slider_end_position(H)}else if(g(u))u.end_pos=[256,192];else{let H=u.data;if(K(this.mods,F.HardRock))H.pos=[H.pos[0],A0(H.pos[1])];u.end_pos=H.pos}}}create_drawables(){this.drawables=[];let I=this.config.use_high_dpi?window.devicePixelRatio||1:1;this.drawable_config={backend:this.backend,skin:this.skin,preempt:this.preempt,fade_in:this.fade_in,radius:this.radius,scale:this.config.scale*I,mods:this.mods};for(let T of this.objects)if(x0(T))this.drawables.push(new a(T,this.drawable_config));else if(D0(T)){let u=T.data,H=u.computed_path||[],D=u.duration||0,M=this.calculate_path_length(H),V=D>0?M/D:0,B=this.get_base_beat_length_at(T.time),$=V*B/this.beatmap.tick_rate;this.drawables.push(new f(T,this.drawable_config,H,D,$))}}calculate_path_length(I){let T=0;for(let u=1;u<I.length;u++)T+=Y(U(I[u],I[u-1]));return T}get_base_beat_length_at(I){if(!this.beatmap||this.beatmap.timing_points.length===0)return 600;let T=this.beatmap.timing_points[0].ms_per_beat;for(let u of this.beatmap.timing_points){if(u.time>I)break;if(u.change)T=u.ms_per_beat}return T}render(I){let{backend:T,config:u}=this;this.render_background(),T.save(),T.translate(u.offset_x,u.offset_y),T.scale(u.scale,u.scale),this.render_playfield(),this.render_grid();let H=this.drawables.filter((D)=>D.is_alive(I));this.draw_follow_points(I);for(let D of this.objects)if(g(D)){let M=D.time-this.preempt;if(I>=M&&I<=D.end_time+200)this.draw_spinner(D,I)}H.sort((D,M)=>M.start_time-D.start_time);for(let D of H)D.update(I);for(let D of H)if(D instanceof f)D.render_body_pass(I);for(let D of H)if(D instanceof f)D.render_head_pass(I);else D.render(I);if(!K(this.mods,F.Hidden)&&this.skin.enable_approach_circle){for(let D of H)if(I<=D.start_time)this.draw_approach_circle(D,I)}T.restore()}draw_follow_points(I){if(K(this.mods,F.Hidden))return;for(let T=0;T<this.objects.length-1;T++){let u=this.objects[T],H=this.objects[T+1];if(g(u)||g(H))continue;if(u.combo_number!==H.combo_number)continue;if(I<u.end_time||I>H.time)continue;let D=u.end_pos,M=H.data.pos,V=M[0]-D[0],B=M[1]-D[1];if(Math.sqrt(V*V+B*B)<48)continue;let $=H.time-u.end_time,J=(I-u.end_time)/$,R=1;if(J<0.2)R=J/0.2;if(J>0.8)R=(1-J)/0.2;if(R<=0)continue;let S=N(J*1.5,0,1),q=E(D[0],M[0],Math.max(0,J-0.3)),C=E(D[1],M[1],Math.max(0,J-0.3)),Q=E(D[0],M[0],S),W=E(D[1],M[1],S);this.backend.set_alpha(R*0.6),this.backend.begin_path(),this.backend.move_to(q,C),this.backend.line_to(Q,W),this.backend.stroke_path("rgba(255,255,255,1)",this.skin.follow_point_width,"round","round"),this.backend.set_alpha(1)}}draw_approach_circle(I,T){let u=I.position,H=I.start_time-this.preempt,D=Math.min(this.fade_in*2,this.preempt),M=N((T-H)/D,0,1),V=this.ease_out_quint(M)*this.skin.approach_circle_opacity,P=4-3*N((T-H)/this.preempt,0,1),$=A(this.skin,I.combo_number,1);this.backend.save(),this.backend.set_alpha(V),this.backend.draw_circle(u[0],u[1],this.radius*P,"transparent",$,this.radius*this.skin.approach_circle_width),this.backend.restore()}ease_out_quint(I){return 1-Math.pow(1-I,5)}draw_spinner(I,T){let u=I.time-this.preempt,H=N((T-u)/this.fade_in,0,1);if(T>I.end_time)H=1-JI(N((T-I.end_time)/200,0,1));if(H<=0)return;let D=256,M=192,V=I.end_time-I.time,B=N((T-I.time)/V,0,1);this.backend.set_alpha(H);let P=this.skin.spinner_size*(1-B);if(P>5)this.backend.begin_path(),this.backend.arc_to(D,M,P,0,Math.PI*2),this.backend.stroke_path("rgba(255,255,255,0.6)",4);this.backend.draw_circle(D,M,this.skin.spinner_size,"rgba(0,0,0,0.2)"),this.backend.draw_circle(D,M,12,"white")}compute_slider_path(I){if(I.path_type==="L")return s(I.pos,I.control_points[0],I.distance);let T=[I.pos,...I.control_points];switch(I.path_type){case"P":return K0(T,I.distance);case"C":return U0(T);default:return this.flatten_multibezier(T,I.distance)}}flatten_multibezier(I,T){let u=[],H=[I[0]];for(let M=1;M<I.length;M++){let[V,B]=[I[M-1],I[M]];if(V[0]===B[0]&&V[1]===B[1]){if(H.length>1)u.push(H);H=[B]}else H.push(B)}if(H.length>1)u.push(H);let D=[];for(let M of u)D.push(..._(M));return this.clamp_path_to_distance(D,T)}clamp_path_to_distance(I,T){if(I.length<2)return I;let u=[I[0]],H=0;for(let D=1;D<I.length;D++){let M=Y(U(I[D],I[D-1]));if(H+M>=T){let V=T-H;u.push(w(I[D-1],I[D],V/M));break}H+=M,u.push(I[D])}return u}get_timing_at(I){for(let T of this.timing_points)if(T.time<=I)return T;return this.timing_points[this.timing_points.length-1]}get_slider_end_position(I){if(!I.computed_path||I.computed_path.length===0)return I.pos;return I.repetitions%2===0?I.pos:I.computed_path[I.computed_path.length-1]}}var n0=11485,c0=20;class I0 extends v{key_count=4;scroll_time=n0/c0;hd_coverage=0.25;fi_coverage=0.6;gradient_ratio=0.2;constructor(I,T,u=0,H=G){super(I,T,u,H);this.update_scroll_time()}initialize(I){this.beatmap=I,this.objects=[...I.objects],this.key_count=Math.floor(I.cs);for(let T of this.objects)if(M0(T))T.end_time=T.data.end_time}set_mods(I){this.mods=I,this.update_scroll_time()}update_scroll_time(){let I=C0(this.mods);this.scroll_time=n0/(c0*I)}time_to_y(I){let T=this.skin.mania_hit_position,u=I/this.scroll_time;return T-u*T}render(I){let{backend:T,config:u,skin:H,key_count:D}=this;this.render_background();let M=D*H.mania_lane_width,V=Math.floor((R0-M)/2),B=H.mania_hit_position;T.save(),T.translate(u.offset_x,u.offset_y),T.scale(u.scale,u.scale),this.render_playfield(M,S0,V),this.draw_lane_keys(I,V),this.draw_judgment_line(V),T.save(),T.begin_path(),T.rect(V,0,M,B),T.clip(),T.set_alpha(0.7),T.draw_rect(V,0,M,B,"#000000"),T.set_alpha(1);for(let P of this.objects){if(P.end_time<I)continue;if(M0(P))this.draw_hold_note(P,I,V);else this.draw_note(P,I,V)}if(K(this.mods,F.Hidden)||K(this.mods,F.FadeIn)){let P=K(this.mods,F.Hidden)?this.hd_coverage:this.fi_coverage,$=B*P,J=B*this.gradient_ratio;if(K(this.mods,F.Hidden)){let R=B-$,S=J/$,q=T.create_linear_gradient(V,R,V,B,[{offset:0,color:"rgba(0,0,0,0)"},{offset:S*0.4,color:"rgba(0,0,0,0.3)"},{offset:S*0.7,color:"rgba(0,0,0,0.75)"},{offset:S*0.9,color:"rgba(0,0,0,0.95)"},{offset:S,color:"rgba(0,0,0,1)"},{offset:1,color:"rgba(0,0,0,1)"}]);T.draw_rect_gradient(V,R,M,$,q)}else{let R=($-J)/$,S=T.create_linear_gradient(V,0,V,$,[{offset:0,color:"rgba(0,0,0,1)"},{offset:R,color:"rgba(0,0,0,1)"},{offset:R+(1-R)*0.1,color:"rgba(0,0,0,0.95)"},{offset:R+(1-R)*0.4,color:"rgba(0,0,0,0.75)"},{offset:R+(1-R)*0.7,color:"rgba(0,0,0,0.3)"},{offset:1,color:"rgba(0,0,0,0)"}]);T.draw_rect_gradient(V,0,M,$,S)}}T.restore(),T.restore()}get_lane(I){let T=I.data.pos,u=Math.floor(T[0]*this.key_count/512);if(K(this.mods,F.Mirror))u=this.key_count-1-u;return u}draw_note(I,T,u){let{backend:H,skin:D,key_count:M}=this,V=this.get_lane(I),B=D.mania_lane_width,P=D.mania_note_height,$=D.mania_lane_spacing,J=I.time-T,R=this.time_to_y(J);if(R<-P-64)return;let S=u+V*B,q=h(D,M,V);H.set_alpha(1),H.draw_rect(S+$,R-P,B-2*$,P,q)}draw_hold_note(I,T,u){let{backend:H,skin:D,key_count:M}=this,V=I.data,B=this.get_lane(I),P=D.mania_lane_width,$=D.mania_note_height,J=D.mania_lane_spacing,R=I.time-T,S=V.end_time-T,q=this.time_to_y(R),C=this.time_to_y(S),Q=u+B*P,W=h(D,M,B);if(C<-64&&q<-64)return;let Z=C,m=(R<0?D.mania_hit_position:q)-Z;if(m>0)H.set_alpha(0.9),H.draw_rect(Q+J,Z,P-2*J,m,W);if(R>=0)H.set_alpha(1),H.draw_rect(Q+J,q-$,P-2*J,$,W);H.set_alpha(1)}draw_judgment_line(I){let{backend:T,skin:u,key_count:H}=this,D=u.mania_lane_width,M=u.mania_hit_position;T.draw_rect(I,M-1,D*H,2,"#ffffff")}draw_lane_keys(I,T){let{backend:u,skin:H,key_count:D}=this,{mania_lane_width:M,mania_hit_position:V,mania_lane_spacing:B,mania_note_height:P}=H,$=P+5,J=new Set,R=50;for(let S of this.objects)if(I>=S.time-50&&I<=S.end_time+50)J.add(this.get_lane(S));for(let S=0;S<D;S++){let q=J.has(S),C=T+S*M,Q=h(H,D,S);if(u.set_alpha(0.3),u.draw_rect(C+B,V,M-2*B,$,Q),q)u.set_alpha(1),u.draw_rect(C+B,V,M-2*B,$,"#ff6666")}u.set_alpha(1)}}class T0{audio_context;audio_source=null;audio_buffer=null;gain_node;start_time=0;pause_time=0;speed=1;_is_playing=!1;_duration=0;_is_loaded=!1;constructor(I){this.audio_context=I,this.gain_node=this.audio_context.createGain(),this.gain_node.connect(this.audio_context.destination)}get is_playing(){return this._is_playing}get is_loaded(){return this._is_loaded}get duration(){return this._duration}get speed_multiplier(){return this.speed}get current_time(){if(!this._is_playing)return this.pause_time;return(this.audio_context.currentTime-this.start_time)*this.speed*1000}async load(I,T=0){this.stop();try{this.audio_buffer=await this.audio_context.decodeAudioData(I.slice(0)),this._duration=this.audio_buffer.duration*1000,this.speed=k(T),this._is_loaded=!0,this.pause_time=0}catch(u){throw console.error("Failed to decode audio data",u),u}}play(I){if(!this.audio_buffer){console.warn("[AudioController] Cannot play: not loaded");return}this.stop_source();let T=I!==void 0?I/1000:this.pause_time/1000,u=this.audio_buffer.duration,H=Math.max(0,Math.min(T,u));if(H>=u){this.pause_time=u*1000;return}this.audio_source=this.audio_context.createBufferSource(),this.audio_source.buffer=this.audio_buffer,this.audio_source.playbackRate.value=this.speed,this.audio_source.connect(this.gain_node),this.audio_source.onended=()=>{if(this._is_playing)this._is_playing=!1,this.pause_time=this._duration,this.audio_source=null},this.start_time=this.audio_context.currentTime-H/this.speed,this.audio_source.start(0,H),this._is_playing=!0}pause(){if(!this._is_playing)return;this.pause_time=this.current_time,this.stop_source(),this._is_playing=!1}seek(I){let T=Math.max(0,Math.min(I,this._duration));if(this._is_playing)this.stop_source(),this._is_playing=!1,this.pause_time=T,this.play();else this.pause_time=T}stop(){this.pause(),this.pause_time=0}get_host_time(I){return this.start_time+I/1000/this.speed}stop_source(){if(this.audio_source){try{this.audio_source.onended=null,this.audio_source.stop(),this.audio_source.disconnect()}catch{}this.audio_source=null}}set_volume(I){if(this.gain_node)this.gain_node.gain.value=Math.max(0,Math.min(1,I))}set_speed(I){if(this._is_playing){let T=this.current_time;this.speed=I,this.start_time=this.audio_context.currentTime-T/1000/I}else this.speed=I;if(this.audio_source)this.audio_source.playbackRate.value=I}dispose(){this.stop(),this.audio_buffer=null,this._is_loaded=!1,this.gain_node.disconnect()}}class u0{video=null;object_url=null;_offset=0;speed=1;get element(){return this.video}get offset(){return this._offset}async load(I,T=0,u=1){this.dispose(),this._offset=T,this.speed=u,this.video=document.createElement("video"),this.video.muted=!0,this.video.loop=!1,this.video.playsInline=!0,this.object_url=URL.createObjectURL(I),this.video.src=this.object_url,await new Promise((H,D)=>{if(!this.video)return D(Error("No video element"));this.video.onloadeddata=()=>H(),this.video.onerror=()=>D(Error("Failed to load video"))}),this.video.playbackRate=u}sync(I){if(!this.video)return;let T=(I-this._offset)/1000;if(T<0){if(!this.video.paused)this.video.pause();return}if(Math.abs(this.video.currentTime-T)>0.1)this.video.currentTime=T}play(){if(this.video&&this.video.paused)this.video.play().catch(()=>{console.log("failed to play video")})}pause(){if(this.video&&!this.video.paused)this.video.pause()}seek(I){if(!this.video)return;let T=Math.max(0,(I-this._offset)/1000);this.video.currentTime=T}set_speed(I){if(this.speed=I,this.video)this.video.playbackRate=I}dispose(){if(this.video)this.video.pause(),this.video.src="",this.video=null;if(this.object_url)URL.revokeObjectURL(this.object_url),this.object_url=null}}class E0{context;gain_node;samples=new Map;volume=1;constructor(I){this.context=I,this.gain_node=I.createGain(),this.gain_node.connect(I.destination)}set_volume(I){this.volume=Math.max(0,Math.min(1,I)),this.gain_node.gain.value=this.volume}async load_samples(I){this.samples.clear();let T=[];for(let[u,H]of I)if(u.endsWith(".wav")||u.endsWith(".mp3")||u.endsWith(".ogg"))T.push(this.context.decodeAudioData(H.slice(0)).then((D)=>{let M=u.toLowerCase().replace(/\.(wav|mp3|ogg)$/,"");this.samples.set(M,D)}).catch((D)=>{console.warn(`[HitsoundController] Failed to decode ${u}:`,D)}));await Promise.all(T)}play(I,T,u,H,D=100,M,V=0){let B=this.get_set_name(I),P=this.get_set_name(T);if(M){let $=M.toLowerCase().replace(/\.(wav|mp3|ogg)$/,"");if(this.play_buffer($,D,V))return}if(this.play_sound(B,"hitnormal",H,D,V),u&n.Whistle)this.play_sound(P,"hitwhistle",H,D,V);if(u&n.Finish)this.play_sound(P,"hitfinish",H,D,V);if(u&n.Clap)this.play_sound(P,"hitclap",H,D,V)}play_sound(I,T,u,H,D){let M=!1;if(u>1)M=this.play_buffer(`${I}-${T}${u}`,H,D);if(!M)this.play_buffer(`${I}-${T}`,H,D)}play_buffer(I,T,u){let H=this.samples.get(I);if(!H)return!1;let D=this.context.createBufferSource();D.buffer=H;let M=this.context.createGain();return M.gain.value=T/100,D.connect(M),M.connect(this.gain_node),D.start(u),!0}get_set_name(I){switch(I){case 3:return"drum";case 2:return"soft";default:return"normal"}}dispose(){this.samples.clear(),this.gain_node.disconnect()}}class p0{backend;renderer=null;audio_context;audio;hitsounds;video=null;resources=null;animation_frame=null;skin;mods;renderer_config;start_offset;volume;listeners=new Map;_raw_osu_content="";_is_loaded=!1;next_hit_object_index=0;resize_observer=null;key_handler=null;options;enable_fps_counter=!1;fps_frame_count=0;fps_last_update=0;current_fps=0;constructor(I){this.options=I,this.backend=I.backend??new o,this.skin=i(I.skin),this.mods=I.mods??0,this.renderer_config={...G,...I.renderer_config},this.calculate_layout(I.canvas.width,I.canvas.height,I.playfield_scale),this.start_offset=I.start_time??-1,this.volume=I.volume??0.5,this.backend.initialize(I.canvas,this.renderer_config.use_high_dpi);let T=window.AudioContext||window.webkitAudioContext;if(this.audio_context=new T,this.audio=new T0(this.audio_context),this.hitsounds=new E0(this.audio_context),this.audio.set_volume(this.volume),this.hitsounds.set_volume(this.volume),I.auto_resize)this.setup_auto_resize();this.enable_fps_counter=I.enable_fps_counter??!1,this.fps_last_update=performance.now()}async load_osz(I,T){try{let H=await new y().load_osz(I,{difficulty:T});return this.resources=H,this.setup()}catch(u){let H=u instanceof Error?u.message:String(u);return this.emit("error","INVALID_BEATMAP",H),L("INVALID_BEATMAP",H)}}async load_files(I,T){try{let u=new y;this.resources=await u.load_from_files(I,{difficulty:T});for(let[H,D]of I)if(H.endsWith(".osu")){this._raw_osu_content=typeof D==="string"?D:new TextDecoder().decode(D);break}return this.setup()}catch(u){let H=u instanceof Error?u.message:String(u);return this.emit("error","INVALID_BEATMAP",H),L("INVALID_BEATMAP",H)}}async load_hitsounds(I){try{await this.hitsounds.load_samples(I)}catch(T){console.error("[BeatmapPlayer] Failed to load hitsounds:",T)}}async load_beatmap(I,T,u,H,D){return this.resources={beatmap:I,available_difficulties:[],files:new Map,audio:T,background:u,video:H,video_offset:D},this.setup()}async load_osu_content(I,T){try{let H=await J0().parse(I);return this._raw_osu_content=I,this.load_beatmap(H,T)}catch(u){let H=u instanceof Error?u.message:String(u);return this.emit("error","INVALID_BEATMAP",H),L("INVALID_BEATMAP",H)}}async setup(){if(!this.resources)return L("NOT_LOADED","No resources loaded");let{beatmap:I,audio:T,video:u,video_offset:H}=this.resources,D=k(this.mods);if(T)try{await this.audio.load(T,this.mods)}catch(M){let V=M instanceof Error?M.message:String(M);return this.emit("error","AUDIO_DECODE_ERROR",V),L("AUDIO_DECODE_ERROR",V)}if(u)this.video=new u0,await this.video.load(u,H??0,D);try{this.renderer=this.create_renderer(I),this.renderer.initialize(I)}catch(M){let V=M instanceof Error?M.message:String(M);return this.emit("error","UNSUPPORTED_MODE",V),L("UNSUPPORTED_MODE",V)}if(this.start_offset<0&&this._raw_osu_content){let V=await J0().extract_preview_time(this._raw_osu_content);this.start_offset=V>0?V:this.get_last_object_time()*0.42}if(this.start_offset<0)this.start_offset=0;if(this.update_hit_index(this.start_offset),this.resources?.background)try{let M=new Image;M.src=URL.createObjectURL(this.resources.background),await M.decode(),this.renderer.set_background({source:M,width:M.width,height:M.height}),this._is_loaded=!0,requestAnimationFrame(()=>this.render_frame(this.start_offset))}catch(M){console.warn("[BeatmapPlayer] Failed to load background",M)}return this._is_loaded=!0,this.emit("loaded",I,this.resources),requestAnimationFrame(()=>this.render_frame(this.start_offset)),w0(this.resources)}create_renderer(I){switch(I.mode){case 0:return new e(this.backend,this.skin,this.mods,this.renderer_config);case 3:return new I0(this.backend,this.skin,this.mods,this.renderer_config);case 1:case 2:default:throw Error(`Unsupported game mode: ${r[I.mode]??I.mode}`)}}get_last_object_time(){if(!this.resources?.beatmap.objects.length)return 0;let I=this.resources.beatmap.objects;return I[I.length-1].end_time}async play(){if(!this.renderer||!this._is_loaded){console.warn("[BeatmapPlayer] Cannot play: not loaded");return}if(this.audio.is_playing)return;if(this.audio_context.state==="suspended")await this.audio_context.resume();this.audio.play(this.start_offset),this.video?.play(),this.start_render_loop(),this.emit("play"),this.emit("statechange",!0)}pause(){if(!this.audio.is_playing)return;this.start_offset=this.audio.current_time,this.audio.pause(),this.video?.pause(),this.stop_render_loop(),this.emit("pause"),this.emit("statechange",!1)}set_mods(I){this.mods=I;let T=k(I);if(this.renderer?.set_mods(I),this.audio.set_speed(T),this.video?.set_speed(T),this._is_loaded)requestAnimationFrame(()=>this.render_frame(this.current_time))}seek(I){this.start_offset=Math.max(0,Math.min(I,this.duration)),this.update_hit_index(this.start_offset),this.audio.seek(this.start_offset),this.video?.seek(this.start_offset),this.emit("seek",this.start_offset),this.render_frame(this.start_offset)}async set_difficulty(I){if(!this.resources)return L("NOT_LOADED","No beatmap resources loaded");let T=this.is_playing;this.stop();try{let H=await new y().load_from_files(this.resources.files,{difficulty:I});this.resources=H;let D=this.resources.available_difficulties.find((V)=>V.version===this.resources.beatmap.version)?.filename;if(D){let V=this.resources.files.get(D);if(V)this._raw_osu_content=typeof V==="string"?V:new TextDecoder().decode(V)}let M=await this.setup();if(M.success&&T)this.play();return M}catch(u){let H=u instanceof Error?u.message:String(u);return this.emit("error","INVALID_BEATMAP",H),L("INVALID_BEATMAP",H)}}update_hit_index(I){if(!this.resources?.beatmap)return;let T=this.resources.beatmap.objects;if(this.next_hit_object_index>0&&T[this.next_hit_object_index-1].time>I)this.next_hit_object_index=0;while(this.next_hit_object_index<T.length&&T[this.next_hit_object_index].time<I)this.next_hit_object_index++}stop(){this.pause(),this.start_offset=0,this.audio.seek(0),this.update_hit_index(0),this.render_frame(0)}dispose(){if(this.stop(),this.backend.dispose(),this.audio.dispose(),this.hitsounds.dispose(),this.video?.dispose(),this.renderer?.dispose(),this.listeners.clear(),this.resize_observer)this.resize_observer.disconnect(),this.resize_observer=null;if(this.key_handler)window.removeEventListener("keydown",this.key_handler),this.key_handler=null;if(this.audio_context&&this.audio_context.state!=="closed")this.audio_context.close().catch(()=>{});this.renderer=null,this.resources=null,this._is_loaded=!1,this.listeners.clear()}get current_time(){return this.audio.current_time}get duration(){return this.audio.duration||this.get_last_object_time()}get is_playing(){return this.audio.is_playing}get is_loaded(){return this._is_loaded}get mode(){if(!this.resources)return"standard";switch(this.resources.beatmap.mode){case 1:return"taiko";case 2:return"catch";case 3:return"mania";default:return"standard"}}get beatmap(){return this.resources?.beatmap??null}get available_difficulties(){return this.resources?.available_difficulties??[]}get background(){return this.resources?.background}get config(){return this.renderer_config}resize(I,T,u){if(this.backend.resize(I,T),this.calculate_layout(I,T,u),this._is_loaded)requestAnimationFrame(()=>this.render_frame(this.current_time))}update_config(I){if(this.renderer_config={...this.renderer_config,...I},this.renderer?.update_config(this.renderer_config),this._is_loaded)requestAnimationFrame(()=>this.render_frame(this.current_time))}set_skin(I){if(this.skin=i(I),this._is_loaded&&this.resources?.beatmap)this.renderer=this.create_renderer(this.resources.beatmap),this.renderer.initialize(this.resources.beatmap),requestAnimationFrame(()=>this.render_frame(this.current_time))}setup_auto_resize(){this.resize_observer=new ResizeObserver(()=>{let T=this.options.canvas.parentElement;if(T){let u=T.getBoundingClientRect();this.resize(u.width,u.height,this.options.playfield_scale)}}),this.resize_observer.observe(this.options.canvas.parentElement||this.options.canvas)}toggle_pause(){if(!this._is_loaded)return;this.is_playing?this.pause():this.play()}toggle_grid(){if(this.renderer_config.grid_level===0)this.renderer_config.grid_level=32;else this.renderer_config.grid_level=0;this.render_frame(this.current_time)}calculate_layout(I,T,u){let M=0.9;if(typeof u==="number")M=u;let V=I*M/512,B=T*M/384,P=Math.min(V,B);if(this.renderer_config.scale=P,this.renderer_config.offset_x=Math.floor((I-512*P)/2),this.renderer_config.offset_y=Math.floor((T-384*P)/2),this.renderer)this.renderer.update_config(this.renderer_config)}set_volume(I){this.volume=I,this.audio.set_volume(I),this.hitsounds.set_volume(I)}on(I,T){if(!this.listeners.has(I))this.listeners.set(I,new Set);this.listeners.get(I).add(T)}off(I,T){this.listeners.get(I)?.delete(T)}emit(I,...T){let u=this.listeners.get(I);if(u)for(let H of u)H(...T)}last_timestamp=0;smooth_time=0;start_render_loop(){if(this.animation_frame!==null)return;this.last_timestamp=performance.now(),this.smooth_time=this.audio.current_time;let I=(T)=>{if(!this.audio.is_playing){this.animation_frame=null;return}let u=T-this.last_timestamp;this.last_timestamp=T,this.smooth_time+=u*this.audio.speed_multiplier;let H=this.audio.current_time;if(Math.abs(this.smooth_time-H)>30)this.smooth_time=H;else this.smooth_time+=(H-this.smooth_time)*0.1;let M=this.smooth_time;if(this.schedule_hitsounds(),this.render_frame(M),this.video?.sync(M),this.emit("timeupdate",M,this.duration),M>=this.duration){this.emit("ended"),this.stop_render_loop(),this.emit("statechange",!1);return}this.animation_frame=requestAnimationFrame(I)};this.animation_frame=requestAnimationFrame(I)}schedule_hitsounds(){if(!this.resources?.beatmap||!this.audio.is_playing)return;let I=this.resources.beatmap.objects,T=this.audio.current_time,H=T+100;while(this.next_hit_object_index<I.length&&I[this.next_hit_object_index].time<=H){let D=I[this.next_hit_object_index];if(D.time>=T-20)this.play_hitsound(D);this.next_hit_object_index++}}play_hitsound(I){let T=this.get_timing_point(I.time),u=T.volume,H=T.sample_set,D=T.sample_set,M=T.sample_index,V=void 0;if(I.hit_sample){let P=I.hit_sample;if(P.normal_set!==0){if(H=P.normal_set,P.addition_set===0)D=H}if(P.addition_set!==0)D=P.addition_set;if(P.index!==0)M=P.index;if(P.volume!==0)u=P.volume;V=P.filename}if(H===0)H=1;if(D===0)D=H;let B=this.audio.get_host_time(I.time);this.hitsounds.play(H,D,I.hit_sound,M,u,V,B)}get_timing_point(I){let T=this.resources?.beatmap.timing_points??[];for(let u=T.length-1;u>=0;u--)if(T[u].time<=I)return T[u];return T[0]}stop_render_loop(){if(this.animation_frame!==null)cancelAnimationFrame(this.animation_frame),this.animation_frame=null}render_frame(I){if(this.backend.clear(),this.renderer?.render(I),this.enable_fps_counter){this.fps_frame_count++;let T=performance.now(),u=T-this.fps_last_update;if(u>=1000)this.current_fps=Math.round(this.fps_frame_count*1000/u),this.fps_frame_count=0,this.fps_last_update=T;this.backend.draw_text(`${this.current_fps} FPS`,10,20,"14px monospace","rgba(255,255,255,0.8)","left","top")}}set_fps_counter(I){this.enable_fps_counter=I}}export{U as vec2_sub,tI as vec2_normalize,m0 as vec2_mul,w as vec2_lerp,sI as vec2_len_sq,Y as vec2_len,_I as vec2_dot,HI as vec2_div,iI as vec2_dist,h0 as vec2_add,SI as unwrap,WI as toggle_mod,w0 as ok,CI as mods_to_string,XI as mods_from_string,i as merge_skin,E as lerp,g as is_spinner,D0 as is_slider,QI as is_ok,y0 as is_new_combo,M0 as is_hold,qI as is_err,x0 as is_circle,Q0 as inverse_difficulty_range,K as has_mod,k as get_speed_multiplier,C0 as get_rate_multiplier,h as get_mania_lane_color,A as get_combo_color,KI as get_available_mods,b0 as get_adjusted_difficulty,K0 as flatten_perfect,s as flatten_linear,U0 as flatten_catmull,_ as flatten_bezier,$0 as extract_video_info,V0 as extract_preview_time,B0 as extract_background_filename,P0 as extract_audio_filename,L as err,k0 as difficulty_range,N as clamp,N0 as calculate_radius,b as calculate_preempt,q0 as calculate_fade_in,uI as apply_rate_to_ar,TI as apply_mods_to_difficulty,u0 as VideoController,e as StandardRenderer,l0 as SpeedChangingMods,H0 as SampleSet,d as PREEMPT_RANGE,d0 as PREEMPT_MIN,R0 as PLAYFIELD_WIDTH,S0 as PLAYFIELD_HEIGHT,y as OszLoader,F as Mods,i0 as ModNightcore,II as ModHidden,Z0 as ModHardRock,t0 as ModHalfTime,X0 as ModEasy,s0 as ModDoubleTime,I0 as ManiaRenderer,n as HitSoundType,z as HitObjectType,e0 as HD_FADE_OUT_MULTIPLIER,a0 as HD_FADE_IN_MULTIPLIER,g0 as GridLevel,r as GameMode,v0 as ErrorCode,ZI as DifficultyChangingMods,O0 as DEFAULT_SKIN,G as DEFAULT_RENDERER_CONFIG,o as CanvasBackend,p0 as BeatmapPlayer,c as BeatmapParser,v as BaseRenderer,T0 as AudioController};
4
4
 
5
- //# debugId=1428400E3EA47B7A64756E2164756E21
5
+ //# debugId=8D68191BE9969DD864756E2164756E21