Import source: app/src/pages/RagCalculatorPage
Import the existing local project snapshot. This commit organizes existing files; it does not represent newly developed functionality.
This commit is contained in:
@@ -0,0 +1,129 @@
|
|||||||
|
import { useState } from 'react';
|
||||||
|
import { useNav, useToast } from '../../teknav-ui.jsx';
|
||||||
|
import { LegalPage } from './shared.jsx';
|
||||||
|
|
||||||
|
export function RagCalculatorPage() {
|
||||||
|
const { navigate } = useNav();
|
||||||
|
const toast = useToast();
|
||||||
|
const [text, setText] = useState('');
|
||||||
|
const [chunkSize, setChunkSize] = useState(500);
|
||||||
|
const [overlap, setOverlap] = useState(50);
|
||||||
|
const [chunks, setChunks] = useState([]);
|
||||||
|
|
||||||
|
const handleCalculate = () => {
|
||||||
|
if (!text.trim()) {
|
||||||
|
toast('لطفاً ابتدا متنی را برای چانکبندی وارد کنید', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (chunkSize <= 0 || overlap < 0 || overlap >= chunkSize) {
|
||||||
|
toast('اندازه چانک یا همپوشانی نامعتبر است', 'error');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const t = text.trim();
|
||||||
|
const result = [];
|
||||||
|
let start = 0;
|
||||||
|
|
||||||
|
while (start < t.length) {
|
||||||
|
let end = start + chunkSize;
|
||||||
|
if (end > t.length) end = t.length;
|
||||||
|
|
||||||
|
const content = t.substring(start, end);
|
||||||
|
const estimatedTokens = Math.round(content.length / 3.8);
|
||||||
|
|
||||||
|
result.push({
|
||||||
|
id: result.length + 1,
|
||||||
|
content,
|
||||||
|
charCount: content.length,
|
||||||
|
tokenCount: estimatedTokens,
|
||||||
|
range: [start, end],
|
||||||
|
});
|
||||||
|
|
||||||
|
start += (chunkSize - overlap);
|
||||||
|
if (start >= t.length || end === t.length) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
setChunks(result);
|
||||||
|
toast(`تکهبندی با موفقیت انجام شد (${result.length} چانک)`, 'success');
|
||||||
|
};
|
||||||
|
|
||||||
|
const copyToClipboard = (val) => {
|
||||||
|
if (!val) return;
|
||||||
|
navigator.clipboard.writeText(val);
|
||||||
|
toast('کپی شد!', 'success');
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LegalPage title="محاسبهگر چانک و زمینه RAG" subtitle="شبیهسازی اندازه تکهها (Chunks)، همپوشانی (Overlap) و تخمین توکن برای سیستمهای پرسش و پاسخ با بازیابی اطلاعات.">
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
|
||||||
|
<div>
|
||||||
|
<label style={{ fontSize: 13, fontWeight: 700, color: '#0F2A2E', display: 'block', marginBottom: 8 }}>متن نمونه:</label>
|
||||||
|
<textarea
|
||||||
|
value={text}
|
||||||
|
onChange={(e) => setText(e.target.value)}
|
||||||
|
placeholder="متن فارسی مورد نظر برای شبیهسازی RAG را در این قسمت بنویسید..."
|
||||||
|
style={{ width: '100%', minHeight: 140, background: '#FAF7F0', border: '1px solid #D8D0C4', borderRadius: 8, padding: '12px 16px', fontSize: 14, fontFamily: 'Vazirmatn, sans-serif', color: '#263238', outline: 'none', lineHeight: 1.7, resize: 'vertical', boxSizing: 'border-box' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ background: '#FAF7F0', border: '1px solid #E4DDD2', borderRadius: 10, padding: 18 }}>
|
||||||
|
<h3 style={{ fontSize: 14, fontWeight: 800, color: '#0F2A2E', marginBottom: 12 }}>پارامترهای شبیهسازی</h3>
|
||||||
|
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: 16 }}>
|
||||||
|
<div>
|
||||||
|
<label style={{ fontSize: 12, color: '#5F6B6D', display: 'block', marginBottom: 5 }}>اندازه هر تکه (به کاراکتر):</label>
|
||||||
|
<input type="number" value={chunkSize} onChange={(e) => setChunkSize(Number(e.target.value))} style={{ width: '100%', padding: '10px 12px', border: '1px solid #D8D0C4', borderRadius: 8, fontSize: 14, fontFamily: 'Vazirmatn, sans-serif' }} />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<label style={{ fontSize: 12, color: '#5F6B6D', display: 'block', marginBottom: 5 }}>اندازه همپوشانی (Overlap):</label>
|
||||||
|
<input type="number" value={overlap} onChange={(e) => setOverlap(Number(e.target.value))} style={{ width: '100%', padding: '10px 12px', border: '1px solid #D8D0C4', borderRadius: 8, fontSize: 14, fontFamily: 'Vazirmatn, sans-serif' }} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ display: 'flex', gap: 12 }}>
|
||||||
|
<button onClick={handleCalculate} style={{ background: '#0F6B73', color: '#fff', border: 'none', borderRadius: 8, padding: '12px 28px', fontSize: 14, fontWeight: 600, cursor: 'pointer', fontFamily: 'Vazirmatn,sans-serif' }}>
|
||||||
|
محاسبه و شبیهسازی
|
||||||
|
</button>
|
||||||
|
<button onClick={() => navigate('/tools')} style={{ background: 'transparent', color: '#5F6B6D', border: '1px solid #D8D0C4', borderRadius: 8, padding: '12px 20px', fontSize: 14, fontWeight: 600, cursor: 'pointer', fontFamily: 'Vazirmatn,sans-serif' }}>
|
||||||
|
بازگشت
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{chunks.length > 0 && (
|
||||||
|
<div style={{ marginTop: 10 }}>
|
||||||
|
<h3 style={{ fontSize: 15, fontWeight: 800, color: '#0F2A2E', marginBottom: 12 }}>نتایج شبیهسازی تکهبندی:</h3>
|
||||||
|
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 12, marginBottom: 20 }}>
|
||||||
|
{[
|
||||||
|
['طول کل کاراکترها', text.length],
|
||||||
|
['تعداد تخمینی توکنها', Math.round(text.length / 3.8)],
|
||||||
|
['تعداد چانکهای خروجی', chunks.length],
|
||||||
|
].map(([lbl, val]) => (
|
||||||
|
<div key={lbl} style={{ background: '#FAF7F0', border: '1px solid #E4DDD2', borderRadius: 8, padding: 12, textAlign: 'center' }}>
|
||||||
|
<div style={{ fontSize: 11, color: '#5F6B6D', marginBottom: 4 }}>{lbl}</div>
|
||||||
|
<div style={{ fontSize: 16, fontWeight: 800, color: '#0F2A2E' }}>{val.toLocaleString('fa-IR')}</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
|
||||||
|
{chunks.map((c) => (
|
||||||
|
<div key={c.id} style={{ border: '1px solid #E4DDD2', borderRadius: 10, overflow: 'hidden' }}>
|
||||||
|
<div style={{ background: '#FAF7F0', borderBottom: '1px solid #E4DDD2', padding: '10px 16px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
|
||||||
|
<span style={{ fontSize: 12, fontWeight: 800, color: '#0F2A2E' }}>چانک #{c.id.toLocaleString('fa-IR')} (اندیس {c.range[0].toLocaleString('fa-IR')} تا {c.range[1].toLocaleString('fa-IR')})</span>
|
||||||
|
<div style={{ display: 'flex', gap: 12, alignItems: 'center' }}>
|
||||||
|
<span style={{ fontSize: 11, color: '#5F6B6D' }}>{c.charCount.toLocaleString('fa-IR')} کاراکتر · {c.tokenCount.toLocaleString('fa-IR')} توکن تخمینی</span>
|
||||||
|
<button onClick={() => copyToClipboard(c.content)} style={{ background: '#fff', border: '1px solid #D8D0C4', borderRadius: 4, padding: '3px 8px', fontSize: 11, cursor: 'pointer', fontFamily: 'Vazirmatn, sans-serif' }}>کپی</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style={{ padding: 16, fontSize: 13, lineHeight: 1.8, color: '#263238', background: '#fff', whiteSpace: 'pre-wrap' }}>
|
||||||
|
{c.content}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</LegalPage>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user