diff --git a/app/controllers/User.scala b/app/controllers/User.scala
index 46ecfa98547d..aba1df138d2a 100644
--- a/app/controllers/User.scala
+++ b/app/controllers/User.scala
@@ -346,8 +346,10 @@ final class User(
ctx: Context,
me: Me
): Fu[Result] =
- env.user.api.withPerfsAndEmails(username).orFail(s"No such user $username").flatMap {
- case WithPerfsAndEmails(user, emails) =>
+ env.report.api.inquiries
+ .ofModId(me.id)
+ .zip(env.user.api.withPerfsAndEmails(username).orFail(s"No such user $username"))
+ .flatMap { case (inquiry, WithPerfsAndEmails(user, emails)) =>
import views.mod.{ user as ui }
import lila.ui.ScalatagsExtensions.{ emptyFrag, given }
given lila.mod.IpRender.RenderIp = env.mod.ipRender.apply
@@ -356,7 +358,10 @@ final class User(
val timeline = env.api.modTimeline
.load(user, withPlayBans = true)
- .map(views.mod.timeline.renderGeneral)
+ .map: tl =>
+ if inquiry.exists(_.isPlay)
+ then views.mod.timeline.renderPlay(tl)
+ else views.mod.timeline.renderGeneral(tl)
.map(lila.mod.ui.mzSection("timeline")(_))
val plan =
@@ -444,7 +449,7 @@ final class User(
.log("User.renderModZone")
.as(ContentTypes.EVENT_STREAM)
.pipe(noProxyBuffer)
- }
+ }
protected[controllers] def renderModZoneActions(username: UserStr)(using ctx: Context) =
env.user.api.withPerfsAndEmails(username).orFail(s"No such user $username").flatMap {
diff --git a/modules/api/src/main/ModTimeline.scala b/modules/api/src/main/ModTimeline.scala
index 1197a695ddcc..51a7f3ad3fe0 100644
--- a/modules/api/src/main/ModTimeline.scala
+++ b/modules/api/src/main/ModTimeline.scala
@@ -113,13 +113,21 @@ object ModTimeline:
case Play
object Angle:
def filter(e: Event)(using angle: Angle): Boolean = e match
- case _: PlayBans => angle != Angle.Comm
- case l: Modlog if l.action == Modlog.chatTimeout && angle != Angle.Comm => false
+ case _: PlayBans => angle != Angle.Comm
+ case l: Modlog if l.action == Modlog.chatTimeout => angle == Angle.Comm
+ case l: Modlog if l.action == Modlog.deletePost => angle != Angle.Play
+ case l: Modlog if l.action == Modlog.disableTeam => angle != Angle.Play
+ case l: Modlog if l.action == Modlog.teamKick => angle != Angle.Play
+ case l: Modlog if l.action == Modlog.blankedPassword => angle == Angle.None
+ case l: Modlog if l.action == Modlog.weakPassword => angle == Angle.None
+ case l: Modlog if l.action == Modlog.troll => angle != Angle.Play
case l: Modlog if l.action == Modlog.modMessage =>
angle match
case Comm => !l.details.has(lila.playban.PlaybanFeedback.sittingAutoPreset.name)
case _ => true
- case _ => true
+ case r: ReportNewAtom if r.report.is(_.Comm) => angle != Angle.Play
+ case _: PublicLine => angle != Angle.Play
+ case _ => true
final class ModTimelineApi(
modLogApi: ModlogApi,
diff --git a/modules/fide/src/main/FidePlayer.scala b/modules/fide/src/main/FidePlayer.scala
index d278a1ad945c..f28eb93be705 100644
--- a/modules/fide/src/main/FidePlayer.scala
+++ b/modules/fide/src/main/FidePlayer.scala
@@ -20,8 +20,7 @@ case class FidePlayer(
blitz: Option[Elo],
blitzK: Option[KFactor],
year: Option[Int],
- inactive: Boolean,
- fetchedAt: Instant
+ inactive: Boolean
) extends lila.core.fide.Player:
def ratingOf(tc: FideTC): Option[Elo] = tc match
diff --git a/modules/fide/src/main/FidePlayerSync.scala b/modules/fide/src/main/FidePlayerSync.scala
index 652009b38dc1..5fa8c6e44d08 100644
--- a/modules/fide/src/main/FidePlayerSync.scala
+++ b/modules/fide/src/main/FidePlayerSync.scala
@@ -119,13 +119,11 @@ final private class FidePlayerSync(repo: FideRepo, ws: StandaloneWSClient)(using
.mapAsync(1)(saveIfChanged)
.runWith(lila.common.LilaStream.sinkSum)
.monSuccess(_.fideSync.time)
- _ = lila.mon.fideSync.updated.update(nbUpdated)
nbAll <- repo.player.countAll
- _ = lila.mon.fideSync.players.update(nbAll)
- nbDeleted <- setDeletedFlags(startAt)
yield
- lila.mon.fideSync.deleted.update(nbDeleted)
- logger.info(s"RelayFidePlayerApi.update upserted: $nbUpdated, deleted: $nbDeleted")
+ lila.mon.fideSync.updated.update(nbUpdated)
+ lila.mon.fideSync.players.update(nbAll)
+ logger.info(s"RelayFidePlayerApi.update upserted: $nbUpdated, total: $nbAll")
yield ()
/*
@@ -161,8 +159,7 @@ final private class FidePlayerSync(repo: FideRepo, ws: StandaloneWSClient)(using
blitz = rating(139),
blitzK = kFactor(149),
year = year,
- inactive = flags.exists(_.contains("i")),
- fetchedAt = nowInstant
+ inactive = flags.exists(_.contains("i"))
)
private def saveIfChanged(players: Seq[FidePlayer]): Future[Int] =
@@ -183,11 +180,3 @@ final private class FidePlayerSync(repo: FideRepo, ws: StandaloneWSClient)(using
)
_ <- elements.nonEmpty.so(update.many(elements).void)
yield elements.size
-
- private def setDeletedFlags(date: Instant): Fu[Int] = for
- nbDeleted <- repo.playerColl.update
- .one($doc("deleted".$ne(true), "fetchedAt".$lt(date)), $set("deleted" -> true), multi = true)
- .map(_.n)
- _ <- repo.playerColl.update
- .one($doc("deleted" -> true, "fetchedAt".$gte(date)), $unset("deleted"), multi = true)
- yield nbDeleted
diff --git a/modules/fide/src/main/FideRepo.scala b/modules/fide/src/main/FideRepo.scala
index 86a5ed2693af..b7c794d8790c 100644
--- a/modules/fide/src/main/FideRepo.scala
+++ b/modules/fide/src/main/FideRepo.scala
@@ -13,7 +13,7 @@ final private class FideRepo(
object player:
given handler: BSONDocumentHandler[FidePlayer] = Macros.handler
- val selectActive: Bdoc = $doc("deleted".$ne(true), "inactive".$ne(true))
+ val selectActive: Bdoc = $doc("inactive".$ne(true))
def selectFed(fed: hub.Federation.Id): Bdoc = $doc("fed" -> fed)
def sortStandard: Bdoc = $sort.desc("standard")
def fetch(id: FideId): Fu[Option[FidePlayer]] = playerColl.byId[FidePlayer](id)
diff --git a/modules/puzzle/src/main/PuzzleBatch.scala b/modules/puzzle/src/main/PuzzleBatch.scala
index d9f62b769a97..4895d60b5333 100644
--- a/modules/puzzle/src/main/PuzzleBatch.scala
+++ b/modules/puzzle/src/main/PuzzleBatch.scala
@@ -20,6 +20,7 @@ final class PuzzleBatch(colls: PuzzleColls, anonApi: PuzzleAnon, pathApi: Puzzle
me.foldUse(anonApi.getBatchFor(angle, difficulty, nb)): me ?=>
val tier =
if perf.nb > 5000 then PuzzleTier.good
+ else if angle.opening.isDefined then PuzzleTier.good
else if PuzzleDifficulty.isExtreme(difficulty) then PuzzleTier.good
else PuzzleTier.top
pathApi
diff --git a/modules/puzzle/src/main/PuzzleFinisher.scala b/modules/puzzle/src/main/PuzzleFinisher.scala
index fd4cf65e0702..dd0d07819d7e 100644
--- a/modules/puzzle/src/main/PuzzleFinisher.scala
+++ b/modules/puzzle/src/main/PuzzleFinisher.scala
@@ -199,9 +199,7 @@ final private[puzzle] class PuzzleFinisher(
if player.clueless then glicko._1
else glicko._1.average(glicko._2, weightOf(angle, win))
- private val VOLATILITY = lila.rating.Glicko.default.volatility
- private val TAU = 0.75d
- private val calculator = glicko2.RatingCalculator(VOLATILITY, TAU)
+ private val calculator = glicko2.RatingCalculator()
def incPuzzlePlays(puzzleId: PuzzleId): Funit =
colls.puzzle.map(_.incFieldUnchecked($id(puzzleId), Puzzle.BSONFields.plays))
diff --git a/modules/rating/src/main/Glicko.scala b/modules/rating/src/main/Glicko.scala
index cea3b5bb82ea..f1c440683e4f 100644
--- a/modules/rating/src/main/Glicko.scala
+++ b/modules/rating/src/main/Glicko.scala
@@ -62,7 +62,7 @@ object Glicko:
val defaultVolatility = 0.09d
// Chosen so a typical player's RD goes from 60 -> 110 in 1 year
- val ratingPeriodsPerDay = 0.21436d
+ val ratingPeriodsPerDay = glicko2.RatingPeriodsPerDay(0.21436d)
val default = new Glicko(1500d, maxDeviation, defaultVolatility)
@@ -76,8 +76,7 @@ object Glicko:
// rating that can be lost or gained with a single game
val maxRatingDelta = 700
- val tau = 0.75d
- val system = glicko2.RatingCalculator(tau, ratingPeriodsPerDay)
+ val system = glicko2.RatingCalculator(glicko2.Tau.default, ratingPeriodsPerDay)
def liveDeviation(p: Perf, reverse: Boolean): Double = {
system.previewDeviation(p.toRating, nowInstant, reverse)
diff --git a/modules/rating/src/main/glicko2/RatingCalculator.scala b/modules/rating/src/main/glicko2/RatingCalculator.scala
index f9f49a9e8858..89977618f4e0 100644
--- a/modules/rating/src/main/glicko2/RatingCalculator.scala
+++ b/modules/rating/src/main/glicko2/RatingCalculator.scala
@@ -1,6 +1,14 @@
package lila.rating
package glicko2
+opaque type Tau = Double
+object Tau extends OpaqueDouble[Tau]:
+ val default: Tau = 0.75d
+
+opaque type RatingPeriodsPerDay = Double
+object RatingPeriodsPerDay extends OpaqueDouble[RatingPeriodsPerDay]:
+ val default: RatingPeriodsPerDay = 0d
+
// rewrite from java https://github.com/goochjs/glicko2
object RatingCalculator:
@@ -20,18 +28,18 @@ object RatingCalculator:
(ratingDeviation / MULTIPLIER)
final class RatingCalculator(
- tau: Double = 0.75d,
- ratingPeriodsPerDay: Double = 0
+ tau: Tau = Tau.default,
+ ratingPeriodsPerDay: RatingPeriodsPerDay = RatingPeriodsPerDay.default
):
import RatingCalculator.*
- val DEFAULT_DEVIATION: Double = 350
- val CONVERGENCE_TOLERANCE: Double = 0.000001
- val ITERATION_MAX: Int = 1000
- val DAYS_PER_MILLI: Double = 1.0 / (1000 * 60 * 60 * 24)
+ private val DEFAULT_DEVIATION: Double = 350
+ private val CONVERGENCE_TOLERANCE: Double = 0.000001
+ private val ITERATION_MAX: Int = 1000
+ private val DAYS_PER_MILLI: Double = 1.0 / (1000 * 60 * 60 * 24)
- val ratingPeriodsPerMilli: Double = ratingPeriodsPerDay * DAYS_PER_MILLI
+ private val ratingPeriodsPerMilli: Double = ratingPeriodsPerDay.value * DAYS_PER_MILLI
/**
Run through all players within a resultset and calculate their new ratings.
Players within the
* resultset who did not compete during the rating period will have see their deviation increase (in line
@@ -89,6 +97,7 @@ final class RatingCalculator(
val a = Math.log(Math.pow(sigma, 2))
val delta = deltaOf(player, results)
val v = vOf(player, results)
+ val tau = this.tau.value
// step 5.2 - set the initial values of the iterative algorithm to come in step 5.4
var A: Double = a
diff --git a/modules/report/src/main/Report.scala b/modules/report/src/main/Report.scala
index dd7207647c0c..8dc42e315002 100644
--- a/modules/report/src/main/Report.scala
+++ b/modules/report/src/main/Report.scala
@@ -72,6 +72,7 @@ case class Report(
def isRecentComm = open && room == Room.Comm
def isRecentCommOf(sus: Suspect) = isRecentComm && user == sus.user.id
+ def isPlay = room == Room.Boost || room == Room.Cheat
def isAppeal = room == Room.Other && atoms.head.text == Report.appealText
def isAppealInquiryByMe(using me: MyId) = isAppeal && atoms.head.by.is(me)
diff --git a/modules/tutor/src/main/TutorGlicko.scala b/modules/tutor/src/main/TutorGlicko.scala
index e99047c74e7c..ffa36ff27575 100644
--- a/modules/tutor/src/main/TutorGlicko.scala
+++ b/modules/tutor/src/main/TutorGlicko.scala
@@ -8,16 +8,12 @@ object TutorGlicko:
private type Rating = Int
private type Score = Float
- private val VOLATILITY = Glicko.default.volatility
- private val TAU = 0.75d
-
def scoresRating(perf: Perf, scores: List[(Rating, Score)]): Rating =
- val calculator = glicko2.RatingCalculator(VOLATILITY, TAU)
+ val calculator = glicko2.RatingCalculator()
val player = perf.toRating
val results = glicko2.FloatingRatingPeriodResults(
- scores.map { case (rating, score) =>
+ scores.map: (rating, score) =>
glicko2.FloatingResult(player, glicko2.Rating(rating, 60, 0.06, 10), score)
- }
)
try calculator.updateRatings(results, true)
diff --git a/translation/dest/broadcast/de-DE.xml b/translation/dest/broadcast/de-DE.xml
index 6d203d124fda..a117e424b8a4 100644
--- a/translation/dest/broadcast/de-DE.xml
+++ b/translation/dest/broadcast/de-DE.xml
@@ -52,21 +52,21 @@
In Lichess öffnen
Teams
Bretter
- Übersicht
- Abonnieren, um bei Rundenbeginn benachrichtigt zu werden. Du kannst in deinen Benutzereinstellungen bei Übertragungen zwischen einer Benachrichtigung per Glocke oder Push-Benachrichtigungen wählen.
+ Überblick
+ Abonnieren, um bei Rundenbeginn benachrichtigt zu werden. Du kannst in deinen Benutzereinstellungen für Übertragungen zwischen einer Benachrichtigung per Glocke oder per Push-Benachrichtigung wählen.
Turnierbild hochladen
Noch keine Bretter vorhanden. Diese werden angezeigt, sobald die Partien hochgeladen werden.
- Die Bretter können per Quelle oder via %s geladen werden
+ Die Bretter können per Quelle oder via %s geladen werden
Beginnt nach %s
Diese Übertragung wird in Kürze beginnen.
Die Übertragung hat noch nicht begonnen.
Offizielle Webseite
Rangliste
- Weitere Optionen auf der %s
- Webmaster-Seite
+ Weitere Optionen auf der %s
+ Webmaster-Seite
Eine öffentliche Echtzeit-PGN-Quelle für diese Runde. Wir bieten auch eine %s für eine schnellere und effizientere Synchronisation.
Bette diese Übertragung in deine Webseite ein
- Bette %s in deine Webseite ein
+ Bette %s in deine Webseite ein
Wertungsdifferenz
Partien in diesem Turnier
Punktestand
diff --git a/translation/dest/broadcast/ko-KR.xml b/translation/dest/broadcast/ko-KR.xml
index 0a8c38c65026..99549e98f9c5 100644
--- a/translation/dest/broadcast/ko-KR.xml
+++ b/translation/dest/broadcast/ko-KR.xml
@@ -48,4 +48,25 @@
올해 나이
비레이팅
최근 토너먼트
+ Lichess에서 열기
+ 팀
+ 보드
+ 개요
+ 라운드가 시작될 때 알림을 받으려면 구독하세요. 계정 설정에서 방송을 위한 벨이나 알림 푸시를 토글할 수 있습니다.
+ 토너먼트 사진 업로드
+ 아직 보드가 없습니다. 게임들이 업로드되면 나타납니다.
+ 보드들은 소스나 %s(으)로 로드될 수 있습니다
+ %s 후 시작
+ 방송이 곧 시작됩니다.
+ 아직 방송이 시작을 하지 않았습니다.
+ 공식 웹사이트
+ 순위
+ %s에서 더 많은 정보를 확인하실 수 있습니다
+ 웹마스터 페이지
+ 이 라운드의 공개된, 실시간 PGN 소스 입니다. 보다 더 빠르고 효율적인 동기화를 위해 %s도 제공됩니다.
+ 이 방송을 웹사이트에 삼입하세요
+ %s을(를) 웹사이트에 삼입하세요
+ 레이팅 차이
+ 이 토너먼트의 게임들
+ 점수
diff --git a/translation/dest/broadcast/nb-NO.xml b/translation/dest/broadcast/nb-NO.xml
index 771eae5464f6..8cb05e4083c0 100644
--- a/translation/dest/broadcast/nb-NO.xml
+++ b/translation/dest/broadcast/nb-NO.xml
@@ -49,4 +49,25 @@
Alder i år
Uratet
Nylige turneringer
+ Åpne i Lichess
+ Lag
+ Brett
+ Oversikt
+ Abonner for å bli varslet når hver runde starter. Du kan velge varselform i kontoinnstillingene dine.
+ Last opp bilde for turneringen
+ Ingen brett. De vises når partiene er lastet opp.
+ Brett kan lastes med en kilde eller via %s
+ Starter etter %s
+ Overføringen starter straks.
+ Overføringen har ikke startet.
+ Offisiell nettside
+ Resultatliste
+ Flere alternativer på %s
+ administratorens side
+ En offentlig PGN-kilde i sanntid for denne runden. Vi tilbyr også en %s for raskere og mer effektiv synkronisering.
+ Bygg inn denne overføringen på nettstedet ditt
+ Bygg inn %s på nettstedet ditt
+ Ratingdifferanse
+ Partier i denne turneringen
+ Poengsum
diff --git a/translation/dest/broadcast/ro-RO.xml b/translation/dest/broadcast/ro-RO.xml
index 617a5be8c3b1..582dfc7c2cb2 100644
--- a/translation/dest/broadcast/ro-RO.xml
+++ b/translation/dest/broadcast/ro-RO.xml
@@ -48,4 +48,8 @@
Vârsta în acest an
Fără rating
Turnee recente
+ Deschide în Lichess
+ Echipe
+ Clasament
+ Scor
diff --git a/translation/dest/broadcast/sk-SK.xml b/translation/dest/broadcast/sk-SK.xml
index 765f0bdb5161..a376992810f4 100644
--- a/translation/dest/broadcast/sk-SK.xml
+++ b/translation/dest/broadcast/sk-SK.xml
@@ -51,4 +51,24 @@
Vek tento rok
Bez hodnotenia
Posledné turnaje
+ Otvoriť na Lichess
+ Tímy
+ Šachovnice
+ Prehľad
+ Prihláste sa, aby ste boli informovaní o začiatku každého kola. V nastaveniach účtu môžete prepnúť zvončekové alebo push upozornenia na vysielanie.
+ Nahrať obrázok pre turnaj
+ Zatiaľ žiadne šachovnice. Objavia sa po nahratí partií.
+ Šachovnice možno načítať pomocou zdroja alebo pomocou %s
+ Vysielanie sa začne čoskoro.
+ Vysielanie sa ešte nezačalo.
+ Oficiálna webstránka
+ Poradie
+ Viac možností nájdete na %s
+ stránke tvorcu
+ Verejný zdroj PGN v reálnom čase pre toto kolo. Ponúkame tiež %s na rýchlejšiu a efektívnejšiu synchronizáciu.
+ Vložiť toto vysielanie na webovú stránku
+ Vložiť %s na webovú stránku
+ Ratingový rozdiel
+ Partie tohto turnaja
+ Skóre
diff --git a/translation/dest/broadcast/tr-TR.xml b/translation/dest/broadcast/tr-TR.xml
index 2aad5b2f4f9c..49d619377306 100644
--- a/translation/dest/broadcast/tr-TR.xml
+++ b/translation/dest/broadcast/tr-TR.xml
@@ -49,4 +49,24 @@
Bu yılki yaşı
Derecelendirilmemiş
Son Turnuvalar
+ Lichess\'te aç
+ Takımlar
+ Tahtalar
+ Genel Bakış
+ Tur başladığında bildirim almak için abone olun. Hesap tercihlerinizden anlık ya da çan bildirimi tercihinizi hesap tercihlerinizden belirleyebilirsiniz.
+ Turnuva görseli yükleyin
+ Henüz tahta bulunmamaktadır. Oyunlar yüklendikçe tahtalar ortaya çıkacaktır.
+ Tahtalar bir kaynaktan ya da %sndan yüklenebilir
+ %s\'ten sonra başlar
+ Yayın az sonra başlayacak.
+ Yayın henüz başlamadı.
+ Resmî site
+ Sıralamalar
+ %snda daha fazla seçenek
+ Bu turun açık, gerçek zamanlı PGN kaynağı. Daha hızlı ve verimli senkronizasyon için %s\'ımız da bulunmaktadır.
+ İnternet sitenizde bu yayını gömülü paylaşın
+ %su İnternet sitenizde gömülü paylaşın
+ Puan farkı
+ Bu turnuvadaki maçlar
+ Skor
diff --git a/translation/dest/challenge/is-IS.xml b/translation/dest/challenge/is-IS.xml
index 3ea04e700dfa..f430e122a3a3 100644
--- a/translation/dest/challenge/is-IS.xml
+++ b/translation/dest/challenge/is-IS.xml
@@ -1,2 +1,19 @@
-
+
+ Áskoranir: %1$s
+ Skráðu þig inn til að senda áskorarnir þessa notanda.
+ %s tekur ekki við áskorunum.
+ Ekki er hægt að skora á vegna tímabundinna skákstiga í %s.
+ %s samþykkir eingöngu áskoranir frá vinum.
+ Ég tek ekki við áskorunum í augnablikinu.
+ Þetta er ekki heppilegur tími fyrir mig, vinsamlegast spyrðu aftur síðar.
+ Þessar tímaskorður er of hraðar fyrir mig, vinsamlegast skoraðu aftur á með hægari leik.
+ Þessar tímaskorður er of hægar fyrir mig, vinsamlegast skoraðu aftur á með hraðari leik.
+ Ég samþykki ekki áskoranir með þessum tímaskorðum.
+ Vinsamlegast sendu mér áskorun með stigagjöf í staðinn.
+ Vinsamlegast sendu mér áskorun til æfingar í staðinn.
+ Ég samþykki ekki afbrigðilegar áskoranir í augnablikinu.
+ Ég er ekki til í að spila þetta afbrigði í augnablikinu.
+ Ég samþykki ekki áskoranir þjarka.
+ Ég samþykki eingöngu áskoranir þjarka.
+
diff --git a/translation/dest/faq/fa-IR.xml b/translation/dest/faq/fa-IR.xml
index 4e56968f504c..98f81d418612 100644
--- a/translation/dest/faq/fa-IR.xml
+++ b/translation/dest/faq/fa-IR.xml
@@ -61,7 +61,7 @@
آموزش Lichess
کیش و مات شدن %s در مقابل استاد بینالمللی اریک روزن را تماشا کنید.
تکرار سه گانه
- اگر یک وضعیت سه بار رخ دهد، بازیکنان میتوانند با %1$s، ادعای تساوی کنند. Lichess قانونهای رسمی فیده را که در ماده 9.2 %2$s آمده را، اجرا میکند.
+ اگر یک وضعیت سه بار رخ دهد، بازیکنان میتوانند با %1$s، ادعای تساوی کنند. Lichess قانونهای رسمی فیده را که در ماده 9.2 %2$s آمده، اجرا میکند.
تکرار سه گانه
ما حرکات را تکرار نکردیم. چرا بازی همچنان با تکرار مساوی می شد؟
تکرار سهگانه درباره %1$s تکراری است، نه حرکتها. لازم نیست که تکرار، پیاپی باشد.
diff --git a/translation/dest/features/zh-TW.xml b/translation/dest/features/zh-TW.xml
index 072d8f6338ab..063978802f90 100644
--- a/translation/dest/features/zh-TW.xml
+++ b/translation/dest/features/zh-TW.xml
@@ -3,31 +3,31 @@
零廣告與追蹤
可以預先移動的通訊棋局
基本西洋棋與其他 %s
- %s 深沉分析
+ %s 深度分析
- 每天 %s 局
- 棋盤編輯器並以 %s 分析
+ 帶有 %s 的棋盤編輯器和棋局分析
雲端引擎分析
研究(可分享的永久性分析)
- 對局洞察(對棋局更加的深刻分析)
+ 對局洞察(對您棋局的深入分析)
所有基礎西洋棋課程
- 從他人棋局中生成謎題以提升西洋棋戰術
- %1$s(亦可分析%2$s)
+ 來自用戶棋局的戰術謎題
+ %1$s(亦可探索%2$s的)
個人開局瀏覽器
- 全域開局瀏覽器(%s 個棋局!)
- 7 子殘局分析器
- 下載/上傳任何 PGN 棋譜
+ 全球開局瀏覽器(%s 個棋局!)
+ 7 子殘局資料庫
+ 以 PGN 格式下載/上傳任何棋局
部落格、論壇、團隊、直播、聯絡、朋友、挑戰
- 亮暗主題、自訂棋盤、棋子、與背景
+ 亮/暗主題,自訂棋盤、棋子與背景
UltraBullet、Bullet、Blitz、快棋、經典、通訊棋
- 所有將來開發的新功能!
+ 所有持續推出的功能,永遠!
iPhones & Android 裝置與橫向模式支援
- 支援 Lichess
- 捐款給 Lichess 取得超酷的贊助者圖示!
+ 支持 Lichess
+ 贊助 Lichess 並獲得一個炫酷的贊助者圖標!
是的,兩種帳號皆有相同的功能!
- 我們相信每個人都直得擁有最好的,所以:
- 所有功能都完全免費給大家使用!
+ 我們相信每個人都值得擁有最好的,所以:
+ 所有功能都完全免費給大家使用,永遠!
如果你喜歡 Lichess,
- 考慮成為贊助者!
+ 透過成為贊助者以支持我們!
diff --git a/translation/dest/oauthScope/is-IS.xml b/translation/dest/oauthScope/is-IS.xml
index 3ea04e700dfa..c025d39b9894 100644
--- a/translation/dest/oauthScope/is-IS.xml
+++ b/translation/dest/oauthScope/is-IS.xml
@@ -1,2 +1,4 @@
-
+
+ Leiktu skákir með forritaskil þjarka
+
diff --git a/translation/dest/preferences/is-IS.xml b/translation/dest/preferences/is-IS.xml
index 8a277f82b2bd..d2e26776642f 100644
--- a/translation/dest/preferences/is-IS.xml
+++ b/translation/dest/preferences/is-IS.xml
@@ -23,7 +23,7 @@
Hvernig hreyfirðu menn?
Veldu tvo reiti
Dragðu taflmann
- Annað hvort
+ Annaðhvort
Fyrirframleikir (leiknir meðan anstæðingur á leik)
Leikir teknir upp (með leyfi mótherja)
Einungis í stigalausum leikjum
@@ -41,4 +41,5 @@
Leika með lyklaborðinu
Segja \"Good game, well played\" sjálfkrafa eftir tapi eða jafntefli
Stillingar þínar voru vistaðar
+ Áskoranir
diff --git a/translation/dest/site/fa-IR.xml b/translation/dest/site/fa-IR.xml
index 19637badde20..b07f6d0a49d1 100644
--- a/translation/dest/site/fa-IR.xml
+++ b/translation/dest/site/fa-IR.xml
@@ -2,7 +2,7 @@
بازی با دوستان
بازی با رایانه
- برای دعوت کردن حریف این لینک را برای او بفرستید
+ برای دعوت کسی به بازی، این وبنشانی را دهید
پایان بازی
انتطار برای حریف
یا اجازه دهید حریف شما این QR کد را پویش کند
@@ -163,8 +163,8 @@
- %1$s ریتینگ در %2$s بازی
- - %s بازی مورد علاقه
- - %s بازی مورد علاقه
+ - %s نشانک
+ - %s نشانک
نمایش در اندازه کامل
خروج
@@ -340,7 +340,7 @@
پیشنهاد پس گرفتن حرکت پذیرفته شد
پیشنهاد پس گرفتن حرکت لغو شد
حریف پیشنهاد پس گرفتن حرکت می دهد
- نشان گذاری بازی
+ نشانکگذاری
مسابقه
مسابقات
مجموع امتیازات مسابقات
@@ -385,7 +385,7 @@
باید در تیم %s باشید
شما در تیم %s نیستید
بازگشت به بازی
- کارساز برخط و رایگان شطرنج. با میانایی روان شطرنج بازی کنید. بدون نامنویسی، بدون تبلیغ، بدون نیاز به افزونه. با رایانه، دوستان یا حریفان تصادفی شطرنج بازی کنید.
+ کارساز برخط و رایگان شطرنج. با میانایی روان، شطرنج بازی کنید. بدون نامنویسی، بدون تبلیغ، بدون نیاز به افزونه. با رایانه، دوستان یا حریفان تصادفی شطرنج بازی کنید.
%1$s به تیم %2$s پیوست
%1$s تیم %2$s را ایجاد کرد
پخش را آغازید
diff --git a/translation/dest/site/is-IS.xml b/translation/dest/site/is-IS.xml
index 391ffc35d70c..9591f7f50a1d 100644
--- a/translation/dest/site/is-IS.xml
+++ b/translation/dest/site/is-IS.xml
@@ -27,7 +27,7 @@
Þú teflir með hvítu mennina
Þú teflir með svörtu mennina
Þú átt leik!
- Svindl greint
+ Svindl greindist
Kóngur á miðborðinu
Þrjár skákir
Kapphlaupi lokið
@@ -89,8 +89,8 @@
Bestu skákir
OTB skákir %1$s+ FIDE-stiga skákmanna frá %2$s til %3$s
- - Mát eftir %s hálfleik
- - Mát eftir %s hálfleikum
+ - Mát í %s hálfleik
+ - Mát í %s hálfleikum
Engin skák fannst
Hámarks dýpt náð!
@@ -261,8 +261,8 @@
Sérsniðin staða
Ótarkmarkað
Tegund
- Venjuleg
- Stigaleikur
+ Æfingaskák
+ Stigaskák
Æfingamót
Með stigagjöf
Þessi skák telur til stiga
@@ -361,7 +361,7 @@
%1$s stofnaði liðið %2$s
byrjaði að streyma
%s byrjaði streymi
- Meðal skákstig
+ Meðalskákstig
Staðsetning
Sía skákir
Hreinsa
@@ -398,8 +398,8 @@
Fylgja
Fylgir
Affylgja
- Fylgja %s
- Affylgja %s
+ Fylgjast með %s
+ Hætta að fylgjast með %s
Blokkera
Blokkaður
Afblokka
@@ -492,6 +492,7 @@
Skipta sjálfkrafa yfir í næstu skák eftir leik
Skipta sjálfkrafa
Þrautir
+ Tengdir þjarkar
Nafn
Lýsing
Texti sem eingöngu liðsfélagar sjá. Ef texti er til staðar kemur hann í stað opinberu lýsingarinnar í sýn liðsfélaga.
diff --git a/translation/dest/site/ko-KR.xml b/translation/dest/site/ko-KR.xml
index d5a9b76745db..a773745523dd 100644
--- a/translation/dest/site/ko-KR.xml
+++ b/translation/dest/site/ko-KR.xml
@@ -952,4 +952,5 @@ FEN 포지션을 생성하기 위해 %s를 사용할 수 있습니다.
Lichess는 비영리 기구이며 완전한 무료/자유 오픈소스 소프트웨어입니다.
모든 운영 비용, 개발, 컨텐츠 조달은 전적으로 사용자들의 기부로 이루어집니다.
지금은 여기에 볼 것이 없습니다.
+ 통계
diff --git a/translation/dest/site/nb-NO.xml b/translation/dest/site/nb-NO.xml
index f7db031ebdd2..cd797170024b 100644
--- a/translation/dest/site/nb-NO.xml
+++ b/translation/dest/site/nb-NO.xml
@@ -994,4 +994,5 @@ La feltet stå tomt for å begynne partiene fra den normale utgangsstillingen.
Lichess er en ideell forening, basert på fri programvare med åpen kildekode.
Alle kostnader for drift, utvikling og innhold finansieres utelukkende av brukerbidrag.
Ingenting her for nå.
+ Statistikk
diff --git a/translation/dest/site/ro-RO.xml b/translation/dest/site/ro-RO.xml
index 434f0218512c..6806b89f65db 100644
--- a/translation/dest/site/ro-RO.xml
+++ b/translation/dest/site/ro-RO.xml
@@ -1036,4 +1036,5 @@ Lăsați gol pentru a începe jocurile din poziția inițială normală.Lichess este o asociație non-profit și un software gratuit și open-source.
Toate costurile de operare și de dezvoltare sunt finanțate doar din donațiile utilizatorilor.
Nimic de văzut aici momentan.
+ Statistici
diff --git a/translation/dest/site/sk-SK.xml b/translation/dest/site/sk-SK.xml
index 2a948c72515d..7e6d507ae156 100644
--- a/translation/dest/site/sk-SK.xml
+++ b/translation/dest/site/sk-SK.xml
@@ -1077,4 +1077,5 @@ Nechajte prázdne pre začatie partií zo základnej pozície!
Ukázať všetko
Lichess je bezplatný a úplne slobodný/nezávislý softvér s otvoreným zdrojovým kódom. Všetky prevádzkové náklady, vývoj a obsah sú financované výlučne z darov používateľov.
Momentálne tu nie je nič k zobrazeniu.
+ Štatistiky
diff --git a/translation/dest/site/tr-TR.xml b/translation/dest/site/tr-TR.xml
index e5b666901170..40cef6bbab2d 100644
--- a/translation/dest/site/tr-TR.xml
+++ b/translation/dest/site/tr-TR.xml
@@ -992,4 +992,5 @@ Başlangıç pozisyonundan oynamak için boş bırakınız.
Bana her şeyi göster
Lichess bir yardım kuruluşudur ve tamamen özgür/açık kaynak kodlu bir yazılımdır. Tüm işletme maliyetleri, geliştirmeler ve içerikler yalnızca kullanıcı bağışları ile finanse edilmektedir.
Şu anda görülebilecek bir şey yok.
+ İstatistikler
diff --git a/ui/round/src/ctrl.ts b/ui/round/src/ctrl.ts
index 61fe1c8d41c8..c5c581790f03 100644
--- a/ui/round/src/ctrl.ts
+++ b/ui/round/src/ctrl.ts
@@ -160,7 +160,7 @@ export default class RoundController implements MoveRootCtrl {
};
private onUserMove = (orig: cg.Key, dest: cg.Key, meta: cg.MoveMetadata) => {
- if (!this.keyboardMove?.usedSan) ab.move(this, meta);
+ if (!this.keyboardMove?.usedSan) ab.move(this, meta, pubsub.emit);
if (!this.startPromotion(orig, dest, meta)) this.sendMove(orig, dest, undefined, meta);
};
diff --git a/ui/round/types/ab.d.ts b/ui/round/types/ab.d.ts
index 80a725ade8e7..e5b7cbb3e36c 100644
--- a/ui/round/types/ab.d.ts
+++ b/ui/round/types/ab.d.ts
@@ -1,5 +1,6 @@
declare module 'ab' {
import { MoveMetadata } from 'chessground/types';
+ import { Pubsub } from 'common/pubsub';
function init(round: unknown): void;
- function move(round: unknown, meta: MoveMetadata): void;
+ function move(round: unknown, meta: MoveMetadata, emit: Pubsub['emit']): void;
}
diff --git a/ui/site/src/site.ts b/ui/site/src/site.ts
index 79dac80afa1b..93614a56a727 100644
--- a/ui/site/src/site.ts
+++ b/ui/site/src/site.ts
@@ -7,10 +7,8 @@ import { unload, redirect, reload } from './reload';
import announce from './announce';
import { displayLocale } from 'common/i18n';
import sound from './sound';
-import { pubsub } from 'common/pubsub';
const site = window.site;
-(site as any).pubsub = pubsub; // do not declare in index.d.ts. some extensions need this here
// site.load is initialized in layout.scala embedded script tags
// site.manifest is fetched
// site.info, site.debug are populated by ui/build