@juki-team/commons 0.1.43 → 0.1.46
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/cjs/index.cjs +514 -546
- package/dist/esm/index.js +416 -491
- package/dist/types/constants/entity.d.ts +3 -3
- package/dist/types/constants/index.d.ts +1 -1
- package/dist/types/constants/organization.d.ts +9 -0
- package/dist/types/constants/websocket.d.ts +18 -22
- package/dist/types/dto/class.d.ts +34 -34
- package/dist/types/dto/code.d.ts +1 -1
- package/dist/types/dto/comments.d.ts +9 -9
- package/dist/types/dto/contest.d.ts +46 -42
- package/dist/types/dto/course.d.ts +13 -13
- package/dist/types/dto/entity.d.ts +30 -25
- package/dist/types/dto/excalidraw.d.ts +7 -7
- package/dist/types/dto/file.d.ts +10 -15
- package/dist/types/dto/image.d.ts +2 -2
- package/dist/types/dto/index.d.ts +1 -1
- package/dist/types/dto/judge.d.ts +5 -5
- package/dist/types/dto/markdown.d.ts +7 -7
- package/dist/types/dto/mermaid.d.ts +7 -7
- package/dist/types/dto/{company.d.ts → organization.d.ts} +16 -16
- package/dist/types/dto/problem.d.ts +22 -22
- package/dist/types/dto/scoreboard.d.ts +8 -18
- package/dist/types/dto/session.d.ts +9 -9
- package/dist/types/dto/socket.d.ts +76 -125
- package/dist/types/dto/statistics.d.ts +7 -7
- package/dist/types/dto/submission.d.ts +22 -22
- package/dist/types/dto/system.d.ts +7 -82
- package/dist/types/dto/url.d.ts +1 -1
- package/dist/types/dto/user.d.ts +22 -22
- package/dist/types/dto/virtual-user.d.ts +3 -25
- package/dist/types/dto/worksheet-submissions.d.ts +22 -22
- package/dist/types/dto/worksheet.d.ts +12 -12
- package/dist/types/helpers/class.d.ts +4 -4
- package/dist/types/helpers/comments.d.ts +1 -1
- package/dist/types/helpers/contest.d.ts +4 -4
- package/dist/types/helpers/date.d.ts +68 -0
- package/dist/types/helpers/document.d.ts +2 -2
- package/dist/types/helpers/index.d.ts +3 -0
- package/dist/types/helpers/number.d.ts +2 -0
- package/dist/types/helpers/responses.d.ts +1 -1
- package/dist/types/helpers/socket.d.ts +48 -50
- package/dist/types/helpers/time.d.ts +0 -11
- package/dist/types/helpers/user.d.ts +2 -2
- package/dist/types/index.d.ts +0 -1
- package/dist/types/types/class.d.ts +6 -6
- package/dist/types/types/comments.d.ts +2 -2
- package/dist/types/types/contest.d.ts +20 -23
- package/dist/types/types/entity.d.ts +13 -19
- package/dist/types/types/file.d.ts +6 -0
- package/dist/types/types/index.d.ts +3 -1
- package/dist/types/types/{company.d.ts → organization.d.ts} +2 -2
- package/dist/types/types/prisma.d.ts +2 -2
- package/dist/types/types/problems.d.ts +1 -1
- package/dist/types/types/scoreboard.d.ts +11 -0
- package/dist/types/types/sheet.d.ts +1 -1
- package/dist/types/types/socket.d.ts +32 -16
- package/dist/types/types/system.d.ts +76 -0
- package/dist/types/types/teams.d.ts +8 -8
- package/dist/types/types/virtual-user.d.ts +22 -0
- package/package.json +1 -1
- package/dist/types/constants/company.d.ts +0 -9
- package/dist/types/prototypes/Date.d.ts +0 -62
- package/dist/types/prototypes/Number.d.ts +0 -7
- package/dist/types/prototypes/index.d.ts +0 -3
- /package/dist/types/{prototypes/Error.d.ts → helpers/errors.d.ts} +0 -0
package/dist/esm/index.js
CHANGED
|
@@ -89,20 +89,20 @@ var EntityAccess;
|
|
|
89
89
|
EntityAccess["EXPOSED"] = "EXPOSED";
|
|
90
90
|
})(EntityAccess || (EntityAccess = {}));
|
|
91
91
|
|
|
92
|
-
var
|
|
93
|
-
(function (
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
})(
|
|
99
|
-
var
|
|
100
|
-
(function (
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
})(
|
|
92
|
+
var OrganizationPlan;
|
|
93
|
+
(function (OrganizationPlan) {
|
|
94
|
+
OrganizationPlan["FREE"] = "FREE";
|
|
95
|
+
OrganizationPlan["STANDARD"] = "STANDARD";
|
|
96
|
+
OrganizationPlan["PREMIUM"] = "PREMIUM";
|
|
97
|
+
OrganizationPlan["CUSTOM"] = "CUSTOM";
|
|
98
|
+
})(OrganizationPlan || (OrganizationPlan = {}));
|
|
99
|
+
var OrganizationLogoType;
|
|
100
|
+
(function (OrganizationLogoType) {
|
|
101
|
+
OrganizationLogoType["HORIZONTAL_WHITE"] = "horizontal-white";
|
|
102
|
+
OrganizationLogoType["HORIZONTAL_COLOR"] = "horizontal-color";
|
|
103
|
+
OrganizationLogoType["VERTICAL_WHITE"] = "vertical-white";
|
|
104
|
+
OrganizationLogoType["VERTICAL_COLOR"] = "vertical-color";
|
|
105
|
+
})(OrganizationLogoType || (OrganizationLogoType = {}));
|
|
106
106
|
|
|
107
107
|
var ContestStatus;
|
|
108
108
|
(function (ContestStatus) {
|
|
@@ -145,7 +145,7 @@ var EntityState;
|
|
|
145
145
|
})(EntityState || (EntityState = {}));
|
|
146
146
|
var EntityCollection;
|
|
147
147
|
(function (EntityCollection) {
|
|
148
|
-
EntityCollection["
|
|
148
|
+
EntityCollection["ORGANIZATION"] = "ORGANIZATION";
|
|
149
149
|
EntityCollection["PROBLEM"] = "PROBLEM";
|
|
150
150
|
EntityCollection["CONTEST"] = "CONTEST";
|
|
151
151
|
EntityCollection["JUDGE"] = "JUDGE";
|
|
@@ -154,7 +154,7 @@ var EntityCollection;
|
|
|
154
154
|
})(EntityCollection || (EntityCollection = {}));
|
|
155
155
|
var CollectionKey;
|
|
156
156
|
(function (CollectionKey) {
|
|
157
|
-
CollectionKey["
|
|
157
|
+
CollectionKey["ORGANIZATION"] = "C";
|
|
158
158
|
CollectionKey["USER"] = "U";
|
|
159
159
|
CollectionKey["PROBLEM"] = "P";
|
|
160
160
|
CollectionKey["CLASS"] = "K";
|
|
@@ -526,7 +526,7 @@ var ErrorCode;
|
|
|
526
526
|
ErrorCode["ERR0818"] = "ERR0818";
|
|
527
527
|
ErrorCode["ERR0819"] = "ERR0819";
|
|
528
528
|
ErrorCode["ERR0820"] = "ERR0820";
|
|
529
|
-
//
|
|
529
|
+
// Organization Errors ERR99XXX',
|
|
530
530
|
ErrorCode["ERR9900"] = "ERR9900";
|
|
531
531
|
ErrorCode["ERR9910"] = "ERR9910";
|
|
532
532
|
ErrorCode["ERR9911"] = "ERR9911";
|
|
@@ -572,14 +572,6 @@ var QuizScoringMode;
|
|
|
572
572
|
QuizScoringMode["PARTIAL"] = "PARTIAL";
|
|
573
573
|
})(QuizScoringMode || (QuizScoringMode = {}));
|
|
574
574
|
|
|
575
|
-
var WebSocketMessageEvent;
|
|
576
|
-
(function (WebSocketMessageEvent) {
|
|
577
|
-
WebSocketMessageEvent["PING"] = "PING";
|
|
578
|
-
WebSocketMessageEvent["CLIENT_TRACK_LOCATION"] = "CLIENT_TRACK_LOCATION";
|
|
579
|
-
WebSocketMessageEvent["CLIENT_TRACK_SCREENSHOT"] = "CLIENT_TRACK_SCREENSHOT";
|
|
580
|
-
WebSocketMessageEvent["CLIENT_TRACK_DEVICE"] = "CLIENT_TRACK_DEVICE";
|
|
581
|
-
WebSocketMessageEvent["CHAT_COMPLETIONS"] = "CHAT_COMPLETIONS";
|
|
582
|
-
})(WebSocketMessageEvent || (WebSocketMessageEvent = {}));
|
|
583
575
|
/**
|
|
584
576
|
* Subscriptions of the client. With the TOPIC channels they are not sent to the server anymore:
|
|
585
577
|
* they only say which channel the client attaches (`getChannelOfWebSocketSubscribeEvent`) and the dispatch key.
|
|
@@ -598,17 +590,13 @@ var WebSocketSubscriptionEvent;
|
|
|
598
590
|
WebSocketSubscriptionEvent["UNSUBSCRIBE_SUBMISSIONS_CRAWL"] = "UNSUBSCRIBE_SUBMISSIONS_CRAWL";
|
|
599
591
|
WebSocketSubscriptionEvent["SUBSCRIBE_CONTEST_CHANGES"] = "SUBSCRIBE_CONTEST_CHANGES";
|
|
600
592
|
WebSocketSubscriptionEvent["UNSUBSCRIBE_CONTEST_CHANGES"] = "UNSUBSCRIBE_CONTEST_CHANGES";
|
|
601
|
-
WebSocketSubscriptionEvent["SUBSCRIBE_CLIENT_TRACK"] = "SUBSCRIBE_CLIENT_TRACK";
|
|
602
|
-
WebSocketSubscriptionEvent["UNSUBSCRIBE_CLIENT_TRACK"] = "UNSUBSCRIBE_CLIENT_TRACK";
|
|
603
593
|
WebSocketSubscriptionEvent["SUBSCRIBE_USER_NOTIFICATION"] = "SUBSCRIBE_USER_NOTIFICATION";
|
|
604
594
|
WebSocketSubscriptionEvent["UNSUBSCRIBE_USER_NOTIFICATION"] = "UNSUBSCRIBE_USER_NOTIFICATION";
|
|
605
|
-
|
|
606
|
-
WebSocketSubscriptionEvent["
|
|
607
|
-
WebSocketSubscriptionEvent["UNSUBSCRIBE_CLIENT_TRACK_DATA"] = "UNSUBSCRIBE_CLIENT_TRACK_DATA";
|
|
595
|
+
WebSocketSubscriptionEvent["SUBSCRIBE_SUBMISSIONS_JUDGING"] = "SUBSCRIBE_SUBMISSIONS_JUDGING";
|
|
596
|
+
WebSocketSubscriptionEvent["UNSUBSCRIBE_SUBMISSIONS_JUDGING"] = "UNSUBSCRIBE_SUBMISSIONS_JUDGING";
|
|
608
597
|
})(WebSocketSubscriptionEvent || (WebSocketSubscriptionEvent = {}));
|
|
609
598
|
var WebSocketResponseEvent;
|
|
610
599
|
(function (WebSocketResponseEvent) {
|
|
611
|
-
WebSocketResponseEvent["PONG"] = "PONG";
|
|
612
600
|
WebSocketResponseEvent["CODE_RUN_STATUS"] = "CODE_RUN_STATUS";
|
|
613
601
|
WebSocketResponseEvent["SUBMISSION_RUN_STATUS"] = "SUBMISSION_RUN_STATUS";
|
|
614
602
|
WebSocketResponseEvent["USER_MESSAGE"] = "USER_MESSAGE";
|
|
@@ -618,15 +606,13 @@ var WebSocketResponseEvent;
|
|
|
618
606
|
WebSocketResponseEvent["SEND_DATA_EC2_INSTANCES_LIST"] = "SEND_DATA_EC2_INSTANCES_LIST";
|
|
619
607
|
WebSocketResponseEvent["SEND_DATA_SSM_SESSIONS_LIST"] = "SEND_DATA_SSM_SESSIONS_LIST";
|
|
620
608
|
WebSocketResponseEvent["SEND_DATA_RUN_COMMAND"] = "SEND_DATA_RUN_COMMAND";
|
|
621
|
-
WebSocketResponseEvent["SEND_DATA_CLIENT_TRACK"] = "SEND_DATA_CLIENT_TRACK";
|
|
622
|
-
WebSocketResponseEvent["SEND_DATA_CHAT_COMPLETIONS"] = "SEND_DATA_CHAT_COMPLETIONS";
|
|
623
609
|
WebSocketResponseEvent["PROBLEM_CRAWLED"] = "PROBLEM_CRAWLED";
|
|
624
610
|
WebSocketResponseEvent["SUBMISSIONS_CRAWL"] = "SUBMISSIONS_CRAWL";
|
|
625
611
|
WebSocketResponseEvent["CONTEST_CHANGES"] = "CONTEST_CHANGES";
|
|
626
|
-
WebSocketResponseEvent["CLIENT_TRACK"] = "CLIENT_TRACK";
|
|
627
612
|
WebSocketResponseEvent["USER_NOTIFICATION_"] = "USER_NOTIFICATION_";
|
|
628
613
|
WebSocketResponseEvent["USER_NOTIFICATION_SUBMISSION"] = "USER_NOTIFICATION_SUBMISSION";
|
|
629
614
|
WebSocketResponseEvent["USER_NOTIFICATION_CONTEST_CLARIFICATION"] = "USER_NOTIFICATION_CONTEST_CLARIFICATION";
|
|
615
|
+
WebSocketResponseEvent["SUBMISSION_JUDGING"] = "SUBMISSION_JUDGING";
|
|
630
616
|
})(WebSocketResponseEvent || (WebSocketResponseEvent = {}));
|
|
631
617
|
/**
|
|
632
618
|
* Roles of a contest, with the same names as the contest members in the DB.
|
|
@@ -642,6 +628,25 @@ var ContestChannelRole;
|
|
|
642
628
|
ContestChannelRole["GUESTS"] = "guests";
|
|
643
629
|
ContestChannelRole["SPECTATORS"] = "spectators";
|
|
644
630
|
})(ContestChannelRole || (ContestChannelRole = {}));
|
|
631
|
+
/**
|
|
632
|
+
* Roles of a problem, the ones computed by `getProblemAccessPermissions` (backend).
|
|
633
|
+
* Each role has its own Ably channel: `problem:{problemKey}:{role}` (see `CHANNEL_PROBLEM`).
|
|
634
|
+
*/
|
|
635
|
+
var ProblemChannelRole;
|
|
636
|
+
(function (ProblemChannelRole) {
|
|
637
|
+
ProblemChannelRole["ADMINISTRATORS"] = "administrators";
|
|
638
|
+
ProblemChannelRole["MANAGERS"] = "managers";
|
|
639
|
+
ProblemChannelRole["SPECTATORS"] = "spectators";
|
|
640
|
+
})(ProblemChannelRole || (ProblemChannelRole = {}));
|
|
641
|
+
/**
|
|
642
|
+
* Roles of the public channels of a user: `user:{userId}:{role}` (see `CHANNEL_USER_ROLE`).
|
|
643
|
+
* There are no per-user permissions: `spectators` is everyone who can list the submissions of the user.
|
|
644
|
+
* The private channel of the user is `user:{userId}` (see `CHANNEL_USER`).
|
|
645
|
+
*/
|
|
646
|
+
var UserChannelRole;
|
|
647
|
+
(function (UserChannelRole) {
|
|
648
|
+
UserChannelRole["SPECTATORS"] = "spectators";
|
|
649
|
+
})(UserChannelRole || (UserChannelRole = {}));
|
|
645
650
|
|
|
646
651
|
var DataViewMode;
|
|
647
652
|
(function (DataViewMode) {
|
|
@@ -1335,25 +1340,25 @@ const HEADER_JUKI_SECRET_TOKEN = 'x-juki-secret-token';
|
|
|
1335
1340
|
const HEADER_JUKI_INTERNAL_API_KEY = 'x-juki-internal-api-key';
|
|
1336
1341
|
const COOKIE_JUKI_SESSION_ID = 'juki-session-id';
|
|
1337
1342
|
|
|
1338
|
-
const
|
|
1339
|
-
const
|
|
1340
|
-
[
|
|
1341
|
-
value:
|
|
1343
|
+
const JUKI_APP_ORGANIZATION_KEY = 'juki-app';
|
|
1344
|
+
const ORGANIZATION_PLAN = {
|
|
1345
|
+
[OrganizationPlan.FREE]: {
|
|
1346
|
+
value: OrganizationPlan.FREE,
|
|
1342
1347
|
label: 'free',
|
|
1343
1348
|
description: 'the resources, runners and compilers, are shared with the juki.app giving priority to juki.app',
|
|
1344
1349
|
},
|
|
1345
|
-
[
|
|
1346
|
-
value:
|
|
1350
|
+
[OrganizationPlan.STANDARD]: {
|
|
1351
|
+
value: OrganizationPlan.STANDARD,
|
|
1347
1352
|
label: 'standard',
|
|
1348
1353
|
description: 'the resources are dedicated, 1 runner and 1 compiler',
|
|
1349
1354
|
},
|
|
1350
|
-
[
|
|
1351
|
-
value:
|
|
1355
|
+
[OrganizationPlan.PREMIUM]: {
|
|
1356
|
+
value: OrganizationPlan.PREMIUM,
|
|
1352
1357
|
label: 'premium',
|
|
1353
1358
|
description: 'the resources are dedicated and on demand use with at least 1 runner and 1 compiler',
|
|
1354
1359
|
},
|
|
1355
|
-
[
|
|
1356
|
-
value:
|
|
1360
|
+
[OrganizationPlan.CUSTOM]: {
|
|
1361
|
+
value: OrganizationPlan.CUSTOM,
|
|
1357
1362
|
label: 'custom',
|
|
1358
1363
|
description: 'the resources are dedicated and on demand use with at least 1 (settable) runner and 1 (settable) compiler',
|
|
1359
1364
|
},
|
|
@@ -1976,18 +1981,18 @@ const ERROR = {
|
|
|
1976
1981
|
[ErrorCode.ERR9997]: { value: ErrorCode.ERR9997, message: 'aborted request', status: 400 },
|
|
1977
1982
|
[ErrorCode.ERR9998]: { value: ErrorCode.ERR9998, message: 'error on response', status: 400 },
|
|
1978
1983
|
[ErrorCode.ERR9999]: { value: ErrorCode.ERR9999, message: 'service no found', status: 400 },
|
|
1979
|
-
//
|
|
1980
|
-
[ErrorCode.ERR9900]: { value: ErrorCode.ERR9900, message: 'internal server error on
|
|
1981
|
-
//
|
|
1982
|
-
[ErrorCode.ERR9910]: { value: ErrorCode.ERR9910, message: '
|
|
1983
|
-
[ErrorCode.ERR9911]: { value: ErrorCode.ERR9911, message: '
|
|
1984
|
-
[ErrorCode.ERR9912]: { value: ErrorCode.ERR9912, message: '
|
|
1985
|
-
[ErrorCode.ERR9913]: { value: ErrorCode.ERR9913, message: '
|
|
1986
|
-
//
|
|
1987
|
-
[ErrorCode.ERR9914]: { value: ErrorCode.ERR9914, message: 'not allowed to create the
|
|
1988
|
-
[ErrorCode.ERR9915]: { value: ErrorCode.ERR9915, message: 'not allowed to view the
|
|
1989
|
-
[ErrorCode.ERR9916]: { value: ErrorCode.ERR9916, message: 'not allowed to updated the
|
|
1990
|
-
[ErrorCode.ERR9917]: { value: ErrorCode.ERR9917, message: 'not allowed to deleted the
|
|
1984
|
+
// ORGANIZATION ERRORS ERR99XX
|
|
1985
|
+
[ErrorCode.ERR9900]: { value: ErrorCode.ERR9900, message: 'internal server error on organization service', status: 500 },
|
|
1986
|
+
// Organization server errors
|
|
1987
|
+
[ErrorCode.ERR9910]: { value: ErrorCode.ERR9910, message: 'organization not created', status: 500 },
|
|
1988
|
+
[ErrorCode.ERR9911]: { value: ErrorCode.ERR9911, message: 'organization not found', status: 500 },
|
|
1989
|
+
[ErrorCode.ERR9912]: { value: ErrorCode.ERR9912, message: 'organization not updated', status: 500 },
|
|
1990
|
+
[ErrorCode.ERR9913]: { value: ErrorCode.ERR9913, message: 'organization not deleted', status: 500 },
|
|
1991
|
+
// Organization user permission error
|
|
1992
|
+
[ErrorCode.ERR9914]: { value: ErrorCode.ERR9914, message: 'not allowed to create the organization', status: 400 },
|
|
1993
|
+
[ErrorCode.ERR9915]: { value: ErrorCode.ERR9915, message: 'not allowed to view the organization', status: 400 },
|
|
1994
|
+
[ErrorCode.ERR9916]: { value: ErrorCode.ERR9916, message: 'not allowed to updated the organization', status: 400 },
|
|
1995
|
+
[ErrorCode.ERR9917]: { value: ErrorCode.ERR9917, message: 'not allowed to deleted the organization', status: 400 },
|
|
1991
1996
|
// USER ERRORS ERR00XX
|
|
1992
1997
|
[ErrorCode.ERR0000]: { value: ErrorCode.ERR0000, message: 'internal server error on users service', status: 500 },
|
|
1993
1998
|
// User server errors
|
|
@@ -2233,7 +2238,7 @@ const EMPTY_USER_PERMISSIONS = {
|
|
|
2233
2238
|
create: false,
|
|
2234
2239
|
manage: false,
|
|
2235
2240
|
},
|
|
2236
|
-
|
|
2241
|
+
organization: {
|
|
2237
2242
|
manage: false,
|
|
2238
2243
|
administrate: false,
|
|
2239
2244
|
},
|
|
@@ -2242,46 +2247,37 @@ const EMPTY_USER_PERMISSIONS = {
|
|
|
2242
2247
|
},
|
|
2243
2248
|
};
|
|
2244
2249
|
|
|
2245
|
-
// LEGACY channels (fan-out per client through the subscriptions registry in Redis)
|
|
2246
|
-
/** @deprecated the subscriptions registry was replaced by the TOPIC channels granted in the Ably token */
|
|
2247
|
-
const CHANNEL_PUBLISH_SUBSCRIPTIONS = 'pub:subscriptions';
|
|
2248
|
-
/** @deprecated not used, the events arrive by the TOPIC channels */
|
|
2249
|
-
const CHANNEL_SUBSCRIBE_NOTIFICATIONS = 'sub:notifications';
|
|
2250
|
-
/** @deprecated the events arrive by the TOPIC channels */
|
|
2251
|
-
const CHANNEL_SUBSCRIBE_CLIENT = (clientId) => `sub:client:${clientId}`;
|
|
2252
|
-
/** messages from the clients to the backend (chat completions, client track screenshots) */
|
|
2253
|
-
const CHANNEL_PUBLISH_MESSAGES = 'pub:messages';
|
|
2254
|
-
/** @deprecated global presence channel (limited to 200 members by Ably), replaced by CHANNEL_COMPANY_PRESENCE */
|
|
2255
|
-
const CHANNEL_PRESENCE_CLIENT = 'pre:client';
|
|
2256
2250
|
// TOPIC channels
|
|
2257
2251
|
// The backend publishes each event once on the channel of its topic and Ably does the fan-out.
|
|
2258
2252
|
// Who can subscribe to each channel is decided by the API in the Ably token (capability), never by the client.
|
|
2259
2253
|
// Dynamic segments are encoded so a key can never inject a `:` (the Ably segment separator used by the wildcards).
|
|
2260
2254
|
const segment = (value) => encodeURIComponent(value);
|
|
2261
|
-
/** private: events of one session (code runs, requested data
|
|
2255
|
+
/** private: events of one session (code runs, requested data) */
|
|
2262
2256
|
const CHANNEL_SESSION = (sessionId) => `session:${segment(sessionId)}`;
|
|
2263
|
-
/** private: events of one user (own submissions while the contest is frozen, notifications) */
|
|
2257
|
+
/** private: events of one user (own submissions while the contest is frozen, notifications, own problem crawls) */
|
|
2264
2258
|
const CHANNEL_USER = (userId) => `user:${segment(userId)}`;
|
|
2259
|
+
/** per role: public events of one user (judging of its submissions visible to everyone, see `UserChannelRole`) */
|
|
2260
|
+
const CHANNEL_USER_ROLE = (userId, role) => `user:${segment(userId)}:${role}`;
|
|
2265
2261
|
/** public: status of a submission when it is visible to everyone */
|
|
2266
2262
|
const CHANNEL_SUBMISSION = (submitId) => `submission:${segment(submitId)}`;
|
|
2267
|
-
/**
|
|
2268
|
-
const CHANNEL_PROBLEM = (problemKey) => `problem:${segment(problemKey)}`;
|
|
2263
|
+
/** per role: events of a problem for one role (judging of its submissions, see `ProblemChannelRole`) */
|
|
2264
|
+
const CHANNEL_PROBLEM = (problemKey, role) => `problem:${segment(problemKey)}:${role}`;
|
|
2269
2265
|
/** per role: events of a contest for one role (and the roles above it, see `ContestChannelRole`) */
|
|
2270
2266
|
const CHANNEL_CONTEST = (contestKey, role) => `contest:${segment(contestKey)}:${role}`;
|
|
2271
|
-
/** system administrators only: data sent by a tracked client (screenshots, location, device) */
|
|
2272
|
-
const CHANNEL_CLIENT_TRACK = (trackedClientId) => `client-track:${segment(trackedClientId)}`;
|
|
2273
2267
|
/**
|
|
2274
|
-
* presence of the clients (tabs) of the logged users of a
|
|
2275
|
-
* The clients only enter (capability `presence`), only the administrators of the
|
|
2268
|
+
* presence of the clients (tabs) of the logged users of a organization (by its key), data: `UserPresenceData`.
|
|
2269
|
+
* The clients only enter (capability `presence`), only the administrators of the organization receive it
|
|
2276
2270
|
* (capability `presence-subscribe`). Ably limits the presence members per channel (200 by default,
|
|
2277
2271
|
* more with server-side batching enabled on the `presence` namespace).
|
|
2278
2272
|
* The identity of a member is its `clientId` (`sessionId|uiId`, verified by Ably), never its data.
|
|
2279
2273
|
*/
|
|
2280
|
-
const
|
|
2281
|
-
// capability resources (wildcards) of the public channels
|
|
2274
|
+
const CHANNEL_ORGANIZATION_PRESENCE = (organizationKey) => `presence:organization:${segment(organizationKey)}`;
|
|
2275
|
+
// capability resources (wildcards) of the public channels.
|
|
2276
|
+
// Ably: a trailing `*` replaces one or more segments, any other `*` exactly one segment. So `user:*:spectators`
|
|
2277
|
+
// matches every `user:{userId}:spectators` but never the private `user:{userId}`.
|
|
2278
|
+
// There is no public `problem:*`: it would also match the role channels `problem:{problemKey}:{role}`.
|
|
2282
2279
|
const CHANNEL_SUBMISSION_ALL = 'submission:*';
|
|
2283
|
-
const
|
|
2284
|
-
const CHANNEL_CLIENT_TRACK_ALL = 'client-track:*';
|
|
2280
|
+
const CHANNEL_USER_SPECTATORS_ALL = `user:*:${UserChannelRole.SPECTATORS}`;
|
|
2285
2281
|
/**
|
|
2286
2282
|
* Returns the contest and role of a `CHANNEL_CONTEST` channel name, or null if it is not one.
|
|
2287
2283
|
*/
|
|
@@ -2292,6 +2288,16 @@ const getContestChannelParams = (channel) => {
|
|
|
2292
2288
|
}
|
|
2293
2289
|
return { contestKey: decodeURIComponent(contestKey), role: role };
|
|
2294
2290
|
};
|
|
2291
|
+
/**
|
|
2292
|
+
* Returns the problem and role of a `CHANNEL_PROBLEM` channel name, or null if it is not one.
|
|
2293
|
+
*/
|
|
2294
|
+
const getProblemChannelParams = (channel) => {
|
|
2295
|
+
const [namespace, problemKey, role, ...rest] = channel.split(':');
|
|
2296
|
+
if (namespace !== 'problem' || !problemKey || rest.length || !Object.values(ProblemChannelRole).includes(role)) {
|
|
2297
|
+
return null;
|
|
2298
|
+
}
|
|
2299
|
+
return { problemKey: decodeURIComponent(problemKey), role: role };
|
|
2300
|
+
};
|
|
2295
2301
|
|
|
2296
2302
|
const NEW_PAGE_SHEET = () => ({
|
|
2297
2303
|
id: v4(),
|
|
@@ -2383,31 +2389,212 @@ const isContestAssignment = (assignment) => {
|
|
|
2383
2389
|
};
|
|
2384
2390
|
|
|
2385
2391
|
const getAssignmentCommentKey = (classKey, cycleKey, sessionKey, assignmentKey) => `class:${classKey}|cycle:${cycleKey}|session:${sessionKey}|assignment:${assignmentKey}`;
|
|
2386
|
-
const getAssignmentUserCommentKey = (classKey, cycleKey, sessionKey, assignmentKey, userNickname,
|
|
2392
|
+
const getAssignmentUserCommentKey = (classKey, cycleKey, sessionKey, assignmentKey, userNickname, userOrganization) => `class:${classKey}|cycle:${cycleKey}|session:${sessionKey}|assignment:${assignmentKey}|user_nickname:${userNickname}|user_organization:${userOrganization}`;
|
|
2387
2393
|
const getProblemCommentKey = (problemKey) => `problem:${problemKey}`;
|
|
2388
2394
|
const getContestCommentKey = (contestKey) => `contest:${contestKey}`;
|
|
2389
2395
|
|
|
2390
2396
|
const isEndlessContest = (settings) => {
|
|
2391
|
-
return settings?.
|
|
2392
|
-
&& settings?.
|
|
2393
|
-
&& settings?.
|
|
2394
|
-
&& settings?.
|
|
2397
|
+
return settings?.startsAt === MIN_DATE.getTime()
|
|
2398
|
+
&& settings?.frozenAt === MAX_DATE.getTime()
|
|
2399
|
+
&& settings?.silencedAt === MAX_DATE.getTime()
|
|
2400
|
+
&& settings?.endsAt === MAX_DATE.getTime()
|
|
2395
2401
|
&& settings?.penalty === 0;
|
|
2396
2402
|
};
|
|
2397
2403
|
const isGlobalContest = (settings) => {
|
|
2398
|
-
return settings?.
|
|
2399
|
-
&& settings?.
|
|
2400
|
-
&& settings?.
|
|
2401
|
-
&& settings?.
|
|
2404
|
+
return settings?.startsAt === 0
|
|
2405
|
+
&& settings?.frozenAt === 0
|
|
2406
|
+
&& settings?.silencedAt === 0
|
|
2407
|
+
&& settings?.endsAt === 0
|
|
2402
2408
|
&& settings?.penalty === 0;
|
|
2403
2409
|
};
|
|
2404
2410
|
const isPastContest = (settings) => {
|
|
2405
|
-
return Date.now() > (settings?.
|
|
2411
|
+
return Date.now() > (settings?.endsAt ?? 0);
|
|
2406
2412
|
};
|
|
2407
2413
|
const isFutureContest = (settings) => {
|
|
2408
|
-
return (settings?.
|
|
2414
|
+
return (settings?.startsAt ?? 0) > Date.now();
|
|
2409
2415
|
};
|
|
2410
2416
|
|
|
2417
|
+
const changeYear = (date, year) => {
|
|
2418
|
+
const newDate = new Date(date);
|
|
2419
|
+
newDate.setFullYear(year);
|
|
2420
|
+
return newDate;
|
|
2421
|
+
};
|
|
2422
|
+
const changeMonth = (date, monthIndex) => {
|
|
2423
|
+
const newDate = new Date(date);
|
|
2424
|
+
newDate.setMonth(monthIndex);
|
|
2425
|
+
return newDate;
|
|
2426
|
+
};
|
|
2427
|
+
const changeDay = (date, day) => {
|
|
2428
|
+
const newDate = new Date(date);
|
|
2429
|
+
newDate.setDate(day);
|
|
2430
|
+
return newDate;
|
|
2431
|
+
};
|
|
2432
|
+
const changeHours = (date, hours) => {
|
|
2433
|
+
const newDate = new Date(date);
|
|
2434
|
+
newDate.setHours(hours);
|
|
2435
|
+
return newDate;
|
|
2436
|
+
};
|
|
2437
|
+
const changeMinutes = (date, minutes) => {
|
|
2438
|
+
const newDate = new Date(date);
|
|
2439
|
+
newDate.setMinutes(minutes);
|
|
2440
|
+
return newDate;
|
|
2441
|
+
};
|
|
2442
|
+
const changeSeconds = (date, seconds) => {
|
|
2443
|
+
const newDate = new Date(date);
|
|
2444
|
+
newDate.setSeconds(seconds);
|
|
2445
|
+
return newDate;
|
|
2446
|
+
};
|
|
2447
|
+
const changeMilliseconds = (date, milliseconds) => {
|
|
2448
|
+
const newDate = new Date(date);
|
|
2449
|
+
newDate.setMilliseconds(milliseconds);
|
|
2450
|
+
return newDate;
|
|
2451
|
+
};
|
|
2452
|
+
const decreaseYear = (date, count = 1) => changeYear(date, date.getFullYear() - count);
|
|
2453
|
+
const increaseYear = (date, count = 1) => changeYear(date, date.getFullYear() + count);
|
|
2454
|
+
const decreaseMonth = (date) => {
|
|
2455
|
+
const newDate = new Date(date);
|
|
2456
|
+
newDate.setMonth(newDate.getMonth() - 1);
|
|
2457
|
+
return newDate;
|
|
2458
|
+
};
|
|
2459
|
+
const increaseMonth = (date) => {
|
|
2460
|
+
const newDate = new Date(date);
|
|
2461
|
+
newDate.setMonth(newDate.getMonth() + 1);
|
|
2462
|
+
return newDate;
|
|
2463
|
+
};
|
|
2464
|
+
const decreaseDay = (date) => {
|
|
2465
|
+
const newDate = new Date(date);
|
|
2466
|
+
newDate.setDate(newDate.getDate() - 1);
|
|
2467
|
+
return newDate;
|
|
2468
|
+
};
|
|
2469
|
+
const increaseDay = (date) => {
|
|
2470
|
+
const newDate = new Date(date);
|
|
2471
|
+
newDate.setDate(newDate.getDate() + 1);
|
|
2472
|
+
return newDate;
|
|
2473
|
+
};
|
|
2474
|
+
const startOfDay = (date) => {
|
|
2475
|
+
const newDate = new Date(date);
|
|
2476
|
+
newDate.setHours(0, 0, 0, 0);
|
|
2477
|
+
return newDate;
|
|
2478
|
+
};
|
|
2479
|
+
const endOfDay = (date) => {
|
|
2480
|
+
const newDate = new Date(date);
|
|
2481
|
+
newDate.setHours(23, 59, 59, 999);
|
|
2482
|
+
return newDate;
|
|
2483
|
+
};
|
|
2484
|
+
const startOfMonth = (date) => {
|
|
2485
|
+
const newDate = new Date(date);
|
|
2486
|
+
newDate.setDate(1);
|
|
2487
|
+
return startOfDay(newDate);
|
|
2488
|
+
};
|
|
2489
|
+
const endOfMonth = (date) => {
|
|
2490
|
+
const nextMonth = startOfMonth(increaseMonth(date));
|
|
2491
|
+
return new Date(nextMonth.getTime() - 1);
|
|
2492
|
+
};
|
|
2493
|
+
const startOfYear = (date) => {
|
|
2494
|
+
const newDate = new Date(date);
|
|
2495
|
+
newDate.setMonth(0);
|
|
2496
|
+
return startOfMonth(newDate);
|
|
2497
|
+
};
|
|
2498
|
+
const endOfYear = (date) => {
|
|
2499
|
+
const nextYear = startOfYear(increaseYear(date));
|
|
2500
|
+
return new Date(nextYear.getTime() - 1);
|
|
2501
|
+
};
|
|
2502
|
+
const startOfWeek = (date) => {
|
|
2503
|
+
const newDate = new Date(date);
|
|
2504
|
+
while (newDate.getDay()) {
|
|
2505
|
+
newDate.setDate(newDate.getDate() - 1);
|
|
2506
|
+
}
|
|
2507
|
+
return startOfDay(newDate);
|
|
2508
|
+
};
|
|
2509
|
+
const endOfWeek = (date) => {
|
|
2510
|
+
const newDate = new Date(date);
|
|
2511
|
+
while (newDate.getDay() < 6) {
|
|
2512
|
+
newDate.setDate(newDate.getDate() + 1);
|
|
2513
|
+
}
|
|
2514
|
+
return endOfDay(newDate);
|
|
2515
|
+
};
|
|
2516
|
+
const startOfHour = (date) => {
|
|
2517
|
+
const newDate = new Date(date);
|
|
2518
|
+
newDate.setMinutes(0, 0, 0);
|
|
2519
|
+
return newDate;
|
|
2520
|
+
};
|
|
2521
|
+
const endOfHour = (date) => {
|
|
2522
|
+
const newDate = new Date(date);
|
|
2523
|
+
newDate.setMinutes(59, 59, 999);
|
|
2524
|
+
return newDate;
|
|
2525
|
+
};
|
|
2526
|
+
const startOfMinute = (date) => {
|
|
2527
|
+
const newDate = new Date(date);
|
|
2528
|
+
newDate.setSeconds(0, 0);
|
|
2529
|
+
return newDate;
|
|
2530
|
+
};
|
|
2531
|
+
const endOfMinute = (date) => {
|
|
2532
|
+
const newDate = new Date(date);
|
|
2533
|
+
newDate.setSeconds(59, 999);
|
|
2534
|
+
return newDate;
|
|
2535
|
+
};
|
|
2536
|
+
const startOfSecond = (date) => {
|
|
2537
|
+
const newDate = new Date(date);
|
|
2538
|
+
newDate.setMilliseconds(0);
|
|
2539
|
+
return newDate;
|
|
2540
|
+
};
|
|
2541
|
+
const endOfSecond = (date) => {
|
|
2542
|
+
const newDate = new Date(date);
|
|
2543
|
+
newDate.setMilliseconds(999);
|
|
2544
|
+
return newDate;
|
|
2545
|
+
};
|
|
2546
|
+
const isEqual = (a, b) => a.getTime() === b.getTime();
|
|
2547
|
+
const isSameYear = (a, b) => a.getFullYear() === b.getFullYear();
|
|
2548
|
+
const isSameMonth = (a, b) => isSameYear(a, b) && a.getMonth() === b.getMonth();
|
|
2549
|
+
const isSameDay = (a, b) => isSameMonth(a, b) && a.getDate() === b.getDate();
|
|
2550
|
+
const isSameHour = (a, b) => isSameDay(a, b) && a.getHours() === b.getHours();
|
|
2551
|
+
const isSameMinute = (a, b) => isSameHour(a, b) && a.getMinutes() === b.getMinutes();
|
|
2552
|
+
const isSameSecond = (a, b) => isSameMinute(a, b) && a.getSeconds() === b.getSeconds();
|
|
2553
|
+
const isSameMillisecond = (a, b) => isEqual(a, b);
|
|
2554
|
+
const isToday = (date) => isSameDay(date, new Date());
|
|
2555
|
+
const isValidDate = (date) => date instanceof Date && !Number.isNaN(date.getTime());
|
|
2556
|
+
const isAfter = (a, b) => a.getTime() > b.getTime();
|
|
2557
|
+
const isBefore = (a, b) => a.getTime() < b.getTime();
|
|
2558
|
+
const isYearAfter = (a, b) => a.getFullYear() > b.getFullYear();
|
|
2559
|
+
const isMonthAfter = (a, b) => isYearAfter(a, b) || (isSameYear(a, b) && a.getMonth() > b.getMonth());
|
|
2560
|
+
const isDayAfter = (a, b) => isMonthAfter(a, b) || (isSameMonth(a, b) && a.getDate() > b.getDate());
|
|
2561
|
+
const isHoursAfter = (a, b) => isDayAfter(a, b) || (isSameDay(a, b) && a.getHours() > b.getHours());
|
|
2562
|
+
const isMinutesAfter = (a, b) => isHoursAfter(a, b) || (isSameHour(a, b) && a.getMinutes() > b.getMinutes());
|
|
2563
|
+
const isSecondsAfter = (a, b) => isMinutesAfter(a, b) || (isSameMinute(a, b) && a.getSeconds() > b.getSeconds());
|
|
2564
|
+
const isMillisecondsAfter = (a, b) => isSecondsAfter(a, b) || (isSameSecond(a, b) && a.getMilliseconds() > b.getMilliseconds());
|
|
2565
|
+
const isYearBefore = (a, b) => a.getFullYear() < b.getFullYear();
|
|
2566
|
+
const isMonthBefore = (a, b) => isYearBefore(a, b) || (isSameYear(a, b) && a.getMonth() < b.getMonth());
|
|
2567
|
+
const isDayBefore = (a, b) => isMonthBefore(a, b) || (isSameMonth(a, b) && a.getDate() < b.getDate());
|
|
2568
|
+
const isHoursBefore = (a, b) => isDayBefore(a, b) || (isSameDay(a, b) && a.getHours() < b.getHours());
|
|
2569
|
+
const isMinutesBefore = (a, b) => isHoursBefore(a, b) || (isSameHour(a, b) && a.getMinutes() < b.getMinutes());
|
|
2570
|
+
const isSecondsBefore = (a, b) => isMinutesBefore(a, b) || (isSameMinute(a, b) && a.getSeconds() < b.getSeconds());
|
|
2571
|
+
const isMillisecondsBefore = (a, b) => isSecondsBefore(a, b) || (isSameSecond(a, b) && a.getMilliseconds() < b.getMilliseconds());
|
|
2572
|
+
const isWithinInterval = (date, { start, end }, cmp = '[]') => (cmp.charAt(0) === '[' ? isEqual(date, start) || isAfter(date, start) : isAfter(date, start)) &&
|
|
2573
|
+
(cmp.charAt(1) === ']' ? isEqual(date, end) || isBefore(date, end) : isBefore(date, end));
|
|
2574
|
+
const normalizeToLocalStartOfDay = (timestamp) => {
|
|
2575
|
+
const d = new Date(timestamp);
|
|
2576
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate());
|
|
2577
|
+
};
|
|
2578
|
+
const normalizeToLocalStartOfHour = (timestamp) => {
|
|
2579
|
+
const d = new Date(timestamp);
|
|
2580
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours());
|
|
2581
|
+
};
|
|
2582
|
+
const normalizeToLocalStartOfMinutes = (timestamp) => {
|
|
2583
|
+
const d = new Date(timestamp);
|
|
2584
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes());
|
|
2585
|
+
};
|
|
2586
|
+
const normalizeToLocalStartOfSeconds = (timestamp) => {
|
|
2587
|
+
const d = new Date(timestamp);
|
|
2588
|
+
return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds());
|
|
2589
|
+
};
|
|
2590
|
+
const getYears = (d) => d.getFullYear();
|
|
2591
|
+
const getMonths = (d) => d.getFullYear() * 12 + d.getMonth();
|
|
2592
|
+
const getDays = (d) => Math.floor(normalizeToLocalStartOfDay(d).getTime() / ONE_DAY);
|
|
2593
|
+
const getHours = (d) => Math.floor(normalizeToLocalStartOfHour(d).getTime() / ONE_HOUR);
|
|
2594
|
+
const getMinutes = (d) => Math.floor(normalizeToLocalStartOfMinutes(d).getTime() / ONE_MINUTE);
|
|
2595
|
+
const getSeconds = (d) => Math.floor(normalizeToLocalStartOfSeconds(d).getTime() / 1000);
|
|
2596
|
+
const getMilliseconds = (d) => d.getTime();
|
|
2597
|
+
|
|
2411
2598
|
const getDocumentAccess = (document) => {
|
|
2412
2599
|
switch (true) {
|
|
2413
2600
|
case (document?.members?.rankAdministrators === EntityMembersRank.NONE || document?.members?.rankAdministrators === EntityMembersRank.CLOSE)
|
|
@@ -2444,7 +2631,7 @@ const isUserMember = (member) => {
|
|
|
2444
2631
|
const isTeamMember = (member) => {
|
|
2445
2632
|
return typeof member.teamId === 'string';
|
|
2446
2633
|
};
|
|
2447
|
-
const
|
|
2634
|
+
const toEntityMembersDto = (members) => {
|
|
2448
2635
|
return {
|
|
2449
2636
|
rankAdministrators: members.rankAdministrators,
|
|
2450
2637
|
administrators: Object.keys(members.administrators),
|
|
@@ -2459,6 +2646,21 @@ const toEntityMembersDTO = (members) => {
|
|
|
2459
2646
|
};
|
|
2460
2647
|
};
|
|
2461
2648
|
|
|
2649
|
+
class JkError extends Error {
|
|
2650
|
+
constructor(code, custom) {
|
|
2651
|
+
const message = custom?.message || ERROR[code].message;
|
|
2652
|
+
super(message);
|
|
2653
|
+
this.message = message;
|
|
2654
|
+
this.code = code;
|
|
2655
|
+
if (custom?.stack) {
|
|
2656
|
+
this.stack = custom.stack;
|
|
2657
|
+
}
|
|
2658
|
+
if (custom?.data) {
|
|
2659
|
+
this.data = custom.data;
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
|
|
2462
2664
|
function removeExtension(fileName) {
|
|
2463
2665
|
const i = fileName.lastIndexOf('.');
|
|
2464
2666
|
return i !== -1 ? fileName.substring(0, i) : fileName;
|
|
@@ -2613,6 +2815,9 @@ const getDataLog = (log) => {
|
|
|
2613
2815
|
};
|
|
2614
2816
|
};
|
|
2615
2817
|
|
|
2818
|
+
const padStart = (n, maxLength, fillString = '0') => `${n}`.padStart(maxLength, fillString);
|
|
2819
|
+
const padEnd = (n, maxLength, fillString = '0') => `${n}`.padEnd(maxLength, fillString);
|
|
2820
|
+
|
|
2616
2821
|
function memorySizeOf(obj) {
|
|
2617
2822
|
let bytes = 0;
|
|
2618
2823
|
function sizeOf(obj) {
|
|
@@ -2647,247 +2852,6 @@ function memorySizeOf(obj) {
|
|
|
2647
2852
|
return sizeOf(obj);
|
|
2648
2853
|
}
|
|
2649
2854
|
|
|
2650
|
-
/* eslint-disable no-extend-native */
|
|
2651
|
-
Date.prototype.changeYear = function (year) {
|
|
2652
|
-
const newDate = new Date(this);
|
|
2653
|
-
newDate.setFullYear(year);
|
|
2654
|
-
return newDate;
|
|
2655
|
-
};
|
|
2656
|
-
Date.prototype.changeMonth = function (monthIndex) {
|
|
2657
|
-
const newDate = new Date(this);
|
|
2658
|
-
newDate.setMonth(monthIndex);
|
|
2659
|
-
return newDate;
|
|
2660
|
-
};
|
|
2661
|
-
Date.prototype.changeDay = function (date) {
|
|
2662
|
-
const newDate = new Date(this);
|
|
2663
|
-
newDate.setDate(date);
|
|
2664
|
-
return newDate;
|
|
2665
|
-
};
|
|
2666
|
-
Date.prototype.changeHours = function (hours) {
|
|
2667
|
-
const newDate = new Date(this);
|
|
2668
|
-
newDate.setHours(hours);
|
|
2669
|
-
return newDate;
|
|
2670
|
-
};
|
|
2671
|
-
Date.prototype.changeMinutes = function (minutes) {
|
|
2672
|
-
const newDate = new Date(this);
|
|
2673
|
-
newDate.setMinutes(minutes);
|
|
2674
|
-
return newDate;
|
|
2675
|
-
};
|
|
2676
|
-
Date.prototype.changeSeconds = function (seconds) {
|
|
2677
|
-
const newDate = new Date(this);
|
|
2678
|
-
newDate.setSeconds(seconds);
|
|
2679
|
-
return newDate;
|
|
2680
|
-
};
|
|
2681
|
-
Date.prototype.changeMilliseconds = function (milliseconds) {
|
|
2682
|
-
const newDate = new Date(this);
|
|
2683
|
-
newDate.setMilliseconds(milliseconds);
|
|
2684
|
-
return newDate;
|
|
2685
|
-
};
|
|
2686
|
-
Date.prototype.decreaseYear = function (count = 1) {
|
|
2687
|
-
return this.changeYear(this.getFullYear() - count);
|
|
2688
|
-
};
|
|
2689
|
-
Date.prototype.increaseYear = function (count = 1) {
|
|
2690
|
-
return this.changeYear(this.getFullYear() + count);
|
|
2691
|
-
};
|
|
2692
|
-
Date.prototype.decreaseMonth = function () {
|
|
2693
|
-
const newDate = new Date(this);
|
|
2694
|
-
newDate.setMonth(newDate.getMonth() - 1);
|
|
2695
|
-
return newDate;
|
|
2696
|
-
};
|
|
2697
|
-
Date.prototype.increaseMonth = function () {
|
|
2698
|
-
const newDate = new Date(this);
|
|
2699
|
-
newDate.setMonth(newDate.getMonth() + 1);
|
|
2700
|
-
return newDate;
|
|
2701
|
-
};
|
|
2702
|
-
Date.prototype.increaseDay = function () {
|
|
2703
|
-
const newDate = new Date(this);
|
|
2704
|
-
newDate.setDate(newDate.getDate() + 1);
|
|
2705
|
-
return newDate;
|
|
2706
|
-
};
|
|
2707
|
-
Date.prototype.decreaseDay = function () {
|
|
2708
|
-
const newDate = new Date(this);
|
|
2709
|
-
newDate.setDate(newDate.getDate() - 1);
|
|
2710
|
-
return newDate;
|
|
2711
|
-
};
|
|
2712
|
-
Date.prototype.startOfYear = function () {
|
|
2713
|
-
const newDate = new Date(this);
|
|
2714
|
-
newDate.setMonth(0);
|
|
2715
|
-
return newDate.startOfMonth();
|
|
2716
|
-
};
|
|
2717
|
-
Date.prototype.endOfYear = function () {
|
|
2718
|
-
const nextMonth = this.increaseYear().startOfYear();
|
|
2719
|
-
return new Date(nextMonth.getTime() - 1);
|
|
2720
|
-
};
|
|
2721
|
-
Date.prototype.startOfMonth = function () {
|
|
2722
|
-
const newDate = new Date(this);
|
|
2723
|
-
newDate.setDate(1);
|
|
2724
|
-
return newDate.startOfDay();
|
|
2725
|
-
};
|
|
2726
|
-
Date.prototype.endOfMonth = function () {
|
|
2727
|
-
const nextMonth = this.increaseMonth().startOfMonth();
|
|
2728
|
-
return new Date(nextMonth.getTime() - 1);
|
|
2729
|
-
};
|
|
2730
|
-
Date.prototype.startOfWeek = function () {
|
|
2731
|
-
const newDate = new Date(this);
|
|
2732
|
-
while (newDate.getDay()) {
|
|
2733
|
-
newDate.setDate(newDate.getDate() - 1);
|
|
2734
|
-
}
|
|
2735
|
-
return newDate.startOfDay();
|
|
2736
|
-
};
|
|
2737
|
-
Date.prototype.endOfWeek = function () {
|
|
2738
|
-
const newDate = new Date(this);
|
|
2739
|
-
while (newDate.getDay() < 6) {
|
|
2740
|
-
newDate.setDate(newDate.getDate() - 1);
|
|
2741
|
-
}
|
|
2742
|
-
return newDate.endOfDay();
|
|
2743
|
-
};
|
|
2744
|
-
Date.prototype.startOfDay = function () {
|
|
2745
|
-
const newDate = new Date(this);
|
|
2746
|
-
newDate.setHours(0, 0, 0, 0);
|
|
2747
|
-
return newDate;
|
|
2748
|
-
};
|
|
2749
|
-
Date.prototype.endOfDay = function () {
|
|
2750
|
-
const newDate = new Date(this);
|
|
2751
|
-
newDate.setHours(23, 59, 59, 999);
|
|
2752
|
-
return newDate;
|
|
2753
|
-
};
|
|
2754
|
-
Date.prototype.startOfHour = function () {
|
|
2755
|
-
const newDate = new Date(this);
|
|
2756
|
-
newDate.setMinutes(0, 0, 0);
|
|
2757
|
-
return newDate;
|
|
2758
|
-
};
|
|
2759
|
-
Date.prototype.endOfHour = function () {
|
|
2760
|
-
const newDate = new Date(this);
|
|
2761
|
-
newDate.setMinutes(59, 59, 999);
|
|
2762
|
-
return newDate;
|
|
2763
|
-
};
|
|
2764
|
-
Date.prototype.startOfMinute = function () {
|
|
2765
|
-
const newDate = new Date(this);
|
|
2766
|
-
newDate.setSeconds(0, 0);
|
|
2767
|
-
return newDate;
|
|
2768
|
-
};
|
|
2769
|
-
Date.prototype.endOfMinute = function () {
|
|
2770
|
-
const newDate = new Date(this);
|
|
2771
|
-
newDate.setSeconds(59, 999);
|
|
2772
|
-
return newDate;
|
|
2773
|
-
};
|
|
2774
|
-
Date.prototype.startOfSecond = function () {
|
|
2775
|
-
const newDate = new Date(this);
|
|
2776
|
-
newDate.setMilliseconds(0);
|
|
2777
|
-
return newDate;
|
|
2778
|
-
};
|
|
2779
|
-
Date.prototype.endOfSecond = function () {
|
|
2780
|
-
const newDate = new Date(this);
|
|
2781
|
-
newDate.setMilliseconds(999);
|
|
2782
|
-
return newDate;
|
|
2783
|
-
};
|
|
2784
|
-
Date.prototype.isToday = function () {
|
|
2785
|
-
const today = new Date();
|
|
2786
|
-
return this.isSameDay(today);
|
|
2787
|
-
};
|
|
2788
|
-
Date.prototype.isEqual = function (date) {
|
|
2789
|
-
return this.getTime() === date.getTime();
|
|
2790
|
-
};
|
|
2791
|
-
Date.prototype.isSameYear = function (date) {
|
|
2792
|
-
return this.getFullYear() === date.getFullYear();
|
|
2793
|
-
};
|
|
2794
|
-
Date.prototype.isSameMonth = function (date) {
|
|
2795
|
-
return this.isSameYear(date) && this.getMonth() === date.getMonth();
|
|
2796
|
-
};
|
|
2797
|
-
Date.prototype.isSameDay = function (date) {
|
|
2798
|
-
return this.isSameMonth(date) && this.getDate() === date.getDate();
|
|
2799
|
-
};
|
|
2800
|
-
Date.prototype.isSameHour = function (date) {
|
|
2801
|
-
return this.isSameDay(date) && this.getHours() === date.getHours();
|
|
2802
|
-
};
|
|
2803
|
-
Date.prototype.isSameMinute = function (date) {
|
|
2804
|
-
return this.isSameHour(date) && this.getMinutes() === date.getMinutes();
|
|
2805
|
-
};
|
|
2806
|
-
Date.prototype.isSameSecond = function (date) {
|
|
2807
|
-
return this.isSameMinute(date) && this.getSeconds() === date.getSeconds();
|
|
2808
|
-
};
|
|
2809
|
-
Date.prototype.isSameMillisecond = function (date) {
|
|
2810
|
-
return this.isEqual(date);
|
|
2811
|
-
};
|
|
2812
|
-
Date.prototype.isValidDate = function () {
|
|
2813
|
-
return this instanceof Date && !isNaN(this.getTime());
|
|
2814
|
-
};
|
|
2815
|
-
Date.prototype.isYearAfter = function (date) {
|
|
2816
|
-
return this.getFullYear() > date.getFullYear();
|
|
2817
|
-
};
|
|
2818
|
-
Date.prototype.isMonthAfter = function (date) {
|
|
2819
|
-
return this.isYearAfter(date) || (this.isSameYear(date) && this.getMonth() > date.getMonth());
|
|
2820
|
-
};
|
|
2821
|
-
Date.prototype.isDayAfter = function (date) {
|
|
2822
|
-
return this.isMonthAfter(date) || (this.isSameMonth(date) && this.getDate() > date.getDate());
|
|
2823
|
-
};
|
|
2824
|
-
Date.prototype.isHoursAfter = function (date) {
|
|
2825
|
-
return this.isDayAfter(date) || (this.isSameDay(date) && this.getHours() > date.getHours());
|
|
2826
|
-
};
|
|
2827
|
-
Date.prototype.isMinutesAfter = function (date) {
|
|
2828
|
-
return this.isHoursAfter(date) || (this.isSameHour(date) && this.getMinutes() > date.getMinutes());
|
|
2829
|
-
};
|
|
2830
|
-
Date.prototype.isSecondsAfter = function (date) {
|
|
2831
|
-
return this.isMinutesAfter(date) || (this.isSameMinute(date) && this.getSeconds() > date.getSeconds());
|
|
2832
|
-
};
|
|
2833
|
-
Date.prototype.isMillisecondsAfter = function (date) {
|
|
2834
|
-
return this.isSecondsAfter(date) || (this.isSameSecond(date) && this.getMilliseconds() > date.getMilliseconds());
|
|
2835
|
-
};
|
|
2836
|
-
Date.prototype.isAfter = function (date) {
|
|
2837
|
-
return this.getTime() > date.getTime();
|
|
2838
|
-
};
|
|
2839
|
-
Date.prototype.isYearBefore = function (date) {
|
|
2840
|
-
return this.getFullYear() < date.getFullYear();
|
|
2841
|
-
};
|
|
2842
|
-
Date.prototype.isMonthBefore = function (date) {
|
|
2843
|
-
return this.isYearBefore(date) || (this.isSameYear(date) && this.getMonth() < date.getMonth());
|
|
2844
|
-
};
|
|
2845
|
-
Date.prototype.isDayBefore = function (date) {
|
|
2846
|
-
return this.isMonthBefore(date) || (this.isSameMonth(date) && this.getDate() < date.getDate());
|
|
2847
|
-
};
|
|
2848
|
-
Date.prototype.isHoursBefore = function (date) {
|
|
2849
|
-
return this.isDayBefore(date) || (this.isSameDay(date) && this.getHours() < date.getHours());
|
|
2850
|
-
};
|
|
2851
|
-
Date.prototype.isMinutesBefore = function (date) {
|
|
2852
|
-
return this.isHoursBefore(date) || (this.isSameHour(date) && this.getMinutes() < date.getMinutes());
|
|
2853
|
-
};
|
|
2854
|
-
Date.prototype.isSecondsBefore = function (date) {
|
|
2855
|
-
return this.isMinutesBefore(date) || (this.isSameMinute(date) && this.getSeconds() < date.getSeconds());
|
|
2856
|
-
};
|
|
2857
|
-
Date.prototype.isMillisecondsBefore = function (date) {
|
|
2858
|
-
return this.isSecondsBefore(date) || (this.isSameSecond(date) && this.getMilliseconds() < date.getMilliseconds());
|
|
2859
|
-
};
|
|
2860
|
-
Date.prototype.isBefore = function (date) {
|
|
2861
|
-
return this.getTime() < date.getTime();
|
|
2862
|
-
};
|
|
2863
|
-
Date.prototype.isWithinInterval = function ({ start, end }, cmp = '[]') {
|
|
2864
|
-
return (cmp.charAt(0) === '[' ? this.isEqual(start) || this.isAfter(start) : this.isAfter(start)) &&
|
|
2865
|
-
(cmp.charAt(1) === '[' ? this.isEqual(end) || this.isBefore(end) : this.isBefore(end));
|
|
2866
|
-
};
|
|
2867
|
-
|
|
2868
|
-
class JkError extends Error {
|
|
2869
|
-
constructor(code, custom) {
|
|
2870
|
-
const message = custom?.message || ERROR[code].message;
|
|
2871
|
-
super(message);
|
|
2872
|
-
this.message = message;
|
|
2873
|
-
this.code = code;
|
|
2874
|
-
if (custom?.stack) {
|
|
2875
|
-
this.stack = custom.stack;
|
|
2876
|
-
}
|
|
2877
|
-
if (custom?.data) {
|
|
2878
|
-
this.data = custom.data;
|
|
2879
|
-
}
|
|
2880
|
-
}
|
|
2881
|
-
}
|
|
2882
|
-
|
|
2883
|
-
/* eslint-disable no-extend-native */
|
|
2884
|
-
Number.prototype.padStart = function (maxLength, fillString = '0') {
|
|
2885
|
-
return (this + '').padStart(maxLength, fillString);
|
|
2886
|
-
};
|
|
2887
|
-
Number.prototype.padEnd = function (maxLength, fillString = '0') {
|
|
2888
|
-
return (this + '').padEnd(maxLength, fillString);
|
|
2889
|
-
};
|
|
2890
|
-
|
|
2891
2855
|
function toJkError(err) {
|
|
2892
2856
|
const error = new Error();
|
|
2893
2857
|
let code = err?.code;
|
|
@@ -2981,258 +2945,230 @@ const getDefaultMeta = (contents, sort) => {
|
|
|
2981
2945
|
};
|
|
2982
2946
|
|
|
2983
2947
|
const isWebsocketSubscription = (event) => {
|
|
2984
|
-
return
|
|
2948
|
+
return Object.values(WebSocketSubscriptionEvent).includes(event?.event)
|
|
2985
2949
|
&& typeof event?.clientId === 'string' && !!event.clientId;
|
|
2986
2950
|
};
|
|
2987
|
-
// Custom CHANNEL_PUBLISH_MESSAGES
|
|
2988
|
-
const isPingWebSocketEventDTO = (event) => {
|
|
2989
|
-
return isWebsocketSubscription(event)
|
|
2990
|
-
&& event?.event === WebSocketMessageEvent.PING;
|
|
2991
|
-
};
|
|
2992
|
-
const isClientTrackLocationWebSocketEventDTO = (event) => {
|
|
2993
|
-
return isWebsocketSubscription(event)
|
|
2994
|
-
&& event?.event === WebSocketMessageEvent.CLIENT_TRACK_LOCATION;
|
|
2995
|
-
};
|
|
2996
|
-
const isClientTrackScreenshotWebSocketEventDTO = (event) => {
|
|
2997
|
-
return isWebsocketSubscription(event)
|
|
2998
|
-
&& event?.event === WebSocketMessageEvent.CLIENT_TRACK_SCREENSHOT;
|
|
2999
|
-
};
|
|
3000
|
-
const isClientTrackDeviceWebSocketEventDTO = (event) => {
|
|
3001
|
-
return isWebsocketSubscription(event)
|
|
3002
|
-
&& event?.event === WebSocketMessageEvent.CLIENT_TRACK_DEVICE;
|
|
3003
|
-
};
|
|
3004
|
-
const isChatCompletionsWebSocketEventDTO = (event) => {
|
|
3005
|
-
return isWebsocketSubscription(event)
|
|
3006
|
-
&& event?.event === WebSocketMessageEvent.CHAT_COMPLETIONS;
|
|
3007
|
-
};
|
|
3008
2951
|
// CHANNEL_PUBLISH_SUBSCRIPTIONS
|
|
3009
|
-
const
|
|
2952
|
+
const isSubscribeCodeRunStatusWebSocketEventDto = (event) => {
|
|
3010
2953
|
return isWebsocketSubscription(event)
|
|
3011
2954
|
&& event?.event === WebSocketSubscriptionEvent.SUBSCRIBE_CODE_RUN_STATUS
|
|
3012
2955
|
&& typeof event?.runId === 'string' && !!event.runId;
|
|
3013
2956
|
};
|
|
3014
|
-
const
|
|
2957
|
+
const isUnsubscribeCodeRunStatusWebSocketEventDto = (event) => {
|
|
3015
2958
|
return isWebsocketSubscription(event)
|
|
3016
2959
|
&& event?.event === WebSocketSubscriptionEvent.UNSUBSCRIBE_CODE_RUN_STATUS
|
|
3017
2960
|
&& typeof event?.runId === 'string' && !!event.runId;
|
|
3018
2961
|
};
|
|
3019
|
-
const
|
|
2962
|
+
const isSubscribeSubmissionRunStatusWebSocketEventDto = (event) => {
|
|
3020
2963
|
return isWebsocketSubscription(event)
|
|
3021
2964
|
&& event?.event === WebSocketSubscriptionEvent.SUBSCRIBE_SUBMISSION_RUN_STATUS
|
|
3022
2965
|
&& typeof event?.submitId === 'string' && !!event.submitId;
|
|
3023
2966
|
};
|
|
3024
|
-
const
|
|
2967
|
+
const isUnsubscribeSubmissionRunStatusWebSocketEventDto = (event) => {
|
|
3025
2968
|
return isWebsocketSubscription(event)
|
|
3026
2969
|
&& event?.event === WebSocketSubscriptionEvent.UNSUBSCRIBE_SUBMISSION_RUN_STATUS
|
|
3027
2970
|
&& typeof event?.submitId === 'string' && !!event.submitId;
|
|
3028
2971
|
};
|
|
3029
|
-
const
|
|
2972
|
+
const isSubscribeGetDataWebSocketEventDto = (event) => {
|
|
3030
2973
|
return isWebsocketSubscription(event)
|
|
3031
2974
|
&& event?.event === WebSocketSubscriptionEvent.SUBSCRIBE_GET_DATA;
|
|
3032
2975
|
};
|
|
3033
|
-
const
|
|
2976
|
+
const isUnsubscribeGetDataWebSocketEventDto = (event) => {
|
|
3034
2977
|
return isWebsocketSubscription(event)
|
|
3035
2978
|
&& event?.event === WebSocketSubscriptionEvent.UNSUBSCRIBE_GET_DATA;
|
|
3036
2979
|
};
|
|
3037
|
-
const
|
|
2980
|
+
const isSubscribeProblemCrawledWebSocketEventDto = (event) => {
|
|
3038
2981
|
return isWebsocketSubscription(event)
|
|
3039
2982
|
&& event?.event === WebSocketSubscriptionEvent.SUBSCRIBE_PROBLEM_CRAWLED;
|
|
3040
2983
|
};
|
|
3041
|
-
const
|
|
2984
|
+
const isUnsubscribeProblemCrawledWebSocketEventDto = (event) => {
|
|
3042
2985
|
return isWebsocketSubscription(event)
|
|
3043
2986
|
&& event?.event === WebSocketSubscriptionEvent.UNSUBSCRIBE_PROBLEM_CRAWLED;
|
|
3044
2987
|
};
|
|
3045
|
-
const
|
|
2988
|
+
const isSubscribeSubmissionsCrawlWebSocketEventDto = (event) => {
|
|
3046
2989
|
return isWebsocketSubscription(event)
|
|
3047
2990
|
&& event?.event === WebSocketSubscriptionEvent.SUBSCRIBE_SUBMISSIONS_CRAWL;
|
|
3048
2991
|
};
|
|
3049
|
-
const
|
|
2992
|
+
const isUnsubscribeSubmissionsCrawlWebSocketEventDto = (event) => {
|
|
3050
2993
|
return isWebsocketSubscription(event)
|
|
3051
2994
|
&& event?.event === WebSocketSubscriptionEvent.UNSUBSCRIBE_SUBMISSIONS_CRAWL;
|
|
3052
2995
|
};
|
|
3053
|
-
const
|
|
2996
|
+
const isSubscribeContestChangesWebSocketEventDto = (event) => {
|
|
3054
2997
|
return isWebsocketSubscription(event)
|
|
3055
2998
|
&& event?.event === WebSocketSubscriptionEvent.SUBSCRIBE_CONTEST_CHANGES;
|
|
3056
2999
|
};
|
|
3057
|
-
const
|
|
3000
|
+
const isUnsubscribeContestChangesWebSocketEventDto = (event) => {
|
|
3058
3001
|
return isWebsocketSubscription(event)
|
|
3059
3002
|
&& event?.event === WebSocketSubscriptionEvent.UNSUBSCRIBE_CONTEST_CHANGES;
|
|
3060
3003
|
};
|
|
3061
|
-
const
|
|
3062
|
-
return isWebsocketSubscription(event)
|
|
3063
|
-
&& event?.event === WebSocketSubscriptionEvent.SUBSCRIBE_CLIENT_TRACK;
|
|
3064
|
-
};
|
|
3065
|
-
const isUnsubscribeClientTrackWebSocketEventDTO = (event) => {
|
|
3066
|
-
return isWebsocketSubscription(event)
|
|
3067
|
-
&& event?.event === WebSocketSubscriptionEvent.UNSUBSCRIBE_CLIENT_TRACK;
|
|
3068
|
-
};
|
|
3069
|
-
const isSubscribeUserNotificationWebSocketEventDTO = (event) => {
|
|
3004
|
+
const isSubscribeUserNotificationWebSocketEventDto = (event) => {
|
|
3070
3005
|
return isWebsocketSubscription(event)
|
|
3071
3006
|
&& event?.event === WebSocketSubscriptionEvent.SUBSCRIBE_USER_NOTIFICATION;
|
|
3072
3007
|
};
|
|
3073
|
-
const
|
|
3008
|
+
const isUnsubscribeUserNotificationWebSocketEventDto = (event) => {
|
|
3074
3009
|
return isWebsocketSubscription(event)
|
|
3075
3010
|
&& event?.event === WebSocketSubscriptionEvent.UNSUBSCRIBE_USER_NOTIFICATION;
|
|
3076
3011
|
};
|
|
3077
|
-
const
|
|
3012
|
+
const isNonEmptyString = (value) => typeof value === 'string' && !!value;
|
|
3013
|
+
/**
|
|
3014
|
+
* Exactly one of `problemKey` / `contestKey` / `userId` is set.
|
|
3015
|
+
*/
|
|
3016
|
+
const isSubmissionsJudgingScope = (scope) => {
|
|
3017
|
+
return [scope?.problemKey, scope?.contestKey, scope?.userId].filter(isNonEmptyString).length === 1;
|
|
3018
|
+
};
|
|
3019
|
+
const isSubscribeSubmissionsJudgingWebSocketEventDto = (event) => {
|
|
3078
3020
|
return isWebsocketSubscription(event)
|
|
3079
|
-
&& event?.event === WebSocketSubscriptionEvent.
|
|
3080
|
-
&&
|
|
3021
|
+
&& event?.event === WebSocketSubscriptionEvent.SUBSCRIBE_SUBMISSIONS_JUDGING
|
|
3022
|
+
&& isSubmissionsJudgingScope(event);
|
|
3081
3023
|
};
|
|
3082
|
-
const
|
|
3024
|
+
const isUnsubscribeSubmissionsJudgingWebSocketEventDto = (event) => {
|
|
3083
3025
|
return isWebsocketSubscription(event)
|
|
3084
|
-
&& event?.event === WebSocketSubscriptionEvent.
|
|
3085
|
-
&&
|
|
3026
|
+
&& event?.event === WebSocketSubscriptionEvent.UNSUBSCRIBE_SUBMISSIONS_JUDGING
|
|
3027
|
+
&& isSubmissionsJudgingScope(event);
|
|
3086
3028
|
};
|
|
3087
|
-
// is
|
|
3088
|
-
const
|
|
3029
|
+
// is WebSocketResponseEventDto, CHANNEL_SUBSCRIBE_CLIENT
|
|
3030
|
+
const isWebSocketResponseEventDto = (event) => {
|
|
3089
3031
|
return Object.values(WebSocketResponseEvent).includes(event?.event)
|
|
3090
3032
|
&& typeof event?.key === 'string'
|
|
3091
3033
|
&& typeof event?.connectionId === 'string'
|
|
3092
|
-
&& typeof event?.
|
|
3093
|
-
};
|
|
3094
|
-
const isPongWebSocketResponseEventDTO = (event) => {
|
|
3095
|
-
return isWebSocketResponseEventDTO(event)
|
|
3096
|
-
&& event?.event === WebSocketResponseEvent.PONG
|
|
3097
|
-
&& !!event?.data;
|
|
3034
|
+
&& typeof event?.createdAt === 'number' && !!event.createdAt;
|
|
3098
3035
|
};
|
|
3099
|
-
const
|
|
3100
|
-
return
|
|
3036
|
+
const isCodeRunStatusMessageWebSocketResponseEventDto = (event) => {
|
|
3037
|
+
return isWebSocketResponseEventDto(event)
|
|
3101
3038
|
&& event?.event === WebSocketResponseEvent.CODE_RUN_STATUS
|
|
3102
3039
|
&& typeof event?.runId === 'string' && !!event.runId
|
|
3103
3040
|
&& event?.status in SubmissionRunStatus;
|
|
3104
3041
|
};
|
|
3105
|
-
const
|
|
3106
|
-
return
|
|
3042
|
+
const isSubmissionRunStatusMessageWebSocketResponseEventDto = (event) => {
|
|
3043
|
+
return isWebSocketResponseEventDto(event)
|
|
3107
3044
|
&& event?.event === WebSocketResponseEvent.SUBMISSION_RUN_STATUS
|
|
3108
3045
|
&& typeof event?.submitId === 'string' && !!event.submitId
|
|
3109
3046
|
&& event?.status in SubmissionRunStatus
|
|
3110
3047
|
&& event?.verdict in ProblemVerdict
|
|
3111
3048
|
&& typeof event?.points === 'number';
|
|
3112
3049
|
};
|
|
3113
|
-
const
|
|
3114
|
-
return
|
|
3050
|
+
const isSubmissionJudgingWebSocketResponseEventDto = (event) => {
|
|
3051
|
+
return isWebSocketResponseEventDto(event)
|
|
3052
|
+
&& event?.event === WebSocketResponseEvent.SUBMISSION_JUDGING
|
|
3053
|
+
&& isNonEmptyString(event?.submitId)
|
|
3054
|
+
&& isNonEmptyString(event?.problemKey)
|
|
3055
|
+
&& (event?.contestKey === null || isNonEmptyString(event?.contestKey))
|
|
3056
|
+
&& isNonEmptyString(event?.userId)
|
|
3057
|
+
&& typeof event?.judging === 'boolean'
|
|
3058
|
+
&& event?.status in SubmissionRunStatus
|
|
3059
|
+
&& event?.verdict in ProblemVerdict
|
|
3060
|
+
&& typeof event?.points === 'number';
|
|
3061
|
+
};
|
|
3062
|
+
const isUserMessageWebSocketResponseEventDto = (event) => {
|
|
3063
|
+
return isWebSocketResponseEventDto(event)
|
|
3115
3064
|
&& event?.event === WebSocketResponseEvent.USER_MESSAGE
|
|
3116
3065
|
&& typeof event?.user?.nickname === 'string' && !!event.user?.nickname
|
|
3117
3066
|
&& typeof event?.user?.imageUrl === 'string' && !!event.user?.imageUrl
|
|
3118
|
-
&& typeof event?.user?.
|
|
3067
|
+
&& typeof event?.user?.organization?.key === 'string' && !!event.user?.organization?.key
|
|
3119
3068
|
&& !!event?.content;
|
|
3120
3069
|
};
|
|
3121
|
-
const
|
|
3070
|
+
const isSendDataWebSocketResponseEventDto = (event) => {
|
|
3122
3071
|
return [
|
|
3123
3072
|
WebSocketResponseEvent.SEND_DATA_ECS_TASK_DEFINITIONS_LIST,
|
|
3124
3073
|
WebSocketResponseEvent.SEND_DATA_EC2_INSTANCES_LIST,
|
|
3125
3074
|
WebSocketResponseEvent.SEND_DATA_ECS_TASKS_LIST,
|
|
3126
3075
|
WebSocketResponseEvent.SEND_DATA_SSM_SESSIONS_LIST,
|
|
3127
3076
|
WebSocketResponseEvent.SEND_DATA_RUN_COMMAND,
|
|
3128
|
-
WebSocketResponseEvent.SEND_DATA_CLIENT_TRACK,
|
|
3129
|
-
WebSocketResponseEvent.SEND_DATA_CHAT_COMPLETIONS,
|
|
3130
3077
|
].includes(event?.event)
|
|
3131
3078
|
&& typeof event?.dataId === 'string' && !!event.dataId
|
|
3132
3079
|
&& !!event?.content;
|
|
3133
3080
|
};
|
|
3134
|
-
const
|
|
3135
|
-
return
|
|
3081
|
+
const isSendDataEcsTaskDefinitionListWebSocketResponseEventDto = (event) => {
|
|
3082
|
+
return isWebSocketResponseEventDto(event) && isSendDataWebSocketResponseEventDto(event)
|
|
3136
3083
|
&& event?.event === WebSocketResponseEvent.SEND_DATA_ECS_TASK_DEFINITIONS_LIST;
|
|
3137
3084
|
};
|
|
3138
|
-
const
|
|
3139
|
-
return
|
|
3085
|
+
const isSendDataEc2InstancesListWebSocketResponseEventDto = (event) => {
|
|
3086
|
+
return isWebSocketResponseEventDto(event) && isSendDataWebSocketResponseEventDto(event)
|
|
3140
3087
|
&& event?.event === WebSocketResponseEvent.SEND_DATA_EC2_INSTANCES_LIST;
|
|
3141
3088
|
};
|
|
3142
|
-
const
|
|
3143
|
-
return
|
|
3089
|
+
const isSendDataEcsTasksListWebSocketResponseEventDto = (event) => {
|
|
3090
|
+
return isWebSocketResponseEventDto(event) && isSendDataWebSocketResponseEventDto(event)
|
|
3144
3091
|
&& event?.event === WebSocketResponseEvent.SEND_DATA_ECS_TASKS_LIST;
|
|
3145
3092
|
};
|
|
3146
|
-
const
|
|
3147
|
-
return
|
|
3093
|
+
const isSendDataSsmSessionsListWebSocketResponseEventDto = (event) => {
|
|
3094
|
+
return isWebSocketResponseEventDto(event) && isSendDataWebSocketResponseEventDto(event)
|
|
3148
3095
|
&& event?.event === WebSocketResponseEvent.SEND_DATA_SSM_SESSIONS_LIST;
|
|
3149
3096
|
};
|
|
3150
|
-
const
|
|
3151
|
-
return
|
|
3097
|
+
const isSendDataRunCommandWebSocketResponseEventDto = (event) => {
|
|
3098
|
+
return isWebSocketResponseEventDto(event) && isSendDataWebSocketResponseEventDto(event)
|
|
3152
3099
|
&& event?.event === WebSocketResponseEvent.SEND_DATA_RUN_COMMAND;
|
|
3153
3100
|
};
|
|
3154
|
-
const
|
|
3155
|
-
return
|
|
3156
|
-
&& event?.event === WebSocketResponseEvent.SEND_DATA_CLIENT_TRACK;
|
|
3157
|
-
};
|
|
3158
|
-
const isSenDataChatCompletionsWebSocketResponseEventDTO = (event) => {
|
|
3159
|
-
return isWebSocketResponseEventDTO(event) && isSendDataWebSocketResponseEventDTO(event)
|
|
3160
|
-
&& event?.event === WebSocketResponseEvent.SEND_DATA_CHAT_COMPLETIONS;
|
|
3161
|
-
};
|
|
3162
|
-
const isProblemCrawledWebSocketResponseEventDTO = (event) => {
|
|
3163
|
-
return isWebSocketResponseEventDTO(event)
|
|
3101
|
+
const isProblemCrawledWebSocketResponseEventDto = (event) => {
|
|
3102
|
+
return isWebSocketResponseEventDto(event)
|
|
3164
3103
|
&& event?.event === WebSocketResponseEvent.PROBLEM_CRAWLED
|
|
3165
3104
|
&& !!event?.content;
|
|
3166
3105
|
};
|
|
3167
|
-
const
|
|
3168
|
-
return
|
|
3106
|
+
const isSubmissionsCrawlWebSocketResponseEventDto = (event) => {
|
|
3107
|
+
return isWebSocketResponseEventDto(event)
|
|
3169
3108
|
&& event?.event === WebSocketResponseEvent.SUBMISSIONS_CRAWL
|
|
3170
3109
|
&& !!event?.content;
|
|
3171
3110
|
};
|
|
3172
|
-
const
|
|
3173
|
-
return
|
|
3111
|
+
const isContestChangesWebSocketResponseEventDto = (event) => {
|
|
3112
|
+
return isWebSocketResponseEventDto(event)
|
|
3174
3113
|
&& event?.event === WebSocketResponseEvent.CONTEST_CHANGES
|
|
3175
3114
|
&& !!event?.content;
|
|
3176
3115
|
};
|
|
3177
|
-
const
|
|
3178
|
-
return isWebSocketResponseEventDTO(event)
|
|
3179
|
-
&& event?.event === WebSocketResponseEvent.CLIENT_TRACK;
|
|
3180
|
-
};
|
|
3181
|
-
const isUserNotificationWebSocketResponseEventDTO = (event) => {
|
|
3116
|
+
const isUserNotificationWebSocketResponseEventDto = (event) => {
|
|
3182
3117
|
return [
|
|
3183
3118
|
WebSocketResponseEvent.USER_NOTIFICATION_SUBMISSION,
|
|
3184
3119
|
WebSocketResponseEvent.USER_NOTIFICATION_CONTEST_CLARIFICATION,
|
|
3185
3120
|
].includes(event?.event)
|
|
3186
3121
|
&& !!event?.content;
|
|
3187
3122
|
};
|
|
3188
|
-
const
|
|
3189
|
-
return
|
|
3123
|
+
const isUserNotificationSubmissionWebSocketResponseEventDto = (event) => {
|
|
3124
|
+
return isWebSocketResponseEventDto(event) && isUserNotificationWebSocketResponseEventDto(event)
|
|
3190
3125
|
&& event?.event === WebSocketResponseEvent.USER_NOTIFICATION_SUBMISSION;
|
|
3191
3126
|
};
|
|
3192
|
-
const
|
|
3193
|
-
return
|
|
3127
|
+
const isUserNotificationContestClarificationWebSocketResponseEventDto = (event) => {
|
|
3128
|
+
return isWebSocketResponseEventDto(event) && isUserNotificationWebSocketResponseEventDto(event)
|
|
3194
3129
|
&& event?.event === WebSocketResponseEvent.USER_NOTIFICATION_CONTEST_CLARIFICATION;
|
|
3195
3130
|
};
|
|
3196
3131
|
// generic
|
|
3197
3132
|
const getWebSocketResponseEventKey = (event, clientId, id) => {
|
|
3198
3133
|
return `${event}-${clientId}-${id}`;
|
|
3199
3134
|
};
|
|
3200
|
-
const
|
|
3135
|
+
const isWebSocketChannelsMessageDto = (message) => {
|
|
3201
3136
|
return Array.isArray(message?.channels)
|
|
3202
3137
|
&& message.channels.every((channel) => typeof channel === 'string' && !!channel)
|
|
3203
3138
|
&& Object.values(WebSocketResponseEvent).includes(message?.event?.event);
|
|
3204
3139
|
};
|
|
3205
3140
|
/**
|
|
3206
3141
|
* Key used by the client to dispatch a response received on a TOPIC channel to its subscribers.
|
|
3207
|
-
* It is the same key that `
|
|
3142
|
+
* It is the same key that `getKeyWebSocketEventDto` (base-ui) computes for the subscription.
|
|
3208
3143
|
* Returns null when the response is not addressed to this client.
|
|
3209
3144
|
*/
|
|
3210
3145
|
const getWebSocketResponseEventKeyOfResponse = (response, clientId) => {
|
|
3211
|
-
if (
|
|
3146
|
+
if (isCodeRunStatusMessageWebSocketResponseEventDto(response)) {
|
|
3212
3147
|
return getWebSocketResponseEventKey(WebSocketResponseEvent.CODE_RUN_STATUS, clientId, response.runId);
|
|
3213
3148
|
}
|
|
3214
|
-
if (
|
|
3149
|
+
if (isSubmissionRunStatusMessageWebSocketResponseEventDto(response)) {
|
|
3215
3150
|
return getWebSocketResponseEventKey(WebSocketResponseEvent.SUBMISSION_RUN_STATUS, clientId, response.submitId);
|
|
3216
3151
|
}
|
|
3217
|
-
if (
|
|
3152
|
+
if (isSendDataWebSocketResponseEventDto(response)) {
|
|
3218
3153
|
return getWebSocketResponseEventKey(WebSocketResponseEvent.SEND_DATA_, clientId, response.dataId);
|
|
3219
3154
|
}
|
|
3220
|
-
if (
|
|
3155
|
+
if (isContestChangesWebSocketResponseEventDto(response)) {
|
|
3221
3156
|
return getWebSocketResponseEventKey(WebSocketResponseEvent.CONTEST_CHANGES, clientId, response.content.contestKey);
|
|
3222
3157
|
}
|
|
3223
|
-
if (
|
|
3158
|
+
if (isProblemCrawledWebSocketResponseEventDto(response)) {
|
|
3224
3159
|
return getWebSocketResponseEventKey(WebSocketResponseEvent.PROBLEM_CRAWLED, clientId, response.content.problemKey);
|
|
3225
3160
|
}
|
|
3226
|
-
if (
|
|
3161
|
+
if (isSubmissionsCrawlWebSocketResponseEventDto(response)) {
|
|
3227
3162
|
return getWebSocketResponseEventKey(WebSocketResponseEvent.SUBMISSIONS_CRAWL, clientId, join([response.content.contestKey, response.content.problemKeys]));
|
|
3228
3163
|
}
|
|
3229
|
-
if (
|
|
3230
|
-
// the command is sent to the session channel, `key` holds the targeted client
|
|
3231
|
-
return response.key === clientId ? getWebSocketResponseEventKey(WebSocketResponseEvent.CLIENT_TRACK, clientId, '*') : null;
|
|
3232
|
-
}
|
|
3233
|
-
if (isUserNotificationWebSocketResponseEventDTO(response)) {
|
|
3164
|
+
if (isUserNotificationWebSocketResponseEventDto(response)) {
|
|
3234
3165
|
return getWebSocketResponseEventKey(WebSocketResponseEvent.USER_NOTIFICATION_, clientId, '*');
|
|
3235
3166
|
}
|
|
3167
|
+
if (isSubmissionJudgingWebSocketResponseEventDto(response)) {
|
|
3168
|
+
// one key for every table: the same event is published on several channels (problem / contest / user) and the
|
|
3169
|
+
// client deduplicates it, so it is dispatched once; each table filters by the submissions it lists
|
|
3170
|
+
return getWebSocketResponseEventKey(WebSocketResponseEvent.SUBMISSION_JUDGING, clientId, '*');
|
|
3171
|
+
}
|
|
3236
3172
|
return null;
|
|
3237
3173
|
};
|
|
3238
3174
|
/**
|
|
@@ -3241,17 +3177,25 @@ const getWebSocketResponseEventKeyOfResponse = (response, clientId) => {
|
|
|
3241
3177
|
* Ably rejects the attach if the token has no capability for the channel.
|
|
3242
3178
|
*/
|
|
3243
3179
|
const getChannelOfWebSocketSubscribeEvent = (event) => {
|
|
3244
|
-
if (
|
|
3180
|
+
if (isSubscribeSubmissionRunStatusWebSocketEventDto(event)) {
|
|
3245
3181
|
return CHANNEL_SUBMISSION(event.submitId);
|
|
3246
3182
|
}
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
}
|
|
3250
|
-
if (isSubscribeContestChangesWebSocketEventDTO(event) || isSubscribeSubmissionsCrawlWebSocketEventDTO(event)) {
|
|
3183
|
+
// SUBSCRIBE_PROBLEM_CRAWLED: the event arrives by the private user channel of who requested the crawl
|
|
3184
|
+
if (isSubscribeContestChangesWebSocketEventDto(event) || isSubscribeSubmissionsCrawlWebSocketEventDto(event)) {
|
|
3251
3185
|
return CHANNEL_CONTEST(event.contestKey, ContestChannelRole.SPECTATORS);
|
|
3252
3186
|
}
|
|
3253
|
-
if (
|
|
3254
|
-
|
|
3187
|
+
if (isSubscribeSubmissionsJudgingWebSocketEventDto(event)) {
|
|
3188
|
+
// the judging start/end is published on the spectators channel when it is visible to everyone; the hidden ones
|
|
3189
|
+
// (frozen / quiet contests) arrive by the role channels of the contest (managers) and the private user channel
|
|
3190
|
+
if ('problemKey' in event && event.problemKey) {
|
|
3191
|
+
return CHANNEL_PROBLEM(event.problemKey, ProblemChannelRole.SPECTATORS);
|
|
3192
|
+
}
|
|
3193
|
+
if ('contestKey' in event && event.contestKey) {
|
|
3194
|
+
return CHANNEL_CONTEST(event.contestKey, ContestChannelRole.SPECTATORS);
|
|
3195
|
+
}
|
|
3196
|
+
if ('userId' in event && event.userId) {
|
|
3197
|
+
return CHANNEL_USER_ROLE(event.userId, UserChannelRole.SPECTATORS);
|
|
3198
|
+
}
|
|
3255
3199
|
}
|
|
3256
3200
|
return null;
|
|
3257
3201
|
};
|
|
@@ -3259,11 +3203,23 @@ const getChannelOfWebSocketSubscribeEvent = (event) => {
|
|
|
3259
3203
|
* Contest whose role channels the client needs (the API grants them when the token is requested with this contest).
|
|
3260
3204
|
*/
|
|
3261
3205
|
const getContestKeyOfWebSocketSubscribeEvent = (event) => {
|
|
3262
|
-
if (
|
|
3206
|
+
if (isSubscribeContestChangesWebSocketEventDto(event) || isSubscribeSubmissionsCrawlWebSocketEventDto(event)) {
|
|
3207
|
+
return event.contestKey;
|
|
3208
|
+
}
|
|
3209
|
+
if (isSubscribeSubmissionsJudgingWebSocketEventDto(event) && 'contestKey' in event && event.contestKey) {
|
|
3263
3210
|
return event.contestKey;
|
|
3264
3211
|
}
|
|
3265
3212
|
return null;
|
|
3266
3213
|
};
|
|
3214
|
+
/**
|
|
3215
|
+
* Problem whose role channels the client needs (the API grants them when the token is requested with this problem).
|
|
3216
|
+
*/
|
|
3217
|
+
const getProblemKeyOfWebSocketSubscribeEvent = (event) => {
|
|
3218
|
+
if (isSubscribeSubmissionsJudgingWebSocketEventDto(event) && 'problemKey' in event && event.problemKey) {
|
|
3219
|
+
return event.problemKey;
|
|
3220
|
+
}
|
|
3221
|
+
return null;
|
|
3222
|
+
};
|
|
3267
3223
|
|
|
3268
3224
|
function splitTime(timeRemaining) {
|
|
3269
3225
|
const remaining = [];
|
|
@@ -3334,44 +3290,13 @@ function splitTime(timeRemaining) {
|
|
|
3334
3290
|
// }
|
|
3335
3291
|
return remaining;
|
|
3336
3292
|
}
|
|
3337
|
-
function normalizeToLocalStartOfDay(timestamp) {
|
|
3338
|
-
const date = new Date(timestamp);
|
|
3339
|
-
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
3340
|
-
}
|
|
3341
|
-
function normalizeToLocalStartOfHour(timestamp) {
|
|
3342
|
-
const date = new Date(timestamp);
|
|
3343
|
-
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours());
|
|
3344
|
-
}
|
|
3345
|
-
function normalizeToLocalStartOfMinutes(timestamp) {
|
|
3346
|
-
const date = new Date(timestamp);
|
|
3347
|
-
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes());
|
|
3348
|
-
}
|
|
3349
|
-
function normalizeToLocalStartOfSeconds(timestamp) {
|
|
3350
|
-
const date = new Date(timestamp);
|
|
3351
|
-
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes());
|
|
3352
|
-
}
|
|
3353
|
-
const getYears = (d) => d.getFullYear();
|
|
3354
|
-
const getMonths = (d) => d.getFullYear() * 12 + d.getMonth();
|
|
3355
|
-
const getDays = (d) => {
|
|
3356
|
-
return Math.floor(normalizeToLocalStartOfDay(d).getTime() / ONE_DAY);
|
|
3357
|
-
};
|
|
3358
|
-
const getHours = (d) => {
|
|
3359
|
-
return Math.floor(normalizeToLocalStartOfHour(d).getTime() / ONE_HOUR);
|
|
3360
|
-
};
|
|
3361
|
-
const getMinutes = (d) => {
|
|
3362
|
-
return Math.floor(normalizeToLocalStartOfMinutes(d).getTime() / ONE_MINUTE);
|
|
3363
|
-
};
|
|
3364
|
-
const getSeconds = (d) => {
|
|
3365
|
-
return Math.floor(normalizeToLocalStartOfSeconds(d).getTime() / 1000);
|
|
3366
|
-
};
|
|
3367
|
-
const getMilliseconds = (d) => d.getTime();
|
|
3368
3293
|
|
|
3369
|
-
const getUserKey = (userNickname,
|
|
3370
|
-
return userNickname + '|' +
|
|
3294
|
+
const getUserKey = (userNickname, userOrganizationKey) => {
|
|
3295
|
+
return userNickname + '|' + userOrganizationKey;
|
|
3371
3296
|
};
|
|
3372
3297
|
const getParamsOfUserKey = (userKey) => {
|
|
3373
|
-
const [userNickname,
|
|
3374
|
-
return { userNickname,
|
|
3298
|
+
const [userNickname, userOrganizationKey] = userKey.split('|');
|
|
3299
|
+
return { userNickname, userOrganizationKey };
|
|
3375
3300
|
};
|
|
3376
3301
|
const getClientId = (sessionId, uiId) => {
|
|
3377
3302
|
return `${sessionId}|${uiId}`;
|
|
@@ -3487,4 +3412,4 @@ const isQuizTextSheet = (value) => {
|
|
|
3487
3412
|
&& ['text', 'number', 'textarea'].includes(value?.inputType);
|
|
3488
3413
|
};
|
|
3489
3414
|
|
|
3490
|
-
export { ACCEPTED_PROGRAMMING_LANGUAGES, ASPECT_RATIO, AspectRatio, AssignmentClass, AssignmentState, AssignmentType,
|
|
3415
|
+
export { ACCEPTED_PROGRAMMING_LANGUAGES, ASPECT_RATIO, AspectRatio, AssignmentClass, AssignmentState, AssignmentType, CHANNEL_CONTEST, CHANNEL_ORGANIZATION_PRESENCE, CHANNEL_PROBLEM, CHANNEL_SESSION, CHANNEL_SUBMISSION, CHANNEL_SUBMISSION_ALL, CHANNEL_USER, CHANNEL_USER_ROLE, CHANNEL_USER_SPECTATORS_ALL, CODE_LANGUAGE, CONTEST_ROLE, CONTEST_STATUS, COOKIE_JUKI_SESSION_ID, COURSE_ROLE, CodeLanguage, CollectionKey, ContestChannelRole, ContestEventAction, ContestProblemBlockedByType, ContestProblemPrerequisiteType, ContestStatus, ContestTimeStatus, CourseRole, CourseStatus, CourseType, DAY_NAMES, DEFAULT_JUKI_PROFILE_IMAGE, DataViewMode, EMPTY_DOCUMENT_MEMBERS, EMPTY_ENTITY_MEMBERS, EMPTY_USER_PERMISSIONS, ENTITY_ACCESS, ENTITY_STATE, ERROR, EmailSubscription, EmailValidationState, EntityAccess, EntityCollection, EntityMembersRank, EntityState, EntityStatus, ErrorCode, FILE_ROLE, FILE_TYPE, FileMemberRole, FileType, FilesJukiPub, GroupType, HEADER_JUKI_FORWARDED_HOST, HEADER_JUKI_INTERNAL_API_KEY, HEADER_JUKI_METADATA, HEADER_JUKI_SECRET_TOKEN, HEADER_JUKI_VISITOR_SESSION_ID, HOURS, HTTPMethod, JUDGE, JUKI_APP_EMAIL_TEMPLATE, JUKI_APP_ORGANIZATION_KEY, JkError, Judge, LANGUAGE, LOWERCASE_LETTERS, Language, LogLevel, LogOperation, MAX_DATE, MEMBER_ROLE, MILLISECONDS, MINUTES, MIN_DATE, MONTH_NAMES, MemberRole, MemberType, MenuViewMode, NEW_PAGE_SHEET, NUMBERS, NotificationType, ONE_DAY, ONE_HOUR, ONE_MINUTE, ONE_SECOND, ONE_WEEK, ORGANIZATION_PLAN, OrganizationLogoType, OrganizationPlan, PAGE, PAGE_SIZE, PAGE_SIZES, PALLETE, PROBLEM_INPUT, PROBLEM_MODE, PROBLEM_MODES, PROBLEM_OUTPUT, PROBLEM_ROLE, PROBLEM_TYPE, PROBLEM_TYPES, PROBLEM_VERDICT, PROBLEM_VERDICTS, ProblemChannelRole, ProblemInput, ProblemOutput, ProblemScoringMode, ProblemType, ProblemVerdict, ProfileSetting, QuizScoringMode, RUNNER_ACCEPTED_PROBLEM_MODES, RUNNER_ACCEPTED_PROBLEM_TYPES, RUNNER_ACCEPTED_PROGRAMMING_LANGUAGES, RUNNER_TYPE, Role, RunnerType, SECONDS, SEC_120, SEC_30, SEC_60, SEC_90, SEPARATOR_TOKEN, SUBMISSION_RUN_STATUS, SUPPORT_EMAIL, SYSTEM_ROLE, ScopeData, Status, SubmissionRunStatus, SystemRole, TEAM_ROLE, THEME, TeamRole, TeamStatus, Theme, TypeTestCase, UPPERCASE_LETTERS, USER_ROLE, USER_STATUS, UserChannelRole, UserRole, UserStatus, UserTeamStatus, WebSocketResponseEvent, WebSocketSubscriptionEvent, WorkingIn, WorksheetType, YEARS, _KEY, _SUB_SUB_TAB, _SUB_TAB, _TAB, _TYPE, areArraysDifferent, changeDay, changeHours, changeMilliseconds, changeMinutes, changeMonth, changeSeconds, changeYear, chunkString, cleanRequest, clearAsyncInterval, consoleError, consoleInfo, consoleWarn, contentResponse, contentsResponse, decreaseDay, decreaseMonth, decreaseYear, endOfDay, endOfHour, endOfMinute, endOfMonth, endOfSecond, endOfWeek, endOfYear, errorsResponse, getAssignmentCommentKey, getAssignmentUserCommentKey, getChannelOfWebSocketSubscribeEvent, getClientId, getContestChannelParams, getContestCommentKey, getContestKeyOfWebSocketSubscribeEvent, getDataLog, getDataOfTestCase, getDays, getDefaultMeta, getDocumentAccess, getHours, getMilliseconds, getMinutes, getMonths, getParamsOfClientId, getParamsOfUserKey, getPlainText, getProblemChannelParams, getProblemCommentKey, getProblemJudgeKey, getProblemKeyOfWebSocketSubscribeEvent, getRandomString, getSeconds, getSummaryWorksheetsInPages, getTotalExercisesOfSummaryWorksheetsInPages, getUserKey, getVerdictFromTestCase, getWebSocketResponseEventKey, getWebSocketResponseEventKeyOfResponse, getWorksheetsInPages, getYears, humanFileSize, increaseDay, increaseMonth, increaseYear, indexToLetters, isAfter, isBasicWorksheet, isBefore, isCodeEditorSheet, isCodeRunStatusMessageWebSocketResponseEventDto, isContestAssignment, isContestChangesWebSocketResponseEventDto, isCourseAssignment, isDayAfter, isDayBefore, isEndlessContest, isEqual, isFutureContest, isGlobalContest, isHoursAfter, isHoursBefore, isJkmdSheet, isMillisecondsAfter, isMillisecondsBefore, isMinutesAfter, isMinutesBefore, isMonthAfter, isMonthBefore, isObjectJson, isPastContest, isProblemCrawledWebSocketResponseEventDto, isQuizOptionsSheet, isQuizProblemSheet, isQuizTextSheet, isSameDay, isSameHour, isSameMillisecond, isSameMinute, isSameMonth, isSameSecond, isSameYear, isSecondsAfter, isSecondsBefore, isSendDataEc2InstancesListWebSocketResponseEventDto, isSendDataEcsTaskDefinitionListWebSocketResponseEventDto, isSendDataEcsTasksListWebSocketResponseEventDto, isSendDataRunCommandWebSocketResponseEventDto, isSendDataSsmSessionsListWebSocketResponseEventDto, isSendDataWebSocketResponseEventDto, isStringJson, isSubmissionJudgingWebSocketResponseEventDto, isSubmissionRunStatusMessageWebSocketResponseEventDto, isSubmissionsCrawlWebSocketResponseEventDto, isSubmissionsJudgingScope, isSubscribeCodeRunStatusWebSocketEventDto, isSubscribeContestChangesWebSocketEventDto, isSubscribeGetDataWebSocketEventDto, isSubscribeProblemCrawledWebSocketEventDto, isSubscribeSubmissionRunStatusWebSocketEventDto, isSubscribeSubmissionsCrawlWebSocketEventDto, isSubscribeSubmissionsJudgingWebSocketEventDto, isSubscribeUserNotificationWebSocketEventDto, isTeamMember, isToday, isUnsubscribeCodeRunStatusWebSocketEventDto, isUnsubscribeContestChangesWebSocketEventDto, isUnsubscribeGetDataWebSocketEventDto, isUnsubscribeProblemCrawledWebSocketEventDto, isUnsubscribeSubmissionRunStatusWebSocketEventDto, isUnsubscribeSubmissionsCrawlWebSocketEventDto, isUnsubscribeSubmissionsJudgingWebSocketEventDto, isUnsubscribeUserNotificationWebSocketEventDto, isUserMember, isUserMessageWebSocketResponseEventDto, isUserNotificationContestClarificationWebSocketResponseEventDto, isUserNotificationSubmissionWebSocketResponseEventDto, isUserNotificationWebSocketResponseEventDto, isValidDate, isWebSocketChannelsMessageDto, isWebSocketResponseEventDto, isWebsocketSubscription, isWithinInterval, isWorksheetAssignment, isYearAfter, isYearBefore, join, lettersToIndex, memorySizeOf, mergeVerdicts, mex, normalizeToLocalStartOfDay, normalizeToLocalStartOfHour, normalizeToLocalStartOfMinutes, normalizeToLocalStartOfSeconds, objectUpdate, objectsUpdate, padEnd, padStart, range, removeExtension, safeJsonParse, setAsyncInterval, split, splitTime, startOfDay, startOfHour, startOfMinute, startOfMonth, startOfSecond, startOfWeek, startOfYear, stringToArrayBuffer, toEntityMembersDto, toJkError };
|