@rel-packages/osu-beatmap-preview 0.8.4 → 0.8.6

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