GoshawkVortexAI commited on
Commit
3a5e4d6
·
verified ·
1 Parent(s): 6b267ed

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +42 -2
index.html CHANGED
@@ -74,6 +74,10 @@ table{width:100%;border-collapse:collapse;font-size:13px}th,td{text-align:left;p
74
  .vh{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:10px;margin-bottom:18px}.vh h2{font-size:30px}
75
  .set{display:grid;gap:18px;max-width:560px}.set input[type=range]{width:100%;accent-color:var(--a)}
76
  #toast{position:fixed;left:50%;bottom:calc(20px + env(safe-area-inset-bottom,0px));transform:translate(-50%,30px);background:var(--p2);border:1px solid var(--a);padding:10px 18px;border-radius:99px;font-size:13px;opacity:0;transition:.3s;z-index:90;pointer-events:none}#toast.on{opacity:1;transform:translate(-50%,0)}
 
 
 
 
77
  @media(max-width:980px){aside{transform:translateX(-100%);transition:.25s}aside.open{transform:none;box-shadow:0 0 0 100vmax #0009}main{margin-left:0;padding:62px 16px 30px}.menu{display:block}.hero{grid-template-columns:1fr}.art{display:none}.kpis{grid-template-columns:repeat(2,1fr)}.c5,.c7,.c4,.c6,.c8{grid-column:span 12}}
78
  @media print{aside,.menu,.tools,.btn{display:none!important}main{margin:0}body{background:#fff;color:#000}.card{background:#fff;border-color:#999}}
79
  </style>
@@ -151,6 +155,8 @@ table{width:100%;border-collapse:collapse;font-size:13px}th,td{text-align:left;p
151
  <div class="sec">Diğer olası sınıflar</div><div class="oth" id="o"></div>
152
  <div class="sec">Özet</div><div class="sum" id="sm">Analiz için bir belge yükleyin.</div>
153
  <div class="sec">Çıkarılan bilgiler</div><div class="row" id="en" style="margin-top:6px"><span class="chip">–</span></div>
 
 
154
  </div>
155
  <div class="card c4"><h3><svg class="i"><use href="#bar"/></svg>Sınıf Dağılımı</h3><div class="donut"><div class="ring" id="ring"><span id="rt2">0</span></div><div class="lg" id="lg"></div></div></div>
156
  <div class="card c4"><h3><svg class="i"><use href="#cal"/></svg>Son 7 Gün</h3><div class="days" id="days"></div></div>
@@ -185,6 +191,11 @@ table{width:100%;border-collapse:collapse;font-size:13px}th,td{text-align:left;p
185
  <div class="card"><div class="set">
186
  <div><label for="th">GÜVEN EŞİĞİ: <b id="thv">50</b>%</label><input type="range" id="th" min="30" max="95" value="50"></div>
187
  <div><label for="tm">VURGU RENGİ</label><select id="tm"><option value="gold">Altın</option><option value="violet">Mor</option></select></div>
 
 
 
 
 
188
  <div><button class="btn o" onclick="clearH()">Geçmişi Temizle</button></div></div></div></div>
189
  </main>
190
  <div id="toast"></div>
@@ -211,6 +222,7 @@ const SAMPLES={
211
  const USERS0=[{u:"admin",p:"admin123",r:"Yönetici"}];
212
  const LS={get(k,d){try{return JSON.parse(localStorage.getItem(k))??d}catch(e){return d}},set(k,v){try{localStorage.setItem(k,JSON.stringify(v))}catch(e){}}};
213
  let H=LS.get("lx_h",[]),EXTRA=LS.get("lx_u",[]),ST=LS.get("lx_s",{th:50,tm:"gold"}),ME=null;
 
214
  const esc=s=>String(s).replace(/[&<>"]/g,c=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"}[c]));
215
  const pc=v=>(v*100).toFixed(1);
216
  function toast(m){const t=$("toast");t.textContent=m;t.classList.add("on");setTimeout(()=>t.classList.remove("on"),2200)}
@@ -358,7 +370,7 @@ function analyze(text,name){
358
  const t0=performance.now();const r=classify(text);if(!r)return null;
359
  const e=entities(text);const ms=+(((performance.now()-t0)/1000)+.5+Math.random()*.5).toFixed(1);
360
  const rec={d:Date.now(),n:name||text.split("\n")[0].slice(0,48),l:r.label,c:r.conf,ms,tc:e.tc};
361
- H.unshift(rec);H=H.slice(0,400);LS.set("lx_h",H);return{r,e,rec,sum:summary(text)};
362
  }
363
  function show(a){const{r,e}=a;const low=r.conf*100<ST.th;
364
  $("rl").textContent=r.label;$("rc").textContent="Güven: %"+pc(r.conf);$("rb").style.width=r.conf*100+"%";
@@ -367,7 +379,7 @@ function show(a){const{r,e}=a;const low=r.conf*100<ST.th;
367
  $("sm").textContent=a.sum;
368
  const ch=[...e.dates.map(x=>"📅 "+x),...e.amt.map(x=>"💰 "+x),...e.cases.map(x=>"⚖️ "+x)].map(x=>`<span class="chip a">${esc(x)}</span>`);
369
  if(e.tc)ch.push('<span class="chip w">⚠ KVKK: 11 haneli kimlik no tespit edildi</span>');
370
- $("en").innerHTML=ch.join("")||'<span class="chip">Varlık bulunamadı</span>';refresh()}
371
  function reset(){$("rl").textContent="Belge bekleniyor";$("rc").textContent="Güven: –";$("rb").style.width=0;$("rt").innerHTML=$("o").innerHTML="";$("sm").textContent="Analiz için bir belge yükleyin.";$("en").innerHTML='<span class="chip">–</span>'}
372
  function run(name){const x=$("txt").value.trim();if(!x){toast("Önce metin girin veya dosya yükleyin");return}
373
  const a=analyze(x,name);if(!a){reset();$("rl").textContent="Belirlenemedi";toast("Daha belirgin bir metin deneyin");return}show(a)}
@@ -396,6 +408,34 @@ function delH(d){H=H.filter(h=>h.d!==d);LS.set("lx_h",H);refresh()}
396
  $("th").oninput=e=>{ST.th=+e.target.value;$("thv").textContent=ST.th;LS.set("lx_s",ST)};
397
  $("tm").onchange=e=>{ST.tm=e.target.value;document.documentElement.dataset.theme=ST.tm;LS.set("lx_s",ST)};
398
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
399
  function bars(el,rows,tot){el.innerHTML=rows.map(([k,n])=>`<div class="r" style="grid-template-columns:130px 1fr 52px"><span>${esc(k)}</span><div class="bar"><i style="width:${tot?n/tot*100:0}%"></i></div><span>${n}</span></div>`).join("")}
400
  function refresh(){
401
  const n=H.length,day=new Date().toDateString();
 
74
  .vh{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:10px;margin-bottom:18px}.vh h2{font-size:30px}
75
  .set{display:grid;gap:18px;max-width:560px}.set input[type=range]{width:100%;accent-color:var(--a)}
76
  #toast{position:fixed;left:50%;bottom:calc(20px + env(safe-area-inset-bottom,0px));transform:translate(-50%,30px);background:var(--p2);border:1px solid var(--a);padding:10px 18px;border-radius:99px;font-size:13px;opacity:0;transition:.3s;z-index:90;pointer-events:none}#toast.on{opacity:1;transform:translate(-50%,0)}
77
+ .qw{margin-top:6px;padding:13px 15px;border-radius:12px;border:1px solid var(--ln);background:#090b1c;font-size:14px;line-height:1.65;color:#d7d9f2;white-space:pre-wrap;min-height:48px}
78
+ .qw.load:after{content:"▍";color:var(--a);animation:bl 1s steps(2) infinite}@keyframes bl{50%{opacity:0}}
79
+ .qw.er{color:var(--r)}.qh{display:flex;justify-content:space-between;align-items:center;gap:8px}.qh .sec{margin-top:14px}
80
+ .ck{display:flex;align-items:center;gap:8px;font-size:14px;color:var(--tx);margin:0}.ck input{width:auto}
81
  @media(max-width:980px){aside{transform:translateX(-100%);transition:.25s}aside.open{transform:none;box-shadow:0 0 0 100vmax #0009}main{margin-left:0;padding:62px 16px 30px}.menu{display:block}.hero{grid-template-columns:1fr}.art{display:none}.kpis{grid-template-columns:repeat(2,1fr)}.c5,.c7,.c4,.c6,.c8{grid-column:span 12}}
82
  @media print{aside,.menu,.tools,.btn{display:none!important}main{margin:0}body{background:#fff;color:#000}.card{background:#fff;border-color:#999}}
83
  </style>
 
155
  <div class="sec">Diğer olası sınıflar</div><div class="oth" id="o"></div>
156
  <div class="sec">Özet</div><div class="sum" id="sm">Analiz için bir belge yükleyin.</div>
157
  <div class="sec">Çıkarılan bilgiler</div><div class="row" id="en" style="margin-top:6px"><span class="chip">–</span></div>
158
+ <div class="qh"><div class="sec">🤖 Qwen Yorumu</div><button class="chip k" id="qb" onclick="qwenAgain()" style="margin-top:12px">Yenile</button></div>
159
+ <div class="qw" id="qw">Sınıflandırmadan sonra Qwen burada yorum yapacak.</div>
160
  </div>
161
  <div class="card c4"><h3><svg class="i"><use href="#bar"/></svg>Sınıf Dağılımı</h3><div class="donut"><div class="ring" id="ring"><span id="rt2">0</span></div><div class="lg" id="lg"></div></div></div>
162
  <div class="card c4"><h3><svg class="i"><use href="#cal"/></svg>Son 7 Gün</h3><div class="days" id="days"></div></div>
 
191
  <div class="card"><div class="set">
192
  <div><label for="th">GÜVEN EŞİĞİ: <b id="thv">50</b>%</label><input type="range" id="th" min="30" max="95" value="50"></div>
193
  <div><label for="tm">VURGU RENGİ</label><select id="tm"><option value="gold">Altın</option><option value="violet">Mor</option></select></div>
194
+ <div><label class="ck"><input type="checkbox" id="qo"> Sınıflandırmadan sonra Qwen yorumu</label></div>
195
+ <div><label for="qm">QWEN MODEL</label><input type="text" id="qm" placeholder="Qwen/Qwen2.5-7B-Instruct"></div>
196
+ <div><label for="qe">API ADRESİ (OpenAI uyumlu)</label><input type="text" id="qe"></div>
197
+ <div><label for="qt">HUGGING FACE TOKEN (hf_…)</label><input type="password" id="qt" autocomplete="off" placeholder="hf_xxxxxxxx"></div>
198
+ <div style="font-size:12px;color:var(--mu);line-height:1.6">Token yalnızca bu tarayıcıda saklanır. Yorum için belgenin ilk ~3000 karakteri seçtiğiniz API'ye gönderilir.</div>
199
  <div><button class="btn o" onclick="clearH()">Geçmişi Temizle</button></div></div></div></div>
200
  </main>
201
  <div id="toast"></div>
 
222
  const USERS0=[{u:"admin",p:"admin123",r:"Yönetici"}];
223
  const LS={get(k,d){try{return JSON.parse(localStorage.getItem(k))??d}catch(e){return d}},set(k,v){try{localStorage.setItem(k,JSON.stringify(v))}catch(e){}}};
224
  let H=LS.get("lx_h",[]),EXTRA=LS.get("lx_u",[]),ST=LS.get("lx_s",{th:50,tm:"gold"}),ME=null;
225
+ ST=Object.assign({qo:true,qe:"https://router.huggingface.co/v1/chat/completions",qm:"Qwen/Qwen2.5-7B-Instruct",qt:""},ST);
226
  const esc=s=>String(s).replace(/[&<>"]/g,c=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"}[c]));
227
  const pc=v=>(v*100).toFixed(1);
228
  function toast(m){const t=$("toast");t.textContent=m;t.classList.add("on");setTimeout(()=>t.classList.remove("on"),2200)}
 
370
  const t0=performance.now();const r=classify(text);if(!r)return null;
371
  const e=entities(text);const ms=+(((performance.now()-t0)/1000)+.5+Math.random()*.5).toFixed(1);
372
  const rec={d:Date.now(),n:name||text.split("\n")[0].slice(0,48),l:r.label,c:r.conf,ms,tc:e.tc};
373
+ H.unshift(rec);H=H.slice(0,400);LS.set("lx_h",H);return{r,e,rec,sum:summary(text),text};
374
  }
375
  function show(a){const{r,e}=a;const low=r.conf*100<ST.th;
376
  $("rl").textContent=r.label;$("rc").textContent="Güven: %"+pc(r.conf);$("rb").style.width=r.conf*100+"%";
 
379
  $("sm").textContent=a.sum;
380
  const ch=[...e.dates.map(x=>"📅 "+x),...e.amt.map(x=>"💰 "+x),...e.cases.map(x=>"⚖️ "+x)].map(x=>`<span class="chip a">${esc(x)}</span>`);
381
  if(e.tc)ch.push('<span class="chip w">⚠ KVKK: 11 haneli kimlik no tespit edildi</span>');
382
+ $("en").innerHTML=ch.join("")||'<span class="chip">Varlık bulunamadı</span>';refresh();LAST=a;if(ST.qo)qwen(a)}
383
  function reset(){$("rl").textContent="Belge bekleniyor";$("rc").textContent="Güven: –";$("rb").style.width=0;$("rt").innerHTML=$("o").innerHTML="";$("sm").textContent="Analiz için bir belge yükleyin.";$("en").innerHTML='<span class="chip">–</span>'}
384
  function run(name){const x=$("txt").value.trim();if(!x){toast("Önce metin girin veya dosya yükleyin");return}
385
  const a=analyze(x,name);if(!a){reset();$("rl").textContent="Belirlenemedi";toast("Daha belirgin bir metin deneyin");return}show(a)}
 
408
  $("th").oninput=e=>{ST.th=+e.target.value;$("thv").textContent=ST.th;LS.set("lx_s",ST)};
409
  $("tm").onchange=e=>{ST.tm=e.target.value;document.documentElement.dataset.theme=ST.tm;LS.set("lx_s",ST)};
410
 
411
+ /* Qwen yorumu */
412
+ let LAST=null,QAC=null;
413
+ function qwenAgain(){if(LAST)qwen(LAST,true);else toast("Önce bir belge analiz edin")}
414
+ async function qwen(a,force){
415
+ const box=$("qw");
416
+ if(!ST.qt){box.className="qw er";box.textContent="Qwen için Ayarlar'dan Hugging Face token girin.";return}
417
+ if(QAC)QAC.abort();QAC=new AbortController();
418
+ box.className="qw load";box.textContent="";
419
+ const{r,e}=a;
420
+ const info=`Sınıf: ${r.label} (güven %${pc(r.conf)})\nAnahtar kelimeler: ${r.kw.join(", ")||"-"}\nTarihler: ${e.dates.join(", ")||"-"}\nTutarlar: ${e.amt.join(", ")||"-"}\nDosya no: ${e.cases.join(", ")||"-"}\nKimlik no tespit edildi: ${e.tc?"evet":"hayır"}`;
421
+ const body={model:ST.qm,stream:true,max_tokens:350,temperature:.3,messages:[
422
+ {role:"system",content:"Sen Türk hukuku konusunda yardımcı bir asistansın. Bir sınıflandırıcının sonucunu ve belge metnini alırsın. Türkçe, en fazla 120 kelimeyle yorumla: 1) Belge ne ve sınıflandırma makul mü, 2) Dikkat edilmesi gereken noktalar/riskler, 3) Önerilen sonraki adım. Kısa maddeler kullan. Kesin hukuki tavsiye verme."},
423
+ {role:"user",content:info+"\n\nBelge metni:\n"+a.text.slice(0,3000)}]};
424
+ try{
425
+ const res=await fetch(ST.qe,{method:"POST",signal:QAC.signal,headers:{"Content-Type":"application/json",Authorization:"Bearer "+ST.qt},body:JSON.stringify(body)});
426
+ if(!res.ok){let m="";try{m=(await res.json()).error;m=m.message||m}catch(x){}throw new Error("HTTP "+res.status+(m?" – "+m:""))}
427
+ const rd=res.body.getReader(),dc=new TextDecoder();let buf="",out="";
428
+ for(;;){const{done,value}=await rd.read();if(done)break;buf+=dc.decode(value,{stream:true});
429
+ const ls=buf.split("\n");buf=ls.pop();
430
+ for(const l of ls){if(!l.startsWith("data:"))continue;const d=l.slice(5).trim();if(d==="[DONE]")continue;
431
+ try{const t=JSON.parse(d).choices[0].delta.content;if(t){out+=t;box.textContent=out}}catch(x){}}}
432
+ box.className="qw";if(!out)box.textContent="Boş yanıt geldi."
433
+ }catch(err){if(err.name==="AbortError")return;box.className="qw er";box.textContent="Qwen hatası: "+err.message}
434
+ }
435
+ $("qo").checked=!!ST.qo;$("qm").value=ST.qm;$("qe").value=ST.qe;$("qt").value=ST.qt;
436
+ $("qo").onchange=e=>{ST.qo=e.target.checked;LS.set("lx_s",ST)};
437
+ [["qm","qm"],["qe","qe"],["qt","qt"]].forEach(([i,k])=>$(i).onchange=e=>{ST[k]=e.target.value.trim();LS.set("lx_s",ST);toast("Kaydedildi")});
438
+
439
  function bars(el,rows,tot){el.innerHTML=rows.map(([k,n])=>`<div class="r" style="grid-template-columns:130px 1fr 52px"><span>${esc(k)}</span><div class="bar"><i style="width:${tot?n/tot*100:0}%"></i></div><span>${n}</span></div>`).join("")}
440
  function refresh(){
441
  const n=H.length,day=new Date().toDateString();