@algoux/standard-ranklist-renderer-component-angular 0.6.2 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/dist/README.md +13 -0
- package/dist/esm2022/lib/index.mjs +2 -1
- package/dist/esm2022/lib/modal/default-solution-modal.component.mjs +6 -3
- package/dist/esm2022/lib/modal/default-user-modal.component.mjs +23 -15
- package/dist/esm2022/lib/progress/progress-utils.mjs +2 -45
- package/dist/esm2022/lib/ranklist/problem-header-cell-template.directive.mjs +18 -0
- package/dist/esm2022/lib/ranklist/ranklist-utils.mjs +2 -110
- package/dist/esm2022/lib/ranklist/ranklist.component.mjs +161 -65
- package/dist/esm2022/lib/ranklist/status-cell-template.directive.mjs +1 -1
- package/dist/esm2022/lib/ranklist/user-cell-template.directive.mjs +1 -1
- package/dist/esm2022/lib/types.mjs +1 -1
- package/dist/fesm2022/algoux-standard-ranklist-renderer-component-angular.mjs +208 -238
- package/dist/fesm2022/algoux-standard-ranklist-renderer-component-angular.mjs.map +1 -1
- package/dist/lib/index.d.ts +2 -1
- package/dist/lib/modal/default-solution-modal.component.d.ts +2 -1
- package/dist/lib/modal/default-user-modal.component.d.ts +5 -3
- package/dist/lib/progress/progress-bar.component.d.ts +1 -1
- package/dist/lib/progress/progress-utils.d.ts +1 -15
- package/dist/lib/ranklist/problem-header-cell-template.directive.d.ts +20 -0
- package/dist/lib/ranklist/ranklist-utils.d.ts +1 -22
- package/dist/lib/ranklist/ranklist.component.d.ts +12 -2
- package/dist/lib/ranklist/status-cell-template.directive.d.ts +1 -0
- package/dist/lib/ranklist/user-cell-template.directive.d.ts +1 -0
- package/dist/lib/types.d.ts +1 -29
- package/package.json +3 -3
|
@@ -2,116 +2,8 @@ import * as i1 from '@angular/common';
|
|
|
2
2
|
import { CommonModule } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
4
|
import { EventEmitter, ViewChild, Output, Input, Component, inject, TemplateRef, Directive, ContentChild, ChangeDetectionStrategy } from '@angular/core';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
const defaultBackgroundColor = {
|
|
9
|
-
[EnumTheme.light]: '#ffffff',
|
|
10
|
-
[EnumTheme.dark]: '#191919',
|
|
11
|
-
};
|
|
12
|
-
function resolveSrkAssetUrl(url, field, formatter) {
|
|
13
|
-
if (typeof formatter === 'function') {
|
|
14
|
-
return formatter(url, field);
|
|
15
|
-
}
|
|
16
|
-
if (url.startsWith('//')) {
|
|
17
|
-
return url;
|
|
18
|
-
}
|
|
19
|
-
const protocolMatch = url.match(/^([a-zA-Z][a-zA-Z0-9+.-]*):/);
|
|
20
|
-
if (protocolMatch) {
|
|
21
|
-
const protocol = protocolMatch[1].toLowerCase();
|
|
22
|
-
if (protocol === 'http' || protocol === 'https' || protocol === 'data') {
|
|
23
|
-
return url;
|
|
24
|
-
}
|
|
25
|
-
console.warn(`unsupported protocol "${protocol}" in srk asset url:`, url);
|
|
26
|
-
return '';
|
|
27
|
-
}
|
|
28
|
-
console.warn('unsupported srk asset url:', url);
|
|
29
|
-
return '';
|
|
30
|
-
}
|
|
31
|
-
function getAcceptedStatusDetails(status) {
|
|
32
|
-
return `${status.tries}/${status.time ? formatTimeDuration(status.time, 'min', Math.floor) : '-'}`;
|
|
33
|
-
}
|
|
34
|
-
function getSolutionResultMeta(result) {
|
|
35
|
-
switch (result) {
|
|
36
|
-
case 'FB':
|
|
37
|
-
return { label: 'First Blood', className: 'srk-preset-result-fb' };
|
|
38
|
-
case 'AC':
|
|
39
|
-
return { label: 'Accepted', className: 'srk-preset-result-ac' };
|
|
40
|
-
case 'RJ':
|
|
41
|
-
return { label: 'Rejected', className: 'srk-preset-result-rj' };
|
|
42
|
-
case '?':
|
|
43
|
-
return { label: 'Frozen', className: 'srk-preset-result-fz' };
|
|
44
|
-
case 'WA':
|
|
45
|
-
return { label: 'Wrong Answer', className: 'srk-preset-result-rj' };
|
|
46
|
-
case 'PE':
|
|
47
|
-
return { label: 'Presentation Error', className: 'srk-preset-result-rj' };
|
|
48
|
-
case 'TLE':
|
|
49
|
-
return { label: 'Time Limit Exceeded', className: 'srk-preset-result-rj' };
|
|
50
|
-
case 'MLE':
|
|
51
|
-
return { label: 'Memory Limit Exceeded', className: 'srk-preset-result-rj' };
|
|
52
|
-
case 'OLE':
|
|
53
|
-
return { label: 'Output Limit Exceeded', className: 'srk-preset-result-rj' };
|
|
54
|
-
case 'RTE':
|
|
55
|
-
return { label: 'Runtime Error', className: 'srk-preset-result-rj' };
|
|
56
|
-
case 'NOUT':
|
|
57
|
-
return { label: 'No Output' };
|
|
58
|
-
case 'CE':
|
|
59
|
-
return { label: 'Compile Error' };
|
|
60
|
-
case 'UKE':
|
|
61
|
-
return { label: 'Unknown Error' };
|
|
62
|
-
case null:
|
|
63
|
-
return { label: '--' };
|
|
64
|
-
default:
|
|
65
|
-
return { label: result };
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
function getSolutionModalTitle(problemIndex, user) {
|
|
69
|
-
return `Solutions of ${numberToAlphabet(problemIndex)} (${resolveText(user.name)})`;
|
|
70
|
-
}
|
|
71
|
-
function formatSolutionTimestamp(solution) {
|
|
72
|
-
return secToTimeStr(formatTimeDuration(solution.time, 's'));
|
|
73
|
-
}
|
|
74
|
-
function getProblemHeaderBackgroundImage(style, theme) {
|
|
75
|
-
const { backgroundColor } = resolveStyle(style || {});
|
|
76
|
-
const resolvedColor = backgroundColor[theme] || defaultBackgroundColor[theme];
|
|
77
|
-
const bgColorAlphaStr = withAlpha(resolvedColor, 0.27);
|
|
78
|
-
return `linear-gradient(180deg, ${resolvedColor} 0%, ${resolvedColor} 10%, ${bgColorAlphaStr} 10%, transparent 100%)`;
|
|
79
|
-
}
|
|
80
|
-
function getMarkerPresentation(marker, theme) {
|
|
81
|
-
if (typeof marker.style === 'string') {
|
|
82
|
-
return { className: `srk-preset-marker-${marker.style}` };
|
|
83
|
-
}
|
|
84
|
-
if (marker.style) {
|
|
85
|
-
return {
|
|
86
|
-
style: {
|
|
87
|
-
backgroundColor: resolveStyle(marker.style).backgroundColor[theme],
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
return {};
|
|
92
|
-
}
|
|
93
|
-
function shouldShowTimeColumn(rows) {
|
|
94
|
-
return rows.some((row) => Boolean(row.score?.time));
|
|
95
|
-
}
|
|
96
|
-
function withAlpha(color, alpha) {
|
|
97
|
-
const hexMatch = color.match(/^#([0-9a-f]{6})$/i);
|
|
98
|
-
if (hexMatch) {
|
|
99
|
-
const value = hexMatch[1];
|
|
100
|
-
const red = parseInt(value.slice(0, 2), 16);
|
|
101
|
-
const green = parseInt(value.slice(2, 4), 16);
|
|
102
|
-
const blue = parseInt(value.slice(4, 6), 16);
|
|
103
|
-
return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
|
|
104
|
-
}
|
|
105
|
-
const rgbMatch = color.match(/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);
|
|
106
|
-
if (rgbMatch) {
|
|
107
|
-
return `rgba(${rgbMatch[1]}, ${rgbMatch[2]}, ${rgbMatch[3]}, ${alpha})`;
|
|
108
|
-
}
|
|
109
|
-
const rgbaMatch = color.match(/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*[\d.]+\s*\)$/i);
|
|
110
|
-
if (rgbaMatch) {
|
|
111
|
-
return `rgba(${rgbaMatch[1]}, ${rgbaMatch[2]}, ${rgbaMatch[3]}, ${alpha})`;
|
|
112
|
-
}
|
|
113
|
-
return color;
|
|
114
|
-
}
|
|
5
|
+
import { ensureModalInteractionTracker, unlockModalBodyScroll, SRK_ANIMATED_MODAL_ROOT_CLASS, resolveModalTransformOrigin, MODAL_ANIMATION_DURATION_MS, lockModalBodyScroll, registerModalFocusScope, unregisterModalFocusScope, formatSolutionTimestamp, getSolutionModalTitle, getSolutionResultMeta, getMarkerPresentation, resolveSrkAssetUrl, formatTeamMemberName, getProgressDurationMinutes, getProgressMaxAvailableMinutes, isProgressEnded, getProgressMetrics, srkSupportedVersions, calculateProblemStatisticsFooter, caniuse, shouldShowTimeColumn, getProblemHeaderBackgroundImage, calculateDirtPercentage, calculateSEValue, getRankProblemStatusCellPresentation, captureModalTriggerPointFromMouseEvent, formatProblemStatisticsAcceptedMinute, formatProblemStatisticsAverageHardness, formatProblemStatisticsPercent } from '@algoux/standard-ranklist-renderer-component-core';
|
|
6
|
+
import { EnumTheme, resolveUserMarkers, resolveText, secToTimeStr, numberToAlphabet, formatTimeDuration, resolveStyle } from '@algoux/standard-ranklist-utils';
|
|
115
7
|
|
|
116
8
|
class ModalComponent {
|
|
117
9
|
open = false;
|
|
@@ -382,6 +274,7 @@ class DefaultSolutionModalComponent {
|
|
|
382
274
|
rootClassName = 'srk-general-modal-root';
|
|
383
275
|
wrapClassName = 'srk-solutions-modal';
|
|
384
276
|
panelStyle = {};
|
|
277
|
+
languages;
|
|
385
278
|
openChange = new EventEmitter();
|
|
386
279
|
close = new EventEmitter();
|
|
387
280
|
formatSolutionTimestamp = formatSolutionTimestamp;
|
|
@@ -398,7 +291,7 @@ class DefaultSolutionModalComponent {
|
|
|
398
291
|
}
|
|
399
292
|
}
|
|
400
293
|
resolvedTitle() {
|
|
401
|
-
return this.title || (this.cachedUser ? getSolutionModalTitle(this.cachedProblemIndex, this.cachedUser) : '');
|
|
294
|
+
return this.title || (this.cachedUser ? getSolutionModalTitle(this.cachedProblemIndex, this.cachedUser, this.languages) : '');
|
|
402
295
|
}
|
|
403
296
|
solutionMeta(solution) {
|
|
404
297
|
return getSolutionResultMeta(solution.result);
|
|
@@ -407,7 +300,7 @@ class DefaultSolutionModalComponent {
|
|
|
407
300
|
return `${solution.result}_${solution.time?.[0]}_${index}`;
|
|
408
301
|
}
|
|
409
302
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefaultSolutionModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
410
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DefaultSolutionModalComponent, isStandalone: true, selector: "srk-default-solution-modal", inputs: { open: "open", user: "user", problem: "problem", problemIndex: "problemIndex", solutions: "solutions", title: "title", width: "width", rootClassName: "rootClassName", wrapClassName: "wrapClassName", panelStyle: "panelStyle" }, outputs: { openChange: "openChange", close: "close" }, usesOnChanges: true, ngImport: i0, template: `
|
|
303
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DefaultSolutionModalComponent, isStandalone: true, selector: "srk-default-solution-modal", inputs: { open: "open", user: "user", problem: "problem", problemIndex: "problemIndex", solutions: "solutions", title: "title", width: "width", rootClassName: "rootClassName", wrapClassName: "wrapClassName", panelStyle: "panelStyle", languages: "languages" }, outputs: { openChange: "openChange", close: "close" }, usesOnChanges: true, ngImport: i0, template: `
|
|
411
304
|
<srk-modal
|
|
412
305
|
*ngIf="cachedUser"
|
|
413
306
|
[open]="open"
|
|
@@ -505,6 +398,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
505
398
|
type: Input
|
|
506
399
|
}], panelStyle: [{
|
|
507
400
|
type: Input
|
|
401
|
+
}], languages: [{
|
|
402
|
+
type: Input
|
|
508
403
|
}], openChange: [{
|
|
509
404
|
type: Output
|
|
510
405
|
}], close: [{
|
|
@@ -522,9 +417,9 @@ class DefaultUserModalComponent {
|
|
|
522
417
|
wrapClassName = 'srk-user-modal';
|
|
523
418
|
panelStyle = {};
|
|
524
419
|
formatSrkAssetUrl;
|
|
420
|
+
languages;
|
|
525
421
|
openChange = new EventEmitter();
|
|
526
422
|
close = new EventEmitter();
|
|
527
|
-
resolveText = resolveText;
|
|
528
423
|
cachedUser = null;
|
|
529
424
|
ngOnChanges(_changes) {
|
|
530
425
|
if (this.user) {
|
|
@@ -543,14 +438,20 @@ class DefaultUserModalComponent {
|
|
|
543
438
|
formatAssetUrl(url, field) {
|
|
544
439
|
return resolveSrkAssetUrl(url, field, this.formatSrkAssetUrl);
|
|
545
440
|
}
|
|
441
|
+
resolveDisplayText(text) {
|
|
442
|
+
return resolveText(text, this.languages);
|
|
443
|
+
}
|
|
444
|
+
formatMemberName(member) {
|
|
445
|
+
return formatTeamMemberName(member, this.languages);
|
|
446
|
+
}
|
|
546
447
|
trackByMarkerId(_index, entry) {
|
|
547
448
|
return entry.marker.id;
|
|
548
449
|
}
|
|
549
|
-
trackByMemberName(_index, member) {
|
|
550
|
-
return
|
|
551
|
-
}
|
|
450
|
+
trackByMemberName = (_index, member) => {
|
|
451
|
+
return this.resolveDisplayText(member.name);
|
|
452
|
+
};
|
|
552
453
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefaultUserModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
553
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DefaultUserModalComponent, isStandalone: true, selector: "srk-default-user-modal", inputs: { open: "open", user: "user", markers: "markers", theme: "theme", title: "title", width: "width", rootClassName: "rootClassName", wrapClassName: "wrapClassName", panelStyle: "panelStyle", formatSrkAssetUrl: "formatSrkAssetUrl" }, outputs: { openChange: "openChange", close: "close" }, usesOnChanges: true, ngImport: i0, template: `
|
|
454
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DefaultUserModalComponent, isStandalone: true, selector: "srk-default-user-modal", inputs: { open: "open", user: "user", markers: "markers", theme: "theme", title: "title", width: "width", rootClassName: "rootClassName", wrapClassName: "wrapClassName", panelStyle: "panelStyle", formatSrkAssetUrl: "formatSrkAssetUrl", languages: "languages" }, outputs: { openChange: "openChange", close: "close" }, usesOnChanges: true, ngImport: i0, template: `
|
|
554
455
|
<srk-modal
|
|
555
456
|
*ngIf="cachedUser as modalUser"
|
|
556
457
|
[open]="open"
|
|
@@ -563,9 +464,9 @@ class DefaultUserModalComponent {
|
|
|
563
464
|
(openChange)="openChange.emit($event)"
|
|
564
465
|
>
|
|
565
466
|
<div class="srk-user-modal-info">
|
|
566
|
-
<h3 class="srk-user-modal-info-user-name">{{
|
|
467
|
+
<h3 class="srk-user-modal-info-user-name">{{ resolveDisplayText(modalUser.name) }}</h3>
|
|
567
468
|
<p *ngIf="modalUser.organization" class="srk-user-modal-info-user-second-name">
|
|
568
|
-
{{
|
|
469
|
+
{{ resolveDisplayText(modalUser.organization) }}
|
|
569
470
|
</p>
|
|
570
471
|
<div class="srk-user-modal-info-labels">
|
|
571
472
|
<span class="srk-user-modal-info-labels-label srk-user-modal-info-labels-label-preset-general">
|
|
@@ -577,13 +478,13 @@ class DefaultUserModalComponent {
|
|
|
577
478
|
[ngClass]="entry.presentation.className"
|
|
578
479
|
[ngStyle]="entry.presentation.style"
|
|
579
480
|
>
|
|
580
|
-
{{
|
|
481
|
+
{{ resolveDisplayText(entry.marker.label) }}
|
|
581
482
|
</span>
|
|
582
483
|
</div>
|
|
583
484
|
<div *ngIf="modalUser.teamMembers?.length" class="srk-user-modal-info-team-members">
|
|
584
485
|
<ng-container *ngFor="let member of modalUser.teamMembers; let index = index; trackBy: trackByMemberName">
|
|
585
486
|
<span *ngIf="index > 0" class="srk-user-modal-info-team-members-slash"> / </span>
|
|
586
|
-
<span>{{
|
|
487
|
+
<span>{{ formatMemberName(member) }}</span>
|
|
587
488
|
</ng-container>
|
|
588
489
|
</div>
|
|
589
490
|
<div *ngIf="modalUser.photo" class="srk-user-modal-info-photo">
|
|
@@ -616,9 +517,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
616
517
|
(openChange)="openChange.emit($event)"
|
|
617
518
|
>
|
|
618
519
|
<div class="srk-user-modal-info">
|
|
619
|
-
<h3 class="srk-user-modal-info-user-name">{{
|
|
520
|
+
<h3 class="srk-user-modal-info-user-name">{{ resolveDisplayText(modalUser.name) }}</h3>
|
|
620
521
|
<p *ngIf="modalUser.organization" class="srk-user-modal-info-user-second-name">
|
|
621
|
-
{{
|
|
522
|
+
{{ resolveDisplayText(modalUser.organization) }}
|
|
622
523
|
</p>
|
|
623
524
|
<div class="srk-user-modal-info-labels">
|
|
624
525
|
<span class="srk-user-modal-info-labels-label srk-user-modal-info-labels-label-preset-general">
|
|
@@ -630,13 +531,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
630
531
|
[ngClass]="entry.presentation.className"
|
|
631
532
|
[ngStyle]="entry.presentation.style"
|
|
632
533
|
>
|
|
633
|
-
{{
|
|
534
|
+
{{ resolveDisplayText(entry.marker.label) }}
|
|
634
535
|
</span>
|
|
635
536
|
</div>
|
|
636
537
|
<div *ngIf="modalUser.teamMembers?.length" class="srk-user-modal-info-team-members">
|
|
637
538
|
<ng-container *ngFor="let member of modalUser.teamMembers; let index = index; trackBy: trackByMemberName">
|
|
638
539
|
<span *ngIf="index > 0" class="srk-user-modal-info-team-members-slash"> / </span>
|
|
639
|
-
<span>{{
|
|
540
|
+
<span>{{ formatMemberName(member) }}</span>
|
|
640
541
|
</ng-container>
|
|
641
542
|
</div>
|
|
642
543
|
<div *ngIf="modalUser.photo" class="srk-user-modal-info-photo">
|
|
@@ -670,56 +571,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
670
571
|
type: Input
|
|
671
572
|
}], formatSrkAssetUrl: [{
|
|
672
573
|
type: Input
|
|
574
|
+
}], languages: [{
|
|
575
|
+
type: Input
|
|
673
576
|
}], openChange: [{
|
|
674
577
|
type: Output
|
|
675
578
|
}], close: [{
|
|
676
579
|
type: Output
|
|
677
580
|
}] } });
|
|
678
581
|
|
|
679
|
-
function getProgressDurationMinutes(contest) {
|
|
680
|
-
return formatTimeDuration(contest.duration, 'min');
|
|
681
|
-
}
|
|
682
|
-
function getProgressMaxAvailableMinutes(contest, localTime, td = 0) {
|
|
683
|
-
const startAt = new Date(contest.startAt).getTime();
|
|
684
|
-
const currentTime = localTime - td;
|
|
685
|
-
return Math.min(Math.max(Math.floor((currentTime - startAt) / 60000), 0), getProgressDurationMinutes(contest));
|
|
686
|
-
}
|
|
687
|
-
function isProgressEnded(contest, localTime, td = 0) {
|
|
688
|
-
const startAt = new Date(contest.startAt).getTime();
|
|
689
|
-
const endAt = startAt + formatTimeDuration(contest.duration, 'ms');
|
|
690
|
-
const currentTime = localTime - td;
|
|
691
|
-
return currentTime >= endAt;
|
|
692
|
-
}
|
|
693
|
-
function getProgressMetrics(data, localTime, td, timeTravelCurrentValue, inTimeMachine) {
|
|
694
|
-
const { contest } = data;
|
|
695
|
-
const startAt = new Date(contest.startAt).getTime();
|
|
696
|
-
const endAt = startAt + formatTimeDuration(contest.duration, 'ms');
|
|
697
|
-
const frozenLength = contest.frozenDuration ? formatTimeDuration(contest.frozenDuration, 'ms') : 0;
|
|
698
|
-
const currentTime = localTime - td;
|
|
699
|
-
const length = endAt - startAt;
|
|
700
|
-
const frozenBreakpoint = length ? 1 - frozenLength / length : 1;
|
|
701
|
-
const elapsed = Math.min(Math.max(currentTime - startAt, 0), length);
|
|
702
|
-
const remaining = length - elapsed;
|
|
703
|
-
const frozenAt = endAt - frozenLength;
|
|
704
|
-
const percent = length ? (elapsed / length) * 100 : 0;
|
|
705
|
-
const normalPercent = length ? (Math.max(Math.min(currentTime, frozenAt) - startAt, 0) / length) * 100 : 0;
|
|
706
|
-
const normalInnerPercent = Math.min(100, frozenBreakpoint ? normalPercent / frozenBreakpoint : 0);
|
|
707
|
-
const frozenPercent = percent - normalPercent;
|
|
708
|
-
const frozenInnerPercent = Math.min(100, 1 - frozenBreakpoint ? frozenPercent / (1 - frozenBreakpoint) : 0);
|
|
709
|
-
const timeTravelElapsed = timeTravelCurrentValue * 60 * 1000;
|
|
710
|
-
const timeTravelRemaining = length - timeTravelElapsed;
|
|
711
|
-
return {
|
|
712
|
-
elapsed: inTimeMachine ? timeTravelElapsed : elapsed,
|
|
713
|
-
remaining: inTimeMachine ? timeTravelRemaining : remaining,
|
|
714
|
-
frozenBreakpoint,
|
|
715
|
-
normalInnerPercent,
|
|
716
|
-
frozenInnerPercent,
|
|
717
|
-
timeTravelElapsed,
|
|
718
|
-
timeTravelRemaining,
|
|
719
|
-
supportRegen: canRegenerateRanklist(data),
|
|
720
|
-
};
|
|
721
|
-
}
|
|
722
|
-
|
|
723
582
|
class ProgressBarComponent {
|
|
724
583
|
data;
|
|
725
584
|
enableTimeTravel = false;
|
|
@@ -961,6 +820,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
961
820
|
type: Output
|
|
962
821
|
}] } });
|
|
963
822
|
|
|
823
|
+
class SrkProblemHeaderCellTemplateDirective {
|
|
824
|
+
templateRef = inject(TemplateRef);
|
|
825
|
+
static ngTemplateContextGuard(_directive, context) {
|
|
826
|
+
return true;
|
|
827
|
+
}
|
|
828
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SrkProblemHeaderCellTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
829
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: SrkProblemHeaderCellTemplateDirective, isStandalone: true, selector: "ng-template[srkProblemHeaderCell]", ngImport: i0 });
|
|
830
|
+
}
|
|
831
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: SrkProblemHeaderCellTemplateDirective, decorators: [{
|
|
832
|
+
type: Directive,
|
|
833
|
+
args: [{
|
|
834
|
+
selector: 'ng-template[srkProblemHeaderCell]',
|
|
835
|
+
standalone: true,
|
|
836
|
+
}]
|
|
837
|
+
}] });
|
|
838
|
+
|
|
964
839
|
class SrkStatusCellTemplateDirective {
|
|
965
840
|
templateRef = inject(TemplateRef);
|
|
966
841
|
static ngTemplateContextGuard(_directive, context) {
|
|
@@ -1009,8 +884,11 @@ class RanklistComponent {
|
|
|
1009
884
|
showSEColumn = false;
|
|
1010
885
|
emptyStatusPlaceholder = null;
|
|
1011
886
|
userAvatarPlacement = 'user';
|
|
887
|
+
languages;
|
|
1012
888
|
userClick = new EventEmitter();
|
|
889
|
+
problemClick = new EventEmitter();
|
|
1013
890
|
solutionClick = new EventEmitter();
|
|
891
|
+
problemHeaderCellTemplate;
|
|
1014
892
|
statusCellTemplate;
|
|
1015
893
|
userCellTemplate;
|
|
1016
894
|
supportedVersions = srkSupportedVersions;
|
|
@@ -1023,8 +901,8 @@ class RanklistComponent {
|
|
|
1023
901
|
tooltip: 'Number of participants who solved this problem',
|
|
1024
902
|
},
|
|
1025
903
|
{
|
|
1026
|
-
key: '
|
|
1027
|
-
label: '
|
|
904
|
+
key: 'attempted',
|
|
905
|
+
label: 'Attempted',
|
|
1028
906
|
tooltip: 'Number of participants who attempted this problem',
|
|
1029
907
|
},
|
|
1030
908
|
{
|
|
@@ -1069,7 +947,7 @@ class RanklistComponent {
|
|
|
1069
947
|
return caniuse(this.data.version);
|
|
1070
948
|
}
|
|
1071
949
|
showTimeColumn() {
|
|
1072
|
-
return shouldShowTimeColumn
|
|
950
|
+
return shouldShowTimeColumn(this.data.rows);
|
|
1073
951
|
}
|
|
1074
952
|
showAvatarInOrganization() {
|
|
1075
953
|
return this.splitOrganization && this.userAvatarPlacement === 'organization';
|
|
@@ -1084,7 +962,7 @@ class RanklistComponent {
|
|
|
1084
962
|
return rankValue.rank ? rankValue.rank : row.user.official === false ? '*' : '';
|
|
1085
963
|
}
|
|
1086
964
|
resolveDisplayText(text) {
|
|
1087
|
-
return resolveText(text);
|
|
965
|
+
return resolveText(text, this.languages);
|
|
1088
966
|
}
|
|
1089
967
|
resolveSeriesColumnTitle(series, index) {
|
|
1090
968
|
const seriesTitles = this.columnTitles?.series;
|
|
@@ -1107,16 +985,16 @@ class RanklistComponent {
|
|
|
1107
985
|
return `${statistics.accepted} / ${statistics.submitted} (${ratio}%)`;
|
|
1108
986
|
}
|
|
1109
987
|
problemHeaderBackgroundImage(problem, gradientDirection = 180) {
|
|
1110
|
-
return getProblemHeaderBackgroundImage
|
|
988
|
+
return getProblemHeaderBackgroundImage(problem.style, this.theme, gradientDirection);
|
|
1111
989
|
}
|
|
1112
990
|
resolvedUserMarkers(user) {
|
|
1113
991
|
return resolveUserMarkers(user, this.data.markers).map((marker) => ({
|
|
1114
992
|
marker,
|
|
1115
|
-
presentation: getMarkerPresentation
|
|
993
|
+
presentation: getMarkerPresentation(marker, this.theme),
|
|
1116
994
|
}));
|
|
1117
995
|
}
|
|
1118
996
|
formatAssetUrl(url, field) {
|
|
1119
|
-
return resolveSrkAssetUrl
|
|
997
|
+
return resolveSrkAssetUrl(url, field, this.formatSrkAssetUrl);
|
|
1120
998
|
}
|
|
1121
999
|
formatTime(time) {
|
|
1122
1000
|
return formatTimeDuration(time, 'min', Math.floor);
|
|
@@ -1167,6 +1045,27 @@ class RanklistComponent {
|
|
|
1167
1045
|
statusCellTabIndex(status) {
|
|
1168
1046
|
return this.isStatusClickable(status) ? 0 : null;
|
|
1169
1047
|
}
|
|
1048
|
+
hasProblemClickListener() {
|
|
1049
|
+
const emitter = this.problemClick;
|
|
1050
|
+
return emitter.observed === true || Boolean(emitter.observers?.length);
|
|
1051
|
+
}
|
|
1052
|
+
problemHeaderRole() {
|
|
1053
|
+
return this.hasProblemClickListener() ? 'button' : null;
|
|
1054
|
+
}
|
|
1055
|
+
problemHeaderTabIndex() {
|
|
1056
|
+
return this.hasProblemClickListener() ? 0 : null;
|
|
1057
|
+
}
|
|
1058
|
+
buildProblemHeaderCellContext(problem, problemIndex) {
|
|
1059
|
+
return {
|
|
1060
|
+
$implicit: problem,
|
|
1061
|
+
problem,
|
|
1062
|
+
problemIndex,
|
|
1063
|
+
index: problemIndex,
|
|
1064
|
+
ranklist: this.data,
|
|
1065
|
+
languages: this.languages,
|
|
1066
|
+
onClick: (event) => this.emitProblemClick(event, problem, problemIndex),
|
|
1067
|
+
};
|
|
1068
|
+
}
|
|
1170
1069
|
buildUserCellContext(row, rowIndex) {
|
|
1171
1070
|
return {
|
|
1172
1071
|
$implicit: row.user,
|
|
@@ -1177,6 +1076,7 @@ class RanklistComponent {
|
|
|
1177
1076
|
markers: this.data.markers,
|
|
1178
1077
|
hideOrganization: this.splitOrganization,
|
|
1179
1078
|
hideAvatar: this.showAvatarInOrganization(),
|
|
1079
|
+
languages: this.languages,
|
|
1180
1080
|
onClick: (event) => this.emitUserClick(event, row, rowIndex),
|
|
1181
1081
|
};
|
|
1182
1082
|
}
|
|
@@ -1194,6 +1094,7 @@ class RanklistComponent {
|
|
|
1194
1094
|
statusCellPreset: this.statusCellPreset,
|
|
1195
1095
|
statusColorAsText: this.statusColorAsText,
|
|
1196
1096
|
emptyStatusPlaceholder: this.emptyStatusPlaceholder,
|
|
1097
|
+
languages: this.languages,
|
|
1197
1098
|
onClick: (event) => this.emitSolutionClick(event, row, rowIndex, status, problemIndex),
|
|
1198
1099
|
};
|
|
1199
1100
|
}
|
|
@@ -1201,6 +1102,13 @@ class RanklistComponent {
|
|
|
1201
1102
|
event.preventDefault();
|
|
1202
1103
|
this.emitUserClick(undefined, row, rowIndex);
|
|
1203
1104
|
}
|
|
1105
|
+
activateProblemHeaderFromKeyboard(event, problem, problemIndex) {
|
|
1106
|
+
if (!this.hasProblemClickListener()) {
|
|
1107
|
+
return;
|
|
1108
|
+
}
|
|
1109
|
+
event.preventDefault();
|
|
1110
|
+
this.emitProblemClick(undefined, problem, problemIndex);
|
|
1111
|
+
}
|
|
1204
1112
|
activateStatusCellFromKeyboard(event, row, rowIndex, status, problemIndex) {
|
|
1205
1113
|
event.preventDefault();
|
|
1206
1114
|
this.emitSolutionClick(undefined, row, rowIndex, status, problemIndex);
|
|
@@ -1223,6 +1131,27 @@ class RanklistComponent {
|
|
|
1223
1131
|
ranklist: this.data,
|
|
1224
1132
|
});
|
|
1225
1133
|
}
|
|
1134
|
+
emitProblemClick(event, problem, problemIndex) {
|
|
1135
|
+
if (!this.hasProblemClickListener()) {
|
|
1136
|
+
return;
|
|
1137
|
+
}
|
|
1138
|
+
if (event) {
|
|
1139
|
+
event.preventDefault();
|
|
1140
|
+
captureModalTriggerPointFromMouseEvent(event, {
|
|
1141
|
+
source: 'problem-header',
|
|
1142
|
+
context: {
|
|
1143
|
+
problemIndex,
|
|
1144
|
+
problemAlias: problem.alias || null,
|
|
1145
|
+
problemTitle: this.resolveDisplayText(problem.title) || null,
|
|
1146
|
+
},
|
|
1147
|
+
});
|
|
1148
|
+
}
|
|
1149
|
+
this.problemClick.emit({
|
|
1150
|
+
problem,
|
|
1151
|
+
problemIndex,
|
|
1152
|
+
ranklist: this.data,
|
|
1153
|
+
});
|
|
1154
|
+
}
|
|
1226
1155
|
emitSolutionClick(event, row, rowIndex, status, problemIndex) {
|
|
1227
1156
|
const solutions = this.getStatusSolutions(status);
|
|
1228
1157
|
if (!solutions.length) {
|
|
@@ -1283,8 +1212,8 @@ class RanklistComponent {
|
|
|
1283
1212
|
switch (key) {
|
|
1284
1213
|
case 'accepted':
|
|
1285
1214
|
return stat.accepted;
|
|
1286
|
-
case '
|
|
1287
|
-
return stat.
|
|
1215
|
+
case 'attempted':
|
|
1216
|
+
return stat.attempted;
|
|
1288
1217
|
case 'submitted':
|
|
1289
1218
|
return stat.submitted;
|
|
1290
1219
|
case 'dirt':
|
|
@@ -1303,8 +1232,8 @@ class RanklistComponent {
|
|
|
1303
1232
|
switch (key) {
|
|
1304
1233
|
case 'accepted':
|
|
1305
1234
|
return formatProblemStatisticsPercent(stat.accepted, stat.participantCount);
|
|
1306
|
-
case '
|
|
1307
|
-
return formatProblemStatisticsPercent(stat.
|
|
1235
|
+
case 'attempted':
|
|
1236
|
+
return formatProblemStatisticsPercent(stat.attempted, stat.participantCount);
|
|
1308
1237
|
case 'dirt':
|
|
1309
1238
|
return formatProblemStatisticsPercent(stat.dirt, stat.dirtSubmitted);
|
|
1310
1239
|
default:
|
|
@@ -1312,7 +1241,7 @@ class RanklistComponent {
|
|
|
1312
1241
|
}
|
|
1313
1242
|
}
|
|
1314
1243
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RanklistComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1315
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: RanklistComponent, isStandalone: true, selector: "srk-ranklist", inputs: { data: "data", theme: "theme", rowBordered: "rowBordered", columnBordered: "columnBordered", rowStriped: "rowStriped", formatSrkAssetUrl: "formatSrkAssetUrl", splitOrganization: "splitOrganization", columnTitles: "columnTitles", statusCellPreset: "statusCellPreset", statusColorAsText: "statusColorAsText", showProblemStatisticsFooter: "showProblemStatisticsFooter", showDirtColumn: "showDirtColumn", showSEColumn: "showSEColumn", emptyStatusPlaceholder: "emptyStatusPlaceholder", userAvatarPlacement: "userAvatarPlacement" }, outputs: { userClick: "userClick", solutionClick: "solutionClick" }, queries: [{ propertyName: "statusCellTemplate", first: true, predicate: SrkStatusCellTemplateDirective, descendants: true }, { propertyName: "userCellTemplate", first: true, predicate: SrkUserCellTemplateDirective, descendants: true }], ngImport: i0, template: `
|
|
1244
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: RanklistComponent, isStandalone: true, selector: "srk-ranklist", inputs: { data: "data", theme: "theme", rowBordered: "rowBordered", columnBordered: "columnBordered", rowStriped: "rowStriped", formatSrkAssetUrl: "formatSrkAssetUrl", splitOrganization: "splitOrganization", columnTitles: "columnTitles", statusCellPreset: "statusCellPreset", statusColorAsText: "statusColorAsText", showProblemStatisticsFooter: "showProblemStatisticsFooter", showDirtColumn: "showDirtColumn", showSEColumn: "showSEColumn", emptyStatusPlaceholder: "emptyStatusPlaceholder", userAvatarPlacement: "userAvatarPlacement", languages: "languages" }, outputs: { userClick: "userClick", problemClick: "problemClick", solutionClick: "solutionClick" }, queries: [{ propertyName: "problemHeaderCellTemplate", first: true, predicate: SrkProblemHeaderCellTemplateDirective, descendants: true }, { propertyName: "statusCellTemplate", first: true, predicate: SrkStatusCellTemplateDirective, descendants: true }, { propertyName: "userCellTemplate", first: true, predicate: SrkUserCellTemplateDirective, descendants: true }], ngImport: i0, template: `
|
|
1316
1245
|
<div *ngIf="data.type !== 'general'; else versionState">
|
|
1317
1246
|
srk type "{{ data.type }}" is not supported
|
|
1318
1247
|
</div>
|
|
@@ -1350,38 +1279,55 @@ class RanklistComponent {
|
|
|
1350
1279
|
<th *ngIf="showTimeColumn()" class="srk--text-right srk--nowrap">
|
|
1351
1280
|
{{ resolveColumnTitle('time', 'Time') }}
|
|
1352
1281
|
</th>
|
|
1353
|
-
<
|
|
1282
|
+
<ng-container
|
|
1354
1283
|
*ngFor="let problem of data.problems; let problemIndex = index"
|
|
1355
|
-
class="srk--nowrap srk-problem-header"
|
|
1356
|
-
[style.background-image]="problemHeaderBackgroundImage(problem)"
|
|
1357
1284
|
>
|
|
1358
|
-
<
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
>
|
|
1365
|
-
<
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
[
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
<ng-template #unlinkedProblemHeader>
|
|
1375
|
-
<span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
|
|
1376
|
-
<span
|
|
1377
|
-
*ngIf="problem.statistics"
|
|
1378
|
-
class="srk--display-block srk-problem-stats"
|
|
1379
|
-
[title]="problemStatsTitle(problem.statistics)"
|
|
1285
|
+
<ng-container *ngIf="problemHeaderCellTemplate; else defaultProblemHeader">
|
|
1286
|
+
<ng-container
|
|
1287
|
+
[ngTemplateOutlet]="problemHeaderCellTemplate.templateRef"
|
|
1288
|
+
[ngTemplateOutletContext]="buildProblemHeaderCellContext(problem, problemIndex)"
|
|
1289
|
+
/>
|
|
1290
|
+
</ng-container>
|
|
1291
|
+
<ng-template #defaultProblemHeader>
|
|
1292
|
+
<th
|
|
1293
|
+
class="srk--nowrap srk-problem-header"
|
|
1294
|
+
[class.srk--cursor-pointer]="hasProblemClickListener()"
|
|
1295
|
+
[attr.role]="problemHeaderRole()"
|
|
1296
|
+
[attr.tabindex]="problemHeaderTabIndex()"
|
|
1297
|
+
[style.background-image]="problemHeaderBackgroundImage(problem)"
|
|
1298
|
+
(click)="emitProblemClick($event, problem, problemIndex)"
|
|
1299
|
+
(keydown.enter)="activateProblemHeaderFromKeyboard($event, problem, problemIndex)"
|
|
1300
|
+
(keydown.space)="activateProblemHeaderFromKeyboard($event, problem, problemIndex)"
|
|
1380
1301
|
>
|
|
1381
|
-
|
|
1382
|
-
|
|
1302
|
+
<a
|
|
1303
|
+
*ngIf="problem.link && !hasProblemClickListener(); else unlinkedProblemHeader"
|
|
1304
|
+
[href]="problem.link"
|
|
1305
|
+
target="_blank"
|
|
1306
|
+
rel="noopener noreferrer"
|
|
1307
|
+
style="color: unset"
|
|
1308
|
+
>
|
|
1309
|
+
<span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
|
|
1310
|
+
<span
|
|
1311
|
+
*ngIf="problem.statistics"
|
|
1312
|
+
class="srk--display-block srk-problem-stats"
|
|
1313
|
+
[title]="problemStatsTitle(problem.statistics)"
|
|
1314
|
+
>
|
|
1315
|
+
{{ problem.statistics.accepted }}
|
|
1316
|
+
</span>
|
|
1317
|
+
</a>
|
|
1318
|
+
<ng-template #unlinkedProblemHeader>
|
|
1319
|
+
<span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
|
|
1320
|
+
<span
|
|
1321
|
+
*ngIf="problem.statistics"
|
|
1322
|
+
class="srk--display-block srk-problem-stats"
|
|
1323
|
+
[title]="problemStatsTitle(problem.statistics)"
|
|
1324
|
+
>
|
|
1325
|
+
{{ problem.statistics.accepted }}
|
|
1326
|
+
</span>
|
|
1327
|
+
</ng-template>
|
|
1328
|
+
</th>
|
|
1383
1329
|
</ng-template>
|
|
1384
|
-
</
|
|
1330
|
+
</ng-container>
|
|
1385
1331
|
<th *ngIf="showDirtColumn" class="srk-dirt-header srk--text-right srk--nowrap">
|
|
1386
1332
|
{{ resolveColumnTitle('dirt', 'Dirt') }}
|
|
1387
1333
|
</th>
|
|
@@ -1673,38 +1619,55 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1673
1619
|
<th *ngIf="showTimeColumn()" class="srk--text-right srk--nowrap">
|
|
1674
1620
|
{{ resolveColumnTitle('time', 'Time') }}
|
|
1675
1621
|
</th>
|
|
1676
|
-
<
|
|
1622
|
+
<ng-container
|
|
1677
1623
|
*ngFor="let problem of data.problems; let problemIndex = index"
|
|
1678
|
-
class="srk--nowrap srk-problem-header"
|
|
1679
|
-
[style.background-image]="problemHeaderBackgroundImage(problem)"
|
|
1680
1624
|
>
|
|
1681
|
-
<
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
>
|
|
1688
|
-
<
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
[
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
<ng-template #unlinkedProblemHeader>
|
|
1698
|
-
<span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
|
|
1699
|
-
<span
|
|
1700
|
-
*ngIf="problem.statistics"
|
|
1701
|
-
class="srk--display-block srk-problem-stats"
|
|
1702
|
-
[title]="problemStatsTitle(problem.statistics)"
|
|
1625
|
+
<ng-container *ngIf="problemHeaderCellTemplate; else defaultProblemHeader">
|
|
1626
|
+
<ng-container
|
|
1627
|
+
[ngTemplateOutlet]="problemHeaderCellTemplate.templateRef"
|
|
1628
|
+
[ngTemplateOutletContext]="buildProblemHeaderCellContext(problem, problemIndex)"
|
|
1629
|
+
/>
|
|
1630
|
+
</ng-container>
|
|
1631
|
+
<ng-template #defaultProblemHeader>
|
|
1632
|
+
<th
|
|
1633
|
+
class="srk--nowrap srk-problem-header"
|
|
1634
|
+
[class.srk--cursor-pointer]="hasProblemClickListener()"
|
|
1635
|
+
[attr.role]="problemHeaderRole()"
|
|
1636
|
+
[attr.tabindex]="problemHeaderTabIndex()"
|
|
1637
|
+
[style.background-image]="problemHeaderBackgroundImage(problem)"
|
|
1638
|
+
(click)="emitProblemClick($event, problem, problemIndex)"
|
|
1639
|
+
(keydown.enter)="activateProblemHeaderFromKeyboard($event, problem, problemIndex)"
|
|
1640
|
+
(keydown.space)="activateProblemHeaderFromKeyboard($event, problem, problemIndex)"
|
|
1703
1641
|
>
|
|
1704
|
-
|
|
1705
|
-
|
|
1642
|
+
<a
|
|
1643
|
+
*ngIf="problem.link && !hasProblemClickListener(); else unlinkedProblemHeader"
|
|
1644
|
+
[href]="problem.link"
|
|
1645
|
+
target="_blank"
|
|
1646
|
+
rel="noopener noreferrer"
|
|
1647
|
+
style="color: unset"
|
|
1648
|
+
>
|
|
1649
|
+
<span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
|
|
1650
|
+
<span
|
|
1651
|
+
*ngIf="problem.statistics"
|
|
1652
|
+
class="srk--display-block srk-problem-stats"
|
|
1653
|
+
[title]="problemStatsTitle(problem.statistics)"
|
|
1654
|
+
>
|
|
1655
|
+
{{ problem.statistics.accepted }}
|
|
1656
|
+
</span>
|
|
1657
|
+
</a>
|
|
1658
|
+
<ng-template #unlinkedProblemHeader>
|
|
1659
|
+
<span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
|
|
1660
|
+
<span
|
|
1661
|
+
*ngIf="problem.statistics"
|
|
1662
|
+
class="srk--display-block srk-problem-stats"
|
|
1663
|
+
[title]="problemStatsTitle(problem.statistics)"
|
|
1664
|
+
>
|
|
1665
|
+
{{ problem.statistics.accepted }}
|
|
1666
|
+
</span>
|
|
1667
|
+
</ng-template>
|
|
1668
|
+
</th>
|
|
1706
1669
|
</ng-template>
|
|
1707
|
-
</
|
|
1670
|
+
</ng-container>
|
|
1708
1671
|
<th *ngIf="showDirtColumn" class="srk-dirt-header srk--text-right srk--nowrap">
|
|
1709
1672
|
{{ resolveColumnTitle('dirt', 'Dirt') }}
|
|
1710
1673
|
</th>
|
|
@@ -1982,10 +1945,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1982
1945
|
type: Input
|
|
1983
1946
|
}], userAvatarPlacement: [{
|
|
1984
1947
|
type: Input
|
|
1948
|
+
}], languages: [{
|
|
1949
|
+
type: Input
|
|
1985
1950
|
}], userClick: [{
|
|
1986
1951
|
type: Output
|
|
1952
|
+
}], problemClick: [{
|
|
1953
|
+
type: Output
|
|
1987
1954
|
}], solutionClick: [{
|
|
1988
1955
|
type: Output
|
|
1956
|
+
}], problemHeaderCellTemplate: [{
|
|
1957
|
+
type: ContentChild,
|
|
1958
|
+
args: [SrkProblemHeaderCellTemplateDirective]
|
|
1989
1959
|
}], statusCellTemplate: [{
|
|
1990
1960
|
type: ContentChild,
|
|
1991
1961
|
args: [SrkStatusCellTemplateDirective]
|
|
@@ -1998,5 +1968,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1998
1968
|
* Generated bundle index. Do not edit.
|
|
1999
1969
|
*/
|
|
2000
1970
|
|
|
2001
|
-
export { DefaultSolutionModalComponent, DefaultUserModalComponent, ModalComponent, ProgressBarComponent, RanklistComponent, SrkStatusCellTemplateDirective, SrkUserCellTemplateDirective };
|
|
1971
|
+
export { DefaultSolutionModalComponent, DefaultUserModalComponent, ModalComponent, ProgressBarComponent, RanklistComponent, SrkProblemHeaderCellTemplateDirective, SrkStatusCellTemplateDirective, SrkUserCellTemplateDirective };
|
|
2002
1972
|
//# sourceMappingURL=algoux-standard-ranklist-renderer-component-angular.mjs.map
|