@rhseung/ps-cli 1.7.5 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -12
- package/dist/chunk-D5PTJ4WQ.js +210 -0
- package/dist/chunk-EGPBBIJ2.js +251 -0
- package/dist/{chunk-F4LZ6ENP.js → chunk-JZK2464U.js} +1037 -118
- package/dist/chunk-SBBC4CBS.js +414 -0
- package/dist/{chunk-VIHXBCOZ.js → chunk-TTTS4CDS.js} +1 -1
- package/dist/chunk-XV6UUPQC.js +288 -0
- package/dist/{chunk-4ISG24GW.js → chunk-YH6VDCNG.js} +173 -15
- package/dist/chunk-YXLVFZZH.js +370 -0
- package/dist/commands/archive.js +6 -195
- package/dist/commands/config.js +74 -188
- package/dist/commands/fetch.js +7 -394
- package/dist/commands/init.js +50 -10
- package/dist/commands/open.js +6 -93
- package/dist/commands/run.js +59 -47
- package/dist/commands/search.js +296 -125
- package/dist/commands/stats.js +333 -84
- package/dist/commands/submit.js +7 -245
- package/dist/commands/test.js +7 -371
- package/dist/index.js +90 -52
- package/package.json +2 -1
- package/dist/chunk-7MQMPJ3X.js +0 -88
- package/dist/chunk-A6STXEAE.js +0 -54
- package/dist/chunk-ASMT3CRD.js +0 -500
- package/dist/chunk-GCOFFYJ3.js +0 -47
package/dist/commands/stats.js
CHANGED
|
@@ -1,84 +1,184 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
getUserProblemStats,
|
|
4
|
+
getUserStats,
|
|
5
|
+
getUserTagRatings,
|
|
6
|
+
getUserTop100,
|
|
7
|
+
scrapeUserStats
|
|
8
|
+
} from "../chunk-YH6VDCNG.js";
|
|
8
9
|
import {
|
|
9
10
|
Command,
|
|
10
11
|
CommandBuilder,
|
|
11
12
|
CommandDef,
|
|
13
|
+
TIER_COLORS,
|
|
14
|
+
__decorateClass,
|
|
12
15
|
calculateTierProgress,
|
|
16
|
+
defineFlags,
|
|
17
|
+
findProjectRoot,
|
|
18
|
+
getArchiveDir,
|
|
13
19
|
getNextTierMinRating,
|
|
14
20
|
getSolvedAcHandle,
|
|
21
|
+
getSolvingDir,
|
|
15
22
|
getTierColor,
|
|
16
|
-
getTierName
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
getTierName,
|
|
24
|
+
getTierShortName,
|
|
25
|
+
icons,
|
|
26
|
+
logger,
|
|
27
|
+
source_default
|
|
28
|
+
} from "../chunk-JZK2464U.js";
|
|
21
29
|
|
|
22
30
|
// src/commands/stats.tsx
|
|
23
|
-
import { Alert } from "@inkjs/ui";
|
|
24
|
-
import {
|
|
25
|
-
import { Box, Text
|
|
31
|
+
import { Alert, Spinner } from "@inkjs/ui";
|
|
32
|
+
import { BarChart, StackedBarChart } from "@pppp606/ink-chart";
|
|
33
|
+
import { Box, Text } from "ink";
|
|
26
34
|
|
|
27
35
|
// src/hooks/use-user-stats.ts
|
|
36
|
+
import { existsSync } from "fs";
|
|
37
|
+
import { readdir, stat } from "fs/promises";
|
|
38
|
+
import { join } from "path";
|
|
28
39
|
import { useEffect, useState } from "react";
|
|
40
|
+
async function countProblems(dir) {
|
|
41
|
+
let count = 0;
|
|
42
|
+
try {
|
|
43
|
+
if (!existsSync(dir)) return 0;
|
|
44
|
+
const entries = await readdir(dir);
|
|
45
|
+
for (const entry of entries) {
|
|
46
|
+
if (entry.startsWith(".")) continue;
|
|
47
|
+
const fullPath = join(dir, entry);
|
|
48
|
+
const s = await stat(fullPath);
|
|
49
|
+
if (s.isDirectory()) {
|
|
50
|
+
if (existsSync(join(fullPath, "meta.json"))) {
|
|
51
|
+
count++;
|
|
52
|
+
} else {
|
|
53
|
+
count += await countProblems(fullPath);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
} catch {
|
|
58
|
+
}
|
|
59
|
+
return count;
|
|
60
|
+
}
|
|
29
61
|
function useUserStats({
|
|
30
62
|
handle,
|
|
31
|
-
onComplete
|
|
63
|
+
onComplete,
|
|
64
|
+
fetchLocalCount = false
|
|
32
65
|
}) {
|
|
33
66
|
const [status, setStatus] = useState(
|
|
34
67
|
"loading"
|
|
35
68
|
);
|
|
36
69
|
const [user, setUser] = useState(null);
|
|
70
|
+
const [top100, setTop100] = useState(null);
|
|
71
|
+
const [problemStats, setProblemStats] = useState(null);
|
|
72
|
+
const [tagRatings, setTagRatings] = useState(
|
|
73
|
+
null
|
|
74
|
+
);
|
|
75
|
+
const [bojStats, setBojStats] = useState(null);
|
|
76
|
+
const [localSolvedCount, setLocalSolvedCount] = useState(null);
|
|
37
77
|
const [error, setError] = useState(null);
|
|
38
78
|
useEffect(() => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
79
|
+
async function fetchData() {
|
|
80
|
+
try {
|
|
81
|
+
const userData = await getUserStats(handle).catch((err) => {
|
|
82
|
+
if (err instanceof Error && err.message.includes("404")) {
|
|
83
|
+
throw new Error(`\uC0AC\uC6A9\uC790 '${handle}'\uC744(\uB97C) \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`);
|
|
84
|
+
}
|
|
85
|
+
throw err;
|
|
86
|
+
});
|
|
87
|
+
if (!userData) {
|
|
88
|
+
throw new Error(`\uC0AC\uC6A9\uC790 '${handle}'\uC744(\uB97C) \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`);
|
|
89
|
+
}
|
|
90
|
+
setUser(userData);
|
|
91
|
+
const [top100Data, problemStatsData, tagRatingsData, bojStatsData] = await Promise.all([
|
|
92
|
+
getUserTop100(handle).catch((err) => {
|
|
93
|
+
console.error("Error fetching top 100:", err);
|
|
94
|
+
return null;
|
|
95
|
+
}),
|
|
96
|
+
getUserProblemStats(handle).catch((err) => {
|
|
97
|
+
console.error("Error fetching problem stats:", err);
|
|
98
|
+
return null;
|
|
99
|
+
}),
|
|
100
|
+
getUserTagRatings(handle).catch((err) => {
|
|
101
|
+
console.error("Error fetching tag ratings:", err);
|
|
102
|
+
return null;
|
|
103
|
+
}),
|
|
104
|
+
scrapeUserStats(handle).catch((err) => {
|
|
105
|
+
console.error("Error scraping BOJ stats:", err);
|
|
106
|
+
return null;
|
|
107
|
+
})
|
|
108
|
+
]);
|
|
109
|
+
setTop100(top100Data);
|
|
110
|
+
setProblemStats(problemStatsData);
|
|
111
|
+
setTagRatings(tagRatingsData);
|
|
112
|
+
setBojStats(bojStatsData);
|
|
113
|
+
if (fetchLocalCount) {
|
|
114
|
+
const projectRoot = findProjectRoot();
|
|
115
|
+
if (projectRoot) {
|
|
116
|
+
const archiveDir = getArchiveDir();
|
|
117
|
+
const solvingDir = getSolvingDir();
|
|
118
|
+
const archivePath = join(projectRoot, archiveDir);
|
|
119
|
+
const solvingPath = join(projectRoot, solvingDir);
|
|
120
|
+
const [archiveCount, solvingCount] = await Promise.all([
|
|
121
|
+
countProblems(archivePath),
|
|
122
|
+
countProblems(solvingPath)
|
|
123
|
+
]);
|
|
124
|
+
setLocalSolvedCount(archiveCount + solvingCount);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
setStatus("success");
|
|
128
|
+
setTimeout(() => {
|
|
129
|
+
onComplete();
|
|
130
|
+
}, 5e3);
|
|
131
|
+
} catch (err) {
|
|
132
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
133
|
+
setStatus("error");
|
|
134
|
+
setTimeout(() => {
|
|
135
|
+
onComplete();
|
|
136
|
+
}, 3e3);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
void fetchData();
|
|
140
|
+
}, [fetchLocalCount, handle, onComplete]);
|
|
53
141
|
return {
|
|
54
142
|
status,
|
|
55
143
|
user,
|
|
144
|
+
top100,
|
|
145
|
+
problemStats,
|
|
146
|
+
tagRatings,
|
|
147
|
+
bojStats,
|
|
148
|
+
localSolvedCount,
|
|
56
149
|
error
|
|
57
150
|
};
|
|
58
151
|
}
|
|
59
152
|
|
|
60
153
|
// src/commands/stats.tsx
|
|
61
154
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
155
|
+
var statsFlagsSchema = {
|
|
156
|
+
handle: {
|
|
157
|
+
type: "string",
|
|
158
|
+
shortFlag: "h",
|
|
159
|
+
description: "Solved.ac \uD578\uB4E4 (\uC124\uC815\uC5D0 \uC800\uC7A5\uB41C \uAC12 \uC0AC\uC6A9 \uAC00\uB2A5)"
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
function StatsView({ handle, onComplete, showLocalStats }) {
|
|
163
|
+
const {
|
|
164
|
+
status,
|
|
165
|
+
user,
|
|
166
|
+
top100,
|
|
167
|
+
problemStats,
|
|
168
|
+
tagRatings,
|
|
169
|
+
bojStats,
|
|
170
|
+
localSolvedCount,
|
|
171
|
+
error
|
|
172
|
+
} = useUserStats({
|
|
74
173
|
handle,
|
|
75
|
-
onComplete
|
|
174
|
+
onComplete,
|
|
175
|
+
fetchLocalCount: showLocalStats
|
|
76
176
|
});
|
|
77
177
|
if (status === "loading") {
|
|
78
|
-
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: /* @__PURE__ */ jsx(Spinner, { label: "\uD1B5\uACC4\uB97C \uBD88\uB7EC\uC624\uB294 \uC911..." }) });
|
|
178
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", paddingY: 1, children: /* @__PURE__ */ jsx(Spinner, { label: "\uD1B5\uACC4\uB97C \uBD88\uB7EC\uC624\uB294 \uC911..." }) });
|
|
79
179
|
}
|
|
80
180
|
if (status === "error") {
|
|
81
|
-
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: /* @__PURE__ */ jsxs(Alert, { variant: "error", children: [
|
|
181
|
+
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", paddingY: 1, children: /* @__PURE__ */ jsxs(Alert, { variant: "error", children: [
|
|
82
182
|
"\uD1B5\uACC4\uB97C \uBD88\uB7EC\uC62C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ",
|
|
83
183
|
error
|
|
84
184
|
] }) });
|
|
@@ -89,50 +189,209 @@ function StatsView({ handle, onComplete }) {
|
|
|
89
189
|
const tierColorFn = typeof tierColor === "string" ? source_default.hex(tierColor) : tierColor.multiline;
|
|
90
190
|
const nextTierMin = getNextTierMinRating(user.tier);
|
|
91
191
|
const progress = user.tier === 31 ? 100 : calculateTierProgress(user.rating, user.tier);
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
192
|
+
const tierDistData = problemStats ? [
|
|
193
|
+
{
|
|
194
|
+
label: "Bronze",
|
|
195
|
+
value: problemStats.filter((s) => s.level >= 1 && s.level <= 5).reduce((a, b) => a + b.solved, 0),
|
|
196
|
+
color: TIER_COLORS[3]
|
|
197
|
+
// Bronze III
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
label: "Silver",
|
|
201
|
+
value: problemStats.filter((s) => s.level >= 6 && s.level <= 10).reduce((a, b) => a + b.solved, 0),
|
|
202
|
+
color: TIER_COLORS[8]
|
|
203
|
+
// Silver III
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
label: "Gold",
|
|
207
|
+
value: problemStats.filter((s) => s.level >= 11 && s.level <= 15).reduce((a, b) => a + b.solved, 0),
|
|
208
|
+
color: TIER_COLORS[13]
|
|
209
|
+
// Gold III
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
label: "Platinum",
|
|
213
|
+
value: problemStats.filter((s) => s.level >= 16 && s.level <= 20).reduce((a, b) => a + b.solved, 0),
|
|
214
|
+
color: TIER_COLORS[18]
|
|
215
|
+
// Platinum III
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
label: "Diamond",
|
|
219
|
+
value: problemStats.filter((s) => s.level >= 21 && s.level <= 25).reduce((a, b) => a + b.solved, 0),
|
|
220
|
+
color: TIER_COLORS[23]
|
|
221
|
+
// Diamond III
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
label: "Ruby",
|
|
225
|
+
value: problemStats.filter((s) => s.level >= 26 && s.level <= 30).reduce((a, b) => a + b.solved, 0),
|
|
226
|
+
color: TIER_COLORS[28]
|
|
227
|
+
// Ruby III
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
label: "Master",
|
|
231
|
+
value: problemStats.filter((s) => s.level === 31).reduce((a, b) => a + b.solved, 0),
|
|
232
|
+
color: TIER_COLORS[31]
|
|
233
|
+
// Master
|
|
234
|
+
}
|
|
235
|
+
].filter((d) => d.value > 0) : [];
|
|
236
|
+
const tagChartData = tagRatings ? tagRatings.sort((a, b) => b.rating - a.rating).slice(0, 8).map((tr) => ({
|
|
237
|
+
label: tr.tag.displayNames.find((dn) => dn.language === "ko")?.name || tr.tag.key,
|
|
238
|
+
value: tr.rating
|
|
239
|
+
})) : [];
|
|
240
|
+
const bojSummaryData = bojStats ? [
|
|
241
|
+
{ label: "\uC815\uB2F5", value: bojStats.accepted, color: "green" },
|
|
242
|
+
{ label: "\uC624\uB2F5", value: bojStats.wrong, color: "red" },
|
|
243
|
+
{
|
|
244
|
+
label: "TLE/MLE",
|
|
245
|
+
value: bojStats.timeout + bojStats.memory,
|
|
246
|
+
color: "yellow"
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
label: "\uAE30\uD0C0",
|
|
250
|
+
value: bojStats.runtimeError + bojStats.compileError,
|
|
251
|
+
color: "gray"
|
|
252
|
+
}
|
|
253
|
+
].filter((d) => d.value > 0) : [];
|
|
254
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 1, children: [
|
|
104
255
|
/* @__PURE__ */ jsx(
|
|
256
|
+
Box,
|
|
257
|
+
{
|
|
258
|
+
flexDirection: "row",
|
|
259
|
+
justifyContent: "space-between",
|
|
260
|
+
alignItems: "flex-end",
|
|
261
|
+
children: /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
262
|
+
/* @__PURE__ */ jsxs(Text, { bold: true, children: [
|
|
263
|
+
icons.user,
|
|
264
|
+
" ",
|
|
265
|
+
source_default.cyan(user.handle)
|
|
266
|
+
] }),
|
|
267
|
+
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
268
|
+
"https://solved.ac/profile/",
|
|
269
|
+
user.handle
|
|
270
|
+
] })
|
|
271
|
+
] })
|
|
272
|
+
}
|
|
273
|
+
),
|
|
274
|
+
/* @__PURE__ */ jsxs(
|
|
105
275
|
Box,
|
|
106
276
|
{
|
|
107
277
|
flexDirection: "column",
|
|
108
278
|
borderStyle: "round",
|
|
109
279
|
borderColor: "gray",
|
|
110
|
-
|
|
111
|
-
children:
|
|
280
|
+
paddingX: 1,
|
|
281
|
+
children: [
|
|
282
|
+
/* @__PURE__ */ jsxs(Box, { justifyContent: "space-between", marginBottom: 1, children: [
|
|
283
|
+
/* @__PURE__ */ jsxs(Box, { gap: 1, children: [
|
|
284
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: tierColorFn(tierName) }),
|
|
285
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: tierColorFn(user.rating.toLocaleString()) }),
|
|
286
|
+
nextTierMin !== null && /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
|
|
287
|
+
" / ",
|
|
288
|
+
nextTierMin.toLocaleString()
|
|
289
|
+
] })
|
|
290
|
+
] }),
|
|
291
|
+
/* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
|
|
292
|
+
icons.trophy,
|
|
293
|
+
" Rank #",
|
|
294
|
+
user.rank.toLocaleString()
|
|
295
|
+
] })
|
|
296
|
+
] }),
|
|
297
|
+
/* @__PURE__ */ jsx(
|
|
298
|
+
StackedBarChart,
|
|
299
|
+
{
|
|
300
|
+
data: [
|
|
301
|
+
{
|
|
302
|
+
label: "Progress",
|
|
303
|
+
value: progress,
|
|
304
|
+
color: typeof tierColor === "string" ? tierColor : "#ff7ca8"
|
|
305
|
+
},
|
|
306
|
+
...progress < 100 ? [{ label: "Remaining", value: 100 - progress, color: "#333" }] : []
|
|
307
|
+
],
|
|
308
|
+
showLabels: false,
|
|
309
|
+
showValues: false,
|
|
310
|
+
width: "full"
|
|
311
|
+
}
|
|
312
|
+
)
|
|
313
|
+
]
|
|
314
|
+
}
|
|
315
|
+
),
|
|
316
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
|
|
317
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [
|
|
318
|
+
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "[ \uC0C1\uC138 \uD1B5\uACC4 ]" }) }),
|
|
319
|
+
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", gap: 0, children: [
|
|
112
320
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
113
321
|
"\uD574\uACB0\uD55C \uBB38\uC81C:",
|
|
114
322
|
" ",
|
|
115
323
|
/* @__PURE__ */ jsx(Text, { bold: true, color: "green", children: user.solvedCount.toLocaleString() }),
|
|
324
|
+
" ",
|
|
116
325
|
"\uAC1C"
|
|
117
326
|
] }),
|
|
327
|
+
localSolvedCount !== null && /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
328
|
+
" ",
|
|
329
|
+
"\u2514 \uB85C\uCEEC \uAD00\uB9AC: ",
|
|
330
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: localSolvedCount }),
|
|
331
|
+
" \uAC1C"
|
|
332
|
+
] }),
|
|
118
333
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
119
|
-
"\uD074\uB798\uC2A4:
|
|
120
|
-
|
|
334
|
+
"\uD074\uB798\uC2A4:",
|
|
335
|
+
" ",
|
|
336
|
+
/* @__PURE__ */ jsxs(Text, { bold: true, color: "magenta", children: [
|
|
337
|
+
user.class,
|
|
338
|
+
user.classDecoration === "gold" ? "++" : user.classDecoration === "silver" ? "+" : ""
|
|
339
|
+
] })
|
|
121
340
|
] }),
|
|
122
|
-
|
|
123
|
-
"\uCD5C\uB300 \
|
|
341
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
342
|
+
"\uCD5C\uB300 \uC2A4\uD2B8\uB9AD:",
|
|
343
|
+
" ",
|
|
344
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "orange", children: user.maxStreak }),
|
|
124
345
|
" ",
|
|
125
|
-
/* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: user.maxStreak }),
|
|
126
346
|
"\uC77C"
|
|
127
347
|
] }),
|
|
128
348
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
129
|
-
"\
|
|
130
|
-
|
|
131
|
-
"
|
|
349
|
+
"\uAE30\uC5EC \uD69F\uC218:",
|
|
350
|
+
" ",
|
|
351
|
+
/* @__PURE__ */ jsx(Text, { bold: true, color: "blue", children: user.voteCount }),
|
|
352
|
+
" ",
|
|
353
|
+
"\uD68C"
|
|
132
354
|
] })
|
|
355
|
+
] }),
|
|
356
|
+
bojSummaryData.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
357
|
+
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "[ \uBC31\uC900 \uC81C\uCD9C \uC694\uC57D ]" }) }),
|
|
358
|
+
/* @__PURE__ */ jsx(
|
|
359
|
+
StackedBarChart,
|
|
360
|
+
{
|
|
361
|
+
data: bojSummaryData,
|
|
362
|
+
mode: "absolute",
|
|
363
|
+
width: 30
|
|
364
|
+
}
|
|
365
|
+
)
|
|
133
366
|
] })
|
|
134
|
-
}
|
|
135
|
-
|
|
367
|
+
] }),
|
|
368
|
+
tagChartData.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: 40, children: [
|
|
369
|
+
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "[ \uC54C\uACE0\uB9AC\uC998 \uAC15\uC810 (Tag Rating) ]" }) }),
|
|
370
|
+
/* @__PURE__ */ jsx(
|
|
371
|
+
BarChart,
|
|
372
|
+
{
|
|
373
|
+
data: tagChartData,
|
|
374
|
+
showValue: "right",
|
|
375
|
+
barChar: "\u2588",
|
|
376
|
+
color: "cyan"
|
|
377
|
+
}
|
|
378
|
+
)
|
|
379
|
+
] })
|
|
380
|
+
] }),
|
|
381
|
+
tierDistData.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
382
|
+
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "[ \uD2F0\uC5B4\uBCC4 \uD574\uACB0 \uBB38\uC81C \uBD84\uD3EC ]" }) }),
|
|
383
|
+
/* @__PURE__ */ jsx(StackedBarChart, { data: tierDistData, width: "full" })
|
|
384
|
+
] }),
|
|
385
|
+
top100 && top100.length > 0 && /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
386
|
+
/* @__PURE__ */ jsx(Box, { marginBottom: 1, children: /* @__PURE__ */ jsx(Text, { bold: true, color: "cyan", children: "[ \uC0C1\uC704 100\uBB38\uC81C \uBD84\uD3EC ]" }) }),
|
|
387
|
+
/* @__PURE__ */ jsx(Box, { flexDirection: "column", children: Array.from({ length: Math.ceil(top100.length / 20) }).map(
|
|
388
|
+
(_, rowIndex) => /* @__PURE__ */ jsx(Box, { flexDirection: "row", children: top100.slice(rowIndex * 20, (rowIndex + 1) * 20).map((p, colIndex) => {
|
|
389
|
+
const tierColor2 = getTierColor(p.level);
|
|
390
|
+
const tierColorFn2 = typeof tierColor2 === "string" ? source_default.hex(tierColor2) : tierColor2.multiline;
|
|
391
|
+
return /* @__PURE__ */ jsx(Box, { width: 3, children: /* @__PURE__ */ jsx(Text, { children: tierColorFn2(getTierShortName(p.level)) }) }, colIndex);
|
|
392
|
+
}) }, rowIndex)
|
|
393
|
+
) })
|
|
394
|
+
] })
|
|
136
395
|
] });
|
|
137
396
|
}
|
|
138
397
|
return null;
|
|
@@ -144,17 +403,15 @@ var StatsCommand = class extends Command {
|
|
|
144
403
|
handle = getSolvedAcHandle();
|
|
145
404
|
}
|
|
146
405
|
if (!handle) {
|
|
147
|
-
|
|
148
|
-
console.
|
|
149
|
-
console.error(`\uB3C4\uC6C0\uB9D0: ps stats --help`);
|
|
150
|
-
console.error(
|
|
151
|
-
`\uD78C\uD2B8: \uC124\uC815\uC5D0 \uD578\uB4E4\uC744 \uC800\uC7A5\uD558\uBA74 \uB9E4\uBC88 \uC785\uB825\uD560 \uD544\uC694\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.`
|
|
152
|
-
);
|
|
406
|
+
logger.error("Solved.ac \uD578\uB4E4\uC744 \uC785\uB825\uD574\uC8FC\uC138\uC694.");
|
|
407
|
+
console.log(`\uB3C4\uC6C0\uB9D0: ps stats --help`);
|
|
153
408
|
process.exit(1);
|
|
154
409
|
return;
|
|
155
410
|
}
|
|
411
|
+
const showLocalStats = !args[0] && !flags.handle;
|
|
156
412
|
await this.renderView(StatsView, {
|
|
157
|
-
handle
|
|
413
|
+
handle,
|
|
414
|
+
showLocalStats
|
|
158
415
|
});
|
|
159
416
|
}
|
|
160
417
|
};
|
|
@@ -163,16 +420,8 @@ StatsCommand = __decorateClass([
|
|
|
163
420
|
name: "stats",
|
|
164
421
|
description: `Solved.ac\uC5D0\uC11C \uC0AC\uC6A9\uC790 \uD1B5\uACC4\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4.
|
|
165
422
|
- \uD2F0\uC5B4, \uB808\uC774\uD305, \uD574\uACB0\uD55C \uBB38\uC81C \uC218 \uB4F1 \uD45C\uC2DC
|
|
166
|
-
- \
|
|
167
|
-
flags:
|
|
168
|
-
{
|
|
169
|
-
name: "handle",
|
|
170
|
-
options: {
|
|
171
|
-
shortFlag: "h",
|
|
172
|
-
description: "Solved.ac \uD578\uB4E4 (\uC124\uC815\uC5D0 \uC800\uC7A5\uB41C \uAC12 \uC0AC\uC6A9 \uAC00\uB2A5)"
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
],
|
|
423
|
+
- \uAE30\uBCF8 Solved.ac \uD578\uB4E4\uC740 ps config\uC5D0\uC11C \uC124\uC815 \uAC00\uB2A5\uD569\uB2C8\uB2E4.`,
|
|
424
|
+
flags: defineFlags(statsFlagsSchema),
|
|
176
425
|
autoDetectProblemId: false,
|
|
177
426
|
examples: ["stats myhandle", "stats --handle myhandle"]
|
|
178
427
|
})
|