OpenLab-NLP commited on
Commit
c60dc40
·
verified ·
1 Parent(s): fbbed72

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +96 -84
index.html CHANGED
@@ -2,34 +2,59 @@
2
  <html lang="ko">
3
  <head>
4
  <meta charset="UTF-8">
5
- <title>HUIUCL Database Final</title>
6
  <style>
7
- :root { --bg: #f4f1ea; --card: #ffffff; --accent: #8b7355; --text: #333; }
8
- body { font-family: sans-serif; background: var(--bg); color: var(--text); padding: 20px; }
 
 
 
 
 
 
 
9
  .container { max-width: 1200px; margin: 0 auto; }
10
- .search-box { width: 100%; padding: 15px; margin-bottom: 20px; border: 2px solid #ddd; border-radius: 8px; font-size: 1.1rem; }
11
- .table-wrapper { background: #fff; border-radius: 12px; box-shadow: 0 4px 20px rgba(0,0,0,0.1); overflow: hidden; }
 
 
 
 
 
 
12
  table { width: 100%; border-collapse: collapse; table-layout: fixed; }
13
- th, td { padding: 15px; text-align: left; border-bottom: 1px solid #eee; word-break: break-all; }
14
- th { background: #f8f8f8; font-weight: bold; border-bottom: 2px solid #ddd; }
15
- .word-cell { font-weight: bold; color: var(--accent); width: 20%; font-size: 1.1rem; }
16
- .path-cell { font-size: 0.8rem; color: #999; width: 20%; }
17
- .usage-tag { background: #f0f0f0; padding: 4px 8px; border-radius: 4px; font-size: 0.8rem; color: #666; display: block; margin-top: 5px; }
18
- .meaning-item { margin-bottom: 4px; }
19
- .sub-row { background: #fafafa; font-size: 0.9rem; }
 
 
 
 
 
 
 
 
 
20
  </style>
21
  </head>
22
  <body>
23
 
24
  <div class="container">
25
- <input type="text" id="searchInput" class="search-box" placeholder="단어, 뜻, 분류 검색..." oninput="render()">
 
 
 
26
  <div class="table-wrapper">
27
  <table>
28
  <thead>
29
  <tr>
30
- <th style="width:20%">단어 (Word)</th>
31
- <th style="width:60%">의미 용법</th>
32
- <th style="width:20%">분류</th>
33
  </tr>
34
  </thead>
35
  <tbody id="dictBody"></tbody>
@@ -54,95 +79,82 @@
54
  const body = document.getElementById('dictBody');
55
  body.innerHTML = '';
56
 
57
- // 모든 카테고리 순회 (Settings 제외)
58
- for (const cat in rawData) {
59
- if (cat === "Settings") continue;
60
- extract(rawData[cat], cat, query);
61
  }
62
  }
63
 
64
- function extract(obj, path, query) {
65
  if (path.includes("Grammar_Rules")) return;
66
 
67
- for (const key in obj) {
68
- const val = obj[key];
69
- if (!val) continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
71
- // 1. 문자열인 경우 (단순 대명사, 인사말 등)
72
- if (typeof val === 'string') {
73
- if (isMatch(key, val, path, query)) {
74
- appendRow(key, val, "", "", path);
75
  }
76
  }
77
- // 2. 객체인 경우 (단어 정보 포함)
78
- else if (typeof val === 'object') {
79
- // 객체가 '단어 정보'를 담고 있는지 확인
80
- const info = getWordInfo(val);
81
-
82
- if (info.hasData) {
83
- if (isMatch(key, info.ko + info.en + info.usage, path, query)) {
84
- appendRow(key, info.ko, info.en, info.usage, path);
85
- }
86
-
87
- // 파생어 처리
88
- if (val.derivations) {
89
- for (const dKey in val.derivations) {
90
- appendRow(dKey, val.derivations[dKey], "", "", path, true);
91
- }
92
- }
93
- // 시제 변형 등 하위 데이터가 더 있다면 탐색 (단, 데이터 키는 제외)
94
- for (const subKey in val) {
95
- if (!["meaning_ko", "meaning_en", "ko", "en", "definition", "usage", "note", "derivations"].includes(subKey)) {
96
- extract({ [subKey]: val[subKey] }, path + " > " + key, query);
97
- }
98
- }
99
- } else {
100
- // 단어 데이터가 아니면 더 깊게 탐색
101
- extract(val, path + " > " + key, query);
102
  }
103
  }
104
  }
105
  }
106
 
107
- // 객체 안에서 한글 뜻, 영어 뜻, 사용법을 긁어모으는 함수
108
- function getWordInfo(obj) {
109
- let info = {
110
- ko: obj.meaning_ko || obj.ko || obj.뜻 || obj.definition || "",
111
- en: obj.meaning_en || obj.en || "",
112
- usage: obj.usage || obj.note || "",
113
- hasData: false
114
- };
115
-
116
- // ko나 definition이 또 객체인 경우 (에러 방지)
117
- if (typeof info.ko === 'object') info.ko = info.ko.ko || info.ko.meaning_ko || JSON.stringify(info.ko);
118
- if (typeof info.en === 'object') info.en = info.en.en || info.en.meaning_en || "";
119
-
120
- if (info.ko || info.en || info.usage) info.hasData = true;
121
- return info;
122
- }
123
-
124
- function isMatch(word, content, path, query) {
125
- const target = (word + content + path).toLowerCase();
126
- return target.includes(query);
127
- }
128
-
129
- function appendRow(word, ko, en, usage, path, isSub) {
130
  const body = document.getElementById('dictBody');
131
  const row = body.insertRow();
132
  if (isSub) row.className = 'sub-row';
133
 
134
- let meaningHtml = `<div class="meaning-item"><strong>${ko}</strong></div>`;
135
- if (en) meaningHtml += `<div class="meaning-item" style="color: #666;">${en}</div>`;
136
- if (usage) {
137
- // usage 객체인 경우 대응
138
- const usageText = typeof usage === 'object' ? JSON.stringify(usage) : usage;
139
- meaningHtml += `<div class="usage-tag">※ ${usageText}</div>`;
140
  }
141
 
142
  row.innerHTML = `
143
- <td class="word-cell">${isSub ? '└ ' : ''}${word}</td>
 
 
144
  <td>${meaningHtml}</td>
145
- <td class="path-cell">${path}</td>
146
  `;
147
  }
148
  </script>
 
2
  <html lang="ko">
3
  <head>
4
  <meta charset="UTF-8">
5
+ <title>HUIUCL Archive v4.0</title>
6
  <style>
7
+ :root {
8
+ --bg: #f8f9fa;
9
+ --primary: #2c3e50;
10
+ --accent: #e67e22;
11
+ --border: #dcdde1;
12
+ --card-bg: #ffffff;
13
+ }
14
+
15
+ body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: var(--bg); color: var(--primary); margin: 0; padding: 20px; }
16
  .container { max-width: 1200px; margin: 0 auto; }
17
+
18
+ /* Search UI */
19
+ .search-area { position: sticky; top: 0; background: var(--bg); padding: 10px 0 20px; z-index: 100; }
20
+ .search-box { width: 100%; padding: 18px; border: 2px solid var(--border); border-radius: 12px; font-size: 1.1rem; outline: none; transition: border-color 0.3s; box-shadow: 0 4px 6px rgba(0,0,0,0.05); }
21
+ .search-box:focus { border-color: var(--accent); }
22
+
23
+ /* Table UI */
24
+ .table-wrapper { background: var(--card-bg); border-radius: 15px; box-shadow: 0 10px 25px rgba(0,0,0,0.1); overflow: hidden; border: 1px solid var(--border); }
25
  table { width: 100%; border-collapse: collapse; table-layout: fixed; }
26
+ th { background: #f1f2f6; padding: 18px; text-align: left; font-size: 0.9rem; text-transform: uppercase; letter-spacing: 1px; color: #7f8c8d; border-bottom: 2px solid var(--border); }
27
+ td { padding: 18px; border-bottom: 1px solid #f1f2f6; vertical-align: top; word-break: break-all; }
28
+
29
+ /* Content Styling */
30
+ .word-text { font-size: 1.2rem; font-weight: 800; color: var(--accent); display: block; margin-bottom: 5px; }
31
+ .meaning-ko { font-size: 1.05rem; font-weight: 600; color: #2f3640; margin-bottom: 4px; }
32
+ .meaning-en { font-size: 0.95rem; color: #7f8c8d; font-style: italic; }
33
+
34
+ .usage-card { background: #fffcf0; border: 1px solid #f1e4b3; border-radius: 8px; padding: 10px; margin-top: 10px; font-size: 0.85rem; color: #5d5d5d; line-height: 1.5; }
35
+ .usage-label { font-weight: 800; color: #b88e2f; margin-right: 5px; font-size: 0.75rem; }
36
+
37
+ .path-tag { display: inline-block; padding: 4px 10px; background: #ebedef; border-radius: 20px; font-size: 0.75rem; color: #34495e; font-weight: bold; }
38
+ .derivation-item { font-size: 0.9rem; padding: 5px 0; color: #636e72; border-top: 1px dashed #eee; margin-top: 5px; }
39
+
40
+ tr:hover { background-color: #fdfdfd; }
41
+ .sub-row { background-color: #fafbfc; }
42
  </style>
43
  </head>
44
  <body>
45
 
46
  <div class="container">
47
+ <div class="search-area">
48
+ <input type="text" id="searchInput" class="search-box" placeholder="Search by word, meaning, or category..." oninput="render()">
49
+ </div>
50
+
51
  <div class="table-wrapper">
52
  <table>
53
  <thead>
54
  <tr>
55
+ <th style="width: 25%;">Word / Morpheme</th>
56
+ <th style="width: 55%;">Meaning & Description</th>
57
+ <th style="width: 20%;">Category</th>
58
  </tr>
59
  </thead>
60
  <tbody id="dictBody"></tbody>
 
79
  const body = document.getElementById('dictBody');
80
  body.innerHTML = '';
81
 
82
+ for (const section in rawData) {
83
+ if (section === "Settings") continue;
84
+ processNode(rawData[section], section, query);
 
85
  }
86
  }
87
 
88
+ function processNode(node, path, query) {
89
  if (path.includes("Grammar_Rules")) return;
90
 
91
+ for (const key in node) {
92
+ const item = node[key];
93
+ if (!item) continue;
94
+
95
+ // 1. 핵심: 이 노드가 "단어 데이터"를 담고 있는가?
96
+ const isWordData = (typeof item === 'object' && (item.meaning_ko || item.ko || item.definition || item.morpheme));
97
+
98
+ if (isWordData) {
99
+ // sa- 같은 Morpheme 예외 처리: item.morpheme이 있으면 그걸 단어로 사용
100
+ const displayWord = item.morpheme || key;
101
+ const info = {
102
+ ko: item.meaning_ko || item.ko || item.뜻 || item.definition || "",
103
+ en: item.meaning_en || item.en || "",
104
+ usage: item.usage || item.note || ""
105
+ };
106
+
107
+ // 검색 필터
108
+ if (displayWord.toLowerCase().includes(query) || info.ko.includes(query) || info.en.toLowerCase().includes(query) || path.toLowerCase().includes(query)) {
109
+ appendRow(displayWord, info, path);
110
+ }
111
+
112
+ // 파생어 처리
113
+ if (item.derivations) {
114
+ for (const dKey in item.derivations) {
115
+ appendRow(dKey, { ko: item.derivations[dKey], en: "", usage: "" }, path, true);
116
+ }
117
+ }
118
 
119
+ // 조동사 시제 변형(tense_variants) 같은 하위 객체 탐색
120
+ if (item.tense_variants) {
121
+ processNode(item.tense_variants, path + " > " + displayWord, query);
 
122
  }
123
  }
124
+ // 2. 단순 문자열인 경우 (대명사 )
125
+ else if (typeof item === 'string') {
126
+ if (key.toLowerCase().includes(query) || item.toLowerCase().includes(query)) {
127
+ appendRow(key, { ko: item, en: "", usage: "" }, path);
128
+ }
129
+ }
130
+ // 3. 데이터가 아닌 단순 카테고리 층인 경우 (재귀)
131
+ else if (typeof item === 'object') {
132
+ // 'morpheme'이 키인 경우를 방지하기 위해 필터링
133
+ if (!["derivations", "tense_variants"].includes(key)) {
134
+ processNode(item, path + " > " + key, query);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  }
136
  }
137
  }
138
  }
139
 
140
+ function appendRow(word, info, path, isSub) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  const body = document.getElementById('dictBody');
142
  const row = body.insertRow();
143
  if (isSub) row.className = 'sub-row';
144
 
145
+ // 의미부 구성
146
+ let meaningHtml = `<div class="meaning-ko">${info.ko}</div>`;
147
+ if (info.en) meaningHtml += `<div class="meaning-en">${info.en}</div>`;
148
+ if (info.usage) {
149
+ meaningHtml += `<div class="usage-card"><span class="usage-label">USAGE</span>${info.usage}</div>`;
 
150
  }
151
 
152
  row.innerHTML = `
153
+ <td>
154
+ <span class="word-text">${isSub ? '↳ ' : ''}${word}</span>
155
+ </td>
156
  <td>${meaningHtml}</td>
157
+ <td><span class="path-tag">${path}</span></td>
158
  `;
159
  }
160
  </script>