OpenLab-NLP commited on
Commit
a4f9303
Β·
verified Β·
1 Parent(s): cbd837d

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +85 -84
index.html CHANGED
@@ -2,57 +2,62 @@
2
  <html lang="ko">
3
  <head>
4
  <meta charset="UTF-8">
5
- <title>Huiucl Precision Dictionary v4</title>
6
  <style>
7
  :root { --primary: #2c3e50; --accent: #e67e22; --bg: #f8f9fa; --card: #ffffff; }
8
- body { font-family: 'Malgun Gothic', sans-serif; background: var(--bg); padding: 20px; color: var(--primary); }
9
  .container { max-width: 900px; margin: 0 auto; }
10
 
 
 
 
11
  /* 헀더 μ„Ήμ…˜ */
12
- .header-panel { background: var(--primary); color: white; padding: 25px; border-radius: 15px; margin-bottom: 25px; text-align: center; }
 
13
 
14
  /* 검색창 */
15
  .search-container { position: sticky; top: 15px; z-index: 1000; margin-bottom: 30px; }
16
- .search-input { width: 100%; padding: 18px 25px; font-size: 20px; border: 4px solid #ddd; border-radius: 50px; outline: none; box-shadow: 0 8px 20px rgba(0,0,0,0.1); }
17
- .search-input:focus { border-color: var(--accent); }
18
 
19
  /* κ²°κ³Ό μΉ΄λ“œ */
20
- .card { background: var(--card); border-radius: 12px; padding: 25px; margin-bottom: 20px; box-shadow: 0 4px 12px rgba(0,0,0,0.05); border-left: 8px solid #bdc3c7; }
 
21
  .card.exact { border-left-color: var(--accent); }
22
 
23
- .tag-row { margin-bottom: 10px; }
24
- .badge { display: inline-block; padding: 3px 10px; border-radius: 5px; font-size: 11px; font-weight: bold; text-transform: uppercase; }
25
- .badge-cat { background: #ebf5fb; color: #2980b9; }
26
- .badge-exact { background: var(--accent); color: white; margin-left: 5px; }
27
 
28
- .word-row { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
29
- .word-text { font-size: 28px; font-weight: 900; color: #2c3e50; }
30
- .meaning-ko { font-size: 22px; color: #e74c3c; font-weight: bold; }
31
- .meaning-en { color: #7f8c8d; font-size: 16px; }
32
-
33
- /* νŒŒμƒ/변이 κ·Έλ¦¬λ“œ */
34
- .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 15px; margin-top: 15px; }
35
- .data-box { background: #fcfcfc; border: 1px solid #efefef; border-radius: 8px; padding: 12px; }
36
- .box-title { font-size: 13px; font-weight: bold; color: #34495e; margin-bottom: 8px; border-bottom: 1px solid #3498db; }
37
- .item-row { display: flex; font-size: 13px; margin-bottom: 3px; }
38
- .item-key { font-weight: bold; width: 100px; color: #d35400; }
39
 
40
  /* 상세 정보 (검색 μ œμ™Έ ꡬ역) */
41
- .extra { margin-top: 15px; padding-top: 10px; border-top: 1px dashed #eee; font-size: 13px; color: #666; }
42
- .ex-box { color: #2980b9; background: #f0f7ff; padding: 10px; border-radius: 5px; margin-top: 5px; border-left: 3px solid #3498db; }
43
- .label { font-weight: bold; color: #95a5a6; margin-right: 5px; }
 
44
  </style>
45
  </head>
46
  <body>
47
 
48
  <div class="container">
49
  <div class="header-panel">
50
- <h1 id="title">Huiucl Precision Dictionary</h1>
51
- <p id="status">βš™οΈ 데이터λ₯Ό λΆˆλŸ¬μ˜€λŠ” 쀑...</p>
52
  </div>
53
 
54
  <div class="search-container">
55
- <input type="text" id="query" class="search-input" placeholder="Huiucl.json을 같은 폴더에 두고 λ‘œλ“œλ˜κΈΈ κΈ°λ‹€λ¦¬μ„Έμš”..." disabled onkeyup="search()">
56
  </div>
57
 
58
  <div id="results"></div>
@@ -61,123 +66,119 @@
61
  <script>
62
  let lexicon = {};
63
 
64
- // 1. 파일 μžλ™ λ‘œλ“œ
65
  window.onload = async function() {
66
  try {
67
- const res = await fetch('Huiucl.json');
68
- if (!res.ok) throw new Error('νŒŒμΌμ„ 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.');
69
- const data = await res.json();
 
70
  process(data);
71
- document.getElementById('status').innerText = `βœ… ${Object.keys(lexicon).length}개 단어 λ‘œλ“œ μ™„λ£Œ`;
72
- document.getElementById('query').disabled = false;
73
- document.getElementById('query').placeholder = "단어 λ˜λŠ” 뜻 검색 (su, a, muihi, κ΄€μ°°...)";
74
  } catch (err) {
75
- document.getElementById('status').innerText = `❌ 였λ₯˜: ${err.message}`;
76
  }
77
  };
78
 
79
- // 2. 데이터 처리 (뜻 μš°μ„ μˆœμœ„ 및 검색 νƒ€κ²Ÿ μ •λ°€ν™”)
80
  function process(obj, parentKey = null, currentCat = null) {
81
  if (typeof obj !== 'object' || obj === null) return;
82
 
83
- // λŒ€λͺ…사 특수 계측
84
  const pSects = ["1st_Person", "2nd_Person", "3rd_Person", "Demonstratives"];
85
  if (pSects.includes(parentKey)) {
86
  for (const [pk, pv] of Object.entries(obj)) {
87
  lexicon[pk] = {
88
  meaning_ko: pv,
89
- _category: `Pronoun`,
90
  _search_target: `${pk} ${pv}`.toLowerCase()
91
  };
92
  }
93
  return;
94
  }
95
 
96
- // 단어 정보 νŒλ‹¨
97
- const keys = ['ko', 'meaning_ko', 'morpheme', 'en', 'meaning_en'];
98
- const hasMeaning = keys.some(k => k in obj);
99
 
100
- if (hasMeaning && parentKey) {
101
  let entry = { ...obj };
102
- // 뜻 μΆ”μΆœ μš°μ„ μˆœμœ„: ν•œκ΅­μ–΄ λŒ€μ‘μ–΄(ko) -> μ‹€μ œ 뜻(meaning_ko) -> ν˜•νƒœμ†Œ 정보(morpheme)
103
- const koVal = entry.ko || entry.meaning_ko || entry.morpheme || "";
104
- const enVal = entry.en || entry.meaning_en || "";
105
 
106
- // [핡심] 검색 νƒ€κ²Ÿμ—μ„œ μƒμœ„ ν‚€(Nominative λ“±) 및 예문/μš©λ²• μ œμ™Έ!
107
- // 였직 단어 이름과 μœ„μ—μ„œ μΆ”μΆœν•œ koVal, enVal만 검색 λŒ€μƒ
108
- entry._category = currentCat;
109
- entry._display_ko = koVal;
110
- entry._display_en = enVal;
111
- entry._search_target = `${parentKey} ${koVal} ${enVal}`.toLowerCase();
112
 
 
 
113
  lexicon[parentKey] = entry;
114
  }
115
 
116
  for (const [k, v] of Object.entries(obj)) {
117
- if (typeof v === 'object' && k !== 'Settings') {
118
- process(v, k, parentKey === null ? k : currentCat);
 
119
  }
120
  }
121
  }
122
 
123
- // 3. 검색 및 λ Œλ”λ§
124
  function search() {
125
  const q = document.getElementById('query').value.trim().toLowerCase();
126
- const area = document.getElementById('results');
127
- area.innerHTML = '';
128
  if (!q) return;
129
 
130
  let found = [];
 
131
  const re = new RegExp(`(^|[^a-zA-Zκ°€-힣])${q}($|[^a-zA-Zκ°€-힣])`, 'i');
132
 
133
  for (const [word, info] of Object.entries(lexicon)) {
134
  const wordL = word.toLowerCase();
135
  const target = info._search_target || "";
136
-
137
  if (q === wordL) found.push({ word, info, score: 2 });
138
  else if (re.test(target) || (q.length > 1 && target.includes(q))) found.push({ word, info, score: 1 });
139
  }
140
 
141
- found.sort((a,b) => b.score - a.score).forEach(item => {
142
  const info = item.info;
143
  const card = document.createElement('div');
144
  card.className = `card ${item.score === 2 ? 'exact' : ''}`;
145
 
146
- // νŒŒμƒμ–΄/μ‹œμ œ λ°•μŠ€ 생성 (데이터 μžˆλŠ” 경우만)
147
- let subHtml = '';
148
- const dr = info.derivations || info.derivation;
149
- if (dr) {
150
- subHtml += `<div class="data-box"><div class="box-title">πŸ“‚ 기둝된 νŒŒμƒμ–΄</div>`;
151
- for(const [k, v] of Object.entries(dr)) subHtml += `<div class="item-row"><span class="item-key">${k}</span><span>${v}</span></div>`;
152
- subHtml += `</div>`;
153
  }
154
-
155
- let vr = {};
156
- ['tense_variants', 'aspect_voice', 'variants'].forEach(k => { if(info[k]) Object.assign(vr, info[k]); });
157
- if (Object.keys(vr).length > 0) {
158
- subHtml += `<div class="data-box"><div class="box-title">πŸ“‚ μ‹œμ œ 및 변이</div>`;
159
- for(const [k, v] of Object.entries(vr)) subHtml += `<div class="item-row"><span class="item-key">${k}</span><span>${v.ko || v.meaning_ko || ''}</span></div>`;
160
- subHtml += `</div>`;
161
  }
162
 
163
  card.innerHTML = `
164
- <div class="tag-row">
165
- <span class="badge badge-cat">${info._category}</span>
166
- ${item.score === 2 ? '<span class="badge badge-exact">μ •ν™•ν•œ 일치</span>' : ''}
167
- </div>
168
  <div class="word-row">
169
  <span class="word-text">${item.word}</span>
170
- <span class="meaning-ko">${info._display_ko}</span>
171
- <span class="meaning-en">${info._display_en}</span>
172
  </div>
173
- <div class="grid">${subHtml}</div>
174
- <div class="extra">
175
- ${info.usage ? `<div><span class="label">πŸ“ μš©λ²•:</span> ${typeof info.usage === 'object' ? info.usage.ko : info.usage}</div>` : ''}
176
- ${info.note ? `<div><span class="label">πŸ’‘ μ°Έκ³ :</span> ${info.note}</div>` : ''}
177
- ${info.example ? `<div class="ex-box"><span class="label">πŸ“– 예문:</span> ${info.example}</div>` : ''}
178
  </div>
179
  `;
180
- area.appendChild(card);
181
  });
182
  }
183
  </script>
 
2
  <html lang="ko">
3
  <head>
4
  <meta charset="UTF-8">
5
+ <title>Huiucl Auto-Load Dictionary</title>
6
  <style>
7
  :root { --primary: #2c3e50; --accent: #e67e22; --bg: #f8f9fa; --card: #ffffff; }
8
+ body { font-family: 'Malgun Gothic', 'Apple SD Gothic Neo', sans-serif; background: var(--bg); padding: 20px; color: var(--primary); }
9
  .container { max-width: 900px; margin: 0 auto; }
10
 
11
+ /* λ‘œλ”© μƒνƒœ ν‘œμ‹œ */
12
+ #loader { text-align: center; padding: 20px; font-weight: bold; color: #2980b9; }
13
+
14
  /* 헀더 μ„Ήμ…˜ */
15
+ .header-panel { background: var(--primary); color: white; padding: 30px; border-radius: 15px; margin-bottom: 25px; box-shadow: 0 4px 15px rgba(0,0,0,0.2); }
16
+ .header-panel h1 { margin: 0; font-size: 32px; letter-spacing: 1px; }
17
 
18
  /* 검색창 */
19
  .search-container { position: sticky; top: 15px; z-index: 1000; margin-bottom: 30px; }
20
+ .search-input { width: 100%; padding: 20px 25px; font-size: 22px; border: 4px solid #ddd; border-radius: 50px; box-sizing: border-box; outline: none; box-shadow: 0 10px 25px rgba(0,0,0,0.1); transition: all 0.3s ease; }
21
+ .search-input:focus { border-color: var(--accent); transform: translateY(-2px); }
22
 
23
  /* κ²°κ³Ό μΉ΄λ“œ */
24
+ .card { background: var(--card); border-radius: 15px; padding: 30px; margin-bottom: 25px; box-shadow: 0 5px 20px rgba(0,0,0,0.05); border-left: 8px solid #dcdde1; transition: transform 0.2s; }
25
+ .card:hover { transform: scale(1.01); }
26
  .card.exact { border-left-color: var(--accent); }
27
 
28
+ .badge { display: inline-block; padding: 4px 12px; border-radius: 20px; font-size: 12px; font-weight: bold; margin-bottom: 10px; }
29
+ .badge-cat { background: #f1f2f6; color: #7f8c8d; }
30
+ .badge-exact { background: var(--accent); color: white; margin-left: 10px; }
 
31
 
32
+ .word-row { display: flex; align-items: baseline; gap: 15px; flex-wrap: wrap; }
33
+ .word-text { font-size: 32px; font-weight: 900; color: #2980b9; text-transform: uppercase; }
34
+ .meaning-text { font-size: 20px; color: #2c3e50; font-weight: 600; }
35
+ .meaning-en { color: #95a5a6; font-size: 16px; font-style: italic; }
36
+
37
+ /* 데이터 κ·Έλ¦¬λ“œ (νŒŒμƒμ–΄, λ³€μ΄ν˜•) */
38
+ .grid-container { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 15px; margin-top: 20px; }
39
+ .data-list { background: #fdfdfd; border: 1px solid #f1f1f1; border-radius: 10px; padding: 15px; }
40
+ .list-title { font-size: 14px; font-weight: bold; color: #34495e; border-bottom: 2px solid #3498db; padding-bottom: 5px; margin-bottom: 10px; }
41
+ .item-row { display: flex; font-size: 14px; margin-bottom: 4px; }
42
+ .item-key { font-weight: bold; width: 110px; color: #e67e22; }
43
 
44
  /* 상세 정보 (검색 μ œμ™Έ ꡬ역) */
45
+ .details { margin-top: 20px; padding-top: 15px; border-top: 1px dashed #eee; font-size: 14px; color: #555; }
46
+ .detail-item { margin-bottom: 5px; }
47
+ .label { font-weight: bold; color: #7f8c8d; margin-right: 5px; }
48
+ .example-box { color: #2980b9; background: #ebf5fb; padding: 10px; border-radius: 5px; margin-top: 5px; }
49
  </style>
50
  </head>
51
  <body>
52
 
53
  <div class="container">
54
  <div class="header-panel">
55
+ <h1>Huiucl Engine <small style="font-size: 14px; opacity: 0.8;">v3.0 Auto-Load</small></h1>
56
+ <div id="loader">βš™οΈ 데이터λ₯Ό λΆˆλŸ¬μ˜€λŠ” 쀑...</div>
57
  </div>
58
 
59
  <div class="search-container">
60
+ <input type="text" id="query" class="search-input" placeholder="검색어λ₯Ό μž…λ ₯ν•˜μ„Έμš” (su, a, mi, μ œμž‘ν•˜λ‹€...)" onkeyup="search()">
61
  </div>
62
 
63
  <div id="results"></div>
 
66
  <script>
67
  let lexicon = {};
68
 
69
+ // [μžλ™ λ‘œλ“œ] νŽ˜μ΄μ§€ λ‘œλ“œ μ‹œ Huiucl.json νŒŒμΌμ„ μ¦‰μ‹œ μ½μ–΄μ˜΄
70
  window.onload = async function() {
71
  try {
72
+ const response = await fetch('Huiucl.json');
73
+ if (!response.ok) throw new Error('νŒŒμΌμ„ 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.');
74
+ const data = await response.json();
75
+
76
  process(data);
77
+
78
+ document.getElementById('loader').innerText = `βœ… ${Object.keys(lexicon).length}개 ν•­λͺ© λ‘œλ“œ μ™„λ£Œ. λ°”λ‘œ 검색 κ°€λŠ₯ν•©λ‹ˆλ‹€.`;
79
+ setTimeout(() => document.getElementById('loader').style.display = 'none', 3000);
80
  } catch (err) {
81
+ document.getElementById('loader').innerHTML = `❌ 였λ₯˜: ${err.message}<br><small>Huiucl.json 파일이 같은 폴더에 μžˆλŠ”μ§€ ν™•μΈν•˜μ„Έμš”.</small>`;
82
  }
83
  };
84
 
 
85
  function process(obj, parentKey = null, currentCat = null) {
86
  if (typeof obj !== 'object' || obj === null) return;
87
 
88
+ // 1. λŒ€λͺ…사 μ„Ήμ…˜ (a, i, u λ“± ν•œ κΈ€μž λŒ€λͺ…사 μ™„λ²½ λ‘œλ“œ)
89
  const pSects = ["1st_Person", "2nd_Person", "3rd_Person", "Demonstratives"];
90
  if (pSects.includes(parentKey)) {
91
  for (const [pk, pv] of Object.entries(obj)) {
92
  lexicon[pk] = {
93
  meaning_ko: pv,
94
+ _category: `Pronoun (${parentKey})`,
95
  _search_target: `${pk} ${pv}`.toLowerCase()
96
  };
97
  }
98
  return;
99
  }
100
 
101
+ // 2. 일반 단어 처리
102
+ const keys = ['meaning_ko', 'ko', 'definition', 'morpheme', 'meaning_en', 'en'];
103
+ const hasInfo = keys.some(k => k in obj);
104
 
105
+ if (hasInfo && parentKey) {
106
  let entry = { ...obj };
107
+ if (entry.definition && typeof entry.definition === 'object') Object.assign(entry, entry.definition);
 
 
108
 
109
+ // [μ€‘μš”] 검색 νƒ€κ²Ÿμ—μ„œ usage, example은 제거 (μ˜€λ‘œμ§€ 단어λͺ…κ³Ό 뜻만)
110
+ let targets = [parentKey];
111
+ keys.forEach(k => { if (entry[k]) targets.push(entry[k]); });
 
 
 
112
 
113
+ entry._category = currentCat;
114
+ entry._search_target = targets.join(" ").toLowerCase();
115
  lexicon[parentKey] = entry;
116
  }
117
 
118
  for (const [k, v] of Object.entries(obj)) {
119
+ if (typeof v === 'object') {
120
+ const nextCat = (parentKey === null) ? k : currentCat;
121
+ if (k !== 'Settings') process(v, k, nextCat);
122
  }
123
  }
124
  }
125
 
 
126
  function search() {
127
  const q = document.getElementById('query').value.trim().toLowerCase();
128
+ const resDiv = document.getElementById('results');
129
+ resDiv.innerHTML = '';
130
  if (!q) return;
131
 
132
  let found = [];
133
+ // μ •ν™•ν•œ 독립 ν˜•νƒœμ†Œ 인지λ₯Ό μœ„ν•œ μ •κ·œμ‹
134
  const re = new RegExp(`(^|[^a-zA-Zκ°€-힣])${q}($|[^a-zA-Zκ°€-힣])`, 'i');
135
 
136
  for (const [word, info] of Object.entries(lexicon)) {
137
  const wordL = word.toLowerCase();
138
  const target = info._search_target || "";
139
+
140
  if (q === wordL) found.push({ word, info, score: 2 });
141
  else if (re.test(target) || (q.length > 1 && target.includes(q))) found.push({ word, info, score: 1 });
142
  }
143
 
144
+ found.sort((a, b) => b.score - a.score).forEach(item => {
145
  const info = item.info;
146
  const card = document.createElement('div');
147
  card.className = `card ${item.score === 2 ? 'exact' : ''}`;
148
 
149
+ // νŒŒμƒμ–΄/λ³€μ΄ν˜• κ·Έλ¦¬λ“œ 생성
150
+ let gridHtml = '';
151
+ const derivs = info.derivations || info.derivation;
152
+ if (derivs) {
153
+ gridHtml += `<div class="data-list"><div class="list-title">πŸ“‚ 기둝된 νŒŒμƒμ–΄</div>`;
154
+ for(const [dw, dm] of Object.entries(derivs)) gridHtml += `<div class="item-row"><span class="item-key">${dw}</span> <span>${dm}</span></div>`;
155
+ gridHtml += `</div>`;
156
  }
157
+
158
+ let vars = {};
159
+ ["tense_variants", "aspect_voice", "variants"].forEach(k => { if(info[k]) Object.assign(vars, info[k]); });
160
+ if (Object.keys(vars).length > 0) {
161
+ gridHtml += `<div class="data-list"><div class="list-title">πŸ“‚ μ‹œμ œ 및 변이</div>`;
162
+ for(const [vw, vi] of Object.entries(vars)) gridHtml += `<div class="item-row"><span class="item-key">${vw}</span> <span>${vi.meaning_ko || vi.ko || ''}</span></div>`;
163
+ gridHtml += `</div>`;
164
  }
165
 
166
  card.innerHTML = `
167
+ <span class="badge badge-cat">${info._category}</span>
168
+ ${item.score === 2 ? '<span class="badge badge-exact">μ •ν™•ν•œ 일치</span>' : ''}
 
 
169
  <div class="word-row">
170
  <span class="word-text">${item.word}</span>
171
+ <span class="meaning-text">${info.meaning_ko || info.ko || info.morpheme || ''}</span>
172
+ <span class="meaning-en">${info.meaning_en || info.en || ''}</span>
173
  </div>
174
+ <div class="grid-container">${gridHtml}</div>
175
+ <div class="details">
176
+ ${info.usage ? `<div class="detail-item"><span class="label">πŸ“ μš©λ²•:</span> ${typeof info.usage === 'object' ? info.usage.ko : info.usage}</div>` : ''}
177
+ ${info.note ? `<div class="detail-item"><span class="label">πŸ’‘ μ°Έκ³ :</span> ${info.note}</div>` : ''}
178
+ ${info.example ? `<div class="example-box"><span class="label">πŸ“– 예문:</span> ${info.example}</div>` : ''}
179
  </div>
180
  `;
181
+ resDiv.appendChild(card);
182
  });
183
  }
184
  </script>