poi-plugin-gimmick-tracker 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/index.js +157 -70
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -28,6 +28,8 @@ P2点空优1次
|
|
|
28
28
|
|
|
29
29
|
导入时逐行报告识别结果,无法识别的行会明确指出,不会静默丢弃。条件可删除,重复导入按签名更新次数。
|
|
30
30
|
|
|
31
|
+
解析器对攻略写法尽量鲁棒:中文数字(两次/一回)、省略「胜/点/次」(`P3点A2次`)、乘号计数(`S×2`)、词序变体(`G点2次S胜`、`到达E2点2次`)、`boss/王点/斩杀` 等装饰词、大小写混排、全角字符、繁体(點/勝/達)、一行挤多条。`击破` 按 A 胜理解;`P1boss一次` 这类无字母点的 boss 简写按「P1点击破 A胜」理解并在报告里提示。
|
|
32
|
+
|
|
31
33
|
## 数据与隐私
|
|
32
34
|
|
|
33
35
|
- 状态按成员分文件保存在 `<poi AppData>/gimmick-tracker/<memberId>/state-v2.json`,临时文件加 rename 原子写。
|
package/index.js
CHANGED
|
@@ -62,96 +62,180 @@ function matchesCondition(condition, observation) {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
// src/parser.js
|
|
65
|
-
var
|
|
65
|
+
var AIR_ALIAS = {
|
|
66
|
+
\u7A7A\u786E: 1,
|
|
67
|
+
\u7A7A\u78BA: 1,
|
|
68
|
+
\u5236\u7A7A\u786E\u4FDD: 1,
|
|
69
|
+
\u5236\u7A7A\u78BA\u4FDD: 1,
|
|
70
|
+
\u5236\u7A7A\u6743\u786E\u4FDD: 1,
|
|
71
|
+
\u5236\u7A7A\u6B0A\u78BA\u4FDD: 1,
|
|
72
|
+
\u7A7A\u512A: 2,
|
|
73
|
+
\u7A7A\u4F18: 2,
|
|
74
|
+
\u822A\u7A7A\u512A\u52E2: 2,
|
|
75
|
+
\u822A\u7A7A\u4F18\u52BF: 2,
|
|
76
|
+
\u7A7A\u5747: 3,
|
|
77
|
+
\u7A7A\u5747\u8861: 3,
|
|
78
|
+
\u7A7A\u52A3: 4
|
|
79
|
+
};
|
|
66
80
|
var AIR_STATE_TO_TEXT = { 1: "\u7A7A\u786E", 2: "\u7A7A\u4F18", 3: "\u7A7A\u5747", 4: "\u7A7A\u52A3" };
|
|
81
|
+
var CHINESE_DIGIT = { \u4E00: 1, \u4E24: 2, \u4E8C: 2, \u4E09: 3, \u56DB: 4, \u4E94: 5, \u516D: 6, \u4E03: 7, \u516B: 8, \u4E5D: 9, \u5341: 10 };
|
|
67
82
|
var NODE = "([A-Za-z]{1,2}\\d{0,2})";
|
|
68
|
-
var
|
|
69
|
-
var
|
|
70
|
-
var
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
83
|
+
var DIAN = "[\u70B9\u70B9\u9EDE]?";
|
|
84
|
+
var CNT = "(\\d+|[\u4E00\u4E24\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D\u5341])";
|
|
85
|
+
var CNT_UNIT = "[\u6B21\u56DE\u51F8]?";
|
|
86
|
+
var RANKC = "(SS|S|A|B|C|D|E)";
|
|
87
|
+
var AIR = "(\u7A7A\u786E|\u7A7A\u512A|\u7A7A\u4F18|\u7A7A\u5747|\u7A7A\u52A3|\u5236\u7A7A\u786E\u4FDD|\u5236\u7A7A\u78BA\u4FDD|\u5236\u7A7A\u6743\u786E\u4FDD|\u5236\u7A7A\u6B0A\u78BA\u4FDD|\u822A\u7A7A\u512A\u52E2|\u822A\u7A7A\u4F18\u52BF)";
|
|
88
|
+
var WIN = "[\u80DC\u52DD]?";
|
|
89
|
+
var KILL = "[\u51FB\u64CA]\u7834";
|
|
90
|
+
var REACH = "\u5230[\u8FBE\u9054]";
|
|
91
|
+
var FORMS = [
|
|
92
|
+
{ kind: "base-air-defense", re: new RegExp(`(\u5B88\u5BB6|\u57FA\u5730\u9632\u7A7A\u6218|\u57FA\u5730\u9632\u7A7A|\u5BB6\u91CC|\u9632\u7A7A|\u57FA\u5730)${AIR}${CNT}${CNT_UNIT}`, "i") },
|
|
93
|
+
{ kind: "reach-after", re: new RegExp(`${REACH}${NODE}${DIAN}${CNT}${CNT_UNIT}`, "i") },
|
|
94
|
+
{ kind: "node-arrival", re: new RegExp(`${NODE}${DIAN}${REACH}${CNT}${CNT_UNIT}`, "i") },
|
|
95
|
+
{ kind: "kill", re: new RegExp(`${NODE}${DIAN}${KILL}${CNT}${CNT_UNIT}`, "i") },
|
|
96
|
+
{ kind: "victory-rank", re: new RegExp(`${NODE}${DIAN}${RANKC}${WIN}${CNT}${CNT_UNIT}`, "i") },
|
|
97
|
+
{ kind: "count-first", re: new RegExp(`${NODE}${DIAN}${CNT}${CNT_UNIT}${RANKC}${WIN}`, "i") },
|
|
98
|
+
{ kind: "node-air-state", re: new RegExp(`${NODE}${DIAN}${AIR}${CNT}${CNT_UNIT}`, "i") }
|
|
75
99
|
];
|
|
100
|
+
var DECORATION = /(boss|王点|王點|門神|门神|斬殺|斩杀|斬殺線|斩杀线)/gi;
|
|
76
101
|
function normalizeNodeLabel(value) {
|
|
77
102
|
return String(value ?? "").trim().toUpperCase();
|
|
78
103
|
}
|
|
104
|
+
function toHalfWidth(text) {
|
|
105
|
+
let out = "";
|
|
106
|
+
for (const ch of text) {
|
|
107
|
+
const code = ch.codePointAt(0);
|
|
108
|
+
if (code >= 65281 && code <= 65374) out += String.fromCharCode(code - 65248);
|
|
109
|
+
else if (ch === "\u3000") out += " ";
|
|
110
|
+
else out += ch;
|
|
111
|
+
}
|
|
112
|
+
return out;
|
|
113
|
+
}
|
|
114
|
+
function chineseCountToNumber(count) {
|
|
115
|
+
return CHINESE_DIGIT[count] ?? Number(count);
|
|
116
|
+
}
|
|
79
117
|
function stripAnnotation(text) {
|
|
80
118
|
const notes = [];
|
|
81
|
-
const cleaned = String(text ?? "").replace(
|
|
82
|
-
const note = (
|
|
119
|
+
const cleaned = String(text ?? "").replace(/[((【〔「]([^()()【】〔〕「」]*)[))】〕」]/g, (_m, inner) => {
|
|
120
|
+
const note = String(inner ?? "").trim();
|
|
83
121
|
if (note !== "") notes.push(note);
|
|
84
122
|
return "";
|
|
85
123
|
});
|
|
86
124
|
return { cleaned: cleaned.trim(), notes };
|
|
87
125
|
}
|
|
88
|
-
function
|
|
89
|
-
|
|
90
|
-
|
|
126
|
+
function airStateOf(word) {
|
|
127
|
+
return AIR_ALIAS[word];
|
|
128
|
+
}
|
|
129
|
+
function parseSegmentBody(segment) {
|
|
91
130
|
const { cleaned, notes } = stripAnnotation(segment);
|
|
92
|
-
|
|
93
|
-
if (text === "") {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
131
|
+
let text = toHalfWidth(cleaned).replace(DECORATION, "").replace(/[×✕**]/g, "").replace(/\s+/g, "");
|
|
132
|
+
if (text === "") return { matches: null, notes };
|
|
133
|
+
const bossSeen = /boss/i.test(segment) || /boss/i.test(text);
|
|
134
|
+
text = text.replace(/([一两二三四五六七八九十])(?=[次回凸]|$)/g, (m) => String(CHINESE_DIGIT[m]));
|
|
135
|
+
const matches = [];
|
|
136
|
+
let rest = text;
|
|
137
|
+
let guard = 0;
|
|
138
|
+
while (rest.length > 0 && guard < 20) {
|
|
139
|
+
guard += 1;
|
|
140
|
+
let matched = null;
|
|
141
|
+
for (const form2 of FORMS) {
|
|
142
|
+
const m2 = form2.re.exec(rest);
|
|
143
|
+
if (m2 != null && (matched == null || m2.index < matched.m.index)) {
|
|
144
|
+
matched = { form: form2, m: m2 };
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (matched == null && bossSeen) {
|
|
148
|
+
const bare = new RegExp(`^${NODE}${DIAN}${CNT}${CNT_UNIT}`, "i").exec(rest);
|
|
149
|
+
if (bare != null) {
|
|
150
|
+
matches.push({
|
|
151
|
+
ok: true,
|
|
152
|
+
condition: {
|
|
153
|
+
kind: "victory-rank",
|
|
154
|
+
nodeLabel: normalizeNodeLabel(bare[1]),
|
|
155
|
+
requiredRank: "A",
|
|
156
|
+
requiredCount: chineseCountToNumber(bare[2]),
|
|
157
|
+
notes: [...notes, "boss\u2192\u6309\u51FB\u7834(A\u80DC)\u8BA1"]
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
rest = rest.slice(bare[0].length);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
if (matched == null) break;
|
|
166
|
+
const { form, m } = matched;
|
|
167
|
+
const count = chineseCountToNumber(form.kind === "count-first" ? m[2] : m[m.length - 1]);
|
|
168
|
+
if (!Number.isInteger(count) || count <= 0) return { matches: [{ ok: false, reason: "\u6B21\u6570\u5FC5\u987B\u662F\u6B63\u6574\u6570" }], notes };
|
|
169
|
+
if (form.kind === "base-air-defense") {
|
|
170
|
+
const airState = airStateOf(m[2]);
|
|
171
|
+
if (airState == null) return { matches: [{ ok: false, reason: `\u672A\u77E5\u5236\u7A7A\u8BCD\u300C${m[2]}\u300D` }], notes };
|
|
172
|
+
matches.push({
|
|
173
|
+
ok: true,
|
|
174
|
+
condition: { kind: "base-air-defense", requiredAirState: airState, requiredCount: count, notes }
|
|
175
|
+
});
|
|
176
|
+
} else if (form.kind === "node-arrival" || form.kind === "reach-after") {
|
|
177
|
+
matches.push({
|
|
101
178
|
ok: true,
|
|
102
|
-
raw: segment,
|
|
103
179
|
condition: {
|
|
104
180
|
kind: "node-arrival",
|
|
105
|
-
nodeLabel: normalizeNodeLabel(
|
|
106
|
-
requiredCount:
|
|
181
|
+
nodeLabel: normalizeNodeLabel(m[1]),
|
|
182
|
+
requiredCount: count,
|
|
107
183
|
notes
|
|
108
184
|
}
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return {
|
|
185
|
+
});
|
|
186
|
+
} else if (form.kind === "kill") {
|
|
187
|
+
matches.push({
|
|
113
188
|
ok: true,
|
|
114
|
-
raw: segment,
|
|
115
189
|
condition: {
|
|
116
190
|
kind: "victory-rank",
|
|
117
|
-
nodeLabel: normalizeNodeLabel(
|
|
118
|
-
requiredRank:
|
|
119
|
-
requiredCount:
|
|
191
|
+
nodeLabel: normalizeNodeLabel(m[1]),
|
|
192
|
+
requiredRank: "A",
|
|
193
|
+
requiredCount: count,
|
|
194
|
+
notes: [...notes, "\u51FB\u7834\u2192\u6309A\u80DC\u8BA1"]
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
} else if (form.kind === "victory-rank") {
|
|
198
|
+
matches.push({
|
|
199
|
+
ok: true,
|
|
200
|
+
condition: {
|
|
201
|
+
kind: "victory-rank",
|
|
202
|
+
nodeLabel: normalizeNodeLabel(m[1]),
|
|
203
|
+
requiredRank: m[2].toUpperCase(),
|
|
204
|
+
requiredCount: count,
|
|
120
205
|
notes
|
|
121
206
|
}
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
|
|
207
|
+
});
|
|
208
|
+
} else if (form.kind === "count-first") {
|
|
209
|
+
matches.push({
|
|
210
|
+
ok: true,
|
|
211
|
+
condition: {
|
|
212
|
+
kind: "victory-rank",
|
|
213
|
+
nodeLabel: normalizeNodeLabel(m[1]),
|
|
214
|
+
requiredRank: m[3].toUpperCase(),
|
|
215
|
+
requiredCount: count,
|
|
216
|
+
notes
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
} else {
|
|
220
|
+
const airState = airStateOf(m[2]);
|
|
221
|
+
if (airState == null) return { matches: [{ ok: false, reason: `\u672A\u77E5\u5236\u7A7A\u8BCD\u300C${m[2]}\u300D` }], notes };
|
|
222
|
+
matches.push({
|
|
126
223
|
ok: true,
|
|
127
|
-
raw: segment,
|
|
128
224
|
condition: {
|
|
129
225
|
kind: "node-air-state",
|
|
130
|
-
nodeLabel: normalizeNodeLabel(
|
|
131
|
-
requiredAirState:
|
|
132
|
-
requiredCount:
|
|
226
|
+
nodeLabel: normalizeNodeLabel(m[1]),
|
|
227
|
+
requiredAirState: airState,
|
|
228
|
+
requiredCount: count,
|
|
133
229
|
notes
|
|
134
230
|
}
|
|
135
|
-
};
|
|
231
|
+
});
|
|
136
232
|
}
|
|
137
|
-
|
|
138
|
-
ok: true,
|
|
139
|
-
raw: segment,
|
|
140
|
-
condition: {
|
|
141
|
-
kind: "base-air-defense",
|
|
142
|
-
requiredAirState: AIR_TEXT_TO_STATE[match[2]],
|
|
143
|
-
requiredCount: Number(match[3]),
|
|
144
|
-
notes
|
|
145
|
-
}
|
|
146
|
-
};
|
|
233
|
+
rest = rest.slice(m.index + m[0].length);
|
|
147
234
|
}
|
|
148
|
-
return {
|
|
235
|
+
return { matches, notes, bossSeen };
|
|
149
236
|
}
|
|
150
237
|
var BUCKET_HEADER = /^(解谜|解密|谜题|削甲|装甲|debuff|gimmick)[::]/;
|
|
151
238
|
var BUCKET_WORDS = { \u89E3\u8C1C: "gimmick", \u89E3\u5BC6: "gimmick", \u8C1C\u9898: "gimmick", gimmick: "gimmick", \u524A\u7532: "debuff", \u88C5\u7532: "debuff", debuff: "debuff" };
|
|
152
|
-
function bucketOf(word) {
|
|
153
|
-
return BUCKET_WORDS[word] ?? null;
|
|
154
|
-
}
|
|
155
239
|
function parseGuideText(text, bucketDefault = "debuff") {
|
|
156
240
|
const report = [];
|
|
157
241
|
const conditions = [];
|
|
@@ -161,27 +245,30 @@ function parseGuideText(text, bucketDefault = "debuff") {
|
|
|
161
245
|
let work = segment;
|
|
162
246
|
const header = BUCKET_HEADER.exec(work.replace(/\s+/g, ""));
|
|
163
247
|
if (header != null) {
|
|
164
|
-
bucket =
|
|
248
|
+
bucket = BUCKET_WORDS[header[1]] ?? bucket;
|
|
165
249
|
work = work.replace(/^\s*[^::]*[::]\s*/, "");
|
|
166
250
|
if (work === "") {
|
|
167
251
|
report.push({ ok: true, raw: segment, header: true, bucket });
|
|
168
252
|
continue;
|
|
169
253
|
}
|
|
170
254
|
}
|
|
171
|
-
const
|
|
172
|
-
if (
|
|
173
|
-
if (!
|
|
174
|
-
|
|
255
|
+
const { matches } = parseSegmentBody(work);
|
|
256
|
+
if (matches == null) continue;
|
|
257
|
+
if (matches.length === 0 || matches.some((match) => !match.ok)) {
|
|
258
|
+
const failure = matches.find((match) => !match.ok);
|
|
259
|
+
report.push({
|
|
260
|
+
ok: false,
|
|
261
|
+
raw: segment,
|
|
262
|
+
reason: failure?.reason ?? "\u672A\u8BC6\u522B\u7684\u5199\u6CD5\uFF08\u793A\u4F8B\uFF1AY2\u70B9S\u80DC1\u6B21 / P3\u70B9A2\u6B21 / \u5B88\u5BB6\u7A7A\u4F183\u6B21\uFF09"
|
|
263
|
+
});
|
|
175
264
|
continue;
|
|
176
265
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
266
|
+
for (const match of matches) {
|
|
267
|
+
match.condition.bucket = bucket;
|
|
268
|
+
match.condition.raw = segment;
|
|
269
|
+
conditions.push(match.condition);
|
|
270
|
+
report.push({ ok: true, raw: segment, condition: match.condition, multiple: matches.length > 1 });
|
|
180
271
|
}
|
|
181
|
-
parsed.condition.bucket = bucket;
|
|
182
|
-
parsed.condition.raw = parsed.raw;
|
|
183
|
-
conditions.push(parsed.condition);
|
|
184
|
-
report.push({ ok: true, raw: parsed.raw, condition: parsed.condition });
|
|
185
272
|
}
|
|
186
273
|
return { conditions, report };
|
|
187
274
|
}
|
|
@@ -1314,9 +1401,9 @@ function createLedgerView(controller2) {
|
|
|
1314
1401
|
rows: 4,
|
|
1315
1402
|
value: guideText,
|
|
1316
1403
|
onChange: (event) => setGuideText(event.currentTarget.value),
|
|
1317
|
-
placeholder: "\
|
|
1404
|
+
placeholder: "\u4F8B\u5982\uFF1AY2\u70B9S\u80DC1\u6B21 / L2\u70B9A\u80DC1\u6B21 / P3\u70B9A2\u6B21 / C2\u70B9\u5230\u8FBE1\u6B21 / P2\u70B9\u7A7A\u4F181\u6B21 / \u5B88\u5BB6\u7A7A\u4F183\u6B21\n\u4E5F\u8BA4\uFF1AP1boss\u4E00\u6B21 / \u5B88\u5BB6\u7A7A\u4F18\u4E24\u6B21 / G\u70B92\u6B21S\u80DC / S\u70B9\u51FB\u78342\u56DE / \uFF30\uFF12\u70B9\u7A7A\u512A\uFF11\u6B21\n\u53EF\u5E26\u6CE8\u8BB0\u4E0E\u5206\u7EC4\u884C\uFF1AG\u70B9\uFF08P1boss\uFF09S\u80DC1\u6B21\u3001\u89E3\u8C1C\uFF1A \u6216 \u524A\u7532\uFF1A"
|
|
1318
1405
|
}
|
|
1319
|
-
), /* @__PURE__ */ import_react.default.createElement("div", { style: styles.actions }, /* @__PURE__ */ import_react.default.createElement(import_core.HTMLSelect, { value: bucket, onChange: (event) => setBucket(event.currentTarget.value) }, /* @__PURE__ */ import_react.default.createElement("option", { value: "debuff" }, "\u5BFC\u5165\u4E3A\u524A\u7532\u6761\u4EF6"), /* @__PURE__ */ import_react.default.createElement("option", { value: "gimmick" }, "\u5BFC\u5165\u4E3A\u89E3\u8C1C\u6761\u4EF6")), /* @__PURE__ */ import_react.default.createElement(import_core.Button, { intent: "primary", onClick: importGuide, disabled: mapRef == null }, "\u5BFC\u5165\u5230\u5F53\u524D\u6D77\u57DF", mapRef != null ? ` ${mapLabel(mapRef)}` : ""), mapRef == null && /* @__PURE__ */ import_react.default.createElement("span", { style: styles.muted }, "\u7B49\u5F85\u6D77\u57DF\u8BC6\u522B\u2026")), report != null && /* @__PURE__ */ import_react.default.createElement("div", { style: { marginTop: 8 } }, report.error != null ? /* @__PURE__ */ import_react.default.createElement(import_core.Callout, { intent: "danger" }, report.error) : /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("div", { style: { marginBottom: 4 } }, /* @__PURE__ */ import_react.default.createElement("strong", null, report.mapLabel), "\uFF1A\u8BC6\u522B ", report.importedCount, " \u6761\u3002"), report.report.map((line, index) => /* @__PURE__ */ import_react.default.createElement("div", { key: index, style: { ...styles.reportLine, color: line.ok ? void 0 : "#cd4a3e" } }, line.header ? "\u2699" : line.ok ? "\u2714" : "\u2718", " ", line.raw, line.header ? ` \u2192 \u5206\u7EC4\uFF1A${BUCKETS[line.bucket]}` : "", !line.ok && line.reason != null ? ` \u2014 ${line.reason}` : ""))))), mapState != null && closedRounds.length > 0 && /* @__PURE__ */ import_react.default.createElement(import_core.Card, { style: styles.section, elevation: import_core.Elevation.ZERO }, /* @__PURE__ */ import_react.default.createElement("h3", { style: { marginTop: 0 } }, mapLabel(mapState), " \xB7 \u5386\u53F2\u8F6E\u6B21"), closedRounds.map((round) => /* @__PURE__ */ import_react.default.createElement(RoundSummary, { key: round.id, round, mapState }))), otherMaps.length > 0 && /* @__PURE__ */ import_react.default.createElement(import_core.Card, { style: styles.section, elevation: import_core.Elevation.ZERO }, /* @__PURE__ */ import_react.default.createElement("h3", { style: { marginTop: 0 } }, "\u5176\u4ED6\u6D77\u57DF"), otherMaps.map((ms) => {
|
|
1406
|
+
), /* @__PURE__ */ import_react.default.createElement("div", { style: styles.actions }, /* @__PURE__ */ import_react.default.createElement(import_core.HTMLSelect, { value: bucket, onChange: (event) => setBucket(event.currentTarget.value) }, /* @__PURE__ */ import_react.default.createElement("option", { value: "debuff" }, "\u5BFC\u5165\u4E3A\u524A\u7532\u6761\u4EF6"), /* @__PURE__ */ import_react.default.createElement("option", { value: "gimmick" }, "\u5BFC\u5165\u4E3A\u89E3\u8C1C\u6761\u4EF6")), /* @__PURE__ */ import_react.default.createElement(import_core.Button, { intent: "primary", onClick: importGuide, disabled: mapRef == null }, "\u5BFC\u5165\u5230\u5F53\u524D\u6D77\u57DF", mapRef != null ? ` ${mapLabel(mapRef)}` : ""), mapRef == null && /* @__PURE__ */ import_react.default.createElement("span", { style: styles.muted }, "\u7B49\u5F85\u6D77\u57DF\u8BC6\u522B\u2026")), report != null && /* @__PURE__ */ import_react.default.createElement("div", { style: { marginTop: 8 } }, report.error != null ? /* @__PURE__ */ import_react.default.createElement(import_core.Callout, { intent: "danger" }, report.error) : /* @__PURE__ */ import_react.default.createElement(import_react.default.Fragment, null, /* @__PURE__ */ import_react.default.createElement("div", { style: { marginBottom: 4 } }, /* @__PURE__ */ import_react.default.createElement("strong", null, report.mapLabel), "\uFF1A\u8BC6\u522B ", report.importedCount, " \u6761\u3002"), report.report.map((line, index) => /* @__PURE__ */ import_react.default.createElement("div", { key: index, style: { ...styles.reportLine, color: line.ok ? void 0 : "#cd4a3e" } }, line.header ? "\u2699" : line.ok ? "\u2714" : "\u2718", " ", line.raw, line.header ? ` \u2192 \u5206\u7EC4\uFF1A${BUCKETS[line.bucket]}` : "", !line.header && line.ok && line.condition != null ? ` \u2192 ${conditionLabel(line.condition)}` : "", !line.ok && line.reason != null ? ` \u2014 ${line.reason}` : ""))))), mapState != null && closedRounds.length > 0 && /* @__PURE__ */ import_react.default.createElement(import_core.Card, { style: styles.section, elevation: import_core.Elevation.ZERO }, /* @__PURE__ */ import_react.default.createElement("h3", { style: { marginTop: 0 } }, mapLabel(mapState), " \xB7 \u5386\u53F2\u8F6E\u6B21"), closedRounds.map((round) => /* @__PURE__ */ import_react.default.createElement(RoundSummary, { key: round.id, round, mapState }))), otherMaps.length > 0 && /* @__PURE__ */ import_react.default.createElement(import_core.Card, { style: styles.section, elevation: import_core.Elevation.ZERO }, /* @__PURE__ */ import_react.default.createElement("h3", { style: { marginTop: 0 } }, "\u5176\u4ED6\u6D77\u57DF"), otherMaps.map((ms) => {
|
|
1320
1407
|
const legacy = ms.rounds.find((round) => round.bucket === "legacy");
|
|
1321
1408
|
const window2 = controller2.legacyWindowFor(ms.mapId);
|
|
1322
1409
|
return /* @__PURE__ */ import_react.default.createElement("div", { key: ms.mapId, style: { padding: "8px 0", borderBottom: "1px solid rgba(128,128,128,.15)" } }, /* @__PURE__ */ import_react.default.createElement("div", { style: { display: "flex", gap: 8, alignItems: "center" } }, /* @__PURE__ */ import_react.default.createElement(import_core.Tag, { minimal: true }, mapLabel(ms)), /* @__PURE__ */ import_react.default.createElement("span", { style: styles.muted }, "\u6761\u4EF6 ", ms.conditions.length, " \xB7 \u8F6E\u6B21 ", ms.rounds.length, ms.cleared ? " \xB7 \u5DF2\u901A\u5173" : "", legacy != null ? " \xB7 \u542B\u65E7\u6570\u636E\u5F52\u6863" : ""), legacy != null && window2 != null && /* @__PURE__ */ import_react.default.createElement(import_core.Button, { small: true, onClick: () => controller2.replayLegacy(ms.mapId, window2.from, window2.to) }, "\u56DE\u653E\u5386\u53F2\u524A\u7532\u4E00\u8F6E")));
|