Merge branch 'correspondance'
* correspondance: lobby correspondence chess creation load trans files even for english language better client-side translation system upgrade perf picker more work on correspondence chess create correspondance games client-side setup more work on correspondance chess backend setup correspondance games add Correspondance PerfType and Game.correspondanceDayPerTurn
This commit is contained in:
commit
0d15b57d09
|
@ -89,7 +89,7 @@ object Setup extends LilaController with TheftPrevention with play.api.http.Cont
|
|||
implicit val req = ctx.body
|
||||
env.forms.hook(ctx).bindFromRequest.fold(
|
||||
err => negotiate(
|
||||
html = BadRequest("Invalid form data").fuccess,
|
||||
html = BadRequest(err.errorsAsJson.toString).fuccess,
|
||||
api = _ => BadRequest(err.errorsAsJson).fuccess),
|
||||
config => (ctx.userId ?? Env.relation.api.blocking) flatMap { blocking =>
|
||||
JsonOk {
|
||||
|
|
|
@ -2,11 +2,20 @@ package lila.app
|
|||
package templating
|
||||
|
||||
import chess.{ Mode, Variant, Speed }
|
||||
import lila.setup.TimeMode
|
||||
import lila.api.Context
|
||||
import lila.tournament.System
|
||||
|
||||
trait SetupHelper { self: I18nHelper =>
|
||||
|
||||
def translatedTimeModeChoices(implicit ctx: Context) = List(
|
||||
(TimeMode.Clock.id.toString, trans.clock.str(), none),
|
||||
(TimeMode.Correspondence.id.toString, trans.correspondence.str(), none),
|
||||
(TimeMode.Unlimited.id.toString, trans.unlimited.str(), none)
|
||||
).map { x =>
|
||||
x.copy(_2 = s"${trans.timeControl.str()}: ${x._2}")
|
||||
}
|
||||
|
||||
def translatedModeChoices(implicit ctx: Context) = List(
|
||||
(Mode.Casual.id.toString, trans.casual.str(), none),
|
||||
(Mode.Rated.id.toString, trans.rated.str(), none)
|
||||
|
@ -17,11 +26,13 @@ trait SetupHelper { self: I18nHelper =>
|
|||
System.Swiss.id.toString -> "Swiss [beta]"
|
||||
)
|
||||
|
||||
private def variantTuple(variant: Variant): (String, String, Option[String]) =
|
||||
(variant.id.toString, variant.name, variant.title.some)
|
||||
private def variantPrefix(name: String)(implicit ctx: Context) = s"${trans.variant.str()}: ${name}"
|
||||
|
||||
private def variantTuple(variant: Variant)(implicit ctx: Context): (String, String, Option[String]) =
|
||||
(variant.id.toString, variantPrefix(variant.name), variant.title.some)
|
||||
|
||||
def translatedVariantChoices(implicit ctx: Context) = List(
|
||||
(Variant.Standard.id.toString, trans.standard.str(), Variant.Standard.title.some),
|
||||
(Variant.Standard.id.toString, variantPrefix(trans.standard.str()), Variant.Standard.title.some),
|
||||
variantTuple(Variant.Chess960)
|
||||
)
|
||||
|
||||
|
|
|
@ -277,8 +277,8 @@ openGraph: Map[Symbol, String] = Map.empty)(body: Html)(implicit ctx: Context)
|
|||
@jsTagCompiled("strongSocket.js")
|
||||
@jsTagCompiled("big.js")
|
||||
@moreJs
|
||||
@if(lang.language != "en") {
|
||||
@jsAt(s"trans/${lang.language}.js")
|
||||
@if(lang.language != "en") {
|
||||
@momentLangTag
|
||||
}
|
||||
@base.ga()
|
||||
|
|
|
@ -17,7 +17,11 @@
|
|||
<span class="setup">
|
||||
@bookmark.toggle(game)
|
||||
@game.clock.map(_.show).getOrElse {
|
||||
@game.daysPerTurn.map { days =>
|
||||
<span data-hint="@trans.correspondence()" class="hint--top">@trans.xDays(days)</span>
|
||||
}.getOrElse {
|
||||
<span data-hint="@trans.unlimited()" class="hint--top">∞</span>
|
||||
}
|
||||
} •
|
||||
@if(game.variant.exotic) {
|
||||
@variantLink(game.variant, (if (game.variant == chess.Variant.KingOfTheHill) game.variant.shortName else game.variant.name).toUpperCase, cssClass = "hint--top")
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
@fields = {
|
||||
<div class="variants">
|
||||
@trans.variant() @setup.select(form("variant"), translatedVariantChoicesWithFenAndKingOfTheHill)
|
||||
@setup.select(form("variant"), translatedVariantChoicesWithFenAndKingOfTheHill)
|
||||
</div>
|
||||
@fenInput(form("fen"), true)
|
||||
@setup.clock(form, lila.setup.AiConfig)
|
||||
@setup.timeMode(form, lila.setup.AiConfig)
|
||||
@trans.level()
|
||||
<div class="level buttons">
|
||||
<div id="config_level">
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
@(form: Form[_], config: lila.setup.BaseConfig)(implicit ctx: Context)
|
||||
|
||||
@import lila.setup.FriendConfig
|
||||
|
||||
<div class="clock_config optional_config">
|
||||
<div class="clock_choice">
|
||||
<label class="required pointer" for="clock">@trans.timeControl()</label>
|
||||
@setup.checkbox(form("clock"))
|
||||
</div>
|
||||
<div class="time_choice">
|
||||
@trans.minutesPerSide(): <span>@form("time").value</span>
|
||||
@setup.input(
|
||||
form("time"))
|
||||
</div>
|
||||
<div class="increment_choice">
|
||||
@trans.incrementInSeconds(): <span>@form("increment").value</span>
|
||||
@setup.input(
|
||||
form("increment"))
|
||||
</div>
|
||||
</div>
|
|
@ -21,7 +21,7 @@
|
|||
}
|
||||
@ctx.me.map { me =>
|
||||
<div class="ratings">
|
||||
@List("bullet", "blitz", "classical", "chess960", "kingOfTheHill", "threeCheck").map { key =>
|
||||
@List("bullet", "blitz", "classical", "correspondence", "chess960", "kingOfTheHill", "threeCheck").map { key =>
|
||||
@lila.rating.PerfType(key).map { perfType =>
|
||||
<div class="@key">
|
||||
@trans.ratingX(s"""<strong data-icon="${perfType.iconChar}">${me.perfs(key).map(_.intRating).getOrElse("?")}</strong> ${perfType.name}""")
|
||||
|
|
|
@ -7,10 +7,10 @@
|
|||
@userLink(u, cssClass="target".some)
|
||||
}
|
||||
<div class="variants">
|
||||
@trans.variant() @setup.select(form("variant"), translatedVariantChoicesWithVariantsAndFen)
|
||||
@setup.select(form("variant"), translatedVariantChoicesWithVariantsAndFen)
|
||||
</div>
|
||||
@fenInput(form("fen"), false)
|
||||
@setup.clock(form, lila.setup.FriendConfig)
|
||||
@setup.timeMode(form, lila.setup.FriendConfig)
|
||||
@if(ctx.isAuth) {
|
||||
<div class="mode_choice buttons">
|
||||
@globalCasualOnlyMessage.getOrElse {
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
|
||||
@fields = {
|
||||
<div class="variants">
|
||||
@trans.variant() @setup.select(form("variant"), translatedVariantChoicesWithVariants)
|
||||
@setup.select(form("variant"), translatedVariantChoicesWithVariants)
|
||||
</div>
|
||||
@setup.clock(form, lila.setup.HookConfig)
|
||||
@setup.timeMode(form, lila.setup.HookConfig)
|
||||
@if(ctx.isAuth) {
|
||||
<div class="mode_choice buttons">
|
||||
@globalCasualOnlyMessage.getOrElse {
|
||||
|
@ -21,7 +21,7 @@
|
|||
@setup.checkbox(form("membersOnly"))
|
||||
</div>
|
||||
}
|
||||
<div class="rating_range_config">
|
||||
<div class="rating_range_config slider">
|
||||
@trans.ratingRange(): <span class="range">? - ?</span>
|
||||
<div class="rating_range">
|
||||
@setup.input(
|
||||
|
|
23
app/views/setup/timeMode.scala.html
Normal file
23
app/views/setup/timeMode.scala.html
Normal file
|
@ -0,0 +1,23 @@
|
|||
@(form: Form[_], config: lila.setup.BaseConfig)(implicit ctx: Context)
|
||||
|
||||
@import lila.setup.FriendConfig
|
||||
|
||||
<div class="time_mode_config optional_config">
|
||||
<div class="time_mode_choice">
|
||||
@setup.select(form("timeMode"), translatedTimeModeChoices)
|
||||
</div>
|
||||
<div class="time_choice slider">
|
||||
@trans.minutesPerSide(): <span>@form("time").value</span>
|
||||
@setup.input(form("time"))
|
||||
</div>
|
||||
<div class="increment_choice slider">
|
||||
@trans.incrementInSeconds(): <span>@form("increment").value</span>
|
||||
@setup.input(form("increment"))
|
||||
</div>
|
||||
<div class="correspondence">
|
||||
<div class="days_choice slider">
|
||||
@trans.daysPerTurn(): <span>@form("days").value</span>
|
||||
@setup.input(form("days"))
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -30,7 +30,7 @@
|
|||
<td data-icon="r"> @tour.playerRatio</td>
|
||||
<td>
|
||||
<form action="@routes.Tournament.join(tour.id)" method="POST">
|
||||
<button type="submit" class="submit button trans_me" data-icon="G"></button>
|
||||
<button type="submit" class="submit button" data-icon="G"></button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
@notification.view("tournament_reminder", cssClass = "foldable", closable = false, glow = true) {
|
||||
<a data-icon="g" href="@routes.Tournament.show(tour.id)"> @tour.name</a> in progress!
|
||||
<div class="actions">
|
||||
<a class="withdraw trans_me" href="@routes.Tournament.withdraw(tour.id)" data-icon="b"> @trans.withdraw.en()</a>
|
||||
<a class="trans_me" href="@routes.Tournament.show(tour.id)" data-icon="G"> @trans.join.en()</a>
|
||||
<a class="withdraw trans_me" href="@routes.Tournament.withdraw(tour.id)" data-icon="b">@trans.withdraw.en()</a>
|
||||
<a class="trans_me" href="@routes.Tournament.show(tour.id)" data-icon="G">@trans.join.en()</a>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
@showPerf(u.perfs.bullet, PerfType.Bullet)
|
||||
@showPerf(u.perfs.blitz, PerfType.Blitz)
|
||||
@showPerf(u.perfs.classical, PerfType.Classical)
|
||||
@showPerf(u.perfs.correspondence, PerfType.Correspondence)
|
||||
<br />
|
||||
@if(u.perfs.chess960.nonEmpty) {
|
||||
@showPerf(u.perfs.chess960, PerfType.Chess960)
|
||||
|
|
16
bin/mongodb/config-timemode.js
Normal file
16
bin/mongodb/config-timemode.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
db.config.find().forEach(function(o) {
|
||||
var sets = {};
|
||||
var unsets = {};
|
||||
['friend', 'hook', 'ai'].forEach(function(type) {
|
||||
if (!o[type]) return;
|
||||
sets[type + '.tm'] = o[type].k ? NumberInt(1) : NumberInt(0);
|
||||
sets[type + '.d'] = NumberInt(2);
|
||||
unsets[type + '.k'] = true;
|
||||
});
|
||||
db.config.update({
|
||||
_id: o._id
|
||||
}, {
|
||||
$set: sets,
|
||||
$unset: unsets
|
||||
});
|
||||
});
|
|
@ -80,6 +80,10 @@ players=Players
|
|||
minutesPerSide=Minutes per side
|
||||
variant=Variant
|
||||
timeControl=Time control
|
||||
clock=Clock
|
||||
correspondence=Correspondence
|
||||
daysPerTurn=Days per turn
|
||||
xDays=%s days
|
||||
time=Time
|
||||
username=User name
|
||||
password=Password
|
||||
|
|
|
@ -210,7 +210,6 @@ xToYMinutes=%s tot %s minute
|
|||
textIsTooShort=Teks is te min.
|
||||
textIsTooLong=Teks is te veel.
|
||||
required=Vereiste.
|
||||
addToChrome=Voeg by Chrome by
|
||||
openTournaments=Oop tornooie
|
||||
duration=Duur
|
||||
winner=Wenner
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=من %s إلى %s دقيقة
|
|||
textIsTooShort=النص قصير جداً
|
||||
textIsTooLong=النص طويل جداً
|
||||
required=مطلوب
|
||||
addToChrome=أضف إلى متصفح كروم
|
||||
openTournaments=المسابقات المفتوحة
|
||||
duration=المدة
|
||||
winner=الفائز
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s - %s dəqiqə arası
|
|||
textIsTooShort=Mətn çox qısadır.
|
||||
textIsTooLong=Mətn çox uzundur.
|
||||
required=Tələb olunur.
|
||||
addToChrome=Xroma əlavə et.
|
||||
openTournaments=Turnir açın.
|
||||
duration=Vaxt.
|
||||
winner=Qalib
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=Ад %s да %s хвілінаў
|
|||
textIsTooShort=Тэкст занадта кароткі.
|
||||
textIsTooLong=Тэкст занадта доўгі.
|
||||
required=Патрабуецца.
|
||||
addToChrome=Дадаць у Хром
|
||||
openTournaments=Адкрытыя турніры
|
||||
duration=Працягласьць
|
||||
winner=Пераможца
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s до %s минути
|
|||
textIsTooShort=Текстът е твърде къс.
|
||||
textIsTooLong=Текстът е твърде дълъг.
|
||||
required=Нужни.
|
||||
addToChrome=Добави към Chrome
|
||||
openTournaments=Отворени турнири
|
||||
duration=Времетраене
|
||||
winner=Победител
|
||||
|
|
|
@ -210,7 +210,6 @@ xToYMinutes=%s থেকে %s মিনিট
|
|||
textIsTooShort=লেখাটি বড্ড ছোট
|
||||
textIsTooLong=লেখাটি বড্ড বড়
|
||||
required=প্রয়োজনীয়
|
||||
addToChrome=গুগল ক্রোমে যোগ করুন
|
||||
openTournaments=উন্মুক্ত টুর্নামেন্টগুলো
|
||||
duration=সময়কাল
|
||||
winner=বিজয়ী
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s do %s minuta
|
|||
textIsTooShort=Tekst je prekratak
|
||||
textIsTooLong=Tekst je predug
|
||||
required=Potrebno
|
||||
addToChrome=Dodaj u Google Chrome
|
||||
openTournaments=Otvoreni turniri
|
||||
duration=Trajanje
|
||||
winner=Pobjednik
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=De %s a %s minuts
|
|||
textIsTooShort=El text és massa curt.
|
||||
textIsTooLong=El text és massa llarg.
|
||||
required=Necessari.
|
||||
addToChrome=Afegeix al Chrome
|
||||
openTournaments=Tornejos oberts
|
||||
duration=Durada
|
||||
winner=Guanyador
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s až %s minut
|
|||
textIsTooShort=Text je příliš krátký.
|
||||
textIsTooLong=Text je příliš dlouhý
|
||||
required=Vyžadováno.
|
||||
addToChrome=Přidat do Chrome
|
||||
openTournaments=Otevřené turnaje
|
||||
duration=Trvání
|
||||
winner=Vítěz
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s til %s minutter
|
|||
textIsTooShort=teksten er for kort
|
||||
textIsTooLong=teksten er for lang
|
||||
required=Påkrævet
|
||||
addToChrome=Tilføj til Chrome
|
||||
openTournaments=Åben turnering
|
||||
duration=Varighed
|
||||
winner=Vinder
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s bis %s Minuten
|
|||
textIsTooShort=Text ist zu kurz.
|
||||
textIsTooLong=Text ist zu lang.
|
||||
required=Benötigt.
|
||||
addToChrome=Füge zu Chrome hinzu
|
||||
openTournaments=Offene Turniere
|
||||
duration=Dauer
|
||||
winner=Gewinner
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s εώς %s λεπτά
|
|||
textIsTooShort=Το κείμενο είναι πολύ μικρό.
|
||||
textIsTooLong=Το κείμενο είναι πολύ μακρύ.
|
||||
required=Απαιτείται
|
||||
addToChrome=Προσθήκη στο Chrome
|
||||
openTournaments=Ανοικτά πρωταθλήματα
|
||||
duration=Διάρκεια
|
||||
winner=Νικητής
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=de %s ĝis %s minutoj
|
|||
textIsTooShort=Teksto estas tro mallonga.
|
||||
textIsTooLong=Teksto estas tro longa.
|
||||
required=Necesa.
|
||||
addToChrome=Aligi al Chrome
|
||||
openTournaments=Daŭrantaj turniroj
|
||||
duration=Daŭro
|
||||
winner=Venkinto
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s hasta %s minutos
|
|||
textIsTooShort=El texto es demasiado corto.
|
||||
textIsTooLong=El texto es demasiado largo.
|
||||
required=Requerido.
|
||||
addToChrome=Añadir a Chrome
|
||||
openTournaments=Torneos abiertos.
|
||||
duration=Duración
|
||||
winner=Ganador
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s kuni %s minutit
|
|||
textIsTooShort=Tekst on liiga lühike
|
||||
textIsTooLong=Tekst on liiga pikk
|
||||
required=Nõutud
|
||||
addToChrome=Lisa Chrome
|
||||
openTournaments=Avatud turniirid
|
||||
duration=Kestvus
|
||||
winner=Võitja
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s به %s دقیقه ها
|
|||
textIsTooShort=متن بیش از حد کوتاه است
|
||||
textIsTooLong=متن بیش از حد بلند است
|
||||
required=مورد نیاز است
|
||||
addToChrome=اضافه شدن به گوگل کروم
|
||||
openTournaments=باز کردن مسابقه
|
||||
duration=مدت
|
||||
winner=برنده
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s-%s minuuttia
|
|||
textIsTooShort=Teksti on liian lyhyt.
|
||||
textIsTooLong=Teksti on liian pitkä.
|
||||
required=Vaadittu.
|
||||
addToChrome=Lisää Chromeen
|
||||
openTournaments=Avoimet turnaukset
|
||||
duration=Kesto
|
||||
winner=Voittaja
|
||||
|
|
|
@ -80,6 +80,7 @@ players=Joueurs
|
|||
minutesPerSide=Minutes par joueur
|
||||
variant=Variante
|
||||
timeControl=Contrôle du temps
|
||||
xDays=%s jours
|
||||
time=Temps
|
||||
username=Pseudonyme
|
||||
password=Mot de passe
|
||||
|
@ -215,7 +216,6 @@ xToYMinutes=De %s à %s minutes
|
|||
textIsTooShort=Le texte est trop court.
|
||||
textIsTooLong=Le texte est trop long.
|
||||
required=Requis.
|
||||
addToChrome=Ajouter à Chrome
|
||||
openTournaments=Tournois ouverts
|
||||
duration=Durée
|
||||
winner=Vainqueur
|
||||
|
|
|
@ -214,7 +214,6 @@ xToYMinutes=%s gu %s mionaidean
|
|||
textIsTooShort=Tha an teacsa ro ghoirid.
|
||||
textIsTooLong=Tha an teacsa ro fhada.
|
||||
required=Riatanach.
|
||||
addToChrome=Cuir ri Chrome
|
||||
openTournaments=Fèill-chluichean fosgailte
|
||||
duration=Faid
|
||||
winner=Buannaiche
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s para %s minutos
|
|||
textIsTooShort=O texto é moi curto.
|
||||
textIsTooLong=O texto é moi longo.
|
||||
required=Requerido.
|
||||
addToChrome=Engadir ao Chrome
|
||||
openTournaments=Torneos Abertos
|
||||
duration=Duración
|
||||
winner=Vencedor
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s עד %s דקות
|
|||
textIsTooShort=טקסט קצר מדי.
|
||||
textIsTooLong=טקסט ארוך מדי.
|
||||
required=נדרש.
|
||||
addToChrome=הוסף לכרום
|
||||
openTournaments=טורנירים פתוחים
|
||||
duration=משך
|
||||
winner=מנצח
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s से %s मिनट तक
|
|||
textIsTooShort=Yaha likha vishay adhik chhota hai
|
||||
textIsTooLong=Yaha likha vishay adhik lamba hai
|
||||
required=Jaroori hai
|
||||
addToChrome=Chrome me shamil keejeeyai
|
||||
openTournaments=Khuli pratigoyitayei
|
||||
duration=avadhi
|
||||
winner=Vijaita
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s do %s minuta
|
|||
textIsTooShort=Tekst je prekratak
|
||||
textIsTooLong=Tekst je predug
|
||||
required=Obvezno.
|
||||
addToChrome=Dodati Chromu
|
||||
openTournaments=Otvoreni turniri
|
||||
duration=Trajanje
|
||||
winner=Pobjednik
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s perctől %s percig
|
|||
textIsTooShort=A szöveg túl rövid
|
||||
textIsTooLong=A szöveg túl hosszú
|
||||
required=Szükséges
|
||||
addToChrome=Hozzáadás a Chrome böngészőhöz
|
||||
openTournaments=Nyílt versenyek
|
||||
duration=Időtartam
|
||||
winner=Győztes
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s -ից %s րոպե
|
|||
textIsTooShort=Տեքստը շատ կարճ է
|
||||
textIsTooLong=Տեքստը շատ երկար է
|
||||
required=Պարտադիր.
|
||||
addToChrome=Ավելացնել Chrome-ին
|
||||
openTournaments=Բաց մրցաշարեր
|
||||
duration=Տևողություն
|
||||
winner=Հաղթող
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s atau %s menit
|
|||
textIsTooShort=Kalimat terlalu pendek.
|
||||
textIsTooLong=Kalimat terlalu panjang.
|
||||
required=Dibutuhkan.
|
||||
addToChrome=Tambahkan ke Chrome.
|
||||
openTournaments=Kejuaraan terbuka
|
||||
duration=Durasi
|
||||
winner=Pemenang
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s til %s mínútur
|
|||
textIsTooShort=Texti er of stuttur.
|
||||
textIsTooLong=Texti er of langur.
|
||||
required=Krafist.
|
||||
addToChrome=Bæta við Chrome
|
||||
openTournaments=Opin mót
|
||||
duration=Lengd
|
||||
winner=Sigurvegari
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=da %s a %s minuti
|
|||
textIsTooShort=Testo troppo corto.
|
||||
textIsTooLong=Testo troppo lungo.
|
||||
required=Richiesto.
|
||||
addToChrome=Aggiungi a Chrome
|
||||
openTournaments=Tornei aperti
|
||||
duration=Durata
|
||||
winner=Vincitore
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s から %s 分
|
|||
textIsTooShort=テキストが短すぎます。
|
||||
textIsTooLong=テキストが長すぎます。
|
||||
required=必須です。
|
||||
addToChrome=Chromeに追加
|
||||
openTournaments=参加募集中のトーナメント
|
||||
duration=トーナメント打ち切りまでの時間
|
||||
winner=優勝者
|
||||
|
|
|
@ -214,7 +214,6 @@ xToYMinutes=%s დან %s წუთი
|
|||
textIsTooShort=ტექსთი ძალიან მოკლეა
|
||||
textIsTooLong=ტეასტი ზედმეტად დიდია
|
||||
required=საჭირო.
|
||||
addToChrome=დაამატეთ ქრომში
|
||||
openTournaments=გახსენით ტურნირი
|
||||
duration=ხანგრძლივობა
|
||||
winner=გამარჯვებული
|
||||
|
|
|
@ -214,7 +214,6 @@ xToYMinutes=S %s armi %s minutes
|
|||
textIsTooShort=Aḍris wezzil aṭas
|
||||
textIsTooLong=Aḍris ɣezzif aṭas
|
||||
required=Usuter
|
||||
addToChrome=Zegged ɣar Chrome
|
||||
openTournaments=Timzizelten ilden
|
||||
duration=Tanzagt
|
||||
winner=Amernay
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s~%s분
|
|||
textIsTooShort=입력한 텍스트가 너무 짧습니다
|
||||
textIsTooLong=입력한 텍스트가 너무 깁니다
|
||||
required=필수
|
||||
addToChrome=Chrome에 추가
|
||||
openTournaments=개최 중인 토너먼트
|
||||
duration=경기 시간
|
||||
winner=승자
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s 70 %s miNu735
|
|||
textIsTooShort=73X7 i$ 700 5h0r7.
|
||||
textIsTooLong=73x7 i5 700 l0Ng.
|
||||
required=r3quIR3D.
|
||||
addToChrome=@dD 70 Chr0m3
|
||||
openTournaments=0P3n 7ouRn@men7$
|
||||
duration=dur@7ioN
|
||||
winner=winN3R
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=nuo %s iki %s minučiu
|
|||
textIsTooShort=Tekstas per trumpas.
|
||||
textIsTooLong=Tekstas per ilgas.
|
||||
required=Būtina.
|
||||
addToChrome=Pridėti į Chrome
|
||||
openTournaments=Atidaryti turnyrus
|
||||
duration=Trukmė
|
||||
winner=Nugalėtojas
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s līdz %s minūtes
|
|||
textIsTooShort=Teksts ir par īsu.
|
||||
textIsTooLong=Teksts ir par garu.
|
||||
required=Obligāts.
|
||||
addToChrome=Pievienot Chrome
|
||||
openTournaments=Atvērt turnīrus
|
||||
duration=Ilgums
|
||||
winner=Uzvarētājs
|
||||
|
|
|
@ -209,7 +209,6 @@ xToYMinutes=%s hatramin'ny %s minitra
|
|||
textIsTooShort=Fohy loatra ny soratra.
|
||||
textIsTooLong=Lava loatra ny soratra.
|
||||
required=Ilaina.
|
||||
addToChrome=Ampio ao amin'ny Chrome
|
||||
openTournaments=Fifaninanana misokatra
|
||||
duration=Halavany
|
||||
winner=Mpandresy
|
||||
|
|
|
@ -214,7 +214,6 @@ xToYMinutes=%s до %s минути
|
|||
textIsTooShort=Текстот е прекраток.
|
||||
textIsTooLong=Текстот е предолг.
|
||||
required=Неопходно.
|
||||
addToChrome=Додади на Chrome
|
||||
openTournaments=Отворени турнири
|
||||
duration=Времетраење
|
||||
winner=Победник
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=Mellom %s og %s minutter igjen
|
|||
textIsTooShort=Teksten er for kort.
|
||||
textIsTooLong=Teksten er for lang.
|
||||
required=Påkrevd.
|
||||
addToChrome=Legg til Chrome
|
||||
openTournaments=Åpne turneringer
|
||||
duration=Varighet
|
||||
winner=Vinner
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s tot %s minuten
|
|||
textIsTooShort=Te weinig tekst.
|
||||
textIsTooLong=Teveel tekst.
|
||||
required=Vereist.
|
||||
addToChrome=Voeg toe aan Chrome
|
||||
openTournaments=Open toernooien
|
||||
duration=Tijdsduur
|
||||
winner=Winnaar
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s til %s minutt
|
|||
textIsTooShort=Teksten er for stutt
|
||||
textIsTooLong=Teksten er for lang
|
||||
required=Påkrevd
|
||||
addToChrome=Legg til Chrome
|
||||
openTournaments=Åpne turneringar
|
||||
duration=Varigheit
|
||||
winner=Vinnar
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=od %s do %s minut
|
|||
textIsTooShort=Tekst jest za krótki.
|
||||
textIsTooLong=Tekst jest za długi.
|
||||
required=Wymagane.
|
||||
addToChrome=Dodaj do Chrome
|
||||
openTournaments=Turnieje otwarte
|
||||
duration=Czas trwania
|
||||
winner=Zwycięzca
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s para %s minutos
|
|||
textIsTooShort=O texto é demasiado curto.
|
||||
textIsTooLong=O texto é demasiado longo.
|
||||
required=Requerido.
|
||||
addToChrome=Adicionar ao Chrome
|
||||
openTournaments=Torneios abertos
|
||||
duration=Duração
|
||||
winner=Vencedor
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s pâna la %s minute
|
|||
textIsTooShort=Textul este prea scurt.
|
||||
textIsTooLong=Textul este prea lung.
|
||||
required=Obligatoriu.
|
||||
addToChrome=Adaugă în Chrome
|
||||
openTournaments=Turnee deschise
|
||||
duration=Durată
|
||||
winner=Caștigător
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=От %s до %s минут
|
|||
textIsTooShort=Текст слишком короткий.
|
||||
textIsTooLong=Текст слишком длинный.
|
||||
required=Требуется заполнить.
|
||||
addToChrome=Добавить в Chrome
|
||||
openTournaments=Открытые турниры
|
||||
duration=Длительность
|
||||
winner=Победитель
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s do %d minút
|
|||
textIsTooShort=Text je príliš krátky
|
||||
textIsTooLong=Text je príliš dlhý
|
||||
required=Vyžaduje sa
|
||||
addToChrome=Pridať do Chrome
|
||||
openTournaments=Otvorené turnaje
|
||||
duration=Dĺžka
|
||||
winner=Víťaz
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s do %s minut
|
|||
textIsTooShort=Besedilo je prekratko
|
||||
textIsTooLong=Besedilo je predolgo
|
||||
required=Zahtevano
|
||||
addToChrome=Dodaj v Chrome
|
||||
openTournaments=Odprti turnirji
|
||||
duration=Trajanje
|
||||
winner=Zmagovalec
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s deri me %s minuta
|
|||
textIsTooShort=Teksti eshte shume i shkurter.
|
||||
textIsTooLong=Teksti eshte shume i gjate.
|
||||
required=E detyrueshme.
|
||||
addToChrome=Shto tek Chrome
|
||||
openTournaments=Turnire te hapura
|
||||
duration=Kohezgjatja
|
||||
winner=Fituesi
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s до %s минута
|
|||
textIsTooShort=Текст је сувише кратак.
|
||||
textIsTooLong=Текст је предугачак.
|
||||
required=Обавезно.
|
||||
addToChrome=Додај у Гугл Хром
|
||||
openTournaments=Отворени турнири
|
||||
duration=Трајање
|
||||
winner=Победник
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s till %s minuter
|
|||
textIsTooShort=Texten är för kort.
|
||||
textIsTooLong=Texten är för lång.
|
||||
required=Nödvändig.
|
||||
addToChrome=Lägg till Chrome
|
||||
openTournaments=Öppen turneringar
|
||||
duration=Varaktighet
|
||||
winner=Vinnare
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s - %s நிமிடங்கள்
|
|||
textIsTooShort=உரை மிகவும் குறுகல்
|
||||
textIsTooLong=உரை மிகவும் நீளம்
|
||||
required=கட்டாயம்
|
||||
addToChrome=கூகில் குரோமோடு சேர்த்து
|
||||
openTournaments=நுழைவேற்கும் போட்டிகள்
|
||||
duration=நேரம்
|
||||
winner=வெல்லி
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s ถึง %s นาที
|
|||
textIsTooShort=ข้อความสั้นไป
|
||||
textIsTooLong=ข้อความยาวไป
|
||||
required=ต้องการ
|
||||
addToChrome=เพิ่มสู่ Chrome
|
||||
openTournaments=ทัวร์นาเมนต์ที่เปิด
|
||||
duration=ระยะเวลา
|
||||
winner=ผู้ชนะ
|
||||
|
|
|
@ -208,7 +208,6 @@ graph=sitelen
|
|||
textIsTooShort=ike a, nimi li lili
|
||||
textIsTooLong=ike a, nimi li suli
|
||||
required=wile
|
||||
addToChrome=pana lon ilo Chrome
|
||||
openTournaments=musi open
|
||||
duration=tenpo
|
||||
createANewTournament=pali e musi sin
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s ile %s dakika arası
|
|||
textIsTooShort=Yazı çok kısa.
|
||||
textIsTooLong=Yazı çok uzun.
|
||||
required=Gerekli.
|
||||
addToChrome=Chrome'a ekle
|
||||
openTournaments=Açık Turnuvalar
|
||||
duration=Süre
|
||||
winner=Kazanan
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s до %s хвилин
|
|||
textIsTooShort=Текст закороткий.
|
||||
textIsTooLong=Текст задовгий.
|
||||
required=Необхідно.
|
||||
addToChrome=Додати до Chrome
|
||||
openTournaments=Відкриті турніри
|
||||
duration=Тривалість
|
||||
winner=Переможець
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s đến %s phút
|
|||
textIsTooShort=Câu quá ngắn
|
||||
textIsTooLong=Câu quá dài
|
||||
required=Bắt buộc
|
||||
addToChrome=Thêm vào Chrome
|
||||
openTournaments=Những giải đấu mở
|
||||
duration=Thời gian
|
||||
winner=Người chiến thắng
|
||||
|
|
|
@ -215,7 +215,6 @@ xToYMinutes=%s到%s分钟
|
|||
textIsTooShort=字数过少。
|
||||
textIsTooLong=字数过多。
|
||||
required=必填项目。
|
||||
addToChrome=添加到Chrome
|
||||
openTournaments=公开赛
|
||||
duration=持续时间
|
||||
winner=胜利者
|
||||
|
|
|
@ -14,7 +14,7 @@ private[evaluation] final class Listener(evaluator: Evaluator) extends Actor {
|
|||
def receive = {
|
||||
|
||||
case lila.game.actorApi.FinishGame(game, white, black) =>
|
||||
PerfType(PerfPicker.key(game.speed, game.variant)) ifTrue game.rated map { perfType =>
|
||||
PerfType(PerfPicker key game) ifTrue game.rated map { perfType =>
|
||||
List(
|
||||
game.whitePlayer -> white,
|
||||
game.blackPlayer -> black
|
||||
|
|
10
modules/game/src/main/CorrespondenceClock.scala
Normal file
10
modules/game/src/main/CorrespondenceClock.scala
Normal file
|
@ -0,0 +1,10 @@
|
|||
package lila.game
|
||||
|
||||
// times are expressed in seconds
|
||||
case class CorrespondenceClock(
|
||||
increment: Int,
|
||||
whiteTime: Float,
|
||||
blackTime: Float) {
|
||||
|
||||
def emerg = 60 * 10
|
||||
}
|
|
@ -157,6 +157,15 @@ object Event {
|
|||
clock remainingTime Color.Black)
|
||||
}
|
||||
|
||||
case class CorrespondenceClock(white: Float, black: Float) extends Event {
|
||||
def typ = "cclock"
|
||||
def data = Json.obj("white" -> white, "black" -> black)
|
||||
}
|
||||
object CorrespondenceClock {
|
||||
def apply(clock: lila.game.CorrespondenceClock): CorrespondenceClock =
|
||||
CorrespondenceClock(clock.whiteTime, clock.blackTime)
|
||||
}
|
||||
|
||||
case class CheckCount(white: Int, black: Int) extends Event {
|
||||
def typ = "checkCount"
|
||||
def data = Json.obj(
|
||||
|
|
|
@ -20,6 +20,7 @@ case class Game(
|
|||
startedAtTurn: Int,
|
||||
clock: Option[Clock],
|
||||
castleLastMoveTime: CastleLastMoveTime,
|
||||
daysPerTurn: Option[Int],
|
||||
positionHashes: PositionHash = Array(),
|
||||
checkCount: CheckCount = CheckCount(0, 0),
|
||||
binaryMoveTimes: ByteArray = ByteArray.empty, // tenths of seconds
|
||||
|
@ -86,6 +87,10 @@ case class Game(
|
|||
private def lastMoveTime: Option[Long] = castleLastMoveTime.lastMoveTime map {
|
||||
_.toLong + (createdAt.getMillis / 100)
|
||||
}
|
||||
private def lastMoveTimeDate: Option[DateTime] = castleLastMoveTime.lastMoveTime map { lmt =>
|
||||
createdAt plusMillis (lmt * 100)
|
||||
}
|
||||
|
||||
def lastMoveTimeInSeconds: Option[Int] = lastMoveTime.map(x => (x / 10).toInt)
|
||||
|
||||
// in tenths of seconds
|
||||
|
@ -160,7 +165,11 @@ case class Game(
|
|||
status = situation.status | status,
|
||||
clock = game.clock)
|
||||
|
||||
val finalEvents = events ::: updated.clock.??(c => List(Event.Clock(c))) ::: {
|
||||
val clockEvent = updated.clock map Event.Clock.apply orElse {
|
||||
updated.correspondenceClock map Event.CorrespondenceClock.apply
|
||||
}
|
||||
|
||||
val finalEvents = events ::: clockEvent.toList ::: {
|
||||
(updated.playable && (
|
||||
abortable != updated.abortable || (Color.all exists { color =>
|
||||
playerCanOfferDraw(color) != updated.playerCanOfferDraw(color)
|
||||
|
@ -200,6 +209,19 @@ case class Game(
|
|||
}
|
||||
)
|
||||
|
||||
def correspondenceClock: Option[CorrespondenceClock] =
|
||||
daysPerTurn ifTrue (playable && bothPlayersHaveMoved) map { days =>
|
||||
val increment = days * 24 * 60 * 60
|
||||
val secondsLeft = lastMoveTimeDate.fold(increment) { lmd =>
|
||||
val flagAt = lmd plusDays days
|
||||
(flagAt.getSeconds - nowSeconds).toInt max 0
|
||||
}
|
||||
CorrespondenceClock(
|
||||
increment = increment,
|
||||
whiteTime = turnColor.fold(secondsLeft, increment),
|
||||
blackTime = turnColor.fold(increment, secondsLeft))
|
||||
}
|
||||
|
||||
def speed = chess.Speed(clock)
|
||||
|
||||
def perfType = PerfType(PerfPicker.key(this))
|
||||
|
@ -306,6 +328,8 @@ case class Game(
|
|||
if (!c.isRunning && !c.isInit) || (c outoftime player.color)
|
||||
} yield player
|
||||
|
||||
def isCorrespondence = daysPerTurn.isDefined
|
||||
|
||||
def hasClock = clock.isDefined
|
||||
|
||||
def isClockRunning = clock ?? (_.isRunning)
|
||||
|
@ -396,7 +420,8 @@ object Game {
|
|||
variant: Variant,
|
||||
source: Source,
|
||||
pgnImport: Option[PgnImport],
|
||||
castles: Castles = Castles.init): Game = Game(
|
||||
castles: Castles = Castles.init,
|
||||
daysPerTurn: Option[Int] = None): Game = Game(
|
||||
id = IdGenerator.game,
|
||||
whitePlayer = whitePlayer,
|
||||
blackPlayer = blackPlayer,
|
||||
|
@ -408,6 +433,7 @@ object Game {
|
|||
startedAtTurn = game.startedAtTurn,
|
||||
clock = game.clock,
|
||||
castleLastMoveTime = CastleLastMoveTime.init.copy(castles = castles),
|
||||
daysPerTurn = daysPerTurn,
|
||||
mode = mode,
|
||||
variant = variant,
|
||||
metadata = Metadata(
|
||||
|
@ -442,6 +468,7 @@ object Game {
|
|||
val positionHashes = "ph"
|
||||
val checkCount = "cc"
|
||||
val castleLastMoveTime = "cl"
|
||||
val daysPerTurn = "cd"
|
||||
val moveTimes = "mt"
|
||||
val rated = "ra"
|
||||
val analysed = "an"
|
||||
|
@ -496,6 +523,7 @@ object Game {
|
|||
CheckCount(~counts.headOption, ~counts.lastOption)
|
||||
},
|
||||
castleLastMoveTime = r.get[CastleLastMoveTime](castleLastMoveTime)(castleLastMoveTimeBSONHandler),
|
||||
daysPerTurn = r intO daysPerTurn,
|
||||
binaryMoveTimes = (r bytesO moveTimes) | ByteArray.empty,
|
||||
mode = Mode(r boolD rated),
|
||||
variant = Variant(r intD variant) | Variant.Standard,
|
||||
|
@ -527,6 +555,7 @@ object Game {
|
|||
positionHashes -> w.bytesO(o.positionHashes),
|
||||
checkCount -> o.checkCount.nonEmpty.option(o.checkCount),
|
||||
castleLastMoveTime -> castleLastMoveTimeBSONHandler.write(o.castleLastMoveTime),
|
||||
daysPerTurn -> o.daysPerTurn,
|
||||
moveTimes -> (BinaryFormat.moveTime write o.moveTimes),
|
||||
rated -> w.boolO(o.mode.rated),
|
||||
variant -> o.variant.exotic.option(o.variant.id).map(w.int),
|
||||
|
|
|
@ -8,26 +8,28 @@ object PerfPicker {
|
|||
|
||||
val default = (perfs: Perfs) => perfs.standard
|
||||
|
||||
def perfType(speed: Speed, variant: Variant): Option[PerfType] =
|
||||
PerfType(key(speed, variant))
|
||||
def perfType(speed: Speed, variant: Variant, daysPerTurn: Option[Int]): Option[PerfType] =
|
||||
PerfType(key(speed, variant, daysPerTurn))
|
||||
|
||||
def key(speed: Speed, variant: Variant): String =
|
||||
def key(speed: Speed, variant: Variant, daysPerTurn: Option[Int]): String =
|
||||
if (variant.standard) {
|
||||
if (speed == Speed.Unlimited) Speed.Classical.key
|
||||
if (daysPerTurn.isDefined) PerfType.Correspondence.key
|
||||
else if (speed == Speed.Unlimited) PerfType.Classical.key
|
||||
else speed.key
|
||||
}
|
||||
else variant.key
|
||||
|
||||
def key(game: Game): String = key(game.speed, game.variant)
|
||||
def key(game: Game): String = key(game.speed, game.variant, game.daysPerTurn)
|
||||
|
||||
def main(speed: Speed, variant: Variant): Option[Perfs => Perf] =
|
||||
if (variant.standard) Perfs.speedLens(speed).some
|
||||
def main(speed: Speed, variant: Variant, daysPerTurn: Option[Int]): Option[Perfs => Perf] =
|
||||
if (daysPerTurn.isDefined) Some((perfs: Perfs) => perfs.correspondence)
|
||||
else if (variant.standard) Perfs.speedLens(speed).some
|
||||
else Perfs variantLens variant
|
||||
|
||||
def main(game: Game): Option[Perfs => Perf] = main(game.speed, game.variant)
|
||||
def main(game: Game): Option[Perfs => Perf] = main(game.speed, game.variant, game.daysPerTurn)
|
||||
|
||||
def mainOrDefault(game: Game): Perfs => Perf = main(game) | default
|
||||
|
||||
def mainOrDefault(speed: Speed, variant: Variant): Perfs => Perf =
|
||||
main(speed, variant) | default
|
||||
def mainOrDefault(speed: Speed, variant: Variant, daysPerTurn: Option[Int]): Perfs => Perf =
|
||||
main(speed, variant, daysPerTurn) | default
|
||||
}
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -19,7 +19,7 @@ private[i18n] final class JsDump(
|
|||
|
||||
def apply: Funit = Future {
|
||||
pathFile.mkdir
|
||||
pool.nonDefaultLangs foreach write(jsMessages)
|
||||
pool.langs foreach write(jsMessages)
|
||||
writeRefs
|
||||
writeFullJson
|
||||
} void
|
||||
|
@ -52,13 +52,13 @@ private[i18n] final class JsDump(
|
|||
keys.decline,
|
||||
keys.challengeToPlay,
|
||||
keys.youNeedAnAccountToDoThat,
|
||||
keys.addToChrome,
|
||||
keys.createANewTournament,
|
||||
keys.join,
|
||||
keys.joinTheGame,
|
||||
keys.cancel,
|
||||
keys.withdraw,
|
||||
keys.tournamentIsStarting)
|
||||
keys.tournamentIsStarting,
|
||||
keys.xDays)
|
||||
|
||||
private val pathFile = new File(path)
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ private[lobby] object Biter {
|
|||
mode = hook.realMode,
|
||||
variant = hook.realVariant,
|
||||
source = lila.game.Source.Lobby,
|
||||
daysPerTurn = hook.daysPerTurn,
|
||||
pgnImport = None)
|
||||
|
||||
def canJoin(hook: Hook, user: Option[LobbyUser]): Boolean = hook.open &&
|
||||
|
|
|
@ -5,10 +5,10 @@ import org.joda.time.DateTime
|
|||
import ornicar.scalalib.Random
|
||||
import play.api.libs.json._
|
||||
|
||||
import actorApi.LobbyUser
|
||||
import lila.game.PerfPicker
|
||||
import lila.rating.RatingRange
|
||||
import lila.user.{ User, Perfs }
|
||||
import actorApi.LobbyUser
|
||||
|
||||
case class Hook(
|
||||
id: String,
|
||||
|
@ -18,6 +18,7 @@ case class Hook(
|
|||
hasClock: Boolean,
|
||||
time: Option[Int],
|
||||
increment: Option[Int],
|
||||
daysPerTurn: Option[Int],
|
||||
mode: Int,
|
||||
allowAnon: Boolean,
|
||||
color: String,
|
||||
|
@ -47,7 +48,7 @@ case class Hook(
|
|||
range => h.rating ?? range.contains
|
||||
}
|
||||
|
||||
private def compatibilityProperties = (variant, time, increment, mode)
|
||||
private def compatibilityProperties = (variant, time, increment, mode, daysPerTurn)
|
||||
|
||||
lazy val realRatingRange: Option[RatingRange] = RatingRange noneIfDefault ratingRange
|
||||
|
||||
|
@ -66,6 +67,7 @@ case class Hook(
|
|||
"mode" -> realMode.toString,
|
||||
"clock" -> clockOption.map(_.show),
|
||||
"time" -> clockOption.map(_.estimateTotalTime),
|
||||
"days" -> daysPerTurn,
|
||||
"speed" -> chess.Speed(clockOption).id,
|
||||
"color" -> chess.Color(color).??(_.name),
|
||||
"perf" -> Json.obj(
|
||||
|
@ -73,7 +75,7 @@ case class Hook(
|
|||
"name" -> perfType.map(_.name))
|
||||
)
|
||||
|
||||
lazy val perfType = PerfPicker.perfType(speed, realVariant)
|
||||
lazy val perfType = PerfPicker.perfType(speed, realVariant, daysPerTurn)
|
||||
|
||||
private lazy val clockOption = (time ifTrue hasClock) |@| increment apply Clock.apply
|
||||
|
||||
|
@ -90,6 +92,7 @@ object Hook {
|
|||
uid: String,
|
||||
variant: Variant,
|
||||
clock: Option[Clock],
|
||||
daysPerTurn: Option[Int],
|
||||
mode: Mode,
|
||||
allowAnon: Boolean,
|
||||
color: String,
|
||||
|
@ -103,6 +106,7 @@ object Hook {
|
|||
hasClock = clock.isDefined,
|
||||
time = clock map (_.limit),
|
||||
increment = clock map (_.increment),
|
||||
daysPerTurn = daysPerTurn,
|
||||
mode = mode.id,
|
||||
allowAnon = allowAnon || user.isEmpty,
|
||||
color = color,
|
||||
|
|
|
@ -28,6 +28,12 @@ object PerfType {
|
|||
title = Speed.Classical.title,
|
||||
iconChar = '+')
|
||||
|
||||
case object Correspondence extends PerfType(
|
||||
key = "correspondence",
|
||||
name = "Corresp.",
|
||||
title = "Correspondence chess (turn based)",
|
||||
iconChar = ';')
|
||||
|
||||
case object Standard extends PerfType(
|
||||
key = "standard",
|
||||
name = Variant.Standard.name,
|
||||
|
@ -58,7 +64,7 @@ object PerfType {
|
|||
title = "Training puzzles",
|
||||
iconChar = '-')
|
||||
|
||||
val all: List[PerfType] = List(Bullet, Blitz, Classical, Standard, Chess960, KingOfTheHill, ThreeCheck, Puzzle)
|
||||
val all: List[PerfType] = List(Bullet, Blitz, Classical, Correspondence, Standard, Chess960, KingOfTheHill, ThreeCheck, Puzzle)
|
||||
val byKey = all map { p => (p.key, p) } toMap
|
||||
|
||||
val default = Standard
|
||||
|
@ -68,5 +74,5 @@ object PerfType {
|
|||
|
||||
def name(key: Perf.Key): Option[String] = apply(key) map (_.name)
|
||||
|
||||
val nonPuzzle: List[PerfType] = List(Bullet, Blitz, Classical, Chess960, KingOfTheHill, ThreeCheck)
|
||||
val nonPuzzle: List[PerfType] = List(Bullet, Blitz, Classical, Correspondence, Chess960, KingOfTheHill, ThreeCheck)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import scala.math
|
|||
import play.api.libs.json._
|
||||
|
||||
import lila.common.PimpedJson._
|
||||
import lila.game.{ Pov, Game, PerfPicker, Source, GameRepo }
|
||||
import lila.game.{ Pov, Game, PerfPicker, Source, GameRepo, CorrespondenceClock }
|
||||
import lila.pref.Pref
|
||||
import lila.user.{ User, UserRepo }
|
||||
|
||||
|
@ -62,9 +62,10 @@ final class JsonView(
|
|||
"rematch" -> game.next,
|
||||
"source" -> game.source.map(sourceJson),
|
||||
"status" -> Json.obj(
|
||||
"id" -> pov.game.status.id,
|
||||
"name" -> pov.game.status.name)),
|
||||
"id" -> game.status.id,
|
||||
"name" -> game.status.name)),
|
||||
"clock" -> game.clock.map(clockJson),
|
||||
"correspondence" -> game.correspondenceClock.map(correspondenceJson),
|
||||
"player" -> Json.obj(
|
||||
"id" -> playerId,
|
||||
"color" -> player.color.name,
|
||||
|
@ -165,9 +166,10 @@ final class JsonView(
|
|||
)
|
||||
},
|
||||
"status" -> Json.obj(
|
||||
"id" -> pov.game.status.id,
|
||||
"name" -> pov.game.status.name)),
|
||||
"id" -> game.status.id,
|
||||
"name" -> game.status.name)),
|
||||
"clock" -> game.clock.map(clockJson),
|
||||
"correspondence" -> game.correspondenceClock.map(correspondenceJson),
|
||||
"player" -> Json.obj(
|
||||
"color" -> color.name,
|
||||
"version" -> socket.version,
|
||||
|
@ -254,6 +256,12 @@ final class JsonView(
|
|||
"emerg" -> clock.emergTime,
|
||||
"moretime" -> moretimeSeconds)
|
||||
|
||||
private def correspondenceJson(c: CorrespondenceClock) = Json.obj(
|
||||
"increment" -> c.increment,
|
||||
"white" -> c.whiteTime,
|
||||
"black" -> c.blackTime,
|
||||
"emerg" -> c.emerg)
|
||||
|
||||
private def sourceJson(source: Source) = source.name
|
||||
|
||||
private def possibleMoves(pov: Pov) = (pov.game playableBy pov.player) option {
|
||||
|
|
|
@ -64,7 +64,7 @@ private[round] final class Rematcher(
|
|||
} inject List(Event.ReloadOwner)
|
||||
|
||||
private def returnGame(pov: Pov): Fu[Game] = for {
|
||||
initialFen <- GameRepo initialFen pov.game.id
|
||||
initialFen <- GameRepo initialFen pov.game.id
|
||||
situation = initialFen flatMap Forsyth.<<<
|
||||
pieces = pov.game.variant.standard.fold(
|
||||
pov.game.variant.pieces,
|
||||
|
@ -86,6 +86,7 @@ private[round] final class Rematcher(
|
|||
mode = pov.game.mode,
|
||||
variant = pov.game.variant,
|
||||
source = pov.game.source | Source.Lobby,
|
||||
daysPerTurn = pov.game.daysPerTurn,
|
||||
castles = situation.fold(Castles.init)(_.situation.board.history.castles),
|
||||
pgnImport = None)
|
||||
|
||||
|
|
|
@ -6,16 +6,17 @@ import lila.lobby.Color
|
|||
|
||||
case class AiConfig(
|
||||
variant: Variant,
|
||||
clock: Boolean,
|
||||
timeMode: TimeMode,
|
||||
time: Int,
|
||||
increment: Int,
|
||||
days: Int,
|
||||
level: Int,
|
||||
color: Color,
|
||||
fen: Option[String] = None) extends Config with GameGenerator with Positional {
|
||||
|
||||
val strictFen = true
|
||||
|
||||
def >> = (variant.id, clock, time, increment, level, color.name, fen).some
|
||||
def >> = (variant.id, timeMode.id, time, increment, days, level, color.name, fen).some
|
||||
|
||||
def game = fenGame { chessGame =>
|
||||
Game.make(
|
||||
|
@ -29,34 +30,38 @@ case class AiConfig(
|
|||
mode = Mode.Casual,
|
||||
variant = variant,
|
||||
source = (variant == Variant.FromPosition).fold(Source.Position, Source.Ai),
|
||||
daysPerTurn = makeDaysPerTurn,
|
||||
pgnImport = None)
|
||||
} start
|
||||
|
||||
def encode = RawAiConfig(
|
||||
v = variant.id,
|
||||
k = clock,
|
||||
tm = timeMode.id,
|
||||
t = time,
|
||||
i = increment,
|
||||
d = days,
|
||||
l = level,
|
||||
f = ~fen)
|
||||
}
|
||||
|
||||
object AiConfig extends BaseConfig {
|
||||
|
||||
def <<(v: Int, k: Boolean, t: Int, i: Int, level: Int, c: String, fen: Option[String]) = new AiConfig(
|
||||
def <<(v: Int, tm: Int, t: Int, i: Int, d: Int, level: Int, c: String, fen: Option[String]) = new AiConfig(
|
||||
variant = Variant(v) err "Invalid game variant " + v,
|
||||
clock = k,
|
||||
timeMode = TimeMode(tm) err s"Invalid time mode $tm",
|
||||
time = t,
|
||||
increment = i,
|
||||
days = d,
|
||||
level = level,
|
||||
color = Color(c) err "Invalid color " + c,
|
||||
fen = fen)
|
||||
|
||||
val default = AiConfig(
|
||||
variant = variantDefault,
|
||||
clock = false,
|
||||
timeMode = TimeMode.Unlimited,
|
||||
time = 5,
|
||||
increment = 8,
|
||||
days = 2,
|
||||
level = 1,
|
||||
color = Color.default)
|
||||
|
||||
|
@ -83,19 +88,22 @@ object AiConfig extends BaseConfig {
|
|||
|
||||
private[setup] case class RawAiConfig(
|
||||
v: Int,
|
||||
k: Boolean,
|
||||
tm: Int,
|
||||
t: Int,
|
||||
i: Int,
|
||||
d: Int,
|
||||
l: Int,
|
||||
f: String = "") {
|
||||
|
||||
def decode = for {
|
||||
variant ← Variant(v)
|
||||
timeMode <- TimeMode(tm)
|
||||
} yield AiConfig(
|
||||
variant = variant,
|
||||
clock = k,
|
||||
timeMode = timeMode,
|
||||
time = t,
|
||||
increment = i,
|
||||
days = d,
|
||||
level = l,
|
||||
color = Color.White,
|
||||
fen = f.some filter (_.nonEmpty))
|
||||
|
|
|
@ -10,9 +10,10 @@ private[setup] case object ApiConfig extends Config with GameGenerator {
|
|||
val color = Color.White
|
||||
val variant = Variant.Standard
|
||||
val mode = Mode.Casual
|
||||
val clock = false
|
||||
val timeMode = TimeMode.Unlimited
|
||||
val time = 5
|
||||
val increment = 8
|
||||
val days = 2
|
||||
|
||||
def game = Game.make(
|
||||
game = makeGame,
|
||||
|
|
|
@ -10,7 +10,7 @@ import lila.tournament.{ System => TournamentSystem }
|
|||
private[setup] trait Config {
|
||||
|
||||
// Whether or not to use a clock
|
||||
val clock: Boolean
|
||||
val timeMode: TimeMode
|
||||
|
||||
// Clock time in minutes
|
||||
val time: Int
|
||||
|
@ -18,23 +18,30 @@ private[setup] trait Config {
|
|||
// Clock increment in seconds
|
||||
val increment: Int
|
||||
|
||||
// Correspondence days per turn
|
||||
val days: Int
|
||||
|
||||
// Game variant code
|
||||
val variant: Variant
|
||||
|
||||
// Creator player color
|
||||
val color: Color
|
||||
|
||||
def hasClock = timeMode == TimeMode.Clock
|
||||
|
||||
lazy val creatorColor = color.resolve
|
||||
|
||||
def makeGame = ChessGame(board = Board init variant, clock = makeClock)
|
||||
|
||||
def validClock = clock.fold(clockHasTime, true)
|
||||
def validClock = hasClock.fold(clockHasTime, true)
|
||||
|
||||
def clockHasTime = time + increment > 0
|
||||
|
||||
def makeClock = clock option {
|
||||
def makeClock = hasClock option {
|
||||
Clock(time * 60, clockHasTime.fold(increment, 1))
|
||||
}
|
||||
|
||||
def makeDaysPerTurn: Option[Int] = (timeMode == TimeMode.Correspondence) option days
|
||||
}
|
||||
|
||||
trait GameGenerator { self: Config =>
|
||||
|
@ -89,9 +96,9 @@ trait BaseConfig {
|
|||
val variantDefault = Variant.Standard
|
||||
|
||||
val variantsWithFen = variants :+ Variant.FromPosition.id
|
||||
val variantsWithFenAndKingOfTheHill = variantsWithFen :+ Variant.KingOfTheHill.id
|
||||
val variantsWithFenAndKingOfTheHill = variants :+ Variant.KingOfTheHill.id :+ Variant.FromPosition.id
|
||||
val variantsWithVariants = variants :+ Variant.KingOfTheHill.id :+ Variant.ThreeCheck.id
|
||||
val variantsWithFenAndVariants = variantsWithFen :+ Variant.KingOfTheHill.id :+ Variant.ThreeCheck.id
|
||||
val variantsWithFenAndVariants = variants :+ Variant.KingOfTheHill.id :+ Variant.ThreeCheck.id :+ Variant.FromPosition.id
|
||||
|
||||
val speeds = Speed.all map (_.id)
|
||||
|
||||
|
|
|
@ -37,9 +37,10 @@ private[setup] final class FormFactory(casualOnly: Boolean) {
|
|||
def ai(ctx: UserContext) = Form(
|
||||
mapping(
|
||||
"variant" -> variantWithFenAndKingOfTheHill,
|
||||
"clock" -> boolean,
|
||||
"timeMode" -> timeMode,
|
||||
"time" -> time,
|
||||
"increment" -> increment,
|
||||
"days" -> days,
|
||||
"level" -> level,
|
||||
"color" -> color,
|
||||
"fen" -> fen
|
||||
|
@ -59,9 +60,10 @@ private[setup] final class FormFactory(casualOnly: Boolean) {
|
|||
def friend(ctx: UserContext) = Form(
|
||||
mapping(
|
||||
"variant" -> variantWithFenAndVariants,
|
||||
"clock" -> boolean,
|
||||
"timeMode" -> timeMode,
|
||||
"time" -> time,
|
||||
"increment" -> increment,
|
||||
"days" -> days,
|
||||
"mode" -> mode(withRated = ctx.isAuth && !casualOnly),
|
||||
"color" -> color,
|
||||
"fen" -> fen
|
||||
|
@ -78,9 +80,10 @@ private[setup] final class FormFactory(casualOnly: Boolean) {
|
|||
def hook(ctx: UserContext) = Form(
|
||||
mapping(
|
||||
"variant" -> variantWithVariants,
|
||||
"clock" -> boolean,
|
||||
"timeMode" -> timeMode,
|
||||
"time" -> time,
|
||||
"increment" -> increment,
|
||||
"days" -> days,
|
||||
"mode" -> mode(ctx.isAuth && !casualOnly),
|
||||
"membersOnly" -> boolean,
|
||||
"ratingRange" -> optional(ratingRange),
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
package lila.setup
|
||||
|
||||
import chess.{ Variant, Mode, Clock, Color => ChessColor }
|
||||
import lila.rating.RatingRange
|
||||
import lila.game.{ Game, Player, Source }
|
||||
import lila.lobby.Color
|
||||
import lila.rating.RatingRange
|
||||
|
||||
case class FriendConfig(
|
||||
variant: Variant,
|
||||
clock: Boolean,
|
||||
timeMode: TimeMode,
|
||||
time: Int,
|
||||
increment: Int,
|
||||
days: Int,
|
||||
mode: Mode,
|
||||
color: Color,
|
||||
fen: Option[String] = None) extends HumanConfig with GameGenerator with Positional {
|
||||
|
||||
val strictFen = false
|
||||
|
||||
def >> = (variant.id, clock, time, increment, mode.id.some, color.name, fen).some
|
||||
def >> = (variant.id, timeMode.id, time, increment, days, mode.id.some, color.name, fen).some
|
||||
|
||||
def game = fenGame { chessGame =>
|
||||
Game.make(
|
||||
|
@ -26,35 +27,39 @@ case class FriendConfig(
|
|||
mode = (variant == Variant.FromPosition).fold(Mode.Casual, mode),
|
||||
variant = variant,
|
||||
source = (variant == Variant.FromPosition).fold(Source.Position, Source.Friend),
|
||||
daysPerTurn = makeDaysPerTurn,
|
||||
pgnImport = None)
|
||||
}
|
||||
|
||||
def encode = RawFriendConfig(
|
||||
v = variant.id,
|
||||
k = clock,
|
||||
tm = timeMode.id,
|
||||
t = time,
|
||||
i = increment,
|
||||
d = days,
|
||||
m = mode.id,
|
||||
f = ~fen)
|
||||
}
|
||||
|
||||
object FriendConfig extends BaseHumanConfig {
|
||||
|
||||
def <<(v: Int, k: Boolean, t: Int, i: Int, m: Option[Int], c: String, fen: Option[String]) =
|
||||
def <<(v: Int, tm: Int, t: Int, i: Int, d: Int, m: Option[Int], c: String, fen: Option[String]) =
|
||||
new FriendConfig(
|
||||
variant = Variant(v) err "Invalid game variant " + v,
|
||||
clock = k,
|
||||
timeMode = TimeMode(tm) err s"Invalid time mode $tm",
|
||||
time = t,
|
||||
increment = i,
|
||||
days = d,
|
||||
mode = m.fold(Mode.default)(Mode.orDefault),
|
||||
color = Color(c) err "Invalid color " + c,
|
||||
fen = fen)
|
||||
|
||||
val default = FriendConfig(
|
||||
variant = variantDefault,
|
||||
clock = false,
|
||||
timeMode = TimeMode.Unlimited,
|
||||
time = 5,
|
||||
increment = 8,
|
||||
days = 2,
|
||||
mode = Mode.default,
|
||||
color = Color.default)
|
||||
|
||||
|
@ -77,20 +82,23 @@ object FriendConfig extends BaseHumanConfig {
|
|||
|
||||
private[setup] case class RawFriendConfig(
|
||||
v: Int,
|
||||
k: Boolean,
|
||||
tm: Int,
|
||||
t: Int,
|
||||
i: Int,
|
||||
d: Int,
|
||||
m: Int,
|
||||
f: String = "") {
|
||||
|
||||
def decode = for {
|
||||
variant ← Variant(v)
|
||||
mode ← Mode(m)
|
||||
timeMode <- TimeMode(tm)
|
||||
} yield FriendConfig(
|
||||
variant = variant,
|
||||
clock = k,
|
||||
timeMode = timeMode,
|
||||
time = t,
|
||||
increment = i,
|
||||
days = d,
|
||||
mode = mode,
|
||||
color = Color.White,
|
||||
fen = f.some filter (_.nonEmpty))
|
||||
|
|
|
@ -8,21 +8,23 @@ import lila.user.User
|
|||
|
||||
case class HookConfig(
|
||||
variant: Variant,
|
||||
clock: Boolean,
|
||||
timeMode: TimeMode,
|
||||
time: Int,
|
||||
increment: Int,
|
||||
days: Int,
|
||||
mode: Mode,
|
||||
allowAnon: Boolean,
|
||||
color: Color,
|
||||
ratingRange: RatingRange) extends HumanConfig {
|
||||
|
||||
// allowAnons -> membersOnly
|
||||
def >> = (variant.id, clock, time, increment, mode.id.some, !allowAnon, ratingRange.toString.some, color.name).some
|
||||
def >> = (variant.id, timeMode.id, time, increment, days, mode.id.some, !allowAnon, ratingRange.toString.some, color.name).some
|
||||
|
||||
def hook(uid: String, user: Option[User], sid: Option[String], blocking: Set[String]) = Hook.make(
|
||||
uid = uid,
|
||||
variant = variant,
|
||||
clock = makeClock,
|
||||
daysPerTurn = makeDaysPerTurn,
|
||||
mode = mode,
|
||||
allowAnon = allowAnon,
|
||||
color = color.name,
|
||||
|
@ -33,26 +35,28 @@ case class HookConfig(
|
|||
|
||||
def encode = RawHookConfig(
|
||||
v = variant.id,
|
||||
k = clock,
|
||||
tm = timeMode.id,
|
||||
t = time,
|
||||
i = increment,
|
||||
d = days,
|
||||
m = mode.id,
|
||||
a = allowAnon,
|
||||
e = ratingRange.toString)
|
||||
|
||||
def noRatedUnlimited = mode.casual || clock
|
||||
def noRatedUnlimited = mode.casual || hasClock || makeDaysPerTurn.isDefined
|
||||
}
|
||||
|
||||
object HookConfig extends BaseHumanConfig {
|
||||
|
||||
def <<(v: Int, k: Boolean, t: Int, i: Int, m: Option[Int], membersOnly: Boolean, e: Option[String], c: String) = {
|
||||
def <<(v: Int, tm: Int, t: Int, i: Int, d: Int, m: Option[Int], membersOnly: Boolean, e: Option[String], c: String) = {
|
||||
val realMode = m.fold(Mode.default)(Mode.orDefault)
|
||||
val useRatingRange = realMode.rated || membersOnly
|
||||
new HookConfig(
|
||||
variant = Variant(v) err "Invalid game variant " + v,
|
||||
clock = k,
|
||||
timeMode = TimeMode(tm) err s"Invalid time mode $tm",
|
||||
time = t,
|
||||
increment = i,
|
||||
days = d,
|
||||
mode = realMode,
|
||||
allowAnon = !membersOnly, // membersOnly
|
||||
ratingRange = e.filter(_ => useRatingRange).fold(RatingRange.default)(RatingRange.orDefault),
|
||||
|
@ -61,9 +65,10 @@ object HookConfig extends BaseHumanConfig {
|
|||
|
||||
val default = HookConfig(
|
||||
variant = variantDefault,
|
||||
clock = true,
|
||||
timeMode = TimeMode.Clock,
|
||||
time = 5,
|
||||
increment = 8,
|
||||
days = 2,
|
||||
mode = Mode.default,
|
||||
allowAnon = true,
|
||||
ratingRange = RatingRange.default,
|
||||
|
@ -88,9 +93,10 @@ object HookConfig extends BaseHumanConfig {
|
|||
|
||||
private[setup] case class RawHookConfig(
|
||||
v: Int,
|
||||
k: Boolean,
|
||||
tm: Int,
|
||||
t: Int,
|
||||
i: Int,
|
||||
d: Int,
|
||||
m: Int,
|
||||
a: Boolean,
|
||||
e: String) {
|
||||
|
@ -99,11 +105,13 @@ private[setup] case class RawHookConfig(
|
|||
variant ← Variant(v)
|
||||
mode ← Mode(m)
|
||||
ratingRange ← RatingRange(e)
|
||||
timeMode <- TimeMode(tm)
|
||||
} yield HookConfig(
|
||||
variant = variant,
|
||||
clock = k,
|
||||
timeMode = timeMode,
|
||||
time = t,
|
||||
increment = i,
|
||||
days = d,
|
||||
mode = mode,
|
||||
allowAnon = a,
|
||||
ratingRange = ratingRange,
|
||||
|
|
|
@ -16,6 +16,8 @@ object Mappings {
|
|||
val variantWithFenAndVariants = number.verifying(Config.variantsWithFenAndVariants contains _)
|
||||
val time = number.verifying(HookConfig validateTime _)
|
||||
val increment = number.verifying(HookConfig validateIncrement _)
|
||||
val days = number(min = 1, max = 14)
|
||||
def timeMode = number.verifying(TimeMode.ids contains _)
|
||||
def mode(withRated: Boolean) = optional(rawMode(withRated))
|
||||
def rawMode(withRated: Boolean) = number
|
||||
.verifying(HookConfig.modes contains _)
|
||||
|
|
19
modules/setup/src/main/TimeMode.scala
Normal file
19
modules/setup/src/main/TimeMode.scala
Normal file
|
@ -0,0 +1,19 @@
|
|||
package lila.setup
|
||||
|
||||
sealed abstract class TimeMode(val id: Int)
|
||||
|
||||
object TimeMode {
|
||||
|
||||
case object Unlimited extends TimeMode(0)
|
||||
case object Clock extends TimeMode(1)
|
||||
case object Correspondence extends TimeMode(2)
|
||||
|
||||
val all = List(Unlimited, Clock, Correspondence)
|
||||
|
||||
val ids = all map (_.id)
|
||||
|
||||
val byId = all map { v => (v.id, v) } toMap
|
||||
|
||||
def apply(id: Int): Option[TimeMode] = byId get id
|
||||
}
|
||||
|
|
@ -49,7 +49,7 @@ sealed trait Tournament {
|
|||
def schedule = data.schedule
|
||||
def scheduled = data.schedule.isDefined
|
||||
|
||||
def perfLens = PerfPicker.mainOrDefault(speed, variant)
|
||||
def perfLens = PerfPicker.mainOrDefault(speed, variant, none)
|
||||
|
||||
def userIds = players map (_.id)
|
||||
def activePlayers = players filter (_.active)
|
||||
|
|
|
@ -14,6 +14,7 @@ case class Perfs(
|
|||
bullet: Perf,
|
||||
blitz: Perf,
|
||||
classical: Perf,
|
||||
correspondence: Perf,
|
||||
puzzle: Perf) {
|
||||
|
||||
def perfs = List(
|
||||
|
@ -24,6 +25,7 @@ case class Perfs(
|
|||
"bullet" -> bullet,
|
||||
"blitz" -> blitz,
|
||||
"classical" -> classical,
|
||||
"correspondence" -> correspondence,
|
||||
"puzzle" -> puzzle)
|
||||
|
||||
def bestPerf: Option[(PerfType, Perf)] = {
|
||||
|
@ -55,6 +57,7 @@ case class Perfs(
|
|||
"bullet" -> bullet,
|
||||
"blitz" -> blitz,
|
||||
"classical" -> classical,
|
||||
"correspondence" -> correspondence,
|
||||
"puzzle" -> puzzle)
|
||||
|
||||
def ratingMap: Map[String, Int] = perfsMap mapValues (_.intRating)
|
||||
|
@ -64,14 +67,15 @@ case class Perfs(
|
|||
def apply(key: String): Option[Perf] = perfsMap get key
|
||||
|
||||
def apply(perfType: PerfType): Perf = perfType match {
|
||||
case PerfType.Standard => standard
|
||||
case PerfType.Bullet => bullet
|
||||
case PerfType.Blitz => blitz
|
||||
case PerfType.Classical => classical
|
||||
case PerfType.Chess960 => chess960
|
||||
case PerfType.KingOfTheHill => kingOfTheHill
|
||||
case PerfType.ThreeCheck => threeCheck
|
||||
case PerfType.Puzzle => puzzle
|
||||
case PerfType.Standard => standard
|
||||
case PerfType.Bullet => bullet
|
||||
case PerfType.Blitz => blitz
|
||||
case PerfType.Classical => classical
|
||||
case PerfType.Correspondence => correspondence
|
||||
case PerfType.Chess960 => chess960
|
||||
case PerfType.KingOfTheHill => kingOfTheHill
|
||||
case PerfType.ThreeCheck => threeCheck
|
||||
case PerfType.Puzzle => puzzle
|
||||
}
|
||||
|
||||
def timesAndVariants: List[Perf] = List(bullet, blitz, classical, chess960, kingOfTheHill, threeCheck)
|
||||
|
@ -82,7 +86,7 @@ case class Perfs(
|
|||
|
||||
def updateStandard = copy(
|
||||
standard = {
|
||||
val subs = List(bullet, blitz, classical)
|
||||
val subs = List(bullet, blitz, classical, correspondence)
|
||||
subs.maxBy(_.latest.fold(0l)(_.getMillis)).latest.fold(standard) { date =>
|
||||
val nb = subs.map(_.nb).sum
|
||||
val glicko = Glicko(
|
||||
|
@ -103,7 +107,7 @@ case object Perfs {
|
|||
|
||||
val default = {
|
||||
val p = Perf.default
|
||||
Perfs(p, p, p, p, p, p, p, p)
|
||||
Perfs(p, p, p, p, p, p, p, p, p)
|
||||
}
|
||||
|
||||
def variantLens(variant: Variant): Option[Perfs => Perf] = variant match {
|
||||
|
@ -135,6 +139,7 @@ case object Perfs {
|
|||
bullet = perf("bullet"),
|
||||
blitz = perf("blitz"),
|
||||
classical = perf("classical"),
|
||||
correspondence = perf("correspondence"),
|
||||
puzzle = perf("puzzle"))
|
||||
}
|
||||
|
||||
|
@ -148,6 +153,7 @@ case object Perfs {
|
|||
"bullet" -> notNew(o.bullet),
|
||||
"blitz" -> notNew(o.blitz),
|
||||
"classical" -> notNew(o.classical),
|
||||
"correspondence" -> notNew(o.correspondence),
|
||||
"puzzle" -> notNew(o.puzzle))
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -89,4 +89,5 @@
|
|||
<glyph unicode="/" d="M389 330c34 0 63-12 87-35 24-23 36-52 36-85 0-34-12-62-36-85-24-23-53-35-87-35 0 0-97 0-97 0 0 0 0 97 0 97 0 0 54 0 54 0 0 0-90 118-90 118 0 0-89-118-89-118 0 0 53 0 53 0 0 0 0-97 0-97 0 0-127 0-127 0-25 0-47 9-65 27-19 17-28 39-28 63 0 25 9 47 27 65 18 17 40 26 66 26 5 0 8 0 10-1 0 4-1 11-1 20 0 37 14 68 40 94 27 26 59 39 97 39 30 0 58-9 82-27 23-17 39-40 48-68 9 1 16 2 20 2"/>
|
||||
<glyph unicode="*" d="M107 6c-2-7-7-8-14-4-6 3-8 9-8 17 2 35 10 73 26 116-34 53-43 107-27 162 4-11 9-24 17-40 7-16 15-29 22-41 8-12 13-17 17-15 2 1 2 15 0 42-3 27-5 55-6 85-1 30 3 57 13 81 7 15 21 31 41 48 19 17 37 29 53 36-8-16-14-32-17-49-3-16-4-29-2-40 2-10 5-15 11-16 4 0 18 21 43 62 24 40 42 61 54 62 16 1 35-4 58-15 24-11 38-22 42-33 4-8 4-22 0-41-4-18-11-33-20-42-15-15-40-26-75-32-35-6-54-10-58-12-6-4-4-9 6-18 18-16 48-19 90-10-19-27-42-47-70-58-27-12-49-18-67-20-18-1-27-3-28-5-1-8 7-17 25-27 18-11 36-13 52-8-10-19-21-33-32-43-12-9-21-15-28-17-7-3-20-5-39-6-19-1-33-3-43-4 0 0-36-115-36-115"/>
|
||||
<glyph unicode=":" d="M239 256c0 19-7 35-20 48-13 14-29 20-48 20-19 0-35-6-49-20-13-13-20-29-20-48 0-19 7-35 20-48 14-14 30-20 49-20 19 0 35 6 48 20 13 13 20 29 20 48z m205-137c0 10-4 18-10 24-7 7-15 11-24 11-10 0-18-4-24-11-7-6-11-14-11-24 0-9 4-17 10-24 7-6 15-10 25-10 9 0 17 4 24 10 6 7 10 15 10 24z m0 274c0 9-4 17-10 24-7 6-15 10-24 10-10 0-18-4-24-10-7-7-11-15-11-24 0-10 4-18 10-25 7-6 15-10 25-10 9 0 17 4 24 10 6 7 10 15 10 25z m-103-113l0-49c0-2 0-4-2-5-1-2-2-3-4-3l-41-6c-2-7-5-13-9-21 6-8 14-18 24-30 2-2 2-4 2-6 0-2 0-4-2-5-4-5-11-13-22-24-10-10-17-16-21-16-2 0-3 1-5 2l-31 24c-6-3-13-6-20-8-2-19-4-33-7-41-1-5-3-7-8-7l-49 0c-2 0-4 1-5 2-2 2-3 3-3 5l-6 41c-6 2-13 4-20 8l-32-24c-1-1-3-2-5-2-2 0-4 1-6 3-25 23-38 37-38 42 0 2 1 4 2 5 2 3 5 8 11 14 5 7 9 13 12 17-4 8-7 15-9 22l-41 6c-1 0-3 1-4 3-1 1-2 3-2 5l0 49c0 2 1 4 2 5 1 2 3 3 4 3l41 6c2 7 5 13 9 21-6 8-14 18-24 30-1 2-2 4-2 6 0 2 1 4 2 5 4 5 11 13 22 24 11 10 18 16 21 16 2 0 4-1 6-2l30-24c6 3 13 6 21 8 2 19 4 33 6 41 1 5 4 7 8 7l49 0c2 0 4-1 6-2 1-2 2-3 2-5l7-41c6-2 12-4 20-8l31 24c1 1 3 2 5 2 2 0 4-1 6-3 26-23 38-37 38-42 0-2 0-4-1-5-3-3-6-8-12-15-5-6-9-12-12-16 4-8 7-16 9-22l41-6c2 0 3-1 4-3 2-1 2-3 2-5z m171-142l0-37c0-3-13-6-40-8-2-5-5-10-8-14 9-20 14-33 14-37 0-1 0-1-1-2-22-13-33-19-33-19-2 0-6 4-13 13-6 8-11 14-13 18-4-1-7-1-8-1-2 0-5 0-8 1-3-4-8-10-14-18-7-9-11-13-13-13 0 0-11 6-33 19 0 1-1 1-1 2 0 4 5 17 14 37-3 4-6 9-8 14-27 2-40 5-40 8l0 37c0 3 13 6 40 8 2 6 5 10 8 14-9 20-14 33-14 37 0 1 1 1 1 2 1 0 4 2 10 5 5 3 10 6 15 9 5 3 8 5 8 5 2 0 6-5 13-13 6-8 11-14 14-18 3 1 6 1 8 1 1 0 4 0 8-1 9 13 17 23 24 30l2 1c0 0 11-7 33-19 1-1 1-1 1-2 0-4-5-17-14-37 3-4 6-8 8-14 27-2 40-5 40-8z m0 273l0-37c0-3-13-6-40-8-2-5-5-10-8-14 9-20 14-33 14-37 0-1 0-1-1-2-22-13-33-19-33-19-2 0-6 4-13 13-6 8-11 14-13 18-4-1-7-1-8-1-2 0-5 0-8 1-3-4-8-10-14-18-7-9-11-13-13-13 0 0-11 6-33 19 0 1-1 1-1 2 0 4 5 17 14 37-3 4-6 9-8 14-27 2-40 5-40 8l0 37c0 3 13 6 40 8 2 6 5 10 8 14-9 20-14 33-14 37 0 1 1 1 1 2 1 0 4 2 10 5 5 4 10 7 15 9 5 3 8 5 8 5 2 0 6-4 13-13 6-8 11-14 14-18 3 1 6 1 8 1 1 0 4 0 8-1 9 13 17 23 24 30l2 1c0 0 11-7 33-19 1-1 1-1 1-2 0-4-5-17-14-37 3-4 6-8 8-14 27-2 40-5 40-8z"/>
|
||||
<glyph unicode=";" d="M230 207l-17-164 102 125 97-44 100 345z m282 262l-512-210 121-24 92-192-66 192z"/>
|
||||
</font></defs></svg>
|
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Binary file not shown.
BIN
public/font22/fonts/lichess.woff
Normal file
BIN
public/font22/fonts/lichess.woff
Normal file
Binary file not shown.
|
@ -43,337 +43,6 @@ h2{font-size:18px;padding:0 0 21px 5px;margin:45px 0 0 0;text-transform:uppercas
|
|||
<div class="container">
|
||||
<h1>lichess</h1>
|
||||
<p class="small">This font was created with<a href="http://fontastic.me/">Fontastic</a></p>
|
||||
<h2>Character mapping</h2>
|
||||
<ul class="glyphs character-mapping">
|
||||
<li>
|
||||
<div data-icon="a" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="a">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="b" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="b">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="c" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="c">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="d" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="d">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="e" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="e">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="f" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="f">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="g" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="g">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="h" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="h">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="j" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="j">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="k" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="k">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="l" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="l">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="m" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="m">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="p" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="p">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="r" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="r">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="s" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="s">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="t" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="t">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="u" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="u">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="v" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="v">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="w" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="w">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="x" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="x">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="z" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="z">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="A" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="A">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="C" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="C">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="D" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="D">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="E" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="E">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="F" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="F">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="G" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="G">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="H" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="H">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="I" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="I">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="J" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="J">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="K" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="K">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="B" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="B">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="M" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="M">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="N" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="N">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="L" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="L">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="O" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="O">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="O" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="O">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="O" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="O">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="Q" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="Q">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="Q" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="Q">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="Q" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="Q">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="R" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="R">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="S" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="S">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="T" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="T">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="U" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="U">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="V" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="V">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="W" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="W">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="X" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="X">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="Y" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="Y">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="Z" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="Z">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="!" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="!">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="P" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="P">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="i" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="i">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="2" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="2">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="3" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="3">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="0" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="0">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="1" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="1">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="4" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="4">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="5" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="5">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="6" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="6">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="9" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="9">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon=""" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value=""">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="7" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="7">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="#" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="#">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="$" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="$">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="%" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="%">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="&" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="o" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="o">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="q" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="q">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="y" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="y">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="n" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="n">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="8" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="8">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="'" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="'">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="(" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="(">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon=")" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value=")">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="+" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="+">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="," class="icon"></div>
|
||||
<input type="text" readonly="readonly" value=",">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="-" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="-">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="." class="icon"></div>
|
||||
<input type="text" readonly="readonly" value=".">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="/" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="/">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="*" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="*">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon=":" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value=":">
|
||||
</li>
|
||||
</ul>
|
||||
<h2>CSS mapping</h2>
|
||||
<ul class="glyphs css-mapping">
|
||||
<li>
|
||||
|
@ -704,6 +373,345 @@ h2{font-size:18px;padding:0 0 21px 5px;margin:45px 0 0 0;text-transform:uppercas
|
|||
<div class="icon icon-gears-setting"></div>
|
||||
<input type="text" readonly="readonly" value="gears-setting">
|
||||
</li>
|
||||
<li>
|
||||
<div class="icon icon-email-plane"></div>
|
||||
<input type="text" readonly="readonly" value="email-plane">
|
||||
</li>
|
||||
</ul>
|
||||
<h2>Character mapping</h2>
|
||||
<ul class="glyphs character-mapping">
|
||||
<li>
|
||||
<div data-icon="a" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="a">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="b" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="b">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="c" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="c">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="d" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="d">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="e" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="e">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="f" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="f">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="g" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="g">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="h" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="h">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="j" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="j">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="k" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="k">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="l" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="l">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="m" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="m">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="p" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="p">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="r" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="r">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="s" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="s">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="t" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="t">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="u" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="u">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="v" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="v">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="w" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="w">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="x" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="x">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="z" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="z">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="A" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="A">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="C" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="C">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="D" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="D">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="E" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="E">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="F" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="F">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="G" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="G">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="H" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="H">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="I" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="I">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="J" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="J">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="K" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="K">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="B" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="B">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="M" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="M">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="N" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="N">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="L" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="L">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="O" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="O">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="O" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="O">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="O" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="O">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="Q" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="Q">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="Q" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="Q">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="Q" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="Q">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="R" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="R">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="S" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="S">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="T" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="T">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="U" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="U">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="V" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="V">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="W" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="W">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="X" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="X">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="Y" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="Y">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="Z" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="Z">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="!" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="!">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="P" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="P">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="i" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="i">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="2" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="2">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="3" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="3">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="0" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="0">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="1" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="1">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="4" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="4">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="5" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="5">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="6" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="6">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="9" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="9">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon=""" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value=""">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="7" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="7">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="#" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="#">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="$" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="$">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="%" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="%">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="&" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="&">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="o" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="o">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="q" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="q">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="y" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="y">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="n" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="n">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="8" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="8">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="'" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="'">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="(" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="(">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon=")" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value=")">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="+" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="+">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="," class="icon"></div>
|
||||
<input type="text" readonly="readonly" value=",">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="-" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="-">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="." class="icon"></div>
|
||||
<input type="text" readonly="readonly" value=".">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="/" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="/">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon="*" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value="*">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon=":" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value=":">
|
||||
</li>
|
||||
<li>
|
||||
<div data-icon=";" class="icon"></div>
|
||||
<input type="text" readonly="readonly" value=";">
|
||||
</li>
|
||||
</ul>
|
||||
</div><script type="text/javascript">
|
||||
(function() {
|
|
@ -284,3 +284,6 @@
|
|||
.icon-gears-setting:before {
|
||||
content: ":";
|
||||
}
|
||||
.icon-email-plane:before {
|
||||
content: ";";
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue