@xcpcio/core 0.64.5 → 0.65.1

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 CHANGED
@@ -77,6 +77,62 @@ function isValidMedalType(medal) {
77
77
  return validMedalType.includes(medal);
78
78
  }
79
79
 
80
+ class I18nText {
81
+ texts;
82
+ fallback;
83
+ fallbackLang;
84
+ constructor() {
85
+ this.texts = /* @__PURE__ */ new Map();
86
+ }
87
+ get(lang) {
88
+ return this.texts.get(lang);
89
+ }
90
+ getOrDefault(lang) {
91
+ return (lang ? this.texts.get(lang) : void 0) || (this.fallbackLang ? this.texts.get(this.fallbackLang) : void 0) || this.fallback || "";
92
+ }
93
+ set(lang, text) {
94
+ this.texts.set(lang, text);
95
+ }
96
+ has(lang) {
97
+ return this.texts.has(lang);
98
+ }
99
+ static fromI18NStringSet(stringSet) {
100
+ const i18nText = new I18nText();
101
+ i18nText.fallback = stringSet.fallback;
102
+ i18nText.fallbackLang = stringSet.fallback_lang;
103
+ if (stringSet.texts) {
104
+ for (const [lang, text] of Object.entries(stringSet.texts)) {
105
+ i18nText.set(lang, text);
106
+ }
107
+ }
108
+ return i18nText;
109
+ }
110
+ static fromIText(text) {
111
+ if (typeof text === "string") {
112
+ const i18nText = new I18nText();
113
+ i18nText.fallback = text;
114
+ return i18nText;
115
+ }
116
+ return I18nText.fromI18NStringSet(text);
117
+ }
118
+ toI18NStringSet() {
119
+ const result = {};
120
+ if (this.fallback !== void 0) {
121
+ result.fallback = this.fallback;
122
+ }
123
+ if (this.fallbackLang !== void 0) {
124
+ result.fallback_lang = this.fallbackLang;
125
+ }
126
+ if (this.texts.size > 0) {
127
+ result.texts = {};
128
+ for (const [lang, text] of this.texts.entries()) {
129
+ result.texts[lang] = text;
130
+ }
131
+ }
132
+ return result;
133
+ }
134
+ }
135
+
80
136
  function calcDirt(attemptedNum, solvedNum) {
81
137
  if (solvedNum === 0) {
82
138
  return 0;
@@ -196,7 +252,6 @@ class Problem {
196
252
  constructor() {
197
253
  this.id = "";
198
254
  this.label = "";
199
- this.name = "";
200
255
  this.statistics = new ProblemStatistics();
201
256
  this.balloonColor = {
202
257
  background_color: "#a0f0a0",
@@ -208,7 +263,9 @@ function createProblem(problemJSON) {
208
263
  const p = new Problem();
209
264
  p.id = String(problemJSON.id);
210
265
  p.label = problemJSON.label;
211
- p.name = problemJSON.name ?? "";
266
+ if (problemJSON.name) {
267
+ p.name = I18nText.fromIText(problemJSON.name);
268
+ }
212
269
  p.timeLimit = problemJSON.time_limit;
213
270
  p.memoryLimit = problemJSON.memory_limit;
214
271
  if (problemJSON.balloon_color) {
@@ -223,7 +280,7 @@ function createProblems(problemsJSON) {
223
280
  function createProblemsByProblemIds(problemIds, balloonColors) {
224
281
  const problems = problemIds.map((label, index) => {
225
282
  const p = new Problem();
226
- p.id = String(index);
283
+ p.id = index.toString();
227
284
  p.label = label;
228
285
  return p;
229
286
  });
@@ -546,6 +603,49 @@ function createSubmissions(submissionsJSON, contest) {
546
603
  }
547
604
  }
548
605
 
606
+ class Person {
607
+ name;
608
+ cfID;
609
+ icpcID;
610
+ constructor(name) {
611
+ this.name = name ?? new I18nText();
612
+ }
613
+ toIPerson() {
614
+ return {
615
+ name: this.name.toI18NStringSet(),
616
+ cf_id: this.cfID,
617
+ icpc_id: this.icpcID
618
+ };
619
+ }
620
+ static fromIPerson(iPerson) {
621
+ const person = new Person();
622
+ person.name = I18nText.fromIText(iPerson.name);
623
+ person.cfID = iPerson.cf_id;
624
+ person.icpcID = iPerson.icpc_id;
625
+ return person;
626
+ }
627
+ }
628
+ function createPersons(iPersons) {
629
+ if (!iPersons) {
630
+ return [];
631
+ }
632
+ if (typeof iPersons === "string") {
633
+ for (const c of " ,\u3001|") {
634
+ if (iPersons.includes(c)) {
635
+ return iPersons.split(c).map((name) => new Person(I18nText.fromIText(name)));
636
+ }
637
+ }
638
+ return [new Person(I18nText.fromIText(iPersons))];
639
+ }
640
+ if (Array.isArray(iPersons)) {
641
+ if (iPersons.length > 0 && typeof iPersons[0] === "object" && "name" in iPersons[0]) {
642
+ return iPersons.map((iPerson) => Person.fromIPerson(iPerson));
643
+ }
644
+ return iPersons.map((name) => new Person(I18nText.fromIText(name)));
645
+ }
646
+ return [new Person(I18nText.fromIText(iPersons))];
647
+ }
648
+
549
649
  class PlaceChartPointData {
550
650
  timePoint;
551
651
  rank;
@@ -563,7 +663,7 @@ class Team {
563
663
  badge;
564
664
  group;
565
665
  tag;
566
- coach;
666
+ coaches;
567
667
  members;
568
668
  rank;
569
669
  originalRank;
@@ -583,10 +683,12 @@ class Team {
583
683
  se;
584
684
  constructor() {
585
685
  this.id = "";
586
- this.name = "";
686
+ this.name = new I18nText();
587
687
  this.organization = "";
588
688
  this.group = [];
589
689
  this.tag = [];
690
+ this.coaches = [];
691
+ this.members = [];
590
692
  this.rank = 0;
591
693
  this.originalRank = 0;
592
694
  this.organizationRank = -1;
@@ -627,26 +729,6 @@ class Team {
627
729
  get isGirl() {
628
730
  return this.group.includes("girl");
629
731
  }
630
- get membersToArray() {
631
- if (Array.isArray(this.members)) {
632
- return this.members;
633
- }
634
- if (typeof this.members === "string") {
635
- if (this.members.includes(", ")) {
636
- return this.members.split(", ");
637
- }
638
- if (this.members.includes("\u3001")) {
639
- return this.members.split("\u3001");
640
- }
641
- }
642
- return [];
643
- }
644
- get membersToString() {
645
- if (typeof this.members === "string") {
646
- return this.members;
647
- }
648
- return this.members?.join(", ");
649
- }
650
732
  get isEffectiveTeam() {
651
733
  return this.solvedProblemNum > 0;
652
734
  }
@@ -655,6 +737,12 @@ class Team {
655
737
  const solvedNum = this.solvedProblemNum;
656
738
  return calcDirt(attemptedNum, solvedNum);
657
739
  }
740
+ membersToString(lang) {
741
+ return this.members.map((member) => member.name.getOrDefault(lang)).join(", ");
742
+ }
743
+ coachesToString(lang) {
744
+ return this.coaches.map((member) => member.name.getOrDefault(lang)).join(", ");
745
+ }
658
746
  calcSE(totalTeams) {
659
747
  let acceptedProblemNums = 0;
660
748
  let total = 0;
@@ -742,13 +830,13 @@ class Team {
742
830
  function createTeam(teamJSON) {
743
831
  const t = new Team();
744
832
  t.id = teamJSON.id ?? teamJSON.team_id ?? "";
745
- t.name = teamJSON.name ?? teamJSON.team_name ?? "";
833
+ t.name = I18nText.fromIText(teamJSON.name ?? teamJSON.team_name ?? "");
746
834
  t.organization = teamJSON.organization ?? "";
747
835
  t.badge = teamJSON.badge;
748
836
  t.group = ___default.cloneDeep(teamJSON.group ?? []);
749
837
  t.tag = ___default.cloneDeep(teamJSON.tag ?? []);
750
- t.coach = teamJSON.coach;
751
- t.members = teamJSON.members;
838
+ t.coaches = createPersons(teamJSON.coach);
839
+ t.members = createPersons(teamJSON.members);
752
840
  if (Boolean(teamJSON.official) === true) {
753
841
  t.group.push("official");
754
842
  }
@@ -962,19 +1050,17 @@ function createContestOptions(contestOptionsJSON = {}) {
962
1050
  }
963
1051
 
964
1052
  class Group {
965
- names;
966
- defaultLang;
1053
+ name;
967
1054
  isDefault;
968
1055
  constructor() {
969
- this.names = /* @__PURE__ */ new Map();
970
- this.defaultLang = "zh-CN";
1056
+ this.name = new I18nText();
971
1057
  this.isDefault = false;
972
1058
  }
973
1059
  }
974
1060
 
975
1061
  class Contest {
976
1062
  id = "";
977
- name = "";
1063
+ name;
978
1064
  startTime;
979
1065
  endTime;
980
1066
  freezeTime;
@@ -991,9 +1077,9 @@ class Contest {
991
1077
  problemsMap;
992
1078
  statusTimeDisplay;
993
1079
  badge;
1080
+ organization;
994
1081
  medal;
995
1082
  awards;
996
- organization;
997
1083
  group;
998
1084
  tag;
999
1085
  logo;
@@ -1002,6 +1088,7 @@ class Contest {
1002
1088
  boardLink;
1003
1089
  options;
1004
1090
  constructor() {
1091
+ this.name = new I18nText();
1005
1092
  this.startTime = createDayJS();
1006
1093
  this.endTime = createDayJS();
1007
1094
  this.freezeTime = createDayJS();
@@ -1116,7 +1203,7 @@ class Contest {
1116
1203
  }
1117
1204
  function createContest(contestJSON) {
1118
1205
  const c = new Contest();
1119
- c.name = contestJSON.contest_name;
1206
+ c.name = I18nText.fromIText(contestJSON.contest_name);
1120
1207
  c.startTime = createDayJS(contestJSON.start_time);
1121
1208
  c.endTime = createDayJS(contestJSON.end_time);
1122
1209
  c.totalDurationTimestamp = c.endTime.unix() - c.startTime.unix();
@@ -1152,6 +1239,7 @@ function createContest(contestJSON) {
1152
1239
  };
1153
1240
  }
1154
1241
  c.badge = contestJSON.badge;
1242
+ c.organization = contestJSON.organization;
1155
1243
  c.medal = contestJSON.medal;
1156
1244
  (() => {
1157
1245
  if (contestJSON.medal === void 0 || contestJSON.medal === null) {
@@ -1189,26 +1277,27 @@ function createContest(contestJSON) {
1189
1277
  }
1190
1278
  }
1191
1279
  })();
1192
- c.organization = contestJSON.organization;
1193
1280
  {
1194
1281
  const g = new Group();
1195
- g.names.set("en", "All");
1196
- g.names.set("zh-CN", "\u6240\u6709\u961F\u4F0D");
1282
+ g.name.fallbackLang = "zh-CN";
1283
+ g.name.set("en", "All");
1284
+ g.name.set("zh-CN", "\u6240\u6709\u961F\u4F0D");
1197
1285
  g.isDefault = true;
1198
1286
  c.group.set("all", g);
1199
1287
  }
1200
1288
  for (const [k, v] of Object.entries(contestJSON?.group ?? {})) {
1201
1289
  let key = k;
1202
1290
  const g = new Group();
1203
- g.names.set("zh-CN", v);
1291
+ g.name.fallbackLang = "zh-CN";
1292
+ g.name.set("zh-CN", v);
1204
1293
  if (k === "official") {
1205
- g.names.set("en", "Official");
1294
+ g.name.set("en", "Official");
1206
1295
  }
1207
1296
  if (k === "unofficial") {
1208
- g.names.set("en", "Unofficial");
1297
+ g.name.set("en", "Unofficial");
1209
1298
  }
1210
1299
  if (k === "girl" || k === "girls") {
1211
- g.names.set("en", "Girls");
1300
+ g.name.set("en", "Girls");
1212
1301
  key = "girl";
1213
1302
  }
1214
1303
  c.group.set(key, g);
@@ -1235,7 +1324,7 @@ class ContestIndexConfig {
1235
1324
  unFreezeDurationTimestamp;
1236
1325
  logo;
1237
1326
  constructor() {
1238
- this.contestName = "";
1327
+ this.contestName = new I18nText();
1239
1328
  this.startTime = createDayJS();
1240
1329
  this.endTime = createDayJS();
1241
1330
  this.freezeTime = createDayJS();
@@ -1300,7 +1389,7 @@ class CodeforcesGymGhostDATConverter {
1300
1389
  }
1301
1390
  convert(rank) {
1302
1391
  let res = "";
1303
- res += `@contest "${rank.contest.name}"
1392
+ res += `@contest "${rank.contest.name.getOrDefault()}"
1304
1393
  @contlen ${Math.floor(dayjs__default.duration(rank.contest.endTime.diff(rank.contest.startTime)).asMinutes())}
1305
1394
  @problems ${rank.contest.problems.length}
1306
1395
  @teams ${rank.teams.length + 100}
@@ -1314,12 +1403,12 @@ class CodeforcesGymGhostDATConverter {
1314
1403
  const teamIdMap = /* @__PURE__ */ new Map();
1315
1404
  const submissionsIdMap = /* @__PURE__ */ new Map();
1316
1405
  rank.teams.forEach((team) => {
1317
- let name = team.name;
1406
+ let name = team.name.getOrDefault();
1318
1407
  if (team.organization) {
1319
1408
  name = `${team.organization} - ${name}`;
1320
1409
  }
1321
1410
  if (team.members) {
1322
- name = `${name} - ${team.membersToString}`;
1411
+ name = `${name} - ${team.membersToString()}`;
1323
1412
  }
1324
1413
  res += `@t ${teamIndex},0,1,"${name}"
1325
1414
  `;
@@ -1400,7 +1489,7 @@ class GeneralExcelConverter {
1400
1489
  rank.options.setGroup(k);
1401
1490
  rank.buildRank();
1402
1491
  const sheet = this.convertToSheet(rank);
1403
- XLSX__namespace.utils.book_append_sheet(workbook, sheet, v.names.get(v.defaultLang));
1492
+ XLSX__namespace.utils.book_append_sheet(workbook, sheet, v.name.getOrDefault());
1404
1493
  }
1405
1494
  return workbook;
1406
1495
  }
@@ -1487,10 +1576,10 @@ class GeneralExcelConverter {
1487
1576
  const aoa = [];
1488
1577
  const specialCells = [];
1489
1578
  const enableAwards = rank.contest.isEnableAwards(rank.options.group);
1490
- const enableMembers = (Array.isArray(rank.teams) && rank.teams[0]?.members) ?? false;
1491
- const enableCoach = rank.teams[0]?.coach ?? false;
1579
+ const enableMembers = rank.teams[0]?.members.length > 0;
1580
+ const enableCoach = rank.teams[0]?.coaches.length > 0;
1492
1581
  {
1493
- aoa.push([rank.contest.name]);
1582
+ aoa.push([rank.contest.name.getOrDefault()]);
1494
1583
  }
1495
1584
  {
1496
1585
  const head = [];
@@ -1507,7 +1596,7 @@ class GeneralExcelConverter {
1507
1596
  head.push("Member1", "Member2", "Member3");
1508
1597
  }
1509
1598
  if (enableCoach) {
1510
- head.push("Coach");
1599
+ head.push("Coaches");
1511
1600
  }
1512
1601
  head.push("Unofficial");
1513
1602
  head.push("Girl");
@@ -1524,7 +1613,7 @@ class GeneralExcelConverter {
1524
1613
  }
1525
1614
  arr.push(team.organization);
1526
1615
  }
1527
- arr.push(team.name, team.solvedProblemNum.toString(), team.penaltyToMinute.toString());
1616
+ arr.push(team.name.getOrDefault(), team.solvedProblemNum.toString(), team.penaltyToMinute.toString());
1528
1617
  for (const p of team.problemStatistics) {
1529
1618
  if (p.isUnSubmitted) {
1530
1619
  arr.push("-");
@@ -1554,19 +1643,15 @@ class GeneralExcelConverter {
1554
1643
  if (enableMembers) {
1555
1644
  const members = team.members;
1556
1645
  if (Array.isArray(members)) {
1557
- arr.push(members[0] ?? "");
1558
- arr.push(members[1] ?? "");
1559
- arr.push(members[2] ?? "");
1646
+ arr.push(members[0]?.name.getOrDefault() ?? "");
1647
+ arr.push(members[1]?.name.getOrDefault() ?? "");
1648
+ arr.push(members[2]?.name.getOrDefault() ?? "");
1560
1649
  } else {
1561
1650
  arr.push("", "", "");
1562
1651
  }
1563
1652
  }
1564
1653
  if (enableCoach) {
1565
- if (typeof team.coach === "string") {
1566
- arr.push(team.coach ?? "");
1567
- } else {
1568
- arr.push("");
1569
- }
1654
+ arr.push(team.coachesToString());
1570
1655
  }
1571
1656
  arr.push(team.isUnofficial ? "Y" : "N");
1572
1657
  arr.push(team.isGirl ? "Y" : "N");
@@ -1594,9 +1679,9 @@ class ICPCStandingsCsvConverter {
1594
1679
  problemsSolved: team.solvedProblemNum,
1595
1680
  totalTime: team.penaltyToMinute,
1596
1681
  lastProblemTime: team.lastSolvedProblemStatistics?.solvedTimestampToMinute ?? 0,
1597
- siteCitation: rank.contest.name,
1682
+ siteCitation: rank.contest.name.getOrDefault(),
1598
1683
  citation: ordinal__default(team.rank),
1599
- teamName: team.name,
1684
+ teamName: team.name.getOrDefault(),
1600
1685
  institution: team.organization
1601
1686
  };
1602
1687
  resList.push(res);
@@ -1644,37 +1729,6 @@ function getImageSource(image, asset_host) {
1644
1729
  return "";
1645
1730
  }
1646
1731
 
1647
- class Person {
1648
- name;
1649
- constructor(name = "") {
1650
- this.name = name;
1651
- }
1652
- toJSON() {
1653
- return {
1654
- name: this.name
1655
- };
1656
- }
1657
- static fromJSON(iPerson) {
1658
- if (typeof iPerson === "string") {
1659
- iPerson = JSON.parse(iPerson);
1660
- }
1661
- const person = new Person();
1662
- person.name = iPerson.name;
1663
- return person;
1664
- }
1665
- }
1666
- function createPersons(iPersons) {
1667
- if (typeof iPersons === "string") {
1668
- for (const c of " ,\u3001|") {
1669
- if (iPersons.includes(c)) {
1670
- return iPersons.split(c).map((name) => new Person(name));
1671
- }
1672
- }
1673
- return [new Person(iPersons)];
1674
- }
1675
- return iPersons.map((name) => new Person(name));
1676
- }
1677
-
1678
1732
  class RankStatistics {
1679
1733
  teamSolvedNum;
1680
1734
  teamSolvedNumIndex;
@@ -2168,12 +2222,12 @@ class RatingHistory {
2168
2222
  constructor() {
2169
2223
  this.rank = 0;
2170
2224
  this.rating = 0;
2171
- this.teamName = "";
2225
+ this.teamName = new I18nText();
2172
2226
  this.organization = "";
2173
2227
  this.members = [];
2174
2228
  this.coaches = [];
2175
2229
  this.contestID = "";
2176
- this.contestName = "";
2230
+ this.contestName = new I18nText();
2177
2231
  this.contestLink = "";
2178
2232
  this.contestTime = createDayJS();
2179
2233
  }
@@ -2181,12 +2235,12 @@ class RatingHistory {
2181
2235
  return {
2182
2236
  rank: this.rank,
2183
2237
  rating: this.rating,
2184
- teamName: this.teamName,
2238
+ teamName: this.teamName.toI18NStringSet(),
2185
2239
  organization: this.organization,
2186
- members: this.members.map((member) => member.toJSON()),
2187
- coaches: this.coaches.map((coach) => coach.toJSON()),
2240
+ members: this.members.map((member) => member.toIPerson()),
2241
+ coaches: this.coaches.map((coach) => coach.toIPerson()),
2188
2242
  contestID: this.contestID,
2189
- contestName: this.contestName,
2243
+ contestName: this.contestName.toI18NStringSet(),
2190
2244
  contestLink: this.contestLink,
2191
2245
  contestTime: this.contestTime.toDate()
2192
2246
  };
@@ -2198,12 +2252,12 @@ class RatingHistory {
2198
2252
  const ratingHistory = new RatingHistory();
2199
2253
  ratingHistory.rank = iRatingHistory.rank;
2200
2254
  ratingHistory.rating = iRatingHistory.rating;
2201
- ratingHistory.teamName = iRatingHistory.teamName;
2255
+ ratingHistory.teamName = I18nText.fromIText(iRatingHistory.teamName);
2202
2256
  ratingHistory.organization = iRatingHistory.organization;
2203
- ratingHistory.members = iRatingHistory.members.map((iMember) => Person.fromJSON(iMember));
2204
- ratingHistory.coaches = iRatingHistory.coaches.map((iCoach) => Person.fromJSON(iCoach));
2257
+ ratingHistory.members = createPersons(iRatingHistory.members);
2258
+ ratingHistory.coaches = createPersons(iRatingHistory.coaches);
2205
2259
  ratingHistory.contestID = iRatingHistory.contestID;
2206
- ratingHistory.contestName = iRatingHistory.contestName;
2260
+ ratingHistory.contestName = I18nText.fromIText(iRatingHistory.contestName);
2207
2261
  ratingHistory.contestLink = iRatingHistory.contestLink;
2208
2262
  ratingHistory.contestTime = createDayJS(iRatingHistory.contestTime);
2209
2263
  return ratingHistory;
@@ -2226,7 +2280,7 @@ class RatingUser {
2226
2280
  ratingHistories;
2227
2281
  constructor() {
2228
2282
  this.id = "";
2229
- this.name = "";
2283
+ this.name = new I18nText();
2230
2284
  this.organization = "";
2231
2285
  this.members = [];
2232
2286
  this.coaches = [];
@@ -2247,10 +2301,10 @@ class RatingUser {
2247
2301
  toJSON() {
2248
2302
  return {
2249
2303
  id: this.id,
2250
- name: this.name,
2304
+ name: this.name.toI18NStringSet(),
2251
2305
  organization: this.organization,
2252
- members: this.members.map((member) => member.toJSON()),
2253
- coaches: this.coaches.map((coach) => coach.toJSON()),
2306
+ members: this.members.map((member) => member.toIPerson()),
2307
+ coaches: this.coaches.map((coach) => coach.toIPerson()),
2254
2308
  rating: this.rating,
2255
2309
  minRating: this.minRating,
2256
2310
  maxRating: this.maxRating,
@@ -2263,10 +2317,10 @@ class RatingUser {
2263
2317
  }
2264
2318
  const ratingUser = new RatingUser();
2265
2319
  ratingUser.id = iRatingUser.id;
2266
- ratingUser.name = iRatingUser.name;
2320
+ ratingUser.name = I18nText.fromIText(iRatingUser.name);
2267
2321
  ratingUser.organization = iRatingUser.organization;
2268
- ratingUser.members = iRatingUser.members.map((member) => Person.fromJSON(member));
2269
- ratingUser.coaches = iRatingUser.coaches.map((coach) => Person.fromJSON(coach));
2322
+ ratingUser.members = iRatingUser.members.map((member) => Person.fromIPerson(member));
2323
+ ratingUser.coaches = iRatingUser.coaches.map((coach) => Person.fromIPerson(coach));
2270
2324
  ratingUser.rating = iRatingUser.rating;
2271
2325
  ratingUser.minRating = iRatingUser.minRating;
2272
2326
  ratingUser.maxRating = iRatingUser.maxRating;
@@ -2361,7 +2415,7 @@ class Rating {
2361
2415
  userMap;
2362
2416
  constructor() {
2363
2417
  this.id = "";
2364
- this.name = "";
2418
+ this.name = new I18nText();
2365
2419
  this.baseRating = 1500;
2366
2420
  this.contestIDs = [];
2367
2421
  this.users = [];
@@ -2380,8 +2434,8 @@ class Rating {
2380
2434
  u.id = id;
2381
2435
  u.name = t.name;
2382
2436
  u.organization = t.organization;
2383
- u.members = createPersons(t.members ?? []);
2384
- u.coaches = createPersons(t.coach ?? []);
2437
+ u.members = t.members;
2438
+ u.coaches = t.coaches;
2385
2439
  u.rank = t.rank;
2386
2440
  u.oldRating = this.baseRating;
2387
2441
  u.UpdateRating(this.baseRating);
@@ -2400,8 +2454,8 @@ class Rating {
2400
2454
  h.rating = u.rating;
2401
2455
  h.teamName = t.name;
2402
2456
  h.organization = t.organization;
2403
- h.members = createPersons(t.members ?? []);
2404
- h.coaches = createPersons(t.coach ?? []);
2457
+ h.members = t.members;
2458
+ h.coaches = t.coaches;
2405
2459
  h.contestID = rank.contest.id;
2406
2460
  h.contestLink = h.contestID;
2407
2461
  h.contestName = rank.contest.name;
@@ -2416,16 +2470,16 @@ class Rating {
2416
2470
  }
2417
2471
  }
2418
2472
  generateTeamId(t) {
2419
- const persons = createPersons(t.members ?? []);
2473
+ const persons = t.members;
2420
2474
  if (persons.length > 0) {
2421
- return persons.map((person) => person.name.trim()).sort().join("|");
2475
+ return persons.map((person) => person.name.getOrDefault().trim()).sort().join("|");
2422
2476
  }
2423
2477
  return `${t.organization}-${t.name}`;
2424
2478
  }
2425
2479
  toJSON() {
2426
2480
  return {
2427
2481
  id: this.id,
2428
- name: this.name,
2482
+ name: this.name.toI18NStringSet(),
2429
2483
  baseRating: this.baseRating,
2430
2484
  contestIDs: this.contestIDs,
2431
2485
  users: this.users.map((ratingUser) => ratingUser.toJSON())
@@ -2437,7 +2491,7 @@ class Rating {
2437
2491
  }
2438
2492
  const rating = new Rating();
2439
2493
  rating.id = iRating.id;
2440
- rating.name = iRating.name;
2494
+ rating.name = I18nText.fromIText(iRating.name);
2441
2495
  rating.baseRating = iRating.baseRating;
2442
2496
  rating.contestIDs = iRating.contestIDs;
2443
2497
  for (const iUser of iRating.users) {
@@ -2780,6 +2834,7 @@ exports.ContestOptions = ContestOptions;
2780
2834
  exports.GeneralExcelConverter = GeneralExcelConverter;
2781
2835
  exports.Giants = Giants;
2782
2836
  exports.GiantsType = GiantsType;
2837
+ exports.I18nText = I18nText;
2783
2838
  exports.ICPCStandingsCsvConverter = ICPCStandingsCsvConverter;
2784
2839
  exports.MedalType = MedalType;
2785
2840
  exports.Person = Person;