@xcpcio/core 0.58.0 → 0.59.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/LICENSE +1 -1
- package/package.json +12 -23
- package/src/award.ts +0 -32
- package/src/balloon.ts +0 -25
- package/src/basic-types.ts +0 -4
- package/src/battle-of-giants.ts +0 -154
- package/src/contest-index.ts +0 -99
- package/src/contest-options.ts +0 -49
- package/src/contest.ts +0 -351
- package/src/export/cf.ts +0 -125
- package/src/export/general-excel.ts +0 -257
- package/src/export/icpc-standings-csv.ts +0 -89
- package/src/export/index.ts +0 -3
- package/src/group.ts +0 -13
- package/src/image.ts +0 -21
- package/src/index.ts +0 -19
- package/src/person.ts +0 -42
- package/src/problem.ts +0 -222
- package/src/rank-statistics.ts +0 -33
- package/src/rank.ts +0 -613
- package/src/rating/index.ts +0 -5
- package/src/rating/rating-calculator.ts +0 -100
- package/src/rating/rating-history.ts +0 -81
- package/src/rating/rating-user.ts +0 -99
- package/src/rating/rating-utility.ts +0 -80
- package/src/rating/rating.ts +0 -136
- package/src/resolver-operation.ts +0 -22
- package/src/resolver-vue.ts +0 -183
- package/src/resolver.ts +0 -138
- package/src/submission-status.ts +0 -157
- package/src/submission.ts +0 -177
- package/src/team.ts +0 -339
- package/src/utils/calc.ts +0 -7
- package/src/utils/color.ts +0 -28
- package/src/utils/dayjs.ts +0 -59
- package/src/utils/index.ts +0 -3
package/src/team.ts
DELETED
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
import type { Image, Team as ITeam, Teams as ITeams } from "@xcpcio/types";
|
|
2
|
-
|
|
3
|
-
import type { Award, MedalType } from "./award";
|
|
4
|
-
|
|
5
|
-
import type { ContestOptions } from "./contest-options";
|
|
6
|
-
import type { Problem, TeamProblemStatistics } from "./problem";
|
|
7
|
-
import type { Submissions } from "./submission";
|
|
8
|
-
import _ from "lodash";
|
|
9
|
-
import { calcDirt } from "./utils";
|
|
10
|
-
|
|
11
|
-
export class PlaceChartPointData {
|
|
12
|
-
timePoint: number;
|
|
13
|
-
rank: number;
|
|
14
|
-
lastSolvedProblem: Problem | null;
|
|
15
|
-
|
|
16
|
-
constructor() {
|
|
17
|
-
this.timePoint = 0;
|
|
18
|
-
this.rank = 0;
|
|
19
|
-
this.lastSolvedProblem = null;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export class Team {
|
|
24
|
-
id: string;
|
|
25
|
-
name: string;
|
|
26
|
-
|
|
27
|
-
organization: string;
|
|
28
|
-
badge?: Image;
|
|
29
|
-
|
|
30
|
-
group: Array<string>;
|
|
31
|
-
tag: Array<string>;
|
|
32
|
-
|
|
33
|
-
coach?: string | Array<string>;
|
|
34
|
-
members?: string | Array<string>;
|
|
35
|
-
|
|
36
|
-
rank: number;
|
|
37
|
-
originalRank: number;
|
|
38
|
-
organizationRank: number;
|
|
39
|
-
|
|
40
|
-
solvedProblemNum: number;
|
|
41
|
-
attemptedProblemNum: number;
|
|
42
|
-
|
|
43
|
-
lastSolvedProblem: Problem | null;
|
|
44
|
-
lastSolvedProblemStatistics: TeamProblemStatistics | null;
|
|
45
|
-
|
|
46
|
-
penalty: number;
|
|
47
|
-
|
|
48
|
-
problemStatistics: Array<TeamProblemStatistics>;
|
|
49
|
-
problemStatisticsMap: Map<string, TeamProblemStatistics>;
|
|
50
|
-
|
|
51
|
-
submissions: Submissions;
|
|
52
|
-
|
|
53
|
-
placeChartPoints: Array<PlaceChartPointData>;
|
|
54
|
-
|
|
55
|
-
awards: MedalType[];
|
|
56
|
-
|
|
57
|
-
location?: string;
|
|
58
|
-
icpcID?: string;
|
|
59
|
-
|
|
60
|
-
se: number;
|
|
61
|
-
|
|
62
|
-
constructor() {
|
|
63
|
-
this.id = "";
|
|
64
|
-
this.name = "";
|
|
65
|
-
|
|
66
|
-
this.organization = "";
|
|
67
|
-
|
|
68
|
-
this.group = [];
|
|
69
|
-
this.tag = [];
|
|
70
|
-
|
|
71
|
-
this.rank = 0;
|
|
72
|
-
this.originalRank = 0;
|
|
73
|
-
this.organizationRank = -1;
|
|
74
|
-
|
|
75
|
-
this.solvedProblemNum = 0;
|
|
76
|
-
this.attemptedProblemNum = 0;
|
|
77
|
-
|
|
78
|
-
this.lastSolvedProblem = null;
|
|
79
|
-
this.lastSolvedProblemStatistics = null;
|
|
80
|
-
|
|
81
|
-
this.penalty = 0;
|
|
82
|
-
|
|
83
|
-
this.problemStatistics = [];
|
|
84
|
-
this.problemStatisticsMap = new Map<string, TeamProblemStatistics>();
|
|
85
|
-
|
|
86
|
-
this.submissions = [];
|
|
87
|
-
|
|
88
|
-
this.placeChartPoints = [];
|
|
89
|
-
|
|
90
|
-
this.awards = [];
|
|
91
|
-
|
|
92
|
-
this.se = 0;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
reset() {
|
|
96
|
-
this.rank = 0;
|
|
97
|
-
this.originalRank = 0;
|
|
98
|
-
this.organizationRank = -1;
|
|
99
|
-
|
|
100
|
-
this.solvedProblemNum = 0;
|
|
101
|
-
this.attemptedProblemNum = 0;
|
|
102
|
-
|
|
103
|
-
this.lastSolvedProblem = null;
|
|
104
|
-
this.lastSolvedProblemStatistics = null;
|
|
105
|
-
|
|
106
|
-
this.penalty = 0;
|
|
107
|
-
|
|
108
|
-
this.problemStatistics = [];
|
|
109
|
-
this.problemStatisticsMap = new Map<string, TeamProblemStatistics>();
|
|
110
|
-
|
|
111
|
-
this.submissions = [];
|
|
112
|
-
|
|
113
|
-
this.placeChartPoints = [];
|
|
114
|
-
|
|
115
|
-
this.awards = [];
|
|
116
|
-
|
|
117
|
-
this.se = 0;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
get penaltyToMinute() {
|
|
121
|
-
return Math.floor(this.penalty / 60);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
get isUnofficial() {
|
|
125
|
-
return this.group.includes("unofficial");
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
get isGirl() {
|
|
129
|
-
return this.group.includes("girl");
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
get membersToArray() {
|
|
133
|
-
if (Array.isArray(this.members)) {
|
|
134
|
-
return this.members;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (typeof this.members === "string") {
|
|
138
|
-
if (this.members.includes(", ")) {
|
|
139
|
-
return this.members.split(", ");
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (this.members.includes("、")) {
|
|
143
|
-
return this.members.split("、");
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
return [];
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
get membersToString() {
|
|
151
|
-
if (typeof this.members === "string") {
|
|
152
|
-
return this.members;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return this.members?.join(", ");
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
get isEffectiveTeam() {
|
|
159
|
-
return this.solvedProblemNum > 0;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
get dirt() {
|
|
163
|
-
const attemptedNum = this.attemptedProblemNum;
|
|
164
|
-
const solvedNum = this.solvedProblemNum;
|
|
165
|
-
|
|
166
|
-
return calcDirt(attemptedNum, solvedNum);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
calcSE(totalTeams: number) {
|
|
170
|
-
let acceptedProblemNums = 0;
|
|
171
|
-
let total = 0;
|
|
172
|
-
|
|
173
|
-
this.problemStatistics.forEach((p) => {
|
|
174
|
-
if (p.isSolved) {
|
|
175
|
-
acceptedProblemNums += 1;
|
|
176
|
-
total += p.problem.statistics.acceptedNum;
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
if (totalTeams === 0 || acceptedProblemNums === 0) {
|
|
181
|
-
return 0;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
const res = (acceptedProblemNums * totalTeams - total) / totalTeams / acceptedProblemNums;
|
|
185
|
-
this.se = Math.round(res * 100) / 100;
|
|
186
|
-
|
|
187
|
-
return this.se;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
calcSolvedData(options: ContestOptions) {
|
|
191
|
-
this.solvedProblemNum = 0;
|
|
192
|
-
this.attemptedProblemNum = 0;
|
|
193
|
-
|
|
194
|
-
this.penalty = 0;
|
|
195
|
-
|
|
196
|
-
for (const p of this.problemStatistics) {
|
|
197
|
-
if (p.isAccepted) {
|
|
198
|
-
this.solvedProblemNum++;
|
|
199
|
-
this.attemptedProblemNum += p.failedCount + 1;
|
|
200
|
-
|
|
201
|
-
if (options?.calculationOfPenalty === "in_seconds"
|
|
202
|
-
|| options?.calculationOfPenalty === "accumulate_in_seconds_and_finally_to_the_minute") {
|
|
203
|
-
this.penalty += p.penaltyInSecond;
|
|
204
|
-
} else {
|
|
205
|
-
this.penalty += p.penalty;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
if (options?.calculationOfPenalty === "accumulate_in_seconds_and_finally_to_the_minute") {
|
|
211
|
-
this.penalty = Math.floor(this.penalty / 60) * 60;
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
calcAwards(awards?: Award[]) {
|
|
216
|
-
if (!awards) {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
for (const award of awards) {
|
|
221
|
-
if (this.rank >= award.minRank && this.rank <= award.maxRank) {
|
|
222
|
-
this.awards.push(award.medalType);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
isEqualRank(otherTeam: Team) {
|
|
228
|
-
return this.solvedProblemNum === otherTeam.solvedProblemNum && this.penalty === otherTeam.penalty;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
postProcessPlaceChartPoints() {
|
|
232
|
-
if (this.placeChartPoints.length === 0) {
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const res = [];
|
|
237
|
-
res.push(this.placeChartPoints[0]);
|
|
238
|
-
|
|
239
|
-
for (let i = 1; i < this.placeChartPoints.length - 1; i++) {
|
|
240
|
-
const p = this.placeChartPoints[i];
|
|
241
|
-
const preP = res[res.length - 1];
|
|
242
|
-
|
|
243
|
-
if (p.rank !== preP.rank || p.lastSolvedProblem !== preP.lastSolvedProblem) {
|
|
244
|
-
res.push(p);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (this.placeChartPoints.length > 1) {
|
|
249
|
-
res.push(this.placeChartPoints[this.placeChartPoints.length - 1]);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
this.placeChartPoints = res;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
static compare(lhs: Team, rhs: Team): number {
|
|
256
|
-
if (lhs.solvedProblemNum !== rhs.solvedProblemNum) {
|
|
257
|
-
return rhs.solvedProblemNum - lhs.solvedProblemNum;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
if (lhs.penalty !== rhs.penalty) {
|
|
261
|
-
return lhs.penalty - rhs.penalty;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
if (lhs.lastSolvedProblemStatistics && rhs.lastSolvedProblemStatistics) {
|
|
265
|
-
return lhs.lastSolvedProblemStatistics.solvedTimestampToMinute - rhs.lastSolvedProblemStatistics.solvedTimestampToMinute;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
if (lhs.name < rhs.name) {
|
|
269
|
-
return -1;
|
|
270
|
-
} else if (lhs.name > rhs.name) {
|
|
271
|
-
return 1;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
return 0;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
export type Teams = Array<Team>;
|
|
279
|
-
|
|
280
|
-
export function createTeam(teamJSON: ITeam): Team {
|
|
281
|
-
const t = new Team();
|
|
282
|
-
|
|
283
|
-
t.id = teamJSON.id ?? teamJSON.team_id ?? "";
|
|
284
|
-
t.name = teamJSON.name ?? teamJSON.team_name ?? "";
|
|
285
|
-
|
|
286
|
-
t.organization = teamJSON.organization ?? "";
|
|
287
|
-
t.badge = teamJSON.badge;
|
|
288
|
-
|
|
289
|
-
t.group = _.cloneDeep(teamJSON.group ?? []);
|
|
290
|
-
t.tag = _.cloneDeep(teamJSON.tag ?? []);
|
|
291
|
-
|
|
292
|
-
t.coach = teamJSON.coach;
|
|
293
|
-
t.members = teamJSON.members;
|
|
294
|
-
|
|
295
|
-
if (Boolean(teamJSON.official) === true) {
|
|
296
|
-
t.group.push("official");
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
if (Boolean(teamJSON.unofficial) === true) {
|
|
300
|
-
t.group.push("unofficial");
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
if (Boolean(teamJSON.girl) === true) {
|
|
304
|
-
t.group.push("girl");
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
{
|
|
308
|
-
const tt: any = teamJSON as any;
|
|
309
|
-
for (const key of Object.keys(tt)) {
|
|
310
|
-
if (tt[key] === 1 || tt[key] === true) {
|
|
311
|
-
t.group.push(key);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
t.group = [...new Set(t.group)];
|
|
317
|
-
t.group.sort();
|
|
318
|
-
|
|
319
|
-
if (teamJSON.location) {
|
|
320
|
-
t.location = teamJSON.location;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
if (teamJSON.icpc_id) {
|
|
324
|
-
t.icpcID = teamJSON.icpc_id;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
return t;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
export function createTeams(teamsJSON: ITeams): Teams {
|
|
331
|
-
if (Array.isArray(teamsJSON)) {
|
|
332
|
-
return teamsJSON.map(t => createTeam(t));
|
|
333
|
-
} else {
|
|
334
|
-
const teams = Object.entries(teamsJSON).map(([teamId, team]) =>
|
|
335
|
-
createTeam({ ...team, team_id: team.team_id ?? teamId }),
|
|
336
|
-
);
|
|
337
|
-
return teams;
|
|
338
|
-
}
|
|
339
|
-
}
|
package/src/utils/calc.ts
DELETED
package/src/utils/color.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import chroma from "chroma-js";
|
|
2
|
-
import { furthest } from "color-diff";
|
|
3
|
-
|
|
4
|
-
export function getWhiteOrBlackColorV1(background: string) {
|
|
5
|
-
const [R, G, B] = chroma(background).rgb();
|
|
6
|
-
const color = { R, G, B };
|
|
7
|
-
const palette = [
|
|
8
|
-
{ R: 0, G: 0, B: 0 },
|
|
9
|
-
{ R: 255, G: 255, B: 255 },
|
|
10
|
-
];
|
|
11
|
-
|
|
12
|
-
const f = furthest(color, palette);
|
|
13
|
-
|
|
14
|
-
if (f.R === 0 && f.G === 0 && f.B === 0) {
|
|
15
|
-
return "#000";
|
|
16
|
-
} else {
|
|
17
|
-
return "#fff";
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function getWhiteOrBlackColor(background: string) {
|
|
22
|
-
const [R, G, B] = chroma(background).rgb();
|
|
23
|
-
|
|
24
|
-
const brightness = (R * 299 + G * 587 + B * 114) / 1000;
|
|
25
|
-
const threshold = 148;
|
|
26
|
-
|
|
27
|
-
return brightness <= threshold ? "#fff" : "#000";
|
|
28
|
-
}
|
package/src/utils/dayjs.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import dayjs from "dayjs";
|
|
2
|
-
|
|
3
|
-
import advancedFormat from "dayjs/plugin/advancedFormat";
|
|
4
|
-
import duration from "dayjs/plugin/duration";
|
|
5
|
-
import isSameOrAfter from "dayjs/plugin/isSameOrAfter";
|
|
6
|
-
import isSameOrBefore from "dayjs/plugin/isSameOrBefore";
|
|
7
|
-
import minMax from "dayjs/plugin/minMax";
|
|
8
|
-
import relativeTime from "dayjs/plugin/relativeTime";
|
|
9
|
-
import timezone from "dayjs/plugin/timezone";
|
|
10
|
-
import utc from "dayjs/plugin/utc";
|
|
11
|
-
|
|
12
|
-
dayjs.extend(duration);
|
|
13
|
-
dayjs.extend(utc);
|
|
14
|
-
dayjs.extend(timezone);
|
|
15
|
-
dayjs.extend(advancedFormat);
|
|
16
|
-
dayjs.extend(isSameOrBefore);
|
|
17
|
-
dayjs.extend(isSameOrAfter);
|
|
18
|
-
dayjs.extend(minMax);
|
|
19
|
-
|
|
20
|
-
dayjs.extend(relativeTime);
|
|
21
|
-
|
|
22
|
-
export function createDayJS(time: Date | string | number | undefined = undefined): dayjs.Dayjs {
|
|
23
|
-
if (time === undefined) {
|
|
24
|
-
return dayjs();
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (typeof time == "number" && String(time).length === 10) {
|
|
28
|
-
return dayjs.unix(time);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return dayjs(time);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function getTimestamp(time: number | dayjs.Dayjs): number {
|
|
35
|
-
if (typeof time === "number") {
|
|
36
|
-
return time;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return time.unix();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function getTimeDiff(seconds: number): string {
|
|
43
|
-
const two = (a: number) => {
|
|
44
|
-
if (a < 10) {
|
|
45
|
-
return `0${a}`;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return String(a);
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const h = Math.floor(seconds / 3600);
|
|
52
|
-
const m = Math.floor((seconds % 3600) / 60);
|
|
53
|
-
const s = seconds % 60;
|
|
54
|
-
|
|
55
|
-
return [two(h), two(m), two(s)].join(":");
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export { dayjs };
|
|
59
|
-
export default dayjs;
|
package/src/utils/index.ts
DELETED