@nbtca/prompt 1.3.2 → 1.4.2
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/LICENSE +1 -1
- package/README.md +45 -1
- package/SECURITY.md +47 -0
- package/dist/app/app.js +202 -0
- package/dist/app/chrome.js +104 -0
- package/dist/app/fields/list-field.js +174 -0
- package/dist/app/fields/text-field.js +38 -0
- package/dist/app/frame.js +48 -0
- package/dist/app/keys.js +20 -0
- package/dist/app/tabs.js +11 -0
- package/dist/app/view.js +1 -0
- package/dist/app/views/docs-render.js +82 -0
- package/dist/app/views/docs.js +450 -0
- package/dist/app/views/events-render.js +111 -0
- package/dist/app/views/events.js +228 -0
- package/dist/app/views/home.js +195 -0
- package/dist/app/views/schedule-grid-cursor.js +52 -0
- package/dist/app/views/schedule-render.js +317 -0
- package/dist/app/views/schedule.js +463 -0
- package/dist/app/views/settings-render.js +53 -0
- package/dist/app/views/settings.js +153 -0
- package/dist/auth/cookie-transport.js +222 -0
- package/dist/auth/errors.js +18 -0
- package/dist/auth/nbt-auth.js +239 -0
- package/dist/auth/session-store.js +118 -0
- package/dist/config/data.js +1 -2
- package/dist/config/paths.js +22 -2
- package/dist/core/canvas.js +23 -0
- package/dist/core/capabilities.js +42 -0
- package/dist/core/components/confirm.js +75 -0
- package/dist/core/components/input-session.js +24 -0
- package/dist/core/components/menu.js +122 -0
- package/dist/core/components/messages.js +16 -0
- package/dist/core/components/note.js +18 -0
- package/dist/core/components/painter.js +26 -0
- package/dist/core/components/screen.js +18 -0
- package/dist/core/components/spinner.js +47 -0
- package/dist/core/components/text-input.js +98 -0
- package/dist/core/logo.js +33 -22
- package/dist/core/menu.js +24 -9
- package/dist/core/motion.js +86 -0
- package/dist/core/text.js +121 -5
- package/dist/core/theme.js +61 -0
- package/dist/core/transitions.js +19 -0
- package/dist/core/ui.js +4 -45
- package/dist/features/calendar-heatmap.js +29 -27
- package/dist/features/calendar-query.js +50 -0
- package/dist/features/calendar.js +192 -98
- package/dist/features/docs.js +222 -61
- package/dist/features/links.js +7 -7
- package/dist/features/schedule-query.js +47 -0
- package/dist/features/schedule-render.js +573 -0
- package/dist/features/schedule-store.js +73 -0
- package/dist/features/schedule-view.js +253 -0
- package/dist/features/settings.js +43 -35
- package/dist/features/status.js +37 -16
- package/dist/features/student-timetable.js +346 -0
- package/dist/features/theme.js +0 -3
- package/dist/features/update.js +16 -18
- package/dist/i18n/index.js +5 -47
- package/dist/i18n/locales/en.json +149 -6
- package/dist/i18n/locales/zh.json +149 -6
- package/dist/index.js +61 -11
- package/dist/logo/ca-dotmatrix-large.txt +26 -0
- package/dist/logo/ca-dotmatrix-small.txt +12 -0
- package/dist/logo/ca-dotmatrix.txt +18 -16
- package/dist/logo/ca-logo.png +0 -0
- package/dist/main.js +33 -13
- package/package.json +18 -12
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
"error": "Error",
|
|
9
9
|
"success": "Success",
|
|
10
10
|
"goodbye": "Goodbye!",
|
|
11
|
-
"current": "current"
|
|
11
|
+
"current": "current",
|
|
12
|
+
"moreAbove": "{count} more above",
|
|
13
|
+
"moreBelow": "{count} more below"
|
|
12
14
|
},
|
|
13
15
|
"menu": {
|
|
14
16
|
"events": "Events",
|
|
@@ -17,11 +19,16 @@
|
|
|
17
19
|
"docsDesc": "Knowledge base",
|
|
18
20
|
"status": "Status",
|
|
19
21
|
"statusDesc": "Online status",
|
|
22
|
+
"timetable": "My Timetable",
|
|
23
|
+
"timetableDesc": "Sign in to JWXT, choose a term and export ICS",
|
|
20
24
|
"links": "Links",
|
|
21
25
|
"linksDesc": "website · GitHub · roadmap",
|
|
22
26
|
"settings": "Settings",
|
|
23
27
|
"settingsDesc": "language · theme · about",
|
|
24
|
-
"chooseAction": "nbtca"
|
|
28
|
+
"chooseAction": "nbtca",
|
|
29
|
+
"hintMove": "move",
|
|
30
|
+
"hintOpen": "open",
|
|
31
|
+
"hintQuit": "quit"
|
|
25
32
|
},
|
|
26
33
|
"about": {
|
|
27
34
|
"title": "About",
|
|
@@ -58,18 +65,34 @@
|
|
|
58
65
|
"pastEvents": "Past Events",
|
|
59
66
|
"pastEventsDesc": "Recent activity history",
|
|
60
67
|
"noPastEvents": "No past events in the last 30 days",
|
|
61
|
-
"viewPastDetail": "Select an event for details:"
|
|
68
|
+
"viewPastDetail": "Select an event for details:",
|
|
69
|
+
"next": "Next",
|
|
70
|
+
"recentActivity": "Recent",
|
|
71
|
+
"inPrefix": "in",
|
|
72
|
+
"startingNow": "starting now",
|
|
73
|
+
"thisWeek": "This Week",
|
|
74
|
+
"thisMonth": "This Month",
|
|
75
|
+
"search": "Search",
|
|
76
|
+
"searchPrompt": "Search events",
|
|
77
|
+
"searchPlaceholder": "keyword…",
|
|
78
|
+
"searchNoResults": "No matching events",
|
|
79
|
+
"exportIcs": "Export .ics",
|
|
80
|
+
"exportSuccess": "Saved",
|
|
81
|
+
"exportError": "Could not write the .ics file",
|
|
82
|
+
"recurringLabel": "recurring"
|
|
62
83
|
},
|
|
63
84
|
"docs": {
|
|
64
85
|
"loading": "Loading documentation list...",
|
|
65
86
|
"loadingDir": "Loading directory",
|
|
66
|
-
"
|
|
87
|
+
"categoryAbout": "About NBTCA",
|
|
88
|
+
"categoryGuide": "Guide",
|
|
67
89
|
"categoryRepairLogs": "Repair Logs",
|
|
68
90
|
"categoryEvents": "Event Docs",
|
|
69
|
-
"
|
|
91
|
+
"categoryConcepts": "Reference",
|
|
70
92
|
"categoryRepair": "Repair",
|
|
71
93
|
"categoryArchived": "Archived",
|
|
72
94
|
"categoryReadme": "Project README",
|
|
95
|
+
"overviewLabel": "Overview",
|
|
73
96
|
"chooseCategory": "Docs",
|
|
74
97
|
"refreshCache": "Refresh cache",
|
|
75
98
|
"cacheCleared": "Documentation cache cleared",
|
|
@@ -106,7 +129,10 @@
|
|
|
106
129
|
"searching": "Searching documents...",
|
|
107
130
|
"searchResults": "results found",
|
|
108
131
|
"searchNoResults": "No documents match your search",
|
|
109
|
-
"loadingFile": "Loading"
|
|
132
|
+
"loadingFile": "Loading",
|
|
133
|
+
"readerLinksTitle": "Jump to",
|
|
134
|
+
"readerLinksHint": "links",
|
|
135
|
+
"readerNoLinks": "This page has no links to other docs"
|
|
110
136
|
},
|
|
111
137
|
"links": {
|
|
112
138
|
"choose": "Links",
|
|
@@ -150,6 +176,114 @@
|
|
|
150
176
|
"watchJsonConflict": "--watch cannot be used with --json.",
|
|
151
177
|
"intervalNeedsWatch": "--interval requires --watch."
|
|
152
178
|
},
|
|
179
|
+
"timetable": {
|
|
180
|
+
"menuTitle": "My Timetable",
|
|
181
|
+
"actionExport": "Export ICS",
|
|
182
|
+
"actionTerms": "List terms",
|
|
183
|
+
"actionLogin": "Sign in or refresh session",
|
|
184
|
+
"actionLogout": "Sign out",
|
|
185
|
+
"actionStatus": "Login status",
|
|
186
|
+
"termPrompt": "Term code",
|
|
187
|
+
"termPromptHint": "Leave empty for current, for example 2026:3",
|
|
188
|
+
"unknownCommand": "Unknown timetable command. Use login, logout, status, terms, or export.",
|
|
189
|
+
"loggedOut": "Local login session cleared.",
|
|
190
|
+
"savedStatus": "A login session is saved{account}.",
|
|
191
|
+
"noSavedStatus": "No login session is saved.",
|
|
192
|
+
"loginSaved": "Login verified and session saved.",
|
|
193
|
+
"loginOneShot": "Login verified; no session was saved.",
|
|
194
|
+
"loginWillSave": "A local bearer session will be saved after success; use --one-shot to avoid this.",
|
|
195
|
+
"sessionRefreshFailed": "The operation completed, but the saved session expiry could not be refreshed.",
|
|
196
|
+
"candidateTerms": "Candidate JWXT terms (not every term necessarily has a personal timetable):",
|
|
197
|
+
"semesterNumber": "Semester {number}",
|
|
198
|
+
"expiredRelogin": "The saved login session expired. Please sign in again.",
|
|
199
|
+
"studentId": "Student id",
|
|
200
|
+
"studentIdHint": "Sent only to the school authentication service",
|
|
201
|
+
"password": "Password",
|
|
202
|
+
"passwordHint": "Input is masked and never saved",
|
|
203
|
+
"weekOne": "First teaching Monday (YYYY-MM-DD)",
|
|
204
|
+
"weekOneHint": "JWXT returned no start date; confirm it against the official calendar",
|
|
205
|
+
"exported": "Exported {count} timetable meetings to {file}",
|
|
206
|
+
"warnings": "{count} record(s) could not be fully resolved; verify the imported calendar.",
|
|
207
|
+
"unresolvedPractice": "{count} practice record(s) lacked a confirmed weekday/period and were not added to the ICS.",
|
|
208
|
+
"calendarName": "{year} {semester} Timetable",
|
|
209
|
+
"invalidOption": "Option {flag} is not valid for this timetable command.",
|
|
210
|
+
"invalidArguments": "Too many timetable arguments. Use login, logout, status, terms, or export.",
|
|
211
|
+
"noSession": "No usable login session. Run `nbtca schedule login` in an interactive terminal.",
|
|
212
|
+
"invalidCredentials": "The student id or password was rejected.",
|
|
213
|
+
"accountLocked": "The account is temporarily locked. Try later or use the official school page.",
|
|
214
|
+
"accountInactive": "The account is inactive. Activate it on the official school page first.",
|
|
215
|
+
"challenge": "The school requires a slider or browser challenge; CLI login stopped safely.",
|
|
216
|
+
"sessionExpired": "The login session expired. Please sign in again.",
|
|
217
|
+
"timeout": "The school service timed out.",
|
|
218
|
+
"network": "Could not connect to the school service.",
|
|
219
|
+
"untrustedUrl": "The school returned an unapproved redirect; the request stopped safely.",
|
|
220
|
+
"httpError": "The school login service returned an error status.",
|
|
221
|
+
"loginChanged": "The school login page changed; credentials were not submitted.",
|
|
222
|
+
"unexpectedResponse": "A valid JWXT session could not be confirmed after login.",
|
|
223
|
+
"missingDates": "JWXT returned no calendar dates. Provide --week-one=YYYY-MM-DD.",
|
|
224
|
+
"missingPeriod": "JWXT returned no usable period times, so export cannot continue safely.",
|
|
225
|
+
"termMismatch": "JWXT returned a different academic term. Try again.",
|
|
226
|
+
"invalidData": "The timetable response format is not currently recognized.",
|
|
227
|
+
"unknownTerm": "Unknown term. Run `nbtca schedule terms` first.",
|
|
228
|
+
"noTerms": "JWXT returned no available terms.",
|
|
229
|
+
"currentTermUnknown": "JWXT did not identify one current term. Choose one with --term=year:code.",
|
|
230
|
+
"genericError": "The timetable operation failed.",
|
|
231
|
+
"hubToday": "Today",
|
|
232
|
+
"hubWeek": "This week",
|
|
233
|
+
"hubSwitchTerm": "Switch term",
|
|
234
|
+
"hubExport": "Export .ics",
|
|
235
|
+
"hubLogout": "Log out",
|
|
236
|
+
"hubUnresolved": "Needs attention",
|
|
237
|
+
"unresolvedTitle": "Needs attention",
|
|
238
|
+
"unresolvedEmpty": "Nothing needs attention",
|
|
239
|
+
"unresolvedUnknownItem": "Unnamed item",
|
|
240
|
+
"nextClass": "Next",
|
|
241
|
+
"noClassToday": "No classes today",
|
|
242
|
+
"noNextClass": "No upcoming classes",
|
|
243
|
+
"nowLabel": "now",
|
|
244
|
+
"weekLabel": "Week",
|
|
245
|
+
"promptWeekOne": "First-week Monday (YYYY-MM-DD)",
|
|
246
|
+
"menuEntry": "Schedule",
|
|
247
|
+
"semester1": "Term 1",
|
|
248
|
+
"semester2": "Term 2",
|
|
249
|
+
"weekLabel2": "Week {week}",
|
|
250
|
+
"academicYearSuffix": "{year}",
|
|
251
|
+
"onBreak": "On break · {title}",
|
|
252
|
+
"publicUnavailable": "Academic calendar not available yet",
|
|
253
|
+
"daysUntilBreak": "{days} days until {title}",
|
|
254
|
+
"publicLoginAction": "Log in to see my timetable",
|
|
255
|
+
"publicLoginHint": "Log in to export your timetable (.ics)",
|
|
256
|
+
"weekOneAutoFailed": "Couldn't infer the term's first week automatically — please confirm it once",
|
|
257
|
+
"weekdayMon": "Mon",
|
|
258
|
+
"weekdayTue": "Tue",
|
|
259
|
+
"weekdayWed": "Wed",
|
|
260
|
+
"weekdayThu": "Thu",
|
|
261
|
+
"weekdayFri": "Fri",
|
|
262
|
+
"weekdaySat": "Sat",
|
|
263
|
+
"weekdaySun": "Sun",
|
|
264
|
+
"todayHeading": "Today · {weekday} · Week {week}",
|
|
265
|
+
"classDone": "Done",
|
|
266
|
+
"classLive": "In progress",
|
|
267
|
+
"minutesRemaining": "{minutes}m left",
|
|
268
|
+
"timelineEnd": "—",
|
|
269
|
+
"termNotStarted": "Term hasn't started yet",
|
|
270
|
+
"termStartsIn": "Classes begin {date} · {days} days to go",
|
|
271
|
+
"hubTermDensity": "Term density",
|
|
272
|
+
"termDensityTitle": "Term density",
|
|
273
|
+
"termDensityThisWeek": "This week",
|
|
274
|
+
"weekOverviewTitle": "Week overview",
|
|
275
|
+
"weekAheadClasses": "Classes",
|
|
276
|
+
"weekAheadBusy": "Busy",
|
|
277
|
+
"weekAheadFree": "Free",
|
|
278
|
+
"weekAheadNone": "N/A",
|
|
279
|
+
"termPreviewWeek": "Week 1 preview",
|
|
280
|
+
"hubFullGrid": "Full grid",
|
|
281
|
+
"detailTime": "Time",
|
|
282
|
+
"detailLocation": "Location",
|
|
283
|
+
"detailTeacher": "Teacher",
|
|
284
|
+
"detailWeeks": "Weeks",
|
|
285
|
+
"teacherSeparator": ", "
|
|
286
|
+
},
|
|
153
287
|
"theme": {
|
|
154
288
|
"current": "Current theme settings",
|
|
155
289
|
"chooseAction": "Settings",
|
|
@@ -197,11 +331,15 @@
|
|
|
197
331
|
"cmdTheme": "View or set theme",
|
|
198
332
|
"cmdLang": "Set language",
|
|
199
333
|
"cmdUpdate": "Check for updates",
|
|
334
|
+
"cmdSchedule": "Personal timetable login, term lookup and ICS export",
|
|
200
335
|
"flagVersion": "Show version",
|
|
201
336
|
"flagHelp": "Show help",
|
|
202
337
|
"flagOpen": "Open in browser (URL commands)",
|
|
203
338
|
"flagJson": "JSON output (events, status)",
|
|
204
339
|
"flagToday": "Today only (events)",
|
|
340
|
+
"flagWeek": "Events this week",
|
|
341
|
+
"flagMonth": "Events this month",
|
|
342
|
+
"flagSearch": "Filter events by keyword",
|
|
205
343
|
"flagNext": "Limit to next N (events)",
|
|
206
344
|
"flagWatch": "Live refresh (status)",
|
|
207
345
|
"flagInterval": "Refresh interval (status --watch)",
|
|
@@ -210,6 +348,11 @@
|
|
|
210
348
|
"flagHeatmap": "Activity heatmap (events)",
|
|
211
349
|
"flagPlain": "Disable colors",
|
|
212
350
|
"flagNoLogo": "Skip logo",
|
|
351
|
+
"flagOneShot": "Do not read or save a login session",
|
|
352
|
+
"flagNoSave": "Alias for --one-shot",
|
|
353
|
+
"flagTerm": "Select a term (for example 2026:3)",
|
|
354
|
+
"flagOutput": "ICS output path",
|
|
355
|
+
"flagWeekOne": "First teaching Monday when JWXT has no dates",
|
|
213
356
|
"unknownCommand": "Unknown command: {command}",
|
|
214
357
|
"unknownCommandHint": "Run `nbtca --help` to see available commands.",
|
|
215
358
|
"unknownFlag": "Unknown flag: {flag}",
|
|
@@ -8,7 +8,9 @@
|
|
|
8
8
|
"error": "错误",
|
|
9
9
|
"success": "成功",
|
|
10
10
|
"goodbye": "再见!",
|
|
11
|
-
"current": "当前"
|
|
11
|
+
"current": "当前",
|
|
12
|
+
"moreAbove": "上方还有 {count} 项",
|
|
13
|
+
"moreBelow": "下方还有 {count} 项"
|
|
12
14
|
},
|
|
13
15
|
"menu": {
|
|
14
16
|
"events": "活动",
|
|
@@ -17,11 +19,16 @@
|
|
|
17
19
|
"docsDesc": "知识库",
|
|
18
20
|
"status": "状态",
|
|
19
21
|
"statusDesc": "在线状态",
|
|
22
|
+
"timetable": "我的课表",
|
|
23
|
+
"timetableDesc": "登录教务、查询学期并导出 ICS",
|
|
20
24
|
"links": "链接",
|
|
21
25
|
"linksDesc": "官网 · GitHub · 路线图",
|
|
22
26
|
"settings": "设置",
|
|
23
27
|
"settingsDesc": "语言 · 主题 · 关于",
|
|
24
|
-
"chooseAction": "nbtca"
|
|
28
|
+
"chooseAction": "nbtca",
|
|
29
|
+
"hintMove": "移动",
|
|
30
|
+
"hintOpen": "打开",
|
|
31
|
+
"hintQuit": "退出"
|
|
25
32
|
},
|
|
26
33
|
"about": {
|
|
27
34
|
"title": "关于",
|
|
@@ -58,18 +65,34 @@
|
|
|
58
65
|
"pastEvents": "历史活动",
|
|
59
66
|
"pastEventsDesc": "近期活动记录",
|
|
60
67
|
"noPastEvents": "最近 30 天内暂无历史活动",
|
|
61
|
-
"viewPastDetail": "选择活动查看详情:"
|
|
68
|
+
"viewPastDetail": "选择活动查看详情:",
|
|
69
|
+
"next": "下一场",
|
|
70
|
+
"recentActivity": "近期动态",
|
|
71
|
+
"inPrefix": "还有",
|
|
72
|
+
"startingNow": "即将开始",
|
|
73
|
+
"thisWeek": "本周",
|
|
74
|
+
"thisMonth": "本月",
|
|
75
|
+
"search": "搜索",
|
|
76
|
+
"searchPrompt": "搜索活动",
|
|
77
|
+
"searchPlaceholder": "关键词…",
|
|
78
|
+
"searchNoResults": "没有匹配的活动",
|
|
79
|
+
"exportIcs": "导出 .ics",
|
|
80
|
+
"exportSuccess": "已保存",
|
|
81
|
+
"exportError": "无法写入 .ics 文件",
|
|
82
|
+
"recurringLabel": "循环"
|
|
62
83
|
},
|
|
63
84
|
"docs": {
|
|
64
85
|
"loading": "正在加载文档列表...",
|
|
65
86
|
"loadingDir": "正在加载目录",
|
|
66
|
-
"
|
|
87
|
+
"categoryAbout": "认识 NBTCA",
|
|
88
|
+
"categoryGuide": "指南",
|
|
67
89
|
"categoryRepairLogs": "维修日记",
|
|
68
90
|
"categoryEvents": "活动文档",
|
|
69
|
-
"
|
|
91
|
+
"categoryConcepts": "参考",
|
|
70
92
|
"categoryRepair": "维修",
|
|
71
93
|
"categoryArchived": "归档",
|
|
72
94
|
"categoryReadme": "项目说明 (README)",
|
|
95
|
+
"overviewLabel": "总览",
|
|
73
96
|
"chooseCategory": "文档",
|
|
74
97
|
"refreshCache": "刷新缓存",
|
|
75
98
|
"cacheCleared": "文档缓存已清除",
|
|
@@ -106,7 +129,10 @@
|
|
|
106
129
|
"searching": "正在搜索文档...",
|
|
107
130
|
"searchResults": "个结果",
|
|
108
131
|
"searchNoResults": "未找到匹配的文档",
|
|
109
|
-
"loadingFile": "正在加载"
|
|
132
|
+
"loadingFile": "正在加载",
|
|
133
|
+
"readerLinksTitle": "跳转到",
|
|
134
|
+
"readerLinksHint": "链接",
|
|
135
|
+
"readerNoLinks": "本页没有指向其他文档的链接"
|
|
110
136
|
},
|
|
111
137
|
"links": {
|
|
112
138
|
"choose": "链接",
|
|
@@ -150,6 +176,114 @@
|
|
|
150
176
|
"watchJsonConflict": "--watch 不能和 --json 同时使用。",
|
|
151
177
|
"intervalNeedsWatch": "--interval 需要配合 --watch 使用。"
|
|
152
178
|
},
|
|
179
|
+
"timetable": {
|
|
180
|
+
"menuTitle": "我的课表",
|
|
181
|
+
"actionExport": "导出 ICS",
|
|
182
|
+
"actionTerms": "查看学期",
|
|
183
|
+
"actionLogin": "登录或刷新会话",
|
|
184
|
+
"actionLogout": "退出登录",
|
|
185
|
+
"actionStatus": "登录状态",
|
|
186
|
+
"termPrompt": "学期代码",
|
|
187
|
+
"termPromptHint": "留空使用当前学期,例如 2026:3",
|
|
188
|
+
"unknownCommand": "未知课表命令。可用:login、logout、status、terms、export。",
|
|
189
|
+
"loggedOut": "本地登录状态已清除。",
|
|
190
|
+
"savedStatus": "已保存登录状态{account}。",
|
|
191
|
+
"noSavedStatus": "没有保存的登录状态。",
|
|
192
|
+
"loginSaved": "登录验证成功,状态已保存。",
|
|
193
|
+
"loginOneShot": "登录验证成功;本次未保存登录状态。",
|
|
194
|
+
"loginWillSave": "成功后将保存本地登录状态(承载凭据);如不希望保存,请使用 --one-shot。",
|
|
195
|
+
"sessionRefreshFailed": "操作已完成,但未能刷新本地登录状态的有效期。",
|
|
196
|
+
"candidateTerms": "教务候选学期(不代表每个学期都有个人课表):",
|
|
197
|
+
"semesterNumber": "第{number}学期",
|
|
198
|
+
"expiredRelogin": "已保存的登录状态过期,请重新登录。",
|
|
199
|
+
"studentId": "学号",
|
|
200
|
+
"studentIdHint": "仅发送给学校统一认证",
|
|
201
|
+
"password": "密码",
|
|
202
|
+
"passwordHint": "输入内容不会显示或保存",
|
|
203
|
+
"weekOne": "第一教学周周一(YYYY-MM-DD)",
|
|
204
|
+
"weekOneHint": "教务响应不含开学日期,请按官方校历确认",
|
|
205
|
+
"exported": "已导出 {count} 条课程安排到 {file}",
|
|
206
|
+
"warnings": "有 {count} 条数据未能完整解析;请导入后核对。",
|
|
207
|
+
"unresolvedPractice": "有 {count} 条实践安排缺少已确认的星期/节次,未写入 ICS。",
|
|
208
|
+
"calendarName": "{year}{semester}课表",
|
|
209
|
+
"invalidOption": "选项 {flag} 不适用于当前课表命令。",
|
|
210
|
+
"invalidArguments": "课表命令参数过多;可用:login、logout、status、terms、export。",
|
|
211
|
+
"noSession": "当前没有可用登录状态;请在交互终端运行 `nbtca schedule login`。",
|
|
212
|
+
"invalidCredentials": "学号或密码不正确。",
|
|
213
|
+
"accountLocked": "账户暂时被锁定,请稍后再试或通过学校页面处理。",
|
|
214
|
+
"accountInactive": "账户尚未激活,请先通过学校官方页面激活。",
|
|
215
|
+
"challenge": "学校要求滑块或其他浏览器验证,本次 CLI 登录已安全中止。",
|
|
216
|
+
"sessionExpired": "登录状态已过期,请重新登录。",
|
|
217
|
+
"timeout": "学校服务响应超时。",
|
|
218
|
+
"network": "无法连接学校服务。",
|
|
219
|
+
"untrustedUrl": "学校返回了未授权的登录跳转,已安全中止。",
|
|
220
|
+
"httpError": "学校登录服务返回了错误状态。",
|
|
221
|
+
"loginChanged": "学校登录页结构已经变化,当前版本未提交凭据。",
|
|
222
|
+
"unexpectedResponse": "登录后未能确认有效的教务会话。",
|
|
223
|
+
"missingDates": "教务响应没有可用日期,请用 --week-one=YYYY-MM-DD 指定第一周周一。",
|
|
224
|
+
"missingPeriod": "教务响应缺少课程节次时间,无法安全导出。",
|
|
225
|
+
"termMismatch": "教务系统返回了不同学期,请重试。",
|
|
226
|
+
"invalidData": "课表数据格式暂时无法识别。",
|
|
227
|
+
"unknownTerm": "未知学期;请先运行 `nbtca schedule terms`。",
|
|
228
|
+
"noTerms": "教务系统没有返回可用学期。",
|
|
229
|
+
"currentTermUnknown": "教务没有标出唯一的当前学期;请用 --term=学年:代码 指定。",
|
|
230
|
+
"genericError": "课表操作失败。",
|
|
231
|
+
"hubToday": "今日",
|
|
232
|
+
"hubWeek": "本周",
|
|
233
|
+
"hubSwitchTerm": "切换学期",
|
|
234
|
+
"hubExport": "导出 .ics",
|
|
235
|
+
"hubLogout": "退出登录",
|
|
236
|
+
"hubUnresolved": "待处理事项",
|
|
237
|
+
"unresolvedTitle": "待处理事项",
|
|
238
|
+
"unresolvedEmpty": "没有待处理事项",
|
|
239
|
+
"unresolvedUnknownItem": "未命名安排",
|
|
240
|
+
"nextClass": "下一节",
|
|
241
|
+
"noClassToday": "今天没有课",
|
|
242
|
+
"noNextClass": "没有即将开始的课",
|
|
243
|
+
"nowLabel": "进行中",
|
|
244
|
+
"weekLabel": "第",
|
|
245
|
+
"promptWeekOne": "第一周周一 (YYYY-MM-DD)",
|
|
246
|
+
"menuEntry": "课表",
|
|
247
|
+
"semester1": "第一学期",
|
|
248
|
+
"semester2": "第二学期",
|
|
249
|
+
"weekLabel2": "第 {week} 周",
|
|
250
|
+
"academicYearSuffix": "{year}学年",
|
|
251
|
+
"onBreak": "假期中 · {title}",
|
|
252
|
+
"publicUnavailable": "校历数据暂不可用",
|
|
253
|
+
"daysUntilBreak": "距离{title}还有 {days} 天",
|
|
254
|
+
"publicLoginAction": "登录查看我的课表",
|
|
255
|
+
"publicLoginHint": "登录后可导出课表 (.ics)",
|
|
256
|
+
"weekOneAutoFailed": "未能从校历自动推算学期第一周,请手动确认一次",
|
|
257
|
+
"weekdayMon": "一",
|
|
258
|
+
"weekdayTue": "二",
|
|
259
|
+
"weekdayWed": "三",
|
|
260
|
+
"weekdayThu": "四",
|
|
261
|
+
"weekdayFri": "五",
|
|
262
|
+
"weekdaySat": "六",
|
|
263
|
+
"weekdaySun": "日",
|
|
264
|
+
"todayHeading": "今日 · 周{weekday} · 第{week}教学周",
|
|
265
|
+
"classDone": "已结束",
|
|
266
|
+
"classLive": "进行中",
|
|
267
|
+
"minutesRemaining": "还剩 {minutes} 分钟",
|
|
268
|
+
"timelineEnd": "无",
|
|
269
|
+
"termNotStarted": "本学期尚未开始",
|
|
270
|
+
"termStartsIn": "{date} 开学 · 还有 {days} 天",
|
|
271
|
+
"hubTermDensity": "学期活跃度",
|
|
272
|
+
"termDensityTitle": "学期活跃度",
|
|
273
|
+
"termDensityThisWeek": "本周",
|
|
274
|
+
"weekOverviewTitle": "本周概览",
|
|
275
|
+
"weekAheadClasses": "课程",
|
|
276
|
+
"weekAheadBusy": "较满",
|
|
277
|
+
"weekAheadFree": "较空",
|
|
278
|
+
"weekAheadNone": "无",
|
|
279
|
+
"termPreviewWeek": "第一周预览",
|
|
280
|
+
"hubFullGrid": "完整课表",
|
|
281
|
+
"detailTime": "时间",
|
|
282
|
+
"detailLocation": "地点",
|
|
283
|
+
"detailTeacher": "教师",
|
|
284
|
+
"detailWeeks": "周次",
|
|
285
|
+
"teacherSeparator": "、"
|
|
286
|
+
},
|
|
153
287
|
"theme": {
|
|
154
288
|
"current": "当前主题设置",
|
|
155
289
|
"chooseAction": "设置",
|
|
@@ -197,11 +331,15 @@
|
|
|
197
331
|
"cmdTheme": "查看或设置主题",
|
|
198
332
|
"cmdLang": "设置语言",
|
|
199
333
|
"cmdUpdate": "检查更新",
|
|
334
|
+
"cmdSchedule": "个人课表登录、学期查询与 ICS 导出",
|
|
200
335
|
"flagVersion": "显示版本号",
|
|
201
336
|
"flagHelp": "显示帮助",
|
|
202
337
|
"flagOpen": "在浏览器中打开(URL 命令)",
|
|
203
338
|
"flagJson": "JSON 输出(events, status)",
|
|
204
339
|
"flagToday": "仅显示今日(events)",
|
|
340
|
+
"flagWeek": "本周活动",
|
|
341
|
+
"flagMonth": "本月活动",
|
|
342
|
+
"flagSearch": "按关键词过滤活动",
|
|
205
343
|
"flagNext": "限制为前 N 个(events)",
|
|
206
344
|
"flagWatch": "实时刷新(status)",
|
|
207
345
|
"flagInterval": "刷新间隔(status --watch)",
|
|
@@ -210,6 +348,11 @@
|
|
|
210
348
|
"flagHeatmap": "活动热力图 (events)",
|
|
211
349
|
"flagPlain": "禁用颜色",
|
|
212
350
|
"flagNoLogo": "跳过 Logo",
|
|
351
|
+
"flagOneShot": "不读取或保存登录状态",
|
|
352
|
+
"flagNoSave": "--one-shot 的别名",
|
|
353
|
+
"flagTerm": "选择学年学期(例如 2026:3)",
|
|
354
|
+
"flagOutput": "ICS 输出路径",
|
|
355
|
+
"flagWeekOne": "第一教学周周一(教务未返回日期时使用)",
|
|
213
356
|
"unknownCommand": "未知命令: {command}",
|
|
214
357
|
"unknownCommandHint": "运行 `nbtca --help` 查看可用命令。",
|
|
215
358
|
"unknownFlag": "未知选项: {flag}",
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* NBTCA Prompt entry point
|
|
3
|
-
*/
|
|
4
1
|
import chalk from 'chalk';
|
|
5
2
|
import open from 'open';
|
|
6
3
|
import { main } from './main.js';
|
|
@@ -11,10 +8,11 @@ import { pickIcon } from './core/icons.js';
|
|
|
11
8
|
import { applyColorModePreference } from './config/preferences.js';
|
|
12
9
|
import { openDocsInBrowser } from './features/docs.js';
|
|
13
10
|
import { runThemeCommand } from './features/theme.js';
|
|
14
|
-
import {
|
|
11
|
+
import { saveLanguagePreference, t, fmt } from './i18n/index.js';
|
|
15
12
|
import { clearScreen, handleGracefulExit } from './core/ui.js';
|
|
16
13
|
import { APP_INFO, URLS } from './config/data.js';
|
|
17
14
|
import { runUpdateCheck } from './features/update.js';
|
|
15
|
+
import { runStudentTimetableCommand } from './features/student-timetable.js';
|
|
18
16
|
const ACTION_ALIASES = {
|
|
19
17
|
events: 'events',
|
|
20
18
|
event: 'events',
|
|
@@ -36,8 +34,11 @@ const URL_ACTIONS = {
|
|
|
36
34
|
github: URLS.github,
|
|
37
35
|
roadmap: URLS.roadmap
|
|
38
36
|
};
|
|
39
|
-
const KNOWN_FLAGS = new Set([
|
|
40
|
-
|
|
37
|
+
const KNOWN_FLAGS = new Set([
|
|
38
|
+
'--help', '--version', '--open', '--json', '--plain', '--no-logo', '--watch', '--today', '--heatmap',
|
|
39
|
+
'--week', '--month', '--one-shot', '--no-save',
|
|
40
|
+
]);
|
|
41
|
+
const KNOWN_FLAG_PREFIXES = ['--interval=', '--timeout=', '--retries=', '--next=', '--search=', '--term=', '--output=', '--week-one='];
|
|
41
42
|
const STATUS_WATCH_INTERVAL_MIN = 3;
|
|
42
43
|
const STATUS_WATCH_INTERVAL_MAX = 300;
|
|
43
44
|
const STATUS_TIMEOUT_MIN = 1000;
|
|
@@ -75,6 +76,11 @@ function getAllowedFlagsFor(command) {
|
|
|
75
76
|
return allowed;
|
|
76
77
|
if (command === 'theme')
|
|
77
78
|
return allowed;
|
|
79
|
+
if (command === 'schedule' || command === 'timetable') {
|
|
80
|
+
allowed.add('--one-shot');
|
|
81
|
+
allowed.add('--no-save');
|
|
82
|
+
return allowed;
|
|
83
|
+
}
|
|
78
84
|
const action = ACTION_ALIASES[command];
|
|
79
85
|
if (!action)
|
|
80
86
|
return allowed;
|
|
@@ -83,6 +89,8 @@ function getAllowedFlagsFor(command) {
|
|
|
83
89
|
allowed.add('--json');
|
|
84
90
|
allowed.add('--today');
|
|
85
91
|
allowed.add('--heatmap');
|
|
92
|
+
allowed.add('--week');
|
|
93
|
+
allowed.add('--month');
|
|
86
94
|
return allowed;
|
|
87
95
|
case 'status':
|
|
88
96
|
allowed.add('--json');
|
|
@@ -103,9 +111,12 @@ function getAllowedFlagsFor(command) {
|
|
|
103
111
|
function getAllowedFlagPrefixesFor(command) {
|
|
104
112
|
if (!command)
|
|
105
113
|
return [];
|
|
114
|
+
if (command === 'schedule' || command === 'timetable') {
|
|
115
|
+
return ['--term=', '--output=', '--week-one='];
|
|
116
|
+
}
|
|
106
117
|
const action = ACTION_ALIASES[command];
|
|
107
118
|
if (action === 'events')
|
|
108
|
-
return ['--next='];
|
|
119
|
+
return ['--next=', '--search='];
|
|
109
120
|
if (action === 'status')
|
|
110
121
|
return ['--interval=', '--timeout=', '--retries='];
|
|
111
122
|
return [];
|
|
@@ -149,6 +160,8 @@ function printHelp() {
|
|
|
149
160
|
console.log(` events ${trans.menu.eventsDesc}`);
|
|
150
161
|
console.log(` docs ${trans.menu.docsDesc}`);
|
|
151
162
|
console.log(` status ${trans.menu.statusDesc}`);
|
|
163
|
+
console.log(' schedule <login|logout|status|terms|export>');
|
|
164
|
+
console.log(` ${c.cmdSchedule}`);
|
|
152
165
|
console.log(` website ${c.cmdWebsite}`);
|
|
153
166
|
console.log(` github ${c.cmdGithub}`);
|
|
154
167
|
console.log(` roadmap ${c.cmdRoadmap}`);
|
|
@@ -164,6 +177,9 @@ function printHelp() {
|
|
|
164
177
|
console.log(` --json ${c.flagJson}`);
|
|
165
178
|
console.log(` --heatmap ${c.flagHeatmap}`);
|
|
166
179
|
console.log(` --today ${c.flagToday}`);
|
|
180
|
+
console.log(` --week ${c.flagWeek}`);
|
|
181
|
+
console.log(` --month ${c.flagMonth}`);
|
|
182
|
+
console.log(` --search=<q> ${c.flagSearch}`);
|
|
167
183
|
console.log(` --next=<n> ${c.flagNext}`);
|
|
168
184
|
console.log(` --watch ${c.flagWatch}`);
|
|
169
185
|
console.log(` --interval=<s> ${c.flagInterval}`);
|
|
@@ -171,6 +187,11 @@ function printHelp() {
|
|
|
171
187
|
console.log(` --retries=<n> ${c.flagRetries}`);
|
|
172
188
|
console.log(` --plain ${c.flagPlain}`);
|
|
173
189
|
console.log(` --no-logo ${c.flagNoLogo}`);
|
|
190
|
+
console.log(` --one-shot ${c.flagOneShot}`);
|
|
191
|
+
console.log(` --no-save ${c.flagNoSave}`);
|
|
192
|
+
console.log(` --term=<year:code> ${c.flagTerm}`);
|
|
193
|
+
console.log(` --output=<path> ${c.flagOutput}`);
|
|
194
|
+
console.log(` --week-one=<date> ${c.flagWeekOne}`);
|
|
174
195
|
}
|
|
175
196
|
async function runEventsCommand(flags) {
|
|
176
197
|
if (flags.has('--heatmap')) {
|
|
@@ -184,7 +205,26 @@ async function runEventsCommand(flags) {
|
|
|
184
205
|
}
|
|
185
206
|
return;
|
|
186
207
|
}
|
|
187
|
-
|
|
208
|
+
const { weekRange, monthRange } = await import('./features/calendar-query.js');
|
|
209
|
+
const { fetchInRange } = await import('./features/calendar.js');
|
|
210
|
+
const now0 = new Date();
|
|
211
|
+
let events;
|
|
212
|
+
if (flags.has('--week')) {
|
|
213
|
+
const r = weekRange(now0);
|
|
214
|
+
events = await fetchInRange(r.start, r.end);
|
|
215
|
+
}
|
|
216
|
+
else if (flags.has('--month')) {
|
|
217
|
+
const r = monthRange(now0);
|
|
218
|
+
events = await fetchInRange(r.start, r.end);
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
events = await fetchEvents();
|
|
222
|
+
}
|
|
223
|
+
const searchFlag = Array.from(flags).find(f => f.startsWith('--search='));
|
|
224
|
+
if (searchFlag) {
|
|
225
|
+
const q = searchFlag.slice('--search='.length).toLowerCase();
|
|
226
|
+
events = events.filter(e => `${e.title} ${e.location}`.toLowerCase().includes(q));
|
|
227
|
+
}
|
|
188
228
|
if (flags.has('--today')) {
|
|
189
229
|
const now = new Date();
|
|
190
230
|
events = events.filter(e => {
|
|
@@ -333,7 +373,7 @@ async function runCommandMode(argv) {
|
|
|
333
373
|
console.error(chalk.red(t().cli.invalidLang));
|
|
334
374
|
process.exit(1);
|
|
335
375
|
}
|
|
336
|
-
const persisted =
|
|
376
|
+
const persisted = saveLanguagePreference(language);
|
|
337
377
|
if (persisted) {
|
|
338
378
|
console.log(chalk.green(`${pickIcon('✓', 'OK')}: ${t().language.changed}`));
|
|
339
379
|
}
|
|
@@ -357,6 +397,17 @@ async function runCommandMode(argv) {
|
|
|
357
397
|
await runUpdateCheck();
|
|
358
398
|
return;
|
|
359
399
|
}
|
|
400
|
+
if (command === 'schedule' || command === 'timetable') {
|
|
401
|
+
if (args.length > 1) {
|
|
402
|
+
console.error(chalk.red(t().timetable.invalidArguments));
|
|
403
|
+
process.exitCode = 1;
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
const exitCode = await runStudentTimetableCommand(args[0], { flags });
|
|
407
|
+
if (exitCode !== 0)
|
|
408
|
+
process.exitCode = exitCode;
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
360
411
|
const action = ACTION_ALIASES[command];
|
|
361
412
|
if (!action) {
|
|
362
413
|
const cliT = t().cli;
|
|
@@ -390,7 +441,7 @@ async function runCommandMode(argv) {
|
|
|
390
441
|
return;
|
|
391
442
|
}
|
|
392
443
|
if (action === 'about') {
|
|
393
|
-
const { note } = await import('
|
|
444
|
+
const { note } = await import('./core/components/note.js');
|
|
394
445
|
const { padEndV } = await import('./core/text.js');
|
|
395
446
|
const pad = 12;
|
|
396
447
|
const row = (label, value) => `${chalk.dim(padEndV(label, pad))}${value}`;
|
|
@@ -410,7 +461,6 @@ async function runCommandMode(argv) {
|
|
|
410
461
|
note(content, trans.about.title);
|
|
411
462
|
return;
|
|
412
463
|
}
|
|
413
|
-
// URL actions: repair, website, github, roadmap
|
|
414
464
|
const mappedUrl = URL_ACTIONS[action];
|
|
415
465
|
if (mappedUrl) {
|
|
416
466
|
if (flags.has('--open')) {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣤⣤⡶⠶⠾⠟⠛⠛⠛⠛⠻⠷⠶⢶⣤⣤⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
|
2
|
+
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣴⠾⠛⢩⠥⠀⠤⡄⡔⡖⡆⡖⡆⡆⡄⡖⣠⣄⣀⠈⠉⠛⠷⣦⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
|
3
|
+
⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⡶⠟⠉⠀⠀⠀⠘⠤⠂⢑⣁⣁⣥⣤⣧⣤⣤⣤⣁⣁⡀⠃⠀⠴⢿⢀⣀⠉⠛⢶⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
|
4
|
+
⠀⠀⠀⠀⠀⠀⠀⢀⣴⠟⠉⡰⣄⢛⠆⢂⣠⡴⠶⠛⠋⠉⠁⠀⠀⠀⠀⠀⠀⠈⠉⠙⠛⠶⢦⣌⡐⠃⣰⡂⣀⠉⠻⣦⡀⠀⠀⠀⠀⠀⠀⠀
|
|
5
|
+
⠀⠀⠀⠀⠀⢀⣴⠟⠁⠠⣮⡣⠈⣡⡶⠛⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠛⢶⣄⡘⠴⡡⢄⠈⠻⣦⡀⠀⠀⠀⠀⠀
|
|
6
|
+
⠀⠀⠀⠀⢠⡾⠃⣐⢤⡀⢉⣴⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣦⡁⠔⣣⡄⠘⢷⡄⠀⠀⠀⠀
|
|
7
|
+
⠀⠀⠀⣰⡟⠀⡄⠨⠇⣠⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠻⣆⠙⡥⣂⠄⢻⣆⠀⠀⠀
|
|
8
|
+
⠀⠀⣰⡟⠀⢖⣪⢁⣼⣯⠴⠖⠚⠛⠛⠛⠓⠒⠦⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⠴⠖⠒⠛⠛⠒⠲⠶⢤⣀⠀⠙⣧⡈⣕⣲⠀⢻⣆⠀⠀
|
|
9
|
+
⠀⢰⡟⠠⢌⡱⣠⡞⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠢⡀⠀⠀⠀⠀⣠⠞⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠓⢦⡈⢷⡀⢒⡣⠀⢻⡆⠀
|
|
10
|
+
⠀⣿⠁⠬⠕⣶⣿⣿⣿⣆⠀⢀⣠⡤⠤⠤⠤⢤⣀⡀⠀⠀⠙⣆⠀⠀⣼⣿⣿⣷⡄⠀⢀⣀⣤⠤⠤⢤⣄⣀⠀⠀⠀⠳⡜⣧⠀⡀⢀⠈⣿⠀
|
|
11
|
+
⢸⡏⠠⠤⡄⢿⣿⣿⣿⣿⠞⠋⠁⠀⠀⠀⠀⠀⠀⠙⠦⣀⠀⣸⠀⠀⣿⣿⣿⣿⣷⠞⠋⠁⠀⠀⠀⠀⠀⠈⠓⢤⡀⠀⣷⢹⡆⢓⣪⣄⢹⡇
|
|
12
|
+
⣾⠇⢠⠵⠁⣼⠛⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠀⠀⠉⠛⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠛⠁⠈⣧⠀⣀⣀⠸⣷
|
|
13
|
+
⣿⠀⢨⡤⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠴⠥⠀⣿
|
|
14
|
+
⣿⠀⠈⠉⠀⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⣉⣏⠀⣿
|
|
15
|
+
⢿⡆⠈⠴⠒⢿⡀⠀⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡄⠀⠀⢀⡟⠠⠤⢴⢰⡿
|
|
16
|
+
⢸⣇⠀⠯⠍⠻⣇⠀⢹⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⠇⠀⠀⣸⠇⠀⠀⠈⣸⡇
|
|
17
|
+
⠀⣿⡀⠸⠩⠂⢻⡄⠈⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡟⠀⠀⢠⡟⠀⠤⣠⢀⣿⠀
|
|
18
|
+
⠀⠸⣧⠐⢨⠁⡄⢷⡀⠈⢧⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⡾⠁⠀⢀⡾⠁⢏⡱⠈⣼⠇⠀
|
|
19
|
+
⠀⠀⠹⣧⠈⢩⢒⡈⢻⡄⠈⠳⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠞⠀⠀⢠⡟⢡⠦⣄⠀⣼⠏⠀⠀
|
|
20
|
+
⠀⠀⠀⠹⣧⡀⠡⣊⠄⠙⣦⡀⠈⠳⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⠞⠁⠀⢀⣴⠏⠰⣺⠉⢀⣼⠏⠀⠀⠀
|
|
21
|
+
⠀⠀⠀⠀⠘⢷⡌⠁⠤⢇⢈⠻⣦⡀⠈⠓⢦⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⡴⠛⠁⠀⢀⣴⠟⢡⡢⡀⠀⢠⡾⠃⠀⠀⠀⠀
|
|
22
|
+
⠀⠀⠀⠀⠀⠈⠻⣦⡀⠑⢋⠔⠀⠙⠶⣄⡀⠈⠙⠛⠶⠦⣤⣤⣤⣤⣤⣤⣤⠴⠶⠚⠉⠁⠀⢀⣠⠶⠋⣁⠈⠳⠍⢀⣴⠟⠁⠀⠀⠀⠀⠀
|
|
23
|
+
⠀⠀⠀⠀⠀⠀⠀⠈⠻⣦⣀⠀⠴⢱⢲⠈⠙⠓⠶⣤⣄⣀⡀⠀⠀⠀⠀⠀⠀⢀⣀⣠⣤⠶⠞⠋⠥⡰⣘⢌⠂⣀⣴⠟⠁⠀⠀⠀⠀⠀⠀⠀
|
|
24
|
+
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠷⣦⣀⠁⠀⠎⡔⡔⢢⠈⢉⢉⡛⠛⠛⠛⠛⠛⢉⡉⡅⡄⢂⢂⠀⠓⠃⣀⣴⠾⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
|
25
|
+
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠙⠻⢶⣤⣀⡈⠁⠃⠆⠠⠆⠶⠇⠕⠇⠼⠐⠙⠸⠈⢁⣀⣤⡶⠟⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
|
26
|
+
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠛⠛⠷⠶⢶⣦⣤⣤⣤⣤⣴⡶⠶⠾⠛⠛⠉⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
⠀⠀⠀⠀⠀⠀⣠⠤⠒⠊⠉⢉⢉⢉⡑⠒⠤⣄⠀⠀⠀⠀⠀⠀
|
|
2
|
+
⠀⠀⠀⢀⠔⠉⠄⣀⠥⠒⠒⠊⠐⠒⠒⠤⣁⠢⡉⠢⡀⠀⠀⠀
|
|
3
|
+
⠀⠀⡔⢁⢈⠔⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠢⡀⡈⢢⠀⠀
|
|
4
|
+
⠀⡞⠠⢠⠇⠒⠒⠒⠂⢄⠀⠀⠀⡠⠄⠒⠒⠂⠤⡘⡄⢀⢳⠀
|
|
5
|
+
⡸⠀⢺⣷⣆⠤⠐⠒⠠⠀⠱⠀⣾⣶⡠⠄⠐⠀⠄⠈⠺⡄⡀⢇
|
|
6
|
+
⡇⠀⠸⠉⠁⠀⠀⠀⠀⠀⠉⠀⠉⠉⠀⠀⠀⠀⠀⠈⠁⠇⠀⢸
|
|
7
|
+
⡇⠠⢰⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⡆⠙⢸
|
|
8
|
+
⢱⠐⠉⡄⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠇⢠⠃⠀⡎
|
|
9
|
+
⠀⢧⠠⠘⡌⠢⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠊⢠⢃⠄⡼⠀
|
|
10
|
+
⠀⠀⠣⡀⢨⠢⣈⠢⢄⣀⠀⠀⠀⢀⣀⠤⠊⣀⠔⡡⢉⠜⠀⠀
|
|
11
|
+
⠀⠀⠀⠈⠢⣐⠀⢉⡒⠤⠬⠍⠩⠤⠤⠒⠉⠀⣀⠔⠁⠀⠀⠀
|
|
12
|
+
⠀⠀⠀⠀⠀⠀⠙⠒⠤⢅⣀⣀⣁⣈⡨⠤⠒⠋⠀⠀⠀⠀⠀⠀
|