@ihabdevteam/core 0.101.0 → 0.103.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.
@@ -1333,7 +1333,7 @@ export declare function copyText(text: string): Promise<boolean>;
1333
1333
  *
1334
1334
  * 값은 손으로 적고 `test/coreVersion.test.ts` 가 package.json 과 어긋나면 운다.
1335
1335
  */
1336
- export declare const CORE_VERSION = "0.101.0";
1336
+ export declare const CORE_VERSION = "0.103.0";
1337
1337
 
1338
1338
  /** @public */
1339
1339
  declare const coreDefault: Record<string, unknown>;
@@ -7,6 +7,7 @@ import { useWindowEvent } from './useWindowEvent';
7
7
  import { useWordAttributeFilterKeys, buildGradeSection, buildPartOfSpeechSection, buildWordTypeSection } from './useWordAttributeFilter';
8
8
  import { matchesFilters } from '../utils/phonemePairSearch';
9
9
  import { hasSel } from '../utils/wordContrast';
10
+ import { phoneticLabel } from '../utils/phonemeGroups';
10
11
  /* 글자↔발음 변환과 음절 상수는 wordTrainingFilterModel.ts 로 옮겼다(React 없는 순수 계층).
11
12
  **공개하던 이름은 여기서 그대로 다시 내보낸다** — 가져다 쓰는 쪽은 바뀌지 않는다. */
12
13
  import { valueToJamos, NO_CODA, SYLLABLE_MIN, SYLLABLE_COUNTS, syllableValue, parseSyllableValue, syllableToFilter, PART_JAMOS, PHONEME_CLUSTERS, convertComposition, EMPTY_COMPOSITION, } from './wordTrainingFilterModel';
@@ -356,9 +357,10 @@ export function useWordTrainingFilter(groupKey, caps, opts) {
356
357
  };
357
358
  if (phonemeView === 'pron') {
358
359
  // 클러스터별 버튼 그룹. 병합 버튼(다자모)은 자모 중 하나라도 viable 하면 활성.
359
- // tooltip(조음 정보)은 버튼 hover 시 노출(대립쌍표와 동일).
360
- const groups = PHONEME_CLUSTERS[part].map(cluster => cluster.map(({ v, tooltip }) => {
360
+ // tooltip(조음 정보)은 버튼 hover 시 노출(대립쌍표와 동일). 글은 여기서 로케일대로 만든다.
361
+ const groups = PHONEME_CLUSTERS[part].map(cluster => cluster.map(({ v, phonetic }) => {
361
362
  const jamos = valueToJamos(v);
363
+ const tooltip = phoneticLabel(t, phonetic);
362
364
  const disabled = lockJong || !jamos.some(j => viable[part].has(j));
363
365
  // 병합(다자모) 버튼은 labels 배열로 넘겨 각 자모를 개별 span으로 렌더(표준 라벨 간격).
364
366
  return jamos.length > 1
@@ -1,5 +1,5 @@
1
1
  import type { CompositionPart } from '../utils/koreanSyllable';
2
- import { type PhonemeGroupItem } from '../utils/phonemeGroups';
2
+ import { type PhonemeGroupItem, type PhoneticFeature } from '../utils/phonemeGroups';
3
3
  export declare const FULL_CHOSEONG: ("ㄱ" | "ㄲ" | "ㄴ" | "ㄷ" | "ㄸ" | "ㄹ" | "ㅁ" | "ㅂ" | "ㅃ" | "ㅅ" | "ㅆ" | "ㅇ" | "ㅈ" | "ㅉ" | "ㅊ" | "ㅋ" | "ㅌ" | "ㅍ" | "ㅎ")[];
4
4
  export declare const FULL_JUNGSEONG: ("ㅏ" | "ㅐ" | "ㅑ" | "ㅒ" | "ㅓ" | "ㅔ" | "ㅕ" | "ㅖ" | "ㅗ" | "ㅘ" | "ㅙ" | "ㅚ" | "ㅛ" | "ㅜ" | "ㅝ" | "ㅞ" | "ㅟ" | "ㅠ" | "ㅡ" | "ㅢ" | "ㅣ")[];
5
5
  export declare const FULL_JONGSEONG: ("ㄱ" | "ㄲ" | "ㄴ" | "ㄷ" | "ㄹ" | "ㅁ" | "ㅂ" | "ㅅ" | "ㅆ" | "ㅇ" | "ㅈ" | "ㅊ" | "ㅋ" | "ㅌ" | "ㅍ" | "ㅎ" | "ㄳ" | "ㄵ" | "ㄶ" | "ㄺ" | "ㄻ" | "ㄼ" | "ㄽ" | "ㄾ" | "ㄿ" | "ㅀ" | "ㅄ")[];
@@ -22,15 +22,18 @@ export declare function syllableToFilter(syllable: number): number[];
22
22
  /** 글자 입력 — 구성요소 종류별 전체 자모 목록(사전순) */
23
23
  export declare const PART_JAMOS: Record<CompositionPart, string[]>;
24
24
  /**
25
- * 발음 입력 — 조음/음성 특성별 클러스터. 각 항목이 버튼 1개(v=값, tooltip=조음 정보)이며,
25
+ * 발음 입력 — 조음/음성 특성별 클러스터. 각 항목이 버튼 1개(v=값, phonetic=조음 정보)이며,
26
26
  * 간격으로 클러스터를 구분한다. 다자모 값(예: 'ㅔㅐ')은 동음 병합 버튼으로 해당 자모 전부를 매칭(OR)한다.
27
- * 조음 정보(양순음 등)는 대립쌍표와 동일하게 버튼 hover 시 tooltip으로 노출한다.
27
+ * 조음 정보(양순음 등)는 대립쌍표와 동일하게 버튼 hover 시 tooltip으로 노출한다 — 글은 그리는 자리에서
28
+ * phoneticLabel(t, phonetic)로 로케일에 맞춰 만든다(여기는 React 없는 층이라 t 가 없다).
28
29
  *
29
30
  * 그룹 데이터 자체는 utils/phonemeGroups의 표준 단일 출처(PHONEME_GROUPS)에서 파생한다(대립쌍표와 공용).
30
31
  * 훈련측 값 인코딩은 병합 문자열(v = jamos.join('')) — 렌더 시 valueToJamos로 각 자모를 복원한다.
31
32
  */
32
33
  export type PronItem = {
33
34
  v: string;
35
+ phonetic: PhoneticFeature;
36
+ /** @deprecated 한국어 고정 — `phoneticLabel(t, phonetic)` 을 쓸 것. 다음 판에 걷는다. */
34
37
  tooltip: string;
35
38
  };
36
39
  export declare const toPronRows: (rows: PhonemeGroupItem[][]) => PronItem[][];
@@ -47,7 +47,7 @@ export const PART_JAMOS = {
47
47
  jung: FULL_JUNGSEONG,
48
48
  jong: FULL_JONGSEONG,
49
49
  };
50
- export const toPronRows = (rows) => rows.map(row => row.map(({ jamos, tooltip }) => ({ v: jamos.join(''), tooltip })));
50
+ export const toPronRows = (rows) => rows.map(row => row.map(({ jamos, phonetic, tooltip }) => ({ v: jamos.join(''), phonetic, tooltip })));
51
51
  export const PHONEME_CLUSTERS = {
52
52
  cho: toPronRows(PHONEME_GROUPS.cho),
53
53
  jung: toPronRows(PHONEME_GROUPS.jung),
@@ -93,6 +93,29 @@
93
93
  "table": "Table",
94
94
  "recent": "Last",
95
95
  "problem": "Question"
96
+ },
97
+ "phonetics": {
98
+ "place": {
99
+ "labial": "Bilabial",
100
+ "alveolar": "Alveolar",
101
+ "palatal": "Palatal",
102
+ "velar": "Velar",
103
+ "glottal": "Glottal"
104
+ },
105
+ "vowel": {
106
+ "frontHigh": "Front high vowel",
107
+ "backHighUnrounded": "Back high unrounded vowel",
108
+ "backHighRounded": "Back high rounded vowel",
109
+ "frontMid": "Front mid vowel",
110
+ "backMidUnrounded": "Back mid unrounded vowel",
111
+ "backMidRounded": "Back mid rounded vowel",
112
+ "low": "Low vowel"
113
+ },
114
+ "glide": {
115
+ "j": "j-glide",
116
+ "w": "w-glide",
117
+ "velar": "ɰ-glide"
118
+ }
96
119
  }
97
120
  },
98
121
  "plan": {
@@ -4008,6 +4031,32 @@
4008
4031
  "goal": "Goal {{pct}}%",
4009
4032
  "suggestPair": "Pair table: {{a}} vs {{b}}",
4010
4033
  "suggestWords": "Word table with {{jamo}}",
4011
- "moreWords": "and {{n}} more"
4034
+ "moreWords": "and {{n}} more",
4035
+ "devOrder": "Ordered by acquisition",
4036
+ "devFull": "Fully acquired by {{age}}",
4037
+ "devMaster": "Mastered by {{age}}",
4038
+ "devLate": "Late for age",
4039
+ "devInStage": "In the mastery stage",
4040
+ "devNotYet": "Not expected yet",
4041
+ "devNone": "No acquisition data",
4042
+ "ageBasis": "Based on age {{age}}",
4043
+ "devSummary": "{{m}} of {{n}} weak sounds are {{group}}",
4044
+ "place": {
4045
+ "labial": "Bilabial",
4046
+ "alveolar": "Alveolar",
4047
+ "palatal": "Palatal",
4048
+ "velar": "Velar",
4049
+ "glottal": "Glottal"
4050
+ },
4051
+ "manner": {
4052
+ "nasal": "Nasal",
4053
+ "plosive": "Plosive",
4054
+ "liquid": "Liquid",
4055
+ "fricative": "Fricative",
4056
+ "affricate": "Affricate"
4057
+ },
4058
+ "suggestSentence": "Sentence set {{name}} ({{jamo}} ×{{n}})",
4059
+ "sentenceMiss": "Words confused in sentence training",
4060
+ "sentenceMissSub": "Where the chosen option differed from the answer — from story and ordering records"
4012
4061
  }
4013
4062
  }
@@ -91,6 +91,29 @@
91
91
  "table": "표",
92
92
  "recent": "최근",
93
93
  "problem": "문제"
94
+ },
95
+ "phonetics": {
96
+ "place": {
97
+ "labial": "양순음",
98
+ "alveolar": "치조음",
99
+ "palatal": "경구개음",
100
+ "velar": "연구개음",
101
+ "glottal": "성문음"
102
+ },
103
+ "vowel": {
104
+ "frontHigh": "전설 고모음",
105
+ "backHighUnrounded": "후설 고모음 평순",
106
+ "backHighRounded": "후설 고모음 원순",
107
+ "frontMid": "전설 중모음",
108
+ "backMidUnrounded": "후설 중모음 평순",
109
+ "backMidRounded": "후설 중모음 원순",
110
+ "low": "저모음"
111
+ },
112
+ "glide": {
113
+ "j": "j활음",
114
+ "w": "w활음",
115
+ "velar": "ɰ활음"
116
+ }
94
117
  }
95
118
  },
96
119
  "plan": {
@@ -4005,6 +4028,32 @@
4005
4028
  "goal": "목표 {{pct}}%",
4006
4029
  "suggestPair": "{{a}}·{{b}} 변별 대립쌍표",
4007
4030
  "suggestWords": "{{jamo}} 든 낱말 단어표",
4008
- "moreWords": "외 {{n}}개"
4031
+ "moreWords": "외 {{n}}개",
4032
+ "devOrder": "발달 순서 기준",
4033
+ "devFull": "{{age}}세 완전습득",
4034
+ "devMaster": "{{age}}세 숙달",
4035
+ "devLate": "연령 대비 늦음",
4036
+ "devInStage": "숙달 단계",
4037
+ "devNotYet": "아직 이른 소리",
4038
+ "devNone": "발달 자료 없음",
4039
+ "ageBasis": "만 {{age}}세 기준",
4040
+ "devSummary": "약한 소리 {{n}}개 중 {{m}}개가 {{group}}",
4041
+ "place": {
4042
+ "labial": "양순음",
4043
+ "alveolar": "치조음",
4044
+ "palatal": "경구개음",
4045
+ "velar": "연구개음",
4046
+ "glottal": "성문음"
4047
+ },
4048
+ "manner": {
4049
+ "nasal": "비음",
4050
+ "plosive": "파열음",
4051
+ "liquid": "유음",
4052
+ "fricative": "마찰음",
4053
+ "affricate": "파찰음"
4054
+ },
4055
+ "suggestSentence": "문장 세트 {{name}} ({{jamo}} {{n}}번)",
4056
+ "sentenceMiss": "문장훈련에서 헷갈린 낱말",
4057
+ "sentenceMissSub": "정답 보기와 고른 보기가 다른 낱말 — 짧은 이야기·문장 순서 기록에서"
4009
4058
  }
4010
4059
  }
@@ -11,12 +11,44 @@
11
11
  * - 대립쌍표: 아이템 value = jamos[0](대표 자모), 병합 버튼은 labels = jamos 전체로 표시.
12
12
  * - 단어훈련: 아이템 v = jamos.join('')(병합 문자열), 렌더 시 valueToJamos로 labels 복원.
13
13
  * 동음 병합 버튼(예: ㅔ/ㅐ)의 jamos 순서는 두 소비처가 공유하므로 여기서 한 번만 정의한다.
14
+ *
15
+ * **조음 정보는 글자가 아니라 식별자로 든다(`phonetic`).** 예전에는 '양순음' 같은 한국어를
16
+ * 그대로 박아 두어 영어 화면의 툴팁에도 한국어가 떴다. 글은 그리는 자리에서
17
+ * `phoneticLabel(t, item.phonetic)` 로 만든다 — 사전 열쇠는 `common.phonetics.*`.
14
18
  */
19
+ /** 자음의 조음 위치. 사전 열쇠 `common.phonetics.place.<id>` 와 이름이 같다. */
20
+ export type ArticulationPlace = 'labial' | 'alveolar' | 'palatal' | 'velar' | 'glottal';
21
+ /** 모음의 혀 자리(전후·높낮이·입술). 사전 열쇠 `common.phonetics.vowel.<id>`. */
22
+ export type VowelClass = 'frontHigh' | 'backHighUnrounded' | 'backHighRounded' | 'frontMid' | 'backMidUnrounded' | 'backMidRounded' | 'low';
23
+ /** 이중모음의 활음. `velar` 는 ɰ(ㅢ). 사전 열쇠 `common.phonetics.glide.<id>`. */
24
+ export type Glide = 'j' | 'w' | 'velar';
25
+ /** 버튼 하나의 조음 정보 — 자음은 위치, 모음은 혀 자리(+활음). */
26
+ export type PhoneticFeature = {
27
+ place: ArticulationPlace;
28
+ } | {
29
+ vowel: VowelClass;
30
+ glide?: Glide;
31
+ };
15
32
  export interface PhonemeGroupItem {
16
33
  /** 이 버튼이 대표/매칭하는 자모들. 단일 버튼이면 1개, 동음 병합 버튼이면 여러 개(예: ['ㅔ','ㅐ']). */
17
34
  jamos: string[];
18
- /** 조음 정보 등 hover 시 노출할 tooltip 텍스트. */
35
+ /** 조음 정보 식별자. hover 툴팁 글은 `phoneticLabel(t, phonetic)` 로 만든다. */
36
+ phonetic: PhoneticFeature;
37
+ /**
38
+ * 조음 정보의 **한국어 고정** 글.
39
+ * @deprecated 로케일을 따르지 않는다 — `phoneticLabel(t, item.phonetic)` 을 쓸 것. 다음 판에 걷는다.
40
+ */
19
41
  tooltip: string;
20
42
  }
43
+ /** `phoneticLabel` 이 받는 t — (열쇠, 옵션) => 글 꼴이면 무엇이든(i18next·react-i18next 의 t). */
44
+ type Translate = (key: string, options: {
45
+ defaultValue: string;
46
+ }) => string;
47
+ /**
48
+ * 조음 정보를 화면 글로. 모음에 활음이 있으면 `전설 고모음 · w활음` 처럼 가운뎃점으로 잇는다.
49
+ * @public
50
+ */
51
+ export declare function phoneticLabel(t: Translate, f: PhoneticFeature): string;
21
52
  /** @internal 발음 선택 표준 그룹. cho/jung/jong 각각 클러스터(행)들의 배열. */
22
53
  export declare const PHONEME_GROUPS: Record<'cho' | 'jung' | 'jong', PhonemeGroupItem[][]>;
54
+ export {};
@@ -1,29 +1,83 @@
1
- /** 자음 행: 같은 tooltip(조음 위치)을 공유하는 단일 자모 버튼들. */
2
- const consonantRow = (tooltip, jamos) => jamos.map(j => ({ jamos: [j], tooltip }));
1
+ /**
2
+ * 발음(음소) 선택 UI의 **표준 그룹 데이터 단일 출처**.
3
+ * 대립쌍표(WordPairsPage)와 단어훈련(useWordTrainingFilter)이 각자 중복 정의하던
4
+ * PHONEME_SECTIONS / PHONEME_CLUSTERS를 하나로 합친 것.
5
+ *
6
+ * 각 파트(cho/jung/jong)는 "시각적 클러스터(행)"의 배열이고, 각 행은 버튼 아이템의 배열이다.
7
+ * 자음 클러스터는 조음 위치별로 묶고 **평음-경음-격음(-비음/유음)** 순서로 나열한다
8
+ * (예: ㅂ-ㅃ-ㅍ-ㅁ, ㄷ-ㄸ-ㅌ, ㄱ-ㄲ-ㅋ).
9
+ *
10
+ * 소비처는 이 데이터에서 자기 값 인코딩을 파생한다 — 매칭 로직은 각 소비처가 그대로 소유한다:
11
+ * - 대립쌍표: 아이템 value = jamos[0](대표 자모), 병합 버튼은 labels = jamos 전체로 표시.
12
+ * - 단어훈련: 아이템 v = jamos.join('')(병합 문자열), 렌더 시 valueToJamos로 labels 복원.
13
+ * 동음 병합 버튼(예: ㅔ/ㅐ)의 jamos 순서는 두 소비처가 공유하므로 여기서 한 번만 정의한다.
14
+ *
15
+ * **조음 정보는 글자가 아니라 식별자로 든다(`phonetic`).** 예전에는 '양순음' 같은 한국어를
16
+ * 그대로 박아 두어 영어 화면의 툴팁에도 한국어가 떴다. 글은 그리는 자리에서
17
+ * `phoneticLabel(t, item.phonetic)` 로 만든다 — 사전 열쇠는 `common.phonetics.*`.
18
+ */
19
+ /* 열쇠를 **글자로** 적어 둔다 — `t(\`…${id}\`)` 로 조립하면 사전 대조 시험(i18nKeysExist)과
20
+ 소비자의 죽은 열쇠 지킴이가 부르는 자리를 못 본다. 기본값은 한국어(인스턴스 없는 소비자용). */
21
+ const PLACE_LABEL = {
22
+ labial: t => t('common.phonetics.place.labial', { defaultValue: '양순음' }),
23
+ alveolar: t => t('common.phonetics.place.alveolar', { defaultValue: '치조음' }),
24
+ palatal: t => t('common.phonetics.place.palatal', { defaultValue: '경구개음' }),
25
+ velar: t => t('common.phonetics.place.velar', { defaultValue: '연구개음' }),
26
+ glottal: t => t('common.phonetics.place.glottal', { defaultValue: '성문음' }),
27
+ };
28
+ const VOWEL_LABEL = {
29
+ frontHigh: t => t('common.phonetics.vowel.frontHigh', { defaultValue: '전설 고모음' }),
30
+ backHighUnrounded: t => t('common.phonetics.vowel.backHighUnrounded', { defaultValue: '후설 고모음 평순' }),
31
+ backHighRounded: t => t('common.phonetics.vowel.backHighRounded', { defaultValue: '후설 고모음 원순' }),
32
+ frontMid: t => t('common.phonetics.vowel.frontMid', { defaultValue: '전설 중모음' }),
33
+ backMidUnrounded: t => t('common.phonetics.vowel.backMidUnrounded', { defaultValue: '후설 중모음 평순' }),
34
+ backMidRounded: t => t('common.phonetics.vowel.backMidRounded', { defaultValue: '후설 중모음 원순' }),
35
+ low: t => t('common.phonetics.vowel.low', { defaultValue: '저모음' }),
36
+ };
37
+ const GLIDE_LABEL = {
38
+ j: t => t('common.phonetics.glide.j', { defaultValue: 'j활음' }),
39
+ w: t => t('common.phonetics.glide.w', { defaultValue: 'w활음' }),
40
+ velar: t => t('common.phonetics.glide.velar', { defaultValue: 'ɰ활음' }),
41
+ };
42
+ /**
43
+ * 조음 정보를 화면 글로. 모음에 활음이 있으면 `전설 고모음 · w활음` 처럼 가운뎃점으로 잇는다.
44
+ * @public
45
+ */
46
+ export function phoneticLabel(t, f) {
47
+ if ('place' in f)
48
+ return PLACE_LABEL[f.place](t);
49
+ const v = VOWEL_LABEL[f.vowel](t);
50
+ return f.glide ? `${v} · ${GLIDE_LABEL[f.glide](t)}` : v;
51
+ }
52
+ /** 기본값만 돌려주는 t — 옛 `tooltip`(한국어 고정)을 같은 표에서 만들어 두 글이 갈라지지 않게 한다. */
53
+ const 한국어 = (_key, { defaultValue }) => defaultValue;
54
+ const item = (jamos, phonetic) => ({ jamos, phonetic, tooltip: phoneticLabel(한국어, phonetic) });
55
+ /** 자음 행: 같은 조음 위치를 공유하는 단일 자모 버튼들. */
56
+ const consonantRow = (place, jamos) => jamos.map(j => item([j], { place }));
3
57
  /** 모음/병합 아이템: `chars`가 여러 글자면 동음 병합 버튼(예: 'ㅔㅐ' → ['ㅔ','ㅐ']). */
4
- const vowel = (chars, tooltip) => ({ jamos: [...chars], tooltip });
58
+ const vowel = (chars, v, glide) => item([...chars], glide ? { vowel: v, glide } : { vowel: v });
5
59
  /** @internal 발음 선택 표준 그룹. cho/jung/jong 각각 클러스터(행)들의 배열. */
6
60
  export const PHONEME_GROUPS = {
7
61
  cho: [
8
- consonantRow('양순음', ['ㅂ', 'ㅃ', 'ㅍ', 'ㅁ']),
9
- consonantRow('치조음', ['ㄷ', 'ㄸ', 'ㅌ', 'ㄴ', 'ㄹ']),
10
- consonantRow('치조음', ['ㅅ', 'ㅆ']),
11
- consonantRow('경구개음', ['ㅈ', 'ㅉ', 'ㅊ']),
12
- consonantRow('연구개음', ['ㄱ', 'ㄲ', 'ㅋ']),
13
- consonantRow('성문음', ['ㅎ']),
62
+ consonantRow('labial', ['ㅂ', 'ㅃ', 'ㅍ', 'ㅁ']),
63
+ consonantRow('alveolar', ['ㄷ', 'ㄸ', 'ㅌ', 'ㄴ', 'ㄹ']),
64
+ consonantRow('alveolar', ['ㅅ', 'ㅆ']),
65
+ consonantRow('palatal', ['ㅈ', 'ㅉ', 'ㅊ']),
66
+ consonantRow('velar', ['ㄱ', 'ㄲ', 'ㅋ']),
67
+ consonantRow('glottal', ['ㅎ']),
14
68
  ],
15
69
  jung: [
16
- [vowel('ㅣ', '전설 고모음'), vowel('ㅟ', '전설 고모음 · w활음'), vowel('ㅢ', '전설 고모음 · ɰ활음')],
17
- [vowel('ㅡ', '후설 고모음 평순')],
18
- [vowel('ㅜ', '후설 고모음 원순'), vowel('ㅠ', '후설 고모음 원순 · j활음')],
19
- [vowel('ㅔㅐ', '전설 중모음'), vowel('ㅖㅒ', '전설 중모음 · j활음'), vowel('ㅙㅚㅞ', '전설 중모음 · w활음')],
20
- [vowel('ㅓ', '후설 중모음 평순'), vowel('ㅕ', '후설 중모음 평순 · j활음'), vowel('ㅝ', '후설 중모음 평순 · w활음')],
21
- [vowel('ㅗ', '후설 중모음 원순'), vowel('ㅛ', '후설 중모음 원순 · j활음')],
22
- [vowel('ㅏ', '저모음'), vowel('ㅑ', '저모음 · j활음'), vowel('ㅘ', '저모음 · w활음')],
70
+ [vowel('ㅣ', 'frontHigh'), vowel('ㅟ', 'frontHigh', 'w'), vowel('ㅢ', 'frontHigh', 'velar')],
71
+ [vowel('ㅡ', 'backHighUnrounded')],
72
+ [vowel('ㅜ', 'backHighRounded'), vowel('ㅠ', 'backHighRounded', 'j')],
73
+ [vowel('ㅔㅐ', 'frontMid'), vowel('ㅖㅒ', 'frontMid', 'j'), vowel('ㅙㅚㅞ', 'frontMid', 'w')],
74
+ [vowel('ㅓ', 'backMidUnrounded'), vowel('ㅕ', 'backMidUnrounded', 'j'), vowel('ㅝ', 'backMidUnrounded', 'w')],
75
+ [vowel('ㅗ', 'backMidRounded'), vowel('ㅛ', 'backMidRounded', 'j')],
76
+ [vowel('ㅏ', 'low'), vowel('ㅑ', 'low', 'j'), vowel('ㅘ', 'low', 'w')],
23
77
  ],
24
78
  jong: [
25
- consonantRow('양순음', ['ㅂ', 'ㅁ']),
26
- consonantRow('치조음', ['ㄷ', 'ㄴ', 'ㄹ']),
27
- consonantRow('연구개음', ['ㄱ', 'ㅇ']),
79
+ consonantRow('labial', ['ㅂ', 'ㅁ']),
80
+ consonantRow('alveolar', ['ㄷ', 'ㄴ', 'ㄹ']),
81
+ consonantRow('velar', ['ㄱ', 'ㅇ']),
28
82
  ],
29
83
  };
@@ -46,4 +46,4 @@
46
46
  *
47
47
  * 값은 손으로 적고 `test/coreVersion.test.ts` 가 package.json 과 어긋나면 운다.
48
48
  */
49
- export declare const CORE_VERSION = "0.101.0";
49
+ export declare const CORE_VERSION = "0.103.0";
@@ -46,4 +46,4 @@
46
46
  *
47
47
  * 값은 손으로 적고 `test/coreVersion.test.ts` 가 package.json 과 어긋나면 운다.
48
48
  */
49
- export const CORE_VERSION = '0.101.0';
49
+ export const CORE_VERSION = '0.103.0';