feat(noita): stores

This commit is contained in:
Loïc Gremaud 2026-05-24 09:29:30 +02:00
parent 9fd0122a67
commit 821e453bc0
Signed by: Legrems
GPG Key ID: D4620E6DF3E0121D
13 changed files with 240 additions and 176 deletions

View File

@ -1,7 +1,9 @@
<script setup lang="ts">
import { ref, computed, onMounted } from "vue";
import { storeToRefs } from "pinia";
import dayjs from "dayjs";
import RankBadge from "@/components/RankBadge.vue";
import { useNoitaStore, type Objective } from "@/stores/noita";
import {
createColumnHelper,
useVueTable,
@ -12,32 +14,11 @@ import {
type SortingState,
} from "@tanstack/vue-table";
interface Objective {
objectiv_id: string;
display_string: string;
first_seen_at: string | null;
count: number;
max_count: number;
seed: string | null;
points_per_objectiv: number;
total_points: number;
}
const userInfo = ref({
username: "Player",
rank: null as number | null,
score: 0,
runsSubmitted: 0,
deathsCount: 0,
isStaff: false,
});
const noitaStore = useNoitaStore();
const { userInfo, objectives, leaderboard, isLoadingLeaderboard, isUploading } = storeToRefs(noitaStore);
const uploadedFiles = ref<File[]>([]);
const isUploading = ref(false);
const isDragover = ref(false);
const objectives = ref<Objective[]>([]);
const isLoadingLeaderboard = ref(false);
const leaderboard = ref<any[]>([]);
const columnHelper = createColumnHelper<Objective>();
const sorting = ref<SortingState>([]);
@ -153,40 +134,13 @@ const handleDrop = (event: DragEvent) => {
const submitRun = async () => {
if (uploadedFiles.value.length === 0) return;
isUploading.value = true;
try {
for (const file of uploadedFiles.value) {
const formData = new FormData();
formData.append("file", file);
const response = await fetch("/api/noita/submit", {
method: "POST",
body: formData,
});
if (!response.ok) {
const error = await response.json();
alert(`Error submitting ${file.name}: ${error.detail || "Unknown error"}`);
return;
}
const result = await response.json();
console.log("Submission successful:", result);
}
await noitaStore.submitRun(uploadedFiles.value);
uploadedFiles.value = [];
alert("Run submitted successfully!");
// Refresh objectives, score, and rank after successful submission
await Promise.all([
fetchUserResults(),
fetchLeaderboard(),
]);
} catch (error) {
console.error("Error submitting run:", error);
alert("Error submitting run. Please try again.");
} finally {
isUploading.value = false;
}
};
@ -194,94 +148,18 @@ const goHome = () => {
window.location.href = "/";
};
const fetchUserResults = async () => {
try {
const response = await fetch("/api/noita/results");
if (!response.ok) throw new Error("Failed to fetch results");
const results = await response.json();
userInfo.value.score = results.total_score;
userInfo.value.deathsCount = results.deaths_count;
userInfo.value.runsSubmitted = results.objectives.length;
objectives.value = results.objectives;
} catch (error) {
console.error("Error fetching results:", error);
}
};
const fetchLeaderboard = async () => {
isLoadingLeaderboard.value = true;
try {
const response = await fetch("/api/noita/leaderboard");
if (!response.ok) throw new Error("Failed to fetch leaderboard");
const data = await response.json();
leaderboard.value = data.leaderboard;
// Find current user's rank
const userRank = leaderboard.value.find(
(entry: any) => entry.username === userInfo.value.username
);
if (userRank) {
userInfo.value.rank = userRank.rank;
userInfo.value.score = userRank.total_score;
userInfo.value.deathsCount = userRank.deaths_count;
}
} catch (error) {
console.error("Error fetching leaderboard:", error);
} finally {
isLoadingLeaderboard.value = false;
}
};
const clearCache = async () => {
try {
const response = await fetch("/api/cache/clear", {
method: "POST",
});
if (response.ok) {
alert("Cache cleared successfully!");
// Refresh data after clearing cache
await Promise.all([
fetchUserResults(),
fetchLeaderboard(),
]);
} else {
const error = await response.json();
alert(`Error clearing cache: ${error.detail || "Unknown error"}`);
}
await noitaStore.clearCache();
alert("Cache cleared successfully!");
} catch (error) {
console.error("Error clearing cache:", error);
alert("Error clearing cache. Please try again.");
}
};
const loadUserData = async () => {
// Get user info first
try {
const response = await fetch("/api/user");
if (response.ok) {
const user = await response.json();
if (user.is_authenticated) {
userInfo.value.username = user.username;
userInfo.value.isStaff = user.is_staff || false;
}
}
} catch (error) {
console.error("Error fetching user info:", error);
}
// Fetch results and leaderboard
await Promise.all([
fetchUserResults(),
fetchLeaderboard(),
]);
};
onMounted(() => {
loadUserData();
noitaStore.loadUserData();
});
</script>

View File

@ -1,8 +1,10 @@
import { createApp } from 'vue'
import Noita from '@/Noita.vue'
import { pinia } from '@/stores'
import '@/style.css'
const selector = "#app"
const mountData = document.querySelector<HTMLElement>(selector)
const app = createApp(Noita, { ...mountData?.dataset })
app.use(pinia)
app.mount(selector)

View File

@ -0,0 +1,184 @@
import { defineStore } from 'pinia'
import { ref } from 'vue'
export interface Objective {
objectiv_id: string
display_string: string
first_seen_at: string | null
count: number
max_count: number
seed: string | null
points_per_objectiv: number
total_points: number
}
interface UserInfo {
username: string
rank: number | null
score: number
runsSubmitted: number
deathsCount: number
isStaff: boolean
}
interface LeaderboardEntry {
rank: number
username: string
total_score: number
objectives_count: number
deaths_count: number
is_staff: boolean
}
export const useNoitaStore = defineStore('noita', () => {
// State
const userInfo = ref<UserInfo>({
username: 'Player',
rank: null,
score: 0,
runsSubmitted: 0,
deathsCount: 0,
isStaff: false,
})
const objectives = ref<Objective[]>([])
const leaderboard = ref<LeaderboardEntry[]>([])
const isLoadingLeaderboard = ref(false)
const isUploading = ref(false)
const error = ref<string>('')
// Actions
const fetchUserResults = async () => {
try {
const response = await fetch('/api/noita/results')
if (!response.ok) throw new Error('Failed to fetch results')
const results = await response.json()
userInfo.value.score = results.total_score
userInfo.value.deathsCount = results.deaths_count
userInfo.value.runsSubmitted = results.objectives.length
objectives.value = results.objectives
} catch (err) {
error.value = 'Failed to fetch user results'
console.error('Error fetching results:', err)
}
}
const fetchLeaderboard = async () => {
isLoadingLeaderboard.value = true
try {
const response = await fetch('/api/noita/leaderboard')
if (!response.ok) throw new Error('Failed to fetch leaderboard')
const data = await response.json()
leaderboard.value = data.leaderboard
// Find current user's rank
const userRank = leaderboard.value.find(
(entry) => entry.username === userInfo.value.username
)
if (userRank) {
userInfo.value.rank = userRank.rank
userInfo.value.score = userRank.total_score
userInfo.value.deathsCount = userRank.deaths_count
}
} catch (err) {
error.value = 'Failed to fetch leaderboard'
console.error('Error fetching leaderboard:', err)
} finally {
isLoadingLeaderboard.value = false
}
}
const loadUserData = async () => {
try {
const response = await fetch('/api/user')
if (response.ok) {
const user = await response.json()
if (user.is_authenticated) {
userInfo.value.username = user.username
userInfo.value.isStaff = user.is_staff || false
}
}
} catch (err) {
console.error('Error fetching user info:', err)
}
await Promise.all([fetchUserResults(), fetchLeaderboard()])
}
const submitRun = async (files: File[]) => {
if (files.length === 0) return
isUploading.value = true
try {
for (const file of files) {
const formData = new FormData()
formData.append('file', file)
const response = await fetch('/api/noita/submit', {
method: 'POST',
body: formData,
})
if (!response.ok) {
const errorData = await response.json()
throw new Error(errorData.detail || 'Unknown error')
}
const result = await response.json()
console.log('Submission successful:', result)
}
// Refresh objectives, score, and rank after successful submission
await Promise.all([fetchUserResults(), fetchLeaderboard()])
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Unknown error'
error.value = `Error submitting run: ${errorMessage}`
throw err
} finally {
isUploading.value = false
}
}
const clearCache = async () => {
try {
const response = await fetch('/api/cache/clear', {
method: 'POST',
})
if (!response.ok) {
const errorData = await response.json()
throw new Error(errorData.detail || 'Unknown error')
}
await Promise.all([fetchUserResults(), fetchLeaderboard()])
} catch (err) {
const errorMessage = err instanceof Error ? err.message : 'Unknown error'
error.value = `Error clearing cache: ${errorMessage}`
throw err
}
}
const refreshData = async () => {
await Promise.all([fetchUserResults(), fetchLeaderboard()])
}
return {
// State
userInfo,
objectives,
leaderboard,
isLoadingLeaderboard,
isUploading,
error,
// Actions
fetchUserResults,
fetchLeaderboard,
loadUserData,
submitRun,
clearCache,
refreshData,
}
})

View File

@ -1 +0,0 @@
import{k as t,l as a,p as n,v as s}from"./style-CSeMeQaG.js";const c={key:0,class:"flex justify-center"},k={key:0,class:"badge badge-warning badge-lg"},d={key:1,class:"badge badge-lg"},l={key:2,class:"badge badge-lg"},o={key:3,class:"badge badge-lg"},g={key:1,class:"text-2xl text-base-content/50"},y=t({__name:"RankBadge",props:{rank:{}},setup(e){return(i,r)=>e.rank!==null?(n(),a("div",c,[e.rank===1?(n(),a("span",k," 🏆 #"+s(e.rank),1)):e.rank===2?(n(),a("span",d," 🥈 #"+s(e.rank),1)):e.rank===3?(n(),a("span",l," 🥉 #"+s(e.rank),1)):(n(),a("span",o," #"+s(e.rank),1))])):(n(),a("div",g," No rank yet "))}});export{y as _};

View File

@ -1 +1 @@
import{k as v,r as l,I as g,l as o,p as r,s as e,B as x,F as f,y as h,v as y,x as _,O as w}from"./style-CSeMeQaG.js";import{g as k}from"./sdk.gen-CMTwTM_A.js";const j={class:"min-h-screen bg-base-300 flex items-center justify-center px-4"},S={class:"w-full max-w-6xl"},C={key:0,class:"flex justify-center py-20"},E={key:1,class:"grid grid-cols-1 md:grid-cols-2 gap-8"},B=["onClick"],N={class:"relative h-60 bg-base-300 overflow-hidden"},$=["src","alt","onError"],A={key:1,class:"w-full h-full bg-gradient-to-br from-blue-600 to-blue-400 flex items-center justify-center text-white"},I={class:"card-body"},L={class:"card-title text-2xl"},P=v({__name:"Home",setup(F){const i=l(),n=l(!0),d=l(new Set),u=s=>`https://cdn.akamai.steamstatic.com/steam/apps/${s}/header.jpg`,b=s=>{d.value.add(s)},c=s=>{window.location.href=s};return g(async()=>{const s=await k();s.data&&(i.value=s.data),n.value=!1}),(s,t)=>(r(),o("div",j,[e("div",S,[t[6]||(t[6]=e("div",{class:"text-center mb-12"},[e("h1",{class:"text-5xl font-bold mb-4"},"PolyLAN Submitter"),e("p",{class:"text-xl text-base-content/70"}," Choose a game and submit your best solutions ")],-1)),n.value?(r(),o("div",C,[...t[1]||(t[1]=[e("span",{class:"loading loading-spinner loading-lg"},null,-1)])])):(r(),o("div",E,[e("div",{onClick:t[0]||(t[0]=a=>c("/market")),class:"card card-xl bg-base-200 shadow-xl hover:shadow-2xl transition-all cursor-pointer transform hover:-translate-y-2 hover:scale-[1.05] hover:bg-base-100 overflow-hidden"},[...t[2]||(t[2]=[x('<figure class="relative h-60 bg-gradient-to-br from-purple-600 to-blue-600 flex items-center justify-center"><i class="mdi mdi-chart-box text-6xl text-white opacity-80"></i><div class="absolute inset-0 bg-black/30 group-hover:bg-black/20 transition-colors"></div></figure><div class="card-body"><h2 class="card-title text-2xl">Market</h2><p class="text-base-content/70">Place your bets and compete</p><div class="card-actions justify-end mt-4"><button class="btn btn-primary"><i class="mdi mdi-arrow-right mr-2"></i> Place bets </button></div></div>',2)])]),(r(!0),o(f,null,h(i.value,a=>(r(),o("div",{key:a.steam_app_id,onClick:p=>c(a.path),class:"card card-xl bg-base-200 shadow-xl hover:shadow-2xl transition-all cursor-pointer transform hover:-translate-y-2 hover:scale-[1.05] hover:bg-base-100 overflow-hidden"},[e("figure",N,[d.value.has(a.steam_app_id)?(r(),o("div",A,[...t[3]||(t[3]=[e("i",{class:"mdi mdi-gamepad-variant text-5xl"},null,-1)])])):(r(),o("img",{key:0,src:u(a.steam_app_id),alt:a.name,onError:p=>b(a.steam_app_id),class:"w-full h-full object-cover"},null,40,$)),t[4]||(t[4]=e("div",{class:"absolute inset-0 bg-black/30 group-hover:bg-black/20 transition-colors"},null,-1))]),e("div",I,[e("h2",L,y(a.name),1),t[5]||(t[5]=e("div",{class:"card-actions justify-end mt-4"},[e("button",{class:"btn btn-primary"},[e("i",{class:"mdi mdi-arrow-right mr-2"}),_(" Submit results ")])],-1))])],8,B))),128))])),t[7]||(t[7]=e("div",{class:"text-center mt-12 text-base-content/50"},[e("p",null,"Select a game above to begin submitting")],-1))])]))}}),m="#app",V=document.querySelector(m),D=w(P,{...V?.dataset});D.mount(m);
import{d as v,r as l,q as g,a as o,o as r,b as e,j as f,F as x,g as h,t as y,f as _,E as w}from"./style-CCc0RrA9.js";import{g as k}from"./sdk.gen-CMTwTM_A.js";const j={class:"min-h-screen bg-base-300 flex items-center justify-center px-4"},S={class:"w-full max-w-6xl"},E={key:0,class:"flex justify-center py-20"},C={key:1,class:"grid grid-cols-1 md:grid-cols-2 gap-8"},N=["onClick"],$={class:"relative h-60 bg-base-300 overflow-hidden"},A=["src","alt","onError"],B={key:1,class:"w-full h-full bg-gradient-to-br from-blue-600 to-blue-400 flex items-center justify-center text-white"},L={class:"card-body"},P={class:"card-title text-2xl"},V=v({__name:"Home",setup(F){const i=l(),n=l(!0),d=l(new Set),u=s=>`https://cdn.akamai.steamstatic.com/steam/apps/${s}/header.jpg`,b=s=>{d.value.add(s)},c=s=>{window.location.href=s};return g(async()=>{const s=await k();s.data&&(i.value=s.data),n.value=!1}),(s,t)=>(r(),o("div",j,[e("div",S,[t[6]||(t[6]=e("div",{class:"text-center mb-12"},[e("h1",{class:"text-5xl font-bold mb-4"},"PolyLAN Submitter"),e("p",{class:"text-xl text-base-content/70"}," Choose a game and submit your best solutions ")],-1)),n.value?(r(),o("div",E,[...t[1]||(t[1]=[e("span",{class:"loading loading-spinner loading-lg"},null,-1)])])):(r(),o("div",C,[e("div",{onClick:t[0]||(t[0]=a=>c("/market")),class:"card card-xl bg-base-200 shadow-xl hover:shadow-2xl transition-all cursor-pointer transform hover:-translate-y-2 hover:scale-[1.05] hover:bg-base-100 overflow-hidden"},[...t[2]||(t[2]=[f('<figure class="relative h-60 bg-gradient-to-br from-purple-600 to-blue-600 flex items-center justify-center"><i class="mdi mdi-chart-box text-6xl text-white opacity-80"></i><div class="absolute inset-0 bg-black/30 group-hover:bg-black/20 transition-colors"></div></figure><div class="card-body"><h2 class="card-title text-2xl">Market</h2><p class="text-base-content/70">Place your bets and compete</p><div class="card-actions justify-end mt-4"><button class="btn btn-primary"><i class="mdi mdi-arrow-right mr-2"></i> Place bets </button></div></div>',2)])]),(r(!0),o(x,null,h(i.value,a=>(r(),o("div",{key:a.steam_app_id,onClick:p=>c(a.path),class:"card card-xl bg-base-200 shadow-xl hover:shadow-2xl transition-all cursor-pointer transform hover:-translate-y-2 hover:scale-[1.05] hover:bg-base-100 overflow-hidden"},[e("figure",$,[d.value.has(a.steam_app_id)?(r(),o("div",B,[...t[3]||(t[3]=[e("i",{class:"mdi mdi-gamepad-variant text-5xl"},null,-1)])])):(r(),o("img",{key:0,src:u(a.steam_app_id),alt:a.name,onError:p=>b(a.steam_app_id),class:"w-full h-full object-cover"},null,40,A)),t[4]||(t[4]=e("div",{class:"absolute inset-0 bg-black/30 group-hover:bg-black/20 transition-colors"},null,-1))]),e("div",L,[e("h2",P,y(a.name),1),t[5]||(t[5]=e("div",{class:"card-actions justify-end mt-4"},[e("button",{class:"btn btn-primary"},[e("i",{class:"mdi mdi-arrow-right mr-2"}),_(" Submit results ")])],-1))])],8,N))),128))])),t[7]||(t[7]=e("div",{class:"text-center mt-12 text-base-content/50"},[e("p",null,"Select a game above to begin submitting")],-1))])]))}}),m="#app",q=document.querySelector(m),D=w(V,{...q?.dataset});D.mount(m);

View File

@ -0,0 +1,5 @@
import{H as K,r as V,I as q,J as z,c as Q,y as p,K as F,L as st,M as nt,N as ot,O as ct,B as rt,C as at,w as ut,h as ft,P as lt,d as it,a as m,o as j,t as E}from"./style-CCc0RrA9.js";/*!
* pinia v3.0.3
* (c) 2025 Eduardo San Martin Morote
* @license MIT
*/let U;const I=t=>U=t,X=Symbol();function B(t){return t&&typeof t=="object"&&Object.prototype.toString.call(t)==="[object Object]"&&typeof t.toJSON!="function"}var R;(function(t){t.direct="direct",t.patchObject="patch object",t.patchFunction="patch function"})(R||(R={}));function ht(){const t=K(!0),n=t.run(()=>V({}));let s=[],e=[];const r=q({install(a){I(r),r._a=a,a.provide(X,r),a.config.globalProperties.$pinia=r,e.forEach(u=>s.push(u)),e=[]},use(a){return this._a?s.push(a):e.push(a),this},_p:s,_a:null,_e:t,_s:new Map,state:n});return r}const Y=()=>{};function D(t,n,s,e=Y){t.push(n);const r=()=>{const a=t.indexOf(n);a>-1&&(t.splice(a,1),e())};return!s&&rt()&&at(r),r}function x(t,...n){t.slice().forEach(s=>{s(...n)})}const bt=t=>t(),J=Symbol(),N=Symbol();function W(t,n){t instanceof Map&&n instanceof Map?n.forEach((s,e)=>t.set(e,s)):t instanceof Set&&n instanceof Set&&n.forEach(t.add,t);for(const s in n){if(!n.hasOwnProperty(s))continue;const e=n[s],r=t[s];B(r)&&B(e)&&t.hasOwnProperty(s)&&!p(e)&&!F(e)?t[s]=W(r,e):t[s]=e}return t}const yt=Symbol();function dt(t){return!B(t)||!Object.prototype.hasOwnProperty.call(t,yt)}const{assign:h}=Object;function St(t){return!!(p(t)&&t.effect)}function vt(t,n,s,e){const{state:r,actions:a,getters:u}=n,C=s.state.value[t];let y;function b(){C||(s.state.value[t]=r?r():{});const d=lt(s.state.value[t]);return h(d,a,Object.keys(u||{}).reduce((S,v)=>(S[v]=q(Q(()=>{I(s);const g=s._s.get(t);return u[v].call(g,g)})),S),{}))}return y=Z(t,b,n,s,e,!0),y}function Z(t,n,s={},e,r,a){let u;const C=h({actions:{}},s),y={deep:!0};let b,d,S=[],v=[],g;const k=e.state.value[t];!a&&!k&&(e.state.value[t]={}),V({});let H;function M(c){let o;b=d=!1,typeof c=="function"?(c(e.state.value[t]),o={type:R.patchFunction,storeId:t,events:g}):(W(e.state.value[t],c),o={type:R.patchObject,payload:c,storeId:t,events:g});const f=H=Symbol();ft().then(()=>{H===f&&(b=!0)}),d=!0,x(S,o,e.state.value[t])}const G=a?function(){const{state:o}=s,f=o?o():{};this.$patch(_=>{h(_,f)})}:Y;function $(){u.stop(),S=[],v=[],e._s.delete(t)}const A=(c,o="")=>{if(J in c)return c[N]=o,c;const f=function(){I(e);const _=Array.from(arguments),P=[],L=[];function tt(l){P.push(l)}function et(l){L.push(l)}x(v,{args:_,name:f[N],store:i,after:tt,onError:et});let w;try{w=c.apply(this&&this.$id===t?this:i,_)}catch(l){throw x(L,l),l}return w instanceof Promise?w.then(l=>(x(P,l),l)).catch(l=>(x(L,l),Promise.reject(l))):(x(P,w),w)};return f[J]=!0,f[N]=o,f},T={_p:e,$id:t,$onAction:D.bind(null,v),$patch:M,$reset:G,$subscribe(c,o={}){const f=D(S,c,o.detached,()=>_()),_=u.run(()=>ut(()=>e.state.value[t],P=>{(o.flush==="sync"?d:b)&&c({storeId:t,type:R.direct,events:g},P)},h({},y,o)));return f},$dispose:$},i=ct(T);e._s.set(t,i);const O=(e._a&&e._a.runWithContext||bt)(()=>e._e.run(()=>(u=K()).run(()=>n({action:A}))));for(const c in O){const o=O[c];if(p(o)&&!St(o)||F(o))a||(k&&dt(o)&&(p(o)?o.value=k[c]:W(o,k[c])),e.state.value[t][c]=o);else if(typeof o=="function"){const f=A(o,c);O[c]=f,C.actions[c]=o}}return h(i,O),h(z(i),O),Object.defineProperty(i,"$state",{get:()=>e.state.value[t],set:c=>{M(o=>{h(o,c)})}}),e._p.forEach(c=>{h(i,u.run(()=>c({store:i,app:e._a,pinia:e,options:C})))}),k&&a&&s.hydrate&&s.hydrate(i.$state,k),b=!0,d=!0,i}/*! #__NO_SIDE_EFFECTS__ */function Pt(t,n,s){let e;const r=typeof n=="function";e=r?s:n;function a(u,C){const y=ot();return u=u||(y?nt(X,null):null),u&&I(u),u=U,u._s.has(t)||(r?Z(t,n,e,u):vt(t,e,u)),u._s.get(t)}return a.$id=t,a}function wt(t){const n=z(t),s={};for(const e in n){const r=n[e];r.effect?s[e]=Q({get:()=>t[e],set(a){t[e]=a}}):(p(r)||F(r))&&(s[e]=st(t,e))}return s}const gt={key:0,class:"flex justify-center"},kt={key:0,class:"badge badge-warning badge-lg"},_t={key:1,class:"badge badge-lg"},mt={key:2,class:"badge badge-lg"},jt={key:3,class:"badge badge-lg"},xt={key:1,class:"text-2xl text-base-content/50"},Rt=it({__name:"RankBadge",props:{rank:{}},setup(t){return(n,s)=>t.rank!==null?(j(),m("div",gt,[t.rank===1?(j(),m("span",kt," 🏆 #"+E(t.rank),1)):t.rank===2?(j(),m("span",_t," 🥈 #"+E(t.rank),1)):t.rank===3?(j(),m("span",mt," 🥉 #"+E(t.rank),1)):(j(),m("span",jt," #"+E(t.rank),1))])):(j(),m("div",xt," No rank yet "))}}),pt=ht();export{Rt as _,Pt as d,pt as p,wt as s};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,9 +1,9 @@
{
"_RankBadge.vue_vue_type_script_setup_true_lang-CfKZiK2-.js": {
"file": "assets/RankBadge.vue_vue_type_script_setup_true_lang-CfKZiK2-.js",
"name": "RankBadge.vue_vue_type_script_setup_true_lang",
"_index-B10U1JZR.js": {
"file": "assets/index-B10U1JZR.js",
"name": "index",
"imports": [
"_style-CSeMeQaG.js"
"_style-CCc0RrA9.js"
]
},
"_sdk.gen-CMTwTM_A.js": {
@ -14,8 +14,8 @@
"file": "assets/style-B7hBs3CR.css",
"src": "_style-B7hBs3CR.css"
},
"_style-CSeMeQaG.js": {
"file": "assets/style-CSeMeQaG.js",
"_style-CCc0RrA9.js": {
"file": "assets/style-CCc0RrA9.js",
"name": "style",
"css": [
"assets/style-B7hBs3CR.css"
@ -44,34 +44,34 @@
"src": "node_modules/.pnpm/@mdi+font@7.4.47/node_modules/@mdi/font/fonts/materialdesignicons-webfont.woff2"
},
"src/home.ts": {
"file": "assets/home-SJcM6NSq.js",
"file": "assets/home-De93wAWA.js",
"name": "home",
"src": "src/home.ts",
"isEntry": true,
"imports": [
"_style-CSeMeQaG.js",
"_style-CCc0RrA9.js",
"_sdk.gen-CMTwTM_A.js"
]
},
"src/noita.ts": {
"file": "assets/noita-D-VLRi4K.js",
"file": "assets/noita-BBUDcHwQ.js",
"name": "noita",
"src": "src/noita.ts",
"isEntry": true,
"imports": [
"_style-CSeMeQaG.js",
"_RankBadge.vue_vue_type_script_setup_true_lang-CfKZiK2-.js"
"_style-CCc0RrA9.js",
"_index-B10U1JZR.js"
]
},
"src/opus-magnum.ts": {
"file": "assets/opus_magnum-CBjPWRy9.js",
"file": "assets/opus_magnum-CniXRQHB.js",
"name": "opus_magnum",
"src": "src/opus-magnum.ts",
"isEntry": true,
"imports": [
"_style-CSeMeQaG.js",
"_sdk.gen-CMTwTM_A.js",
"_RankBadge.vue_vue_type_script_setup_true_lang-CfKZiK2-.js"
"_style-CCc0RrA9.js",
"_index-B10U1JZR.js",
"_sdk.gen-CMTwTM_A.js"
]
}
}

View File

@ -1 +1 @@
{"root":["./src/home.ts","./src/market.ts","./src/noita.ts","./src/opus-magnum.ts","./src/api/client.gen.ts","./src/api/index.ts","./src/api/sdk.gen.ts","./src/api/types.gen.ts","./src/api/client/client.gen.ts","./src/api/client/index.ts","./src/api/client/types.gen.ts","./src/api/client/utils.gen.ts","./src/api/core/auth.gen.ts","./src/api/core/bodySerializer.gen.ts","./src/api/core/params.gen.ts","./src/api/core/pathSerializer.gen.ts","./src/api/core/queryKeySerializer.gen.ts","./src/api/core/serverSentEvents.gen.ts","./src/api/core/types.gen.ts","./src/api/core/utils.gen.ts","./src/services/apiService.ts","./src/services/ocrService.ts","./src/stores/index.ts","./src/stores/market.ts","./src/stores/puzzles.ts","./src/stores/submissions.ts","./src/stores/uploads.ts","./src/types/index.ts","./src/Home.vue","./src/Market.vue","./src/Noita.vue","./src/OpusMagnum.vue","./src/components/AdminPanel.vue","./src/components/FileUpload.vue","./src/components/MarketCard.vue","./src/components/PuzzleCard.vue","./src/components/PuzzleResults.vue","./src/components/RankBadge.vue","./src/components/Results.vue","./src/components/SubmissionForm.vue","./src/components/TopUsersLeaderboard.vue","./src/components/UserBets.vue","./src/components/Winners.vue"],"version":"5.9.3"}
{"root":["./src/home.ts","./src/market.ts","./src/noita.ts","./src/opus-magnum.ts","./src/api/client.gen.ts","./src/api/index.ts","./src/api/sdk.gen.ts","./src/api/types.gen.ts","./src/api/client/client.gen.ts","./src/api/client/index.ts","./src/api/client/types.gen.ts","./src/api/client/utils.gen.ts","./src/api/core/auth.gen.ts","./src/api/core/bodySerializer.gen.ts","./src/api/core/params.gen.ts","./src/api/core/pathSerializer.gen.ts","./src/api/core/queryKeySerializer.gen.ts","./src/api/core/serverSentEvents.gen.ts","./src/api/core/types.gen.ts","./src/api/core/utils.gen.ts","./src/services/apiService.ts","./src/services/ocrService.ts","./src/stores/index.ts","./src/stores/market.ts","./src/stores/noita.ts","./src/stores/puzzles.ts","./src/stores/submissions.ts","./src/stores/uploads.ts","./src/types/index.ts","./src/Home.vue","./src/Market.vue","./src/Noita.vue","./src/OpusMagnum.vue","./src/components/AdminPanel.vue","./src/components/FileUpload.vue","./src/components/MarketCard.vue","./src/components/PuzzleCard.vue","./src/components/PuzzleResults.vue","./src/components/RankBadge.vue","./src/components/Results.vue","./src/components/SubmissionForm.vue","./src/components/TopUsersLeaderboard.vue","./src/components/UserBets.vue","./src/components/Winners.vue"],"version":"5.9.3"}