Spaces:
Running
Running
| <html lang="ko"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>HUIUCL Database</title> | |
| <style> | |
| :root { --bg-color: #f9f7f2; --card-bg: #ffffff; --primary-color: #5d5b54; --accent-color: #d4a373; --border-color: #e0ddd5; } | |
| body { font-family: 'Pretendard', sans-serif; background-color: var(--bg-color); color: var(--primary-color); margin: 0; padding: 0; line-height: 1.6; } | |
| nav { position: sticky; top: 0; background: rgba(249, 247, 242, 0.9); backdrop-filter: blur(10px); padding: 15px; text-align: center; border-bottom: 1px solid var(--border-color); z-index: 100; } | |
| nav a { margin: 0 15px; text-decoration: none; color: var(--primary-color); font-weight: 600; cursor: pointer; } | |
| header { text-align: center; padding: 40px 20px; } | |
| h1 { font-weight: 300; letter-spacing: 8px; color: var(--accent-color); margin: 0; } | |
| .container { max-width: 1100px; margin: 0 auto; padding: 0 20px 100px; } | |
| section { display: none; } | |
| section.active { display: block; } | |
| .filter-container { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-bottom: 25px; } | |
| .filter-btn { background: var(--card-bg); border: 1px solid var(--border-color); padding: 8px 16px; cursor: pointer; border-radius: 20px; font-size: 0.85rem; } | |
| .filter-btn.active { background: var(--accent-color); color: white; border-color: var(--accent-color); } | |
| .search-box { width: 100%; padding: 15px 25px; border: 1px solid var(--border-color); border-radius: 30px; font-size: 1rem; margin-bottom: 20px; box-sizing: border-box; outline: none; } | |
| .table-wrapper { background: white; border-radius: 15px; overflow: hidden; box-shadow: 0 10px 30px rgba(0,0,0,0.05); } | |
| table { width: 100%; border-collapse: collapse; } | |
| th, td { padding: 15px 20px; text-align: left; border-bottom: 1px solid #eee; } | |
| th { background: #f1eee6; color: #777; font-size: 0.85rem; } | |
| .word-cell { font-weight: bold; color: var(--accent-color); width: 25%; } | |
| .meaning-cell { width: 55%; font-size: 0.95rem; } | |
| .path-cell { font-size: 0.7rem; color: #bbb; width: 20%; text-align: right; } | |
| .usage-tag { font-size: 0.8rem; color: #888; display: block; margin-top: 4px; border-top: 1px dashed #eee; padding-top: 4px; } | |
| </style> | |
| </head> | |
| <body> | |
| <nav> | |
| <a onclick="showSection('dictionary')">DICTIONARY</a> | |
| <a onclick="showSection('grammar')">GRAMMAR</a> | |
| </nav> | |
| <header> | |
| <h1>HUIUCL</h1> | |
| <div style="color:#999; font-size:0.8rem; margin-top:5px;">DATABASE v2.7 (Manual Mapping)</div> | |
| </header> | |
| <div class="container"> | |
| <section id="dictionary" class="active"> | |
| <input type="text" id="searchInput" class="search-box" placeholder="λ¨μ΄, λ», μΉ΄ν κ³ λ¦¬ κ²μ..." oninput="renderTable()"> | |
| <div class="filter-container" id="categoryButtons"> | |
| <button class="filter-btn active" onclick="filterCategory('λͺ¨λ', this)">λͺ¨λ 보기</button> | |
| </div> | |
| <div class="table-wrapper"> | |
| <table> | |
| <thead> | |
| <tr><th>λ¨μ΄</th><th>μλ―Έ λ° μ€λͺ </th><th style="text-align:right;">λΆλ₯</th></tr> | |
| </thead> | |
| <tbody id="dictBody"></tbody> | |
| </table> | |
| </div> | |
| </section> | |
| <section id="grammar"><div id="grammarContent"></div></section> | |
| </div> | |
| <script> | |
| let conlangData = {}; | |
| let currentCategory = 'λͺ¨λ'; | |
| function showSection(id) { | |
| document.querySelectorAll('section').forEach(s => s.classList.remove('active')); | |
| document.getElementById(id).classList.add('active'); | |
| } | |
| window.onload = () => { | |
| fetch('Huiucl.json').then(res => res.json()).then(data => { | |
| conlangData = data; | |
| initFilterButtons(); | |
| renderTable(); | |
| renderGrammarPage(); | |
| }); | |
| }; | |
| function initFilterButtons() { | |
| const btnContainer = document.getElementById('categoryButtons'); | |
| Object.keys(conlangData).forEach(key => { | |
| if (key === "Settings") return; | |
| const btn = document.createElement('button'); | |
| btn.className = 'filter-btn'; | |
| btn.innerText = key; | |
| btn.onclick = (e) => filterCategory(key, e.target); | |
| btnContainer.appendChild(btn); | |
| }); | |
| } | |
| function filterCategory(cat, btn) { | |
| document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active')); | |
| btn.classList.add('active'); | |
| currentCategory = cat; | |
| renderTable(); | |
| } | |
| function renderTable() { | |
| const query = document.getElementById('searchInput').value.toLowerCase(); | |
| const body = document.getElementById('dictBody'); | |
| body.innerHTML = ''; | |
| const categories = currentCategory === 'λͺ¨λ' | |
| ? Object.keys(conlangData).filter(k => k !== "Settings") | |
| : [currentCategory]; | |
| categories.forEach(cat => { | |
| manualProcess(conlangData[cat], cat, query); | |
| }); | |
| } | |
| // νλνλ μ±κ²©μ λ§μΆ° μ§μ μ²λ¦¬νλ μλ λ§€ν μμ§ | |
| function manualProcess(obj, path, query) { | |
| if (path.includes("Grammar_Rules")) return; // λ¬Έλ² κ·μΉμ μ¬μ μμ μ μΈ | |
| for (let key in obj) { | |
| const val = obj[key]; | |
| if (!val) continue; | |
| // 1. [λ¨μ΄ κ°μ²΄] - meaning_ko, ko, definition λ±μ ν€κ° μλ κ²½μ° | |
| if (typeof val === 'object' && (val.meaning_ko || val.ko || val.definition || val.λ»)) { | |
| let mainWord = key; | |
| let kor = val.meaning_ko || val.ko || val.λ» || val.definition || ""; | |
| let eng = val.meaning_en || val.en || ""; | |
| let extra = val.usage || val.note || ""; | |
| if (mainWord.toLowerCase().includes(query) || kor.toLowerCase().includes(query)) { | |
| appendRow(mainWord, kor, eng, extra, path); | |
| } | |
| // νμ νμμ΄ μ²λ¦¬ | |
| if (val.derivations) { | |
| for (let dKey in val.derivations) { | |
| appendRow(dKey, val.derivations[dKey], "", "", path, true); | |
| } | |
| } | |
| // μ‘°λμ¬ λ± λ΄λΆ ν μ€ λ³νμ΄ μλ κ²½μ° (acam, acac λ±) | |
| if (val.tense_variants) { | |
| manualProcess(val.tense_variants, path + " > " + key, query); | |
| } | |
| } | |
| // 2. [λ¨μ ν€-κ°] - λλͺ μ¬, μΈμ¬λ§ λ± (key: "string") | |
| else if (typeof val === 'string') { | |
| if (key.toLowerCase().includes(query) || val.toLowerCase().includes(query)) { | |
| appendRow(key, val, "", "", path); | |
| } | |
| } | |
| // 3. [μ‘°μ¬/μ μ¬ κ΅¬μ‘°] - ν€ λ΄λΆμ λ μ€λͺ μ΄ μκ±°λ, λ¬Άμ¬ μλ κ²½μ° | |
| else if (typeof val === 'object') { | |
| // νΉμ ν€(usage, note, definition) μμ²΄κ° λ¨μ΄λ‘ λ¨μ§ μλλ‘ νν°λ§νλ©° μ¬κ· νμ | |
| if (!["usage", "note", "definition", "tense_variants"].includes(key)) { | |
| manualProcess(val, path + " > " + key, query); | |
| } | |
| } | |
| } | |
| } | |
| function appendRow(word, kor, eng, usage, path, isSub) { | |
| const body = document.getElementById('dictBody'); | |
| const row = body.insertRow(); | |
| if (isSub) row.className = 'variation-row'; | |
| let meaningHtml = `<strong>${kor}</strong>`; | |
| if (eng) meaningHtml += ` <span style="color:#888;">(${eng})</span>`; | |
| if (usage) meaningHtml += `<span class="usage-tag">β» ${usage}</span>`; | |
| row.innerHTML = ` | |
| <td class="word-cell">${isSub ? 'β ' : ''}${word}</td> | |
| <td class="meaning-cell">${meaningHtml}</td> | |
| <td class="path-cell">${path}</td> | |
| `; | |
| } | |
| function renderGrammarPage() { | |
| const target = document.getElementById('grammarContent'); | |
| let html = ""; | |
| function findRules(obj, path) { | |
| for (let key in obj) { | |
| if (key === "Grammar_Rules") { | |
| html += `<div style="background:white; padding:30px; border-radius:15px; margin-bottom:20px; box-shadow:0 5px 15px rgba(0,0,0,0.05);"> | |
| <h3 style="margin-top:0; color:var(--accent-color);">${path || 'General'} Rules</h3>`; | |
| for (let rKey in obj[key]) { | |
| html += `<p><strong>${rKey}:</strong> ${obj[key][rKey]}</p>`; | |
| } | |
| html += `</div>`; | |
| } else if (typeof obj[key] === 'object' && key !== "Settings") { | |
| findRules(obj[key], path ? path + " > " + key : key); | |
| } | |
| } | |
| } | |
| findRules(conlangData, ""); | |
| target.innerHTML = html || "<p>λ‘λλ λ¬Έλ² κ·μΉμ΄ μμ΅λλ€.</p>"; | |
| } | |
| </script> | |
| </body> | |
| </html> |