@algoux/standard-ranklist-renderer-component-solid 0.5.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.
@@ -0,0 +1,694 @@
1
+ import "@algoux/standard-ranklist-renderer-component-styles";
2
+ import { createComponent, ssr, ssrHydrationKey, ssrAttribute, escape, ssrStyle, ssrStyleProperty, mergeProps } from "solid-js/web";
3
+ import { SRK_ANIMATED_MODAL_ROOT_CLASS, ensureModalInteractionTracker, unregisterModalFocusScope, resolveModalTransformOrigin, MODAL_ANIMATION_DURATION_MS, lockModalBodyScroll, unlockModalBodyScroll, getSolutionModalTitle, formatSolutionTimestamp, getSolutionResultMeta, getMarkerPresentation, resolveSrkAssetUrl, getProgressMaxAvailableMinutes, getProgressDurationMinutes, isProgressEnded, getProgressMetrics, caniuse, srkSupportedVersions, getProblemHeaderBackgroundImage, shouldShowTimeColumn, captureModalTriggerPointFromMouseEvent, getAcceptedStatusDetails } from "@algoux/standard-ranklist-renderer-component-core";
4
+ import { createUniqueId, createSignal, createMemo, onMount, createEffect, onCleanup, on, untrack, Show, For } from "solid-js";
5
+ import { resolveText, resolveUserMarkers, EnumTheme, secToTimeStr, formatTimeDuration, numberToAlphabet, resolveStyle } from "@algoux/standard-ranklist-utils";
6
+ var _tmpl$$4 = ["<div", ' class="srk-modal-header"><div class="srk-modal-title"', ">", "</div></div>"], _tmpl$2$4 = ["<div", '><div class="srk-modal-mask"></div><div', ' tabindex="-1"><div', ' aria-modal="true" class="srk-modal" data-srk-modal-panel="true" role="dialog" style="', '" tabindex="-1"><div class="srk-modal-content"><button aria-label="Close" class="srk-modal-close" type="button"><span class="srk-modal-close-x"></span></button><!--$-->', '<!--/--><div class="srk-modal-body">', "</div></div></div></div></div>"];
7
+ function classNames(...values) {
8
+ return values.filter(Boolean).join(" ");
9
+ }
10
+ function Modal(props) {
11
+ const titleId = createUniqueId();
12
+ const destroyOnClose = () => {
13
+ var _a;
14
+ return (_a = props.destroyOnClose) != null ? _a : true;
15
+ };
16
+ const [isMounted, setIsMounted] = createSignal(props.open || !destroyOnClose());
17
+ const [animationState, setAnimationState] = createSignal(props.open ? "pre-open" : "closing");
18
+ const [transformOrigin, setTransformOrigin] = createSignal({
19
+ x: 0,
20
+ y: 0
21
+ });
22
+ let rootRef;
23
+ let dialogRef;
24
+ let closeTimer = null;
25
+ let openTimer = null;
26
+ let bodyLocked = false;
27
+ let focusScopeId = null;
28
+ let pendingFocusRegistration = false;
29
+ const shouldRender = createMemo(() => props.open || isMounted() || !destroyOnClose());
30
+ const shouldLockBody = createMemo(() => props.open || destroyOnClose() && isMounted());
31
+ const rootClassName = createMemo(() => classNames("srk-modal-root", SRK_ANIMATED_MODAL_ROOT_CLASS, props.rootClassName));
32
+ const baseDialogStyle = createMemo(() => {
33
+ var _a, _b;
34
+ return {
35
+ ...props.style,
36
+ width: props.width ? `${props.width}px` : (_a = props.style) == null ? void 0 : _a.width,
37
+ maxWidth: (_b = props.style) == null ? void 0 : _b.maxWidth
38
+ };
39
+ });
40
+ const clearTimers = () => {
41
+ if (closeTimer !== null) {
42
+ window.clearTimeout(closeTimer);
43
+ closeTimer = null;
44
+ }
45
+ if (openTimer !== null) {
46
+ window.clearTimeout(openTimer);
47
+ openTimer = null;
48
+ }
49
+ };
50
+ const registerFocusScope = () => {
51
+ if (!props.open || !dialogRef || focusScopeId !== null) {
52
+ return;
53
+ }
54
+ if (!dialogRef.isConnected) {
55
+ if (!pendingFocusRegistration) {
56
+ pendingFocusRegistration = true;
57
+ queueMicrotask(() => {
58
+ pendingFocusRegistration = false;
59
+ registerFocusScope();
60
+ });
61
+ }
62
+ return;
63
+ }
64
+ };
65
+ onMount(() => {
66
+ registerFocusScope();
67
+ });
68
+ createEffect(() => {
69
+ ensureModalInteractionTracker();
70
+ });
71
+ onCleanup(() => {
72
+ clearTimers();
73
+ unregisterModalFocusScope(focusScopeId);
74
+ focusScopeId = null;
75
+ });
76
+ createEffect(on(() => props.open, (open) => {
77
+ const destroy = destroyOnClose();
78
+ clearTimers();
79
+ if (open) {
80
+ setIsMounted(true);
81
+ setTransformOrigin({
82
+ x: 0,
83
+ y: 0
84
+ });
85
+ setAnimationState("pre-open");
86
+ if (typeof window !== "undefined") {
87
+ openTimer = window.setTimeout(() => {
88
+ if (!props.open || animationState() !== "pre-open") {
89
+ openTimer = null;
90
+ return;
91
+ }
92
+ const resolution = resolveModalTransformOrigin(null);
93
+ setTransformOrigin(resolution.origin);
94
+ setAnimationState("opening");
95
+ openTimer = null;
96
+ }, 0);
97
+ }
98
+ return;
99
+ }
100
+ if (focusScopeId !== null) {
101
+ unregisterModalFocusScope(focusScopeId);
102
+ focusScopeId = null;
103
+ }
104
+ setAnimationState("closing");
105
+ if (!destroy) {
106
+ setIsMounted(true);
107
+ return;
108
+ }
109
+ if (untrack(isMounted) && typeof window !== "undefined") {
110
+ closeTimer = window.setTimeout(() => {
111
+ if (bodyLocked) {
112
+ unlockModalBodyScroll();
113
+ bodyLocked = false;
114
+ }
115
+ rootRef == null ? void 0 : rootRef.remove();
116
+ setIsMounted(false);
117
+ closeTimer = null;
118
+ }, MODAL_ANIMATION_DURATION_MS);
119
+ }
120
+ }, {
121
+ defer: false
122
+ }));
123
+ createEffect(on(shouldLockBody, (lock) => {
124
+ if (lock && !bodyLocked) {
125
+ lockModalBodyScroll();
126
+ bodyLocked = true;
127
+ return;
128
+ }
129
+ if (!lock && bodyLocked) {
130
+ unlockModalBodyScroll();
131
+ bodyLocked = false;
132
+ return;
133
+ }
134
+ }, {
135
+ defer: false
136
+ }));
137
+ onCleanup(() => {
138
+ if (bodyLocked) {
139
+ unlockModalBodyScroll();
140
+ bodyLocked = false;
141
+ }
142
+ unregisterModalFocusScope(focusScopeId);
143
+ focusScopeId = null;
144
+ });
145
+ createEffect(() => {
146
+ if (props.open && shouldRender()) {
147
+ registerFocusScope();
148
+ }
149
+ });
150
+ createEffect(() => {
151
+ var _a;
152
+ props.width ? `${props.width}px` : typeof ((_a = props.style) == null ? void 0 : _a.width) === "string" ? props.style.width : null;
153
+ `${transformOrigin().x}px`;
154
+ `${transformOrigin().y}px`;
155
+ animationState();
156
+ {
157
+ return;
158
+ }
159
+ });
160
+ const content = () => ssr(_tmpl$2$4, ssrHydrationKey() + ssrAttribute("class", escape(rootClassName(), true), false) + ssrAttribute("data-srk-modal-state", escape(animationState(), true), false), ssrAttribute("class", escape(classNames("srk-modal-wrap", props.wrapClassName), true), false), ssrAttribute("aria-labelledby", props.title !== void 0 ? escape(titleId, true) : escape(void 0, true), false), ssrStyle(baseDialogStyle()), escape(createComponent(Show, {
161
+ get when() {
162
+ return props.title !== void 0;
163
+ },
164
+ get children() {
165
+ return ssr(_tmpl$$4, ssrHydrationKey(), ssrAttribute("id", escape(titleId, true), false), escape(props.title));
166
+ }
167
+ })), escape(props.children));
168
+ return createComponent(Show, {
169
+ get when() {
170
+ return shouldRender();
171
+ },
172
+ children: content
173
+ });
174
+ }
175
+ var _tmpl$$3 = ["<table", ' class="srk-common-table srk-solutions-table"><thead><tr><th class="srk--text-left">Result</th><th class="srk--text-right">Time</th></tr></thead><tbody>', "</tbody></table>"], _tmpl$2$3 = ["<tr", '><td><span class="', '">', '</span></td><td class="srk--text-right">', "</td></tr>"];
176
+ function DefaultSolutionModal(props) {
177
+ const [cachedPayload, setCachedPayload] = createSignal(props.user ? {
178
+ user: props.user,
179
+ problem: props.problem,
180
+ problemIndex: props.problemIndex,
181
+ solutions: props.solutions || []
182
+ } : null);
183
+ createEffect(() => {
184
+ if (props.user) {
185
+ setCachedPayload({
186
+ user: props.user,
187
+ problem: props.problem,
188
+ problemIndex: props.problemIndex,
189
+ solutions: props.solutions || []
190
+ });
191
+ }
192
+ });
193
+ return createComponent(Show, {
194
+ get when() {
195
+ return cachedPayload();
196
+ },
197
+ children: (payload) => createComponent(Modal, {
198
+ get open() {
199
+ return props.open;
200
+ },
201
+ get onClose() {
202
+ return props.onClose;
203
+ },
204
+ get rootClassName() {
205
+ return props.rootClassName || "srk-general-modal-root";
206
+ },
207
+ get style() {
208
+ return props.style;
209
+ },
210
+ get title() {
211
+ return props.title || getSolutionModalTitle(payload().problemIndex, payload().user);
212
+ },
213
+ get width() {
214
+ return props.width || 320;
215
+ },
216
+ get wrapClassName() {
217
+ return props.wrapClassName || "srk-solutions-modal";
218
+ },
219
+ get children() {
220
+ return ssr(_tmpl$$3, ssrHydrationKey(), escape(createComponent(For, {
221
+ get each() {
222
+ return payload().solutions;
223
+ },
224
+ children: (solution) => {
225
+ const meta = () => getSolutionResultMeta(solution.result);
226
+ return ssr(_tmpl$2$3, ssrHydrationKey(), `srk-solution-result-text ${escape(meta().className || "", true)}`, escape(meta().label), escape(formatSolutionTimestamp(solution)));
227
+ }
228
+ })));
229
+ }
230
+ })
231
+ });
232
+ }
233
+ var _tmpl$$2 = ["<div", ' class="srk-user-modal-info-team-members">', "</div>"], _tmpl$2$2 = ["<div", ' class="srk-user-modal-info"><h3 class="srk-user-modal-info-user-name">', "</h3><!--$-->", '<!--/--><div class="srk-user-modal-info-labels"><span class="srk-user-modal-info-labels-label srk-user-modal-info-labels-label-preset-general">', "</span><!--$-->", "<!--/--></div><!--$-->", "<!--/--><!--$-->", "<!--/--></div>"], _tmpl$3$2 = ["<p", ' class="srk-user-modal-info-user-second-name">', "</p>"], _tmpl$4$2 = ["<span", ' class="', '" style="', '">', "</span>"], _tmpl$5$2 = ["<span", ' class="srk-user-modal-info-team-members-slash"> / </span>'], _tmpl$6$2 = ["<span", ">", "</span>"], _tmpl$7$1 = ["<div", ' class="srk-user-modal-info-photo"><img', ' alt="User portrait" class="srk-user-modal-info-photo-img"></div>'];
234
+ function DefaultUserModal(props) {
235
+ const [cachedUser, setCachedUser] = createSignal(props.user || null);
236
+ const theme = () => props.theme || EnumTheme.light;
237
+ const markers = () => props.markers || [];
238
+ const resolvedMarkers = (user) => resolveUserMarkers(user, markers()).map((marker) => ({
239
+ marker,
240
+ presentation: getMarkerPresentation(marker, theme())
241
+ }));
242
+ const formatAssetUrl = (url, field) => resolveSrkAssetUrl(url, field, props.formatSrkAssetUrl);
243
+ createEffect(() => {
244
+ if (props.user) {
245
+ setCachedUser(props.user);
246
+ }
247
+ });
248
+ return createComponent(Show, {
249
+ get when() {
250
+ return cachedUser();
251
+ },
252
+ children: (user) => createComponent(Modal, {
253
+ get open() {
254
+ return props.open;
255
+ },
256
+ get onClose() {
257
+ return props.onClose;
258
+ },
259
+ get rootClassName() {
260
+ return props.rootClassName || "srk-general-modal-root";
261
+ },
262
+ get style() {
263
+ return props.style;
264
+ },
265
+ get title() {
266
+ return props.title || "User Info";
267
+ },
268
+ get width() {
269
+ return props.width || 420;
270
+ },
271
+ get wrapClassName() {
272
+ return props.wrapClassName || "srk-user-modal";
273
+ },
274
+ get children() {
275
+ return ssr(_tmpl$2$2, ssrHydrationKey(), escape(resolveText(user().name)), escape(createComponent(Show, {
276
+ get when() {
277
+ return user().organization;
278
+ },
279
+ children: (organization) => ssr(_tmpl$3$2, ssrHydrationKey(), escape(resolveText(organization())))
280
+ })), user().official === false ? "\uFF0A \u975E\u6B63\u5F0F\u53C2\u52A0\u8005" : "\u6B63\u5F0F\u53C2\u52A0\u8005", escape(createComponent(For, {
281
+ get each() {
282
+ return resolvedMarkers(user());
283
+ },
284
+ children: (entry) => ssr(_tmpl$4$2, ssrHydrationKey(), `srk-user-modal-info-labels-label ${escape(entry.presentation.className || "", true)}`, ssrStyle(entry.presentation.style), escape(resolveText(entry.marker.label)))
285
+ })), escape(createComponent(Show, {
286
+ get when() {
287
+ var _a;
288
+ return (_a = user().teamMembers) == null ? void 0 : _a.length;
289
+ },
290
+ get children() {
291
+ return ssr(_tmpl$$2, ssrHydrationKey(), escape(createComponent(For, {
292
+ get each() {
293
+ return user().teamMembers;
294
+ },
295
+ children: (member, index) => [createComponent(Show, {
296
+ get when() {
297
+ return index() > 0;
298
+ },
299
+ get children() {
300
+ return ssr(_tmpl$5$2, ssrHydrationKey());
301
+ }
302
+ }), ssr(_tmpl$6$2, ssrHydrationKey(), escape(resolveText(member.name)))]
303
+ })));
304
+ }
305
+ })), escape(createComponent(Show, {
306
+ get when() {
307
+ return user().photo;
308
+ },
309
+ children: (photo) => ssr(_tmpl$7$1, ssrHydrationKey(), ssrAttribute("src", escape(formatAssetUrl(photo(), "user.photo"), true), false))
310
+ })));
311
+ }
312
+ })
313
+ });
314
+ }
315
+ var _tmpl$$1 = ["<div", ' class="srk-progress-slider-tooltip" style="', '">', "</div>"], _tmpl$2$1 = ["<div", ' class="srk-progress-slider-layer"><!--$-->', '<!--/--><input aria-label="Time Travel" class="srk-progress-slider"', ' min="0" step="1"', ' type="range"', "></div>"], _tmpl$3$1 = ["<div", ' class="srk-progress-time-machine-status"><div class="srk-progress-time-machine-text">Time Travel Mode</div></div>'], _tmpl$4$1 = ["<div", ' class="srk-progress-bar-container"><div class="srk-progress-bar"><div class="srk-progress-bar-body"><div class="srk-progress-bar-segment srk-progress-bar-normal" style="', '"><div class="srk-progress-bar-fill" style="', '"></div></div><div class="srk-progress-bar-segment srk-progress-bar-frozen" style="', '"><div class="srk-progress-bar-fill" style="', '"></div></div></div><!--$-->', '<!--/--></div><div class="srk-progress-secondary-area"><div class="srk-progress-secondary-area-left" style="', '">Elapsed: <!--$-->', '<!--/--></div><div class="srk-progress-secondary-area-center">', '</div><div class="srk-progress-secondary-area-right" style="', '">Remaining: <!--$-->', "<!--/--></div></div></div>"], _tmpl$5$1 = ["<div", ' class="srk-progress-live-text">Live</div>'], _tmpl$6$1 = ["<div", ' style="', '">SRK</div>'];
316
+ function ProgressBar(props) {
317
+ var _a, _b;
318
+ const [localTime, setLocalTime] = createSignal(Date.now());
319
+ const [inTimeMachine, setInTimeMachine] = createSignal(false);
320
+ const [timeTravelIsChanging, setTimeTravelIsChanging] = createSignal(false);
321
+ const [timeTravelCurrentValue, setTimeTravelCurrentValue] = createSignal(getProgressMaxAvailableMinutes(props.data.contest, localTime(), props.td));
322
+ const [timeTravelValue, setTimeTravelValue] = createSignal(null);
323
+ const [isMounted, setIsMounted] = createSignal(false);
324
+ let liveInterval;
325
+ let previousContestTitle = JSON.stringify((_b = (_a = props.data) == null ? void 0 : _a.contest) == null ? void 0 : _b.title);
326
+ const td = () => {
327
+ var _a2;
328
+ return (_a2 = props.td) != null ? _a2 : 0;
329
+ };
330
+ const durationMinutes = () => getProgressDurationMinutes(props.data.contest);
331
+ const maxAvailableMinutes = () => getProgressMaxAvailableMinutes(props.data.contest, localTime(), td());
332
+ const ended = () => isProgressEnded(props.data.contest, localTime(), td());
333
+ const progressMetrics = () => getProgressMetrics(props.data, localTime(), td(), timeTravelCurrentValue(), inTimeMachine());
334
+ const clearLiveInterval = () => {
335
+ if (liveInterval) {
336
+ window.clearInterval(liveInterval);
337
+ liveInterval = void 0;
338
+ }
339
+ };
340
+ const handleProgressTimer = () => {
341
+ setLocalTime(Date.now());
342
+ if (ended()) {
343
+ clearLiveInterval();
344
+ }
345
+ };
346
+ createEffect(() => {
347
+ const maxValue = maxAvailableMinutes();
348
+ if (!timeTravelIsChanging() && timeTravelValue() === null && timeTravelCurrentValue() !== maxValue) {
349
+ setTimeTravelCurrentValue(maxValue);
350
+ }
351
+ });
352
+ createEffect(() => {
353
+ var _a2, _b2, _c;
354
+ const contestTitle = JSON.stringify((_b2 = (_a2 = props.data) == null ? void 0 : _a2.contest) == null ? void 0 : _b2.title);
355
+ if (contestTitle === previousContestTitle) {
356
+ return;
357
+ }
358
+ previousContestTitle = contestTitle;
359
+ setTimeTravelIsChanging(false);
360
+ setTimeTravelCurrentValue(maxAvailableMinutes());
361
+ setTimeTravelValue(null);
362
+ setInTimeMachine(false);
363
+ (_c = props.onTimeTravel) == null ? void 0 : _c.call(props, null);
364
+ });
365
+ createEffect(() => {
366
+ if (!props.live || typeof window === "undefined") {
367
+ clearLiveInterval();
368
+ return;
369
+ }
370
+ clearLiveInterval();
371
+ liveInterval = window.setInterval(handleProgressTimer, 1e3);
372
+ onCleanup(clearLiveInterval);
373
+ });
374
+ onMount(() => setIsMounted(true));
375
+ onCleanup(clearLiveInterval);
376
+ return ssr(_tmpl$4$1, ssrHydrationKey(), ssrStyleProperty("width:", `${escape(progressMetrics().frozenBreakpoint, true) * 100}%`), ssrStyleProperty("width:", `${escape(progressMetrics().normalInnerPercent, true)}%`), ssrStyleProperty("width:", `${(1 - escape(progressMetrics().frozenBreakpoint, true)) * 100}%`), ssrStyleProperty("width:", `${escape(progressMetrics().frozenInnerPercent, true)}%`), escape(createComponent(Show, {
377
+ get when() {
378
+ return props.enableTimeTravel && progressMetrics().supportRegen && isMounted();
379
+ },
380
+ get children() {
381
+ return ssr(_tmpl$2$1, ssrHydrationKey(), escape(createComponent(Show, {
382
+ get when() {
383
+ return timeTravelIsChanging();
384
+ },
385
+ get children() {
386
+ return ssr(_tmpl$$1, ssrHydrationKey(), ssrStyleProperty("left:", `${durationMinutes() ? escape(timeTravelCurrentValue(), true) / escape(durationMinutes(), true) * 100 : 0}%`), escape(secToTimeStr(timeTravelCurrentValue() * 60)));
387
+ }
388
+ })), ssrAttribute("max", escape(durationMinutes(), true), false), ssrAttribute("title", escape(secToTimeStr(timeTravelCurrentValue() * 60), true), false), ssrAttribute("value", escape(timeTravelCurrentValue(), true), false));
389
+ }
390
+ })), ssrStyle(props.live || inTimeMachine() ? {} : {
391
+ display: "none"
392
+ }), escape(secToTimeStr(Math.round(progressMetrics().elapsed / 1e3))), escape(createComponent(Show, {
393
+ get when() {
394
+ return inTimeMachine();
395
+ },
396
+ get fallback() {
397
+ return props.live && !ended() ? ssr(_tmpl$5$1, ssrHydrationKey()) : ssr(_tmpl$6$1, ssrHydrationKey(), ssrStyleProperty("visibility:", "hidden"));
398
+ },
399
+ get children() {
400
+ return ssr(_tmpl$3$1, ssrHydrationKey());
401
+ }
402
+ })), ssrStyle(props.live || inTimeMachine() ? {} : {
403
+ display: "none"
404
+ }), escape(secToTimeStr(Math.round(progressMetrics().remaining / 1e3))));
405
+ }
406
+ var _tmpl$ = ["<th", ' class="srk--nowrap">Time</th>'], _tmpl$2 = ["<div", ' class="srk-common-table srk-main"><table class="', '"><thead><tr><!--$-->', '<!--/--><th class="srk--text-left srk--nowrap">Name</th><th class="srk--nowrap">Score</th><!--$-->', "<!--/--><!--$-->", "<!--/--></tr></thead><tbody>", "</tbody></table></div>"], _tmpl$3 = ["<div", '>srk type "<!--$-->', '<!--/-->" is not supported</div>'], _tmpl$4 = ["<div", '>srk version "<!--$-->', '<!--/-->" is not supported (current supported: <!--$-->', "<!--/-->)</div>"], _tmpl$5 = ["<th", ' class="srk-series-header srk--text-right srk--nowrap">', "</th>"], _tmpl$6 = ["<th", ' class="srk--nowrap srk-problem-header" style="', '">', "</th>"], _tmpl$7 = ["<a", ' target="_blank" rel="noopener noreferrer" style="', '">', "</a>"], _tmpl$8 = ["<td", ' class="srk--text-right srk--nowrap">', "</td>"], _tmpl$9 = ["<tr", "><!--$-->", "<!--/--><!--$-->", '<!--/--><td class="srk--text-right srk--nowrap">', "</td><!--$-->", "<!--/--><!--$-->", "<!--/--></tr>"], _tmpl$10 = ["<td", ' class="', '" style="', '">', "</td>"], _tmpl$11 = ["<td", ' class="', '"><div class="srk-user-cell-content"><!--$-->', '<!--/--><div class="srk-user-body"><div class="srk-user-name-row"><span class="srk-user-name-text"', ">", '</span><span class="srk-marker-dot-group">', "</span></div><!--$-->", "<!--/--></div></div></td>"], _tmpl$12 = ["<div", ' class="srk-user-avatar"><img', ' alt="User Avatar"></div>'], _tmpl$13 = ["<span", ' class="', '" style="', '"', "></span>"], _tmpl$14 = ["<p", ' class="srk-user-secondary-text srk--text-ellipsis" title>', "</p>"], _tmpl$15 = ["<span", ' class="srk--display-block">', "</span>"], _tmpl$16 = ["<span", ' class="srk--display-block srk-problem-stats"', ">", "</span>"], _tmpl$17 = ["<td", ' class="', '">', "</td>"], _tmpl$18 = ["<td", "></td>"], _tmpl$19 = ["<span", ' class="srk-prest-status-block-score">', "</span>"], _tmpl$20 = ["<span", ' class="srk-prest-status-block-score-details">', "</span>"];
407
+ function Ranklist(props) {
408
+ const theme = () => props.theme || EnumTheme.light;
409
+ const showTimeColumn = () => shouldShowTimeColumn(props.data.rows);
410
+ const formatAssetUrl = (url, field) => resolveSrkAssetUrl(url, field, props.formatSrkAssetUrl);
411
+ const emitUserClick = (event, row, rowIndex) => {
412
+ var _a;
413
+ if (event) {
414
+ captureModalTriggerPointFromMouseEvent(event, {
415
+ source: "user-cell",
416
+ context: {
417
+ rowIndex,
418
+ userId: row.user.id || null,
419
+ userName: resolveText(row.user.name)
420
+ }
421
+ });
422
+ }
423
+ (_a = props.onUserClick) == null ? void 0 : _a.call(props, {
424
+ user: row.user,
425
+ row,
426
+ rowIndex,
427
+ ranklist: props.data
428
+ });
429
+ };
430
+ const buildSolutionPayload = (row, rowIndex, status, problemIndex) => ({
431
+ user: row.user,
432
+ row,
433
+ rowIndex,
434
+ problemIndex,
435
+ problem: props.data.problems[problemIndex],
436
+ status,
437
+ solutions: getStatusSolutions(status),
438
+ ranklist: props.data
439
+ });
440
+ const emitSolutionClick = (event, row, rowIndex, status, problemIndex) => {
441
+ var _a, _b;
442
+ const payload = buildSolutionPayload(row, rowIndex, status, problemIndex);
443
+ if (!payload.solutions.length) {
444
+ return;
445
+ }
446
+ if (event) {
447
+ captureModalTriggerPointFromMouseEvent(event, {
448
+ source: "status-cell",
449
+ context: {
450
+ rowIndex,
451
+ problemIndex,
452
+ problemAlias: ((_a = payload.problem) == null ? void 0 : _a.alias) || null,
453
+ problemTitle: payload.problem ? resolveText(payload.problem.title) : null,
454
+ userId: row.user.id || null
455
+ }
456
+ });
457
+ }
458
+ (_b = props.onSolutionClick) == null ? void 0 : _b.call(props, payload);
459
+ };
460
+ return createComponent(Show, {
461
+ get when() {
462
+ return props.data.type === "general";
463
+ },
464
+ get fallback() {
465
+ return ssr(_tmpl$3, ssrHydrationKey(), escape(props.data.type));
466
+ },
467
+ get children() {
468
+ return createComponent(Show, {
469
+ get when() {
470
+ return caniuse(props.data.version);
471
+ },
472
+ get fallback() {
473
+ return ssr(_tmpl$4, ssrHydrationKey(), escape(props.data.version), escape(srkSupportedVersions));
474
+ },
475
+ get children() {
476
+ return ssr(_tmpl$2, ssrHydrationKey(), `${!!props.borderedRows ? "srk-table-row-bordered" : ""} ${!!props.stripedRows ? "srk-table-row-striped" : ""}`, escape(createComponent(For, {
477
+ get each() {
478
+ return props.data.series;
479
+ },
480
+ children: (series) => ssr(_tmpl$5, ssrHydrationKey(), escape(series.title))
481
+ })), escape(createComponent(Show, {
482
+ get when() {
483
+ return showTimeColumn();
484
+ },
485
+ get children() {
486
+ return ssr(_tmpl$, ssrHydrationKey());
487
+ }
488
+ })), escape(createComponent(For, {
489
+ get each() {
490
+ return props.data.problems;
491
+ },
492
+ children: (problem, problemIndex) => {
493
+ var _a;
494
+ const ProblemHeaderCellPart = (_a = props.parts) == null ? void 0 : _a.problemHeaderCell;
495
+ const index = problemIndex();
496
+ return ProblemHeaderCellPart ? createComponent(ProblemHeaderCellPart, {
497
+ problem,
498
+ problemIndex: index,
499
+ index,
500
+ get theme() {
501
+ return theme();
502
+ }
503
+ }) : ssr(_tmpl$6, ssrHydrationKey(), ssrStyleProperty("background-image:", escape(getProblemHeaderBackgroundImage(problem.style, theme()), true)), escape(createComponent(Show, {
504
+ get when() {
505
+ return problem.link;
506
+ },
507
+ get fallback() {
508
+ return createComponent(ProblemHeaderBody, {
509
+ problem,
510
+ index
511
+ });
512
+ },
513
+ children: (link) => ssr(_tmpl$7, ssrHydrationKey() + ssrAttribute("href", escape(link(), true), false), ssrStyleProperty("color:", "unset"), escape(createComponent(ProblemHeaderBody, {
514
+ problem,
515
+ index
516
+ })))
517
+ })));
518
+ }
519
+ })), escape(createComponent(For, {
520
+ get each() {
521
+ return props.data.rows;
522
+ },
523
+ children: (row, rowIndex) => ssr(_tmpl$9, ssrHydrationKey(), escape(createComponent(For, {
524
+ get each() {
525
+ return getRankValues(row, props.data.series);
526
+ },
527
+ children: (rankValue, seriesIndex) => ssr(_tmpl$10, ssrHydrationKey(), `srk--text-right srk--nowrap ${escape(getSeriesSegmentClass(rankValue, props.data.series[seriesIndex()]), true)}`, ssrStyle(getSeriesSegmentStyle(rankValue, props.data.series[seriesIndex()], theme())), escape(getRankText(rankValue, row)))
528
+ })), (() => {
529
+ var _a;
530
+ const UserCellPart = (_a = props.parts) == null ? void 0 : _a.userCell;
531
+ return UserCellPart ? escape(createComponent(UserCellPart, {
532
+ get user() {
533
+ return row.user;
534
+ },
535
+ row,
536
+ get rowIndex() {
537
+ return rowIndex();
538
+ },
539
+ get ranklist() {
540
+ return props.data;
541
+ },
542
+ get markers() {
543
+ return props.data.markers;
544
+ },
545
+ get theme() {
546
+ return theme();
547
+ },
548
+ onClick: (event) => emitUserClick(event, row, rowIndex())
549
+ })) : ssr(_tmpl$11, ssrHydrationKey(), `srk--text-left srk--nowrap srk-user-cell ${!!props.onUserClick ? "srk--cursor-pointer" : ""}`, escape(createComponent(Show, {
550
+ get when() {
551
+ return row.user.avatar;
552
+ },
553
+ children: (avatar) => ssr(_tmpl$12, ssrHydrationKey(), ssrAttribute("src", escape(formatAssetUrl(avatar(), "user.avatar"), true), false))
554
+ })), ssrAttribute("title", escape(resolveText(row.user.name), true), false), escape(resolveText(row.user.name)), escape(createComponent(For, {
555
+ get each() {
556
+ return getResolvedUserMarkers(row.user, props.data.markers, theme());
557
+ },
558
+ children: (entry) => ssr(_tmpl$13, ssrHydrationKey(), `srk-marker srk-marker-dot srk--c-tooltip ${escape(entry.presentation.className || "", true)}`, ssrStyle(getMarkerStyle(entry.presentation.style)), ssrAttribute("data-tooltip", escape(resolveText(entry.marker.label), true), false))
559
+ })), escape(createComponent(Show, {
560
+ get when() {
561
+ return row.user.organization;
562
+ },
563
+ children: (organization) => ssr(_tmpl$14, ssrHydrationKey(), escape(resolveText(organization())))
564
+ })));
565
+ })(), escape(row.score.value), escape(createComponent(Show, {
566
+ get when() {
567
+ return showTimeColumn();
568
+ },
569
+ get children() {
570
+ return ssr(_tmpl$8, ssrHydrationKey(), row.score.time ? escape(formatTimeDuration(row.score.time, "min", Math.floor)) : "-");
571
+ }
572
+ })), escape(createComponent(For, {
573
+ get each() {
574
+ return row.statuses;
575
+ },
576
+ children: (status, problemIndex) => {
577
+ var _a;
578
+ const partProps = {
579
+ status,
580
+ problem: props.data.problems[problemIndex()],
581
+ problemIndex: problemIndex(),
582
+ user: row.user,
583
+ row,
584
+ rowIndex: rowIndex(),
585
+ ranklist: props.data,
586
+ solutions: getStatusSolutions(status),
587
+ onClick: (event) => emitSolutionClick(event, row, rowIndex(), status, problemIndex())
588
+ };
589
+ const StatusCellPart = (_a = props.parts) == null ? void 0 : _a.statusCell;
590
+ return StatusCellPart ? createComponent(StatusCellPart, partProps) : createComponent(StatusCell, mergeProps(partProps, {
591
+ get onSolutionClick() {
592
+ return props.onSolutionClick;
593
+ }
594
+ }));
595
+ }
596
+ })))
597
+ })));
598
+ }
599
+ });
600
+ }
601
+ });
602
+ }
603
+ function ProblemHeaderBody(props) {
604
+ return [ssr(_tmpl$15, ssrHydrationKey(), escape(props.problem.alias || numberToAlphabet(props.index))), createComponent(Show, {
605
+ get when() {
606
+ return props.problem.statistics;
607
+ },
608
+ children: (statistics) => ssr(_tmpl$16, ssrHydrationKey(), ssrAttribute("title", escape(getProblemStatsTitle(statistics()), true), false), escape(statistics().accepted))
609
+ })];
610
+ }
611
+ function getProblemStatsTitle(statistics) {
612
+ const ratio = statistics.submitted ? (statistics.accepted / statistics.submitted * 100).toFixed(1) : 0;
613
+ return `${statistics.accepted} / ${statistics.submitted} (${ratio}%)`;
614
+ }
615
+ function StatusCell(props) {
616
+ const isClickable = () => props.solutions.length > 0 && !!props.onSolutionClick;
617
+ if (props.status.result === "FB") {
618
+ return ssr(_tmpl$17, ssrHydrationKey(), `${escape("srk-prest-status-block srk--text-center srk--nowrap srk-prest-status-block-fb", true)} ${isClickable() ? "srk--cursor-pointer" : ""}`, escape(createComponent(AcceptedStatusBody, {
619
+ get status() {
620
+ return props.status;
621
+ }
622
+ })));
623
+ }
624
+ if (props.status.result === "AC") {
625
+ return ssr(_tmpl$17, ssrHydrationKey(), `${escape("srk-prest-status-block srk--text-center srk--nowrap srk-prest-status-block-accepted", true)} ${isClickable() ? "srk--cursor-pointer" : ""}`, escape(createComponent(AcceptedStatusBody, {
626
+ get status() {
627
+ return props.status;
628
+ }
629
+ })));
630
+ }
631
+ if (props.status.result === "?") {
632
+ return ssr(_tmpl$17, ssrHydrationKey(), `${escape("srk-prest-status-block srk--text-center srk--nowrap srk-prest-status-block-frozen", true)} ${isClickable() ? "srk--cursor-pointer" : ""}`, escape(props.status.tries));
633
+ }
634
+ if (props.status.result === "RJ") {
635
+ return ssr(_tmpl$17, ssrHydrationKey(), `${escape("srk-prest-status-block srk--text-center srk--nowrap srk-prest-status-block-failed", true)} ${isClickable() ? "srk--cursor-pointer" : ""}`, escape(props.status.tries));
636
+ }
637
+ return ssr(_tmpl$18, ssrHydrationKey());
638
+ }
639
+ function AcceptedStatusBody(props) {
640
+ const details = () => getAcceptedStatusDetails(props.status);
641
+ if (typeof props.status.score === "number") {
642
+ return [ssr(_tmpl$19, ssrHydrationKey(), escape(props.status.score)), ssr(_tmpl$20, ssrHydrationKey(), escape(details()))];
643
+ }
644
+ return details();
645
+ }
646
+ function getRankValues(row, series) {
647
+ return row.rankValues || series.map(() => ({
648
+ rank: null,
649
+ segmentIndex: null
650
+ }));
651
+ }
652
+ function getRankText(rankValue, row) {
653
+ return rankValue.rank ? rankValue.rank : row.user.official === false ? "\uFF0A" : "";
654
+ }
655
+ function getStatusSolutions(status) {
656
+ return [...status.solutions || []].reverse();
657
+ }
658
+ function getResolvedUserMarkers(user, markers, theme) {
659
+ return resolveUserMarkers(user, markers).map((marker) => ({
660
+ marker,
661
+ presentation: getMarkerPresentation(marker, theme)
662
+ }));
663
+ }
664
+ function resolveSeriesSegment(rankValue, series) {
665
+ const index = rankValue.segmentIndex || rankValue.segmentIndex === 0 ? rankValue.segmentIndex : -1;
666
+ return ((series == null ? void 0 : series.segments) || [])[index] || {};
667
+ }
668
+ function getSeriesSegmentClass(rankValue, series) {
669
+ const segmentStyle = resolveSeriesSegment(rankValue, series).style;
670
+ return typeof segmentStyle === "string" ? `srk-preset-series-segment-${segmentStyle}` : "";
671
+ }
672
+ function getSeriesSegmentStyle(rankValue, series, theme) {
673
+ const emptyColor = {
674
+ [EnumTheme.light]: void 0,
675
+ [EnumTheme.dark]: void 0
676
+ };
677
+ const segmentStyle = resolveSeriesSegment(rankValue, series).style;
678
+ if (!segmentStyle || typeof segmentStyle === "string") {
679
+ return {};
680
+ }
681
+ const style = resolveStyle(segmentStyle);
682
+ const textColor = style.textColor || emptyColor;
683
+ const backgroundColor = style.backgroundColor || emptyColor;
684
+ return {
685
+ color: textColor[theme],
686
+ "background-color": backgroundColor[theme]
687
+ };
688
+ }
689
+ function getMarkerStyle(style) {
690
+ return (style == null ? void 0 : style.backgroundColor) ? {
691
+ "background-color": style.backgroundColor
692
+ } : {};
693
+ }
694
+ export { DefaultSolutionModal, DefaultUserModal, Modal, ProgressBar, Ranklist };