@xcpcio/board-app 0.27.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/assets/{Board-f6dd53aa.css → Board-2cad79eb.css} +1 -1
  2. package/dist/assets/Board-9442407d.js +3 -0
  3. package/dist/assets/{DataSourceInput.vue_vue_type_script_setup_true_lang-effb1be0.js → DataSourceInput.vue_vue_type_script_setup_true_lang-d16f2a12.js} +1 -1
  4. package/dist/assets/{TheInput.vue_vue_type_script_setup_true_lang-2b1997a6.js → TheInput.vue_vue_type_script_setup_true_lang-1dafe5cb.js} +1 -1
  5. package/dist/assets/{_...all_-bb67b33f.js → _...all_-d54370e4.js} +1 -1
  6. package/dist/assets/{_name_-d0a3d653.js → _name_-c7264d89.js} +1 -1
  7. package/dist/assets/{about-8e4f6558.js → about-55b7ba92.js} +1 -1
  8. package/dist/assets/{board-c38fef02.js → board-88a98e6a.js} +1 -1
  9. package/dist/assets/{board-layout-2f8b4c8e.js → board-layout-e4e0bae6.js} +1 -1
  10. package/dist/assets/{headless-04b3d2be.js → headless-3466779c.js} +1 -1
  11. package/dist/assets/{home-f7c22489.js → home-37e85146.js} +1 -1
  12. package/dist/assets/{index-522cf95a.css → index-a0a089d2.css} +1 -1
  13. package/dist/assets/{index-e972e718.js → index-bc173751.js} +1 -1
  14. package/dist/assets/{index-7955279c.js → index-f1d19db1.js} +35 -35
  15. package/dist/assets/{index-layout-f3e9e819.js → index-layout-c91f7cfd.js} +1 -1
  16. package/dist/assets/{test-94bf1ee1.js → test-133c6df2.js} +1 -1
  17. package/dist/assets/{useQueryBoardData-78fadedd.js → useQueryBoardData-c0567554.js} +1 -1
  18. package/dist/assets/{user-c31467e6.js → user-6ae7ff90.js} +1 -1
  19. package/dist/assets/{virtual_pwa-register-d035b16b.js → virtual_pwa-register-7ea4486e.js} +1 -1
  20. package/dist/index.html +3 -3
  21. package/dist/sw.js +1 -1
  22. package/package.json +3 -3
  23. package/src/components/board/ProblemBlock.vue +57 -0
  24. package/src/components/board/ProblemInfoModal.vue +111 -0
  25. package/src/components/board/Standings.vue +7 -13
  26. package/src/components/board/SubmissionsTable.vue +15 -23
  27. package/src/components/flowbite/Tooltip.vue +2 -2
  28. package/src/components.d.ts +2 -0
  29. package/src/composables/statistics.ts +3 -3
  30. package/src/composables/useQueryBoardData.ts +5 -0
  31. package/dist/assets/Board-88436e20.js +0 -3
@@ -1 +1 @@
1
- import{a as s,r as a,o as c,c as r,b as e,d as _,F as m,e as p,f as l}from"./index-7955279c.js";const i={},d={class:"lg:mt-[-52px]","py-2":"","text-gray-700":"","dark:text-gray-200":""};function u(x,f){const o=p,t=a("RouterView"),n=l;return c(),r(m,null,[e(o,{width:"sm:w-[1024px] lg:w-screen"}),_("main",d,[e(t),e(n,{class:"sm:w-[1024px] lg:w-screen"})])],64)}const w=s(i,[["render",u]]);export{w as default};
1
+ import{a as s,r as a,o as c,c as r,b as e,d as _,F as m,e as p,f as l}from"./index-f1d19db1.js";const i={},d={class:"lg:mt-[-52px]","py-2":"","text-gray-700":"","dark:text-gray-200":""};function u(x,f){const o=p,t=a("RouterView"),n=l;return c(),r(m,null,[e(o,{width:"sm:w-[1024px] lg:w-screen"}),_("main",d,[e(t),e(n,{class:"sm:w-[1024px] lg:w-screen"})])],64)}const w=s(i,[["render",u]]);export{w as default};
@@ -1 +1 @@
1
- import{_ as m}from"./TheInput.vue_vue_type_script_setup_true_lang-2b1997a6.js";import{g as _,i as p,D as f,q as h,o as b,c as v,d as e,t as n,j as o,b as y,E as x,G as g,C as l}from"./index-7955279c.js";import{u as w}from"./user-c31467e6.js";const V={flex:"","flex-col":"","justify-center":"","items-center":""},k=e("div",{"text-4xl":""},[e("div",{"i-carbon-campsite":""})],-1),C=e("p",null,[e("a",{rel:"noreferrer",href:"https://github.com/antfu/vitesse",target:"_blank"}," Vitesse ")],-1),I={"text-sm":"","opacity-75":""},B=e("div",{"py-4":""},null,-1),K={"w-48":""},N={class:"hidden",for:"input"},R=["disabled"],U=_({name:"IndexPage",__name:"test",setup(j){const r=w(),t=p(r.savedName),c=f();function a(){t.value&&c.push(`/hi/${encodeURIComponent(t.value)}`)}const{t:s}=h();return(D,i)=>{const d=m;return b(),v("div",V,[k,C,e("p",null,[e("em",I,n(o(s)("intro.desc")),1)]),B,e("div",K,[y(d,{modelValue:o(t),"onUpdate:modelValue":i[0]||(i[0]=u=>x(t)?t.value=u:null),placeholder:o(s)("intro.whats-your-name"),autocomplete:"false",onKeydown:g(a,["enter"])},null,8,["modelValue","placeholder","onKeydown"]),e("label",N,n(o(s)("intro.whats-your-name")),1)]),e("div",null,[e("button",{"m-3":"","text-sm":"",btn:"",disabled:!o(t),onClick:a},n(o(s)("button.go")),9,R)])])}}});typeof l=="function"&&l(U);export{U as default};
1
+ import{_ as m}from"./TheInput.vue_vue_type_script_setup_true_lang-1dafe5cb.js";import{g as _,i as p,D as f,q as h,o as b,c as v,d as e,t as n,j as o,b as y,E as x,G as g,C as l}from"./index-f1d19db1.js";import{u as w}from"./user-6ae7ff90.js";const V={flex:"","flex-col":"","justify-center":"","items-center":""},k=e("div",{"text-4xl":""},[e("div",{"i-carbon-campsite":""})],-1),C=e("p",null,[e("a",{rel:"noreferrer",href:"https://github.com/antfu/vitesse",target:"_blank"}," Vitesse ")],-1),I={"text-sm":"","opacity-75":""},B=e("div",{"py-4":""},null,-1),K={"w-48":""},N={class:"hidden",for:"input"},R=["disabled"],U=_({name:"IndexPage",__name:"test",setup(j){const r=w(),t=p(r.savedName),c=f();function a(){t.value&&c.push(`/hi/${encodeURIComponent(t.value)}`)}const{t:s}=h();return(D,i)=>{const d=m;return b(),v("div",V,[k,C,e("p",null,[e("em",I,n(o(s)("intro.desc")),1)]),B,e("div",K,[y(d,{modelValue:o(t),"onUpdate:modelValue":i[0]||(i[0]=u=>x(t)?t.value=u:null),placeholder:o(s)("intro.whats-your-name"),autocomplete:"false",onKeydown:g(a,["enter"])},null,8,["modelValue","placeholder","onKeydown"]),e("label",N,n(o(s)("intro.whats-your-name")),1)]),e("div",null,[e("button",{"m-3":"","text-sm":"",btn:"",disabled:!o(t),onClick:a},n(o(s)("button.go")),9,R)])])}}});typeof l=="function"&&l(U);export{U as default};
@@ -1 +1 @@
1
- import{ak as M,al as S,am as K,an as U,ao as D,ap as B,aq as W,ar as V,as as A,at as z,au as N,av as H,aw as Y,ax as _,h as P,ay as $,w as b,az as x,aA as G,aB as J,aC as X,aD as Z,j as C,aE as ee,aF as te}from"./index-7955279c.js";class se extends M{constructor(e,t){super(),this.client=e,this.options=t,this.trackedProps=new Set,this.selectError=null,this.bindMethods(),this.setOptions(t)}bindMethods(){this.remove=this.remove.bind(this),this.refetch=this.refetch.bind(this)}onSubscribe(){this.listeners.size===1&&(this.currentQuery.addObserver(this),k(this.currentQuery,this.options)&&this.executeFetch(),this.updateTimers())}onUnsubscribe(){this.hasListeners()||this.destroy()}shouldFetchOnReconnect(){return E(this.currentQuery,this.options,this.options.refetchOnReconnect)}shouldFetchOnWindowFocus(){return E(this.currentQuery,this.options,this.options.refetchOnWindowFocus)}destroy(){this.listeners=new Set,this.clearStaleTimeout(),this.clearRefetchInterval(),this.currentQuery.removeObserver(this)}setOptions(e,t){const s=this.options,u=this.currentQuery;if(this.options=this.client.defaultQueryOptions(e),S(s,this.options)||this.client.getQueryCache().notify({type:"observerOptionsUpdated",query:this.currentQuery,observer:this}),typeof this.options.enabled<"u"&&typeof this.options.enabled!="boolean")throw new Error("Expected enabled to be a boolean");this.options.queryKey||(this.options.queryKey=s.queryKey),this.updateQuery();const i=this.hasListeners();i&&j(this.currentQuery,u,this.options,s)&&this.executeFetch(),this.updateResult(t),i&&(this.currentQuery!==u||this.options.enabled!==s.enabled||this.options.staleTime!==s.staleTime)&&this.updateStaleTimeout();const n=this.computeRefetchInterval();i&&(this.currentQuery!==u||this.options.enabled!==s.enabled||n!==this.currentRefetchInterval)&&this.updateRefetchInterval(n)}getOptimisticResult(e){const t=this.client.getQueryCache().build(this.client,e),s=this.createResult(t,e);return ie(this,s,e)&&(this.currentResult=s,this.currentResultOptions=this.options,this.currentResultState=this.currentQuery.state),s}getCurrentResult(){return this.currentResult}trackResult(e){const t={};return Object.keys(e).forEach(s=>{Object.defineProperty(t,s,{configurable:!1,enumerable:!0,get:()=>(this.trackedProps.add(s),e[s])})}),t}getCurrentQuery(){return this.currentQuery}remove(){this.client.getQueryCache().remove(this.currentQuery)}refetch({refetchPage:e,...t}={}){return this.fetch({...t,meta:{refetchPage:e}})}fetchOptimistic(e){const t=this.client.defaultQueryOptions(e),s=this.client.getQueryCache().build(this.client,t);return s.isFetchingOptimistic=!0,s.fetch().then(()=>this.createResult(s,t))}fetch(e){var t;return this.executeFetch({...e,cancelRefetch:(t=e.cancelRefetch)!=null?t:!0}).then(()=>(this.updateResult(),this.currentResult))}executeFetch(e){this.updateQuery();let t=this.currentQuery.fetch(this.options,e);return e!=null&&e.throwOnError||(t=t.catch(K)),t}updateStaleTimeout(){if(this.clearStaleTimeout(),U||this.currentResult.isStale||!D(this.options.staleTime))return;const t=B(this.currentResult.dataUpdatedAt,this.options.staleTime)+1;this.staleTimeoutId=setTimeout(()=>{this.currentResult.isStale||this.updateResult()},t)}computeRefetchInterval(){var e;return typeof this.options.refetchInterval=="function"?this.options.refetchInterval(this.currentResult.data,this.currentQuery):(e=this.options.refetchInterval)!=null?e:!1}updateRefetchInterval(e){this.clearRefetchInterval(),this.currentRefetchInterval=e,!(U||this.options.enabled===!1||!D(this.currentRefetchInterval)||this.currentRefetchInterval===0)&&(this.refetchIntervalId=setInterval(()=>{(this.options.refetchIntervalInBackground||W.isFocused())&&this.executeFetch()},this.currentRefetchInterval))}updateTimers(){this.updateStaleTimeout(),this.updateRefetchInterval(this.computeRefetchInterval())}clearStaleTimeout(){this.staleTimeoutId&&(clearTimeout(this.staleTimeoutId),this.staleTimeoutId=void 0)}clearRefetchInterval(){this.refetchIntervalId&&(clearInterval(this.refetchIntervalId),this.refetchIntervalId=void 0)}createResult(e,t){const s=this.currentQuery,u=this.options,i=this.currentResult,n=this.currentResultState,a=this.currentResultOptions,l=e!==s,h=l?e.state:this.currentQueryInitialState,o=l?this.currentResult:this.previousQueryResult,{state:c}=e;let{dataUpdatedAt:d,error:R,errorUpdatedAt:m,fetchStatus:v,status:f}=c,w=!1,F=!1,y;if(t._optimisticResults){const p=this.hasListeners(),O=!p&&k(e,t),L=p&&j(e,s,t,u);(O||L)&&(v=V(e.options.networkMode)?"fetching":"paused",d||(f="loading")),t._optimisticResults==="isRestoring"&&(v="idle")}if(t.keepPreviousData&&!c.dataUpdatedAt&&o!=null&&o.isSuccess&&f!=="error")y=o.data,d=o.dataUpdatedAt,f=o.status,w=!0;else if(t.select&&typeof c.data<"u")if(i&&c.data===(n==null?void 0:n.data)&&t.select===this.selectFn)y=this.selectResult;else try{this.selectFn=t.select,y=t.select(c.data),y=A(i==null?void 0:i.data,y,t),this.selectResult=y,this.selectError=null}catch(p){this.selectError=p}else y=c.data;if(typeof t.placeholderData<"u"&&typeof y>"u"&&f==="loading"){let p;if(i!=null&&i.isPlaceholderData&&t.placeholderData===(a==null?void 0:a.placeholderData))p=i.data;else if(p=typeof t.placeholderData=="function"?t.placeholderData():t.placeholderData,t.select&&typeof p<"u")try{p=t.select(p),this.selectError=null}catch(O){this.selectError=O}typeof p<"u"&&(f="success",y=A(i==null?void 0:i.data,p,t),F=!0)}this.selectError&&(R=this.selectError,y=this.selectResult,m=Date.now(),f="error");const Q=v==="fetching",g=f==="loading",I=f==="error";return{status:f,fetchStatus:v,isLoading:g,isSuccess:f==="success",isError:I,isInitialLoading:g&&Q,data:y,dataUpdatedAt:d,error:R,errorUpdatedAt:m,failureCount:c.fetchFailureCount,failureReason:c.fetchFailureReason,errorUpdateCount:c.errorUpdateCount,isFetched:c.dataUpdateCount>0||c.errorUpdateCount>0,isFetchedAfterMount:c.dataUpdateCount>h.dataUpdateCount||c.errorUpdateCount>h.errorUpdateCount,isFetching:Q,isRefetching:Q&&!g,isLoadingError:I&&c.dataUpdatedAt===0,isPaused:v==="paused",isPlaceholderData:F,isPreviousData:w,isRefetchError:I&&c.dataUpdatedAt!==0,isStale:T(e,t),refetch:this.refetch,remove:this.remove}}updateResult(e){const t=this.currentResult,s=this.createResult(this.currentQuery,this.options);if(this.currentResultState=this.currentQuery.state,this.currentResultOptions=this.options,S(s,t))return;this.currentResult=s;const u={cache:!0},i=()=>{if(!t)return!0;const{notifyOnChangeProps:n}=this.options,a=typeof n=="function"?n():n;if(a==="all"||!a&&!this.trackedProps.size)return!0;const l=new Set(a??this.trackedProps);return this.options.useErrorBoundary&&l.add("error"),Object.keys(this.currentResult).some(h=>{const o=h;return this.currentResult[o]!==t[o]&&l.has(o)})};(e==null?void 0:e.listeners)!==!1&&i()&&(u.listeners=!0),this.notify({...u,...e})}updateQuery(){const e=this.client.getQueryCache().build(this.client,this.options);if(e===this.currentQuery)return;const t=this.currentQuery;this.currentQuery=e,this.currentQueryInitialState=e.state,this.previousQueryResult=this.currentResult,this.hasListeners()&&(t==null||t.removeObserver(this),e.addObserver(this))}onQueryUpdate(e){const t={};e.type==="success"?t.onSuccess=!e.manual:e.type==="error"&&!z(e.error)&&(t.onError=!0),this.updateResult(t),this.hasListeners()&&this.updateTimers()}notify(e){N.batch(()=>{if(e.onSuccess){var t,s,u,i;(t=(s=this.options).onSuccess)==null||t.call(s,this.currentResult.data),(u=(i=this.options).onSettled)==null||u.call(i,this.currentResult.data,null)}else if(e.onError){var n,a,l,h;(n=(a=this.options).onError)==null||n.call(a,this.currentResult.error),(l=(h=this.options).onSettled)==null||l.call(h,void 0,this.currentResult.error)}e.listeners&&this.listeners.forEach(({listener:o})=>{o(this.currentResult)}),e.cache&&this.client.getQueryCache().notify({query:this.currentQuery,type:"observerResultsUpdated"})})}}function re(r,e){return e.enabled!==!1&&!r.state.dataUpdatedAt&&!(r.state.status==="error"&&e.retryOnMount===!1)}function k(r,e){return re(r,e)||r.state.dataUpdatedAt>0&&E(r,e,e.refetchOnMount)}function E(r,e,t){if(e.enabled!==!1){const s=typeof t=="function"?t(r):t;return s==="always"||s!==!1&&T(r,e)}return!1}function j(r,e,t,s){return t.enabled!==!1&&(r!==e||s.enabled===!1)&&(!t.suspense||r.state.status!=="error")&&T(r,t)}function T(r,e){return r.isStaleByTime(e.staleTime)}function ie(r,e,t){return t.keepPreviousData?!1:t.placeholderData!==void 0?e.isPlaceholderData:!S(r.getCurrentResult(),e)}function ne(r=""){var e;if(!((e=H())==null?void 0:e.proxy))throw new Error("vue-query hooks can only be used inside setup() function.");const s=_(r),u=Y(s);if(!u)throw new Error("No 'queryClient' found in Vue context, use 'VueQueryPlugin' to properly initialize the library.");return u}function ue(r,e,t={},s={}){var u;const i=P(()=>ae(e,t,s)),n=(u=i.value.queryClient)!=null?u:ne(i.value.queryClientKey),a=P(()=>{const d=n.defaultQueryOptions(i.value);return d._optimisticResults=n.isRestoring.value?"isRestoring":"optimistic",d}),l=new r(n,a.value),h=$(l.getCurrentResult());let o=()=>{};b(n.isRestoring,d=>{d||(o(),o=l.subscribe(R=>{x(h,R)}))},{immediate:!0}),b(a,()=>{l.setOptions(a.value),x(h,l.getCurrentResult())}),G(()=>{o()});const c=()=>new Promise((d,R)=>{let m=()=>{};const v=()=>{if(a.value.enabled!==!1){const f=l.getOptimisticResult(a.value);f.isStale?(m(),l.fetchOptimistic(a.value).then(d,R)):(m(),d(f))}};v(),m=b(a,v,{deep:!0})});return b(()=>h.error,d=>{if(h.isError&&!h.isFetching&&J(a.value.useErrorBoundary,[d,l.getCurrentQuery()]))throw d}),{...X(Z(h)),suspense:c}}function ae(r,e={},t={}){const s=C(r),u=C(e),i=C(t);let n=s;return ee(s)?typeof u=="function"?n={...i,queryKey:s,queryFn:u}:n={...u,queryKey:s}:n=s,te(n)}function le(r,e,t){const s=ue(se,r,e,t);return{...s,refetch:s.refetch.value,remove:s.remove.value}}const ce=3,q=30*1e3;async function oe(r,e){const t=r.startsWith("/")?r.slice(1):r;let s=`${window.DATA_HOST}${t}`;r.startsWith("http")&&(s=r),s.endsWith("/")&&(s=s.slice(0,-1));const u=await fetch(`${s}/config.json?t=${e??0}`),i=await fetch(`${s}/team.json?t=${e??0}`),n=await fetch(`${s}/run.json?t=${e??0}`);return Promise.all([u.json(),i.json(),n.json()]).then(l=>({contest:l[0],teams:l[1],submissions:l[2]}))}function fe(r,e){return le({queryKey:[r,e.value.getTime()],queryFn:()=>oe(r,e.value.getTime()),retry:ce,staleTime:q,refetchInterval:q})}export{fe as u};
1
+ import{ak as M,al as S,am as K,an as U,ao as D,ap as B,aq as W,ar as V,as as A,at as z,au as N,av as $,aw as H,ax as Y,h as P,ay as _,w as b,az as x,aA as G,aB as J,aC as X,aD as Z,j as C,aE as ee,aF as te}from"./index-f1d19db1.js";class se extends M{constructor(e,t){super(),this.client=e,this.options=t,this.trackedProps=new Set,this.selectError=null,this.bindMethods(),this.setOptions(t)}bindMethods(){this.remove=this.remove.bind(this),this.refetch=this.refetch.bind(this)}onSubscribe(){this.listeners.size===1&&(this.currentQuery.addObserver(this),k(this.currentQuery,this.options)&&this.executeFetch(),this.updateTimers())}onUnsubscribe(){this.hasListeners()||this.destroy()}shouldFetchOnReconnect(){return E(this.currentQuery,this.options,this.options.refetchOnReconnect)}shouldFetchOnWindowFocus(){return E(this.currentQuery,this.options,this.options.refetchOnWindowFocus)}destroy(){this.listeners=new Set,this.clearStaleTimeout(),this.clearRefetchInterval(),this.currentQuery.removeObserver(this)}setOptions(e,t){const s=this.options,n=this.currentQuery;if(this.options=this.client.defaultQueryOptions(e),S(s,this.options)||this.client.getQueryCache().notify({type:"observerOptionsUpdated",query:this.currentQuery,observer:this}),typeof this.options.enabled<"u"&&typeof this.options.enabled!="boolean")throw new Error("Expected enabled to be a boolean");this.options.queryKey||(this.options.queryKey=s.queryKey),this.updateQuery();const i=this.hasListeners();i&&j(this.currentQuery,n,this.options,s)&&this.executeFetch(),this.updateResult(t),i&&(this.currentQuery!==n||this.options.enabled!==s.enabled||this.options.staleTime!==s.staleTime)&&this.updateStaleTimeout();const u=this.computeRefetchInterval();i&&(this.currentQuery!==n||this.options.enabled!==s.enabled||u!==this.currentRefetchInterval)&&this.updateRefetchInterval(u)}getOptimisticResult(e){const t=this.client.getQueryCache().build(this.client,e),s=this.createResult(t,e);return ie(this,s,e)&&(this.currentResult=s,this.currentResultOptions=this.options,this.currentResultState=this.currentQuery.state),s}getCurrentResult(){return this.currentResult}trackResult(e){const t={};return Object.keys(e).forEach(s=>{Object.defineProperty(t,s,{configurable:!1,enumerable:!0,get:()=>(this.trackedProps.add(s),e[s])})}),t}getCurrentQuery(){return this.currentQuery}remove(){this.client.getQueryCache().remove(this.currentQuery)}refetch({refetchPage:e,...t}={}){return this.fetch({...t,meta:{refetchPage:e}})}fetchOptimistic(e){const t=this.client.defaultQueryOptions(e),s=this.client.getQueryCache().build(this.client,t);return s.isFetchingOptimistic=!0,s.fetch().then(()=>this.createResult(s,t))}fetch(e){var t;return this.executeFetch({...e,cancelRefetch:(t=e.cancelRefetch)!=null?t:!0}).then(()=>(this.updateResult(),this.currentResult))}executeFetch(e){this.updateQuery();let t=this.currentQuery.fetch(this.options,e);return e!=null&&e.throwOnError||(t=t.catch(K)),t}updateStaleTimeout(){if(this.clearStaleTimeout(),U||this.currentResult.isStale||!D(this.options.staleTime))return;const t=B(this.currentResult.dataUpdatedAt,this.options.staleTime)+1;this.staleTimeoutId=setTimeout(()=>{this.currentResult.isStale||this.updateResult()},t)}computeRefetchInterval(){var e;return typeof this.options.refetchInterval=="function"?this.options.refetchInterval(this.currentResult.data,this.currentQuery):(e=this.options.refetchInterval)!=null?e:!1}updateRefetchInterval(e){this.clearRefetchInterval(),this.currentRefetchInterval=e,!(U||this.options.enabled===!1||!D(this.currentRefetchInterval)||this.currentRefetchInterval===0)&&(this.refetchIntervalId=setInterval(()=>{(this.options.refetchIntervalInBackground||W.isFocused())&&this.executeFetch()},this.currentRefetchInterval))}updateTimers(){this.updateStaleTimeout(),this.updateRefetchInterval(this.computeRefetchInterval())}clearStaleTimeout(){this.staleTimeoutId&&(clearTimeout(this.staleTimeoutId),this.staleTimeoutId=void 0)}clearRefetchInterval(){this.refetchIntervalId&&(clearInterval(this.refetchIntervalId),this.refetchIntervalId=void 0)}createResult(e,t){const s=this.currentQuery,n=this.options,i=this.currentResult,u=this.currentResultState,a=this.currentResultOptions,l=e!==s,h=l?e.state:this.currentQueryInitialState,c=l?this.currentResult:this.previousQueryResult,{state:o}=e;let{dataUpdatedAt:d,error:R,errorUpdatedAt:m,fetchStatus:v,status:f}=o,w=!1,F=!1,y;if(t._optimisticResults){const p=this.hasListeners(),O=!p&&k(e,t),L=p&&j(e,s,t,n);(O||L)&&(v=V(e.options.networkMode)?"fetching":"paused",d||(f="loading")),t._optimisticResults==="isRestoring"&&(v="idle")}if(t.keepPreviousData&&!o.dataUpdatedAt&&c!=null&&c.isSuccess&&f!=="error")y=c.data,d=c.dataUpdatedAt,f=c.status,w=!0;else if(t.select&&typeof o.data<"u")if(i&&o.data===(u==null?void 0:u.data)&&t.select===this.selectFn)y=this.selectResult;else try{this.selectFn=t.select,y=t.select(o.data),y=A(i==null?void 0:i.data,y,t),this.selectResult=y,this.selectError=null}catch(p){this.selectError=p}else y=o.data;if(typeof t.placeholderData<"u"&&typeof y>"u"&&f==="loading"){let p;if(i!=null&&i.isPlaceholderData&&t.placeholderData===(a==null?void 0:a.placeholderData))p=i.data;else if(p=typeof t.placeholderData=="function"?t.placeholderData():t.placeholderData,t.select&&typeof p<"u")try{p=t.select(p),this.selectError=null}catch(O){this.selectError=O}typeof p<"u"&&(f="success",y=A(i==null?void 0:i.data,p,t),F=!0)}this.selectError&&(R=this.selectError,y=this.selectResult,m=Date.now(),f="error");const Q=v==="fetching",g=f==="loading",I=f==="error";return{status:f,fetchStatus:v,isLoading:g,isSuccess:f==="success",isError:I,isInitialLoading:g&&Q,data:y,dataUpdatedAt:d,error:R,errorUpdatedAt:m,failureCount:o.fetchFailureCount,failureReason:o.fetchFailureReason,errorUpdateCount:o.errorUpdateCount,isFetched:o.dataUpdateCount>0||o.errorUpdateCount>0,isFetchedAfterMount:o.dataUpdateCount>h.dataUpdateCount||o.errorUpdateCount>h.errorUpdateCount,isFetching:Q,isRefetching:Q&&!g,isLoadingError:I&&o.dataUpdatedAt===0,isPaused:v==="paused",isPlaceholderData:F,isPreviousData:w,isRefetchError:I&&o.dataUpdatedAt!==0,isStale:T(e,t),refetch:this.refetch,remove:this.remove}}updateResult(e){const t=this.currentResult,s=this.createResult(this.currentQuery,this.options);if(this.currentResultState=this.currentQuery.state,this.currentResultOptions=this.options,S(s,t))return;this.currentResult=s;const n={cache:!0},i=()=>{if(!t)return!0;const{notifyOnChangeProps:u}=this.options,a=typeof u=="function"?u():u;if(a==="all"||!a&&!this.trackedProps.size)return!0;const l=new Set(a??this.trackedProps);return this.options.useErrorBoundary&&l.add("error"),Object.keys(this.currentResult).some(h=>{const c=h;return this.currentResult[c]!==t[c]&&l.has(c)})};(e==null?void 0:e.listeners)!==!1&&i()&&(n.listeners=!0),this.notify({...n,...e})}updateQuery(){const e=this.client.getQueryCache().build(this.client,this.options);if(e===this.currentQuery)return;const t=this.currentQuery;this.currentQuery=e,this.currentQueryInitialState=e.state,this.previousQueryResult=this.currentResult,this.hasListeners()&&(t==null||t.removeObserver(this),e.addObserver(this))}onQueryUpdate(e){const t={};e.type==="success"?t.onSuccess=!e.manual:e.type==="error"&&!z(e.error)&&(t.onError=!0),this.updateResult(t),this.hasListeners()&&this.updateTimers()}notify(e){N.batch(()=>{if(e.onSuccess){var t,s,n,i;(t=(s=this.options).onSuccess)==null||t.call(s,this.currentResult.data),(n=(i=this.options).onSettled)==null||n.call(i,this.currentResult.data,null)}else if(e.onError){var u,a,l,h;(u=(a=this.options).onError)==null||u.call(a,this.currentResult.error),(l=(h=this.options).onSettled)==null||l.call(h,void 0,this.currentResult.error)}e.listeners&&this.listeners.forEach(({listener:c})=>{c(this.currentResult)}),e.cache&&this.client.getQueryCache().notify({query:this.currentQuery,type:"observerResultsUpdated"})})}}function re(r,e){return e.enabled!==!1&&!r.state.dataUpdatedAt&&!(r.state.status==="error"&&e.retryOnMount===!1)}function k(r,e){return re(r,e)||r.state.dataUpdatedAt>0&&E(r,e,e.refetchOnMount)}function E(r,e,t){if(e.enabled!==!1){const s=typeof t=="function"?t(r):t;return s==="always"||s!==!1&&T(r,e)}return!1}function j(r,e,t,s){return t.enabled!==!1&&(r!==e||s.enabled===!1)&&(!t.suspense||r.state.status!=="error")&&T(r,t)}function T(r,e){return r.isStaleByTime(e.staleTime)}function ie(r,e,t){return t.keepPreviousData?!1:t.placeholderData!==void 0?e.isPlaceholderData:!S(r.getCurrentResult(),e)}function ne(r=""){var e;if(!((e=$())==null?void 0:e.proxy))throw new Error("vue-query hooks can only be used inside setup() function.");const s=Y(r),n=H(s);if(!n)throw new Error("No 'queryClient' found in Vue context, use 'VueQueryPlugin' to properly initialize the library.");return n}function ue(r,e,t={},s={}){var n;const i=P(()=>ae(e,t,s)),u=(n=i.value.queryClient)!=null?n:ne(i.value.queryClientKey),a=P(()=>{const d=u.defaultQueryOptions(i.value);return d._optimisticResults=u.isRestoring.value?"isRestoring":"optimistic",d}),l=new r(u,a.value),h=_(l.getCurrentResult());let c=()=>{};b(u.isRestoring,d=>{d||(c(),c=l.subscribe(R=>{x(h,R)}))},{immediate:!0}),b(a,()=>{l.setOptions(a.value),x(h,l.getCurrentResult())}),G(()=>{c()});const o=()=>new Promise((d,R)=>{let m=()=>{};const v=()=>{if(a.value.enabled!==!1){const f=l.getOptimisticResult(a.value);f.isStale?(m(),l.fetchOptimistic(a.value).then(d,R)):(m(),d(f))}};v(),m=b(a,v,{deep:!0})});return b(()=>h.error,d=>{if(h.isError&&!h.isFetching&&J(a.value.useErrorBoundary,[d,l.getCurrentQuery()]))throw d}),{...X(Z(h)),suspense:o}}function ae(r,e={},t={}){const s=C(r),n=C(e),i=C(t);let u=s;return ee(s)?typeof n=="function"?u={...i,queryKey:s,queryFn:n}:u={...n,queryKey:s}:u=s,te(u)}function ce(r,e,t){const s=ue(se,r,e,t);return{...s,refetch:s.refetch.value,remove:s.remove.value}}const le=3,q=30*1e3;async function oe(r,e){const t=r.startsWith("/")?r.slice(1):r;let s=`${window.DATA_HOST}${t}`;r.startsWith("http")&&(s=r),s.endsWith("/")&&(s=s.slice(0,-1));const n=await fetch(`${s}/config.json?t=${e??0}`),i=await fetch(`${s}/team.json?t=${e??0}`),u=await fetch(`${s}/run.json?t=${e??0}`),{status:a,statusText:l}=n;if(a>=300||a<200)throw new Error(`fetch data failed. [status=${a}] [statusText=${l}]`);return Promise.all([n.json(),i.json(),u.json()]).then(c=>({contest:c[0],teams:c[1],submissions:c[2]}))}function fe(r,e){return ce({queryKey:[r,e.value.getTime()],queryFn:()=>oe(r,e.value.getTime()),retry:le,staleTime:q,refetchInterval:q})}export{fe as u};
@@ -1 +1 @@
1
- import{aH as m,i as r,h as t}from"./index-7955279c.js";const l=m("user",()=>{const e=r(""),s=r(new Set),o=t(()=>Array.from(s.value)),u=t(()=>o.value.filter(a=>a!==e.value));function n(a){e.value&&s.value.add(e.value),e.value=a}return{setNewName:n,otherNames:u,savedName:e}});export{l as u};
1
+ import{aH as m,i as r,h as t}from"./index-f1d19db1.js";const l=m("user",()=>{const e=r(""),s=r(new Set),o=t(()=>Array.from(s.value)),u=t(()=>o.value.filter(a=>a!==e.value));function n(a){e.value&&s.value.add(e.value),e.value=a}return{setNewName:n,otherNames:u,savedName:e}});export{l as u};
@@ -1 +1 @@
1
- import{_ as u}from"./index-7955279c.js";function p(d={}){const{immediate:l=!1,onNeedRefresh:v,onOfflineReady:t,onRegistered:r,onRegisteredSW:o,onRegisterError:s}=d;let i,n;const c=async(a=!0)=>{await n};async function f(){if("serviceWorker"in navigator){const{Workbox:a}=await u(()=>import("./workbox-window.prod.es5-a7b12eab.js"),[],import.meta.url);i=new a("/sw.js",{scope:"/",type:"classic"}),i.addEventListener("activated",e=>{(e.isUpdate||e.isExternal)&&window.location.reload()}),i.addEventListener("installed",e=>{e.isUpdate||t==null||t()}),i.register({immediate:l}).then(e=>{o?o("/sw.js",e):r==null||r(e)}).catch(e=>{s==null||s(e)})}}return n=f(),c}export{p as registerSW};
1
+ import{_ as u}from"./index-f1d19db1.js";function p(d={}){const{immediate:l=!1,onNeedRefresh:v,onOfflineReady:t,onRegistered:r,onRegisteredSW:o,onRegisterError:s}=d;let i,n;const c=async(a=!0)=>{await n};async function f(){if("serviceWorker"in navigator){const{Workbox:a}=await u(()=>import("./workbox-window.prod.es5-a7b12eab.js"),[],import.meta.url);i=new a("/sw.js",{scope:"/",type:"classic"}),i.addEventListener("activated",e=>{(e.isUpdate||e.isExternal)&&window.location.reload()}),i.addEventListener("installed",e=>{e.isUpdate||t==null||t()}),i.register({immediate:l}).then(e=>{o?o("/sw.js",e):r==null||r(e)}).catch(e=>{s==null||s(e)})}}return n=f(),c}export{p as registerSW};
package/dist/index.html CHANGED
@@ -3,8 +3,8 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> -->
6
- <link rel="apple-touch-icon" href="https://cdn.jsdelivr.net/npm/@xcpcio/board-app@0.27.0/dist/balloon-192x192.png">
7
- <link rel="mask-icon" href="https://cdn.jsdelivr.net/npm/@xcpcio/board-app@0.27.0/dist/balloon-512x512.svg" color="#00aba9">
6
+ <link rel="apple-touch-icon" href="https://cdn.jsdelivr.net/npm/@xcpcio/board-app@0.29.0/dist/balloon-192x192.png">
7
+ <link rel="mask-icon" href="https://cdn.jsdelivr.net/npm/@xcpcio/board-app@0.29.0/dist/balloon-512x512.svg" color="#00aba9">
8
8
  <meta name="msapplication-TileColor" content="#00aba9">
9
9
  <script>
10
10
  function normalizePath(path) {
@@ -44,7 +44,7 @@
44
44
  }
45
45
  })();
46
46
  </script>
47
- <script type="module" crossorigin src="https://cdn.jsdelivr.net/npm/@xcpcio/board-app@0.27.0/dist/assets/index-7955279c.js"></script>
47
+ <script type="module" crossorigin src="https://cdn.jsdelivr.net/npm/@xcpcio/board-app@0.29.0/dist/assets/index-f1d19db1.js"></script>
48
48
  <link rel="manifest" href="/manifest.webmanifest"><style></style></head>
49
49
  <body class="font-sans">
50
50
  <div id="app"></div>
package/dist/sw.js CHANGED
@@ -1 +1 @@
1
- if(!self.define){let s,e={};const l=(l,r)=>(l=new URL(l+".js",r).href,e[l]||new Promise((e=>{if("document"in self){const s=document.createElement("script");s.src=l,s.onload=e,document.head.appendChild(s)}else s=l,importScripts(l),e()})).then((()=>{let s=e[l];if(!s)throw new Error(`Module ${l} didn’t register its module`);return s})));self.define=(r,n)=>{const i=s||("document"in self?document.currentScript.src:"")||location.href;if(e[i])return;let u={};const t=s=>l(s,i),a={module:{uri:i},exports:u,require:t};e[i]=Promise.all(r.map((s=>a[s]||t(s)))).then((s=>(n(...s),u)))}}define(["./workbox-b8d87ee1"],(function(s){"use strict";self.skipWaiting(),s.clientsClaim(),s.precacheAndRoute([{url:"assets/_...all_-bb67b33f.js",revision:null},{url:"assets/_name_-d0a3d653.js",revision:null},{url:"assets/about-8e4f6558.js",revision:null},{url:"assets/Board-88436e20.js",revision:null},{url:"assets/board-c38fef02.js",revision:null},{url:"assets/Board-f6dd53aa.css",revision:null},{url:"assets/board-layout-2f8b4c8e.js",revision:null},{url:"assets/DataSourceInput.vue_vue_type_script_setup_true_lang-effb1be0.js",revision:null},{url:"assets/en-644e039f.js",revision:null},{url:"assets/headless-04b3d2be.js",revision:null},{url:"assets/home-f7c22489.js",revision:null},{url:"assets/index-522cf95a.css",revision:null},{url:"assets/index-7955279c.js",revision:null},{url:"assets/index-e972e718.js",revision:null},{url:"assets/index-layout-f3e9e819.js",revision:null},{url:"assets/test-94bf1ee1.js",revision:null},{url:"assets/TheInput.vue_vue_type_script_setup_true_lang-2b1997a6.js",revision:null},{url:"assets/useQueryBoardData-78fadedd.js",revision:null},{url:"assets/user-c31467e6.js",revision:null},{url:"assets/virtual_pwa-register-d035b16b.js",revision:null},{url:"assets/workbox-window.prod.es5-a7b12eab.js",revision:null},{url:"assets/zh-CN-44b801f0.js",revision:null},{url:"index.html",revision:"d6c322c4d573a247a7102037db2cd17c"},{url:"favicon.svg",revision:"5a744f4ccbb122d4a0575be779ddcd43"},{url:"safari-pinned-tab.svg",revision:"5eaf74d1c43d30e0af743b68a3f48504"},{url:"balloon2-192x192.png",revision:"c857ae6d9dfae118ab4397d4358422bd"},{url:"balloon2-512x512.png",revision:"065594f4f743fe3884793c03d3fe7d9e"},{url:"manifest.webmanifest",revision:"3082e8d8ebc9619c6c1055ff243a02a8"}],{}),s.cleanupOutdatedCaches(),s.registerRoute(new s.NavigationRoute(s.createHandlerBoundToURL("index.html")))}));
1
+ if(!self.define){let s,e={};const l=(l,r)=>(l=new URL(l+".js",r).href,e[l]||new Promise((e=>{if("document"in self){const s=document.createElement("script");s.src=l,s.onload=e,document.head.appendChild(s)}else s=l,importScripts(l),e()})).then((()=>{let s=e[l];if(!s)throw new Error(`Module ${l} didn’t register its module`);return s})));self.define=(r,n)=>{const i=s||("document"in self?document.currentScript.src:"")||location.href;if(e[i])return;let u={};const a=s=>l(s,i),t={module:{uri:i},exports:u,require:a};e[i]=Promise.all(r.map((s=>t[s]||a(s)))).then((s=>(n(...s),u)))}}define(["./workbox-b8d87ee1"],(function(s){"use strict";self.skipWaiting(),s.clientsClaim(),s.precacheAndRoute([{url:"assets/_...all_-d54370e4.js",revision:null},{url:"assets/_name_-c7264d89.js",revision:null},{url:"assets/about-55b7ba92.js",revision:null},{url:"assets/Board-2cad79eb.css",revision:null},{url:"assets/board-88a98e6a.js",revision:null},{url:"assets/Board-9442407d.js",revision:null},{url:"assets/board-layout-e4e0bae6.js",revision:null},{url:"assets/DataSourceInput.vue_vue_type_script_setup_true_lang-d16f2a12.js",revision:null},{url:"assets/en-644e039f.js",revision:null},{url:"assets/headless-3466779c.js",revision:null},{url:"assets/home-37e85146.js",revision:null},{url:"assets/index-a0a089d2.css",revision:null},{url:"assets/index-bc173751.js",revision:null},{url:"assets/index-f1d19db1.js",revision:null},{url:"assets/index-layout-c91f7cfd.js",revision:null},{url:"assets/test-133c6df2.js",revision:null},{url:"assets/TheInput.vue_vue_type_script_setup_true_lang-1dafe5cb.js",revision:null},{url:"assets/useQueryBoardData-c0567554.js",revision:null},{url:"assets/user-6ae7ff90.js",revision:null},{url:"assets/virtual_pwa-register-7ea4486e.js",revision:null},{url:"assets/workbox-window.prod.es5-a7b12eab.js",revision:null},{url:"assets/zh-CN-44b801f0.js",revision:null},{url:"index.html",revision:"b06a5a5b7720b252ecb2476c728cea7c"},{url:"favicon.svg",revision:"5a744f4ccbb122d4a0575be779ddcd43"},{url:"safari-pinned-tab.svg",revision:"5eaf74d1c43d30e0af743b68a3f48504"},{url:"balloon2-192x192.png",revision:"c857ae6d9dfae118ab4397d4358422bd"},{url:"balloon2-512x512.png",revision:"065594f4f743fe3884793c03d3fe7d9e"},{url:"manifest.webmanifest",revision:"3082e8d8ebc9619c6c1055ff243a02a8"}],{}),s.cleanupOutdatedCaches(),s.registerRoute(new s.NavigationRoute(s.createHandlerBoundToURL("index.html")))}));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xcpcio/board-app",
3
3
  "type": "module",
4
- "version": "0.27.0",
4
+ "version": "0.29.0",
5
5
  "description": "XCPCIO Board App",
6
6
  "author": "Dup4 <lyuzhi.pan@gmail.com>",
7
7
  "license": "MIT",
@@ -53,8 +53,8 @@
53
53
  "vue-router": "^4.2.4",
54
54
  "vue-search-select": "^3.1.2",
55
55
  "vue-toast-notification": "^3",
56
- "@xcpcio/core": "0.27.0",
57
- "@xcpcio/types": "0.27.0"
56
+ "@xcpcio/core": "0.29.0",
57
+ "@xcpcio/types": "0.29.0"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@antfu/eslint-config": "^0.39.8",
@@ -0,0 +1,57 @@
1
+ <script setup lang="ts">
2
+ import type { Problem, Rank } from "@xcpcio/core";
3
+
4
+ const props = defineProps<{
5
+ rank: Rank,
6
+ problem: Problem
7
+ }>();
8
+
9
+ const hiddenModal = ref(true);
10
+ function onClick() {
11
+ hiddenModal.value = false;
12
+ }
13
+
14
+ const rank = computed(() => props.rank);
15
+ const problem = computed(() => props.problem);
16
+ </script>
17
+
18
+ <template>
19
+ <th
20
+ :key="problem.id"
21
+ class="success"
22
+ text-center
23
+ style="width: 3rem;"
24
+ :style="{
25
+ 'background-color': problem.balloonColor?.background_color,
26
+ 'color': problem.balloonColor?.color,
27
+ }"
28
+ >
29
+ <div
30
+ cursor-pointer
31
+ flex
32
+ flex-col justify-center
33
+ items-center
34
+ @click="onClick"
35
+ >
36
+ <div>
37
+ {{ problem.label }}
38
+ </div>
39
+ <div>
40
+ {{ problem.statistics.acceptedNum }}
41
+ </div>
42
+ </div>
43
+
44
+ <div>
45
+ <ProblemInfoModal
46
+ v-if="!hiddenModal"
47
+ v-model:is-hidden="hiddenModal"
48
+ :rank="rank"
49
+ :problem="problem"
50
+ />
51
+ </div>
52
+ </th>
53
+ </template>
54
+
55
+ <style scoped lang="less">
56
+ @import "./Standings.less";
57
+ </style>
@@ -0,0 +1,111 @@
1
+ <script setup lang="ts">
2
+ import type { Problem, Rank } from "@xcpcio/core";
3
+
4
+ const props = defineProps<{
5
+ isHidden: boolean,
6
+
7
+ rank: Rank,
8
+ problem: Problem
9
+ }>();
10
+
11
+ const emit = defineEmits(["update:isHidden"]);
12
+
13
+ const isHidden = computed({
14
+ get() {
15
+ return props.isHidden;
16
+ },
17
+ set(value) {
18
+ emit("update:isHidden", value);
19
+ },
20
+ });
21
+
22
+ const currentType = ref("submissions");
23
+
24
+ const rank = computed(() => props.rank);
25
+ const problem = computed(() => props.problem);
26
+
27
+ const headerTitle = computed(() => {
28
+ return `Problem ${problem.value.label}`;
29
+ });
30
+
31
+ const submissions = computed(() => {
32
+ return rank.value.getSubmissions().filter(s => s.problemId === problem.value.id);
33
+ });
34
+
35
+ const TYPE_SUBMISSIONS = "submissions";
36
+ const TYPE_STATISTICS = "statistics";
37
+ const TYPE_AWARDS = "awards";
38
+ const types = [TYPE_SUBMISSIONS, TYPE_STATISTICS, TYPE_AWARDS];
39
+ </script>
40
+
41
+ <template>
42
+ <Modal
43
+ v-model:isHidden="isHidden"
44
+ >
45
+ <template #header>
46
+ <div
47
+ w-full max-w-screen-xl
48
+ px-4 mx-auto lg:px-12
49
+ >
50
+ <div
51
+ relative overflow-hidden
52
+ bg-white dark:bg-gray-800
53
+ >
54
+ <div
55
+ flex flex-col items-center justify-between
56
+ md:flex-row
57
+ space-y-3 md:space-y-0
58
+ >
59
+ <div
60
+ flex flex-row
61
+ space-x-3
62
+ >
63
+ <h3
64
+ text-gray-900 dark:text-white
65
+ text-2xl
66
+ font-sans font-semibold italic
67
+ >
68
+ {{ headerTitle }}
69
+ </h3>
70
+ </div>
71
+
72
+ <ModalMenu
73
+ v-model:current-type="currentType"
74
+ :types="types"
75
+ />
76
+ </div>
77
+ </div>
78
+ </div>
79
+ </template>
80
+
81
+ <div
82
+ w-full
83
+ font-bold font-mono
84
+ flex items-center justify-center
85
+ >
86
+ <div
87
+ v-if="currentType === TYPE_SUBMISSIONS"
88
+ w-full
89
+ class="mt-[-12px]"
90
+ >
91
+ <SubmissionsTable
92
+ w-full
93
+ :rank="rank"
94
+ :submissions="submissions"
95
+ :page-size="8"
96
+ :remove-border="true"
97
+ />
98
+ </div>
99
+
100
+ <div
101
+ v-if="currentType === TYPE_STATISTICS"
102
+ w-full
103
+ />
104
+
105
+ <div
106
+ v-if="currentType === TYPE_AWARDS"
107
+ w-full
108
+ />
109
+ </div>
110
+ </Modal>
111
+ </template>
@@ -96,21 +96,15 @@ const maxTeamLength = computed(() => {
96
96
  >
97
97
  {{ t("standings.penalty") }}
98
98
  </th>
99
- <th
99
+ <template
100
100
  v-for="p in rank.contest.problems"
101
- :key="p.id"
102
- class="success"
103
- text-center
104
- style="width: 3rem;"
105
- :style="{
106
- 'background-color': p.balloonColor?.background_color,
107
- 'color': p.balloonColor?.color,
108
- }"
101
+ :key="`problem-block-${p.id}`"
109
102
  >
110
- {{ p.label }}
111
- <br>
112
- <s>{{ p.statistics.acceptedNum }}</s>
113
- </th>
103
+ <ProblemBlock
104
+ :rank="rank"
105
+ :problem="p"
106
+ />
107
+ </template>
114
108
  <th class="title" style="width: 2.5rem;">
115
109
  {{ t("standings.dirt") }}
116
110
  </th>
@@ -38,18 +38,6 @@ const currentSubmissions = computed(() => {
38
38
 
39
39
  const notShowing = ref(false);
40
40
 
41
- function getSubmitTime(
42
- timeDiff: number,
43
- ): string {
44
- const h = Math.floor(timeDiff / 3600);
45
- const m = Math.floor(timeDiff % 3600 / 60);
46
- const s = timeDiff % 60;
47
-
48
- const f = (x: number) => x.toString().padStart(2, "0");
49
-
50
- return `${f(h)}:${f(m)}:${f(s)}`;
51
- }
52
-
53
41
  function getProblemLabelColorClass(s: Submission) {
54
42
  const defaultClass = "bg-primary-100 text-primary-800 dark:bg-primary-900 dark:text-primary-300";
55
43
 
@@ -192,7 +180,7 @@ function getProblemLabelColorStyle(s: Submission) {
192
180
  Status
193
181
  </th>
194
182
  <th
195
- v-if="notShowing"
183
+ v-if="rank.contest.options.submissionHasTimeField"
196
184
  scope="col"
197
185
  class="px-4 py-3"
198
186
  >
@@ -206,7 +194,7 @@ function getProblemLabelColorStyle(s: Submission) {
206
194
  Memory
207
195
  </th>
208
196
  <th
209
- v-if="notShowing"
197
+ v-if="rank.contest.options.submissionHasLanguageField"
210
198
  scope="col"
211
199
  class="px-4 py-3"
212
200
  >
@@ -263,12 +251,11 @@ function getProblemLabelColorStyle(s: Submission) {
263
251
  </td>
264
252
 
265
253
  <td
266
- v-if="notShowing"
254
+ v-if="rank.contest.options.submissionHasTimeField"
267
255
  class="whitespace-nowrap px-4 py-2 text-gray-900 dark:text-white"
268
256
  >
269
- <div class="flex items-center">
270
- <div class="mr-2 inline-block h-4 w-4 rounded-full bg-red-700" />
271
- 95
257
+ <div flex items-center>
258
+ {{ `${s.time ?? 0} ms` }}
272
259
  </div>
273
260
  </td>
274
261
 
@@ -280,17 +267,22 @@ function getProblemLabelColorStyle(s: Submission) {
280
267
  </td>
281
268
 
282
269
  <td
283
- v-if="notShowing"
270
+ v-if="rank.contest.options.submissionHasLanguageField"
284
271
  class="whitespace-nowrap px-4 py-2 text-gray-900 dark:text-white"
285
272
  >
286
- <div class="flex items-center">
287
- <span class="ml-1 text-gray-500 dark:text-gray-400">5.0</span>
273
+ <div flex items-center>
274
+ {{ s.language }}
288
275
  </div>
289
276
  </td>
290
277
 
291
278
  <td class="whitespace-nowrap px-4 py-2 text-gray-900 dark:text-white">
292
- <div class="flex items-center">
293
- {{ getSubmitTime(s.timestamp) }}
279
+ <div flex items-center>
280
+ <Tooltip>
281
+ {{ s.timestampDisplayFormatWithSecond }}
282
+ <template #popper>
283
+ {{ s.timestampDisplayFormatWithMilliSecond }}
284
+ </template>
285
+ </Tooltip>
294
286
  </div>
295
287
  </td>
296
288
  </tr>
@@ -5,7 +5,7 @@ import type { TooltipInterface, TooltipOptions } from "flowbite";
5
5
  import "./Tooltip.css";
6
6
 
7
7
  const props = defineProps<{
8
- placement?: "left" | "right" | "top" | "bottom",
8
+ placement?: "left" | "right" | "top" | "bottom" | "auto",
9
9
  }>();
10
10
 
11
11
  const tooltipTargetEl = ref(null);
@@ -15,7 +15,7 @@ const tooltipTriggerEl = ref(null);
15
15
  let tooltip: TooltipInterface | null = null;
16
16
 
17
17
  const placement = computed(() => {
18
- return props.placement ?? "top";
18
+ return props.placement ?? "auto";
19
19
  });
20
20
 
21
21
  onMounted(() => {
@@ -26,6 +26,8 @@ declare module 'vue' {
26
26
  ModalMenu: typeof import('./components/board/ModalMenu.vue')['default']
27
27
  NavBar: typeof import('./components/NavBar.vue')['default']
28
28
  OptionsModal: typeof import('./components/board/OptionsModal.vue')['default']
29
+ ProblemBlock: typeof import('./components/board/ProblemBlock.vue')['default']
30
+ ProblemInfoModal: typeof import('./components/board/ProblemInfoModal.vue')['default']
29
31
  Progress: typeof import('./components/board/Progress.vue')['default']
30
32
  RightArrowIcon: typeof import('./components/icon/RightArrowIcon.vue')['default']
31
33
  RouterLink: typeof import('vue-router')['RouterLink']
@@ -119,7 +119,7 @@ export function getProblemChart(rank: Rank) {
119
119
  return { cat, series, colors };
120
120
  })();
121
121
 
122
- return getChartObj("题目通过数统计", "题目编号", "通过数", cat, series, colors);
122
+ return getChartObj("题目通过数", "题目编号", "通过数", cat, series, colors);
123
123
  }
124
124
 
125
125
  export function getTeamChart(rank: Rank) {
@@ -151,7 +151,7 @@ export function getTeamChart(rank: Rank) {
151
151
  return { cat, series, colors };
152
152
  })();
153
153
 
154
- return getChartObj("队伍过题数统计", "过题数", "队伍数", cat, series, colors);
154
+ return getChartObj("队伍过题数", "过题数", "队伍数", cat, series, colors);
155
155
  }
156
156
 
157
157
  export function getSubmitChart(rank: Rank) {
@@ -190,7 +190,7 @@ export function getSubmitChart(rank: Rank) {
190
190
  return { cat, series, colors };
191
191
  })();
192
192
 
193
- return getChartObj("提交分类统计", "题目编号", "提交数", cat, series, colors);
193
+ return getChartObj("提交分类", "题目编号", "提交数", cat, series, colors);
194
194
  }
195
195
 
196
196
  export function getTeamPlaceChart(_rank: Rank, team: Team) {
@@ -26,6 +26,11 @@ async function fetcher(target: string, timestamp?: number): Promise<BoardData> {
26
26
  const teamsResp = await fetch(`${prefix}/team.json?t=${timestamp ?? 0}`);
27
27
  const submissionsResp = await fetch(`${prefix}/run.json?t=${timestamp ?? 0}`);
28
28
 
29
+ const { status, statusText } = contestResp;
30
+ if (status >= 300 || status < 200) {
31
+ throw new Error(`fetch data failed. [status=${status}] [statusText=${statusText}]`);
32
+ }
33
+
29
34
  const p = Promise.all([
30
35
  contestResp.json(),
31
36
  teamsResp.json(),