@rel-packages/osu-beatmap-preview 0.8.5 → 0.9.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.
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- var hr;((s)=>{s[s.Standard=0]="Standard";s[s.Taiko=1]="Taiko";s[s.Catch=2]="Catch";s[s.Mania=3]="Mania"})(hr||={});var mr;((s)=>{s[s.Auto=0]="Auto";s[s.Normal=1]="Normal";s[s.Soft=2]="Soft";s[s.Drum=3]="Drum"})(mr||={});var P={Circle:1,Slider:2,NewCombo:4,Spinner:8,ComboSkip:112,Hold:128},K={Normal:1,Whistle:2,Finish:4,Clap:8},Or=(r)=>(r.type&P.Circle)!==0,fr=(r)=>(r.type&P.Slider)!==0,$=(r)=>(r.type&P.Spinner)!==0,Ar=(r)=>(r.type&P.Hold)!==0,Nr=(r)=>(r.type&P.NewCombo)!==0;var $r;((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"})($r||={});var Lr=(r)=>({success:!0,data:r}),w=(r,e)=>({success:!1,code:r,reason:e}),qe=(r)=>{if(r.success)return r.data;throw Error(`[${r.code}] ${r.reason}`)},Ze=(r)=>{return r.success},Xe=(r)=>{return!r.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},ie=f.DoubleTime|f.HalfTime|f.Nightcore,We=f.HardRock|f.Easy|ie,Ye=(r)=>{let e=0,t=r.toLowerCase(),n={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 s=0;s<t.length-1;s+=2){let o=t.slice(s,s+2);if(n[o])e|=n[o]}return e},ge=(r)=>{let e=[];if(r&f.NoFail)e.push("NF");if(r&f.Easy)e.push("EZ");if(r&f.Hidden)e.push("HD");if(r&f.HardRock)e.push("HR");if(r&f.SuddenDeath)e.push("SD");if(r&f.DoubleTime)e.push("DT");if(r&f.HalfTime)e.push("HT");if(r&f.Nightcore)e.push("NC");if(r&f.Flashlight)e.push("FL");if(r&f.SpunOut)e.push("SO");if(r&f.FadeIn)e.push("FI");if(r&f.Mirror)e.push("MR");let t=e.indexOf("DT"),n=e.indexOf("NC");if(t>=0&&n>=0)e.splice(t,1);return e.join("")},J=(r)=>{if(r&(f.DoubleTime|f.Nightcore))return 1.5;if(r&f.HalfTime)return 0.75;return 1},pe=[f.HardRock|f.Easy,f.DoubleTime|f.HalfTime|f.Nightcore,f.Hidden|f.FadeIn],Ke=(r,e)=>{if(r&e)return r&~e;let t=r;for(let n of pe)if(e&n)t&=~n;return t|e},R=(r,e)=>(r&e)!==0,Ge=(r)=>{let e=[{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(r){case"standard":return[...e,{name:"Hard Rock",acronym:"HR",value:f.HardRock}];case"mania":return[...e,{name:"Hard Rock",acronym:"HR",value:f.HardRock},{name:"Fade In",acronym:"FI",value:f.FadeIn}];case"taiko":case"catch":return[...e,{name:"Hard Rock",acronym:"HR",value:f.HardRock}];default:return e}};import Qr from"jszip";import{init_wasm as Ur,parse as Er}from"@rel-packages/osu-beatmap-parser/browser";class L{async load_osz(r,e){await Ur();let t=await Qr.loadAsync(r),n=new Map;for(let[s,o]of Object.entries(t.files))if(!o.dir)n.set(s,await o.async("arraybuffer"));return this.load_from_files(n,e)}async load_from_files(r,e){await Ur();let t=[...r.keys()].filter((T)=>T.toLowerCase().endsWith(".osu"));if(t.length===0)throw Error("No .osu files found in beatmap");let n=await Promise.all(t.map(async(T)=>{let H=r.get(T),D=this.to_bytes(H),M=await Er(D);return{filename:T,beatmap:M}})),s=this.select_difficulty(t,n,e?.difficulty),o=r.get(s),u=this.to_bytes(o),i=await Er(u),p=i.General.AudioFilename||null,a=i.Events.background?.filename||null,l=i.Events.video?.filename||null,h=i.Events.video?.startTime??0,m=new Map;for(let[T,H]of r)if(H instanceof ArrayBuffer)m.set(T,H);else m.set(T,new TextEncoder().encode(H).buffer);let d;if(p)d=this.find_file(m,p);let I;if(a){let T=this.find_file(m,a);if(T)I=new Blob([T])}let c;if(l){let T=this.find_file(m,l);if(T)c=new Blob([T])}return{beatmap:i,available_difficulties:n,files:m,audio:d,background:I,video:c,audio_filename:p??void 0,background_filename:a??void 0,video_filename:l??void 0,video_offset:l?h:void 0}}async list_difficulties(r){let e=await Qr.loadAsync(r),t=[];for(let s of Object.keys(e.files))if(s.toLowerCase().endsWith(".osu"))t.push(s);let n=[];for(let s of t){let u=(await e.files[s].async("string")).match(/Version:\s*(.+)/);n.push(u?u[1].trim():s)}return n}select_difficulty(r,e,t){if(t===void 0)return r[0];if(typeof t==="number"){if(t<0||t>=r.length)throw Error(`Difficulty index ${t} out of range (0-${r.length-1})`);return r[t]}let n=e.find((u)=>u.beatmap.Metadata.Version===t);if(n)return n.filename;let s=t.toLowerCase(),o=e.find((u)=>u.filename.toLowerCase().includes(s)||u.beatmap.Metadata.Version.toLowerCase().includes(s));if(o)return o.filename;throw Error(`Difficulty "${t}" not found`)}find_file(r,e){if(r.has(e))return r.get(e);let t=e.toLowerCase();for(let[n,s]of r)if(n.toLowerCase()===t)return s;return}to_bytes(r){if(r instanceof ArrayBuffer)return new Uint8Array(r);return new TextEncoder().encode(r)}}import{init_wasm as ee,parse as $e}from"@rel-packages/osu-beatmap-parser/browser";var lr=512,cr=384,Jr;((o)=>{o[o.None=0]="None";o[o.Large=32]="Large";o[o.Medium=16]="Medium";o[o.Small=8]="Small";o[o.Tiny=4]="Tiny"})(Jr||={});var S={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 Q{backend;skin;config;mods;beatmap;objects=[];background_image=null;constructor(r,e,t=0,n=S){this.backend=r,this.skin=e,this.mods=t,this.config={...S,...n}}set_background(r){this.background_image=r}update_config(r){this.config={...this.config,...r}}precompute(){}dispose(){this.objects=[]}render_playfield(r,e,t,n){if(!this.config.show_playfield)return;let{backend:s,config:o}=this,u=r??512,i=e??384,p=t??0,a=n??0;s.save(),s.set_alpha(o.playfield_opacity),s.begin_path(),s.move_to(p,a),s.line_to(p+u,a),s.line_to(p+u,a+i),s.line_to(p,a+i),s.line_to(p,a),s.stroke_path(o.playfield_color,2),s.restore()}render_grid(){if(this.config.grid_level===0)return;let{backend:r,config:e}=this,t=e.grid_level;r.save(),r.set_alpha(e.grid_opacity);for(let n=0;n<=512;n+=t)r.begin_path(),r.move_to(n,0),r.line_to(n,384),r.stroke_path(e.grid_color,n%(t*4)===0?1:0.5);for(let n=0;n<=384;n+=t)r.begin_path(),r.move_to(0,n),r.line_to(512,n),r.stroke_path(e.grid_color,n%(t*4)===0?1:0.5);r.restore()}render_background(){if(!this.background_image)return;let{backend:r}=this;r.save(),r.set_alpha(0.3);let{width:e,height:t}=r,{width:n,height:s}=this.background_image;if(n>0&&s>0){let o=Math.max(e/n,t/s),u=n*o,i=s*o,p=(e-u)/2,a=(t-i)/2;r.draw_image(this.background_image,p,a,u,i)}else r.draw_image(this.background_image,0,0,e,t);r.restore()}get_visible_objects(r,e,t){let n=[];for(let s of this.objects){let o=s.time-e,u=s.end_time+t;if(r>=o&&r<=u)n.push(s)}return n}}class G{ctx;_width=0;_height=0;_dpr=1;is_initialized=!1;get width(){return this._width}get height(){return this._height}initialize(r,e=!0){this._dpr=e?window.devicePixelRatio||1:1;let t=r.clientWidth||r.width,n=r.clientHeight||r.height;this.apply_canvas_size(r,t,n);let s=r.getContext("2d",{alpha:!0,desynchronized:!0});if(!s)throw Error("Failed to get 2D context");this.ctx=s,this._width=t,this._height=n,this.configure_context(),this.is_initialized=!0}clear(){if(!this.is_initialized)return;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(){}begin_frame(){}end_frame(){}resize(r,e){if(!this.is_initialized)return;this._width=r,this._height=e,this._dpr=window.devicePixelRatio||1;let t=this.ctx.canvas;this.apply_canvas_size(t,r,e),this.reset_transform(),this.configure_context()}draw_circle(r,e,t,n,s,o){let u=this.ctx;if(u.beginPath(),u.arc(r,e,t,0,Math.PI*2),n&&n!=="transparent")u.fillStyle=n,u.fill();if(s&&o&&o>0)u.strokeStyle=s,u.lineWidth=o,u.stroke()}draw_arc(r,e,t,n,s,o,u,i=!1){let p=this.ctx;p.beginPath(),p.arc(r,e,t,n,s,i),p.strokeStyle=o,p.lineWidth=u,p.stroke()}draw_rect(r,e,t,n,s){this.ctx.fillStyle=s,this.ctx.fillRect(r,e,t,n)}draw_rect_gradient(r,e,t,n,s){this.ctx.fillStyle=s,this.ctx.fillRect(r,e,t,n)}create_linear_gradient(r,e,t,n,s){let o=this.ctx.createLinearGradient(r,e,t,n);for(let u of s)o.addColorStop(u.offset,u.color);return o}draw_text(r,e,t,n,s,o="left",u="alphabetic"){let i=this.ctx;i.font=n,i.fillStyle=s,i.textAlign=o,i.textBaseline=u,i.fillText(r,e,t)}measure_text(r,e){let t=this.ctx,n=t.font;t.font=e;let s=t.measureText(r);return t.font=n,s}begin_path(){this.ctx.beginPath()}move_to(r,e){this.ctx.moveTo(r,e)}line_to(r,e){this.ctx.lineTo(r,e)}draw_line(r,e,t,n,s,o,u="butt",i="miter"){this.ctx.beginPath(),this.ctx.moveTo(r,e),this.ctx.lineTo(t,n),this.ctx.strokeStyle=s,this.ctx.lineWidth=o,this.ctx.lineCap=u,this.ctx.lineJoin=i,this.ctx.stroke()}bezier_curve_to(r,e,t,n,s,o){this.ctx.bezierCurveTo(r,e,t,n,s,o)}quadratic_curve_to(r,e,t,n){this.ctx.quadraticCurveTo(r,e,t,n)}arc_to(r,e,t,n,s,o){this.ctx.arc(r,e,t,n,s,o)}rect(r,e,t,n){this.ctx.rect(r,e,t,n)}clip(){this.ctx.clip()}stroke_path(r,e,t="butt",n="miter"){let s=this.ctx;s.strokeStyle=r,s.lineWidth=e,s.lineCap=t,s.lineJoin=n,s.stroke()}fill_path(r){this.ctx.fillStyle=r,this.ctx.fill()}close_path(){this.ctx.closePath()}save(){this.ctx.save()}restore(){this.ctx.restore()}translate(r,e){this.ctx.translate(r,e)}scale(r,e){this.ctx.scale(r,e)}rotate(r){this.ctx.rotate(r)}set_alpha(r){this.ctx.globalAlpha=r}set_shadow(r,e){this.ctx.shadowColor=r,this.ctx.shadowBlur=e}set_composite_operation(r){this.ctx.globalCompositeOperation=r}set_blend_mode(r){let e={normal:"source-over",lighter:"lighter",multiply:"multiply",screen:"screen"};this.ctx.globalCompositeOperation=e[r]??"source-over"}draw_image(r,e,t,n,s){if(n!==void 0&&s!==void 0)this.ctx.drawImage(r.source,e,t,n,s);else this.ctx.drawImage(r.source,e,t)}draw_image_part(r,e,t,n,s,o,u,i,p){this.ctx.drawImage(r.source,e,t,n,s,o,u,i,p)}render_slider_to_image(r,e,t,n,s,o=1,u=1){let i=1/0,p=1/0,a=-1/0,l=-1/0;for(let D of r){if(D[0]<i)i=D[0];if(D[0]>a)a=D[0];if(D[1]<p)p=D[1];if(D[1]>l)l=D[1]}let h=e+2;i-=h,p-=h,a+=h,l+=h;let m=Math.ceil((a-i)*s),d=Math.ceil((l-p)*s);if(m<=0||d<=0)return null;let I=document.createElement("canvas");I.width=m,I.height=d;let c=I.getContext("2d");if(!c)return null;c.save(),c.scale(s,s),c.translate(-i,-p);let T=()=>{if(c.beginPath(),r.length>0){c.moveTo(r[0][0],r[0][1]);for(let D=1;D<r.length;D++)c.lineTo(r[D][0],r[D][1])}};c.lineCap="round",c.lineJoin="round",c.globalAlpha=u,c.strokeStyle=t,c.lineWidth=e*2,T(),c.stroke();let H=e*0.872;if(o<1)c.globalCompositeOperation="destination-out",c.globalAlpha=1,c.lineWidth=H*2,T(),c.stroke(),c.globalCompositeOperation="source-over";return c.globalAlpha=o,c.strokeStyle=n,c.lineWidth=H*2,T(),c.stroke(),c.restore(),{source:I,width:m,height:d,min_x:i,min_y:p}}apply_canvas_size(r,e,t){r.width=e*this._dpr,r.height=t*this._dpr,r.style.width=`${e}px`,r.style.height=`${t}px`}configure_context(){this.ctx.scale(this._dpr,this._dpr),this.ctx.imageSmoothingEnabled=!0,this.ctx.imageSmoothingQuality="high"}reset_transform(){if(this.ctx.resetTransform)this.ctx.resetTransform();else this.ctx.setTransform(1,0,0,1,0,0)}}var dr={min:1800,mid:1200,max:450};var ae=(r,e)=>{if(r>5)return e.mid+(e.max-e.mid)*(r-5)/5;if(r<5)return e.mid+(e.mid-e.min)*(r-5)/5;return e.mid},qr=(r,e)=>{if(Math.sign(r-e.mid)===Math.sign(e.max-e.mid))return(r-e.mid)/(e.max-e.mid)*5+5;return(r-e.mid)/(e.mid-e.min)*5+5},x=(r)=>ae(r,dr),Zr=(r)=>400*Math.min(1,r/450),he=(r)=>{return(1-0.7*((r-5)/5))/2},Xr=(r)=>he(r)*64;var Ir={name:"Hard Rock",acronym:"HR",apply_to_difficulty(r){r.cs=Math.min(r.cs*1.3,10),r.ar=Math.min(r.ar*1.4,10),r.od=Math.min(r.od*1.4,10),r.hp=Math.min(r.hp*1.4,10)}};var Tr={name:"Easy",acronym:"EZ",apply_to_difficulty(r){r.cs*=0.5,r.ar*=0.5,r.od*=0.5,r.hp*=0.5}};var me={name:"Double Time",acronym:"DT",get_rate_multiplier:()=>1.5},fe={name:"Nightcore",acronym:"NC",get_rate_multiplier:()=>1.5};var le={name:"Half Time",acronym:"HT",get_rate_multiplier:()=>0.75};var ce=0.4,de=0.3,Ie={name:"Hidden",acronym:"HD"};var Hr=(r)=>{if(r&(f.DoubleTime|f.Nightcore))return 1.5;if(r&f.HalfTime)return 0.75;return 1},Te=(r,e)=>{if(e&f.Easy)Tr.apply_to_difficulty(r);if(e&f.HardRock)Ir.apply_to_difficulty(r)},He=(r,e)=>{if(e===1)return r;let t=x(r)/e;return qr(t,dr)},zr=(r,e,t,n,s)=>{let o={cs:r,ar:e,od:t,hp:n};Te(o,s);let u=Hr(s);return o.ar=He(o.ar,u),o};var Wr=(r,e)=>[r[0]+e[0],r[1]+e[1]],_=(r,e)=>[r[0]-e[0],r[1]-e[1]],Yr=(r,e)=>[r[0]*e,r[1]*e];var B=(r)=>Math.sqrt(r[0]*r[0]+r[1]*r[1]);var U=(r,e,t)=>r+(e-r)*t,F=(r,e,t)=>[U(r[0],e[0],t),U(r[1],e[1],t)],b=(r,e,t)=>Math.min(t,Math.max(e,r));var br={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"]},Dr={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_hitburst:!0,hitburst_duration:180,hitburst_scale:1.2,hitburst_glow_enabled:!1,hitburst_glow_use_combo_color:!0,hitburst_glow_opacity:0.3,slider_body_opacity:0.9,slider_border_opacity:1,slider_tick_opacity:0.75,slider_tick_size:0.1,slider_render_scale:2,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,follow_point_shape:"line",follow_point_mode:"full",follow_point_length:12,follow_point_line_gap:0,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:br,default_font:'"Trebuchet MS", Verdana, Arial, sans-serif',hit_animation_duration:240,hit_animation_scale:1.2,enable_hit_animations:!0,enable_follow_circle_animations:!0},j=(r)=>{if(!r)return{...Dr};return{...Dr,...r,mania_lane_colors:r.mania_lane_colors?{...br,...r.mania_lane_colors}:br}},C=(r,e,t=1)=>{return`rgba(${r.combo_colors[e%r.combo_colors.length]},${t})`},q=(r,e,t)=>{let n=r.mania_lane_colors[e]??r.mania_lane_colors[4];return n[t%n.length]??"#ffffff"};var y={None:(r)=>r,Out:(r)=>1-Math.pow(1-r,2),In:(r)=>r*r,InOut:(r)=>r<0.5?2*r*r:1-Math.pow(-2*r+2,2)/2,OutCubic:(r)=>1-Math.pow(1-r,3),InCubic:(r)=>r*r*r,OutQuad:(r)=>1-Math.pow(1-r,2),InQuad:(r)=>r*r,OutQuint:(r)=>1-Math.pow(1-r,5),InQuint:(r)=>r*r*r*r*r,OutElastic:(r)=>{let e=2*Math.PI/3;return r===0?0:r===1?1:Math.pow(2,-10*r)*Math.sin((r*10-0.75)*e)+1}};class Rr{transforms=[];add(r,e,t,n,s,o=y.None){return this.transforms.push({property:r,start_value:e,end_value:t,start_time:n,end_time:n+s,easing:o}),this}then(){return this}get_value(r,e,t){let n=t;for(let s of this.transforms){if(s.property!==r)continue;if(e<s.start_time)continue;if(e>=s.end_time)n=s.end_value;else{let o=(e-s.start_time)/(s.end_time-s.start_time),u=s.easing(o);n=s.start_value+(s.end_value-s.start_value)*u}}return n}clear(){this.transforms=[]}}class E{backend;skin;hit_object;config;alpha=1;scale=1;rotation=0;x=0;y=0;armed_state=0;transforms=new Rr;life_time_start=0;life_time_end=0;constructor(r,e){this.hit_object=r,this.config=e,this.backend=e.backend,this.skin=e.skin;let t=r.data;this.x=t.pos[0],this.y=t.pos[1],this.apply_defaults()}apply_defaults(){let{hit_object:r,config:e}=this,t=r.time-e.preempt;this.life_time_start=t,this.life_time_end=r.end_time+800}is_alive(r){return r>=this.life_time_start&&r<=this.life_time_end}update(r){this.alpha=this.transforms.get_value("alpha",r,1),this.scale=this.transforms.get_value("scale",r,1),this.rotation=this.transforms.get_value("rotation",r,0),this.update_state(r)}update_state(r){if(this.armed_state===0&&r>=this.hit_object.time)this.armed_state=1,this.on_hit(r)}on_hit(r){}render_body_pass(r){}render_head_pass(r){}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 Z{state={circle_alpha:0,circle_scale:1,number_alpha:1};update(r,e,t){let n=e-t.preempt;if(r<n){this.reset_pre_hit_state();return}if(r<e){this.update_pre_hit(r,n,e,t);return}let s=k(e,n,e,t);this.update_post_hit(r,e,t,s)}render(r,e,t,n,s,o){let{circle_alpha:u,circle_scale:i,number_alpha:p}=this.state;if(u<=0.01)return;let a=n*i;if(u>0.01){let l=n*e.circle_border_width,h=n*(1-e.circle_border_width/2)*i;if(r.set_alpha(u*e.hit_circle_opacity),r.draw_circle(t[0],t[1],h,s,"rgba(255,255,255,1)",l),p>0.01){let m=n*0.7*i;r.set_alpha(p*e.hit_circle_opacity);let d=e.default_font??'"Trebuchet MS", Verdana, Arial, sans-serif',I=`600 ${m}px ${d}`;r.draw_text(String(o),t[0],t[1],I,"rgba(255,255,255,1)","center","middle")}r.set_alpha(1)}r.set_alpha(1)}get circle_alpha(){return this.state.circle_alpha}reset_pre_hit_state(){this.state.circle_alpha=0,this.state.circle_scale=1,this.state.number_alpha=1}update_pre_hit(r,e,t,n){let s=k(r,e,t,n);this.state.circle_alpha=s,this.state.circle_scale=1,this.state.number_alpha=s}update_post_hit(r,e,t,n){let s=r-e,{skin:o}=t,u=Math.max(90,o.hit_animation_duration*0.75),i=b(s/u,0,1),p=R(t.mods,f.Hidden)?b(n,0,1):b(Math.max(n,0.25),0,1);this.state.circle_alpha=p*(1-y.OutQuad(i));let a=Math.max(90,u*0.85),l=b(s/a,0,1);this.state.circle_scale=U(1,o.hit_animation_scale,y.OutCubic(l)),this.state.number_alpha=this.state.circle_alpha}}var k=(r,e,t,n)=>{let o=b((r-e)/n.fade_in,0,1);if(R(n.mods,f.Hidden)){let u=t-n.preempt+n.fade_in,i=n.preempt*0.3;if(r>u){let p=b((r-u)/i,0,1);o*=1-p}}return o};class yr{state={alpha:0,scale:1};update(r,e,t){if(!t.skin.enable_hitburst){this.state.alpha=0,this.state.scale=1;return}if(r<e){this.state.alpha=0,this.state.scale=1;return}let n=e-t.preempt,s=k(e,n,e,t),o=R(t.mods,f.Hidden)?b(s,0,1):b(Math.max(s,0.25),0,1),u=r-e,i=Math.max(70,t.skin.hitburst_duration),p=b(u/i,0,1),a=1-y.OutQuint(p);this.state.alpha=R(t.mods,f.Hidden)?a*o:a,this.state.scale=U(1,t.skin.hitburst_scale,y.OutCubic(p))}render(r,e,t,n,s){if(!e.enable_hitburst)return;if(this.state.alpha<=0.01)return;if(r.set_alpha(this.state.alpha),r.draw_circle(t[0],t[1],n*this.state.scale,"rgba(255,255,255,1)","transparent",0),e.hitburst_glow_enabled){r.save(),r.set_blend_mode("lighter"),r.set_alpha(this.state.alpha*e.hitburst_glow_opacity);let o=e.hitburst_glow_use_combo_color?s:e.hitburst_glow_color??s;r.draw_circle(t[0],t[1],n*this.state.scale*1.08,o,"transparent",0),r.restore()}}}class rr extends E{visual=new Z;hitburst=new yr;constructor(r,e){super(r,e)}update(r){super.update(r),this.visual.update(r,this.hit_object.time,this.config),this.hitburst.update(r,this.hit_object.time,this.config)}render(r){let{backend:e,skin:t,config:n}=this,{radius:s}=n,o=this.position,u=C(t,this.combo_number,1);this.visual.render(e,t,o,s,u,this.combo_count),this.hitburst.render(e,t,o,s,u)}}var er=(r)=>{let{start_time:e,span_duration:t,span_count:n,length:s,tick_distance:o,min_distance_from_end:u,get_position_at_progress:i}=r,p=[],a=[];if(s<=0||t<=0||n<=0)return{ticks:p,repeats:a};let h=Math.min(1e5,s),m=Math.min(Math.max(o,0),h),d=Math.max(0,Math.min(u,h));for(let I=0;I<n;I++){let c=e+I*t,T=I%2===1;if(m>0){let H=be(I,c,t,T,h,m,d,i);if(T)H.reverse();p.push(...H)}if(I<n-1){let H=(I+1)%2;a.push({pos:i(H),time:c+t,repeat_index:I,path_progress:H})}}return p.sort((I,c)=>I.time-c.time),{ticks:p,repeats:a}},be=(r,e,t,n,s,o,u,i)=>{let p=[];for(let a=o;a<=s;a+=o){if(a>=s-u)break;let l=a/s,h=n?1-l:l;p.push({pos:i(l),time:e+h*t,span_index:r,path_progress:l})}return p};var Mr=240,Vr=1.3,vr=35,De=250,Re=300,X=150,ye=X*4;class A extends E{slider_data;position_path;render_path;path_length;span_duration;body_alpha=0;head_visual=new Z;ball_alpha=0;ball_position;follow_alpha=0;follow_scale=1;ticks=[];repeats=[];tick_distance;min_distance_from_end;cached_texture=null;cached_scale=1;tick_entries=[];tick_entries_by_start=[];constructor(r,e,t,n,s,o){super(r,e);this.slider_data=r.data;let u=Math.max(1,e.radius*0.05);this.position_path=t,this.render_path=this.resample_path(t,u),this.span_duration=n,this.tick_distance=s,this.min_distance_from_end=o;let i=this.calculate_path_length();this.path_length=this.slider_data.distance>0?this.slider_data.distance:i,this.ball_position=this.slider_data.pos,this.build_nested_objects(),this.life_time_end=r.end_time+Mr}build_nested_objects(){let{slider_data:r,path_length:e,span_duration:t,hit_object:n}=this,s=Math.max(1,r.repetitions),o=1e5,u=Math.min(1e5,r.distance>0?r.distance:e),i=b(this.tick_distance,0,u);if(u<=0||t<=0){this.ticks=[],this.repeats=[];return}let p=er({start_time:n.time,span_duration:t,span_count:s,length:u,tick_distance:i,min_distance_from_end:this.min_distance_from_end,get_position_at_progress:(a)=>this.get_position_at_progress(a)});this.ticks=p.ticks,this.repeats=p.repeats,this.build_tick_entries()}calculate_path_length(){let r=0;for(let e=1;e<this.position_path.length;e++)r+=B(_(this.position_path[e],this.position_path[e-1]));return r}resample_path(r,e){if(r.length<2)return r.slice();let t=[r[0]],n=0,s=[];for(let l=1;l<r.length;l++){let h=B(_(r[l],r[l-1]));s.push(h),n+=h}if(n<=0)return t;let o=e,u=0,i=0;while(o<n&&i<s.length){let l=s[i],h=r[i],m=r[i+1];if(l>0&&u+l>=o){let d=(o-u)/l;t.push(F(h,m,d)),o+=e}else u+=l,i++}let p=r[r.length-1],a=t[t.length-1];if(a[0]!==p[0]||a[1]!==p[1])t.push(p);return t}update(r){super.update(r),this.calculate_ball_position(r),this.calculate_opacities(r),this.head_visual.update(r,this.hit_object.time,this.config)}calculate_ball_position(r){let{hit_object:e,span_duration:t}=this,n=300,s=300,o=2.4;if(r<e.time){this.ball_alpha=0,this.follow_alpha=0,this.follow_scale=1;return}if(r<=e.end_time){let a=r-e.time,l=Math.max(1,this.slider_data.repetitions),h=Math.min(Math.floor(a/t),l-1),m=b((a-h*t)/t,0,1),d=h%2===1?1-m:m;this.ball_position=this.get_position_at_progress(d),this.ball_alpha=1;let I=b(a/300,0,1),c=y.OutQuint(I);this.follow_alpha=c,this.follow_scale=1+1.4*c;return}let u=r-e.end_time,i=b(u/300,0,1),p=y.OutQuint(i);this.ball_alpha=1-p,this.follow_alpha=1-p,this.follow_scale=2.4-1.4*p}get_position_at_progress(r){let e=r*this.path_length;return this.get_position_at_length(e)}get_position_at_length(r){let e=0;for(let t=1;t<this.position_path.length;t++){let n=B(_(this.position_path[t],this.position_path[t-1]));if(e+n>=r){let s=(r-e)/n;return F(this.position_path[t-1],this.position_path[t],s)}e+=n}return this.position_path[this.position_path.length-1]}calculate_opacities(r){let{hit_object:e,config:t}=this,n=e.time-t.preempt,s=e.time;if(R(t.mods,f.Hidden)){let o=s-t.preempt+t.fade_in;if(r<n)this.body_alpha=0;else if(r<o)this.body_alpha=b((r-n)/t.fade_in,0,1);else if(r<=e.end_time){let u=Math.max(1,e.end_time-o);this.body_alpha=1-b((r-o)/u,0,1)}else this.body_alpha=0}else if(r<n)this.body_alpha=0;else if(r<s)this.body_alpha=b((r-n)/t.fade_in,0,1);else if(r<=e.end_time)this.body_alpha=1;else this.body_alpha=1-b((r-e.end_time)/Mr,0,1)}render(r){if(this.body_alpha<=0&&this.head_visual.circle_alpha<=0&&this.ball_alpha<=0)return;this.render_body(r),this.render_head(),this.render_ball(r)}render_body_pass(r){this.render_body(r)}render_head_pass(r){this.render_head(),this.render_reverse_arrows(r),this.render_ball(r)}render_body(r){if(this.body_alpha<=0.01||this.render_path.length<2)return;let{backend:e}=this;if(this.prepare_body_cache(),this.cached_texture&&this.cached_texture.min_x!==void 0&&this.cached_texture.min_y!==void 0){let t=this.cached_scale;e.set_alpha(this.body_alpha),e.draw_image(this.cached_texture,this.cached_texture.min_x,this.cached_texture.min_y,this.cached_texture.width/t,this.cached_texture.height/t),e.set_alpha(1)}this.render_ticks(r)}prepare_body_cache(){if(this.render_path.length<2)return;let{backend:r,skin:e,config:t}=this,{radius:n}=t,s=(t.scale??1)*(e.slider_render_scale||1);if(!this.cached_texture||this.cached_scale!==s){let o=C(e,this.combo_number,1),u=e.slider_border_color??"rgba(255,255,255,1)",i=s;this.cached_texture=r.render_slider_to_image(this.render_path,n,u,o,i,e.slider_body_opacity,e.slider_border_opacity),this.cached_scale=s}}render_ticks(r){if(this.tick_entries_by_start.length===0)return;let{backend:e,config:t,hit_object:n}=this,{radius:s}=t,o=s*0.12,u=n.time-t.preempt,i=R(t.mods,f.Hidden);for(let p of this.tick_entries_by_start){let a=p.tick,l=r-p.appear_time;if(l<0)continue;if(p.visible_end<r)continue;let h=b(l/X,0,1);if(i&&p.preempt>0){let T=Math.min(p.preempt-X,1000);if(T>0){let H=a.time-T;if(r>=H){let D=b((r-H)/T,0,1);h*=1-D}}}else if(r>a.time){let T=b((r-a.time)/X,0,1);h*=1-T}h*=this.body_alpha;let m=b(l/ye,0,1),I=0.5+0.5*this.ease_out_elastic_half(m),c=o*I;if(h>0.01)e.set_alpha(h),e.draw_circle(a.pos[0],a.pos[1],c,"rgba(255,255,255,0.8)","transparent",0)}e.set_alpha(1)}build_tick_entries(){let{hit_object:r,config:e}=this,t=r.time-e.preempt,n=R(e.mods,f.Hidden);this.tick_entries=this.ticks.map((s)=>{let o=r.time+s.span_index*this.span_duration,u=e.preempt,i=s.span_index>0?200:u*0.66,p=(s.time-o)/2+i,a=s.time-p,l=n?s.time:s.time+X;return{tick:s,appear_time:a,visible_end:l,preempt:p}}),this.tick_entries_by_start=[...this.tick_entries].sort((s,o)=>s.appear_time-o.appear_time)}ease_out_elastic_half(r){if(r<=0)return 0;if(r>=1)return 1;let e=0.3;return Math.pow(2,-10*r)*Math.sin((r-e/4)*(2*Math.PI)/e)+1}render_reverse_arrows(r){if(this.repeats.length===0)return;let{backend:e,config:t,hit_object:n,span_duration:s}=this,{radius:o}=t,u=o*0.6;for(let i of this.repeats){let p=t.preempt;if(i.repeat_index>0)p=s*2;else p+=n.time-(n.time-t.preempt);let a=i.time-p,l=i.repeat_index%2===0;if(r<a||r>i.time+Mr)continue;let h=this.body_alpha*0.9;if(i.repeat_index===0){let H=b((r-a)/150,0,1);h*=y.OutQuint(H)}else if(r<a)h=0;if(r>i.time){let H=Math.min(300,s);h*=1-b((r-i.time)/H,0,1)}if(h<=0.01)continue;let m=this.position_path,d;if(l){let H=m.length-1;d=m[0];for(let D=H;D>=0;D--)if(Math.abs(m[D][0]-i.pos[0])>0.01||Math.abs(m[D][1]-i.pos[1])>0.01){d=m[D];break}}else{d=m[m.length-1];for(let H=0;H<m.length;H++)if(Math.abs(m[H][0]-i.pos[0])>0.01||Math.abs(m[H][1]-i.pos[1])>0.01){d=m[H];break}}let I=Math.atan2(d[1]-i.pos[1],d[0]-i.pos[0]),c=1;if(r<i.time){let H=n.time-t.preempt,D=(r-H)%Re;if(D<vr)c=1+(Vr-1)*y.Out(D/vr);else{let M=(D-vr)/De;c=Vr-(Vr-1)*y.Out(b(M,0,1))}}else{let H=Math.min(300,s),D=b((r-i.time)/H,0,1);c=1+0.5*y.Out(D)}let T=u*c;e.save(),e.set_alpha(h),e.translate(i.pos[0],i.pos[1]),e.rotate(I),e.begin_path(),e.move_to(T*0.8,0),e.line_to(-T*0.4,-T*0.5),e.line_to(-T*0.4,T*0.5),e.close_path(),e.fill_path("rgba(255,255,255,0.9)"),e.restore()}}render_head(){if(this.head_visual.circle_alpha<=0.01)return;let{backend:r,skin:e,config:t}=this,{radius:n}=t,s=this.slider_data.pos,o=C(e,this.combo_number,1);this.head_visual.render(r,e,s,n,o,this.combo_count)}render_ball(r){if(this.ball_alpha<=0.01&&this.follow_alpha<=0.01)return;let{backend:e,skin:t,config:n}=this,{radius:s}=n,o=this.ball_position,u=C(t,this.combo_number,0.9);if(this.follow_alpha>0.01){let i=s*this.follow_scale;e.set_alpha(this.follow_alpha*t.follow_circle_opacity),e.begin_path(),e.arc_to(o[0],o[1],i,0,Math.PI*2),e.stroke_path(t.follow_circle_color,t.follow_circle_width)}if(t.enable_slider_ball&&this.ball_alpha>0.01)e.set_alpha(this.ball_alpha*t.slider_ball_opacity),e.draw_circle(o[0],o[1],s*0.85,u,"rgba(255,255,255,0.9)",s*0.1);e.set_alpha(1)}}class _r{skin;mods;preempt;fade_in;radius;points=[];lines=[];constructor(r,e,t,n,s){this.skin=r,this.mods=e,this.preempt=t,this.fade_in=n,this.radius=s}update_settings(r,e,t,n){this.mods=r,this.preempt=e,this.fade_in=t,this.radius=n}build(r){this.points=[],this.lines=[];let e=32,t=Math.max(450,this.preempt*0.9);for(let n=0;n<r.length-1;n++){let s=r[n],o=r[n+1];if($(s)||$(o))continue;if(s.combo_number!==o.combo_number)continue;let u=s.end_pos,i=o.data.pos,p=i[0]-u[0],a=i[1]-u[1],l=Math.sqrt(p*p+a*a);if(l<e*1.5)continue;let h=s.end_time,m=o.time-h;if(m<=0)continue;let d=l>0?1/l:0,I=[p*d,a*d],c=h-t,T=o.time-t,H=h+(T-h)*0.5,D=o.time;if(R(this.mods,f.Hidden))H=h+(T-h)*0.3,D=h+(o.time-h)*0.65;this.lines.push({start_pos:u,end_pos:i,dir:I,start_time:h,end_time:o.time,appear_time:c,grow_end_time:T,shrink_start_time:H,shrink_end_time:D});for(let M=e*1.5;M<l-e;M+=e){let v=M/l,V=s.end_time+v*m,N=Math.max(s.end_time,V-t);if(R(this.mods,f.Hidden))V=Math.min(V,h+m*0.65);let Y=[u[0]+(v-0.1)*p,u[1]+(v-0.1)*a],g=[u[0]+v*p,u[1]+v*a];this.points.push({start_pos:Y,end_pos:g,dir:I,fade_in_time:N,fade_out_time:V})}}}render(r,e,t){let n=this.skin.follow_point_shape,s=this.skin.follow_point_mode??"segments",o=this.skin.follow_point_length||this.radius*0.6,u=b(this.skin.follow_point_line_gap??0,0,0.9),i=Math.max(this.fade_in*0.15,50),p=0.2;if(s==="full")for(let a of this.lines){if(r<a.appear_time||r>a.shrink_end_time)continue;let l=0,h=a.start_pos[0],m=a.start_pos[1],d=a.end_pos[0],I=a.end_pos[1],c=Math.hypot(d-h,I-m),T=this.get_alpha_gate(r,a.start_time,a.end_time,t);if(T<=0.01)continue;let H=this.radius*1.05,D=Math.min(H,c*0.22);if(h+=a.dir[0]*D,m+=a.dir[1]*D,d-=a.dir[0]*D,I-=a.dir[1]*D,r<a.grow_end_time){let M=Math.max(1,a.grow_end_time-a.appear_time),v=b((r-a.appear_time)/M,0,1),V=y.OutQuint(v);l=V,d=h+(d-h)*V,I=m+(I-m)*V}else if(r<a.shrink_start_time)l=1;else{let M=Math.max(1,a.shrink_end_time-a.shrink_start_time),v=b((r-a.shrink_start_time)/M,0,1),V=y.InQuint(v);l=1,h=h+(d-h)*V,m=m+(I-m)*V}if(l<=0)continue;if(e.set_alpha(l*0.2*T),n==="line")if(u>0){let M=Math.hypot(d-h,I-m),v=a.dir[0],V=a.dir[1],N=M*u/2,Y=(h+d)/2,g=(m+I)/2,ne=Y-v*N,se=g-V*N,oe=Y+v*N,ue=g+V*N;e.draw_line(h,m,ne,se,"rgba(255,255,255,1)",this.skin.follow_point_width,"round","round"),e.draw_line(oe,ue,d,I,"rgba(255,255,255,1)",this.skin.follow_point_width,"round","round")}else e.draw_line(h,m,d,I,"rgba(255,255,255,1)",this.skin.follow_point_width,"round","round");else{let M=this.radius*0.12,v=(a.start_pos[0]+a.end_pos[0])/2,V=(a.start_pos[1]+a.end_pos[1])/2;e.draw_circle(v,V,M,"rgba(255,255,255,1)","transparent",0)}}else for(let a of this.points){if(r<a.fade_in_time||r>a.fade_out_time+i)continue;let l=0,h=1,m=a.end_pos;if(r<a.fade_in_time+i){let I=b((r-a.fade_in_time)/i,0,1),c=y.OutCubic(I);l=c,h=1.5-0.5*c,m=F(a.start_pos,a.end_pos,c)}else if(r<=a.fade_out_time)l=1,h=1,m=a.end_pos;else{let I=b((r-a.fade_out_time)/i,0,1),c=y.OutCubic(I);l=1-c,h=1,m=F(a.start_pos,a.end_pos,1-c)}if(l<=0)continue;let d=this.get_alpha_gate(r,a.fade_in_time+this.preempt,a.fade_out_time,t);if(d<=0.01)continue;if(e.set_alpha(l*0.2*d),n==="line"){let c=o*h/2,T=a.dir[0],H=a.dir[1],D=m[0]-T*c,M=m[1]-H*c,v=m[0]+T*c,V=m[1]+H*c;e.draw_line(D,M,v,V,"rgba(255,255,255,1)",this.skin.follow_point_width,"round","round")}else{let I=this.radius*0.12*h;e.draw_circle(m[0],m[1],I,"rgba(255,255,255,1)","transparent",0)}}e.set_alpha(1)}get_alpha_gate(r,e,t,n){let s=n(r,e),o=n(r,t);return b(Math.min(s,o)/0.7,0,1)}}var Pr=(r,e=0.08)=>{if(r.length<2)return[...r];let t=[];return Br(r,t,e),t},Br=(r,e,t)=>{if(Me(r,t)){if(e.length===0)e.push(r[0]);e.push(r[r.length-1]);return}let n=[],s=[];ve(r,n,s),Br(n,e,t),Br(s,e,t)},Me=(r,e)=>{if(r.length<=2)return!0;let t=r[0],n=r[r.length-1];for(let s=1;s<r.length-1;s++)if(Ve(r[s],t,n)>e)return!1;return!0},Ve=(r,e,t)=>{let n=_(t,e),s=n[0]*n[0]+n[1]*n[1];if(s===0)return B(_(r,e));let o=Math.max(0,Math.min(1,((r[0]-e[0])*n[0]+(r[1]-e[1])*n[1])/s)),u=[e[0]+o*n[0],e[1]+o*n[1]];return B(_(r,u))},ve=(r,e,t)=>{let n=r.length,s=[r];for(let o=1;o<n;o++){s[o]=[];for(let u=0;u<n-o;u++)s[o][u]=F(s[o-1][u],s[o-1][u+1],0.5)}for(let o=0;o<n;o++)e.push(s[o][0]),t.push(s[n-1-o][o])},wr=(r,e,t)=>{let n=_(e,r),s=B(n);if(s===0)return[r];let o=[n[0]/s,n[1]/s],u=Wr(r,Yr(o,t));return[r,u]},gr=(r,e)=>{if(r.length!==3)return Pr(r);let[t,n,s]=r,o=_e(t,n,s);if(!o)return wr(t,s,e);let u=B(_(t,o)),i=Math.atan2(t[1]-o[1],t[0]-o[0]),p=Math.atan2(s[1]-o[1],s[0]-o[0]),l=(n[0]-t[0])*(s[1]-t[1])-(n[1]-t[1])*(s[0]-t[0])>0,h=p-i;if(l&&h<0)h+=2*Math.PI;if(!l&&h>0)h-=2*Math.PI;let m=Math.abs(h)*u,d=2;if(u*2>0.1){let c=Math.abs(h),T=2*Math.acos(1-0.1/u);if(d=Math.max(2,Math.ceil(c/T)),d>=1000)d=1000}let I=[];for(let c=0;c<=d;c++){let T=c/d,H=i+h*T;I.push([o[0]+u*Math.cos(H),o[1]+u*Math.sin(H)])}return I},_e=(r,e,t)=>{let n=2*(r[0]*(e[1]-t[1])+e[0]*(t[1]-r[1])+t[0]*(r[1]-e[1]));if(Math.abs(n)<0.001)return null;let s=((r[0]*r[0]+r[1]*r[1])*(e[1]-t[1])+(e[0]*e[0]+e[1]*e[1])*(t[1]-r[1])+(t[0]*t[0]+t[1]*t[1])*(r[1]-e[1]))/n,o=((r[0]*r[0]+r[1]*r[1])*(t[0]-e[0])+(e[0]*e[0]+e[1]*e[1])*(r[0]-t[0])+(t[0]*t[0]+t[1]*t[1])*(e[0]-r[0]))/n;return[s,o]},Kr=(r)=>{if(r.length<2)return[...r];let e=[];for(let t=0;t<r.length-1;t++){let n=r[Math.max(0,t-1)],s=r[t],o=r[t+1],u=r[Math.min(r.length-1,t+2)],i=B(_(o,s)),p=Math.max(8,Math.ceil(i/3));for(let a=0;a<=p;a++){let l=a/p;e.push(Be(n,s,o,u,l))}}return e},Be=(r,e,t,n,s)=>{let o=s*s,u=o*s;return[0.5*(2*e[0]+(-r[0]+t[0])*s+(2*r[0]-5*e[0]+4*t[0]-n[0])*o+(-r[0]+3*e[0]-3*t[0]+n[0])*u),0.5*(2*e[1]+(-r[1]+t[1])*s+(2*r[1]-5*e[1]+4*t[1]-n[1])*o+(-r[1]+3*e[1]-3*t[1]+n[1])*u)]};var Gr=(r)=>{let e;if(r.path_type==="L")e=wr(r.pos,r.control_points[0],r.distance);else{let t=[r.pos,...r.control_points];switch(r.path_type){case"P":e=gr(t,r.distance);break;case"C":e=Kr(t);break;default:e=Pe(t);break}}return we(e,r.distance)},xr=(r)=>{if(!r.computed_path||r.computed_path.length===0)return r.pos;return r.repetitions%2===0?r.pos:r.computed_path[r.computed_path.length-1]},Pe=(r)=>{let e=[],t=[r[0]];for(let s=1;s<r.length;s++){let[o,u]=[r[s-1],r[s]];if(o[0]===u[0]&&o[1]===u[1]){if(t.length>1)e.push(t);t=[u]}else t.push(u)}if(t.length>1)e.push(t);let n=[];for(let s of e)n.push(...Pr(s));return n},we=(r,e)=>{if(r.length<2)return r;let t=[r[0]],n=0,s=null,o=!1;for(let u=1;u<r.length;u++){let i=B(_(r[u],r[u-1])),p=_(r[u],r[u-1]);if(i>0)s=[p[0]/i,p[1]/i];if(i===0)continue;if(n+i>=e){let a=e-n;t.push(F(r[u-1],r[u],a/i)),n=e,o=!0;break}n+=i,t.push(r[u])}if(!o&&n<e&&s){let u=e-n,i=t[t.length-1];t.push([i[0]+s[0]*u,i[1]+s[1]*u])}return t};var tr=(r,e,t)=>{if(r<=0)return 0;let n=e.Difficulty.SliderMultiplier;return r*t.base_beat_length/(100*n*t.sv_multiplier)},nr=(r,e)=>{let t=e.sv_multiplier||1,n=r.Difficulty.SliderMultiplier,s=r.Difficulty.SliderTickRate,o=100*n*t,u=r.version<8?1/t:1,i=o/s*u,p=o/e.base_beat_length;return{tick_distance:i,min_distance_from_end:p*10}};class z{points;index=0;last_time=Number.NEGATIVE_INFINITY;base_beat_length=600;sv_multiplier=1;constructor(r){if(this.points=r,r.length>0&&r[0].uninherited===1&&r[0].beatLength>0)this.base_beat_length=r[0].beatLength}reset(){this.index=0,this.last_time=Number.NEGATIVE_INFINITY,this.base_beat_length=600,this.sv_multiplier=1}get_state_at(r){if(this.points.length===0)return{base_beat_length:600,sv_multiplier:1};if(r<this.last_time)this.reset();for(let e=this.index;e<this.points.length;e++){let t=this.points[e];if(t.time>r)break;if(t.uninherited===1&&t.beatLength>0)this.base_beat_length=t.beatLength,this.sv_multiplier=1;else if(t.uninherited===0&&t.beatLength<0){let n=-100/t.beatLength;if(n>0)this.sv_multiplier=n}this.index=e}return this.last_time=r,this.sv_multiplier=b(this.sv_multiplier,0.1,10),{base_beat_length:this.base_beat_length,sv_multiplier:this.sv_multiplier}}}var sr=(r)=>{if(r.length===0)return r;return r.sort((e,t)=>{if(e.time!==t.time)return e.time-t.time;if(e.uninherited===t.uninherited)return 0;return e.uninherited>t.uninherited?-1:1})};var or=(r)=>{let e=[];for(let t of r.HitObjects){let n={...t,end_time:t.endTime||t.time,end_pos:[t.x,t.y],combo_number:0,combo_count:0,data:{pos:[t.x,t.y]}};if(t.type&P.Slider){let s={pos:[t.x,t.y],path_type:t.curveType||"L",control_points:(t.curvePoints||[]).map((o)=>[o.x,o.y]),repetitions:t.slides||1,distance:t.length||0};n.data=s}else if(t.type&P.Spinner){let s=t.endTime||t.time;n.data={end_time:s},n.end_time=s,n.end_pos=[256,192]}else if(t.type&P.Hold){let s=t.endTime||t.time;n.data={pos:[t.x,t.y],end_time:s},n.end_time=s}e.push(n)}return e};var Fr=(r)=>384-r;class ur extends Q{radius=32;preempt=1200;fade_in=600;timing_points=[];timing_resolver=null;drawables=[];drawable_config;follow_point_renderer;constructor(r,e,t=0,n=S){super(r,e,t,n);this.follow_point_renderer=new _r(e,t,this.preempt,this.fade_in,this.radius)}initialize(r){this.beatmap=r,this.objects=or(r).sort((n,s)=>n.time-s.time),this.timing_points=sr([...r.TimingPoints]),this.timing_resolver=new z(this.timing_points);let e=r.Difficulty.ApproachRate>=0?r.Difficulty.ApproachRate:r.Difficulty.OverallDifficulty,t=zr(r.Difficulty.CircleSize,e,0,0,this.mods);if(this.radius=Xr(t.cs),this.preempt=x(t.ar),this.fade_in=Zr(this.preempt),R(this.mods,f.Hidden))this.fade_in=this.preempt*0.4;this.follow_point_renderer.update_settings(this.mods,this.preempt,this.fade_in,this.radius),this.preprocess_objects(),this.follow_point_renderer.build(this.objects),this.create_drawables()}set_mods(r){if(this.mods=r,this.beatmap)this.initialize(this.beatmap)}preprocess_objects(){let r=0,e=1;if(this.timing_resolver)this.timing_resolver.reset();for(let t of this.objects){if(Nr(t))r=(r+1)%this.skin.combo_colors.length,e=1;else e++;if(t.combo_number=r,t.combo_count=e,fr(t)){let n=t.data;if(R(this.mods,f.HardRock))n.pos=[n.pos[0],Fr(n.pos[1])],n.control_points=n.control_points.map((u)=>[u[0],Fr(u[1])]);n.computed_path=Gr(n);let s=this.timing_resolver?.get_state_at(t.time)??{base_beat_length:600,sv_multiplier:1},o=tr(n.distance,this.beatmap,s);n.duration=o,t.end_time=t.time+o*n.repetitions,t.end_pos=xr(n)}else if($(t))t.end_pos=[256,192];else{let n=t.data;if(R(this.mods,f.HardRock))n.pos=[n.pos[0],Fr(n.pos[1])];t.end_pos=n.pos}}}create_drawables(){this.drawables=[];let r=this.config.use_high_dpi?window.devicePixelRatio||1:1;if(this.drawable_config={backend:this.backend,skin:this.skin,preempt:this.preempt,fade_in:this.fade_in,radius:this.radius,scale:this.config.scale*r,mods:this.mods},this.timing_resolver)this.timing_resolver.reset();for(let e of this.objects)if(Or(e))this.drawables.push(new rr(e,this.drawable_config));else if(fr(e)){let t=e.data,n=t.computed_path||[],s=t.duration||0,o=this.timing_resolver?.get_state_at(e.time)??{base_beat_length:600,sv_multiplier:1},{tick_distance:u,min_distance_from_end:i}=nr(this.beatmap,o);this.drawables.push(new A(e,this.drawable_config,n,s,u,i))}}render(r){let{backend:e,config:t}=this;this.render_background(),e.save(),e.translate(t.offset_x,t.offset_y),e.scale(t.scale,t.scale),this.render_playfield(),this.render_grid();let n=[];for(let s=this.drawables.length-1;s>=0;s--){let o=this.drawables[s];if(o.is_alive(r))n.push(o)}this.follow_point_renderer.render(r,e,(s,o)=>this.get_circle_alpha(s,o));for(let s of this.objects)if($(s)){let o=s.time-this.preempt;if(r>=o&&r<=s.end_time+200)this.draw_spinner(s,r)}for(let s of n)s.update(r);for(let s of n)if(s instanceof A)s.render_body_pass(r);for(let s of n)if(s instanceof A)s.render_head_pass(r);else s.render(r);if(!R(this.mods,f.Hidden)&&this.skin.enable_approach_circle){for(let s of n)if(r<=s.start_time)this.draw_approach_circle(s,r)}e.restore()}precompute(){for(let r of this.drawables)if(r instanceof A)r.prepare_body_cache()}draw_approach_circle(r,e){let t=r.position,n=r.start_time-this.preempt,s=Math.min(this.fade_in*2,this.preempt),u=b((e-n)/s,0,1)*this.skin.approach_circle_opacity,p=4-3*b((e-n)/this.preempt,0,1),a=C(this.skin,r.combo_number,1);this.backend.save(),this.backend.set_alpha(u),this.backend.draw_circle(t[0],t[1],this.radius*p,"transparent",a,this.radius*this.skin.approach_circle_width),this.backend.restore()}get_circle_alpha(r,e){let t=e-this.preempt;if(r<t)return 0;let n=b((r-t)/this.fade_in,0,1);if(R(this.mods,f.Hidden)){let s=e-this.preempt+this.fade_in,o=this.preempt*0.3;if(r>s){let u=b((r-s)/o,0,1);n*=1-u}}return n}draw_spinner(r,e){let t=r.time-this.preempt,n=b((e-t)/this.fade_in,0,1);if(e>r.end_time)n=1-y.OutCubic(b((e-r.end_time)/200,0,1));if(n<=0)return;let s=256,o=192,u=r.end_time-r.time,i=b((e-r.time)/u,0,1);this.backend.set_alpha(n);let p=this.skin.spinner_size*(1-i);if(p>5)this.backend.begin_path(),this.backend.arc_to(s,o,p,0,Math.PI*2),this.backend.stroke_path("rgba(255,255,255,0.6)",4);this.backend.draw_circle(s,o,this.skin.spinner_size,"rgba(0,0,0,0.2)"),this.backend.draw_circle(s,o,12,"white")}}var jr=11485,kr=20;class ir extends Q{key_count=4;scroll_time=jr/kr;hd_coverage=0.25;fi_coverage=0.6;gradient_ratio=0.2;constructor(r,e,t=0,n=S){super(r,e,t,n);this.update_scroll_time()}initialize(r){this.beatmap=r,this.objects=or(r),this.key_count=Math.floor(r.Difficulty.CircleSize)}set_mods(r){this.mods=r,this.update_scroll_time()}update_scroll_time(){let r=Hr(this.mods);this.scroll_time=jr/(kr*r)}time_to_y(r){let e=this.skin.mania_hit_position,t=r/this.scroll_time;return e-t*e}render(r){let{backend:e,config:t,skin:n,key_count:s}=this;this.render_background();let o=s*n.mania_lane_width,u=Math.floor((lr-o)/2),i=n.mania_hit_position;e.save(),e.translate(t.offset_x,t.offset_y),e.scale(t.scale,t.scale),this.render_playfield(o,cr,u),this.draw_lane_keys(r,u),this.draw_judgment_line(u),e.save(),e.begin_path(),e.rect(u,0,o,i),e.clip(),e.set_alpha(0.7),e.draw_rect(u,0,o,i,"#000000"),e.set_alpha(1);for(let p of this.objects){if(p.end_time<r)continue;if(Ar(p))this.draw_hold_note(p,r,u);else this.draw_note(p,r,u)}if(R(this.mods,f.Hidden)||R(this.mods,f.FadeIn)){let p=R(this.mods,f.Hidden)?this.hd_coverage:this.fi_coverage,a=i*p,l=i*this.gradient_ratio;if(R(this.mods,f.Hidden)){let h=i-a,m=l/a,d=e.create_linear_gradient(u,h,u,i,[{offset:0,color:"rgba(0,0,0,0)"},{offset:m*0.4,color:"rgba(0,0,0,0.3)"},{offset:m*0.7,color:"rgba(0,0,0,0.75)"},{offset:m*0.9,color:"rgba(0,0,0,0.95)"},{offset:m,color:"rgba(0,0,0,1)"},{offset:1,color:"rgba(0,0,0,1)"}]);e.draw_rect_gradient(u,h,o,a,d)}else{let h=(a-l)/a,m=e.create_linear_gradient(u,0,u,a,[{offset:0,color:"rgba(0,0,0,1)"},{offset:h,color:"rgba(0,0,0,1)"},{offset:h+(1-h)*0.1,color:"rgba(0,0,0,0.95)"},{offset:h+(1-h)*0.4,color:"rgba(0,0,0,0.75)"},{offset:h+(1-h)*0.7,color:"rgba(0,0,0,0.3)"},{offset:1,color:"rgba(0,0,0,0)"}]);e.draw_rect_gradient(u,0,o,a,m)}}e.restore(),e.restore()}get_lane(r){let e=r.data.pos,t=Math.floor(e[0]*this.key_count/512);if(R(this.mods,f.Mirror))t=this.key_count-1-t;return t}draw_note(r,e,t){let{backend:n,skin:s,key_count:o}=this,u=this.get_lane(r),i=s.mania_lane_width,p=s.mania_note_height,a=s.mania_lane_spacing,l=r.time-e,h=this.time_to_y(l);if(h<-p-64)return;let m=t+u*i,d=q(s,o,u);n.set_alpha(1),n.draw_rect(m+a,h-p,i-2*a,p,d)}draw_hold_note(r,e,t){let{backend:n,skin:s,key_count:o}=this,u=r.data,i=this.get_lane(r),p=s.mania_lane_width,a=s.mania_note_height,l=s.mania_lane_spacing,h=r.time-e,m=u.end_time-e,d=this.time_to_y(h),I=this.time_to_y(m),c=t+i*p,T=q(s,o,i);if(I<-64&&d<-64)return;let H=I,M=(h<0?s.mania_hit_position:d)-H;if(M>0)n.set_alpha(0.9),n.draw_rect(c+l,H,p-2*l,M,T);if(h>=0)n.set_alpha(1),n.draw_rect(c+l,d-a,p-2*l,a,T);n.set_alpha(1)}draw_judgment_line(r){let{backend:e,skin:t,key_count:n}=this,s=t.mania_lane_width,o=t.mania_hit_position;e.draw_rect(r,o-1,s*n,2,"#ffffff")}draw_lane_keys(r,e){let{backend:t,skin:n,key_count:s}=this,{mania_lane_width:o,mania_hit_position:u,mania_lane_spacing:i,mania_note_height:p}=n,a=p+5,l=new Set,h=50;for(let m of this.objects)if(r>=m.time-50&&r<=m.end_time+50)l.add(this.get_lane(m));for(let m=0;m<s;m++){let d=l.has(m),I=e+m*o,c=q(n,s,m);if(t.set_alpha(0.3),t.draw_rect(I+i,u,o-2*i,a,c),d)t.set_alpha(1),t.draw_rect(I+i,u,o-2*i,a,"#ff6666")}t.set_alpha(1)}}class W{audio_context;gain_node;constructor(r){this.audio_context=r,this.gain_node=this.audio_context.createGain(),this.gain_node.connect(this.audio_context.destination)}set_volume(r){this.gain_node.gain.value=b(r,0,1)}dispose_audio_node(){this.gain_node.disconnect()}}class pr extends W{audio_element=null;media_source_node=null;object_url=null;pause_time=0;speed=1;_is_playing=!1;_duration=0;_is_loaded=!1;constructor(r){super(r)}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.audio_element)return this.pause_time;if(!this._is_playing)return this.pause_time;return this.audio_element.currentTime*1000}async load(r,e=0){this.stop(),this.release_media();try{this.speed=J(e);let t=new Blob([r]),n=URL.createObjectURL(t),s=new Audio(n);s.preload="metadata",s.playbackRate=this.speed,s.preservesPitch=!1,this.audio_element=s,this.object_url=n,this.media_source_node=this.audio_context.createMediaElementSource(s),this.media_source_node.connect(this.gain_node),await new Promise((o,u)=>{let i=()=>{s.removeEventListener("loadedmetadata",i),s.removeEventListener("error",p),o()},p=()=>{s.removeEventListener("loadedmetadata",i),s.removeEventListener("error",p),u(Error("Failed to load audio metadata"))};s.addEventListener("loadedmetadata",i,{once:!0}),s.addEventListener("error",p,{once:!0})}),this._duration=Math.max(0,(this.audio_element.duration||0)*1000),this._is_loaded=!0,this.pause_time=0,this.audio_element.onended=()=>{this._is_playing=!1,this.pause_time=this._duration}}catch(t){throw console.error("Failed to load audio data",t),this.release_media(),t}}async play(r){if(!this.audio_element){console.warn("[AudioController] Cannot play: not loaded");return}let e=r!==void 0?r/1000:this.pause_time/1000,t=this.audio_element.duration||this._duration/1000,n=Math.max(0,Math.min(e,t));if(n>=t){this.pause_time=t*1000;return}this.audio_element.currentTime=n,this.audio_element.playbackRate=this.speed;try{await this.audio_element.play(),this._is_playing=!0}catch(s){throw this._is_playing=!1,s}}pause(){if(!this.audio_element||!this._is_playing)return;this.pause_time=this.current_time,this.audio_element.pause(),this._is_playing=!1}seek(r){let e=Math.max(0,Math.min(r,this._duration));if(this.pause_time=e,!this.audio_element)return;this.audio_element.currentTime=e/1000}stop(){if(this.pause(),this.pause_time=0,this.audio_element)this.audio_element.currentTime=0}get_host_time(r){let e=r-this.current_time;return this.audio_context.currentTime+e/1000/this.speed}set_speed(r){if(this.speed=r,this.audio_element)this.audio_element.playbackRate=r}dispose(){this.stop(),this.release_media(),this._is_loaded=!1,this._duration=0,this.pause_time=0,this._is_playing=!1,this.dispose_audio_node()}release_media(){if(this.audio_element)this.audio_element.pause(),this.audio_element.onended=null,this.audio_element.src="",this.audio_element.load(),this.audio_element=null;if(this.media_source_node)this.media_source_node.disconnect(),this.media_source_node=null;if(this.object_url)URL.revokeObjectURL(this.object_url),this.object_url=null}}class ar{video=null;object_url=null;_offset=0;get element(){return this.video}get offset(){return this._offset}async load(r,e=0){this.dispose(),this._offset=e,this.video=document.createElement("video"),this.video.muted=!0,this.video.loop=!1,this.video.playsInline=!0,this.object_url=URL.createObjectURL(r),this.video.src=this.object_url,await new Promise((t,n)=>{if(!this.video)return n(Error("No video element"));this.video.onloadeddata=()=>t(),this.video.onerror=()=>n(Error("Failed to load video"))})}sync(r){if(!this.video)return;let e=(r-this._offset)/1000;if(e<0){if(!this.video.paused)this.video.pause();return}if(Math.abs(this.video.currentTime-e)>0.1)this.video.currentTime=e}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(r){if(!this.video)return;let e=Math.max(0,(r-this._offset)/1000);this.video.currentTime=e}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 O extends W{static default_samples=new Map;static default_loads=new Map;custom_samples=new Map;constructor(r){super(r)}async load_samples(r){this.custom_samples.clear(),await this.load_into_cache(r,this.custom_samples,!1)}async load_samples_from_files(r){this.custom_samples.clear(),await this.load_files_into_cache(r,this.custom_samples)}async load_default_samples(r){await this.load_into_cache(r,O.default_samples,!0)}clear(){this.custom_samples.clear()}play(r,e,t,n,s=100,o,u=0){let i=this.get_set_name(r),p=this.get_set_name(e);if(o){let a=o.toLowerCase().replace(/\.(wav|mp3|ogg)$/,"");if(this.play_buffer(a,s,u))return}if(this.play_sound(i,"hitnormal",n,s,u),t&K.Whistle)this.play_sound(p,"hitwhistle",n,s,u);if(t&K.Finish)this.play_sound(p,"hitfinish",n,s,u);if(t&K.Clap)this.play_sound(p,"hitclap",n,s,u)}play_sample(r,e,t,n=100,s=0){let o=this.get_set_name(r);this.play_sound(o,e,t,n,s)}play_sound(r,e,t,n,s){let o=!1;if(t>1)o=this.play_buffer(`${r}-${e}${t}`,n,s);if(!o)this.play_buffer(`${r}-${e}`,n,s)}play_buffer(r,e,t){let n=this.custom_samples.get(r)??O.default_samples.get(r);if(!n)return!1;let s=this.audio_context.createBufferSource();s.buffer=n;let o=this.audio_context.createGain();return o.gain.value=e/100,s.connect(o),o.connect(this.gain_node),s.start(t),!0}get_set_name(r){switch(r){case 3:return"drum";case 2:return"soft";default:return"normal"}}get_sample_key_from_url(r){let t=r.split("?")[0].split("#")[0].split("/").pop();if(!t)return null;if(!t.endsWith(".wav")&&!t.endsWith(".mp3")&&!t.endsWith(".ogg"))return null;return t.toLowerCase().replace(/\.(wav|mp3|ogg)$/,"")}async load_into_cache(r,e,t){if(r.length==0)return;let n=[],s=r.map(async(o)=>{let u=this.get_sample_key_from_url(o);if(!u){n.push(o);return}if(e.has(u))return;if(!t){await this.load_single_sample(o,u,e,n);return}let i=O.default_loads.get(u);if(i){await i;return}let p=this.load_single_sample(o,u,e,n).finally(()=>{O.default_loads.delete(u)});O.default_loads.set(u,p),await p});if(await Promise.all(s),n.length>0)console.warn(`[HitsoundController] Failed to load ${n.length} hitsounds`)}async load_single_sample(r,e,t,n){try{let s=await fetch(r);if(!s.ok){n.push(r);return}let o=await s.arrayBuffer();if(o.byteLength<128){n.push(r);return}let u=await this.audio_context.decodeAudioData(o.slice(0));t.set(e,u)}catch{n.push(r)}}async load_files_into_cache(r,e){if(r.size==0)return;let t=[],n=[...r.entries()].map(async([s,o])=>{let u=this.get_sample_key_from_url(s);if(!u)return;if(e.has(u))return;if(o.byteLength<128){t.push(s);return}try{let i=await this.audio_context.decodeAudioData(o.slice(0));e.set(u,i)}catch{t.push(s)}});if(await Promise.all(n),t.length>0)console.warn(`[HitsoundController] Failed to load ${t.length} hitsounds`)}dispose(){this.custom_samples.clear(),this.dispose_audio_node()}}class Sr{files;audio_filename;background_filename;video_filename;video_offset;constructor(r){this.files=r.files,this.audio_filename=r.audio_filename,this.background_filename=r.background_filename,this.video_filename=r.video_filename,this.video_offset=r.video_offset}resolve(){let r=this.audio_filename?this.find_file(this.audio_filename):void 0,e=this.background_filename?this.find_file(this.background_filename):void 0,t=this.video_filename?this.find_file(this.video_filename):void 0;return{audio:r,background:e?new Blob([e]):void 0,video:t?new Blob([t]):void 0,video_offset:this.video_offset}}find_file(r){if(this.files.has(r))return this.files.get(r);let e=r.toLowerCase();for(let[t,n]of this.files)if(t.toLowerCase()===e)return n;return}}var Fe=100,Se=20;class Cr{audio;hitsounds;resources=null;timing_points=[];timing_resolver=null;audio_offset=20;next_hit_object_index=0;constructor(r,e){this.audio=r;this.hitsounds=e}set_context(r,e,t,n){this.resources=r,this.timing_points=e,this.timing_resolver=t,this.audio_offset=n,this.next_hit_object_index=0}set_audio_offset(r){this.audio_offset=r}update_hit_index(r){if(!this.resources?.beatmap)return;let e=this.resources.beatmap.HitObjects;if(this.next_hit_object_index>0&&e[this.next_hit_object_index-1].time>r)this.next_hit_object_index=0;while(this.next_hit_object_index<e.length&&e[this.next_hit_object_index].time<r)this.next_hit_object_index++}schedule_hitsounds(r){if(!this.resources?.beatmap||!this.audio.is_playing)return;let e=this.resources.beatmap.HitObjects,t=r+Fe;while(this.next_hit_object_index<e.length&&e[this.next_hit_object_index].time<=t){let n=e[this.next_hit_object_index];if(n.time>=r-Se)this.play_hitsound(n);this.next_hit_object_index++}}play_hitsound(r){let e=this.get_timing_point(r.time),t=this.resolve_sample_settings(e,r.hitSample);if((r.type&P.Slider)===0){this.play_node_hitsound(r.time,r.hitSound,t,t.custom_filename);return}let n=this.resources?.beatmap;if(!n)return;let s=this.timing_resolver?.get_state_at(r.time)??{base_beat_length:600,sv_multiplier:1},o=r.length??0,u=tr(o,n,s),i=Math.max(1,r.slides||1);if(u<=0||o<=0){this.play_node_hitsound(r.time,r.hitSound,t,t.custom_filename);return}let p=r.edgeSounds??[],a=r.edgeSets??[];for(let m=0;m<=i;m++){let d=r.time+u*m,I=p.length>0?p[m]??0:m==0?r.hitSound:0,c=a.length>0?a[m]:void 0,T=this.resolve_edge_sets(t,c),H=m==0?t.custom_filename:void 0;this.play_node_hitsound(d,I,{...t,...T},H)}let l=nr(n,s),h=er({start_time:r.time,span_duration:u,span_count:i,length:o,tick_distance:l.tick_distance,min_distance_from_end:l.min_distance_from_end,get_position_at_progress:()=>[0,0]});for(let m of h.ticks){let d=this.audio.get_host_time(m.time+this.audio_offset);this.hitsounds.play_sample(t.normal_set,"slidertick",t.index,t.volume,d)}}play_node_hitsound(r,e,t,n){let s=this.audio.get_host_time(r+this.audio_offset);this.hitsounds.play(t.normal_set,t.addition_set,e,t.index,t.volume,n,s)}resolve_sample_settings(r,e){let{volume:t,sampleSet:n,sampleSet:s,sampleIndex:o}=r,u=void 0;if(e){if(e.normalSet!==0){if(n=e.normalSet,e.additionSet===0)s=n}if(e.additionSet!==0)s=e.additionSet;if(e.index!==0)o=e.index;if(e.volume!==0)t=e.volume;u=e.filename||void 0}if(n===0)n=1;if(s===0)s=n;return{normal_set:n,addition_set:s,index:o,volume:t,custom_filename:u}}resolve_edge_sets(r,e){let{normal_set:t,addition_set:n}=r;if(e){let{normalSet:s,additionSet:o}=e;if(s!==0)t=s;if(o!==0)n=o;else n=t}if(t===0)t=1;if(n===0)n=t;return{normal_set:t,addition_set:n}}get_timing_point(r){let e=this.timing_points;if(e.length==0)return{time:0,beatLength:600,meter:4,sampleSet:1,sampleIndex:1,volume:100,uninherited:1,effects:0};for(let t=e.length-1;t>=0;t--)if(e[t].time<=r)return e[t];return e[0]}}var Ce=[".wav",".mp3",".ogg"],Oe=/^(normal|soft|drum)-(hitnormal|hitwhistle|hitfinish|hitclap|slidertick|sliderslide|sliderwhistle)\d*$/i,re=(r,e,t)=>{let n=new Set;for(let u of r.HitObjects){let i=u.hitSample?.filename?.trim();if(i)n.add(i.toLowerCase())}let s=new Map,o=t?.toLowerCase();for(let[u,i]of e){let p=u.toLowerCase();if(!Ae(p))continue;if(o&&p==o)continue;let a=Ne(p),l=a.replace(/\.(wav|mp3|ogg)$/,""),h=Oe.test(l),m=n.has(a)||n.has(l)||n.has(p);if(h||m)s.set(u,i)}return s},Ae=(r)=>{for(let e of Ce)if(r.endsWith(e))return!0;return!1},Ne=(r)=>{let e=r.split("?")[0].split("#")[0];return e.split("/").pop()??e};var Le=0.42,Qe=30;class te{backend;renderer=null;audio_context;audio;hitsounds;video=null;resources=null;animation_frame=null;skin;mods;renderer_config;start_offset;start_mode;custom_start_time;music_volume;hitsound_volume;audio_offset;background_url=null;listeners=new Map;is_loaded_flag=!1;hitsound_scheduler;timing_points=[];timing_resolver=null;resize_observer=null;key_handler=null;options;enable_fps_counter=!1;fps_frame_count=0;fps_last_update=0;current_fps=0;time_smoothing=0.1;smoothed_delta=0;max_frame_delta=100;last_timestamp=0;smooth_time=0;constructor(r){this.options=r,this.backend=r.backend??new G,this.skin=j(r.skin),this.mods=r.mods??0,this.renderer_config={...S,...r.renderer_config},this.calculate_layout(r.canvas.width,r.canvas.height,r.playfield_scale),this.start_mode=r.start_mode??(Number.isFinite(r.start_time)?"custom":"preview"),this.custom_start_time=Number.isFinite(r.start_time)?Math.max(0,r.start_time):null,this.start_offset=0,this.music_volume=r.volume??0.5,this.hitsound_volume=r.hitsound_volume??0.25,this.audio_offset=r.audio_offset??20,this.backend.initialize(r.canvas,this.renderer_config.use_high_dpi);let e=window.AudioContext||window.webkitAudioContext;if(this.audio_context=new e,this.audio=new pr(this.audio_context),this.hitsounds=new O(this.audio_context),this.hitsound_scheduler=new Cr(this.audio,this.hitsounds),this.audio.set_volume(this.music_volume),this.hitsounds.set_volume(this.hitsound_volume),r.auto_resize)this.setup_auto_resize();this.enable_fps_counter=r.enable_fps_counter??!1,this.fps_last_update=performance.now();let t=r.time_smoothing;if(Number.isFinite(t))this.time_smoothing=Math.max(0,Math.min(1,t));let n=r.max_frame_delta;if(Number.isFinite(n))this.max_frame_delta=Math.max(10,n)}async load_osz(r,e){try{let n=await new L().load_osz(r,{difficulty:e});return this.resources=n,this.setup()}catch(t){let n=t instanceof Error?t.message:String(t);return this.emit("error","INVALID_BEATMAP",n),w("INVALID_BEATMAP",n)}}async load_files(r,e){try{let t=new L;return this.resources=await t.load_from_files(r,{difficulty:e}),this.setup()}catch(t){let n=t instanceof Error?t.message:String(t);return this.emit("error","INVALID_BEATMAP",n),w("INVALID_BEATMAP",n)}}async load_default_hitsounds(r){if(r.length==0){console.warn("[BeatmapPlayer] No default hitsound URLs were provided");return}try{await this.hitsounds.load_default_samples(r)}catch(e){console.error("[BeatmapPlayer] Failed to load default hitsounds:",e)}}async load_custom_hitsounds(r){if(r.length==0){console.warn("[BeatmapPlayer] No custom hitsound URLs were provided"),this.hitsounds.clear();return}try{await this.hitsounds.load_samples(r)}catch(e){console.error("[BeatmapPlayer] Failed to load custom hitsounds:",e)}}async load_map_custom_hitsounds(){if(!this.resources?.beatmap)return;let r=re(this.resources.beatmap,this.resources.files,this.resources.audio_filename);if(r.size==0){this.hitsounds.clear();return}try{await this.hitsounds.load_samples_from_files(r)}catch(e){console.error("[BeatmapPlayer] Failed to load map custom hitsounds:",e),this.hitsounds.clear()}}async load_beatmap(r,e,t,n,s){return this.resources={beatmap:r,available_difficulties:[],files:new Map,audio:e,background:t,video:n,video_offset:s},this.setup()}async load_osu_content(r,e){try{await ee();let t=await this.parse_content(r);return this.load_beatmap(t,e)}catch(t){let n=t instanceof Error?t.message:String(t);return this.emit("error","INVALID_BEATMAP",n),w("INVALID_BEATMAP",n)}}async load_beatmap_files(r,e,t,n,s){try{await ee();let o=typeof r==="string",u=r instanceof Uint8Array?r:r instanceof ArrayBuffer?new Uint8Array(r):null,i=await this.parse_content(o?r:u);return this.load_beatmap(i,e,t,n,s)}catch(o){let u=o instanceof Error?o.message:String(o);return this.emit("error","INVALID_BEATMAP",u),w("INVALID_BEATMAP",u)}}async setup(){if(!this.resources)return w("NOT_LOADED","No resources loaded");let{beatmap:r}=this.resources;this.timing_points=sr([...r.TimingPoints]),this.timing_resolver=new z(this.timing_points);let e=J(this.mods);this.resolve_assets();let{audio:t,video:n,video_offset:s}=this.resources;if(t)try{await this.audio.load(t,this.mods)}catch(o){let u=o instanceof Error?o.message:String(o);return this.emit("error","AUDIO_DECODE_ERROR",u),w("AUDIO_DECODE_ERROR",u)}if(this.hitsound_scheduler.set_context(this.resources,this.timing_points,this.timing_resolver,this.audio_offset),this.load_map_custom_hitsounds(),n)this.video=new ar,await this.video.load(n,s??0);try{this.renderer=this.create_renderer(r),this.renderer.initialize(r),this.renderer.precompute()}catch(o){let u=o instanceof Error?o.message:String(o);return this.emit("error","UNSUPPORTED_MODE",u),w("UNSUPPORTED_MODE",u)}return this.start_offset=this.resolve_initial_start_offset(),this.hitsound_scheduler.update_hit_index(this.start_offset),this.load_background(),this.is_loaded_flag=!0,this.emit("loaded",r,this.resources),requestAnimationFrame(()=>this.render_frame(this.start_offset)),Lr(this.resources)}async load_background(){if(this.resources)this.resolve_assets();if(!this.resources?.background||!this.renderer)return;try{let r=new Image;if(this.background_url)URL.revokeObjectURL(this.background_url);this.background_url=URL.createObjectURL(this.resources.background),r.src=this.background_url,await r.decode(),this.renderer.set_background({source:r,width:r.width,height:r.height});let e=this.audio.is_playing?this.current_time:this.start_offset;requestAnimationFrame(()=>this.render_frame(e))}catch(r){console.warn("[BeatmapPlayer] Failed to load background",r)}}resolve_assets(){if(!this.resources)return;let r=new Sr(this.resources).resolve();if(!this.resources.audio&&r.audio)this.resources.audio=r.audio;if(!this.resources.background&&r.background)this.resources.background=r.background;if(!this.resources.video&&r.video)this.resources.video=r.video;if(!this.resources.video_offset&&r.video_offset)this.resources.video_offset=r.video_offset}create_renderer(r){switch(r.General.Mode){case 0:return new ur(this.backend,this.skin,this.mods,this.renderer_config);case 3:return new ir(this.backend,this.skin,this.mods,this.renderer_config);case 1:case 2:default:throw Error(`Unsupported game mode: ${hr[r.General.Mode]??r.General.Mode}`)}}get_last_object_time(){if(!this.resources?.beatmap.HitObjects.length)return 0;let r=this.resources.beatmap.HitObjects,e=0;for(let t of r){let n=t.endTime||t.time;if(n>e)e=n}return e}resolve_preview_start_offset(){if(!this.resources?.beatmap)return 0;let r=this.resources.beatmap.General.PreviewTime;if(r>0)return r;return Math.max(0,this.get_last_object_time()*Le)}resolve_initial_start_offset(){let r=Math.max(0,this.duration);if(this.start_mode=="beginning")return 0;if(this.start_mode=="custom"){if(this.custom_start_time!==null)return Math.max(0,Math.min(this.custom_start_time,r));return Math.max(0,Math.min(this.resolve_preview_start_offset(),r))}return Math.max(0,Math.min(this.resolve_preview_start_offset(),r))}async play(){if(!this.renderer||!this.is_loaded_flag){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(Math.max(0,this.start_offset+this.audio_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=Math.max(0,this.audio.current_time-this.audio_offset),this.audio.pause(),this.video?.pause(),this.stop_render_loop(),this.emit("pause"),this.emit("statechange",!1)}set_mods(r){this.mods=r;let e=J(r);if(this.renderer?.set_mods(r),this.audio.set_speed(e),this.is_loaded_flag)requestAnimationFrame(()=>this.render_frame(this.current_time))}seek(r){this.start_offset=Math.max(0,Math.min(r,this.duration)),this.hitsound_scheduler.update_hit_index(this.start_offset),this.audio.seek(Math.max(0,this.start_offset+this.audio_offset)),this.video?.seek(this.start_offset),this.emit("seek",this.start_offset),this.render_frame(this.start_offset)}async set_difficulty(r){if(!this.resources)return w("NOT_LOADED","No beatmap resources loaded");let e=this.is_playing;this.stop();try{let n=await new L().load_from_files(this.resources.files,{difficulty:r});this.resources=n;let s=await this.setup();if(s.success&&e)this.play();return s}catch(t){let n=t instanceof Error?t.message:String(t);return this.emit("error","INVALID_BEATMAP",n),w("INVALID_BEATMAP",n)}}async parse_content(r){let e=typeof r=="string"?new TextEncoder().encode(r):r;return await $e(e)}stop(){this.pause(),this.start_offset=0,this.audio.seek(Math.max(0,this.audio_offset)),this.hitsound_scheduler.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.background_url)URL.revokeObjectURL(this.background_url),this.background_url=null;if(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_flag=!1,this.listeners.clear()}get current_time(){return Math.max(0,this.audio.current_time-this.audio_offset)}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_flag}get mode(){if(!this.resources)return"standard";switch(this.resources.beatmap.General.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(r,e,t){if(this.backend.resize(r,e),this.calculate_layout(r,e,t),this.is_loaded_flag)requestAnimationFrame(()=>this.render_frame(this.current_time))}update_config(r){if(this.renderer_config={...this.renderer_config,...r},this.renderer?.update_config(this.renderer_config),this.is_loaded_flag)requestAnimationFrame(()=>this.render_frame(this.current_time))}set_skin(r){if(this.skin=j(r),this.is_loaded_flag&&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 e=this.options.canvas.parentElement;if(e){let t=e.getBoundingClientRect();this.resize(t.width,t.height,this.options.playfield_scale)}}),this.resize_observer.observe(this.options.canvas.parentElement||this.options.canvas)}toggle_pause(){if(!this.is_loaded_flag)return;if(this.is_playing)this.pause();else 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(r,e,t){let o=0.9;if(Number.isFinite(t))o=t;let u=r*o/512,i=e*o/384,p=Math.min(u,i);if(this.renderer_config.scale=p,this.renderer_config.offset_x=Math.floor((r-512*p)/2),this.renderer_config.offset_y=Math.floor((e-384*p)/2),this.renderer)this.renderer.update_config(this.renderer_config)}set_volume(r){this.music_volume=r,this.audio.set_volume(r)}set_hitsound_volume(r){this.hitsound_volume=r,this.hitsounds.set_volume(r)}set_offset(r){if(this.audio_offset=r,this.hitsound_scheduler.set_audio_offset(r),this.is_loaded_flag)this.seek(this.current_time)}on(r,e){if(!this.listeners.has(r))this.listeners.set(r,new Set);this.listeners.get(r).add(e)}off(r,e){this.listeners.get(r)?.delete(e)}emit(r,...e){let t=this.listeners.get(r);if(t)for(let n of t)n(...e)}start_render_loop(){if(this.animation_frame!==null)return;this.last_timestamp=performance.now(),this.smooth_time=this.audio.current_time-this.audio_offset,this.smoothed_delta=0;let r=(e)=>{if(!this.audio.is_playing){this.animation_frame=null;return}let t=Math.max(0,e-this.last_timestamp);this.last_timestamp=e;let n=Math.min(t,this.max_frame_delta);if(this.time_smoothing>0){if(this.smoothed_delta===0)this.smoothed_delta=n;else this.smoothed_delta+=(n-this.smoothed_delta)*this.time_smoothing;n=this.smoothed_delta}this.smooth_time+=n*this.audio.speed_multiplier;let s=this.audio.current_time-this.audio_offset;if(Math.abs(this.smooth_time-s)>Qe)this.smooth_time=s;else this.smooth_time+=(s-this.smooth_time)*0.1;let u=this.smooth_time;if(this.hitsound_scheduler.schedule_hitsounds(s),this.render_frame(u),this.video?.sync(u),this.emit("timeupdate",u,this.duration),u>=this.duration){this.emit("ended"),this.stop_render_loop(),this.emit("statechange",!1);return}this.animation_frame=requestAnimationFrame(r)};this.animation_frame=requestAnimationFrame(r)}stop_render_loop(){if(this.animation_frame!==null)cancelAnimationFrame(this.animation_frame),this.animation_frame=null}render_frame(r){if(this.backend.begin_frame?.(),this.backend.clear(),this.renderer?.render(r),this.enable_fps_counter){this.fps_frame_count++;let e=performance.now(),t=e-this.fps_last_update;if(t>=1000)this.current_fps=Math.round(this.fps_frame_count*1000/t),this.fps_frame_count=0,this.fps_last_update=e;let n=`14px ${this.skin.default_font??"monospace"}`;this.backend.draw_text(`${this.current_fps} FPS`,10,20,n,"rgba(255,255,255,0.8)","left","top")}this.backend.end_frame?.()}set_fps_counter(r){this.enable_fps_counter=r}}var Ue=(r)=>{try{return new FontFace(r.family,r.url,{weight:r.weight,style:"normal"})}catch(e){return console.error(e),null}},Ee=async(r)=>{let e=Ue(r);if(!e)return!1;try{await e.load(),document.fonts.add(e)}catch(t){return console.error(t),!1}return!0};export{qe as unwrap,Ke as toggle_mod,Lr as ok,ge as mods_to_string,Ye as mods_from_string,j as merge_skin,Ee as load_font,$ as is_spinner,fr as is_slider,Ze as is_ok,Nr as is_new_combo,Ar as is_hold,Xe as is_err,Or as is_circle,R as has_mod,J as get_speed_multiplier,Hr as get_rate_multiplier,q as get_mania_lane_color,C as get_combo_color,Ge as get_available_mods,zr as get_adjusted_difficulty,w as err,He as apply_rate_to_ar,Te as apply_mods_to_difficulty,ar as VideoController,ur as StandardRenderer,ie as SpeedChangingMods,mr as SampleSet,lr as PLAYFIELD_WIDTH,cr as PLAYFIELD_HEIGHT,L as OszLoader,f as Mods,fe as ModNightcore,Ie as ModHidden,Ir as ModHardRock,le as ModHalfTime,Tr as ModEasy,me as ModDoubleTime,ir as ManiaRenderer,K as HitSoundType,P as HitObjectType,de as HD_FADE_OUT_MULTIPLIER,ce as HD_FADE_IN_MULTIPLIER,Jr as GridLevel,hr as GameMode,$r as ErrorCode,We as DifficultyChangingMods,Dr as DEFAULT_SKIN,S as DEFAULT_RENDERER_CONFIG,G as CanvasBackend,te as BeatmapPlayer,Q as BaseRenderer,pr as AudioController};
1
+ var Tr;((t)=>{t[t.Standard=0]="Standard";t[t.Taiko=1]="Taiko";t[t.Catch=2]="Catch";t[t.Mania=3]="Mania"})(Tr||={});var Hr;((t)=>{t[t.Auto=0]="Auto";t[t.Normal=1]="Normal";t[t.Soft=2]="Soft";t[t.Drum=3]="Drum"})(Hr||={});var J={Circle:1,Slider:2,NewCombo:4,Spinner:8,ComboSkip:112,Hold:128},i={Normal:1,Whistle:2,Finish:4,Clap:8},Xr=(r)=>(r.type&J.Circle)!==0,Vr=(r)=>(r.type&J.Slider)!==0,U=(r)=>(r.type&J.Spinner)!==0,mr=(r)=>(r.type&J.Hold)!==0,Ur=(r)=>(r.type&J.NewCombo)!==0;var Wr;((f)=>{f.NoOsuFiles="NO_OSU_FILES";f.DifficultyNotFound="DIFFICULTY_NOT_FOUND";f.InvalidBeatmap="INVALID_BEATMAP";f.UnsupportedMode="UNSUPPORTED_MODE";f.AudioNotLoaded="AUDIO_NOT_LOADED";f.AudioDecodeError="AUDIO_DECODE_ERROR";f.NotLoaded="NOT_LOADED";f.Unknown="UNKNOWN"})(Wr||={});var Yr=(r)=>({success:!0,data:r}),L=(r,u)=>({success:!1,code:r,reason:u}),ju=(r)=>{if(r.success)return r.data;throw Error(`[${r.code}] ${r.reason}`)},bu=(r)=>{return r.success},iu=(r)=>{return!r.success};var V={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},fu=V.DoubleTime|V.HalfTime|V.Nightcore,du=V.HardRock|V.Easy|fu,au=(r)=>{let u=0,n=r.toLowerCase(),s={nf:V.NoFail,ez:V.Easy,td:V.TouchDevice,hd:V.Hidden,hr:V.HardRock,sd:V.SuddenDeath,dt:V.DoubleTime,rx:V.Relax,ht:V.HalfTime,nc:V.Nightcore,fl:V.Flashlight,at:V.Autoplay,so:V.SpunOut,ap:V.Autopilot,pf:V.Perfect,fi:V.FadeIn,mr:V.Mirror};for(let t=0;t<n.length-1;t+=2){let e=n.slice(t,t+2);if(s[e])u|=s[e]}return u},_u=(r)=>{let u=[];if(r&V.NoFail)u.push("NF");if(r&V.Easy)u.push("EZ");if(r&V.Hidden)u.push("HD");if(r&V.HardRock)u.push("HR");if(r&V.SuddenDeath)u.push("SD");if(r&V.DoubleTime)u.push("DT");if(r&V.HalfTime)u.push("HT");if(r&V.Nightcore)u.push("NC");if(r&V.Flashlight)u.push("FL");if(r&V.SpunOut)u.push("SO");if(r&V.FadeIn)u.push("FI");if(r&V.Mirror)u.push("MR");let n=u.indexOf("DT"),s=u.indexOf("NC");if(n>=0&&s>=0)u.splice(n,1);return u.join("")},E=(r)=>{if(r&(V.DoubleTime|V.Nightcore))return 1.5;if(r&V.HalfTime)return 0.75;return 1},Iu=[V.HardRock|V.Easy,V.DoubleTime|V.HalfTime|V.Nightcore,V.Hidden|V.FadeIn],rn=(r,u)=>{if(r&u)return r&~u;let n=r;for(let s of Iu)if(u&s)n&=~s;return n|u},$=(r,u)=>(r&u)!==0,un=(r)=>{let u=[{name:"Easy",acronym:"EZ",value:V.Easy},{name:"Hidden",acronym:"HD",value:V.Hidden},{name:"Double Time",acronym:"DT",value:V.DoubleTime},{name:"Half Time",acronym:"HT",value:V.HalfTime},{name:"Nightcore",acronym:"NC",value:V.Nightcore}];switch(r){case"standard":return[...u,{name:"Hard Rock",acronym:"HR",value:V.HardRock}];case"mania":return[...u,{name:"Hard Rock",acronym:"HR",value:V.HardRock},{name:"Fade In",acronym:"FI",value:V.FadeIn}];case"taiko":case"catch":return[...u,{name:"Hard Rock",acronym:"HR",value:V.HardRock}];default:return u}};import zr from"jszip";import{init_wasm as Kr,parse as lr}from"@rel-packages/osu-beatmap-parser/browser";class W{async load_osz(r,u){await Kr();let n=await zr.loadAsync(r),s=new Map;for(let[t,e]of Object.entries(n.files))if(!e.dir)s.set(t,await e.async("arraybuffer"));return this.load_from_files(s,u)}async load_from_files(r,u){await Kr();let n=[...r.keys()].filter((R)=>R.toLowerCase().endsWith(".osu"));if(n.length===0)throw Error("No .osu files found in beatmap");let s=await Promise.all(n.map(async(R)=>{let P=r.get(R),F=this.to_bytes(P),S=await lr(F);return{filename:R,beatmap:S}})),t=this.select_difficulty(n,s,u?.difficulty),e=r.get(t),o=this.to_bytes(e),h=await lr(o),f=h.General.AudioFilename||null,I=h.Events.background?.filename||null,D=h.Events.video?.filename||null,T=h.Events.video?.startTime??0,H=new Map;for(let[R,P]of r)if(P instanceof ArrayBuffer)H.set(R,P);else H.set(R,new TextEncoder().encode(P).buffer);let M;if(f)M=this.find_file(H,f);let B;if(I){let R=this.find_file(H,I);if(R)B=new Blob([R])}let p;if(D){let R=this.find_file(H,D);if(R)p=new Blob([R])}return{beatmap:h,available_difficulties:s,files:H,audio:M,background:B,video:p,audio_filename:f??void 0,background_filename:I??void 0,video_filename:D??void 0,video_offset:D?T:void 0}}async list_difficulties(r){let u=await zr.loadAsync(r),n=[];for(let t of Object.keys(u.files))if(t.toLowerCase().endsWith(".osu"))n.push(t);let s=[];for(let t of n){let o=(await u.files[t].async("string")).match(/Version:\s*(.+)/);s.push(o?o[1].trim():t)}return s}select_difficulty(r,u,n){if(n===void 0)return r[0];if(typeof n==="number"){if(n<0||n>=r.length)throw Error(`Difficulty index ${n} out of range (0-${r.length-1})`);return r[n]}let s=u.find((o)=>o.beatmap.Metadata.Version===n);if(s)return s.filename;let t=n.toLowerCase(),e=u.find((o)=>o.filename.toLowerCase().includes(t)||o.beatmap.Metadata.Version.toLowerCase().includes(t));if(e)return e.filename;throw Error(`Difficulty "${n}" not found`)}find_file(r,u){if(r.has(u))return r.get(u);let n=u.toLowerCase();for(let[s,t]of r)if(s.toLowerCase()===n)return t;return}to_bytes(r){if(r instanceof ArrayBuffer)return new Uint8Array(r);return new TextEncoder().encode(r)}}import{init_wasm as nu,parse as Eu}from"@rel-packages/osu-beatmap-parser/browser";var Dr=512,pr=384,Er;((e)=>{e[e.None=0]="None";e[e.Large=32]="Large";e[e.Medium=16]="Medium";e[e.Small=8]="Small";e[e.Tiny=4]="Tiny"})(Er||={});var q={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 Y{backend;skin;config;mods;beatmap;objects=[];background_image=null;constructor(r,u,n=0,s=q){this.backend=r,this.skin=u,this.mods=n,this.config={...q,...s}}set_background(r){this.background_image=r}update_config(r){this.config={...this.config,...r}}precompute(r=0){}on_seek(r){}dispose(){this.objects=[]}render_playfield(r,u,n,s){if(!this.config.show_playfield)return;let{backend:t,config:e}=this,o=r??512,h=u??384,f=n??0,I=s??0;t.save(),t.set_alpha(e.playfield_opacity),t.begin_path(),t.move_to(f,I),t.line_to(f+o,I),t.line_to(f+o,I+h),t.line_to(f,I+h),t.line_to(f,I),t.stroke_path(e.playfield_color,2),t.restore()}render_grid(){if(this.config.grid_level===0)return;let{backend:r,config:u}=this,n=u.grid_level;r.save(),r.set_alpha(u.grid_opacity);for(let s=0;s<=512;s+=n)r.begin_path(),r.move_to(s,0),r.line_to(s,384),r.stroke_path(u.grid_color,s%(n*4)===0?1:0.5);for(let s=0;s<=384;s+=n)r.begin_path(),r.move_to(0,s),r.line_to(512,s),r.stroke_path(u.grid_color,s%(n*4)===0?1:0.5);r.restore()}render_background(){if(!this.background_image)return;let{backend:r}=this;r.save(),r.set_alpha(0.3);let{width:u,height:n}=r,{width:s,height:t}=this.background_image;if(s>0&&t>0){let e=Math.max(u/s,n/t),o=s*e,h=t*e,f=(u-o)/2,I=(n-h)/2;r.draw_image(this.background_image,f,I,o,h)}else r.draw_image(this.background_image,0,0,u,n);r.restore()}get_visible_objects(r,u,n){let s=[];for(let t of this.objects){let e=t.time-u,o=t.end_time+n;if(r>=e&&r<=o)s.push(t)}return s}}class k{ctx;_width=0;_height=0;_dpr=1;is_initialized=!1;get width(){return this._width}get height(){return this._height}initialize(r,u=!0){this._dpr=u?window.devicePixelRatio||1:1;let n=r.clientWidth||r.width,s=r.clientHeight||r.height;this.apply_canvas_size(r,n,s);let t=r.getContext("2d",{alpha:!0,desynchronized:!0});if(!t)throw Error("Failed to get 2D context");this.ctx=t,this._width=n,this._height=s,this.configure_context(),this.is_initialized=!0}clear(){if(!this.is_initialized)return;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(){}begin_frame(){}end_frame(){}resize(r,u){if(!this.is_initialized)return;this._width=r,this._height=u,this._dpr=window.devicePixelRatio||1;let n=this.ctx.canvas;this.apply_canvas_size(n,r,u),this.reset_transform(),this.configure_context()}draw_circle(r,u,n,s,t,e){let o=this.ctx;if(o.beginPath(),o.arc(r,u,n,0,Math.PI*2),s&&s!=="transparent")o.fillStyle=s,o.fill();if(t&&e&&e>0)o.strokeStyle=t,o.lineWidth=e,o.stroke()}draw_arc(r,u,n,s,t,e,o,h=!1){let f=this.ctx;f.beginPath(),f.arc(r,u,n,s,t,h),f.strokeStyle=e,f.lineWidth=o,f.stroke()}draw_rect(r,u,n,s,t){this.ctx.fillStyle=t,this.ctx.fillRect(r,u,n,s)}draw_rect_gradient(r,u,n,s,t){this.ctx.fillStyle=t,this.ctx.fillRect(r,u,n,s)}create_linear_gradient(r,u,n,s,t){let e=this.ctx.createLinearGradient(r,u,n,s);for(let o of t)e.addColorStop(o.offset,o.color);return e}draw_text(r,u,n,s,t,e="left",o="alphabetic"){let h=this.ctx;h.font=s,h.fillStyle=t,h.textAlign=e,h.textBaseline=o,h.fillText(r,u,n)}measure_text(r,u){let n=this.ctx,s=n.font;n.font=u;let t=n.measureText(r);return n.font=s,t}begin_path(){this.ctx.beginPath()}move_to(r,u){this.ctx.moveTo(r,u)}line_to(r,u){this.ctx.lineTo(r,u)}draw_line(r,u,n,s,t,e,o="butt",h="miter"){this.ctx.beginPath(),this.ctx.moveTo(r,u),this.ctx.lineTo(n,s),this.ctx.strokeStyle=t,this.ctx.lineWidth=e,this.ctx.lineCap=o,this.ctx.lineJoin=h,this.ctx.stroke()}bezier_curve_to(r,u,n,s,t,e){this.ctx.bezierCurveTo(r,u,n,s,t,e)}quadratic_curve_to(r,u,n,s){this.ctx.quadraticCurveTo(r,u,n,s)}arc_to(r,u,n,s,t,e){this.ctx.arc(r,u,n,s,t,e)}rect(r,u,n,s){this.ctx.rect(r,u,n,s)}clip(){this.ctx.clip()}stroke_path(r,u,n="butt",s="miter"){let t=this.ctx;t.strokeStyle=r,t.lineWidth=u,t.lineCap=n,t.lineJoin=s,t.stroke()}fill_path(r){this.ctx.fillStyle=r,this.ctx.fill()}close_path(){this.ctx.closePath()}save(){this.ctx.save()}restore(){this.ctx.restore()}translate(r,u){this.ctx.translate(r,u)}scale(r,u){this.ctx.scale(r,u)}rotate(r){this.ctx.rotate(r)}set_alpha(r){this.ctx.globalAlpha=r}set_shadow(r,u){this.ctx.shadowColor=r,this.ctx.shadowBlur=u}set_composite_operation(r){this.ctx.globalCompositeOperation=r}set_blend_mode(r){let u={normal:"source-over",lighter:"lighter",multiply:"multiply",screen:"screen"};this.ctx.globalCompositeOperation=u[r]??"source-over"}draw_image(r,u,n,s,t){if(s!==void 0&&t!==void 0)this.ctx.drawImage(r.source,u,n,s,t);else this.ctx.drawImage(r.source,u,n)}draw_image_part(r,u,n,s,t,e,o,h,f){this.ctx.drawImage(r.source,u,n,s,t,e,o,h,f)}render_slider_to_image(r,u,n,s,t,e=1,o=1){let h=1/0,f=1/0,I=-1/0,D=-1/0;for(let F of r){if(F[0]<h)h=F[0];if(F[0]>I)I=F[0];if(F[1]<f)f=F[1];if(F[1]>D)D=F[1]}let T=u+2;h-=T,f-=T,I+=T,D+=T;let H=Math.ceil((I-h)*t),M=Math.ceil((D-f)*t);if(H<=0||M<=0)return null;let B=document.createElement("canvas");B.width=H,B.height=M;let p=B.getContext("2d");if(!p)return null;p.save(),p.scale(t,t),p.translate(-h,-f);let R=()=>{if(p.beginPath(),r.length>0){p.moveTo(r[0][0],r[0][1]);for(let F=1;F<r.length;F++)p.lineTo(r[F][0],r[F][1])}};p.lineCap="round",p.lineJoin="round",p.globalAlpha=o,p.strokeStyle=n,p.lineWidth=u*2,R(),p.stroke();let P=u*0.872;if(e<1)p.globalCompositeOperation="destination-out",p.globalAlpha=1,p.lineWidth=P*2,R(),p.stroke(),p.globalCompositeOperation="source-over";return p.globalAlpha=e,p.strokeStyle=s,p.lineWidth=P*2,R(),p.stroke(),p.restore(),{source:B,width:H,height:M,min_x:h,min_y:f}}apply_canvas_size(r,u,n){r.width=u*this._dpr,r.height=n*this._dpr,r.style.width=`${u}px`,r.style.height=`${n}px`}configure_context(){this.ctx.scale(this._dpr,this._dpr),this.ctx.imageSmoothingEnabled=!0,this.ctx.imageSmoothingQuality="high"}reset_transform(){if(this.ctx.resetTransform)this.ctx.resetTransform();else this.ctx.setTransform(1,0,0,1,0,0)}}var Mr={min:1800,mid:1200,max:450};var Tu=(r,u)=>{if(r>5)return u.mid+(u.max-u.mid)*(r-5)/5;if(r<5)return u.mid+(u.mid-u.min)*(r-5)/5;return u.mid},Gr=(r,u)=>{if(Math.sign(r-u.mid)===Math.sign(u.max-u.mid))return(r-u.mid)/(u.max-u.mid)*5+5;return(r-u.mid)/(u.mid-u.min)*5+5},d=(r)=>Tu(r,Mr),wr=(r)=>400*Math.min(1,r/450),Hu=(r)=>{return(1-0.7*((r-5)/5))/2},xr=(r)=>Hu(r)*64;var Br={name:"Hard Rock",acronym:"HR",apply_to_difficulty(r){r.cs=Math.min(r.cs*1.3,10),r.ar=Math.min(r.ar*1.4,10),r.od=Math.min(r.od*1.4,10),r.hp=Math.min(r.hp*1.4,10)}};var Rr={name:"Easy",acronym:"EZ",apply_to_difficulty(r){r.cs*=0.5,r.ar*=0.5,r.od*=0.5,r.hp*=0.5}};var Vu={name:"Double Time",acronym:"DT",get_rate_multiplier:()=>1.5},Du={name:"Nightcore",acronym:"NC",get_rate_multiplier:()=>1.5};var pu={name:"Half Time",acronym:"HT",get_rate_multiplier:()=>0.75};var Mu=0.4,Bu=0.3,Ru={name:"Hidden",acronym:"HD"};var Pr=(r)=>{if(r&(V.DoubleTime|V.Nightcore))return 1.5;if(r&V.HalfTime)return 0.75;return 1},Pu=(r,u)=>{if(u&V.Easy)Rr.apply_to_difficulty(r);if(u&V.HardRock)Br.apply_to_difficulty(r)},yu=(r,u)=>{if(u===1)return r;let n=d(r)/u;return Gr(n,Mr)},cr=(r,u,n,s,t)=>{let e={cs:r,ar:u,od:n,hp:s};Pu(e,t);let o=Pr(t);return e.ar=yu(e.ar,o),e};var gr=(r,u)=>[r[0]+u[0],r[1]+u[1]],O=(r,u)=>[r[0]-u[0],r[1]-u[1]],jr=(r,u)=>[r[0]*u,r[1]*u];var Q=(r)=>Math.sqrt(r[0]*r[0]+r[1]*r[1]);var z=(r,u,n)=>r+(u-r)*n,v=(r,u,n)=>[z(r[0],u[0],n),z(r[1],u[1],n)],y=(r,u,n)=>Math.min(n,Math.max(u,r));var yr={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"]},Fr={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_hitburst:!0,hitburst_duration:180,hitburst_scale:1.2,hitburst_glow_enabled:!1,hitburst_glow_use_combo_color:!0,hitburst_glow_opacity:0.3,slider_body_opacity:0.9,slider_border_opacity:1,slider_tick_opacity:0.75,slider_tick_size:0.1,slider_render_scale:2,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,follow_point_shape:"line",follow_point_mode:"full",follow_point_length:12,follow_point_line_gap:0,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:yr,default_font:'"Trebuchet MS", Verdana, Arial, sans-serif',hit_animation_duration:240,hit_animation_scale:1.2,enable_hit_animations:!0,enable_follow_circle_animations:!0},a=(r)=>{if(!r)return{...Fr};return{...Fr,...r,mania_lane_colors:r.mania_lane_colors?{...yr,...r.mania_lane_colors}:yr}},Z=(r,u,n=1)=>{return`rgba(${r.combo_colors[u%r.combo_colors.length]},${n})`},G=(r,u,n)=>{let s=r.mania_lane_colors[u]??r.mania_lane_colors[4];return s[n%s.length]??"#ffffff"};var C={None:(r)=>r,Out:(r)=>1-Math.pow(1-r,2),In:(r)=>r*r,InOut:(r)=>r<0.5?2*r*r:1-Math.pow(-2*r+2,2)/2,OutCubic:(r)=>1-Math.pow(1-r,3),InCubic:(r)=>r*r*r,OutQuad:(r)=>1-Math.pow(1-r,2),InQuad:(r)=>r*r,OutQuint:(r)=>1-Math.pow(1-r,5),InQuint:(r)=>r*r*r*r*r,OutElastic:(r)=>{let u=2*Math.PI/3;return r===0?0:r===1?1:Math.pow(2,-10*r)*Math.sin((r*10-0.75)*u)+1}};class $r{transforms=[];add(r,u,n,s,t,e=C.None){return this.transforms.push({property:r,start_value:u,end_value:n,start_time:s,end_time:s+t,easing:e}),this}then(){return this}get_value(r,u,n){let s=n;for(let t of this.transforms){if(t.property!==r)continue;if(u<t.start_time)continue;if(u>=t.end_time)s=t.end_value;else{let e=(u-t.start_time)/(t.end_time-t.start_time),o=t.easing(e);s=t.start_value+(t.end_value-t.start_value)*o}}return s}clear(){this.transforms=[]}}class K{backend;skin;hit_object;config;alpha=1;scale=1;rotation=0;x=0;y=0;armed_state=0;transforms=new $r;life_time_start=0;life_time_end=0;constructor(r,u){this.hit_object=r,this.config=u,this.backend=u.backend,this.skin=u.skin;let n=r.data;this.x=n.pos[0],this.y=n.pos[1],this.apply_defaults()}apply_defaults(){let{hit_object:r,config:u}=this,n=r.time-u.preempt;this.life_time_start=n,this.life_time_end=r.end_time+800}is_alive(r){return r>=this.life_time_start&&r<=this.life_time_end}update(r){this.alpha=this.transforms.get_value("alpha",r,1),this.scale=this.transforms.get_value("scale",r,1),this.rotation=this.transforms.get_value("rotation",r,0),this.update_state(r)}update_state(r){if(this.armed_state===0&&r>=this.hit_object.time)this.armed_state=1,this.on_hit(r)}on_hit(r){}render_body_pass(r){}render_head_pass(r){}dispose(){}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 w{state={circle_alpha:0,circle_scale:1,number_alpha:1};update(r,u,n){let s=u-n.preempt;if(r<s){this.reset_pre_hit_state();return}if(r<u){this.update_pre_hit(r,s,u,n);return}let t=_(u,s,u,n);this.update_post_hit(r,u,n,t)}render(r,u,n,s,t,e){let{circle_alpha:o,circle_scale:h,number_alpha:f}=this.state;if(o<=0.01)return;let I=s*h;if(o>0.01){let D=s*u.circle_border_width,T=s*(1-u.circle_border_width/2)*h;if(r.set_alpha(o*u.hit_circle_opacity),r.draw_circle(n[0],n[1],T,t,"rgba(255,255,255,1)",D),f>0.01){let H=s*0.7*h;r.set_alpha(f*u.hit_circle_opacity);let M=u.default_font??'"Trebuchet MS", Verdana, Arial, sans-serif',B=`600 ${H}px ${M}`;r.draw_text(String(e),n[0],n[1],B,"rgba(255,255,255,1)","center","middle")}r.set_alpha(1)}r.set_alpha(1)}get circle_alpha(){return this.state.circle_alpha}reset_pre_hit_state(){this.state.circle_alpha=0,this.state.circle_scale=1,this.state.number_alpha=1}update_pre_hit(r,u,n,s){let t=_(r,u,n,s);this.state.circle_alpha=t,this.state.circle_scale=1,this.state.number_alpha=t}update_post_hit(r,u,n,s){let t=r-u,{skin:e}=n,o=Math.max(90,e.hit_animation_duration*0.75),h=y(t/o,0,1),f=$(n.mods,V.Hidden)?y(s,0,1):y(Math.max(s,0.25),0,1);this.state.circle_alpha=f*(1-C.OutQuad(h));let I=Math.max(90,o*0.85),D=y(t/I,0,1);this.state.circle_scale=z(1,e.hit_animation_scale,C.OutCubic(D)),this.state.number_alpha=this.state.circle_alpha}}var _=(r,u,n,s)=>{let e=y((r-u)/s.fade_in,0,1);if($(s.mods,V.Hidden)){let o=n-s.preempt+s.fade_in,h=s.preempt*0.3;if(r>o){let f=y((r-o)/h,0,1);e*=1-f}}return e};class Cr{state={alpha:0,scale:1};update(r,u,n){if(!n.skin.enable_hitburst){this.state.alpha=0,this.state.scale=1;return}if(r<u){this.state.alpha=0,this.state.scale=1;return}let s=u-n.preempt,t=_(u,s,u,n),e=$(n.mods,V.Hidden)?y(t,0,1):y(Math.max(t,0.25),0,1),o=r-u,h=Math.max(70,n.skin.hitburst_duration),f=y(o/h,0,1),I=1-C.OutQuint(f);this.state.alpha=$(n.mods,V.Hidden)?I*e:I,this.state.scale=z(1,n.skin.hitburst_scale,C.OutCubic(f))}render(r,u,n,s,t){if(!u.enable_hitburst)return;if(this.state.alpha<=0.01)return;if(r.set_alpha(this.state.alpha),r.draw_circle(n[0],n[1],s*this.state.scale,"rgba(255,255,255,1)","transparent",0),u.hitburst_glow_enabled){r.save(),r.set_blend_mode("lighter"),r.set_alpha(this.state.alpha*u.hitburst_glow_opacity);let e=u.hitburst_glow_use_combo_color?t:u.hitburst_glow_color??t;r.draw_circle(n[0],n[1],s*this.state.scale*1.08,e,"transparent",0),r.restore()}}}class rr extends K{visual=new w;hitburst=new Cr;constructor(r,u){super(r,u)}update(r){super.update(r),this.visual.update(r,this.hit_object.time,this.config),this.hitburst.update(r,this.hit_object.time,this.config)}render(r){let{backend:u,skin:n,config:s}=this,{radius:t}=s,e=this.position,o=Z(n,this.combo_number,1);this.visual.render(u,n,e,t,o,this.combo_count),this.hitburst.render(u,n,e,t,o)}}var ur=(r)=>{let{start_time:u,span_duration:n,span_count:s,length:t,tick_distance:e,min_distance_from_end:o,get_position_at_progress:h}=r,f=[],I=[];if(t<=0||n<=0||s<=0)return{ticks:f,repeats:I};let T=Math.min(1e5,t),H=Math.min(Math.max(e,0),T),M=Math.max(0,Math.min(o,T));for(let B=0;B<s;B++){let p=u+B*n,R=B%2===1;if(H>0){let P=Fu(B,p,n,R,T,H,M,h);if(R)P.reverse();f.push(...P)}if(B<s-1){let P=(B+1)%2;I.push({pos:h(P),time:p+n,repeat_index:B,path_progress:P})}}return f.sort((B,p)=>B.time-p.time),{ticks:f,repeats:I}},Fu=(r,u,n,s,t,e,o,h)=>{let f=[];for(let I=e;I<=t;I+=e){if(I>=t-o)break;let D=I/t,T=s?1-D:D;f.push({pos:h(D),time:u+T*n,span_index:r,path_progress:D})}return f};var Sr=240,Nr=1.3,Ar=35,$u=250,Cu=300,x=150,Su=x*4;class l extends K{slider_data;position_path;render_path;path_length;span_duration;body_alpha=0;head_visual=new w;ball_alpha=0;ball_position;follow_alpha=0;follow_scale=1;ticks=[];repeats=[];tick_distance;min_distance_from_end;cached_texture=null;cached_scale=1;tick_entries=[];tick_entries_by_start=[];constructor(r,u,n,s,t,e){super(r,u);this.slider_data=r.data;let o=Math.max(1,u.radius*0.05);this.position_path=n,this.render_path=this.resample_path(n,o),this.span_duration=s,this.tick_distance=t,this.min_distance_from_end=e;let h=this.calculate_path_length();this.path_length=this.slider_data.distance>0?this.slider_data.distance:h,this.ball_position=this.slider_data.pos,this.build_nested_objects(),this.life_time_end=r.end_time+Sr}build_nested_objects(){let{slider_data:r,path_length:u,span_duration:n,hit_object:s}=this,t=Math.max(1,r.repetitions),e=1e5,o=Math.min(1e5,r.distance>0?r.distance:u),h=y(this.tick_distance,0,o);if(o<=0||n<=0){this.ticks=[],this.repeats=[];return}let f=ur({start_time:s.time,span_duration:n,span_count:t,length:o,tick_distance:h,min_distance_from_end:this.min_distance_from_end,get_position_at_progress:(I)=>this.get_position_at_progress(I)});this.ticks=f.ticks,this.repeats=f.repeats,this.build_tick_entries()}calculate_path_length(){let r=0;for(let u=1;u<this.position_path.length;u++)r+=Q(O(this.position_path[u],this.position_path[u-1]));return r}resample_path(r,u){if(r.length<2)return r.slice();let n=[r[0]],s=0,t=[];for(let D=1;D<r.length;D++){let T=Q(O(r[D],r[D-1]));t.push(T),s+=T}if(s<=0)return n;let e=u,o=0,h=0;while(e<s&&h<t.length){let D=t[h],T=r[h],H=r[h+1];if(D>0&&o+D>=e){let M=(e-o)/D;n.push(v(T,H,M)),e+=u}else o+=D,h++}let f=r[r.length-1],I=n[n.length-1];if(I[0]!==f[0]||I[1]!==f[1])n.push(f);return n}update(r){super.update(r),this.calculate_ball_position(r),this.calculate_opacities(r),this.head_visual.update(r,this.hit_object.time,this.config)}calculate_ball_position(r){let{hit_object:u,span_duration:n}=this,s=300,t=300,e=2.4;if(r<u.time){this.ball_alpha=0,this.follow_alpha=0,this.follow_scale=1;return}if(r<=u.end_time){let I=r-u.time,D=Math.max(1,this.slider_data.repetitions),T=Math.min(Math.floor(I/n),D-1),H=y((I-T*n)/n,0,1),M=T%2===1?1-H:H;this.ball_position=this.get_position_at_progress(M),this.ball_alpha=1;let B=y(I/300,0,1),p=C.OutQuint(B);this.follow_alpha=p,this.follow_scale=1+1.4*p;return}let o=r-u.end_time,h=y(o/300,0,1),f=C.OutQuint(h);this.ball_alpha=1-f,this.follow_alpha=1-f,this.follow_scale=2.4-1.4*f}get_position_at_progress(r){let u=r*this.path_length;return this.get_position_at_length(u)}get_position_at_length(r){let u=0;for(let n=1;n<this.position_path.length;n++){let s=Q(O(this.position_path[n],this.position_path[n-1]));if(u+s>=r){let t=(r-u)/s;return v(this.position_path[n-1],this.position_path[n],t)}u+=s}return this.position_path[this.position_path.length-1]}calculate_opacities(r){let{hit_object:u,config:n}=this,s=u.time-n.preempt,t=u.time;if($(n.mods,V.Hidden)){let e=t-n.preempt+n.fade_in;if(r<s)this.body_alpha=0;else if(r<e)this.body_alpha=y((r-s)/n.fade_in,0,1);else if(r<=u.end_time){let o=Math.max(1,u.end_time-e);this.body_alpha=1-y((r-e)/o,0,1)}else this.body_alpha=0}else if(r<s)this.body_alpha=0;else if(r<t)this.body_alpha=y((r-s)/n.fade_in,0,1);else if(r<=u.end_time)this.body_alpha=1;else this.body_alpha=1-y((r-u.end_time)/Sr,0,1)}render(r){if(this.body_alpha<=0&&this.head_visual.circle_alpha<=0&&this.ball_alpha<=0)return;this.render_body(r),this.render_head(),this.render_ball(r)}render_body_pass(r){this.render_body(r)}render_head_pass(r){this.render_head(),this.render_reverse_arrows(r),this.render_ball(r)}render_body(r){if(this.body_alpha<=0.01||this.render_path.length<2)return;let{backend:u}=this;if(this.prepare_body_cache(),this.cached_texture&&this.cached_texture.min_x!==void 0&&this.cached_texture.min_y!==void 0){let n=this.cached_scale;u.set_alpha(this.body_alpha),u.draw_image(this.cached_texture,this.cached_texture.min_x,this.cached_texture.min_y,this.cached_texture.width/n,this.cached_texture.height/n),u.set_alpha(1)}this.render_ticks(r)}prepare_body_cache(){if(this.render_path.length<2)return;let{backend:r,skin:u,config:n}=this,{radius:s}=n,t=(n.scale??1)*(u.slider_render_scale||1);if(!this.cached_texture||this.cached_scale!==t){let e=Z(u,this.combo_number,1),o=u.slider_border_color??"rgba(255,255,255,1)",h=t;this.cached_texture=r.render_slider_to_image(this.render_path,s,o,e,h,u.slider_body_opacity,u.slider_border_opacity),this.cached_scale=t}}has_body_cache(){return this.cached_texture!=null}release_body_cache(){if(this.cached_texture?.source instanceof HTMLCanvasElement)this.cached_texture.source.width=0,this.cached_texture.source.height=0;this.cached_texture=null}estimate_complexity(){return this.render_path.length+this.ticks.length*8+this.repeats.length*16}dispose(){this.release_body_cache(),this.position_path=[],this.render_path=[],this.ticks=[],this.repeats=[],this.tick_entries=[],this.tick_entries_by_start=[]}render_ticks(r){if(this.tick_entries_by_start.length===0)return;let{backend:u,config:n,hit_object:s}=this,{radius:t}=n,e=t*0.12,o=s.time-n.preempt,h=$(n.mods,V.Hidden);for(let f of this.tick_entries_by_start){let I=f.tick,D=r-f.appear_time;if(D<0)continue;if(f.visible_end<r)continue;let T=y(D/x,0,1);if(h&&f.preempt>0){let R=Math.min(f.preempt-x,1000);if(R>0){let P=I.time-R;if(r>=P){let F=y((r-P)/R,0,1);T*=1-F}}}else if(r>I.time){let R=y((r-I.time)/x,0,1);T*=1-R}T*=this.body_alpha;let H=y(D/Su,0,1),B=0.5+0.5*this.ease_out_elastic_half(H),p=e*B;if(T>0.01)u.set_alpha(T),u.draw_circle(I.pos[0],I.pos[1],p,"rgba(255,255,255,0.8)","transparent",0)}u.set_alpha(1)}build_tick_entries(){let{hit_object:r,config:u}=this,n=r.time-u.preempt,s=$(u.mods,V.Hidden);this.tick_entries=this.ticks.map((t)=>{let e=r.time+t.span_index*this.span_duration,o=u.preempt,h=t.span_index>0?200:o*0.66,f=(t.time-e)/2+h,I=t.time-f,D=s?t.time:t.time+x;return{tick:t,appear_time:I,visible_end:D,preempt:f}}),this.tick_entries_by_start=[...this.tick_entries].sort((t,e)=>t.appear_time-e.appear_time)}ease_out_elastic_half(r){if(r<=0)return 0;if(r>=1)return 1;let u=0.3;return Math.pow(2,-10*r)*Math.sin((r-u/4)*(2*Math.PI)/u)+1}render_reverse_arrows(r){if(this.repeats.length===0)return;let{backend:u,config:n,hit_object:s,span_duration:t}=this,{radius:e}=n,o=e*0.6;for(let h of this.repeats){let f=n.preempt;if(h.repeat_index>0)f=t*2;else f+=s.time-(s.time-n.preempt);let I=h.time-f,D=h.repeat_index%2===0;if(r<I||r>h.time+Sr)continue;let T=this.body_alpha*0.9;if(h.repeat_index===0){let P=y((r-I)/150,0,1);T*=C.OutQuint(P)}else if(r<I)T=0;if(r>h.time){let P=Math.min(300,t);T*=1-y((r-h.time)/P,0,1)}if(T<=0.01)continue;let H=this.position_path,M;if(D){let P=H.length-1;M=H[0];for(let F=P;F>=0;F--)if(Math.abs(H[F][0]-h.pos[0])>0.01||Math.abs(H[F][1]-h.pos[1])>0.01){M=H[F];break}}else{M=H[H.length-1];for(let P=0;P<H.length;P++)if(Math.abs(H[P][0]-h.pos[0])>0.01||Math.abs(H[P][1]-h.pos[1])>0.01){M=H[P];break}}let B=Math.atan2(M[1]-h.pos[1],M[0]-h.pos[0]),p=1;if(r<h.time){let P=s.time-n.preempt,F=(r-P)%Cu;if(F<Ar)p=1+(Nr-1)*C.Out(F/Ar);else{let S=(F-Ar)/$u;p=Nr-(Nr-1)*C.Out(y(S,0,1))}}else{let P=Math.min(300,t),F=y((r-h.time)/P,0,1);p=1+0.5*C.Out(F)}let R=o*p;u.save(),u.set_alpha(T),u.translate(h.pos[0],h.pos[1]),u.rotate(B),u.begin_path(),u.move_to(R*0.8,0),u.line_to(-R*0.4,-R*0.5),u.line_to(-R*0.4,R*0.5),u.close_path(),u.fill_path("rgba(255,255,255,0.9)"),u.restore()}}render_head(){if(this.head_visual.circle_alpha<=0.01)return;let{backend:r,skin:u,config:n}=this,{radius:s}=n,t=this.slider_data.pos,e=Z(u,this.combo_number,1);this.head_visual.render(r,u,t,s,e,this.combo_count)}render_ball(r){if(this.ball_alpha<=0.01&&this.follow_alpha<=0.01)return;let{backend:u,skin:n,config:s}=this,{radius:t}=s,e=this.ball_position,o=Z(n,this.combo_number,0.9);if(this.follow_alpha>0.01){let h=t*this.follow_scale;u.set_alpha(this.follow_alpha*n.follow_circle_opacity),u.begin_path(),u.arc_to(e[0],e[1],h,0,Math.PI*2),u.stroke_path(n.follow_circle_color,n.follow_circle_width)}if(n.enable_slider_ball&&this.ball_alpha>0.01)u.set_alpha(this.ball_alpha*n.slider_ball_opacity),u.draw_circle(e[0],e[1],t*0.85,o,"rgba(255,255,255,0.9)",t*0.1);u.set_alpha(1)}}class Or{skin;mods;preempt;fade_in;radius;points=[];lines=[];constructor(r,u,n,s,t){this.skin=r,this.mods=u,this.preempt=n,this.fade_in=s,this.radius=t}update_settings(r,u,n,s){this.mods=r,this.preempt=u,this.fade_in=n,this.radius=s}build(r){this.points=[],this.lines=[];let u=32,n=Math.max(450,this.preempt*0.9);for(let s=0;s<r.length-1;s++){let t=r[s],e=r[s+1];if(U(t)||U(e))continue;if(t.combo_number!==e.combo_number)continue;let o=t.end_pos,h=e.data.pos,f=h[0]-o[0],I=h[1]-o[1],D=Math.sqrt(f*f+I*I);if(D<u*1.5)continue;let T=t.end_time,H=e.time-T;if(H<=0)continue;let M=D>0?1/D:0,B=[f*M,I*M],p=T-n,R=e.time-n,P=T+(R-T)*0.5,F=e.time;if($(this.mods,V.Hidden))P=T+(R-T)*0.3,F=T+(e.time-T)*0.65;this.lines.push({start_pos:o,end_pos:h,dir:B,start_time:T,end_time:e.time,appear_time:p,grow_end_time:R,shrink_start_time:P,shrink_end_time:F});for(let S=u*1.5;S<D-u;S+=u){let A=S/D,N=t.end_time+A*H,m=Math.max(t.end_time,N-n);if($(this.mods,V.Hidden))N=Math.min(N,T+H*0.65);let j=[o[0]+(A-0.1)*f,o[1]+(A-0.1)*I],b=[o[0]+A*f,o[1]+A*I];this.points.push({start_pos:j,end_pos:b,dir:B,fade_in_time:m,fade_out_time:N})}}}render(r,u,n){let s=this.skin.follow_point_shape,t=this.skin.follow_point_mode??"segments",e=this.skin.follow_point_length||this.radius*0.6,o=y(this.skin.follow_point_line_gap??0,0,0.9),h=Math.max(this.fade_in*0.15,50),f=0.2;if(t==="full")for(let I of this.lines){if(r<I.appear_time||r>I.shrink_end_time)continue;let D=0,T=I.start_pos[0],H=I.start_pos[1],M=I.end_pos[0],B=I.end_pos[1],p=Math.hypot(M-T,B-H),R=this.get_alpha_gate(r,I.start_time,I.end_time,n);if(R<=0.01)continue;let P=this.radius*1.05,F=Math.min(P,p*0.22);if(T+=I.dir[0]*F,H+=I.dir[1]*F,M-=I.dir[0]*F,B-=I.dir[1]*F,r<I.grow_end_time){let S=Math.max(1,I.grow_end_time-I.appear_time),A=y((r-I.appear_time)/S,0,1),N=C.OutQuint(A);D=N,M=T+(M-T)*N,B=H+(B-H)*N}else if(r<I.shrink_start_time)D=1;else{let S=Math.max(1,I.shrink_end_time-I.shrink_start_time),A=y((r-I.shrink_start_time)/S,0,1),N=C.InQuint(A);D=1,T=T+(M-T)*N,H=H+(B-H)*N}if(D<=0)continue;if(u.set_alpha(D*0.2*R),s==="line")if(o>0){let S=Math.hypot(M-T,B-H),A=I.dir[0],N=I.dir[1],m=S*o/2,j=(T+M)/2,b=(H+B)/2,tu=j-A*m,eu=b-N*m,ou=j+A*m,hu=b+N*m;u.draw_line(T,H,tu,eu,"rgba(255,255,255,1)",this.skin.follow_point_width,"round","round"),u.draw_line(ou,hu,M,B,"rgba(255,255,255,1)",this.skin.follow_point_width,"round","round")}else u.draw_line(T,H,M,B,"rgba(255,255,255,1)",this.skin.follow_point_width,"round","round");else{let S=this.radius*0.12,A=(I.start_pos[0]+I.end_pos[0])/2,N=(I.start_pos[1]+I.end_pos[1])/2;u.draw_circle(A,N,S,"rgba(255,255,255,1)","transparent",0)}}else for(let I of this.points){if(r<I.fade_in_time||r>I.fade_out_time+h)continue;let D=0,T=1,H=I.end_pos;if(r<I.fade_in_time+h){let B=y((r-I.fade_in_time)/h,0,1),p=C.OutCubic(B);D=p,T=1.5-0.5*p,H=v(I.start_pos,I.end_pos,p)}else if(r<=I.fade_out_time)D=1,T=1,H=I.end_pos;else{let B=y((r-I.fade_out_time)/h,0,1),p=C.OutCubic(B);D=1-p,T=1,H=v(I.start_pos,I.end_pos,1-p)}if(D<=0)continue;let M=this.get_alpha_gate(r,I.fade_in_time+this.preempt,I.fade_out_time,n);if(M<=0.01)continue;if(u.set_alpha(D*0.2*M),s==="line"){let p=e*T/2,R=I.dir[0],P=I.dir[1],F=H[0]-R*p,S=H[1]-P*p,A=H[0]+R*p,N=H[1]+P*p;u.draw_line(F,S,A,N,"rgba(255,255,255,1)",this.skin.follow_point_width,"round","round")}else{let B=this.radius*0.12*T;u.draw_circle(H[0],H[1],B,"rgba(255,255,255,1)","transparent",0)}}u.set_alpha(1)}get_alpha_gate(r,u,n,s){let t=s(r,u),e=s(r,n);return y(Math.min(t,e)/0.7,0,1)}}var Jr=(r,u=0.08)=>{if(r.length<2)return[...r];let n=[];return Qr(r,n,u),n},Qr=(r,u,n)=>{if(Nu(r,n)){if(u.length===0)u.push(r[0]);u.push(r[r.length-1]);return}let s=[],t=[];Ou(r,s,t),Qr(s,u,n),Qr(t,u,n)},Nu=(r,u)=>{if(r.length<=2)return!0;let n=r[0],s=r[r.length-1];for(let t=1;t<r.length-1;t++)if(Au(r[t],n,s)>u)return!1;return!0},Au=(r,u,n)=>{let s=O(n,u),t=s[0]*s[0]+s[1]*s[1];if(t===0)return Q(O(r,u));let e=Math.max(0,Math.min(1,((r[0]-u[0])*s[0]+(r[1]-u[1])*s[1])/t)),o=[u[0]+e*s[0],u[1]+e*s[1]];return Q(O(r,o))},Ou=(r,u,n)=>{let s=r.length,t=[r];for(let e=1;e<s;e++){t[e]=[];for(let o=0;o<s-e;o++)t[e][o]=v(t[e-1][o],t[e-1][o+1],0.5)}for(let e=0;e<s;e++)u.push(t[e][0]),n.push(t[s-1-e][e])},Lr=(r,u,n)=>{let s=O(u,r),t=Q(s);if(t===0)return[r];let e=[s[0]/t,s[1]/t],o=gr(r,jr(e,n));return[r,o]},br=(r,u)=>{if(r.length!==3)return Jr(r);let[n,s,t]=r,e=Qu(n,s,t);if(!e)return Lr(n,t,u);let o=Q(O(n,e)),h=Math.atan2(n[1]-e[1],n[0]-e[0]),f=Math.atan2(t[1]-e[1],t[0]-e[0]),D=(s[0]-n[0])*(t[1]-n[1])-(s[1]-n[1])*(t[0]-n[0])>0,T=f-h;if(D&&T<0)T+=2*Math.PI;if(!D&&T>0)T-=2*Math.PI;let H=Math.abs(T)*o,M=2;if(o*2>0.1){let p=Math.abs(T),R=2*Math.acos(1-0.1/o);if(M=Math.max(2,Math.ceil(p/R)),M>=1000)M=1000}let B=[];for(let p=0;p<=M;p++){let R=p/M,P=h+T*R;B.push([e[0]+o*Math.cos(P),e[1]+o*Math.sin(P)])}return B},Qu=(r,u,n)=>{let s=2*(r[0]*(u[1]-n[1])+u[0]*(n[1]-r[1])+n[0]*(r[1]-u[1]));if(Math.abs(s)<0.001)return null;let t=((r[0]*r[0]+r[1]*r[1])*(u[1]-n[1])+(u[0]*u[0]+u[1]*u[1])*(n[1]-r[1])+(n[0]*n[0]+n[1]*n[1])*(r[1]-u[1]))/s,e=((r[0]*r[0]+r[1]*r[1])*(n[0]-u[0])+(u[0]*u[0]+u[1]*u[1])*(r[0]-n[0])+(n[0]*n[0]+n[1]*n[1])*(u[0]-r[0]))/s;return[t,e]},ir=(r)=>{if(r.length<2)return[...r];let u=[];for(let n=0;n<r.length-1;n++){let s=r[Math.max(0,n-1)],t=r[n],e=r[n+1],o=r[Math.min(r.length-1,n+2)],h=Q(O(e,t)),f=Math.max(8,Math.ceil(h/3));for(let I=0;I<=f;I++){let D=I/f;u.push(Ju(s,t,e,o,D))}}return u},Ju=(r,u,n,s,t)=>{let e=t*t,o=e*t;return[0.5*(2*u[0]+(-r[0]+n[0])*t+(2*r[0]-5*u[0]+4*n[0]-s[0])*e+(-r[0]+3*u[0]-3*n[0]+s[0])*o),0.5*(2*u[1]+(-r[1]+n[1])*t+(2*r[1]-5*u[1]+4*n[1]-s[1])*e+(-r[1]+3*u[1]-3*n[1]+s[1])*o)]};var kr=(r)=>{let u;if(r.path_type==="L")u=Lr(r.pos,r.control_points[0],r.distance);else{let n=[r.pos,...r.control_points];switch(r.path_type){case"P":u=br(n,r.distance);break;case"C":u=ir(n);break;default:u=Lu(n);break}}return vu(u,r.distance)},dr=(r)=>{if(!r.computed_path||r.computed_path.length===0)return r.pos;return r.repetitions%2===0?r.pos:r.computed_path[r.computed_path.length-1]},Lu=(r)=>{let u=[],n=[r[0]];for(let t=1;t<r.length;t++){let[e,o]=[r[t-1],r[t]];if(e[0]===o[0]&&e[1]===o[1]){if(n.length>1)u.push(n);n=[o]}else n.push(o)}if(n.length>1)u.push(n);let s=[];for(let t of u)s.push(...Jr(t));return s},vu=(r,u)=>{if(r.length<2)return r;let n=[r[0]],s=0,t=null,e=!1;for(let o=1;o<r.length;o++){let h=Q(O(r[o],r[o-1])),f=O(r[o],r[o-1]);if(h>0)t=[f[0]/h,f[1]/h];if(h===0)continue;if(s+h>=u){let I=u-s;n.push(v(r[o-1],r[o],I/h)),s=u,e=!0;break}s+=h,n.push(r[o])}if(!e&&s<u&&t){let o=u-s,h=n[n.length-1];n.push([h[0]+t[0]*o,h[1]+t[1]*o])}return n};var nr=(r,u,n)=>{if(r<=0)return 0;let s=u.Difficulty.SliderMultiplier;return r*n.base_beat_length/(100*s*n.sv_multiplier)},sr=(r,u)=>{let n=u.sv_multiplier||1,s=r.Difficulty.SliderMultiplier,t=r.Difficulty.SliderTickRate,e=100*s*n,o=r.version<8?1/n:1,h=e/t*o,f=e/u.base_beat_length;return{tick_distance:h,min_distance_from_end:f*10}};class c{points;index=0;last_time=Number.NEGATIVE_INFINITY;base_beat_length=600;sv_multiplier=1;constructor(r){if(this.points=r,r.length>0&&r[0].uninherited===1&&r[0].beatLength>0)this.base_beat_length=r[0].beatLength}reset(){this.index=0,this.last_time=Number.NEGATIVE_INFINITY,this.base_beat_length=600,this.sv_multiplier=1}get_state_at(r){if(this.points.length===0)return{base_beat_length:600,sv_multiplier:1};if(r<this.last_time)this.reset();for(let u=this.index;u<this.points.length;u++){let n=this.points[u];if(n.time>r)break;if(n.uninherited===1&&n.beatLength>0)this.base_beat_length=n.beatLength,this.sv_multiplier=1;else if(n.uninherited===0&&n.beatLength<0){let s=-100/n.beatLength;if(s>0)this.sv_multiplier=s}this.index=u}return this.last_time=r,this.sv_multiplier=y(this.sv_multiplier,0.1,10),{base_beat_length:this.base_beat_length,sv_multiplier:this.sv_multiplier}}}var tr=(r)=>{if(r.length===0)return r;return r.sort((u,n)=>{if(u.time!==n.time)return u.time-n.time;if(u.uninherited===n.uninherited)return 0;return u.uninherited>n.uninherited?-1:1})};var er=(r)=>{let u=[];for(let n of r.HitObjects){let s={...n,end_time:n.endTime||n.time,end_pos:[n.x,n.y],combo_number:0,combo_count:0,data:{pos:[n.x,n.y]}};if(n.type&J.Slider){let t={pos:[n.x,n.y],path_type:n.curveType||"L",control_points:(n.curvePoints||[]).map((e)=>[e.x,e.y]),repetitions:n.slides||1,distance:n.length||0};s.data=t}else if(n.type&J.Spinner){let t=n.endTime||n.time;s.data={end_time:t},s.end_time=t,s.end_pos=[256,192]}else if(n.type&J.Hold){let t=n.endTime||n.time;s.data={pos:[n.x,n.y],end_time:t},s.end_time=t}u.push(s)}return u};var vr=(r)=>384-r,qu=1500,Zu=20000,ar=1.5,Xu=8,mu=120;class or extends Y{radius=32;preempt=1200;fade_in=600;timing_points=[];timing_resolver=null;drawables=[];slider_drawables=[];slider_cache_lru=[];precompute_focus_time=0;precompute_handle=null;precompute_pause_until=0;last_seek_prefetch_at=0;drawable_config;follow_point_renderer;constructor(r,u,n=0,s=q){super(r,u,n,s);this.follow_point_renderer=new Or(u,n,this.preempt,this.fade_in,this.radius)}initialize(r){this.release_drawables(),this.beatmap=r,this.objects=er(r).sort((s,t)=>s.time-t.time),this.timing_points=tr([...r.TimingPoints]),this.timing_resolver=new c(this.timing_points);let u=r.Difficulty.ApproachRate>=0?r.Difficulty.ApproachRate:r.Difficulty.OverallDifficulty,n=cr(r.Difficulty.CircleSize,u,0,0,this.mods);if(this.radius=xr(n.cs),this.preempt=d(n.ar),this.fade_in=wr(this.preempt),$(this.mods,V.Hidden))this.fade_in=this.preempt*0.4;this.follow_point_renderer.update_settings(this.mods,this.preempt,this.fade_in,this.radius),this.preprocess_objects(),this.follow_point_renderer.build(this.objects),this.create_drawables()}set_mods(r){if(this.mods=r,this.beatmap)this.initialize(this.beatmap)}preprocess_objects(){let r=0,u=1;if(this.timing_resolver)this.timing_resolver.reset();for(let n of this.objects){if(Ur(n))r=(r+1)%this.skin.combo_colors.length,u=1;else u++;if(n.combo_number=r,n.combo_count=u,Vr(n)){let s=n.data;if($(this.mods,V.HardRock))s.pos=[s.pos[0],vr(s.pos[1])],s.control_points=s.control_points.map((o)=>[o[0],vr(o[1])]);s.computed_path=kr(s);let t=this.timing_resolver?.get_state_at(n.time)??{base_beat_length:600,sv_multiplier:1},e=nr(s.distance,this.beatmap,t);s.duration=e,n.end_time=n.time+e*s.repetitions,n.end_pos=dr(s)}else if(U(n))n.end_pos=[256,192];else{let s=n.data;if($(this.mods,V.HardRock))s.pos=[s.pos[0],vr(s.pos[1])];n.end_pos=s.pos}}}create_drawables(){this.release_drawables();let r=this.config.use_high_dpi?window.devicePixelRatio||1:1;if(this.drawable_config={backend:this.backend,skin:this.skin,preempt:this.preempt,fade_in:this.fade_in,radius:this.radius,scale:this.config.scale*r,mods:this.mods},this.timing_resolver)this.timing_resolver.reset();for(let u of this.objects)if(Xr(u))this.drawables.push(new rr(u,this.drawable_config));else if(Vr(u)){let n=u.data,s=n.computed_path||[],t=n.duration||0,e=this.timing_resolver?.get_state_at(u.time)??{base_beat_length:600,sv_multiplier:1},{tick_distance:o,min_distance_from_end:h}=sr(this.beatmap,e),f=new l(u,this.drawable_config,s,t,o,h);this.drawables.push(f),this.slider_drawables.push(f)}}render(r){let{backend:u,config:n}=this;if(this.precompute_focus_time=r,performance.now()>=this.precompute_pause_until)this.process_precompute_queue(r,ar,!1);this.render_background(),u.save(),u.translate(n.offset_x,n.offset_y),u.scale(n.scale,n.scale),this.render_playfield(),this.render_grid();let s=[];for(let t=this.drawables.length-1;t>=0;t--){let e=this.drawables[t];if(e.is_alive(r))s.push(e)}this.follow_point_renderer.render(r,u,(t,e)=>this.get_circle_alpha(t,e));for(let t of this.objects)if(U(t)){let e=t.time-this.preempt;if(r>=e&&r<=t.end_time+200)this.draw_spinner(t,r)}for(let t of s)t.update(r);for(let t of s)if(t instanceof l){if(!t.has_body_cache())t.prepare_body_cache();this.touch_slider_cache(t),t.render_body_pass(r)}for(let t of s)if(t instanceof l)t.render_head_pass(r);else t.render(r);if(!$(this.mods,V.Hidden)&&this.skin.enable_approach_circle){for(let t of s)if(r<=t.start_time)this.draw_approach_circle(t,r)}u.restore()}precompute(r=0){this.precompute_focus_time=r,this.process_precompute_queue(r,Xu,!0),this.start_precompute_loop()}on_seek(r){this.precompute_focus_time=r,this.precompute_pause_until=performance.now()+90;let u=performance.now();if(u-this.last_seek_prefetch_at<48)return;this.last_seek_prefetch_at=u,this.process_precompute_queue(r,2.5,!1)}dispose(){this.stop_precompute_loop(),this.release_drawables(),this.timing_points=[],this.timing_resolver=null,super.dispose()}release_drawables(){this.stop_precompute_loop();for(let r of this.drawables)r.dispose();this.drawables=[],this.slider_drawables=[],this.slider_cache_lru=[]}start_precompute_loop(){if(this.precompute_handle!==null)return;let r=()=>{if(this.precompute_handle=null,!this.has_uncached_sliders())return;this.process_precompute_queue(this.precompute_focus_time,ar,!1),this.precompute_handle=window.requestAnimationFrame(r)};this.precompute_handle=window.requestAnimationFrame(r)}stop_precompute_loop(){if(this.precompute_handle!==null)window.cancelAnimationFrame(this.precompute_handle),this.precompute_handle=null}has_uncached_sliders(){for(let r of this.slider_drawables)if(!r.has_body_cache())return!0;return!1}process_precompute_queue(r,u,n){if(this.slider_drawables.length==0)return;let s=performance.now()+u;while(performance.now()<s){let t=this.pick_next_slider_for_precompute(r,n);if(!t)break;t.prepare_body_cache(),this.touch_slider_cache(t),this.enforce_slider_cache_limit()}}pick_next_slider_for_precompute(r,u){let n=null,s=-1/0;for(let t of this.slider_drawables){if(t.has_body_cache())continue;let e=t.start_time-r,o=e>=-qu&&e<=Zu,h=t.estimate_complexity();if(o){let f=Math.abs(e)*0.02,I=h-f;if(I>s)s=I,n=t}else if(n==null&&u){if(h>s)s=h,n=t}}return n}touch_slider_cache(r){if(!r.has_body_cache())return;let u=this.slider_cache_lru.indexOf(r);if(u>=0)this.slider_cache_lru.splice(u,1);this.slider_cache_lru.push(r)}enforce_slider_cache_limit(){while(this.slider_cache_lru.length>mu){let r=this.slider_cache_lru.shift();if(!r)break;r.release_body_cache()}}draw_approach_circle(r,u){let n=r.position,s=r.start_time-this.preempt,t=Math.min(this.fade_in*2,this.preempt),o=y((u-s)/t,0,1)*this.skin.approach_circle_opacity,f=4-3*y((u-s)/this.preempt,0,1),I=Z(this.skin,r.combo_number,1);this.backend.save(),this.backend.set_alpha(o),this.backend.draw_circle(n[0],n[1],this.radius*f,"transparent",I,this.radius*this.skin.approach_circle_width),this.backend.restore()}get_circle_alpha(r,u){let n=u-this.preempt;if(r<n)return 0;let s=y((r-n)/this.fade_in,0,1);if($(this.mods,V.Hidden)){let t=u-this.preempt+this.fade_in,e=this.preempt*0.3;if(r>t){let o=y((r-t)/e,0,1);s*=1-o}}return s}draw_spinner(r,u){let n=r.time-this.preempt,s=y((u-n)/this.fade_in,0,1);if(u>r.end_time)s=1-C.OutCubic(y((u-r.end_time)/200,0,1));if(s<=0)return;let t=256,e=192,o=r.end_time-r.time,h=y((u-r.time)/o,0,1);this.backend.set_alpha(s);let f=this.skin.spinner_size*(1-h);if(f>5)this.backend.begin_path(),this.backend.arc_to(t,e,f,0,Math.PI*2),this.backend.stroke_path("rgba(255,255,255,0.6)",4);this.backend.draw_circle(t,e,this.skin.spinner_size,"rgba(0,0,0,0.2)"),this.backend.draw_circle(t,e,12,"white")}}var _r=11485,ru=20;class hr extends Y{key_count=4;scroll_time=_r/ru;hd_coverage=0.25;fi_coverage=0.6;gradient_ratio=0.2;constructor(r,u,n=0,s=q){super(r,u,n,s);this.update_scroll_time()}initialize(r){this.beatmap=r,this.objects=er(r),this.key_count=Math.floor(r.Difficulty.CircleSize)}set_mods(r){this.mods=r,this.update_scroll_time()}update_scroll_time(){let r=Pr(this.mods);this.scroll_time=_r/(ru*r)}time_to_y(r){let u=this.skin.mania_hit_position,n=r/this.scroll_time;return u-n*u}render(r){let{backend:u,config:n,skin:s,key_count:t}=this;this.render_background();let e=t*s.mania_lane_width,o=Math.floor((Dr-e)/2),h=s.mania_hit_position;u.save(),u.translate(n.offset_x,n.offset_y),u.scale(n.scale,n.scale),this.render_playfield(e,pr,o),this.draw_lane_keys(r,o),this.draw_judgment_line(o),u.save(),u.begin_path(),u.rect(o,0,e,h),u.clip(),u.set_alpha(0.7),u.draw_rect(o,0,e,h,"#000000"),u.set_alpha(1);for(let f of this.objects){if(f.end_time<r)continue;if(mr(f))this.draw_hold_note(f,r,o);else this.draw_note(f,r,o)}if($(this.mods,V.Hidden)||$(this.mods,V.FadeIn)){let f=$(this.mods,V.Hidden)?this.hd_coverage:this.fi_coverage,I=h*f,D=h*this.gradient_ratio;if($(this.mods,V.Hidden)){let T=h-I,H=D/I,M=u.create_linear_gradient(o,T,o,h,[{offset:0,color:"rgba(0,0,0,0)"},{offset:H*0.4,color:"rgba(0,0,0,0.3)"},{offset:H*0.7,color:"rgba(0,0,0,0.75)"},{offset:H*0.9,color:"rgba(0,0,0,0.95)"},{offset:H,color:"rgba(0,0,0,1)"},{offset:1,color:"rgba(0,0,0,1)"}]);u.draw_rect_gradient(o,T,e,I,M)}else{let T=(I-D)/I,H=u.create_linear_gradient(o,0,o,I,[{offset:0,color:"rgba(0,0,0,1)"},{offset:T,color:"rgba(0,0,0,1)"},{offset:T+(1-T)*0.1,color:"rgba(0,0,0,0.95)"},{offset:T+(1-T)*0.4,color:"rgba(0,0,0,0.75)"},{offset:T+(1-T)*0.7,color:"rgba(0,0,0,0.3)"},{offset:1,color:"rgba(0,0,0,0)"}]);u.draw_rect_gradient(o,0,e,I,H)}}u.restore(),u.restore()}get_lane(r){let u=r.data.pos,n=Math.floor(u[0]*this.key_count/512);if($(this.mods,V.Mirror))n=this.key_count-1-n;return n}draw_note(r,u,n){let{backend:s,skin:t,key_count:e}=this,o=this.get_lane(r),h=t.mania_lane_width,f=t.mania_note_height,I=t.mania_lane_spacing,D=r.time-u,T=this.time_to_y(D);if(T<-f-64)return;let H=n+o*h,M=G(t,e,o);s.set_alpha(1),s.draw_rect(H+I,T-f,h-2*I,f,M)}draw_hold_note(r,u,n){let{backend:s,skin:t,key_count:e}=this,o=r.data,h=this.get_lane(r),f=t.mania_lane_width,I=t.mania_note_height,D=t.mania_lane_spacing,T=r.time-u,H=o.end_time-u,M=this.time_to_y(T),B=this.time_to_y(H),p=n+h*f,R=G(t,e,h);if(B<-64&&M<-64)return;let P=B,S=(T<0?t.mania_hit_position:M)-P;if(S>0)s.set_alpha(0.9),s.draw_rect(p+D,P,f-2*D,S,R);if(T>=0)s.set_alpha(1),s.draw_rect(p+D,M-I,f-2*D,I,R);s.set_alpha(1)}draw_judgment_line(r){let{backend:u,skin:n,key_count:s}=this,t=n.mania_lane_width,e=n.mania_hit_position;u.draw_rect(r,e-1,t*s,2,"#ffffff")}draw_lane_keys(r,u){let{backend:n,skin:s,key_count:t}=this,{mania_lane_width:e,mania_hit_position:o,mania_lane_spacing:h,mania_note_height:f}=s,I=f+5,D=new Set,T=50;for(let H of this.objects)if(r>=H.time-50&&r<=H.end_time+50)D.add(this.get_lane(H));for(let H=0;H<t;H++){let M=D.has(H),B=u+H*e,p=G(s,t,H);if(n.set_alpha(0.3),n.draw_rect(B+h,o,e-2*h,I,p),M)n.set_alpha(1),n.draw_rect(B+h,o,e-2*h,I,"#ff6666")}n.set_alpha(1)}}class g{audio_context;gain_node;constructor(r){this.audio_context=r,this.gain_node=this.audio_context.createGain(),this.gain_node.connect(this.audio_context.destination)}set_volume(r){this.gain_node.gain.value=y(r,0,1)}dispose_audio_node(){this.gain_node.disconnect()}}class fr extends g{audio_element=null;media_source_node=null;object_url=null;pause_time=0;speed=1;_is_playing=!1;_duration=0;_is_loaded=!1;constructor(r){super(r)}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.audio_element)return this.pause_time;if(!this._is_playing)return this.pause_time;return this.audio_element.currentTime*1000}async load(r,u=0){this.stop(),this.release_media();try{this.speed=E(u);let n=new Blob([r]),s=URL.createObjectURL(n),t=new Audio(s);t.preload="metadata",t.playbackRate=this.speed,t.preservesPitch=!1,this.audio_element=t,this.object_url=s,this.media_source_node=this.audio_context.createMediaElementSource(t),this.media_source_node.connect(this.gain_node),await new Promise((e,o)=>{let h=()=>{t.removeEventListener("loadedmetadata",h),t.removeEventListener("error",f),e()},f=()=>{t.removeEventListener("loadedmetadata",h),t.removeEventListener("error",f),o(Error("Failed to load audio metadata"))};t.addEventListener("loadedmetadata",h,{once:!0}),t.addEventListener("error",f,{once:!0})}),this._duration=Math.max(0,(this.audio_element.duration||0)*1000),this._is_loaded=!0,this.pause_time=0,this.audio_element.onended=()=>{this._is_playing=!1,this.pause_time=this._duration}}catch(n){throw console.error("Failed to load audio data",n),this.release_media(),n}}async play(r){if(!this.audio_element){console.warn("[AudioController] Cannot play: not loaded");return}let u=r!==void 0?r/1000:this.pause_time/1000,n=this.audio_element.duration||this._duration/1000,s=Math.max(0,Math.min(u,n));if(s>=n){this.pause_time=n*1000;return}this.audio_element.currentTime=s,this.audio_element.playbackRate=this.speed;try{await this.audio_element.play(),this._is_playing=!0}catch(t){throw this._is_playing=!1,t}}pause(){if(!this.audio_element||!this._is_playing)return;this.pause_time=this.current_time,this.audio_element.pause(),this._is_playing=!1}seek(r){let u=Math.max(0,Math.min(r,this._duration));if(this.pause_time=u,!this.audio_element)return;this.audio_element.currentTime=u/1000}stop(){if(this.pause(),this.pause_time=0,this.audio_element)this.audio_element.currentTime=0}get_host_time(r){let u=r-this.current_time;return this.audio_context.currentTime+u/1000/this.speed}set_speed(r){if(this.speed=r,this.audio_element)this.audio_element.playbackRate=r}dispose(){this.stop(),this.release_media(),this._is_loaded=!1,this._duration=0,this.pause_time=0,this._is_playing=!1,this.dispose_audio_node()}release_media(){if(this.audio_element)this.audio_element.pause(),this.audio_element.onended=null,this.audio_element.src="",this.audio_element.load(),this.audio_element=null;if(this.media_source_node)this.media_source_node.disconnect(),this.media_source_node=null;if(this.object_url)URL.revokeObjectURL(this.object_url),this.object_url=null}}class Ir{video=null;object_url=null;_offset=0;get element(){return this.video}get offset(){return this._offset}async load(r,u=0){this.dispose(),this._offset=u,this.video=document.createElement("video"),this.video.muted=!0,this.video.loop=!1,this.video.playsInline=!0,this.object_url=URL.createObjectURL(r),this.video.src=this.object_url,await new Promise((n,s)=>{if(!this.video)return s(Error("No video element"));this.video.onloadeddata=()=>n(),this.video.onerror=()=>s(Error("Failed to load video"))})}sync(r){if(!this.video)return;let u=(r-this._offset)/1000;if(u<0){if(!this.video.paused)this.video.pause();return}if(Math.abs(this.video.currentTime-u)>0.1)this.video.currentTime=u}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(r){if(!this.video)return;let u=Math.max(0,(r-this._offset)/1000);this.video.currentTime=u}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 X extends g{static default_samples=new Map;static default_loads=new Map;custom_samples=new Map;constructor(r){super(r)}async load_samples(r){this.custom_samples.clear(),await this.load_into_cache(r,this.custom_samples,!1)}async load_samples_from_files(r){this.custom_samples.clear(),await this.load_files_into_cache(r,this.custom_samples)}async load_default_samples(r){await this.load_into_cache(r,X.default_samples,!0)}clear(){this.custom_samples.clear()}play(r,u,n,s,t=100,e,o=0){let h=this.get_set_name(r),f=this.get_set_name(u);if(e){let I=e.toLowerCase().replace(/\.(wav|mp3|ogg)$/,"");if(this.play_buffer(I,t,o))return}if(this.play_sound(h,"hitnormal",s,t,o),n&i.Whistle)this.play_sound(f,"hitwhistle",s,t,o);if(n&i.Finish)this.play_sound(f,"hitfinish",s,t,o);if(n&i.Clap)this.play_sound(f,"hitclap",s,t,o)}play_sample(r,u,n,s=100,t=0){let e=this.get_set_name(r);this.play_sound(e,u,n,s,t)}play_sound(r,u,n,s,t){let e=!1;if(n>1)e=this.play_buffer(`${r}-${u}${n}`,s,t);if(!e)this.play_buffer(`${r}-${u}`,s,t)}play_buffer(r,u,n){let s=this.custom_samples.get(r)??X.default_samples.get(r);if(!s)return!1;let t=this.audio_context.createBufferSource();t.buffer=s;let e=this.audio_context.createGain();return e.gain.value=u/100,t.connect(e),e.connect(this.gain_node),t.start(n),!0}get_set_name(r){switch(r){case 3:return"drum";case 2:return"soft";default:return"normal"}}get_sample_key_from_url(r){let n=r.split("?")[0].split("#")[0].split("/").pop();if(!n)return null;if(!n.endsWith(".wav")&&!n.endsWith(".mp3")&&!n.endsWith(".ogg"))return null;return n.toLowerCase().replace(/\.(wav|mp3|ogg)$/,"")}async load_into_cache(r,u,n){if(r.length==0)return;let s=[],t=r.map(async(e)=>{let o=this.get_sample_key_from_url(e);if(!o){s.push(e);return}if(u.has(o))return;if(!n){await this.load_single_sample(e,o,u,s);return}let h=X.default_loads.get(o);if(h){await h;return}let f=this.load_single_sample(e,o,u,s).finally(()=>{X.default_loads.delete(o)});X.default_loads.set(o,f),await f});if(await Promise.all(t),s.length>0)console.warn(`[HitsoundController] Failed to load ${s.length} hitsounds`)}async load_single_sample(r,u,n,s){try{let t=await fetch(r);if(!t.ok){s.push(r);return}let e=await t.arrayBuffer();if(e.byteLength<128){s.push(r);return}let o=await this.audio_context.decodeAudioData(e.slice(0));n.set(u,o)}catch{s.push(r)}}async load_files_into_cache(r,u){if(r.size==0)return;let n=[],s=[...r.entries()].map(async([t,e])=>{let o=this.get_sample_key_from_url(t);if(!o)return;if(u.has(o))return;if(e.byteLength<128){n.push(t);return}try{let h=await this.audio_context.decodeAudioData(e.slice(0));u.set(o,h)}catch{n.push(t)}});if(await Promise.all(s),n.length>0)console.warn(`[HitsoundController] Failed to load ${n.length} hitsounds`)}dispose(){this.custom_samples.clear(),this.dispose_audio_node()}}class qr{files;audio_filename;background_filename;video_filename;video_offset;constructor(r){this.files=r.files,this.audio_filename=r.audio_filename,this.background_filename=r.background_filename,this.video_filename=r.video_filename,this.video_offset=r.video_offset}resolve(){let r=this.audio_filename?this.find_file(this.audio_filename):void 0,u=this.background_filename?this.find_file(this.background_filename):void 0,n=this.video_filename?this.find_file(this.video_filename):void 0;return{audio:r,background:u?new Blob([u]):void 0,video:n?new Blob([n]):void 0,video_offset:this.video_offset}}find_file(r){if(this.files.has(r))return this.files.get(r);let u=r.toLowerCase();for(let[n,s]of this.files)if(n.toLowerCase()===u)return s;return}}var Uu=100,Wu=20;class Zr{audio;hitsounds;resources=null;timing_points=[];timing_resolver=null;audio_offset=20;next_hit_object_index=0;constructor(r,u){this.audio=r;this.hitsounds=u}set_context(r,u,n,s){this.resources=r,this.timing_points=u,this.timing_resolver=n,this.audio_offset=s,this.next_hit_object_index=0}set_audio_offset(r){this.audio_offset=r}update_hit_index(r){if(!this.resources?.beatmap)return;let u=this.resources.beatmap.HitObjects;if(this.next_hit_object_index>0&&u[this.next_hit_object_index-1].time>r)this.next_hit_object_index=0;while(this.next_hit_object_index<u.length&&u[this.next_hit_object_index].time<r)this.next_hit_object_index++}schedule_hitsounds(r){if(!this.resources?.beatmap||!this.audio.is_playing)return;let u=this.resources.beatmap.HitObjects,n=r+Uu;while(this.next_hit_object_index<u.length&&u[this.next_hit_object_index].time<=n){let s=u[this.next_hit_object_index];if(s.time>=r-Wu)this.play_hitsound(s);this.next_hit_object_index++}}play_hitsound(r){let u=this.get_timing_point(r.time),n=this.resolve_sample_settings(u,r.hitSample);if((r.type&J.Slider)===0){this.play_node_hitsound(r.time,r.hitSound,n,n.custom_filename);return}let s=this.resources?.beatmap;if(!s)return;let t=this.timing_resolver?.get_state_at(r.time)??{base_beat_length:600,sv_multiplier:1},e=r.length??0,o=nr(e,s,t),h=Math.max(1,r.slides||1);if(o<=0||e<=0){this.play_node_hitsound(r.time,r.hitSound,n,n.custom_filename);return}let f=r.edgeSounds??[],I=r.edgeSets??[];for(let H=0;H<=h;H++){let M=r.time+o*H,B=f.length>0?f[H]??0:H==0?r.hitSound:0,p=I.length>0?I[H]:void 0,R=this.resolve_edge_sets(n,p),P=H==0?n.custom_filename:void 0;this.play_node_hitsound(M,B,{...n,...R},P)}let D=sr(s,t),T=ur({start_time:r.time,span_duration:o,span_count:h,length:e,tick_distance:D.tick_distance,min_distance_from_end:D.min_distance_from_end,get_position_at_progress:()=>[0,0]});for(let H of T.ticks){let M=this.audio.get_host_time(H.time+this.audio_offset);this.hitsounds.play_sample(n.normal_set,"slidertick",n.index,n.volume,M)}}play_node_hitsound(r,u,n,s){let t=this.audio.get_host_time(r+this.audio_offset);this.hitsounds.play(n.normal_set,n.addition_set,u,n.index,n.volume,s,t)}resolve_sample_settings(r,u){let{volume:n,sampleSet:s,sampleSet:t,sampleIndex:e}=r,o=void 0;if(u){if(u.normalSet!==0){if(s=u.normalSet,u.additionSet===0)t=s}if(u.additionSet!==0)t=u.additionSet;if(u.index!==0)e=u.index;if(u.volume!==0)n=u.volume;o=u.filename||void 0}if(s===0)s=1;if(t===0)t=s;return{normal_set:s,addition_set:t,index:e,volume:n,custom_filename:o}}resolve_edge_sets(r,u){let{normal_set:n,addition_set:s}=r;if(u){let{normalSet:t,additionSet:e}=u;if(t!==0)n=t;if(e!==0)s=e;else s=n}if(n===0)n=1;if(s===0)s=n;return{normal_set:n,addition_set:s}}get_timing_point(r){let u=this.timing_points;if(u.length==0)return{time:0,beatLength:600,meter:4,sampleSet:1,sampleIndex:1,volume:100,uninherited:1,effects:0};for(let n=u.length-1;n>=0;n--)if(u[n].time<=r)return u[n];return u[0]}}var Yu=[".wav",".mp3",".ogg"],zu=/^(normal|soft|drum)-(hitnormal|hitwhistle|hitfinish|hitclap|slidertick|sliderslide|sliderwhistle)\d*$/i,uu=(r,u,n)=>{let s=new Set;for(let o of r.HitObjects){let h=o.hitSample?.filename?.trim();if(h)s.add(h.toLowerCase())}let t=new Map,e=n?.toLowerCase();for(let[o,h]of u){let f=o.toLowerCase();if(!Ku(f))continue;if(e&&f==e)continue;let I=lu(f),D=I.replace(/\.(wav|mp3|ogg)$/,""),T=zu.test(D),H=s.has(I)||s.has(D)||s.has(f);if(T||H)t.set(o,h)}return t},Ku=(r)=>{for(let u of Yu)if(r.endsWith(u))return!0;return!1},lu=(r)=>{let u=r.split("?")[0].split("#")[0];return u.split("/").pop()??u};var Gu=0.42,wu=30;class su{backend;renderer=null;audio_context;audio;hitsounds;video=null;resources=null;animation_frame=null;skin;mods;renderer_config;start_offset;start_mode;custom_start_time;music_volume;hitsound_volume;audio_offset;background_url=null;listeners=new Map;is_loaded_flag=!1;hitsound_scheduler;timing_points=[];timing_resolver=null;resize_observer=null;key_handler=null;options;enable_fps_counter=!1;fps_frame_count=0;fps_last_update=0;current_fps=0;time_smoothing=0.1;smoothed_delta=0;max_frame_delta=100;last_timestamp=0;smooth_time=0;constructor(r){this.options=r,this.backend=r.backend??new k,this.skin=a(r.skin),this.mods=r.mods??0,this.renderer_config={...q,...r.renderer_config},this.calculate_layout(r.canvas.width,r.canvas.height,r.playfield_scale),this.start_mode=r.start_mode??(Number.isFinite(r.start_time)?"custom":"preview"),this.custom_start_time=Number.isFinite(r.start_time)?Math.max(0,r.start_time):null,this.start_offset=0,this.music_volume=r.volume??0.5,this.hitsound_volume=r.hitsound_volume??0.25,this.audio_offset=r.audio_offset??20,this.backend.initialize(r.canvas,this.renderer_config.use_high_dpi);let u=window.AudioContext||window.webkitAudioContext;if(this.audio_context=new u,this.audio=new fr(this.audio_context),this.hitsounds=new X(this.audio_context),this.hitsound_scheduler=new Zr(this.audio,this.hitsounds),this.audio.set_volume(this.music_volume),this.hitsounds.set_volume(this.hitsound_volume),r.auto_resize)this.setup_auto_resize();this.enable_fps_counter=r.enable_fps_counter??!1,this.fps_last_update=performance.now();let n=r.time_smoothing;if(Number.isFinite(n))this.time_smoothing=Math.max(0,Math.min(1,n));let s=r.max_frame_delta;if(Number.isFinite(s))this.max_frame_delta=Math.max(10,s)}async load_osz(r,u){try{let s=await new W().load_osz(r,{difficulty:u});return this.resources=s,this.setup()}catch(n){let s=n instanceof Error?n.message:String(n);return this.emit("error","INVALID_BEATMAP",s),L("INVALID_BEATMAP",s)}}async load_files(r,u){try{let n=new W;return this.resources=await n.load_from_files(r,{difficulty:u}),this.setup()}catch(n){let s=n instanceof Error?n.message:String(n);return this.emit("error","INVALID_BEATMAP",s),L("INVALID_BEATMAP",s)}}async load_default_hitsounds(r){if(r.length==0){console.warn("[BeatmapPlayer] No default hitsound URLs were provided");return}try{await this.hitsounds.load_default_samples(r)}catch(u){console.error("[BeatmapPlayer] Failed to load default hitsounds:",u)}}async load_custom_hitsounds(r){if(r.length==0){console.warn("[BeatmapPlayer] No custom hitsound URLs were provided"),this.hitsounds.clear();return}try{await this.hitsounds.load_samples(r)}catch(u){console.error("[BeatmapPlayer] Failed to load custom hitsounds:",u)}}async load_map_custom_hitsounds(){if(!this.resources?.beatmap)return;let r=uu(this.resources.beatmap,this.resources.files,this.resources.audio_filename);if(r.size==0){this.hitsounds.clear();return}try{await this.hitsounds.load_samples_from_files(r)}catch(u){console.error("[BeatmapPlayer] Failed to load map custom hitsounds:",u),this.hitsounds.clear()}}async load_beatmap(r,u,n,s,t){return this.resources={beatmap:r,available_difficulties:[],files:new Map,audio:u,background:n,video:s,video_offset:t},this.setup()}async load_osu_content(r,u){try{await nu();let n=await this.parse_content(r);return this.load_beatmap(n,u)}catch(n){let s=n instanceof Error?n.message:String(n);return this.emit("error","INVALID_BEATMAP",s),L("INVALID_BEATMAP",s)}}async load_beatmap_files(r,u,n,s,t){try{await nu();let e=typeof r==="string",o=r instanceof Uint8Array?r:r instanceof ArrayBuffer?new Uint8Array(r):null,h=await this.parse_content(e?r:o);return this.load_beatmap(h,u,n,s,t)}catch(e){let o=e instanceof Error?e.message:String(e);return this.emit("error","INVALID_BEATMAP",o),L("INVALID_BEATMAP",o)}}async setup(){if(!this.resources)return L("NOT_LOADED","No resources loaded");let{beatmap:r}=this.resources;this.timing_points=tr([...r.TimingPoints]),this.timing_resolver=new c(this.timing_points);let u=E(this.mods);this.resolve_assets();let{audio:n,video:s,video_offset:t}=this.resources;if(n)try{await this.audio.load(n,this.mods)}catch(e){let o=e instanceof Error?e.message:String(e);return this.emit("error","AUDIO_DECODE_ERROR",o),L("AUDIO_DECODE_ERROR",o)}if(this.hitsound_scheduler.set_context(this.resources,this.timing_points,this.timing_resolver,this.audio_offset),this.load_map_custom_hitsounds(),s)this.video=new Ir,await this.video.load(s,t??0);try{this.renderer=this.create_renderer(r),this.renderer.initialize(r),this.renderer.precompute()}catch(e){let o=e instanceof Error?e.message:String(e);return this.emit("error","UNSUPPORTED_MODE",o),L("UNSUPPORTED_MODE",o)}return this.start_offset=this.resolve_initial_start_offset(),this.hitsound_scheduler.update_hit_index(this.start_offset),this.load_background(),this.is_loaded_flag=!0,this.emit("loaded",r,this.resources),requestAnimationFrame(()=>this.render_frame(this.start_offset)),Yr(this.resources)}async load_background(){if(this.resources)this.resolve_assets();if(!this.resources?.background||!this.renderer)return;try{let r=new Image;if(this.background_url)URL.revokeObjectURL(this.background_url);this.background_url=URL.createObjectURL(this.resources.background),r.src=this.background_url,await r.decode(),this.renderer.set_background({source:r,width:r.width,height:r.height});let u=this.audio.is_playing?this.current_time:this.start_offset;requestAnimationFrame(()=>this.render_frame(u))}catch(r){console.warn("[BeatmapPlayer] Failed to load background",r)}}resolve_assets(){if(!this.resources)return;let r=new qr(this.resources).resolve();if(!this.resources.audio&&r.audio)this.resources.audio=r.audio;if(!this.resources.background&&r.background)this.resources.background=r.background;if(!this.resources.video&&r.video)this.resources.video=r.video;if(!this.resources.video_offset&&r.video_offset)this.resources.video_offset=r.video_offset}create_renderer(r){switch(r.General.Mode){case 0:return new or(this.backend,this.skin,this.mods,this.renderer_config);case 3:return new hr(this.backend,this.skin,this.mods,this.renderer_config);case 1:case 2:default:throw Error(`Unsupported game mode: ${Tr[r.General.Mode]??r.General.Mode}`)}}get_last_object_time(){if(!this.resources?.beatmap.HitObjects.length)return 0;let r=this.resources.beatmap.HitObjects,u=0;for(let n of r){let s=n.endTime||n.time;if(s>u)u=s}return u}resolve_preview_start_offset(){if(!this.resources?.beatmap)return 0;let r=this.resources.beatmap.General.PreviewTime;if(r>0)return r;return Math.max(0,this.get_last_object_time()*Gu)}resolve_initial_start_offset(){let r=Math.max(0,this.duration);if(this.start_mode=="beginning")return 0;if(this.start_mode=="custom"){if(this.custom_start_time!==null)return Math.max(0,Math.min(this.custom_start_time,r));return Math.max(0,Math.min(this.resolve_preview_start_offset(),r))}return Math.max(0,Math.min(this.resolve_preview_start_offset(),r))}async play(){if(!this.renderer||!this.is_loaded_flag){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();try{await this.audio.play(Math.max(0,this.start_offset+this.audio_offset))}catch(r){console.warn("[BeatmapPlayer] Failed to start audio",r),this.emit("statechange",!1);return}this.video?.play(),this.start_render_loop(),this.emit("play"),this.emit("statechange",!0)}pause(){if(!this.audio.is_playing)return;this.start_offset=Math.max(0,this.audio.current_time-this.audio_offset),this.audio.pause(),this.video?.pause(),this.stop_render_loop(),this.emit("pause"),this.emit("statechange",!1)}set_mods(r){this.mods=r;let u=E(r);if(this.renderer?.set_mods(r),this.audio.set_speed(u),this.is_loaded_flag)requestAnimationFrame(()=>this.render_frame(this.current_time))}seek(r){this.start_offset=Math.max(0,Math.min(r,this.duration)),this.hitsound_scheduler.update_hit_index(this.start_offset),this.audio.seek(Math.max(0,this.start_offset+this.audio_offset)),this.video?.seek(this.start_offset),this.emit("seek",this.start_offset),this.render_frame(this.start_offset),this.renderer?.on_seek(this.start_offset)}async set_difficulty(r){if(!this.resources)return L("NOT_LOADED","No beatmap resources loaded");let u=this.is_playing;this.stop();try{let s=await new W().load_from_files(this.resources.files,{difficulty:r});this.resources=s;let t=await this.setup();if(t.success&&u)this.play();return t}catch(n){let s=n instanceof Error?n.message:String(n);return this.emit("error","INVALID_BEATMAP",s),L("INVALID_BEATMAP",s)}}async parse_content(r){let u=typeof r=="string"?new TextEncoder().encode(r):r;return await Eu(u)}stop(){this.pause(),this.start_offset=0,this.audio.seek(Math.max(0,this.audio_offset)),this.hitsound_scheduler.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.background_url)URL.revokeObjectURL(this.background_url),this.background_url=null;if(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_flag=!1,this.listeners.clear()}get current_time(){return Math.max(0,this.audio.current_time-this.audio_offset)}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_flag}get mode(){if(!this.resources)return"standard";switch(this.resources.beatmap.General.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(r,u,n){if(this.backend.resize(r,u),this.calculate_layout(r,u,n),this.is_loaded_flag)requestAnimationFrame(()=>this.render_frame(this.current_time))}update_config(r){if(this.renderer_config={...this.renderer_config,...r},this.renderer?.update_config(this.renderer_config),this.is_loaded_flag)requestAnimationFrame(()=>this.render_frame(this.current_time))}set_skin(r){if(this.skin=a(r),this.is_loaded_flag&&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 u=this.options.canvas.parentElement;if(u){let n=u.getBoundingClientRect();this.resize(n.width,n.height,this.options.playfield_scale)}}),this.resize_observer.observe(this.options.canvas.parentElement||this.options.canvas)}toggle_pause(){if(!this.is_loaded_flag)return;if(this.is_playing)this.pause();else 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(r,u,n){let e=0.9;if(Number.isFinite(n))e=n;let o=r*e/512,h=u*e/384,f=Math.min(o,h);if(this.renderer_config.scale=f,this.renderer_config.offset_x=Math.floor((r-512*f)/2),this.renderer_config.offset_y=Math.floor((u-384*f)/2),this.renderer)this.renderer.update_config(this.renderer_config)}set_volume(r){this.music_volume=r,this.audio.set_volume(r)}set_hitsound_volume(r){this.hitsound_volume=r,this.hitsounds.set_volume(r)}set_offset(r){if(this.audio_offset=r,this.hitsound_scheduler.set_audio_offset(r),this.is_loaded_flag)this.seek(this.current_time)}on(r,u){if(!this.listeners.has(r))this.listeners.set(r,new Set);this.listeners.get(r).add(u)}off(r,u){this.listeners.get(r)?.delete(u)}emit(r,...u){let n=this.listeners.get(r);if(n)for(let s of n)s(...u)}start_render_loop(){if(this.animation_frame!==null)return;this.last_timestamp=performance.now(),this.smooth_time=this.audio.current_time-this.audio_offset,this.smoothed_delta=0;let r=(u)=>{if(!this.audio.is_playing){this.animation_frame=null;return}let n=Math.max(0,u-this.last_timestamp);this.last_timestamp=u;let s=Math.min(n,this.max_frame_delta);if(this.time_smoothing>0){if(this.smoothed_delta===0)this.smoothed_delta=s;else this.smoothed_delta+=(s-this.smoothed_delta)*this.time_smoothing;s=this.smoothed_delta}this.smooth_time+=s*this.audio.speed_multiplier;let t=this.audio.current_time-this.audio_offset;if(Math.abs(this.smooth_time-t)>wu)this.smooth_time=t;else this.smooth_time+=(t-this.smooth_time)*0.1;let o=this.smooth_time;if(this.hitsound_scheduler.schedule_hitsounds(t),this.render_frame(o),this.video?.sync(o),this.emit("timeupdate",o,this.duration),o>=this.duration){this.emit("ended"),this.stop_render_loop(),this.emit("statechange",!1);return}this.animation_frame=requestAnimationFrame(r)};this.animation_frame=requestAnimationFrame(r)}stop_render_loop(){if(this.animation_frame!==null)cancelAnimationFrame(this.animation_frame),this.animation_frame=null}render_frame(r){if(this.backend.begin_frame?.(),this.backend.clear(),this.renderer?.render(r),this.enable_fps_counter){this.fps_frame_count++;let u=performance.now(),n=u-this.fps_last_update;if(n>=1000)this.current_fps=Math.round(this.fps_frame_count*1000/n),this.fps_frame_count=0,this.fps_last_update=u;let s=`14px ${this.skin.default_font??"monospace"}`;this.backend.draw_text(`${this.current_fps} FPS`,10,20,s,"rgba(255,255,255,0.8)","left","top")}this.backend.end_frame?.()}set_fps_counter(r){this.enable_fps_counter=r}}var xu=(r)=>{try{return new FontFace(r.family,r.url,{weight:r.weight,style:"normal"})}catch(u){return console.error(u),null}},cu=async(r)=>{let u=xu(r);if(!u)return!1;try{await u.load(),document.fonts.add(u)}catch(n){return console.error(n),!1}return!0};export{ju as unwrap,rn as toggle_mod,Yr as ok,_u as mods_to_string,au as mods_from_string,a as merge_skin,cu as load_font,U as is_spinner,Vr as is_slider,bu as is_ok,Ur as is_new_combo,mr as is_hold,iu as is_err,Xr as is_circle,$ as has_mod,E as get_speed_multiplier,Pr as get_rate_multiplier,G as get_mania_lane_color,Z as get_combo_color,un as get_available_mods,cr as get_adjusted_difficulty,L as err,yu as apply_rate_to_ar,Pu as apply_mods_to_difficulty,Ir as VideoController,or as StandardRenderer,fu as SpeedChangingMods,Hr as SampleSet,Dr as PLAYFIELD_WIDTH,pr as PLAYFIELD_HEIGHT,W as OszLoader,V as Mods,Du as ModNightcore,Ru as ModHidden,Br as ModHardRock,pu as ModHalfTime,Rr as ModEasy,Vu as ModDoubleTime,hr as ManiaRenderer,i as HitSoundType,J as HitObjectType,Bu as HD_FADE_OUT_MULTIPLIER,Mu as HD_FADE_IN_MULTIPLIER,Er as GridLevel,Tr as GameMode,Wr as ErrorCode,du as DifficultyChangingMods,Fr as DEFAULT_SKIN,q as DEFAULT_RENDERER_CONFIG,k as CanvasBackend,su as BeatmapPlayer,Y as BaseRenderer,fr as AudioController};
2
2
 
3
- //# debugId=496A49AD8DD58A0064756E2164756E21
3
+ //# debugId=E365849A69CE2F6264756E2164756E21