@xcpcio/core 0.12.0 → 0.14.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.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import { SubmissionStatus, ContestState } from '@xcpcio/types';
1
2
  import dayjs from 'dayjs';
2
3
  export { default as dayjs } from 'dayjs';
3
4
  import duration from 'dayjs/plugin/duration';
@@ -8,30 +9,125 @@ import isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
8
9
  import isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
9
10
  import minMax from 'dayjs/plugin/minMax';
10
11
  import relativeTime from 'dayjs/plugin/relativeTime';
11
- import { ContestState, SubmissionStatus } from '@xcpcio/types';
12
12
  import _ from 'lodash';
13
+ import * as XLSX from 'xlsx-js-style';
14
+ import stringWidth from 'string-width';
13
15
 
14
- var MedalType = /* @__PURE__ */ ((MedalType2) => {
15
- MedalType2[MedalType2["UNKNOWN"] = 0] = "UNKNOWN";
16
- MedalType2[MedalType2["GOLD"] = 1] = "GOLD";
17
- MedalType2[MedalType2["SILVER"] = 2] = "SILVER";
18
- MedalType2[MedalType2["BRONZE"] = 3] = "BRONZE";
19
- MedalType2[MedalType2["HONORABLE"] = 4] = "HONORABLE";
20
- return MedalType2;
21
- })(MedalType || {});
22
- class Award {
23
- constructor() {
24
- this.medalType = 0 /* UNKNOWN */;
25
- this.minRank = 0;
26
- this.maxRank = 0;
16
+ function stringToSubmissionStatus(status) {
17
+ status = status.toUpperCase().replace(" ", "_");
18
+ if (["OK", "AC", SubmissionStatus.ACCEPTED.toString()].includes(status)) {
19
+ return SubmissionStatus.ACCEPTED;
27
20
  }
28
- }
29
-
30
- function calcDict(attemptedNum, solvedNum) {
31
- if (solvedNum === 0) {
32
- return 0;
21
+ if ([SubmissionStatus.CORRECT.toString()].includes(status)) {
22
+ return SubmissionStatus.ACCEPTED;
33
23
  }
34
- return Math.floor((attemptedNum - solvedNum) * 100 / attemptedNum);
24
+ if ([SubmissionStatus.PARTIALLY_CORRECT.toString()].includes(status)) {
25
+ return SubmissionStatus.PARTIALLY_CORRECT;
26
+ }
27
+ if (["WA", SubmissionStatus.WRONG_ANSWER.toString()].includes(status)) {
28
+ return SubmissionStatus.WRONG_ANSWER;
29
+ }
30
+ if (["RJ", "INCORRECT", SubmissionStatus.REJECTED.toString()].includes(status)) {
31
+ return SubmissionStatus.REJECTED;
32
+ }
33
+ if (["PD", SubmissionStatus.PENDING.toString()].includes(status)) {
34
+ return SubmissionStatus.PENDING;
35
+ }
36
+ if ([SubmissionStatus.WAITING.toString()].includes(status)) {
37
+ return SubmissionStatus.WAITING;
38
+ }
39
+ if ([SubmissionStatus.JUDGING.toString()].includes(status)) {
40
+ return SubmissionStatus.JUDGING;
41
+ }
42
+ if ([SubmissionStatus.FROZEN.toString()].includes(status)) {
43
+ return SubmissionStatus.FROZEN;
44
+ }
45
+ if (["CE", SubmissionStatus.COMPILATION_ERROR.toString()].includes(status)) {
46
+ return SubmissionStatus.COMPILATION_ERROR;
47
+ }
48
+ if (["PE", SubmissionStatus.PRESENTATION_ERROR.toString()].includes(status)) {
49
+ return SubmissionStatus.PRESENTATION_ERROR;
50
+ }
51
+ if (["TL", "TLE", SubmissionStatus.TIME_LIMIT_EXCEEDED.toString()].includes(status)) {
52
+ return SubmissionStatus.TIME_LIMIT_EXCEEDED;
53
+ }
54
+ if (["ML", "MLE", SubmissionStatus.MEMORY_LIMIT_EXCEEDED.toString()].includes(status)) {
55
+ return SubmissionStatus.MEMORY_LIMIT_EXCEEDED;
56
+ }
57
+ if (["OL", "OLE", SubmissionStatus.OUTPUT_LIMIT_EXCEEDED.toString()].includes(status)) {
58
+ return SubmissionStatus.OUTPUT_LIMIT_EXCEEDED;
59
+ }
60
+ if (["IL", "ILE", SubmissionStatus.IDLENESS_LIMIT_EXCEEDED.toString()].includes(status)) {
61
+ return SubmissionStatus.IDLENESS_LIMIT_EXCEEDED;
62
+ }
63
+ if (["RT", "RE", "RTE", SubmissionStatus.RUNTIME_ERROR.toString()].includes(status)) {
64
+ return SubmissionStatus.RUNTIME_ERROR;
65
+ }
66
+ if (["JE", SubmissionStatus.JUDGEMENT_FAILED.toString()].includes(status)) {
67
+ return SubmissionStatus.JUDGEMENT_FAILED;
68
+ }
69
+ if (["SE", SubmissionStatus.SYSTEM_ERROR.toString()].includes(status)) {
70
+ return SubmissionStatus.SYSTEM_ERROR;
71
+ }
72
+ if ([SubmissionStatus.HACKED.toString()].includes(status)) {
73
+ return SubmissionStatus.HACKED;
74
+ }
75
+ if ([SubmissionStatus.CONFIGURATION_ERROR.toString()].includes(status)) {
76
+ return SubmissionStatus.CONFIGURATION_ERROR;
77
+ }
78
+ if ([SubmissionStatus.CANCELED.toString()].includes(status)) {
79
+ return SubmissionStatus.CANCELED;
80
+ }
81
+ if ([SubmissionStatus.SKIPPED.toString()].includes(status)) {
82
+ return SubmissionStatus.SKIPPED;
83
+ }
84
+ if ([SubmissionStatus.SECURITY_VIOLATED.toString()].includes(status)) {
85
+ return SubmissionStatus.SECURITY_VIOLATED;
86
+ }
87
+ if ([SubmissionStatus.DENIAL_OF_JUDGEMENT.toString()].includes(status)) {
88
+ return SubmissionStatus.DENIAL_OF_JUDGEMENT;
89
+ }
90
+ return SubmissionStatus.UNKNOWN;
91
+ }
92
+ function isAccepted(status) {
93
+ const acceptedArray = [SubmissionStatus.ACCEPTED, SubmissionStatus.CORRECT];
94
+ return acceptedArray.includes(status);
95
+ }
96
+ function isRejected(status) {
97
+ const rejectArray = [
98
+ SubmissionStatus.RUNTIME_ERROR,
99
+ SubmissionStatus.TIME_LIMIT_EXCEEDED,
100
+ SubmissionStatus.MEMORY_LIMIT_EXCEEDED,
101
+ SubmissionStatus.OUTPUT_LIMIT_EXCEEDED,
102
+ SubmissionStatus.IDLENESS_LIMIT_EXCEEDED,
103
+ SubmissionStatus.WRONG_ANSWER,
104
+ SubmissionStatus.REJECTED,
105
+ SubmissionStatus.JUDGEMENT_FAILED,
106
+ SubmissionStatus.HACKED
107
+ ];
108
+ return rejectArray.includes(status);
109
+ }
110
+ function isPending(status) {
111
+ const pendingArray = [
112
+ SubmissionStatus.PENDING,
113
+ SubmissionStatus.WAITING,
114
+ SubmissionStatus.JUDGING,
115
+ SubmissionStatus.FROZEN
116
+ ];
117
+ return pendingArray.includes(status);
118
+ }
119
+ function isNotCalculatedPenaltyStatus(status) {
120
+ const isNotCalculatedPenaltyArray = [
121
+ SubmissionStatus.COMPILATION_ERROR,
122
+ SubmissionStatus.PRESENTATION_ERROR,
123
+ SubmissionStatus.CONFIGURATION_ERROR,
124
+ SubmissionStatus.SYSTEM_ERROR,
125
+ SubmissionStatus.CANCELED,
126
+ SubmissionStatus.SKIPPED,
127
+ SubmissionStatus.UNKNOWN,
128
+ SubmissionStatus.UNDEFINED
129
+ ];
130
+ return isNotCalculatedPenaltyArray.includes(status);
35
131
  }
36
132
 
37
133
  dayjs.extend(duration);
@@ -70,6 +166,239 @@ function getTimeDiff(seconds) {
70
166
  return [two(h), two(m), two(s)].join(":");
71
167
  }
72
168
 
169
+ class CodeforcesGymGhostDATConverter {
170
+ constructor() {
171
+ }
172
+ convert(rank) {
173
+ let res = "";
174
+ res += `@contest "${rank.contest.name}"
175
+ @contlen ${Math.floor(dayjs.duration(rank.contest.endTime.diff(rank.contest.startTime)).asMinutes())}
176
+ @problems ${rank.contest.problems.length}
177
+ @teams ${rank.teams.length + 100}
178
+ @submissions ${rank.submissions.length}
179
+ `;
180
+ rank.contest.problems.forEach((p) => {
181
+ res += `@p ${p.label},${p.label},20,0
182
+ `;
183
+ });
184
+ let teamIndex = 1;
185
+ const teamIdMap = /* @__PURE__ */ new Map();
186
+ const submissionsIdMap = /* @__PURE__ */ new Map();
187
+ rank.teams.forEach((team) => {
188
+ let name = team.name;
189
+ if (team.organization) {
190
+ name = `${team.organization} - ${name}`;
191
+ }
192
+ if (team.members) {
193
+ name = `${name} - ${team.membersToString}`;
194
+ }
195
+ res += `@t ${teamIndex},0,1,${name}
196
+ `;
197
+ teamIdMap.set(team.id, teamIndex);
198
+ teamIndex++;
199
+ {
200
+ const mp = /* @__PURE__ */ new Map();
201
+ rank.contest.problems.forEach((p) => {
202
+ mp.set(p.id, 0);
203
+ });
204
+ submissionsIdMap.set(team.id, mp);
205
+ }
206
+ });
207
+ for (let i = 0; i < 100; i++) {
208
+ res += `@t ${teamIndex},0,1,\u041F\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u044C \u043A\u043E\u043C\u0430\u043D\u0434\u0443
209
+ `;
210
+ teamIndex++;
211
+ }
212
+ rank.getSubmissions().forEach((submission) => {
213
+ const teamId = submission.teamId;
214
+ const problemId = submission.problemId;
215
+ const problem = rank.contest.problemsMap.get(problemId);
216
+ if (!problem) {
217
+ return;
218
+ }
219
+ const status = this.submissionStatusToCodeforcesGymDatStatus(submission.status);
220
+ submissionsIdMap.get(teamId).set(problemId, submissionsIdMap.get(teamId).get(problemId) + 1);
221
+ res += `@s ${teamIdMap.get(teamId)},${problem.label},${submissionsIdMap.get(teamId)?.get(problemId)},${submission.timestamp},${status}
222
+ `;
223
+ });
224
+ return res;
225
+ }
226
+ submissionStatusToCodeforcesGymDatStatus(status) {
227
+ if (isAccepted(status)) {
228
+ return "OK";
229
+ }
230
+ if (status === SubmissionStatus.WRONG_ANSWER) {
231
+ return "WA";
232
+ }
233
+ if (status === SubmissionStatus.TIME_LIMIT_EXCEEDED) {
234
+ return "TL";
235
+ }
236
+ if (status === SubmissionStatus.MEMORY_LIMIT_EXCEEDED) {
237
+ return "ML";
238
+ }
239
+ if (status === SubmissionStatus.OUTPUT_LIMIT_EXCEEDED) {
240
+ return "IL";
241
+ }
242
+ if (status === SubmissionStatus.PRESENTATION_ERROR) {
243
+ return "PE";
244
+ }
245
+ if (status === SubmissionStatus.RUNTIME_ERROR) {
246
+ return "RT";
247
+ }
248
+ if (status === SubmissionStatus.COMPILATION_ERROR || isNotCalculatedPenaltyStatus(status)) {
249
+ return "CE";
250
+ }
251
+ if (isPending(status)) {
252
+ return "PD";
253
+ }
254
+ return "RJ";
255
+ }
256
+ }
257
+
258
+ class GeneralExcelConverter {
259
+ constructor() {
260
+ }
261
+ convert(rank) {
262
+ const workbook = XLSX.utils.book_new();
263
+ const aoa = this.convertToAoa(rank);
264
+ const mainWorksheet = XLSX.utils.aoa_to_sheet(aoa);
265
+ const cols = [];
266
+ const head = aoa[1];
267
+ for (let j = 0; j < head.length; j++) {
268
+ let wch = 10;
269
+ for (let i = 1; i < aoa.length; i++) {
270
+ wch = Math.max(wch, stringWidth(aoa[i][j]) + 2);
271
+ }
272
+ cols.push({
273
+ wch
274
+ });
275
+ }
276
+ mainWorksheet["!cols"] = cols;
277
+ {
278
+ const mergeRange = { s: { r: 0, c: 0 }, e: { r: 0, c: head.length - 1 } };
279
+ const merges = [{ s: mergeRange.s, e: mergeRange.e }];
280
+ mainWorksheet["!merges"] = merges;
281
+ }
282
+ const font = {
283
+ name: "Arial Unicode MS",
284
+ bold: false,
285
+ italic: false,
286
+ sz: 12
287
+ };
288
+ const borderStyle = {
289
+ style: "thin"
290
+ };
291
+ const cellStyle = {
292
+ alignment: {
293
+ vertical: "center",
294
+ horizontal: "center"
295
+ },
296
+ border: {
297
+ top: borderStyle,
298
+ bottom: borderStyle,
299
+ left: borderStyle,
300
+ right: borderStyle
301
+ },
302
+ font
303
+ };
304
+ for (let i = 1; i < aoa.length; i++) {
305
+ for (let j = 0; j < aoa[i].length; j++) {
306
+ const cellAddress = XLSX.utils.encode_cell({ r: i, c: j });
307
+ const cell = mainWorksheet[cellAddress];
308
+ cell.s = cellStyle;
309
+ }
310
+ }
311
+ {
312
+ const cellAddress = XLSX.utils.encode_cell({ r: 0, c: 0 });
313
+ const cell = mainWorksheet[cellAddress];
314
+ const titleStyle = _.cloneDeep(cellStyle);
315
+ titleStyle.font.sz = 28;
316
+ titleStyle.font.bold = true;
317
+ cell.s = titleStyle;
318
+ }
319
+ XLSX.utils.book_append_sheet(workbook, mainWorksheet, "Scoreboard");
320
+ return workbook;
321
+ }
322
+ convertAndWrite(rank, filename) {
323
+ return XLSX.writeFile(
324
+ this.convert(rank),
325
+ filename,
326
+ {
327
+ compression: true
328
+ }
329
+ );
330
+ }
331
+ convertToAoa(rank) {
332
+ const aoa = [];
333
+ {
334
+ aoa.push([rank.contest.name]);
335
+ }
336
+ {
337
+ const head = [];
338
+ head.push("Rank");
339
+ if (rank.contest.organization) {
340
+ head.push(`${rank.contest.organization} Rank`);
341
+ head.push(rank.contest.organization);
342
+ }
343
+ head.push("Name", "Solved", "Penalty", ...rank.contest.problems.map((p) => p.label), "Dict");
344
+ aoa.push(head);
345
+ }
346
+ for (const team of rank.teams) {
347
+ const arr = [];
348
+ arr.push(team.rank.toString());
349
+ if (team.organization) {
350
+ if (team.organizationRank !== -1) {
351
+ arr.push(team.organizationRank.toString());
352
+ } else {
353
+ arr.push("");
354
+ }
355
+ arr.push(team.organization);
356
+ }
357
+ arr.push(team.name, team.solvedProblemNum.toString(), team.penaltyToMinute.toString());
358
+ for (const p of team.problemStatistics) {
359
+ if (p.isUnSubmitted) {
360
+ arr.push("-");
361
+ }
362
+ if (p.isSolved) {
363
+ arr.push(`+${p.totalCount}(${p.solvedTimestampToMinute})`);
364
+ }
365
+ if (p.isWrongAnswer) {
366
+ arr.push(`-${p.failedCount}`);
367
+ }
368
+ if (p.isPending) {
369
+ arr.push(`? ${p.failedCount} + ${p.pendingCount}`);
370
+ }
371
+ }
372
+ arr.push(`${team.dict}%`);
373
+ aoa.push(arr);
374
+ }
375
+ return aoa;
376
+ }
377
+ }
378
+
379
+ var MedalType = /* @__PURE__ */ ((MedalType2) => {
380
+ MedalType2[MedalType2["UNKNOWN"] = 0] = "UNKNOWN";
381
+ MedalType2[MedalType2["GOLD"] = 1] = "GOLD";
382
+ MedalType2[MedalType2["SILVER"] = 2] = "SILVER";
383
+ MedalType2[MedalType2["BRONZE"] = 3] = "BRONZE";
384
+ MedalType2[MedalType2["HONORABLE"] = 4] = "HONORABLE";
385
+ return MedalType2;
386
+ })(MedalType || {});
387
+ class Award {
388
+ constructor() {
389
+ this.medalType = 0 /* UNKNOWN */;
390
+ this.minRank = 0;
391
+ this.maxRank = 0;
392
+ }
393
+ }
394
+
395
+ function calcDict(attemptedNum, solvedNum) {
396
+ if (solvedNum === 0) {
397
+ return 0;
398
+ }
399
+ return Math.floor((attemptedNum - solvedNum) * 100 / attemptedNum);
400
+ }
401
+
73
402
  class ProblemStatistics {
74
403
  constructor() {
75
404
  this.acceptedNum = 0;
@@ -175,6 +504,12 @@ class TeamProblemStatistics {
175
504
  }
176
505
  return Math.floor(this.solvedTimestamp / 60) * 60 + this.failedCount * this.contestPenalty;
177
506
  }
507
+ get penaltyToMinute() {
508
+ return Math.floor(this.penalty / 60);
509
+ }
510
+ get solvedTimestampToMinute() {
511
+ return Math.floor(this.solvedTimestamp / 60);
512
+ }
178
513
  }
179
514
 
180
515
  class Group {
@@ -424,208 +759,6 @@ function createContestIndexList(contestListJSON) {
424
759
  return contestIndexList;
425
760
  }
426
761
 
427
- function stringToSubmissionStatus(status) {
428
- status = status.toUpperCase().replace(" ", "_");
429
- if (["OK", "AC", SubmissionStatus.ACCEPTED.toString()].includes(status)) {
430
- return SubmissionStatus.ACCEPTED;
431
- }
432
- if ([SubmissionStatus.CORRECT.toString()].includes(status)) {
433
- return SubmissionStatus.ACCEPTED;
434
- }
435
- if ([SubmissionStatus.PARTIALLY_CORRECT.toString()].includes(status)) {
436
- return SubmissionStatus.PARTIALLY_CORRECT;
437
- }
438
- if (["WA", SubmissionStatus.WRONG_ANSWER.toString()].includes(status)) {
439
- return SubmissionStatus.WRONG_ANSWER;
440
- }
441
- if (["RJ", "INCORRECT", SubmissionStatus.REJECTED.toString()].includes(status)) {
442
- return SubmissionStatus.REJECTED;
443
- }
444
- if (["PD", SubmissionStatus.PENDING.toString()].includes(status)) {
445
- return SubmissionStatus.PENDING;
446
- }
447
- if ([SubmissionStatus.WAITING.toString()].includes(status)) {
448
- return SubmissionStatus.WAITING;
449
- }
450
- if ([SubmissionStatus.JUDGING.toString()].includes(status)) {
451
- return SubmissionStatus.JUDGING;
452
- }
453
- if ([SubmissionStatus.FROZEN.toString()].includes(status)) {
454
- return SubmissionStatus.FROZEN;
455
- }
456
- if (["CE", SubmissionStatus.COMPILATION_ERROR.toString()].includes(status)) {
457
- return SubmissionStatus.COMPILATION_ERROR;
458
- }
459
- if (["PE", SubmissionStatus.PRESENTATION_ERROR.toString()].includes(status)) {
460
- return SubmissionStatus.PRESENTATION_ERROR;
461
- }
462
- if (["TL", "TLE", SubmissionStatus.TIME_LIMIT_EXCEEDED.toString()].includes(status)) {
463
- return SubmissionStatus.TIME_LIMIT_EXCEEDED;
464
- }
465
- if (["ML", "MLE", SubmissionStatus.MEMORY_LIMIT_EXCEEDED.toString()].includes(status)) {
466
- return SubmissionStatus.MEMORY_LIMIT_EXCEEDED;
467
- }
468
- if (["OL", "OLE", SubmissionStatus.OUTPUT_LIMIT_EXCEEDED.toString()].includes(status)) {
469
- return SubmissionStatus.OUTPUT_LIMIT_EXCEEDED;
470
- }
471
- if (["IL", "ILE", SubmissionStatus.IDLENESS_LIMIT_EXCEEDED.toString()].includes(status)) {
472
- return SubmissionStatus.IDLENESS_LIMIT_EXCEEDED;
473
- }
474
- if (["RT", "RE", "RTE", SubmissionStatus.RUNTIME_ERROR.toString()].includes(status)) {
475
- return SubmissionStatus.RUNTIME_ERROR;
476
- }
477
- if (["JE", SubmissionStatus.JUDGEMENT_FAILED.toString()].includes(status)) {
478
- return SubmissionStatus.JUDGEMENT_FAILED;
479
- }
480
- if (["SE", SubmissionStatus.SYSTEM_ERROR.toString()].includes(status)) {
481
- return SubmissionStatus.SYSTEM_ERROR;
482
- }
483
- if ([SubmissionStatus.HACKED.toString()].includes(status)) {
484
- return SubmissionStatus.HACKED;
485
- }
486
- if ([SubmissionStatus.CONFIGURATION_ERROR.toString()].includes(status)) {
487
- return SubmissionStatus.CONFIGURATION_ERROR;
488
- }
489
- if ([SubmissionStatus.CANCELED.toString()].includes(status)) {
490
- return SubmissionStatus.CANCELED;
491
- }
492
- if ([SubmissionStatus.SKIPPED.toString()].includes(status)) {
493
- return SubmissionStatus.SKIPPED;
494
- }
495
- if ([SubmissionStatus.SECURITY_VIOLATED.toString()].includes(status)) {
496
- return SubmissionStatus.SECURITY_VIOLATED;
497
- }
498
- if ([SubmissionStatus.DENIAL_OF_JUDGEMENT.toString()].includes(status)) {
499
- return SubmissionStatus.DENIAL_OF_JUDGEMENT;
500
- }
501
- return SubmissionStatus.UNKNOWN;
502
- }
503
- function isAccepted(status) {
504
- const acceptedArray = [SubmissionStatus.ACCEPTED, SubmissionStatus.CORRECT];
505
- return acceptedArray.includes(status);
506
- }
507
- function isRejected(status) {
508
- const rejectArray = [
509
- SubmissionStatus.RUNTIME_ERROR,
510
- SubmissionStatus.TIME_LIMIT_EXCEEDED,
511
- SubmissionStatus.MEMORY_LIMIT_EXCEEDED,
512
- SubmissionStatus.OUTPUT_LIMIT_EXCEEDED,
513
- SubmissionStatus.IDLENESS_LIMIT_EXCEEDED,
514
- SubmissionStatus.WRONG_ANSWER,
515
- SubmissionStatus.REJECTED,
516
- SubmissionStatus.JUDGEMENT_FAILED,
517
- SubmissionStatus.HACKED
518
- ];
519
- return rejectArray.includes(status);
520
- }
521
- function isPending(status) {
522
- const pendingArray = [
523
- SubmissionStatus.PENDING,
524
- SubmissionStatus.WAITING,
525
- SubmissionStatus.JUDGING,
526
- SubmissionStatus.FROZEN
527
- ];
528
- return pendingArray.includes(status);
529
- }
530
- function isNotCalculatedPenaltyStatus(status) {
531
- const isNotCalculatedPenaltyArray = [
532
- SubmissionStatus.COMPILATION_ERROR,
533
- SubmissionStatus.PRESENTATION_ERROR,
534
- SubmissionStatus.CONFIGURATION_ERROR,
535
- SubmissionStatus.SYSTEM_ERROR,
536
- SubmissionStatus.CANCELED,
537
- SubmissionStatus.SKIPPED,
538
- SubmissionStatus.UNKNOWN,
539
- SubmissionStatus.UNDEFINED
540
- ];
541
- return isNotCalculatedPenaltyArray.includes(status);
542
- }
543
-
544
- function submissionStatusToCodeforcesGymDatStatus(status) {
545
- if (isAccepted(status)) {
546
- return "OK";
547
- }
548
- if (status === SubmissionStatus.WRONG_ANSWER) {
549
- return "WA";
550
- }
551
- if (status === SubmissionStatus.TIME_LIMIT_EXCEEDED) {
552
- return "TL";
553
- }
554
- if (status === SubmissionStatus.MEMORY_LIMIT_EXCEEDED) {
555
- return "ML";
556
- }
557
- if (status === SubmissionStatus.OUTPUT_LIMIT_EXCEEDED) {
558
- return "IL";
559
- }
560
- if (status === SubmissionStatus.PRESENTATION_ERROR) {
561
- return "PE";
562
- }
563
- if (status === SubmissionStatus.RUNTIME_ERROR) {
564
- return "RT";
565
- }
566
- if (status === SubmissionStatus.COMPILATION_ERROR || isNotCalculatedPenaltyStatus(status)) {
567
- return "CE";
568
- }
569
- if (isPending(status)) {
570
- return "PD";
571
- }
572
- return "RJ";
573
- }
574
- function rankToCodeforcesGymDAT(rank) {
575
- let res = "";
576
- res += `@contest "${rank.contest.name}"
577
- @contlen ${Math.floor(dayjs.duration(rank.contest.endTime.diff(rank.contest.startTime)).asMinutes())}
578
- @problems ${rank.contest.problems.length}
579
- @teams ${rank.teams.length + 100}
580
- @submissions ${rank.submissions.length}
581
- `;
582
- rank.contest.problems.forEach((p) => {
583
- res += `@p ${p.label},${p.label},20,0
584
- `;
585
- });
586
- let teamIndex = 1;
587
- const teamIdMap = /* @__PURE__ */ new Map();
588
- const submissionsIdMap = /* @__PURE__ */ new Map();
589
- rank.teams.forEach((team) => {
590
- let name = team.name;
591
- if (team.organization) {
592
- name = `${team.organization} - ${name}`;
593
- }
594
- if (team.members) {
595
- name = `${name} - ${team.membersToString}`;
596
- }
597
- res += `@t ${teamIndex},0,1,${name}
598
- `;
599
- teamIdMap.set(team.id, teamIndex);
600
- teamIndex++;
601
- {
602
- const mp = /* @__PURE__ */ new Map();
603
- rank.contest.problems.forEach((p) => {
604
- mp.set(p.id, 0);
605
- });
606
- submissionsIdMap.set(team.id, mp);
607
- }
608
- });
609
- for (let i = 0; i < 100; i++) {
610
- res += `@t ${teamIndex},0,1,\u041F\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u044C \u043A\u043E\u043C\u0430\u043D\u0434\u0443
611
- `;
612
- teamIndex++;
613
- }
614
- rank.getSubmissions().forEach((submission) => {
615
- const teamId = submission.teamId;
616
- const problemId = submission.problemId;
617
- const problem = rank.contest.problemsMap.get(problemId);
618
- if (!problem) {
619
- return;
620
- }
621
- const status = submissionStatusToCodeforcesGymDatStatus(submission.status);
622
- submissionsIdMap.get(teamId).set(problemId, submissionsIdMap.get(teamId).get(problemId) + 1);
623
- res += `@s ${teamIdMap.get(teamId)},${problem.label},${submissionsIdMap.get(teamId)?.get(problemId)},${submission.timestamp},${status}
624
- `;
625
- });
626
- return res;
627
- }
628
-
629
762
  function getImageSource(image) {
630
763
  if (image?.url) {
631
764
  return image.url;
@@ -1227,4 +1360,4 @@ class Resolver extends Rank {
1227
1360
  }
1228
1361
  }
1229
1362
 
1230
- export { Award, Contest, ContestIndex, ContestIndexConfig, MedalType, PlaceChartPointData, Problem, ProblemStatistics, Rank, RankOptions, RankStatistics, Resolver, Submission, Team, TeamProblemStatistics, calcDict, createContest, createContestIndex, createContestIndexList, createDayJS, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, rankToCodeforcesGymDAT, stringToSubmissionStatus };
1363
+ export { Award, CodeforcesGymGhostDATConverter, Contest, ContestIndex, ContestIndexConfig, GeneralExcelConverter, MedalType, PlaceChartPointData, Problem, ProblemStatistics, Rank, RankOptions, RankStatistics, Resolver, Submission, Team, TeamProblemStatistics, calcDict, createContest, createContestIndex, createContestIndexList, createDayJS, createProblem, createProblems, createProblemsByProblemIds, createSubmission, createSubmissions, createTeam, createTeams, getImageSource, getTimeDiff, getTimestamp, isAccepted, isNotCalculatedPenaltyStatus, isPending, isRejected, stringToSubmissionStatus };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xcpcio/core",
3
- "version": "0.12.0",
3
+ "version": "0.14.0",
4
4
  "description": "XCPCIO Core",
5
5
  "author": "Dup4 <lyuzhi.pan@gmail.com>",
6
6
  "license": "MIT",
@@ -42,7 +42,9 @@
42
42
  "dependencies": {
43
43
  "dayjs": "^1.11.8",
44
44
  "lodash": "^4.17.21",
45
- "@xcpcio/types": "0.12.0"
45
+ "string-width": "^6.1.0",
46
+ "xlsx-js-style": "^1.2.0",
47
+ "@xcpcio/types": "0.14.0"
46
48
  },
47
49
  "devDependencies": {
48
50
  "@babel/types": "^7.22.4",