PageSourceSearch

https://vogclub.com/dist/chunks/backgammonArchive-CfXjwsii.js

js vogclub.com collected 2026-09-24 22:17:51 UTC 12,106 bytes, 1 lines download raw bytes

1import{r as h,j as e}from"../islands.js";import{q as k,p as N,B as M}from"./BackgammonBoard-D7-ZGUy_.js";import{i as _}from"./initialPosition-DGZYz0Y1.js";import{buildBackgammonReplay as D,backgammonNames as C}from"./backgammonReplay-YBKbmMke.js";const f=s=>s[0]===s[1]?4*s[0]:s[0]+s[1],w=(()=>{let s=0,t=0;for(let o=1;o<=6;o++)for(let x=1;x<=6;x++){const a=f([o,x]);s+=a,t+=a*a}const l=s/36;return{mean:l,sd:Math.sqrt(t/36-l*l)}})(),E=w.mean,T=w.sd,A=(s,t)=>t===0?0:(s-E)/(T/Math.sqrt(t)),B=s=>!!s&&(s.acey_deucey===!0||!!s.gul_bara&&s.gul_bara!=="none"||s.complementary_doublet===!0),y=s=>({side:s,rolls:0,pips:0,avg:0,doubles:0,luck:0,pairs:{}});function P(s){var x;const t=y("black"),l=y("white");let o;for(const a of s){const n=(x=a.move)==null?void 0:x.dice;if(!a.move||!n||!n[0]||!n[1])continue;const p=a.move.side==="black"?t:l,r=f(n);p.rolls++,p.pips+=r,n[0]===n[1]&&p.doubles++;const d=`${Math.max(n[0],n[1])}-${Math.min(n[0],n[1])}`;p.pairs[d]=(p.pairs[d]??0)+1,(!o||r>f(o.dice))&&(o={side:a.move.side,dice:n,no:a.move.no})}for(const a of[t,l])a.avg=a.rolls?a.pips/a.rolls:0,a.luck=A(a.avg,a.rolls);return{sides:[t,l],pipsGap:t.pips-l.pips,best:o}}const S=s=>`${s>0?"+":""}${s.toFixed(2)}`,R=s=>s>=2?"text-[#4ade80]":s<=-2?"text-[#f87171]":"text-[#e6edf3]";function L({frames:s,names:t,rules:l}){const o=h.useMemo(()=>P(s),[s]);if(B(l))return e.jsxs("section",{className:"mt-4 rounded-lg border border-[#21262d] bg-[#0b0f14] px-4 py-3 text-sm text-[#9ca3af]","data-testid":"backgammon-dice-panel",children:[e.jsx("h3",{className:"mb-1 font-semibold text-[#e6edf3]",children:"Кости"}),"Разбор бросков не даётся: по правилам этой партии дуплеты достаются и не броском, в записи их не отличить."]});const[x,a]=o.sides;if(x.rolls+a.rolls===0)return null;const n=o.pipsGap,p=n>0?t[0]:n<0?t[1]:"";return e.jsxs("section",{className:"mt-4 rounded-lg border border-[#21262d] bg-[#0b0f14] px-4 py-3 text-sm","data-testid":"backgammon-dice-panel",children:[e.jsxs("div",{className:"mb-2 flex flex-wrap items-baseline gap-x-3 gap-y-1",children:[e.jsx("h3",{className:"font-semibold text-[#e6edf3]",children:"Кости"}),e.jsxs("span",{className:"text-xs text-[#6b7280]",children:["очки броска: сумма граней, дуплет вчетверо; ожидание ",E.toFixed(2),"; везение — отклонение среднего броска в единицах разброса (z), до ±2 — обычное"]})]}),e.jsxs("table",{className:"w-full text-sm",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"text-left text-[11px] uppercase tracking-wide text-[#6b7280]",children:[e.jsx("th",{className:"py-1 pr-2 font-medium",children:" "}),e.jsx("th",{className:"py-1 pr-2 text-right font-medium",children:"бросков"}),e.jsx("th",{className:"py-1 pr-2 text-right font-medium",children:"очков"}),e.jsx("th",{className:"py-1 pr-2 text-right font-medium",children:"средний"}),e.jsx("th",{className:"py-1 pr-2 text-right font-medium",children:"дуплетов"}),e.jsx("th",{className:"py-1 text-right font-medium",children:"везение"})]})}),e.jsx("tbody",{children:o.sides.map((r,d)=>e.jsxs("tr",{className:"border-t border-[#21262d]","data-testid":`backgammon-dice-${r.side}`,children:[e.jsxs("td",{className:"py-1 pr-2",children:[e.jsx("span",{className:d===0?"mr-2 text-[#9ca3af]":"mr-2 text-white",children:d===0?"●":"○"}),t[d]]}),e.jsx("td",{className:"py-1 pr-2 text-right tabular-nums",children:r.rolls}),e.jsx("td",{className:"py-1 pr-2 text-right tabular-nums",children:r.pips}),e.jsx("td",{className:"py-1 pr-2 text-right tabular-nums",children:r.rolls?r.avg.toFixed(2):"—"}),e.jsxs("td",{className:"py-1 pr-2 text-right tabular-nums",children:[r.doubles,r.rolls>0&&e.jsxs("span",{className:"ml-1 text-xs text-[#6b7280]",children:["(",Math.round(r.doubles/r.rolls*100)," %)"]})]}),e.jsx("td",{className:`py-1 text-right tabular-nums font-semibold ${R(r.luck)}`,children:r.rolls?S(r.luck):"—"})]},r.side))})]}),e.jsxs("p",{className:"mt-2 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-[#9ca3af]","data-testid":"backgammon-dice-summary",children:[p?e.jsxs("span",{children:["костями набросано больше у ",e.jsx("b",{className:"text-[#e6edf3]",children:p}),": на ",Math.abs(n)," ",F(Math.abs(n))]}):e.jsx("span",{children:"очков костями поровну"}),o.best&&e.jsxs("span",{className:"inline-flex items-center gap-2",children:["лучший бросок — ход ",o.best.no,", ",o.best.
1side==="black"?t[0]:t[1],":"," ",e.jsxs("b",{className:"font-mono text-[#e6edf3]",children:[o.best.dice[0],"-",o.best.dice[1]]})," ",e.jsx(k,{dice:o.best.dice})]})]})]})}const F=s=>{const t=s%10,l=s%100;return t===1&&l!==11?"очко":t>=2&&t<=4&&(l<12||l>14)?"очка":"очков"},I=()=>{},q=s=>{if(!s)return"";const t=new Date(s);return Number.isNaN(t.getTime())?"":new Intl.DateTimeFormat("ru",{dateStyle:"medium",timeStyle:"short"}).format(t)},v=["","обычная","марс","кокс"];function K({frame:s,rules:t,names:l}){return e.jsxs("div",{className:"flex w-full flex-col gap-2","data-testid":"backgammon-frame",children:[e.jsxs("div",{className:"flex flex-wrap items-center gap-3 rounded px-3 py-2 text-sm text-[#ffdeb5]",style:{backgroundColor:"rgb(73,36,18)"},children:[e.jsxs("span",{className:"font-mono","data-testid":"backgammon-frame-score",children:["● ",l[0]," ",s.score[0]," : ",s.score[1]," ",l[1]," ○"]}),e.jsxs("span",{className:"text-[#e6dbb5]",children:["партия ",s.subgame]}),e.jsxs("span",{className:"font-mono text-xs text-[#e6deb5]",title:"Пипсы: сколько осталось пройти до выноса","data-testid":"backgammon-frame-pips",children:["пипсы ",N(s.board,"black",t)," : ",N(s.board,"white",t)]}),s.move&&e.jsxs("span",{className:"flex items-center gap-2",children:[e.jsx("span",{children:s.move.side==="black"?"●":"○"}),e.jsx(k,{dice:s.move.dice}),e.jsx("span",{className:"font-mono",children:s.move.text.replace(/^\d\d: /,"")})]}),s.subgameEnd&&e.jsx("span",{className:"font-bold text-[#fde68a]","data-testid":"backgammon-frame-end",children:s.subgameEnd.winner?`${s.subgameEnd.winner==="black"?l[0]:l[1]}: +${s.subgameEnd.points}${v[s.subgameEnd.endType]?` (${v[s.subgameEnd.endType]})`:""}`:"ничья"})]}),e.jsx(M,{board:s.board,mySide:null,disabled:!0,rules:t,cube:s.cube,onCellClick:I,gameOver:s.subgameEnd?{info:{names:l,winner:s.subgameEnd.winner,endType:s.subgameEnd.endType,points:s.subgameEnd.points,match:s.matchEnd??null}}:null})]})}const z={win:"Победа",resign:"Победа по сдаче",flag:"Победа по истечении времени",timeout:"Победа по истечении времени",abort:"Партия прервана",draw:"Ничья"};function W({transcript:s}){var j;const t=h.useMemo(()=>D(s),[s]),l=h.useMemo(()=>C(s),[s]),{frames:o,violation:x}=t,a=o.length-1,[n,p]=h.useState(()=>_(a)),r=h.useRef(null),d=i=>p(Math.max(0,Math.min(a,i)));h.useEffect(()=>{const i=c=>{const m=c.target;m!=null&&m.isContentEditable||["INPUT","TEXTAREA","SELECT"].includes((m==null?void 0:m.tagName)??"")||c.altKey||c.ctrlKey||c.metaKey||((c.key==="ArrowLeft"||c.key==="ArrowUp")&&(c.preventDefault(),p(u=>Math.max(0,u-1))),(c.key==="ArrowRight"||c.key==="ArrowDown")&&(c.preventDefault(),p(u=>Math.min(a,u+1))))};return window.addEventListener("keydown",i),()=>window.removeEventListener("keydown",i)},[a]),h.useEffect(()=>{var i,c;(c=(i=r.current)==null?void 0:i.scrollIntoView)==null||c.call(i,{block:"nearest"})},[n]);const $=o[Math.max(0,Math.min(n,a))],b=s.result,g=b?`${z[b.reason??""]??"Партия завершена"}${b.winner?`: ${l[b.winner-1]}`:""}${b.score?` · ${b.score[0]} : ${b.score[1]}`:""}`:"";return e.jsxs("div",{className:"mx-auto max-w-[1280px]","data-testid":"backgammon-archive",children:[e.jsxs("header",{className:"mb-5",children:[e.jsx("p",{className:"text-xs font-semibold uppercase tracking-[.16em] text-[#60a5fa]",children:"Архивная партия"}),e.jsxs("h1",{className:"mt-1 text-2xl font-bold sm:text-3xl",children:[l[0]," — ",l[1]]}),e.jsxs("div",{className:"mt-2 flex flex-wrap gap-x-4 gap-y-1 text-sm text-[#9ca3af]",children:[e.jsxs("span",{children:["Нарды",(j=s.rules)!=null&&j.match_points?` · матч до ${s.rules.match_points}`:""]}),e.jsx("span",{children:s.rated||s.class==="rated"?"Рейтинговая":"Нерейтинговая"}),s.finished_at&&e.jsx("span",{children:q(s.finished_at)}),g&&e.jsx("span",{className:"text-[#d1d5db]",children:g})]})]}),e.jsxs("div",{className:"grid gap-5 lg:grid-cols-[minmax(0,820px)_minmax(280px,1fr)]",children:[e.jsxs("section",{className:"rounded-xl border border-[#21262d] bg-[#0d1117] p-3 sm:p-5","aria-label":"Позиция партии",children:[x&&e.jsxs("div",{role:"alert","data-testid":"archive-violation",className:"mb-4 rounded-lg border border-red-700/70 bg-red-950/50 px-4 py-3 text-sm text-red-100",children:[e.jsxs("p",{className:"font-semibold",children:["Ход ",x.moveNo,": запись не сходится с правилами"]}),e.jsx("p",{className:"mt-1 font-mono text-xs text-red-300",children:x.reason})]}),e.jsx(K,{frame:$,rules:t.boardRules,names:l}),e.jsxs("div",{className:"mt-4 flex flex-wrap items-center justify-between gap-3 border-t border-[#21262d] pt-4",children:[e.jsxs("div",{className:"text-sm text-[#9ca3af]","data-testid":"archive-position",children:["Позиция ",e.jsx("strong",{className:"text-[#e6edf3]",children:n})," из ",a]}),e.jsxs("div",{className:"flex items-center gap-2","aria-label":"Навигация по ходам",children:[e.jsx("button",{type:"button",onClick:()=>d(0),disabled:n===0,"aria-label":"В начало",className:"archive-nav-button",children:"|‹"}),e.jsx("button",{type:"button",onClick:()=>d(n-1),disabled:n===0,"aria-label":"Шаг назад",className:"archive-nav-button",children:"←"}),e.jsx("button",{type:"button",onClick:()=>d(n+1),disabled:n===a,"aria-label":"Шаг вперёд",className:"archive-nav-button",children:"→"}),e.jsx("button",{type:"button",onClick:()=>d(a),disabled:n===a,"aria-label":"В конец",className:"archive-nav-button",children:"›|"})]})]}),e.jsx("p",{className:"mt-2 text-xs text-[#6b7280]",children:"Клавиши ←/↑ — назад, →/↓ — вперёд. По ходу в списке можно перейти сразу."}),e.jsx(L,{frames:o,names:l,rules:s.rules})]}),e.jsxs("aside",{className:"flex min-h-0 flex-col rounded-xl border border-[#21262d] bg-[#0d1117] p-3 sm:p-4",children:[e.jsx("h2",{className:"mb-3 font-semibold",children:"Ходы"}),e.jsx("ol",{className:"max-h-[700px] space-y-1 overflow-y-auto pr-1",children:o.map((i,c)=>{const m=c===n;return i.move?e.jsx("li",{children:e.jsxs("button",{ref:m?r:void 0,type:"button",onClick:()=>d(c),"aria-current":m?"step":void 0,"data-testid":`archive-move-${i.move.no}`,className:["grid w-full grid-cols-[2.5rem_1fr] items-center gap-2 rounded px-2 py-1.5 text-left text-sm transition",m?"bg-[#1f3a5f] text-white ring-1 ring-[#3b82f6]":"hover:bg-[#161b22]"].join(" "),children:[e.jsxs("span",{className:"font-mono text-xs text-[#9ca3af]",children:[i.move.no,"."]}),e.jsxs("span",{children:[e.jsx("span",{className:i.move.side==="black"?"mr-2 text-[#9ca3af]":"mr-2 text-white",children:i.move.side==="black"?"●":"○"}),e.jsx("span",{className:"font-mono",children:i.move.text}),i.subgameEnd&&e.jsxs("span",{className:"ml-2 text-xs text-[#fde68a]",children:[i.score[0]," : ",i.score[1]]})]})]})},`m-${c}`):e.jsx("li",{children:e.jsxs("button",{ref:m?r:void 0,type:"button",onClick:()=>d(c),"aria-current":m?"step":void 0,"data-testid":`archive-subgame-${i.subgame}`,className:`mt-2 w-full rounded px-2 py-1 text-left text-xs font-semibold uppercase tracking-wider ${m?"bg-[#1f3a5f] text-white":"text-[#60a5fa] hover:bg-[#161b22]"}`,children:["Партия ",i.subgame]})},`s-${c}`)})})]})]})]})}export{W as BackgammonArchive,K as BackgammonFrameBoard};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.