@pitvox/partner-react 0.1.0 → 0.2.1

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/README.md CHANGED
@@ -192,6 +192,69 @@ import {
192
192
  **`useCompetitionEntryList(competitionId)`** — Registered drivers.
193
193
  ```
194
194
 
195
+ ## Driver Dashboard
196
+
197
+ ### Drop-in (recommended)
198
+
199
+ One component gives you a complete driver dashboard with profile, stats cards, and current records:
200
+
201
+ ```jsx
202
+ import { DriverDashboard } from '@pitvox/partner-react'
203
+ import '@pitvox/partner-react/styles.css'
204
+
205
+ function DashboardPage() {
206
+ return (
207
+ <DriverDashboard
208
+ steamId={user.steamId}
209
+ avatarUrl={user.avatarUrl}
210
+ memberSince={user.createdAt}
211
+ />
212
+ )
213
+ }
214
+ ```
215
+
216
+ **Props:**
217
+
218
+ | Prop | Type | Default | Description |
219
+ |------|------|---------|-------------|
220
+ | `steamId` | `string` | — | Driver's Steam ID (required) |
221
+ | `avatarUrl` | `string` | — | Avatar URL from your auth provider |
222
+ | `memberSince` | `string` | — | ISO date for "Racing since" display |
223
+ | `className` | `string` | — | Additional class on root container |
224
+
225
+ **Displays:**
226
+ - Driver profile card (avatar, name, racing since)
227
+ - Stats cards: total laps (with track breakdown tooltip), cars used (with car breakdown tooltip), driver rating
228
+ - Current records list sorted by most recent, with track, car, lap time, and game badge
229
+
230
+ ### Layer components
231
+
232
+ For more control, use the individual components directly:
233
+
234
+ ```jsx
235
+ import { DriverProfile, StatsCards, RecordsTable } from '@pitvox/partner-react'
236
+ import '@pitvox/partner-react/styles.css'
237
+ ```
238
+
239
+ - **`<DriverProfile>`** — Avatar, driver name, and "Racing since" date
240
+ - **`<StatsCards>`** — Stats cards with icons and hover breakdown tooltips (accepts `stats` from `useDriverStats` and `rating` from `useDriverRating`)
241
+ - **`<RecordsTable>`** — Compact records list sorted by most recent, with expand/collapse
242
+
243
+ ### Hooks only
244
+
245
+ For fully custom UIs, use the data hooks directly:
246
+
247
+ ```jsx
248
+ import { useDriverStats, useDriverRating } from '@pitvox/partner-react'
249
+ ```
250
+
251
+ **`useDriverStats(steamId)`** — Fetch driver stats, records, and ranking from CDN.
252
+ - Shares the same query cache as `useDriverLaps` (same CDN file)
253
+ - Returns `{ data: { driverName, lapCount, trackBreakdown, carBreakdown, recordsHeld, currentRecords, bestRanking, bestRankingTrackId, bestRankingLayout, bestRankingCarId }, isLoading, error }`
254
+
255
+ **`useDriverRating(steamId)`** — Fetch driver's rating from the partner ratings file.
256
+ - Returns `{ data: { rating, rank, totalDrivers, comboCount, distinctCars, combos }, isLoading, error }`
257
+
195
258
  ## Registration
196
259
 
197
260
  ```jsx
@@ -250,6 +313,7 @@ The SDK reads pre-computed JSON from the PitVox CDN. No API key is needed for re
250
313
  | Standings | `competitions/{slug}/{id}/standings.json` |
251
314
  | Round results | `competitions/{slug}/{id}/rounds/{n}.json` |
252
315
  | Entry list | `competitions/{slug}/{id}/entrylist.json` |
316
+ | Driver ratings | `leaderboards/partners/{slug}/ratings.json` |
253
317
 
254
318
  ## Local development
255
319
 
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),b=require("react"),w=require("@tanstack/react-query"),te=require("react-router-dom"),O=b.createContext(null),qe="https://cdn.pitvox.com",_e="https://api.pitvox.com";let K=null;function Ve({partnerSlug:s,apiKey:t,cdnUrl:r=qe,apiUrl:n=_e,getSteamId:a,children:i}){const l=b.useMemo(()=>({partnerSlug:s,apiKey:t,cdnUrl:r.replace(/\/$/,""),apiUrl:n.replace(/\/$/,""),getSteamId:a||(()=>null)}),[s,t,r,n,a]);let o=!1;try{w.useQueryClient(),o=!0}catch{o=!1}return o?e.jsx(O.Provider,{value:l,children:i}):(K||(K=new w.QueryClient({defaultOptions:{queries:{staleTime:6e4}}})),e.jsx(w.QueryClientProvider,{client:K,children:e.jsx(O.Provider,{value:l,children:i})}))}function S(){const s=b.useContext(O);if(!s)throw new Error("usePitVox must be used within a <PitVoxPartnerProvider>");return s}async function R(s,t){const r=await fetch(`${s}/${t}`);if(!r.ok){if(r.status===404||r.status===403)return null;throw new Error(`CDN fetch failed: ${r.status}`)}return r.json()}function E(s){if(!s&&s!==0)return"-";const t=Math.floor(s/1e3),r=Math.floor(t/60),n=t%60,a=s%1e3;return`${r}:${String(n).padStart(2,"0")}.${String(a).padStart(3,"0")}`}function I(s){return!s&&s!==0?"-":(s/1e3).toFixed(3)}function $(s){if(!s)return"";let t=s;return t.startsWith("ks_")&&(t=t.slice(3)),t.split("_").map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join(" ")}function Q(s,t,r){const n=s.split("_").map(l=>l.charAt(0).toUpperCase()+l.slice(1)).join(" "),a=r==="acc"||!r&&(t==null?void 0:t.toLowerCase())==="track config";if(!t||t==="default"||a)return n;const i=t.split("_").map(l=>l.charAt(0).toUpperCase()+l.slice(1)).join(" ");return`${n} ${i}`}function A(s){if(!s)return"-";try{return new Date(s).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"})}catch{return"-"}}function Ke(s){if(!s)return"";const t=Date.now()-new Date(s).getTime(),r=Math.floor(t/1e3);if(r<60)return"Just now";const n=Math.floor(r/60);if(n<60)return`${n}m ago`;const a=Math.floor(n/60);if(a<24)return`${a}h ago`;const i=Math.floor(a/24);return i<30?`${i}d ago`:A(s)}function Oe(s){return s==null?"":`${s>=0?"+":"-"}${(Math.abs(s)/1e3).toFixed(3)}`}function H(s){return s?{E:"Eco",RD:"Road",SC:"SuperCar",RV:"Race Vintage",SM:"Semislick",ST:"Street",HR:"Hard Race",MR:"Medium Race",SR:"Soft Race",S:"Soft"}[s]||s:"Unknown"}function re(s={}){var o,m,c,h,f,v;const{cdnUrl:t,partnerSlug:r}=S(),{game:n,gameVersion:a}=s,i=w.useQuery({queryKey:["pitvox","leaderboards",r,"index"],queryFn:()=>R(t,`leaderboards/partners/${r}/index.json`),staleTime:3e4,refetchInterval:3e4}),l=b.useMemo(()=>{var j;if(!((j=i.data)!=null&&j.tracks))return[];let x=i.data.tracks;return n&&(x=x.filter(d=>d.game===n)),a&&(x=x.filter(d=>d.gameVersion===a)),x.map(d=>({id:d.trackId,layout:d.layout,game:d.game,gameVersion:d.gameVersion,displayName:Q(d.trackId,d.layout,d.game),driverCount:d.driverCount||0,carCount:d.carCount||0,record:d.recordHolder?{visibleId:d.recordHolder.steamId||d.recordHolder.userId,carId:d.recordHolder.carId,carDisplayName:$(d.recordHolder.carId),lapTimeMs:d.recordHolder.lapTimeMs,timestamp:d.recordHolder.recordedAt}:null,recordByTag:d.recordByTag||null}))},[(o=i.data)==null?void 0:o.tracks,n,a]);return{...i,data:l,partner:((m=i.data)==null?void 0:m.partner)||null,generatedAt:(c=i.data)==null?void 0:c.generatedAt,totalLaps:((h=i.data)==null?void 0:h.totalLaps)||0,totalUsers:((f=i.data)==null?void 0:f.totalUsers)||0,versions:((v=i.data)==null?void 0:v.versions)||{}}}function G(s,t,r={}){const{cdnUrl:n,partnerSlug:a}=S(),{carId:i,game:l,gameVersion:o}=r,m=t||"default",c=o?`leaderboards/partners/${a}/v/${o}/tracks/${s}/${m}.json`:`leaderboards/partners/${a}/tracks/${s}/${m}.json`,{data:h,isLoading:f,error:v}=w.useQuery({queryKey:["pitvox","leaderboards",a,"track",s,m,o],queryFn:()=>R(n,c),enabled:!!s,staleTime:3e4,refetchInterval:3e4});return{data:b.useMemo(()=>{if(!(h!=null&&h.entries))return[];let j=h.entries;if(l&&(j=j.filter(d=>d.game===l)),!i){const d=new Map,u=new Map;for(const p of j){const N=p.steamId||p.userId;u.has(p.carId)||u.set(p.carId,new Set),u.get(p.carId).add(N),(!d.has(p.carId)||p.lapTimeMs<d.get(p.carId).lapTimeMs)&&d.set(p.carId,p)}return Array.from(d.values()).map(p=>{var N;return{...p,driverCount:((N=u.get(p.carId))==null?void 0:N.size)||0}}).sort((p,N)=>p.lapTimeMs-N.lapTimeMs)}return j.filter(d=>d.carId===i).sort((d,u)=>d.lapTimeMs-u.lapTimeMs)},[h==null?void 0:h.entries,i,l]),isLoading:f,error:v}}function ne(s,t,r,n,a={}){var v,x;const{cdnUrl:i,partnerSlug:l}=S(),{showInvalid:o=!1,game:m,gameVersion:c}=a,h=w.useQuery({queryKey:["pitvox","laps",l,s],queryFn:()=>R(i,`laps/partners/${l}/${s}.json`),enabled:!!s,staleTime:3e4,refetchInterval:3e4}),f=b.useMemo(()=>{var j;return(j=h.data)!=null&&j.laps?h.data.laps.filter(d=>{if(d.trackId!==t)return!1;if(r){if(d.trackLayout!==r)return!1}else if(d.trackLayout&&d.trackLayout!=="default")return!1;return!(d.carId!==n||m&&d.game!==m||c&&d.gameVersion!==c||!o&&!d.isValid)}).sort((d,u)=>d.lapTimeMs-u.lapTimeMs):[]},[(v=h.data)==null?void 0:v.laps,t,r,n,m,c,o]);return{...h,data:f,driverName:((x=h.data)==null?void 0:x.driverName)||"Driver"}}function ae(){const{cdnUrl:s}=S(),{data:t}=w.useQuery({queryKey:["pitvox","users","index"],queryFn:()=>R(s,"users/index.json"),staleTime:5*6e4,gcTime:30*6e4}),r=(t==null?void 0:t.users)||{};return(n,a)=>{const i=r[n];return{displayName:(i==null?void 0:i.displayName)||a||n||"Unknown",avatarUrl:(i==null?void 0:i.avatarUrl)||null,affiliations:(i==null?void 0:i.affiliations)||[]}}}function ie(){const{cdnUrl:s}=S(),{data:t}=w.useQuery({queryKey:["pitvox","cars","index"],queryFn:()=>R(s,"cars/index.json"),staleTime:5*6e4,gcTime:30*6e4});return{tags:(t==null?void 0:t.tags)||[],cars:(t==null?void 0:t.cars)||{}}}function Qe(s,t){return G(s,null,{carId:t})}function oe(){const{cdnUrl:s,partnerSlug:t}=S();return w.useQuery({queryKey:["pitvox","competitions",t],queryFn:async()=>{const r=await R(s,"competitions/index.json");return r!=null&&r.competitions?r.competitions.filter(n=>n.partnerSlug===t):[]},staleTime:6e4})}function W(s){const{cdnUrl:t,partnerSlug:r}=S();return w.useQuery({queryKey:["pitvox","competition",r,s,"config"],queryFn:()=>R(t,`competitions/${r}/${s}/config.json`),enabled:!!s,staleTime:6e4})}function le(s){const{cdnUrl:t,partnerSlug:r}=S();return w.useQuery({queryKey:["pitvox","competition",r,s,"standings"],queryFn:()=>R(t,`competitions/${r}/${s}/standings.json`),enabled:!!s,staleTime:6e4})}function ce(s,t){const{cdnUrl:r,partnerSlug:n}=S();return w.useQuery({queryKey:["pitvox","competition",n,s,"round",t],queryFn:()=>R(r,`competitions/${n}/${s}/rounds/${t}.json`),enabled:!!s&&t!=null,staleTime:6e4})}function He(s,t=[]){const{cdnUrl:r,partnerSlug:n}=S();return w.useQuery({queryKey:["pitvox","competition",n,s,"allRounds",t],queryFn:async()=>(await Promise.all(t.map(i=>R(r,`competitions/${n}/${s}/rounds/${i}.json`).catch(()=>null)))).filter(Boolean),enabled:!!s&&t.length>0,staleTime:6e4})}function de(s){const{cdnUrl:t,partnerSlug:r}=S();return w.useQuery({queryKey:["pitvox","competition",r,s,"entrylist"],queryFn:()=>R(t,`competitions/${r}/${s}/entrylist.json`),enabled:!!s,staleTime:6e4})}async function pe(s,t,r,n={}){const a=await fetch(`${s}${r}`,{...n,headers:{"Content-Type":"application/json","X-Partner-Key":t,...n.headers}});if(!a.ok){const i=await a.json().catch(()=>({}));throw new Error(i.detail||`API request failed: ${a.status}`)}return a.json()}function Ge(s,t,r,n){return pe(s,t,`/api/v1/competitions/${r}/register`,{method:"POST",body:JSON.stringify(n)})}function We(s,t,r,n){return pe(s,t,`/api/v1/competitions/${r}/register/${n}`,{method:"DELETE"})}function xe(s){const{cdnUrl:t,partnerSlug:r,getSteamId:n}=S(),a=n();return w.useQuery({queryKey:["pitvox","registration",r,s,a],queryFn:async()=>{var m;const i=await fetch(`${t}/competitions/${r}/${s}/entrylist.json`);if(!i.ok)return{isRegistered:!1,entryList:null};const l=await i.json();return{isRegistered:!!a&&((m=l.drivers)==null?void 0:m.some(c=>c.steamId===a)),entryList:l}},enabled:!!s,staleTime:6e4})}function ue(s){const{apiUrl:t,apiKey:r,partnerSlug:n}=S(),a=w.useQueryClient();return w.useMutation({mutationFn:i=>Ge(t,r,s,i),onSuccess:()=>{a.invalidateQueries({queryKey:["pitvox","registration",n,s]}),a.invalidateQueries({queryKey:["pitvox","competition",n,s,"entrylist"]})}})}function me(s){const{apiUrl:t,apiKey:r,partnerSlug:n,getSteamId:a}=S(),i=w.useQueryClient();return w.useMutation({mutationFn:l=>{const o=l||a();if(!o)throw new Error("No Steam ID available");return We(t,r,s,o)},onSuccess:()=>{i.invalidateQueries({queryKey:["pitvox","registration",n,s]}),i.invalidateQueries({queryKey:["pitvox","competition",n,s,"entrylist"]})}})}const ze={formula:"Formula",gt3:"GT3",gt2:"GT2",gt4:"GT4",cup:"Cup",prototype:"Prototype",rally:"Rally",hypercar:"Hypercar",supercar:"Supercar",sports_car:"Sports Car",hot_hatch:"Hot Hatch",lightweight:"Lightweight","1960s":"1960s","1970s":"1970s","1980s":"1980s","1990s":"1990s","2000s":"2000s","2010s":"2010s","2020s":"2020s"},ve=[{id:"class",tags:["formula","gt3","gt2","gt4","cup","prototype","rally"]},{id:"tier",tags:["hypercar","supercar","sports_car","hot_hatch","lightweight"]},{id:"era",tags:["1960s","1970s","1980s","1990s","2000s","2010s","2020s"]}];function Je(s){for(const t of ve)if(t.tags.includes(s))return t.id;return"other"}function he(s,t){if(t.size===0)return!0;const r={};for(const n of t){const a=Je(n);r[a]||(r[a]=[]),r[a].push(n)}for(const n of Object.values(r))if(!n.some(a=>s.includes(a)))return!1;return!0}function je(){const[s,t]=b.useState(new Set),r=b.useCallback(a=>{t(i=>{const l=new Set(i);return l.has(a)?l.delete(a):l.add(a),l})},[]),n=b.useCallback(()=>t(new Set),[]);return{activeTags:s,toggle:r,clear:n}}function z(s){const[t,r]=b.useState(s),n=b.useCallback(a=>{r(i=>i.key===a?{key:a,dir:i.dir==="asc"?"desc":"asc"}:{key:a,dir:a.includes("timestamp")||a.includes("Date")?"desc":"asc"})},[]);return[t,n]}function J(s,t,r){return[...s].sort((n,a)=>{const i=r(n,t.key),l=r(a,t.key);if(i==null&&l==null)return 0;if(i==null)return 1;if(l==null)return-1;const o=typeof i=="string"?i.localeCompare(l):i-l;return t.dir==="desc"?-o:o})}function fe(s,t=!1){const r=t?s==null?void 0:s.filter(n=>n.isValid):s;return r!=null&&r.length?{s1:Math.min(...r.map(n=>n.sector1Ms).filter(Boolean)),s2:Math.min(...r.map(n=>n.sector2Ms).filter(Boolean)),s3:Math.min(...r.map(n=>n.sector3Ms).filter(Boolean))}:null}function Ze({active:s,dir:t}){return s?t==="asc"?e.jsx("svg",{className:"pvx-sort-icon",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4.5 15.75l7.5-7.5 7.5 7.5"})}):e.jsx("svg",{className:"pvx-sort-icon",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19.5 8.25l-7.5 7.5-7.5-7.5"})}):e.jsx("svg",{className:"pvx-sort-icon pvx-sort-icon--inactive",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8 9l4-4 4 4M16 15l-4 4-4-4"})})}function L({label:s,sortKey:t,config:r,onSort:n,className:a=""}){return e.jsx("th",{className:`pvx-th pvx-th--sortable ${a}`,onClick:()=>n(t),children:e.jsxs("span",{className:"pvx-th-inner",children:[s,e.jsx(Ze,{active:r.key===t,dir:r.dir})]})})}function Z({userId:s,getUserDisplay:t}){const{displayName:r,avatarUrl:n}=t(s);return e.jsxs("span",{className:"pvx-driver",children:[n?e.jsx("img",{src:n,alt:"",className:"pvx-driver-avatar"}):e.jsx("span",{className:"pvx-driver-avatar pvx-driver-avatar--placeholder"}),e.jsx("span",{className:"pvx-driver-name",children:r})]})}function ge({rank:s,podium:t=!1}){const r=t?s===1?"pvx-rank pvx-rank--gold":s===2?"pvx-rank pvx-rank--silver":s===3?"pvx-rank pvx-rank--bronze":"pvx-rank":"pvx-rank";return e.jsx("span",{className:r,children:s})}function Ne({availableTags:s,activeTags:t,onToggle:r,onClear:n}){if(!s||s.length<2)return null;const a=ve.map(i=>({id:i.id,tags:i.tags.filter(l=>s.includes(l))})).filter(i=>i.tags.length>0);return e.jsxs("div",{className:"pvx-tag-bar",children:[e.jsx("button",{onClick:n,className:`pvx-tag ${t.size===0?"pvx-tag--active":""}`,children:"All"}),a.map((i,l)=>e.jsxs("span",{className:"contents",children:[l>0&&e.jsx("span",{className:"pvx-tag-separator"}),i.tags.map(o=>e.jsx("button",{onClick:()=>r(o),className:`pvx-tag ${t.has(o)?"pvx-tag--active":""}`,children:ze[o]||o},o))]},i.id))]})}function X({segments:s}){return e.jsx("nav",{className:"pvx-breadcrumb","aria-label":"Breadcrumb",children:e.jsx("ol",{className:"pvx-breadcrumb-list",children:s.map((t,r)=>{const n=r===s.length-1;return e.jsxs("li",{className:"pvx-breadcrumb-item",children:[r>0&&e.jsx("svg",{className:"pvx-breadcrumb-chevron",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8.25 4.5l7.5 7.5-7.5 7.5"})}),!n&&t.onClick?e.jsx("button",{onClick:t.onClick,className:"pvx-breadcrumb-link",children:t.label}):e.jsx("span",{className:"pvx-breadcrumb-current",children:t.label})]},t.key)})})})}function q({message:s}){return e.jsxs("div",{className:"pvx-empty",children:[e.jsx("svg",{className:"pvx-empty-icon",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M16.5 18.75h-9m9 0a3 3 0 013 3h-15a3 3 0 013-3m9 0v-4.5A3.375 3.375 0 0013.125 10.875h-2.25A3.375 3.375 0 007.5 14.25v4.5"})}),e.jsx("p",{children:s})]})}function _(){return e.jsx("div",{className:"pvx-loading",children:"Loading..."})}function Xe(){return e.jsx("svg",{className:"pvx-icon pvx-icon--valid",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4.5 12.75l6 6 9-13.5"})})}function Ye(){return e.jsx("svg",{className:"pvx-icon pvx-icon--invalid",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})}function be({tracks:s,isLoading:t,carMetadata:r,getUserDisplay:n,onTrackSelect:a}){const[i,l]=z({key:"record.timestamp",dir:"desc"}),{activeTags:o,toggle:m,clear:c}=je(),h=b.useMemo(()=>{var j;if(!((j=r==null?void 0:r.tags)!=null&&j.length))return[];const x=new Set;for(const d of s||[])d.recordByTag&&Object.keys(d.recordByTag).forEach(u=>x.add(u));return r.tags.filter(d=>x.has(d))},[s,r]),f=b.useMemo(()=>s?o.size===0?s:s.map(x=>{var u,p;if(!x.recordByTag)return null;let j=null;const d=new Set;for(const N of Object.values(x.recordByTag)){if(d.has(N.carId))continue;d.add(N.carId);const y=((p=(u=r==null?void 0:r.cars)==null?void 0:u[N.carId])==null?void 0:p.tags)||["sports_car"];he(y,o)&&(!j||N.lapTimeMs<j.lapTimeMs)&&(j=N)}return j?{...x,record:{visibleId:j.steamId||j.identifier,carId:j.carId,carDisplayName:$(j.carId),lapTimeMs:j.lapTimeMs,timestamp:j.recordedAt}}:null}).filter(Boolean):[],[s,o,r]),v=b.useMemo(()=>J(f,i,(x,j)=>{var d,u;switch(j){case"displayName":return x.displayName;case"record.lapTimeMs":return(d=x.record)==null?void 0:d.lapTimeMs;case"driverCount":return x.driverCount||0;case"carCount":return x.carCount||0;case"record.timestamp":default:return(u=x.record)!=null&&u.timestamp?new Date(x.record.timestamp).getTime():0}}),[f,i]);return t?e.jsx(_,{}):s!=null&&s.length?e.jsxs("div",{className:"pvx-card",children:[e.jsx("div",{className:"pvx-card-header",children:e.jsx("h2",{className:"pvx-card-title",children:"Track Records"})}),e.jsx(Ne,{availableTags:h,activeTags:o,onToggle:m,onClear:c}),e.jsx("div",{className:"pvx-table-scroll",children:e.jsxs("table",{className:"pvx-table",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"pvx-thead-row",children:[e.jsx(L,{label:"Track",sortKey:"displayName",config:i,onSort:l}),e.jsx("th",{className:"pvx-th",children:"Record Holder"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-lg",children:"Car"}),e.jsx(L,{label:"Lap Time",sortKey:"record.lapTimeMs",config:i,onSort:l}),e.jsx(L,{label:"Drivers",sortKey:"driverCount",config:i,onSort:l,className:"pvx-hidden-below-md"}),e.jsx(L,{label:"Cars",sortKey:"carCount",config:i,onSort:l,className:"pvx-hidden-below-lg"}),e.jsx(L,{label:"Date",sortKey:"record.timestamp",config:i,onSort:l,className:"pvx-hidden-below-xl"})]})}),e.jsx("tbody",{className:"pvx-tbody",children:v.map(x=>{var j,d,u;return e.jsxs("tr",{className:"pvx-row pvx-row--clickable",onClick:()=>a(x.id,x.layout),children:[e.jsx("td",{className:"pvx-td pvx-td--primary",children:x.displayName}),e.jsx("td",{className:"pvx-td",children:(j=x.record)!=null&&j.visibleId?e.jsx(Z,{userId:x.record.visibleId,getUserDisplay:n}):"-"}),e.jsx("td",{className:"pvx-td pvx-hidden-below-lg",children:((d=x.record)==null?void 0:d.carDisplayName)||"-"}),e.jsx("td",{className:"pvx-td pvx-td--primary pvx-td--mono",children:x.record?E(x.record.lapTimeMs):"-"}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-md",children:x.driverCount||"-"}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-lg",children:x.carCount||"-"}),e.jsx("td",{className:"pvx-td pvx-td--muted pvx-hidden-below-xl",children:(u=x.record)!=null&&u.timestamp?A(x.record.timestamp):"-"})]},`${x.id}|${x.layout||""}`)})})]})})]}):e.jsx(q,{message:"No lap times recorded yet."})}function ye({entries:s,isLoading:t,track:r,carMetadata:n,getUserDisplay:a,onCarSelect:i,onNavigate:l}){const[o,m]=z({key:"lapTimeMs",dir:"asc"}),{activeTags:c,toggle:h,clear:f}=je(),v=b.useMemo(()=>{var p,N,y;if(!s||!((p=n==null?void 0:n.tags)!=null&&p.length))return[];const u=new Set;for(const k of s)(((y=(N=n.cars)==null?void 0:N[k.carId])==null?void 0:y.tags)||["sports_car"]).forEach(T=>u.add(T));return n.tags.filter(k=>u.has(k))},[s,n]),x=b.useMemo(()=>s?c.size===0?s:s.filter(u=>{var N,y;const p=((y=(N=n==null?void 0:n.cars)==null?void 0:N[u.carId])==null?void 0:y.tags)||["sports_car"];return he(p,c)}):[],[s,c,n]),j=b.useMemo(()=>J(x,o,(u,p)=>{switch(p){case"carId":return $(u.carId);case"driverCount":return u.driverCount||0;case"lapTimeMs":default:return u.lapTimeMs}}),[x,o]),d=[{key:"tracks",label:"Tracks",onClick:()=>l("tracks")},{key:"track",label:r.displayName}];return t?e.jsx(_,{}):e.jsxs("div",{className:"pvx-card",children:[e.jsx("div",{className:"pvx-card-header",children:e.jsx(X,{segments:d})}),e.jsx(Ne,{availableTags:v,activeTags:c,onToggle:h,onClear:f}),s!=null&&s.length?e.jsx("div",{className:"pvx-table-scroll",children:e.jsxs("table",{className:"pvx-table",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"pvx-thead-row",children:[e.jsx("th",{className:"pvx-th pvx-th--narrow",children:"#"}),e.jsx(L,{label:"Car",sortKey:"carId",config:o,onSort:m}),e.jsx("th",{className:"pvx-th",children:"Record Holder"}),e.jsx(L,{label:"Lap Time",sortKey:"lapTimeMs",config:o,onSort:m}),e.jsx(L,{label:"Drivers",sortKey:"driverCount",config:o,onSort:m,className:"pvx-hidden-below-md"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-lg",children:"Date"})]})}),e.jsx("tbody",{className:"pvx-tbody",children:j.map((u,p)=>e.jsxs("tr",{className:"pvx-row pvx-row--clickable",onClick:()=>i(u.carId),children:[e.jsx("td",{className:"pvx-td",children:e.jsx(ge,{rank:p+1,podium:!0})}),e.jsx("td",{className:"pvx-td pvx-td--primary",children:$(u.carId)}),e.jsx("td",{className:"pvx-td",children:e.jsx(Z,{userId:u.steamId||u.userId,getUserDisplay:a})}),e.jsx("td",{className:"pvx-td pvx-td--primary pvx-td--mono",children:E(u.lapTimeMs)}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-md",children:u.driverCount||"-"}),e.jsx("td",{className:"pvx-td pvx-td--muted pvx-hidden-below-lg",children:u.recordedAt?A(u.recordedAt):"-"})]},u.carId))})]})}):e.jsx(q,{message:"No lap times for this track yet."})]})}function Ce({entries:s,isLoading:t,track:r,carId:n,getUserDisplay:a,onDriverSelect:i,onNavigate:l}){const[o,m]=z({key:"lapTimeMs",dir:"asc"}),c=b.useMemo(()=>fe(s),[s]),h=b.useMemo(()=>J(s||[],o,(v,x)=>{switch(x){case"userId":return a(v.steamId||v.userId).displayName;case"lapCount":return v.lapCount||0;case"lapTimeMs":default:return v.lapTimeMs}}),[s,o,a]),f=[{key:"tracks",label:"Tracks",onClick:()=>l("tracks")},{key:"track",label:r.displayName,onClick:()=>l("track")},{key:"car",label:$(n)}];return t?e.jsx(_,{}):e.jsxs("div",{className:"pvx-card",children:[e.jsx("div",{className:"pvx-card-header",children:e.jsx(X,{segments:f})}),s!=null&&s.length?e.jsx("div",{className:"pvx-table-scroll",children:e.jsxs("table",{className:"pvx-table",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"pvx-thead-row",children:[e.jsx("th",{className:"pvx-th pvx-th--narrow",children:"#"}),e.jsx(L,{label:"Driver",sortKey:"userId",config:o,onSort:m}),e.jsx(L,{label:"Lap Time",sortKey:"lapTimeMs",config:o,onSort:m}),e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"S1"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"S2"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"S3"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-lg",children:"Tyre"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-xl",children:"Fuel"}),e.jsx(L,{label:"Laps",sortKey:"lapCount",config:o,onSort:m,className:"pvx-hidden-below-lg"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-xl",children:"Date"})]})}),e.jsx("tbody",{className:"pvx-tbody",children:h.map((v,x)=>{const j=x+1,d=v.steamId||v.userId,u=c&&v.sector1Ms===c.s1,p=c&&v.sector2Ms===c.s2,N=c&&v.sector3Ms===c.s3;return e.jsxs("tr",{className:`pvx-row pvx-row--clickable ${j<=3?"pvx-row--podium":""}`,onClick:()=>i(d),children:[e.jsx("td",{className:"pvx-td",children:e.jsx(ge,{rank:j,podium:!0})}),e.jsx("td",{className:"pvx-td pvx-td--primary",children:e.jsx(Z,{userId:d,getUserDisplay:a})}),e.jsx("td",{className:"pvx-td pvx-td--primary pvx-td--mono",children:E(v.lapTimeMs)}),e.jsx("td",{className:`pvx-td pvx-td--mono pvx-td--sector pvx-hidden-below-sm ${u?"pvx-td--best-sector":""}`,children:I(v.sector1Ms)}),e.jsx("td",{className:`pvx-td pvx-td--mono pvx-td--sector pvx-hidden-below-sm ${p?"pvx-td--best-sector":""}`,children:I(v.sector2Ms)}),e.jsx("td",{className:`pvx-td pvx-td--mono pvx-td--sector pvx-hidden-below-sm ${N?"pvx-td--best-sector":""}`,children:I(v.sector3Ms)}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-lg",title:H(v.tyreCompound),children:v.tyreCompound||"-"}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-xl",children:v.startingFuelL?`${v.startingFuelL}L`:"-"}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-lg",children:v.lapCount||"-"}),e.jsx("td",{className:"pvx-td pvx-td--muted pvx-hidden-below-xl",children:v.recordedAt?A(v.recordedAt):"-"})]},d)})})]})}):e.jsx(q,{message:"No lap times for this car yet."})]})}function we({userId:s,track:t,carId:r,game:n,gameVersion:a,showInvalid:i,getUserDisplay:l,onToggleInvalid:o,onNavigate:m}){const{data:c,driverName:h,isLoading:f}=ne(s,t.id,t.layout,r,{showInvalid:i,game:n,gameVersion:a}),{displayName:v,avatarUrl:x}=l(s,h),j=b.useMemo(()=>fe(c,!0),[c]),d=b.useMemo(()=>{const p=(c==null?void 0:c.filter(N=>N.isValid))||[];return p.length?Math.min(...p.map(N=>N.lapTimeMs)):null},[c]),u=[{key:"tracks",label:"Tracks",onClick:()=>m("tracks")},{key:"track",label:t.displayName,onClick:()=>m("track")},{key:"car",label:$(r),onClick:()=>m("car")},{key:"driver",label:v}];return f?e.jsx(_,{}):e.jsxs("div",{className:"pvx-card",children:[e.jsxs("div",{className:"pvx-card-header pvx-card-header--split",children:[e.jsxs("div",{className:"pvx-card-header-left",children:[e.jsx(X,{segments:u}),x?e.jsx("img",{src:x,alt:"",className:"pvx-driver-avatar pvx-driver-avatar--lg"}):e.jsx("span",{className:"pvx-driver-avatar pvx-driver-avatar--lg pvx-driver-avatar--placeholder"})]}),e.jsxs("label",{className:"pvx-checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:i,onChange:o,className:"pvx-checkbox"}),e.jsx("span",{children:"Show invalid laps"})]})]}),c!=null&&c.length?e.jsx("div",{className:"pvx-table-scroll",children:e.jsxs("table",{className:"pvx-table",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"pvx-thead-row",children:[e.jsx("th",{className:"pvx-th pvx-th--narrow",children:"#"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-md",children:"Lap"}),e.jsx("th",{className:"pvx-th",children:"Lap Time"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"S1"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"S2"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"S3"}),e.jsx("th",{className:"pvx-th pvx-th--narrow",children:"Valid"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-lg",children:"Tyre"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-lg",children:"Fuel"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-xl",children:"Date"})]})}),e.jsx("tbody",{className:"pvx-tbody",children:c.map((p,N)=>{const y=p.isValid&&p.lapTimeMs===d,k=j&&p.isValid&&p.sector1Ms===j.s1,U=j&&p.isValid&&p.sector2Ms===j.s2,T=j&&p.isValid&&p.sector3Ms===j.s3;let P="pvx-row";return p.isValid||(P+=" pvx-row--invalid"),y&&(P+=" pvx-row--personal-best"),e.jsxs("tr",{className:P,children:[e.jsx("td",{className:"pvx-td",children:e.jsx("span",{className:`pvx-rank ${y?"pvx-rank--gold":""}`,children:N+1})}),e.jsx("td",{className:"pvx-td pvx-td--muted pvx-hidden-below-md",children:p.lapNumber||"-"}),e.jsx("td",{className:"pvx-td pvx-td--primary pvx-td--mono",children:E(p.lapTimeMs)}),e.jsx("td",{className:`pvx-td pvx-td--mono pvx-td--sector pvx-hidden-below-sm ${k?"pvx-td--best-sector":""}`,children:I(p.sector1Ms)}),e.jsx("td",{className:`pvx-td pvx-td--mono pvx-td--sector pvx-hidden-below-sm ${U?"pvx-td--best-sector":""}`,children:I(p.sector2Ms)}),e.jsx("td",{className:`pvx-td pvx-td--mono pvx-td--sector pvx-hidden-below-sm ${T?"pvx-td--best-sector":""}`,children:I(p.sector3Ms)}),e.jsx("td",{className:"pvx-td",title:p.isValid?void 0:p.invalidReason||"Invalid",children:p.isValid?e.jsx(Xe,{}):e.jsx(Ye,{})}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-lg",title:H(p.tyreCompound),children:p.tyreCompound||"-"}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-lg",children:p.startingFuelL?`${p.startingFuelL}L`:"-"}),e.jsx("td",{className:"pvx-td pvx-td--muted pvx-hidden-below-xl",children:A(p.timestamp)})]},p.id)})})]})}):e.jsx(q,{message:i?"No laps recorded for this combination.":'No valid laps. Try enabling "Show invalid laps".'})]})}function es({className:s,defaultGame:t="evo",title:r="Leaderboards"}){const[n,a]=te.useSearchParams(),i=ae(),l=ie(),o=n.get("game")||t,m=n.get("version"),c=n.get("track"),h=n.get("car"),f=n.get("driver"),v=n.get("invalid")==="true",{data:x,isLoading:j,generatedAt:d,totalLaps:u,totalUsers:p,versions:N}=re({game:o}),y=N==null?void 0:N[o],k=m||(y==null?void 0:y.default)||null,U=b.useMemo(()=>!x||!k?x||[]:x.filter(g=>g.gameVersion===k),[x,k]),T=b.useMemo(()=>{if(!c)return null;const[g,C]=c.split("|");return{id:g,layout:C||null,displayName:Q(g,C,o)}},[c,o]),{data:P,isLoading:Y}=G(T==null?void 0:T.id,T==null?void 0:T.layout,{carId:h,game:o,gameVersion:k});function D(g){a(g)}function Ie(g){D({game:g})}function Pe(g){const C={game:o};g&&g!==(y==null?void 0:y.default)&&(C.version=g),D(C)}function Be(g,C){const ee={game:o,track:C?`${g}|${C}`:g};m&&(ee.version=m),D(ee)}function Ae(g){const C={game:o,track:c};m&&(C.version=m),g&&(C.car=g),D(C)}function Ee(g){const C={game:o,track:c,car:h,driver:g};m&&(C.version=m),D(C)}function V(g){const C={game:o};m&&(C.version=m),(g==="track"||g==="car")&&(C.track=c),g==="car"&&(C.car=h),D(C)}function Fe(){const g={game:o,track:c,car:h,driver:f};m&&(g.version=m),v||(g.invalid="true"),D(g)}const Ue=()=>T&&h&&f?e.jsx(we,{userId:f,track:T,carId:h,game:o,gameVersion:k,showInvalid:v,getUserDisplay:i,onToggleInvalid:Fe,onNavigate:V}):T&&h?e.jsx(Ce,{entries:P||[],isLoading:Y,track:T,carId:h,getUserDisplay:i,onDriverSelect:Ee,onNavigate:V}):T?e.jsx(ye,{entries:P||[],isLoading:Y,track:T,carMetadata:l,getUserDisplay:i,onCarSelect:Ae,onNavigate:V}):e.jsx(be,{tracks:U,isLoading:j,carMetadata:l,getUserDisplay:i,onTrackSelect:Be});return e.jsxs("div",{className:`pvx-leaderboard-explorer ${s||""}`,children:[e.jsxs("div",{className:"pvx-explorer-header",children:[e.jsx("h1",{className:"pvx-explorer-title",children:r}),e.jsxs("div",{className:"pvx-explorer-stats",children:[u>0&&e.jsxs("span",{children:[u.toLocaleString()," laps"]}),u>0&&p>0&&e.jsx("span",{className:"pvx-explorer-stats-sep",children:"|"}),p>0&&e.jsxs("span",{children:[p.toLocaleString()," drivers"]})]})]}),e.jsxs("div",{className:"pvx-explorer-controls",children:[e.jsx("div",{className:"pvx-game-tabs",children:["evo","acc"].map(g=>e.jsx("button",{onClick:()=>Ie(g),className:`pvx-game-tab ${o===g?"pvx-game-tab--active":""}`,children:g==="evo"?"AC EVO":"ACC"},g))}),y&&e.jsx("select",{value:k||"",onChange:g=>Pe(g.target.value),className:"pvx-version-select",children:y.available.slice().reverse().map(g=>e.jsxs("option",{value:g,children:["v",g,g===y.default?" (Latest)":""]},g))})]}),Ue(),d&&e.jsxs("p",{className:"pvx-data-timestamp",children:["Data updated: ",new Date(d).toLocaleString()]})]})}const ss={GBR:"🇬🇧",DEU:"🇩🇪",NLD:"🇳🇱",SWE:"🇸🇪",ESP:"🇪🇸",ZAF:"🇿🇦",FRA:"🇫🇷",ITA:"🇮🇹",USA:"🇺🇸",AUS:"🇦🇺",BRA:"🇧🇷",JPN:"🇯🇵",CAN:"🇨🇦",POL:"🇵🇱",AUT:"🇦🇹",BEL:"🇧🇪",PRT:"🇵🇹",NOR:"🇳🇴",DNK:"🇩🇰",FIN:"🇫🇮",IRL:"🇮🇪",CHE:"🇨🇭",NZL:"🇳🇿",MEX:"🇲🇽",ARG:"🇦🇷",CZE:"🇨🇿",HUN:"🇭🇺",RUS:"🇷🇺",TUR:"🇹🇷",KOR:"🇰🇷"},ts={championship:"Championship",series:"Series",event:"Event"},se=["PRACTICE","QUALIFYING","RACE"];function Te({position:s}){const t=s===1?"pvx-rank pvx-rank--gold":s===2?"pvx-rank pvx-rank--silver":s===3?"pvx-rank pvx-rank--bronze":"pvx-rank";return e.jsx("span",{className:t,children:s})}function Se({nation:s}){const t=s&&ss[s];return t?e.jsx("span",{className:"pvx-nation-flag",title:s,children:t}):null}function rs({sessions:s,activeSession:t,onSelect:r}){if(!s||s.length<=1)return null;const n=[...s].sort((a,i)=>se.indexOf(a.type)-se.indexOf(i.type));return e.jsx("div",{className:"pvx-session-tabs",children:n.map(a=>e.jsx("button",{onClick:()=>r(a.type),className:`pvx-session-tab ${t===a.type?"pvx-session-tab--active":""}`,children:a.type},a.type))})}function ke({type:s}){return e.jsx("span",{className:`pvx-comp-badge pvx-comp-badge--${s}`,children:ts[s]||s})}function B({children:s,variant:t="default"}){return e.jsx("span",{className:`pvx-info-pill ${t!=="default"?`pvx-info-pill--${t}`:""}`,children:s})}function Le(s){if(!s)return"TBD";const t=new Date(s);if(isNaN(t))return"TBD";const r=t.toLocaleDateString("en-GB",{weekday:"short",day:"numeric",month:"short"}),n=t.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit"});return`${r} • ${n}`}function ns(s){return s.reduce((t,r)=>{var n;return(n=r.splits)!=null&&n.length?t?t.map((a,i)=>{const l=r.splits[i];return l&&l<a?l:a}):[...r.splits]:t},null)}function F({message:s="Loading..."}){return e.jsx("div",{className:"pvx-loading",children:s})}function M({message:s="No data available."}){return e.jsx("div",{className:"pvx-empty",children:e.jsx("p",{children:s})})}function Re({competitions:s,isLoading:t,onSelect:r,className:n}){return t?e.jsx(F,{message:"Loading competitions..."}):s!=null&&s.length?e.jsx("div",{className:`pvx-comp-grid ${n||""}`,children:s.map(a=>e.jsx(as,{comp:a,onSelect:r},a.id))}):e.jsx(M,{message:"No competitions available."})}function as({comp:s,onSelect:t}){var j,d,u;const{cdnUrl:r}=S(),n=s.posterCdnPath?`${r}/${s.posterCdnPath}`:null,a=s.registration,i=(a==null?void 0:a.currentCount)||0,l=a==null?void 0:a.maxParticipants,o=l&&i>=l,m=(a==null?void 0:a.deadline)&&new Date(a.deadline)<new Date,c=(a==null?void 0:a.isOpen)&&!m&&!o,h=new Date,f=(j=s.rounds)==null?void 0:j.find(p=>p.startTime&&new Date(p.startTime)>=h),v=((d=s.rounds)==null?void 0:d.length)||0,x=((u=s.rounds)==null?void 0:u.filter(p=>p.isFinalized).length)||0;return e.jsxs("div",{className:"pvx-comp-card",onClick:()=>t(s.id),role:"button",tabIndex:0,onKeyDown:p=>{(p.key==="Enter"||p.key===" ")&&(p.preventDefault(),t(s.id))},children:[e.jsx("div",{className:"pvx-comp-card-poster",children:n?e.jsx("img",{src:n,alt:s.name,className:"pvx-comp-card-poster-img"}):e.jsx("div",{className:"pvx-comp-card-poster-placeholder",children:e.jsx(is,{})})}),e.jsxs("div",{className:"pvx-comp-card-body",children:[e.jsx("h3",{className:"pvx-comp-card-title",children:s.name}),s.description&&e.jsx("p",{className:"pvx-comp-card-desc",children:s.description}),e.jsxs("div",{className:"pvx-comp-card-pills",children:[e.jsx(ke,{type:s.type}),s.game&&e.jsx(B,{children:s.game.toUpperCase()}),s.formatDescription&&s.formatDescription.split(", ").map((p,N)=>e.jsx(B,{variant:"format",children:p},N))]}),s.carsDescription&&e.jsx("div",{className:"pvx-comp-card-pills",children:s.carsDescription.split(", ").map((p,N)=>e.jsx(B,{children:p},N))}),e.jsxs("div",{className:"pvx-comp-card-schedule",children:[f?e.jsxs("span",{className:"pvx-comp-card-schedule-next",children:[e.jsx("span",{className:"pvx-comp-card-schedule-label",children:"Next:"})," ","R",f.roundNumber," ",f.track||"TBD"," — ",Le(f.startTime)]}):v>0?e.jsxs("span",{className:"pvx-comp-card-schedule-next",children:[x,"/",v," rounds completed"]}):null,v>0&&e.jsxs("span",{className:"pvx-comp-card-round-count",children:[v," round",v!==1?"s":""]})]}),a&&e.jsxs("div",{className:"pvx-comp-card-reg",children:[e.jsx("span",{className:`pvx-comp-reg-badge ${c?"pvx-comp-reg-badge--open":o?"pvx-comp-reg-badge--full":"pvx-comp-reg-badge--closed"}`,children:c?"Registration Open":o?"Full":"Registration Closed"}),e.jsxs("span",{className:"pvx-comp-reg-count",children:[i,"/",l||"∞"," drivers"]})]})]})]})}function is(){return e.jsxs("svg",{className:"pvx-comp-trophy-icon",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M6 9H4.5a2.5 2.5 0 0 1 0-5H6"}),e.jsx("path",{d:"M18 9h1.5a2.5 2.5 0 0 0 0-5H18"}),e.jsx("path",{d:"M4 22h16"}),e.jsx("path",{d:"M10 14.66V17c0 .55-.47.98-.97 1.21C7.85 18.75 7 20.24 7 22"}),e.jsx("path",{d:"M14 14.66V17c0 .55.47.98.97 1.21C16.15 18.75 17 20.24 17 22"}),e.jsx("path",{d:"M18 2H6v7a6 6 0 0 0 12 0V2Z"})]})}function $e({competitionId:s,className:t}){var o,m;const{data:r,isLoading:n}=le(s),{data:a,isLoading:i}=W(s);if(n||i)return e.jsx(F,{message:"Loading standings..."});if(!((o=r==null?void 0:r.standings)!=null&&o.length))return e.jsx(M,{message:"No standings data yet. Results will appear once rounds are finalised."});const l=((m=a==null?void 0:a.rounds)==null?void 0:m.filter(c=>c.isFinalized))||[];return e.jsxs("div",{className:`pvx-card ${t||""}`,children:[e.jsx("div",{className:"pvx-card-header--split",children:e.jsxs("div",{className:"pvx-card-header-left",children:[e.jsx("h3",{className:"pvx-card-title",children:"Championship Standings"}),e.jsxs("span",{className:"pvx-standings-subtitle",children:["After ",r.roundsCompleted," round",r.roundsCompleted!==1?"s":"",r.countingRounds>0&&` (best ${r.countingRounds} count)`]})]})}),e.jsx("div",{className:"pvx-table-scroll",children:e.jsxs("table",{className:"pvx-table",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"pvx-thead-row",children:[e.jsx("th",{className:"pvx-th pvx-th--narrow",children:"Pos"}),e.jsx("th",{className:"pvx-th",children:"Driver"}),e.jsx("th",{className:"pvx-th pvx-th--center pvx-hidden-below-sm",children:"W"}),e.jsx("th",{className:"pvx-th pvx-th--center pvx-hidden-below-sm",children:"Pod"}),e.jsx("th",{className:"pvx-th pvx-th--center",children:"Points"}),l.map(c=>e.jsxs("th",{className:"pvx-th pvx-th--center pvx-hidden-below-md",title:c.track||`Round ${c.roundNumber}`,children:["R",c.roundNumber]},c.roundNumber))]})}),e.jsx("tbody",{className:"pvx-tbody",children:r.standings.map(c=>e.jsx(os,{driver:c,finalizedRounds:l},c.driverId||c.driverName))})]})})]})}function os({driver:s,finalizedRounds:t}){var l,o,m;const r=s.position<=3,n=new Map(((l=s.roundResults)==null?void 0:l.map(c=>[c.roundNumber,c]))||[]),a=((o=s.roundResults)==null?void 0:o.filter(c=>c.position===1).length)||0,i=((m=s.roundResults)==null?void 0:m.filter(c=>c.position<=3).length)||0;return e.jsxs("tr",{className:`pvx-row ${r?"pvx-row--podium":""}`,children:[e.jsx("td",{className:"pvx-td",children:e.jsx(Te,{position:s.position})}),e.jsxs("td",{className:"pvx-td pvx-td--primary",children:[e.jsx(Se,{nation:s.nation}),s.driverName]}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-sm",children:a||"-"}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-sm",children:i||"-"}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-standings-total",children:s.totalPoints}),t.map(c=>{const h=n.get(c.roundNumber),f=h==null?void 0:h.dropped;return e.jsx("td",{className:`pvx-td pvx-td--center pvx-hidden-below-md ${!f&&(h==null?void 0:h.position)<=3?"pvx-standings-cell--podium":""}`,children:h?e.jsxs("div",{className:`pvx-standings-round-cell ${f?"pvx-standings-round-cell--dropped":""}`,children:[e.jsxs("span",{className:"pvx-standings-round-pos",children:["P",h.position]}),e.jsx("span",{className:"pvx-standings-round-pts",children:h.points})]}):e.jsx("span",{className:"pvx-td--muted",children:"-"})},c.roundNumber)})]})}function Me({competitionId:s,roundNumber:t,className:r}){var h,f;const{data:n,isLoading:a}=ce(s,t),[i,l]=b.useState(null);if(a)return e.jsx(F,{message:"Loading results..."});if(!n)return e.jsx(M,{message:"No results for this round."});const o=n.sessions||[];if(!o.length)return e.jsx(M,{message:"No session data for this round."});const m=i||((h=o.find(v=>v.type==="RACE"))==null?void 0:h.type)||((f=o[0])==null?void 0:f.type),c=o.find(v=>v.type===m)||o[0];return e.jsxs("div",{className:`pvx-round-results ${r||""}`,children:[e.jsxs("div",{className:"pvx-round-results-header",children:[e.jsxs("div",{children:[e.jsxs("h4",{className:"pvx-round-results-title",children:["Round ",n.roundNumber,n.track?`: ${n.track}`:""]}),n.startTime&&e.jsx("p",{className:"pvx-round-results-date",children:new Date(n.startTime).toLocaleDateString("en-GB",{day:"numeric",month:"long",year:"numeric"})})]}),e.jsx(ls,{sessions:o})]}),e.jsx(rs,{sessions:o,activeSession:m,onSelect:l}),e.jsx(cs,{session:c})]})}function ls({sessions:s}){var a;const t=s.find(i=>i.type==="RACE"),r=(a=t==null?void 0:t.results)==null?void 0:a.filter(i=>i.position<=3).sort((i,l)=>i.position-l.position);if(!(r!=null&&r.length))return null;const n=["🥇","🥈","🥉"];return e.jsx("div",{className:"pvx-round-podium-summary",children:r.map(i=>e.jsxs("span",{className:"pvx-round-podium-item",children:[e.jsx("span",{children:n[i.position-1]}),e.jsx("span",{children:i.driverName})]},i.driverId))})}function cs({session:s}){var n;const t=s.type==="RACE";if(!((n=s.results)!=null&&n.length))return e.jsx(M,{message:`No results for ${s.type}.`});const r=ns(s.results);return e.jsx("div",{className:"pvx-table-scroll",children:e.jsxs("table",{className:"pvx-table",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"pvx-thead-row",children:[e.jsx("th",{className:"pvx-th pvx-th--narrow",children:"Pos"}),e.jsx("th",{className:"pvx-th",children:"Driver"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"Car"}),e.jsx("th",{className:"pvx-th",children:"Best Lap"}),t&&e.jsxs(e.Fragment,{children:[e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"Laps"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"Time / Gap"}),e.jsx("th",{className:"pvx-th pvx-th--center",children:"Points"})]})]})}),e.jsx("tbody",{className:"pvx-tbody",children:s.results.map((a,i)=>e.jsx(ds,{result:a,isRace:t,fastestSplits:r,rowIndex:i},a.driverId||i))})]})})}function ds({result:s,isRace:t,fastestSplits:r,rowIndex:n}){const a=s.position<=3;return e.jsxs("tr",{className:`pvx-row ${a?"pvx-row--podium":""}`,children:[e.jsx("td",{className:"pvx-td",children:e.jsx(Te,{position:s.position})}),e.jsxs("td",{className:"pvx-td pvx-td--primary",children:[e.jsx(Se,{nation:s.nation}),s.driverName,s.carNumber!=null&&e.jsxs("span",{className:"pvx-car-number",children:["#",s.carNumber]}),s.penalty&&e.jsx("span",{className:"pvx-penalty",children:s.penalty})]}),e.jsx("td",{className:"pvx-td pvx-hidden-below-sm",children:$(s.carId)}),e.jsx("td",{className:"pvx-td pvx-td--mono",children:e.jsx(ps,{bestLap:s.bestLapFormatted,hasBestLap:s.hasBestLap,splits:s.splits,fastestSplits:r,showAbove:n<=1})}),t&&e.jsxs(e.Fragment,{children:[e.jsx("td",{className:"pvx-td pvx-hidden-below-sm",children:s.lapsCompleted}),e.jsx("td",{className:"pvx-td pvx-td--mono pvx-td--muted pvx-hidden-below-sm",children:s.position===1?s.totalTime||"-":s.gap||"-"}),e.jsxs("td",{className:"pvx-td pvx-td--center",children:[e.jsx("span",{className:"pvx-session-points",children:s.points}),s.pointsOverride!==0&&s.pointsOverride&&e.jsxs("span",{className:"pvx-points-override",children:["(",s.pointsOverride>0?"+":"",s.pointsOverride,")"]})]})]})]})}function ps({bestLap:s,hasBestLap:t,splits:r,fastestSplits:n,showAbove:a}){return s?e.jsxs("span",{className:`pvx-best-lap-cell ${t?"pvx-best-lap-cell--fastest":""}`,children:[e.jsx("span",{className:"pvx-best-lap-time",children:s}),(r==null?void 0:r.length)>0&&e.jsx("span",{className:"pvx-splits-tooltip-anchor",children:e.jsx("span",{className:`pvx-splits-tooltip ${a?"":"pvx-splits-tooltip--above"}`,children:r.map((i,l)=>{const o=n&&i===n[l];return e.jsxs("span",{className:"pvx-splits-tooltip-row",children:[e.jsxs("span",{className:"pvx-splits-tooltip-label",children:["S",l+1]}),e.jsx("span",{className:o?"pvx-splits-tooltip-best":"",children:i})]},l)})})})]}):e.jsx("span",{className:"pvx-td--muted",children:"-"})}function De({competitionId:s,className:t}){const{data:r,isLoading:n}=de(s);if(n)return e.jsx(F,{message:"Loading drivers..."});const a=(r==null?void 0:r.drivers)||(r==null?void 0:r.entries)||[];return a.length?e.jsx("div",{className:`pvx-entry-grid ${t||""}`,children:a.map(i=>{var l,o;return e.jsxs("div",{className:"pvx-entry-card",children:[i.avatarUrl?e.jsx("img",{src:i.avatarUrl,alt:"",className:"pvx-entry-avatar"}):e.jsx("div",{className:"pvx-entry-avatar pvx-entry-avatar--placeholder",children:((o=(l=i.displayName)==null?void 0:l.charAt(0))==null?void 0:o.toUpperCase())||"?"}),e.jsx("span",{className:"pvx-entry-name",children:i.displayName})]},i.steamId||i.driverId)})}):e.jsx(M,{message:"No drivers registered yet."})}const xs=[{id:"standings",label:"Standings"},{id:"rounds",label:"Rounds"},{id:"drivers",label:"Drivers"}];function us({className:s,title:t="Competitions"}){const[r,n]=te.useSearchParams(),a=r.get("competition"),i=r.get("tab")||"standings",l=r.get("round")?Number(r.get("round")):null,{data:o,isLoading:m}=oe();function c(j){n({competition:j})}function h(){n({})}function f(j){n({competition:a,tab:j})}function v(j){n({competition:a,tab:"rounds",round:String(j)})}function x(){n({competition:a,tab:"rounds"})}return a?e.jsx("div",{className:`pvx-comp-explorer ${s||""}`,children:e.jsx(ms,{competitionId:a,activeTab:i,selectedRound:l,onBack:h,onTabChange:f,onSelectRound:v,onDeselectRound:x})}):e.jsxs("div",{className:`pvx-comp-explorer ${s||""}`,children:[e.jsxs("div",{className:"pvx-explorer-header",children:[e.jsx("h2",{className:"pvx-explorer-title",children:t}),!m&&(o==null?void 0:o.length)>0&&e.jsx("div",{className:"pvx-explorer-stats",children:e.jsxs("span",{children:[o.length," competition",o.length!==1?"s":""]})})]}),e.jsx(Re,{competitions:o,isLoading:m,onSelect:c})]})}function ms({competitionId:s,activeTab:t,selectedRound:r,onBack:n,onTabChange:a,onSelectRound:i,onDeselectRound:l}){var j,d;const{data:o,isLoading:m}=W(s);if(m)return e.jsx(F,{message:"Loading competition..."});if(!o)return e.jsxs("div",{children:[e.jsx(M,{message:"Competition not found."}),e.jsx("div",{className:"pvx-comp-back-link-wrap",children:e.jsx("button",{onClick:n,className:"pvx-comp-back-link",children:"← Back to competitions"})})]});const c=o.type==="championship",h=((j=o.rounds)==null?void 0:j.filter(u=>u.isFinalized))||[],f=o.rounds||[],v=xs.filter(u=>!(u.id==="standings"&&!c||u.id==="rounds"&&h.length===0)),x=v.find(u=>u.id===t)?t:((d=v[0])==null?void 0:d.id)||"standings";return e.jsxs(e.Fragment,{children:[e.jsx("button",{onClick:n,className:"pvx-comp-back-link",children:"← Competitions"}),e.jsxs("div",{className:"pvx-comp-detail-header",children:[e.jsx("h2",{className:"pvx-explorer-title",children:o.name}),o.description&&e.jsx("p",{className:"pvx-comp-detail-desc",children:o.description}),e.jsxs("div",{className:"pvx-comp-detail-meta",children:[e.jsx(ke,{type:o.type}),o.game&&e.jsx(B,{children:o.game.toUpperCase()}),o.countingRounds>0&&e.jsxs(B,{variant:"format",children:["Best ",o.countingRounds," of ",f.length," rounds count"]}),f.length>0&&e.jsxs(B,{children:[f.length," round",f.length!==1?"s":""]})]})]}),f.length>0&&e.jsx(vs,{rounds:f}),v.length>1&&e.jsx("div",{className:"pvx-comp-tabs",children:v.map(u=>e.jsx("button",{onClick:()=>a(u.id),className:`pvx-comp-tab ${x===u.id?"pvx-comp-tab--active":""}`,children:u.label},u.id))}),x==="standings"&&e.jsx($e,{competitionId:s}),x==="rounds"&&e.jsx(hs,{competitionId:s,finalizedRounds:h,selectedRound:r,onSelectRound:i,onDeselectRound:l}),x==="drivers"&&e.jsx(De,{competitionId:s})]})}function vs({rounds:s}){const t=new Date,r=s.find(n=>n.startTime&&new Date(n.startTime)>=t);return e.jsx("div",{className:"pvx-comp-schedule",children:e.jsx("div",{className:"pvx-comp-schedule-list",children:s.map(n=>{const a=n===r,i=n.startTime&&new Date(n.startTime)<t;return e.jsxs("div",{className:`pvx-comp-schedule-item ${a?"pvx-comp-schedule-item--next":""} ${i?"pvx-comp-schedule-item--past":""}`,children:[e.jsxs("span",{className:"pvx-comp-schedule-round",children:["R",n.roundNumber]}),e.jsx("span",{className:"pvx-comp-schedule-track",children:n.track||"TBD"}),e.jsx("span",{className:"pvx-comp-schedule-date",children:Le(n.startTime)}),n.isFinalized&&e.jsx("span",{className:"pvx-comp-schedule-badge",children:"Results"})]},n.roundNumber)})})})}function hs({competitionId:s,finalizedRounds:t,selectedRound:r,onSelectRound:n,onDeselectRound:a}){return t.length?e.jsxs("div",{className:"pvx-comp-rounds",children:[e.jsx("div",{className:"pvx-comp-round-pills",children:t.map(i=>e.jsxs("button",{onClick:()=>r===i.roundNumber?a():n(i.roundNumber),className:`pvx-comp-round-pill ${r===i.roundNumber?"pvx-comp-round-pill--active":""}`,children:[e.jsxs("span",{className:"pvx-comp-round-pill-num",children:["R",i.roundNumber]}),i.track&&e.jsx("span",{className:"pvx-comp-round-pill-track",children:i.track})]},i.roundNumber))}),r?e.jsx(Me,{competitionId:s,roundNumber:r}):e.jsx("div",{className:"pvx-empty",children:e.jsx("p",{children:"Select a round to view results."})})]}):e.jsx(M,{message:"No finalised rounds yet."})}function js({competitionId:s,driverData:t,className:r,children:n}){const{data:a,isLoading:i}=xe(s),l=ue(s),o=me(s),m=(a==null?void 0:a.isRegistered)||!1,c=i||l.isPending||o.isPending,h=l.error||o.error||null,f=()=>{t&&l.mutate(t)},v=()=>{o.mutate()};return typeof n=="function"?n({isRegistered:m,isLoading:c,register:f,withdraw:v,error:h}):e.jsx("button",{className:r,onClick:m?v:f,disabled:c,children:c?"Loading...":m?"Withdraw":"Register"})}exports.CarsTable=ye;exports.CompetitionCards=Re;exports.CompetitionExplorer=us;exports.DriversTable=Ce;exports.EntryList=De;exports.LapHistoryTable=we;exports.LeaderboardExplorer=es;exports.PitVoxPartnerProvider=Ve;exports.RegisterButton=js;exports.RoundResults=Me;exports.StandingsTable=$e;exports.TracksTable=be;exports.formatCarName=$;exports.formatDate=A;exports.formatDelta=Oe;exports.formatLapTime=E;exports.formatRelativeTime=Ke;exports.formatSectorTime=I;exports.formatTrackName=Q;exports.formatTyreCompound=H;exports.useCarLeaderboard=Qe;exports.useCarMetadata=ie;exports.useCompetitionAllRounds=He;exports.useCompetitionConfig=W;exports.useCompetitionEntryList=de;exports.useCompetitionRound=ce;exports.useCompetitionStandings=le;exports.useCompetitions=oe;exports.useDriverLaps=ne;exports.useLeaderboardIndex=re;exports.usePitVox=S;exports.useRegister=ue;exports.useRegistrationStatus=xe;exports.useTrackLeaderboard=G;exports.useUserLookup=ae;exports.useWithdraw=me;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),b=require("react"),y=require("@tanstack/react-query"),ae=require("react-router-dom"),Q=b.createContext(null),We="https://cdn.pitvox.com",Ge="https://api.pitvox.com";let H=null;function ze({partnerSlug:s,apiKey:r,cdnUrl:t=We,apiUrl:a=Ge,getSteamId:n,children:i}){const l=b.useMemo(()=>({partnerSlug:s,apiKey:r,cdnUrl:t.replace(/\/$/,""),apiUrl:a.replace(/\/$/,""),getSteamId:n||(()=>null)}),[s,r,t,a,n]);let o=!1;try{y.useQueryClient(),o=!0}catch{o=!1}return o?e.jsx(Q.Provider,{value:l,children:i}):(H||(H=new y.QueryClient({defaultOptions:{queries:{staleTime:6e4}}})),e.jsx(y.QueryClientProvider,{client:H,children:e.jsx(Q.Provider,{value:l,children:i})}))}function w(){const s=b.useContext(Q);if(!s)throw new Error("usePitVox must be used within a <PitVoxPartnerProvider>");return s}async function S(s,r){const t=await fetch(`${s}/${r}`);if(!t.ok){if(t.status===404||t.status===403)return null;throw new Error(`CDN fetch failed: ${t.status}`)}return t.json()}function P(s){if(!s&&s!==0)return"-";const r=Math.floor(s/1e3),t=Math.floor(r/60),a=r%60,n=s%1e3;return`${t}:${String(a).padStart(2,"0")}.${String(n).padStart(3,"0")}`}function I(s){return!s&&s!==0?"-":(s/1e3).toFixed(3)}function $(s){if(!s)return"";let r=s;return r.startsWith("ks_")&&(r=r.slice(3)),r.split("_").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}function F(s,r,t){const a=s.split("_").map(l=>l.charAt(0).toUpperCase()+l.slice(1)).join(" "),n=t==="acc"||!t&&(r==null?void 0:r.toLowerCase())==="track config";if(!r||r==="default"||n)return a;const i=r.split("_").map(l=>l.charAt(0).toUpperCase()+l.slice(1)).join(" ");return`${a} ${i}`}function E(s){if(!s)return"-";try{return new Date(s).toLocaleDateString("en-GB",{day:"numeric",month:"short",year:"numeric"})}catch{return"-"}}function Je(s){if(!s)return"";const r=Date.now()-new Date(s).getTime(),t=Math.floor(r/1e3);if(t<60)return"Just now";const a=Math.floor(t/60);if(a<60)return`${a}m ago`;const n=Math.floor(a/60);if(n<24)return`${n}h ago`;const i=Math.floor(n/24);return i<30?`${i}d ago`:E(s)}function Ze(s){return s==null?"":`${s>=0?"+":"-"}${(Math.abs(s)/1e3).toFixed(3)}`}function O(s){return s?{E:"Eco",RD:"Road",SC:"SuperCar",RV:"Race Vintage",SM:"Semislick",ST:"Street",HR:"Hard Race",MR:"Medium Race",SR:"Soft Race",S:"Soft"}[s]||s:"Unknown"}function ne(s={}){var o,x,c,v,g,h;const{cdnUrl:r,partnerSlug:t}=w(),{game:a,gameVersion:n}=s,i=y.useQuery({queryKey:["pitvox","leaderboards",t,"index"],queryFn:()=>S(r,`leaderboards/partners/${t}/index.json`),staleTime:3e4,refetchInterval:3e4}),l=b.useMemo(()=>{var j;if(!((j=i.data)!=null&&j.tracks))return[];let u=i.data.tracks;return a&&(u=u.filter(d=>d.game===a)),n&&(u=u.filter(d=>d.gameVersion===n)),u.map(d=>({id:d.trackId,layout:d.layout,game:d.game,gameVersion:d.gameVersion,displayName:F(d.trackId,d.layout,d.game),driverCount:d.driverCount||0,carCount:d.carCount||0,record:d.recordHolder?{visibleId:d.recordHolder.steamId||d.recordHolder.userId,carId:d.recordHolder.carId,carDisplayName:$(d.recordHolder.carId),lapTimeMs:d.recordHolder.lapTimeMs,timestamp:d.recordHolder.recordedAt}:null,recordByTag:d.recordByTag||null}))},[(o=i.data)==null?void 0:o.tracks,a,n]);return{...i,data:l,partner:((x=i.data)==null?void 0:x.partner)||null,generatedAt:(c=i.data)==null?void 0:c.generatedAt,totalLaps:((v=i.data)==null?void 0:v.totalLaps)||0,totalUsers:((g=i.data)==null?void 0:g.totalUsers)||0,versions:((h=i.data)==null?void 0:h.versions)||{}}}function W(s,r,t={}){const{cdnUrl:a,partnerSlug:n}=w(),{carId:i,game:l,gameVersion:o}=t,x=r||"default",c=o?`leaderboards/partners/${n}/v/${o}/tracks/${s}/${x}.json`:`leaderboards/partners/${n}/tracks/${s}/${x}.json`,{data:v,isLoading:g,error:h}=y.useQuery({queryKey:["pitvox","leaderboards",n,"track",s,x,o],queryFn:()=>S(a,c),enabled:!!s,staleTime:3e4,refetchInterval:3e4});return{data:b.useMemo(()=>{if(!(v!=null&&v.entries))return[];let j=v.entries;if(l&&(j=j.filter(d=>d.game===l)),!i){const d=new Map,m=new Map;for(const p of j){const N=p.steamId||p.userId;m.has(p.carId)||m.set(p.carId,new Set),m.get(p.carId).add(N),(!d.has(p.carId)||p.lapTimeMs<d.get(p.carId).lapTimeMs)&&d.set(p.carId,p)}return Array.from(d.values()).map(p=>{var N;return{...p,driverCount:((N=m.get(p.carId))==null?void 0:N.size)||0}}).sort((p,N)=>p.lapTimeMs-N.lapTimeMs)}return j.filter(d=>d.carId===i).sort((d,m)=>d.lapTimeMs-m.lapTimeMs)},[v==null?void 0:v.entries,i,l]),isLoading:g,error:h}}function ie(s,r,t,a,n={}){var h,u;const{cdnUrl:i,partnerSlug:l}=w(),{showInvalid:o=!1,game:x,gameVersion:c}=n,v=y.useQuery({queryKey:["pitvox","laps",l,s],queryFn:()=>S(i,`laps/partners/${l}/${s}.json`),enabled:!!s,staleTime:3e4,refetchInterval:3e4}),g=b.useMemo(()=>{var j;return(j=v.data)!=null&&j.laps?v.data.laps.filter(d=>{if(d.trackId!==r)return!1;if(t){if(d.trackLayout!==t)return!1}else if(d.trackLayout&&d.trackLayout!=="default")return!1;return!(d.carId!==a||x&&d.game!==x||c&&d.gameVersion!==c||!o&&!d.isValid)}).sort((d,m)=>d.lapTimeMs-m.lapTimeMs):[]},[(h=v.data)==null?void 0:h.laps,r,t,a,x,c,o]);return{...v,data:g,driverName:((u=v.data)==null?void 0:u.driverName)||"Driver"}}function oe(){const{cdnUrl:s}=w(),{data:r}=y.useQuery({queryKey:["pitvox","users","index"],queryFn:()=>S(s,"users/index.json"),staleTime:5*6e4,gcTime:30*6e4}),t=(r==null?void 0:r.users)||{};return(a,n)=>{const i=t[a];return{displayName:(i==null?void 0:i.displayName)||n||a||"Unknown",avatarUrl:(i==null?void 0:i.avatarUrl)||null,affiliations:(i==null?void 0:i.affiliations)||[]}}}function le(){const{cdnUrl:s}=w(),{data:r}=y.useQuery({queryKey:["pitvox","cars","index"],queryFn:()=>S(s,"cars/index.json"),staleTime:5*6e4,gcTime:30*6e4});return{tags:(r==null?void 0:r.tags)||[],cars:(r==null?void 0:r.cars)||{}}}function Xe(s,r){return W(s,null,{carId:r})}function ce(){const{cdnUrl:s,partnerSlug:r}=w();return y.useQuery({queryKey:["pitvox","competitions",r],queryFn:async()=>{const t=await S(s,"competitions/index.json");return t!=null&&t.competitions?t.competitions.filter(a=>a.partnerSlug===r):[]},staleTime:6e4})}function G(s){const{cdnUrl:r,partnerSlug:t}=w();return y.useQuery({queryKey:["pitvox","competition",t,s,"config"],queryFn:()=>S(r,`competitions/${t}/${s}/config.json`),enabled:!!s,staleTime:6e4})}function de(s){const{cdnUrl:r,partnerSlug:t}=w();return y.useQuery({queryKey:["pitvox","competition",t,s,"standings"],queryFn:()=>S(r,`competitions/${t}/${s}/standings.json`),enabled:!!s,staleTime:6e4})}function pe(s,r){const{cdnUrl:t,partnerSlug:a}=w();return y.useQuery({queryKey:["pitvox","competition",a,s,"round",r],queryFn:()=>S(t,`competitions/${a}/${s}/rounds/${r}.json`),enabled:!!s&&r!=null,staleTime:6e4})}function Ye(s,r=[]){const{cdnUrl:t,partnerSlug:a}=w();return y.useQuery({queryKey:["pitvox","competition",a,s,"allRounds",r],queryFn:async()=>(await Promise.all(r.map(i=>S(t,`competitions/${a}/${s}/rounds/${i}.json`).catch(()=>null)))).filter(Boolean),enabled:!!s&&r.length>0,staleTime:6e4})}function xe(s){const{cdnUrl:r,partnerSlug:t}=w();return y.useQuery({queryKey:["pitvox","competition",t,s,"entrylist"],queryFn:()=>S(r,`competitions/${t}/${s}/entrylist.json`),enabled:!!s,staleTime:6e4})}async function ue(s,r,t,a={}){const n=await fetch(`${s}${t}`,{...a,headers:{"Content-Type":"application/json","X-Partner-Key":r,...a.headers}});if(!n.ok){const i=await n.json().catch(()=>({}));throw new Error(i.detail||`API request failed: ${n.status}`)}return n.json()}function es(s,r,t,a){return ue(s,r,`/api/v1/competitions/${t}/register`,{method:"POST",body:JSON.stringify(a)})}function ss(s,r,t,a){return ue(s,r,`/api/v1/competitions/${t}/register/${a}`,{method:"DELETE"})}function me(s){const{cdnUrl:r,partnerSlug:t,getSteamId:a}=w(),n=a();return y.useQuery({queryKey:["pitvox","registration",t,s,n],queryFn:async()=>{var x;const i=await fetch(`${r}/competitions/${t}/${s}/entrylist.json`);if(!i.ok)return{isRegistered:!1,entryList:null};const l=await i.json();return{isRegistered:!!n&&((x=l.drivers)==null?void 0:x.some(c=>c.steamId===n)),entryList:l}},enabled:!!s,staleTime:6e4})}function he(s){const{apiUrl:r,apiKey:t,partnerSlug:a}=w(),n=y.useQueryClient();return y.useMutation({mutationFn:i=>es(r,t,s,i),onSuccess:()=>{n.invalidateQueries({queryKey:["pitvox","registration",a,s]}),n.invalidateQueries({queryKey:["pitvox","competition",a,s,"entrylist"]})}})}function ve(s){const{apiUrl:r,apiKey:t,partnerSlug:a,getSteamId:n}=w(),i=y.useQueryClient();return y.useMutation({mutationFn:l=>{const o=l||n();if(!o)throw new Error("No Steam ID available");return ss(r,t,s,o)},onSuccess:()=>{i.invalidateQueries({queryKey:["pitvox","registration",a,s]}),i.invalidateQueries({queryKey:["pitvox","competition",a,s,"entrylist"]})}})}const ts={formula:"Formula",gt3:"GT3",gt2:"GT2",gt4:"GT4",cup:"Cup",prototype:"Prototype",rally:"Rally",hypercar:"Hypercar",supercar:"Supercar",sports_car:"Sports Car",hot_hatch:"Hot Hatch",lightweight:"Lightweight","1960s":"1960s","1970s":"1970s","1980s":"1980s","1990s":"1990s","2000s":"2000s","2010s":"2010s","2020s":"2020s"},je=[{id:"class",tags:["formula","gt3","gt2","gt4","cup","prototype","rally"]},{id:"tier",tags:["hypercar","supercar","sports_car","hot_hatch","lightweight"]},{id:"era",tags:["1960s","1970s","1980s","1990s","2000s","2010s","2020s"]}];function rs(s){for(const r of je)if(r.tags.includes(s))return r.id;return"other"}function ge(s,r){if(r.size===0)return!0;const t={};for(const a of r){const n=rs(a);t[n]||(t[n]=[]),t[n].push(a)}for(const a of Object.values(t))if(!a.some(n=>s.includes(n)))return!1;return!0}function fe(){const[s,r]=b.useState(new Set),t=b.useCallback(n=>{r(i=>{const l=new Set(i);return l.has(n)?l.delete(n):l.add(n),l})},[]),a=b.useCallback(()=>r(new Set),[]);return{activeTags:s,toggle:t,clear:a}}function z(s){const[r,t]=b.useState(s),a=b.useCallback(n=>{t(i=>i.key===n?{key:n,dir:i.dir==="asc"?"desc":"asc"}:{key:n,dir:n.includes("timestamp")||n.includes("Date")?"desc":"asc"})},[]);return[r,a]}function J(s,r,t){return[...s].sort((a,n)=>{const i=t(a,r.key),l=t(n,r.key);if(i==null&&l==null)return 0;if(i==null)return 1;if(l==null)return-1;const o=typeof i=="string"?i.localeCompare(l):i-l;return r.dir==="desc"?-o:o})}function Ne(s,r=!1){const t=r?s==null?void 0:s.filter(a=>a.isValid):s;return t!=null&&t.length?{s1:Math.min(...t.map(a=>a.sector1Ms).filter(Boolean)),s2:Math.min(...t.map(a=>a.sector2Ms).filter(Boolean)),s3:Math.min(...t.map(a=>a.sector3Ms).filter(Boolean))}:null}function as({active:s,dir:r}){return s?r==="asc"?e.jsx("svg",{className:"pvx-sort-icon",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4.5 15.75l7.5-7.5 7.5 7.5"})}):e.jsx("svg",{className:"pvx-sort-icon",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M19.5 8.25l-7.5 7.5-7.5-7.5"})}):e.jsx("svg",{className:"pvx-sort-icon pvx-sort-icon--inactive",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8 9l4-4 4 4M16 15l-4 4-4-4"})})}function R({label:s,sortKey:r,config:t,onSort:a,className:n=""}){return e.jsx("th",{className:`pvx-th pvx-th--sortable ${n}`,onClick:()=>a(r),children:e.jsxs("span",{className:"pvx-th-inner",children:[s,e.jsx(as,{active:t.key===r,dir:t.dir})]})})}function Z({userId:s,getUserDisplay:r}){const{displayName:t,avatarUrl:a}=r(s);return e.jsxs("span",{className:"pvx-driver",children:[a?e.jsx("img",{src:a,alt:"",className:"pvx-driver-avatar"}):e.jsx("span",{className:"pvx-driver-avatar pvx-driver-avatar--placeholder"}),e.jsx("span",{className:"pvx-driver-name",children:t})]})}function be({rank:s,podium:r=!1}){const t=r?s===1?"pvx-rank pvx-rank--gold":s===2?"pvx-rank pvx-rank--silver":s===3?"pvx-rank pvx-rank--bronze":"pvx-rank":"pvx-rank";return e.jsx("span",{className:t,children:s})}function ye({availableTags:s,activeTags:r,onToggle:t,onClear:a}){if(!s||s.length<2)return null;const n=je.map(i=>({id:i.id,tags:i.tags.filter(l=>s.includes(l))})).filter(i=>i.tags.length>0);return e.jsxs("div",{className:"pvx-tag-bar",children:[e.jsx("button",{onClick:a,className:`pvx-tag ${r.size===0?"pvx-tag--active":""}`,children:"All"}),n.map((i,l)=>e.jsxs("span",{className:"contents",children:[l>0&&e.jsx("span",{className:"pvx-tag-separator"}),i.tags.map(o=>e.jsx("button",{onClick:()=>t(o),className:`pvx-tag ${r.has(o)?"pvx-tag--active":""}`,children:ts[o]||o},o))]},i.id))]})}function X({segments:s}){return e.jsx("nav",{className:"pvx-breadcrumb","aria-label":"Breadcrumb",children:e.jsx("ol",{className:"pvx-breadcrumb-list",children:s.map((r,t)=>{const a=t===s.length-1;return e.jsxs("li",{className:"pvx-breadcrumb-item",children:[t>0&&e.jsx("svg",{className:"pvx-breadcrumb-chevron",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M8.25 4.5l7.5 7.5-7.5 7.5"})}),!a&&r.onClick?e.jsx("button",{onClick:r.onClick,className:"pvx-breadcrumb-link",children:r.label}):e.jsx("span",{className:"pvx-breadcrumb-current",children:r.label})]},r.key)})})})}function _({message:s}){return e.jsxs("div",{className:"pvx-empty",children:[e.jsx("svg",{className:"pvx-empty-icon",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M16.5 18.75h-9m9 0a3 3 0 013 3h-15a3 3 0 013-3m9 0v-4.5A3.375 3.375 0 0013.125 10.875h-2.25A3.375 3.375 0 007.5 14.25v4.5"})}),e.jsx("p",{children:s})]})}function V(){return e.jsx("div",{className:"pvx-loading",children:"Loading..."})}function ns(){return e.jsx("svg",{className:"pvx-icon pvx-icon--valid",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M4.5 12.75l6 6 9-13.5"})})}function is(){return e.jsx("svg",{className:"pvx-icon pvx-icon--invalid",fill:"none",viewBox:"0 0 24 24",strokeWidth:2,stroke:"currentColor",children:e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M6 18L18 6M6 6l12 12"})})}function Ce({tracks:s,isLoading:r,carMetadata:t,getUserDisplay:a,onTrackSelect:n}){const[i,l]=z({key:"record.timestamp",dir:"desc"}),{activeTags:o,toggle:x,clear:c}=fe(),v=b.useMemo(()=>{var j;if(!((j=t==null?void 0:t.tags)!=null&&j.length))return[];const u=new Set;for(const d of s||[])d.recordByTag&&Object.keys(d.recordByTag).forEach(m=>u.add(m));return t.tags.filter(d=>u.has(d))},[s,t]),g=b.useMemo(()=>s?o.size===0?s:s.map(u=>{var m,p;if(!u.recordByTag)return null;let j=null;const d=new Set;for(const N of Object.values(u.recordByTag)){if(d.has(N.carId))continue;d.add(N.carId);const C=((p=(m=t==null?void 0:t.cars)==null?void 0:m[N.carId])==null?void 0:p.tags)||["sports_car"];ge(C,o)&&(!j||N.lapTimeMs<j.lapTimeMs)&&(j=N)}return j?{...u,record:{visibleId:j.steamId||j.identifier,carId:j.carId,carDisplayName:$(j.carId),lapTimeMs:j.lapTimeMs,timestamp:j.recordedAt}}:null}).filter(Boolean):[],[s,o,t]),h=b.useMemo(()=>J(g,i,(u,j)=>{var d,m;switch(j){case"displayName":return u.displayName;case"record.lapTimeMs":return(d=u.record)==null?void 0:d.lapTimeMs;case"driverCount":return u.driverCount||0;case"carCount":return u.carCount||0;case"record.timestamp":default:return(m=u.record)!=null&&m.timestamp?new Date(u.record.timestamp).getTime():0}}),[g,i]);return r?e.jsx(V,{}):s!=null&&s.length?e.jsxs("div",{className:"pvx-card",children:[e.jsx("div",{className:"pvx-card-header",children:e.jsx("h2",{className:"pvx-card-title",children:"Track Records"})}),e.jsx(ye,{availableTags:v,activeTags:o,onToggle:x,onClear:c}),e.jsx("div",{className:"pvx-table-scroll",children:e.jsxs("table",{className:"pvx-table",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"pvx-thead-row",children:[e.jsx(R,{label:"Track",sortKey:"displayName",config:i,onSort:l}),e.jsx("th",{className:"pvx-th",children:"Record Holder"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-lg",children:"Car"}),e.jsx(R,{label:"Lap Time",sortKey:"record.lapTimeMs",config:i,onSort:l}),e.jsx(R,{label:"Drivers",sortKey:"driverCount",config:i,onSort:l,className:"pvx-hidden-below-md"}),e.jsx(R,{label:"Cars",sortKey:"carCount",config:i,onSort:l,className:"pvx-hidden-below-lg"}),e.jsx(R,{label:"Date",sortKey:"record.timestamp",config:i,onSort:l,className:"pvx-hidden-below-xl"})]})}),e.jsx("tbody",{className:"pvx-tbody",children:h.map(u=>{var j,d,m;return e.jsxs("tr",{className:"pvx-row pvx-row--clickable",onClick:()=>n(u.id,u.layout),children:[e.jsx("td",{className:"pvx-td pvx-td--primary",children:u.displayName}),e.jsx("td",{className:"pvx-td",children:(j=u.record)!=null&&j.visibleId?e.jsx(Z,{userId:u.record.visibleId,getUserDisplay:a}):"-"}),e.jsx("td",{className:"pvx-td pvx-hidden-below-lg",children:((d=u.record)==null?void 0:d.carDisplayName)||"-"}),e.jsx("td",{className:"pvx-td pvx-td--primary pvx-td--mono",children:u.record?P(u.record.lapTimeMs):"-"}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-md",children:u.driverCount||"-"}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-lg",children:u.carCount||"-"}),e.jsx("td",{className:"pvx-td pvx-td--muted pvx-hidden-below-xl",children:(m=u.record)!=null&&m.timestamp?E(u.record.timestamp):"-"})]},`${u.id}|${u.layout||""}`)})})]})})]}):e.jsx(_,{message:"No lap times recorded yet."})}function ke({entries:s,isLoading:r,track:t,carMetadata:a,getUserDisplay:n,onCarSelect:i,onNavigate:l}){const[o,x]=z({key:"lapTimeMs",dir:"asc"}),{activeTags:c,toggle:v,clear:g}=fe(),h=b.useMemo(()=>{var p,N,C;if(!s||!((p=a==null?void 0:a.tags)!=null&&p.length))return[];const m=new Set;for(const L of s)(((C=(N=a.cars)==null?void 0:N[L.carId])==null?void 0:C.tags)||["sports_car"]).forEach(T=>m.add(T));return a.tags.filter(L=>m.has(L))},[s,a]),u=b.useMemo(()=>s?c.size===0?s:s.filter(m=>{var N,C;const p=((C=(N=a==null?void 0:a.cars)==null?void 0:N[m.carId])==null?void 0:C.tags)||["sports_car"];return ge(p,c)}):[],[s,c,a]),j=b.useMemo(()=>J(u,o,(m,p)=>{switch(p){case"carId":return $(m.carId);case"driverCount":return m.driverCount||0;case"lapTimeMs":default:return m.lapTimeMs}}),[u,o]),d=[{key:"tracks",label:"Tracks",onClick:()=>l("tracks")},{key:"track",label:t.displayName}];return r?e.jsx(V,{}):e.jsxs("div",{className:"pvx-card",children:[e.jsx("div",{className:"pvx-card-header",children:e.jsx(X,{segments:d})}),e.jsx(ye,{availableTags:h,activeTags:c,onToggle:v,onClear:g}),s!=null&&s.length?e.jsx("div",{className:"pvx-table-scroll",children:e.jsxs("table",{className:"pvx-table",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"pvx-thead-row",children:[e.jsx("th",{className:"pvx-th pvx-th--narrow",children:"#"}),e.jsx(R,{label:"Car",sortKey:"carId",config:o,onSort:x}),e.jsx("th",{className:"pvx-th",children:"Record Holder"}),e.jsx(R,{label:"Lap Time",sortKey:"lapTimeMs",config:o,onSort:x}),e.jsx(R,{label:"Drivers",sortKey:"driverCount",config:o,onSort:x,className:"pvx-hidden-below-md"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-lg",children:"Date"})]})}),e.jsx("tbody",{className:"pvx-tbody",children:j.map((m,p)=>e.jsxs("tr",{className:"pvx-row pvx-row--clickable",onClick:()=>i(m.carId),children:[e.jsx("td",{className:"pvx-td",children:e.jsx(be,{rank:p+1,podium:!0})}),e.jsx("td",{className:"pvx-td pvx-td--primary",children:$(m.carId)}),e.jsx("td",{className:"pvx-td",children:e.jsx(Z,{userId:m.steamId||m.userId,getUserDisplay:n})}),e.jsx("td",{className:"pvx-td pvx-td--primary pvx-td--mono",children:P(m.lapTimeMs)}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-md",children:m.driverCount||"-"}),e.jsx("td",{className:"pvx-td pvx-td--muted pvx-hidden-below-lg",children:m.recordedAt?E(m.recordedAt):"-"})]},m.carId))})]})}):e.jsx(_,{message:"No lap times for this track yet."})]})}function we({entries:s,isLoading:r,track:t,carId:a,getUserDisplay:n,onDriverSelect:i,onNavigate:l}){const[o,x]=z({key:"lapTimeMs",dir:"asc"}),c=b.useMemo(()=>Ne(s),[s]),v=b.useMemo(()=>J(s||[],o,(h,u)=>{switch(u){case"userId":return n(h.steamId||h.userId).displayName;case"lapCount":return h.lapCount||0;case"lapTimeMs":default:return h.lapTimeMs}}),[s,o,n]),g=[{key:"tracks",label:"Tracks",onClick:()=>l("tracks")},{key:"track",label:t.displayName,onClick:()=>l("track")},{key:"car",label:$(a)}];return r?e.jsx(V,{}):e.jsxs("div",{className:"pvx-card",children:[e.jsx("div",{className:"pvx-card-header",children:e.jsx(X,{segments:g})}),s!=null&&s.length?e.jsx("div",{className:"pvx-table-scroll",children:e.jsxs("table",{className:"pvx-table",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"pvx-thead-row",children:[e.jsx("th",{className:"pvx-th pvx-th--narrow",children:"#"}),e.jsx(R,{label:"Driver",sortKey:"userId",config:o,onSort:x}),e.jsx(R,{label:"Lap Time",sortKey:"lapTimeMs",config:o,onSort:x}),e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"S1"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"S2"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"S3"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-lg",children:"Tyre"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-xl",children:"Fuel"}),e.jsx(R,{label:"Laps",sortKey:"lapCount",config:o,onSort:x,className:"pvx-hidden-below-lg"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-xl",children:"Date"})]})}),e.jsx("tbody",{className:"pvx-tbody",children:v.map((h,u)=>{const j=u+1,d=h.steamId||h.userId,m=c&&h.sector1Ms===c.s1,p=c&&h.sector2Ms===c.s2,N=c&&h.sector3Ms===c.s3;return e.jsxs("tr",{className:`pvx-row pvx-row--clickable ${j<=3?"pvx-row--podium":""}`,onClick:()=>i(d),children:[e.jsx("td",{className:"pvx-td",children:e.jsx(be,{rank:j,podium:!0})}),e.jsx("td",{className:"pvx-td pvx-td--primary",children:e.jsx(Z,{userId:d,getUserDisplay:n})}),e.jsx("td",{className:"pvx-td pvx-td--primary pvx-td--mono",children:P(h.lapTimeMs)}),e.jsx("td",{className:`pvx-td pvx-td--mono pvx-td--sector pvx-hidden-below-sm ${m?"pvx-td--best-sector":""}`,children:I(h.sector1Ms)}),e.jsx("td",{className:`pvx-td pvx-td--mono pvx-td--sector pvx-hidden-below-sm ${p?"pvx-td--best-sector":""}`,children:I(h.sector2Ms)}),e.jsx("td",{className:`pvx-td pvx-td--mono pvx-td--sector pvx-hidden-below-sm ${N?"pvx-td--best-sector":""}`,children:I(h.sector3Ms)}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-lg",title:O(h.tyreCompound),children:h.tyreCompound||"-"}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-xl",children:h.startingFuelL?`${h.startingFuelL}L`:"-"}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-lg",children:h.lapCount||"-"}),e.jsx("td",{className:"pvx-td pvx-td--muted pvx-hidden-below-xl",children:h.recordedAt?E(h.recordedAt):"-"})]},d)})})]})}):e.jsx(_,{message:"No lap times for this car yet."})]})}function Te({userId:s,track:r,carId:t,game:a,gameVersion:n,showInvalid:i,getUserDisplay:l,onToggleInvalid:o,onNavigate:x}){const{data:c,driverName:v,isLoading:g}=ie(s,r.id,r.layout,t,{showInvalid:i,game:a,gameVersion:n}),{displayName:h,avatarUrl:u}=l(s,v),j=b.useMemo(()=>Ne(c,!0),[c]),d=b.useMemo(()=>{const p=(c==null?void 0:c.filter(N=>N.isValid))||[];return p.length?Math.min(...p.map(N=>N.lapTimeMs)):null},[c]),m=[{key:"tracks",label:"Tracks",onClick:()=>x("tracks")},{key:"track",label:r.displayName,onClick:()=>x("track")},{key:"car",label:$(t),onClick:()=>x("car")},{key:"driver",label:h}];return g?e.jsx(V,{}):e.jsxs("div",{className:"pvx-card",children:[e.jsxs("div",{className:"pvx-card-header pvx-card-header--split",children:[e.jsxs("div",{className:"pvx-card-header-left",children:[e.jsx(X,{segments:m}),u?e.jsx("img",{src:u,alt:"",className:"pvx-driver-avatar pvx-driver-avatar--lg"}):e.jsx("span",{className:"pvx-driver-avatar pvx-driver-avatar--lg pvx-driver-avatar--placeholder"})]}),e.jsxs("label",{className:"pvx-checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:i,onChange:o,className:"pvx-checkbox"}),e.jsx("span",{children:"Show invalid laps"})]})]}),c!=null&&c.length?e.jsx("div",{className:"pvx-table-scroll",children:e.jsxs("table",{className:"pvx-table",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"pvx-thead-row",children:[e.jsx("th",{className:"pvx-th pvx-th--narrow",children:"#"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-md",children:"Lap"}),e.jsx("th",{className:"pvx-th",children:"Lap Time"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"S1"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"S2"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"S3"}),e.jsx("th",{className:"pvx-th pvx-th--narrow",children:"Valid"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-lg",children:"Tyre"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-lg",children:"Fuel"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-xl",children:"Date"})]})}),e.jsx("tbody",{className:"pvx-tbody",children:c.map((p,N)=>{const C=p.isValid&&p.lapTimeMs===d,L=j&&p.isValid&&p.sector1Ms===j.s1,q=j&&p.isValid&&p.sector2Ms===j.s2,T=j&&p.isValid&&p.sector3Ms===j.s3;let B="pvx-row";return p.isValid||(B+=" pvx-row--invalid"),C&&(B+=" pvx-row--personal-best"),e.jsxs("tr",{className:B,children:[e.jsx("td",{className:"pvx-td",children:e.jsx("span",{className:`pvx-rank ${C?"pvx-rank--gold":""}`,children:N+1})}),e.jsx("td",{className:"pvx-td pvx-td--muted pvx-hidden-below-md",children:p.lapNumber||"-"}),e.jsx("td",{className:"pvx-td pvx-td--primary pvx-td--mono",children:P(p.lapTimeMs)}),e.jsx("td",{className:`pvx-td pvx-td--mono pvx-td--sector pvx-hidden-below-sm ${L?"pvx-td--best-sector":""}`,children:I(p.sector1Ms)}),e.jsx("td",{className:`pvx-td pvx-td--mono pvx-td--sector pvx-hidden-below-sm ${q?"pvx-td--best-sector":""}`,children:I(p.sector2Ms)}),e.jsx("td",{className:`pvx-td pvx-td--mono pvx-td--sector pvx-hidden-below-sm ${T?"pvx-td--best-sector":""}`,children:I(p.sector3Ms)}),e.jsx("td",{className:"pvx-td",title:p.isValid?void 0:p.invalidReason||"Invalid",children:p.isValid?e.jsx(ns,{}):e.jsx(is,{})}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-lg",title:O(p.tyreCompound),children:p.tyreCompound||"-"}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-lg",children:p.startingFuelL?`${p.startingFuelL}L`:"-"}),e.jsx("td",{className:"pvx-td pvx-td--muted pvx-hidden-below-xl",children:E(p.timestamp)})]},p.id)})})]})}):e.jsx(_,{message:i?"No laps recorded for this combination.":'No valid laps. Try enabling "Show invalid laps".'})]})}function os({className:s,defaultGame:r="evo",title:t="Leaderboards"}){const[a,n]=ae.useSearchParams(),i=oe(),l=le(),o=a.get("game")||r,x=a.get("version"),c=a.get("track"),v=a.get("car"),g=a.get("driver"),h=a.get("invalid")==="true",{data:u,isLoading:j,generatedAt:d,totalLaps:m,totalUsers:p,versions:N}=ne({game:o}),C=N==null?void 0:N[o],L=x||(C==null?void 0:C.default)||null,q=b.useMemo(()=>!u||!L?u||[]:u.filter(f=>f.gameVersion===L),[u,L]),T=b.useMemo(()=>{if(!c)return null;const[f,k]=c.split("|");return{id:f,layout:k||null,displayName:F(f,k,o)}},[c,o]),{data:B,isLoading:Y}=W(T==null?void 0:T.id,T==null?void 0:T.layout,{carId:v,game:o,gameVersion:L});function D(f){n(f)}function qe(f){D({game:f})}function _e(f){const k={game:o};f&&f!==(C==null?void 0:C.default)&&(k.version=f),D(k)}function Ve(f,k){const ee={game:o,track:k?`${f}|${k}`:f};x&&(ee.version=x),D(ee)}function Ke(f){const k={game:o,track:c};x&&(k.version=x),f&&(k.car=f),D(k)}function He(f){const k={game:o,track:c,car:v,driver:f};x&&(k.version=x),D(k)}function K(f){const k={game:o};x&&(k.version=x),(f==="track"||f==="car")&&(k.track=c),f==="car"&&(k.car=v),D(k)}function Qe(){const f={game:o,track:c,car:v,driver:g};x&&(f.version=x),h||(f.invalid="true"),D(f)}const Oe=()=>T&&v&&g?e.jsx(Te,{userId:g,track:T,carId:v,game:o,gameVersion:L,showInvalid:h,getUserDisplay:i,onToggleInvalid:Qe,onNavigate:K}):T&&v?e.jsx(we,{entries:B||[],isLoading:Y,track:T,carId:v,getUserDisplay:i,onDriverSelect:He,onNavigate:K}):T?e.jsx(ke,{entries:B||[],isLoading:Y,track:T,carMetadata:l,getUserDisplay:i,onCarSelect:Ke,onNavigate:K}):e.jsx(Ce,{tracks:q,isLoading:j,carMetadata:l,getUserDisplay:i,onTrackSelect:Ve});return e.jsxs("div",{className:`pvx-leaderboard-explorer ${s||""}`,children:[e.jsxs("div",{className:"pvx-explorer-header",children:[e.jsx("h1",{className:"pvx-explorer-title",children:t}),e.jsxs("div",{className:"pvx-explorer-stats",children:[m>0&&e.jsxs("span",{children:[m.toLocaleString()," laps"]}),m>0&&p>0&&e.jsx("span",{className:"pvx-explorer-stats-sep",children:"|"}),p>0&&e.jsxs("span",{children:[p.toLocaleString()," drivers"]})]})]}),e.jsxs("div",{className:"pvx-explorer-controls",children:[e.jsx("div",{className:"pvx-game-tabs",children:["evo","acc"].map(f=>e.jsx("button",{onClick:()=>qe(f),className:`pvx-game-tab ${o===f?"pvx-game-tab--active":""}`,children:f==="evo"?"AC EVO":"ACC"},f))}),C&&e.jsx("select",{value:L||"",onChange:f=>_e(f.target.value),className:"pvx-version-select",children:C.available.slice().reverse().map(f=>e.jsxs("option",{value:f,children:["v",f,f===C.default?" (Latest)":""]},f))})]}),Oe(),d&&e.jsxs("p",{className:"pvx-data-timestamp",children:["Data updated: ",new Date(d).toLocaleString()]})]})}const ls={GBR:"🇬🇧",DEU:"🇩🇪",NLD:"🇳🇱",SWE:"🇸🇪",ESP:"🇪🇸",ZAF:"🇿🇦",FRA:"🇫🇷",ITA:"🇮🇹",USA:"🇺🇸",AUS:"🇦🇺",BRA:"🇧🇷",JPN:"🇯🇵",CAN:"🇨🇦",POL:"🇵🇱",AUT:"🇦🇹",BEL:"🇧🇪",PRT:"🇵🇹",NOR:"🇳🇴",DNK:"🇩🇰",FIN:"🇫🇮",IRL:"🇮🇪",CHE:"🇨🇭",NZL:"🇳🇿",MEX:"🇲🇽",ARG:"🇦🇷",CZE:"🇨🇿",HUN:"🇭🇺",RUS:"🇷🇺",TUR:"🇹🇷",KOR:"🇰🇷"},cs={championship:"Championship",series:"Series",event:"Event"},se=["PRACTICE","QUALIFYING","RACE"];function Se({position:s}){const r=s===1?"pvx-rank pvx-rank--gold":s===2?"pvx-rank pvx-rank--silver":s===3?"pvx-rank pvx-rank--bronze":"pvx-rank";return e.jsx("span",{className:r,children:s})}function Le({nation:s}){const r=s&&ls[s];return r?e.jsx("span",{className:"pvx-nation-flag",title:s,children:r}):null}function ds({sessions:s,activeSession:r,onSelect:t}){if(!s||s.length<=1)return null;const a=[...s].sort((n,i)=>se.indexOf(n.type)-se.indexOf(i.type));return e.jsx("div",{className:"pvx-session-tabs",children:a.map(n=>e.jsx("button",{onClick:()=>t(n.type),className:`pvx-session-tab ${r===n.type?"pvx-session-tab--active":""}`,children:n.type},n.type))})}function Re({type:s}){return e.jsx("span",{className:`pvx-comp-badge pvx-comp-badge--${s}`,children:cs[s]||s})}function A({children:s,variant:r="default"}){return e.jsx("span",{className:`pvx-info-pill ${r!=="default"?`pvx-info-pill--${r}`:""}`,children:s})}function $e(s){if(!s)return"TBD";const r=new Date(s);if(isNaN(r))return"TBD";const t=r.toLocaleDateString("en-GB",{weekday:"short",day:"numeric",month:"short"}),a=r.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit"});return`${t} • ${a}`}function ps(s){return s.reduce((r,t)=>{var a;return(a=t.splits)!=null&&a.length?r?r.map((n,i)=>{const l=t.splits[i];return l&&l<n?l:n}):[...t.splits]:r},null)}function U({message:s="Loading..."}){return e.jsx("div",{className:"pvx-loading",children:s})}function M({message:s="No data available."}){return e.jsx("div",{className:"pvx-empty",children:e.jsx("p",{children:s})})}function Me({competitions:s,isLoading:r,onSelect:t,className:a}){return r?e.jsx(U,{message:"Loading competitions..."}):s!=null&&s.length?e.jsx("div",{className:`pvx-comp-grid ${a||""}`,children:s.map(n=>e.jsx(xs,{comp:n,onSelect:t},n.id))}):e.jsx(M,{message:"No competitions available."})}function xs({comp:s,onSelect:r}){var j,d,m;const{cdnUrl:t}=w(),a=s.posterCdnPath?`${t}/${s.posterCdnPath}`:null,n=s.registration,i=(n==null?void 0:n.currentCount)||0,l=n==null?void 0:n.maxParticipants,o=l&&i>=l,x=(n==null?void 0:n.deadline)&&new Date(n.deadline)<new Date,c=(n==null?void 0:n.isOpen)&&!x&&!o,v=new Date,g=(j=s.rounds)==null?void 0:j.find(p=>p.startTime&&new Date(p.startTime)>=v),h=((d=s.rounds)==null?void 0:d.length)||0,u=((m=s.rounds)==null?void 0:m.filter(p=>p.isFinalized).length)||0;return e.jsxs("div",{className:"pvx-comp-card",onClick:()=>r(s.id),role:"button",tabIndex:0,onKeyDown:p=>{(p.key==="Enter"||p.key===" ")&&(p.preventDefault(),r(s.id))},children:[e.jsx("div",{className:"pvx-comp-card-poster",children:a?e.jsx("img",{src:a,alt:s.name,className:"pvx-comp-card-poster-img"}):e.jsx("div",{className:"pvx-comp-card-poster-placeholder",children:e.jsx(us,{})})}),e.jsxs("div",{className:"pvx-comp-card-body",children:[e.jsx("h3",{className:"pvx-comp-card-title",children:s.name}),s.description&&e.jsx("p",{className:"pvx-comp-card-desc",children:s.description}),e.jsxs("div",{className:"pvx-comp-card-pills",children:[e.jsx(Re,{type:s.type}),s.game&&e.jsx(A,{children:s.game.toUpperCase()}),s.formatDescription&&s.formatDescription.split(", ").map((p,N)=>e.jsx(A,{variant:"format",children:p},N))]}),s.carsDescription&&e.jsx("div",{className:"pvx-comp-card-pills",children:s.carsDescription.split(", ").map((p,N)=>e.jsx(A,{children:p},N))}),e.jsxs("div",{className:"pvx-comp-card-schedule",children:[g?e.jsxs("span",{className:"pvx-comp-card-schedule-next",children:[e.jsx("span",{className:"pvx-comp-card-schedule-label",children:"Next:"})," ","R",g.roundNumber," ",g.track||"TBD"," — ",$e(g.startTime)]}):h>0?e.jsxs("span",{className:"pvx-comp-card-schedule-next",children:[u,"/",h," rounds completed"]}):null,h>0&&e.jsxs("span",{className:"pvx-comp-card-round-count",children:[h," round",h!==1?"s":""]})]}),n&&e.jsxs("div",{className:"pvx-comp-card-reg",children:[e.jsx("span",{className:`pvx-comp-reg-badge ${c?"pvx-comp-reg-badge--open":o?"pvx-comp-reg-badge--full":"pvx-comp-reg-badge--closed"}`,children:c?"Registration Open":o?"Full":"Registration Closed"}),e.jsxs("span",{className:"pvx-comp-reg-count",children:[i,"/",l||"∞"," drivers"]})]})]})]})}function us(){return e.jsxs("svg",{className:"pvx-comp-trophy-icon",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.5",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M6 9H4.5a2.5 2.5 0 0 1 0-5H6"}),e.jsx("path",{d:"M18 9h1.5a2.5 2.5 0 0 0 0-5H18"}),e.jsx("path",{d:"M4 22h16"}),e.jsx("path",{d:"M10 14.66V17c0 .55-.47.98-.97 1.21C7.85 18.75 7 20.24 7 22"}),e.jsx("path",{d:"M14 14.66V17c0 .55.47.98.97 1.21C16.15 18.75 17 20.24 17 22"}),e.jsx("path",{d:"M18 2H6v7a6 6 0 0 0 12 0V2Z"})]})}function De({competitionId:s,className:r}){var o,x;const{data:t,isLoading:a}=de(s),{data:n,isLoading:i}=G(s);if(a||i)return e.jsx(U,{message:"Loading standings..."});if(!((o=t==null?void 0:t.standings)!=null&&o.length))return e.jsx(M,{message:"No standings data yet. Results will appear once rounds are finalised."});const l=((x=n==null?void 0:n.rounds)==null?void 0:x.filter(c=>c.isFinalized))||[];return e.jsxs("div",{className:`pvx-card ${r||""}`,children:[e.jsx("div",{className:"pvx-card-header--split",children:e.jsxs("div",{className:"pvx-card-header-left",children:[e.jsx("h3",{className:"pvx-card-title",children:"Championship Standings"}),e.jsxs("span",{className:"pvx-standings-subtitle",children:["After ",t.roundsCompleted," round",t.roundsCompleted!==1?"s":"",t.countingRounds>0&&` (best ${t.countingRounds} count)`]})]})}),e.jsx("div",{className:"pvx-table-scroll",children:e.jsxs("table",{className:"pvx-table",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"pvx-thead-row",children:[e.jsx("th",{className:"pvx-th pvx-th--narrow",children:"Pos"}),e.jsx("th",{className:"pvx-th",children:"Driver"}),e.jsx("th",{className:"pvx-th pvx-th--center pvx-hidden-below-sm",children:"W"}),e.jsx("th",{className:"pvx-th pvx-th--center pvx-hidden-below-sm",children:"Pod"}),e.jsx("th",{className:"pvx-th pvx-th--center",children:"Points"}),l.map(c=>e.jsxs("th",{className:"pvx-th pvx-th--center pvx-hidden-below-md",title:c.track||`Round ${c.roundNumber}`,children:["R",c.roundNumber]},c.roundNumber))]})}),e.jsx("tbody",{className:"pvx-tbody",children:t.standings.map(c=>e.jsx(ms,{driver:c,finalizedRounds:l},c.driverId||c.driverName))})]})})]})}function ms({driver:s,finalizedRounds:r}){var l,o,x;const t=s.position<=3,a=new Map(((l=s.roundResults)==null?void 0:l.map(c=>[c.roundNumber,c]))||[]),n=((o=s.roundResults)==null?void 0:o.filter(c=>c.position===1).length)||0,i=((x=s.roundResults)==null?void 0:x.filter(c=>c.position<=3).length)||0;return e.jsxs("tr",{className:`pvx-row ${t?"pvx-row--podium":""}`,children:[e.jsx("td",{className:"pvx-td",children:e.jsx(Se,{position:s.position})}),e.jsxs("td",{className:"pvx-td pvx-td--primary",children:[e.jsx(Le,{nation:s.nation}),s.driverName]}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-sm",children:n||"-"}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-hidden-below-sm",children:i||"-"}),e.jsx("td",{className:"pvx-td pvx-td--center pvx-standings-total",children:s.totalPoints}),r.map(c=>{const v=a.get(c.roundNumber),g=v==null?void 0:v.dropped;return e.jsx("td",{className:`pvx-td pvx-td--center pvx-hidden-below-md ${!g&&(v==null?void 0:v.position)<=3?"pvx-standings-cell--podium":""}`,children:v?e.jsxs("div",{className:`pvx-standings-round-cell ${g?"pvx-standings-round-cell--dropped":""}`,children:[e.jsxs("span",{className:"pvx-standings-round-pos",children:["P",v.position]}),e.jsx("span",{className:"pvx-standings-round-pts",children:v.points})]}):e.jsx("span",{className:"pvx-td--muted",children:"-"})},c.roundNumber)})]})}function Ie({competitionId:s,roundNumber:r,className:t}){var v,g;const{data:a,isLoading:n}=pe(s,r),[i,l]=b.useState(null);if(n)return e.jsx(U,{message:"Loading results..."});if(!a)return e.jsx(M,{message:"No results for this round."});const o=a.sessions||[];if(!o.length)return e.jsx(M,{message:"No session data for this round."});const x=i||((v=o.find(h=>h.type==="RACE"))==null?void 0:v.type)||((g=o[0])==null?void 0:g.type),c=o.find(h=>h.type===x)||o[0];return e.jsxs("div",{className:`pvx-round-results ${t||""}`,children:[e.jsxs("div",{className:"pvx-round-results-header",children:[e.jsxs("div",{children:[e.jsxs("h4",{className:"pvx-round-results-title",children:["Round ",a.roundNumber,a.track?`: ${a.track}`:""]}),a.startTime&&e.jsx("p",{className:"pvx-round-results-date",children:new Date(a.startTime).toLocaleDateString("en-GB",{day:"numeric",month:"long",year:"numeric"})})]}),e.jsx(hs,{sessions:o})]}),e.jsx(ds,{sessions:o,activeSession:x,onSelect:l}),e.jsx(vs,{session:c})]})}function hs({sessions:s}){var n;const r=s.find(i=>i.type==="RACE"),t=(n=r==null?void 0:r.results)==null?void 0:n.filter(i=>i.position<=3).sort((i,l)=>i.position-l.position);if(!(t!=null&&t.length))return null;const a=["🥇","🥈","🥉"];return e.jsx("div",{className:"pvx-round-podium-summary",children:t.map(i=>e.jsxs("span",{className:"pvx-round-podium-item",children:[e.jsx("span",{children:a[i.position-1]}),e.jsx("span",{children:i.driverName})]},i.driverId))})}function vs({session:s}){var a;const r=s.type==="RACE";if(!((a=s.results)!=null&&a.length))return e.jsx(M,{message:`No results for ${s.type}.`});const t=ps(s.results);return e.jsx("div",{className:"pvx-table-scroll",children:e.jsxs("table",{className:"pvx-table",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"pvx-thead-row",children:[e.jsx("th",{className:"pvx-th pvx-th--narrow",children:"Pos"}),e.jsx("th",{className:"pvx-th",children:"Driver"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"Car"}),e.jsx("th",{className:"pvx-th",children:"Best Lap"}),r&&e.jsxs(e.Fragment,{children:[e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"Laps"}),e.jsx("th",{className:"pvx-th pvx-hidden-below-sm",children:"Time / Gap"}),e.jsx("th",{className:"pvx-th pvx-th--center",children:"Points"})]})]})}),e.jsx("tbody",{className:"pvx-tbody",children:s.results.map((n,i)=>e.jsx(js,{result:n,isRace:r,fastestSplits:t,rowIndex:i},n.driverId||i))})]})})}function js({result:s,isRace:r,fastestSplits:t,rowIndex:a}){const n=s.position<=3;return e.jsxs("tr",{className:`pvx-row ${n?"pvx-row--podium":""}`,children:[e.jsx("td",{className:"pvx-td",children:e.jsx(Se,{position:s.position})}),e.jsxs("td",{className:"pvx-td pvx-td--primary",children:[e.jsx(Le,{nation:s.nation}),s.driverName,s.carNumber!=null&&e.jsxs("span",{className:"pvx-car-number",children:["#",s.carNumber]}),s.penalty&&e.jsx("span",{className:"pvx-penalty",children:s.penalty})]}),e.jsx("td",{className:"pvx-td pvx-hidden-below-sm",children:$(s.carId)}),e.jsx("td",{className:"pvx-td pvx-td--mono",children:e.jsx(gs,{bestLap:s.bestLapFormatted,hasBestLap:s.hasBestLap,splits:s.splits,fastestSplits:t,showAbove:a<=1})}),r&&e.jsxs(e.Fragment,{children:[e.jsx("td",{className:"pvx-td pvx-hidden-below-sm",children:s.lapsCompleted}),e.jsx("td",{className:"pvx-td pvx-td--mono pvx-td--muted pvx-hidden-below-sm",children:s.position===1?s.totalTime||"-":s.gap||"-"}),e.jsxs("td",{className:"pvx-td pvx-td--center",children:[e.jsx("span",{className:"pvx-session-points",children:s.points}),s.pointsOverride!==0&&s.pointsOverride&&e.jsxs("span",{className:"pvx-points-override",children:["(",s.pointsOverride>0?"+":"",s.pointsOverride,")"]})]})]})]})}function gs({bestLap:s,hasBestLap:r,splits:t,fastestSplits:a,showAbove:n}){return s?e.jsxs("span",{className:`pvx-best-lap-cell ${r?"pvx-best-lap-cell--fastest":""}`,children:[e.jsx("span",{className:"pvx-best-lap-time",children:s}),(t==null?void 0:t.length)>0&&e.jsx("span",{className:"pvx-splits-tooltip-anchor",children:e.jsx("span",{className:`pvx-splits-tooltip ${n?"":"pvx-splits-tooltip--above"}`,children:t.map((i,l)=>{const o=a&&i===a[l];return e.jsxs("span",{className:"pvx-splits-tooltip-row",children:[e.jsxs("span",{className:"pvx-splits-tooltip-label",children:["S",l+1]}),e.jsx("span",{className:o?"pvx-splits-tooltip-best":"",children:i})]},l)})})})]}):e.jsx("span",{className:"pvx-td--muted",children:"-"})}function Be({competitionId:s,className:r}){const{data:t,isLoading:a}=xe(s);if(a)return e.jsx(U,{message:"Loading drivers..."});const n=(t==null?void 0:t.drivers)||(t==null?void 0:t.entries)||[];return n.length?e.jsx("div",{className:`pvx-entry-grid ${r||""}`,children:n.map(i=>{var l,o;return e.jsxs("div",{className:"pvx-entry-card",children:[i.avatarUrl?e.jsx("img",{src:i.avatarUrl,alt:"",className:"pvx-entry-avatar"}):e.jsx("div",{className:"pvx-entry-avatar pvx-entry-avatar--placeholder",children:((o=(l=i.displayName)==null?void 0:l.charAt(0))==null?void 0:o.toUpperCase())||"?"}),e.jsx("span",{className:"pvx-entry-name",children:i.displayName})]},i.steamId||i.driverId)})}):e.jsx(M,{message:"No drivers registered yet."})}const fs=[{id:"standings",label:"Standings"},{id:"rounds",label:"Rounds"},{id:"drivers",label:"Drivers"}];function Ns({className:s,title:r="Competitions"}){const[t,a]=ae.useSearchParams(),n=t.get("competition"),i=t.get("tab")||"standings",l=t.get("round")?Number(t.get("round")):null,{data:o,isLoading:x}=ce();function c(j){a({competition:j})}function v(){a({})}function g(j){a({competition:n,tab:j})}function h(j){a({competition:n,tab:"rounds",round:String(j)})}function u(){a({competition:n,tab:"rounds"})}return n?e.jsx("div",{className:`pvx-comp-explorer ${s||""}`,children:e.jsx(bs,{competitionId:n,activeTab:i,selectedRound:l,onBack:v,onTabChange:g,onSelectRound:h,onDeselectRound:u})}):e.jsxs("div",{className:`pvx-comp-explorer ${s||""}`,children:[e.jsxs("div",{className:"pvx-explorer-header",children:[e.jsx("h2",{className:"pvx-explorer-title",children:r}),!x&&(o==null?void 0:o.length)>0&&e.jsx("div",{className:"pvx-explorer-stats",children:e.jsxs("span",{children:[o.length," competition",o.length!==1?"s":""]})})]}),e.jsx(Me,{competitions:o,isLoading:x,onSelect:c})]})}function bs({competitionId:s,activeTab:r,selectedRound:t,onBack:a,onTabChange:n,onSelectRound:i,onDeselectRound:l}){var j,d;const{data:o,isLoading:x}=G(s);if(x)return e.jsx(U,{message:"Loading competition..."});if(!o)return e.jsxs("div",{children:[e.jsx(M,{message:"Competition not found."}),e.jsx("div",{className:"pvx-comp-back-link-wrap",children:e.jsx("button",{onClick:a,className:"pvx-comp-back-link",children:"← Back to competitions"})})]});const c=o.type==="championship",v=((j=o.rounds)==null?void 0:j.filter(m=>m.isFinalized))||[],g=o.rounds||[],h=fs.filter(m=>!(m.id==="standings"&&!c||m.id==="rounds"&&v.length===0)),u=h.find(m=>m.id===r)?r:((d=h[0])==null?void 0:d.id)||"standings";return e.jsxs(e.Fragment,{children:[e.jsx("button",{onClick:a,className:"pvx-comp-back-link",children:"← Competitions"}),e.jsxs("div",{className:"pvx-comp-detail-header",children:[e.jsx("h2",{className:"pvx-explorer-title",children:o.name}),o.description&&e.jsx("p",{className:"pvx-comp-detail-desc",children:o.description}),e.jsxs("div",{className:"pvx-comp-detail-meta",children:[e.jsx(Re,{type:o.type}),o.game&&e.jsx(A,{children:o.game.toUpperCase()}),o.countingRounds>0&&e.jsxs(A,{variant:"format",children:["Best ",o.countingRounds," of ",g.length," rounds count"]}),g.length>0&&e.jsxs(A,{children:[g.length," round",g.length!==1?"s":""]})]})]}),g.length>0&&e.jsx(ys,{rounds:g}),h.length>1&&e.jsx("div",{className:"pvx-comp-tabs",children:h.map(m=>e.jsx("button",{onClick:()=>n(m.id),className:`pvx-comp-tab ${u===m.id?"pvx-comp-tab--active":""}`,children:m.label},m.id))}),u==="standings"&&e.jsx(De,{competitionId:s}),u==="rounds"&&e.jsx(Cs,{competitionId:s,finalizedRounds:v,selectedRound:t,onSelectRound:i,onDeselectRound:l}),u==="drivers"&&e.jsx(Be,{competitionId:s})]})}function ys({rounds:s}){const r=new Date,t=s.find(a=>a.startTime&&new Date(a.startTime)>=r);return e.jsx("div",{className:"pvx-comp-schedule",children:e.jsx("div",{className:"pvx-comp-schedule-list",children:s.map(a=>{const n=a===t,i=a.startTime&&new Date(a.startTime)<r;return e.jsxs("div",{className:`pvx-comp-schedule-item ${n?"pvx-comp-schedule-item--next":""} ${i?"pvx-comp-schedule-item--past":""}`,children:[e.jsxs("span",{className:"pvx-comp-schedule-round",children:["R",a.roundNumber]}),e.jsx("span",{className:"pvx-comp-schedule-track",children:a.track||"TBD"}),e.jsx("span",{className:"pvx-comp-schedule-date",children:$e(a.startTime)}),a.isFinalized&&e.jsx("span",{className:"pvx-comp-schedule-badge",children:"Results"})]},a.roundNumber)})})})}function Cs({competitionId:s,finalizedRounds:r,selectedRound:t,onSelectRound:a,onDeselectRound:n}){return r.length?e.jsxs("div",{className:"pvx-comp-rounds",children:[e.jsx("div",{className:"pvx-comp-round-pills",children:r.map(i=>e.jsxs("button",{onClick:()=>t===i.roundNumber?n():a(i.roundNumber),className:`pvx-comp-round-pill ${t===i.roundNumber?"pvx-comp-round-pill--active":""}`,children:[e.jsxs("span",{className:"pvx-comp-round-pill-num",children:["R",i.roundNumber]}),i.track&&e.jsx("span",{className:"pvx-comp-round-pill-track",children:i.track})]},i.roundNumber))}),t?e.jsx(Ie,{competitionId:s,roundNumber:t}):e.jsx("div",{className:"pvx-empty",children:e.jsx("p",{children:"Select a round to view results."})})]}):e.jsx(M,{message:"No finalised rounds yet."})}function ks({competitionId:s,driverData:r,className:t,children:a}){const{data:n,isLoading:i}=me(s),l=he(s),o=ve(s),x=(n==null?void 0:n.isRegistered)||!1,c=i||l.isPending||o.isPending,v=l.error||o.error||null,g=()=>{r&&l.mutate(r)},h=()=>{o.mutate()};return typeof a=="function"?a({isRegistered:x,isLoading:c,register:g,withdraw:h,error:v}):e.jsx("button",{className:t,onClick:x?h:g,disabled:c,children:c?"Loading...":x?"Withdraw":"Register"})}function Ae(s){const{cdnUrl:r,partnerSlug:t}=w(),a=y.useQuery({queryKey:["pitvox","laps",t,s],queryFn:()=>S(r,`laps/partners/${t}/${s}.json`),enabled:!!s,staleTime:3e4,refetchInterval:3e4}),n=a.data;return{isLoading:a.isLoading,error:a.error,data:n?{driverName:n.driverName||"Driver",lapCount:n.lapCount||0,trackBreakdown:n.trackBreakdown||[],carBreakdown:n.carBreakdown||[],recordsHeld:n.recordsHeld||0,currentRecords:n.currentRecords||[],bestRanking:n.bestRanking??null,bestRankingTrackId:n.bestRankingTrackId??null,bestRankingLayout:n.bestRankingLayout??null,bestRankingCarId:n.bestRankingCarId??null,generatedAt:n.generatedAt}:null}}function Pe(s){var i;const{cdnUrl:r,partnerSlug:t}=w(),a=y.useQuery({queryKey:["pitvox","ratings",t],queryFn:()=>S(r,`leaderboards/partners/${t}/ratings.json`),staleTime:6e4,refetchInterval:6e4}),n=b.useMemo(()=>{var l;return!((l=a.data)!=null&&l.drivers)||!s?null:a.data.drivers.find(o=>o.identifier===s)||null},[(i=a.data)==null?void 0:i.drivers,s]);return{isLoading:a.isLoading,error:a.error,data:n?{rating:n.rating,rank:n.rank,totalDrivers:a.data.driverCount||a.data.drivers.length,comboCount:n.comboCount||0,distinctCars:n.distinctCars||0,combos:n.combos||[]}:null}}function Ee({driverName:s,avatarUrl:r,memberSince:t,className:a=""}){const n=t?new Date(t).toLocaleDateString("en-GB",{day:"2-digit",month:"2-digit",year:"numeric"}):null;return e.jsxs("div",{className:`pvx-card pvx-dash-profile ${a}`,children:[r?e.jsx("img",{src:r,alt:"",className:"pvx-dash-profile-avatar"}):e.jsx("div",{className:"pvx-dash-profile-avatar pvx-dash-profile-avatar--placeholder",children:(s||"?")[0].toUpperCase()}),e.jsxs("div",{className:"pvx-dash-profile-info",children:[e.jsx("h2",{className:"pvx-dash-profile-name",children:s}),n&&e.jsxs("p",{className:"pvx-dash-profile-since",children:["Racing since ",n]})]})]})}function ws(){return e.jsxs("svg",{className:"pvx-dash-stat-icon",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("line",{x1:"4",y1:"9",x2:"20",y2:"9"}),e.jsx("line",{x1:"4",y1:"15",x2:"20",y2:"15"}),e.jsx("line",{x1:"10",y1:"3",x2:"8",y2:"21"}),e.jsx("line",{x1:"16",y1:"3",x2:"14",y2:"21"})]})}function Ts(){return e.jsxs("svg",{className:"pvx-dash-stat-icon",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("circle",{cx:"12",cy:"12",r:"10"}),e.jsx("circle",{cx:"12",cy:"12",r:"2"}),e.jsx("path",{d:"M12 14v4"}),e.jsx("path",{d:"M10.5 12.5l-4 2.5"}),e.jsx("path",{d:"M13.5 12.5l4 2.5"})]})}function Ss(){return e.jsx("svg",{className:"pvx-dash-stat-icon",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:e.jsx("polygon",{points:"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"})})}function te({items:s,labelKey:r,countKey:t}){if(!(s!=null&&s.length))return null;const a=s.slice().sort((n,i)=>i[t]-n[t]).slice(0,10);return e.jsxs("div",{className:"pvx-dash-tooltip",children:[a.map((n,i)=>e.jsxs("div",{className:"pvx-dash-tooltip-row",children:[e.jsx("span",{className:"pvx-dash-tooltip-label",children:n[r]}),e.jsx("span",{className:"pvx-dash-tooltip-value",children:n[t]})]},i)),s.length>10&&e.jsxs("div",{className:"pvx-dash-tooltip-row pvx-dash-tooltip-more",children:["+",s.length-10," more"]})]})}function Fe({stats:s,rating:r,className:t=""}){if(!s)return null;const a=s.trackBreakdown.map(i=>({name:F(i.trackId,i.layout),lapCount:i.lapCount})),n=s.carBreakdown.map(i=>({name:$(i.carId),lapCount:i.lapCount}));return e.jsxs("div",{className:`pvx-dash-stats ${t}`,children:[e.jsxs("div",{className:"pvx-dash-stat-card pvx-dash-stat-card--has-tooltip",children:[e.jsx(ws,{}),e.jsxs("div",{className:"pvx-dash-stat-content",children:[e.jsx("span",{className:"pvx-dash-stat-value",children:s.lapCount.toLocaleString()}),e.jsx("span",{className:"pvx-dash-stat-label",children:"Total Laps"})]}),e.jsx(te,{items:a,labelKey:"name",countKey:"lapCount"})]}),e.jsxs("div",{className:"pvx-dash-stat-card pvx-dash-stat-card--has-tooltip",children:[e.jsx(Ts,{}),e.jsxs("div",{className:"pvx-dash-stat-content",children:[e.jsx("span",{className:"pvx-dash-stat-value",children:s.carBreakdown.length}),e.jsx("span",{className:"pvx-dash-stat-label",children:"Cars Used"})]}),e.jsx(te,{items:n,labelKey:"name",countKey:"lapCount"})]}),r&&e.jsxs("div",{className:"pvx-dash-stat-card pvx-dash-stat-card--rating",children:[e.jsx(Ss,{}),e.jsxs("div",{className:"pvx-dash-stat-content",children:[e.jsx("span",{className:"pvx-dash-stat-value",children:r.rating.toFixed(1)}),e.jsx("span",{className:"pvx-dash-stat-label",children:"Driver Rating"}),e.jsxs("span",{className:"pvx-dash-stat-sub",children:["#",r.rank," of ",r.totalDrivers]})]})]})]})}const re=10;function Ue({records:s,className:r=""}){const[t,a]=b.useState(!1),n=b.useMemo(()=>s!=null&&s.length?s.slice().sort((o,x)=>{const c=o.recordedAt?new Date(o.recordedAt).getTime():0;return(x.recordedAt?new Date(x.recordedAt).getTime():0)-c}):[],[s]);if(!n.length)return null;const i=t?n:n.slice(0,re),l=n.length>re;return e.jsxs("div",{className:`pvx-card ${r}`,children:[e.jsx("div",{className:"pvx-card-header",children:e.jsxs("h3",{className:"pvx-card-title",children:[e.jsx("span",{className:"pvx-dash-records-icon",children:e.jsxs("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M6 9H4.5a2.5 2.5 0 010-5H6"}),e.jsx("path",{d:"M18 9h1.5a2.5 2.5 0 000-5H18"}),e.jsx("path",{d:"M4 22h16"}),e.jsx("path",{d:"M10 14.66V17c0 .55-.47.98-.97 1.21C7.85 18.75 7 20 7 22"}),e.jsx("path",{d:"M14 14.66V17c0 .55.47.98.97 1.21C16.15 18.75 17 20 17 22"}),e.jsx("path",{d:"M18 2H6v7a6 6 0 0012 0V2z"})]})}),"Current Records",e.jsxs("span",{className:"pvx-dash-records-count",children:["(",n.length,")"]})]})}),e.jsx("div",{className:"pvx-dash-records-list",children:i.map((o,x)=>e.jsxs("div",{className:"pvx-dash-record-row",children:[e.jsxs("div",{className:"pvx-dash-record-info",children:[e.jsx("span",{className:"pvx-dash-record-track",children:F(o.trackId,o.layout,o.game)}),e.jsx("span",{className:"pvx-dash-record-car",children:$(o.carId)})]}),e.jsxs("div",{className:"pvx-dash-record-time",children:[e.jsx("span",{className:"pvx-dash-record-lap",children:P(o.lapTimeMs)}),e.jsxs("span",{className:`pvx-dash-game-badge pvx-dash-game-badge--${o.game||"evo"}`,children:[(o.game||"evo").toUpperCase(),o.gameVersion?` ${o.gameVersion}`:""]})]})]},x))}),l&&e.jsx("button",{className:"pvx-dash-records-toggle",onClick:()=>a(!t),children:t?"Show less":`Show all ${n.length} records`})]})}function Ls({steamId:s,avatarUrl:r,memberSince:t,className:a=""}){const{data:n,isLoading:i,error:l}=Ae(s),{data:o,isLoading:x}=Pe(s);return i||x?e.jsx("div",{className:"pvx-loading",children:"Loading dashboard..."}):l?e.jsx("div",{className:"pvx-empty",children:"Failed to load dashboard data."}):n?e.jsxs("div",{className:`pvx-dash ${a}`,children:[e.jsx(Ee,{driverName:n.driverName,avatarUrl:r,memberSince:t}),e.jsx(Fe,{stats:n,rating:o}),e.jsx(Ue,{records:n.currentRecords})]}):e.jsx("div",{className:"pvx-empty",children:"No data available yet. Start driving to see your stats!"})}exports.CarsTable=ke;exports.CompetitionCards=Me;exports.CompetitionExplorer=Ns;exports.DriverDashboard=Ls;exports.DriverProfile=Ee;exports.DriversTable=we;exports.EntryList=Be;exports.LapHistoryTable=Te;exports.LeaderboardExplorer=os;exports.PitVoxPartnerProvider=ze;exports.RecordsTable=Ue;exports.RegisterButton=ks;exports.RoundResults=Ie;exports.StandingsTable=De;exports.StatsCards=Fe;exports.TracksTable=Ce;exports.formatCarName=$;exports.formatDate=E;exports.formatDelta=Ze;exports.formatLapTime=P;exports.formatRelativeTime=Je;exports.formatSectorTime=I;exports.formatTrackName=F;exports.formatTyreCompound=O;exports.useCarLeaderboard=Xe;exports.useCarMetadata=le;exports.useCompetitionAllRounds=Ye;exports.useCompetitionConfig=G;exports.useCompetitionEntryList=xe;exports.useCompetitionRound=pe;exports.useCompetitionStandings=de;exports.useCompetitions=ce;exports.useDriverLaps=ie;exports.useDriverRating=Pe;exports.useDriverStats=Ae;exports.useLeaderboardIndex=ne;exports.usePitVox=w;exports.useRegister=he;exports.useRegistrationStatus=me;exports.useTrackLeaderboard=W;exports.useUserLookup=oe;exports.useWithdraw=ve;