@xcpcio/core 0.32.0 → 0.33.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.
- package/dist/index.cjs +32 -12
- package/dist/index.d.ts +6 -3
- package/dist/index.mjs +31 -13
- package/package.json +6 -2
- package/src/balloon.ts +4 -0
- package/src/problem.ts +17 -18
- package/src/rank.ts +2 -2
- package/src/utils/color.ts +16 -0
- package/src/utils/index.ts +1 -0
package/dist/index.cjs
CHANGED
|
@@ -15,6 +15,8 @@ const relativeTime = require('dayjs/plugin/relativeTime');
|
|
|
15
15
|
const _ = require('lodash');
|
|
16
16
|
const XLSX = require('xlsx-js-style');
|
|
17
17
|
const stringWidth = require('string-width');
|
|
18
|
+
const colorDiff = require('color-diff');
|
|
19
|
+
const chroma = require('chroma-js');
|
|
18
20
|
|
|
19
21
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e["default"] : e; }
|
|
20
22
|
|
|
@@ -42,6 +44,7 @@ const relativeTime__default = /*#__PURE__*/_interopDefaultLegacy(relativeTime);
|
|
|
42
44
|
const ___default = /*#__PURE__*/_interopDefaultLegacy(_);
|
|
43
45
|
const XLSX__namespace = /*#__PURE__*/_interopNamespace(XLSX);
|
|
44
46
|
const stringWidth__default = /*#__PURE__*/_interopDefaultLegacy(stringWidth);
|
|
47
|
+
const chroma__default = /*#__PURE__*/_interopDefaultLegacy(chroma);
|
|
45
48
|
|
|
46
49
|
function stringToSubmissionStatus(status) {
|
|
47
50
|
status = status.toUpperCase().replace(" ", "_");
|
|
@@ -462,6 +465,18 @@ function calcDirt(attemptedNum, solvedNum) {
|
|
|
462
465
|
return Math.floor((attemptedNum - solvedNum) * 100 / attemptedNum);
|
|
463
466
|
}
|
|
464
467
|
|
|
468
|
+
function getWhiteOrBlackColor(background) {
|
|
469
|
+
const [R, G, B] = chroma__default(background).rgb();
|
|
470
|
+
const color = { R, G, B };
|
|
471
|
+
const palette = [{ R: 0, G: 0, B: 0 }, { R: 255, G: 255, B: 255 }];
|
|
472
|
+
const f = colorDiff.furthest(color, palette);
|
|
473
|
+
if (f.R === 0 && f.G === 0 && f.B === 0) {
|
|
474
|
+
return "#000";
|
|
475
|
+
} else {
|
|
476
|
+
return "#fff";
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
465
480
|
class ProblemStatistics {
|
|
466
481
|
constructor() {
|
|
467
482
|
this.acceptedNum = 0;
|
|
@@ -496,6 +511,10 @@ class Problem {
|
|
|
496
511
|
this.label = "";
|
|
497
512
|
this.name = "";
|
|
498
513
|
this.statistics = new ProblemStatistics();
|
|
514
|
+
this.balloonColor = {
|
|
515
|
+
background_color: "#a0f0a0",
|
|
516
|
+
color: "#000"
|
|
517
|
+
};
|
|
499
518
|
}
|
|
500
519
|
}
|
|
501
520
|
function createProblem(problemJSON) {
|
|
@@ -505,20 +524,14 @@ function createProblem(problemJSON) {
|
|
|
505
524
|
p.name = problemJSON.name ?? "";
|
|
506
525
|
p.timeLimit = problemJSON.time_limit;
|
|
507
526
|
p.memoryLimit = problemJSON.memory_limit;
|
|
508
|
-
|
|
527
|
+
if (problemJSON.balloon_color) {
|
|
528
|
+
p.balloonColor = problemJSON.balloon_color;
|
|
529
|
+
}
|
|
530
|
+
p.balloonColor.color = getWhiteOrBlackColor(p.balloonColor.background_color);
|
|
509
531
|
return p;
|
|
510
532
|
}
|
|
511
533
|
function createProblems(problemsJSON) {
|
|
512
|
-
return problemsJSON.map((pJSON) =>
|
|
513
|
-
const p = new Problem();
|
|
514
|
-
p.id = pJSON.id;
|
|
515
|
-
p.label = pJSON.label;
|
|
516
|
-
p.name = pJSON.name ?? "";
|
|
517
|
-
p.timeLimit = pJSON.time_limit;
|
|
518
|
-
p.memoryLimit = pJSON.memory_limit;
|
|
519
|
-
p.balloonColor = pJSON.balloon_color;
|
|
520
|
-
return p;
|
|
521
|
-
});
|
|
534
|
+
return problemsJSON.map((pJSON) => createProblem(pJSON));
|
|
522
535
|
}
|
|
523
536
|
function createProblemsByProblemIds(problemIds, balloonColors) {
|
|
524
537
|
const problems = problemIds.map((label, index) => {
|
|
@@ -532,6 +545,9 @@ function createProblemsByProblemIds(problemIds, balloonColors) {
|
|
|
532
545
|
problems[index].balloonColor = balloonColors[index];
|
|
533
546
|
}
|
|
534
547
|
}
|
|
548
|
+
problems.forEach((p) => {
|
|
549
|
+
p.balloonColor.color = getWhiteOrBlackColor(p.balloonColor.background_color);
|
|
550
|
+
});
|
|
535
551
|
return problems;
|
|
536
552
|
}
|
|
537
553
|
class TeamProblemStatistics {
|
|
@@ -871,6 +887,9 @@ class Balloon {
|
|
|
871
887
|
get key() {
|
|
872
888
|
return `balloon-${this.team.id}-${this.problem.id}`;
|
|
873
889
|
}
|
|
890
|
+
static compare(lhs, rhs) {
|
|
891
|
+
return Submission.compare(lhs.submission, rhs.submission);
|
|
892
|
+
}
|
|
874
893
|
}
|
|
875
894
|
|
|
876
895
|
class Group {
|
|
@@ -1190,7 +1209,7 @@ class RankOptions {
|
|
|
1190
1209
|
this.filterOrganizationMap = /* @__PURE__ */ new Map();
|
|
1191
1210
|
this.filterTeams = [];
|
|
1192
1211
|
this.filterTeamMap = /* @__PURE__ */ new Map();
|
|
1193
|
-
this.
|
|
1212
|
+
this.enableAnimatedSubmissions = false;
|
|
1194
1213
|
}
|
|
1195
1214
|
setWidth(width, contest) {
|
|
1196
1215
|
this.width = width;
|
|
@@ -1646,6 +1665,7 @@ exports.createTeams = createTeams;
|
|
|
1646
1665
|
exports.getImageSource = getImageSource;
|
|
1647
1666
|
exports.getTimeDiff = getTimeDiff;
|
|
1648
1667
|
exports.getTimestamp = getTimestamp;
|
|
1668
|
+
exports.getWhiteOrBlackColor = getWhiteOrBlackColor;
|
|
1649
1669
|
exports.isAccepted = isAccepted;
|
|
1650
1670
|
exports.isNotCalculatedPenaltyStatus = isNotCalculatedPenaltyStatus;
|
|
1651
1671
|
exports.isPending = isPending;
|
package/dist/index.d.ts
CHANGED
|
@@ -47,7 +47,7 @@ declare class Problem {
|
|
|
47
47
|
name: string;
|
|
48
48
|
timeLimit?: string;
|
|
49
49
|
memoryLimit?: string;
|
|
50
|
-
balloonColor
|
|
50
|
+
balloonColor: BalloonColor;
|
|
51
51
|
statistics: ProblemStatistics;
|
|
52
52
|
constructor();
|
|
53
53
|
}
|
|
@@ -83,6 +83,8 @@ declare class TeamProblemStatistics {
|
|
|
83
83
|
|
|
84
84
|
declare function calcDirt(attemptedNum: number, solvedNum: number): number;
|
|
85
85
|
|
|
86
|
+
declare function getWhiteOrBlackColor(background: string): "#000" | "#fff";
|
|
87
|
+
|
|
86
88
|
declare function createDayJS(time?: Date | string | number | undefined): dayjs.Dayjs;
|
|
87
89
|
declare function getTimestamp(time: number | dayjs.Dayjs): number;
|
|
88
90
|
declare function getTimeDiff(seconds: number): string;
|
|
@@ -210,6 +212,7 @@ declare class Balloon {
|
|
|
210
212
|
submission: Submission;
|
|
211
213
|
constructor();
|
|
212
214
|
get key(): string;
|
|
215
|
+
static compare(lhs: Balloon, rhs: Balloon): number;
|
|
213
216
|
}
|
|
214
217
|
type Balloons = Array<Balloon>;
|
|
215
218
|
|
|
@@ -227,7 +230,7 @@ declare class RankOptions {
|
|
|
227
230
|
filterOrganizationMap: Map<string, SelectOptionItem>;
|
|
228
231
|
filterTeams: Array<SelectOptionItem>;
|
|
229
232
|
filterTeamMap: Map<string, SelectOptionItem>;
|
|
230
|
-
|
|
233
|
+
enableAnimatedSubmissions: boolean;
|
|
231
234
|
constructor();
|
|
232
235
|
setWidth(width: number, contest: Contest): void;
|
|
233
236
|
disableFilterSubmissionByTimestamp(): void;
|
|
@@ -321,4 +324,4 @@ declare function isRejected(status: SubmissionStatus): boolean;
|
|
|
321
324
|
declare function isPending(status: SubmissionStatus): boolean;
|
|
322
325
|
declare function isNotCalculatedPenaltyStatus(status: SubmissionStatus): boolean;
|
|
323
326
|
|
|
324
|
-
export { Award, Awards, Balloon, Balloons, CodeforcesGymGhostDATConverter, Contest, ContestIndex, ContestIndexConfig, ContestIndexList, ContestOptions, GeneralExcelConverter, MedalType, PlaceChartPointData, Problem, ProblemStatistics, Problems, Rank, RankOptions, RankStatistics, Resolver, SelectOptionItem, Submission, Submissions, Team, TeamProblemStatistics, Teams, calcDirt, createContest, createContestIndex, createContestIndexList, createDayJS, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, isValidMedalType, stringToSubmissionStatus };
|
|
327
|
+
export { Award, Awards, Balloon, Balloons, CodeforcesGymGhostDATConverter, Contest, ContestIndex, ContestIndexConfig, ContestIndexList, ContestOptions, GeneralExcelConverter, MedalType, PlaceChartPointData, Problem, ProblemStatistics, Problems, Rank, RankOptions, RankStatistics, Resolver, SelectOptionItem, Submission, Submissions, Team, TeamProblemStatistics, Teams, calcDirt, createContest, createContestIndex, createContestIndexList, createDayJS, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, getWhiteOrBlackColor, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, isValidMedalType, stringToSubmissionStatus };
|
package/dist/index.mjs
CHANGED
|
@@ -12,6 +12,8 @@ import relativeTime from 'dayjs/plugin/relativeTime';
|
|
|
12
12
|
import _ from 'lodash';
|
|
13
13
|
import * as XLSX from 'xlsx-js-style';
|
|
14
14
|
import stringWidth from 'string-width';
|
|
15
|
+
import { furthest } from 'color-diff';
|
|
16
|
+
import chroma from 'chroma-js';
|
|
15
17
|
|
|
16
18
|
function stringToSubmissionStatus(status) {
|
|
17
19
|
status = status.toUpperCase().replace(" ", "_");
|
|
@@ -432,6 +434,18 @@ function calcDirt(attemptedNum, solvedNum) {
|
|
|
432
434
|
return Math.floor((attemptedNum - solvedNum) * 100 / attemptedNum);
|
|
433
435
|
}
|
|
434
436
|
|
|
437
|
+
function getWhiteOrBlackColor(background) {
|
|
438
|
+
const [R, G, B] = chroma(background).rgb();
|
|
439
|
+
const color = { R, G, B };
|
|
440
|
+
const palette = [{ R: 0, G: 0, B: 0 }, { R: 255, G: 255, B: 255 }];
|
|
441
|
+
const f = furthest(color, palette);
|
|
442
|
+
if (f.R === 0 && f.G === 0 && f.B === 0) {
|
|
443
|
+
return "#000";
|
|
444
|
+
} else {
|
|
445
|
+
return "#fff";
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
435
449
|
class ProblemStatistics {
|
|
436
450
|
constructor() {
|
|
437
451
|
this.acceptedNum = 0;
|
|
@@ -466,6 +480,10 @@ class Problem {
|
|
|
466
480
|
this.label = "";
|
|
467
481
|
this.name = "";
|
|
468
482
|
this.statistics = new ProblemStatistics();
|
|
483
|
+
this.balloonColor = {
|
|
484
|
+
background_color: "#a0f0a0",
|
|
485
|
+
color: "#000"
|
|
486
|
+
};
|
|
469
487
|
}
|
|
470
488
|
}
|
|
471
489
|
function createProblem(problemJSON) {
|
|
@@ -475,20 +493,14 @@ function createProblem(problemJSON) {
|
|
|
475
493
|
p.name = problemJSON.name ?? "";
|
|
476
494
|
p.timeLimit = problemJSON.time_limit;
|
|
477
495
|
p.memoryLimit = problemJSON.memory_limit;
|
|
478
|
-
|
|
496
|
+
if (problemJSON.balloon_color) {
|
|
497
|
+
p.balloonColor = problemJSON.balloon_color;
|
|
498
|
+
}
|
|
499
|
+
p.balloonColor.color = getWhiteOrBlackColor(p.balloonColor.background_color);
|
|
479
500
|
return p;
|
|
480
501
|
}
|
|
481
502
|
function createProblems(problemsJSON) {
|
|
482
|
-
return problemsJSON.map((pJSON) =>
|
|
483
|
-
const p = new Problem();
|
|
484
|
-
p.id = pJSON.id;
|
|
485
|
-
p.label = pJSON.label;
|
|
486
|
-
p.name = pJSON.name ?? "";
|
|
487
|
-
p.timeLimit = pJSON.time_limit;
|
|
488
|
-
p.memoryLimit = pJSON.memory_limit;
|
|
489
|
-
p.balloonColor = pJSON.balloon_color;
|
|
490
|
-
return p;
|
|
491
|
-
});
|
|
503
|
+
return problemsJSON.map((pJSON) => createProblem(pJSON));
|
|
492
504
|
}
|
|
493
505
|
function createProblemsByProblemIds(problemIds, balloonColors) {
|
|
494
506
|
const problems = problemIds.map((label, index) => {
|
|
@@ -502,6 +514,9 @@ function createProblemsByProblemIds(problemIds, balloonColors) {
|
|
|
502
514
|
problems[index].balloonColor = balloonColors[index];
|
|
503
515
|
}
|
|
504
516
|
}
|
|
517
|
+
problems.forEach((p) => {
|
|
518
|
+
p.balloonColor.color = getWhiteOrBlackColor(p.balloonColor.background_color);
|
|
519
|
+
});
|
|
505
520
|
return problems;
|
|
506
521
|
}
|
|
507
522
|
class TeamProblemStatistics {
|
|
@@ -841,6 +856,9 @@ class Balloon {
|
|
|
841
856
|
get key() {
|
|
842
857
|
return `balloon-${this.team.id}-${this.problem.id}`;
|
|
843
858
|
}
|
|
859
|
+
static compare(lhs, rhs) {
|
|
860
|
+
return Submission.compare(lhs.submission, rhs.submission);
|
|
861
|
+
}
|
|
844
862
|
}
|
|
845
863
|
|
|
846
864
|
class Group {
|
|
@@ -1160,7 +1178,7 @@ class RankOptions {
|
|
|
1160
1178
|
this.filterOrganizationMap = /* @__PURE__ */ new Map();
|
|
1161
1179
|
this.filterTeams = [];
|
|
1162
1180
|
this.filterTeamMap = /* @__PURE__ */ new Map();
|
|
1163
|
-
this.
|
|
1181
|
+
this.enableAnimatedSubmissions = false;
|
|
1164
1182
|
}
|
|
1165
1183
|
setWidth(width, contest) {
|
|
1166
1184
|
this.width = width;
|
|
@@ -1581,4 +1599,4 @@ class Resolver extends Rank {
|
|
|
1581
1599
|
}
|
|
1582
1600
|
}
|
|
1583
1601
|
|
|
1584
|
-
export { Award, Balloon, CodeforcesGymGhostDATConverter, Contest, ContestIndex, ContestIndexConfig, ContestOptions, GeneralExcelConverter, MedalType, PlaceChartPointData, Problem, ProblemStatistics, Rank, RankOptions, RankStatistics, Resolver, Submission, Team, TeamProblemStatistics, calcDirt, createContest, createContestIndex, createContestIndexList, createDayJS, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, isValidMedalType, stringToSubmissionStatus };
|
|
1602
|
+
export { Award, Balloon, CodeforcesGymGhostDATConverter, Contest, ContestIndex, ContestIndexConfig, ContestOptions, GeneralExcelConverter, MedalType, PlaceChartPointData, Problem, ProblemStatistics, Rank, RankOptions, RankStatistics, Resolver, Submission, Team, TeamProblemStatistics, calcDirt, createContest, createContestIndex, createContestIndexList, createDayJS, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, getWhiteOrBlackColor, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, isValidMedalType, stringToSubmissionStatus };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xcpcio/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.0",
|
|
4
4
|
"description": "XCPCIO Core",
|
|
5
5
|
"author": "Dup4 <lyuzhi.pan@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -40,14 +40,18 @@
|
|
|
40
40
|
"dist"
|
|
41
41
|
],
|
|
42
42
|
"dependencies": {
|
|
43
|
+
"chroma-js": "^2.4.2",
|
|
44
|
+
"color-diff": "^1.4.0",
|
|
43
45
|
"dayjs": "^1.11.8",
|
|
44
46
|
"lodash": "^4.17.21",
|
|
45
47
|
"string-width": "^6.1.0",
|
|
46
48
|
"xlsx-js-style": "^1.2.0",
|
|
47
|
-
"@xcpcio/types": "0.
|
|
49
|
+
"@xcpcio/types": "0.33.0"
|
|
48
50
|
},
|
|
49
51
|
"devDependencies": {
|
|
50
52
|
"@babel/types": "^7.22.4",
|
|
53
|
+
"@types/chroma-js": "^2.4.2",
|
|
54
|
+
"@types/color-diff": "^1.2.3",
|
|
51
55
|
"@types/lodash": "^4.14.195",
|
|
52
56
|
"@types/node": "^17.0.45",
|
|
53
57
|
"@typescript-eslint/eslint-plugin": "^5.59.9",
|
package/src/balloon.ts
CHANGED
|
@@ -16,6 +16,10 @@ export class Balloon {
|
|
|
16
16
|
get key() {
|
|
17
17
|
return `balloon-${this.team.id}-${this.problem.id}`;
|
|
18
18
|
}
|
|
19
|
+
|
|
20
|
+
static compare(lhs: Balloon, rhs: Balloon): number {
|
|
21
|
+
return Submission.compare(lhs.submission, rhs.submission);
|
|
22
|
+
}
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
export type Balloons = Array<Balloon>;
|
package/src/problem.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { BalloonColor, Problem as IProblem, Problems as IProblems } from "@xcpcio/types";
|
|
2
2
|
|
|
3
3
|
import type { Submissions } from "./submission";
|
|
4
|
-
import { calcDirt } from "./utils";
|
|
4
|
+
import { calcDirt, getWhiteOrBlackColor } from "./utils";
|
|
5
5
|
|
|
6
6
|
export class ProblemStatistics {
|
|
7
7
|
acceptedNum: number;
|
|
@@ -59,7 +59,7 @@ export class Problem {
|
|
|
59
59
|
timeLimit?: string;
|
|
60
60
|
memoryLimit?: string;
|
|
61
61
|
|
|
62
|
-
balloonColor
|
|
62
|
+
balloonColor: BalloonColor;
|
|
63
63
|
|
|
64
64
|
statistics: ProblemStatistics;
|
|
65
65
|
|
|
@@ -70,6 +70,11 @@ export class Problem {
|
|
|
70
70
|
this.name = "";
|
|
71
71
|
|
|
72
72
|
this.statistics = new ProblemStatistics();
|
|
73
|
+
|
|
74
|
+
this.balloonColor = {
|
|
75
|
+
background_color: "#a0f0a0",
|
|
76
|
+
color: "#000",
|
|
77
|
+
};
|
|
73
78
|
}
|
|
74
79
|
}
|
|
75
80
|
|
|
@@ -86,27 +91,17 @@ export function createProblem(problemJSON: IProblem): Problem {
|
|
|
86
91
|
p.timeLimit = problemJSON.time_limit;
|
|
87
92
|
p.memoryLimit = problemJSON.memory_limit;
|
|
88
93
|
|
|
89
|
-
|
|
94
|
+
if (problemJSON.balloon_color) {
|
|
95
|
+
p.balloonColor = problemJSON.balloon_color;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
p.balloonColor.color = getWhiteOrBlackColor(p.balloonColor.background_color as string);
|
|
90
99
|
|
|
91
100
|
return p;
|
|
92
101
|
}
|
|
93
102
|
|
|
94
103
|
export function createProblems(problemsJSON: IProblems): Problems {
|
|
95
|
-
return problemsJSON.map(
|
|
96
|
-
const p = new Problem();
|
|
97
|
-
|
|
98
|
-
p.id = pJSON.id;
|
|
99
|
-
p.label = pJSON.label;
|
|
100
|
-
|
|
101
|
-
p.name = pJSON.name ?? "";
|
|
102
|
-
|
|
103
|
-
p.timeLimit = pJSON.time_limit;
|
|
104
|
-
p.memoryLimit = pJSON.memory_limit;
|
|
105
|
-
|
|
106
|
-
p.balloonColor = pJSON.balloon_color;
|
|
107
|
-
|
|
108
|
-
return p;
|
|
109
|
-
});
|
|
104
|
+
return problemsJSON.map(pJSON => createProblem(pJSON));
|
|
110
105
|
}
|
|
111
106
|
|
|
112
107
|
export function createProblemsByProblemIds(problemIds: string[], balloonColors?: BalloonColor[]): Problems {
|
|
@@ -124,6 +119,10 @@ export function createProblemsByProblemIds(problemIds: string[], balloonColors?:
|
|
|
124
119
|
}
|
|
125
120
|
}
|
|
126
121
|
|
|
122
|
+
problems.forEach((p) => {
|
|
123
|
+
p.balloonColor.color = getWhiteOrBlackColor(p.balloonColor.background_color as string);
|
|
124
|
+
});
|
|
125
|
+
|
|
127
126
|
return problems;
|
|
128
127
|
}
|
|
129
128
|
|
package/src/rank.ts
CHANGED
|
@@ -29,7 +29,7 @@ export class RankOptions {
|
|
|
29
29
|
filterTeams: Array<SelectOptionItem>;
|
|
30
30
|
filterTeamMap: Map<string, SelectOptionItem>;
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
enableAnimatedSubmissions: boolean;
|
|
33
33
|
|
|
34
34
|
constructor() {
|
|
35
35
|
this.enableFilterSubmissionsByTimestamp = false;
|
|
@@ -45,7 +45,7 @@ export class RankOptions {
|
|
|
45
45
|
this.filterTeams = [];
|
|
46
46
|
this.filterTeamMap = new Map<string, SelectOptionItem>();
|
|
47
47
|
|
|
48
|
-
this.
|
|
48
|
+
this.enableAnimatedSubmissions = false;
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
setWidth(width: number, contest: Contest) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { furthest } from "color-diff";
|
|
2
|
+
import chroma from "chroma-js";
|
|
3
|
+
|
|
4
|
+
export function getWhiteOrBlackColor(background: string) {
|
|
5
|
+
const [R, G, B] = chroma(background).rgb();
|
|
6
|
+
const color = { R, G, B };
|
|
7
|
+
const palette = [{ R: 0, G: 0, B: 0 }, { R: 255, G: 255, B: 255 }];
|
|
8
|
+
|
|
9
|
+
const f = furthest(color, palette);
|
|
10
|
+
|
|
11
|
+
if (f.R === 0 && f.G === 0 && f.B === 0) {
|
|
12
|
+
return "#000";
|
|
13
|
+
} else {
|
|
14
|
+
return "#fff";
|
|
15
|
+
}
|
|
16
|
+
}
|
package/src/utils/index.ts
CHANGED