@algoux/standard-ranklist-renderer-component-core 0.5.1 → 0.6.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/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var J=require("color"),s=require("@algoux/standard-ranklist-utils"),V=require("semver");function B(e){return e&&typeof e=="object"&&"default"in e?e:{default:e}}var O=B(J),Z=B(V);const N={[s.EnumTheme.light]:"#ffffff",[s.EnumTheme.dark]:"#191919"};function G(e,t,o){if(typeof o=="function")return o(e,t);if(e.startsWith("//"))return e;const n=e.match(/^([a-zA-Z][a-zA-Z0-9+.-]*):/);if(n){const r=n[1].toLowerCase();return r==="http"||r==="https"||r==="data"?e:(console.warn(`unsupported protocol "${r}" in srk asset url:`,e),"")}return console.warn("unsupported srk asset url:",e),""}function Q(e,t){const{backgroundColor:o}=s.resolveStyle(e||{}),n=o[t]||N[t],r=O.default(n).string(),i=O.default(n).alpha(.27).string();return`linear-gradient(180deg, ${r} 0%, ${r} 10%, ${i} 10%, transparent 100%)`}function ee(e,t){return typeof e.style=="string"?{className:`srk-preset-marker-${e.style}`}:e.style?{style:{backgroundColor:s.resolveStyle(e.style).backgroundColor[t]}}:{}}function te(e){switch(e){case"FB":return{label:"First Blood",className:"srk-preset-result-fb"};case"AC":return{label:"Accepted",className:"srk-preset-result-ac"};case"RJ":return{label:"Rejected",className:"srk-preset-result-rj"};case"?":return{label:"Frozen",className:"srk-preset-result-fz"};case"WA":return{label:"Wrong Answer",className:"srk-preset-result-rj"};case"PE":return{label:"Presentation Error",className:"srk-preset-result-rj"};case"TLE":return{label:"Time Limit Exceeded",className:"srk-preset-result-rj"};case"MLE":return{label:"Memory Limit Exceeded",className:"srk-preset-result-rj"};case"OLE":return{label:"Output Limit Exceeded",className:"srk-preset-result-rj"};case"RTE":return{label:"Runtime Error",className:"srk-preset-result-rj"};case"NOUT":return{label:"No Output"};case"CE":return{label:"Compile Error"};case"UKE":return{label:"Unknown Error"};case null:return{label:"--"};default:return{label:e}}}function oe(e){return`${e.tries}/${e.time?s.formatTimeDuration(e.time,"min",Math.floor):"-"}`}function ne(e,t){return`Solutions of ${s.numberToAlphabet(e)} (${s.resolveText(t.name)})`}function re(e){return s.secToTimeStr(s.formatTimeDuration(e.time,"s"))}function se(e){return e.some(t=>{var o;return Boolean((o=t.score)==null?void 0:o.time)})}function F(e){return s.formatTimeDuration(e.duration,"min")}function ie(e,t,o=0){const n=new Date(e.startAt).getTime(),r=t-o;return Math.min(Math.max(Math.floor((r-n)/6e4),0),F(e))}function le(e,t,o=0){const r=new Date(e.startAt).getTime()+s.formatTimeDuration(e.duration,"ms");return t-o>=r}function ae(e){const t={};for(let o=0;o<=e;++o)t[o]="";return t}function ue(e,t,o,n,r){const{contest:i}=e,u=new Date(i.startAt).getTime(),g=u+s.formatTimeDuration(i.duration,"ms"),L=i.frozenDuration?s.formatTimeDuration(i.frozenDuration,"ms"):0,R=t-o,c=g-u,f=c?1-L/c:1,h=Math.min(Math.max(R-u,0),c),X=c-h,K=g-L,U=c?h/c*100:0,I=c?Math.max(Math.min(R,K)-u,0)/c*100:0,W=Math.min(100,f?I/f:0),H=U-I,q=Math.min(100,1-f?H/(1-f):0),M=n*60*1e3,D=c-M;return{elapsed:r?M:h,remaining:r?D:X,frozenBreakpoint:f,normalInnerPercent:W,frozenInnerPercent:q,timeTravelElapsed:M,timeTravelRemaining:D,supportRegen:s.canRegenerateRanklist(e)}}const j=">=0.3.0 <=0.3.12";function ce(e){return Z.default.satisfies(e,j)}const de=280,fe="srk-animated-modal-root",b="srk-scrolling-effect";let m=null,a=null,_=!1,d=0,S="",v="",w="",k="",A="",x="",P="",E="",p=0,y=0,T=1,l=[],C=!1;function me(e){var o,n;if(e.key!=="Escape")return;const t=l[l.length-1];!t||((o=t.onEscape)==null||o.call(t,e),(n=e.stopImmediatePropagation)==null||n.call(e),e.stopPropagation())}function ge(){typeof document=="undefined"||C||(document.addEventListener("keydown",me),C=!0)}function pe(){typeof document=="undefined"||_||(document.addEventListener("mousedown",e=>{a={x:e.clientX,y:e.clientY}},!0),document.addEventListener("touchstart",e=>{const t=e.touches[0]||e.changedTouches[0];!t||(a={x:t.clientX,y:t.clientY})},{capture:!0,passive:!0}),_=!0)}function Y(e,t,o){m={x:e,y:t,timestamp:Date.now(),source:o==null?void 0:o.source,context:o==null?void 0:o.context}}function ye(e,t){Y(e.clientX,e.clientY,t)}function z(e=500){return!m||Date.now()-m.timestamp>e?null:m}function be(){return a}function he(e){if(typeof window=="undefined"||!e)return{origin:{x:0,y:0},source:"fallback",explicitTriggerPoint:null,globalInteractionPoint:a,dialogRect:null,fallbackPoint:{x:0,y:0}};const t=e.getBoundingClientRect(),o={x:t.width/2,y:Math.min(t.height*.22,96)},n=z();return n?{origin:{x:n.x-t.left,y:n.y-t.top},source:"explicit-trigger",explicitTriggerPoint:n,globalInteractionPoint:a,dialogRect:{left:t.left,top:t.top,width:t.width,height:t.height},fallbackPoint:o}:a?{origin:{x:a.x-t.left,y:a.y-t.top},source:"global-pointer",explicitTriggerPoint:null,globalInteractionPoint:a,dialogRect:{left:t.left,top:t.top,width:t.width,height:t.height},fallbackPoint:o}:{origin:o,source:"fallback",explicitTriggerPoint:null,globalInteractionPoint:null,dialogRect:{left:t.left,top:t.top,width:t.width,height:t.height},fallbackPoint:o}}function Me(){return typeof document=="undefined"?null:document.activeElement instanceof HTMLElement?document.activeElement:null}function $(e){try{e.focus({preventScroll:!0})}catch{e.focus()}}function Te(e,t={}){if(typeof document=="undefined"||!e)return null;ge();const o=l.find(u=>u.dialogElement===e);if(o)return o.onEscape=t.onEscape,o.id;const n=e.hasAttribute("tabindex"),r=e.getAttribute("tabindex");n||e.setAttribute("tabindex","-1");const i={id:T,dialogElement:e,restoreElement:Me(),hadTabIndex:n,previousTabIndex:r,onEscape:t.onEscape};return T+=1,l.push(i),$(e),i.id}function Se(e){var u;if(typeof document=="undefined"||e==null)return;const t=l.findIndex(g=>g.id===e);if(t===-1)return;const[o]=l.splice(t,1);if(o.hadTabIndex?o.previousTabIndex===null?o.dialogElement.removeAttribute("tabindex"):o.dialogElement.setAttribute("tabindex",o.previousTabIndex):o.dialogElement.removeAttribute("tabindex"),!(t===l.length))return;const r=l[l.length-1],i=(u=o.restoreElement)!=null&&u.isConnected?o.restoreElement:r==null?void 0:r.dialogElement;i&&$(i)}function ve(e){var t;return e==null?!1:((t=l[l.length-1])==null?void 0:t.id)===e}function we(){typeof document!="undefined"&&(d===0&&(p=window.scrollX,y=window.scrollY,S=document.body.style.overflow,v=document.body.style.overflowX,w=document.body.style.overflowY,k=document.body.style.position,A=document.body.style.top,x=document.body.style.left,P=document.body.style.right,E=document.body.style.width,document.body.classList.add(b),document.body.style.overflow="hidden",document.body.style.overflowX="hidden",document.body.style.overflowY="hidden",document.body.style.position="fixed",document.body.style.top=`-${y}px`,document.body.style.left=`-${p}px`,document.body.style.right="0",document.body.style.width="100%"),d+=1)}function ke(){if(!(typeof document=="undefined"||d===0)&&(d-=1,d===0&&(document.body.classList.remove(b),document.body.style.overflow=S,document.body.style.overflowX=v,document.body.style.overflowY=w,document.body.style.position=k,document.body.style.top=A,document.body.style.left=x,document.body.style.right=P,document.body.style.width=E,!(typeof navigator!="undefined"&&/jsdom/i.test(navigator.userAgent))&&typeof window.scrollTo=="function")))try{window.scrollTo(p,y)}catch{}}function Ae(){m=null,a=null,d=0,T=1,l=[],S="",v="",w="",k="",A="",x="",P="",E="",p=0,y=0,typeof document!="undefined"&&(document.body.classList.remove(b),document.body.style.overflow="",document.body.style.overflowX="",document.body.style.overflowY="",document.body.style.position="",document.body.style.top="",document.body.style.left="",document.body.style.right="",document.body.style.width="")}Object.defineProperty(exports,"convertToStaticRanklist",{enumerable:!0,get:function(){return s.convertToStaticRanklist}});exports.MODAL_ANIMATION_DURATION_MS=de;exports.SRK_ANIMATED_MODAL_ROOT_CLASS=fe;exports.SRK_SCROLL_LOCK_BODY_CLASS=b;exports.buildSliderMarks=ae;exports.caniuse=ce;exports.captureModalTriggerPointFromMouseEvent=ye;exports.defaultBackgroundColor=N;exports.ensureModalInteractionTracker=pe;exports.formatSolutionTimestamp=re;exports.getAcceptedStatusDetails=oe;exports.getLastModalInteractionPoint=be;exports.getMarkerPresentation=ee;exports.getProblemHeaderBackgroundImage=Q;exports.getProgressDurationMinutes=F;exports.getProgressMaxAvailableMinutes=ie;exports.getProgressMetrics=ue;exports.getRecentModalTriggerPoint=z;exports.getSolutionModalTitle=ne;exports.getSolutionResultMeta=te;exports.isProgressEnded=le;exports.isTopModalFocusScope=ve;exports.lockModalBodyScroll=we;exports.registerModalFocusScope=Te;exports.resetModalInteractionStateForTests=Ae;exports.resolveModalTransformOrigin=he;exports.resolveSrkAssetUrl=G;exports.setModalTriggerPoint=Y;exports.shouldShowTimeColumn=se;exports.srkSupportedVersions=j;exports.unlockModalBodyScroll=ke;exports.unregisterModalFocusScope=Se;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var le=require("color"),c=require("@algoux/standard-ranklist-utils"),ce=require("semver");function z(e){return e&&typeof e=="object"&&"default"in e?e:{default:e}}var B=z(le),se=z(ce);const U={[c.EnumTheme.light]:"#ffffff",[c.EnumTheme.dark]:"#191919"},ae=["FB","AC","?","NOUT","CE","UKE",null];function ue(e,t,r){if(typeof r=="function")return r(e,t);if(e.startsWith("//"))return e;const o=e.match(/^([a-zA-Z][a-zA-Z0-9+.-]*):/);if(o){const n=o[1].toLowerCase();return n==="http"||n==="https"||n==="data"?e:(console.warn(`unsupported protocol "${n}" in srk asset url:`,e),"")}return console.warn("unsupported srk asset url:",e),""}function de(e,t,r=180){const{backgroundColor:o}=c.resolveStyle(e||{}),n=o[t]||U[t],i=B.default(n).string(),l=B.default(n).alpha(.27).string();return`linear-gradient(${r}deg, ${i} 0%, ${i} 10%, ${l} 10%, transparent 100%)`}function fe(e,t){return typeof e.style=="string"?{className:`srk-preset-marker-${e.style}`}:e.style?{style:{backgroundColor:c.resolveStyle(e.style).backgroundColor[t]}}:{}}function me(e){switch(e){case"FB":return{label:"First Blood",className:"srk-preset-result-fb"};case"AC":return{label:"Accepted",className:"srk-preset-result-ac"};case"RJ":return{label:"Rejected",className:"srk-preset-result-rj"};case"?":return{label:"Frozen",className:"srk-preset-result-fz"};case"WA":return{label:"Wrong Answer",className:"srk-preset-result-rj"};case"PE":return{label:"Presentation Error",className:"srk-preset-result-rj"};case"TLE":return{label:"Time Limit Exceeded",className:"srk-preset-result-rj"};case"MLE":return{label:"Memory Limit Exceeded",className:"srk-preset-result-rj"};case"OLE":return{label:"Output Limit Exceeded",className:"srk-preset-result-rj"};case"RTE":return{label:"Runtime Error",className:"srk-preset-result-rj"};case"NOUT":return{label:"No Output"};case"CE":return{label:"Compile Error"};case"UKE":return{label:"Unknown Error"};case null:return{label:"--"};default:return{label:e}}}function X(e){return`${e.tries}/${e.time?c.formatTimeDuration(e.time,"min",Math.floor):"-"}`}function g(e){return(e==null?void 0:e.result)==="AC"||(e==null?void 0:e.result)==="FB"}function K(e){return(e==null?void 0:e.result)==="RJ"||(e==null?void 0:e.result)==="?"}function v(e){return(e==null?void 0:e.tries)||0}function H(e,t){const r=ke(t),o=e.solutions||[];for(let n=o.length-1;n>=0;n-=1){const i=o[n];if(!r.includes(i.result))return i}}function f(e,t){if(!e)return"-";const r=we(e,t);if(r==="ms"){const n=Math.floor(c.formatTimeDuration(e,"ms")),i=Math.floor(n/1e3);return`${F(i)}.${b(n%1e3,3)}`}if(r==="s")return F(Math.floor(c.formatTimeDuration(e,"s")));const o=Math.floor(c.formatTimeDuration(e,"min"));return`${Math.floor(o/60)}:${b(o%60,2)}`}function ge(e,t,r="classic"){if(!e.result)return{};if(r==="classic"){if(g(e)){const o=X(e);return typeof e.score=="number"?{score:e.score,scoreDetails:o}:{primary:o}}return{primary:typeof e.tries=="number"?String(e.tries):""}}if(g(e)){const o=Math.max((e.tries||0)-1,0);if(r==="detailed")return{primary:f(e.time,t),secondary:o>0?`(-${o})`:""};const n=o>0?`+${o}`:"+";return r==="compact"?{primary:n,secondary:f(e.time,t)}:{primary:n}}if(K(e)){const o=e.tries||0,n=`-${o}`;if(r==="detailed")return{primary:"",secondary:o>0?`(-${o})`:""};if(r==="compact"&&o>0){const i=H(e,t);if(i)return{primary:n,secondary:f(i.time,t)}}return{primary:n}}return{}}function pe(e){const t=e.statuses.reduce((r,o)=>{if(!g(o))return r;const n=v(o);return{wrong:r.wrong+Math.max(n-1,0),submitted:r.submitted+n}},{wrong:0,submitted:0});return!t.submitted||!t.wrong?"0%":`${Math.floor(t.wrong/t.submitted*100)}%`}function ye(e){const t=e.rows.length;return e.problems.map((r,o)=>{const n={participantCount:t,accepted:0,tried:0,submitted:0,dirt:0,dirtSubmitted:0};return e.rows.forEach(i=>{const l=i.statuses[o],u=v(l);u>0&&(n.tried+=1,n.submitted+=u),g(l)&&(n.accepted+=1,n.dirt+=Math.max(u-1,0),n.dirtSubmitted+=u,l.time&&((!n.firstAcceptedTime||N(l.time,n.firstAcceptedTime)<0)&&(n.firstAcceptedTime=l.time),(!n.lastAcceptedTime||N(l.time,n.lastAcceptedTime)>0)&&(n.lastAcceptedTime=l.time)))}),n})}function be(e,t){return!e.firstAcceptedTime||!e.lastAcceptedTime?"-":`${f(e.firstAcceptedTime,t)} / ${f(e.lastAcceptedTime,t)}`}function he(e){return e?String(Math.floor(c.formatTimeDuration(e,"min"))):"-"}function Te(e,t){return t<=0?"(-)":`(${Math.floor(e/t*100)}%)`}function Me(e){const t=V(e);return t===void 0?"-":W(t)}function Se(e,t){const r=e.statuses.reduce((o,n,i)=>{if(!g(n))return o;const l=V(t[i]);return l!==void 0&&o.push(l),o},[]);return r.length?W(r.reduce((o,n)=>o+n,0)/r.length):"0.00"}function Pe(e,t){return`Solutions of ${c.numberToAlphabet(e)} (${c.resolveText(t.name)})`}function Ae(e){return c.secToTimeStr(c.formatTimeDuration(e.time,"s"))}function ve(e){return e.some(t=>{var r;return Boolean((r=t.score)==null?void 0:r.time)})}function we(e,t){const r=t.sorter;return(r==null?void 0:r.algorithm)==="ICPC"&&r.config.timePrecision?r.config.timePrecision:e[1]}function ke(e){const t=e.sorter;return(t==null?void 0:t.algorithm)==="ICPC"&&t.config.noPenaltyResults?t.config.noPenaltyResults:ae}function V(e){if(!(!e||e.participantCount<=0))return(e.participantCount-e.accepted)/e.participantCount}function W(e){return e.toFixed(2)}function N(e,t){return c.formatTimeDuration(e,"ms")-c.formatTimeDuration(t,"ms")}function F(e){const t=Math.floor(e/3600),r=Math.floor(e%3600/60),o=e%60;return`${t}:${b(r,2)}:${b(o,2)}`}function b(e,t){const r=String(Math.trunc(Math.abs(e)));return r.length>=t?r:`${"0".repeat(t-r.length)}${r}`}function J(e){return c.formatTimeDuration(e.duration,"min")}function Re(e,t,r=0){const o=new Date(e.startAt).getTime(),n=t-r;return Math.min(Math.max(Math.floor((n-o)/6e4),0),J(e))}function xe(e,t,r=0){const n=new Date(e.startAt).getTime()+c.formatTimeDuration(e.duration,"ms");return t-r>=n}function Ee(e){const t={};for(let r=0;r<=e;++r)t[r]="";return t}function Ce(e,t,r,o,n){const{contest:i}=e,l=new Date(i.startAt).getTime(),u=l+c.formatTimeDuration(i.duration,"ms"),I=i.frozenDuration?c.formatTimeDuration(i.frozenDuration,"ms"):0,O=t-r,d=u-l,p=d?1-I/d:1,S=Math.min(Math.max(O-l,0),d),ee=d-S,te=u-I,re=d?S/d*100:0,_=d?Math.max(Math.min(O,te)-l,0)/d*100:0,oe=Math.min(100,p?_/p:0),ne=re-_,ie=Math.min(100,1-p?ne/(1-p):0),P=o*60*1e3,$=d-P;return{elapsed:n?P:S,remaining:n?$:ee,frozenBreakpoint:p,normalInnerPercent:oe,frozenInnerPercent:ie,timeTravelElapsed:P,timeTravelRemaining:$,supportRegen:c.canRegenerateRanklist(e)}}const q=">=0.3.0 <=0.3.12";function De(e){return se.default.satisfies(e,q)}const Le=280,Ie="srk-animated-modal-root",M="srk-scrolling-effect";let y=null,a=null,j=!1,m=0,w="",k="",R="",x="",E="",C="",D="",L="",h=0,T=0,A=1,s=[],Y=!1;function Oe(e){var r,o;if(e.key!=="Escape")return;const t=s[s.length-1];!t||((r=t.onEscape)==null||r.call(t,e),(o=e.stopImmediatePropagation)==null||o.call(e),e.stopPropagation())}function _e(){typeof document=="undefined"||Y||(document.addEventListener("keydown",Oe),Y=!0)}function $e(){typeof document=="undefined"||j||(document.addEventListener("mousedown",e=>{a={x:e.clientX,y:e.clientY}},!0),document.addEventListener("touchstart",e=>{const t=e.touches[0]||e.changedTouches[0];!t||(a={x:t.clientX,y:t.clientY})},{capture:!0,passive:!0}),j=!0)}function Z(e,t,r){y={x:e,y:t,timestamp:Date.now(),source:r==null?void 0:r.source,context:r==null?void 0:r.context}}function Be(e,t){Z(e.clientX,e.clientY,t)}function G(e=500){return!y||Date.now()-y.timestamp>e?null:y}function Ne(){return a}function Fe(e){if(typeof window=="undefined"||!e)return{origin:{x:0,y:0},source:"fallback",explicitTriggerPoint:null,globalInteractionPoint:a,dialogRect:null,fallbackPoint:{x:0,y:0}};const t=e.getBoundingClientRect(),r={x:t.width/2,y:Math.min(t.height*.22,96)},o=G();return o?{origin:{x:o.x-t.left,y:o.y-t.top},source:"explicit-trigger",explicitTriggerPoint:o,globalInteractionPoint:a,dialogRect:{left:t.left,top:t.top,width:t.width,height:t.height},fallbackPoint:r}:a?{origin:{x:a.x-t.left,y:a.y-t.top},source:"global-pointer",explicitTriggerPoint:null,globalInteractionPoint:a,dialogRect:{left:t.left,top:t.top,width:t.width,height:t.height},fallbackPoint:r}:{origin:r,source:"fallback",explicitTriggerPoint:null,globalInteractionPoint:null,dialogRect:{left:t.left,top:t.top,width:t.width,height:t.height},fallbackPoint:r}}function je(){return typeof document=="undefined"?null:document.activeElement instanceof HTMLElement?document.activeElement:null}function Q(e){try{e.focus({preventScroll:!0})}catch{e.focus()}}function Ye(e,t={}){if(typeof document=="undefined"||!e)return null;_e();const r=s.find(l=>l.dialogElement===e);if(r)return r.onEscape=t.onEscape,r.id;const o=e.hasAttribute("tabindex"),n=e.getAttribute("tabindex");o||e.setAttribute("tabindex","-1");const i={id:A,dialogElement:e,restoreElement:je(),hadTabIndex:o,previousTabIndex:n,onEscape:t.onEscape};return A+=1,s.push(i),Q(e),i.id}function ze(e){var l;if(typeof document=="undefined"||e==null)return;const t=s.findIndex(u=>u.id===e);if(t===-1)return;const[r]=s.splice(t,1);if(r.hadTabIndex?r.previousTabIndex===null?r.dialogElement.removeAttribute("tabindex"):r.dialogElement.setAttribute("tabindex",r.previousTabIndex):r.dialogElement.removeAttribute("tabindex"),!(t===s.length))return;const n=s[s.length-1],i=(l=r.restoreElement)!=null&&l.isConnected?r.restoreElement:n==null?void 0:n.dialogElement;i&&Q(i)}function Ue(e){var t;return e==null?!1:((t=s[s.length-1])==null?void 0:t.id)===e}function Xe(){typeof document!="undefined"&&(m===0&&(h=window.scrollX,T=window.scrollY,w=document.body.style.overflow,k=document.body.style.overflowX,R=document.body.style.overflowY,x=document.body.style.position,E=document.body.style.top,C=document.body.style.left,D=document.body.style.right,L=document.body.style.width,document.body.classList.add(M),document.body.style.overflow="hidden",document.body.style.overflowX="hidden",document.body.style.overflowY="hidden",document.body.style.position="fixed",document.body.style.top=`-${T}px`,document.body.style.left=`-${h}px`,document.body.style.right="0",document.body.style.width="100%"),m+=1)}function Ke(){if(!(typeof document=="undefined"||m===0)&&(m-=1,m===0&&(document.body.classList.remove(M),document.body.style.overflow=w,document.body.style.overflowX=k,document.body.style.overflowY=R,document.body.style.position=x,document.body.style.top=E,document.body.style.left=C,document.body.style.right=D,document.body.style.width=L,!(typeof navigator!="undefined"&&/jsdom/i.test(navigator.userAgent))&&typeof window.scrollTo=="function")))try{window.scrollTo(h,T)}catch{}}function He(){y=null,a=null,m=0,A=1,s=[],w="",k="",R="",x="",E="",C="",D="",L="",h=0,T=0,typeof document!="undefined"&&(document.body.classList.remove(M),document.body.style.overflow="",document.body.style.overflowX="",document.body.style.overflowY="",document.body.style.position="",document.body.style.top="",document.body.style.left="",document.body.style.right="",document.body.style.width="")}Object.defineProperty(exports,"convertToStaticRanklist",{enumerable:!0,get:function(){return c.convertToStaticRanklist}});exports.MODAL_ANIMATION_DURATION_MS=Le;exports.SRK_ANIMATED_MODAL_ROOT_CLASS=Ie;exports.SRK_SCROLL_LOCK_BODY_CLASS=M;exports.buildSliderMarks=Ee;exports.calculateDirtPercentage=pe;exports.calculateProblemStatisticsFooter=ye;exports.calculateSEValue=Se;exports.caniuse=De;exports.captureModalTriggerPointFromMouseEvent=Be;exports.defaultBackgroundColor=U;exports.ensureModalInteractionTracker=$e;exports.formatProblemStatisticsAcceptedMinute=he;exports.formatProblemStatisticsAcceptedRange=be;exports.formatProblemStatisticsAverageHardness=Me;exports.formatProblemStatisticsPercent=Te;exports.formatRanklistStatusTime=f;exports.formatSolutionTimestamp=Ae;exports.getAcceptedStatusDetails=X;exports.getLastModalInteractionPoint=Ne;exports.getLastPenaltySolution=H;exports.getMarkerPresentation=fe;exports.getProblemHeaderBackgroundImage=de;exports.getProgressDurationMinutes=J;exports.getProgressMaxAvailableMinutes=Re;exports.getProgressMetrics=Ce;exports.getRankProblemStatusCellPresentation=ge;exports.getRankProblemStatusTries=v;exports.getRecentModalTriggerPoint=G;exports.getSolutionModalTitle=Pe;exports.getSolutionResultMeta=me;exports.isAcceptedRankProblemStatus=g;exports.isProgressEnded=xe;exports.isRejectedRankProblemStatus=K;exports.isTopModalFocusScope=Ue;exports.lockModalBodyScroll=Xe;exports.registerModalFocusScope=Ye;exports.resetModalInteractionStateForTests=He;exports.resolveModalTransformOrigin=Fe;exports.resolveSrkAssetUrl=ue;exports.setModalTriggerPoint=Z;exports.shouldShowTimeColumn=ve;exports.srkSupportedVersions=q;exports.unlockModalBodyScroll=Ke;exports.unregisterModalFocusScope=ze;
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ const defaultBackgroundColor = {
6
6
  [EnumTheme.light]: "#ffffff",
7
7
  [EnumTheme.dark]: "#191919"
8
8
  };
9
+ const defaultNoPenaltyResults = ["FB", "AC", "?", "NOUT", "CE", "UKE", null];
9
10
  function resolveSrkAssetUrl(url, field, formatter) {
10
11
  if (typeof formatter === "function") {
11
12
  return formatter(url, field);
@@ -25,12 +26,12 @@ function resolveSrkAssetUrl(url, field, formatter) {
25
26
  console.warn("unsupported srk asset url:", url);
26
27
  return "";
27
28
  }
28
- function getProblemHeaderBackgroundImage(style, theme) {
29
+ function getProblemHeaderBackgroundImage(style, theme, gradientDirection = 180) {
29
30
  const { backgroundColor } = resolveStyle(style || {});
30
31
  const resolvedColor = backgroundColor[theme] || defaultBackgroundColor[theme];
31
32
  const bgColorStr = Color(resolvedColor).string();
32
33
  const bgColorAlphaStr = Color(resolvedColor).alpha(0.27).string();
33
- return `linear-gradient(180deg, ${bgColorStr} 0%, ${bgColorStr} 10%, ${bgColorAlphaStr} 10%, transparent 100%)`;
34
+ return `linear-gradient(${gradientDirection}deg, ${bgColorStr} 0%, ${bgColorStr} 10%, ${bgColorAlphaStr} 10%, transparent 100%)`;
34
35
  }
35
36
  function getMarkerPresentation(marker, theme) {
36
37
  if (typeof marker.style === "string") {
@@ -82,6 +83,194 @@ function getSolutionResultMeta(result) {
82
83
  function getAcceptedStatusDetails(status) {
83
84
  return `${status.tries}/${status.time ? formatTimeDuration(status.time, "min", Math.floor) : "-"}`;
84
85
  }
86
+ function isAcceptedRankProblemStatus(status) {
87
+ return (status == null ? void 0 : status.result) === "AC" || (status == null ? void 0 : status.result) === "FB";
88
+ }
89
+ function isRejectedRankProblemStatus(status) {
90
+ return (status == null ? void 0 : status.result) === "RJ" || (status == null ? void 0 : status.result) === "?";
91
+ }
92
+ function getRankProblemStatusTries(status) {
93
+ return (status == null ? void 0 : status.tries) || 0;
94
+ }
95
+ function getLastPenaltySolution(status, ranklist) {
96
+ const noPenaltyResults = getNoPenaltyResults(ranklist);
97
+ const solutions = status.solutions || [];
98
+ for (let index = solutions.length - 1; index >= 0; index -= 1) {
99
+ const solution = solutions[index];
100
+ if (!noPenaltyResults.includes(solution.result)) {
101
+ return solution;
102
+ }
103
+ }
104
+ return void 0;
105
+ }
106
+ function formatRanklistStatusTime(time, ranklist) {
107
+ if (!time) {
108
+ return "-";
109
+ }
110
+ const precision = getRanklistTimePrecision(time, ranklist);
111
+ if (precision === "ms") {
112
+ const totalMs = Math.floor(formatTimeDuration(time, "ms"));
113
+ const totalSeconds = Math.floor(totalMs / 1e3);
114
+ return `${formatClockSeconds(totalSeconds)}.${padNumber(totalMs % 1e3, 3)}`;
115
+ }
116
+ if (precision === "s") {
117
+ return formatClockSeconds(Math.floor(formatTimeDuration(time, "s")));
118
+ }
119
+ const totalMinutes = Math.floor(formatTimeDuration(time, "min"));
120
+ return `${Math.floor(totalMinutes / 60)}:${padNumber(totalMinutes % 60, 2)}`;
121
+ }
122
+ function getRankProblemStatusCellPresentation(status, ranklist, preset = "classic") {
123
+ if (!status.result) {
124
+ return {};
125
+ }
126
+ if (preset === "classic") {
127
+ if (isAcceptedRankProblemStatus(status)) {
128
+ const details = getAcceptedStatusDetails(status);
129
+ if (typeof status.score === "number") {
130
+ return {
131
+ score: status.score,
132
+ scoreDetails: details
133
+ };
134
+ }
135
+ return { primary: details };
136
+ }
137
+ return {
138
+ primary: typeof status.tries === "number" ? String(status.tries) : ""
139
+ };
140
+ }
141
+ if (isAcceptedRankProblemStatus(status)) {
142
+ const wrongTries = Math.max((status.tries || 0) - 1, 0);
143
+ if (preset === "detailed") {
144
+ return {
145
+ primary: formatRanklistStatusTime(status.time, ranklist),
146
+ secondary: wrongTries > 0 ? `(-${wrongTries})` : ""
147
+ };
148
+ }
149
+ const primary = wrongTries > 0 ? `+${wrongTries}` : "+";
150
+ if (preset === "compact") {
151
+ return {
152
+ primary,
153
+ secondary: formatRanklistStatusTime(status.time, ranklist)
154
+ };
155
+ }
156
+ return { primary };
157
+ }
158
+ if (isRejectedRankProblemStatus(status)) {
159
+ const tries = status.tries || 0;
160
+ const primary = `-${tries}`;
161
+ if (preset === "detailed") {
162
+ return {
163
+ primary: "",
164
+ secondary: tries > 0 ? `(-${tries})` : ""
165
+ };
166
+ }
167
+ if (preset === "compact" && tries > 0) {
168
+ const lastPenaltySolution = getLastPenaltySolution(status, ranklist);
169
+ if (lastPenaltySolution) {
170
+ return {
171
+ primary,
172
+ secondary: formatRanklistStatusTime(lastPenaltySolution.time, ranklist)
173
+ };
174
+ }
175
+ }
176
+ return { primary };
177
+ }
178
+ return {};
179
+ }
180
+ function calculateDirtPercentage(row) {
181
+ const totals = row.statuses.reduce((result, status) => {
182
+ if (!isAcceptedRankProblemStatus(status)) {
183
+ return result;
184
+ }
185
+ const tries = getRankProblemStatusTries(status);
186
+ return {
187
+ wrong: result.wrong + Math.max(tries - 1, 0),
188
+ submitted: result.submitted + tries
189
+ };
190
+ }, { wrong: 0, submitted: 0 });
191
+ if (!totals.submitted || !totals.wrong) {
192
+ return "0%";
193
+ }
194
+ return `${Math.floor(totals.wrong / totals.submitted * 100)}%`;
195
+ }
196
+ function calculateProblemStatisticsFooter(ranklist) {
197
+ const participantCount = ranklist.rows.length;
198
+ return ranklist.problems.map((_, problemIndex) => {
199
+ const stat = {
200
+ participantCount,
201
+ accepted: 0,
202
+ tried: 0,
203
+ submitted: 0,
204
+ dirt: 0,
205
+ dirtSubmitted: 0
206
+ };
207
+ ranklist.rows.forEach((row) => {
208
+ const status = row.statuses[problemIndex];
209
+ const tries = getRankProblemStatusTries(status);
210
+ if (tries > 0) {
211
+ stat.tried += 1;
212
+ stat.submitted += tries;
213
+ }
214
+ if (!isAcceptedRankProblemStatus(status)) {
215
+ return;
216
+ }
217
+ stat.accepted += 1;
218
+ stat.dirt += Math.max(tries - 1, 0);
219
+ stat.dirtSubmitted += tries;
220
+ if (!status.time) {
221
+ return;
222
+ }
223
+ if (!stat.firstAcceptedTime || compareTimeDuration(status.time, stat.firstAcceptedTime) < 0) {
224
+ stat.firstAcceptedTime = status.time;
225
+ }
226
+ if (!stat.lastAcceptedTime || compareTimeDuration(status.time, stat.lastAcceptedTime) > 0) {
227
+ stat.lastAcceptedTime = status.time;
228
+ }
229
+ });
230
+ return stat;
231
+ });
232
+ }
233
+ function formatProblemStatisticsAcceptedRange(stat, ranklist) {
234
+ if (!stat.firstAcceptedTime || !stat.lastAcceptedTime) {
235
+ return "-";
236
+ }
237
+ return `${formatRanklistStatusTime(stat.firstAcceptedTime, ranklist)} / ${formatRanklistStatusTime(stat.lastAcceptedTime, ranklist)}`;
238
+ }
239
+ function formatProblemStatisticsAcceptedMinute(time) {
240
+ if (!time) {
241
+ return "-";
242
+ }
243
+ return String(Math.floor(formatTimeDuration(time, "min")));
244
+ }
245
+ function formatProblemStatisticsPercent(numerator, denominator) {
246
+ if (denominator <= 0) {
247
+ return "(-)";
248
+ }
249
+ return `(${Math.floor(numerator / denominator * 100)}%)`;
250
+ }
251
+ function formatProblemStatisticsAverageHardness(stat) {
252
+ const value = getProblemStatisticsAverageHardness(stat);
253
+ if (value === void 0) {
254
+ return "-";
255
+ }
256
+ return formatAverageHardnessValue(value);
257
+ }
258
+ function calculateSEValue(row, problemStatistics) {
259
+ const values = row.statuses.reduce((result, status, index) => {
260
+ if (!isAcceptedRankProblemStatus(status)) {
261
+ return result;
262
+ }
263
+ const problemSE = getProblemStatisticsAverageHardness(problemStatistics[index]);
264
+ if (problemSE !== void 0) {
265
+ result.push(problemSE);
266
+ }
267
+ return result;
268
+ }, []);
269
+ if (!values.length) {
270
+ return "0.00";
271
+ }
272
+ return formatAverageHardnessValue(values.reduce((sum, value) => sum + value, 0) / values.length);
273
+ }
85
274
  function getSolutionModalTitle(problemIndex, user) {
86
275
  return `Solutions of ${numberToAlphabet(problemIndex)} (${resolveText(user.name)})`;
87
276
  }
@@ -94,6 +283,42 @@ function shouldShowTimeColumn(rows) {
94
283
  return Boolean((_a = row.score) == null ? void 0 : _a.time);
95
284
  });
96
285
  }
286
+ function getRanklistTimePrecision(time, ranklist) {
287
+ const sorter = ranklist.sorter;
288
+ if ((sorter == null ? void 0 : sorter.algorithm) === "ICPC" && sorter.config.timePrecision) {
289
+ return sorter.config.timePrecision;
290
+ }
291
+ return time[1];
292
+ }
293
+ function getNoPenaltyResults(ranklist) {
294
+ const sorter = ranklist.sorter;
295
+ if ((sorter == null ? void 0 : sorter.algorithm) === "ICPC" && sorter.config.noPenaltyResults) {
296
+ return sorter.config.noPenaltyResults;
297
+ }
298
+ return defaultNoPenaltyResults;
299
+ }
300
+ function getProblemStatisticsAverageHardness(stat) {
301
+ if (!stat || stat.participantCount <= 0) {
302
+ return void 0;
303
+ }
304
+ return (stat.participantCount - stat.accepted) / stat.participantCount;
305
+ }
306
+ function formatAverageHardnessValue(value) {
307
+ return value.toFixed(2);
308
+ }
309
+ function compareTimeDuration(a, b) {
310
+ return formatTimeDuration(a, "ms") - formatTimeDuration(b, "ms");
311
+ }
312
+ function formatClockSeconds(totalSeconds) {
313
+ const hours = Math.floor(totalSeconds / 3600);
314
+ const minutes = Math.floor(totalSeconds % 3600 / 60);
315
+ const seconds = totalSeconds % 60;
316
+ return `${hours}:${padNumber(minutes, 2)}:${padNumber(seconds, 2)}`;
317
+ }
318
+ function padNumber(num, size) {
319
+ const raw = String(Math.trunc(Math.abs(num)));
320
+ return raw.length >= size ? raw : `${"0".repeat(size - raw.length)}${raw}`;
321
+ }
97
322
  function getProgressDurationMinutes(contest) {
98
323
  return formatTimeDuration(contest.duration, "min");
99
324
  }
@@ -451,4 +676,4 @@ function resetModalInteractionStateForTests() {
451
676
  document.body.style.width = "";
452
677
  }
453
678
  }
454
- export { MODAL_ANIMATION_DURATION_MS, SRK_ANIMATED_MODAL_ROOT_CLASS, SRK_SCROLL_LOCK_BODY_CLASS, buildSliderMarks, caniuse, captureModalTriggerPointFromMouseEvent, defaultBackgroundColor, ensureModalInteractionTracker, formatSolutionTimestamp, getAcceptedStatusDetails, getLastModalInteractionPoint, getMarkerPresentation, getProblemHeaderBackgroundImage, getProgressDurationMinutes, getProgressMaxAvailableMinutes, getProgressMetrics, getRecentModalTriggerPoint, getSolutionModalTitle, getSolutionResultMeta, isProgressEnded, isTopModalFocusScope, lockModalBodyScroll, registerModalFocusScope, resetModalInteractionStateForTests, resolveModalTransformOrigin, resolveSrkAssetUrl, setModalTriggerPoint, shouldShowTimeColumn, srkSupportedVersions, unlockModalBodyScroll, unregisterModalFocusScope };
679
+ export { MODAL_ANIMATION_DURATION_MS, SRK_ANIMATED_MODAL_ROOT_CLASS, SRK_SCROLL_LOCK_BODY_CLASS, buildSliderMarks, calculateDirtPercentage, calculateProblemStatisticsFooter, calculateSEValue, caniuse, captureModalTriggerPointFromMouseEvent, defaultBackgroundColor, ensureModalInteractionTracker, formatProblemStatisticsAcceptedMinute, formatProblemStatisticsAcceptedRange, formatProblemStatisticsAverageHardness, formatProblemStatisticsPercent, formatRanklistStatusTime, formatSolutionTimestamp, getAcceptedStatusDetails, getLastModalInteractionPoint, getLastPenaltySolution, getMarkerPresentation, getProblemHeaderBackgroundImage, getProgressDurationMinutes, getProgressMaxAvailableMinutes, getProgressMetrics, getRankProblemStatusCellPresentation, getRankProblemStatusTries, getRecentModalTriggerPoint, getSolutionModalTitle, getSolutionResultMeta, isAcceptedRankProblemStatus, isProgressEnded, isRejectedRankProblemStatus, isTopModalFocusScope, lockModalBodyScroll, registerModalFocusScope, resetModalInteractionStateForTests, resolveModalTransformOrigin, resolveSrkAssetUrl, setModalTriggerPoint, shouldShowTimeColumn, srkSupportedVersions, unlockModalBodyScroll, unregisterModalFocusScope };
@@ -1,5 +1,6 @@
1
1
  import type * as srk from '@algoux/standard-ranklist';
2
2
  import { EnumTheme } from '@algoux/standard-ranklist-utils';
3
+ import type { StaticRanklist, StaticRanklistRow } from './types';
3
4
  export declare const defaultBackgroundColor: Record<EnumTheme, string>;
4
5
  export interface MarkerPresentation {
5
6
  className?: string;
@@ -11,11 +12,51 @@ export interface SolutionResultMeta {
11
12
  label: string;
12
13
  className?: string;
13
14
  }
15
+ export declare type RanklistStatusCellPreset = 'classic' | 'detailed' | 'minimal' | 'compact';
16
+ export declare type RanklistUserAvatarPlacement = 'user' | 'organization';
17
+ export interface RanklistColumnTitles {
18
+ series?: string[] | ((series: srk.RankSeries, index: number) => string | undefined);
19
+ organization?: string;
20
+ user?: string;
21
+ score?: string;
22
+ time?: string;
23
+ dirt?: string;
24
+ se?: string;
25
+ }
26
+ export interface ProblemStatisticsFooter {
27
+ participantCount: number;
28
+ accepted: number;
29
+ tried: number;
30
+ submitted: number;
31
+ dirt: number;
32
+ dirtSubmitted: number;
33
+ firstAcceptedTime?: srk.TimeDuration;
34
+ lastAcceptedTime?: srk.TimeDuration;
35
+ }
36
+ export interface RanklistStatusCellPresentation {
37
+ primary?: string;
38
+ secondary?: string;
39
+ score?: number;
40
+ scoreDetails?: string;
41
+ }
14
42
  export declare function resolveSrkAssetUrl(url: string, field: string, formatter?: (url: string, field: string) => string): string;
15
- export declare function getProblemHeaderBackgroundImage(style: srk.Style | undefined, theme: EnumTheme): string;
43
+ export declare function getProblemHeaderBackgroundImage(style: srk.Style | undefined, theme: EnumTheme, gradientDirection?: number): string;
16
44
  export declare function getMarkerPresentation(marker: srk.Marker, theme: EnumTheme): MarkerPresentation;
17
45
  export declare function getSolutionResultMeta(result: srk.Solution['result']): SolutionResultMeta;
18
46
  export declare function getAcceptedStatusDetails(status: srk.RankProblemStatus): string;
47
+ export declare function isAcceptedRankProblemStatus(status: srk.RankProblemStatus | undefined): boolean;
48
+ export declare function isRejectedRankProblemStatus(status: srk.RankProblemStatus | undefined): boolean;
49
+ export declare function getRankProblemStatusTries(status: srk.RankProblemStatus | undefined): number;
50
+ export declare function getLastPenaltySolution(status: srk.RankProblemStatus, ranklist: srk.Ranklist): srk.Solution | undefined;
51
+ export declare function formatRanklistStatusTime(time: srk.TimeDuration | undefined, ranklist: srk.Ranklist): string;
52
+ export declare function getRankProblemStatusCellPresentation(status: srk.RankProblemStatus, ranklist: srk.Ranklist, preset?: RanklistStatusCellPreset): RanklistStatusCellPresentation;
53
+ export declare function calculateDirtPercentage(row: Pick<StaticRanklistRow, 'statuses'>): string;
54
+ export declare function calculateProblemStatisticsFooter(ranklist: StaticRanklist): ProblemStatisticsFooter[];
55
+ export declare function formatProblemStatisticsAcceptedRange(stat: ProblemStatisticsFooter, ranklist: srk.Ranklist): string;
56
+ export declare function formatProblemStatisticsAcceptedMinute(time: srk.TimeDuration | undefined): string;
57
+ export declare function formatProblemStatisticsPercent(numerator: number, denominator: number): string;
58
+ export declare function formatProblemStatisticsAverageHardness(stat: ProblemStatisticsFooter): string;
59
+ export declare function calculateSEValue(row: Pick<StaticRanklistRow, 'statuses'>, problemStatistics: ProblemStatisticsFooter[]): string;
19
60
  export declare function getSolutionModalTitle(problemIndex: number, user: srk.User): string;
20
61
  export declare function formatSolutionTimestamp(solution: srk.Solution): string;
21
62
  export declare function shouldShowTimeColumn(rows: srk.RanklistRow[]): boolean;
package/package.json CHANGED
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "name": "@algoux/standard-ranklist-renderer-component-core",
3
- "version": "0.5.1",
3
+ "version": "0.6.1",
4
4
  "description": "Core helpers and shared types for Standard Ranklist Renderer Component",
5
5
  "license": "MIT",
6
+ "homepage": "https://github.com/algoux/standard-ranklist-renderer-component",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/algoux/standard-ranklist-renderer-component"
10
+ },
6
11
  "type": "module",
7
12
  "files": [
8
13
  "dist"