parse-comcigan 0.0.5 → 0.2.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 CHANGED
@@ -7,7 +7,7 @@
7
7
  ## 경고
8
8
 
9
9
  본 라이브러리는 **비공식적**으로 컴시간알리미의 데이터를 파싱합니다.
10
- 상업적으로 사용하다 문제가 발생할경우, **제작자는 책임을 지지 않습니다.**
10
+ 상업적으로 사용하다 문제가 발생할경우, **제작자는 책임을 지지 않습니다.**
11
11
 
12
12
  ## 설치
13
13
 
@@ -25,6 +25,7 @@ Comcigan 클래스의 인스턴스를 생성하여 사용합니다.
25
25
  |cacheMs|number|0|캐시될 시간(밀리초)입니다. 0일때 캐시를 비활성화합니다.|
26
26
  |doNotThrow|boolean|true|[Axios](https://axios-http.com/)에서 validateStatus를 항상 true로 반환할 지에 대한 여부입니다.|
27
27
  |debug|(msg: string) => any|undefined|디버그 메시지를 처리하는 콜백입니다. 이 콜백은 주로 컴시간과 통신할 때 호출됩니다.|
28
+ |appVersion|string|2.11|컴시간알리미 안드로이드 앱의 버전입니다.|
28
29
 
29
30
  ```typescript
30
31
  import Comcigan from 'parse-comcigan';
@@ -141,6 +142,16 @@ comci.GetClassList(96211).then(data => {
141
142
 
142
143
  ## 업데이트 로그
143
144
 
145
+ ### 0.2.0
146
+
147
+ - 버전 넘버링 수정
148
+ - 앱 버전 수정 기능 추가
149
+ - 시간표 버그 수정
150
+
151
+ ### 0.0.6
152
+
153
+ - 모듈이 불러와지지 않던 버그 수정
154
+
144
155
  ### 0.0.5
145
156
 
146
157
  - 문서의 많은 오류 수정
@@ -0,0 +1,8 @@
1
+ export default class Cache {
2
+ private _cacheStorage;
3
+ register(id: string, data: any, duration: number): void;
4
+ delete(id: string): void;
5
+ clear(): void;
6
+ has(id: string): boolean;
7
+ get(id: string): any;
8
+ }
package/dist/cache.js ADDED
@@ -0,0 +1,32 @@
1
+ export default class Cache {
2
+ constructor() {
3
+ this._cacheStorage = {};
4
+ }
5
+ register(id, data, duration) {
6
+ this._cacheStorage[id] = {
7
+ "timeout": setTimeout(() => {
8
+ delete this._cacheStorage[id];
9
+ }, duration),
10
+ "data": data
11
+ };
12
+ }
13
+ delete(id) {
14
+ clearTimeout(this._cacheStorage[id].timeout);
15
+ delete this._cacheStorage[id];
16
+ }
17
+ clear() {
18
+ const caches = Object.keys(this._cacheStorage);
19
+ for (let cache of caches) {
20
+ clearTimeout(this._cacheStorage[cache].timeout);
21
+ delete this._cacheStorage[cache];
22
+ }
23
+ }
24
+ has(id) {
25
+ return Boolean(this._cacheStorage[id]);
26
+ }
27
+ get(id) {
28
+ var _a;
29
+ return (_a = this._cacheStorage[id]) === null || _a === void 0 ? void 0 : _a.data;
30
+ }
31
+ }
32
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,OAAO,KAAK;IAA1B;QACY,kBAAa,GAGhB,EAAE,CAAC;IA2BZ,CAAC;IAzBU,QAAQ,CAAC,EAAU,EAAE,IAAS,EAAE,QAAgB;QACnD,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,GAAG;YACrB,SAAS,EAAE,UAAU,CAAC,GAAG,EAAE;gBACvB,OAAO,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAClC,CAAC,EAAE,QAAQ,CAAC;YACZ,MAAM,EAAE,IAAI;SACf,CAAC;IACN,CAAC;IACM,MAAM,CAAC,EAAU;QACpB,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IAClC,CAAC;IACM,KAAK;QACR,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC/C,KAAK,IAAI,KAAK,IAAI,MAAM,EAAE,CAAC;YACvB,YAAY,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC;YAChD,OAAO,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;IACL,CAAC;IACM,GAAG,CAAC,EAAU;QACjB,OAAO,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3C,CAAC;IACM,GAAG,CAAC,EAAU;;QACjB,OAAO,MAAA,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC,0CAAE,IAAI,CAAC;IACxC,CAAC;CACJ"}
@@ -0,0 +1,138 @@
1
+ export type GetTimetableOptions = {
2
+ /**
3
+ * 컴시간 학교 코드입니다.
4
+ */
5
+ "schoolCode": number;
6
+ /**
7
+ * 구분을 어떻게 할지 여부입니다.
8
+ *
9
+ * - weekday로 설정하면 시간표[교시][요일]로 과목과 선생님을 불러옵니다.
10
+ * - period로 설정하면 시간표[요일][교시]로 과목과 선생님을 불러옵니다.
11
+ */
12
+ "criteria": "weekday" | "period";
13
+ /**
14
+ * 학년입니다.
15
+ */
16
+ "grade": number;
17
+ /**
18
+ * 반입니다.
19
+ */
20
+ "classN": number;
21
+ /**
22
+ * 8교시를 빼고 리턴할지 여부입니다.
23
+ */
24
+ "without8th"?: boolean;
25
+ };
26
+ export interface ComciganInitializeType {
27
+ /**
28
+ * 이 기간동안 컴시간과 통신한 데이터가 캐시됩니다.
29
+ *
30
+ * 기본값은 0ms이며, 0ms일때는 캐시를 하지 않습니다.
31
+ */
32
+ cacheMs?: number;
33
+ /**
34
+ * axios에서 요청을 보내고 status가 오류 status일 때 throw할 지 여부입니다.
35
+ * 만약 false일 때 요청에 status가 오류 status면 그 타입에서 빈 값을 리턴합니다.
36
+ *
37
+ * 기본값은 false입니다.
38
+ */
39
+ doNotThrow?: boolean;
40
+ /**
41
+ * 디버그 메시지를 파라메터로 받습니다.
42
+ *
43
+ * 기본값은 없습니다.
44
+ */
45
+ debug?: (msg: string) => any;
46
+ /**
47
+ * 컴시간알리미의 앱 버전입니다.
48
+ *
49
+ * 기본값은 2.11입니다.
50
+ */
51
+ appVersion?: string;
52
+ }
53
+ export type ComciganSearched = {
54
+ /**
55
+ * 학교의 지역입니다.
56
+ */
57
+ region: string;
58
+ /**
59
+ * 학교의 이름입니다.
60
+ */
61
+ name: string;
62
+ /**
63
+ * 학교의 코드입니다.
64
+ */
65
+ code: number;
66
+ };
67
+ export type ComciganTimetableObject = {
68
+ /**
69
+ * 과목입니다.
70
+ */
71
+ subject: string;
72
+ /**
73
+ * 교사 성명입니다.
74
+ */
75
+ teacher: string;
76
+ /**
77
+ * 만약 변경되었을때 이 값이 주어집니다.
78
+ */
79
+ original?: {
80
+ /**
81
+ * 과목입니다.
82
+ */
83
+ subject: string;
84
+ /**
85
+ * 교사 성명입니다.
86
+ */
87
+ teacher: string;
88
+ };
89
+ };
90
+ export type ComciganTimetable = {
91
+ /**
92
+ * 컴시간알리미 앱의 최신 버전입니다.
93
+ */
94
+ latestVersion: string;
95
+ /**
96
+ * 수정일입니다.
97
+ */
98
+ changed: string;
99
+ /**
100
+ * 시간표입니다.
101
+ */
102
+ timetable: ComciganTimetableObject[][];
103
+ };
104
+ export default class Comcigan {
105
+ private _options;
106
+ private _cache;
107
+ private mSb;
108
+ private mTh;
109
+ private unusable;
110
+ private request;
111
+ private EUC_KR_encodeURI;
112
+ /**
113
+ * 파서를 초기화 합니다.
114
+ * @param options 파서의 옵션입니다.
115
+ */
116
+ constructor(options?: ComciganInitializeType);
117
+ /**
118
+ * 학교를 검색합니다.
119
+ * 마지막 "없으면 추가 검색 하세요" 문구는 빠져서 나옵니다.
120
+ * @param query 검색어
121
+ * @returns 검색된 학교들
122
+ */
123
+ SearchSchool(query: string): Promise<ComciganSearched[]>;
124
+ /**
125
+ * 시간표를 가져옵니다.
126
+ *
127
+ * @param schoolCode
128
+ * @param criteria
129
+ */
130
+ GetTimetable(options: GetTimetableOptions): Promise<ComciganTimetable | undefined>;
131
+ /**
132
+ * 학급 목록을 가져옵니다.
133
+ *
134
+ * @param schoolCode 학교 코드입니다.
135
+ * @returns (학년)-(반) 문자열이 모인 배열
136
+ */
137
+ GetClassList(schoolCode: number): Promise<string[]>;
138
+ }
package/dist/index.js ADDED
@@ -0,0 +1,216 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import axios from 'axios';
11
+ import iconv from 'iconv-lite';
12
+ import Cache from './cache.js';
13
+ //#endregion
14
+ export default class Comcigan {
15
+ mSb(mm, m2) { if (m2 == 100) {
16
+ return mm % m2;
17
+ } return Math.floor(mm / m2); }
18
+ mTh(mm, m2) { if (m2 == 100) {
19
+ return Math.floor(mm / m2);
20
+ } return mm % m2; }
21
+ unusable(object, array) {
22
+ if (object === array[0])
23
+ return;
24
+ return object;
25
+ }
26
+ request(route, doNotParse) {
27
+ return __awaiter(this, void 0, void 0, function* () {
28
+ if (this._cache.has(route)) {
29
+ this._options.debug ? this._options.debug(`[request] Return cache with id registered as ${route}`) : 0;
30
+ return this._cache.get(route);
31
+ }
32
+ this._options.debug ? this._options.debug(`[request] Requesting to http://comci.kr:4081/${route}`) : 0;
33
+ const r = yield axios.get(`http://comci.kr:4081/${route}`, Object.assign({}, (this._options.doNotThrow && { "validateStatus": () => true })));
34
+ if (doNotParse) {
35
+ if (this._options.cacheMs && this._options.cacheMs !== 0) {
36
+ this._options.debug ? this._options.debug(`[request] Registered cache with id ${route}`) : 0;
37
+ this._cache.register(route, r.data, this._options.cacheMs);
38
+ }
39
+ return r.data;
40
+ }
41
+ const data = JSON.parse(r.data.slice(0, r.data.indexOf("}") + 1));
42
+ if (this._options.cacheMs && this._options.cacheMs !== 0) {
43
+ this._options.debug ? this._options.debug(`[request] Registered cache with id ${route}`) : 0;
44
+ this._cache.register(route, data, this._options.cacheMs);
45
+ }
46
+ return data;
47
+ });
48
+ }
49
+ EUC_KR_encodeURI(str) {
50
+ const buffer = iconv.encode(str, 'euc-kr');
51
+ return Array.from(buffer)
52
+ .map((byte) => '%' + byte.toString(16).toUpperCase().padStart(2, '0'))
53
+ .join('');
54
+ }
55
+ /**
56
+ * 파서를 초기화 합니다.
57
+ * @param options 파서의 옵션입니다.
58
+ */
59
+ constructor(options) {
60
+ this._options = {
61
+ "cacheMs": 0,
62
+ "doNotThrow": false,
63
+ "appVersion": "2.11",
64
+ };
65
+ this._cache = new Cache();
66
+ this._options = Object.assign(Object.assign({}, this._options), options);
67
+ }
68
+ /**
69
+ * 학교를 검색합니다.
70
+ * 마지막 "없으면 추가 검색 하세요" 문구는 빠져서 나옵니다.
71
+ * @param query 검색어
72
+ * @returns 검색된 학교들
73
+ */
74
+ SearchSchool(query) {
75
+ return __awaiter(this, void 0, void 0, function* () {
76
+ const r = yield this.request(`sc_${this.EUC_KR_encodeURI(query)}`);
77
+ return r.학교검색.map(v => ({
78
+ "region": v[1],
79
+ "name": v[2],
80
+ "code": v[3]
81
+ })).filter(v => v.code !== 0);
82
+ });
83
+ }
84
+ /**
85
+ * 시간표를 가져옵니다.
86
+ *
87
+ * @param schoolCode
88
+ * @param criteria
89
+ */
90
+ GetTimetable(options) {
91
+ return __awaiter(this, void 0, void 0, function* () {
92
+ var _a, _b, _c, _d, _e, _f, _g;
93
+ const { schoolCode, criteria, grade, classN, without8th } = options;
94
+ const { appVersion } = this._options;
95
+ const str = `36174_${schoolCode}_1_4_0_3_${appVersion}`;
96
+ const route = (str.substring(9) + str.substring(0, 9)).split("").reverse().join("");
97
+ const data = yield this.request(`7813?${route}`, true);
98
+ const [latestVersion, step1] = data.split("^");
99
+ const edited = step1.substring(0, step1.indexOf("{"));
100
+ const step2 = step1.slice(step1.indexOf("{"));
101
+ const json = JSON.parse(step2.slice(0, step2.indexOf("}") + 1));
102
+ const WEEKDAY = ["월", "화", "수", "목", "금"];
103
+ const sep = (_a = json.분리) !== null && _a !== void 0 ? _a : 100;
104
+ if (!json.시간표)
105
+ return undefined;
106
+ // 시간표[학년][반][요일][교시]
107
+ const origin = json.시간표[grade][classN];
108
+ const today = json.학급시간표[grade][classN];
109
+ const toReturn = [];
110
+ if (criteria === "period") {
111
+ for (let weekday = 1; weekday < WEEKDAY.length + 1; weekday++) {
112
+ const weekdayList = [];
113
+ for (let period = 1; period < (without8th ? 8 : 9); period++) {
114
+ const o = origin[weekday][period];
115
+ const t = today[weekday][period];
116
+ if (o === undefined || t === undefined) {
117
+ weekdayList.push({
118
+ "subject": "-",
119
+ "teacher": "-"
120
+ });
121
+ continue;
122
+ }
123
+ const originSubject = json.과목명[this.mSb(o, sep) % sep];
124
+ const originTeacher = json.성명[this.mTh(o, sep) % sep];
125
+ if (o === t) {
126
+ weekdayList.push({
127
+ "subject": (_b = this.unusable(originSubject, json.과목명)) !== null && _b !== void 0 ? _b : "-",
128
+ "teacher": (_c = this.unusable(originTeacher, json.성명)) !== null && _c !== void 0 ? _c : "-"
129
+ });
130
+ continue;
131
+ }
132
+ const changedSubject = json.과목명[this.mSb(t, sep) % sep];
133
+ const changedTeacher = json.성명[this.mTh(t, sep) % sep];
134
+ weekdayList.push({
135
+ "subject": (_d = this.unusable(changedSubject, json.과목명)) !== null && _d !== void 0 ? _d : "-",
136
+ "teacher": (_e = this.unusable(changedTeacher, json.성명)) !== null && _e !== void 0 ? _e : "-",
137
+ "original": {
138
+ "subject": (_f = this.unusable(originSubject, json.과목명)) !== null && _f !== void 0 ? _f : "-",
139
+ "teacher": (_g = this.unusable(originTeacher, json.성명)) !== null && _g !== void 0 ? _g : "-",
140
+ }
141
+ });
142
+ }
143
+ toReturn.push(weekdayList);
144
+ }
145
+ }
146
+ else {
147
+ for (let period = 1; period < (without8th ? 8 : 9); period++) {
148
+ const periodList = [];
149
+ for (let weekday = 1; weekday < WEEKDAY.length + 1; weekday++) {
150
+ const o = origin[weekday][period];
151
+ const t = today[weekday][period];
152
+ if (!o || !t) {
153
+ periodList.push({
154
+ "subject": "-",
155
+ "teacher": "-"
156
+ });
157
+ continue;
158
+ }
159
+ const originSubject = json.과목명[this.mSb(o, sep) % sep];
160
+ const originTeacher = json.성명[this.mTh(o, sep) % sep];
161
+ if (o === t) {
162
+ periodList.push({
163
+ "subject": originSubject,
164
+ "teacher": originTeacher
165
+ });
166
+ continue;
167
+ }
168
+ const changedSubject = json.과목명[this.mSb(t, sep) % sep];
169
+ const changedTeacher = json.성명[this.mTh(t, sep) % sep];
170
+ periodList.push({
171
+ "subject": originSubject,
172
+ "teacher": originTeacher,
173
+ "original": {
174
+ "subject": changedSubject,
175
+ "teacher": changedTeacher
176
+ }
177
+ });
178
+ }
179
+ toReturn.push(periodList);
180
+ }
181
+ }
182
+ return {
183
+ "changed": edited,
184
+ latestVersion,
185
+ "timetable": toReturn
186
+ };
187
+ });
188
+ }
189
+ /**
190
+ * 학급 목록을 가져옵니다.
191
+ *
192
+ * @param schoolCode 학교 코드입니다.
193
+ * @returns (학년)-(반) 문자열이 모인 배열
194
+ */
195
+ GetClassList(schoolCode) {
196
+ return __awaiter(this, void 0, void 0, function* () {
197
+ const str = `36174_${schoolCode}_1_4_0_3_1.00`;
198
+ const route = (str.substring(9) + str.substring(0, 9)).split("").reverse().join("");
199
+ const data = yield this.request(`7813?${route}`, true);
200
+ const step1 = data.split("^")[1];
201
+ const step2 = step1.slice(step1.indexOf("{"));
202
+ const json = JSON.parse(step2.slice(0, step2.indexOf("}") + 1));
203
+ const rawClasses = json.학급수;
204
+ if (!rawClasses)
205
+ return [];
206
+ const toReturn = [];
207
+ for (let g = 1; g < rawClasses.length; g++) {
208
+ for (let c = 1; c < rawClasses[g] + 1; c++) {
209
+ toReturn.push(`${g}-${c}`);
210
+ }
211
+ }
212
+ return toReturn;
213
+ });
214
+ }
215
+ }
216
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "parse-comcigan",
3
- "version": "0.0.5",
3
+ "version": "0.2.0",
4
4
  "description": "컴시간 알리미에서 시간표를 가져오는 라이브러리입니다.",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -11,7 +11,9 @@
11
11
  "pack": "npm run clean && npm run build",
12
12
  "build": "tsc",
13
13
  "clean": "tsc --build --clean",
14
- "dev": "nodemon --exec ts-node src/index.ts"
14
+ "dev": "nodemon --exec ts-node src/index.ts",
15
+ "test": "npm run pack && node \"test.js\"",
16
+ "publish": "npm run pack && npm publish"
15
17
  },
16
18
  "devDependencies": {
17
19
  "@types/node": "^22.15.30",
package/src/index.ts CHANGED
@@ -48,6 +48,12 @@ export interface ComciganInitializeType {
48
48
  * 기본값은 없습니다.
49
49
  */
50
50
  debug?: (msg: string) => any;
51
+ /**
52
+ * 컴시간알리미의 앱 버전입니다.
53
+ *
54
+ * 기본값은 2.11입니다.
55
+ */
56
+ appVersion?: string;
51
57
  }
52
58
  export type ComciganSearched = {
53
59
  /**
@@ -105,13 +111,20 @@ export type ComciganTimetable = {
105
111
  export default class Comcigan {
106
112
  private _options: ComciganInitializeType = {
107
113
  "cacheMs": 0,
108
- "doNotThrow": false
114
+ "doNotThrow": false,
115
+ "appVersion": "2.11",
109
116
  };
110
117
  private _cache = new Cache();
111
118
 
112
119
  private mSb(mm: number, m2: number) { if (m2 == 100) { return mm % m2; } return Math.floor(mm / m2); }
113
120
  private mTh(mm: number, m2: number) { if (m2 == 100) { return Math.floor(mm / m2); } return mm % m2; }
114
121
 
122
+ private unusable(object: any, array: any[]) {
123
+ if (object === array[0]) return;
124
+
125
+ return object;
126
+ }
127
+
115
128
  private async request<T = any>(route: string, doNotParse?: boolean): Promise<T> {
116
129
  if (this._cache.has(route)) {
117
130
  this._options.debug ? this._options.debug(`[request] Return cache with id registered as ${route}`) : 0;
@@ -181,8 +194,9 @@ export default class Comcigan {
181
194
  */
182
195
  public async GetTimetable(options: GetTimetableOptions): Promise<ComciganTimetable | undefined> {
183
196
  const { schoolCode, criteria, grade, classN, without8th } = options;
197
+ const { appVersion } = this._options;
184
198
 
185
- const str = `36174_${schoolCode}_1_4_0_3_1.00`;
199
+ const str = `36174_${schoolCode}_1_4_0_3_${appVersion}`;
186
200
  const route = (str.substring(9) + str.substring(0, 9)).split("").reverse().join("");
187
201
  const data = await this.request<string>(`7813?${route}`, true);
188
202
 
@@ -209,7 +223,7 @@ export default class Comcigan {
209
223
  const o = origin[weekday][period];
210
224
  const t = today[weekday][period];
211
225
 
212
- if (!o || !t) {
226
+ if (o === undefined || t === undefined) {
213
227
  weekdayList.push({
214
228
  "subject": "-",
215
229
  "teacher": "-"
@@ -222,8 +236,8 @@ export default class Comcigan {
222
236
 
223
237
  if (o === t) {
224
238
  weekdayList.push({
225
- "subject": originSubject,
226
- "teacher": originTeacher
239
+ "subject": this.unusable(originSubject, json.과목명) ?? "-",
240
+ "teacher": this.unusable(originTeacher, json.성명) ?? "-"
227
241
  });
228
242
  continue;
229
243
  }
@@ -232,11 +246,11 @@ export default class Comcigan {
232
246
  const changedTeacher = json.성명[this.mTh(t, sep) % sep];
233
247
 
234
248
  weekdayList.push({
235
- "subject": originSubject,
236
- "teacher": originTeacher,
249
+ "subject": this.unusable(changedSubject, json.과목명) ?? "-",
250
+ "teacher": this.unusable(changedTeacher, json.성명) ?? "-",
237
251
  "original": {
238
- "subject": changedSubject,
239
- "teacher": changedTeacher
252
+ "subject": this.unusable(originSubject, json.과목명) ?? "-",
253
+ "teacher": this.unusable(originTeacher, json.성명) ?? "-",
240
254
  }
241
255
  });
242
256
  }