@xcpcio/core 0.58.3 → 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/package.json +11 -22
- 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
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import type { IRatingHistory } from "@xcpcio/types";
|
|
2
|
-
import type { Persons } from "../person";
|
|
3
|
-
import type { dayjs } from "../utils";
|
|
4
|
-
|
|
5
|
-
import { Person } from "../person";
|
|
6
|
-
import { createDayJS } from "../utils";
|
|
7
|
-
|
|
8
|
-
export class RatingHistory {
|
|
9
|
-
rank: number;
|
|
10
|
-
rating: number;
|
|
11
|
-
|
|
12
|
-
teamName: string;
|
|
13
|
-
organization: string;
|
|
14
|
-
|
|
15
|
-
members: Persons;
|
|
16
|
-
coaches: Persons;
|
|
17
|
-
|
|
18
|
-
contestID: string;
|
|
19
|
-
contestName: string;
|
|
20
|
-
contestLink: string;
|
|
21
|
-
contestTime: dayjs.Dayjs;
|
|
22
|
-
|
|
23
|
-
constructor() {
|
|
24
|
-
this.rank = 0;
|
|
25
|
-
this.rating = 0;
|
|
26
|
-
|
|
27
|
-
this.teamName = "";
|
|
28
|
-
this.organization = "";
|
|
29
|
-
|
|
30
|
-
this.members = [];
|
|
31
|
-
this.coaches = [];
|
|
32
|
-
|
|
33
|
-
this.contestID = "";
|
|
34
|
-
this.contestName = "";
|
|
35
|
-
this.contestLink = "";
|
|
36
|
-
this.contestTime = createDayJS();
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
toJSON(): IRatingHistory {
|
|
40
|
-
return {
|
|
41
|
-
rank: this.rank,
|
|
42
|
-
rating: this.rating,
|
|
43
|
-
|
|
44
|
-
teamName: this.teamName,
|
|
45
|
-
organization: this.organization,
|
|
46
|
-
|
|
47
|
-
members: this.members.map(member => member.toJSON()),
|
|
48
|
-
coaches: this.coaches.map(coach => coach.toJSON()),
|
|
49
|
-
|
|
50
|
-
contestID: this.contestID,
|
|
51
|
-
contestName: this.contestName,
|
|
52
|
-
contestLink: this.contestLink,
|
|
53
|
-
contestTime: this.contestTime.toDate(),
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
static fromJSON(iRatingHistory: IRatingHistory | string): RatingHistory {
|
|
58
|
-
if (typeof iRatingHistory === "string") {
|
|
59
|
-
iRatingHistory = JSON.parse(iRatingHistory) as IRatingHistory;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const ratingHistory = new RatingHistory();
|
|
63
|
-
ratingHistory.rank = iRatingHistory.rank;
|
|
64
|
-
ratingHistory.rating = iRatingHistory.rating;
|
|
65
|
-
|
|
66
|
-
ratingHistory.teamName = iRatingHistory.teamName;
|
|
67
|
-
ratingHistory.organization = iRatingHistory.organization;
|
|
68
|
-
|
|
69
|
-
ratingHistory.members = iRatingHistory.members.map(iMember => Person.fromJSON(iMember));
|
|
70
|
-
ratingHistory.coaches = iRatingHistory.coaches.map(iCoach => Person.fromJSON(iCoach));
|
|
71
|
-
|
|
72
|
-
ratingHistory.contestID = iRatingHistory.contestID;
|
|
73
|
-
ratingHistory.contestName = iRatingHistory.contestName;
|
|
74
|
-
ratingHistory.contestLink = iRatingHistory.contestLink;
|
|
75
|
-
ratingHistory.contestTime = createDayJS(iRatingHistory.contestTime);
|
|
76
|
-
|
|
77
|
-
return ratingHistory;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export type RatingHistories = Array<RatingHistory>;
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import type { IRatingUser } from "@xcpcio/types";
|
|
2
|
-
|
|
3
|
-
import type { Persons } from "../person";
|
|
4
|
-
import type { RatingHistories } from "./rating-history";
|
|
5
|
-
import { Person } from "../person";
|
|
6
|
-
import { RatingHistory } from "./rating-history";
|
|
7
|
-
|
|
8
|
-
export class RatingUser {
|
|
9
|
-
id: string;
|
|
10
|
-
name: string;
|
|
11
|
-
organization: string;
|
|
12
|
-
|
|
13
|
-
members: Persons;
|
|
14
|
-
coaches: Persons;
|
|
15
|
-
|
|
16
|
-
rating: number;
|
|
17
|
-
minRating: number;
|
|
18
|
-
maxRating: number;
|
|
19
|
-
|
|
20
|
-
rank: number;
|
|
21
|
-
oldRating: number;
|
|
22
|
-
|
|
23
|
-
seed: number;
|
|
24
|
-
delta: number;
|
|
25
|
-
|
|
26
|
-
ratingHistories: RatingHistories;
|
|
27
|
-
|
|
28
|
-
constructor() {
|
|
29
|
-
this.id = "";
|
|
30
|
-
this.name = "";
|
|
31
|
-
this.organization = "";
|
|
32
|
-
|
|
33
|
-
this.members = [];
|
|
34
|
-
this.coaches = [];
|
|
35
|
-
|
|
36
|
-
this.rating = 0;
|
|
37
|
-
this.minRating = 0x3F3F3F3F;
|
|
38
|
-
this.maxRating = -0x3F3F3F3F;
|
|
39
|
-
|
|
40
|
-
this.rank = 0;
|
|
41
|
-
this.oldRating = 0;
|
|
42
|
-
|
|
43
|
-
this.seed = 1.0;
|
|
44
|
-
this.delta = 0;
|
|
45
|
-
|
|
46
|
-
this.ratingHistories = [];
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
UpdateRating(rating: number) {
|
|
50
|
-
this.rating = rating;
|
|
51
|
-
this.minRating = Math.min(this.minRating, rating);
|
|
52
|
-
this.maxRating = Math.max(this.maxRating, rating);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
toJSON(): IRatingUser {
|
|
56
|
-
return {
|
|
57
|
-
id: this.id,
|
|
58
|
-
name: this.name,
|
|
59
|
-
organization: this.organization,
|
|
60
|
-
|
|
61
|
-
members: this.members.map(member => member.toJSON()),
|
|
62
|
-
coaches: this.coaches.map(coach => coach.toJSON()),
|
|
63
|
-
|
|
64
|
-
rating: this.rating,
|
|
65
|
-
minRating: this.minRating,
|
|
66
|
-
maxRating: this.maxRating,
|
|
67
|
-
|
|
68
|
-
ratingHistories: this.ratingHistories.map(ratingHistory => ratingHistory.toJSON()),
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
static fromJSON(iRatingUser: IRatingUser | string): RatingUser {
|
|
73
|
-
if (typeof iRatingUser === "string") {
|
|
74
|
-
iRatingUser = JSON.parse(iRatingUser) as IRatingUser;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const ratingUser = new RatingUser();
|
|
78
|
-
|
|
79
|
-
ratingUser.id = iRatingUser.id;
|
|
80
|
-
ratingUser.name = iRatingUser.name;
|
|
81
|
-
ratingUser.organization = iRatingUser.organization;
|
|
82
|
-
|
|
83
|
-
ratingUser.members = iRatingUser.members.map(member => Person.fromJSON(member));
|
|
84
|
-
ratingUser.coaches = iRatingUser.coaches.map(coach => Person.fromJSON(coach));
|
|
85
|
-
|
|
86
|
-
ratingUser.rating = iRatingUser.rating;
|
|
87
|
-
ratingUser.minRating = iRatingUser.minRating;
|
|
88
|
-
ratingUser.maxRating = iRatingUser.maxRating;
|
|
89
|
-
|
|
90
|
-
for (const iRatingHistory of iRatingUser.ratingHistories) {
|
|
91
|
-
ratingUser.ratingHistories.push(RatingHistory.fromJSON(iRatingHistory));
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return ratingUser;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export type RatingUsers = Array<RatingUser>;
|
|
99
|
-
export type RatingUserMap = Map<string, RatingUser>;
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
export enum RatingLevel {
|
|
2
|
-
NEWBIE = "NEWBIE",
|
|
3
|
-
PUPIL = "PUPIL",
|
|
4
|
-
SPECIALIST = "SPECIALIST",
|
|
5
|
-
EXPERT = "EXPERT",
|
|
6
|
-
CANDIDATE_MASTER = "CANDIDATE_MASTER",
|
|
7
|
-
MASTER = "MASTER",
|
|
8
|
-
INTERNATIONAL_MASTER = "INTERNATIONAL_MASTER",
|
|
9
|
-
GRANDMASTER = "GRANDMASTER",
|
|
10
|
-
INTERNATIONAL_GRANDMASTER = "INTERNATIONAL_GRANDMASTER",
|
|
11
|
-
LEGENDARY_GRANDMASTER = "LEGENDARY_GRANDMASTER",
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const RatingLevelToString: { [key in RatingLevel]: string } = {
|
|
15
|
-
[RatingLevel.NEWBIE]: "Newbie",
|
|
16
|
-
[RatingLevel.PUPIL]: "Pupil",
|
|
17
|
-
[RatingLevel.SPECIALIST]: "Specialist",
|
|
18
|
-
[RatingLevel.EXPERT]: "Expert",
|
|
19
|
-
[RatingLevel.CANDIDATE_MASTER]: "Candidate Master",
|
|
20
|
-
[RatingLevel.MASTER]: "Master",
|
|
21
|
-
[RatingLevel.INTERNATIONAL_MASTER]: "International Master",
|
|
22
|
-
[RatingLevel.GRANDMASTER]: "Grandmaster",
|
|
23
|
-
[RatingLevel.INTERNATIONAL_GRANDMASTER]: "International Grandmaster",
|
|
24
|
-
[RatingLevel.LEGENDARY_GRANDMASTER]: "Legendary Grandmaster",
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export class RatingUtility {
|
|
28
|
-
static getRatingLevel(rating: number): RatingLevel {
|
|
29
|
-
if (rating >= 3000) {
|
|
30
|
-
return RatingLevel.LEGENDARY_GRANDMASTER;
|
|
31
|
-
} else if (rating >= 2600) {
|
|
32
|
-
return RatingLevel.INTERNATIONAL_GRANDMASTER;
|
|
33
|
-
} else if (rating >= 2400) {
|
|
34
|
-
return RatingLevel.GRANDMASTER;
|
|
35
|
-
} else if (rating >= 2300) {
|
|
36
|
-
return RatingLevel.INTERNATIONAL_MASTER;
|
|
37
|
-
} else if (rating >= 2100) {
|
|
38
|
-
return RatingLevel.MASTER;
|
|
39
|
-
} else if (rating >= 1900) {
|
|
40
|
-
return RatingLevel.CANDIDATE_MASTER;
|
|
41
|
-
} else if (rating >= 1600) {
|
|
42
|
-
return RatingLevel.EXPERT;
|
|
43
|
-
} else if (rating >= 1400) {
|
|
44
|
-
return RatingLevel.SPECIALIST;
|
|
45
|
-
} else if (rating >= 1200) {
|
|
46
|
-
return RatingLevel.PUPIL;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return RatingLevel.NEWBIE;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
static getRatingLevelClass(ratingLevel: RatingLevel | number): string {
|
|
53
|
-
if (typeof ratingLevel === "number") {
|
|
54
|
-
return this.getRatingLevelClass(this.getRatingLevel(ratingLevel));
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
switch (ratingLevel) {
|
|
58
|
-
case RatingLevel.NEWBIE:
|
|
59
|
-
return "user-gray";
|
|
60
|
-
case RatingLevel.PUPIL:
|
|
61
|
-
return "user-green";
|
|
62
|
-
case RatingLevel.SPECIALIST:
|
|
63
|
-
return "user-cyan";
|
|
64
|
-
case RatingLevel.EXPERT:
|
|
65
|
-
return "user-blue";
|
|
66
|
-
case RatingLevel.CANDIDATE_MASTER:
|
|
67
|
-
return "user-violet";
|
|
68
|
-
case RatingLevel.MASTER:
|
|
69
|
-
return "user-orange";
|
|
70
|
-
case RatingLevel.INTERNATIONAL_MASTER:
|
|
71
|
-
return "user-orange";
|
|
72
|
-
case RatingLevel.GRANDMASTER:
|
|
73
|
-
return "user-red";
|
|
74
|
-
case RatingLevel.INTERNATIONAL_GRANDMASTER:
|
|
75
|
-
return "user-red";
|
|
76
|
-
case RatingLevel.LEGENDARY_GRANDMASTER:
|
|
77
|
-
return "user-legendary";
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
package/src/rating/rating.ts
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
import type { IRating } from "@xcpcio/types";
|
|
2
|
-
import type { Ranks } from "../rank";
|
|
3
|
-
import type { Team } from "../team";
|
|
4
|
-
import type { RatingUserMap, RatingUsers } from "./rating-user";
|
|
5
|
-
|
|
6
|
-
import { createPersons } from "../person";
|
|
7
|
-
import { RatingCalculator } from "./rating-calculator";
|
|
8
|
-
import { RatingHistory } from "./rating-history";
|
|
9
|
-
import { RatingUser } from "./rating-user";
|
|
10
|
-
|
|
11
|
-
export class Rating {
|
|
12
|
-
id: string;
|
|
13
|
-
name: string;
|
|
14
|
-
baseRating: number;
|
|
15
|
-
|
|
16
|
-
contestIDs: string[];
|
|
17
|
-
users: RatingUsers;
|
|
18
|
-
|
|
19
|
-
ranks: Ranks;
|
|
20
|
-
userMap: RatingUserMap;
|
|
21
|
-
|
|
22
|
-
constructor() {
|
|
23
|
-
this.id = "";
|
|
24
|
-
this.name = "";
|
|
25
|
-
this.baseRating = 1500;
|
|
26
|
-
|
|
27
|
-
this.contestIDs = [];
|
|
28
|
-
this.users = [];
|
|
29
|
-
|
|
30
|
-
this.ranks = [];
|
|
31
|
-
this.userMap = new Map<string, RatingUser>();
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
buildRating() {
|
|
35
|
-
for (const rank of this.ranks) {
|
|
36
|
-
rank.buildRank();
|
|
37
|
-
|
|
38
|
-
const ratingCalculator = new RatingCalculator();
|
|
39
|
-
|
|
40
|
-
for (const t of rank.teams) {
|
|
41
|
-
const id = this.generateTeamId(t);
|
|
42
|
-
|
|
43
|
-
let u = null;
|
|
44
|
-
|
|
45
|
-
if (!this.userMap.has(id)) {
|
|
46
|
-
u = new RatingUser();
|
|
47
|
-
u.id = id;
|
|
48
|
-
u.name = t.name;
|
|
49
|
-
u.organization = t.organization;
|
|
50
|
-
|
|
51
|
-
u.members = createPersons(t.members ?? []);
|
|
52
|
-
u.coaches = createPersons(t.coach ?? []);
|
|
53
|
-
|
|
54
|
-
u.rank = t.rank;
|
|
55
|
-
u.oldRating = this.baseRating;
|
|
56
|
-
u.UpdateRating(this.baseRating);
|
|
57
|
-
|
|
58
|
-
this.userMap.set(id, u);
|
|
59
|
-
this.users.push(u);
|
|
60
|
-
|
|
61
|
-
ratingCalculator.users.push(u);
|
|
62
|
-
} else {
|
|
63
|
-
u = this.userMap.get(id)!;
|
|
64
|
-
u.rank = t.rank;
|
|
65
|
-
u.oldRating = u.rating;
|
|
66
|
-
ratingCalculator.users.push(u);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
{
|
|
70
|
-
const h = new RatingHistory();
|
|
71
|
-
h.rank = t.rank;
|
|
72
|
-
h.rating = u.rating;
|
|
73
|
-
|
|
74
|
-
h.teamName = t.name;
|
|
75
|
-
h.organization = t.organization;
|
|
76
|
-
|
|
77
|
-
h.members = createPersons(t.members ?? []);
|
|
78
|
-
h.coaches = createPersons(t.coach ?? []);
|
|
79
|
-
|
|
80
|
-
h.contestID = rank.contest.id;
|
|
81
|
-
h.contestLink = h.contestID;
|
|
82
|
-
h.contestName = rank.contest.name;
|
|
83
|
-
h.contestTime = rank.contest.startTime;
|
|
84
|
-
|
|
85
|
-
u.ratingHistories.push(h);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
ratingCalculator.calculate();
|
|
90
|
-
|
|
91
|
-
for (const u of ratingCalculator.users) {
|
|
92
|
-
u.ratingHistories.at(-1)!.rating = u.rating;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
generateTeamId(t: Team) {
|
|
98
|
-
const persons = createPersons(t.members ?? []);
|
|
99
|
-
if (persons.length > 0) {
|
|
100
|
-
return persons.map(person => person.name.trim()).sort().join("|");
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return `${t.organization}-${t.name}`;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
toJSON(): IRating {
|
|
107
|
-
return {
|
|
108
|
-
id: this.id,
|
|
109
|
-
name: this.name,
|
|
110
|
-
baseRating: this.baseRating,
|
|
111
|
-
|
|
112
|
-
contestIDs: this.contestIDs,
|
|
113
|
-
users: this.users.map(ratingUser => ratingUser.toJSON()),
|
|
114
|
-
};
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
static fromJSON(iRating: IRating | string): Rating {
|
|
118
|
-
if (typeof iRating === "string") {
|
|
119
|
-
iRating = JSON.parse(iRating) as IRating;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const rating = new Rating();
|
|
123
|
-
|
|
124
|
-
rating.id = iRating.id;
|
|
125
|
-
rating.name = iRating.name;
|
|
126
|
-
rating.baseRating = iRating.baseRating;
|
|
127
|
-
|
|
128
|
-
rating.contestIDs = iRating.contestIDs;
|
|
129
|
-
|
|
130
|
-
for (const iUser of iRating.users) {
|
|
131
|
-
rating.users.push(RatingUser.fromJSON(iUser));
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return rating;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { TeamProblemStatistics } from "./problem";
|
|
2
|
-
import { Team } from "./team";
|
|
3
|
-
|
|
4
|
-
export class ResolverOperation {
|
|
5
|
-
id: number;
|
|
6
|
-
|
|
7
|
-
team: Team;
|
|
8
|
-
problemIx: number;
|
|
9
|
-
|
|
10
|
-
beforeTeamProblemStatistics: TeamProblemStatistics;
|
|
11
|
-
afterTeamProblemStatistics: TeamProblemStatistics;
|
|
12
|
-
|
|
13
|
-
constructor() {
|
|
14
|
-
this.id = 0;
|
|
15
|
-
|
|
16
|
-
this.team = new Team();
|
|
17
|
-
this.problemIx = 0;
|
|
18
|
-
|
|
19
|
-
this.beforeTeamProblemStatistics = new TeamProblemStatistics();
|
|
20
|
-
this.afterTeamProblemStatistics = new TeamProblemStatistics();
|
|
21
|
-
}
|
|
22
|
-
}
|
package/src/resolver-vue.ts
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
import type { Contest } from "./contest";
|
|
2
|
-
import type { Submissions } from "./submission";
|
|
3
|
-
import type { Teams } from "./team";
|
|
4
|
-
|
|
5
|
-
import { Resolver } from "./resolver";
|
|
6
|
-
import { Team } from "./team";
|
|
7
|
-
|
|
8
|
-
export class ResolverVue extends Resolver {
|
|
9
|
-
readonly FLASHING_TIME_MS = 100;
|
|
10
|
-
readonly ROLLING_TIME_MS = 600;
|
|
11
|
-
|
|
12
|
-
maxIndex: number;
|
|
13
|
-
currentIndex: number;
|
|
14
|
-
|
|
15
|
-
maxOpIndex: number;
|
|
16
|
-
currentOpIndex: number;
|
|
17
|
-
|
|
18
|
-
oldRank: number;
|
|
19
|
-
newRank: number;
|
|
20
|
-
|
|
21
|
-
currentTeamId: string;
|
|
22
|
-
currentProblemIndex: number;
|
|
23
|
-
|
|
24
|
-
problemFlashingEnded: boolean;
|
|
25
|
-
duringAnimation: boolean;
|
|
26
|
-
|
|
27
|
-
startScrollUp: boolean;
|
|
28
|
-
startScrollDown: boolean;
|
|
29
|
-
|
|
30
|
-
constructor(contest: Contest, teams: Teams, submissions: Submissions) {
|
|
31
|
-
super(contest, teams, submissions);
|
|
32
|
-
|
|
33
|
-
this.maxIndex = 0;
|
|
34
|
-
this.currentIndex = 0;
|
|
35
|
-
|
|
36
|
-
this.maxOpIndex = 0;
|
|
37
|
-
this.currentOpIndex = 0;
|
|
38
|
-
|
|
39
|
-
this.oldRank = -1;
|
|
40
|
-
this.newRank = -1;
|
|
41
|
-
|
|
42
|
-
this.currentTeamId = "";
|
|
43
|
-
this.currentProblemIndex = -1;
|
|
44
|
-
|
|
45
|
-
this.problemFlashingEnded = true;
|
|
46
|
-
this.duringAnimation = false;
|
|
47
|
-
|
|
48
|
-
this.startScrollUp = false;
|
|
49
|
-
this.startScrollDown = false;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
buildResolver() {
|
|
53
|
-
super.buildResolver();
|
|
54
|
-
|
|
55
|
-
this.maxIndex = this.teams.length - 1;
|
|
56
|
-
this.currentIndex = this.maxIndex;
|
|
57
|
-
|
|
58
|
-
this.maxOpIndex = this.operations.length - 1;
|
|
59
|
-
this.currentOpIndex = 0;
|
|
60
|
-
|
|
61
|
-
this.oldRank = -1;
|
|
62
|
-
this.newRank = -1;
|
|
63
|
-
|
|
64
|
-
this.currentTeamId = "";
|
|
65
|
-
this.currentProblemIndex = -1;
|
|
66
|
-
|
|
67
|
-
this.problemFlashingEnded = true;
|
|
68
|
-
this.duringAnimation = false;
|
|
69
|
-
|
|
70
|
-
this.startScrollUp = false;
|
|
71
|
-
this.startScrollDown = false;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
next() {
|
|
75
|
-
if (this.duringAnimation) {
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (this.currentOpIndex > this.maxOpIndex) {
|
|
80
|
-
if (this.currentIndex > 0) {
|
|
81
|
-
this.currentIndex--;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const op = this.operations[this.currentOpIndex];
|
|
88
|
-
const pIx = op.problemIx;
|
|
89
|
-
const teamId = op.team.id;
|
|
90
|
-
const team = this.teamsMap.get(teamId) as Team;
|
|
91
|
-
const currentRank = team.rank;
|
|
92
|
-
|
|
93
|
-
if (this.currentIndex + 1 > currentRank) {
|
|
94
|
-
this.currentIndex--;
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (this.currentIndex + 1 !== currentRank) {
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
team.problemStatistics[pIx] = op.afterTeamProblemStatistics;
|
|
103
|
-
team.calcSolvedData(this.contest.options);
|
|
104
|
-
|
|
105
|
-
this.currentProblemIndex = pIx;
|
|
106
|
-
this.currentTeamId = teamId;
|
|
107
|
-
|
|
108
|
-
{
|
|
109
|
-
this.oldRank = team.rank;
|
|
110
|
-
this.newRank = this.oldRank;
|
|
111
|
-
for (let j = this.currentIndex - 1; j >= 0; j--) {
|
|
112
|
-
if (Team.compare(team, this.teams[j]) < 0) {
|
|
113
|
-
this.newRank = this.teams[j].rank;
|
|
114
|
-
} else {
|
|
115
|
-
break;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
this.currentOpIndex++;
|
|
121
|
-
|
|
122
|
-
{
|
|
123
|
-
let j = this.oldRank - 1;
|
|
124
|
-
|
|
125
|
-
while (j >= 0 && Team.compare(this.teams[j], this.teams[j - 1]) < 0) {
|
|
126
|
-
[this.teams[j], this.teams[j - 1]] = [this.teams[j - 1], this.teams[j]];
|
|
127
|
-
this.teams[j].rank = j + 1;
|
|
128
|
-
this.teams[j - 1].rank = j;
|
|
129
|
-
j--;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
rewind() {
|
|
135
|
-
if (this.duringAnimation) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
if (this.currentOpIndex < 1) {
|
|
140
|
-
return;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
this.currentOpIndex--;
|
|
144
|
-
|
|
145
|
-
const op = this.operations[this.currentOpIndex];
|
|
146
|
-
const pIx = op.problemIx;
|
|
147
|
-
const teamId = op.team.id;
|
|
148
|
-
const team = this.teamsMap.get(teamId) as Team;
|
|
149
|
-
|
|
150
|
-
team.problemStatistics[pIx] = op.beforeTeamProblemStatistics;
|
|
151
|
-
team.calcSolvedData(this.contest.options);
|
|
152
|
-
|
|
153
|
-
this.currentProblemIndex = pIx;
|
|
154
|
-
this.currentTeamId = teamId;
|
|
155
|
-
|
|
156
|
-
{
|
|
157
|
-
this.oldRank = team.rank;
|
|
158
|
-
this.newRank = this.oldRank;
|
|
159
|
-
for (let j = this.currentIndex + 1; j <= this.maxIndex; j++) {
|
|
160
|
-
if (Team.compare(team, this.teams[j]) > 0) {
|
|
161
|
-
this.newRank = this.teams[j].rank;
|
|
162
|
-
} else {
|
|
163
|
-
break;
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
{
|
|
169
|
-
let j = this.oldRank - 1;
|
|
170
|
-
let newIndex = j;
|
|
171
|
-
|
|
172
|
-
while (j < this.maxIndex && Team.compare(this.teams[j], this.teams[j + 1]) > 0) {
|
|
173
|
-
[this.teams[j], this.teams[j + 1]] = [this.teams[j + 1], this.teams[j]];
|
|
174
|
-
this.teams[j].rank = j + 1;
|
|
175
|
-
this.teams[j + 1].rank = j + 2;
|
|
176
|
-
newIndex = j + 1;
|
|
177
|
-
j++;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
this.currentIndex = newIndex;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|