diff --git a/.gitignore b/.gitignore index f24a2cb18a..a6277425e7 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,7 @@ public/vendor/stockfish.wasm public/vendor/stockfish-mv.wasm public/vendor/stockfish.pexe public/vendor/stockfish.js +public/css/ target bin/.translate_version data/ @@ -17,6 +18,7 @@ node_modules/ local/ ui/*/npm-debug.log hs_*.log +yarn-error.log RUNNING_PID diff --git a/COPYING.md b/COPYING.md index aac4bc31b8..0c8d2edfae 100644 --- a/COPYING.md +++ b/COPYING.md @@ -36,7 +36,7 @@ Exceptions (free) Files | Author(s) | License --- | --- | --- public/font70 | [Dave Gandy](http://fontawesome.io/), [GitHub](https://github.com/primer/octicons), [Webalys](http://www.webalys.com/), [Zurb](http://zurb.com/playground/foundation-icon-fonts-3), [Daniel Bruce](http://www.entypo.com/), [Shapemade](http://steadysets.com/), [Sergey Shmidt](http://designmodo.com/linecons-free/) and the lichess authors | [OFL](http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL), [MIT](https://github.com/primer/octicons/blob/master/LICENSE), [CC BY 3.0](https://creativecommons.org/licenses/by/3.0/), AGPLv3+ -ChessSansPiratf in public/fonts | the [pgn4web](http://pgn4web.casaschi.net/home.html) authors | [GPLv2+](https://www.gnu.org/licenses/gpl-2.0.txt) +ChessSansPiratf in public/font | the [pgn4web](http://pgn4web.casaschi.net/home.html) authors | [GPLv2+](https://www.gnu.org/licenses/gpl-2.0.txt) public/images/staunton | [James Clarke](https://github.com/clarkerubber/Staunton-Pieces) | [MIT](https://github.com/clarkerubber/Staunton-Pieces/blob/master/LICENSE) public/images/staunton/piece/CubesAndPi | CubesAndPi | AGPLv3+ public/images/trophy | [James Clarke](https://github.com/clarkerubber/Staunton-Pieces/tree/master/Trophies) | [MIT](https://github.com/clarkerubber/Staunton-Pieces/blob/master/LICENSE) diff --git a/app/actor/Renderer.scala b/app/actor/Renderer.scala index 6f84d7096b..c2007fce30 100644 --- a/app/actor/Renderer.scala +++ b/app/actor/Renderer.scala @@ -2,7 +2,6 @@ package lila.app package actor import akka.actor._ -import play.twirl.api.Html import lila.game.Pov import views.{ html => V } @@ -12,10 +11,10 @@ private[app] final class Renderer extends Actor { def receive = { case lila.tv.actorApi.RenderFeaturedJs(game) => - sender ! V.game.bits.featuredJs(Pov first game).body + sender ! V.game.bits.featuredJs(Pov first game).render case lila.tournament.actorApi.TournamentTable(tours) => - sender ! V.tournament.enterable(tours).render + sender ! V.tournament.bits.enterable(tours).render case lila.simul.actorApi.SimulTable(simuls) => sender ! V.simul.bits.allCreated(simuls).render diff --git a/app/controllers/Analyse.scala b/app/controllers/Analyse.scala index a755c58139..467da71c0d 100644 --- a/app/controllers/Analyse.scala +++ b/app/controllers/Analyse.scala @@ -68,16 +68,16 @@ object Analyse extends LilaController { } } - def embed(gameId: String, color: String) = Open { implicit ctx => + def embed(gameId: String, color: String) = Action.async { implicit req => GameRepo.gameWithInitialFen(gameId) flatMap { case Some((game, initialFen)) => val pov = Pov(game, chess.Color(color == "white")) - Env.api.roundApi.review(pov, lila.api.Mobile.Api.currentVersion, + Env.api.roundApi.embed(pov, lila.api.Mobile.Api.currentVersion, initialFenO = initialFen.some, withFlags = WithFlags(opening = true)) map { data => Ok(html.analyse.embed(pov, data)) } - case _ => fuccess(NotFound(html.analyse.embed.notFound())) + case _ => fuccess(NotFound(html.analyse.embed.notFound)) } } diff --git a/app/controllers/Api.scala b/app/controllers/Api.scala index 6532e424f0..0d920b0491 100644 --- a/app/controllers/Api.scala +++ b/app/controllers/Api.scala @@ -43,7 +43,7 @@ object Api extends LilaController { } def index = Action { - Ok(views.html.site.api()) + Ok(views.html.site.bits.api) } def user(name: String) = CookieBasedApiRequest { ctx => diff --git a/app/controllers/Auth.scala b/app/controllers/Auth.scala index fab04dfb06..4e232685e8 100644 --- a/app/controllers/Auth.scala +++ b/app/controllers/Auth.scala @@ -42,13 +42,12 @@ object Auth extends LilaController { } def authenticateUser(u: UserModel, result: Option[String => Result] = None)(implicit ctx: Context): Fu[Result] = { - implicit val req = ctx.req if (u.ipBan) fuccess(Redirect(routes.Lobby.home)) else api.saveAuthentication(u.id, ctx.mobileApiVersion) flatMap { sessionId => negotiate( html = fuccess { val redirectTo = get("referrer").filter(goodReferrer) orElse - req.session.get(api.AccessUri) getOrElse + ctxReq.session.get(api.AccessUri) getOrElse routes.Lobby.home.url result.fold(Redirect(redirectTo))(_(redirectTo)) }, @@ -118,21 +117,19 @@ object Auth extends LilaController { } def logout = Open { implicit ctx => - implicit val req = ctx.req - req.session get "sessionId" foreach lila.security.Store.delete + ctxReq.session get "sessionId" foreach lila.security.Store.delete negotiate( - html = Redirect(routes.Main.mobile).fuccess, + html = Redirect(routes.Auth.login).fuccess, api = _ => Ok(Json.obj("ok" -> true)).fuccess ) map (_ withCookies LilaCookie.newSession) } // mobile app BC logout with GET def logoutGet = Open { implicit ctx => - implicit val req = ctx.req negotiate( html = notFound, api = _ => { - req.session get "sessionId" foreach lila.security.Store.delete + ctxReq.session get "sessionId" foreach lila.security.Store.delete Ok(Json.obj("ok" -> true)).withCookies(LilaCookie.newSession).fuccess } ) @@ -248,7 +245,7 @@ object Auth extends LilaController { private def welcome(user: UserModel, email: EmailAddress)(implicit ctx: Context) = { garbageCollect(user, email) - env.welcomeEmail(user, email) + env.automaticEmail.welcome(user, email) } private def garbageCollect(user: UserModel, email: EmailAddress)(implicit ctx: Context) = @@ -317,7 +314,6 @@ object Auth extends LilaController { } private def redirectNewUser(user: UserModel)(implicit ctx: Context) = { - implicit val req = ctx.req api.saveAuthentication(user.id, ctx.mobileApiVersion) flatMap { sessionId => negotiate( html = Redirect(routes.User.show(user.username)).fuccess, @@ -344,7 +340,7 @@ object Auth extends LilaController { def passwordReset = Open { implicit ctx => forms.passwordResetWithCaptcha map { - case (form, captcha) => Ok(html.auth.passwordReset(form, captcha)) + case (form, captcha) => Ok(html.auth.bits.passwordReset(form, captcha)) } } @@ -352,7 +348,7 @@ object Auth extends LilaController { implicit val req = ctx.body forms.passwordReset.bindFromRequest.fold( err => forms.anyCaptcha map { captcha => - BadRequest(html.auth.passwordReset(err, captcha, false.some)) + BadRequest(html.auth.bits.passwordReset(err, captcha, false.some)) }, data => { UserRepo.enabledWithEmail(data.realEmail.normalize) flatMap { @@ -363,7 +359,7 @@ object Auth extends LilaController { case _ => { lila.mon.user.auth.passwordResetRequest("no_email")() forms.passwordResetWithCaptcha map { - case (form, captcha) => BadRequest(html.auth.passwordReset(form, captcha, false.some)) + case (form, captcha) => BadRequest(html.auth.bits.passwordReset(form, captcha, false.some)) } } } @@ -373,7 +369,7 @@ object Auth extends LilaController { def passwordResetSent(email: String) = Open { implicit ctx => fuccess { - Ok(html.auth.passwordResetSent(email)) + Ok(html.auth.bits.passwordResetSent(email)) } } @@ -386,7 +382,7 @@ object Auth extends LilaController { case Some(user) => { authLog(user.username, "Reset password") lila.mon.user.auth.passwordResetConfirm("token_ok")() - fuccess(html.auth.passwordResetConfirm(user, token, forms.passwdReset, none)) + fuccess(html.auth.bits.passwordResetConfirm(user, token, forms.passwdReset, none)) } } } @@ -400,7 +396,7 @@ object Auth extends LilaController { case Some(user) => implicit val req = ctx.body FormFuResult(forms.passwdReset) { err => - fuccess(html.auth.passwordResetConfirm(user, token, err, false.some)) + fuccess(html.auth.bits.passwordResetConfirm(user, token, err, false.some)) } { data => HasherRateLimit(user.username, ctx.req) { _ => Env.user.authenticator.setPassword(user.id, ClearPassword(data.newPasswd1)) >> diff --git a/app/controllers/Blog.scala b/app/controllers/Blog.scala index 43f4a719a7..7f8aae4ee5 100644 --- a/app/controllers/Blog.scala +++ b/app/controllers/Blog.scala @@ -49,7 +49,7 @@ object Blog extends LilaController { blogApi context req flatMap { implicit prismic => blogApi.recent(prismic.api, none, 1, lila.common.MaxPerPage(50)) map { _ ?? { docs => - Ok(views.xml.blog.atom(docs)) as XML + Ok(views.html.blog.atom(docs)) as XML } } } diff --git a/app/controllers/Challenge.scala b/app/controllers/Challenge.scala index f8f9203835..de10958718 100644 --- a/app/controllers/Challenge.scala +++ b/app/controllers/Challenge.scala @@ -41,13 +41,16 @@ object Challenge extends LilaController { else none val json = env.jsonView.show(c, version, direction) negotiate( - html = fuccess { - if (mine) error match { - case Some(e) => BadRequest(html.challenge.mine.apply(c, json, e.some)) - case None => Ok(html.challenge.mine.apply(c, json, none)) + html = + if (mine) fuccess { + error match { + case Some(e) => BadRequest(html.challenge.mine(c, json, e.some)) + case None => Ok(html.challenge.mine(c, json, none)) + } } - else Ok(html.challenge.theirs.apply(c, json)) - }, + else (c.challengerUserId ?? UserRepo.named) map { user => + Ok(html.challenge.theirs(c, json, user)) + }, api = _ => Ok(json).fuccess ) flatMap withChallengeAnonCookie(mine && c.challengerIsAnon, c, true) } @@ -90,7 +93,6 @@ object Challenge extends LilaController { cond ?? { GameRepo.game(c.id).map { _ map { game => - implicit val req = ctx.req LilaCookie.cookie( AnonCookie.name, game.player(if (owner) c.finalColor else !c.finalColor).id, diff --git a/app/controllers/Coordinate.scala b/app/controllers/Coordinate.scala index 824b425636..a017af1497 100644 --- a/app/controllers/Coordinate.scala +++ b/app/controllers/Coordinate.scala @@ -30,8 +30,7 @@ object Coordinate extends LilaController { err => fuccess(BadRequest), value => Env.pref.api.setPref( me, - (p: lila.pref.Pref) => p.copy(coordColor = value), - notifyChange = false + (p: lila.pref.Pref) => p.copy(coordColor = value) ) inject Ok(()) ) } diff --git a/app/controllers/Dasher.scala b/app/controllers/Dasher.scala index ee8ad3cfc3..95e199cd83 100644 --- a/app/controllers/Dasher.scala +++ b/app/controllers/Dasher.scala @@ -70,8 +70,7 @@ object Dasher extends LilaController { "image" -> ctx.pref.bgImgOrDefault ), "board" -> Json.obj( - "is3d" -> ctx.pref.is3d, - "zoom" -> ctx.zoom + "is3d" -> ctx.pref.is3d ), "theme" -> Json.obj( "d2" -> Json.obj( diff --git a/app/controllers/Editor.scala b/app/controllers/Editor.scala index 0ebcb357fe..6418f66fb0 100644 --- a/app/controllers/Editor.scala +++ b/app/controllers/Editor.scala @@ -3,7 +3,6 @@ package controllers import chess.format.Forsyth import chess.Situation import play.api.libs.json._ -import play.twirl.api.Html import lila.app._ import lila.game.GameRepo diff --git a/app/controllers/Event.scala b/app/controllers/Event.scala index 2546d17151..fd1ebb9ebd 100644 --- a/app/controllers/Event.scala +++ b/app/controllers/Event.scala @@ -7,12 +7,6 @@ object Event extends LilaController { private def api = Env.event.api - def index = Open { implicit ctx => - api.recentEnabled.map { events => - Ok(html.event.index(events)) - } - } - def show(id: String) = Open { implicit ctx => OptionOk(api oneEnabled id) { event => html.event.show(event) diff --git a/app/controllers/ForumTopic.scala b/app/controllers/ForumTopic.scala index fd8823c448..5cd2868671 100644 --- a/app/controllers/ForumTopic.scala +++ b/app/controllers/ForumTopic.scala @@ -46,7 +46,7 @@ object ForumTopic extends LilaController with ForumController { case (categ, topic, posts) => for { unsub <- ctx.userId ?? Env.timeline.status(s"forum:${topic.id}") canWrite <- isGrantedWrite(categSlug) - form <- (!posts.hasNextPage && canWrite && topic.open) ?? forms.postWithCaptcha.map(_.some) + form <- (!posts.hasNextPage && canWrite && topic.open && !topic.isOld) ?? forms.postWithCaptcha.map(_.some) canModCateg <- isGrantedMod(categ.slug) _ <- Env.user.lightUserApi preloadMany posts.currentPageResults.flatMap(_.userId) } yield html.forum.topic.show(categ, topic, posts, form, unsub, canModCateg = canModCateg) diff --git a/app/controllers/LilaController.scala b/app/controllers/LilaController.scala index 2bfb86af4a..8fb2e23f16 100644 --- a/app/controllers/LilaController.scala +++ b/app/controllers/LilaController.scala @@ -6,8 +6,7 @@ import play.api.http._ import play.api.libs.json.{ Json, JsObject, JsArray, JsString, Writes } import play.api.mvc._ import play.api.mvc.BodyParsers.parse -import play.twirl.api.Html -import scalatags.Text.{ TypedTag, Frag } +import scalatags.Text.Frag import lila.api.{ PageData, Context, HeaderContext, BodyContext } import lila.app._ @@ -28,22 +27,11 @@ private[controllers] trait LilaController protected implicit val LilaResultZero = Zero.instance[Result](Results.NotFound) - protected implicit val LilaHtmlMonoid = lila.app.templating.Environment.LilaHtmlMonoid - protected implicit final class LilaPimpedResult(result: Result) { def fuccess = scala.concurrent.Future successful result } - protected implicit def LilaHtmlToResult(content: Html): Result = Ok(content) - - protected implicit def contentTypeOfFrag(implicit codec: Codec): ContentTypeOf[Frag] = - ContentTypeOf[Frag](Some(ContentTypes.HTML)) - protected implicit def writeableOfFrag(implicit codec: Codec): Writeable[Frag] = - Writeable(frag => codec.encode(frag.render)) - - protected implicit def LilaScalatagsToHtml(tags: scalatags.Text.TypedTag[String]): Html = Html(tags.render) - - protected implicit def LilaFragToResult(content: Frag): Result = Ok(content) + protected implicit def LilaFragToResult(frag: Frag): Result = Ok(frag) protected implicit def makeApiVersion(v: Int) = ApiVersion(v) @@ -56,7 +44,9 @@ private[controllers] trait LilaController api = _ => fuccess(jsonOkResult) ) - implicit def lang(implicit ctx: Context) = ctx.lang + implicit def ctxLang(implicit ctx: Context) = ctx.lang + implicit def ctxReq(implicit ctx: Context) = ctx.req + implicit def reqConfig(implicit req: RequestHeader) = ui.EmbedConfig(req) protected def NoCache(res: Result): Result = res.withHeaders( CACHE_CONTROL -> "no-cache, no-store, must-revalidate", EXPIRES -> "0" @@ -213,7 +203,7 @@ private[controllers] trait LilaController protected def NoTor(res: => Fu[Result])(implicit ctx: Context) = if (Env.security.tor isExitNode HTTPRequest.lastRemoteAddress(ctx.req)) - Unauthorized(views.html.auth.tor()).fuccess + Unauthorized(views.html.auth.bits.tor()).fuccess else res protected def NoEngine[A <: Result](a: => Fu[A])(implicit ctx: Context): Fu[Result] = @@ -347,8 +337,7 @@ private[controllers] trait LilaController protected def authenticationFailed(implicit ctx: Context): Fu[Result] = negotiate( html = fuccess { - implicit val req = ctx.req - Redirect(routes.Auth.signup) withCookies LilaCookie.session(Env.security.api.AccessUri, req.uri) + Redirect(routes.Auth.signup) withCookies LilaCookie.session(Env.security.api.AccessUri, ctx.req.uri) }, api = _ => ensureSessionId(ctx.req) { Unauthorized(jsonError("Login required")) @@ -361,7 +350,7 @@ private[controllers] trait LilaController html = if (HTTPRequest isSynchronousHttp ctx.req) fuccess { lila.mon.http.response.code403() - Forbidden(views.html.base.authFailed()) + Forbidden(views.html.site.message.authFailed) } else fuccess(Results.Forbidden("Authorization failed")), api = _ => fuccess(forbiddenJsonResult) @@ -371,8 +360,8 @@ private[controllers] trait LilaController if (req.session.data.contains(LilaCookie.sessionId)) res else res withCookies LilaCookie.makeSessionId(req) - protected def negotiate(html: => Fu[Result], api: ApiVersion => Fu[Result])(implicit ctx: Context): Fu[Result] = - lila.api.Mobile.Api.requestVersion(ctx.req).fold(html) { v => + protected def negotiate(html: => Fu[Result], api: ApiVersion => Fu[Result])(implicit req: RequestHeader): Fu[Result] = + lila.api.Mobile.Api.requestVersion(req).fold(html) { v => api(v) dmap (_ as JSON) }.dmap(_.withHeaders("Vary" -> "Accept")) @@ -430,7 +419,9 @@ private[controllers] trait LilaController } } dmap { case Some(d) if !lila.common.PlayApp.isProd => - Some(d.copy(user = d.user.addRole(lila.security.Permission.Beta.name))) + d.copy(user = d.user + .addRole(lila.security.Permission.Beta.name) + .addRole(lila.security.Permission.Prismic.name)).some case d => d } flatMap { case None => fuccess(None -> None) diff --git a/app/controllers/Main.scala b/app/controllers/Main.scala index 7e483b3b8a..5e9a8294e9 100644 --- a/app/controllers/Main.scala +++ b/app/controllers/Main.scala @@ -69,7 +69,7 @@ object Main extends LilaController { def mobile = Open { implicit ctx => pageHit OptionOk(Prismic getBookmark "mobile-apk") { - case (doc, resolver) => html.mobile.home(doc, resolver) + case (doc, resolver) => html.mobile(doc, resolver) } } @@ -135,10 +135,6 @@ Disallow: /games/export } } - val freeJs = Open { implicit ctx => - Ok(html.site.freeJs(ctx)).fuccess - } - def renderNotFound(req: RequestHeader): Fu[Result] = reqToCtx(req) map renderNotFound @@ -147,12 +143,8 @@ Disallow: /games/export NotFound(html.base.notFound()(ctx)) } - def fpmenu = Open { implicit ctx => - Ok(html.base.fpmenu()).fuccess - } - def getFishnet = Open { implicit ctx => - Ok(html.site.getFishnet()).fuccess + Ok(html.site.bits.getFishnet()).fuccess } def costs = Open { implicit ctx => @@ -181,6 +173,7 @@ Disallow: /games/export case 87 => routes.Stat.ratingDistribution("blitz").url case 110 => s"$faq#name" case 29 => s"$faq#titles" + case 4811 => s"$faq#lm" case 216 => routes.Main.mobile.url case 340 => s"$faq#trophies" case 6 => s"$faq#ratings" diff --git a/app/controllers/Message.scala b/app/controllers/Message.scala index 0601d4db27..5f82b237d7 100644 --- a/app/controllers/Message.scala +++ b/app/controllers/Message.scala @@ -3,8 +3,8 @@ package controllers import play.api.data.Form import play.api.libs.json._ import play.api.mvc.Result -import play.twirl.api.Html import scala.concurrent.duration._ +import scalatags.Text.Frag import lila.api.Context import lila.app._ @@ -47,7 +47,7 @@ object Message extends LilaController { negotiate( html = OptionFuOk(api.thread(id, me)) { thread => relationApi.fetchBlocks(thread otherUserId me, me.id) map { blocked => - val form = !thread.isTooBig option forms.post + val form = thread.isReplyable option forms.post html.message.thread(thread, form, blocked) } } map NoCache, @@ -131,7 +131,7 @@ object Message extends LilaController { } } - private def renderForm(me: UserModel, title: Option[String], f: Form[_] => Form[_])(implicit ctx: Context): Fu[Html] = + private def renderForm(me: UserModel, title: Option[String], f: Form[_] => Form[_])(implicit ctx: Context): Fu[Frag] = get("user") ?? UserRepo.named flatMap { user => user.fold(fuTrue)(u => security.canMessage(me.id, u.id)) map { canMessage => html.message.form( diff --git a/app/controllers/Mod.scala b/app/controllers/Mod.scala index 620c3ad769..cabee1af2e 100644 --- a/app/controllers/Mod.scala +++ b/app/controllers/Mod.scala @@ -7,6 +7,7 @@ import lila.common.{ IpAddress, EmailAddress, HTTPRequest } import lila.report.{ Suspect, Mod => AsMod, SuspectId } import lila.security.Permission import lila.user.{ UserRepo, User => UserModel, Title } +import lila.mod.UserSearch import ornicar.scalalib.Zero import views._ @@ -236,13 +237,18 @@ object Mod extends LilaController { def search = SecureBody(_.UserSearch) { implicit ctx => me => implicit def req = ctx.body - val f = lila.mod.UserSearch.form + val f = UserSearch.form f.bindFromRequest.fold( err => BadRequest(html.mod.search(err, Nil)).fuccess, query => Env.mod.search(query) map { html.mod.search(f.fill(query), _) } ) } + protected[controllers] def searchTerm(q: String)(implicit ctx: Context) = { + val query = UserSearch exact q + Env.mod.search(query) map { users => Ok(html.mod.search(UserSearch.form fill query, users)) } + } + def chatUser(username: String) = Secure(_.ChatTimeout) { implicit ctx => me => implicit val lightUser = Env.user.lightUserSync _ JsonOptionOk { @@ -267,7 +273,7 @@ object Mod extends LilaController { )).bindFromRequest.fold( err => BadRequest(html.mod.permissions(user)).fuccess, permissions => - modApi.setPermissions(me.id, user.username, Permission(permissions)) >> { + modApi.setPermissions(AsMod(me), user.username, Permission(permissions)) >> { (Permission(permissions) diff Permission(user.roles) contains Permission.Coach) ?? Env.security.automaticEmail.onBecomeCoach(user) } >> { @@ -285,7 +291,7 @@ object Mod extends LilaController { val email = query.headOption.map(EmailAddress.apply) flatMap Env.security.emailAddressValidator.validate val username = query lift 1 def tryWith(setEmail: EmailAddress, q: String): Fu[Option[Result]] = - Env.mod.search(lila.mod.UserSearch.exact(q)) flatMap { + Env.mod.search(UserSearch.exact(q)) flatMap { case List(UserModel.WithEmails(user, _)) => (!user.everLoggedIn).?? { lila.mon.user.register.modConfirmEmail() modApi.setEmail(me.id, user.id, setEmail) diff --git a/app/controllers/OAuthApp.scala b/app/controllers/OAuthApp.scala index edddfa537c..ba2ebfb54f 100644 --- a/app/controllers/OAuthApp.scala +++ b/app/controllers/OAuthApp.scala @@ -19,13 +19,13 @@ object OAuthApp extends LilaController { } def create = Auth { implicit ctx => me => - Ok(html.oAuth.app.create(env.forms.app.create)).fuccess + Ok(html.oAuth.app.form.create(env.forms.app.create)).fuccess } def createApply = AuthBody { implicit ctx => me => implicit val req = ctx.body env.forms.app.create.bindFromRequest.fold( - err => BadRequest(html.oAuth.app.create(err)).fuccess, + err => BadRequest(html.oAuth.app.form.create(err)).fuccess, setup => { val app = setup make me env.appApi.create(app) inject Redirect(routes.OAuthApp.edit(app.clientId.value)) @@ -35,7 +35,7 @@ object OAuthApp extends LilaController { def edit(id: String) = Auth { implicit ctx => me => OptionFuResult(env.appApi.findBy(App.Id(id), me)) { app => - Ok(html.oAuth.app.edit(app, env.forms.app.edit(app))).fuccess + Ok(html.oAuth.app.form.edit(app, env.forms.app.edit(app))).fuccess } } @@ -43,7 +43,7 @@ object OAuthApp extends LilaController { OptionFuResult(env.appApi.findBy(App.Id(id), me)) { app => implicit val req = ctx.body env.forms.app.edit(app).bindFromRequest.fold( - err => BadRequest(html.oAuth.app.edit(app, err)).fuccess, + err => BadRequest(html.oAuth.app.form.edit(app, err)).fuccess, data => env.appApi.update(app) { data.update(_) } map { r => Redirect(routes.OAuthApp.edit(app.clientId.value)) } ) } diff --git a/app/controllers/Page.scala b/app/controllers/Page.scala index 48611812b1..d01cd3c831 100644 --- a/app/controllers/Page.scala +++ b/app/controllers/Page.scala @@ -28,6 +28,13 @@ object Page extends LilaController { } } + def source = Open { implicit ctx => + pageHit + OptionOk(Prismic getBookmark "source") { + case (doc, resolver) => views.html.site.help.source(doc, resolver) + } + } + def swag = Open { implicit ctx => pageHit OptionOk(Prismic getBookmark "swag") { diff --git a/app/controllers/Pref.scala b/app/controllers/Pref.scala index 44e2685043..210f7fc88b 100644 --- a/app/controllers/Pref.scala +++ b/app/controllers/Pref.scala @@ -31,8 +31,7 @@ object Pref extends LilaController { } def formApply = AuthBody { implicit ctx => me => - def onSuccess(data: lila.pref.DataForm.PrefData) = - api.setPref(data(ctx.pref), notifyChange = true) inject Ok("saved") + def onSuccess(data: lila.pref.DataForm.PrefData) = api.setPref(data(ctx.pref)) inject Ok("saved") implicit val req = ctx.body forms.pref.bindFromRequest.fold( err => forms.pref.bindFromRequest(lila.pref.FormCompatLayer(ctx.body)).fold( @@ -43,16 +42,16 @@ object Pref extends LilaController { ) } - def setZoom = Action { implicit req => - val zoom = getInt("v", req) | 100 - Ok(()).withCookies(LilaCookie.session("zoom", zoom.toString)) - } - def set(name: String) = OpenBody { implicit ctx => implicit val req = ctx.body - (setters get name) ?? { - case (form, fn) => FormResult(form) { v => - fn(v, ctx) map { cookie => Ok(()).withCookies(cookie) } + if (name == "zoom") { + Ok.withCookies(LilaCookie.session("zoom", (getInt("v") | 180).toString)).fuccess + } else { + implicit val req = ctx.body + (setters get name) ?? { + case (form, fn) => FormResult(form) { v => + fn(v, ctx) map { cookie => Ok(()).withCookies(cookie) } + } } } } @@ -75,6 +74,6 @@ object Pref extends LilaController { private def save(name: String)(value: String, ctx: Context): Fu[Cookie] = ctx.me ?? { - api.setPrefString(_, name, value, notifyChange = false) + api.setPrefString(_, name, value) } inject LilaCookie.session(name, value)(ctx.req) } diff --git a/app/controllers/Puzzle.scala b/app/controllers/Puzzle.scala index 39a083368e..2a53e88ec5 100644 --- a/app/controllers/Puzzle.scala +++ b/app/controllers/Puzzle.scala @@ -5,6 +5,7 @@ import play.api.mvc._ import lila.api.Context import lila.app._ +import lila.common.{ HTTPRequest, IpAddress, MaxPerSecond } import lila.game.PgnDump import lila.puzzle.{ PuzzleId, Result, Puzzle => PuzzleModel, UserInfos } import lila.user.UserRepo @@ -215,18 +216,37 @@ object Puzzle extends LilaController { ) } + /* For BC */ def embed = Action { req => Ok { val bg = get("bg", req) | "light" val theme = get("theme", req) | "brown" val url = s"""${req.domain + routes.Puzzle.frame}?bg=$bg&theme=$theme""" - s"""document.write("");""" + s"""document.write("");""" } as JAVASCRIPT withHeaders (CACHE_CONTROL -> "max-age=86400") } - def frame = Open { implicit ctx => - OptionOk(env.daily.get) { daily => - html.puzzle.embed(daily) + def frame = Action.async { implicit req => + env.daily.get map { + case None => NotFound + case Some(daily) => html.puzzle.embed(daily) } } + + def activity = Scoped(_.Puzzle.Read) { req => me => + Api.GlobalLinearLimitPerIP(HTTPRequest lastRemoteAddress req) { + Api.GlobalLinearLimitPerUserOption(me.some) { + val config = lila.puzzle.PuzzleActivity.Config( + user = me, + max = getInt("max", req) map (_ atLeast 1), + perSecond = MaxPerSecond(20) + ) + Ok.chunked(env.activity.stream(config)).withHeaders( + noProxyBufferHeader, + CONTENT_TYPE -> ndJsonContentType + ).fuccess + } + } + } + } diff --git a/app/controllers/Relation.scala b/app/controllers/Relation.scala index 8d3ed5f9da..a1adb55015 100644 --- a/app/controllers/Relation.scala +++ b/app/controllers/Relation.scala @@ -35,7 +35,13 @@ object Relation extends LilaController { } def follow(userId: String) = Auth { implicit ctx => me => - env.api.follow(me.id, UserModel normalize userId).nevermind >> renderActions(userId, getBool("mini")) + env.api.reachedMaxFollowing(me.id) flatMap { + case true => Env.message.api.sendPresetFromLichess( + me, + lila.message.ModPreset.maxFollow(me.username, Env.relation.MaxFollow) + ).void + case _ => env.api.follow(me.id, UserModel normalize userId).nevermind >> renderActions(userId, getBool("mini")) + } } def unfollow(userId: String) = Auth { implicit ctx => me => @@ -56,7 +62,7 @@ object Relation extends LilaController { RelatedPager(env.api.followingPaginatorAdapter(user.id), page) flatMap { pag => negotiate( html = env.api countFollowers user.id map { nbFollowers => - Ok(html.relation.following(user, pag, nbFollowers)) + Ok(html.relation.bits.following(user, pag, nbFollowers)) }, api = _ => Ok(jsonRelatedPaginator(pag)).fuccess ) @@ -71,7 +77,7 @@ object Relation extends LilaController { RelatedPager(env.api.followersPaginatorAdapter(user.id), page) flatMap { pag => negotiate( html = env.api countFollowing user.id map { nbFollowing => - Ok(html.relation.followers(user, pag, nbFollowing)) + Ok(html.relation.bits.followers(user, pag, nbFollowing)) }, api = _ => Ok(jsonRelatedPaginator(pag)).fuccess ) @@ -112,7 +118,7 @@ object Relation extends LilaController { def blocks(page: Int) = Auth { implicit ctx => me => Reasonable(page, 20) { RelatedPager(env.api.blockingPaginatorAdapter(me.id), page) map { pag => - html.relation.blocks(me, pag) + html.relation.bits.blocks(me, pag) } } } diff --git a/app/controllers/Relay.scala b/app/controllers/Relay.scala index 64fce59101..a214ce107c 100644 --- a/app/controllers/Relay.scala +++ b/app/controllers/Relay.scala @@ -23,14 +23,14 @@ object Relay extends LilaController { def form = Auth { implicit ctx => me => NoLame { - Ok(html.relay.create(env.forms.create)).fuccess + Ok(html.relay.form.create(env.forms.create)).fuccess } } def create = AuthBody { implicit ctx => me => implicit val req = ctx.body env.forms.create.bindFromRequest.fold( - err => BadRequest(html.relay.create(err)).fuccess, + err => BadRequest(html.relay.form.create(err)).fuccess, setup => env.api.create(setup, me) map { relay => Redirect(showRoute(relay)) } @@ -39,7 +39,7 @@ object Relay extends LilaController { def edit(slug: String, id: String) = Auth { implicit ctx => me => OptionFuResult(env.api.byIdAndContributor(id, me)) { relay => - Ok(html.relay.edit(relay, env.forms.edit(relay))).fuccess + Ok(html.relay.form.edit(relay, env.forms.edit(relay))).fuccess } } @@ -47,7 +47,7 @@ object Relay extends LilaController { OptionFuResult(env.api.byIdAndContributor(id, me)) { relay => implicit val req = ctx.body env.forms.edit(relay).bindFromRequest.fold( - err => BadRequest(html.relay.edit(relay, err)).fuccess, + err => BadRequest(html.relay.form.edit(relay, err)).fuccess, data => env.api.update(relay) { data.update(_, me) } map { r => Redirect(showRoute(r)) } diff --git a/app/controllers/Round.scala b/app/controllers/Round.scala index 6fcf23d0b5..186588f6db 100644 --- a/app/controllers/Round.scala +++ b/app/controllers/Round.scala @@ -73,7 +73,7 @@ object Round extends LilaController with TheftPrevention { simul foreach Env.simul.api.onPlayerConnection(pov.game, ctx.me) Ok(html.round.player(pov, data, tour = tour, - simul = simul.filter(_ isHost ctx.me), + simul = simul, cross = crosstable, playing = playing, chatOption = chatOption, @@ -192,7 +192,7 @@ object Round extends LilaController with TheftPrevention { else for { // web crawlers don't need the full thing initialFen <- GameRepo.initialFen(pov.gameId) pgn <- Env.api.pgnDump(pov.game, initialFen, none, PgnDump.WithFlags(clocks = false)) - } yield Ok(html.round.watcherBot(pov, initialFen, pgn)) + } yield Ok(html.round.watcher.crawler(pov, initialFen, pgn)) }.mon(_.http.response.watcher.website), api = apiVersion => for { data <- Env.api.roundApi.watcher(pov, apiVersion, tv = none) @@ -210,7 +210,7 @@ object Round extends LilaController with TheftPrevention { tourId ?? { Env.tournament.api.miniView(_, withTop) } private[controllers] def getWatcherChat(game: GameModel)(implicit ctx: Context): Fu[Option[lila.chat.UserChat.Mine]] = { - ctx.noKid && ctx.me.exists(Env.chat.panic.allowed) && { + ctx.noKid && ctx.me.fold(true)(Env.chat.panic.allowed) && { game.finishedOrAborted || !ctx.userId.exists(game.userIds.contains) } } ?? { @@ -222,7 +222,7 @@ object Round extends LilaController with TheftPrevention { private[controllers] def getPlayerChat(game: GameModel, tour: Option[Tour])(implicit ctx: Context): Fu[Option[Chat.GameOrEvent]] = ctx.noKid ?? { (game.tournamentId, game.simulId) match { case (Some(tid), _) => { - ctx.isAuth && tour.fold(true)(Tournament.canHaveChat) + ctx.isAuth && tour.fold(true)(Tournament.canHaveChat(_, none)) } ?? Env.chat.api.userChat.cached.findMine(Chat.Id(tid), ctx.me).map { chat => Chat.GameOrEvent(Right(chat truncate 50)).some @@ -294,14 +294,10 @@ object Round extends LilaController with TheftPrevention { } def mini(gameId: String, color: String) = Open { implicit ctx => - OptionOk(GameRepo.pov(gameId, color)) { pov => - html.game.bits.mini(pov) - } + OptionOk(GameRepo.pov(gameId, color))(html.game.bits.mini) } def miniFullId(fullId: String) = Open { implicit ctx => - OptionOk(GameRepo pov fullId) { pov => - html.game.bits.mini(pov) - } + OptionOk(GameRepo pov fullId)(html.game.bits.mini) } } diff --git a/app/controllers/Setup.scala b/app/controllers/Setup.scala index 15473d9e66..734e0a3640 100644 --- a/app/controllers/Setup.scala +++ b/app/controllers/Setup.scala @@ -218,7 +218,6 @@ object Setup extends LilaController with TheftPrevention { } private[controllers] def redirectPov(pov: Pov)(implicit ctx: Context) = { - implicit val req = ctx.req val redir = Redirect(routes.Round.watcher(pov.gameId, "white")) if (ctx.isAuth) redir else redir withCookies LilaCookie.cookie( diff --git a/app/controllers/Simul.scala b/app/controllers/Simul.scala index 50355e99e3..82e7d5616a 100644 --- a/app/controllers/Simul.scala +++ b/app/controllers/Simul.scala @@ -5,9 +5,9 @@ import play.api.mvc._ import lila.api.Context import lila.app._ +import lila.chat.Chat import lila.common.HTTPRequest import lila.simul.{ Simul => Sim } -import lila.chat.Chat import views._ object Simul extends LilaController { @@ -48,36 +48,50 @@ object Simul extends LilaController { } map NoCache } - private[controllers] def canHaveChat(implicit ctx: Context): Boolean = ctx.me ?? { u => - if (ctx.kid) false - else Env.chat.panic allowed u - } + private[controllers] def canHaveChat(implicit ctx: Context): Boolean = + !ctx.kid && // no public chats for kids + ctx.me.fold(true) { // anon can see public chats + Env.chat.panic.allowed + } def start(simulId: String) = Open { implicit ctx => AsHost(simulId) { simul => env.api start simul.id - Ok(Json.obj("ok" -> true)) as JSON + jsonOkResult } } def abort(simulId: String) = Open { implicit ctx => AsHost(simulId) { simul => env.api abort simul.id - Ok(Json.obj("ok" -> true)) as JSON + jsonOkResult } } def accept(simulId: String, userId: String) = Open { implicit ctx => AsHost(simulId) { simul => env.api.accept(simul.id, userId, true) - Ok(Json.obj("ok" -> true)) as JSON + jsonOkResult } } def reject(simulId: String, userId: String) = Open { implicit ctx => AsHost(simulId) { simul => env.api.accept(simul.id, userId, false) - Ok(Json.obj("ok" -> true)) as JSON + jsonOkResult + } + } + + def setText(simulId: String) = OpenBody { implicit ctx => + AsHost(simulId) { simul => + implicit val req = ctx.body + env.forms.setText.bindFromRequest.fold( + err => BadRequest, + text => { + env.api.setText(simul.id, text) + jsonOkResult + } + ) } } diff --git a/app/controllers/Streamer.scala b/app/controllers/Streamer.scala index aaaebbb9e3..2a1238af87 100644 --- a/app/controllers/Streamer.scala +++ b/app/controllers/Streamer.scala @@ -47,7 +47,7 @@ object Streamer extends LilaController { def create = AuthBody { implicit ctx => me => NoLame { NoShadowban { - api.find(me) flatMap { + api find me flatMap { case None => api.create(me) inject Redirect(routes.Streamer.edit) case _ => Redirect(routes.Streamer.edit).fuccess } @@ -120,7 +120,7 @@ object Streamer extends LilaController { private def AsStreamer(f: StreamerModel.WithUser => Fu[Result])(implicit ctx: Context) = ctx.me.fold(notFound) { me => api.find(get("u").ifTrue(isGranted(_.Streamers)) | me.id) flatMap { - _.fold(Ok(html.streamer.create(me)).fuccess)(f) + _.fold(Ok(html.streamer.bits.create(me)).fuccess)(f) } } diff --git a/app/controllers/Study.scala b/app/controllers/Study.scala index f56174b954..353e0dbe0b 100644 --- a/app/controllers/Study.scala +++ b/app/controllers/Study.scala @@ -32,7 +32,7 @@ object Study extends LilaController { } else Env.studySearch(ctx.me)(text, page) flatMap { pag => negotiate( - html = Ok(html.study.search(pag, text)).fuccess, + html = Ok(html.study.list.search(pag, text)).fuccess, api = _ => apiStudies(pag) ) } @@ -209,10 +209,12 @@ object Study extends LilaController { } } - private[controllers] def chatOf(study: lila.study.Study)(implicit ctx: Context) = - (ctx.noKid && ctx.me.exists { me => - study.isMember(me.id) || Env.chat.panic.allowed(me) - }) ?? Env.chat.api.userChat.findMine(Chat.Id(study.id.value), ctx.me).map(some) + private[controllers] def chatOf(study: lila.study.Study)(implicit ctx: Context) = { + !ctx.kid && // no public chats for kids + ctx.me.fold(true) { // anon can see public chats + Env.chat.panic.allowed + } + } ?? Env.chat.api.userChat.findMine(Chat.Id(study.id.value), ctx.me).map(some) def websocket(id: String, apiVersion: Int) = SocketOption[JsValue] { implicit ctx => get("sri") ?? { uid => @@ -278,17 +280,17 @@ object Study extends LilaController { ) } - def embed(id: String, chapterId: String) = Open { implicit ctx => - env.api.byIdWithChapter(id, chapterId) flatMap { + def embed(id: String, chapterId: String) = Action.async { implicit req => + env.api.byIdWithChapter(id, chapterId).map(_.filterNot(_.study.isPrivate)) flatMap { _.fold(embedNotFound) { - case WithChapter(study, chapter) => CanViewResult(study) { + case WithChapter(study, chapter) => env.jsonView(study.copy( members = lila.study.StudyMembers(Map.empty) // don't need no members - ), List(chapter.metadata), chapter, ctx.me) flatMap { studyJson => + ), List(chapter.metadata), chapter, none) flatMap { studyJson => val setup = chapter.setup val initialFen = chapter.root.fen.some val pov = UserAnalysis.makePov(initialFen, setup.variant) - val baseData = Env.round.jsonView.userAnalysisJson(pov, ctx.pref, initialFen, setup.orientation, owner = false, me = ctx.me) + val baseData = Env.round.jsonView.userAnalysisJson(pov, lila.pref.Pref.default, initialFen, setup.orientation, owner = false, me = none) val analysis = baseData ++ Json.obj( "treeParts" -> partitionTreeJsonWriter.writes { lila.study.TreeBuilder.makeRoot(chapter.root, setup.variant) @@ -303,13 +305,12 @@ object Study extends LilaController { api = _ => Ok(Json.obj("study" -> data.study, "analysis" -> data.analysis)).fuccess ) } - } } } map NoCache } - private def embedNotFound(implicit ctx: Context): Fu[Result] = - fuccess(NotFound(html.study.embed.notFound())) + private def embedNotFound(implicit req: RequestHeader): Fu[Result] = + fuccess(NotFound(html.study.embed.notFound)) def cloneStudy(id: String) = Auth { implicit ctx => me => OptionFuResult(env.api.byId(id)) { study => diff --git a/app/controllers/Team.scala b/app/controllers/Team.scala index 4b7d672709..503323b032 100644 --- a/app/controllers/Team.scala +++ b/app/controllers/Team.scala @@ -19,7 +19,7 @@ object Team extends LilaController { def all(page: Int) = Open { implicit ctx => NotForKids { - paginator popularTeams page map { html.team.all(_) } + paginator popularTeams page map { html.team.list.all(_) } } } @@ -40,8 +40,8 @@ object Team extends LilaController { def search(text: String, page: Int) = OpenBody { implicit ctx => NotForKids { - if (text.trim.isEmpty) paginator popularTeams page map { html.team.all(_) } - else Env.teamSearch(text, page) map { html.team.search(text, _) } + if (text.trim.isEmpty) paginator popularTeams page map { html.team.list.all(_) } + else Env.teamSearch(text, page) map { html.team.list.search(text, _) } } } @@ -68,7 +68,7 @@ object Team extends LilaController { def edit(id: String) = Auth { implicit ctx => me => OptionFuResult(api team id) { team => - Owner(team) { fuccess(html.team.edit(team, forms edit team)) } + Owner(team) { fuccess(html.team.form.edit(team, forms edit team)) } } } @@ -77,7 +77,7 @@ object Team extends LilaController { Owner(team) { implicit val req = ctx.body forms.edit(team).bindFromRequest.fold( - err => BadRequest(html.team.edit(team, err)).fuccess, + err => BadRequest(html.team.form.edit(team, err)).fuccess, data => api.update(team, data, me) inject Redirect(routes.Team.show(team.id)) ) } @@ -88,7 +88,7 @@ object Team extends LilaController { OptionFuResult(api team id) { team => Owner(team) { MemberRepo userIdsByTeam team.id map { userIds => - html.team.kick(team, userIds - me.id) + html.team.admin.kick(team, userIds - me.id) } } } @@ -98,7 +98,7 @@ object Team extends LilaController { OptionFuResult(api team id) { team => Owner(team) { implicit val req = ctx.body - forms.selectMember.bindFromRequest.value ?? { api.kick(team, _, me) } inject Redirect(routes.Team.show(team.id)) + forms.selectMember.bindFromRequest.value.pp ?? { api.kick(team, _, me) } inject Redirect(routes.Team.show(team.id)) } } } @@ -107,7 +107,7 @@ object Team extends LilaController { OptionFuResult(api team id) { team => Owner(team) { MemberRepo userIdsByTeam team.id map { userIds => - html.team.changeOwner(team, userIds - team.createdBy) + html.team.admin.changeOwner(team, userIds - team.createdBy) } } } @@ -134,7 +134,7 @@ object Team extends LilaController { NotForKids { OnePerWeek(me) { forms.anyCaptcha map { captcha => - Ok(html.team.form(forms.create, captcha)) + Ok(html.team.form.create(forms.create, captcha)) } } } @@ -145,7 +145,7 @@ object Team extends LilaController { implicit val req = ctx.body forms.create.bindFromRequest.fold( err => forms.anyCaptcha map { captcha => - BadRequest(html.team.form(err, captcha)) + BadRequest(html.team.form.create(err, captcha)) }, data => api.create(data, me) ?? { _ map { team => Redirect(routes.Team.show(team.id)): Result } @@ -155,7 +155,7 @@ object Team extends LilaController { } def mine = Auth { implicit ctx => me => - api mine me map { html.team.mine(_) } + api mine me map { html.team.list.mine(_) } } def join(id: String) = Auth { implicit ctx => implicit me => @@ -168,12 +168,12 @@ object Team extends LilaController { def requests = Auth { implicit ctx => me => Env.team.cached.nbRequests invalidate me.id - api requestsWithUsers me map { html.team.allRequests(_) } + api requestsWithUsers me map { html.team.request.all(_) } } def requestForm(id: String) = Auth { implicit ctx => me => OptionFuOk(api.requestable(id, me)) { team => - forms.anyCaptcha map { html.team.requestForm(team, forms.request, _) } + forms.anyCaptcha map { html.team.request.requestForm(team, forms.request, _) } } } @@ -182,7 +182,7 @@ object Team extends LilaController { implicit val req = ctx.body forms.request.bindFromRequest.fold( err => forms.anyCaptcha map { captcha => - BadRequest(html.team.requestForm(team, err, captcha)) + BadRequest(html.team.request.requestForm(team, err, captcha)) }, setup => api.createRequest(team, setup, me) inject Redirect(routes.Team.show(team.id)) ) diff --git a/app/controllers/Tournament.scala b/app/controllers/Tournament.scala index 353df2ca5a..6855a14735 100644 --- a/app/controllers/Tournament.scala +++ b/app/controllers/Tournament.scala @@ -19,7 +19,7 @@ object Tournament extends LilaController { private def env = Env.tournament private def repo = TournamentRepo - private def tournamentNotFound(implicit ctx: Context) = NotFound(html.tournament.notFound()) + private def tournamentNotFound(implicit ctx: Context) = NotFound(html.tournament.bits.notFound()) private[controllers] val upcomingCache = Env.memo.asyncCache.single[(VisibleTournaments, List[Tour])]( name = "tournament.home", @@ -64,7 +64,7 @@ object Tournament extends LilaController { case "arena" => System.Arena.some case _ => none } - Ok(html.tournament.faqPage(system)).fuccess + Ok(html.tournament.faq.page(system)).fuccess } def leaderboard = Open { implicit ctx => @@ -74,11 +74,14 @@ object Tournament extends LilaController { } yield Ok(html.tournament.leaderboard(winners)) } - private[controllers] def canHaveChat(tour: Tour)(implicit ctx: Context): Boolean = ctx.me ?? { u => - if (ctx.kid) false - else if (tour.isPrivate) true - else Env.chat.panic.allowed(u, tighter = tour.variant == chess.variant.Antichess) - } + private[controllers] def canHaveChat(tour: Tour, json: Option[JsObject])(implicit ctx: Context): Boolean = + !ctx.kid && // no public chats for kids + ctx.me.fold(!tour.isPrivate) { u => // anon can see public chats, except for private tournaments + (!tour.isPrivate || json.fold(true)(jsonHasMe)) && // private tournament that I joined + Env.chat.panic.allowed(u, tighter = tour.variant == chess.variant.Antichess) + } + + private def jsonHasMe(js: JsObject): Boolean = (js \ "me").toOption.isDefined def show(id: String) = Open { implicit ctx => val page = getInt("page") @@ -88,8 +91,8 @@ object Tournament extends LilaController { (for { verdicts <- env.api.verdicts(tour, ctx.me, getUserTeamIds) version <- env.version(tour.id) - chat <- canHaveChat(tour) ?? Env.chat.api.userChat.cached.findMine(Chat.Id(tour.id), ctx.me).map(some) json <- env.jsonView(tour, page, ctx.me, getUserTeamIds, none, version.some, partial = false, ctx.lang) + chat <- canHaveChat(tour, json.some) ?? Env.chat.api.userChat.cached.findMine(Chat.Id(tour.id), ctx.me).map(some) _ <- chat ?? { c => Env.user.lightUserApi.preloadMany(c.chat.userIds) } streamers <- streamerCache get tour.id shieldOwner <- env.shieldApi currentOwner tour @@ -284,11 +287,19 @@ object Tournament extends LilaController { def shields = Open { implicit ctx => for { - history <- env.shieldApi.history + history <- env.shieldApi.history(5.some) _ <- Env.user.lightUserApi preloadMany history.userIds } yield html.tournament.shields(history) } + def categShields(k: String) = Open { implicit ctx => + OptionFuOk(env.shieldApi.byCategKey(k)) { + case (categ, awards) => + Env.user.lightUserApi preloadMany awards.map(_.owner.value) inject + html.tournament.shields.byCateg(categ, awards) + } + } + def calendar = Open { implicit ctx => env.api.calendar map { tours => Ok(html.tournament.calendar(env.scheduleJsonView calendar tours)) diff --git a/app/controllers/Tv.scala b/app/controllers/Tv.scala index 31bfe5d1ff..b80b28b49a 100644 --- a/app/controllers/Tv.scala +++ b/app/controllers/Tv.scala @@ -15,16 +15,11 @@ object Tv extends LilaController { (lila.tv.Tv.Channel.byKey get chanKey).fold(notFound)(lichessTv) } - def sides(chanKey: String, gameId: String, color: String) = Open { implicit ctx => - lila.tv.Tv.Channel.byKey get chanKey match { - case None => notFound - case Some(channel) => - OptionFuResult(GameRepo.pov(gameId, color)) { pov => - Env.tv.tv.getChampions zip - Env.game.crosstableApi.withMatchup(pov.game) map { - case (champions, crosstable) => Ok(html.tv.side.sides(channel, champions, pov, crosstable)) - } - } + def sides(gameId: String, color: String) = Open { implicit ctx => + OptionFuResult(GameRepo.pov(gameId, color)) { pov => + Env.game.crosstableApi.withMatchup(pov.game) map { ct => + Ok(html.tv.side.sides(pov, ct)) + } } } @@ -62,7 +57,7 @@ object Tv extends LilaController { def gamesChannel(chanKey: String) = Open { implicit ctx => (lila.tv.Tv.Channel.byKey get chanKey) ?? { channel => - Env.tv.tv.getChampions zip Env.tv.tv.getGames(channel, 9) map { + Env.tv.tv.getChampions zip Env.tv.tv.getGames(channel, 12) map { case (champs, games) => NoCache { Ok(html.tv.games(channel, games map lila.game.Pov.first, champs)) } @@ -81,23 +76,19 @@ object Tv extends LilaController { } } + /* for BC */ def embed = Action { req => Ok { - val bg = get("bg", req) | "light" - val theme = get("theme", req) | "brown" - val url = s"""${req.domain + routes.Tv.frame}?bg=$bg&theme=$theme""" - s"""document.write("");""" + val config = ui.EmbedConfig(req) + val url = s"""${req.domain + routes.Tv.frame}?bg=${config.bg}&theme=${config.board}""" + s"""document.write("");""" } as JAVASCRIPT withHeaders (CACHE_CONTROL -> "max-age=86400") } def frame = Action.async { implicit req => Env.tv.tv.getBestGame map { case None => NotFound - case Some(game) => Ok(views.html.tv.embed( - Pov first game, - get("bg", req) | "light", - lila.pref.Theme(~get("theme", req)).cssClass - )) + case Some(game) => Ok(views.html.tv.embed(Pov first game)) } } } diff --git a/app/controllers/User.scala b/app/controllers/User.scala index c39d678a56..033e9252e0 100644 --- a/app/controllers/User.scala +++ b/app/controllers/User.scala @@ -4,7 +4,6 @@ import play.api.data.Form import play.api.libs.iteratee._ import play.api.libs.json._ import play.api.mvc._ -import play.twirl.api.Html import scala.concurrent.duration._ import lila.api.{ Context, BodyContext } @@ -68,7 +67,7 @@ object User extends LilaController { nbs ← Env.current.userNbGames(u, ctx) info ← Env.current.userInfo(u, nbs, ctx) social ← Env.current.socialInfo(u, ctx) - } yield status(html.user.show.activity(u, as, info, social)) + } yield status(html.user.show.page.activity(u, as, info, social)) }.mon(_.http.response.user.show.website) else Env.activity.read.recent(u) map { as => status(html.activity(u, as)) @@ -98,7 +97,7 @@ object User extends LilaController { _ <- Env.team.cached.nameCache preloadMany info.teamIds social ← Env.current.socialInfo(u, ctx) searchForm = (filters.current == GameFilter.Search) option GameFilterMenu.searchForm(userGameSearch, filters.current)(ctx.body) - } yield html.user.show.games(u, info, pag, filters, searchForm, social) + } yield html.user.show.page.games(u, info, pag, filters, searchForm, social) else fuccess(html.user.show.gamesContent(u, nbs, pag, filters, filter)) } yield res, api = _ => apiGames(u, filter, page) @@ -108,12 +107,14 @@ object User extends LilaController { } private def EnabledUser(username: String)(f: UserModel => Fu[Result])(implicit ctx: Context): Fu[Result] = - OptionFuResult(UserRepo named username) { u => - if (u.enabled || isGranted(_.UserSpy)) f(u) - else negotiate( + UserRepo named username flatMap { + case None if isGranted(_.UserSpy) => Mod.searchTerm(username.trim) + case None => notFound + case Some(u) if (u.enabled || isGranted(_.UserSpy)) => f(u) + case Some(u) => negotiate( html = UserRepo isErased u flatMap { erased => if (erased.value) notFound - else NotFound(html.user.disabled(u)).fuccess + else NotFound(html.user.show.page.disabled(u)).fuccess }, api = _ => fuccess(NotFound(jsonError("No such user, or account closed"))) ) @@ -145,12 +146,12 @@ object User extends LilaController { } } - def online = Open { implicit req => + def online = Action.async { implicit req => val max = 50 negotiate( - html = notFound, + html = notFoundJson(), api = _ => env.cached.getTop50Online map { list => - Ok(Json.toJson(list.take(getInt("nb").fold(10)(_ min max)).map(env.jsonView(_)))) + Ok(Json.toJson(list.take(getInt("nb", req).fold(10)(_ min max)).map(env.jsonView(_)))) } ) } @@ -291,7 +292,7 @@ object User extends LilaController { } val irwin = Env.irwin.api.reports.withPovs(user) map { _ ?? { reps => - html.irwin.irwinReport(reps).some + html.irwin.report(reps).some } } val assess = Env.mod.assessApi.getPlayerAggregateAssessmentWithGames(user.id) flatMap { @@ -300,7 +301,7 @@ object User extends LilaController { } } import play.api.libs.EventSource - implicit val extractor = EventSource.EventDataExtractor[Html](_.toString) + implicit val extractor = EventSource.EventDataExtractor[scalatags.Text.Frag](_.render) Ok.chunked { (Enumerator(html.user.mod.menu(user)) interleave futureToEnumerator(parts.logTimeIfGt(s"$username parts", 2 seconds)) interleave diff --git a/app/controllers/UserTournament.scala b/app/controllers/UserTournament.scala index 91a429def9..702887619b 100644 --- a/app/controllers/UserTournament.scala +++ b/app/controllers/UserTournament.scala @@ -12,11 +12,11 @@ object UserTournament extends LilaController { path match { case "recent" => Env.tournament.leaderboardApi.recentByUser(user, page).map { entries => - Ok(html.userTournament.recent(user, entries)) + Ok(html.userTournament.bits.recent(user, entries)) } case "best" => Env.tournament.leaderboardApi.bestByUser(user, page).map { entries => - Ok(html.userTournament.best(user, entries)) + Ok(html.userTournament.bits.best(user, entries)) } case "chart" => Env.tournament.leaderboardApi.chart(user).map { data => Ok(html.userTournament.chart(user, data)) diff --git a/app/controllers/Video.scala b/app/controllers/Video.scala index 9e1f3c3d21..beb9bf672e 100644 --- a/app/controllers/Video.scala +++ b/app/controllers/Video.scala @@ -41,7 +41,7 @@ object Video extends LilaController { def show(id: String) = Open { implicit ctx => WithUserControl { control => env.api.video.find(id) flatMap { - case None => fuccess(NotFound(html.video.notFound(control))) + case None => fuccess(NotFound(html.video.bits.notFound(control))) case Some(video) => env.api.video.similar(ctx.me, video, 9) zip ctx.userId.?? { userId => env.api.view.add(View.make(videoId = video.id, userId = userId)) @@ -56,7 +56,7 @@ object Video extends LilaController { def author(author: String) = Open { implicit ctx => WithUserControl { control => env.api.video.byAuthor(ctx.me, author, getInt("page") | 1) map { videos => - Ok(html.video.author(author, videos, control)) + Ok(html.video.bits.author(author, videos, control)) } } } @@ -64,7 +64,7 @@ object Video extends LilaController { def tags = Open { implicit ctx => WithUserControl { control => env.api.tag.allPopular map { tags => - Ok(html.video.tags(tags, control)) + Ok(html.video.bits.tags(tags, control)) } } } diff --git a/app/mashup/Preload.scala b/app/mashup/Preload.scala index 07e5984ef7..55525330f9 100644 --- a/app/mashup/Preload.scala +++ b/app/mashup/Preload.scala @@ -28,7 +28,7 @@ final class Preload( lightUserApi: LightUserApi ) { - private type Response = (JsObject, Vector[Entry], List[MiniForumPost], List[Tournament], List[Event], List[Simul], Option[Game], List[User.LightPerf], List[Winner], Option[lila.puzzle.DailyPuzzle], LiveStreams.WithTitles, List[lila.blog.MiniPost], Option[TempBan], Option[Preload.CurrentGame], Int) + private type Response = (JsObject, Vector[Entry], List[MiniForumPost], List[Tournament], List[Event], List[Simul], Option[Game], List[User.LightPerf], List[Winner], Option[lila.puzzle.DailyPuzzle], LiveStreams.WithTitles, List[lila.blog.MiniPost], Option[TempBan], Option[Preload.CurrentGame], Int, List[Pov]) def apply( posts: Fu[List[MiniForumPost]], @@ -46,16 +46,17 @@ final class Preload( leaderboard(()) zip tourneyWinners zip (ctx.noBot ?? dailyPuzzle()) zip - liveStreams().dmap(_.autoFeatured.withTitles(lightUserApi)) zip - (ctx.userId ?? getPlayban) flatMap { - case (data, povs) ~ posts ~ tours ~ events ~ simuls ~ feat ~ entries ~ lead ~ tWinners ~ puzzle ~ streams ~ playban => + liveStreams().dmap(_.autoFeatured withTitles lightUserApi) zip + (ctx.userId ?? getPlayban) zip + (ctx.blind ?? ctx.me ?? GameRepo.urgentGames) flatMap { + case (data, povs) ~ posts ~ tours ~ events ~ simuls ~ feat ~ entries ~ lead ~ tWinners ~ puzzle ~ streams ~ playban ~ blindGames => val currentGame = ctx.me ?? Preload.currentGameMyTurn(povs, lightUserApi.sync) _ lightUserApi.preloadMany { tWinners.map(_.userId) ::: posts.flatMap(_.userId) ::: entries.flatMap(_.userIds).toList } inject - (data, entries, posts, tours, events, simuls, feat, lead, tWinners, puzzle, streams, Env.blog.lastPostCache.apply, playban, currentGame, countRounds()) + (data, entries, posts, tours, events, simuls, feat, lead, tWinners, puzzle, streams, Env.blog.lastPostCache.apply, playban, currentGame, countRounds(), blindGames) } } diff --git a/app/package.scala b/app/package.scala index a38045b553..a331405a4c 100644 --- a/app/package.scala +++ b/app/package.scala @@ -1,3 +1,14 @@ package lila -package object app extends PackageObject with socket.WithSocket +import play.api.http._ +import play.api.mvc.Codec +import scalatags.Text.Frag + +package object app extends PackageObject with socket.WithSocket { + + implicit def contentTypeOfFrag(implicit codec: Codec): ContentTypeOf[Frag] = + ContentTypeOf[Frag](Some(ContentTypes.HTML)) + + implicit def writeableOfFrag(implicit codec: Codec): Writeable[Frag] = + Writeable(frag => codec.encode(frag.render)) +} diff --git a/app/templating/AiHelper.scala b/app/templating/AiHelper.scala index ac3eac616e..b678436090 100644 --- a/app/templating/AiHelper.scala +++ b/app/templating/AiHelper.scala @@ -1,8 +1,7 @@ package lila.app package templating -import play.twirl.api.Html - +import lila.app.ui.ScalatagsTemplate._ import lila.user.UserContext trait AiHelper { self: I18nHelper => @@ -15,8 +14,8 @@ trait AiHelper { self: I18nHelper => s"$name$rating" } - def aiNameHtml(level: Int, withRating: Boolean = true)(implicit ctx: UserContext) = - Html(aiName(level, withRating).replace(" ", " ")) + def aiNameFrag(level: Int, withRating: Boolean = true)(implicit ctx: UserContext) = + raw(aiName(level, withRating).replace(" ", " ")) def aiRating(level: Int): Option[Int] = Env.fishnet.aiPerfApi.intRatings get level } diff --git a/app/templating/AssetHelper.scala b/app/templating/AssetHelper.scala index 671361bb68..2680c42b8f 100644 --- a/app/templating/AssetHelper.scala +++ b/app/templating/AssetHelper.scala @@ -3,18 +3,21 @@ package templating import controllers.routes import play.api.mvc.RequestHeader -import play.twirl.api.Html import lila.api.Context -import lila.common.{ AssetVersion, ContentSecurityPolicy } +import lila.app.ui.ScalatagsTemplate._ +import lila.common.{ Nonce, AssetVersion, ContentSecurityPolicy } trait AssetHelper { self: I18nHelper with SecurityHelper => def isProd: Boolean + val siteDomain = lila.api.Env.current.Net.Domain val assetDomain = lila.api.Env.current.Net.AssetDomain val socketDomain = lila.api.Env.current.Net.SocketDomain + val sameAssetDomain = siteDomain == assetDomain + val assetBaseUrl = s"//$assetDomain" def assetVersion = AssetVersion.current @@ -26,75 +29,72 @@ trait AssetHelper { self: I18nHelper with SecurityHelper => def dbImageUrl(path: String) = s"$assetBaseUrl/image/$path" - def cssTag(name: String): Html = cssAt("stylesheets/" + name) + def cssTag(name: String)(implicit ctx: Context): Frag = + cssTagWithTheme(name, ctx.currentBg) - def cssTags(names: String*): Html = Html { - names.map { name => - cssTag(name).body - } mkString "" - } - def cssTags(names: List[(String, Boolean)]): Html = - cssTags(names.collect { case (k, true) => k }: _*) + def cssTagWithTheme(name: String, theme: String): Frag = + cssAt(s"css/$name.$theme.${if (isProd) "min" else "dev"}.css") - def cssVendorTag(name: String) = cssAt("vendor/" + name) + def cssTagNoTheme(name: String)(implicit ctx: Context): Frag = + cssAt(s"css/$name.${if (isProd) "min" else "dev"}.css") - def cssAt(path: String): Html = Html { - s"""""" - } + private def cssAt(path: String): Frag = + link(href := assetUrl(path), tpe := "text/css", rel := "stylesheet") - def jsTag(name: String, async: Boolean = false) = - jsAt("javascripts/" + name, async = async) + def jsTag(name: String, defer: Boolean = false): Frag = + jsAt("javascripts/" + name, defer = defer) - def jsAt(path: String, async: Boolean = false): Html = Html { - val src = assetUrl(path) - s"""""" - } + /* about async & defer, see https://flaviocopes.com/javascript-async-defer/ + * we want defer only, to ensure scripts are executed in order of declaration, + * so that round.js doesn't run before site.js */ + def jsAt(path: String, defer: Boolean = false): Frag = script( + defer option deferAttr, + src := assetUrl(path) + ) - val jQueryTag = Html { + val jQueryTag = raw { s"""""" } - def roundTag = jsAt(s"compiled/lichess.round${isProd ?? (".min")}.js", async = true) + def roundTag = jsAt(s"compiled/lichess.round${isProd ?? (".min")}.js", defer = true) def roundNvuiTag(implicit ctx: Context) = ctx.blind option - jsAt(s"compiled/lichess.round.nvui.min.js", async = true) + jsAt(s"compiled/lichess.round.nvui.min.js", defer = true) def analyseTag = jsAt(s"compiled/lichess.analyse${isProd ?? (".min")}.js") def analyseNvuiTag(implicit ctx: Context) = ctx.blind option jsAt(s"compiled/lichess.analyse.nvui.min.js") - val highchartsLatestTag = Html { + def captchaTag = jsAt(s"compiled/captcha.js") + + val highchartsLatestTag = raw { s"""""" } - val highchartsMoreTag = Html { + val highchartsMoreTag = raw { s"""""" } - val typeaheadTag = Html { - s"""""" + val fingerprintTag = raw { + s"""""" } - val fingerprintTag = Html { - s"""""" - } - - val flatpickrTag = Html { - s"""""" - } - - val nonAsyncFlatpickrTag = Html { + val flatpickrTag = raw { s"""""" } - def delayFlatpickrStart(implicit ctx: Context) = embedJs { + val nonAsyncFlatpickrTag = raw { + s"""""" + } + + def delayFlatpickrStart(implicit ctx: Context) = embedJsUnsafe { """$(function() { setTimeout(function() { $(".flatpickr").flatpickr(); }, 2000) });""" } val infiniteScrollTag = jsTag("vendor/jquery.infinitescroll.min.js") - def prismicJs(implicit ctx: Context) = Html { + def prismicJs(implicit ctx: Context): Frag = raw { isGranted(_.Prismic) ?? { - embedJsUnsafe("""window.prismic={endpoint:'https://lichess.prismic.io/api/v2'}""").body ++ + embedJsUnsafe("""window.prismic={endpoint:'https://lichess.prismic.io/api/v2'}""").render ++ """""" } } @@ -105,7 +105,7 @@ trait AssetHelper { self: I18nHelper with SecurityHelper => ContentSecurityPolicy( defaultSrc = List("'self'", assets), connectSrc = List("'self'", assets, socket, lila.api.Env.current.ExplorerEndpoint, lila.api.Env.current.TablebaseEndpoint), - styleSrc = List("'self'", "'unsafe-inline'", assets, "https://fonts.googleapis.com"), + styleSrc = List("'self'", "'unsafe-inline'", assets), fontSrc = List("'self'", assetDomain, "https://fonts.gstatic.com"), frameSrc = List("'self'", assets, "https://www.youtube.com"), workerSrc = List("'self'", assets), @@ -120,15 +120,12 @@ trait AssetHelper { self: I18nHelper with SecurityHelper => ctx.nonce.fold(csp)(csp.withNonce(_)) } - def embedJsUnsafe(js: String)(implicit ctx: Context): Html = Html { - val nonce = ctx.nonce ?? { nonce => s""" nonce="$nonce"""" } - s"""$js""" - } - def embedJsUnsafe(js: scalatags.Text.RawFrag)(implicit ctx: Context): scalatags.Text.RawFrag = scalatags.Text.all.raw { + def embedJsUnsafe(js: String)(implicit ctx: Context): Frag = raw { val nonce = ctx.nonce ?? { nonce => s""" nonce="$nonce"""" } s"""$js""" } - def embedJs(js: Html)(implicit ctx: Context): Html = embedJsUnsafe(js.body) - def embedJs(js: String)(implicit ctx: Context): Html = embedJsUnsafe(js) + def embedJsUnsafe(js: String, nonce: Nonce): Frag = raw { + s"""""" + } } diff --git a/app/templating/ChessgroundHelper.scala b/app/templating/ChessgroundHelper.scala index 8f039b31d9..e09e1c76f9 100644 --- a/app/templating/ChessgroundHelper.scala +++ b/app/templating/ChessgroundHelper.scala @@ -3,32 +3,34 @@ package templating import chess.{ Color, Board, Pos } import lila.api.Context -import play.twirl.api.Html +import lila.app.ui.ScalatagsTemplate._ import lila.game.Pov trait ChessgroundHelper { - def chessground(board: Board, orient: Color, lastMove: List[Pos] = Nil)(implicit ctx: Context): Html = wrap { - if (ctx.pref.is3d) "" - else { - def top(p: Pos) = orient.fold(8 - p.y, p.y - 1) * 12.5 - def left(p: Pos) = orient.fold(p.x - 1, 8 - p.x) * 12.5 - val highlights = ctx.pref.highlight ?? lastMove.distinct.map { pos => - s"""""" - } mkString "" - val pieces = - if (ctx.pref.isBlindfold) "" - else board.pieces.map { - case (pos, piece) => - val klass = s"${piece.color.name} ${piece.role.name}" - s"""""" + def chessground(board: Board, orient: Color, lastMove: List[Pos] = Nil)(implicit ctx: Context): Frag = wrap { + raw { + if (ctx.pref.is3d) "" + else { + def top(p: Pos) = orient.fold(8 - p.y, p.y - 1) * 12.5 + def left(p: Pos) = orient.fold(p.x - 1, 8 - p.x) * 12.5 + val highlights = ctx.pref.highlight ?? lastMove.distinct.map { pos => + s"""""" } mkString "" - s"$highlights$pieces" + val pieces = + if (ctx.pref.isBlindfold) "" + else board.pieces.map { + case (pos, piece) => + val klass = s"${piece.color.name} ${piece.role.name}" + s"""""" + } mkString "" + s"$highlights$pieces" + } } } - def chessground(pov: Pov)(implicit ctx: Context): Html = chessground( + def chessground(pov: Pov)(implicit ctx: Context): Frag = chessground( board = pov.game.board, orient = pov.color, lastMove = pov.game.history.lastMove.map(_.origDest) ?? { @@ -36,9 +38,11 @@ trait ChessgroundHelper { } ) - private def wrap(content: String) = Html { - s"""
$content
""" - } + private def wrap(content: Frag): Frag = div(cls := "cg-board-wrap")( + div(cls := "cg-board")(content) + ) lazy val miniBoardContent = wrap("") + + lazy val chessgroundSvg = wrap(raw("")) } diff --git a/app/templating/DateHelper.scala b/app/templating/DateHelper.scala index 349b686dff..fb6e919af7 100644 --- a/app/templating/DateHelper.scala +++ b/app/templating/DateHelper.scala @@ -7,9 +7,9 @@ import scala.collection.mutable.AnyRefMap import org.joda.time.format._ import org.joda.time.format.ISODateTimeFormat import org.joda.time.{ Period, PeriodType, DurationFieldType, DateTime, DateTimeZone } -import play.twirl.api.Html import lila.api.Context +import lila.app.ui.ScalatagsTemplate._ trait DateHelper { self: I18nHelper => @@ -61,9 +61,8 @@ trait DateHelper { self: I18nHelper => def showEnglishDate(date: DateTime): String = englishDateFormatter print date - def semanticDate(date: DateTime)(implicit ctx: Context) = Html { - s"""""" - } + def semanticDate(date: DateTime)(implicit ctx: Context): Frag = + timeTag(datetimeAttr := isoDate(date))(showDate(date)) def showPeriod(period: Period)(implicit ctx: Context): String = periodFormatter(ctx) print period.normalizedStandard(periodType) @@ -74,13 +73,15 @@ trait DateHelper { self: I18nHelper => def isoDate(date: DateTime): String = isoFormatter print date private val oneDayMillis = 1000 * 60 * 60 * 24 - def momentFromNow(date: DateTime, alwaysRelative: Boolean = false, once: Boolean = false) = Html { + + def momentFromNow(date: DateTime, alwaysRelative: Boolean = false, once: Boolean = false): Frag = { if (!alwaysRelative && (date.getMillis - nowMillis) > oneDayMillis) absClientDateTime(date) - s"""""" - } - def absClientDateTime(date: DateTime) = Html { - s"""""" + else timeTag(cls := s"timeago${once ?? " once"}", datetimeAttr := isoDate(date)) } + + def absClientDateTime(date: DateTime): Frag = + timeTag(cls := "timeago abs", datetimeAttr := isoDate(date))("-") + def momentFromNowOnce(date: DateTime) = momentFromNow(date, once = true) def secondsFromNow(seconds: Int, alwaysRelative: Boolean = false)(implicit ctx: Context) = diff --git a/app/templating/Environment.scala b/app/templating/Environment.scala index 95d4811ca4..7533fc77d8 100644 --- a/app/templating/Environment.scala +++ b/app/templating/Environment.scala @@ -3,17 +3,13 @@ package templating import scala.concurrent.duration._ -import play.twirl.api.Html - import lila.api.Env.{ current => apiEnv } +import lila.app.ui.ScalatagsTemplate._ object Environment extends lila.Lilaisms with StringHelper - with HtmlHelper - with JsonHelper with AssetHelper - with RequestHelper with DateHelper with NumberHelper with PaginatorHelper @@ -27,9 +23,7 @@ object Environment with SecurityHelper with TeamHelper with TournamentHelper - with SimulHelper - with ChessgroundHelper - with ui.ScalatagsTwirl { + with ChessgroundHelper { type FormWithCaptcha = (play.api.data.Form[_], lila.common.Captcha) @@ -48,7 +42,7 @@ object Environment def contactEmail = apiEnv.Net.Email - def contactEmailLink = Html(s"""$contactEmail""") + def contactEmailLink = a(href := s"mailto:$contactEmail")(contactEmail) def cspEnabled = apiEnv.cspEnabledSetting.get _ @@ -58,5 +52,7 @@ object Environment def reportNbOpen: Int = lila.report.Env.current.api.nbOpen.awaitOrElse(10.millis, 0) - def NotForKids(f: => Html)(implicit ctx: lila.api.Context) = if (ctx.kid) emptyHtml else f + def NotForKids(f: => Frag)(implicit ctx: lila.api.Context) = if (ctx.kid) emptyFrag else f + + val spinner: Frag = raw("""
""") } diff --git a/app/templating/FormHelper.scala b/app/templating/FormHelper.scala index 71dd0c6c4d..5238ceed69 100644 --- a/app/templating/FormHelper.scala +++ b/app/templating/FormHelper.scala @@ -2,33 +2,29 @@ package lila.app package templating import play.api.data._ -import play.twirl.api.Html import lila.api.Context +import lila.app.ui.ScalatagsTemplate._ import lila.i18n.I18nDb trait FormHelper { self: I18nHelper => - def errMsg(form: Field)(implicit ctx: Context): Html = errMsg(form.errors) + def errMsg(form: Field)(implicit ctx: Context): Frag = errMsg(form.errors) - def errMsg(form: Form[_])(implicit ctx: Context): Html = errMsg(form.errors) + def errMsg(form: Form[_])(implicit ctx: Context): Frag = errMsg(form.errors) - def errMsg(error: FormError)(implicit ctx: Context): Html = Html { - s"""

${transKey(error.message, I18nDb.Site, error.args)}

""" - } + def errMsg(error: FormError)(implicit ctx: Context): Frag = + p(cls := "error")(transKey(error.message, I18nDb.Site, error.args)) - def errMsg(errors: Seq[FormError])(implicit ctx: Context): Html = Html { + def errMsg(errors: Seq[FormError])(implicit ctx: Context): Frag = errors map errMsg mkString - } - def globalError(form: Form[_])(implicit ctx: Context): Option[Html] = + def globalError(form: Form[_])(implicit ctx: Context): Option[Frag] = form.globalError map errMsg val booleanChoices = Seq("true" -> "✓ Yes", "false" -> "✗ No") - object form3 extends ui.ScalatagsPlay { - - import ui.ScalatagsTemplate._ + object form3 { private val idPrefix = "form3" @@ -47,20 +43,14 @@ trait FormHelper { self: I18nHelper => * such as `optional(nonEmptyText)`. * And we can't tell from the Field whether it's optional or not :( */ - // case ("constraint.required", _) => required := true + // case ("constraint.required", _) => required case ("constraint.minLength", Seq(m: Int)) => minlength := m case ("constraint.maxLength", Seq(m: Int)) => maxlength := m case ("constraint.min", Seq(m: Int)) => min := m case ("constraint.max", Seq(m: Int)) => max := m } - /* All public methods must return HTML - * because twirl just calls toString on scalatags frags - * and that escapes the content :( */ - - def split(html: Html): Html = div(cls := "form-split")(html) - - def split(frags: Frag*): Html = div(cls := "form-split")(frags) + val split = div(cls := "form-split") def group( field: Field, @@ -68,94 +58,84 @@ trait FormHelper { self: I18nHelper => klass: String = "", half: Boolean = false, help: Option[Frag] = None - )(content: Field => Frag)(implicit ctx: Context): Html = - div(cls := List( - "form-group" -> true, - "is-invalid" -> field.hasErrors, - "form-half" -> half, - klass -> klass.nonEmpty - ))( - groupLabel(field)(labelContent), - content(field), - errors(field), - help map { helper(_) } - ) + )(content: Field => Frag)(implicit ctx: Context): Frag = div(cls := List( + "form-group" -> true, + "is-invalid" -> field.hasErrors, + "form-half" -> half, + klass -> klass.nonEmpty + ))( + groupLabel(field)(labelContent), + content(field), + errors(field), + help map { helper(_) } + ) def input(field: Field, typ: String = "", klass: String = ""): BaseTagType = st.input( st.id := id(field), name := field.name, value := field.value, - `type` := typ.nonEmpty.option(typ), + tpe := typ.nonEmpty.option(typ), cls := List("form-control" -> true, klass -> klass.nonEmpty) )(validationModifiers(field)) - def inputHtml(field: Field, typ: String = "", klass: String = "")(modifiers: Modifier*): Html = - input(field, typ, klass)(modifiers) - def checkbox( field: Field, labelContent: Frag, half: Boolean = false, help: Option[Frag] = None, disabled: Boolean = false - ): Html = - div(cls := List( - "form-check form-group" -> true, - "form-half" -> half - ))( - div( - span(cls := "form-check-input")( - st.input( - st.id := id(field), - name := field.name, - value := "true", - `type` := "checkbox", - cls := "form-control cmn-toggle", - checked := field.value.has("true").option(true), - st.disabled := disabled.option(true) - ), - label(`for` := id(field)) + ): Frag = div(cls := List( + "form-check form-group" -> true, + "form-half" -> half + ))( + div( + span(cls := "form-check-input")( + st.input( + st.id := id(field), + name := field.name, + value := "true", + tpe := "checkbox", + cls := "form-control cmn-toggle", + field.value.has("true") option checked, + disabled option st.disabled ), - groupLabel(field)(labelContent) + label(`for` := id(field)) ), - help map { helper(_) } - ) + groupLabel(field)(labelContent) + ), + help map { helper(_) } + ) def select( field: Field, options: Iterable[(Any, String)], default: Option[String] = None - ): Html = - st.select( - st.id := id(field), - name := field.name, - cls := "form-control" - )(validationModifiers(field))( - default map { option(value := "")(_) }, - options.toSeq map { - case (value, name) => option( - st.value := value.toString, - selected := field.value.has(value.toString).option(true) - )(name) - } - ) + ): Frag = st.select( + st.id := id(field), + name := field.name, + cls := "form-control" + )(validationModifiers(field))( + default map { option(value := "")(_) }, + options.toSeq map { + case (value, name) => option( + st.value := value.toString, + field.value.has(value.toString) option selected + )(name) + } + ) def textarea( field: Field, klass: String = "" - )(modifiers: Modifier*): Html = - st.textarea( - st.id := id(field), - name := field.name, - cls := List("form-control" -> true, klass -> klass.nonEmpty) - )(validationModifiers(field))(modifiers)(~field.value) + )(modifiers: Modifier*): Frag = st.textarea( + st.id := id(field), + name := field.name, + cls := List("form-control" -> true, klass -> klass.nonEmpty) + )(validationModifiers(field))(modifiers)(~field.value) val actions = div(cls := "form-actions") - def actionsHtml(html: Frag): Html = actions(html) - val action = div(cls := "form-actions single") - def actionHtml(html: Frag): Html = div(cls := "form-actions single")(html) def submit( content: Frag, @@ -163,8 +143,8 @@ trait FormHelper { self: I18nHelper => nameValue: Option[(String, String)] = None, klass: String = "", confirm: Option[String] = None - ): Html = button( - `type` := "submit", + ): Frag = button( + tpe := "submit", dataIcon := icon, name := nameValue.map(_._1), value := nameValue.map(_._2), @@ -177,34 +157,33 @@ trait FormHelper { self: I18nHelper => title := confirm )(content) - def hidden(field: Field, value: Option[String] = None): Html = - st.input( - st.id := id(field), - name := field.name, - st.value := value.orElse(field.value), - `type` := "hidden" - ) + def hidden(field: Field, value: Option[String] = None): Frag = st.input( + st.id := id(field), + name := field.name, + st.value := value.orElse(field.value), + tpe := "hidden" + ) - def password(field: Field, content: Html)(implicit ctx: Context): Frag = - group(field, content)(input(_, typ = "password")(required := true)) + def password(field: Field, content: Frag)(implicit ctx: Context): Frag = + group(field, content)(input(_, typ = "password")(required)) - def passwordNoAutocomplete(field: Field, content: Html)(implicit ctx: Context): Frag = - group(field, content)(input(_, typ = "password")(autocomplete := "off")(required := true)) + def passwordModified(field: Field, content: Frag)(modifiers: Modifier*)(implicit ctx: Context): Frag = + group(field, content)(input(_, typ = "password")(required)(modifiers)) - def globalError(form: Form[_])(implicit ctx: Context): Option[Html] = + def globalError(form: Form[_])(implicit ctx: Context): Option[Frag] = form.globalError map { err => div(cls := "form-group is-invalid")(error(err)) } - def flatpickr(field: Field, withTime: Boolean = true): Html = + def flatpickr(field: Field, withTime: Boolean = true): Frag = input(field, klass = "flatpickr")( dataEnableTime := withTime, datatime24h := withTime ) object file { - def image(name: String): Html = st.input(`type` := "file", st.name := name, accept := "image/*") - def pgn(name: String): Html = st.input(`type` := "file", st.name := name, accept := ".pgn") + def image(name: String): Frag = st.input(tpe := "file", st.name := name, accept := "image/*") + def pgn(name: String): Frag = st.input(tpe := "file", st.name := name, accept := ".pgn") } } } diff --git a/app/templating/ForumHelper.scala b/app/templating/ForumHelper.scala index ef7fa3fed3..2a587aa208 100644 --- a/app/templating/ForumHelper.scala +++ b/app/templating/ForumHelper.scala @@ -1,9 +1,8 @@ package lila.app package templating -import play.twirl.api.Html - import lila.api.Context +import lila.app.ui.ScalatagsTemplate._ import lila.forum.Post trait ForumHelper { self: UserHelper with StringHelper => @@ -22,7 +21,7 @@ trait ForumHelper { self: UserHelper with StringHelper => def authorName(post: Post) = post.userId match { case Some(userId) => userIdSpanMini(userId, withOnline = true) - case None => Html(lila.user.User.anonymous) + case None => frag(lila.user.User.anonymous) } def authorLink( @@ -30,9 +29,9 @@ trait ForumHelper { self: UserHelper with StringHelper => cssClass: Option[String] = None, withOnline: Boolean = true, modIcon: Boolean = false - ) = - if (post.erased) Html(s"""${lila.common.String.erasedHtml}""") - else post.userId.fold(Html(lila.user.User.anonymous)) { userId => + ): Frag = + if (post.erased) span(cls := "author")("") + else post.userId.fold(frag(lila.user.User.anonymous)) { userId => userIdLink(userId.some, cssClass = cssClass, withOnline = withOnline, modIcon = modIcon) } } diff --git a/app/templating/GameHelper.scala b/app/templating/GameHelper.scala index 56e82b1933..1987537c34 100644 --- a/app/templating/GameHelper.scala +++ b/app/templating/GameHelper.scala @@ -4,15 +4,18 @@ package templating import chess.format.Forsyth import chess.{ Status => S, Color, Clock, Mode } import controllers.routes -import play.twirl.api.Html -import scalatags.Text.Frag -import lila.common.String.html.escapeHtml +import lila.app.ui.ScalatagsTemplate._ import lila.game.{ Game, Player, Namer, Pov } -import lila.i18n.{ I18nKeys, enLang } -import lila.user.{ User, UserContext } +import lila.i18n.{ I18nKeys => trans, enLang } +import lila.user.{ User, UserContext, Title } -trait GameHelper { self: I18nHelper with UserHelper with AiHelper with StringHelper with HtmlHelper with ChessgroundHelper => +trait GameHelper { self: I18nHelper with UserHelper with AiHelper with StringHelper with ChessgroundHelper => + + private val dataLive = attr("data-live") + private val dataColor = attr("data-color") + private val dataFen = attr("data-fen") + private val dataLastmove = attr("data-lastmove") def netBaseUrl: String def cdnUrl(path: String): String @@ -67,34 +70,49 @@ trait GameHelper { self: I18nHelper with UserHelper with AiHelper with StringHel } def variantName(variant: chess.variant.Variant)(implicit ctx: UserContext) = variant match { - case chess.variant.Standard => I18nKeys.standard.txt() - case chess.variant.FromPosition => I18nKeys.fromPosition.txt() + case chess.variant.Standard => trans.standard.txt() + case chess.variant.FromPosition => trans.fromPosition.txt() case v => v.name } def variantNameNoCtx(variant: chess.variant.Variant) = variant match { - case chess.variant.Standard => I18nKeys.standard.literalTxtTo(enLang) - case chess.variant.FromPosition => I18nKeys.fromPosition.literalTxtTo(enLang) + case chess.variant.Standard => trans.standard.literalTxtTo(enLang) + case chess.variant.FromPosition => trans.fromPosition.literalTxtTo(enLang) case v => v.name } - def shortClockName(clock: Option[Clock.Config])(implicit ctx: UserContext): Html = - clock.fold(I18nKeys.unlimited())(shortClockName) + def shortClockName(clock: Option[Clock.Config])(implicit ctx: UserContext): Frag = + clock.fold[Frag](trans.unlimited())(shortClockName) - def shortClockName(clock: Clock.Config): Html = Html(clock.show) + def shortClockName(clock: Clock.Config): Frag = raw(clock.show) def modeName(mode: Mode)(implicit ctx: UserContext): String = mode match { - case Mode.Casual => I18nKeys.casual.txt() - case Mode.Rated => I18nKeys.rated.txt() + case Mode.Casual => trans.casual.txt() + case Mode.Rated => trans.rated.txt() } def modeNameNoCtx(mode: Mode): String = mode match { - case Mode.Casual => I18nKeys.casual.literalTxtTo(enLang) - case Mode.Rated => I18nKeys.rated.literalTxtTo(enLang) + case Mode.Casual => trans.casual.literalTxtTo(enLang) + case Mode.Rated => trans.rated.literalTxtTo(enLang) } - def playerUsername(player: Player, withRating: Boolean = true, withTitle: Boolean = true) = - Namer.player(player, withRating, withTitle)(lightUser) + def playerUsername(player: Player, withRating: Boolean = true, withTitle: Boolean = true): Frag = + player.aiLevel.fold[Frag]( + player.userId.flatMap(lightUser).fold[Frag](lila.user.User.anonymous) { user => + val title = user.title ifTrue withTitle map { t => + frag( + span( + cls := "title", + (Title(t) == Title.BOT) option dataBotAttr, + st.title := Title titleName Title(t) + )(t), + " " + ) + } + if (withRating) frag(title, user.name, " ", "(", lila.game.Namer ratingString player, ")") + else frag(title, user.name) + } + ) { level => raw(s"A.I. level $level") } def playerText(player: Player, withRating: Boolean = false) = Namer.playerText(player, withRating)(lightUser) @@ -102,8 +120,8 @@ trait GameHelper { self: I18nHelper with UserHelper with AiHelper with StringHel def gameVsText(game: Game, withRatings: Boolean = false): String = Namer.gameVsText(game, withRatings)(lightUser) - val berserkIconSpan = """""" - val statusIconSpan = """""" + val berserkIconSpan = iconTag("`") + val statusIconSpan = i(cls := "status") def playerLink( player: Player, @@ -116,59 +134,63 @@ trait GameHelper { self: I18nHelper with UserHelper with AiHelper with StringHel withBerserk: Boolean = false, mod: Boolean = false, link: Boolean = true - )(implicit ctx: UserContext) = Html { + )(implicit ctx: UserContext): Frag = { val statusIcon = - if (withStatus) statusIconSpan - else if (withBerserk && player.berserk) berserkIconSpan - else "" + if (withStatus) statusIconSpan.some + else if (withBerserk && player.berserk) berserkIconSpan.some + else none player.userId.flatMap(lightUser) match { case None => val klass = cssClass.??(" " + _) - val content = (player.aiLevel, player.name) match { - case (Some(level), _) => aiNameHtml(level, withRating).body - case (_, Some(name)) => escapeHtml(name).body - case _ => User.anonymous - } - s"""$content$statusIcon""" - case Some(user) => - val klass = userClass(user.id, cssClass, withOnline) - val href = s"${routes.User show user.name}${if (mod) "?mod" else ""}" - val content = playerUsername(player, withRating) - val diff = (player.ratingDiff ifTrue withDiff) ?? showRatingDiff - val mark = engine ?? s"""""" - val icon = withOnline ?? lineIcon(user) - val space = if (withOnline) " " else "" - val tag = if (link) "a" else "span" - s"""<$tag $klass href="$href">$icon$space$content$diff$mark$statusIcon""" + span(cls := s"user-link$klass")( + (player.aiLevel, player.name) match { + case (Some(level), _) => aiNameFrag(level, withRating) + case (_, Some(name)) => name + case _ => User.anonymous + }, + statusIcon + ) + case Some(user) => frag( + (if (link) a else span)( + cls := userClass(user.id, cssClass, withOnline), + href := s"${routes.User show user.name}${if (mod) "?mod" else ""}" + )( + withOnline option frag(lineIcon(user), " "), + playerUsername(player, withRating), + (player.ratingDiff ifTrue withDiff) map { d => frag(" ", showRatingDiff(d)) }, + engine option span(cls := "engine_mark", title := trans.thisPlayerUsesChessComputerAssistance.txt()) + ), + statusIcon + ) } } def gameEndStatus(game: Game)(implicit ctx: UserContext): String = game.status match { - case S.Aborted => I18nKeys.gameAborted.txt() - case S.Mate => I18nKeys.checkmate.txt() + case S.Aborted => trans.gameAborted.txt() + case S.Mate => trans.checkmate.txt() case S.Resign => game.loser match { - case Some(p) if p.color.white => I18nKeys.whiteResigned.txt() - case _ => I18nKeys.blackResigned.txt() + case Some(p) if p.color.white => trans.whiteResigned.txt() + case _ => trans.blackResigned.txt() } - case S.UnknownFinish => I18nKeys.finished.txt() - case S.Stalemate => I18nKeys.stalemate.txt() + case S.UnknownFinish => trans.finished.txt() + case S.Stalemate => trans.stalemate.txt() case S.Timeout => game.loser match { - case Some(p) if p.color.white => I18nKeys.whiteLeftTheGame.txt() - case Some(_) => I18nKeys.blackLeftTheGame.txt() - case None => I18nKeys.draw.txt() + case Some(p) if p.color.white => trans.whiteLeftTheGame.txt() + case Some(_) => trans.blackLeftTheGame.txt() + case None => trans.draw.txt() } - case S.Draw => I18nKeys.draw.txt() - case S.Outoftime => I18nKeys.timeOut.txt() + case S.Draw => trans.draw.txt() + case S.Outoftime => trans.timeOut.txt() case S.NoStart => { val color = game.loser.fold(Color.white)(_.color).name.capitalize s"$color didn't move" } case S.Cheat => "Cheat detected" case S.VariantEnd => game.variant match { - case chess.variant.KingOfTheHill => I18nKeys.kingInTheCenter.txt() - case chess.variant.ThreeCheck => I18nKeys.threeChecks.txt() - case chess.variant.RacingKings => I18nKeys.raceFinished.txt() - case _ => I18nKeys.variantEnding.txt() + case chess.variant.KingOfTheHill => trans.kingInTheCenter.txt() + case chess.variant.ThreeCheck => trans.threeChecks.txt() + case chess.variant.RacingKings => trans.raceFinished.txt() + case _ => trans.variantEnding.txt() } case _ => "" } @@ -203,6 +225,10 @@ trait GameHelper { self: I18nHelper with UserHelper with AiHelper with StringHel } }.toString + def gameLink(pov: Pov)(implicit ctx: UserContext): String = gameLink(pov.game, pov.color) + + private val cgBoard = div(cls := "cg-board") + def gameFen( pov: Pov, ownerLink: Boolean = false, @@ -210,34 +236,40 @@ trait GameHelper { self: I18nHelper with UserHelper with AiHelper with StringHel withTitle: Boolean = true, withLink: Boolean = true, withLive: Boolean = true - )(implicit ctx: UserContext) = Html { + )(implicit ctx: UserContext): Frag = { val game = pov.game val isLive = withLive && game.isBeingPlayed - val href = withLink ?? s"""href="${gameLink(game, pov.color, ownerLink, tv)}"""" - val title = withTitle ?? s"""title="${gameTitle(game, pov.color)}"""" - val cssClass = isLive ?? ("live live_" + game.id) - val live = isLive ?? game.id - val fen = Forsyth exportBoard game.board - val lastMove = ~game.lastMoveKeys + val cssClass = isLive ?? ("live mini-board-" + game.id) val variant = game.variant.key - val tag = if (withLink) "a" else "span" - s"""<$tag $href $title class="mini_board mini_board_${game.id} parse_fen is2d $cssClass $variant" data-live="$live" data-color="${pov.color.name}" data-fen="$fen" data-lastmove="$lastMove">$miniBoardContent""" + val tag = if (withLink) a else span + val classes = s"mini-board mini-board-${game.id} cg-board-wrap parse-fen is2d $cssClass $variant" + tag( + href := withLink.option(gameLink(game, pov.color, ownerLink, tv)), + title := withTitle.option(gameTitle(game, pov.color)), + cls := s"mini-board mini-board-${game.id} cg-board-wrap parse-fen is2d $cssClass $variant", + dataLive := isLive.option(game.id), + dataColor := pov.color.name, + dataFen := Forsyth.exportBoard(game.board), + dataLastmove := ~game.lastMoveKeys + )(cgBoard) } - def gameFenNoCtx(pov: Pov, tv: Boolean = false, blank: Boolean = false) = Html { + def gameFenNoCtx(pov: Pov, tv: Boolean = false, blank: Boolean = false): Frag = { val isLive = pov.game.isBeingPlayed val variant = pov.game.variant.key - s"""$miniBoardContent""".format( - blank ?? netBaseUrl, - if (tv) routes.Tv.index else routes.Round.watcher(pov.gameId, pov.color.name), - gameTitle(pov.game, pov.color), - isLive ?? ("live live_" + pov.gameId), - isLive ?? pov.gameId, - pov.color.name, - Forsyth exportBoard pov.game.board, - ~pov.game.lastMoveKeys, - blank ?? """ target="_blank"""" - ) + a( + href := (if (tv) routes.Tv.index() else routes.Round.watcher(pov.gameId, pov.color.name)), + title := gameTitle(pov.game, pov.color), + cls := List( + s"mini-board mini-board-${pov.gameId} cg-board-wrap parse-fen is2d $variant" -> true, + s"live mini-board-${pov.gameId}" -> isLive + ), + dataLive := isLive.option(pov.gameId), + dataColor := pov.color.name, + dataFen := Forsyth.exportBoard(pov.game.board), + dataLastmove := ~pov.game.lastMoveKeys, + target := blank.option("_blank") + )(cgBoard) } def challengeTitle(c: lila.challenge.Challenge)(implicit ctx: UserContext) = { diff --git a/app/templating/HtmlHelper.scala b/app/templating/HtmlHelper.scala deleted file mode 100644 index 010220d08f..0000000000 --- a/app/templating/HtmlHelper.scala +++ /dev/null @@ -1,26 +0,0 @@ -package lila.app -package templating - -import ornicar.scalalib.Zero -import play.twirl.api.Html - -trait HtmlHelper { - - val emptyHtml = Html("") - - implicit val LilaHtmlZero: Zero[Html] = Zero.instance(emptyHtml) - - implicit val LilaHtmlMonoid = scalaz.Monoid.instance[Html]( - (a, b) => Html(a.body + b.body), - LilaHtmlZero.zero - ) - - val spinner = Html("""
""") - - @inline implicit def toPimpedHtml(html: Html) = new PimpedHtml(html) -} - -final class PimpedHtml(private val self: Html) extends AnyVal { - def ++(other: Html): Html = Html(s"${self.body}${other.body}") - def ++(other: String): Html = Html(s"${self.body}${other}") -} diff --git a/app/templating/I18hHelper.scala b/app/templating/I18hHelper.scala index a7cda67cf8..9347a1343e 100644 --- a/app/templating/I18hHelper.scala +++ b/app/templating/I18hHelper.scala @@ -2,9 +2,9 @@ package lila.app package templating import play.api.libs.json.JsObject -import play.twirl.api.Html import lila.common.Lang +import lila.app.ui.ScalatagsTemplate._ import lila.i18n.{ LangList, I18nKey, Translator, JsQuantity, I18nDb, JsDump, TimeagoLocales } import lila.user.UserContext @@ -12,8 +12,8 @@ trait I18nHelper { implicit def ctxLang(implicit ctx: UserContext): Lang = ctx.lang - def transKey(key: String, db: I18nDb.Ref, args: Seq[Any] = Nil)(implicit lang: Lang): Html = - Translator.html.literal(key, db, args, lang) + def transKey(key: String, db: I18nDb.Ref, args: Seq[Any] = Nil)(implicit lang: Lang): Frag = + Translator.frag.literal(key, db, args, lang) def i18nJsObject(keys: Seq[I18nKey])(implicit lang: Lang): JsObject = JsDump.keysToObject(keys, I18nDb.Site, lang) @@ -24,11 +24,10 @@ trait I18nHelper { def i18nFullDbJsObject(db: I18nDb.Ref)(implicit lang: Lang): JsObject = JsDump.dbToObject(db, lang) - private val defaultTimeagoLocale = TimeagoLocales.js.get("en") err "Missing en TimeagoLocales" def timeagoLocaleScript(implicit ctx: lila.api.Context): String = { TimeagoLocales.js.get(ctx.lang.code) orElse TimeagoLocales.js.get(ctx.lang.language) getOrElse - defaultTimeagoLocale + ~TimeagoLocales.js.get("en") } def langName = LangList.nameByStr _ diff --git a/app/templating/JsonHelper.scala b/app/templating/JsonHelper.scala deleted file mode 100644 index 80e9c7e94d..0000000000 --- a/app/templating/JsonHelper.scala +++ /dev/null @@ -1,25 +0,0 @@ -package lila.app -package templating - -import play.api.libs.json._ -import play.twirl.api.Html -import scalatags.Text.{ Frag, RawFrag } - -import lila.api.Context - -trait JsonHelper { - - def toJsonHtml[A: Writes](map: Map[Int, A]): Html = toJsonHtml { - map mapKeys (_.toString) - } - - def toJsonHtml[A: Writes](a: A): Html = lila.common.String.html.safeJsonHtml(Json toJson a) - def toJsonFrag[A: Writes](a: A): Frag = RawFrag(lila.common.String.html.safeJsonValue(Json toJson a)) - - def htmlOrNull[A, B](a: Option[A])(f: A => Html) = a.fold(Html("null"))(f) - - def jsOrNull[A: Writes](a: Option[A]) = a.fold(Html("null"))(x => toJsonHtml(x)) - - def jsUserIdString(implicit ctx: Context) = ctx.userId.fold("null")(id => s""""$id"""") - def jsUserId(implicit ctx: Context) = Html { jsUserIdString(ctx) } -} diff --git a/app/templating/RequestHelper.scala b/app/templating/RequestHelper.scala deleted file mode 100644 index ba2e143b5e..0000000000 --- a/app/templating/RequestHelper.scala +++ /dev/null @@ -1,9 +0,0 @@ -package lila.app -package templating - -import lila.api.Context - -trait RequestHelper { - - def currentPath(implicit ctx: Context) = ctx.req.path -} diff --git a/app/templating/SecurityHelper.scala b/app/templating/SecurityHelper.scala index 05238cca5f..050ee51115 100644 --- a/app/templating/SecurityHelper.scala +++ b/app/templating/SecurityHelper.scala @@ -1,8 +1,7 @@ package lila.app package templating -import play.twirl.api.Html - +import lila.app.ui.ScalatagsTemplate._ import lila.security.{ Permission, Granter } import lila.user.{ User, UserContext } @@ -20,13 +19,11 @@ trait SecurityHelper { def isGranted(permission: Permission, user: User): Boolean = Granter(permission)(user) + def canGrant = Granter.canGrant _ + def canViewRoles(user: User)(implicit ctx: UserContext): Boolean = isGranted(_.ChangePermission) || (isGranted(_.Admin) && user.roles.nonEmpty) - def reportScore(score: lila.report.Report.Score) = Html { - s"""
${score.value.toInt}
""" - } - // def reportScore(score: lila.report.Report.Score) = Html { - // s"""
Score${score.value.toInt}
""" - // } + def reportScore(score: lila.report.Report.Score): Frag = + div(cls := s"score ${score.color}", title := "Report score")(score.value.toInt) } diff --git a/app/templating/SetupHelper.scala b/app/templating/SetupHelper.scala index a270c02b31..baa0aa0af0 100644 --- a/app/templating/SetupHelper.scala +++ b/app/templating/SetupHelper.scala @@ -211,6 +211,12 @@ trait SetupHelper { self: I18nHelper => (Pref.InsightShare.EVERYBODY, trans.withEverybody.txt()) ) + def translatedBoardResizeHandleChoices(implicit ctx: Context) = List( + (Pref.ResizeHandle.NEVER, trans.never.txt()), + (Pref.ResizeHandle.INITIAL, "Only on initial position"), + (Pref.ResizeHandle.ALWAYS, trans.always.txt()) + ) + def translatedBlindfoldChoices(implicit ctx: Context) = List( Pref.Blindfold.NO -> trans.no.txt(), Pref.Blindfold.YES -> trans.yes.txt() diff --git a/app/templating/SimulHelper.scala b/app/templating/SimulHelper.scala deleted file mode 100644 index fc184b13a7..0000000000 --- a/app/templating/SimulHelper.scala +++ /dev/null @@ -1,15 +0,0 @@ -package lila.app -package templating - -import controllers.routes -import lila.simul.Simul - -import play.twirl.api.Html - -trait SimulHelper { self: I18nHelper => - - def simulLink(simulId: Simul.ID): Html = Html { - val url = routes.Simul.show(simulId) - s"""Simultaneous exhibition""" - } -} diff --git a/app/templating/StringHelper.scala b/app/templating/StringHelper.scala index bc66c4124a..c6d7ea8f24 100644 --- a/app/templating/StringHelper.scala +++ b/app/templating/StringHelper.scala @@ -1,9 +1,8 @@ package lila.app package templating -import play.twirl.api.Html - import lila.user.UserContext +import ui.ScalatagsTemplate._ trait StringHelper { self: NumberHelper => @@ -15,10 +14,6 @@ trait StringHelper { self: NumberHelper => def pluralize(s: String, n: Int) = s"$n $s${if (n > 1) "s" else ""}" - def repositionTooltipUnsafe(link: Html, position: String) = Html { - link.body.replace(" 0) s"+$n" else n.toString implicit def lilaRichString(str: String) = new { @@ -30,23 +25,32 @@ trait StringHelper { self: NumberHelper => private val NumberFirstRegex = """(\d++)\s(.+)""".r private val NumberLastRegex = """\s(\d++)$""".r.unanchored - def splitNumberUnsafe(s: String)(implicit ctx: UserContext): Html = Html { - s match { - case NumberFirstRegex(number, text) => - s"${(~parseIntOption(number)).localize}
$text" - case NumberLastRegex(n) if s.length > n.length + 1 => - s"${s.dropRight(n.length + 1)}
${(~parseIntOption(n)).localize}" - case h => h.replaceIf('\n', "
") + + def splitNumber(s: Frag)(implicit ctx: UserContext): Frag = { + val rendered = s.render + rendered match { + case NumberFirstRegex(number, html) => frag( + strong((~parseIntOption(number)).localize), + br, + raw(html) + ) + case NumberLastRegex(n) if rendered.length > n.length + 1 => frag( + raw(rendered.dropRight(n.length + 1)), + br, + strong((~parseIntOption(n)).localize) + ) + case h => raw(h.replaceIf('\n', "
")) } } - def splitNumber(s: Html)(implicit ctx: UserContext): Html = splitNumberUnsafe(s.body) def encodeFen(fen: String) = lila.common.String.base64.encode(fen).reverse def addQueryParameter(url: String, key: String, value: Any) = if (url contains "?") s"$url&$key=$value" else s"$url?$key=$value" - def htmlList(htmls: List[Html], separator: String = ", ") = Html { - htmls mkString separator + def fragList(frags: List[Frag], separator: String = ", "): Frag = frags match { + case Nil => emptyFrag + case one :: Nil => one + case first :: rest => first :: rest.map { f => frag(separator, f) } } } diff --git a/app/templating/TeamHelper.scala b/app/templating/TeamHelper.scala index 2efffda94d..3eb3f4e62c 100644 --- a/app/templating/TeamHelper.scala +++ b/app/templating/TeamHelper.scala @@ -2,11 +2,10 @@ package lila.app package templating import controllers.routes -import play.twirl.api.Html import lila.api.Context +import lila.app.ui.ScalatagsTemplate._ import lila.team.Env.{ current => teamEnv } -import lila.common.String.html.escapeHtml trait TeamHelper { @@ -15,15 +14,12 @@ trait TeamHelper { def myTeam(teamId: String)(implicit ctx: Context): Boolean = ctx.me.??(me => api.syncBelongsTo(teamId, me.id)) - def teamIdToName(id: String): Html = escapeHtml(api teamName id getOrElse id) + def teamIdToName(id: String): Frag = StringFrag(api.teamName(id).getOrElse(id)) - def teamLink(id: String, withIcon: Boolean = true): Html = Html { - val href = routes.Team.show(id) - val content = teamIdToName(id) - val icon = if (withIcon) """ data-icon="f"""" else "" - val space = if (withIcon) " " else "" - s"""$space$content
""" - } + def teamLink(id: String, withIcon: Boolean = true): Frag = a( + href := routes.Team.show(id), + dataIcon := withIcon.option("f") + )(withIcon option nbsp, teamIdToName(id)) def teamForumUrl(id: String) = routes.ForumCateg.show("team-" + id) } diff --git a/app/templating/TournamentHelper.scala b/app/templating/TournamentHelper.scala index 5c6d142154..fd4c50365c 100644 --- a/app/templating/TournamentHelper.scala +++ b/app/templating/TournamentHelper.scala @@ -2,12 +2,12 @@ package lila.app package templating import controllers.routes +import lila.app.ui.ScalatagsTemplate._ import lila.tournament.Env.{ current => tournamentEnv } import lila.tournament.{ Tournament, System, Schedule } import lila.user.{ User, UserContext } import play.api.libs.json.Json -import play.twirl.api.Html trait TournamentHelper { self: I18nHelper with DateHelper with UserHelper => @@ -24,16 +24,17 @@ trait TournamentHelper { self: I18nHelper with DateHelper with UserHelper => } } - def tournamentLink(tour: Tournament): Html = Html { - val cssClass = if (tour.isScheduled) "text is-gold" else "text" - val url = routes.Tournament.show(tour.id) - s"""${tour.fullName}""" - } + def tournamentLink(tour: Tournament): Frag = a( + dataIcon := "g", + cls := (if (tour.isScheduled) "text is-gold" else "text"), + href := routes.Tournament.show(tour.id).url + )(tour.fullName) - def tournamentLink(tourId: String): Html = Html { - val url = routes.Tournament.show(tourId) - s"""${tournamentIdToName(tourId)}""" - } + def tournamentLink(tourId: String): Frag = a( + dataIcon := "g", + cls := "text", + href := routes.Tournament.show(tourId).url + )(tournamentIdToName(tourId)) def tournamentIdToName(id: String) = tournamentEnv.cached name id getOrElse "Tournament" @@ -47,7 +48,7 @@ trait TournamentHelper { self: I18nHelper with DateHelper with UserHelper => ) ::: lila.rating.PerfType.leaderboardable.map { pt => pt.name -> icon(pt.iconChar) } - def apply(name: String) = Html { + def apply(name: String): Frag = raw { replacements.foldLeft(name) { case (n, (from, to)) => n.replace(from, to) } diff --git a/app/templating/UserHelper.scala b/app/templating/UserHelper.scala index 8d1fa16fd0..1bfbec61b0 100644 --- a/app/templating/UserHelper.scala +++ b/app/templating/UserHelper.scala @@ -1,29 +1,22 @@ package lila.app package templating -import play.twirl.api.Html - import controllers.routes import mashup._ import lila.api.Context +import lila.app.ui.ScalatagsTemplate._ import lila.common.LightUser -import lila.i18n.I18nKeys +import lila.i18n.{ I18nKeys => trans } import lila.rating.{ PerfType, Perf } import lila.user.{ User, Title, UserContext } -trait UserHelper { self: I18nHelper with StringHelper with HtmlHelper with NumberHelper => +trait UserHelper { self: I18nHelper with StringHelper with NumberHelper => - def showProgress(progress: Int, withTitle: Boolean = true) = Html { - val span = progress match { - case 0 => "" - case p if p > 0 => s"""$p""" - case p if p < 0 => s"""${math.abs(p)}""" - } - val title = if (withTitle) """ data-hint="Rating progression over the last twelve games"""" else "" - val klass = if (withTitle) "progress hint--bottom" else "progress" - s"""$span""" - } + def ratingProgress(progress: Int) = + if (progress > 0) goodTag(cls := "rp")(progress) + else if (progress < 0) badTag(cls := "rp")(math.abs(progress)) + else emptyFrag val topBarSortedPerfTypes: List[PerfType] = List( PerfType.Bullet, @@ -40,38 +33,37 @@ trait UserHelper { self: I18nHelper with StringHelper with HtmlHelper with Numbe PerfType.Crazyhouse ) - def showPerfRating(rating: Int, name: String, nb: Int, provisional: Boolean, icon: Char, klass: String)(implicit ctx: Context) = Html { - val title = s"$name rating over ${nb.localize} games" - val attr = if (klass == "title") "title" else "data-hint" - val number = if (nb > 0) s"$rating${if (provisional) "?" else ""}" - else "   -" - s"""$number""" - } + def showPerfRating(rating: Int, name: String, nb: Int, provisional: Boolean, icon: Char)(implicit ctx: Context): Frag = + span( + title := s"$name rating over ${nb.localize} games", + dataIcon := icon, + cls := "text" + )( + if (nb > 0) frag(rating, provisional option "?") + else frag(nbsp, nbsp, nbsp, "-") + ) - def showPerfRating(perfType: PerfType, perf: Perf, klass: String)(implicit ctx: Context): Html = - showPerfRating(perf.intRating, perfType.name, perf.nb, perf.provisional, perfType.iconChar, klass) + def showPerfRating(perfType: PerfType, perf: Perf)(implicit ctx: Context): Frag = + showPerfRating(perf.intRating, perfType.name, perf.nb, perf.provisional, perfType.iconChar) - def showPerfRating(u: User, perfType: PerfType, klass: String = "hint--bottom")(implicit ctx: Context): Html = - showPerfRating(perfType, u perfs perfType, klass) + def showPerfRating(u: User, perfType: PerfType)(implicit ctx: Context): Frag = + showPerfRating(perfType, u perfs perfType) - def showPerfRating(u: User, perfKey: String)(implicit ctx: Context): Option[Html] = + def showPerfRating(u: User, perfKey: String)(implicit ctx: Context): Option[Frag] = PerfType(perfKey) map { showPerfRating(u, _) } - def showBestPerf(u: User)(implicit ctx: Context): Option[Html] = u.perfs.bestPerf map { - case (pt, perf) => showPerfRating(pt, perf, klass = "hint--bottom") + def showBestPerf(u: User)(implicit ctx: Context): Option[Frag] = u.perfs.bestPerf map { + case (pt, perf) => showPerfRating(pt, perf) } - def showBestPerfs(u: User, nb: Int)(implicit ctx: Context): Html = Html { + def showBestPerfs(u: User, nb: Int)(implicit ctx: Context): List[Frag] = u.perfs.bestPerfs(nb) map { - case (pt, perf) => showPerfRating(pt, perf, klass = "hint--bottom").body - } mkString " " - } - - def showRatingDiff(diff: Int) = Html { - diff match { - case 0 => """±0""" - case d if d > 0 => s"""+$d""" - case d => s"""−${-d}""" + case (pt, perf) => showPerfRating(pt, perf) } + + def showRatingDiff(diff: Int): Frag = diff match { + case 0 => span("±0") + case d if d > 0 => goodTag(s"+$d") + case d => badTag(s"−${-d}") } def lightUser(userId: String): Option[LightUser] = Env.user lightUserSync userId @@ -94,8 +86,8 @@ trait UserHelper { self: I18nHelper with StringHelper with HtmlHelper with Numbe truncate: Option[Int] = None, params: String = "", modIcon: Boolean = false - ): Html = Html { - userIdOption.flatMap(lightUser).fold(User.anonymous) { user => + ): Frag = + userIdOption.flatMap(lightUser).fold[Frag](User.anonymous) { user => userIdNameLink( userId = user.id, username = user.name, @@ -108,7 +100,6 @@ trait UserHelper { self: I18nHelper with StringHelper with HtmlHelper with Numbe modIcon = modIcon ) } - } def lightUserLink( user: LightUser, @@ -117,31 +108,33 @@ trait UserHelper { self: I18nHelper with StringHelper with HtmlHelper with Numbe withTitle: Boolean = true, truncate: Option[Int] = None, params: String = "" - ): Html = Html { - userIdNameLink( - userId = user.id, - username = user.name, - isPatron = user.isPatron, - title = withTitle ?? user.title map Title.apply, - cssClass = cssClass, - withOnline = withOnline, - truncate = truncate, - params = params, - modIcon = false - ) - } + ): Frag = userIdNameLink( + userId = user.id, + username = user.name, + isPatron = user.isPatron, + title = withTitle ?? user.title map Title.apply, + cssClass = cssClass, + withOnline = withOnline, + truncate = truncate, + params = params, + modIcon = false + ) def userIdLink( userId: String, cssClass: Option[String] - ): Html = userIdLink(userId.some, cssClass) + ): Frag = userIdLink(userId.some, cssClass) - def titleTag(title: Option[Title]) = Html { - title.fold("") { t => - s"""$t """ - } + def titleTag(title: Option[Title]): Option[Frag] = title map { t => + frag( + span( + cls := s"title${(t == Title.BOT) ?? " data-bot"}", + st.title := Title.titleName(t) + )(t), + nbsp + ) } - def titleTag(lu: LightUser): Html = titleTag(lu.title map Title.apply) + def titleTag(lu: LightUser): Frag = titleTag(lu.title map Title.apply) private def userIdNameLink( userId: String, @@ -153,14 +146,14 @@ trait UserHelper { self: I18nHelper with StringHelper with HtmlHelper with Numbe title: Option[Title], params: String, modIcon: Boolean - ): String = { - val klass = userClass(userId, cssClass, withOnline) - val href = userHref(username, params = params) - val content = truncate.fold(username)(username.take) - val titleS = titleTag(title).body - val icon = withOnline ?? (if (modIcon) moderatorIcon else lineIcon(isPatron)) - s"""$icon$titleS$content""" - } + ): Frag = a( + cls := userClass(userId, cssClass, withOnline), + href := userUrl(username, params = params) + )( + withOnline ?? (if (modIcon) moderatorIcon else lineIcon(isPatron)), + titleTag(title), + truncate.fold(username)(username.take) + ) def userLink( user: User, @@ -172,33 +165,15 @@ trait UserHelper { self: I18nHelper with StringHelper with HtmlHelper with Numbe withPerfRating: Option[PerfType] = None, text: Option[String] = None, params: String = "" - ): Html = Html { - val klass = userClass(user.id, cssClass, withOnline, withPowerTip) - val href = userHref(user.username, params) - val content = text | user.username - val titleS = if (withTitle) titleTag(user.title).body else "" - val rating = userRating(user, withPerfRating, withBestRating) - val icon = withOnline ?? lineIcon(user) - s"""$icon$titleS$content$rating""" - } - - def userInfosLink( - userId: String, - rating: Option[Int], - cssClass: Option[String] = None, - withPowerTip: Boolean = true, - withTitle: Boolean = false, - withOnline: Boolean = true - ) = { - val user = lightUser(userId) - val name = user.fold(userId)(_.name) - val klass = userClass(userId, cssClass, withOnline, withPowerTip) - val href = userHref(name) - val rat = rating ?? { r => s" ($r)" } - val titleS = withTitle ?? user ?? (u => titleTag(u).body) - val icon = withOnline ?? lineIcon(user) - Html(s"""$icon$titleS$name$rat""") - } + ): Frag = a( + cls := userClass(user.id, cssClass, withOnline, withPowerTip), + href := userUrl(user.username, params) + )( + withOnline ?? lineIcon(user), + withTitle option titleTag(user.title), + text | user.username, + userRating(user, withPerfRating, withBestRating) + ) def userSpan( user: User, @@ -209,31 +184,37 @@ trait UserHelper { self: I18nHelper with StringHelper with HtmlHelper with Numbe withBestRating: Boolean = false, withPerfRating: Option[PerfType] = None, text: Option[String] = None - ) = Html { - val klass = userClass(user.id, cssClass, withOnline, withPowerTip) - val href = s"data-${userHref(user.username)}" - val content = text | user.username - val titleS = if (withTitle) titleTag(user.title).body else "" - val rating = userRating(user, withPerfRating, withBestRating) - val icon = withOnline ?? lineIcon(user) - s"""$icon$titleS$content$rating""" - } + ): Frag = span( + cls := userClass(user.id, cssClass, withOnline, withPowerTip), + dataHref := userUrl(user.username) + )( + withOnline ?? lineIcon(user), + withTitle option titleTag(user.title), + text | user.username, + userRating(user, withPerfRating, withBestRating) + ) - def userIdSpanMini(userId: String, withOnline: Boolean = false) = Html { + def userIdSpanMini(userId: String, withOnline: Boolean = false): Frag = { val user = lightUser(userId) val name = user.fold(userId)(_.name) - val content = user.fold(userId)(_.name) - val titleS = user.??(u => titleTag(u.title map Title.apply).body) - val klass = userClass(userId, none, withOnline) - val href = s"data-${userHref(name)}" - val icon = withOnline ?? lineIcon(user) - s"""$icon$titleS$content""" + span( + cls := userClass(userId, none, withOnline), + dataHref := userUrl(name) + )( + withOnline ?? lineIcon(user), + user.??(u => titleTag(u.title map Title.apply)), + name + ) } - private def renderRating(perf: Perf) = - s" (${perf.intRating}${if (perf.provisional) "?" else ""})" + private def renderRating(perf: Perf): Frag = frag( + " (", + perf.intRating, + perf.provisional option "?", + ")" + ) - private def userRating(user: User, withPerfRating: Option[PerfType], withBestRating: Boolean) = + private def userRating(user: User, withPerfRating: Option[PerfType], withBestRating: Boolean): Frag = withPerfRating match { case Some(perfType) => renderRating(user.perfs(perfType)) case _ if withBestRating => user.perfs.bestPerf ?? { @@ -242,37 +223,36 @@ trait UserHelper { self: I18nHelper with StringHelper with HtmlHelper with Numbe case _ => "" } - private def userHref(username: String, params: String = "") = - s"""href="${routes.User.show(username)}$params"""" - - private def addClass(cls: Option[String]) = cls.fold("")(" " + _) + private def userUrl(username: String, params: String = "") = + s"""${routes.User.show(username)}$params""" protected def userClass( userId: String, cssClass: Option[String], withOnline: Boolean, withPowerTip: Boolean = true - ): String = { - val online = if (withOnline) { - if (isOnline(userId)) " online" else " offline" - } else "" - s"""class="user_link${addClass(cssClass)}${addClass(withPowerTip option "ulpt")}$online"""" - } + ): List[(String, Boolean)] = + (withOnline ?? List((if (isOnline(userId)) "online" else "offline") -> true)) ::: List( + "user-link" -> true, + ~cssClass -> cssClass.isDefined, + "ulpt" -> withPowerTip + ) - def userGameFilterTitle(u: User, nbs: UserInfo.NbGames, filter: GameFilter)(implicit ctx: UserContext) = - splitNumber(userGameFilterTitleNoTag(u, nbs, filter)) + def userGameFilterTitle(u: User, nbs: UserInfo.NbGames, filter: GameFilter)(implicit ctx: UserContext): Frag = + if (filter == GameFilter.Search) frag(br, trans.advancedSearch()) + else splitNumber(userGameFilterTitleNoTag(u, nbs, filter)) - def userGameFilterTitleNoTag(u: User, nbs: UserInfo.NbGames, filter: GameFilter)(implicit ctx: UserContext): Html = (filter match { - case GameFilter.All => I18nKeys.nbGames.pluralSame(u.count.game) - case GameFilter.Me => nbs.withMe ?? I18nKeys.nbGamesWithYou.pluralSame - case GameFilter.Rated => I18nKeys.nbRated.pluralSame(u.count.rated) - case GameFilter.Win => I18nKeys.nbWins.pluralSame(u.count.win) - case GameFilter.Loss => I18nKeys.nbLosses.pluralSame(u.count.loss) - case GameFilter.Draw => I18nKeys.nbDraws.pluralSame(u.count.draw) - case GameFilter.Playing => I18nKeys.nbPlaying.pluralSame(nbs.playing) - case GameFilter.Bookmark => I18nKeys.nbBookmarks.pluralSame(nbs.bookmark) - case GameFilter.Imported => I18nKeys.nbImportedGames.pluralSame(nbs.imported) - case GameFilter.Search => I18nKeys.advancedSearch() + def userGameFilterTitleNoTag(u: User, nbs: UserInfo.NbGames, filter: GameFilter)(implicit ctx: UserContext): String = (filter match { + case GameFilter.All => trans.nbGames.pluralSameTxt(u.count.game) + case GameFilter.Me => nbs.withMe ?? trans.nbGamesWithYou.pluralSameTxt + case GameFilter.Rated => trans.nbRated.pluralSameTxt(u.count.rated) + case GameFilter.Win => trans.nbWins.pluralSameTxt(u.count.win) + case GameFilter.Loss => trans.nbLosses.pluralSameTxt(u.count.loss) + case GameFilter.Draw => trans.nbDraws.pluralSameTxt(u.count.draw) + case GameFilter.Playing => trans.nbPlaying.pluralSameTxt(nbs.playing) + case GameFilter.Bookmark => trans.nbBookmarks.pluralSameTxt(nbs.bookmark) + case GameFilter.Imported => trans.nbImportedGames.pluralSameTxt(nbs.imported) + case GameFilter.Search => trans.advancedSearch.txt() }) def describeUser(user: User) = { @@ -288,12 +268,12 @@ trait UserHelper { self: I18nHelper with StringHelper with HtmlHelper with Numbe val patronIconChar = "" val lineIconChar = "" - val lineIcon: String = """""" - val patronIcon: String = """""" - val moderatorIcon: String = """""" - private def lineIcon(patron: Boolean): String = if (patron) patronIcon else lineIcon - private def lineIcon(user: Option[LightUser]): String = lineIcon(user.??(_.isPatron)) - def lineIcon(user: LightUser): String = lineIcon(user.isPatron) - def lineIcon(user: User): String = lineIcon(user.isPatron) - def lineIconChar(user: User): String = if (user.isPatron) patronIconChar else lineIconChar + val lineIcon: Frag = i(cls := "line") + val patronIcon: Frag = i(cls := "line patron", title := "Lichess Patron") + val moderatorIcon: Frag = i(cls := "line moderator", title := "Lichess Mod") + private def lineIcon(patron: Boolean): Frag = if (patron) patronIcon else lineIcon + private def lineIcon(user: Option[LightUser]): Frag = lineIcon(user.??(_.isPatron)) + def lineIcon(user: LightUser): Frag = lineIcon(user.isPatron) + def lineIcon(user: User): Frag = lineIcon(user.isPatron) + def lineIconChar(user: User): Frag = if (user.isPatron) patronIconChar else lineIconChar } diff --git a/app/ui/EmbedConfig.scala b/app/ui/EmbedConfig.scala new file mode 100644 index 0000000000..bf4c7257e0 --- /dev/null +++ b/app/ui/EmbedConfig.scala @@ -0,0 +1,27 @@ +package lila.app +package ui + +import play.api.mvc.RequestHeader + +import lila.common.{ Nonce, Lang } + +case class EmbedConfig(bg: String, board: String, lang: Lang, req: RequestHeader, nonce: Nonce) + +object EmbedConfig { + + object implicits { + implicit def configLang(implicit config: EmbedConfig): Lang = config.lang + implicit def configReq(implicit config: EmbedConfig): RequestHeader = config.req + } + + def apply(req: RequestHeader): EmbedConfig = EmbedConfig( + bg = get("bg", req).filterNot("auto" ==) | "light", + board = lila.pref.Theme(~get("theme", req)).cssClass, + lang = lila.i18n.I18nLangPicker(req, none), + req = req, + nonce = Nonce.random + ) + + private def get(name: String, req: RequestHeader): Option[String] = + req.queryString get name flatMap (_.headOption) filter (_.nonEmpty) +} diff --git a/app/ui/OpenGraph.scala b/app/ui/OpenGraph.scala index 851c7466ed..1412882166 100644 --- a/app/ui/OpenGraph.scala +++ b/app/ui/OpenGraph.scala @@ -1,7 +1,7 @@ package lila.app package ui -import lila.common.String.html.escapeHtml +import lila.app.ui.ScalatagsTemplate._ case class OpenGraph( title: String, @@ -13,39 +13,45 @@ case class OpenGraph( more: List[(String, String)] = Nil ) { - def frag = scalatags.Text.RawFrag(s"${og.str}${twitter.str}") + def frags: List[Frag] = og.frags ::: twitter.frags object og { - private def tag(name: String, value: String) = - s"""""" + private val property = attr("property") + + private def tag(name: String, value: String) = meta( + property := s"og:$name", + content := value + ) private val tupledTag = (tag _).tupled - def str = List( + def frags: List[Frag] = List( "title" -> title, "description" -> description, "url" -> url, "type" -> `type`, "site_name" -> siteName - ).map(tupledTag).mkString + - image.?? { tag("image", _) } + - more.map(tupledTag).mkString + ).map(tupledTag) ::: + image.map { tag("image", _) }.toList ::: + more.map(tupledTag) } object twitter { - private def tag(name: String, value: String) = - s"""""" + private def tag(name: String, value: String) = meta( + st.name := s"twitter:$name", + content := value + ) private val tupledTag = (tag _).tupled - def str = List( + def frags: List[Frag] = List( "card" -> "summary", "title" -> title, "description" -> description - ).map(tupledTag).mkString + - image.?? { tag("image", _) } + - more.map(tupledTag).mkString + ).map(tupledTag) ::: + image.map { tag("image", _) }.toList ::: + more.map(tupledTag) } } diff --git a/app/ui/scalatags.scala b/app/ui/scalatags.scala index 1d7f8f4242..4eed6e71a6 100644 --- a/app/ui/scalatags.scala +++ b/app/ui/scalatags.scala @@ -3,24 +3,30 @@ package ui import ornicar.scalalib.Zero -import play.twirl.api.Html -import scalatags.Text.all.{ genericAttr, attr, StringFrag } import scalatags.text.Builder -import scalatags.Text.{ Frag, RawFrag, Attr, AttrValue, Modifier, Cap, Aggregate, Attrs, Styles } +import scalatags.Text.{ Aggregate, Cap } +import scalatags.Text.all._ // collection of lila attrs trait ScalatagsAttrs { - lazy val minlength = attr("minlength") // missing from scalatags atm - lazy val dataTag = attr("data-tag") - lazy val dataIcon = attr("data-icon") - lazy val dataHint = attr("data-hint") - lazy val dataHref = attr("data-href") - lazy val dataCount = attr("data-count") - lazy val dataEnableTime = attr("data-enable-time") - lazy val datatime24h = attr("data-time_24h") - lazy val dataColor = attr("data-color") - lazy val dataFen = attr("data-fen") - lazy val novalidate = attr("novalidate") + val minlength = attr("minlength") // missing from scalatags atm + val dataTag = attr("data-tag") + val dataIcon = attr("data-icon") + val dataHref = attr("data-href") + val dataCount = attr("data-count") + val dataEnableTime = attr("data-enable-time") + val datatime24h = attr("data-time_24h") + val dataColor = attr("data-color") + val dataFen = attr("data-fen") + val dataRel = attr("data-rel") + val novalidate = attr("novalidate").empty + val datetimeAttr = attr("datetime") + val dataBotAttr = attr("data-bot").empty + val deferAttr = attr("defer").empty + object frame { + val scrolling = attr("scrolling") + val allowfullscreen = attr("allowfullscreen").empty + } } // collection of lila snippets @@ -30,15 +36,30 @@ trait ScalatagsSnippets extends Cap { import scalatags.Text.all._ val nbsp = raw(" ") + val amp = raw("&") def iconTag(icon: Char): Tag = iconTag(icon.toString) def iconTag(icon: String): Tag = i(dataIcon := icon) + def iconTag(icon: Char, text: Frag): Tag = iconTag(icon.toString, text) def iconTag(icon: String, text: Frag): Tag = i(dataIcon := icon, cls := "text")(text) - - lazy val dataBotAttr = attr("data-bot").empty + val styleTag = tag("style")(tpe := "text/css") + val ratingTag = tag("rating") + val countTag = tag("count") + val goodTag = tag("good") + val badTag = tag("bad") + val timeTag = tag("time") def dataBot(title: lila.user.Title): Modifier = if (title == lila.user.Title.BOT) dataBotAttr else emptyModifier + + def pagerNext(pager: lila.common.paginator.Paginator[_], url: Int => String): Option[Frag] = + pager.nextPage.map { np => + div(cls := "pager none")(a(rel := "next", href := url(np))("Next")) + } + def pagerNextTable(pager: lila.common.paginator.Paginator[_], url: Int => String): Option[Frag] = + pager.nextPage.map { np => + tr(th(cls := "pager none")(a(rel := "next", href := url(np))("Next"))) + } } // basic imports from scalatags @@ -51,9 +72,16 @@ trait ScalatagsBundle extends Cap // short prefix trait ScalatagsPrefix { object st extends Cap with Attrs with scalatags.text.Tags { - lazy val group = tag("group") - } + val group = tag("group") + val headTitle = tag("title") + val nav = tag("nav") + val section = tag("section") + val article = tag("article") + val aside = tag("aside") + val rating = tag("rating") + val frameborder = attr("frameborder") + } } // what to import in a pure scalatags template @@ -65,42 +93,24 @@ trait ScalatagsTemplate extends Styles with ScalatagsPrefix { val trans = lila.i18n.I18nKeys + def main = scalatags.Text.tags2.main + + /* Convert play URLs to scalatags attributes with toString */ + implicit val playCallAttr = genericAttr[play.api.mvc.Call] } object ScalatagsTemplate extends ScalatagsTemplate -// what to import in all twirl templates -trait ScalatagsTwirl extends ScalatagsPlay - -// what to import in twirl templates containing scalatags forms -// Allows `*.rows := 5` -trait ScalatagsTwirlForm extends ScalatagsPlay with Cap with Aggregate { - object * extends Cap with Attrs with ScalatagsAttrs -} -object ScalatagsTwirlForm extends ScalatagsTwirlForm - -// interop with play -trait ScalatagsPlay { - - /* Feed frags back to twirl by converting them to rendered Html */ - implicit def fragToPlayHtml(frag: Frag): Html = Html(frag.render) - - /* Use play Html inside tags without double-encoding */ - implicit def playHtmlToFrag(html: Html): Frag = RawFrag(html.body) - - /* Convert play URLs to scalatags attributes with toString */ - implicit val playCallAttr = genericAttr[play.api.mvc.Call] - - @inline implicit def fragToHtml(frag: Frag) = new FragToHtml(frag) -} - -final class FragToHtml(private val self: Frag) extends AnyVal { - def toHtml: Html = Html(self.render) -} - // generic extensions trait ScalatagsExtensions { + implicit def stringValueFrag(sv: StringValue): Frag = new StringFrag(sv.value) + + implicit val stringValueAttr = new AttrValue[StringValue] { + def apply(t: scalatags.text.Builder, a: Attr, v: StringValue): Unit = + t.setAttr(a.name, scalatags.text.Builder.GenericAttrValueSource(v.value)) + } + implicit val charAttr = genericAttr[Char] implicit val optionStringAttr = new AttrValue[Option[String]] { @@ -111,11 +121,6 @@ trait ScalatagsExtensions { } } - implicit val optionBooleanAttr = new AttrValue[Option[Boolean]] { - def apply(t: scalatags.text.Builder, a: Attr, v: Option[Boolean]): Unit = - if (~v) t.setAttr(a.name, scalatags.text.Builder.GenericAttrValueSource("true")) - } - /* for class maps such as List("foo" -> true, "active" -> isActive) */ implicit val classesAttr = new AttrValue[List[(String, Boolean)]] { def apply(t: scalatags.text.Builder, a: Attr, m: List[(String, Boolean)]): Unit = { diff --git a/app/views/account/bits.scala b/app/views/account/bits.scala index ec1077add3..fdf9acddde 100644 --- a/app/views/account/bits.scala +++ b/app/views/account/bits.scala @@ -8,10 +8,10 @@ import lila.pref.PrefCateg object bits { - def categName(categ: lila.pref.PrefCateg)(implicit ctx: Context) = categ match { - case PrefCateg.GameDisplay => trans.gameDisplay() - case PrefCateg.ChessClock => trans.chessClock() - case PrefCateg.GameBehavior => trans.gameBehavior() - case PrefCateg.Privacy => trans.privacy() + def categName(categ: lila.pref.PrefCateg)(implicit ctx: Context): String = categ match { + case PrefCateg.GameDisplay => trans.gameDisplay.txt() + case PrefCateg.ChessClock => trans.chessClock.txt() + case PrefCateg.GameBehavior => trans.gameBehavior.txt() + case PrefCateg.Privacy => trans.privacy.txt() } } diff --git a/app/views/account/close.scala b/app/views/account/close.scala index c31645502e..2e6a37da24 100644 --- a/app/views/account/close.scala +++ b/app/views/account/close.scala @@ -11,26 +11,24 @@ object close { def apply(u: lila.user.User, form: play.api.data.Form[_])(implicit ctx: Context) = account.layout( title = s"${u.username} - ${trans.closeAccount.txt()}", - active = "close", - evenMoreCss = cssTag("form3.css") + active = "close" ) { - div(cls := "content_box small_box")( - div(cls := "signup_box")( - h1(dataIcon := "j", cls := "lichess_title text")(trans.closeAccount.frag()), - st.form(cls := "form3", action := routes.Account.closeConfirm, method := "POST")( - div(cls := "form-group")(trans.closeAccountExplanation.frag()), - div(cls := "form-group")("You will not be allowed to open a new account with the same name, even if the case if different."), - form3.passwordNoAutocomplete(form("passwd"), trans.password.frag()), - form3.actions(frag( - a(href := routes.User.show(u.username))(trans.changedMindDoNotCloseAccount.frag()), - form3.submit( - trans.closeAccount.frag(), - icon = "j".some, - confirm = "Closing is definitive. There is no going back. Are you sure?".some - ) - )) + div(cls := "account box box-pad")( + h1(dataIcon := "j", cls := "text")(trans.closeAccount()), + st.form(cls := "form3", action := routes.Account.closeConfirm, method := "POST")( + div(cls := "form-group")(trans.closeAccountExplanation()), + div(cls := "form-group")("You will not be allowed to open a new account with the same name, even if the case if different."), + form3.passwordModified(form("passwd"), trans.password())(autocomplete := "off"), + form3.actions(frag( + a(href := routes.User.show(u.username))(trans.changedMindDoNotCloseAccount()), + form3.submit( + trans.closeAccount(), + icon = "j".some, + confirm = "Closing is definitive. There is no going back. Are you sure?".some, + klass = "button-red" ) - ) + )) ) - } + ) + } } diff --git a/app/views/account/email.scala b/app/views/account/email.scala new file mode 100644 index 0000000000..43f45103fb --- /dev/null +++ b/app/views/account/email.scala @@ -0,0 +1,29 @@ +package views.html +package account + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object email { + + def apply(u: lila.user.User, form: play.api.data.Form[_])(implicit ctx: Context) = account.layout( + title = trans.changeEmail.txt(), + active = "email" + ) { + div(cls := "account box box-pad")( + h1( + trans.changeEmail(), + ctx.req.queryString.contains("ok") option + frag(" ", i(cls := "is-green", dataIcon := "E")) + ), + st.form(cls := "form3", action := routes.Account.emailApply, method := "POST")( + form3.password(form("passwd"), trans.password()), + form3.group(form("email"), trans.email())(form3.input(_, typ = "email")(required)), + form3.action(form3.submit(trans.apply())) + ) + ) + } +} diff --git a/app/views/account/email.scala.html b/app/views/account/email.scala.html deleted file mode 100644 index 92976144fd..0000000000 --- a/app/views/account/email.scala.html +++ /dev/null @@ -1,18 +0,0 @@ -@(u: User, form: Form[_])(implicit ctx: Context) -@import lila.app.ui.ScalatagsTwirlForm._ - -@account.layout(title = s"${u.username} - ${trans.changeEmail.txt()}", active = "email", evenMoreCss = cssTag("form3.css")) { -
- -
-}.toHtml diff --git a/app/views/account/emailConfirmHelp.scala b/app/views/account/emailConfirmHelp.scala index 7c854c5670..0347da6c13 100644 --- a/app/views/account/emailConfirmHelp.scala +++ b/app/views/account/emailConfirmHelp.scala @@ -16,23 +16,23 @@ object emailConfirmHelp { def apply(form: Form[_], status: Option[Status])(implicit ctx: Context) = views.html.base.layout( title = title, - moreCss = cssTags("form3.css", "emailConfirmHelp.css"), + moreCss = cssTag("email-confirm"), moreJs = jsTag("emailConfirmHelp.js") )(frag( - div(cls := "content_box small_box emailConfirmHelp")( - h1(cls := "lichess_title")(title), + main(cls := "page-small box box-pad email-confirm-help")( + h1(title), p("You signed up, but didn't receive your confirmation email?"), st.form(cls := "form3", action := routes.Account.emailConfirmHelp, method := "get")( form3.split( form3.group( form("username"), - trans.username.frag(), + trans.username(), help = raw("What username did you create?").some ) { f => form3.input(f)(pattern := lila.user.User.newUsernameRegex.regex) }, div(cls := "form-group")( - form3.submit(trans.apply.frag()) + form3.submit(trans.apply()) ) ) ), diff --git a/app/views/account/kid.scala b/app/views/account/kid.scala index 0b5b0a08ed..7fd96b9a04 100644 --- a/app/views/account/kid.scala +++ b/app/views/account/kid.scala @@ -13,20 +13,25 @@ object kid { title = s"${u.username} - ${trans.kidMode.txt()}", active = "kid" ) { - div(cls := "content_box small_box high")( - div(cls := "signup_box")( - h1(cls := "lichess_title")(trans.kidMode.frag()), - p(cls := "explanation")(trans.kidModeExplanation.frag()), - br, - br, - br, - st.form(action := s"${routes.Account.kidPost}?v=${!u.kid}", method := "POST")( - input(tpe := "submit", cls := "submit button", value := (if (u.kid) { trans.disableKidMode.txt() } else { trans.enableKidMode.txt() })) - ), - br, - br, - p(trans.inKidModeTheLichessLogoGetsIconX.frag(raw(s"""😊"""))) - ) + div(cls := "account box box-pad")( + h1(trans.kidMode()), + p(trans.kidModeExplanation()), + br, + br, + br, + st.form(action := s"${routes.Account.kidPost}?v=${!u.kid}", method := "POST")( + input( + tpe := "submit", + cls := List( + "button" -> true, + "button-red" -> u.kid + ), + value := (if (u.kid) { trans.disableKidMode.txt() } else { trans.enableKidMode.txt() }) + ) + ), + br, + br, + p(trans.inKidModeTheLichessLogoGetsIconX(span(cls := "kiddo", title := trans.kidMode.txt())(":)"))) ) } } diff --git a/app/views/account/layout.scala b/app/views/account/layout.scala index f1df883e85..786c50a09f 100644 --- a/app/views/account/layout.scala +++ b/app/views/account/layout.scala @@ -1,7 +1,4 @@ -package views.html -package account - -import play.twirl.api.Html +package views.html.account import lila.api.Context import lila.app.templating.Environment._ @@ -14,53 +11,58 @@ object layout { def apply( title: String, active: String, - evenMoreCss: Html = emptyHtml, - evenMoreJs: Html = emptyHtml - )(body: Html)(implicit ctx: Context) = views.html.base.layout( + evenMoreCss: Frag = emptyFrag, + evenMoreJs: Frag = emptyFrag + )(body: Frag)(implicit ctx: Context): Frag = views.html.base.layout( title = title, - menu = Some(frag( - lila.pref.PrefCateg.all.map { categ => - a(cls := active.activeO(categ.slug), href := routes.Pref.form(categ.slug))( - bits.categName(categ) - ) - }, - a(cls := active.activeO("kid"), href := routes.Account.kid())( - trans.kidMode.frag() - ), - div(cls := "sep"), - a(cls := active.activeO("editProfile"), href := routes.Account.profile())( - trans.editProfile.frag() - ), - isGranted(_.Coach) option a(href := routes.Coach.edit)("Coach profile"), - div(cls := "sep"), - a(cls := active.activeO("username"), href := routes.Account.username())( - trans.changeUsername.frag() - ), - a(cls := active.activeO("password"), href := routes.Account.passwd())( - trans.changePassword.frag() - ), - a(cls := active.activeO("email"), href := routes.Account.email())( - trans.changeEmail.frag() - ), - a(cls := active.activeO("twofactor"), href := routes.Account.twoFactor())( - "Two-factor authentication" - ), - a(cls := active.activeO("security"), href := routes.Account.security())( - trans.security.frag() - ), - div(cls := "sep"), - a(href := routes.Plan.index, style := "color: #d59120; font-weight: bold;")("Patron"), - div(cls := "sep"), - a(cls := active.activeO("oauth.token"), href := routes.OAuthToken.index)( - "API Access tokens" - ), - ctx.noBot option a(cls := active.activeO("oauth.app"), href := routes.OAuthApp.index)("OAuth Apps"), - div(cls := "sep"), - a(cls := active.activeO("close"), href := routes.Account.close())( - trans.closeAccount.frag() - ) - )), - moreCss = frag(cssTag("account.css"), evenMoreCss), + moreCss = frag(cssTag("account"), evenMoreCss), moreJs = frag(jsTag("account.js"), evenMoreJs) - )(body) + ) { + def activeCls(c: String) = cls := active.activeO(c) + main(cls := "account page-menu")( + st.nav(cls := "page-menu__menu subnav")( + lila.pref.PrefCateg.all.map { categ => + a(activeCls(categ.slug), href := routes.Pref.form(categ.slug))( + bits.categName(categ) + ) + }, + a(activeCls("kid"), href := routes.Account.kid())( + trans.kidMode() + ), + div(cls := "sep"), + a(activeCls("editProfile"), href := routes.Account.profile())( + trans.editProfile() + ), + isGranted(_.Coach) option a(activeCls("coach"), href := routes.Coach.edit)("Coach profile"), + div(cls := "sep"), + a(activeCls("password"), href := routes.Account.passwd())( + trans.changePassword() + ), + a(activeCls("email"), href := routes.Account.email())( + trans.changeEmail() + ), + a(activeCls("username"), href := routes.Account.username())( + trans.changeUsername() + ), + a(activeCls("twofactor"), href := routes.Account.twoFactor())( + "Two-factor authentication" + ), + a(activeCls("security"), href := routes.Account.security())( + trans.security() + ), + div(cls := "sep"), + a(href := routes.Plan.index)("Patron"), + div(cls := "sep"), + a(activeCls("oauth.token"), href := routes.OAuthToken.index)( + "API Access tokens" + ), + ctx.noBot option a(activeCls("oauth.app"), href := routes.OAuthApp.index)("OAuth Apps"), + div(cls := "sep"), + a(activeCls("close"), href := routes.Account.close())( + trans.closeAccount() + ) + ), + div(cls := "page-menu__content")(body) + ) + } } diff --git a/app/views/account/passwd.scala b/app/views/account/passwd.scala index 22b298993b..1fe0c9a4b3 100644 --- a/app/views/account/passwd.scala +++ b/app/views/account/passwd.scala @@ -11,21 +11,19 @@ object passwd { def apply(form: play.api.data.Form[_])(implicit ctx: Context) = account.layout( title = trans.changePassword.txt(), - active = "password", - evenMoreCss = cssTag("form3.css") + active = "password" ) { - div(cls := "content_box small_box")( - div(cls := "signup_box")( - h1(cls := "lichess_title")( - trans.changePassword.frag(), - raw(ctx.req.queryString.contains("ok") ?? """ """) - ), - st.form(cls := "form3", action := routes.Account.passwdApply, method := "POST")( - form3.password(form("oldPasswd"), trans.currentPassword.frag()), - form3.password(form("newPasswd1"), trans.newPassword.frag()), - form3.password(form("newPasswd2"), trans.newPasswordAgain.frag()), - form3.actionHtml(form3.submit(trans.apply.frag())) - ) + div(cls := "account box box-pad")( + h1( + trans.changePassword(), + ctx.req.queryString.contains("ok") option + frag(" ", i(cls := "is-green", dataIcon := "E")) + ), + st.form(cls := "form3", action := routes.Account.passwdApply, method := "POST")( + form3.password(form("oldPasswd"), trans.currentPassword()), + form3.password(form("newPasswd1"), trans.newPassword()), + form3.password(form("newPasswd2"), trans.newPasswordAgain()), + form3.action(form3.submit(trans.apply())) ) ) } diff --git a/app/views/account/pref.scala b/app/views/account/pref.scala index 2e60b230b2..32ad8f790a 100644 --- a/app/views/account/pref.scala +++ b/app/views/account/pref.scala @@ -10,10 +10,10 @@ import controllers.routes object pref { - private def categFieldset(categ: lila.pref.PrefCateg, active: lila.pref.PrefCateg)(body: Frag) = - div(cls := List("none" -> (categ != active)))(body) + private def categFieldset(categ: lila.pref.PrefCateg, active: lila.pref.PrefCateg) = + div(cls := List("none" -> (categ != active))) - private def setting(name: Frag, body: Frag) = li(h2(name), body) + private def setting(name: Frag, body: Frag) = st.section(h2(name), body) private def radios(field: play.api.data.Field, options: Iterable[(Any, String)], prefix: String = "ir") = st.group(cls := "radio")( @@ -23,7 +23,7 @@ object pref { div( input( st.id := s"$prefix$id", - st.checked := checked option true, + checked option st.checked, cls := checked option "active", `type` := "radio", value := v._1.toString, @@ -36,137 +36,130 @@ object pref { def apply(u: lila.user.User, form: play.api.data.Form[_], categ: lila.pref.PrefCateg)(implicit ctx: Context) = account.layout( title = s"${bits.categName(categ)} - ${u.username} - ${trans.preferences.txt()}", - active = categ.slug, - evenMoreCss = cssTag("pref.css") + active = categ.slug ) { - val booleanChoices = Seq(0 -> trans.no.txt(), 1 -> trans.yes.txt()) - div(cls := "content_box small_box prefs")( - div(cls := "signup_box")( - h1(cls := "lichess_title text", dataIcon := "%")(bits.categName(categ)), - st.form(cls := "autosubmit", action := routes.Pref.formApply, method := "POST")( - categFieldset(PrefCateg.GameDisplay, categ) { - ul( - setting( - trans.pieceAnimation.frag(), - radios(form("display.animation"), translatedAnimationChoices) - ), - setting( - trans.materialDifference.frag(), - radios(form("display.captured"), booleanChoices) - ), - setting( - trans.boardHighlights.frag(), - radios(form("display.highlight"), booleanChoices) - ), - setting( - trans.pieceDestinations.frag(), - radios(form("display.destination"), booleanChoices) - ), - setting( - trans.boardCoordinates.frag(), - radios(form("display.coords"), translatedBoardCoordinateChoices) - ), - setting( - trans.moveListWhilePlaying.frag(), - radios(form("display.replay"), translatedMoveListWhilePlayingChoices) - ), - setting( - trans.pgnPieceNotation.frag(), - radios(form("display.pieceNotation"), translatedPieceNotationChoices) - ), - setting( - trans.zenMode.frag(), - radios(form("display.zen"), booleanChoices) - ), - setting( - trans.blindfoldChess.frag(), - radios(form("display.blindfold"), translatedBlindfoldChoices) - ) - ) - }, - categFieldset(PrefCateg.ChessClock, categ) { - ul( - setting( - trans.tenthsOfSeconds.frag(), - radios(form("clockTenths"), translatedClockTenthsChoices) - ), - setting( - trans.horizontalGreenProgressBars.frag(), - radios(form("clockBar"), booleanChoices) - ), - setting( - trans.soundWhenTimeGetsCritical.frag(), - radios(form("clockSound"), booleanChoices) - ) - ) - }, - categFieldset(PrefCateg.GameBehavior, categ) { - ul( - setting( - trans.howDoYouMovePieces.frag(), - radios(form("behavior.moveEvent"), translatedMoveEventChoices) - ), - setting( - trans.premovesPlayingDuringOpponentTurn.frag(), - radios(form("behavior.premove"), booleanChoices) - ), - setting( - trans.takebacksWithOpponentApproval.frag(), - radios(form("behavior.takeback"), translatedTakebackChoices) - ), - setting( - trans.promoteToQueenAutomatically.frag(), - radios(form("behavior.autoQueen"), translatedAutoQueenChoices) - ), - setting( - trans.claimDrawOnThreefoldRepetitionAutomatically.frag(), - radios(form("behavior.autoThreefold"), translatedAutoThreefoldChoices) - ), - setting( - trans.moveConfirmation.frag(), - radios(form("behavior.submitMove"), submitMoveChoices) - ), - setting( - trans.confirmResignationAndDrawOffers.frag(), - radios(form("behavior.confirmResign"), confirmResignChoices) - ), - setting( - trans.inputMovesWithTheKeyboard.frag(), - radios(form("behavior.keyboardMove"), booleanChoices) - ), - setting( - trans.castleByMovingTheKingTwoSquaresOrOntoTheRook.frag(), - radios(form("behavior.rookCastle"), translatedRookCastleChoices) - ) - ) - }, - categFieldset(PrefCateg.Privacy, categ) { - ul( - setting( - trans.letOtherPlayersFollowYou.frag(), - radios(form("follow"), booleanChoices) - ), - setting( - trans.letOtherPlayersChallengeYou.frag(), - radios(form("challenge"), translatedChallengeChoices) - ), - setting( - trans.letOtherPlayersMessageYou.frag(), - radios(form("message"), translatedMessageChoices) - ), - setting( - trans.letOtherPlayersInviteYouToStudy.frag(), - radios(form("studyInvite"), translatedStudyInviteChoices) - ), - setting( - trans.shareYourInsightsData.frag(), - radios(form("insightShare"), translatedInsightSquareChoices) - ) - ) - }, - p(cls := "saved text none", dataIcon := "E")(trans.yourPreferencesHaveBeenSaved.frag()) + val booleanChoices = Seq(0 -> trans.no.txt(), 1 -> trans.yes.txt()) + div(cls := "account box box-pad")( + h1(bits.categName(categ)), + st.form(cls := "autosubmit", action := routes.Pref.formApply, method := "POST")( + categFieldset(PrefCateg.GameDisplay, categ)( + setting( + trans.pieceAnimation(), + radios(form("display.animation"), translatedAnimationChoices) + ), + setting( + trans.materialDifference(), + radios(form("display.captured"), booleanChoices) + ), + setting( + trans.boardHighlights(), + radios(form("display.highlight"), booleanChoices) + ), + setting( + trans.pieceDestinations(), + radios(form("display.destination"), booleanChoices) + ), + setting( + trans.boardCoordinates(), + radios(form("display.coords"), translatedBoardCoordinateChoices) + ), + setting( + trans.moveListWhilePlaying(), + radios(form("display.replay"), translatedMoveListWhilePlayingChoices) + ), + setting( + trans.pgnPieceNotation(), + radios(form("display.pieceNotation"), translatedPieceNotationChoices) + ), + setting( + trans.zenMode(), + radios(form("display.zen"), booleanChoices) + ), + setting( + "Display board resize handle", + radios(form("display.resizeHandle"), translatedBoardResizeHandleChoices) + ), + setting( + trans.blindfoldChess(), + radios(form("display.blindfold"), translatedBlindfoldChoices) ) - ) + ), + categFieldset(PrefCateg.ChessClock, categ)( + setting( + trans.tenthsOfSeconds(), + radios(form("clockTenths"), translatedClockTenthsChoices) + ), + setting( + trans.horizontalGreenProgressBars(), + radios(form("clockBar"), booleanChoices) + ), + setting( + trans.soundWhenTimeGetsCritical(), + radios(form("clockSound"), booleanChoices) + ) + ), + categFieldset(PrefCateg.GameBehavior, categ)( + setting( + trans.howDoYouMovePieces(), + radios(form("behavior.moveEvent"), translatedMoveEventChoices) + ), + setting( + trans.premovesPlayingDuringOpponentTurn(), + radios(form("behavior.premove"), booleanChoices) + ), + setting( + trans.takebacksWithOpponentApproval(), + radios(form("behavior.takeback"), translatedTakebackChoices) + ), + setting( + trans.promoteToQueenAutomatically(), + radios(form("behavior.autoQueen"), translatedAutoQueenChoices) + ), + setting( + trans.claimDrawOnThreefoldRepetitionAutomatically(), + radios(form("behavior.autoThreefold"), translatedAutoThreefoldChoices) + ), + setting( + trans.moveConfirmation(), + radios(form("behavior.submitMove"), submitMoveChoices) + ), + setting( + trans.confirmResignationAndDrawOffers(), + radios(form("behavior.confirmResign"), confirmResignChoices) + ), + setting( + trans.castleByMovingTheKingTwoSquaresOrOntoTheRook(), + radios(form("behavior.rookCastle"), translatedRookCastleChoices) + ), + setting( + trans.inputMovesWithTheKeyboard(), + radios(form("behavior.keyboardMove"), booleanChoices) + ) + ), + categFieldset(PrefCateg.Privacy, categ)( + setting( + trans.letOtherPlayersFollowYou(), + radios(form("follow"), booleanChoices) + ), + setting( + trans.letOtherPlayersChallengeYou(), + radios(form("challenge"), translatedChallengeChoices) + ), + setting( + trans.letOtherPlayersMessageYou(), + radios(form("message"), translatedMessageChoices) + ), + setting( + trans.letOtherPlayersInviteYouToStudy(), + radios(form("studyInvite"), translatedStudyInviteChoices) + ), + setting( + trans.shareYourInsightsData(), + radios(form("insightShare"), translatedInsightSquareChoices) + ) + ), + p(cls := "saved text none", dataIcon := "E")(trans.yourPreferencesHaveBeenSaved()) ) - } + ) + } } diff --git a/app/views/account/profile.scala b/app/views/account/profile.scala index 9e13d79966..14c8ff7045 100644 --- a/app/views/account/profile.scala +++ b/app/views/account/profile.scala @@ -17,38 +17,37 @@ object profile { def apply(u: lila.user.User, form: play.api.data.Form[_])(implicit ctx: Context) = account.layout( title = s"${u.username} - ${trans.editProfile.txt()}", - active = "editProfile", - evenMoreCss = cssTag("form3.css") + active = "editProfile" ) { - div(cls := "content_box small_box")( - h1(cls := "lichess_title text", dataIcon := "*")(trans.editProfile()), - st.form(cls := "form3", action := routes.Account.profileApply, method := "POST")( - div(cls := "form-group")(trans.allInformationIsPublicAndOptional()), - form3.split( - form3.group(form("country"), trans.country.frag(), half = true) { f => - form3.select(f, lila.user.Countries.allPairs, default = "".some) - }, - form3.group(form("location"), trans.location.frag(), half = true)(form3.input(_)) - ), - NotForKids { - form3.group(form("bio"), trans.biography.frag(), help = trans.biographyDescription.frag().some) { f => - form3.textarea(f)(rows := 5) - } + div(cls := "account box box-pad")( + h1(trans.editProfile()), + st.form(cls := "form3", action := routes.Account.profileApply, method := "POST")( + div(cls := "form-group")(trans.allInformationIsPublicAndOptional()), + form3.split( + form3.group(form("country"), trans.country(), half = true) { f => + form3.select(f, lila.user.Countries.allPairs, default = "".some) }, - form3.split( - form3.group(form("firstName"), trans.firstName.frag(), half = true)(form3.input(_)), - form3.group(form("lastName"), trans.lastName.frag(), half = true)(form3.input(_)) - ), - form3.split( - List("fide", "uscf", "ecf").map { rn => - form3.group(form(s"${rn}Rating"), trans.xRating.frag(rn.toUpperCase), help = trans.ifNoneLeaveEmpty.frag().some, klass = "form-third")(form3.input(_, typ = "number")) - } - ), - form3.group(form("links"), raw("Social media links "), help = Some(linksHelp)) { f => + form3.group(form("location"), trans.location(), half = true)(form3.input(_)) + ), + NotForKids { + form3.group(form("bio"), trans.biography(), help = trans.biographyDescription().some) { f => form3.textarea(f)(rows := 5) - }, - form3.actionHtml(form3.submit(trans.apply.frag())) - ) + } + }, + form3.split( + form3.group(form("firstName"), trans.firstName(), half = true)(form3.input(_)), + form3.group(form("lastName"), trans.lastName(), half = true)(form3.input(_)) + ), + form3.split( + List("fide", "uscf", "ecf").map { rn => + form3.group(form(s"${rn}Rating"), trans.xRating(rn.toUpperCase), help = trans.ifNoneLeaveEmpty().some, klass = "form-third")(form3.input(_, typ = "number")) + } + ), + form3.group(form("links"), raw("Social media links "), help = Some(linksHelp)) { f => + form3.textarea(f)(rows := 5) + }, + form3.action(form3.submit(trans.apply())) ) - } + ) + } } diff --git a/app/views/account/security.scala b/app/views/account/security.scala new file mode 100644 index 0000000000..5ae6762eaa --- /dev/null +++ b/app/views/account/security.scala @@ -0,0 +1,60 @@ +package views.html +package account + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object security { + + def apply(u: lila.user.User, sessions: List[lila.security.LocatedSession], curSessionId: String)(implicit ctx: Context) = + account.layout(title = s"${u.username} - ${trans.security.txt()}", active = "security") { + div(cls := "account security box")( + h1(trans.security()), + div(cls := "box__pad")( + p(trans.thisIsAListOfDevicesThatHaveLoggedIntoYourAccount()), + sessions.length > 1 option div( + trans.alternativelyYouCanX { + form(cls := "revoke-all", action := routes.Account.signout("all"), method := "POST")( + button(tpe := "submit", cls := "button button-empty button-red confirm")( + trans.revokeAllSessions() + ) + ) + } + ) + ), + table(cls := "slist slist-pad")( + sessions.map { s => + tr( + td(cls := "icon")( + span( + cls := s"is-${if (s.session.id == curSessionId) "gold" else "green"}", + dataIcon := (if (s.session.isMobile) "" else "") + ) + ), + td(cls := "info")( + span(cls := "ip")(s.session.ip), + " ", + span(cls := "location")(s.location.map(_.toString)), + p(cls := "ua")(s.session.ua), + s.session.date.map { date => + p(cls := "date")( + momentFromNow(date), + s.session.id == curSessionId option span(cls := "current")("[CURRENT]") + ) + } + ), + td( + s.session.id != curSessionId option + form(action := routes.Account.signout(s.session.id), method := "POST")( + button(tpe := "submit", cls := "button button-red", title := trans.logOut.txt(), dataIcon := "L") + ) + ) + ) + } + ) + ) + } +} diff --git a/app/views/account/security.scala.html b/app/views/account/security.scala.html deleted file mode 100644 index ca46f54d00..0000000000 --- a/app/views/account/security.scala.html +++ /dev/null @@ -1,50 +0,0 @@ -@(u: User, sessions: List[lila.security.LocatedSession], curSessionId: String)(implicit ctx: Context) - -@title = @{ s"${u.username} - ${trans.security.txt()}" } - -@account.layout(title = title, active = "security") { -
- -
-}.toHtml diff --git a/app/views/account/twoFactor.scala b/app/views/account/twoFactor.scala index 6a49e02044..ad5bdb4421 100644 --- a/app/views/account/twoFactor.scala +++ b/app/views/account/twoFactor.scala @@ -9,19 +9,18 @@ import controllers.routes object twoFactor { - private val qrCode = raw("""
""") + private val qrCode = raw("""
""") def setup(u: lila.user.User, form: play.api.data.Form[_])(implicit ctx: Context) = account.layout( title = s"${u.username} - Two-factor authentication", active = "twofactor", - evenMoreCss = cssTag("form3.css"), evenMoreJs = frag( jsAt("javascripts/vendor/qrcode.min.js"), jsTag("twofactor.form.js") ) ) { - div(cls := "content_box small_box high twofactor")( - h1(cls := "lichess_title")("Setup two-factor authentication"), + div(cls := "account twofactor box box-pad")( + h1("Setup two-factor authentication"), st.form(cls := "form3", action := routes.Account.setupTwoFactor, method := "POST")( div(cls := "form-group")("Two-factor authentication adds another layer of security to your account."), div(cls := "form-group")( @@ -31,35 +30,34 @@ object twoFactor { qrCode, div(cls := "form-group explanation")("Enter your password and the authentication code generated by the app to complete the setup. You will need an authentication code every time you log in."), form3.hidden(form("secret")), - form3.password(form("passwd"), trans.password.frag()), - form3.group(form("token"), raw("Authentication code"))(form3.input(_)(pattern := "[0-9]{6}", autocomplete := "off", required := "")), + form3.password(form("passwd"), trans.password()), + form3.group(form("token"), raw("Authentication code"))(form3.input(_)(pattern := "[0-9]{6}", autocomplete := "off", required)), form3.globalError(form), div(cls := "form-group")("Note: If you lose access to your two-factor authentication codes, you can do a password reset via email."), - form3.actionHtml(form3.submit(raw("Enable two-factor authentication"))) + form3.action(form3.submit(raw("Enable two-factor authentication"))) ) ) } def disable(u: lila.user.User, form: play.api.data.Form[_])(implicit ctx: Context) = account.layout( title = s"${u.username} - Two-factor authentication", - active = "twofactor", - evenMoreCss = cssTag("form3.css") + active = "twofactor" ) { - div(cls := "content_box small_box high twofactor")( - h1(cls := "lichess_title")( - raw(""" """), - "Two-factor authentication enabled" + div(cls := "account twofactor box box-pad")( + h1( + i(cls := "is-green", dataIcon := "E"), + " Two-factor authentication enabled" + ), + p("Your account is protected with two-factor authentication."), + st.form(cls := "form3", action := routes.Account.disableTwoFactor, method := "POST")( + p( + "You need your password and an authentication code from your authenticator app to disable two-factor authentication. ", + "If you lost access to your authentication codes, you can also do a password reset via email." ), - p(cls := "explanation")("Your account is protected with two-factor authentication."), - st.form(cls := "form3", action := routes.Account.disableTwoFactor, method := "POST")( - p(cls := "explanation")( - "You need your password and an authentication code from your authenticator app to disable two-factor authentication. ", - "If you lost access to your authentication codes, you can also do a password reset via email." - ), - form3.password(form("passwd"), trans.password.frag()), - form3.group(form("token"), raw("Authentication code"))(form3.input(_)(pattern := "[0-9]{6}", autocomplete := "off", required := "")), - form3.actionHtml(form3.submit(raw("Disable two-factor authentication"), icon = None)) - ) + form3.password(form("passwd"), trans.password()), + form3.group(form("token"), raw("Authentication code"))(form3.input(_)(pattern := "[0-9]{6}", autocomplete := "off", required)), + form3.action(form3.submit(raw("Disable two-factor authentication"), icon = None)) ) - } + ) + } } diff --git a/app/views/account/username.scala b/app/views/account/username.scala index c7d544cf0d..d3054f1362 100644 --- a/app/views/account/username.scala +++ b/app/views/account/username.scala @@ -11,16 +11,15 @@ object username { def apply(u: lila.user.User, form: play.api.data.Form[_])(implicit ctx: Context) = account.layout( title = s"${u.username} - ${trans.editProfile.txt()}", - active = "editUsername", - evenMoreCss = cssTag("form3.css") + active = "username" ) { - div(cls := "content_box small_box")( - h1(cls := "lichess_title text", dataIcon := "*")(trans.editProfile()), - st.form(cls := "form3", action := routes.Account.usernameApply, method := "POST")( - form3.globalError(form), - form3.group(form("userName"), trans.username.frag(), half = true, help = trans.changeUsernameDescription.frag().some)(form3.input(_)), - form3.actionHtml(form3.submit(trans.apply.frag())) - ) + div(cls := "account box box-pad")( + h1(cls := "text", dataIcon := "*")(trans.changeUsername()), + st.form(cls := "form3", action := routes.Account.usernameApply, method := "POST")( + form3.globalError(form), + form3.group(form("username"), trans.username(), help = trans.changeUsernameDescription().some)(form3.input(_)(required)), + form3.action(form3.submit(trans.apply())) ) - } + ) + } } diff --git a/app/views/activity.scala b/app/views/activity.scala index 9a4b5e3acf..e84e15357d 100644 --- a/app/views/activity.scala +++ b/app/views/activity.scala @@ -1,14 +1,10 @@ package views.html -import play.twirl.api.Html -import scalatags.Text.tags2.section - import lila.activity.activities._ import lila.activity.model._ import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ -import lila.common.String.html.escapeHtml import lila.user.User import controllers.routes @@ -18,7 +14,7 @@ object activity { def apply(u: User, as: Iterable[lila.activity.ActivityView])(implicit ctx: Context) = div(cls := "activity")( as.toSeq map { a => - section( + st.section( h2(semanticDate(a.interval.getStart)), div(cls := "entries")( a.patron map renderPatron, @@ -49,7 +45,9 @@ object activity { private def renderPatron(p: Patron)(implicit ctx: Context) = div(cls := "entry plan")( iconTag(""), - div(trans.activity.supportedNbMonths.plural(p.months, p.months, Html(s"""Patron"""))) + div( + trans.activity.supportedNbMonths.plural(p.months, p.months, a(href := routes.Plan.index)("Patron")) + ) ) private def renderPractice(p: Map[lila.practice.PracticeStudy, Int])(implicit ctx: Context) = { @@ -70,7 +68,7 @@ object activity { case (study, nb) => val href = routes.Practice.show("-", study.slug, study.id.value) frag( - trans.activity.practicedNbPositions.plural(nb, nb, Html(s"""${study.name}""")), + trans.activity.practicedNbPositions.plural(nb, nb, a(st.href := href)(study.name)), br ) } @@ -105,9 +103,8 @@ object activity { posts.toSeq.map { case (topic, posts) => val url = routes.ForumTopic.show(topic.categId, topic.slug) - val content = escapeHtml(shorten(topic.name, 70)) frag( - trans.activity.postedNbMessages.plural(posts.size, posts.size, Html(s"""$content""")), + trans.activity.postedNbMessages.plural(posts.size, posts.size, a(href := url)(shorten(topic.name, 70))), subTag( posts.map { post => div(cls := "line")(a(href := routes.ForumPost.redirect(post.id))(shorten(post.text, 120))) @@ -173,7 +170,7 @@ object activity { if (in) trans.activity.gainedNbFollowers.pluralSame(f.actualNb) else trans.activity.followedNbPlayers.pluralSame(f.actualNb), subTag( - htmlList(f.ids.map(id => userIdLink(id.some))), + fragList(f.ids.map(id => userIdLink(id.some))), f.nb.map { nb => frag(" and ", nb - maxSubEntries, " more") } @@ -185,7 +182,7 @@ object activity { private def renderSimuls(u: User)(simuls: List[lila.simul.Simul])(implicit ctx: Context) = entryTag( - iconTag("|"), + iconTag("f"), div( simuls.groupBy(_.isHost(u.some)).toSeq.map { case (isHost, simuls) => frag( @@ -226,7 +223,7 @@ object activity { iconTag("f"), div( trans.activity.joinedNbTeams.pluralSame(teams.value.size), - subTag(htmlList(teams.value.map(id => teamLink(id)))) + subTag(fragList(teams.value.map(id => teamLink(id)))) ) ) @@ -245,7 +242,7 @@ object activity { ), dataIcon := (t.rank <= 3).option("g") )( - trans.activity.rankedInTournament.plural(t.nbGames, Html(s"""${t.rank}"""), (t.rankRatio.value * 100).toInt atLeast 1, t.nbGames, link), + trans.activity.rankedInTournament.plural(t.nbGames, strong(t.rank), (t.rankRatio.value * 100).toInt atLeast 1, t.nbGames, link), br ) } @@ -273,10 +270,10 @@ object activity { s"""${scoreStr("win", s.win, trans.nbWins)}${scoreStr("draw", s.draw, trans.nbDraws)}${scoreStr("loss", s.loss, trans.nbLosses)}""" } - private def ratingProgFrag(r: RatingProg)(implicit ctx: Context) = raw { - val prog = showProgress(r.diff, withTitle = false) - s"""${r.after.value}$prog""" - } + private def ratingProgFrag(r: RatingProg)(implicit ctx: Context) = ratingTag( + r.after.value, + ratingProgress(r.diff) + ) private def scoreStr(tag: String, p: Int, name: lila.i18n.I18nKey)(implicit ctx: Context) = if (p == 0) "" diff --git a/app/views/analyse/bits.scala b/app/views/analyse/bits.scala index c6df184f73..7a5235e658 100644 --- a/app/views/analyse/bits.scala +++ b/app/views/analyse/bits.scala @@ -1,11 +1,9 @@ package views.html.analyse -import play.twirl.api.Html - +import lila.analyse.Advice.Judgement import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ -import lila.analyse.Advice.Judgement object bits { @@ -20,18 +18,12 @@ object bits { def layout( title: String, - side: Option[Frag] = None, - chat: Option[Frag] = None, - underchat: Option[Frag] = None, - moreCss: Html = emptyHtml, - moreJs: Html = emptyHtml, + moreCss: Frag = emptyFrag, + moreJs: Frag = emptyFrag, openGraph: Option[lila.app.ui.OpenGraph] = None - )(body: Html)(implicit ctx: Context): Frag = + )(body: Frag)(implicit ctx: Context): Frag = views.html.base.layout( title = title, - side = side.map(_.toHtml), - chat = chat, - underchat = underchat, moreCss = moreCss, moreJs = moreJs, openGraph = openGraph, diff --git a/app/views/analyse/embed.scala b/app/views/analyse/embed.scala index 71a0510e26..31c8362865 100644 --- a/app/views/analyse/embed.scala +++ b/app/views/analyse/embed.scala @@ -1,44 +1,36 @@ package views.html.analyse -import play.api.libs.json.Json -import scalatags.Text.tags2.{ title => titleTag } +import play.api.libs.json.{ Json, JsObject } +import play.api.mvc.RequestHeader -import lila.api.Context import lila.app.templating.Environment._ +import lila.app.ui.EmbedConfig import lila.app.ui.ScalatagsTemplate._ import lila.common.String.html.safeJsonValue +import views.html.base.layout.{ bits => layout } import controllers.routes object embed { - import views.html.base.layout.bits._ + import EmbedConfig.implicits._ - private def bodyClass(implicit ctx: Context) = List( - "base" -> true, - ctx.currentTheme.cssClass -> true, - (if (ctx.currentBg == "transp") "dark transp" else ctx.currentBg) -> true - ) - - def apply(pov: lila.game.Pov, data: play.api.libs.json.JsObject)(implicit ctx: Context) = frag( - doctype, - htmlTag(ctx)( - topComment, + def apply(pov: lila.game.Pov, data: JsObject)(implicit config: EmbedConfig) = frag( + layout.doctype, + layout.htmlTag(config.lang)( head( - charset, - metaCsp(none), - titleTag(s"${playerText(pov.game.whitePlayer)} vs ${playerText(pov.game.blackPlayer)} in ${pov.gameId} : ${pov.game.opening.fold(trans.analysis.txt())(_.opening.ecoName)}"), - fontStylesheets, - currentBgCss, - cssTags("common.css", "board.css", "analyse.css", "analyse-embed.css"), - pieceSprite + layout.charset, + layout.viewport, + layout.metaCsp(basicCsp withNonce config.nonce), + st.headTitle(replay titleOf pov), + layout.pieceSprite(lila.pref.PieceSet.default), + cssTagWithTheme("analyse.embed", config.bg) ), - body(cls := bodyClass ::: List( - "highlight" -> true, - "piece_letter" -> ctx.pref.pieceNotationIsLetter + body(cls := List( + s"highlight ${config.bg} ${config.board}" -> true ))( div(cls := "is2d")( - div(cls := "embedded_analyse analyse cg-512")(miniBoardContent) + main(cls := "analyse") ), footer { val url = routes.Round.watcher(pov.gameId, pov.color.name) @@ -55,32 +47,31 @@ object embed { jsTag("vendor/mousetrap.js"), jsAt("compiled/util.js"), jsAt("compiled/trans.js"), + jsAt("compiled/embed-analyse.js"), analyseTag, - jsTag("embed-analyse.js"), - embedJs(s"""lichess.startEmbeddedAnalyse({ -element: document.querySelector('.embedded_analyse'), -data: ${safeJsonValue(data)}, -embed: true, -i18n: ${views.html.board.userAnalysisI18n(withCeval = false, withExplorer = false)} -});""") + embedJsUnsafe(s"""lichess.startEmbeddedAnalyse(${ + safeJsonValue(Json.obj( + "data" -> data, + "embed" -> true, + "i18n" -> views.html.board.userAnalysisI18n(withCeval = false, withExplorer = false) + )) + })""", config.nonce) ) ) ) - def notFound()(implicit ctx: Context) = frag( - doctype, - htmlTag(ctx)( - topComment, + def notFound(implicit config: EmbedConfig) = frag( + layout.doctype, + layout.htmlTag(config.lang)( head( - charset, - metaCsp(none), - titleTag("404 - Game not found"), - fontStylesheets, - currentBgCss, - cssTags("common.css", "analyse-embed.css") + layout.charset, + layout.viewport, + layout.metaCsp(basicCsp), + st.headTitle("404 - Game not found"), + cssTagWithTheme("analyse.round.embed", "dark") ), - body(cls := bodyClass)( - div(cls := "not_found")( + body(cls := "dark")( + div(cls := "not-found")( h1("Game not found") ) ) diff --git a/app/views/analyse/help.scala b/app/views/analyse/help.scala index a1702936ed..e5b7437924 100644 --- a/app/views/analyse/help.scala +++ b/app/views/analyse/help.scala @@ -19,7 +19,7 @@ object help { private def k(str: String) = raw(s"""$str""") def apply(isStudy: Boolean)(implicit ctx: Context) = frag( - h2(trans.keyboardShortcuts.frag()), + h2(trans.keyboardShortcuts()), table( tbody( header("Navigate the move tree"), @@ -37,7 +37,7 @@ object help { row(frag(k("x")), "Show threat"), row(frag(k("e")), "Opening/endgame explorer"), row(frag(k("f")), trans.flipBoard.txt()), - row(frag(k("/")), "Focus chat"), + row(frag(k("c")), "Focus chat"), row(frag(k("shift"), k("C")), trans.keyShowOrHideComments.txt()), row(frag(k("?")), "Show this help dialog"), isStudy option frag( @@ -49,8 +49,8 @@ object help { tr( td(cls := "mouse", colspan := 2)( ul( - li(trans.youCanAlsoScrollOverTheBoardToMoveInTheGame.frag()), - li(trans.analysisShapesHowTo.frag()) + li(trans.youCanAlsoScrollOverTheBoardToMoveInTheGame()), + li(trans.analysisShapesHowTo()) ) ) ) diff --git a/app/views/analyse/jsI18n.scala b/app/views/analyse/jsI18n.scala index 709ebb8868..5e6e9938f9 100644 --- a/app/views/analyse/jsI18n.scala +++ b/app/views/analyse/jsI18n.scala @@ -2,12 +2,11 @@ package views.html.analyse import lila.api.Context import lila.app.templating.Environment._ -import lila.common.String.html.safeJsonValue import lila.i18n.{ I18nKeys => trans } private object jsI18n { - def apply()(implicit ctx: Context) = safeJsonValue(i18nJsObject(translations)) + def apply()(implicit ctx: Context) = i18nJsObject(translations) private val translations = List( trans.flipBoard, @@ -51,7 +50,6 @@ private object jsI18n { trans.toggleLocalEvaluation, // action menu trans.menu, - trans.preferences, trans.inlineNotation, trans.computerAnalysis, trans.enable, diff --git a/app/views/analyse/replay.scala b/app/views/analyse/replay.scala index e736b18c6e..6cf8871f10 100644 --- a/app/views/analyse/replay.scala +++ b/app/views/analyse/replay.scala @@ -1,11 +1,14 @@ package views.html.analyse -import play.twirl.api.Html +import play.api.libs.json.Json + +import chess.variant.Crazyhouse import bits.dataPanel import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ +import lila.common.Lang import lila.common.String.html.safeJsonValue import lila.game.Pov @@ -13,6 +16,9 @@ import controllers.routes object replay { + private[analyse] def titleOf(pov: Pov)(implicit lang: Lang) = + s"${playerText(pov.game.whitePlayer)} vs ${playerText(pov.game.blackPlayer)}: ${pov.game.opening.fold(trans.analysis.txt())(_.opening.ecoName)}" + def apply( pov: Pov, data: play.api.libs.json.JsObject, @@ -33,82 +39,101 @@ object replay { views.html.chat.json(c.chat, name = trans.spectatorRoom.txt(), timeout = c.timeout, withNote = ctx.isAuth, public = true) } val pgnLinks = div( - a(dataIcon := "x", cls := "text", rel := "nofollow", href := s"${routes.Game.exportOne(game.id)}?literate=1")(trans.downloadAnnotated()), - a(dataIcon := "x", cls := "text", rel := "nofollow", href := s"${routes.Game.exportOne(game.id)}?evals=0&clocks=0")(trans.downloadRaw()), - game.isPgnImport option a(dataIcon := "x", cls := "text", rel := "nofollow", href := s"${routes.Game.exportOne(game.id)}?imported=1")(trans.downloadImported()), - ctx.noBlind option a(dataIcon := "=", cls := "text embed_howto", target := "_blank")(trans.embedInYourWebsite()) + a(dataIcon := "x", cls := "text", href := s"${routes.Game.exportOne(game.id)}?literate=1")(trans.downloadAnnotated()), + a(dataIcon := "x", cls := "text", href := s"${routes.Game.exportOne(game.id)}?evals=0&clocks=0")(trans.downloadRaw()), + game.isPgnImport option a(dataIcon := "x", cls := "text", href := s"${routes.Game.exportOne(game.id)}?imported=1")(trans.downloadImported()), + ctx.noBlind option a(dataIcon := "=", cls := "text embed-howto", target := "_blank")(trans.embedInYourWebsite()) ) bits.layout( - title = s"${playerText(pov.game.whitePlayer)} vs ${playerText(pov.game.blackPlayer)}: ${game.opening.fold(trans.analysis.txt())(_.opening.ecoName)}", - side = views.html.game.side(pov, initialFen, none, simul = simul, userTv = userTv, bookmarked = bookmarked), - chat = views.html.chat.frag.some, - underchat = Some(views.html.round.bits underchat pov.game), - moreCss = cssTags("analyse.css", "chat.css"), + title = titleOf(pov), + moreCss = frag( + cssTag("analyse.round"), + pov.game.variant == Crazyhouse option cssTag("analyse.zh"), + ctx.blind option cssTag("round.nvui") + ), moreJs = frag( analyseTag, analyseNvuiTag, - embedJs(s"""lichess=lichess||{}; -lichess.analyse={data:${safeJsonValue(data)},i18n:${jsI18n()},userId:$jsUserId,chat:${jsOrNull(chatJson)}, -explorer:{endpoint:"$explorerEndpoint",tablebaseEndpoint:"$tablebaseEndpoint"}}""") + embedJsUnsafe(s"""lichess=lichess||{};lichess.analyse=${ + safeJsonValue(Json.obj( + "data" -> data, + "i18n" -> jsI18n(), + "userId" -> ctx.userId, + "chat" -> chatJson, + "explorer" -> Json.obj( + "endpoint" -> explorerEndpoint, + "tablebaseEndpoint" -> tablebaseEndpoint + ) + )) + }""") ), openGraph = povOpenGraph(pov).some )(frag( - div(cls := "analyse cg-512")( - views.html.board.bits.domPreload(none) + main(cls := "analyse")( + st.aside(cls := "analyse__side")( + views.html.game.side(pov, initialFen, none, simul = simul, userTv = userTv, bookmarked = bookmarked) + ), + chatOption.map(_ => views.html.chat.frag), + div(cls := "analyse__board main-board")(chessgroundSvg), + div(cls := "analyse__tools")(div(cls := "ceval")), + div(cls := "analyse__controls"), + !ctx.blind option frag( + div(cls := "analyse__underboard")( + div(cls := "analyse__underboard__panels")( + div(cls := "active"), + game.analysable option div(cls := "computer-analysis")( + if (analysis.isDefined || analysisStarted) div(id := "adv-chart") + else form( + cls := s"future-game-analysis${ctx.isAnon ?? " must-login"}", + action := routes.Analyse.requestAnalysis(gameId), + method := "post" + )( + button(`type` := "submit", cls := "button text")( + span(cls := "is3 text", dataIcon := "")(trans.requestAComputerAnalysis()) + ) + ) + ), + div(cls := "fen-pgn")( + div( + strong("FEN"), + input(readonly, spellcheck := false, cls := "copyable autoselect analyse__underboard__fen") + ), + div(cls := "pgn-options")( + strong("PGN"), + pgnLinks + ), + div(cls := "pgn")(pgn) + ), + div(cls := "move-times")( + game.turns > 1 option div(id := "movetimes-chart") + ), + cross.map { c => + div(cls := "ctable")( + views.html.game.crosstable(pov.player.userId.fold(c)(c.fromPov), pov.gameId.some) + ) + } + ), + div(cls := "analyse__underboard__menu")( + game.analysable option + span( + cls := "computer-analysis", + dataPanel := "computer-analysis", + title := analysis.map { a => s"Provided by ${usernameOrId(a.providedBy)}" } + )(trans.computerAnalysis()), + !game.isPgnImport option frag( + game.turns > 1 option span(dataPanel := "move-times")(trans.moveTimes()), + cross.isDefined option span(dataPanel := "ctable")(trans.crosstable()) + ), + span(dataPanel := "fen-pgn")(raw("FEN & PGN")) + ) + ) + ) ), - if (ctx.blind) div(cls := "blind_content none")( + if (ctx.blind) div(cls := "blind-content none")( h2("PGN downloads"), pgnLinks ) - else div(cls := "underboard_content none")( - div(cls := "analysis_panels")( - game.analysable option div(cls := "panel computer_analysis")( - if (analysis.isDefined || analysisStarted) div(id := "adv_chart") - else form( - cls := s"future_game_analysis${ctx.isAnon ?? " must_login"}", - action := routes.Analyse.requestAnalysis(gameId), - method := "post" - )( - button(`type` := "submit", cls := "button text")( - span(cls := "is3 text", dataIcon := "")(trans.requestAComputerAnalysis()) - ) - ) - ), - div(cls := "panel fen_pgn")( - div( - strong("FEN"), - input(readonly := true, spellcheck := false, cls := "copyable autoselect fen") - ), - div(cls := "pgn_options")( - strong("PGN"), - pgnLinks - ), - div(cls := "pgn")(pgn) - ), - div(cls := "panel move_times")( - game.turns > 1 option div(id := "movetimes_chart") - ), - cross.map { c => - div(cls := "panel crosstable")( - views.html.game.crosstable(pov.player.userId.fold(c)(c.fromPov), pov.gameId.some) - ) - } - ), - div(cls := "analysis_menu")( - game.analysable option - a( - dataPanel := "computer_analysis", - cls := "computer_analysis", - title := analysis.map { a => s"Provided by ${usernameOrId(a.providedBy)}" } - )(trans.computerAnalysis()), - !game.isPgnImport option frag( - game.turns > 1 option a(dataPanel := "move_times", cls := "move_times")(trans.moveTimes()), - cross.isDefined option a(dataPanel := "crosstable", cls := "crosstable")(trans.crosstable()) - ), - a(dataPanel := "fen_pgn", cls := "fen_pgn")(raw("FEN & PGN")) - ) - ) )) } } diff --git a/app/views/analyse/replayBot.scala b/app/views/analyse/replayBot.scala index 9f41e1b023..28c7778de1 100644 --- a/app/views/analyse/replayBot.scala +++ b/app/views/analyse/replayBot.scala @@ -1,7 +1,5 @@ package views.html.analyse -import play.twirl.api.Html - import bits.dataPanel import lila.api.Context import lila.app.templating.Environment._ @@ -22,65 +20,31 @@ object replayBot { import pov._ views.html.analyse.bits.layout( - title = s"${playerText(pov.player)} vs ${playerText(pov.opponent)} in $gameId : ${game.opening.fold(trans.analysis.txt())(_.opening.ecoName)}", - side = views.html.game.side(pov, initialFen, none, simul = simul, bookmarked = false), - chat = none, - underchat = Some(views.html.game.bits.watchers), - moreCss = cssTag("analyse.css"), + title = replay titleOf pov, + moreCss = cssTag("analyse.round"), openGraph = povOpenGraph(pov).some ) { - frag( - div(cls := "analyse cg-512")( - views.html.board.bits.domPreload(pov.some), - div(cls := "lichess_ground for_bot")( - h1(titleGame(pov.game)), - p(describePov(pov)), - p(pov.game.opening.map(_.opening.ecoName)) - ) + main(cls := "analyse")( + st.aside(cls := "analyse__side")( + views.html.game.side(pov, initialFen, none, simul = simul, bookmarked = false) ), - analysis.map { a => - div(cls := "advice_summary")( - table( - a.summary map { - case (color, pairs) => frag( - thead( - tr( - td(span(cls := s"is color-icon $color")) - ), - th(playerLink(pov.game.player(color), withOnline = false)) - ), - tbody( - pairs map { - case (judgment, nb) => tr( - td(strong(nb)), - th(bits.judgmentName(judgment)) - ) - }, - tr( - td(strong(lila.analyse.Accuracy.mean(pov.withColor(color), a))), - th(trans.averageCentipawnLoss()) - ), - tr(td(cls := "spacerlol", colspan := 2)) - ) - ) - } - ) - ) - }, - div(cls := "underboard_content")( - div(cls := "analysis_panels")( - div(cls := "panel fen_pgn")( + div(cls := "analyse__board main-board")(chessgroundSvg), + div(cls := "analyse__tools")(div(cls := "ceval")), + div(cls := "analyse__controls"), + div(cls := "analyse__underboard")( + div(cls := "analyse__underboard__panels")( + div(cls := "fen-pgn active")( + div( + strong("FEN"), + input(readonly, spellcheck := false, cls := "copyable autoselect analyse__underboard__fen") + ), div(cls := "pgn")(pgn) ), cross.map { c => - div(cls := "panel crosstable")( + div(cls := "ctable active")( views.html.game.crosstable(pov.player.userId.fold(c)(c.fromPov), pov.gameId.some) ) } - ), - div(cls := "analysis_menu")( - cross.isDefined option a(dataPanel := "crosstable", cls := "crosstable")(trans.crosstable()), - a(dataPanel := "fen_pgn", cls := "fen_pgn")(raw("FEN & PGN")) ) ) ) diff --git a/app/views/auth/bits.scala b/app/views/auth/bits.scala new file mode 100644 index 0000000000..dbbfd3fcfa --- /dev/null +++ b/app/views/auth/bits.scala @@ -0,0 +1,131 @@ +package views.html +package auth + +import play.api.data.{ Form, Field } + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.user.User + +import controllers.routes + +object bits { + + def formFields(username: Field, password: Field, emailOption: Option[Field], register: Boolean)(implicit ctx: Context) = frag( + form3.group(username, if (register) trans.username() else trans.usernameOrEmail()) { f => + frag( + form3.input(f)(autofocus, required), + p(cls := "error exists none")(trans.usernameAlreadyUsed()) + ) + }, + form3.password(password, trans.password()), + emailOption.map { email => + form3.group(email, trans.email(), help = frag("We will only use it for password reset.").some)(form3.input(_, typ = "email")(required)) + } + ) + + def passwordReset(form: Form[_], captcha: lila.common.Captcha, ok: Option[Boolean] = None)(implicit ctx: Context) = + views.html.base.layout( + title = trans.passwordReset.txt(), + moreCss = cssTag("auth"), + moreJs = captchaTag + ) { + main(cls := "auth auth-signup box box-pad")( + h1( + ok.map { r => + span(cls := (if (r) "is-green" else "is-red"), dataIcon := (if (r) "E" else "L")) + }, + trans.passwordReset() + ), + st.form( + cls := "form3", + action := routes.Auth.passwordResetApply, + method := "post" + )( + form3.group(form("email"), trans.email())(form3.input(_, typ = "email")(autofocus)), + views.html.base.captcha(form, captcha), + form3.action(form3.submit(trans.emailMeALink())) + ) + ) + } + + def passwordResetSent(email: String)(implicit ctx: Context) = + views.html.base.layout( + title = trans.passwordReset.txt() + ) { + main(cls := "page-small box box-pad")( + h1(cls := "is-green text", dataIcon := "E")(trans.checkYourEmail()), + p(trans.weHaveSentYouAnEmailTo(email)), + p(trans.ifYouDoNotSeeTheEmailCheckOtherPlaces()) + ) + } + + def passwordResetConfirm(u: User, token: String, form: Form[_], ok: Option[Boolean] = None)(implicit ctx: Context) = + views.html.base.layout( + title = s"${u.username} - ${trans.changePassword.txt()}", + moreCss = cssTag("form3") + ) { + main(cls := "page-small box box-pad")( + (ok match { + case Some(true) => h1(cls := "is-green text", dataIcon := "E") + case Some(false) => h1(cls := "is-red text", dataIcon := "L") + case _ => h1 + })( + userLink(u, withOnline = false), + " - ", + trans.changePassword() + ), + st.form(cls := "form3", action := routes.Auth.passwordResetConfirmApply(token), method := "POST")( + form3.hidden(form("token")), + form3.passwordModified(form("newPasswd1"), trans.newPassword())(autofocus), + form3.password(form("newPasswd2"), trans.newPasswordAgain()), + form3.globalError(form), + form3.action(form3.submit(trans.changePassword())) + ) + ) + } + + def checkYourEmailBanner(userEmail: lila.security.EmailConfirm.UserEmail) = frag( + styleTag(""" +body { margin-top: 45px; } +#email-confirm { + height: 40px; + background: #3893E8; + color: #fff!important; + font-size: 1.3em; + display: flex; + flex-flow: row nowrap; + justify-content: center; + align-items: center; + border-bottom: 1px solid #666; + box-shadow: 0 5px 6px rgba(0, 0, 0, 0.3); + position: fixed; + top: 0; + left: 0; + right: 0; + z-index: 107; +} +#email-confirm a { + color: #fff!important; + text-decoration: underline; + margin-left: 1em; +} +"""), + div(id := "email-confirm")( + s"Almost there, ${userEmail.username}! Now check your email (${userEmail.email.conceal}) for signup confirmation.", + a(href := routes.Auth.checkYourEmail)("Click here for help") + ) + ) + + def tor()(implicit ctx: Context) = + views.html.base.layout( + title = "Tor exit node" + ) { + main(cls := "page-small box box-pad")( + h1(cls := "text", dataIcon := "2")("Ooops"), + p("Sorry, you can't signup to lichess through TOR!"), + p("As an Anonymous user, you can play, train, and use all lichess features.") + ) + } +} diff --git a/app/views/auth/checkYourEmail.scala b/app/views/auth/checkYourEmail.scala new file mode 100644 index 0000000000..59c84b770c --- /dev/null +++ b/app/views/auth/checkYourEmail.scala @@ -0,0 +1,68 @@ +package views.html.auth + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object checkYourEmail { + + def apply( + userEmail: Option[lila.security.EmailConfirm.UserEmail], + form: Option[Form[_]] = None + )(implicit ctx: Context) = + views.html.base.layout( + title = "Check your email", + moreCss = cssTag("email-confirm") + ) { + main(cls := s"page-small box box-pad email-confirm ${if (form.exists(_.hasErrors)) "error" else "anim"}")( + h1(cls := "is-green text", dataIcon := "E")(trans.checkYourEmail()), + p(trans.weHaveSentYouAnEmailClickTheLink()), + h2("Not receiving it?"), + ol( + li(h3(trans.ifYouDoNotSeeTheEmailCheckOtherPlaces())), + userEmail.map(_.email).map { email => + li( + h3("Make sure your email address is correct:"), + br, br, + st.form(action := routes.Auth.fixEmail, method := "POST")( + input( + id := "new-email", + tpe := "email", + required, + name := "email", + value := form.flatMap(_("email").value).getOrElse(email.value), + pattern := s"^((?!^${email.value}$$).)*$$" + ), + embedJsUnsafe(""" +var email = document.getElementById("new-email"); +var currentError = "This is already your current email."; +email.setCustomValidity(currentError); +email.addEventListener("input", function() { +email.setCustomValidity(email.validity.patternMismatch ? currentError : ""); + });"""), + button(tpe := "submit", cls := "button")("Change it"), + form.map { f => + errMsg(f("email")) + } + ) + ) + }, + li( + h3("Wait up to 5 minutes."), br, + "Depending on your email provider, it can take a while to arrive." + ), + li( + h3("Still not getting it?"), br, + "Did you make sure your email address is correct?", br, + "Did you wait 5 minutes?", br, + "If so, ", + a(href := routes.Account.emailConfirmHelp)("proceed to this page to solve the issue"), "." + ) + ) + ) + } +} diff --git a/app/views/auth/checkYourEmail.scala.html b/app/views/auth/checkYourEmail.scala.html deleted file mode 100644 index 73e5741ec7..0000000000 --- a/app/views/auth/checkYourEmail.scala.html +++ /dev/null @@ -1,54 +0,0 @@ -@(userEmail: Option[lila.security.EmailConfirm.UserEmail], form: Option[Form[_]] = None)(implicit ctx: Context) - -@auth.layout(title = "Check your email") { - -} diff --git a/app/views/auth/emailConfirmBanner.scala.html b/app/views/auth/emailConfirmBanner.scala.html deleted file mode 100644 index 0afe47a107..0000000000 --- a/app/views/auth/emailConfirmBanner.scala.html +++ /dev/null @@ -1,35 +0,0 @@ -@(userEmail: lila.security.EmailConfirm.UserEmail) - - - -
- Almost there, @userEmail.username! Now check your email (@userEmail.email.conceal) for signup confirmation. - Click here for help -
diff --git a/app/views/auth/formFields.scala.html b/app/views/auth/formFields.scala.html deleted file mode 100644 index ef5066121a..0000000000 --- a/app/views/auth/formFields.scala.html +++ /dev/null @@ -1,11 +0,0 @@ -@(username: Field, password: Field, emailOption: Option[Field], register: Boolean)(implicit ctx: Context) -@import lila.app.ui.ScalatagsTwirlForm._ - -@form3.group(username, if(register) trans.username.frag() else trans.usernameOrEmail.frag()) { f => -@form3.inputHtml(f)(*.autofocus := true) -

@trans.usernameAlreadyUsed()

-} -@form3.group(password, trans.password.frag())(form3.input(_, typ = "password")) -@emailOption.map { email => -@form3.group(email, trans.email.frag())(form3.input(_, typ = "email")) -} diff --git a/app/views/auth/layout.scala.html b/app/views/auth/layout.scala.html deleted file mode 100644 index 85c2252572..0000000000 --- a/app/views/auth/layout.scala.html +++ /dev/null @@ -1,6 +0,0 @@ -@(title: String, moreJs: Html = emptyHtml, formCss: Boolean = false, csp: Option[lila.common.ContentSecurityPolicy] = None)(body: Html)(implicit ctx: Context) -@base.layout( -title = title, -moreCss = cssTags(List("user-signup.css" -> true, "form3.css" -> formCss)), -moreJs = moreJs, -csp = csp)(body).toHtml diff --git a/app/views/auth/login.scala b/app/views/auth/login.scala new file mode 100644 index 0000000000..3eb4091de8 --- /dev/null +++ b/app/views/auth/login.scala @@ -0,0 +1,47 @@ +package views.html +package auth + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object login { + + val twoFactorHelp = span(dataIcon := "")( + "Open the two-factor authentication app on your device to view your authentication code and verify your identity." + ) + + def apply(form: Form[_], referrer: Option[String])(implicit ctx: Context) = views.html.base.layout( + title = trans.signIn.txt(), + moreJs = jsTag("login.js"), + moreCss = cssTag("auth") + ) { + main(cls := "auth auth-login box box-pad")( + h1(trans.signIn()), + st.form( + cls := "form3", + action := s"${routes.Auth.authenticate}${referrer.?? { ref => s"?referrer=${java.net.URLEncoder.encode(ref, "US-ASCII")}" }}", + method := "post" + )( + div(cls := "one-factor")( + form3.globalError(form), + auth.bits.formFields(form("username"), form("password"), none, register = false), + form3.submit(trans.signIn(), icon = none) + ), + div(cls := "two-factor none")( + form3.group(form("token"), raw("Authentication code"), help = Some(twoFactorHelp))(form3.input(_)(autocomplete := "off", pattern := "[0-9]{6}")), + p(cls := "error none")("Invalid code."), + form3.submit(trans.signIn(), icon = none) + ) + ), + div(cls := "alternative")( + a(href := routes.Auth.signup())(trans.signUp()), + a(href := routes.Auth.passwordReset())(trans.passwordReset()) + ) + ) + } +} diff --git a/app/views/auth/login.scala.html b/app/views/auth/login.scala.html deleted file mode 100644 index 1896c44dcb..0000000000 --- a/app/views/auth/login.scala.html +++ /dev/null @@ -1,42 +0,0 @@ -@(form: Form[_], referrer: Option[String])(implicit ctx: Context) -@import lila.app.ui.ScalatagsTwirlForm._ - -@twoFactorHelp = { -Open the two-factor authentication app on your device to view your authentication code and verify your identity. -} - -@auth.layout( -title = trans.signIn.txt(), -moreJs = jsTag("login.js"), -formCss = true) { - -} diff --git a/app/views/auth/passwordReset.scala.html b/app/views/auth/passwordReset.scala.html deleted file mode 100644 index d8b0355f14..0000000000 --- a/app/views/auth/passwordReset.scala.html +++ /dev/null @@ -1,22 +0,0 @@ -@(form: Form[_], captcha: lila.common.Captcha, ok: Option[Boolean] = None)(implicit ctx: Context) - -@auth.layout( -title = trans.passwordReset.txt(), -formCss= true) { - -} diff --git a/app/views/auth/passwordResetConfirm.scala.html b/app/views/auth/passwordResetConfirm.scala.html deleted file mode 100644 index e2439848bd..0000000000 --- a/app/views/auth/passwordResetConfirm.scala.html +++ /dev/null @@ -1,24 +0,0 @@ -@(u: User, token: String, form: Form[_], ok: Option[Boolean] = None)(implicit ctx: Context) - -@title = @{ s"${u.username} - ${trans.changePassword.txt()}" } - -@auth.layout(title = title, formCss = true) { -
- -
-} diff --git a/app/views/auth/passwordResetSent.scala.html b/app/views/auth/passwordResetSent.scala.html deleted file mode 100644 index 41014396e0..0000000000 --- a/app/views/auth/passwordResetSent.scala.html +++ /dev/null @@ -1,12 +0,0 @@ -@(email: String)(implicit ctx: Context) - -@auth.layout( -title = trans.passwordReset.txt()) { - -} diff --git a/app/views/auth/signup.scala b/app/views/auth/signup.scala new file mode 100644 index 0000000000..31745fbb4e --- /dev/null +++ b/app/views/auth/signup.scala @@ -0,0 +1,51 @@ +package views.html +package auth + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object signup { + + private val recaptchaScript = raw("""""") + + def apply(form: Form[_], recaptcha: lila.security.RecaptchaPublicConfig)(implicit ctx: Context) = + views.html.base.layout( + title = trans.signUp.txt(), + moreJs = frag( + jsTag("signup.js"), + recaptcha.enabled option recaptchaScript, + fingerprintTag + ), + moreCss = cssTag("auth"), + csp = defaultCsp.withRecaptcha.some + ) { + main(cls := "auth auth-signup box box-pad")( + h1(trans.signUp()), + st.form( + id := "signup_form", + cls := "form3", + action := routes.Auth.signupPost, + method := "post" + )( + auth.bits.formFields(form("username"), form("password"), form("email").some, register = true), + input(id := "signup-fp-input", name := "fp", tpe := "hidden"), + div(cls := "form-group text", dataIcon := "")( + trans.computersAreNotAllowedToPlay(), br, + small(trans.byRegisteringYouAgreeToBeBoundByOur(a(href := routes.Page.tos)(trans.termsOfService()))) + ), + if (recaptcha.enabled) + button( + cls := "g-recaptcha submit button text big", + attr("data-sitekey") := recaptcha.key, + attr("data-callback") := "signupSubmit" + )(trans.signUp()) + else form3.submit(trans.signUp(), icon = none, klass = "big") + ) + ) + } +} diff --git a/app/views/auth/signup.scala.html b/app/views/auth/signup.scala.html deleted file mode 100644 index 8223a60f26..0000000000 --- a/app/views/auth/signup.scala.html +++ /dev/null @@ -1,44 +0,0 @@ -@(form: Form[_], recaptcha: lila.security.RecaptchaPublicConfig)(implicit ctx: Context) - -@moreJs = { -@jsTag("signup.js") -@if(recaptcha.enabled) { - -} -@fingerprintTag -} - -@tosLink = { -@trans.termsOfService() -} - -@auth.layout( -title = trans.signUp.txt(), -moreJs = moreJs, -formCss = true, -csp = defaultCsp.withRecaptcha.some) { - -} diff --git a/app/views/auth/tor.scala.html b/app/views/auth/tor.scala.html deleted file mode 100644 index 011aa005bf..0000000000 --- a/app/views/auth/tor.scala.html +++ /dev/null @@ -1,16 +0,0 @@ -@()(implicit ctx: Context) - -@auth.layout( -title = "Tor exit node") { - -} diff --git a/app/views/base/authFailed.scala.html b/app/views/base/authFailed.scala.html deleted file mode 100644 index c16b7decf8..0000000000 --- a/app/views/base/authFailed.scala.html +++ /dev/null @@ -1,14 +0,0 @@ -@()(implicit ctx: Context) - -@base.layout( -title = "Access denied", -moreCss = cssTag("authFailed.css")) { - -
-
-

403

- Access denied! -

You tried to visit a page you're not authorized to access. Return to the homepage.

-

-
-}.toHtml diff --git a/app/views/base/bits.scala b/app/views/base/bits.scala new file mode 100644 index 0000000000..407062fecd --- /dev/null +++ b/app/views/base/bits.scala @@ -0,0 +1,31 @@ +package views.html.base + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +object bits { + + def mselect(id: String, current: Frag, items: List[Frag]) = div(cls := "mselect")( + input(tpe := "checkbox", cls := "mselect__toggle fullscreen-toggle", st.id := s"mselect-$id", aria.label := "Other variants"), + label(`for` := s"mselect-$id", cls := "mselect__label")(current), + label(`for` := s"mselect-$id", cls := "fullscreen-mask"), + st.nav(cls := "mselect__list")(items) + ) + + lazy val stage = a( + href := "https://lichess.org", + style := """ +background: #7f1010; +color: #fff; +position: fixed; +bottom: 0; +left: 0; +padding: .5em 1em; +border-top-right-radius: 3px; +z-index: 99; +""" + )( + "This is an empty lichess preview website, go to lichess.org instead" + ) +} diff --git a/app/views/base/captcha.scala b/app/views/base/captcha.scala index a6748ca8c0..1f7e5efef2 100644 --- a/app/views/base/captcha.scala +++ b/app/views/base/captcha.scala @@ -29,27 +29,29 @@ object captcha { ), dataCheckUrl := routes.Main.captchaCheck(captcha.gameId) )( - div( - cls := "mini_board parse_fen is2d", - dataPlayable := "1", - dataX := encodeFen(safeJsonValue(Json.toJson(captcha.moves))), - dataY := encodeFen(if (captcha.white) { "white" } else { "black" }), - dataZ := encodeFen(captcha.fen) - )(miniBoardContent), + div(cls := "challenge")( + div( + cls := "mini-board cg-board-wrap parse-fen is2d", + dataPlayable := "1", + dataX := encodeFen(safeJsonValue(Json.toJson(captcha.moves))), + dataY := encodeFen(if (captcha.white) { "white" } else { "black" }), + dataZ := encodeFen(captcha.fen) + )(div(cls := "cg-board")) + ), div(cls := "captcha-explanation")( - label(cls := "form-label")(trans.colorPlaysCheckmateInOne.frag( - (if (captcha.white) trans.white else trans.black).frag() + label(cls := "form-label")(trans.colorPlaysCheckmateInOne( + (if (captcha.white) trans.white else trans.black)() )), br, br, - trans.thisIsAChessCaptcha.frag(), + trans.thisIsAChessCaptcha(), br, - trans.clickOnTheBoardToMakeYourMove.frag(), + trans.clickOnTheBoardToMakeYourMove(), br, br, - trans.help.frag(), + trans.help(), " ", - a(cls := "hint--bottom", dataHint := trans.viewTheSolution.txt(), target := "_blank", href := url)(url), - div(cls := "result success text", dataIcon := "E")(trans.checkmate.frag()), - div(cls := "result failure text", dataIcon := "k")(trans.notACheckmate.frag()), + a(title := trans.viewTheSolution.txt(), target := "_blank", href := url)(url), + div(cls := "result success text", dataIcon := "E")(trans.checkmate()), + div(cls := "result failure text", dataIcon := "k")(trans.notACheckmate()), form3.hidden(form("move")) ) ) diff --git a/app/views/base/errorPage.scala b/app/views/base/errorPage.scala new file mode 100644 index 0000000000..6284c1af07 --- /dev/null +++ b/app/views/base/errorPage.scala @@ -0,0 +1,25 @@ +package views.html +package base + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object errorPage { + + def apply(ex: Throwable)(implicit ctx: Context) = layout( + title = "Internal server error" + ) { + main(cls := "page-small box box-pad")( + h1("Something went wrong on this page"), + p( + "If the problem persists, please ", + a(href := s"${routes.Main.contact}#help-error-page")("report the bug"), + "." + ), + code(ex.getMessage) + ) + } +} diff --git a/app/views/base/errorPage.scala.html b/app/views/base/errorPage.scala.html deleted file mode 100644 index b667ea19e4..0000000000 --- a/app/views/base/errorPage.scala.html +++ /dev/null @@ -1,14 +0,0 @@ -@(ex: Throwable)(implicit ctx: Context) - -@base.layout(title = "Internal server error") { - -
-

Something went wrong on this page.

-
-
-

If the problem persists, please report the bug.

-
-
- @ex.getMessage -
-}.toHtml diff --git a/app/views/base/form/select.scala.html b/app/views/base/form/select.scala.html deleted file mode 100644 index 640d53a627..0000000000 --- a/app/views/base/form/select.scala.html +++ /dev/null @@ -1,10 +0,0 @@ -@(field: play.api.data.Field, options: Iterable[(Any,String)], default: Option[String] = None) - - diff --git a/app/views/base/fpmenu.scala.html b/app/views/base/fpmenu.scala.html deleted file mode 100644 index dfa3070b33..0000000000 --- a/app/views/base/fpmenu.scala.html +++ /dev/null @@ -1,95 +0,0 @@ -@()(implicit ctx: Context) - -
-
- @ctx.me.map { me => -
-

@me.username

- -
- }.getOrElse { -
-
-

@trans.signIn()

- - -
- -
- } - -
- -
diff --git a/app/views/base/layout.scala b/app/views/base/layout.scala index 7c79927c31..48b15a4fa8 100644 --- a/app/views/base/layout.scala +++ b/app/views/base/layout.scala @@ -1,78 +1,72 @@ package views.html.base -import play.twirl.api.Html - import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ -import lila.common.ContentSecurityPolicy -import scalatags.Text.tags2.{ title => titleTag } +import lila.common.{ Lang, ContentSecurityPolicy } +import lila.pref.Pref import controllers.routes object layout { - private val fontVersion = 82 - object bits { val doctype = raw("") - def htmlTag(implicit ctx: Context) = html(st.lang := ctx.lang.language) + def htmlTag(implicit lang: Lang) = html(st.lang := lang.language) val topComment = raw("""""") val charset = raw("""""") - def metaCsp(csp: Option[ContentSecurityPolicy])(implicit ctx: Context): Option[Frag] = + val viewport = raw("""""") + def metaCsp(csp: ContentSecurityPolicy): Option[Frag] = cspEnabled() option raw( - s"""""" + s"""""" ) - def currentBgCss(implicit ctx: Context) = ctx.currentBg match { - case "dark" => cssTag("dark.css") - case "transp" => cssTags("dark.css", "transp.css") - case _ => emptyHtml - } - def pieceSprite(implicit ctx: Context) = - link(id := "piece-sprite", href := assetUrl(s"stylesheets/piece/${ctx.currentPieceSet}.css"), `type` := "text/css", rel := "stylesheet") - val fontStylesheets = raw(List( - """""", - """""" - ).mkString) + def metaCsp(csp: Option[ContentSecurityPolicy])(implicit ctx: Context): Option[Frag] = + metaCsp(csp.getOrElse(defaultCsp)) + def pieceSprite(implicit ctx: Context): Frag = pieceSprite(ctx.currentPieceSet) + def pieceSprite(ps: lila.pref.PieceSet): Frag = + link(id := "piece-sprite", href := assetUrl(s"piece-css/$ps.css"), tpe := "text/css", rel := "stylesheet") } import bits._ private val noTranslate = raw("""""") - private val fontPreload = raw(s"""""") - private val manifests = raw(List( - """""", - """""" - ).mkString) + private def fontPreload(implicit ctx: Context) = raw { + s"""""" + + !ctx.pref.pieceNotationIsLetter ?? + s"""""" + } + private val manifests = raw("""""") + + private val jsLicense = raw("""""") private val favicons = raw { List(256, 128, 64) map { px => s"""""" } mkString } - private def blindModeForm(implicit ctx: Context) = raw(s"""
""") + private def blindModeForm(implicit ctx: Context) = raw(s"""
""") private val zenToggle = raw("""ZEN MODE""") private def dasher(me: lila.user.User) = raw(s"""""") - private def allNotifications(implicit ctx: Context) = spaceless(s"""
- - + private def allNotifications(implicit ctx: Context) = spaceless(s""" -
- - +""") private def anonDasher(playing: Boolean)(implicit ctx: Context) = spaceless(s""" -""") +""") private val clinputLink = a(cls := "link")(span(dataIcon := "y")) @@ -82,7 +76,8 @@ object layout { input(spellcheck := "false", placeholder := trans.search.txt()) ) - private lazy val botImage = img(src := staticUrl("images/icons/bot.png"), title := "Robot chess", style := "display:inline;width:34px;height:34px;vertical-align:top;margin-right:5px;") + private lazy val botImage = img(src := staticUrl("images/icons/bot.png"), title := "Robot chess", style := + "display:inline;width:34px;height:34px;vertical-align:top;margin-right:5px;vertical-align:text-top") private val spaceRegex = """\s{2,}+""".r private def spaceless(html: String) = raw(spaceRegex.replaceAllIn(html.replace("\\n", ""), "")) @@ -93,57 +88,44 @@ object layout { private val dataSocketDomain = attr("data-socket-domain") private val dataAssetUrl = attr("data-asset-url") private val dataAssetVersion = attr("data-asset-version") - private val dataNonce = attr("data-nonce") private val dataZoom = attr("data-zoom") + private val dataTheme = attr("data-theme") private val dataPreload = attr("data-preload") private val dataPlaying = attr("data-playing") private val dataPatrons = attr("data-patrons") private val dataStudying = attr("data-studying") + private val dataNonce = attr("data-nonce") def apply( title: String, fullTitle: Option[String] = None, - baseline: Option[Html] = None, - side: Option[Html] = None, - menu: Option[Html] = None, - chat: Option[Frag] = None, - underchat: Option[Frag] = None, robots: Boolean = isGloballyCrawlable, - moreCss: Html = emptyHtml, - moreJs: Html = emptyHtml, + moreCss: Frag = emptyFrag, + moreJs: Frag = emptyFrag, playing: Boolean = false, openGraph: Option[lila.app.ui.OpenGraph] = None, chessground: Boolean = true, zoomable: Boolean = false, - asyncJs: Boolean = false, - csp: Option[ContentSecurityPolicy] = None - )(body: Html)(implicit ctx: Context) = frag( + deferJs: Boolean = false, + csp: Option[ContentSecurityPolicy] = None, + wrapClass: String = "" + )(body: Frag)(implicit ctx: Context) = frag( doctype, - htmlTag(ctx)( + htmlTag(ctx.lang)( topComment, head( charset, + viewport, metaCsp(csp), if (isProd && !isStage) frag( - titleTag(fullTitle | s"$title • lichess.org"), - fontStylesheets + st.headTitle(fullTitle | s"$title • lichess.org") ) - else frag( - titleTag(s"[dev] ${fullTitle | s"$title • lichess.dev"}"), - cssAt("offline/font.noto.css"), - cssAt("offline/font.roboto.mono.css") - ), - currentBgCss, - cssTag("common.css"), - cssTag("board.css"), - ctx.zoom ifTrue zoomable map { z => - zoomStyle(z / 100f, ctx.pref.is3d) - }, - ctx.pref.is3d option cssTag("board-3d.css"), - ctx.pref.coords == 1 option cssTag("board.coords.inner.css"), - ctx.pageData.inquiry.isDefined option cssTag("inquiry.css"), - ctx.userContext.impersonatedBy.isDefined option cssTag("impersonate.css"), - isStage option cssTag("stage.css"), + else st.headTitle(s"[dev] ${fullTitle | s"$title • lichess.dev"}"), + cssTag("site"), + ctx.pref.is3d option cssTag("board-3d"), + ctx.pageData.inquiry.isDefined option cssTagNoTheme("mod.inquiry"), + ctx.userContext.impersonatedBy.isDefined option cssTagNoTheme("mod.impersonate"), + ctx.blind option cssTagNoTheme("blind"), moreCss, pieceSprite, meta(content := openGraph.fold(trans.siteDescription.txt())(o => o.description), name := "description"), @@ -152,27 +134,25 @@ object layout { favicons, !robots option raw(""""""), noTranslate, - openGraph.map(_.frag), + openGraph.map(_.frags), link(href := routes.Blog.atom, `type` := "application/atom+xml", rel := "alternate", st.title := trans.blog.txt()), ctx.transpBgImg map { img => raw(s"""""") }, fontPreload, - manifests + manifests, + jsLicense ), st.body( cls := List( - "preload base" -> true, - ctx.currentTheme.cssClass -> true, - ctx.currentTheme3d.cssClass -> true, - (if (ctx.currentBg == "transp") "dark transp" else ctx.currentBg) -> true, - ctx.currentPieceSet3d.toString -> true, - "piece_letter" -> ctx.pref.pieceNotationIsLetter, + s"${ctx.currentBg} ${ctx.currentTheme.cssClass} ${ctx.currentTheme3d.cssClass} ${ctx.currentPieceSet3d.toString} coords-${ctx.pref.coordsClass}" -> true, + "piece-letter" -> ctx.pref.pieceNotationIsLetter, "zen" -> ctx.pref.isZen, - "blind_mode" -> ctx.blind, + "blind-mode" -> ctx.blind, "kid" -> ctx.kid, "mobile" -> ctx.isMobileBrowser, - "playing fixed-scroll" -> playing + "playing fixed-scroll" -> playing, + "coords-out" -> (ctx.pref.coords == Pref.Coords.OUTSIDE) ), dataDev := (!isProd).option("true"), dataUser := ctx.userId, @@ -180,63 +160,22 @@ object layout { dataSocketDomain := socketDomain, dataAssetUrl := assetBaseUrl, dataAssetVersion := assetVersion.value, - dataNonce := ctx.nonce.map(_.value), - dataZoom := ctx.zoom.map(_.toString) + dataNonce := ctx.nonce.ifTrue(sameAssetDomain).map(_.value), + dataTheme := ctx.currentBg, + style := zoomable option s"--zoom:${ctx.respZoom}" )( blindModeForm, - div(id := "site_description")(trans.siteDescription.frag()), ctx.pageData.inquiry map { views.html.mod.inquiry(_) }, ctx.me ifTrue ctx.userContext.impersonatedBy.isDefined map { views.html.mod.impersonate(_) }, - isStage option div(id := "stage")( - "This is an empty lichess preview website for developers. ", - a(href := "https://lichess.org")("Go to lichess.org instead") - ), - lila.security.EmailConfirm.cookie.get(ctx.req).map(views.html.auth.emailConfirmBanner(_)), + // isStage option views.html.base.bits.stage, + lila.security.EmailConfirm.cookie.get(ctx.req).map(views.html.auth.bits.checkYourEmailBanner(_)), playing option zenToggle, - div(id := "top", cls := (if (ctx.pref.is3d) "is3d" else "is2d"))( - topmenu(), - div(id := "ham-plate", cls := "link hint--bottom", dataHint := trans.menu.txt())( - div(id := "hamburger", dataIcon := "[") - ), - ctx.me map { me => - frag(dasher(me), allNotifications) - } getOrElse { - !ctx.pageData.error option anonDasher(playing) - }, - ctx.teamNbRequests > 0 option - a(cls := "link data-count", href := routes.Team.requests, dataCount := ctx.teamNbRequests)( - span(cls := "hint--bottom-left", dataHint := trans.teams.txt())(span(dataIcon := "f")) - ), - isGranted(_.SeeReport) option - a(cls := "link text data-count", href := routes.Report.list, dataCount := reportNbOpen, dataIcon := ""), - clinput, - a(id := "reconnecting", cls := "link text", dataIcon := "B")(trans.reconnecting.frag()) - ), - div(cls := s"content ${if (ctx.pref.is3d) "is3d" else "is2d"}")( - div(id := "site_header")( - div(id := "notifications"), - div(cls := "board_left")( - h1( - a(id := "site_title", href := routes.Lobby.home)( - if (ctx.kid) span(st.title := trans.kidMode.txt(), cls := "kiddo")("😊") - else ctx.isBot option botImage, - "lichess", - span(cls := "extension")(if (isProd && !isStage) ".org" else ".dev") - ) - ), - baseline, - menu map { sideMenu => - div(cls := "side_menu")(sideMenu) - }, - side, - chat - ), - underchat map { g => - div(cls := "under_chat")(g) - } - ), - div(id := "lichess")(body) - ), + siteHeader(playing), + div(id := "main-wrap", cls := List( + wrapClass -> wrapClass.nonEmpty, + "is2d" -> ctx.pref.is2d, + "is3d" -> ctx.pref.is3d + ))(body), ctx.me.map { me => div( id := "friend_box", @@ -246,9 +185,9 @@ object layout { dataStudying := ctx.onlineFriends.studying.mkString(",") )( div(cls := "friend_box_title")( - strong(cls := "online")(" "), + strong(cls := "online")("?"), " ", - trans.onlineFriends.frag() + trans.onlineFriends() ), div(cls := "content_wrap")( div(cls := "content list"), @@ -256,21 +195,66 @@ object layout { "nobody" -> true, "none" -> ctx.onlineFriends.users.nonEmpty ))( - span(trans.noFriendsOnline.frag()), + span(trans.noFriendsOnline()), a(cls := "find button", href := routes.User.opponents)( - span(cls := "is3 text", dataIcon := "h")(trans.findFriends.frag()) + span(cls := "is3 text", dataIcon := "h")(trans.findFriends()) ) ) ) ) }, + a(id := "reconnecting", cls := "link text", dataIcon := "B")(trans.reconnecting()), chessground option jsTag("vendor/chessground.min.js"), ctx.requiresFingerprint option fingerprintTag, - jsAt(s"compiled/lichess.site${isProd ?? ".min"}.js", async = asyncJs), + if (isProd) + jsAt(s"compiled/lichess.site.min.js", defer = deferJs) + else frag( + jsAt(s"compiled/lichess.deps.js", defer = deferJs), + jsAt(s"compiled/lichess.site.js", defer = deferJs) + ), moreJs, - embedJs(s"""lichess.quantity=${lila.i18n.JsQuantity(ctx.lang)};$timeagoLocaleScript;"""), - ctx.pageData.inquiry.isDefined option jsTag("inquiry.js", async = asyncJs) + embedJsUnsafe(s"""lichess.quantity=${lila.i18n.JsQuantity(ctx.lang)};$timeagoLocaleScript"""), + ctx.pageData.inquiry.isDefined option jsTag("inquiry.js", defer = deferJs) ) ) ) + + object siteHeader { + + private val topnavToggle = spaceless(""" + + +""") + + private def reports(implicit ctx: Context) = isGranted(_.SeeReport) option + a(cls := "link data-count link-center", title := "Moderation", href := routes.Report.list, dataCount := reportNbOpen, dataIcon := "") + + private def teamRequests(implicit ctx: Context) = ctx.teamNbRequests > 0 option + a(cls := "link data-count link-center", href := routes.Team.requests, dataCount := ctx.teamNbRequests, dataIcon := "f", title := trans.teams.txt()) + + def apply(playing: Boolean)(implicit ctx: Context) = + header(id := "top")( + div(cls := "site-title-nav")( + topnavToggle, + h1(cls := "site-title")( + if (ctx.kid) span(title := trans.kidMode.txt(), cls := "kiddo")(":)") + else ctx.isBot option botImage, + a(href := "/")( + "lichess", + span(if (isProd && !isStage) ".org" else ".dev") + ) + ), + ctx.blind option h2("Navigation"), + topnav() + ), + div(cls := "site-buttons")( + clinput, + reports, + teamRequests, + ctx.me map { me => + frag(allNotifications, dasher(me)) + } getOrElse { !ctx.pageData.error option anonDasher(playing) } + ) + ) + } } diff --git a/app/views/base/notFound.scala b/app/views/base/notFound.scala new file mode 100644 index 0000000000..dd35f511b8 --- /dev/null +++ b/app/views/base/notFound.scala @@ -0,0 +1,45 @@ +package views.html +package base + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object notFound { + + def apply()(implicit ctx: Context) = layout( + title = "Page not found", + moreJs = prismicJs, + moreCss = cssTag("not-found"), + csp = isGranted(_.Prismic) option defaultCsp.withPrismic(true) + ) { + main(cls := "not-found page-small box box-pad")( + header( + h1("404"), + div( + strong("Page not found!"), + p( + "Return to ", + a(href := routes.Lobby.home)("the homepage"), + span(cls := "or-play")(" or play this mini-game") + ) + ) + ), + div(cls := "game")( + iframe( + src := staticUrl(s"vendor/ChessPursuit/bin-release/index.html"), + st.frameborder := 0, + width := 400, + height := 500 + ), + p(cls := "credits")( + a(href := "https://github.com/Saturnyn/ChessPursuit")("ChessPursuit"), + " courtesy of ", + a(href := "https://github.com/Saturnyn")("Saturnyn") + ) + ) + ) + } +} diff --git a/app/views/base/notFound.scala.html b/app/views/base/notFound.scala.html deleted file mode 100644 index 0b5f4794d1..0000000000 --- a/app/views/base/notFound.scala.html +++ /dev/null @@ -1,28 +0,0 @@ -@()(implicit ctx: Context) - -@base.layout( -title = "Page not found", -moreJs = prismicJs, -moreCss = cssTag("notFound.css"), -csp = isGranted(_.Prismic) option defaultCsp.withPrismic(true)) { -
-
-

404

- Page not found! -

Return to the homepage, or play this mini-game!

-

-
- -

- ChessPursuit - courtesy of - Saturnyn -

-
-
-}.toHtml diff --git a/app/views/base/topmenu.scala b/app/views/base/topmenu.scala deleted file mode 100644 index 18228e0e49..0000000000 --- a/app/views/base/topmenu.scala +++ /dev/null @@ -1,75 +0,0 @@ -package views.html.base - -import scalatags.Text.tags2.{ nav, section } - -import lila.api.Context -import lila.app.templating.Environment._ -import lila.app.ui.ScalatagsTemplate._ - -import controllers.routes - -object topmenu { - - private def linkTitle(url: String, name: Frag)(implicit ctx: Context) = - if (ctx.blind) h2(name) else a(href := url)(name) - - def apply()(implicit ctx: Context) = nav( - id := "topmenu", - cls := (if (ctx.blind) "blind" else "hover") - )( - section( - linkTitle("/", trans.play.frag()), - div(role := "group")( - if (ctx.noBot) a(href := "/?any#hook")(trans.createAGame.frag()) - else a(href := "/?any#friend")(trans.playWithAFriend.frag()), - ctx.noBot option frag( - a(href := routes.Tournament.home())(trans.tournament.frag()), - a(href := routes.Simul.home)(trans.simultaneousExhibitions.frag()) - ) - ) - ), - section( - linkTitle(routes.Puzzle.home.toString, trans.learnMenu.frag()), - div(role := "group")( - ctx.noBot option frag( - a(href := routes.Learn.index)(trans.chessBasics.frag()), - a(href := routes.Puzzle.home)(trans.training.frag()), - a(href := routes.Practice.index)("Practice"), - a(href := routes.Coordinate.home)(trans.coordinates.coordinates()) - ), - a(href := routes.Study.allDefault(1))("Study"), - a(href := routes.Coach.allDefault(1))(trans.coaches.frag()) - ) - ), - section( - linkTitle(routes.Tv.index.toString, trans.watch.frag()), - div(role := "group")( - a(href := routes.Tv.index)("Lichess TV"), - a(href := routes.Tv.games)(trans.currentGames.frag()), - a(href := routes.Streamer.index())("Streamers"), - a(href := routes.Relay.index())("Broadcasts (beta)"), - ctx.noBot option a(href := routes.Video.index)(trans.videoLibrary.frag()) - ) - ), - section( - linkTitle(routes.User.list.toString, trans.community.frag()), - div(role := "group")( - a(href := routes.User.list)(trans.players.frag()), - NotForKids(frag( - a(href := routes.Team.home())(trans.teams.frag()), - a(href := routes.ForumCateg.index)(trans.forum.frag()) - )) - ) - ), - section( - linkTitle(routes.UserAnalysis.index.toString, trans.tools.frag()), - div(role := "group")( - a(href := routes.UserAnalysis.index)(trans.analysis.frag()), - a(href := s"${routes.UserAnalysis.index}#explorer")(trans.openingExplorer.frag()), - a(href := routes.Editor.index)(trans.boardEditor.frag()), - a(href := routes.Importer.importGame)(trans.importGame.frag()), - a(href := routes.Search.index())(trans.advancedSearch.frag()) - ) - ) - ) -} diff --git a/app/views/base/topnav.scala b/app/views/base/topnav.scala new file mode 100644 index 0000000000..6562f40211 --- /dev/null +++ b/app/views/base/topnav.scala @@ -0,0 +1,73 @@ +package views.html.base + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object topnav { + + private def linkTitle(url: String, name: Frag)(implicit ctx: Context) = + if (ctx.blind) h3(name) else a(href := url)(name) + + def apply()(implicit ctx: Context) = st.nav(id := "topnav", role := "navigation", cls := "hover")( + st.section( + linkTitle("/", frag( + span(cls := "play")(trans.play()), + span(cls := "home")("lichess.org") + )), + div(role := "group")( + if (ctx.noBot) a(href := "/?any#hook")(trans.createAGame()) + else a(href := "/?any#friend")(trans.playWithAFriend()), + ctx.noBot option frag( + a(href := routes.Tournament.home())(trans.tournament()), + a(href := routes.Simul.home)(trans.simultaneousExhibitions()) + ) + ) + ), + st.section( + linkTitle(routes.Puzzle.home.toString, trans.learnMenu()), + div(role := "group")( + ctx.noBot option frag( + a(href := routes.Learn.index)(trans.chessBasics()), + a(href := routes.Puzzle.home)(trans.training()), + a(href := routes.Practice.index)("Practice"), + a(href := routes.Coordinate.home)(trans.coordinates.coordinates()) + ), + a(href := routes.Study.allDefault(1))("Study"), + a(href := routes.Coach.allDefault(1))(trans.coaches()) + ) + ), + st.section( + linkTitle(routes.Tv.index.toString, trans.watch()), + div(role := "group")( + a(href := routes.Tv.index)("Lichess TV"), + a(href := routes.Tv.games)(trans.currentGames()), + a(href := routes.Streamer.index())("Streamers"), + a(href := routes.Relay.index())("Broadcasts"), + ctx.noBot option a(href := routes.Video.index)(trans.videoLibrary()) + ) + ), + st.section( + linkTitle(routes.User.list.toString, trans.community()), + div(role := "group")( + a(href := routes.User.list)(trans.players()), + NotForKids(frag( + a(href := routes.Team.home())(trans.teams()), + a(href := routes.ForumCateg.index)(trans.forum()) + )) + ) + ), + st.section( + linkTitle(routes.UserAnalysis.index.toString, trans.tools()), + div(role := "group")( + a(href := routes.UserAnalysis.index)(trans.analysis()), + a(href := s"${routes.UserAnalysis.index}#explorer")(trans.openingExplorer()), + a(href := routes.Editor.index)(trans.boardEditor()), + a(href := routes.Importer.importGame)(trans.importGame()), + a(href := routes.Search.index())(trans.advancedSearch()) + ) + ) + ) +} diff --git a/app/views/base/zoomStyle.scala.html b/app/views/base/zoomStyle.scala.html deleted file mode 100644 index e4de531ea6..0000000000 --- a/app/views/base/zoomStyle.scala.html +++ /dev/null @@ -1,41 +0,0 @@ -@(zoom: Float, is3d: Boolean) -@defining(is3d ?? ".is3d") { prefix => -@defining(Math.round(zoom * 64) * 8) { boardPx => - -} -} diff --git a/app/views/blog/atom.scala b/app/views/blog/atom.scala new file mode 100644 index 0000000000..d54fb73eba --- /dev/null +++ b/app/views/blog/atom.scala @@ -0,0 +1,48 @@ +package views.html.blog + +import play.api.mvc.RequestHeader + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator + +import controllers.routes + +object atom { + + def apply(pager: Paginator[io.prismic.Document])(implicit req: RequestHeader) = frag( + raw(""""""), + raw(""""""), + tag("id")(routes.Blog.index().absoluteURL(true)), + link(rel := "alternate", tpe := "text/html", href := routes.Blog.index().absoluteURL(true)), + link(rel := "self", tpe := "application/atom+xml", href := routes.Blog.atom().absoluteURL(true)), + tag("title")("lichess.org blog"), + tag("updated")(pager.currentPageResults.headOption.flatMap(atomDate("blog.date"))), + pager.currentPageResults.map { doc => + tag("entry")( + tag("id")(routes.Blog.show(doc.id, doc.slug).absoluteURL(true)), + tag("published")(atomDate("blog.date")(doc)), + tag("updated")(atomDate("blog.date")(doc)), + link(rel := "alternate", tpe := "text/html", href := routes.Blog.show(doc.id, doc.slug).absoluteURL(true)), + tag("title")(doc.getText("blog.title")), + tag("category")( + tag("term")(doc.getText("blog.category")), + tag("label")(slugify(~doc.getText("blog.category"))) + ), + tag("content")(tpe := "html")( + doc.getText("blog.shortlede"), + "
", // yes, scalatags encodes it. + doc.getImage("blog.image", "main").map { img => + st.img(src := img.url).render + }, + "
", + lila.blog.ProtocolFix.add(doc.getStructuredText("blog.body") ?? lila.blog.BlogApi.extract) + ), + tag("tag")("media:thumbnail")(attr("url") := doc.getImage(s"blog.image", "main").map(_.url)), + tag("author")(tag("name")(doc.getText("blog.author"))) + ) + }, + raw("
") + ) +} diff --git a/app/views/blog/atom.scala.xml b/app/views/blog/atom.scala.xml deleted file mode 100644 index 32148786ed..0000000000 --- a/app/views/blog/atom.scala.xml +++ /dev/null @@ -1,37 +0,0 @@ -@(pager: Paginator[io.prismic.Document])(implicit req: RequestHeader) - - - @routes.Blog.index().absoluteURL(true) - - - lichess.org blog - @pager.currentPageResults.headOption.flatMap(atomDate("blog.date")) - @pager.currentPageResults.map { doc => - - @routes.Blog.show(doc.id, doc.slug).absoluteURL(true) - @atomDate("blog.date")(doc) - @atomDate("blog.date")(doc) - - @doc.getText("blog.title") - - @doc.getText("blog.category") - - - - @doc.getText("blog.shortlede") - - <br /> - @doc.getImage("blog.image", "main").map { img => - <img src="@img.url"/> - } - <br /> - @lila.blog.ProtocolFix.add(doc.getStructuredText("blog.body") ?? lila.blog.BlogApi.extract) - - - - @doc.getText("blog.author") - - - } - - diff --git a/app/views/blog/bits.scala b/app/views/blog/bits.scala new file mode 100644 index 0000000000..0f5317466d --- /dev/null +++ b/app/views/blog/bits.scala @@ -0,0 +1,29 @@ +package views.html.blog + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.String.html.richText + +import controllers.routes + +object bits { + + private[blog] def metas(doc: io.prismic.Document)(implicit ctx: Context, prismic: lila.blog.BlogApi.Context) = + div(cls := "meta-headline")( + div(cls := "meta")( + doc.getDate("blog.date").map { date => + span(cls := "text", dataIcon := "p")(semanticDate(date.value.toDateTimeAtStartOfDay)) + }, + doc.getText("blog.author").map { author => + span(cls := "text", dataIcon := "r")(richText(author)) + }, + doc.getText("blog.category").map { categ => + span(cls := "text", dataIcon := "t")(categ) + } + ), + strong(cls := "headline")(doc.getHtml("blog.shortlede", prismic.linkResolver).map(raw)) + ) + + private[blog] def csp(implicit ctx: Context) = defaultCsp.withPrismic(isGranted(_.Prismic)).some +} diff --git a/app/views/blog/index.scala b/app/views/blog/index.scala new file mode 100644 index 0000000000..360db8a9a1 --- /dev/null +++ b/app/views/blog/index.scala @@ -0,0 +1,52 @@ +package views.html.blog + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator + +import controllers.routes + +object index { + + def apply(pager: Paginator[io.prismic.Document])(implicit ctx: Context, prismic: lila.blog.BlogApi.Context) = + views.html.base.layout( + title = "Blog", + moreCss = cssTag("blog"), + csp = bits.csp, + moreJs = infiniteScrollTag + )( + main(cls := "blog list page-small box")( + div(cls := "box__top")( + h1("Lichess Official Blog"), + a(cls := "atom", href := routes.Blog.atom, dataIcon := "3") + ), + div(cls := "list infinitescroll")( + pager.currentPageResults.map { doc => + st.article(cls := "paginated")( + doc.getText("blog.title").map { title => + h2(a(href := routes.Blog.show(doc.id, doc.slug, prismic.maybeRef))(title)) + }, + bits.metas(doc), + doc.getImage("blog.image", "main").map { img => + div(cls := "illustration")( + a(href := routes.Blog.show(doc.id, doc.slug, ref = prismic.maybeRef))(st.img(src := img.url)) + ) + }, + div(cls := "body")( + doc.getStructuredText("blog.body").map { body => + raw(lila.blog.BlogApi.extract(body)) + }, + p(cls := "more")( + a(cls := "button", href := routes.Blog.show(doc.id, doc.slug, ref = prismic.maybeRef), dataIcon := "G")( + " Continue reading this post" + ) + ) + ) + ) + }, + pagerNext(pager, np => routes.Blog.index(np, none).url) + ) + ) + ) +} diff --git a/app/views/blog/index.scala.html b/app/views/blog/index.scala.html deleted file mode 100644 index 7c83a49b9d..0000000000 --- a/app/views/blog/index.scala.html +++ /dev/null @@ -1,39 +0,0 @@ -@(pager: Paginator[io.prismic.Document])(implicit ctx: Context, prismic: lila.blog.BlogApi.Context) - -@layout(title = "Blog", -moreJs = infiniteScrollTag) { - -

- - Lichess Official Blog -

-
- @pager.currentPageResults.map { doc => -
- @doc.getText("blog.title").map { title => -

@title

- } - @meta(doc) - @doc.getHtml("blog.shortlede", prismic.linkResolver).map(Html.apply) - @doc.getImage("blog.image", "main").map { img => -
- -
- } -
- @doc.getStructuredText("blog.body").map { body => - @Html(lila.blog.BlogApi.extract(body)) - } -

- Continue reading this post -

-
-
- } - @pager.nextPage.map { np => -
- -
- } -
-} diff --git a/app/views/blog/layout.scala.html b/app/views/blog/layout.scala.html deleted file mode 100644 index 6f6c71532b..0000000000 --- a/app/views/blog/layout.scala.html +++ /dev/null @@ -1,19 +0,0 @@ -@(title: String, side: Option[Html] = None, openGraph: Option[lila.app.ui.OpenGraph] = None, moreJs: Html = emptyHtml)(body: Html)(implicit ctx: Context) - -@pageJs = { -@moreJs -@jsTag("embed-analyse.js") -@prismicJs -} - -@base.layout( -title = title, -moreCss = cssTag("blog.css"), -moreJs = pageJs, -side = side, -openGraph = openGraph, -csp = defaultCsp.withPrismic(isGranted(_.Prismic)).some) { -
- @body -
-}.toHtml diff --git a/app/views/blog/meta.scala.html b/app/views/blog/meta.scala.html deleted file mode 100644 index da4c2a60a3..0000000000 --- a/app/views/blog/meta.scala.html +++ /dev/null @@ -1,12 +0,0 @@ -@(doc: io.prismic.Document)(implicit ctx: Context, prismic: lila.blog.BlogApi.Context) -
- @doc.getDate("blog.date").map { date => - @semanticDate(date.value.toDateTimeAtStartOfDay) - } - @doc.getText("blog.author").map { author => - @richText(author) - } - @doc.getText("blog.category").map { categ => - @categ - } -
diff --git a/app/views/blog/show.scala b/app/views/blog/show.scala new file mode 100644 index 0000000000..54abcef7ef --- /dev/null +++ b/app/views/blog/show.scala @@ -0,0 +1,47 @@ +package views.html.blog + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object show { + + def apply(doc: io.prismic.Document)(implicit ctx: Context, prismic: lila.blog.BlogApi.Context) = + views.html.base.layout( + title = s"${~doc.getText("blog.title")} | Blog", + moreJs = jsAt("compiled/embed-analyse.js"), + openGraph = lila.app.ui.OpenGraph( + `type` = "article", + image = doc.getImage("blog.image", "main").map(_.url), + title = ~doc.getText("blog.title"), + url = s"$netBaseUrl${routes.Blog.show(doc.id, doc.slug).url}", + description = ~doc.getText("blog.shortlede") + ).some, + moreCss = cssTag("blog"), + csp = bits.csp + )( + main(cls := s"blog page-small box post ${~doc.getText("blog.cssClasses")}")( + h1( + a(href := routes.Blog.index(), dataIcon := "I", cls := "text"), + doc.getText("blog.title") + ), + bits.metas(doc), + doc.getImage("blog.image", "main").map { img => + div(cls := "illustration")(st.img(src := img.url)) + }, + div(cls := "body embed_analyse")( + doc.getHtml("blog.body", prismic.linkResolver).map(lila.blog.Youtube.fixStartTimes).map(lila.blog.ProtocolFix.remove).map(raw) + ), + NotForKids { + div(cls := "footer")( + if (prismic.maybeRef.isEmpty) { + (doc.getDate("blog.date").exists(_.value.toDateTimeAtStartOfDay isAfter org.joda.time.DateTime.now.minusWeeks(2))) option + a(href := routes.Blog.discuss(doc.id), cls := "button text discuss", dataIcon := "d")("Discuss this blog post in the forum") + } else p("This is a preview.") + ) + } + ) + ) +} diff --git a/app/views/blog/show.scala.html b/app/views/blog/show.scala.html deleted file mode 100644 index b0ae755726..0000000000 --- a/app/views/blog/show.scala.html +++ /dev/null @@ -1,44 +0,0 @@ -@(doc: io.prismic.Document)(implicit ctx: Context, prismic: lila.blog.BlogApi.Context) - -@side = { -
-Return to blog -
-
-Subscribe -} - -@layout( -title = s"${~doc.getText("blog.title")} | Blog", -side = side.some, -openGraph = lila.app.ui.OpenGraph( -`type` = "article", -image = doc.getImage("blog.image", "main").map(_.url), -title = ~doc.getText("blog.title"), -url = s"$netBaseUrl${routes.Blog.show(doc.id, doc.slug).url}", -description = ~doc.getText("blog.shortlede")).some) { -
-

@doc.getText("blog.title")

- @meta(doc) - @doc.getHtml("blog.shortlede", prismic.linkResolver).map(Html.apply) -
- @doc.getImage("blog.image", "main").map { img => - - } -
-
- @doc.getHtml("blog.body", prismic.linkResolver).map(lila.blog.Youtube.fixStartTimes).map(lila.blog.ProtocolFix.remove).map(Html.apply) -
- @NotForKids { - - } -
-} diff --git a/app/views/board/bits.scala b/app/views/board/bits.scala index 6d3f92d9a7..8a5035c21f 100644 --- a/app/views/board/bits.scala +++ b/app/views/board/bits.scala @@ -32,17 +32,13 @@ object bits { "i18n" -> i18nJsObject(translations)(ctxLang(ctx)) ) - def domPreload(pov: Option[lila.game.Pov])(implicit ctx: Context) = { + def domPreload(pov: Option[lila.game.Pov])(implicit ctx: Context): Frag = { val theme = ctx.currentTheme - div(cls := "lichess_game")( - div(cls := "lichess_board_wrap")( - div(cls := "lichess_board")( - (!ctx.pref.is3d) option raw(s""" + frag( + (!ctx.pref.is3d) option raw(s""" """), - pov.fold(miniBoardContent)(chessground) - ) - ) + pov.fold(chessgroundSvg)(chessground) ) } diff --git a/app/views/board/editor.scala b/app/views/board/editor.scala index d3009c35f2..136cc770d2 100644 --- a/app/views/board/editor.scala +++ b/app/views/board/editor.scala @@ -20,17 +20,22 @@ object editor { title = trans.boardEditor.txt(), moreJs = frag( jsAt(s"compiled/lichess.editor${isProd ?? (".min")}.js"), - embedJs(s"""var data=${safeJsonValue(bits.jsData(sit, fen, animationDuration))};data.positions=$positionsJson; -LichessEditor(document.getElementById('board_editor'), data);""") + embedJsUnsafe(s"""var data=${safeJsonValue(bits.jsData(sit, fen, animationDuration))};data.positions=$positionsJson; +LichessEditor(document.getElementById('board-editor'), data);""") ), - moreCss = cssTag("boardEditor.css"), + moreCss = cssTag("editor"), chessground = false, + zoomable = true, openGraph = lila.app.ui.OpenGraph( title = "Chess board editor", url = s"$netBaseUrl${routes.Editor.index.url}", description = "Load opening positions or create your own chess position on a chess board editor" ).some - ) { - div(id := "board_editor", cls := "board_editor cg-512") - } + )(main(id := "board-editor")( + div(cls := "board-editor")( + div(cls := "spare"), + div(cls := "main-board")(chessgroundSvg), + div(cls := "spare") + ) + )) } diff --git a/app/views/board/userAnalysis.scala b/app/views/board/userAnalysis.scala index d858af57a9..bb6763549f 100644 --- a/app/views/board/userAnalysis.scala +++ b/app/views/board/userAnalysis.scala @@ -1,6 +1,8 @@ package views.html.board -import play.api.libs.json.JsObject +import play.api.libs.json.{ Json, JsObject } + +import chess.variant.Crazyhouse import lila.api.Context import lila.app.templating.Environment._ @@ -14,29 +16,27 @@ object userAnalysis { def apply(data: JsObject, pov: lila.game.Pov)(implicit ctx: Context) = views.html.base.layout( title = trans.analysis.txt(), - moreCss = cssTags(List( - "analyse.css" -> true, - "forecast.css" -> (!pov.game.synthetic && pov.game.playable && ctx.me.flatMap(pov.game.player).isDefined) - )), + moreCss = frag( + cssTag("analyse.free"), + pov.game.variant == Crazyhouse option cssTag("analyse.zh"), + !pov.game.synthetic && pov.game.playable && ctx.me.flatMap(pov.game.player).isDefined option cssTag("analyse.forecast"), + ctx.blind option cssTag("round.nvui") + ), moreJs = frag( analyseTag, analyseNvuiTag, - embedJs(s"""lichess=lichess||{};lichess.user_analysis={data:${safeJsonValue(data)},i18n:${ - userAnalysisI18n( - withForecast = !pov.game.synthetic && pov.game.playable && ctx.me.flatMap(pov.game.player).isDefined - ) - },explorer:{endpoint:"$explorerEndpoint",tablebaseEndpoint:"$tablebaseEndpoint"}};""") - ), - side = pov.game.synthetic option div(cls := "mselect")( - div(cls := "button", dataIcon := iconByVariant(pov.game.variant))( - pov.game.variant.name, - iconTag("u") - ), - div(cls := "list")( - chess.variant.Variant.all.filterNot(chess.variant.FromPosition ==).map { v => - a(dataIcon := iconByVariant(v), href := routes.UserAnalysis.parse(v.key))(v.name) - } - ) + embedJsUnsafe(s"""lichess=lichess||{};lichess.user_analysis=${ + safeJsonValue(Json.obj( + "data" -> data, + "i18n" -> userAnalysisI18n( + withForecast = !pov.game.synthetic && pov.game.playable && ctx.me.flatMap(pov.game.player).isDefined + ), + "explorer" -> Json.obj( + "endpoint" -> explorerEndpoint, + "tablebaseEndpoint" -> tablebaseEndpoint + ) + )) + }""") ), chessground = false, openGraph = lila.app.ui.OpenGraph( @@ -46,6 +46,23 @@ object userAnalysis { ).some, zoomable = true ) { - div(cls := "analyse cg-512")(views.html.board.bits.domPreload(none)) + main(cls := "analyse")( + pov.game.synthetic option st.aside(cls := "analyse__side")( + views.html.base.bits.mselect( + "analyse-variant", + span(cls := "text", dataIcon := iconByVariant(pov.game.variant))(pov.game.variant.name), + chess.variant.Variant.all.filter(chess.variant.FromPosition !=).map { v => + a( + dataIcon := iconByVariant(v), + cls := (pov.game.variant == v).option("current"), + href := routes.UserAnalysis.parse(v.key) + )(v.name) + } + ) + ), + div(cls := "analyse__board main-board")(chessgroundSvg), + div(cls := "analyse__tools"), + div(cls := "analyse__controls") + ) } } diff --git a/app/views/board/userAnalysisI18n.scala b/app/views/board/userAnalysisI18n.scala index 58ad78d819..56384c256e 100644 --- a/app/views/board/userAnalysisI18n.scala +++ b/app/views/board/userAnalysisI18n.scala @@ -2,7 +2,7 @@ package views.html.board import lila.api.Context import lila.app.templating.Environment._ -import lila.common.String.html.safeJsonValue +import lila.common.Lang import lila.i18n.{ I18nKeys => trans } object userAnalysisI18n { @@ -11,7 +11,7 @@ object userAnalysisI18n { withCeval: Boolean = true, withExplorer: Boolean = true, withForecast: Boolean = false - )(implicit ctx: Context) = safeJsonValue(i18nJsObject( + )(implicit lang: Lang) = i18nJsObject( baseTranslations ++ { withCeval ?? cevalTranslations } ++ { @@ -19,7 +19,7 @@ object userAnalysisI18n { } ++ { withForecast ?? forecastTranslations } - )) + ) private val baseTranslations = Vector( trans.analysis, diff --git a/app/views/bookmark.scala b/app/views/bookmark.scala index f92ff57998..feb6bcc933 100644 --- a/app/views/bookmark.scala +++ b/app/views/bookmark.scala @@ -11,9 +11,8 @@ object bookmark { def toggle(g: lila.game.Game, bookmarked: Boolean)(implicit ctx: Context) = ctx.me map { m => a(cls := List( "bookmark" -> true, - "bookmarked" -> bookmarked, - "hint--top" -> true - ), href := routes.Bookmark.toggle(g.id), dataHint := trans.bookmarkThisGame.txt())( + "bookmarked" -> bookmarked + ), href := routes.Bookmark.toggle(g.id), title := trans.bookmarkThisGame.txt())( iconTag("t")(cls := "on is3"), iconTag("s")(cls := "off is3"), span(g.showBookmarks) diff --git a/app/views/challenge/bits.scala b/app/views/challenge/bits.scala new file mode 100644 index 0000000000..402334acb8 --- /dev/null +++ b/app/views/challenge/bits.scala @@ -0,0 +1,46 @@ +package views.html.challenge + +import play.api.libs.json.Json + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.challenge.Challenge +import lila.common.String.html.safeJsonValue + +import controllers.routes + +object bits { + + def js(c: Challenge, json: play.api.libs.json.JsObject, owner: Boolean)(implicit ctx: Context) = + frag( + jsTag("challenge.js", defer = true), + embedJsUnsafe(s"""lichess=window.lichess||{};customWs=true;lichess_challenge = ${ + safeJsonValue(Json.obj( + "socketUrl" -> routes.Challenge.websocket(c.id, apiVersion.value).url, + "xhrUrl" -> routes.Challenge.show(c.id).url, + "owner" -> owner, + "data" -> json + )) + }""") + ) + + def details(c: Challenge)(implicit ctx: Context) = div(cls := "details")( + div(cls := "variant", dataIcon := (if (c.initialFen.isDefined) '*' else c.perfType.iconChar))( + div( + if (c.variant.exotic) + views.html.game.bits.variantLink(c.variant, variantName(c.variant)) + else + c.perfType.name, + br, + span(cls := "clock")( + c.daysPerTurn map { days => + if (days == 1) trans.oneDay() + else trans.nbDays.pluralSame(days) + } getOrElse shortClockName(c.clock.map(_.config)) + ) + ) + ), + div(cls := "mode")(modeName(c.mode)) + ) +} diff --git a/app/views/challenge/explanation.scala.html b/app/views/challenge/explanation.scala.html deleted file mode 100644 index f92ea9b781..0000000000 --- a/app/views/challenge/explanation.scala.html +++ /dev/null @@ -1,10 +0,0 @@ -@(c: lila.challenge.Challenge)(implicit ctx: Context) - -

- @views.html.game.bits.variantLink(c.variant, variantName(c.variant)).toHtml • @modeName(c.mode)
- @c.daysPerTurn.map { days => - @if(days == 1){@trans.oneDay()}else{@trans.nbDays.pluralSame(days)} - }.getOrElse { - @shortClockName(c.clock.map(_.config)) - } -

diff --git a/app/views/challenge/js.scala.html b/app/views/challenge/js.scala.html deleted file mode 100644 index ebbbbc49cf..0000000000 --- a/app/views/challenge/js.scala.html +++ /dev/null @@ -1,11 +0,0 @@ -@(c: lila.challenge.Challenge, json: play.api.libs.json.JsObject, owner: Boolean)(implicit ctx: Context) - -@embedJs { -lichess_challenge = { -socketUrl: '@routes.Challenge.websocket(c.id, apiVersion.value)', -xhrUrl: '@routes.Challenge.show(c.id)', -owner: @owner, -data: @toJsonHtml(json) -}; -} -@jsTag("challenge.js", async = false) diff --git a/app/views/challenge/mine.scala b/app/views/challenge/mine.scala new file mode 100644 index 0000000000..db90885338 --- /dev/null +++ b/app/views/challenge/mine.scala @@ -0,0 +1,88 @@ +package views.html.challenge + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.challenge.Challenge.Status + +import controllers.routes + +object mine { + + def apply(c: lila.challenge.Challenge, json: play.api.libs.json.JsObject, error: Option[String])(implicit ctx: Context) = { + + val cancelForm = + form(method := "post", action := routes.Challenge.cancel(c.id), cls := "cancel xhr")( + button(tpe := "submit", cls := "button button-red text", dataIcon := "L")(trans.cancel()) + ) + + views.html.base.layout( + title = challengeTitle(c), + openGraph = challengeOpenGraph(c).some, + moreJs = bits.js(c, json, true), + moreCss = cssTag("challenge.page") + ) { + main(cls := "page-small challenge-page box box-pad")( + c.status match { + case Status.Created | Status.Offline => div(id := "ping-challenge")( + h1(trans.challengeToPlay()), + bits.details(c), + c.destUserId.map { destId => + div(cls := "waiting")( + userIdLink(destId.some, cssClass = "target".some), + spinner, + p(trans.waitingForOpponent()) + ) + } getOrElse div(cls := "invite")( + div( + h2(cls := "ninja-title", trans.toInviteSomeoneToPlayGiveThisUrl(), ": "), br, + p(cls := "challenge-id-form")( + input( + id := "challenge-id", + cls := "copyable autoselect", + spellcheck := "false", + readonly, + value := s"$netBaseUrl${routes.Round.watcher(c.id, "white")}" + ), + button(title := "Copy URL", cls := "copy button", dataRel := "challenge-id", dataIcon := "\"") + ), + p(trans.theFirstPersonToComeOnThisUrlWillPlayWithYou()) + ), + ctx.isAuth option div( + h2(cls := "ninja-title", "Or invite a lichess user:"), br, + form(cls := "user-invite", action := routes.Challenge.toFriend(c.id), method := "POST")( + input(name := "username", cls := "friend-autocomplete", placeholder := trans.search.txt()), + error.map { badTag(_) } + ) + ) + ), + c.notableInitialFen.map { fen => + frag( + br, + div(cls := "board-preview", views.html.game.bits.miniBoard(fen, color = c.finalColor)) + ) + }, + cancelForm + ) + case Status.Declined => div(cls := "follow-up")( + h1("Challenge declined"), + bits.details(c), + a(cls := "button button-fat", href := routes.Lobby.home())(trans.newOpponent()) + ) + case Status.Accepted => div(cls := "follow-up")( + h1("Challenge accepted!"), + bits.details(c), + a(id := "challenge-redirect", href := routes.Round.watcher(c.id, "white"), cls := "button-fat")( + trans.joinTheGame() + ) + ) + case Status.Canceled => div(cls := "follow-up")( + h1("Challenge canceled."), + bits.details(c), + a(cls := "button button-fat", href := routes.Lobby.home())(trans.newOpponent()) + ) + } + ) + } + } +} diff --git a/app/views/challenge/mine.scala.html b/app/views/challenge/mine.scala.html deleted file mode 100644 index 4dec9bb59f..0000000000 --- a/app/views/challenge/mine.scala.html +++ /dev/null @@ -1,81 +0,0 @@ -@(c: lila.challenge.Challenge, json: play.api.libs.json.JsObject, error: Option[String])(implicit ctx: Context) - -@import lila.challenge.Challenge.Status - -@cancelForm = { -
- -
-} - -@round.bits.layout( -title = challengeTitle(c), -side = none, -openGraph = challengeOpenGraph(c).some, -moreJs = js(c, json, true), -moreCss = cssTag("challenge.css")) { -
-
-
- @c.status match { - case Status.Created | Status.Offline => { -
-

@trans.challengeToPlay()

- @c.destUserId.map { destId => - @userIdLink(destId.some, cssClass="target".some) - @spinner - @trans.waitingForOpponent()
- @cancelForm - }.getOrElse { - @trans.toInviteSomeoneToPlayGiveThisUrl(): - - -
- @trans.theFirstPersonToComeOnThisUrlWillPlayWithYou() -
- @if(ctx.isAuth) { -
- Or invite a lichess user:
-
- - @error.map { e => -

@e

- } -
-
- } - @cancelForm - } - @c.initialFen.map { fen => -
- @views.html.game.bits.miniBoard(fen, color = c.finalColor) - } -
- } - case Status.Declined => { -
-

Challenge declined

- @trans.newOpponent() -
- } - case Status.Accepted => { -
-

Challenge accepted!

- @trans.joinTheGame() -
- } - case Status.Canceled => { -
-

Challenge canceled.

- @trans.newOpponent() -
- } - } -
- @explanation(c) -
-
-
-
-
-}.toHtml diff --git a/app/views/challenge/theirs.scala b/app/views/challenge/theirs.scala new file mode 100644 index 0000000000..360e9fb3c5 --- /dev/null +++ b/app/views/challenge/theirs.scala @@ -0,0 +1,74 @@ +package views.html.challenge + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.challenge.Challenge.Status + +import controllers.routes + +object theirs { + + def apply( + c: lila.challenge.Challenge, + json: play.api.libs.json.JsObject, + user: Option[lila.user.User] + )(implicit ctx: Context) = + views.html.base.layout( + title = challengeTitle(c), + openGraph = challengeOpenGraph(c).some, + moreJs = bits.js(c, json, false), + moreCss = cssTag("challenge.page") + ) { + main(cls := "page-small challenge-page challenge-theirs box box-pad")( + c.status match { + case Status.Created | Status.Offline => frag( + h1(user.fold[Frag]("Anonymous")(u => + frag( + userLink(u), + " (", u.perfs(c.perfType).glicko.display, ")" + ))), + bits.details(c), + c.notableInitialFen.map { fen => + div(cls := "board-preview", views.html.game.bits.miniBoard(fen, color = !c.finalColor)) + }, + if (!c.mode.rated || ctx.isAuth) frag( + (c.mode.rated && c.unlimited) option + badTag(trans.bewareTheGameIsRatedButHasNoClock()), + form(cls := "accept", action := routes.Challenge.accept(c.id), method := "post")( + button(tpe := "submit", cls := "text button button-fat", dataIcon := "G")(trans.joinTheGame()) + ) + ) + else frag( + hr, + badTag( + p("This game is rated"), + p( + "You must ", + a(cls := "button", href := s"${routes.Auth.login}?referrer=${routes.Round.watcher(c.id, "white")}")(trans.signIn()), + " to join it." + ) + ) + ) + ) + case Status.Declined => div(cls := "follow-up")( + h1("Challenge declined"), + bits.details(c), + a(cls := "button button-fat", href := routes.Lobby.home())(trans.newOpponent()) + ) + case Status.Accepted => div(cls := "follow-up")( + h1("Challenge accepted!"), + bits.details(c), + a(id := "challenge-redirect", href := routes.Round.watcher(c.id, "white"), cls := "button button-fat")( + trans.joinTheGame() + ) + ) + case Status.Canceled => div(cls := "follow-up")( + h1("Challenge canceled."), + bits.details(c), + a(cls := "button button-fat", href := routes.Lobby.home())(trans.newOpponent()) + ) + } + ) + } +} diff --git a/app/views/challenge/theirs.scala.html b/app/views/challenge/theirs.scala.html deleted file mode 100644 index 0bc23d3e62..0000000000 --- a/app/views/challenge/theirs.scala.html +++ /dev/null @@ -1,58 +0,0 @@ -@(c: lila.challenge.Challenge, json: play.api.libs.json.JsObject)(implicit ctx: Context) - -@import lila.challenge.Challenge.Status - -@round.bits.layout( -title = challengeTitle(c), -side = none, -openGraph = challengeOpenGraph(c).some, -moreJs = js(c, json, false)) { -
-
-
-
- @userIdLink(c.challengerUserId) -
- @explanation(c) - @c.initialFen.map { fen => -
- @views.html.game.bits.miniBoard(fen, color = !c.finalColor) - } -
- @c.status match { - case Status.Created | Status.Offline => { - @if(!c.mode.rated || ctx.isAuth) { - @if(c.mode.rated && c.unlimited) { -
@trans.bewareTheGameIsRatedButHasNoClock()
- } -
- -
- } else { -
-

This game is rated
You must log in to join it.

- } - } - case Status.Declined => { -
-

Challenge declined

- @trans.newOpponent() -
- } - case Status.Accepted => { -
-

Challenge accepted!

- @trans.joinTheGame() -
- } - case Status.Canceled => { -
-

Challenge canceled.

- @trans.newOpponent() -
- } - } -
-
-
-}.toHtml diff --git a/app/views/chat.scala b/app/views/chat.scala index c46a1dbfe7..dee557fdf4 100644 --- a/app/views/chat.scala +++ b/app/views/chat.scala @@ -1,16 +1,20 @@ package views.html import play.api.libs.json.Json -import play.twirl.api.Html -import scalatags.Text.RawFrag import lila.api.Context import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ import lila.i18n.I18nKeys object chat { - val frag = RawFrag("""""") + val frag = st.section(cls := "mchat")( + div(cls := "mchat__tabs")( + div(cls := "mchat__tab")(nbsp) + ), + div(cls := "mchat__content") + ) import lila.chat.JsonView.chatIdWrites diff --git a/app/views/coach/barRating.scala.html b/app/views/coach/barRating.scala.html deleted file mode 100644 index 0e65bd60fe..0000000000 --- a/app/views/coach/barRating.scala.html +++ /dev/null @@ -1,14 +0,0 @@ -@(selected: Option[Int], enabled: Boolean) - -@if(enabled) { - -} else { -
-
@Html(List(1, 2, 3, 4, 5).map(s => s"").mkString)
-
-} diff --git a/app/views/coach/edit.scala b/app/views/coach/edit.scala new file mode 100644 index 0000000000..54364cfc47 --- /dev/null +++ b/app/views/coach/edit.scala @@ -0,0 +1,117 @@ +package views.html.coach + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator +import lila.common.String.html.richText + +import controllers.routes + +object edit { + + private val dataTab = attr("data-tab") + private val dataValue = attr("data-value") + + def apply(c: lila.coach.Coach.WithUser, form: Form[_], reviews: lila.coach.CoachReview.Reviews)(implicit ctx: Context) = { + views.html.account.layout( + title = s"${c.user.titleUsername} coach page", + evenMoreCss = cssTag("coach.editor"), + evenMoreJs = frag( + jsAt("vendor/jquery.form.min.js"), + jsAt("vendor/bar-rating/dist/jquery.barrating.min.js"), + jsTag("coach.form.js") + ), + active = "coach" + )( + div(cls := "account coach-edit box")( + div(cls := "top")( + div(cls := "picture_wrap")( + if (c.coach.hasPicture) + a(cls := "upload_picture", href := routes.Coach.picture, title := "Change/delete your profile picture")( + widget.pic(c, 250) + ) + else div(cls := "upload_picture")( + a(cls := "button", href := routes.Coach.picture)("Upload a profile picture") + ) + ), + div(cls := "overview")( + h1(widget.titleName(c)), + div(cls := "todo", attr("data-profile") := c.user.profileOrDefault.isComplete)( + h3("TODO list before publishing your coach profile"), + ul + ), + div( + a(href := routes.Coach.show(c.user.username), cls := "button button-empty text", dataIcon := "v")("Preview coach page") + ) + ) + ), + st.form(cls := "box__pad form3 async", action := routes.Coach.edit, method := "POST")( + div(cls := "tabs")( + div(dataTab := "basics", cls := "active")("Basics"), + div(dataTab := "texts")("Texts"), + div(dataTab := "contents")("Contents"), + div(dataTab := "reviews", dataCount := reviews.list.size, cls := "data-count")( + "Pending reviews" + ) + ), + div(cls := "panels")( + div(cls := "panel basics active")( + form3.split( + form3.checkbox(form("listed"), raw("Publish on the coaches list"), help = raw("Enable when your profile is ready").some, half = true), + form3.checkbox(form("available"), raw("Currently available for lessons"), help = raw("Enable to get more students").some, half = true) + ), + form3.group(form("profile.headline"), raw("Short and inspiring headline"), help = raw("Just one sentence to make students want to choose you (3 to 170 chars)").some)(form3.input(_)), + form3.split( + form3.group(form("profile.languages"), raw("Languages spoken"), help = raw("Which languages can you give lessons in? (3 to 140 chars)").some, half = true)(form3.input(_)), + form3.group(form("profile.hourlyRate"), raw("Hourly rate"), help = raw("Indicative, non-contractual (3 to 140 chars)").some, half = true)(form3.input(_)) + ) + ), + div(cls := "panel texts")( + form3.group(form("profile.description"), raw("Who are you?"), help = raw("Age, profession, country... let your students know you").some)(form3.textarea(_)(rows := 8)), + form3.group(form("profile.playingExperience"), raw("Playing experience"), help = raw("Tournaments played, best wins, other achievements").some)(form3.textarea(_)(rows := 8)), + form3.group(form("profile.teachingExperience"), raw("Teaching experience"), help = raw("Diplomas, years of practice, best student results").some)(form3.textarea(_)(rows := 8)), + form3.group(form("profile.otherExperience"), raw("Other experiences"), help = raw("E.g. as chess commentator, or teaching other domains").some)(form3.textarea(_)(rows := 8)), + form3.group(form("profile.skills"), raw("Best skills in chess and teaching"))(form3.textarea(_)(rows := 8)), + form3.group(form("profile.methodology"), raw("Teaching methodology"), help = raw("How you prepare and run lessons. How you follow up with students.").some)(form3.textarea(_)(rows := 8)) + ), + div(cls := "panel contents")( + form3.group(form("profile.publicStudies"), raw("Featured public lichess studies"), help = raw("Up to 6 lichess study URLs, one per line").some)(form3.textarea(_)()), + form3.group(form("profile.youtubeChannel"), raw("URL of your Youtube channel"))(form3.input(_)), + form3.group(form("profile.youtubeVideos"), raw("Featured youtube videos"), help = raw("Up to 6 Youtube video URLs, one per line").some)(form3.textarea(_)(rows := 6)) + ), + div(cls := "panel reviews")( + p(cls := "help text", dataIcon := "")("Reviews are visible only after you approve them."), + reviews.list.map { r => + div(cls := "review", attr("data-action") := routes.Coach.approveReview(r.id))( + div(cls := "user")( + userIdLink(r.userId.some), + review.barRating(selected = r.score.some, enabled = false), + momentFromNow(r.updatedAt) + ), + div(cls := "content")( + r.moddedAt.isDefined option div(cls := "modded")( + "Moderators have disapproved this review. Please only accept reviews from ", + "actual students, based on actual lessons. Reviews must be about your coaching services.", + br, + "You may delete this review, or ask the author to rephrase it, then approve it." + ), + richText(r.text) + ), + div(cls := "actions btn-rack")( + r.moddedAt.fold(true)(_.isBefore(r.updatedAt)) option + a(dataValue := "1", cls := "btn-rack__btn yes", dataIcon := "E"), + a(dataValue := "0", cls := "btn-rack__btn no", dataIcon := "L") + ) + ) + } + ) + ), + div(cls := "status text", dataIcon := "E")("Your changes have been saved.") + ) + ) + ) + } +} diff --git a/app/views/coach/edit.scala.html b/app/views/coach/edit.scala.html deleted file mode 100644 index 26df706349..0000000000 --- a/app/views/coach/edit.scala.html +++ /dev/null @@ -1,109 +0,0 @@ -@(c: lila.coach.Coach.WithUser, form: Form[_], reviews: lila.coach.CoachReview.Reviews)(implicit ctx: Context) -@import lila.app.ui.ScalatagsTwirlForm._ - -@moreJs = { -@jsAt("vendor/jquery.form.min.js") -@jsAt("vendor/bar-rating/dist/jquery.barrating.min.js") -@jsTag("coach.form.js") -} - -@side = { -Preview coach page -} - -@base.layout(title = s"${c.user.titleUsername} coach page", -moreCss = cssTags("form3.css", "coach.form.css"), -moreJs = moreJs, -side = side.some) { -
-
-
- @if(c.coach.hasPicture) { - - @pic(c, 250) - - } else { - - } -
-
-

- @c.user.title.map { t => @t }@c.user.profileOrDefault.nonEmptyRealName.getOrElse(c.user.username) -

-
-

TODO list before publishing your coach profile

-
    -
    -
    -
    -
    -
    -
    Basics
    -
    Texts
    -
    Contents
    -
    - Pending reviews -
    -
    -
    -
    - @form3.split { - @form3.checkbox(form("listed"), raw("Publish on the coaches list"), help = raw("Enable when your profile is ready").some, half = true) - @form3.checkbox(form("available"), raw("Currently available for lessons"), help = raw("Enable to get more students").some, half = true) - } - @form3.group(form("profile.headline"), raw("Short and inspiring headline"), help = raw("Just one sentence to make students want to choose you").some)(form3.input(_)) - @form3.split { - @form3.group(form("profile.languages"), raw("Languages spoken"), help = raw("Which languages can you give lessons in?").some, half = true)(form3.input(_)) - @form3.group(form("profile.hourlyRate"), raw("Hourly rate"), help = raw("Indicative, non-contractual").some, half = true)(form3.input(_)) - } -
    -
    - @form3.group(form("profile.description"), raw("Who are you?"), help = raw("Age, profession, country... let your students know you").some)(form3.textarea(_)(*.rows := 8)) - @form3.group(form("profile.playingExperience"), raw("Playing experience"), help = raw("Tournaments played, best wins, other achievements").some)(form3.textarea(_)(*.rows := 8)) - @form3.group(form("profile.teachingExperience"), raw("Teaching experience"), help = raw("Diplomas, years of practice, best student results").some)(form3.textarea(_)(*.rows := 8)) - @form3.group(form("profile.otherExperience"), raw("Other experiences"), help = raw("E.g. as chess commentator, or teaching other domains").some)(form3.textarea(_)(*.rows := 8)) - @form3.group(form("profile.skills"), raw("Best skills in chess and teaching"))(form3.textarea(_)(*.rows := 8)) - @form3.group(form("profile.methodology"), raw("Teaching methodology"), help = raw("How you prepare and run lessons. How you follow up with students.").some)(form3.textarea(_)(*.rows := 8)) -
    -
    - @form3.group(form("profile.publicStudies"), raw("Featured public lichess studies"), help = raw("Up to 6 lichess study URLs, one per line").some)(form3.textarea(_)()) - @form3.group(form("profile.youtubeChannel"), raw("URL of your Youtube channel"))(form3.input(_)) - - @form3.group(form("profile.youtubeVideos"), raw("Featured youtube videos"), help = raw("Up to 6 Youtube video URLs, one per line").some)(form3.textarea(_)(*.rows := 6)) -
    -
    -

    Reviews are visible only after you approve them.

    - @reviews.list.map { r => -
    -
    - @userIdLink(r.userId.some) - @barRating(selected = r.score.some, enabled = false) - @momentFromNow(r.updatedAt) -
    -
    - @if(r.moddedAt.isDefined) { -
    - Moderators have disapproved this review. Please only accept reviews from - actual students, based on actual lessons. Reviews must be about your coaching services. -
    - You may delete this review, or ask the author to rephrase it, then approve it. -
    - } - @richText(r.text) -
    -
    - @if(r.moddedAt.fold(true)(_.isBefore(r.updatedAt))) { - - } - -
    -
    - } -
    -
    -
    Your changes have been saved.
    -
    -
    -}.toHtml diff --git a/app/views/coach/index.scala b/app/views/coach/index.scala new file mode 100644 index 0000000000..acb954bd21 --- /dev/null +++ b/app/views/coach/index.scala @@ -0,0 +1,52 @@ +package views.html +package coach + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator + +import controllers.routes + +object index { + + def apply(pager: Paginator[lila.coach.Coach.WithUser], order: lila.coach.CoachPager.Order)(implicit ctx: Context) = + views.html.base.layout( + title = "Lichess coaches", + moreCss = cssTag("coach"), + moreJs = infiniteScrollTag + ) { + main(cls := "coach-list coach-full-page")( + st.aside(cls := "coach-list__side coach-side")( + p( + "Are you a great chess coach?", br, + "Do you have a ", a(href := "https://lichess.org/help/master")("FIDE title"), "?", br, + "Send us an email at ", contactEmailLink, br, + "and we will review your application." + ) + ), + div(cls := "coach-list__main coach-main box")( + div(cls := "box__top")( + h1("Top chess coaches"), + div(cls := "box__top__actions")( + views.html.base.bits.mselect( + "coach-sort", + order.name, + lila.coach.CoachPager.Order.all map { o => + a(href := routes.Coach.all(o.key), cls := (order == o).option("current"))(o.name) + } + ) + ) + ), + div(cls := "list infinitescroll")( + pager.currentPageResults.map { c => + st.article(cls := "coach-widget paginated", attr("data-dedup") := c.coach.id.value)(widget(c, link = true)) + }, + pagerNext(pager, np => addQueryParameter(routes.Coach.all(order.key).url, "page", np)).map { + frag(_, div(cls := "none")) // don't break the even/odd CSS flow + } + ) + ) + ) + } +} diff --git a/app/views/coach/index.scala.html b/app/views/coach/index.scala.html deleted file mode 100644 index 9c82c9c3b3..0000000000 --- a/app/views/coach/index.scala.html +++ /dev/null @@ -1,46 +0,0 @@ -@(pager: Paginator[lila.coach.Coach.WithUser], order: lila.coach.CoachPager.Order)(implicit ctx: Context) - -@side = { -
    -

    - Are you a great chess coach?
    - Do you have a FIDE title?
    - Send us an email at @contactEmailLink
    - and we will review your application. -

    -
    -} - -@base.layout(title = "Lichess coaches", -moreCss = cssTag("coach.list.css"), -moreJs = infiniteScrollTag, -side = side.some) { -
    -
    -

    Top chess coaches

    -
    -
    - @order.name - -
    -
    - @lila.coach.CoachPager.Order.all.map { o => - @o.name - } -
    -
    -
    -
    - @pager.currentPageResults.map { c => -
    - @widget(c) -
    - } - @pager.nextPage.map { np => -
    - -
    - } -
    -
    -}.toHtml diff --git a/app/views/coach/pic.scala.html b/app/views/coach/pic.scala.html deleted file mode 100644 index 652fa62a4c..0000000000 --- a/app/views/coach/pic.scala.html +++ /dev/null @@ -1,6 +0,0 @@ -@(c: lila.coach.Coach.WithUser, size: Int)(implicit ctx: Context) -@c.coach.picturePath.map { path => -@c.user.titleUsername lichess coach -}.getOrElse { - -} diff --git a/app/views/coach/picture.scala b/app/views/coach/picture.scala new file mode 100644 index 0000000000..3fc1dde3f2 --- /dev/null +++ b/app/views/coach/picture.scala @@ -0,0 +1,45 @@ +package views.html +package coach + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object picture { + + def apply(c: lila.coach.Coach.WithUser, error: Option[String] = None)(implicit ctx: Context) = + views.html.account.layout( + title = s"${c.user.titleUsername} coach picture", + evenMoreJs = jsTag("coach.form.js"), + evenMoreCss = cssTag("coach.editor"), + active = "coach" + ) { + div(cls := "account coach-edit coach-picture box")( + div(cls := "top")( + div(cls := "picture_wrap")( + widget.pic(c, 250) + ), + h1(widget.titleName(c)) + ), + div(cls := "forms")( + error.map { e => + p(cls := "error")(e) + }, + st.form(action := routes.Coach.pictureApply, enctype := "multipart/form-data", method := "post", cls := "upload")( + p("Max size: ", lila.db.Photographer.uploadMaxMb, "MB."), + form3.file.image("picture"), + form3.actions( + a(href := routes.Coach.edit())(trans.cancel()), + form3.submit("Upload profile picture") + ) + ), + c.coach.hasPicture option + st.form(action := routes.Coach.pictureDelete, cls := "delete")( + button(tpe := "submit", cls := "confirm button button-empty button-red")("Delete profile picture") + ) + ) + ) + } +} diff --git a/app/views/coach/picture.scala.html b/app/views/coach/picture.scala.html deleted file mode 100644 index bf0b3966c0..0000000000 --- a/app/views/coach/picture.scala.html +++ /dev/null @@ -1,32 +0,0 @@ -@(c: lila.coach.Coach.WithUser, error: Option[String] = None)(implicit ctx: Context) - -@base.layout(title = s"${c.user.titleUsername} coach picture", -moreJs = jsTag("coach.form.js"), -moreCss = cssTags("form3.css", "coach.form.css")) { -
    -

    - @userLink(c.user) coach picture -

    -
    - @pic(c, 200) -
    -
    - @error.map { e => -

    @e

    - } - @helper.form(action = routes.Coach.pictureApply, 'enctype -> "multipart/form-data", 'class -> "upload") { -

    Max size: @{lila.db.Photographer.uploadMaxMb}MB.

    - @form3.file.image("picture") - - } - @if(c.coach.hasPicture) { - @helper.form(action = routes.Coach.pictureDelete, 'enctype -> "multipart/form-data", 'class -> "delete") { - - } - } - -
    -
    -}.toHtml diff --git a/app/views/coach/review.scala b/app/views/coach/review.scala new file mode 100644 index 0000000000..e54744e65c --- /dev/null +++ b/app/views/coach/review.scala @@ -0,0 +1,69 @@ +package views.html.coach + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.String.html.richText + +import controllers.routes + +object review { + + def list(c: lila.coach.Coach.WithUser, reviews: lila.coach.CoachReview.Reviews)(implicit ctx: Context) = + reviews.list.nonEmpty option div(cls := "coach-show__reviews")( + h2(pluralize("Player review", reviews.list.size)), + reviews.list.map { r => + div(cls := "coach-review")( + div(cls := "top")( + userIdLink(r.userId.some), + barRating(selected = r.score.some, enabled = false) + ), + div(cls := "content")(richText(r.text)), + isGranted(_.DisapproveCoachReview) option + st.form(cls := "disapprove", method := "post", action := routes.Coach.modReview(r.id))( + button(cls := "button button-empty button-red button-thin confirm", tpe := "submit", title := "Instructs the coach to reject the review, or to ask the author to rephrase it.")("Disapprove") + ) + ) + } + ) + + def form(c: lila.coach.Coach.WithUser, mine: Option[lila.coach.CoachReview])(implicit ctx: Context) = + div(cls := "coach-review-form")( + if (mine.exists(_.pendingApproval)) + div(cls := "approval")( + p("Thank you for the review!"), + p(c.user.realNameOrUsername, " will approve it very soon, or a moderator will have a look at it.") + ) + else if (ctx.isAuth) a(cls := "button button-empty toggle")("Write a review") + else a(href := s"${routes.Auth.login}?referrer=${ctx.req.path}", cls := "button")("Review this coach"), + st.form(action := routes.Coach.review(c.user.username), method := "POST")( + barRating(selected = mine.map(_.score), enabled = true), + textarea( + name := "text", + required, + minlength := 3, + maxlength := 2000, + placeholder := s"Describe your coaching experience with ${c.user.realNameOrUsername}" + )( + mine.map(_.text) + ), + button(tpe := "submit", cls := "button")(trans.apply()) + ) + ) + + def barRating(selected: Option[Int], enabled: Boolean) = + if (enabled) + select(cls := "bar-rating", name := "score", required)( + option(value := ""), + List(1, 2, 3, 4, 5).map { score => + option(value := score, selected.contains(score) option st.selected)(score) + } + ) + else div(cls := "br-wrapper")( + div(cls := "br-widget br-readonly")( + List(1, 2, 3, 4, 5).map { s => + a(cls := List("br-selected" -> selected.exists(s.<=))) + } + ) + ) +} diff --git a/app/views/coach/reviewForm.scala.html b/app/views/coach/reviewForm.scala.html deleted file mode 100644 index 61d38e7fec..0000000000 --- a/app/views/coach/reviewForm.scala.html +++ /dev/null @@ -1,24 +0,0 @@ -@(c: lila.coach.Coach.WithUser, mine: Option[lila.coach.CoachReview])(implicit ctx: Context) - -
    - @if(mine.exists(_.pendingApproval)) { -
    -

    Thank you for the review!

    -

    @c.user.realNameOrUsername will approve it very soon.

    -
    - } else { - @if(ctx.isAuth) { - Write a review - } else { - Review this coach - } - } - -
    - @barRating(selected = mine.map(_.score), enabled = true) - - -
    -
    diff --git a/app/views/coach/reviews.scala.html b/app/views/coach/reviews.scala.html deleted file mode 100644 index 39f33e7f16..0000000000 --- a/app/views/coach/reviews.scala.html +++ /dev/null @@ -1,21 +0,0 @@ -@(c: lila.coach.Coach.WithUser, reviews: lila.coach.CoachReview.Reviews)(implicit ctx: Context) - -@if(reviews.list.nonEmpty) { -
    -

    @pluralize("Player review", reviews.list.size)

    - @reviews.list.map { r => -
    -
    - @userIdLink(r.userId.some) - @barRating(selected = r.score.some, enabled = false) -
    -
    @richText(r.text)
    - @if(isGranted(_.DisapproveCoachReview)) { -
    -
    - } -
    -} diff --git a/app/views/coach/show.scala b/app/views/coach/show.scala new file mode 100644 index 0000000000..a4a42e3ff5 --- /dev/null +++ b/app/views/coach/show.scala @@ -0,0 +1,102 @@ +package views.html +package coach + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.String.html.richText + +import controllers.routes + +object show { + + private def section(title: String, text: Option[lila.coach.CoachProfile.RichText]) = text.map { t => + st.section( + h2(title), + div(cls := "content")(richText(t.value)) + ) + } + + def apply( + c: lila.coach.Coach.WithUser, + coachReviews: lila.coach.CoachReview.Reviews, + studies: Seq[lila.study.Study.WithChaptersAndLiked], + myReview: Option[lila.coach.CoachReview] + )(implicit ctx: Context) = { + val profile = c.coach.profile + val coachName = s"${c.user.title.??(t => s"$t ")}${c.user.realNameOrUsername}" + val title = s"$coachName coaches chess students" + views.html.base.layout( + title = title, + moreJs = frag( + jsAt("vendor/bar-rating/dist/jquery.barrating.min.js"), + ctx.isAuth option embedJsUnsafe("""$(function() { +$(".bar-rating").barrating(); +$('.coach-review-form .toggle').click(function() { +$(this).remove(); +$('.coach-review-form form').show(); +}); +});""") + ), + moreCss = cssTag("coach"), + openGraph = lila.app.ui.OpenGraph( + title = title, + description = shorten(~(c.coach.profile.headline), 152), + url = s"$netBaseUrl${routes.Coach.show(c.user.username)}", + `type` = "profile", + image = c.coach.picturePath.map(p => dbImageUrl(p.value)) + ).some + ) { + main(cls := "coach-show coach-full-page")( + st.aside(cls := "coach-show__side coach-side")( + a(cls := "button button-empty", href := routes.User.show(c.user.username))("View ", c.user.username, " lichess profile"), + if (ctx.me.exists(c.coach.is)) frag( + if (c.coach.isListed) p("This page is now public.") + else "This page is not public yet. ", + a(href := routes.Coach.edit, cls := "text", dataIcon := "m")("Edit my coach profile") + ) + else a(cls := "text button button-empty", dataIcon := "c", href := s"${routes.Message.form}?user=${c.user.username}")( + "Send a private message" + ), + ctx.me.exists(_.id != c.user.id) option review.form(c, myReview), + review.list(c, coachReviews) + ), + div(cls := "coach-show__main coach-main box")( + div(cls := "coach-widget")(widget(c, link = false)), + div(cls := "coach-show__sections")( + section("About me", profile.description), + section("Playing experience", profile.playingExperience), + section("Teaching experience", profile.teachingExperience), + section("Other experiences", profile.otherExperience), + section("Best skills", profile.skills), + section("Teaching methodology", profile.methodology) + ), + studies.nonEmpty option st.section(cls := "coach-show__studies")( + h2("Public studies"), + div(cls := "studies")( + studies.map { s => + st.article(cls := "study")(study.bits.widget(s, h3)) + } + ) + ), + profile.youtubeUrls.nonEmpty option st.section(cls := "coach-show__youtube")( + h2( + "Youtube videos", + profile.youtubeChannel.map { url => + frag( + " from my ", + a(href := url, target := "_blank", rel := "nofollow")("channel") + ) + } + ), + div(cls := "list")( + profile.youtubeUrls.map { url => + iframe(width := "256", height := "192", src := url.value, attr("frameborder") := "0", frame.allowfullscreen) + } + ) + ) + ) + ) + } + } +} diff --git a/app/views/coach/show.scala.html b/app/views/coach/show.scala.html deleted file mode 100644 index 92b80144e0..0000000000 --- a/app/views/coach/show.scala.html +++ /dev/null @@ -1,181 +0,0 @@ -@(c: lila.coach.Coach.WithUser, coachReviews: lila.coach.CoachReview.Reviews, studies: Seq[lila.study.Study.WithChaptersAndLiked], myReview: Option[lila.coach.CoachReview])(implicit ctx: Context) - -@moreCss = { -@cssTag("coach.css") -@if(studies.nonEmpty) { @cssTag("studyList.css") } -} - -@moreJs = { -@jsAt("vendor/bar-rating/dist/jquery.barrating.min.js") -@if(ctx.isAuth) { -@embedJs { -$(function() { -$(".bar-rating").barrating(); -$('.review-form .toggle').click(function() { -$(this).remove(); -$('.review-form form').show(); -}); -}); -} -} -} - -@side = { -
    - - @if(ctx.me.exists(_.id != c.user.id)) { - @reviewForm(c, myReview) - } - @reviews(c, coachReviews) -
    -} - -@section(title: String, text: Option[lila.coach.CoachProfile.RichText]) = { -@text.map { t => -
    -

    @title

    -
    @richText(t.value)
    -
    -} -} - -@coachName = @{ s"${c.user.title.??(t => s"$t ")}${c.user.realNameOrUsername}" } -@title = @{ s"$coachName coaches chess students" } - -@base.layout(title = title, -side = side.some, -moreJs = moreJs, -moreCss = moreCss, -openGraph = lila.app.ui.OpenGraph( -title = title, -description = shorten(~(c.coach.profile.headline), 152), -url = s"$netBaseUrl${routes.Coach.show(c.user.username)}", -`type` = "profile", -image = c.coach.picturePath.map(p => dbImageUrl(p.value))).some) { -
    -
    - @pic(c, 250) - @defining(c.user.profileOrDefault) { profile => -
    -

    - @c.user.title.map { t => @t }@c.user.realNameOrUsername -

    - @c.coach.profile.headline.map { h => -

    @h

    - } - - - - - - - @c.coach.profile.languages.map { l => - - - - - } - - - - - @c.coach.profile.hourlyRate.map { r => - - - - - } - - - - - @if(ctx.me.??(c.coach.is)) { - - - - - } else { - - - - - } - -
    Location - @profile.nonEmptyLocation.map { l => - @l, - } - @profile.countryInfo.map { c => - @c.name - } -
    Languages@l
    Rating - @profile.officialRating.map { r => - @r.name.toUpperCase: @r.rating, - } - - @c.user.best8Perfs.take(6).filter(c.user.hasEstablishedRating).map { pt => - @showPerfRating(c.user, pt) - } - -
    Hourly rate@r
    Availability - @if(c.coach.available.value) { - Now accepting students - } else { - Not accepting students at the moment - } -
    Admin - @if(c.coach.isListed) { - This page is now public. - } else { - This page is not public yet. - } - @if(ctx.me.??(c.coach.is)) { - Edit my coach profile - } -
    Contact - Send a private message -
    -
    -
    - } - @defining(c.coach.profile) { profile => -
    - @section("About me", profile.description) - @section("Playing experience", profile.playingExperience) - @section("Teaching experience", profile.teachingExperience) - @section("Other experiences", profile.otherExperience) - @section("Best skills", profile.skills) - @section("Teaching methodology", profile.methodology) -
    - @if(studies.nonEmpty) { -
    -

    Public studies

    -
    - @studies.map { s => -
    - @study.bits.widget(s).toHtml -
    - } -
    -
    - } - @if(profile.youtubeUrls.nonEmpty) { -
    -

    - Youtube videos - @profile.youtubeChannel.map { url => - from my channel - } -

    -
    - @profile.youtubeUrls.map { url => - - } -
    -
    - } - } -
    -}.toHtml diff --git a/app/views/coach/widget.scala b/app/views/coach/widget.scala new file mode 100644 index 0000000000..a26efdf9b1 --- /dev/null +++ b/app/views/coach/widget.scala @@ -0,0 +1,96 @@ +package views.html +package coach + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator + +import controllers.routes + +object widget { + + def titleName(c: lila.coach.Coach.WithUser) = frag( + c.user.title.map { t => s"$t " }, + c.user.realNameOrUsername + ) + + def pic(c: lila.coach.Coach.WithUser, size: Int)(implicit ctx: Context) = + c.coach.picturePath.map { path => + img(width := size, height := size, cls := "picture", src := dbImageUrl(path.value), alt := s"${c.user.titleUsername} lichess coach") + }.getOrElse { + img(width := size, height := size, cls := "default picture", src := staticUrl("images/coach-nopic.svg")) + } + + def apply(c: lila.coach.Coach.WithUser, link: Boolean)(implicit ctx: Context) = { + val profile = c.user.profileOrDefault + frag( + link option a(cls := "overlay", href := routes.Coach.show(c.user.username)), + pic(c, if (link) 300 else 350), + div(cls := "overview")( + (if (link) h2 else h1)(cls := "coach-name")(titleName(c)), + c.coach.profile.headline.map { h => + p(cls := s"headline ${if (h.size < 60) "small" else if (h.size < 120) "medium" else "large"}")(h) + }, + table( + tbody( + tr( + th("Location"), + td( + profile.nonEmptyLocation.map { l => + span(cls := "location")(l) + }, + profile.countryInfo.map { c => + frag( + span(cls := "country")( + img(cls := "flag", src := staticUrl(s"images/flags/${c.code}.png")), + " ", c.name + ) + ) + } + ) + ), + c.coach.profile.languages.map { l => + tr(cls := "languages")( + th("Languages"), + td(l) + ) + }, + tr(cls := "rating")( + th("Rating"), + td( + profile.fideRating.map { r => + frag("FIDE: ", r) + }, + a(href := routes.User.show(c.user.username))( + c.user.best8Perfs.take(6).filter(c.user.hasEstablishedRating).map { + showPerfRating(c.user, _) + } + ) + ) + ), + c.coach.profile.hourlyRate.map { r => + tr(cls := "rate")( + th("Hourly rate"), + td(r) + ) + }, + tr(cls := "available")( + th("Availability"), + td( + if (c.coach.available.value) span(cls := "text", dataIcon := "E")("Accepting students") + else span(cls := "text", dataIcon := "L")("Not accepting students at the moment") + ) + ), + c.user.seenAt.map { seen => + tr(cls := "seen")( + th, + td(trans.lastSeenActive(momentFromNow(seen))) + ) + } + ) + ) + ) + ) + } +} diff --git a/app/views/coach/widget.scala.html b/app/views/coach/widget.scala.html deleted file mode 100644 index 448f4445d1..0000000000 --- a/app/views/coach/widget.scala.html +++ /dev/null @@ -1,69 +0,0 @@ -@(c: lila.coach.Coach.WithUser)(implicit ctx: Context) - -@pic(c, 250) -@defining(c.user.profileOrDefault) { profile => -
    -

    - @c.user.title.map { t => @t }@c.user.realNameOrUsername -

    - @c.coach.profile.headline.map { h => -

    @h

    - } - - - - - - - @c.coach.profile.languages.map { l => - - - - - } - - - - - @c.coach.profile.hourlyRate.map { r => - - - - - } - - - - - @c.user.seenAt.map { seen => - - - - - } - -
    Location - @profile.nonEmptyLocation.map { l => - @l, - } - @profile.countryInfo.map { c => - @c.name - } -
    Languages@l
    Rating - @profile.fideRating.map { r => - FIDE: @r, - } - - @c.user.best8Perfs.take(6).filter(c.user.hasEstablishedRating).map { pt => - @showPerfRating(c.user, pt) - } - -
    Hourly rate@r
    Availability - @if(c.coach.available.value) { - Accepting students - } else { - Not accepting students at the moment - } -
    @trans.lastSeenActive(momentFromNow(seen))
    -
    -} diff --git a/app/views/coordinate.scala b/app/views/coordinate.scala new file mode 100644 index 0000000000..80ae90b946 --- /dev/null +++ b/app/views/coordinate.scala @@ -0,0 +1,99 @@ +package views.html + +import play.api.libs.json.Json + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.String.html.safeJsonValue +import lila.pref.Pref.Color + +import controllers.routes + +object coordinate { + + def home(scoreOption: Option[lila.coordinate.Score])(implicit ctx: Context) = + views.html.base.layout( + title = trans.coordinates.coordinateTraining.txt(), + moreCss = cssTag("coordinate"), + moreJs = frag( + jsTag("vendor/sparkline.min.js"), + jsAt("compiled/coordinate.js") + ), + openGraph = lila.app.ui.OpenGraph( + title = "Chess board coordinates trainer", + url = s"$netBaseUrl${routes.Coordinate.home.url}", + description = "Knowing the chessboard coordinates is a very important chess skill. A square name appears on the board and you must click on the correct square." + ).some, + zoomable = true + )( + main( + id := "trainer", + cls := "coord-trainer training init", + attr("data-color-pref") := ctx.pref.coordColorName, + attr("data-score-url") := ctx.isAuth.option(routes.Coordinate.score().url) + )( + div(cls := "coord-trainer__side")( + div(cls := "box")( + h1(trans.coordinates.coordinates()), + if (ctx.isAuth) scoreOption.map { score => + div(cls := "scores")(scoreCharts(score)) + } + else div(cls := "register")( + p(trans.toTrackYourProgress()), + p(cls := "signup")( + a(cls := "button", href := routes.Auth.signup)(trans.signUp()) + ) + ) + ), + form(cls := "color buttons", action := routes.Coordinate.color)( + st.group(cls := "radio")( + List(Color.BLACK, Color.RANDOM, Color.WHITE).map { id => + div( + input( + tpe := "radio", + st.id := s"coord_color_$id", + name := "coord_color", + value := id, + (id == ctx.pref.coordColor) option checked + ), + label(`for` := s"coord_color_$id", cls := s"color color_$id")(i) + ) + } + ) + ) + ), + div(cls := "coord-trainer__board main-board")( + div(cls := "next_coord", id := "next_coord0"), + div(cls := "next_coord", id := "next_coord1"), + div(cls := "next_coord", id := "next_coord2"), + chessgroundSvg + ), + div(cls := "coord-trainer__table")( + div(cls := "explanation")( + p(trans.coordinates.knowingTheChessBoard()), + ul( + li(trans.coordinates.mostChessCourses()), + li(trans.coordinates.talkToYourChessFriends()), + li(trans.coordinates.youCanAnalyseAGameMoreEffectively()) + ), + p(trans.coordinates.aSquareNameAppears()) + ), + button(cls := "start button button-fat")(trans.coordinates.startTraining()) + ), + div(cls := "coord-trainer__score")(0), + div(cls := "coord-trainer__progress")(div(cls := "progress_bar")) + ) + ) + + def scoreCharts(score: lila.coordinate.Score)(implicit ctx: Context) = frag( + List((trans.coordinates.averageScoreAsWhiteX, score.white), (trans.coordinates.averageScoreAsBlackX, score.black)).map { + case (averageScoreX, s) => div(cls := "chart_container")( + s.nonEmpty option frag( + p(averageScoreX(raw(s"""${"%.2f".format(s.sum.toDouble / s.size)}"""))), + div(cls := "user_chart", attr("data-points") := safeJsonValue(Json toJson s)) + ) + ) + } + ) +} diff --git a/app/views/coordinate/home.scala.html b/app/views/coordinate/home.scala.html deleted file mode 100644 index 3b04d82fa5..0000000000 --- a/app/views/coordinate/home.scala.html +++ /dev/null @@ -1,83 +0,0 @@ -@(scoreOption: Option[lila.coordinate.Score])(implicit ctx: Context) - -@import lila.pref.Pref.Color - -@moreCss = { -@cssTag("coordinate.css") -} - -@moreJs = { -@jsTag("vendor/sparkline.min.js") -@jsAt("compiled/coordinate.js") -} - -@base.layout( -title = trans.coordinates.coordinateTraining.txt(), -moreCss = moreCss, -moreJs = moreJs, -openGraph = lila.app.ui.OpenGraph( -title = "Chess board coordinates trainer", -url = s"$netBaseUrl${routes.Coordinate.home.url}", -description = "Knowing the chessboard coordinates is a very important chess skill. A square name appears on the board and you must click on the correct square.").some, -zoomable = true) { -
    -
    -
    -
    -
    -
    0
    -
    -
    -
    -

    @trans.coordinates.coordinates()

    - @if(ctx.isAuth) { - @scoreOption.map { score => -
    - @scoreCharts(score) -
    - } - } else { -
    -

    @trans.toTrackYourProgress()

    - -
    - } -
    -
    - - @List(Color.BLACK, Color.RANDOM, Color.WHITE).map { id => -
    - - -
    - } -
    -
    -
    -
    -
    -
    -
    -
    -
    -

    @trans.coordinates.knowingTheChessBoard()

    -
      -
    • @trans.coordinates.mostChessCourses()
    • -
    • @trans.coordinates.talkToYourChessFriends()
    • -
    • @trans.coordinates.youCanAnalyseAGameMoreEffectively()
    • -
    -

    @trans.coordinates.aSquareNameAppears()

    -
    - -
    -
    -
    -
    -}.toHtml diff --git a/app/views/coordinate/scoreCharts.scala.html b/app/views/coordinate/scoreCharts.scala.html deleted file mode 100644 index 3d465cbe06..0000000000 --- a/app/views/coordinate/scoreCharts.scala.html +++ /dev/null @@ -1,11 +0,0 @@ -@(score: lila.coordinate.Score)(implicit ctx: Context) -@List((trans.coordinates.averageScoreAsWhiteX, score.white), (trans.coordinates.averageScoreAsBlackX, score.black)).map { -case (averageScoreX, s) => { -
    - @if(s.nonEmpty) { -

    @averageScoreX(Html(s"""${"%.2f".format(s.sum.toDouble / s.size)}"""))

    -
    - } -
    -} -} diff --git a/app/views/dev.scala b/app/views/dev.scala new file mode 100644 index 0000000000..fcf2998a51 --- /dev/null +++ b/app/views/dev.scala @@ -0,0 +1,76 @@ +package views.html + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object dev { + + def settings(settings: List[lila.memo.SettingStore[_]])(implicit ctx: Context) = { + val title = "Settings" + views.html.base.layout( + title = title, + moreCss = cssTag("mod.misc") + )( + main(cls := "page-menu")( + mod.menu("setting"), + div(id := "settings", cls := "page-menu__content box box-pad")( + h1(title), + p("Tread lightly."), + settings.map { s => + form(action := routes.Dev.settingsPost(s.id), method := "POST")( + p(s.text | s.id), + input(name := "v", value := (s.form.value match { + case None => "" + case Some(x) => x.toString + case x => x.toString + })), + button(tpe := "submit", cls := "button", dataIcon := "E") + ) + } + ) + ) + ) + } + + def cli(form: Form[_], res: Option[String])(implicit ctx: Context) = { + val title = "Command Line Interface" + views.html.base.layout( + title = title, + moreCss = cssTag("mod.misc") + ) { + main(cls := "page-menu")( + views.html.mod.menu("cli"), + div(id := "dev-cli", cls := "page-menu__content box box-pad")( + h1(title), + p( + "Run arbitrary lila commands.", br, + "Only use if you know exactly what you're doing." + ), + res.map { r => + h2("Result:") + pre(r) + }, + st.form(action := routes.Dev.cliPost, method := "POST")( + form3.input(form("command"))(autofocus) + ), + h2("Command examples:"), + pre("""uptime +announce Lichess will undergo maintenance in 15 minutes! +change asset version +puzzle disable 70000 +team disable foobar +team enable foobar +fishnet client create {username} analysis +gdpr erase {username} forever +patron lifetime {username} +patron month {username}""") + ) + ) + } + } +} diff --git a/app/views/dev/cli.scala.html b/app/views/dev/cli.scala.html deleted file mode 100644 index eaac2ee9a1..0000000000 --- a/app/views/dev/cli.scala.html +++ /dev/null @@ -1,56 +0,0 @@ -@(form: Form[_], res: Option[String])(implicit ctx: Context) - -@title = @{ "Command Line Interface" } - -@mod.layout(title = title, active = "cli") { - - - -
    -

    @title

    -

    -

    - Run arbitrary lila commands.
    - Only use if you know exactly what you're doing. -

    -

    - @res.map { r => -

    Result:

    -
    @r
    - } -
    @form3.inputHtml(form("command"))()
    -

    Command examples:

    -
    change asset version
    -puzzle disable 70000
    -team disable foobar
    -team enable foobar
    -fishnet client create {username} analysis
    -gdpr erase {username} forever
    -patron lifetime {username}
    -patron month {username}
    -
    -
    -} diff --git a/app/views/dev/settings.scala.html b/app/views/dev/settings.scala.html deleted file mode 100644 index 55cb3035ea..0000000000 --- a/app/views/dev/settings.scala.html +++ /dev/null @@ -1,38 +0,0 @@ -@(settings: List[lila.memo.SettingStore[_]])(implicit ctx: Context) - -@title = @{ "Settings" } - -@mod.layout(title = title, active = "setting") { - - - -
    -

    @title

    -

    -

    - Tread lightly. -

    - @settings.map { s => -
    - - -
    - } -
    -} diff --git a/app/views/event.scala b/app/views/event.scala new file mode 100644 index 0000000000..cbfe5ba624 --- /dev/null +++ b/app/views/event.scala @@ -0,0 +1,133 @@ +package views.html + +import play.api.data.{ Field, Form } + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.String.html.richText +import lila.user.User + +import controllers.routes + +object event { + + private val dataSeconds = attr("data-seconds") + + def create(form: Form[_])(implicit ctx: Context) = + layout(title = "New event", css = "mod.form") { + div(cls := "crud page-menu__content box box-pad")( + h1("New event"), + st.form(cls := "content_box_content form3", action := routes.Event.create, method := "POST")(inForm(form)) + ) + } + + def edit(event: lila.event.Event, form: Form[_])(implicit ctx: Context) = + layout(title = event.title, css = "mod.form") { + div(cls := "crud edit page-menu__content box box-pad")( + h1( + event.title, + span("Created by ", usernameOrId(event.createdBy.value), " ", momentFromNow(event.createdAt)) + ), + st.form(cls := "content_box_content form3", action := routes.Event.update(event.id), method := "POST")(inForm(form)) + ) + } + + def show(e: lila.event.Event)(implicit ctx: Context) = views.html.base.layout( + title = e.title, + moreCss = cssTag("event"), + moreJs = jsTag("event-countdown.js") + ) { + main(cls := "page-small event box box-pad")( + h1(dataIcon := "", cls := "text")(e.title), + h2(cls := "headline")(e.headline), + e.description.map { d => + p(cls := "desc")(richText(d)) + }, + if (e.isFinished) p(cls := "desc")("The event is finished.") + else { + if (e.isNow) a(href := e.url, cls := "button button-fat")(trans.eventInProgress()) + else ul(cls := "countdown", dataSeconds := ~e.secondsToStart)( + List("Days", "Hours", "Minutes", "Seconds") map { t => + li(span(cls := t.toLowerCase), t) + } + ) + } + ) + } + + def manager(events: List[lila.event.Event])(implicit ctx: Context) = { + val title = "Event manager" + layout(title = title) { + div(cls := "crud page-menu__content box")( + div(cls := "box__top")( + h1(title), + div(cls := "box__top__actions")( + a(cls := "button button-green", href := routes.Event.form, dataIcon := "O") + ) + ), + table(cls := "slist slist-pad")( + thead( + tr( + th, + th("UTC start"), + th("UTC end"), + th + ) + ), + tbody( + events.map { e => + tr( + td(a(href := routes.Event.edit(e.id))( + strong(e.title), + em(e.headline) + )), + td( + showDateTimeUTC(e.startsAt), + momentFromNow(e.startsAt) + ), + td( + showDateTimeUTC(e.finishesAt), + momentFromNow(e.finishesAt) + ), + td(a(cls := "text", href := routes.Event.show(e.id), dataIcon := "v")) + ) + } + ) + ) + ) + } + } + + private def inForm(form: Form[_])(implicit ctx: Context) = frag( + form3.split( + form3.group(form("startsAt"), raw("Start date UTC"), half = true)(form3.flatpickr(_)), + form3.group(form("finishesAt"), raw("End date UTC"), half = true)(form3.flatpickr(_)) + ), + form3.group(form("title"), raw("Short title"), help = raw("Keep it VERY short, so it fits on homepage").some)(form3.input(_)), + form3.group(form("headline"), raw("Short headline"), help = raw("Keep it VERY short, so it fits on homepage").some)(form3.input(_)), + form3.group(form("description"), raw("Possibly long description"), help = raw("Link: [text](url)").some)(form3.textarea(_)()), + form3.group(form("url"), raw("External URL"), help = raw("What to redirect to when the event starts").some)(form3.input(_)), + form3.group(form("lang"), raw("Language"))(form3.select(_, lila.i18n.LangList.choices)), + form3.split( + form3.checkbox(form("enabled"), raw("Enabled"), help = raw("Display the event").some, half = true), + form3.group(form("homepageHours"), raw("Hours on homepage (0 to 24)"), half = true, help = raw("Ask on slack first!").some)(form3.input(_, typ = "number")) + ), + form3.action(form3.submit(trans.apply())) + ) + + private def layout(title: String, css: String = "mod.misc")(body: Frag)(implicit ctx: Context) = + views.html.base.layout( + title = title, + moreCss = cssTag(css), + moreJs = frag( + flatpickrTag, + delayFlatpickrStart + ) + ) { + main(cls := "page-menu")( + mod.menu("event"), + body + ) + } +} diff --git a/app/views/event/create.scala.html b/app/views/event/create.scala.html deleted file mode 100644 index 123ecf3085..0000000000 --- a/app/views/event/create.scala.html +++ /dev/null @@ -1,10 +0,0 @@ -@(form: Form[_])(implicit ctx: Context) - -@layout(title = "New event") { -
    -

    New event

    -
    - @inForm(form) -
    -
    -} diff --git a/app/views/event/edit.scala.html b/app/views/event/edit.scala.html deleted file mode 100644 index 3b477561d5..0000000000 --- a/app/views/event/edit.scala.html +++ /dev/null @@ -1,13 +0,0 @@ -@(event: lila.event.Event, form: Form[_])(implicit ctx: Context) - -@layout(title = event.title) { -
    -

    - @event.title - Created by @usernameOrId(event.createdBy.value) @momentFromNow(event.createdAt) -

    -
    - @inForm(form) -
    -
    -} diff --git a/app/views/event/inForm.scala.html b/app/views/event/inForm.scala.html deleted file mode 100644 index 227b1b0869..0000000000 --- a/app/views/event/inForm.scala.html +++ /dev/null @@ -1,18 +0,0 @@ -@(form: Form[_])(implicit ctx: Context) -@import lila.app.ui.ScalatagsTwirlForm._ - -@form3.split { -@form3.group(form("startsAt"), raw("Start date UTC"), half = true)(form3.flatpickr(_)) -@form3.group(form("finishesAt"), raw("End date UTC"), half = true)(form3.flatpickr(_)) -} -@form3.group(form("title"), raw("Short title"), help = raw("Keep it VERY short, so it fits on homepage").some)(form3.input(_)) -@form3.group(form("headline"), raw("Short headline"), help = raw("Keep it VERY short, so it fits on homepage").some)(form3.input(_)) -@form3.group(form("description"), raw("Possibly long description"), help = raw("Link: [text](url)").some)(form3.textarea(_)()) -@form3.group(form("url"), raw("External URL"), help = raw("What to redirect to when the event starts").some)(form3.input(_)) -@form3.group(form("lang"), raw("Language"))(form3.select(_, lila.i18n.LangList.choices)) -@form3.split { -@form3.checkbox(form("enabled"), raw("Enabled"), help = raw("Display the event").some, half = true) -@form3.group(form("homepageHours"), raw("Hours on homepage (0 to 24)"), half = true, help = raw("Ask on slack first!").some)(form3.input(_, typ = "number")) -} - -@form3.actionHtml(form3.submit(trans.apply.frag())) diff --git a/app/views/event/index.scala.html b/app/views/event/index.scala.html deleted file mode 100644 index a707c99550..0000000000 --- a/app/views/event/index.scala.html +++ /dev/null @@ -1,30 +0,0 @@ -@(events: List[lila.event.Event])(implicit ctx: Context) - -@base.layout( -title = "All lichess public events", -moreCss = cssTag("event.css")) { -
    -

    All public events

    - - @events.map { e => - - - - - } -
    - @if(e.isNow) { - -

    @e.title

    - @e.headline -
    - } else { -

    @e.title

    - @e.headline - } -
    - @momentFromNow(e.startsAt) - @momentFromNow(e.startsAt) -
    -
    -}.toHtml diff --git a/app/views/event/layout.scala.html b/app/views/event/layout.scala.html deleted file mode 100644 index fff4196b37..0000000000 --- a/app/views/event/layout.scala.html +++ /dev/null @@ -1,12 +0,0 @@ -@(title: String)(body: Html)(implicit ctx: Context) - -@moreJs = { -@flatpickrTag -@delayFlatpickrStart -} - -@mod.layout( -title = title, -active = "event", -moreCss = cssTags("flatpickr.css", "form3.css", "event.crud.css"), -moreJs = moreJs)(body) diff --git a/app/views/event/manager.scala.html b/app/views/event/manager.scala.html deleted file mode 100644 index 31203483df..0000000000 --- a/app/views/event/manager.scala.html +++ /dev/null @@ -1,41 +0,0 @@ -@(events: List[lila.event.Event])(implicit ctx: Context) - -@title = {Event manager} - -@layout(title = title.body) { -
    -

    - - @title -

    - - - - - - - - - - - @events.map { e => - - - - - - - } - -
    UTC startUTC end
    -

    @e.title

    - @e.headline -
    - @showDateTimeUTC(e.startsAt) - @momentFromNow(e.startsAt) - - @showDateTimeUTC(e.finishesAt) - @momentFromNow(e.finishesAt) -
    -
    -} diff --git a/app/views/event/show.scala.html b/app/views/event/show.scala.html deleted file mode 100644 index 9d32e5bab6..0000000000 --- a/app/views/event/show.scala.html +++ /dev/null @@ -1,25 +0,0 @@ -@(e: lila.event.Event)(implicit ctx: Context) - -@base.layout( -title = e.title, -moreCss = cssTag("event.css"), -moreJs = jsTag("event-countdown.js")) { -
    -

    @e.title

    -

    @e.headline

    - @e.description.map { d => -

    @richText(d)

    - } - @if(e.isFinished) { -

    The event is finished.

    - } else { - @if(e.isNow) { - @trans.eventInProgress() - } else { -
      -
    • days
    • Hours
    • Minutes
    • Seconds
    • -
    - } - } -
    -}.toHtml diff --git a/app/views/forum/bits.scala b/app/views/forum/bits.scala new file mode 100644 index 0000000000..e3bb5fcee9 --- /dev/null +++ b/app/views/forum/bits.scala @@ -0,0 +1,38 @@ +package views.html +package forum + +import play.api.mvc.Call + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator + +import controllers.routes + +object bits { + + def searchForm(search: String = "")(implicit ctx: Context) = + div(cls := "box__top__actions")( + form(cls := "search", action := routes.ForumPost.search())( + input(name := "text", value := search, placeholder := trans.search.txt()) + ) + ) + + def pagination(route: Call, pager: Paginator[_], showPost: Boolean) = pager.hasToPaginate option { + def url(page: Int) = s"$route?page=$page" + st.nav(cls := "pagination")( + if (pager.hasPreviousPage) a(href := url(pager.previousPage.get), dataIcon := "I") + else span(cls := "disabled", dataIcon := "I"), + pager.sliding(3, showPost = showPost).map { + case None => frag(" ... ") + case Some(p) if p == pager.currentPage => span(cls := "current")(p) + case Some(p) => a(href := url(p))(p) + }, + if (pager.hasNextPage) a(rel := "next", href := url(pager.nextPage.get), dataIcon := "H") + else span(cls := "disabled", dataIcon := "H") + ) + } + private[forum] val dataTopic = attr("data-topic") + private[forum] val dataUnsub = attr("data-unsub") +} diff --git a/app/views/forum/categ.scala b/app/views/forum/categ.scala new file mode 100644 index 0000000000..13ff03b693 --- /dev/null +++ b/app/views/forum/categ.scala @@ -0,0 +1,141 @@ +package views.html +package forum + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator + +import controllers.routes + +object categ { + + def index(categs: List[lila.forum.CategView])(implicit ctx: Context) = views.html.base.layout( + title = trans.forum.txt(), + moreCss = cssTag("forum"), + openGraph = lila.app.ui.OpenGraph( + title = "Lichess community forum", + url = s"$netBaseUrl${routes.ForumCateg.index.url}", + description = "Chess discussions and feedback about lichess development" + ).some + ) { + main(cls := "forum index box")( + div(cls := "box__top")( + h1(dataIcon := "d", cls := "text")("Lichess Forum"), + bits.searchForm() + ), + showCategs(categs.filterNot(_.categ.isTeam)), + if (categs.exists(_.categ.isTeam)) frag( + h1("Your teams boards"), + showCategs(categs.filter(_.categ.isTeam)) + ) + ) + } + + def show( + categ: lila.forum.Categ, + topics: Paginator[lila.forum.TopicView], + canWrite: Boolean, + stickyPosts: List[lila.forum.TopicView] + )(implicit ctx: Context) = { + + val newTopicButton = canWrite option + a(href := routes.ForumTopic.form(categ.slug), cls := "button button-empty button-green text", dataIcon := "m")( + trans.createANewTopic() + ) + def showTopic(sticky: Boolean)(topic: lila.forum.TopicView) = tr(cls := List("sticky" -> sticky))( + td(cls := "subject")( + a(href := routes.ForumTopic.show(categ.slug, topic.slug))(topic.name) + ), + td(cls := "right")(topic.views.localize), + td(cls := "right")(topic.nbReplies.localize), + td( + topic.lastPost.map { post => + frag( + a(href := s"${routes.ForumTopic.show(categ.slug, topic.slug, topic.lastPage)}#${post.number}")( + momentFromNow(post.createdAt) + ), + br, + authorLink(post) + ) + } + ) + ) + val bar = div(cls := "bar")( + bits.pagination(routes.ForumCateg.show(categ.slug, 1), topics, showPost = false), + newTopicButton + ) + + views.html.base.layout( + title = categ.name, + moreCss = cssTag("forum"), + openGraph = lila.app.ui.OpenGraph( + title = s"Forum: ${categ.name}", + url = s"$netBaseUrl${routes.ForumCateg.show(categ.slug).url}", + description = categ.desc + ).some + ) { + main(cls := "forum forum-categ box")( + h1( + a( + href := categ.team.fold(routes.ForumCateg.index)(routes.Team.show(_)), + dataIcon := "I", + cls := "text" + ), + categ.team.fold(frag(categ.name))(teamIdToName) + ), + bar, + table(cls := "topics slist slist-pad")( + thead( + tr( + th, + th(cls := "right")(trans.views()), + th(cls := "right")(trans.replies()), + th(trans.lastPost()) + ) + ), + tbody( + stickyPosts map showTopic(true), + topics.currentPageResults map showTopic(false) + ) + ), + bar + ) + } + } + + private def showCategs(categs: List[lila.forum.CategView])(implicit ctx: Context) = + table(cls := "categs slist slist-pad")( + thead( + tr( + th, + th(cls := "right")(trans.topics()), + th(cls := "right")(trans.posts()), + th(trans.lastPost()) + ) + ), + tbody( + categs.map { categ => + tr( + td(cls := "subject")( + h2(a(href := routes.ForumCateg.show(categ.slug))(categ.name)), + p(categ.desc) + ), + td(cls := "right")(categ.nbTopics.localize), + td(cls := "right")(categ.nbPosts.localize), + td( + categ.lastPost.map { + case (topic, post, page) => frag( + a(href := s"${routes.ForumTopic.show(categ.slug, topic.slug, page)}#${post.number}")( + momentFromNow(post.createdAt) + ), + br, + trans.by(authorName(post)) + ) + } + ) + ) + } + ) + ) +} diff --git a/app/views/forum/categ/index.scala.html b/app/views/forum/categ/index.scala.html deleted file mode 100644 index 91f563246d..0000000000 --- a/app/views/forum/categ/index.scala.html +++ /dev/null @@ -1,19 +0,0 @@ -@(categs: List[lila.forum.CategView])(implicit ctx: Context) - -@forum.layout( -title = trans.forum.txt(), -openGraph = lila.app.ui.OpenGraph( -title = "Lichess community forum", -url = s"$netBaseUrl${routes.ForumCateg.index.url}", -description = "Chess discussions and feedback about lichess development").some) { - -

    Lichess Forum

    -@forum.categ.table(categs.filterNot(_.categ.isTeam)) - -@if(categs.exists(_.categ.isTeam)) { -
    -
    -

    Your teams boards

    -@forum.categ.table(categs.filter(_.categ.isTeam)) -} -} diff --git a/app/views/forum/categ/show.scala.html b/app/views/forum/categ/show.scala.html deleted file mode 100644 index 1b19c70988..0000000000 --- a/app/views/forum/categ/show.scala.html +++ /dev/null @@ -1,76 +0,0 @@ -@(categ: lila.forum.Categ, topics: Paginator[lila.forum.TopicView], canWrite: Boolean, stickyPosts: List[lila.forum.TopicView])(implicit ctx: Context) - -@newTopicButton = { -@if(canWrite) { - @trans.createANewTopic() -} -} - -@forum.layout( -title = categ.name, -openGraph = lila.app.ui.OpenGraph( -title = s"Forum: ${categ.name}", -url = s"$netBaseUrl${routes.ForumCateg.show(categ.slug).url}", -description = categ.desc).some) { -
    - @categ.team.map { team => -
      -
    1. -
    2. @teamLink(team)
    3. -
    4. Forum

    5. -
    - }.getOrElse { -
      -
    1. Forum
    2. -
    3. @categ.name

    4. -
    - } - -

    @categ.desc

    -
    - @forum.pagination(routes.ForumCateg.show(categ.slug, 1), topics, showPost = false) - @newTopicButton -
    - - - - - - - - - - - @stickyPosts.map { topic => - - - - - - - } - @topics.currentPageResults.map { topic => - - - - - - - } - -
    @trans.views()@trans.replies()@trans.lastPost()
    @topic.name@topic.views.localize@topic.nbReplies.localize - @topic.lastPost.map { post => - @momentFromNow(post.createdAt)
    @trans.by(authorLink(post)) - } -
    @topic.name@topic.views.localize@topic.nbReplies.localize - @topic.lastPost.map { post => - @momentFromNow(post.createdAt)
    @trans.by(authorLink(post)) - } -
    - -
    - @forum.pagination(routes.ForumCateg.show(categ.slug, 1), topics, showPost = false) - @newTopicButton -
    -
    -} diff --git a/app/views/forum/categ/table.scala.html b/app/views/forum/categ/table.scala.html deleted file mode 100644 index b26df72b9f..0000000000 --- a/app/views/forum/categ/table.scala.html +++ /dev/null @@ -1,32 +0,0 @@ -@(categs: List[lila.forum.CategView])(implicit ctx: Context) - - - - - - - - - - - - @categs.map { categ => - - - - - - - - } - -
    @trans.topics()@trans.posts()@trans.lastPost()
    - @categ.name -

    @categ.desc

    -
    @categ.nbTopics.localize@categ.nbPosts.localize - @categ.lastPost.map { - case (topic, post, page) => { - @momentFromNow(post.createdAt)
    @trans.by(authorName(post)) - } - } -
    diff --git a/app/views/forum/layout.scala.html b/app/views/forum/layout.scala.html deleted file mode 100644 index aa98175141..0000000000 --- a/app/views/forum/layout.scala.html +++ /dev/null @@ -1,13 +0,0 @@ -@(title: String, searchText: String = "", side: Option[Html] = None, moreJs: Html = emptyHtml, formCss: Boolean = false, openGraph: Option[lila.app.ui.OpenGraph] = None)(body: Html)(implicit ctx: Context) - -@base.layout( -title = title, -side = side, -moreCss = cssTags(List("forum.css" -> true, "form3.css" -> formCss)), -moreJs = moreJs, -openGraph = openGraph) { -
    - @forum.searchForm(searchText.trim) - @body -
    -}.toHtml diff --git a/app/views/forum/pagination.scala.html b/app/views/forum/pagination.scala.html deleted file mode 100644 index fabc9c1703..0000000000 --- a/app/views/forum/pagination.scala.html +++ /dev/null @@ -1,32 +0,0 @@ -@(route: Call, pager: Paginator[_], showPost: Boolean) - -@url(page: Int) = { -@route?page=@page -} - -@if(pager.hasToPaginate) { - -} diff --git a/app/views/forum/post.scala b/app/views/forum/post.scala new file mode 100644 index 0000000000..c298af9798 --- /dev/null +++ b/app/views/forum/post.scala @@ -0,0 +1,82 @@ +package views +package html.forum + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.String.html.richText + +import controllers.routes + +object post { + + def recent(posts: List[lila.forum.MiniForumPost])(implicit ctx: Context) = ol( + posts map { p => + li( + a(dataIcon := p.isTeam.option("f"), cls := "post_link text", href := routes.ForumPost.redirect(p.postId), title := p.topicName)( + shorten(p.topicName, 30) + ), + " ", + userIdLink(p.userId, withOnline = false), + " ", + span(cls := "extract")(shorten(p.text, 70)) + ) + } + ) + + def show( + categ: lila.forum.Categ, + topic: lila.forum.Topic, + post: lila.forum.Post, + url: String, + canModCateg: Boolean + )(implicit ctx: Context) = { + st.article(cls := List("forum-post" -> true, "erased" -> post.erased), id := post.number)( + div(cls := "forum-post__metas")( + div( + authorLink(post = post, cssClass = "author".some, modIcon = post.displayModIcon), + a(href := url)( + post.updatedAt.map { updatedAt => + frag( + span(cls := "post-edited")("edited "), + momentFromNow(updatedAt) + ) + }.getOrElse { + momentFromNow(post.createdAt) + } + ), + isGranted(_.IpBan) option span(cls := "mod postip")(post.ip), + ctx.userId.fold(false)(post.shouldShowEditForm(_)) option + a(cls := "mod edit button button-empty text", dataIcon := "m")("Edit"), + canModCateg option a( + cls := "mod delete button button-empty button-red", + href := routes.ForumPost.delete(categ.slug, post.id), + dataIcon := "q", + title := "Delete" + ) + ), + a(cls := "anchor", href := url)(s"#${post.number}") + ), + p(cls := "forum-post__message")( + if (post.erased) "" + else richText(post.text) + ), + ctx.userId.exists(post.shouldShowEditForm(_)) option + st.form(cls := "edit-post-form", method := "post", action := routes.ForumPost.edit(post.id))( + textarea( + bits.dataTopic := topic.id, + name := "changes", + cls := "post-text-area edit-post-box", + minlength := 3, + required + )(post.text), + div(cls := "edit-buttons")( + a(cls := "edit-post-cancel", href := routes.ForumPost.redirect(post.id), style := "margin-left:20px")( + trans.cancel() + ), + button(`type` := "submit", cls := "button")(trans.apply()) + ) + ) + ) + } +} diff --git a/app/views/forum/post/recent.scala b/app/views/forum/post/recent.scala deleted file mode 100644 index b227e05905..0000000000 --- a/app/views/forum/post/recent.scala +++ /dev/null @@ -1,25 +0,0 @@ -package views -package html.forum.post - -import lila.api.Context -import lila.app.templating.Environment._ -import lila.app.ui.ScalatagsTemplate._ - -import controllers.routes - -object recent { - - def apply(posts: List[lila.forum.MiniForumPost])(implicit ctx: Context) = ol( - posts map { p => - li( - a(dataIcon := p.isTeam.option("f"), cls := "post_link text", href := routes.ForumPost.redirect(p.postId), title := p.topicName)( - shorten(p.topicName, 30) - ), - " ", - userIdLink(p.userId, withOnline = false), - " ", - span(cls := "extract")(shorten(p.text, 70)) - ) - } - ) -} diff --git a/app/views/forum/search.scala b/app/views/forum/search.scala new file mode 100644 index 0000000000..00ed1985ce --- /dev/null +++ b/app/views/forum/search.scala @@ -0,0 +1,53 @@ +package views.html.forum + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator +import lila.common.String.html.nl2br + +import controllers.routes + +object search { + + def apply(text: String, pager: Paginator[lila.forum.PostView])(implicit ctx: Context) = { + val title = s"""${trans.search.txt()} "${text.trim}"""" + views.html.base.layout( + title = title, + moreJs = infiniteScrollTag, + moreCss = cssTag("forum") + )( + main(cls := "box box search")( + div(cls := "box__top")( + h1( + a(href := routes.ForumCateg.index, dataIcon := "I", cls := "text"), + title + ), + bits.searchForm() + ), + strong(cls := "nb-results box__pad")(pager.nbResults, " posts found"), + table(cls := "slist slist-pad search__results")( + if (pager.nbResults > 0) tbody(cls := "infinitescroll")( + pagerNextTable(pager, n => routes.ForumPost.search(text, n).url) | tr, + pager.currentPageResults.map { view => + tr(cls := "paginated")( + td( + a(cls := "post", href := routes.ForumPost.redirect(view.post.id))( + view.categ.name, " - ", + view.topic.name, "#", view.post.number + ), + p(nl2br(shorten(view.post.text.replace("\n\n", "\n"), 200))) + ), + td(cls := "info")( + momentFromNow(view.post.createdAt), br, + authorLink(view.post) + ) + ) + } + ) + else tbody(tr(td("No forum post found"))) + ) + ) + ) + } +} diff --git a/app/views/forum/search.scala.html b/app/views/forum/search.scala.html deleted file mode 100644 index 725e1b6fb2..0000000000 --- a/app/views/forum/search.scala.html +++ /dev/null @@ -1,40 +0,0 @@ -@(text: String, views: Paginator[lila.forum.PostView])(implicit ctx: Context) - -@title = @{ trans.search.txt() + " \"" + text.trim + "\"" } - -@forum.layout( -title = title, -moreJs = infiniteScrollTag, -searchText = text -) { - -

    @title

    - -

    @views.nbResults posts found

    - - - @if(views.nbResults > 0) { - - @views.nextPage.map { n => - - - } - @views.currentPageResults.map { view => - - - - - } - - } else { - - } -
    - -
    - @view.categ.name - @view.topic.name #@view.post.number -

    @nl2br(shorten(view.post.text.replace("\n\n", "\n"), 200))

    -
    - @momentFromNow(view.post.createdAt) by @authorLink(view.post) -
    No forum post found
    -} diff --git a/app/views/forum/searchForm.scala.html b/app/views/forum/searchForm.scala.html deleted file mode 100644 index 1ea2e6bbd7..0000000000 --- a/app/views/forum/searchForm.scala.html +++ /dev/null @@ -1,4 +0,0 @@ -@(search: String = "")(implicit ctx: Context) - diff --git a/app/views/forum/topic.scala b/app/views/forum/topic.scala new file mode 100644 index 0000000000..e3bfa87fcc --- /dev/null +++ b/app/views/forum/topic.scala @@ -0,0 +1,159 @@ +package views.html +package forum + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator + +import controllers.routes + +object topic { + + def form(categ: lila.forum.Categ, form: Form[_], captcha: lila.common.Captcha)(implicit ctx: Context) = + views.html.base.layout( + title = "New forum topic", + moreCss = cssTag("forum"), + moreJs = frag( + jsTag("forum-post.js"), + captchaTag + ) + ) { + main(cls := "forum forum-topic topic-form page-small box box-pad")( + h1( + a(href := routes.ForumCateg.show(categ.slug), dataIcon := "I", cls := "text"), + categ.name + ), + st.section(cls := "warning")( + h2(dataIcon := "!", cls := "text")("Important"), + p( + "Your question may already have an answer ", strong(a(href := routes.Main.faq)("in the F.A.Q.")) + ), + p( + "To report a user for cheating or bad behaviour, ", strong(a(href := routes.Report.form)("use the report form")) + ), + p( + "To request support, ", strong(a(href := routes.Main.contact())(raw("try the contact page"))) + ) + ), + + st.form(cls := "form3", action := routes.ForumTopic.create(categ.slug), method := "POST")( + form3.group(form("name"), trans.subject())(form3.input(_)(autofocus)), + form3.group(form("post")("text"), trans.message())(form3.textarea(_, klass = "post-text-area")(rows := 10)), + views.html.base.captcha(form("post"), captcha), + form3.actions( + a(href := routes.ForumCateg.show(categ.slug))(trans.cancel()), + isGranted(_.PublicMod) option + form3.submit(frag("Create as mod"), nameValue = (form("post")("modIcon").name, "true").some, icon = "".some), + form3.submit(trans.createTheTopic()) + ) + ) + ) + } + + def show( + categ: lila.forum.Categ, + topic: lila.forum.Topic, + posts: Paginator[lila.forum.Post], + formWithCaptcha: Option[FormWithCaptcha], + unsub: Option[Boolean], + canModCateg: Boolean + )(implicit ctx: Context) = views.html.base.layout( + title = s"${topic.name} • page ${posts.currentPage}/${posts.nbPages} • ${categ.name}", + moreJs = frag( + jsTag("forum-post.js"), + formWithCaptcha.isDefined option captchaTag, + jsAt("compiled/embed-analyse.js") + ), + moreCss = cssTag("forum"), + openGraph = lila.app.ui.OpenGraph( + title = topic.name, + url = s"$netBaseUrl${routes.ForumTopic.show(categ.slug, topic.slug, posts.currentPage).url}", + description = shorten(posts.currentPageResults.headOption.??(_.text), 152) + ).some + ) { + val pager = bits.pagination(routes.ForumTopic.show(categ.slug, topic.slug, 1), posts, showPost = false) + + main(cls := "forum forum-topic page-small box box-pad")( + h1( + a( + href := routes.ForumCateg.show(categ.slug), + dataIcon := "I", + cls := "text" + ), + topic.name + ), + pager, + div(cls := "forum-topic__posts embed_analyse")( + posts.currentPageResults.map { p => + post.show( + categ, + topic, + p, + s"${routes.ForumTopic.show(categ.slug, topic.slug, posts.currentPage)}#${p.number}", + canModCateg = canModCateg + ) + } + ), + + div(cls := "forum-topic__actions")( + if (posts.hasNextPage) pager + else if (topic.isOld) + p("This topic has been archived and can no longer be replied to.") + else if (formWithCaptcha.isDefined) + h2(id := "reply")(trans.replyToThisTopic()) + else if (topic.closed) p(trans.thisTopicIsNowClosed()) + else categ.team.filterNot(myTeam).map { teamId => + p( + a(href := routes.Team.show(teamId)), + s"Join the ${teamIdToName(teamId)} team", + " to post in this forum" + ) + } getOrElse p("You can't post in the forums yet. Play some games!"), + div( + unsub.map { uns => + st.form(cls := s"unsub ${if (uns) "on" else "off"}", method := "post", action := routes.Timeline.unsub(s"forum:${topic.id}"))( + button(cls := "button button-empty text on", dataIcon := "v", bits.dataUnsub := "off")("Subscribe"), + button(cls := "button button-empty text off", dataIcon := "v", bits.dataUnsub := "on")("Unsubscribe") + ) + }, + + isGranted(_.ModerateForum) option + st.form(method := "post", action := routes.ForumTopic.hide(categ.slug, topic.slug))( + button(cls := "button button-empty button-green")(if (topic.hidden) "Feature" else "Un-feature") + ), + canModCateg option + st.form(method := "post", action := routes.ForumTopic.close(categ.slug, topic.slug))( + button(cls := "button button-empty button-red")(if (topic.closed) "Reopen" else "Close") + ), + canModCateg option + st.form(method := "post", action := routes.ForumTopic.sticky(categ.slug, topic.slug))( + button(cls := "button button-empty button-brag")(if (topic.isSticky) "Un-sticky" else "Sticky") + ) + ) + ), + + formWithCaptcha.map { + case (form, captcha) => st.form( + cls := "form3 reply", + action := s"${routes.ForumPost.create(categ.slug, topic.slug, posts.currentPage)}#reply", + method := "POST", + novalidate + )( + form3.group(form("text"), trans.message()) { f => + form3.textarea(f, klass = "post-text-area")(rows := 10, bits.dataTopic := topic.id) + }, + views.html.base.captcha(form, captcha), + form3.actions( + a(href := routes.ForumCateg.show(categ.slug))(trans.cancel()), + isGranted(_.PublicMod) option + form3.submit(frag("Reply as mod"), nameValue = (form("modIcon").name, "true").some, icon = "".some), + form3.submit(trans.reply()) + ) + ) + } + ) + } +} diff --git a/app/views/forum/topic/form.scala.html b/app/views/forum/topic/form.scala.html deleted file mode 100644 index 5e902a335b..0000000000 --- a/app/views/forum/topic/form.scala.html +++ /dev/null @@ -1,29 +0,0 @@ -@(categ: lila.forum.Categ, form: Form[_], captcha: lila.common.Captcha)(implicit ctx: Context) -@import lila.app.ui.ScalatagsTwirlForm._ - -@forum.layout(title = "New forum topic", moreJs = jsTag("forum-post.js"), formCss = true) { -
      -
    1. Forum
    2. -
    3. @categ.name

    4. -
    -
    -

    Important

    -

    - To report a user for cheating or bad behaviour,
    - use the report form. -

    -
    - -
    - @form3.group(form("name"), trans.subject.frag())(form3.input(_)(*.autofocus := true)) - @form3.group(form("post")("text"), trans.message.frag())(form3.textarea(_, klass = "post-text-area")(*.rows := 10)) - @base.captcha(form("post"), captcha).toHtml - @form3.actionsHtml { - @trans.cancel() - @if(isGranted(_.PublicMod)){ - @form3.submit(raw("Create as mod"), nameValue = (form("post")("modIcon").name, "true").some, icon = "".some) - } - @form3.submit(trans.createTheTopic.frag()) - } -
    -} diff --git a/app/views/forum/topic/show.scala.html b/app/views/forum/topic/show.scala.html deleted file mode 100644 index 401958157a..0000000000 --- a/app/views/forum/topic/show.scala.html +++ /dev/null @@ -1,141 +0,0 @@ -@(categ: lila.forum.Categ, topic: lila.forum.Topic, posts: Paginator[lila.forum.Post], formWithCaptcha: Option[FormWithCaptcha], unsub: Option[Boolean], canModCateg: Boolean)(implicit ctx: Context) -@import lila.app.ui.ScalatagsTwirlForm._ - -@moreJs = { -@jsTag("forum-post.js") -@jsTag("embed-analyse.js") -} - -@title = @{ s"${topic.name} • page ${posts.currentPage}/${posts.nbPages} • ${categ.name}" } - -@forum.layout( -title = title, -moreJs = moreJs, -openGraph = lila.app.ui.OpenGraph( -title = topic.name, -url = s"$netBaseUrl${routes.ForumTopic.show(categ.slug, topic.slug, posts.currentPage).url}", -description = shorten(posts.currentPageResults.headOption.??(_.text), 152)).some, -formCss = formWithCaptcha.isDefined) { -
    - @categ.team.map { team => -
      -
    1. -
    2. @teamLink(team)
    3. -
    4. Forum
    5. -
    6. @topic.name

    7. -
    - }.getOrElse { -
      -
    1. Forum
    2. -
    3. @categ.name
    4. -
    5. @topic.name

    6. -
    - } -
    - @forum.pagination(routes.ForumTopic.show(categ.slug, topic.slug, 1), posts, showPost = true) -
    - -
    - @posts.currentPageResults.map { post => -
    -
    - @defining(routes.ForumTopic.show(categ.slug, topic.slug, posts.currentPage) + s"#${post.number}") { url => - @authorLink(post=post, cssClass="author".some, modIcon=post.displayModIcon) - - - @post.updatedAt.map { updatedAt => - edited - @momentFromNow(updatedAt) - }.getOrElse { - @momentFromNow(post.createdAt) - } - - - #@post.number - - @if(isGranted(_.IpBan)) { - @post.ip - } - @if(ctx.userId.fold(false)(post.shouldShowEditForm(_))) { - Edit - } - @if(canModCateg) { - Delete - } - } -
    -

    @if(post.erased){@lila.common.String.erasedHtml}else{@richText(post.text)}

    - @if(ctx.userId.fold(false)(post.shouldShowEditForm(_))) { -
    - -
    - @trans.cancel() - -
    -
    - } -
    - } -
    - - @unsub.map { uns => -
    - - -
    - } - - @if(isGranted(_.ModerateForum)) { -
    - -
    - } - @if(canModCateg) { -
    - -
    -
    - -
    - } - -
    - @if(topic.isOld) { -

    This topic has been archived and can no longer be replied to.

    - } else { - @formWithCaptcha.map { - case (form, captcha) => { -

    @trans.replyToThisTopic()

    -
    - @form3.group(form("text"), trans.message.frag()) { f => - @form3.textarea(f, klass = "post-text-area")(*.rows := 10, *.attr("data-topic") := topic.id) - } - @base.captcha(form, captcha).toHtml - @form3.actionsHtml { - @trans.cancel() - @if(isGranted(_.PublicMod)){ - @form3.submit(raw("Reply as mod"), nameValue = (form("modIcon").name, "true").some, icon = "".some) - } - @form3.submit(trans.reply.frag()) - } -
    - } - }.getOrElse { - @if(topic.closed) { -

    @trans.thisTopicIsNowClosed()

    - } else { - @categ.team.map { teamId => - @if(!myTeam(teamId)) { -

    Join the @teamIdToName(teamId) team to post in this forum

    - } - } - } - } - } -
    - -
    - @forum.pagination(routes.ForumTopic.show(categ.slug, topic.slug, 1), posts, showPost = true) -
    -
    -} diff --git a/app/views/game/bits.scala b/app/views/game/bits.scala index 2189fb646a..019d866c04 100644 --- a/app/views/game/bits.scala +++ b/app/views/game/bits.scala @@ -1,7 +1,5 @@ package views.html.game -import play.twirl.api.Html - import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ @@ -12,30 +10,22 @@ import controllers.routes object bits { - def featuredJs(pov: Pov) = Html { - s"""${gameFenNoCtx(pov, tv = true)}${vstext(pov)(none)}""" - } + def featuredJs(pov: Pov): Frag = frag( + gameFenNoCtx(pov, tv = true), + vstext(pov)(none) + ) - def mini(pov: Pov)(implicit ctx: Context) = Html { - s"""${gameFen(pov)}${vstext(pov)(ctx.some)}""" - } + def mini(pov: Pov)(implicit ctx: Context): Frag = + a(href := gameLink(pov))( + gameFen(pov, withLink = false), + vstext(pov)(ctx.some) + ) - def miniBoard(fen: chess.format.FEN, color: chess.Color = chess.White) = Html { - s"""
    $miniBoardContent
    """ - } - - def watchers(implicit ctx: Context): Frag = - div( - cls := "watchers hidden", - aria.live := "off", - aria.relevant := "additions removals text" - )( - span(cls := "number")(nbsp), - " ", - trans.spectators.txt().replace(":", ""), - " ", - span(cls := "list inline_userlist") - ) + def miniBoard(fen: chess.format.FEN, color: chess.Color = chess.White): Frag = div( + cls := "mini-board parse-fen cg-board-wrap is2d", + dataColor := color.name, + dataFen := fen.value + )(div(cls := "cg-board")) def gameIcon(game: Game): Char = game.perfType match { case _ if game.fromPosition => '*' @@ -54,8 +44,8 @@ object bits { simul: Option[lila.simul.Simul], userTv: Option[lila.user.User] = None, bookmarked: Boolean - )(implicit ctx: Context) = div(cls := "sides")( - side(pov, initialFen, tour, simul, userTv, bookmarked = bookmarked), + )(implicit ctx: Context) = frag( + side.meta(pov, initialFen, tour, simul, userTv, bookmarked = bookmarked), cross.map { c => div(cls := "crosstable")(crosstable(ctx.userId.fold(c)(c.fromPov), pov.gameId.some)) } @@ -64,11 +54,9 @@ object bits { def variantLink( variant: chess.variant.Variant, name: String, - hintAsTitle: Boolean = false, - cssClass: String = "hint--bottom", initialFen: Option[chess.format.FEN] = None ) = a( - cls := s"$cssClass variant-link", + cls := "variant-link", href := (variant match { case chess.variant.Standard => "https://en.wikipedia.org/wiki/Chess" case chess.variant.FromPosition => s"""${routes.Editor.index}?fen=${initialFen.??(_.value.replace(' ', '_'))}""" @@ -76,8 +64,7 @@ object bits { }), rel := "nofollow", target := "_blank", - title := hintAsTitle option variant.title, - dataHint := !hintAsTitle option variant.title + title := variant.title )(name) private def playerTitle(player: Player) = @@ -85,34 +72,32 @@ object bits { span(cls := "title", dataBot(t), title := Title titleName t)(t.value) } - def vstext(pov: Pov)(ctxOption: Option[Context]) = - div(cls := "vstext clearfix")( - div(cls := "left user_link")( + def vstext(pov: Pov)(ctxOption: Option[Context]): Frag = + span(cls := "vstext")( + span(cls := "vstext__pl user-link")( playerUsername(pov.player, withRating = false, withTitle = false), br, playerTitle(pov.player) map { t => frag(t, " ") }, pov.player.rating, pov.player.provisional option "?" ), - div(cls := "right user_link")( + pov.game.clock map { c => + span(cls := "vstext__clock")(shortClockName(c.config)) + } orElse { + ctxOption flatMap { implicit ctx => + pov.game.daysPerTurn map { days => + span(cls := "vstext__clock")( + if (days == 1) trans.oneDay() else trans.nbDays.pluralSame(days) + ) + } + } + }, + span(cls := "vstext__op user-link")( playerUsername(pov.opponent, withRating = false, withTitle = false), br, pov.opponent.rating, pov.opponent.provisional option "?", playerTitle(pov.opponent) map { t => frag(" ", t) } - ), - pov.game.clock map { c => - div(cls := "center")(span(cls := "text", dataIcon := "p")(shortClockName(c.config))) - } orElse { - ctxOption flatMap { implicit ctx => - pov.game.daysPerTurn map { days => - div(cls := "center")( - span(cls := "hint--top", dataHint := trans.correspondence.txt())( - if (days == 1) trans.oneDay() else trans.nbDays.pluralSame(days) - ) - ) - } - } - } + ) ) } diff --git a/app/views/game/crosstable.scala b/app/views/game/crosstable.scala index 7f2c466d03..0dca736461 100644 --- a/app/views/game/crosstable.scala +++ b/app/views/game/crosstable.scala @@ -1,61 +1,62 @@ package views.html.game -import play.twirl.api.Html - -import controllers.routes import lila.api.Context import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ import lila.game.Crosstable +import controllers.routes + object crosstable { - def apply(ct: Crosstable.WithMatchup, currentId: Option[String])(implicit ctx: Context): Html = + def apply(ct: Crosstable.WithMatchup, currentId: Option[String])(implicit ctx: Context): Frag = apply(ct.crosstable, ct.matchup, currentId)(ctx) - def apply(ct: Crosstable, trueMatchup: Option[Crosstable.Matchup], currentId: Option[String])(implicit ctx: Context): Html = Html { + def apply(ct: Crosstable, trueMatchup: Option[Crosstable.Matchup], currentId: Option[String])(implicit ctx: Context): Frag = raw { val matchup = trueMatchup.filter(_.users != ct.users) - val users = ct.users.toList.map { u => + val matchupSepAt: Option[Int] = matchup map { m => + (ct.nbGames min Crosstable.maxGames) - m.users.nbGames + } - val fill = ct.fill.map { i => - s""" """ - } mkString "" + val fill = (ct.fillSize > 0) ?? s"""""" - val matchupSepAt: Option[Int] = matchup map { m => - (ct.nbGames min Crosstable.maxGames) - m.users.nbGames - } - - val results = ct.results.zipWithIndex.map { - case (r, i) => + val results = ct.results.zipWithIndex.map { + case (r, i) => + val links = ct.users.toList.map { u => val href = s"""${routes.Round.watcher(r.gameId, "white")}?pov=${u.id}""" val (linkClass, text) = r.winnerId match { case Some(w) if w == u.id => "glpt win" -> "1" case None => "glpt" -> "½" case _ => "glpt loss" -> "0" } - val link = s"""$text""" - val outClass = matchupSepAt.fold("") { at => - if (at == i) "sep new" - else if (at > i) "old" - else "new" - } - val current = if (currentId contains r.gameId) " current" else "" - s"""$link""" - } mkString "" - - val matchScore = matchup ?? { m => - s""" if (w == u.id) " win" else " loss")}">${m.users.showScore(u.id)}""" - } - - val user = s"""${userIdLink(u.id.some, withOnline = false)}""" - - val score = s""" if (w == u.id) " win" else " loss")}">${ct.showScore(u.id)}""" - - s"""$fill$results$matchScore$user$score""" - + s"""$text""" + } mkString "" + val outClass = matchupSepAt.has(i) ?? "sep" + val current = if (currentId contains r.gameId) " current" else "" + val cls = s"$outClass$current" + val clsDec = cls.nonEmpty ?? s""" class="$outClass$current"""" + s"""$links""" } mkString "" - s"""$users
    """ + val matchScore = matchup ?? { m => + val scores = ct.users.toList.map { u => + s""" if (w == u.id) "win" else "loss")}">${m.users.showScore(u.id)}""" + } + s"""
    ${scores mkString ""}
    """ + } + + val users = ct.users.toList.map { u => + userIdLink(u.id.some, withOnline = false).render + } + val usersDiv = s"""
    ${users mkString ""}
    """ + + val scores = ct.users.toList.map { u => + s""" if (w == u.id) "win" else "loss")}">${ct.showScore(u.id)}""" + } + val scoreDiv = s"""
    ${scores mkString ""}
    """ + + s"""
    $fill$results$matchScore$usersDiv$scoreDiv
    """ } } diff --git a/app/views/game/importGame.scala b/app/views/game/importGame.scala index 47fc180efd..15029e15fe 100644 --- a/app/views/game/importGame.scala +++ b/app/views/game/importGame.scala @@ -14,25 +14,25 @@ object importGame { def apply(form: play.api.data.Form[_])(implicit ctx: Context) = views.html.base.layout( title = trans.importGame.txt(), - moreCss = cssTags("form3.css", "import.css"), + moreCss = cssTag("importer"), moreJs = jsTag("importer.js"), openGraph = lila.app.ui.OpenGraph( title = "Paste PGN chess game", url = s"$netBaseUrl${routes.Importer.importGame.url}", - description = "When pasting a game PGN, you get a browsable replay, a computer analysis, a game chat and a sharable URL" + description = trans.importGameExplanation.txt() ).some ) { - div(id := "import_game", cls := "content_box")( - h1(dataIcon := "/", cls := "title text")(trans.importGame()), + main(cls := "importer page-small box box-pad")( + h1(trans.importGame()), p(cls := "explanation")(trans.importGameExplanation()), st.form(cls := "form3 import", action := routes.Importer.sendGame(), method := "post")( - form3.group(form("pgn"), trans.pasteThePgnStringHere.frag())(form3.textarea(_)()), + form3.group(form("pgn"), trans.pasteThePgnStringHere())(form3.textarea(_)()), form3.group(form("pgnFile"), raw("Or upload a PGN file"), klass = "upload") { f => form3.file.pgn(f.name) }, - form3.checkbox(form("analyse"), trans.requestAComputerAnalysis.frag(), help = Some(analyseHelp), disabled = ctx.isAnon), - form3.action(form3.submit(trans.importGame.frag())) + form3.checkbox(form("analyse"), trans.requestAComputerAnalysis(), help = Some(analyseHelp), disabled = ctx.isAnon), + form3.action(form3.submit(trans.importGame(), "/".some)) ) ) - }.toHtml + } } diff --git a/app/views/game/side.scala b/app/views/game/side.scala index 2e1d6f0fc5..87ec3591e9 100644 --- a/app/views/game/side.scala +++ b/app/views/game/side.scala @@ -20,117 +20,112 @@ object side { simul: Option[lila.simul.Simul], userTv: Option[lila.user.User] = None, bookmarked: Boolean + )(implicit ctx: Context): Option[Frag] = ctx.noBlind option frag( + meta(pov, initialFen, tour, simul, userTv, bookmarked), + pov.game.userIds.filter(isStreaming) map views.html.streamer.bits.contextual + ) + + def meta( + pov: lila.game.Pov, + initialFen: Option[chess.format.FEN], + tour: Option[lila.tournament.Tournament], + simul: Option[lila.simul.Simul], + userTv: Option[lila.user.User] = None, + bookmarked: Boolean )(implicit ctx: Context): Option[Frag] = ctx.noBlind option { import pov._ - div(cls := "side")( - div(cls := "side_box padded")( - div(cls := "game_infos", dataIcon := bits.gameIcon(game))( - div(cls := "header")( - span(cls := "setup")( - views.html.bookmark.toggle(game, bookmarked), - if (game.imported) frag( - a(cls := "hint--top", href := routes.Importer.importGame, dataHint := trans.importGame.txt())("IMPORT"), - separator, - if (game.variant.exotic) - bits.variantLink(game.variant, (if (game.variant == chess.variant.KingOfTheHill) game.variant.shortName else game.variant.name).toUpperCase, cssClass = "hint--top", initialFen = initialFen) - else - game.variant.name.toUpperCase - ) - else frag( - widgets showClock game, - separator, - if (game.rated) trans.rated.txt() else trans.casual.txt(), - separator, - if (game.variant.exotic) - bits.variantLink(game.variant, (if (game.variant == chess.variant.KingOfTheHill) game.variant.shortName else game.variant.name).toUpperCase, cssClass = "hint--top", initialFen = initialFen) - else - game.perfType.map { pt => - span(cls := "hint--top", dataHint := pt.title)(pt.shortName) - } - ) - ), - game.pgnImport.flatMap(_.date).map(frag(_)) getOrElse { - frag(if (game.isBeingPlayed) trans.playingRightNow() else momentFromNow(game.createdAt)) - } - ), - game.pgnImport.flatMap(_.date).map { date => - frag( - "Imported", - game.pgnImport.flatMap(_.user).map { user => - frag( - " by ", - userIdLink(user.some, None, false), - br + div(cls := "game__meta")( + st.section( + div(cls := "game__meta__infos", dataIcon := bits.gameIcon(game))( + div( + div(cls := "header")( + div(cls := "setup")( + views.html.bookmark.toggle(game, bookmarked), + if (game.imported) div( + a(href := routes.Importer.importGame, title := trans.importGame.txt())("IMPORT"), + separator, + if (game.variant.exotic) + bits.variantLink(game.variant, (if (game.variant == chess.variant.KingOfTheHill) game.variant.shortName else game.variant.name).toUpperCase, initialFen = initialFen) + else + game.variant.name.toUpperCase ) + else frag( + widgets showClock game, + separator, + if (game.rated) trans.rated.txt() else trans.casual.txt(), + separator, + if (game.variant.exotic) + bits.variantLink(game.variant, (if (game.variant == chess.variant.KingOfTheHill) game.variant.shortName else game.variant.name).toUpperCase, initialFen = initialFen) + else + game.perfType.map { pt => + span(title := pt.title)(pt.shortName) + } + ) + ), + game.pgnImport.flatMap(_.date).map(frag(_)) getOrElse { + frag(if (game.isBeingPlayed) trans.playingRightNow() else momentFromNow(game.createdAt)) } - ) - } + ), + game.pgnImport.flatMap(_.date).map { date => + small( + "Imported ", + game.pgnImport.flatMap(_.user).map { user => + trans.by(userIdLink(user.some, None, false)) + } + ) + } + ) ), - div(cls := "players")( + div(cls := "game__meta__players")( game.players.map { p => div(cls := s"player color-icon is ${p.color.name} text")( playerLink(p, withOnline = false, withDiff = true, withBerserk = true) ) } - ), - game.finishedOrAborted option { - div(cls := "status")( - gameEndStatus(game), - game.winner.map { winner => - frag( - separator, - winner.color.fold(trans.whiteIsVictorious(), trans.blackIsVictorious()) - ) - } - ) - }, - initialFen.ifTrue(game.variant.chess960).map(_.value).flatMap { - chess.variant.Chess960.positionNumber - }.map { number => - frag( - "Chess960 start position: ", - strong(number) - ) - } + ) ), - - game.userIds.filter(isStreaming).map { id => - a(cls := "context-streamer text side_box", dataIcon := "", href := routes.Streamer.show(id))( - usernameOrId(id), - " is streaming" + game.finishedOrAborted option { + st.section(cls := "status")( + gameEndStatus(game), + game.winner.map { winner => + frag( + separator, + winner.color.fold(trans.whiteIsVictorious, trans.blackIsVictorious)() + ) + } + ) + }, + initialFen.ifTrue(game.variant.chess960).map(_.value).flatMap { + chess.variant.Chess960.positionNumber + }.map { number => + st.section( + "Chess960 start position: ", + strong(number) ) }, userTv.map { u => - div(cls := "side_box")( - h2(cls := "top user_tv text", dataUserTv := u.id, dataIcon := "1")(u.titleUsername) + st.section(cls := "game__tv")( + h2(cls := "top user-tv text", dataUserTv := u.id, dataIcon := "1")(u.titleUsername) ) - } orElse { - lila.common.HTTPRequest.isMobile(ctx.req) option - a(cls := "side_box text deep_link", dataIcon := "", href := s"lichess://analyse/${pov.gameId}")( - "Open with ", - strong("Mobile app") - ) }, tour.map { t => - div(cls := "game_tournament side_box no_padding scroll-shadow-soft")( - p(cls := "top text", dataIcon := "g")(a(href := routes.Tournament.show(t.id))(t.fullName)), - div(cls := "clock", dataTime := t.secondsToFinish)( - div(cls := "time")(t.clockStatus) - ) + st.section(cls := "game__tournament")( + a(cls := "text", dataIcon := "g", href := routes.Tournament.show(t.id))(t.fullName), + div(cls := "clock", dataTime := t.secondsToFinish)(div(cls := "time")(t.clockStatus)) ) } orElse { game.tournamentId map { tourId => - div(cls := "game_tournament side_box no_padding")( - p(cls := "top text", dataIcon := "g")(a(href := routes.Tournament.show(tourId))(tournamentIdToName(tourId))) + st.section(cls := "game__tournament-link")( + a(href := routes.Tournament.show(tourId), dataIcon := "g", cls := "text")(tournamentIdToName(tourId)) ) } }, simul.map { sim => - div(cls := "game_simul side_box no_padding")( - p(cls := "top text", dataIcon := "|")(a(href := routes.Simul.show(sim.id))(sim.fullName)) + st.section(cls := "game__simul-link")( + a(href := routes.Simul.show(sim.id))(sim.fullName) ) } ) diff --git a/app/views/game/widgets.scala b/app/views/game/widgets.scala index f71c2f90a0..afadec6fee 100644 --- a/app/views/game/widgets.scala +++ b/app/views/game/widgets.scala @@ -3,8 +3,8 @@ package game import lila.api.Context import lila.app.templating.Environment._ -import lila.game.{ Game, Pov, Player } import lila.app.ui.ScalatagsTemplate._ +import lila.game.{ Game, Pov, Player } import controllers.routes @@ -20,36 +20,40 @@ object widgets { )(implicit ctx: Context): Frag = games map { g => val fromPlayer = user flatMap g.player val firstPlayer = fromPlayer | g.firstPlayer - div(cls := "game_row paginated")( - gameFen(Pov(g, firstPlayer), ownerLink, withTitle = false), - a(cls := "game_link_overlay", href := gameLink(g, firstPlayer.color, ownerLink)), - div(cls := "infos", dataIcon := bits.gameIcon(g))( - div(cls := "header")( - strong( - if (g.imported) frag( - span("IMPORT"), - g.pgnImport.flatMap(_.user).map { user => - frag(" ", trans.by(userIdLink(user.some, None, false))) - }, - separator, - if (g.variant.exotic) bits.variantLink(g.variant, g.variant.name.toUpperCase, cssClass = "hint--top") - else g.variant.name.toUpperCase - ) - else frag( - showClock(g), - separator, - g.perfType.fold(chess.variant.FromPosition.name)(_.name), - separator, - if (g.rated) trans.rated.txt() else trans.casual.txt() - ) - ), - g.pgnImport.flatMap(_.date).fold(momentFromNow(g.createdAt))(frag(_)), - g.tournamentId map { tourId => - frag(separator, tournamentLink(tourId)) - }, - g.simulId map { simulId => - frag(separator, simulLink(simulId)) - } + st.article(cls := "game-row paginated")( + a(cls := "game-row__overlay", href := gameLink(g, firstPlayer.color, ownerLink)), + div(cls := "game-row__board")( + gameFen(Pov(g, firstPlayer), withLink = false, withTitle = false) + ), + div(cls := "game-row__infos")( + div(cls := "header", dataIcon := bits.gameIcon(g))( + div(cls := "header__text")( + strong( + if (g.imported) frag( + span("IMPORT"), + g.pgnImport.flatMap(_.user).map { user => + frag(" ", trans.by(userIdLink(user.some, None, false))) + }, + separator, + if (g.variant.exotic) bits.variantLink(g.variant, g.variant.name.toUpperCase) + else g.variant.name.toUpperCase + ) + else frag( + showClock(g), + separator, + g.perfType.fold(chess.variant.FromPosition.name)(_.name), + separator, + if (g.rated) trans.rated.txt() else trans.casual.txt() + ) + ), + g.pgnImport.flatMap(_.date).fold(momentFromNow(g.createdAt))(frag(_)), + g.tournamentId map { tourId => + frag(separator, tournamentLink(tourId)) + }, + g.simulId map { simulId => + frag(separator, views.html.simul.bits.link(simulId)) + } + ) ), div(cls := "versus")( gamePlayer(g.variant, g.whitePlayer), @@ -59,7 +63,7 @@ object widgets { div(cls := "result")( if (g.isBeingPlayed) trans.playingRightNow() else { if (g.finishedOrAborted) - span(cls := g.winner.flatMap(w => fromPlayer.map(p => if (p == w) "up" else "down")))( + span(cls := g.winner.flatMap(w => fromPlayer.map(p => if (p == w) "win" else "loss")))( gameEndStatus(g), g.winner.map { winner => frag( @@ -73,9 +77,9 @@ object widgets { ), if (g.turns > 0) { val pgnMoves = g.pgnMoves take 20 - frag( + div(cls := "opening")( (!g.fromPosition ?? g.opening) map { opening => - div(cls := "opening")(opening.opening.ecoName) + strong(opening.opening.ecoName) }, div(cls := "pgn")( pgnMoves.take(6).grouped(2).zipWithIndex map { @@ -87,15 +91,11 @@ object widgets { ) ) } else frag(br, br), - div(cls := "metadata")( - g.metadata.analysed option frag( - span(cls := "text", dataIcon := "")(trans.computerAnalysisAvailable()), - br - ), - g.pgnImport.flatMap(_.user).map { user => - frag("PGN import by ", userIdLink(user.some), br) - } - ) + g.metadata.analysed option + div(cls := "metadata text", dataIcon := "")(trans.computerAnalysisAvailable()), + g.pgnImport.flatMap(_.user).map { user => + div(cls := "metadata")("PGN import by ", userIdLink(user.some)) + } ) ) } @@ -104,15 +104,14 @@ object widgets { frag(clock.config.show) } getOrElse { game.daysPerTurn.map { days => - span(cls := "hint--top", dataHint := trans.correspondence.txt())( + span(title := trans.correspondence.txt())( if (days == 1) trans.oneDay() else trans.nbDays.pluralSame(days) ) }.getOrElse { - span(cls := "hint--top", dataHint := trans.unlimited.txt())("∞") + span(title := trans.unlimited.txt())("∞") } } - private val berserkIconSpanFrag = raw(berserkIconSpan) private lazy val anonSpan = span(cls := "anon")(lila.user.User.anonymous) private def gamePlayer(variant: chess.variant.Variant, player: Player)(implicit ctx: Context) = @@ -121,7 +120,7 @@ object widgets { frag( userIdLink(playerUser.id.some, withOnline = false), br, - player.berserk option berserkIconSpanFrag, + player.berserk option berserkIconSpan, playerUser.rating, player.provisional option "?", playerUser.ratingDiff map { d => frag(" ", showRatingDiff(d)) } diff --git a/app/views/insight.scala b/app/views/insight.scala new file mode 100644 index 0000000000..75edbdb1bd --- /dev/null +++ b/app/views/insight.scala @@ -0,0 +1,99 @@ +package views.html + +import play.api.libs.json.Json + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.String.html.safeJsonValue +import lila.user.User + +import controllers.routes + +object insight { + + def index( + u: User, + cache: lila.insight.UserCache, + prefId: Int, + ui: play.api.libs.json.JsObject, + question: play.api.libs.json.JsObject, + stale: Boolean + )(implicit ctx: Context) = + views.html.base.layout( + title = s"${u.username}'s chess insights", + moreJs = frag( + highchartsLatestTag, + jsAt("vendor/multiple-select/multiple-select.js"), + jsAt(s"compiled/lichess.insight${isProd ?? (".min")}.js"), + jsTag("insight-refresh.js"), + jsTag("insight-tour.js"), + embedJsUnsafe(s""" +$$(function() { +lichess = lichess || {}; +lichess.insight = LichessInsight(document.getElementById('insight'), ${ + safeJsonValue(Json.obj( + "ui" -> ui, + "initialQuestion" -> question, + "i18n" -> Json.obj(), + "myUserId" -> ctx.userId, + "user" -> Json.obj( + "id" -> u.id, + "name" -> u.username, + "nbGames" -> cache.count, + "stale" -> stale, + "shareId" -> prefId + ), + "pageUrl" -> routes.Insight.index(u.username).url, + "postUrl" -> routes.Insight.json(u.username).url + )) + }); +});""") + ), + moreCss = cssTag("insight") + )(frag( + main(id := "insight"), + stale option div(cls := "insight-stale none")( + p("There are new games to learn from!"), + refreshForm(u, "Update insights") + ) + )) + + def empty(u: User)(implicit ctx: Context) = + views.html.base.layout( + title = s"${u.username}'s chess insights", + moreJs = jsTag("insight-refresh.js"), + moreCss = cssTag("insight") + )( + main(cls := "box box-pad page-small")( + h1(cls := "text", dataIcon := "7")(u.username, " chess insights"), + p(userLink(u), " has no chess insights yet!"), + refreshForm(u, s"Generate ${u.username}'s chess insights") + ) + ) + + def forbidden(u: User)(implicit ctx: Context) = + views.html.site.message( + title = s"${u.username}'s chess insights are protected", + back = true, + icon = "7".some + )( + p("Sorry, you cannot see ", userLink(u), "'s chess insights."), + br, + p( + "Maybe ask them to change their ", + a(cls := "button", href := routes.Pref.form("privacy"))("privacy settings"), + " ?" + ) + ) + + def refreshForm(u: User, action: String)(implicit ctx: Context) = + form(cls := "insight-refresh", method := "post", st.action := routes.Insight.refresh(u.username))( + button(dataIcon := "E", cls := "button text")(action), + div(cls := "crunching none")( + spinner, + br, + p(strong("Now crunching data just for you!")) + ) + ) +} diff --git a/app/views/insight/empty.scala.html b/app/views/insight/empty.scala.html deleted file mode 100644 index 11209aa711..0000000000 --- a/app/views/insight/empty.scala.html +++ /dev/null @@ -1,16 +0,0 @@ -@(u: User)(implicit ctx: Context) - -@insight.layout(u, -title = s"${u.username}'s chess insights", -moreJs = jsTag("insight-refresh.js")) { - -
    -
    -

    @u.username chess insights

    -
    -


    -

    @userLink(u) has no chess insights yet!

    -

    - @refreshForm(u, s"Generate ${u.username}'s chess insights") -
    -} diff --git a/app/views/insight/forbidden.scala.html b/app/views/insight/forbidden.scala.html deleted file mode 100644 index 7e2e16922b..0000000000 --- a/app/views/insight/forbidden.scala.html +++ /dev/null @@ -1,16 +0,0 @@ -@(u: User)(implicit ctx: Context) - -@site.message( -title = s"${u.username}'s chess insights are protected", -back = true, -icon = "7".some) { - -Sorry, you cannot see @userLink(u)'s chess insights. -
    -
    -
    -Maybe ask them to change their privacy settings ? -
    -
    -
    -}.toHtml diff --git a/app/views/insight/index.scala.html b/app/views/insight/index.scala.html deleted file mode 100644 index 282ea6c469..0000000000 --- a/app/views/insight/index.scala.html +++ /dev/null @@ -1,52 +0,0 @@ -@(u: User, cache: lila.insight.UserCache, prefId: Int, ui: play.api.libs.json.JsObject, question: play.api.libs.json.JsObject, stale: Boolean)(implicit ctx: Context) - -@moreJs = { -@highchartsLatestTag -@jsAt("vendor/multiple-select/multiple-select.js") -@jsAt(s"compiled/lichess.insight${isProd??(".min")}.js") -@jsTag("insight-refresh.js") -@jsTag("insight-tour.js") -@embedJs { -$(function() { -lichess = lichess || {}; -lichess.insight = LichessInsight(document.getElementById('insight'), { -ui: @toJsonHtml(ui), -initialQuestion: @toJsonHtml(question), -i18n: {}, -myUserId: @jsUserId, -user: { -id: "@u.id", -name: "@u.username", -nbGames: @cache.count, -stale: @stale, -shareId: @prefId -}, -pageUrl: "@routes.Insight.index(u.username)", -postUrl: "@routes.Insight.json(u.username)" -}); -}); -} -} - -@moreCss = { -@cssTag("insight.css") -@cssVendorTag("multiple-select/multiple-select.css") -@ctx.currentBg match { -case "dark" => { @cssTag("insight.dark.css") } -case "transp" => { @cssTag("insight.dark.css")@cssTag("insight.transp.css") } -case _ => {} -} -} - -@insight.layout(u, -title = s"${u.username}'s chess insights", -moreJs = moreJs, -moreCss = moreCss) { -
    -@if(stale) { -
    -

    There are new games to learn from!

    - @refreshForm(u, "Update insights") -
    -} -} diff --git a/app/views/insight/layout.scala.html b/app/views/insight/layout.scala.html deleted file mode 100644 index ce84acc65f..0000000000 --- a/app/views/insight/layout.scala.html +++ /dev/null @@ -1,8 +0,0 @@ -@(u: User, title: String, moreJs: Html = emptyHtml, moreCss: Html = emptyHtml, openGraph: Option[lila.app.ui.OpenGraph] = None, chessground: Boolean = true)(body: Html)(implicit ctx: Context) - -@base.layout( -title = title, -moreCss = moreCss, -moreJs = moreJs, -chessground = chessground, -openGraph = openGraph)(body).toHtml diff --git a/app/views/insight/refreshForm.scala.html b/app/views/insight/refreshForm.scala.html deleted file mode 100644 index 80369f47d7..0000000000 --- a/app/views/insight/refreshForm.scala.html +++ /dev/null @@ -1,12 +0,0 @@ -@(u: User, action: String)(implicit ctx: Context) - -
    - -
    - @spinner -
    - Now crunching data just for you! -
    -
    -
    -
    diff --git a/app/views/irwin.scala b/app/views/irwin.scala new file mode 100644 index 0000000000..5a61bf299e --- /dev/null +++ b/app/views/irwin.scala @@ -0,0 +1,124 @@ +package views.html + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object irwin { + + private def percentClass(percent: Int) = percent match { + case p if p < 30 => "green" + case p if p < 60 => "yellow" + case p if p < 80 => "orange" + case _ => "red" + } + + def dashboard(dashboard: lila.irwin.IrwinDashboard)(implicit ctx: Context) = base.layout( + title = "Irwin dashboard", + moreCss = cssTag("mod.misc") + ) { + main(cls := "page-menu")( + mod.menu("irwin"), + div(cls := "irwin page-menu__content box")( + div(cls := "box__top")( + h1( + "Irwin status: ", + if (dashboard.seenRecently) span(cls := "up")("Operational") + else span(cls := "down")( + dashboard.lastSeenAt.map { seenAt => + frag("Last seen ", momentFromNow(seenAt)) + } getOrElse { + frag("Unknown") + } + ) + ), + div(cls := "box__top__actions")( + a(href := "https://monitor.lichess.ovh/dashboard/db/lichess-moderation", cls := "button button-empty")("Monitoring") + ) + ), + table(cls := "slist slist-pad")( + thead( + tr( + th("Recent report"), + th("Completed"), + th("Owner"), + th("Activation") + ) + ), + tbody( + dashboard.recent.map { rep => + tr(cls := "report")( + td(userIdLink(rep.suspectId.value.some, params = "?mod")), + td(cls := "little completed")(momentFromNow(rep.date)), + td(rep.owner), + td(cls := s"little activation ${percentClass(rep.activation)}")( + strong(rep.activation, "%"), " over ", rep.games.size, " games" + ) + ) + } + ) + ) + ) + ) + } + + def report(report: lila.irwin.IrwinReport.WithPovs)(implicit ctx: Context): Frag = + div(id := "mz_irwin")( + header( + a(cls := "title", href := routes.Irwin.dashboard)( + img(src := staticUrl("images/icons/brain.blue.svg")), + " Irwin AI", br, "Hunter" + ), + div(cls := "infos")( + p("Updated ", momentFromNow(report.report.date)) + ), + div(cls := "assess text")( + strong(cls := percentClass(report.report.activation))(report.report.activation, "%"), + " Overall assessment" + ) + ), + table(cls := "slist")( + tbody( + report.withPovs.sortBy(-_.report.activation).map { + case lila.irwin.IrwinReport.GameReport.WithPov(gameReport, pov) => + tr(cls := "text")( + td(cls := "moves")( + a(href := routes.Round.watcher(pov.gameId, pov.color.name))( + gameReport.moves.map { move => + span( + cls := percentClass(move.activation), + st.title := move.toString, + style := s"height:${move.activation}%" + ) + } + ) + ), + td( + a(href := routes.Round.watcher(pov.gameId, pov.color.name))( + playerLink(pov.opponent, withRating = true, withDiff = true, withOnline = false, link = false), + br, + pov.game.isTournament ?? frag(iconTag("g")), + pov.game.perfType.map { pt => iconTag(pt.iconChar) }, + shortClockName(pov.game.clock.map(_.config)), + momentFromNowOnce(pov.game.createdAt) + ) + ), + td( + strong(cls := percentClass(gameReport.activation))(gameReport.activation, "%"), + " ", em("assessment") + ), + td { + val blurs = pov.game.playerBlurPercent(pov.color) + frag(strong(cls := percentClass(blurs))(blurs, "%"), " ", em("blurs")) + }, + td( + pov.player.holdAlert.exists(_.suspicious) option strong(cls := percentClass(50))("Bot?") + ) + ) + } + ) + ) + ) +} diff --git a/app/views/irwin/dashboard.scala.html b/app/views/irwin/dashboard.scala.html deleted file mode 100644 index 671b1aca60..0000000000 --- a/app/views/irwin/dashboard.scala.html +++ /dev/null @@ -1,62 +0,0 @@ -@(dashboard: lila.irwin.IrwinDashboard)(implicit ctx: Context) - -@percentClass(percent: Int) = { @percent match { -case p if p < 30 => {green} -case p if p < 60 => {yellow} -case p if p < 80 => {orange} -case _ => {red} -} } - -@mod.layout( -title = "Irwin dashboard", -active = "irwin", -moreCss = cssTag("mod-irwin.css")) { -
    -
    -

    - Irwin status: - @if(dashboard.seenRecently) { - Operational - } else { - - @dashboard.lastSeenAt.map { seenAt => - Last seen @momentFromNow(seenAt) - }.getOrElse { - Unknown - } - - } -

    - Monitoring -
    -
    - - - - - - - - - - - @dashboard.recent.map { rep => - - - - - - - } - -
    Recent reportCompletedOwnerActivation
    - @userIdLink(rep.suspectId.value.some, params = "?mod") - - @momentFromNow(rep.date) - @rep.owner - @rep.activation% - over @rep.games.size games -
    -
    -
    -} diff --git a/app/views/irwin/irwinReport.scala.html b/app/views/irwin/irwinReport.scala.html deleted file mode 100644 index 03f8882040..0000000000 --- a/app/views/irwin/irwinReport.scala.html +++ /dev/null @@ -1,65 +0,0 @@ -@(report: lila.irwin.IrwinReport.WithPovs)(implicit ctx: Context) - -@percentClass(percent: Int) = { @percent match { -case p if p < 30 => {green} -case p if p < 60 => {yellow} -case p if p < 80 => {orange} -case _ => {red} -} } - -
    -
    - - - Irwin AI
    - Hunter -
    -
    -

    Updated @momentFromNow(report.report.date)

    -
    -
    - @report.report.activation% - Overall assessment -
    -
    - - - @report.withPovs.sortBy(-_.report.activation).map { - case lila.irwin.IrwinReport.GameReport.WithPov(gameReport, pov) => { - - - - - - - - } - } - -
    - - @gameReport.moves.map { move => } - - - - @playerLink(pov.opponent, withRating = true, withDiff = true, withOnline = false, link = false) -
    - @if(pov.game.isTournament) { } - @pov.game.perfType.map { pt => } - @shortClockName(pov.game.clock.map(_.config)) - - @momentFromNowOnce(pov.game.createdAt) -
    -
    - @gameReport.activation% - assessment - - @defining(pov.game.playerBlurPercent(pov.color)) { blurs => - @blurs% - } - blurs - - @if(pov.player.holdAlert.??(_.suspicious)) { - Bot? - } -
    -
    diff --git a/app/views/learn/index.scala b/app/views/learn.scala similarity index 62% rename from app/views/learn/index.scala rename to app/views/learn.scala index 4ece5e1a0c..5c70f74386 100644 --- a/app/views/learn/index.scala +++ b/app/views/learn.scala @@ -1,6 +1,6 @@ package views.html.learn -import play.api.libs.json.JsObject +import play.api.libs.json.Json import lila.api.Context import lila.app.templating.Environment._ @@ -13,17 +13,17 @@ object index { def apply(data: Option[play.api.libs.json.JsValue])(implicit ctx: Context) = views.html.base.layout( title = s"${trans.learn.learnChess.txt()} - ${trans.learn.byPlaying.txt()}", - side = Some(div(id := "learn_side", cls := "side_box")), moreJs = frag( jsAt(s"compiled/lichess.learn${isProd ?? (".min")}.js"), - embedJs(s"""$$(function() { -LichessLearn(document.getElementById('learn_app'), { -data: ${data.fold("null")(safeJsonValue)}, -sideElement: document.getElementById('learn_side'), -i18n: ${safeJsonValue(i18nFullDbJsObject(lila.i18n.I18nDb.Learn))}});});""") + embedJsUnsafe(s"""$$(function() { +LichessLearn(document.getElementById('learn-app'), ${ + safeJsonValue(Json.obj( + "data" -> data, + "i18n" -> i18nFullDbJsObject(lila.i18n.I18nDb.Learn) + )) + })})""") ), - moreCss = cssTag("learn.css"), - chessground = false, + moreCss = cssTag("learn"), openGraph = lila.app.ui.OpenGraph( title = "Learn chess by playing", description = "You don't know anything about chess? Excellent! Let's have fun and learn to play chess!", @@ -31,6 +31,6 @@ i18n: ${safeJsonValue(i18nFullDbJsObject(lila.i18n.I18nDb.Learn))}});});""") ).some, zoomable = true ) { - div(id := "learn_app", cls := "learn cg-512") + main(id := "learn-app") } } diff --git a/app/views/lobby/bits.scala b/app/views/lobby/bits.scala index d3f28181c4..9c4a1dda65 100644 --- a/app/views/lobby/bits.scala +++ b/app/views/lobby/bits.scala @@ -8,120 +8,143 @@ import controllers.routes object bits { + val lobbyApp = div(cls := "lobby__app")( + div(cls := "tabs-horiz")(span(nbsp)), + div(cls := "lobby__app__content") + ) + def underboards( tours: List[lila.tournament.Tournament], simuls: List[lila.simul.Simul], leaderboard: List[lila.user.User.LightPerf], tournamentWinners: List[lila.tournament.Winner] )(implicit ctx: Context) = frag( - div(cls := "leaderboards undertable")( - div( - div(cls := "undertable_top")( - a(cls := "more", href := routes.User.list)(trans.more(), " »"), - span(cls := "title text", dataIcon := "C")(trans.leaderboard()) - ), - div(cls := "undertable_inner scroll-shadow-hard")( - table(tbody( - leaderboard map { l => - tr( - td(lightUserLink(l.user)), - lila.rating.PerfType(l.perfKey) map { pt => - td(cls := "text", dataIcon := pt.iconChar)(l.rating) - }, - td(showProgress(l.progress, withTitle = false)) - ) - } - )) - ) + div(cls := "lobby__leaderboard lobby__box")( + div(cls := "lobby__box__top")( + h2(cls := "title text", dataIcon := "C")(trans.leaderboard()), + a(cls := "more", href := routes.User.list)(trans.more(), " »") ), - div( - div(cls := "undertable_top")( - a(cls := "more", href := routes.Tournament.leaderboard)(trans.more(), " »"), - span(cls := "title text", dataIcon := "g")(trans.tournamentWinners()) - ), - div(cls := "undertable_inner scroll-shadow-hard")( - table(tbody( - tournamentWinners take 10 map { w => - tr( - td(userIdLink(w.userId.some)), - td(a(title := w.tourName, href := routes.Tournament.show(w.tourId))(scheduledTournamentNameShortHtml(w.tourName))) - ) - } - )) - ) + div(cls := "lobby__box__content")( + table(tbody( + leaderboard map { l => + tr( + td(lightUserLink(l.user)), + lila.rating.PerfType(l.perfKey) map { pt => + td(cls := "text", dataIcon := pt.iconChar)(l.rating) + }, + td(ratingProgress(l.progress)) + ) + } + )) ) ), - div(cls := "undertable")( - div(cls := "undertable_top")( - a(cls := "more", href := routes.Tournament.home())(frag(trans.more(), " »")), - span(cls := "title text", dataIcon := "g")(trans.openTournaments()) + div(cls := "lobby__winners lobby__box")( + div(cls := "lobby__box__top")( + h2(cls := "title text", dataIcon := "g")(trans.tournamentWinners()), + a(cls := "more", href := routes.Tournament.leaderboard)(trans.more(), " »") ), - div(id := "enterable_tournaments", cls := "enterable_list undertable_inner scroll-shadow-hard")( - views.html.tournament.enterable(tours) + div(cls := "lobby__box__content")( + table(tbody( + tournamentWinners take 10 map { w => + tr( + td(userIdLink(w.userId.some)), + td(a(title := w.tourName, href := routes.Tournament.show(w.tourId))(scheduledTournamentNameShortHtml(w.tourName))) + ) + } + )) ) ), - div(cls := List("undertable" -> true, "none" -> simuls.isEmpty))( - div(cls := "undertable_top")( - a(cls := "more", href := routes.Simul.home())(frag(trans.more(), " »")), - span(cls := "title text", dataIcon := "|")(trans.simultaneousExhibitions()) + div(cls := "lobby__tournaments lobby__box")( + div(cls := "lobby__box__top")( + h2(cls := "title text", dataIcon := "g")(trans.openTournaments()), + a(cls := "more", href := routes.Tournament.home())(trans.more(), " »") ), - div(id := "enterable_simuls", cls := "enterable_list undertable_inner")( + div(id := "enterable_tournaments", cls := "enterable_list lobby__box__content")( + views.html.tournament.bits.enterable(tours) + ) + ), + div(cls := "lobby__simuls lobby__box")( + div(cls := "lobby__box__top")( + h2(cls := "title text", dataIcon := "f")(trans.simultaneousExhibitions()), + a(cls := "more", href := routes.Simul.home())(trans.more(), " »") + ), + div(id := "enterable_simuls", cls := "enterable_list lobby__box__content")( views.html.simul.bits.allCreated(simuls) ) ) ) def lastPosts(posts: List[lila.blog.MiniPost])(implicit ctx: Context): Option[Frag] = posts.nonEmpty option - div(cls := "blog undertable")( - div( - div(cls := "undertable_top")( - a(cls := "more", href := routes.Blog.index())(trans.more(), " »"), - span(cls := "title text", dataIcon := "6")(trans.latestUpdates()) - ), - div(cls := "undertable_inner")( - posts map { post => - a(cls := "post", href := routes.Blog.show(post.id, post.slug))( - img(src := post.image), - span(cls := "text")( - span(cls := "title")(post.title), - p(cls := "shortlede")(post.shortlede) - ), - semanticDate(post.date) - ) - } - ) + div(cls := "lobby__blog lobby__box")( + div(cls := "lobby__box__top")( + h2(cls := "title text", dataIcon := "6")(trans.latestUpdates()), + a(cls := "more", href := routes.Blog.index())(trans.more(), " »") + ), + div(cls := "lobby__box__content")( + posts map { post => + a(cls := "post", href := routes.Blog.show(post.id, post.slug))( + img(src := post.image), + span(cls := "text")( + strong(post.title), + span(post.shortlede) + ), + semanticDate(post.date) + ) + } ) ) - def currentGameInfo(current: lila.app.mashup.Preload.CurrentGame)(implicit ctx: Context) = - div(id := "lobby_current_game")( - h2("Hang on!"), - p("You have a game in progress with ", strong(current.opponent), "."), - br, br, - a(cls := "big text button", dataIcon := "G", href := routes.Round.player(current.pov.fullId))("Join the game"), - br, br, - "or", - br, br, - form(action := routes.Round.resign(current.pov.fullId), method := "post")( - button(cls := "big text button", dataIcon := "L")( - if (current.pov.game.abortable) "Abort" else "Resign", " the game" - ) - ), - br, - p("You can't start a new game until this one is finished."), - br, br, - p( - "If you want to play several games simultaneously,", - br, - a(href := routes.Simul.home)("create a simultaneous exhibition event"), - "!" - ) + def playbanInfo(ban: lila.playban.TempBan)(implicit ctx: Context) = nopeInfo( + h1("Sorry :("), + p("We had to time you out for a ", (ban.remainingSeconds < 3600) ?? "little ", "while."), + p("The timeout expires ", strong(secondsFromNow(ban.remainingSeconds)), "."), + h2("Why?"), + p( + "We aim to provide a pleasant chess experience for everyone.", br, + "To that effect, we must ensure that all players follow good practice.", br, + "When a potential problem is detected, we display this message." + ), + h2("How to avoid this?"), + ul( + li("Play every game you start"), + li("Try to win (or at least draw) every game you play"), + li("Resign lost games (don't let the clock run down)") + ), + p( + "We apologize for the temporary inconvenience,", br, + "and wish you great games on lichess.org.", br, + "Thank you for reading!" ) + ) + + def currentGameInfo(current: lila.app.mashup.Preload.CurrentGame)(implicit ctx: Context) = nopeInfo( + h1("Hang on!"), + p("You have a game in progress with ", strong(current.opponent), "."), + br, br, + a(cls := "text button button-fat", dataIcon := "G", href := routes.Round.player(current.pov.fullId))("Join the game"), + br, br, + "or", + br, br, + form(action := routes.Round.resign(current.pov.fullId), method := "post")( + button(cls := "text button button-red", dataIcon := "L")( + if (current.pov.game.abortable) "Abort" else "Resign", " the game" + ) + ), + br, + p("You can't start a new game until this one is finished.") + ) + + def nopeInfo(content: Modifier*) = frag( + div(cls := "lobby__app"), + div(cls := "lobby__nope")( + st.section(cls := "lobby__app__content")(content) + ) + ) def spotlight(e: lila.event.Event)(implicit ctx: Context) = a( href := (if (e.isNow) e.url else routes.Event.show(e.id).url), cls := List( - s"tour_spotlight event_spotlight id_${e.id}" -> true, + s"tour-spotlight event-spotlight id_${e.id}" -> true, "invert" -> e.isNowOrSoon ) )( diff --git a/app/views/lobby/blindLobby.scala b/app/views/lobby/blindLobby.scala new file mode 100644 index 0000000000..b286a7ddb0 --- /dev/null +++ b/app/views/lobby/blindLobby.scala @@ -0,0 +1,34 @@ +package views.html.lobby + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.game.Pov + +import controllers.routes + +object blindLobby { + + def apply(games: List[Pov])(implicit ctx: Context) = div( + h2(games.size, " ongoing games"), + games.nonEmpty option ongoingGames(games), + div(cls := "lobby__app none") + ) + + private def ongoingGames(games: List[Pov])(implicit ctx: Context) = games.partition(_.isMyTurn) match { + case (myTurn, opTurn) => frag( + h3("My turn: ", myTurn.size, " games"), + ul(myTurn map renderGame), + h3("Opponent turn: ", opTurn.size, " games"), + ul(opTurn map renderGame) + ) + } + + private def renderGame(pov: Pov)(implicit ctx: Context) = li( + a(href := gameLink(pov))( + playerText(pov.opponent), + " ", + pov.isMyTurn ?? pov.remainingSeconds map { secondsFromNow(_, true) } + ) + ) +} diff --git a/app/views/lobby/home.scala b/app/views/lobby/home.scala index 27eaa51a9c..6e41417da0 100644 --- a/app/views/lobby/home.scala +++ b/app/views/lobby/home.scala @@ -1,7 +1,6 @@ package views.html.lobby import play.api.libs.json.{ Json, JsObject } -import play.twirl.api.Html import lila.api.Context import lila.app.templating.Environment._ @@ -29,64 +28,31 @@ object home { lastPost: List[lila.blog.MiniPost], playban: Option[lila.playban.TempBan], currentGame: Option[lila.app.mashup.Preload.CurrentGame], - nbRounds: Int + nbRounds: Int, + blindGames: List[Pov] // only in blind mode )(implicit ctx: Context) = views.html.base.layout( title = "", - fullTitle = Some("lichess.org • " + trans.freeOnlineChess.txt()), - baseline = Some(frag( - a(id := "nb_connected_players", href := ctx.noBlind.option(routes.User.list.toString))(trans.nbPlayers.frag(nbPlayersPlaceholder)), - a(id := "nb_games_in_play", href := ctx.noBlind.option(routes.Tv.games.toString))( - trans.nbGamesInPlay.pluralFrag(nbRounds, span(nbRounds)) - ), - ctx.isMobileBrowser option { - if (HTTPRequest isAndroid ctx.req) views.html.mobile.bits.googlePlayButton - else if (HTTPRequest isIOS ctx.req) views.html.mobile.bits.appleStoreButton - else emptyFrag - } - )), - side = Some(frag( - ctx.noKid option div(id := "streams_on_air")(views.html.streamer.bits liveStreams streams), - events map { bits.spotlight(_) }, - !ctx.isBot option frag( - lila.tournament.Spotlight.select(tours, ctx.me, 3) map { views.html.tournament.homepageSpotlight(_) }, - simuls.find(_.spotlightable) take 2 map { views.html.simul.bits.homepageSpotlight(_) } toList - ), - ctx.me map { u => - div(id := "timeline", dataHref := routes.Timeline.home)( - views.html.timeline entries userTimeline, - div(cls := "links")( - userTimeline.size >= 8 option - a(cls := "more", href := routes.Timeline.home)(trans.more.frag(), " »") - ) - ) - } getOrElse { - div(cls := "about-side")( - trans.xIsAFreeYLibreOpenSourceChessServer.frag("Lichess", a(cls := "blue", href := routes.Plan.features)(trans.really.txt())), - " ", - a(cls := "blue", href := "/about")(trans.aboutX.frag("lichess.org"), "...") - ) - } - )), + fullTitle = Some { + s"lichess.${if (isProd && !isStage) "org" else "dev"} • ${trans.freeOnlineChess.txt()}" + }, moreJs = frag( - jsAt(s"compiled/lichess.lobby${isProd ?? (".min")}.js", async = true), - embedJs { - val playbanJs = playban.fold("null")(pb => safeJsonValue(Json.obj("minutes" -> pb.mins, "remainingSeconds" -> (pb.remainingSeconds + 3)))) - val gameJs = currentGame.fold("null")(cg => safeJsonValue(cg.json)) - val transJs = safeJsonValue(i18nJsObject(translations)) - s"""window.customWS = true; lichess_lobby = { data: ${safeJsonValue(data)}, playban: $playbanJs, currentGame: $gameJs, i18n: $transJs, }""" - } - ), - moreCss = cssTag("home.css"), - underchat = Some(frag( - div(id := "featured_game")( - featured map { g => - frag( - gameFen(Pov first g, tv = true), - views.html.game.bits.vstext(Pov first g)(ctx.some) - ) - } + jsAt(s"compiled/lichess.lobby${isProd ?? (".min")}.js", defer = true), + embedJsUnsafe( + s"""lichess=window.lichess||{};customWS=true;lichess_lobby=${ + safeJsonValue(Json.obj( + "data" -> data, + "playban" -> playban.map { pb => + Json.obj( + "minutes" -> pb.mins, + "remainingSeconds" -> (pb.remainingSeconds + 3) + ) + }, + "i18n" -> i18nJsObject(translations) + )) + }""" ) - )), + ), + moreCss = cssTag("lobby"), chessground = false, openGraph = lila.app.ui.OpenGraph( image = staticUrl("images/large_tile.png").some, @@ -94,68 +60,118 @@ object home { url = netBaseUrl, description = trans.siteDescription.txt() ).some, - asyncJs = true + deferJs = true ) { - frag( - div(cls := List( - "lobby_and_ground" -> true, - "playban" -> playban.isDefined, - "current_game" -> currentGame.isDefined - ))( - currentGame map { bits.currentGameInfo(_) }, - div(id := "hooks_wrap"), - playban.map(ban => playbanInfo(ban.remainingSeconds)), - div(id := "start_buttons", cls := "lichess_ground")( + main(cls := List( + "lobby" -> true, + "lobby-nope" -> (playban.isDefined || currentGame.isDefined) + ))( + div(cls := "lobby__table")( + div(cls := "lobby__start")( + ctx.blind option h2("Play"), a(href := routes.Setup.hookForm, cls := List( - "fat button config_hook" -> true, + "button button-metal config_hook" -> true, "disabled" -> (playban.isDefined || currentGame.isDefined || ctx.isBot) - ), trans.createAGame.frag()), + ), trans.createAGame()), a(href := routes.Setup.friendForm(none), cls := List( - "fat button config_friend" -> true, + "button button-metal config_friend" -> true, "disabled" -> currentGame.isDefined - ), trans.playWithAFriend.frag()), + ), trans.playWithAFriend()), a(href := routes.Setup.aiForm, cls := List( - "fat button config_ai" -> true, + "button button-metal config_ai" -> true, "disabled" -> currentGame.isDefined - ), trans.playWithTheMachine.frag()) + ), trans.playWithTheMachine()) + ), + div(cls := "lobby__counters")( + ctx.blind option h2("Counters"), + a(id := "nb_connected_players", href := ctx.noBlind.option(routes.User.list.toString))(trans.nbPlayers(nbPlayersPlaceholder)), + a(id := "nb_games_in_play", href := ctx.noBlind.option(routes.Tv.games.toString))( + trans.nbGamesInPlay.plural(nbRounds, strong(nbRounds)) + ) ) ), + currentGame.map(bits.currentGameInfo) orElse + playban.map(bits.playbanInfo) getOrElse { + if (ctx.blind) blindLobby(blindGames) + else bits.lobbyApp + }, + div(cls := "lobby__side")( + ctx.blind option h2("Highlights"), + ctx.noKid option st.section(cls := "lobby__streams")(views.html.streamer.bits liveStreams streams), + div(cls := "lobby__spotlights")( + events.map(bits.spotlight), + !ctx.isBot option frag( + lila.tournament.Spotlight.select(tours, ctx.me, 3 - events.size) map { views.html.tournament.homepageSpotlight(_) }, + simuls.find(_.spotlightable).headOption map views.html.simul.bits.homepageSpotlight + ) + ), + ctx.me map { u => + div(cls := "timeline", dataHref := routes.Timeline.home)( + ctx.blind option h2("Timeline"), + views.html.timeline entries userTimeline, + // userTimeline.size >= 8 option + a(cls := "more", href := routes.Timeline.home)(trans.more(), " »") + ) + } getOrElse div(cls := "about-side")( + ctx.blind option h2("About"), + trans.xIsAFreeYLibreOpenSourceChessServer("Lichess", a(cls := "blue", href := routes.Plan.features)(trans.really.txt())), + " ", + a(href := "/about")(trans.aboutX("Lichess"), "...") + ) + ), + featured map { g => + div(cls := "lobby__tv")( + gameFen(Pov first g, tv = true), + views.html.game.bits.vstext(Pov first g)(ctx.some) + ) + }, puzzle map { p => - div(id := "daily_puzzle", title := trans.clickToSolve.txt())( + div(cls := "lobby__puzzle", title := trans.clickToSolve.txt())( raw(p.html), div(cls := "vstext")( - trans.puzzleOfTheDay.frag(), + trans.puzzleOfTheDay(), br, p.color.fold(trans.whitePlays, trans.blackPlays)() ) ) }, ctx.noBot option bits.underboards(tours, simuls, leaderboard, tournamentWinners), - ctx.noKid option frag( - div(cls := "new_posts undertable")( - div(cls := "undertable_top")( - a(cls := "more", href := routes.ForumCateg.index)(trans.more.frag(), " »"), - span(cls := "title text", dataIcon := "d")(trans.latestForumPosts.frag()) - ), - div(cls := "undertable_inner scroll-shadow-hard")( - div(cls := "content")(views.html.forum.post recent forumRecent) - ) + ctx.noKid option div(cls := "lobby__forum lobby__box")( + div(cls := "lobby__box__top")( + h2(cls := "title text", dataIcon := "d")(trans.latestForumPosts()), + a(cls := "more", href := routes.ForumCateg.index)(trans.more(), " »") + ), + div(cls := "lobby__box__content")( + views.html.forum.post recent forumRecent ) ), bits.lastPosts(lastPost), - div(cls := "donation undertable")( + div(cls := "lobby__support")( a(href := routes.Plan.index)( iconTag(patronIconChar), - strong("Lichess Patron"), - span(trans.directlySupportLichess.frag()) + span(cls := "lobby__support__text")( + strong("Lichess Patron"), + span(trans.directlySupportLichess()) + ) ), a(href := routes.Page.swag)( iconTag(""), - strong("Swag Store"), - span(trans.playChessInStyle.frag()) + span(cls := "lobby__support__text")( + strong("Swag Store"), + span(trans.playChessInStyle()) + ) ) ), - div(cls := "about-footer")(a(href := "/about")(trans.aboutX.frag("lichess.org"))) + div(cls := "lobby__about")( + ctx.blind option h2("About"), + a(href := "/about")(trans.aboutX("Lichess")), + a(href := "/faq")("FAQ"), + a(href := "/contact")(trans.contact()), + a(href := "/mobile")(trans.mobileApp()), + a(href := routes.Page.tos)(trans.termsOfService()), + a(href := routes.Page.privacy)(trans.privacy()), + a(href := routes.Page.source)(trans.sourceCode()) + ) ) } diff --git a/app/views/lobby/playbanInfo.scala.html b/app/views/lobby/playbanInfo.scala.html deleted file mode 100644 index 2168047579..0000000000 --- a/app/views/lobby/playbanInfo.scala.html +++ /dev/null @@ -1,26 +0,0 @@ -@(seconds: Int)(implicit ctx: Context) -
    -

    Sorry :(

    -

    We had to time you out for a @if(seconds < 3600){little }while. -
    -

    The timeout expires @secondsFromNow(seconds).

    -

    Why?

    -

    - We aim to provide a pleasant chess experience for everyone.
    - To that effect, we must ensure that all players follow good practices.
    - When a potential problem is detected, we display this message. -

    -

    How to avoid this?

    -
      -
    • Play every game you start
    • -
    • Try to win (or at least draw) every game you play
    • -
    • Resign lost games (don't let the clock run down)
    • -
    -
    -
    -

    - We apologize for the temporary inconvenience,
    - and wish you great games on lichess.org.
    - Thank you for reading! -

    -
    diff --git a/app/views/message/form.scala b/app/views/message/form.scala new file mode 100644 index 0000000000..bafd31a5a0 --- /dev/null +++ b/app/views/message/form.scala @@ -0,0 +1,89 @@ +package views.html.message + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator +import lila.common.String.html.safeJsonValue + +import controllers.routes + +object form { + + def apply( + form: Form[_], + reqUser: Option[lila.user.User], + reqTitle: Option[String], + reqMod: Boolean, + canMessage: Boolean, + oldEnough: Boolean + )(implicit ctx: Context) = + views.html.base.layout( + title = trans.composeMessage.txt(), + moreCss = cssTag("message"), + moreJs = jsTag("message.js") + ) { + main(cls := "message-new box box-pad page-small")( + h1(trans.composeMessage()), + reqUser.ifFalse(canMessage).map { u => + frag( + br, br, hr, br, + p("Sorry, ", u.username, " doesn't accept new messages.") + ) + } getOrElse { + if (!oldEnough) frag( + br, br, hr, br, + p("Sorry, you cannot start conversations yet.") + ) + else st.form( + cls := "form3", + action := s"${routes.Message.create()}${reqUser.??(u => "?username=" + u.username)}", + method := "post" + )( + form3.group(form("username"), trans.recipient()) { f => + reqUser map { user => + frag( + userLink(user), + form3.hidden(f) + ) + } getOrElse input( + cls := "form-control user-autocomplete", + required, + name := f.name, + id := form3.id(f), + value := f.value, + autofocus, + dataTag := "span" + ) + }, + isGranted(_.ModMessage) option frag( + form3.checkbox(form("mod"), frag("Send as mod")), + form3.group(form("preset"), frag("Preset")) { form3.select(_, Nil) }, + embedJsUnsafe(s"""lichess_mod_presets=${safeJsonValue(lila.message.ModPreset.asJson)}""") + ), + form3.group(form("subject"), trans.subject()) { f => + input( + cls := "form-control", + required, + minlength := 3, + maxlength := 100, + name := f.name, + id := form3.id(f), + value := f.value.filter(_.nonEmpty).orElse(reqTitle), + reqUser.isDefined option autofocus + ) + }, + form3.group(form("text"), frag("Message"), klass = "message-text") { f => + form3.textarea(f)(required) + }, + form3.actions( + a(cls := "cancel", href := routes.Message.inbox())(trans.cancel()), + button(cls := "button text", dataIcon := "E", tpe := "submit")(trans.send()) + ) + ) + } + ) + } +} diff --git a/app/views/message/form.scala.html b/app/views/message/form.scala.html deleted file mode 100644 index 4e1fff1172..0000000000 --- a/app/views/message/form.scala.html +++ /dev/null @@ -1,94 +0,0 @@ -@(form: Form[_], reqUser: Option[User], reqTitle: Option[String], reqMod: Boolean, canMessage: Boolean, oldEnough: Boolean)(implicit ctx: Context) - -@message.layout( -title = trans.composeMessage.txt()) { -
    -
    -

    @trans.composeMessage()

    - @reqUser.ifFalse(canMessage).map { u => -



    -

    Sorry, @u.username doesn't accept new messages.

    - }.getOrElse { - @if(!oldEnough) { -



    -

    Sorry, you cannot start conversations yet.

    - } else { -
    -
    -
    - - @reqUser.map { user => - @userLink(user) - - }.getOrElse { - - @errMsg(form("username")) - } -
    - - @if(isGranted(_.ModMessage)) { -
    - - - - - -
    -
    - - -
    - @embedJs { - window.lichess_mod_presets = @toJsonHtml(lila.message.ModPreset.asJson); - } - } - -
    - - - @errMsg(form("subject")) -
    -
    - - @errMsg(form("text")) -
    -
    - - @trans.cancel() -
    -
    -
    - } - } -
    -
    -} diff --git a/app/views/message/inbox.scala b/app/views/message/inbox.scala new file mode 100644 index 0000000000..bab3cbfd07 --- /dev/null +++ b/app/views/message/inbox.scala @@ -0,0 +1,60 @@ +package views.html.message + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator + +import controllers.routes + +object inbox { + + def apply(me: lila.user.User, threads: Paginator[lila.message.Thread])(implicit ctx: Context) = + views.html.base.layout( + title = trans.inbox.txt(), + moreCss = cssTag("message"), + moreJs = frag(infiniteScrollTag, jsTag("message.js")) + ) { + main(cls := "message-list box")( + div(cls := "box__top")( + h1(trans.inbox()), + div(cls := "box__top__actions")( + threads.nbResults > 0 option frag( + select(cls := "select")( + option(value := "")("Select"), + option(value := "all")("All"), + option(value := "none")("None"), + option(value := "unread")("Unread"), + option(value := "read")("Read") + ), + select(cls := "action")( + option(value := "")("Do"), + option(value := "unread")("Mark as unread"), + option(value := "read")("Mark as read"), + option(value := "delete")("Delete") + ) + ), + a(href := routes.Message.form, cls := "button button-green text", dataIcon := "m")(trans.composeMessage()) + ) + ), + table(cls := "slist slist-pad")( + if (threads.nbResults > 0) tbody(cls := "infinitescroll")( + pagerNextTable(threads, p => routes.Message.inbox(p).url), + threads.currentPageResults.map { thread => + tr(cls := List( + "paginated" -> true, + "new" -> thread.isUnReadBy(me), + "mod" -> thread.asMod + ))( + td(cls := "author")(userIdLink(thread.visibleOtherUserId(me), none)), + td(cls := "subject")(a(href := s"${routes.Message.thread(thread.id)}#bottom")(thread.name)), + td(cls := "date")(momentFromNow(thread.updatedAt)), + td(cls := "check")(input(tpe := "checkbox", name := "threads", value := thread.id)) + ) + } + ) + else tbody(tr(td(trans.noNewMessages(), br, br))) + ) + ) + } +} diff --git a/app/views/message/inbox.scala.html b/app/views/message/inbox.scala.html deleted file mode 100644 index cbdf559cb0..0000000000 --- a/app/views/message/inbox.scala.html +++ /dev/null @@ -1,61 +0,0 @@ -@(me: User, threads: Paginator[lila.message.Thread])(implicit ctx: Context) - -@message.layout( -title = trans.inbox.txt()) { -
    -
    -

    @trans.inbox()

    - @if(threads.nbResults > 0) { -
    - - -
    - } -
    - - @if(threads.nbResults > 0) { - - @if(threads.hasToPaginate) { - - } - @threads.currentPageResults.map { thread => - - - - - - - } - - } else { - - - - - - } - -
    - -
    - @userIdLink(thread.visibleOtherUserId(me), none) - - @thread.name - @momentFromNow(thread.updatedAt) - -
    - @trans.noNewMessages() -
    -
    -} diff --git a/app/views/message/layout.scala.html b/app/views/message/layout.scala.html deleted file mode 100644 index 7813d95e66..0000000000 --- a/app/views/message/layout.scala.html +++ /dev/null @@ -1,24 +0,0 @@ -@(title: String)(body: Html)(implicit ctx: Context) - -@moreCss = { -@cssTag("message.css") -} - -@moreJs = { -@infiniteScrollTag -@jsTag("message.js") -@jsTag("embed-analyse.js") -} - -@side = { - -} - -@base.layout( -title = title, -moreCss = moreCss, -moreJs = moreJs, -side = side.some)(body).toHtml diff --git a/app/views/message/thread.scala b/app/views/message/thread.scala new file mode 100644 index 0000000000..3873923b5f --- /dev/null +++ b/app/views/message/thread.scala @@ -0,0 +1,85 @@ +package views.html.message + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator +import lila.common.String.html.richText + +import controllers.routes + +object thread { + + def apply( + thread: lila.message.Thread, + replyForm: Option[Form[_]], + blocks: Boolean + )(implicit ctx: Context, me: lila.user.User) = + views.html.base.layout( + title = thread.name, + moreCss = cssTag("message"), + moreJs = frag( + jsTag("message.js"), + jsAt("compiled/embed-analyse.js") + ) + ) { + main(cls := List( + "message-thread box box-pad page-small" -> true, + "mod" -> thread.asMod + ))( + div(cls := "box__top")( + h1( + a(href := routes.Message.inbox(1), dataIcon := "I", cls := "text"), + thread.nonEmptyName + ), + st.form(action := routes.Message.delete(thread.id), method := "post")( + button(tpe := "submit", cls := "button button-empty button-red confirm")("Delete") + ) + ), + thread.posts.map { post => + st.article(cls := "message-thread__message embed_analyse", id := s"message_${post.id}")( + div(cls := "infos")( + div( + userIdLink(thread.visibleSenderOf(post), none), + iconTag("H")(cls := "to"), + userIdLink(thread.visibleReceiverOf(post), "inline".some) + ), + momentFromNow(post.createdAt) + ), + div(cls := "message-thread__message__body")(richText(post.text)) + ) + }, + div(cls := "message-thread__answer", id := "bottom")( + if (blocks) + p(cls := "end")( + userIdLink(thread.visibleOtherUserId(me).some), + " blocks you. You cannot reply." + ) + else { + if (!thread.isVisibleByOther(me) && !me.troll) p(cls := "end")( + userIdLink(thread.visibleOtherUserId(me).some), " has closed this thread.", + !thread.asMod option + a( + href := s"${routes.Message.form}?user=${thread.otherUserId(me)}", + cls := "button" + )("Create a new one") + ) + else replyForm.map { form => + st.form(action := routes.Message.answer(thread.id), method := "post")( + div(cls := "field_body")( + form3.textarea(form("text"))(required), + errMsg(form("text")) + ), + div(cls := "actions")( + a(cls := "cancel", href := routes.Message.inbox(1))(trans.cancel()), + button(cls := "button text", dataIcon := "E", tpe := "submit")(trans.send()) + ) + ) + } + } + ) + ) + } +} diff --git a/app/views/message/thread.scala.html b/app/views/message/thread.scala.html deleted file mode 100644 index fcdb317141..0000000000 --- a/app/views/message/thread.scala.html +++ /dev/null @@ -1,53 +0,0 @@ -@(thread: lila.message.Thread, form: Option[Form[_]], blocks: Boolean)(implicit ctx: Context, me: User) - -@message.layout( -title = thread.name) { -
    -
    -
    - -
    -
    - -
    -

    @thread.nonEmptyName

    -
    - - @thread.posts.map { post => -
    - - @userIdLink(thread.visibleSenderOf(post), none) @userIdLink(thread.visibleReceiverOf(post), "inline".some) - @momentFromNow(post.createdAt) - -
    @richText(post.text)
    -
    - } - -
    - @if(blocks) { -

    @userIdLink(thread.visibleOtherUserId(me).some) blocks you. You cannot answer.

    - } else { - @if(!thread.isVisibleByOther(me) && !me.troll) { -

    - @userIdLink(thread.visibleOtherUserId(me).some) has closed this thread. - @if(!thread.asMod){ - Create a new one - } -

    - } else { - @form.map { f => -
    -
    - - @errMsg(f("text")) -
    -
    - - @trans.cancel() -
    -
    - } - } - } -
    -
    -} diff --git a/app/views/mobile.scala b/app/views/mobile.scala new file mode 100644 index 0000000000..cc2a560d0b --- /dev/null +++ b/app/views/mobile.scala @@ -0,0 +1,77 @@ +package views.html + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object mobile { + + def apply(apkDoc: io.prismic.Document, resolver: io.prismic.DocumentLinkResolver)(implicit ctx: Context) = base.layout( + title = "Mobile", + moreCss = cssTag("mobile") + ) { + main( + div(cls := "mobile page-small box box-pad")( + h1(trans.playChessEverywhere()), + div(cls := "sides")( + div(cls := "left-side")( + div(cls := "stores")( + googlePlayButton, + appleStoreButton + ), + div(cls := "apk")( + raw(~apkDoc.getHtml("doc.content", resolver)) + ), + h2(trans.asFreeAsLichess()), + ul(cls := "block")( + li(trans.builtForTheLoveOfChessNotMoney()), + li(trans.everybodyGetsAllFeaturesForFree()), + li(trans.zeroAdvertisement()), + li("Entirely ", a(href := "https://github.com/veloce/lichobile")("Open Source")) + ), + h2(trans.fullFeatured()), + ul(cls := "block")( + li(trans.phoneAndTablet()), + li(trans.bulletBlitzClassical()), + li(trans.correspondenceChess()), + li(trans.onlineAndOfflinePlay()), + li(trans.tournaments()), + li(trans.puzzles()), + li(trans.gameAnalysis()), + li(trans.boardEditor()), + li("Lichess TV"), + li(trans.followAndChallengeFriends()), + li(trans.availableInNbLanguages.pluralSame(80)) + ) + ), + div(cls := "right-side")( + img(cls := "nexus5-playing", width := "268", height := "513", src := staticUrl("images/mobile/nexus5-playing.png"), alt := "Lichess mobile on nexus 5"), + img(cls := "qrcode", width := "200", height := "200", src := staticUrl("images/mobile/dynamic-qrcode.png"), alt := "Download QR code") + ) + ) + ) + ) + } + + lazy val appleStoreButton = raw(""" + + Download on the Apple App Store + +""") + + lazy val googlePlayButton = raw(""" + + Android app on Google Play + +""") +} diff --git a/app/views/mobile/bits.scala b/app/views/mobile/bits.scala deleted file mode 100644 index 40d75f3c12..0000000000 --- a/app/views/mobile/bits.scala +++ /dev/null @@ -1,30 +0,0 @@ -package views.html.mobile - -import lila.api.Context -import lila.app.templating.Environment._ -import lila.app.ui.ScalatagsTemplate._ - -import controllers.routes - -object bits { - - lazy val appleStoreButton = raw(""" - - Download on the Apple App Store - -""") - - lazy val googlePlayButton = raw(""" - - Android app on Google Play - -""") -} diff --git a/app/views/mobile/home.scala.html b/app/views/mobile/home.scala.html deleted file mode 100644 index 1ab6b13e50..0000000000 --- a/app/views/mobile/home.scala.html +++ /dev/null @@ -1,46 +0,0 @@ -@(apkDoc: io.prismic.Document, resolver: io.prismic.DocumentLinkResolver)(implicit ctx: Context) - -@base.layout( -title = "Mobile", -moreCss = cssTag("mobile.css")) { -
    -
    - Lichess mobile on nexus 5 - Download QR code -
    -
    -

    @trans.playChessEverywhere()

    - @bits.googlePlayButton.toHtml - @bits.appleStoreButton.toHtml -
    - @Html(~apkDoc.getHtml("doc.content", resolver)) -
    -

    @trans.asFreeAsLichess()

    -
      -
    • @trans.builtForTheLoveOfChessNotMoney()
    • -
    • @trans.everybodyGetsAllFeaturesForFree()
    • -
    • @trans.zeroAdvertisement()
    • -
    • Entirely Open Source
    • -
    -

    @trans.fullFeatured()

    -
      -
    • @trans.phoneAndTablet()
    • -
    • @trans.bulletBlitzClassical()
    • -
    • @trans.correspondenceChess()
    • -
    • @trans.onlineAndOfflinePlay()
    • -
    • @trans.tournaments()
    • -
    • @trans.puzzles()
    • -
    • @trans.gameAnalysis()
    • -
    • @trans.boardEditor()
    • -
    • Lichess TV
    • -
    • @trans.followAndChallengeFriends()
    • -
    • @trans.availableInNbLanguages.pluralSame(80)
    • -
    - -
    -
    -}.toHtml diff --git a/app/views/mod/chatPanic.scala b/app/views/mod/chatPanic.scala new file mode 100644 index 0000000000..faf6efbf66 --- /dev/null +++ b/app/views/mod/chatPanic.scala @@ -0,0 +1,51 @@ +package views.html.mod + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object chatPanic { + + def apply(state: Option[org.joda.time.DateTime])(implicit ctx: Context) = { + val title = "Chat Panic" + views.html.base.layout( + title = title, + moreCss = cssTag("mod.misc") + ) { + main(cls := "page-menu")( + views.html.mod.menu("panic"), + div(id := "chat-panic", cls := "page-menu__content box box-pad")( + h1(title), + p( + "When Chat Panic is enabled, restrictions apply to public chats (tournament, simul) and PM", br, + "Only players 24h old, and with 10 games played, can write messages." + ), + p( + "Current state: ", + state.map { s => + frag( + goodTag(cls := "text", dataIcon := "E")(strong("ENABLED")), + ". Expires in ", momentFromNow(s) + ) + } getOrElse badTag(cls := "text", dataIcon := "L")(strong("DISABLED")) + ), + div(cls := "forms")( + if (state.isDefined) frag( + st.form(action := s"${routes.Mod.chatPanicPost}?v=0", method := "POST")( + button(tpe := "submit", cls := "button button-fat button-red text", dataIcon := "L")("Disable") + ), + st.form(action := s"${routes.Mod.chatPanicPost}?v=1", method := "POST")( + button(tpe := "submit", cls := "button button-fat button-green text", dataIcon := "E")("Renew for two hours") + ) + ) + else form(action := s"${routes.Mod.chatPanicPost}?v=1", method := "POST")( + button(tpe := "submit", cls := "button button-fat text", dataIcon := "E")("Enable") + ) + ) + ) + ) + } + } +} diff --git a/app/views/mod/chatPanic.scala.html b/app/views/mod/chatPanic.scala.html deleted file mode 100644 index 9072ba35f2..0000000000 --- a/app/views/mod/chatPanic.scala.html +++ /dev/null @@ -1,57 +0,0 @@ -@(state: Option[org.joda.time.DateTime])(implicit ctx: Context) - -@title = @{ "Chat Panic" } - -@mod.layout(title = title, active = "panic") { - - - -
    -

    @title

    -

    -

    - When Chat Panic is enabled, restrictions apply to public chats (tournament, simul) and PMs
    - Only players 24h old, and with 10 games played, can write messages. -

    -

    -

    - Current state: - @state.map { s => - ENABLED. Expires in @momentFromNow(s) - }.getOrElse { - DISABLED - } -

    -
    - @if(state.isDefined) { -
    - -
    -
    - -
    - } else { -
    - -
    - } -
    -
    -} diff --git a/app/views/mod/communication.scala b/app/views/mod/communication.scala new file mode 100644 index 0000000000..f050493a6b --- /dev/null +++ b/app/views/mod/communication.scala @@ -0,0 +1,164 @@ +package views.html.mod + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.String.html.richText +import lila.hub.actorApi.shutup.PublicSource + +import controllers.routes + +object communication { + + def apply( + u: lila.user.User, + players: List[(lila.game.Pov, lila.chat.MixedChat)], + threads: List[lila.message.Thread], + publicLines: List[lila.shutup.PublicLine], + spy: lila.security.UserSpy, + notes: List[lila.user.Note], + history: List[lila.mod.Modlog], + priv: Boolean + )(implicit ctx: Context) = + views.html.base.layout( + title = u.username + " communications", + moreCss = cssTag("mod.communication") + ) { + main(id := "communication", cls := "box box-pad")( + h1( + div(cls := "title")(userLink(u), " communications"), + div(cls := "actions")( + isGranted(_.ViewPrivateComms) option { + if (priv) a(cls := "priv button active", href := routes.Mod.communicationPublic(u.username))("PMs") + else a( + cls := "priv button", + href := routes.Mod.communicationPrivate(u.username), + title := "View private messages. This will be logged in #commlog" + )("PMs") + } + ) + ), + + history.nonEmpty option frag( + h2("Moderation history"), + div(cls := "history")( + history.map { e => + div(userIdLink(e.mod.some), " ", b(e.showAction), " ", u.username, " ", e.details, " ", momentFromNowOnce(e.date)) + } + ) + ), + + notes.nonEmpty option frag( + h2("Notes from other users"), + div(cls := "notes")( + notes.map { note => + div(userIdLink(note.from.some), " ", momentFromNowOnce(note.date), ": ", richText(note.text)) + } + ) + ), + + h2("Dubious public chats"), + if (publicLines.isEmpty) strong("None!") + else ul(cls := "public_chats")( + publicLines.reverse.map { line => + li( + line.date.map(momentFromNowOnce(_)).getOrElse("[OLD]"), + line.from.map { + case PublicSource.Tournament(id) => tournamentLink(id) + case PublicSource.Simul(id) => views.html.simul.bits.link(id) + case PublicSource.Watcher(id) => a(href := routes.Round.watcher(id, "white"))("Game #", id) + case PublicSource.Study(id) => a(href := routes.Study.show(id))("Study #", id) + }, + line.text + ) + } + ), + + priv option frag( + h2("Recent private chats"), + div(cls := "player_chats")( + players.map { + case (pov, chat) => div(cls := "game")( + a( + href := routes.Round.player(pov.fullId), + cls := List( + "title" -> true, + "friend_title" -> pov.game.fromFriend + ), + title := pov.game.fromFriend.option("Friend game") + )( + usernameOrAnon(pov.opponent.userId), " – ", momentFromNowOnce(pov.game.movedAt) + ), + div(cls := "chat")( + chat.lines.map { line => + div(cls := List( + "line" -> true, + "author" -> (line.author.toLowerCase == u.id) + ))( + userIdLink(line.author.toLowerCase.some, withOnline = false, withTitle = false), + richText(line.text) + ) + } + ) + ) + } + ), + + div(cls := "threads")( + h2("Recent inbox messages"), + threads.map { thread => + div(cls := "thread")( + p(cls := "title")( + strong(thread.name), + momentFromNowOnce(thread.createdAt), + userIdLink(thread.creatorId.some), " -> ", userIdLink(thread.invitedId.some) + ), + thread.posts.map { post => + div(cls := List("post" -> true, "author" -> thread.isWrittenBy(post, u)))( + userIdLink(thread.senderOf(post).some), + richText(post.text) + ) + } + ) + } + ) + ), + div(cls := "alternate_accounts")( + h2("Alternate accounts"), + table(cls := "others slist")( + thead( + tr( + th(spy.otherUsers.size, " similar user(s)"), + th("Same"), + th("Games"), + th("Marks"), + th("IPban"), + th("Closed"), + th("Created") + ) + ), + tbody( + spy.withMeSorted(u).map { + case lila.security.UserSpy.OtherUser(o, byIp, byFp) => tr(cls := (o == u).option("same"))( + td(userLink(o, withBestRating = true, params = "?mod")), + td( + if (o == u) " - " + else List(byIp option "IP", byFp option "Print").flatten.mkString(", ") + ), + td(o.count.game.localize), + td( + o.engine option "ENGINE", + o.booster option "BOOSTER", + o.troll option "SHADOWBAN" + ), + td(o.ipBan option "IPBAN"), + td(o.disabled option "CLOSED"), + td(momentFromNowOnce(o.createdAt)) + ) + } + ) + ) + ) + ) + } +} diff --git a/app/views/mod/communication.scala.html b/app/views/mod/communication.scala.html deleted file mode 100644 index 9043e9bc41..0000000000 --- a/app/views/mod/communication.scala.html +++ /dev/null @@ -1,165 +0,0 @@ -@(u: User, players: List[(Pov, lila.chat.MixedChat)], threads: List[lila.message.Thread], publicLines: List[lila.shutup.PublicLine], spy: lila.security.UserSpy, notes: List[lila.user.Note], history: List[lila.mod.Modlog], priv: Boolean)(implicit ctx: Context) - -@import lila.hub.actorApi.shutup.PublicSource - -@moreCss = { -@cssTag("mod-communication.css") -} - -@side = { -
    -
    -Return to the report list -} - -@base.layout( -title = u.username + " communications", -moreCss = moreCss, -side = side.some) { - -
    -

    -
    - @userLink(u) communications -
    -
    - @if(isGranted(_.ViewPrivateComms)) { - @if(priv) { - PMs - } else { - PMs - } - } -
    -

    - - @if(history.nonEmpty) { -

    Moderation history

    -
    - @history.map { e => -
    - @userIdLink(e.mod.some) @e.showAction @u.username @e.details @momentFromNowOnce(e.date) -
    - } -
    - } - - @if(notes.nonEmpty) { -

    Notes from other users

    -
    - @notes.map { note => -
    - @userIdLink(note.from.some) @momentFromNowOnce(note.date): @richText(note.text) -
    - } -
    - } - -

    Dubious public chats

    - @if(publicLines.isEmpty) { - None! - } else { -
      - @publicLines.reverse.map { line => -
    • - @line.date.map(momentFromNowOnce(_)).getOrElse("[OLD]") - @line.from.map { - case PublicSource.Tournament(id) => { @tournamentLink(id) } - case PublicSource.Simul(id) => { @simulLink(id) } - case PublicSource.Watcher(id) => { Game #@id } - case PublicSource.Study(id) => { Study #@id } - } - @line.text -
    • - } -
    - } - - @if(priv) { -

    Recent private chats

    -
    - @players.map { - case (pov, chat) => { -
    - - @usernameOrAnon(pov.opponent.userId) – @momentFromNowOnce(pov.game.movedAt) - -
    - @chat.lines.map { line => -
    - @userIdLink(line.author.toLowerCase.some, withOnline = false, withTitle = false) - @richText(line.text) -
    - } -
    -
    - } - } -
    - -
    -

    Recent inbox messages

    - @threads.map { thread => -
    -

    - @thread.name - @momentFromNowOnce(thread.createdAt) - @userIdLink(thread.creatorId.some) -> @userIdLink(thread.invitedId.some) -

    - @thread.posts.map { post => -
    - @userIdLink(thread.senderOf(post).some) - @richText(post.text) -
    - } -
    - } -
    - } -
    -

    Alternate accounts

    - - - - - - - - - - - - - - @spy.withMeSorted(u).map { - case lila.security.UserSpy.OtherUser(o, byIp, byFp) => { - - - - - - - - - - } - } - -
    @spy.otherUsers.size similar user(s)SameGamesMarksIPbanClosedCreated
    @userLink(o, withBestRating = true, params = "?mod") - @if(o == u) { - } else { - @List(byIp option "IP", byFp option "Print").flatten.mkString(", ") - } - @o.count.game.localize - @if(o.engine){ENGINE} - @if(o.booster){BOOSTER} - @if(o.troll){SHADOWBAN} - @if(o.ipBan){IPBAN}@if(o.disabled){CLOSED}@momentFromNowOnce(o.createdAt)
    -
    -
    -}.toHtml diff --git a/app/views/mod/emailConfirm.scala b/app/views/mod/emailConfirm.scala new file mode 100644 index 0000000000..ac40442988 --- /dev/null +++ b/app/views/mod/emailConfirm.scala @@ -0,0 +1,71 @@ +package views.html.mod + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object emailConfirm { + + def apply(query: String, user: Option[lila.user.User], email: Option[lila.common.EmailAddress])(implicit ctx: Context) = + views.html.base.layout( + title = "Email confirmation", + moreCss = cssTag("mod.misc"), + moreJs = embedJsUnsafe("""$('.mod-confirm form input').on('paste', function() { +setTimeout(function() { $(this).parent().submit(); }.bind(this), 50); +}).each(function() { +this.setSelectionRange(this.value.length, this.value.length); +});""") + ) { + main(cls := "page-menu")( + views.html.mod.menu("email"), + div(cls := "mod-confirm page-menu__content box box-pad")( + h1("Confirm a user email"), + p( + "If you provide an email, it will confirm the corresponding account, if any.", br, + "If you provide an email and a username, it will set the email to that user, ", + "but only if the user has not yet confirmed their email." + ), + st.form(cls := "search", action := routes.Mod.emailConfirm, method := "GET")( + input(name := "q", placeholder := " ", value := query, autofocus) + ), + user.map { u => + table(cls := "slist")( + thead( + tr( + th("User"), + th("Email"), + th("Games"), + th("Marks"), + th("Created"), + th("Active"), + th("Confirmed") + ) + ), + tbody( + tr( + td(userLink(u, withBestRating = true, params = "?mod")), + td(email.fold("-")(_.value)), + td(u.count.game.localize), + td( + u.engine option "ENGINE", + u.booster option "BOOSTER", + u.troll option "SHADOWBAN", + u.ipBan option "IPBAN", + u.disabled option "CLOSED" + ), + td(momentFromNow(u.createdAt)), + td(u.seenAt.map(momentFromNow(_))), + td(style := "font-size:2em")( + if (!u.everLoggedIn) iconTag("E")(cls := "is-green") + else iconTag("L")(cls := "is-red") + ) + ) + ) + ) + } + ) + ) + } +} diff --git a/app/views/mod/emailConfirm.scala.html b/app/views/mod/emailConfirm.scala.html deleted file mode 100644 index 878daf05a1..0000000000 --- a/app/views/mod/emailConfirm.scala.html +++ /dev/null @@ -1,84 +0,0 @@ -@(query: String, user: Option[User], email: Option[lila.common.EmailAddress])(implicit ctx: Context) - -@title = @{ "Email confirmation" } - -@js = { -@embedJs { -$('#mod-confirm form input').on('paste', function() { -setTimeout(function() { $(this).parent().submit(); }.bind(this), 50); -}).focus().each(function() { -this.setSelectionRange(this.value.length, this.value.length); -}); -} -} - -@layout( -title = title, -active = "email", -moreJs = js) { - - - -
    -

    @title

    -
    -
    -

    - If you provide an email, it will confirm the corresponding account, if any.
    - If you provide an email and a username, it will set the email to that user, - but only if the user has not yet confirmed their email. -

    - - @user.map { u => - - - - - - - - - - - - - - - - - - - - - - -
    UserEmailGamesMarksCreatedActiveConfirmed
    @userLink(u, withBestRating = true, params = "?mod")@email.getOrElse("-")@u.count.game.localize - @if(u.engine){ENGINE} - @if(u.booster){BOOSTER} - @if(u.troll){SHADOWBAN} - @if(u.ipBan){IPBAN} - @if(u.disabled){CLOSED} - @momentFromNow(u.createdAt)@u.seenAt.map(momentFromNow(_)) - @if(!u.everLoggedIn) { - - } else { - - } -
    - } -
    -} diff --git a/app/views/mod/gamify.scala b/app/views/mod/gamify.scala new file mode 100644 index 0000000000..2b6dc4d3b5 --- /dev/null +++ b/app/views/mod/gamify.scala @@ -0,0 +1,127 @@ +package views.html.mod + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.mod.Gamify.Period + +import controllers.routes + +object gamify { + + def index(leaderboards: lila.mod.Gamify.Leaderboards, history: List[lila.mod.Gamify.HistoryMonth])(implicit ctx: Context) = { + val title = "Moderator hall of fame" + def yearHeader(year: Int) = tr(cls := "year")( + th(year), + th("Champions of the past"), + th("Score"), + th("Actions taken"), + th("Reports closed") + ) + + views.html.base.layout( + title = title, + moreCss = cssTag("mod.gamify") + ) { + main(cls := "page-menu")( + views.html.mod.menu("gamify"), + div(id := "mod-gamify", cls := "page-menu__content index box")( + h1(title), + div(cls := "champs")( + champion(leaderboards.daily.headOption, "reward1", Period.Day), + champion(leaderboards.weekly.headOption, "reward2", Period.Week), + champion(leaderboards.monthly.headOption, "reward3", Period.Month) + ), + table(cls := "slist slist-pad history")( + tbody( + history.headOption.filterNot(_.date.getMonthOfYear == 12).map { h => + yearHeader(h.date.getYear) + }, + history.map { h => + frag( + h.date.getMonthOfYear == 12 option yearHeader(h.date.getYear), + tr( + th(h.date.monthOfYear.getAsText), + th(userIdLink(h.champion.modId.some, withOnline = false)), + td(cls := "score")(h.champion.score.localize), + td(h.champion.action.localize), + td(h.champion.report.localize) + ) + ) + } + ) + ) + ) + ) + } + } + + def period(leaderboards: lila.mod.Gamify.Leaderboards, period: lila.mod.Gamify.Period)(implicit ctx: Context) = { + val title = s"Moderators of the ${period.name}" + views.html.base.layout( + title = title, + moreCss = cssTag("mod.gamify") + ) { + main(cls := "page-menu")( + views.html.mod.menu("gamify"), + div(id := "mod-gamify", cls := "page-menu__content box")( + h1( + a(href := routes.Mod.gamify, dataIcon := "I"), + title + ), + div(cls := "period")( + table(cls := "slist")( + thead( + tr( + th(colspan := "2"), + th("Actions"), + th("Reports"), + th("Score") + ) + ), + tbody( + leaderboards(period).zipWithIndex.map { + case (m, i) => tr( + th(i + 1), + th(userIdLink(m.modId.some, withOnline = false)), + td(m.action.localize), + td(m.report.localize), + td(cls := "score")(m.score.localize) + ) + } + ) + ) + ) + ) + ) + } + } + + def champion(champ: Option[lila.mod.Gamify.ModMixed], img: String, period: lila.mod.Gamify.Period)(implicit ctx: Context) = + div(cls := "champ")( + st.img(src := staticUrl(s"images/mod/$img.png")), + h2("Mod of the ", period.name), + champ.map { m => + frag( + userIdLink(m.modId.some, withOnline = false), + table( + tbody( + tr( + th("Total score"), + td(m.score) + ), + tr( + th("Actions taken"), + td(m.action) + ), + tr( + th("Reports closed"), + td(m.report) + ) + ) + ) + ) + } getOrElse "Nobody!", + a(cls := "button button-empty", href := routes.Mod.gamifyPeriod(period.name))("View ", period.name, " leaderboard") + ) +} diff --git a/app/views/mod/gamify/champion.scala.html b/app/views/mod/gamify/champion.scala.html deleted file mode 100644 index 2b7693e76b..0000000000 --- a/app/views/mod/gamify/champion.scala.html +++ /dev/null @@ -1,26 +0,0 @@ -@(champ: Option[lila.mod.Gamify.ModMixed], img: String, period: lila.mod.Gamify.Period)(implicit ctx: Context) - -
    - -

    Mod of the @period.name

    - @champ.map { m => -

    @userIdLink(m.modId.some, withOnline = false)

    - - - - - - - - - - - - - - - -
    Total score@m.score
    Actions taken@m.action
    Reports closed@m.report
    - }.getOrElse { Nobody! } - View @period.name leaderboard -
    diff --git a/app/views/mod/gamify/index.scala.html b/app/views/mod/gamify/index.scala.html deleted file mode 100644 index fb14d6d62f..0000000000 --- a/app/views/mod/gamify/index.scala.html +++ /dev/null @@ -1,57 +0,0 @@ -@(leaderboards: lila.mod.Gamify.Leaderboards, history: List[lila.mod.Gamify.HistoryMonth])(implicit ctx: Context) - -@import lila.mod.Gamify.Period - -@title = @{ "Moderator hall of fame" } - -@yearHeader(year: Int) = @{ -Html(s""" - $year - Champions of the past - Score - Actions taken - Reports closed -""") -} - -@mod.layout( -title = title, -active = "gamify", -moreCss = cssTag("mod-gamify.css")) { - -
    -

    @title

    -
    -
    - @champion(leaderboards.daily.headOption, "reward1", Period.Day) -
    -
    - @champion(leaderboards.weekly.headOption, "reward2", Period.Week) -
    -
    - @champion(leaderboards.monthly.headOption, "reward3", Period.Month) -
    -
    -
    - - - @history.headOption.filterNot(_.date.getMonthOfYear == 12).map { h => - @yearHeader(h.date.getYear) - } - @history.map { h => - @if(h.date.getMonthOfYear == 12) { - @yearHeader(h.date.getYear) - } - - - - - - - - } - -
    @h.date.monthOfYear.getAsText@userIdLink(h.champion.modId.some, withOnline = false)@h.champion.score.localize@h.champion.action.localize@h.champion.report.localize
    -
    -
    -} diff --git a/app/views/mod/gamify/period.scala.html b/app/views/mod/gamify/period.scala.html deleted file mode 100644 index 211f16bdc8..0000000000 --- a/app/views/mod/gamify/period.scala.html +++ /dev/null @@ -1,40 +0,0 @@ -@(leaderboards: lila.mod.Gamify.Leaderboards, period: lila.mod.Gamify.Period)(implicit ctx: Context) - -@title = @{ s"Moderators of the ${period.name}" } - -@mod.layout( -title = title, -active = "gamify", -moreCss = cssTag("mod-gamify.css")) { - -
    -

    - @title -

    -
    - - - - - - - - - - - @leaderboards(period).zipWithIndex.map { - case (m, i) => { - - - - - - - - } - } - -
    ActionsReportsScore
    @(i + 1)@userIdLink(m.modId.some, withOnline = false)@m.action.localize@m.report.localize@m.score.localize
    -
    -
    -} diff --git a/app/views/mod/impersonate.scala b/app/views/mod/impersonate.scala new file mode 100644 index 0000000000..4435b27da7 --- /dev/null +++ b/app/views/mod/impersonate.scala @@ -0,0 +1,23 @@ +package views.html.mod + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object impersonate { + + def apply(user: lila.user.User)(implicit ctx: Context) = + div(id := "impersonate")( + div(cls := "meat")( + "You are impersonating ", + userLink(user, withOnline = false) + ), + div(cls := "actions")( + form(method := "post", action := routes.Mod.impersonate("-"))( + input(cls := "button button-empty", tpe := "submit", value := "Quit") + ) + ) + ) +} diff --git a/app/views/mod/impersonate.scala.html b/app/views/mod/impersonate.scala.html deleted file mode 100644 index 8784ebc02a..0000000000 --- a/app/views/mod/impersonate.scala.html +++ /dev/null @@ -1,12 +0,0 @@ -@(user: lila.user.User)(implicit ctx: Context) - -
    -
    - You are impersonating @Html(userLink(user, withOnline = false).body.replace(" -
    -
    - -
    -
    -
    diff --git a/app/views/mod/inquiry.scala b/app/views/mod/inquiry.scala new file mode 100644 index 0000000000..e169894b9b --- /dev/null +++ b/app/views/mod/inquiry.scala @@ -0,0 +1,168 @@ +package views.html.mod + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.String.html.richText + +import controllers.routes + +object inquiry { + + def apply(in: lila.mod.Inquiry)(implicit ctx: Context) = { + + def renderReport(r: lila.report.Report) = + div(cls := "doc report")( + r.bestAtoms(10).toList.map { atom => + div(cls := "atom")( + h3( + reportScore(atom.score), + userIdLink(atom.by.value.some, withOnline = false), + " for ", strong(r.reason.name), + " ", momentFromNow(atom.at) + ), + p(richText(atom.simplifiedText)) + ) + } + ) + + def renderNote(r: lila.user.Note) = + div(cls := "doc note")( + h3("by ", userIdLink(r.from.some, withOnline = false), ", ", momentFromNow(r.date)), + p(richText(r.text)) + ) + + def autoNextInput = + input(cls := "auto-next", tpe := "hidden", name := "next", value := "1") + + div(id := "inquiry")( + i(title := "Costello the Inquiry Octopus", cls := "costello"), + div(cls := "meat")( + userLink(in.user, withBestRating = true, params = "?mod"), + div(cls := "docs reports")( + div(cls := "expendable")( + in.allReports.map(renderReport) + ) + ), + div(cls := List( + "dropper counter history" -> true, + "empty" -> in.history.isEmpty + ))( + span( + countTag(in.history.size), + "Mod log" + ), + in.history.nonEmpty option div( + ul( + in.history.map { e => + li( + userIdLink(e.mod.some, withOnline = false), + " ", b(e.showAction), " ", e.details, " ", momentFromNow(e.date) + ) + } + ) + ) + ), + div(cls := List( + "dropper counter notes" -> true, + "empty" -> in.notes.isEmpty + ))( + span( + countTag(in.notes.size), + "Notes" + ), + div( + form(cls := "note", action := s"${routes.User.writeNote(in.user.username)}?note", method := "post")( + textarea(name := "text", placeholder := "Write a mod note"), + input(tpe := "hidden", name := "mod", value := "true"), + div(cls := "submission")( + button(tpe := "submit", cls := "button thin")("SEND") + ) + ), + in.notes.map(renderNote) + ) + ) + ), + div(cls := "links")( + in.report.boostWith.map { userId => + a(href := s"${routes.User.games(in.user.id, "search")}?players.b=${userId}")("View", br, "Games") + }.getOrElse { + in.report.bestAtomByHuman.map { atom => + a(href := s"${routes.User.games(in.user.id, "search")}?players.b=$atom.by.valueuserId}")("View", br, "Games") + } + }, + isGranted(_.Shadowban) option + a(href := routes.Mod.communicationPublic(in.user.id))("View", br, "Comms") + ), + div(cls := "actions")( + div(cls := "dropper warn")( + span(cls := "icon", dataIcon := "e"), + div( + lila.message.ModPreset.all.map { preset => + form(method := "post", action := routes.Mod.warn(in.user.username, preset.subject))( + button(cls := "fbt", tpe := "submit")(preset.subject), + autoNextInput + ) + }, + form(method := "get", action := routes.Message.form)( + input(tpe := "hidden", name := "mod", value := "1"), + input(tpe := "hidden", name := "user", value := "@in.user.id"), + button(cls := "fbt", tpe := "submit")("Custom message") + ) + ) + ), + isGranted(_.MarkEngine) option + form(method := "post", action := routes.Mod.engine(in.user.username, !in.user.engine), title := "Mark as cheat")( + button(dataIcon := "n", cls := List( + "fbt icon" -> true, + "active" -> in.user.engine + ), tpe := "submit"), + autoNextInput + ), + isGranted(_.MarkBooster) option + form(method := "post", action := routes.Mod.booster(in.user.username, !in.user.booster), title := "Mark as booster or sandbagger")( + button(dataIcon := "9", cls := List( + "fbt icon" -> true, + "active" -> in.user.booster + ), tpe := "submit"), + autoNextInput + ), + isGranted(_.Shadowban) option + form(method := "post", action := routes.Mod.troll(in.user.username, !in.user.booster), + title := (if (in.user.troll) "Un-shadowban" else "Shadowban"), + button(dataIcon := "c", cls := List( + "fbt icon" -> true, + "active" -> in.user.troll + ), tpe := "submit"), + autoNextInput), + div(cls := "dropper more")( + span(cls := "icon", dataIcon := "u"), + div( + form(method := "post", action := routes.Mod.notifySlack(in.user.id))( + button(cls := "fbt", tpe := "submit")("Notify Slack") + ), + form(method := "post", action := routes.Report.xfiles(in.report.id))( + button(cls := List("fbt" -> true, "active" -> (in.report.room.key == "xfiles")), tpe := "submit")("Move to X-Files"), + autoNextInput + ) + ) + ) + ), + div(cls := "actions close")( + span(cls := "switcher", title := "Automatically open next report")( + span(cls := "switch")( + input(id := "auto-next", cls := "cmn-toggle", tpe := "checkbox", checked), + label(`for` := "auto-next") + ) + ), + form(action := routes.Report.process(in.report.id), method := "post", title := "Dismiss this report as processed.", cls := "process")( + button(tpe := "submit", dataIcon := "E", cls := "fbt"), + autoNextInput + ), + form(action := routes.Report.inquiry(in.report.id), method := "post", title := "Cancel the inquiry, re-instore the report", cls := "cancel")( + button(tpe := "submit", dataIcon := "L", cls := "fbt") + ) + ) + ) + } +} diff --git a/app/views/mod/inquiry.scala.html b/app/views/mod/inquiry.scala.html deleted file mode 100644 index 9b9312db2a..0000000000 --- a/app/views/mod/inquiry.scala.html +++ /dev/null @@ -1,150 +0,0 @@ -@(in: lila.mod.Inquiry)(implicit ctx: Context) - -@renderReport(r: lila.report.Report) = { -
    - @r.bestAtoms(10).toList.map { atom => -
    -

    - @reportScore(atom.score) - @userIdLink(atom.by.value.some, withOnline = false) - for @r.reason.name, - @momentFromNow(atom.at) -

    -

    @richText(atom.simplifiedText)

    -
    - } -
    -} - -@renderNote(r: lila.user.Note) = { -
    -

    by @userIdLink(r.from.some, withOnline = false), @momentFromNow(r.date)

    -

    @richText(r.text)

    -
    -} - -@autoNextInput = { - -} - -
    - -
    -

    - @repositionTooltipUnsafe(userLink(in.user, withBestRating = true, params = "?mod"), "se") -

    -
    -
    - @in.allReports.map(renderReport) -
    -
    -
    - - @in.history.size - Mod log - - @if(in.history.nonEmpty) { -
    -
      - @in.history.map { e => -
    • @userIdLink(e.mod.some, withOnline = false) @e.showAction @e.details @momentFromNow(e.date)
    • - } -
    -
    - } -
    -
    - - @in.notes.size - Notes - -
    -
    - - -
    - -
    -
    - @in.notes.map(renderNote) -
    -
    -
    -
    -
    -
    - -
    - @lila.message.ModPreset.all.map { preset => -
    - - @autoNextInput -
    - } -
    - - - -
    -
    -
    - @if(isGranted(_.MarkEngine)) { -
    - - @autoNextInput -
    - } - @if(isGranted(_.MarkBooster)) { -
    - - @autoNextInput -
    - } - @if(isGranted(_.Shadowban)) { -
    - - @autoNextInput -
    - } -
    - -
    -
    - -
    -
    - - @autoNextInput -
    -
    -
    -
    -
    - @defining("auto-next") { id => - - - - - - - } -
    - - @autoNextInput -
    -
    - -
    -
    -
    diff --git a/app/views/mod/layout.scala.html b/app/views/mod/layout.scala.html deleted file mode 100644 index f2c3b0fbac..0000000000 --- a/app/views/mod/layout.scala.html +++ /dev/null @@ -1,13 +0,0 @@ -@(title: String, active: String, moreCss: Html = emptyHtml, moreJs: Html = emptyHtml)(body: Html)(implicit ctx: Context) - -@modMenu = { - @mod.menu(active) -} - -@base.layout( -title = title, -moreJs = moreJs, -moreCss = moreCss, -menu = modMenu.some) { -@body -}.toHtml diff --git a/app/views/mod/log.scala b/app/views/mod/log.scala new file mode 100644 index 0000000000..b1aa126e08 --- /dev/null +++ b/app/views/mod/log.scala @@ -0,0 +1,50 @@ +package views.html.mod + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object log { + + def apply(logs: List[lila.mod.Modlog])(implicit ctx: Context) = { + + val title = "Mod logs" + + views.html.base.layout( + title = title, + moreCss = cssTag("mod.misc") + ) { + main(cls := "page-menu")( + views.html.mod.menu("log"), + div(id := "modlog_table", cls := "page-menu__content box")( + h1(title), + table(cls := "slist slist-pad")( + thead( + tr( + th("Mod"), + th("Action"), + th("Details") + ) + ), + tbody( + logs.map { log => + tr( + td(userIdLink(log.mod.some), br, momentFromNow(log.date)), + td( + log.showAction.capitalize, " ", + log.user.map { u => + userIdLink(u.some, params = "?mod") + } + ), + td(log.details) + ) + } + ) + ) + ) + ) + } + } +} diff --git a/app/views/mod/log.scala.html b/app/views/mod/log.scala.html deleted file mode 100644 index 6020107dbc..0000000000 --- a/app/views/mod/log.scala.html +++ /dev/null @@ -1,37 +0,0 @@ -@(logs: List[lila.mod.Modlog])(implicit ctx: Context) - -@title = @{ "Mod logs" } - -@layout( -title = title, -active = "log") { - - -
    -

    @title

    - - - - - - - - - - @logs.map { log => - - - - - - } -
    ModActionDetails
    @userIdLink(log.mod.some)
    @momentFromNow(log.date)
    @log.showAction.capitalize @log.user.map { u => - @userIdLink(u.some, params="?mod") - }@log.details
    -
    -} diff --git a/app/views/mod/menu.scala b/app/views/mod/menu.scala new file mode 100644 index 0000000000..dfa289c864 --- /dev/null +++ b/app/views/mod/menu.scala @@ -0,0 +1,42 @@ +package views.html.mod + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object menu { + + def apply(active: String)(implicit ctx: Context) = st.nav(cls := "page-menu__menu subnav")( + isGranted(_.SeeReport) option + a(cls := active.active("report"), href := routes.Report.list)("Reports"), + isGranted(_.ChatTimeout) option + a(cls := active.active("public-chat"), href := routes.Mod.publicChat)("Public Chats"), + isGranted(_.SeeReport) option + a(cls := active.active("gamify"), href := routes.Mod.gamify)("Hall of fame"), + isGranted(_.UserSearch) option + a(cls := active.active("search"), href := routes.Mod.search)("Search users"), + isGranted(_.SetEmail) option + a(cls := active.active("email"), href := routes.Mod.emailConfirm)("Email confirm"), + isGranted(_.PracticeConfig) option + a(cls := active.active("practice"), href := routes.Practice.config)("Practice"), + isGranted(_.ManageTournament) option + a(cls := active.active("tour"), href := routes.TournamentCrud.index(1))("Tournaments"), + isGranted(_.ManageEvent) option + a(cls := active.active("event"), href := routes.Event.manager)("Events"), + isGranted(_.SeeReport) option + a(cls := active.active("log"), href := routes.Mod.log)("Mod log"), + isGranted(_.SeeReport) option + a(cls := active.active("irwin"), href := routes.Irwin.dashboard)("Irwin dashboard"), + isGranted(_.Shadowban) option + a(cls := active.active("panic"), href := routes.Mod.chatPanic)( + "Chat Panic: ", + strong(if (isChatPanicEnabled) "ON" else "OFF") + ), + isGranted(_.Settings) option + a(cls := active.active("setting"), href := routes.Dev.settings)("Settings"), + isGranted(_.Cli) option + a(cls := active.active("cli"), href := routes.Dev.cli)("CLI") + ) +} diff --git a/app/views/mod/menu.scala.html b/app/views/mod/menu.scala.html deleted file mode 100644 index 688e973067..0000000000 --- a/app/views/mod/menu.scala.html +++ /dev/null @@ -1,43 +0,0 @@ -@(active: String)(implicit ctx: Context) - -@if(isGranted(_.SeeReport)) { -Reports -} -@if(isGranted(_.ChatTimeout)) { -Public Chats -} -@if(isGranted(_.SeeReport)) { -Hall of fame -} -@if(isGranted(_.UserSearch)) { -Search users -} -@if(isGranted(_.SetEmail)) { -Email confirm -} -@if(isGranted(_.PracticeConfig)) { -Practice -} -@if(isGranted(_.ManageTournament)) { -Tournaments -} -@if(isGranted(_.ManageEvent)) { -Events -} -@if(isGranted(_.SeeReport)) { -Mod log -} -@if(isGranted(_.SeeReport)) { -Irwin dashboard -} -@if(isGranted(_.Shadowban)) { - - Chat Panic @if(isChatPanicEnabled){ON}else{OFF} - -} -@if(isGranted(_.Settings)) { -Settings -} -@if(isGranted(_.Cli)) { -CLI -} diff --git a/app/views/mod/permissions.scala b/app/views/mod/permissions.scala new file mode 100644 index 0000000000..72d043ac3e --- /dev/null +++ b/app/views/mod/permissions.scala @@ -0,0 +1,45 @@ +package views.html.mod + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object permissions { + + def apply(u: lila.user.User)(implicit ctx: Context) = + views.html.base.layout( + title = s"${u.username} permissions", + moreCss = frag( + cssTag("mod.communication"), + cssTag("form3") + ), + moreJs = embedJsUnsafe("""$(function() { +$('button.clear').on('click', function() { + $('#permissions option:selected').prop('selected', false); +});});""") + ) { + main(id := "permissions", cls := "page-small box box-pad")( + h1(userLink(u), " permissions"), + p("Use Ctrl+click to select multiple permissions"), + form(cls := "form3", action := routes.Mod.permissions(u.username), method := "post")( + select(name := "permissions[]", multiple)( + lila.security.Permission.allButSuperAdmin.sortBy(_.name).flatMap { p => + ctx.me.exists(canGrant(_, p)) option option( + value := p.name, + u.roles.contains(p.name) option selected, + title := p.children.mkString(", ") + )(p.toString) + } + ), + form3.actions( + button(cls := "button button-red clear", tpe := "button")("Clear"), + button(cls := "button", tpe := "submit")("Save") + ) + ) + ) + } +} diff --git a/app/views/mod/permissions.scala.html b/app/views/mod/permissions.scala.html deleted file mode 100644 index 7e41acb3a5..0000000000 --- a/app/views/mod/permissions.scala.html +++ /dev/null @@ -1,39 +0,0 @@ -@(u: User)(implicit ctx: Context) - -@moreCss = { -@cssTag("mod-communication.css") -} - -@moreJs = { -@embedJs { -$(function() { - $('button.clear').on('click', function() { - $('#permissions option:selected').prop('selected', false); - }); -}); -} -} - -@base.layout( -title = u.username + " permissions", -moreCss = moreCss, -moreJs = moreJs) { - -
    -

    @userLink(u) permissions

    -
    - -
    - - -
    -
    -
    -}.toHtml diff --git a/app/views/mod/publicChat.scala b/app/views/mod/publicChat.scala new file mode 100644 index 0000000000..e8c683f1d3 --- /dev/null +++ b/app/views/mod/publicChat.scala @@ -0,0 +1,61 @@ +package views.html.mod + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.String.html.richText + +import controllers.routes + +object publicChat { + + def apply( + tourChats: List[(lila.tournament.Tournament, lila.chat.UserChat)], + simulChats: List[(lila.simul.Simul, lila.chat.UserChat)] + )(implicit ctx: Context) = + views.html.base.layout( + title = "Public Chats", + moreCss = cssTag("mod.communication"), + moreJs = jsTag("public-chat.js") + ) { + main(cls := "page-menu")( + views.html.mod.menu("public-chat"), + div(id := "communication", cls := "page-menu__content public_chat box box-pad")( + h2("Tournament Chats"), + div(cls := "player_chats")( + tourChats.map { + case (tournament, chat) => div(cls := "game")( + a(cls := "title", href := routes.Tournament.show(tournament.id))(tournament.name), + div(cls := "chat")( + chat.lines.filter(_.isVisible).map { line => + div(cls := "line")( + userIdLink(line.author.toLowerCase.some, withOnline = false, withTitle = false), " ", + richText(line.text) + ) + } + ) + ) + } + ), + div( + h2("Simul Chats"), + div(cls := "player_chats")( + simulChats.map { + case (simul, chat) => div(cls := "game")( + a(cls := "title", href := routes.Simul.show(simul.id))(simul.name), + div(cls := "chat")( + chat.lines.filter(_.isVisible).map { line => + div(cls := "line")( + userIdLink(line.author.toLowerCase.some, withOnline = false, withTitle = false), " ", + richText(line.text) + ) + } + ) + ) + } + ) + ) + ) + ) + } +} diff --git a/app/views/mod/publicChat.scala.html b/app/views/mod/publicChat.scala.html deleted file mode 100644 index 70712090bf..0000000000 --- a/app/views/mod/publicChat.scala.html +++ /dev/null @@ -1,57 +0,0 @@ -@(tourChats : List[(lila.tournament.Tournament, lila.chat.UserChat)], -simulChats: List[(lila.simul.Simul, lila.chat.UserChat)])(implicit ctx: Context) - -@mod.layout( -title = "Public Chats", -active = "public-chat", -moreCss = cssTag("mod-communication.css"), -moreJs = jsTag("public-chat.js")) { - -
    -

    Tournament Chats

    -
    - @tourChats.map { - case (tournament, chat) => { -
    - - @tournament.name - -
    - @chat.lines.filter(_.isVisible).map { line => -
    - @userIdLink(line.author.toLowerCase.some, withOnline = false, withTitle = false) - @richText(line.text) -
    - } -
    -
    - } - } -
    -
    -

    Simul Chats

    -
    - - @simulChats.map { - case (simul, chat) => { -
    - - @simul.name - -
    - @chat.lines.filter(_.isVisible).map { line => -
    - @userIdLink(line.author.toLowerCase.some, withOnline = false, withTitle = false) - @richText(line.text) -
    - } -
    -
    - } - } -
    - -
    - - -} diff --git a/app/views/mod/search.scala b/app/views/mod/search.scala new file mode 100644 index 0000000000..b11741b308 --- /dev/null +++ b/app/views/mod/search.scala @@ -0,0 +1,65 @@ +package views.html.mod + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object search { + + private val email = tag("email") + private val mark = tag("marked") + + def apply(form: Form[_], users: List[lila.user.User.WithEmails])(implicit ctx: Context) = + views.html.base.layout( + title = "Search users", + moreCss = cssTag("mod.misc") + ) { + main(cls := "page-menu")( + views.html.mod.menu("search"), + div(cls := "mod-search page-menu__content box")( + h1("Search users"), + st.form(cls := "search box__pad", action := routes.Mod.search, method := "GET")( + input(name := "q", autofocus, placeholder := "Search by IP, email, or username", value := form("q").value), + form3.select(form("as"), lila.mod.UserSearch.asChoices) + ), + users.nonEmpty option table(cls := "slist slist-pad")( + thead( + tr( + th("User"), + th("Games"), + th("Marks"), + th("IPban"), + th("Closed"), + th("Created"), + th("Active") + ) + ), + tbody( + users.map { + case lila.user.User.WithEmails(u, emails) => tr( + td( + userLink(u, withBestRating = true, params = "?mod"), + email(emails.list.map(_.value).mkString(", ")) + ), + td(u.count.game.localize), + td( + u.engine option mark("ENGINE"), + u.booster option mark("BOOSTER"), + u.troll option mark("SHADOWBAN") + ), + td(u.ipBan option mark("IPBAN")), + td(u.disabled option mark("CLOSED")), + td(momentFromNow(u.createdAt)), + td(u.seenAt.map(momentFromNow(_))) + ) + } + ) + ) + ) + ) + } +} diff --git a/app/views/mod/search.scala.html b/app/views/mod/search.scala.html deleted file mode 100644 index 34103a77a8..0000000000 --- a/app/views/mod/search.scala.html +++ /dev/null @@ -1,33 +0,0 @@ -@(form: Form[_], users: List[User.WithEmails])(implicit ctx: Context) - -@title = @{ "Search users" } - -@layout( -title = title, -active = "search") { - - - - -} diff --git a/app/views/mod/userTable.scala.html b/app/views/mod/userTable.scala.html deleted file mode 100644 index 1399b4cf47..0000000000 --- a/app/views/mod/userTable.scala.html +++ /dev/null @@ -1,38 +0,0 @@ -@(users: List[User.WithEmails])(implicit ctx: Context) -@if(users.nonEmpty) { - - - - - - - - - - - - - - @users.map { - case lila.user.User.WithEmails(u, emails) => { - - - - - - - - - - - } - } -
    UserGamesMarksIPbanClosedCreatedActive
    - @userLink(u, withBestRating = true, params = "?mod") - @emails.list.mkString(", ") - @u.count.game.localize - @if(u.engine){ENGINE} - @if(u.booster){BOOSTER} - @if(u.troll){SHADOWBAN} - @if(u.ipBan){IPBAN}@if(u.disabled){CLOSED}@momentFromNow(u.createdAt)@u.seenAt.map(momentFromNow(_))
    -} diff --git a/app/views/oAuth/app/create.scala.html b/app/views/oAuth/app/create.scala.html deleted file mode 100644 index 19aab9a3b6..0000000000 --- a/app/views/oAuth/app/create.scala.html +++ /dev/null @@ -1,20 +0,0 @@ -@(form: Form[_])(implicit ctx: Context) - -@title = @{ "New OAuth App" } - -@account.layout( -title = title, -active = "oauth.app", -evenMoreCss = cssTag("form3.css") -) { -
    -

    @title

    -
    -

    -
    - Want to build something that integrates with and extends Lichess? Register a new OAuth App to get started developing on the Lichess API. -
    - @inForm(form) -
    -
    -}.toHtml diff --git a/app/views/oAuth/app/edit.scala.html b/app/views/oAuth/app/edit.scala.html deleted file mode 100644 index c94745d8f7..0000000000 --- a/app/views/oAuth/app/edit.scala.html +++ /dev/null @@ -1,28 +0,0 @@ -@(app: lila.oauth.OAuthApp, form: Form[_])(implicit ctx: Context) - -@title = @{ s"Edit ${app.name}" } - -@account.layout( -title = title, -active = "oauth.app", -evenMoreCss = cssTag("form3.css") -) { -
    -

    @title

    -

    - - - - - -
    Client ID@app.clientId.value
    Client Secret@app.clientSecret.value
    -

    -
    -
    - Here's a lichess OAuth app example, - and the API documentation. -
    - @inForm(form) -
    -
    -}.toHtml diff --git a/app/views/oAuth/app/form.scala b/app/views/oAuth/app/form.scala new file mode 100644 index 0000000000..f50e089bcd --- /dev/null +++ b/app/views/oAuth/app/form.scala @@ -0,0 +1,67 @@ +package views.html.oAuth.app + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object form { + + def create(form: Form[_])(implicit ctx: Context) = { + val title = "New OAuth App" + views.html.account.layout(title = title, active = "oauth.app") { + div(cls := "account oauth box box-pad")( + h1(title), + st.form(cls := "form3", action := routes.OAuthApp.create, method := "POST")( + div(cls := "form-group")( + "Want to build something that integrates with and extends Lichess? Register a new OAuth App to get started developing on the Lichess API." + ), + inner(form) + ) + ) + } + } + + def edit(app: lila.oauth.OAuthApp, form: Form[_])(implicit ctx: Context) = { + val title = s"Edit ${app.name}" + views.html.account.layout(title = title, active = "oauth.app") { + div(cls := "account oauth box box-pad")( + h1(title), + table(cls := "codes")( + tbody( + tr(th("Client ID"), td(app.clientId.value)), + tr(th("Client Secret"), td(app.clientSecret.value)) + ) + ), + br, br, + st.form(cls := "form3", action := routes.OAuthApp.update(app.clientId.value), method := "POST")( + div(cls := "form-group")( + "Here's a ", + a(href := "https://github.com/lichess-org/api/tree/master/example/oauth-authorization-code")( + "lichess OAuth app example" + ), + ", and the ", a(href := routes.Api.index)("API documentation"), "." + ), + inner(form) + ) + ) + } + } + + private def inner(form: Form[_])(implicit ctx: Context) = frag( + errMsg(form), + form3.group(form("name"), raw("App name"))(form3.input(_)), + form3.group(form("description"), raw("App description"))(form3.textarea(_)()), + form3.split( + form3.group(form("homepageUri"), raw("Homepage URL"), half = true)(form3.input(_, typ = "url")), + form3.group(form("redirectUri"), raw("Callback URL"), half = true, help = frag("It must match the URL in your code").some)(form3.input(_, typ = "url")) + ), + form3.actions( + a(href := routes.OAuthApp.index)("Cancel"), + form3.submit(trans.apply()) + ) + ) +} diff --git a/app/views/oAuth/app/inForm.scala.html b/app/views/oAuth/app/inForm.scala.html deleted file mode 100644 index 6ebf041b2a..0000000000 --- a/app/views/oAuth/app/inForm.scala.html +++ /dev/null @@ -1,13 +0,0 @@ -@(form: Form[_])(implicit ctx: Context) -@import lila.app.ui.ScalatagsTwirlForm._ - -@form3.group(form("name"), raw("App name"))(form3.input(_)) -@form3.group(form("description"), raw("App description"))(form3.textarea(_)()) -@form3.split { -@form3.group(form("homepageUri"), raw("Homepage URL"), half = true)(form3.input(_, typ = "url")) -@form3.group(form("redirectUri"), raw("Callback URL"), half = true)(form3.input(_, typ = "url")) -} -@form3.actionsHtml { -Cancel -@form3.submit(trans.apply.frag()) -} diff --git a/app/views/oAuth/app/index.scala b/app/views/oAuth/app/index.scala new file mode 100644 index 0000000000..f65e41bf72 --- /dev/null +++ b/app/views/oAuth/app/index.scala @@ -0,0 +1,49 @@ +package views.html.oAuth.app + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object index { + + def apply(apps: List[lila.oauth.OAuthApp])(implicit ctx: Context) = + views.html.account.layout(title = "OAuth Apps", active = "oauth.app")( + div(cls := "account oauth box")( + div(cls := "box__top")( + h1("OAuth Apps"), + st.form(cls := "box__top__actions", action := routes.OAuthApp.create)( + button(tpe := "submit", cls := "button button-fat button-empty", title := "New app", dataIcon := "O") + ) + ), + p(cls := "box__pad")( + "Want to build something that integrates with and extends Lichess? Register a new OAuth App to get started developing on the Lichess API.", + br, br, + "Here's a ", + a(href := "https://github.com/lichess-org/api/tree/master/example/oauth-authorization-code")("lichess OAuth app example"), + ", and the ", a(href := routes.Api.index)("API documentation"), "." + ), + table(cls := "slist slist-pad")( + apps.map { t => + tr( + td( + strong(t.name), br, + t.description.map { em(_) } + ), + td(cls := "date")( + t.homepageUri, br, + "Created ", momentFromNow(t.createdAt) + ), + td(cls := "action")( + a(href := routes.OAuthApp.edit(t.clientId.value), cls := "button", title := "Edit this app", dataIcon := "m"), + st.form(action := routes.OAuthApp.delete(t.clientId.value), method := "POST")( + button(tpe := "submit", cls := "button button-empty button-red confirm", title := "Delete this app", dataIcon := "q") + ) + ) + ) + } + ) + ) + ) +} diff --git a/app/views/oAuth/app/index.scala.html b/app/views/oAuth/app/index.scala.html deleted file mode 100644 index 4fb1e252e4..0000000000 --- a/app/views/oAuth/app/index.scala.html +++ /dev/null @@ -1,45 +0,0 @@ -@(apps: List[lila.oauth.OAuthApp])(implicit ctx: Context) - -@title = @{ "OAuth Apps" } - -@account.layout(title = title, active = "oauth.app") { -
    -
    -

    @title

    -
    - -
    -
    -

    - Want to build something that integrates with and extends Lichess? Register a new OAuth App to get started developing on the Lichess API.
    -
    - Here's a lichess OAuth app example, - and the API documentation. -

    - - - @apps.map { t => - - - - - - } -
    - @t.name
    - @t.description.map { desc => - @desc - } -
    - @t.homepageUri
    - Created @momentFromNow(t.createdAt) -
    - -
    - -
    -
    -
    -}.toHtml diff --git a/app/views/oAuth/token/create.scala b/app/views/oAuth/token/create.scala new file mode 100644 index 0000000000..3a1b7d198e --- /dev/null +++ b/app/views/oAuth/token/create.scala @@ -0,0 +1,53 @@ +package views.html.oAuth.token + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object create { + + def apply(form: Form[_], me: lila.user.User)(implicit ctx: Context) = { + + val title = "New personal API access token" + + views.html.account.layout(title = title, active = "oauth.token")( + div(cls := "account oauth box box-pad")( + h1(title), + st.form(cls := "form3", action := routes.OAuthToken.create, method := "POST")( + div(cls := "form-group")( + "Personal access tokens function like ordinary lichess OAuth access tokens. ", + "They can be used to authenticate to the API over Basic Authentication." + ), + form3.group( + form("description"), + raw("Token description"), + help = raw("For you to remember what this token is for").some + )(form3.input(_)), + br, br, + h2("Scopes define the access for personal tokens:"), + div(cls := "scopes")( + lila.oauth.OAuthScope.all.map { scope => + val disabled = me.noBot && scope == lila.oauth.OAuthScope.Bot.Play && me.count.game > 0 + val id = s"oauth-scope-${scope.key.replace(":", "_")}" + div( + span( + input(st.id := id, cls := "cmn-toggle", tpe := "checkbox", name := s"${form("scopes").name}[]", value := scope.key, disabled option st.disabled), + label(`for` := id) + ), + label(`for` := id, st.title := disabled.option("You already have played games!"))(scope.name) + ) + } + ), + form3.actions( + a(href := routes.OAuthToken.index)("Cancel"), + form3.submit(trans.apply()) + ) + ) + ) + ) + } +} diff --git a/app/views/oAuth/token/create.scala.html b/app/views/oAuth/token/create.scala.html deleted file mode 100644 index 0fd6f5a368..0000000000 --- a/app/views/oAuth/token/create.scala.html +++ /dev/null @@ -1,43 +0,0 @@ -@(form: Form[_], me: User)(implicit ctx: Context) -@import lila.app.ui.ScalatagsTwirlForm._ - -@title = @{ "New personal API access token" } - -@account.layout( -title = title, -active = "oauth.token", -evenMoreCss = cssTag("form3.css") -) { -
    -

    @title

    -
    - -

    -
    - Personal access tokens function like ordinary lichess OAuth access tokens. - They can be used to authenticate to the API over Basic Authentication. -
    - - @form3.group(form("description"), raw("Token description"), help = raw("For you to remember what this token is for").some)(form3.input(_)) - -

    -

    Scopes define the access for personal tokens:

    - -
    - @lila.oauth.OAuthScope.all.map { scope => - @defining(me.noBot && scope == lila.oauth.OAuthScope.Bot.Play && me.count.game > 0) { disabled => - - - @scope.name - - } - } -
    - - @form3.actionsHtml { - Cancel - @form3.submit(trans.apply.frag()) - } -
    -
    -}.toHtml diff --git a/app/views/oAuth/token/index.scala b/app/views/oAuth/token/index.scala new file mode 100644 index 0000000000..ec8303c426 --- /dev/null +++ b/app/views/oAuth/token/index.scala @@ -0,0 +1,71 @@ +package views.html.oAuth.token + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object index { + + def apply(tokens: List[lila.oauth.AccessToken])(implicit ctx: Context) = { + + val title = "Personal API access tokens" + + views.html.account.layout(title = title, active = "oauth.token")( + div(cls := "account oauth box")( + div(cls := "box__top")( + h1(title), + st.form(cls := "box-top__actions", action := routes.OAuthToken.create)( + button(tpe := "submit", cls := "button frameless", st.title := "New access token", dataIcon := "O") + ) + ), + p(cls := "box__pad")( + "You can make OAuth requests without going through the authorization code flow.", br, br, + "Instead, ", + a(href := routes.OAuthToken.create)("generate a personal token"), + " that you can directly use in API requests.", br, br, + "Be careful, these tokens are like passwords so you should guard them carefully. ", + "The advantage to using a token over putting your password into a script is that a token can be revoked, ", + "and you can generate lots of them.", br, br, + "Here's a ", + a(href := "https://github.com/lichess-org/api/tree/master/example/oauth-personal-token")("personal token app example"), + " and the ", + a(href := routes.Api.index)("API documentation"), "." + ), + tokens.headOption.filter(_.isBrandNew).map { token => + div(cls := "box__pad brand")( + iconTag("E")(cls := "is-green"), + div( + p("Make sure to copy your new personal access token now.", br, "You won’t be able to see it again!"), + code(token.id.value) + ) + ) + }, + table(cls := "slist slist-pad")( + tokens.map { t => + tr( + td( + strong(t.description | "Unnamed"), br, + em(t.scopes.map(_.name).mkString(", ")) + ), + td(cls := "date")( + t.createdAt.map { created => + frag("Created ", momentFromNow(created), br) + }, + t.usedAt.map { used => + frag("Last used ", momentFromNow(used)) + } + ), + td(cls := "action")( + form(action := routes.OAuthToken.delete(t.id.value), method := "POST")( + button(tpe := "submit", cls := "button button-red button-empty confirm", st.title := "Delete this access token")("Delete") + ) + ) + ) + } + ) + ) + ) + } +} diff --git a/app/views/oAuth/token/index.scala.html b/app/views/oAuth/token/index.scala.html deleted file mode 100644 index 9790484e39..0000000000 --- a/app/views/oAuth/token/index.scala.html +++ /dev/null @@ -1,63 +0,0 @@ -@(tokens: List[lila.oauth.AccessToken])(implicit ctx: Context) - -@title = @{ "Personal API access tokens" } - -@account.layout(title = title, active = "oauth.token") { -
    -
    -

    @title

    -
    - -
    -
    -

    - You can make OAuth requests without going through the authorization code flow.
    -
    - Instead, generate a personal token that you can directly use in API requests.
    -
    - Be careful, these tokens are like passwords so you should guard them carefully.
    - The advantage to using a token over putting your password into a script is that a token can be revoked, - and you can generate lots of them.
    -
    - Here's a - personal token app example, - and the API documentation. -

    - - @tokens.headOption.filter(_.isBrandNew).map { token => -
    - -
    -

    Make sure to copy your new personal access token now.
    You won’t be able to see it again!

    - @token.id.value -
    -
    - } - - - @tokens.map { t => - - - - - - } -
    - @t.description.getOrElse("Unnamed")
    - @t.scopes.map(_.name).mkString(", ") -
    - @t.createdAt.map { created => - Created @momentFromNow(created)
    - } - @t.usedAt.map { used => - Last used @momentFromNow(used) - } -
    -
    - -
    -
    -
    -}.toHtml diff --git a/app/views/plan/badCheckout.scala b/app/views/plan/badCheckout.scala new file mode 100644 index 0000000000..bfe2d193c3 --- /dev/null +++ b/app/views/plan/badCheckout.scala @@ -0,0 +1,14 @@ +package views.html.plan + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +object badCheckout { + + def apply(err: String)(implicit ctx: Context) = + views.html.site.message("Payment can not be processed.")( + p("The payment didn't go through. Your card was not charged."), + p(err) + ) +} diff --git a/app/views/plan/badCheckout.scala.html b/app/views/plan/badCheckout.scala.html deleted file mode 100644 index 695b99a058..0000000000 --- a/app/views/plan/badCheckout.scala.html +++ /dev/null @@ -1,6 +0,0 @@ -@(err: String)(implicit ctx: Context) - -@site.message("Payment can not be processed.") { -

    The payment didn't go through. Your card was not charged.

    -

    @err

    -}.toHtml diff --git a/app/views/plan/features.scala b/app/views/plan/features.scala index 8ba9d9e7ae..aac86338b5 100644 --- a/app/views/plan/features.scala +++ b/app/views/plan/features.scala @@ -1,8 +1,6 @@ package views package html.plan -import play.twirl.api.Html - import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ @@ -13,15 +11,14 @@ object features { def apply()(implicit ctx: Context) = views.html.base.layout( title = title, - side = side.some, - moreCss = cssTag("features.css"), + moreCss = cssTag("feature"), openGraph = lila.app.ui.OpenGraph( title = title, url = s"$netBaseUrl${routes.Plan.features.url}", - description = "All of Lichess features are free for all and forever. We do it for chess!" + description = "All of Lichess features are free for all and forever. We do it for the chess!" ).some ) { - div(cls := "content_box features")( + main(cls := "box box-pad features")( table( header(h1(dataIcon := "")("Website")), tbody( @@ -75,7 +72,7 @@ object features { ), tr(unlimited)( a(href := routes.Search.index(1))("Advanced search"), - " through Lichess 900 million games" + " through Lichess 1.5 billion games" ), tr(unlimited)( a(href := routes.Video.index)("Chess video library") @@ -112,7 +109,7 @@ object features { a(href := routes.Tournament.home(1))("Arena tournaments") ), tr(check)( - "Board editor and analysis board with $engineName" + s"Board editor and analysis board with $engineName" ), tr(unlimited)( a(href := routes.Puzzle.home)("Tactics puzzles") @@ -161,7 +158,7 @@ object features { strong("all features are free for everybody, forever!"), br, "If you love Lichess, ", - a(cls := "button", href := routes.Plan.index)("support us with a Patron account!") + a(cls := "button", href := routes.Plan.index)("Support us with a Patron account!") ) ) } @@ -182,11 +179,5 @@ object features { private val title = "Lichess features" - private val side: Html = - div(cls := "features_side")( - h2("Free chess for everyone, forever!"), - a(href := routes.Plan.index, cls := "button")("Support Lichess") - ) - private val engineName = "Stockfish 10+" } diff --git a/app/views/plan/index.scala b/app/views/plan/index.scala new file mode 100644 index 0000000000..f4f3f541af --- /dev/null +++ b/app/views/plan/index.scala @@ -0,0 +1,262 @@ +package views.html.plan + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.pref.PrefCateg + +import controllers.routes + +object index { + + def apply( + email: Option[lila.common.EmailAddress], + stripePublicKey: String, + patron: Option[lila.plan.Patron], + recentIds: List[String], + bestIds: List[String] + )(implicit ctx: Context) = { + + val title = "Become a Patron of lichess.org" + + views.html.base.layout( + title = title, + moreCss = cssTag("plan"), + moreJs = frag( + script(src := "https://checkout.stripe.com/checkout.js"), + jsTag("checkout.js"), + embedJsUnsafe(s"""lichess.checkout("$stripePublicKey");""") + ), + openGraph = lila.app.ui.OpenGraph( + title = title, + url = s"$netBaseUrl${routes.Plan.index.url}", + description = "Free chess for everyone, forever!" + ).some, + csp = defaultCsp.withStripe.some + ) { + main(cls := "page-menu plan")( + st.aside(cls := "page-menu__menu recent-patrons")( + h2("New Patrons"), + div(cls := "list")( + recentIds.map { userId => + div(userIdLink(userId.some)) + } + ) + ), + div(cls := "page-menu__content box")( + patron.ifTrue(ctx.me.??(_.isPatron)).map { p => + div(cls := "banner one_time_active")( + iconTag(patronIconChar), + div( + h1("Thank you for your donation!"), + if (p.isLifetime) frag( + "You have a ", strong("Lifetime Patron"), " account. That's pretty awesome!" + ) + else p.expiresAt.map { expires => + frag( + "You have a Patron account until ", showDate(expires), ".", br, + "If not renewed, you will then be downgraded to free." + ) + } + ), + iconTag(patronIconChar) + ) + } getOrElse div(cls := "banner moto")( + iconTag(patronIconChar), + div( + h1("Free chess for everyone, forever!"), + p("No ads, no subscriptions; but open source and passion.") + ), + iconTag(patronIconChar) + ), + div(cls := "box__pad")( + div(cls := "wrapper")( + div(cls := "text")( + p( + "We are a non‑profit association because we believe in a free, ", + "world-class chess experience for anyone, anywhere." + ), + p( + "We rely on support from people like you to make it possible. ", + "If you've gotten something out of Lichess, please take a second to pitch in!" + ) + ), + div(cls := "content")( + + div( + cls := "plan_checkout", + attr("data-email") := email.map(_.value), + attr("data-lifetime-usd") := lila.plan.Cents.lifetime.usd.toString, + attr("data-lifetime-cents") := lila.plan.Cents.lifetime.value + )( + raw(s""" +
    + + + + +
    +
    + + + + + + + + + + + + + +
    +
    + + + + + + + + + + + + + + + +
    +
    + + + + + + + + + + + + + +
    """), + + patron.exists(_.isLifetime) option + p(style := "text-align:center;margin-bottom:1em")("Make an extra donation?"), + + st.group(cls := "radio buttons freq")( + div( + st.title := s"Pay ${lila.plan.Cents.lifetime.usd} once. Be a Lichess Patron forever!", + cls := List("lifetime-check" -> patron.exists(_.isLifetime)), + input(tpe := "radio", name := "freq", id := "freq_lifetime", patron.exists(_.isLifetime) option disabled, value := "lifetime"), + label(`for` := "freq_lifetime")("Lifetime") + ), + div( + st.title := "Recurring billing, renewing your Patron Wings every month.", + input(tpe := "radio", name := "freq", id := "freq_monthly", checked, value := "monthly"), + label(`for` := "freq_monthly")("Monthly") + ), + div( + st.title := "A single donation that grants you the Patron Wings for one month.", + input(tpe := "radio", name := "freq", id := "freq_onetime", checked, value := "onetime"), + label(`for` := "freq_onetime")("One-time") + ) + ), + div(cls := "amount_choice")( + st.group(cls := "radio buttons amount")( + lila.plan.StripePlan.defaultAmounts.map { cents => + val id = s"plan_${cents.value}" + div( + input(tpe := "radio", name := "plan", + st.id := id, + cents.usd.value == 10 option checked, + value := cents.value, + attr("data-usd") := cents.usd.toString, + attr("data-amount") := cents.value), + label(`for` := id)(cents.usd.toString) + ) + }, + div(cls := "other")( + input(tpe := "radio", name := "plan", + id := "plan_other", + value := "other"), + label(`for` := "plan_other")("Other") + ) + ) + ), + div(cls := "amount_fixed none")( + st.group(cls := "radio buttons amount")( + div { + val cents = lila.plan.Cents.lifetime + label(`for` := s"plan_${cents.value}")(cents.usd.toString) + } + ) + ), + div(cls := "service")( + button(cls := "stripe button")("Credit Card"), + button(cls := "paypal button")("PayPal") + ) + ) + ) + ), + p(cls := "small_team")( + "We are a small team, so your support makes a huge difference!" + ), + faq, + div(cls := "best_patrons")( + h2("The celebrated Patrons who make Lichess possible"), + div(cls := "list")( + bestIds.map { userId => + div(userIdLink(userId.some)) + } + ) + ) + ) + ) + ) + } + } + + private def faq(implicit ctx: Context) = div(cls := "faq")( + dl( + dt("Where does the money go?"), + dd( + "First of all, powerful servers.", br, + "Then we pay a full-time developer: ", userIdLink("thibault".some), ", the founder of Lichess.", br, + "See the ", a(href := "/costs", target := "_blank")("detailed cost breakdown.") + ), + dt("Is Lichess an official non-profit?"), + dd( + "Yes, here's the ", a(href := "http://www.journal-officiel.gouv.fr/association/index.php?ACTION=Rechercher&WHAT=lichess.org")( + "act of creation (FR)" + ), "." + ) + ), + dl( + dt("Can I change/cancel my monthly support?"), + dd( + "Yes, at any time, from this page.", br, + "Or you can ", a(href := routes.Main.contact, target := "_blank")("contact Lichess support"), "." + ), + dt("Other methods of donation?"), + dd( + "We also accept ", a(href := staticUrl("doc/iban_LICHESS_ORG_00022031601.pdf"), target := "_blank")( + "bank transfers" + ), ".", br, + "And here's our bitcoin address: ", code("15ZA4bBki3uu3yR2ENC2WYa9baVGUZ8Cf8") + ) + ), + dl( + dt("Are some features reserved to Patrons?"), + dd( + a(href := routes.Plan.features, target := "_blank")("No"), ", because ", + "Lichess is entirely free, forever, and for everyone. That's a promise. ", + "But Patrons get bragging rights with a cool new profile icon.", br, + "See the ", a(href := routes.Plan.features, target := "_blank")("detailed features comparison"), "." + ) + ) + ) +} diff --git a/app/views/plan/index.scala.html b/app/views/plan/index.scala.html deleted file mode 100644 index ca820efe39..0000000000 --- a/app/views/plan/index.scala.html +++ /dev/null @@ -1,241 +0,0 @@ -@(email: Option[lila.common.EmailAddress], stripePublicKey: String, patron: Option[lila.plan.Patron], recentIds: List[String], bestIds: List[String])(implicit ctx: Context) - -@title = @{"Become a Patron of lichess.org"} - -@moreJs = { - -@jsTag("checkout.js") -@embedJs { -lichess.checkout("@stripePublicKey"); -} -} - -@side = { -
    -

    New Patrons

    -
    - @recentIds.map { userId => -
    @userIdLink(userId.some)
    - } -
    -
    -} - -@base.layout( -title = title, -side = side.some, -moreCss = cssTag("plan.css"), -moreJs = moreJs, -openGraph = lila.app.ui.OpenGraph( -title = title, -url = s"$netBaseUrl${routes.Plan.index.url}", -description = "Free chess for everyone, forever!").some, -csp = defaultCsp.withStripe.some) { -
    - @patron.ifTrue(ctx.me.??(_.isPatron)).map { p => - - }.getOrElse { - - } -
    -
    -
    -

    - We are a non‑profit association because we believe in a free, - world-class chess experience for anyone, anywhere. -

    -

    - We rely on support from people like you to make it possible. - If you've gotten something out of Lichess, please take a second to pitch in! -

    -
    -
    - -
    -
    - - - - -
    -
    - - - - - - - - - - - - - -
    -
    - - - - - - - - - - - - - - - -
    -
    - - - - - - - - - - - - - -
    - - @if(patron.exists(_.isLifetime)) {

    Make an extra donation?

    } - - - @defining(s"Pay ${lila.plan.Cents.lifetime.usd} once. Be a Lichess Patron forever!") { info => -
    - - -
    - } - @defining("Recurring billing, renewing your Patron Wings every month.") { info => -
    - - -
    - } - @defining("A single donation that grants you the Patron Wings for one month.") { info => -
    - - -
    - } -
    -
    - - @lila.plan.StripePlan.defaultAmounts.map { cents => - @defining(s"plan_${cents.value}") { id => -
    - - -
    - } - } -
    - - -
    -
    -
    -
    - -
    - @defining(lila.plan.Cents.lifetime) { cents => - - } -
    -
    -
    -
    - - -
    -
    -
    -
    -

    - We are a small team, so your support will make a huge difference! -

    -
    -
    -
    Where does the money go?
    -
    - First of all, powerful servers.
    - Then we pay a full-time developer: @userIdLink("thibault".some), the founder of Lichess.
    - See the detailed cost breakdown. -
    -
    Is Lichess an official non-profit?
    -
    - Yes, here's the act of creation (FR). -
    -
    -
    -
    Can I change/cancel my monthly support?
    -
    - Yes, at any time, from this page.
    - Or you can contact Lichess support. -
    -
    Other methods of donation?
    -
    - We also accept bank transfers.
    - And here's our bitcoin address: 15ZA4bBki3uu3yR2ENC2WYa9baVGUZ8Cf8 -
    -
    -
    -
    Are some features reserved to Patrons?
    -
    - No, because - Lichess is entirely free, forever, and for everyone. That's a promise.
    - But Patrons get bragging rights with a cool new profile icon.
    - See the detailed features comparison. -
    -
    -
    -
    -

    The celebrated Patrons who make Lichess possible

    -
    - @bestIds.map { userId => -
    - @userIdLink(userId.some) -
    - } -
    -
    -
    -
    -}.toHtml diff --git a/app/views/plan/indexPaypal.scala.html b/app/views/plan/indexPaypal.scala.html deleted file mode 100644 index 938b0f5bb7..0000000000 --- a/app/views/plan/indexPaypal.scala.html +++ /dev/null @@ -1,14 +0,0 @@ -@(me: User, patron: lila.plan.Patron)(implicit ctx: Context) - -@base.layout( -title = "Thank you for your support!", -moreCss = cssTag("plan.css")) { - -
    -

    @userLink(me) • Lichess Patron for @pluralize("month", me.plan.months)

    -
    -

    You are supporting Lichess with paypal.

    -

    If you wish to cancel your support, please contact us at contact@@lichess.org.

    -
    -
    -}.toHtml diff --git a/app/views/plan/indexStripe.scala b/app/views/plan/indexStripe.scala new file mode 100644 index 0000000000..780cac5d2d --- /dev/null +++ b/app/views/plan/indexStripe.scala @@ -0,0 +1,94 @@ +package views.html.plan + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object indexStripe { + + private val dataForm = attr("data-form") + + def apply(me: lila.user.User, patron: lila.plan.Patron, info: lila.plan.MonthlyCustomerInfo)(implicit ctx: Context) = + views.html.base.layout( + title = "Thank you for your support!", + moreCss = cssTag("plan"), + moreJs = jsTag("plan.js") + ) { + main(cls := "box box-pad plan")( + h1( + userLink(me), " • ", + if (patron.isLifetime) strong("Lifetime Lichess Patron") + else frag("Lichess Patron for ", pluralize("month", me.plan.months)) + ), + table(cls := "all")( + tbody( + tr( + th("Current status"), + td( + "You support lichess.org with ", strong(info.subscription.plan.usd.toString), " per month.", + span(cls := "thanks")("Thank you very much for your help. You rock!") + ) + ), + tr( + th("Next payment"), + td( + "You will be charged ", strong(info.nextInvoice.usd.toString), " on ", showDate(info.nextInvoice.dateTime), ".", + br, + a(href := s"${routes.Plan.list()}#onetime")("Make an additional donation now") + ) + ), + tr( + th("Update"), + td(cls := "change")( + a(dataForm := "switch")("Change the monthly amount (", info.subscription.plan.usd.toString, ")"), + " or ", a(dataForm := "cancel")("cancel your support"), + form(cls := "switch", action := routes.Plan.switch, method := "POST")( + p("Decide what Lichess is worth to you:"), + "USD $ ", + input(tpe := "number", min := 1, max := 100000, step := "0.01", name := "usd", value := info.subscription.plan.usd.toString), + button(tpe := "submit", cls := "button")(trans.apply()), + a(dataForm := "switch")("Nevermind") + ), + form(cls := "cancel", action := routes.Plan.cancel, method := "POST")( + p("Withdraw your credit card and stop payments:"), + button(tpe := "submit", cls := "button button-red")("No longer support Lichess"), + a(dataForm := "cancel")("Nevermind :)") + ) + ) + ), + tr( + th("Payment history"), + td( + table(cls := "slist payments")( + thead( + tr( + th, + th("ID"), + th("Date"), + th("Amount") + ) + ), + tbody( + info.pastInvoices.map { in => + tr( + td(in.paid option span(dataIcon := "E", cls := "is-green text")("Paid")), + td(cls := "id")(in.id), + td(showDate(in.dateTime)), + td(in.usd.toString) + ) + } + ) + ) + ) + ), + tr( + th, + td(a(href := routes.Plan.list)("View other Lichess Patrons")) + ) + ) + ) + ) + } +} diff --git a/app/views/plan/indexStripe.scala.html b/app/views/plan/indexStripe.scala.html deleted file mode 100644 index cd5a2b87a9..0000000000 --- a/app/views/plan/indexStripe.scala.html +++ /dev/null @@ -1,86 +0,0 @@ -@(me: User, patron: lila.plan.Patron, info: lila.plan.MonthlyCustomerInfo)(implicit ctx: Context) - -@base.layout( -title = "Thank you for your support!", -moreCss = cssTag("plan.css"), -moreJs = jsTag("plan.js")) { - -
    -

    @userLink(me) • - @if(patron.isLifetime) { - Lifetime Lichess Patron - } else { - Lichess Patron for @pluralize("month", me.plan.months) - } -

    - - - - - - - - - - - - - - - - - - - - - - - -
    Current status - You support lichess.org with @info.subscription.plan.usd per month. - Thank you very much for your help. You rock! -
    Next payment - You will be charged @info.nextInvoice.usd on @showDate(info.nextInvoice.dateTime). -
    - Make an additional donation now -
    Update - Change the monthly amount (@info.subscription.plan.usd) or cancel your support -
    -

    Decide what Lichess is worth to you:

    - USD $ - - Nevermind -
    -
    -

    Withdraw your credit card and stop payments:

    - - Nevermind :) -
    -
    Payment history - - - - - - - - - - - - @info.pastInvoices.map { in => - - - - - - - - } - -
    IDDateAmount
    @if(in.paid){Paid}@in.id@showDate(in.dateTime)@in.usd
    -
    - View other Lichess Patrons -
    -
    -}.toHtml diff --git a/app/views/plan/thanks.scala b/app/views/plan/thanks.scala new file mode 100644 index 0000000000..056f09770c --- /dev/null +++ b/app/views/plan/thanks.scala @@ -0,0 +1,71 @@ +package views.html.plan + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object thanks { + + def apply(patron: Option[lila.plan.Patron], customer: Option[lila.plan.StripeCustomer])(implicit ctx: Context) = + views.html.base.layout( + moreCss = cssTag("page"), + title = "Thank you for your support!" + ) { + main(cls := "page-small page box box-pad")( + + h1(cls := "text", dataIcon := patronIconChar)("Thank you for your support!"), + + div(cls := "body")( + p("Thank you for helping us build Lichess. ", strong("You rock!")), + p( + "Your transaction has been completed, ", + "and a receipt for your donation has been emailed to you." + ), + patron.map { pat => + if (pat.payPal.??(_.renew)) p( + "You now have a permanent Patron account.", br, + ctx.me.map { me => + frag("Check out your ", a(href := routes.User.show(me.username))("profile page"), "!") + } + ) + else { + if (customer.??(_.renew)) frag( + p( + "Note that your ", a(href := routes.Plan.index)("Patron page"), + " only shows invoices for your monthly subscription." + ), + p("But worry not, we received your donation! Thanks again!") + ) + else frag( + if (pat.isLifetime) p( + "You are now a lifetime Lichess Patron!", br, + ctx.me.map { me => + frag("Check out your ", a(href := routes.User.show(me.username))("profile page"), ".") + } + ) + else frag( + p( + "You are now a Lichess Patron for one month!", br, + ctx.me.map { me => + frag("Check out your ", a(href := routes.User.show(me.username))("profile page"), ".") + } + ), + p( + "In one month, you will ", strong("not"), " be charged again, ", + "and your Lichess account will be downgraded to free." + ), + p( + "To get a permanent Patron account, please consider making a ", + a(href := routes.Plan.index)("monthly donation"), "." + ) + ) + ) + } + }, + p("Success! ", a(href := routes.Lobby.home)("Return to Lichess homepage"), ".") + ) + ) + } +} diff --git a/app/views/plan/thanks.scala.html b/app/views/plan/thanks.scala.html deleted file mode 100644 index 92f09f3a03..0000000000 --- a/app/views/plan/thanks.scala.html +++ /dev/null @@ -1,69 +0,0 @@ -@(patron: Option[lila.plan.Patron], customer: Option[lila.plan.StripeCustomer])(implicit ctx: Context) - -@base.layout( -moreCss = cssTag("page.css"), -title = "Thank you for your support!") { - -
    - -

    Thank you for your support!

    - -
    -
    -

    - Thank you for helping us build Lichess. You rock! -

    -

    - Your transaction has been completed, - and a receipt for your donation has been emailed to you. -

    - @patron.map { p => - @if(p.payPal.??(_.renew)) { -

    - You now have a permanent Patron account.
    - @ctx.me.map { me => - Check out your profile page! - } -

    - } else { - @if(customer.??(_.renew)) { -

    - Note that your Patron page only shows - invoices for your monthly subscription. -

    -

    - But worry not, we received your donation! Thanks again! -

    - } else { - @if(p.isLifetime) { -

    - You are now a lifetime Lichess Patron!
    - @ctx.me.map { me => - Check out your profile page. - } -

    - } else { -

    - You are now a Lichess Patron for one month!
    - @ctx.me.map { me => - Check out your profile page. - } -

    -

    - In one month, you will not be charged again, - and your Lichess account will be downgraded to free. -

    -

    - To get a permanent Patron account, please consider making a - monthly donation. -

    - } - } - } - } -

    - Success! Return to Lichess homepage. -

    -
    -
    -}.toHtml diff --git a/app/views/practice/config.scala b/app/views/practice/config.scala new file mode 100644 index 0000000000..25c01bac1a --- /dev/null +++ b/app/views/practice/config.scala @@ -0,0 +1,56 @@ +package views.html.practice + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object config { + + def apply(structure: lila.practice.PracticeStructure, form: Form[_])(implicit ctx: Context) = + views.html.base.layout( + title = "Practice structure", + moreCss = cssTag("mod.misc") + )( + main(cls := "page-menu")( + views.html.mod.menu("practice"), + div(cls := "practice_config page-menu__content box box-pad")( + h1("Practice config"), + div(cls := "both")( + st.form(action := routes.Practice.configSave, method := "POST")( + textarea(cls := "practice_text", name := "text")(form("text").value), + errMsg(form("text")), + button(tpe := "submit", cls := "button button-fat text", dataIcon := "E")("Save") + ), + div(cls := "preview")( + ol( + structure.sections.map { section => + li( + h2(s"${section.name} (#${section.id})"), + ol( + section.studies.map { stud => + li( + i(cls := s"practice icon ${stud.id}")( + h3(a(href := routes.Study.show(stud.id.value))(s"${stud.name} (#${stud.id})")), + em(stud.desc), + ol( + stud.chapters.map { cha => + li(a(href := routes.Study.chapter(stud.id.value, cha.id.value))(cha.name)) + } + ) + ) + ) + } + ) + ) + } + ) + ) + ) + ) + ) + ) +} diff --git a/app/views/practice/config.scala.html b/app/views/practice/config.scala.html deleted file mode 100644 index 7188ff84db..0000000000 --- a/app/views/practice/config.scala.html +++ /dev/null @@ -1,42 +0,0 @@ -@(structure: lila.practice.PracticeStructure, form: Form[_])(implicit ctx: Context) - -@mod.layout( -title = "Practice structure", -active = "practice", -moreCss = cssTag("mod-practice.css")) { -
    -

    Practice config

    -
    -
    - - @errMsg(form("text")) - -
    -
    -
      - @structure.sections.map { section => -
    1. -

      @section.name (#@section.id)

      -
        - @section.studies.map { stud => -
      1. - -

        @stud.name (#@stud.id)

        - @stud.desc -
          - @stud.chapters.map { cha => -
        1. - @cha.name -
        2. - } -
        -
      2. - } -
      -
    2. - } -
    -
    -
    -
    -} diff --git a/app/views/practice/index.scala b/app/views/practice/index.scala index 8adc1a3c79..4ca5808ea6 100644 --- a/app/views/practice/index.scala +++ b/app/views/practice/index.scala @@ -4,7 +4,6 @@ package practice import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ -import lila.common.String.html.safeJsonValue import controllers.routes @@ -12,25 +11,8 @@ object index { def apply(data: lila.practice.UserPractice)(implicit ctx: Context) = views.html.base.layout( title = "Practice chess positions", - side = Some( - div(id := "practice_side", cls := "side_box")( - div(cls := "home")( - i(cls := "fat"), - h1("Practice"), - h2("makes your chess perfect"), - div(cls := "progress")( - div(cls := "text")("Progress: ", data.progressPercent, "%"), - div(cls := "bar", style := s"width: ${data.progressPercent}%") - ), - form(id := "practice_reset", cls := "actions", action := routes.Practice.reset, method := "post")( - if (ctx.isAuth) (data.nbDoneChapters > 0) option a(cls := "do-reset")("Reset my progress") - else a(href := routes.Auth.signup)("Sign up to save your progress") - ) - ) - ) - ), - moreCss = cssTag("practice.css"), - moreJs = embedJs(s"""$$('#practice_reset .do-reset').on('click', function() { + moreCss = cssTag("practice.index"), + moreJs = embedJsUnsafe(s"""$$('.do-reset').on('click', function() { if (confirm('You will lose your practice progress!')) this.parentNode.submit(); });"""), openGraph = lila.app.ui.OpenGraph( @@ -39,10 +21,23 @@ if (confirm('You will lose your practice progress!')) this.parentNode.submit(); url = s"$netBaseUrl${routes.Practice.index}" ).some ) { - div(id := "practice_app")( - div(cls := "sections")( + main(cls := "page-menu")( + st.aside(cls := "page-menu__menu practice-side")( + i(cls := "fat"), + h1("Practice"), + h2("makes your chess perfect"), + div(cls := "progress")( + div(cls := "text")("Progress: ", data.progressPercent, "%"), + div(cls := "bar", style := s"width: ${data.progressPercent}%") + ), + form(action := routes.Practice.reset, method := "post")( + if (ctx.isAuth) (data.nbDoneChapters > 0) option a(cls := "do-reset")("Reset my progress") + else a(href := routes.Auth.signup)("Sign up to save your progress") + ) + ), + div(cls := "page-menu__content practice-app")( data.structure.sections.map { section => - div(cls := "section")( + st.section( h2(section.name), div(cls := "studies")( section.studies.map { stud => @@ -54,7 +49,7 @@ if (confirm('You will lose your practice progress!')) this.parentNode.submit(); ctx.isAuth option span(cls := "ribbon-wrapper")( span(cls := "ribbon")(prog.done, " / ", prog.total) ), - i(cls := s"practice icon ${stud.id}"), + i(cls := s"${stud.id}"), span(cls := "text")( h3(stud.name), em(stud.desc) diff --git a/app/views/practice/show.scala b/app/views/practice/show.scala index 6cfd2db34c..f322190896 100644 --- a/app/views/practice/show.scala +++ b/app/views/practice/show.scala @@ -1,6 +1,8 @@ package views.html package practice +import play.api.libs.json.Json + import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ @@ -15,24 +17,26 @@ object show { data: lila.practice.JsonView.JsData )(implicit ctx: Context) = views.html.base.layout( title = us.practiceStudy.name, - side = div(cls := "side_box study_box").toHtml.some, - moreCss = cssTags("analyse.css", "study.css", "practice.css"), + moreCss = cssTag("analyse.practice"), moreJs = frag( analyseTag, analyseNvuiTag, - embedJs(s"""lichess = lichess || {}; lichess.practice = { -practice: ${safeJsonValue(data.practice)}, -study: ${safeJsonValue(data.study)}, -data: ${safeJsonValue(data.analysis)}, -i18n: ${board.userAnalysisI18n()}, -explorer: { -endpoint: "$explorerEndpoint", -tablebaseEndpoint: "$tablebaseEndpoint" -}};""") + embedJsUnsafe(s"""lichess=window.lichess||{};lichess.practice=${ + safeJsonValue(Json.obj( + "practice" -> data.practice, + "study" -> data.study, + "data" -> data.analysis, + "i18n" -> board.userAnalysisI18n(), + "explorer" -> Json.obj( + "endpoint" -> explorerEndpoint, + "tablebaseEndpoint" -> tablebaseEndpoint + ) + )) + }""") ), chessground = false, zoomable = true ) { - div(cls := "analyse cg-512")(miniBoardContent) + main(cls := "analyse") } } diff --git a/app/views/puzzle/bits.scala b/app/views/puzzle/bits.scala index 1f1d953e17..49e727b871 100644 --- a/app/views/puzzle/bits.scala +++ b/app/views/puzzle/bits.scala @@ -1,8 +1,6 @@ package views package html.puzzle -import play.twirl.api.Html - import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ @@ -15,13 +13,13 @@ object bits { def daily(p: lila.puzzle.Puzzle, fen: String, lastMove: String) = a( href := routes.Puzzle.daily(), - cls := "mini_board parse_fen is2d", + cls := "mini-board cg-board-wrap parse-fen is2d", dataColor := p.color.name, dataFen := fen, dataLastmove := lastMove - )(miniBoardContent) + )(div(cls := "cg-board")) - def jsI18n(implicit ctx: Context) = toJsonFrag(i18nJsObject(translations)) + def jsI18n()(implicit ctx: Context) = i18nJsObject(translations) private val translations = List( trans.training, diff --git a/app/views/puzzle/embed.scala b/app/views/puzzle/embed.scala new file mode 100644 index 0000000000..8cf295d39c --- /dev/null +++ b/app/views/puzzle/embed.scala @@ -0,0 +1,45 @@ +package views.html.puzzle + +import play.api.mvc.RequestHeader + +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.app.ui.EmbedConfig +import views.html.base.layout.{ bits => layout } + +import controllers.routes + +object embed { + + import EmbedConfig.implicits._ + + private val dataStreamUrl = attr("data-stream-url") + + def apply(daily: lila.puzzle.DailyPuzzle)(implicit config: EmbedConfig) = frag( + layout.doctype, + layout.htmlTag(config.lang)( + head( + layout.charset, + layout.metaCsp(basicCsp), + st.headTitle("lichess.org chess puzzle"), + layout.pieceSprite(lila.pref.PieceSet.default), + cssTagWithTheme("tv.embed", config.bg) + ), + body( + cls := s"base ${config.board}", + dataStreamUrl := routes.Tv.feed + )( + div(id := "daily-puzzle", cls := "embedded", title := trans.clickToSolve.txt())( + raw(daily.html), + div(cls := "vstext", style := "text-align: center; justify-content: center")( + trans.puzzleOfTheDay(), br, + daily.color.fold(trans.whitePlays, trans.blackPlays)() + ) + ), + jQueryTag, + jsAt("javascripts/vendor/chessground.min.js", false), + jsAt("compiled/puzzle.js", false) + ) + ) + ) +} diff --git a/app/views/puzzle/embed.scala.html b/app/views/puzzle/embed.scala.html deleted file mode 100644 index 1c434c4eff..0000000000 --- a/app/views/puzzle/embed.scala.html +++ /dev/null @@ -1,33 +0,0 @@ -@(daily: lila.puzzle.DailyPuzzle)(implicit ctx: Context) - - - - - - - lichess.org training - @ctx.currentBg match { - case "dark" => { @cssTag("dark.css") } - case "transp" => { @cssTag("dark.css")@cssTag("transp.css") } - case _ => {} - } - @cssTag(s"piece/merida.css") - @cssTag("common.css") - @cssTag("board.css") - - -
    - @Html(daily.html) -
    - @trans.puzzleOfTheDay()
    - @daily.color.fold(trans.whitePlays, trans.blackPlays)() -
    -
    - @jsTag("vendor/chessground.min.js") - @jsAt("compiled/puzzle.js") - - - diff --git a/app/views/puzzle/show.scala b/app/views/puzzle/show.scala new file mode 100644 index 0000000000..cc60749ee2 --- /dev/null +++ b/app/views/puzzle/show.scala @@ -0,0 +1,53 @@ +package views.html.puzzle + +import play.api.libs.json.{ Json, JsObject } + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.String.html.safeJsonValue + +import controllers.routes + +object show { + + def apply(puzzle: lila.puzzle.Puzzle, data: JsObject, pref: JsObject)(implicit ctx: Context) = + views.html.base.layout( + title = trans.training.txt(), + moreCss = cssTag("puzzle"), + moreJs = frag( + jsTag("vendor/sparkline.min.js"), + jsAt(s"compiled/lichess.puzzle${isProd ?? (".min")}.js"), + embedJsUnsafe(s""" +lichess = lichess || {}; +lichess.puzzle = ${ + safeJsonValue(Json.obj( + "data" -> data, + "pref" -> pref, + "i18n" -> bits.jsI18n() + )) + }""") + ), + chessground = false, + openGraph = lila.app.ui.OpenGraph( + image = cdnUrl(routes.Export.puzzlePng(puzzle.id).url).some, + title = s"Chess tactic #${puzzle.id} - ${puzzle.color.name.capitalize} to play", + url = s"$netBaseUrl${routes.Puzzle.show(puzzle.id).url}", + description = s"Lichess tactic trainer: " + puzzle.color.fold( + trans.findTheBestMoveForWhite, + trans.findTheBestMoveForBlack + ).txt() + s" Played by ${puzzle.attempts} players." + ).some, + zoomable = true + ) { + main(cls := "puzzle")( + st.aside(cls := "puzzle__side")( + div(cls := "puzzle__side__metas")(spinner) + ), + div(cls := "puzzle__board main-board")(chessgroundSvg), + div(cls := "puzzle__tools"), + div(cls := "puzzle__controls"), + div(cls := "puzzle__history") + ) + } +} diff --git a/app/views/puzzle/show.scala.html b/app/views/puzzle/show.scala.html deleted file mode 100644 index de7112ad7e..0000000000 --- a/app/views/puzzle/show.scala.html +++ /dev/null @@ -1,30 +0,0 @@ -@(puzzle: lila.puzzle.Puzzle, data: play.api.libs.json.JsObject, pref: play.api.libs.json.JsObject)(implicit ctx: Context) - -@moreJs = { -@jsTag("vendor/sparkline.min.js") -@jsAt(s"compiled/lichess.puzzle${isProd??(".min")}.js") -@embedJs { -lichess = lichess || {}; -lichess.puzzle = { data: @toJsonHtml(data), pref: @toJsonHtml(pref), i18n: @bits.jsI18n.toHtml }; -} -} - -@base.layout( -title = trans.training.txt(), -side = Html("""
    """).some, -moreCss = cssTags("analyse.css", "puzzle.css"), -moreJs = moreJs, -chessground = false, -openGraph = lila.app.ui.OpenGraph( -image = cdnUrl(routes.Export.puzzlePng(puzzle.id).url).some, -title = s"Chess tactic #${puzzle.id} - ${puzzle.color.name.capitalize} to play", -url = s"$netBaseUrl${routes.Puzzle.show(puzzle.id).url}", -description = s"Lichess tactic trainer: " + puzzle.color.fold( -trans.findTheBestMoveForWhite, -trans.findTheBestMoveForBlack -).txt() + s" Played by ${puzzle.attempts} players.").some, -zoomable = true) { -
    - @board.bits.domPreload(none).toHtml -
    -}.toHtml diff --git a/app/views/relation/actions.scala b/app/views/relation/actions.scala index 0cf26e8dde..e01f578b93 100644 --- a/app/views/relation/actions.scala +++ b/app/views/relation/actions.scala @@ -8,6 +8,8 @@ import controllers.routes object actions { + private val dataHoverText = data("hover-text") + def apply( userId: lila.user.User.ID, relation: Option[lila.relation.Relation], @@ -15,40 +17,52 @@ object actions { blocked: Boolean, signup: Boolean = false )(implicit ctx: Context) = - div(cls := "relation_actions")( + div(cls := "relation-actions btn-rack")( ctx.userId map { myId => (myId != userId) ?? frag( !blocked option frag( - a(dataHint := trans.challengeToPlay.txt(), href := s"${routes.Lobby.home()}?user=$userId#friend", cls := "icon button hint--bottom")( - iconTag("U") + a( + title := trans.challengeToPlay.txt(), + href := s"${routes.Lobby.home()}?user=$userId#friend", + cls := "btn-rack__btn", + dataIcon := "U" ), - a(dataHint := trans.composeMessage.txt(), href := s"${routes.Message.form()}?user=$userId", cls := "icon button hint--bottom")( - iconTag("c") + a( + title := trans.composeMessage.txt(), + href := s"${routes.Message.form()}?user=$userId", + cls := "btn-rack__btn", + dataIcon := "c" ) ), relation match { case None => frag( followable && !blocked option a( - cls := "icon button relation hint--bottom", + cls := "btn-rack__btn relation-button", href := routes.Relation.follow(userId), - dataHint := trans.follow.txt() - )(iconTag("h")), + title := trans.follow.txt(), + dataIcon := "h" + ), a( - cls := "icon button relation hint--bottom", + cls := "btn-rack__btn relation-button", href := routes.Relation.block(userId), - dataHint := trans.block.txt() - )(iconTag("k")) + title := trans.block.txt(), + dataIcon := "k" + ) + ) + case Some(true) => a( + dataIcon := "h", + cls := "btn-rack__btn relation-button text hover-text", + href := routes.Relation.unfollow(userId), + st.title := trans.following.txt(), + dataHoverText := trans.unfollow.txt() + ) + case Some(false) => a( + dataIcon := "k", + cls := "btn-rack__btn relation-button text hover-text", + href := routes.Relation.unblock(userId), + st.title := trans.blocked.txt(), + dataHoverText := trans.unblock.txt() ) - case Some(true) => - a(cls := "button relation hover_text", href := routes.Relation.unfollow(userId))( - iconTag("h")(cls := "base text")(trans.following()), - iconTag("h")(cls := "hover text")(trans.unfollow()) - ) - case Some(false) => - a(cls := "button relation hover_text", href := routes.Relation.unblock(userId))( - iconTag("k")(cls := "base text")(trans.blocked()), - iconTag("k")(cls := "hover text")(trans.unblock()) - ) } ) } getOrElse { diff --git a/app/views/relation/bits.scala b/app/views/relation/bits.scala new file mode 100644 index 0000000000..36e705746c --- /dev/null +++ b/app/views/relation/bits.scala @@ -0,0 +1,78 @@ +package views.html.relation + +import play.api.mvc.Call + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator +import lila.relation.Related +import lila.user.User + +import controllers.routes + +object bits { + + def followers(u: User, pag: Paginator[Related], nbFollowing: Int)(implicit ctx: Context) = + layout(s"${u.username} • ${trans.nbFollowers.pluralSameTxt(pag.nbResults)}")( + div(cls := "box__top")( + h1(userLink(u, withOnline = false)), + div(cls := "actions")( + trans.nbFollowers.pluralSame(pag.nbResults), + " ", amp, " ", + a(href := routes.Relation.following(u.username))(trans.nbFollowing.pluralSame(nbFollowing)) + ) + ), + pagTable(pag, routes.Relation.followers(u.username)) + ) + + def following(u: User, pag: Paginator[Related], nbFollowers: Int)(implicit ctx: Context) = + layout(s"${u.username} • ${trans.nbFollowing.pluralSameTxt(pag.nbResults)}")( + div(cls := "box__top")( + h1(userLink(u, withOnline = false)), + div(cls := "actions")( + trans.nbFollowing.pluralSame(pag.nbResults), + " ", amp, " ", + a(href := routes.Relation.followers(u.username))(trans.nbFollowers.pluralSame(nbFollowers)) + ) + ), + pagTable(pag, routes.Relation.following(u.username)) + ) + + def blocks(u: User, pag: Paginator[Related])(implicit ctx: Context) = + layout(s"${u.username} • ${trans.blocks.pluralSameTxt(pag.nbResults)}")( + div(cls := "box__top")( + h1(userLink(u, withOnline = false)), + div(cls := "actions")( + trans.blocks.pluralSame(pag.nbResults) + ) + ), + pagTable(pag, routes.Relation.blocks()) + ) + + def layout(title: String)(content: Modifier*)(implicit ctx: Context) = + views.html.base.layout( + title = title, + moreCss = cssTag("relation"), + moreJs = infiniteScrollTag + ) { + main(cls := "box page-small")(content) + } + + private def pagTable(pager: Paginator[Related], call: Call)(implicit ctx: Context) = + table(cls := "slist")( + if (pager.nbResults > 0) + tbody(cls := "infinitescroll")( + pagerNextTable(pager, np => addQueryParameter(call.url, "page", np)), + pager.currentPageResults.map { r => + tr(cls := "paginated")( + td(userLink(r.user)), + td(showBestPerf(r.user)), + td(trans.nbGames.pluralSame(r.user.count.game)), + td(actions(r.user.id, relation = r.relation, followable = r.followable, blocked = false)) + ) + } + ) + else tbody(tr(td(colspan := 2)("None found.", br))) + ) +} diff --git a/app/views/relation/blocks.scala.html b/app/views/relation/blocks.scala.html deleted file mode 100644 index cb5b04dd35..0000000000 --- a/app/views/relation/blocks.scala.html +++ /dev/null @@ -1,12 +0,0 @@ -@(u: User, pag: Paginator[lila.relation.Related])(implicit ctx: Context) - -@user.layout(title = u.username + " - " + trans.blocks.pluralSameTxt(pag.nbResults)) { -
    -

    - @userLink(u, withOnline = false) - @trans.blocks.pluralSame(pag.nbResults) -

    - @user.simpleTable(pag, routes.Relation.blocks()) -
    -} - diff --git a/app/views/relation/followers.scala.html b/app/views/relation/followers.scala.html deleted file mode 100644 index 5b33c5263d..0000000000 --- a/app/views/relation/followers.scala.html +++ /dev/null @@ -1,13 +0,0 @@ -@(u: User, pag: Paginator[lila.relation.Related], nbFollowing: Int)(implicit ctx: Context) - -@user.layout(title = u.username + " - " + trans.nbFollowers.pluralSameTxt(pag.nbResults)) { -
    -

    - @userLink(u, withOnline = false) - @trans.nbFollowers.pluralSame(pag.nbResults) - & - @trans.nbFollowing.pluralSame(nbFollowing) -

    - @user.simpleTable(pag, routes.Relation.followers(u.username)) -
    -} diff --git a/app/views/relation/following.scala.html b/app/views/relation/following.scala.html deleted file mode 100644 index 16887c424a..0000000000 --- a/app/views/relation/following.scala.html +++ /dev/null @@ -1,13 +0,0 @@ -@(u: User, pag: Paginator[lila.relation.Related], nbFollowers: Int)(implicit ctx: Context) - -@user.layout(title = u.username + " - " + trans.nbFollowing.pluralSameTxt(pag.nbResults)) { -
    -

    - @userLink(u, withOnline = false) - @trans.nbFollowing.pluralSame(pag.nbResults) - & - @trans.nbFollowers.pluralSame(nbFollowers) -

    - @user.simpleTable(pag, routes.Relation.following(u.username)) -
    -} diff --git a/app/views/relation/mini.scala b/app/views/relation/mini.scala index 339a824710..41d91a8aa1 100644 --- a/app/views/relation/mini.scala +++ b/app/views/relation/mini.scala @@ -14,18 +14,23 @@ object mini { followable: Boolean, relation: Option[lila.relation.Relation] = None )(implicit ctx: Context) = relation match { - case None if followable && !blocked => - a(cls := "relation button", href := s"${routes.Relation.follow(userId)}?mini=1")( - iconTag("h", trans.follow()) - ) - case Some(true) => - a(cls := "relation button hint--bottom", dataHint := trans.unfollow.txt(), href := s"${routes.Relation.unfollow(userId)}?mini=1")( - iconTag("h", trans.following()) - ) - case Some(false) => - a(cls := "relation button hint--bottom hover_text", dataHint := trans.unblock.txt(), href := s"${routes.Relation.unblock(userId)}?mini=1")( - iconTag("k", trans.blocked()) - ) + case None if followable && !blocked => a( + cls := "btn-rack__btn relation-button text", + dataIcon := "h", + href := s"${routes.Relation.follow(userId)}?mini=1" + )(trans.follow()) + case Some(true) => a( + cls := "btn-rack__btn relation-button text", + title := trans.unfollow.txt(), + href := s"${routes.Relation.unfollow(userId)}?mini=1", + dataIcon := "h" + )(trans.following()) + case Some(false) => a( + cls := "btn-rack__btn relation-button text", + title := trans.unblock.txt(), + href := s"${routes.Relation.unblock(userId)}?mini=1", + dataIcon := "k" + )(trans.blocked()) case _ => emptyFrag } } diff --git a/app/views/relay/create.scala.html b/app/views/relay/create.scala.html deleted file mode 100644 index f538bf785e..0000000000 --- a/app/views/relay/create.scala.html +++ /dev/null @@ -1,10 +0,0 @@ -@(form: Form[_])(implicit ctx: Context) - -@formLayout("New live broadcast") { -
    -

    New live broadcast

    -
    - @inForm(form) -
    -
    -} diff --git a/app/views/relay/edit.scala.html b/app/views/relay/edit.scala.html deleted file mode 100644 index e6a382a258..0000000000 --- a/app/views/relay/edit.scala.html +++ /dev/null @@ -1,10 +0,0 @@ -@(r: lila.relay.Relay, form: Form[_])(implicit ctx: Context) - -@formLayout(r.name) { -
    -

    Edit "@r.name"

    -
    - @inForm(form) -
    -
    -} diff --git a/app/views/relay/form.scala b/app/views/relay/form.scala new file mode 100644 index 0000000000..1bf86ed51f --- /dev/null +++ b/app/views/relay/form.scala @@ -0,0 +1,55 @@ +package views.html.relay + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object form { + + def create(form: Form[_])(implicit ctx: Context) = + layout("New live broadcast")( + h1("New live broadcast"), + inner(form, routes.Relay.create) + ) + + def edit(r: lila.relay.Relay, form: Form[_])(implicit ctx: Context) = + layout(r.name)( + h1("Edit ", r.name), + inner(form, routes.Relay.update(r.slug, r.id.value)) + ) + + private def layout(title: String)(body: Modifier*)(implicit ctx: Context) = + views.html.base.layout( + title = title, + moreCss = cssTag("relay.form"), + moreJs = frag( + flatpickrTag, + delayFlatpickrStart + ) + )( + main(cls := "page-small box box-pad")(body) + ) + + private def inner(form: Form[_], url: play.api.mvc.Call)(implicit ctx: Context) = + st.form(cls := "form3", action := url, method := "POST")( + form3.group(form("name"), frag("Event name"))(form3.input(_)(autofocus)), + form3.group(form("description"), raw("Event description"))(form3.textarea(_)(rows := 6)), + if (isGranted(_.Relay)) + form3.checkbox(form("official"), raw("Official lichess broadcast"), help = raw("Feature on /broadcast - for admins only").some) + else form3.hidden(form("official")), + form3.group(form("syncUrl"), raw("Source URL"))(form3.input(_, typ = "url")), + form3.split( + form3.group(form("startsAt"), raw("Start date UTC"), help = raw("Optional, if you know when the event starts").some, half = true)(form3.flatpickr(_)), + isGranted(_.Relay) option + form3.group(form("throttle"), raw("Throttle in seconds"), help = raw("Optional, to manually throttle requests. Min 2s, max 60s.").some, half = true)(form3.input(_, typ = "number")) + ), + form3.actions( + a(href := routes.Relay.index(1))(trans.cancel()), + form3.submit(trans.apply()) + ) + ) +} diff --git a/app/views/relay/formLayout.scala.html b/app/views/relay/formLayout.scala.html deleted file mode 100644 index ab0746ceb4..0000000000 --- a/app/views/relay/formLayout.scala.html +++ /dev/null @@ -1,12 +0,0 @@ -@(title: String)(body: Html)(implicit ctx: Context) - -@moreJs = { -@flatpickrTag -@delayFlatpickrStart -} - -@base.layout( -title = title, -moreCss = cssTags("flatpickr.css", "form3.css", "relay.css"), -moreJs = moreJs -)(body).toHtml diff --git a/app/views/relay/inForm.scala.html b/app/views/relay/inForm.scala.html deleted file mode 100644 index 56b87d9c16..0000000000 --- a/app/views/relay/inForm.scala.html +++ /dev/null @@ -1,20 +0,0 @@ -@(form: Form[_])(implicit ctx: Context) -@import lila.app.ui.ScalatagsTwirlForm._ - -@form3.group(form("name"), raw("Event name"))(form3.input(_)) -@form3.group(form("description"), raw("Event description"))(form3.textarea(_)(*.rows := 6)) - -@if(isGranted(_.Relay)) { -@form3.checkbox(form("official"), raw("Official lichess broadcast"), help = raw("Feature on /broadcast - for admins only").some) -} else { @form3.hidden(form("official")) } -@form3.group(form("syncUrl"), raw("Source URL"))(form3.input(_, typ = "url")) -@form3.split { -@form3.group(form("startsAt"), raw("Start date UTC"), help = raw("Optional, if you know when the event starts").some, half = true)(form3.flatpickr(_)) -@if(isGranted(_.Relay)) { -@form3.group(form("throttle"), raw("Throttle in seconds"), help = raw("Optional, to manually throttle requests. Min 2s, max 60s.").some, half = true)(form3.input(_, typ = "number")) -} -} -@form3.actionsHtml { -@trans.cancel() -@form3.submit(trans.apply.frag()) -} diff --git a/app/views/relay/index.scala b/app/views/relay/index.scala new file mode 100644 index 0000000000..e2ea1ba35d --- /dev/null +++ b/app/views/relay/index.scala @@ -0,0 +1,54 @@ +package views.html.relay + +import play.api.mvc.Call + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator + +import controllers.routes + +object index { + + def apply( + fresh: Option[lila.relay.Relay.Fresh], + pager: Paginator[lila.relay.Relay.WithStudyAndLiked], + url: Call + )(implicit ctx: Context) = { + + def sublist(name: String, relays: Seq[lila.relay.Relay.WithStudyAndLiked]) = + relays.nonEmpty option st.section( + h2(name), + div(cls := "list")( + relays.map(show.widget(_)) + ) + ) + + views.html.base.layout( + title = "Live tournament broadcasts", + moreCss = cssTag("relay.index"), + moreJs = infiniteScrollTag + ) { + main(cls := "relay-index page-small box")( + div(cls := "box__top")( + h1("Live tournament broadcasts"), + a(href := routes.Relay.form, cls := "new button button-empty", title := "New Broadcast", dataIcon := "O") + ), + fresh.map { f => + frag( + sublist("Ongoing", f.started), + sublist("Upcoming", f.created) + ) + }, + st.section( + h2("Completed"), + div(cls := "infinitescroll")( + pager.currentPageResults.map { show.widget(_, "paginated") }, + pagerNext(pager, np => addQueryParameter(url.url, "page", np)) + ) + ) + ) + } + } +} diff --git a/app/views/relay/index.scala.html b/app/views/relay/index.scala.html deleted file mode 100644 index ef49fd6f7b..0000000000 --- a/app/views/relay/index.scala.html +++ /dev/null @@ -1,51 +0,0 @@ -@(fresh: Option[lila.relay.Relay.Fresh], pager: Paginator[lila.relay.Relay.WithStudyAndLiked], url: Call)(implicit ctx: Context) - -@sublist(name: String, relays: Seq[lila.relay.Relay.WithStudyAndLiked]) = { -@if(relays.nonEmpty) { -
    -

    @name

    -
    - @relays.map { r => -
    - @widget(r) -
    - } -
    -
    -} -} - -@title = @{ "Live tournament broadcasts [BETA]" } - -@base.layout( -title = title, -moreCss = cssTag("relay-list.css"), -moreJs = infiniteScrollTag) { -
    -
    -

    @title

    - - - -
    - @fresh.map { f => - @sublist("Ongoing", f.started) - @sublist("Upcoming", f.created) - } -
    -

    Completed

    -
    - @pager.currentPageResults.map { r => -
    - @widget(r) -
    - } - @pager.nextPage.map { np => -
    - -
    - } -
    -
    -
    -}.toHtml diff --git a/app/views/relay/show.scala b/app/views/relay/show.scala index a3cb0817fa..455aacdcbe 100644 --- a/app/views/relay/show.scala +++ b/app/views/relay/show.scala @@ -1,6 +1,8 @@ package views.html package relay +import play.api.libs.json.Json + import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ @@ -20,45 +22,34 @@ object show { streams: List[lila.streamer.Stream] )(implicit ctx: Context) = views.html.base.layout( title = r.name, - side = Some(frag( - div(cls := "side_box study_box"), - streams.map { s => - a(href := routes.Streamer.show(s.streamer.userId), cls := "context-streamer text side_box", dataIcon := "")( - usernameOrId(s.streamer.userId), - " is streaming" - ) - } - )), - chat = chat.frag.some, - underchat = Some(views.html.game.bits.watchers), - moreCss = cssTags("analyse.css", "study.css", "relay.css", "chat.css"), + moreCss = cssTag("analyse.study"), moreJs = frag( analyseTag, analyseNvuiTag, - embedJs(s"""lichess = lichess || {}; lichess.relay = { -relay: ${safeJsonValue(data.relay)}, -study: ${safeJsonValue(data.study)}, -data: ${safeJsonValue(data.analysis)}, -i18n: ${board.userAnalysisI18n()}, -tagTypes: '${lila.study.PgnTags.typesToString}', -userId: $jsUserIdString, -chat: ${ - chatOption.fold("null")(c => safeJsonValue(chat.json( - c.chat, - name = trans.chatRoom.txt(), - timeout = c.timeout, - writeable = ctx.userId.??(s.canChat), - public = false, - localMod = ctx.userId.??(s.canContribute) - ))) - }, -explorer: { -endpoint: "$explorerEndpoint", -tablebaseEndpoint: "$tablebaseEndpoint" -}, -socketUrl: "${routes.Relay.websocket(s.id.value, apiVersion.value)}", -socketVersion: $socketVersion -};""") + embedJsUnsafe(s"""lichess=window.lichess||{};lichess.relay=${ + safeJsonValue(Json.obj( + "relay" -> data.relay, + "study" -> data.study, + "data" -> data.analysis, + "i18n" -> board.userAnalysisI18n(), + "tagTypes" -> lila.study.PgnTags.typesToString, + "userId" -> ctx.userId, + "chat" -> chatOption.map(c => chat.json( + c.chat, + name = trans.chatRoom.txt(), + timeout = c.timeout, + writeable = ctx.userId.??(s.canChat), + public = false, + localMod = ctx.userId.??(s.canContribute) + )), + "explorer" -> Json.obj( + "endpoint" -> explorerEndpoint, + "tablebaseEndpoint" -> tablebaseEndpoint + ), + "socketUrl" -> routes.Relay.websocket(s.id.value, apiVersion.value).url, + "socketVersion" -> socketVersion.value + )) + }""") ), chessground = false, zoomable = true, @@ -67,9 +58,17 @@ socketVersion: $socketVersion url = s"$netBaseUrl${routes.Relay.show(r.slug, r.id.value).url}", description = shorten(r.description, 152) ).some - ) { - div(cls := "analyse cg-512")( - board.bits.domPreload(none) + )(frag( + main(cls := "analyse"), + views.html.study.bits.streamers(streams) + )) + + def widget(r: lila.relay.Relay.WithStudyAndLiked, extraCls: String = "")(implicit ctx: Context) = + div(cls := s"relay-widget $extraCls", dataIcon := "")( + a(cls := "overlay", href := routes.Relay.show(r.relay.slug, r.relay.id.value)), + div( + h3(r.relay.name), + p(r.relay.description) ) - } + ) } diff --git a/app/views/relay/widget.scala.html b/app/views/relay/widget.scala.html deleted file mode 100644 index 1cd0d7e30d..0000000000 --- a/app/views/relay/widget.scala.html +++ /dev/null @@ -1,7 +0,0 @@ -@(r: lila.relay.Relay.WithStudyAndLiked)(implicit ctx: Context) - -

    - - @r.relay.name - @r.relay.description -

    diff --git a/app/views/report/form.scala b/app/views/report/form.scala new file mode 100644 index 0000000000..349b005e20 --- /dev/null +++ b/app/views/report/form.scala @@ -0,0 +1,47 @@ +package views.html.report + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.user.User + +import controllers.routes + +object form { + + def apply(form: Form[_], reqUser: Option[User] = None, captcha: lila.common.Captcha)(implicit ctx: Context) = + views.html.base.layout( + title = trans.reportAUser.txt(), + moreCss = cssTag("form3-captcha"), + moreJs = captchaTag + ) { + main(cls := "page-small box box-pad report")( + h1(trans.reportAUser()), + st.form( + cls := "form3", + action := s"${routes.Report.create()}${reqUser.??(u => "?username=" + u.username)}", + method := "post" + )( + form3.globalError(form), + form3.group(form("username"), trans.user(), klass = "field_to") { f => + reqUser.map { user => + frag(userLink(user), form3.hidden(f, user.id.some)) + }.getOrElse { + div(form3.input(f, klass = "user-autocomplete")(dataTag := "span")) + } + }, + form3.group(form("reason"), trans.reason()) { f => + form3.select(f, translatedReasonChoices, trans.whatIsIheMatter.txt().some) + }, + form3.group(form("text"), trans.description(), help = trans.reportDescriptionHelp().some)(form3.textarea(_)(rows := 8)), + views.html.base.captcha(form, captcha), + form3.actions( + a(href := routes.Lobby.home())(trans.cancel()), + form3.submit(trans.send()) + ) + ) + ) + } +} diff --git a/app/views/report/form.scala.html b/app/views/report/form.scala.html deleted file mode 100644 index 271f29b6e0..0000000000 --- a/app/views/report/form.scala.html +++ /dev/null @@ -1,30 +0,0 @@ -@(form: Form[_], reqUser: Option[User] = None, captcha: lila.common.Captcha)(implicit ctx: Context) -@import lila.app.ui.ScalatagsTwirlForm._ - -@title = @{ trans.reportAUser.txt() } - -@base.layout(title = title, moreCss = cssTags("report.css", "form3.css")) { -
    -

    @title

    -
    - @form3.globalError(form) - @form3.group(form("username"), trans.user.frag(), klass = "field_to") { f => - @reqUser.map { user => - @userLink(user) - @form3.hidden(f, user.id.some) - }.getOrElse { -
    @form3.inputHtml(f, klass = "user-autocomplete")(*.dataTag := "span")
    - } - } - @form3.group(form("reason"), trans.reason.frag()) { f => - @form3.select(f, translatedReasonChoices, trans.whatIsIheMatter.txt().some) - } - @form3.group(form("text"), trans.description.frag(), help = trans.reportDescriptionHelp.frag().some)(form3.textarea(_)(*.rows := 8)) - @base.captcha(form, captcha).toHtml - @form3.actionsHtml { - @trans.cancel() - @form3.submit(trans.send.frag()) - } -
    -
    -}.toHtml diff --git a/app/views/report/list.scala b/app/views/report/list.scala new file mode 100644 index 0000000000..ecc2c6788b --- /dev/null +++ b/app/views/report/list.scala @@ -0,0 +1,111 @@ +package views.html.report + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.report.Report.WithSuspect + +import controllers.routes + +object list { + + def apply( + reports: List[lila.report.Report.WithSuspect], + filter: String, + counts: lila.report.Room.Counts, + streamers: Int + )(implicit ctx: Context) = views.html.base.layout( + title = "Reports", + moreCss = cssTag("mod.report") + ) { + main(cls := "page-menu")( + views.html.mod.menu("report"), + div(id := "report_list", cls := "page-menu__content box")( + div(cls := "header")( + i(cls := "icon"), + span(cls := "tabs")( + a( + href := routes.Report.listWithFilter("all"), + cls := List("new" -> (counts.sum > 0), "active" -> (filter == "all")) + )( + countTag(counts.sum > 0 option counts.sum), + "All" + ), + lila.report.Room.all.map { room => + a( + href := routes.Report.listWithFilter(room.key), + cls := List( + "new" -> counts.value.contains(room), + "active" -> (filter == room.key), + s"room-${room.key}" -> true + ) + )( + countTag(counts.get(room)), + room.name + ) + }, + streamers > 0 option + a(href := s"${routes.Streamer.index()}?requests=1", cls := "new")( + countTag(streamers), + "Streamers" + ) + ) + ), + table(cls := "slist slist-pad see")( + thead( + tr( + th("Report"), + th("By"), + th + ) + ), + tbody( + reports.map { + case WithSuspect(r, sus, _) if !r.isTrollOrInsult || isGranted(_.Shadowban) => + tr(cls := List("new" -> r.open))( + td( + reportScore(r.score), + strong(r.reason.name.capitalize), + br, + userLink(sus.user, params = "?mod"), + br, + p(cls := "perfs")(showBestPerfs(sus.user, 2)), + views.html.user.mod.userMarks(sus.user, none) + ), + td(cls := "atoms")( + r.bestAtoms(3).map { atom => + div(cls := "atom")( + span(cls := "head")( + reportScore(atom.score), + " ", userIdLink(atom.by.value.some), + " ", momentFromNowOnce(atom.at) + ), + p(cls := List( + "text" -> true, + "large" -> (atom.text.size > 100 || atom.text.lines.size > 3) + ))(shorten(atom.text, 200)) + ) + }, + r.atoms.size > 3 option i(cls := "more")("And ", (r.atoms.size - 3), " more") + ), + td( + r.processedBy map { u => + st.form(action := routes.Report.inquiry(r.id), method := "post", cls := "reopen")( + button(tpe := "submit", dataIcon := "G", cls := "text button button-metal")("Re-open") + ) + } getOrElse st.form(action := routes.Report.inquiry(r.id), method := "post", cls := "inquiry")( + button(tpe := "submit", dataIcon := "G", cls := "button button-metal") + ), + st.form(action := routes.Report.process(r.id), method := "post", cls := "cancel")( + button(tpe := "submit", cls := "button button-thin button-empty")("Dismiss") + ) + ) + ) + case _ => emptyFrag + } + ) + ) + ) + ) + } +} diff --git a/app/views/report/list.scala.html b/app/views/report/list.scala.html deleted file mode 100644 index c2b8c9cbcb..0000000000 --- a/app/views/report/list.scala.html +++ /dev/null @@ -1,87 +0,0 @@ -@(reports: List[lila.report.Report.WithSuspect], filter: String, counts: lila.report.Room.Counts, streamers: Int)(implicit ctx: Context) - -@import lila.report.Report.WithSuspect - -@title = @{ "Reports" } - -@tab(reports: List[WithSuspect], room: lila.report.Room) = { - - @counts.get(room)@room.name -} - -@mod.layout( -title = title, -active = "report", -moreCss = cssTag("report.css")) { - -
    -
    - - - - @if(counts.sum > 0) {@counts.sum}All - @lila.report.Room.all.map { r => - @tab(reports, r) - } - @if(streamers > 0) { - - @streamersStreamers - - } - -
    - - - - - - - - - - @reports.map { - case WithSuspect(r, sus, _) if (!r.isTrollOrInsult || isGranted(_.Shadowban)) => { - - - - - - } - case _ => {} - } - -
    ReportBy
    - @reportScore(r.score) - @r.reason.name.capitalize
    - @userLink(sus.user, params = "?mod")
    -

    @showBestPerfs(sus.user, 2)

    - @user.mod.userMarks(sus.user, none) -
    - @r.bestAtoms(3).map { atom => -
    - @reportScore(atom.score) @userIdLink(atom.by.value.some), @momentFromNowOnce(atom.at) -

    - @shorten(atom.text, 200) -

    -
    - } - @if(r.atoms.size > 3) { - And @{r.atoms.size - 3} more - } -
    @r.processedBy.map { u => -
    - -
    - }.getOrElse { -
    - -
    -
    - -
    - } -
    -
    -} diff --git a/app/views/report/thanks.scala b/app/views/report/thanks.scala new file mode 100644 index 0000000000..b97daa5ef4 --- /dev/null +++ b/app/views/report/thanks.scala @@ -0,0 +1,56 @@ +package views.html.report + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.user.User + +import controllers.routes + +object thanks { + + def apply(userId: String, blocked: Boolean)(implicit ctx: Context) = { + + val title = "Thanks for the report" + + val moreJs = embedJsUnsafe(""" +$('button.report-block').one('click', function() { +var $button = $(this); +$button.find('span').text('Blocking...'); +$.ajax({ +url:$button.data('action'), +method:'post', +success: function() { +$button.find('span').text('Blocked!'); +} +}); +}); +""") + + views.html.base.layout(title = title, moreJs = moreJs) { + main(cls := "page-small box box-pad")( + h1(title), + p("The moderators will review it very soon, and take appropriate action."), + br, br, + !blocked option p( + "In the meantime, you can block this user: ", + button( + attr("data-action") := routes.Relation.block(userId), + cls := "report-block button", + tpe := "submit", + st.title := trans.block.txt() + )( + span(cls := "text", dataIcon := "k")("Block ", usernameOrId(userId)) + ) + ), + br, br, + p( + a(href := routes.Lobby.home)("Return to lichess homepage") + ) + ) + + } + } +} diff --git a/app/views/report/thanks.scala.html b/app/views/report/thanks.scala.html deleted file mode 100644 index 05bade1ce8..0000000000 --- a/app/views/report/thanks.scala.html +++ /dev/null @@ -1,39 +0,0 @@ -@(userId: String, blocked: Boolean)(implicit ctx: Context) - -@title = @{ "Thanks for the report" } - -@moreJs = { -@embedJs { -$('button.report-block').one('click', function() { -var $button = $(this); -$button.find('span').text('Blocking...'); -$.ajax({ -url:$button.data('action'), -method:'post', -success: function() { -$button.find('span').text('Blocked!'); -} -}); -}); -} -} - -@base.layout(title = title, moreCss = cssTag("report.css"), moreJs = moreJs) { - -
    -

    @title

    -

    The moderators will review it very soon, and take appropriate action.

    -


    - @if(!blocked) { - In the meantime, you can block this user: - -


    - } -

    - Return to lichess homepage -

    -
    - -}.toHtml diff --git a/app/views/round/bits.scala b/app/views/round/bits.scala index ed594a36cb..bc5afaa00a 100644 --- a/app/views/round/bits.scala +++ b/app/views/round/bits.scala @@ -1,80 +1,143 @@ package views.html package round -import play.twirl.api.Html - +import chess.variant.{ Variant, Crazyhouse } import lila.api.Context import lila.app.templating.Environment._ -import lila.game.{ Game, Pov, Player } import lila.app.ui.ScalatagsTemplate._ +import lila.game.{ Game, Pov, Player } import controllers.routes object bits { def layout( + variant: Variant, title: String, - side: Option[Frag], - chat: Option[Frag] = None, - underchat: Option[Frag] = None, - moreJs: Html = emptyHtml, + moreJs: Frag = emptyFrag, openGraph: Option[lila.app.ui.OpenGraph] = None, - moreCss: Html = emptyHtml, + moreCss: Frag = emptyFrag, chessground: Boolean = true, playing: Boolean = false, robots: Boolean = false - )(body: Html)(implicit ctx: Context) = + )(body: Frag)(implicit ctx: Context) = views.html.base.layout( title = title, - side = side.map(_.toHtml), - chat = chat, - underchat = underchat, openGraph = openGraph, moreJs = moreJs, - moreCss = moreCss, + moreCss = frag( + cssTag { if (variant == Crazyhouse) "round.zh" else "round" }, + ctx.blind option cssTag("round.nvui"), + moreCss + ), chessground = chessground, playing = playing, robots = robots, - asyncJs = true, + deferJs = true, zoomable = true )(body) - def underboard(game: Game, cross: Option[lila.game.Crosstable.WithMatchup])(implicit ctx: Context) = - div(cls := "underboard")( - div(cls := "center")( - cross map { c => - div(cls := "crosstable")( - views.html.game.crosstable(ctx.userId.fold(c)(c.fromPov), game.id.some) - ) - } - ) - ) + def crosstable(cross: Option[lila.game.Crosstable.WithMatchup], game: Game)(implicit ctx: Context) = + cross map { c => + views.html.game.crosstable(ctx.userId.fold(c)(c.fromPov), game.id.some) + } def underchat(game: Game)(implicit ctx: Context) = frag( - views.html.game.bits.watchers, - isGranted(_.ViewBlurs) option frag( + div( + cls := "chat__members none", + aria.live := "off", + aria.relevant := "additions removals text" + )( + span(cls := "number")(nbsp), + " ", + trans.spectators.txt().replace(":", ""), + " ", + span(cls := "list") + ), + isGranted(_.ViewBlurs) option div(cls := "round__mod")( game.players.filter(p => game.playerBlurPercent(p.color) > 30) map { p => - frag( - br, - span(cls := "mod blurs")( - playerLink(p, cssClass = s"is color-icon ${p.color.name}".some, withOnline = false, mod = true), - s"${p.blurs.nb}/${game.playerMoves(p.color)} blurs", - strong(game.playerBlurPercent(p.color), "%") - ) + div( + playerLink(p, cssClass = s"is color-icon ${p.color.name}".some, withOnline = false, mod = true), + s" ${p.blurs.nb}/${game.playerMoves(p.color)} blurs ", + strong(game.playerBlurPercent(p.color), "%") ) }, game.players flatMap { p => p.holdAlert.map(p ->) } map { - case (p, h) => frag( + case (p, h) => div( + playerLink(p, cssClass = s"is color-icon ${p.color.name}".some, mod = true, withOnline = false), + "hold alert", br, - span(cls := "mod hold")( - playerLink(p, cssClass = s"is color-icon ${p.color.name}".some, mod = true, withOnline = false), - "hold alert", - br, - s"(ply: ${h.ply}, mean: ${h.mean} ms, SD: ${h.sd})" - ), - br + s"(ply: ${h.ply}, mean: ${h.mean} ms, SD: ${h.sd})" ) } ) ) + + def others(playing: List[Pov], simul: Option[lila.simul.Simul])(implicit ctx: Context) = frag( + h3( + simul.map { s => + span(cls := "simul")( + a(href := routes.Simul.show(s.id))("SIMUL"), + span(cls := "win")(s.wins, " W"), " / ", + span(cls := "draw")(s.draws, " D"), " / ", + span(cls := "loss")(s.losses, " L"), " / ", + s.ongoing, " ongoing" + ) + } getOrElse trans.currentGames(), + "round-toggle-autoswitch" |> { id => + span(cls := "move-on switcher", st.title := trans.automaticallyProceedToNextGameAfterMoving.txt())( + label(`for` := id)(trans.autoSwitch()), + span(cls := "switch")( + input(st.id := id, cls := "cmn-toggle", tpe := "checkbox"), + label(`for` := id) + ) + ) + } + ), + div(cls := "now-playing")( + playing.partition(_.isMyTurn) |> { + case (myTurn, otherTurn) => + (myTurn ++ otherTurn.take(6 - myTurn.size)) take 9 map { pov => + a(href := routes.Round.player(pov.fullId), cls := pov.isMyTurn.option("my_turn"))( + gameFen(pov, withLink = false, withTitle = false, withLive = false), + span(cls := "meta")( + playerText(pov.opponent, withRating = false), + span(cls := "indicator")( + if (pov.isMyTurn) pov.remainingSeconds.fold[Frag](trans.yourTurn())(secondsFromNow(_, true)) + else nbsp + ) + ) + ) + } + } + ) + ) + + private[round] def side( + pov: Pov, + data: play.api.libs.json.JsObject, + tour: Option[lila.tournament.TourMiniView], + simul: Option[lila.simul.Simul], + userTv: Option[lila.user.User] = None, + bookmarked: Boolean + )(implicit ctx: Context) = views.html.game.side( + pov, + (data \ "game" \ "initialFen").asOpt[String].map(chess.format.FEN), + tour.map(_.tour), + simul = simul, + userTv = userTv, + bookmarked = bookmarked + ) + + def roundAppPreload(pov: Pov, controls: Boolean)(implicit ctx: Context) = + div(cls := "round__app")( + div(cls := "round__app__board main-board")(board.bits.domPreload(pov.some)), + div(cls := "round__app__table"), + div(cls := "ruser ruser-top user-link")(i(cls := "line"), a(cls := "text")(playerText(pov.opponent))), + div(cls := "ruser ruser-bottom user-link")(i(cls := "line"), a(cls := "text")(playerText(pov.player))), + div(cls := "rclock rclock-top preload")(div(cls := "time")(nbsp)), + div(cls := "rclock rclock-bottom preload")(div(cls := "time")(nbsp)), + div(cls := "rmoves")(div(cls := "moves")), + controls option div(cls := "rcontrols")(i(cls := "ddloader")) + ) } diff --git a/app/views/round/jsI18n.scala b/app/views/round/jsI18n.scala index c003f6d094..8320323b31 100644 --- a/app/views/round/jsI18n.scala +++ b/app/views/round/jsI18n.scala @@ -2,12 +2,11 @@ package views.html.round import lila.api.Context import lila.app.templating.Environment._ -import lila.common.String.html.safeJsonValue import lila.i18n.{ I18nKeys => trans } object jsI18n { - def apply(g: lila.game.Game)(implicit ctx: Context): String = safeJsonValue(i18nJsObject { + def apply(g: lila.game.Game)(implicit ctx: Context) = i18nJsObject { baseTranslations ++ { if (g.isCorrespondence) correspondenceTranslations else realtimeTranslations @@ -16,7 +15,7 @@ object jsI18n { } ++ { g.isTournament ?? tournamentTranslations } - }) + } private val correspondenceTranslations = Vector( trans.oneDay, diff --git a/app/views/round/others.scala.html b/app/views/round/others.scala.html deleted file mode 100644 index 97d76f31f6..0000000000 --- a/app/views/round/others.scala.html +++ /dev/null @@ -1,42 +0,0 @@ -@(playing: List[Pov], simul: Option[lila.simul.Simul])(implicit ctx: Context) -

    - @simul.map { s => - - SIMUL - @s.wins W/ - @s.draws D/ - @s.losses L/ - @s.ongoing ongoing - - }.getOrElse { - @trans.currentGames() - } - @defining("round-toggle-autoswitch") { id => - - - - - - - - } -

    -@defining(playing.partition(_.isMyTurn)) { -case (myTurn, otherTurn) => { -@defining(myTurn ++ otherTurn.take(6 - myTurn.size)) { povs => -@povs.take(9).map { pov => - - @gameFen(pov, withLink = false, withTitle = false, withLive = false) - - @playerText(pov.opponent, withRating = false) - - @if(pov.isMyTurn) { - @pov.remainingSeconds.fold(trans.yourTurn())(secondsFromNow(_, true)) - } else { } - - - -} -} -} -} diff --git a/app/views/round/player.scala b/app/views/round/player.scala index 0dfa39f188..eb427a71af 100644 --- a/app/views/round/player.scala +++ b/app/views/round/player.scala @@ -1,6 +1,8 @@ package views.html package round +import play.api.libs.json.Json + import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ @@ -29,33 +31,43 @@ object player { } bits.layout( + variant = pov.game.variant, title = s"${trans.play.txt()} ${if (ctx.pref.isZen) "ZEN" else playerText(pov.opponent)}", - side = game.side(pov, (data \ "game" \ "initialFen").asOpt[String].map(chess.format.FEN), tour.map(_.tour), simul, bookmarked = bookmarked), - chat = chatOption.map(_ => chat.frag), - underchat = Some(bits underchat pov.game), moreJs = frag( roundNvuiTag, roundTag, - embedJs(s"""window.customWS=true;window.onload=function(){ -LichessRound.boot({data:${safeJsonValue(data)},i18n:${jsI18n(pov.game)},userId:$jsUserId,chat:${jsOrNull(chatJson)} -${tour.flatMap(_.top).??(top => s",tour:${safeJsonValue(lila.tournament.JsonView.top(top, lightUser))}")} -}, document.getElementById('lichess'))}""") + embedJsUnsafe(s"""lichess=window.lichess||{};customWS=true;onload=function(){ +LichessRound.boot(${ + safeJsonValue(Json.obj( + "data" -> data, + "i18n" -> jsI18n(pov.game), + "userId" -> ctx.userId, + "chat" -> chatJson + ) ++ tour.flatMap(_.top).??(top => Json.obj( + "tour" -> lila.tournament.JsonView.top(top, lightUser) + ))) + })}""") ), - moreCss = cssTag("chat.css"), openGraph = povOpenGraph(pov).some, chessground = false, playing = true - ) { - frag( - div(cls := "round cg-512")( - board.bits.domPreload(pov.some), - bits.underboard(pov.game, cross) + )( + main(cls := "round")( + st.aside(cls := "round__side")( + bits.side(pov, data, tour, simul, bookmarked = bookmarked), + chatOption.map(_ => chat.frag) ), - (playing.nonEmpty || simul.nonEmpty) option - div(id := "now_playing", cls := List("other_games" -> true, "blindfold" -> ctx.pref.isBlindfold))( - others(playing, simul) - ) + bits.roundAppPreload(pov, true), + div(cls := "round__underboard")( + bits.crosstable(cross, pov.game), + (playing.nonEmpty || simul.exists(_ isHost ctx.me)) option + div(cls := List( + "round__now-playing" -> true, + "blindfold" -> ctx.pref.isBlindfold + ))(bits.others(playing, simul)) + ), + div(cls := "round__underchat")(bits underchat pov.game) ) - } + ) } } diff --git a/app/views/round/watcher.scala b/app/views/round/watcher.scala index becb90344e..f8b0c951a3 100644 --- a/app/views/round/watcher.scala +++ b/app/views/round/watcher.scala @@ -1,12 +1,14 @@ package views.html package round +import play.api.libs.json.Json + import lila.api.Context import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ import lila.common.HTTPRequest import lila.common.String.html.safeJsonValue import lila.game.Pov -import lila.app.ui.ScalatagsTemplate._ import controllers.routes @@ -28,24 +30,52 @@ object watcher { } bits.layout( + variant = pov.game.variant, title = gameVsText(pov.game, withRatings = true), - side = game.side(pov, (data \ "game" \ "initialFen").asOpt[String].map(chess.format.FEN), tour.map(_.tour), simul = simul, userTv = userTv, bookmarked = bookmarked), - chat = chat.frag.some, - underchat = Some(bits underchat pov.game), moreJs = frag( roundNvuiTag, roundTag, - embedJs(s"""window.customWS = true; window.onload = function() { -LichessRound.boot({ data: ${safeJsonValue(data)}, i18n: ${jsI18n(pov.game)}, chat: ${jsOrNull(chatJson)} }, document.getElementById('lichess'))}""") + embedJsUnsafe(s"""lichess=window.lichess||{};customWS=true;onload=function(){ +LichessRound.boot(${ + safeJsonValue(Json.obj( + "data" -> data, + "i18n" -> jsI18n(pov.game), + "chat" -> chatJson + )) + })}""") ), - moreCss = cssTag("chat.css"), openGraph = povOpenGraph(pov).some, chessground = false - ) { - div(cls := "round cg-512")( - board.bits.domPreload(pov.some), - bits.underboard(pov.game, cross) + )( + main(cls := "round")( + st.aside(cls := "round__side")( + bits.side(pov, data, tour, simul, userTv, bookmarked), + chatOption.map(_ => chat.frag) + ), + bits.roundAppPreload(pov, false), + div(cls := "round__underboard")(bits.crosstable(cross, pov.game)), + div(cls := "round__underchat")(bits underchat pov.game) ) - } + ) } + + def crawler(pov: Pov, initialFen: Option[chess.format.FEN], pgn: chess.format.pgn.Pgn)(implicit ctx: Context) = + bits.layout( + variant = pov.game.variant, + title = gameVsText(pov.game, withRatings = true), + openGraph = povOpenGraph(pov).some, + chessground = false + )(frag( + main(cls := "round")( + st.aside(cls := "round__side")( + game.side(pov, initialFen, none, simul = none, userTv = none, bookmarked = false), + div(cls := "for-crawler")( + h1(titleGame(pov.game)), + p(describePov(pov)), + div(cls := "pgn")(pgn.render) + ) + ), + div(cls := "round__board main-board")(board.bits.domPreload(pov.some)) + ) + )) } diff --git a/app/views/round/watcherBot.scala.html b/app/views/round/watcherBot.scala.html deleted file mode 100644 index 39ef54f1d9..0000000000 --- a/app/views/round/watcherBot.scala.html +++ /dev/null @@ -1,20 +0,0 @@ -@(pov: Pov, initialFen: Option[chess.format.FEN], pgn: chess.format.pgn.Pgn)(implicit ctx: Context) - -@title = @{ s"${playerText(pov.player)} vs ${playerText(pov.opponent)} in ${pov.gameId}" } - -@round.bits.layout( -title = title, -side = views.html.game.side(pov, initialFen, none, simul = none, userTv = none, bookmarked = false), -chat = none, -underchat = Some(views.html.game.bits.watchers), -chessground = false, -openGraph = povOpenGraph(pov).some) { -
    - @board.bits.domPreload(pov.some).toHtml -
    -

    @titleGame(pov.game)

    -

    @describePov(pov)

    -
    @pgn.render
    -
    -
    -}.toHtml diff --git a/app/views/search/bits.scala b/app/views/search/bits.scala new file mode 100644 index 0000000000..36f2c32303 --- /dev/null +++ b/app/views/search/bits.scala @@ -0,0 +1,168 @@ +package views.html.search + +import play.api.data.Form +import org.joda.time.DateTime +import org.joda.time.format.DateTimeFormat + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.gameSearch.{ Query, Sorting } + +private object bits { + + private val dateFormatter = DateTimeFormat.forPattern("YYYY-MM-dd"); + private val dateMin = "2011-01-01" + private def dateMinMax: List[Modifier] = List(min := dateMin, max := dateFormatter.print(DateTime.now)) + + def of(form: Form[_])(implicit ctx: Context) = new { + + def dataReqs = List("winner", "loser", "white", "black").map { f => + data(s"req-$f") := ~form("players")(f).value + } + + def colors(hide: Boolean) = + chess.Color.all.map { color => + tr(cls := List(s"${color.name}User user-row" -> true, "none" -> hide))( + th(label(`for` := form3.id(form("players")(color.name)))(color.fold(trans.white, trans.black)())), + td(cls := "single")( + st.select(id := form3.id(form("players")(color.name)), name := form("players")(color.name).name)( + option(cls := "blank", value := "") + ) + ) + ) + } + + def winner(hide: Boolean) = tr(cls := List("winner user-row" -> true, "none" -> hide))( + th(label(`for` := form3.id(form("players")("winner")))(trans.winner())), + td(cls := "single")( + st.select(id := form3.id(form("players")("winner")), name := form("players")("winner").name)( + option(cls := "blank", value := "") + ) + ) + ) + + def loser(hide: Boolean) = tr(cls := List("loser user-row" -> true, "none" -> hide))( + th(label(`for` := form3.id(form("players")("loser")))("Loser")), + td(cls := "single")( + st.select(id := form3.id(form("players")("loser")), name := form("players")("loser").name)( + option(cls := "blank", value := "") + ) + ) + ) + + def rating = tr( + th(label(trans.rating(), " ", span(cls := "help", title := "The average rating of both players")("(?)"))), + td( + div(cls := "half")("From ", form3.select(form("ratingMin"), Query.averageRatings, "".some)), + div(cls := "half")("To ", form3.select(form("ratingMax"), Query.averageRatings, "".some)) + ) + ) + + def hasAi = tr( + th(label(`for` := form3.id(form("hasAi")))(trans.opponent(), " ", span(cls := "help", title := "Whether the player's opponent was human or a computer")("(?)"))), + td(cls := "single opponent")(form3.select(form("hasAi"), Query.hasAis, "".some)) + ) + + def aiLevel = tr(cls := "aiLevel none")( + th(label("A.I. level")), + td( + div(cls := "half")("From ", form3.select(form("aiLevelMin"), Query.aiLevels, "".some)), + div(cls := "half")("To ", form3.select(form("aiLevelMax"), Query.aiLevels, "".some)) + ) + ) + + def source = tr( + th(label(`for` := form3.id(form("source")))("Source")), + td(cls := "single")(form3.select(form("source"), Query.sources, "".some)) + ) + + def perf = tr( + th(label(`for` := form3.id(form("perf")))(trans.variant())), + td(cls := "single")(form3.select(form("perf"), Query.perfs, "".some)) + ) + + def mode = tr( + th(label(`for` := form3.id(form("mode")))(trans.mode())), + td(cls := "single")(form3.select(form("mode"), Query.modes, "".some)) + ) + + def turns = tr( + th(label("Number of turns")), + td( + div(cls := "half")("From ", form3.select(form("turnsMin"), Query.turns, "".some)), + div(cls := "half")("To ", form3.select(form("turnsMax"), Query.turns, "".some)) + ) + ) + + def duration = tr( + tr( + th(label(trans.duration())), + td( + div(cls := "half")("From ", form3.select(form("durationMin"), Query.durations, "".some)), + div(cls := "half")("To ", form3.select(form("durationMax"), Query.durations, "".some)) + ) + ) + ) + + def clockTime = tr( + th(label("Clock initial time")), + td( + div(cls := "half")("From ", form3.select(form("clock")("initMin"), Query.clockInits, "".some)), + div(cls := "half")("To ", form3.select(form("clock")("initMax"), Query.clockInits, "".some)) + ) + ) + + def clockIncrement = tr( + th(label("Clock increment")), + td( + div(cls := "half")("From ", form3.select(form("clock")("incMin"), Query.clockIncs, "".some)), + div(cls := "half")("To ", form3.select(form("clock")("incMax"), Query.clockIncs, "".some)) + ) + ) + + def status = tr( + th(label(`for` := form3.id(form("status")))("Result")), + td(cls := "single")(form3.select(form("status"), Query.statuses, "".some)) + ) + + def winnerColor = tr( + th(label(`for` := form3.id(form("winnerColor")))("Winner color")), + td(cls := "single")(form3.select(form("winnerColor"), Query.winnerColors, "".some)) + ) + + def date = tr(cls := "date")( + th(label("Date")), + td( + div(cls := "half")("From ", form3.input(form("dateMin"), "date")(dateMinMax: _*)), + div(cls := "half")("To ", form3.input(form("dateMax"), "date")(dateMinMax: _*)) + ) + ) + + def sort = tr( + th(label("Sort")), + td( + div(cls := "half")("By ", form3.select(form("sort")("field"), Sorting.fields)), + div(cls := "half")("Order ", form3.select(form("sort")("order"), Sorting.orders)) + ) + ) + + def analysed = { + val field = form("analysed") + tr( + th(label(`for` := form3.id(field))("Analysis ", span(cls := "help", title := "Only games where a computer analysis is available")("(?)"))), + td(cls := "single")( + st.input( + tpe := "checkbox", + cls := "cmn-toggle", + id := form3.id(field), + name := field.name, + value := "1", + field.value.has("1") option checked + ), + label(`for` := form3.id(field)) + ) + ) + } + } +} diff --git a/app/views/search/index.scala b/app/views/search/index.scala new file mode 100644 index 0000000000..f896f6e141 --- /dev/null +++ b/app/views/search/index.scala @@ -0,0 +1,97 @@ +package views.html.search + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator +import lila.gameSearch.{ Query, Sorting } +import lila.user.User + +import controllers.routes + +object index { + + def apply(form: Form[_], paginator: Option[Paginator[lila.game.Game]] = None, nbGames: Int)(implicit ctx: Context) = { + val commons = bits of form + import commons._ + views.html.base.layout( + title = trans.advancedSearch.txt(), + moreJs = frag( + jsTag("search.js"), + infiniteScrollTag + ), + moreCss = cssTag("search"), + openGraph = lila.app.ui.OpenGraph( + title = s"Search in ${nbGames.localize} chess games", + url = s"$netBaseUrl${routes.Search.index().url}", + description = s"Search in ${nbGames.localize} chess games using advanced criterions" + ).some + ) { + main(cls := "box page-small search")( + h1(trans.advancedSearch()), + st.form( + rel := "nofollow", + cls := "box__pad search__form", + action := s"${routes.Search.index()}#results", + method := "GET" + )(dataReqs)( + globalError(form), + table( + tr( + th(label(trans.players())), + td(cls := "usernames")(List("a", "b").map { p => + div(cls := "half")(form3.input(form("players")(p))(tpe := "text")) + }) + ), + colors(hide = true), + winner(hide = true), + loser(hide = true), + rating, + hasAi, + aiLevel, + source, + perf, + mode, + turns, + duration, + clockTime, + clockIncrement, + status, + winnerColor, + date, + sort, + analysed, + tr( + th, + td(cls := "action")( + button(tpe := "submit", cls := "button")(trans.search()), + div(cls := "wait")( + spinner, + "Searching in ", nbGames.localize, " games" + ) + ) + ) + ) + ), + div(cls := "search__result", id := "results")( + paginator.map { pager => + val permalink = a(cls := "permalink", href := routes.Search.index(), rel := "nofollow")("Permalink") + if (pager.nbResults > 0) frag( + div(cls := "search__status box__pad")( + strong(pager.nbResults.localize, " games found"), " • ", + permalink + ), + div(cls := "search__rows")( + pagerNext(pager, np => routes.Search.index(np).url), + views.html.game.widgets(pager.currentPageResults) + ) + ) + else div(cls := "search__status box__pad")(strong("No game found"), " • ", permalink) + } + ) + ) + } + } +} diff --git a/app/views/search/index.scala.html b/app/views/search/index.scala.html deleted file mode 100644 index 38404088fd..0000000000 --- a/app/views/search/index.scala.html +++ /dev/null @@ -1,240 +0,0 @@ -@(form: Form[_], paginator: Option[Paginator[Game]] = None, nbGames: Int)(implicit ctx: Context) - -@import lila.gameSearch.{ Query, Sorting } - -@moreCss = { -@cssTags("search.css", "flatpickr.css") -} -@moreJs = { -@nonAsyncFlatpickrTag -@jsTag("search.js") -@infiniteScrollTag -} - -@base.layout( -title = trans.advancedSearch.txt(), -moreJs = moreJs, -moreCss = moreCss, -openGraph = lila.app.ui.OpenGraph( -title = s"Search in ${nbGames.localize} chess games", -url = s"$netBaseUrl${routes.Search.index().url}", -description = s"Search in ${nbGames.localize} chess games using advanced criterions").some) { -
    -

    @trans.advancedSearch()

    - -
    - @paginator.map { pager => - @if(pager.nbResults > 0) { -
    - @pager.nbResults.localize games found • - • -
    -
    - @pager.nextPage.map { n => - - }.getOrElse { -
    - } - @game.widgets(pager.currentPageResults).toHtml -
    - } else { -
    - No game found - - -
    - } - } -
    -
    -}.toHtml diff --git a/app/views/search/user.scala b/app/views/search/user.scala new file mode 100644 index 0000000000..07bce9ee1d --- /dev/null +++ b/app/views/search/user.scala @@ -0,0 +1,59 @@ +package views.html.search + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.gameSearch.{ Query, Sorting } +import lila.user.User + +import controllers.routes + +object user { + + def apply(u: User, form: Form[_])(implicit ctx: Context) = { + val commons = bits of form + import commons._ + st.form( + rel := "nofollow", + cls := "search__form", + action := routes.User.games(u.username, "search"), + method := "GET" + )(dataReqs)( + table( + date, + rating, + turns, + duration, + clockTime, + clockIncrement, + source, + perf, + mode + ), + table( + hasAi, + aiLevel, + tr(cls := "opponentName")( + th(label(`for` := form3.id(form("players")("b")))("Opponent name")), + td(cls := "usernames")( + st.input(tpe := "hidden", value := u.id, name := "players.a"), + form3.input(form("players")("b"))(tpe := "text") + ) + ), + winner(hide = false), + loser(hide = false), + colors(hide = false), + status, + winnerColor, + sort, + analysed, + tr(cls := "action")( + th, + td(button(cls := "button")(trans.search())) + ) + ) + ) + } +} diff --git a/app/views/search/user.scala.html b/app/views/search/user.scala.html deleted file mode 100644 index c057973d4f..0000000000 --- a/app/views/search/user.scala.html +++ /dev/null @@ -1,188 +0,0 @@ -@(u: User, form: Form[_])(implicit ctx: Context) - -@import lila.gameSearch.{ Query, Sorting } - - diff --git a/app/views/setup/bits.scala b/app/views/setup/bits.scala index c40dd9d9b2..99543f5105 100644 --- a/app/views/setup/bits.scala +++ b/app/views/setup/bits.scala @@ -17,18 +17,18 @@ private object bits { div(cls := "fen_position optional_config")( frag( div(cls := "fen_form", dataValidateUrl := s"""${routes.Setup.validateFen()}${strict.??("?strict=1")}""")( - a(cls := "button thin hint--bottom", dataHint := trans.boardEditor.txt(), href := url)(iconTag("m")), - form3.input(field)(st.placeholder := trans.pasteTheFenStringHere.txt()) + form3.input(field)(st.placeholder := trans.pasteTheFenStringHere.txt()), + a(cls := "button button-empty", dataIcon := "m", title := trans.boardEditor.txt(), href := url) ), a(cls := "board_editor", href := url)( span(cls := "preview")( validFen.map { vf => div( - cls := "mini_board parse_fen is2d", + cls := "mini-board cg-board-wrap parse-fen is2d", dataColor := vf.color.name, dataFen := vf.fen.value, dataResizable := "1" - )(miniBoardContent) + )(div(cls := "cg-board")) } ) ) @@ -38,7 +38,7 @@ private object bits { def renderVariant(form: Form[_], variants: List[SelectChoice])(implicit ctx: Context) = div(cls := "variant label_select")( - renderLabel(form("variant"), trans.variant.frag()), + renderLabel(form("variant"), trans.variant()), renderSelect(form("variant"), variants.filter { case (id, _, _) => ctx.noBlind || lila.game.Game.blindModeVariants.exists(_.id.toString == id) }) @@ -53,7 +53,7 @@ private object bits { case (value, name, title) => option( st.value := value, st.title := title, - selected := field.value.exists(v => compare(v, value)).option(true) + field.value.exists(v => compare(v, value)) option selected )(name) } ) @@ -67,11 +67,11 @@ private object bits { id := s"$prefix${field.id}_${key}", st.name := field.name, value := key, - checked := field.value.has(key).option(true) + field.value.has(key) option checked ), label( - cls := List("required" -> true, "hint--top" -> hint.isDefined), - dataHint := hint, + cls := "required", + title := hint, `for` := s"$prefix${field.id}_$key" )(name) ) diff --git a/app/views/setup/filter.scala b/app/views/setup/filter.scala index 3d0248bbf9..c9e0c22cef 100644 --- a/app/views/setup/filter.scala +++ b/app/views/setup/filter.scala @@ -13,8 +13,9 @@ object filter { import bits._ - def apply(form: Form[_], filter: lila.setup.FilterConfig)(implicit ctx: Context) = - st.form(action := routes.Setup.filter(), novalidate := true)( + def apply(form: Form[_], filter: lila.setup.FilterConfig)(implicit ctx: Context) = frag( + cssTag("lobby.setup"), + st.form(action := routes.Setup.filter(), novalidate)( table( tbody( tr(cls := "variant")( @@ -32,9 +33,9 @@ object filter { ctx.me.map { me => tr( td(trans.ratingRange()), - td(cls := "rating_range_config")( + td( label(cls := "range")("? - ?"), - div(cls := "rating_range")( + div(cls := "rating-range")( renderInput(form("ratingRange"))( dataMin := RatingRange.min, dataMax := RatingRange.max @@ -50,10 +51,11 @@ object filter { renderInput(form("ratingRange")) ), div(cls := "actions")( - button(`type` := "submit", cls := "reset button text", dataIcon := "k")(trans.reset()), - button(`type` := "submit", cls := "submit button text", dataIcon := "E")(trans.apply()) + button(tpe := "submit", cls := "button button-empty button-red text reset", dataIcon := "k")(trans.reset()), + button(tpe := "submit", cls := "button button-green text apply", dataIcon := "E")(trans.apply()) ) ) + ) def renderCheckboxes( form: Form[_], @@ -75,12 +77,12 @@ object filter { checks: List[String], content: Frag, hint: Option[String] - ) = label(cls := "hover", title := hint)( + ) = label(title := hint)( input( - `type` := "checkbox", + tpe := "checkbox", name := s"${form(key).name}[$index]", st.value := value, - checked := checks.has(value).option(true) + checks.has(value) option checked )(content) ) } diff --git a/app/views/setup/forms.scala b/app/views/setup/forms.scala index 9494658319..d5fe6ec0b0 100644 --- a/app/views/setup/forms.scala +++ b/app/views/setup/forms.scala @@ -2,7 +2,6 @@ package views.html.setup import play.api.data.Form import play.api.mvc.Call -import play.twirl.api.Html import lila.api.Context import lila.app.templating.Environment._ @@ -20,7 +19,7 @@ object forms { def hook(form: Form[_])(implicit ctx: Context) = layout( form, "hook", - trans.createAGame.frag(), + trans.createAGame(), routes.Setup.hook("uid-placeholder") ) { frag( @@ -31,11 +30,11 @@ object forms { renderRadios(form("mode"), translatedModeChoices) ), ctx.noBlind option div(cls := "optional_config")( - div(cls := "rating_range_config slider")( - trans.ratingRange.frag(), + div(cls := "rating-range-config slider")( + trans.ratingRange(), ": ", span(cls := "range")("? - ?"), - div(cls := "rating_range")( + div(cls := "rating-range")( renderInput(form("ratingRange"))( dataMin := RatingRange.min, dataMax := RatingRange.max @@ -48,25 +47,26 @@ object forms { } def ai(form: Form[_], ratings: Map[Int, Int], validFen: Option[lila.setup.ValidFen])(implicit ctx: Context) = - layout(form, "ai", trans.playWithTheMachine.frag(), routes.Setup.ai) { + layout(form, "ai", trans.playWithTheMachine(), routes.Setup.ai) { frag( renderVariant(form, translatedAiVariantChoices), fenInput(form("fen"), true, validFen), renderTimeMode(form, lila.setup.AiConfig), if (ctx.blind) frag( - renderLabel(form("level"), trans.level.frag()), + renderLabel(form("level"), trans.level()), renderSelect(form("level"), lila.setup.AiConfig.levelChoices), blindSideChoice(form) ) else frag( - trans.level.frag(), + br, + trans.level(), div(cls := "level buttons")( div(id := "config_level")( renderRadios(form("level"), lila.setup.AiConfig.levelChoices) ), div(cls := "ai_info")( ratings.toList.map { - case (level, rating) => div(cls := s"${prefix}level_$level")(trans.aiNameLevelAiLevel.frag("A.I.", level)) + case (level, rating) => div(cls := s"${prefix}level_$level")(trans.aiNameLevelAiLevel("A.I.", level)) } ) ) @@ -85,7 +85,7 @@ object forms { "friend", (if (user.isDefined) trans.challengeToPlay else trans.playWithAFriend)(), routes.Setup.friend(user map (_.id)), - error.map(e => Html(e.replace("{{user}}", userIdLink(user.map(_.id)).toString))) + error.map(e => raw(e.replace("{{user}}", userIdLink(user.map(_.id)).toString))) )(frag( user.map { u => userLink(u, cssClass = "target".some) @@ -101,59 +101,56 @@ object forms { private def blindSideChoice(form: Form[_])(implicit ctx: Context) = ctx.blind option frag( - renderLabel(form("color"), trans.side.frag()), + renderLabel(form("color"), trans.side()), renderSelect(form("color").copy(value = "random".some), translatedSideChoices) ) private def layout( form: Form[_], typ: String, - title: Frag, + titleF: Frag, route: Call, error: Option[Frag] = None )(fields: Frag)(implicit ctx: Context) = - div( - cls := s"""lichess_overboard game_config${error.isDefined ?? " error"}""", - dataRandomColorVariants, - dataType := typ, - dataAnon := ctx.isAnon.option("1") - )( - a(href := routes.Lobby.home, cls := "close icon", st.title := trans.cancel.txt(), dataIcon := "L"), - h2(title), - error.map { e => - frag( - p(cls := "error")(e), - br, - a(href := routes.Lobby.home, cls := "button text", dataIcon := "L")(trans.cancel.txt()) - ) - }.getOrElse { - st.form(action := route, method := "post", novalidate := true)( + div(cls := error.isDefined option "error")( + h2(titleF), + error.map { e => + frag( + p(cls := "error")(e), + br, + a(href := routes.Lobby.home, cls := "button text", dataIcon := "L")(trans.cancel.txt()) + ) + }.getOrElse { + st.form(action := route, method := "post", novalidate, + dataRandomColorVariants, + dataType := typ, + dataAnon := ctx.isAnon.option("1"))( fields, if (ctx.blind) button(tpe := "submit")("Create the game") - else div(cls := "color_submits")( + else div(cls := "color-submits")( translatedSideChoices.map { case (key, name, _) => button( - disabled := typ == "hook" option true, + (typ == "hook") option disabled, tpe := "submit", - dataHint := ctx.noBlind option name, - cls := s"button hint--bottom $key", + title := name, + cls := s"color-submits__button button button-metal $key", st.name := "color", value := key )(i) } ) ) - }, - ctx.me.ifFalse(ctx.blind).map { me => - div(cls := "ratings")( - lila.rating.PerfType.nonPuzzle.map { perfType => - div(cls := perfType.key)( - trans.perfRatingX.frag( - Html(s"""${me.perfs(perfType.key).map(_.intRating).getOrElse("?")} ${perfType.name}""") - ) + }, + ctx.me.ifFalse(ctx.blind).map { me => + div(cls := "ratings")( + lila.rating.PerfType.nonPuzzle.map { perfType => + div(cls := perfType.key)( + trans.perfRatingX( + raw(s"""${me.perfs(perfType.key).map(_.intRating).getOrElse("?")} ${perfType.name}""") ) - } - ) - } - ) + ) + } + ) + } + ) } diff --git a/app/views/simul/bits.scala b/app/views/simul/bits.scala index ef9b844323..b86c85146e 100644 --- a/app/views/simul/bits.scala +++ b/app/views/simul/bits.scala @@ -5,29 +5,29 @@ import play.api.libs.json.Json import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ -import lila.common.String.html.safeJsonValue import controllers.routes object bits { - def jsI18n()(implicit ctx: Context) = safeJsonValue(i18nJsObject(baseTranslations)) + def link(simulId: lila.simul.Simul.ID): Frag = + a(href := routes.Simul.show(simulId))("Simultaneous exhibition") + + def jsI18n()(implicit ctx: Context) = i18nJsObject(baseTranslations) def notFound()(implicit ctx: Context) = - layout(title = trans.noSimulFound.txt()) { - div(id := "simul")( - div(cls := "content_box small_box faq_page")( - h1(trans.noSimulFound.frag()), - br, br, - trans.noSimulExplanation.frag(), - br, br, - a(href := routes.Simul.home())(trans.returnToSimulHomepage.frag()) + views.html.base.layout( + title = trans.noSimulFound.txt() + ) { + main(cls := "page-small box box-pad")( + h1(trans.noSimulFound()), + p(trans.noSimulExplanation()), + p(a(href := routes.Simul.home())(trans.returnToSimulHomepage())) ) - ) - } + } def homepageSpotlight(s: lila.simul.Simul)(implicit ctx: Context) = - a(href := routes.Simul.show(s.id), cls := "tour_spotlight little id_@s.id")( + a(href := routes.Simul.show(s.id), cls := "tour-spotlight little id_@s.id")( img(cls := "img icon", src := staticUrl("images/fire-silhouette.svg")), span(cls := "content")( span(cls := "name")(s.name, " simul"), @@ -40,17 +40,10 @@ object bits { ) def allCreated(simuls: List[lila.simul.Simul]) = - table(cls := "tournaments")( + table( simuls map { simul => tr( - td(cls := "name")( - a(cls := "text", href := routes.Simul.show(simul.id))( - simul.perfTypes map { pt => - span(dataIcon := pt.iconChar) - }, - simul.fullName - ) - ), + td(cls := "name")(a(href := routes.Simul.show(simul.id))(simul.fullName)), td(userIdLink(simul.hostId.some)), td(cls := "text", dataIcon := "p")(simul.clock.config.show), td(cls := "text", dataIcon := "r")(simul.applicants.size), @@ -66,26 +59,6 @@ object bits { sim.variants.map(_.name).mkString(", ") ) - private[simul] def layout( - title: String, - moreJs: Frag = emptyFrag, - moreCss: Frag = emptyFrag, - side: Option[Frag] = None, - chat: Option[Frag] = None, - underchat: Option[Frag] = None, - chessground: Boolean = true, - openGraph: Option[lila.app.ui.OpenGraph] = None - )(body: Frag)(implicit ctx: Context) = views.html.base.layout( - title = title, - moreJs = moreJs, - moreCss = frag(cssTag("simul.css"), moreCss), - side = side.map(_.toHtml), - chat = chat.map(_.toHtml), - underchat = underchat.map(_.toHtml), - chessground = chessground, - openGraph = openGraph - )(body) - private val baseTranslations = Vector( trans.finished, trans.withdraw, diff --git a/app/views/simul/form.scala b/app/views/simul/form.scala index 12365e780e..16606f4e03 100644 --- a/app/views/simul/form.scala +++ b/app/views/simul/form.scala @@ -15,35 +15,36 @@ object form { import config._ - bits.layout( + views.html.base.layout( title = trans.hostANewSimul.txt(), - moreCss = cssTag("form3.css") + moreCss = cssTag("simul.form") ) { - div(id := "simul", cls := "form")( - div(cls := "content_box small_box simul_box")( - h1(trans.hostANewSimul.frag()), - st.form(cls := "form3", action := routes.Simul.create(), method := "POST")( - br, br, - p(trans.whenCreateSimul.frag()), - br, br, - globalError(form), - form3.group(form("variant"), trans.simulVariantsHint.frag()) { f => - div(cls := "variants")( - views.html.setup.filter.renderCheckboxes(form, "variants", form.value.map(_.variants.map(_.toString)).getOrElse(Nil), translatedVariantChoicesWithVariants) - ) - }, - form3.split( - form3.group(form("clockTime"), raw("Clock initial time"), help = trans.simulClockHint.frag().some, half = true)(form3.select(_, clockTimeChoices)), - form3.group(form("clockIncrement"), raw("Clock increment"), half = true)(form3.select(_, clockIncrementChoices)) - ), - form3.group(form("clockExtra"), trans.simulHostExtraTime.frag(), help = trans.simulAddExtraTime.frag().some)( + main(cls := "box box-pad page-small simul-form")( + h1(trans.hostANewSimul()), + st.form(cls := "form3", action := routes.Simul.create(), method := "POST")( + br, br, + p(trans.whenCreateSimul()), + br, br, + globalError(form), + form3.group(form("variant"), trans.simulVariantsHint()) { f => + div(cls := "variants")( + views.html.setup.filter.renderCheckboxes(form, "variants", form.value.map(_.variants.map(_.toString)).getOrElse(Nil), translatedVariantChoicesWithVariants) + ) + }, + form3.split( + form3.group(form("clockTime"), raw("Clock initial time"), help = trans.simulClockHint().some, half = true)(form3.select(_, clockTimeChoices)), + form3.group(form("clockIncrement"), raw("Clock increment"), half = true)(form3.select(_, clockIncrementChoices)) + ), + form3.split( + form3.group(form("clockExtra"), trans.simulHostExtraTime(), help = trans.simulAddExtraTime().some, half = true)( form3.select(_, clockExtraChoices) ), - form3.group(form("color"), raw("Host color for each game"))(form3.select(_, colorChoices)), - form3.actions( - a(href := routes.Simul.home())(trans.cancel.frag()), - form3.submit(trans.hostANewSimul.frag(), icon = "g".some) - ) + form3.group(form("color"), raw("Host color for each game"), half = true)(form3.select(_, colorChoices)) + ), + form3.group(form("text"), raw("Simul description"), help = frag("Anything you want to tell the participants?").some)(form3.textarea(_)(rows := 10)), + form3.actions( + a(href := routes.Simul.home())(trans.cancel()), + form3.submit(trans.hostANewSimul(), icon = "g".some) ) ) ) diff --git a/app/views/simul/home.scala b/app/views/simul/home.scala index 0313f424a3..572f9a4fb6 100644 --- a/app/views/simul/home.scala +++ b/app/views/simul/home.scala @@ -14,29 +14,34 @@ object home { opens: List[lila.simul.Simul], starteds: List[lila.simul.Simul], finisheds: List[lila.simul.Simul] - )(implicit ctx: Context) = bits.layout( + )(implicit ctx: Context) = views.html.base.layout( + moreCss = cssTag("simul.list"), + moreJs = embedJsUnsafe(s"""$$(function() { + lichess.StrongSocket.defaults.params.flag = 'simul'; + lichess.pubsub.on('socket.in.reload', () => { + $$('.simul-list__content').load('${routes.Simul.homeReload()}', lichess.pubsub.emit('content_loaded')); + }); +});"""), title = trans.simultaneousExhibitions.txt(), - side = div(cls := "help")( - trans.aboutSimul(), - " ", - a(cls := "more")(trans.more.frag(), "..."), - div(cls := "more none")( - img(src := staticUrl("images/fischer-simul.jpg"), alt := "Simul IRL with Bobby Fischer")( - em("[1964] ", trans.aboutSimulImage.frag()), - p(trans.aboutSimulRealLife.frag()), - p(trans.aboutSimulRules.frag()), - p(trans.aboutSimulSettings.frag()) - ) - ) - ).some, openGraph = lila.app.ui.OpenGraph( title = trans.simultaneousExhibitions.txt(), url = s"$netBaseUrl${routes.Simul.home}", description = trans.aboutSimul.txt() ).some ) { - div(id := "simul_list", dataHref := routes.Simul.homeReload())( - homeInner(opens, starteds, finisheds) + main(cls := "page-menu simul-list")( + st.aside(cls := "page-menu__menu simul-list__help")( + p(trans.aboutSimul()), + img(src := staticUrl("images/fischer-simul.jpg"), alt := "Simul IRL with Bobby Fischer")( + em("[1964] ", trans.aboutSimulImage()), + p(trans.aboutSimulRealLife()), + p(trans.aboutSimulRules()), + p(trans.aboutSimulSettings()) + ) + ), + div(cls := "page-menu__content simul-list__content")( + homeInner(opens, starteds, finisheds) + ) ) } } diff --git a/app/views/simul/homeInner.scala b/app/views/simul/homeInner.scala index d8c14eb2fd..ffebe18eec 100644 --- a/app/views/simul/homeInner.scala +++ b/app/views/simul/homeInner.scala @@ -15,78 +15,65 @@ object homeInner { starteds: List[lila.simul.Simul], finisheds: List[lila.simul.Simul] )(implicit ctx: Context) = - div(cls := "content_box simul_box no_padding")( - h1(trans.simultaneousExhibitions.frag()), - table(cls := "slist")( + div(cls := "box")( + h1(trans.simultaneousExhibitions()), + table(cls := "slist slist-pad")( thead( tr( - th(colspan := 2, cls := "large")(trans.createdSimuls.frag()), - th(trans.host.frag()), - th(trans.players.frag()) + th(trans.createdSimuls()), + th(cls := "host")(trans.host()), + th(cls := "players")(trans.players()) ) ), tbody( createds.map { sim => tr(cls := "scheduled")( - iconTd(sim), simTd(sim), simHost(sim), - td(cls := "text", dataIcon := "r")(sim.applicants.size) + td(cls := "players text", dataIcon := "r")(sim.applicants.size) ) }, ctx.isAuth option tr(cls := "create")( td(colspan := "4")( - a(href := routes.Simul.form(), cls := "action button text")(trans.hostANewSimul.frag()) + a(href := routes.Simul.form(), cls := "action button text")(trans.hostANewSimul()) ) ) ), starteds.nonEmpty option (frag( thead( tr( - th(colspan := 2, cls := "large")(trans.eventInProgress.frag()), - th(trans.host.frag()), - th(trans.players.frag()) + th(trans.eventInProgress()), + th(cls := "host")(trans.host()), + th(cls := "players")(trans.players()) ) ), starteds.map { sim => tr( - iconTd(sim), simTd(sim), simHost(sim), - td(cls := "text", dataIcon := "r")(sim.pairings.size) + td(cls := "players text", dataIcon := "r")(sim.pairings.size) ) } )), thead( tr( - th(colspan := 2, cls := "large")(trans.finished.frag()), - th(trans.host.frag()), - th(trans.players.frag()) + th(trans.finished()), + th(cls := "host")(trans.host()), + th(cls := "players")(trans.players()) ) ), tbody( finisheds.map { sim => tr( - iconTd(sim), simTd(sim), simHost(sim), - td(cls := "text", dataIcon := "r")(sim.pairings.size) + td(cls := "players text", dataIcon := "r")(sim.pairings.size) ) } ) ) ) - private def iconTd(sim: lila.simul.Simul) = - td(cls := List( - "variant_icons" -> true, - "rich" -> sim.variantRich - ))( - sim.perfTypes.map { pt => - span(cls := "is-gold", dataIcon := pt.iconChar) - } - ) - private def simTd(sim: lila.simul.Simul)(implicit ctx: Context) = td(cls := "header")( a(href := routes.Simul.show(sim.id))( diff --git a/app/views/simul/show.scala b/app/views/simul/show.scala index aba0e95f0e..845efa2c06 100644 --- a/app/views/simul/show.scala +++ b/app/views/simul/show.scala @@ -17,64 +17,59 @@ object show { data: play.api.libs.json.JsObject, chatOption: Option[lila.chat.UserChat.Mine], stream: Option[lila.streamer.Stream] - )(implicit ctx: Context) = bits.layout( + )(implicit ctx: Context) = views.html.base.layout( + moreCss = cssTag("simul.show"), title = sim.fullName, - side = Some(frag( - div(cls := "side_box padded")( - div(cls := "game_infos")( - div(cls := List( - "variant_icons" -> true, - "rich" -> sim.variantRich - ))(sim.perfTypes.map { pt => span(dataIcon := pt.iconChar) }), - span(cls := "clock")(sim.clock.config.show), - br, - div(cls := "setup")( - sim.variants.map(_.name).mkString(", "), - " • ", - trans.casual() - ), - trans.simulHostExtraTime(), - ": ", - pluralize("minute", sim.clock.hostExtraMinutes), - br, - trans.hostColorX(sim.color match { - case Some("white") => trans.white() - case Some("black") => trans.black() - case _ => trans.randomColor() - }) - ), - trans.by(usernameOrId(sim.hostId)), - " ", - momentFromNow(sim.createdAt) - ), - stream.map { s => - a( - href := routes.Streamer.show(s.streamer.userId), - cls := "context-streamer text side_box", - dataIcon := "" - )(usernameOrId(s.streamer.userId), " is streaming") - } - )), - underchat = Some(div( - cls := "watchers hidden", - aria.live := "off", - aria.relevant := "additions removals text" - )(span(cls := "list inline_userlist"))), - chat = views.html.chat.frag.some, moreJs = frag( jsAt(s"compiled/lichess.simul${isProd ?? (".min")}.js"), - embedJs(s"""lichess.simul={ -data:${safeJsonValue(data)}, -i18n:${bits.jsI18n()}, -socketVersion:${socketVersion.value}, -userId: $jsUserIdString, -chat: ${chatOption.fold("null")(c => safeJsonValue(views.html.chat.json(c.chat, name = trans.chatRoom.txt(), timeout = c.timeout, public = true)))}}""") - ), - moreCss = cssTags(List( - "chat.css" -> true, - "quote.css" -> sim.isCreated - )) + embedJsUnsafe(s"""lichess.simul=${ + safeJsonValue(Json.obj( + "data" -> data, + "i18n" -> bits.jsI18n(), + "socketVersion" -> socketVersion.value, + "userId" -> ctx.userId, + "chat" -> chatOption.map { c => + views.html.chat.json(c.chat, name = trans.chatRoom.txt(), timeout = c.timeout, public = true) + } + )) + }""") + ) ) { - div(id := "simul") + main(cls := "simul")( + st.aside(cls := "simul__side")( + div(cls := "simul__meta")( + div(cls := "game-infos")( + div(cls := "header")( + iconTag("f"), + div( + span(cls := "clock")(sim.clock.config.show), + div(cls := "setup")( + sim.variants.map(_.name).mkString(", "), + " • ", + trans.casual() + ) + ) + ), + trans.simulHostExtraTime(), + ": ", + pluralize("minute", sim.clock.hostExtraMinutes), + br, + trans.hostColorX(sim.color match { + case Some("white") => trans.white() + case Some("black") => trans.black() + case _ => trans.randomColor() + }) + ), + trans.by(usernameOrId(sim.hostId)), + " ", + momentFromNow(sim.createdAt) + ), + stream.map { s => + views.html.streamer.bits.contextual(s.streamer.userId) + }, + chatOption.isDefined option views.html.chat.frag + ), + div(cls := "simul__main box")(spinner) + ) } } diff --git a/app/views/site/api.scala.html b/app/views/site/bits.scala similarity index 51% rename from app/views/site/api.scala.html rename to app/views/site/bits.scala index dfe9f9e734..7f5cb65e8d 100644 --- a/app/views/site/api.scala.html +++ b/app/views/site/bits.scala @@ -1,5 +1,28 @@ -@() - +package views.html.site + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object bits { + + def getFishnet()(implicit ctx: Context) = + views.html.base.layout( + title = "fishnet API key request", + csp = defaultCsp.withGoogleForm.some + ) { + main( + iframe( + src := "https://docs.google.com/forms/d/e/1FAIpQLSeSAp51tSaW9JlPGVX0o8dcScAuxGMhNOL9eEUIfARGzpITmA/viewform?embedded=true", + style := "width:100%;height:1400px", + st.frameborder := 0 + )(spinner) + ) + } + + def api = raw(""" @@ -11,6 +34,7 @@ - + - +""") +} diff --git a/app/views/site/contact.scala b/app/views/site/contact.scala index 51fa367e9b..d97ea134ee 100644 --- a/app/views/site/contact.scala +++ b/app/views/site/contact.scala @@ -90,7 +90,7 @@ object contact { )), reopenLeaf("login"), Leaf("dns", "\"This site can’t be reached\"", frag( - p("If you can't reach lichess, and your browser says something like:"), + p("If you can't reach Lichess, and your browser says something like:"), ul( li("This site can't be reached."), li(strong("lichess.org"), "’s server IP address could not be found."), @@ -105,9 +105,9 @@ object contact { )) )), Branch("account", "I need account support", List( - Leaf("title", "I want my title displayed on lichess", frag( + Leaf("title", "I want my title displayed on Lichess", frag( p( - "To show your title on your lichess profile, and participate to Titled Arenas, ", + "To show your title on your Lichess profile, and participate to Titled Arenas, ", a(href := routes.Page.master)( "visit the title confirmation page" ), @@ -205,7 +205,7 @@ object contact { Leaf("appeal-cheat", "Engine or cheat mark", frag( p(s"If you have been marked as an engine, you may send an appeal to $contactEmail."), p( - "False positives do happen sometimes, and we're sorry about that.", + "False positives do happen sometimes, and we're sorry about that.", br, "If your appeal is legit, we will lift the ban ASAP." ), p( @@ -219,27 +219,27 @@ object contact { Leaf("appeal-other", "None of the above", frag( p(s"You may send an appeal to $contactEmail."), p( - "False positives do happen sometimes, and we're sorry about that.", + "False positives do happen sometimes, and we're sorry about that.", br, "If your appeal is legit, we will lift the ban or restriction ASAP." ) )) )), Branch("collab", "Collaboration, legal, commercial", List( - Leaf("monetize", "Monetizing lichess", frag( - p("We are not interested in any way of monetizing lichess."), + Leaf("monetize", "Monetizing Lichess", frag( + p("We are not interested in any way of monetizing Lichess."), p("We will never display any kind of ads, we won't track our players, and we won't sell or buy traffic or users."), p("Please do not email us about marketing, tracking, or advertising.") )), - Leaf("buy", "Buying lichess", frag( + Leaf("buy", "Buying Lichess", frag( p("We are not selling, to anyone, for any price. Ever.") )), - Leaf("authorize", "Authorization to use lichess", frag( - p("You are welcome to use lichess for your activity, even commercial."), - p("You can show it in your videos, and you can print screenshots of lichess in your books."), + Leaf("authorize", "Authorization to use Lichess", frag( + p("You are welcome to use Lichess for your activity, even commercial."), + p("You can show it in your videos, and you can print screenshots of Lichess in your books."), p("Credit is appreciated but not required.") )), Leaf("gdpr", "GDPR", frag( - p("If you are a European citizen, you may request the deletion of your lichess account."), + p("If you are a European citizen, you may request the deletion of your Lichess account."), p( "First, ", a(href := routes.Account.close)("close your account"), @@ -251,8 +251,8 @@ object contact { Leaf("contact-other", "None of the above", frag( p(s"Please send us an email at $contactEmail."), p( - "Please explain your request clearly and thoroughly.", - "State your lichess username, and any information that could help us help you." + "Please explain your request clearly and thoroughly. ", + "State your Lichess username, and any information that could help us help you." ) )) )) @@ -289,14 +289,13 @@ object contact { def apply()(implicit ctx: Context) = help.layout( title = "Contact", active = "contact", - moreCss = cssTags("contact.css"), - moreJs = embedJs("""location=location.hash||"#help-root"""") - )( - div(cls := "content_box small_box")( - h1(cls := "lichess_title")("Contact lichess"), - div(cls := "contact")( - renderedMenu - ) + moreCss = cssTag("contact"), + moreJs = embedJsUnsafe("""location=location.hash||"#help-root""""), + contentCls = "page box box-pad" + )(frag( + h1("Contact Lichess"), + div(cls := "contact")( + renderedMenu ) - ) + )) } diff --git a/app/views/site/faq.scala b/app/views/site/faq.scala index 8ca1fc4386..26ac2a7df1 100644 --- a/app/views/site/faq.scala +++ b/app/views/site/faq.scala @@ -19,146 +19,160 @@ object faq { def apply()(implicit ctx: Context) = help.layout( title = "Frequently Asked Questions", active = "faq", - moreCss = cssTags("faq.css") + moreCss = cssTag("faq") ) { - div(cls := "content_box small_box")( - div(cls := "faq")( - h1(cls := "lichess_title")("Frequently Asked Questions"), - h2("Lichess"), - question( - "name", - "Why is Lichess called Lichess?", - p("Lichess is a combination of live/light/libre and chess. It is pronounced 'lee-chess.'"), - p("Live because games are played and watched in real-time 24/7; light and libre for the fact that Lichess is open-source and unencumbered by proprietary junk that plagues other websites."), - p("Similarly, the source code for Lichess, ", a(href := "https://github.com/ornicar/lila")("lila"), ", stands for li[chess in sca]la, seeing as the bulk of Lichess is written in ", a(href := "https://www.scala-lang.org/")("Scala"), ", an intuitive programming language.") + main(cls := "faq small-page box box-pad")( + h1(cls := "lichess_title")("Frequently Asked Questions"), + h2("Lichess"), + question( + "name", + "Why is Lichess called Lichess?", + p("Lichess is a combination of live/light/libre and chess. It is pronounced ", em("lee-chess"), "."), + p("Live, because games are played and watched in real-time 24/7; light and libre for the fact that Lichess is open-source and unencumbered by proprietary junk that plagues other websites."), + p("Similarly, the source code for Lichess, ", a(href := "https://github.com/ornicar/lila")("lila"), ", stands for li[chess in sca]la, seeing as the bulk of Lichess is written in ", a(href := "https://www.scala-lang.org/")("Scala"), ", an intuitive programming language.") + ), + question( + "contributing", + "How can I contribute to Lichess?", + p("Lichess is powered by donations from patrons and the efforts of a team of volunteers."), + p("You can find out more about ", a(href := routes.Plan.index())("being a patron"), " (including a ", a(href := routes.Main.costs())("breakdown of our costs"), "). If you want to help Lichess by volunteering your time and skills, there are many ", a(href := routes.Page.help())("other ways to help"), ".") + ), + h2("Fair Play"), + question( + "marks", + "Why am I flagged for artificial rating manipulation (sandbagging and boosting) or computer assistance?", + p("Lichess has strong detection methods and a very thorough process for reviewing all the evidence and making a decision. The process often involves many moderators and can take a long time. Other than the mark itself, we will not go into details about evidence or the decision making process for individual cases. Doing so would make it easier to avoid detection in the future, and be an invitation to unproductive debates. That time and effort is better spent on other important cases. Users can appeal by emailing contact@lichess.org, but decisions are rarely overturned.") + ), + question( + "rating-refund", + "When am I eligible for the automatic rating refund from cheaters?", + p("One minute after a user is marked as engine, their 30 latest rated wins are taken (but only the games played in the latest 3 days). If you are the opponent in one of these games, you get a rating refund if your rating was not provisional. The rating refund will not be the full number of points lost if it would exceed ", em("your rating at the start of cheated game + points lost to cheater + 100"), ". (So, if you earned much rating after the games against the cheater, you might get no or only a partial refund). A refund will never exceed 200 points.") + ), + question( + "leaving", + "What is done about players leaving games without resigning?", + p("""If your opponent frequently aborts/leaves games, they get "play banned", which means they're temporarily banned from playing games. This is not publically indicated on their profile. If this behaviour continues, the length of the playban increases - and prolonged behaviour of this nature may lead to account closure.""") + ), + question( + "mod-application", + "How can I become a moderator?", + p("It’s not possible to apply to become a moderator. If we see someone who we think would be good as a moderator, we will contact them directly.") + ), + question( + "correspondence", + "Is correspondence different from normal chess?", + p("On Lichess, the main difference in rules for correspondence chess is that an opening book is allowed. The use of engines is still prohibited and will result in being flagged for engine assistance. Although ICCF allows engine use in correspondence, Lichess does not.") + ), + h2("Gameplay"), + question( + "acpl", + """What is "average centipawn loss"?""", + p("The centipawn is the unit of measure used in chess as representation of the advantage. A centipawn is equal to 1/100th of a pawn. Therefore 100 centipawns = 1 pawn. These values play no formal role in the game but are useful to players, and essential in computer chess, for evaluating positions."), + p("The top computer move will lose zero centipawns, but lesser moves will result in a deterioration of the position, measured in centipawns."), + p("This value can be used as an indicator of the quality of play. The fewer centipawns one loses per move, the stronger the play."), + p("The computer analysis on Lichess is powered by Stockfish.") + ), + question( + "timeout", + "Losing on time, drawing and insufficient material", + p("In the event of one player running out of time, that player will usually lose the game. However, the game is drawn if the position is such that the opponent cannot checkmate the player’s king by any possible series of legal moves (", a(href := "https://www.fide.com/fide/handbook.html?id=208&view=article")("FIDE handbook §6.9"), ")."), + p("Note that it can be possible to mate with a single knight or bishop if the opponent has pieces that could block the king.") + ), + question( + "en-passant", + "Why can a pawn capture another pawn when it is already passed? (en passant)", + p("""This is a legal move known as "en passant". The Wikipedia article gives a """, a(href := "https://en.wikipedia.org/wiki/En_passant")("good introduction.")), + p("It is described in section 3.7 (d) of the ", a(href := "https://www.fide.com/fide/handbook.html?id=171&view=article")("official rules"), ":"), + p(""""A pawn occupying a square on the same rank as and on an adjacent file to an opponent’s pawn which has just advanced two squares in one move from its original square may capture this opponent’s pawn as though the latter had been moved only one square. This capture is only legal on the move following this advance and is called an ‘en passant’ capture.""""), + p("See the ", a(href := s"${routes.Learn.index()}#/15")("Lichess training"), " on this move for some practice with it.") + ), + h2("Accounts"), + question( + "titles", + "What titles are there on Lichess?", + p( + "Lichess recognises all FIDE titles gained from OTB (over the board) play, as well as ", + a(href := "https://github.com/ornicar/lila/wiki/Handling-title-verification-requests")("many national master titles"), ".", + "Here is a list of FIDE titles:" ), - question( - "contributing", - "How can I contribute to Lichess?", - p("Lichess is powered by donations from patrons and the efforts of a team of volunteers."), - p("You can find out more about being a patron ", a(href := routes.Plan.index())("here"), " (including a breakdown of our costs). If you want to help Lichess by volunteering your time and skills, there are many ", a(href := routes.Page.help())("other ways to help"), ", listed in detail here.") + ul( + li("Grandmaster (GM)"), + li("International Master (IM)"), + li("FIDE Master (FM)"), + li("Candidate Master (CM)"), + li("Woman Grandmaster (WGM)"), + li("Woman International Master (WIM)"), + li("Woman FIDE Master (WFM)"), + li("Woman Candidate Master (WCM)") ), - h2("Fair Play"), - question( - "marks", - "Why am I flagged for artificial rating manipulation (sandbagging and boosting) or computer assistance?", - p("Lichess has strong detection methods and a very thorough process for reviewing all the evidence and making a decision. The process often involves many moderators and can take a long time. Other than the mark itself, we will not go into details about evidence or the decision making process for individual cases. Doing so would make it easier to avoid detection in the future, and be an invitation to unproductive debates. That time and effort is better spent on other important cases. Users can appeal by emailing contact@lichess.org, but decisions are rarely overturned.") + p("If you have an OTB title, you can apply to have this displayed on your account by completing the ", a(href := "https://docs.google.com/forms/d/e/1FAIpQLSd64rDqXOihJzPlBsQba75di5ioL-WMFhkInS2_vhVTvDtBag/viewform")("verification form"), ", including a clear image of an identifying document/card and a selfie of you holding the document/card."), + p("Verifying as a titled player on Lichess gives access to play in the Titled Arena events."), + p("Finally there is an honorary ", a(href := "#lm")("Lichess Master (LM)"), " title.") + ), + question( + "lm", + "How do I get the Lichess Master (LM) title?", + p("This honorific title is unofficial and only exists on Lichess."), + p("We award it to highly notable players who are good citizens of Lichess, at our discretion. You don't get the LM title, the LM title gets to you. If you qualify, you will get a message from us regarding it and the choice to accept or decline.") + ), + question( + "usernames", + "What can my username be?", + p("In general, usernames should not be: offensive, impersonating someone else, or advertising. You can read more about the ", a(href := "https://github.com/ornicar/lila/wiki/Username-policy")("guidelines"), ".") + ), + question( + "trophies", + "Unique trophies", + h4("The way of Berserk"), + p("That trophy is unique in the history of Lichess, nobody other than ", a(href := "https://lichess.org/@/hiimgosu")("hiimgosu"), " will ever have it."), + p("To get it, hiimgosu challenged himself to berserk and win 100% games of ", a(href := "https://lichess.org/tournament/cDyjj1nL")("a hourly bullet tournament"), "."), + h4("The Golden Zee"), + p("That trophy is unique in the history of Lichess, nobody other than ", a(href := "https://lichess.org/@/ZugAddict")("ZugAddict"), " will ever have it."), + p("ZugAddict was streaming and for the last 2 hours he had been trying to defeat A.I. level 8 in a 1+0 game, without success. Thibault told him that if he successfully did it on stream, he'd get a unique trophy. One hour later, he smashed Stockfish, and the promise was honoured.") + ), + h2("Lichess ratings"), + question( + "ratings", + "What rating system does Lichess use?", + p("Ratings are calculated using the Glicko-2 rating method developed by Mark Glickman. This is a very popular rating method, and is used by a significant number of chess organisations (FIDE being a notable counter-example, as they still use the dated Elo rating system)."), + p("""Fundamentally, Glicko ratings use "confidence intervals" when calculating and representing your rating. When you first start using the site, your rating starts at 1500 ± 700. The 1500 represents your rating, and the 700 represents the confidence interval."""), + p("Basically, the system is 90% sure that your rating is somewhere between 800 and 2200. It is incredibly uncertain. Because of this, when a player is just starting out, their rating will change very dramatically, potentially several hundred points at a time. But after some games against established players the confidence interval will narrow, and the amount of points gained/lost after each game will decrease."), + p("""Another point to note is that the confidence interval changes over time. If you win or lose many games (or rather "points") in a row, the confidence interval will increase allowing you to gain/lose points points more rapidly. This is because a winning/losing streak means that you are incorrectly rated/seeded and the rating system should compensate for that.""") + ), + question( + "provisional", + "Why is there a question mark (?) next to a rating?", + p("The question mark means the rating is provisional. Reasons include:"), + ul( + li("The player has not yet finished enough rated games against ", em("opponents of similar strength"), " in the rating category."), + li("The player's strength has recently improved or dropped significantly.") ), - question( - "rating-refund", - "When am I eligible for the automatic rating refund from cheaters?", - p("One minute after a user is marked as engine, their 30 latest rated wins are taken (but only the games played in the latest 3 days). If you are the opponent in one of these games, you get a rating refund if your rating was not provisional. The rating refund will not be the full number of points lost if it would exceed ", em("(your rating at the start of cheated game + points lost to cheater + 100)"), " (so, if you earned much rating after the games against the cheater, you might get no or only a partial refund). A refund will never exceed 200 points.") + p("Concretely, it means that the Glicko-2 deviation is greater than 110. The deviation is the level of confidence the system has in the rating. The lower the deviation, the more stable is a rating.") + ), + question( + "leaderboards", + "How do ranks and leaderboards work?", + p("In order to get on the ", a(href := routes.User.list())("rating leaderboards"), ", you must:"), + ol( + li("have played at least 30 rated games in a given rating,"), + li("have played a rated game within the last week for this rating,"), + li("be in the top 10 in this rating.") ), - question( - "leaving", - "What is done about players leaving games without resigning?", - p("""If your opponent frequently aborts/leaves games, they get "play banned" which means they're temporarily banned from playing games. There is no "public" banner on the profile, however, that marks the user as someone who aborts/leaves games. If this behaviour continues, the length of the playban increases - and prolonged behaviour of this nature may lead to account closure.""") - ), - question( - "mod-application", - "How can I become a moderator?", - p("It’s not possible to apply to become a moderator. If we see someone who we think would be good as a moderator, we will contact them directly.") - ), - question( - "correspondence", - "Is correspondence different from normal chess?", - p("On Lichess, the main difference in rules for correspondence chess is that an opening book is allowed. The use of engines is still prohibited and will result in being flagged for engine assistance. Although ICCF allows engine use in correspondence, Lichess does not.") - ), - h2("Gameplay"), - question( - "acpl", - """What is "average centipawn loss"?""", - p("The centipawn is the unit of measure used in chess as representation of the advantage. A centipawn is equal to 1/100th of a pawn. Therefore 100 centipawns = 1 pawn. These values play no formal role in the game but are useful to players, and essential in computer chess, for evaluating positions."), - p("A perfect move will lose zero centipawns, but lesser moves will result in a deterioration of the position, measured in centipawns."), - p("This value can be used as an indicator of the quality of play. The fewer centipawns one loses per move, the stronger the play."), - p("These numbers are provided by the computer analysis, which is powered by Stockfish.") - ), - question( - "timeout", - "Losing on time, drawing and insufficient material", - p("In the event of one player running out of time, that player will usually lose the game. However, the game is drawn if the position is such that the opponent cannot checkmate the player’s king by any possible series of legal moves. ", a(href := "https://www.fide.com/fide/handbook.html?id=208&view=article")("FIDE handbook (6.9)")) - ), - question( - "en-passant", - "Why can a pawn capture another pawn when it is already passed? (en passant)", - p("""This is a legal move known as "en passant". The Wikipedia article gives a """, a(href := "https://en.wikipedia.org/wiki/En_passant")("good introduction.")), - p("It is described in section 3.7 (d) of the ", a(href := "https://www.fide.com/fide/handbook.html?id=171&view=article")("official rules"), ":"), - p(""""A pawn occupying a square on the same rank as and on an adjacent file to an opponent’s pawn which has just advanced two squares in one move from its original square may capture this opponent’s pawn as though the latter had been moved only one square. This capture is only legal on the move following this advance and is called an ‘en passant’ capture.""""), - p("See the ", a(href := s"${routes.Learn.index()}#/15")("Lichess training"), " on this move for some practice with it.") - ), - h2("Accounts"), - question( - "titles", - "What titles are there on Lichess?", - p("Lichess recognises all FIDE titles gained from OTB (over the board) play, as well as many national master titles. The full list of FIDE titles is available here and is as follows:"), - ul( - li("Grandmaster (GM)"), - li("International Master (IM)"), - li("FIDE Master (FM)"), - li("Candidate Master (CM)"), - li("Woman Grandmaster (WGM)"), - li("Woman International Master (WIM)"), - li("Woman FIDE Master (WFM)"), - li("Woman Candidate Master (WCM)") - ), - p("Other titles currently recognised by Lichess are listed ", a(href := "https://github.com/ornicar/lila/wiki/Handling-title-verification-requests")("here"), "."), - p("If you have an OTB title, you can apply to have this displayed on your account by completing the ", a(href := "https://docs.google.com/forms/d/e/1FAIpQLSd64rDqXOihJzPlBsQba75di5ioL-WMFhkInS2_vhVTvDtBag/viewform")("verification form"), " here including a clear image of an identifying document/card and a selfie of you holding the document/card."), - p("Verifying as a titled player on Lichess gives access to play in the Titled Arena events."), - h4("Other titles: LM"), - p("""LM means "Lichess Master". This honorific title is unofficial and only exists on Lichess."""), - p("We award it to highly notable players who are good citizens of Lichess, at our discretion. You don't get the LM title, the LM title gets to you. If you qualify, you will get a message from us regarding it and the choice to accept or decline.") - ), - question( - "usernames", - "What can my username be?", - p("In general, usernames should not be: offensive, impersonating someone else, or advertising. You can read more about the ", a(href := "https://github.com/ornicar/lila/wiki/Username-policy")("guidelines"), ".") - ), - question( - "trophies", - "Unique trophies", - h4("The way of Berserk"), - p("That trophy is unique in the history of Lichess, nobody other than ", a(href := "https://lichess.org/@/hiimgosu")("hiimgosu"), " will ever have it."), - p("To get it, hiimgosu challenged himself to berserk and win 100% games of ", a(href := "https://lichess.org/tournament/cDyjj1nL")("a hourly bullet tournament"), "."), - h4("The Golden Zee"), - p("That trophy is unique in the history of Lichess, nobody other than ZugAddict will ever have it."), - p("ZugAddict was streaming and for the last 2 hours he had been trying to defeat A.I. level 8 in a 1+0 game, without success. Thibault told him that if he successfully did it on stream, he'd get a unique trophy. One hour later, he smashed Stockfish, and the promise was honoured.") - ), - h2("Lichess ratings"), - question( - "ratings", - "What rating system does Lichess use?", - p("Ratings are calculated using the Glicko-2 rating method developed by Mark Glickman. This is a very popular rating method, and is used by a significant amount of chess organisations (FIDE being a notable counter-example, as they still use the dated Elo rating system)."), - p("""Fundamentally, Glicko ratings use "confidence intervals" when calculating and representing your rating. When you first start using the site, your rating starts at 1500 ± 700. The 1500 represents your rating, and the 700 represents the confidence interval."""), - p("Basically, the system is 90% sure that your rating is somewhere between 800 and 2200. It is incredibly uncertain. Because of this, when a player is just starting out, their rating will change very dramatically, potentially several hundred points at a time. But after several games, the confidence interval will narrow, and the amount of points gained/lost after each game will lessen."), - p("""Another thing to note is that the confidence interval changes over time. If you win or lose many games (or rather "points") in a row, the confidence interval will increase allowing you to gain/lose points points more rapidly. This is because a winning/losing streak means that you are incorrectly rated/seeded and the rating system should compensate for that.""") - ), - question( - "provisional", - "Why is there a question mark (?) next to my rating?", - p("The question mark means the rating is provisional, because you have not yet played enough games in that category to have a reliable rating."), - p("Concretely, that means the Glicko-2 deviation is larger than 110. The deviation is the level of confidence the system has in the rating. The lower the deviation, the more stable is a rating.") - ), - question( - "leaderboards", - "How do ranks and leaderboards work?", - p("In order to get on the rating leaderboards at lichess.org/player, you must:"), - ol( - li("have played at least 30 rated games in a given rating,"), - li("have played a rated game within the last week for this rating,"), - li("be in the top 10 in this rating.") - ), - p("The 2nd requirement is so that players who no longer use their accounts stop populating leaderboards.") - ), - question( - "high-ratings", - "Why are ratings higher compared to other sites and organisations such as FIDE, USCF, the ICC, etc.?", - p("It is best not to think of ratings as absolute numbers, or compare them against other organisations. Different organisations have different levels of players, different rating systems (Elo, Glicko, Glicko-2, or a modified version of the aforementioned). These factors can drastically affect the absolute numbers (ratings)."), - p("""It's best to think of ratings as "relative" figures (as opposed to "absolute" figures). By this I mean: within a pool of players, their relative differences in ratings will help you estimate who will win/draw/loss, and how often. Saying "I have X rating" means nothing unless there are other players to compare that rating to.""") - ), - question( - "hide-ratings", - "How to hide ratings while playing?", - p("Enable Zen-mode by pressing ", em("z"), " during a game.") + p("The 2nd requirement is so that players who no longer use their accounts stop populating leaderboards.") + ), + question( + "high-ratings", + "Why are ratings higher compared to other sites and organisations such as FIDE, USCF and the ICC?", + p("It is best not to think of ratings as absolute numbers, or compare them against other organisations. Different organisations have different levels of players, different rating systems (Elo, Glicko, Glicko-2, or a modified version of the aforementioned). These factors can drastically affect the absolute numbers (ratings)."), + p("""It's best to think of ratings as "relative" figures (as opposed to "absolute" figures): Within a pool of players, their relative differences in ratings will help you estimate who will win/draw/lose, and how often. Saying "I have X rating" means nothing unless there are other players to compare that rating to.""") + ), + question( + "hide-ratings", + "How to hide ratings while playing?", + p( + "Enable Zen-mode in the ", + a(href := routes.Pref.form("game-display"))("display preferences"), + " or by pressing ", em("z"), " during a game." ) ) ) diff --git a/app/views/site/freeJs.scala b/app/views/site/freeJs.scala index cabe1df14d..4fbd00f791 100644 --- a/app/views/site/freeJs.scala +++ b/app/views/site/freeJs.scala @@ -7,42 +7,37 @@ import lila.app.ui.ScalatagsTemplate._ object freeJs { - private lazy val agpl = a(href := "https://www.gnu.org/licenses/agpl-3.0.en.html", cls := "blue")("AGPL-3.0+") + private lazy val agpl = a(href := "https://www.gnu.org/licenses/agpl-3.0.en.html")("AGPL-3.0+") - private def github(path: String) = a(href := s"https://github.com/ornicar/lila/tree/master/$path", cls := "blue")(path) + private def github(path: String) = a(href := s"https://github.com/ornicar/lila/tree/master/$path")(path) private val uiModules = List("site", "chat", "cli", "challenge", "notify", "learn", "insight", "editor", "puzzle", "round", "analyse", "lobby", "tournament", "tournamentSchedule", "tournamentCalendar", "simul", "perfStat", "dasher") - def apply(implicit ctx: Context) = message( - title = "LibreJS Validation Table", - back = false - ) { - frag( - p( - "Here's the ", - a(cls := "blue", href := "https://www.gnu.org/licenses/javascript-labels.en.html")( - "JavaScript License Web Labels" - ), - " table,", - br, - "where you can find the source code for the website' scripts." + def apply(): Frag = frag( + div(cls := "box__top")( + h1("JavaScript modules") + ), + p(cls := "box__pad")( + "Here are all frontend modules from ", + a(href := "https://github.com/ornicar/lila/tree/master/ui")("ornicar/lila ui"), + " in ", + a(href := "https://www.gnu.org/licenses/javascript-labels.en.html")("Web Labels"), + " compatible format:" + ), + table(id := "jslicense-labels1", cls := "slist slist-pad")( + thead( + tr(List("Script File", "License", "Source Code").map(th(_))) ), - br, br, - table(id := "jslicense-labels1", cls := "slist")( - thead( - tr(List("Script File", "License", "Source Code").map(th(_))) - ), - tbody( - uiModules map { module => - val file = s"lichess.$module.min.js" - tr( - td(a(href := assetUrl(s"compiled/$file"), cls := "blue")(file)), - td(agpl), - td(github(s"ui/$module/src")) - ) - } - ) + tbody( + uiModules map { module => + val file = s"lichess.$module.min.js" + tr( + td(a(href := assetUrl(s"compiled/$file"))(file)), + td(agpl), + td(github(s"ui/$module/src")) + ) + } ) ) - } + ) } diff --git a/app/views/site/getFishnet.scala.html b/app/views/site/getFishnet.scala.html deleted file mode 100644 index ed07a7d611..0000000000 --- a/app/views/site/getFishnet.scala.html +++ /dev/null @@ -1,9 +0,0 @@ -@()(implicit ctx: Context) - -@base.layout(title = "fishnet API key request", -csp = defaultCsp.withGoogleForm.some) { - -}.toHtml diff --git a/app/views/site/help.scala b/app/views/site/help.scala index 9c451326ec..0d7e236d5b 100644 --- a/app/views/site/help.scala +++ b/app/views/site/help.scala @@ -1,7 +1,4 @@ -package views -package html.site - -import play.twirl.api.Html +package views.html.site import lila.api.Context import lila.app.templating.Environment._ @@ -16,14 +13,33 @@ object help { layout( title = title, active = active, - moreCss = cssTag("page.css") - )(div(cls := "content_box small_box doc_box")( - h1(cls := "lichess_title")(title), + contentCls = "page box box-pad", + moreCss = cssTag("page") + )(frag( + h1(title), div(cls := "body")(raw(~doc.getHtml("doc.content", resolver))) )) } + def source(doc: io.prismic.Document, resolver: io.prismic.DocumentLinkResolver)(implicit ctx: Context) = { + val title = ~doc.getText("doc.title") + layout( + title = title, + active = "source", + moreCss = frag(cssTag("source")), + contentCls = "page" + )(frag( + div(cls := "box box-pad body")( + h1(title), + raw(~doc.getHtml("doc.content", resolver)) + ), + br, + div(cls := "box")(freeJs()) + )) + } + def webmasters()(implicit ctx: Context) = { + val baseUrl = "https://lichess.org" val parameters = frag( p("Parameters:"), ul( @@ -33,86 +49,116 @@ object help { ) layout( title = "Webmasters", - active = "webmasters" + active = "webmasters", + moreCss = cssTag("page"), + contentCls = "page" )(frag( - div(cls := "content_box small_box developers")( - h1(id := "embed-tv", cls := "lichess_title")("Embed Lichess TV in your site"), - raw(""""""), - p("Just add the following HTML to your site:"), - pre(""""""), - parameters - ), - br, - div(cls := "content_box small_box developers")( - h1(id := "embed-puzzle", cls := "lichess_title")("Embed the daily puzzle in your site"), - raw(""""""), - p("Just add the following HTML to your site:"), - pre(""""""), - parameters, - p("The text is automatically translated to your visitor's language.") - ), - br, - div(cls := "content_box small_box developers")( - h1("Embed a chess analysis in your site"), - raw(""""""), - p("Create ", a(href := routes.Study.allDefault(1), cls := "blue")("a study"), ", then click the share button to get the HTML code for the current chapter."), - pre(""""""), - parameters, - p("The text is automatically translated to your visitor's language.") - ), - br, - div(cls := "content_box small_box developers")( - h1("Embed a chess game in your site"), - raw(""""""), - p(raw("""On a game analysis page, click the "FEN & PGN" tab at the bottom, then """), "\"", em(trans.embedInYourWebsite(), "\".")), - pre(""""""), - parameters, - p("The text is automatically translated to your visitor's language.") - ), - br, - div(cls := "content_box small_box developers")( - h1("HTTP API"), - p(raw("""Lichess exposes a RESTish HTTP/JSON API that you are welcome to use. Read the HTTP API documentation.""")) - ), - br, - div(cls := "content_box small_box developers")( - h1(id := "widgets", cls := "lichess_title")("Lichess Widgets"), - p("Let your website/blog visitors know that you're playing on lichess!"), - p(raw("""See https://rubenwardy.com/lichess_widgets/ for widgets with your username and rating.""")) - ) - )) + div(cls := "box box-pad developers body") { + val args = """style="width: 400px; height: 444px;" allowtransparency="true" frameborder="0"""" + frag( + h1(id := "embed-tv")("Embed Lichess TV in your site"), + div(cls := "center")(raw(s"""""")), + p("Add the following HTML to your site:"), + p(cls := "copy-zone")( + input( + id := "tv-embed-src", + cls := "copyable autoselect", + value := s"""""" + ), + button(title := "Copy code", cls := "copy button", dataRel := "tv-embed-src", dataIcon := "\"") + ), + parameters + ) + }, + br, + div(cls := "box box-pad developers body") { + val args = """style="width: 400px; height: 444px;" allowtransparency="true" frameborder="0"""" + frag( + h1(id := "embed-puzzle")("Embed the daily puzzle in your site"), + div(cls := "center")(raw(s"""""")), + p("Add the following HTML to your site:"), + p(cls := "copy-zone")( + input( + id := "puzzle-embed-src", + cls := "copyable autoselect", + value := s"""""" + ), + button(title := "Copy code", cls := "copy button", dataRel := "puzzle-embed-src", dataIcon := "\"") + ), + parameters, + p("The text is automatically translated to your visitor's language.") + ) + }, + br, + div(cls := "box box-pad developers body") { + val args = """style="width: 600px; height: 397px;" frameborder="0"""" + frag( + h1("Embed a chess analysis in your site"), + raw(s""""""), + p("Create ", a(href := routes.Study.allDefault(1))("a study"), ", then click the share button to get the HTML code for the current chapter."), + parameters, + p("The text is automatically translated to your visitor's language.") + ) + }, + br, + div(cls := "box box-pad developers body") { + val args = """style="width: 600px; height: 397px;" frameborder="0"""" + frag( + h1("Embed a chess game in your site"), + raw(s""""""), + p(raw("""On a game analysis page, click the "FEN & PGN" tab at the bottom, then """), "\"", em(trans.embedInYourWebsite(), "\".")), + parameters, + p("The text is automatically translated to your visitor's language.") + ) + }, + br, + div(cls := "box box-pad developers body")( + h1("HTTP API"), + p(raw("""Lichess exposes a RESTish HTTP/JSON API that you are welcome to use. Read the HTTP API documentation.""")) + ), + br, + div(cls := "box box-pad developers body")( + h1(id := "widgets")("Lichess Widgets"), + p("Let your website/blog visitors know that you're playing on lichess!"), + p(raw("""See https://rubenwardy.com/lichess_widgets/ for widgets with your username and rating.""")) + ) + )) } def layout( title: String, active: String, - moreCss: Html = emptyHtml, - moreJs: Html = emptyHtml + contentCls: String = "", + moreCss: Frag = emptyFrag, + moreJs: Frag = emptyFrag )(body: Frag)(implicit ctx: Context) = views.html.base.layout( title = title, moreCss = moreCss, - moreJs = moreJs, - menu = Some(frag( - a(cls := active.activeO("about"), href := routes.Page.about)(trans.aboutX("lichess.org")), - a(cls := active.activeO("faq"), href := routes.Main.faq)("FAQ"), - a(cls := active.activeO("contact"), href := routes.Main.contact)(trans.contact()), - a(cls := active.activeO("tos"), href := routes.Page.tos)(trans.termsOfService()), - a(cls := active.activeO("privacy"), href := routes.Page.privacy)(trans.privacy()), - a(cls := active.activeO("master"), href := routes.Page.master)("Title verification"), - div(cls := "sep"), - a(cls := active.activeO("help"), href := routes.Page.help)(trans.contribute()), - a(cls := active.activeO("thanks"), href := routes.Page.thanks)(trans.thankYou()), - div(cls := "sep"), - a(cls := active.activeO("webmasters"), href := routes.Main.webmasters)(trans.webmasters()), - a(cls := active.activeO("database"), href := "https://database.lichess.org")(trans.database(), raw(""" """)), - a(cls := active.activeO("api"), href := routes.Api.index)("API", raw(""" """)), - a(cls := active.activeO("source"), href := "https://github.com/ornicar/lila")("Source code", raw(""" """)), - div(cls := "sep"), - a(href := routes.Main.lag)("Is Lichess lagging?") - )) - )(body) + moreJs = moreJs + ) { + val sep = div(cls := "sep") + val external = frag(" ", i(dataIcon := "0")) + def activeCls(c: String) = cls := active.activeO(c) + main(cls := "page-menu")( + st.nav(cls := "page-menu__menu subnav")( + a(activeCls("about"), href := routes.Page.about)(trans.aboutX("lichess.org")), + a(activeCls("faq"), href := routes.Main.faq)("FAQ"), + a(activeCls("contact"), href := routes.Main.contact)(trans.contact()), + a(activeCls("tos"), href := routes.Page.tos)(trans.termsOfService()), + a(activeCls("privacy"), href := routes.Page.privacy)(trans.privacy()), + a(activeCls("master"), href := routes.Page.master)("Title verification"), + sep, + a(activeCls("source"), href := routes.Page.source)(trans.sourceCode()), + a(activeCls("help"), href := routes.Page.help)(trans.contribute()), + a(activeCls("thanks"), href := routes.Page.thanks)(trans.thankYou()), + sep, + a(activeCls("webmasters"), href := routes.Main.webmasters)(trans.webmasters()), + a(activeCls("database"), href := "https://database.lichess.org")(trans.database(), external), + a(activeCls("api"), href := routes.Api.index)("API", external), + sep, + a(activeCls("lag"), href := routes.Main.lag)("Is Lichess lagging?") + ), + div(cls := s"page-menu__content $contentCls")(body) + ) + } } diff --git a/app/views/site/lag.scala b/app/views/site/lag.scala new file mode 100644 index 0000000000..ad8c218a38 --- /dev/null +++ b/app/views/site/lag.scala @@ -0,0 +1,67 @@ +package views.html.site + +import controllers.routes +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +object lag { + + def apply()(implicit ctx: Context) = help.layout( + title = "Is Lichess lagging?", + active = "lag", + moreCss = cssTag("lag"), + moreJs = frag( + highchartsLatestTag, + highchartsMoreTag, + jsTag("lag.js") + ) + ) { + main(cls := "box box-pad lag")( + h1( + "Is Lichess lagging?", + span(cls := "answer short")( + span(cls := "waiting")("Measurements in progress..."), + span(cls := "nope-nope none")(strong("No."), " And your network is good."), + span(cls := "nope-yep none")(strong("No."), " But your network is bad."), + span(cls := "yep none")(strong("Yes."), " It will be fixed soon!") + ) + ), + div(cls := "answer long")( + "And now, the long answer! Game lag is composed of two unrelated values (lower is better):" + ), + div(cls := "sections")( + st.section(cls := "server")( + h2("Lichess server latency"), + div(cls := "meter"), + p( + "The time it takes to process a move on the server. ", + "It's the ", strong("same for everybody"), ", and only depends on the server load. ", + "The more players and the higher it gets, but Lichess developers ", + "do their best to keep it low. It rarely exceeds 10ms." + ) + ), + st.section(cls := "network")( + h2("Network between Lichess and you"), + div(cls := "meter"), + p( + "The time it takes to send a move from your computer to Lichess server, ", + "and get the response back.", + "It's specific to your ", strong("distance to Lichess (France)"), ", and ", + "to the ", strong("quality of your Internet connection"), ". ", + "Lichess developers can not fix your wifi or make light go faster." + ) + ) + ), + div(cls := "last-word")( + p("You can find both these values at any time, by clicking your username in the top bar."), + h2("Lag compensation"), + p( + "Lichess compensates network lag, up to one second per move. ", + "After your move, ", strong("your average network lag is added to your clock"), ". ", + "As a result, having a higher network lag than your opponent is ", strong("not a handicap"), "!" + ) + ) + ) + } +} diff --git a/app/views/site/lag.scala.html b/app/views/site/lag.scala.html deleted file mode 100644 index 55c35f66ba..0000000000 --- a/app/views/site/lag.scala.html +++ /dev/null @@ -1,60 +0,0 @@ -@()(implicit ctx: Context) - -@moreJs = { -@highchartsLatestTag -@highchartsMoreTag -@jsTag("lag.js") -} - -@base.layout( -title = "Is lichess lagging?", -moreCss = cssTag("lag.css"), -moreJs = moreJs) { - -
    -

    - Is lichess lagging? - - Measurements in progress... - No. And your network is good. - No. But your network is bad. - Yes. It will be fixed soon! - -

    -
    - And now, the long answer! Game lag is composed of two unrelated values (lower is better): -
    -
    -
    -

    Lichess server latency

    -
    -

    - The time it takes to process a move on the server. - It's the same for everybody, and only depends on the server load. - The more players and the higher it gets, but lichess developers - do their best to keep it low. It rarely exceeds 10ms. -

    -
    -
    -

    Network between lichess and you

    -
    -

    - The time it takes to send a move from your computer to lichess server, - and get the response back. - It's specific to your distance to lichess (France) and - to the quality of your Internet connection. - Lichess developers can not fix your wifi or make light go faster. -

    -
    -
    -
    -

    You can find both these values at any time, by clicking your username in the top bar.

    -

    Lag compensation

    -

    Lichess compensates network lag, up to one second per move. - After your move, your average network lag is added to your clock. - As a result, having a higher network lag than your opponent is not a handicap!

    -

    Now when you see someone complain about lag, you can send them to this - page, so they can learn a thing or two :)

    -
    -
    -}.toHtml diff --git a/app/views/site/message.scala b/app/views/site/message.scala index 420ba704fc..d8a4ddfe5a 100644 --- a/app/views/site/message.scala +++ b/app/views/site/message.scala @@ -1,8 +1,6 @@ package views package html.site -import play.twirl.api.Html - import controllers.routes import lila.api.Context import lila.app.templating.Environment._ @@ -15,20 +13,15 @@ object message { title: String, back: Boolean = true, icon: Option[String] = None, - moreCss: Option[Html] = None - )(message: Frag)(implicit ctx: Context) = + moreCss: Option[Frag] = None + )(message: Modifier*)(implicit ctx: Context) = views.html.base.layout(title = title, moreCss = ~moreCss) { - div(cls := "content_box small_box")( - div(cls := "head")( - h1(cls := List("text" -> icon.isDefined), dataIcon := icon)(title) - ), - br, br, + main(cls := "box box-pad")( + h1(cls := List("text" -> icon.isDefined), dataIcon := icon)(title), p(message), br, back option embedJsUnsafe { - raw { - """if (document.referrer) document.write('Go Back');""" - } + """if (document.referrer) document.write('Go Back');""" } ) } @@ -67,10 +60,14 @@ object message { )(frag( "Before using chess insights,", userLink(u), - "has to play at least one rated game." + " has to play at least one rated game." )) def teamCreateLimit(implicit ctx: Context) = apply("Cannot create a team") { "You have already created a team this week." } + + def authFailed(implicit ctx: Context) = apply("403 - Access denied!") { + "You tried to visit a page you're not authorized to access." + } } diff --git a/app/views/site/page.scala b/app/views/site/page.scala new file mode 100644 index 0000000000..3e3426a210 --- /dev/null +++ b/app/views/site/page.scala @@ -0,0 +1,21 @@ +package views.html.site + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +object page { + + def apply(doc: io.prismic.Document, resolver: io.prismic.DocumentLinkResolver)(implicit ctx: Context) = + views.html.base.layout( + moreCss = cssTag("page"), + title = s"${~doc.getText("doc.title")}" + ) { + main(cls := "page-small box box-pad page")( + h1(doc.getText("doc.title")), + div(cls := "body")( + raw(~doc.getHtml("doc.content", resolver)) + ) + ) + } +} diff --git a/app/views/site/page.scala.html b/app/views/site/page.scala.html deleted file mode 100644 index cfc0c70175..0000000000 --- a/app/views/site/page.scala.html +++ /dev/null @@ -1,15 +0,0 @@ -@(doc: io.prismic.Document, resolver: io.prismic.DocumentLinkResolver)(implicit ctx: Context) - -@base.layout( -moreCss = cssTag("page.css"), -title = s"${~doc.getText("doc.title")}") { - -
    - -

    @doc.getText("doc.title")

    - -
    - @Html(~doc.getHtml("doc.content", resolver)) -
    -
    -}.toHtml diff --git a/app/views/site/swag.scala b/app/views/site/swag.scala new file mode 100644 index 0000000000..46b145725d --- /dev/null +++ b/app/views/site/swag.scala @@ -0,0 +1,48 @@ +package views.html.site + +import controllers.routes +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +object swag { + + def apply(doc: io.prismic.Document, resolver: io.prismic.DocumentLinkResolver)(implicit ctx: Context) = + views.html.base.layout( + moreCss = cssTag("swag"), + title = "Lichess Swag", + wrapClass = "full-screen-force", + openGraph = lila.app.ui.OpenGraph( + title = "Lichess merch store", + description = "Great chess deserves great T-shirts! Get yourself some swag and help pay for the servers.", + url = s"$netBaseUrl${routes.Page.swag}" + ).some, + csp = defaultCsp.withSpreadshirt.some + ) { + main(cls := "page-menu swag")( + st.aside(cls := "page-menu__menu swag__side")( + div(cls := "box")( + raw(~doc.getHtml("doc.content", resolver)) + ) + ), + div(cls := "page-menu__content box")( + div(id := "myShop")( + spinner, + p(cls := "loading")( + "Not loading? ", + a(target := "_blank", href := "https://shop.spreadshirt.com/lichess-org/")("Open the shop in a new tab"), + "." + ) + ), + embedJsUnsafe(""" + var spread_shop_config = { + shopName: 'lichess-org', + locale: 'us_US', + prefix: 'https://shop.spreadshirt.com', + baseId: 'myShop' + };"""), + script(src := "https://shop.spreadshirt.com/shopfiles/shopclient/shopclient.nocache.js") + ) + ) + } +} diff --git a/app/views/site/swag.scala.html b/app/views/site/swag.scala.html deleted file mode 100644 index 302a151bcb..0000000000 --- a/app/views/site/swag.scala.html +++ /dev/null @@ -1,38 +0,0 @@ -@(doc: io.prismic.Document, resolver: io.prismic.DocumentLinkResolver)(implicit ctx: Context) - -@side = { -
    - @Html(~doc.getHtml("doc.content", resolver)) -
    -} - -@base.layout( -moreCss = cssTag("swag.css"), -side = side.some, -title = "Lichess Swag", -openGraph = lila.app.ui.OpenGraph( -title = "Lichess merch store", -description = "Great chess deserves great T-shirts! Get yourself some swag and help pay for the servers.", -url = s"$netBaseUrl${routes.Page.swag}").some, -csp = defaultCsp.withSpreadshirt.some) { - -
    -
    - @spinner -

    - Not loading? Open the shop in a new tab. -

    -
    - - @embedJs { - var spread_shop_config = { - shopName: 'lichess-org', - locale: 'us_US', - prefix: 'https://shop.spreadshirt.com', - baseId: 'myShop' - }; - } - - -
    -}.toHtml diff --git a/app/views/site/variant.scala b/app/views/site/variant.scala index 9f436d7b47..6c4d25c642 100644 --- a/app/views/site/variant.scala +++ b/app/views/site/variant.scala @@ -13,49 +13,59 @@ object variant { resolver: io.prismic.DocumentLinkResolver, variant: chess.variant.Variant, perfType: lila.rating.PerfType - )(implicit ctx: Context) = layout(active = perfType.some, title = s"${variant.name} • ${variant.title}") { - div(cls := "content_box small_box doc_box")( - h1(cls := "lichess_title text", dataIcon := perfType.iconChar)(variant.name), - h2(cls := "headline")(variant.title), - div(cls := "body")(raw(~doc.getHtml("variant.content", resolver))) - ) - } + )(implicit ctx: Context) = layout( + active = perfType.some, + title = s"${variant.name} • ${variant.title}", + klass = "box-pad page variant" + )( + h1(cls := "text", dataIcon := perfType.iconChar)(variant.name), + h2(cls := "headline")(variant.title), + div(cls := "body")(raw(~doc.getHtml("variant.content", resolver))) + ) def home( doc: io.prismic.Document, resolver: io.prismic.DocumentLinkResolver - )(implicit ctx: Context) = layout(title = "Lichess variants") { - div(cls := "content_box small_box doc_box no_padding")( - h1(cls := "lichess_title text", dataIcon := "")("Lichess variants"), - div(cls := "body content_box_content")(raw(~doc.getHtml("doc.content", resolver))), - div(cls := "variants")( - lila.rating.PerfType.variants map { pt => - val variant = lila.rating.PerfType variantOf pt - a(cls := "variant text", href := routes.Page.variant(pt.key), dataIcon := pt.iconChar)( + )(implicit ctx: Context) = layout( + title = "Lichess variants", + klass = "variants" + )( + h1("Lichess variants"), + div(cls := "body box__pad")(raw(~doc.getHtml("doc.content", resolver))), + div(cls := "variants")( + lila.rating.PerfType.variants map { pt => + val variant = lila.rating.PerfType variantOf pt + a(cls := "variant text box__pad", href := routes.Page.variant(pt.key), dataIcon := pt.iconChar)( + span( h2(variant.name), h3(cls := "headline")(variant.title) ) - } - ) + ) + } ) - } + ) private def layout( title: String, + klass: String, active: Option[lila.rating.PerfType] = None, openGraph: Option[lila.app.ui.OpenGraph] = None - )(body: Frag)(implicit ctx: Context) = views.html.base.layout( + )(body: Modifier*)(implicit ctx: Context) = views.html.base.layout( title = title, - menu = Some(frag( - lila.rating.PerfType.variants map { pt => - a( - cls := List("text" -> true, "active" -> active.has(pt)), - href := routes.Page.variant(pt.key), - dataIcon := pt.iconChar - )(pt.name) - } - )), - moreCss = cssTags("page.css", "variant.css"), + moreCss = cssTag("variant"), openGraph = openGraph - )(body) + )( + main(cls := "page-menu")( + st.aside(cls := "page-menu__menu subnav")( + lila.rating.PerfType.variants map { pt => + a( + cls := List("text" -> true, "active" -> active.has(pt)), + href := routes.Page.variant(pt.key), + dataIcon := pt.iconChar + )(pt.name) + } + ), + div(cls := s"page-menu__content box $klass")(body) + ) + ) } diff --git a/app/views/stat/layout.scala.html b/app/views/stat/layout.scala.html deleted file mode 100644 index 7293a72af7..0000000000 --- a/app/views/stat/layout.scala.html +++ /dev/null @@ -1,20 +0,0 @@ -@(title: String, active: String, moreJs: Html)(body: Html)(implicit ctx: Context) - -@menu = { -@lila.rating.PerfType.leaderboardable.map { pt => - - @pt.name - -} -} - -@moreCss = { -@cssTag("user-list.css") -@cssTag("stat.css") -} - -@base.layout( -title = title, -menu = menu.some, -moreCss = moreCss, -moreJs = moreJs)(body).toHtml diff --git a/app/views/stat/ratingDistribution.scala b/app/views/stat/ratingDistribution.scala new file mode 100644 index 0000000000..46ae36ac42 --- /dev/null +++ b/app/views/stat/ratingDistribution.scala @@ -0,0 +1,58 @@ +package views.html +package stat + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.rating.PerfType + +import controllers.routes + +object ratingDistribution { + + def apply(perfType: PerfType, data: List[Int])(implicit ctx: Context) = views.html.base.layout( + title = trans.weeklyPerfTypeRatingDistribution.txt(perfType.name), + moreCss = cssTag("user.rating.stats"), + wrapClass = "full-screen-force", + moreJs = frag( + jsTag("chart/ratingDistribution.js"), + embedJsUnsafe(s"""lichess.ratingDistributionChart({ + freq: ${data.mkString("[", ",", "]")}, + myRating: ${ctx.me.fold("null")(_.perfs(perfType).intRating.toString)} +});""") + ) + ) { + main(cls := "page-menu")( + user.bits.communityMenu("ratings"), + div(cls := "rating-stats page-menu__content box box-pad")( + h1(trans.weeklyPerfTypeRatingDistribution(views.html.base.bits.mselect( + "variant-stats", + span(perfType.name), + PerfType.leaderboardable map { pt => + a( + dataIcon := pt.iconChar, + cls := (perfType == pt).option("current"), + href := routes.Stat.ratingDistribution(pt.key) + )(pt.name) + } + ))), + div(cls := "desc", dataIcon := perfType.iconChar)( + ctx.me.flatMap(_.perfs(perfType).glicko.establishedIntRating).map { rating => + lila.user.Stat.percentile(data, rating) match { + case (under, sum) => div( + trans.nbPerfTypePlayersThisWeek(raw(s"""${sum.localize}"""), perfType.name), br, + trans.yourPerfTypeRatingIsRating(perfType.name, raw(s"""$rating""")), br, + trans.youAreBetterThanPercentOfPerfTypePlayers(raw(s"""${"%.1f" format under * 100.0 / sum}%"""), perfType.name) + ) + } + } getOrElse div( + trans.nbPerfTypePlayersThisWeek.plural(data.sum, raw(s"""${data.sum.localize}"""), perfType.name), br, + trans.youDoNotHaveAnEstablishedPerfTypeRating(perfType.name) + ) + ), + div(id := "rating_distribution_chart")(spinner) + ) + ) + } + +} diff --git a/app/views/stat/ratingDistribution.scala.html b/app/views/stat/ratingDistribution.scala.html deleted file mode 100644 index c6281641db..0000000000 --- a/app/views/stat/ratingDistribution.scala.html +++ /dev/null @@ -1,40 +0,0 @@ -@(perfType: lila.rating.PerfType, data: List[Int])(implicit ctx: Context) - -@moreJs = { -@jsTag("chart/ratingDistribution.js") -@embedJs { -lichess.ratingDistributionChart({ -freq: @data.mkString("[", ",", "]"), -myRating: @ctx.me.fold("null")(_.perfs(perfType).intRating.toString) -}); -} -} - -@title = @{ trans.weeklyPerfTypeRatingDistribution.txt(perfType.name) } - -@layout( -title = title.toString, -active = perfType.key, -moreJs = moreJs) { -
    - @user.communityTabs("ratings") -

    @title

    -

    - @ctx.me.flatMap(_.perfs(perfType).glicko.establishedIntRating).map { rating => - @lila.user.Stat.percentile(data, rating) match { - case (under, sum) => { - @trans.nbPerfTypePlayersThisWeek(Html(s"""${sum.localize}"""), perfType.name)
    - @trans.yourPerfTypeRatingIsRating(perfType.name, Html(s"""$rating"""))
    - @trans.youAreBetterThanPercentOfPerfTypePlayers(Html(s"""${"%.1f" format under * 100.0 / sum}%"""), perfType.name) - } - } - }.getOrElse { - @trans.nbPerfTypePlayersThisWeek.plural(data.sum, Html(s"""${data.sum.localize}"""), perfType.name)
    - @trans.youDoNotHaveAnEstablishedPerfTypeRating(perfType.name)
    - } -

    -
    - @spinner -
    -
    -} diff --git a/app/views/streamer/bits.scala b/app/views/streamer/bits.scala index fa5075b3d4..d6126c0d76 100644 --- a/app/views/streamer/bits.scala +++ b/app/views/streamer/bits.scala @@ -1,41 +1,101 @@ package views.html.streamer -import play.twirl.api.Html - import controllers.routes +import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ +import lila.user.User object bits { + def create(me: User)(implicit ctx: Context) = views.html.site.message( + title = "Become a lichess streamer", + icon = Some(""), + back = false, + moreCss = cssTag("streamer.form").some + )( + form(cls := "streamer-new", action := routes.Streamer.create, method := "POST")( + h2("Do you have a Twitch or YouTube stream, ", me.username, "?"), + br, br, + bits.rules(), + br, br, + p(style := "text-align: center")( + button(tpe := "submit", cls := "button button-fat text", dataIcon := "")("Here we go!") + ) + ) + ) + + def pic(s: lila.streamer.Streamer, u: User, size: Int = 300)(implicit ctx: Context) = s.picturePath match { + case Some(path) => img( + width := size, + height := size, + cls := "picture", + src := dbImageUrl(path.value), + alt := s"${u.titleUsername} lichess streamer" + ) + case _ => img( + width := size, + height := size, + cls := "default picture", + src := staticUrl("images/streamer-nopic.svg"), + alt := "Default streamer picture" + ) + } + + def menu(active: String, s: Option[lila.streamer.Streamer.WithUser])(implicit ctx: Context) = + st.nav(cls := "subnav")( + a(cls := active.active("index"), href := routes.Streamer.index())("All streamers"), + s.map { st => + frag( + a(cls := active.active("show"), href := routes.Streamer.show(st.streamer.id.value))(st.streamer.name), + (ctx.is(st.user) || isGranted(_.Streamers)) option + a(cls := active.active("edit"), href := s"${routes.Streamer.edit}?u=${st.streamer.id.value}")("Edit streamer page") + ) + } getOrElse a(href := routes.Streamer.edit)("Your streamer page"), + a(dataIcon := "", cls := "text", href := "/blog/Wk5z0R8AACMf6ZwN/join-the-lichess-streamer-community")("Streamer community"), + a(href := "/about")("Download streamer kit") + ) + def liveStreams(l: lila.streamer.LiveStreams.WithTitles): Frag = l.live.streams.map { s => a(cls := "stream highlight", href := routes.Streamer.show(s.streamer.id.value), title := s.status)( - span(cls := "text", dataIcon := "")(l titleName s), + strong(cls := "text", dataIcon := "")(l titleName s), " ", s.status ) } + def contextual(userId: User.ID): Frag = + a(cls := "context-streamer text", dataIcon := "", href := routes.Streamer.show(userId))( + usernameOrId(userId), " is streaming" + ) + object svg { - val twitch = Html(""" + val twitch = raw(""" """) - val youTube = Html(""" + val youTube = raw(""" """) - val lichess = Html(""" + val lichess = raw(""" """) } + + def rules = ul(cls := "streamer-rules")( + li("Be listed as a lichess streamer."), + li(title := "For example: Blitz battle on lichess.org")("Get bumped up the top of the list when you stream with the keyword \"lichess.org\" in the stream title."), + li("Notify your lichess followers when you start streaming."), + li("Promote your stream in your games and tournaments.") + ) } diff --git a/app/views/streamer/create.scala.html b/app/views/streamer/create.scala.html deleted file mode 100644 index 557c41edec..0000000000 --- a/app/views/streamer/create.scala.html +++ /dev/null @@ -1,15 +0,0 @@ -@(me: User)(implicit ctx: Context) - -@site.message( -title = "Become a lichess streamer", -icon = Some(""), -back = true, -moreCss = cssTag("streamer.form.css").some) { -
    -

    Do you have a Twitch or YouTube stream, @me.username?

    - @rules() -

    - -

    -
    -}.toHtml diff --git a/app/views/streamer/edit.scala b/app/views/streamer/edit.scala new file mode 100644 index 0000000000..3ac344a177 --- /dev/null +++ b/app/views/streamer/edit.scala @@ -0,0 +1,150 @@ +package views.html.streamer + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.String.html.richText +import lila.user.User + +import controllers.routes + +object edit { + + def apply( + s: lila.streamer.Streamer.WithUserAndStream, + form: Form[_], + modData: Option[(List[lila.mod.Modlog], List[lila.user.Note])] + )(implicit ctx: Context) = { + + val modsOnly = raw("Moderators only").some + + views.html.base.layout( + title = s"${s.user.titleUsername} streamer page", + moreCss = cssTag("streamer.form"), + moreJs = jsTag("streamer.form.js") + ) { + main(cls := "page-menu")( + bits.menu("edit", s.withoutStream.some), + div(cls := "page-menu__content box streamer-edit")( + if (ctx.is(s.user)) div(cls := "streamer-header")( + if (s.streamer.hasPicture) + a(target := "_blank", href := routes.Streamer.picture, title := "Change/delete your picture")( + bits.pic(s.streamer, s.user) + ) + else div(cls := "picture-create")( + ctx.is(s.user) option + a(target := "_blank", cls := "button", href := routes.Streamer.picture)("Upload a picture") + ), + div(cls := "overview")( + h1(s.streamer.name), + bits.rules() + ) + ) + else header(s, none), + div(cls := "box__pad") { + val granted = s.streamer.approval.granted + frag( + s.streamer.listed.value option + div( + cls := s"status is${granted ?? "-green"}", + dataIcon := (if (granted) "E" else "") + )( + if (granted) frag( + "Your stream is approved and listed on ", + a(href := routes.Streamer.index())("lichess streamers list"), "." + ) + else frag( + if (s.streamer.approval.requested) frag( + "Your stream is being reviewed by moderators, and will soon be listed on ", + a(href := routes.Streamer.index())("lichess streamers list"), "." + ) + else frag( + if (s.streamer.completeEnough) frag( + "When you are ready to be listed on ", + a(href := routes.Streamer.index())("lichess streamers list"), ", ", + st.form(method := "post", action := routes.Streamer.approvalRequest)( + button(tpe := "submmit", cls := "button", (!ctx.is(s.user)) option disabled)( + "request a moderator review" + ) + ) + ) + else "Please fill in your streamer information, and upload a picture." + ) + ) + ), + div(cls := "status")( + strong("If your stream is in another language than English"), + ", include the correct language tag (", + a(href := "https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes")("2-letter ISO 639-1 code"), + " enclosed in square brackets) at the start of your stream title. ", + """As examples, include "[RU]" for Russian, "[TR]" for Turkish, "[FR]" for French, etc. """, + "If your stream is in English, there is no need to include a language tag." + ), + modData.map { + case (log, notes) => div(cls := "mod_log status")( + strong(cls := "text", dataIcon := "!")( + "Moderation history", + log.isEmpty option ": nothing to show." + ), + log.nonEmpty option ul( + log.map { e => + li( + userIdLink(e.mod.some, withTitle = false), " ", + b(e.showAction), " ", e.details, " ", momentFromNow(e.date) + ) + } + ), + br, + strong(cls := "text", dataIcon := "!")( + "Moderator notes", + notes.isEmpty option ": nothing to show." + ), + notes.nonEmpty option ul( + notes.map { note => + li( + p(cls := "meta")(userIdLink(note.from.some), " ", momentFromNow(note.date)), + p(cls := "text")(richText(note.text)) + ) + } + ) + ) + }, + st.form(cls := "form3", action := s"${routes.Streamer.edit}${!ctx.is(s.user) ?? s"?u=${s.user.id}"}", method := "POST")( + isGranted(_.Streamers) option div(cls := "mod")( + form3.split( + form3.checkbox(form("approval.granted"), raw("Publish on the streamers list"), help = modsOnly, half = true), + form3.checkbox(form("approval.requested"), raw("Active approval request"), help = modsOnly, half = true) + ), + form3.split( + form3.checkbox(form("approval.chat"), raw("Embed stream chat too"), help = modsOnly, half = true), + if (granted) + form3.checkbox(form("approval.featured"), raw("Feature on lichess homepage"), help = modsOnly, half = true) + else + form3.checkbox(form("approval.ignored"), raw("Ignore further approval requests"), help = modsOnly, half = true) + ), + form3.action(form3.submit(trans.apply())) + ), + form3.split( + form3.group(form("twitch"), raw("Your Twitch username or URL"), help = raw("Optional. Leave empty if none").some, half = true)(form3.input(_)), + form3.group(form("youTube"), raw("Your YouTube channel ID or URL"), help = raw("Optional. Leave empty if none").some, half = true)(form3.input(_)) + ), + form3.split( + form3.group(form("name"), raw("Your streamer name on lichess"), help = raw("Keep it short: 20 characters max").some, half = true)(form3.input(_)), + form3.checkbox(form("listed"), raw("Visible on the streamers page"), help = raw("When approved by moderators").some, half = true) + ), + form3.group(form("headline"), raw("Headline"), help = raw("In one sentence, tell us about your stream").some)(form3.input(_)), + form3.group(form("description"), raw("Long description"))(form3.textarea(_)(rows := 10)), + form3.actions( + a(href := routes.Streamer.show(s.user.username))("Cancel"), + form3.submit(trans.apply()) + ) + ) + ) + } + ) + ) + } + } +} diff --git a/app/views/streamer/edit.scala.html b/app/views/streamer/edit.scala.html deleted file mode 100644 index 6e07ee96d6..0000000000 --- a/app/views/streamer/edit.scala.html +++ /dev/null @@ -1,118 +0,0 @@ -@(s: lila.streamer.Streamer.WithUserAndStream, form: Form[_], modData: Option[(List[lila.mod.Modlog], List[lila.user.Note])])(implicit ctx: Context) -@import lila.app.ui.ScalatagsTwirlForm._ -@modsOnly = @{ raw("Moderators only").some } - -@base.layout(title = s"${s.user.titleUsername} streamer page", -moreCss = cssTags("form3.css", "streamer.show.css", "streamer.form.css"), -moreJs = jsTag("streamer.form.js"), -menu = menu("edit", s.withoutStream.some).some) { -
    - @if(ctx.is(s.user)) { -
    -
    - @if(s.streamer.hasPicture) { - - @pic(s.streamer, s.user, 250) - - } else { -
    - @if(ctx.is(s.user)) { - Upload a picture - } -
    - } -
    -
    -

    @s.streamer.name

    - @rules() -
    -
    - } else { - @header(s, none) - } - @defining(s.streamer.approval.granted) { granted => - @if(s.streamer.listed.value) { -
    - @if(granted) { - Your stream is approved and listed on lichess streamers list. - } else { - @if(s.streamer.approval.requested) { - Your stream is being reviewed by moderators, and will soon be listed on lichess streamers list. - } else { - @if(s.streamer.completeEnough) { - When you are ready to be listed on lichess streamers list, -
    - -
    - } else { - Please fill in your streamer information, and upload a picture. - } - } - } -
    -
    - If your stream is in another language than English, include the correct language tag (2-letter ISO 639-1 code enclosed in square brackets) at the start of your stream title. As examples, include "[RU]" for Russian, "[TR]" for Turkish, "[FR]" for French, etc. If your stream is in English, there is no need to include a language tag. -
    - } - @modData.map { - case (log, notes) => { -
    - Moderation history@if(log.isEmpty){: nothing to show.} - @if(log.nonEmpty) { -
      - @log.map { e => -
    • @userIdLink(e.mod.some, withTitle=false) @e.showAction @e.details @momentFromNow(e.date)
    • - } -
    - } -
    - Moderator notes@if(notes.isEmpty){: nothing to show.} - @if(notes.nonEmpty) { -
      - @notes.map { note => -
    • -

      @userIdLink(note.from.some) @momentFromNow(note.date)

      -

      @richText(note.text)

      -
    • - } -
    - } -
    - } - } -
    - @if(isGranted(_.Streamers)) { -
    - @form3.split { - @form3.checkbox(form("approval.granted"), raw("Publish on the streamers list"), help = modsOnly, half = true) - @form3.checkbox(form("approval.requested"), raw("Active approval request"), help = modsOnly, half = true) - } - @form3.split { - @form3.checkbox(form("approval.chat"), raw("Embed stream chat too"), help = modsOnly, half = true) - @if(granted) { - @form3.checkbox(form("approval.featured"), raw("Feature on lichess homepage"), help = modsOnly, half = true) - } else { - @form3.checkbox(form("approval.ignored"), raw("Ignore further approval requests"), help = modsOnly, half = true) - } - } - @form3.actionHtml(form3.submit(trans.apply.frag())) -
    - } - @form3.split { - @form3.group(form("twitch"), raw("Your Twitch username or URL"), help = raw("Optional. Leave empty if none").some, half = true)(form3.input(_)) - @form3.group(form("youTube"), raw("Your YouTube channel ID or URL"), help = raw("Optional. Leave empty if none").some, half = true)(form3.input(_)) - } - @form3.split { - @form3.group(form("name"), raw("Your streamer name on lichess"), help = raw("Keep it short: 20 characters max").some, half = true)(form3.input(_)) - @form3.checkbox(form("listed"), raw("Visible on the streamers page"), help = raw("When approved by moderators").some, half = true) - } - @form3.group(form("headline"), raw("Headline"), help = raw("In one sentence, tell us about your stream").some)(form3.input(_)) - @form3.group(form("description"), raw("Long description"))(form3.textarea(_)(*.rows := 10)) - @form3.actionsHtml { - Cancel - @form3.submit(trans.apply.frag()) - } -
    - } -
    -}.toHtml diff --git a/app/views/streamer/header.scala b/app/views/streamer/header.scala new file mode 100644 index 0000000000..d99f71259c --- /dev/null +++ b/app/views/streamer/header.scala @@ -0,0 +1,71 @@ +package views.html.streamer + +import controllers.routes +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +object header { + + def apply(s: lila.streamer.Streamer.WithUserAndStream, following: Option[Boolean])(implicit ctx: Context) = + div(cls := "streamer-header")( + bits.pic(s.streamer, s.user), + div(cls := "overview")( + h1(dataIcon := "")( + titleTag(s.user.title), + s.streamer.name + ), + s.streamer.headline.map(_.value).map { d => + p(cls := s"headline ${if (d.size < 60) "small" else if (d.size < 120) "medium" else "large"}")(d) + }, + div(cls := "services")( + s.streamer.twitch.map { twitch => + a( + cls := List( + "service twitch" -> true, + "live" -> s.stream.exists(_.twitch) + ), + href := twitch.fullUrl + )(bits.svg.twitch, " ", twitch.minUrl) + }, + s.streamer.youTube.map { youTube => + a( + cls := List( + "service youTube" -> true, + "live" -> s.stream.exists(_.twitch) + ), + href := youTube.fullUrl + )(bits.svg.youTube, " ", youTube.minUrl) + }, + a(cls := "service lichess", href := routes.User.show(s.user.username))( + bits.svg.lichess, + " ", + s"lichess.org/@/${s.user.username}" + ) + ), + div(cls := "ats")( + s.stream.map { s => + p(cls := "at")( + "Currently streaming: ", + strong(s.status) + ) + } getOrElse frag( + p(cls := "at")(trans.lastSeenActive(momentFromNow(s.streamer.seenAt))), + s.streamer.liveAt.map { liveAt => + p(cls := "at")("Last stream ", momentFromNow(liveAt)) + } + ) + ), + following.map { f => + (ctx.isAuth && !ctx.is(s.user)) option + button(attr("data-user") := s.user.id, dataIcon := "h", cls := List( + "follow button text" -> true, + "active" -> f + ), tpe := "submit")( + span(cls := "active-no")(trans.follow()), + span(cls := "active-yes")(trans.following()) + ) + } + ) + ) +} diff --git a/app/views/streamer/header.scala.html b/app/views/streamer/header.scala.html deleted file mode 100644 index cb7726a631..0000000000 --- a/app/views/streamer/header.scala.html +++ /dev/null @@ -1,50 +0,0 @@ -@(s: lila.streamer.Streamer.WithUserAndStream, following: Option[Boolean])(implicit ctx: Context) -
    - @pic(s.streamer, s.user, 250) -
    -

    @titleTag(s.user.title)@s.streamer.name

    - @s.streamer.headline.map(_.value).map { d => -

    @d

    - } - -
    -
    - @s.stream.map { s => -

    - Currently streaming:
    - @s.status -

    - }.getOrElse { -

    @trans.lastSeenActive(momentFromNow(s.streamer.seenAt))

    - @s.streamer.liveAt.map { liveAt => -

    Last stream @momentFromNow(liveAt)

    - } - } -
    - @following.map { f => - @if(ctx.isAuth && !ctx.is(s.user)) { - - } - } -
    -
    -
    diff --git a/app/views/streamer/index.scala b/app/views/streamer/index.scala new file mode 100644 index 0000000000..0fe0d9fd86 --- /dev/null +++ b/app/views/streamer/index.scala @@ -0,0 +1,102 @@ +package views.html.streamer + +import controllers.routes +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator + +object index { + + private val dataDedup = attr("data-dedup") + + def apply( + live: List[lila.streamer.Streamer.WithUserAndStream], + pager: Paginator[lila.streamer.Streamer.WithUser], + requests: Boolean + )(implicit ctx: Context) = { + + val title = if (requests) "Streamer approval requests" else "Lichess streamers" + + def widget(s: lila.streamer.Streamer.WithUser, stream: Option[lila.streamer.Stream]) = frag( + a( + cls := "overlay", + href := { + if (requests) s"${routes.Streamer.edit}?u=${s.user.username}" + else routes.Streamer.show(s.user.username).url + } + ), + stream.isDefined option span(cls := "ribbon")(span("LIVE!")), + bits.pic(s.streamer, s.user), + div(cls := "overview")( + h1(dataIcon := "")(titleTag(s.user.title), stringValueFrag(s.streamer.name)), + s.streamer.headline.map(_.value).map { d => + p(cls := s"headline ${if (d.size < 60) "small" else if (d.size < 120) "medium" else "large"}")(d) + }, + div(cls := "services")( + s.streamer.twitch.map { twitch => + div(cls := "service twitch")( + bits.svg.twitch, + " ", + twitch.minUrl + ) + }, + s.streamer.youTube.map { youTube => + div(cls := "service youTube")( + bits.svg.youTube, + " ", + youTube.minUrl + ) + } + ), + div(cls := "ats")( + stream.map { s => + p(cls := "at")( + "Currently streaming: ", + strong(s.status) + ) + } getOrElse frag( + p(cls := "at")(trans.lastSeenActive(momentFromNow(s.streamer.seenAt))), + s.streamer.liveAt.map { liveAt => + p(cls := "at")("Last stream ", momentFromNow(liveAt)) + } + ) + ) + ) + ) + + views.html.base.layout( + title = title, + moreCss = cssTag("streamer.list"), + moreJs = infiniteScrollTag + ) { + main(cls := "page-menu")( + bits.menu("index", none)(ctx)(cls := " page-menu__menu"), + div(cls := "page-menu__content box streamer-list")( + h1(dataIcon := "", cls := "text")(title), + !requests option div(cls := "list live")( + live.map { s => + st.article(cls := "streamer")(widget(s.withoutStream, s.stream)) + } + ), + div(cls := "list infinitescroll")( + (live.size % 2 == 1) option div(cls := "none"), + pager.currentPageResults.map { s => + st.article(cls := "streamer paginated", dataDedup := s.streamer.id.value)(widget(s, none)) + }, + pagerNext( + pager, + np => addQueryParameter( + addQueryParameter(routes.Streamer.index().url, "page", np), + "requests", + if (requests) 1 else 0 + ) + ).map { + frag(_, div(cls := "none")) // don't break the even/odd CSS flow + } + ) + ) + ) + } + } +} diff --git a/app/views/streamer/index.scala.html b/app/views/streamer/index.scala.html deleted file mode 100644 index 0475503e43..0000000000 --- a/app/views/streamer/index.scala.html +++ /dev/null @@ -1,72 +0,0 @@ -@(live: List[lila.streamer.Streamer.WithUserAndStream], pager: Paginator[lila.streamer.Streamer.WithUser], requests: Boolean)(implicit ctx: Context) - -@title = @{ if (requests) "Streamer approval requests" else "Lichess streamers" } - -@widget(s: lila.streamer.Streamer.WithUser, stream: Option[lila.streamer.Stream]) = { - -@if(stream.isDefined) { - - LIVE! - -} -@pic(s.streamer, s.user, 250) -
    -

    @titleTag(s.user.title)@s.streamer.name

    - @s.streamer.headline.map(_.value).map { d => -

    @d

    - } -
    - @s.streamer.twitch.map { twitch => -
    - @bits.svg.twitch - @twitch.minUrl -
    - } - @s.streamer.youTube.map { youTube => -
    - @bits.svg.youTube - @youTube.minUrl -
    - } -
    -
    - @stream.map { s => -

    - Currently streaming: - @s.status -

    - }.getOrElse { -

    @trans.lastSeenActive(momentFromNow(s.streamer.seenAt))

    - @s.streamer.liveAt.map { liveAt => -

    Last stream @momentFromNow(liveAt)

    - } - } -
    -
    -} - -@base.layout(title = title, -moreCss = cssTag("streamer.list.css"), -moreJs = infiniteScrollTag, -menu = menu("index", none).some) { -
    -

    @title

    - @if(!requests) { -
    - @live.map { s => -
    @widget(s.withoutStream, s.stream)
    - } -
    - } -
    - @pager.currentPageResults.map { s => -
    @widget(s, none)
    - } - @pager.nextPage.map { np => -
    - -
    - } -
    -
    -}.toHtml diff --git a/app/views/streamer/menu.scala.html b/app/views/streamer/menu.scala.html deleted file mode 100644 index 4e9d30ba98..0000000000 --- a/app/views/streamer/menu.scala.html +++ /dev/null @@ -1,14 +0,0 @@ -@(active: String, s: Option[lila.streamer.Streamer.WithUser])(implicit ctx: Context) - -All streamers - -@s.map { st => -@st.streamer.name -@if(ctx.is(st.user) || isGranted(_.Streamers)) { -Edit streamer page -} -}.getOrElse { -Your streamer page -} -Streamer community program -Download streamer kit diff --git a/app/views/streamer/pic.scala.html b/app/views/streamer/pic.scala.html deleted file mode 100644 index ac50e4116d..0000000000 --- a/app/views/streamer/pic.scala.html +++ /dev/null @@ -1,6 +0,0 @@ -@(s: lila.streamer.Streamer, u: User, size: Int)(implicit ctx: Context) -@s.picturePath.map { path => -@u.titleUsername lichess streamer -}.getOrElse { - -} diff --git a/app/views/streamer/picture.scala b/app/views/streamer/picture.scala new file mode 100644 index 0000000000..25e40b486c --- /dev/null +++ b/app/views/streamer/picture.scala @@ -0,0 +1,41 @@ +package views.html.streamer + +import controllers.routes +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +object picture { + + def apply(s: lila.streamer.Streamer.WithUser, error: Option[String] = None)(implicit ctx: Context) = + views.html.base.layout( + title = s"${s.user.titleUsername} streamer picture", + moreJs = jsTag("streamer.form.js"), + moreCss = cssTag("streamer.form") + ) { + main(cls := "streamer-picture small-page box")( + h1(userLink(s.user), " streamer picture"), + div(cls := "picture_wrap")(bits.pic(s.streamer, s.user, 250)), + div(cls := "forms")( + error.map { badTag(_) }, + st.form( + action := routes.Streamer.pictureApply, + method := "post", + enctype := "multipart/form-data", + cls := "upload" + )( + p("Max size: ", lila.db.Photographer.uploadMaxMb, "MB."), + form3.file.image("picture"), + button(tpe := "submit", cls := "button")("Upload profile picture") + ), + s.streamer.hasPicture option + st.form(action := routes.Streamer.pictureDelete, method := "post", cls := "delete")( + button(tpe := "submit", cls := "button button-red")("Delete profile picture") + ), + div(cls := "cancel")( + a(href := routes.Streamer.edit, cls := "text", dataIcon := "I")("Return to streamer page form") + ) + ) + ) + } +} diff --git a/app/views/streamer/picture.scala.html b/app/views/streamer/picture.scala.html deleted file mode 100644 index d6b6195ddd..0000000000 --- a/app/views/streamer/picture.scala.html +++ /dev/null @@ -1,32 +0,0 @@ -@(s: lila.streamer.Streamer.WithUser, error: Option[String] = None)(implicit ctx: Context) - -@base.layout(title = s"${s.user.titleUsername} streamer picture", -moreJs = jsTag("streamer.form.js"), -moreCss = cssTags("form3.css", "streamer.form.css")) { -
    -

    - @userLink(s.user) streamer picture -

    -
    - @pic(s.streamer, s.user, 200) -
    -
    - @error.map { e => -

    @e

    - } - @helper.form(action = routes.Streamer.pictureApply, 'enctype -> "multipart/form-data", 'class -> "upload") { -

    Max size: @{lila.db.Photographer.uploadMaxMb}MB.

    - @form3.file.image("picture") - - } - @if(s.streamer.hasPicture) { - @helper.form(action = routes.Streamer.pictureDelete, 'enctype -> "multipart/form-data", 'class -> "delete") { - - } - } - -
    -
    -}.toHtml diff --git a/app/views/streamer/rules.scala.html b/app/views/streamer/rules.scala.html deleted file mode 100644 index 7dc8005368..0000000000 --- a/app/views/streamer/rules.scala.html +++ /dev/null @@ -1,7 +0,0 @@ -@() -
      -
    • Be listed as a lichess streamer.
    • -
    • Get bumped up the top of the list when you stream with the keyword "lichess.org" in the stream title.
    • -
    • Notify your lichess followers when you start streaming.
    • -
    • Promote your stream in your games and tournaments.
    • -
    diff --git a/app/views/streamer/show.scala b/app/views/streamer/show.scala new file mode 100644 index 0000000000..493cf5c0bb --- /dev/null +++ b/app/views/streamer/show.scala @@ -0,0 +1,96 @@ +package views.html.streamer + +import controllers.routes +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.String.html.richText +import lila.streamer.Stream.{ Twitch, YouTube } + +object show { + + def apply( + s: lila.streamer.Streamer.WithUserAndStream, + activities: Vector[lila.activity.ActivityView], + following: Boolean + )(implicit ctx: Context) = views.html.base.layout( + title = s"${s.titleName} streams chess", + moreCss = cssTag("streamer.show"), + moreJs = embedJsUnsafe(""" +$(function() { +$('button.follow').click(function() { +var klass = 'active'; +$(this).toggleClass(klass); +$.ajax({ +url: '/rel/' + ($(this).hasClass('active') ? 'follow/' : 'unfollow/') + $(this).data('user'), +method:'post' +}); +}); +});"""), + openGraph = lila.app.ui.OpenGraph( + title = s"${s.titleName} streams chess", + description = shorten(~(s.streamer.headline.map(_.value) orElse s.streamer.description.map(_.value)), 152), + url = s"$netBaseUrl${routes.Streamer.show(s.user.username)}", + `type` = "video", + image = s.streamer.picturePath.map(p => dbImageUrl(p.value)) + ).some, + csp = defaultCsp.withTwitch.some + )( + main(cls := "page-menu streamer-show")( + st.aside(cls := "page-menu__menu")( + s.streamer.approval.chatEnabled option div(cls := "streamer-chat")( + s.stream match { + case Some(YouTube.Stream(_, _, videoId, _)) => iframe( + st.frameborder := "0", + frame.scrolling := "no", + src := s"https://www.youtube.com/live_chat?v=$videoId&embed_domain=$netDomain" + ) + case _ => s.streamer.twitch.map { twitch => + iframe( + st.frameborder := "0", + frame.scrolling := "yes", + src := s"https://twitch.tv/embed/${twitch.userId}/chat${(ctx.currentBg != "light") ?? "?darkpopout"}" + ) + } + } + ), + bits.menu("show", s.withoutStream.some), + a(cls := "blocker button button-metal", href := "https://getublockorigin.com")( + i(dataIcon := ""), + strong("Install a malware blocker!"), + "Be safe from ads and trackers", br, + "infesting Twitch and YouTube.", br, + "Lichess recommend uBlock Origin", br, + "which is free and open-source." + ) + ), + div(cls := "page-menu__content")( + s.stream match { + case Some(YouTube.Stream(_, _, videoId, _)) => div(cls := "box embed youTube")( + iframe( + src := s"https://www.youtube.com/embed/$videoId?autoplay=1", + st.frameborder := "0", + frame.allowfullscreen + ) + ) + case _ => s.streamer.twitch.map { twitch => + div(cls := "box embed twitch")( + iframe( + src := s"https://player.twitch.tv/?channel=${twitch.userId}", + frame.allowfullscreen + ) + ) + } getOrElse div(cls := "box embed")(div(cls := "nostream")("OFFLINE")) + }, + div(cls := "box streamer")( + header(s, following.some), + div(cls := "description")(richText(s.streamer.description.fold("")(_.value))), + a(cls := "ratings", href := routes.User.show(s.user.username))( + s.user.best6Perfs.map { showPerfRating(s.user, _) } + ), + views.html.activity(s.user, activities) + ) + ) + ) + ) +} diff --git a/app/views/streamer/show.scala.html b/app/views/streamer/show.scala.html deleted file mode 100644 index 52e2accdce..0000000000 --- a/app/views/streamer/show.scala.html +++ /dev/null @@ -1,110 +0,0 @@ -@(s: lila.streamer.Streamer.WithUserAndStream, activities: Vector[lila.activity.ActivityView], following: Boolean)(implicit ctx: Context) - -@import lila.streamer.Stream.{ Twitch, YouTube } - -@side = { -@if(s.streamer.approval.chatEnabled) { -
    - @s.stream match { - case Some(YouTube.Stream(_, _, videoId, _)) => { - - } - case _ => { - @s.streamer.twitch.map { twitch => - - } - } - } -
    -} -
    - @menu("show", s.withoutStream.some) -
    - - - Install a malware blocker! - Be safe from ads and trackers
    - infesting Twitch and YouTube.
    - We recommend uBlock Origin
    - which is free and open-source. -
    -} - -@moreCss = { -@cssTag("streamer.show.css") -@cssTag("activity.css") -} - -@moreJs = { -@embedJs { -$(function() { -$('button.follow').click(function() { -var klass = 'active'; -$(this).toggleClass(klass); -$.ajax({ -url: '/rel/' + ($(this).hasClass('active') ? 'follow/' : 'unfollow/') + $(this).data('user'), -method:'post' -}); -}); -}); -} -} - -@title = @{ s"${s.titleName} streams chess" } - -@base.layout(title = title, -side = side.some, -moreCss = moreCss, -moreJs = moreJs, -openGraph = lila.app.ui.OpenGraph( -title = title, -description = shorten(~(s.streamer.headline.map(_.value) orElse s.streamer.description.map(_.value)), 152), -url = s"$netBaseUrl${routes.Streamer.show(s.user.username)}", -`type` = "video", -image = s.streamer.picturePath.map(p => dbImageUrl(p.value))).some, -csp = defaultCsp.withTwitch.some) { -@s.stream match { -case Some(YouTube.Stream(_, _, videoId, _)) => { -
    - -
    -} -case _ => { -@s.streamer.twitch.map { twitch => -
    - -
    -}.getOrElse { -
    OFFLINE
    -} -} -} -
    - @header(s, following.some) -
    @richText(s.streamer.description.fold("")(_.value))
    - - @s.user.best6Perfs.map { pt => - @showPerfRating(s.user, pt) - } - - @views.html.activity(s.user, activities).toHtml -
    -}.toHtml diff --git a/app/views/study/bits.scala b/app/views/study/bits.scala index 84102a582e..b07ab4abfb 100644 --- a/app/views/study/bits.scala +++ b/app/views/study/bits.scala @@ -4,7 +4,6 @@ package study import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ -import lila.common.String.html.safeJsonValue import lila.user.User import controllers.routes @@ -12,38 +11,40 @@ import controllers.routes object bits { def newButton()(implicit ctx: Context) = ctx.isAuth option - form(cls := "new_study", action := routes.Study.create, method := "post")( - button(`type` := "submit", cls := "button")("New study") + form(cls := "new-study", action := routes.Study.create, method := "post")( + button(tpe := "submit", cls := "button")("New study") ) def newForm()(implicit ctx: Context) = - form(cls := "new_study", action := routes.Study.create, method := "post")( - button(`type` := "submit", cls := "button frameless hint--top", dataHint := "New study")( - iconTag("O") - ) + form(cls := "new-study", action := routes.Study.create, method := "post")( + button(tpe := "submit", cls := "button button-green", dataIcon := "O", title := "New study") ) - def authLinks(me: User, active: String, order: lila.study.Order)(implicit ctx: Context) = frag( - a(cls := "mine" == active option "mine", href := routes.Study.mine(order.key))("My studies"), - a(cls := "mineMember" == active option "mineMember", href := routes.Study.mineMember(order.key))("Studies I contribute to"), - a(cls := "minePublic" == active option "minePublic", href := routes.Study.minePublic(order.key))("My public studies"), - a(cls := "minePrivate" == active option "minePrivate", href := routes.Study.minePrivate(order.key))("My private studies"), - a(cls := "mineLikes" == active option "mineLikes", href := routes.Study.mineLikes(order.key))("Favourite studies") - ) + def authLinks(me: User, active: String, order: lila.study.Order)(implicit ctx: Context) = { + def activeCls(c: String) = cls := (c == active).option("active") + frag( + a(activeCls("mine"), href := routes.Study.mine(order.key))("My studies"), + a(activeCls("mineMember"), href := routes.Study.mineMember(order.key))("Studies I contribute to"), + a(activeCls("minePublic"), href := routes.Study.minePublic(order.key))("My public studies"), + a(activeCls("minePrivate"), href := routes.Study.minePrivate(order.key))("My private studies"), + a(activeCls("mineLikes"), href := routes.Study.mineLikes(order.key))("Favourite studies") + ) + } - def widget(s: lila.study.Study.WithChaptersAndLiked)(implicit ctx: Context) = frag( + def widget(s: lila.study.Study.WithChaptersAndLiked, tag: Tag = h2)(implicit ctx: Context) = frag( a(cls := "overlay", href := routes.Study.show(s.study.id.value)), - h2( - iconTag("4")(cls := "icon"), - strong(s.study.name.value), - span( - iconTag(if (s.liked) "" else ""), - " ", - s.study.likes.value, - " • ", - usernameOrId(s.study.ownerId), - " • ", - momentFromNow(s.study.createdAt) + div(cls := "top", dataIcon := "4")( + div( + tag(cls := "study-name")(s.study.name.value), + span( + iconTag(if (s.liked) "" else ""), + " ", + s.study.likes.value, + " • ", + usernameOrId(s.study.ownerId), + " • ", + momentFromNow(s.study.createdAt) + ) ) ), div(cls := "body")( @@ -59,4 +60,11 @@ object bits { ) ) ) + + def streamers(streams: List[lila.streamer.Stream]) = + streams.nonEmpty option div(cls := "streamers none")( + streams.map { s => + views.html.streamer.bits.contextual(s.streamer.userId) + } + ) } diff --git a/app/views/study/clone.scala b/app/views/study/clone.scala index 012f1427fa..035208188f 100644 --- a/app/views/study/clone.scala +++ b/app/views/study/clone.scala @@ -1,7 +1,5 @@ package views.html.study -import play.api.libs.json.Json - import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ diff --git a/app/views/study/create.scala b/app/views/study/create.scala index 34d55e0a47..a3726605f8 100644 --- a/app/views/study/create.scala +++ b/app/views/study/create.scala @@ -5,7 +5,6 @@ import play.api.libs.json.Json import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ -import lila.common.String.html.safeJsonValue import lila.study.Study import controllers.routes @@ -20,27 +19,29 @@ object create { title = "Study", icon = Some("4"), back = true, - moreCss = cssTag("study-create.css").some + moreCss = cssTag("study.create").some ) { - form(action := routes.Study.create, method := "POST")( - input(`type` := "hidden", name := "gameId", value := data.gameId), - input(`type` := "hidden", name := "orientation", value := data.orientationStr), - input(`type` := "hidden", name := "fen", value := data.fenStr), - input(`type` := "hidden", name := "pgn", value := data.pgnStr), - input(`type` := "hidden", name := "variant", value := data.variantStr), - h2("So, where do you want to study that?"), - p( - button(name := "as", value := "study", - `type` := "submit", cls := "submit button large new text", dataIcon := "4")("New study") - ), - div(cls := "studies")( - div( - h2("My studies"), - owner map studyButton + div(cls := "study-create")( + form(action := routes.Study.create, method := "POST")( + input(tpe := "hidden", name := "gameId", value := data.gameId), + input(tpe := "hidden", name := "orientation", value := data.orientationStr), + input(tpe := "hidden", name := "fen", value := data.fenStr), + input(tpe := "hidden", name := "pgn", value := data.pgnStr), + input(tpe := "hidden", name := "variant", value := data.variantStr), + h2("So, where do you want to study that?"), + p( + button(name := "as", value := "study", + tpe := "submit", cls := "submit button large new text", dataIcon := "4")("New study") ), - div( - h2("Studies I contribute to"), - contrib map studyButton + div(cls := "studies")( + div( + h2("My studies"), + owner map studyButton + ), + div( + h2("Studies I contribute to"), + contrib map studyButton + ) ) ) ) diff --git a/app/views/study/embed.scala b/app/views/study/embed.scala index 9d7a3db42e..0d2f1ff1ce 100644 --- a/app/views/study/embed.scala +++ b/app/views/study/embed.scala @@ -1,87 +1,80 @@ package views.html.study import play.api.libs.json.Json -import scalatags.Text.tags2.{ title => titleTag } +import play.api.mvc.RequestHeader -import lila.api.Context import lila.app.templating.Environment._ +import lila.app.ui.EmbedConfig import lila.app.ui.ScalatagsTemplate._ import lila.common.String.html.safeJsonValue +import views.html.base.layout.{ bits => layout } import controllers.routes object embed { - import views.html.base.layout.bits._ + import EmbedConfig.implicits._ - private def bodyClass(implicit ctx: Context) = List( - "base" -> true, - ctx.currentTheme.cssClass -> true, - (if (ctx.currentBg == "transp") "dark transp" else ctx.currentBg) -> true - ) - - def apply(s: lila.study.Study, chapter: lila.study.Chapter, data: lila.study.JsonView.JsData)(implicit ctx: Context) = frag( - doctype, - htmlTag(ctx)( - topComment, + def apply(s: lila.study.Study, chapter: lila.study.Chapter, data: lila.study.JsonView.JsData)(implicit config: EmbedConfig) = frag( + layout.doctype, + layout.htmlTag(config.lang)( head( - charset, - metaCsp(none), - titleTag(s"${s.name} ${chapter.name}"), - fontStylesheets, - currentBgCss, - cssTags("common.css", "board.css", "analyse.css", "analyse-embed.css"), - pieceSprite + layout.charset, + layout.viewport, + layout.metaCsp(basicCsp withNonce config.nonce), + st.headTitle(s"${s.name} ${chapter.name}"), + layout.pieceSprite(lila.pref.PieceSet.default), + cssTagWithTheme("analyse.embed", config.bg) ), - body(cls := bodyClass ::: List( - "highlight" -> true, - "piece_letter" -> ctx.pref.pieceNotationIsLetter + body(cls := List( + s"highlight ${config.bg} ${config.board}" -> true ))( div(cls := "is2d")( - div(cls := "embedded_study analyse cg-512")(miniBoardContent) + main(cls := "analyse") ), footer { val url = routes.Study.chapter(s.id.value, chapter.id.value) - div(cls := "left")( - a(target := "_blank", href := url)(h1(s.name.value)), - " ", - em("brought to you by ", a(target := "_blank", href := netBaseUrl)(netDomain)) + frag( + div(cls := "left")( + a(target := "_blank", href := url)(h1(s.name.value)), + " ", + em("brought to you by ", a(target := "_blank", href := netBaseUrl)(netDomain)) + ), + a(target := "_blank", cls := "open", href := url)("Open") ) - a(target := "_blank", cls := "open", href := url)("Open") }, jQueryTag, jsTag("vendor/mousetrap.js"), jsAt("compiled/util.js"), jsAt("compiled/trans.js"), + jsAt("compiled/embed-analyse.js"), analyseTag, - jsTag("embed-analyse.js"), - embedJs(s"""lichess.startEmbeddedAnalyse({ -element: document.querySelector('.embedded_study'), -study: ${safeJsonValue(data.study)}, -data: ${safeJsonValue(data.analysis)}, -embed: true, -i18n: ${views.html.board.userAnalysisI18n()}, -userId: null -});""") + embedJsUnsafe(s"""lichess.startEmbeddedAnalyse(${ + safeJsonValue(Json.obj( + "study" -> data.study, + "data" -> data.analysis, + "embed" -> true, + "i18n" -> views.html.board.userAnalysisI18n(), + "userId" -> none[String] + )) + })""", config.nonce) ) ) ) - def notFound()(implicit ctx: Context) = frag( - doctype, - htmlTag(ctx)( - topComment, + def notFound(implicit config: EmbedConfig) = frag( + layout.doctype, + layout.htmlTag(config.lang)( head( - charset, - metaCsp(none), - titleTag("404 - Study not available"), - fontStylesheets, - currentBgCss, - cssTags("common.css", "analyse-embed.css") + layout.charset, + layout.viewport, + layout.metaCsp(basicCsp), + st.headTitle("404 - Study not found"), + cssTagWithTheme("analyse.round.embed", "dark") ), - body(cls := bodyClass)( - div(cls := "not_found")( - h1("Study not available") + body(cls := "dark")( + div(cls := "not-found")( + h1("Study not found") ) ) ) diff --git a/app/views/study/list.scala b/app/views/study/list.scala index 0b4cc122a0..af4ec3e788 100644 --- a/app/views/study/list.scala +++ b/app/views/study/list.scala @@ -7,14 +7,15 @@ import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ import lila.common.paginator.Paginator -import lila.common.String.html.safeJsonValue +import lila.study.Order +import lila.study.Study.WithChaptersAndLiked import lila.user.User import controllers.routes object list { - def all(pag: Paginator[lila.study.Study.WithChaptersAndLiked], order: lila.study.Order)(implicit ctx: Context) = layout( + def all(pag: Paginator[WithChaptersAndLiked], order: Order)(implicit ctx: Context) = layout( title = s"All studies", active = "all", order = order, @@ -23,7 +24,7 @@ object list { url = o => routes.Study.all(o) )("All studies") - def byOwner(pag: Paginator[lila.study.Study.WithChaptersAndLiked], order: lila.study.Order, owner: User)(implicit ctx: Context) = layout( + def byOwner(pag: Paginator[WithChaptersAndLiked], order: Order, owner: User)(implicit ctx: Context) = layout( title = s"Studies created by ${owner.titleUsername}", active = "owner", order = order, @@ -35,7 +36,7 @@ object list { "'s studies" )) - def mine(pag: Paginator[lila.study.Study.WithChaptersAndLiked], order: lila.study.Order, me: User)(implicit ctx: Context) = layout( + def mine(pag: Paginator[WithChaptersAndLiked], order: Order, me: User)(implicit ctx: Context) = layout( title = s"My studies", active = "mine", order = order, @@ -45,8 +46,8 @@ object list { )("My studies") def mineLikes( - pag: Paginator[lila.study.Study.WithChaptersAndLiked], - order: lila.study.Order, + pag: Paginator[WithChaptersAndLiked], + order: Order, me: User )(implicit ctx: Context) = layout( title = "My favourite studies", @@ -57,7 +58,7 @@ object list { url = o => routes.Study.mineLikes(o) )("My favourite studies") - def mineMember(pag: Paginator[lila.study.Study.WithChaptersAndLiked], order: lila.study.Order, me: User)(implicit ctx: Context) = layout( + def mineMember(pag: Paginator[WithChaptersAndLiked], order: Order, me: User)(implicit ctx: Context) = layout( title = s"Studies I contribute to", active = "mineMember", order = order, @@ -66,7 +67,7 @@ object list { url = o => routes.Study.mineMember(o) )("Studies I contribute to") - def minePublic(pag: Paginator[lila.study.Study.WithChaptersAndLiked], order: lila.study.Order, me: User)(implicit ctx: Context) = layout( + def minePublic(pag: Paginator[WithChaptersAndLiked], order: Order, me: User)(implicit ctx: Context) = layout( title = "My public studies", active = "minePublic", order = order, @@ -75,7 +76,7 @@ object list { url = o => routes.Study.minePublic(o) )("My public studies") - def minePrivate(pag: Paginator[lila.study.Study.WithChaptersAndLiked], order: lila.study.Order, me: User)(implicit ctx: Context) = layout( + def minePrivate(pag: Paginator[WithChaptersAndLiked], order: Order, me: User)(implicit ctx: Context) = layout( title = "My private studies", active = "minePrivate", order = order, @@ -84,68 +85,78 @@ object list { url = o => routes.Study.minePrivate(o) )("My private studies") - private[study] def paginate(pager: Paginator[lila.study.Study.WithChaptersAndLiked], url: Call)(implicit ctx: Context) = + def search(pag: Paginator[WithChaptersAndLiked], text: String)(implicit ctx: Context) = + views.html.base.layout( + title = text, + moreCss = cssTag("study.index"), + moreJs = infiniteScrollTag + ) { + main(cls := "page-menu")( + menu("search", Order.default), + main(cls := "page-menu__content study-index box")( + div(cls := "box__top")( + searchForm(trans.search.txt(), text), + bits.newForm() + ), + paginate(pag, routes.Study.search(text)) + ) + ) + } + + private[study] def paginate(pager: Paginator[WithChaptersAndLiked], url: Call)(implicit ctx: Context) = if (pager.currentPageResults.isEmpty) div(cls := "nostudies")( iconTag("4"), p("None yet.") ) - else div(cls := "list infinitescroll")( + else div(cls := "studies list infinitescroll")( pager.currentPageResults.map { s => div(cls := "study paginated")(bits.widget(s)) }, - pager.nextPage.map { np => - div(cls := "pager none")( - a(rel := "next", href := addQueryParameter(url.toString, "page", np))("Next") - ) - } + pagerNext(pager, np => addQueryParameter(url.url, "page", np)) ) - private def orderChoice( - url: lila.study.Order => Call, - order: lila.study.Order, - orders: List[lila.study.Order] = lila.study.Order.all - )(implicit ctx: Context) = div(cls := "orders mselect")( - div(cls := "button")( - order.name, - iconTag("u") - ), - div(cls := "list")( - orders.map { o => - a(href := url(o))(o.name) - } + private[study] def menu(active: String, order: Order)(implicit ctx: Context) = + st.aside(cls := "page-menu__menu subnav")( + a(cls := active.active("all"), href := routes.Study.all(order.key))("All studies"), + ctx.me.map { bits.authLinks(_, active, order) }, + a(cls := "text", dataIcon := "", href := "/blog/V0KrLSkAAMo3hsi4/study-chess-the-lichess-way")("What are studies?") + ) + + private[study] def searchForm(placeholder: String, value: String) = + form(cls := "search", action := routes.Study.search(), method := "get")( + input(name := "q", st.placeholder := placeholder, st.value := value), + button(tpe := "submit", cls := "button", dataIcon := "y") ) - ) private def layout( title: String, active: String, - order: lila.study.Order, - pag: Paginator[lila.study.Study.WithChaptersAndLiked], + order: Order, + pag: Paginator[WithChaptersAndLiked], url: controllers.Study.ListUrl, searchFilter: String )(titleFrag: Frag)(implicit ctx: Context) = views.html.base.layout( title = title, - menu = Some(frag( - a( - cls := active.active("all"), - href := routes.Study.all(order.key) - )("All studies"), - ctx.me.map { bits.authLinks(_, active, order) }, - a(cls := "text", dataIcon := "", href := "//lichess.org/blog/V0KrLSkAAMo3hsi4/study-chess-the-lichess-way")("What are studies?") - )), - moreCss = cssTag("studyList.css"), + moreCss = cssTag("study.index"), + wrapClass = "full-screen-force", moreJs = infiniteScrollTag ) { - div(cls := "content_box no_padding studies")( - div(cls := "top")( - form(cls := "search", action := routes.Study.search(), method := "get")( - input(name := "q", placeholder := title, value := s"$searchFilter${searchFilter.nonEmpty ?? " "}"), - button(`type` := "submit", cls := "submit button", dataIcon := "y") + main(cls := "page-menu")( + menu(active, order), + main(cls := "page-menu__content study-index box")( + div(cls := "box__top")( + searchForm(title, s"$searchFilter${searchFilter.nonEmpty ?? " "}"), + views.html.base.bits.mselect( + "orders", + span(order.name), + (if (active == "all") Order.allButOldest else Order.all) map { o => + a(href := url(o.key), cls := (order == o).option("current"))(o.name) + } + ), + bits.newForm() ), - orderChoice(o => url(o.key), order, if (active == "all") lila.study.Order.allButOldest else lila.study.Order.all), - bits.newForm() - ), - paginate(pag, url(order.key)) + paginate(pag, url(order.key)) + ) ) } } diff --git a/app/views/study/search.scala b/app/views/study/search.scala deleted file mode 100644 index 14b096ef47..0000000000 --- a/app/views/study/search.scala +++ /dev/null @@ -1,37 +0,0 @@ -package views.html -package study - -import play.api.mvc.Call - -import lila.api.Context -import lila.app.templating.Environment._ -import lila.app.ui.ScalatagsTemplate._ -import lila.common.paginator.Paginator -import lila.study.Order - -import controllers.routes - -object search { - - def apply(pag: Paginator[lila.study.Study.WithChaptersAndLiked], text: String)(implicit ctx: Context) = - views.html.base.layout( - title = text, - menu = Some(frag( - a(href := routes.Study.all(Order.default.key))("All studies"), - ctx.me.map { bits.authLinks(_, "search", Order.default) }, - a(cls := "text", dataIcon := "", href := "//lichess.org/blog/V0KrLSkAAMo3hsi4/study-chess-the-lichess-way")("What are studies?") - )), - moreCss = cssTag("studyList.css"), - moreJs = infiniteScrollTag - ) { - div(cls := "content_box no_padding studies search")( - div(cls := "top")( - form(cls := "search", action := routes.Study.search(), method := "get")( - input(name := "q", placeholder := trans.search.txt(), value := text) - ), - bits.newForm() - ), - list.paginate(pag, routes.Study.search(text)) - ) - } -} diff --git a/app/views/study/show.scala b/app/views/study/show.scala index 01557cf91f..e72a905805 100644 --- a/app/views/study/show.scala +++ b/app/views/study/show.scala @@ -19,47 +19,35 @@ object show { streams: List[lila.streamer.Stream] )(implicit ctx: Context) = views.html.base.layout( title = s.name.value, - side = Some(div(cls := "side_box study_box")( - streams.map { s => - a( - href := routes.Streamer.show(s.streamer.userId), - cls := "context-streamer text side_box", - dataIcon := "" - )( - usernameOrId(s.streamer.userId), - " is streaming" - ) - } - )), - chat = views.html.chat.frag.some, - underchat = Some(views.html.game.bits.watchers), - moreCss = cssTags("analyse.css", "study.css", "chat.css"), + moreCss = cssTag("analyse.study"), moreJs = frag( analyseTag, analyseNvuiTag, - embedJs(s"""lichess=lichess||{};lichess.study={ -study: ${safeJsonValue(data.study)}, -data: ${safeJsonValue(data.analysis)}, -i18n: ${views.html.board.userAnalysisI18n()}, -tagTypes: '${lila.study.PgnTags.typesToString}', -userId: $jsUserIdString, -chat: ${ - chatOption.fold("null")(c => safeJsonValue(views.html.chat.json( - c.chat, - name = trans.chatRoom.txt(), - timeout = c.timeout, - writeable = ctx.userId.??(s.canChat), - public = false, - localMod = ctx.userId.??(s.canContribute) - ))) - }, -explorer: { -endpoint: "$explorerEndpoint", -tablebaseEndpoint: "$tablebaseEndpoint" -}, -socketUrl: "${routes.Study.websocket(s.id.value, apiVersion.value)}", -socketVersion: $socketVersion -};""") + embedJsUnsafe(s"""lichess=window.lichess||{};lichess.study=${ + safeJsonValue(Json.obj( + "study" -> data.study, + "data" -> data.analysis, + "i18n" -> views.html.board.userAnalysisI18n(), + "tagTypes" -> lila.study.PgnTags.typesToString, + "userId" -> ctx.userId, + "chat" -> chatOption.map { c => + views.html.chat.json( + c.chat, + name = trans.chatRoom.txt(), + timeout = c.timeout, + writeable = ctx.userId.??(s.canChat), + public = false, + localMod = ctx.userId.??(s.canContribute) + ) + }, + "explorer" -> Json.obj( + "endpoint" -> explorerEndpoint, + "tablebaseEndpoint" -> tablebaseEndpoint + ), + "socketUrl" -> routes.Study.websocket(s.id.value, apiVersion.value).url, + "socketVersion" -> socketVersion.value + )) + }""") ), robots = s.isPublic, chessground = false, @@ -69,7 +57,8 @@ socketVersion: $socketVersion url = s"$netBaseUrl${routes.Study.show(s.id.value).url}", description = s"A chess study by ${usernameOrId(s.ownerId)}" ).some - ) { - div(cls := "analyse cg-512")(views.html.board.bits.domPreload(none)) - } + )(frag( + main(cls := "analyse"), + bits.streamers(streams) + )) } diff --git a/app/views/team/admin.scala b/app/views/team/admin.scala new file mode 100644 index 0000000000..17304a2bd6 --- /dev/null +++ b/app/views/team/admin.scala @@ -0,0 +1,56 @@ +package views.html.team + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object admin { + + def changeOwner(t: lila.team.Team, userIds: Iterable[lila.user.User.ID])(implicit ctx: Context) = { + + val title = s"Change owner of Team ${t.name}" + + bits.layout(title = title) { + main(cls := "page-menu page-small")( + bits.menu(none), + div(cls := "page-menu__content box box-pad")( + h1(title), + p("Who do you want to make owner of this team?"), + br, br, + st.form(cls := "kick", action := routes.Team.changeOwner(t.id), method := "POST")( + userIds.toList.sorted.map { userId => + button(name := "userId", cls := "button button-empty button-no-upper confirm", value := userId)( + usernameOrId(userId) + ) + } + ) + ) + ) + } + } + + def kick(t: lila.team.Team, userIds: Iterable[lila.user.User.ID])(implicit ctx: Context) = { + + val title = s"Kick from Team ${t.name}" + + bits.layout(title = title) { + main(cls := "page-menu page-small")( + bits.menu(none), + div(cls := "page-menu__content box box-pad")( + h1(title), + p("Who do you want to kick out of the team?"), + br, br, + st.form(cls := "kick", action := routes.Team.kick(t.id), method := "POST")( + userIds.toList.sorted.map { userId => + button(name := "userId", cls := "button button-empty button-no-upper confirm", value := userId)( + usernameOrId(userId) + ) + } + ) + ) + ) + } + } +} diff --git a/app/views/team/all.scala.html b/app/views/team/all.scala.html deleted file mode 100644 index edf427d61e..0000000000 --- a/app/views/team/all.scala.html +++ /dev/null @@ -1,7 +0,0 @@ -@(teams: Paginator[lila.team.Team])(implicit ctx: Context) - -@team.list( -name = trans.teams.txt(), -teams = teams, -next = teams.nextPage map { n => routes.Team.all(n) }, -tab = "all") diff --git a/app/views/team/allRequests.scala.html b/app/views/team/allRequests.scala.html deleted file mode 100644 index 958f06ef33..0000000000 --- a/app/views/team/allRequests.scala.html +++ /dev/null @@ -1,13 +0,0 @@ -@(requests: List[lila.team.RequestWithUser])(implicit ctx: Context) - -@title = @{ requests.size + " join requests" } - -@team.layout( -title = title, -currentTab = "requests".some) { -
    -

    @title

    - @team.requests(requests, none) -
    -} - diff --git a/app/views/team/bits.scala b/app/views/team/bits.scala new file mode 100644 index 0000000000..d27f2218b9 --- /dev/null +++ b/app/views/team/bits.scala @@ -0,0 +1,52 @@ +package views.html.team + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator + +import controllers.routes + +object bits { + + def menu(currentTab: Option[String])(implicit ctx: Context) = ~currentTab |> { tab => + st.nav(cls := "page-menu__menu subnav")( + (ctx.teamNbRequests > 0) option + a(cls := tab.active("requests"), href := routes.Team.requests())( + ctx.teamNbRequests, " join requests" + ), + ctx.me.??(_.canTeam) option + a(cls := tab.active("mine"), href := routes.Team.mine())( + trans.myTeams() + ), + a(cls := tab.active("all"), href := routes.Team.all())( + trans.allTeams() + ), + ctx.me.??(_.canTeam) option + a(cls := tab.active("form"), href := routes.Team.form())( + trans.newTeam() + ) + ) + } + + private[team] def teamTr(t: lila.team.Team)(implicit ctx: Context) = tr(cls := "paginated")( + td(cls := "subject")( + a(dataIcon := "f", cls := List( + "team-name text" -> true, + "mine" -> myTeam(t.id) + ), href := routes.Team.show(t.id))(t.name), + shorten(t.description, 200) + ), + td(cls := "info")( + p(trans.nbMembers.plural(t.nbMembers, t.nbMembers.localize)) + ) + ) + + private[team] def layout(title: String, openGraph: Option[lila.app.ui.OpenGraph] = None)(body: Frag)(implicit ctx: Context) = + views.html.base.layout( + title = title, + moreCss = cssTag("team"), + moreJs = infiniteScrollTag, + openGraph = openGraph + )(body) +} diff --git a/app/views/team/changeOwner.scala.html b/app/views/team/changeOwner.scala.html deleted file mode 100644 index 8fbc17870c..0000000000 --- a/app/views/team/changeOwner.scala.html +++ /dev/null @@ -1,17 +0,0 @@ -@(t: lila.team.Team, userIds: Iterable[User.ID])(implicit ctx: Context) - -@title = @{ "Change owner of Team " + t.name } - -@team.layout(title = title) { -
    -
    -

    @title

    -

    Who do you want to make owner of this team?

    -
    - @userIds.toList.sorted.map { userId => - - } -
    -
    -
    -} diff --git a/app/views/team/edit.scala.html b/app/views/team/edit.scala.html deleted file mode 100644 index 714d091527..0000000000 --- a/app/views/team/edit.scala.html +++ /dev/null @@ -1,27 +0,0 @@ -@(t: lila.team.Team, form: Form[_])(implicit ctx: Context) -@import lila.app.ui.ScalatagsTwirlForm._ - -@title = @{ "Edit Team " + t.name } - -@team.layout(title = title, formCss = true) { -
    -
    -

    @title

    - -
    - @form3.group(form("open"), trans.joiningPolicy.frag()) { f => - @form3.select(f, Seq(0 -> trans.aConfirmationIsRequiredToJoin.txt(), 1 -> trans.anyoneCanJoin.txt())) - } - @form3.group(form("location"), trans.location.frag())(form3.input(_)) - @form3.group(form("description"), trans.description.frag())(form3.textarea(_)(*.rows := 10)) - @form3.actionsHtml { - @trans.cancel() - @form3.submit(trans.apply.frag()) - } -
    -
    -
    -} diff --git a/app/views/team/form.scala b/app/views/team/form.scala new file mode 100644 index 0000000000..9eb3a73e58 --- /dev/null +++ b/app/views/team/form.scala @@ -0,0 +1,72 @@ +package views.html.team + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object form { + + def create(form: Form[_], captcha: lila.common.Captcha)(implicit ctx: Context) = + views.html.base.layout( + title = trans.newTeam.txt(), + moreCss = cssTag("team"), + moreJs = frag(infiniteScrollTag, captchaTag) + ) { + main(cls := "page-menu page-small")( + bits.menu("form".some), + div(cls := "page-menu__content box box-pad")( + h1(trans.newTeam()), + st.form(cls := "form3", action := routes.Team.create(), method := "POST")( + form3.globalError(form), + form3.group(form("name"), trans.name())(form3.input(_)), + form3.group(form("open"), trans.joiningPolicy()) { f => + form3.select(form("open"), Seq(0 -> trans.aConfirmationIsRequiredToJoin.txt(), 1 -> trans.anyoneCanJoin.txt())) + }, + form3.group(form("location"), trans.location())(form3.input(_)), + form3.group(form("description"), trans.description())(form3.textarea(_)(rows := 10)), + views.html.base.captcha(form, captcha), + form3.actions( + a(href := routes.Team.home(1))(trans.cancel()), + form3.submit(trans.newTeam()) + ) + ) + ) + ) + } + + def edit(t: lila.team.Team, form: Form[_])(implicit ctx: Context) = { + val title = "Edit Team " + t.name + bits.layout(title = title) { + main(cls := "page-menu page-small")( + bits.menu(none), + div(cls := "page-menu__content box box-pad")( + h1(title), + st.form(cls := "form3", action := routes.Team.update(t.id), method := "POST")( + div(cls := "form-group")( + a(cls := "button button-empty", href := routes.Team.kick(t.id))("Kick someone out of the team"), + a(cls := "button button-empty", href := routes.Team.changeOwner(t.id))("Appoint another team owner") + ), + form3.group(form("open"), trans.joiningPolicy()) { f => + form3.select(f, Seq(0 -> trans.aConfirmationIsRequiredToJoin.txt(), 1 -> trans.anyoneCanJoin.txt())) + }, + form3.group(form("location"), trans.location())(form3.input(_)), + form3.group(form("description"), trans.description())(form3.textarea(_)(rows := 10)), + form3.actions( + a(href := routes.Team.show(t.id), style := "margin-left:20px")(trans.cancel()), + form3.submit(trans.apply()) + ) + ), + hr, + st.form(cls := "inline", method := "post", action := routes.Team.close(t.id))( + button(dataIcon := "q", cls := "text button button-empty button-red confirm", tpe := "submit", + st.title := "Deletes the team and its memberships. Cannot be reverted!")("Delete") + ) + ) + ) + } + } +} diff --git a/app/views/team/form.scala.html b/app/views/team/form.scala.html deleted file mode 100644 index 070faaa4f7..0000000000 --- a/app/views/team/form.scala.html +++ /dev/null @@ -1,27 +0,0 @@ -@(form: Form[_], captcha: lila.common.Captcha)(implicit ctx: Context) -@import lila.app.ui.ScalatagsTwirlForm._ - -@team.layout( -title = trans.newTeam.txt(), -currentTab = "form".some, -formCss = true) { -
    -
    -

    @trans.newTeam()

    -
    - @form3.globalError(form) - @form3.group(form("name"), trans.name.frag())(form3.input(_)) - @form3.group(form("open"), trans.joiningPolicy.frag()) { f => - @form3.select(form("open"), Seq(0 -> trans.aConfirmationIsRequiredToJoin.txt(), 1 -> trans.anyoneCanJoin.txt())) - } - @form3.group(form("location"), trans.location.frag())(form3.input(_)) - @form3.group(form("description"), trans.description.frag())(form3.textarea(_)(*.rows := 10)) - @base.captcha(form, captcha).toHtml - @form3.actionsHtml { - @trans.cancel() - @form3.submit(trans.newTeam.frag()) - } -
    -
    -
    -} diff --git a/app/views/team/kick.scala.html b/app/views/team/kick.scala.html deleted file mode 100644 index 81ea88b74d..0000000000 --- a/app/views/team/kick.scala.html +++ /dev/null @@ -1,17 +0,0 @@ -@(t: lila.team.Team, userIds: Iterable[User.ID])(implicit ctx: Context) - -@title = @{ "Kick from Team " + t.name } - -@team.layout(title = title) { -
    -
    -

    @title

    -

    Who do you want to kick out of the team?

    -
    - @userIds.toList.sorted.map { userId => - - } -
    -
    -
    -} diff --git a/app/views/team/layout.scala.html b/app/views/team/layout.scala.html deleted file mode 100644 index 52d70a392f..0000000000 --- a/app/views/team/layout.scala.html +++ /dev/null @@ -1,40 +0,0 @@ -@(title: String, currentTab: Option[String] = None, openGraph: Option[lila.app.ui.OpenGraph] = None, formCss: Boolean = false)(body: Html)(implicit ctx: Context) - -@allCss = { -@cssTag("team.css") -@if(formCss) { @cssTag("form3.css") } -} - -@side = { -
    - @defining(~currentTab) { tab => - @if(ctx.teamNbRequests > 0) { - - @ctx.teamNbRequests join requests - - } - @if(ctx.me.??(_.canTeam)) { - - @trans.myTeams() - - } - - @trans.allTeams() - - @if(ctx.me.??(_.canTeam)) { - - @trans.newTeam() - - } - } -
    -} - -@base.layout( -title = title, -moreCss = allCss, -moreJs = infiniteScrollTag, -openGraph = openGraph, -side = side.some) { -@body -}.toHtml diff --git a/app/views/team/list.scala b/app/views/team/list.scala new file mode 100644 index 0000000000..4f8e146817 --- /dev/null +++ b/app/views/team/list.scala @@ -0,0 +1,78 @@ +package views.html.team + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator + +import controllers.routes + +object list { + + def search(text: String, teams: Paginator[lila.team.Team])(implicit ctx: Context) = list( + name = trans.search.txt() + " \"" + text + "\"", + teams = teams, + nextPageUrl = n => routes.Team.search(text, n).url, + tab = "all", + search = text + ) + + def all(teams: Paginator[lila.team.Team])(implicit ctx: Context) = list( + name = trans.teams.txt(), + teams = teams, + nextPageUrl = n => routes.Team.all(n).url, + tab = "all" + ) + + def mine(teams: List[lila.team.Team])(implicit ctx: Context) = + bits.layout(title = trans.myTeams.txt()) { + main(cls := "team-list page-menu")( + bits.menu("mine".some), + div(cls := "page-menu__content box")( + h1(trans.myTeams()), + table(cls := "slist slist-pad")( + if (teams.size > 0) tbody(teams.map(bits.teamTr(_))) + else noTeam() + ) + ) + ) + } + + private def noTeam()(implicit ctx: Context) = tbody( + tr(td(colspan := "2")( + br, + trans.noTeamFound() + )) + ) + + private def list( + name: String, + teams: Paginator[lila.team.Team], + nextPageUrl: Int => String, + tab: String, + search: String = "" + )(implicit ctx: Context) = + bits.layout(title = "%s - page %d".format(name, teams.currentPage)) { + main(cls := "team-list page-menu")( + bits.menu("all".some), + div(cls := "page-menu__content box")( + div(cls := "box__top")( + h1(name), + div(cls := "box__top__actions")( + st.form(cls := "search", action := routes.Team.search())( + input(st.name := "text", value := search, placeholder := trans.search.txt()) + ) + ) + ), + table(cls := "slist slist-pad")( + if (teams.nbResults > 0) tbody(cls := "infinitescroll")( + pagerNext(teams, nextPageUrl), + tr, + teams.currentPageResults map { bits.teamTr(_) } + ) + else noTeam() + ) + ) + ) + } +} diff --git a/app/views/team/list.scala.html b/app/views/team/list.scala.html deleted file mode 100644 index 8e87a5b0c7..0000000000 --- a/app/views/team/list.scala.html +++ /dev/null @@ -1,29 +0,0 @@ -@(name: String, teams: Paginator[lila.team.Team], next: Option[Call], tab: String, search: String = "")(implicit ctx: Context) - -@title = @{ "%s - page %d".format(name, teams.currentPage) } - -@team.layout( -title = title, -currentTab = tab.some) { -
    - -

    @name

    - - @if(teams.nbResults > 0) { - - @next.map { n => - - - } - @teams.currentPageResults.map(x => team.teamTr(x)) - - } else { - @team.noTeam() - } -
    - -
    -
    -} diff --git a/app/views/team/mine.scala.html b/app/views/team/mine.scala.html deleted file mode 100644 index a164600e90..0000000000 --- a/app/views/team/mine.scala.html +++ /dev/null @@ -1,16 +0,0 @@ -@(teams: List[lila.team.Team])(implicit ctx: Context) - -@team.layout( -title = trans.myTeams.txt(), -currentTab = "mine".some) { -
    -

    @trans.myTeams()

    - - @if(teams.size > 0) { - @teams.map(x => team.teamTr(x)) - } else { - @team.noTeam() - } -
    -
    -} diff --git a/app/views/team/noTeam.scala.html b/app/views/team/noTeam.scala.html deleted file mode 100644 index 0e4a923ea0..0000000000 --- a/app/views/team/noTeam.scala.html +++ /dev/null @@ -1,6 +0,0 @@ -@()(implicit ctx: Context) - - -
    @trans.noTeamFound() - - diff --git a/app/views/team/request.scala b/app/views/team/request.scala new file mode 100644 index 0000000000..6315ba875a --- /dev/null +++ b/app/views/team/request.scala @@ -0,0 +1,75 @@ +package views.html.team + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.String.html.richText + +import controllers.routes + +object request { + + def requestForm(t: lila.team.Team, form: Form[_], captcha: lila.common.Captcha)(implicit ctx: Context) = { + + val title = s"${trans.joinTeam.txt()} ${t.name}" + + views.html.base.layout( + title = title, + moreCss = cssTag("team"), + moreJs = frag(infiniteScrollTag, captchaTag) + ) { + main(cls := "page-menu page-small")( + bits.menu("requests".some), + div(cls := "page-menu__content box box-pad")( + h1(title), + p(style := "margin:2em 0")(richText(t.description)), + st.form(cls := "form3", action := routes.Team.requestCreate(t.id), method := "POST")( + form3.group(form("message"), raw("Message"))(form3.textarea(_)()), + p("Your join request will be reviewed by the team leader."), + views.html.base.captcha(form, captcha), + form3.actions( + a(href := routes.Team.show(t.slug))(trans.cancel()), + form3.submit(trans.joinTeam()) + ) + ) + ) + ) + } + } + + def all(requests: List[lila.team.RequestWithUser])(implicit ctx: Context) = { + val title = s"${requests.size} join requests" + bits.layout(title = title) { + main(cls := "page-menu")( + bits.menu("requests".some), + div(cls := "page-menu__content box box-pad")( + h1(title), + list(requests, none) + ) + ) + } + } + + private[team] def list(requests: List[lila.team.RequestWithUser], t: Option[lila.team.Team])(implicit ctx: Context) = + table(cls := "slist requests @if(t.isEmpty){all}else{for-team} datatable")( + tbody( + requests.map { request => + tr( + if (t.isEmpty) td(userLink(request.user), " ", teamLink(request.team)) + else td(userLink(request.user)), + td(richText(request.message)), + td(momentFromNow(request.date)), + td(cls := "process")( + st.form(cls := "process-request", action := routes.Team.requestProcess(request.id), method := "post")( + input(tpe := "hidden", name := "url", value := t.fold(routes.Team.requests())(te => routes.Team.show(te.id))), + button(name := "process", cls := "button button-empty button-red", value := "decline")(trans.decline()), + button(name := "process", cls := "button button-green", value := "accept")(trans.accept()) + ) + ) + ) + } + ) + ) +} diff --git a/app/views/team/requestForm.scala.html b/app/views/team/requestForm.scala.html deleted file mode 100644 index 2040535d61..0000000000 --- a/app/views/team/requestForm.scala.html +++ /dev/null @@ -1,24 +0,0 @@ -@(t: lila.team.Team, form: Form[_], captcha: lila.common.Captcha)(implicit ctx: Context) -@import lila.app.ui.ScalatagsTwirlForm._ - -@title = @{ trans.joinTeam.txt() + " " + t.name } - -@team.layout(title = title, formCss = true) { -
    -
    -

    @title

    -

    @richText(t.description)

    -
    - @form3.group(form("message"), raw("Message"))(form3.textarea(_)()) -
    -

    Your join request will be reviewed by the team leader.

    -
    - @base.captcha(form, captcha).toHtml - @form3.actionsHtml { - @trans.cancel() - @form3.submit(trans.joinTeam.frag()) - } -
    -
    -
    -} diff --git a/app/views/team/requests.scala.html b/app/views/team/requests.scala.html deleted file mode 100644 index a8a3f1fdc7..0000000000 --- a/app/views/team/requests.scala.html +++ /dev/null @@ -1,31 +0,0 @@ -@(requests: List[lila.team.RequestWithUser], t: Option[lila.team.Team])(implicit ctx: Context) - - - @if(t.nonEmpty) { - - - - - - } - - @requests.map { request => - - @if(t.isEmpty) { - - } else { - - } - - - - - } - -
    @requests.size join requests
    @userLink(request.user) @teamLink(request.team)@userLink(request.user)@richText(request.message)@momentFromNow(request.date) -
    - - - -
    -
    diff --git a/app/views/team/search.scala.html b/app/views/team/search.scala.html deleted file mode 100644 index ab99671225..0000000000 --- a/app/views/team/search.scala.html +++ /dev/null @@ -1,8 +0,0 @@ -@(text: String, teams: Paginator[lila.team.Team])(implicit ctx: Context) - -@team.list( -name = trans.search.txt() + " \"" + text + "\"", -teams = teams, -next = teams.nextPage map { n => routes.Team.search(text, n) }, -tab = "all", -search = text) diff --git a/app/views/team/show.scala b/app/views/team/show.scala new file mode 100644 index 0000000000..f477a769f1 --- /dev/null +++ b/app/views/team/show.scala @@ -0,0 +1,106 @@ +package views.html.team + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator +import lila.common.String.html.richText + +import controllers.routes + +object show { + + def apply(t: lila.team.Team, members: Paginator[lila.team.MemberWithUser], info: lila.app.mashup.TeamInfo)(implicit ctx: Context) = + bits.layout( + title = t.name, + openGraph = lila.app.ui.OpenGraph( + title = s"${t.name} team", + url = s"$netBaseUrl${routes.Team.show(t.id).url}", + description = shorten(t.description, 152) + ).some + )( + main(cls := "page-menu")( + bits.menu(none), + div(cls := "team-show page-menu__content box team-show")( + div(cls := "box__top")( + h1(cls := "text", dataIcon := "f")(t.name, " ", em("TEAM")), + div( + if (t.disabled) span(cls := "staff")("CLOSED") + else trans.nbMembers.plural(t.nbMembers, strong(t.nbMembers.localize)) + ) + ), + (info.mine || t.enabled) option div(cls := "team-show__content")( + st.section(cls := "team-show__meta")( + p(trans.tournamentPoints(), ": ", strong(info.toints.localize)), + p(trans.teamLeader(), ": ", userIdLink(t.createdBy.some)) + ), + + div(cls := "team-show__members")( + !info.bestUserIds.isEmpty option st.section(cls := "best-members")( + h2(trans.teamBestPlayers()), + ol(cls := "userlist best_players")( + info.bestUserIds.map { userId => + li(userIdLink(userId.some)) + } + ) + ), + st.section(cls := "recent-members")( + h2(trans.teamRecentMembers()), + div(cls := "userlist infinitescroll")( + pagerNext(members, np => routes.Team.show(t.id, np).url), + members.currentPageResults.map { member => + div(cls := "paginated")(userLink(member.user)) + } + ) + ) + ), + st.section(cls := "team-show__desc")( + richText(t.description), + t.location.map { loc => + frag(br, trans.location(), ": ", richText(loc)) + }, + info.hasRequests option div(cls := "requests")( + h2(info.requests.size, " join requests"), + views.html.team.request.list(info.requests, t.some) + ) + ), + st.section(cls := "team-show__actions")( + (t.enabled && !info.mine) option frag( + if (info.requestedByMe) strong("Your join request is being reviewed by the team leader") + else ctx.me.??(_.canTeam) option + st.form(cls := "inline", method := "post", action := routes.Team.join(t.id))( + input(cls := "button button-green", tpe := "submit", value := trans.joinTeam.txt()) + ) + ), + (info.mine && !info.createdByMe) option + st.form(cls := "quit", method := "post", action := routes.Team.quit(t.id))( + input(cls := "button button-empty button-red confirm", tpe := "submit", value := trans.quitTeam.txt()) + ), + (info.createdByMe || isGranted(_.Admin)) option + a(href := routes.Team.edit(t.id), cls := "button button-empty text", dataIcon := "%")(trans.settings()) + ), + st.section(cls := "team-show__forum")( + h2(dataIcon := "d", cls := "text")( + a(href := teamForumUrl(t.id))(trans.forum()), + " (", info.forumNbPosts, ")" + ), + info.forumPosts.take(10).map { post => + st.article( + p(cls := "meta")( + a(href := routes.ForumPost.redirect(post.postId))(post.topicName), + em( + userIdLink(post.userId, withOnline = false), + " ", + momentFromNow(post.createdAt) + ) + ), + p(shorten(post.text, 200)) + ) + }, + a(cls := "more", href := teamForumUrl(t.id))(t.name, " ", trans.forum(), " »") + ) + ) + ) + ) + ) +} diff --git a/app/views/team/show.scala.html b/app/views/team/show.scala.html deleted file mode 100644 index 4f482cd85d..0000000000 --- a/app/views/team/show.scala.html +++ /dev/null @@ -1,25 +0,0 @@ -@(t: lila.team.Team, members: Paginator[lila.team.MemberWithUser], info: lila.app.mashup.TeamInfo)(implicit ctx: Context) - -@team.layout(title = t.name, openGraph = lila.app.ui.OpenGraph( -title = s"${t.name} team", -url = s"$netBaseUrl${routes.Team.show(t.id).url}", -description = shorten(t.description, 152)).some) { -
    -
    - @trans.nbMembers.plural(t.nbMembers, Html("" + t.nbMembers.localize + "")) -
    -

    @t.name TEAM

    - @if(t.disabled) { - CLOSED - } -
    - @if(info.mine || t.enabled) { - @if(info.hasRequests) { - @team.requests(info.requests, t.some) - } -
    - @team.showContent(t, members, info) -
    - } -
    -} diff --git a/app/views/team/showContent.scala.html b/app/views/team/showContent.scala.html deleted file mode 100644 index c2b3f7ef9a..0000000000 --- a/app/views/team/showContent.scala.html +++ /dev/null @@ -1,78 +0,0 @@ -@(t: lila.team.Team, members: Paginator[lila.team.MemberWithUser], info: lila.app.mashup.TeamInfo)(implicit ctx: Context) - -
    -
    -

    @trans.tournamentPoints(): @info.toints.localize

    -

    @trans.teamLeader(): @userIdLink(t.createdBy.some)

    -
    - @if(!info.bestUserIds.isEmpty) { -

    @trans.teamBestPlayers()

    -
      - @info.bestUserIds.map { userId => -
    1. @userIdLink(userId.some)
    2. - } -
    - } -

    @trans.teamRecentMembers()

    -
    - @members.nextPage.map { np => - - } - @members.currentPageResults.map { member => -
    @userLink(member.user)
    - } -
    -
    -
    -

    - @richText(t.description) - @t.location.map { loc => -
    @trans.location(): @richText(loc) - } -

    -
    - @if(t.enabled && !info.mine) { - @if(info.requestedByMe) { - Your join request is being reviewed by the team leader - } else { - @if(ctx.me.??(_.canTeam)) { -
    - -
    - } - } - } - @if(isGranted(_.ManageTeam)) { -
    - -
    - } -
    -
    -

    @trans.forum() (@info.forumNbPosts)

    -
      - @info.forumPosts.take(10).map { p => -
    1. -

      - @p.topicName - @userIdLink(p.userId, withOnline = false) - @momentFromNow(p.createdAt) -

      -

      @shorten(p.text, 200)

      -
    2. - } -
    - @t.name @trans.forum() » -
    - @if(info.mine && !info.createdByMe) { -
    - -
    - } - @if(info.createdByMe || isGranted(_.Admin)) { - @trans.settings() - } -
    -
    -
    diff --git a/app/views/team/teamTr.scala.html b/app/views/team/teamTr.scala.html deleted file mode 100644 index 45189492a7..0000000000 --- a/app/views/team/teamTr.scala.html +++ /dev/null @@ -1,14 +0,0 @@ -@(t: lila.team.Team)(implicit ctx: Context) - - - - - - @t.name - - @shorten(t.description, 200) - - -

    @trans.nbMembers.plural(t.nbMembers, t.nbMembers.localize)

    - - diff --git a/app/views/timeline.scala b/app/views/timeline.scala index e330aa5442..985ecd8be1 100644 --- a/app/views/timeline.scala +++ b/app/views/timeline.scala @@ -1,12 +1,9 @@ package views.html -import play.twirl.api.Html - import lila.api.Context import lila.app.templating.Environment._ -import lila.hub.actorApi.timeline._ -import lila.common.String.html.escapeHtml import lila.app.ui.ScalatagsTemplate._ +import lila.hub.actorApi.timeline._ import controllers.routes @@ -20,18 +17,21 @@ object timeline { ) def more(entries: Vector[lila.timeline.Entry])(implicit ctx: Context) = - base.layout(title = trans.timeline.txt(), moreCss = cssTag("timeline.css"))( - div(id := "timeline_more", cls := "content_box small_box no_padding")( - h1(trans.timeline()), - table(cls := "datatable")( - tbody( - filterEntries(entries) map { e => - tr(td(entry(e))) - } + base.layout( + title = trans.timeline.txt(), + moreCss = cssTag("slist") + )( + main(cls := "timeline page-small box")( + h1(trans.timeline()), + table(cls := "slist slist-pad")( + tbody( + filterEntries(entries) map { e => + tr(td(entry(e))) + } + ) ) ) ) - ) private def filterEntries(entries: Vector[lila.timeline.Entry])(implicit ctx: Context) = if (ctx.noKid) entries @@ -39,23 +39,52 @@ object timeline { private def entry(e: lila.timeline.Entry)(implicit ctx: Context) = frag( e.decode.map[Frag] { - case Follow(u1, u2) => playHtmlToFrag(trans.xStartedFollowingY(userIdLink(u1.some, withOnline = false), userIdLink(u2.some, withOnline = false))) + case Follow(u1, u2) => trans.xStartedFollowingY(userIdLink(u1.some, withOnline = false), userIdLink(u2.some, withOnline = false)) case TeamJoin(userId, teamId) => trans.xJoinedTeamY(userIdLink(userId.some, withOnline = false), teamLink(teamId, withIcon = false)) case TeamCreate(userId, teamId) => trans.xCreatedTeamY(userIdLink(userId.some, withOnline = false), teamLink(teamId, withIcon = false)) - case ForumPost(userId, topicId, topicName, postId) => trans.xPostedInForumY(userIdLink(userId.some, withOnline = false), Html("""%s""".format(routes.ForumPost.redirect(postId), escapeHtml(topicName), shorten(topicName, 30)))) + case ForumPost(userId, topicId, topicName, postId) => trans.xPostedInForumY( + userIdLink(userId.some, withOnline = false), + a( + href := routes.ForumPost.redirect(postId), + title := topicName + )(shorten(topicName, 30)) + ) case NoteCreate(fromId, toId) => trans.xLeftANoteOnY(userIdLink(fromId.some, withOnline = false), userIdLink(toId.some, withOnline = false, params = "?note")) - case TourJoin(userId, tourId, tourName) => trans.xCompetesInY(userIdLink(userId.some, withOnline = false), Html("""%s""".format(routes.Tournament.show(tourId), escapeHtml(tourName)))) - case SimulCreate(userId, simulId, simulName) => trans.xHostsY(userIdLink(userId.some, withOnline = false), Html(s"""${escapeHtml(simulName)}""")) - case SimulJoin(userId, simulId, simulName) => trans.xJoinsY(userIdLink(userId.some, withOnline = false), Html(s"""${escapeHtml(simulName)}""")) + case TourJoin(userId, tourId, tourName) => trans.xCompetesInY( + userIdLink(userId.some, withOnline = false), + a(href := routes.Tournament.show(tourId))(tourName) + ) + case SimulCreate(userId, simulId, simulName) => trans.xHostsY( + userIdLink(userId.some, withOnline = false), + a(href := routes.Simul.show(simulId))(simulName) + ) + case SimulJoin(userId, simulId, simulName) => trans.xJoinsY( + userIdLink(userId.some, withOnline = false), + a(href := routes.Simul.show(simulId))(simulName) + ) case GameEnd(playerId, opponent, win, perfKey) => lila.rating.PerfType(perfKey) map { perf => - trans.xVsYinZ(Html(""" %s""".format(routes.Round.player(playerId), perf.iconChar, win match { - case Some(true) => trans.victory() - case Some(false) => trans.defeat() - case _ => trans.draw() - })), userIdLink(opponent, withOnline = false), perf.name) + trans.xVsYinZ( + a( + href := routes.Round.player(playerId), + dataIcon := perf.iconChar, + cls := "text glpt" + )(win match { + case Some(true) => trans.victory() + case Some(false) => trans.defeat() + case _ => trans.draw() + }), + userIdLink(opponent, withOnline = false), + perf.name + ) } - case StudyCreate(userId, studyId, studyName) => trans.xCreatesStudyY(userIdLink(userId.some, withOnline = false), Html(s"""${escapeHtml(studyName)}""")) - case StudyLike(userId, studyId, studyName) => trans.xLikesY(userIdLink(userId.some, withOnline = false), Html(s"""${escapeHtml(studyName)}""")) + case StudyCreate(userId, studyId, studyName) => trans.xCreatesStudyY( + userIdLink(userId.some, withOnline = false), + a(href := routes.Study.show(studyId))(studyName) + ) + case StudyLike(userId, studyId, studyName) => trans.xLikesY( + userIdLink(userId.some, withOnline = false), + a(href := routes.Study.show(studyId))(studyName) + ) case PlanStart(userId) => frag( userIdLink(userId.some, withOnline = true), " became a ", diff --git a/app/views/tournament/bits.scala b/app/views/tournament/bits.scala index 4e0008b50b..828b3dea6f 100644 --- a/app/views/tournament/bits.scala +++ b/app/views/tournament/bits.scala @@ -1,34 +1,14 @@ package views.html.tournament -import play.twirl.api.Html - import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ +import lila.i18n.{ I18nKeys => trans } + +import controllers.routes object bits { - def layout( - title: String, - moreJs: Html = emptyHtml, - moreCss: Html = emptyHtml, - side: Option[Html] = None, - chat: Option[Frag] = None, - underchat: Option[Frag] = None, - chessground: Boolean = true, - openGraph: Option[lila.app.ui.OpenGraph] = None - )(body: Frag)(implicit ctx: Context) = - views.html.base.layout( - title = title, - moreCss = frag(cssTag("tournament.css"), moreCss), - moreJs = moreJs, - side = side, - chat = chat, - underchat = underchat, - openGraph = openGraph, - chessground = chessground - )(body) - def miniGame(pov: lila.game.Pov)(implicit ctx: Context) = frag( gameFen(pov), div(cls := "vstext")( @@ -41,4 +21,63 @@ object bits { ))(gameEndStatus(pov.game)) ) ) + + def notFound()(implicit ctx: Context) = + views.html.base.layout( + title = trans.tournamentNotFound.txt() + ) { + main(cls := "page-small box box-pad")( + h1(trans.tournamentNotFound()), + p(trans.tournamentDoesNotExist()), + p(trans.tournamentMayHaveBeenCanceled()), + br, + br, + a(href := routes.Tournament.home())(trans.returnToTournamentsHomepage()) + ) + } + + def enterable(tours: List[lila.tournament.Tournament]) = + table(cls := "tournaments")( + tours map { tour => + tr( + td(cls := "name")( + a(cls := "text", dataIcon := tournamentIconChar(tour), href := routes.Tournament.show(tour.id))(tour.name) + ), + tour.schedule.fold(td()) { s => td(momentFromNow(s.at)) }, + td(tour.durationString), + td(dataIcon := "r", cls := "text")(tour.nbPlayers) + ) + } + ) + + def jsI18n()(implicit ctx: Context) = i18nJsObject(translations) + + private val translations = List( + trans.standing, + trans.starting, + trans.tournamentIsStarting, + trans.youArePlaying, + trans.standByX, + trans.tournamentPairingsAreNowClosed, + trans.join, + trans.withdraw, + trans.joinTheGame, + trans.signIn, + trans.averageElo, + trans.gamesPlayed, + trans.nbPlayers, + trans.winRate, + trans.berserkRate, + trans.performance, + trans.tournamentComplete, + trans.movesPlayed, + trans.whiteWins, + trans.blackWins, + trans.draws, + trans.nextXTournament, + trans.viewMoreTournaments, + trans.averageOpponent, + trans.ratedTournament, + trans.casualTournament + ) } diff --git a/app/views/tournament/calendar.scala b/app/views/tournament/calendar.scala index 5538dad28c..8213add9fe 100644 --- a/app/views/tournament/calendar.scala +++ b/app/views/tournament/calendar.scala @@ -1,5 +1,7 @@ package views.html.tournament +import play.api.libs.json.Json + import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ @@ -13,16 +15,18 @@ object calendar { title = "Tournament calendar", moreJs = frag( jsAt(s"compiled/lichess.tournamentCalendar${isProd ?? (".min")}.js"), - embedJs(s"""LichessTournamentCalendar.app(document.getElementById('tournament_calendar'), { -data: ${safeJsonValue(json)}, -i18n: ${jsI18n()} -});""") + embedJsUnsafe(s"""LichessTournamentCalendar.app(document.getElementById('tournament-calendar'), ${ + safeJsonValue(Json.obj( + "data" -> json, + "i18n" -> bits.jsI18n() + )) + })""") ), - moreCss = cssTag("tournament_calendar.css") + moreCss = cssTag("tournament.calendar") ) { - div(cls := "content_box no_padding tournament_calendar")( + main(cls := "box")( h1("Tournament calendar"), - div(id := "tournament_calendar") + div(id := "tournament-calendar") ) } } diff --git a/app/views/tournament/conditionForm.scala.html b/app/views/tournament/conditionForm.scala.html deleted file mode 100644 index 00f63574ec..0000000000 --- a/app/views/tournament/conditionForm.scala.html +++ /dev/null @@ -1,36 +0,0 @@ -@(form: Form[_], auto: Boolean, teams: lila.hub.tournamentTeam.TeamIdsWithNames)(implicit ctx: Context) -@import lila.app.ui.ScalatagsTwirlForm._ - -@import lila.tournament.Condition - -@autoField(fieldName: String)(visible: Field => Frag) = @{ -if(auto) form3.hidden(form(fieldName)) else visible(form(fieldName)).toHtml -} - -@form3.split { -@form3.group(form("conditions.nbRatedGame.nb"), raw("Minimum rated games"), half = true)(form3.select(_, Condition.DataForm.nbRatedGameChoices)) -@autoField("conditions.nbRatedGame.perf") { field => -@form3.group(field, raw("In variant"), half = true)(form3.select(_, ("", "Any") :: Condition.DataForm.perfChoices)) -} -} -@form3.split { -@form3.group(form("conditions.minRating.rating"), raw("Minimum rating"), half = true)(form3.select(_, Condition.DataForm.minRatingChoices)) -@autoField("conditions.minRating.perf") { field => -@form3.group(field, raw("In variant"), half = true)(form3.select(_, Condition.DataForm.perfChoices)) -} -} -@form3.split { -@form3.group(form("conditions.maxRating.rating"), raw("Maximum weekly rating"), half = true)(form3.select(_, Condition.DataForm.maxRatingChoices)) -@autoField("conditions.maxRating.perf") { field => -@form3.group(field, raw("In variant"), half = true)(form3.select(_, Condition.DataForm.perfChoices)) -} -} -@form3.split { -@if(ctx.me.exists(_.hasTitle) || isGranted(_.ManageTournament)) { -@form3.checkbox(form("conditions.titled"), raw("Only titled players"), help = raw("Require an official title to join the tournament").some, half = true) -} -@form3.checkbox(form("berserkable"), raw("Allow Berserk"), help = raw("Let players halve their clock time to gain an extra point").some, half = true) -} -@if(auto && teams.size > 0) { -@form3.group(form("conditions.teamMember.teamId"), raw("Only members of team"), half = false)(form3.select(_, List(("", "No Restriction")) ::: teams)) -} diff --git a/app/views/tournament/crud.scala b/app/views/tournament/crud.scala new file mode 100644 index 0000000000..64ed5356ec --- /dev/null +++ b/app/views/tournament/crud.scala @@ -0,0 +1,137 @@ +package views.html +package tournament + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator +import lila.tournament.{ DataForm, Tournament } +import lila.tournament.crud.CrudForm +import lila.rating.PerfType + +import controllers.routes + +object crud { + + private def layout(title: String, evenMoreJs: Frag = emptyFrag, css: String = "mod.misc")(body: Frag)(implicit ctx: Context) = + views.html.base.layout( + title = title, + moreCss = cssTag(css), + moreJs = frag( + flatpickrTag, + delayFlatpickrStart, + evenMoreJs + ) + ) { + main(cls := "page-menu")( + views.html.mod.menu("tour"), + body + ) + } + + def create(form: Form[_])(implicit ctx: Context) = layout( + title = "New tournament", + css = "mod.form" + ) { + div(cls := "crud page-menu__content box box-pad")( + h1("New tournament"), + st.form(cls := "form3", action := routes.TournamentCrud.create, method := "POST")(inForm(form)) + ) + } + + def edit(tour: Tournament, form: Form[_])(implicit ctx: Context) = layout( + title = tour.fullName, + css = "mod.form" + ) { + div(cls := "crud edit page-menu__content box box-pad")( + h1( + a(href := routes.Tournament.show(tour.id))(tour.fullName), + " ", + span("Created by ", usernameOrId(tour.createdBy), " on ", showDate(tour.createdAt)) + ), + st.form(cls := "form3", action := routes.TournamentCrud.update(tour.id), method := "POST")(inForm(form)) + ) + } + + private def inForm(form: Form[_])(implicit ctx: Context) = frag( + form3.split( + form3.group(form("date"), raw("Start date UTC"), half = true)(form3.flatpickr(_)), + form3.group(form("name"), raw("Name"), help = raw("Keep it VERY short, so it fits on homepage").some, half = true)(form3.input(_)) + ), + form3.split( + form3.group(form("homepageHours"), raw(s"Hours on homepage (0 to ${CrudForm.maxHomepageHours})"), half = true, help = raw("Ask on slack first").some)(form3.input(_, typ = "number")), + form3.group(form("image"), raw("Custom icon"), half = true)(form3.select(_, CrudForm.imageChoices)) + ), + form3.group(form("headline"), raw("Homepage headline"), help = raw("Keep it VERY short, so it fits on homepage").some)(form3.input(_)), + form3.group(form("description"), raw("Full description"), help = raw("Link: [text](url)").some)(form3.textarea(_)(rows := 6)), + + form3.split( + form3.group(form("variant"), raw("Variant"), half = true) { f => + form3.select(f, translatedVariantChoicesWithVariants.map(x => x._1 -> x._2)) + }, + form3.group(form("minutes"), raw("Duration in minutes"), half = true)(form3.input(_, typ = "number")) + ), + form3.split( + form3.group(form("clockTime"), raw("Clock time"), half = true)(form3.select(_, DataForm.clockTimeChoices)), + form3.group(form("clockIncrement"), raw("Clock increment"), half = true)(form3.select(_, DataForm.clockIncrementChoices)) + ), + form3.group(form("position"), trans.startPosition())(tournament.form.startingPosition(_)), + + hr, + h2("Conditions of entry"), + tournament.form.condition(form, auto = false, Nil), + form3.action(form3.submit(trans.apply())) + ) + + def index(tours: Paginator[Tournament])(implicit ctx: Context) = layout( + title = "Tournament manager", + evenMoreJs = infiniteScrollTag + ) { + div(cls := "crud page-menu__content box")( + div(cls := "box__top")( + h1("Tournament manager"), + div(cls := "box__top__actions")( + a(cls := "button button-green", href := routes.TournamentCrud.form, dataIcon := "O") + ) + ), + table(cls := "slist slist-pad")( + thead( + tr( + th(), + th("Variant"), + th("Clock"), + th("Duration"), + th("UTC Date"), + th() + ) + ), + tbody(cls := "infinitescroll")( + tours.nextPage.map { n => + frag( + tr( + th(cls := "pager none")( + a(rel := "next", href := routes.TournamentCrud.index(n))("Next") + ) + ), + tr() + ) + }, + tours.currentPageResults.map { tour => + tr(cls := "paginated")( + td( + a(href := routes.TournamentCrud.edit(tour.id))(strong(tour.fullName), " ", em(tour.spotlight.map(_.headline))) + ), + td(tour.variant.name), + td(tour.clock.toString), + td(tour.minutes, "m"), + td(showDateTimeUTC(tour.startsAt), " ", momentFromNow(tour.startsAt)), + td(a(href := routes.Tournament.show(tour.id), dataIcon := "v", title := "View on site")) + ) + } + ) + ) + ) + } +} diff --git a/app/views/tournament/crud/create.scala.html b/app/views/tournament/crud/create.scala.html deleted file mode 100644 index f8bbf13d17..0000000000 --- a/app/views/tournament/crud/create.scala.html +++ /dev/null @@ -1,10 +0,0 @@ -@(form: Form[_])(implicit ctx: Context) - -@layout(title = "New tournament") { -
    -

    New tournament

    -
    - @inForm(form) -
    -
    -} diff --git a/app/views/tournament/crud/edit.scala.html b/app/views/tournament/crud/edit.scala.html deleted file mode 100644 index ba4dcb5b8b..0000000000 --- a/app/views/tournament/crud/edit.scala.html +++ /dev/null @@ -1,13 +0,0 @@ -@(tour: lila.tournament.Tournament, form: Form[_])(implicit ctx: Context) - -@layout(title = tour.fullName) { -
    -

    - @tour.fullName - Created by @usernameOrId(tour.createdBy) on @showDate(tour.createdAt) -

    -
    - @inForm(form) -
    -
    -} diff --git a/app/views/tournament/crud/inForm.scala.html b/app/views/tournament/crud/inForm.scala.html deleted file mode 100644 index a3650c04a7..0000000000 --- a/app/views/tournament/crud/inForm.scala.html +++ /dev/null @@ -1,33 +0,0 @@ -@(form: Form[_])(implicit ctx: Context) -@import lila.app.ui.ScalatagsTwirlForm._ -@import lila.tournament.DataForm._ -@import lila.tournament.crud.CrudForm._ -@import lila.rating.PerfType - -@form3.split { -@form3.group(form("date"), raw("Start date UTC"), half = true)(form3.flatpickr(_)) -@form3.group(form("name"), raw("Name"), help = raw("Keep it VERY short, so it fits on homepage").some, half = true)(form3.input(_)) -} -@form3.split { -@form3.group(form("homepageHours"), raw(s"Hours on homepage (0 to $maxHomepageHours)"), half = true, help = raw("Ask on slack first").some)(form3.input(_, typ = "number")) -@form3.group(form("image"), raw("Custom icon"), half = true)(form3.select(_, imageChoices)) -} -@form3.group(form("headline"), raw("Homepage headline"), help = raw("Keep it VERY short, so it fits on homepage").some)(form3.input(_)) -@form3.group(form("description"), raw("Full description"), help = raw("Link: [text](url)").some)(form3.textarea(_)(*.rows := 6)) - -@form3.split { -@form3.group(form("variant"), raw("Variant"), half = true) { f => -@form3.select(f, translatedVariantChoicesWithVariants.map(x => x._1 -> x._2)) -} -@form3.group(form("minutes"), raw("Duration in minutes"), half = true)(form3.input(_, typ = "number")) -} -@form3.split { -@form3.group(form("clockTime"), raw("Clock time"), half = true)(form3.select(_, clockTimeChoices)) -@form3.group(form("clockIncrement"), raw("Clock increment"), half = true)(form3.select(_, clockIncrementChoices)) -} -@form3.group(form("position"), trans.startPosition.frag())(tournament.startingPosition(_)) - -
    -

    Conditions of entry

    -@tournament.conditionForm(form, auto = false, Nil) -@form3.actionHtml(form3.submit(trans.apply.frag())) diff --git a/app/views/tournament/crud/index.scala.html b/app/views/tournament/crud/index.scala.html deleted file mode 100644 index 58c4480c2c..0000000000 --- a/app/views/tournament/crud/index.scala.html +++ /dev/null @@ -1,51 +0,0 @@ -@(tours: Paginator[lila.tournament.Tournament])(implicit ctx: Context) - -@title = {Tournament manager} - -@layout( - title = title.body, - evenMoreJs = infiniteScrollTag -) { -
    -

    - - @title -

    - - - - - - - - - - - - - @tours.nextPage.map { n => - - - } - @tours.currentPageResults.map { tour => - - - - - - - - - } - -
    VariantClockDurationUTC Date
    - -
    -

    @tour.fullName

    - @tour.spotlight.map(_.headline) -
    @tour.variant.name@tour.clock@{tour.minutes}m - @showDateTimeUTC(tour.startsAt) - @momentFromNow(tour.startsAt) -
    -
    -} diff --git a/app/views/tournament/crud/layout.scala.html b/app/views/tournament/crud/layout.scala.html deleted file mode 100644 index abde56d538..0000000000 --- a/app/views/tournament/crud/layout.scala.html +++ /dev/null @@ -1,13 +0,0 @@ -@(title: String, evenMoreJs: Html = emptyHtml)(body: Html)(implicit ctx: Context) - -@moreJs = { -@flatpickrTag -@delayFlatpickrStart -@evenMoreJs -} - -@mod.layout( -title = title, -active = "tour", -moreCss = cssTags("flatpickr.css", "form3.css", "tournament.crud.css"), -moreJs = moreJs)(body) diff --git a/app/views/tournament/enterable.scala b/app/views/tournament/enterable.scala deleted file mode 100644 index 7a49fa57a3..0000000000 --- a/app/views/tournament/enterable.scala +++ /dev/null @@ -1,28 +0,0 @@ -package views -package html.tournament - -import lila.tournament.Tournament -import lila.app.templating.Environment._ -import lila.app.ui.ScalatagsTemplate._ - -import controllers.routes - -object enterable { - - def apply(tours: List[Tournament]) = - table(cls := "tournaments")( - tours map { tour => - tr( - td(cls := "name")( - a(cls := "text", href := routes.Tournament.show(tour.id))( - span(dataIcon := tournamentIconChar(tour)), - tour.name - ) - ), - tour.schedule.fold(td()) { s => td(momentFromNow(s.at)) }, - td(tour.durationString), - td(dataIcon := "r", cls := "text")(tour.nbPlayers) - ) - } - ) -} diff --git a/app/views/tournament/faq.scala b/app/views/tournament/faq.scala new file mode 100644 index 0000000000..c80a9baa7a --- /dev/null +++ b/app/views/tournament/faq.scala @@ -0,0 +1,59 @@ +package views.html +package tournament + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object faq { + + def page(system: Option[lila.tournament.System])(implicit ctx: Context) = views.html.base.layout( + title = "Tournament FAQ", + moreCss = cssTag("page") + ) { + main(cls := "page-small box box-pad page")( + h1( + a(href := routes.Tournament.home(), dataIcon := "I", cls := "text"), + system.??(_.toString), " Tournament FAQ" + ), + div(cls := "body")(apply(system = system)) + ) + } + + def apply(rated: Option[Boolean] = None, system: Option[lila.tournament.System] = None, privateId: Option[String] = None)(implicit ctx: Context) = frag( + privateId.map { id => + frag( + h2(trans.arena.thisIsPrivate()), + p(trans.arena.shareUrl(s"$netBaseUrl${routes.Tournament.show(id)}")) // XXX + ) + }, + p(trans.arena.willBeNotified()), + + h2(trans.arena.isItRated()), + rated match { + case Some(true) => p(trans.arena.isRated()) + case Some(false) => p(trans.arena.isNotRated()) + case None => p(trans.arena.someRated()) + }, + + h2(trans.arena.howAreScoresCalculated()), + p(trans.arena.howAreScoresCalculatedAnswer()), + + h2(trans.arena.berserk()), + p(trans.arena.berserkAnswer()), + + h2(trans.arena.howIsTheWinnerDecided()), + p(trans.arena.howIsTheWinnerDecidedAnswer()), + + h2(trans.arena.howDoesPairingWork()), + p(trans.arena.howDoesPairingWorkAnswer()), + + h2(trans.arena.howDoesItEnd()), + p(trans.arena.howDoesItEndAnswer()), + + h2(trans.arena.otherRules()), + p(trans.arena.otherRulesAnswer()) + ) +} diff --git a/app/views/tournament/faq.scala.html b/app/views/tournament/faq.scala.html deleted file mode 100644 index b4513ded69..0000000000 --- a/app/views/tournament/faq.scala.html +++ /dev/null @@ -1,40 +0,0 @@ -@(rated: Option[Boolean] = None, system: Option[lila.tournament.System] = None, privateId: Option[String] = None)(implicit ctx: Context) - -@import lila.tournament.System - -
    - @privateId.map { id => -

    @trans.arena.thisIsPrivate()

    - @trans.arena.shareUrl(netBaseUrl + routes.Tournament.show(id)) - } - @trans.arena.willBeNotified() - -

    @trans.arena.isItRated()

    - @rated.map { r => - @if(r) { - @trans.arena.isRated() - } else { - @trans.arena.isNotRated() - } - }.getOrElse { - @trans.arena.someRated() - } - -

    @trans.arena.howAreScoresCalculated()

    - @trans.arena.howAreScoresCalculatedAnswer() - -

    @trans.arena.berserk()

    - @trans.arena.berserkAnswer() - -

    @trans.arena.howIsTheWinnerDecided()

    - @trans.arena.howIsTheWinnerDecidedAnswer() - -

    @trans.arena.howDoesPairingWork()

    - @trans.arena.howDoesPairingWorkAnswer() - -

    @trans.arena.howDoesItEnd()

    - @trans.arena.howDoesItEndAnswer() - -

    @trans.arena.otherRules()

    - @trans.arena.otherRulesAnswer() -
    diff --git a/app/views/tournament/faqPage.scala.html b/app/views/tournament/faqPage.scala.html deleted file mode 100644 index 001db1adb8..0000000000 --- a/app/views/tournament/faqPage.scala.html +++ /dev/null @@ -1,15 +0,0 @@ -@(system: Option[lila.tournament.System])(implicit ctx: Context) - -@tournament.bits.layout(title = "Tournament FAQ") { -
    -
    -

    - @system Tournament - FAQ -

    -
    -
    - @tournament.faq(system = system) -
    -
    -}.toHtml diff --git a/app/views/tournament/finishedPaginator.scala b/app/views/tournament/finishedPaginator.scala index 07c29024a1..eca9903f53 100644 --- a/app/views/tournament/finishedPaginator.scala +++ b/app/views/tournament/finishedPaginator.scala @@ -19,7 +19,7 @@ object finishedPaginator { finished.currentPageResults.map { t => tr(cls := List( "paginated" -> true, - "scheduled" -> t.isScheduled + "tour-scheduled" -> t.isScheduled ))( td(cls := "icon")(iconTag(tournamentIconChar(t))), td(cls := "header")( diff --git a/app/views/tournament/form.scala b/app/views/tournament/form.scala new file mode 100644 index 0000000000..e52b36a99f --- /dev/null +++ b/app/views/tournament/form.scala @@ -0,0 +1,131 @@ +package views.html +package tournament + +import play.api.data.{ Field, Form } + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.user.User +import lila.tournament.{ Condition, DataForm } + +import controllers.routes + +object form { + + def apply(form: Form[_], config: DataForm, me: User, teams: lila.hub.tournamentTeam.TeamIdsWithNames)(implicit ctx: Context) = views.html.base.layout( + title = trans.newTournament.txt(), + moreCss = cssTag("tournament.form"), + moreJs = frag( + flatpickrTag, + jsTag("tournamentForm.js") + ) + )(main(cls := "page-small")( + div(cls := "tour__form box box-pad")( + h1(trans.createANewTournament()), + st.form(cls := "form3", action := routes.Tournament.create, method := "POST")( + DataForm.canPickName(me) ?? { + form3.group(form("name"), trans.name()) { f => + div( + form3.input(f), " Arena", br, + small(cls := "form-help")( + trans.safeTournamentName(), br, + trans.inappropriateNameWarning(), br, + trans.emptyTournamentName(), br + ) + ) + } + }, + form3.split( + form3.checkbox(form("rated"), trans.rated(), help = raw("Games are rated
    and impact players ratings").some), + st.input(tpe := "hidden", name := form("rated").name, value := "false"), // hack allow disabling rated + form3.group(form("variant"), trans.variant(), half = true)(form3.select(_, translatedVariantChoicesWithVariants.map(x => x._1 -> x._2))) + ), + form3.group(form("position"), trans.startPosition(), klass = "position")(startingPosition(_)), + form3.split( + form3.group(form("clockTime"), raw("Clock initial time"), half = true)(form3.select(_, DataForm.clockTimeChoices)), + form3.group(form("clockIncrement"), raw("Clock increment"), half = true)(form3.select(_, DataForm.clockIncrementChoices)) + ), + form3.split( + form3.group(form("minutes"), trans.duration(), half = true)(form3.select(_, DataForm.minuteChoices)), + form3.group(form("waitMinutes"), trans.timeBeforeTournamentStarts(), half = true)(form3.select(_, DataForm.waitMinuteChoices)) + ), + form3.globalError(form), + fieldset(cls := "conditions")( + legend(trans.advancedSettings()), + errMsg(form("conditions")), + p( + strong(dataIcon := "!", cls := "text")(trans.recommendNotTouching()), + " ", + trans.fewerPlayers(), + " ", + a(cls := "show")(trans.showAdvancedSettings()) + ), + div(cls := "form")( + form3.group(form("password"), trans.password(), help = raw("Make the tournament private, and restrict access with a password").some)(form3.input(_)), + condition(form, auto = true, teams = teams), + input(tpe := "hidden", name := form("berserkable").name, value := "false"), // hack allow disabling berserk + form3.group(form("startDate"), raw("Custom start date"), help = raw("""This overrides the "Time before tournament starts" setting""").some)(form3.flatpickr(_)) + ) + ), + form3.actions( + a(href := routes.Tournament.home())(trans.cancel()), + form3.submit(trans.createANewTournament(), icon = "g".some) + ) + ) + ), + div(cls := "box box-pad tour__faq")(tournament.faq()) + )) + + private def autoField(auto: Boolean, field: Field)(visible: Field => Frag) = frag( + if (auto) form3.hidden(field) else visible(field) + ) + + def condition(form: Form[_], auto: Boolean, teams: lila.hub.tournamentTeam.TeamIdsWithNames)(implicit ctx: Context) = frag( + form3.split( + form3.group(form("conditions.nbRatedGame.nb"), raw("Minimum rated games"), half = true)(form3.select(_, Condition.DataForm.nbRatedGameChoices)), + autoField(auto, form("conditions.nbRatedGame.perf")) { field => + form3.group(field, raw("In variant"), half = true)(form3.select(_, ("", "Any") :: Condition.DataForm.perfChoices)) + } + ), + form3.split( + form3.group(form("conditions.minRating.rating"), raw("Minimum rating"), half = true)(form3.select(_, Condition.DataForm.minRatingChoices)), + autoField(auto, form("conditions.minRating.perf")) { field => + form3.group(field, raw("In variant"), half = true)(form3.select(_, Condition.DataForm.perfChoices)) + } + ), + form3.split( + form3.group(form("conditions.maxRating.rating"), raw("Maximum weekly rating"), half = true)(form3.select(_, Condition.DataForm.maxRatingChoices)), + autoField(auto, form("conditions.maxRating.perf")) { field => + form3.group(field, raw("In variant"), half = true)(form3.select(_, Condition.DataForm.perfChoices)) + } + ), + form3.split( + (ctx.me.exists(_.hasTitle) || isGranted(_.ManageTournament)) ?? { + form3.checkbox(form("conditions.titled"), raw("Only titled players"), help = raw("Require an official title to join the tournament").some, half = true) + }, + form3.checkbox(form("berserkable"), raw("Allow Berserk"), help = raw("Let players halve their clock time to gain an extra point").some, half = true) + ), + (auto && teams.size > 0) ?? { + form3.group(form("conditions.teamMember.teamId"), raw("Only members of team"), half = false)(form3.select(_, List(("", "No Restriction")) ::: teams)) + } + ) + + def startingPosition(field: Field)(implicit ctx: Context) = st.select( + id := form3.id(field), + name := field.name, + cls := "form-control" + )( + option( + value := chess.StartingPosition.initial.fen, + field.value.has(chess.StartingPosition.initial.fen) option selected + )(chess.StartingPosition.initial.name), + chess.StartingPosition.categories.map { categ => + optgroup(attr("label") := categ.name)( + categ.positions.map { v => + option(value := v.fen, field.value.has(v.fen) option selected)(v.fullName) + } + ) + } + ) +} diff --git a/app/views/tournament/form.scala.html b/app/views/tournament/form.scala.html deleted file mode 100644 index c8eb0a3a82..0000000000 --- a/app/views/tournament/form.scala.html +++ /dev/null @@ -1,72 +0,0 @@ -@(form: Form[_], config: lila.tournament.DataForm, me: User, teams: lila.hub.tournamentTeam.TeamIdsWithNames)(implicit ctx: Context) -@import config._ -@import lila.tournament.DataForm._ -@import lila.app.ui.ScalatagsTwirlForm._ - -@moreJs = { -@flatpickrTag -@jsTag("tournamentForm.js") -} - -@tournament.bits.layout( -title = trans.newTournament.txt(), -moreCss = cssTags("flatpickr.css", "form3.css", "tournament.form.css"), -moreJs = moreJs) { -
    -
    -

    @trans.createANewTournament()

    - -
    - @if(lila.tournament.DataForm.canPickName(me)) { - @form3.group(form("name"), trans.name.frag()) { f => -
    - @form3.inputHtml(f)() Arena
    - - @trans.safeTournamentName()
    - @trans.inappropriateNameWarning()
    - @trans.emptyTournamentName() -
    -
    - } - } - @form3.split { - @form3.checkbox(form("rated"), trans.rated.frag(), help = raw("Games are rated
    and impact players ratings").some) - @* hack allow disabling rated *@ - @form3.group(form("variant"), trans.variant.frag(), half = true)(form3.select(_, translatedVariantChoicesWithVariants.map(x => x._1 -> x._2))) - } - @form3.group(form("position"), trans.startPosition.frag(), klass = "position")(tournament.startingPosition(_)) - @form3.split { - @form3.group(form("clockTime"), raw("Clock initial time"), half = true)(form3.select(_, clockTimeChoices)) - @form3.group(form("clockIncrement"), raw("Clock increment"), half = true)(form3.select(_, clockIncrementChoices)) - } - @form3.split { - @form3.group(form("minutes"), trans.duration.frag(), half = true)(form3.select(_, minuteChoices)) - @form3.group(form("waitMinutes"), trans.timeBeforeTournamentStarts.frag(), half = true)(form3.select(_, waitMinuteChoices)) - } - @form3.globalError(form) -
    -  @trans.advancedSettings()  - @errMsg(form("conditions")) -

    - @trans.recommendNotTouching() - @trans.fewerPlayers() - @trans.showAdvancedSettings() -

    -
    - @form3.group(form("password"), trans.password.frag(), help = raw("Make the tournament private, and restrict access with a password").some)(form3.input(_)) - @tournament.conditionForm(form, auto = true, teams = teams) - @* hack allow disabling berserk *@ - @form3.group(form("startDate"), raw("Custom start date"), help = raw("""This overrides the "Time before tournament starts" setting""").some)(form3.flatpickr(_)) -
    -
    - @form3.actionsHtml { - @trans.cancel() - @form3.submit(trans.createANewTournament.frag(), icon = "g".some) - } -
    -
    -
    -
    @tournament.faq()
    -
    -
    -}.toHtml diff --git a/app/views/tournament/home.scala b/app/views/tournament/home.scala index 6ab0e70669..77740c00f7 100644 --- a/app/views/tournament/home.scala +++ b/app/views/tournament/home.scala @@ -1,5 +1,7 @@ package views.html.tournament +import play.api.libs.json.Json + import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ @@ -16,62 +18,69 @@ object home { winners: lila.tournament.AllWinners, json: play.api.libs.json.JsObject )(implicit ctx: Context) = - bits.layout( + views.html.base.layout( title = trans.tournaments.txt(), + moreCss = cssTag("tournament.home"), + wrapClass = "full-screen-force", moreJs = frag( infiniteScrollTag, jsAt(s"compiled/lichess.tournamentSchedule${isProd ?? (".min")}.js"), - embedJs(s"""var app=LichessTournamentSchedule.app(document.getElementById('tournament_schedule'), { -data: ${safeJsonValue(json)}, -i18n: ${jsI18n()} -}); + embedJsUnsafe(s"""var app=LichessTournamentSchedule.app(document.querySelector('.tour-chart'), ${ + safeJsonValue(Json.obj( + "data" -> json, + "i18n" -> bits.jsI18n() + )) + }); var d=lichess.StrongSocket.defaults;d.params.flag="tournament";d.events.reload=app.update;""") ), - side = Some(frag( - div(cls := "tournament_home_side")( - div(cls := "tournament_links")( - a(dataIcon := "", cls := "text", href := routes.Tournament.help("arena".some))(trans.tournamentFAQ()) - ), - h2(cls := "leaderboard_title")( - a(href := routes.Tournament.leaderboard)(trans.leaderboard()) - ) - ), - ul(cls := "tournament_leaderboard")( - winners.top.map { w => - li( - userIdLink(w.userId.some), - a(title := w.tourName, href := routes.Tournament.show(w.tourId))(scheduledTournamentNameShortHtml(w.tourName)) - ) - } - ), - h2(cls := "leaderboard_title")(trans.lichessTournaments()), - div(cls := "scheduled_tournaments")( - scheduled.map { tour => - tour.schedule.filter(s => s.freq != lila.tournament.Schedule.Freq.Hourly) map { s => - a(href := routes.Tournament.show(tour.id), dataIcon := tournamentIconChar(tour))( - strong(tour.name), - momentFromNow(s.at) - ) - } - } - ) - )), openGraph = lila.app.ui.OpenGraph( url = s"$netBaseUrl${routes.Tournament.home().url}", title = trans.tournamentHomeTitle.txt(), description = trans.tournamentHomeDescription.txt() ).some ) { - div(cls := "content_box tournament_box no_padding")( - div(cls := "create_tournament")( - a(href := "/tournament/calendar", cls := "blue")(trans.tournamentCalendar()), - " ", - ctx.isAuth option a(href := routes.Tournament.form(), cls := "button")(trans.createANewTournament()) + main(cls := "tour-home")( + st.aside(cls := "tour-home__side")( + h2( + a(href := routes.Tournament.leaderboard)(trans.leaderboard()) + ), + ul(cls := "leaderboard")( + winners.top.map { w => + li( + userIdLink(w.userId.some), + a(title := w.tourName, href := routes.Tournament.show(w.tourId))(scheduledTournamentNameShortHtml(w.tourName)) + ) + } + ), + p(cls := "tour__links")( + a(href := "/tournament/calendar")(trans.tournamentCalendar()), br, + a(href := routes.Tournament.help("arena".some))(trans.tournamentFAQ()) + ), + h2(trans.lichessTournaments()), + div(cls := "scheduled")( + scheduled.map { tour => + tour.schedule.filter(s => s.freq != lila.tournament.Schedule.Freq.Hourly) map { s => + a(href := routes.Tournament.show(tour.id), dataIcon := tournamentIconChar(tour))( + strong(tour.name), + momentFromNow(s.at) + ) + } + } + ) ), - h1(trans.tournaments()), - div(id := "tournament_schedule"), - div(id := "tournament_list")( - table(cls := "slist finished")( + st.section(cls := "tour-home__schedule box")( + div(cls := "box__top")( + h1(trans.tournaments()), + ctx.isAuth option div(cls := "box__top__actions")(a( + href := routes.Tournament.form(), + cls := "button button-green", + title := trans.createANewTournament.txt() + )("+")) + ), + div(cls := "tour-chart") + ), + div(cls := "tour-home__list box")( + table(cls := "slist")( thead( tr( th(colspan := 2, cls := "large")(trans.finished()), diff --git a/app/views/tournament/homepageSpotlight.scala b/app/views/tournament/homepageSpotlight.scala index b79929e1e1..217413032b 100644 --- a/app/views/tournament/homepageSpotlight.scala +++ b/app/views/tournament/homepageSpotlight.scala @@ -14,7 +14,7 @@ object homepageSpotlight { val distant = (tour.isDistant) ?? " distant little" s"${sched.freq} ${sched.speed} ${sched.variant.key}$invert$distant" } - val tourClass = s"tour_spotlight id_${tour.id} $schedClass" + val tourClass = s"tour-spotlight id_${tour.id} $schedClass" tour.spotlight map { spot => a(href := routes.Tournament.show(tour.id), cls := tourClass)( frag( diff --git a/app/views/tournament/jsI18n.scala b/app/views/tournament/jsI18n.scala deleted file mode 100644 index 207bbc4e29..0000000000 --- a/app/views/tournament/jsI18n.scala +++ /dev/null @@ -1,40 +0,0 @@ -package views.html.tournament - -import lila.api.Context -import lila.app.templating.Environment._ -import lila.common.String.html.safeJsonValue -import lila.i18n.{ I18nKeys => trans } - -object jsI18n { - - def apply()(implicit ctx: Context) = safeJsonValue(i18nJsObject(translations)) - - private val translations = List( - trans.standing, - trans.starting, - trans.tournamentIsStarting, - trans.youArePlaying, - trans.standByX, - trans.tournamentPairingsAreNowClosed, - trans.join, - trans.withdraw, - trans.joinTheGame, - trans.signIn, - trans.averageElo, - trans.gamesPlayed, - trans.nbPlayers, - trans.winRate, - trans.berserkRate, - trans.performance, - trans.tournamentComplete, - trans.movesPlayed, - trans.whiteWins, - trans.blackWins, - trans.draws, - trans.nextXTournament, - trans.viewMoreTournaments, - trans.averageOpponent, - trans.ratedTournament, - trans.casualTournament - ) -} diff --git a/app/views/tournament/leaderboard.scala b/app/views/tournament/leaderboard.scala new file mode 100644 index 0000000000..a7d1669a28 --- /dev/null +++ b/app/views/tournament/leaderboard.scala @@ -0,0 +1,82 @@ +package views.html.tournament + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.rating.PerfType +import lila.tournament.Tournament + +import controllers.routes + +object leaderboard { + + private def freqWinner(w: lila.tournament.Winner, freq: String) = li( + userIdLink(w.userId.some), + a(title := w.tourName, href := routes.Tournament.show(w.tourId))(freq) + ) + + private val section = st.section(cls := "tournament-leaderboards__item") + + private def freqWinners(fws: lila.tournament.FreqWinners, perfType: PerfType, name: String) = + section( + h2(cls := "text", dataIcon := perfType.iconChar)(name), + ul( + fws.yearly.map { w => freqWinner(w, "Yearly") }, + fws.monthly.map { w => freqWinner(w, "Monthly") }, + fws.weekly.map { w => freqWinner(w, "Weekly") }, + fws.daily.map { w => freqWinner(w, "Daily") } + ) + ) + + def apply(winners: lila.tournament.AllWinners)(implicit ctx: Context) = views.html.base.layout( + title = "Tournament leaderboard", + moreCss = cssTag("tournament.leaderboard"), + wrapClass = "full-screen-force" + ) { + def eliteWinners = section( + h2(cls := "text", dataIcon := "C")("Elite Arena"), + ul( + winners.elite.map { w => + li( + userIdLink(w.userId.some), + a(title := w.tourName, href := routes.Tournament.show(w.tourId))(showDate(w.date)) + ) + } + ) + ) + + def marathonWinners = section( + h2(cls := "text", dataIcon := "\\")("Marathon"), + ul( + winners.marathon.map { w => + li( + userIdLink(w.userId.some), + a(title := w.tourName, href := routes.Tournament.show(w.tourId))(w.tourName.replace(" Marathon", "")) + ) + } + ) + ) + main(cls := "page-menu")( + views.html.user.bits.communityMenu("tournament"), + div(cls := "page-menu__content box box-pad")( + h1("Tournament winners"), + div(cls := "tournament-leaderboards")( + eliteWinners, + freqWinners(winners.hyperbullet, PerfType.Bullet, "HyperBullet"), + freqWinners(winners.bullet, PerfType.Bullet, "Bullet"), + freqWinners(winners.superblitz, PerfType.Blitz, "SuperBlitz"), + freqWinners(winners.blitz, PerfType.Blitz, "Blitz"), + freqWinners(winners.rapid, PerfType.Rapid, "Rapid"), + marathonWinners, + lila.tournament.WinnersApi.variants.map { v => + PerfType.byVariant(v).map { pt => + winners.variants.get(pt.key).map { w => + freqWinners(w, pt, v.name) + } + } + } + ) + ) + ) + } +} diff --git a/app/views/tournament/leaderboard.scala.html b/app/views/tournament/leaderboard.scala.html deleted file mode 100644 index bfd13833ad..0000000000 --- a/app/views/tournament/leaderboard.scala.html +++ /dev/null @@ -1,74 +0,0 @@ -@(winners: lila.tournament.AllWinners)(implicit ctx: Context) -@import lila.rating.PerfType -@freqWinner(w: lila.tournament.Winner, freq: String) = { -
  • - @userIdLink(w.userId.some) - @freq -
  • -} - -@freqWinners(fws: lila.tournament.FreqWinners, perfType: PerfType, name: String) = { -
    -

    @name

    -
      - @fws.yearly.map { w => @freqWinner(w, "Yearly") } - @fws.monthly.map { w => @freqWinner(w, "Monthly") } - @fws.weekly.map { w => @freqWinner(w, "Weekly") } - @fws.daily.map { w => @freqWinner(w, "Daily") } -
    -
    -} - -@eliteWinners = { -
    -

    Elite Arena

    -
      - @winners.elite.map { w => -
    • - @userIdLink(w.userId.some) - @showDate(w.date) -
    • - } -
    -
    -} - -@marathonWinners = { -
    -

    Marathon

    - -
    -} - -@base.layout( -title = "Tournament leaderboard", -moreCss = cssTags("tournament_leaderboard.css", "user-list.css") -) { -
    - @user.communityTabs("tournament") -

    Tournament winners

    -
    - @eliteWinners - @freqWinners(winners.hyperbullet, PerfType.Bullet, "HyperBullet") - @freqWinners(winners.bullet, PerfType.Bullet, "Bullet") - @freqWinners(winners.superblitz, PerfType.Blitz, "SuperBlitz") - @freqWinners(winners.blitz, PerfType.Blitz, "Blitz") - @freqWinners(winners.rapid, PerfType.Rapid, "Rapid") - @marathonWinners - @lila.tournament.WinnersApi.variants.map { v => - @PerfType.byVariant(v).map { pt => - @winners.variants.get(pt.key).map { w => - @freqWinners(w, pt, v.name) - } - } - } -
    -
    -}.toHtml diff --git a/app/views/tournament/notFound.scala.html b/app/views/tournament/notFound.scala.html deleted file mode 100644 index 6b80b1a01a..0000000000 --- a/app/views/tournament/notFound.scala.html +++ /dev/null @@ -1,14 +0,0 @@ -@()(implicit ctx: Context) - -@tournament.bits.layout(title = trans.tournamentNotFound.txt()) { -
    -
    -

    @trans.tournamentNotFound()

    - @trans.tournamentDoesNotExist()
    - @trans.tournamentMayHaveBeenCanceled() -
    -
    - @trans.returnToTournamentsHomepage() -
    -
    -}.toHtml diff --git a/app/views/tournament/shields.scala b/app/views/tournament/shields.scala new file mode 100644 index 0000000000..08d76c4f5b --- /dev/null +++ b/app/views/tournament/shields.scala @@ -0,0 +1,71 @@ +package views.html.tournament + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.rating.PerfType +import lila.tournament.TournamentShield + +import controllers.routes + +object shields { + + private val section = st.section(cls := "tournament-shields__item") + + def apply(history: TournamentShield.History)(implicit ctx: Context) = + views.html.base.layout( + title = "Tournament shields", + moreCss = cssTag("tournament.leaderboard"), + wrapClass = "full-screen-force" + ) { + main(cls := "page-menu")( + views.html.user.bits.communityMenu("shield"), + div(cls := "page-menu__content box box-pad")( + h1("Tournament shields"), + div(cls := "tournament-shields")( + history.sorted.map { + case (categ, awards) => { + section( + h2( + a(href := routes.Tournament.categShields(categ.key))( + span(cls := "shield-trophy")(categ.iconChar.toString), + categ.name + ) + ), + ol(awards.map { aw => + li( + userIdLink(aw.owner.value.some), + a(href := routes.Tournament.show(aw.tourId))(showDate(aw.date)) + ) + }) + ) + } + } + ) + ) + ) + } + + def byCateg(categ: TournamentShield.Category, awards: List[TournamentShield.Award])(implicit ctx: Context) = + views.html.base.layout( + title = "Tournament shields", + moreCss = frag(cssTag("tournament.leaderboard"), cssTag("slist")) + ) { + main(cls := "page-menu page-small tournament-categ-shields")( + views.html.user.bits.communityMenu("shield"), + div(cls := "page-menu__content box")( + h1( + a(href := routes.Tournament.shields, dataIcon := "I", cls := "text"), + categ.name, " shields" + ), + ol(awards.map { aw => + li( + span(cls := "shield-trophy")(categ.iconChar.toString), + userIdLink(aw.owner.value.some), + a(href := routes.Tournament.show(aw.tourId))(showDate(aw.date)) + ) + }) + ) + ) + } +} diff --git a/app/views/tournament/shields.scala.html b/app/views/tournament/shields.scala.html deleted file mode 100644 index 267734af6b..0000000000 --- a/app/views/tournament/shields.scala.html +++ /dev/null @@ -1,35 +0,0 @@ -@(history: lila.tournament.TournamentShield.History)(implicit ctx: Context) - -@moreCss = { -@cssTag("tournament_shields.css") -@cssTag("user-list.css") -} - -@base.layout( -title = "Tournament shields", -moreCss = moreCss) { -
    - @user.communityTabs("shield") -

    Tournament shields

    -
    - @history.sorted.map { - case (categ, awards) => { -
    -

    - @categ.iconChar - @categ.name -

    -
      - @awards.map { a => -
    • - @userIdLink(a.owner.value.some) - @showDate(a.date) -
    • - } -
    -
    - } - } -
    -
    -}.toHtml diff --git a/app/views/tournament/show.scala b/app/views/tournament/show.scala index e5253cdfcd..88524f0f63 100644 --- a/app/views/tournament/show.scala +++ b/app/views/tournament/show.scala @@ -1,7 +1,7 @@ package views.html package tournament -import play.twirl.api.Html +import play.api.libs.json.Json import lila.api.Context import lila.app.templating.Environment._ @@ -20,27 +20,22 @@ object show { chatOption: Option[lila.chat.UserChat.Mine], streamers: Set[lila.user.User.ID], shieldOwner: Option[lila.tournament.TournamentShield.OwnerId] - )(implicit ctx: Context) = bits.layout( + )(implicit ctx: Context) = views.html.base.layout( title = s"${tour.fullName} #${tour.id}", - side = Some(tournament.side(tour, verdicts, streamers, shieldOwner)), - chat = chat.frag.some, - underchat = Some(div( - cls := "watchers hidden", - aria.live := "off", - aria.relevant := "additions removals text" - )(span(cls := "list inline_userlist"))), moreJs = frag( jsAt(s"compiled/lichess.tournament${isProd ?? (".min")}.js"), - embedJs(s"""lichess = lichess || {}; lichess.tournament = { -data: ${safeJsonValue(data)}, -i18n: ${jsI18n()}, -userId: ${jsUserIdString}, -chat: ${ - chatOption.fold("null")(c => - safeJsonValue(chat.json(c.chat, name = trans.chatRoom.txt(), timeout = c.timeout, public = true))) - }};""") + embedJsUnsafe(s"""lichess=lichess||{};lichess.tournament=${ + safeJsonValue(Json.obj( + "data" -> data, + "i18n" -> bits.jsI18n(), + "userId" -> ctx.userId, + "chat" -> chatOption.map { c => + chat.json(c.chat, name = trans.chatRoom.txt(), timeout = c.timeout, public = true) + } + )) + }""") ), - moreCss = cssTags(List("chat.css" -> true, "quote.css" -> tour.isCreated)), + moreCss = cssTag("tournament.show"), chessground = false, openGraph = lila.app.ui.OpenGraph( title = s"${tour.fullName}: ${tour.variant.name} ${tour.clock.show} ${tour.mode.name} #${tour.id}", @@ -52,15 +47,16 @@ chat: ${ } ).some )(frag( - div(id := "tournament", cls := tour.schedule.map { sched => - s"scheduled ${sched.freq.name} ${sched.speed.name} ${sched.variant.key} id_${tour.id}" - })( - div(cls := "content_box no_padding tournament_box tournament_show")( - div(cls := "content_box_content")(spinner) + main(cls := s"tour${ + tour.schedule.?? { sched => + s" tour-sched tour-sched-${sched.freq.name} tour-speed-${sched.speed.name} tour-variant-${sched.variant.key} tour-id-${tour.id}" + } + }")( + st.aside(cls := "tour__side")(tournament.side(tour, verdicts, streamers, shieldOwner, chatOption.isDefined)), + div(cls := "tour__main")(div(cls := "box")), + tour.isCreated option div(cls := "tour__faq")( + faq(tour.mode.rated.some, tour.system.some, tour.isPrivate.option(tour.id)) ) - ), - tour.isCreated option div(id := "tournament_faq", cls := "none")( - faq(tour.mode.rated.some, tour.system.some, tour.isPrivate.option(tour.id)) ) )) } diff --git a/app/views/tournament/side.scala b/app/views/tournament/side.scala index 3d548c3b90..d725c1eb77 100644 --- a/app/views/tournament/side.scala +++ b/app/views/tournament/side.scala @@ -15,23 +15,19 @@ object side { tour: lila.tournament.Tournament, verdicts: lila.tournament.Condition.All.WithVerdicts, streamers: Set[lila.user.User.ID], - shieldOwner: Option[lila.tournament.TournamentShield.OwnerId] + shieldOwner: Option[lila.tournament.TournamentShield.OwnerId], + chat: Boolean )(implicit ctx: Context) = frag( - div(cls := "side_box padded")( - div(cls := "game_infos", dataIcon := tour.perfType.map(_.iconChar.toString))( - div(cls := "header")( - isGranted(_.TerminateTournament) option - scalatags.Text.all.form(cls := "terminate", method := "post", action := routes.Tournament.terminate(tour.id), style := "float:right")( - button(dataIcon := "j", cls := "submit text fbt confirm", `type` := "submit", title := "Terminates the tournament immediately") - ), - span(cls := "setup")( + div(cls := "tour__meta")( + st.section(dataIcon := tour.perfType.map(_.iconChar.toString))( + div( + p( tour.clock.show, separator, if (tour.variant.exotic) { views.html.game.bits.variantLink( tour.variant, - if (tour.variant == chess.variant.KingOfTheHill) tour.variant.shortName else tour.variant.name, - cssClass = "hint--top" + if (tour.variant == chess.variant.KingOfTheHill) tour.variant.shortName else tour.variant.name ) } else tour.perfType.map(_.name), (!tour.position.initial) ?? s"• ${trans.thematic.txt()}", @@ -41,12 +37,14 @@ object side { tour.mode.fold(trans.casualTournament, trans.ratedTournament)(), separator, systemName(tour.system).capitalize, - " ", - a(cls := "blue help", href := routes.Tournament.help(tour.system.toString.toLowerCase.some), dataIcon := "") + isGranted(_.TerminateTournament) option + scalatags.Text.all.form(cls := "terminate", method := "post", action := routes.Tournament.terminate(tour.id))( + button(dataIcon := "j", cls := "fbt fbt-red confirm", `type` := "submit", title := "Terminates the tournament immediately") + ) ) ), tour.spotlight map { s => - div(cls := "game_infos spotlight")( + st.section( lila.common.String.html.markdownLinks(s.description), shieldOwner map { owner => p(cls := "defender", dataIcon := "5")( @@ -56,11 +54,11 @@ object side { } ) }, - verdicts.relevant option div(dataIcon := "7", cls := List( - "game_infos conditions" -> true, + verdicts.relevant option st.section(dataIcon := "7", cls := List( + "conditions" -> true, "accepted" -> (ctx.isAuth && verdicts.accepted), "refused" -> (ctx.isAuth && !verdicts.accepted) - ))( + ))(div( (verdicts.list.size < 2) option p(trans.conditionOfEntry()), verdicts.list map { v => p(cls := List( @@ -69,23 +67,17 @@ object side { "refused" -> !v.verdict.accepted ))(v.condition.name(ctx.lang)) } - ), + )), tour.noBerserk option div(cls := "text", dataIcon := "`")("No Berserk allowed"), !tour.isScheduled option frag(trans.by(usernameOrId(tour.createdBy)), br), - !tour.isStarted option absClientDateTime(tour.startsAt), - (!tour.position.initial) ?? frag( - br, br, + (!tour.isStarted || (tour.isScheduled && !tour.position.initial)) option absClientDateTime(tour.startsAt), + !tour.position.initial option p( a(target := "_blank", href := tour.position.url)( - strong(tour.position.eco), - s" ${tour.position.name}" + strong(tour.position.eco), " ", tour.position.name ) ) ), - streamers.toList map { id => - a(href := routes.Streamer.show(id), cls := "context-streamer text side_box", dataIcon := "")( - usernameOrId(id), - " is streaming" - ) - } + streamers.toList map views.html.streamer.bits.contextual, + chat option views.html.chat.frag ) } diff --git a/app/views/tournament/startingPosition.scala.html b/app/views/tournament/startingPosition.scala.html deleted file mode 100644 index 3691431882..0000000000 --- a/app/views/tournament/startingPosition.scala.html +++ /dev/null @@ -1,14 +0,0 @@ -@(field: play.api.data.Field)(implicit ctx: Context) - - diff --git a/app/views/tv/embed.scala b/app/views/tv/embed.scala new file mode 100644 index 0000000000..ef5eb67fe0 --- /dev/null +++ b/app/views/tv/embed.scala @@ -0,0 +1,40 @@ +package views.html.tv + +import play.api.mvc.RequestHeader + +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import views.html.base.layout.{ bits => layout } + +import controllers.routes + +object embed { + + private val dataStreamUrl = attr("data-stream-url") + + def apply(pov: lila.game.Pov)(implicit config: lila.app.ui.EmbedConfig) = frag( + layout.doctype, + layout.htmlTag(config.lang)( + head( + layout.charset, + layout.viewport, + layout.metaCsp(basicCsp(config.req)), + st.headTitle("lichess.org chess TV"), + layout.pieceSprite(lila.pref.PieceSet.default), + cssTagWithTheme("tv.embed", config.bg) + ), + body( + cls := s"base ${config.board}", + dataStreamUrl := routes.Tv.feed + )( + div(id := "featured-game", cls := "embedded", title := "lichess.org TV")( + gameFenNoCtx(pov, tv = true, blank = true), + views.html.game.bits.vstext(pov)(none) + ), + jQueryTag, + jsAt("javascripts/vendor/chessground.min.js", false), + jsAt("compiled/tv.js", false) + ) + ) + ) +} diff --git a/app/views/tv/embed.scala.html b/app/views/tv/embed.scala.html deleted file mode 100644 index 567254e18c..0000000000 --- a/app/views/tv/embed.scala.html +++ /dev/null @@ -1,27 +0,0 @@ -@(pov: Pov, bg: String, theme: String)(implicit req: RequestHeader) - - - - - - lichess.org TV - @if(bg == "dark") { - @cssAt("stylesheets/dark.css") - } - @cssAt(s"stylesheets/piece/merida.css") - @cssAt("stylesheets/common.css") - @cssAt("stylesheets/board.css") - - - - @jQueryTag - @jsAt("javascripts/vendor/chessground.min.js", false) - @jsAt("compiled/tv.js", false) - - diff --git a/app/views/tv/games.scala b/app/views/tv/games.scala new file mode 100644 index 0000000000..29ccfa7041 --- /dev/null +++ b/app/views/tv/games.scala @@ -0,0 +1,25 @@ +package views.html.tv + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object games { + + def apply(channel: lila.tv.Tv.Channel, povs: List[lila.game.Pov], champions: lila.tv.Tv.Champions)(implicit ctx: Context) = + views.html.base.layout( + title = s"${channel.name} • ${trans.currentGames.txt()}", + moreCss = cssTag("tv.games") + ) { + main(cls := "page-menu tv-games")( + st.aside(cls := "page-menu__menu")( + side(channel, champions, "/games") + ), + div(cls := "page-menu__content now-playing")( + povs map views.html.game.bits.mini + ) + ) + } +} diff --git a/app/views/tv/games.scala.html b/app/views/tv/games.scala.html deleted file mode 100644 index f7c0404032..0000000000 --- a/app/views/tv/games.scala.html +++ /dev/null @@ -1,17 +0,0 @@ -@(channel: lila.tv.Tv.Channel, povs: List[Pov], champions: lila.tv.Tv.Champions)(implicit ctx: Context) - -@title = @{ s"${channel.name} • ${trans.currentGames.txt()}" } - -@base.layout( -title = title, -side = side(channel, champions, "/games", povOption = none).map(_.toHtml), -moreCss = cssTag("tv.css")) { - -
    -
    - @povs.map { p => -
    @game.bits.mini(p)
    - } -
    -
    -}.toHtml diff --git a/app/views/tv/index.scala b/app/views/tv/index.scala index 1c1fbb6ec2..f0a20b7357 100644 --- a/app/views/tv/index.scala +++ b/app/views/tv/index.scala @@ -1,4 +1,7 @@ -package views.html.tv +package views.html +package tv + +import play.api.libs.json.Json import lila.api.Context import lila.app.templating.Environment._ @@ -19,18 +22,20 @@ object index { history: List[lila.game.Pov] )(implicit ctx: Context) = views.html.round.bits.layout( + variant = pov.game.variant, title = s"${channel.name} TV: ${playerText(pov.player)} vs ${playerText(pov.opponent)}", - side = side(channel, champions, "/tv", pov.some), - underchat = Some(views.html.game.bits.watchers), moreJs = frag( roundTag, - embedJs { - val transJs = views.html.round.jsI18n(pov.game) - s"""window.customWS = true; -window.onload = function() { LichessRound.boot({ data: ${safeJsonValue(data)}, i18n: $transJs }, document.getElementById('lichess')) }""" - } + embedJsUnsafe( + s"""lichess=window.lichess||{};customWS=true;onload=function(){LichessRound.boot(${ + safeJsonValue(Json.obj( + "data" -> data, + "i18n" -> views.html.round.jsI18n(pov.game) + )) + })}""" + ) ), - moreCss = cssTag("tv.css"), + moreCss = cssTag("tv.single"), chessground = false, openGraph = lila.app.ui.OpenGraph( title = s"Watch the best ${channel.name.toLowerCase} games of lichess.org", @@ -38,26 +43,19 @@ window.onload = function() { LichessRound.boot({ data: ${safeJsonValue(data)}, i url = s"$netBaseUrl${routes.Tv.onChannel(channel.key)}" ).some, robots = true - ) { - frag( - div(cls := "round cg-512")( - views.html.board.bits.domPreload(pov.some), - div(cls := "underboard")( - div(cls := "center")( - cross map { c => - div(cls := "crosstable")( - views.html.game.crosstable(ctx.userId.fold(c)(c.fromPov), pov.gameId.some) - ) - } + )( + main(cls := "round tv-single")( + st.aside(cls := "round__side")(side(channel, champions, "/tv")), + views.html.round.bits.roundAppPreload(pov, false), + div(cls := "round__underboard")( + views.html.round.bits.crosstable(cross, pov.game), + div(cls := "tv-history")( + h2(trans.previouslyOnLichessTV()), + div(cls := "now-playing")( + history map views.html.game.bits.mini ) ) - ), - div(cls := "game_list playing tv_history")( - h2(trans.previouslyOnLichessTV()), - history.map { p => - div(views.html.game.bits.mini(p)) - } ) ) - } + ) } diff --git a/app/views/tv/side.scala b/app/views/tv/side.scala index 90e41286e1..feb1a0583a 100644 --- a/app/views/tv/side.scala +++ b/app/views/tv/side.scala @@ -3,74 +3,47 @@ package views.html.tv import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ -import lila.common.String.html.safeJsonValue import controllers.routes object side { - private val titleTag = h2(dataIcon := "1", cls := "text") - def apply( channel: lila.tv.Tv.Channel, champions: lila.tv.Tv.Champions, - baseUrl: String, - povOption: Option[lila.game.Pov] - )(implicit ctx: Context): Option[Frag] = ctx.noBlind option div(cls := "side")( - div(cls := "side_box padded")( - povOption.fold[Frag](titleTag("Lichess games")) { pov => - frag( - titleTag("Lichess TV"), - br, - div(cls := "confrontation")( - playerLink(pov.game.whitePlayer, withRating = false, withOnline = false, withDiff = false), - em(" vs "), - playerLink(pov.game.blackPlayer, withRating = false, withOnline = false, withDiff = false) - ), - br, - shortClockName(pov.game.clock.map(_.config)), - " ", - views.html.game.bits.variantLink(pov.game.variant, variantName(pov.game.variant)), - pov.game.rated option frag(", ", trans.rated()) - ) - } - ), - povOption.map { pov => - pov.game.userIds.filter(isStreaming).map { id => - a(href := routes.Streamer.show(id), cls := "context-streamer text side_box", dataIcon := "")( - usernameOrId(id), - " is streaming" - ) - } - }, - div(id := "tv_channels")( - lila.tv.Tv.Channel.all.map { c => - a(dataIcon := c.icon, href := s"$baseUrl/${c.key}", cls := List(c.key -> true, "active" -> (c == channel)))( - strong(c.name), + baseUrl: String + )(implicit ctx: Context): Frag = div(cls := "tv-channels subnav")( + lila.tv.Tv.Channel.all.map { c => + a(href := s"$baseUrl/${c.key}", cls := List( + "tv-channel" -> true, + c.key -> true, + "active" -> (c == channel) + ))( + span(dataIcon := c.icon)( span( - champions.get(c).fold[Frag](raw(" - ")) { p => - frag( - p.user.title.fold[Frag](p.user.name)(t => frag(t, nbsp, p.user.name)), - nbsp, - p.rating - ) - } + strong(c.name), + span(cls := "champion")( + champions.get(c).fold[Frag](raw(" - ")) { p => + frag( + p.user.title.fold[Frag](p.user.name)(t => frag(t, nbsp, p.user.name)), + " ", + p.rating + ) + } + ) ) ) - } - ) + ) + } ) def sides( - channel: lila.tv.Tv.Channel, - champions: lila.tv.Tv.Champions, pov: lila.game.Pov, cross: Option[lila.game.Crosstable.WithMatchup] )(implicit ctx: Context) = div(cls := "sides")( - side(channel, champions, "/tv", pov.some), - cross.map { c => - div(cls := "crosstable")(views.html.game.crosstable(c, pov.gameId.some)) + cross.map { + views.html.game.crosstable(_, pov.gameId.some) } ) } diff --git a/app/views/user/bits.scala b/app/views/user/bits.scala index a25bea4a6e..9045c16b8c 100644 --- a/app/views/user/bits.scala +++ b/app/views/user/bits.scala @@ -1,15 +1,23 @@ -package views.html -package user +package views.html.user import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ +import lila.rating.PerfType import lila.user.User import controllers.routes object bits { + def communityMenu(active: String)(implicit ctx: Context) = + st.nav(cls := "page-menu__menu subnav")( + a(cls := active.active("leaderboard"), href := routes.User.list)(trans.leaderboard()), + a(cls := active.active("ratings"), href := routes.Stat.ratingDistribution("blitz"))(trans.ratingStats()), + a(cls := active.active("tournament"), href := routes.Tournament.leaderboard)(trans.tournamentWinners()), + a(cls := active.active("shield"), href := routes.Tournament.shields)("Shields") + ) + def miniClosed(u: User)(implicit ctx: Context) = frag( div(cls := "title")(userLink(u, withPowerTip = false)), div(style := "padding: 20px 8px; text-align: center")(trans.thisAccountIsClosed()) @@ -25,6 +33,28 @@ object bits { case 3 => "Good connection" case _ => "Excellent connection" } - s"""$bars""" + s"""$bars""" } + + def perfTrophies(u: User, rankMap: Option[lila.rating.UserRankMap])(implicit ctx: Context) = + rankMap.ifFalse(u.lame).map { ranks => + ranks.toList.sortBy(_._2).collect { + case (perf, rank) if rank == 1 => + span(cls := "trophy perf top1", title := s"${~PerfType.name(perf)} Champion!")( + img(src := staticUrl("images/trophy/Big-Gold-Cup.png")) + ) + case (perf, rank) if rank <= 10 => + span(cls := "trophy perf top10", title := s"${~PerfType.name(perf)} Top 10!")( + img(src := staticUrl("images/trophy/Big-Silver-Cup.png")) + ) + case (perf, rank) if rank <= 50 => + span(cls := "trophy perf top50", title := s"${~PerfType.name(perf)} Top 50 player!")( + img(src := staticUrl("images/trophy/Fancy-Gold.png")) + ) + case (perf, rank) if rank <= 100 => + span(cls := "trophy perf", title := s"${~PerfType.name(perf)} Top 100 player!")( + img(src := staticUrl("images/trophy/Gold-Cup.png")) + ) + } + } } diff --git a/app/views/user/communityTabs.scala.html b/app/views/user/communityTabs.scala.html deleted file mode 100644 index 1329e68a8c..0000000000 --- a/app/views/user/communityTabs.scala.html +++ /dev/null @@ -1,7 +0,0 @@ -@(active: String)(implicit ctx: Context) - diff --git a/app/views/user/disabled.scala.html b/app/views/user/disabled.scala.html deleted file mode 100644 index d26412181c..0000000000 --- a/app/views/user/disabled.scala.html +++ /dev/null @@ -1,14 +0,0 @@ -@(u: User)(implicit ctx: Context) - -@user.layout( -title = u.username, -robots = false) { -
    -
    -

    @u.username

    -
    -
    - @trans.thisAccountIsClosed() -
    -
    -} diff --git a/app/views/user/layout.scala.html b/app/views/user/layout.scala.html deleted file mode 100644 index 9d290d53d3..0000000000 --- a/app/views/user/layout.scala.html +++ /dev/null @@ -1,23 +0,0 @@ -@(title: String, side: Option[Html] = None, robots: Boolean = true, evenMoreJs: Html = emptyHtml, evenMoreCss: Html = emptyHtml, openGraph: Option[lila.app.ui.OpenGraph] = None, menu: Option[Html] = None, withInfScroll: Boolean = true)(body: Html)(implicit ctx: Context) - -@moreCss = { -@cssTags("user-list.css", "user-show.css") -@evenMoreCss -} - -@moreJs = { -@if(withInfScroll) { -@infiniteScrollTag -} -@jsAt("compiled/user.js") -@evenMoreJs -} - -@base.layout( -title = title, -side = side, -moreCss = moreCss, -moreJs = moreJs, -menu = menu, -robots = robots, -openGraph = openGraph)(body).toHtml diff --git a/app/views/user/list.scala b/app/views/user/list.scala index 222fb4ba34..6bb07d5666 100644 --- a/app/views/user/list.scala +++ b/app/views/user/list.scala @@ -1,11 +1,11 @@ -package views -package html.user +package views.html +package user import lila.api.Context import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ import lila.rating.PerfType import lila.user.User -import lila.app.ui.ScalatagsTemplate._ import controllers.routes @@ -17,96 +17,90 @@ object list { leaderboards: lila.user.Perfs.Leaderboards, nbDay: List[User.LightCount], nbAllTime: List[User.LightCount] - )(implicit ctx: Context) = layout( + )(implicit ctx: Context) = views.html.base.layout( title = trans.players.txt(), - side = Some(side(online)), + moreCss = cssTag("user.list"), + wrapClass = "full-screen-force", openGraph = lila.app.ui.OpenGraph( title = "Chess players and leaderboards", url = s"$netBaseUrl${routes.User.list.url}", description = "Best chess players in bullet, blitz, rapid, classical, Chess960 and more chess variants" - ).some, - withInfScroll = false + ).some ) { - div(cls := "content_box community")( - communityTabs("leaderboard"), - div(cls := "user_lists")( - userTopPerf(leaderboards.bullet, PerfType.Bullet), - userTopPerf(leaderboards.crazyhouse, PerfType.Crazyhouse), - div(cls := "user_top")( - h2(cls := "text", dataIcon := "g")( - a(href := routes.Tournament.leaderboard)(trans.tournamentWinners()) - ), - tourneyWinners take 10 map { w => - div( - div(userIdLink(w.userId.some)), - div(a(title := w.tourName, href := routes.Tournament.show(w.tourId))( - scheduledTournamentNameShortHtml(w.tourName) - )) + main(cls := "page-menu")( + bits.communityMenu("leaderboard"), + div(cls := "community page-menu__content box box-pad")( + st.section(cls := "community__online")( + h2(trans.onlinePlayers()), + ol(cls := "user-top")(online map { u => + li( + userLink(u), + showBestPerf(u) ) - } + }) ), + div(cls := "community__leaders")( + h2(trans.leaderboard()), + div(cls := "leaderboards")( + userTopPerf(leaderboards.bullet, PerfType.Bullet), + userTopPerf(leaderboards.blitz, PerfType.Blitz), + userTopPerf(leaderboards.rapid, PerfType.Rapid), + userTopPerf(leaderboards.classical, PerfType.Classical), + userTopPerf(leaderboards.ultraBullet, PerfType.UltraBullet), - userTopPerf(leaderboards.blitz, PerfType.Blitz), - userTopPerf(leaderboards.chess960, PerfType.Chess960), - userTopActive(nbAllTime, trans.activePlayers(), icon = 'U'.some), + userTopActive(nbAllTime, trans.activePlayers(), icon = 'U'.some), + tournamentWinners(tourneyWinners), - userTopPerf(leaderboards.rapid, PerfType.Rapid), - userTopPerf(leaderboards.threeCheck, PerfType.ThreeCheck), - userTopPerf(leaderboards.antichess, PerfType.Antichess), - - userTopPerf(leaderboards.classical, PerfType.Classical), - userTopPerf(leaderboards.kingOfTheHill, PerfType.KingOfTheHill), - userTopPerf(leaderboards.horde, PerfType.Horde), - - userTopPerf(leaderboards.ultraBullet, PerfType.UltraBullet), - userTopPerf(leaderboards.atomic, PerfType.Atomic), - userTopPerf(leaderboards.racingKings, PerfType.RacingKings) + userTopPerf(leaderboards.crazyhouse, PerfType.Crazyhouse), + userTopPerf(leaderboards.chess960, PerfType.Chess960), + userTopPerf(leaderboards.antichess, PerfType.Antichess), + userTopPerf(leaderboards.atomic, PerfType.Atomic), + userTopPerf(leaderboards.threeCheck, PerfType.ThreeCheck), + userTopPerf(leaderboards.kingOfTheHill, PerfType.KingOfTheHill), + userTopPerf(leaderboards.horde, PerfType.Horde), + userTopPerf(leaderboards.racingKings, PerfType.RacingKings) + ) + ) ) ) } + private def tournamentWinners(winners: List[lila.tournament.Winner])(implicit ctx: Context) = + st.section(cls := "user-top")( + h2(cls := "text", dataIcon := "g")( + a(href := routes.Tournament.leaderboard)(trans.tournament()) + ), + ol(winners take 10 map { w => + li( + userIdLink(w.userId.some), + a(title := w.tourName, href := routes.Tournament.show(w.tourId))( + scheduledTournamentNameShortHtml(w.tourName) + ) + ) + }) + ) + private def userTopPerf(users: List[User.LightPerf], perfType: PerfType) = - div(cls := "user_top")( + st.section(cls := "user-top")( h2(cls := "text", dataIcon := perfType.iconChar)( a(href := routes.User.topNb(200, perfType.key))(perfType.name) ), - users map { l => - div( - div(lightUserLink(l.user)), - div(l.rating) + ol(users map { l => + li( + lightUserLink(l.user), + l.rating ) - } + }) ) - private def userTopActive(users: List[User.LightCount], hTitle: Any, icon: Option[Char] = None)(implicit ctx: Context) = - div(cls := "user_top")( - h2(cls := "text", dataIcon := icon.map(_.toString))(hTitle.toString), - users map { u => - div( - div(lightUserLink(u.user)), - div(title := trans.gamesPlayed.txt())(s"#${u.count.localize}") + private def userTopActive(users: List[User.LightCount], hTitle: Frag, icon: Option[Char] = None)(implicit ctx: Context) = + st.section(cls := "user-top")( + h2(cls := "text", dataIcon := icon.map(_.toString))(hTitle), + ol(users map { u => + li( + lightUserLink(u.user), + span(title := trans.gamesPlayed.txt())(s"#${u.count.localize}") ) - } - ) - - private def side(online: List[User])(implicit ctx: Context) = - div(cls := "side")( - form(cls := "search public")( - input(placeholder := trans.search.txt(), cls := "search_user user-autocomplete") - ), - isGranted(_.UserSearch) option form(cls := "search", action := routes.Mod.search())( - input(name := "q", placeholder := "Search by IP, email, or username") - ), - div(cls := "user_lists")( - div(cls := "user_top")( - h2(trans.onlinePlayers()), - online map { u => - div( - div(userLink(u)), - showBestPerf(u) - ) - } - ) - ) + }) ) } diff --git a/app/views/user/mini.scala b/app/views/user/mini.scala index 9e3cf458b3..c461ff7bc7 100644 --- a/app/views/user/mini.scala +++ b/app/views/user/mini.scala @@ -1,7 +1,5 @@ package views.html.user -import play.twirl.api.Html - import lila.api.Context import lila.app.templating.Environment._ import lila.app.ui.ScalatagsTemplate._ @@ -20,66 +18,62 @@ object mini { ping: Option[Int], crosstable: Option[lila.game.Crosstable] )(implicit ctx: Context) = frag( - div(cls := "title")( - div( - ping map bits.signalBars, - u.profileOrDefault.countryInfo map { c => - val hasRoomForNameText = u.username.size + c.shortName.size < 20 - span( - cls := (if (hasRoomForNameText) "country" else "country hint--top"), - dataHint := (!hasRoomForNameText).option(c.name) - )( - img(cls := "flag", src := staticUrl(s"images/flags/${c.code}.png")), - hasRoomForNameText option c.shortName - ) - }, - userLink(u, withPowerTip = false) + div(cls := "upt__info")( + div(cls := "upt__info__top")( + div(cls := "left")( + userLink(u, withPowerTip = false), + u.profileOrDefault.countryInfo map { c => + val hasRoomForNameText = u.username.size + c.shortName.size < 20 + span( + cls := "upt__info__top__country", + title := (!hasRoomForNameText).option(c.name) + )( + img(cls := "flag", src := staticUrl(s"images/flags/${c.code}.png")), + hasRoomForNameText option c.shortName + ) + } + ), + ping map bits.signalBars ), if (u.engine && !ctx.me.has(u) && !isGranted(_.UserSpy)) - div(cls := "warning", dataIcon := "j")(trans.thisPlayerUsesChessComputerAssistance()) + div(cls := "upt__info__warning", dataIcon := "j")(trans.thisPlayerUsesChessComputerAssistance()) else - div(cls := "ratings")(u.best8Perfs map { showPerfRating(u, _) }) + div(cls := "upt__info__ratings")(u.best8Perfs map { showPerfRating(u, _) }) ), ctx.userId map { myId => frag( - (myId != u.id && u.enabled) option div(cls := "actions")( - a(cls := "button hint--bottom", dataHint := trans.watchGames.txt(), href := routes.User.tv(u.username))( - iconTag("1") - ), + (myId != u.id && u.enabled) option div(cls := "upt__actions btn-rack")( + a(dataIcon := "1", cls := "btn-rack__btn", title := trans.watchGames.txt(), href := routes.User.tv(u.username)), !blocked option frag( - a(cls := "button hint--bottom", dataHint := trans.chat.txt(), href := s"${routes.Message.form()}?user=${u.username}")( - iconTag("c") - ), - a(cls := "button hint--bottom", dataHint := trans.challengeToPlay.txt(), href := s"${routes.Lobby.home()}?user=${u.username}#friend")( - iconTag("U") - ) + a(dataIcon := "c", cls := "btn-rack__btn", title := trans.chat.txt(), href := s"${routes.Message.form()}?user=${u.username}"), + a(dataIcon := "U", cls := "btn-rack__btn", title := trans.challengeToPlay.txt(), href := s"${routes.Lobby.home()}?user=${u.username}#friend") ), views.html.relation.mini(u.id, blocked, followable, rel) ), crosstable.flatMap(_.nonEmpty) map { cross => a( - cls := "score hint--bottom", + cls := "upt__score", href := s"${routes.User.games(u.username, "me")}#games", - dataHint := trans.nbGames.pluralTxt(cross.nbGames, cross.nbGames.localize) - )(trans.yourScore(Html(s"""${cross.showScore(myId)} - ${~cross.showOpponentScore(myId)}"""))) + title := trans.nbGames.pluralTxt(cross.nbGames, cross.nbGames.localize) + )(trans.yourScore(raw(s"""${cross.showScore(myId)} - ${~cross.showOpponentScore(myId)}"""))) } ) }, - isGranted(_.UserSpy) option div(cls := "mod_info_box")( - (u.lameOrTroll || u.disabled) option span(cls := "mod_marks")(mod.userMarks(u, None)), - p( + isGranted(_.UserSpy) option div(cls := "upt__mod")( + span( trans.nbGames.plural(u.count.game, u.count.game.localize), " ", momentFromNowOnce(u.createdAt) - ) + ), + (u.lameOrTroll || u.disabled) option span(cls := "upt__mod__marks")(mod.userMarks(u, None)) ), (!ctx.pref.isBlindfold) ?? playing map { pov => frag( gameFen(pov), - div(cls := "game_legend")( - playerText(pov.opponent, withRating = true), - pov.game.clock map { c => - frag(" • ", c.config.show) - } + div(cls := "upt__game-legend")( + i(dataIcon := pov.game.perfType.map(_.iconChar.toString), cls := "text")( + pov.game.clock.map(_.config.show) + ), + playerText(pov.opponent, withRating = true) ) ) } diff --git a/app/views/user/mod.scala b/app/views/user/mod.scala new file mode 100644 index 0000000000..ec206de84f --- /dev/null +++ b/app/views/user/mod.scala @@ -0,0 +1,408 @@ +package views.html.user + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.evaluation.Display +import lila.user.User + +import controllers.routes + +object mod { + + def menu(u: User)(implicit ctx: Context) = div(id := "mz_menu")( + div(cls := "inner")( + a(href := "#mz_actions")("Actions"), + canViewRoles(u) option a(href := "#mz_roles")("Roles"), + a(href := "#mz_irwin")("Irwin"), + a(href := "#mz_assessments")("Evaluation"), + a(href := "#mz_plan", cls := "mz_plan")("Patron"), + a(href := "#mz_mod_log")("Mod log"), + a(href := "#mz_reports_out")("Reports sent"), + a(href := "#mz_reports_in")("Reports received"), + a(href := "#mz_others")("Accounts"), + a(href := "#mz_identification")("Identification"), + a(href := "#us_profile")("Profile") + ) + ) + + def actions(u: User, emails: User.Emails, erased: User.Erased)(implicit ctx: Context): Frag = + div(id := "mz_actions")( + isGranted(_.UserEvaluate) option div(cls := "btn-rack")( + st.form(method := "POST", action := routes.Mod.spontaneousInquiry(u.username), title := "Start an inquiry")( + button(cls := "btn-rack__btn inquiry", tpe := "submit")(i) + ), + st.form(method := "POST", action := routes.Mod.refreshUserAssess(u.username), title := "Collect data and analyze if the user is suspicious.")( + button(cls := "btn-rack__btn", tpe := "submit")("Evaluate") + ), + isGranted(_.Shadowban) option { + a(cls := "btn-rack__btn", href := routes.Mod.communicationPublic(u.id), title := "View communications")("Comms") + }, + st.form(method := "POST", action := routes.Mod.notifySlack(u.id), title := "Notify slack #tavern", cls := "xhr")( + button(cls := "btn-rack__btn", tpe := "submit")("Slack") + ) + ), + div(cls := "btn-rack")( + isGranted(_.MarkEngine) option { + st.form(method := "POST", action := routes.Mod.engine(u.username, !u.engine), title := "This user is clearly cheating.", cls := "xhr")( + button(cls := List("btn-rack__btn" -> true, "active" -> u.engine), tpe := "submit")("Engine") + ) + }, + isGranted(_.MarkBooster) option { + st.form(method := "POST", action := routes.Mod.booster(u.username, !u.booster), title := "Marks the user as a booster or sandbagger.", cls := "xhr")( + button(cls := List("btn-rack__btn" -> true, "active" -> u.booster), tpe := "submit")("Booster") + ) + }, + isGranted(_.Shadowban) option { + st.form(method := "POST", action := routes.Mod.troll(u.username, !u.troll), title := "Enable/disable communication features for this user.", cls := "xhr")( + button(cls := List("btn-rack__btn" -> true, "active" -> u.troll), tpe := "submit")("Shadowban") + ) + }, + u.troll option { + st.form(method := "POST", action := routes.Mod.deletePmsAndChats(u.username), title := "Delete all PMs and public chat messages", cls := "xhr")( + button(cls := "btn-rack__btn confirm", tpe := "submit")("Clear PMs & chats") + ) + }, + isGranted(_.RemoveRanking) option { + st.form(method := "POST", action := routes.Mod.rankban(u.username, !u.rankban), title := "Include/exclude this user from the rankings.", cls := "xhr")( + button(cls := List("btn-rack__btn" -> true, "active" -> u.rankban), tpe := "submit")("Rankban") + ) + }, + isGranted(_.ReportBan) option { + st.form(method := "POST", action := routes.Mod.reportban(u.username, !u.reportban), title := "Enable/disable the report feature for this user.", cls := "xhr")( + button(cls := List("btn-rack__btn" -> true, "active" -> u.reportban), tpe := "submit")("Reportban") + ) + } + ), + div(cls := "btn-rack")( + isGranted(_.IpBan) option { + st.form(method := "POST", action := routes.Mod.ban(u.username, !u.ipBan), cls := "xhr")( + button(cls := List("btn-rack__btn" -> true, "active" -> u.ipBan), tpe := "submit")("IP ban") + ) + }, + if (u.enabled) { + isGranted(_.CloseAccount) option { + st.form(method := "POST", action := routes.Mod.closeAccount(u.username), title := "Disables this account.", cls := "xhr")( + button(cls := "btn-rack__btn", tpe := "submit")("Close") + ) + } + } else if (erased.value) { + "Erased" + } else { + isGranted(_.ReopenAccount) option { + st.form(method := "POST", action := routes.Mod.reopenAccount(u.username), title := "Re-activates this account.", cls := "xhr")( + button(tpe := "submit", cls := "btn-rack__btn active")("Closed") + ) + } + } + ), + div(cls := "btn-rack")( + (u.totpSecret.isDefined && isGranted(_.DisableTwoFactor)) option { + st.form(method := "POST", action := routes.Mod.disableTwoFactor(u.username), title := "Disables two-factor authentication for this account.", cls := "xhr")( + button(cls := "btn-rack__btn confirm", tpe := "submit")("Disable 2FA") + ) + }, + isGranted(_.Impersonate) option { + st.form(method := "post", action := routes.Mod.impersonate(u.username))( + button(cls := "btn-rack__btn", tpe := "submit")("Impersonate") + ) + } + ), + isGranted(_.SetTitle) option { + st.form(cls := "fide_title", method := "POST", action := routes.Mod.setTitle(u.username))( + form3.select(lila.user.DataForm.title.fill(u.title.map(_.value))("title"), lila.user.Title.all, "No title".some) + ) + }, + isGranted(_.SetEmail) ?? frag( + st.form(cls := "email", method := "POST", action := routes.Mod.setEmail(u.username))( + st.input(tpe := "email", value := emails.current.??(_.value), name := "email", placeholder := "Email address"), + button(tpe := "submit", cls := "button", dataIcon := "E") + ), + emails.previous.map { email => + s"Previously $email" + } + ) + ) + + def parts(u: User, history: List[lila.mod.Modlog], charges: List[lila.plan.Charge], reports: lila.report.Report.ByAndAbout, pref: lila.pref.Pref)(implicit ctx: Context) = frag( + roles(u), + prefs(u, pref), + plan(u, charges), + modLog(u, history), + reportLog(u, reports) + ) + + def roles(u: User)(implicit ctx: Context) = canViewRoles(u) option div(cls := "mz_roles")( + (if (isGranted(_.ChangePermission)) a(href := routes.Mod.permissions(u.username)) else span)( + strong(cls := "text inline", dataIcon := " ")("Mod permissions: "), + if (u.roles.isEmpty) "Add some" else u.roles.mkString(", ") + ) + ) + + def prefs(u: User, pref: lila.pref.Pref)(implicit ctx: Context) = div(id := "mz_preferences")( + strong(cls := "text inline", dataIcon := "%")("Notable preferences:"), + ul( + (pref.keyboardMove != lila.pref.Pref.KeyboardMove.NO) option li("keyboard moves"), + pref.botCompatible option li( + strong( + a(cls := "text", dataIcon := "j", href := lila.common.String.base64.decode("aHR0cDovL2NoZXNzLWNoZWF0LmNvbS9ob3dfdG9fY2hlYXRfYXRfbGljaGVzcy5odG1s"))("BOT-COMPATIBLE SETTINGS") + ) + ) + ) + ) + + def plan(u: User, charges: List[lila.plan.Charge])(implicit ctx: Context) = charges.headOption.map { firstCharge => + div(id := "mz_plan")( + strong(cls := "text", dataIcon := patronIconChar)( + "Patron payments", + isGranted(_.PayPal) option { + firstCharge.payPal.flatMap(_.subId).map { subId => + frag(" - ", a(href := s"https://www.paypal.com/fr/cgi-bin/webscr?cmd=_profile-recurring-payments&encrypted_profile_id=$subId")("[PayPal sub]")) + } + } + ), + ul( + charges.map { c => + li(c.cents.usd.toString, " with ", c.serviceName, " on ", absClientDateTime(c.date)) + } + ), + br + ) + } + + def modLog(u: User, history: List[lila.mod.Modlog])(implicit ctx: Context) = div(id := "mz_mod_log")( + strong(cls := "text", dataIcon := "!")("Moderation history", history.isEmpty option ": nothing to show"), + history.nonEmpty ?? frag( + ul( + history.map { e => + li( + userIdLink(e.mod.some, withTitle = false), " ", + b(e.showAction), " ", + e.details, " ", + momentFromNowOnce(e.date) + ) + } + ), + br + ) + ) + + def reportLog(u: User, reports: lila.report.Report.ByAndAbout)(implicit ctx: Context) = frag( + div(id := "mz_reports_out", cls := "mz_reports")( + strong(cls := "text", dataIcon := "!")( + s"Reports sent by ${u.username}", + reports.by.isEmpty option ": nothing to show." + ), + reports.by.map { r => + r.atomBy(lila.report.ReporterId(u.id)).map { atom => + st.form(action := routes.Report.inquiry(r.id), method := "POST")( + button(tpe := "submit")(reportScore(r.score), " ", strong(r.reason.name)), " ", + userIdLink(r.user.some), " ", momentFromNowOnce(atom.at), ": ", shorten(atom.text, 200) + ) + } + } + ), + div(id := "mz_reports_in", cls := "mz_reports")( + strong(cls := "text", dataIcon := "!")( + s"Reports concerning ${u.username}", + reports.about.isEmpty option ": nothing to show." + ), + reports.about.map { r => + st.form(action := routes.Report.inquiry(r.id), method := "POST")( + button(tpe := "submit")(reportScore(r.score), " ", strong(r.reason.name)), + div(cls := "atoms")( + r.bestAtoms(3).map { atom => + div(cls := "atom")( + "By ", userIdLink(atom.by.value.some), " ", momentFromNowOnce(atom.at), ": ", shorten(atom.text, 200) + ) + }, + (r.atoms.size > 3) option s"(and ${r.atoms.size - 3} more)" + ) + ) + } + ) + ) + + def assessments(pag: lila.evaluation.PlayerAggregateAssessment.WithGames)(implicit ctx: Context): Frag = + div(id := "mz_assessments")( + pag.pag.sfAvgBlurs.map { blursYes => + p(cls := "text", dataIcon := "j")( + "ACPL in games with blurs is ", strong(blursYes), + pag.pag.sfAvgNoBlurs ?? { blursNo => + frag(" against ", strong(blursNo), " in games without blurs.") + } + ) + }, + pag.pag.sfAvgLowVar.map { lowVar => + p(cls := "text", dataIcon := "j")( + "ACPL in games with consistent move times is ", strong(lowVar), + pag.pag.sfAvgHighVar ?? { highVar => + frag(" against ", strong(highVar), " in games with random move times.") + } + ) + }, + pag.pag.sfAvgHold.map { holdYes => + p(cls := "text", dataIcon := "j")( + "ACPL in games with bot signature ", strong(holdYes), + pag.pag.sfAvgNoHold.map { holdNo => + frag(" against ", strong(holdNo), " in games without bot signature.") + } + ) + }, + table(cls := "slist")( + thead( + tr( + th("Opponent"), + th("Game"), + th("Centi-Pawn", br, "(Avg ± SD)"), + th("Move Times", br, "(Avg ± SD)"), + th(span(title := "The frequency of which the user leaves the game page.")("Blurs")), + th(span(title := "Bot detection using grid click analysis.")("Bot")), + th(span(title := "Aggregate match")(raw("Σ"))) + ) + ), + tbody( + pag.pag.playerAssessments.sortBy(-_.assessment.id).take(15).map { result => + tr( + td( + a(href := routes.Round.watcher(result.gameId, result.color.name))( + pag.pov(result) match { + case None => result.gameId + case Some(p) => playerLink(p.opponent, withRating = true, withDiff = true, withOnline = false, link = false) + } + ) + ), + td( + pag.pov(result).map { p => + a(href := routes.Round.watcher(p.gameId, p.color.name))( + p.game.isTournament option iconTag("g"), + p.game.perfType.map { pt => iconTag(pt.iconChar) }, + shortClockName(p.game.clock.map(_.config)) + ) + } + ), + td( + span(cls := s"sig sig_${Display.stockfishSig(result)}", dataIcon := "J"), + s" ${result.sfAvg} ± ${result.sfSd}" + ), + td( + span(cls := s"sig sig_${Display.moveTimeSig(result)}", dataIcon := "J"), + s" ${result.mtAvg / 10} ± ${result.mtSd / 10}", + (~result.mtStreak) ?? frag(br, "STREAK") + ), + td( + span(cls := s"sig sig_${Display.blurSig(result)}", dataIcon := "J"), + s" ${result.blurs}%", + (~result.blurStreak >= 8) ?? frag(br, s"STREAK ${result.blurStreak}/12") + ), + td( + span(cls := s"sig sig_${Display.holdSig(result)}", dataIcon := "J"), + if (result.hold) "Yes" else "No" + ), + td( + div(cls := "aggregate")( + span(cls := s"sig sig_${result.assessment.id}")(result.assessment.emoticon) + ) + ) + ) + } + ) + ) + ) + + def otherUsers(u: User, spy: lila.security.UserSpy, notes: List[lila.user.Note], bans: Map[String, Int])(implicit ctx: Context): Frag = + div(id := "mz_others")( + table(cls := "slist")( + thead( + tr( + th(spy.otherUsers.size, " similar user(s)"), + th("Same"), + th(attr("data-sort-method") := "number")("Games"), + th("Status"), + th(attr("data-sort-method") := "number")("Created"), + th(attr("data-sort-method") := "number")("Active") + ) + ), + tbody( + spy.withMeSorted(u).map { + case lila.security.UserSpy.OtherUser(o, byIp, byFp) => { + tr((o == u) option (cls := "same"))( + td(attr("data-sort") := o.id)(userLink(o, withBestRating = true, params = "?mod")), + td( + if (o == u) "-" + else List(byIp option "IP", byFp option "Print").flatten.mkString(", ") + ), + td(attr("data-sort") := o.count.game)(o.count.game.localize), + td(cls := "i") { + val ns = notes.filter(_.to == o.id) + frag( + ns.nonEmpty option { + a(href := s"${routes.User.show(o.username)}?notes")(i(title := s"Notes from ${ns.map(_.from).map(usernameOrId).mkString(", ")}", dataIcon := "m", cls := "is-green"), ns.size) + }, + userMarks(o, bans.get(o.id)) + ) + }, + td(attr("data-sort") := o.createdAt.getMillis)(momentFromNowOnce(o.createdAt)), + td(attr("data-sort") := o.seenAt.map(_.getMillis.toString))(o.seenAt.map(momentFromNowOnce)) + ) + } + } + ) + ) + ) + + def identification(u: User, spy: lila.security.UserSpy)(implicit ctx: Context): Frag = + div(id := "mz_identification")( + div(cls := "spy_ips")( + strong(spy.ips.size, " IP addresses"), + ul( + spy.ipsByLocations.map { + case (location, ips) => { + li( + p(location.toString), + ul( + ips.map { ip => + li(cls := "ip")( + a(cls := List("address" -> true, "blocked" -> ip.blocked), href := s"${routes.Mod.search}?q=${ip.ip.value}")( + tag("ip")(ip.ip.value.value), " ", momentFromNowOnce(ip.ip.date) + ) + ) + } + ) + ) + } + } + ) + ), + div(cls := "spy_uas")( + strong(spy.uas.size, " User agent(s)"), + ul( + spy.uas.sorted.map { ua => + li(ua.value, " ", momentFromNowOnce(ua.date)) + } + ) + ), + div(cls := "spy_fps")( + strong(pluralize("Fingerprint", spy.prints.size)), + ul( + spy.prints.sorted.map { fp => + li( + a(href := s"${routes.Mod.search}?q=${java.net.URLEncoder.encode(fp.value.value, "US-ASCII")}")( + fp.value.value, " ", momentFromNowOnce(fp.date) + ) + ) + } + ) + ) + ) + + def userMarks(o: User, playbans: Option[Int])(implicit ctx: Context) = div(cls := "user_marks")( + playbans.map { nb => iconTag("p", nb.toString)(title := "Playban") }, + o.troll option iconTag("c")(title := "Shadowban"), + o.booster option iconTag("9")(title := "Boosting"), + o.engine option iconTag("n")(title := "Engine"), + o.ipBan option iconTag("2")(title := "IP ban", cls := "is-red"), + o.disabled option iconTag("k")(title := "Closed"), + o.reportban option iconTag("!")(title := "Reportban") + ) +} diff --git a/app/views/user/mod/actions.scala.html b/app/views/user/mod/actions.scala.html deleted file mode 100644 index fd1d7b07a2..0000000000 --- a/app/views/user/mod/actions.scala.html +++ /dev/null @@ -1,97 +0,0 @@ -@(u: User, emails: User.Emails, erased: User.Erased)(implicit ctx: Context) - -
    - @if(isGranted(_.UserEvaluate)) { -
    - -
    -
    - -
    - @if(isGranted(_.Shadowban)) { - Comms - } -
    - -
    - • - } - @if(isGranted(_.MarkEngine)) { -
    - -
    - } - @if(isGranted(_.MarkBooster)) { -
    - -
    - } - @if(isGranted(_.Shadowban)) { -
    - -
    - @if(u.troll) { -
    - -
    - } - } - @if(isGranted(_.IpBan)) { -
    - -
    - } - @if(u.totpSecret.isDefined && isGranted(_.DisableTwoFactor)) { -
    - -
    - } - @if(u.enabled) { - @if(isGranted(_.CloseAccount)) { -
    - -
    - } - } else { - @if(erased.value) { - Erased - } else { - @if(isGranted(_.ReopenAccount)) { -
    - -
    - } - } - } -
    - @if(isGranted(_.RemoveRanking)) { -
    - -
    - } - @if(isGranted(_.ReportBan)) { -
    - -
    - } - @if(isGranted(_.Impersonate)) { -
    - -
    - } -
    - @if(isGranted(_.SetTitle)) { -
    - @base.form.select(lila.user.DataForm.title.fill(u.title.map(_.value))("title"), lila.user.Title.all, "No title".some) -
    - } - @if(isGranted(_.SetEmail)) { - - @emails.previous.map { email => - Previously @email - } - } -
    diff --git a/app/views/user/mod/assessments.scala.html b/app/views/user/mod/assessments.scala.html deleted file mode 100644 index 7452fa8811..0000000000 --- a/app/views/user/mod/assessments.scala.html +++ /dev/null @@ -1,97 +0,0 @@ -@(pag: lila.evaluation.PlayerAggregateAssessment.WithGames)(implicit ctx: Context) - -@import lila.evaluation.Display - -
    - @pag.pag.sfAvgBlurs.map { blursYes => -

    ACPL in games with blurs is @blursYes - @pag.pag.sfAvgNoBlurs.map { blursNo => - against @blursNo in games without blurs. - } -

    - } - @pag.pag.sfAvgLowVar.map { lowVar => -

    ACPL in games with consistent move times is @lowVar - @pag.pag.sfAvgHighVar.map { highVar => - against @highVar in games with random move times. - } -

    - } - @pag.pag.sfAvgHold.map { holdYes => -

    ACPL in games with bot signature @holdYes - @pag.pag.sfAvgNoHold.map { holdNo => - against @holdNo in games without bot signature. - } -

    - } - - - - - - - - - - - - - - @pag.pag.playerAssessments.sortBy(-_.assessment.id).take(15).map { result => - - - - - - - - - - } - -
    OpponentGame - Centi-Pawn -
    (Avg ± SD) -
    - Move Times -
    (Avg ± SD) -
    BlursBotΣ
    - - @pag.pov(result).fold{ - @result.gameId - } { p => - @playerLink(p.opponent, withRating = true, withDiff = true, withOnline = false, link = false) - } - - - @pag.pov(result).map { p => - - @if(p.game.isTournament) { - - } - @p.game.perfType.map { pt => - - } - @shortClockName(p.game.clock.map(_.config)) - - } - - - @result.sfAvg ± @result.sfSd - - - @(result.mtAvg/10) ± @(result.mtSd/10) - @if(~result.mtStreak){
    STREAK} -
    - - @(result.blurs)% - @if(~result.blurStreak >= 8){
    STREAK @result.blurStreak/12} -
    - - @if(result.hold){Yes} else {No} - -
    - @result.assessment.emoticon -
    -
    -
    diff --git a/app/views/user/mod/identification.scala.html b/app/views/user/mod/identification.scala.html deleted file mode 100644 index 0b843dffe9..0000000000 --- a/app/views/user/mod/identification.scala.html +++ /dev/null @@ -1,40 +0,0 @@ -@(u: User, spy: lila.security.UserSpy)(implicit ctx: Context) - -
    -
    - @spy.ips.size IP addresses -
    -
    - @spy.uas.size User agent(s)
      @spy.uas.sorted.map { ua => -
    • - @ua.value @momentFromNowOnce(ua.date) -
    • - }
    -
    -
    - @pluralize("Fingerprint", spy.prints.size) -
    -
    diff --git a/app/views/user/mod/menu.scala.html b/app/views/user/mod/menu.scala.html deleted file mode 100644 index d64327360c..0000000000 --- a/app/views/user/mod/menu.scala.html +++ /dev/null @@ -1,16 +0,0 @@ -@(u: User)(implicit ctx: Context) - diff --git a/app/views/user/mod/modLog.scala.html b/app/views/user/mod/modLog.scala.html deleted file mode 100644 index 489d725ad3..0000000000 --- a/app/views/user/mod/modLog.scala.html +++ /dev/null @@ -1,13 +0,0 @@ -@(u: User, history: List[lila.mod.Modlog])(implicit ctx: Context) - -
    - Moderation history@if(history.isEmpty){: nothing to show.} - @if(history.nonEmpty) { -
      - @history.map { e => -
    • @userIdLink(e.mod.some, withTitle=false) @e.showAction @e.details @momentFromNowOnce(e.date)
    • - } -
    -
    - } -
    diff --git a/app/views/user/mod/otherUsers.scala.html b/app/views/user/mod/otherUsers.scala.html deleted file mode 100644 index 37c76fdf4e..0000000000 --- a/app/views/user/mod/otherUsers.scala.html +++ /dev/null @@ -1,41 +0,0 @@ -@(u: User, spy: lila.security.UserSpy, notes: List[lila.user.Note], bans: Map[String, Int])(implicit ctx: Context) - -
    - - - - - - - - - - - - - @spy.withMeSorted(u).map { - case lila.security.UserSpy.OtherUser(o, byIp, byFp) => { - - - - - - - - - } - } - -
    @spy.otherUsers.size similar user(s)SameGamesStatusCreatedActive
    @userLink(o, withBestRating = true, params = "?mod") - @if(o == u) { - } else { - @List(byIp option "IP", byFp option "Print").flatten.mkString(", ") - } - @o.count.game.localize - @defining(notes.filter(_.to == o.id)) { ns => - @if(ns.nonEmpty) { - @ns.size - } - } - @userMarks(o, bans.get(o.id)) - @momentFromNowOnce(o.createdAt)@o.seenAt.map(momentFromNowOnce)
    -
    diff --git a/app/views/user/mod/parts.scala.html b/app/views/user/mod/parts.scala.html deleted file mode 100644 index 95e0eed7d2..0000000000 --- a/app/views/user/mod/parts.scala.html +++ /dev/null @@ -1,7 +0,0 @@ -@(u: User, history: List[lila.mod.Modlog], charges: List[lila.plan.Charge], reports: lila.report.Report.ByAndAbout, pref: lila.pref.Pref)(implicit ctx: Context) - -@roles(u) -@prefs(u, pref) -@user.mod.plan(u, charges) -@modLog(u, history) -@reportLog(u, reports) diff --git a/app/views/user/mod/plan.scala.html b/app/views/user/mod/plan.scala.html deleted file mode 100644 index 677e8edd04..0000000000 --- a/app/views/user/mod/plan.scala.html +++ /dev/null @@ -1,20 +0,0 @@ -@(u: User, charges: List[lila.plan.Charge])(implicit ctx: Context) - -@charges.headOption.map { firstCharge => -
    - - Patron payments - @if(isGranted(_.PayPal)) { - @firstCharge.payPal.flatMap(_.subId).map { subId => - - [PayPal sub] - } - } - -
      - @charges.map { c => -
    • @c.cents.usd with @c.serviceName on @absClientDateTime(c.date)
    • - } -
    -
    -
    -} diff --git a/app/views/user/mod/prefs.scala.html b/app/views/user/mod/prefs.scala.html deleted file mode 100644 index ff5caa1eba..0000000000 --- a/app/views/user/mod/prefs.scala.html +++ /dev/null @@ -1,15 +0,0 @@ -@(u: User, pref: lila.pref.Pref)(implicit ctx: Context) - -
    - Notable preferences: -
      - @if(pref.keyboardMove != lila.pref.Pref.KeyboardMove.NO) {
    • keyboard moves
    • } - @if(pref.botCompatible) { -
    • - - BOT-COMPATIBLE SETTINGS - -
    • - } -
    -
    diff --git a/app/views/user/mod/reportLog.scala.html b/app/views/user/mod/reportLog.scala.html deleted file mode 100644 index 90c46ae734..0000000000 --- a/app/views/user/mod/reportLog.scala.html +++ /dev/null @@ -1,33 +0,0 @@ -@(u: User, reports: lila.report.Report.ByAndAbout)(implicit ctx: Context) - -
    - Reports sent by @u.username@if(reports.by.isEmpty){: nothing to show.} - @if(reports.by.nonEmpty) { - @reports.by.map { r => - @r.atomBy(lila.report.ReporterId(u.id)).map { atom => -
    - - @userIdLink(r.user.some), @momentFromNowOnce(atom.at): @shorten(atom.text, 200) -
    - } - } - } -
    -
    - Reports concerning @u.username@if(reports.about.isEmpty){: nothing to show.} - @if(reports.about.nonEmpty) { - @reports.about.map { r => -
    - -
    - @r.bestAtoms(3).map { atom => -
    - By @userIdLink(atom.by.value.some), @momentFromNowOnce(atom.at): @shorten(atom.text, 200) -
    - } - @if(r.atoms.size > 3) { (and @{r.atoms.size - 3} more) } -
    -
    - } - } -
    diff --git a/app/views/user/mod/roles.scala.html b/app/views/user/mod/roles.scala.html deleted file mode 100644 index c7c3989dcd..0000000000 --- a/app/views/user/mod/roles.scala.html +++ /dev/null @@ -1,10 +0,0 @@ -@(u: User)(implicit ctx: Context) - -@if(canViewRoles(u)) { -
    - <@if(isGranted(_.ChangePermission)){a href="@routes.Mod.permissions(u.username)"}else{span}> - Mod permissions: - @if(u.roles.isEmpty) { Add some } else { @u.roles.mkString(", ") } - -
    -} diff --git a/app/views/user/mod/userMarks.scala.html b/app/views/user/mod/userMarks.scala.html deleted file mode 100644 index 7c5813eac0..0000000000 --- a/app/views/user/mod/userMarks.scala.html +++ /dev/null @@ -1,10 +0,0 @@ -@(o: User, playbans: Option[Int])(implicit ctx: Context) -
    - @playbans.map { nb => @nb } - @if(o.troll){} - @if(o.booster){} - @if(o.engine){} - @if(o.ipBan){} - @if(o.disabled){} - @if(o.reportban){} -
    diff --git a/app/views/user/opponents.scala b/app/views/user/opponents.scala new file mode 100644 index 0000000000..ce77949a8c --- /dev/null +++ b/app/views/user/opponents.scala @@ -0,0 +1,38 @@ +package views.html +package user + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.user.User + +import controllers.routes + +object opponents { + def apply(u: User, sugs: List[lila.relation.Related])(implicit ctx: Context) = + relation.bits.layout(s"${u.username} • ${trans.favoriteOpponents.txt()}")( + h1( + userLink(u, withOnline = false), + " favourite opponents" + ), + table(cls := "slist")( + tbody( + if (sugs.nonEmpty) sugs.map { r => + tr( + td(userLink(r.user)), + td(showBestPerf(r.user)), + td( + r.nbGames.filter(_ > 0).map { nbGames => + a(href := s"${routes.User.games(u.username, "search")}?players.b=${r.user.username}", title := "Games count over your last 1000 games")( + trans.nbGames.pluralSame(nbGames) + ) + } + ), + td(relation.actions(r.user.id, r.relation, followable = r.followable, blocked = false)) + ) + } + else tr(td("None found.")) + ) + ) + ) +} diff --git a/app/views/user/opponents.scala.html b/app/views/user/opponents.scala.html deleted file mode 100644 index d209bc8275..0000000000 --- a/app/views/user/opponents.scala.html +++ /dev/null @@ -1,33 +0,0 @@ -@(u: User, sugs: List[lila.relation.Related])(implicit ctx: Context) - -@user.layout(title = "%s - %s".format(u.username, trans.favoriteOpponents.txt())) { -
    -

    @userLink(u, withOnline = false) @trans.favoriteOpponents()

    - - @if(sugs.size > 0) { - - @sugs.map { r => - - - - - - - } - - } else { - - - - } -
    @userLink(r.user)@showBestPerf(r.user) - @r.nbGames.filter(_ > 0).map { nbGames => - - @trans.nbGames.pluralSame(nbGames) - - } - @relation.actions(r.user.id, r.relation, followable = r.followable, blocked = false).toHtml
    - None found.
    -
    -
    -} diff --git a/app/views/user/perfStat.scala b/app/views/user/perfStat.scala new file mode 100644 index 0000000000..56ded5337d --- /dev/null +++ b/app/views/user/perfStat.scala @@ -0,0 +1,62 @@ +package views.html.user + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.String.html.safeJsonValue +import lila.rating.PerfType +import lila.user.User + +import controllers.routes + +object perfStat { + + def apply( + u: User, + rankMap: lila.rating.UserRankMap, + perfType: lila.rating.PerfType, + data: play.api.libs.json.JsObject, + ratingChart: Option[String] + )(implicit ctx: Context) = views.html.base.layout( + title = s"${u.username} ${perfType.name} stats", + robots = false, + moreJs = frag( + jsAt("compiled/user.js"), + ratingChart.map { rc => + frag( + jsTag("chart/ratingHistory.js"), + embedJsUnsafe(s"lichess.ratingHistoryChart($rc,'${perfType.name}');") + ) + }, + jsAt(s"compiled/lichess.perfStat${isProd ?? (".min")}.js"), + embedJsUnsafe(s"""$$(function() { +LichessPerfStat(document.querySelector('.perf-stat__content'), { +data: ${safeJsonValue(data)} +}); +});""") + ), + moreCss = cssTag("perf-stat") + ) { + main(cls := s"page-menu")( + st.aside(cls := "page-menu__menu")(show.side(u, rankMap.some, perfType.some)), + div(cls := s"page-menu__content box perf-stat ${perfType.key}")( + div(cls := "box__top")( + h1( + a(href := routes.User.show(u.username))(u.username), + span(perfType.name, " stats") + ), + div(cls := "box__top__actions")( + u.perfs(perfType).nb > 0 option a( + cls := "button button-empty text", + dataIcon := perfType.iconChar, + href := s"${routes.User.games(u.username, "search")}?perf=${perfType.id}" + )("View the games"), + bits.perfTrophies(u, rankMap.filterKeys(perfType.key==).some) + ) + ), + ratingChart.isDefined option div(cls := "rating-history")(spinner), + div(cls := "box__pad perf-stat__content") + ) + ) + } +} diff --git a/app/views/user/perfStat.scala.html b/app/views/user/perfStat.scala.html deleted file mode 100644 index 4a70a161ad..0000000000 --- a/app/views/user/perfStat.scala.html +++ /dev/null @@ -1,50 +0,0 @@ -@(u: User, rankMap: lila.rating.UserRankMap, perfType: lila.rating.PerfType, data: play.api.libs.json.JsObject, ratingChart: Option[String])(implicit ctx: Context) - -@moreJs = { -@ratingChart.map { rc => - @jsTag("chart/ratingHistory.js") - @embedJsUnsafe(s"lichess.ratingHistoryChart($rc,'${perfType.name}');") -} - -@jsAt(s"compiled/lichess.perfStat${isProd??(".min")}.js") -@embedJs { -$(function() { -LichessPerfStat(document.getElementById('perfStatContent'), { -data: @toJsonHtml(data) -}); -}); -} -} - -@moreCss = { -@cssTag("user-perf-stat.css") -} - -@user.layout( -title = s"${u.username} ${perfType.name} stats", -side = Some(show.side(u, rankMap.some, perfType.some)), -robots = false, -evenMoreJs = moreJs, -evenMoreCss = moreCss) { -
    -
    - @if(u.perfs(perfType).nb > 0) { - - View the games - - } - @show.perfTrophies(u, rankMap.filterKeys(perfType.key==).some) -

    - - @u.username @perfType.name stats - -

    -
    - @if(ratingChart.isDefined){ -
    - @spinner -
    - } -
    -
    -} diff --git a/app/views/user/show/activity.scala.html b/app/views/user/show/activity.scala.html deleted file mode 100644 index 856a782597..0000000000 --- a/app/views/user/show/activity.scala.html +++ /dev/null @@ -1,27 +0,0 @@ -@(u: User, activities: Vector[lila.activity.ActivityView], info: lila.app.mashup.UserInfo, social: lila.app.mashup.UserInfo.Social)(implicit ctx: Context) - -@import lila.app.mashup.UserInfo.Angle - -@evenMoreJs = { -@info.ratingChart.map { ratingChart => -@jsTag("chart/ratingHistory.js") -@embedJsUnsafe(s"lichess.ratingHistoryChart($ratingChart);") -} -@if(isGranted(_.UserSpy)) { @jsAt("compiled/user-mod.js") } -} - -@evenMoreCss = { -@cssTag("activity.css") -@if(isGranted(_.UserSpy)) { @cssTag("user-mod.css") } -} - -@user.layout( -title = s"${u.username} : ${trans.activity.activity.txt()}", -side = Some(side(u, info.ranks, none)), -evenMoreJs = evenMoreJs, -evenMoreCss = evenMoreCss) { -
    - @header(u, info, Angle.Activity, social) -
    @views.html.activity(u, activities).toHtml
    -
    -} diff --git a/app/views/user/show/claimTitle.scala b/app/views/user/show/claimTitle.scala new file mode 100644 index 0000000000..92601aa76a --- /dev/null +++ b/app/views/user/show/claimTitle.scala @@ -0,0 +1,32 @@ +package views.html.user.show + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.user.User + +import controllers.routes + +object claimTitle { + + def apply(u: User)(implicit ctx: Context) = + div(cls := "claim-title")( + h2(dataIcon := "C", cls := "text")("Congratulations for breaking the 2400 rating threshold!"), + p( + "To ensure honest players aren't falsely accused of cheating, we request titled players ", + "to identify themselves. For instance, ", a(href := routes.User.show("opperwezen"))("opperwezen"), " and ", + a(href := routes.User.show("DrNykterstein"))("Magnus Carlsen"), " are verified IM, and GM. ", + "You can confirm your title and decide to remain anonymous. We will not reveal your identity." + ), + p( + "To confirm your title, ", a(href := "https://goo.gl/forms/KymEzEIFpqTO2Jbr1")("please fill in this form"), "." + ), + p( + "If you need help or have any question, feel free to contact us by email at ", contactEmailLink, "." + ), + p(cls := "actions")( + a(cls := "gotit button text", href := routes.Pref.saveTag(lila.pref.Pref.Tag.verifyTitle, "1"), dataIcon := "E")("Got it, thanks!"), + a(cls := "button", href := routes.Pref.saveTag(lila.pref.Pref.Tag.verifyTitle, "0"))("I don't have an official title") + ) + ) +} diff --git a/app/views/user/show/claimTitle.scala.html b/app/views/user/show/claimTitle.scala.html deleted file mode 100644 index e18d3efd43..0000000000 --- a/app/views/user/show/claimTitle.scala.html +++ /dev/null @@ -1,26 +0,0 @@ -@(u: User)(implicit ctx: Context) - -
    - -

    Congratulations for breaking the 2400 rating threshold!

    - -

    - To ensure honest players aren't falsely accused of cheating, we request titled players - to identify themselves. For instance, opperwezen and - Magnus Carlsen are verified IM, and GM. - Identification can be performed in a number of ways, and you can choose to remain anonymous. -

    - -

    - To confirm your title, please fill in this form.. -

    - -

    - If you need help or have any question, feel free to contact us by email at @contactEmailLink. -

    - -

    - Got it, thanks! - I don't have an official title -

    -
    diff --git a/app/views/user/show/games.scala.html b/app/views/user/show/games.scala.html deleted file mode 100644 index 236b48a577..0000000000 --- a/app/views/user/show/games.scala.html +++ /dev/null @@ -1,32 +0,0 @@ -@(u: User, info: lila.app.mashup.UserInfo, games: Paginator[Game], filters: lila.app.mashup.GameFilterMenu, searchForm: Option[Form[_]], social: lila.app.mashup.UserInfo.Social)(implicit ctx: Context) - -@import lila.app.mashup.UserInfo.Angle - -@evenMoreJs = { -@if(filters.current.name == "search") { -@nonAsyncFlatpickrTag -@jsTag("search.js") -} -@if(!u.lame || ctx.is(u) || isGranted(_.UserSpy)) { -@info.ratingChart.map { ratingChart => -@jsTag("chart/ratingHistory.js") -@embedJsUnsafe(s"lichess.ratingHistoryChart($ratingChart);") -} -} -} - -@user.layout( -title = s"${u.username} : ${userGameFilterTitleNoTag(u, info.nbs, filters.current)}${if(games.currentPage == 1) "" else " - page " + games.currentPage}", -side = Some(side(u, info.ranks, none)), -robots = false, -evenMoreJs = evenMoreJs, -openGraph = lila.app.ui.OpenGraph( -image = staticUrl("images/large_tile.png").some, -title = u.titleUsernameWithBestRating, -url = s"$netBaseUrl${routes.User.show(u.username).url}", -description = describeUser(u)).some) { -
    - @header(u, info, Angle.Games(searchForm), social) -
    @gamesContent(u, info.nbs, games, filters, filters.current.name)
    -
    -} diff --git a/app/views/user/show/gamesContent.scala b/app/views/user/show/gamesContent.scala new file mode 100644 index 0000000000..a69fc2442a --- /dev/null +++ b/app/views/user/show/gamesContent.scala @@ -0,0 +1,67 @@ +package views.html.user.show + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator +import lila.game.{ Game, Pov } +import lila.user.User + +import controllers.routes + +object gamesContent { + + def apply( + u: User, + nbs: lila.app.mashup.UserInfo.NbGames, + pager: Paginator[Game], + filters: lila.app.mashup.GameFilterMenu, + filterName: String + )(implicit ctx: Context) = frag( + + div(cls := "number-menu number-menu--tabs menu-box-pop", id := "games")( + filters.list.map { f => + a( + cls := s"nm-item to-${f.name}${(filters.current == f) ?? " active"}", + href := routes.User.games(u.username, f.name) + )(userGameFilterTitle(u, nbs, f)) + } + ), + nbs.crosstable.ifTrue(filters.current.name == "me").map { + views.html.game.crosstable(_, none) + }, + div(cls := "search__result")( + if (filterName == "search") { + val permalink = a(rel := "nofollow", href := routes.User.games(u.username, filterName))("Permalink") + if (pager.nbResults > 0) frag( + div(cls := "search__status")( + strong(pager.nbResults.localize, " games found"), + " • ", + permalink + ), + div(cls := "search__rows")( + pagerNext(pager, np => routes.User.games(u.username, filterName, np).url) | div(cls := "none"), + views.html.game.widgets(pager.currentPageResults, user = u.some, ownerLink = ctx is u) + ) + ) + else div(cls := "search__status")(strong("No game found"), " • ", permalink) + } else + div(cls := List( + "games infinitescroll" -> true, + "now-playing center" -> (filterName == "playing" && pager.nbResults > 2) + ))( + pagerNext(pager, np => routes.User.games(u.username, filterName, np).url) | div(cls := "none"), + if (filterName == "playing" && pager.nbResults > 2) + pager.currentPageResults.flatMap { Pov(_, u) }.map { p => + a(href := gameLink(p), cls := "paginated")( + gameFen(p, withLink = false), + views.html.game.bits.vstext(p)(ctx.some) + ) + } + else views.html.game.widgets(pager.currentPageResults, user = u.some, ownerLink = ctx is u) + ) + ) + ) +} diff --git a/app/views/user/show/gamesContent.scala.html b/app/views/user/show/gamesContent.scala.html deleted file mode 100644 index 4cf7bb5d98..0000000000 --- a/app/views/user/show/gamesContent.scala.html +++ /dev/null @@ -1,54 +0,0 @@ -@(u: User, nbs: lila.app.mashup.UserInfo.NbGames, pager: Paginator[Game], filters: lila.app.mashup.GameFilterMenu, filterName: String)(implicit ctx: Context) - -
    - @filters.list.map { f => - - @userGameFilterTitle(u, nbs, f) - - } -
    -@if(filters.current.name == "me") { -@nbs.crosstable.map { c => -
    @game.crosstable(c, none)
    -} -} -
    - - @if(filterName == "search") { - @if(pager.nbResults > 0) { -
    - @pager.nbResults.localize games found • - • -
    -
    - @pager.nextPage.map { n => - - }.getOrElse { -
    - } - @game.widgets(pager.currentPageResults, user = u.some, ownerLink = ctx is u).toHtml -
    - } else { -
    - No game found - - -
    - } - } else { -
    2) {game_list playing center}"> - @pager.nextPage.map { np => - - } - @if(filterName == "playing" && pager.nbResults > 2) { - @pager.currentPageResults.flatMap{ Pov(_, u) }.map { p => -
    - @gameFen(p) - @game.bits.vstext(p)(ctx.some).toHtml -
    - } - } else { - @game.widgets(pager.currentPageResults, user = u.some, ownerLink = ctx is u).toHtml - } -
    - } -
    diff --git a/app/views/user/show/header.scala b/app/views/user/show/header.scala new file mode 100644 index 0000000000..319a900f43 --- /dev/null +++ b/app/views/user/show/header.scala @@ -0,0 +1,242 @@ +package views.html.user.show + +import play.api.data.Form + +import lila.api.Context +import lila.app.mashup.UserInfo.Angle +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.String.html.richText +import lila.user.User + +import controllers.routes + +object header { + + private val dataToints = attr("data-toints") + private val dataTab = attr("data-tab") + + def apply( + u: User, + info: lila.app.mashup.UserInfo, + angle: lila.app.mashup.UserInfo.Angle, + social: lila.app.mashup.UserInfo.Social + )(implicit ctx: Context) = frag( + div(cls := "box__top user-show__header")( + h1(cls := s"user-link ${if (isOnline(u.id)) "online" else "offline"}")( + if (u.isPatron) frag( + a(cls := routes.Plan.index)(patronIcon), + userSpan(u, withPowerTip = false, withOnline = false) + ) + else userSpan(u, withPowerTip = false) + ), + div(cls := List( + "trophies" -> true, + "packed" -> (info.countTrophiesAndPerfCups > 7) + ))( + views.html.user.bits.perfTrophies(u, info.ranks), + otherTrophies(u, info), + u.plan.active option + a(href := routes.Plan.index, cls := "trophy award patron icon3d", title := s"Patron since ${showDate(u.plan.sinceDate)}")(patronIconChar) + ), + u.disabled option span(cls := "closed")("CLOSED") + ), + div(cls := "user-show__social")( + div(cls := "number-menu")( + a(cls := "nm-item", href := routes.Relation.followers(u.username))( + splitNumber(trans.nbFollowers.pluralSame(info.nbFollowers)) + ), + info.nbBlockers.map { nb => + a(cls := "nm-item")(splitNumber(nb + " Blockers")) + }, + u.noBot option a( + href := routes.UserTournament.path(u.username, "recent"), + cls := "nm-item tournament_stats", + dataToints := u.toints + )( + splitNumber(trans.nbTournamentPoints.pluralSame(u.toints)) + ), + a(href := routes.Study.byOwnerDefault(u.username), cls := "nm-item")( + splitNumber(info.nbStudies + " studies") + ), + a( + cls := "nm-item", + href := ctx.noKid option routes.ForumPost.search("user:" + u.username, 1).url + )( + splitNumber(trans.nbForumPosts.pluralSame(info.nbPosts)) + ), + (ctx.isAuth && ctx.noKid && !ctx.is(u)) option + a(cls := "nm-item note-zone-toggle")(splitNumber(social.notes.size + " Notes")) + ), + div(cls := "user-actions btn-rack")( + (ctx is u) option frag( + a(cls := "btn-rack__btn", href := routes.Account.profile, title := trans.editProfile.txt(), dataIcon := "%"), + a(cls := "btn-rack__btn", href := routes.Relation.blocks(), title := trans.listBlockedPlayers.txt(), dataIcon := "k") + ), + isGranted(_.UserSpy) option + a(cls := "btn-rack__btn mod-zone-toggle", href := routes.User.mod(u.username), title := "Mod zone", dataIcon := ""), + a(cls := "btn-rack__btn", href := routes.User.tv(u.username), title := trans.watchGames.txt(), dataIcon := "1"), + (ctx.isAuth && !ctx.is(u)) option + views.html.relation.actions(u.id, relation = social.relation, followable = social.followable, blocked = social.blocked), + if (ctx is u) a( + cls := "btn-rack__btn", + href := routes.Game.exportByUser(u.username), + title := trans.exportGames.txt(), + dataIcon := "x" + ) + else (ctx.isAuth && ctx.noKid) option a( + title := trans.reportXToModerators.txt(u.username), + cls := "btn-rack__btn", + href := s"${routes.Report.form}?username=${u.username}", + dataIcon := "!" + ) + ) + ), + (ctx.noKid && !ctx.is(u)) option div(cls := "note-zone")( + form(action := s"${routes.User.writeNote(u.username)}?note", method := "post")( + textarea(name := "text", placeholder := "Write a note about this user only you and your friends can read"), + button(tpe := "submit", cls := "button")(trans.send()), + if (isGranted(_.ModNote)) label(style := "margin-left: 1em;")( + input(tpe := "checkbox", name := "mod", checked, value := "true", style := "vertical-align: middle;"), + "For moderators only" + ) + else input(tpe := "hidden", name := "mod", value := "false") + ), + social.notes.isEmpty option div("No note yet"), + social.notes.map { note => + div(cls := "note")( + p(cls := "note__text")(richText(note.text)), + p(cls := "note__meta")( + userIdLink(note.from.some), + br, + momentFromNow(note.date), + (ctx.me.exists(note.isFrom) && !note.mod) option frag( + br, + form(action := routes.User.deleteNote(note._id), method := "post")( + button(tpe := "submit", cls := "button-empty button-red confirm button text", style := "float:right", dataIcon := "q")("Delete") + ) + ) + ) + ) + } + ), + ((ctx is u) && u.perfs.bestStandardRating > 2400 && !u.hasTitle && !ctx.pref.hasSeenVerifyTitle) option claimTitle(u), + isGranted(_.UserSpy) option div(cls := "mod-zone none"), + angle match { + case Angle.Games(Some(searchForm)) => views.html.search.user(u, searchForm) + case _ => + val profile = u.profileOrDefault + div(id := "us_profile")( + info.ratingChart.ifTrue(!u.lame || ctx.is(u) || isGranted(_.UserSpy)).map { ratingChart => + div(cls := "rating-history")(spinner) + } getOrElse { + ctx.is(u) option newPlayer(u) + }, + div(cls := "profile-side")( + div(cls := "user-infos")( + !ctx.is(u) option frag( + u.engine option div(cls := "warning engine_warning")( + span(dataIcon := "j", cls := "is4"), + trans.thisPlayerUsesChessComputerAssistance() + ), + (u.booster && (u.count.game > 0 || isGranted(_.Hunter))) option div(cls := "warning engine_warning")( + span(dataIcon := "j", cls := "is4"), + trans.thisPlayerArtificiallyIncreasesTheirRating(), + (u.count.game == 0) option """ +Only visible to mods. A booster mark without any games is a way to +prevent a player from ever playing (except against boosters/cheaters). +It's useful against spambots. These marks are not visible to the public.""" + ) + ), + ctx.noKid option frag( + profile.nonEmptyRealName.map { name => + strong(cls := "name")(name) + }, + profile.nonEmptyBio.ifTrue(!u.troll || ctx.is(u)).map { bio => + p(cls := "bio")(richText(shorten(bio, 400), nl2br = false)) + } + ), + div(cls := "stats")( + profile.officialRating.map { r => + div(r.name.toUpperCase, " rating: ", strong(r.rating)) + }, + profile.nonEmptyLocation.ifTrue(ctx.noKid).map { l => + span(cls := "location")(l) + }, + profile.countryInfo.map { c => + span(cls := "country")( + img(cls := "flag", src := staticUrl(s"images/flags/${c.code}.png")), + " ", + c.name + ) + }, + p(cls := "thin")(trans.memberSince(), " ", showDate(u.createdAt)), + u.seenAt.map { seen => + p(cls := "thin")(trans.lastSeenActive(momentFromNow(seen))) + }, + info.completionRatePercent.map { c => + p(cls := "thin")(trans.gameCompletionRate(s"$c%")) + }, + (ctx is u) option frag( + a(href := routes.Account.profile, title := trans.editProfile.txt())( + trans.profileCompletion(s"${profile.completionPercent}%") + ), + br, + a(href := routes.User.opponents)(trans.favoriteOpponents()) + ), + info.playTime.map { playTime => + frag( + p(trans.tpTimeSpentPlaying(showPeriod(playTime.totalPeriod))), + playTime.nonEmptyTvPeriod.map { tvPeriod => + p(trans.tpTimeSpentOnTV(showPeriod(tvPeriod))) + } + ) + }, + div(cls := "social_links col2")( + profile.actualLinks.map { link => + a(href := link.url, target := "_blank", rel := "no-follow")(link.site.name) + } + ), + div(cls := "teams col2")( + info.teamIds.sorted.map { t => + teamLink(t, withIcon = false) + } + ) + ) + ), + info.insightVisible option + a(cls := "insight", href := routes.Insight.index(u.username), dataIcon := "7")( + span( + strong("Chess Insights"), + em("Analytics from ", if (ctx.is(u)) "your" else s"${u.username}'s", " games") + ) + ) + ) + ) + }, + div(cls := "angles number-menu number-menu--tabs menu-box-pop")( + a( + dataTab := "activity", + cls := List( + "nm-item to-activity" -> true, + "active" -> (angle == Angle.Activity) + ), + href := routes.User.show(u.username) + )(trans.activity.activity()), + a( + dataTab := "games", + cls := List( + "nm-item to-games" -> true, + "active" -> (angle.key == "games") + ), + href := routes.User.gamesAll(u.username) + )( + trans.nbGames.plural(info.user.count.game, info.user.count.game.localize), + info.nbs.playing > 0 option + span(cls := "unread", title := trans.nbPlaying.pluralTxt(info.nbs.playing, info.nbs.playing.localize))( + info.nbs.playing + ) + ) + ) + ) +} diff --git a/app/views/user/show/header.scala.html b/app/views/user/show/header.scala.html deleted file mode 100644 index e833105536..0000000000 --- a/app/views/user/show/header.scala.html +++ /dev/null @@ -1,219 +0,0 @@ -@(u: User, info: lila.app.mashup.UserInfo, angle: lila.app.mashup.UserInfo.Angle, social: lila.app.mashup.UserInfo.Social)(implicit ctx: Context) - -@import lila.app.mashup.UserInfo.Angle -@import social._ - -
    -

    - @if(u.isPatron) { - @Html(patronIcon)@userSpan(u, withPowerTip = false, withOnline = false) - } else { - @userSpan(u, withPowerTip = false) - } -

    -
    - @perfTrophies(u, info.ranks) - @otherTrophies(u, info) -
    - @if(u.plan.active) { - @patronIconChar - } - @if(u.disabled) { - CLOSED - } -
    - -@NotForKids { -@if(!(ctx is u)) { -
    -
    - - - @if(isGranted(_.ModNote)) { - - } else { } -
    - @if(notes.isEmpty) { -
    No note yet
    - } - @notes.map { note => -
    -

    - @userIdLink(note.from.some)
    @momentFromNow(note.date) - @if(ctx.me.exists(note.isFrom) && !note.mod) { -
    -

    - -
    - } -

    -

    @richText(note.text)

    -
    - } -
    -} -} -@if((ctx is u) && u.perfs.bestStandardRating > 2400 && !u.hasTitle && !ctx.pref.hasSeenVerifyTitle ) { -@claimTitle(u) -} -@if(isGranted(_.UserSpy)) {
    } -@angle match { -case Angle.Games(Some(searchForm)) => { @search.user(u, searchForm) } -case _ => { -
    - @info.ratingChart.ifTrue(!u.lame || ctx.is(u) || isGranted(_.UserSpy)).map { ratingChart => -
    - @spinner -
    - }.getOrElse { - @if(ctx.is(u)) { - @newPlayer(u) - } - } - @defining(u.profileOrDefault) { profile => -
    - @if(!ctx.is(u)) { - @if(u.engine) { -
    - - @trans.thisPlayerUsesChessComputerAssistance() -
    - } - @if(u.booster && (u.count.game > 0 || isGranted(_.Hunter))) { -
    - - @trans.thisPlayerArtificiallyIncreasesTheirRating() - @if(u.count.game == 0) { - Only visible to mods. A booster mark without any games is a way to - prevent a player from ever playing (except against boosters/cheaters). - It's useful against spambots. These marks are not visible to the public. - } -
    - } - } else { - @u.title.flatMap(lila.user.Title.names.get).map { title => -

    @title

    - } - } - @NotForKids { - @profile.nonEmptyRealName.map { name => - @name - } - @profile.nonEmptyBio.ifTrue(!u.troll || ctx.is(u)).map { bio => -

    @richText(shorten(bio, 400), nl2br=false)

    - } - } -
    - @profile.officialRating.map { r => -
    @r.name.toUpperCase rating: @r.rating
    - } - @NotForKids { - @profile.nonEmptyLocation.map { l => - @l, - } - } - @profile.countryInfo.map { c => - @c.name - } -

    @trans.memberSince() @showDate(u.createdAt)

    - @u.seenAt.map { seen => -

    @trans.lastSeenActive(momentFromNow(seen))

    - } - @info.completionRatePercent.map { c => -

    @trans.gameCompletionRate(s"$c%")

    - } - @if(ctx is u) { - - @trans.profileCompletion(s"${profile.completionPercent}%") - -
    - @trans.favoriteOpponents() - } - @info.playTime.map { playTime => -
    -
    -

    @trans.tpTimeSpentPlaying(showPeriod(playTime.totalPeriod))

    - @playTime.nonEmptyTvPeriod.map { tvPeriod => -

    @trans.tpTimeSpentOnTV(showPeriod(tvPeriod))

    - } - } - -
    - @info.teamIds.sorted.map { t => - @teamLink(t, withIcon = false) - } -
    -
    -
    - } - @if(info.insightVisible) { - - - Chess Insights - Analytics from @if(ctx.is(u)){your}else{@u.username's} games - - } -
    -} -} - diff --git a/app/views/user/show/newPlayer.scala b/app/views/user/show/newPlayer.scala new file mode 100644 index 0000000000..d0dc292a41 --- /dev/null +++ b/app/views/user/show/newPlayer.scala @@ -0,0 +1,47 @@ +package views.html.user.show + +import play.api.data.Form + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.user.User + +import controllers.routes + +object newPlayer { + + def apply(u: User)(implicit ctx: Context) = + div(cls := "new-player")( + h2("Welcome to lichess.org!"), + p( + "This is your profile page.", + u.profile.isEmpty option frag( + br, + "Would you like to ", + a(href := routes.Account.profile)("improve it"), "?" + ) + ), + p( + if (u.kid) "Kid mode is enabled." + else frag( + "Will a child use this account? You might want to enable ", a(href := routes.Account.kid)("Kid mode"), "." + ) + ), + p( + "What now? Here are a few suggestions:" + ), + ul( + li(a(href := routes.Learn.index)("Learn chess rules")), + li(a(href := routes.Puzzle.home)("Improve with chess tactics puzzles")), + li(a(href := s"${routes.Lobby.home}#ai")("Play the artificial intelligence")), + li(a(href := s"${routes.Lobby.home}#hook")("Play opponents from around the world")), + li(a(href := routes.User.list)("Follow your friends on lichess")), + li(a(href := routes.Tournament.home(1))("Play in tournaments")), + li("Learn from ", a(href := routes.Study.allDefault(1))("studies"), + " and ", a(href := routes.Video.index)("videos")), + li(a(href := routes.Pref.form("game-display"))("Configure lichess to your liking")), + li("Explore the site and have fun :)") + ) + ) +} diff --git a/app/views/user/show/newPlayer.scala.html b/app/views/user/show/newPlayer.scala.html deleted file mode 100644 index 41f0789ed4..0000000000 --- a/app/views/user/show/newPlayer.scala.html +++ /dev/null @@ -1,32 +0,0 @@ -@(u: User)(implicit ctx: Context) - -
    -

    Welcome to lichess.org!

    -

    - This is your profile page. - @if(u.profile.isEmpty) { - Would you like to improve it? - } -

    -

    - @if(u.kid) { - Kid mode is enabled. - } else { - Will a child use this account? You might want to enable Kid mode. - } -

    -

    - What now? Here are a few suggestions: -

    - -
    diff --git a/app/views/user/show/otherTrophies.scala b/app/views/user/show/otherTrophies.scala new file mode 100644 index 0000000000..4063fa8364 --- /dev/null +++ b/app/views/user/show/otherTrophies.scala @@ -0,0 +1,101 @@ +package views.html.user.show + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.user.Trophy +import Trophy.Kind +import lila.user.User + +import controllers.routes + +object otherTrophies { + + def apply(u: User, info: lila.app.mashup.UserInfo)(implicit ctx: Context) = frag( + info.allTrophies.filter(_.kind.klass.has("fire-trophy")).some.filter(_.nonEmpty) map { trophies => + div(cls := "stacked")( + trophies.sorted.map { trophy => + trophy.kind.icon.map { iconChar => + a( + awardCls(trophy), + href := trophy.kind.url, + title := s"${trophy.kind.name}" + )(raw(iconChar)) + } + } + ) + }, + info.shields.map { shield => + a( + cls := "shield-trophy combo-trophy", + title := s"${shield.categ.name} Shield", + href := routes.Tournament.shields + )(shield.categ.iconChar.toString) + }, + info.revolutions.map { revol => + a( + cls := "revol_trophy combo-trophy", + title := s"${revol.variant.name} Revolution", + href := routes.Tournament.show(revol.tourId) + )(revol.iconChar.toString) + }, + info.allTrophies.find(_.kind == Kind.ZugMiracle).map { t => + frag( + styleTag(""" +.trophy.zugMiracle { + display: flex; + align-items: flex-end; + height: 40px; + margin: 0 8px!important; + transition: 2s; +} +.trophy.zugMiracle img { + height: 60px; +} +@keyframes psyche { + 100% { filter: hue-rotate(360deg); } +} +.trophy.zugMiracle:hover { + transform: translateY(-9px); + animation: psyche 0.3s ease-in-out infinite alternate; +}"""), + a(awardCls(t), href := t.kind.url, title := t.kind.name)( + img(src := staticUrl("images/trophy/zug-trophy.png")) + ) + ) + }, + info.allTrophies.filter(t => t.kind == Kind.ZHWC17 || t.kind == Kind.ZHWC18).::: { + info.allTrophies.filter(t => t.kind == Kind.AtomicWC16 || t.kind == Kind.AtomicWC17 || t.kind == Kind.AtomicWC18) + }.map { t => + a(awardCls(t), href := t.kind.url, title := t.kind.name, + style := "width: 65px; height: 80px; margin: 0 3px!important;")( + img(src := staticUrl(s"images/trophy/${t.kind.key}.png"), width := 65, height := 80) + ) + }, + info.allTrophies.filter(_.kind.klass.has("icon3d")).sorted.map { trophy => + trophy.kind.icon.map { iconChar => + a( + awardCls(trophy), + href := trophy.kind.url, + title := trophy.kind.name + )(raw(iconChar)) + } + }, + info.isCoach option + a( + href := routes.Coach.show(u.username), + cls := "trophy award icon3d coach", title := "Lichess Coach" + )(":"), + info.isStreamer option + a( + href := routes.Streamer.show(u.username), + cls := List( + "trophy award icon3d streamer" -> true, + "streaming" -> isStreaming(u.id) + ), + title := (if (isStreaming(u.id)) "Live now!" else "Lichess Streamer") + )("") + ) + + private def awardCls(t: Trophy) = cls := s"trophy award ${t.kind.key} ${~t.kind.klass}" +} diff --git a/app/views/user/show/otherTrophies.scala.html b/app/views/user/show/otherTrophies.scala.html deleted file mode 100644 index 1fb3b0cfd9..0000000000 --- a/app/views/user/show/otherTrophies.scala.html +++ /dev/null @@ -1,78 +0,0 @@ -@(u: User, info: lila.app.mashup.UserInfo)(implicit ctx: Context) - -@import lila.user.Trophy.Kind - -@defining(info.allTrophies.filter(_.kind.klass.has("fire_trophy"))) { fireTrophies => -@if(fireTrophies.nonEmpty) { -
    - @fireTrophies.sorted.map { trophy => - @trophy.kind.icon.map { iconChar => - href="@url" } - class="trophy award @trophy.kind.key @trophy.kind.klass hint--left" - data-hint="@trophy.kind.name">@Html(iconChar) - } - } -
    -} -} -@info.shields.map { shield => -@shield.categ.iconChar -} -@info.revolutions.map { revol => -@revol.iconChar -} -@info.allTrophies.find(_.kind == Kind.ZugMiracle).map { t => - - href="@url" } class="trophy award @t.kind.key @t.kind.klass hint--left" data-hint="@t.kind.name"> - - -} -@info.allTrophies.filter(t => t.kind == Kind.ZHWC17 || t.kind == Kind.ZHWC18).map { t => - href="@url" } class="trophy award @t.kind.key @t.kind.klass hint--left" data-hint="@t.kind.name" - style="width: 65px; height: 80px; margin: 0 3px!important;"> - - -} -@info.allTrophies.filter(t => t.kind == Kind.AtomicWC16 || t.kind == Kind.AtomicWC17 || t.kind == Kind.AtomicWC18).map { t => - href="@url" } class="trophy award @t.kind.key @t.kind.klass hint--left" data-hint="@t.kind.name" - style="width: 65px; height: 80px; margin: 0 3px!important;"> - - -} -@defining(info.allTrophies.filter(_.kind.klass.has("icon3d"))) { iconTrophies => -@iconTrophies.sorted.map { trophy => -@trophy.kind.icon.map { iconChar => - href="@url" } - class="trophy award @trophy.kind.key @trophy.kind.klass hint--left" - data-hint="@trophy.kind.name">@Html(iconChar) -} -} -} -@if(info.isCoach) { -: -} -@if(info.isStreamer) { - -} diff --git a/app/views/user/show/page.scala b/app/views/user/show/page.scala new file mode 100644 index 0000000000..edfb697b7b --- /dev/null +++ b/app/views/user/show/page.scala @@ -0,0 +1,94 @@ +package views.html.user.show + +import play.api.data.Form + +import lila.api.Context +import lila.app.mashup.UserInfo.Angle +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator +import lila.app.mashup.UserInfo +import lila.game.Game +import lila.user.User + +import controllers.routes + +object page { + + def activity( + u: User, + activities: Vector[lila.activity.ActivityView], + info: UserInfo, + social: lila.app.mashup.UserInfo.Social + )(implicit ctx: Context) = views.html.base.layout( + title = s"${u.username} : ${trans.activity.activity.txt()}", + openGraph = lila.app.ui.OpenGraph( + image = staticUrl("images/large_tile.png").some, + title = u.titleUsernameWithBestRating, + url = s"$netBaseUrl${routes.User.show(u.username).url}", + description = describeUser(u) + ).some, + moreJs = moreJs(info), + moreCss = frag( + cssTag("user.show"), + isGranted(_.UserSpy) option cssTag("mod.user") + ) + ) { + main(cls := "page-menu", dataUsername := u.username)( + st.aside(cls := "page-menu__menu")(side(u, info.ranks, none)), + div(cls := "page-menu__content box user-show")( + header(u, info, Angle.Activity, social), + div(cls := "angle-content")(views.html.activity(u, activities)) + ) + ) + } + + def games( + u: User, + info: UserInfo, + games: Paginator[Game], + filters: lila.app.mashup.GameFilterMenu, + searchForm: Option[Form[_]], + social: lila.app.mashup.UserInfo.Social + )(implicit ctx: Context) = views.html.base.layout( + title = s"${u.username} : ${userGameFilterTitleNoTag(u, info.nbs, filters.current)}${if (games.currentPage == 1) "" else " - page " + games.currentPage}", + moreJs = moreJs(info, filters.current.name == "search"), + moreCss = frag( + cssTag("user.show"), + if (filters.current.name == "search") cssTag("user.show.search") + else info.nbs.crosstable.isDefined option cssTag("crosstable"), + isGranted(_.UserSpy) option cssTag("mod.user") + ) + ) { + main(cls := "page-menu", dataUsername := u.username)( + st.aside(cls := "page-menu__menu")(side(u, info.ranks, none)), + div(cls := "page-menu__content box user-show")( + header(u, info, Angle.Games(searchForm), social), + div(cls := "angle-content")(gamesContent(u, info.nbs, games, filters, filters.current.name)) + ) + ) + } + + private def moreJs(info: UserInfo, withSearch: Boolean = false)(implicit ctx: Context) = frag( + infiniteScrollTag, + jsAt("compiled/user.js"), + info.ratingChart.map { ratingChart => + frag( + jsTag("chart/ratingHistory.js"), + embedJsUnsafe(s"lichess.ratingHistoryChart($ratingChart);") + ) + }, + withSearch option frag(jsTag("search.js")), + isGranted(_.UserSpy) option jsAt("compiled/user-mod.js") + ) + + def disabled(u: User)(implicit ctx: Context) = + views.html.base.layout(title = u.username, robots = false) { + main(cls := "box box-pad")( + h1(u.username), + p(trans.thisAccountIsClosed()) + ) + } + + private val dataUsername = attr("data-username") +} diff --git a/app/views/user/show/perfTrophies.scala.html b/app/views/user/show/perfTrophies.scala.html deleted file mode 100644 index ec138233fb..0000000000 --- a/app/views/user/show/perfTrophies.scala.html +++ /dev/null @@ -1,29 +0,0 @@ -@(u: User, rankMap: Option[lila.rating.UserRankMap])(implicit ctx: Context) - -@import lila.rating.PerfType - -@rankMap.ifFalse(u.lame).map { ranks => -@ranks.toList.sortBy(_._2).map { -case (perf, rank) if rank == 1 => { - - - -} -case (perf, rank) if rank <= 10 => { - - - -} -case (perf, rank) if rank <= 50 => { - - - -} -case (perf, rank) if rank <= 100 => { - - - -} -case _ => {} -} -} diff --git a/app/views/user/show/side.scala b/app/views/user/show/side.scala index 4b75e310fd..a8c36246fa 100644 --- a/app/views/user/show/side.scala +++ b/app/views/user/show/side.scala @@ -30,30 +30,32 @@ object side { "active" -> active.has(perfType) ), href := isGame option routes.User.perfStat(u.username, perfType.key).url, - h3(name.getOrElse(perfType.name).toUpperCase), - span(cls := "rating")( - strong( - perf.glicko.intRating, - perf.provisional option "?" + span( + h3(name.getOrElse(perfType.name).toUpperCase), + st.rating( + strong( + perf.glicko.intRating, + perf.provisional option "?" + ), + " ", + ratingProgress(perf.progress), + " ", + span( + if (perfType.key == "puzzle") trans.nbPuzzles(perf.nb, perf.nb.localize) + else trans.nbGames(perf.nb, perf.nb.localize) + ) ), - " ", - span( - if (perfType.key == "puzzle") trans.nbPuzzles(perf.nb, perf.nb.localize) - else trans.nbGames(perf.nb, perf.nb.localize) - ), - " ", - showProgress(perf.progress, withTitle = false) - ), - rankMap.fold(rankUnavailable) { ranks => - ranks.get(perfType.key) map { rank => - span(cls := "rank", title := trans.rankIsUpdatedEveryNbMinutes.pluralSameTxt(15))(trans.rankX(rank.localize)) + rankMap.fold(rankUnavailable) { ranks => + ranks.get(perfType.key) map { rank => + span(cls := "rank", title := trans.rankIsUpdatedEveryNbMinutes.pluralSameTxt(15))(trans.rankX(rank.localize)) + } } - }, + ), isGame option iconTag("G") ) } - div(cls := "side sub_ratings")( + div(cls := "side sub-ratings")( (!u.lame || ctx.is(u) || isGranted(_.UserSpy)) option frag( showNonEmptyPerf(u.perfs.ultraBullet, PerfType.UltraBullet), showPerf(u.perfs.bullet, PerfType.Bullet), diff --git a/app/views/user/simpleTable.scala.html b/app/views/user/simpleTable.scala.html deleted file mode 100644 index d4a4a46921..0000000000 --- a/app/views/user/simpleTable.scala.html +++ /dev/null @@ -1,25 +0,0 @@ -@(pager: Paginator[lila.relation.Related], call: Call)(implicit ctx: Context) - - - @if(pager.nbResults > 0) { - - @pager.nextPage.map { np => - - } - @pager.currentPageResults.map { r => - - - - - - - } - - } else { - - - - } -
    - -
    @userLink(r.user)@showBestPerf(r.user)@trans.nbGames.pluralSame(r.user.count.game)@relation.actions(r.user.id, relation = r.relation, followable = r.followable, blocked = false).toHtml
    None found.
    diff --git a/app/views/user/top.scala b/app/views/user/top.scala new file mode 100644 index 0000000000..f0e4a59704 --- /dev/null +++ b/app/views/user/top.scala @@ -0,0 +1,45 @@ +package views.html +package user + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.rating.PerfType +import lila.user.User + +import controllers.routes + +object top { + + def apply(perfType: lila.rating.PerfType, users: List[User.LightPerf])(implicit ctx: Context) = { + + val title = s"${perfType.name} top 200" + + views.html.base.layout( + title = title, + moreCss = cssTag("slist"), + openGraph = lila.app.ui.OpenGraph( + title = s"Leaderboard of ${perfType.name}", + url = s"$netBaseUrl${routes.User.topNb(200, perfType.key).url}", + description = s"The 200 best chess players in ${perfType.name}, sorted by rating" + ).some + )( + main(cls := "page-small box")( + h1(a(href := routes.User.list, dataIcon := "I"), title), + table(cls := "slist slist-pad")( + tbody( + users.zipWithIndex.map { + case (u, i) => tr( + td(i + 1), + td(lightUserLink(u.user)), + td(u.rating), + td(ratingProgress(u.progress)) + ) + } + ) + ) + ) + ) + } + +} diff --git a/app/views/user/top.scala.html b/app/views/user/top.scala.html deleted file mode 100644 index 61d01d5771..0000000000 --- a/app/views/user/top.scala.html +++ /dev/null @@ -1,33 +0,0 @@ -@(perfType: lila.rating.PerfType, users: List[lila.user.User.LightPerf])(implicit ctx: Context) - -@title = @{ s"${perfType.name} top 200" } - -@user.layout( -title = title, -openGraph = lila.app.ui.OpenGraph( -title = s"Leaderboard of ${perfType.name}", -url = s"$netBaseUrl${routes.User.topNb(200, perfType.key).url}", -description = s"The 200 best chess players in ${perfType.name}, sorted by rating").some, -withInfScroll = false) { -
    -

    - @title -

    -
    -
    - - - @users.zipWithIndex.map { - case (u, i) => { - - - - - - - } - } - -
    @(i + 1)@lightUserLink(u.user)@u.rating@showProgress(u.progress)
    -
    -} diff --git a/app/views/userTournament/best.scala.html b/app/views/userTournament/best.scala.html deleted file mode 100644 index 7e37759861..0000000000 --- a/app/views/userTournament/best.scala.html +++ /dev/null @@ -1,10 +0,0 @@ -@(u: User, pager: Paginator[lila.tournament.LeaderboardApi.TourEntry])(implicit ctx: Context) - -@layout(u, -title = s"${u.username} tournaments", -path = "best", -moreJs = infiniteScrollTag) { -
    - @list(u, "best", pager, "Best results", "BEST") -
    -} diff --git a/app/views/userTournament/bits.scala b/app/views/userTournament/bits.scala new file mode 100644 index 0000000000..afc7a99196 --- /dev/null +++ b/app/views/userTournament/bits.scala @@ -0,0 +1,55 @@ +package views.html +package userTournament + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator +import lila.user.User + +import controllers.routes + +object bits { + + def best(u: User, pager: Paginator[lila.tournament.LeaderboardApi.TourEntry])(implicit ctx: Context) = + layout( + u, + title = s"${u.username} tournaments", + path = "best", + moreJs = infiniteScrollTag + ) { + views.html.userTournament.list(u, "best", pager, "Best results", "BEST") + } + + def recent(u: User, pager: Paginator[lila.tournament.LeaderboardApi.TourEntry])(implicit ctx: Context) = + layout( + u, + title = s"${u.username} tournaments", + path = "recent", + moreJs = infiniteScrollTag + ) { + views.html.userTournament.list(u, "recent", pager, "Recently played", pager.nbResults.toString) + } + + def layout(u: User, title: String, path: String, moreJs: Frag = emptyFrag)(body: Frag)(implicit ctx: Context) = + views.html.base.layout( + title = title, + moreCss = cssTag("user-tournament"), + moreJs = moreJs + ) { + main(cls := "page-menu")( + st.nav(cls := "page-menu__menu subnav")( + a(cls := path.active("recent"), href := routes.UserTournament.path(u.username, "recent"))( + "Recently played" + ), + a(cls := path.active("best"), href := routes.UserTournament.path(u.username, "best"))( + "Best results" + ), + a(cls := path.active("chart"), href := routes.UserTournament.path(u.username, "chart"))( + "Stats" + ) + ), + div(cls := "page-menu__content box")(body) + ) + } +} diff --git a/app/views/userTournament/chart.scala b/app/views/userTournament/chart.scala new file mode 100644 index 0000000000..b28977b1b0 --- /dev/null +++ b/app/views/userTournament/chart.scala @@ -0,0 +1,60 @@ +package views.html +package userTournament + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.user.User + +object chart { + + def apply(u: User, data: lila.tournament.LeaderboardApi.ChartData)(implicit ctx: Context) = bits.layout( + u, + title = s"${u.username} tournaments", + path = "chart" + ) { + div(cls := "tournament-stats")( + h1(cls := "box__pad")(userLink(u, withOnline = true), " tournament stats"), + p(cls := "box__pad")( + "The rank avg is a percentage of your ranking. Lower is better.", br, + "For instance, being ranked 3 in a tournament of 100 players = 3%. ", + "Being ranked 10 in a tournament of 1000 players = 1%." + ), + p(cls := "box__pad")( + "All averages on this page are ", + a(href := "http://dictionary.reference.com/help/faq/language/d72.html")("medians"), "." + ), + table(cls := "slist slist-pad perf-results")( + thead( + tr( + th, + th("Tournaments"), + th("Points avg"), + th("Points sum"), + th("Rank avg") + ) + ), + tbody( + data.perfResults.map { + case (pt, res) => { + tr( + th(iconTag(pt.iconChar, pt.name)), + td(res.nb.localize), + td(res.points.median.map(_.toInt)), + td(res.points.sum.localize), + td(res.rankPercentMedian, "%") + ) + } + }, + tr( + th("Total"), + td(data.allPerfResults.nb.localize), + td(data.allPerfResults.points.median.map(_.toInt)), + td(data.allPerfResults.points.sum.localize), + td(data.allPerfResults.rankPercentMedian, "%") + ) + ) + ) + ) + } +} diff --git a/app/views/userTournament/chart.scala.html b/app/views/userTournament/chart.scala.html deleted file mode 100644 index cdb5082eb9..0000000000 --- a/app/views/userTournament/chart.scala.html +++ /dev/null @@ -1,50 +0,0 @@ -@(u: User, data: lila.tournament.LeaderboardApi.ChartData)(implicit ctx: Context) - -@layout(u, -title = s"${u.username} tournaments", -path = "chart") { -
    -

    @userLink(u, withOnline = true) tournaments stats

    -

    - The rank avg is a percentage of your ranking. Lower is better.
    - For instance, being ranked 3 in a tournament of 100 players = 3%. - Being ranked 10 in a tournament of 1000 players = 1%. -

    -

    - All averages on this page are medians. -

    - - - - - - - - - - - - @data.perfResults.map { - case (pt, res) => { - - - - - - - - } - } - @defining(data.allPerfResults) { res => - - - - - - - - } - -
    TournamentsPoints avgPoints sumRank avg
    @pt.name@res.nb.localize@res.points.median.map(_.toInt)@res.points.sum.localize@res.rankPercentMedian%
    Total@res.nb.localize@res.points.median.map(_.toInt)@res.points.sum.localize@res.rankPercentMedian%
    -
    -} diff --git a/app/views/userTournament/layout.scala.html b/app/views/userTournament/layout.scala.html deleted file mode 100644 index 550e60ca8f..0000000000 --- a/app/views/userTournament/layout.scala.html +++ /dev/null @@ -1,19 +0,0 @@ -@(u: User, title: String, path: String, moreJs: Html = emptyHtml)(body: Html)(implicit ctx: Context) - -@menu = { - - Recently played - - - Best results - - - Stats - -} - -@base.layout( -title = title, -menu = menu.some, -moreCss = cssTag("user-tournaments.css"), -moreJs = moreJs)(body).toHtml diff --git a/app/views/userTournament/list.scala b/app/views/userTournament/list.scala new file mode 100644 index 0000000000..5c4443249a --- /dev/null +++ b/app/views/userTournament/list.scala @@ -0,0 +1,53 @@ +package views.html +package userTournament + +import lila.api.Context +import lila.user.User +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator + +import controllers.routes + +object list { + + def apply(u: User, path: String, pager: Paginator[lila.tournament.LeaderboardApi.TourEntry], title: String, count: String)(implicit ctx: Context) = + if (pager.nbResults == 0) { + div(cls := "box-pad")(u.username, " hasn't played in any tournament yet!") + } else { + div(cls := "tournament-list")( + table(cls := "slist")( + thead( + tr( + th(cls := "count")(count), + th(h1(userLink(u, withOnline = true), " tournaments")), + th("Games"), + th("Points"), + th("Rank") + ) + ), + tbody(cls := "infinitescroll")( + pagerNextTable(pager, np => routes.UserTournament.path(u.username, path, np).url), + pager.currentPageResults.map { e => + tr(cls := List("paginated" -> true, "scheduled" -> e.tour.isScheduled))( + td(cls := "icon")(iconTag(tournamentIconChar(e.tour))), + td(cls := "header")( + a(href := routes.Tournament.show(e.tour.id))( + span(cls := "name")(e.tour.fullName), + span(cls := "setup")( + e.tour.clock.show, " • ", + if (e.tour.variant.exotic) e.tour.variant.name else e.tour.perfType.map(_.name), " • ", + momentFromNow(e.tour.startsAt) + ) + ) + ), + td(cls := "games")(e.entry.nbGames), + td(cls := "score")(e.entry.score), + td(cls := "rank")(strong(e.entry.rank), " / ", e.tour.nbPlayers) + ) + } + ) + ) + ) + } +} diff --git a/app/views/userTournament/list.scala.html b/app/views/userTournament/list.scala.html deleted file mode 100644 index ce3a2edeb8..0000000000 --- a/app/views/userTournament/list.scala.html +++ /dev/null @@ -1,51 +0,0 @@ -@(u: User, path: String, pager: Paginator[lila.tournament.LeaderboardApi.TourEntry], title: String, count: String)(implicit ctx: Context) -@if(pager.nbResults == 0) { -@u.username hasn't played in any tournament yet! -} else { -
    - - - - - - - - - - - - @pager.nextPage.map { np => - - } - @pager.currentPageResults.map { e => - - - - - - - - } - -
    @count -

    @userLink(u, withOnline = true) tournaments

    -
    GamesPointsRank
    - -
    - - - - @e.tour.fullName - - @e.tour.clock.show • - @if(e.tour.variant.exotic) { - @e.tour.variant.name - } else { - @e.tour.perfType.map(_.name) - } • - @momentFromNow(e.tour.startsAt) - - - @e.entry.nbGames@e.entry.score@e.entry.rank / @e.tour.nbPlayers
    -
    -} diff --git a/app/views/userTournament/recent.scala.html b/app/views/userTournament/recent.scala.html deleted file mode 100644 index 524b7181ce..0000000000 --- a/app/views/userTournament/recent.scala.html +++ /dev/null @@ -1,10 +0,0 @@ -@(u: User, pager: Paginator[lila.tournament.LeaderboardApi.TourEntry])(implicit ctx: Context) - -@layout(u, -title = s"${u.username} tournaments", -path = "recent", -moreJs = infiniteScrollTag) { -
    - @list(u, "recent", pager, "Recently played", pager.nbResults.toString) -
    -} diff --git a/app/views/video/author.scala.html b/app/views/video/author.scala.html deleted file mode 100644 index 2d2401be3c..0000000000 --- a/app/views/video/author.scala.html +++ /dev/null @@ -1,23 +0,0 @@ -@(author: String, videos: Paginator[lila.video.VideoView], control: lila.video.UserControl)(implicit ctx: Context) - -@layout( -title = s"$author • Free Chess Videos", -control = control) { - -
    - -

    - @author • @pluralize("video", videos.nbResults) found -

    -
    -
    - @videos.currentPageResults.map { video => - @card(video, control) - } - @videos.nextPage.map { next => -
    - -
    - } -
    -} diff --git a/app/views/video/bits.scala b/app/views/video/bits.scala new file mode 100644 index 0000000000..22826dfcc2 --- /dev/null +++ b/app/views/video/bits.scala @@ -0,0 +1,92 @@ +package views.html.video + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator + +import controllers.routes + +object bits { + + private[video] def card(vv: lila.video.VideoView, control: lila.video.UserControl)(implicit ctx: Context) = + a(cls := "card paginated", href := s"${routes.Video.show(vv.video.id)}?${control.queryStringUnlessBot}")( + vv.view option span(cls := "view")("watched"), + span(cls := "duration")(vv.video.durationString), + span(cls := "img", style := s"background-image: url(${vv.video.thumbnail})"), + span(cls := "info")( + span(cls := "title")(vv.video.title) + ), + span(cls := "reveal")( + span(cls := "full-title")(vv.video.title), + span(cls := "author")(vv.video.author), + span(cls := "target")(vv.video.targets.map(lila.video.Target.name).mkString(", ")), + span(cls := "tags")( + vv.video.tags.map { tag => + span(dataIcon := "o")(tag.capitalize) + } + ) + ) + ) + + def author(name: String, videos: Paginator[lila.video.VideoView], control: lila.video.UserControl)(implicit ctx: Context) = + layout( + title = s"$name • Free Chess Videos", + control = control + )( + div(cls := "box__top")( + h1( + a(cls := "is4 text", dataIcon := "i", href := s"${routes.Video.index}?${control.queryString}"), + name + ), + span( + pluralize("video", videos.nbResults), + " found" + ) + ), + div(cls := "list infinitescroll box__pad")( + videos.currentPageResults.map { card(_, control) }, + videos.nextPage.map { next => + div(cls := "pager none")( + a(rel := "next", href := s"${routes.Video.author(name)}?${control.queryString}&page=${next}")("Next") + ) + } + ) + ) + + def notFound(control: lila.video.UserControl)(implicit ctx: Context) = + layout(title = "Video not found", control = control)( + div(cls := "content_box_top")( + a(cls := "is4 text lichess_title", dataIcon := "i", href := routes.Video.index)("Video library") + ), + div(cls := "not_found")( + h1("Video Not Found!"), + br, br, + a(cls := "big button text", dataIcon := "i", href := routes.Video.index)("Return to the video library") + ) + ) + + def searchForm(query: Option[String])(implicit ctx: Context) = + form(cls := "search", method := "GET", action := routes.Video.index)( + input(placeholder := trans.search.txt(), tpe := "text", name := "q", value := query) + ) + + def tags(ts: List[lila.video.TagNb], control: lila.video.UserControl)(implicit ctx: Context) = + layout(title = s"Tags • Free Chess Videos", control = control)( + div(cls := "box__top")( + h1(cls := "lichess_title")( + a(cls := "text", dataIcon := "i", href := s"${routes.Video.index}?${control.queryString}")( + "All ", ts.size, " video tags" + ) + ) + ), + div(cls := "tag-list box__pad")( + ts.sortBy(_.tag).map { t => + a(cls := "tag", href := s"${routes.Video.index}?tags=${t.tag}")( + t.tag.capitalize, + em(t.nb) + ) + } + ) + ) +} diff --git a/app/views/video/card.scala.html b/app/views/video/card.scala.html deleted file mode 100644 index 178422360d..0000000000 --- a/app/views/video/card.scala.html +++ /dev/null @@ -1,22 +0,0 @@ -@(vv: lila.video.VideoView, control: lila.video.UserControl)(implicit ctx: Context) - - - @if(vv.view) { - watched - } - @vv.video.durationString - - - @vv.video.title - - - @vv.video.title - @vv.video.author - @vv.video.targets.map(lila.video.Target.name).mkString(", ") - - @vv.video.tags.map { tag => - @tag.capitalize - } - - - diff --git a/app/views/video/index.scala b/app/views/video/index.scala new file mode 100644 index 0000000000..14811a00c2 --- /dev/null +++ b/app/views/video/index.scala @@ -0,0 +1,52 @@ +package views.html.video + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator + +import controllers.routes + +object index { + + def apply(videos: Paginator[lila.video.VideoView], count: Int, control: lila.video.UserControl)(implicit ctx: Context) = { + + val tagString = s"${if (control.filter.tags.nonEmpty) control.filter.tags.mkString(" + ") + " • " else ""}" + + layout( + title = s"${tagString}Free Chess Videos", + openGraph = lila.app.ui.OpenGraph( + title = s"${tagString}free, carefully curated chess videos", + description = s"${videos.nbResults} curated chess videos${if (tagString.nonEmpty) " matching the tags " + tagString else " • "}free for all", + url = s"$netBaseUrl${routes.Video.index}?${control.queryString}" + ).some, + control = control + )( + div(cls := "box__top")( + h1( + if (control.filter.tags.nonEmpty) frag(pluralize("video", videos.nbResults), " found") + else "Chess videos" + ), + bits.searchForm(control.query) + ), + control.filter.tags.isEmpty option p(cls := "explain box__pad")( + "All videos are free for everyone.", br, + "Click one or many tags on the left to filter.", br, + "We have carefully selected ", strong(count), " videos so far!" + ), + div(cls := "list box__pad infinitescroll")( + videos.currentPageResults.map { bits.card(_, control) }, + videos.currentPageResults.size < 4 option div(cls := s"not_much nb_${videos.nbResults}")( + if (videos.currentPageResults.isEmpty) "No videos for these tags:" + else "That's all we got for these tags:", + control.filter.tags.map { tag => + a(cls := "tag", dataIcon := "o", href := s"${routes.Video.index}?tags=$tag")(tag.capitalize) + }, + br, br, + a(href := routes.Video.index, cls := "button")("Clear search") + ), + pagerNext(videos, np => s"${routes.Video.index}?${control.queryString}&page=$np") + ) + ) + } +} diff --git a/app/views/video/index.scala.html b/app/views/video/index.scala.html deleted file mode 100644 index 39ce7820e3..0000000000 --- a/app/views/video/index.scala.html +++ /dev/null @@ -1,55 +0,0 @@ -@(videos: Paginator[lila.video.VideoView], count: Int, control: lila.video.UserControl)(implicit ctx: Context) - -@tagString = @{ s"${if(control.filter.tags.nonEmpty) control.filter.tags.mkString(" + ") + " • " else ""}" } - -@layout( -title = s"${tagString}Free Chess Videos", -openGraph = lila.app.ui.OpenGraph( -title = s"${tagString}free, carefully curated chess videos", -description = s"${videos.nbResults} curated chess videos${if(tagString.nonEmpty) " matching the tags " + tagString else " • "}free for all", -url = s"$netBaseUrl${routes.Video.index}?${control.queryString}").some, -control = control) { - -
    - @searchForm(control.query) -

    - @if(control.filter.tags.nonEmpty) { - @pluralize("video", videos.nbResults) found - } else { - Free Chess video library - } -

    -
    -@if(control.filter.tags.isEmpty) { -

    - All videos are free for everyone.
    - Click one or many tags on the left to filter.
    - We have carefully selected @count videos so far! -

    -} -
    - @videos.currentPageResults.map { video => - @card(video, control) - } - @if(videos.currentPageResults.size < 4) { -
    - @if(videos.currentPageResults.isEmpty) { - No videos for these tags: - } else { - That's all we got for these tags: - } - @control.filter.tags.map { tag => - @tag.capitalize - } -
    -
    - Clear search -
    - } - @videos.nextPage.map { next => -
    - -
    - } -
    -} diff --git a/app/views/video/layout.scala b/app/views/video/layout.scala new file mode 100644 index 0000000000..2de0fe8fdb --- /dev/null +++ b/app/views/video/layout.scala @@ -0,0 +1,51 @@ +package views.html.video + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object layout { + + def apply( + title: String, + control: lila.video.UserControl, + openGraph: Option[lila.app.ui.OpenGraph] = None + )(body: Modifier*)(implicit ctx: Context) = + views.html.base.layout( + title = title, + moreCss = cssTag("video"), + moreJs = infiniteScrollTag, + wrapClass = "full-screen-force", + openGraph = openGraph + ) { + main(cls := "video page-menu")( + st.aside(cls := "page-menu__menu")( + div(cls := "subnav")( + control.tags.map { t => + val checked = control.filter.tags contains t.tag + a( + cls := List( + "checked" -> checked, + "full" -> (checked || t.nb > 0), + "empty" -> !(checked || t.nb > 0) + ), + href := (checked || t.nb > 0) option s"${routes.Video.index}?${control.toggleTag(t.tag).queryString}" + )( + span(t.tag.capitalize), + (!checked && t.nb > 0) option em(t.nb) + ) + } + ), + div(cls := "under-tags")( + if (control.filter.tags.nonEmpty) + a(cls := "button button-empty", href := routes.Video.index)("Clear search") + else + a(dataIcon := "o", href := routes.Video.tags)("View more tags") + ) + ), + div(cls := "page-menu__content box")(body) + ) + } +} diff --git a/app/views/video/layout.scala.html b/app/views/video/layout.scala.html deleted file mode 100644 index bb62a5fed0..0000000000 --- a/app/views/video/layout.scala.html +++ /dev/null @@ -1,37 +0,0 @@ -@(title: String, control: lila.video.UserControl, openGraph: Option[lila.app.ui.OpenGraph] = None)(body: Html)(implicit ctx: Context) - -@sideSection = { -
    -
    - @control.tags.map { t => - @defining(control.filter.tags contains t.tag) { checked => - 0) {href="@routes.Video.index?@control.toggleTag(t.tag).queryString"}> - @if(t.nb > 0) {@t.nb} - @t.tag.capitalize - - } - } -
    - @if(control.filter.tags.nonEmpty) { - - } else { - - } -
    -} - -@base.layout( -title = title, -moreCss = cssTag("video.css"), -moreJs = infiniteScrollTag, -side = sideSection.some, -openGraph = openGraph) { -
    - @body -
    -}.toHtml diff --git a/app/views/video/notFound.scala.html b/app/views/video/notFound.scala.html deleted file mode 100644 index 1be19e8d7b..0000000000 --- a/app/views/video/notFound.scala.html +++ /dev/null @@ -1,16 +0,0 @@ -@(control: lila.video.UserControl)(implicit ctx: Context) - -@layout( -title = "Video not found", -control = control) { - - -
    -

    Video Not Found!

    -
    -
    - Return to the video library -
    -} diff --git a/app/views/video/search.scala b/app/views/video/search.scala new file mode 100644 index 0000000000..765f23e787 --- /dev/null +++ b/app/views/video/search.scala @@ -0,0 +1,30 @@ +package views.html.video + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ +import lila.common.paginator.Paginator + +import controllers.routes + +object search { + + def apply(videos: Paginator[lila.video.VideoView], control: lila.video.UserControl)(implicit ctx: Context) = + layout(title = s"${control.query.getOrElse("Search")} • Free Chess Videos", control = control)( + div(cls := "box__top")( + h1(pluralize("video", videos.nbResults), " found"), + bits.searchForm(control.query) + ), + div(cls := "list infinitescroll box__pad")( + videos.currentPageResults.map { bits.card(_, control) }, + videos.currentPageResults.size < 4 option div(cls := s"not_much nb_${videos.nbResults}")( + if (videos.currentPageResults.isEmpty) "No videos for this search:" + else "That's all we got for this search:", + s""""$control.query"""", + br, br, + a(href := routes.Video.index, cls := "button")("Clear search") + ), + pagerNext(videos, np => s"${routes.Video.index}?${control.queryString}&page=$np") + ) + ) +} diff --git a/app/views/video/search.scala.html b/app/views/video/search.scala.html deleted file mode 100644 index bf3334b0da..0000000000 --- a/app/views/video/search.scala.html +++ /dev/null @@ -1,36 +0,0 @@ -@(videos: Paginator[lila.video.VideoView], control: lila.video.UserControl)(implicit ctx: Context) - -@layout( -title = s"${control.query.getOrElse("Search")} • Free Chess Videos", -control = control) { - -
    - @searchForm(control.query) -

    - @pluralize("video", videos.nbResults) found -

    -
    -
    - @videos.currentPageResults.map { video => - @card(video, control) - } - @if(videos.currentPageResults.size < 4) { -
    - @if(videos.currentPageResults.isEmpty) { - No videos for this search: - } else { - That's all we got for this search: - } - "@control.query" -
    -
    - Clear search -
    - } - @videos.nextPage.map { next => -
    - -
    - } -
    -} diff --git a/app/views/video/searchForm.scala.html b/app/views/video/searchForm.scala.html deleted file mode 100644 index c745b3c019..0000000000 --- a/app/views/video/searchForm.scala.html +++ /dev/null @@ -1,5 +0,0 @@ -@(query: Option[String])(implicit ctx: Context) - diff --git a/app/views/video/show.scala b/app/views/video/show.scala new file mode 100644 index 0000000000..ccdb653589 --- /dev/null +++ b/app/views/video/show.scala @@ -0,0 +1,54 @@ +package views.html.video + +import lila.common.String.html.richText + +import lila.api.Context +import lila.app.templating.Environment._ +import lila.app.ui.ScalatagsTemplate._ + +import controllers.routes + +object show { + + def apply( + video: lila.video.Video, + similar: Seq[lila.video.VideoView], + control: lila.video.UserControl + )(implicit ctx: Context) = + layout( + title = s"${video.title} • Free Chess Videos", + control = control, + openGraph = lila.app.ui.OpenGraph( + title = s"${video.title} by ${video.author}", + description = shorten(~video.metadata.description, 152), + url = s"$netBaseUrl${routes.Video.show(video.id)}", + `type` = "video", + more = video.tags.map("video:tag" -> _) + ).some + ) { + div(cls := "show")( + div(cls := "embed")( + iframe(id := "ytplayer", tpe := "text/html", + src := s"https://www.youtube.com/embed/${video.id}?autoplay=1&origin=https://lichess.org&start=${video.startTime}", + st.frameborder := "0", frame.allowfullscreen) + ), + h1(cls := "box__pad")( + a(cls := "is4 text", dataIcon := "i", href := s"${routes.Video.index}?${control.queryString}"), + video.title + ), + div(cls := "meta box__pad")( + div(cls := "target")(video.targets.map(lila.video.Target.name).mkString(", ")), + a(cls := "author", href := s"${routes.Video.author(video.author)}?${control.queryString}")(video.author), + video.tags.map { tag => + a(cls := "tag", dataIcon := "o", href := s"${routes.Video.index}?tags=${tag.replace(" ", "+")}")(tag.capitalize) + }, + video.metadata.description.map { desc => + p(cls := "description")(richText(desc)) + } + ), + div(cls := "similar list box__pad")( + similar.map { bits.card(_, control) } + ) + ) + } +} diff --git a/app/views/video/show.scala.html b/app/views/video/show.scala.html deleted file mode 100644 index 5dc3e268d5..0000000000 --- a/app/views/video/show.scala.html +++ /dev/null @@ -1,37 +0,0 @@ -@(video: lila.video.Video, similar: Seq[lila.video.VideoView], control: lila.video.UserControl)(implicit ctx: Context) - -@layout( -title = s"${video.title} • Free Chess Videos", -control = control, -openGraph = lila.app.ui.OpenGraph( -title = s"${video.title} by ${video.author}", -description = shorten(~video.metadata.description, 152), -url = s"$netBaseUrl${routes.Video.show(video.id)}", -`type` = "video", -more = video.tags.map("video:tag" -> _)).some) { -
    -
    - @searchForm(control.query) - Video library -
    - -

    @video.title

    -
    -
    @video.targets.map(lila.video.Target.name).mkString(", ")
    - @video.author - @video.tags.map { tag => - @tag.capitalize - } - @video.metadata.description.map { desc => -

    @richText(desc)

    - } -
    -
    - @similar.map { vv => - @card(vv, control) - } -
    -
    -} diff --git a/app/views/video/tags.scala.html b/app/views/video/tags.scala.html deleted file mode 100644 index d1ce715577..0000000000 --- a/app/views/video/tags.scala.html +++ /dev/null @@ -1,19 +0,0 @@ -@(ts: List[lila.video.TagNb], control: lila.video.UserControl)(implicit ctx: Context) - -@layout( -title = s"Tags • Free Chess Videos", -control = control) { - -
    - -

    All @ts.size video tags

    -
    -
    - @ts.sortBy(_.tag).map { t => - - @t.tag.capitalize - @t.nb - - } -
    -} diff --git a/bin/cli-stage b/bin/cli-stage index 6fa78877cf..c50536f7b8 100755 --- a/bin/cli-stage +++ b/bin/cli-stage @@ -3,4 +3,4 @@ COMMAND=$* PASSWORD=$LILA_CLI_PASSWORD -curl -d "password=$PASSWORD&command=$COMMAND" https://listage.ovh/cli +curl -d "password=$PASSWORD&command=$COMMAND" https://lichess.dev/cli diff --git a/bin/gen/piece-sprite b/bin/gen/piece-sprite index 4885bce113..6a32a18931 100755 --- a/bin/gen/piece-sprite +++ b/bin/gen/piece-sprite @@ -42,8 +42,8 @@ themes.map { |theme| File.open(file, 'r') do|image_file| image = image_file.read base64 = Base64.strict_encode64(image) - 'body.base .is2d piece.' + role + '.' + color + ' { ' + - "background-image: url('data:image/" + types[ext] + base64 + "'); }" + '.is2d .' + role + '.' + color + ' {' + + "background-image:url('data:image/" + types[ext] + base64 + "')}" end } }.flatten diff --git a/bin/prod/deploy b/bin/prod/deploy index 55d3b971c7..7f219b6d26 100755 --- a/bin/prod/deploy +++ b/bin/prod/deploy @@ -100,7 +100,7 @@ fi if [ $FRONT_REMOTE ] && [ $FRONT_REMOTE_DIR ]; then lilalog "Deploy assets to $mode frontend server $FRONT_REMOTE:$FRONT_REMOTE_DIR" - rsync --archive --no-o --no-g --progress public $FRONT_REMOTE:$FRONT_REMOTE_DIR + rsync --archive --no-o --no-g --progress --exclude '*.dev.css' public $FRONT_REMOTE:$FRONT_REMOTE_DIR fi read -n 1 -p "Press [Enter] to complete deployment to $mode server $REMOTE:$REMOTE_DIR" diff --git a/bin/prod/deploy-assets b/bin/prod/deploy-assets index b27dbec181..30438e9647 100755 --- a/bin/prod/deploy-assets +++ b/bin/prod/deploy-assets @@ -14,9 +14,6 @@ elif [ $mode = "stage" ]; then elif [ $mode = "greco" ]; then REMOTE="greco" REMOTE_DIR="/home/lichess-deploy" -elif [ $mode = "moore" ]; then - REMOTE="moore" - REMOTE_DIR="/home/lichess-deploy" elif [ $mode = "leess" ]; then REMOTE="leess" REMOTE_DIR="/home/lichess-deploy" @@ -30,8 +27,17 @@ lilalog "Deploy assets to $mode server $REMOTE:$REMOTE_DIR" ./ui/build prod lilalog "Rsync scripts" -rsync --archive --no-o --no-g --progress public $REMOTE:$REMOTE_DIR +rsync --archive --no-o --no-g --progress --exclude '*.dev.css' public $REMOTE:$REMOTE_DIR + +SSH_COMMAND="chown -R lichess:lichess $REMOTE_DIR" +echo $SSH_COMMAND +ssh $REMOTE $SSH_COMMAND lilalog "Deploy complete" -xdg-open https://lichess.org/dev/cli +if [ $mode = "main" ]; then + xdg-open https://lichess.org/dev/cli +fi +if [ $mode = "stage" ]; then + xdg-open https://lichess.dev/dev/cli +fi diff --git a/build.sbt b/build.sbt index cfbba241fb..4f1f334719 100644 --- a/build.sbt +++ b/build.sbt @@ -3,7 +3,6 @@ import com.typesafe.sbt.SbtScalariform.autoImport.scalariformFormat import com.typesafe.sbt.web.SbtWeb.autoImport._ import play.Play.autoImport._ import play.sbt.PlayImport._ -import play.twirl.sbt.Import._ import PlayKeys._ import BuildSettings._ @@ -36,23 +35,14 @@ libraryDependencies ++= Seq( kamon.core, kamon.influxdb, scalatags, java8compat, semver, scrimage, scalaConfigs, scaffeine ) -TwirlKeys.templateImports ++= Seq( - "lila.game.{ Game, Player, Pov }", - "lila.tournament.Tournament", - "lila.user.{ User, UserContext }", - "lila.security.Permission", - "lila.app.templating.Environment._", - "lila.api.Context", - "lila.i18n.{ I18nKeys => trans }", - "lila.common.paginator.Paginator", - "lila.common.String.html._" -) resourceDirectory in Assets := (sourceDirectory in Compile).value / "assets" unmanagedResourceDirectories in Assets ++= (if (scala.sys.env.get("SERVE_ASSETS").exists(_ == "1")) Seq(baseDirectory.value / "public") else Nil) scalariformPreferences := scalariformPrefs(scalariformPreferences.value) excludeFilter in scalariformFormat := "*Routes*" +routesGenerator := LilaRoutesGenerator + lazy val modules = Seq( common, db, rating, user, security, hub, socket, message, notifyModule, i18n, game, bookmark, search, @@ -84,7 +74,7 @@ lazy val api = module("api", moduleCPDeps) lazy val puzzle = module("puzzle", Seq( common, memo, hub, history, db, user, rating, pref, tree, game )).settings( - libraryDependencies ++= provided(play.api, reactivemongo.driver) + libraryDependencies ++= provided(play.api, reactivemongo.driver, reactivemongo.iteratees) ) lazy val quote = module("quote", Seq()) @@ -140,7 +130,7 @@ lazy val perfStat = module("perfStat", Seq(common, db, user, game, rating)).sett ) lazy val history = module("history", Seq(common, db, memo, game, user)).settings( - libraryDependencies ++= provided(play.api, reactivemongo.driver) + libraryDependencies ++= provided(play.api, scalatags, reactivemongo.driver) ) lazy val db = module("db", Seq(common)).settings( @@ -238,7 +228,7 @@ lazy val insight = module( Seq(common, game, user, analyse, relation, pref, socket, round, security) ).settings( libraryDependencies ++= provided( - play.api, reactivemongo.driver, reactivemongo.iteratees + play.api, reactivemongo.driver, reactivemongo.iteratees, scalatags ) ) diff --git a/conf/base.conf b/conf/base.conf index e66420279a..39a3d6e380 100644 --- a/conf/base.conf +++ b/conf/base.conf @@ -447,7 +447,7 @@ forum { post.max_per_page = 10 recent { ttl = 1 hour - nb = 20 + nb = 12 } collection { categ = f_categ diff --git a/conf/routes b/conf/routes index ac878e95c6..8680b203fb 100644 --- a/conf/routes +++ b/conf/routes @@ -24,7 +24,7 @@ GET /tv/frame controllers.Tv.frame GET /tv/feed controllers.Tv.feed GET /tv/channels controllers.Tv.channels GET /tv/:chanKey controllers.Tv.onChannel(chanKey: String) -GET /tv/:chanKey/$gameId<\w{8}>/$color/sides controllers.Tv.sides(chanKey: String, gameId: String, color: String) +GET /tv/$gameId<\w{8}>/$color/sides controllers.Tv.sides(gameId: String, color: String) GET /games controllers.Tv.games GET /games/:chanKey controllers.Tv.gamesChannel(chanKey: String) @@ -237,6 +237,7 @@ GET /tournament/help controllers.Tournament.help(system GET /tournament/limited-invitation controllers.Tournament.limitedInvitation GET /tournament/leaderboard controllers.Tournament.leaderboard GET /tournament/shields controllers.Tournament.shields +GET /tournament/shields/:categ controllers.Tournament.categShields(categ: String) # Tournament CRUD GET /tournament/manager controllers.TournamentCrud.index(page: Int ?= 1) @@ -258,6 +259,7 @@ POST /simul/$id<\w{8}>/start controllers.Simul.start(id: String POST /simul/$id<\w{8}>/abort controllers.Simul.abort(id: String) POST /simul/$id<\w{8}>/join/:variant controllers.Simul.join(id: String, variant: String) POST /simul/$id<\w{8}>/withdraw controllers.Simul.withdraw(id: String) +POST /simul/$id<\w{8}>/set-text controllers.Simul.setText(id: String) # Team GET /team controllers.Team.home(page: Int ?= 1) @@ -298,7 +300,6 @@ GET /fishnet/key/$key<\w{8}> controllers.Fishnet.keyExists(key: GET /fishnet/status controllers.Fishnet.status # Pref -POST /pref/zoom controllers.Pref.setZoom POST /pref/:name controllers.Pref.set(name: String) GET /account/preferences/:categ controllers.Pref.form(categ: String) POST /account/preferences controllers.Pref.formApply @@ -468,6 +469,7 @@ GET /stat/rating/distribution/:perf controllers.Stat.ratingDistribution(perf: # API GET /api controllers.Api.index POST /api/users controllers.Api.usersByIds +GET /api/user/puzzle-activity controllers.Puzzle.activity GET /api/user/:name controllers.Api.user(name: String) GET /api/user/:name/activity controllers.Api.activity(name: String) GET /api/user/:name/following controllers.Relation.apiFollowing(name: String) @@ -546,7 +548,6 @@ POST /account/oauth/app/:id/edit controllers.OAuthApp.update(id: String) POST /account/oauth/app/:id/delete controllers.OAuthApp.delete(id: String) # Events -GET /event controllers.Event.index GET /event/$id<\w{8}> controllers.Event.show(id: String) GET /event/manager controllers.Event.manager GET /event/manager/$id<\w{8}> controllers.Event.edit(id: String) @@ -559,7 +560,6 @@ GET /captcha/$id<\w{8}> controllers.Main.captchaCheck(id: String) GET /developers controllers.Main.webmasters GET /mobile controllers.Main.mobile GET /lag controllers.Main.lag -GET /fpmenu controllers.Main.fpmenu GET /get-fishnet controllers.Main.getFishnet GET /costs controllers.Main.costs @@ -581,6 +581,7 @@ GET /privacy controllers.Page.privacy GET /contact controllers.Main.contact GET /about controllers.Page.about GET /faq controllers.Main.faq +GET /source controllers.Page.source GET /qa controllers.Main.legacyQa GET /qa/:id/:slug controllers.Main.legacyQaQuestion(id: Int, slug: String) GET /swag controllers.Page.swag @@ -603,4 +604,3 @@ GET /assets/$version<_\w{6}>/*file controllers.Main.versionedAsset(version: GET /assets/*file controllers.Assets.at(path = "/public", file: String) GET /robots.txt controllers.Main.robots -GET /free-js controllers.Main.freeJs diff --git a/doc/game-export.md b/doc/game-export.md deleted file mode 100644 index 729e111045..0000000000 --- a/doc/game-export.md +++ /dev/null @@ -1,50 +0,0 @@ -## Lichess games CSV export - -This is a direct export from lichess database. -Some fields are binary encoded. - -``` -nb games: > 45,000,000 -file size: 16.45GB -torrent: http://sacem.lichess.org/lichess-games-2014-11-25.csv.torrent -``` - -### Head - -```csv -_id,so,s,v,if,us,p0.ai,p0.e,p1.ai,p1.e,c,mt,w,an,ra,pg,ca -"04tbfylw",1,33,,,"[ ""miroslavm970"", ""redlightning530"" ]",,1480,,1072,0500000884000B930000000000,4665B5,true,,true,23242B55806A801C6140,2013-11-14T07:59:10.945Z -"04tbgd0m",3,31,,,,5,,,,,00060805070B0A0D0806050F0E150C1B1917141D0C0508070804080A05050F060D0608050900,true,,,1B1C52806D8022356A8076A061A040C06480DE80016A801559A0E76005C860002464846484A440646440C067403A63806384A3404BA02C5D406FA06F4C6F4453A876206FAC6F24D860056620792065A00A53A42B4C60034B609340486448640D58605F6048605960125160702052640453648D408D404D646D204960144E603D4D687620556052606920,2014-01-23T12:40:15.314Z -"04tbiq94",1,33,,,,,,,,0500003D040048DC0000000000,5564275E5B89248C6ABE7CA744D8,false,,,236D8052802453A066A06A801D3A40C01A5580020541A00C3365A05C804680748015668C66446584A58062A01C59401B,2013-04-13T04:06:27.392Z -"04tboc0g",1,33,,,"[ ""lifungkuee"" ]",,1200,,,,CC,true,,,031C22,2013-11-08T09:14:05.455Z -"04tbpis6",1,30,,,"[ ""tarn"", ""steven21ys"" ]",,1997,,1910,03020013100038E90000000000,24042424644A945A2547568758647527AB8B592647484647B85C46CA6754249BA95A678A686648544524252454245448442426442524245282454404,true,,true,1B1C132552806D806A801574A0DE800123A3406384444859A04BA06D8C6D845AA040C040C059A45984144A80564054840D4A804EA02ADF60056140D76000D860057C8064406B805644566468A0043275803B668069200350806C8061803C0A02D06000DE6002335B845B845B645B645B6462202461A02D1494405464B380B3405D60446057A0426465A04560456445A473A40B5EA00C6E200D55A00E4EA44EA46520035D2004562045A04F203C46204CA04E20632046206C204E207520462076242C3D2B3E23BF022A6F404E206648472055A84F204E50,2013-09-18T14:35:55.887Z -"04tbr8kr",1,35,2,"brqbknnr/pppppppp/8/8/8/8/PPPPPPPP/BRQBKNNR w KQkq - 0 1",,,,,,01020017C60003410000000000,44B846B6B5B5A5,false,,,1B0D1214229B409B404E402A454061A04144598044400B7440,2013-05-24T22:17:22.218Z -"04tbx6qs",1,35,,,,,,,,0508006A6900757B0000000000,86652C499B27A897D5FFCAC7EB7ADFDEBAEBEDEF7BA6CACD,true,,,22251B1C5AA06D806A801440C0558064806484A4405E80528064844CA85EA07C405580231B43800574A05640138C408C804B80025A800B43649440548458404CA441605DA059A079AC78205DA06A4068A4724072A47020,2013-11-25T22:53:22.255Z -"04tbxm1g",,30,,,,,,,,03088037A480351B0000000000,5B7A7787585BC75C58DD5C9B7DDDDA,false,,,23241A6D806A805DA05280558061A073803A6D8040C054A05C803D6D8CAD801377600A5BA04860664049A054A05040654042A07A4458607154,2013-02-18T00:55:23.182Z -"04tbxm9c",2,30,,,,,,,,05050006E5001A580000000000,0A575553294844C8AC8C6A588549574686A846CB543449A886CD,false,,,1B6D801335528076A02340C02B1D6A80149480948051405580025B805B849B405C805E805AA0548040C05A845A44254B800D244EA051802DE06005A480A4806C605B445B4C5B846464646464A46584676074805BA8682045A06BA053B4,2013-12-20T20:24:02.620Z -``` - -### Fields - -|key|name|default|description| -|---|----|-------|-----------| -|_id|unique ID|N/A|Append this ID to http://lichess.org/ to get the game URL| -|so|source|1|How the game was created. Values on https://github.com/ornicar/lila/blob/explore/modules/game/src/main/Source.scala| -|s|status|N/A|Current status of the game. Values on https://github.com/ornicar/scalachess/blob/master/src/main/scala/Status.scala| -|v|variant|1|Chess variant in use. Values on https://github.com/ornicar/scalachess/blob/master/src/main/scala/Variant.scala| -|if|initial FEN|*1|Starting position of the game, in case of chess960 or game from a position| -|us|user IDs|[,]|User IDs of both players. If empty, both are anon. If only one element, black is anon. If first element is empty, white is anon. AI is treated as anon: see p0.ai & p1.ai fields| -|p0.ai|white AI level|-|AI level of white player. 1 to 8. Only set if white player is an AI| -|p0.e|white rating|-|Rating of white player. Empty if white is anon or AI| -|p1.ai|black AI level|-|AI level of black player. 1 to 8. Only set if black player is an AI| -|p2.e|black rating|-|Rating of black player. Empty if black is anon or AI| -|c|clock|-|Chess clock configuration, binary encoded. Empty if unlimited game. See https://github.com/ornicar/lila/blob/master/modules/game/src/main/BinaryFormat.scala#L58| -|mt|move times|N/A|Approximated move times, binary encoded. See https://github.com/ornicar/lila/blob/master/modules/game/src/main/BinaryFormat.scala#L25| -|w|winner color|-|Color of the winner player. true = white, false = black, none = no winner| -|an|analysed|false|Tells if an analysis is available for this game| -|ra|rated|false|Tells if the game is rated| -|pg|binary moves|N/A|PGN moves, binary encoded| -|ca|creation date|N/A|Date of creation of the game| - - -> *1 rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 diff --git a/modules/api/src/main/Cli.scala b/modules/api/src/main/Cli.scala index 0b26da81c7..b6a39c94c4 100644 --- a/modules/api/src/main/Cli.scala +++ b/modules/api/src/main/Cli.scala @@ -15,7 +15,7 @@ private[api] final class Cli(bus: lila.common.Bus) extends lila.common.Cli { } def process = { - case "uptime" :: Nil => fuccess(lila.common.PlayApp.uptime.toStandardSeconds.getSeconds.toString) + case "uptime" :: Nil => fuccess(s"${lila.common.PlayApp.uptimeSeconds} seconds") case "deploy" :: "pre" :: Nil => remindDeploy(lila.hub.actorApi.DeployPre) case "deploy" :: "post" :: Nil => remindDeploy(lila.hub.actorApi.DeployPost) case "change" :: ("asset" | "assets") :: "version" :: Nil => @@ -23,16 +23,17 @@ private[api] final class Cli(bus: lila.common.Bus) extends lila.common.Cli { AssetVersion.change fuccess(s"Changed to ${AssetVersion.current}") case "gdpr" :: "erase" :: username :: "forever" :: Nil => - lila.user.UserRepo named username flatMap { - case None => fuccess("No such user.") - case Some(user) if user.enabled => fuccess("That user account is not closed. Can't erase.") - case Some(user) => lila.user.UserRepo.email(user.id) map { - case Some(email) if email.value.toLowerCase == s"${user.id}@erase.forever" => - bus.publish(lila.user.User.GDPRErase(user), 'gdprErase) - s"Erasing all data about ${user.username} now" - case _ => s"The user email must be set to @erase.forever for erasing to start." - } + lila.user.UserRepo named username map { + case None => "No such user." + case Some(user) if user.enabled => "That user account is not closed. Can't erase." + case Some(user) => + bus.publish(lila.user.User.GDPRErase(user), 'gdprErase) + s"Erasing all data about ${user.username} now" } + case "announce" :: msgWords => + val msg = msgWords mkString " " + bus.publish(lila.hub.actorApi.Announce(msg), 'announce) + fuccess(s"Announcing: $msg") } private def remindDeploy(event: Deploy): Fu[String] = { diff --git a/modules/api/src/main/Context.scala b/modules/api/src/main/Context.scala index 0762819616..f54220f4cc 100644 --- a/modules/api/src/main/Context.scala +++ b/modules/api/src/main/Context.scala @@ -76,7 +76,9 @@ sealed trait Context extends lila.user.UserContextWrapper { def requiresFingerprint = isAuth && !pageData.hasFingerprint - def zoom: Option[Int] = req.session get "zoom" flatMap parseIntOption filter (100<) + def zoom: Option[Int] = req.session get "zoom" flatMap parseIntOption filter (100<=) + + def respZoom = zoom.fold(85)(_ - 100) } sealed abstract class BaseContext( diff --git a/modules/api/src/main/KamonPusher.scala b/modules/api/src/main/KamonPusher.scala index 78e127e9ca..e4a87b5376 100644 --- a/modules/api/src/main/KamonPusher.scala +++ b/modules/api/src/main/KamonPusher.scala @@ -34,7 +34,7 @@ private final class KamonPusher( case Tick => lila.mon.jvm.thread(threadStats.getThreadCount) lila.mon.jvm.daemon(threadStats.getDaemonThreadCount) - lila.mon.jvm.uptime(app.uptime.toStandardSeconds.getSeconds) + lila.mon.jvm.uptime(app.uptimeSeconds) lila.mon.user.online(countUsers()) scheduleTick } diff --git a/modules/api/src/main/RoundApi.scala b/modules/api/src/main/RoundApi.scala index 87d086f9f8..a2792a9967 100644 --- a/modules/api/src/main/RoundApi.scala +++ b/modules/api/src/main/RoundApi.scala @@ -90,6 +90,21 @@ private[api] final class RoundApi( } }.mon(_.round.api.watcher) + def embed(pov: Pov, apiVersion: ApiVersion, + analysis: Option[Analysis] = None, + initialFenO: Option[Option[FEN]] = None, + withFlags: WithFlags): Fu[JsObject] = + initialFenO.fold(GameRepo initialFen pov.game)(fuccess).flatMap { initialFen => + jsonView.watcherJson(pov, Pref.default, apiVersion, none, none, + initialFen = initialFen, + withFlags = withFlags) map { json => + ( + withTree(pov, analysis, initialFen, withFlags)_ compose + withAnalysis(pov.game, analysis)_ + )(json) + } + }.mon(_.round.api.embed) + def userAnalysisJson(pov: Pov, pref: Pref, initialFen: Option[FEN], orientation: chess.Color, owner: Boolean, me: Option[User]) = owner.??(forecastApi loadForDisplay pov).map { fco => withForecast(pov, owner, fco) { diff --git a/modules/challenge/src/main/Challenge.scala b/modules/challenge/src/main/Challenge.scala index ed9811270f..8698329f22 100644 --- a/modules/challenge/src/main/Challenge.scala +++ b/modules/challenge/src/main/Challenge.scala @@ -1,7 +1,7 @@ package lila.challenge import chess.format.FEN -import chess.variant.{ Variant, FromPosition } +import chess.variant.{ Variant, FromPosition, Horde, Chess960, RacingKings, KingOfTheHill } import chess.{ Mode, Speed } import org.joda.time.DateTime @@ -62,6 +62,11 @@ case class Challenge( def speed = speedOf(timeControl) + def notableInitialFen: Option[FEN] = variant match { + case FromPosition | Horde | RacingKings => initialFen + case _ => none + } + lazy val perfType = perfTypeOf(variant, timeControl) } diff --git a/modules/chat/src/main/Line.scala b/modules/chat/src/main/Line.scala index 5d9a836fbf..b1d53184ac 100644 --- a/modules/chat/src/main/Line.scala +++ b/modules/chat/src/main/Line.scala @@ -57,13 +57,14 @@ object Line { } private val UserLineRegex = """(?s)([\w-~]{2,}+)([ !?])(.++)""".r - def strToUserLine(str: String): Option[UserLine] = str match { - case UserLineRegex(username, " ", text) => username split titleSep match { - case Array(title, name) => UserLine(name, Some(title), text, troll = false, deleted = false).some - case _ => UserLine(username, None, text, troll = false, deleted = false).some - } - case UserLineRegex(username, "!", text) => UserLine(username, None, text, troll = true, deleted = false).some - case UserLineRegex(username, "?", text) => UserLine(username, None, text, troll = false, deleted = true).some + private def strToUserLine(str: String): Option[UserLine] = str match { + case UserLineRegex(username, sep, text) => + val troll = sep == "!" + val deleted = sep == "?" + username split titleSep match { + case Array(title, name) => UserLine(name, Some(title), text, troll = troll, deleted = deleted).some + case _ => UserLine(username, None, text, troll = troll, deleted = deleted).some + } case _ => none } def userLineToStr(x: UserLine): String = { diff --git a/modules/common/src/main/Form.scala b/modules/common/src/main/Form.scala index e07b6166f4..5ce5ce9e1d 100644 --- a/modules/common/src/main/Form.scala +++ b/modules/common/src/main/Form.scala @@ -91,12 +91,18 @@ object Form { val utcDate = jodaDate(dateTimePattern, DateTimeZone.UTC) implicit val dateTimeFormat = jodaDateTimeFormat(dateTimePattern) } - object ISODate { + object ISODateTime { val dateTimePattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" val formatter = jodaDateTimeFormat(dateTimePattern, DateTimeZone.UTC) - val isoDate = jodaDate(dateTimePattern, DateTimeZone.UTC) + val isoDateTime = jodaDate(dateTimePattern, DateTimeZone.UTC) implicit val dateTimeFormat = jodaDateTimeFormat(dateTimePattern) } + object ISODate { + val datePattern = "yyyy-MM-dd" + val formatter = jodaDateTimeFormat(datePattern, DateTimeZone.UTC) + val isoDateTime = jodaDate(datePattern, DateTimeZone.UTC) + implicit val dateFormat = jodaDateTimeFormat(datePattern) + } object Timestamp { import lila.base.PimpedTry val formatter = new Formatter[org.joda.time.DateTime] { diff --git a/modules/common/src/main/HTTPRequest.scala b/modules/common/src/main/HTTPRequest.scala index f42027bf39..927a0f72da 100644 --- a/modules/common/src/main/HTTPRequest.scala +++ b/modules/common/src/main/HTTPRequest.scala @@ -28,7 +28,6 @@ object HTTPRequest { val isMobile = UaMatcher("""(?i)iphone|ipad|ipod|android.+mobile""") private def uaContains(req: RequestHeader, str: String) = userAgent(req).exists(_ contains str) - def isTrident(req: RequestHeader) = uaContains(req, "Trident/") def isChrome(req: RequestHeader) = uaContains(req, "Chrome/") def origin(req: RequestHeader): Option[String] = req.headers get HeaderNames.ORIGIN diff --git a/modules/common/src/main/Lilaisms.scala b/modules/common/src/main/Lilaisms.scala index 6616dc50b1..45884d5a67 100644 --- a/modules/common/src/main/Lilaisms.scala +++ b/modules/common/src/main/Lilaisms.scala @@ -36,6 +36,8 @@ trait Lilaisms with scalaz.syntax.ToTraverseOps with scalaz.syntax.ToValidationOps { + type StringValue = lila.base.LilaTypes.StringValue + @inline implicit def toPimpedFuture[A](f: Fu[A]) = new PimpedFuture(f) @inline implicit def toPimpedFutureBoolean(f: Fu[Boolean]) = new PimpedFutureBoolean(f) @inline implicit def toPimpedFutureOption[A](f: Fu[Option[A]]) = new PimpedFutureOption(f) @@ -68,7 +70,6 @@ trait Lilaisms @inline implicit def toPimpedFiniteDuration(d: FiniteDuration) = new PimpedFiniteDuration(d) @inline implicit def toPimpedActorSystem(a: akka.actor.ActorSystem) = new PimpedActorSystem(a) - } final class PimpedActorSystem(private val a: akka.actor.ActorSystem) extends AnyVal { diff --git a/modules/common/src/main/PlayApp.scala b/modules/common/src/main/PlayApp.scala index ced6eb93f0..92fda80d81 100644 --- a/modules/common/src/main/PlayApp.scala +++ b/modules/common/src/main/PlayApp.scala @@ -10,7 +10,7 @@ object PlayApp { val startedAt = DateTime.now val startedAtMillis = nowMillis - def uptime = new Period(startedAt, DateTime.now) + def uptimeSeconds = nowSeconds - startedAt.getSeconds def startedSinceMinutes(minutes: Int) = startedSinceSeconds(minutes * 60) diff --git a/modules/common/src/main/String.scala b/modules/common/src/main/String.scala index 36e95a4e10..9db5e02927 100644 --- a/modules/common/src/main/String.scala +++ b/modules/common/src/main/String.scala @@ -2,17 +2,13 @@ package lila.common import java.text.Normalizer import play.api.libs.json._ -import play.twirl.api.Html -import scalatags.Text.RawFrag +import scalatags.Text.all._ import lila.base.RawHtml -import lila.common.base.StringUtils.{ safeJsonString, escapeHtml => escapeHtmlRaw } +import lila.common.base.StringUtils.{ safeJsonString, escapeHtmlRaw } final object String { - val erased = "" - val erasedHtml = Html("<deleted>") - private[this] val slugR = """[^\w-]""".r private[this] val slugMultiDashRegex = """-{2,}""".r @@ -53,22 +49,22 @@ final object String { val atUsernameRegex = RawHtml.atUsernameRegex object html { - def richText(rawText: String, nl2br: Boolean = true) = Html { + def richText(rawText: String, nl2br: Boolean = true): Frag = raw { val withLinks = RawHtml.addLinks(rawText) if (nl2br) RawHtml.nl2br(withLinks) else withLinks } - def nl2brUnsafe(text: String) = Html { - RawHtml.nl2br(text) + def nl2brUnsafe(text: String): Frag = raw { + RawHtml nl2br text } - def nl2br(text: String): Html = nl2brUnsafe(escapeHtmlRaw(text)) + def nl2br(text: String): Frag = nl2brUnsafe(escapeHtmlRaw(text)) - def escapeHtml(s: String) = Html { + def escapeHtml(s: String): RawFrag = raw { escapeHtmlRaw(s) } - def markdownLinks(text: String) = Html { + def markdownLinks(text: String): Frag = raw { RawHtml.markdownLinks(text) } @@ -88,14 +84,5 @@ final object String { } } } - - def safeJsonHtml(jsValue: JsValue) = Html(safeJsonValue(jsValue)) } - - object frag { - def escapeHtml(s: String) = RawFrag { - escapeHtmlRaw(s) - } - } - } diff --git a/modules/common/src/main/base/LilaTypes.scala b/modules/common/src/main/base/LilaTypes.scala index 08e1e4f38a..91e8414e80 100644 --- a/modules/common/src/main/base/LilaTypes.scala +++ b/modules/common/src/main/base/LilaTypes.scala @@ -9,10 +9,6 @@ import play.api.libs.json.{ JsObject, JsError } trait LilaTypes extends ValidTypes { - trait StringValue extends Any { - def value: String - override def toString = value - } trait IntValue extends Any { def value: Int override def toString = value.toString @@ -51,4 +47,10 @@ trait LilaTypes extends ValidTypes { implicit val dateTimeOrdering: Ordering[DateTime] = Ordering.fromLessThan(_ isBefore _) } -object LilaTypes extends LilaTypes +object LilaTypes extends LilaTypes { + + trait StringValue extends Any { + def value: String + override def toString = value + } +} diff --git a/modules/common/src/main/base/RawHtml.scala b/modules/common/src/main/base/RawHtml.scala index b0c73df04e..8383746377 100644 --- a/modules/common/src/main/base/RawHtml.scala +++ b/modules/common/src/main/base/RawHtml.scala @@ -4,7 +4,7 @@ import scala.annotation.{ tailrec, switch } import java.lang.{ StringBuilder => jStringBuilder, Math } import java.lang.Character.isLetterOrDigit -import lila.common.base.StringUtils.escapeHtml +import lila.common.base.StringUtils.escapeHtmlRaw final object RawHtml { @inline implicit def toPimpedChars(i: Iterable[CharSequence]) = new PimpedChars(i) @@ -71,7 +71,7 @@ final object RawHtml { expandAtUser(text) map { expanded => val m = urlPattern.matcher(expanded) - if (!m.find) escapeHtml(expanded) // preserve fast case! + if (!m.find) escapeHtmlRaw(expanded) // preserve fast case! else { val sb = new jStringBuilder(expanded.length + 200) val sArr = expanded.toCharArray @@ -79,7 +79,7 @@ final object RawHtml { do { val start = m.start - escapeHtml(sb, sArr, lastAppendIdx, start) + escapeHtmlRaw(sb, sArr, lastAppendIdx, start) val domainS = Math.max(m.start(1), start) val pathS = m.start(2) @@ -104,7 +104,7 @@ final object RawHtml { csb.append(sArr, pathS, end - pathS) } - val allButScheme = escapeHtml(csb.toString) + val allButScheme = escapeHtmlRaw(csb.toString) if (isTldInternal) { sb.append(s"""$1""") + markdownLinkRegex.replaceAllIn(escapeHtmlRaw(text), """$1""") } } diff --git a/modules/common/src/main/java/StringUtils.java b/modules/common/src/main/java/StringUtils.java index 2eb6d18d83..6fd820a826 100644 --- a/modules/common/src/main/java/StringUtils.java +++ b/modules/common/src/main/java/StringUtils.java @@ -17,11 +17,11 @@ public class StringUtils { if (c >= ' ' && c <= '~') switch(c) { case '<': case '>': case '&': case '"': case '\'': case '\\': case '`': - break; // cur char is bad, escape it + break; // cur char is bad, escape it default: - continue; // char is OK, continue scan. + continue; // char is ok, continue scan } - // this code runs when char is either out of alphanumeric range OR + // This code runs when char is either out of alphanumeric range OR // char is restricted. if (sb == null) { sb = new StringBuilder(c <= '~' ? len + 22 : len * 6 + 2); @@ -42,21 +42,21 @@ public class StringUtils { return sb.toString(); } - public static String escapeHtml(final String s) { + public static String escapeHtmlRaw(final String s) { final char[] sArr = s.toCharArray(); for (int i = 0, end = sArr.length; i < end; i++) { switch (sArr[i]) { case '<': case '>': case '&': case '"': case '\'': final StringBuilder sb = new StringBuilder(end + 20); sb.append(s, 0, i); - escapeHtml(sb, sArr, i, end); + escapeHtmlRaw(sb, sArr, i, end); return sb.toString(); } } return s; } - public static void escapeHtml(final StringBuilder sb, final char[] sArr, + public static void escapeHtmlRaw(final StringBuilder sb, final char[] sArr, int start, final int end) { for (int i = start; i < end; i++) { diff --git a/modules/common/src/main/model.scala b/modules/common/src/main/model.scala index 2d18b00217..4088e3aa71 100644 --- a/modules/common/src/main/model.scala +++ b/modules/common/src/main/model.scala @@ -63,6 +63,9 @@ case class EmailAddress(value: String) extends AnyVal with StringValue { case Array(_, domain) => Domain(domain.toLowerCase).some case _ => none } + + // safer logs + override def toString = "EmailAddress(****)" } object EmailAddress { diff --git a/modules/common/src/main/mon.scala b/modules/common/src/main/mon.scala index 96980b7999..e2609fa9b7 100644 --- a/modules/common/src/main/mon.scala +++ b/modules/common/src/main/mon.scala @@ -180,6 +180,7 @@ object mon { object api { val player = rec("round.api.player") val watcher = rec("round.api.watcher") + val embed = rec("round.api.embed") } object actor { val count = rec("round.actor.count") diff --git a/modules/common/src/test/RawHtmlTest.scala b/modules/common/src/test/RawHtmlTest.scala index fc682ac467..8e43cb4e94 100644 --- a/modules/common/src/test/RawHtmlTest.scala +++ b/modules/common/src/test/RawHtmlTest.scala @@ -1,7 +1,7 @@ package lila.base import org.specs2.mutable.Specification -import play.twirl.api.Html +// import scalatags.Text.all._ import RawHtml._ diff --git a/modules/common/src/test/StringTest.scala b/modules/common/src/test/StringTest.scala index d93904ebad..9c04c4628e 100644 --- a/modules/common/src/test/StringTest.scala +++ b/modules/common/src/test/StringTest.scala @@ -1,8 +1,8 @@ package lila.common -import org.specs2.mutable.Specification +import scalatags.Text.all._ -import play.twirl.api.Html +import org.specs2.mutable.Specification class StringTest extends Specification { @@ -16,15 +16,15 @@ class StringTest extends Specification { "richText" should { "handle nl" in { val url = "http://imgur.com/gallery/pMtTE" - String.html.richText(s"link to $url here\n") must_== Html { + String.html.richText(s"link to $url here\n") must_== raw { s"""link to $url here
    """ } - String.html.richText(s"link\n", false) must_== Html("link\n") + String.html.richText(s"link\n", false) must_== raw("link\n") } "escape chars" in { - String.html.richText(s"&") must_== Html("&") + String.html.richText(s"&") must_== raw("&") } } diff --git a/modules/db/src/main/CollExt.scala b/modules/db/src/main/CollExt.scala index 86ecdfbe95..5ec213f99a 100644 --- a/modules/db/src/main/CollExt.scala +++ b/modules/db/src/main/CollExt.scala @@ -114,6 +114,21 @@ trait CollExt { self: dsl with QueryBuilderExt => _ flatMap { _.getAs[V](field) } } + def primitiveMap[I: BSONValueReader: BSONValueWriter, V]( + ids: Iterable[I], + field: String, + fieldExtractor: Bdoc => Option[V] + ): Fu[Map[I, V]] = + coll.find($inIds(ids), $doc(field -> true)) + .list[Bdoc]() + .dmap { + _ flatMap { obj => + obj.getAs[I]("_id") flatMap { id => + fieldExtractor(obj) map { id -> _ } + } + } toMap + } + def updateField[V: BSONValueWriter](selector: Bdoc, field: String, value: V) = coll.update(selector, $set(field -> value)) diff --git a/modules/event/src/main/EventApi.scala b/modules/event/src/main/EventApi.scala index cd84d2cf51..719c49405c 100644 --- a/modules/event/src/main/EventApi.scala +++ b/modules/event/src/main/EventApi.scala @@ -38,11 +38,6 @@ final class EventApi( def list = coll.find($empty).sort($doc("startsAt" -> -1)).list[Event](50) - def recentEnabled = coll - .find($doc("enabled" -> true)) - .sort($doc("startsAt" -> -1)) - .list[Event](50) - def oneEnabled(id: String) = coll.byId[Event](id).map(_.filter(_.enabled)) def one(id: String) = coll.byId[Event](id) diff --git a/modules/forum/src/main/MentionNotifier.scala b/modules/forum/src/main/MentionNotifier.scala index 830c481462..459739cf69 100644 --- a/modules/forum/src/main/MentionNotifier.scala +++ b/modules/forum/src/main/MentionNotifier.scala @@ -50,7 +50,7 @@ final class MentionNotifier(notifyApi: NotifyApi, relationApi: RelationApi) { } private def extractMentionedUsers(post: Post): Set[User.ID] = - (post.text.indexOf('@') >= 0) ?? { + (post.text.contains('@')) ?? { val m = lila.common.String.atUsernameRegex.findAllMatchIn(post.text) (post.author foldLeft m.map(_ group 1).toSet) { _ - _ } } diff --git a/modules/forum/src/main/Post.scala b/modules/forum/src/main/Post.scala index f04fd6dc31..96f4d1b409 100644 --- a/modules/forum/src/main/Post.scala +++ b/modules/forum/src/main/Post.scala @@ -33,7 +33,7 @@ case class Post( def showAuthor = (author map (_.trim) filter ("" !=)) | User.anonymous - def showUserIdOrAuthor = if (erased) lila.common.String.erased else userId | showAuthor + def showUserIdOrAuthor = if (erased) "" else userId | showAuthor def isTeam = categId startsWith teamSlug("") diff --git a/modules/game/src/main/Crosstable.scala b/modules/game/src/main/Crosstable.scala index 351c666b48..2f269eda33 100644 --- a/modules/game/src/main/Crosstable.scala +++ b/modules/game/src/main/Crosstable.scala @@ -18,7 +18,7 @@ case class Crosstable( lazy val size = results.size - def fill = (1 to Crosstable.maxGames - size) + def fillSize = Crosstable.maxGames - size } object Crosstable { diff --git a/modules/game/src/main/Namer.scala b/modules/game/src/main/Namer.scala index 06de7aff42..dbd2fd7bcf 100644 --- a/modules/game/src/main/Namer.scala +++ b/modules/game/src/main/Namer.scala @@ -1,26 +1,10 @@ package lila.game import lila.common.LightUser -import lila.user.{ User, Title } -import play.twirl.api.Html +import lila.user.User object Namer { - def players(game: Game, withRatings: Boolean = true)(implicit lightUser: LightUser.GetterSync): (Html, Html) = - player(game.firstPlayer, withRatings) -> player(game.secondPlayer, withRatings) - - def player(p: Player, withRating: Boolean = true, withTitle: Boolean = true)(implicit lightUser: LightUser.GetterSync) = Html { - p.aiLevel.fold( - p.userId.flatMap(lightUser).fold(lila.user.User.anonymous) { user => - val title = withTitle ?? user.title ?? { t => - s"""$t """ - } - if (withRating) s"$title${user.name} (${ratingString(p)})" - else s"$title${user.name}" - } - ) { level => s"A.I. level $level" } - } - def playerText(player: Player, withRating: Boolean = false)(implicit lightUser: LightUser.GetterSync): String = player.aiLevel.fold( player.userId.flatMap(lightUser).fold(player.name | "Anon.") { u => @@ -31,7 +15,7 @@ object Namer { def gameVsText(game: Game, withRatings: Boolean = false)(implicit lightUser: LightUser.GetterSync): String = s"${playerText(game.whitePlayer, withRatings)} - ${playerText(game.blackPlayer, withRatings)}" - private def ratingString(p: Player) = p.rating match { + def ratingString(p: Player) = p.rating match { case Some(rating) => s"$rating${if (p.provisional) "?" else ""}" case _ => "?" } diff --git a/modules/gameSearch/src/main/DataForm.scala b/modules/gameSearch/src/main/DataForm.scala index 8f63b929d5..c77dfc14f6 100644 --- a/modules/gameSearch/src/main/DataForm.scala +++ b/modules/gameSearch/src/main/DataForm.scala @@ -103,7 +103,6 @@ private[gameSearch] case class SearchData( ) def nonEmptyQuery = Some(query).filter(_.nonEmpty) - } private[gameSearch] case class SearchPlayer( diff --git a/modules/hub/src/main/actorApi.scala b/modules/hub/src/main/actorApi.scala index e80bdcc57d..695e8da409 100644 --- a/modules/hub/src/main/actorApi.scala +++ b/modules/hub/src/main/actorApi.scala @@ -12,6 +12,9 @@ case object DeployPost extends Deploy("deployPost") case object Shutdown // on actor system termination +// announce something to all clients +case class Announce(msg: String) + package streamer { case class StreamsOnAir(html: String) case class StreamStart(userId: String) diff --git a/modules/i18n/src/main/I18nKey.scala b/modules/i18n/src/main/I18nKey.scala index b8156083da..76d74e028a 100644 --- a/modules/i18n/src/main/I18nKey.scala +++ b/modules/i18n/src/main/I18nKey.scala @@ -1,6 +1,5 @@ package lila.i18n -import play.twirl.api.Html import scalatags.Text.RawFrag import lila.common.Lang @@ -9,26 +8,18 @@ sealed trait I18nKey { val key: String - def literalHtmlTo(lang: Lang, args: Seq[Any] = Seq.empty): Html - def pluralHtmlTo(lang: Lang, count: Count, args: Seq[Any] = Nil): Html - - def literalFragTo(lang: Lang, args: Seq[Any] = Seq.empty): RawFrag - def pluralFragTo(lang: Lang, count: Count, args: Seq[Any] = Nil): RawFrag + def literalTo(lang: Lang, args: Seq[Any] = Seq.empty): RawFrag + def pluralTo(lang: Lang, count: Count, args: Seq[Any] = Nil): RawFrag def literalTxtTo(lang: Lang, args: Seq[Any] = Seq.empty): String def pluralTxtTo(lang: Lang, count: Count, args: Seq[Any] = Nil): String /* Implicit context convenience functions */ - // html - def apply(args: Any*)(implicit lang: Lang): Html = literalHtmlTo(lang, args) - def plural(count: Count, args: Any*)(implicit lang: Lang): Html = pluralHtmlTo(lang, count, args) - def pluralSame(count: Int)(implicit lang: Lang): Html = plural(count, count) - // frag - def frag(args: Any*)(implicit lang: Lang): RawFrag = literalFragTo(lang, args) - def pluralFrag(count: Count, args: Any*)(implicit lang: Lang): RawFrag = pluralFragTo(lang, count, args) - def pluralSameFrag(count: Int)(implicit lang: Lang): RawFrag = pluralFrag(count, count) + def apply(args: Any*)(implicit lang: Lang): RawFrag = literalTo(lang, args) + def plural(count: Count, args: Any*)(implicit lang: Lang): RawFrag = pluralTo(lang, count, args) + def pluralSame(count: Int)(implicit lang: Lang): RawFrag = plural(count, count) // txt def txt(args: Any*)(implicit lang: Lang): String = literalTxtTo(lang, args) @@ -38,16 +29,10 @@ sealed trait I18nKey { final class Translated(val key: String, val db: I18nDb.Ref) extends I18nKey { - def literalHtmlTo(lang: Lang, args: Seq[Any] = Nil): Html = - Translator.html.literal(key, db, args, lang) - - def pluralHtmlTo(lang: Lang, count: Count, args: Seq[Any] = Nil): Html = - Translator.html.plural(key, db, count, args, lang) - - def literalFragTo(lang: Lang, args: Seq[Any] = Nil): RawFrag = + def literalTo(lang: Lang, args: Seq[Any] = Nil): RawFrag = Translator.frag.literal(key, db, args, lang) - def pluralFragTo(lang: Lang, count: Count, args: Seq[Any] = Nil): RawFrag = + def pluralTo(lang: Lang, count: Count, args: Seq[Any] = Nil): RawFrag = Translator.frag.plural(key, db, count, args, lang) def literalTxtTo(lang: Lang, args: Seq[Any] = Nil): String = @@ -59,11 +44,8 @@ final class Translated(val key: String, val db: I18nDb.Ref) extends I18nKey { final class Untranslated(val key: String) extends I18nKey { - def literalHtmlTo(lang: Lang, args: Seq[Any]) = Html(key) - def pluralHtmlTo(lang: Lang, count: Count, args: Seq[Any]) = Html(key) - - def literalFragTo(lang: Lang, args: Seq[Any]) = RawFrag(key) - def pluralFragTo(lang: Lang, count: Count, args: Seq[Any]) = RawFrag(key) + def literalTo(lang: Lang, args: Seq[Any]) = RawFrag(key) + def pluralTo(lang: Lang, count: Count, args: Seq[Any]) = RawFrag(key) def literalTxtTo(lang: Lang, args: Seq[Any]) = key def pluralTxtTo(lang: Lang, count: Count, args: Seq[Any]) = key diff --git a/modules/i18n/src/main/I18nKeys.scala b/modules/i18n/src/main/I18nKeys.scala index 5993ff655d..eef3eabe8f 100644 --- a/modules/i18n/src/main/I18nKeys.scala +++ b/modules/i18n/src/main/I18nKeys.scala @@ -121,7 +121,6 @@ val `currentGames` = new Translated("currentGames", Site) val `viewInFullSize` = new Translated("viewInFullSize", Site) val `logOut` = new Translated("logOut", Site) val `signIn` = new Translated("signIn", Site) -val `newToLichess` = new Translated("newToLichess", Site) val `youNeedAnAccountToDoThat` = new Translated("youNeedAnAccountToDoThat", Site) val `signUp` = new Translated("signUp", Site) val `computersAreNotAllowedToPlay` = new Translated("computersAreNotAllowedToPlay", Site) @@ -147,7 +146,6 @@ val `changeUsername` = new Translated("changeUsername", Site) val `changeUsernameNotSame` = new Translated("changeUsernameNotSame", Site) val `changeUsernameDescription` = new Translated("changeUsernameDescription", Site) val `password` = new Translated("password", Site) -val `haveAnAccount` = new Translated("haveAnAccount", Site) val `changePassword` = new Translated("changePassword", Site) val `changeEmail` = new Translated("changeEmail", Site) val `email` = new Translated("email", Site) diff --git a/modules/i18n/src/main/TimeagoLocales.scala b/modules/i18n/src/main/TimeagoLocales.scala index d0dd670b11..29f1e9b19c 100644 --- a/modules/i18n/src/main/TimeagoLocales.scala +++ b/modules/i18n/src/main/TimeagoLocales.scala @@ -5,88 +5,47 @@ package lila.i18n object TimeagoLocales { val js: Map[String, String] = Map( - "ar" -> """(function(){lichess.timeagoLocale=function(s,e){if(0===e)return["منذ لحظات","بعد لحظات"];var t=formatTime(Math.floor(e/2),s);return["منذ "+t,"بعد "+t]};var timeTypes=[["ثانية","ثانيتين","%s ثوان","%s ثانية"],["دقيقة","دقيقتين","%s دقائق","%s دقيقة"],["ساعة","ساعتين","%s ساعات","%s ساعة"],["يوم","يومين","%s أيام","%s يوماً"],["أسبوع","أسبوعين","%s أسابيع","%s أسبوعاً"],["شهر","شهرين","%s أشهر","%s شهراً"],["عام","عامين","%s أعوام","%s عاماً"]];function formatTime(s,e){return e<3?timeTypes[s][e-1]:3<=e&&e<=10?timeTypes[s][2]:timeTypes[s][3]} -})()""", - "be" -> """(function(){var seconds=formatNum.bind(null,"секунду","%s секунду","%s секунды","%s секунд"),minutes=formatNum.bind(null,"хвіліну","%s хвіліну","%s хвіліны","%s хвілін"),hours=formatNum.bind(null,"гадзіну","%s гадзіну","%s гадзіны","%s гадзін"),days=formatNum.bind(null,"дзень","%s дзень","%s дні","%s дзён"),weeks=formatNum.bind(null,"тыдзень","%s тыдзень","%s тыдні","%s тыдняў"),months=formatNum.bind(null,"месяц","%s месяц","%s месяцы","%s месяцаў"),years=formatNum.bind(null,"год","%s год","%s гады","%s гадоў");function formatNum(s,e,n,r,u){var a=u%10,t=r;return 1===u?t=s:1===a&&20 """(function(){lichess.timeagoLocale=function(s,e){return[["току що","съвсем скоро"],["преди %s секунди","след %s секунди"],["преди 1 минута","след 1 минута"],["преди %s минути","след %s минути"],["преди 1 час","след 1 час"],["преди %s часа","след %s часа"],["преди 1 ден","след 1 ден"],["преди %s дни","след %s дни"],["преди 1 седмица","след 1 седмица"],["преди %s седмици","след %s седмици"],["преди 1 месец","след 1 месец"],["преди %s месеца","след %s месеца"],["преди 1 година","след 1 година"],["преди %s години","след %s години"]][e]}; -})()""", - "bn_IN" -> """(function(){lichess.timeagoLocale=function(s,e){return[["এইমাত্র","একটা সময়"],["%s সেকেন্ড আগে","%s এর সেকেন্ডের মধ্যে"],["1 মিনিট আগে","1 মিনিটে"],["%s এর মিনিট আগে","%s এর মিনিটের মধ্যে"],["1 ঘন্টা আগে","1 ঘন্টা"],["%s ঘণ্টা আগে","%s এর ঘন্টার মধ্যে"],["1 দিন আগে","1 দিনের মধ্যে"],["%s এর দিন আগে","%s এর দিন"],["1 সপ্তাহ আগে","1 সপ্তাহের মধ্যে"],["%s এর সপ্তাহ আগে","%s সপ্তাহের মধ্যে"],["1 মাস আগে","1 মাসে"],["%s মাস আগে","%s মাসে"],["1 বছর আগে","1 বছরের মধ্যে"],["%s বছর আগে","%s বছরে"]][e]}; -})()""", - "ca" -> """(function(){lichess.timeagoLocale=function(a,s){return[["fa un moment","d'aquí un moment"],["fa %s segons","d'aquí %s segons"],["fa 1 minut","d'aquí 1 minut"],["fa %s minuts","d'aquí %s minuts"],["fa 1 hora","d'aquí 1 hora"],["fa %s hores","d'aquí %s hores"],["fa 1 dia","d'aquí 1 dia"],["fa %s dies","d'aquí %s dies"],["fa 1 setmana","d'aquí 1 setmana"],["fa %s setmanes","d'aquí %s setmanes"],["fa 1 mes","d'aquí 1 mes"],["fa %s mesos","d'aquí %s mesos"],["fa 1 any","d'aquí 1 any"],["fa %s anys","d'aquí %s anys"]][s]}; -})()""", - "da" -> """(function(){lichess.timeagoLocale=function(e,o){return[["for et øjeblik siden","om et øjeblik"],["for %s sekunder siden","om %s sekunder"],["for 1 minut siden","om 1 minut"],["for %s minutter siden","om %s minutter"],["for 1 time siden","om 1 time"],["for %s timer siden","om %s timer"],["for 1 dag siden","om 1 dag"],["for %s dage siden","om %s dage"],["for 1 uge siden","om 1 uge"],["for %s uger siden","om %s uger"],["for 1 måned siden","om 1 måned"],["for %s måneder siden","om %s måneder"],["for 1 år siden","om 1 år"],["for %s år siden","om %s år"]][o]}; -})()""", - "de" -> """(function(){lichess.timeagoLocale=function(n,e){return[["gerade eben","vor einer Weile"],["vor %s Sekunden","in %s Sekunden"],["vor 1 Minute","in 1 Minute"],["vor %s Minuten","in %s Minuten"],["vor 1 Stunde","in 1 Stunde"],["vor %s Stunden","in %s Stunden"],["vor 1 Tag","in 1 Tag"],["vor %s Tagen","in %s Tagen"],["vor 1 Woche","in 1 Woche"],["vor %s Wochen","in %s Wochen"],["vor 1 Monat","in 1 Monat"],["vor %s Monaten","in %s Monaten"],["vor 1 Jahr","in 1 Jahr"],["vor %s Jahren","in %s Jahren"]][e]}; -})()""", - "el" -> """(function(){lichess.timeagoLocale=function(s,e){return[["μόλις τώρα","σε λίγο"],["%s δευτερόλεπτα πριν","σε %s δευτερόλεπτα"],["1 λεπτό πριν","σε 1 λεπτό"],["%s λεπτά πριν","σε %s λεπτά"],["1 ώρα πριν","σε 1 ώρα"],["%s ώρες πριν","σε %s ώρες"],["1 μέρα πριν","σε 1 μέρα"],["%s μέρες πριν","σε %s μέρες"],["1 εβδομάδα πριν","σε 1 εβδομάδα"],["%s εβδομάδες πριν","σε %s εβδομάδες"],["1 μήνα πριν","σε 1 μήνα"],["%s μήνες πριν","σε %s μήνες"],["1 χρόνο πριν","σε 1 χρόνο"],["%s χρόνια πριν","σε %s χρόνια"]][e]}; -})()""", + "ar" -> """(function(){lichess.timeagoLocale=function(s,e){if(0===e)return["منذ لحظات","بعد لحظات"];var t=formatTime(Math.floor(e/2),s);return["منذ "+t,"بعد "+t]};var timeTypes=[["ثانية","ثانيتين","%s ثوان","%s ثانية"],["دقيقة","دقيقتين","%s دقائق","%s دقيقة"],["ساعة","ساعتين","%s ساعات","%s ساعة"],["يوم","يومين","%s أيام","%s يوماً"],["أسبوع","أسبوعين","%s أسابيع","%s أسبوعاً"],["شهر","شهرين","%s أشهر","%s شهراً"],["عام","عامين","%s أعوام","%s عاماً"]];function formatTime(s,e){return e<3?timeTypes[s][e-1]:3<=e&&e<=10?timeTypes[s][2]:timeTypes[s][3]}})()""", + "be" -> """(function(){var seconds=formatNum.bind(null,"секунду","%s секунду","%s секунды","%s секунд"),minutes=formatNum.bind(null,"хвіліну","%s хвіліну","%s хвіліны","%s хвілін"),hours=formatNum.bind(null,"гадзіну","%s гадзіну","%s гадзіны","%s гадзін"),days=formatNum.bind(null,"дзень","%s дзень","%s дні","%s дзён"),weeks=formatNum.bind(null,"тыдзень","%s тыдзень","%s тыдні","%s тыдняў"),months=formatNum.bind(null,"месяц","%s месяц","%s месяцы","%s месяцаў"),years=formatNum.bind(null,"год","%s год","%s гады","%s гадоў");function formatNum(s,e,n,r,u){var a=u%10,t=r;return 1===u?t=s:1===a&&20 """(function(){lichess.timeagoLocale=function(s,e){return[["току що","съвсем скоро"],["преди %s секунди","след %s секунди"],["преди 1 минута","след 1 минута"],["преди %s минути","след %s минути"],["преди 1 час","след 1 час"],["преди %s часа","след %s часа"],["преди 1 ден","след 1 ден"],["преди %s дни","след %s дни"],["преди 1 седмица","след 1 седмица"],["преди %s седмици","след %s седмици"],["преди 1 месец","след 1 месец"],["преди %s месеца","след %s месеца"],["преди 1 година","след 1 година"],["преди %s години","след %s години"]][e]}})()""", + "bn_IN" -> """(function(){lichess.timeagoLocale=function(s,e){return[["এইমাত্র","একটা সময়"],["%s সেকেন্ড আগে","%s এর সেকেন্ডের মধ্যে"],["1 মিনিট আগে","1 মিনিটে"],["%s এর মিনিট আগে","%s এর মিনিটের মধ্যে"],["1 ঘন্টা আগে","1 ঘন্টা"],["%s ঘণ্টা আগে","%s এর ঘন্টার মধ্যে"],["1 দিন আগে","1 দিনের মধ্যে"],["%s এর দিন আগে","%s এর দিন"],["1 সপ্তাহ আগে","1 সপ্তাহের মধ্যে"],["%s এর সপ্তাহ আগে","%s সপ্তাহের মধ্যে"],["1 মাস আগে","1 মাসে"],["%s মাস আগে","%s মাসে"],["1 বছর আগে","1 বছরের মধ্যে"],["%s বছর আগে","%s বছরে"]][e]}})()""", + "ca" -> """(function(){lichess.timeagoLocale=function(a,s){return[["fa un moment","d'aquí un moment"],["fa %s segons","d'aquí %s segons"],["fa 1 minut","d'aquí 1 minut"],["fa %s minuts","d'aquí %s minuts"],["fa 1 hora","d'aquí 1 hora"],["fa %s hores","d'aquí %s hores"],["fa 1 dia","d'aquí 1 dia"],["fa %s dies","d'aquí %s dies"],["fa 1 setmana","d'aquí 1 setmana"],["fa %s setmanes","d'aquí %s setmanes"],["fa 1 mes","d'aquí 1 mes"],["fa %s mesos","d'aquí %s mesos"],["fa 1 any","d'aquí 1 any"],["fa %s anys","d'aquí %s anys"]][s]}})()""", + "da" -> """(function(){lichess.timeagoLocale=function(e,o){return[["for et øjeblik siden","om et øjeblik"],["for %s sekunder siden","om %s sekunder"],["for 1 minut siden","om 1 minut"],["for %s minutter siden","om %s minutter"],["for 1 time siden","om 1 time"],["for %s timer siden","om %s timer"],["for 1 dag siden","om 1 dag"],["for %s dage siden","om %s dage"],["for 1 uge siden","om 1 uge"],["for %s uger siden","om %s uger"],["for 1 måned siden","om 1 måned"],["for %s måneder siden","om %s måneder"],["for 1 år siden","om 1 år"],["for %s år siden","om %s år"]][o]}})()""", + "de" -> """(function(){lichess.timeagoLocale=function(n,e){return[["gerade eben","vor einer Weile"],["vor %s Sekunden","in %s Sekunden"],["vor 1 Minute","in 1 Minute"],["vor %s Minuten","in %s Minuten"],["vor 1 Stunde","in 1 Stunde"],["vor %s Stunden","in %s Stunden"],["vor 1 Tag","in 1 Tag"],["vor %s Tagen","in %s Tagen"],["vor 1 Woche","in 1 Woche"],["vor %s Wochen","in %s Wochen"],["vor 1 Monat","in 1 Monat"],["vor %s Monaten","in %s Monaten"],["vor 1 Jahr","in 1 Jahr"],["vor %s Jahren","in %s Jahren"]][e]}})()""", + "el" -> """(function(){lichess.timeagoLocale=function(s,e){return[["μόλις τώρα","σε λίγο"],["%s δευτερόλεπτα πριν","σε %s δευτερόλεπτα"],["1 λεπτό πριν","σε 1 λεπτό"],["%s λεπτά πριν","σε %s λεπτά"],["1 ώρα πριν","σε 1 ώρα"],["%s ώρες πριν","σε %s ώρες"],["1 μέρα πριν","σε 1 μέρα"],["%s μέρες πριν","σε %s μέρες"],["1 εβδομάδα πριν","σε 1 εβδομάδα"],["%s εβδομάδες πριν","σε %s εβδομάδες"],["1 μήνα πριν","σε 1 μήνα"],["%s μήνες πριν","σε %s μήνες"],["1 χρόνο πριν","σε 1 χρόνο"],["%s χρόνια πριν","σε %s χρόνια"]][e]}})()""", "en" -> """lichess.timeagoLocale=function(s,n){return[["just now","right now"],["%s seconds ago","in %s seconds"],["1 minute ago","in 1 minute"],["%s minutes ago","in %s minutes"],["1 hour ago","in 1 hour"],["%s hours ago","in %s hours"],["1 day ago","in 1 day"],["%s days ago","in %s days"],["1 week ago","in 1 week"],["%s weeks ago","in %s weeks"],["1 month ago","in 1 month"],["%s months ago","in %s months"],["1 year ago","in 1 year"],["%s years ago","in %s years"]][n]};""", - "es" -> """(function(){lichess.timeagoLocale=function(e,s){return[["justo ahora","en un rato"],["hace %s segundos","en %s segundos"],["hace 1 minuto","en 1 minuto"],["hace %s minutos","en %s minutos"],["hace 1 hora","en 1 hora"],["hace %s horas","en %s horas"],["hace 1 día","en 1 día"],["hace %s días","en %s días"],["hace 1 semana","en 1 semana"],["hace %s semanas","en %s semanas"],["hace 1 mes","en 1 mes"],["hace %s meses","en %s meses"],["hace 1 año","en 1 año"],["hace %s años","en %s años"]][s]}; -})()""", - "eu" -> """(function(){lichess.timeagoLocale=function(u,r){return[["orain","denbora bat barru"],["duela %s segundu","%s segundu barru"],["duela minutu 1","minutu 1 barru"],["duela %s minutu","%s minutu barru"],["duela ordu 1","ordu 1 barru"],["duela %s ordu","%s ordu barru"],["duela egun 1","egun 1 barru"],["duela %s egun","%s egun barru"],["duela aste 1","aste 1 barru"],["duela %s aste","%s aste barru"],["duela hillabete 1","hillabete 1 barru"],["duela %s hillabete","%s hillabete barru"],["duela urte 1","urte 1 barru"],["duela %s urte","%s urte barru"]][r]}; -})()""", - "fa" -> """(function(){lichess.timeagoLocale=function(s,e){return[["همین الآن","لحظاتی پیش"],["%s ثانیه پیش","حدود %s ثانیه پیش"],["1 دقیقه پیش","حدود 1 دقیقه پیش"],["%s دقیقه پیش","حدود %s دقیقه پیش"],["1 ساعت پیش","حدود 1 ساعت پیش"],["%s ساعت پیش","حدود %s ساعت پیش"],["1 روز پیش","حدود 1 روز پیش"],["%s روز پیش","حدود %s روز پیش"],["1 هفته پیش","حدود 1 هفته پیش"],["%s هفته پیش","حدود %s هفته پیش"],["1 ماه پیش","حدود 1 ماه پیش"],["%s ماه پیش","حدود %s ماه پیش"],["1 سال پیش","حدود 1 سال پیش"],["%s سال پیش","حدود %s سال پیش"]][e]}; -})()""", - "fi" -> """(function(){lichess.timeagoLocale=function(t,s){return[["juuri äsken","juuri nyt"],["%s sekuntia sitten","%s sekunnin päästä"],["minuutti sitten","minuutin päästä"],["%s minuuttia sitten","%s minuutin päästä"],["tunti sitten","tunnin päästä"],["%s tuntia sitten","%s tunnin päästä"],["päivä sitten","päivän päästä"],["%s päivää sitten","%s päivän päästä"],["viikko sitten","viikon päästä"],["%s viikkoa sitten","%s viikon päästä"],["kuukausi sitten","kuukauden päästä"],["%s kuukautta sitten","%s kuukauden päästä"],["vuosi sitten","vuoden päästä"],["%s vuotta sitten","%s vuoden päästä"]][s]}; -})()""", - "fr" -> """(function(){lichess.timeagoLocale=function(s,a){return[["à l'instant","dans un instant"],["il y a %s secondes","dans %s secondes"],["il y a 1 minute","dans 1 minute"],["il y a %s minutes","dans %s minutes"],["il y a 1 heure","dans 1 heure"],["il y a %s heures","dans %s heures"],["il y a 1 jour","dans 1 jour"],["il y a %s jours","dans %s jours"],["il y a 1 semaine","dans 1 semaine"],["il y a %s semaines","dans %s semaines"],["il y a 1 mois","dans 1 mois"],["il y a %s mois","dans %s mois"],["il y a 1 an","dans 1 an"],["il y a %s ans","dans %s ans"]][a]}; -})()""", - "gl" -> """(function(){lichess.timeagoLocale=function(s,a){return[["xusto agora","daquí a un pouco"],["hai %s segundos","en %s segundos"],["hai 1 minuto","nun minuto"],["hai %s minutos","en %s minutos"],["hai 1 hora","nunha hora"],["hai %s horas","en %s horas"],["hai 1 día","nun día"],["hai %s días","en %s días"],["hai 1 semana","nunha semana"],["hai %s semanas","en %s semanas"],["hai 1 mes","nun mes"],["hai %s meses","en %s meses"],["hai 1 ano","nun ano"],["hai %s anos","en %s anos"]][a]}; -})()""", - "he" -> """(function(){lichess.timeagoLocale=function(s,e){return[["זה עתה","עכשיו"],["לפני %s שניות","בעוד %s שניות"],["לפני דקה","בעוד דקה"],["לפני %s דקות","בעוד %s דקות"],["לפני שעה","בעוד שעה"],["לפני %s שעות","בעוד %s שעות"],["אתמול","מחר"],["לפני %s ימים","בעוד %s ימים"],["לפני שבוע","בעוד שבוע"],["לפני %s שבועות","בעוד %s שבועות"],["לפני חודש","בעוד חודש"],["לפני %s חודשים","בעוד %s חודשים"],["לפני שנה","בעוד שנה"],["לפני %s שנים","בעוד %s שנים"]][e]}; -})()""", - "hi_IN" -> """(function(){lichess.timeagoLocale=function(s,e){return[["अभी","कुछ समय"],["%s सेकंड पहले","%s सेकंड में"],["1 मिनट पहले","1 मिनट में"],["%s मिनट पहले","%s मिनट में"],["1 घंटे पहले","1 घंटे में"],["%s घंटे पहले","%s घंटे में"],["1 दिन पहले","1 दिन में"],["%s दिन पहले","%s दिनों में"],["1 सप्ताह पहले","1 सप्ताह में"],["%s हफ्ते पहले","%s हफ्तों में"],["1 महीने पहले","1 महीने में"],["%s महीने पहले","%s महीनों में"],["1 साल पहले","1 साल में"],["%s साल पहले","%s साल में"]][e]}; -})()""", - "hu" -> """(function(){lichess.timeagoLocale=function(e,l){return[["éppen most","éppen most"],["%s másodperce","%s másodpercen belül"],["1 perce","1 percen belül"],["%s perce","%s percen belül"],["1 órája","1 órán belül"],["%s órája","%s órán belül"],["1 napja","1 napon belül"],["%s napja","%s napon belül"],["1 hete","1 héten belül"],["%s hete","%s héten belül"],["1 hónapja","1 hónapon belül"],["%s hónapja","%s hónapon belül"],["1 éve","1 éven belül"],["%s éve","%s éven belül"]][l]}; -})()""", - "id_ID" -> """(function(){lichess.timeagoLocale=function(a,l){return[["baru saja","sebentar"],["%s detik yang lalu","dalam %s detik"],["1 menit yang lalu","dalam 1 menit"],["%s menit yang lalu","dalam %s menit"],["1 jam yang lalu","dalam 1 jam"],["%s jam yang lalu","dalam %s jam"],["1 hari yang lalu","dalam 1 hari"],["%s hari yang lalu","dalam %s hari"],["1 minggu yang lalu","dalam 1 minggu"],["%s minggu yang lalu","dalam %s minggu"],["1 bulan yang lalu","dalam 1 bulan"],["%s bulan yang lalu","dalam %s bulan"],["1 tahun yang lalu","dalam 1 tahun"],["%s tahun yang lalu","dalam %s tahun"]][l]}; -})()""", - "it" -> """(function(){lichess.timeagoLocale=function(a,n){return[["poco fa","fra poco"],["%s secondi fa","fra %s secondi"],["un minuto fa","fra un minuto"],["%s minuti fa","fra %s minuti"],["un'ora fa","fra un'ora"],["%s ore fa","fra %s ore"],["un giorno fa","fra un giorno"],["%s giorni fa","fra %s giorni"],["una settimana fa","fra una settimana"],["%s settimane fa","fra %s settimane"],["un mese fa","fra un mese"],["%s mesi fa","fra %s mesi"],["un anno fa","fra un anno"],["%s anni fa","fra %s anni"]][n]}; -})()""", - "ja" -> """(function(){lichess.timeagoLocale=function(s,e){return[["すこし前","すぐに"],["%s秒前","%s秒以内"],["1分前","1分以内"],["%s分前","%s分以内"],["1時間前","1時間以内"],["%s時間前","%s時間以内"],["1日前","1日以内"],["%s日前","%s日以内"],["1週間前","1週間以内"],["%s週間前","%s週間以内"],["1ヶ月前","1ヶ月以内"],["%sヶ月前","%sヶ月以内"],["1年前","1年以内"],["%s年前","%s年以内"]][e]}; -})()""", - "ka" -> """(function(){lichess.timeagoLocale=function(s,e){return[["ამ წამს","ახლა"],["%s წამის წინ","%s წამში"],["1 წუთის წინ","1 წუთში"],["%s წუთის წინ","%s წუთში"],["1 საათის წინ","1 საათში"],["%s საათის წინ","%s საათში"],["1 დღის წინ","1 დღეში"],["%s დღის წინ","%s დღეში"],["1 კვირის წინ","1 კვირაში"],["%s კვირის წინ","%s კვირაში"],["1 თვის წინ","1 თვეში"],["%s თვის წინ","%s თვეში"],["1 წლის წინ","1 წელიწადში"],["%s წლის წინ","%s წელიწადში"]][e]}; -})()""", - "ko" -> """(function(){lichess.timeagoLocale=function(s,e){return[["방금","곧"],["%s초 전","%s초 후"],["1분 전","1분 후"],["%s분 전","%s분 후"],["1시간 전","1시간 후"],["%s시간 전","%s시간 후"],["1일 전","1일 후"],["%s일 전","%s일 후"],["1주일 전","1주일 후"],["%s주일 전","%s주일 후"],["1개월 전","1개월 후"],["%s개월 전","%s개월 후"],["1년 전","1년 후"],["%s년 전","%s년 후"]][e]}; -})()""", - "ml" -> """(function(){lichess.timeagoLocale=function(s,e){return[["ഇപ്പോള്‍","കുറച്ചു മുന്‍പ്"],["%s സെക്കന്റ്‌കള്‍ക്ക് മുന്‍പ്","%s സെക്കന്റില്‍"],["1 മിനിറ്റിനു മുന്‍പ്","1 മിനിറ്റില്‍"],["%s മിനിറ്റുകള്‍ക്ക് മുന്‍പ","%s മിനിറ്റില്‍"],["1 മണിക്കൂറിനു മുന്‍പ്","1 മണിക്കൂറില്‍"],["%s മണിക്കൂറുകള്‍ക്കു മുന്‍പ്","%s മണിക്കൂറില്‍"],["1 ഒരു ദിവസം മുന്‍പ്","1 ദിവസത്തില്‍"],["%s ദിവസങ്ങള്‍ക് മുന്‍പ്","%s ദിവസങ്ങള്‍ക്കുള്ളില്‍"],["1 ആഴ്ച മുന്‍പ്","1 ആഴ്ചയില്‍"],["%s ആഴ്ചകള്‍ക്ക് മുന്‍പ്","%s ആഴ്ചകള്‍ക്കുള്ളില്‍"],["1 മാസത്തിനു മുന്‍പ്","1 മാസത്തിനുള്ളില്‍"],["%s മാസങ്ങള്‍ക്ക് മുന്‍പ്","%s മാസങ്ങള്‍ക്കുള്ളില്‍"],["1 വര്‍ഷത്തിനു മുന്‍പ്","1 വര്‍ഷത്തിനുള്ളില്‍"],["%s വര്‍ഷങ്ങള്‍ക്കു മുന്‍പ്","%s വര്‍ഷങ്ങള്‍ക്കുല്ല്ളില്‍"]][e]}; -})()""", - "my" -> """(function(){lichess.timeagoLocale=function(s,e){return[["ယခုအတွင်း","ယခု"],["%s စက္ကန့် အကြာက","%s စက္ကန့်အတွင်း"],["1 မိနစ် အကြာက","1 မိနစ်အတွင်း"],["%s မိနစ် အကြာက","%s မိနစ်အတွင်း"],["1 နာရီ အကြာက","1 နာရီအတွင်း"],["%s နာရီ အကြာက","%s နာရီအတွင်း"],["1 ရက် အကြာက","1 ရက်အတွင်း"],["%s ရက် အကြာက","%s ရက်အတွင်း"],["1 ပတ် အကြာက","1 ပတ်အတွင်း"],["%s ပတ် အကြာက","%s ပတ်အတွင်း"],["1 လ အကြာက","1 လအတွင်း"],["%s လ အကြာက","%s လအတွင်း"],["1 နှစ် အကြာက","1 နှစ်အတွင်း"],["%s နှစ် အကြာက","%s နှစ်အတွင်း"]][e]}; -})()""", - "nb_NO" -> """(function(){lichess.timeagoLocale=function(e,s){return[["akkurat nå","om litt"],["%s sekunder siden","om %s sekunder"],["1 minutt siden","om 1 minutt"],["%s minutter siden","om %s minutter"],["1 time siden","om 1 time"],["%s timer siden","om %s timer"],["1 dag siden","om 1 dag"],["%s dager siden","om %s dager"],["1 uke siden","om 1 uke"],["%s uker siden","om %s uker"],["1 måned siden","om 1 måned"],["%s måneder siden","om %s måneder"],["1 år siden","om 1 år"],["%s år siden","om %s år"]][s]}; -})()""", - "nl" -> """(function(){lichess.timeagoLocale=function(n,e){return[["recent","binnenkort"],["%s seconden geleden","binnen %s seconden"],["1 minuut geleden","binnen 1 minuut"],["%s minuten geleden","binnen %s minuten"],["1 uur geleden","binnen 1 uur"],["%s uur geleden","binnen %s uur"],["1 dag geleden","binnen 1 dag"],["%s dagen geleden","binnen %s dagen"],["1 week geleden","binnen 1 week"],["%s weken geleden","binnen %s weken"],["1 maand geleden","binnen 1 maand"],["%s maanden geleden","binnen %s maanden"],["1 jaar geleden","binnen 1 jaar"],["%s jaar geleden","binnen %s jaar"]][e]}; -})()""", - "nn_NO" -> """(function(){lichess.timeagoLocale=function(s,n){return[["nett no","om litt"],["%s sekund sidan","om %s sekund"],["1 minutt sidan","om 1 minutt"],["%s minutt sidan","om %s minutt"],["1 time sidan","om 1 time"],["%s timar sidan","om %s timar"],["1 dag sidan","om 1 dag"],["%s dagar sidan","om %s dagar"],["1 veke sidan","om 1 veke"],["%s veker sidan","om %s veker"],["1 månad sidan","om 1 månad"],["%s månadar sidan","om %s månadar"],["1 år sidan","om 1 år"],["%s år sidan","om %s år"]][n]}; -})()""", - "pl" -> """(function(){var l=[["w tej chwili","za chwilę"],["%s sekund temu","za %s sekund"],["1 minutę temu","za 1 minutę"],["%s minut temu","za %s minut"],["1 godzinę temu","za 1 godzinę"],["%s godzin temu","za %s godzin"],["1 dzień temu","za 1 dzień"],["%s dni temu","za %s dni"],["1 tydzień temu","za 1 tydzień"],["%s tygodni temu","za %s tygodni"],["1 miesiąc temu","za 1 miesiąc"],["%s miesięcy temu","za %s miesięcy"],["1 rok temu","za 1 rok"],["%s lat temu","za %s lat"],["%s sekundy temu","za %s sekundy"],["%s minuty temu","za %s minuty"],["%s godziny temu","za %s godziny"],["%s dni temu","za %s dni"],["%s tygodnie temu","za %s tygodnie"],["%s miesiące temu","za %s miesiące"],["%s lata temu","za %s lata"]];lichess.timeagoLocale=function(e,i){return l[1&i?4 """(function(){lichess.timeagoLocale=function(m,s){return[["agora mesmo","daqui um pouco"],["há %s segundos","em %s segundos"],["há um minuto","em um minuto"],["há %s minutos","em %s minutos"],["há uma hora","em uma hora"],["há %s horas","em %s horas"],["há um dia","em um dia"],["há %s dias","em %s dias"],["há uma semana","em uma semana"],["há %s semanas","em %s semanas"],["há um mês","em um mês"],["há %s meses","em %s meses"],["há um ano","em um ano"],["há %s anos","em %s anos"]][s]}; -})()""", - "ro" -> """(function(){lichess.timeagoLocale=function(e,s){var u=[["chiar acum","chiar acum"],["acum %s secunde","peste %s secunde"],["acum un minut","peste un minut"],["acum %s minute","peste %s minute"],["acum o oră","peste o oră"],["acum %s ore","peste %s ore"],["acum o zi","peste o zi"],["acum %s zile","peste %s zile"],["acum o săptămână","peste o săptămână"],["acum %s săptămâni","peste %s săptămâni"],["acum o lună","peste o lună"],["acum %s luni","peste %s luni"],["acum un an","peste un an"],["acum %s ani","peste %s ani"]];return e<20?u[s]:[u[s][0].replace("%s","%s de"),u[s][1].replace("%s","%s de")]}; -})()""", - "ru" -> """(function(){var seconds=formatNum.bind(null,"секунду","%s секунду","%s секунды","%s секунд"),minutes=formatNum.bind(null,"минуту","%s минуту","%s минуты","%s минут"),hours=formatNum.bind(null,"час","%s час","%s часа","%s часов"),days=formatNum.bind(null,"день","%s день","%s дня","%s дней"),weeks=formatNum.bind(null,"неделю","%s неделю","%s недели","%s недель"),months=formatNum.bind(null,"месяц","%s месяц","%s месяца","%s месяцев"),years=formatNum.bind(null,"год","%s год","%s года","%s лет");function formatNum(s,e,r,n,u){var a=u%10,t=n;return 1===u?t=s:1===a&&20 """(function(){lichess.timeagoLocale=function(a,s){return[["pak më parë","pas pak"],["para %s sekondash","pas %s sekondash"],["para një minute","pas një minute"],["para %s minutash","pas %s minutash"],["para një ore","pas një ore"],["para %s orësh","pas %s orësh"],["dje","nesër"],["para %s ditësh","pas %s ditësh"],["para një jave","pas një jave"],["para %s javësh","pas %s javësh"],["para një muaji","pas një muaji"],["para %s muajsh","pas %s muajsh"],["para një viti","pas një viti"],["para %s vjetësh","pas %s vjetësh"]][s]}; -})()""", - "sr" -> """(function(){var seconds=formatNum.bind(null,"1 секунд","%s секунд","%s секунде","%s секунди"),minutes=formatNum.bind(null,"1 минут","%s минут","%s минуте","%s минута"),hours=formatNum.bind(null,"сат времена","%s сат","%s сата","%s сати"),days=formatNum.bind(null,"1 дан","%s дан","%s дана","%s дана"),weeks=formatNum.bind(null,"недељу дана","%s недељу","%s недеље","%s недеља"),months=formatNum.bind(null,"месец дана","%s месец","%s месеца","%s месеци"),years=formatNum.bind(null,"годину дана","%s годину","%s године","%s година");function formatNum(s,e,n,r,u){var a=u%10,t=u%100;return 1==u?s:1==a&&11!=t?e:2<=a&&a<=4&&!(12<=t&&t<=14)?n:r}lichess.timeagoLocale=function(s,e){switch(e){case 0:return["малопре","управо сад"];case 1:return["пре "+seconds(s),"за "+seconds(s)];case 2:case 3:return["пре "+minutes(s),"за "+minutes(s)];case 4:case 5:return["пре "+hours(s),"за "+hours(s)];case 6:case 7:return["пре "+days(s),"за "+days(s)];case 8:case 9:return["пре "+weeks(s),"за "+weeks(s)];case 10:case 11:return["пре "+months(s),"за "+months(s)];case 12:case 13:return["пре "+years(s),"за "+years(s)];default:return["",""]}}; -})()""", - "sv" -> """(function(){lichess.timeagoLocale=function(s,e){return[["just nu","om en stund"],["%s sekunder sedan","om %s sekunder"],["1 minut sedan","om 1 minut"],["%s minuter sedan","om %s minuter"],["1 timme sedan","om 1 timme"],["%s timmar sedan","om %s timmar"],["1 dag sedan","om 1 dag"],["%s dagar sedan","om %s dagar"],["1 vecka sedan","om 1 vecka"],["%s veckor sedan","om %s veckor"],["1 månad sedan","om 1 månad"],["%s månader sedan","om %s månader"],["1 år sedan","om 1 år"],["%s år sedan","om %s år"]][e]}; -})()""", - "ta" -> """(function(){lichess.timeagoLocale=function(s,e){return[["இப்போது","சற்று நேரம் முன்பு"],["%s நொடிக்கு முன்","%s நொடிகளில்"],["1 நிமிடத்திற்க்கு முன்","1 நிமிடத்தில்"],["%s நிமிடத்திற்க்கு முன்","%s நிமிடங்களில்"],["1 மணி நேரத்திற்கு முன்","1 மணி நேரத்திற்குள்"],["%s மணி நேரத்திற்கு முன்","%s மணி நேரத்திற்குள்"],["1 நாளுக்கு முன்","1 நாளில்"],["%s நாட்களுக்கு முன்","%s நாட்களில்"],["1 வாரத்திற்கு முன்","1 வாரத்தில்"],["%s வாரங்களுக்கு முன்","%s வாரங்களில்"],["1 மாதத்திற்கு முன்","1 மாதத்தில்"],["%s மாதங்களுக்கு முன்","%s மாதங்களில்"],["1 வருடத்திற்கு முன்","1 வருடத்தில்"],["%s வருடங்களுக்கு முன்","%s வருடங்களில்"]][e]}; -})()""", - "th" -> """(function(){lichess.timeagoLocale=function(s,e){return[["เมื่อสักครู่นี้","อีกสักครู่"],["%s วินาทีที่แล้ว","ใน %s วินาที"],["1 นาทีที่แล้ว","ใน 1 นาที"],["%s นาทีที่แล้ว","ใน %s นาที"],["1 ชั่วโมงที่แล้ว","ใน 1 ชั่วโมง"],["%s ชั่วโมงที่แล้ว","ใน %s ชั่วโมง"],["1 วันที่แล้ว","ใน 1 วัน"],["%s วันที่แล้ว","ใน %s วัน"],["1 อาทิตย์ที่แล้ว","ใน 1 อาทิตย์"],["%s อาทิตย์ที่แล้ว","ใน %s อาทิตย์"],["1 เดือนที่แล้ว","ใน 1 เดือน"],["%s เดือนที่แล้ว","ใน %s เดือน"],["1 ปีที่แล้ว","ใน 1 ปี"],["%s ปีที่แล้ว","ใน %s ปี"]][e]}; -})()""", - "tr" -> """(function(){lichess.timeagoLocale=function(n,i){return[["az önce","şimdi"],["%s saniye önce","%s saniye içinde"],["1 dakika önce","1 dakika içinde"],["%s dakika önce","%s dakika içinde"],["1 saat önce","1 saat içinde"],["%s saat önce","%s saat içinde"],["1 gün önce","1 gün içinde"],["%s gün önce","%s gün içinde"],["1 hafta önce","1 hafta içinde"],["%s hafta önce","%s hafta içinde"],["1 ay önce","1 ay içinde"],["%s ay önce","%s ay içinde"],["1 yıl önce","1 yıl içinde"],["%s yıl önce","%s yıl içinde"]][i]}; -})()""", - "uk" -> """(function(){var seconds=formatNum.bind(null,"секунду","%s секунду","%s секунди","%s секунд"),minutes=formatNum.bind(null,"хвилину","%s хвилину","%s хвилини","%s хвилин"),hours=formatNum.bind(null,"годину","%s годину","%s години","%s годин"),days=formatNum.bind(null,"день","%s день","%s дні","%s днів"),weeks=formatNum.bind(null,"тиждень","%s тиждень","%s тиждні","%s тижднів"),months=formatNum.bind(null,"місяць","%s місяць","%s місяці","%s місяців"),years=formatNum.bind(null,"рік","%s рік","%s роки","%s років");function formatNum(s,e,n,r,u){var a=u%10,t=r;return 1===u?t=s:1===a&&20 """(function(){lichess.timeagoLocale=function(t,n){return[["vừa xong","một lúc"],["%s giây trước","trong %s giây"],["1 phút trước","trong 1 phút"],["%s phút trước","trong %s phút"],["1 giờ trước","trong 1 giờ"],["%s giờ trước","trong %s giờ"],["1 ngày trước","trong 1 ngày"],["%s ngày trước","trong %s ngày"],["1 tuần trước","trong 1 tuần"],["%s tuần trước","trong %s tuần"],["1 tháng trước","trong 1 tháng"],["%s tháng trước","trong %s tháng"],["1 năm trước","trong 1 năm"],["%s năm trước","trong %s năm"]][n]}; -})()""", - "zh_CN" -> """(function(){lichess.timeagoLocale=function(s,e){return[["刚刚","片刻后"],["%s 秒前","%s 秒后"],["1 分钟前","1 分钟后"],["%s 分钟前","%s 分钟后"],["1 小时前","1小 时后"],["%s 小时前","%s 小时后"],["1 天前","1 天后"],["%s 天前","%s 天后"],["1 周前","1 周后"],["%s 周前","%s 周后"],["1 月前","1 月后"],["%s 月前","%s 月后"],["1 年前","1 年后"],["%s 年前","%s 年后"]][e]}; -})()""", - "zh_TW" -> """(function(){lichess.timeagoLocale=function(s,e){return[["剛剛","片刻後"],["%s 秒前","%s 秒後"],["1 分鐘前","1 分鐘後"],["%s 分鐘前","%s 分鐘後"],["1 小時前","1 小時後"],["%s 小時前","%s 小時後"],["1 天前","1 天後"],["%s 天前","%s 天後"],["1 週前","1 週後"],["%s 週前","%s 週後"],["1 月前","1 月後"],["%s 月前","%s 月後"],["1 年前","1 年後"],["%s 年前","%s 年後"]][e]}; -})()""" + "es" -> """(function(){lichess.timeagoLocale=function(e,s){return[["justo ahora","en un rato"],["hace %s segundos","en %s segundos"],["hace 1 minuto","en 1 minuto"],["hace %s minutos","en %s minutos"],["hace 1 hora","en 1 hora"],["hace %s horas","en %s horas"],["hace 1 día","en 1 día"],["hace %s días","en %s días"],["hace 1 semana","en 1 semana"],["hace %s semanas","en %s semanas"],["hace 1 mes","en 1 mes"],["hace %s meses","en %s meses"],["hace 1 año","en 1 año"],["hace %s años","en %s años"]][s]}})()""", + "eu" -> """(function(){lichess.timeagoLocale=function(u,r){return[["orain","denbora bat barru"],["duela %s segundu","%s segundu barru"],["duela minutu 1","minutu 1 barru"],["duela %s minutu","%s minutu barru"],["duela ordu 1","ordu 1 barru"],["duela %s ordu","%s ordu barru"],["duela egun 1","egun 1 barru"],["duela %s egun","%s egun barru"],["duela aste 1","aste 1 barru"],["duela %s aste","%s aste barru"],["duela hillabete 1","hillabete 1 barru"],["duela %s hillabete","%s hillabete barru"],["duela urte 1","urte 1 barru"],["duela %s urte","%s urte barru"]][r]}})()""", + "fa" -> """(function(){lichess.timeagoLocale=function(s,e){return[["همین الآن","لحظاتی پیش"],["%s ثانیه پیش","حدود %s ثانیه پیش"],["1 دقیقه پیش","حدود 1 دقیقه پیش"],["%s دقیقه پیش","حدود %s دقیقه پیش"],["1 ساعت پیش","حدود 1 ساعت پیش"],["%s ساعت پیش","حدود %s ساعت پیش"],["1 روز پیش","حدود 1 روز پیش"],["%s روز پیش","حدود %s روز پیش"],["1 هفته پیش","حدود 1 هفته پیش"],["%s هفته پیش","حدود %s هفته پیش"],["1 ماه پیش","حدود 1 ماه پیش"],["%s ماه پیش","حدود %s ماه پیش"],["1 سال پیش","حدود 1 سال پیش"],["%s سال پیش","حدود %s سال پیش"]][e]}})()""", + "fi" -> """(function(){lichess.timeagoLocale=function(t,s){return[["juuri äsken","juuri nyt"],["%s sekuntia sitten","%s sekunnin päästä"],["minuutti sitten","minuutin päästä"],["%s minuuttia sitten","%s minuutin päästä"],["tunti sitten","tunnin päästä"],["%s tuntia sitten","%s tunnin päästä"],["päivä sitten","päivän päästä"],["%s päivää sitten","%s päivän päästä"],["viikko sitten","viikon päästä"],["%s viikkoa sitten","%s viikon päästä"],["kuukausi sitten","kuukauden päästä"],["%s kuukautta sitten","%s kuukauden päästä"],["vuosi sitten","vuoden päästä"],["%s vuotta sitten","%s vuoden päästä"]][s]}})()""", + "fr" -> """(function(){lichess.timeagoLocale=function(s,a){return[["à l'instant","dans un instant"],["il y a %s secondes","dans %s secondes"],["il y a 1 minute","dans 1 minute"],["il y a %s minutes","dans %s minutes"],["il y a 1 heure","dans 1 heure"],["il y a %s heures","dans %s heures"],["il y a 1 jour","dans 1 jour"],["il y a %s jours","dans %s jours"],["il y a 1 semaine","dans 1 semaine"],["il y a %s semaines","dans %s semaines"],["il y a 1 mois","dans 1 mois"],["il y a %s mois","dans %s mois"],["il y a 1 an","dans 1 an"],["il y a %s ans","dans %s ans"]][a]}})()""", + "gl" -> """(function(){lichess.timeagoLocale=function(s,a){return[["xusto agora","daquí a un pouco"],["hai %s segundos","en %s segundos"],["hai 1 minuto","nun minuto"],["hai %s minutos","en %s minutos"],["hai 1 hora","nunha hora"],["hai %s horas","en %s horas"],["hai 1 día","nun día"],["hai %s días","en %s días"],["hai 1 semana","nunha semana"],["hai %s semanas","en %s semanas"],["hai 1 mes","nun mes"],["hai %s meses","en %s meses"],["hai 1 ano","nun ano"],["hai %s anos","en %s anos"]][a]}})()""", + "he" -> """(function(){lichess.timeagoLocale=function(s,e){return[["זה עתה","עכשיו"],["לפני %s שניות","בעוד %s שניות"],["לפני דקה","בעוד דקה"],["לפני %s דקות","בעוד %s דקות"],["לפני שעה","בעוד שעה"],["לפני %s שעות","בעוד %s שעות"],["אתמול","מחר"],["לפני %s ימים","בעוד %s ימים"],["לפני שבוע","בעוד שבוע"],["לפני %s שבועות","בעוד %s שבועות"],["לפני חודש","בעוד חודש"],["לפני %s חודשים","בעוד %s חודשים"],["לפני שנה","בעוד שנה"],["לפני %s שנים","בעוד %s שנים"]][e]}})()""", + "hi_IN" -> """(function(){lichess.timeagoLocale=function(s,e){return[["अभी","कुछ समय"],["%s सेकंड पहले","%s सेकंड में"],["1 मिनट पहले","1 मिनट में"],["%s मिनट पहले","%s मिनट में"],["1 घंटे पहले","1 घंटे में"],["%s घंटे पहले","%s घंटे में"],["1 दिन पहले","1 दिन में"],["%s दिन पहले","%s दिनों में"],["1 सप्ताह पहले","1 सप्ताह में"],["%s हफ्ते पहले","%s हफ्तों में"],["1 महीने पहले","1 महीने में"],["%s महीने पहले","%s महीनों में"],["1 साल पहले","1 साल में"],["%s साल पहले","%s साल में"]][e]}})()""", + "hu" -> """(function(){lichess.timeagoLocale=function(e,l){return[["éppen most","éppen most"],["%s másodperce","%s másodpercen belül"],["1 perce","1 percen belül"],["%s perce","%s percen belül"],["1 órája","1 órán belül"],["%s órája","%s órán belül"],["1 napja","1 napon belül"],["%s napja","%s napon belül"],["1 hete","1 héten belül"],["%s hete","%s héten belül"],["1 hónapja","1 hónapon belül"],["%s hónapja","%s hónapon belül"],["1 éve","1 éven belül"],["%s éve","%s éven belül"]][l]}})()""", + "id_ID" -> """(function(){lichess.timeagoLocale=function(a,l){return[["baru saja","sebentar"],["%s detik yang lalu","dalam %s detik"],["1 menit yang lalu","dalam 1 menit"],["%s menit yang lalu","dalam %s menit"],["1 jam yang lalu","dalam 1 jam"],["%s jam yang lalu","dalam %s jam"],["1 hari yang lalu","dalam 1 hari"],["%s hari yang lalu","dalam %s hari"],["1 minggu yang lalu","dalam 1 minggu"],["%s minggu yang lalu","dalam %s minggu"],["1 bulan yang lalu","dalam 1 bulan"],["%s bulan yang lalu","dalam %s bulan"],["1 tahun yang lalu","dalam 1 tahun"],["%s tahun yang lalu","dalam %s tahun"]][l]}})()""", + "it" -> """(function(){lichess.timeagoLocale=function(a,n){return[["poco fa","fra poco"],["%s secondi fa","fra %s secondi"],["un minuto fa","fra un minuto"],["%s minuti fa","fra %s minuti"],["un'ora fa","fra un'ora"],["%s ore fa","fra %s ore"],["un giorno fa","fra un giorno"],["%s giorni fa","fra %s giorni"],["una settimana fa","fra una settimana"],["%s settimane fa","fra %s settimane"],["un mese fa","fra un mese"],["%s mesi fa","fra %s mesi"],["un anno fa","fra un anno"],["%s anni fa","fra %s anni"]][n]}})()""", + "ja" -> """(function(){lichess.timeagoLocale=function(s,e){return[["すこし前","すぐに"],["%s秒前","%s秒以内"],["1分前","1分以内"],["%s分前","%s分以内"],["1時間前","1時間以内"],["%s時間前","%s時間以内"],["1日前","1日以内"],["%s日前","%s日以内"],["1週間前","1週間以内"],["%s週間前","%s週間以内"],["1ヶ月前","1ヶ月以内"],["%sヶ月前","%sヶ月以内"],["1年前","1年以内"],["%s年前","%s年以内"]][e]}})()""", + "ka" -> """(function(){lichess.timeagoLocale=function(s,e){return[["ამ წამს","ახლა"],["%s წამის წინ","%s წამში"],["1 წუთის წინ","1 წუთში"],["%s წუთის წინ","%s წუთში"],["1 საათის წინ","1 საათში"],["%s საათის წინ","%s საათში"],["1 დღის წინ","1 დღეში"],["%s დღის წინ","%s დღეში"],["1 კვირის წინ","1 კვირაში"],["%s კვირის წინ","%s კვირაში"],["1 თვის წინ","1 თვეში"],["%s თვის წინ","%s თვეში"],["1 წლის წინ","1 წელიწადში"],["%s წლის წინ","%s წელიწადში"]][e]}})()""", + "ko" -> """(function(){lichess.timeagoLocale=function(s,e){return[["방금","곧"],["%s초 전","%s초 후"],["1분 전","1분 후"],["%s분 전","%s분 후"],["1시간 전","1시간 후"],["%s시간 전","%s시간 후"],["1일 전","1일 후"],["%s일 전","%s일 후"],["1주일 전","1주일 후"],["%s주일 전","%s주일 후"],["1개월 전","1개월 후"],["%s개월 전","%s개월 후"],["1년 전","1년 후"],["%s년 전","%s년 후"]][e]}})()""", + "ml" -> """(function(){lichess.timeagoLocale=function(s,e){return[["ഇപ്പോള്‍","കുറച്ചു മുന്‍പ്"],["%s സെക്കന്റ്‌കള്‍ക്ക് മുന്‍പ്","%s സെക്കന്റില്‍"],["1 മിനിറ്റിനു മുന്‍പ്","1 മിനിറ്റില്‍"],["%s മിനിറ്റുകള്‍ക്ക് മുന്‍പ","%s മിനിറ്റില്‍"],["1 മണിക്കൂറിനു മുന്‍പ്","1 മണിക്കൂറില്‍"],["%s മണിക്കൂറുകള്‍ക്കു മുന്‍പ്","%s മണിക്കൂറില്‍"],["1 ഒരു ദിവസം മുന്‍പ്","1 ദിവസത്തില്‍"],["%s ദിവസങ്ങള്‍ക് മുന്‍പ്","%s ദിവസങ്ങള്‍ക്കുള്ളില്‍"],["1 ആഴ്ച മുന്‍പ്","1 ആഴ്ചയില്‍"],["%s ആഴ്ചകള്‍ക്ക് മുന്‍പ്","%s ആഴ്ചകള്‍ക്കുള്ളില്‍"],["1 മാസത്തിനു മുന്‍പ്","1 മാസത്തിനുള്ളില്‍"],["%s മാസങ്ങള്‍ക്ക് മുന്‍പ്","%s മാസങ്ങള്‍ക്കുള്ളില്‍"],["1 വര്‍ഷത്തിനു മുന്‍പ്","1 വര്‍ഷത്തിനുള്ളില്‍"],["%s വര്‍ഷങ്ങള്‍ക്കു മുന്‍പ്","%s വര്‍ഷങ്ങള്‍ക്കുല്ല്ളില്‍"]][e]}})()""", + "my" -> """(function(){lichess.timeagoLocale=function(s,e){return[["ယခုအတွင်း","ယခု"],["%s စက္ကန့် အကြာက","%s စက္ကန့်အတွင်း"],["1 မိနစ် အကြာက","1 မိနစ်အတွင်း"],["%s မိနစ် အကြာက","%s မိနစ်အတွင်း"],["1 နာရီ အကြာက","1 နာရီအတွင်း"],["%s နာရီ အကြာက","%s နာရီအတွင်း"],["1 ရက် အကြာက","1 ရက်အတွင်း"],["%s ရက် အကြာက","%s ရက်အတွင်း"],["1 ပတ် အကြာက","1 ပတ်အတွင်း"],["%s ပတ် အကြာက","%s ပတ်အတွင်း"],["1 လ အကြာက","1 လအတွင်း"],["%s လ အကြာက","%s လအတွင်း"],["1 နှစ် အကြာက","1 နှစ်အတွင်း"],["%s နှစ် အကြာက","%s နှစ်အတွင်း"]][e]}})()""", + "nb_NO" -> """(function(){lichess.timeagoLocale=function(e,s){return[["akkurat nå","om litt"],["%s sekunder siden","om %s sekunder"],["1 minutt siden","om 1 minutt"],["%s minutter siden","om %s minutter"],["1 time siden","om 1 time"],["%s timer siden","om %s timer"],["1 dag siden","om 1 dag"],["%s dager siden","om %s dager"],["1 uke siden","om 1 uke"],["%s uker siden","om %s uker"],["1 måned siden","om 1 måned"],["%s måneder siden","om %s måneder"],["1 år siden","om 1 år"],["%s år siden","om %s år"]][s]}})()""", + "nl" -> """(function(){lichess.timeagoLocale=function(n,e){return[["recent","binnenkort"],["%s seconden geleden","binnen %s seconden"],["1 minuut geleden","binnen 1 minuut"],["%s minuten geleden","binnen %s minuten"],["1 uur geleden","binnen 1 uur"],["%s uur geleden","binnen %s uur"],["1 dag geleden","binnen 1 dag"],["%s dagen geleden","binnen %s dagen"],["1 week geleden","binnen 1 week"],["%s weken geleden","binnen %s weken"],["1 maand geleden","binnen 1 maand"],["%s maanden geleden","binnen %s maanden"],["1 jaar geleden","binnen 1 jaar"],["%s jaar geleden","binnen %s jaar"]][e]}})()""", + "nn_NO" -> """(function(){lichess.timeagoLocale=function(s,n){return[["nett no","om litt"],["%s sekund sidan","om %s sekund"],["1 minutt sidan","om 1 minutt"],["%s minutt sidan","om %s minutt"],["1 time sidan","om 1 time"],["%s timar sidan","om %s timar"],["1 dag sidan","om 1 dag"],["%s dagar sidan","om %s dagar"],["1 veke sidan","om 1 veke"],["%s veker sidan","om %s veker"],["1 månad sidan","om 1 månad"],["%s månadar sidan","om %s månadar"],["1 år sidan","om 1 år"],["%s år sidan","om %s år"]][n]}})()""", + "pl" -> """(function(){var l=[["w tej chwili","za chwilę"],["%s sekund temu","za %s sekund"],["1 minutę temu","za 1 minutę"],["%s minut temu","za %s minut"],["1 godzinę temu","za 1 godzinę"],["%s godzin temu","za %s godzin"],["1 dzień temu","za 1 dzień"],["%s dni temu","za %s dni"],["1 tydzień temu","za 1 tydzień"],["%s tygodni temu","za %s tygodni"],["1 miesiąc temu","za 1 miesiąc"],["%s miesięcy temu","za %s miesięcy"],["1 rok temu","za 1 rok"],["%s lat temu","za %s lat"],["%s sekundy temu","za %s sekundy"],["%s minuty temu","za %s minuty"],["%s godziny temu","za %s godziny"],["%s dni temu","za %s dni"],["%s tygodnie temu","za %s tygodnie"],["%s miesiące temu","za %s miesiące"],["%s lata temu","za %s lata"]];lichess.timeagoLocale=function(e,i){return l[1&i?4 """(function(){lichess.timeagoLocale=function(m,s){return[["agora mesmo","daqui um pouco"],["há %s segundos","em %s segundos"],["há um minuto","em um minuto"],["há %s minutos","em %s minutos"],["há uma hora","em uma hora"],["há %s horas","em %s horas"],["há um dia","em um dia"],["há %s dias","em %s dias"],["há uma semana","em uma semana"],["há %s semanas","em %s semanas"],["há um mês","em um mês"],["há %s meses","em %s meses"],["há um ano","em um ano"],["há %s anos","em %s anos"]][s]}})()""", + "ro" -> """(function(){lichess.timeagoLocale=function(e,s){var u=[["chiar acum","chiar acum"],["acum %s secunde","peste %s secunde"],["acum un minut","peste un minut"],["acum %s minute","peste %s minute"],["acum o oră","peste o oră"],["acum %s ore","peste %s ore"],["acum o zi","peste o zi"],["acum %s zile","peste %s zile"],["acum o săptămână","peste o săptămână"],["acum %s săptămâni","peste %s săptămâni"],["acum o lună","peste o lună"],["acum %s luni","peste %s luni"],["acum un an","peste un an"],["acum %s ani","peste %s ani"]];return e<20?u[s]:[u[s][0].replace("%s","%s de"),u[s][1].replace("%s","%s de")]}})()""", + "ru" -> """(function(){var seconds=formatNum.bind(null,"секунду","%s секунду","%s секунды","%s секунд"),minutes=formatNum.bind(null,"минуту","%s минуту","%s минуты","%s минут"),hours=formatNum.bind(null,"час","%s час","%s часа","%s часов"),days=formatNum.bind(null,"день","%s день","%s дня","%s дней"),weeks=formatNum.bind(null,"неделю","%s неделю","%s недели","%s недель"),months=formatNum.bind(null,"месяц","%s месяц","%s месяца","%s месяцев"),years=formatNum.bind(null,"год","%s год","%s года","%s лет");function formatNum(s,e,r,n,u){var a=u%10,t=n;return 1===u?t=s:1===a&&20 """(function(){lichess.timeagoLocale=function(a,s){return[["pak më parë","pas pak"],["para %s sekondash","pas %s sekondash"],["para një minute","pas një minute"],["para %s minutash","pas %s minutash"],["para një ore","pas një ore"],["para %s orësh","pas %s orësh"],["dje","nesër"],["para %s ditësh","pas %s ditësh"],["para një jave","pas një jave"],["para %s javësh","pas %s javësh"],["para një muaji","pas një muaji"],["para %s muajsh","pas %s muajsh"],["para një viti","pas një viti"],["para %s vjetësh","pas %s vjetësh"]][s]}})()""", + "sr" -> """(function(){var seconds=formatNum.bind(null,"1 секунд","%s секунд","%s секунде","%s секунди"),minutes=formatNum.bind(null,"1 минут","%s минут","%s минуте","%s минута"),hours=formatNum.bind(null,"сат времена","%s сат","%s сата","%s сати"),days=formatNum.bind(null,"1 дан","%s дан","%s дана","%s дана"),weeks=formatNum.bind(null,"недељу дана","%s недељу","%s недеље","%s недеља"),months=formatNum.bind(null,"месец дана","%s месец","%s месеца","%s месеци"),years=formatNum.bind(null,"годину дана","%s годину","%s године","%s година");function formatNum(s,e,n,r,u){var a=u%10,t=u%100;return 1==u?s:1==a&&11!=t?e:2<=a&&a<=4&&!(12<=t&&t<=14)?n:r}lichess.timeagoLocale=function(s,e){switch(e){case 0:return["малопре","управо сад"];case 1:return["пре "+seconds(s),"за "+seconds(s)];case 2:case 3:return["пре "+minutes(s),"за "+minutes(s)];case 4:case 5:return["пре "+hours(s),"за "+hours(s)];case 6:case 7:return["пре "+days(s),"за "+days(s)];case 8:case 9:return["пре "+weeks(s),"за "+weeks(s)];case 10:case 11:return["пре "+months(s),"за "+months(s)];case 12:case 13:return["пре "+years(s),"за "+years(s)];default:return["",""]}}})()""", + "sv" -> """(function(){lichess.timeagoLocale=function(s,e){return[["just nu","om en stund"],["%s sekunder sedan","om %s sekunder"],["1 minut sedan","om 1 minut"],["%s minuter sedan","om %s minuter"],["1 timme sedan","om 1 timme"],["%s timmar sedan","om %s timmar"],["1 dag sedan","om 1 dag"],["%s dagar sedan","om %s dagar"],["1 vecka sedan","om 1 vecka"],["%s veckor sedan","om %s veckor"],["1 månad sedan","om 1 månad"],["%s månader sedan","om %s månader"],["1 år sedan","om 1 år"],["%s år sedan","om %s år"]][e]}})()""", + "ta" -> """(function(){lichess.timeagoLocale=function(s,e){return[["இப்போது","சற்று நேரம் முன்பு"],["%s நொடிக்கு முன்","%s நொடிகளில்"],["1 நிமிடத்திற்க்கு முன்","1 நிமிடத்தில்"],["%s நிமிடத்திற்க்கு முன்","%s நிமிடங்களில்"],["1 மணி நேரத்திற்கு முன்","1 மணி நேரத்திற்குள்"],["%s மணி நேரத்திற்கு முன்","%s மணி நேரத்திற்குள்"],["1 நாளுக்கு முன்","1 நாளில்"],["%s நாட்களுக்கு முன்","%s நாட்களில்"],["1 வாரத்திற்கு முன்","1 வாரத்தில்"],["%s வாரங்களுக்கு முன்","%s வாரங்களில்"],["1 மாதத்திற்கு முன்","1 மாதத்தில்"],["%s மாதங்களுக்கு முன்","%s மாதங்களில்"],["1 வருடத்திற்கு முன்","1 வருடத்தில்"],["%s வருடங்களுக்கு முன்","%s வருடங்களில்"]][e]}})()""", + "th" -> """(function(){lichess.timeagoLocale=function(s,e){return[["เมื่อสักครู่นี้","อีกสักครู่"],["%s วินาทีที่แล้ว","ใน %s วินาที"],["1 นาทีที่แล้ว","ใน 1 นาที"],["%s นาทีที่แล้ว","ใน %s นาที"],["1 ชั่วโมงที่แล้ว","ใน 1 ชั่วโมง"],["%s ชั่วโมงที่แล้ว","ใน %s ชั่วโมง"],["1 วันที่แล้ว","ใน 1 วัน"],["%s วันที่แล้ว","ใน %s วัน"],["1 อาทิตย์ที่แล้ว","ใน 1 อาทิตย์"],["%s อาทิตย์ที่แล้ว","ใน %s อาทิตย์"],["1 เดือนที่แล้ว","ใน 1 เดือน"],["%s เดือนที่แล้ว","ใน %s เดือน"],["1 ปีที่แล้ว","ใน 1 ปี"],["%s ปีที่แล้ว","ใน %s ปี"]][e]}})()""", + "tr" -> """(function(){lichess.timeagoLocale=function(n,i){return[["az önce","şimdi"],["%s saniye önce","%s saniye içinde"],["1 dakika önce","1 dakika içinde"],["%s dakika önce","%s dakika içinde"],["1 saat önce","1 saat içinde"],["%s saat önce","%s saat içinde"],["1 gün önce","1 gün içinde"],["%s gün önce","%s gün içinde"],["1 hafta önce","1 hafta içinde"],["%s hafta önce","%s hafta içinde"],["1 ay önce","1 ay içinde"],["%s ay önce","%s ay içinde"],["1 yıl önce","1 yıl içinde"],["%s yıl önce","%s yıl içinde"]][i]}})()""", + "uk" -> """(function(){var seconds=formatNum.bind(null,"секунду","%s секунду","%s секунди","%s секунд"),minutes=formatNum.bind(null,"хвилину","%s хвилину","%s хвилини","%s хвилин"),hours=formatNum.bind(null,"годину","%s годину","%s години","%s годин"),days=formatNum.bind(null,"день","%s день","%s дні","%s днів"),weeks=formatNum.bind(null,"тиждень","%s тиждень","%s тиждні","%s тижднів"),months=formatNum.bind(null,"місяць","%s місяць","%s місяці","%s місяців"),years=formatNum.bind(null,"рік","%s рік","%s роки","%s років");function formatNum(s,e,n,r,u){var a=u%10,t=r;return 1===u?t=s:1===a&&20 """(function(){lichess.timeagoLocale=function(t,n){return[["vừa xong","một lúc"],["%s giây trước","trong %s giây"],["1 phút trước","trong 1 phút"],["%s phút trước","trong %s phút"],["1 giờ trước","trong 1 giờ"],["%s giờ trước","trong %s giờ"],["1 ngày trước","trong 1 ngày"],["%s ngày trước","trong %s ngày"],["1 tuần trước","trong 1 tuần"],["%s tuần trước","trong %s tuần"],["1 tháng trước","trong 1 tháng"],["%s tháng trước","trong %s tháng"],["1 năm trước","trong 1 năm"],["%s năm trước","trong %s năm"]][n]}})()""", + "zh_CN" -> """(function(){lichess.timeagoLocale=function(s,e){return[["刚刚","片刻后"],["%s 秒前","%s 秒后"],["1 分钟前","1 分钟后"],["%s 分钟前","%s 分钟后"],["1 小时前","1小 时后"],["%s 小时前","%s 小时后"],["1 天前","1 天后"],["%s 天前","%s 天后"],["1 周前","1 周后"],["%s 周前","%s 周后"],["1 月前","1 月后"],["%s 月前","%s 月后"],["1 年前","1 年后"],["%s 年前","%s 年后"]][e]}})()""", + "zh_TW" -> """(function(){lichess.timeagoLocale=function(s,e){return[["剛剛","片刻後"],["%s 秒前","%s 秒後"],["1 分鐘前","1 分鐘後"],["%s 分鐘前","%s 分鐘後"],["1 小時前","1 小時後"],["%s 小時前","%s 小時後"],["1 天前","1 天後"],["%s 天前","%s 天後"],["1 週前","1 週後"],["%s 週前","%s 週後"],["1 月前","1 月後"],["%s 月前","%s 月後"],["1 年前","1 年後"],["%s 年前","%s 年後"]][e]}})()""" ) } diff --git a/modules/i18n/src/main/Translation.scala b/modules/i18n/src/main/Translation.scala index 148e958a10..21bfa42aa4 100644 --- a/modules/i18n/src/main/Translation.scala +++ b/modules/i18n/src/main/Translation.scala @@ -1,10 +1,8 @@ package lila.i18n -import play.twirl.api.Html -import scalatags.Text.RawFrag +import scalatags.Text.all._ import lila.common.String.html.escapeHtml -import lila.common.String.frag.{ escapeHtml => escapeFrag } private sealed trait Translation @@ -14,14 +12,10 @@ private final class Simple(val message: String) extends Translation { if (args.isEmpty) message else message.format(args: _*) - def formatFrag(args: Seq[RawFrag]): RawFrag = + def format(args: Seq[RawFrag]): RawFrag = if (args.isEmpty) RawFrag(message) else RawFrag(message.format(args.map(_.v): _*)) - def formatHtml(args: Seq[Html]): Html = - if (args.isEmpty) Html(message) - else Html(message.format(args.map(_.body): _*)) - override def toString = s"Simple($message)" } @@ -31,14 +25,10 @@ private final class Escaped(val message: String, escaped: String) extends Transl if (args.isEmpty) message else message.format(args: _*) - def formatFrag(args: Seq[RawFrag]): RawFrag = + def format(args: Seq[RawFrag]): RawFrag = if (args.isEmpty) RawFrag(escaped) else RawFrag(escaped.format(args.map(_.v): _*)) - def formatHtml(args: Seq[Html]): Html = - if (args.isEmpty) Html(escaped) - else Html(escaped.format(args.map(_.body): _*)) - override def toString = s"Escaped($message)" } @@ -55,19 +45,12 @@ private final class Plurals(val messages: Map[I18nQuantity, String]) extends Tra else message.format(args: _*) } - def formatFrag(quantity: I18nQuantity, args: Seq[RawFrag]): Option[RawFrag] = + def format(quantity: I18nQuantity, args: Seq[RawFrag]): Option[RawFrag] = messageFor(quantity).map { message => - val escaped = escapeFrag(message) + val escaped = escapeHtml(message) if (args.isEmpty) escaped else RawFrag(escaped.v.format(args.map(_.v): _*)) } - def formatHtml(quantity: I18nQuantity, args: Seq[Html]): Option[Html] = - messageFor(quantity).map { message => - val escaped = escapeHtml(message) - if (args.isEmpty) escaped - else Html(escaped.body.format(args.map(_.body): _*)) - } - override def toString = s"Plurals($messages)" } diff --git a/modules/i18n/src/main/Translator.scala b/modules/i18n/src/main/Translator.scala index 5621884e07..135d5a5b20 100644 --- a/modules/i18n/src/main/Translator.scala +++ b/modules/i18n/src/main/Translator.scala @@ -1,49 +1,12 @@ package lila.i18n -import play.twirl.api.Html -import scalatags.Text.RawFrag +import scalatags.Text.all._ import lila.common.Lang import lila.common.String.html.escapeHtml -import lila.common.String.frag.{ escapeHtml => escapeFrag } object Translator { - object html { - - def literal(key: MessageKey, db: I18nDb.Ref, args: Seq[Any], lang: Lang): Html = - translate(key, db, lang, I18nQuantity.Other /* grmbl */ , args) - - def plural(key: MessageKey, db: I18nDb.Ref, count: Count, args: Seq[Any], lang: Lang): Html = - translate(key, db, lang, I18nQuantity(lang, count), args) - - private def translate(key: MessageKey, db: I18nDb.Ref, lang: Lang, quantity: I18nQuantity, args: Seq[Any]): Html = - findTranslation(key, db, lang) flatMap { translation => - val htmlArgs = escapeArgs(args) - try { - translation match { - case literal: Simple => Some(literal.formatHtml(htmlArgs)) - case literal: Escaped => Some(literal.formatHtml(htmlArgs)) - case plurals: Plurals => plurals.formatHtml(quantity, htmlArgs) - } - } catch { - case e: Exception => - logger.warn(s"Failed to format html $db/$lang/$key -> $translation (${args.toList})", e) - Some(Html(key)) - } - } getOrElse { - logger.info(s"No translation found for $quantity $key in $lang") - Html(key) - } - - private def escapeArgs(args: Seq[Any]): Seq[Html] = args.map { - case s: String => escapeHtml(s) - case h: Html => h - case r: RawFrag => Html(r.v) - case a => Html(a.toString) - } - } - object frag { def literal(key: MessageKey, db: I18nDb.Ref, args: Seq[Any], lang: Lang): RawFrag = translate(key, db, lang, I18nQuantity.Other /* grmbl */ , args) @@ -56,9 +19,9 @@ object Translator { val htmlArgs = escapeArgs(args) try { translation match { - case literal: Simple => Some(literal.formatFrag(htmlArgs)) - case literal: Escaped => Some(literal.formatFrag(htmlArgs)) - case plurals: Plurals => plurals.formatFrag(quantity, htmlArgs) + case literal: Simple => Some(literal.format(htmlArgs)) + case literal: Escaped => Some(literal.format(htmlArgs)) + case plurals: Plurals => plurals.format(quantity, htmlArgs) } } catch { case e: Exception => @@ -71,8 +34,7 @@ object Translator { } private def escapeArgs(args: Seq[Any]): Seq[RawFrag] = args.map { - case s: String => escapeFrag(s) - case h: Html => RawFrag(h.body) + case s: String => escapeHtml(s) case r: RawFrag => r case a => RawFrag(a.toString) } diff --git a/modules/insight/src/main/Dimension.scala b/modules/insight/src/main/Dimension.scala index 6b25572bb1..f8891fafee 100644 --- a/modules/insight/src/main/Dimension.scala +++ b/modules/insight/src/main/Dimension.scala @@ -1,6 +1,6 @@ package lila.insight -import play.twirl.api.Html +import scalatags.Text.all._ import reactivemongo.bson._ import play.api.libs.json._ @@ -14,7 +14,7 @@ sealed abstract class Dimension[A: BSONValueHandler]( val name: String, val dbKey: String, val position: Position, - val description: Html + val description: Frag ) { def bson = implicitly[BSONValueHandler[A]] @@ -32,77 +32,77 @@ object Dimension { case object Period extends Dimension[Period]( "period", "Date", F.date, Game, - Html("The date at which the game was played") + raw("The date at which the game was played") ) case object Date extends Dimension[lila.insight.DateRange]( "date", "Date", F.date, Game, - Html("The date at which the game was played") + raw("The date at which the game was played") ) case object Perf extends Dimension[PerfType]( "variant", "Variant", F.perf, Game, - Html("The rating category of the game, like Bullet, Blitz, or Chess960.") + raw("The rating category of the game, like Bullet, Blitz, or Chess960.") ) case object Phase extends Dimension[Phase]( "phase", "Game phase", F.moves("p"), Move, - Html("The portion of the game: Opening, Middlegame, or Endgame.") + raw("The portion of the game: Opening, Middlegame, or Endgame.") ) case object Result extends Dimension[Result]( "result", "Game result", F.result, Game, - Html("Whether you won, lost, or drew the game.") + raw("Whether you won, lost, or drew the game.") ) case object Termination extends Dimension[Termination]( "termination", "Game termination", F.termination, Game, - Html("The way that the game ended, like Checkmate or Resignation.") + raw("The way that the game ended, like Checkmate or Resignation.") ) case object Color extends Dimension[Color]( "color", "Color", F.color, Game, - Html("The side you are playing: White or Black.") + raw("The side you are playing: White or Black.") ) case object Opening extends Dimension[chess.opening.Ecopening]( "opening", "Opening", F.eco, Game, - Html("ECO identification of the initial moves, like \"A58 Benko Gambit\".") + raw("ECO identification of the initial moves, like \"A58 Benko Gambit\".") ) case object OpponentStrength extends Dimension[RelativeStrength]( "opponentStrength", "Opponent strength", F.opponentStrength, Game, - Html("Rating of your opponent compared to yours. Much weaker:-200, Weaker:-100, Stronger:+100, Much stronger:+200.") + raw("Rating of your opponent compared to yours. Much weaker:-200, Weaker:-100, Stronger:+100, Much stronger:+200.") ) case object PieceRole extends Dimension[Role]( "piece", "Piece moved", F.moves("r"), Move, - Html("The type of piece you move.") + raw("The type of piece you move.") ) case object MovetimeRange extends Dimension[MovetimeRange]( "movetime", "Move time", F.moves("t"), Move, - Html("The amount of time you spend thinking on each move, in seconds.") + raw("The amount of time you spend thinking on each move, in seconds.") ) case object MyCastling extends Dimension[Castling]( "myCastling", "My castling side", F.myCastling, Game, - Html("The side you castled on during the game: kingside, queenside, or none.") + raw("The side you castled on during the game: kingside, queenside, or none.") ) case object OpCastling extends Dimension[Castling]( "opCastling", "Opponent castling side", F.opponentCastling, Game, - Html("The side your opponent castled on during the game: kingside, queenside, or none.") + raw("The side your opponent castled on during the game: kingside, queenside, or none.") ) case object QueenTrade extends Dimension[QueenTrade]( "queenTrade", "Queen trade", F.queenTrade, Game, - Html("Whether queens were traded before the endgame or not.") + raw("Whether queens were traded before the endgame or not.") ) case object MaterialRange extends Dimension[MaterialRange]( "material", "Material imbalance", F.moves("i"), Move, - Html("Value of your pieces compared to your opponent's. Pawn=1, Bishop/Knight=3, Rook=5, Queen=9.") + raw("Value of your pieces compared to your opponent's. Pawn=1, Bishop/Knight=3, Rook=5, Queen=9.") ) def requiresStableRating(d: Dimension[_]) = d match { diff --git a/modules/insight/src/main/JsonView.scala b/modules/insight/src/main/JsonView.scala index ba6b78f0f5..36b3bb6ee5 100644 --- a/modules/insight/src/main/JsonView.scala +++ b/modules/insight/src/main/JsonView.scala @@ -15,7 +15,7 @@ final class JsonView { "key" -> D.Opening.key, "name" -> D.Opening.name, "position" -> D.Opening.position, - "description" -> D.Opening.description.body, + "description" -> D.Opening.description.render, "values" -> Dimension.valuesOf(D.Opening).filter { o => ecos contains o.eco }.map(Dimension.valueToJson(D.Opening)) @@ -93,7 +93,7 @@ final class JsonView { "key" -> d.key, "name" -> d.name, "position" -> d.position, - "description" -> d.description.body, + "description" -> d.description.render, "values" -> Dimension.valuesOf(d).map(Dimension.valueToJson(d)) ) } @@ -102,7 +102,7 @@ final class JsonView { Json.obj( "key" -> m.key, "name" -> m.name, - "description" -> m.description.body, + "description" -> m.description.render, "position" -> m.position ) } diff --git a/modules/insight/src/main/Metric.scala b/modules/insight/src/main/Metric.scala index 22272da800..34004c4767 100644 --- a/modules/insight/src/main/Metric.scala +++ b/modules/insight/src/main/Metric.scala @@ -1,6 +1,7 @@ package lila.insight -import play.twirl.api.Html +import scalatags.Text.all._ + import reactivemongo.bson._ sealed abstract class Metric( @@ -10,7 +11,7 @@ sealed abstract class Metric( val position: Position, val per: Position, val dataType: Metric.DataType, - val description: Html + val description: Frag ) object Metric { @@ -30,7 +31,7 @@ object Metric { import Entry.{ BSONFields => F } case object MeanCpl extends Metric("acpl", "Average centipawn loss", F moves "c", Move, Move, Average, - Html("""Precision of your moves. Lower is better.""")) + raw("""Precision of your moves. Lower is better.""")) case object Movetime extends Metric("movetime", "Move time", F moves "t", Move, Move, Seconds, Dimension.MovetimeRange.description) @@ -42,22 +43,22 @@ object Metric { Dimension.Termination.description) case object RatingDiff extends Metric("ratingDiff", "Rating gain", F.ratingDiff, Game, Game, Average, - Html("The amount of rating points you win or lose when the game ends.")) + raw("The amount of rating points you win or lose when the game ends.")) case object OpponentRating extends Metric("opponentRating", "Opponent rating", F.opponentRating, Game, Game, Average, - Html("The average rating of your opponent for the relevant variant.")) + raw("The average rating of your opponent for the relevant variant.")) case object NbMoves extends Metric("nbMoves", "Moves per game", F moves "r", Move, Game, Average, - Html("Number of moves you play in the game. Doesn't count the opponent moves.")) + raw("Number of moves you play in the game. Doesn't count the opponent moves.")) case object PieceRole extends Metric("piece", "Piece moved", F moves "r", Move, Move, Percent, Dimension.PieceRole.description) case object Opportunism extends Metric("opportunism", "Opportunism", F moves "o", Move, Move, Percent, - Html("How often you take advantage of your opponent blunders. 100% means you punish them all, 0% means you counter-blunder them all.")) + raw("How often you take advantage of your opponent blunders. 100% means you punish them all, 0% means you counter-blunder them all.")) case object Luck extends Metric("luck", "Luck", F moves "l", Move, Move, Percent, - Html("How often your opponent fails to punish your blunders. 100% means they miss all your blunders, 0% means they spot them all.")) + raw("How often your opponent fails to punish your blunders. 100% means they miss all your blunders, 0% means they spot them all.")) case object Material extends Metric("material", "Material imbalance", F moves "i", Move, Move, Average, Dimension.MaterialRange.description) diff --git a/modules/message/src/main/MessageApi.scala b/modules/message/src/main/MessageApi.scala index 650f0130f5..662679f156 100644 --- a/modules/message/src/main/MessageApi.scala +++ b/modules/message/src/main/MessageApi.scala @@ -1,7 +1,7 @@ package lila.message -import scala.concurrent.duration._ import com.github.blemale.scaffeine.{ AsyncLoadingCache, Scaffeine } +import scala.concurrent.duration._ import lila.common.paginator._ import lila.db.dsl._ @@ -54,6 +54,9 @@ final class MessageApi( mod ) + def sendPresetFromLichess(user: User, preset: ModPreset) = + UserRepo.lichess flatten "Missing lichess user" flatMap { sendPreset(_, user, preset) } + def makeThread(data: DataForm.ThreadData, me: User): Fu[Thread] = { val fromMod = Granter(_.MessageAnyone)(me) UserRepo named data.user.id flatMap { diff --git a/modules/message/src/main/ModPreset.scala b/modules/message/src/main/ModPreset.scala index fa434c5273..a1a4e0846f 100644 --- a/modules/message/src/main/ModPreset.scala +++ b/modules/message/src/main/ModPreset.scala @@ -70,7 +70,7 @@ Please also remember that, over the long run, ratings tend to gravitate towards Warning: Username that implies you are a titled player -The username policy (https://github.com/ornicar/lila/wiki/Username-policy) for Lichess states that you can't have a username that implies that you have a FIDE title or the Lichess Master title. Actual titled players can send an email to support@lichess.org with evidence that documents their identity, e.g. a scanned ID card, driving license, passport or similar. We will then verify your identity and title, and your title will be shown in front of your username and on your Lichess user profile. Since your username implies that you have a title, we reserve the right to close your account within two weeks, if you have not verified your title within that time. +The username policy (https://github.com/ornicar/lila/wiki/Username-policy) for Lichess states that you can't have a username that implies that you have a FIDE title or the Lichess Master title. Actual titled players can send an email to contact@lichess.org with evidence that documents their identity, e.g. a scanned ID card, driving license, passport or similar. We will then verify your identity and title, and your title will be shown in front of your username and on your Lichess user profile. Since your username implies that you have a title, we reserve the right to close your account within two weeks, if you have not verified your title within that time. """, /* ---------------------------------------------------------------*/ """ @@ -91,7 +91,15 @@ Our cheating detection algorithms have marked your account for using computer as lazy val sandbagAuto = ModPreset( subject = "Warning: possible sandbagging", text = """You have lost a couple games after a few moves. Please note that you MUST try to win every rated game. -Losing rated games on purpose is called "sandbagging", and is not allowed on lichess. +Losing rated games on purpose is called "sandbagging", and is not allowed on Lichess. + +Thank you for your understanding.""" + ) + + def maxFollow(username: String, max: Int) = ModPreset( + subject = "Follow limit reached!", + text = s"""Sorry, you can't follow more than $max players on Lichess. +To follow new players, you must first unfollow some on https://lichess.org/@/$username/following. Thank you for your understanding.""" ) diff --git a/modules/message/src/main/Thread.scala b/modules/message/src/main/Thread.scala index 1f05f6bfe9..ed771c1b7f 100644 --- a/modules/message/src/main/Thread.scala +++ b/modules/message/src/main/Thread.scala @@ -41,6 +41,10 @@ case class Thread( def isTooBig = nbPosts > 200 + def isReplyable = !isTooBig && !isLichess + + def isLichess = creatorId == User.lichessId + def firstPost: Option[Post] = posts.headOption def firstPostUnreadBy(user: User): Option[Post] = posts find isPostUnreadBy(user) diff --git a/modules/mod/src/main/ModApi.scala b/modules/mod/src/main/ModApi.scala index 14c29bb3a4..167ba89fd4 100644 --- a/modules/mod/src/main/ModApi.scala +++ b/modules/mod/src/main/ModApi.scala @@ -2,7 +2,7 @@ package lila.mod import lila.common.{ IpAddress, EmailAddress } import lila.report.{ Mod, ModId, Suspect, SuspectId, Room } -import lila.security.Permission +import lila.security.{ Permission, Granter } import lila.security.{ Firewall, UserSpy, Store => SecurityStore } import lila.user.{ User, UserRepo, Title, LightUserApi } @@ -133,10 +133,16 @@ final class ModApi( logApi.setEmail(mod, user.id) } - def setPermissions(mod: String, username: String, permissions: List[Permission]): Funit = withUser(username) { user => - UserRepo.setRoles(user.id, permissions.map(_.name)) >> { - lilaBus.publish(lila.hub.actorApi.mod.SetPermissions(user.id, permissions.map(_.name)), 'setPermissions) - logApi.setPermissions(mod, user.id, permissions) + def setPermissions(mod: Mod, username: String, permissions: Set[Permission]): Funit = withUser(username) { user => + val finalPermissions = Permission(user.roles).filter { p => + // only remove permissions the mod can actually grant + permissions.contains(p) || !Granter.canGrant(mod.user, p) + } ++ + // only add permissions the mod can actually grant + permissions.filter(Granter.canGrant(mod.user, _)) + UserRepo.setRoles(user.id, finalPermissions.map(_.name).toList) >> { + lilaBus.publish(lila.hub.actorApi.mod.SetPermissions(user.id, finalPermissions.map(_.name).toList), 'setPermissions) + logApi.setPermissions(mod, user.id, permissions.toList) } } diff --git a/modules/mod/src/main/ModlogApi.scala b/modules/mod/src/main/ModlogApi.scala index 4a39cf5432..a54a0fa7a8 100644 --- a/modules/mod/src/main/ModlogApi.scala +++ b/modules/mod/src/main/ModlogApi.scala @@ -105,8 +105,8 @@ final class ModlogApi(coll: Coll) { Modlog(mod, user.some, Modlog.chatTimeout, details = reason.some) } - def setPermissions(mod: String, user: String, permissions: List[Permission]) = add { - Modlog(mod, user.some, Modlog.permissions, details = permissions.mkString(", ").some) + def setPermissions(mod: Mod, user: String, permissions: List[Permission]) = add { + Modlog(mod.id.value, user.some, Modlog.permissions, details = permissions.mkString(", ").some) } def reportban(mod: Mod, sus: Suspect, v: Boolean) = add { diff --git a/modules/mod/src/main/UserSearch.scala b/modules/mod/src/main/UserSearch.scala index 2662f5cc49..d9d1ee3027 100644 --- a/modules/mod/src/main/UserSearch.scala +++ b/modules/mod/src/main/UserSearch.scala @@ -20,9 +20,9 @@ final class UserSearch( case "regex" => userColl.find($doc( F.watchList -> true, $or( - F.id $regex query.q, - F.email $regex query.q, - F.prevEmail $regex query.q + F.id $regex query.q.toLowerCase, + F.email.$regex(query.q, "i"), + F.prevEmail.$regex(query.q, "i") ) )).hint($doc(F.watchList -> 1)) .cursor[User](ReadPreference.secondaryPreferred) diff --git a/modules/oauth/src/main/OAuthScope.scala b/modules/oauth/src/main/OAuthScope.scala index 6bf6dadd23..542887f9ba 100644 --- a/modules/oauth/src/main/OAuthScope.scala +++ b/modules/oauth/src/main/OAuthScope.scala @@ -24,6 +24,10 @@ object OAuthScope { case object Write extends OAuthScope("tournament:write", "Create tournaments") } + object Puzzle { + case object Read extends OAuthScope("puzzle:read", "Read puzzle activity") + } + object Bot { case object Play extends OAuthScope("bot:play", "Play as a bot") } @@ -37,6 +41,7 @@ object OAuthScope { Email.Read, Challenge.Read, Challenge.Write, Tournament.Write, + Puzzle.Read, Bot.Play ) diff --git a/modules/pool/src/main/MatchMaking.scala b/modules/pool/src/main/MatchMaking.scala index 8d5a9f9b34..0b5edac9b1 100644 --- a/modules/pool/src/main/MatchMaking.scala +++ b/modules/pool/src/main/MatchMaking.scala @@ -44,7 +44,7 @@ object MatchMaking { } // score bonus based on how many waves the member missed - private def missBonus(p: PoolMember) = (p.misses * 20) atMost 500 + private def missBonus(p: PoolMember) = (p.misses * 15) atMost 400 // big malus if players have conflicting rating ranges private def rangeMalus(a: PoolMember, b: PoolMember) = diff --git a/modules/pref/src/main/DataForm.scala b/modules/pref/src/main/DataForm.scala index 2e30266fe8..cbba3c5e9b 100644 --- a/modules/pref/src/main/DataForm.scala +++ b/modules/pref/src/main/DataForm.scala @@ -5,36 +5,46 @@ import play.api.data.Forms._ object DataForm { + private def containedIn(choices: Seq[(Int, String)]): Int => Boolean = + choice => choices.exists(_._1 == choice) + + private def checkedNumber(choices: Seq[(Int, String)]) = + number.verifying(containedIn(choices)) + + private lazy val booleanNumber = + number.verifying(Pref.BooleanPref.verify) + val pref = Form(mapping( "display" -> mapping( "animation" -> number.verifying(Set(0, 1, 2, 3) contains _), - "captured" -> number.verifying(Pref.BooleanPref.verify), - "highlight" -> number.verifying(Pref.BooleanPref.verify), - "destination" -> number.verifying(Pref.BooleanPref.verify), - "coords" -> number.verifying(Pref.Coords.choices.toMap contains _), - "replay" -> number.verifying(Pref.Replay.choices.toMap contains _), - "pieceNotation" -> optional(number.verifying(Pref.BooleanPref.verify)), - "zen" -> optional(number.verifying(Pref.BooleanPref.verify)), - "blindfold" -> number.verifying(Pref.Blindfold.choices.toMap contains _) + "captured" -> booleanNumber, + "highlight" -> booleanNumber, + "destination" -> booleanNumber, + "coords" -> checkedNumber(Pref.Coords.choices), + "replay" -> checkedNumber(Pref.Replay.choices), + "pieceNotation" -> optional(booleanNumber), + "zen" -> optional(booleanNumber), + "resizeHandle" -> optional(checkedNumber(Pref.ResizeHandle.choices)), + "blindfold" -> checkedNumber(Pref.Blindfold.choices) )(DisplayData.apply)(DisplayData.unapply), "behavior" -> mapping( "moveEvent" -> optional(number.verifying(Set(0, 1, 2) contains _)), - "premove" -> number.verifying(Pref.BooleanPref.verify), - "takeback" -> number.verifying(Pref.Takeback.choices.toMap contains _), - "autoQueen" -> number.verifying(Pref.AutoQueen.choices.toMap contains _), - "autoThreefold" -> number.verifying(Pref.AutoThreefold.choices.toMap contains _), - "submitMove" -> number.verifying(Pref.SubmitMove.choices.toMap contains _), - "confirmResign" -> number.verifying(Pref.ConfirmResign.choices.toMap contains _), - "keyboardMove" -> optional(number.verifying(Pref.BooleanPref.verify)), - "rookCastle" -> optional(number.verifying(Pref.BooleanPref.verify)) + "premove" -> booleanNumber, + "takeback" -> checkedNumber(Pref.Takeback.choices), + "autoQueen" -> checkedNumber(Pref.AutoQueen.choices), + "autoThreefold" -> checkedNumber(Pref.AutoThreefold.choices), + "submitMove" -> checkedNumber(Pref.SubmitMove.choices), + "confirmResign" -> checkedNumber(Pref.ConfirmResign.choices), + "keyboardMove" -> optional(booleanNumber), + "rookCastle" -> optional(booleanNumber) )(BehaviorData.apply)(BehaviorData.unapply), - "clockTenths" -> number.verifying(Pref.ClockTenths.choices.toMap contains _), - "clockBar" -> number.verifying(Pref.BooleanPref.verify), - "clockSound" -> number.verifying(Pref.BooleanPref.verify), - "follow" -> number.verifying(Pref.BooleanPref.verify), - "challenge" -> number.verifying(Pref.Challenge.choices.toMap contains _), - "message" -> number.verifying(Pref.Message.choices.toMap contains _), - "studyInvite" -> optional(number.verifying(Pref.StudyInvite.choices.toMap contains _)), + "clockTenths" -> checkedNumber(Pref.ClockTenths.choices), + "clockBar" -> booleanNumber, + "clockSound" -> booleanNumber, + "follow" -> booleanNumber, + "challenge" -> checkedNumber(Pref.Challenge.choices), + "message" -> checkedNumber(Pref.Message.choices), + "studyInvite" -> optional(checkedNumber(Pref.StudyInvite.choices)), "insightShare" -> number.verifying(Set(0, 1, 2) contains _) )(PrefData.apply)(PrefData.unapply)) @@ -47,6 +57,7 @@ object DataForm { replay: Int, pieceNotation: Option[Int], zen: Option[Int], + resizeHandle: Option[Int], blindfold: Int ) @@ -99,6 +110,7 @@ object DataForm { captured = display.captured == 1, keyboardMove = behavior.keyboardMove | pref.keyboardMove, zen = display.zen | pref.zen, + resizeHandle = display.resizeHandle | pref.resizeHandle, rookCastle = behavior.rookCastle | pref.rookCastle, pieceNotation = display.pieceNotation | pref.pieceNotation, moveEvent = behavior.moveEvent | pref.moveEvent @@ -116,6 +128,7 @@ object DataForm { captured = if (pref.captured) 1 else 0, blindfold = pref.blindfold, zen = pref.zen.some, + resizeHandle = pref.resizeHandle.some, pieceNotation = pref.pieceNotation.some ), behavior = BehaviorData( diff --git a/modules/pref/src/main/Pref.scala b/modules/pref/src/main/Pref.scala index 1b7b4deb11..ec16d44ffd 100644 --- a/modules/pref/src/main/Pref.scala +++ b/modules/pref/src/main/Pref.scala @@ -38,6 +38,7 @@ case class Pref( rookCastle: Int, moveEvent: Int, pieceNotation: Int, + resizeHandle: Int, tags: Map[String, String] = Map.empty ) { @@ -53,6 +54,7 @@ case class Pref( def realSoundSet = SoundSet(soundSet) def coordColorName = Color.choices.toMap.get(coordColor).fold("random")(_.toLowerCase) + def coordsClass = Coords classOf coords def hasSeenVerifyTitle = tags contains Tag.verifyTitle @@ -87,11 +89,13 @@ case class Pref( def isZen = zen == Zen.YES + def is2d = !is3d + // atob("aHR0cDovL2NoZXNzLWNoZWF0LmNvbS9ob3dfdG9fY2hlYXRfYXRfbGljaGVzcy5odG1s") def botCompatible = theme == "brown" && pieceSet == "cburnett" && - !is3d && + is2d && animation == Animation.NONE && highlight && coords == Coords.OUTSIDE @@ -256,6 +260,12 @@ object Pref { INSIDE -> "Inside the board", OUTSIDE -> "Outside the board" ) + + def classOf(v: Int) = v match { + case INSIDE => "in" + case OUTSIDE => "out" + case _ => "no" + } } object Replay { @@ -322,6 +332,18 @@ object Pref { ) } + object ResizeHandle { + val NEVER = 0 + val INITIAL = 1 + val ALWAYS = 2 + + val choices = Seq( + NEVER -> "Never", + INITIAL -> "On initial position", + ALWAYS -> "Always" + ) + } + object Zen extends BooleanPref { } @@ -350,7 +372,7 @@ object Pref { follow = true, highlight = true, destination = true, - coords = Coords.OUTSIDE, + coords = Coords.INSIDE, replay = Replay.ALWAYS, clockTenths = ClockTenths.LOWTIME, challenge = Challenge.ALWAYS, @@ -365,6 +387,7 @@ object Pref { rookCastle = RookCastle.YES, moveEvent = MoveEvent.BOTH, pieceNotation = PieceNotation.SYMBOL, + resizeHandle = ResizeHandle.INITIAL, tags = Map.empty ) diff --git a/modules/pref/src/main/PrefApi.scala b/modules/pref/src/main/PrefApi.scala index 87a2ab1db9..3ef0eab141 100644 --- a/modules/pref/src/main/PrefApi.scala +++ b/modules/pref/src/main/PrefApi.scala @@ -64,6 +64,7 @@ final class PrefApi( zen = r.getD("zen", Pref.default.zen), rookCastle = r.getD("rookCastle", Pref.default.rookCastle), pieceNotation = r.getD("pieceNotation", Pref.default.pieceNotation), + resizeHandle = r.getD("resizeHandle", Pref.default.resizeHandle), moveEvent = r.getD("moveEvent", Pref.default.moveEvent), tags = r.getD("tags", Pref.default.tags) ) @@ -106,6 +107,7 @@ final class PrefApi( "rookCastle" -> o.rookCastle, "moveEvent" -> o.moveEvent, "pieceNotation" -> o.pieceNotation, + "resizeHandle" -> o.resizeHandle, "tags" -> o.tags ) } @@ -144,18 +146,18 @@ final class PrefApi( def followables(userIds: List[String]): Fu[List[Boolean]] = followableIds(userIds) map { followables => userIds map followables.contains } - def setPref(pref: Pref, notifyChange: Boolean): Funit = + def setPref(pref: Pref): Funit = coll.update($id(pref.id), pref, upsert = true).void >>- { cache refresh pref.id } - def setPref(user: User, change: Pref => Pref, notifyChange: Boolean): Funit = - getPref(user) map change flatMap { setPref(_, notifyChange) } + def setPref(user: User, change: Pref => Pref): Funit = + getPref(user) map change flatMap setPref - def setPref(userId: String, change: Pref => Pref, notifyChange: Boolean): Funit = - getPref(userId) map change flatMap { setPref(_, notifyChange) } + def setPref(userId: String, change: Pref => Pref): Funit = + getPref(userId) map change flatMap setPref - def setPrefString(user: User, name: String, value: String, notifyChange: Boolean): Funit = + def setPrefString(user: User, name: String, value: String): Funit = getPref(user) map { _.set(name, value) } flatten - s"Bad pref ${user.id} $name -> $value" flatMap { setPref(_, notifyChange) } + s"Bad pref ${user.id} $name -> $value" flatMap setPref } diff --git a/modules/pref/src/main/SoundSet.scala b/modules/pref/src/main/SoundSet.scala index 314190db76..64405d363f 100644 --- a/modules/pref/src/main/SoundSet.scala +++ b/modules/pref/src/main/SoundSet.scala @@ -19,7 +19,8 @@ object SoundSet { new SoundSet("sfx", "SFX"), new SoundSet("futuristic", "Futuristic"), new SoundSet("robot", "Robot"), - new SoundSet("music", "Pentatonic") + new SoundSet("music", "Pentatonic"), + new SoundSet("speech", "Speech") ) lazy val allByKey = list map { c => c.key -> c } toMap diff --git a/modules/puzzle/src/main/Env.scala b/modules/puzzle/src/main/Env.scala index 11686e65e7..dce9d63b40 100644 --- a/modules/puzzle/src/main/Env.scala +++ b/modules/puzzle/src/main/Env.scala @@ -77,6 +77,11 @@ final class Env( system.scheduler ) + lazy val activity = new PuzzleActivity( + puzzleColl = puzzleColl, + roundColl = roundColl + )(system) + def cli = new lila.common.Cli { def process = { case "puzzle" :: "disable" :: id :: Nil => parseIntOption(id) ?? { id => diff --git a/modules/puzzle/src/main/PuzzleActivity.scala b/modules/puzzle/src/main/PuzzleActivity.scala new file mode 100644 index 0000000000..a3e38aac53 --- /dev/null +++ b/modules/puzzle/src/main/PuzzleActivity.scala @@ -0,0 +1,88 @@ +package lila.puzzle + +import org.joda.time.DateTime +import play.api.libs.iteratee._ +import play.api.libs.json._ +import reactivemongo.api.ReadPreference +import reactivemongo.play.iteratees.cursorProducer +import scala.concurrent.duration._ + +import lila.common.MaxPerSecond +import lila.db.dsl._ +import lila.user.User + +final class PuzzleActivity( + puzzleColl: Coll, + roundColl: Coll +)(implicit system: akka.actor.ActorSystem) { + + import PuzzleActivity._ + import Round.RoundBSONHandler + + def stream(config: Config): Enumerator[String] = { + + val selector = $doc("_id" $startsWith config.user.id) + + val query = roundColl.find(selector).sort($sort desc "_id") + + val infinite = query.copy(options = query.options.batchSize(config.perSecond.value)) + .cursor[Round](ReadPreference.secondaryPreferred) + .bulkEnumerator() &> + Enumeratee.mapM[Iterator[Round]].apply[Seq[JsObject]] { rounds => + enrich(rounds.toSeq) + } &> + lila.common.Iteratee.delay(1 second) &> + Enumeratee.mapConcat(_.toSeq) + + val stream = config.max.fold(infinite) { max => + // I couldn't figure out how to do it properly :( :( :( + // the nb can't be set as bulkEnumerator(nb) + // because games are further filtered after being fetched + var nb = 0 + infinite &> Enumeratee.mapInput { in => + nb = nb + 1 + if (nb <= max) in + else Input.EOF + } + } + + stream &> formatter + } + + private def enrich(rounds: Seq[Round]): Fu[Seq[JsObject]] = + puzzleColl.primitiveMap[Int, Double]( + ids = rounds.map(_.id.puzzleId).toSeq, + field = "perf.gl.r", + fieldExtractor = obj => for { + perf <- obj.getAs[Bdoc]("perf") + gl <- perf.getAs[Bdoc]("gl") + rating <- gl.getAs[Double]("r") + } yield rating + ) map { ratings => + rounds.toSeq flatMap { round => + ratings get round.id.puzzleId map { puzzleRating => + Json.obj( + "id" -> round.id.puzzleId, + "date" -> round.date, + "rating" -> round.rating, + "ratingDiff" -> round.ratingDiff, + "puzzleRating" -> puzzleRating.toInt + ) + } + } + } + + private def formatter = + Enumeratee.map[JsObject].apply[String] { json => + s"${Json.stringify(json)}\n" + } +} + +object PuzzleActivity { + + case class Config( + user: User, + max: Option[Int] = None, + perSecond: MaxPerSecond + ) +} diff --git a/modules/rating/src/main/Glicko.scala b/modules/rating/src/main/Glicko.scala index 7a44960094..6872562ef4 100644 --- a/modules/rating/src/main/Glicko.scala +++ b/modules/rating/src/main/Glicko.scala @@ -44,6 +44,8 @@ case class Glicko( volatility = (volatility + other.volatility) / 2 ) + def display = s"$intRating${provisional ?? "?"}" + override def toString = s"$intRating $intDeviation" } diff --git a/modules/relation/src/main/Env.scala b/modules/relation/src/main/Env.scala index 50512f7e89..2c5a2b0eb8 100644 --- a/modules/relation/src/main/Env.scala +++ b/modules/relation/src/main/Env.scala @@ -20,11 +20,12 @@ final class Env( val CollectionRelation = config getString "collection.relation" val ActorNotifyFreq = config duration "actor.notify_freq" val ActorName = config getString "actor.name" - val MaxFollow = config getInt "limit.follow" val MaxBlock = config getInt "limit.block" } import settings._ + val MaxFollow = config getInt "limit.follow" + private[relation] val coll = db(CollectionRelation) lazy val api = new RelationApi( diff --git a/modules/relation/src/main/RelationApi.scala b/modules/relation/src/main/RelationApi.scala index 2e623e5a77..252a0e8d3f 100644 --- a/modules/relation/src/main/RelationApi.scala +++ b/modules/relation/src/main/RelationApi.scala @@ -1,7 +1,7 @@ package lila.relation -import scala.concurrent.duration._ import akka.actor.ActorSelection +import scala.concurrent.duration._ import lila.db.dsl._ import lila.db.paginator._ @@ -71,6 +71,8 @@ final class RelationApi( def countFollowing(userId: ID) = countFollowingCache get userId + def reachedMaxFollowing(userId: ID): Fu[Boolean] = countFollowingCache get userId map (maxFollow <=) + private val countFollowersCache = asyncCache.clearable[ID, Int]( name = "relation.count.followers", f = userId => coll.countSel($doc("u2" -> userId, "r" -> Follow)), @@ -106,30 +108,28 @@ final class RelationApi( sort = $empty ).map(_.userId) - def follow(u1: ID, u2: ID): Funit = (u1 != u2) ?? { - followable(u2) flatMap { - case false => funit - case true => fetchRelation(u1, u2) zip fetchRelation(u2, u1) flatMap { - case (Some(Follow), _) => funit - case (_, Some(Block)) => funit - case _ => RelationRepo.follow(u1, u2) >> limitFollow(u1) >>- { - countFollowersCache.update(u2, 1+) - countFollowingCache.update(u1, 1+) - reloadOnlineFriends(u1, u2) - timeline ! Propagate(FollowUser(u1, u2)).toFriendsOf(u1).toUsers(List(u2)) - bus.publish(lila.hub.actorApi.relation.Follow(u1, u2), 'relation) - lila.mon.relation.follow() - } + def follow(u1: ID, u2: ID): Funit = (u1 != u2) ?? followable(u2).flatMap { + case false => funit + case true => fetchRelation(u1, u2) zip fetchRelation(u2, u1) flatMap { + case (Some(Follow), _) => funit + case (_, Some(Block)) => funit + case _ => RelationRepo.follow(u1, u2) >> limitFollow(u1) >>- { + countFollowersCache.update(u2, 1+) + countFollowingCache.update(u1, prev => (prev + 1) atMost maxFollow) + reloadOnlineFriends(u1, u2) + timeline ! Propagate(FollowUser(u1, u2)).toFriendsOf(u1).toUsers(List(u2)) + bus.publish(lila.hub.actorApi.relation.Follow(u1, u2), 'relation) + lila.mon.relation.follow() } } } private def limitFollow(u: ID) = countFollowing(u) flatMap { nb => - (nb >= maxFollow) ?? RelationRepo.drop(u, true, nb - maxFollow + 1) + (nb > maxFollow) ?? RelationRepo.drop(u, true, nb - maxFollow) } private def limitBlock(u: ID) = countBlocking(u) flatMap { nb => - (nb >= maxBlock) ?? RelationRepo.drop(u, false, nb - maxBlock + 1) + (nb > maxBlock) ?? RelationRepo.drop(u, false, nb - maxBlock) } def block(u1: ID, u2: ID): Funit = (u1 != u2) ?? { diff --git a/modules/round/src/main/Env.scala b/modules/round/src/main/Env.scala index 4fe2650b3d..26a65b7e01 100644 --- a/modules/round/src/main/Env.scala +++ b/modules/round/src/main/Env.scala @@ -8,7 +8,7 @@ import scala.concurrent.duration._ import actorApi.{ GetSocketStatus, SocketStatus } import lila.game.{ Game, GameRepo, Pov } -import lila.hub.actorApi.DeployPost +import lila.hub.actorApi.{ DeployPost, Announce } import lila.hub.actorApi.map.Tell import lila.hub.actorApi.round.{ Abort, Resign, FishnetPlay } import lila.hub.actorApi.socket.HasUserId diff --git a/modules/round/src/main/JsonView.scala b/modules/round/src/main/JsonView.scala index 6b0d435dff..556606be1b 100644 --- a/modules/round/src/main/JsonView.scala +++ b/modules/round/src/main/JsonView.scala @@ -83,6 +83,7 @@ final class JsonView( "pref" -> Json.obj( "animationDuration" -> animationDuration(pov, pref), "coords" -> pref.coords, + "resizeHandle" -> pref.resizeHandle, "replay" -> pref.replay, "autoQueen" -> (if (pov.game.variant == chess.variant.Antichess) Pref.AutoQueen.NEVER else pref.autoQueen), "clockTenths" -> pref.clockTenths, diff --git a/modules/round/src/main/TreeBuilder.scala b/modules/round/src/main/TreeBuilder.scala index 5cd7795513..ab3a1b0f24 100644 --- a/modules/round/src/main/TreeBuilder.scala +++ b/modules/round/src/main/TreeBuilder.scala @@ -44,7 +44,7 @@ object TreeBuilder { withFlags: WithFlags, clocks: Option[Vector[Centis]] ): Root = { - val withClocks = withFlags.clocks ?? clocks + val withClocks: Option[Vector[Centis]] = withFlags.clocks ?? clocks chess.Replay.gameMoveWhileValid(pgnMoves, initialFen.value, variant) match { case (init, games, error) => error foreach logChessError(id) @@ -61,7 +61,7 @@ object TreeBuilder { fen = fen, check = init.situation.check, opening = openingOf(fen), - clock = withFlags.clocks ?? init.clock.map(_.limit), + clock = withClocks.flatMap(_.headOption), crazyData = init.situation.board.crazyData, eval = infos lift 0 map makeEval ) @@ -76,7 +76,7 @@ object TreeBuilder { fen = fen, check = g.situation.check, opening = openingOf(fen), - clock = withClocks ?? (_ lift (g.turns - init.turns - 1)), + clock = withClocks flatMap (_ lift (g.turns - init.turns - 1)), crazyData = g.situation.board.crazyData, eval = info map makeEval, glyphs = Glyphs.fromList(advice.map(_.judgment.glyph).toList), diff --git a/modules/security/src/main/AutomaticEmail.scala b/modules/security/src/main/AutomaticEmail.scala index 038ed620e5..92ed04e68b 100644 --- a/modules/security/src/main/AutomaticEmail.scala +++ b/modules/security/src/main/AutomaticEmail.scala @@ -1,9 +1,9 @@ package lila.security -import play.twirl.api.Html +import scalatags.Text.all._ import lila.common.{ Lang, EmailAddress } -import lila.common.String.html.nl2brUnsafe +import lila.i18n.I18nKeys.{ emails => trans } import lila.user.{ User, UserRepo } final class AutomaticEmail( @@ -11,6 +11,25 @@ final class AutomaticEmail( baseUrl: String ) { + import Mailgun.html._ + + def welcome(user: User, email: EmailAddress)(implicit lang: Lang): Funit = { + val profileUrl = s"$baseUrl/@/${user.username}" + val editUrl = s"$baseUrl/account/profile" + mailgun send Mailgun.Message( + to = email, + subject = trans.welcome_subject.literalTxtTo(lang, List(user.username)), + text = s""" +${trans.welcome_text.literalTxtTo(lang, List(profileUrl, editUrl))} + +${Mailgun.txt.serviceNote} +""", + htmlBody = standardEmail( + trans.welcome_text.literalTxtTo(lang, List(profileUrl, editUrl)) + ).some + ) + } + def onTitleSet(username: String)(implicit lang: Lang): Funit = for { user <- UserRepo named username flatten s"No such user $username" emailOption <- UserRepo email user.id @@ -38,11 +57,7 @@ $body ${Mailgun.txt.serviceNote} """, - htmlBody = Html(s""" -
    -

    ${nl2brUnsafe(body)}

    - ${Mailgun.html.serviceNote} -
    """).some + htmlBody = standardEmail(body).some ) } @@ -67,11 +82,7 @@ $body ${Mailgun.txt.serviceNote} """, - htmlBody = Html(s""" -
    -

    ${nl2brUnsafe(body)}

    - ${Mailgun.html.serviceNote} -
    """).some + htmlBody = standardEmail(body).some ) } } @@ -107,11 +118,7 @@ $body ${Mailgun.txt.serviceNote} """, - htmlBody = Html(s""" -
    -

    ${nl2brUnsafe(body)}

    - ${Mailgun.html.serviceNote} -
    """).some + htmlBody = standardEmail(body).some ) } } diff --git a/modules/security/src/main/DisposableEmailDomain.scala b/modules/security/src/main/DisposableEmailDomain.scala index cc7470899e..09d2dbdcf7 100644 --- a/modules/security/src/main/DisposableEmailDomain.scala +++ b/modules/security/src/main/DisposableEmailDomain.scala @@ -104,6 +104,6 @@ private object DisposableEmailDomain { "yahoo.com.br", "hotmail.com.br", "outlook.com.br", "uol.com.br", "bol.com.br", "terra.com.br", "ig.com.br", "itelefonica.com.br", "r7.com", "zipmail.com.br", "globo.com", "globomail.com", "oi.com.br", /* Domains without an A record */ - "cabletv.on.ca", "live.ca" + "cabletv.on.ca", "live.ca", "unitybox.de", "volki.at" ) } diff --git a/modules/security/src/main/EmailChange.scala b/modules/security/src/main/EmailChange.scala index 8ecad8f80e..6c50e1a3ec 100644 --- a/modules/security/src/main/EmailChange.scala +++ b/modules/security/src/main/EmailChange.scala @@ -1,10 +1,10 @@ package lila.security -import play.twirl.api.Html +import scalatags.Text.all._ import lila.common.{ Lang, EmailAddress } -import lila.user.{ User, UserRepo } import lila.i18n.I18nKeys.{ emails => trans } +import lila.user.{ User, UserRepo } final class EmailChange( mailgun: Mailgun, @@ -12,6 +12,8 @@ final class EmailChange( tokenerSecret: String ) { + import Mailgun.html._ + def send(user: User, email: EmailAddress)(implicit lang: Lang): Funit = tokener make TokenPayload(user.id, email).some flatMap { token => lila.mon.email.types.change() @@ -30,16 +32,12 @@ ${trans.common_orPaste.literalTxtTo(lang)} ${Mailgun.txt.serviceNote} """, - htmlBody = Html(s""" -
    -

    ${trans.emailChange_intro.literalHtmlTo(lang)}

    -

    ${trans.emailChange_click.literalHtmlTo(lang)}

    -
    - - ${Mailgun.html.url(url)} -
    - ${Mailgun.html.serviceNote} -
    """).some + htmlBody = emailMessage( + pDesc(trans.emailChange_intro.literalTo(lang)), + p(trans.emailChange_click.literalTo(lang)), + potentialAction(metaName("Change email address"), Mailgun.html.url(url)), + serviceNote + ).some ) } @@ -60,7 +58,7 @@ ${Mailgun.txt.serviceNote} case _ => none } def write(a: Option[TokenPayload]) = a ?? { - case TokenPayload(userId, email) => s"$userId$sep$email" + case TokenPayload(userId, EmailAddress(email)) => s"$userId$sep$email" } } diff --git a/modules/security/src/main/EmailConfirm.scala b/modules/security/src/main/EmailConfirm.scala index 423566a86b..6a87b94f0f 100644 --- a/modules/security/src/main/EmailConfirm.scala +++ b/modules/security/src/main/EmailConfirm.scala @@ -1,6 +1,6 @@ package lila.security -import play.twirl.api.Html +import scalatags.Text.all._ import lila.common.{ Lang, EmailAddress } import lila.i18n.I18nKeys.{ emails => trans } @@ -30,6 +30,8 @@ final class EmailConfirmMailgun( tokenerSecret: String ) extends EmailConfirm { + import Mailgun.html._ + def effective = true val maxTries = 3 @@ -51,20 +53,17 @@ ${trans.common_orPaste.literalTxtTo(lang)} ${Mailgun.txt.serviceNote} ${trans.emailConfirm_ignore.literalTxtTo(lang, List("https://lichess.org"))} """, - htmlBody = Html(s""" -
    -

    ${trans.emailConfirm_click.literalHtmlTo(lang)}

    -
    - - ${Mailgun.html.url(url)} -
    -
    - - ${trans.common_note.literalHtmlTo(lang, List(Mailgun.html.noteLink))} - ${trans.emailConfirm_ignore.literalHtmlTo(lang)} - -
    -
    """).some + htmlBody = emailMessage( + pDesc(trans.emailConfirm_click.literalTo(lang)), + potentialAction(metaName("Activate account"), Mailgun.html.url(url)), + publisher( + small( + trans.common_note.literalTo(lang, List(Mailgun.html.noteLink)), + " ", + trans.emailConfirm_ignore.literalTo(lang) + ) + ) + ).some ) } diff --git a/modules/security/src/main/Env.scala b/modules/security/src/main/Env.scala index f8cf13f693..4e110ddb92 100644 --- a/modules/security/src/main/Env.scala +++ b/modules/security/src/main/Env.scala @@ -138,11 +138,6 @@ final class Env( secret = LoginTokenSecret ) - lazy val welcomeEmail = new WelcomeEmail( - mailgun = mailgun, - baseUrl = NetBaseUrl - ) - lazy val automaticEmail = new AutomaticEmail( mailgun = mailgun, baseUrl = NetBaseUrl diff --git a/modules/security/src/main/Granter.scala b/modules/security/src/main/Granter.scala index ffa4922505..3cf0485661 100644 --- a/modules/security/src/main/Granter.scala +++ b/modules/security/src/main/Granter.scala @@ -9,4 +9,15 @@ object Granter { def apply(f: Permission.Selector)(user: User): Boolean = apply(f(Permission))(user) + + def canGrant(user: User, permission: Permission): Boolean = apply(_.SuperAdmin)(user) || { + apply(_.ChangePermission)(user) && + Set[Permission]( + Permission.Coach, + Permission.Developer, + Permission.PublicMod, + Permission.Verified, + Permission.Prismic + ).contains(permission) + } } diff --git a/modules/security/src/main/Mailgun.scala b/modules/security/src/main/Mailgun.scala index 37cae55575..e0e3b72899 100644 --- a/modules/security/src/main/Mailgun.scala +++ b/modules/security/src/main/Mailgun.scala @@ -1,13 +1,14 @@ package lila.security -import scala.concurrent.duration._ +import scala.concurrent.duration.{ span => _, _ } import akka.actor.ActorSystem import play.api.libs.ws.{ WS, WSAuthScheme } import play.api.Play.current -import play.twirl.api.Html +import scalatags.Text.all._ import lila.common.String.html.escapeHtml +import lila.common.String.html.nl2brUnsafe import lila.common.{ Lang, EmailAddress } import lila.i18n.I18nKeys.{ emails => trans } @@ -33,7 +34,7 @@ final class Mailgun( "subject" -> Seq(msg.subject), "text" -> Seq(msg.text) ) ++ msg.htmlBody.?? { body => - Map("html" -> Seq(Mailgun.html.wrap(msg.subject, body).body)) + Map("html" -> Seq(Mailgun.html.wrap(msg.subject, body).render)) }).void addFailureEffect { case e: java.net.ConnectException => lila.mon.http.mailgun.timeout() case _ => @@ -58,7 +59,7 @@ object Mailgun { to: EmailAddress, subject: String, text: String, - htmlBody: Option[Html] = none, + htmlBody: Option[Frag] = none, from: Option[String] = none, replyTo: Option[String] = none, tag: Option[String] = none, @@ -67,45 +68,64 @@ object Mailgun { object txt { - def serviceNote(implicit lang: Lang) = s""" -${trans.common_note.literalHtmlTo(lang, List("https://lichess.org"))} + def serviceNote(implicit lang: Lang): String = s""" +${trans.common_note.literalTo(lang, List("https://lichess.org")).render} -${trans.common_contact.literalHtmlTo(lang, List("https://lichess.org/contact"))}""" +${trans.common_contact.literalTo(lang, List("https://lichess.org/contact")).render}""" } object html { - val noteLink = Html { - """""" - } - val noteContact = Html { - """""" - } + val itemscope = attr("itemscope").empty + val itemtype = attr("itemtype") + val itemprop = attr("itemprop") + val emailMessage = div(itemscope, itemtype := "http://schema.org/EmailMessage") + val pDesc = p(itemprop := "description") + val potentialAction = div(itemprop := "potentialAction", itemscope, itemtype := "http://schema.org/ViewAction") + def metaName(cont: String) = meta(itemprop := "name", content := cont) + val publisher = div(itemprop := "publisher", itemscope, itemtype := "http://schema.org/Organization") + val noteContact = a(itemprop := "url", href := "https://lichess.org/contact")( + span(itemprop := "name")("lichess.org/contact") + ) - def serviceNote(implicit lang: Lang) = s""" -
    - ${trans.common_note.literalHtmlTo(lang, List(noteLink))} ${trans.common_contact.literalHtmlTo(lang, List(noteContact))} -
    -""" + def serviceNote(implicit lang: Lang) = publisher( + small( + trans.common_note.literalTo(lang, List(Mailgun.html.noteLink)), + " ", + trans.common_contact.literalTo(lang, List(noteContact)) + ) + ) - def url(u: String)(implicit lang: Lang) = s""" - -

    $u

    -

    ${trans.common_orPaste.literalHtmlTo(lang)}

    -""" + def standardEmail(body: String)(implicit lang: Lang): Frag = + emailMessage( + pDesc(nl2brUnsafe(body)), + publisher + ) - private[Mailgun] def wrap(subject: String, body: Html) = Html { - s""" + val noteLink = a( + itemprop := "url", + href := "https://lichess.org/" + )(span(itemprop := "name")("lichess.org")) + + def url(u: String)(implicit lang: Lang) = frag( + meta(itemprop := "url", content := u), + p(a(itemprop := "target", href := u)(u)), + p(trans.common_orPaste.literalTo(lang)) + ) + + private[Mailgun] def wrap(subject: String, body: Frag): Frag = frag( + raw(s""" ${escapeHtml(subject)} - - $body + """), + body, + raw(""" -""" - } +""") + ) } } diff --git a/modules/security/src/main/PasswordReset.scala b/modules/security/src/main/PasswordReset.scala index 8ac91f1daa..19d5c7ff5a 100644 --- a/modules/security/src/main/PasswordReset.scala +++ b/modules/security/src/main/PasswordReset.scala @@ -1,10 +1,10 @@ package lila.security -import play.twirl.api.Html +import scalatags.Text.all._ import lila.common.{ Lang, EmailAddress } -import lila.user.{ User, UserRepo } import lila.i18n.I18nKeys.{ emails => trans } +import lila.user.{ User, UserRepo } final class PasswordReset( mailgun: Mailgun, @@ -12,6 +12,8 @@ final class PasswordReset( tokenerSecret: String ) { + import Mailgun.html._ + def send(user: User, email: EmailAddress)(implicit lang: Lang): Funit = tokener make user.id flatMap { token => lila.mon.email.types.resetPassword() @@ -30,16 +32,12 @@ ${trans.common_orPaste.literalTxtTo(lang)} ${Mailgun.txt.serviceNote} """, - htmlBody = Html(s""" -
    -

    ${trans.passwordReset_intro.literalHtmlTo(lang)}

    -

    ${trans.passwordReset_clickOrIgnore.literalHtmlTo(lang)}

    -
    - - ${Mailgun.html.url(url)} -
    - ${Mailgun.html.serviceNote} -
    """).some + htmlBody = emailMessage( + pDesc(trans.passwordReset_intro.literalTo(lang)), + p(trans.passwordReset_clickOrIgnore.literalTo(lang)), + potentialAction(metaName("Reset password"), Mailgun.html.url(url)), + serviceNote + ).some ) } diff --git a/modules/security/src/main/Permission.scala b/modules/security/src/main/Permission.scala index 030fcabb35..5a1137831c 100644 --- a/modules/security/src/main/Permission.scala +++ b/modules/security/src/main/Permission.scala @@ -28,7 +28,6 @@ object Permission { case object SeeReport extends Permission("ROLE_SEE_REPORT") case object ModLog extends Permission("ROLE_MOD_LOG") case object SeeInsight extends Permission("ROLE_SEE_INSIGHT") - case object StreamConfig extends Permission("ROLE_STREAM_CONFIG") case object PracticeConfig extends Permission("ROLE_PRACTICE_CONFIG") case object Beta extends Permission("ROLE_BETA") case object MessageAnyone extends Permission("ROLE_MESSAGE_ANYONE") @@ -55,7 +54,12 @@ object Permission { case object Verified extends Permission("ROLE_VERIFIED") case object Prismic extends Permission("ROLE_PRISMIC") + case object LichessTeam extends Permission("ROLE_LICHESS_TEAM", List( + Prismic + )) + case object Hunter extends Permission("ROLE_HUNTER", List( + LichessTeam, ViewBlurs, MarkEngine, MarkBooster, UserSpy, UserEvaluate, SeeReport, ModLog, SeeInsight, UserSearch, ModNote, RemoveRanking, ModMessage @@ -63,19 +67,19 @@ object Permission { case object Admin extends Permission("ROLE_ADMIN", List( Hunter, ModerateForum, IpBan, CloseAccount, ReopenAccount, ViewPrivateComms, - ChatTimeout, Shadowban, SetTitle, SetEmail, StreamConfig, + ChatTimeout, Shadowban, SetTitle, SetEmail, MessageAnyone, ManageTeam, TerminateTournament, ManageTournament, ManageEvent, PracticeConfig, RemoveRanking, ReportBan, DisapproveCoachReview, - Relay, Streamers, DisableTwoFactor, Prismic + Relay, Streamers, DisableTwoFactor, ChangePermission )) case object SuperAdmin extends Permission("ROLE_SUPER_ADMIN", List( - Admin, ChangePermission, Developer, Impersonate, PayPal, Cli, Settings + Admin, Developer, Impersonate, PayPal, Cli, Settings )) lazy val allButSuperAdmin: List[Permission] = List( Admin, Hunter, Shadowban, ChatTimeout, ChangePermission, ViewBlurs, ModerateForum, - UserSpy, MarkEngine, MarkBooster, IpBan, StreamConfig, PracticeConfig, + UserSpy, MarkEngine, MarkBooster, IpBan, PracticeConfig, Beta, MessageAnyone, UserSearch, ManageTeam, TerminateTournament, ManageTournament, ManageEvent, PublicMod, Developer, Coach, ModNote, RemoveRanking, ReportBan, Impersonate, Relay, Cli, Settings, Streamers, DisableTwoFactor, Verified, Prismic @@ -87,7 +91,7 @@ object Permission { def apply(name: String): Option[Permission] = allByName get name - def apply(names: List[String]): List[Permission] = names flatMap { apply(_) } + def apply(names: List[String]): Set[Permission] = names flatMap { apply(_) } toSet def exists(name: String) = allByName contains name } diff --git a/modules/security/src/main/WelcomeEmail.scala b/modules/security/src/main/WelcomeEmail.scala deleted file mode 100644 index 482931a57f..0000000000 --- a/modules/security/src/main/WelcomeEmail.scala +++ /dev/null @@ -1,32 +0,0 @@ -package lila.security - -import play.twirl.api.Html - -import lila.common.{ Lang, EmailAddress } -import lila.user.User -import lila.i18n.I18nKeys.{ emails => trans } - -final class WelcomeEmail( - mailgun: Mailgun, - baseUrl: String -) { - - def apply(user: User, email: EmailAddress)(implicit lang: Lang): Funit = { - val profileUrl = s"$baseUrl/@/${user.username}" - val editUrl = s"$baseUrl/account/profile" - mailgun send Mailgun.Message( - to = email, - subject = trans.welcome_subject.literalTxtTo(lang, List(user.username)), - text = s""" -${trans.welcome_text.literalTxtTo(lang, List(profileUrl, editUrl))} - -${Mailgun.txt.serviceNote} -""", - htmlBody = Html(s""" -
    -

    ${trans.welcome_text.literalHtmlTo(lang, List(profileUrl, editUrl))}

    - ${Mailgun.html.serviceNote} -
    """).some - ) - } -} diff --git a/modules/simul/src/main/DataForm.scala b/modules/simul/src/main/DataForm.scala index ee02990db1..8ce21ce544 100644 --- a/modules/simul/src/main/DataForm.scala +++ b/modules/simul/src/main/DataForm.scala @@ -36,14 +36,18 @@ final class DataForm { chess.variant.KingOfTheHill.id, chess.variant.ThreeCheck.id, chess.variant.Antichess.id, chess.variant.Atomic.id, chess.variant.Horde.id, chess.variant.RacingKings.id, chess.variant.Crazyhouse.id) contains _) }.verifying("At least one variant", _.nonEmpty), - "color" -> stringIn(colorChoices) + "color" -> stringIn(colorChoices), + "text" -> text )(SimulSetup.apply)(SimulSetup.unapply)) fill SimulSetup( clockTime = clockTimeDefault, clockIncrement = clockIncrementDefault, clockExtra = clockExtraDefault, variants = List(chess.variant.Standard.id), - color = colorDefault + color = colorDefault, + text = "" ) + + def setText = Form(single("text" -> text)) } case class SimulSetup( @@ -51,5 +55,6 @@ case class SimulSetup( clockIncrement: Int, clockExtra: Int, variants: List[Int], - color: String + color: String, + text: String ) diff --git a/modules/simul/src/main/JsonView.scala b/modules/simul/src/main/JsonView.scala index cc87d15951..38b1619e44 100644 --- a/modules/simul/src/main/JsonView.scala +++ b/modules/simul/src/main/JsonView.scala @@ -4,6 +4,7 @@ import play.api.libs.json._ import lila.common.LightUser import lila.game.{ Game, GameRepo } +import lila.user.User final class JsonView(getLightUser: LightUser.Getter) { @@ -15,7 +16,11 @@ final class JsonView(getLightUser: LightUser.Getter) { games <- fetchGames(simul) lightHost <- getLightUser(simul.hostId) applicants <- simul.applicants.sortBy(-_.player.rating).map(applicantJson).sequenceFu - pairings <- simul.pairings.sortBy(-_.player.rating).map(pairingJson(games, simul.hostId)).sequenceFu + pairingOptions <- simul.pairings + .sortBy(-_.player.rating) + .map(pairingJson(games, simul.hostId)) + .sequenceFu + pairings = pairingOptions.flatten } yield Json.obj( "id" -> simul.id, "host" -> lightHost.map { host => @@ -36,7 +41,8 @@ final class JsonView(getLightUser: LightUser.Getter) { "isCreated" -> simul.isCreated, "isRunning" -> simul.isRunning, "isFinished" -> simul.isFinished, - "quote" -> lila.quote.Quote.one(simul.id) + "quote" -> lila.quote.Quote.one(simul.id), + "text" -> simul.text ) private def variantJson(speed: chess.Speed)(v: chess.variant.Variant) = Json.obj( @@ -65,7 +71,7 @@ final class JsonView(getLightUser: LightUser.Getter) { ) } - private def gameJson(hostId: String)(g: Game) = Json.obj( + private def gameJson(hostId: User.ID, g: Game) = Json.obj( "id" -> g.id, "status" -> g.status.id, "fen" -> (chess.format.Forsyth exportBoard g.board), @@ -73,15 +79,17 @@ final class JsonView(getLightUser: LightUser.Getter) { "orient" -> g.playerByUserId(hostId).map(_.color) ) - private def pairingJson(games: List[Game], hostId: String)(p: SimulPairing): Fu[JsObject] = - playerJson(p.player) map { player => - Json.obj( - "player" -> player, - "hostColor" -> p.hostColor, - "winnerColor" -> p.winnerColor, - "wins" -> p.wins, // can't be normalized because BC - "game" -> games.find(_.id == p.gameId).map(gameJson(hostId)) - ) + private def pairingJson(games: List[Game], hostId: String)(p: SimulPairing): Fu[Option[JsObject]] = + games.find(_.id == p.gameId) ?? { game => + playerJson(p.player) map { player => + Json.obj( + "player" -> player, + "hostColor" -> p.hostColor, + "winnerColor" -> p.winnerColor, + "wins" -> p.wins, // can't be normalized because BC + "game" -> gameJson(hostId, game) + ).some + } } private implicit val colorWriter: Writes[chess.Color] = Writes { c => diff --git a/modules/simul/src/main/Simul.scala b/modules/simul/src/main/Simul.scala index f161ab9345..3aecb7e033 100644 --- a/modules/simul/src/main/Simul.scala +++ b/modules/simul/src/main/Simul.scala @@ -21,7 +21,8 @@ case class Simul( startedAt: Option[DateTime], finishedAt: Option[DateTime], hostSeenAt: Option[DateTime], - color: Option[String] + color: Option[String], + text: String ) { def id = _id @@ -148,7 +149,8 @@ object Simul { host: User, clock: SimulClock, variants: List[Variant], - color: String + color: String, + text: String ): Simul = Simul( _id = Random nextString 8, name = makeName(host), @@ -173,6 +175,7 @@ object Simul { startedAt = none, finishedAt = none, hostSeenAt = DateTime.now.some, - color = color.some + color = color.some, + text = text ) } diff --git a/modules/simul/src/main/SimulApi.scala b/modules/simul/src/main/SimulApi.scala index 7193d1fab6..05b4e92ab2 100644 --- a/modules/simul/src/main/SimulApi.scala +++ b/modules/simul/src/main/SimulApi.scala @@ -45,7 +45,8 @@ final class SimulApi( ), variants = setup.variants.flatMap { chess.variant.Variant(_) }, host = me, - color = setup.color + color = setup.color, + text = setup.text ) repo.createdByHostId(me.id) foreach { _.filter(_.isNotBrandNew).map(_.id).foreach(abort) @@ -130,6 +131,16 @@ final class SimulApi( } } + def setText(simulId: Simul.ID, text: String): Unit = { + Sequence(simulId) { + repo.find(simulId) flatMap { + _ ?? { simul => + repo.setText(simul, text) >>- socketReload(simulId) + } + } + } + } + def finishGame(game: Game): Unit = game.simulId foreach { simulId => Sequence(simulId) { repo.findStarted(simulId) flatMap { diff --git a/modules/simul/src/main/SimulRepo.scala b/modules/simul/src/main/SimulRepo.scala index d65cae24e1..50a1a4da19 100644 --- a/modules/simul/src/main/SimulRepo.scala +++ b/modules/simul/src/main/SimulRepo.scala @@ -7,12 +7,11 @@ import reactivemongo.core.commands._ import chess.Status import chess.variant.Variant import lila.db.BSON +import lila.db.BSON.BSONJodaDateTimeHandler import lila.db.dsl._ private[simul] final class SimulRepo(simulColl: Coll) { - import lila.db.BSON.BSONJodaDateTimeHandler - import reactivemongo.bson.Macros private implicit val SimulStatusBSONHandler = new BSONHandler[BSONInteger, SimulStatus] { def read(bsonInt: BSONInteger): SimulStatus = SimulStatus(bsonInt.value) err s"No such simul status: ${bsonInt.value}" def write(x: SimulStatus) = BSONInteger(x.id) @@ -108,6 +107,11 @@ private[simul] final class SimulRepo(simulColl: Coll) { $set("hostSeenAt" -> DateTime.now) ).void + def setText(simul: Simul, text: String) = simulColl.update( + $id(simul.id), + $set("text" -> text) + ).void + def cleanup = simulColl.remove( createdSelect ++ $doc( "createdAt" -> $doc("$lt" -> (DateTime.now minusMinutes 60)) diff --git a/modules/socket/src/main/SocketMap.scala b/modules/socket/src/main/SocketMap.scala index 83df3b15ed..63c64d54bb 100644 --- a/modules/socket/src/main/SocketMap.scala +++ b/modules/socket/src/main/SocketMap.scala @@ -1,7 +1,7 @@ package lila.socket -import scala.concurrent.duration._ import ornicar.scalalib.Random.approximatly +import scala.concurrent.duration._ import lila.hub.{ Trouper, TrouperMap } @@ -26,7 +26,14 @@ object SocketMap { system.scheduler.schedule(approximatly(0.1f)(12.seconds.toMillis).millis, broomFrequency) { trouperMap tellAll actorApi.Broom } - system.lilaBus.subscribeFun('shutdown) { case _ => trouperMap.killAll } + system.lilaBus.subscribeFuns( + 'shutdown -> { + case _ => trouperMap.killAll + }, + 'announce -> { + case m: lila.hub.actorApi.Announce => trouperMap tellAll m + } + ) trouperMap } diff --git a/modules/socket/src/main/SocketTrouper.scala b/modules/socket/src/main/SocketTrouper.scala index 258d85b181..e2adf982c4 100644 --- a/modules/socket/src/main/SocketTrouper.scala +++ b/modules/socket/src/main/SocketTrouper.scala @@ -8,7 +8,7 @@ import scala.concurrent.Promise import actorApi._ import chess.Centis import lila.common.LightUser -import lila.hub.actorApi.Deploy +import lila.hub.actorApi.{ Deploy, Announce } import lila.hub.actorApi.socket.HasUserId import lila.hub.Trouper import lila.memo.ExpireSetMemo @@ -56,6 +56,8 @@ abstract class SocketTrouper[M <: SocketMember]( case Resync(uid) => resync(uid) case d: Deploy => onDeploy(d) + + case Announce(msg) => notifyAll(makeMessage("announce", Json.obj("msg" -> msg)).pp) } protected def hasUserId(userId: String) = members.values.exists(_.userId contains userId) @@ -181,5 +183,5 @@ trait LoneSocket { self: SocketTrouper[_] => this ! lila.socket.actorApi.Broom lila.mon.socket.queueSize(monitoringName)(queueSize) } - system.lilaBus.subscribe(this, 'deploy, 'shutdown) + system.lilaBus.subscribe(this, 'deploy, 'shutdown, 'announce) } diff --git a/modules/streamer/src/main/LiveStream.scala b/modules/streamer/src/main/LiveStream.scala index f2fd78bd8d..289ab70153 100644 --- a/modules/streamer/src/main/LiveStream.scala +++ b/modules/streamer/src/main/LiveStream.scala @@ -55,7 +55,7 @@ final class LiveStreamApi( // requested = false, // granted = true, // ignored = false, - // autoFeatured = false, + // autoFeatured = true, // chatEnabled = true // ), // picturePath = none, @@ -70,6 +70,7 @@ final class LiveStreamApi( // updatedAt = DateTime.now // )) // ))) + def of(s: Streamer.WithUser): Fu[Streamer.WithUserAndStream] = all.map { live => Streamer.WithUserAndStream(s.streamer, s.user, live get s.streamer) } diff --git a/modules/streamer/src/main/StreamerApi.scala b/modules/streamer/src/main/StreamerApi.scala index 9238e8fcaa..0201a1113c 100644 --- a/modules/streamer/src/main/StreamerApi.scala +++ b/modules/streamer/src/main/StreamerApi.scala @@ -55,12 +55,7 @@ final class StreamerApi( def update(prev: Streamer, data: StreamerForm.UserData, asMod: Boolean): Fu[Streamer.ModChange] = { val streamer = data(prev, asMod) - val writeConcern = reactivemongo.api.commands.GetLastError.ReplicaAcknowledged( - n = 3, - timeout = 3000, - journaled = false - ) - coll.update($id(streamer.id), streamer, writeConcern = writeConcern) >>- + coll.update($id(streamer.id), streamer) >>- listedIdsCache.refresh inject { val modChange = Streamer.ModChange( list = prev.approval.granted != streamer.approval.granted option streamer.approval.granted, diff --git a/modules/streamer/src/main/Streaming.scala b/modules/streamer/src/main/Streaming.scala index 65d527492c..d06cecbc97 100644 --- a/modules/streamer/src/main/Streaming.scala +++ b/modules/streamer/src/main/Streaming.scala @@ -4,7 +4,6 @@ import akka.actor._ import play.api.libs.json._ import play.api.libs.ws.WS import play.api.Play.current -import play.twirl.api.Html import scala.concurrent.duration._ import lila.db.dsl._ diff --git a/modules/study/src/main/BSONHandlers.scala b/modules/study/src/main/BSONHandlers.scala index 1234589f10..dc2a3e10aa 100644 --- a/modules/study/src/main/BSONHandlers.scala +++ b/modules/study/src/main/BSONHandlers.scala @@ -332,6 +332,7 @@ object BSONHandlers { import Study.Rank private[study] implicit val RankBSONHandler = dateIsoHandler[Rank](Iso[DateTime, Rank](Rank.apply, _.value)) + // implicit val StudyBSONHandler = BSON.LoggingHandler(logger)(Macros.handler[Study]) implicit val StudyBSONHandler = Macros.handler[Study] implicit val lightStudyBSONReader = new BSONDocumentReader[Study.LightStudy] { diff --git a/modules/study/src/main/StudyMultiBoard.scala b/modules/study/src/main/StudyMultiBoard.scala index 0182a3be9f..1819c66fb9 100644 --- a/modules/study/src/main/StudyMultiBoard.scala +++ b/modules/study/src/main/StudyMultiBoard.scala @@ -43,7 +43,8 @@ final class StudyMultiBoard( sort = $sort asc "order", runCommand = runCommand, command = $doc( - "map" -> """var node = this.root, child, tagPrefixes = ['White','Black','Result'], result = {name:this.name,orientation:this.setup.orientation,tags:this.tags.filter(t => tagPrefixes.find(p => t.indexOf(p) === 0))}; + "map" -> """var node = this.root, child, tagPrefixes = ['White','Black','Result'], result = + {name:this.name,orientation:this.setup.orientation,tags:this.tags.filter(t => tagPrefixes.find(p => t.startsWith(p)))}; if (result.tags.length > 1) { while(child = node.n[0]) { node = child }; } result.fen = node.f; result.uci = node.u; diff --git a/modules/team/src/main/TeamApi.scala b/modules/team/src/main/TeamApi.scala index 40a3cbdd6c..da97352143 100644 --- a/modules/team/src/main/TeamApi.scala +++ b/modules/team/src/main/TeamApi.scala @@ -193,7 +193,7 @@ final class TeamApi( def owns(teamId: String, userId: String): Fu[Boolean] = TeamRepo ownerOf teamId map (Some(userId) ==) - def teamName(teamId: String) = cached name teamId + def teamName(teamId: String): Option[String] = cached.name(teamId) def nbRequests(teamId: String) = cached.nbRequests get teamId diff --git a/modules/tournament/src/main/Cached.scala b/modules/tournament/src/main/Cached.scala index dac452aa68..9e30581c95 100644 --- a/modules/tournament/src/main/Cached.scala +++ b/modules/tournament/src/main/Cached.scala @@ -28,19 +28,6 @@ private[tournament] final class Cached( expireAfter = _.ExpireAfterWrite(createdTtl) ) - def findNext(tour: Tournament): Fu[Option[Tournament]] = tour.perfType ?? { pt => - promotable.get map { tours => - tours - .filter(_.isScheduled) - .filter { t => - if (tour.conditions.isRatingLimited) tour.conditions sameRatings t.conditions - else t.perfType has pt - } - .sortBy(_.startsAt) - .headOption - } - } - def ranking(tour: Tournament): Fu[Ranking] = if (tour.isFinished) finishedRanking get tour.id else ongoingRanking get tour.id diff --git a/modules/tournament/src/main/DataForm.scala b/modules/tournament/src/main/DataForm.scala index 16e7ae12fc..8e70d83a88 100644 --- a/modules/tournament/src/main/DataForm.scala +++ b/modules/tournament/src/main/DataForm.scala @@ -8,7 +8,7 @@ import play.api.data.validation.Constraints import chess.Mode import chess.StartingPosition import lila.common.Form._ -import lila.common.Form.ISODate._ +import lila.common.Form.ISODateTime._ import lila.user.User final class DataForm { diff --git a/modules/tournament/src/main/JsonView.scala b/modules/tournament/src/main/JsonView.scala index a73371ddcd..66c9ec931f 100644 --- a/modules/tournament/src/main/JsonView.scala +++ b/modules/tournament/src/main/JsonView.scala @@ -30,8 +30,7 @@ final class JsonView( private case class CachableData( duels: JsArray, featured: Option[JsObject], - podium: Option[JsArray], - next: Option[JsObject] + podium: Option[JsArray] ) def apply( @@ -81,7 +80,6 @@ final class JsonView( .add("playerInfo" -> playerInfoJson) .add("pairingsClosed" -> tour.pairingsClosed) .add("stats" -> stats) - .add("next" -> data.next) .add("socketVersion" -> socketVersion.map(_.value)) ++ full.?? { Json.obj( "id" -> tour.id, @@ -229,25 +227,14 @@ final class JsonView( jsonDuels <- duels.map(duelJson).sequenceFu featured <- tour ?? fetchFeaturedGame podium <- tour.exists(_.isFinished) ?? podiumJsonCache.get(id) - next <- tour.filter(_.isFinished) ?? cached.findNext map2 nextJson } yield CachableData( duels = JsArray(jsonDuels), featured = featured map featuredJson, - podium = podium, - next = next + podium = podium ), expireAfter = _.ExpireAfterWrite(1 second) ) - private def nextJson(tour: Tournament) = Json.obj( - "id" -> tour.id, - "name" -> tour.fullName, - "perf" -> tour.perfType, - "nbPlayers" -> tour.nbPlayers, - "finishesAt" -> tour.isStarted.option(tour.finishesAt).map(formatDate), - "startsAt" -> tour.isCreated.option(tour.startsAt).map(formatDate) - ) - private def featuredJson(featured: FeaturedGame) = { val game = featured.game def ofPlayer(rp: RankedPlayer, p: lila.game.Player) = { diff --git a/modules/tournament/src/main/TournamentInviter.scala b/modules/tournament/src/main/TournamentInviter.scala index 96c25a7f9a..38f725c043 100644 --- a/modules/tournament/src/main/TournamentInviter.scala +++ b/modules/tournament/src/main/TournamentInviter.scala @@ -30,6 +30,7 @@ private final class TournamentInviter( private def qualifies(user: User) = !user.seenRecently && !user.kid && + !user.hasTitle && user.count.rated > 50 && user.toints < 10 && bestRating(user).??(1700 >=) && diff --git a/modules/tournament/src/main/TournamentShield.scala b/modules/tournament/src/main/TournamentShield.scala index 47b4aaf721..d7fef12984 100644 --- a/modules/tournament/src/main/TournamentShield.scala +++ b/modules/tournament/src/main/TournamentShield.scala @@ -1,8 +1,8 @@ package lila.tournament import org.joda.time.DateTime -import scala.concurrent.duration._ import reactivemongo.api.ReadPreference +import scala.concurrent.duration._ import lila.db.dsl._ import lila.rating.PerfType @@ -20,11 +20,21 @@ final class TournamentShieldApi( _.value.values.flatMap(_.headOption.filter(_.owner.value == u.id)).toList } - def history: Fu[History] = cache.get + def history(maxPerCateg: Option[Int]): Fu[History] = cache.get map { h => + maxPerCateg.fold(h)(h.take) + } + + def byCategKey(k: String): Fu[Option[(Category, List[Award])]] = Category.byKey(k) ?? { categ => + cache.get map { + _.value get categ map { + categ -> _ + } + } + } def currentOwner(tour: Tournament): Fu[Option[OwnerId]] = tour.isShield ?? { Category.of(tour) ?? { cat => - history.map(_.current(cat).map(_.owner)) + history(none).map(_.current(cat).map(_.owner)) } } @@ -75,6 +85,10 @@ object TournamentShield { def userIds: List[User.ID] = value.values.flatMap(_.map(_.owner.value)).toList def current(cat: Category): Option[Award] = value get cat flatMap (_.headOption) + + def take(max: Int) = copy( + value = value.mapValues(_ take max) + ) } private type SpeedOrVariant = Either[Schedule.Speed, chess.variant.Variant] @@ -172,7 +186,9 @@ object TournamentShield { val all: List[Category] = List(Bullet, SuperBlitz, Blitz, Rapid, Classical, HyperBullet, UltraBullet, Crazyhouse, Chess960, KingOfTheHill, ThreeCheck, Antichess, Atomic, Horde, RacingKings) - def of(t: Tournament) = all.find(_ matches t) + def of(t: Tournament): Option[Category] = all.find(_ matches t) + + def byKey(k: String): Option[Category] = all.find(_.key == k) } def spotlight(name: String) = Spotlight( diff --git a/modules/tv/src/main/Tv.scala b/modules/tv/src/main/Tv.scala index 4a8051c4f9..420f6032b9 100644 --- a/modules/tv/src/main/Tv.scala +++ b/modules/tv/src/main/Tv.scala @@ -28,7 +28,7 @@ final class Tv(trouper: Trouper, roundProxyGame: Game.ID => Fu[Option[Game]]) { _.map(roundProxyGame).sequenceFu.map(_.flatten) } - def getBestGame = getGame(Tv.Channel.Best) + def getBestGame = getGame(Tv.Channel.Best) orElse lila.game.GameRepo.random def getBestAndHistory = getGameAndHistory(Tv.Channel.Best) diff --git a/modules/user/src/main/Trophy.scala b/modules/user/src/main/Trophy.scala index cd97d3a7f6..2df8457912 100644 --- a/modules/user/src/main/Trophy.scala +++ b/modules/user/src/main/Trophy.scala @@ -43,7 +43,7 @@ object Trophy { name = "The way of Berserk", icon = "`".some, url = "//lichess.org/qa/340/way-of-berserk-trophy".some, - klass = "fire_trophy".some, + klass = "fire-trophy".some, order = 2 ) @@ -52,7 +52,7 @@ object Trophy { name = "Marathon Winner", icon = "\\".some, url = none, - klass = "fire_trophy".some, + klass = "fire-trophy".some, order = 3 ) @@ -61,7 +61,7 @@ object Trophy { name = "Marathon Top 10", icon = "\\".some, url = none, - klass = "fire_trophy".some, + klass = "fire-trophy".some, order = 4 ) @@ -70,7 +70,7 @@ object Trophy { name = "Marathon Top 50", icon = "\\".some, url = none, - klass = "fire_trophy".some, + klass = "fire-trophy".some, order = 5 ) @@ -79,7 +79,7 @@ object Trophy { name = "Marathon Top 100", icon = "\\".some, url = none, - klass = "fire_trophy".some, + klass = "fire-trophy".some, order = 6 ) @@ -88,7 +88,7 @@ object Trophy { name = "Marathon #1 survivor", icon = ",".some, url = "//lichess.org/blog/VXF45yYAAPQgLH4d/chess-marathon-1".some, - klass = "fire_trophy".some, + klass = "fire-trophy".some, order = 7 ) @@ -97,7 +97,7 @@ object Trophy { name = "Bongcloud Warrior", icon = "~".some, url = "//lichess.org/forum/lichess-feedback/bongcloud-trophy".some, - klass = "fire_trophy".some, + klass = "fire-trophy".some, order = 8 ) diff --git a/modules/user/src/main/User.scala b/modules/user/src/main/User.scala index 99a2a0a90c..091bb614ee 100644 --- a/modules/user/src/main/User.scala +++ b/modules/user/src/main/User.scala @@ -93,12 +93,9 @@ case class User( -(perfs(pt).nb * PerfType.totalTimeRoughEstimation.get(pt).fold(0)(_.roundSeconds)) } take nb - private val firstRow: List[PerfType] = List(PerfType.Bullet, PerfType.Blitz, PerfType.Rapid, PerfType.Classical, PerfType.Correspondence) - private val secondRow: List[PerfType] = List(PerfType.UltraBullet, PerfType.Crazyhouse, PerfType.Chess960, PerfType.KingOfTheHill, PerfType.ThreeCheck, PerfType.Antichess, PerfType.Atomic, PerfType.Horde, PerfType.RacingKings) + def best8Perfs: List[PerfType] = bestOf(User.firstRow, 4) ::: bestOf(User.secondRow, 4) - def best8Perfs: List[PerfType] = bestOf(firstRow, 4) ::: bestOf(secondRow, 4) - - def best6Perfs: List[PerfType] = bestOf(firstRow ::: secondRow, 6) + def best6Perfs: List[PerfType] = bestOf(User.firstRow ::: User.secondRow, 6) def hasEstablishedRating(pt: PerfType) = perfs(pt).established @@ -305,4 +302,7 @@ object User { } implicit val speakerHandler = reactivemongo.bson.Macros.handler[Speaker] + + private val firstRow: List[PerfType] = List(PerfType.Bullet, PerfType.Blitz, PerfType.Rapid, PerfType.Classical, PerfType.Correspondence) + private val secondRow: List[PerfType] = List(PerfType.UltraBullet, PerfType.Crazyhouse, PerfType.Chess960, PerfType.KingOfTheHill, PerfType.ThreeCheck, PerfType.Antichess, PerfType.Atomic, PerfType.Horde, PerfType.RacingKings) } diff --git a/package.json b/package.json index 96734c777b..07cf854f66 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ }, "private": true, "workspaces": [ + "ui", "ui/analyse", "ui/ceval", "ui/challenge", @@ -36,6 +37,7 @@ "ui/editor", "ui/game", "ui/nvui", + "ui/speech", "ui/insight", "ui/learn", "ui/lobby", diff --git a/project/RoutesCompiler.scala b/project/RoutesCompiler.scala new file mode 100644 index 0000000000..c222c9cb78 --- /dev/null +++ b/project/RoutesCompiler.scala @@ -0,0 +1,97 @@ +import play.routes.compiler._ + +import play.routes.compiler.RoutesCompiler.RoutesCompilerTask +import java.io.File + +object LilaRoutesGenerator extends RoutesGenerator { + + val ForwardsRoutesFile = "Routes.scala" + val ReverseRoutesFile = "ReverseRoutes.scala" + val RoutesPrefixFile = "RoutesPrefix.scala" + val JavaWrapperFile = "routes.java" + + val id = "lila" + + def generate(task: RoutesCompilerTask, namespace: Option[String], rules: List[Rule]): Seq[(String, String)] = { + + val folder = namespace.map(_.replace('.', '/') + "/").getOrElse("") + "/" + + val sourceInfo = RoutesSourceInfo(task.file.getCanonicalPath.replace(File.separator, "/"), new java.util.Date().toString) + val routes = rules.collect { case r: Route => r } + + val forwardsRoutesFiles = if (task.forwardsRouter) { + Seq(folder + ForwardsRoutesFile -> generateRouter(sourceInfo, namespace, task.additionalImports, rules)) + } else { + Nil + } + + val reverseRoutesFiles = if (task.reverseRouter) { + Seq(folder + RoutesPrefixFile -> generateRoutesPrefix(sourceInfo, namespace)) ++ + generateReverseRouters(sourceInfo, namespace, task.additionalImports, routes, task.namespaceReverseRouter) ++ + generateJavaWrappers(sourceInfo, namespace, rules, task.namespaceReverseRouter) + } else { + Nil + } + + forwardsRoutesFiles ++ reverseRoutesFiles + } + + private def generateRouter(sourceInfo: RoutesSourceInfo, namespace: Option[String], additionalImports: Seq[String], rules: List[Rule]) = + static.twirl.forwardsRouter( + sourceInfo, + namespace, + additionalImports, + rules + ).body + + private def generateRoutesPrefix(sourceInfo: RoutesSourceInfo, namespace: Option[String]) = + static.twirl.routesPrefix( + sourceInfo, + namespace, + _.call.instantiate + ).body + + private def generateReverseRouters(sourceInfo: RoutesSourceInfo, namespace: Option[String], additionalImports: Seq[String], routes: List[Route], namespaceReverseRouter: Boolean) = { + routes.groupBy(_.call.packageName).map { + case (pn, routes) => + val packageName = namespace.filter(_ => namespaceReverseRouter).map(_ + "." + pn).getOrElse(pn) + (packageName.replace(".", "/") + "/" + ReverseRoutesFile) -> + static.twirl.reverseRouter( + sourceInfo, + namespace, + additionalImports, + packageName, + routes, + namespaceReverseRouter, + _.call.instantiate + ).body + } + } + + private def generateJavaWrappers(sourceInfo: RoutesSourceInfo, namespace: Option[String], rules: List[Rule], namespaceReverseRouter: Boolean) = { + rules.collect { case r: Route => r }.groupBy(_.call.packageName).map { + case (pn, routes) => + val packageName = namespace.filter(_ => namespaceReverseRouter).map(_ + "." + pn).getOrElse(pn) + val controllers = routes.groupBy(_.call.controller).keys.toSeq + + (packageName.replace(".", "/") + "/" + JavaWrapperFile) -> + renderJavaWrappers(sourceInfo, namespace, packageName, controllers) + } + } + + private def renderJavaWrappers( + sourceInfo: RoutesSourceInfo, + pkg: Option[String], + packageName: String, + controllers: Seq[String]) = s"""package $packageName; + +import ${pkg getOrElse "_routes_"}.RoutesPrefix; + +public class routes { +""" + controllers.map { controller => + s"""public static final ${packageName}.Reverse${controller} ${controller} = new ${packageName}.Reverse${controller}(RoutesPrefix.byNamePrefix()); +""" +}.mkString + """ + +}""" +} diff --git a/public/css/README b/public/css/README new file mode 100644 index 0000000000..7db2043cb4 --- /dev/null +++ b/public/css/README @@ -0,0 +1,2 @@ +Don't modify these files. +They are generated from SCSS code in ui/ modules. diff --git a/public/font/lichess.chess.sfd b/public/font/lichess.chess.sfd new file mode 100644 index 0000000000..77bf0ea74d --- /dev/null +++ b/public/font/lichess.chess.sfd @@ -0,0 +1,4597 @@ +SplineFontDB: 3.0 +FontName: NotoSans +FullName: Noto Sans +FamilyName: Noto Sans +Weight: Book +Copyright: Copyright 2012 Google Inc. All Rights Reserved. +Version: 1.04 +ItalicAngle: 0 +UnderlinePosition: -205 +UnderlineWidth: 102 +Ascent: 1638 +Descent: 410 +InvalidEm: 0 +sfntRevision: 0x00010a3d +LayerCount: 2 +Layer: 0 1 "Back" 1 +Layer: 1 1 "Fore" 0 +XUID: [1021 568 66413622 7990395] +StyleMap: 0x0040 +FSType: 8 +OS2Version: 3 +OS2_WeightWidthSlopeOnly: 0 +OS2_UseTypoMetrics: 0 +CreationTime: 1392839385 +ModificationTime: 1556185251 +PfmFamily: 17 +TTFWeight: 400 +TTFWidth: 5 +LineGap: 0 +VLineGap: 0 +Panose: 2 11 5 2 4 5 4 2 2 4 +OS2TypoAscent: 2189 +OS2TypoAOffset: 0 +OS2TypoDescent: -600 +OS2TypoDOffset: 0 +OS2TypoLinegap: 0 +OS2WinAscent: 2189 +OS2WinAOffset: 0 +OS2WinDescent: 600 +OS2WinDOffset: 0 +HheadAscent: 2189 +HheadAOffset: 0 +HheadDescent: -600 +HheadDOffset: 0 +OS2SubXSize: 1434 +OS2SubYSize: 1331 +OS2SubXOff: 0 +OS2SubYOff: 287 +OS2SupXSize: 1434 +OS2SupYSize: 1331 +OS2SupXOff: 0 +OS2SupYOff: 977 +OS2StrikeYSize: 102 +OS2StrikeYPos: 512 +OS2CapHeight: 1462 +OS2XHeight: 1098 +OS2FamilyClass: 2050 +OS2Vendor: 'MONO' +OS2CodePages: 2000019f.dfd70000 +OS2UnicodeRanges: 80000027.0000006b.00000020.00000000 +Lookup: 258 8 0 "'kern' Horizontal Kerning lookup 0" { "'kern' Horizontal Kerning lookup 0 subtable" } ['kern' ('cyrl' <'dflt' > 'grek' <'dflt' > 'latn' <'dflt' > ) ] +DEI: 91125 +TtTable: prep +NPUSHB + 255 + 9 + 33 + 51 + 32 + 85 + 0 + 32 + 1 + 239 + 32 + 1 + 144 + 32 + 1 + 127 + 32 + 1 + 32 + 1 + 30 + 85 + 31 + 51 + 3 + 85 + 31 + 30 + 1 + 15 + 30 + 63 + 30 + 175 + 30 + 3 + 91 + 80 + 90 + 85 + 63 + 90 + 79 + 90 + 2 + 90 + 1 + 88 + 85 + 89 + 80 + 88 + 85 + 48 + 88 + 64 + 88 + 80 + 88 + 176 + 88 + 4 + 87 + 80 + 86 + 85 + 32 + 86 + 1 + 240 + 86 + 1 + 86 + 1 + 84 + 85 + 85 + 80 + 84 + 85 + 112 + 84 + 1 + 31 + 84 + 1 + 48 + 84 + 64 + 84 + 128 + 84 + 208 + 84 + 224 + 84 + 5 + 48 + 77 + 1 + 77 + 2 + 78 + 85 + 71 + 100 + 70 + 85 + 63 + 70 + 175 + 70 + 2 + 70 + 1 + 75 + 85 + 74 + 80 + 73 + 85 + 73 + 1 + 75 + 85 + 79 + 80 + 78 + 85 + 51 + 78 + 1 + 78 + 1 + 75 + 85 + 76 + 80 + 75 + 85 + 31 + 75 + 1 + 15 + 75 + 63 + 75 + 175 + 75 + 3 + 83 + 80 + 82 + 85 + 59 + 82 + 1 + 82 + 1 + 80 + 85 + 81 + 80 + 80 + 85 + 55 + 36 + 1 + 126 + 97 + 100 + 31 + 88 + 125 + 1 + 119 + 115 + 30 + 31 + 118 + 115 + 65 + 31 + 117 + 115 + 50 + 31 + 116 + 115 + 50 + 31 + 151 + 115 + 1 + 184 + 115 + 1 + 216 + 115 + 1 + 25 + 51 + 24 + 85 + 7 + 51 + 3 + 85 + 6 + 3 + 255 + 31 + 109 + 105 + 25 + 31 + 108 + 105 + 38 + 31 + 107 + 105 + 61 + 31 + 106 + 105 + 72 + 31 + 167 + 105 + 1 + 90 + 38 + 1 + 8 + 38 + 72 + 38 + 2 + 72 + 38 + 136 + 38 + 200 + 38 + 3 + 127 + 35 + 143 + 35 + 207 + 35 + 3 + 19 + 51 + 18 +NPUSHB + 109 + 85 + 5 + 1 + 3 + 85 + 4 + 51 + 3 + 85 + 31 + 3 + 1 + 15 + 3 + 63 + 3 + 175 + 3 + 3 + 100 + 93 + 52 + 31 + 120 + 99 + 1 + 98 + 93 + 35 + 31 + 97 + 93 + 51 + 31 + 96 + 93 + 42 + 31 + 95 + 93 + 42 + 31 + 94 + 93 + 51 + 31 + 184 + 93 + 200 + 93 + 2 + 216 + 93 + 232 + 93 + 2 + 28 + 100 + 27 + 85 + 22 + 51 + 21 + 85 + 16 + 51 + 15 + 85 + 15 + 15 + 79 + 15 + 2 + 31 + 15 + 207 + 15 + 2 + 15 + 15 + 255 + 15 + 2 + 6 + 2 + 1 + 0 + 85 + 1 + 100 + 0 + 85 + 111 + 0 + 127 + 0 + 175 + 0 + 239 + 0 + 4 + 16 + 0 + 1 + 128 + 22 + 1 + 5 + 1 +PUSHW_1 + 400 +PUSHB_2 + 84 + 83 +CALL +CALL +MPPEM +PUSHW_1 + 2047 +GT +MPPEM +PUSHB_1 + 9 +LT +OR +PUSHB_1 + 1 +GETINFO +PUSHB_1 + 37 +GTEQ +PUSHB_1 + 1 +GETINFO +PUSHB_1 + 64 +LTEQ +AND +PUSHB_1 + 6 +GETINFO +PUSHB_1 + 0 +NEQ +AND +OR +IF +PUSHB_2 + 1 + 1 +INSTCTRL +EIF +SCANCTRL +SCANTYPE +SCANTYPE +SVTCA[y-axis] +WS +SCVTCI +MPPEM +PUSHB_1 + 50 +GTEQ +IF +PUSHB_1 + 96 +SCVTCI +EIF +MPPEM +PUSHB_1 + 100 +GTEQ +IF +PUSHB_1 + 64 +SCVTCI +EIF +MPPEM +PUSHB_1 + 128 +GTEQ +IF +PUSHB_1 + 16 +SCVTCI +PUSHB_2 + 22 + 0 +WS +EIF +DELTAC1 +DELTAC1 +CALL +CALL +SDB +DELTAC1 +DELTAC2 +DELTAC3 +CALL +CALL +CALL +DELTAC1 +DELTAC2 +CALL +CALL +CALL +CALL +CALL +DELTAC1 +CALL +DELTAC1 +DELTAC2 +CALL +CALL +CALL +DELTAC1 +DELTAC1 +DELTAC2 +DELTAC2 +DELTAC2 +CALL +CALL +CALL +CALL +CALL +CALL +CALL +DELTAC1 +DELTAC2 +DELTAC3 +CALL +CALL +CALL +CALL +DELTAC1 +CALL +DELTAC1 +CALL +CALL +DELTAC1 +CALL +DELTAC1 +DELTAC2 +CALL +CALL +DELTAC1 +CALL +CALL +CALL +CALL +DELTAC1 +CALL +CALL +DELTAC1 +DELTAC1 +DELTAC2 +DELTAC2 +CALL +CALL +DELTAC1 +DELTAC2 +CALL +DELTAC1 +CALL +CALL +DELTAC1 +CALL +DELTAC1 +DELTAC2 +CALL +CALL +DELTAC1 +DELTAC1 +DELTAC1 +DELTAC2 +CALL +RTG +SDB +EndTTInstrs +TtTable: fpgm +NPUSHB + 71 + 91 + 90 + 89 + 88 + 85 + 84 + 83 + 82 + 81 + 80 + 79 + 78 + 77 + 76 + 75 + 74 + 73 + 72 + 71 + 70 + 69 + 68 + 67 + 66 + 65 + 64 + 63 + 62 + 61 + 60 + 59 + 58 + 57 + 56 + 55 + 54 + 53 + 49 + 48 + 47 + 46 + 45 + 44 + 40 + 39 + 38 + 37 + 36 + 35 + 34 + 33 + 31 + 24 + 20 + 17 + 16 + 15 + 14 + 13 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0 +FDEF +DUP +PUSHB_1 + 1 +ADD +RCVT +PUSHB_1 + 3 +CINDEX +DUP +SRP1 +GC[cur] +SUB +SWAP +RCVT +SWAP +SUB +SCFS +ENDF +FDEF +DUP +RCVT +RTG +ROUND[Grey] +WCVTP +ENDF +FDEF +RCVT +SWAP +GC[cur] +ADD +PUSHB_1 + 32 +SUB +DUP +PUSHB_1 + 70 +ADD +PUSHB_1 + 4 +MINDEX +SWAP +SCFS +SCFS +ENDF +FDEF +RCVT +SWAP +GC[cur] +SWAP +SUB +PUSHB_1 + 32 +ADD +DUP +PUSHB_1 + 38 +SUB +PUSHB_1 + 32 +SUB +PUSHB_1 + 4 +MINDEX +SWAP +SCFS +SCFS +ENDF +FDEF +RCVT +SWAP +GC[cur] +ADD +PUSHB_1 + 64 +SUB +DUP +PUSHB_1 + 102 +ADD +PUSHB_1 + 4 +MINDEX +SWAP +SCFS +SCFS +ENDF +FDEF +RCVT +SWAP +GC[cur] +SWAP +SUB +PUSHB_1 + 64 +ADD +DUP +PUSHB_1 + 38 +SUB +PUSHB_1 + 64 +SUB +PUSHB_1 + 4 +MINDEX +SWAP +SCFS +SCFS +ENDF +FDEF +SVTCA[x-axis] +SRP0 +DUP +ALIGNRP +SVTCA[y-axis] +ALIGNRP +ENDF +FDEF +DUP +RCVT +SWAP +DUP +PUSHB_1 + 205 +WCVTP +SWAP +DUP +PUSHW_1 + 346 +LTEQ +IF +SWAP +DUP +PUSHB_1 + 141 +WCVTP +SWAP +EIF +DUP +PUSHB_1 + 237 +LTEQ +IF +SWAP +DUP +PUSHB_1 + 77 +WCVTP +SWAP +EIF +DUP +PUSHB_1 + 4 +MINDEX +LTEQ +IF +SWAP +DUP +PUSHB_1 + 13 +WCVTP +SWAP +EIF +POP +POP +ENDF +FDEF +DUP +DUP +RCVT +RTG +ROUND[Grey] +WCVTP +DUP +PUSHB_1 + 1 +ADD +DUP +RCVT +PUSHB_1 + 70 +SROUND +ROUND[Grey] +ROLL +RCVT +ADD +WCVTP +ENDF +FDEF +SVTCA[x-axis] +PUSHB_2 + 11 + 10 +RS +SWAP +RS +NEG +SPVFS +ENDF +FDEF +SVTCA[y-axis] +PUSHB_2 + 10 + 11 +RS +SWAP +RS +SFVFS +ENDF +FDEF +SVTCA[y-axis] +PUSHB_1 + 40 +SWAP +WCVTF +PUSHB_2 + 1 + 40 +MIAP[no-rnd] +SVTCA[x-axis] +PUSHB_1 + 40 +SWAP +WCVTF +PUSHB_2 + 2 + 40 +RCVT +MSIRP[no-rp0] +PUSHB_2 + 2 + 0 +SFVTL[parallel] +GFV +ENDF +FDEF +DUP +RCVT +PUSHB_1 + 3 +CINDEX +RCVT +SUB +ABS +PUSHB_1 + 80 +LTEQ +IF +RCVT +WCVTP +ELSE +POP +POP +EIF +ENDF +FDEF +MD[grid] +PUSHB_1 + 14 +SWAP +WCVTP +ENDF +FDEF +DUP +RCVT +PUSHB_1 + 0 +RS +ADD +WCVTP +ENDF +FDEF +SVTCA[x-axis] +PUSHB_1 + 6 +RS +PUSHB_1 + 7 +RS +NEG +SPVFS +ENDF +FDEF +DUP +ROUND[Black] +PUSHB_1 + 64 +SUB +PUSHB_1 + 0 +MAX +DUP +PUSHB_2 + 44 + 192 +ROLL +MIN +PUSHW_1 + 4096 +DIV +ADD +CALL +GPV +ABS +SWAP +ABS +SUB +NOT +IF +PUSHB_1 + 3 +SUB +EIF +ENDF +FDEF +ROLL +SPVTCA[x-axis] +RCVT +ROLL +ROLL +SDPVTL[orthog] +PUSHB_1 + 17 +CALL +PUSHB_1 + 41 +SWAP +WCVTP +PUSHB_1 + 41 +ROFF +MIRP[rnd,grey] +RTG +ENDF +FDEF +RCVT +NEG +PUSHB_1 + 44 +SWAP +WCVTP +RCVT +PUSHB_1 + 43 +SWAP +WCVTP +ENDF +FDEF +MPPEM +GT +IF +RCVT +WCVTP +ELSE +POP +POP +EIF +ENDF +FDEF +MPPEM +LTEQ +IF +RCVT +WCVTP +ELSE +POP +POP +EIF +ENDF +FDEF +SVTCA[x-axis] +PUSHB_1 + 5 +CINDEX +SRP0 +SWAP +DUP +ROLL +MIRP[rp0,rnd,black] +SVTCA[y-axis] +PUSHB_1 + 1 +ADD +SWAP +MIRP[min,rnd,black] +MIRP[min,rnd,grey] +ENDF +FDEF +SVTCA[x-axis] +PUSHB_1 + 5 +CINDEX +SRP0 +SWAP +DUP +ROLL +MIRP[rp0,rnd,black] +SVTCA[y-axis] +PUSHB_1 + 1 +SUB +SWAP +MIRP[min,rnd,black] +MIRP[min,rnd,grey] +ENDF +FDEF +SVTCA[x-axis] +PUSHB_1 + 6 +CINDEX +SRP0 +MIRP[rp0,rnd,black] +SVTCA[y-axis] +MIRP[min,rnd,black] +MIRP[min,rnd,grey] +ENDF +FDEF +PUSHB_1 + 2 +RS +PUSHB_1 + 1 +GT +IF +POP +POP +POP +POP +POP +ELSE +GC[cur] +SWAP +GC[cur] +ADD +ROLL +ROLL +GC[cur] +SWAP +DUP +GC[cur] +ROLL +ADD +ROLL +SUB +PUSHW_1 + -128 +DIV +SWAP +DUP +SRP0 +SWAP +ROLL +PUSHB_2 + 12 + 12 +ROLL +WCVTF +RCVT +ADD +DUP +PUSHB_1 + 0 +LT +IF +PUSHB_1 + 1 +SUB +PUSHW_1 + -70 +MAX +ELSE +PUSHB_1 + 70 +MIN +EIF +PUSHB_1 + 16 +ADD +ROUND[Grey] +SVTCA[x-axis] +MSIRP[no-rp0] +EIF +ENDF +FDEF +DUP +RCVT +PUSHB_1 + 3 +CINDEX +GC[cur] +GT +MPPEM +PUSHB_1 + 19 +LTEQ +OR +IF +PUSHB_1 + 2 +CINDEX +GC[cur] +DUP +ROUND[Grey] +SUB +PUSHB_1 + 3 +CINDEX +PUSHB_1 + 3 +CINDEX +MIAP[rnd] +SWAP +POP +SHPIX +ELSE +POP +SRP1 +EIF +ENDF +FDEF +DUP +RCVT +PUSHB_1 + 3 +CINDEX +GC[cur] +LT +IF +PUSHB_1 + 2 +CINDEX +GC[cur] +DUP +ROUND[Grey] +SUB +PUSHB_1 + 3 +CINDEX +PUSHB_1 + 3 +CINDEX +MIAP[rnd] +SWAP +POP +SHPIX +ELSE +POP +SRP1 +EIF +ENDF +FDEF +SVTCA[y-axis] +PUSHB_1 + 7 +RS +PUSHB_1 + 6 +RS +SFVFS +ENDF +FDEF +DUP +PUSHB_1 + 3 +CINDEX +RCVT +LT +IF +ROLL +DUP +RCVT +ROLL +MAX +WCVTP +POP +ELSE +POP +RCVT +WCVTP +EIF +ENDF +FDEF +POP +PUSHB_1 + 128 +LTEQ +IF +GPV +ABS +SWAP +ABS +MAX +PUSHW_1 + 8192 +DIV +ELSE +PUSHB_3 + 0 + 64 + 47 +CALL +EIF +PUSHB_1 + 2 +ADD +ENDF +FDEF +POP +PUSHB_1 + 192 +LTEQ +IF +GPV +ABS +SWAP +ABS +MAX +PUSHW_1 + 5461 +DIV +ELSE +PUSHB_3 + 0 + 128 + 47 +CALL +EIF +PUSHB_1 + 2 +ADD +ENDF +FDEF +GPV +ABS +SWAP +ABS +MAX +PUSHW_1 + 16384 +DIV +ADD +SWAP +POP +ENDF +FDEF +MPPEM +GTEQ +IF +ROLL +PUSHB_1 + 4 +CINDEX +MD[grid] +ABS +SWAP +RCVT +ROUND[Black] +PUSHB_1 + 64 +MAX +SUB +PUSHB_1 + 128 +DIV +PUSHB_1 + 32 +SUB +ROUND[White] +PUSHB_1 + 14 +SWAP +WCVTP +SWAP +SRP0 +PUSHB_1 + 14 +MIRP[rp0,rnd,white] +ELSE +POP +SWAP +ROLL +SRP2 +SRP1 +DUP +IP +MDAP[rnd] +EIF +ENDF +FDEF +MPPEM +GTEQ +IF +DUP +PUSHB_1 + 3 +CINDEX +MD[grid] +ABS +ROUND[Black] +DUP +PUSHB_1 + 5 +MINDEX +PUSHB_1 + 6 +CINDEX +MD[grid] +ABS +SWAP +SUB +PUSHB_1 + 128 +DIV +PUSHB_1 + 32 +SUB +ROUND[White] +PUSHB_1 + 14 +SWAP +WCVTP +PUSHB_1 + 4 +MINDEX +SRP0 +PUSHB_1 + 14 +MIRP[rp0,rnd,white] +ROLL +SRP0 +PUSHB_1 + 14 +SWAP +WCVTP +PUSHB_1 + 14 +MIRP[rp0,rnd,white] +PUSHB_1 + 14 +SWAP +WCVTP +PUSHB_1 + 14 +MIRP[min,rnd,black] +ELSE +ROLL +PUSHB_1 + 4 +MINDEX +SRP1 +SRP2 +DUP +IP +SWAP +DUP +IP +MDAP[rnd] +MDAP[rnd] +EIF +ENDF +FDEF +RCVT +SWAP +RCVT +ADD +SWAP +RCVT +ADD +SWAP +RCVT +ADD +SWAP +SROUND +ROUND[Grey] +RTG +PUSHB_1 + 128 +DIV +DUP +ENDF +FDEF +PUSHB_1 + 72 +CALL +ENDF +FDEF +DUP +RCVT +PUSHB_1 + 0 +EQ +IF +PUSHB_1 + 64 +WCVTP +DUP +RCVT +PUSHB_1 + 64 +SUB +WCVTP +ELSE +POP +POP +EIF +ENDF +FDEF +RCVT +PUSHB_2 + 48 + 47 +RCVT +SWAP +RCVT +SUB +ADD +PUSHB_1 + 1 +ADD +ROUND[Black] +WCVTP +ENDF +FDEF +MPPEM +LTEQ +IF +PUSHB_1 + 47 +SWAP +WCVTF +PUSHB_1 + 20 +SWAP +WS +ELSE +POP +POP +EIF +ENDF +FDEF +MPPEM +LTEQ +IF +DUP +PUSHB_1 + 3 +CINDEX +RCVT +ROUND[Black] +GTEQ +IF +WCVTP +ELSE +POP +POP +EIF +ELSE +POP +POP +EIF +ENDF +FDEF +RCVT +PUSHB_1 + 20 +RS +PUSHB_1 + 0 +ADD +MUL +PUSHB_1 + 1 +ADD +ROUND[Black] +WCVTP +ENDF +FDEF +PUSHB_1 + 47 +RCVT +WCVTP +ENDF +FDEF +RCVT +SWAP +DUP +RCVT +ROLL +ADD +WCVTP +ENDF +FDEF +RCVT +SWAP +RCVT +ADD +WCVTP +ENDF +FDEF +MPPEM +SWAP +LTEQ +IF +PUSHW_2 + 51 + -32 +PUSHB_2 + 52 + 32 +ELSE +PUSHB_4 + 51 + 0 + 52 + 0 +EIF +WCVTP +WCVTP +ENDF +FDEF +PUSHB_1 + 22 +RS +IF +PUSHB_1 + 3 +MINDEX +RCVT +ROLL +IF +ABS +FLOOR +PUSHB_1 + 31 +ADD +ELSE +ABS +PUSHB_1 + 32 +ADD +FLOOR +DUP +IF +ELSE +POP +PUSHB_1 + 64 +EIF +PUSHB_1 + 1 +SUB +EIF +SWAP +IF +NEG +EIF +PUSHB_1 + 41 +SWAP +WCVTP +SWAP +SRP0 +PUSHB_1 + 41 +MIRP[grey] +ELSE +POP +POP +POP +POP +POP +EIF +ENDF +FDEF +PUSHB_1 + 2 +RS +EQ +IF +MPPEM +GTEQ +SWAP +MPPEM +LTEQ +AND +IF +SHPIX +ELSE +POP +POP +EIF +ELSE +POP +POP +POP +POP +EIF +ENDF +FDEF +PUSHB_1 + 22 +RS +IF +PUSHB_1 + 4 +CINDEX +RCVT +ABS +PUSHB_1 + 32 +ADD +FLOOR +DUP +IF +ELSE +POP +PUSHB_1 + 64 +EIF +PUSHB_1 + 1 +SUB +SWAP +IF +ELSE +NEG +EIF +PUSHB_1 + 41 +SWAP +WCVTP +PUSHB_1 + 5 +CINDEX +PUSHB_1 + 8 +CINDEX +SFVTL[parallel] +DUP +IF +SPVTCA[y-axis] +ELSE +SPVTCA[x-axis] +EIF +PUSHB_1 + 4 +CINDEX +SRP0 +PUSHB_1 + 5 +CINDEX +DUP +GC[cur] +PUSHB_1 + 4 +CINDEX +SWAP +WS +ALIGNRP +PUSHB_1 + 4 +CINDEX +PUSHB_1 + 7 +CINDEX +SFVTL[parallel] +PUSHB_1 + 7 +CINDEX +SRP0 +PUSHB_1 + 6 +CINDEX +DUP +GC[cur] +PUSHB_1 + 4 +CINDEX +PUSHB_1 + 1 +ADD +SWAP +WS +ALIGNRP +DUP +IF +SVTCA[x-axis] +ELSE +SVTCA[y-axis] +EIF +PUSHB_1 + 4 +CINDEX +SRP0 +PUSHB_1 + 5 +CINDEX +PUSHB_1 + 41 +MIRP[grey] +PUSHB_1 + 41 +DUP +RCVT +NEG +WCVTP +PUSHB_1 + 7 +CINDEX +SRP0 +PUSHB_1 + 6 +CINDEX +PUSHB_1 + 41 +MIRP[grey] +PUSHB_1 + 5 +CINDEX +PUSHB_1 + 8 +CINDEX +SFVTL[parallel] +DUP +IF +SPVTCA[y-axis] +ELSE +SPVTCA[x-axis] +EIF +PUSHB_1 + 5 +CINDEX +PUSHB_1 + 3 +CINDEX +RS +SCFS +PUSHB_1 + 4 +CINDEX +PUSHB_1 + 7 +CINDEX +SFVTL[parallel] +PUSHB_1 + 6 +CINDEX +PUSHB_1 + 3 +CINDEX +PUSHB_1 + 1 +ADD +RS +SCFS +ELSE +POP +EIF +POP +POP +POP +POP +POP +POP +POP +ENDF +FDEF +SPVTCA[y-axis] +PUSHB_1 + 4 +CINDEX +DUP +DUP +GC[cur] +PUSHB_1 + 4 +CINDEX +SWAP +WS +PUSHB_1 + 5 +CINDEX +SFVTL[parallel] +PUSHB_1 + 3 +CINDEX +RCVT +SCFS +POP +POP +POP +POP +ENDF +FDEF +SPVTCA[y-axis] +PUSHB_1 + 3 +CINDEX +DUP +PUSHB_1 + 4 +CINDEX +SFVTL[parallel] +PUSHB_1 + 2 +CINDEX +RS +SCFS +POP +POP +POP +ENDF +FDEF +RCVT +SWAP +DUP +RCVT +RTG +DUP +PUSHB_1 + 0 +LT +DUP +IF +SWAP +NEG +SWAP +EIF +SWAP +ROUND[Grey] +DUP +PUSHB_1 + 64 +LT +IF +POP +PUSHB_1 + 64 +EIF +SWAP +IF +NEG +EIF +ROLL +ADD +WCVTP +ENDF +FDEF +MPPEM +GTEQ +SWAP +MPPEM +LTEQ +AND +IF +DUP +RCVT +ROLL +ADD +WCVTP +ELSE +POP +POP +EIF +ENDF +FDEF +MPPEM +EQ +IF +DUP +RCVT +ROLL +ADD +WCVTP +ELSE +POP +POP +EIF +ENDF +FDEF +MPPEM +GTEQ +SWAP +MPPEM +LTEQ +AND +IF +SHPIX +ELSE +POP +POP +EIF +ENDF +FDEF +PUSHB_1 + 0 +POP +MPPEM +EQ +IF +SHPIX +ELSE +POP +POP +EIF +ENDF +FDEF +PUSHB_1 + 2 +RS +EQ +IF +PUSHB_1 + 70 +CALL +ELSE +POP +POP +POP +POP +EIF +ENDF +FDEF +PUSHB_1 + 2 +RS +EQ +IF +PUSHB_1 + 71 +CALL +ELSE +POP +POP +POP +EIF +ENDF +FDEF +DUP +PUSHB_1 + 2 +EQ +SWAP +PUSHB_1 + 0 +EQ +OR +IF +PUSHB_1 + 128 +PUSHB_1 + 2 +RS +LT +PUSHB_1 + 1 +PUSHB_1 + 2 +RS +EQ +OR +IF +POP +POP +POP +POP +ELSE +PUSHB_1 + 72 +CALL +EIF +ELSE +PUSHB_1 + 128 +PUSHB_1 + 2 +RS +LT +PUSHB_1 + 1 +PUSHB_1 + 2 +RS +EQ +OR +IF +PUSHB_1 + 72 +CALL +ELSE +POP +POP +POP +POP +EIF +EIF +ENDF +FDEF +DUP +PUSHB_1 + 2 +EQ +SWAP +PUSHB_1 + 0 +EQ +OR +IF +PUSHB_1 + 128 +PUSHB_1 + 2 +RS +LT +PUSHB_1 + 1 +PUSHB_1 + 2 +RS +EQ +OR +IF +POP +POP +POP +ELSE +PUSHB_1 + 73 +CALL +EIF +ELSE +PUSHB_1 + 128 +PUSHB_1 + 2 +RS +LT +PUSHB_1 + 1 +PUSHB_1 + 2 +RS +EQ +OR +IF +PUSHB_1 + 73 +CALL +ELSE +POP +POP +POP +EIF +EIF +ENDF +FDEF +DUP +ROLL +SFVTL[parallel] +SWAP +MPPEM +GTEQ +ROLL +MPPEM +LTEQ +AND +IF +SWAP +SHPIX +ELSE +POP +POP +EIF +ENDF +FDEF +SVTCA[y-axis] +PUSHB_1 + 2 +CINDEX +SRP1 +PUSHB_1 + 2 +CINDEX +MD[grid] +ROUND[White] +DUP +PUSHB_1 + 0 +GTEQ +IF +PUSHB_1 + 64 +ADD +SHPIX +ELSE +POP +POP +EIF +ENDF +FDEF +SVTCA[y-axis] +PUSHB_1 + 2 +CINDEX +SRP1 +PUSHB_1 + 2 +CINDEX +MD[grid] +ROUND[White] +DUP +PUSHB_1 + 0 +LTEQ +IF +PUSHB_1 + 64 +SUB +SHPIX +ELSE +POP +POP +EIF +ENDF +FDEF +DUP +ROLL +SWAP +MD[grid] +ABS +ROLL +SWAP +GTEQ +IF +ALIGNRP +ELSE +POP +EIF +ENDF +FDEF +MPPEM +GT +IF +RDTG +ELSE +ROFF +EIF +ENDF +FDEF +PUSHB_1 + 18 +SVTCA[y-axis] +MPPEM +SVTCA[x-axis] +MPPEM +EQ +WS +ENDF +FDEF +PUSHB_2 + 2 + 1 +WS +PUSHB_2 + 35 + 1 +GETINFO +LTEQ +PUSHB_2 + 64 + 1 +GETINFO +GTEQ +AND +IF +PUSHB_2 + 2 + 0 +WS +PUSHW_2 + 4096 + 32 +GETINFO +EQ +IF +PUSHB_3 + 2 + 1 + 2 +RS +ADD +WS +EIF +PUSHB_2 + 36 + 1 +GETINFO +LTEQ +IF +PUSHW_2 + 8192 + 64 +GETINFO +EQ +IF +PUSHB_3 + 2 + 2 + 2 +RS +ADD +WS +PUSHB_2 + 36 + 1 +GETINFO +EQ +IF +PUSHB_3 + 2 + 32 + 2 +RS +ADD +WS +SVTCA[y-axis] +MPPEM +SVTCA[x-axis] +MPPEM +GT +IF +PUSHB_3 + 2 + 8 + 2 +RS +ADD +WS +EIF +ELSE +PUSHW_2 + 16384 + 128 +GETINFO +EQ +IF +PUSHB_3 + 2 + 4 + 2 +RS +ADD +WS +EIF +PUSHW_2 + 16384 + 128 +MUL +PUSHW_1 + 256 +GETINFO +EQ +IF +PUSHB_3 + 2 + 8 + 2 +RS +ADD +WS +EIF +PUSHW_2 + 16384 + 256 +MUL +PUSHW_1 + 512 +GETINFO +EQ +IF +PUSHB_3 + 2 + 16 + 2 +RS +ADD +WS +EIF +PUSHB_2 + 38 + 1 +GETINFO +LTEQ +IF +PUSHW_2 + 16384 + 512 +MUL +PUSHW_1 + 1024 +GETINFO +EQ +IF +PUSHB_3 + 2 + 64 + 2 +RS +ADD +WS +EIF +PUSHW_2 + 16384 + 1024 +MUL +PUSHW_1 + 2048 +GETINFO +EQ +IF +PUSHB_3 + 2 + 128 + 2 +RS +ADD +WS +EIF +EIF +EIF +EIF +EIF +EIF +PUSHB_2 + 0 + 2 +RS +EQ +IF +PUSHB_2 + 2 + 1 +WS +EIF +ENDF +FDEF +RCVT +RTG +ROUND[Grey] +SWAP +MPPEM +LTEQ +IF +SWAP +DUP +RCVT +DUP +ABS +PUSHB_1 + 64 +LT +IF +RUTG +EIF +ROUND[Grey] +ROLL +ADD +EIF +WCVTP +ENDF +FDEF +PUSHB_1 + 0 +SZPS +PUSHB_1 + 2 +CINDEX +PUSHB_1 + 2 +CINDEX +SVTCA[x-axis] +PUSHB_1 + 1 +SWAP +MIAP[no-rnd] +SVTCA[y-axis] +PUSHB_1 + 2 +SWAP +MIAP[no-rnd] +PUSHB_2 + 1 + 2 +SPVTL[parallel] +GPV +PUSHB_1 + 10 +SWAP +NEG +WS +PUSHB_1 + 11 +SWAP +WS +SVTCA[x-axis] +PUSHB_1 + 1 +SWAP +MIAP[rnd] +SVTCA[y-axis] +PUSHB_1 + 2 +SWAP +MIAP[rnd] +PUSHB_2 + 1 + 2 +SPVTL[parallel] +GPV +PUSHB_1 + 6 +SWAP +NEG +WS +PUSHB_1 + 7 +SWAP +WS +PUSHB_1 + 1 +SZPS +SVTCA[x-axis] +ENDF +FDEF +PUSHB_1 + 128 +PUSHB_1 + 2 +RS +LT +PUSHB_1 + 1 +PUSHB_1 + 2 +RS +EQ +OR +IF +POP +SWAP +SRP0 +PUSHB_1 + 32 +SMD +MDRP[min,black] +ELSE +ROLL +SRP0 +MIRP[min,rnd,black] +EIF +ENDF +FDEF +PUSHB_1 + 89 +CALL +ENDF +FDEF +ROLL +SRP0 +MIRP[rnd,black] +ENDF +EndTTInstrs +ShortTable: cvt 127 + 1556 + 11 + 80 + 1462 + 23 + 117 + 1462 + 23 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 1096 + 20 + 0 + 0 + -20 + 0 + 0 + -20 + 0 + 0 + -20 + 0 + -492 + -10 + 0 + 1462 + 19 + -876 + -19 + -385 + -406 + -324 + -182 + -512 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 2048 + 0 + 0 + 307 + 9 + 0 + 246 + 14 + 1462 + 13 + -332 + -770 + -12 + -160 + -12 + 770 + 12 + 391 + -14 + 832 + 14 + 565 + -13 + 682 + 13 + 0 + 149 + 143 + 135 + 125 + 156 + 164 + 229 + 139 + 0 + 0 + 0 + 0 + 162 + 166 + 154 + 143 + 131 + 106 + 0 + 0 + 0 + 0 + 153 + 158 + 164 + 145 + 133 + 0 + 0 + 0 + 0 + 0 + 277 + 155 +EndShort +ShortTable: maxp 16 + 1 + 0 + 234 + 338 + 84 + 132 + 11 + 2 + 16 + 23 + 92 + 0 + 457 + 843 + 3 + 1 +EndShort +LangName: 1033 "" "" "Regular" "Monotype Imaging - Noto Sans" "" "Version 1.04" "" "" "" "" "" "" "" "" "http://www.apache.org/licenses/LICENSE-2.0" +GaspTable: 3 8 10 14 7 65535 15 1 +Encoding: UnicodeBmp +Compacted: 1 +UnicodeInterp: none +NameList: AGL For New Fonts +DisplaySize: -48 +AntiAlias: 1 +FitToEm: 0 +WinInfo: 0 38 14 +BeginChars: 65544 30 + +StartChar: at +Encoding: 64 64 0 +Width: 1841 +GlyphClass: 2 +Flags: W +TtInstrs: +NPUSHB + 37 + 42 + 23 + 21 + 36 + 47 + 55 + 14 + 21 + 60 + 0 + 28 + 28 + 60 + 14 + 47 + 4 + 65 + 66 + 8 + 51 + 62 + 18 + 18 + 51 + 25 + 57 + 4 + 57 + 11 + 11 + 44 + 32 + 51 + 3 + 39 + 44 + 37 +SVTCA[y-axis] +MIAP[rnd] +SHP[rp1] +MIAP[rnd] +SHP[rp1] +SRP2 +IP +MDAP[rnd] +SHP[rp1] +SHP[rp1] +SRP1 +SHP[rp1] +SRP1 +IP +MDAP[rnd] +SHP[rp1] +SRP1 +IP +SRP1 +SRP2 +SVTCA[x-axis] +SLOOP +IP +SRP1 +SHP[rp1] +SRP1 +SHP[rp1] +SRP1 +SHP[rp1] +SRP1 +SHP[rp1] +SRP1 +SHP[rp1] +SHP[rp1] +IUP[x] +IUP[y] +EndTTInstrs +LayerCount: 2 +Fore +SplineSet +1722 731 m 0,0,1 + 1722 591 1722 591 1677.5 473 c 128,-1,2 + 1633 355 1633 355 1553 289 c 128,-1,3 + 1473 223 1473 223 1368 223 c 0,4,5 + 1283 223 1283 223 1225 272.5 c 128,-1,6 + 1167 322 1167 322 1153 401 c 1,7,-1 + 1143 401 l 1,8,9 + 1104 318 1104 318 1029 270.5 c 128,-1,10 + 954 223 954 223 854 223 c 0,11,12 + 702 223 702 223 615 324.5 c 128,-1,13 + 528 426 528 426 528 604 c 0,14,15 + 528 737 528 737 581.5 842.5 c 128,-1,16 + 635 948 635 948 735 1006.5 c 128,-1,17 + 835 1065 835 1065 963 1065 c 0,18,19 + 1032 1065 1032 1065 1120.5 1052.5 c 128,-1,20 + 1209 1040 1209 1040 1276 1016 c 1,21,-1 + 1253 548 l 1,22,-1 + 1253 526 l 2,23,24 + 1253 350 1253 350 1380 350 c 0,25,26 + 1469 350 1469 350 1524 455 c 128,-1,27 + 1579 560 1579 560 1579 733 c 0,28,29 + 1579 912 1579 912 1505.5 1047 c 128,-1,30 + 1432 1182 1432 1182 1296.5 1254.5 c 128,-1,31 + 1161 1327 1161 1327 987 1327 c 0,32,33 + 767 1327 767 1327 603.5 1235.5 c 128,-1,34 + 440 1144 440 1144 353 974.5 c 128,-1,35 + 266 805 266 805 266 580 c 0,36,37 + 266 278 266 278 425 115.5 c 128,-1,38 + 584 -47 584 -47 887 -47 c 0,39,40 + 1099 -47 1099 -47 1327 41 c 1,41,-1 + 1327 -98 l 1,42,43 + 1127 -182 1127 -182 887 -182 c 0,44,45 + 523 -182 523 -182 321 17.5 c 128,-1,46 + 119 217 119 217 119 573 c 0,47,48 + 119 832 119 832 226.5 1035.5 c 128,-1,49 + 334 1239 334 1239 532 1350.5 c 128,-1,50 + 730 1462 730 1462 987 1462 c 0,51,52 + 1202 1462 1202 1462 1370.5 1371 c 128,-1,53 + 1539 1280 1539 1280 1630.5 1113 c 128,-1,54 + 1722 946 1722 946 1722 731 c 0,0,1 +688 600 m 0,55,56 + 688 350 688 350 881 350 c 0,57,58 + 1086 350 1086 350 1104 659 c 2,59,-1 + 1116 915 l 1,60,61 + 1043 936 1043 936 965 936 c 0,62,63 + 836 936 836 936 762 847 c 128,-1,64 + 688 758 688 758 688 600 c 0,55,56 +EndSplineSet +EndChar + +StartChar: B +Encoding: 66 66 1 +Width: 1533 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +796 1277 m 1,0,-1 + 933 1277 l 1,1,-1 + 933 1053 l 1,2,-1 + 1124 1053 l 1,3,-1 + 1124 902 l 1,4,-1 + 933 902 l 1,5,-1 + 933 675 l 1,6,-1 + 796 675 l 1,7,-1 + 796 902 l 1,8,-1 + 603 902 l 1,9,-1 + 603 1053 l 1,10,-1 + 796 1053 l 1,11,-1 + 796 1277 l 1,0,-1 +1294 904 m 0,12,13 + 1294 1039 1294 1039 1183 1168 c 0,14,15 + 1164 1187 1164 1187 1132 1232 c 0,16,17 + 1103 1266 1103 1266 1087 1287 c 0,18,19 + 1005 1373 1005 1373 941 1424 c 0,20,21 + 935 1430 935 1430 923 1440 c 0,22,23 + 883 1474 883 1474 863 1486 c 1,24,25 + 814 1457 814 1457 765 1408 c 1,26,27 + 714 1367 714 1367 632 1279 c 0,28,29 + 628 1275 628 1275 618 1264 c 0,30,31 + 599 1246 599 1246 569 1207 c 0,32,33 + 552 1184 552 1184 544 1174 c 0,34,35 + 435 1049 435 1049 435 904 c 0,36,37 + 435 812 435 812 483 724 c 0,38,39 + 532 640 532 640 607 591 c 1,40,-1 + 1126 591 l 1,41,42 + 1201 642 1201 642 1246 724 c 0,43,44 + 1294 812 1294 812 1294 904 c 0,12,13 +646 412 m 1,45,-1 + 1083 412 l 1,46,-1 + 1083 457 l 1,47,-1 + 646 457 l 1,48,-1 + 646 412 l 1,45,-1 +1220 275 m 1,49,-1 + 1064 275 l 1,50,-1 + 1064 267 l 1,51,-1 + 1072 263 l 1,52,53 + 1117 226 1117 226 1158 201 c 0,54,55 + 1185 185 1185 185 1203 185 c 0,56,57 + 1236 185 1236 185 1255 216 c 0,58,59 + 1298 286 1298 286 1339 402 c 1,60,-1 + 1435 249 l 1,61,62 + 1398 165 1398 165 1347 113 c 1,63,64 + 1291 5 1291 5 1203 5 c 0,65,66 + 1156 5 1156 5 1103 31 c 0,67,68 + 1052 58 1052 58 1001 99 c 1,69,-1 + 995 103 l 2,70,71 + 939 144 939 144 911 163 c 0,72,73 + 888 177 888 177 863 177 c 0,74,75 + 839 177 839 177 814 160 c 0,76,77 + 806 154 806 154 794 146 c 0,78,79 + 755 120 755 120 728 97 c 0,80,81 + 671 52 671 52 626 31 c 0,82,83 + 569 5 569 5 521 5 c 0,84,85 + 437 5 437 5 380 74 c 0,86,87 + 331 134 331 134 290 249 c 1,88,-1 + 392 398 l 1,89,90 + 435 277 435 277 472 216 c 1,91,92 + 497 185 497 185 521 185 c 0,93,94 + 544 185 544 185 566 201 c 0,95,96 + 618 232 618 232 655 259 c 1,97,-1 + 659 263 l 2,98,99 + 665 271 665 271 673 279 c 1,100,-1 + 507 279 l 1,101,-1 + 507 492 l 1,102,103 + 417 560 417 560 358 668 c 0,104,105 + 296 787 296 787 296 904 c 0,106,107 + 296 994 296 994 333 1087 c 128,-1,108 + 370 1180 370 1180 444 1264 c 0,109,110 + 458 1283 458 1283 468 1293 c 0,111,112 + 503 1336 503 1336 517 1350 c 0,113,114 + 554 1395 554 1395 650 1483 c 1,115,-1 + 652 1486 l 1,116,117 + 771 1596 771 1596 863 1641 c 1,118,119 + 913 1617 913 1617 964 1579 c 128,-1,120 + 1015 1541 1015 1541 1062 1496 c 2,121,-1 + 1103 1459 l 2,122,123 + 1164 1402 1164 1402 1191 1369 c 0,124,125 + 1210 1348 1210 1348 1242 1309 c 2,126,-1 + 1285 1256 l 2,127,128 + 1431 1079 1431 1079 1431 904 c 0,129,130 + 1431 785 1431 785 1371 668 c 0,131,132 + 1318 566 1318 566 1220 492 c 1,133,-1 + 1220 275 l 1,49,-1 +EndSplineSet +EndChar + +StartChar: K +Encoding: 75 75 2 +Width: 1533 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +866 851 m 1,0,1 + 868 849 868 849 872 841 c 1,2,3 + 889 892 889 892 909 966 c 0,4,5 + 920 1021 920 1021 920 1060 c 0,6,7 + 920 1088 920 1088 897 1117 c 0,8,9 + 895 1121 895 1121 887 1129 c 0,10,11 + 879 1136 879 1136 864 1136 c 0,12,13 + 858 1136 858 1136 846 1129 c 2,14,15 + 846 1129 846 1129 842 1127 c 0,16,17 + 836 1125 836 1125 825 1115 c 2,18,-1 + 821 1111 l 2,19,20 + 813 1099 813 1099 812 1089.5 c 128,-1,21 + 811 1080 811 1080 811 1060 c 0,22,23 + 811 1006 811 1006 821 968 c 0,24,25 + 826 949 826 949 850 871 c 2,26,-1 + 858 845 l 1,27,28 + 862 847 862 847 866 851 c 1,0,1 +805 470 m 1,29,30 + 805 531 805 531 801 600 c 128,-1,31 + 797 669 797 669 786 705 c 0,32,33 + 760 814 760 814 721 884 c 1,34,35 + 676 937 676 937 631 957 c 1,36,37 + 580 992 580 992 528 992 c 0,38,39 + 467 992 467 992 420 927 c 1,40,41 + 371 851 371 851 371 750 c 0,42,43 + 371 689 371 689 397 632 c 1,44,45 + 436 566 436 566 479 515 c 0,46,47 + 485 509 485 509 496 497 c 0,48,49 + 514 478 514 478 518 470 c 1,50,-1 + 805 470 l 1,29,30 +1214 468 m 1,51,52 + 1219 476 1219 476 1237 497 c 0,53,54 + 1249 513 1249 513 1251 515 c 0,55,56 + 1298 572 1298 572 1331 632 c 0,57,58 + 1360 685 1360 685 1360 750 c 0,59,60 + 1360 845 1360 845 1311 927 c 1,61,62 + 1264 992 1264 992 1202 992 c 0,63,64 + 1153 992 1153 992 1098 957 c 0,65,66 + 1044 918 1044 918 1010 853 c 0,67,68 + 967 775 967 775 946 691 c 0,69,70 + 934 652 934 652 928 586.5 c 128,-1,71 + 922 521 922 521 922 470 c 1,72,-1 + 1214 468 l 1,51,52 +631 126 m 1,73,-1 + 1087 126 l 1,74,-1 + 1087 277 l 1,75,-1 + 631 277 l 1,76,-1 + 631 126 l 1,73,-1 +791 1246 m 1,77,-1 + 791 1328 l 1,78,-1 + 592 1328 l 1,79,-1 + 592 1457 l 1,80,-1 + 791 1457 l 1,81,-1 + 791 1625 l 1,82,-1 + 932 1625 l 1,83,-1 + 932 1457 l 1,84,-1 + 1130 1457 l 1,85,-1 + 1130 1328 l 1,86,-1 + 932 1328 l 1,87,-1 + 932 1246 l 1,88,89 + 942 1242 942 1242 946 1238 c 2,90,-1 + 956 1228 l 2,91,92 + 958 1224 958 1224 961 1222 c 0,93,94 + 965 1219 965 1219 973 1211 c 0,95,96 + 989 1197 989 1197 995 1187 c 0,97,98 + 1016 1156 1016 1156 1024 1128 c 0,99,100 + 1030 1108 1030 1108 1032 1079 c 1,101,102 + 1049 1088 1049 1088 1077 1097 c 1,103,104 + 1128 1127 1128 1127 1202 1127 c 0,105,106 + 1266 1127 1266 1127 1311 1097 c 0,107,108 + 1364 1060 1364 1060 1395 1013 c 0,109,110 + 1436 953 1436 953 1450 894 c 1,111,112 + 1473 828 1473 828 1473 750 c 0,113,114 + 1473 654 1473 654 1434 572 c 0,115,116 + 1405 517 1405 517 1333 419 c 0,117,118 + 1323 404 1323 404 1303.5 387 c 128,-1,119 + 1284 370 1284 370 1262 353 c 0,120,121 + 1233 329 1233 329 1229 322 c 1,122,-1 + 1229 -3 l 1,123,-1 + 489 -3 l 1,124,-1 + 489 327 l 2,125,126 + 489 335 489 335 453 365 c 0,127,128 + 412 400 412 400 397 419 c 0,129,130 + 328 531 328 531 297 601 c 1,131,132 + 256 667 256 667 256 750 c 0,133,134 + 256 826 256 826 276 896 c 1,135,136 + 303 963 303 963 334 1013 c 0,137,138 + 367 1060 367 1060 420 1099 c 1,139,140 + 467 1127 467 1127 528 1127 c 0,141,142 + 602 1127 602 1127 653 1097 c 1,143,144 + 670 1107 670 1107 678 1117 c 1,145,146 + 680 1113 680 1113 684 1093 c 0,147,148 + 694 1056 694 1056 698 1029 c 1,149,150 + 696 1043 696 1043 696 1060 c 0,151,152 + 696 1101 696 1101 704.5 1124.5 c 128,-1,153 + 713 1148 713 1148 733 1183 c 0,154,155 + 743 1201 743 1201 766 1219 c 1,156,-1 + 770 1224 l 2,157,158 + 772 1226 772 1226 776 1232 c 0,159,160 + 782 1242 782 1242 791 1246 c 1,77,-1 +EndSplineSet +Kerns2: 5 -20 "'kern' Horizontal Kerning lookup 0 subtable" 4 -20 "'kern' Horizontal Kerning lookup 0 subtable" +EndChar + +StartChar: N +Encoding: 78 78 3 +Width: 1654 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +956 882 m 1,0,-1 + 1057 882 l 1,1,-1 + 1057 757 l 2,2,3 + 1057 683 1057 683 1030 617 c 1,4,5 + 1001 521 1001 521 952 458 c 2,6,-1 + 780 245 l 2,7,8 + 762 222 762 222 739 173 c 0,9,10 + 723 140 723 140 719 124 c 1,11,-1 + 1413 124 l 1,12,-1 + 1413 408 l 2,13,14 + 1413 583 1413 583 1374 738 c 0,15,16 + 1327 912 1327 912 1255 1033 c 1,17,18 + 1178 1142 1178 1142 1075 1217 c 1,19,20 + 975 1306 975 1306 856 1342 c 1,21,-1 + 764 1359 l 1,22,-1 + 426 535 l 2,23,24 + 422 515 422 515 422 503 c 0,25,26 + 422 472 422 472 436 451 c 0,27,28 + 440 439 440 439 451 439 c 0,29,30 + 471 439 471 439 496 447 c 0,31,32 + 498 449 498 449 504 451 c 0,33,34 + 532 468 532 468 541 476 c 2,35,-1 + 956 882 l 1,0,-1 +924 685 m 1,36,37 + 924 685 924 685 627 382 c 0,38,39 + 604 353 604 353 545 331 c 0,40,41 + 498 310 498 310 451 310 c 0,42,43 + 385 310 385 310 342 406 c 1,44,45 + 301 447 301 447 301 503 c 0,46,47 + 301 551 301 551 319 595 c 2,48,-1 + 653 1404 l 1,49,-1 + 549 1627 l 1,50,-1 + 901 1463 l 1,51,52 + 1046 1414 1046 1414 1155 1314 c 1,53,54 + 1274 1211 1274 1211 1358 1070 c 0,55,56 + 1448 923 1448 923 1491 757 c 0,57,58 + 1536 595 1536 595 1536 408 c 2,59,-1 + 1536 -3 l 1,60,-1 + 586 -3 l 1,61,62 + 586 92 586 92 610 167 c 0,63,64 + 640 260 640 260 686 327 c 1,65,-1 + 860 538 l 2,66,67 + 897 587 897 587 907 617 c 0,68,69 + 913 626 913 626 917.5 646.5 c 128,-1,70 + 922 667 922 667 924 685 c 1,36,37 +EndSplineSet +EndChar + +StartChar: O +Encoding: 79 79 4 +Width: 1599 +GlyphClass: 2 +Flags: W +TtInstrs: +NPUSHB + 20 + 12 + 6 + 0 + 18 + 6 + 18 + 24 + 25 + 9 + 21 + 105 + 89 + 9 + 4 + 3 + 15 + 105 + 89 + 3 + 19 +SVTCA[y-axis] +MIAP[rnd] +CALL +SVTCA[y-axis] +RTG +MIAP[rnd] +CALL +SRP1 +SRP2 +SVTCA[x-axis] +IP +IP +SRP1 +SHP[rp1] +SRP1 +SHP[rp1] +IUP[x] +IUP[y] +EndTTInstrs +LayerCount: 2 +Fore +SplineSet +1475 733 m 0,0,1 + 1475 382 1475 382 1297.5 181 c 128,-1,2 + 1120 -20 1120 -20 801 -20 c 0,3,4 + 478 -20 478 -20 301.5 177.5 c 128,-1,5 + 125 375 125 375 125 735 c 0,6,7 + 125 1092 125 1092 300.5 1288.5 c 128,-1,8 + 476 1485 476 1485 803 1485 c 0,9,10 + 1121 1485 1121 1485 1298 1285.5 c 128,-1,11 + 1475 1086 1475 1086 1475 733 c 0,0,1 +319 733 m 0,12,13 + 319 443 319 443 442 291 c 128,-1,14 + 565 139 565 139 801 139 c 0,15,16 + 1036 139 1036 139 1158 289 c 128,-1,17 + 1280 439 1280 439 1280 733 c 0,18,19 + 1280 1026 1280 1026 1159 1174.5 c 128,-1,20 + 1038 1323 1038 1323 803 1323 c 0,21,22 + 565 1323 565 1323 442 1172.5 c 128,-1,23 + 319 1022 319 1022 319 733 c 0,12,13 +EndSplineSet +EndChar + +StartChar: Q +Encoding: 81 81 5 +Width: 1533 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +588 140 m 1,0,-1 + 1071 140 l 1,1,-1 + 1071 322 l 1,2,-1 + 588 322 l 1,3,-1 + 588 140 l 1,0,-1 +1192 605 m 1,4,-1 + 467 605 l 1,5,-1 + 553 464 l 1,6,-1 + 1108 464 l 1,7,-1 + 1192 605 l 1,4,-1 +1071 1449 m 1,8,-1 + 1071 736 l 1,9,-1 + 1259 736 l 1,10,-1 + 1259 1287 l 1,11,12 + 1225 1318 1225 1318 1225 1363 c 0,13,14 + 1225 1406 1225 1406 1256.5 1435.5 c 128,-1,15 + 1288 1465 1288 1465 1331 1465 c 128,-1,16 + 1374 1465 1374 1465 1406 1434.5 c 128,-1,17 + 1438 1404 1438 1404 1438 1363 c 0,18,19 + 1438 1316 1438 1316 1405 1287 c 1,20,-1 + 1405 679 l 1,21,-1 + 1216 368 l 1,22,-1 + 1216 -3 l 1,23,-1 + 442 -3 l 1,24,-1 + 442 368 l 1,25,-1 + 252 679 l 1,26,-1 + 252 1287 l 1,27,28 + 217 1316 217 1316 217 1363 c 0,29,30 + 217 1404 217 1404 248.5 1434.5 c 128,-1,31 + 280 1465 280 1465 323 1465 c 0,32,33 + 367 1465 367 1465 398.5 1434.5 c 128,-1,34 + 430 1404 430 1404 430 1363 c 0,35,36 + 430 1316 430 1316 397 1287 c 1,37,-1 + 397 736 l 1,38,-1 + 590 736 l 1,39,-1 + 590 1447 l 1,40,41 + 553 1478 553 1478 553 1523 c 0,42,43 + 553 1566 553 1566 584.5 1596.5 c 128,-1,44 + 616 1627 616 1627 659 1627 c 0,45,46 + 704 1627 704 1627 735 1596.5 c 128,-1,47 + 766 1566 766 1566 766 1523 c 0,48,49 + 766 1490 766 1490 735 1451 c 1,50,-1 + 735 734 l 1,51,-1 + 924 734 l 1,52,-1 + 924 1443 l 1,53,54 + 889 1473 889 1473 889 1523 c 0,55,56 + 889 1566 889 1566 919.5 1596.5 c 128,-1,57 + 950 1627 950 1627 995 1627 c 0,58,59 + 1038 1627 1038 1627 1069 1596.5 c 128,-1,60 + 1100 1566 1100 1566 1100 1523 c 0,61,62 + 1100 1482 1100 1482 1071 1449 c 1,8,-1 +EndSplineSet +EndChar + +StartChar: R +Encoding: 82 82 6 +Width: 1533 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +1222 1192 m 1,0,-1 + 1222 1386 l 1,1,-1 + 1175 1386 l 1,2,-1 + 1175 1269 l 1,3,-1 + 856 1269 l 1,4,-1 + 856 1386 l 1,5,-1 + 811 1386 l 1,6,-1 + 811 1269 l 1,7,-1 + 491 1269 l 1,8,-1 + 491 1386 l 1,9,-1 + 444 1386 l 1,10,-1 + 444 1202 l 1,11,-1 + 555 1110 l 1,12,-1 + 1114 1110 l 1,13,-1 + 1222 1192 l 1,0,-1 +614 983 m 1,14,-1 + 614 590 l 1,15,-1 + 1050 590 l 1,16,-1 + 1050 983 l 1,17,-1 + 614 983 l 1,14,-1 +1319 211 m 1,18,-1 + 1108 465 l 1,19,-1 + 559 465 l 1,20,-1 + 350 209 l 1,21,-1 + 350 131 l 1,22,-1 + 1319 131 l 1,23,-1 + 1319 211 l 1,18,-1 +1442 256 m 1,24,-1 + 1442 0 l 1,25,-1 + 225 0 l 1,26,-1 + 225 256 l 1,27,-1 + 491 571 l 1,28,-1 + 491 999 l 1,29,-1 + 319 1143 l 1,30,-1 + 319 1511 l 1,31,-1 + 614 1511 l 1,32,-1 + 614 1401 l 1,33,-1 + 684 1401 l 1,34,-1 + 684 1511 l 1,35,-1 + 981 1511 l 1,36,-1 + 981 1401 l 1,37,-1 + 1050 1401 l 1,38,-1 + 1050 1511 l 1,39,-1 + 1347 1511 l 1,40,-1 + 1347 1138 l 1,41,-1 + 1175 999 l 1,42,-1 + 1175 571 l 1,43,-1 + 1442 256 l 1,24,-1 +EndSplineSet +EndChar + +StartChar: a +Encoding: 97 97 7 +Width: 1149 +GlyphClass: 2 +Flags: W +TtInstrs: +NPUSHB + 47 + 19 + 35 + 35 + 8 + 11 + 30 + 26 + 1 + 1 + 30 + 8 + 3 + 38 + 39 + 2 + 0 + 22 + 11 + 31 + 96 + 89 + 15 + 11 + 31 + 11 + 127 + 11 + 3 + 29 + 3 + 11 + 11 + 22 + 0 + 21 + 22 + 15 + 94 + 89 + 22 + 16 + 5 + 27 + 94 + 89 + 5 + 22 +SVTCA[y-axis] +MIAP[rnd] +CALL +SVTCA[y-axis] +RTG +MIAP[rnd] +CALL +SVTCA[y-axis] +RTG +MIAP[rnd] +SRP2 +IP +MDAP[rnd] +SDS +SDB +DELTAP1 +CALL +SRP1 +SRP2 +SVTCA[y-axis] +IP +SRP1 +SRP2 +SVTCA[x-axis] +SLOOP +IP +SRP1 +SHP[rp1] +SRP1 +SHP[rp1] +SRP1 +SHP[rp1] +SRP1 +SHP[rp1] +IUP[x] +IUP[y] +EndTTInstrs +LayerCount: 2 +Fore +SplineSet +852 0 m 1,0,-1 + 817 156 l 1,1,-1 + 809 156 l 1,2,3 + 727 53 727 53 645.5 16.5 c 128,-1,4 + 564 -20 564 -20 440 -20 c 0,5,6 + 278 -20 278 -20 186 65 c 128,-1,7 + 94 150 94 150 94 305 c 0,8,9 + 94 639 94 639 621 655 c 2,10,-1 + 807 662 l 1,11,-1 + 807 727 l 2,12,13 + 807 852 807 852 753 911.5 c 128,-1,14 + 699 971 699 971 580 971 c 0,15,16 + 493 971 493 971 415.5 945 c 128,-1,17 + 338 919 338 919 270 887 c 1,18,-1 + 215 1022 l 1,19,20 + 298 1066 298 1066 396 1091 c 128,-1,21 + 494 1116 494 1116 590 1116 c 0,22,23 + 789 1116 789 1116 886 1028 c 128,-1,24 + 983 940 983 940 983 748 c 2,25,-1 + 983 0 l 1,26,-1 + 852 0 l 1,0,-1 +481 125 m 0,27,28 + 632 125 632 125 718.5 206.5 c 128,-1,29 + 805 288 805 288 805 438 c 2,30,-1 + 805 537 l 1,31,-1 + 643 530 l 2,32,33 + 454 523 454 523 367.5 470 c 128,-1,34 + 281 417 281 417 281 303 c 0,35,36 + 281 217 281 217 333.5 171 c 128,-1,37 + 386 125 386 125 481 125 c 0,27,28 +EndSplineSet +EndChar + +StartChar: b +Encoding: 98 98 8 +Width: 1260 +GlyphClass: 2 +Flags: W +TtInstrs: +NPUSHB + 30 + 18 + 10 + 10 + 13 + 3 + 31 + 13 + 31 + 34 + 35 + 9 + 18 + 6 + 0 + 14 + 0 + 13 + 21 + 0 + 21 + 93 + 89 + 0 + 16 + 6 + 28 + 93 + 89 + 6 + 22 +SVTCA[y-axis] +MIAP[rnd] +CALL +SVTCA[y-axis] +RTG +MIAP[rnd] +CALL +SVTCA[y-axis] +RTG +MIAP[rnd] +MIAP[rnd] +SRP1 +SRP2 +IP +IP +SRP1 +SRP2 +SVTCA[x-axis] +IP +IP +SRP1 +SHP[rp1] +SRP1 +SHP[rp1] +SRP1 +SHP[rp1] +IUP[x] +IUP[y] +EndTTInstrs +LayerCount: 2 +Fore +SplineSet +694 1116 m 0,0,1 + 911 1116 911 1116 1029 966.5 c 128,-1,2 + 1147 817 1147 817 1147 549 c 0,3,4 + 1147 277 1147 277 1027 128.5 c 128,-1,5 + 907 -20 907 -20 694 -20 c 0,6,7 + 583 -20 583 -20 496 20 c 128,-1,8 + 409 60 409 60 354 139 c 1,9,-1 + 340 139 l 1,10,11 + 309 19 309 19 303 0 c 1,12,-1 + 174 0 l 1,13,-1 + 174 1556 l 1,14,-1 + 354 1556 l 1,15,-1 + 354 1178 l 2,16,17 + 354 1065 354 1065 344 952 c 1,18,-1 + 354 952 l 1,19,20 + 465 1116 465 1116 694 1116 c 0,0,1 +664 967 m 0,21,22 + 498 967 498 967 426 873 c 128,-1,23 + 354 779 354 779 354 555 c 2,24,-1 + 354 547 l 2,25,26 + 354 322 354 322 427.5 225.5 c 128,-1,27 + 501 129 501 129 668 129 c 0,28,29 + 816 129 816 129 888.5 237.5 c 128,-1,30 + 961 346 961 346 961 551 c 0,31,32 + 961 759 961 759 888 863 c 128,-1,33 + 815 967 815 967 664 967 c 0,21,22 +EndSplineSet +EndChar + +StartChar: c +Encoding: 99 99 9 +Width: 983 +GlyphClass: 2 +Flags: W +TtInstrs: +NPUSHB + 20 + 15 + 3 + 9 + 21 + 3 + 21 + 23 + 24 + 6 + 12 + 97 + 89 + 6 + 16 + 0 + 18 + 97 + 89 + 0 + 22 +SVTCA[y-axis] +MIAP[rnd] +CALL +SVTCA[y-axis] +RTG +MIAP[rnd] +CALL +SRP1 +SRP2 +SVTCA[x-axis] +IP +IP +SRP1 +SHP[rp1] +SRP1 +SHP[rp1] +IUP[x] +IUP[y] +EndTTInstrs +LayerCount: 2 +Fore +SplineSet +614 -20 m 0,0,1 + 377 -20 377 -20 245 125.5 c 128,-1,2 + 113 271 113 271 113 543 c 0,3,4 + 113 819 113 819 246.5 968.5 c 128,-1,5 + 380 1118 380 1118 627 1118 c 0,6,7 + 707 1118 707 1118 785.5 1101.5 c 128,-1,8 + 864 1085 864 1085 915 1059 c 1,9,-1 + 860 909 l 1,10,11 + 721 961 721 961 623 961 c 0,12,13 + 457 961 457 961 378 856.5 c 128,-1,14 + 299 752 299 752 299 545 c 0,15,16 + 299 346 299 346 378 240.5 c 128,-1,17 + 457 135 457 135 612 135 c 0,18,19 + 757 135 757 135 897 199 c 1,20,-1 + 897 39 l 1,21,22 + 783 -20 783 -20 614 -20 c 0,0,1 +EndSplineSet +EndChar + +StartChar: d +Encoding: 100 100 10 +Width: 1260 +GlyphClass: 2 +Flags: W +TtInstrs: +NPUSHB + 33 + 30 + 3 + 12 + 23 + 15 + 9 + 17 + 17 + 23 + 3 + 3 + 33 + 34 + 18 + 8 + 0 + 6 + 13 + 0 + 16 + 21 + 6 + 27 + 93 + 89 + 6 + 16 + 0 + 20 + 93 + 89 + 0 + 22 +SVTCA[y-axis] +MIAP[rnd] +CALL +SVTCA[y-axis] +RTG +MIAP[rnd] +CALL +SVTCA[y-axis] +RTG +MIAP[rnd] +MIAP[rnd] +SRP1 +SRP2 +IP +IP +SRP1 +SRP2 +SVTCA[x-axis] +SLOOP +IP +SRP1 +SHP[rp1] +SHP[rp1] +SRP1 +SHP[rp1] +SRP1 +SHP[rp1] +IUP[x] +IUP[y] +EndTTInstrs +LayerCount: 2 +Fore +SplineSet +563 -20 m 0,0,1 + 349 -20 349 -20 231 128 c 128,-1,2 + 113 276 113 276 113 547 c 0,3,4 + 113 816 113 816 231.5 967 c 128,-1,5 + 350 1118 350 1118 565 1118 c 0,6,7 + 786 1118 786 1118 905 956 c 1,8,-1 + 918 956 l 1,9,10 + 915 976 915 976 910 1036.5 c 128,-1,11 + 905 1097 905 1097 905 1118 c 2,12,-1 + 905 1556 l 1,13,-1 + 1085 1556 l 1,14,-1 + 1085 0 l 1,15,-1 + 940 0 l 1,16,-1 + 913 147 l 1,17,-1 + 905 147 l 1,18,19 + 790 -20 790 -20 563 -20 c 0,0,1 +592 129 m 0,20,21 + 756 129 756 129 831.5 218.5 c 128,-1,22 + 907 308 907 308 907 512 c 2,23,-1 + 907 545 l 2,24,25 + 907 774 907 774 830.5 871.5 c 128,-1,26 + 754 969 754 969 590 969 c 0,27,28 + 451 969 451 969 375 858.5 c 128,-1,29 + 299 748 299 748 299 543 c 0,30,31 + 299 339 299 339 374.5 234 c 128,-1,32 + 450 129 450 129 592 129 c 0,20,21 +EndSplineSet +EndChar + +StartChar: e +Encoding: 101 101 11 +Width: 1155 +GlyphClass: 2 +Flags: W +TtInstrs: +NPUSHB + 40 + 18 + 10 + 24 + 11 + 3 + 10 + 25 + 3 + 25 + 28 + 29 + 24 + 11 + 94 + 89 + 25 + 24 + 1 + 3 + 15 + 24 + 1 + 16 + 6 + 24 + 24 + 0 + 6 + 6 + 21 + 93 + 89 + 6 + 16 + 0 + 14 + 97 + 89 + 0 + 22 +SVTCA[y-axis] +MIAP[rnd] +CALL +SVTCA[y-axis] +RTG +MIAP[rnd] +CALL +SRP1 +SRP2 +SVTCA[y-axis] +IP +RTG +MDAP[rnd] +SDS +SDB +DELTAP1 +SDS +DELTAP1 +CALL +SRP1 +SRP2 +SVTCA[x-axis] +IP +IP +SRP1 +SHP[rp1] +SRP1 +SHP[rp1] +SHP[rp1] +SRP1 +SHP[rp1] +IUP[x] +IUP[y] +EndTTInstrs +LayerCount: 2 +Fore +SplineSet +641 -20 m 0,0,1 + 394 -20 394 -20 253.5 129.5 c 128,-1,2 + 113 279 113 279 113 541 c 0,3,4 + 113 805 113 805 244 961.5 c 128,-1,5 + 375 1118 375 1118 598 1118 c 0,6,7 + 805 1118 805 1118 928 984.5 c 128,-1,8 + 1051 851 1051 851 1051 623 c 2,9,-1 + 1051 514 l 1,10,-1 + 299 514 l 1,11,12 + 304 327 304 327 394 230 c 128,-1,13 + 484 133 484 133 649 133 c 0,14,15 + 737 133 737 133 816 148.5 c 128,-1,16 + 895 164 895 164 1001 209 c 1,17,-1 + 1001 51 l 1,18,19 + 910 12 910 12 830 -4 c 128,-1,20 + 750 -20 750 -20 641 -20 c 0,0,1 +596 971 m 0,21,22 + 467 971 467 971 392 888 c 128,-1,23 + 317 805 317 805 303 657 c 1,24,-1 + 862 657 l 1,25,26 + 860 811 860 811 791 891 c 128,-1,27 + 722 971 722 971 596 971 c 0,21,22 +EndSplineSet +EndChar + +StartChar: f +Encoding: 102 102 12 +Width: 705 +GlyphClass: 2 +Flags: W +TtInstrs: +NPUSHB + 30 + 13 + 23 + 20 + 2 + 2 + 7 + 3 + 0 + 3 + 5 + 3 + 22 + 23 + 3 + 21 + 11 + 16 + 93 + 89 + 11 + 1 + 1 + 5 + 7 + 5 + 94 + 89 + 20 + 7 + 15 +SVTCA[y-axis] +MIAP[rnd] +SHP[rp1] +CALL +SRP1 +SVTCA[y-axis] +SHP[rp1] +RTG +MIAP[rnd] +CALL +SVTCA[y-axis] +RTG +MIAP[rnd] +SRP1 +SRP2 +SVTCA[x-axis] +SLOOP +IP +SRP1 +SHP[rp1] +SHP[rp1] +SRP1 +SHP[rp1] +SRP1 +SHP[rp1] +IUP[x] +IUP[y] +EndTTInstrs +LayerCount: 2 +Fore +SplineSet +680 958 m 1,0,-1 + 403 958 l 1,1,-1 + 403 0 l 1,2,-1 + 223 0 l 1,3,-1 + 223 958 l 1,4,-1 + 31 958 l 1,5,-1 + 31 1042 l 1,6,-1 + 223 1104 l 1,7,-1 + 223 1167 l 2,8,9 + 223 1367 223 1367 310.5 1467 c 128,-1,10 + 398 1567 398 1567 580 1567 c 0,11,12 + 685 1567 685 1567 793 1530 c 1,13,-1 + 745 1389 l 1,14,15 + 652 1419 652 1419 582 1419 c 0,16,17 + 491 1419 491 1419 447 1359 c 128,-1,18 + 403 1299 403 1299 403 1169 c 2,19,-1 + 403 1098 l 1,20,-1 + 680 1098 l 1,21,-1 + 680 958 l 1,0,-1 +EndSplineSet +EndChar + +StartChar: g +Encoding: 103 103 13 +Width: 1260 +GlyphClass: 2 +Flags: W +TtInstrs: +NPUSHB + 38 + 34 + 10 + 20 + 3 + 40 + 29 + 26 + 14 + 14 + 40 + 20 + 3 + 41 + 42 + 15 + 25 + 17 + 23 + 27 + 15 + 23 + 7 + 93 + 89 + 23 + 16 + 17 + 0 + 93 + 89 + 17 + 22 + 32 + 37 + 93 + 89 + 32 + 27 +SVTCA[y-axis] +MIAP[rnd] +CALL +SVTCA[y-axis] +RTG +MIAP[rnd] +CALL +SVTCA[y-axis] +RTG +MIAP[rnd] +CALL +SVTCA[y-axis] +RTG +MIAP[rnd] +SRP1 +SRP2 +IP +IP +SRP1 +SRP2 +SVTCA[x-axis] +SLOOP +IP +SRP1 +SHP[rp1] +SHP[rp1] +SRP1 +SHP[rp1] +SRP1 +SHP[rp1] +SHP[rp1] +IUP[x] +IUP[y] +EndTTInstrs +LayerCount: 2 +Fore +SplineSet +592 127 m 0,0,1 + 758 127 758 127 833.5 216.5 c 128,-1,2 + 909 306 909 306 909 504 c 2,3,-1 + 909 547 l 2,4,5 + 909 767 909 767 833 867 c 128,-1,6 + 757 967 757 967 588 967 c 0,7,8 + 450 967 450 967 374.5 857.5 c 128,-1,9 + 299 748 299 748 299 545 c 0,10,11 + 299 341 299 341 372.5 234 c 128,-1,12 + 446 127 446 127 592 127 c 0,0,1 +907 10 m 1,13,-1 + 913 145 l 1,14,-1 + 905 145 l 1,15,16 + 794 -20 794 -20 565 -20 c 0,17,18 + 352 -20 352 -20 232.5 128.5 c 128,-1,19 + 113 277 113 277 113 547 c 0,20,21 + 113 812 113 812 233.5 965 c 128,-1,22 + 354 1118 354 1118 563 1118 c 0,23,24 + 786 1118 786 1118 907 952 c 1,25,-1 + 918 952 l 1,26,-1 + 942 1098 l 1,27,-1 + 1085 1098 l 1,28,-1 + 1085 -18 l 2,29,30 + 1085 -254 1085 -254 965.5 -373 c 128,-1,31 + 846 -492 846 -492 594 -492 c 0,32,33 + 354 -492 354 -492 199 -422 c 1,34,-1 + 199 -256 l 1,35,36 + 359 -342 359 -342 604 -342 c 0,37,38 + 744 -342 744 -342 825.5 -260 c 128,-1,39 + 907 -178 907 -178 907 -33 c 2,40,-1 + 907 10 l 1,13,-1 +EndSplineSet +EndChar + +StartChar: h +Encoding: 104 104 14 +Width: 1266 +GlyphClass: 2 +Flags: W +TtInstrs: +NPUSHB + 25 + 14 + 12 + 8 + 8 + 9 + 22 + 0 + 9 + 0 + 23 + 24 + 14 + 9 + 18 + 10 + 0 + 0 + 9 + 21 + 18 + 4 + 93 + 89 + 18 + 16 +SVTCA[y-axis] +MIAP[rnd] +CALL +SVTCA[y-axis] +RTG +MIAP[rnd] +SHP[rp1] +MIAP[rnd] +SRP1 +SRP2 +IP +SRP1 +SRP2 +SVTCA[x-axis] +IP +IP +SRP1 +SHP[rp1] +SRP1 +SHP[rp1] +SRP1 +SHP[rp1] +SHP[rp1] +IUP[x] +IUP[y] +EndTTInstrs +LayerCount: 2 +Fore +SplineSet +922 0 m 1,0,-1 + 922 702 l 2,1,2 + 922 836 922 836 862.5 901.5 c 128,-1,3 + 803 967 803 967 676 967 c 0,4,5 + 509 967 509 967 431.5 874 c 128,-1,6 + 354 781 354 781 354 567 c 2,7,-1 + 354 0 l 1,8,-1 + 174 0 l 1,9,-1 + 174 1556 l 1,10,-1 + 354 1556 l 1,11,-1 + 354 1100 l 2,12,13 + 354 1010 354 1010 344 946 c 1,14,-1 + 356 946 l 1,15,16 + 405 1026 405 1026 495 1071 c 128,-1,17 + 585 1116 585 1116 698 1116 c 0,18,19 + 898 1116 898 1116 999 1020.5 c 128,-1,20 + 1100 925 1100 925 1100 715 c 2,21,-1 + 1100 0 l 1,22,-1 + 922 0 l 1,0,-1 +EndSplineSet +EndChar + +StartChar: glyph180 +Encoding: 0 -1 15 +AltUni2: 000000.ffffffff.0 +Width: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: uni000D +Encoding: 13 13 16 +Width: 532 +Flags: W +LayerCount: 2 +EndChar + +StartChar: numbersign +Encoding: 35 35 17 +Width: 1337 +Flags: W +LayerCount: 2 +Fore +SplineSet +983 807 m 1,0,-1 + 924 496 l 1,1,-1 + 1196 496 l 1,2,-1 + 1196 361 l 1,3,-1 + 897 361 l 1,4,-1 + 828 0 l 1,5,-1 + 684 0 l 1,6,-1 + 755 361 l 1,7,-1 + 470 361 l 1,8,-1 + 400 0 l 1,9,-1 + 259 0 l 1,10,-1 + 325 361 l 1,11,-1 + 70 361 l 1,12,-1 + 70 496 l 1,13,-1 + 351 496 l 1,14,-1 + 413 807 l 1,15,-1 + 144 807 l 1,16,-1 + 144 941 l 1,17,-1 + 437 941 l 1,18,-1 + 505 1295 l 1,19,-1 + 649 1295 l 1,20,-1 + 582 941 l 1,21,-1 + 869 941 l 1,22,-1 + 938 1295 l 1,23,-1 + 1079 1295 l 1,24,-1 + 1010 941 l 1,25,-1 + 1267 941 l 1,26,-1 + 1267 807 l 1,27,-1 + 983 807 l 1,0,-1 +495 496 m 1,28,-1 + 781 496 l 1,29,-1 + 841 807 l 1,30,-1 + 556 807 l 1,31,-1 + 495 496 l 1,28,-1 +EndSplineSet +EndChar + +StartChar: plus +Encoding: 43 43 18 +Width: 1128 +Flags: W +LayerCount: 2 +Fore +SplineSet +489 585 m 1,0,-1 + 102 585 l 1,1,-1 + 102 735 l 1,2,-1 + 489 735 l 1,3,-1 + 489 1123 l 1,4,-1 + 639 1123 l 1,5,-1 + 639 735 l 1,6,-1 + 1026 735 l 1,7,-1 + 1026 585 l 1,8,-1 + 639 585 l 1,9,-1 + 639 199 l 1,10,-1 + 489 199 l 1,11,-1 + 489 585 l 1,0,-1 +453 1274 m 1024,12,-1 +EndSplineSet +EndChar + +StartChar: hyphen +Encoding: 45 45 19 +Width: 696 +Flags: W +LayerCount: 2 +Fore +SplineSet +100 524 m 1,0,-1 + 100 692 l 1,1,-1 + 596 692 l 1,2,-1 + 596 524 l 1,3,-1 + 100 524 l 1,0,-1 +453 1274 m 1024,4,-1 +EndSplineSet +EndChar + +StartChar: one +Encoding: 49 49 20 +Width: 1128 +Flags: W +LayerCount: 2 +Fore +SplineSet +711 0 m 1,0,-1 + 535 0 l 1,1,-1 + 535 913 l 2,2,3 + 535 956 535 956 535.5 1005 c 128,-1,4 + 536 1054 536 1054 537.5 1102.5 c 128,-1,5 + 539 1151 539 1151 540.5 1195.5 c 128,-1,6 + 542 1240 542 1240 543 1274 c 1,7,8 + 526 1256 526 1256 513 1243 c 128,-1,9 + 500 1230 500 1230 486.5 1218 c 128,-1,10 + 473 1206 473 1206 458 1192.5 c 128,-1,11 + 443 1179 443 1179 422 1161 c 2,12,-1 + 274 1040 l 1,13,-1 + 178 1163 l 1,14,-1 + 561 1462 l 1,15,-1 + 711 1462 l 1,16,-1 + 711 0 l 1,0,-1 +EndSplineSet +EndChar + +StartChar: two +Encoding: 50 50 21 +Width: 1128 +Flags: W +LayerCount: 2 +Fore +SplineSet +1008 0 m 1,0,-1 + 96 0 l 1,1,-1 + 96 156 l 1,2,-1 + 446 537 l 2,3,4 + 521 618 521 618 580 685 c 128,-1,5 + 639 752 639 752 680.5 816 c 128,-1,6 + 722 880 722 880 744 944.5 c 128,-1,7 + 766 1009 766 1009 766 1085 c 0,8,9 + 766 1144 766 1144 749 1189 c 128,-1,10 + 732 1234 732 1234 700.5 1265.5 c 128,-1,11 + 669 1297 669 1297 626 1313 c 128,-1,12 + 583 1329 583 1329 530 1329 c 0,13,14 + 435 1329 435 1329 358.5 1290.5 c 128,-1,15 + 282 1252 282 1252 213 1192 c 1,16,-1 + 111 1311 l 1,17,18 + 151 1347 151 1347 197 1378.5 c 128,-1,19 + 243 1410 243 1410 296 1433 c 128,-1,20 + 349 1456 349 1456 408 1469.5 c 128,-1,21 + 467 1483 467 1483 532 1483 c 0,22,23 + 628 1483 628 1483 705.5 1456 c 128,-1,24 + 783 1429 783 1429 837 1378.5 c 128,-1,25 + 891 1328 891 1328 920.5 1255.5 c 128,-1,26 + 950 1183 950 1183 950 1092 c 0,27,28 + 950 1007 950 1007 923.5 930 c 128,-1,29 + 897 853 897 853 850.5 778.5 c 128,-1,30 + 804 704 804 704 739.5 629 c 128,-1,31 + 675 554 675 554 600 473 c 2,32,-1 + 319 174 l 1,33,-1 + 319 166 l 1,34,-1 + 1008 166 l 1,35,-1 + 1008 0 l 1,0,-1 +EndSplineSet +EndChar + +StartChar: three +Encoding: 51 51 22 +Width: 1128 +Flags: W +LayerCount: 2 +Fore +SplineSet +961 1120 m 0,0,1 + 961 1047 961 1047 938 987 c 128,-1,2 + 915 927 915 927 873.5 883 c 128,-1,3 + 832 839 832 839 774 810.5 c 128,-1,4 + 716 782 716 782 645 770 c 1,5,-1 + 645 764 l 1,6,7 + 822 742 822 742 914 651.5 c 128,-1,8 + 1006 561 1006 561 1006 416 c 0,9,10 + 1006 320 1006 320 973.5 240 c 128,-1,11 + 941 160 941 160 875 102 c 128,-1,12 + 809 44 809 44 708 12 c 128,-1,13 + 607 -20 607 -20 469 -20 c 0,14,15 + 360 -20 360 -20 263.5 -3 c 128,-1,16 + 167 14 167 14 82 59 c 1,17,-1 + 82 229 l 1,18,19 + 169 183 169 183 270.5 158 c 128,-1,20 + 372 133 372 133 465 133 c 0,21,22 + 557 133 557 133 624 153 c 128,-1,23 + 691 173 691 173 734.5 210 c 128,-1,24 + 778 247 778 247 798.5 301 c 128,-1,25 + 819 355 819 355 819 422 c 0,26,27 + 819 490 819 490 792.5 538.5 c 128,-1,28 + 766 587 766 587 717 618.5 c 128,-1,29 + 668 650 668 650 597.5 665 c 128,-1,30 + 527 680 527 680 438 680 c 2,31,-1 + 305 680 l 1,32,-1 + 305 831 l 1,33,-1 + 438 831 l 2,34,35 + 519 831 519 831 582 851 c 128,-1,36 + 645 871 645 871 687.5 908 c 128,-1,37 + 730 945 730 945 752 996 c 128,-1,38 + 774 1047 774 1047 774 1108 c 0,39,40 + 774 1160 774 1160 756 1201 c 128,-1,41 + 738 1242 738 1242 705 1270.5 c 128,-1,42 + 672 1299 672 1299 626 1314 c 128,-1,43 + 580 1329 580 1329 524 1329 c 0,44,45 + 417 1329 417 1329 335.5 1295.5 c 128,-1,46 + 254 1262 254 1262 180 1208 c 1,47,-1 + 88 1333 l 1,48,49 + 126 1364 126 1364 172.5 1391 c 128,-1,50 + 219 1418 219 1418 274 1438.5 c 128,-1,51 + 329 1459 329 1459 391.5 1471 c 128,-1,52 + 454 1483 454 1483 524 1483 c 0,53,54 + 632 1483 632 1483 713.5 1456 c 128,-1,55 + 795 1429 795 1429 850 1380.5 c 128,-1,56 + 905 1332 905 1332 933 1265.5 c 128,-1,57 + 961 1199 961 1199 961 1120 c 0,0,1 +EndSplineSet +EndChar + +StartChar: four +Encoding: 52 52 23 +Width: 1128 +Flags: W +LayerCount: 2 +Fore +SplineSet +1087 328 m 1,0,-1 + 874 328 l 1,1,-1 + 874 0 l 1,2,-1 + 698 0 l 1,3,-1 + 698 328 l 1,4,-1 + 23 328 l 1,5,-1 + 23 487 l 1,6,-1 + 686 1470 l 1,7,-1 + 874 1470 l 1,8,-1 + 874 494 l 1,9,-1 + 1087 494 l 1,10,-1 + 1087 328 l 1,0,-1 +698 494 m 1,11,-1 + 698 850 l 2,12,13 + 698 906 698 906 699.5 967.5 c 128,-1,14 + 701 1029 701 1029 703 1087.5 c 128,-1,15 + 705 1146 705 1146 707.5 1197 c 128,-1,16 + 710 1248 710 1248 711 1282 c 1,17,-1 + 702 1282 l 1,18,19 + 695 1262 695 1262 684.5 1237.5 c 128,-1,20 + 674 1213 674 1213 661.5 1188.5 c 128,-1,21 + 649 1164 649 1164 636 1141 c 128,-1,22 + 623 1118 623 1118 612 1102 c 2,23,-1 + 201 494 l 1,24,-1 + 698 494 l 1,11,-1 +EndSplineSet +EndChar + +StartChar: five +Encoding: 53 53 24 +Width: 1128 +Flags: W +LayerCount: 2 +Fore +SplineSet +545 897 m 0,0,1 + 644 897 644 897 729.5 869.5 c 128,-1,2 + 815 842 815 842 878.5 788 c 128,-1,3 + 942 734 942 734 978 654 c 128,-1,4 + 1014 574 1014 574 1014 469 c 0,5,6 + 1014 355 1014 355 980 264 c 128,-1,7 + 946 173 946 173 879 110 c 128,-1,8 + 812 47 812 47 713.5 13.5 c 128,-1,9 + 615 -20 615 -20 487 -20 c 0,10,11 + 436 -20 436 -20 386.5 -15 c 128,-1,12 + 337 -10 337 -10 291.5 -0.5 c 128,-1,13 + 246 9 246 9 205 24 c 128,-1,14 + 164 39 164 39 131 59 c 1,15,-1 + 131 231 l 1,16,17 + 164 208 164 208 208.5 190 c 128,-1,18 + 253 172 253 172 302 160 c 128,-1,19 + 351 148 351 148 400.5 141.5 c 128,-1,20 + 450 135 450 135 492 135 c 0,21,22 + 571 135 571 135 633 153.5 c 128,-1,23 + 695 172 695 172 738 211 c 128,-1,24 + 781 250 781 250 804 309 c 128,-1,25 + 827 368 827 368 827 449 c 0,26,27 + 827 592 827 592 739 667.5 c 128,-1,28 + 651 743 651 743 483 743 c 0,29,30 + 456 743 456 743 424.5 740.5 c 128,-1,31 + 393 738 393 738 361.5 734 c 128,-1,32 + 330 730 330 730 301.5 725.5 c 128,-1,33 + 273 721 273 721 252 717 c 1,34,-1 + 162 774 l 1,35,-1 + 217 1462 l 1,36,-1 + 907 1462 l 1,37,-1 + 907 1296 l 1,38,-1 + 375 1296 l 1,39,-1 + 336 877 l 1,40,41 + 368 883 368 883 420.5 890 c 128,-1,42 + 473 897 473 897 545 897 c 0,0,1 +EndSplineSet +EndChar + +StartChar: six +Encoding: 54 54 25 +Width: 1128 +Flags: W +LayerCount: 2 +Fore +SplineSet +113 625 m 0,0,1 + 113 730 113 730 123.5 834 c 128,-1,2 + 134 938 134 938 160.5 1033.5 c 128,-1,3 + 187 1129 187 1129 233 1211 c 128,-1,4 + 279 1293 279 1293 350 1353.5 c 128,-1,5 + 421 1414 421 1414 520 1448.5 c 128,-1,6 + 619 1483 619 1483 752 1483 c 0,7,8 + 771 1483 771 1483 794 1482 c 128,-1,9 + 817 1481 817 1481 840.5 1478.5 c 128,-1,10 + 864 1476 864 1476 885.5 1472.5 c 128,-1,11 + 907 1469 907 1469 924 1464 c 1,12,-1 + 924 1309 l 1,13,14 + 889 1321 889 1321 845 1327 c 128,-1,15 + 801 1333 801 1333 758 1333 c 0,16,17 + 668 1333 668 1333 599.5 1311.5 c 128,-1,18 + 531 1290 531 1290 481 1251 c 128,-1,19 + 431 1212 431 1212 397.5 1158 c 128,-1,20 + 364 1104 364 1104 343 1038.5 c 128,-1,21 + 322 973 322 973 312 899 c 128,-1,22 + 302 825 302 825 299 745 c 1,23,-1 + 311 745 l 1,24,25 + 331 781 331 781 359.5 812.5 c 128,-1,26 + 388 844 388 844 426 866.5 c 128,-1,27 + 464 889 464 889 511.5 902 c 128,-1,28 + 559 915 559 915 618 915 c 0,29,30 + 713 915 713 915 790 885.5 c 128,-1,31 + 867 856 867 856 921 799 c 128,-1,32 + 975 742 975 742 1004.5 659.5 c 128,-1,33 + 1034 577 1034 577 1034 471 c 0,34,35 + 1034 357 1034 357 1003 266 c 128,-1,36 + 972 175 972 175 914 111.5 c 128,-1,37 + 856 48 856 48 774 14 c 128,-1,38 + 692 -20 692 -20 590 -20 c 0,39,40 + 490 -20 490 -20 402.5 19 c 128,-1,41 + 315 58 315 58 251 138 c 128,-1,42 + 187 218 187 218 150 339 c 128,-1,43 + 113 460 113 460 113 625 c 0,0,1 +588 133 m 0,44,45 + 648 133 648 133 697.5 153.5 c 128,-1,46 + 747 174 747 174 783 215.5 c 128,-1,47 + 819 257 819 257 838.5 320.5 c 128,-1,48 + 858 384 858 384 858 471 c 0,49,50 + 858 541 858 541 841.5 596.5 c 128,-1,51 + 825 652 825 652 792 691 c 128,-1,52 + 759 730 759 730 709.5 751 c 128,-1,53 + 660 772 660 772 594 772 c 0,54,55 + 527 772 527 772 471.5 748.5 c 128,-1,56 + 416 725 416 725 377 687.5 c 128,-1,57 + 338 650 338 650 316.5 602 c 128,-1,58 + 295 554 295 554 295 506 c 0,59,60 + 295 439 295 439 313.5 372.5 c 128,-1,61 + 332 306 332 306 368.5 253 c 128,-1,62 + 405 200 405 200 460 166.5 c 128,-1,63 + 515 133 515 133 588 133 c 0,44,45 +EndSplineSet +EndChar + +StartChar: seven +Encoding: 55 55 26 +Width: 1128 +Flags: W +LayerCount: 2 +Fore +SplineSet +281 0 m 1,0,-1 + 844 1296 l 1,1,-1 + 90 1296 l 1,2,-1 + 90 1462 l 1,3,-1 + 1030 1462 l 1,4,-1 + 1030 1317 l 1,5,-1 + 475 0 l 1,6,-1 + 281 0 l 1,0,-1 +EndSplineSet +EndChar + +StartChar: eight +Encoding: 56 56 27 +Width: 1128 +Flags: W +LayerCount: 2 +Fore +SplineSet +565 1485 m 0,0,1 + 649 1485 649 1485 723.5 1463 c 128,-1,2 + 798 1441 798 1441 854.5 1397 c 128,-1,3 + 911 1353 911 1353 944 1287 c 128,-1,4 + 977 1221 977 1221 977 1133 c 0,5,6 + 977 1066 977 1066 957 1012 c 128,-1,7 + 937 958 937 958 902 914.5 c 128,-1,8 + 867 871 867 871 819 836.5 c 128,-1,9 + 771 802 771 802 715 774 c 1,10,11 + 773 743 773 743 828.5 705 c 128,-1,12 + 884 667 884 667 927.5 619.5 c 128,-1,13 + 971 572 971 572 997.5 513 c 128,-1,14 + 1024 454 1024 454 1024 381 c 0,15,16 + 1024 289 1024 289 990.5 214.5 c 128,-1,17 + 957 140 957 140 896.5 88 c 128,-1,18 + 836 36 836 36 751.5 8 c 128,-1,19 + 667 -20 667 -20 565 -20 c 0,20,21 + 455 -20 455 -20 369.5 7 c 128,-1,22 + 284 34 284 34 225.5 84.5 c 128,-1,23 + 167 135 167 135 136.5 208 c 128,-1,24 + 106 281 106 281 106 373 c 0,25,26 + 106 448 106 448 128.5 508 c 128,-1,27 + 151 568 151 568 189 616 c 128,-1,28 + 227 664 227 664 279 701 c 128,-1,29 + 331 738 331 738 389 766 c 1,30,31 + 340 797 340 797 297 833.5 c 128,-1,32 + 254 870 254 870 222.5 915 c 128,-1,33 + 191 960 191 960 172.5 1014.5 c 128,-1,34 + 154 1069 154 1069 154 1135 c 0,35,36 + 154 1222 154 1222 187.5 1287.5 c 128,-1,37 + 221 1353 221 1353 278 1397 c 128,-1,38 + 335 1441 335 1441 409.5 1463 c 128,-1,39 + 484 1485 484 1485 565 1485 c 0,0,1 +285 371 m 0,40,41 + 285 318 285 318 301 273.5 c 128,-1,42 + 317 229 317 229 351 197.5 c 128,-1,43 + 385 166 385 166 437 148.5 c 128,-1,44 + 489 131 489 131 561 131 c 0,45,46 + 631 131 631 131 684.5 148.5 c 128,-1,47 + 738 166 738 166 774 198.5 c 128,-1,48 + 810 231 810 231 828 277 c 128,-1,49 + 846 323 846 323 846 379 c 0,50,51 + 846 431 846 431 826.5 473 c 128,-1,52 + 807 515 807 515 770.5 551 c 128,-1,53 + 734 587 734 587 683 619 c 128,-1,54 + 632 651 632 651 569 682 c 2,55,-1 + 539 696 l 1,56,57 + 413 636 413 636 349 558.5 c 128,-1,58 + 285 481 285 481 285 371 c 0,40,41 +563 1333 m 0,59,60 + 457 1333 457 1333 394.5 1280 c 128,-1,61 + 332 1227 332 1227 332 1126 c 0,62,63 + 332 1069 332 1069 349.5 1028 c 128,-1,64 + 367 987 367 987 398 955 c 128,-1,65 + 429 923 429 923 472.5 897.5 c 128,-1,66 + 516 872 516 872 567 848 c 1,67,68 + 615 870 615 870 657.5 896 c 128,-1,69 + 700 922 700 922 731.5 955 c 128,-1,70 + 763 988 763 988 781 1030 c 128,-1,71 + 799 1072 799 1072 799 1126 c 0,72,73 + 799 1227 799 1227 736 1280 c 128,-1,74 + 673 1333 673 1333 563 1333 c 0,59,60 +967 696 m 1024,75,-1 +EndSplineSet +EndChar + +StartChar: equal +Encoding: 61 61 28 +Width: 1128 +Flags: W +LayerCount: 2 +Fore +SplineSet +102 791 m 1,0,-1 + 102 940 l 1,1,-1 + 1026 940 l 1,2,-1 + 1026 791 l 1,3,-1 + 102 791 l 1,0,-1 +102 381 m 1,4,-1 + 102 531 l 1,5,-1 + 1026 531 l 1,6,-1 + 1026 381 l 1,7,-1 + 102 381 l 1,4,-1 +453 1274 m 1024,8,-1 +EndSplineSet +EndChar + +StartChar: endash +Encoding: 8211 8211 29 +Width: 1024 +Flags: W +LayerCount: 2 +Fore +SplineSet +82 535 m 1,0,-1 + 82 703 l 1,1,-1 + 942 703 l 1,2,-1 + 942 535 l 1,3,-1 + 82 535 l 1,0,-1 +453 1274 m 1024,4,-1 +EndSplineSet +EndChar +EndChars +EndSplineFont diff --git a/public/font/lichess.chess.woff b/public/font/lichess.chess.woff new file mode 100644 index 0000000000..a90d5ba1f2 Binary files /dev/null and b/public/font/lichess.chess.woff differ diff --git a/public/font/lichess.chess.woff2 b/public/font/lichess.chess.woff2 new file mode 100644 index 0000000000..7d7faa2734 Binary files /dev/null and b/public/font/lichess.chess.woff2 differ diff --git a/public/font/lichess.sfd b/public/font/lichess.sfd new file mode 100644 index 0000000000..3ee38f6359 --- /dev/null +++ b/public/font/lichess.sfd @@ -0,0 +1,6927 @@ +SplineFontDB: 3.0 +FontName: lichess +FullName: lichess +FamilyName: lichess +Weight: Book +Version: 1.0 +ItalicAngle: 0 +UnderlinePosition: 0 +UnderlineWidth: 0 +Ascent: 480 +Descent: 32 +InvalidEm: 0 +sfntRevision: 0x00010000 +LayerCount: 2 +Layer: 0 1 "Back" 1 +Layer: 1 1 "Fore" 0 +XUID: [1021 568 66413622 13418983] +StyleMap: 0x0040 +FSType: 8 +OS2Version: 3 +OS2_WeightWidthSlopeOnly: 0 +OS2_UseTypoMetrics: 0 +CreationTime: 1554434404 +ModificationTime: 1556668052 +PfmFamily: 17 +TTFWeight: 400 +TTFWidth: 5 +LineGap: 46 +VLineGap: 0 +Panose: 2 0 5 9 0 0 0 0 0 0 +OS2TypoAscent: 480 +OS2TypoAOffset: 0 +OS2TypoDescent: -32 +OS2TypoDOffset: 0 +OS2TypoLinegap: 46 +OS2WinAscent: 512 +OS2WinAOffset: 0 +OS2WinDescent: 0 +OS2WinDOffset: 0 +HheadAscent: 512 +HheadAOffset: 0 +HheadDescent: 0 +HheadDOffset: 0 +OS2SubXSize: 332 +OS2SubYSize: 358 +OS2SubXOff: 0 +OS2SubYOff: 71 +OS2SupXSize: 332 +OS2SupYSize: 358 +OS2SupXOff: 0 +OS2SupYOff: 245 +OS2StrikeYSize: 25 +OS2StrikeYPos: 132 +OS2CapHeight: 475 +OS2XHeight: 475 +OS2Vendor: 'PfEd' +OS2CodePages: 00000001.00000000 +OS2UnicodeRanges: 00000001.10000000.00000000.00000000 +DEI: 91125 +ShortTable: maxp 16 + 1 + 0 + 115 + 381 + 14 + 0 + 0 + 2 + 0 + 1 + 1 + 0 + 64 + 0 + 0 + 0 +EndShort +LangName: 1033 "" "" "Regular" "FontForge 2.0 : lichess : 5-4-2019" "" "Version 1.0" +GaspTable: 1 65535 2 0 +Encoding: UnicodeBmp +Compacted: 1 +UnicodeInterp: none +NameList: AGL For New Fonts +DisplaySize: -48 +AntiAlias: 1 +FitToEm: 0 +WinInfo: 0 38 14 +BeginChars: 65539 115 + +StartChar: .notdef +Encoding: 0 -1 0 +AltUni2: 000000.ffffffff.0 +Width: 512 +Flags: W +LayerCount: 2 +Fore +Validated: 1 +EndChar + +StartChar: fontawesome-webfont-40 +Encoding: 33 33 1 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +293 119 m 2,0,-1 + 293 173 l 2,1,2 + 293 177 293 177 290 180 c 128,-1,3 + 287 183 287 183 283 183 c 2,4,-1 + 229 183 l 2,5,6 + 225 183 225 183 222 180 c 128,-1,7 + 219 177 219 177 219 173 c 2,8,-1 + 219 119 l 2,9,10 + 219 115 219 115 222 112 c 0,11,12 + 226 110 226 110 229 110 c 2,13,-1 + 283 110 l 2,14,15 + 286 110 286 110 290 112 c 0,16,17 + 293 115 293 115 293 119 c 2,0,-1 +292 226 m 2,18,-1 + 297 357 l 2,19,20 + 297 360 297 360 294 363 c 128,-1,21 + 291 366 291 366 287 366 c 2,22,-1 + 225 366 l 2,23,24 + 221 366 221 366 218 363 c 128,-1,25 + 215 360 215 360 215 357 c 2,26,-1 + 220 226 l 2,27,28 + 220 224 220 224 223 221 c 0,29,30 + 225 219 225 219 229 219 c 2,31,-1 + 282 219 l 2,32,33 + 285 219 285 219 289 221 c 0,34,35 + 292 224 292 224 292 226 c 2,18,-1 +288 493 m 2,36,-1 + 507 91 l 2,37,38 + 518 73 518 73 507 55 c 0,39,40 + 504 49 504 49 494 41 c 0,41,42 + 486 37 486 37 475 37 c 2,43,-1 + 37 37 l 2,44,45 + 26 37 26 37 18 41 c 0,46,47 + 8 49 8 49 5 55 c 0,48,49 + -6 73 -6 73 5 91 c 2,50,-1 + 224 493 l 2,51,52 + 227 499 227 499 237 507 c 0,53,54 + 247 512 247 512 256 512 c 128,-1,55 + 265 512 265 512 275 507 c 0,56,57 + 285 499 285 499 288 493 c 2,36,-1 +EndSplineSet +Validated: 545 +EndChar + +StartChar: link +Encoding: 34 34 2 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +202 136 m 2,0,1 + 209 143 209 143 219 143 c 0,2,3 + 230 143 230 143 238 136 c 0,4,5 + 253 120 253 120 238 100 c 1,6,-1 + 216 80 l 2,7,8 + 187 51 187 51 148 51 c 128,-1,9 + 109 51 109 51 80 80 c 128,-1,10 + 51 109 51 109 51 147 c 0,11,12 + 51 187 51 187 80 216 c 2,13,-1 + 156 292 l 2,14,15 + 192 327 192 327 229 331 c 0,16,17 + 267 335 267 335 295 309 c 0,18,19 + 303 301 303 301 303 291 c 0,20,21 + 303 282 303 282 295 272 c 0,22,23 + 277 256 277 256 259 272 c 0,24,25 + 234 298 234 298 191 255 c 2,26,-1 + 116 180 l 2,27,28 + 102 166 102 166 102 147 c 128,-1,29 + 102 128 102 128 116 116 c 0,30,31 + 130 102 130 102 148 102 c 128,-1,32 + 166 102 166 102 180 116 c 2,33,-1 + 202 136 l 2,0,1 +432 430 m 0,34,35 + 461 401 461 401 461 362 c 128,-1,36 + 461 323 461 323 432 294 c 2,37,-1 + 351 213 l 2,38,39 + 314 176 314 176 274 176 c 0,40,41 + 243 176 243 176 217 202 c 0,42,43 + 210 209 210 209 210 219 c 0,44,45 + 210 230 210 230 217 238 c 0,46,47 + 226 245 226 245 235 245 c 128,-1,48 + 244 245 244 245 253 238 c 0,49,50 + 279 212 279 212 315 250 c 2,51,-1 + 396 330 l 2,52,53 + 411 344 411 344 411 362 c 0,54,55 + 411 382 411 382 396 394 c 0,56,57 + 384 407 384 407 368 410 c 0,58,59 + 351 413 351 413 337 399 c 2,60,-1 + 311 374 l 2,61,62 + 304 367 304 367 293 367 c 128,-1,63 + 282 367 282 367 275 374 c 0,64,65 + 258 390 258 390 275 410 c 2,66,-1 + 301 435 l 2,67,68 + 327 463 327 463 366 461 c 0,69,70 + 404 459 404 459 432 430 c 0,34,35 +EndSplineSet +Validated: 33 +EndChar + +StartChar: rabbit +Encoding: 35 35 3 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +353 59 m 2,0,-1 + 349 60 l 2,1,2 + 345 60 345 60 338 60 c 128,-1,3 + 331 60 331 60 325 60 c 0,4,5 + 299 62 299 62 258 61 c 0,6,7 + 172 58 172 58 161 63 c 2,8,-1 + 158 64 l 1,9,-1 + 158 70 l 2,10,11 + 158 79 158 79 165 85 c 0,12,13 + 184 101 184 101 277 103 c 2,14,-1 + 287 103 l 1,15,-1 + 279 105 l 2,16,17 + 235 114 235 114 218 144 c 0,18,19 + 203 171 203 171 223 193 c 0,20,21 + 235 205 235 205 262 205 c 0,22,23 + 276 205 276 205 280 204 c 2,24,-1 + 287 203 l 2,25,26 + 287 205 287 205 286 207 c 0,27,28 + 275 226 275 226 244 228 c 0,29,30 + 209 231 209 231 194 201 c 0,31,32 + 189 188 189 188 189 172 c 0,33,34 + 189 158 189 158 190 152 c 2,35,-1 + 192 143 l 1,36,-1 + 181 125 l 2,37,38 + 144 67 144 67 132 62 c 0,39,40 + 129 61 129 61 110 60 c 0,41,42 + 86 60 86 60 79 64 c 0,43,44 + 77 65 77 65 77 71 c 0,45,46 + 77 82 77 82 82 87 c 0,47,48 + 88 94 88 94 108 97 c 0,49,50 + 120 99 120 99 122.5 102 c 128,-1,51 + 125 105 125 105 126 118 c 0,52,53 + 129 147 129 147 132 158 c 0,54,55 + 138 183 138 183 129 206 c 0,56,57 + 122 224 122 224 122 233 c 0,58,59 + 120 244 120 244 124 254 c 2,60,-1 + 125 257 l 1,61,-1 + 121 258 l 2,62,63 + 98 261 98 261 93 263 c 0,64,65 + 66 269 66 269 63 285 c 0,66,67 + 55 317 55 317 88 360 c 0,68,69 + 108 386 108 386 134 395 c 0,70,71 + 155 400 155 400 178 395 c 0,72,73 + 179 394 179 394 179.5 395 c 128,-1,74 + 180 396 180 396 182 399 c 0,75,76 + 189 415 189 415 222 438 c 0,77,78 + 260 463 260 463 294 463 c 0,79,80 + 309 463 309 463 312 454 c 0,81,82 + 314 446 314 446 306.5 440 c 128,-1,83 + 299 434 299 434 276 424 c 0,84,85 + 264 419 264 419 264 418 c 1,86,87 + 266 419 266 419 269 420 c 0,88,89 + 311 434 311 434 334 418 c 0,90,91 + 345 410 345 410 340 401 c 0,92,93 + 335 396 335 396 311 390 c 0,94,95 + 277 379 277 379 259 369 c 0,96,97 + 247 363 247 363 233 355 c 2,98,-1 + 222 349 l 1,99,-1 + 223 341 l 2,100,101 + 227 326 227 326 240 321 c 0,102,103 + 249 318 249 318 285 315 c 0,104,105 + 329 312 329 312 345 305 c 0,106,107 + 354 300 354 300 362 293 c 0,108,109 + 405 254 405 254 417 206 c 0,110,111 + 420 184 420 184 419 175 c 2,112,-1 + 419 169 l 1,113,-1 + 425 169 l 2,114,115 + 442 166 442 166 448 151 c 0,116,117 + 451 145 451 145 451 138 c 0,118,119 + 451 133 451 133 449 125 c 0,120,121 + 442 111 442 111 428 108 c 0,122,123 + 411 103 411 103 390 118 c 2,124,-1 + 387 120 l 1,125,-1 + 386 118 l 2,126,127 + 385 116 385 116 384.5 108 c 128,-1,128 + 384 100 384 100 385 95 c 2,129,-1 + 388 83 l 2,130,131 + 391 73 391 73 389 67 c 0,132,133 + 388 65 388 65 379 60 c 0,134,135 + 376 59 376 59 366 58.5 c 128,-1,136 + 356 58 356 58 353 59 c 2,0,-1 +135 309 m 0,137,138 + 145 314 145 314 144.5 325.5 c 128,-1,139 + 144 337 144 337 134 342 c 0,140,141 + 127 346 127 346 120 342 c 0,142,143 + 112 338 112 338 111 331 c 0,144,145 + 110 325 110 325 111 320 c 0,146,147 + 113 312 113 312 120.5 308.5 c 128,-1,148 + 128 305 128 305 135 309 c 0,137,138 +EndSplineSet +Validated: 33 +EndChar + +StartChar: share-alt +Encoding: 36 36 4 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +384 219 m 0,0,1 + 423 219 423 219 449 193 c 128,-1,2 + 475 167 475 167 475 128 c 128,-1,3 + 475 89 475 89 449 63 c 128,-1,4 + 423 37 423 37 384 37 c 128,-1,5 + 345 37 345 37 319 63 c 128,-1,6 + 293 89 293 89 293 128 c 2,7,-1 + 293 138 l 1,8,-1 + 190 189 l 1,9,10 + 164 165 164 165 128 165 c 0,11,12 + 89 165 89 165 63 191 c 128,-1,13 + 37 217 37 217 37 256 c 128,-1,14 + 37 295 37 295 63 321 c 128,-1,15 + 89 347 89 347 128 347 c 0,16,17 + 164 347 164 347 190 323 c 1,18,-1 + 293 374 l 1,19,-1 + 293 384 l 2,20,21 + 293 423 293 423 319 449 c 128,-1,22 + 345 475 345 475 384 475 c 128,-1,23 + 423 475 423 475 449 449 c 128,-1,24 + 475 423 475 423 475 384 c 128,-1,25 + 475 345 475 345 449 319 c 128,-1,26 + 423 293 423 293 384 293 c 0,27,28 + 348 293 348 293 322 317 c 1,29,-1 + 219 266 l 1,30,-1 + 219 256 l 1,31,-1 + 219 246 l 1,32,-1 + 322 195 l 1,33,34 + 348 219 348 219 384 219 c 0,0,1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: gear +Encoding: 37 37 5 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +256 337 m 128,-1,1 + 222 337 222 337 198.5 313.5 c 128,-1,2 + 175 290 175 290 175 256 c 128,-1,3 + 175 222 175 222 198.5 198.5 c 128,-1,4 + 222 175 222 175 256 175 c 128,-1,5 + 290 175 290 175 313.5 198.5 c 128,-1,6 + 337 222 337 222 337 256 c 128,-1,7 + 337 290 337 290 313.5 313.5 c 128,-1,0 + 290 337 290 337 256 337 c 128,-1,1 +418 209 m 1,8,-1 + 404 174 l 1,9,-1 + 430 123 l 1,10,-1 + 433 116 l 1,11,-1 + 397 80 l 1,12,-1 + 338 108 l 1,13,-1 + 303 94 l 1,14,-1 + 285 39 l 1,15,-1 + 283 32 l 1,16,-1 + 232 32 l 1,17,-1 + 210 94 l 1,18,-1 + 174 108 l 1,19,-1 + 123 82 l 1,20,-1 + 116 79 l 1,21,-1 + 80 115 l 1,22,-1 + 108 174 l 1,23,-1 + 94 209 l 1,24,-1 + 39 227 l 1,25,-1 + 32 229 l 1,26,-1 + 32 280 l 1,27,-1 + 94 302 l 1,28,-1 + 108 338 l 1,29,-1 + 82 389 l 1,30,-1 + 79 396 l 1,31,-1 + 115 432 l 1,32,-1 + 174 404 l 1,33,-1 + 209 418 l 1,34,-1 + 227 473 l 1,35,-1 + 229 480 l 1,36,-1 + 280 480 l 1,37,-1 + 302 418 l 1,38,-1 + 338 404 l 1,39,-1 + 389 430 l 1,40,-1 + 396 433 l 1,41,-1 + 432 397 l 1,42,-1 + 404 338 l 1,43,-1 + 418 303 l 1,44,-1 + 473 285 l 1,45,-1 + 480 283 l 1,46,-1 + 480 232 l 1,47,-1 + 418 209 l 1,8,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: repo +Encoding: 38 38 6 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +224 384 m 1,0,-1 + 192 384 l 1,1,-1 + 192 352 l 1,2,-1 + 224 352 l 1,3,-1 + 224 384 l 1,0,-1 +224 448 m 1,4,-1 + 192 448 l 1,5,-1 + 192 416 l 1,6,-1 + 224 416 l 1,7,-1 + 224 448 l 1,4,-1 +416 512 m 2,8,-1 + 96 512 l 2,9,10 + 84 512 84 512 74 502 c 128,-1,11 + 64 492 64 492 64 480 c 2,12,-1 + 64 96 l 2,13,14 + 64 84 64 84 74 74 c 128,-1,15 + 84 64 84 64 96 64 c 2,16,-1 + 160 64 l 1,17,-1 + 160 0 l 1,18,-1 + 208 48 l 1,19,-1 + 256 0 l 1,20,-1 + 256 64 l 1,21,-1 + 416 64 l 2,22,23 + 428 64 428 64 438 74 c 128,-1,24 + 448 84 448 84 448 96 c 2,25,-1 + 448 480 l 2,26,27 + 448 492 448 492 438 502 c 128,-1,28 + 428 512 428 512 416 512 c 2,8,-1 +416 112 m 2,29,30 + 416 106 416 106 411.5 101 c 128,-1,31 + 407 96 407 96 400 96 c 2,32,-1 + 256 96 l 1,33,-1 + 256 128 l 1,34,-1 + 160 128 l 1,35,-1 + 160 96 l 1,36,-1 + 112 96 l 2,37,38 + 106 96 106 96 101 101 c 128,-1,39 + 96 106 96 106 96 112 c 2,40,-1 + 96 160 l 1,41,-1 + 416 160 l 1,42,-1 + 416 112 l 2,29,30 +416 192 m 1,43,-1 + 160 192 l 1,44,-1 + 160 480 l 1,45,-1 + 417 480 l 1,46,-1 + 416 192 l 1,43,-1 +224 256 m 1,47,-1 + 192 256 l 1,48,-1 + 192 224 l 1,49,-1 + 224 224 l 1,50,-1 + 224 256 l 1,47,-1 +224 320 m 1,51,-1 + 192 320 l 1,52,-1 + 192 288 l 1,53,-1 + 224 288 l 1,54,-1 + 224 320 l 1,51,-1 +EndSplineSet +Validated: 9 +EndChar + +StartChar: die-six +Encoding: 39 39 7 +Width: 535 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +458.66015625 405.330078125 m 6,0,1 + 457.5703125 421.6796875 457.5703125 421.6796875 446.125 433.125 c 132,-1,2 + 434.6796875 444.5703125 434.6796875 444.5703125 418.330078125 445.66015625 c 6,3,-1 + 119.669921875 445.66015625 l 6,4,5 + 103.3203125 444.5703125 103.3203125 444.5703125 91.875 433.125 c 132,-1,6 + 80.4296875 421.6796875 80.4296875 421.6796875 79.33984375 405.330078125 c 6,7,-1 + 79.33984375 106.669921875 l 6,8,9 + 80.4296875 90.3203125 80.4296875 90.3203125 91.875 78.875 c 132,-1,10 + 103.3203125 67.4296875 103.3203125 67.4296875 119.669921875 66.33984375 c 6,11,-1 + 418.330078125 66.33984375 l 6,12,13 + 434.6796875 67.4296875 434.6796875 67.4296875 446.125 78.875 c 132,-1,14 + 457.5703125 90.3203125 457.5703125 90.3203125 458.66015625 106.669921875 c 6,15,-1 + 458.66015625 405.330078125 l 6,0,1 +174.169921875 124.110351562 m 132,-1,17 + 157.8203125 124.110351562 157.8203125 124.110351562 146.375 135.5546875 c 132,-1,18 + 134.9296875 147 134.9296875 147 134.9296875 163.349609375 c 132,-1,19 + 134.9296875 179.700195312 134.9296875 179.700195312 146.375 191.14453125 c 132,-1,20 + 157.8203125 202.58984375 157.8203125 202.58984375 174.169921875 202.58984375 c 132,-1,21 + 190.51953125 202.58984375 190.51953125 202.58984375 201.96484375 191.14453125 c 132,-1,22 + 213.41015625 179.700195312 213.41015625 179.700195312 213.41015625 163.349609375 c 132,-1,23 + 213.41015625 147 213.41015625 147 201.96484375 135.5546875 c 132,-1,16 + 190.51953125 124.110351562 190.51953125 124.110351562 174.169921875 124.110351562 c 132,-1,17 +174.169921875 216.759765625 m 132,-1,25 + 157.8203125 216.759765625 157.8203125 216.759765625 146.375 228.205078125 c 132,-1,26 + 134.9296875 239.650390625 134.9296875 239.650390625 134.9296875 256 c 132,-1,27 + 134.9296875 272.349609375 134.9296875 272.349609375 146.375 283.794921875 c 132,-1,28 + 157.8203125 295.240234375 157.8203125 295.240234375 174.169921875 295.240234375 c 132,-1,29 + 190.51953125 295.240234375 190.51953125 295.240234375 201.96484375 283.794921875 c 132,-1,30 + 213.41015625 272.349609375 213.41015625 272.349609375 213.41015625 256 c 132,-1,31 + 213.41015625 239.650390625 213.41015625 239.650390625 201.96484375 228.205078125 c 132,-1,24 + 190.51953125 216.759765625 190.51953125 216.759765625 174.169921875 216.759765625 c 132,-1,25 +174.169921875 311.58984375 m 132,-1,33 + 157.8203125 311.58984375 157.8203125 311.58984375 146.375 323.03515625 c 132,-1,34 + 134.9296875 334.48046875 134.9296875 334.48046875 134.9296875 350.830078125 c 132,-1,35 + 134.9296875 367.1796875 134.9296875 367.1796875 146.375 378.625 c 132,-1,36 + 157.8203125 390.0703125 157.8203125 390.0703125 174.169921875 390.0703125 c 132,-1,37 + 190.51953125 390.0703125 190.51953125 390.0703125 201.96484375 378.625 c 132,-1,38 + 213.41015625 367.1796875 213.41015625 367.1796875 213.41015625 350.830078125 c 132,-1,39 + 213.41015625 334.48046875 213.41015625 334.48046875 201.96484375 323.03515625 c 132,-1,32 + 190.51953125 311.58984375 190.51953125 311.58984375 174.169921875 311.58984375 c 132,-1,33 +363.830078125 121.9296875 m 132,-1,41 + 347.48046875 121.9296875 347.48046875 121.9296875 336.03515625 133.375 c 132,-1,42 + 324.58984375 144.8203125 324.58984375 144.8203125 324.58984375 161.169921875 c 132,-1,43 + 324.58984375 177.51953125 324.58984375 177.51953125 336.03515625 188.96484375 c 132,-1,44 + 347.48046875 200.41015625 347.48046875 200.41015625 363.830078125 200.41015625 c 132,-1,45 + 380.1796875 200.41015625 380.1796875 200.41015625 391.625 188.96484375 c 132,-1,46 + 403.0703125 177.51953125 403.0703125 177.51953125 403.0703125 161.169921875 c 132,-1,47 + 403.0703125 144.8203125 403.0703125 144.8203125 391.625 133.375 c 132,-1,40 + 380.1796875 121.9296875 380.1796875 121.9296875 363.830078125 121.9296875 c 132,-1,41 +363.830078125 216.759765625 m 132,-1,49 + 347.48046875 216.759765625 347.48046875 216.759765625 336.03515625 228.205078125 c 132,-1,50 + 324.58984375 239.650390625 324.58984375 239.650390625 324.58984375 256 c 132,-1,51 + 324.58984375 272.349609375 324.58984375 272.349609375 336.03515625 283.794921875 c 132,-1,52 + 347.48046875 295.240234375 347.48046875 295.240234375 363.830078125 295.240234375 c 132,-1,53 + 380.1796875 295.240234375 380.1796875 295.240234375 391.625 283.794921875 c 132,-1,54 + 403.0703125 272.349609375 403.0703125 272.349609375 403.0703125 256 c 132,-1,55 + 403.0703125 239.650390625 403.0703125 239.650390625 391.625 228.205078125 c 132,-1,48 + 380.1796875 216.759765625 380.1796875 216.759765625 363.830078125 216.759765625 c 132,-1,49 +363.830078125 311.58984375 m 132,-1,57 + 347.48046875 311.58984375 347.48046875 311.58984375 336.03515625 323.03515625 c 132,-1,58 + 324.58984375 334.48046875 324.58984375 334.48046875 324.58984375 350.830078125 c 132,-1,59 + 324.58984375 367.1796875 324.58984375 367.1796875 336.03515625 378.625 c 132,-1,60 + 347.48046875 390.0703125 347.48046875 390.0703125 363.830078125 390.0703125 c 132,-1,61 + 380.1796875 390.0703125 380.1796875 390.0703125 391.625 378.625 c 132,-1,62 + 403.0703125 367.1796875 403.0703125 367.1796875 403.0703125 350.830078125 c 132,-1,63 + 403.0703125 334.48046875 403.0703125 334.48046875 391.625 323.03515625 c 132,-1,56 + 380.1796875 311.58984375 380.1796875 311.58984375 363.830078125 311.58984375 c 132,-1,57 +EndSplineSet +EndChar + +StartChar: flag +Encoding: 40 40 8 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +473 392 m 0,0,1 + 481 395 481 395 484 392 c 0,2,3 + 488 388 488 388 484 382 c 0,4,5 + 434 308 434 308 400 273 c 0,6,7 + 366 235 366 235 344 227 c 0,8,9 + 321 219 321 219 307 226 c 0,10,11 + 294 231 294 231 276 245 c 0,12,13 + 260 258 260 258 244 265 c 0,14,15 + 227 274 227 274 196 263 c 0,16,17 + 163 252 163 252 125 219 c 1,18,-1 + 171 39 l 1,19,-1 + 120 39 l 1,20,-1 + 26 408 l 1,21,-1 + 73 425 l 1,22,23 + 119 459 119 459 151 469 c 0,24,25 + 181 479 181 479 201 471 c 0,26,27 + 220 462 220 462 233 444 c 0,28,29 + 255 420 255 420 265 408 c 0,30,31 + 282 389 282 389 306 376 c 128,-1,32 + 330 363 330 363 372 366 c 0,33,34 + 418 369 418 369 473 392 c 0,0,1 +EndSplineSet +Validated: 33 +EndChar + +StartChar: flame +Encoding: 41 41 9 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +217 489 m 1,0,1 + 248 406 248 406 201 357 c 0,2,3 + 192 348 192 348 150.5 314.5 c 128,-1,4 + 109 281 109 281 89 254 c 0,5,6 + 71 229 71 229 65 195.5 c 128,-1,7 + 59 162 59 162 66 126.5 c 128,-1,8 + 73 91 73 91 107 61 c 128,-1,9 + 141 31 141 31 198 18 c 1,10,11 + 145 45 145 45 140.5 108 c 128,-1,12 + 136 171 136 171 189 221 c 1,13,14 + 175 175 175 175 195 148 c 128,-1,15 + 215 121 215 121 248 133 c 0,16,17 + 279 143 279 143 299 126.5 c 128,-1,18 + 319 110 319 110 318 82 c 0,19,20 + 316 41 316 41 283 26 c 1,21,22 + 332 34 332 34 367 63.5 c 128,-1,23 + 402 93 402 93 416 127 c 128,-1,24 + 430 161 430 161 430 197 c 0,25,26 + 430 225 430 225 418.5 250 c 128,-1,27 + 407 275 407 275 396 288 c 128,-1,28 + 385 301 385 301 380.5 323.5 c 128,-1,29 + 376 346 376 346 391 369 c 1,30,31 + 327 363 327 363 333 284 c 0,32,33 + 335 260 335 260 315.5 246.5 c 128,-1,34 + 296 233 296 233 276 244 c 0,35,36 + 261 253 261 253 260.5 269 c 128,-1,37 + 260 285 260 285 274 298 c 0,38,39 + 295 319 295 319 302 349.5 c 128,-1,40 + 309 380 309 380 289 419.5 c 128,-1,41 + 269 459 269 459 217 489 c 1,0,1 +EndSplineSet +Validated: 41 +EndChar + +StartChar: feather +Encoding: 42 42 10 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +107 6 m 2,0,1 + 104 -4 104 -4 93 2 c 0,2,3 + 85 6 85 6 85 19 c 0,4,5 + 88 73 88 73 111 135 c 1,6,7 + 60 214 60 214 84 297 c 1,8,9 + 92 275 92 275 101 257 c 0,10,11 + 107 244 107 244 123 216 c 0,12,13 + 135 198 135 198 140 201 c 0,14,15 + 143 202 143 202 140 243 c 0,16,17 + 135 284 135 284 134 328 c 0,18,19 + 132 374 132 374 147 409 c 0,20,21 + 157 431 157 431 188 457 c 0,22,23 + 216 482 216 482 241 493 c 1,24,25 + 228 467 228 467 224 444 c 0,26,27 + 219 419 219 419 222 404 c 128,-1,28 + 225 389 225 389 233 388 c 0,29,30 + 238 388 238 388 276 450 c 0,31,32 + 312 511 312 511 330 512 c 0,33,34 + 354 513 354 513 388 497 c 0,35,36 + 424 480 424 480 430 464 c 0,37,38 + 436 452 436 452 430 423 c 0,39,40 + 424 395 424 395 410 381 c 0,41,42 + 387 358 387 358 335 349 c 128,-1,43 + 283 340 283 340 277 337 c 0,44,45 + 269 332 269 332 283 319 c 0,46,47 + 310 295 310 295 373 309 c 1,48,49 + 343 267 343 267 303 251 c 0,50,51 + 265 234 265 234 236 231 c 0,52,53 + 210 230 210 230 208 226 c 0,54,55 + 206 214 206 214 233 199 c 0,56,57 + 259 183 259 183 285 191 c 1,58,59 + 271 164 271 164 253 148 c 0,60,61 + 234 133 234 133 225 131 c 0,62,63 + 214 126 214 126 186 125 c 0,64,65 + 180 125 180 125 143 121 c 1,66,-1 + 107 6 l 2,0,1 +EndSplineSet +Validated: 33 +EndChar + +StartChar: turtle +Encoding: 43 43 11 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +177 221 m 1,0,-1 + 119 221 l 1,1,2 + 124 153 124 153 167 108 c 1,3,-1 + 205 174 l 1,4,-1 + 177 221 l 1,0,-1 +167 364 m 1,5,6 + 124 319 124 319 119 251 c 1,7,-1 + 177 251 l 1,8,-1 + 205 298 l 1,9,-1 + 167 364 l 1,5,6 +335 221 m 1,10,-1 + 307 174 l 1,11,-1 + 345 108 l 1,12,13 + 388 153 388 153 393 221 c 1,14,-1 + 335 221 l 1,10,-1 +280 160 m 1,15,-1 + 232 160 l 1,16,-1 + 190 88 l 1,17,18 + 221 68 221 68 256 68 c 128,-1,19 + 291 68 291 68 322 88 c 1,20,-1 + 280 160 l 1,15,-1 +256 404 m 128,-1,22 + 221 404 221 404 190 384 c 1,23,-1 + 232 312 l 1,24,-1 + 280 312 l 1,25,-1 + 322 384 l 1,26,21 + 291 404 291 404 256 404 c 128,-1,22 +345 364 m 1,27,-1 + 307 298 l 1,28,-1 + 335 251 l 1,29,-1 + 393 251 l 1,30,31 + 388 319 388 319 345 364 c 1,27,-1 +282 282 m 1,32,-1 + 230 282 l 1,33,-1 + 203 236 l 1,34,-1 + 230 190 l 1,35,-1 + 282 190 l 1,36,-1 + 309 236 l 1,37,-1 + 282 282 l 1,32,-1 +453 390 m 0,38,39 + 405 420 405 420 352 399 c 1,40,41 + 365 387 365 387 377 374 c 0,42,43 + 391 357 391 357 405 328 c 1,44,-1 + 512 328 l 1,45,46 + 493 366 493 366 453 390 c 0,38,39 +382 104 m 1,47,48 + 378 100 378 100 377 98 c 0,49,50 + 356 73 356 73 328 57 c 1,51,-1 + 368 0 l 1,52,53 + 397 52 397 52 382 104 c 1,47,48 +135 98 m 0,54,55 + 134 100 134 100 130 104 c 1,56,57 + 115 52 115 52 144 0 c 1,58,-1 + 184 57 l 1,59,60 + 156 73 156 73 135 98 c 0,54,55 +59 390 m 0,61,62 + 19 366 19 366 0 328 c 1,63,-1 + 107 328 l 1,64,65 + 121 356 121 356 135 374 c 0,66,67 + 147 387 147 387 160 399 c 1,68,69 + 107 420 107 420 59 390 c 0,61,62 +256 512 m 128,-1,71 + 236 512 236 512 222 498 c 128,-1,72 + 208 484 208 484 208 464 c 2,73,-1 + 208 426 l 1,74,75 + 232 434 232 434 256 434 c 128,-1,76 + 280 434 280 434 304 426 c 1,77,-1 + 304 464 l 2,78,79 + 304 484 304 484 290 498 c 128,-1,70 + 276 512 276 512 256 512 c 128,-1,71 +EndSplineSet +Validated: 41 +EndChar + +StartChar: nuclear +Encoding: 44 44 12 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +350 263 m 0,0,1 + 344 269 344 269 338 262 c 0,2,3 + 332 256 332 256 339 250 c 0,4,5 + 363 231 363 231 375 203 c 1,6,-1 + 372 203 l 1,7,8 + 346 193 346 193 346 177 c 0,9,10 + 345 173 345 173 324 158 c 1,11,-1 + 322 156 l 2,12,13 + 313 151 313 151 310.5 142 c 128,-1,14 + 308 133 308 133 311 127 c 0,15,16 + 315 116 315 116 326 120 c 0,17,18 + 346 128 346 128 356 120 c 0,19,20 + 364 113 364 113 376 113 c 0,21,22 + 380 113 380 113 381 114 c 1,23,24 + 373 85 373 85 354 64 c 1,25,-1 + 353 65 l 2,26,27 + 352 65 352 65 351 66 c 128,-1,28 + 350 67 350 67 349 69.5 c 128,-1,29 + 348 72 348 72 348 74 c 0,30,31 + 352 97 352 97 343 104 c 0,32,33 + 338 109 338 109 327 101 c 0,34,35 + 322 97 322 97 302 102 c 0,36,37 + 301 102 301 102 298.5 103 c 128,-1,38 + 296 104 296 104 295 104 c 0,39,40 + 268 110 268 110 253 95 c 0,41,42 + 247 89 247 89 250 83 c 0,43,44 + 257 63 257 63 243 55 c 0,45,46 + 235 50 235 50 234 42 c 0,47,48 + 233 32 233 32 240 21 c 1,49,50 + 196 27 196 27 164 59 c 1,51,52 + 173 89 173 89 182 94 c 1,53,54 + 203 91 203 91 211 111 c 0,55,56 + 216 123 216 123 206 131 c 0,57,58 + 191 140 191 140 191 151 c 0,59,60 + 191 169 191 169 174 176 c 0,61,62 + 168 179 168 179 132 185 c 1,63,64 + 143 225 143 225 174 250 c 0,65,66 + 180 256 180 256 175 262 c 0,67,68 + 169 269 169 269 163 263 c 0,69,70 + 110 219 110 219 110 150 c 0,71,72 + 110 89 110 89 153 46 c 128,-1,73 + 196 3 196 3 257 3 c 128,-1,74 + 318 3 318 3 361 46 c 128,-1,75 + 404 89 404 89 404 150 c 0,76,77 + 404 219 404 219 350 263 c 0,0,1 +128 168 m 1,78,79 + 161 164 161 164 166 161 c 0,80,81 + 174 158 174 158 174 151 c 0,82,83 + 174 134 174 134 195 117 c 0,84,85 + 195 114 195 114 192 113 c 0,86,87 + 188 110 188 110 184 110 c 0,88,89 + 174 112 174 112 166 101.5 c 128,-1,90 + 158 91 158 91 151 74 c 1,91,92 + 127 108 127 108 127 150 c 0,93,94 + 127 162 127 162 128 168 c 1,78,79 +252 41 m 0,95,96 + 273 53 273 53 267 84 c 1,97,98 + 276 90 276 90 291 87 c 0,99,100 + 292 87 292 87 294.5 86.5 c 128,-1,101 + 297 86 297 86 298 86 c 0,102,103 + 323 79 323 79 332 84 c 1,104,105 + 332 80 332 80 331 78 c 0,106,107 + 329 63 329 63 342 52 c 1,108,109 + 307 21 307 21 262 20 c 1,110,111 + 250 35 250 35 251 39 c 0,112,113 + 251 40 251 40 252 41 c 0,95,96 +385 132 m 1,114,115 + 374 127 374 127 368 133 c 0,116,117 + 354 145 354 145 328 138 c 1,118,119 + 329 140 329 140 331 142 c 2,120,-1 + 333 143 l 1,121,122 + 362 162 362 162 363 177 c 0,123,124 + 363 181 363 181 378 187 c 0,125,126 + 379 187 379 187 381 189 c 1,127,128 + 387 163 387 163 387 150 c 0,129,130 + 387 144 387 144 385 132 c 1,114,115 +412 432 m 0,131,132 + 401 439 401 439 387 436 c 1,133,134 + 384 451 384 451 370 460 c 0,135,136 + 354 470 354 470 332 472 c 1,137,138 + 306 512 306 512 257 512 c 128,-1,139 + 208 512 208 512 182 472 c 1,140,141 + 163 470 163 470 152 464 c 0,142,143 + 136 457 136 457 130 443 c 1,144,145 + 116 448 116 448 102 440 c 0,146,147 + 83 429 83 429 83 406 c 0,148,149 + 83 381 83 381 103 372 c 0,150,151 + 117 364 117 364 132 369 c 1,152,153 + 140 357 140 357 160 349 c 0,154,155 + 172 345 172 345 189 345 c 0,156,157 + 199 345 199 345 204 346 c 0,158,159 + 206 344 206 344 208.5 342 c 128,-1,160 + 211 340 211 340 212 339 c 0,161,162 + 219 333 219 333 220 327 c 1,163,164 + 212 325 212 325 208 323 c 0,165,166 + 191 313 191 313 191 295 c 128,-1,167 + 191 277 191 277 208 267 c 0,168,169 + 211 264 211 264 216 264 c 1,170,171 + 216 263 216 263 216 262 c 2,172,-1 + 215 260 l 1,173,174 + 211 214 211 214 199 202 c 0,175,176 + 192 197 192 197 199 190 c 0,177,178 + 201 188 201 188 205 188 c 0,179,180 + 207 188 207 188 211 190 c 0,181,182 + 228 207 228 207 232 258 c 0,183,184 + 232 259 232 259 232.5 261 c 128,-1,185 + 233 263 233 263 233 264 c 1,186,187 + 234 264 234 264 236.5 265 c 128,-1,188 + 239 266 239 266 240 267 c 0,189,190 + 247 272 247 272 243 279 c 0,191,192 + 237 287 237 287 231 282 c 0,193,194 + 224 278 224 278 216 282 c 0,195,196 + 208 285 208 285 208 295 c 0,197,198 + 208 303 208 303 216 308 c 0,199,200 + 225 311 225 311 232 307 c 0,201,202 + 240 303 240 303 243 310 c 0,203,204 + 245 312 245 312 244.5 316 c 128,-1,205 + 244 320 244 320 241 321 c 0,206,207 + 239 323 239 323 238 323 c 0,208,209 + 237 335 237 335 232 343 c 1,210,211 + 244 338 244 338 254 338 c 2,212,-1 + 256 338 l 2,213,214 + 269 338 269 338 282 343 c 1,215,216 + 277 336 277 336 277 323 c 1,217,218 + 275 323 275 323 273 321 c 0,219,220 + 270 320 270 320 269.5 316 c 128,-1,221 + 269 312 269 312 271 310 c 0,222,223 + 276 303 276 303 283 307 c 0,224,225 + 290 313 290 313 298 308 c 128,-1,226 + 306 303 306 303 306 295 c 0,227,228 + 306 285 306 285 298 282 c 0,229,230 + 291 277 291 277 283 282 c 0,231,232 + 276 287 276 287 272 279 c 0,233,234 + 267 273 267 273 275 267 c 0,235,236 + 277 267 277 267 279 265 c 0,237,238 + 279 264 279 264 279.5 262 c 128,-1,239 + 280 260 280 260 280 258 c 0,240,241 + 284 207 284 207 301 190 c 0,242,243 + 305 188 305 188 307 188 c 0,244,245 + 311 188 311 188 313 190 c 0,246,247 + 320 197 320 197 313 202 c 0,248,249 + 301 214 301 214 297 260 c 0,250,251 + 297 262 297 262 296 263 c 1,252,253 + 302 264 302 264 307 267 c 0,254,255 + 323 277 323 277 323 295 c 0,256,257 + 323 314 323 314 306 323 c 0,258,259 + 302 325 302 325 294 327 c 1,260,261 + 295 334 295 334 302 340 c 0,262,263 + 306 344 306 344 309 346 c 0,264,265 + 314 345 314 345 326 345 c 0,266,267 + 333 345 333 345 347 347 c 0,268,269 + 367 352 367 352 378 364 c 1,270,271 + 394 356 394 356 410 363 c 0,272,273 + 432 373 432 373 432 398 c 0,274,275 + 432 422 432 422 412 432 c 0,131,132 +402 379 m 0,276,277 + 392 373 392 373 382 382 c 0,278,279 + 380 384 380 384 375 384 c 0,280,281 + 370 382 370 382 369 380 c 0,282,283 + 362 368 362 368 343 364 c 0,284,285 + 315 357 315 357 298 368 c 1,286,-1 + 297 368 l 1,287,-1 + 296 369 l 1,288,-1 + 294 369 l 1,289,-1 + 292 369 l 1,290,-1 + 291 369 l 1,291,-1 + 289 368 l 1,292,-1 + 288 367 l 1,293,-1 + 287 367 l 1,294,295 + 273 353 273 353 255 355 c 0,296,297 + 237 355 237 355 227 367 c 1,298,-1 + 225 368 l 1,299,-1 + 224 369 l 1,300,-1 + 222 369 l 1,301,-1 + 221 369 l 1,302,-1 + 219 369 l 1,303,-1 + 217 368 l 1,304,-1 + 216 368 l 1,305,306 + 196 355 196 355 165 366 c 0,307,308 + 149 370 149 370 144 384 c 0,309,310 + 142 387 142 387 139 389 c 0,311,312 + 135 390 135 390 131 388 c 0,313,314 + 120 381 120 381 111 387 c 0,315,316 + 100 392 100 392 100 406 c 0,317,318 + 100 419 100 419 111 425 c 0,319,320 + 121 430 121 430 130 424 c 0,321,322 + 137 421 137 421 139 412 c 0,323,324 + 140 406 140 406 148 406 c 2,325,-1 + 150 406 l 2,326,327 + 158 408 158 408 156 416 c 0,328,329 + 153 427 153 427 145 435 c 1,330,331 + 148 443 148 443 160 449 c 0,332,333 + 185 462 185 462 210 449 c 0,334,335 + 217 446 217 446 222 453 c 0,336,337 + 225 460 225 460 218 465 c 0,338,339 + 208 469 208 469 202 470 c 1,340,341 + 222 495 222 495 257 495 c 128,-1,342 + 292 495 292 495 312 470 c 1,343,344 + 304 468 304 468 297 464 c 0,345,346 + 289 461 289 461 293 453 c 128,-1,347 + 297 445 297 445 304 449 c 0,348,349 + 316 455 316 455 327 455 c 2,350,-1 + 328 455 l 2,351,352 + 348 455 348 455 360 446 c 0,353,354 + 371 437 371 437 371 429 c 1,355,356 + 366 424 366 424 361 416 c 0,357,358 + 357 409 357 409 365 405 c 0,359,360 + 366 404 366 404 369 404 c 0,361,362 + 374 404 374 404 377 408 c 0,363,364 + 378 413 378 413 384 417 c 0,365,366 + 394 424 394 424 404 417 c 0,367,368 + 415 412 415 412 415 398 c 0,369,370 + 415 383 415 383 402 379 c 0,276,277 +256 179 m 0,371,372 + 265 179 265 179 265 188 c 2,373,-1 + 265 247 l 2,374,375 + 265 256 265 256 256 256 c 0,376,377 + 248 256 248 256 248 247 c 2,378,-1 + 248 188 l 2,379,380 + 248 179 248 179 256 179 c 0,371,372 +EndSplineSet +Validated: 41 +EndChar + +StartChar: arrow-streamline-target +Encoding: 45 45 13 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +459 437 m 1,0,-1 + 459 491 l 2,1,2 + 456 490 456 490 450 488 c 128,-1,3 + 444 486 444 486 429 479 c 128,-1,4 + 414 472 414 472 401 464.5 c 128,-1,5 + 388 457 388 457 374.5 445.5 c 128,-1,6 + 361 434 361 434 354.5 421.5 c 128,-1,7 + 348 409 348 409 350 393 c 128,-1,8 + 352 377 352 377 366 360 c 1,9,-1 + 341 335 l 1,10,11 + 285 384 285 384 213 384 c 0,12,13 + 134 384 134 384 77.5 328 c 128,-1,14 + 21 272 21 272 21 192 c 0,15,16 + 21 120 21 120 70 64 c 1,17,-1 + 24 18 l 2,18,19 + 16 10 16 10 24 3 c 0,20,21 + 28 0 28 0 32 0 c 128,-1,22 + 36 0 36 0 40 3 c 2,23,-1 + 85 49 l 1,24,25 + 141 0 141 0 213 0 c 128,-1,26 + 285 0 285 0 341 49 c 1,27,-1 + 342 49 l 1,28,-1 + 387 3 l 2,29,30 + 390 0 390 0 395 0 c 0,31,32 + 399 0 399 0 402 3 c 0,33,34 + 410 10 410 10 402 18 c 2,35,-1 + 357 64 l 1,36,-1 + 356 64 l 1,37,38 + 405 118 405 118 405 192 c 128,-1,39 + 405 266 405 266 356 320 c 1,40,-1 + 381 345 l 1,41,42 + 401 328 401 328 421 328 c 0,43,44 + 446 328 446 328 469 355 c 128,-1,45 + 492 382 492 382 502 410 c 2,46,-1 + 512 437 l 1,47,-1 + 459 437 l 1,0,-1 +437 437 m 1,48,-1 + 437 431 l 1,49,-1 + 416 410 l 1,50,-1 + 416 449 l 2,51,52 + 419 451 419 451 426 454.5 c 128,-1,53 + 433 458 433 458 437 460 c 1,54,-1 + 437 437 l 1,48,-1 +371 405 m 1,55,56 + 375 418 375 418 395 435 c 1,57,-1 + 395 388 l 1,58,-1 + 381 375 l 1,59,60 + 371 387 371 387 371 405 c 1,55,56 +384 192 m 0,61,62 + 384 122 384 122 334 71.5 c 128,-1,63 + 284 21 284 21 213 21 c 0,64,65 + 143 21 143 21 93 71 c 128,-1,66 + 43 121 43 121 43 192 c 128,-1,67 + 43 263 43 263 93 313 c 128,-1,68 + 143 363 143 363 213 363 c 0,69,70 + 276 363 276 363 326 320 c 1,71,-1 + 296 290 l 1,72,73 + 261 320 261 320 213 320 c 0,74,75 + 160 320 160 320 122.5 282.5 c 128,-1,76 + 85 245 85 245 85 192 c 128,-1,77 + 85 139 85 139 122.5 101.5 c 128,-1,78 + 160 64 160 64 213 64 c 128,-1,79 + 266 64 266 64 303.5 101.5 c 128,-1,80 + 341 139 341 139 341 192 c 0,81,82 + 341 239 341 239 311 275 c 1,83,-1 + 341 305 l 1,84,85 + 384 257 384 257 384 192 c 0,61,62 +256 192 m 0,86,87 + 256 174 256 174 243.5 161.5 c 128,-1,88 + 231 149 231 149 213 149 c 0,89,90 + 196 149 196 149 183.5 161.5 c 128,-1,91 + 171 174 171 174 171 192 c 128,-1,92 + 171 210 171 210 183.5 222.5 c 128,-1,93 + 196 235 196 235 213 235 c 0,94,95 + 223 235 223 235 235 229 c 1,96,-1 + 219 213 l 1,97,-1 + 213 213 l 2,98,99 + 205 213 205 213 198.5 207 c 128,-1,100 + 192 201 192 201 192 192 c 128,-1,101 + 192 183 192 183 198.5 177 c 128,-1,102 + 205 171 205 171 213 171 c 0,103,104 + 222 171 222 171 228.5 177 c 128,-1,105 + 235 183 235 183 235 192 c 0,106,107 + 235 193 235 193 234 195 c 2,108,-1 + 234 197 l 1,109,-1 + 250 214 l 1,110,111 + 256 204 256 204 256 192 c 0,86,87 +250 244 m 1,112,113 + 235 256 235 256 213 256 c 0,114,115 + 187 256 187 256 168 237 c 128,-1,116 + 149 218 149 218 149 192 c 128,-1,117 + 149 166 149 166 168 147 c 128,-1,118 + 187 128 187 128 213 128 c 0,119,120 + 240 128 240 128 258.5 147 c 128,-1,121 + 277 166 277 166 277 192 c 0,122,123 + 277 214 277 214 265 229 c 1,124,-1 + 296 259 l 1,125,126 + 320 230 320 230 320 192 c 0,127,128 + 320 148 320 148 288.5 116.5 c 128,-1,129 + 257 85 257 85 213 85 c 128,-1,130 + 169 85 169 85 138 116.5 c 128,-1,131 + 107 148 107 148 107 192 c 128,-1,132 + 107 236 107 236 138 267.5 c 128,-1,133 + 169 299 169 299 213 299 c 0,134,135 + 251 299 251 299 281 275 c 1,136,-1 + 250 244 l 1,112,113 +421 349 m 0,137,138 + 410 349 410 349 396 360 c 1,139,-1 + 452 416 l 1,140,-1 + 481 416 l 1,141,142 + 451 349 451 349 421 349 c 0,137,138 +EndSplineSet +Validated: 553 +EndChar + +StartChar: buffer +Encoding: 46 46 14 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +71 348 m 2,0,1 + 64 351 64 351 64 355.5 c 128,-1,2 + 64 360 64 360 71 363 c 2,3,-1 + 240 445 l 2,4,5 + 246 448 246 448 256 448 c 128,-1,6 + 266 448 266 448 272 445 c 2,7,-1 + 441 363 l 2,8,9 + 448 360 448 360 448 355.5 c 128,-1,10 + 448 351 448 351 441 348 c 2,11,-1 + 272 266 l 2,12,13 + 266 263 266 263 256 263 c 128,-1,14 + 246 263 246 263 240 266 c 2,15,-1 + 71 348 l 2,0,1 +441 264 m 2,16,17 + 448 261 448 261 448 256 c 128,-1,18 + 448 251 448 251 441 248 c 2,19,-1 + 272 167 l 2,20,21 + 264 163 264 163 256 163 c 128,-1,22 + 248 163 248 163 240 167 c 2,23,-1 + 71 248 l 2,24,25 + 64 251 64 251 64 256 c 128,-1,26 + 64 261 64 261 71 264 c 0,27,28 + 98 277 98 277 104 280 c 0,29,30 + 110 284 110 284 117 280 c 2,31,-1 + 240 220 l 2,32,33 + 246 217 246 217 256 217 c 128,-1,34 + 266 217 266 217 272 220 c 0,35,36 + 393 279 393 279 397 281 c 0,37,38 + 402 283 402 283 406 281 c 2,39,-1 + 441 264 l 2,16,17 +441 164 m 2,40,41 + 448 161 448 161 448 156.5 c 128,-1,42 + 448 152 448 152 441 149 c 2,43,-1 + 272 67 l 2,44,45 + 266 64 266 64 256 64 c 128,-1,46 + 246 64 246 64 240 67 c 2,47,-1 + 71 149 l 2,48,49 + 64 152 64 152 64 156.5 c 128,-1,50 + 64 161 64 161 71 164 c 0,51,52 + 98 178 98 178 104 181 c 0,53,54 + 109 184 109 184 117 180 c 2,55,-1 + 240 121 l 2,56,57 + 246 118 246 118 256 118 c 128,-1,58 + 266 118 266 118 272 121 c 0,59,60 + 393 179 393 179 397 181 c 0,61,62 + 402 183 402 183 406 181 c 2,63,-1 + 441 164 l 2,40,41 +EndSplineSet +Validated: 1 +EndChar + +StartChar: upload-cloud +Encoding: 47 47 15 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +389 330 m 0,0,1 + 439 330 439 330 476 295 c 0,2,3 + 512 260 512 260 512 210 c 128,-1,4 + 512 160 512 160 476 125 c 0,5,6 + 439 90 439 90 389 90 c 2,7,-1 + 292 90 l 1,8,-1 + 292 187 l 1,9,-1 + 346 187 l 1,10,-1 + 256 305 l 1,11,-1 + 167 187 l 1,12,-1 + 220 187 l 1,13,-1 + 220 90 l 1,14,-1 + 93 90 l 2,15,16 + 55 90 55 90 28 117 c 0,17,18 + 0 142 0 142 0 180 c 128,-1,19 + 0 218 0 218 27 245 c 0,20,21 + 55 271 55 271 93 271 c 0,22,23 + 101 271 101 271 103 270 c 1,24,25 + 103 271 103 271 102.5 278 c 128,-1,26 + 102 285 102 285 102 290 c 0,27,28 + 102 344 102 344 142 384 c 0,29,30 + 182 423 182 423 239 423 c 0,31,32 + 285 423 285 423 321 396 c 0,33,34 + 355 371 355 371 369 328 c 1,35,36 + 387 330 387 330 389 330 c 0,0,1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-42 +Encoding: 48 48 16 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +201 101 m 1,0,-1 + 201 95 l 2,1,2 + 202 92 202 92 202 87 c 0,3,4 + 201 85 201 85 201 81 c 0,5,6 + 200 76 200 76 198 75 c 0,7,8 + 194 73 194 73 192 73 c 2,9,-1 + 101 73 l 2,10,11 + 68 73 68 73 42 97 c 0,12,13 + 18 121 18 121 18 155 c 2,14,-1 + 18 357 l 2,15,16 + 18 391 18 391 42 415 c 0,17,18 + 67 439 67 439 101 439 c 2,19,-1 + 192 439 l 2,20,21 + 196 439 196 439 198 436 c 0,22,23 + 201 433 201 433 201 430 c 2,24,-1 + 201 424 l 2,25,26 + 202 421 202 421 202 416 c 0,27,28 + 201 414 201 414 201 410 c 0,29,30 + 200 406 200 406 198 404 c 0,31,32 + 194 402 194 402 192 402 c 2,33,-1 + 101 402 l 2,34,35 + 81 402 81 402 68 389 c 128,-1,36 + 55 376 55 376 55 357 c 2,37,-1 + 55 155 l 2,38,39 + 55 136 55 136 68 123 c 128,-1,40 + 81 110 81 110 101 110 c 2,41,-1 + 190 110 l 2,42,43 + 191 110 191 110 193 109 c 2,44,-1 + 196 109 l 2,45,46 + 196 108 196 108 199 107 c 0,47,48 + 201 105 201 105 201 104 c 2,49,-1 + 201 101 l 1,0,-1 +466 256 m 128,-1,51 + 466 250 466 250 461 243 c 2,52,-1 + 305 88 l 2,53,54 + 300 82 300 82 293 82 c 0,55,56 + 284 82 284 82 280 88 c 0,57,58 + 274 92 274 92 274 101 c 2,59,-1 + 274 183 l 1,60,-1 + 146 183 l 2,61,62 + 140 183 140 183 133 188 c 0,63,64 + 128 195 128 195 128 201 c 2,65,-1 + 128 311 l 2,66,67 + 128 317 128 317 133 324 c 0,68,69 + 140 329 140 329 146 329 c 2,70,-1 + 274 329 l 1,71,-1 + 274 411 l 2,72,73 + 274 419 274 419 280 424 c 0,74,75 + 284 430 284 430 293 430 c 0,76,77 + 300 430 300 430 305 424 c 2,78,-1 + 461 269 l 2,79,50 + 466 262 466 262 466 256 c 128,-1,51 +EndSplineSet +Validated: 513 +EndChar + +StartChar: television-tv +Encoding: 49 49 17 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +480 384 m 2,0,-1 + 303 384 l 1,1,-1 + 373 454 l 2,2,3 + 384 465 384 465 373 476 c 0,4,5 + 361 488 361 488 350 476 c 2,6,-1 + 258 384 l 1,7,-1 + 239 384 l 1,8,-1 + 146 476 l 2,9,10 + 135 489 135 489 124 476 c 0,11,12 + 113 465 113 465 124 454 c 2,13,-1 + 194 384 l 1,14,-1 + 32 384 l 2,15,16 + 18 384 18 384 9 375 c 128,-1,17 + 0 366 0 366 0 352 c 2,18,-1 + 0 64 l 2,19,20 + 0 50 0 50 9 41 c 128,-1,21 + 18 32 18 32 32 32 c 2,22,-1 + 480 32 l 2,23,24 + 494 32 494 32 503 41 c 128,-1,25 + 512 50 512 50 512 64 c 2,26,-1 + 512 352 l 2,27,28 + 512 366 512 366 503 375 c 128,-1,29 + 494 384 494 384 480 384 c 2,0,-1 +352 96 m 1,30,-1 + 64 96 l 1,31,-1 + 64 320 l 1,32,-1 + 352 320 l 1,33,-1 + 352 96 l 1,30,-1 +448 192 m 1,34,-1 + 416 192 l 1,35,-1 + 416 224 l 1,36,-1 + 448 224 l 1,37,-1 + 448 192 l 1,34,-1 +448 256 m 1,38,-1 + 416 256 l 1,39,-1 + 416 288 l 1,40,-1 + 448 288 l 1,41,-1 + 448 256 l 1,38,-1 +EndSplineSet +Validated: 553 +EndChar + +StartChar: hand-stop +Encoding: 50 50 18 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +32 384 m 2,0,-1 + 32 128 l 2,1,2 + 32 104 32 104 32.5 91 c 128,-1,3 + 33 78 33 78 38 57.5 c 128,-1,4 + 43 37 43 37 52.5 27 c 128,-1,5 + 62 17 62 17 81 8.5 c 128,-1,6 + 100 0 100 0 128 0 c 2,7,-1 + 256 0 l 2,8,9 + 306 0 306 0 326.5 22.5 c 128,-1,10 + 347 45 347 45 350 83 c 1,11,-1 + 473 236 l 2,12,13 + 490 258 490 258 471 279 c 1,14,15 + 440 302 440 302 415 302 c 0,16,17 + 385 302 385 302 361 279 c 2,18,-1 + 320 237 l 1,19,-1 + 320 448 l 2,20,21 + 320 462 320 462 311 471 c 128,-1,22 + 302 480 302 480 288 480 c 2,23,-1 + 256 480 l 1,24,25 + 256 494 256 494 247 503 c 128,-1,26 + 238 512 238 512 224 512 c 2,27,-1 + 192 512 l 2,28,29 + 178 512 178 512 169 503 c 128,-1,30 + 160 494 160 494 160 480 c 1,31,-1 + 128 480 l 2,32,33 + 114 480 114 480 105 471 c 128,-1,34 + 96 462 96 462 96 448 c 2,35,-1 + 96 416 l 1,36,-1 + 64 416 l 2,37,38 + 50 416 50 416 41 407 c 128,-1,39 + 32 398 32 398 32 384 c 2,0,-1 +64 384 m 1,40,-1 + 96 384 l 1,41,-1 + 96 256 l 1,42,-1 + 128 256 l 1,43,-1 + 128 448 l 1,44,-1 + 160 448 l 1,45,-1 + 160 256 l 1,46,-1 + 192 256 l 1,47,-1 + 192 480 l 1,48,-1 + 224 480 l 1,49,-1 + 224 256 l 1,50,-1 + 256 256 l 1,51,-1 + 256 448 l 1,52,-1 + 288 448 l 1,53,-1 + 288 192 l 1,54,-1 + 320 192 l 1,55,-1 + 384 256 l 2,56,57 + 398 270 398 270 415 270 c 0,58,59 + 423 270 423 270 431.5 266.5 c 128,-1,60 + 440 263 440 263 444 260 c 2,61,-1 + 448 256 l 1,62,-1 + 320 97 l 1,63,-1 + 320 96 l 1,64,-1 + 319 96 l 1,65,66 + 318 62 318 62 305.5 47 c 128,-1,67 + 293 32 293 32 256 32 c 2,68,-1 + 128 32 l 2,69,70 + 84 32 84 32 74 52 c 128,-1,71 + 64 72 64 72 64 128 c 2,72,-1 + 64 384 l 1,40,-1 +EndSplineSet +Validated: 553 +EndChar + +StartChar: ionicons +Encoding: 51 51 19 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +120 176 m 128,-1,1 + 143 176 143 176 159.5 159.5 c 128,-1,2 + 176 143 176 143 176 120 c 128,-1,3 + 176 97 176 97 159.5 80.5 c 128,-1,4 + 143 64 143 64 120 64 c 128,-1,5 + 97 64 97 64 80.5 80.5 c 128,-1,6 + 64 97 64 97 64 120 c 128,-1,7 + 64 143 64 143 80.5 159.5 c 128,-1,0 + 97 176 97 176 120 176 c 128,-1,1 +64 320 m 1,8,9 + 169 320 169 320 244.5 244.5 c 128,-1,10 + 320 169 320 169 320 64 c 1,11,-1 + 240 64 l 1,12,13 + 240 144 240 144 192 192 c 128,-1,14 + 144 240 144 240 64 240 c 1,15,-1 + 64 320 l 1,8,9 +64 448 m 1,16,17 + 223 448 223 448 335.5 335.5 c 128,-1,18 + 448 223 448 223 448 64 c 1,19,-1 + 368 64 l 1,20,21 + 368 192 368 192 280 280 c 128,-1,22 + 192 368 192 368 64 368 c 1,23,-1 + 64 448 l 1,16,17 +EndSplineSet +Validated: 1 +EndChar + +StartChar: delicious +Encoding: 52 52 20 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +457 119 m 2,0,-1 + 457 256 l 1,1,-1 + 256 256 l 1,2,-1 + 256 457 l 1,3,-1 + 119 457 l 2,4,5 + 92 457 92 457 74 438 c 0,6,7 + 55 420 55 420 55 393 c 2,8,-1 + 55 256 l 1,9,-1 + 256 256 l 1,10,-1 + 256 55 l 1,11,-1 + 393 55 l 2,12,13 + 420 55 420 55 438 74 c 0,14,15 + 457 92 457 92 457 119 c 2,0,-1 +475 393 m 2,16,-1 + 475 119 l 2,17,18 + 475 85 475 85 451 61 c 128,-1,19 + 427 37 427 37 393 37 c 2,20,-1 + 119 37 l 2,21,22 + 85 37 85 37 61 61 c 128,-1,23 + 37 85 37 85 37 119 c 2,24,-1 + 37 393 l 2,25,26 + 37 427 37 427 61 451 c 128,-1,27 + 85 475 85 475 119 475 c 2,28,-1 + 393 475 l 2,29,30 + 427 475 427 475 451 451 c 128,-1,31 + 475 427 475 427 475 393 c 2,16,-1 +EndSplineSet +Validated: 5 +EndChar + +StartChar: shield +Encoding: 53 53 21 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +256 458 m 1,0,-1 + 256 459 l 1,1,-1 + 84 359 l 1,2,-1 + 84 241 l 2,3,4 + 85 168 85 168 135 114.5 c 128,-1,5 + 185 61 185 61 256 53 c 1,6,7 + 328 60 328 60 377 114 c 128,-1,8 + 426 168 426 168 428 241 c 2,9,-1 + 428 359 l 1,10,-1 + 256 458 l 1,0,-1 +256 105 m 1,11,-1 + 256 247 l 1,12,-1 + 135 247 l 1,13,-1 + 135 329 l 1,14,-1 + 256 399 l 1,15,-1 + 256 247 l 1,16,-1 + 377 247 l 1,17,-1 + 377 241 l 2,18,19 + 376 189 376 189 341 150.5 c 128,-1,20 + 306 112 306 112 256 105 c 1,11,-1 +EndSplineSet +Validated: 5 +EndChar + +StartChar: ink-pen +Encoding: 54 54 22 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +121 264 m 1,0,-1 + 36 196 l 1,1,-1 + 71 189 l 1,2,-1 + 146 252 l 1,3,4 + 210 253 210 253 268.5 267.5 c 128,-1,5 + 327 282 327 282 353 296 c 2,6,-1 + 379 310 l 1,7,-1 + 328 354 l 1,8,9 + 418 361 418 361 441 350 c 1,10,11 + 498 380 498 380 512 506 c 1,12,13 + 473 512 473 512 439 512.5 c 128,-1,14 + 405 513 405 513 376 508 c 128,-1,15 + 347 503 347 503 323.5 496.5 c 128,-1,16 + 300 490 300 490 278.5 475.5 c 128,-1,17 + 257 461 257 461 241.5 450 c 128,-1,18 + 226 439 226 439 209.5 418 c 128,-1,19 + 193 397 193 397 183 383.5 c 128,-1,20 + 173 370 173 370 160 344.5 c 128,-1,21 + 147 319 147 319 140.5 305 c 128,-1,22 + 134 291 134 291 121 264 c 1,0,-1 +159 279 m 1,23,-1 + 157 280 l 1,24,25 + 175 299 175 299 198.5 320 c 128,-1,26 + 222 341 222 341 267.5 378.5 c 128,-1,27 + 313 416 313 416 369 445 c 128,-1,28 + 425 474 425 474 477 485 c 1,29,30 + 396 457 396 457 159 279 c 1,23,-1 +190 131 m 2,31,-1 + 158 131 l 1,32,33 + 158 144 158 144 148.5 153.5 c 128,-1,34 + 139 163 139 163 126 163 c 2,35,-1 + 94 163 l 2,36,37 + 80 163 80 163 71 153.5 c 128,-1,38 + 62 144 62 144 62 131 c 1,39,-1 + 30 131 l 2,40,41 + 16 131 16 131 7 121.5 c 128,-1,42 + -2 112 -2 112 -2 99 c 2,43,-1 + -2 35 l 2,44,45 + -2 22 -2 22 7.5 12.5 c 128,-1,46 + 17 3 17 3 30 3 c 2,47,-1 + 190 3 l 2,48,49 + 203 3 203 3 212.5 12.5 c 128,-1,50 + 222 22 222 22 222 35 c 2,51,-1 + 222 99 l 2,52,53 + 222 112 222 112 212.5 121.5 c 128,-1,54 + 203 131 203 131 190 131 c 2,31,-1 +EndSplineSet +Validated: 553 +EndChar + +StartChar: ionicons-1 +Encoding: 55 55 23 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +160 256 m 128,-1,1 + 160 352 160 352 256 352 c 128,-1,2 + 352 352 352 352 352 256 c 128,-1,3 + 352 160 352 160 256 160 c 128,-1,0 + 160 160 160 160 160 256 c 128,-1,1 +512 272 m 1,4,-1 + 512 240 l 1,5,-1 + 447 240 l 1,6,7 + 441 169 441 169 392 120 c 128,-1,8 + 343 71 343 71 272 65 c 1,9,-1 + 272 0 l 1,10,-1 + 240 0 l 1,11,-1 + 240 65 l 1,12,13 + 169 71 169 71 120 120 c 128,-1,14 + 71 169 71 169 65 240 c 1,15,-1 + 0 240 l 1,16,-1 + 0 272 l 1,17,-1 + 65 272 l 1,18,19 + 67 294 67 294 72 311 c 128,-1,20 + 77 328 77 328 87 346 c 128,-1,21 + 97 364 97 364 108 378 c 0,22,23 + 120 392 120 392 134 404 c 0,24,25 + 148 415 148 415 166 425 c 128,-1,26 + 184 435 184 435 201 440 c 128,-1,27 + 218 445 218 445 240 447 c 1,28,-1 + 240 512 l 1,29,-1 + 272 512 l 1,30,-1 + 272 447 l 1,31,32 + 343 441 343 441 392 392 c 128,-1,33 + 441 343 441 343 447 272 c 1,34,-1 + 512 272 l 1,4,-1 +256 113 m 128,-1,36 + 315 113 315 113 357 155 c 128,-1,37 + 399 197 399 197 399 256 c 128,-1,38 + 399 315 399 315 357 357 c 128,-1,39 + 315 399 315 399 256 399 c 128,-1,40 + 197 399 197 399 155 357 c 128,-1,41 + 113 315 113 315 113 256 c 128,-1,42 + 113 197 113 197 155 155 c 128,-1,35 + 197 113 197 113 256 113 c 128,-1,36 +EndSplineSet +Validated: 513 +EndChar + +StartChar: crown +Encoding: 56 56 24 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +430 102 m 2,0,1 + 430 109 430 109 425.5 113.5 c 128,-1,2 + 421 118 421 118 415 118 c 2,3,-1 + 97 118 l 2,4,5 + 91 118 91 118 86.5 113.5 c 128,-1,6 + 82 109 82 109 82 102 c 2,7,-1 + 82 83 l 2,8,9 + 82 76 82 76 86.5 71.5 c 128,-1,10 + 91 67 91 67 97 67 c 2,11,-1 + 415 67 l 2,12,13 + 421 67 421 67 425.5 71.5 c 128,-1,14 + 430 76 430 76 430 83 c 2,15,-1 + 430 102 l 2,0,1 +126 315 m 2,16,17 + 122 319 122 319 115 319 c 0,18,19 + 100 319 100 319 98 303 c 2,20,-1 + 98 153 l 1,21,-1 + 99 153 l 1,22,23 + 99 147 99 147 103.5 142.5 c 128,-1,24 + 108 138 108 138 115 138 c 1,25,-1 + 115 138 l 1,26,-1 + 397 138 l 1,27,-1 + 397 139 l 1,28,29 + 411 139 411 139 413 153 c 1,30,-1 + 414 153 l 1,31,-1 + 414 155 l 1,32,-1 + 414 300 l 1,33,-1 + 414 303 l 2,34,35 + 414 310 414 310 409 315 c 128,-1,36 + 404 320 404 320 397 320 c 0,37,38 + 391 320 391 320 387 316 c 1,39,-1 + 386 316 l 1,40,-1 + 386 315 l 1,41,-1 + 385 314 l 1,42,-1 + 349 279 l 1,43,-1 + 268 360 l 2,44,45 + 263 365 263 365 256 365 c 128,-1,46 + 249 365 249 365 244 360 c 2,47,-1 + 162 279 l 1,48,-1 + 128 314 l 1,49,-1 + 127 314 l 1,50,-1 + 126 315 l 2,16,17 +374 272 m 1,51,-1 + 373 272 l 1,52,-1 + 374 272 l 1,51,-1 +145 373 m 128,-1,54 + 145 360 145 360 136 351 c 128,-1,55 + 127 342 127 342 114 342 c 128,-1,56 + 101 342 101 342 92 351 c 128,-1,57 + 83 360 83 360 83 373 c 128,-1,58 + 83 386 83 386 92 395 c 128,-1,59 + 101 404 101 404 114 404 c 128,-1,60 + 127 404 127 404 136 395 c 128,-1,53 + 145 386 145 386 145 373 c 128,-1,54 +427 373 m 128,-1,62 + 427 360 427 360 418 351 c 128,-1,63 + 409 342 409 342 396 342 c 128,-1,64 + 383 342 383 342 374 351 c 128,-1,65 + 365 360 365 360 365 373 c 128,-1,66 + 365 386 365 386 374 395 c 128,-1,67 + 383 404 383 404 396 404 c 128,-1,68 + 409 404 409 404 418 395 c 128,-1,61 + 427 386 427 386 427 373 c 128,-1,62 +289 414 m 128,-1,70 + 289 401 289 401 280 392 c 128,-1,71 + 271 383 271 383 258 383 c 128,-1,72 + 245 383 245 383 236 392 c 128,-1,73 + 227 401 227 401 227 414 c 128,-1,74 + 227 427 227 427 236 436 c 128,-1,75 + 245 445 245 445 258 445 c 128,-1,76 + 271 445 271 445 280 436 c 128,-1,69 + 289 427 289 427 289 414 c 128,-1,70 +EndSplineSet +Validated: 5 +EndChar + +StartChar: chart-line +Encoding: 57 57 25 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +17 222 m 2,0,1 + -5 228 -5 228 1 251 c 0,2,3 + 6 273 6 273 28 267 c 2,4,-1 + 78 255 l 1,5,-1 + 52 214 l 1,6,-1 + 17 222 l 2,0,1 +472 216 m 2,7,8 + 478 222 478 222 488 222 c 0,9,10 + 499 220 499 220 504 214 c 0,11,12 + 521 197 521 197 503 181 c 2,13,-1 + 375 66 l 2,14,15 + 368 60 368 60 359 60 c 0,16,17 + 353 60 353 60 345 65 c 2,18,-1 + 199 177 l 1,19,-1 + 171 185 l 1,20,-1 + 197 225 l 1,21,-1 + 215 221 l 2,22,23 + 222 219 222 219 223 217 c 2,24,-1 + 358 113 l 1,25,-1 + 472 216 l 2,7,8 +221 328 m 1,26,-1 + 43 48 l 2,27,28 + 37 36 37 36 23 36 c 0,29,30 + 18 36 18 36 11 41 c 0,31,32 + 2 46 2 46 1 55 c 0,33,34 + 0 65 0 65 4 72 c 2,35,-1 + 195 372 l 2,36,37 + 199 380 199 380 209 383 c 0,38,39 + 218 386 218 386 228 380 c 2,40,-1 + 353 300 l 1,41,-1 + 468 466 l 2,42,43 + 474 474 474 474 483 476 c 0,44,45 + 492 477 492 477 500 471 c 0,46,47 + 519 459 519 459 506 440 c 2,48,-1 + 378 255 l 2,49,50 + 365 237 365 237 346 249 c 2,51,-1 + 221 328 l 1,26,-1 +EndSplineSet +Validated: 545 +EndChar + +StartChar: graduate-cap +Encoding: 58 58 26 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +256 422 m 1,0,-1 + 22 335 l 1,1,-1 + 256 218 l 1,2,-1 + 367 274 l 1,3,-1 + 263 306 l 2,4,5 + 259 304 259 304 256 304 c 0,6,7 + 240 304 240 304 240 320 c 128,-1,8 + 240 336 240 336 256 336 c 1,9,-1 + 253 327 l 1,10,-1 + 272 322 l 2,11,12 + 283 322 283 322 291.5 313.5 c 128,-1,13 + 300 305 300 305 300 294 c 0,14,15 + 300 282 300 282 291.5 274 c 128,-1,16 + 283 266 283 266 272 266 c 2,17,-1 + 299 257 l 1,18,-1 + 455 265 l 1,19,-1 + 455 253 l 1,20,21 + 448 248 448 248 448 240 c 128,-1,22 + 448 232 448 232 455 227 c 1,23,24 + 448 199 448 199 448 112 c 1,25,26 + 460 104 460 104 464 104 c 128,-1,27 + 468 104 468 104 480 112 c 1,28,29 + 480 199 480 199 473 227 c 1,30,31 + 480 232 480 232 480 240 c 128,-1,32 + 480 248 480 248 473 253 c 1,33,-1 + 473 279 l 1,34,-1 + 414 297 l 1,35,-1 + 490 335 l 1,36,-1 + 256 422 l 1,0,-1 +120 263 m 1,37,-1 + 107 184 l 1,38,39 + 141 180 141 180 193 148 c 0,40,41 + 220 130 220 130 237 115 c 0,42,43 + 245 109 245 109 256 96 c 1,44,45 + 267 109 267 109 275 115 c 0,46,47 + 292 130 292 130 319 148 c 0,48,49 + 371 180 371 180 406 184 c 1,50,-1 + 392 263 l 1,51,-1 + 386 263 l 1,52,-1 + 256 198 l 1,53,-1 + 126 263 l 1,54,-1 + 120 263 l 1,37,-1 +EndSplineSet +Validated: 517 +EndChar + +StartChar: email-plane +Encoding: 59 59 27 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +203 207 m 5,0,-1 + 186 43 l 5,1,-1 + 288 168 l 5,2,-1 + 385 124 l 5,3,-1 + 485 469 l 5,4,-1 + 203 207 l 5,0,-1 +485 469 m 5,5,-1 + -27 259 l 5,6,-1 + 94 235 l 5,7,-1 + 186 43 l 5,8,-1 + 120 235 l 5,9,-1 + 485 469 l 5,5,-1 +EndSplineSet +EndChar + +StartChar: zoom-in +Encoding: 60 60 28 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +498 14 m 128,-1,1 + 484 0 484 0 464 0 c 128,-1,2 + 444 0 444 0 430 14 c 2,3,-1 + 345 99 l 1,4,5 + 288 63 288 63 224 63 c 0,6,7 + 131 63 131 63 65.5 129 c 128,-1,8 + 0 195 0 195 0 288 c 128,-1,9 + 0 381 0 381 65.5 446.5 c 128,-1,10 + 131 512 131 512 224 512 c 128,-1,11 + 317 512 317 512 383 446.5 c 128,-1,12 + 449 381 449 381 449 288 c 0,13,14 + 449 224 449 224 413 167 c 1,15,-1 + 498 82 l 2,16,17 + 512 68 512 68 512 48 c 128,-1,0 + 512 28 512 28 498 14 c 128,-1,1 +224 448 m 0,18,19 + 158 448 158 448 111 401 c 128,-1,20 + 64 354 64 354 64 288 c 0,21,22 + 64 221 64 221 111 174 c 128,-1,23 + 158 127 158 127 224 127 c 0,24,25 + 291 127 291 127 338 174 c 128,-1,26 + 385 221 385 221 385 288 c 0,27,28 + 385 354 385 354 338 401 c 128,-1,29 + 291 448 291 448 224 448 c 0,18,19 +256 191 m 1,30,-1 + 192 191 l 1,31,-1 + 192 256 l 1,32,-1 + 128 256 l 1,33,-1 + 128 320 l 1,34,-1 + 192 320 l 1,35,-1 + 192 384 l 1,36,-1 + 256 384 l 1,37,-1 + 256 320 l 1,38,-1 + 321 320 l 1,39,-1 + 321 256 l 1,40,-1 + 256 256 l 1,41,-1 + 256 191 l 1,30,-1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: screen-full +Encoding: 61 61 29 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +96 128 m 1,0,-1 + 416 128 l 1,1,-1 + 416 384 l 1,2,-1 + 96 384 l 1,3,-1 + 96 128 l 1,0,-1 +160 320 m 1,4,-1 + 352 320 l 1,5,-1 + 352 192 l 1,6,-1 + 160 192 l 1,7,-1 + 160 320 l 1,4,-1 +64 416 m 1,8,-1 + 160 416 l 1,9,-1 + 160 448 l 1,10,-1 + 32 448 l 1,11,-1 + 32 320 l 1,12,-1 + 64 320 l 1,13,-1 + 64 416 l 1,8,-1 +64 192 m 1,14,-1 + 32 192 l 1,15,-1 + 32 64 l 1,16,-1 + 160 64 l 1,17,-1 + 160 96 l 1,18,-1 + 64 96 l 1,19,-1 + 64 192 l 1,14,-1 +352 448 m 1,20,-1 + 352 416 l 1,21,-1 + 448 416 l 1,22,-1 + 448 320 l 1,23,-1 + 480 320 l 1,24,-1 + 480 448 l 1,25,-1 + 352 448 l 1,20,-1 +448 96 m 1,26,-1 + 352 96 l 1,27,-1 + 352 64 l 1,28,-1 + 480 64 l 1,29,-1 + 480 192 l 1,30,-1 + 448 192 l 1,31,-1 + 448 96 l 1,26,-1 +EndSplineSet +Validated: 521 +EndChar + +StartChar: atom +Encoding: 62 62 30 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +256 320 m 128,-1,1 + 230 320 230 320 211 301 c 128,-1,2 + 192 282 192 282 192 256 c 128,-1,3 + 192 230 192 230 211 211 c 128,-1,4 + 230 192 230 192 256 192 c 128,-1,5 + 282 192 282 192 301 211 c 128,-1,6 + 320 230 320 230 320 256 c 128,-1,7 + 320 282 320 282 301 301 c 128,-1,0 + 282 320 282 320 256 320 c 128,-1,1 +453 312 m 1,8,9 + 444 315 444 315 434 323 c 1,10,11 + 428 311 428 311 404 274 c 1,12,13 + 375 311 375 311 343 343 c 0,14,15 + 303 382 303 382 274 404 c 1,16,17 + 361 466 361 466 419 466 c 0,18,19 + 442 466 442 466 454 454 c 0,20,21 + 466 443 466 443 466 416 c 1,22,-1 + 469 416 l 2,23,24 + 478 416 478 416 487 413 c 1,25,26 + 489 449 489 449 469 469 c 0,27,28 + 451 487 451 487 419 487 c 0,29,30 + 353 487 353 487 256 417 c 1,31,32 + 159 487 159 487 93 487 c 0,33,34 + 84 487 84 487 80 486 c 1,35,36 + 88 479 88 479 93 466 c 1,37,38 + 151 466 151 466 238 404 c 1,39,40 + 209 382 209 382 169 343 c 0,41,42 + 130 303 130 303 108 274 c 1,43,44 + 79 316 79 316 64 350 c 0,45,46 + 54 372 54 372 49 395 c 1,47,-1 + 43 395 l 2,48,49 + 37 395 37 395 27 397 c 1,50,51 + 31 373 31 373 45 341 c 0,52,53 + 63 300 63 300 95 256 c 1,54,55 + 63 212 63 212 45 171 c 0,56,57 + 4 80 4 80 43 43 c 0,58,59 + 61 25 61 25 93 25 c 0,60,61 + 141 25 141 25 209 64 c 128,-1,62 + 277 103 277 103 343 169 c 0,63,64 + 382 209 382 209 404 238 c 1,65,66 + 447 177 447 177 460.5 126.5 c 128,-1,67 + 474 76 474 76 454 58 c 0,68,69 + 442 46 442 46 419 46 c 0,70,71 + 391 46 391 46 348 65 c 1,72,73 + 344 54 344 54 336 47 c 1,74,75 + 385 25 385 25 419 25 c 0,76,77 + 451 25 451 25 469 43 c 0,78,79 + 496 72 496 72 481.5 129.5 c 128,-1,80 + 467 187 467 187 417 256 c 1,81,82 + 437 283 437 283 453 312 c 1,8,9 +93 46 m 0,83,84 + 70 46 70 46 58 58 c 0,85,86 + 31 84 31 84 64 162 c 0,87,88 + 79 196 79 196 108 238 c 1,89,90 + 137 201 137 201 169 169 c 128,-1,91 + 201 137 201 137 238 108 c 1,92,93 + 151 46 151 46 93 46 c 0,83,84 +328 184 m 0,94,95 + 299 155 299 155 256 121 c 1,96,97 + 220 150 220 150 184 184 c 0,98,99 + 150 220 150 220 121 256 c 1,100,101 + 150 292 150 292 184 328 c 0,102,103 + 220 362 220 362 256 391 c 1,104,105 + 292 362 292 362 328 328 c 0,106,107 + 364 292 364 292 391 256 c 1,108,109 + 362 220 362 220 328 184 c 0,94,95 +469 384 m 0,110,111 + 461 384 461 384 454.5 377.5 c 128,-1,112 + 448 371 448 371 448 363 c 0,113,114 + 448 354 448 354 454.5 347.5 c 128,-1,115 + 461 341 461 341 469 341 c 0,116,117 + 478 341 478 341 484.5 347.5 c 128,-1,118 + 491 354 491 354 491 363 c 0,119,120 + 491 371 491 371 484.5 377.5 c 128,-1,121 + 478 384 478 384 469 384 c 0,110,111 +299 107 m 0,122,123 + 290 107 290 107 283.5 100.5 c 128,-1,124 + 277 94 277 94 277 85 c 0,125,126 + 277 77 277 77 283.5 70.5 c 128,-1,127 + 290 64 290 64 299 64 c 0,128,129 + 307 64 307 64 313.5 70.5 c 128,-1,130 + 320 77 320 77 320 85 c 0,131,132 + 320 94 320 94 313.5 100.5 c 128,-1,133 + 307 107 307 107 299 107 c 0,122,123 +43 427 m 0,134,135 + 51 427 51 427 57.5 433 c 128,-1,136 + 64 439 64 439 64 448 c 128,-1,137 + 64 457 64 457 57.5 463 c 128,-1,138 + 51 469 51 469 43 469 c 0,139,140 + 34 469 34 469 27.5 463 c 128,-1,141 + 21 457 21 457 21 448 c 128,-1,142 + 21 439 21 439 27.5 433 c 128,-1,143 + 34 427 34 427 43 427 c 0,134,135 +EndSplineSet +Validated: 41 +EndChar + +StartChar: list +Encoding: 63 63 31 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +73 137 m 2,0,-1 + 73 82 l 2,1,2 + 73 79 73 79 70 76 c 0,3,4 + 68 73 68 73 64 73 c 2,5,-1 + 9 73 l 2,6,7 + 6 73 6 73 3 76 c 128,-1,8 + 0 79 0 79 0 82 c 2,9,-1 + 0 137 l 2,10,11 + 0 141 0 141 3 144 c 0,12,13 + 7 146 7 146 9 146 c 2,14,-1 + 64 146 l 2,15,16 + 68 146 68 146 70 144 c 0,17,18 + 73 141 73 141 73 137 c 2,0,-1 +73 247 m 2,19,-1 + 73 192 l 2,20,21 + 73 188 73 188 70 186 c 0,22,23 + 68 183 68 183 64 183 c 2,24,-1 + 9 183 l 2,25,26 + 6 183 6 183 3 186 c 0,27,28 + 0 188 0 188 0 192 c 2,29,-1 + 0 247 l 2,30,31 + 0 250 0 250 3 253 c 128,-1,32 + 6 256 6 256 9 256 c 2,33,-1 + 64 256 l 2,34,35 + 68 256 68 256 70 253 c 0,36,37 + 73 250 73 250 73 247 c 2,19,-1 +73 357 m 2,38,-1 + 73 302 l 2,39,40 + 73 298 73 298 70 295 c 0,41,42 + 69 293 69 293 64 293 c 2,43,-1 + 9 293 l 2,44,45 + 5 293 5 293 3 295 c 0,46,47 + 0 298 0 298 0 302 c 2,48,-1 + 0 357 l 2,49,50 + 0 360 0 360 3 363 c 128,-1,51 + 6 366 6 366 9 366 c 2,52,-1 + 64 366 l 2,53,54 + 68 366 68 366 70 363 c 0,55,56 + 73 360 73 360 73 357 c 2,38,-1 +512 137 m 2,57,-1 + 512 82 l 2,58,59 + 512 79 512 79 509 76 c 128,-1,60 + 506 73 506 73 503 73 c 2,61,-1 + 119 73 l 2,62,63 + 115 73 115 73 112 76 c 0,64,65 + 110 80 110 80 110 82 c 2,66,-1 + 110 137 l 2,67,68 + 110 140 110 140 112 144 c 0,69,70 + 116 146 116 146 119 146 c 2,71,-1 + 503 146 l 2,72,73 + 505 146 505 146 509 144 c 0,74,75 + 512 141 512 141 512 137 c 2,57,-1 +73 466 m 2,76,-1 + 73 411 l 2,77,78 + 73 408 73 408 70 405 c 0,79,80 + 68 402 68 402 64 402 c 2,81,-1 + 9 402 l 2,82,83 + 6 402 6 402 3 405 c 128,-1,84 + 0 408 0 408 0 411 c 2,85,-1 + 0 466 l 2,86,87 + 0 470 0 470 3 473 c 0,88,89 + 5 475 5 475 9 475 c 2,90,-1 + 64 475 l 2,91,92 + 69 475 69 475 70 473 c 0,93,94 + 73 470 73 470 73 466 c 2,76,-1 +512 247 m 2,95,-1 + 512 192 l 2,96,97 + 512 188 512 188 509 186 c 0,98,99 + 506 183 506 183 503 183 c 2,100,-1 + 119 183 l 2,101,102 + 115 183 115 183 112 186 c 0,103,104 + 110 188 110 188 110 192 c 2,105,-1 + 110 247 l 2,106,107 + 110 249 110 249 112 253 c 0,108,109 + 115 256 115 256 119 256 c 2,110,-1 + 503 256 l 2,111,112 + 506 256 506 256 509 253 c 128,-1,113 + 512 250 512 250 512 247 c 2,95,-1 +512 357 m 2,114,-1 + 512 302 l 2,115,116 + 512 298 512 298 509 295 c 0,117,118 + 507 293 507 293 503 293 c 2,119,-1 + 119 293 l 2,120,121 + 114 293 114 293 112 295 c 0,122,123 + 110 299 110 299 110 302 c 2,124,-1 + 110 357 l 2,125,126 + 110 359 110 359 112 363 c 0,127,128 + 115 366 115 366 119 366 c 2,129,-1 + 503 366 l 2,130,131 + 506 366 506 366 509 363 c 128,-1,132 + 512 360 512 360 512 357 c 2,114,-1 +512 466 m 2,133,-1 + 512 411 l 2,134,135 + 512 408 512 408 509 405 c 128,-1,136 + 506 402 506 402 503 402 c 2,137,-1 + 119 402 l 2,138,139 + 115 402 115 402 112 405 c 0,140,141 + 110 409 110 409 110 411 c 2,142,-1 + 110 466 l 2,143,144 + 110 469 110 469 112 473 c 0,145,146 + 114 475 114 475 119 475 c 2,147,-1 + 503 475 l 2,148,149 + 507 475 507 475 509 473 c 0,150,151 + 512 470 512 470 512 466 c 2,133,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: antichess +Encoding: 64 64 32 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +223 464 m 0,0,1 + 130 460 130 460 118 426 c 0,2,3 + 116 420 116 420 116 409 c 0,4,5 + 115 380 115 380 109 358 c 0,6,7 + 102 331 102 331 70 286 c 0,8,9 + 48 254 48 254 48 227 c 0,10,11 + 48 194 48 194 70 172 c 0,12,13 + 89 153 89 153 116 147 c 0,14,15 + 137 145 137 145 151 148 c 0,16,17 + 175 152 175 152 196 169 c 2,18,-1 + 201 172 l 1,19,-1 + 201 164 l 2,20,21 + 201 140 201 140 208 127 c 0,22,23 + 211 121 211 121 218 114 c 0,24,25 + 224 108 224 108 232 102 c 2,26,-1 + 238 98 l 1,27,-1 + 238 89 l 1,28,-1 + 238 81 l 1,29,-1 + 224 73 l 1,30,-1 + 211 64 l 1,31,-1 + 210 52 l 1,32,-1 + 210 39 l 1,33,-1 + 223 39 l 1,34,-1 + 236 39 l 1,35,-1 + 240 27 l 1,36,-1 + 244 14 l 1,37,-1 + 267 14 l 1,38,-1 + 272 27 l 1,39,-1 + 276 39 l 1,40,-1 + 289 39 l 1,41,-1 + 301 39 l 1,42,-1 + 301 52 l 1,43,-1 + 301 64 l 1,44,-1 + 287 73 l 1,45,-1 + 274 81 l 1,46,-1 + 274 89 l 1,47,-1 + 274 98 l 1,48,-1 + 279 102 l 2,49,50 + 298 116 298 116 303 125 c 0,51,52 + 311 139 311 139 311 162 c 0,53,54 + 311 163 311 163 311 166 c 2,55,-1 + 313 172 l 1,56,-1 + 313 171 l 1,57,58 + 320 164 320 164 334 158 c 0,59,60 + 356 146 356 146 379 146 c 0,61,62 + 408 146 408 146 429 161 c 0,63,64 + 443 169 443 169 452 185 c 0,65,66 + 473 217 473 217 460 251 c 0,67,68 + 453 271 453 271 433 299 c 0,69,70 + 420 316 420 316 414 328 c 0,71,72 + 399 358 399 358 396 408 c 0,73,74 + 395 429 395 429 387 437 c 0,75,76 + 375 450 375 450 347 456 c 0,77,78 + 303 468 303 468 223 464 c 0,0,1 +214 408 m 2,79,-1 + 256 404 l 1,80,-1 + 298 408 l 2,81,82 + 342 411 342 411 350 410 c 0,83,84 + 356 408 356 408 357 403.5 c 128,-1,85 + 358 399 358 399 353 395 c 0,86,87 + 336 382 336 382 248 384 c 0,88,89 + 175 386 175 386 159 395 c 0,90,91 + 154 398 154 398 154 402 c 0,92,93 + 155 409 155 409 165 410 c 0,94,95 + 169 411 169 411 214 408 c 2,79,-1 +194 330 m 0,96,97 + 223 328 223 328 247 322 c 2,98,-1 + 255 321 l 1,99,-1 + 268 323 l 2,100,101 + 301 329 301 329 336 331 c 0,102,103 + 358 333 358 333 373 326 c 0,104,105 + 385 320 385 320 409 290 c 0,106,107 + 426 264 426 264 435 243 c 0,108,109 + 437 235 437 235 437 225 c 0,110,111 + 437 208 437 208 431 198 c 0,112,113 + 418 172 418 172 378 170 c 0,114,115 + 376 170 376 170 371 170.5 c 128,-1,116 + 366 171 366 171 365 171 c 0,117,118 + 336 177 336 177 308 205 c 0,119,120 + 294 219 294 219 286 235 c 0,121,122 + 274 259 274 259 274 290 c 0,123,124 + 274 302 274 302 261 305 c 0,125,126 + 248 307 248 307 240 301 c 0,127,128 + 237 296 237 296 237 289 c 0,129,130 + 237 253 237 253 217 221 c 0,131,132 + 193 187 193 187 158 174 c 0,133,134 + 133 165 133 165 108 174 c 0,135,136 + 89 180 89 180 80 197 c 0,137,138 + 75 209 75 209 74 219 c 0,139,140 + 73 234 73 234 77 245 c 0,141,142 + 88 278 88 278 124 315 c 0,143,144 + 137 327 137 327 147 329 c 0,145,146 + 161 333 161 333 194 330 c 0,96,97 +157 312 m 0,147,148 + 148 311 148 311 137 302 c 0,149,150 + 112 284 112 284 96 252 c 0,151,152 + 90 241 90 241 89 228 c 0,153,154 + 89 210 89 210 99 200 c 0,155,156 + 106 193 106 193 120 189 c 0,157,158 + 136 185 136 185 151 189 c 0,159,160 + 174 196 174 196 191 214 c 0,161,162 + 217 243 217 243 220 287 c 0,163,164 + 221 298 221 298 220 301 c 0,165,166 + 215 309 215 309 200 312 c 0,167,168 + 183 314 183 314 157 312 c 0,147,148 +313 312 m 0,169,170 + 296 309 296 309 291 300 c 0,171,172 + 290 297 290 297 290 288 c 0,173,174 + 293 261 293 261 303 239 c 0,175,176 + 310 224 310 224 324 212 c 0,177,178 + 341 195 341 195 360 189 c 0,179,180 + 365 188 365 188 376 188 c 0,181,182 + 392 188 392 188 403 193 c 0,183,184 + 414 200 414 200 417 207 c 0,185,186 + 422 215 422 215 422 229 c 0,187,188 + 422 261 422 261 376 299 c 0,189,190 + 362 311 362 311 352 312 c 0,191,192 + 329 314 329 314 313 312 c 0,169,170 +EndSplineSet +Validated: 41 +EndChar + +StartChar: microscope +Encoding: 65 65 33 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +416 32 m 2,0,-1 + 394 32 l 1,1,2 + 434 58 434 58 457 100.5 c 128,-1,3 + 480 143 480 143 480 192 c 0,4,5 + 480 259 480 259 439 310.5 c 128,-1,6 + 398 362 398 362 335 378 c 1,7,-1 + 371 446 l 2,8,9 + 378 462 378 462 364 469 c 2,10,-1 + 278 510 l 2,11,12 + 273 513 273 513 265 511 c 0,13,14 + 259 508 259 508 256 502 c 2,15,-1 + 154 308 l 2,16,17 + 148 295 148 295 152 282 c 128,-1,18 + 156 269 156 269 168 264 c 1,19,-1 + 154 235 l 1,20,-1 + 211 207 l 1,21,-1 + 225 236 l 1,22,23 + 237 230 237 230 250 235 c 128,-1,24 + 263 240 263 240 269 253 c 2,25,-1 + 304 318 l 1,26,27 + 351 313 351 313 383.5 277 c 128,-1,28 + 416 241 416 241 416 192 c 0,29,30 + 416 139 416 139 378.5 101.5 c 128,-1,31 + 341 64 341 64 288 64 c 0,32,33 + 227 64 227 64 192 96 c 1,34,-1 + 192 112 l 2,35,36 + 192 128 192 128 208 128 c 2,37,-1 + 288 128 l 1,38,-1 + 288 160 l 1,39,-1 + 32 160 l 1,40,-1 + 32 128 l 1,41,-1 + 112 128 l 2,42,43 + 128 128 128 128 128 112 c 2,44,-1 + 128 32 l 1,45,46 + 83 32 83 32 73 24 c 0,47,48 + 64 17 64 17 64 0 c 1,49,-1 + 480 0 l 1,50,51 + 480 15 480 15 471.5 22.5 c 128,-1,52 + 463 30 463 30 453.5 31 c 128,-1,53 + 444 32 444 32 424 32 c 0,54,55 + 419 32 419 32 416 32 c 2,0,-1 +304 469 m 1,56,57 + 296 465 296 465 294 459 c 2,58,-1 + 220 320 l 1,59,-1 + 192 334 l 2,60,61 + 192 335 192 335 193 337 c 128,-1,62 + 194 339 194 339 194 340 c 2,63,-1 + 264 470 l 2,64,65 + 267 476 267 476 273 479 c 0,66,67 + 281 481 281 481 286 478 c 2,68,-1 + 304 469 l 1,56,57 +EndSplineSet +Validated: 41 +EndChar + +StartChar: loop-alt2 +Encoding: 66 66 34 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +319 160 m 1,0,-1 + 415 288 l 1,1,-1 + 512 160 l 1,2,-1 + 448 160 l 1,3,-1 + 448 128 l 2,4,5 + 448 88 448 88 420 60 c 128,-1,6 + 392 32 392 32 352 32 c 2,7,-1 + 160 32 l 2,8,9 + 120 32 120 32 92 60 c 128,-1,10 + 64 88 64 88 64 128 c 2,11,-1 + 64 160 l 1,12,-1 + 128 160 l 1,13,-1 + 128 128 l 2,14,15 + 128 114 128 114 137 105 c 128,-1,16 + 146 96 146 96 160 96 c 2,17,-1 + 352 96 l 2,18,19 + 366 96 366 96 375 105 c 128,-1,20 + 384 114 384 114 384 128 c 2,21,-1 + 384 160 l 1,22,-1 + 319 160 l 1,0,-1 +193 352 m 1,23,-1 + 97 224 l 1,24,-1 + 0 352 l 1,25,-1 + 64 352 l 1,26,-1 + 64 384 l 2,27,28 + 64 424 64 424 92 452 c 128,-1,29 + 120 480 120 480 160 480 c 2,30,-1 + 352 480 l 2,31,32 + 392 480 392 480 420 452 c 128,-1,33 + 448 424 448 424 448 384 c 2,34,-1 + 448 352 l 1,35,-1 + 384 352 l 1,36,-1 + 384 384 l 2,37,38 + 384 398 384 398 375 407 c 128,-1,39 + 366 416 366 416 352 416 c 2,40,-1 + 160 416 l 2,41,42 + 146 416 146 416 137 407 c 128,-1,43 + 128 398 128 398 128 384 c 2,44,-1 + 128 352 l 1,45,-1 + 193 352 l 1,23,-1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: crown-king-1 +Encoding: 67 67 35 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +410 64 m 2,0,-1 + 70 64 l 2,1,2 + 64 64 64 64 64 58 c 2,3,-1 + 64 6 l 2,4,5 + 64 0 64 0 70 0 c 2,6,-1 + 410 0 l 2,7,8 + 416 0 416 0 416 6 c 2,9,-1 + 416 58 l 2,10,11 + 416 64 416 64 410 64 c 2,0,-1 +480 400 m 0,12,13 + 480 420 480 420 466 434 c 128,-1,14 + 452 448 452 448 432 448 c 128,-1,15 + 412 448 412 448 398 434 c 128,-1,16 + 384 420 384 420 384 400 c 0,17,18 + 384 376 384 376 404 361 c 1,19,-1 + 320 192 l 1,20,-1 + 264 359 l 1,21,22 + 288 373 288 373 288 400 c 0,23,24 + 288 420 288 420 274 434 c 128,-1,25 + 260 448 260 448 240 448 c 128,-1,26 + 220 448 220 448 206 434 c 128,-1,27 + 192 420 192 420 192 400 c 0,28,29 + 192 373 192 373 216 359 c 1,30,-1 + 160 192 l 1,31,-1 + 76 361 l 1,32,33 + 96 376 96 376 96 400 c 0,34,35 + 96 420 96 420 82 434 c 128,-1,36 + 68 448 68 448 48 448 c 128,-1,37 + 28 448 28 448 14 434 c 128,-1,38 + 0 420 0 420 0 400 c 0,39,40 + 0 384 0 384 10 371 c 128,-1,41 + 20 358 20 358 35 354 c 1,42,-1 + 64 96 l 1,43,-1 + 416 96 l 1,44,-1 + 445 354 l 1,45,46 + 460 358 460 358 470 371 c 128,-1,47 + 480 384 480 384 480 400 c 0,12,13 +EndSplineSet +Validated: 521 +EndChar + +StartChar: fontawesome-webfont-24 +Encoding: 68 68 36 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +456 428 m 0,0,1 + 461 415 461 415 452 408 c 2,2,-1 + 311 267 l 1,3,-1 + 311 55 l 2,4,5 + 311 43 311 43 300 38 c 0,6,7 + 297 37 297 37 293 37 c 0,8,9 + 284 37 284 37 280 42 c 2,10,-1 + 207 115 l 2,11,12 + 201 121 201 121 201 128 c 2,13,-1 + 201 267 l 1,14,-1 + 60 408 l 2,15,16 + 51 415 51 415 56 428 c 0,17,18 + 62 439 62 439 73 439 c 2,19,-1 + 439 439 l 2,20,21 + 450 439 450 439 456 428 c 0,0,1 +EndSplineSet +Validated: 545 +EndChar + +StartChar: fontawesome-webfont-25 +Encoding: 69 69 37 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +477 350 m 128,-1,1 + 477 338 477 338 469 331 c 2,2,-1 + 263 124 l 1,3,-1 + 224 85 l 2,4,5 + 214 77 214 77 204 77 c 0,6,7 + 193 77 193 77 185 85 c 2,8,-1 + 43 227 l 2,9,10 + 35 235 35 235 35 247 c 128,-1,11 + 35 259 35 259 43 266 c 2,12,-1 + 81 305 l 2,13,14 + 91 313 91 313 101 313 c 0,15,16 + 112 313 112 313 120 305 c 2,17,-1 + 204 221 l 1,18,-1 + 392 409 l 2,19,20 + 400 417 400 417 411 417 c 0,21,22 + 421 417 421 417 431 409 c 2,23,-1 + 469 370 l 2,24,0 + 477 362 477 362 477 350 c 128,-1,1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-26 +Encoding: 70 70 38 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +375 256 m 128,-1,1 + 375 249 375 249 369 243 c 2,2,-1 + 214 88 l 2,3,4 + 208 82 208 82 201 82 c 128,-1,5 + 194 82 194 82 188 88 c 0,6,7 + 183 93 183 93 183 101 c 2,8,-1 + 183 183 l 1,9,-1 + 55 183 l 2,10,11 + 49 183 49 183 42 188 c 0,12,13 + 37 193 37 193 37 201 c 2,14,-1 + 37 311 l 2,15,16 + 37 319 37 319 42 324 c 0,17,18 + 49 329 49 329 55 329 c 2,19,-1 + 183 329 l 1,20,-1 + 183 411 l 2,21,22 + 183 419 183 419 188 424 c 0,23,24 + 194 430 194 430 201 430 c 128,-1,25 + 208 430 208 430 214 424 c 2,26,-1 + 369 269 l 2,27,0 + 375 263 375 263 375 256 c 128,-1,1 +475 357 m 2,28,-1 + 475 155 l 2,29,30 + 475 121 475 121 451 97 c 128,-1,31 + 427 73 427 73 393 73 c 2,32,-1 + 302 73 l 2,33,34 + 298 73 298 73 295 76 c 0,35,36 + 293 78 293 78 293 82 c 2,37,-1 + 292 84 l 2,38,39 + 292 86 292 86 292 88 c 2,40,-1 + 292 96 l 2,41,42 + 292 97 292 97 292.5 99 c 128,-1,43 + 293 101 293 101 293 102 c 0,44,45 + 293 106 293 106 296 108 c 0,46,47 + 298 110 298 110 302 110 c 2,48,-1 + 393 110 l 2,49,50 + 412 110 412 110 425 123 c 0,51,52 + 439 137 439 137 439 155 c 2,53,-1 + 439 357 l 2,54,55 + 439 375 439 375 425 389 c 0,56,57 + 412 402 412 402 393 402 c 2,58,-1 + 304 402 l 2,59,60 + 303 402 303 402 301 403 c 2,61,-1 + 297 403 l 2,62,63 + 297 404 297 404 295 405 c 0,64,65 + 293 407 293 407 293 408 c 2,66,-1 + 293 411 l 1,67,-1 + 292 413 l 2,68,69 + 292 415 292 415 292 417 c 2,70,-1 + 292 425 l 2,71,72 + 292 426 292 426 292.5 428 c 128,-1,73 + 293 430 293 430 293 431 c 0,74,75 + 293 436 293 436 296 437 c 0,76,77 + 298 439 298 439 302 439 c 2,78,-1 + 393 439 l 2,79,80 + 427 439 427 439 451 415 c 128,-1,81 + 475 391 475 391 475 357 c 2,28,-1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-27 +Encoding: 71 71 39 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +450 247 m 2,0,-1 + 71 36 l 2,1,2 + 65 33 65 33 60 35 c 0,3,4 + 55 38 55 38 55 46 c 2,5,-1 + 55 466 l 2,6,7 + 55 474 55 474 60 477 c 0,8,9 + 65 479 65 479 71 476 c 2,10,-1 + 450 265 l 2,11,12 + 457 261 457 261 457 256 c 128,-1,13 + 457 251 457 251 450 247 c 2,0,-1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-28 +Encoding: 72 72 40 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +405 274 m 0,0,1 + 405 259 405 259 395 248 c 2,2,-1 + 209 62 l 2,3,4 + 199 52 199 52 183 52 c 128,-1,5 + 167 52 167 52 157 62 c 2,6,-1 + 135 84 l 2,7,8 + 125 94 125 94 125 110 c 0,9,10 + 125 125 125 125 135 135 c 2,11,-1 + 274 274 l 1,12,-1 + 135 413 l 2,13,14 + 125 423 125 423 125 439 c 128,-1,15 + 125 455 125 455 135 465 c 2,16,-1 + 157 486 l 2,17,18 + 168 497 168 497 183 497 c 128,-1,19 + 198 497 198 497 209 486 c 2,20,-1 + 395 300 l 2,21,22 + 405 290 405 290 405 274 c 0,0,1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-29 +Encoding: 73 73 41 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +303 63 m 2,0,-1 + 117 249 l 2,1,2 + 107 259 107 259 107 274 c 0,3,4 + 107 290 107 290 117 300 c 2,5,-1 + 303 486 l 2,6,7 + 314 497 314 497 329 497 c 128,-1,8 + 344 497 344 497 355 486 c 2,9,-1 + 377 465 l 2,10,11 + 387 455 387 455 387 439 c 128,-1,12 + 387 423 387 423 377 413 c 2,13,-1 + 238 274 l 1,14,-1 + 377 136 l 2,15,16 + 387 125 387 125 387 110 c 0,17,18 + 387 94 387 94 377 84 c 2,19,-1 + 355 63 l 2,20,21 + 344 52 344 52 329 52 c 128,-1,22 + 314 52 314 52 303 63 c 2,0,-1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-30 +Encoding: 74 74 42 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +475 256 m 128,-1,1 + 475 194 475 194 446 146 c 0,2,3 + 416 96 416 96 366 66 c 0,4,5 + 318 37 318 37 256 37 c 128,-1,6 + 194 37 194 37 146 66 c 0,7,8 + 96 96 96 96 66 146 c 0,9,10 + 37 194 37 194 37 256 c 128,-1,11 + 37 318 37 318 66 366 c 0,12,13 + 96 416 96 416 146 446 c 0,14,15 + 194 475 194 475 256 475 c 128,-1,16 + 318 475 318 475 366 446 c 0,17,18 + 416 416 416 416 446 366 c 0,19,0 + 475 318 475 318 475 256 c 128,-1,1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-31 +Encoding: 75 75 43 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +256 411 m 128,-1,1 + 215 411 215 411 178 391 c 0,2,3 + 142 370 142 370 121 334 c 0,4,5 + 101 297 101 297 101 256 c 128,-1,6 + 101 215 101 215 121 178 c 0,7,8 + 142 142 142 142 178 121 c 0,9,10 + 215 101 215 101 256 101 c 128,-1,11 + 297 101 297 101 334 121 c 0,12,13 + 370 142 370 142 391 178 c 0,14,15 + 411 215 411 215 411 256 c 128,-1,16 + 411 297 411 297 391 334 c 0,17,18 + 370 370 370 370 334 391 c 0,19,0 + 297 411 297 411 256 411 c 128,-1,1 +475 256 m 128,-1,21 + 475 194 475 194 446 146 c 0,22,23 + 416 96 416 96 366 66 c 0,24,25 + 318 37 318 37 256 37 c 128,-1,26 + 194 37 194 37 146 66 c 0,27,28 + 96 96 96 96 66 146 c 0,29,30 + 37 194 37 194 37 256 c 128,-1,31 + 37 318 37 318 66 366 c 0,32,33 + 96 416 96 416 146 446 c 0,34,35 + 194 475 194 475 256 475 c 128,-1,36 + 318 475 318 475 366 446 c 0,37,38 + 416 416 416 416 446 366 c 0,39,20 + 475 318 475 318 475 256 c 128,-1,21 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-32 +Encoding: 76 76 44 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +426 134 m 0,0,1 + 426 123 426 123 418 115 c 2,2,-1 + 379 76 l 2,3,4 + 371 68 371 68 359 68 c 0,5,6 + 348 68 348 68 340 76 c 2,7,-1 + 256 160 l 1,8,-1 + 172 76 l 2,9,10 + 164 68 164 68 153 68 c 0,11,12 + 141 68 141 68 133 76 c 2,13,-1 + 94 115 l 2,14,15 + 86 123 86 123 86 134 c 0,16,17 + 86 144 86 144 94 154 c 2,18,-1 + 178 238 l 1,19,-1 + 94 322 l 2,20,21 + 86 330 86 330 86 341 c 0,22,23 + 86 351 86 351 94 361 c 2,24,-1 + 133 399 l 2,25,26 + 140 407 140 407 153 407 c 0,27,28 + 165 407 165 407 172 399 c 2,29,-1 + 256 315 l 1,30,-1 + 340 399 l 2,31,32 + 347 407 347 407 359 407 c 0,33,34 + 372 407 372 407 379 399 c 2,35,-1 + 418 361 l 2,36,37 + 426 351 426 351 426 341 c 0,38,39 + 426 330 426 330 418 322 c 2,40,-1 + 334 238 l 1,41,-1 + 418 154 l 2,42,43 + 426 144 426 144 426 134 c 0,0,1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: arrow-full-lowerright +Encoding: 77 77 45 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +448 384 m 1,0,-1 + 352 288 l 1,1,-1 + 192 448 l 1,2,-1 + 64 320 l 1,3,-1 + 224 160 l 1,4,-1 + 128 64 l 1,5,-1 + 448 64 l 1,6,-1 + 448 384 l 1,0,-1 +EndSplineSet +Validated: 521 +EndChar + +StartChar: arrow-full-upperright +Encoding: 78 78 46 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +448 128 m 1,0,-1 + 352 224 l 1,1,-1 + 192 64 l 1,2,-1 + 64 192 l 1,3,-1 + 224 352 l 1,4,-1 + 128 448 l 1,5,-1 + 448 448 l 1,6,-1 + 448 128 l 1,0,-1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-33 +Encoding: 79 79 47 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +402 238 m 2,0,-1 + 402 274 l 2,1,2 + 402 282 402 282 397 287 c 0,3,4 + 391 293 391 293 384 293 c 2,5,-1 + 293 293 l 1,6,-1 + 293 384 l 2,7,8 + 293 391 293 391 287 397 c 0,9,10 + 282 402 282 402 274 402 c 2,11,-1 + 238 402 l 2,12,13 + 230 402 230 402 225 397 c 0,14,15 + 219 391 219 391 219 384 c 2,16,-1 + 219 293 l 1,17,-1 + 128 293 l 2,18,19 + 121 293 121 293 115 287 c 0,20,21 + 110 282 110 282 110 274 c 2,22,-1 + 110 238 l 2,23,24 + 110 230 110 230 115 225 c 0,25,26 + 121 219 121 219 128 219 c 2,27,-1 + 219 219 l 1,28,-1 + 219 128 l 2,29,30 + 219 121 219 121 225 115 c 0,31,32 + 230 110 230 110 238 110 c 2,33,-1 + 274 110 l 2,34,35 + 282 110 282 110 287 115 c 0,36,37 + 293 121 293 121 293 128 c 2,38,-1 + 293 219 l 1,39,-1 + 384 219 l 2,40,41 + 391 219 391 219 397 225 c 0,42,43 + 402 230 402 230 402 238 c 2,0,-1 +475 393 m 2,44,-1 + 475 119 l 2,45,46 + 475 85 475 85 451 61 c 128,-1,47 + 427 37 427 37 393 37 c 2,48,-1 + 119 37 l 2,49,50 + 85 37 85 37 61 61 c 128,-1,51 + 37 85 37 85 37 119 c 2,52,-1 + 37 393 l 2,53,54 + 37 427 37 427 61 451 c 128,-1,55 + 85 475 85 475 119 475 c 2,56,-1 + 393 475 l 2,57,58 + 427 475 427 475 451 451 c 128,-1,59 + 475 427 475 427 475 393 c 2,44,-1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-41 +Encoding: 80 80 48 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +475 256 m 128,-1,1 + 475 209 475 209 458 171 c 0,2,3 + 438 127 438 127 411 101 c 0,4,5 + 385 74 385 74 341 54 c 0,6,7 + 303 37 303 37 256 37 c 0,8,9 + 204 37 204 37 163 57 c 0,10,11 + 120 77 120 77 87 116 c 0,12,13 + 85 120 85 120 85 122 c 0,14,15 + 85 125 85 125 88 128 c 2,16,-1 + 127 167 l 2,17,18 + 130 170 130 170 134 170 c 0,19,20 + 135 170 135 170 141 167 c 0,21,22 + 160 139 160 139 192 125 c 0,23,24 + 222 110 222 110 256 110 c 0,25,26 + 285 110 285 110 313 121 c 0,27,28 + 341 133 341 133 359 153 c 0,29,30 + 379 171 379 171 391 199 c 0,31,32 + 402 227 402 227 402 256 c 128,-1,33 + 402 285 402 285 391 313 c 0,34,35 + 379 341 379 341 359 359 c 0,36,37 + 341 379 341 379 313 391 c 0,38,39 + 285 402 285 402 256 402 c 0,40,41 + 226 402 226 402 202 392 c 0,42,43 + 175 381 175 381 157 363 c 1,44,-1 + 196 324 l 2,45,46 + 205 315 205 315 200 304 c 0,47,48 + 194 293 194 293 183 293 c 2,49,-1 + 55 293 l 2,50,51 + 47 293 47 293 42 298 c 128,-1,52 + 37 303 37 303 37 311 c 2,53,-1 + 37 439 l 2,54,55 + 37 450 37 450 48 456 c 0,56,57 + 59 461 59 461 68 452 c 2,58,-1 + 105 415 l 1,59,60 + 134 443 134 443 175 460 c 0,61,62 + 214 475 214 475 256 475 c 0,63,64 + 303 475 303 475 341 458 c 0,65,66 + 385 438 385 438 411 411 c 0,67,68 + 438 385 438 385 458 341 c 0,69,0 + 475 303 475 303 475 256 c 128,-1,1 +EndSplineSet +Validated: 545 +EndChar + +StartChar: burning-fire +Encoding: 81 81 49 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +384 320 m 1,0,1 + 361 319 361 319 306 288 c 1,2,-1 + 302 293 l 1,3,4 + 306 380 306 380 320 416 c 1,5,6 + 317 414 317 414 308.5 407.5 c 128,-1,7 + 300 401 300 401 285 389.5 c 128,-1,8 + 270 378 270 378 258 369 c 1,9,10 + 246 398 246 398 244.5 440 c 128,-1,11 + 243 482 243 482 256 512 c 1,12,13 + 154 439 154 439 93 343.5 c 128,-1,14 + 32 248 32 248 32 176 c 0,15,16 + 32 172 32 172 32 165 c 0,17,18 + 32 141 32 141 32.5 128 c 128,-1,19 + 33 115 33 115 37 92 c 128,-1,20 + 41 69 41 69 51.5 55.5 c 128,-1,21 + 62 42 62 42 78.5 27.5 c 128,-1,22 + 95 13 95 13 124 6.5 c 128,-1,23 + 153 0 153 0 192 0 c 0,24,25 + 255 0 255 0 293.5 15 c 128,-1,26 + 332 30 332 30 345.5 54 c 128,-1,27 + 359 78 359 78 363.5 112.5 c 128,-1,28 + 368 147 368 147 365 180 c 128,-1,29 + 362 213 362 213 366 252.5 c 128,-1,30 + 370 292 370 292 384 320 c 1,0,1 +211 50 m 0,31,32 + 100 47 100 47 101 126 c 0,33,34 + 102 165 102 165 123 197 c 1,35,-1 + 124 198 l 2,36,37 + 123 196 123 196 122 194 c 256,38,39 + 121 192 121 192 119.5 187 c 128,-1,40 + 118 182 118 182 119 172.5 c 128,-1,41 + 120 163 120 163 124.5 153 c 128,-1,42 + 129 143 129 143 141.5 131 c 128,-1,43 + 154 119 154 119 173 109 c 1,44,45 + 165 119 165 119 164 131 c 128,-1,46 + 163 143 163 143 165.5 152 c 128,-1,47 + 168 161 168 161 177 174 c 128,-1,48 + 186 187 186 187 191.5 193 c 128,-1,49 + 197 199 197 199 209 211 c 128,-1,50 + 221 223 221 223 222 224 c 1,51,52 + 222 198 222 198 228 169 c 128,-1,53 + 234 140 234 140 240 124 c 2,54,-1 + 246 109 l 1,55,56 + 250 112 250 112 257.5 118 c 128,-1,57 + 265 124 265 124 283 151 c 128,-1,58 + 301 178 301 178 313 214 c 1,59,60 + 332 132 332 132 310 92.5 c 128,-1,61 + 288 53 288 53 211 50 c 0,31,32 +EndSplineSet +Validated: 553 +EndChar + +StartChar: arrow-sans-down +Encoding: 82 82 50 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +32 352 m 1,0,-1 + 256 128 l 1,1,-1 + 480 352 l 1,2,-1 + 32 352 l 1,0,-1 +EndSplineSet +Validated: 521 +EndChar + +StartChar: arrow-sans-up +Encoding: 83 83 51 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +480 160 m 1,0,-1 + 256 384 l 1,1,-1 + 32 160 l 1,2,-1 + 480 160 l 1,0,-1 +EndSplineSet +Validated: 521 +EndChar + +StartChar: fontawesome-webfont-34 +Encoding: 84 84 52 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +381 350 m 0,0,1 + 386 344 386 344 383 338 c 2,2,-1 + 229 7 l 2,3,4 + 225 0 225 0 217 0 c 0,5,6 + 214 0 214 0 213 1 c 0,7,8 + 207 2 207 2 205 6 c 0,9,10 + 203 12 203 12 204 15 c 2,11,-1 + 260 245 l 1,12,-1 + 144 217 l 2,13,14 + 144 216 144 216 141 216 c 0,15,16 + 135 216 135 216 132 219 c 0,17,18 + 127 224 127 224 128 231 c 2,19,-1 + 186 466 l 2,20,21 + 186 469 186 469 190 473 c 0,22,23 + 193 475 193 475 198 475 c 2,24,-1 + 292 475 l 2,25,26 + 298 475 298 475 301 472 c 0,27,28 + 305 468 305 468 305 463 c 0,29,30 + 305 462 305 462 303 458 c 2,31,-1 + 255 326 l 1,32,-1 + 368 354 l 1,33,-1 + 369 354 l 2,34,35 + 370 355 370 355 371 355 c 0,36,37 + 376 355 376 355 381 350 c 0,0,1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: crossed-swords-small +Encoding: 85 85 53 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +281 240 m 1,0,-1 + 377 136 l 1,1,2 + 403 156 403 156 412 177 c 1,3,-1 + 443 177 l 1,4,5 + 434 135 434 135 403 112 c 1,6,-1 + 456 49 l 1,7,8 + 477 48 477 48 478 26 c 0,9,10 + 477 13 477 13 466 6 c 0,11,12 + 456 0 456 0 441 0 c 0,13,14 + 416 1 416 1 415 28 c 1,15,-1 + 361 86 l 1,16,17 + 326 67 326 67 295 64 c 1,18,-1 + 281 87 l 1,19,20 + 315 91 315 91 339 109 c 1,21,-1 + 255 209 l 1,22,-1 + 172 109 l 1,23,24 + 196 91 196 91 229 87 c 1,25,-1 + 216 64 l 1,26,27 + 184 67 184 67 149 86 c 1,28,-1 + 96 28 l 1,29,30 + 94 3 94 3 74 0 c 0,31,32 + 58 0 58 0 47 5 c 0,33,34 + 35 10 35 10 33 22 c 0,35,36 + 33 48 33 48 55 49 c 1,37,-1 + 108 112 l 1,38,39 + 75 137 75 137 68 177 c 1,40,-1 + 99 177 l 1,41,42 + 108 156 108 156 134 136 c 1,43,-1 + 229 240 l 1,44,-1 + 44 461 l 1,45,-1 + 33 512 l 1,46,-1 + 255 269 l 1,47,-1 + 478 512 l 1,48,-1 + 467 461 l 1,49,-1 + 281 240 l 1,0,-1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-35 +Encoding: 86 86 54 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +13 40 m 2,0,1 + 6 35 6 35 4 37 c 0,2,3 + 0 38 0 38 0 46 c 2,4,-1 + 0 466 l 2,5,6 + 0 474 0 474 4 475 c 0,7,8 + 6 477 6 477 13 472 c 2,9,-1 + 216 269 l 1,10,-1 + 219 263 l 1,11,-1 + 219 466 l 2,12,13 + 219 473 219 473 223 475 c 128,-1,14 + 227 477 227 477 232 472 c 2,15,-1 + 435 269 l 2,16,17 + 438 266 438 266 439 263 c 2,18,-1 + 439 457 l 2,19,20 + 439 463 439 463 444 470 c 0,21,22 + 449 475 449 475 457 475 c 2,23,-1 + 494 475 l 2,24,25 + 502 475 502 475 507 470 c 0,26,27 + 512 463 512 463 512 457 c 2,28,-1 + 512 55 l 2,29,30 + 512 49 512 49 507 42 c 0,31,32 + 502 37 502 37 494 37 c 2,33,-1 + 457 37 l 2,34,35 + 449 37 449 37 444 42 c 0,36,37 + 439 49 439 49 439 55 c 2,38,-1 + 439 249 l 2,39,40 + 437 245 437 245 435 243 c 2,41,-1 + 232 40 l 2,42,43 + 227 35 227 35 223 37 c 128,-1,44 + 219 39 219 39 219 46 c 2,45,-1 + 219 249 l 1,46,-1 + 216 243 l 1,47,-1 + 13 40 l 2,0,1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-36 +Encoding: 87 87 55 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +499 472 m 2,0,1 + 506 477 506 477 508 475 c 0,2,3 + 512 474 512 474 512 466 c 2,4,-1 + 512 46 l 2,5,6 + 512 38 512 38 508 37 c 0,7,8 + 506 35 506 35 499 40 c 2,9,-1 + 296 243 l 1,10,-1 + 293 249 l 1,11,-1 + 293 46 l 2,12,13 + 293 39 293 39 289 37 c 128,-1,14 + 285 35 285 35 280 40 c 2,15,-1 + 77 243 l 2,16,17 + 75 245 75 245 73 249 c 2,18,-1 + 73 55 l 2,19,20 + 73 49 73 49 68 42 c 0,21,22 + 63 37 63 37 55 37 c 2,23,-1 + 18 37 l 2,24,25 + 10 37 10 37 5 42 c 0,26,27 + 0 49 0 49 0 55 c 2,28,-1 + 0 457 l 2,29,30 + 0 463 0 463 5 470 c 0,31,32 + 10 475 10 475 18 475 c 2,33,-1 + 55 475 l 2,34,35 + 63 475 63 475 68 470 c 0,36,37 + 73 463 73 463 73 457 c 2,38,-1 + 73 263 l 2,39,40 + 74 266 74 266 77 269 c 2,41,-1 + 280 472 l 2,42,43 + 285 477 285 477 289 475 c 128,-1,44 + 293 473 293 473 293 466 c 2,45,-1 + 293 263 l 1,46,-1 + 296 269 l 1,47,-1 + 499 472 l 2,0,1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-37 +Encoding: 88 88 56 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +123 40 m 2,0,1 + 116 35 116 35 113 37 c 0,2,3 + 110 38 110 38 110 46 c 2,4,-1 + 110 466 l 2,5,6 + 110 474 110 474 113 475 c 0,7,8 + 116 477 116 477 123 472 c 2,9,-1 + 325 269 l 2,10,11 + 328 266 328 266 329 263 c 2,12,-1 + 329 457 l 2,13,14 + 329 464 329 464 335 470 c 0,15,16 + 339 475 339 475 347 475 c 2,17,-1 + 384 475 l 2,18,19 + 392 475 392 475 397 470 c 0,20,21 + 402 463 402 463 402 457 c 2,22,-1 + 402 55 l 2,23,24 + 402 49 402 49 397 42 c 0,25,26 + 392 37 392 37 384 37 c 2,27,-1 + 347 37 l 2,28,29 + 339 37 339 37 335 42 c 0,30,31 + 329 48 329 48 329 55 c 2,32,-1 + 329 249 l 2,33,34 + 327 245 327 245 325 243 c 2,35,-1 + 123 40 l 2,0,1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-38 +Encoding: 89 89 57 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +389 472 m 2,0,1 + 396 477 396 477 399 475 c 0,2,3 + 402 474 402 474 402 466 c 2,4,-1 + 402 46 l 2,5,6 + 402 38 402 38 399 37 c 0,7,8 + 396 35 396 35 389 40 c 2,9,-1 + 187 243 l 2,10,11 + 185 245 185 245 183 249 c 2,12,-1 + 183 55 l 2,13,14 + 183 48 183 48 177 42 c 0,15,16 + 173 37 173 37 165 37 c 2,17,-1 + 128 37 l 2,18,19 + 120 37 120 37 115 42 c 0,20,21 + 110 49 110 49 110 55 c 2,22,-1 + 110 457 l 2,23,24 + 110 463 110 463 115 470 c 0,25,26 + 120 475 120 475 128 475 c 2,27,-1 + 165 475 l 2,28,29 + 173 475 173 475 177 470 c 0,30,31 + 183 464 183 464 183 457 c 2,32,-1 + 183 263 l 2,33,34 + 184 266 184 266 187 269 c 2,35,-1 + 389 472 l 2,0,1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-39 +Encoding: 90 90 58 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +475 457 m 2,0,-1 + 475 55 l 2,1,2 + 475 47 475 47 470 42 c 128,-1,3 + 465 37 465 37 457 37 c 2,4,-1 + 311 37 l 2,5,6 + 303 37 303 37 298 42 c 128,-1,7 + 293 47 293 47 293 55 c 2,8,-1 + 293 457 l 2,9,10 + 293 465 293 465 298 470 c 128,-1,11 + 303 475 303 475 311 475 c 2,12,-1 + 457 475 l 2,13,14 + 465 475 465 475 470 470 c 128,-1,15 + 475 465 475 465 475 457 c 2,0,-1 +219 457 m 2,16,-1 + 219 55 l 2,17,18 + 219 47 219 47 214 42 c 128,-1,19 + 209 37 209 37 201 37 c 2,20,-1 + 55 37 l 2,21,22 + 47 37 47 37 42 42 c 128,-1,23 + 37 47 37 47 37 55 c 2,24,-1 + 37 457 l 2,25,26 + 37 465 37 465 42 470 c 128,-1,27 + 47 475 47 475 55 475 c 2,28,-1 + 201 475 l 2,29,30 + 209 475 209 475 214 470 c 128,-1,31 + 219 465 219 465 219 457 c 2,16,-1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: reorder +Encoding: 91 91 59 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +484 396 m 128,-1,1 + 484 382 484 382 473.5 371.5 c 128,-1,2 + 463 361 463 361 448 361 c 2,3,-1 + 64 361 l 2,4,5 + 49 361 49 361 38.5 371.5 c 128,-1,6 + 28 382 28 382 28 396 c 128,-1,7 + 28 410 28 410 38.5 420.5 c 128,-1,8 + 49 431 49 431 64 431 c 2,9,-1 + 448 431 l 2,10,11 + 463 431 463 431 473.5 420.5 c 128,-1,0 + 484 410 484 410 484 396 c 128,-1,1 +484 256 m 128,-1,13 + 484 242 484 242 473.5 231.5 c 128,-1,14 + 463 221 463 221 448 221 c 2,15,-1 + 64 221 l 2,16,17 + 49 221 49 221 38.5 231.5 c 128,-1,18 + 28 242 28 242 28 256 c 128,-1,19 + 28 270 28 270 38.5 280.5 c 128,-1,20 + 49 291 49 291 64 291 c 2,21,-1 + 448 291 l 2,22,23 + 463 291 463 291 473.5 280.5 c 128,-1,12 + 484 270 484 270 484 256 c 128,-1,13 +484 116 m 128,-1,25 + 484 102 484 102 473.5 91.5 c 128,-1,26 + 463 81 463 81 448 81 c 2,27,-1 + 64 81 l 2,28,29 + 49 81 49 81 38.5 91.5 c 128,-1,30 + 28 102 28 102 28 116 c 128,-1,31 + 28 130 28 130 38.5 140.5 c 128,-1,32 + 49 151 49 151 64 151 c 2,33,-1 + 448 151 l 2,34,35 + 463 151 463 151 473.5 140.5 c 128,-1,24 + 484 130 484 130 484 116 c 128,-1,25 +EndSplineSet +Validated: 1 +EndChar + +StartChar: earth-globe-streamline +Encoding: 92 92 60 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +235 139 m 128,-1,1 + 310 139 310 139 363 192 c 128,-1,2 + 416 245 416 245 416 320 c 128,-1,3 + 416 395 416 395 363 448 c 128,-1,4 + 310 501 310 501 235 501 c 128,-1,5 + 160 501 160 501 106.5 448 c 128,-1,6 + 53 395 53 395 53 320 c 128,-1,7 + 53 245 53 245 106.5 192 c 128,-1,0 + 160 139 160 139 235 139 c 128,-1,1 +235 480 m 128,-1,9 + 301 480 301 480 348 433 c 128,-1,10 + 395 386 395 386 395 320 c 128,-1,11 + 395 254 395 254 348 207 c 128,-1,12 + 301 160 301 160 235 160 c 128,-1,13 + 169 160 169 160 122 207 c 128,-1,14 + 75 254 75 254 75 320 c 128,-1,15 + 75 386 75 386 122 433 c 128,-1,8 + 169 480 169 480 235 480 c 128,-1,9 +401 154 m 0,16,17 + 468 221 468 221 469.5 315 c 128,-1,18 + 471 409 471 409 408 478 c 1,19,-1 + 416 486 l 2,20,21 + 424 494 424 494 416 501 c 128,-1,22 + 408 508 408 508 401 501 c 2,23,-1 + 370 471 l 2,24,25 + 362 464 362 464 370 456 c 0,26,27 + 374 453 374 453 378 453 c 0,28,29 + 383 453 383 453 386 456 c 2,30,-1 + 393 463 l 1,31,32 + 449 400 449 400 447.5 315 c 128,-1,33 + 446 230 446 230 386 169 c 0,34,35 + 325 109 325 109 239.5 107 c 128,-1,36 + 154 105 154 105 92 162 c 1,37,-1 + 99 169 l 2,38,39 + 106 176 106 176 99 184 c 128,-1,40 + 92 192 92 192 84 184 c 2,41,-1 + 54 154 l 2,42,43 + 46 146 46 146 54 139 c 0,44,45 + 57 136 57 136 61 136 c 0,46,47 + 66 136 66 136 69 139 c 2,48,-1 + 77 147 l 1,49,50 + 134 94 134 94 213 86 c 1,51,-1 + 213 63 l 1,52,53 + 151 57 151 57 101 19 c 2,54,-1 + 75 0 l 1,55,-1 + 394 0 l 1,56,-1 + 369 19 l 2,57,58 + 317 57 317 57 256 63 c 1,59,-1 + 256 86 l 1,60,61 + 339 94 339 94 401 154 c 0,16,17 +145 21 m 1,62,63 + 187 43 187 43 235 43 c 0,64,65 + 281 43 281 43 325 21 c 1,66,-1 + 145 21 l 1,62,63 +EndSplineSet +Validated: 553 +EndChar + +StartChar: book +Encoding: 93 93 61 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +487 375 m 0,0,1 + 498 359 498 359 492 339 c 2,2,-1 + 413 80 l 2,3,4 + 408 62 408 62 391 49 c 0,5,6 + 374 37 374 37 356 37 c 2,7,-1 + 93 37 l 2,8,9 + 71 37 71 37 50 52 c 0,10,11 + 30 68 30 68 22 89 c 0,12,13 + 15 108 15 108 21 126 c 0,14,15 + 21 129 21 129 22 133 c 0,16,17 + 23 138 23 138 23 144 c 0,18,19 + 23 148 23 148 22 150 c 0,20,21 + 22 152 22 152 22 154 c 2,22,-1 + 21 156 l 1,23,-1 + 24 162 l 2,24,25 + 26 166 26 166 28 168 c 0,26,27 + 29 169 29 169 30.5 171.5 c 128,-1,28 + 32 174 32 174 33 175 c 0,29,30 + 39 183 39 183 46 201 c 0,31,32 + 52 215 52 215 55 227 c 2,33,-1 + 55 236 l 2,34,35 + 54 241 54 241 55 244 c 0,36,37 + 55 246 55 246 59 252 c 0,38,39 + 64 257 64 257 64 259 c 0,40,41 + 70 267 70 267 76 285 c 0,42,43 + 83 304 83 304 83 311 c 2,44,-1 + 83 320 l 2,45,46 + 81 326 81 326 83 328 c 0,47,48 + 85 332 85 332 89 336 c 0,49,50 + 95 342 95 342 95 343 c 0,51,52 + 100 349 100 349 108 367 c 0,53,54 + 115 386 115 386 115 395 c 2,55,-1 + 115 402 l 2,56,57 + 114 405 114 405 114 409 c 0,58,59 + 114 412 114 412 117 415 c 2,60,-1 + 119 418 l 2,61,62 + 121 420 121 420 122 421 c 0,63,64 + 126 426 126 426 127 427 c 0,65,66 + 130 434 130 434 131 436 c 0,67,68 + 132 437 132 437 133.5 440.5 c 128,-1,69 + 135 444 135 444 136 446 c 0,70,71 + 138 452 138 452 140 456 c 0,72,73 + 143 462 143 462 146 465 c 0,74,75 + 149 469 149 469 153 472 c 0,76,77 + 158 475 158 475 164 475 c 0,78,79 + 172 475 172 475 177 474 c 1,80,-1 + 177 473 l 1,81,82 + 184 475 184 475 191 475 c 2,83,-1 + 409 475 l 2,84,85 + 431 475 431 475 441 459 c 0,86,87 + 453 444 453 444 447 422 c 2,88,-1 + 368 163 l 2,89,90 + 357 127 357 127 348 120 c 0,91,92 + 338 110 338 110 311 110 c 2,93,-1 + 63 110 l 2,94,95 + 55 110 55 110 52 105 c 256,96,97 + 49 100 49 100 52 93 c 0,98,99 + 58 73 58 73 93 73 c 2,100,-1 + 357 73 l 2,101,102 + 363 73 363 73 373 78 c 0,103,104 + 380 82 380 82 383 89 c 2,105,-1 + 468 371 l 2,106,107 + 470 376 470 376 470 388 c 1,108,109 + 482 383 482 383 487 375 c 0,0,1 +183 375 m 2,110,111 + 182 371 182 371 183 368 c 0,112,113 + 185 366 185 366 189 366 c 2,114,-1 + 363 366 l 2,115,116 + 364 366 364 366 370 368 c 0,117,118 + 374 372 374 372 375 375 c 2,119,-1 + 381 393 l 2,120,121 + 381 398 381 398 380 400 c 0,122,123 + 378 402 378 402 374 402 c 2,124,-1 + 201 402 l 2,125,126 + 199 402 199 402 193 400 c 0,127,128 + 189 396 189 396 189 393 c 2,129,-1 + 183 375 l 2,110,111 +159 302 m 2,130,131 + 158 298 158 298 159 295 c 0,132,133 + 161 293 161 293 165 293 c 2,134,-1 + 339 293 l 2,135,136 + 344 293 344 293 346 295 c 0,137,138 + 349 297 349 297 351 302 c 2,139,-1 + 357 320 l 2,140,141 + 359 323 359 323 356 326 c 0,142,143 + 354 329 354 329 351 329 c 2,144,-1 + 177 329 l 2,145,146 + 173 329 173 329 170 326 c 0,147,148 + 168 325 168 325 165 320 c 2,149,-1 + 159 302 l 2,130,131 +EndSplineSet +Validated: 33 +EndChar + +StartChar: graph +Encoding: 94 94 62 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +352 384 m 1,0,-1 + 256 384 l 1,1,-1 + 256 64 l 1,2,-1 + 352 64 l 1,3,-1 + 352 384 l 1,0,-1 +480 288 m 1,4,-1 + 384 288 l 1,5,-1 + 384 64 l 1,6,-1 + 480 64 l 1,7,-1 + 480 288 l 1,4,-1 +32 32 m 1,8,-1 + 32 96 l 1,9,-1 + 64 96 l 1,10,-1 + 64 128 l 1,11,-1 + 32 128 l 1,12,-1 + 32 192 l 1,13,-1 + 64 192 l 1,14,-1 + 64 224 l 1,15,-1 + 32 224 l 1,16,-1 + 32 288 l 1,17,-1 + 64 288 l 1,18,-1 + 64 320 l 1,19,-1 + 32 320 l 1,20,-1 + 32 384 l 1,21,-1 + 64 384 l 1,22,-1 + 64 416 l 1,23,-1 + 32 416 l 1,24,-1 + 32 480 l 1,25,-1 + 64 480 l 1,26,-1 + 64 512 l 1,27,-1 + 0 512 l 1,28,-1 + 0 0 l 1,29,-1 + 512 0 l 1,30,-1 + 512 32 l 1,31,-1 + 32 32 l 1,8,-1 +224 224 m 1,32,-1 + 128 224 l 1,33,-1 + 128 64 l 1,34,-1 + 224 64 l 1,35,-1 + 224 224 l 1,32,-1 +EndSplineSet +Validated: 9 +EndChar + +StartChar: keypad +Encoding: 95 95 63 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +160 426 m 2,0,1 + 160 416 160 416 150 416 c 2,2,-1 + 74 416 l 2,3,4 + 64 416 64 416 64 426 c 2,5,-1 + 64 502 l 2,6,7 + 64 512 64 512 74 512 c 2,8,-1 + 150 512 l 2,9,10 + 160 512 160 512 160 502 c 2,11,-1 + 160 426 l 2,0,1 +307 426 m 2,12,13 + 307 416 307 416 297 416 c 2,14,-1 + 221 416 l 2,15,16 + 211 416 211 416 211 426 c 2,17,-1 + 211 502 l 2,18,19 + 211 512 211 512 221 512 c 2,20,-1 + 297 512 l 2,21,22 + 307 512 307 512 307 502 c 2,23,-1 + 307 426 l 2,12,13 +448 426 m 2,24,25 + 448 416 448 416 438 416 c 2,26,-1 + 362 416 l 2,27,28 + 352 416 352 416 352 426 c 2,29,-1 + 352 502 l 2,30,31 + 352 512 352 512 362 512 c 2,32,-1 + 438 512 l 2,33,34 + 448 512 448 512 448 502 c 2,35,-1 + 448 426 l 2,24,25 +160 298 m 2,36,37 + 160 288 160 288 150 288 c 2,38,-1 + 74 288 l 2,39,40 + 64 288 64 288 64 298 c 2,41,-1 + 64 374 l 2,42,43 + 64 384 64 384 74 384 c 2,44,-1 + 150 384 l 2,45,46 + 160 384 160 384 160 374 c 2,47,-1 + 160 298 l 2,36,37 +307 298 m 2,48,49 + 307 288 307 288 297 288 c 2,50,-1 + 221 288 l 2,51,52 + 211 288 211 288 211 298 c 2,53,-1 + 211 374 l 2,54,55 + 211 384 211 384 221 384 c 2,56,-1 + 297 384 l 2,57,58 + 307 384 307 384 307 374 c 2,59,-1 + 307 298 l 2,48,49 +448 298 m 2,60,61 + 448 288 448 288 438 288 c 2,62,-1 + 362 288 l 2,63,64 + 352 288 352 288 352 298 c 2,65,-1 + 352 374 l 2,66,67 + 352 384 352 384 362 384 c 2,68,-1 + 438 384 l 2,69,70 + 448 384 448 384 448 374 c 2,71,-1 + 448 298 l 2,60,61 +160 170 m 2,72,73 + 160 160 160 160 150 160 c 2,74,-1 + 74 160 l 2,75,76 + 64 160 64 160 64 170 c 2,77,-1 + 64 246 l 2,78,79 + 64 256 64 256 74 256 c 2,80,-1 + 150 256 l 2,81,82 + 160 256 160 256 160 246 c 2,83,-1 + 160 170 l 2,72,73 +307 170 m 2,84,85 + 307 160 307 160 297 160 c 2,86,-1 + 221 160 l 2,87,88 + 211 160 211 160 211 170 c 2,89,-1 + 211 246 l 2,90,91 + 211 256 211 256 221 256 c 2,92,-1 + 297 256 l 2,93,94 + 307 256 307 256 307 246 c 2,95,-1 + 307 170 l 2,84,85 +307 42 m 2,96,97 + 307 32 307 32 297 32 c 2,98,-1 + 221 32 l 2,99,100 + 211 32 211 32 211 42 c 2,101,-1 + 211 118 l 2,102,103 + 211 128 211 128 221 128 c 2,104,-1 + 297 128 l 2,105,106 + 307 128 307 128 307 118 c 2,107,-1 + 307 42 l 2,96,97 +448 170 m 2,108,109 + 448 160 448 160 438 160 c 2,110,-1 + 362 160 l 2,111,112 + 352 160 352 160 352 170 c 2,113,-1 + 352 246 l 2,114,115 + 352 256 352 256 362 256 c 2,116,-1 + 438 256 l 2,117,118 + 448 256 448 256 448 246 c 2,119,-1 + 448 170 l 2,108,109 +EndSplineSet +Validated: 1 +EndChar + +StartChar: body-cut +Encoding: 96 96 64 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +228 359 m 0,0,1 + 232 359 232 359 242 361 c 0,2,3 + 246 361 246 361 247 364 c 0,4,5 + 249 368 249 368 249 370 c 2,6,-1 + 225 505 l 2,7,8 + 223 514 223 514 215 512 c 0,9,10 + 183 507 183 507 165 480.5 c 128,-1,11 + 147 454 147 454 153 423 c 0,12,13 + 157 395 157 395 178.5 377 c 128,-1,14 + 200 359 200 359 228 359 c 0,0,1 +210 493 m 1,15,-1 + 230 377 l 1,16,-1 + 228 376 l 1,17,18 + 206 376 206 376 190 390 c 128,-1,19 + 174 404 174 404 170 426 c 128,-1,20 + 166 448 166 448 177.5 467 c 128,-1,21 + 189 486 189 486 210 493 c 1,15,-1 +364 361 m 0,22,23 + 374 359 374 359 378 359 c 0,24,25 + 406 359 406 359 427.5 377 c 128,-1,26 + 449 395 449 395 453 423 c 0,27,28 + 459 454 459 454 441 480.5 c 128,-1,29 + 423 507 423 507 391 512 c 0,30,31 + 387 512 387 512 385 510 c 0,32,33 + 383 509 383 509 381 505 c 2,34,-1 + 358 370 l 2,35,36 + 356 361 356 361 364 361 c 0,22,23 +396 493 m 1,37,38 + 417 486 417 486 429 467 c 128,-1,39 + 441 448 441 448 437 426 c 0,40,41 + 432 404 432 404 415 390 c 128,-1,42 + 398 376 398 376 376 377 c 1,43,-1 + 396 493 l 1,37,38 +495 119 m 2,44,-1 + 401 119 l 1,45,-1 + 407 152 l 1,46,47 + 417 146 417 146 423 145 c 0,48,49 + 437 142 437 142 449 150.5 c 128,-1,50 + 461 159 461 159 463 173 c 2,51,-1 + 477 263 l 2,52,53 + 482 286 482 286 467 307 c 0,54,55 + 453 327 453 327 429 332 c 2,56,-1 + 362 344 l 2,57,58 + 357 344 357 344 355 342 c 0,59,60 + 352 340 352 340 352 337 c 2,61,-1 + 321 160 l 2,62,63 + 319 151 319 151 327 151 c 0,64,65 + 336 149 336 149 334 141 c 2,66,-1 + 331 119 l 1,67,-1 + 274 119 l 1,68,-1 + 272 141 l 2,69,70 + 270 149 270 149 279 151 c 0,71,72 + 282 151 282 151 284 154 c 0,73,74 + 286 156 286 156 286 160 c 2,75,-1 + 255 337 l 2,76,77 + 253 346 253 346 245 344 c 2,78,-1 + 177 332 l 2,79,80 + 153 327 153 327 139 307 c 128,-1,81 + 125 287 125 287 129 263 c 2,82,-1 + 144 174 l 2,83,84 + 147 160 147 160 158 152 c 0,85,86 + 170 143 170 143 184 146 c 0,87,88 + 191 147 191 147 199 153 c 1,89,-1 + 205 119 l 1,90,-1 + 162 119 l 1,91,-1 + 162 128 l 2,92,93 + 162 137 162 137 154 137 c 0,94,95 + 145 137 145 137 145 128 c 2,96,-1 + 145 119 l 1,97,-1 + 17 119 l 2,98,99 + 2 119 2 119 2 85 c 128,-1,100 + 2 51 2 51 17 51 c 2,101,-1 + 145 51 l 1,102,-1 + 145 26 l 2,103,104 + 145 17 145 17 154 17 c 0,105,106 + 162 17 162 17 162 26 c 2,107,-1 + 162 51 l 1,108,-1 + 218 51 l 1,109,-1 + 222 28 l 2,110,111 + 224 16 224 16 234 8 c 128,-1,112 + 244 0 244 0 256 0 c 2,113,-1 + 262 0 l 2,114,115 + 276 3 276 3 284 14.5 c 128,-1,116 + 292 26 292 26 290 40 c 2,117,-1 + 288 51 l 1,118,-1 + 319 51 l 1,119,-1 + 317 40 l 2,120,121 + 314 27 314 27 322 14 c 0,122,123 + 330 3 330 3 344 0 c 2,124,-1 + 350 0 l 2,125,126 + 363 0 363 0 372.5 8 c 128,-1,127 + 382 16 382 16 384 28 c 2,128,-1 + 388 51 l 1,129,-1 + 461 51 l 2,130,131 + 478 51 478 51 491 72 c 128,-1,132 + 504 93 504 93 504 111 c 0,133,134 + 504 119 504 119 495 119 c 2,44,-1 +211 184 m 1,135,-1 + 211 185 l 1,136,-1 + 201 243 l 2,137,138 + 199 252 199 252 191 250 c 0,139,140 + 188 250 188 250 185.5 247 c 128,-1,141 + 183 244 183 244 184 241 c 2,142,-1 + 194 183 l 1,143,-1 + 194 182 l 2,144,145 + 196 175 196 175 192 169.5 c 128,-1,146 + 188 164 188 164 181 163 c 128,-1,147 + 174 162 174 162 168 166 c 0,148,149 + 163 169 163 169 161 177 c 2,150,-1 + 146 266 l 2,151,152 + 143 283 143 283 153 297.5 c 128,-1,153 + 163 312 163 312 180 315 c 2,154,-1 + 239 326 l 1,155,-1 + 268 164 l 1,156,157 + 252 156 252 156 255 138 c 2,158,-1 + 257 119 l 1,159,-1 + 222 119 l 1,160,-1 + 211 184 l 1,135,-1 +94 102 m 1,161,-1 + 111 102 l 1,162,-1 + 111 68 l 1,163,-1 + 94 68 l 1,164,-1 + 94 102 l 1,161,-1 +77 68 m 1,165,-1 + 60 68 l 1,166,-1 + 60 102 l 1,167,-1 + 77 102 l 1,168,-1 + 77 68 l 1,165,-1 +20 102 m 1,169,-1 + 43 102 l 1,170,-1 + 43 68 l 1,171,-1 + 20 68 l 1,172,173 + 18 73 18 73 18 85 c 128,-1,174 + 18 97 18 97 20 102 c 1,169,-1 +128 68 m 1,175,-1 + 128 102 l 1,176,-1 + 145 102 l 1,177,-1 + 145 68 l 1,178,-1 + 128 68 l 1,175,-1 +273 37 m 2,179,180 + 275 21 275 21 259 17 c 0,181,182 + 252 16 252 16 246.5 20 c 128,-1,183 + 241 24 241 24 239 31 c 2,184,-1 + 236 51 l 1,185,-1 + 270 51 l 1,186,-1 + 273 37 l 2,179,180 +162 68 m 1,187,-1 + 162 102 l 1,188,-1 + 328 102 l 1,189,-1 + 322 68 l 1,190,-1 + 162 68 l 1,187,-1 +367 31 m 2,191,192 + 363 14 363 14 347 17 c 0,193,194 + 340 19 340 19 336 24 c 0,195,196 + 333 30 333 30 333 37 c 2,197,-1 + 351 138 l 2,198,199 + 354 156 354 156 339 164 c 1,200,-1 + 367 326 l 1,201,-1 + 426 315 l 2,202,203 + 444 312 444 312 453 298 c 0,204,205 + 463 283 463 283 460 266 c 2,206,-1 + 446 175 l 2,207,208 + 442 159 442 159 426 162 c 0,209,210 + 420 162 420 162 415 169 c 0,211,212 + 412 173 412 173 412 181 c 2,213,-1 + 412 182 l 1,214,-1 + 423 241 l 2,215,216 + 423 249 423 249 416 251 c 0,217,218 + 408 253 408 253 406 244 c 2,219,-1 + 395 183 l 1,220,-1 + 395 182 l 1,221,-1 + 367 31 l 2,191,192 +461 68 m 2,222,-1 + 391 68 l 1,223,-1 + 398 102 l 1,224,-1 + 485 102 l 1,225,226 + 483 90 483 90 475.5 79 c 128,-1,227 + 468 68 468 68 461 68 c 2,222,-1 +EndSplineSet +Validated: 553 +EndChar + +StartChar: fontawesome-webfont-1 +Encoding: 97 97 65 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +393 293 m 2,0,1 + 403 293 403 293 413 285 c 0,2,3 + 421 275 421 275 421 265 c 2,4,-1 + 421 101 l 2,5,6 + 421 89 421 89 413 81 c 0,7,8 + 403 73 403 73 393 73 c 2,9,-1 + 119 73 l 2,10,11 + 109 73 109 73 99 81 c 0,12,13 + 91 89 91 89 91 101 c 2,14,-1 + 91 265 l 2,15,16 + 91 275 91 275 99 285 c 0,17,18 + 109 293 109 293 119 293 c 2,19,-1 + 128 293 l 1,20,-1 + 128 384 l 2,21,22 + 128 436 128 436 166 474 c 128,-1,23 + 204 512 204 512 256 512 c 128,-1,24 + 308 512 308 512 346 474 c 128,-1,25 + 384 436 384 436 384 384 c 0,26,27 + 384 378 384 378 379 371 c 0,28,29 + 372 366 372 366 366 366 c 2,30,-1 + 347 366 l 2,31,32 + 340 366 340 366 335 371 c 0,33,34 + 329 377 329 377 329 384 c 0,35,36 + 329 414 329 414 308 436 c 0,37,38 + 286 457 286 457 256 457 c 128,-1,39 + 226 457 226 457 204 436 c 0,40,41 + 183 414 183 414 183 384 c 2,42,-1 + 183 293 l 1,43,-1 + 393 293 l 2,0,1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-2 +Encoding: 98 98 66 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +475 213 m 1,0,-1 + 475 389 l 1,1,2 + 426 363 426 363 388 363 c 0,3,4 + 364 363 364 363 347 373 c 0,5,6 + 319 386 319 386 294 394 c 0,7,8 + 273 402 273 402 243 402 c 0,9,10 + 194 402 194 402 128 366 c 1,11,-1 + 128 195 l 1,12,13 + 200 227 200 227 252 227 c 0,14,15 + 263 227 263 227 281 225 c 0,16,17 + 291 224 291 224 309 218 c 0,18,19 + 315 216 315 216 322 213 c 128,-1,20 + 329 210 329 210 331 209 c 128,-1,21 + 333 208 333 208 337 206 c 128,-1,22 + 341 204 341 204 345.5 202 c 128,-1,23 + 350 200 350 200 355 197 c 2,24,-1 + 363 193 l 2,25,26 + 375 187 375 187 392 187 c 0,27,28 + 425 187 425 187 475 213 c 1,0,-1 +91 439 m 0,29,30 + 91 427 91 427 86 421 c 0,31,32 + 82 413 82 413 73 407 c 1,33,-1 + 73 46 l 2,34,35 + 73 43 73 43 71 39 c 0,36,37 + 69 37 69 37 64 37 c 2,38,-1 + 46 37 l 2,39,40 + 41 37 41 37 39 39 c 128,-1,41 + 37 41 37 41 37 46 c 2,42,-1 + 37 407 l 1,43,44 + 29 413 29 413 23 421 c 0,45,46 + 18 429 18 429 18 439 c 0,47,48 + 18 454 18 454 29 465 c 0,49,50 + 39 475 39 475 55 475 c 128,-1,51 + 71 475 71 475 81 465 c 128,-1,52 + 91 455 91 455 91 439 c 0,29,30 +512 421 m 2,53,-1 + 512 203 l 2,54,55 + 512 192 512 192 502 186 c 0,56,57 + 498 184 498 184 497 184 c 0,58,59 + 436 151 436 151 392 151 c 0,60,61 + 366 151 366 151 347 161 c 2,62,-1 + 339 165 l 2,63,64 + 322 173 322 173 310 178 c 0,65,66 + 302 182 302 182 284 187 c 0,67,68 + 264 191 264 191 252 191 c 0,69,70 + 226 191 226 191 184 178 c 0,71,72 + 147 166 147 166 119 149 c 0,73,74 + 114 146 114 146 110 146 c 128,-1,75 + 106 146 106 146 101 149 c 0,76,77 + 91 153 91 153 91 165 c 2,78,-1 + 91 377 l 2,79,80 + 91 386 91 386 100 392 c 0,81,82 + 114 400 114 400 123 404 c 0,83,84 + 124 405 124 405 155 419 c 0,85,86 + 179 429 179 429 199 433 c 0,87,88 + 222 439 222 439 243 439 c 0,89,90 + 274 439 274 439 303 430 c 0,91,92 + 333 420 333 420 363 405 c 0,93,94 + 375 400 375 400 388 400 c 0,95,96 + 422 400 422 400 477 432 c 0,97,98 + 483 435 483 435 485 437 c 0,99,100 + 494 442 494 442 503 436 c 128,-1,101 + 512 430 512 430 512 421 c 2,53,-1 +EndSplineSet +Validated: 545 +EndChar + +StartChar: fontawesome-webfont-3 +Encoding: 99 99 67 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +256 402 m 128,-1,1 + 196 402 196 402 147 382 c 0,2,3 + 97 363 97 363 66 329 c 0,4,5 + 37 294 37 294 37 256 c 0,6,7 + 37 222 37 222 57 195 c 0,8,9 + 79 165 79 165 115 145 c 2,10,-1 + 139 131 l 1,11,-1 + 132 103 l 2,12,13 + 124 77 124 77 112 54 c 1,14,15 + 157 72 157 72 190 103 c 2,16,-1 + 203 114 l 1,17,-1 + 219 112 l 2,18,19 + 232 110 232 110 256 110 c 0,20,21 + 316 110 316 110 365 130 c 0,22,23 + 415 149 415 149 446 183 c 0,24,25 + 475 218 475 218 475 256 c 128,-1,26 + 475 294 475 294 446 329 c 0,27,28 + 415 363 415 363 365 382 c 0,29,0 + 316 402 316 402 256 402 c 128,-1,1 +512 256 m 128,-1,31 + 512 205 512 205 478 164 c 0,32,33 + 444 122 444 122 385 98 c 0,34,35 + 326 73 326 73 256 73 c 0,36,37 + 243 73 243 73 215 75 c 1,38,39 + 158 26 158 26 83 6 c 0,40,41 + 71 3 71 3 51 0 c 2,42,-1 + 49 0 l 2,43,44 + 46 0 46 0 41 3 c 0,45,46 + 39 5 39 5 37 11 c 0,47,48 + 36 12 36 12 37 15 c 2,49,-1 + 37 17 l 2,50,51 + 37 18 37 18 39 20 c 2,52,-1 + 40 23 l 1,53,-1 + 42 25 l 2,54,55 + 45 28 45 28 45 28 c 1,56,-1 + 46 30 l 2,57,58 + 48 31 48 31 50 33.5 c 128,-1,59 + 52 36 52 36 53 38 c 2,60,-1 + 63 48 l 2,61,62 + 64 49 64 49 67 53 c 128,-1,63 + 70 57 70 57 72 60 c 0,64,65 + 77 67 77 67 81 74 c 0,66,67 + 84 78 84 78 89 91 c 0,68,69 + 91 95 91 95 93.5 102.5 c 128,-1,70 + 96 110 96 110 97 113 c 0,71,72 + 51 139 51 139 26 176 c 0,73,74 + 0 214 0 214 0 256 c 0,75,76 + 0 307 0 307 34 348 c 0,77,78 + 68 390 68 390 127 414 c 0,79,80 + 186 439 186 439 256 439 c 128,-1,81 + 326 439 326 439 385 414 c 0,82,83 + 444 390 444 390 478 348 c 0,84,30 + 512 307 512 307 512 256 c 128,-1,31 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-4 +Encoding: 100 100 68 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +201 402 m 0,0,1 + 158 402 158 402 119 387 c 0,2,3 + 83 374 83 374 59 347 c 0,4,5 + 37 322 37 322 37 293 c 0,6,7 + 37 270 37 270 52 247 c 0,8,9 + 68 224 68 224 94 210 c 2,10,-1 + 122 194 l 1,11,-1 + 112 170 l 2,12,13 + 115 172 115 172 121 175.5 c 128,-1,14 + 127 179 127 179 130 181 c 2,15,-1 + 142 190 l 1,16,-1 + 157 187 l 2,17,18 + 177 183 177 183 201 183 c 0,19,20 + 246 183 246 183 283 198 c 0,21,22 + 321 213 321 213 343 238 c 0,23,24 + 366 264 366 264 366 293 c 0,25,26 + 366 321 366 321 343 347 c 0,27,28 + 319 374 319 374 283 387 c 0,29,30 + 245 402 245 402 201 402 c 0,0,1 +201 439 m 128,-1,32 + 254 439 254 439 302 419 c 0,33,34 + 349 399 349 399 375 366 c 0,35,36 + 402 333 402 333 402 293 c 0,37,38 + 402 254 402 254 375 219 c 0,39,40 + 349 186 349 186 302 166 c 0,41,42 + 254 146 254 146 201 146 c 0,43,44 + 179 146 179 146 151 151 c 1,45,46 + 116 126 116 126 71 114 c 0,47,48 + 69 114 69 114 64.5 113 c 128,-1,49 + 60 112 60 112 55.5 111 c 128,-1,50 + 51 110 51 110 47 110 c 2,51,-1 + 46 110 l 2,52,53 + 42 110 42 110 40 112 c 0,54,55 + 37 115 37 115 37 118 c 2,56,-1 + 37 120 l 1,57,-1 + 37 122 l 1,58,-1 + 37 123 l 1,59,-1 + 38 125 l 1,60,-1 + 39 126 l 1,61,-1 + 40 128 l 2,62,63 + 41 128 41 128 41 129 c 2,64,-1 + 43 131 l 2,65,66 + 46 134 46 134 49 138 c 2,67,-1 + 57 146 l 2,68,69 + 59 150 59 150 63 154 c 0,70,71 + 65 156 65 156 67.5 160 c 128,-1,72 + 70 164 70 164 70 165 c 0,73,74 + 74 173 74 173 76 178 c 1,75,76 + 42 198 42 198 20 229 c 0,77,78 + 0 260 0 260 0 293 c 0,79,80 + 0 333 0 333 27 366 c 0,81,82 + 55 400 55 400 100 419 c 0,83,31 + 148 439 148 439 201 439 c 128,-1,32 +436 105 m 1,84,85 + 438 100 438 100 442 92 c 0,86,87 + 444 87 444 87 449 81 c 0,88,89 + 453 77 453 77 455 73 c 0,90,91 + 456 72 456 72 457 70.5 c 128,-1,92 + 458 69 458 69 459.5 67.5 c 128,-1,93 + 461 66 461 66 463 65 c 0,94,95 + 464 64 464 64 465.5 62 c 128,-1,96 + 467 60 467 60 468 59 c 128,-1,97 + 469 58 469 58 469 57 c 1,98,99 + 470 57 470 57 471 56 c 2,100,-1 + 472 55 l 2,101,102 + 472 54 472 54 472.5 54 c 128,-1,103 + 473 54 473 54 473 53 c 2,104,-1 + 474 52 l 1,105,-1 + 475 50 l 1,106,-1 + 475 49 l 2,107,108 + 476 47 476 47 475 47 c 2,109,-1 + 475 45 l 2,110,111 + 475 41 475 41 471 39 c 0,112,113 + 469 35 469 35 465 37 c 0,114,115 + 447 39 447 39 441 41 c 0,116,117 + 396 53 396 53 361 78 c 1,118,119 + 333 73 333 73 311 73 c 0,120,121 + 234 73 234 73 176 111 c 1,122,123 + 187 110 187 110 201 110 c 0,124,125 + 249 110 249 110 289 123 c 0,126,127 + 332 135 332 135 365 159 c 0,128,129 + 401 186 401 186 420 220 c 0,130,131 + 439 256 439 256 439 293 c 0,132,133 + 439 316 439 316 432 336 c 1,134,135 + 470 315 470 315 491 285 c 128,-1,136 + 512 255 512 255 512 219 c 0,137,138 + 512 186 512 186 492 155 c 0,139,140 + 471 126 471 126 436 105 c 1,84,85 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-5 +Encoding: 101 101 69 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +512 309 m 1,0,-1 + 512 82 l 2,1,2 + 512 63 512 63 499 50 c 128,-1,3 + 486 37 486 37 466 37 c 2,4,-1 + 46 37 l 2,5,6 + 26 37 26 37 13 50 c 128,-1,7 + 0 63 0 63 0 82 c 2,8,-1 + 0 309 l 1,9,10 + 10 298 10 298 29 284 c 0,11,12 + 145 205 145 205 171 186 c 0,13,14 + 175 183 175 183 181 178.5 c 128,-1,15 + 187 174 187 174 190.5 171.5 c 128,-1,16 + 194 169 194 169 197 167 c 0,17,18 + 212 159 212 159 224 153 c 0,19,20 + 245 146 245 146 256 146 c 128,-1,21 + 267 146 267 146 288 153 c 0,22,23 + 300 159 300 159 315 167 c 0,24,25 + 318 169 318 169 321.5 171.5 c 128,-1,26 + 325 174 325 174 331 178.5 c 128,-1,27 + 337 183 337 183 341 186 c 0,28,29 + 433 250 433 250 483 284 c 0,30,31 + 502 298 502 298 512 309 c 1,0,-1 +512 393 m 0,32,33 + 512 372 512 372 498 350 c 0,34,35 + 486 332 486 332 463 315 c 0,36,37 + 365 246 365 246 329 222 c 1,38,-1 + 327 220 l 2,39,40 + 325 219 325 219 322.5 217 c 128,-1,41 + 320 215 320 215 317 213 c 128,-1,42 + 314 211 314 211 302 202 c 0,43,44 + 296 199 296 199 287 193 c 2,45,-1 + 271 185 l 2,46,47 + 259 183 259 183 256 183 c 128,-1,48 + 253 183 253 183 241 185 c 0,49,50 + 239 186 239 186 237 187 c 128,-1,51 + 235 188 235 188 233.5 188.5 c 128,-1,52 + 232 189 232 189 229.5 190.5 c 128,-1,53 + 227 192 227 192 225 193 c 0,54,55 + 216 199 216 199 210 202 c 0,56,57 + 198 211 198 211 195 213 c 128,-1,58 + 192 215 192 215 189.5 217 c 128,-1,59 + 187 219 187 219 185 220 c 2,60,-1 + 183 222 l 2,61,62 + 173 228 173 228 147.5 246 c 128,-1,63 + 122 264 122 264 108 274 c 0,64,65 + 94 283 94 283 80 293 c 128,-1,66 + 66 303 66 303 59 308 c 128,-1,67 + 52 313 52 313 49 315 c 0,68,69 + 31 327 31 327 16 348 c 0,70,71 + 0 368 0 368 0 387 c 0,72,73 + 0 409 0 409 12 424 c 128,-1,74 + 24 439 24 439 46 439 c 2,75,-1 + 466 439 l 2,76,77 + 484 439 484 439 498 425 c 128,-1,78 + 512 411 512 411 512 393 c 0,32,33 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-6 +Encoding: 102 102 70 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +158 256 m 1,0,1 + 115 255 115 255 87 222 c 1,2,-1 + 52 222 l 2,3,4 + 29 222 29 222 15 233 c 0,5,6 + 0 244 0 244 0 264 c 0,7,8 + 0 358 0 358 33 358 c 0,9,10 + 36 358 36 358 45 353 c 0,11,12 + 53 347 53 347 71 341 c 0,13,14 + 88 336 88 336 102 336 c 0,15,16 + 120 336 120 336 138 342 c 1,17,18 + 137 335 137 335 137 324 c 0,19,20 + 137 288 137 288 158 256 c 1,0,1 +444 86 m 0,21,22 + 444 54 444 54 424 36 c 0,23,24 + 405 17 405 17 373 17 c 2,25,-1 + 139 17 l 2,26,27 + 107 17 107 17 88 36 c 0,28,29 + 68 54 68 54 68 86 c 0,30,31 + 68 91 68 91 68.5 100.5 c 128,-1,32 + 69 110 69 110 69 114 c 0,33,34 + 71 132 71 132 73 143 c 0,35,36 + 77 163 77 163 80 172 c 0,37,38 + 82 177 82 177 91 198 c 0,39,40 + 98 209 98 209 108 219 c 0,41,42 + 117 228 117 228 131 234 c 0,43,44 + 146 239 146 239 161 239 c 0,45,46 + 163 239 163 239 172 233 c 0,47,48 + 184 225 184 225 191 220 c 0,49,50 + 210 210 210 210 220 208 c 0,51,52 + 238 202 238 202 256 202 c 128,-1,53 + 274 202 274 202 292 208 c 0,54,55 + 302 210 302 210 321 220 c 0,56,57 + 328 225 328 225 340 233 c 0,58,59 + 349 239 349 239 351 239 c 0,60,61 + 366 239 366 239 381 234 c 0,62,63 + 395 228 395 228 404 219 c 0,64,65 + 414 209 414 209 421 198 c 0,66,67 + 430 177 430 177 432 172 c 0,68,69 + 435 163 435 163 439 143 c 0,70,71 + 441 132 441 132 443 114 c 0,72,73 + 443 110 443 110 443.5 100.5 c 128,-1,74 + 444 91 444 91 444 86 c 0,21,22 +171 427 m 0,75,76 + 171 400 171 400 151 378 c 0,77,78 + 129 358 129 358 102 358 c 0,79,80 + 74 358 74 358 54 378 c 0,81,82 + 34 400 34 400 34 427 c 0,83,84 + 34 455 34 455 54 475 c 128,-1,85 + 74 495 74 495 102 495 c 0,86,87 + 129 495 129 495 151 475 c 0,88,89 + 171 455 171 455 171 427 c 0,75,76 +358 324 m 0,90,91 + 358 282 358 282 328 252 c 128,-1,92 + 298 222 298 222 256 222 c 128,-1,93 + 214 222 214 222 184 252 c 128,-1,94 + 154 282 154 282 154 324 c 0,95,96 + 154 367 154 367 184 397 c 128,-1,97 + 214 427 214 427 256 427 c 128,-1,98 + 298 427 298 427 328 397 c 128,-1,99 + 358 367 358 367 358 324 c 0,90,91 +512 264 m 0,100,101 + 512 244 512 244 497 233 c 0,102,103 + 483 222 483 222 460 222 c 2,104,-1 + 425 222 l 1,105,106 + 397 255 397 255 354 256 c 1,107,108 + 375 288 375 288 375 324 c 0,109,110 + 375 335 375 335 374 342 c 1,111,112 + 392 336 392 336 410 336 c 0,113,114 + 424 336 424 336 441 341 c 0,115,116 + 459 347 459 347 467 353 c 0,117,118 + 476 358 476 358 479 358 c 0,119,120 + 512 358 512 358 512 264 c 0,100,101 +478 427 m 0,121,122 + 478 400 478 400 458 378 c 0,123,124 + 438 358 438 358 410 358 c 0,125,126 + 383 358 383 358 361 378 c 0,127,128 + 341 400 341 400 341 427 c 0,129,130 + 341 455 341 455 361 475 c 0,131,132 + 383 495 383 495 410 495 c 0,133,134 + 438 495 438 495 458 475 c 128,-1,135 + 478 455 478 455 478 427 c 0,121,122 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-7 +Encoding: 103 103 71 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +149 260 m 1,0,1 + 128 307 128 307 128 366 c 1,2,-1 + 55 366 l 1,3,-1 + 55 338 l 2,4,5 + 55 316 55 316 82 292 c 0,6,7 + 110 267 110 267 149 260 c 1,0,1 +457 338 m 2,8,-1 + 457 366 l 1,9,-1 + 384 366 l 1,10,11 + 384 307 384 307 363 260 c 1,12,13 + 402 267 402 267 430 292 c 0,14,15 + 457 316 457 316 457 338 c 2,8,-1 +494 375 m 2,16,-1 + 494 338 l 2,17,18 + 494 318 494 318 482 297 c 0,19,20 + 469 276 469 276 450 260 c 0,21,22 + 429 244 429 244 400 232 c 0,23,24 + 372 222 372 222 339 220 c 1,25,26 + 327 204 327 204 312 193 c 0,27,28 + 300 182 300 182 297 172 c 0,29,30 + 293 163 293 163 293 146 c 128,-1,31 + 293 129 293 129 301 120 c 0,32,33 + 310 110 310 110 329 110 c 0,34,35 + 349 110 349 110 367 97 c 0,36,37 + 384 83 384 83 384 64 c 2,38,-1 + 384 46 l 2,39,40 + 384 42 384 42 381 39 c 0,41,42 + 380 37 380 37 375 37 c 2,43,-1 + 137 37 l 2,44,45 + 132 37 132 37 131 39 c 0,46,47 + 128 42 128 42 128 46 c 2,48,-1 + 128 64 l 2,49,50 + 128 83 128 83 145 97 c 0,51,52 + 163 110 163 110 183 110 c 0,53,54 + 202 110 202 110 211 120 c 0,55,56 + 219 129 219 129 219 146 c 128,-1,57 + 219 163 219 163 215 172 c 0,58,59 + 212 182 212 182 200 193 c 0,60,61 + 185 204 185 204 173 220 c 1,62,63 + 140 222 140 222 112 232 c 0,64,65 + 83 244 83 244 62 260 c 0,66,67 + 43 276 43 276 30 297 c 0,68,69 + 18 318 18 318 18 338 c 2,70,-1 + 18 375 l 2,71,72 + 18 386 18 386 26 394 c 128,-1,73 + 34 402 34 402 46 402 c 2,74,-1 + 128 402 l 1,75,-1 + 128 430 l 2,76,77 + 128 449 128 449 141 462 c 128,-1,78 + 154 475 154 475 174 475 c 2,79,-1 + 338 475 l 2,80,81 + 358 475 358 475 371 462 c 128,-1,82 + 384 449 384 449 384 430 c 2,83,-1 + 384 402 l 1,84,-1 + 466 402 l 2,85,86 + 478 402 478 402 486 394 c 128,-1,87 + 494 386 494 386 494 375 c 2,16,-1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-8 +Encoding: 104 104 72 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +110 128 m 128,-1,1 + 110 135 110 135 104 141 c 0,2,3 + 99 146 99 146 91 146 c 0,4,5 + 84 146 84 146 79 141 c 0,6,7 + 73 135 73 135 73 128 c 128,-1,8 + 73 121 73 121 79 115 c 0,9,10 + 84 110 84 110 91 110 c 0,11,12 + 99 110 99 110 104 115 c 0,13,0 + 110 121 110 121 110 128 c 128,-1,1 +439 293 m 0,14,15 + 439 307 439 307 428 318 c 0,16,17 + 415 329 415 329 402 329 c 2,18,-1 + 302 329 l 1,19,20 + 302 346 302 346 315 375 c 0,21,22 + 329 402 329 402 329 421 c 0,23,24 + 329 448 329 448 320 462 c 0,25,26 + 311 475 311 475 283 475 c 1,27,28 + 276 468 276 468 273 451 c 0,29,30 + 268 434 268 434 264 415 c 0,31,32 + 257 394 257 394 247 384 c 0,33,34 + 238 375 238 375 225 358 c 1,35,-1 + 224 356 l 2,36,37 + 223 355 223 355 221.5 353 c 128,-1,38 + 220 351 220 351 218 349 c 0,39,40 + 212 341 212 341 209 338 c 0,41,42 + 205 332 205 332 199 326 c 0,43,44 + 191 316 191 316 188 313 c 0,45,46 + 181 306 181 306 177 303 c 0,47,48 + 175 301 175 301 166 295 c 0,49,50 + 162 293 162 293 155 293 c 2,51,-1 + 146 293 l 1,52,-1 + 146 110 l 1,53,-1 + 155 110 l 2,54,55 + 156 110 156 110 159 109.5 c 128,-1,56 + 162 109 162 109 164 109 c 128,-1,57 + 166 109 166 109 169 108.5 c 128,-1,58 + 172 108 172 108 174 107 c 0,59,60 + 180 105 180 105 185 104 c 0,61,62 + 191 101 191 101 195 101 c 2,63,-1 + 205 97 l 2,64,65 + 211 94 211 94 213 94 c 0,66,67 + 273 73 273 73 311 73 c 2,68,-1 + 345 73 l 2,69,70 + 400 73 400 73 400 121 c 0,71,72 + 400 131 400 131 399 137 c 1,73,74 + 407 141 407 141 412 152 c 0,75,76 + 417 161 417 161 417 173 c 0,77,78 + 417 184 417 184 412 193 c 1,79,80 + 427 206 427 206 427 227 c 0,81,82 + 427 232 427 232 425 242 c 0,83,84 + 422 251 422 251 417 256 c 1,85,86 + 426 256 426 256 433 269 c 0,87,88 + 439 282 439 282 439 293 c 0,14,15 +475 293 m 0,89,90 + 475 266 475 266 461 246 c 1,91,92 + 464 237 464 237 464 227 c 0,93,94 + 464 205 464 205 453 185 c 0,95,96 + 454 181 454 181 454 173 c 0,97,98 + 454 145 454 145 437 122 c 1,99,100 + 437 82 437 82 413 60 c 0,101,102 + 389 37 389 37 348 37 c 2,103,-1 + 311 37 l 2,104,105 + 284 37 284 37 257 43 c 0,106,107 + 237 48 237 48 195 62 c 0,108,109 + 160 73 160 73 155 73 c 2,110,-1 + 73 73 l 2,111,112 + 58 73 58 73 47 84 c 0,113,114 + 37 94 37 94 37 110 c 2,115,-1 + 37 293 l 2,116,117 + 37 308 37 308 47 318 c 0,118,119 + 57 329 57 329 73 329 c 2,120,-1 + 151 329 l 1,121,122 + 162 337 162 337 191 373 c 0,123,124 + 206 393 206 393 221 410 c 0,125,126 + 228 417 228 417 231 434 c 128,-1,127 + 234 451 234 451 240 471 c 0,128,129 + 246 489 246 489 258 501 c 0,130,131 + 269 512 269 512 283 512 c 0,132,133 + 308 512 308 512 327 503 c 0,134,135 + 345 494 345 494 356 474 c 0,136,137 + 366 452 366 452 366 421 c 0,138,139 + 366 396 366 396 352 366 c 1,140,-1 + 402 366 l 2,141,142 + 430 366 430 366 454 344 c 0,143,144 + 475 323 475 323 475 293 c 0,89,90 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont +Encoding: 105 105 73 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +512 192 m 0,0,1 + 512 144 512 144 476 63 c 0,2,3 + 474 61 474 61 473 56 c 2,4,-1 + 469 48 l 2,5,6 + 469 47 469 47 468 45.5 c 128,-1,7 + 467 44 467 44 466 43 c 128,-1,8 + 465 42 465 42 465 41 c 0,9,10 + 462 37 462 37 457 37 c 0,11,12 + 454 37 454 37 450 39 c 0,13,14 + 448 43 448 43 448 47 c 128,-1,15 + 448 51 448 51 449 54 c 2,16,-1 + 449 61 l 2,17,18 + 451 87 451 87 451 96 c 0,19,20 + 451 121 451 121 446 148 c 0,21,22 + 442 169 442 169 432 187 c 0,23,24 + 423 204 423 204 409 216 c 0,25,26 + 394 229 394 229 379 236 c 0,27,28 + 362 244 362 244 341 248 c 0,29,30 + 318 253 318 253 297 254 c 0,31,32 + 267 256 267 256 247 256 c 2,33,-1 + 183 256 l 1,34,-1 + 183 183 l 2,35,36 + 183 176 183 176 177 170 c 0,37,38 + 173 165 173 165 165 165 c 0,39,40 + 156 165 156 165 152 170 c 2,41,-1 + 5 316 l 2,42,43 + 0 323 0 323 0 329 c 128,-1,44 + 0 335 0 335 5 342 c 2,45,-1 + 152 488 l 2,46,47 + 156 494 156 494 165 494 c 0,48,49 + 172 494 172 494 177 488 c 0,50,51 + 183 484 183 484 183 475 c 2,52,-1 + 183 402 l 1,53,-1 + 247 402 l 2,54,55 + 451 402 451 402 497 287 c 0,56,57 + 512 249 512 249 512 192 c 0,0,1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-9 +Encoding: 106 106 74 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +256 475 m 128,-1,1 + 318 475 318 475 366 446 c 0,2,3 + 416 416 416 416 446 366 c 0,4,5 + 475 318 475 318 475 256 c 128,-1,6 + 475 194 475 194 446 146 c 0,7,8 + 416 96 416 96 366 66 c 0,9,10 + 318 37 318 37 256 37 c 128,-1,11 + 194 37 194 37 146 66 c 0,12,13 + 96 96 96 96 66 146 c 0,14,15 + 37 194 37 194 37 256 c 128,-1,16 + 37 318 37 318 66 366 c 0,17,18 + 96 416 96 416 146 446 c 0,19,0 + 194 475 194 475 256 475 c 128,-1,1 +293 119 m 2,20,-1 + 293 173 l 2,21,22 + 293 177 293 177 290 180 c 128,-1,23 + 287 183 287 183 284 183 c 2,24,-1 + 229 183 l 2,25,26 + 225 183 225 183 222 180 c 128,-1,27 + 219 177 219 177 219 173 c 2,28,-1 + 219 119 l 2,29,30 + 219 114 219 114 222 113 c 0,31,32 + 225 110 225 110 229 110 c 2,33,-1 + 284 110 l 2,34,35 + 286 110 286 110 290 112 c 0,36,37 + 293 115 293 115 293 119 c 2,20,-1 +292 217 m 2,38,-1 + 297 395 l 2,39,40 + 297 398 297 398 294 400 c 0,41,42 + 292 402 292 402 287 402 c 2,43,-1 + 225 402 l 2,44,45 + 220 402 220 402 218 400 c 0,46,47 + 215 398 215 398 215 395 c 2,48,-1 + 220 217 l 2,49,50 + 220 215 220 215 223 212 c 0,51,52 + 225 210 225 210 229 210 c 2,53,-1 + 282 210 l 2,54,55 + 285 210 285 210 289 212 c 0,56,57 + 292 215 292 215 292 217 c 2,38,-1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-10 +Encoding: 107 107 75 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +411 257 m 0,0,1 + 411 304 411 304 387 341 c 1,2,-1 + 171 126 l 1,3,4 + 209 101 209 101 256 101 c 0,5,6 + 288 101 288 101 316 113 c 0,7,8 + 344 124 344 124 366 146 c 0,9,10 + 387 167 387 167 399 196 c 128,-1,11 + 411 225 411 225 411 257 c 0,0,1 +126 171 m 1,12,-1 + 342 387 l 1,13,14 + 302 413 302 413 256 413 c 0,15,16 + 214 413 214 413 178 392 c 128,-1,17 + 142 371 142 371 121 335 c 0,18,19 + 101 298 101 298 101 257 c 0,20,21 + 101 211 101 211 126 171 c 1,12,-1 +475 257 m 0,22,23 + 475 209 475 209 458 171 c 0,24,25 + 438 127 438 127 411 101 c 0,26,27 + 385 74 385 74 341 54 c 0,28,29 + 303 37 303 37 256 37 c 128,-1,30 + 209 37 209 37 171 54 c 0,31,32 + 127 74 127 74 101 101 c 0,33,34 + 74 127 74 127 54 171 c 0,35,36 + 37 209 37 209 37 257 c 0,37,38 + 37 304 37 304 54 342 c 0,39,40 + 72 384 72 384 101 413 c 0,41,42 + 131 443 131 443 171 459 c 0,43,44 + 212 477 212 477 256 477 c 128,-1,45 + 300 477 300 477 341 459 c 0,46,47 + 382 443 382 443 411 413 c 0,48,49 + 440 384 440 384 458 342 c 0,50,51 + 475 304 475 304 475 257 c 0,22,23 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-11 +Encoding: 108 108 76 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +256 101 m 1,0,-1 + 256 411 l 1,1,2 + 215 411 215 411 178 391 c 0,3,4 + 142 370 142 370 121 334 c 0,5,6 + 101 297 101 297 101 256 c 128,-1,7 + 101 215 101 215 121 178 c 0,8,9 + 142 142 142 142 178 121 c 0,10,11 + 215 101 215 101 256 101 c 1,0,-1 +475 256 m 128,-1,13 + 475 194 475 194 446 146 c 0,14,15 + 416 96 416 96 366 66 c 0,16,17 + 318 37 318 37 256 37 c 128,-1,18 + 194 37 194 37 146 66 c 0,19,20 + 96 96 96 96 66 146 c 0,21,22 + 37 194 37 194 37 256 c 128,-1,23 + 37 318 37 318 66 366 c 0,24,25 + 96 416 96 416 146 446 c 0,26,27 + 194 475 194 475 256 475 c 128,-1,28 + 318 475 318 475 366 446 c 0,29,30 + 416 416 416 416 446 366 c 0,31,12 + 475 318 475 318 475 256 c 128,-1,13 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-12 +Encoding: 109 109 77 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +140 73 m 1,0,-1 + 166 99 l 1,1,-1 + 99 166 l 1,2,-1 + 73 140 l 1,3,-1 + 73 110 l 1,4,-1 + 110 110 l 1,5,-1 + 110 73 l 1,6,-1 + 140 73 l 1,0,-1 +290 338 m 0,7,8 + 290 345 290 345 283 345 c 0,9,10 + 281 345 281 345 279 343 c 2,11,-1 + 124 188 l 2,12,13 + 122 186 122 186 122 183 c 0,14,15 + 122 177 122 177 128 177 c 0,16,17 + 132 177 132 177 133 179 c 2,18,-1 + 288 333 l 2,19,20 + 290 337 290 337 290 338 c 0,7,8 +274 393 m 1,21,-1 + 393 274 l 1,22,-1 + 155 37 l 1,23,-1 + 37 37 l 1,24,-1 + 37 155 l 1,25,-1 + 274 393 l 1,21,-1 +469 366 m 0,26,27 + 469 350 469 350 459 340 c 2,28,-1 + 411 293 l 1,29,-1 + 293 411 l 1,30,-1 + 340 459 l 2,31,32 + 350 469 350 469 366 469 c 0,33,34 + 381 469 381 469 392 459 c 2,35,-1 + 459 392 l 2,36,37 + 469 381 469 381 469 366 c 0,26,27 +EndSplineSet +Validated: 513 +EndChar + +StartChar: cogs +Encoding: 110 110 78 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +238 256 m 128,-1,1 + 238 286 238 286 216 308 c 0,2,3 + 195 329 195 329 165 329 c 0,4,5 + 134 329 134 329 113 308 c 0,6,7 + 91 284 91 284 91 256 c 128,-1,8 + 91 228 91 228 113 204 c 0,9,10 + 134 183 134 183 165 183 c 0,11,12 + 195 183 195 183 216 204 c 0,13,0 + 238 226 238 226 238 256 c 128,-1,1 +457 110 m 0,14,15 + 457 125 457 125 446 135 c 0,16,17 + 436 146 436 146 421 146 c 0,18,19 + 405 146 405 146 395 135 c 0,20,21 + 384 124 384 124 384 110 c 0,22,23 + 384 95 384 95 395 84 c 128,-1,24 + 406 73 406 73 421 73 c 0,25,26 + 435 73 435 73 446 84 c 0,27,28 + 457 94 457 94 457 110 c 0,14,15 +457 402 m 0,29,30 + 457 418 457 418 446 428 c 0,31,32 + 435 439 435 439 421 439 c 0,33,34 + 406 439 406 439 395 428 c 128,-1,35 + 384 417 384 417 384 402 c 0,36,37 + 384 389 384 389 395 376 c 0,38,39 + 405 366 405 366 421 366 c 0,40,41 + 436 366 436 366 446 376 c 0,42,43 + 457 387 457 387 457 402 c 0,29,30 +347 282 m 2,44,-1 + 347 229 l 2,45,46 + 347 225 347 225 345 224 c 0,47,48 + 344 221 344 221 341 221 c 2,49,-1 + 297 214 l 1,50,51 + 291 200 291 200 287 192 c 1,52,53 + 309 164 309 164 313 159 c 0,54,55 + 315 155 315 155 315 153 c 0,56,57 + 315 150 315 150 313 148 c 0,58,59 + 311 145 311 145 290 122 c 0,60,61 + 271 105 271 105 267 105 c 0,62,63 + 265 105 265 105 261 107 c 2,64,-1 + 228 133 l 1,65,66 + 214 127 214 127 206 124 c 1,67,68 + 203 93 203 93 200 80 c 0,69,70 + 197 73 197 73 191 73 c 2,71,-1 + 138 73 l 2,72,73 + 136 73 136 73 132 75 c 0,74,75 + 132 76 132 76 131 77.5 c 128,-1,76 + 130 79 130 79 129 80 c 2,77,-1 + 123 124 l 1,78,79 + 114 127 114 127 101 133 c 1,80,-1 + 68 107 l 2,81,82 + 64 105 64 105 62 105 c 0,83,84 + 59 105 59 105 56 108 c 0,85,86 + 15 146 15 146 15 153 c 0,87,88 + 15 155 15 155 17 159 c 0,89,90 + 20 164 20 164 29 174 c 0,91,92 + 32 178 32 178 37 184 c 128,-1,93 + 42 190 42 190 42 191 c 0,94,95 + 33 211 33 211 32 215 c 2,96,-1 + -11 222 l 2,97,98 + -14 222 -14 222 -16 224 c 128,-1,99 + -18 226 -18 226 -18 230 c 2,100,-1 + -18 283 l 2,101,102 + -18 287 -18 287 -16 288 c 0,103,104 + -14 291 -14 291 -12 291 c 2,105,-1 + 33 298 l 1,106,107 + 36 307 36 307 42 320 c 1,108,109 + 20 348 20 348 16 353 c 0,110,111 + 14 357 14 357 14 359 c 0,112,113 + 14 362 14 362 16 364 c 0,114,115 + 18 367 18 367 39 390 c 0,116,117 + 58 407 58 407 62 407 c 0,118,119 + 64 407 64 407 68 405 c 2,120,-1 + 101 379 l 1,121,122 + 107 382 107 382 123 388 c 1,123,124 + 126 418 126 418 129 432 c 0,125,126 + 132 439 132 439 138 439 c 2,127,-1 + 191 439 l 2,128,129 + 193 439 193 439 197 437 c 0,130,131 + 200 434 200 434 200 432 c 2,132,-1 + 206 388 l 1,133,134 + 215 385 215 385 228 379 c 1,135,-1 + 261 405 l 2,136,137 + 265 407 265 407 267 407 c 0,138,139 + 270 407 270 407 273 404 c 0,140,141 + 314 367 314 367 314 359 c 0,142,143 + 314 355 314 355 312 353 c 0,144,145 + 309 348 309 348 300 338 c 0,146,147 + 298 334 298 334 295.5 331 c 128,-1,148 + 293 328 293 328 290.5 325 c 128,-1,149 + 288 322 288 322 287 321 c 0,150,151 + 294 306 294 306 297 297 c 1,152,-1 + 341 291 l 2,153,154 + 342 290 342 290 343 289 c 128,-1,155 + 344 288 344 288 345 288 c 0,156,157 + 347 286 347 286 347 282 c 2,44,-1 +530 130 m 2,158,-1 + 530 90 l 2,159,160 + 530 86 530 86 488 81 c 0,161,162 + 487 79 487 79 485.5 76 c 128,-1,163 + 484 73 484 73 482.5 70.5 c 128,-1,164 + 481 68 481 68 479 66 c 0,165,166 + 494 33 494 33 494 27 c 2,167,-1 + 493 25 l 1,168,-1 + 457 4 l 2,169,170 + 455 4 455 4 444 18 c 0,171,172 + 440 22 440 22 435.5 28.5 c 128,-1,173 + 431 35 431 35 429 37 c 2,174,-1 + 421 37 l 1,175,-1 + 412 37 l 2,176,177 + 410 35 410 35 405 28.5 c 128,-1,178 + 400 22 400 22 397 18 c 0,179,180 + 386 4 386 4 384 4 c 0,181,182 + 372 11 372 11 349 25 c 0,183,184 + 347 25 347 25 347 27 c 0,185,186 + 347 33 347 33 362 66 c 1,187,-1 + 353 81 l 1,188,189 + 311 86 311 86 311 90 c 2,190,-1 + 311 130 l 2,191,192 + 311 134 311 134 353 139 c 1,193,194 + 359 149 359 149 362 153 c 1,195,196 + 347 186 347 186 347 193 c 1,197,-1 + 349 195 l 2,198,199 + 353 197 353 197 359 201 c 0,200,201 + 362 203 362 203 367.5 206 c 128,-1,202 + 373 209 373 209 375 210 c 2,203,-1 + 384 215 l 2,204,205 + 386 215 386 215 397 202 c 0,206,207 + 400 198 400 198 403 194 c 128,-1,208 + 406 190 406 190 408.5 186.5 c 128,-1,209 + 411 183 411 183 412 182 c 0,210,211 + 416 183 416 183 421 183 c 0,212,213 + 425 183 425 183 429 182 c 0,214,215 + 438 194 438 194 455 214 c 1,216,-1 + 457 215 l 2,217,218 + 458 215 458 215 493 195 c 0,219,220 + 493 194 493 194 493.5 194 c 128,-1,221 + 494 194 494 194 494 193 c 0,222,223 + 494 186 494 186 479 153 c 1,224,225 + 482 149 482 149 488 139 c 1,226,227 + 530 134 530 134 530 130 c 2,158,-1 +530 422 m 2,228,-1 + 530 382 l 2,229,230 + 530 378 530 378 488 373 c 1,231,232 + 480 361 480 361 479 359 c 0,233,234 + 494 326 494 326 494 319 c 0,235,236 + 494 318 494 318 493.5 318 c 128,-1,237 + 493 318 493 318 493 317 c 0,238,239 + 488 314 488 314 483.5 311.5 c 128,-1,240 + 479 309 479 309 475.5 307 c 128,-1,241 + 472 305 472 305 469 303.5 c 128,-1,242 + 466 302 466 302 464 301 c 128,-1,243 + 462 300 462 300 460.5 299 c 128,-1,244 + 459 298 459 298 458 298 c 2,245,-1 + 457 297 l 2,246,247 + 454 297 454 297 444 310 c 0,248,249 + 441 314 441 314 438 318 c 128,-1,250 + 435 322 435 322 432.5 325.5 c 128,-1,251 + 430 329 430 329 429 330 c 0,252,253 + 425 329 425 329 421 329 c 0,254,255 + 416 329 416 329 412 330 c 0,256,257 + 411 329 411 329 408.5 325.5 c 128,-1,258 + 406 322 406 322 403 318 c 128,-1,259 + 400 314 400 314 397 310 c 0,260,261 + 387 297 387 297 384 297 c 0,262,263 + 372 304 372 304 349 317 c 1,264,-1 + 347 319 l 1,265,266 + 347 326 347 326 362 359 c 1,267,268 + 359 363 359 363 353 373 c 1,269,270 + 311 378 311 378 311 382 c 2,271,-1 + 311 422 l 2,272,273 + 311 426 311 426 353 431 c 1,274,275 + 358 440 358 440 362 446 c 1,276,277 + 347 479 347 479 347 485 c 0,278,279 + 347 487 347 487 349 487 c 1,280,281 + 349 488 349 488 359 493 c 0,282,283 + 361 495 361 495 375 503 c 2,284,-1 + 384 507 l 2,285,286 + 387 507 387 507 397 494 c 0,287,288 + 400 490 400 490 405 483.5 c 128,-1,289 + 410 477 410 477 412 475 c 2,290,-1 + 421 475 l 1,291,-1 + 429 475 l 1,292,293 + 444 494 444 494 455 507 c 1,294,-1 + 457 507 l 2,295,296 + 460 507 460 507 493 487 c 0,297,298 + 494 486 494 486 494 485 c 0,299,300 + 494 479 494 479 479 446 c 1,301,302 + 484 440 484 440 488 431 c 1,303,304 + 530 426 530 426 530 422 c 2,228,-1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: tag +Encoding: 111 111 79 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +224 450 m 5,0,-1 + 96 450 l 5,1,-1 + 32 386 l 5,2,-1 + 32 258 l 5,3,-1 + 288 2 l 5,4,-1 + 480 194 l 5,5,-1 + 224 450 l 5,0,-1 +64 274 m 5,6,-1 + 64 370 l 5,7,-1 + 112 418 l 5,8,-1 + 208 418 l 5,9,-1 + 432 194 l 5,10,-1 + 288 50 l 5,11,-1 + 64 274 l 5,6,-1 +256 322 m 5,12,-1 + 160 226 l 5,13,-1 + 288 98 l 5,14,-1 + 384 194 l 5,15,-1 + 256 322 l 5,12,-1 +208 226 m 5,16,-1 + 256 274 l 5,17,-1 + 336 194 l 5,18,-1 + 288 146 l 5,19,-1 + 208 226 l 5,16,-1 +192 338 m 132,-1,21 + 192 358 192 358 178 372 c 132,-1,22 + 164 386 164 386 144 386 c 132,-1,23 + 124 386 124 386 110 372 c 132,-1,24 + 96 358 96 358 96 338 c 132,-1,25 + 96 318 96 318 110 304 c 132,-1,26 + 124 290 124 290 144 290 c 132,-1,27 + 164 290 164 290 178 304 c 132,-1,20 + 192 318 192 318 192 338 c 132,-1,21 +144 322 m 132,-1,29 + 128 322 128 322 128 338 c 132,-1,30 + 128 354 128 354 144 354 c 132,-1,31 + 160 354 160 354 160 338 c 132,-1,28 + 160 322 160 322 144 322 c 132,-1,29 +EndSplineSet +EndChar + +StartChar: fontawesome-webfont-15 +Encoding: 112 112 80 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +293 357 m 2,0,-1 + 293 229 l 2,1,2 + 293 225 293 225 290 222 c 128,-1,3 + 287 219 287 219 283 219 c 2,4,-1 + 192 219 l 2,5,6 + 188 219 188 219 185 222 c 0,7,8 + 183 226 183 226 183 229 c 2,9,-1 + 183 247 l 2,10,11 + 183 251 183 251 185 253 c 0,12,13 + 188 256 188 256 192 256 c 2,14,-1 + 256 256 l 1,15,-1 + 256 357 l 2,16,17 + 256 360 256 360 259 363 c 0,18,19 + 260 366 260 366 265 366 c 2,20,-1 + 283 366 l 2,21,22 + 287 366 287 366 290 363 c 128,-1,23 + 293 360 293 360 293 357 c 2,0,-1 +411 256 m 128,-1,25 + 411 297 411 297 391 334 c 0,26,27 + 370 370 370 370 334 391 c 0,28,29 + 297 411 297 411 256 411 c 128,-1,30 + 215 411 215 411 178 391 c 0,31,32 + 142 370 142 370 121 334 c 0,33,34 + 101 297 101 297 101 256 c 128,-1,35 + 101 215 101 215 121 178 c 0,36,37 + 142 142 142 142 178 121 c 0,38,39 + 215 101 215 101 256 101 c 128,-1,40 + 297 101 297 101 334 121 c 0,41,42 + 370 142 370 142 391 178 c 0,43,24 + 411 215 411 215 411 256 c 128,-1,25 +475 256 m 128,-1,45 + 475 194 475 194 446 146 c 0,46,47 + 416 96 416 96 366 66 c 0,48,49 + 318 37 318 37 256 37 c 128,-1,50 + 194 37 194 37 146 66 c 0,51,52 + 96 96 96 96 66 146 c 0,53,54 + 37 194 37 194 37 256 c 128,-1,55 + 37 318 37 318 66 366 c 0,56,57 + 96 416 96 416 146 446 c 0,58,59 + 194 475 194 475 256 475 c 128,-1,60 + 318 475 318 475 366 446 c 0,61,62 + 416 416 416 416 446 366 c 0,63,44 + 475 318 475 318 475 256 c 128,-1,45 +EndSplineSet +Validated: 513 +EndChar + +StartChar: trash-bin +Encoding: 113 113 81 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +201 302 m 2,0,-1 + 201 137 l 2,1,2 + 201 133 201 133 199 131 c 0,3,4 + 196 128 196 128 192 128 c 2,5,-1 + 174 128 l 2,6,7 + 170 128 170 128 167 131 c 0,8,9 + 165 132 165 132 165 137 c 2,10,-1 + 165 302 l 2,11,12 + 165 307 165 307 167 308 c 0,13,14 + 170 311 170 311 174 311 c 2,15,-1 + 192 311 l 2,16,17 + 196 311 196 311 199 308 c 0,18,19 + 201 306 201 306 201 302 c 2,0,-1 +274 302 m 2,20,-1 + 274 137 l 2,21,22 + 274 133 274 133 272 131 c 0,23,24 + 269 128 269 128 265 128 c 2,25,-1 + 247 128 l 2,26,27 + 243 128 243 128 240 131 c 0,28,29 + 238 133 238 133 238 137 c 2,30,-1 + 238 302 l 2,31,32 + 238 306 238 306 240 308 c 0,33,34 + 243 311 243 311 247 311 c 2,35,-1 + 265 311 l 2,36,37 + 269 311 269 311 272 308 c 0,38,39 + 274 306 274 306 274 302 c 2,20,-1 +347 302 m 2,40,-1 + 347 137 l 2,41,42 + 347 132 347 132 345 131 c 0,43,44 + 342 128 342 128 338 128 c 2,45,-1 + 320 128 l 2,46,47 + 316 128 316 128 313 131 c 0,48,49 + 311 133 311 133 311 137 c 2,50,-1 + 311 302 l 2,51,52 + 311 306 311 306 313 308 c 0,53,54 + 316 311 316 311 320 311 c 2,55,-1 + 338 311 l 2,56,57 + 342 311 342 311 345 308 c 0,58,59 + 347 307 347 307 347 302 c 2,40,-1 +384 95 m 2,60,-1 + 384 366 l 1,61,-1 + 128 366 l 1,62,-1 + 128 95 l 2,63,64 + 128 91 128 91 130 83 c 0,65,66 + 132 78 132 78 134 76 c 2,67,-1 + 137 73 l 1,68,-1 + 375 73 l 1,69,-1 + 378 76 l 2,70,71 + 380 78 380 78 382 83 c 0,72,73 + 384 91 384 91 384 95 c 2,60,-1 +192 402 m 1,74,-1 + 320 402 l 1,75,-1 + 306 436 l 2,76,77 + 305 437 305 437 301 439 c 2,78,-1 + 211 439 l 2,79,80 + 207 437 207 437 206 436 c 2,81,-1 + 192 402 l 1,74,-1 +457 393 m 2,82,-1 + 457 375 l 2,83,84 + 457 372 457 372 455 368 c 0,85,86 + 451 366 451 366 448 366 c 2,87,-1 + 421 366 l 1,88,-1 + 421 95 l 2,89,90 + 421 71 421 71 407 54 c 0,91,92 + 394 37 394 37 375 37 c 2,93,-1 + 137 37 l 2,94,95 + 118 37 118 37 105 53 c 0,96,97 + 91 70 91 70 91 94 c 2,98,-1 + 91 366 l 1,99,-1 + 64 366 l 2,100,101 + 61 366 61 366 57 368 c 0,102,103 + 55 372 55 372 55 375 c 2,104,-1 + 55 393 l 2,105,106 + 55 396 55 396 57 400 c 0,107,108 + 61 402 61 402 64 402 c 2,109,-1 + 152 402 l 1,110,-1 + 172 450 l 2,111,112 + 177 461 177 461 188 468 c 0,113,114 + 198 475 198 475 210 475 c 2,115,-1 + 302 475 l 2,116,117 + 314 475 314 475 324 468 c 0,118,119 + 335 461 335 461 340 450 c 2,120,-1 + 360 402 l 1,121,-1 + 448 402 l 2,122,123 + 451 402 451 402 455 400 c 0,124,125 + 457 396 457 396 457 393 c 2,82,-1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-17 +Encoding: 114 114 82 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +457 111 m 0,0,1 + 457 77 457 77 436 56 c 0,2,3 + 416 37 416 37 381 37 c 2,4,-1 + 131 37 l 2,5,6 + 96 37 96 37 76 56 c 0,7,8 + 55 77 55 77 55 111 c 0,9,10 + 55 131 55 131 56 140 c 0,11,12 + 58 160 58 160 60 171 c 0,13,14 + 64 193 64 193 67 202 c 0,15,16 + 70 212 70 212 80 230 c 0,17,18 + 88 244 88 244 97 253 c 0,19,20 + 107 263 107 263 122 269 c 0,21,22 + 137 274 137 274 154 274 c 0,23,24 + 156 274 156 274 166 268 c 2,25,-1 + 187 254 l 2,26,27 + 198 247 198 247 218 241 c 128,-1,28 + 238 235 238 235 256 235 c 128,-1,29 + 274 235 274 235 294 241 c 128,-1,30 + 314 247 314 247 325 254 c 2,31,-1 + 346 268 l 2,32,33 + 356 274 356 274 358 274 c 0,34,35 + 375 274 375 274 390 269 c 0,36,37 + 405 263 405 263 415 253 c 0,38,39 + 424 244 424 244 432 230 c 0,40,41 + 442 212 442 212 445 202 c 0,42,43 + 448 193 448 193 452 171 c 0,44,45 + 454 160 454 160 456 140 c 0,46,47 + 457 131 457 131 457 111 c 0,0,1 +366 366 m 0,48,49 + 366 322 366 322 334 288 c 0,50,51 + 300 256 300 256 256 256 c 128,-1,52 + 212 256 212 256 178 288 c 0,53,54 + 146 322 146 322 146 366 c 0,55,56 + 146 411 146 411 178 443 c 128,-1,57 + 210 475 210 475 256 475 c 128,-1,58 + 302 475 302 475 334 443 c 128,-1,59 + 366 411 366 411 366 366 c 0,48,49 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-18 +Encoding: 115 115 83 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +343 225 m 1,0,-1 + 431 310 l 1,1,-1 + 310 328 l 1,2,-1 + 256 437 l 1,3,-1 + 202 328 l 1,4,-1 + 81 310 l 1,5,-1 + 169 225 l 1,6,-1 + 148 105 l 1,7,-1 + 256 162 l 1,8,-1 + 364 105 l 1,9,-1 + 343 225 l 1,0,-1 +494 327 m 0,10,11 + 494 321 494 321 486 313 c 2,12,-1 + 383 212 l 1,13,-1 + 407 69 l 1,14,-1 + 407 64 l 2,15,16 + 407 49 407 49 396 49 c 0,17,18 + 392 49 392 49 384 53 c 2,19,-1 + 256 120 l 1,20,-1 + 128 53 l 2,21,22 + 120 49 120 49 116 49 c 0,23,24 + 110 49 110 49 107 54 c 0,25,26 + 104 57 104 57 104 64 c 0,27,28 + 104 67 104 67 105 69 c 2,29,-1 + 129 212 l 1,30,-1 + 25 313 l 2,31,32 + 18 324 18 324 18 327 c 0,33,34 + 18 338 18 338 34 340 c 2,35,-1 + 178 361 l 1,36,-1 + 242 491 l 2,37,38 + 248 503 248 503 256 503 c 128,-1,39 + 264 503 264 503 270 491 c 2,40,-1 + 334 361 l 1,41,-1 + 478 340 l 2,42,43 + 494 338 494 338 494 327 c 0,10,11 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-19 +Encoding: 116 116 84 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +494 327 m 0,0,1 + 494 321 494 321 486 313 c 2,2,-1 + 383 212 l 1,3,-1 + 407 69 l 1,4,-1 + 407 64 l 2,5,6 + 407 57 407 57 404 54 c 0,7,8 + 401 49 401 49 396 49 c 0,9,10 + 392 49 392 49 384 53 c 2,11,-1 + 256 120 l 1,12,-1 + 128 53 l 2,13,14 + 120 49 120 49 116 49 c 0,15,16 + 110 49 110 49 107 54 c 0,17,18 + 104 57 104 57 104 64 c 0,19,20 + 104 67 104 67 105 69 c 2,21,-1 + 129 212 l 1,22,-1 + 25 313 l 2,23,24 + 18 324 18 324 18 327 c 0,25,26 + 18 338 18 338 34 340 c 2,27,-1 + 178 361 l 1,28,-1 + 242 491 l 2,29,30 + 248 503 248 503 256 503 c 128,-1,31 + 264 503 264 503 270 491 c 2,32,-1 + 334 361 l 1,33,-1 + 478 340 l 2,34,35 + 494 338 494 338 494 327 c 0,0,1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-20 +Encoding: 117 117 85 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +402 311 m 128,-1,1 + 402 305 402 305 397 298 c 2,2,-1 + 269 170 l 2,3,4 + 264 165 264 165 256 165 c 128,-1,5 + 248 165 248 165 243 170 c 2,6,-1 + 115 298 l 2,7,8 + 110 305 110 305 110 311 c 128,-1,9 + 110 317 110 317 115 324 c 0,10,11 + 122 329 122 329 128 329 c 2,12,-1 + 384 329 l 2,13,14 + 390 329 390 329 397 324 c 0,15,0 + 402 317 402 317 402 311 c 128,-1,1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: eye-view-1 +Encoding: 118 118 86 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +0 281 m 1,0,-1 + -2 262 l 1,1,2 + 35 188 35 188 102.5 145 c 128,-1,3 + 170 102 170 102 243 96.5 c 128,-1,4 + 316 91 316 91 389 123 c 128,-1,5 + 462 155 462 155 510 222 c 1,6,-1 + 512 241 l 1,7,8 + 463 339 463 339 366 381.5 c 128,-1,9 + 269 424 269 424 166.5 397.5 c 128,-1,10 + 64 371 64 371 0 281 c 1,0,-1 +251 136 m 128,-1,12 + 203 140 203 140 171.5 176.5 c 128,-1,13 + 140 213 140 213 144 261 c 128,-1,14 + 148 309 148 309 184.5 340 c 128,-1,15 + 221 371 221 371 269 367 c 128,-1,16 + 317 363 317 363 348.5 326.5 c 128,-1,17 + 380 290 380 290 376 242 c 128,-1,18 + 372 194 372 194 335.5 163 c 128,-1,11 + 299 132 299 132 251 136 c 128,-1,12 +260 310 m 128,-1,20 + 236 310 236 310 219 293 c 128,-1,21 + 202 276 202 276 202 252 c 0,22,23 + 202 227 202 227 219 210 c 128,-1,24 + 236 193 236 193 260 193 c 128,-1,25 + 284 193 284 193 301 210 c 128,-1,26 + 318 227 318 227 318 252 c 0,27,28 + 318 276 318 276 301 293 c 128,-1,19 + 284 310 284 310 260 310 c 128,-1,20 +EndSplineSet +Validated: 553 +EndChar + +StartChar: fontawesome-webfont-21 +Encoding: 119 119 87 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +475 256 m 0,0,1 + 475 209 475 209 458 171 c 0,2,3 + 438 127 438 127 411 101 c 0,4,5 + 385 74 385 74 341 54 c 0,6,7 + 303 37 303 37 256 37 c 128,-1,8 + 209 37 209 37 171 54 c 0,9,10 + 127 74 127 74 101 101 c 0,11,12 + 74 127 74 127 54 171 c 0,13,14 + 37 209 37 209 37 256 c 0,15,16 + 37 309 37 309 60 354 c 0,17,18 + 82 400 82 400 124 431 c 0,19,20 + 137 441 137 441 152 438 c 0,21,22 + 167 436 167 436 175 424 c 0,23,24 + 185 412 185 412 182 397 c 0,25,26 + 181 382 181 382 168 373 c 0,27,28 + 139 350 139 350 125 321 c 0,29,30 + 110 291 110 291 110 256 c 0,31,32 + 110 227 110 227 121 199 c 0,33,34 + 133 171 133 171 153 153 c 0,35,36 + 171 133 171 133 199 121 c 0,37,38 + 227 110 227 110 256 110 c 128,-1,39 + 285 110 285 110 313 121 c 0,40,41 + 341 133 341 133 359 153 c 0,42,43 + 379 171 379 171 391 199 c 0,44,45 + 402 227 402 227 402 256 c 0,46,47 + 402 291 402 291 387 321 c 0,48,49 + 373 350 373 350 344 373 c 0,50,51 + 331 382 331 382 330 397 c 0,52,53 + 327 412 327 412 337 424 c 0,54,55 + 345 437 345 437 361 438 c 0,56,57 + 375 441 375 441 388 431 c 0,58,59 + 430 400 430 400 452 354 c 0,60,61 + 475 309 475 309 475 256 c 0,0,1 +293 475 m 2,62,-1 + 293 293 l 2,63,64 + 293 278 293 278 282 267 c 0,65,66 + 269 256 269 256 256 256 c 128,-1,67 + 243 256 243 256 230 267 c 0,68,69 + 219 278 219 278 219 293 c 2,70,-1 + 219 475 l 2,71,72 + 219 490 219 490 230 501 c 0,73,74 + 243 512 243 512 256 512 c 128,-1,75 + 269 512 269 512 282 501 c 0,76,77 + 293 490 293 490 293 475 c 2,62,-1 +EndSplineSet +Validated: 545 +EndChar + +StartChar: fontawesome-webfont-22 +Encoding: 120 120 88 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +384 128 m 128,-1,1 + 384 134 384 134 379 141 c 0,2,3 + 372 146 372 146 366 146 c 0,4,5 + 358 146 358 146 353 141 c 0,6,7 + 347 135 347 135 347 128 c 128,-1,8 + 347 121 347 121 353 115 c 0,9,10 + 358 110 358 110 366 110 c 0,11,12 + 372 110 372 110 379 115 c 0,13,0 + 384 122 384 122 384 128 c 128,-1,1 +457 128 m 128,-1,15 + 457 134 457 134 452 141 c 0,16,17 + 445 146 445 146 439 146 c 128,-1,18 + 433 146 433 146 426 141 c 0,19,20 + 421 136 421 136 421 128 c 128,-1,21 + 421 120 421 120 426 115 c 0,22,23 + 433 110 433 110 439 110 c 128,-1,24 + 445 110 445 110 452 115 c 0,25,14 + 457 122 457 122 457 128 c 128,-1,15 +494 192 m 2,26,-1 + 494 101 l 2,27,28 + 494 89 494 89 486 81 c 0,29,30 + 476 73 476 73 466 73 c 2,31,-1 + 46 73 l 2,32,33 + 36 73 36 73 26 81 c 0,34,35 + 18 89 18 89 18 101 c 2,36,-1 + 18 192 l 2,37,38 + 18 203 18 203 26 211 c 128,-1,39 + 34 219 34 219 46 219 c 2,40,-1 + 179 219 l 1,41,-1 + 217 181 l 2,42,43 + 233 165 233 165 256 165 c 128,-1,44 + 279 165 279 165 295 181 c 2,45,-1 + 334 219 l 1,46,-1 + 466 219 l 2,47,48 + 478 219 478 219 486 211 c 128,-1,49 + 494 203 494 203 494 192 c 2,26,-1 +401 355 m 0,50,51 + 406 342 406 342 397 335 c 2,52,-1 + 269 207 l 2,53,54 + 263 201 263 201 256 201 c 128,-1,55 + 249 201 249 201 243 207 c 2,56,-1 + 115 335 l 2,57,58 + 106 342 106 342 111 355 c 0,59,60 + 116 366 116 366 128 366 c 2,61,-1 + 201 366 l 1,62,-1 + 201 494 l 2,63,64 + 201 501 201 501 207 507 c 0,65,66 + 212 512 212 512 219 512 c 2,67,-1 + 293 512 l 2,68,69 + 300 512 300 512 305 507 c 0,70,71 + 311 501 311 501 311 494 c 2,72,-1 + 311 366 l 1,73,-1 + 384 366 l 2,74,75 + 396 366 396 366 401 355 c 0,50,51 +EndSplineSet +Validated: 545 +EndChar + +StartChar: search-find +Encoding: 121 121 89 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +347 274 m 0,0,1 + 347 328 347 328 310 365 c 128,-1,2 + 273 402 273 402 219 402 c 0,3,4 + 166 402 166 402 129 365 c 0,5,6 + 91 327 91 327 91 274 c 0,7,8 + 91 222 91 222 129 184 c 128,-1,9 + 167 146 167 146 219 146 c 0,10,11 + 272 146 272 146 310 184 c 0,12,13 + 347 221 347 221 347 274 c 0,0,1 +494 37 m 0,14,15 + 494 22 494 22 483 11 c 128,-1,16 + 472 0 472 0 457 0 c 128,-1,17 + 442 0 442 0 431 11 c 2,18,-1 + 333 109 l 1,19,20 + 282 73 282 73 219 73 c 0,21,22 + 177 73 177 73 141 89 c 0,23,24 + 104 105 104 105 77 132 c 0,25,26 + 50 158 50 158 34 196 c 0,27,28 + 18 236 18 236 18 274 c 0,29,30 + 18 314 18 314 34 352 c 0,31,32 + 51 391 51 391 77 417 c 128,-1,33 + 103 443 103 443 141 460 c 0,34,35 + 178 475 178 475 219 475 c 256,36,37 + 260 475 260 475 298 460 c 0,38,39 + 337 442 337 442 362 417 c 0,40,41 + 388 391 388 391 405 352 c 0,42,43 + 421 314 421 314 421 274 c 0,44,45 + 421 211 421 211 385 160 c 1,46,-1 + 483 62 l 2,47,48 + 494 51 494 51 494 37 c 0,14,15 +EndSplineSet +Validated: 513 +EndChar + +StartChar: fontawesome-webfont-23 +Encoding: 122 122 90 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +512 329 m 128,-1,1 + 512 323 512 323 507 316 c 2,2,-1 + 360 170 l 2,3,4 + 356 165 356 165 347 165 c 0,5,6 + 339 165 339 165 335 170 c 0,7,8 + 329 176 329 176 329 183 c 2,9,-1 + 329 256 l 1,10,-1 + 265 256 l 2,11,12 + 245 256 245 256 215 254 c 0,13,14 + 194 253 194 253 171 248 c 0,15,16 + 150 244 150 244 133 236 c 0,17,18 + 118 229 118 229 103 216 c 0,19,20 + 89 204 89 204 80 187 c 0,21,22 + 70 169 70 169 66 148 c 0,23,24 + 61 121 61 121 61 96 c 0,25,26 + 61 87 61 87 63 61 c 2,27,-1 + 63 54 l 2,28,29 + 64 51 64 51 64 47 c 128,-1,30 + 64 43 64 43 62 39 c 0,31,32 + 58 37 58 37 55 37 c 0,33,34 + 50 37 50 37 47 41 c 2,35,-1 + 46 44 l 2,36,37 + 44 46 44 46 43 48 c 2,38,-1 + 39 56 l 2,39,40 + 38 61 38 61 36 63 c 0,41,42 + 0 144 0 144 0 192 c 0,43,44 + 0 250 0 250 15 287 c 0,45,46 + 61 402 61 402 265 402 c 2,47,-1 + 329 402 l 1,48,-1 + 329 475 l 2,49,50 + 329 484 329 484 335 488 c 0,51,52 + 340 494 340 494 347 494 c 0,53,54 + 356 494 356 494 360 488 c 2,55,-1 + 507 342 l 2,56,0 + 512 335 512 335 512 329 c 128,-1,1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: pointer +Encoding: 123 123 91 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +459 214 m 2,0,1 + 467 206 467 206 463 194 c 0,2,3 + 458 183 458 183 446 183 c 2,4,-1 + 337 183 l 1,5,-1 + 394 47 l 2,6,7 + 397 39 397 39 394 33 c 0,8,9 + 391 26 391 26 385 23 c 2,10,-1 + 334 1 l 2,11,12 + 327 0 327 0 320 1 c 0,13,14 + 314 4 314 4 310 11 c 2,15,-1 + 255 140 l 1,16,-1 + 166 51 l 2,17,18 + 161 46 161 46 153 46 c 0,19,20 + 149 46 149 46 147 47 c 0,21,22 + 135 51 135 51 135 64 c 2,23,-1 + 135 494 l 2,24,25 + 135 505 135 505 147 511 c 0,26,27 + 149 512 149 512 153 512 c 0,28,29 + 161 512 161 512 166 507 c 2,30,-1 + 459 214 l 2,0,1 +EndSplineSet +Validated: 33 +EndChar + +StartChar: color-palette +Encoding: 125 125 92 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +288 480 m 0,0,1 + 220 480 220 480 163 448.5 c 128,-1,2 + 106 417 106 417 71.5 368 c 128,-1,3 + 37 319 37 319 18.5 264.5 c 128,-1,4 + 0 210 0 210 0 160 c 0,5,6 + 0 150 0 150 7 138 c 128,-1,7 + 14 126 14 126 25 118.5 c 128,-1,8 + 36 111 36 111 48.5 109.5 c 128,-1,9 + 61 108 61 108 74 120.5 c 128,-1,10 + 87 133 87 133 96 160 c 0,11,12 + 103 181 103 181 126.5 185.5 c 128,-1,13 + 150 190 150 190 171 174 c 128,-1,14 + 192 158 192 158 192 128 c 0,15,16 + 192 72 192 72 217 36 c 128,-1,17 + 242 0 242 0 288 0 c 0,18,19 + 343 0 343 0 385 18 c 128,-1,20 + 427 36 427 36 450.5 62.5 c 128,-1,21 + 474 89 474 89 488.5 125 c 128,-1,22 + 503 161 503 161 507.5 192 c 128,-1,23 + 512 223 512 223 512 256 c 0,24,25 + 512 480 512 480 288 480 c 0,0,1 +128 248 m 128,-1,27 + 112 248 112 248 100 260 c 128,-1,28 + 88 272 88 272 88 288 c 128,-1,29 + 88 304 88 304 100 316 c 128,-1,30 + 112 328 112 328 128 328 c 128,-1,31 + 144 328 144 328 156 316 c 128,-1,32 + 168 304 168 304 168 288 c 128,-1,33 + 168 272 168 272 156 260 c 128,-1,26 + 144 248 144 248 128 248 c 128,-1,27 +200 368 m 128,-1,35 + 200 384 200 384 212 396 c 128,-1,36 + 224 408 224 408 240 408 c 128,-1,37 + 256 408 256 408 268 396 c 128,-1,38 + 280 384 280 384 280 368 c 128,-1,39 + 280 352 280 352 268 340 c 128,-1,40 + 256 328 256 328 240 328 c 128,-1,41 + 224 328 224 328 212 340 c 128,-1,34 + 200 352 200 352 200 368 c 128,-1,35 +304 88 m 128,-1,43 + 281 88 281 88 264.5 104.5 c 128,-1,44 + 248 121 248 121 248 144 c 128,-1,45 + 248 167 248 167 264.5 183.5 c 128,-1,46 + 281 200 281 200 304 200 c 128,-1,47 + 327 200 327 200 343.5 183.5 c 128,-1,48 + 360 167 360 167 360 144 c 128,-1,49 + 360 121 360 121 343.5 104.5 c 128,-1,42 + 327 88 327 88 304 88 c 128,-1,43 +400 184 m 128,-1,51 + 390 184 390 184 383 191 c 128,-1,52 + 376 198 376 198 376 208 c 128,-1,53 + 376 218 376 218 383 225 c 128,-1,54 + 390 232 390 232 400 232 c 128,-1,55 + 410 232 410 232 417 225 c 128,-1,56 + 424 218 424 218 424 208 c 128,-1,57 + 424 198 424 198 417 191 c 128,-1,50 + 410 184 410 184 400 184 c 128,-1,51 +368 280 m 128,-1,59 + 345 280 345 280 328.5 296.5 c 128,-1,60 + 312 313 312 313 312 336 c 128,-1,61 + 312 359 312 359 328.5 375.5 c 128,-1,62 + 345 392 345 392 368 392 c 128,-1,63 + 391 392 391 392 407.5 375.5 c 128,-1,64 + 424 359 424 359 424 336 c 128,-1,65 + 424 313 424 313 407.5 296.5 c 128,-1,58 + 391 280 391 280 368 280 c 128,-1,59 +EndSplineSet +Validated: 553 +EndChar + +StartChar: hookah +Encoding: 126 126 93 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +475 288 m 2,0,-1 + 433 330 l 2,1,2 + 429 334 429 334 424 332 c 0,3,4 + 420 332 420 332 418 326 c 2,5,-1 + 410 292 l 2,6,7 + 408 288 408 288 412 284 c 2,8,-1 + 415 282 l 1,9,-1 + 405 272 l 1,10,-1 + 399 279 l 2,11,12 + 392 284 392 284 387 279 c 0,13,14 + 379 273 379 273 387 267 c 2,15,-1 + 393 260 l 1,16,-1 + 362 229 l 2,17,18 + 362 230 362 230 360 230 c 0,19,20 + 340 249 340 249 280 269 c 0,21,22 + 277 269 277 269 273 271 c 1,23,-1 + 273 461 l 1,24,-1 + 282 461 l 2,25,26 + 290 461 290 461 290 469 c 2,27,-1 + 290 503 l 2,28,29 + 290 512 290 512 282 512 c 2,30,-1 + 162 512 l 2,31,32 + 154 512 154 512 154 503 c 2,33,-1 + 154 469 l 2,34,35 + 154 461 154 461 162 461 c 2,36,-1 + 171 461 l 1,37,-1 + 171 271 l 1,38,39 + 165 269 165 269 164 269 c 0,40,41 + 105 250 105 250 84 230 c 1,42,43 + 77 230 77 230 77 222 c 1,44,45 + 60 202 60 202 60 171 c 0,46,47 + 60 148 60 148 68.5 130.5 c 128,-1,48 + 77 113 77 113 95 102 c 128,-1,49 + 113 91 113 91 127 85.5 c 128,-1,50 + 141 80 141 80 164 73 c 0,51,52 + 168 71 168 71 171 71 c 2,53,-1 + 171 56 l 1,54,-1 + 115 15 l 2,55,56 + 109 11 109 11 111 6 c 0,57,58 + 114 0 114 0 120 0 c 2,59,-1 + 324 0 l 2,60,61 + 333 0 333 0 333 9 c 0,62,63 + 333 14 333 14 328 16 c 2,64,-1 + 273 56 l 1,65,-1 + 273 71 l 2,66,67 + 276 71 276 71 280 73 c 0,68,69 + 304 80 304 80 317 85.5 c 128,-1,70 + 330 91 330 91 348.5 102 c 128,-1,71 + 367 113 367 113 375.5 130.5 c 128,-1,72 + 384 148 384 148 384 171 c 0,73,74 + 384 197 384 197 372 215 c 1,75,-1 + 405 248 l 1,76,-1 + 412 241 l 2,77,78 + 416 239 416 239 418 239 c 0,79,80 + 422 239 422 239 424 241 c 0,81,82 + 431 248 431 248 424 253 c 2,83,-1 + 417 260 l 1,84,-1 + 427 270 l 1,85,-1 + 429 267 l 2,86,87 + 431 265 431 265 435 265 c 2,88,-1 + 437 265 l 1,89,-1 + 471 273 l 2,90,91 + 477 275 477 275 478 279 c 0,92,93 + 478 285 478 285 475 288 c 2,0,-1 +171 495 m 1,94,-1 + 273 495 l 1,95,-1 + 273 478 l 1,96,-1 + 171 478 l 1,97,-1 + 171 495 l 1,94,-1 +169 252 m 0,98,99 + 172 254 172 254 182 256 c 0,100,101 + 188 260 188 260 188 265 c 2,102,-1 + 188 461 l 1,103,-1 + 256 461 l 1,104,-1 + 256 265 l 2,105,106 + 256 259 256 259 262 256 c 0,107,108 + 272 254 272 254 275 252 c 0,109,110 + 315 240 315 240 331 230 c 1,111,-1 + 113 230 l 1,112,113 + 131 241 131 241 169 252 c 0,98,99 +146 17 m 1,114,-1 + 182 43 l 1,115,-1 + 262 43 l 1,116,-1 + 298 17 l 1,117,-1 + 146 17 l 1,114,-1 +367 171 m 0,118,119 + 367 146 367 146 352 129 c 128,-1,120 + 337 112 337 112 321.5 105.5 c 128,-1,121 + 306 99 306 99 275 89 c 0,122,123 + 273 88 273 88 268.5 87 c 128,-1,124 + 264 86 264 86 262 85 c 0,125,126 + 256 84 256 84 256 77 c 2,127,-1 + 256 60 l 1,128,-1 + 188 60 l 1,129,-1 + 188 77 l 2,130,131 + 188 83 188 83 182 85 c 0,132,133 + 180 86 180 86 175.5 87 c 128,-1,134 + 171 88 171 88 169 89 c 0,135,136 + 138 99 138 99 122.5 105.5 c 128,-1,137 + 107 112 107 112 92 129 c 128,-1,138 + 77 146 77 146 77 171 c 0,139,140 + 77 197 77 197 91 213 c 1,141,-1 + 346 213 l 1,142,-1 + 241 108 l 2,143,144 + 236 103 236 103 241 96 c 0,145,146 + 245 94 245 94 248 94 c 0,147,148 + 250 94 250 94 254 96 c 2,149,-1 + 360 203 l 1,150,151 + 367 187 367 187 367 171 c 0,118,119 +438 283 m 1,152,-1 + 428 293 l 1,153,-1 + 431 308 l 1,154,-1 + 453 286 l 1,155,-1 + 438 283 l 1,152,-1 +EndSplineSet +Validated: 9 +EndChar + +StartChar: tools +Encoding: 57344 57344 94 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +79 336 m 0,0,1 + 78 335 78 335 73 325 c 0,2,3 + 72 320 72 320 72 312 c 0,4,5 + 72 306 72 306 71 306 c 2,6,-1 + 70 305 l 2,7,8 + 68 304 68 304 66 302 c 128,-1,9 + 64 300 64 300 62 298 c 0,10,11 + 57 294 57 294 53 290 c 0,12,13 + 44 283 44 283 38 292 c 2,14,-1 + 2 331 l 2,15,16 + -3 337 -3 337 3 343 c 0,17,18 + 4 344 4 344 13 350 c 2,19,-1 + 23 358 l 2,20,21 + 26 361 26 361 37 361 c 0,22,23 + 46 361 46 361 56 369 c 0,24,25 + 62 375 62 375 65 388 c 0,26,27 + 66 399 66 399 70 403 c 2,28,-1 + 72 404 l 2,29,30 + 73 406 73 406 75 407 c 0,31,32 + 81 413 81 413 88 418 c 0,33,34 + 102 430 102 430 109 434 c 0,35,36 + 177 480 177 480 204 483 c 0,37,38 + 271 483 271 483 280 482 c 0,39,40 + 285 482 285 482 276 478 c 0,41,42 + 214 451 214 451 198 439 c 0,43,44 + 157 410 157 410 179 381 c 0,45,46 + 194 361 194 361 199 356 c 0,47,48 + 204 353 204 353 198 349 c 2,49,-1 + 196 347 l 2,50,51 + 193 345 193 345 188.5 340.5 c 128,-1,52 + 184 336 184 336 178 331 c 0,53,54 + 166 320 166 320 159 313 c 0,55,56 + 151 310 151 310 150 311 c 0,57,58 + 128 336 128 336 113 342 c 0,59,60 + 99 348 99 348 79 336 c 0,0,1 +226 323 m 2,61,-1 + 435 79 l 2,62,63 + 445 68 445 68 434 59 c 2,64,-1 + 410 38 l 2,65,66 + 399 31 399 31 390 40 c 2,67,-1 + 178 282 l 2,68,69 + 175 285 175 285 178 292 c 2,70,-1 + 215 324 l 2,71,72 + 222 327 222 327 226 323 c 2,61,-1 +509 426 m 0,73,74 + 518 373 518 373 501 341 c 0,75,76 + 475 296 475 296 422 309 c 0,77,78 + 393 315 393 315 371 293 c 2,79,-1 + 329 253 l 1,80,-1 + 294 293 l 1,81,-1 + 329 329 l 2,82,83 + 340 340 340 340 345 356 c 0,84,85 + 348 371 348 371 348 389 c 0,86,87 + 348 411 348 411 350 419 c 0,88,89 + 358 448 358 448 422 476 c 0,90,91 + 428 479 428 479 431 475 c 0,92,93 + 435 470 435 470 432 467 c 0,94,95 + 426 460 426 460 409 426 c 1,96,97 + 402 422 402 422 403 408 c 0,98,99 + 403 395 403 395 423 381 c 0,100,101 + 452 360 452 360 472 392 c 0,102,103 + 474 395 474 395 486 413 c 0,104,105 + 495 428 495 428 497 430 c 0,106,107 + 499 435 499 435 504 435 c 0,108,109 + 509 433 509 433 509 426 c 0,73,74 +70 76 m 2,110,-1 + 200 203 l 1,111,-1 + 239 159 l 1,112,-1 + 113 35 l 2,113,114 + 103 25 103 25 93 33 c 2,115,-1 + 70 56 l 2,116,117 + 58 65 58 65 70 76 c 2,110,-1 +EndSplineSet +Validated: 33 +EndChar + +StartChar: bullseye +Encoding: 57345 57345 95 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +329 256 m 128,-1,1 + 329 226 329 226 308 204 c 0,2,3 + 286 183 286 183 256 183 c 128,-1,4 + 226 183 226 183 204 204 c 0,5,6 + 183 226 183 226 183 256 c 128,-1,7 + 183 286 183 286 204 308 c 0,8,9 + 226 329 226 329 256 329 c 128,-1,10 + 286 329 286 329 308 308 c 0,11,0 + 329 286 329 286 329 256 c 128,-1,1 +366 256 m 128,-1,13 + 366 300 366 300 334 334 c 0,14,15 + 300 366 300 366 256 366 c 128,-1,16 + 212 366 212 366 178 334 c 0,17,18 + 146 300 146 300 146 256 c 128,-1,19 + 146 212 146 212 178 178 c 0,20,21 + 212 146 212 146 256 146 c 128,-1,22 + 300 146 300 146 334 178 c 0,23,12 + 366 212 366 212 366 256 c 128,-1,13 +402 256 m 128,-1,25 + 402 195 402 195 359 153 c 0,26,27 + 317 110 317 110 256 110 c 128,-1,28 + 195 110 195 110 153 153 c 0,29,30 + 110 195 110 195 110 256 c 128,-1,31 + 110 317 110 317 153 359 c 0,32,33 + 195 402 195 402 256 402 c 128,-1,34 + 317 402 317 402 359 359 c 0,35,24 + 402 317 402 317 402 256 c 128,-1,25 +439 256 m 0,36,37 + 439 292 439 292 424 327 c 0,38,39 + 411 361 411 361 385 385 c 0,40,41 + 361 411 361 411 327 424 c 0,42,43 + 292 439 292 439 256 439 c 128,-1,44 + 220 439 220 439 185 424 c 0,45,46 + 151 411 151 411 127 385 c 0,47,48 + 101 361 101 361 88 327 c 0,49,50 + 73 292 73 292 73 256 c 128,-1,51 + 73 220 73 220 88 185 c 0,52,53 + 101 151 101 151 127 127 c 0,54,55 + 151 101 151 101 185 88 c 0,56,57 + 220 73 220 73 256 73 c 128,-1,58 + 292 73 292 73 327 88 c 0,59,60 + 361 101 361 101 385 127 c 0,61,62 + 411 151 411 151 424 185 c 0,63,64 + 439 219 439 219 439 256 c 0,36,37 +475 256 m 128,-1,66 + 475 194 475 194 446 146 c 0,67,68 + 416 96 416 96 366 66 c 0,69,70 + 318 37 318 37 256 37 c 128,-1,71 + 194 37 194 37 146 66 c 0,72,73 + 96 96 96 96 66 146 c 0,74,75 + 37 194 37 194 37 256 c 128,-1,76 + 37 318 37 318 66 366 c 0,77,78 + 96 416 96 416 146 446 c 0,79,80 + 194 475 194 475 256 475 c 128,-1,81 + 318 475 318 475 366 446 c 0,82,83 + 416 416 416 416 446 366 c 0,84,65 + 475 318 475 318 475 256 c 128,-1,66 +EndSplineSet +Validated: 1 +EndChar + +StartChar: agent +Encoding: 57346 57346 96 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +384 64 m 128,-1,1 + 384 90 384 90 403 109 c 128,-1,2 + 422 128 422 128 448 128 c 128,-1,3 + 474 128 474 128 493 109 c 128,-1,4 + 512 90 512 90 512 64 c 128,-1,5 + 512 38 512 38 493 19 c 128,-1,6 + 474 0 474 0 448 0 c 128,-1,7 + 422 0 422 0 403 19 c 128,-1,0 + 384 38 384 38 384 64 c 128,-1,1 +416 64 m 128,-1,9 + 416 50 416 50 425 41 c 128,-1,10 + 434 32 434 32 448 32 c 128,-1,11 + 462 32 462 32 471 41 c 128,-1,12 + 480 50 480 50 480 64 c 128,-1,13 + 480 78 480 78 471 87 c 128,-1,14 + 462 96 462 96 448 96 c 128,-1,15 + 434 96 434 96 425 87 c 128,-1,8 + 416 78 416 78 416 64 c 128,-1,9 +0 448 m 128,-1,17 + 0 474 0 474 19 493 c 128,-1,18 + 38 512 38 512 64 512 c 128,-1,19 + 90 512 90 512 109 493 c 128,-1,20 + 128 474 128 474 128 448 c 128,-1,21 + 128 422 128 422 109 403 c 128,-1,22 + 90 384 90 384 64 384 c 128,-1,23 + 38 384 38 384 19 403 c 128,-1,16 + 0 422 0 422 0 448 c 128,-1,17 +32 448 m 128,-1,25 + 32 434 32 434 41 425 c 128,-1,26 + 50 416 50 416 64 416 c 128,-1,27 + 78 416 78 416 87 425 c 128,-1,28 + 96 434 96 434 96 448 c 128,-1,29 + 96 462 96 462 87 471 c 128,-1,30 + 78 480 78 480 64 480 c 128,-1,31 + 50 480 50 480 41 471 c 128,-1,24 + 32 462 32 462 32 448 c 128,-1,25 +448 384 m 0,32,33 + 474 384 474 384 493 403 c 128,-1,34 + 512 422 512 422 512 448 c 128,-1,35 + 512 474 512 474 493 493 c 128,-1,36 + 474 512 474 512 448 512 c 128,-1,37 + 422 512 422 512 403 493 c 128,-1,38 + 384 474 384 474 384 448 c 0,39,40 + 384 430 384 430 393 416 c 1,41,-1 + 342 364 l 1,42,43 + 299 384 299 384 256 384 c 0,44,45 + 215 384 215 384 177 368.5 c 128,-1,46 + 139 353 139 353 111 327.5 c 128,-1,47 + 83 302 83 302 72 290.5 c 128,-1,48 + 61 279 61 279 52 267 c 2,49,-1 + 51 266 l 1,50,-1 + 44 257 l 1,51,-1 + 51 247 l 1,52,-1 + 55 242 l 2,53,54 + 59 237 59 237 67 228 c 128,-1,55 + 75 219 75 219 85 208.5 c 128,-1,56 + 95 198 95 198 110 186 c 128,-1,57 + 125 174 125 174 141 164 c 1,58,-1 + 96 119 l 1,59,60 + 82 128 82 128 64 128 c 0,61,62 + 38 128 38 128 19 109 c 128,-1,63 + 0 90 0 90 0 64 c 128,-1,64 + 0 38 0 38 19 19 c 128,-1,65 + 38 0 38 0 64 0 c 128,-1,66 + 90 0 90 0 109 19 c 128,-1,67 + 128 38 128 38 128 64 c 0,68,69 + 128 82 128 82 119 96 c 1,70,-1 + 171 148 l 1,71,72 + 213 128 213 128 256 128 c 0,73,74 + 374 129 374 129 460 246 c 1,75,-1 + 461 247 l 1,76,-1 + 468 256 l 1,77,-1 + 461 265 l 1,78,-1 + 460 267 l 2,79,80 + 458 269 458 269 455.5 272 c 128,-1,81 + 453 275 453 275 449.5 279.5 c 128,-1,82 + 446 284 446 284 441.5 289 c 128,-1,83 + 437 294 437 294 431.5 299.5 c 128,-1,84 + 426 305 426 305 419 311.5 c 128,-1,85 + 412 318 412 318 405 324 c 128,-1,86 + 398 330 398 330 389 336.5 c 128,-1,87 + 380 343 380 343 371 348 c 1,88,-1 + 416 393 l 1,89,90 + 429 384 429 384 448 384 c 0,32,33 +422 263 m 0,91,92 + 424 260 424 260 428 256 c 1,93,94 + 424 252 424 252 422 249 c 0,95,96 + 341 159 341 159 256 160 c 0,97,98 + 193 160 193 160 128 213 c 0,99,100 + 111 227 111 227 90 250 c 0,101,102 + 89 251 89 251 87 253.5 c 128,-1,103 + 85 256 85 256 84 257 c 2,104,-1 + 90 263 l 1,105,106 + 169 353 169 353 256 352 c 0,107,108 + 318 352 318 352 384 300 c 0,109,110 + 406 281 406 281 422 263 c 0,91,92 +320 256 m 128,-1,112 + 320 230 320 230 301 211 c 128,-1,113 + 282 192 282 192 256 192 c 128,-1,114 + 230 192 230 192 211 211 c 128,-1,115 + 192 230 192 230 192 256 c 128,-1,116 + 192 282 192 282 211 301 c 128,-1,117 + 230 320 230 320 256 320 c 128,-1,118 + 282 320 282 320 301 301 c 128,-1,111 + 320 282 320 282 320 256 c 128,-1,112 +EndSplineSet +Validated: 41 +EndChar + +StartChar: mic +Encoding: 57347 57347 97 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +244 476 m 1,0,1 + 226 474 226 474 211 469 c 1,2,-1 + 211 411 l 1,3,-1 + 187 411 l 1,4,-1 + 187 460 l 1,5,6 + 174 454 174 454 157 441 c 1,7,-1 + 157 440 l 1,8,-1 + 157 200 l 1,9,10 + 199 164 199 164 256 164 c 128,-1,11 + 313 164 313 164 355 200 c 1,12,-1 + 355 440 l 1,13,-1 + 355 441 l 1,14,15 + 344 450 344 450 325 460 c 1,16,-1 + 325 411 l 1,17,-1 + 301 411 l 1,18,-1 + 301 469 l 1,19,20 + 286 474 286 474 268 476 c 1,21,-1 + 268 411 l 1,22,-1 + 244 411 l 1,23,-1 + 244 476 l 1,0,1 +110 283 m 1,24,-1 + 110 160 l 1,25,26 + 118 152 118 152 138 138 c 0,27,28 + 174 114 174 114 216 107 c 1,29,-1 + 216 121 l 1,30,-1 + 296 121 l 1,31,-1 + 296 107 l 1,32,33 + 337 114 337 114 374 138 c 0,34,35 + 394 152 394 152 402 160 c 1,36,-1 + 402 283 l 1,37,-1 + 374 283 l 1,38,-1 + 374 174 l 1,39,40 + 322 132 322 132 256 132 c 128,-1,41 + 190 132 190 132 138 174 c 1,42,-1 + 138 283 l 1,43,-1 + 110 283 l 1,24,-1 +296 107 m 1,44,45 + 279 103 279 103 256 103 c 128,-1,46 + 233 103 233 103 216 107 c 1,47,-1 + 216 66 l 1,48,-1 + 168 66 l 1,49,-1 + 168 36 l 1,50,-1 + 344 36 l 1,51,-1 + 344 66 l 1,52,-1 + 296 66 l 1,53,-1 + 296 107 l 1,44,45 +EndSplineSet +Validated: 5 +EndChar + +StartChar: bar-chart +Encoding: 57348 57348 98 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +137 222 m 1,0,-1 + 137 119 l 1,1,-1 + 68 119 l 1,2,-1 + 68 222 l 1,3,-1 + 137 222 l 1,0,-1 +239 358 m 1,4,-1 + 239 119 l 1,5,-1 + 171 119 l 1,6,-1 + 171 358 l 1,7,-1 + 239 358 l 1,4,-1 +341 290 m 1,8,-1 + 341 119 l 1,9,-1 + 273 119 l 1,10,-1 + 273 290 l 1,11,-1 + 341 290 l 1,8,-1 +444 393 m 1,12,-1 + 444 119 l 1,13,-1 + 375 119 l 1,14,-1 + 375 393 l 1,15,-1 + 444 393 l 1,12,-1 +478 94 m 2,16,-1 + 478 418 l 2,17,18 + 478 421 478 421 475 424 c 0,19,20 + 474 427 474 427 469 427 c 2,21,-1 + 43 427 l 2,22,23 + 38 427 38 427 37 424 c 0,24,25 + 34 421 34 421 34 418 c 2,26,-1 + 34 94 l 2,27,28 + 34 91 34 91 37 88 c 0,29,30 + 38 85 38 85 43 85 c 2,31,-1 + 469 85 l 2,32,33 + 474 85 474 85 475 88 c 0,34,35 + 478 91 478 91 478 94 c 2,16,-1 +512 418 m 2,36,-1 + 512 94 l 2,37,38 + 512 76 512 76 499 64 c 0,39,40 + 487 51 487 51 469 51 c 2,41,-1 + 43 51 l 2,42,43 + 25 51 25 51 13 64 c 0,44,45 + 0 76 0 76 0 94 c 2,46,-1 + 0 418 l 2,47,48 + 0 436 0 436 13 448 c 0,49,50 + 25 461 25 461 43 461 c 2,51,-1 + 469 461 l 2,52,53 + 487 461 487 461 499 448 c 0,54,55 + 512 436 512 436 512 418 c 2,36,-1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: info-circled +Encoding: 57349 57349 99 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +253 492 m 0,0,1 + 350 492 350 492 420 425 c 0,2,3 + 489 358 489 358 492 260 c 0,4,5 + 492 161 492 161 424 93 c 0,6,7 + 357 23 357 23 259 20 c 0,8,9 + 160 20 160 20 92 88 c 0,10,11 + 22 156 22 156 20 253 c 0,12,13 + 18 351 18 351 87 420 c 0,14,15 + 156 491 156 491 253 492 c 0,0,1 +280 414 m 0,16,17 + 258 414 258 414 246 401 c 0,18,19 + 234 389 234 389 234 376 c 0,20,21 + 234 361 234 361 242 353 c 0,22,23 + 252 345 252 345 267 345 c 0,24,25 + 287 345 287 345 298 356 c 0,26,27 + 310 368 310 368 310 384 c 0,28,29 + 310 414 310 414 280 414 c 0,16,17 +218 110 m 0,30,31 + 235 110 235 110 261 123 c 0,32,33 + 290 137 290 137 315 163 c 1,34,-1 + 306 175 l 1,35,36 + 282 157 282 157 269 157 c 0,37,38 + 263 157 263 157 267 176 c 2,39,-1 + 289 258 l 2,40,41 + 302 307 302 307 278 307 c 0,42,43 + 262 307 262 307 232 292 c 0,44,45 + 198 275 198 275 173 254 c 1,46,-1 + 181 241 l 1,47,48 + 209 258 209 258 219 258 c 0,49,50 + 225 258 225 258 219 241 c 2,51,-1 + 201 163 l 2,52,53 + 188 110 188 110 218 110 c 0,30,31 +EndSplineSet +Validated: 545 +EndChar + +StartChar: screen-desktop +Encoding: 57350 57350 100 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +478 230 m 2,0,-1 + 478 452 l 2,1,2 + 478 456 478 456 475 458 c 0,3,4 + 474 461 474 461 469 461 c 2,5,-1 + 43 461 l 2,6,7 + 38 461 38 461 37 458 c 0,8,9 + 34 456 34 456 34 452 c 2,10,-1 + 34 230 l 2,11,12 + 34 227 34 227 37 224 c 0,13,14 + 39 222 39 222 43 222 c 2,15,-1 + 469 222 l 2,16,17 + 473 222 473 222 475 224 c 0,18,19 + 478 227 478 227 478 230 c 2,0,-1 +512 452 m 2,20,-1 + 512 162 l 2,21,22 + 512 144 512 144 499 132 c 0,23,24 + 486 119 486 119 469 119 c 2,25,-1 + 324 119 l 1,26,27 + 324 111 324 111 329 99 c 0,28,29 + 332 88 332 88 337 80 c 0,30,31 + 341 72 341 72 341 68 c 0,32,33 + 341 61 341 61 336 56 c 128,-1,34 + 331 51 331 51 324 51 c 2,35,-1 + 188 51 l 2,36,37 + 181 51 181 51 176 56 c 128,-1,38 + 171 61 171 61 171 68 c 0,39,40 + 171 73 171 73 175 80 c 0,41,42 + 180 88 180 88 183 99 c 0,43,44 + 188 111 188 111 188 119 c 1,45,-1 + 43 119 l 2,46,47 + 26 119 26 119 13 132 c 0,48,49 + 0 144 0 144 0 162 c 2,50,-1 + 0 452 l 2,51,52 + 0 470 0 470 13 482 c 0,53,54 + 25 495 25 495 43 495 c 2,55,-1 + 469 495 l 2,56,57 + 487 495 487 495 499 482 c 0,58,59 + 512 470 512 470 512 452 c 2,20,-1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: phone-mobile +Encoding: 57351 57351 101 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +279 110 m 0,0,1 + 279 119 279 119 272 126 c 128,-1,2 + 265 133 265 133 256 133 c 128,-1,3 + 247 133 247 133 240 126 c 128,-1,4 + 233 119 233 119 233 110 c 0,5,6 + 233 100 233 100 240 94 c 0,7,8 + 246 87 246 87 256 87 c 128,-1,9 + 266 87 266 87 272 94 c 0,10,11 + 279 100 279 100 279 110 c 0,0,1 +338 155 m 2,12,-1 + 338 357 l 2,13,14 + 338 359 338 359 336 363 c 0,15,16 + 333 366 333 366 329 366 c 2,17,-1 + 183 366 l 2,18,19 + 179 366 179 366 176 363 c 0,20,21 + 174 359 174 359 174 357 c 2,22,-1 + 174 155 l 2,23,24 + 174 153 174 153 176 149 c 0,25,26 + 179 146 179 146 183 146 c 2,27,-1 + 329 146 l 2,28,29 + 333 146 333 146 336 149 c 0,30,31 + 338 153 338 153 338 155 c 2,12,-1 +283 398 m 0,32,33 + 283 402 283 402 279 402 c 2,34,-1 + 233 402 l 2,35,36 + 229 402 229 402 229 398 c 0,37,38 + 229 393 229 393 233 393 c 2,39,-1 + 279 393 l 2,40,41 + 283 393 283 393 283 398 c 0,32,33 +366 402 m 2,42,-1 + 366 110 l 2,43,44 + 366 95 366 95 355 84 c 128,-1,45 + 344 73 344 73 329 73 c 2,46,-1 + 183 73 l 2,47,48 + 168 73 168 73 157 84 c 128,-1,49 + 146 95 146 95 146 110 c 2,50,-1 + 146 402 l 2,51,52 + 146 417 146 417 157 428 c 128,-1,53 + 168 439 168 439 183 439 c 2,54,-1 + 329 439 l 2,55,56 + 344 439 344 439 355 428 c 128,-1,57 + 366 417 366 417 366 402 c 2,42,-1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: th-large +Encoding: 57352 57352 102 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +238 219 m 2,0,-1 + 238 110 l 2,1,2 + 238 95 238 95 227 84 c 128,-1,3 + 216 73 216 73 201 73 c 2,4,-1 + 55 73 l 2,5,6 + 40 73 40 73 29 84 c 128,-1,7 + 18 95 18 95 18 110 c 2,8,-1 + 18 219 l 2,9,10 + 18 234 18 234 29 245 c 128,-1,11 + 40 256 40 256 55 256 c 2,12,-1 + 201 256 l 2,13,14 + 216 256 216 256 227 245 c 128,-1,15 + 238 234 238 234 238 219 c 2,0,-1 +238 439 m 2,16,-1 + 238 329 l 2,17,18 + 238 316 238 316 227 303 c 0,19,20 + 217 293 217 293 201 293 c 2,21,-1 + 55 293 l 2,22,23 + 39 293 39 293 29 303 c 0,24,25 + 18 316 18 316 18 329 c 2,26,-1 + 18 439 l 2,27,28 + 18 452 18 452 29 465 c 0,29,30 + 39 475 39 475 55 475 c 2,31,-1 + 201 475 l 2,32,33 + 217 475 217 475 227 465 c 0,34,35 + 238 452 238 452 238 439 c 2,16,-1 +494 219 m 2,36,-1 + 494 110 l 2,37,38 + 494 95 494 95 483 84 c 128,-1,39 + 472 73 472 73 457 73 c 2,40,-1 + 311 73 l 2,41,42 + 296 73 296 73 285 84 c 128,-1,43 + 274 95 274 95 274 110 c 2,44,-1 + 274 219 l 2,45,46 + 274 234 274 234 285 245 c 128,-1,47 + 296 256 296 256 311 256 c 2,48,-1 + 457 256 l 2,49,50 + 472 256 472 256 483 245 c 128,-1,51 + 494 234 494 234 494 219 c 2,36,-1 +494 439 m 2,52,-1 + 494 329 l 2,53,54 + 494 316 494 316 483 303 c 0,55,56 + 473 293 473 293 457 293 c 2,57,-1 + 311 293 l 2,58,59 + 295 293 295 293 285 303 c 0,60,61 + 274 316 274 316 274 329 c 2,62,-1 + 274 439 l 2,63,64 + 274 452 274 452 285 465 c 0,65,66 + 295 475 295 475 311 475 c 2,67,-1 + 457 475 l 2,68,69 + 473 475 473 475 483 465 c 0,70,71 + 494 452 494 452 494 439 c 2,52,-1 +EndSplineSet +Validated: 513 +EndChar + +StartChar: heart-o +Encoding: 57353 57353 103 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +475 342 m 0,0,1 + 475 365 475 365 469 383 c 0,2,3 + 462 401 462 401 454 411 c 0,4,5 + 446 419 446 419 430 428 c 0,6,7 + 416 434 416 434 403 437 c 0,8,9 + 387 439 387 439 375 439 c 0,10,11 + 364 439 364 439 343 432 c 0,12,13 + 323 423 323 423 312 413 c 0,14,15 + 303 407 303 407 287 393 c 0,16,17 + 283 389 283 389 277.5 383 c 128,-1,18 + 272 377 272 377 270 375 c 0,19,20 + 266 369 266 369 256 369 c 128,-1,21 + 246 369 246 369 242 375 c 0,22,23 + 240 377 240 377 234.5 383 c 128,-1,24 + 229 389 229 389 225 393 c 0,25,26 + 209 407 209 407 200 413 c 0,27,28 + 189 423 189 423 169 432 c 0,29,30 + 148 439 148 439 137 439 c 0,31,32 + 125 439 125 439 109 437 c 0,33,34 + 96 434 96 434 82 428 c 0,35,36 + 66 419 66 419 58 411 c 0,37,38 + 50 401 50 401 43 383 c 0,39,40 + 37 365 37 365 37 342 c 0,41,42 + 37 293 37 293 90 240 c 2,43,-1 + 256 80 l 1,44,-1 + 422 240 l 2,45,46 + 475 293 475 293 475 342 c 0,0,1 +512 342 m 128,-1,48 + 512 280 512 280 447 213 c 2,49,-1 + 269 42 l 2,50,51 + 264 37 264 37 256 37 c 128,-1,52 + 248 37 248 37 243 42 c 2,53,-1 + 65 214 l 2,54,55 + 64 214 64 214 61.5 216.5 c 128,-1,56 + 59 219 59 219 57 221 c 0,57,58 + 52 227 52 227 41 240 c 0,59,60 + 31 252 31 252 22 268 c 0,61,62 + 14 281 14 281 7 302 c 0,63,64 + 0 322 0 322 0 342 c 0,65,66 + 0 404 0 404 36 440 c 0,67,68 + 71 475 71 475 137 475 c 0,69,70 + 154 475 154 475 173 469 c 256,71,72 + 192 463 192 463 207 453 c 0,73,74 + 221 444 221 444 234 433 c 0,75,76 + 246 424 246 424 256 414 c 1,77,78 + 266 424 266 424 278 433 c 0,79,80 + 291 444 291 444 305 453 c 0,81,82 + 320 463 320 463 339 469 c 256,83,84 + 358 475 358 475 375 475 c 0,85,86 + 441 475 441 475 476 440 c 0,87,47 + 512 404 512 404 512 342 c 128,-1,48 +EndSplineSet +Validated: 513 +EndChar + +StartChar: flag-checkered +Encoding: 57354 57354 104 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +238 226 m 1,0,-1 + 238 281 l 1,1,2 + 187 277 187 277 128 248 c 1,3,-1 + 128 195 l 1,4,5 + 189 223 189 223 238 226 c 1,0,-1 +238 346 m 1,6,-1 + 238 402 l 1,7,8 + 188 399 188 399 128 366 c 1,9,-1 + 128 312 l 1,10,11 + 188 343 188 343 238 346 c 1,6,-1 +475 213 m 1,12,-1 + 475 266 l 1,13,14 + 408 233 408 233 366 246 c 1,15,-1 + 366 310 l 1,16,17 + 358 312 358 312 355 314 c 2,18,-1 + 354 315 l 2,19,20 + 352 316 352 316 349.5 317 c 128,-1,21 + 347 318 347 318 345 319 c 128,-1,22 + 343 320 343 320 341 321 c 128,-1,23 + 339 322 339 322 337.5 323 c 128,-1,24 + 336 324 336 324 335 324 c 2,25,-1 + 334 324 l 2,26,27 + 332 325 332 325 330 326 c 128,-1,28 + 328 327 328 327 326 328 c 0,29,30 + 318 332 318 332 316 332 c 0,31,32 + 315 333 315 333 307 336 c 0,33,34 + 305 337 305 337 301.5 338.5 c 128,-1,35 + 298 340 298 340 297 340 c 0,36,37 + 295 340 295 340 287 342 c 128,-1,38 + 279 344 279 344 276 344 c 0,39,40 + 272 345 272 345 264 345 c 0,41,42 + 260 346 260 346 252 346 c 0,43,44 + 243 346 243 346 238 345 c 1,45,-1 + 238 282 l 1,46,-1 + 243 282 l 2,47,48 + 272 282 272 282 298 273 c 0,49,50 + 321 266 321 266 355 250 c 0,51,52 + 358 248 358 248 366 246 c 1,53,-1 + 366 192 l 1,54,55 + 379 187 379 187 392 187 c 0,56,57 + 425 187 425 187 475 213 c 1,12,-1 +475 335 m 1,58,-1 + 475 389 l 1,59,60 + 426 363 426 363 388 363 c 0,61,62 + 375 363 375 363 366 366 c 1,63,-1 + 366 310 l 1,64,65 + 408 298 408 298 475 335 c 1,58,-1 +91 439 m 0,66,67 + 91 427 91 427 86 421 c 0,68,69 + 82 413 82 413 73 407 c 1,70,-1 + 73 46 l 2,71,72 + 73 43 73 43 71 39 c 0,73,74 + 69 37 69 37 64 37 c 2,75,-1 + 46 37 l 2,76,77 + 41 37 41 37 39 39 c 128,-1,78 + 37 41 37 41 37 46 c 2,79,-1 + 37 407 l 1,80,81 + 29 413 29 413 23 421 c 0,82,83 + 18 429 18 429 18 439 c 0,84,85 + 18 454 18 454 29 465 c 0,86,87 + 39 475 39 475 55 475 c 128,-1,88 + 71 475 71 475 81 465 c 128,-1,89 + 91 455 91 455 91 439 c 0,66,67 +512 421 m 2,90,-1 + 512 203 l 2,91,92 + 512 192 512 192 502 186 c 0,93,94 + 498 184 498 184 497 184 c 0,95,96 + 436 151 436 151 392 151 c 0,97,98 + 366 151 366 151 347 161 c 2,99,-1 + 339 165 l 2,100,101 + 322 173 322 173 310 178 c 0,102,103 + 302 182 302 182 284 187 c 0,104,105 + 264 191 264 191 252 191 c 0,106,107 + 226 191 226 191 184 178 c 0,108,109 + 147 166 147 166 119 149 c 0,110,111 + 114 146 114 146 110 146 c 128,-1,112 + 106 146 106 146 101 149 c 0,113,114 + 91 153 91 153 91 165 c 2,115,-1 + 91 377 l 2,116,117 + 91 386 91 386 100 392 c 0,118,119 + 114 400 114 400 123 404 c 0,120,121 + 124 405 124 405 155 419 c 0,122,123 + 179 429 179 429 199 433 c 0,124,125 + 222 439 222 439 243 439 c 0,126,127 + 274 439 274 439 303 430 c 0,128,129 + 333 420 333 420 363 405 c 0,130,131 + 375 400 375 400 388 400 c 0,132,133 + 422 400 422 400 477 432 c 0,134,135 + 483 435 483 435 485 437 c 0,136,137 + 494 442 494 442 503 436 c 128,-1,138 + 512 430 512 430 512 421 c 2,90,-1 +EndSplineSet +Validated: 549 +EndChar + +StartChar: h-square +Encoding: 57355 57355 105 +Width: 488 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +388.860351562 139.51953125 m 2,0,-1 + 388.860351562 372.48046875 l 2,1,2 + 388.860351562 377.940429688 388.860351562 377.940429688 384.309570312 384.309570312 c 0,3,4 + 377.940429688 388.860351562 377.940429688 388.860351562 372.48046875 388.860351562 c 2,5,-1 + 338.809570312 388.860351562 l 2,6,7 + 332.440429688 388.860351562 332.440429688 388.860351562 327.889648438 384.309570312 c 0,8,9 + 322.4296875 378.849609375 322.4296875 378.849609375 322.4296875 372.48046875 c 2,10,-1 + 322.4296875 289.669921875 l 1,11,-1 + 189.5703125 289.669921875 l 1,12,-1 + 189.5703125 372.48046875 l 2,13,14 + 189.5703125 378.849609375 189.5703125 378.849609375 184.110351562 384.309570312 c 0,15,16 + 179.559570312 388.860351562 179.559570312 388.860351562 173.190429688 388.860351562 c 2,17,-1 + 139.51953125 388.860351562 l 2,18,19 + 134.059570312 388.860351562 134.059570312 388.860351562 127.690429688 384.309570312 c 0,20,21 + 123.139648438 377.940429688 123.139648438 377.940429688 123.139648438 372.48046875 c 2,22,-1 + 123.139648438 139.51953125 l 2,23,24 + 123.139648438 134.059570312 123.139648438 134.059570312 127.690429688 127.690429688 c 0,25,26 + 134.059570312 123.139648438 134.059570312 123.139648438 139.51953125 123.139648438 c 2,27,-1 + 173.190429688 123.139648438 l 2,28,29 + 179.559570312 123.139648438 179.559570312 123.139648438 184.110351562 127.690429688 c 0,30,31 + 189.5703125 133.150390625 189.5703125 133.150390625 189.5703125 139.51953125 c 2,32,-1 + 189.5703125 222.330078125 l 1,33,-1 + 322.4296875 222.330078125 l 1,34,-1 + 322.4296875 139.51953125 l 2,35,36 + 322.4296875 133.150390625 322.4296875 133.150390625 327.889648438 127.690429688 c 0,37,38 + 332.440429688 123.139648438 332.440429688 123.139648438 338.809570312 123.139648438 c 2,39,-1 + 372.48046875 123.139648438 l 2,40,41 + 377.940429688 123.139648438 377.940429688 123.139648438 384.309570312 127.690429688 c 0,42,43 + 388.860351562 134.059570312 388.860351562 134.059570312 388.860351562 139.51953125 c 2,0,-1 +455.290039062 380.669921875 m 2,44,-1 + 455.290039062 131.330078125 l 2,45,46 + 455.290039062 100.389648438 455.290039062 100.389648438 433.450195312 78.5498046875 c 128,-1,47 + 411.610351562 56.7099609375 411.610351562 56.7099609375 380.669921875 56.7099609375 c 2,48,-1 + 131.330078125 56.7099609375 l 2,49,50 + 100.389648438 56.7099609375 100.389648438 56.7099609375 78.5498046875 78.5498046875 c 128,-1,51 + 56.7099609375 100.389648438 56.7099609375 100.389648438 56.7099609375 131.330078125 c 2,52,-1 + 56.7099609375 380.669921875 l 2,53,54 + 56.7099609375 411.610351562 56.7099609375 411.610351562 78.5498046875 433.450195312 c 128,-1,55 + 100.389648438 455.290039062 100.389648438 455.290039062 131.330078125 455.290039062 c 2,56,-1 + 380.669921875 455.290039062 l 2,57,58 + 411.610351562 455.290039062 411.610351562 455.290039062 433.450195312 433.450195312 c 128,-1,59 + 455.290039062 411.610351562 455.290039062 411.610351562 455.290039062 380.669921875 c 2,44,-1 +EndSplineSet +EndChar + +StartChar: t-shirt +Encoding: 57356 57356 106 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +500 409 m 2,0,-1 + 420 473 l 2,1,2 + 412 480 412 480 400 480 c 2,3,-1 + 112 480 l 2,4,5 + 100 480 100 480 92 473 c 2,6,-1 + 12 409 l 2,7,8 + -6 395 -6 395 2 374 c 2,9,-1 + 34 278 l 2,10,11 + 39 263 39 263 54 258 c 0,12,13 + 60 256 60 256 64 256 c 0,14,15 + 73 256 73 256 80 260 c 1,16,-1 + 80 64 l 2,17,18 + 80 50 80 50 89 41 c 128,-1,19 + 98 32 98 32 112 32 c 2,20,-1 + 400 32 l 2,21,22 + 414 32 414 32 423 41 c 128,-1,23 + 432 50 432 50 432 64 c 2,24,-1 + 432 260 l 1,25,26 + 439 256 439 256 448 256 c 0,27,28 + 452 256 452 256 458 258 c 0,29,30 + 473 263 473 263 478 278 c 2,31,-1 + 510 374 l 2,32,33 + 518 395 518 395 500 409 c 2,0,-1 +316 448 m 1,34,35 + 301 416 301 416 256 416 c 128,-1,36 + 211 416 211 416 196 448 c 1,37,-1 + 316 448 l 1,34,35 +448 288 m 1,38,-1 + 400 320 l 1,39,-1 + 400 64 l 1,40,-1 + 112 64 l 1,41,-1 + 112 320 l 1,42,-1 + 64 288 l 1,43,-1 + 32 384 l 1,44,-1 + 112 448 l 1,45,-1 + 179 448 l 1,46,47 + 186 427 186 427 207 413.5 c 128,-1,48 + 228 400 228 400 256 400 c 128,-1,49 + 284 400 284 400 305 413.5 c 128,-1,50 + 326 427 326 427 333 448 c 1,51,-1 + 400 448 l 1,52,-1 + 480 384 l 1,53,-1 + 448 288 l 1,38,-1 +EndSplineSet +Validated: 553 +EndChar + +StartChar: heart +Encoding: 57357 57357 107 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +256 37 m 128,-1,1 + 248 37 248 37 243 42 c 2,2,-1 + 65 214 l 2,3,4 + 64 214 64 214 61.5 216.5 c 128,-1,5 + 59 219 59 219 57 221 c 0,6,7 + 52 227 52 227 41 240 c 0,8,9 + 31 252 31 252 22 268 c 0,10,11 + 14 281 14 281 7 302 c 0,12,13 + 0 322 0 322 0 342 c 0,14,15 + 0 404 0 404 36 440 c 0,16,17 + 71 475 71 475 137 475 c 0,18,19 + 154 475 154 475 173 469 c 256,20,21 + 192 463 192 463 207 453 c 0,22,23 + 221 444 221 444 234 433 c 0,24,25 + 246 424 246 424 256 414 c 1,26,27 + 266 424 266 424 278 433 c 0,28,29 + 291 444 291 444 305 453 c 0,30,31 + 320 463 320 463 339 469 c 256,32,33 + 358 475 358 475 375 475 c 0,34,35 + 441 475 441 475 476 440 c 0,36,37 + 512 404 512 404 512 342 c 128,-1,38 + 512 280 512 280 447 213 c 2,39,-1 + 269 42 l 2,40,0 + 264 37 264 37 256 37 c 128,-1,1 +EndSplineSet +Validated: 1 +EndChar + +StartChar: radio-tower +Encoding: 57358 57358 108 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +153 317 m 0,0,1 + 159 323 159 323 159 331.5 c 128,-1,2 + 159 340 159 340 153 346 c 0,3,4 + 138 363 138 363 138 384 c 0,5,6 + 138 407 138 407 153 422 c 0,7,8 + 159 428 159 428 159 437 c 128,-1,9 + 159 446 159 446 153 452 c 128,-1,10 + 147 458 147 458 139 458 c 128,-1,11 + 131 458 131 458 125 452 c 0,12,13 + 97 422 97 422 97 384 c 0,14,15 + 97 345 97 345 125 317 c 0,16,17 + 139 301 139 301 153 317 c 0,0,1 +75 495 m 0,18,19 + 68 502 68 502 60 502 c 0,20,21 + 51 502 51 502 45 495 c 0,22,23 + 0 450 0 450 0 384 c 0,24,25 + 0 320 0 320 45 273 c 0,26,27 + 59 259 59 259 75 273 c 0,28,29 + 81 279 81 279 81 288 c 128,-1,30 + 81 297 81 297 75 303 c 0,31,32 + 42 338 42 338 42 384 c 0,33,34 + 42 432 42 432 75 465 c 0,35,36 + 89 481 89 481 75 495 c 0,18,19 +257 332 m 0,37,38 + 278 332 278 332 293 347 c 128,-1,39 + 308 362 308 362 308 384 c 128,-1,40 + 308 406 308 406 293 421 c 128,-1,41 + 278 436 278 436 257 436 c 0,42,43 + 235 436 235 436 220 421 c 128,-1,44 + 205 406 205 406 205 384 c 128,-1,45 + 205 362 205 362 220 347 c 128,-1,46 + 235 332 235 332 257 332 c 0,37,38 +467 495 m 0,47,48 + 461 501 461 501 452.5 501 c 128,-1,49 + 444 501 444 501 438 495 c 0,50,51 + 431 489 431 489 431 480 c 128,-1,52 + 431 471 431 471 438 465 c 0,53,54 + 470 431 470 431 470 384 c 128,-1,55 + 470 337 470 337 438 303 c 0,56,57 + 422 287 422 287 438 273 c 0,58,59 + 445 266 445 266 452 266 c 0,60,61 + 460 266 460 266 467 273 c 0,62,63 + 512 318 512 318 512 384 c 0,64,65 + 512 448 512 448 467 495 c 0,47,48 +257 291 m 0,66,67 + 236 291 236 291 218 300 c 1,68,-1 + 118 32 l 1,69,-1 + 165 32 l 1,70,-1 + 193 64 l 1,71,-1 + 320 64 l 1,72,-1 + 347 32 l 1,73,-1 + 395 32 l 1,74,-1 + 295 300 l 1,75,76 + 277 291 277 291 257 291 c 0,66,67 +256 275 m 1,77,-1 + 289 160 l 1,78,-1 + 225 160 l 1,79,-1 + 256 275 l 1,77,-1 +193 96 m 1,80,-1 + 225 128 l 1,81,-1 + 289 128 l 1,82,-1 + 320 96 l 1,83,-1 + 193 96 l 1,80,-1 +359 451 m 0,84,85 + 353 445 353 445 353 436.5 c 128,-1,86 + 353 428 353 428 359 422 c 0,87,88 + 374 406 374 406 374 384 c 0,89,90 + 374 361 374 361 359 346 c 0,91,92 + 353 340 353 340 353 331 c 128,-1,93 + 353 322 353 322 359 316 c 128,-1,94 + 365 310 365 310 373 310 c 128,-1,95 + 381 310 381 310 387 316 c 0,96,97 + 415 346 415 346 415 384 c 0,98,99 + 415 423 415 423 387 451 c 0,100,101 + 373 467 373 467 359 451 c 0,84,85 +EndSplineSet +Validated: 553 +EndChar + +StartChar: bell-o +Encoding: 57359 57359 109 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +261 27 m 0,0,1 + 261 32 261 32 256 32 c 0,2,3 + 239 32 239 32 227 44 c 128,-1,4 + 215 56 215 56 215 73 c 0,5,6 + 215 78 215 78 210 78 c 0,7,8 + 206 78 206 78 206 73 c 0,9,10 + 206 52 206 52 220 38 c 0,11,12 + 235 23 235 23 256 23 c 0,13,14 + 261 23 261 23 261 27 c 0,0,1 +70 110 m 1,15,-1 + 442 110 l 1,16,17 + 366 195 366 195 366 347 c 0,18,19 + 366 360 366 360 359 377 c 0,20,21 + 351 395 351 395 339 407 c 0,22,23 + 327 421 327 421 304 430 c 0,24,25 + 283 439 283 439 256 439 c 128,-1,26 + 229 439 229 439 208 430 c 0,27,28 + 185 421 185 421 173 407 c 0,29,30 + 161 395 161 395 153 377 c 0,31,32 + 146 360 146 360 146 347 c 0,33,34 + 146 195 146 195 70 110 c 1,15,-1 +494 110 m 1,35,36 + 494 95 494 95 483 84 c 128,-1,37 + 472 73 472 73 457 73 c 2,38,-1 + 329 73 l 1,39,40 + 329 44 329 44 308 21 c 0,41,42 + 286 0 286 0 256 0 c 128,-1,43 + 226 0 226 0 204 21 c 0,44,45 + 183 43 183 43 183 73 c 1,46,-1 + 55 73 l 2,47,48 + 40 73 40 73 29 84 c 128,-1,49 + 18 95 18 95 18 110 c 1,50,51 + 31 120 31 120 44 135 c 0,52,53 + 55 148 55 148 69 169 c 0,54,55 + 81 190 81 190 90 214 c 0,56,57 + 97 233 97 233 104 273 c 0,58,59 + 110 308 110 308 110 347 c 0,60,61 + 110 390 110 390 143 428 c 0,62,63 + 176 465 176 465 231 473 c 1,64,65 + 229 477 229 477 229 485 c 0,66,67 + 229 497 229 497 237 504 c 0,68,69 + 245 512 245 512 256 512 c 128,-1,70 + 267 512 267 512 275 504 c 0,71,72 + 283 497 283 497 283 485 c 0,73,74 + 283 477 283 477 281 473 c 1,75,76 + 336 465 336 465 369 428 c 0,77,78 + 402 390 402 390 402 347 c 0,79,80 + 402 308 402 308 408 273 c 0,81,82 + 415 233 415 233 422 214 c 0,83,84 + 431 190 431 190 443 169 c 0,85,86 + 457 148 457 148 468 135 c 0,87,88 + 481 120 481 120 494 110 c 1,35,36 +EndSplineSet +Validated: 513 +EndChar + +StartChar: disc +Encoding: 57360 57360 110 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +406 235 m 4,0,1 + 406 189 406 189 386 155 c 4,2,3 + 367 120 367 120 332 97 c 4,4,5 + 299 77 299 77 256 77 c 132,-1,6 + 213 77 213 77 180 97 c 4,7,8 + 145 120 145 120 126 155 c 4,9,10 + 106 189 106 189 106 235 c 4,11,12 + 106 280 106 280 126 314 c 4,13,14 + 144 348 144 348 180 372 c 4,15,16 + 215 393 215 393 256 393 c 4,17,18 + 298 393 298 393 332 372 c 4,19,20 + 368 348 368 348 386 314 c 4,21,22 + 406 280 406 280 406 235 c 4,0,1 +EndSplineSet +EndChar + +StartChar: crown1-1 +Encoding: 57369 57369 111 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +Fore +SplineSet +1 508 m 0,0,1 + 1 507 1 507 1.5 505 c 128,-1,2 + 2 503 2 503 2.5 500 c 128,-1,3 + 3 497 3 497 3 495 c 0,4,5 + 5 460 5 460 24 423 c 0,6,7 + 37 396 37 396 59 376 c 0,8,9 + 83 352 83 352 116 333 c 128,-1,10 + 149 314 149 314 220 284 c 0,11,12 + 288 256 288 256 320 237 c 0,13,14 + 361 213 361 213 361 209 c 2,15,-1 + 356 212 l 2,16,17 + 350 214 350 214 345 216 c 0,18,19 + 311 226 311 226 233 240 c 0,20,21 + 132 258 132 258 89 276 c 0,22,23 + 61 288 61 288 46 297 c 0,24,25 + 38 302 38 302 38 301 c 0,26,27 + 40 296 40 296 42 290 c 0,28,29 + 70 217 70 217 152 194 c 0,30,31 + 183 186 183 186 260 177 c 0,32,33 + 338 170 338 170 368 161 c 2,34,-1 + 377 158 l 1,35,-1 + 359 158 l 2,36,37 + 334 158 334 158 289 151 c 0,38,39 + 234 145 234 145 207 144 c 0,40,41 + 168 142 168 142 125 152 c 1,42,-1 + 116 156 l 2,43,44 + 115 155 115 155 124.5 142.5 c 128,-1,45 + 134 130 134 130 141 123 c 0,46,47 + 164 100 164 100 198 89 c 0,48,49 + 208 87 208 87 232 87 c 0,50,51 + 263 87 263 87 315 99 c 0,52,53 + 377 111 377 111 383 111 c 0,54,55 + 387 112 387 112 398 112 c 2,56,-1 + 404 113 l 1,57,-1 + 395 110 l 2,58,59 + 369 99 369 99 345 85 c 0,60,61 + 285 51 285 51 242 48 c 2,62,-1 + 229 46 l 1,63,-1 + 239 38 l 2,64,65 + 260 22 260 22 276 16 c 0,66,67 + 279 15 279 15 298 11 c 0,68,69 + 317 10 317 10 334 18 c 128,-1,70 + 351 26 351 26 387 53 c 0,71,72 + 416 74 416 74 426 77 c 0,73,74 + 440 82 440 82 452 76 c 0,75,76 + 468 67 468 67 468 49 c 0,77,78 + 468 47 468 47 468 45 c 128,-1,79 + 468 43 468 43 468 42 c 2,80,-1 + 468 40 l 2,81,82 + 467 38 467 38 466 40 c 2,83,84 + 466 40 466 40 465 43 c 0,85,86 + 460 53 460 53 449.5 56.5 c 128,-1,87 + 439 60 439 60 430 54 c 0,88,89 + 412 45 412 45 419 25 c 0,90,91 + 420 22 420 22 426 14 c 0,92,93 + 440 0 440 0 459 0.5 c 128,-1,94 + 478 1 478 1 491 16 c 0,95,96 + 516 40 516 40 498 70 c 0,97,98 + 488 84 488 84 478 88 c 2,99,-1 + 466 94 l 2,100,101 + 452 105 452 105 451 109 c 1,102,103 + 467 104 467 104 483.5 111 c 128,-1,104 + 500 118 500 118 507 134 c 0,105,106 + 517 156 517 156 504 176 c 0,107,108 + 493 196 493 196 467 198 c 0,109,110 + 454 198 454 198 446 193 c 0,111,112 + 433 182 433 182 440 169 c 0,113,114 + 448 150 448 150 467 157 c 0,115,116 + 478 162 478 162 479 169 c 0,117,118 + 480 171 480 171 481 164 c 0,119,120 + 478 146 478 146 464 138 c 0,121,122 + 450 132 450 132 435 138 c 0,123,124 + 427 143 427 143 421 153 c 0,125,126 + 418 165 418 165 418 173 c 0,127,128 + 412 204 412 204 403 221 c 0,129,130 + 388 253 388 253 354 281 c 0,131,132 + 318 310 318 310 225 358 c 0,133,134 + 135 405 135 405 93 432.5 c 128,-1,135 + 51 460 51 460 17 496 c 2,136,-1 + 2 511 l 2,137,138 + 1 511 1 511 1 508 c 0,0,1 +EndSplineSet +EndChar + +StartChar: uni007F +Encoding: 65538 -1 112 +Width: 512 +GlyphClass: 2 +Flags: W +LayerCount: 2 +EndChar + +StartChar: questiondown +Encoding: 191 191 113 +Width: 512 +VWidth: 0 +Flags: W +LayerCount: 2 +EndChar + +StartChar: Ograve +Encoding: 210 210 114 +Width: 512 +Flags: WO +LayerCount: 2 +Fore +SplineSet +256 370 m 132,-1,1 + 223 370 223 370 194 354 c 4,2,3 + 165 337 165 337 148 308 c 4,4,5 + 132 279 132 279 132 246 c 132,-1,6 + 132 213 132 213 148 184 c 4,7,8 + 165 155 165 155 194 138 c 4,9,10 + 223 122 223 122 256 122 c 132,-1,11 + 289 122 289 122 318 138 c 4,12,13 + 347 155 347 155 364 184 c 4,14,15 + 380 213 380 213 380 246 c 132,-1,16 + 380 279 380 279 364 308 c 4,17,18 + 347 337 347 337 318 354 c 4,19,0 + 289 370 289 370 256 370 c 132,-1,1 +431 246 m 132,-1,21 + 431 196 431 196 408 158 c 4,22,23 + 384 118 384 118 344 94 c 4,24,25 + 306 71 306 71 256 71 c 132,-1,26 + 206 71 206 71 168 94 c 4,27,28 + 128 118 128 118 104 158 c 4,29,30 + 81 196 81 196 81 246 c 132,-1,31 + 81 296 81 296 104 334 c 4,32,33 + 128 374 128 374 168 398 c 4,34,35 + 206 421 206 421 256 421 c 132,-1,36 + 306 421 306 421 344 398 c 4,37,38 + 384 374 384 374 408 334 c 4,39,20 + 431 296 431 296 431 246 c 132,-1,21 +EndSplineSet +EndChar +EndChars +EndSplineFont diff --git a/public/font/lichess.woff b/public/font/lichess.woff new file mode 100644 index 0000000000..8102454104 Binary files /dev/null and b/public/font/lichess.woff differ diff --git a/public/font/lichess.woff2 b/public/font/lichess.woff2 new file mode 100644 index 0000000000..6018820682 Binary files /dev/null and b/public/font/lichess.woff2 differ diff --git a/public/font/noto-sans-bold-latin.woff2 b/public/font/noto-sans-bold-latin.woff2 new file mode 100644 index 0000000000..67500d5362 Binary files /dev/null and b/public/font/noto-sans-bold-latin.woff2 differ diff --git a/public/font/noto-sans-latin.woff2 b/public/font/noto-sans-latin.woff2 new file mode 100644 index 0000000000..22818e7d4c Binary files /dev/null and b/public/font/noto-sans-latin.woff2 differ diff --git a/public/font/roboto-light-latin.woff2 b/public/font/roboto-light-latin.woff2 new file mode 100644 index 0000000000..52c5845a7c Binary files /dev/null and b/public/font/roboto-light-latin.woff2 differ diff --git a/public/font82/fonts/lichess.eot b/public/font82/fonts/lichess.eot deleted file mode 100644 index 92eb964c8c..0000000000 Binary files a/public/font82/fonts/lichess.eot and /dev/null differ diff --git a/public/font82/fonts/lichess.svg b/public/font82/fonts/lichess.svg deleted file mode 100644 index 98cfead9b5..0000000000 --- a/public/font82/fonts/lichess.svg +++ /dev/null @@ -1,126 +0,0 @@ - - - -Generated by Fontastic.me - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/font82/fonts/lichess.ttf b/public/font82/fonts/lichess.ttf deleted file mode 100644 index faf53cca4e..0000000000 Binary files a/public/font82/fonts/lichess.ttf and /dev/null differ diff --git a/public/font82/fonts/lichess.woff b/public/font82/fonts/lichess.woff deleted file mode 100644 index 7a1b7bc404..0000000000 Binary files a/public/font82/fonts/lichess.woff and /dev/null differ diff --git a/public/font82/icons-reference.html b/public/font82/icons-reference.html deleted file mode 100644 index 3731840aea..0000000000 --- a/public/font82/icons-reference.html +++ /dev/null @@ -1,968 +0,0 @@ - - - - - - - Font Reference - lichess - - - - - -
    -

    lichess

    -

    This font was created withFontastic

    -

    CSS mapping

    -
      -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • - - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    -

    Character mapping

    -
      -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    • -
      - -
    • -
    -
    - - - \ No newline at end of file diff --git a/public/font82/styles.css b/public/font82/styles.css deleted file mode 100644 index d64433635a..0000000000 --- a/public/font82/styles.css +++ /dev/null @@ -1,388 +0,0 @@ -@charset "UTF-8"; - -@font-face { - font-family: "lichess"; - src:url("fonts/lichess.eot"); - src:url("fonts/lichess.eot?#iefix") format("embedded-opentype"), - url("fonts/lichess.woff") format("woff"), - url("fonts/lichess.ttf") format("truetype"), - url("fonts/lichess.svg#lichess") format("svg"); - font-weight: normal; - font-style: normal; - font-display: block; -} - -[data-icon]:before { - font-family: "lichess" !important; - content: attr(data-icon); - font-style: normal !important; - font-weight: normal !important; - font-variant: normal !important; - text-transform: none !important; - speak: none; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -[class^="icon-"]:before, -[class*=" icon-"]:before { - font-family: "lichess" !important; - font-style: normal !important; - font-weight: normal !important; - font-variant: normal !important; - text-transform: none !important; - speak: none; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.icon-fontawesome-webfont-1:before { - content: "\61"; -} -.icon-fontawesome-webfont-2:before { - content: "\62"; -} -.icon-fontawesome-webfont-3:before { - content: "\63"; -} -.icon-fontawesome-webfont-4:before { - content: "\64"; -} -.icon-fontawesome-webfont-5:before { - content: "\65"; -} -.icon-fontawesome-webfont-6:before { - content: "\66"; -} -.icon-fontawesome-webfont-7:before { - content: "\67"; -} -.icon-fontawesome-webfont-8:before { - content: "\68"; -} -.icon-fontawesome-webfont-9:before { - content: "\6a"; -} -.icon-fontawesome-webfont-10:before { - content: "\6b"; -} -.icon-fontawesome-webfont-11:before { - content: "\6c"; -} -.icon-fontawesome-webfont-12:before { - content: "\6d"; -} -.icon-fontawesome-webfont-15:before { - content: "\70"; -} -.icon-fontawesome-webfont-17:before { - content: "\72"; -} -.icon-fontawesome-webfont-18:before { - content: "\73"; -} -.icon-fontawesome-webfont-19:before { - content: "\74"; -} -.icon-fontawesome-webfont-20:before { - content: "\75"; -} -.icon-eye-view-1:before { - content: "\76"; -} -.icon-fontawesome-webfont-21:before { - content: "\77"; -} -.icon-fontawesome-webfont-22:before { - content: "\78"; -} -.icon-fontawesome-webfont-23:before { - content: "\7a"; -} -.icon-microscope:before { - content: "\41"; -} -.icon-crown-king-1:before { - content: "\43"; -} -.icon-fontawesome-webfont-24:before { - content: "\44"; -} -.icon-fontawesome-webfont-25:before { - content: "\45"; -} -.icon-fontawesome-webfont-26:before { - content: "\46"; -} -.icon-fontawesome-webfont-27:before { - content: "\47"; -} -.icon-fontawesome-webfont-28:before { - content: "\48"; -} -.icon-fontawesome-webfont-29:before { - content: "\49"; -} -.icon-fontawesome-webfont-30:before { - content: "\4a"; -} -.icon-fontawesome-webfont-31:before { - content: "\4b"; -} -.icon-loop-alt2:before { - content: "\42"; -} -.icon-arrow-full-lowerright:before { - content: "\4d"; -} -.icon-arrow-full-upperright:before { - content: "\4e"; -} -.icon-fontawesome-webfont-32:before { - content: "\4c"; -} -.icon-plus-squared:before { - content: "\4f"; -} -.icon-plus-circled:before { - content: "\4f"; -} -.icon-fontawesome-webfont-33:before { - content: "\4f"; -} -.icon-fontawesome-webfont-34:before { - content: "\51"; -} -.icon-fire-station-24:before { - content: "\51"; -} -.icon-burning-fire:before { - content: "\51"; -} -.icon-arrow-sans-down:before { - content: "\52"; -} -.icon-arrow-sans-up:before { - content: "\53"; -} -.icon-fontawesome-webfont-34:before { - content: "\54"; -} -.icon-crossed-swords-small:before { - content: "\55"; -} -.icon-fontawesome-webfont-35:before { - content: "\56"; -} -.icon-fontawesome-webfont-36:before { - content: "\57"; -} -.icon-fontawesome-webfont-37:before { - content: "\58"; -} -.icon-fontawesome-webfont-38:before { - content: "\59"; -} -.icon-fontawesome-webfont-39:before { - content: "\5a"; -} -.icon-fontawesome-webfont-40:before { - content: "\21"; -} -.icon-fontawesome-webfont-41:before { - content: "\50"; -} -.icon-fontawesome-webfont:before { - content: "\69"; -} -.icon-hand-stop:before { - content: "\32"; -} -.icon-ionicons:before { - content: "\33"; -} -.icon-fontawesome-webfont-42:before { - content: "\30"; -} -.icon-television-tv:before { - content: "\31"; -} -.icon-ink-pen:before { - content: "\36"; -} -.icon-chart-line:before { - content: "\39"; -} -.icon-link:before { - content: "\22"; -} -.icon-ionicons-1:before { - content: "\37"; -} -.icon-gear:before { - content: "\25"; -} -.icon-repo:before { - content: "\26"; -} -.icon-tag:before { - content: "\6f"; -} -.icon-trash-bin:before { - content: "\71"; -} -.icon-search-find:before { - content: "\79"; -} -.icon-crown:before { - content: "\38"; -} -.icon-die-six:before { - content: "\27"; -} -.icon-flag:before { - content: "\28"; -} -.icon-flame:before { - content: "\29"; -} -.icon-arrow-streamline-target:before { - content: "\2d"; -} -.icon-buffer:before { - content: "\2e"; -} -.icon-upload-cloud:before { - content: "\2f"; -} -.icon-feather:before { - content: "\2a"; -} -.icon-email-plane:before { - content: "\3b"; -} -.icon-zoom-in:before { - content: "\3c"; -} -.icon-screen-full:before { - content: "\3d"; -} -.icon-list:before { - content: "\3f"; -} -.icon-atom:before { - content: "\3e"; -} -.icon-book:before { - content: "\5d"; -} -.icon-body-cut:before { - content: "\60"; -} -.icon-antichess:before { - content: "\40"; -} -.icon-reorder:before { - content: "\5b"; -} -.icon-keypad:before { - content: "\5f"; -} -.icon-arrows-in:before { - content: "\7c"; -} -.icon-color-palette:before { - content: "\7d"; -} -.icon-earth-globe-streamline:before { - content: "\5c"; -} -.icon-nuclear:before { - content: "\2c"; -} -.icon-hookah:before { - content: "\7e"; -} -.icon-tools:before { - content: "\e000"; -} -.icon-agent:before { - content: "\e002"; -} -.icon-mic:before { - content: "\e003"; -} -.icon-bar-chart:before { - content: "\e004"; -} -.icon-graph:before { - content: "\5e"; -} -.icon-info-circled:before { - content: "\e005"; -} -.icon-screen-desktop:before { - content: "\e006"; -} -.icon-phone-mobile:before { - content: "\e007"; -} -.icon-flag-checkered:before { - content: "\e00a"; -} -.icon-h-square:before { - content: "\e00b"; -} -.icon-t-shirt:before { - content: "\e00c"; -} -.icon-radio-tower:before { - content: "\e00e"; -} -.icon-heart-o:before { - content: "\e009"; -} -.icon-heart:before { - content: "\e00d"; -} -.icon-bell-o:before { - content: "\e00f"; -} -.icon-disc:before { - content: "\e010"; -} -.icon-crown1-1:before { - content: "\e019"; -} -.icon-cogs:before { - content: "\6e"; -} -.icon-graduate-cap:before { - content: "\3a"; -} -.icon-bullseye:before { - content: "\e001"; -} -.icon-delicious:before { - content: "\34"; -} -.icon-shield:before { - content: "\35"; -} -.icon-pointer:before { - content: "\7b"; -} -.icon-turtle:before { - content: "\2b"; -} -.icon-rabbit:before { - content: "\23"; -} -.icon-share-alt:before { - content: "\24"; -} -.icon-th-large:before { - content: "\e008"; -} diff --git a/public/fonts/ChessSansPiratf.eot b/public/fonts/ChessSansPiratf.eot deleted file mode 100644 index 708d66b804..0000000000 Binary files a/public/fonts/ChessSansPiratf.eot and /dev/null differ diff --git a/public/fonts/ChessSansPiratf.svg b/public/fonts/ChessSansPiratf.svg deleted file mode 100644 index ce5c98709e..0000000000 --- a/public/fonts/ChessSansPiratf.svg +++ /dev/null @@ -1,1288 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/fonts/ChessSansPiratf.ttf b/public/fonts/ChessSansPiratf.ttf deleted file mode 100644 index ebedacd597..0000000000 Binary files a/public/fonts/ChessSansPiratf.ttf and /dev/null differ diff --git a/public/fonts/ChessSansPiratf.woff b/public/fonts/ChessSansPiratf.woff deleted file mode 100644 index b67246b595..0000000000 Binary files a/public/fonts/ChessSansPiratf.woff and /dev/null differ diff --git a/public/images/board/3d/marble.512.png b/public/images/board/3d/marble.512.png deleted file mode 100644 index e63f248d8c..0000000000 Binary files a/public/images/board/3d/marble.512.png and /dev/null differ diff --git a/public/images/board/3d/woodi.512.png b/public/images/board/3d/woodi.512.png deleted file mode 100644 index 34e0167b26..0000000000 Binary files a/public/images/board/3d/woodi.512.png and /dev/null differ diff --git a/public/images/browser-chrome.png b/public/images/browser-chrome.png deleted file mode 100644 index 5e94931ed9..0000000000 Binary files a/public/images/browser-chrome.png and /dev/null differ diff --git a/public/images/browser-firefox.png b/public/images/browser-firefox.png deleted file mode 100644 index 157b5f1593..0000000000 Binary files a/public/images/browser-firefox.png and /dev/null differ diff --git a/public/images/browser-opera.png b/public/images/browser-opera.png deleted file mode 100644 index 9efac48304..0000000000 Binary files a/public/images/browser-opera.png and /dev/null differ diff --git a/public/images/browser-safari.png b/public/images/browser-safari.png deleted file mode 100644 index 00435ca2bc..0000000000 Binary files a/public/images/browser-safari.png and /dev/null differ diff --git a/public/images/browsers.xcf b/public/images/browsers.xcf deleted file mode 100644 index 91b3b45039..0000000000 Binary files a/public/images/browsers.xcf and /dev/null differ diff --git a/public/images/icons/pointer.png b/public/images/icons/pointer.png deleted file mode 100644 index 7033a48028..0000000000 Binary files a/public/images/icons/pointer.png and /dev/null differ diff --git a/public/images/icons/pointer.svg b/public/images/icons/pointer.svg new file mode 100644 index 0000000000..c9851ecd9f --- /dev/null +++ b/public/images/icons/pointer.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/icons/trash.svg b/public/images/icons/trash.svg new file mode 100644 index 0000000000..945834b792 --- /dev/null +++ b/public/images/icons/trash.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/images/board/3d/marble.1024.png b/public/images/staunton/board/Marble.png similarity index 100% rename from public/images/board/3d/marble.1024.png rename to public/images/staunton/board/Marble.png diff --git a/public/images/board/3d/marble.thumbnail.png b/public/images/staunton/board/Marble.thumbnail.png similarity index 100% rename from public/images/board/3d/marble.thumbnail.png rename to public/images/staunton/board/Marble.thumbnail.png diff --git a/public/images/board/3d/woodi.1024.png b/public/images/staunton/board/Woodi.png similarity index 100% rename from public/images/board/3d/woodi.1024.png rename to public/images/staunton/board/Woodi.png diff --git a/public/images/board/3d/woodi.thumbnail.png b/public/images/staunton/board/Woodi.thumbnail.png similarity index 100% rename from public/images/board/3d/woodi.thumbnail.png rename to public/images/staunton/board/Woodi.thumbnail.png diff --git a/public/javascripts/account.js b/public/javascripts/account.js index 5cb9915c41..13f1cc4126 100644 --- a/public/javascripts/account.js +++ b/public/javascripts/account.js @@ -1,6 +1,6 @@ $(function() { - $('.security.content_box table form').submit(function() { + $('.security table form').submit(function() { $.post($(this).attr('action')); $(this).parent().parent().fadeOut(300, function() { $(this).remove(); }); return false; @@ -15,7 +15,7 @@ $(function() { data: $form.serialize(), success: function() { $form.find('.saved').fadeIn(); - lichess.reloadOtherTabs(); + lichess.storage.set('reload-round-tabs', Math.random()); } }); }); diff --git a/public/javascripts/challenge.js b/public/javascripts/challenge.js index 697814b9fe..565b65fd80 100644 --- a/public/javascripts/challenge.js +++ b/public/javascripts/challenge.js @@ -1,9 +1,10 @@ window.onload = function() { - if (!window.lichess_challenge) return; var opts = lichess_challenge; - var element = document.getElementById('challenge'); + var selector = '.challenge-page'; + var element = document.querySelector(selector); var challenge = opts.data.challenge; var accepting; + lichess.socket = new lichess.StrongSocket( opts.socketUrl, opts.data.socketVersion, { @@ -15,7 +16,7 @@ window.onload = function() { $.ajax({ url: opts.xhrUrl, success: function(html) { - $('.lichess_overboard').replaceWith($(html).find('.lichess_overboard')); + $(selector).replaceWith($(html).find(selector)); init(); } }); @@ -23,15 +24,15 @@ window.onload = function() { } }); - var init = function() { - if (!accepting) $('#challenge_redirect').each(function() { + function init() { + if (!accepting) $('#challenge-redirect').each(function() { location.href = $(this).attr('href'); }); - $('.lichess_overboard').find('form.accept').submit(function() { + $(selector).find('form.accept').submit(function() { accepting = true; $(this).html(''); }); - $('.lichess_overboard').find('form.xhr').submit(function(e) { + $(selector).find('form.xhr').submit(function(e) { e.preventDefault(); $.ajax({ url: $(this).attr('action'), @@ -39,7 +40,7 @@ window.onload = function() { }); $(this).html(''); }); - $('.lichess_overboard').find('input.friend-autocomplete').each(function() { + $(selector).find('input.friend-autocomplete').each(function() { var $input = $(this); lichess.userAutocomplete($input, { focus: 1, @@ -50,26 +51,16 @@ window.onload = function() { } }); }); - }; + } + init(); - var pingNow = function() { - if (document.getElementById('ping_challenge')) { + function pingNow() { + if (document.getElementById('ping-challenge')) { lichess.socket.send('ping'); setTimeout(pingNow, 2000); } - }; - pingNow(); + } - var ground = Chessground(element.querySelector('.lichess_board'), { - viewOnly: true, - drawable: { enabled: false, visible: false }, - fen: challenge.initialFen, - orientation: (opts.owner ^ challenge.color === 'black') ? 'white' : 'black', - coordinates: false, - disableContextMenu: true - }); - setTimeout(function() { - $('.lichess_overboard_wrap', element).addClass('visible'); - }, 100); -}; + pingNow(); +} diff --git a/public/javascripts/chart/acpl.js b/public/javascripts/chart/acpl.js index 23aae1f7fc..6cdfc4079b 100644 --- a/public/javascripts/chart/acpl.js +++ b/public/javascripts/chart/acpl.js @@ -20,7 +20,7 @@ lichess.advantageChart = function(data, trans, el) { if (node.eval && node.eval.mate) { cp = node.eval.mate > 0 ? Infinity : -Infinity; - } else if (node.san.indexOf('#') > 0) { + } else if (node.san.includes('#')) { cp = color === 1 ? Infinity : -Infinity; if (d.game.variant.key === 'antichess') cp = -cp; } else if (node.eval && typeof node.eval.cp !== 'undefined') { diff --git a/public/javascripts/chart/movetime.js b/public/javascripts/chart/movetime.js index e514ca7c9a..a8d6e0a2fa 100644 --- a/public/javascripts/chart/movetime.js +++ b/public/javascripts/chart/movetime.js @@ -6,7 +6,7 @@ lichess.movetimeChart = function(data, trans) { lichess.loadScript('javascripts/chart/division.js').done(function() { lichess.chartCommon('highchart').done(function() { lichess.movetimeChart.render = function() { - $('#movetimes_chart:not(.rendered)').each(function() { + $('#movetimes-chart:not(.rendered)').each(function() { var $this = $(this).addClass('rendered'); var series = { @@ -106,7 +106,7 @@ lichess.movetimeChart = function(data, trans) { click: function(event) { if (event.point) { event.point.select(); - lichess.analyse.jumpToIndex(event.point.x); + lichess.pubsub.emit('analysis.chart.click')(event.point.x); } } }, diff --git a/public/javascripts/chart/ratingHistory.js b/public/javascripts/chart/ratingHistory.js index c8ff477b03..1386bfd15b 100644 --- a/public/javascripts/chart/ratingHistory.js +++ b/public/javascripts/chart/ratingHistory.js @@ -1,7 +1,9 @@ lichess.ratingHistoryChart = function(data, singlePerfName) { + var $el = $('div.rating-history'); + var $profile = $('#us_profile'); var singlePerfIndex = data.findIndex(x => x.name === singlePerfName); if (singlePerfName && data[singlePerfIndex].points.length === 0) { - $('div.rating_history').hide(); + $el.hide(); return; } var indexFilter = function(_, i) { @@ -9,13 +11,14 @@ lichess.ratingHistoryChart = function(data, singlePerfName) { }; lichess.loadScript('javascripts/chart/common.js').done(function() { lichess.chartCommon('highstock').done(function() { + // support: Fx when user bio overflows var disabled = { enabled: false }; var noText = { text: null }; - $('div.rating_history').each(function() { + $el.each(function() { var dashStyles = [ // order of perfs from RatingChartApi.scala 'Solid', // Bullet @@ -32,7 +35,7 @@ lichess.ratingHistoryChart = function(data, singlePerfName) { 'ShortDot', // Racing Kings 'Dash', // Crazyhouse 'Dash', // Puzzle - 'Dash' // Ultrabullet + 'Dash' // Ultrabullet ].filter(indexFilter); $(this).highcharts('StockChart', { yAxis: { diff --git a/public/javascripts/coach.form.js b/public/javascripts/coach.form.js index 7375c24c12..37ca46e86d 100644 --- a/public/javascripts/coach.form.js +++ b/public/javascripts/coach.form.js @@ -1,6 +1,6 @@ $(function() { - var $editor = $('.coach_edit'); + var $editor = $('.coach-edit'); var todo = (function() { @@ -42,7 +42,7 @@ $(function() { }); $el.find('ul').html(points); var fail = !!points.length; - $overview.toggleClass('with_todo', fail); + $overview.toggleClass('with-todo', fail); if (fail) $checkbox.prop('checked', false); $checkbox.attr('disabled', fail); }; @@ -56,8 +56,8 @@ $(function() { $editor.find('.panel.' + $(this).data('tab')).addClass('active'); $editor.find('div.status').removeClass('saved'); }); - var submit = lichess.fp.debounce(function() { - $editor.find('form.form3').ajaxSubmit({ + var submit = lichess.debounce(function() { + $editor.find('form.async').ajaxSubmit({ success: function() { $editor.find('div.status').addClass('saved'); todo(); diff --git a/public/javascripts/event-countdown.js b/public/javascripts/event-countdown.js index 95993e6e12..f064b6dc20 100644 --- a/public/javascripts/event-countdown.js +++ b/public/javascripts/event-countdown.js @@ -1,4 +1,4 @@ -$('#event .countdown').each(function() { +$('.event .countdown').each(function() { var $el = $(this); var seconds = parseInt($(this).data('seconds')) - 1; diff --git a/public/javascripts/forum-post.js b/public/javascripts/forum-post.js index 6e79622328..57e915cd69 100644 --- a/public/javascripts/forum-post.js +++ b/public/javascripts/forum-post.js @@ -1,6 +1,6 @@ $(function() { - $('#lichess_forum').on('click', 'a.delete', function() { + $('.forum').on('click', 'a.delete', function() { $.post($(this).attr("href")); $(this).closest(".post").hide(); return false; @@ -13,7 +13,7 @@ $(function() { $('.edit.button').add('.edit-post-cancel').click(function(e) { e.preventDefault(); - var post = $(this).closest('.post'); + var post = $(this).closest('.forum-post'); var message = post.find('.message').toggle(); var form = post.find('form.edit-post-form').toggle(); @@ -29,7 +29,7 @@ $(function() { var searchCandidates = function(term, candidateUsers) { return candidateUsers.filter(function(user) { - return user.toLowerCase().indexOf(term.toLowerCase()) === 0; + return user.toLowerCase().startsWith(term.toLowerCase()); }); }; diff --git a/public/javascripts/importer.js b/public/javascripts/importer.js index 520e357602..525dc30019 100644 --- a/public/javascripts/importer.js +++ b/public/javascripts/importer.js @@ -1,5 +1,5 @@ $(function() { - var $form = $("#import_game form"); + var $form = $("main.importer form"); $form.submit(function() { setTimeout(function() { $form.html(lichess.spinnerHtml); }, 50); }); diff --git a/public/javascripts/inquiry.js b/public/javascripts/inquiry.js index 41458dc62b..4833be1985 100644 --- a/public/javascripts/inquiry.js +++ b/public/javascripts/inquiry.js @@ -8,9 +8,9 @@ window.requestIdleCallback(function() { $('body').toggleClass('no-inquiry'); }); - var nextStore = lichess.storage.make('inquiry-auto-next'); + var nextStore = lichess.storage.makeBoolean('inquiry-auto-next'); var next = function() { - return nextStore.get() !== ''; + return nextStore.get(); }; if (!next()) { @@ -19,7 +19,7 @@ window.requestIdleCallback(function() { } $('#inquiry .switcher input').on('change', function() { - nextStore.set(next() ? '' : '1'); + nextStore.set(next()); $('#inquiry input.auto-next').val(next() ? '1' : '0'); }); }); diff --git a/public/javascripts/login.js b/public/javascripts/login.js index 9fb92a12f9..44b8bf7f0e 100644 --- a/public/javascripts/login.js +++ b/public/javascripts/login.js @@ -1,5 +1,7 @@ +var selector = '.auth-login form'; + $(function() { - load($('form.login')); + load($(selector)); }); function load($f) { @@ -21,11 +23,11 @@ function load($f) { $f.find('.submit').attr('disabled', false); if (res === 'InvalidTotpToken') $f.find('.two-factor .error').show(); } - else location.href = res.indexOf('ok:') === 0 ? res.substr(3) : '/'; + else location.href = res.startsWith('ok:') ? res.substr(3) : '/'; }, error: function(err) { - $f.replaceWith($(err.responseText).find('form.login')); - load($('form.login')); + $f.replaceWith($(err.responseText).find(selector)); + load($(selector)); } }); return false; diff --git a/public/javascripts/message.js b/public/javascripts/message.js index 5e61f8ac75..455146d5ac 100644 --- a/public/javascripts/message.js +++ b/public/javascripts/message.js @@ -1,5 +1,5 @@ $(function() { - $root = $('#lichess_message'); + $root = $('.message-list'); $root.find('select.select').change(function() { $root.find('input[name=threads]').prop('checked', false); switch ($(this).val()) { @@ -19,6 +19,7 @@ $(function() { }); $root.find('select.action').change(function() { var action = $(this).val(); + if (!action) return; var ids = []; $root.find('input[name=threads]:checked').each(function() { return ids.push(this.value); @@ -34,15 +35,16 @@ $(function() { var presets = window.lichess_mod_presets; if (presets) { - var toggle = $root.find('input[name=mod]'); - var select = $root.find('select[name=preset]'); + var toggle = $('#form3-mod'); + var select = $('#form3-preset'); + select.append(''); presets.forEach(function(p, i) { select.append(''); }); select.on('change', function() { var p = presets[$(this).val()] || ['', '']; - $root.find('input[name=subject]').val(p[0]); - $root.find('textarea[name=text]').val(p[1]); + $('#form3-subject').val(p[0]); + $('#form3-text').val(p[1]); }); var toggleSelect = function() { diff --git a/public/javascripts/music/lobby.js b/public/javascripts/music/lobby.js deleted file mode 100644 index 3aa1d96c13..0000000000 --- a/public/javascripts/music/lobby.js +++ /dev/null @@ -1,61 +0,0 @@ -function lichessLobbyMusic() { - - var orchestra; - - lichess.loadScript('javascripts/music/orchestra.js').then(function() { - orchestra = lichessOrchestra(); - }); - - // 1200 -> 0 - // 2200 -> 23 - var ratingToPitch = function(rating) { - return Math.round((rating - 1200) / 1000 * 23); - } - - var newHook = function(data) { - var pitch = ratingToPitch(data.rating); - var instrument; - switch (data.perf) { - case 'Blitz': - instrument = 'clav'; - break; - case 'Bullet': - case 'Classical': - instrument = 'celesta'; - break; - default: - instrument = 'swells'; - break; - } - orchestra.play(instrument, pitch); - }; - - if (lichess.once('lobby-music')) lichess.shepherd(function(theme) { - var tour = new Shepherd.Tour({ - defaults: { - classes: theme, - scrollTo: false - } - }); - tour.addStep('music', { - title: 'Music from lichess seeks', - text: "Blitz seeks play the clavier.
    " + - "Classical and bullet play celesta.
    " + - "Variants play the swells.
    " + - "Rating determines the pitch.", - attachTo: '#hooks_wrap left', - buttons: [{ - text: 'OK', - action: tour.next - }], - }); - tour.start(); - }); - - return { - receive: function(type, data) { - if (!orchestra) return; - if (type === 'had' && data.rating) newHook(data); - } - }; -}; diff --git a/public/javascripts/music/play.js b/public/javascripts/music/play.js index bbecccd4ad..384c2d241d 100644 --- a/public/javascripts/music/play.js +++ b/public/javascripts/music/play.js @@ -14,16 +14,16 @@ lichess.playMusic = function() { }; var hasCastle = function(san) { - return san.indexOf('O-O') === 0; + return san.startsWith('O-O'); }; var hasCheck = function(san) { - return san.indexOf('+') !== -1; + return san.includes('+'); }; var hasMate = function(san) { - return san.indexOf('#') !== -1; + return san.includes('#'); }; var hasCapture = function(san) { - return san.indexOf('x') !== -1; + return san.includes('x'); }; // a -> 0 diff --git a/public/javascripts/music/replay.js b/public/javascripts/music/replay.js index 93a0e95144..02561bce6c 100644 --- a/public/javascripts/music/replay.js +++ b/public/javascripts/music/replay.js @@ -14,16 +14,16 @@ function lichessReplayMusic() { }; var hasCastle = function(san) { - return san.indexOf('O-O') === 0; + return san.startsWith('O-O'); }; var hasCheck = function(san) { - return san.indexOf('+') !== -1; + return san.includes('+'); }; var hasMate = function(san) { - return san.indexOf('#') !== -1; + return san.includes('#'); }; var hasCapture = function(san) { - return san.indexOf('x') !== -1; + return san.includes('x'); }; // a -> 0 diff --git a/public/javascripts/plan.js b/public/javascripts/plan.js index 8fd2baaca6..618e9285e5 100644 --- a/public/javascripts/plan.js +++ b/public/javascripts/plan.js @@ -1,6 +1,6 @@ $(function() { - $table = $('div.plan table.all'); + $table = $('.plan table.all'); $change = $table.find('.change'); $change.find('a').click(function() { var f = $(this).data('form'); diff --git a/public/javascripts/search.js b/public/javascripts/search.js index 20ce6afb39..71e623bf9e 100644 --- a/public/javascripts/search.js +++ b/public/javascripts/search.js @@ -1,14 +1,14 @@ $(function() { - var $form = $("form.search"); + var $form = $(".search__form"); var $usernames = $form.find(".usernames input"); - var $userRows = $form.find(".user_row"); - var $result = $(".search_result"); + var $userRows = $form.find(".user-row"); + var $result = $(".search__result"); function getUsernames() { var us = []; $usernames.each(function() { - var u = $.trim($(this).val()); + var u = $(this).val().trim(); if (u) us.push(u); }); return us; @@ -63,14 +63,14 @@ $(function() { var s = $(this).hasClass('download') ? serialize(true) : serialized; $(this).attr("href", $(this).attr("href").split('?')[0] + "?" + s); }); - $result.find('.search_infinitescroll').each(function() { + $result.find('.search__rows').each(function() { var $next = $(this).find(".pager a"); if (!$next.length) return; $next.attr("href", $next.attr("href") + "&" + serialized); $(this).infinitescroll({ navSelector: ".pager", nextSelector: $next, - itemSelector: ".search_infinitescroll .paginated", + itemSelector: ".search__rows .paginated", loading: { msgText: "", finishedMsg: "---" @@ -83,21 +83,6 @@ $(function() { $form.submit(function() { $form.find("input,select").filter(function() { return !this.value; }).attr("disabled", "disabled"); - $(this).addClass('searching'); - }); - - if ($form.hasClass('realtime')) { - var submit = function() { - $form.submit(); - }; - $form.find("select, input[type=checkbox]").change(submit); - $usernames.on("keyup", lichess.fp.debounce(submit, 1500)); - } - - $("form.search .flatpickr").flatpickr({ - maxDate: 'today', - dateFormat: 'Z', - altInput: true, - altFormat: 'Y-m-d h:i K' + $form.addClass('searching'); }); }); diff --git a/public/javascripts/signup.js b/public/javascripts/signup.js index 0fc4676a2e..4693fbf552 100644 --- a/public/javascripts/signup.js +++ b/public/javascripts/signup.js @@ -1,7 +1,7 @@ $(function() { var $form = $('.signup_box form'); var $exists = $form.find('.username .exists'); - var runCheck = lichess.fp.debounce(function() { + var runCheck = lichess.debounce(function() { var name = $username.val(); if (name.length >= 3) $.ajax({ method: 'GET', diff --git a/public/javascripts/study/tour-chapter.js b/public/javascripts/study/tour-chapter.js index c2cd6895f1..11ecc714f6 100644 --- a/public/javascripts/study/tour-chapter.js +++ b/public/javascripts/study/tour-chapter.js @@ -1,5 +1,15 @@ +function loadShepherd(f) { + var theme = 'shepherd-theme-' + ($('body').hasClass('dark') ? 'default' : 'dark'); + lichess.loadCss('vendor/shepherd/dist/css/' + theme + '.css'); + lichess.loadCss('stylesheets/shepherd.css'); + lichess.loadScript('vendor/shepherd/dist/js/tether.js', {noVersion:true}).done(function() { + lichess.loadScript('vendor/shepherd/dist/js/shepherd.min.js', {noVersion:true}).done(function() { + f(theme); + }); + }); +}; lichess.studyTourChapter = function(study) { - lichess.shepherd(function(theme) { + loadShepherd(function(theme) { var onTab = function(tab) { return { 'before-show': function() { @@ -19,44 +29,44 @@ lichess.studyTourChapter = function(study) { text: "A study can have several chapters.
    " + "Each chapter has a distinct move tree,
    " + "and can be created in various ways.", - attachTo: '.study_overboard label[for=chapter-name] left' + attachTo: '.study__modal label[for=chapter-name] left' }, { title: "From initial position", text: "Just a board setup for a new game.
    " + "Suited to explore openings.", - attachTo: '.study_overboard .study_tabs .init top', + attachTo: '.study__modal .tabs-horiz .init top', when: onTab('init') }, { title: "Custom position", text: "Setup the board your way.
    " + "Suited to explore endgames.", - attachTo: '.study_overboard .study_tabs .edit bottom', + attachTo: '.study__modal .tabs-horiz .edit bottom', when: onTab('edit') }, { title: "Load an existing lichess game", text: "Paste a lichess game URL
    " + "(like lichess.org/7fHIU0XI)
    " + "to load the game moves in the chapter.", - attachTo: '.study_overboard .study_tabs .game top', + attachTo: '.study__modal .tabs-horiz .game top', when: onTab('game') }, { title: "From a FEN string", text: "Paste a position in FEN format
    " + "4k3/4rb2/8/7p/8/5Q2/1PP5/1K6 w
    " + "to start the chapter from a position.", - attachTo: '.study_overboard .study_tabs .fen top', + attachTo: '.study__modal .tabs-horiz .fen top', when: onTab('fen') }, { title: "From a PGN game", text: "Paste a game in PGN format.
    " + "to load moves, comments and variations in the chapter.", - attachTo: '.study_overboard .study_tabs .pgn top', + attachTo: '.study__modal .tabs-horiz .pgn top', when: onTab('pgn') }, { title: "Studies support variants", text: "Yes, you can study crazyhouse,
    " + "and all lichess variants!", - attachTo: '.study_overboard label[for=chapter-variant] left', + attachTo: '.study__modal label[for=chapter-variant] left', when: onTab('init') }, { title: "Thanks for your time", @@ -66,7 +76,7 @@ lichess.studyTourChapter = function(study) { text: 'Done', action: tour.next }], - attachTo: '.study_overboard .help bottom' + attachTo: '.study__modal .help bottom' }].forEach(function(s) { tour.addStep(s.title, s); }); diff --git a/public/javascripts/study/tour.js b/public/javascripts/study/tour.js index 80b790ec56..a4a80e40be 100644 --- a/public/javascripts/study/tour.js +++ b/public/javascripts/study/tour.js @@ -1,5 +1,15 @@ +function loadShepherd(f) { + var theme = 'shepherd-theme-' + ($('body').hasClass('dark') ? 'default' : 'dark'); + lichess.loadCss('vendor/shepherd/dist/css/' + theme + '.css'); + lichess.loadCss('stylesheets/shepherd.css'); + lichess.loadScript('vendor/shepherd/dist/js/tether.js', {noVersion:true}).done(function() { + lichess.loadScript('vendor/shepherd/dist/js/shepherd.min.js', {noVersion:true}).done(function() { + f(theme); + }); + }); +}; lichess.studyTour = function(study) { - lichess.shepherd(function(theme) { + loadShepherd(function(theme) { var onTab = function(tab) { return { 'before-show': function() { @@ -15,64 +25,64 @@ lichess.studyTour = function(study) { } }); [{ - title: "Welcome to lichess study!", - text: "This is a shared analysis board.

    " + - "Use it to analyse and annotate games,
    " + - "discuss positions with friends,
    " + - "and of course for chess lessons!

    " + - "It's a powerful tool, let's take some time to see how it works.", - attachTo: "#lichess .analyse .help top" - }, { - title: "Shared and saved", - text: "Other members can see your moves in real time!
    " + - "Plus, everything is saved forever.", - attachTo: "#lichess .analyse .areplay left" - }, { - title: "Study members", - text: " Spectators can view the study and talk in the chat.
    " + - "
    Contributors can make moves and update the study.", - attachTo: "#site_header .study_box right", - when: onTab('members') - }, - study.isContrib ? { + title: "Welcome to lichess study!", + text: "This is a shared analysis board.

    " + + "Use it to analyse and annotate games,
    " + + "discuss positions with friends,
    " + + "and of course for chess lessons!

    " + + "It's a powerful tool, let's take some time to see how it works.", + attachTo: "main.analyse .study__buttons .help top" + }, { + title: "Shared and saved", + text: "Other members can see your moves in real time!
    " + + "Plus, everything is saved forever.", + attachTo: "main.analyse .areplay left" + }, { + title: "Study members", + text: " Spectators can view the study and talk in the chat.
    " + + "
    Contributors can make moves and update the study.", + attachTo: ".study__members right", + when: onTab('members') + }, + study.isOwner ? { title: "Invite members", text: "By clicking the button.
    " + - "Then decide who can contribute or not.", - attachTo: "#site_header .study_box .add right", + "Then decide who can contribute or not.", + attachTo: ".study__members .add right", when: onTab('members') } : null, { title: "Study chapters", text: "A study can contain several chapters.
    " + - "Each chapter has a distinct initial position and move tree.", - attachTo: "#site_header .study_box right", + "Each chapter has a distinct initial position and move tree.", + attachTo: ".study__chapters right", when: onTab('chapters') }, study.isContrib ? { title: "Create new chapters", text: "By clicking the button.", - attachTo: "#site_header .study_box .add right", + attachTo: ".study__chapters .add right", when: onTab('chapters') } : null, study.isContrib ? { title: "Comment on a position", text: "With the button, or a right click on the move list on the right.
    " + - "Comments are shared and persisted.", - attachTo: "#lichess .member_buttons .comments top" + "Comments are shared and persisted.", + attachTo: ".study__buttons .left-buttons .comments top" } : null, study.isContrib ? { title: "Annotate a position", text: "With the !? button, or a right click on the move list on the right.
    " + - "Annotation glyphs are shared and persisted.", - attachTo: "#lichess .member_buttons .glyphs top" + "Annotation glyphs are shared and persisted.", + attachTo: ".study__buttons .left-buttons .glyphs top" } : null, { title: "Thanks for your time", text: "You can find your previous studies from your profile page.
    " + - "There is also a blog post about studies.
    " + - "Power users might want to press \"?\" to see keyboard shortcuts.
    " + - "Have fun!", + "There is also a blog post about studies.
    " + + "Power users might want to press \"?\" to see keyboard shortcuts.
    " + + "Have fun!", buttons: [{ text: 'Done', action: tour.next }], - attachTo: "#lichess .analyse .help top" + attachTo: "main.analyse .study__buttons .help top" } ].filter(function(v) { return v; diff --git a/public/javascripts/tournamentForm.js b/public/javascripts/tournamentForm.js index fe1db86ca7..d31c42e571 100644 --- a/public/javascripts/tournamentForm.js +++ b/public/javascripts/tournamentForm.js @@ -8,12 +8,12 @@ $(function() { $variant.on('change', showPosition); showPosition(); - $('form.create .conditions a.show').on('click', function() { + $('.tour__form .conditions a.show').on('click', function() { $(this).remove(); - $('form.create .conditions').addClass('visible'); + $('.tour__form .conditions').addClass('visible'); }); - $("form.create .flatpickr").flatpickr({ + $(".tour__form .flatpickr").flatpickr({ minDate: 'today', maxDate: new Date(Date.now() + 1000 * 3600 * 24 * 31), dateFormat: 'Z', diff --git a/public/javascripts/vendor/chessground.min.js b/public/javascripts/vendor/chessground.min.js index 84141db211..8e3cb31e00 100644 --- a/public/javascripts/vendor/chessground.min.js +++ b/public/javascripts/vendor/chessground.min.js @@ -1 +1 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Chessground=e()}}(function(){return function i(a,s,c){function l(t,e){if(!s[t]){if(!a[t]){var r="function"==typeof require&&require;if(!e&&r)return r(t,!0);if(u)return u(t,!0);var n=new Error("Cannot find module '"+t+"'");throw n.code="MODULE_NOT_FOUND",n}var o=s[t]={exports:{}};a[t][0].call(o.exports,function(e){return l(a[t][1][e]||e)},o,o.exports,i,a,s,c)}return s[t].exports}for(var u="function"==typeof require&&require,e=0;e=Math.pow(a.draggable.distance,2)&&(e.started=!0),e.started){if("function"==typeof e.element){var r=e.element();if(!r)return;e.element=r,e.element.cgDragging=!0,e.element.classList.add("dragging")}var n="white"===a.orientation,o=a.dom.bounds();e.pos=[e.epos[0]-e.rel[0],e.epos[1]-e.rel[1]];var i=g.posToTranslateAbs(o)(e.origPos,n);i[0]+=e.pos[0]+e.dec[0],i[1]+=e.pos[1]+e.dec[1],g.translateAbs(e.element,i)}}else s(a);m(a)}})}function s(e){var t=e.draggable.current;t&&(t.newPiece&&delete e.pieces[t.orig],e.draggable.current=void 0,v.unselect(e),i(e),e.dom.redraw())}function i(e){var t=e.dom.elements;t.ghost&&g.setVisible(t.ghost,!1)}function y(e,t,r){var n=g.key2pos(e);return t||(n[0]=9-n[0],n[1]=9-n[1]),{left:r.left+r.width*(n[0]-1)/8,top:r.top+r.height*(8-n[1])/8,width:r.width/8,height:r.height/8}}function w(e,t){for(var r=e.dom.elements.board.firstChild;r;){if(r.cgKey===t&&"PIECE"===r.tagName)return r;r=r.nextSibling}}r.start=function(e,t){if(!(void 0!==t.button&&0!==t.button||t.touches&&1=Math.pow(a.draggable.distance,2)&&(e.started=!0),e.started){if("function"==typeof e.element){var r=e.element();if(!r)return;e.element=r,e.element.cgDragging=!0,e.element.classList.add("dragging")}var n="white"===a.orientation,o=a.dom.bounds();e.pos=[e.epos[0]-e.rel[0],e.epos[1]-e.rel[1]];var i=h.posToTranslateAbs(o)(e.origPos,n);i[0]+=e.pos[0]+e.dec[0],i[1]+=e.pos[1]+e.dec[1],h.translateAbs(e.element,i)}}else s(a);m(a)}})}function s(e){var t=e.draggable.current;t&&(t.newPiece&&delete e.pieces[t.orig],e.draggable.current=void 0,v.unselect(e),i(e),e.dom.redraw())}function i(e){var t=e.dom.elements;t.ghost&&h.setVisible(t.ghost,!1)}function y(e,t,r){var n=h.key2pos(e);return t||(n[0]=9-n[0],n[1]=9-n[1]),{left:r.left+r.width*(n[0]-1)/8,top:r.top+r.height*(8-n[1])/8,width:r.width/8,height:r.height/8}}function w(e,t){for(var r=e.dom.elements.board.firstChild;r;){if(r.cgKey===t&&"PIECE"===r.tagName)return r;r=r.nextSibling}}r.start=function(e,t){if(!(void 0!==t.button&&0!==t.button||t.touches&&1a;a++)for(s in o[a])n=o[a][s],o[a].hasOwnProperty(s)&&void 0!==n&&(e[s]=t.isPlainObject(n)?t.isPlainObject(e[s])?t.widget.extend({},e[s],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,s){var n=s.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=i.call(arguments,1),l=this;return a?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(l=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(l=i&&i.jquery?l.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new s(o,this))})),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
    ",options:{classes:{},disabled:!1,create:null},_createWidget:function(i,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=e++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),i),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var l=s.match(/^([\w:-]*)\s*(.*)$/),h=l[1]+o.eventNamespace,c=l[2];c?n.on(h,c,r):i.on(h,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var s=!1;t(document).on("mouseup",function(){s=!1}),t.widget("ui.mouse",{version:"1.12.0",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!s){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,n=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return n&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),s=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,s=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.widget("ui.slider",t.ui.mouse,{version:"1.12.0",widgetEventPrefix:"slide",options:{animate:!1,classes:{"ui-slider":"ui-corner-all","ui-slider-handle":"ui-corner-all","ui-slider-range":"ui-corner-all ui-widget-header"},distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},numPages:5,_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this._calculateNewMax(),this._addClass("ui-slider ui-slider-"+this.orientation,"ui-widget ui-widget-content"),this._refresh(),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var e,i,s=this.options,n=this.element.find(".ui-slider-handle"),o="",a=[];for(i=s.values&&s.values.length||1,n.length>i&&(n.slice(i).remove(),n=n.slice(0,i)),e=n.length;i>e;e++)a.push(o);this.handles=n.add(t(a.join("")).appendTo(this.element)),this._addClass(this.handles,"ui-slider-handle","ui-state-default"),this.handle=this.handles.eq(0),this.handles.each(function(e){t(this).data("ui-slider-handle-index",e)})},_createRange:function(){var e=this.options;e.range?(e.range===!0&&(e.values?e.values.length&&2!==e.values.length?e.values=[e.values[0],e.values[0]]:t.isArray(e.values)&&(e.values=e.values.slice(0)):e.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?(this._removeClass(this.range,"ui-slider-range-min ui-slider-range-max"),this.range.css({left:"",bottom:""})):(this.range=t("
    ").appendTo(this.element),this._addClass(this.range,"ui-slider-range")),("min"===e.range||"max"===e.range)&&this._addClass(this.range,"ui-slider-range-"+e.range)):(this.range&&this.range.remove(),this.range=null)},_setupEvents:function(){this._off(this.handles),this._on(this.handles,this._handleEvents),this._hoverable(this.handles),this._focusable(this.handles)},_destroy:function(){this.handles.remove(),this.range&&this.range.remove(),this._mouseDestroy()},_mouseCapture:function(e){var i,s,n,o,a,r,l,h,c=this,u=this.options;return u.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:e.pageX,y:e.pageY},s=this._normValueFromMouse(i),n=this._valueMax()-this._valueMin()+1,this.handles.each(function(e){var i=Math.abs(s-c.values(e));(n>i||n===i&&(e===c._lastChangedValue||c.values(e)===u.min))&&(n=i,o=t(this),a=e)}),r=this._start(e,a),r===!1?!1:(this._mouseSliding=!0,this._handleIndex=a,this._addClass(o,null,"ui-state-active"),o.trigger("focus"),l=o.offset(),h=!t(e.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=h?{left:0,top:0}:{left:e.pageX-l.left-o.width()/2,top:e.pageY-l.top-o.height()/2-(parseInt(o.css("borderTopWidth"),10)||0)-(parseInt(o.css("borderBottomWidth"),10)||0)+(parseInt(o.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(e,a,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(t){var e={x:t.pageX,y:t.pageY},i=this._normValueFromMouse(e);return this._slide(t,this._handleIndex,i),!1},_mouseStop:function(t){return this._removeClass(this.handles,null,"ui-state-active"),this._mouseSliding=!1,this._stop(t,this._handleIndex),this._change(t,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(t){var e,i,s,n,o;return"horizontal"===this.orientation?(e=this.elementSize.width,i=t.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(e=this.elementSize.height,i=t.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/e,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),n=this._valueMax()-this._valueMin(),o=this._valueMin()+s*n,this._trimAlignValue(o)},_uiHash:function(t,e,i){var s={handle:this.handles[t],handleIndex:t,value:void 0!==e?e:this.value()};return this._hasMultipleValues()&&(s.value=void 0!==e?e:this.values(t),s.values=i||this.values()),s},_hasMultipleValues:function(){return this.options.values&&this.options.values.length},_start:function(t,e){return this._trigger("start",t,this._uiHash(e))},_slide:function(t,e,i){var s,n,o=this.value(),a=this.values();this._hasMultipleValues()&&(n=this.values(e?0:1),o=this.values(e),2===this.options.values.length&&this.options.range===!0&&(i=0===e?Math.min(n,i):Math.max(n,i)),a[e]=i),i!==o&&(s=this._trigger("slide",t,this._uiHash(e,i,a)),s!==!1&&(this._hasMultipleValues()?this.values(e,i):this.value(i)))},_stop:function(t,e){this._trigger("stop",t,this._uiHash(e))},_change:function(t,e){this._keySliding||this._mouseSliding||(this._lastChangedValue=e,this._trigger("change",t,this._uiHash(e)))},value:function(t){return arguments.length?(this.options.value=this._trimAlignValue(t),this._refreshValue(),this._change(null,0),void 0):this._value()},values:function(e,i){var s,n,o;if(arguments.length>1)return this.options.values[e]=this._trimAlignValue(i),this._refreshValue(),this._change(null,e),void 0;if(!arguments.length)return this._values();if(!t.isArray(arguments[0]))return this._hasMultipleValues()?this._values(e):this.value();for(s=this.options.values,n=arguments[0],o=0;s.length>o;o+=1)s[o]=this._trimAlignValue(n[o]),this._change(null,o);this._refreshValue()},_setOption:function(e,i){var s,n=0;switch("range"===e&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),t.isArray(this.options.values)&&(n=this.options.values.length),this._super(e,i),e){case"orientation":this._detectOrientation(),this._removeClass("ui-slider-horizontal ui-slider-vertical")._addClass("ui-slider-"+this.orientation),this._refreshValue(),this.options.range&&this._refreshRange(i),this.handles.css("horizontal"===i?"bottom":"left","");break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=n-1;s>=0;s--)this._change(null,s);this._animateOff=!1;break;case"step":case"min":case"max":this._animateOff=!0,this._calculateNewMax(),this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_setOptionDisabled:function(t){this._super(t),this._toggleClass(null,"ui-state-disabled",!!t)},_value:function(){var t=this.options.value;return t=this._trimAlignValue(t)},_values:function(t){var e,i,s;if(arguments.length)return e=this.options.values[t],e=this._trimAlignValue(e);if(this._hasMultipleValues()){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(t){if(this._valueMin()>=t)return this._valueMin();if(t>=this._valueMax())return this._valueMax();var e=this.options.step>0?this.options.step:1,i=(t-this._valueMin())%e,s=t-i;return 2*Math.abs(i)>=e&&(s+=i>0?e:-e),parseFloat(s.toFixed(5))},_calculateNewMax:function(){var t=this.options.max,e=this._valueMin(),i=this.options.step,s=Math.round((t-e)/i)*i;t=s+e,t>this.options.max&&(t-=i),this.max=parseFloat(t.toFixed(this._precision()))},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_valueMin:function(){return this.options.min},_valueMax:function(){return this.max},_refreshRange:function(t){"vertical"===t&&this.range.css({width:"",left:""}),"horizontal"===t&&this.range.css({height:"",bottom:""})},_refreshValue:function(){var e,i,s,n,o,a=this.options.range,r=this.options,l=this,h=this._animateOff?!1:r.animate,c={};this._hasMultipleValues()?this.handles.each(function(s){i=100*((l.values(s)-l._valueMin())/(l._valueMax()-l._valueMin())),c["horizontal"===l.orientation?"left":"bottom"]=i+"%",t(this).stop(1,1)[h?"animate":"css"](c,r.animate),l.options.range===!0&&("horizontal"===l.orientation?(0===s&&l.range.stop(1,1)[h?"animate":"css"]({left:i+"%"},r.animate),1===s&&l.range[h?"animate":"css"]({width:i-e+"%"},{queue:!1,duration:r.animate})):(0===s&&l.range.stop(1,1)[h?"animate":"css"]({bottom:i+"%"},r.animate),1===s&&l.range[h?"animate":"css"]({height:i-e+"%"},{queue:!1,duration:r.animate}))),e=i}):(s=this.value(),n=this._valueMin(),o=this._valueMax(),i=o!==n?100*((s-n)/(o-n)):0,c["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[h?"animate":"css"](c,r.animate),"min"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({width:i+"%"},r.animate),"max"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({width:100-i+"%"},r.animate),"min"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({height:i+"%"},r.animate),"max"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({height:100-i+"%"},r.animate))},_handleEvents:{keydown:function(e){var i,s,n,o,a=t(e.target).data("ui-slider-handle-index");switch(e.keyCode){case t.ui.keyCode.HOME:case t.ui.keyCode.END:case t.ui.keyCode.PAGE_UP:case t.ui.keyCode.PAGE_DOWN:case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(e.preventDefault(),!this._keySliding&&(this._keySliding=!0,this._addClass(t(e.target),null,"ui-state-active"),i=this._start(e,a),i===!1))return}switch(o=this.options.step,s=n=this._hasMultipleValues()?this.values(a):this.value(),e.keyCode){case t.ui.keyCode.HOME:n=this._valueMin();break;case t.ui.keyCode.END:n=this._valueMax();break;case t.ui.keyCode.PAGE_UP:n=this._trimAlignValue(s+(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.PAGE_DOWN:n=this._trimAlignValue(s-(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:if(s===this._valueMax())return;n=this._trimAlignValue(s+o);break;case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(s===this._valueMin())return;n=this._trimAlignValue(s-o)}this._slide(e,a,n)},keyup:function(e){var i=t(e.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(e,i),this._change(e,i),this._removeClass(t(e.target),null,"ui-state-active"))}}})}); \ No newline at end of file +(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){t.ui=t.ui||{},t.ui.version="1.12.0";var e=0,i=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},l=e.split(".")[0];e=e.split(".")[1];var h=l+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][h.toLowerCase()]=function(e){return!!t.data(e,h)},t[l]=t[l]||{},n=t[l][e],o=t[l][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(r[e]=s,void 0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:l,widgetName:e,widgetFullName:h}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var s,n,o=i.call(arguments,1),a=0,r=o.length;r>a;a++)for(s in o[a])n=o[a][s],o[a].hasOwnProperty(s)&&void 0!==n&&(e[s]=t.isPlainObject(n)?t.isPlainObject(e[s])?t.widget.extend({},e[s],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,s){var n=s.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=i.call(arguments,1),l=this;return a?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(l=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(l=i&&i.jquery?l.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new s(o,this))})),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
    ",options:{classes:{},disabled:!1,create:null},_createWidget:function(i,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=e++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),i),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var l=s.match(/^([\w:-]*)\s*(.*)$/),h=l[1]+o.eventNamespace,c=l[2];c?n.on(h,c,r):i.on(h,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var s=!1;t(document).on("mouseup",function(){s=!1}),t.widget("ui.mouse",{version:"1.12.0",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!s){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,n=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return n&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),s=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,s=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.widget("ui.slider",t.ui.mouse,{version:"1.12.0",widgetEventPrefix:"slide",options:{animate:!1,classes:{"ui-slider":"ui-corner-all","ui-slider-handle":"ui-corner-all","ui-slider-range":"ui-corner-all ui-widget-header"},distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},numPages:5,_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this._calculateNewMax(),this._addClass("ui-slider ui-slider-"+this.orientation,"ui-widget ui-widget-content"),this._refresh(),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var e,i,s=this.options,n=this.element.find(".ui-slider-handle"),o="",a=[];for(i=s.values&&s.values.length||1,n.length>i&&(n.slice(i).remove(),n=n.slice(0,i)),e=n.length;i>e;e++)a.push(o);this.handles=n.add(t(a.join("")).appendTo(this.element)),this._addClass(this.handles,"ui-slider-handle","ui-state-default"),this.handle=this.handles.eq(0),this.handles.each(function(e){t(this).data("ui-slider-handle-index",e)})},_createRange:function(){var e=this.options;e.range?(e.range===!0&&(e.values?e.values.length&&2!==e.values.length?e.values=[e.values[0],e.values[0]]:t.isArray(e.values)&&(e.values=e.values.slice(0)):e.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?(this._removeClass(this.range,"ui-slider-range-min ui-slider-range-max"),this.range.css({left:"",bottom:""})):(this.range=t("
    ").appendTo(this.element),this._addClass(this.range,"ui-slider-range")),("min"===e.range||"max"===e.range)&&this._addClass(this.range,"ui-slider-range-"+e.range)):(this.range&&this.range.remove(),this.range=null)},_setupEvents:function(){this._off(this.handles),this._on(this.handles,this._handleEvents),this._hoverable(this.handles),this._focusable(this.handles)},_destroy:function(){this.handles.remove(),this.range&&this.range.remove(),this._mouseDestroy()},_mouseCapture:function(e){var i,s,n,o,a,r,l,h,c=this,u=this.options;return u.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:e.pageX,y:e.pageY},s=this._normValueFromMouse(i),n=this._valueMax()-this._valueMin()+1,this.handles.each(function(e){var i=Math.abs(s-c.values(e));(n>i||n===i&&(e===c._lastChangedValue||c.values(e)===u.min))&&(n=i,o=t(this),a=e)}),r=this._start(e,a),r===!1?!1:(this._mouseSliding=!0,this._handleIndex=a,this._addClass(o,null,"ui-state-active"),o.trigger("focus"),l=o.offset(),h=!t(e.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=h?{left:0,top:0}:{left:e.pageX-l.left-o.width()/2,top:e.pageY-l.top-o.height()/2-(parseInt(o.css("borderTopWidth"),10)||0)-(parseInt(o.css("borderBottomWidth"),10)||0)+(parseInt(o.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(e,a,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(t){var e={x:t.pageX,y:t.pageY},i=this._normValueFromMouse(e);return this._slide(t,this._handleIndex,i),!1},_mouseStop:function(t){return this._removeClass(this.handles,null,"ui-state-active"),this._mouseSliding=!1,this._stop(t,this._handleIndex),this._change(t,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(t){var e,i,s,n,o;return"horizontal"===this.orientation?(e=this.elementSize.width,i=t.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(e=this.elementSize.height,i=t.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/e,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),n=this._valueMax()-this._valueMin(),o=this._valueMin()+s*n,this._trimAlignValue(o)},_uiHash:function(t,e,i){var s={handle:this.handles[t],handleIndex:t,value:void 0!==e?e:this.value()};return this._hasMultipleValues()&&(s.value=void 0!==e?e:this.values(t),s.values=i||this.values()),s},_hasMultipleValues:function(){return this.options.values&&this.options.values.length},_start:function(t,e){return this._trigger("start",t,this._uiHash(e))},_slide:function(t,e,i){var s,n,o=this.value(),a=this.values();this._hasMultipleValues()&&(n=this.values(e?0:1),o=this.values(e),2===this.options.values.length&&this.options.range===!0&&(i=0===e?Math.min(n,i):Math.max(n,i)),a[e]=i),i!==o&&(s=this._trigger("slide",t,this._uiHash(e,i,a)),s!==!1&&(this._hasMultipleValues()?this.values(e,i):this.value(i)))},_stop:function(t,e){this._trigger("stop",t,this._uiHash(e))},_change:function(t,e){this._keySliding||this._mouseSliding||(this._lastChangedValue=e,this._trigger("change",t,this._uiHash(e)))},value:function(t){return arguments.length?(this.options.value=this._trimAlignValue(t),this._refreshValue(),this._change(null,0),void 0):this._value()},values:function(e,i){var s,n,o;if(arguments.length>1)return this.options.values[e]=this._trimAlignValue(i),this._refreshValue(),this._change(null,e),void 0;if(!arguments.length)return this._values();if(!t.isArray(arguments[0]))return this._hasMultipleValues()?this._values(e):this.value();for(s=this.options.values,n=arguments[0],o=0;s.length>o;o+=1)s[o]=this._trimAlignValue(n[o]),this._change(null,o);this._refreshValue()},_setOption:function(e,i){var s,n=0;switch("range"===e&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),t.isArray(this.options.values)&&(n=this.options.values.length),this._super(e,i),e){case"orientation":this._detectOrientation(),this._removeClass("ui-slider-horizontal ui-slider-vertical")._addClass("ui-slider-"+this.orientation),this._refreshValue(),this.options.range&&this._refreshRange(i),this.handles.css("horizontal"===i?"bottom":"left","");break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=n-1;s>=0;s--)this._change(null,s);this._animateOff=!1;break;case"step":case"min":case"max":this._animateOff=!0,this._calculateNewMax(),this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_setOptionDisabled:function(t){this._super(t),this._toggleClass(null,"ui-state-disabled",!!t)},_value:function(){var t=this.options.value;return t=this._trimAlignValue(t)},_values:function(t){var e,i,s;if(arguments.length)return e=this.options.values[t],e=this._trimAlignValue(e);if(this._hasMultipleValues()){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(t){if(this._valueMin()>=t)return this._valueMin();if(t>=this._valueMax())return this._valueMax();var e=this.options.step>0?this.options.step:1,i=(t-this._valueMin())%e,s=t-i;return 2*Math.abs(i)>=e&&(s+=i>0?e:-e),parseFloat(s.toFixed(5))},_calculateNewMax:function(){var t=this.options.max,e=this._valueMin(),i=this.options.step,s=Math.round((t-e)/i)*i;t=s+e,t>this.options.max&&(t-=i),this.max=parseFloat(t.toFixed(this._precision()))},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_valueMin:function(){return this.options.min},_valueMax:function(){return this.max},_refreshRange:function(t){"vertical"===t&&this.range.css({width:"",left:""}),"horizontal"===t&&this.range.css({height:"",bottom:""})},_refreshValue:function(){var e,i,s,n,o,a=this.options.range,r=this.options,l=this,h=this._animateOff?!1:r.animate,c={};this._hasMultipleValues()?this.handles.each(function(s){i=100*((l.values(s)-l._valueMin())/(l._valueMax()-l._valueMin())),c["horizontal"===l.orientation?"left":"bottom"]=i+"%",t(this).stop(1,1)[h?"animate":"css"](c,r.animate),l.options.range===!0&&("horizontal"===l.orientation?(0===s&&l.range.stop(1,1)[h?"animate":"css"]({left:i+"%"},r.animate),1===s&&l.range[h?"animate":"css"]({width:i-e+"%"},{queue:!1,duration:r.animate})):(0===s&&l.range.stop(1,1)[h?"animate":"css"]({bottom:i+"%"},r.animate),1===s&&l.range[h?"animate":"css"]({height:i-e+"%"},{queue:!1,duration:r.animate}))),e=i}):(s=this.value(),n=this._valueMin(),o=this._valueMax(),i=o!==n?100*((s-n)/(o-n)):0,c["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[h?"animate":"css"](c,r.animate),"min"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({width:i+"%"},r.animate),"max"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({width:100-i+"%"},r.animate),"min"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({height:i+"%"},r.animate),"max"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({height:100-i+"%"},r.animate))},_handleEvents:{keydown:function(e){var i,s,n,o,a=t(e.target).data("ui-slider-handle-index");switch(e.keyCode){case t.ui.keyCode.HOME:case t.ui.keyCode.END:case t.ui.keyCode.PAGE_UP:case t.ui.keyCode.PAGE_DOWN:case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(e.preventDefault(),!this._keySliding&&(this._keySliding=!0,this._addClass(t(e.target),null,"ui-state-active"),i=this._start(e,a),i===!1))return}switch(o=this.options.step,s=n=this._hasMultipleValues()?this.values(a):this.value(),e.keyCode){case t.ui.keyCode.HOME:n=this._valueMin();break;case t.ui.keyCode.END:n=this._valueMax();break;case t.ui.keyCode.PAGE_UP:n=this._trimAlignValue(s+(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.PAGE_DOWN:n=this._trimAlignValue(s-(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:if(s===this._valueMax())return;n=this._trimAlignValue(s+o);break;case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(s===this._valueMin())return;n=this._trimAlignValue(s-o)}this._slide(e,a,n)},keyup:function(e){var i=t(e.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(e,i),this._change(e,i),this._removeClass(t(e.target),null,"ui-state-active"))}}})}); diff --git a/public/javascripts/vendor/jquery-ui.slider.touch.min.js b/public/javascripts/vendor/jquery-ui.slider.touch.min.js new file mode 100644 index 0000000000..181bc6974e --- /dev/null +++ b/public/javascripts/vendor/jquery-ui.slider.touch.min.js @@ -0,0 +1,42 @@ +/*! jQuery UI - v1.12.0 - 2016-07-30 + * http://jqueryui.com + * Includes: widget.js, keycode.js, widgets/mouse.js, widgets/slider.js + * Copyright jQuery Foundation and other contributors; Licensed MIT */ + +jQuery.proxy = function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Simulated bind + args = [].slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( [].slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; +}; + +(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){t.ui=t.ui||{},t.ui.version="1.12.0";var e=0,i=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},l=e.split(".")[0];e=e.split(".")[1];var h=l+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][h.toLowerCase()]=function(e){return!!t.data(e,h)},t[l]=t[l]||{},n=t[l][e],o=t[l][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(r[e]=s,void 0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:l,widgetName:e,widgetFullName:h}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var s,n,o=i.call(arguments,1),a=0,r=o.length;r>a;a++)for(s in o[a])n=o[a][s],o[a].hasOwnProperty(s)&&void 0!==n&&(e[s]=t.isPlainObject(n)?t.isPlainObject(e[s])?t.widget.extend({},e[s],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,s){var n=s.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=i.call(arguments,1),l=this;return a?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(l=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(l=i&&i.jquery?l.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new s(o,this))})),l}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"
    ",options:{classes:{},disabled:!1,create:null},_createWidget:function(i,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=e++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),i),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var l=s.match(/^([\w:-]*)\s*(.*)$/),h=l[1]+o.eventNamespace,c=l[2];c?n.on(h,c,r):i.on(h,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var s=!1;t(document).on("mouseup",function(){s=!1}),t.widget("ui.mouse",{version:"1.12.0",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!s){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,n=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return n&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),s=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,s=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.widget("ui.slider",t.ui.mouse,{version:"1.12.0",widgetEventPrefix:"slide",options:{animate:!1,classes:{"ui-slider":"ui-corner-all","ui-slider-handle":"ui-corner-all","ui-slider-range":"ui-corner-all ui-widget-header"},distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null,change:null,slide:null,start:null,stop:null},numPages:5,_create:function(){this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this._calculateNewMax(),this._addClass("ui-slider ui-slider-"+this.orientation,"ui-widget ui-widget-content"),this._refresh(),this._animateOff=!1},_refresh:function(){this._createRange(),this._createHandles(),this._setupEvents(),this._refreshValue()},_createHandles:function(){var e,i,s=this.options,n=this.element.find(".ui-slider-handle"),o="",a=[];for(i=s.values&&s.values.length||1,n.length>i&&(n.slice(i).remove(),n=n.slice(0,i)),e=n.length;i>e;e++)a.push(o);this.handles=n.add(t(a.join("")).appendTo(this.element)),this._addClass(this.handles,"ui-slider-handle","ui-state-default"),this.handle=this.handles.eq(0),this.handles.each(function(e){t(this).data("ui-slider-handle-index",e)})},_createRange:function(){var e=this.options;e.range?(e.range===!0&&(e.values?e.values.length&&2!==e.values.length?e.values=[e.values[0],e.values[0]]:t.isArray(e.values)&&(e.values=e.values.slice(0)):e.values=[this._valueMin(),this._valueMin()]),this.range&&this.range.length?(this._removeClass(this.range,"ui-slider-range-min ui-slider-range-max"),this.range.css({left:"",bottom:""})):(this.range=t("
    ").appendTo(this.element),this._addClass(this.range,"ui-slider-range")),("min"===e.range||"max"===e.range)&&this._addClass(this.range,"ui-slider-range-"+e.range)):(this.range&&this.range.remove(),this.range=null)},_setupEvents:function(){this._off(this.handles),this._on(this.handles,this._handleEvents),this._hoverable(this.handles),this._focusable(this.handles)},_destroy:function(){this.handles.remove(),this.range&&this.range.remove(),this._mouseDestroy()},_mouseCapture:function(e){var i,s,n,o,a,r,l,h,c=this,u=this.options;return u.disabled?!1:(this.elementSize={width:this.element.outerWidth(),height:this.element.outerHeight()},this.elementOffset=this.element.offset(),i={x:e.pageX,y:e.pageY},s=this._normValueFromMouse(i),n=this._valueMax()-this._valueMin()+1,this.handles.each(function(e){var i=Math.abs(s-c.values(e));(n>i||n===i&&(e===c._lastChangedValue||c.values(e)===u.min))&&(n=i,o=t(this),a=e)}),r=this._start(e,a),r===!1?!1:(this._mouseSliding=!0,this._handleIndex=a,this._addClass(o,null,"ui-state-active"),o.trigger("focus"),l=o.offset(),h=!t(e.target).parents().addBack().is(".ui-slider-handle"),this._clickOffset=h?{left:0,top:0}:{left:e.pageX-l.left-o.width()/2,top:e.pageY-l.top-o.height()/2-(parseInt(o.css("borderTopWidth"),10)||0)-(parseInt(o.css("borderBottomWidth"),10)||0)+(parseInt(o.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(e,a,s),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(t){var e={x:t.pageX,y:t.pageY},i=this._normValueFromMouse(e);return this._slide(t,this._handleIndex,i),!1},_mouseStop:function(t){return this._removeClass(this.handles,null,"ui-state-active"),this._mouseSliding=!1,this._stop(t,this._handleIndex),this._change(t,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation="vertical"===this.options.orientation?"vertical":"horizontal"},_normValueFromMouse:function(t){var e,i,s,n,o;return"horizontal"===this.orientation?(e=this.elementSize.width,i=t.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(e=this.elementSize.height,i=t.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),s=i/e,s>1&&(s=1),0>s&&(s=0),"vertical"===this.orientation&&(s=1-s),n=this._valueMax()-this._valueMin(),o=this._valueMin()+s*n,this._trimAlignValue(o)},_uiHash:function(t,e,i){var s={handle:this.handles[t],handleIndex:t,value:void 0!==e?e:this.value()};return this._hasMultipleValues()&&(s.value=void 0!==e?e:this.values(t),s.values=i||this.values()),s},_hasMultipleValues:function(){return this.options.values&&this.options.values.length},_start:function(t,e){return this._trigger("start",t,this._uiHash(e))},_slide:function(t,e,i){var s,n,o=this.value(),a=this.values();this._hasMultipleValues()&&(n=this.values(e?0:1),o=this.values(e),2===this.options.values.length&&this.options.range===!0&&(i=0===e?Math.min(n,i):Math.max(n,i)),a[e]=i),i!==o&&(s=this._trigger("slide",t,this._uiHash(e,i,a)),s!==!1&&(this._hasMultipleValues()?this.values(e,i):this.value(i)))},_stop:function(t,e){this._trigger("stop",t,this._uiHash(e))},_change:function(t,e){this._keySliding||this._mouseSliding||(this._lastChangedValue=e,this._trigger("change",t,this._uiHash(e)))},value:function(t){return arguments.length?(this.options.value=this._trimAlignValue(t),this._refreshValue(),this._change(null,0),void 0):this._value()},values:function(e,i){var s,n,o;if(arguments.length>1)return this.options.values[e]=this._trimAlignValue(i),this._refreshValue(),this._change(null,e),void 0;if(!arguments.length)return this._values();if(!t.isArray(arguments[0]))return this._hasMultipleValues()?this._values(e):this.value();for(s=this.options.values,n=arguments[0],o=0;s.length>o;o+=1)s[o]=this._trimAlignValue(n[o]),this._change(null,o);this._refreshValue()},_setOption:function(e,i){var s,n=0;switch("range"===e&&this.options.range===!0&&("min"===i?(this.options.value=this._values(0),this.options.values=null):"max"===i&&(this.options.value=this._values(this.options.values.length-1),this.options.values=null)),t.isArray(this.options.values)&&(n=this.options.values.length),this._super(e,i),e){case"orientation":this._detectOrientation(),this._removeClass("ui-slider-horizontal ui-slider-vertical")._addClass("ui-slider-"+this.orientation),this._refreshValue(),this.options.range&&this._refreshRange(i),this.handles.css("horizontal"===i?"bottom":"left","");break;case"value":this._animateOff=!0,this._refreshValue(),this._change(null,0),this._animateOff=!1;break;case"values":for(this._animateOff=!0,this._refreshValue(),s=n-1;s>=0;s--)this._change(null,s);this._animateOff=!1;break;case"step":case"min":case"max":this._animateOff=!0,this._calculateNewMax(),this._refreshValue(),this._animateOff=!1;break;case"range":this._animateOff=!0,this._refresh(),this._animateOff=!1}},_setOptionDisabled:function(t){this._super(t),this._toggleClass(null,"ui-state-disabled",!!t)},_value:function(){var t=this.options.value;return t=this._trimAlignValue(t)},_values:function(t){var e,i,s;if(arguments.length)return e=this.options.values[t],e=this._trimAlignValue(e);if(this._hasMultipleValues()){for(i=this.options.values.slice(),s=0;i.length>s;s+=1)i[s]=this._trimAlignValue(i[s]);return i}return[]},_trimAlignValue:function(t){if(this._valueMin()>=t)return this._valueMin();if(t>=this._valueMax())return this._valueMax();var e=this.options.step>0?this.options.step:1,i=(t-this._valueMin())%e,s=t-i;return 2*Math.abs(i)>=e&&(s+=i>0?e:-e),parseFloat(s.toFixed(5))},_calculateNewMax:function(){var t=this.options.max,e=this._valueMin(),i=this.options.step,s=Math.round((t-e)/i)*i;t=s+e,t>this.options.max&&(t-=i),this.max=parseFloat(t.toFixed(this._precision()))},_precision:function(){var t=this._precisionOf(this.options.step);return null!==this.options.min&&(t=Math.max(t,this._precisionOf(this.options.min))),t},_precisionOf:function(t){var e=""+t,i=e.indexOf(".");return-1===i?0:e.length-i-1},_valueMin:function(){return this.options.min},_valueMax:function(){return this.max},_refreshRange:function(t){"vertical"===t&&this.range.css({width:"",left:""}),"horizontal"===t&&this.range.css({height:"",bottom:""})},_refreshValue:function(){var e,i,s,n,o,a=this.options.range,r=this.options,l=this,h=this._animateOff?!1:r.animate,c={};this._hasMultipleValues()?this.handles.each(function(s){i=100*((l.values(s)-l._valueMin())/(l._valueMax()-l._valueMin())),c["horizontal"===l.orientation?"left":"bottom"]=i+"%",t(this).stop(1,1)[h?"animate":"css"](c,r.animate),l.options.range===!0&&("horizontal"===l.orientation?(0===s&&l.range.stop(1,1)[h?"animate":"css"]({left:i+"%"},r.animate),1===s&&l.range[h?"animate":"css"]({width:i-e+"%"},{queue:!1,duration:r.animate})):(0===s&&l.range.stop(1,1)[h?"animate":"css"]({bottom:i+"%"},r.animate),1===s&&l.range[h?"animate":"css"]({height:i-e+"%"},{queue:!1,duration:r.animate}))),e=i}):(s=this.value(),n=this._valueMin(),o=this._valueMax(),i=o!==n?100*((s-n)/(o-n)):0,c["horizontal"===this.orientation?"left":"bottom"]=i+"%",this.handle.stop(1,1)[h?"animate":"css"](c,r.animate),"min"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({width:i+"%"},r.animate),"max"===a&&"horizontal"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({width:100-i+"%"},r.animate),"min"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({height:i+"%"},r.animate),"max"===a&&"vertical"===this.orientation&&this.range.stop(1,1)[h?"animate":"css"]({height:100-i+"%"},r.animate))},_handleEvents:{keydown:function(e){var i,s,n,o,a=t(e.target).data("ui-slider-handle-index");switch(e.keyCode){case t.ui.keyCode.HOME:case t.ui.keyCode.END:case t.ui.keyCode.PAGE_UP:case t.ui.keyCode.PAGE_DOWN:case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(e.preventDefault(),!this._keySliding&&(this._keySliding=!0,this._addClass(t(e.target),null,"ui-state-active"),i=this._start(e,a),i===!1))return}switch(o=this.options.step,s=n=this._hasMultipleValues()?this.values(a):this.value(),e.keyCode){case t.ui.keyCode.HOME:n=this._valueMin();break;case t.ui.keyCode.END:n=this._valueMax();break;case t.ui.keyCode.PAGE_UP:n=this._trimAlignValue(s+(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.PAGE_DOWN:n=this._trimAlignValue(s-(this._valueMax()-this._valueMin())/this.numPages);break;case t.ui.keyCode.UP:case t.ui.keyCode.RIGHT:if(s===this._valueMax())return;n=this._trimAlignValue(s+o);break;case t.ui.keyCode.DOWN:case t.ui.keyCode.LEFT:if(s===this._valueMin())return;n=this._trimAlignValue(s-o)}this._slide(e,a,n)},keyup:function(e){var i=t(e.target).data("ui-slider-handle-index");this._keySliding&&(this._keySliding=!1,this._stop(e,i),this._change(e,i),this._removeClass(t(e.target),null,"ui-state-active"))}}})}); + +/*! + * jQuery UI Touch Punch 0.2.3 + * + * Copyright 2011–2014, Dave Furfero + * Dual licensed under the MIT or GPL Version 2 licenses. + * + * Depends: + * jquery.ui.widget.js + * jquery.ui.mouse.js + * + * Hack: bind->on, unbind->off, $.support + */ +$.support = {}; +!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.on({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.off({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery); diff --git a/public/javascripts/vendor/jquery.hoverIntent.js b/public/javascripts/vendor/jquery.hoverIntent.js deleted file mode 100644 index 0ed4cc4118..0000000000 --- a/public/javascripts/vendor/jquery.hoverIntent.js +++ /dev/null @@ -1,153 +0,0 @@ -/*! - * MODIFICATION OF hoverIntent v1.8.1 // 2014.08.11 // jQuery v1.9.1+ - * http://cherne.net/brian/resources/jquery.hoverIntent.html - * - * You may use hoverIntent under the terms of the MIT license. Basically that - * means you are free to use hoverIntent as long as this header is left intact. - * Copyright 2007, 2014 Brian Cherne - */ - -/* hoverIntent is similar to jQuery's built-in "hover" method except that - * instead of firing the handlerIn function immediately, hoverIntent checks - * to see if the user's mouse has slowed down (beneath the sensitivity - * threshold) before firing the event. The handlerOut function is only - * called after a matching handlerIn. - * - * // basic usage ... just like .hover() - * .hoverIntent( handlerIn, handlerOut ) - * .hoverIntent( handlerInOut ) - * - * // basic usage ... with event delegation! - * .hoverIntent( handlerIn, handlerOut, selector ) - * .hoverIntent( handlerInOut, selector ) - * - * // using a basic configuration object - * .hoverIntent( config ) - * - * @param handlerIn function OR configuration object - * @param handlerOut function OR selector for delegation OR undefined - * @param selector selector OR undefined - * @author Brian Cherne - */ - -(function(factory) { - 'use strict'; - if (typeof define === 'function' && define.amd) { - define(['jquery'], factory); - } else if (jQuery && !jQuery.fn.hoverIntent) { - factory(jQuery); - } -})(function($) { - 'use strict'; - - // default configuration values - var _cfg = { - interval: 100, - sensitivity: 6, - timeout: 0 - }; - - // counter used to generate an ID for each instance - var INSTANCE_COUNT = 0; - - // current X and Y position of mouse, updated during mousemove tracking (shared across instances) - var cX, cY; - - // saves the current pointer position coordinated based on the given mouse event - var track = function(ev) { - cX = ev.pageX; - cY = ev.pageY; - }; - - // compares current and previous mouse positions - var compare = function(ev,$el,s,cfg) { - // compare mouse positions to see if pointer has slowed enough to trigger `over` function - if ( Math.sqrt( (s.pX-cX)*(s.pX-cX) + (s.pY-cY)*(s.pY-cY) ) < cfg.sensitivity ) { - $el.off('mousemove.hoverIntent'+s.namespace,track); - delete s.timeoutId; - // set hoverIntent state as active for this element (so `out` handler can eventually be called) - s.isActive = true; - // clear coordinate data - delete s.pX; delete s.pY; - return cfg.over.apply($el[0],[ev]); - } else { - // set previous coordinates for next comparison - s.pX = cX; s.pY = cY; - // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs) - s.timeoutId = setTimeout( function(){compare(ev, $el, s, cfg);} , cfg.interval ); - } - }; - - // triggers given `out` function at configured `timeout` after a mouseleave and clears state - var delay = function(ev,$el,s,out) { - delete $el.data('hoverIntent')[s.id]; - return out.apply($el[0],[ev]); - }; - - $.fn.hoverIntent = function(handlerIn,handlerOut,selector) { - // instance ID, used as a key to store and retrieve state information on an element - var instanceId = INSTANCE_COUNT++; - - // extend the default configuration and parse parameters - var cfg = $.extend({}, _cfg); - if ( $.isPlainObject(handlerIn) ) { - cfg = $.extend(cfg, handlerIn ); - } else if ($.isFunction(handlerOut)) { - cfg = $.extend(cfg, { over: handlerIn, out: handlerOut, selector: selector } ); - } else { - cfg = $.extend(cfg, { over: handlerIn, out: handlerIn, selector: handlerOut } ); - } - - // A private function for handling mouse 'hovering' - var handleHover = function(e) { - // cloned event to pass to handlers (copy required for event object to be passed in IE) - var ev = $.extend({},e); - - // the current target of the mouse event, wrapped in a jQuery object - var $el = $(this); - - // read hoverIntent data from element (or initialize if not present) - var hoverIntentData = $el.data('hoverIntent'); - if (!hoverIntentData) { $el.data('hoverIntent', (hoverIntentData = {})); } - - // read per-instance state from element (or initialize if not present) - var state = hoverIntentData[instanceId]; - if (!state) { hoverIntentData[instanceId] = state = { id: instanceId }; } - - // state properties: - // id = instance ID, used to clean up data - // timeoutId = timeout ID, reused for tracking mouse position and delaying "out" handler - // isActive = plugin state, true after `over` is called just until `out` is called - // pX, pY = previously-measured pointer coordinates, updated at each polling interval - // namespace = string used as namespace for per-instance event management - - // clear any existing timeout - if (state.timeoutId) { state.timeoutId = clearTimeout(state.timeoutId); } - - // event namespace, used to register and unregister mousemove tracking - var namespace = state.namespace = '.hoverIntent'+instanceId; - - // handle the event, based on its type - if (e.type === 'mouseenter') { - // do nothing if already active or mouse left button is down - if (state.isActive || e.buttons === 1) { return; } - // set "previous" X and Y position based on initial entry point - state.pX = ev.pageX; state.pY = ev.pageY; - // update "current" X and Y position based on mousemove - $el.on('mousemove.hoverIntent'+namespace,track); - // start polling interval (self-calling timeout) to compare mouse coordinates over time - state.timeoutId = setTimeout( function(){compare(ev,$el,state,cfg);} , cfg.interval ); - } else { // "mouseleave" - // do nothing if not already active - if (!state.isActive) { return; } - // unbind expensive mousemove event - $el.off('mousemove.hoverIntent'+namespace,track); - // if hoverIntent state is true, then call the mouseOut function after the specified delay - state.timeoutId = setTimeout( function(){delay(ev,$el,state,cfg.out);} , cfg.timeout ); - } - }; - - // listen for mouseenter and mouseleave - return this.on({'mouseenter.hoverIntent':handleHover,'mouseleave.hoverIntent':handleHover}, cfg.selector); - }; -}); diff --git a/public/javascripts/vendor/jquery.hoverIntent.min.js b/public/javascripts/vendor/jquery.hoverIntent.min.js deleted file mode 100644 index 3550bfe4c3..0000000000 --- a/public/javascripts/vendor/jquery.hoverIntent.min.js +++ /dev/null @@ -1 +0,0 @@ -!function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery"],e):jQuery&&!jQuery.fn.hoverIntent&&e(jQuery)}(function(e){"use strict";var t,n,o={interval:100,sensitivity:6,timeout:0},i=0,r=function(e){t=e.pageX,n=e.pageY},u=function(e,o,i,s){if(Math.sqrt((i.pX-t)*(i.pX-t)+(i.pY-n)*(i.pY-n))on, unbind->off -(function(o,i,k){i.infinitescroll=function z(D,F,E){this.element=i(E);if(!this._create(D,F)){this.failed=true}};i.infinitescroll.defaults={loading:{finished:k,finishedMsg:"",msg:null,msgText:"",selector:null,speed:"fast",start:k},state:{isDuringAjax:false,isInvalidPage:false,isDestroyed:false,isDone:false,isPaused:false,currPage:1},debug:false,behavior:k,binder:i(o),nextSelector:"div.navigation a:first",navSelector:"div.navigation",contentSelector:null,extraScrollPx:150,itemSelector:"div.post",animate:false,pathParse:k,dataType:"html",appendCallback:true,bufferPx:40,errorCallback:function(){},infid:0,pixelsFromNavToBottom:k,path:k,prefill:false,maxPage:k};i.infinitescroll.prototype={_binding:function g(F){var D=this,E=D.options;E.v="2.0b2.120520";if(!!E.behavior&&this["_binding_"+E.behavior]!==k){this["_binding_"+E.behavior].call(this);return}if(F!=="on"&&F!=="off"){this._debug("Binding value "+F+" not valid");return false}if(F==="off"){(this.options.binder).off("smartscroll.infscr."+D.options.infid)}else{(this.options.binder)[F]("smartscroll.infscr."+D.options.infid,function(){D.scroll()})}this._debug("Binding",F)},_create:function t(F,J){var G=i.extend(true,{},i.infinitescroll.defaults,F);this.options=G;var I=i(o);var D=this;if(!D._validate(F)){return false}var H=i(G.nextSelector).attr("href");if(!H){this._debug("Navigation selector not found");return false}G.path=G.path||this._determinepath(H);G.contentSelector=G.contentSelector||this.element;G.loading.selector=G.loading.selector||G.contentSelector;G.loading.msg=G.loading.msg||i('
    ');if(G.pixelsFromNavToBottom===k){G.pixelsFromNavToBottom=i(document).height()-i(G.navSelector).offset().top}var E=this;G.loading.start=G.loading.start||function(){i(G.navSelector).hide();G.loading.msg.appendTo(G.loading.selector).show(0,i.proxy(function(){this.beginAjax(G)},E))};G.loading.finished=G.loading.finished||function(){G.loading.msg.fadeOut(G.loading.speed)};G.callback=function(K,M,L){if(!!G.behavior&&K["_callback_"+G.behavior]!==k){K["_callback_"+G.behavior].call(i(G.contentSelector)[0],M,L)}if(J){J.call(i(G.contentSelector)[0],M,G,L)}if(G.prefill){I.on("resize.infinite-scroll",K._prefill)}};if(F.debug){if(Function.prototype.bind&&(typeof console==="object"||typeof console==="function")&&typeof console.log==="object"){["log","info","warn","error","assert","dir","clear","profile","profileEnd"].forEach(function(K){console[K]=this.call(console[K],console)},Function.prototype.bind)}}this._setup();if(G.prefill){this._prefill()}return true},_prefill:function n(){var D=this;var G=i(document);var F=i(o);function E(){return(G.height()<=F.height())}this._prefill=function(){if(E()){D.scroll()}F.on("resize.infinite-scroll",function(){if(E()){F.off("resize.infinite-scroll");D.scroll()}})};this._prefill()},_debug:function q(){if(true!==this.options.debug){return}if(typeof console!=="undefined"&&typeof console.log==="function"){if((Array.prototype.slice.call(arguments)).length===1&&typeof Array.prototype.slice.call(arguments)[0]==="string"){console.log((Array.prototype.slice.call(arguments)).toString())}else{console.log(Array.prototype.slice.call(arguments))}}else{if(!Function.prototype.bind&&typeof console!=="undefined"&&typeof console.log==="object"){Function.prototype.call.call(console.log,console,Array.prototype.slice.call(arguments))}}},_determinepath:function A(E){var D=this.options;if(!!D.behavior&&this["_determinepath_"+D.behavior]!==k){return this["_determinepath_"+D.behavior].call(this,E)}if(!!D.pathParse){this._debug("pathParse manual");return D.pathParse(E,this.options.state.currPage+1)}else{if(E.match(/^(.*?)\b2\b(.*?$)/)){E=E.match(/^(.*?)\b2\b(.*?$)/).slice(1)}else{if(E.match(/^(.*?)2(.*?$)/)){if(E.match(/^(.*?page=)2(\/.*|$)/)){E=E.match(/^(.*?page=)2(\/.*|$)/).slice(1);return E}E=E.match(/^(.*?)2(.*?$)/).slice(1)}else{if(E.match(/^(.*?page=)1(\/.*|$)/)){E=E.match(/^(.*?page=)1(\/.*|$)/).slice(1);return E}else{this._debug("Sorry, we couldn't parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag. If you still get this error: yell, scream, and kindly ask for help at infinite-scroll.com.");D.state.isInvalidPage=true}}}}this._debug("determinePath",E);return E},_error:function v(E){var D=this.options;if(!!D.behavior&&this["_error_"+D.behavior]!==k){this["_error_"+D.behavior].call(this,E);return}if(E!=="destroy"&&E!=="end"){E="unknown"}this._debug("Error",E);if(E==="end"){this._showdonemsg()}D.state.isDone=true;D.state.currPage=1;D.state.isPaused=false;this._binding("off")},_loadcallback:function c(H,G,E){var D=this.options,J=this.options.callback,L=(D.state.isDone)?"done":(!D.appendCallback)?"no-append":"append",K;if(!!D.behavior&&this["_loadcallback_"+D.behavior]!==k){this["_loadcallback_"+D.behavior].call(this,H,G);return}switch(L){case"done":this._showdonemsg();return false;case"no-append":if(D.dataType==="html"){G="
    "+G+"
    ";G=i(G).find(D.itemSelector)}break;case"append":var F=H.children();if(F.length===0){return this._error("end")}K=document.createDocumentFragment();while(H[0].firstChild){K.appendChild(H[0].firstChild)}this._debug("contentSelector",i(D.contentSelector)[0]);i(D.contentSelector)[0].appendChild(K);G=F.get();break}D.loading.finished.call(i(D.contentSelector)[0],D);if(D.animate){var I=i(o).scrollTop()+i("#infscr-loading").height()+D.extraScrollPx+"px";i("html,body").animate({scrollTop:I},800,function(){D.state.isDuringAjax=false})}if(!D.animate){D.state.isDuringAjax=false}J(this,G,E);if(D.prefill){this._prefill()}},_nearbottom:function u(){var E=this.options,D=0+i(document).height()-(E.binder.scrollTop())-i(o).height();if(!!E.behavior&&this["_nearbottom_"+E.behavior]!==k){return this["_nearbottom_"+E.behavior].call(this)}this._debug("math:",D,E.pixelsFromNavToBottom);return(D-E.bufferPx-1&&i(E[D]).length===0){this._debug("Your "+D+" found no elements.");return false}}return true},bind:function p(){this._binding("on")},destroy:function C(){this.options.state.isDestroyed=true;this.options.loading.finished();return this._error("destroy")},pause:function e(){this._pausing("pause")},resume:function h(){this._pausing("resume")},beginAjax:function B(G){var E=this,I=G.path,F,D,K,J;G.state.currPage++;if(G.maxPage!=k&&G.state.currPage>G.maxPage){this.destroy();return}F=i(G.contentSelector).is("table")?i(""):i("
    ");D=(typeof I==="function")?I(G.state.currPage):I.join(G.state.currPage);E._debug("heading into ajax",D);K=(G.dataType==="html"||G.dataType==="json")?G.dataType:"html+callback";if(G.appendCallback&&G.dataType==="html"){K+="+callback"}switch(K){case"html+callback":E._debug("Using HTML via .load() method");F.load(D+" "+G.itemSelector,k,function H(L){E._loadcallback(F,L,D)});break;case"html":E._debug("Using "+(K.toUpperCase())+" via $.ajax() method");i.ajax({url:D,dataType:G.dataType,complete:function H(L,M){J=(typeof(L.isResolved)!=="undefined")?(L.isResolved()):(M==="success"||M==="notmodified");if(J){E._loadcallback(F,L.responseText,D)}else{E._error("end")}}});break;case"json":E._debug("Using "+(K.toUpperCase())+" via $.ajax() method");i.ajax({dataType:"json",type:"GET",url:D,success:function(N,O,M){J=(typeof(M.isResolved)!=="undefined")?(M.isResolved()):(O==="success"||O==="notmodified");if(G.appendCallback){if(G.template!==k){var L=G.template(N);F.append(L);if(J){E._loadcallback(F,L)}else{E._error("end")}}else{E._debug("template must be defined.");E._error("end")}}else{if(J){E._loadcallback(F,N,D)}else{E._error("end")}}},error:function(){E._debug("JSON ajax request failed.");E._error("end")}});break}},retrieve:function b(F){F=F||null;var D=this,E=D.options;if(!!E.behavior&&this["retrieve_"+E.behavior]!==k){this["retrieve_"+E.behavior].call(this,F);return}if(E.state.isDestroyed){this._debug("Instance is destroyed");return false}E.state.isDuringAjax=true;E.loading.start.call(i(E.contentSelector)[0],E)},scroll:function f(){var D=this.options,E=D.state;if(!!D.behavior&&this["scroll_"+D.behavior]!==k){this["scroll_"+D.behavior].call(this);return}if(E.isDuringAjax||E.isInvalidPage||E.isDone||E.isDestroyed||E.isPaused){return}if(!this._nearbottom()){return}this.retrieve()},toggle:function y(){this._pausing()},unbind:function m(){this._binding("off")},update:function j(D){if(i.isPlainObject(D)){this.options=i.extend(true,this.options,D)}}};i.fn.infinitescroll=function d(F,G){var E=typeof F;switch(E){case"string":var D=Array.prototype.slice.call(arguments,1);this.each(function(){var H=i.data(this,"infinitescroll");if(!H){return false}if(!i.isFunction(H[F])||F.charAt(0)==="_"){return false}H[F].apply(H,D)});break;case"object":this.each(function(){var H=i.data(this,"infinitescroll");if(H){H.update(F)}else{H=new i.infinitescroll(F,G,this);if(!H.failed){i.data(this,"infinitescroll",H)}}});break}return this};var x=i.event,s;x.special.smartscroll={setup:function(){i(this).on("scroll",x.special.smartscroll.handler)},teardown:function(){i(this).off("scroll",x.special.smartscroll.handler)},handler:function(G,D){var F=this,E=arguments;G.type="smartscroll";if(s){clearTimeout(s)}s=setTimeout(function(){i(F).trigger("smartscroll",E)},D==="execAsap"?0:100)}};i.fn.smartscroll=function(D){return D?this.on("smartscroll",D):this.trigger("smartscroll",["execAsap"])}})(window,jQuery); +// hack: bind->on, unbind->off, remove proxy +(function(o,i,k){i.infinitescroll=function z(D,F,E){this.element=i(E);if(!this._create(D,F)){this.failed=true}};i.infinitescroll.defaults={loading:{finished:k,finishedMsg:"",msg:null,msgText:"",selector:null,speed:"fast",start:k},state:{isDuringAjax:false,isInvalidPage:false,isDestroyed:false,isDone:false,isPaused:false,currPage:1},debug:false,behavior:k,binder:i(o),nextSelector:"div.navigation a:first",navSelector:"div.navigation",contentSelector:null,extraScrollPx:150,itemSelector:"div.post",animate:false,pathParse:k,dataType:"html",appendCallback:true,bufferPx:40,errorCallback:function(){},infid:0,pixelsFromNavToBottom:k,path:k,prefill:false,maxPage:k};i.infinitescroll.prototype={_binding:function g(F){var D=this,E=D.options;E.v="2.0b2.120520";if(!!E.behavior&&this["_binding_"+E.behavior]!==k){this["_binding_"+E.behavior].call(this);return}if(F!=="on"&&F!=="off"){this._debug("Binding value "+F+" not valid");return false}if(F==="off"){(this.options.binder).off("smartscroll.infscr."+D.options.infid)}else{(this.options.binder)[F]("smartscroll.infscr."+D.options.infid,function(){D.scroll()})}this._debug("Binding",F)},_create:function t(F,J){var G=i.extend(true,{},i.infinitescroll.defaults,F);this.options=G;var I=i(o);var D=this;if(!D._validate(F)){return false}var H=i(G.nextSelector).attr("href");if(!H){this._debug("Navigation selector not found");return false}G.path=G.path||this._determinepath(H);G.contentSelector=G.contentSelector||this.element;G.loading.selector=G.loading.selector||G.contentSelector;G.loading.msg=G.loading.msg||i('
    ');if(G.pixelsFromNavToBottom===k){G.pixelsFromNavToBottom=i(document).height()-i(G.navSelector).offset().top}var E=this;G.loading.start=G.loading.start||function(){i(G.navSelector).hide();G.loading.msg.appendTo(G.loading.selector).show(0,function(){E.beginAjax(G)})};G.loading.finished=G.loading.finished||function(){G.loading.msg.fadeOut(G.loading.speed)};G.callback=function(K,M,L){if(!!G.behavior&&K["_callback_"+G.behavior]!==k){K["_callback_"+G.behavior].call(i(G.contentSelector)[0],M,L)}if(J){J.call(i(G.contentSelector)[0],M,G,L)}if(G.prefill){I.on("resize.infinite-scroll",K._prefill)}};if(F.debug){if(Function.prototype.bind&&(typeof console==="object"||typeof console==="function")&&typeof console.log==="object"){["log","info","warn","error","assert","dir","clear","profile","profileEnd"].forEach(function(K){console[K]=this.call(console[K],console)},Function.prototype.bind)}}this._setup();if(G.prefill){this._prefill()}return true},_prefill:function n(){var D=this;var G=i(document);var F=i(o);function E(){return(G.height()<=F.height())}this._prefill=function(){if(E()){D.scroll()}F.on("resize.infinite-scroll",function(){if(E()){F.off("resize.infinite-scroll");D.scroll()}})};this._prefill()},_debug:function q(){if(true!==this.options.debug){return}if(typeof console!=="undefined"&&typeof console.log==="function"){if((Array.prototype.slice.call(arguments)).length===1&&typeof Array.prototype.slice.call(arguments)[0]==="string"){console.log((Array.prototype.slice.call(arguments)).toString())}else{console.log(Array.prototype.slice.call(arguments))}}else{if(!Function.prototype.bind&&typeof console!=="undefined"&&typeof console.log==="object"){Function.prototype.call.call(console.log,console,Array.prototype.slice.call(arguments))}}},_determinepath:function A(E){var D=this.options;if(!!D.behavior&&this["_determinepath_"+D.behavior]!==k){return this["_determinepath_"+D.behavior].call(this,E)}if(!!D.pathParse){this._debug("pathParse manual");return D.pathParse(E,this.options.state.currPage+1)}else{if(E.match(/^(.*?)\b2\b(.*?$)/)){E=E.match(/^(.*?)\b2\b(.*?$)/).slice(1)}else{if(E.match(/^(.*?)2(.*?$)/)){if(E.match(/^(.*?page=)2(\/.*|$)/)){E=E.match(/^(.*?page=)2(\/.*|$)/).slice(1);return E}E=E.match(/^(.*?)2(.*?$)/).slice(1)}else{if(E.match(/^(.*?page=)1(\/.*|$)/)){E=E.match(/^(.*?page=)1(\/.*|$)/).slice(1);return E}else{this._debug("Sorry, we couldn't parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag. If you still get this error: yell, scream, and kindly ask for help at infinite-scroll.com.");D.state.isInvalidPage=true}}}}this._debug("determinePath",E);return E},_error:function v(E){var D=this.options;if(!!D.behavior&&this["_error_"+D.behavior]!==k){this["_error_"+D.behavior].call(this,E);return}if(E!=="destroy"&&E!=="end"){E="unknown"}this._debug("Error",E);if(E==="end"){this._showdonemsg()}D.state.isDone=true;D.state.currPage=1;D.state.isPaused=false;this._binding("off")},_loadcallback:function c(H,G,E){var D=this.options,J=this.options.callback,L=(D.state.isDone)?"done":(!D.appendCallback)?"no-append":"append",K;if(!!D.behavior&&this["_loadcallback_"+D.behavior]!==k){this["_loadcallback_"+D.behavior].call(this,H,G);return}switch(L){case"done":this._showdonemsg();return false;case"no-append":if(D.dataType==="html"){G="
    "+G+"
    ";G=i(G).find(D.itemSelector)}break;case"append":var F=H.children();if(F.length===0){return this._error("end")}K=document.createDocumentFragment();while(H[0].firstChild){K.appendChild(H[0].firstChild)}this._debug("contentSelector",i(D.contentSelector)[0]);i(D.contentSelector)[0].appendChild(K);G=F.get();break}D.loading.finished.call(i(D.contentSelector)[0],D);if(D.animate){var I=i(o).scrollTop()+i("#infscr-loading").height()+D.extraScrollPx+"px";i("html,body").animate({scrollTop:I},800,function(){D.state.isDuringAjax=false})}if(!D.animate){D.state.isDuringAjax=false}J(this,G,E);if(D.prefill){this._prefill()}},_nearbottom:function u(){var E=this.options,D=0+i(document).height()-(E.binder.scrollTop())-i(o).height();if(!!E.behavior&&this["_nearbottom_"+E.behavior]!==k){return this["_nearbottom_"+E.behavior].call(this)}this._debug("math:",D,E.pixelsFromNavToBottom);return(D-E.bufferPx-1&&i(E[D]).length===0){this._debug("Your "+D+" found no elements.");return false}}return true},bind:function p(){this._binding("on")},destroy:function C(){this.options.state.isDestroyed=true;this.options.loading.finished();return this._error("destroy")},pause:function e(){this._pausing("pause")},resume:function h(){this._pausing("resume")},beginAjax:function B(G){var E=this,I=G.path,F,D,K,J;G.state.currPage++;if(G.maxPage!=k&&G.state.currPage>G.maxPage){this.destroy();return}F=i(G.contentSelector).is("table")?i(""):i("
    ");D=(typeof I==="function")?I(G.state.currPage):I.join(G.state.currPage);E._debug("heading into ajax",D);K=(G.dataType==="html"||G.dataType==="json")?G.dataType:"html+callback";if(G.appendCallback&&G.dataType==="html"){K+="+callback"}switch(K){case"html+callback":E._debug("Using HTML via .load() method");F.load(D+" "+G.itemSelector,k,function H(L){E._loadcallback(F,L,D)});break;case"html":E._debug("Using "+(K.toUpperCase())+" via $.ajax() method");i.ajax({url:D,dataType:G.dataType,complete:function H(L,M){J=(typeof(L.isResolved)!=="undefined")?(L.isResolved()):(M==="success"||M==="notmodified");if(J){E._loadcallback(F,L.responseText,D)}else{E._error("end")}}});break;case"json":E._debug("Using "+(K.toUpperCase())+" via $.ajax() method");i.ajax({dataType:"json",type:"GET",url:D,success:function(N,O,M){J=(typeof(M.isResolved)!=="undefined")?(M.isResolved()):(O==="success"||O==="notmodified");if(G.appendCallback){if(G.template!==k){var L=G.template(N);F.append(L);if(J){E._loadcallback(F,L)}else{E._error("end")}}else{E._debug("template must be defined.");E._error("end")}}else{if(J){E._loadcallback(F,N,D)}else{E._error("end")}}},error:function(){E._debug("JSON ajax request failed.");E._error("end")}});break}},retrieve:function b(F){F=F||null;var D=this,E=D.options;if(!!E.behavior&&this["retrieve_"+E.behavior]!==k){this["retrieve_"+E.behavior].call(this,F);return}if(E.state.isDestroyed){this._debug("Instance is destroyed");return false}E.state.isDuringAjax=true;E.loading.start.call(i(E.contentSelector)[0],E)},scroll:function f(){var D=this.options,E=D.state;if(!!D.behavior&&this["scroll_"+D.behavior]!==k){this["scroll_"+D.behavior].call(this);return}if(E.isDuringAjax||E.isInvalidPage||E.isDone||E.isDestroyed||E.isPaused){return}if(!this._nearbottom()){return}this.retrieve()},toggle:function y(){this._pausing()},unbind:function m(){this._binding("off")},update:function j(D){if(i.isPlainObject(D)){this.options=i.extend(true,this.options,D)}}};i.fn.infinitescroll=function d(F,G){var E=typeof F;switch(E){case"string":var D=Array.prototype.slice.call(arguments,1);this.each(function(){var H=i.data(this,"infinitescroll");if(!H){return false}if(!i.isFunction(H[F])||F.charAt(0)==="_"){return false}H[F].apply(H,D)});break;case"object":this.each(function(){var H=i.data(this,"infinitescroll");if(H){H.update(F)}else{H=new i.infinitescroll(F,G,this);if(!H.failed){i.data(this,"infinitescroll",H)}}});break}return this};var x=i.event,s;x.special.smartscroll={setup:function(){i(this).on("scroll",x.special.smartscroll.handler)},teardown:function(){i(this).off("scroll",x.special.smartscroll.handler)},handler:function(G,D){var F=this,E=arguments;G.type="smartscroll";if(s){clearTimeout(s)}s=setTimeout(function(){i(F).trigger("smartscroll",E)},D==="execAsap"?0:100)}};i.fn.smartscroll=function(D){return D?this.on("smartscroll",D):this.trigger("smartscroll",["execAsap"])}})(window,jQuery); diff --git a/public/javascripts/vendor/jquery.min.js b/public/javascripts/vendor/jquery.min.js index 8ae1a2972c..e9137a7f32 100644 --- a/public/javascripts/vendor/jquery.min.js +++ b/public/javascripts/vendor/jquery.min.js @@ -1,2 +1,2 @@ /*! jQuery v3.2.2-pre | (c) jQuery Foundation | jquery.org/license | hacked for lichess.org on https://github.com/ornicar/jquery/tree/lila */ -!function(e,t){"use strict";t(e)}("undefined"!=typeof window?window:this,function(e){"use strict";var t=[],n=e.document,r=Object.getPrototypeOf,i=t.slice,o=t.concat,a=t.push,s=t.indexOf,c={},u=c.toString,l=c.hasOwnProperty,f=l.toString,p=f.call(Object),d={},h=function e(t){return null!=t&&t===t.window};function v(e,t){var r=(t=t||n).createElement("script");r.text=e,t.head.appendChild(r).parentNode.removeChild(r)}var g="3.1.1",y=function(e,t){return new y.fn.init(e,t)},m=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,x=/^-ms-/,b=/-([a-z])/g,w=function(e,t){return t.toUpperCase()};y.fn=y.prototype={jquery:"3.1.1",constructor:y,length:0,toArray:function(){return i.call(this)},get:function(e){return null==e?i.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=y.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return y.each(this,e)},map:function(e){return this.pushStack(y.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(i.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n0&&t-1 in e)}var C=n.documentElement,k,S,j=y.expando.split("").sort(N).join("")===y.expando,E=C.matches||C.webkitMatchesSelector||C.mozMatchesSelector||C.oMatchesSelector||C.msMatchesSelector,D=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g,A=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e};function N(e,t){if(e===t)return k=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)?e===n||e.ownerDocument===n&&y.contains(n,e)?-1:t===n||t.ownerDocument===n&&y.contains(n,t)?1:S?s.call(S,e)-s.call(S,t):0:4&r?-1:1)}function H(e){var t,n=[],r=0,i=0;if(k=!1,S=!j&&e.slice(0),e.sort(N),k){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return S=null,e}function F(e){return(e+"").replace(D,A)}function O(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)}var L={visible:function(){return O(this)},hidden:function(){return!O(this)},selected:function(){return this.selected},checked:function(){return this.checked},first:function(e){return 0===e},last:function(e,t){return e===t.length-1},eq:function(e,t,n){return e===n},contains:function(e,t,n){return y(this).text().indexOf(n)>-1}},P=new RegExp("(.*):(\\w+)(?:\\(([^)]+)\\))?$\\s*");function q(e,t){e=e.replace(/=#\]/g,'="#"]');var n,r,i=P.exec(e);if(i&&i[2]in L&&(n=L[i[2]],r=i[3],e=i[1],r)){var o=Number(r);r=isNaN(o)?r.replace(/^["']|["']$/g,""):o}return t(e,n,r)}y.extend({uniqueSort:H,unique:H,escapeSelector:F,find:function(e,t,r,i){var o,a,s=0;return r=r||[],t=t||n,e&&"string"==typeof e?1!==(a=t.nodeType)&&9!==a?[]:q(e,function(e,n,a){if(i)while(o=i[s++])e&&!y.find.matchesSelector(o,e)||n&&!n.call(o,null,r,a)||r.push(o);else{var c=t.querySelectorAll(e);n&&(c=Array.prototype.filter.call(c,function(e,t){return n.call(e,t,r,a)})),y.merge(r,c)}return r}):r},text:function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i)return e.textContent;if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=y.text(t);return n},contains:function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!n.contains(r))},isXMLDoc:function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},expr:{attrHandle:{},match:{bool:new RegExp("^(?:checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped)$","i"),needsContext:/^[\x20\t\r\n\f]*[>+~]/}}}),y.extend(y.find,{matches:function(e,t){return y.find(e,null,null,t)},matchesSelector:function(e,t){return E.call(e,t)},attr:function(e,t){var n=y.expr.attrHandle[t.toLowerCase()],r=n&&l.call(y.expr.attrHandle,t.toLowerCase())?n(e,t,y.isXMLDoc(e)):void 0;return void 0!==r?r:e.getAttribute(t)}}),y.expr[":"]=[];var M=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&y(e).is(n))break;r.push(e)}return r},R=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},W=y.expr.match.needsContext;function $(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var _=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,I=/^.[^:#\[\.,]*$/;function z(e,t,n){return y.isFunction(t)?y.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?y.grep(e,function(e){return e===t!==n}):"string"!=typeof t?y.grep(e,function(e){return s.call(t,e)>-1!==n}):I.test(t)?y.filter(t,e,n):(t=y.filter(t,e),y.grep(e,function(e){return s.call(t,e)>-1!==n&&1===e.nodeType}))}y.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),y.find.matches(e,y.grep(t,function(e){return 1===e.nodeType}))},y.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(y(e).filter(function(){for(t=0;t1?y.uniqueSort(n):n},filter:function(e){return this.pushStack(z(this,e||[],!1))},not:function(e){return this.pushStack(z(this,e||[],!0))},is:function(e){return!!z(this,"string"==typeof e&&W.test(e)?y(e):e||[],!1).length}});var B,U=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(y.fn.init=function(e,t,r){var i,o;if(!e)return this;if(r=r||B,"string"==typeof e){if(!(i="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:U.exec(e))||!i[1]&&t)return!t||t.jquery?(t||r).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof y?t[0]:t,y.merge(this,y.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:n,!0)),_.test(i[1])&&y.isPlainObject(t))for(i in t)y.isFunction(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(o=n.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):y.isFunction(e)?void 0!==r.ready?r.ready(e):e(y):y.makeArray(e,this)}).prototype=y.fn,B=y(n);var X=/^(?:parents|prev(?:Until|All))/,V={children:!0,contents:!0,next:!0,prev:!0};y.fn.extend({has:function(e){var t=y(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&y.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?y.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?s.call(y(e),this[0]):s.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(y.uniqueSort(y.merge(this.get(),y(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function Y(e,t){while((e=e[t])&&1!==e.nodeType);return e}y.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return M(e,"parentNode")},parentsUntil:function(e,t,n){return M(e,"parentNode",n)},next:function(e){return Y(e,"nextSibling")},prev:function(e){return Y(e,"previousSibling")},nextAll:function(e){return M(e,"nextSibling")},prevAll:function(e){return M(e,"previousSibling")},nextUntil:function(e,t,n){return M(e,"nextSibling",n)},prevUntil:function(e,t,n){return M(e,"previousSibling",n)},siblings:function(e){return R((e.parentNode||{}).firstChild,e)},children:function(e){return R(e.firstChild)},contents:function(e){return $(e,"iframe")?e.contentDocument:($(e,"template")&&(e=e.content||e),y.merge([],e.childNodes))}},function(e,t){y.fn[e]=function(n,r){var i=y.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=y.filter(r,i)),this.length>1&&(V[e]||y.uniqueSort(i),X.test(e)&&i.reverse()),this.pushStack(i)}});var G=/[^\x20\t\r\n\f]+/g;function J(e){var t={};return y.each(e.match(G)||[],function(e,n){t[n]=!0}),t}y.Callbacks=function(e){e="string"==typeof e?J(e):y.extend({},e);var t,n,r,i,o=[],a=[],s=-1,c=function(){for(i=i||e.once,r=t=!0;a.length;s=-1){n=a.shift();while(++s-1)o.splice(n,1),n<=s&&s--}),this},has:function(e){return e?y.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||c()),this},fire:function(){return u.fireWith(this,arguments),this},fired:function(){return!!r}};return u};function K(e){return e}function Q(e){throw e}function Z(e,t,n,r){var i;try{e&&y.isFunction(i=e.promise)?i.call(e).done(t).fail(n):e&&y.isFunction(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}y.extend({Deferred:function(t){var n=[["notify","progress",y.Callbacks("memory"),y.Callbacks("memory"),2],["resolve","done",y.Callbacks("once memory"),y.Callbacks("once memory"),0,"resolved"],["reject","fail",y.Callbacks("once memory"),y.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},catch:function(e){return i.then(null,e)},pipe:function(){var e=arguments;return y.Deferred(function(t){y.each(n,function(n,r){var i=y.isFunction(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&y.isFunction(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){var o=0;function a(t,n,r,i){return function(){var s=this,c=arguments,u=function(){var e,u;if(!(t=o&&(r!==Q&&(s=void 0,c=[e]),n.rejectWith(s,c))}};t?l():(y.Deferred.getStackHook&&(l.stackTrace=y.Deferred.getStackHook()),e.setTimeout(l))}}return y.Deferred(function(e){n[0][3].add(a(0,e,y.isFunction(i)?i:K,e.notifyWith)),n[1][3].add(a(0,e,y.isFunction(t)?t:K)),n[2][3].add(a(0,e,y.isFunction(r)?r:Q))}).promise()},promise:function(e){return null!=e?y.extend(e,i):i}},o={};return y.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),o=i.call(arguments),a=y.Deferred(),s=function(e){return function(n){r[e]=this,o[e]=arguments.length>1?i.call(arguments):n,--t||a.resolveWith(r,o)}};if(t<=1&&(Z(e,a.done(s(n)).resolve,a.reject,!t),"pending"===a.state()||y.isFunction(o[n]&&o[n].then)))return a.then();while(n--)Z(o[n],s(n),a.reject);return a.promise()}}),y.readyException=function(t){e.setTimeout(function(){throw t})};var ee=y.Deferred();y.fn.ready=function(e){return ee.then(e).catch(function(e){y.readyException(e)}),this},y.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--y.readyWait:y.isReady)||(y.isReady=!0,!0!==e&&--y.readyWait>0||ee.resolveWith(n,[y]))}}),y.ready.then=ee.then;function te(){n.removeEventListener("DOMContentLoaded",te),e.removeEventListener("load",te),y.ready()}"complete"===n.readyState||"loading"!==n.readyState&&!n.documentElement.doScroll?e.setTimeout(y.ready):(n.addEventListener("DOMContentLoaded",te),e.addEventListener("load",te));var ne=function(e,t,n,r,i,o,a){var s=0,c=e.length,u=null==n;if("object"===y.type(n)){i=!0;for(s in n)ne(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,y.isFunction(r)||(a=!0),u&&(a?(t.call(e,r),t=null):(u=t,t=function(e,t,n){return u.call(y(e),n)})),t))for(;s1,null,!0)},removeData:function(e){return this.each(function(){ae.remove(this,e)})}}),y.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=oe.get(e,t),n&&(!r||Array.isArray(n)?r=oe.access(e,t,y.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=y.queue(e,t),r=n.length,i=n.shift(),o=y._queueHooks(e,t),a=function(){y.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return oe.get(e,n)||oe.access(e,n,{empty:y.Callbacks("once memory").add(function(){oe.remove(e,[t+"queue",n])})})}}),y.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length1)},removeAttr:function(e){return this.each(function(){y.removeAttr(this,e)})}}),y.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?y.prop(e,t,n):(1===o&&y.isXMLDoc(e)||(i=y.attrHooks[t.toLowerCase()]||(y.expr.match.bool.test(t)?fe:void 0)),void 0!==n?null===n?void y.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=y.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!d.radioValue&&"radio"===t&&$(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(G);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),fe={set:function(e,t,n){return!1===t?y.removeAttr(e,n):e.setAttribute(n,n),n}},y.each(y.expr.match.bool.source.match(/\w+/g),function(e,t){var n=pe[t]||y.find.attr;pe[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=pe[a],pe[a]=i,i=null!=n(e,t,r)?a:null,pe[a]=o),i}});var de=/^(?:input|select|textarea|button)$/i,he=/^(?:a|area)$/i;y.fn.extend({prop:function(e,t){return ne(this,y.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[y.propFix[e]||e]})}}),y.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&y.isXMLDoc(e)||(t=y.propFix[t]||t,i=y.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=y.find.attr(e,"tabindex");return t?parseInt(t,10):de.test(e.nodeName)||he.test(e.nodeName)&&e.href?0:-1}}},propFix:{for:"htmlFor",class:"className"}}),d.optSelected||(y.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),y.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){y.propFix[this.toLowerCase()]=this});function ve(e){return(e.match(G)||[]).join(" ")}function ge(e){return e.getAttribute&&e.getAttribute("class")||""}y.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,c=0;if(y.isFunction(e))return this.each(function(t){y(this).addClass(e.call(this,t,ge(this)))});if("string"==typeof e&&e){t=e.match(G)||[];while(n=this[c++])if(i=ge(n),r=1===n.nodeType&&" "+ve(i)+" "){a=0;while(o=t[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=ve(r))&&n.setAttribute("class",s)}}return this},removeClass:function(e){var t,n,r,i,o,a,s,c=0;if(y.isFunction(e))return this.each(function(t){y(this).removeClass(e.call(this,t,ge(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof e&&e){t=e.match(G)||[];while(n=this[c++])if(i=ge(n),r=1===n.nodeType&&" "+ve(i)+" "){a=0;while(o=t[a++])while(r.indexOf(" "+o+" ")>-1)r=r.replace(" "+o+" "," ");i!==(s=ve(r))&&n.setAttribute("class",s)}}return this},toggleClass:function(e,t){var n=typeof e;return"boolean"==typeof t&&"string"===n?t?this.addClass(e):this.removeClass(e):y.isFunction(e)?this.each(function(n){y(this).toggleClass(e.call(this,n,ge(this),t),t)}):this.each(function(){var t,r,i,o;if("string"===n){r=0,i=y(this),o=e.match(G)||[];while(t=o[r++])i.hasClass(t)?i.removeClass(t):i.addClass(t)}else void 0!==e&&"boolean"!==n||((t=ge(this))&&oe.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":oe.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&(" "+ve(ge(n))+" ").indexOf(t)>-1)return!0;return!1}});var ye=/\r/g;y.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=y.isFunction(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,y(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=y.map(i,function(e){return null==e?"":e+""})),(t=y.valHooks[this.type]||y.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return(t=y.valHooks[i.type]||y.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(ye,""):null==n?"":n}}}),y.extend({valHooks:{option:{get:function(e){var t=y.find.attr(e,"value");return null!=t?t:ve(y.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],c=a?o+1:i.length;for(r=o<0?c:a?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),y.each(["radio","checkbox"],function(){y.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=y.inArray(y(e).val(),t)>-1}},d.checkOn||(y.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})});var me=/^key/,xe=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,be=/^([^.]*)(?:\.(.+)|)/;function we(){return!0}function Te(){return!1}function Ce(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)Ce(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Te;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return y().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=y.guid++)),e.each(function(){y.event.add(this,t,i,r,n)})}y.event={global:{},add:function(e,t,n,r,i){var o,a,s,c,u,l,f,p,d,h,v,g=oe.get(e);if(g){n.handler&&(n=(o=n).handler,i=o.selector),i&&y.find.matchesSelector(C,i),n.guid||(n.guid=y.guid++),(c=g.events)||(c=g.events={}),(a=g.handle)||(a=g.handle=function(t){return"undefined"!=typeof y&&y.event.triggered!==t.type?y.event.dispatch.apply(e,arguments):void 0}),u=(t=(t||"").match(G)||[""]).length;while(u--)d=v=(s=be.exec(t[u])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=y.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=y.event.special[d]||{},l=y.extend({type:d,origType:v,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&y.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=c[d])||((p=c[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,l),l.handler.guid||(l.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,l):p.push(l),y.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,c,u,l,f,p,d,h,v,g=oe.hasData(e)&&oe.get(e);if(g&&(c=g.events)){u=(t=(t||"").match(G)||[""]).length;while(u--)if(s=be.exec(t[u])||[],d=v=s[1],h=(s[2]||"").split(".").sort(),d){f=y.event.special[d]||{},p=c[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)l=p[o],!i&&v!==l.origType||n&&n.guid!==l.guid||s&&!s.test(l.namespace)||r&&r!==l.selector&&("**"!==r||!l.selector)||(p.splice(o,1),l.selector&&p.delegateCount--,f.remove&&f.remove.call(e,l));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,g.handle)||y.removeEvent(e,d,g.handle),delete c[d])}else for(d in c)y.event.remove(e,d+t[u],n,r,!0);y.isEmptyObject(c)&&oe.remove(e,"handle events")}},dispatch:function(e){var t=y.event.fix(e),n,r,i,o,a,s,c=new Array(arguments.length),u=(oe.get(this,"events")||{})[t.type]||[],l=y.event.special[t.type]||{};for(c[0]=t,n=1;n=1))for(;u!==this;u=u.parentNode||this)if(1===u.nodeType&&("click"!==e.type||!0!==u.disabled)){for(o=[],a={},n=0;n-1:y.find(i,this,null,[u]).length),a[i]&&o.push(r);o.length&&s.push({elem:u,handlers:o})}return u=this,c-1&&(m=(x=m.split(".")).shift(),x.sort()),f=m.indexOf(":")<0&&"on"+m,t=t[y.expando]?t:new y.Event(m,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=x.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+x.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),r=null==r?[t]:y.makeArray(r,[t]),d=y.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(i,r))){if(!o&&!d.noBubble&&!h(i)){for(u=d.delegateType||m,ke.test(u+m)||(s=s.parentNode);s;s=s.parentNode)g.push(s),c=s;c===(i.ownerDocument||n)&&g.push(c.defaultView||c.parentWindow||e)}a=0;while((s=g[a++])&&!t.isPropagationStopped())v=s,t.type=a>1?u:d.bindType||m,(p=(oe.get(s,"events")||{})[t.type]&&oe.get(s,"handle"))&&p.apply(s,r),(p=f&&s[f])&&p.apply&&re(s)&&(t.result=p.apply(s,r),!1===t.result&&t.preventDefault());return t.type=m,o||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(g.pop(),r)||!re(i)||f&&y.isFunction(i[m])&&!h(i)&&((c=i[f])&&(i[f]=null),y.event.triggered=m,t.isPropagationStopped()&&v.addEventListener(m,Se),i[m](),t.isPropagationStopped()&&v.removeEventListener(m,Se),y.event.triggered=void 0,c&&(i[f]=c)),t.result}},simulate:function(e,t,n){var r=y.extend(new y.Event,n,{type:e,isSimulated:!0});y.event.trigger(r,null,t)}}),y.fn.extend({trigger:function(e,t){return this.each(function(){y.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return y.event.trigger(e,t,n,!0)}}),y.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,t){y.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),y.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}});var je=/^(?:checkbox|radio)$/i,Ee=/<([a-z][^\/\0>\x20\t\r\n\f]+)/i,De=/^$|\/(?:java|ecma)script/i,Ae={thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};Ae.tbody=Ae.tfoot=Ae.colgroup=Ae.caption=Ae.thead,Ae.th=Ae.td;function Ne(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&$(e,t)?y.merge([e],n):n}function He(e,t){for(var n=0,r=e.length;n-1)i&&i.push(o);else if(u=y.contains(o.ownerDocument,o),a=Ne(f.appendChild(o),"script"),u&&He(a),n){l=0;while(o=a[l++])De.test(o.type||"")&&n.push(o)}return f}var Le=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,Pe=/\s*$/g;function We(e,t){return $(e,"table")&&$(11!==t.nodeType?t:t.firstChild,"tr")?y(">tbody",e)[0]||e:e}function $e(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function _e(e){var t=Me.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function Ie(e,t){var n,r,i,o,a,s,c,u;if(1===t.nodeType){if(oe.hasData(e)&&(o=oe.access(e),a=oe.set(t,o),u=o.events)){delete a.handle,a.events={};for(i in u)for(n=0,r=u[i].length;n")},clone:function(e,t,n){var r,i,o,a,s=e.cloneNode(!0),c=y.contains(e.ownerDocument,e);if(t)if(n)for(o=o||Ne(e),a=a||Ne(s),r=0,i=o.length;r0&&He(a,!c&&Ne(e,"script")),s},cleanData:function(e){for(var t,n,r,i=y.event.special,o=0;void 0!==(n=e[o]);o++)if(re(n)){if(t=n[oe.expando]){if(t.events)for(r in t.events)i[r]?y.event.remove(n,r):y.removeEvent(n,r,t.handle);n[oe.expando]=void 0}n[ae.expando]&&(n[ae.expando]=void 0)}}}),y.fn.extend({detach:function(e){return Be(this,e,!0)},remove:function(e){return Be(this,e)},text:function(e){return ne(this,function(e){return void 0===e?y.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return ze(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||We(this,e).appendChild(e)})},prepend:function(){return ze(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=We(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return ze(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return ze(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(y.cleanData(Ne(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return y.clone(this,e,t)})},html:function(e){return ne(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Pe.test(e)&&!Ae[(Ee.exec(e)||["",""])[1].toLowerCase()]){e=y.htmlPrefilter(e);try{for(;n0&&(c=e.setTimeout(function(){k.abort("timeout")},h.timeout));try{l=!1,i.send(w,S)}catch(e){if(l)throw e;S(-1,e)}}else S(-1,"No Transport");function S(t,n,r,s){var u,p,d,w,T,C=n;l||(l=!0,c&&e.clearTimeout(c),i=void 0,a=s||"",k.readyState=t>0?4:0,u=t>=200&&t<300||304===t,r&&(w=dt(h,k,r)),w=ht(h,w,k,u),u?(h.ifModified&&((T=k.getResponseHeader("Last-Modified"))&&(y.lastModified[o]=T),(T=k.getResponseHeader("etag"))&&(y.etag[o]=T)),204===t||"HEAD"===h.type?C="nocontent":304===t?C="notmodified":(C=w.state,p=w.data,u=!(d=w.error))):(d=C,!t&&C||(C="error",t<0&&(t=0))),k.status=t,k.statusText=(n||C)+"",u?m.resolveWith(v,[p,C,k]):m.rejectWith(v,[k,C,d]),k.statusCode(b),b=void 0,f&&g.trigger(u?"ajaxSuccess":"ajaxError",[k,h,u?p:d]),x.fireWith(v,[k,C]),f&&(g.trigger("ajaxComplete",[k,h]),--y.active||y.event.trigger("ajaxStop")))}return k},getJSON:function(e,t,n){return y.get(e,t,n,"json")},getScript:function(e,t){return y.get(e,void 0,t,"script")}}),y.each(["get","post"],function(e,t){y[t]=function(e,n,r,i){return y.isFunction(n)&&(i=i||r,r=n,n=void 0),y.ajax(y.extend({url:e,type:t,dataType:i,data:n,success:r},y.isPlainObject(e)&&e))}}),y._evalUrl=function(e){return y.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,throws:!0})},y.fn.extend({wrapAll:function(e){var t;return this[0]&&(y.isFunction(e)&&(e=e.call(this[0])),t=y(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrap:function(e){var t=y.isFunction(e);return this.each(function(n){y(this).wrapAll(t?e.call(this,n):e)})}});var vt=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,gt=/^margin/,yt=new RegExp("^(?:([+-])=|)("+vt+")([a-z%]*)$","i"),mt=new RegExp("^("+vt+")(?!px)[a-z%]+$","i"),xt=["Top","Right","Bottom","Left"],bt=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)},wt=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i};!function(){function t(){if(c){s.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",c.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",C.appendChild(s).appendChild(c);var t=e.getComputedStyle(c);r="1%"!==t.top,a="12px"===t.marginLeft,c.style.marginRight="60%",o="36px"===t.marginRight,i="36px"===t.width,C.removeChild(s),c=null}}var r,i,o,a,s=n.createElement("div"),c=n.createElement("div");c.style&&(c.style.backgroundClip="content-box",c.cloneNode(!0).style.backgroundClip="",d.clearCloneStyle="content-box"===c.style.backgroundClip,y.extend(d,{boxSizingReliable:function(){return t(),i},pixelPosition:function(){return t(),r},pixelMarginRight:function(){return t(),o},reliableMarginLeft:function(){return t(),a}}))}();function Tt(e,t,n){var r,i,o,a,s=e.style;return(n=n||bt(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||y.contains(e.ownerDocument,e)||(a=y.style(e,t)),!d.pixelMarginRight()&&mt.test(a)&>.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function Ct(e,t,n,r){var i,o=1,a=20,s=r?function(){return r.cur()}:function(){return y.css(e,t,"")},c=s(),u=n&&n[3]||(y.cssNumber[t]?"":"px"),l=(y.cssNumber[t]||"px"!==u&&+c)&&yt.exec(y.css(e,t));if(l&&l[3]!==u){u=u||l[3],n=n||[],l=+c||1;do{l/=o=o||".5",y.style(e,t,l+u)}while(o!==(o=s()/c)&&1!==o&&--a)}return n&&(l=+l||+c||0,i=n[1]?l+(n[1]+1)*n[2]:+n[2],r&&(r.unit=u,r.start=l,r.end=i)),i}function kt(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}var St=/^(none|table(?!-c[ea]).+)/,jt=/^--/,Et={position:"absolute",visibility:"hidden",display:"block"},Dt={letterSpacing:"0",fontWeight:"400"},At=["Webkit","Moz","ms"],Nt=n.createElement("div").style;function Ht(e){if(e in Nt)return e;var t=e[0].toUpperCase()+e.slice(1),n=At.length;while(n--)if((e=At[n]+t)in Nt)return e}function Ft(e){var t=y.cssProps[e];return t||(t=y.cssProps[e]=Ht(e)||e),t}function Ot(e,t,n){var r=yt.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Lt(e,t,n,r,i,o){var a="width"===t?1:0,s=0,c=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(c+=y.css(e,n+xt[a],!0,i)),r?("content"===n&&(c-=y.css(e,"padding"+xt[a],!0,i)),"margin"!==n&&(c-=y.css(e,"border"+xt[a]+"Width",!0,i))):(c+=y.css(e,"padding"+xt[a],!0,i),"padding"!==n?c+=y.css(e,"border"+xt[a]+"Width",!0,i):s+=y.css(e,"border"+xt[a]+"Width",!0,i));return!r&&o>=0&&(c+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-c-s-.5))),c}function Pt(e,t,n){var r=bt(e),i=Tt(e,t,r),o="border-box"===y.css(e,"boxSizing",!1,r),a=o;return mt.test(i)?i:(a=a&&(d.boxSizingReliable()||i===e.style[t]),"auto"===i&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)]),(i=parseFloat(i)||0)+Lt(e,t,n||(o?"border":"content"),a,r,i)+"px")}return y.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Tt(e,"opacity");return""===n?"1":n}}}},cssNumber:{opacity:!0,zIndex:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=y.camelCase(t),c=jt.test(t),u=e.style;if(c||(t=Ft(s)),a=y.cssHooks[t]||y.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:u[t];"string"==(o=typeof n)&&(i=yt.exec(n))&&i[1]&&(n=Ct(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(y.cssNumber[s]?"":"px")),d.clearCloneStyle||""!==n||0!==t.indexOf("background")||(u[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(c?u.setProperty(t,n):u[t]=n))}},css:function(e,t,n,r){var i,o,a,s=y.camelCase(t);return jt.test(t)||(t=Ft(s)),(a=y.cssHooks[t]||y.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Tt(e,t,r)),"normal"===i&&t in Dt&&(i=Dt[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),y.each(["height","width"],function(e,t){y.cssHooks[t]={get:function(e,n,r){if(n)return!St.test(y.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Pt(e,t,r):wt(e,Et,function(){return Pt(e,t,r)})},set:function(e,n,r){var i,o=bt(e),a="border-box"===y.css(e,"boxSizing",!1,o),s=r&&Lt(e,t,r,a,o);return s&&(i=yt.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=y.css(e,t)),Ot(e,n,s)}}}),y.cssHooks.marginLeft=kt(d.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Tt(e,"marginLeft"))||e.getBoundingClientRect().left-wt(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),y.each({margin:"",padding:"",border:"Width"},function(e,t){y.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+xt[r]+t]=o[r]||o[r-2]||o[0];return i}},gt.test(e)||(y.cssHooks[e+t].set=Ot)}),y.fn.extend({css:function(e,t){return ne(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=bt(e),i=t.length;a1)}}),y.ajaxSettings.xhr=function(){return new e.XMLHttpRequest},y.ajaxTransport(function(t){var n,r;return{send:function(i,o){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(a in i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?o(s.status,s.statusText):o(s.status,s.statusText,{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n("error"),s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),y.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),y.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return y.globalEval(e),e}}}),y.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),y.ajaxTransport("script",function(e){if(e.crossDomain){var t,r;return{send:function(i,o){t=y(" diff --git a/public/oops/font.html b/public/oops/font.html new file mode 100644 index 0000000000..4163ae8cb2 --- /dev/null +++ b/public/oops/font.html @@ -0,0 +1,144 @@ + + + + + + ! + " + # + $ + % + & + ' + ( + ) + * + + + , + - + . + / + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + : + ; + < + = + > + ? + @ + A + B + C + D + E + F + G + H + I + J + K + L + M + N + O + P + Q + R + S + T + U + V + W + X + Y + Z + [ + \ + ] + ^ + _ + ` + a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r + s + t + u + v + w + x + y + z + { + } + ~ + + + + + + + + + + + + + + + + + + Ò + + + diff --git a/public/oops/scheduled-maintenance.html b/public/oops/scheduled-maintenance.html index 2de76fa6bd..4d9c63c1c8 100644 --- a/public/oops/scheduled-maintenance.html +++ b/public/oops/scheduled-maintenance.html @@ -59,7 +59,7 @@
    diff --git a/public/oops/toomanyrequests.html b/public/oops/toomanyrequests.html index d6ce001884..fb7b39fd33 100644 --- a/public/oops/toomanyrequests.html +++ b/public/oops/toomanyrequests.html @@ -23,7 +23,7 @@
    diff --git a/public/piece-css/alpha.css b/public/piece-css/alpha.css new file mode 100644 index 0000000000..56bd4382f4 --- /dev/null +++ b/public/piece-css/alpha.css @@ -0,0 +1,12 @@ +.is2d .pawn.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik01MjAgMTc2OWgxMDA4cTgtOTctMTMyLTE4Mi0xMzItMTAxLTE5Ni41LTIzOS41VDExMjAgMTAzOUg5MjhxLTE1IDE3MC03OS41IDMwOC41VDY1MiAxNTg3cS0xNDEgODUtMTMyIDE4MnptNTA0IDc0SDQ0NnYtNzRxLTQtODAgNDEuNS0xMzdUNjEzIDE1MjRxMTE3LTkxIDE3MS41LTIxNy41VDg2MyAxMDM5SDU3NmwyODQtMjM5cS04Ni03NC04Ni0xODggMC0xMDMgNzMtMTc3dDE3Ny03NHExMDMgMCAxNzYuNSA3NHQ3My41IDE3N3EwIDExNC04NiAxODhsMjg0IDIzOWgtMjg3cTIzIDE0MSA3OCAyNjcuNXQxNzIgMjE3LjVxNzkgNTEgMTI0LjUgMTA4dDQyLjUgMTM3djc0ek03NTYgOTc0aDUzNmwtMjI1LTE5MXExMzQtMzEgMTM0LTE3MSAwLTc2LTUyLjUtMTI2LjVUMTAyNCA0MzVxLTczIDAtMTI1IDUwLjVUODQ3IDYxMnEwIDE0MCAxMzQgMTcxeiIgZmlsbD0iIzEwMTAxMCIvPjxnIGZpbGw9IiNmOWY5ZjkiPjxwYXRoIGQ9Ik04NzMuNDU3IDg4MS4zNDdjNTYuNTQ4LTQ3LjkxMiAxMDMuOTAxLTkwLjIyNSAxMDUuMjMtOTQuMDI4cy0xMy41Ni0xNC4xMTktMzMuMDg2LTIyLjkyNGMtMTUyLjI1Mi02OC42NTYtMTA4LjA5My0zMDIuNTM3IDYwLjktMzIyLjU1MiAzNS41MzctNC4yMDggNTEuMTYtMS4wNDMgOTAuOTYgMTguNDMgMTI5LjI3OCA2My4yNSAxMzIuMjU3IDI0Ni43MDkgNC45MzggMzA0LjEyMi0xOS41MjYgOC44MDUtMzQuNDE1IDE5LjEyLTMzLjA4NiAyMi45MjQgMS4zMjggMy44MDMgNDguNjgyIDQ2LjExNiAxMDUuMjMgOTQuMDI4bDEwMi44MTUgODcuMTE0SDc3MC42NDJ6Ii8+PHBhdGggZD0iTTc4MS4wMTcgOTYxLjg3YzAtMy42MjQgNy4wMjktMTAuOTggMTUuNjItMTYuMzQ1IDIxLjE5Ni0xMy4yMzcgMTc4LjkzMS0xNTIuMDcgMTgyLjQyLTE2MC41NiAxLjUzMi0zLjcyOC03LjI1NC05LjI5OS0xOS41MjUtMTIuMzc5LTEyLjI3Mi0zLjA4LTIyLjMxMi04LjQyMi0yMi4zMTItMTEuODdzLTkuNzIzLTExLjQ3NS0yMS42MDgtMTcuODM2Yy00OS41NzktMjYuNTMzLTcyLjM1Mi0xMjcuNTMtNDQuMDM3LTE5NS4yOTcgNS45ODMtMTQuMzIgMTEuNDg2LTI4Ljk2NiAxMi4yMjgtMzIuNTQ2IDIuMjEyLTEwLjY2NyAzNS4zNzMtNDEuMjIgNDQuNzQtNDEuMjIgNC43NzIgMCA4LjY3Ny0zLjIzNCA4LjY3Ny03LjE4OCAwLTEzLjIgODEuOTQ3LTI2Ljc4NiAxMTUuNjgxLTE5LjE3OCA1MC43MzQgMTEuNDQzIDExNi43OTMgNjIuMTMgMTI2LjIxIDk2Ljg0MiAxOS43MzUgNzIuNzUyIDE5LjQzIDEwMi42NC0xLjQ1NSAxNDIuOTc1LTE1Ljk1NCAzMC44MTItNjYuMDE2IDc3LjQwMy05Mi4wNDYgODUuNjY0LTEwLjU0NiAzLjM0OC0xNy45ODQgOC45NS0xNi41MjggMTIuNDUgMy40MTggOC4yMTcgMTYxLjc1NyAxNDcuMzI2IDE4Mi4yODEgMTYwLjE0MyA4LjU5MSA1LjM2NSAxNS42MiAxMi43MiAxNS42MiAxNi4zNDZzLTEwOS4zNDIgNi41OS0yNDIuOTgzIDYuNTljLTEzMy42NCAwLTI0Mi45ODMtMi45NjYtMjQyLjk4My02LjU5em0tMjYwLjMzOSA3OTYuMDA3YzAtMTUuODUgMjYuMjM2LTcyLjMzNSA0MS41NTEtODkuNDU2IDguMTctOS4xMzQgNTAuMTA3LTQ1LjAyNCA5My4xOTMtNzkuNzU2IDE1Mi45NDEtMTIzLjI5IDIzMy41ODgtMjY2LjUxNSAyNjUuOTc5LTQ3Mi4zNjRsMTAuOTczLTY5LjczOGgxODMuMjUybDEwLjk3MyA2OS43MzhjMzEuMDQgMTk3LjI3IDExMy42ODEgMzQ5LjUzIDI0OC4xMDcgNDU3LjEyMyAxMTUuMDQxIDkyLjA3NyAxMzMuODQgMTEzLjcyNiAxNDcuMjI1IDE2OS41NDVsNS43MjIgMjMuODY1aC01MDMuNDg4Yy0zNDAuMzE4IDAtNTAzLjQ4Ny0yLjkwMy01MDMuNDg3LTguOTU3eiIvPjwvZz48L3N2Zz4=')} +.is2d .knight.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMDA0IDEwOTJxMzEgMTcgNTQgNDIgMjEtMTUgMzYuNS0xMy41dDMzLjUtMS41cTc4LTExIDEyOC41LTg1dDUyLjUtMTY1bC0xOS02N3EtNTUgMjM5LTE4OCAyNTctMjEgMy00NSA1LjV0LTUzIDI3LjV6TTc0NiA2NDNsLTQ2LTYwcTYtMzkgMTE1LjUtMTA3LjVUMTAzNiAzMzJsMTE1LTE1NCA5NiAyMTdxMzQyIDE3MiA0MzIuNSA0MTcuNVQxNzI3IDE0MTZxLTE4IDEyOCA0LjUgMjM2LjVUMTc4OSAxODQzSDU0N3EtOS0xNzggMzktMzAxLjVUNzY5IDEzMDRxNzgtMTYgMTE1LTcxdDU1LTg1cS0yMzYtNDItMjkyIDYwbC01NiAxMDItMjE3LTEyMSAxMTUtODItNTEtNTAtMTIyIDg2LTEyLTI5NyAzOTYtMjYzcTEyIDE4IDIzIDMxdDIzIDI5TDM4MCA4ODRsNCAxMjUgNjQtNDEgMTM4IDE0NC03OCA2NSA0NyAyOCAzOC41LTQ1IDEwOC41LTczcTU0LTE4IDE2NS0yN3QxOTEgNzRxLTU2IDYzLTkxIDEzMi41VDgxNSAxMzY5cS05MiA3OS0xNDYgMTc2LjVUNjIxIDE3NjloMTAxOXEtMzUtMTMzLTMyLTIzNC41dDEyLjUtMTk5IDktMjA1VDE1ODkgODc4cS01MS0xMjYtMTM0LTIzNHQtMjYyLTE4OGwtNTktMTMzLTQ5IDY5cS05OSA2Mi0yMDggMTMxVDc0NiA2NDN6bTI5MiAzMGwtMjEyLTIgMTE2LTEwMHEzMC0yNSA4MCAzOC41dDE2IDYzLjV6TTUwMiA4NjhsMzcgMzEtNDYgNTUtNTctMjYgMzMtNTZ6IiBmaWxsPSIjMTAxMDEwIi8+PHBhdGggZD0iTTYyNy45NDcgMTcwNi4zMDZjNy4wNjUtNzYuMDE0IDMwLjY1OC0xMzkuNjg3IDc2LjAxNS0yMDUuMTQyIDU1LjYxMy04MC4yNTcgOTQuMzM1LTExNi4xNDcgMTU1LjE0LTE0My43OTQgNzEuMzA0LTMyLjQyMSA3OS4zODUtMzkuODgxIDEzNC41ODItMTI0LjIzMSA2Mi4yMTEtOTUuMDY5IDc2LjM5LTEwOC40MzUgMTE1LjI2NC0xMDguNjY1IDQyLjMwNy0uMjUgOTQuOTExLTI1LjMyMSAxMjkuMzg3LTYxLjY2NSA1Ni4xNC01OS4xODIgODUuNjUtMTY5Ljk5NyA2My4zMDEtMjM3LjcxMmwtMTAuOTA3LTMzLjA0OC0yMy42NDUgNzAuNDc0Yy0zNC4xMyAxMDEuNzIzLTY1LjQ5NCAxNDYuNTAyLTEyMy40MTYgMTc2LjIwNi0xNy43MDggOS4wODItNDIuMjQgMTYuNTEyLTU0LjUxNiAxNi41MTItMTIuMjc2IDAtMzYuNTQ2IDUuOTQ0LTUzLjkzNCAxMy4yMS0yOC41OSAxMS45NDUtMzUuNzQ4IDExLjgzNi03NC44MDgtMS4xMzgtNDYuNTg2LTE1LjQ3My0xNDQuMDc4LTEyLjM3OC0yMjIuNTYxIDcuMDY2LTQyLjgyMSAxMC42MS0xNTkuNzIgODQuNDg0LTE2OC4wNTQgMTA2LjIwNC02LjExNSAxNS45MzYtMjQuMjEyIDE3LjU4My0zOC4zMDkgMy40ODYtNy41NzMtNy41NzMtMS4zMzktMTcuNzIgMjUuNTM2LTQxLjU3bDM1LjU1NS0zMS41NTItNjkuNjEtNzMuMzUxLTY5LjYxMS03My4zNTItMzAuMzM1IDE0LjQ2Ni0zMC4zMzQgMTQuNDY1LTUuNDI4LTM5LjYwMmMtMi45ODYtMjEuNzgxLTUuNDI4LTQ1LjAxOS01LjQyOC01MS42MzkgMC02LjYyIDgyLjAzLTY2LjMzMyAxODIuMjkxLTEzMi42OTYgMTAwLjI2LTY2LjM2MiAxOTMuMDA2LTEzMy42MjEgMjA2LjEwMi0xNDkuNDY0IDM2LjI1Ny00My44NjIgNDguNDQ4LTUyLjk3NyAxOTAuNzA3LTE0Mi41ODcgOTUuNzY4LTYwLjMyNCAxMzcuNTE4LTkxLjg5NCAxNTEuNTQ2LTExNC41OTFsMTkuMzYyLTMxLjMyOCAyOS41NTYgNjYuMDg1YzI2LjAyIDU4LjE3NSAzMy44MjMgNjguMDAzIDY1LjIgODIuMTIxIDE5MC40MzcgODUuNjg3IDMzMy41MTYgMjczLjM3IDM3OS4zOTMgNDk3LjY2NSAxOS41NTIgOTUuNTg4IDE5LjgyMiAxNDkuMTA2IDIuNjI1IDUyMC42NzgtNC4yMjQgOTEuMjctMi4zIDEzMi4yMTYgOC43MTEgMTg1LjMzNSA3Ljc3NCAzNy41IDE0LjEzNCA3MS42NyAxNC4xMzQgNzUuOTMyIDAgNC40NTktMjE0LjI2NSA3Ljc1LTUwNC41NjkgNy43NUg2MjIuMzIxem0tMTAwLjE1LTgyMS45NDRjLTI3LjE4OC0yOC45NDEtNTUuODc3LTI1Ljg4NC03Ni42MzggOC4xNjctMjIuNTYgMzctMjIuMTI0IDM5LjExMyAxMC45NDMgNTMuMTA0IDI2LjkzMyAxMS4zOTcgMjkuNDcxIDEwLjczNyA1Ni4zNjEtMTQuNjVsMjguMTU4LTI2LjU4NXptNTIzLjU3My0yMzIuNDVjLTQuNjU4LTI2LjYxOC01Mi41My04Mi4wODgtNzUuOTA5LTg3Ljk1NS0yNC42NTYtNi4xODgtNDEuNzc2IDQuMTQtMTA3LjY2NCA2NC45NTVsLTQ3LjczIDQ0LjA1NCAxMTcuMTUzLTEuOTQ4YzExMS40MDctMS44NTEgMTE3LjAwNi0yLjc4OCAxMTQuMTUtMTkuMTA2eiIgZmlsbD0iI2Y5ZjlmOSIvPjwvc3ZnPg==')} +.is2d .bishop.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMDI0IDM1NnE2NiAwIDY0LTY2IDEtNTUtNjQtNTUtNjYgMC02NCA1NS0zIDY2IDY0IDY2em0wIDEyMDRxMCAxMTQtMTAxIDE5OC41VDcwMCAxODQzSDIwNXEwLTExNyA2NS0xNzl0MTQyLTYyaDI1MHE1MSAwIDg4LTd0NzEtNjBxMTItMjAgMTAtMTZoNzZxLTcgMjEtMyAxMy00NSAxMDUtMTA5IDEyNC41VDY0OSAxNjc2SDQwOXEtNTIgMC04NiA0MHQtMzQgNTNoNDI0cTY2IDAgMTU4LjUtNjV0OTMuNS0xODVINjI0cTY3LTExNiA3Mi0yMjktMTE0LTExOS0xNjItMjIzLjVUNTI4IDg0M3EzMy05NiAxMTgtMTg5LjVUOTU4IDQwN3EtMTctMTEtNDYtMzZ0LTI5LTc5cTAtNTggNDEtOTZ0MTAwLTM4cTU4IDAgOTkuNSAzOHQ0MS41IDk2cTAgNTQtMjkuNSA3OXQtNDUuNSAzNnEyMjYgMTUzIDMxMSAyNDYuNVQxNTIwIDg0M3E0MiAxMTktNiAyMjMuNVQxMzUyIDEyOTBxNCAxMTMgNzIgMjI5aC0zNDFxMCAxMjAgOTMgMTg1dDE1OSA2NWg0MjRxMC0xMy0zNC41LTUzdC04NS41LTQwaC0yNDBxLTgzIDAtMTQ2LjUtMTkuNVQxMTQ0IDE1MzJxNCA4LTMtMTNoNzZxLTItNCAxMCAxNiAzMyA1MyA3MCA2MHQ4OSA3aDI1MHE3NiAwIDE0MS41IDYydDY1LjUgMTc5aC00OTVxLTEyMyAwLTIyMy41LTg0LjVUMTAyNCAxNTYwem0wLTExNGgyODNxLTI4LTg0LTI5LTE1NC0xMjAtNDEtMjU0LTM4LTEzNS0zLTI1NCAzOC0yIDcwLTI5IDE1NHptMC0yNjdxMTU5LTEgMjg1IDQyIDE4OS0xODAgMTQyLTM0Ni02MC0xOTMtNDI3LTQzMS0zNjggMjM4LTQyNyA0MzEtNDggMTY2IDE0MiAzNDYgMTI1LTQzIDI4NS00MnptLTQ3LTM2MVY3MTRoOTR2MTA0aDk1djg5aC05NXYxNjVoLTk0VjkwN2gtOTV2LTg5eiIgZmlsbD0iIzEwMTAxMCIvPjxwYXRoIGQ9Ik05ODAuMTggMzMzLjM0NGMtMjIuMTktMjIuMTktMjIuMTktNTUuOTEzIDAtNzguMTAyIDM1LjgzOC0zNS44MzggMTA0LjEzNS0xMC4yMjcgMTA0LjEzNSAzOS4wNSAwIDI5LjQ1OC0yOS4wMjMgNTYuNDA4LTYwLjc0NiA1Ni40MDgtMTQuNDYzIDAtMzMuNzQ3LTcuNzE0LTQzLjM5LTE3LjM1NnptLTI4OC42MjMgODI5LjU4Yy04Ni4wMTYtMTAzLjMwNC0xMTguNDMtMjE3LjUxNS04NS4yMDQtMzAwLjIyNCAyMy40Ni01OC40MDIgODcuNjI1LTE0NS40ODIgMTUyLjg1NC0yMDcuNDQzIDY2LjY1Ni02My4zMTcgMTkzLjgzNy0xNjEuNzE1IDI0My43ODktMTg4LjYxNmwyNy4zMzgtMTQuNzIyIDkwLjc5NCA2Ni4xNjdjMjMwLjMxIDE2Ny44NDEgMzQ3LjIyNiAzMjMuNDQ0IDMzMy4xNjkgNDQzLjQxMS02LjgxIDU4LjExNS00Ni4wNCAxMzguMTY0LTk4LjcxNiAyMDEuNDI3bC00NC4wNDkgNTIuOTAxLTYzLjcxLTE3LjQ2MWMtNTMuMTY2LTE0LjU3Mi05MC4yOC0xNy40NjItMjI0LjI1My0xNy40NjItMTMzLjk3MyAwLTE3MS4wODYgMi44OS0yMjQuMjUyIDE3LjQ2MmwtNjMuNzEgMTcuNDYxem0zODQuMDgtMTY1LjcxNnYtODIuNDRoOTUuNDU4VjgxMC42MzJoLTk1LjQ1OFY3MDYuNDk2SDk3MS41MDF2MTA0LjEzNmgtOTUuNDU4djEwNC4xMzZoOTUuNDU4djE2NC44OGgxMDQuMTM2em0tMzI5LjY2IDQ0NC43NDZjLjA1Ny0xLjE5MyA1Ljg2OC0yMy42NDggMTIuOTE0LTQ5Ljg5OCA3LjA0Ni0yNi4yNTEgMTIuODU4LTU4LjM2IDEyLjkxNC03MS4zNTEuMDkzLTIxLjE1NyA1LjMxLTI1LjIzMiA1MC4wMDItMzkuMDUxIDcwLjg4Ny0yMS45MTkgMzMxLjU4LTIyLjI2MSA0MDEuNzEtLjUyOGw0OC4wODMgMTQuOTAxIDEwLjIyMyA1OS42MThjNS42MjMgMzIuNzkgMTIuNzE1IDY2LjExMiAxNS43NiA3NC4wNDggNS4wOTMgMTMuMjctMTYuODU3IDE0LjQzLTI3My4wODUgMTQuNDMtMTUzLjI0MyAwLTI3OC41NzctLjk3Ni0yNzguNTItMi4xNjl6bS00MzMuNzUxIDI5Ni44NjljMzguMjAzLTUzLjY1IDQ2LjIyNC01NS41NzQgMjU1LjMzMi02MS4yMzYgMTA1LjI2Ni0yLjg1IDIwNS4zMjYtOS42ODcgMjIyLjQ0MS0xNS4xOTkgMzguNjMyLTEyLjQ0IDg3LjMwOC02MC4xNCAxMDcuODQ1LTEwNS42ODUgMTIuNzk0LTI4LjM3MiAxOS44ODYtMzQuNDc4IDQwLjA0Ny0zNC40NzggMjIuOTIgMCAyNC4xNjQgMS44MTggMTkuMzA3IDI4LjIwMy0xNS42MTcgODQuODM2LTU4Ljg2MSAxMzYuNzE3LTE1My45MTMgMTg0LjY1MmwtNTkuNzQzIDMwLjEyOEgyOTMuNDM4em05MzEuNjI4LTMuNzQzYy05NS41OS00OC4yMDctMTM1LjA5NC05NC4wMDMtMTUwLjAyNS0xNzMuOTIzLTcuMTItMzguMTA3LTYuNzkyLTM4LjkyNiAxNS40Ny0zOC42NzQgMTguNDQuMjEgMjguMTcxIDkuNjUzIDUxLjQxNyA0OS44OTggNTMuODU1IDkzLjIzOSA5Mi42MTIgMTA1Ljc5MiAzMjcuMTI0IDEwNS45NTggMTgzLjcxMS4xMyAyMDQuOTk3IDUuMjE2IDI0NS41MiA1OC42NjZsMjEuMzgzIDI4LjIwM2gtNDUxLjE0N3oiIGZpbGw9IiNmOWY5ZjkiLz48L3N2Zz4=')} +.is2d .rook.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMDI0IDE1MDFINjQzbDUtNzRoNzUybDUgNzR6bTAtNjYxSDY5Mmw1LTc0aDY1NGw1IDc0em0wIDEwMDNIMzgzbDI5LTI2NCAxNTktMTE4IDUwLTY1OS0xNDktMTA3LTE3LTM0MWgyODl2MTQ3aDEzN1YzNTRoMjg2djE0N2gxMzdWMzU0aDI4OWwtMTcgMzQxLTE0OSAxMDcgNTAgNjU5IDE1OSAxMTggMjkgMjY0em0wLTc0aDU1N2wtMTUtMTQ5LTE2MS0xMTktNTQtNzM1IDE1Mi0xMDkgMTMtMjMwaC0xMzh2MTQ4aC0yODVWNDI3SDk1NXYxNDhINjcwVjQyN0g1MzJsMTMgMjMwIDE1MiAxMDktNTQgNzM1LTE2MSAxMTktMTUgMTQ5eiIgZmlsbD0iIzEwMTAxMCIvPjxwYXRoIGQ9Ik02NTUuODMyIDEzNzguNDk1YzUuMDIzLTQ5LjY4NCAzOC40MDUtNTAwLjU2NyAzOC40MDUtNTE4LjcyMiAwLTExLjA2MSA0NC44NjgtMTIuODA0IDMyOS43NjMtMTIuODA0czMyOS43NjMgMS43NDMgMzI5Ljc2MyAxMi44MDRjMCAxOC4xNTUgMzMuMzgyIDQ2OS4wMzggMzguNDA1IDUxOC43MjJsNC4xNjcgNDEuMjJoLTc0NC42N3ptLTMxLjA0OC02NzAuODQ4bC03My43MzMtNTIuNTQzLTUuNjQ3LTcxLjExOGMtMy4xMDYtMzkuMTE1LTYuMDM1LTg5LjY2Ny02LjUwOS0xMTIuMzM5bC0uODYxLTQxLjIyaDEzMC4xNjl2MTQ3LjUyNmgyOTUuMDUxVjQzMC40MjdoMTIxLjQ5MnYxNDcuNTI2aDI5NS4wNTFWNDMwLjQyN2gxMzAuMTY5bC0uODYgNDEuMjJjLS40NzUgMjIuNjcyLTMuNDAzIDczLjIyNC02LjUxIDExMi4zNGwtNS42NDcgNzEuMTE3LTczLjczMyA1Mi41NDMtNzMuNzM0IDUyLjU0M0g2OTguNTE4ek00NzEuNjY3IDE3NTEuNjQ4YzIuMzI0LTguMzUzIDYuNzUxLTQxLjA2IDkuODM4LTcyLjY4NGw1LjYxMS01Ny40OTcgNzkuMzM1LTU3LjQ4NiA3OS4zMzUtNTcuNDg2aDc1Ni40MjhsNzkuMzM1IDU3LjQ4NiA3OS4zMzUgNTcuNDg2IDUuNjExIDU3LjQ5N2MzLjA4NyAzMS42MjMgNy41MTQgNjQuMzMgOS44MzggNzIuNjgzIDMuOTkzIDE0LjM1LTI2LjQ1MiAxNS4xODctNTUyLjMzMyAxNS4xODdzLTU1Ni4zMjYtLjgzNy01NTIuMzMzLTE1LjE4NnoiIGZpbGw9IiNmOWY5ZjkiLz48L3N2Zz4=')} +.is2d .queen.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Im0xMDI0IDE3NjloNDc4cS01My0xMzAtNDMtMjgwLTEwMC0zOS0yMTMtNjcuNXQtMjIyLTI4LjVxLTExMCAwLTIyMyAyOC41dC0yMTIgNjcuNXE5IDE1MC00MyAyODB6bTAtNDUwcTExMSAwIDIyMy41IDI2LjV0MjIwLjUgNjcuNXExNy0xMDUgNjAuNS0yMTIuNXQxMDUuNS0yMTIuNWwtMjIwIDE1NS0xMjMtNjAxLTI2NyA1NTUtMjY3LTU1NS0xMjMgNjAxLTIyMC0xNTVxNjEgMTA1IDEwNC41IDIxMi41dDYxLjUgMjEyLjVxMTA4LTQxIDIyMC41LTY3LjV0MjIzLjUtMjYuNXptMCA1MjRoLTU4M3ExMTQtMjMxIDU3LjUtNDU2LjV0LTIwMi41LTQ0OS41cS0xMiAyLTE5IDItNTQgMC05Mi41LTM4LjV0LTM4LjUtOTIuNSAzOC41LTkyLjUgOTIuNS0zOC41IDkyLjUgMzguNSAzOC41IDkyLjVxMCAyMC02IDM4LTQgMTQtMTUgMzNsMTk2IDEzOSAxMDAtNDg2cS02NC0zMS03Mi0xMDMtNS00NCAyOS05MXQ4OC01M3E1NC01IDk2IDI5dDQ4IDg4cTcgNjgtNDYgMTE0bDE5OCA0MTIgMTk4LTQxMnEtNTQtNDYtNDYtMTE0IDYtNTQgNDgtODh0OTYtMjlxNTQgNiA4Ny41IDUzdDI5LjUgOTFxLTkgNzItNzIgMTAzbDEwMCA0ODYgMTk2LTEzOXEtMTItMTktMTUtMzMtNi0xOC02LTM4IDAtNTQgMzguNS05Mi41dDkyLjUtMzguNSA5Mi41IDM4LjUgMzguNSA5Mi41LTM4LjUgOTIuNS05Mi41IDM4LjVxLTcgMC0xOS0yLTE0NyAyMjQtMjAzIDQ0OS41dDU4IDQ1Ni41em0tNzQ4LTEwOTdxLTYyIDAtNjIgNjJ0NjIgNjJxNjMgMCA2My02MnQtNjMtNjJ6bTQ2Ni0zOTRxLTYyIDAtNjIgNjJ0NjIgNjIgNjItNjItNjItNjJ6bS0xNTIgMTE2NyAxMTkgNzItMTM0IDg2cTE5LTg2IDE1LTE1OHptMTE4Mi03NzNxLTYzIDAtNjMgNjJ0NjMgNjJxNjIgMCA2Mi02MnQtNjItNjJ6bS00NjYtMzk0cS02MiAwLTYyIDYydDYyIDYyIDYyLTYyLTYyLTYyem0xNTIgMTE2Ny0xMTkgNzIgMTM0IDg2cS0yMC04Ni0xNS0xNTh6bS01NzMgNDcgMTM5LTgzIDEzOSA4Ni0xMzkgODR6IiBmaWxsPSIjMTAxMDEwIi8+PGcgZmlsbD0iI2Y5ZjlmOSI+PHBhdGggZD0ibTU3Ni43NzQgMTM3NC4xNTZjLTE0LjI2Ny02Ni43NC01Mi4zMjgtMTczLjQ0MS05MS44MTMtMjU3LjM5My0yMy4zNy00OS42ODgtNDAuODM1LTkxLjk5OS0zOC44MS05NC4wMjQgMi4wMjUtMi4wMjQgNDUuODMgMjYuMTc2IDk3LjM0NCA2Mi42NjhsOTMuNjYzIDY2LjM1IDU4LjQ0Ny0yODQuNzMzYzMyLjE0NS0xNTYuNjA0IDU5LjYzMi0yOTAuMzA0IDYxLjA4Mi0yOTcuMTE0czYwLjk0NCAxMDkuMzY3IDEzMi4yMTIgMjU4LjE3YzcxLjI2NyAxNDguODAyIDEzMi4wNjIgMjcwLjU1IDEzNS4xMDEgMjcwLjU1czYzLjgzNC0xMjEuNzQ4IDEzNS4xMDEtMjcwLjU1YzcxLjI2Ny0xNDguODAzIDEzMC43NjMtMjY0Ljk4IDEzMi4yMTItMjU4LjE3IDEuNDUgNi44MSAyOC45MzYgMTQwLjUxIDYxLjA4MiAyOTcuMTEzbDU4LjQ0NyAyODQuNzMyIDkzLjY2My02Ni4zNDljNTEuNTE0LTM2LjQ5MiA5NS41NDItNjQuNDcgOTcuODM5LTYyLjE3M3MtMTEuOTU3IDM2LjI2NC0zMS42NzUgNzUuNDhjLTM4LjQ3NCA3Ni41MjItNzguMzE2IDE4NC40MDUtOTUuMzE0IDI1OC4wODYtNS43OCAyNS4wNTgtMTMuMDUgNDUuNDktMTYuMTUzIDQ1LjQwNnMtNDEuNjYtMTEuNTIxLTg1LjY4LTI1LjQxNWMtMTQyLjUzNi00NC45ODctMjEyLjk4OC01Ni4zNDQtMzQ5LjUyMi01Ni4zNDRzLTIwNi45ODYgMTEuMzU3LTM0OS41MjEgNTYuMzQ0Yy00NC4wMjEgMTMuODk0LTgyLjY1NyAyNS4zMy04NS44NTcgMjUuNDE1LTMuMi4wODQtOC41MzItMTIuNTM4LTExLjg0OC0yOC4wNXoiLz48cGF0aCBkPSJtNTU4LjkyNiAxNzQ3LjMwOWMzLjA1OC0xMC43NCA3Ljc3MS0yOS41ODkgMTAuNDc0LTQxLjg4OCAzLjU3NC0xNi4yNjEgMjMuNjAzLTM0LjAxNSA3My40MjQtNjUuMDg0IDM3LjY4LTIzLjQ5OCA2OC41NjgtNDUuMjA0IDY4LjY0LTQ4LjIzNi4wNy0zLjAzMi0yNy4yMDYtMjIuMDMtNjAuNjE3LTQyLjIxNi0zMy40MS0yMC4xODctNjAuNzQ1LTQxLjM0LTYwLjc0NS00Ny4wMDUgMC0xMi43NjkgMTQxLjMyLTU5LjgxMiAyNTEuMzU3LTgzLjY3NCAxMTAuOTY0LTI0LjA2MiAyNTQuMTE4LTI0LjA2MiAzNjUuMDgyIDAgMTEwLjAzNyAyMy44NjIgMjUxLjM1NyA3MC45MDUgMjUxLjM1NyA4My42NzQgMCA1LjY2Ni0yNy4zMzUgMjYuODE4LTYwLjc0NSA0Ny4wMDVzLTYwLjY2IDM5LjE4NC02MC41NTQgNDIuMjE2Yy4xMDUgMy4wMzIgMjkuNDI5IDIzLjkgNjUuMTYzIDQ2LjM3NiA2Mi44NDIgMzkuNTIzIDczLjgwNCA1Mi45NTMgODcuMzggMTA3LjA0NWw1LjM1IDIxLjMxMmgtOTQxLjEyNnptNTM4LjUyOS0xMzIuOTljMzUuOTY2LTIxLjgzNSA2NS4zNzMtNDIuMzM2IDY1LjM0OC00NS41NTktLjA1NC03LjE0My0xMjcuNzE0LTg4LjI5OS0xMzguODk3LTg4LjI5OS0xNC43MjggMC0xMzkuNjI1IDc5LjgyNy0xMzcuMDA1IDg3LjU2NiAzLjQwMiAxMC4wNDggMTIwLjk5NiA4NC42NTQgMTM0LjYyMiA4NS40MSA1Ljc5Ny4zMiAzOS45NjYtMTcuMjgyIDc1LjkzMi0zOS4xMTd6bTY0MC43NC03NTYuODc5Yy0yNy45MjQtMTcuNzUxLTI3Ljg1My04MS4zMy4xMS05OS4xMSAzNS4zMzYtMjIuNDY5IDkyLjc0NiA4LjIyNyA5Mi43NDYgNDkuNTg5IDAgNDEuNDMtNTcuNDE0IDcyLjA1LTkyLjg1NiA0OS41MnptLTQ1My44NTYtMzg5LjQ2NWMtMzQuMjc2LTEyLjcyNS00Ni42OTMtNjcuNzE2LTIxLjA3NS05My4zMzUgMTcuNTc2LTE3LjU3NiA2Ny45NjQtMTcuNTc2IDg1LjU0IDAgMTYuMzYyIDE2LjM2MiAxNy44MTcgNTUuNjc1IDIuNzkgNzUuMzQ4LTEyLjE0OSAxNS45MDMtNDcuNDQzIDI1LjM0Mi02Ny4yNTUgMTcuOTg3em0tNTY0LjA2OCAwYy0zNC4yNzYtMTIuNzI1LTQ2LjY5My02Ny43MTYtMjEuMDc1LTkzLjMzNSAxNy41NzYtMTcuNTc2IDY3Ljk2NC0xNy41NzYgODUuNTQgMCAxNi4zNjIgMTYuMzYyIDE3LjgxNyA1NS42NzUgMi43OSA3NS4zNDgtMTIuMTQ4IDE1LjkwMy00Ny40NDIgMjUuMzQyLTY3LjI1NSAxNy45ODd6bS00ODUuOTY2IDM3OC45OTVjLTIyLjE5LTIyLjE5LTIyLjE5LTU1LjkxMyAwLTc4LjEwMiAxNy40NDEtMTcuNDQyIDU2LjEtMjIuODAyIDc1LjUtMTAuNDcgMjcuOTI0IDE3Ljc1IDI3Ljg1MyA4MS4zMjktLjExIDk5LjExLTE5LjMgMTIuMjctNTcuOTg5IDYuODYzLTc1LjM5LTEwLjUzOXoiLz48L2c+PC9zdmc+')} +.is2d .king.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik05NzcgMjk4di05NWg5NHY5NWgxMDd2OTVoLTEwN3YxNTNxLTQ4LTE2LTk0IDBWMzkzSDg3MHYtOTV6bTQ3IDMxNHEtNDcgMC0xMzYgMTIxLTMxLTM2LTUwLTU1IDkzLTE0MCAxODYtMTQwIDkyIDAgMTg2IDE0MC0yMCAxOS01MCA1NS05MC0xMjEtMTM2LTEyMXptLTQ0NyA5MDdsLTI2IDE1NiAxNDUtODR6bTQxMC0yMDZxLTEtMTQ3LTM2LjUtMjc0LjVUODcwIDg0NXEtNDUtODgtMTMxLjUtMTUzVDU3MCA2MjdxLTEwMyAwLTIwOCA5M1QyNTcgOTQ5cTAgMTA5IDg2LjUgMjM2VDU0NiAxNDA4cTIxMi04OCA0NDEtOTV6bTM3IDUzMEg0NDhsNjEtMzY1cS0zMjUtMjgwLTMyNi01MzUtMS0xNTkgMTI1LTI3NC41VDU3NSA1NTNxNzggMCAxNTguNSA0N1Q4NzYgNzE5cTYxIDc0IDk4LjUgMTY0LjVUMTAyNCAxMDM0cTEyLTYwIDQ5LTE1MC41dDk5LTE2NC41cTYxLTcyIDE0Mi0xMTl0MTU5LTQ3cTE0MCAwIDI2NiAxMTUuNVQxODY1IDk0M3EtMiAyNTUtMzI2IDUzNWw2MSAzNjV6bTAtNzRoNDg5bC01MC0yOThxLTIxNi04NC00MzktODR0LTQzOSA4NGwtNTAgMjk4em00NDctMjUwbDI2IDE1Ni0xNDUtODR6bS00MTAtMjA2cTIyOSA3IDQ0MSA5NSAxMTUtOTYgMjAyLTIyM3Q4Ny0yMzZxMC0xMzYtMTA1LjUtMjI5VDE0NzggNjI3cS04MyAwLTE2OS41IDY1VDExNzggODQ1cS00NiA2Ni04MS41IDE5My41VDEwNjEgMTMxM3ptLTE3NiAyMzNsMTQxLTg0IDEzNyA4Ni0xNDEgODR6IiBmaWxsPSIjMTAxMDEwIi8+PGcgZmlsbD0iI2Y5ZjlmOSI+PHBhdGggZD0iTTQ2Ny40NzMgMTMyNC43MzdjLTEzNC43My0xMzkuMzcxLTIwMC40MjgtMjU5LjY0Mi0yMDEuNzI3LTM2OS4yOTMtMS4wNDgtODguNDU1IDE5Ljk5My0xNDEuMjc1IDgzLjE5Mi0yMDguODM1IDEzOC43MTYtMTQ4LjI4OCAyOTYuODAxLTE0OC45NiA0MzcuNjEzLTEuODU5IDYyLjUwMyA2NS4yOTYgMTA3LjMwMiAxNDIuODUzIDE0Mi40OTMgMjQ2LjY4NyAyNy44MjkgODIuMTEzIDUxLjQ3NCAyMDcuNDg3IDUxLjUzMSAyNzMuMjMyLjAzOCA0NC4zNzYtOC4zNTkgNTAuNTI2LTY5LjM4OSA1MC44Mi01NS4yNTIuMjY2LTE4NS4yMiAyNi45NzgtMjc3LjY5NCA1Ny4wNzRsLTkxLjEyIDI5LjY1NXptNTQ0Ljc4LTM0Ny43NTdjLTguODg3LTQ0LjQzNC01OC4xOS0xNTQuODQzLTg5LjQxNy0yMDAuMjRsLTI5LjY5Mi00My4xNjQgMzIuMDYzLTM5LjEzYzc4LjI5Ny05NS41NSAxMTkuMjg5LTk1LjU1IDE5Ny41ODYgMGwzMi4wNjMgMzkuMTMtMjkuNjkyIDQzLjE2NGMtMzEuMjI3IDQ1LjM5Ny04MC41MyAxNTUuODA2LTg5LjQxNyAyMDAuMjQtNi42OTcgMzMuNDgzLTE2Ljc5NyAzMy40ODMtMjMuNDk0IDB6Ii8+PHBhdGggZD0iTTQ3MC4zNzYgMTMyNS42NzljLTE0NC4yLTE2MC44OC0xOTIuNjYxLTI0Ni44NjQtMTk5LjU0LTM1NC4wNDItNS4wNS03OC43MTIgOC43MzktMTMxLjc4OCA0Ny4zOTctMTgyLjQzMyAxNS44ODctMjAuODEzIDI4Ljg4Ni00MS43MTQgMjguODg2LTQ2LjQ0NSAwLTQuNzMyIDQuMzY1LTguNjAzIDkuNzAxLTguNjAzczIzLjcwNy0xMi4yOTcgNDAuODI1LTI3LjMyNmM3Ny4xNDYtNjcuNzM1IDE3NC4yMjctODYuNDg4IDI1OS4xOTItNTAuMDY4IDE1NS45NSA2Ni44NDcgMjY2LjAzIDI0NS4yIDMwOS44MjIgNTAxLjk3NCAyMy43NzQgMTM5LjM5NiAxNy42MiAxNTYuODQ0LTU1LjMyOSAxNTYuODQ0LTU4LjMyIDAtMTYyLjA4OCAyMC45NzgtMjY0Ljc5NSA1My41My00Ny43NDMgMTUuMTMzLTkxLjc0OCAyOC40NjgtOTcuNzg4IDI5LjYzNC02LjA0IDEuMTY1LTQxLjMwNy0zMS43MTQtNzguMzctNzMuMDY1em05MzkuNzMyIDQ1LjYzNmMtODguNjk2LTI4Ljk4Ni0yMTguODA5LTU1LjU2NC0yNzMuMjk0LTU1LjgyNi02Mi41OTgtLjMwMS02OS40MjQtNS44MjctNjkuNDI0LTU2LjE5MSAwLTY3LjM1OSAyMy40NDktMTg5Ljg3OCA1Mi4wMi0yNzEuODA0IDM1LjAzNS0xMDAuNDU3IDgwLjk1LTE3OC45MjUgMTQyLjA0LTI0Mi43NDQgMTQwLjgxLTE0Ny4xIDI5OC44OTUtMTQ2LjQzIDQzNy42MTIgMS44NiA2My4zMDcgNjcuNjc0IDg0LjI5NiAxMjAuNDQzIDgzLjA2NyAyMDguODM0LTEuMDE3IDczLjE4OS0yNi4xNjEgMTQwLjQ5My04NS41NjIgMjI5LjAyOS00MS45NzQgNjIuNTYxLTE2MC40ODEgMTk1LjU4NS0xODUuMzYzIDIwOC4wNjktOS4xNyA0LjYwMS00NS4yMjYtMi45NjktMTAxLjA5Ni0yMS4yMjd6bS04NjUuOTgyIDM2Mi45NzdjNy43NTktNTAuNDk0IDE0Ljc5LTU4LjQyNSA5MC41MzYtMTAyLjExNWw3MC44ODYtNDAuODg4LTQ2Ljg3NS0yOC40NzZjLTcyLjA4NS00My43OS03Ny45MzItNDkuNTk3LTcxLjkyOS03MS40NDIgNi0yMS44MyA4MS40MTgtNDkuMzcxIDIxMi43MTYtNzcuNjggMTAyLjEwMy0yMi4wMTYgMzQ2Ljk3Ny0yMi4wMTYgNDQ5LjA4IDAgMTMxLjI5OCAyOC4zMDkgMjA2LjcxNiA1NS44NSAyMTIuNzE2IDc3LjY4IDYuMDAzIDIxLjg0NS4xNTYgMjcuNjUyLTcxLjkyOSA3MS40NDJsLTQ2Ljg3NiAyOC40NzYgNzAuODg3IDQwLjg4OGM3NS43NDUgNDMuNjkgODIuNzc3IDUxLjYyIDkwLjUzNiAxMDIuMTE1bDUgMzIuNTQySDUzOS4xMjZ6bTU1MC4xMTgtMTM4Ljc3MWMzNy43Ni0yMi42MjkgNjcuNDIyLTQ0Ljg0MSA2NS45MTYtNDkuMzZzLTMyLjIzNC0yNi43MDktNjguMjg0LTQ5LjMwOWwtNjUuNTQ0LTQxLjA5MS02Ny43MjYgNDAuNjRjLTM3LjI0OSAyMi4zNS02OC44NzEgNDQuNTA1LTcwLjI3MiA0OS4yMy0yLjAyNyA2LjgzNyAxMjEuOTkzIDkxLjAzMyAxMzQuMDg5IDkxLjAzMyAxLjc0MSAwIDM0LjA2LTE4LjUxNCA3MS44Mi00MS4xNDN6Ii8+PC9nPjwvc3ZnPg==')} +.is2d .pawn.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMDI0IDE4NDNINDQ2di03NHEtNC04MCA0MS41LTEzN1Q2MTMgMTUyNHExMTctOTEgMTcxLjUtMjE3LjVUODYzIDEwMzlINTc2bDI4NC0yMzlxLTg2LTc0LTg2LTE4OCAwLTEwMyA3My0xNzd0MTc3LTc0cTEwMyAwIDE3Ni41IDc0dDczLjUgMTc3cTAgMTE0LTg2IDE4OGwyODQgMjM5aC0yODdxMjMgMTQxIDc4IDI2Ny41dDE3MiAyMTcuNXE3OSA1MSAxMjQuNSAxMDh0NDIuNSAxMzd2NzR6IiBmaWxsPSIjMTAxMDEwIi8+PC9zdmc+')} +.is2d .knight.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik01MDIgODY4bC01MiAxLTI2IDY0IDY5IDIxIDQ2LTU1em01MzYtMTg3cTM0IDEtMTYtNjh0LTgwLTQyTDgyNiA2ODB6bS0zMzgtOThxNi0zOSAxMTUuNS0xMDcuNVQxMDM2IDMzMmwxMTUtMTU0IDk2IDIxN3EzNDIgMTcyIDQzMi41IDQxNy41VDE3MjcgMTQxNnEtMTggMTI4IDQuNSAyMzZ0NTcuNSAxOTBsLTEyNDIgMXEtOS0xNzggMzktMzAxLjVUNzY5IDEzMDRxNTAtMTEgODIuNS0zOS41VDkwNSAxMjA2bDYyLjUtMSAxMzgtMjkgMTM5LTk3IDY2LjUtMjA3cTAtMTctOC41LTM0dC0xMS41LTM3cS02MiAyMjgtMTYxIDI4OC41VDkzOSAxMTQ4cS0yMzYtNDItMjkyIDYwbC01NiAxMDItMjE3LTEyMSAxMTUtODItNTEtNTAtMTIyIDg2LTEyLTI5N3ptOTgxIDExOTJxLTEwMi0xMzAtODUtMzA4LjV0MjctMzYyLjUtNTAtMzUxLjVUMTI1NyA0NzdxMjIwIDE2NCAyNTIuNSAzNDJ0MTYuNSAzNTAuNS0xMiAzMjkgMTY3IDI3Ni41eiIgZmlsbD0iIzEwMTAxMCIvPjxwYXRoIGQ9Ik0xNjAxLjMwNSAxNjkzLjA0Yy04MS4wOC04OS43NDctOTEuNTg0LTE1Ni41NDEtNzQuMjI3LTQ3Mi4wNSAyMC4zNzktMzcwLjQ1LTguNzUyLTQ5NS4xMTktMTUwLjU1OC02NDQuMzQtMjguMzQ4LTI5LjgzLTQ3LjgxMy01NC4yMzYtNDMuMjU2LTU0LjIzNiAxNy4wMTcgMCAxMDAuMTEgNTguNDM0IDE0NC42NSAxMDEuNzI2IDU3LjA1MiA1NS40NSA4Ni4xNCAxMDcuODkxIDEwOS42MzkgMTk3LjY2MyAzNC45OTQgMTMzLjY4NiAzNy41NDQgMjAxLjk0IDE3LjMyNyA0NjMuODE4LTE5Ljk5IDI1OC45Ni0xNy41NDEgMzEyLjYyIDE4LjA1OCAzOTUuNjcxIDkuNjk5IDIyLjYyNSAxNi4xMyA0Mi42NCAxNC4yOTQgNDQuNDc3LTEuODM3IDEuODM3LTE4LjAwNC0xMi44OS0zNS45MjctMzIuNzI5ek04OTYuNzAzIDYyMS4zM2M1NS42ODMtNTMuMjY4IDYwLjQyMi01NS45NjEgNzguMTAyLTQ0LjM3OCAyNi4wNjggMTcuMDc4IDc2LjQwMyA4NC4wNjYgNzAuNDMgOTMuNzMtMi42OTcgNC4zNjQtNTAuNTU4IDcuODA1LTEwNi4zNTcgNy42NDZsLTEwMS40NTQtLjI4OHpNNDY0LjI3MSA5NDEuNDQ2Yy0yNy40NDEtNi42LTMxLjI3LTE0LjY4NC0yMC45Ni00NC4yNTggNy42ODMtMjIuMDM4IDE0LjQ4NC0yNy42NTYgMzMuNDgxLTI3LjY1NiAxMy4xMTIgMCAzMC4zNjMgNy4yMDggMzguMzM1IDE2LjAxNyAxMy41OTIgMTUuMDIgMTMuMzY3IDE3LjQ1LTMuNjI0IDM5LjA1LTkuOTY1IDEyLjY3LTIwLjc2NCAyMi41ODItMjMuOTk3IDIyLjAyOC0zLjIzMy0uNTUzLTEzLjY4OS0yLjg4NS0yMy4yMzUtNS4xODF6IiBmaWxsPSIjZWNlY2VjIi8+PC9zdmc+')} +.is2d .bishop.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik03NjggMTM2NXEtNSAzOS0yNiA4Mmg1NjRxLTE4LTM2LTI2LTgyem00OTUtNzNsNDYtNzNxLTE0Mi00OS0yODUtNDctMTQ0LTItMjg1IDQ3bDQ2IDczcTExOC00MCAyMzktMzggMTIwLTIgMjM5IDM4em0tNDMyIDIyN0g2MjRxNjctMTE2IDcyLTIyOS0xMTQtMTE5LTE2Mi0yMjMuNVQ1MjggODQzcTMzLTk2IDExOC0xODkuNVQ5NTggNDA3cS0xNy0xMS00Ni0zNnQtMjktNzlxMC01OCA0MS05NnQxMDAtMzhxNTggMCA5OS41IDM4dDQxLjUgOTZxMCA1NC0yOS41IDc5dC00NS41IDM2cTIyNiAxNTMgMzExIDI0Ni41VDE1MjAgODQzcTQyIDExOS02IDIyMy41VDEzNTIgMTI5MHE0IDExMyA3MiAyMjloLTIwN3EtMi00IDEwIDE2IDMzIDUzIDcwIDYwdDg5IDdoMjUwcTc2IDAgMTQxLjUgNjJ0NjUuNSAxNzloLTQ5NXEtMTIzIDAtMjIzLjUtODQuNVQxMDI0IDE1NjBxMCAxMTQtMTAxIDE5OC41VDcwMCAxODQzSDIwNXEwLTExNyA2NS0xNzl0MTQyLTYyaDI1MHE1MSAwIDg4LTd0NzEtNjBxMTItMjAgMTAtMTZ6bTE0Ni03MDFoLTk1djg5aDk1djE2NWg5NFY5MDdoOTV2LTg5aC05NVY3MTRoLTk0eiIgZmlsbD0iIzEwMTAxMCIvPjxwYXRoIGQ9Ik03NjEuNTQgMTQwNi42OThsMTIuODU2LTM5LjA1aDQ5OS4yMDhsMTIuODU2IDM5LjA1IDEyLjg1NiAzOS4wNTFINzQ4LjY4NHptMy41MzgtMTU1Ljc1bC0xNy42NTMtMjkuOTIgNDUtMTMuMDY4Yzg0LjY2NC0yNC41ODYgMTcyLjQxLTMzLjU5NSAyNzQuOTY1LTI4LjIzIDU0Ljg4OCAyLjg3MiAxMTMuNDY0IDguOTggMTMwLjE3IDEzLjU3M3M0Ni43NzggMTIuNjA2IDY2LjgzIDE3LjgwNmwzNi40NiA5LjQ1NC0xNy43OTEgMzAuMTUyYy0yMC4zMjcgMzQuNDUyLTIzLjMxIDM0Ljk5My05MS41ODUgMTYuNTg2LTY4LjcyLTE4LjUyNi0yNjYuMjI4LTE4LjUyNi0zMzQuOTQ4IDAtNjguMjMgMTguMzk1LTcxLjI2NiAxNy44NTItOTEuNDQ4LTE2LjM1M3ptMjE1LjUzMi0yNjkuNDd2LTgyLjQ0aC05NS40NTd2LTc4LjEwMmg5NS40NThWNzE2LjhoODYuNzc5djEwNC4xMzZoOTUuNDU4djc4LjEwMWgtOTUuNDU4djE2NC44ODFoLTg2Ljc4eiIgZmlsbD0iI2VjZWNlYyIvPjwvc3ZnPg==')} +.is2d .rook.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMDI0IDE4NDNIMzgzbDI5LTI2NCAxNTktMTE4IDUwLTY1OS0xNDktMTA3LTE3LTM0MWgyODl2MTQ3aDEzN1YzNTRoMjg2djE0N2gxMzdWMzU0aDI4OWwtMTcgMzQxLTE0OSAxMDcgNTAgNjU5IDE1OSAxMTggMjkgMjY0em0wLTk4OWgzMzNsLTYtODhINjk3bC02IDg4em0wIDY0N2gzODFsLTYtODdINjQ5bC02IDg3eiIgZmlsbD0iIzEwMTAxMCIvPjxwYXRoIGQ9Ik02NTAuODQ3IDE0NTcuMDN2LTM5LjA1aDc0Ni4zMDV2NzguMTAxSDY1MC44NDd6bTQzLjM5LTYxOS4zOWMwLTguOTQ4IDIuNDQxLTI4LjQ3NCA1LjQyNC00My4zOWw1LjQyNC0yNy4xMThoNjM3LjgzbDUuNDI0IDI3LjExOWMxMy4wNjYgNjUuMzI5IDQzLjg4IDU5LjY2LTMyNC4zMzkgNTkuNjYtMzE2LjY1IDAtMzI5Ljc2My0uNjQ2LTMyOS43NjMtMTYuMjd6IiBmaWxsPSIjZWNlY2VjIi8+PC9zdmc+')} +.is2d .queen.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik01OTAgMTUxOXE0IDcyLTE1IDE1OGwxMzQtODZ6bTQzNCAzMjRINDQxcTExNC0yMzEgNTcuNS00NTYuNVQyOTYgOTM3cS0xMiAyLTE5IDItNTQgMC05Mi41LTM4LjVUMTQ2IDgwOHQzOC41LTkyLjVUMjc3IDY3N3Q5Mi41IDM4LjVUNDA4IDgwOHEwIDIwLTYgMzgtNCAxNC0xNSAzM2wxOTYgMTM5IDEwMC00ODZxLTY0LTMxLTcyLTEwMy01LTQ0IDI5LTkxdDg4LTUzcTU0LTUgOTYgMjl0NDggODhxNyA2OC00NiAxMTRsMTk4IDQxMiAxOTgtNDEycS01NC00Ni00Ni0xMTQgNi01NCA0OC04OHQ5Ni0yOXE1NCA2IDg3LjUgNTN0MjkuNSA5MXEtOSA3Mi03MiAxMDNsMTAwIDQ4NiAxOTYtMTM5cS0xMi0xOS0xNS0zMy02LTE4LTYtMzggMC01NCAzOC41LTkyLjVUMTc3MSA2Nzd0OTIuNSAzOC41VDE5MDIgODA4dC0zOC41IDkyLjVUMTc3MSA5MzlxLTcgMC0xOS0yLTE0NyAyMjQtMjAzIDQ0OS41dDU4IDQ1Ni41em0wLTQ1MHExMDkgMCAyMjIgMjguNXQyMTMgNjcuNXEyLTQxIDExLTg5LTEwOC00Mi0yMjEuNS02OHQtMjI0LjUtMjYtMjI1IDI2LTIyMSA2OHE4IDQ4IDExIDg5IDk5LTM5IDIxMi02Ny41dDIyMy0yOC41em0wIDM3Nmg0NzhxLTE1LTM0LTI0LTczSDU3MHEtMTAgMzktMjQgNzN6bTQzNC0yNTBsLTExOSA3MiAxMzQgODZxLTIwLTg2LTE1LTE1OHptLTU3MyA0N2wxMzkgODcgMTM5LTg0LTEzOS04NnoiIGZpbGw9IiMxMDEwMTAiLz48cGF0aCBkPSJNNTU1LjM5IDE3NTguNTgzYzAtMS42NzQgNC4yODctMTUuMzQyIDkuNTI3LTMwLjM3M2w5LjUyNy0yNy4zMjloODk5LjExMmw5LjUyNyAyNy4zM2M1LjI0IDE1LjAzIDkuNTI3IDI4LjY5OCA5LjUyNyAzMC4zNzJzLTIxMC44NzQgMy4wNDQtNDY4LjYxIDMuMDQ0LTQ2OC42MS0xLjM3LTQ2OC42MS0zLjA0NHptMzk2Ljk3My0xNTYuMTUxbC01OC42Mi0zNy4yNTIgNjUuMTM3LTM3LjI3IDY1LjEzNy0zNy4yNjggNjAuNzM3IDM2LjA4NGMzMy40MDYgMTkuODQ1IDYwLjY2MyAzOC44MzcgNjAuNTcxIDQyLjIwNC0uMjMgOC41MS0xMDguODg2IDcxLjI1Ny0xMjIuOTEgNzAuOTgtNi4yODgtLjEyNC0zNy44MTEtMTYuOTktNzAuMDUyLTM3LjQ3OHptNDYwLjU2IDMwLjIzNmMtMjcuMTIzLTE3LjM3MS00OS4zODUtMzUuNDg4LTQ5LjQ3Mi00MC4yNjEtLjA4Ni00Ljc3MyAyMC4xNTMtMjEuNTA3IDQ0Ljk3Ni0zNy4xODZsNDUuMTMyLTI4LjUwOSA1LjIwMyA2Ny41NmMyLjg2MSAzNy4xNTcgNC44MTQgNjguMTAzIDQuMzM5IDY4Ljc2OC0uNDc1LjY2Ni0yMy4wNTUtMTMuMDAyLTUwLjE3OC0zMC4zNzJ6TTU4OC44IDE0NTIuNTMxYy0uNzE2LTE2LjE0LTEuNjkyLTMzLjY0MS0yLjE3LTM4Ljg5My0yLjA5NS0yMy4wNTMgMjAzLjkyMi04MC43ODYgMzQzLjc3NC05Ni4zMzcgNzIuMDI0LTguMDA5IDExNC42ODctOC4wODUgMTg0LjA3Ny0uMzMxIDE0MC41NzMgMTUuNzA4IDM0OC45NjggNzMuNzgyIDM0Ni44ODkgOTYuNjY4LS40NzggNS4yNTItMS40NTQgMjIuNzUzLTIuMTcgMzguODkzbC0xLjMwMiAyOS4zNDUtMTAxLjk2Ni0zMi41OTNjLTEzMy45MTctNDIuODA0LTIxMC44MDYtNTUuNzA5LTMzMS45MzItNTUuNzA5cy0xOTguMDE1IDEyLjkwNS0zMzEuOTMyIDU1LjcxbC0xMDEuOTY2IDMyLjU5MXptLTEuMTUgMTUwLjIyNmMyLjExMi0zNC4zMyA0LjUyNC02NS40MSA1LjM2Mi02OS4wNjcuODM3LTMuNjU3IDI0LjI1IDcuNTY4IDUyLjAzIDI0Ljk0NCAyNy43OCAxNy4zNzYgNDcuMjg0IDM0LjU5MyA0My4zNDMgMzguMjYtMy45NCAzLjY2OC0yOS4wODEgMjAuNTMyLTU1Ljg2OSAzNy40NzVsLTQ4LjcwNCAzMC44MDZ6IiBmaWxsPSIjZWNlY2VjIi8+PC9zdmc+')} +.is2d .king.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMDI0IDE3NjloNDg5bC0xMi03M0g1NDdsLTEyIDczem0wLTkyMXEtMjUtNjAtNjItMTExIDMxLTQ4IDYyLTY1IDMwIDE3IDYyIDY1LTM4IDUxLTYyIDExMXptLTk3IDQ1NHEtMTU0IDExLTMwMyA1OC0xMjMtMTA4LTIwMC0yMTMuNVQzNDcgOTQ1cTAtODkgNzMuNS0xNTlUNTY5IDcxNnE2NyAwIDEzNC41IDYyLjVUODA2IDkwOXEzMCA1NCA3NSAxNzV0NDYgMjE4em0tMzUwIDIxN2wtMjYgMTU2IDE0NS04NHptNDQ3LTkwN3EtNDcgMC0xMzYgMTIxLTMxLTM2LTUwLTU1IDkzLTE0MCAxODYtMTQwIDkyIDAgMTg2IDE0MC0yMCAxOS01MCA1NS05MC0xMjEtMTM2LTEyMXptMCA3NzVxLTEtMTI2LTQyLTI2Ny41VDg5OCA4OTNxLTgtMTQtMTQtMjd0LTEyLTIzcS0yOC00My00OC02OS01MS02My0xMjAtMTA1dC0xMzQtNDJxLTEwMyAwLTIwOCA5M1QyNTcgOTQ5cTAgMTIwIDk5IDI1NC41VDYwNSAxNDYzcTIwMS03NCA0MTktNzZ6bTAgNDU2SDQ0OGw2MS0zNjVxLTMyNS0yODAtMzI2LTUzNS0xLTE1OSAxMjUtMjc0LjVUNTc1IDU1M3E3OCAwIDE1OC41IDQ3VDg3NiA3MTlxNjEgNzQgOTguNSAxNjQuNVQxMDI0IDEwMzRxMTItNjAgNDktMTUwLjV0OTktMTY0LjVxNjEtNzIgMTQyLTExOXQxNTktNDdxMTQwIDAgMjY2IDExNS41VDE4NjUgOTQzcS0yIDI1NS0zMjYgNTM1bDYxIDM2NXptOTctNTQxcTAtOTcgNDUtMjE4dDc2LTE3NXEzNC02OCAxMDEuNS0xMzAuNVQxNDc5IDcxNnE3NCAwIDE0Ny41IDcwdDc0LjUgMTU5cTAgOTYtNzcgMjAxLjVUMTQyNCAxMzYwcS0xNTAtNDctMzAzLTU4em0zNTAgMjE3bC0xMTkgNzIgMTQ1IDg0em0tNDQ3LTEzMnEyMTcgMiA0MTkgNzYgMTUwLTEyNSAyNDktMjU5LjV0OTktMjU0LjVxMC0xMzYtMTA1LjUtMjI5VDE0NzggNjI3cS02NiAwLTEzNSA0MnQtMTE5IDEwNXEtMjEgMjYtNDggNjktNiAxMC0xMi41IDIzbC0xMy41IDI3cS00NCA4NS04NSAyMjYuNXQtNDEgMjY3LjV6bS0xMzkgMTU5bDEzOSA4NiAxMzktODQtMTM5LTg2em05Mi0xMjQ4di05NWg5NHY5NWgxMDd2OTVoLTEwN3YxNTNxLTQ4LTE2LTk0IDBWMzkzSDg3MHYtOTV6IiBmaWxsPSIjMTAxMDEwIi8+PHBhdGggZD0iTTE0MDEuNDkyIDE0NDUuMDIyYy03OC44NjYtMjcuOTcyLTI4MC44NS02My40OS0zNjEuMDU1LTYzLjQ5LTEzLjU3MyAwLTguMzctOTIuOTM4IDkuOTMxLTE3Ny40MSA0Ni41NDEtMjE0LjgxNSAxMzQuNDczLTM5Ny42NiAyMzEuNDgtNDgxLjMzNyAxMDQuMjg3LTg5Ljk1OCAyMDIuNDI1LTExMC4yOTIgMzAxLjg4LTYyLjU1IDEwMS43MDcgNDguODIzIDE2OC44NTcgMTI2LjQ3NiAxOTIuNjExIDIyMi43MzYgMTEuOTUzIDQ4LjQzNCAxMi41MDcgNjUuODM1IDMuNjMzIDExMy45OTUtMjAuMDQ3IDEwOC44LTgxLjM3OSAyMDUuMzU5LTIyMS4yMzYgMzQ4LjMwNC0xMDkuOTk3IDExMi40MjUtMTE0LjEyNyAxMTUuMDQ1LTE1Ny4yNDQgOTkuNzUyem0xMjIuODE3LTE3OS42NmMxMzQuNzYxLTE0MS40NjQgMTc1LjQ4My0yMTQuNDYyIDE3Ni4xOTItMzE1LjgzNy40NjgtNjcuMDM3LTEzLjQzNC0xMDEuODM2LTYxLjUyNS0xNTQuMDA4LTE0My40MS0xNTUuNTgxLTMxNS4xMDQtODMuNDUyLTQzNC4zOTggMTgyLjQ5LTQyLjYyIDk1LjAxNS03Ni40ODcgMjA2LjA5Ny04Mi41MTUgMjcwLjY1LTUuNzA3IDYxLjEwOS0xMC4yMzIgNTcuNDkzIDg0LjgwNCA2Ny43NjYgMjYuNTk3IDIuODc1IDgzLjIyMSAxNC4zNzYgMTI1LjgzIDI1LjU1N3M4MS45NzQgMjAuNzUgODcuNDc3IDIxLjI2M2M1LjUwMi41MTMgNTIuMzYzLTQzLjUzMyAxMDQuMTM1LTk3Ljg4em0tMTAwMS42MTYgMTEzLjRjLTIzOS44MzktMjMwLjkzMy0zMDguMTEtNDAyLjY1Ni0yMjUuNjg5LTU2Ny42ODYgMTAuNzA0LTIxLjQzNCA0MS4wMDMtNTguNjcxIDY3LjMzLTgyLjc1IDEwMy4zODctOTQuNTU1IDIwOS4xNzItMTE3LjU3NCAzMDguOTkyLTY3LjIzNyAxMDQuOTQgNTIuOTIgMTc3LjM0OSAxMzcuMjI3IDIzNy45MjYgMjc3LjAyNSA1OC41MjggMTM1LjA2OCAxMDQuMDcgMzEwLjE1NiAxMDQuMDcgNDAwLjEwMXY0MS45MzZsLTU4LjU3NiA1LjMzOWMtMTA0LjAwNiA5LjQ4LTIxNC43ODEgMjkuNTg3LTI4My44NjQgNTEuNTI0bC02Ny40NDUgMjEuNDE4em0xODYuMzgzLTM1Ljg3NGM0Ni43MjctMTEuNzA5IDEwNi40MzYtMjMuNjYgMTMyLjY4Ny0yNi41NTggOTUuMDIzLTEwLjQ5MiA4OS45MTQtNi4yMDcgODMuOTItNzAuMzk4LTYuNjE3LTcwLjg2LTU2LjQ1Ny0yMTguODI4LTEwNi40NTMtMzE2LjA0OC04OC4zNTItMTcxLjgwNC0yMTAuMDY4LTI0OS4wMTUtMzIwLjA4NC0yMDMuMDQ3LTQ0LjE2IDE4LjQ1MS0xMTYuNDM3IDg3LjQ5NS0xMzUuNzUyIDEyOS42NzgtMTkuMDUxIDQxLjYwNy0yMC45ODcgMTMyLjE4NS0zLjg1MiAxODAuMjA4IDIyLjY1NSA2My40OTMgNzEuMDc2IDEzMC45MzcgMTY0LjE0OSAyMjguNjQgNTEuNzcyIDU0LjM0NyA5NS41NDggOTguODEzIDk3LjI4IDk4LjgxMyAxLjczIDAgNDEuMzc4LTkuNTggODguMTA1LTIxLjI4OHptMjk0LjI5OC0zOTMuMTQ4Yy0xNi41MjItNTAuNTU2LTcyLjA1My0xNjQuMTk2LTk3LjMxNC0xOTkuMTQ0LTEzLjM1Mi0xOC40NzItMTEuOTAxLTIxLjEyMSA0MS41NzktNzUuOTMzIDM4LjAwNC0zOC45NSA2MS45OTQtNTYuNzkyIDc2LjM2MS01Ni43OTJzMzguMzU3IDE3Ljg0MyA3Ni4zNjEgNTYuNzkyYzUzLjcxNyA1NS4wNTUgNTQuOTggNTcuMzc5IDQxLjI4IDc1LjkzMy0yNC4wMjEgMzIuNTMyLTk5Ljc0NCAxOTEuMTI4LTEwNS40NyAyMjAuOTAyLTIuOTg0IDE1LjUxMi03LjkxOSAyOC4xNzUtMTAuOTY3IDI4LjE0LTMuMDQ5LS4wMzQtMTIuODcyLTIyLjQ4OC0yMS44My00OS44OTd6bTU2LjY2Ny0xNTcuNjhsMzEuNzAyLTU5LjgxOC0yOC41MzMtMzEuMTUyYy0xNS42OTQtMTcuMTMzLTMzLjMzOC0zMS4xNTEtMzkuMjEtMzEuMTUxcy0yMy41MTYgMTQuMDE4LTM5LjIxIDMxLjE1MWwtMjguNTMzIDMxLjE1MiAzMS43MDIgNTkuODE4YzE3LjQzNiAzMi45IDMzLjY1NSA1OS44MTkgMzYuMDQxIDU5LjgxOXMxOC42MDUtMjYuOTE4IDM2LjA0MS01OS44MTl6bS05OC45NTYgNzk1LjQ5NmMtMzIuMjE3LTIwLjEzNi01OC41NDMtMzguNjA3LTU4LjUwMi00MS4wNDYuMDQtMi40NCAyNy4wNjYtMjEuMDg3IDYwLjA1Ny00MS40MzhsNTkuOTgzLTM3LjAwMyA2MS40MzQgMzYuOTU4YzMzLjc5IDIwLjMyNyA2MS40MzQgMzkuNDYyIDYxLjQzNCA0Mi41MjIgMCA0LjkxNS0xMTUuODQ0IDc3LjIzNS0xMjMuMDA4IDc2Ljc5Mi0xLjU1Mi0uMDk2LTI5LjE4MS0xNi42NS02MS4zOTgtMzYuNzg1em0tNDAyLjMwOCA2NC43NjNjMi4zNjYtOC4xMzMgNi45NjMtMzQuMzEyIDEwLjIxNS01OC4xNzcgOC45OTQtNjYgMTEuMDQtNjcuMTkxIDYyLjMzLTM2LjI4NiAyNS4wNTggMTUuMDk5IDQ1LjU2IDI5LjkxMSA0NS41NiAzMi45MTdzLTI3LjU0MiAyMS40MS02MS4yMDQgNDAuODk4Yy00NS4xMTcgMjYuMTItNjAuMDczIDMxLjU0OC01Ni45MDEgMjAuNjQ4em04NzMuMDg3LTIwLjU5N2MtMzEuMDIzLTE4LjMwNC01Ny4zOTItMzYuMjMtNTguNTk4LTM5LjgzNC0yLjQ0Ny03LjMyMSA4Ni45NDYtNjMuNDA5IDkyLjM4OS01Ny45NjYgMy40MTcgMy40MTcgMjYuNDYzIDEyOC45NzQgMjMuOTI4IDEzMC4zNjItLjcyMS4zOTYtMjYuNjk1LTE0LjI1Ny01Ny43MTktMzIuNTYyek01NDUuMDY1IDE3MzIuOTlsMy41NDYtMzAuMzczaDk1MC43NzlsMy41NDUgMzAuMzczIDMuNTQ2IDMwLjM3M0g1NDEuNTE5eiIgZmlsbD0iI2VjZWNlYyIvPjwvc3ZnPg==')} diff --git a/public/piece-css/cburnett.css b/public/piece-css/cburnett.css new file mode 100644 index 0000000000..6680ad9015 --- /dev/null +++ b/public/piece-css/cburnett.css @@ -0,0 +1,12 @@ +.is2d .pawn.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PHBhdGggZD0iTTIyLjUgOWMtMi4yMSAwLTQgMS43OS00IDQgMCAuODkuMjkgMS43MS43OCAyLjM4QzE3LjMzIDE2LjUgMTYgMTguNTkgMTYgMjFjMCAyLjAzLjk0IDMuODQgMi40MSA1LjAzLTMgMS4wNi03LjQxIDUuNTUtNy40MSAxMy40N2gyM2MwLTcuOTItNC40MS0xMi40MS03LjQxLTEzLjQ3IDEuNDctMS4xOSAyLjQxLTMgMi40MS01LjAzIDAtMi40MS0xLjMzLTQuNS0zLjI4LTUuNjIuNDktLjY3Ljc4LTEuNDkuNzgtMi4zOCAwLTIuMjEtMS43OS00LTQtNHoiIGZpbGw9IiNmZmYiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPjwvc3ZnPg==')} +.is2d .knight.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0yMiAxMGMxMC41IDEgMTYuNSA4IDE2IDI5SDE1YzAtOSAxMC02LjUgOC0yMSIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0yNCAxOGMuMzggMi45MS01LjU1IDcuMzctOCA5LTMgMi0yLjgyIDQuMzQtNSA0LTEuMDQyLS45NCAxLjQxLTMuMDQgMC0zLTEgMCAuMTkgMS4yMy0xIDItMSAwLTQuMDAzIDEtNC00IDAtMiA2LTEyIDYtMTJzMS44OS0xLjkgMi0zLjVjLS43My0uOTk0LS41LTItLjUtMyAxLTEgMyAyLjUgMyAyLjVoMnMuNzgtMS45OTIgMi41LTNjMSAwIDEgMyAxIDMiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNOS41IDI1LjVhLjUuNSAwIDEgMS0xIDAgLjUuNSAwIDEgMSAxIDB6bTUuNDMzLTkuNzVhLjUgMS41IDMwIDEgMS0uODY2LS41LjUgMS41IDMwIDEgMSAuODY2LjV6IiBmaWxsPSIjMDAwIi8+PC9nPjwvc3ZnPg==')} +.is2d .bishop.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxnIGZpbGw9IiNmZmYiIHN0cm9rZS1saW5lY2FwPSJidXR0Ij48cGF0aCBkPSJNOSAzNmMzLjM5LS45NyAxMC4xMS40MyAxMy41LTIgMy4zOSAyLjQzIDEwLjExIDEuMDMgMTMuNSAyIDAgMCAxLjY1LjU0IDMgMi0uNjguOTctMS42NS45OS0zIC41LTMuMzktLjk3LTEwLjExLjQ2LTEzLjUtMS0zLjM5IDEuNDYtMTAuMTEuMDMtMTMuNSAxLTEuMzU0LjQ5LTIuMzIzLjQ3LTMtLjUgMS4zNTQtMS45NCAzLTIgMy0yeiIvPjxwYXRoIGQ9Ik0xNSAzMmMyLjUgMi41IDEyLjUgMi41IDE1IDAgLjUtMS41IDAtMiAwLTIgMC0yLjUtMi41LTQtMi41LTQgNS41LTEuNSA2LTExLjUtNS0xNS41LTExIDQtMTAuNSAxNC01IDE1LjUgMCAwLTIuNSAxLjUtMi41IDQgMCAwLS41LjUgMCAyeiIvPjxwYXRoIGQ9Ik0yNSA4YTIuNSAyLjUgMCAxIDEtNSAwIDIuNSAyLjUgMCAxIDEgNSAweiIvPjwvZz48cGF0aCBkPSJNMTcuNSAyNmgxME0xNSAzMGgxNW0tNy41LTE0LjV2NU0yMCAxOGg1IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIi8+PC9nPjwvc3ZnPg==')} +.is2d .rook.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik05IDM5aDI3di0zSDl2M3ptMy0zdi00aDIxdjRIMTJ6bS0xLTIyVjloNHYyaDVWOWg1djJoNVY5aDR2NSIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiLz48cGF0aCBkPSJNMzQgMTRsLTMgM0gxNGwtMy0zIi8+PHBhdGggZD0iTTMxIDE3djEyLjVIMTRWMTciIHN0cm9rZS1saW5lY2FwPSJidXR0IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIi8+PHBhdGggZD0iTTMxIDI5LjVsMS41IDIuNWgtMjBsMS41LTIuNSIvPjxwYXRoIGQ9Ik0xMSAxNGgyMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciIvPjwvZz48L3N2Zz4=')} +.is2d .queen.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik04IDEyYTIgMiAwIDEgMS00IDAgMiAyIDAgMSAxIDQgMHptMTYuNS00LjVhMiAyIDAgMSAxLTQgMCAyIDIgMCAxIDEgNCAwek00MSAxMmEyIDIgMCAxIDEtNCAwIDIgMiAwIDEgMSA0IDB6TTE2IDguNWEyIDIgMCAxIDEtNCAwIDIgMiAwIDEgMSA0IDB6TTMzIDlhMiAyIDAgMSAxLTQgMCAyIDIgMCAxIDEgNCAweiIvPjxwYXRoIGQ9Ik05IDI2YzguNS0xLjUgMjEtMS41IDI3IDBsMi0xMi03IDExVjExbC01LjUgMTMuNS0zLTE1LTMgMTUtNS41LTE0VjI1TDcgMTRsMiAxMnoiIHN0cm9rZS1saW5lY2FwPSJidXR0Ii8+PHBhdGggZD0iTTkgMjZjMCAyIDEuNSAyIDIuNSA0IDEgMS41IDEgMSAuNSAzLjUtMS41IDEtMS41IDIuNS0xLjUgMi41LTEuNSAxLjUuNSAyLjUuNSAyLjUgNi41IDEgMTYuNSAxIDIzIDAgMCAwIDEuNS0xIDAtMi41IDAgMCAuNS0xLjUtMS0yLjUtLjUtMi41LS41LTIgLjUtMy41IDEtMiAyLjUtMiAyLjUtNC04LjUtMS41LTE4LjUtMS41LTI3IDB6IiBzdHJva2UtbGluZWNhcD0iYnV0dCIvPjxwYXRoIGQ9Ik0xMS41IDMwYzMuNS0xIDE4LjUtMSAyMiAwTTEyIDMzLjVjNi0xIDE1LTEgMjEgMCIgZmlsbD0ibm9uZSIvPjwvZz48L3N2Zz4=')} +.is2d .king.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0yMi41IDExLjYzVjZNMjAgOGg1IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIi8+PHBhdGggZD0iTTIyLjUgMjVzNC41LTcuNSAzLTEwLjVjMCAwLTEtMi41LTMtMi41cy0zIDIuNS0zIDIuNWMtMS41IDMgMyAxMC41IDMgMTAuNSIgZmlsbD0iI2ZmZiIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiLz48cGF0aCBkPSJNMTEuNSAzN2M1LjUgMy41IDE1LjUgMy41IDIxIDB2LTdzOS00LjUgNi0xMC41Yy00LTYuNS0xMy41LTMuNS0xNiA0VjI3di0zLjVjLTMuNS03LjUtMTMtMTAuNS0xNi00LTMgNiA1IDEwIDUgMTBWMzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTExLjUgMzBjNS41LTMgMTUuNS0zIDIxIDBtLTIxIDMuNWM1LjUtMyAxNS41LTMgMjEgMG0tMjEgMy41YzUuNS0zIDE1LjUtMyAyMSAwIi8+PC9nPjwvc3ZnPg==')} +.is2d .pawn.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PHBhdGggZD0iTTIyLjUgOWMtMi4yMSAwLTQgMS43OS00IDQgMCAuODkuMjkgMS43MS43OCAyLjM4QzE3LjMzIDE2LjUgMTYgMTguNTkgMTYgMjFjMCAyLjAzLjk0IDMuODQgMi40MSA1LjAzLTMgMS4wNi03LjQxIDUuNTUtNy40MSAxMy40N2gyM2MwLTcuOTItNC40MS0xMi40MS03LjQxLTEzLjQ3IDEuNDctMS4xOSAyLjQxLTMgMi40MS01LjAzIDAtMi40MS0xLjMzLTQuNS0zLjI4LTUuNjIuNDktLjY3Ljc4LTEuNDkuNzgtMi4zOCAwLTIuMjEtMS43OS00LTQtNHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPjwvc3ZnPg==')} +.is2d .knight.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0yMiAxMGMxMC41IDEgMTYuNSA4IDE2IDI5SDE1YzAtOSAxMC02LjUgOC0yMSIgZmlsbD0iIzAwMCIvPjxwYXRoIGQ9Ik0yNCAxOGMuMzggMi45MS01LjU1IDcuMzctOCA5LTMgMi0yLjgyIDQuMzQtNSA0LTEuMDQyLS45NCAxLjQxLTMuMDQgMC0zLTEgMCAuMTkgMS4yMy0xIDItMSAwLTQuMDAzIDEtNC00IDAtMiA2LTEyIDYtMTJzMS44OS0xLjkgMi0zLjVjLS43My0uOTk0LS41LTItLjUtMyAxLTEgMyAyLjUgMyAyLjVoMnMuNzgtMS45OTIgMi41LTNjMSAwIDEgMyAxIDMiIGZpbGw9IiMwMDAiLz48cGF0aCBkPSJNOS41IDI1LjVhLjUuNSAwIDEgMS0xIDAgLjUuNSAwIDEgMSAxIDB6bTUuNDMzLTkuNzVhLjUgMS41IDMwIDEgMS0uODY2LS41LjUgMS41IDMwIDEgMSAuODY2LjV6IiBmaWxsPSIjZWNlY2VjIiBzdHJva2U9IiNlY2VjZWMiLz48cGF0aCBkPSJNMjQuNTUgMTAuNGwtLjQ1IDEuNDUuNS4xNWMzLjE1IDEgNS42NSAyLjQ5IDcuOSA2Ljc1UzM1Ljc1IDI5LjA2IDM1LjI1IDM5bC0uMDUuNWgyLjI1bC4wNS0uNWMuNS0xMC4wNi0uODgtMTYuODUtMy4yNS0yMS4zNC0yLjM3LTQuNDktNS43OS02LjY0LTkuMTktNy4xNmwtLjUxLS4xeiIgZmlsbD0iI2VjZWNlYyIgc3Ryb2tlPSJub25lIi8+PC9nPjwvc3ZnPg==')} +.is2d .bishop.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxnIGZpbGw9IiMwMDAiIHN0cm9rZS1saW5lY2FwPSJidXR0Ij48cGF0aCBkPSJNOSAzNmMzLjM5LS45NyAxMC4xMS40MyAxMy41LTIgMy4zOSAyLjQzIDEwLjExIDEuMDMgMTMuNSAyIDAgMCAxLjY1LjU0IDMgMi0uNjguOTctMS42NS45OS0zIC41LTMuMzktLjk3LTEwLjExLjQ2LTEzLjUtMS0zLjM5IDEuNDYtMTAuMTEuMDMtMTMuNSAxLTEuMzU0LjQ5LTIuMzIzLjQ3LTMtLjUgMS4zNTQtMS45NCAzLTIgMy0yeiIvPjxwYXRoIGQ9Ik0xNSAzMmMyLjUgMi41IDEyLjUgMi41IDE1IDAgLjUtMS41IDAtMiAwLTIgMC0yLjUtMi41LTQtMi41LTQgNS41LTEuNSA2LTExLjUtNS0xNS41LTExIDQtMTAuNSAxNC01IDE1LjUgMCAwLTIuNSAxLjUtMi41IDQgMCAwLS41LjUgMCAyeiIvPjxwYXRoIGQ9Ik0yNSA4YTIuNSAyLjUgMCAxIDEtNSAwIDIuNSAyLjUgMCAxIDEgNSAweiIvPjwvZz48cGF0aCBkPSJNMTcuNSAyNmgxME0xNSAzMGgxNW0tNy41LTE0LjV2NU0yMCAxOGg1IiBzdHJva2U9IiNlY2VjZWMiIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiLz48L2c+PC9zdmc+')} +.is2d .rook.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik05IDM5aDI3di0zSDl2M3ptMy41LTdsMS41LTIuNWgxN2wxLjUgMi41aC0yMHptLS41IDR2LTRoMjF2NEgxMnoiIHN0cm9rZS1saW5lY2FwPSJidXR0Ii8+PHBhdGggZD0iTTE0IDI5LjV2LTEzaDE3djEzSDE0eiIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiLz48cGF0aCBkPSJNMTQgMTYuNUwxMSAxNGgyM2wtMyAyLjVIMTR6TTExIDE0VjloNHYyaDVWOWg1djJoNVY5aDR2NUgxMXoiIHN0cm9rZS1saW5lY2FwPSJidXR0Ii8+PHBhdGggZD0iTTEyIDM1LjVoMjFtLTIwLTRoMTltLTE4LTJoMTdtLTE3LTEzaDE3TTExIDE0aDIzIiBmaWxsPSJub25lIiBzdHJva2U9IiNlY2VjZWMiIHN0cm9rZS13aWR0aD0iMSIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciIvPjwvZz48L3N2Zz4=')} +.is2d .queen.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxnIHN0cm9rZT0ibm9uZSI+PGNpcmNsZSBjeD0iNiIgY3k9IjEyIiByPSIyLjc1Ii8+PGNpcmNsZSBjeD0iMTQiIGN5PSI5IiByPSIyLjc1Ii8+PGNpcmNsZSBjeD0iMjIuNSIgY3k9IjgiIHI9IjIuNzUiLz48Y2lyY2xlIGN4PSIzMSIgY3k9IjkiIHI9IjIuNzUiLz48Y2lyY2xlIGN4PSIzOSIgY3k9IjEyIiByPSIyLjc1Ii8+PC9nPjxwYXRoIGQ9Ik05IDI2YzguNS0xLjUgMjEtMS41IDI3IDBsMi41LTEyLjVMMzEgMjVsLS4zLTE0LjEtNS4yIDEzLjYtMy0xNC41LTMgMTQuNS01LjItMTMuNkwxNCAyNSA2LjUgMTMuNSA5IDI2eiIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiLz48cGF0aCBkPSJNOSAyNmMwIDIgMS41IDIgMi41IDQgMSAxLjUgMSAxIC41IDMuNS0xLjUgMS0xLjUgMi41LTEuNSAyLjUtMS41IDEuNS41IDIuNS41IDIuNSA2LjUgMSAxNi41IDEgMjMgMCAwIDAgMS41LTEgMC0yLjUgMCAwIC41LTEuNS0xLTIuNS0uNS0yLjUtLjUtMiAuNS0zLjUgMS0yIDIuNS0yIDIuNS00LTguNS0xLjUtMTguNS0xLjUtMjcgMHoiIHN0cm9rZS1saW5lY2FwPSJidXR0Ii8+PHBhdGggZD0iTTExIDM4LjVhMzUgMzUgMSAwIDAgMjMgMCIgZmlsbD0ibm9uZSIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiLz48cGF0aCBkPSJNMTEgMjlhMzUgMzUgMSAwIDEgMjMgMG0tMjEuNSAyLjVoMjBtLTIxIDNhMzUgMzUgMSAwIDAgMjIgMG0tMjMgM2EzNSAzNSAxIDAgMCAyNCAwIiBmaWxsPSJub25lIiBzdHJva2U9IiNlY2VjZWMiLz48L2c+PC9zdmc+')} +.is2d .king.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0yMi41IDExLjYzVjYiIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiLz48cGF0aCBkPSJNMjIuNSAyNXM0LjUtNy41IDMtMTAuNWMwIDAtMS0yLjUtMy0yLjVzLTMgMi41LTMgMi41Yy0xLjUgMyAzIDEwLjUgMyAxMC41IiBmaWxsPSIjMDAwIiBzdHJva2UtbGluZWNhcD0iYnV0dCIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciIvPjxwYXRoIGQ9Ik0xMS41IDM3YzUuNSAzLjUgMTUuNSAzLjUgMjEgMHYtN3M5LTQuNSA2LTEwLjVjLTQtNi41LTEzLjUtMy41LTE2IDRWMjd2LTMuNWMtMy41LTcuNS0xMy0xMC41LTE2LTQtMyA2IDUgMTAgNSAxMFYzN3oiIGZpbGw9IiMwMDAiLz48cGF0aCBkPSJNMjAgOGg1IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIi8+PHBhdGggZD0iTTMyIDI5LjVzOC41LTQgNi4wMy05LjY1QzM0LjE1IDE0IDI1IDE4IDIyLjUgMjQuNWwuMDEgMi4xLS4wMS0yLjFDMjAgMTggOS45MDYgMTQgNi45OTcgMTkuODVjLTIuNDk3IDUuNjUgNC44NTMgOSA0Ljg1MyA5IiBzdHJva2U9IiNlY2VjZWMiLz48cGF0aCBkPSJNMTEuNSAzMGM1LjUtMyAxNS41LTMgMjEgMG0tMjEgMy41YzUuNS0zIDE1LjUtMyAyMSAwbS0yMSAzLjVjNS41LTMgMTUuNS0zIDIxIDAiIHN0cm9rZT0iI2VjZWNlYyIvPjwvZz48L3N2Zz4=')} diff --git a/public/piece-css/chess7.css b/public/piece-css/chess7.css new file mode 100644 index 0000000000..e4212e9137 --- /dev/null +++ b/public/piece-css/chess7.css @@ -0,0 +1,12 @@ +.is2d .pawn.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTIyLjk5MiA0NC43NTJxMS4zNDQtLjY0IDIuMTc2LTIuNDk2Ljg5Ni0yLjE3NiAxLjk4NC00Ljg2NCAxLjA4OC0yLjc1MiAyLjE3Ni01LjYzMi0uMjU2LS4xOTItLjUxMi0uMzItLjE5Mi0uMTI4LS4yNTYtLjI1Ni0xLjc5Mi0xLjk4NCAwLTMuMzkybC43MDQtLjcwNCAxLjE1Mi0xLjE1MnEtMi4yNC0xLjAyNC0zLjcxMi0zLjEzNi0xLjQwOC0yLjE3Ni0xLjQwOC00LjczNiAwLTMuNTIgMi41Ni02LjE0NCAyLjYyNC0yLjYyNCA2LjA4LTIuNjI0IDMuNTIgMCA2LjAxNiAyLjYyNCAyLjU2IDIuNjI0IDIuNTYgNi4xNDQgMCAyLjU2LTEuNDcyIDQuNzM2LTEuNDA4IDIuMTEyLTMuNTg0IDMuMTM2LjU3Ni41NzYgMS4wODggMS4xNTIuNTEyLjUxMi43NjguNzA0IDEuNiAxLjQwOCAwIDMuMzkyLS4xMjguMTI4LS4zODQuMjU2LS4xOTIuMTI4LS4zODQuMzIgMS4xNTIgMi44OCAyLjE3NiA1LjYzMiAxLjAyNCAyLjY4OCAxLjk4NCA0Ljg2NC43NjggMS44NTYgMi4xMTIgMi40OTYgMS40MDguNTc2IDQuMTYgMi4yNCAyLjc1MiAxLjYgMy4yNjQgMi45NDQuNDQ4IDEuMjguNTc2IDMuNzEyLjE5MiAyLjQzMi4zMiA1LjA1NmgtMzguMjcycTAtMi42MjQuMTI4LTUuMDU2dC42NC0zLjcxMnEuMzg0LTEuMzQ0IDMuMi0yLjk0NCAyLjgxNi0xLjY2NCA0LjE2LTIuMjR6bTEwLjc1Mi0xOC40OTZxMCAuMTI4LTEuMzQ0IDEuNTM2bC0xLjUzNiAxLjUzNnEuMTkyLjM4NCAxLjQ3MiAxLjcyOCAxLjM0NCAxLjI4IDEuNiAxLjQ3MmwxLjQ3Mi0xLjQ3MiAxLjcyOC0xLjcyOHEtLjM4NC0uMTkyLTEuODU2LTEuNTM2em01LjY5Ni04LjMycTAtMi4zMDQtMS42LTMuOTA0LTEuNi0xLjY2NC0zLjkwNC0xLjY2NC0yLjI0IDAtMy45MDQgMS43MjgtMS42NjQgMS42NjQtMS42NjQgMy45NjggMCAyLjExMiAxLjM0NCAzLjY0OHQzLjI2NCAxLjcyOHEuODk2LjU3NiAxLjg1NiAwIDEuOTItLjE5MiAzLjI2NC0xLjcyOCAxLjM0NC0xLjUzNiAxLjM0NC0zLjc3NnptLTIxLjA1NiAzMi44OTZxLS40NDggMS45ODQtLjQ0OCA0LjhoMzJxMC0yLjMwNC0uNDQ4LTQuOC0uMzg0LS43NjgtMi4zNjgtMS42NjQtMS45ODQtLjk2LTQuMDMyLTEuOTItMS45ODQtMS4wMjQtMy4xMzYtMy45MDQtLjk2LTEuOTItMS45Mi00LjI4OC0uODk2LTIuMzY4LTEuNzkyLTQuOC0uMjU2LjEyOC0uMzg0LjMyLS4xMjguMTI4LS4yNTYuMTI4LTEuNjY0IDIuMDQ4LTMuMzkyIDAtLjEyOCAwLS4yNTYtLjEyOC0uMTI4LS4xOTItLjMyLS4zMi0uOTYgMi40MzItMS45MiA0LjgtLjg5NiAyLjM2OC0xLjc5MiA0LjI4OC0xLjE1MiAyLjg4LTMuMiAzLjkwNC0yLjA0OC45Ni00LjAzMiAxLjkyLTEuOTg0Ljg5Ni0yLjMwNCAxLjY2NHoiLz48cGF0aCBkPSJtMTcuOTQ1IDU1LjEzOGMwLTEuMDE4LjQwNC00LjAwMy41OS00LjM1LjMxLS41ODUuNTg4LS43NTUgMy44OS0yLjM4NiAyLjQ4Ny0xLjIyNyAzLjI3My0xLjcwNyAzLjg4Ni0yLjM3My45MTgtLjk5NSAyLjE0Ny0zLjUzNCA0LjAxNS04LjI4OGwxLjMzNy0zLjQwNS40NTkuNDIyYzEuMzY4IDEuMjU2IDEuOTc4IDEuMzEzIDMuMjA2LjI5OGwuODc3LS43MjUuMjIyLjU4OWMxLjI0NiAzLjMgMi44MDIgNy4wNzEgMy41MzMgOC41NjUgMS4zMDUgMi42NjMgMS44MyAzLjEzMiA1LjUzIDQuOTM0IDEuNy44MjkgMy4yNzggMS43MDcgMy41MDYgMS45NTIuNDMuNDYyLjYyNSAxLjM1Ny44NTMgMy45MWwuMTE4IDEuMzE4aC0zMi4wMjJ6bTE0LjQyNS0yNC4xOTljLS43MzQtLjc2My0xLjMzNC0xLjQ4MS0xLjMzNC0xLjU5NiAwLS4xMTQuNjA1LS44MDkgMS4zNDUtMS41NDQgMS41NTMtMS41NDIgMS4yOC0xLjU3MyAzLjMzOC4zN2wxLjI3NyAxLjIwNS0xLjQ4NCAxLjQ3NmMtLjgxNi44MTItMS41NTcgMS40NzYtMS42NDUgMS40NzYtLjA5IDAtLjc2Mi0uNjI0LTEuNDk3LTEuMzg3em0tLjIyNC03LjczNWMtMy43My0xLjE1Ny00Ljg5LTUuODc4LTIuMi04Ljk0MiAxLjAwNy0xLjE0NiAyLjAyMi0xLjYyMyAzLjY2Mi0xLjcxOCAxLjc1OS0uMTAyIDIuNzc0LjIzNSAzLjkzMyAxLjMwNCAyLjA1OSAxLjg5NyAyLjQxOCA0Ljk3My44NTcgNy4zMzEtLjcwMyAxLjA2My0xLjc2IDEuNzcyLTMuMjIzIDIuMTYxLTEuMjE4LjMyNC0xLjYwMy4zMDctMy4wMjktLjEzNnoiIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==')} +.is2d .knight.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTI0Ljg0OCAzOS43MjhxLS4zODQuNzA0LjE5MiAxLjI4LjU3Ni41NzYtLjE5MiAxLjQ3Mi0uNzA0IDEuMDI0LTIuNjI0IDIuNzUyLTEuODU2IDEuNzI4LTMuMiAyLjMwNC0yLjE3NiAxLjI4LTQuNDguMTkyLTEuMTUyLS41NzYtMi44OC0yLjI0LTEuNjY0LTEuNjY0LTIuMzA0LTIuNjg4LS43NjgtMS4wMjQtLjU3Ni0xLjcyOC4xOTItLjcwNC4wNjQtMS42NjQgMC0uNzY4LS4zODQtMS4wODgtLjM4NC0uMzg0LjM4NC0yLjQ5Ni43NjgtMS45MiAzLjI2NC02LjMzNiAyLjQ5Ni00LjQxNiAzLjItNi41MjguNzA0LTEuOTItLjI1Ni0xLjcyOC0uODk2LjEyOC0uNTEyLS44OTYuMzg0LTEuMTUyIDEuNDA4LTMuMDcyIDEuMDI0LTEuOTg0IDEuODU2LTIuOTQ0Ljg5Ni0uODk2IDEuODU2LS43MDQgMS4wMjQuMTI4IDEuNzkyLTEuMTUyLjcwNC0xLjIxNiAxLjM0NC0zLjc3Ni43MDQtMi41NiAxLjQ3Mi00LjY3Mi45NiAxLjk4NCAyLjA0OCAzLjc3NiAxLjA4OCAxLjc5MiAyLjI0IDIuMjQgMi44OC0xLjA4OCA2LjkxMi0uNTEyIDUuNzYuNzY4IDguNTEyIDIuMzA0IDIuNzUyIDEuNDcyIDYuNTkyIDYuMjA4IDEuNDcyIDEuODU2IDIuMzY4IDMuOTY4Ljg5NiAyLjA0OCAxLjYgNC40OC43MDQgMi40MzIgMS4wODggNS41NjguNDQ4IDMuMTM2LjY0IDUuNjMyIDAgMi42ODgtLjE5MiA0Ljk5Mi0uMTI4IDIuMjQgMCA0LjU0NHYzLjc3NnEwIDEuNDA4LjUxMiAzLjc3Ni4zMiAxLjk4NCAxLjI4IDQuNDE2Ljk2IDIuNDMyIDEuNzkyIDQuOGgtNDAuMTkycS0uODMyLTEuNjY0LS41NzYtMy42NDggMC0xLjI4LjMyLTMuMTM2dDEuMDI0LTMuNTJxLjU3Ni0xLjQ3MiAxLjUzNi0yLjgxNi45Ni0xLjQwOCAyLjA0OC0yLjY4OCAyLjA0OC0zLjIgMy44NC01LjEyIDEuNTM2LTEuNzI4IDMuMjY0LTMuMiAxLjc5Mi0xLjQ3MiAzLjMyOC0zLjM5MiAxLjM0NC0yLjExMiAxLjY2NC0zLjcxMi4xOTItLjk2LS4wNjQtMi42MjQtLjE5Mi0xLjcyOC0uNTEyLTEuNjY0LS4yNTYuMTI4LTEuMDI0IDIuMzY4LS43NjggMi4yNC0xLjQ3MiAzLjAwOC0uNzA0IDEuMDg4LTEuNTM2IDEuNTM2LS43NjguMzg0LTEuMzQ0Ljc2OC0uNzY4LjM4NC0xLjIxNi4zODQtLjM4NCAwLS45Ni4zODQtLjcwNC41MTItMS42NjQgMS4zNDQtLjg5Ni43NjgtMS4yOCAxLjQ3MnptMi42MjQgNy40ODgtMy44NCA1LjI0OCA4LjQ0OC42NCAzLjg0LTQuMDMycTEuOTItMS45MiAzLjkwNCAwbDQuMDk2IDQuMTYgOS40MDgtLjY0cTAtMy4yNjQuMjU2LTcuNzQ0LjMyLTQuNTQ0LjE5Mi02Ljk3Ni0uMTI4LTIuNDk2LS41MTItNS40NC0uMzItMy4wMDgtMS4wMjQtNS4xODQtMS4yOC00LjI4OC0zLjY0OC03LjQyNC0xLjQwOC0xLjUzNi0yLjYyNC0yLjc1Mi0xLjE1Mi0xLjIxNi0yLjk0NC0yLjYyNC0yLjExMi0uODk2LTMuOTY4LTEuNi0xLjc5Mi0uNzA0LTMuOTA0LS44MzItMy45MDQtLjQ0OC02LjU5Mi41NzYtMi4xMTItLjc2OC0yLjY4OC0xLjY2NC0uNTEyLS44OTYtLjgzMi0xLjg1NiAwIDIuNzUyLTEuNDA4IDQuNDgtLjcwNC44MzItMS45ODQgMS4yMTYtMS4yMTYuMzItMS45ODQgMS4yMTYtLjgzMi45Ni0xLjY2NCAyLjQ5Ni0uNzY4IDEuNDcyLTEuMTUyIDIuNDMyLS4xOTIgMS4wODguNjQgMS4wODguODMyLS4wNjQuMTI4IDEuODU2LS43MDQgMS45ODQtMy4yNjQgNi41MjgtMi40OTYgNC40OC0zLjIgNi40LS43NjggMS45ODQtLjMyIDEuOTIuNTEyLS4wNjQuNTEyLjUxMiAwIC41NzYtLjMyIDEuMDg4LS4yNTYuNDQ4LjMyIDEuMDg4LjU3Ni44MzIgMi4xMTIgMi4zMDQgMS41MzYgMS40MDggMi4zNjggMS44NTYuNzY4LjQ0OC45Ni40NDguMTkyLS4wNjQgMS4xNTItLjY0Ljc2OC0uMzg0IDIuNTYtMS45MnQyLjM2OC0yLjM2OHEuNzA0LS44OTYuMDY0LTEuMjgtLjU3Ni0uNDQ4LS4xOTItMS4xNTIuMzg0LS43NjggMS42LTEuOTIgMS4yMTYtMS4yMTYgMS45Mi0xLjc5Mi43NjgtLjU3NiAxLjI4LS41MTIuNTc2IDAgMS4xNTItLjM4NHQxLjA4OC0uNTEycS41MTItLjE5MiAxLjA4OC0uODk2LjQ0OC0uNjQgMS4wODgtMS45ODQuNzA0LTEuNDA4IDEuMDg4LTIuNDk2LjE5Mi0uODk2LjQ0OC0xLjY2NC4zMi0uODMyIDAtMS41MzYtLjUxMi0uNzY4LTIuMTEyLTEuNjY0LTEuNi0uODk2LTEuNDA4LTEuMjguMDY0LS4zMiAxLjc5Mi0uMzJ0Mi44MTYuNzY4cS43NjguNzY4IDEuNzkyIDIuNDk2dDEuNDA4IDMuMDcycTEuMDg4IDMuMi41MTIgNS4zNzYtLjUxMiAyLjMwNC0yLjM2OCA0LjQ4LTEuMjggMS45ODQtMy4wMDggMy41ODR0LTMuNDU2IDMuMzI4cS0xLjQwOCAxLjQwOC0xLjk4NCAyLjQzMnptLTUuMDU2IDguNTEycS0uMzg0IDEuMzQ0LS42NCAzLjAwOHQuMzIgMi44MTZoMzMuMjE2bC0xLjY2NC01LjY5Ni05LjcyOC42NC00LjA5NiA0LjA5NnEtMS45ODQgMS43MjgtMy45MDQgMGwtMy45NjgtNC4yODh6bTE1LjU1Mi00LjM1Mi0zLjM5MiAzLjM5MiAzLjM5MiAzLjUyIDMuMzkyLTMuNTJ6bS0xNS4yMzItMjguMjg4cS42NC4yNTYgMS4wMjQuMzIuNDQ4LjA2NC4zMi43NjggMCAuMjU2LS41NzYuNDQ4LS41MTIuMTI4LS45Ni4zMi0uNDQ4LjI1Ni0xLjA4OC40NDgtLjU3Ni4xOTItLjc2OC4zMi0xLjA4OC4zMi0xLjUzNi0uMTkyLS4yNTYtLjI1Ni0uMjU2LTEuMjE2LjA2NC0uMzIuNDQ4LS44MzIuNDQ4LS41MTIuODk2LS41MTIgMS43MjggMCAyLjQ5Ni4xMjh6bS0xMC4zMDQgMTQuMjcycS41NzYgMCAxLjM0NC4xOTIuNzY4LjE5Mi45Ni41NzYgMCAuNTEyLS44MzIgMS40NzItLjgzMi44OTYtMS4yMTYuNzA0IDAtLjE5Mi4xMjgtLjU3Ni4xMjgtLjM4NC4wNjQtLjc2OCAwLS45Ni0uNDQ4LTEuNnoiLz48ZyBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Im0yMS45OTUgNjEuMTMzYy0uMjYyLS42ODktLjIxNi0yLjE1Ni4xMi0zLjg1bC4yOTctMS41IDEuMjAzLjA5NmMxLjkxNS4xNSA2Ljk1My40NDggNy42NTQuNDUuNTg2LjAwMy44MTQuMTk1IDIuNzMgMi4yOTggMS4zNjEgMS40OTMgMi4zNDUgMi40MTEgMi44MTkgMi42My43Mi4zMzIuNjU0LjMzNS02Ljk2LjMzOWwtNy42ODYuMDA0em0xNi45MTQuMTUyYy4zNS0uMTY5IDEuNjU5LTEuMzAxIDIuOTA5LTIuNTE3bDIuMjcyLTIuMjEgNC43MDctLjMwM2MyLjU4OS0uMTY2IDQuNzM3LS4yNzIgNC43NzMtLjIzNi4wNi4wNi42IDEuODQgMS40MDcgNC42MjZsLjI3Ni45NTUtOC40OS0uMDA0Yy04LjA5Ny0uMDA0LTguNDYxLS4wMTktNy44NTQtLjMxMXptLTIuNjM3LTQuNzc2LTEuNjMyLTEuNjM5IDEuNjc4LTEuNjc4IDEuNjc4LTEuNjc4IDEuNjMgMS42MjIgMS42MyAxLjYyMy0xLjUwNiAxLjYzN2MtLjgyOC45LTEuNTgzIDEuNjYzLTEuNjc3IDEuNjk0LS4wOTQuMDMyLS45MDUtLjY4LTEuODAyLTEuNTgxeiIvPjxwYXRoIGQ9Im00MS44ODkgNTEuMTM3Yy0yLjY4My0yLjg3NC0zLjc2LTMuNDQ0LTUuMTQ2LTIuNzI3LS4yODEuMTQ1LTEuNDQ1IDEuMjU3LTIuNTg2IDIuNDdsLTIuMDc1IDIuMjA2LTQuMDg3LS4zMTJjLTIuMjQ3LS4xNzItNC4xMTMtLjMzNS00LjE0NS0uMzYzLS4wMzItLjAyNy45NDEtMS40MjcgMi4xNjMtMy4xMTIgMS43NTYtMi40MjEgMi45My0zLjc4NiA1LjYxLTYuNTE3IDUuNTkzLTUuNyA3LjEyNy04LjMgNi44NjgtMTEuNjM3LS4yMjYtMi45MTUtMi4zMDYtNy40MTktNC4wMzQtOC43MzctLjcxNy0uNTQ3LTIuMzc3LS44NzgtMy41NzMtLjcxNC0xLjM0MS4xODUtMS4xOTEuNTc2LjcwNiAxLjg0MyAyLjAzIDEuMzU2IDIuMjAyIDEuNjggMS43NjQgMy4zMTMtLjQxNCAxLjU0Mi0xLjM3IDMuODM0LTIuMTM0IDUuMTEzLS41LjgzNi0uODA1IDEuMTExLTEuODYzIDEuNjc3LS42OTcuMzcxLTEuNDcxLjY3OS0xLjcyMS42ODItLjYxNS4wMDktMS4zMS40NjYtMi44MDUgMS44NDQtMS4yODYgMS4xODQtMi4yODYgMi41MzQtMi4yODYgMy4wODQgMCAuMTY4LjEyMy40MDcuMjczLjUzMi43MTUuNTk0IDAgMS42NTYtMi41NDkgMy43ODMtLjkzMy43OC0yLjEwOSAxLjY0MS0yLjYxMiAxLjkxNWwtLjkxNi40OTgtLjY4OS0uMzU1Yy0uOTU0LS40OTEtMy4zMjYtMi41NjItNC4yMi0zLjY4NC0uNzgtLjk4LS44Ni0xLjI3OC0uNTU1LTIuMDc5LjIyMS0uNTgxLjA3NS0xLjE3LS4yOS0xLjE3YS4yNjUuMjY1IDAgMCAxIC0uMjYtLjI2OGMwLS43OTQgMS42NDYtNC4yODYgNC4zNzUtOS4yNzcgMS43MjYtMy4xNTcgMi43NC01LjQ3NSAyLjc3Ni02LjM0OC4wMjctLjYyNi0uMDI3LS43MzItLjQyNC0uODI4LS43MTktLjE3NS0uNjY3LS44NjIuMTk0LTIuNTggMS40OTMtMi45NzcgMi40MDYtMy45ODUgNC4xNzctNC42MS40MzItLjE1MiAxLjA1Mi0uNDggMS4zNzgtLjczLjcxMi0uNTQyIDEuNjQyLTIuMzg3IDEuODA5LTMuNTg5bC4xMi0uODY3LjM2Mi42ODVjLjUzIDEuMDAzIDEuMDA3IDEuNDU3IDIuMDU1IDEuOTUyLjkyOC40NC45NDIuNDQgMi4wMS4xMzQuODEtLjIzMSAxLjczMS0uMzAzIDMuNzEzLS4yODggMy4xMTQuMDIzIDQuMTkuMjQ0IDcuNDQgMS41MjYgMS45ODMuNzgyIDIuNDgyIDEuMDY5IDMuNzQ3IDIuMTQ4IDIuODQxIDIuNDIzIDUuMzQ1IDUuNTggNi40NzIgOC4xNTggMi4zNDMgNS4zNiAzLjExNiAxMS41MjUgMi42MiAyMC45MDctLjE1MyAyLjg4Mi0uMjc4IDUuNzg4LS4yNzggNi40NTh2MS4yMmwtLjU5Mi4wOTNjLS4zMjUuMDUxLTIuMDIyLjE3OC0zLjc3Mi4yODJzLTMuNi4yMzQtNC4xMTIuMjg5bC0uOTMuMXptLTI3LjkxMy0xMS42MjRjLjkzNy0xLjAxNi45NjctMS40NzguMTItMS44MzItLjM0Ny0uMTQ0LS44ODEtLjI2My0xLjE4OC0uMjYzLS41MiAwLS41NDMuMDI3LS4zNC40MDYuMTE5LjIyMy4yMTIuODc3LjIwNyAxLjQ1NC0uMDEyIDEuMjk3LjE4NyAxLjMzNiAxLjIwMS4yMzV6bTguMjA1LTE0LjMyNWMxLjcwOS0uNjkgMS45MS0uODE4IDEuOTEtMS4yMjQgMC0uNi0uOTQzLS45MTYtMi44NzYtLjk2NS0xLjM1Ny0uMDM0LTEuNDQ3LS4wMS0xLjg2Ni40NzUtLjU5Mi42ODUtLjYxIDEuODA1LS4wMzYgMi4yMDYuNTY4LjM5OC43MjYuMzcgMi44NjgtLjQ5MnoiLz48L2c+PC9zdmc+')} +.is2d .bishop.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTI3Ljk4NCA1NS40NzJxLTIuNzUyLS4wNjQtNC41NDQtLjA2NC0xLjc5Mi0uMDY0LTEuOTItLjI1Ni0uODMyLS43NjgtLjg5Ni0xLjg1Ni0uMDY0LTEuMDg4Ljc2OC0xLjc5Mi4wNjQtLjEyOCAxLjA4OC0xLjUzNiAxLjAyNC0xLjQ3MiAyLjQzMi0zLjU4NC0yLjQzMi0zLjA3Mi00LjYwOC02LjAxNi0yLjE3Ni0zLjAwOC0yLjYyNC0zLjUyLTEuNDA4LTEuMjE2LTEuNDA4LTMuMDA4IDAtMS44NTYgMS40MDgtMy4yNjQuMzg0LS4zODQgMi4zMDQtMi45NDQgMS45ODQtMi41NiA0LjIyNC01LjU2OCAyLjMwNC0zLjAwOCA0LjIyNC01LjU2OCAxLjk4NC0yLjYyNCAyLjI0LTIuODguMjU2LS4yNTYuMzg0LS40NDgtLjcwNC0uNzY4LTEuNDcyLTEuNDcyLS43MDQtLjcwNC0uODMyLS45Ni0yLjA0OC0xLjc5MiAwLTMuNTg0LjE5Mi0uMzIgMS43MjgtMS43OTIgMS42LTEuNDcyIDEuODU2LTEuODU2IDEuNzI4LTEuNjY0IDMuMzI4IDBsMS44NTYgMS44NTZxMS40NzIgMS40NzIgMS44NTYgMS43OTIgMS43OTIgMS43OTIgMCAzLjU4NC0uMjU2LjI1Ni0xLjAyNC45NnQtMS40MDggMS40NzJxLjA2NCAwIC4wNjQuMTI4LjA2NC4wNjQuMjU2LjA2NC40NDguNTEyIDIuMzY4IDMuMTM2IDEuOTIgMi41NiA0LjA5NiA1LjU2OCAyLjI0IDMuMDA4IDQuMDk2IDUuNTY4IDEuOTIgMi41NiAyLjMwNCAyLjk0NCAxLjM0NCAxLjQwOCAxLjM0NCAzLjI2NCAwIDEuNzkyLTEuMzQ0IDMuMDA4LS40NDguNTEyLTIuNTYgMy4zOTItMi4wNDggMi44MTYtNC4zNTIgNS44ODggMS42IDIuMTEyIDIuNjg4IDMuNzEyIDEuMTUyIDEuNTM2IDEuMzQ0IDEuNjY0IDEuNzI4IDEuNzkyLS4xOTIgMy42NDgtLjEyOC4xOTItMi4xMTIuMjU2LTEuOTIgMC00LjguMDY0LS4xOTIgMS40MDgtLjEyOCAxLjQwOC4zMi4zMiAyLjE3Ni4zMiAxLjg1Ni0uMDY0IDQuMDk2LS4xMjh0NC4yODgtLjA2NHEyLjExMi0uMDY0IDIuOTQ0LjE5MiAyLjExMi43MDQgMi45NDQgMy4yNjQuODMyIDIuNDk2IDEuNDA4IDQuODY0aC0xNy4wODhxLTEuMzQ0IDAtMi41Ni0uMDY0LTEuMTUyLS4xMjgtMi4zNjgtLjcwNC0xLjE1Mi0uNTc2LTEuNDcyLS44MzItLjMyLS4zMi0uMzg0LS43MDQgMCAuMzg0LS4yNTYuNzA0LS4yNTYuMjU2LTEuNDA4LjgzMi0xLjM0NC41NzYtMi41Ni43MDQtMS4yMTYuMDY0LTIuMzY4LjA2NGgtMTcuMjhxLjcwNC0yLjM2OCAxLjY2NC00Ljg2NCAxLjAyNC0yLjU2IDMuMTM2LTMuMjY0Ljc2OC0uMjU2IDIuNzUyLS4xOTIgMi4wNDggMCA0LjE2LjA2NCAyLjE3Ni4wNjQgMy45MDQuMTI4IDEuNzkyIDAgMi4xMTItLjMyLjMyLS4xOTIuMTkyLS4zODQtLjA2NC0uMjU2LS4wNjQtMS4wMjR6bTYuOTEyLS4xMjhxMCAzLjk2OCAxLjA4OCA1LjA1Ni41NzYuODMyLjU3Ni45NnQuNTEyLjQ0OHEyLjA0OC43NjggMy41Mi43NjhoMTMuMjQ4cS0uMTI4LS4zMi0uMzg0LTEuMjh0LTEuMTUyLTEuMzQ0cS0uNzA0LS4xOTItMi44MTYtLjEyOC0yLjA0OCAwLTQuMzUyLjEyOC0yLjMwNC4wNjQtNC4yODguMDY0LTEuOTItLjA2NC0yLjM2OC0uNTEyLTEuMDg4LS44OTYtMS4wODgtMS45MiAwLTEuMDg4LjEyOC0yLjI0em0tMS43OTIgMS45MnEwLTEuOTItLjA2NC0xLjkyaC0yLjU2cS4wNjQgMS4xNTIuMDY0IDIuMTc2IDAgLjk2LTEuMTUyIDEuOTg0LS40NDguNDQ4LTIuMzY4LjUxMi0xLjkyIDAtNC4yMjQtLjA2NC0yLjMwNC0uMTI4LTQuNDE2LS4xMjgtMi4xMTItLjA2NC0yLjgxNi4xMjgtLjgzMi4zODQtMS4xNTIgMS4zNDQtLjMyLjk2LS4zODQgMS4yOGgxMy4zNzZxMS42IDAgMy41Mi0uNzY4LjU3Ni0uMzIuNTEyLS40NDggMC0uMTI4LjcwNC0uOTYuOTYtMS4yMTYuOTYtMy4xMzZ6bTIuNDMyLTIyLjIwOHYxMS4wNzJoLTIuOTQ0di0xMS4wNzJoLTMuNTJ2LTIuOTQ0aDMuNTJ2LTQuMjg4aDIuOTQ0djQuMjg4aDMuNTJ2Mi45NDR6bS02LjkxMiAxMS4zMjhxLTEuOTg0IDIuOTQ0LTMuNTIgNC44NjQtMS40NzIgMS44NTYtMS41MzYgMS45Mi4wNjQuMTI4IDMuMzkyLjE5MnQ3LjI5Ni4wNjRxMy45NjggMCA3LjI5Ni0uMDY0IDMuMzkyLS4wNjQgMy41Mi0uMTkyLS4xMjgtLjA2NC0xLjc5Mi0yLjA0OC0xLjYtMS45ODQtMy43MTItNC45OTIgMi42MjQtMy42NDggNS4yNDgtNy4yMzIgMi42ODgtMy41ODQgMy4yLTQuMTYgMS4wODgtLjgzMiAwLTEuOTg0LS41MTItLjQ0OC0yLjQzMi0zLjAwOC0xLjkyLTIuNjI0LTQuMTYtNS41NjgtMi4xNzYtMy4wMDgtNC4wOTYtNS41NjgtMS44NTYtMi42MjQtMi4yNC0zLjEzNi0uNDQ4LS40NDgtLjk2LS40NDgtLjcwNCAwLTEuMDI0LjQ0OC0uNTEyLjUxMi0yLjQ5NiAzLjEzNi0xLjkyIDIuNTYtNC4yMjQgNS41NjgtMi4yNCAyLjk0NC00LjE2IDUuNTY4LTEuOTIgMi41Ni0yLjM2OCAzLjAwOC0xLjI4IDEuMTUyIDAgMS45ODQuMzg0LjU3NiAzLjEzNiA0LjIyNCAyLjgxNiAzLjY0OCA1LjYzMiA3LjQyNHptNS4zNzYtNDAuNzY4cS0uMjU2LjM4NC0xLjYgMS43MjgtMS4yOCAxLjM0NC0xLjQ3MiAxLjUzNi4xOTIuMzg0IDEuNDcyIDEuNzI4IDEuMzQ0IDEuMjggMS42IDEuNDcyLjE5Mi0uMTkyIDEuNTM2LTEuNDcybDEuNzI4LTEuNzI4cS0uMzg0LS4xOTItMS43MjgtMS41MzYtMS4zNDQtMS4zNDQtMS41MzYtMS43Mjh6Ii8+PHBhdGggZD0ibTE0LjIyOCA2Mi4wNDhjLjMxMy0xLjAyNC42MzItMS41ODUgMS4wNTktMS44NjUuNDE0LS4yNzIgMS4xMzItLjI5NyA2Ljg3OS0uMjQyIDcuMjEuMDcgNy4xNjQuMDc2IDcuOTktMS4yNTIuMzU1LS41NzIuNDIyLS45MDcuMzk4LTIuMDA1bC0uMDI4LTEuMzE4aDIuNTZsLS4wODYgMS43NzVjLS4wODkgMS44NDYtLjE3NiAyLjEyMS0xLjEyIDMuNTMzLTEuMTEzIDEuNjY1LTEuOCAxLjc4LTEwLjUzNyAxLjc4MmwtNy4yNC4wMDF6bTI0LjkuMzE3YTQzLjMyIDQzLjMyIDAgMCAwIC0xLjIyNS0uMzUzYy0uOTU5LS4yNjctMS4wOTUtLjM3NC0xLjcxLTEuMzMyLS44MTMtMS4yNy0xLjE1MS0yLjQ2Ny0xLjE1NC00LjA4N2wtLjAwMi0xLjIyN2gyLjM2M3YxLjQxYy4wMDEgMS42MjcuMzM2IDIuMzY4IDEuMzEgMi45LjU1LjMgMS4xMTQuMzIyIDcuMDcuMjY1bDYuNDcyLS4wNi40ODkuNDI0Yy4yNjkuMjM0LjYwNS44MTMuNzQ3IDEuMjg4bC4yNTguODY0LTcuMjE5LS4wMTRjLTMuOTctLjAwOC03LjMtLjA0My03LjQtLjA3OHptLTE0LjMxOC05LjEyNWMtLjU3NS0uMDQtMS4wNDYtLjExNy0xLjA0Ni0uMTdzLjQ4LS42ODQgMS4wNjctMS40MDJjMS4wMzUtMS4yNjcgMy4zNDUtNC40NDYgMy42NzUtNS4wNTguMTI3LS4yMzYtLjc1LTEuNTA4LTQuMDE0LTUuODE5LTIuMjk4LTMuMDMzLTQuNDI0LTUuODE3LTQuNzI2LTYuMTg1LS4zLS4zNjktLjU0Ny0uNzU3LS41NDctLjg2MyAwLS4xMDcuMjczLS41MDEuNjA2LS44NzYuMzM0LS4zNzYgMS42MTgtMi4wMzMgMi44NTMtMy42ODMgNC4wNjgtNS40MzIgOS4xMzItMTIuMDc0IDkuOTI5LTEzLjAyMi40My0uNTEzLjkzNi0uOTcyIDEuMTIzLTEuMDIxLjc4Ny0uMjA2IDEuMzI1LjM2MiA0LjY4OSA0Ljk1MiA1LjEwMiA2Ljk2MyA4LjQ2MiAxMS40NDQgOS4zMTEgMTIuNDIuNzQ5Ljg2MS45NzIgMS42MS41NTcgMS44NjctLjE5OC4xMjMtNi4wOTIgNy45NzgtNy44NjUgMTAuNDgyLS41MjUuNzQxLS44MTMgMS4zMTUtLjczMiAxLjQ1NS40NC43NiAyLjU0OCAzLjU3IDMuNzY2IDUuMDIuNzg0LjkzNSAxLjM3MiAxLjc1MyAxLjMwNiAxLjgxOS0uMTI5LjEzLTE4LjIzMy4yMDUtMTkuOTUyLjA4NHptMTAuNzMtMTIuNTU2LjA0OC01LjVoMy40NDl2LTMuMDkxaC0zLjQ1NXYtNC4zNjNoLTMuMDkxdjQuMzYzaC0zLjQ1NHYzLjA5MWgzLjQ1NHY1LjQyNWMwIDIuOTgzLjA1OCA1LjQ4Mi4xMjkgNS41NTIuMDcuMDcuNzQ1LjEwNSAxLjUuMDc2bDEuMzcxLS4wNTN6bS0zLjEyNC0zMC4yMjItMS40MTYtMS40NTcuOTEyLTEuMDQ3Yy41MDEtLjU3NSAxLjE4NS0xLjI5NCAxLjUxOS0xLjU5N2wuNjA3LS41NSAxLjU3MSAxLjYgMS41NzIgMS42LTEuNTQgMS40MDVjLS44NDguNzcyLTEuNiAxLjQyNy0xLjY3MyAxLjQ1NHMtLjc3LS42MDctMS41NS0xLjQwOHoiIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==')} +.is2d .rook.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTQ4LjQ2NCAyNS4wMDhsMi40MzIgMTkuNTIgMi42MjQgNi4wMTZ2MTIuOTI4SDE0LjE2VjUwLjU0NGwyLjYyNC02LjAxNiAyLjQzMi0xOS41Mi00LjkyOC0xMC43NTIgMy4wNzItOS43MjhIMjZ2OC4zMmgzLjcxMnYtOC4zMmg4Ljc2OHY4LjMyaDMuNjQ4di04LjMyaDguNjRsMy4wNzIgOS43Mjh6bS0zMS41NTIgMjcuMnY4LjY0aDMzLjk4NHYtOC42NHptLjc2OC0yLjc1Mkg1MGwtMS40MDgtMy4zOTJIMTkuMDg4em0xNy44NTYtMTkuNTJsNC4xNiA0LjE2aDcuMjMybC0uOTYtNy44NzJoLTI0bC0xLjAyNCA3Ljg3Mmg2LjkxMmw0LjQxNi00LjE2cTEuNDA4LTEuNzkyIDMuMjY0IDB6bS03LjM2IDYuOTEyaC03LjU1MmwtLjk2IDYuNzg0aDI4LjM1MmwtLjc2OC02Ljc4NGgtNy43NDRsLTMuOTY4IDMuOTY4cS0xLjg1NiAxLjg1Ni0zLjI2NCAwek0xNy4wNCAxNC4wNjRsNC42NzIgOS41MzZoMjQuNTc2bDQuOC05LjUzNi0yLjE3Ni02LjkxMmgtNC4xNlYxNS42aC04Ljg5NlY3LjE1MmgtMy41ODRWMTUuNmgtOC44OTZWNy4xNTJoLTQuMDMyem0xMy4yNDggMjEuMjQ4bDMuNTIgMy43MTIgMy43MTItMy43MTItMy43MTItMy41MnoiLz48ZyBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0xNy4wMzYgNTYuNnYtNC4yNzNoMzMuODE4djguNTQ2SDE3LjAzNnptMS4xMTctOC4xMzZsLjY2Mi0xLjYzNy4yNzYtLjY4MiAxNC43NDUuMDAxaDE0Ljc0NWwuNjcgMS42MzYuNjcgMS42MzZIMTcuNzY5em0xLjYxLTUuMDI5YzAtLjA5LjIwNS0xLjU3MS40NTUtMy4yOS4yNS0xLjcxOC40NTQtMy4xNTguNDU0LTMuMTk4IDAtLjA0MSAxLjY4OS0uMDc0IDMuNzUzLS4wNzRoMy43NTJsMi40OTUgMi40NTRjMi42NTUgMi42MTIgMi45MSAyLjc1MyAzLjk2NCAyLjE5NS4yNy0uMTQzIDEuNDcxLTEuMjQ4IDIuNjctMi40NTVsMi4xNzktMi4xOTRoMy44NjZjMi45NzIgMCAzLjg2Ny4wNTIgMy44NjguMjI3IDAgLjEyNS4xNjQgMS41NzcuMzYyIDMuMjI3cy4zNjIgMy4wNjIuMzYzIDMuMTM3YzAgLjA3NS02LjM0LjEzNi0xNC4wOS4xMzYtOC4zMTEgMC0xNC4wOS0uMDY4LTE0LjA5LS4xNjV6Ii8+PHBhdGggZD0iTTMyLjAwMiAzNy4wNzZsLTEuNjctMS43NzkgMS43MS0xLjcwMyAxLjcxLTEuNzA0LjUwNi40NGE3My4wMjMgNzMuMDIzIDAgMCAxIDEuODI0IDEuNzE1TDM3LjQgMzUuMzJsLTEuNzcgMS43NzdjLS45NzQuOTc3LTEuODEzIDEuNzczLTEuODY0IDEuNzY4LS4wNTItLjAwNS0uODQ3LS44MS0xLjc2NS0xLjc4OHoiLz48cGF0aCBkPSJNMjEuMDk2IDMzLjM3M2ExODUuNiAxODUuNiAwIDAgMCAuNTA1LTMuODE5bC40MDQtMy4yMjdoMTEuOTdjNi41ODMgMCAxMS45Ny4wNDcgMTEuOTcuMTA1IDAgLjIuNzI3IDYuMTcyLjgzNCA2Ljg1bC4xMDcuNjgyaC03LjIybC0xLjkwNi0xLjkyOWMtMi4zODQtMi40MTMtMy4xMzYtMi45OC0zLjk0NC0yLjk4LS42NjQgMC0uOTM2LjIxNy00LjI1NyAzLjQwNGwtMS41NjcgMS41MDVoLTYuOTk3em0tMS42NzEtMTQuNTQ2TDE3LjEgMTQuMDU0bDEuMTItMy4zNjMgMS4xMi0zLjM2NCAyLjAzLS4wNTEgMi4wMy0uMDUyVjE1LjZoOC45MDhWNy4yMzZoMy40NTRWMTUuNmg5LjA5MlY3LjIyNGwyLjAyNi4wNTIgMi4wMjYuMDUxIDEuMDUyIDMuMzQzIDEuMDUyIDMuMzQzLTIuMzk0IDQuNzkzTDQ2LjIyIDIzLjZIMjEuNzVsLTIuMzI1LTQuNzczeiIvPjwvZz48L3N2Zz4=')} +.is2d .queen.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTIxLjA4OCA1MS4zMTItMS42NjQgNS4xODQgMy42NDgtMy4zMjh6bTI1LjA4OC4xMjgtMi4xNzYgMS44NTYgMy4yNjQgMi43NTJ6bS0xNy43MjggMi4xNzYtMi43NTIuNTc2LTMuMzkyIDQuMTZoMjIuNDY0cS0uNzA0LS42NC0zLjM5Mi00LjE2bC0yLjMwNC0uNDQ4LTMuNTIgMy41MnEtMS43OTIgMS43OTItMy41MiAwem0tOS4zNDQtNS41NjhxLTIuODE2LTYuMDgtNS41MDQtMTIuMTYtMi42MjQtNi4xNDQtNS4yNDgtMTIuMTYtMS40MDguMzg0LTIuMzA0LS41NzZsLTEuNDA4LTEuNTM2cS0xLjkyLTEuNjY0IDAtMy41ODRsMS40MDgtMS4zNDRxMS42NjQtMi4wNDggMy41MiAwbDEuNTM2IDEuMzQ0cTEuNTM2IDEuOTIgMCAzLjU4NGwtLjc2OC43NjggMTAuOTQ0IDguNTc2LS45Ni0xMy44MjRxLS44MzItLjE5Mi0xLjQwOC0uNzY4bC0xLjM0NC0xLjQwOHEtMS45ODQtMS43OTIgMC0zLjUybDEuMzQ0LTEuNTM2cTEuNzkyLTEuNjY0IDMuNTg0IDBsMS41MzYgMS41MzZxMS41MzYgMS43MjggMCAzLjUybC0xLjUzNiAxLjQwOCA2LjU5MiAxMS4yNjQgMy41Mi0xMi45MjhxLjE5MiAwLS41NzYtLjMybC0xLjQwOC0xLjUzNnEtMS43MjgtMS43OTIgMC0zLjU4NGwxLjQwOC0xLjUzNnExLjcyOC0xLjQwOCAzLjUyIDBsMS40MDggMS41MzZxMS45ODQgMS43OTIgMCAzLjU4NGwtMS40MDggMS41MzZxLS4zMi4zMi0uNjQuMzJsMy41ODQgMTMuMDU2IDYuNTkyLTExLjA3Mi0xLjUzNi0xLjUzNnEtMS41MzYtMS44NTYgMC0zLjcxMmwxLjQwOC0xLjQwOHExLjg1Ni0xLjUzNiAzLjY0OCAwbDEuNDA4IDEuNDA4cTEuODU2IDEuODU2IDAgMy43MTJsLTEuNDA4IDEuMzQ0LTEuMjE2Ljc2OC0uNzY4IDEzLjU2OCAxMS4yNjQtOS45ODQtLjk2LS43NjhxLTEuNTM2LTEuODU2IDAtMy43MTJsMS41MzYtMS40MDhxMS43OTItMS42NjQgMy41ODQgMGwxLjM0NCAxLjQwOHExLjg1NiAxLjg1NiAwIDMuNzEybC0xLjM0NCAxLjM0NHEtMS4wODggMS4wODgtMi4zNjguNzY4bC0xMS4yIDI2LjMwNCAzLjA3MiAxMi40OGgtMzYuOTI4em0wLTcuMzZxNi41OTItMy44NCAxNC45MTItMy44NCA3LjU1MiAwIDE0LjMzNiA0LjE2bDUuMzc2LTEyLjM1Mi05LjIxNiA2Ljg0OC0uNjQtMTAuODE2LTYuMzM2IDcuODcyLTMuNjQ4LTEwLjYyNC00LjM1MiAxMC42MjQtNS42OTYtNy44NzItLjUxMiAxMC44MTYtOS4yOC02LjIwOHptMTQuNzg0IDgtMy4yNjQgMy4yIDMuMjY0IDMuMjY0IDMuMDcyLTMuMjY0em0tMTMuNTY4LTUuMDU2cS4zMi43MDQuNjQgMS4zNDQuMzg0LjY0LjU3NiAxLjIxNiAyLjY4OC0xLjIxNiA1LjgyNC0yLjMwNCAzLjItMS4wODggNi42NTYtMS4wODggMy4zMjggMCA1LjgyNC44MzJ0Ni4zMzYgMi43NTJsMS4wODgtMi42MjRxLTMuNDU2LTEuOTItNi41MjgtMi44OC0zLjA3Mi0uOTYtNi43Mi0uOTYtMy41ODQgMC03LjI5Ni45Ni0zLjY0OC44OTYtNi40IDIuNzUyem0tMTIuNDgtMjQuODMyLTEuMDI0IDEuMDg4IDEuMDI0IDEuMDg4IDEuMDg4LTEuMDg4em0xMi45MjgtNi43Mi0xLjA4OCAxLjA4OCAxLjA4OCAxLjAyNCAxLjA4OC0xLjAyNHptMTMuMTItMi4wNDgtMS4wODggMS4wODggMS4wODggMS4wODguODk2LTEuMDg4em0xMi45MjggMi4xNzYtMS4wODggMS4wODggMS4wODggMS4wODggMS4wMjQtMS4wODh6bTEzLjM3NiA0LjkyOC0xLjA4OCAxLjA4OCAxLjA4OCAxLjA4OCAxLjA4OC0xLjA4OHptLTE1Ljg3MiAzMS44NzJxLTMuMDA4LTEuNi01LjE4NC0yLjQzMi0yLjExMi0uODMyLTUuMTItLjgzMnQtNS44ODggMS4wODhxLTIuODggMS4wMjQtNS4xODQgMi4xNzZsMi4zMDQgMi4zMDQgMi45NDQtLjY0IDMuODQtNC4xNnExLjcyOC0xLjQwOCAzLjUyIDBsNC4wMzIgNC4xNiAyLjU2LjY0eiIvPjxnIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggZD0ibTE5Ljc0OCA1NS44NTljMC0uMDY1LjI5OC0xLjA4Mi42NjMtMi4yNmwuNjYzLTIuMTQ0Ljk3NC44NDEuOTc0Ljg0MS0xLjUgMS40MWMtMS40MDkgMS4zMjQtMS43NzQgMS41OTQtMS43NzQgMS4zMTJ6bTMuMDY5IDEuOTgxYTc0LjcxIDc0LjcxIDAgMCAxIDEuNjM0LTIuMDQzbDEuMjY4LTEuNTQzIDEuMzMzLS4yOTUgMS4zMzItLjI5NCAyLjI4OSAyLjI0NmMyLjEwMiAyLjA2NCAyLjM0MyAyLjI0NiAyLjk2NiAyLjI0Ni45NzggMCAxLjI1NC0uMTg4IDMuNDczLTIuMzdsMi0xLjk2OCAxLjExMi4yMTRjMS4xLjIxMyAxLjEyOC4yMzQgMi4yNTIgMS42Ny42MjcuOCAxLjM5IDEuNzIgMS42OTYgMi4wNDVsLjU1Ni41OTFoLTIyLjI3OHoiLz48cGF0aCBkPSJtMzIuMjMzIDUzLjQ2NS0xLjYwNy0xLjYxOCAxLjU2OS0xLjQzNmMuODYyLS43OSAxLjY1Ni0xLjQzNSAxLjc2NC0xLjQzNXMuODA3LjY3IDEuNTU0IDEuNDkxbDEuMzU3IDEuNDkyLTEuNTE1IDEuNTYyLTEuNTE2IDEuNTYzem0xMy4yNzkgMS4wODgtMS40MTgtMS4yMTQuOTU4LS44NTNjLjUyNy0uNDcgMS4wMDItLjgxMSAxLjA1NS0uNzU5LjE1MS4xNTEgMS4wNTIgNC4wNjguOTMxIDQuMDU0LS4wNi0uMDA4LS43NDYtLjU2LTEuNTI2LTEuMjI4em0tNC44MjItMy42MzJjLTEuMTE3LS4yOC0xLjItLjM0My0zLjEzNC0yLjQxLTEuMDkzLTEuMTY5LTIuMjU0LTIuMjU2LTIuNTgtMi40MTdsLS41OTItLjI5Mi41NDYuMDAyYy45NzUuMDA0IDMuMjQ1LjQ4NiA0LjQ1NC45NDUuOTkuMzc3IDQuNDg2IDIuMDQgNC43MDMgMi4yMzguMTEzLjEwNC0xLjg3MyAyLjI1NC0yLjA2NiAyLjIzNy0uMS0uMDEtLjY5OS0uMTQ1LTEuMzMtLjMwM3ptLTE2LjQ3Ny0uNzUxYy0uNTk0LS42MDItMS4wNDQtMS4xMjctMS0xLjE2Ni4xOTctLjE3OCAxLjM5MS0uNzI1IDMuMjEzLTEuNDcgMi4wNDMtLjgzOCA0LjIwNC0xLjQ0OSA1Ljc3Ny0xLjYzNGwuOTA5LS4xMDgtLjU0Ni4zMzZjLS4zLjE4Ni0xLjQyIDEuMjc2LTIuNDkgMi40MjUtMS44OCAyLjAxOS0xLjk3OCAyLjA5NS0zIDIuMzE2LS41OC4xMjYtMS4yMTkuMjY2LTEuNDE5LjMxMi0uMjYzLjA2LS42NjQtLjIyMS0xLjQ0NC0xLjAxMXoiLz48cGF0aCBkPSJtNDQuMDIgNDUuMzM0Yy00LjQyMy0yLjE1Mi04LjA4NS0yLjkwNy0xMS45ODUtMi40NjgtMi41Ni4yODgtNC4xOTUuNzM4LTcuNjA0IDIuMDlsLTIuODYxIDEuMTM0LS41NDktMS4xNzNjLS40MDMtLjg2Mi0uNDk3LTEuMjM1LS4zNTQtMS40MDguMzEtLjM3MiAzLjA0MS0xLjY1NyA0LjU5LTIuMTU3IDMuNzMtMS4yMDYgOC41Mi0xLjY0OSAxMi4xMDItMS4xMTkgMi42OTUuMzk5IDQuNDkuOTc0IDcuNDM2IDIuMzgzIDIuMjg2IDEuMDk0IDIuNCAxLjE3NCAyLjI0NCAxLjU3NC0uMzUyLjkwMS0uOTE2IDIuMTQ4LS45NjUgMi4xMzItLjAyOS0uMDA4LS45NTItLjQ1My0yLjA1Mi0uOTg5eiIvPjxwYXRoIGQ9Im00Ni4yMDMgMzkuODExYTI4LjMwOCAyOC4zMDggMCAwIDAgLTctMi41MDRjLTIuMjA1LS40NzItOC44NjItLjQ3Ni0xMS4wOTEtLjAwNi0yLjQ0OS41MTctNS4wMjcgMS4zNjYtNy4wNzUgMi4zMy0xLjA0MS40OTEtMS45Mi44NjYtMS45NTEuODM0LS4xMjgtLjEyNy00Ljc4Ny0xMC43MzctNC43MzgtMTAuNzg2LjAzLS4wMyAyLjAzNCAxLjI2NiA0LjQ1NSAyLjg3OCAyLjQyIDEuNjEyIDQuNDQyIDIuODkyIDQuNDkgMi44NDMuMDUtLjA0OS4yMDEtMi4zNTYuMzM5LTUuMTI2cy4yODUtNS4wNzQuMzMtNS4xMThjLjA0NC0uMDQ0IDEuMjk0IDEuNTkyIDIuNzc4IDMuNjM2IDEuNDg0IDIuMDQ1IDIuNzU1IDMuNjgyIDIuODI1IDMuNjM5czEuMDYtMi4zNjYgMi4yLTUuMTYzYzEuMTQtMi43OTYgMi4xMjYtNC45ODggMi4xOS00Ljg3LjA2My4xMTguODc4IDIuNDQ0IDEuODEyIDUuMTdzMS43NTMgNC45MzUgMS44MiA0LjkxYy4wNjgtLjAyNyAxLjQ0Mi0xLjY4NCAzLjA1NC0zLjY4NHMyLjk5Ni0zLjY1OCAzLjA3My0zLjY4NWMuMDc4LS4wMjYuMjcyIDIuMjQ5LjQzMSA1LjA1Ni4xNiAyLjgwNy4zMzYgNS4xNS4zOTMgNS4yMDYuMDU2LjA1NyAyLjA0NC0xLjMzNyA0LjQxNy0zLjA5N3M0LjM1LTMuMTY1IDQuMzkzLTMuMTIyYy4wOTYuMDk1LTQuOTI2IDExLjcyOC01LjA1NSAxMS43MDgtLjA1LS4wMDgtLjk5LS40OC0yLjA5LTEuMDQ5em0tMzguODc2LTE5LjQzNi0uNDktLjUxMi41MTItLjQ5LjUxMS0uNDkuNDkuNTEyLjQ5LjUxMS0uNTExLjQ5LS41MTIuNDl6bTEyLjkwOS02LjcyNy0uNDktLjUxMi41MTItLjQ5LjUxMS0uNDkuNDkuNTExLjQ5LjUxMi0uNTExLjQ5LS41MTEuNDl6bTEzLjA4OC0yLjAwNS0uNDg3LS41MDcuNTEzLS40OTEuNTEzLS40OTEuNDEyLjQzOWMuMzI3LjM0OC4zNzQuNTEyLjIyNi43OS0uMzk4Ljc0My0uNjYuOC0xLjE3Ny4yNnptMTMuMDAzIDIuMjc3Yy0uNS0uNTMzLS40OTgtLjY5Ni4wMjQtMS4xODUuNTMtLjQ5OS41MjUtLjUuOTg4LjEyN2wuMzg2LjUyMi0uNS40OC0uNS40OHptMTMuMzY0IDQuODE4LS40OS0uNTExLjUxMS0uNDkuNTEyLS40OS40OS41MTEuNDkuNTEyLS41MTEuNDktLjUxMi40OXoiLz48L2c+PC9zdmc+')} +.is2d .king.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTM5LjU5NCA1Ny4xMzZxLTMuNTIgMy41Mi0zLjg0IDMuNzEyLTEuNiAxLjQ3Mi0zLjM5MiAwLS4zODQtLjE5Mi0zLjg0LTMuODRsLTQuNDguMjU2LTMuOTY4IDQuMzUyaDI3Ljg0bC00LjAzMi00LjE2em02LjAxNi01LjA1NnEtLjk2LS41NzYtMS44NTYtMS4wMjQtLjg5Ni0uNDQ4LTEuNTM2LS44MzItMS4yOC0uNTc2LTQuMDk2LS43NjgtMi43NTItLjE5Mi0zLjc3Ni0uMjU2LS45Ni4wNjQtMy4zOTIuMzg0LTIuMzY4LjMyLTUuMzc2IDEuMjE2LTMuMTM2IDEuMTUyLTMuODQgMS41MzZsMi4wNDggMi4wNDggNC43MzYtLjMyIDMuODQtNC4wMzJxMS43MjgtMS42IDMuMzkyIDBsNC4wMzIgNC4wMzIgMy45MDQuMzJ6bS0yNS40MDggMi44OC0uMzIgMi40OTYgMS43MjgtMS40MDh6bTAtNS4xODRxLjcwNC0uMzg0IDEuNzI4LS43NjggMS4wMjQtLjQ0OCAyLjc1Mi0uOTYgMi4zMDQtLjc2OCA0LjM1Mi0xLjE1MiAyLjExMi0uMzg0IDMuNjQ4LS41MTJsLS4xMjgtMTEuMzkycS0xLjE1Mi01Ljk1Mi0yLjU2LTExLjItMS40MDgtNS4yNDgtMy45MDQtNi4wMTYtMi44OC0uNzY4LTYuNzItLjQ0OC0zLjc3Ni4zMi00Ljk5Mi44OTYtMS4zNDQuNzA0LTMuMzkyIDIuNjI0LTEuOTg0IDEuODU2LTIuNzUyIDQuMTYtLjgzMiAyLjQzMi0xLjA4OCA0LjM1Mi0uMTkyIDEuOTItLjMyIDMuMTM2IDAgMi40OTYgMS4wODggNy4xMDQuNjQgMi4zMDQgMS43MjggMy45NjggMS4xNTIgMS42NjQgMy4zMjggMy4zOTIgMS45MiAxLjY2NCAzLjcxMiAyLjE3NiAxLjc5Mi40NDggMy41Mi42NHptMTMuODg4LTIxLjQ0cS41NzYtMi42ODggMS4yMTYtNS4xMi43MDQtMi40OTYgMS42NjQtNC40MTYgMC0uNjQtLjU3Ni0xLjc5Mi0uNTEyLS45Ni0xLjE1Mi0xLjc5Mi0uNTc2LS44MzItMS4wMjQtMS43OTItMS42IDIuMTc2LTIuMzA0IDMuNTg0LS41NzYgMS4wMjQtLjcwNCAxLjQ3Mi0uMDY0LjQ0OC0uMDY0LjgzMiAxLjcyOCAzLjUyIDIuOTQ0IDkuMDI0em0xNi4yNTYgMjQuMTkyIDEuMjggMTIuMTZoLTM1LjU4NGwxLjQwOC0xMi4xNnEtMS41MzYtLjMyLTMuMDcyLS45Ni0xLjUzNi0uNzA0LTMuMzkyLTIuMTEyLTIuNTYtMi4xMTItMy45MDQtNC4xNi0xLjM0NC0yLjA0OC0yLjExMi00LjkyOC0xLjIxNi00LjczNi0xLjIxNi04IC4wNjQtMS4zNDQuMzItMy41Mi4zMi0yLjE3NiAxLjQwOC00LjkyOC44OTYtMi44OCAzLjQ1Ni01LjI0OCAyLjU2LTIuMzY4IDQuMjI0LTMuMDcyIDEuNDcyLS43NjggNS45NTItMS4yMTYgNC40OC0uNDQ4IDcuNzQ0LjQ0OCAxLjUzNi42NCAxLjk4NCAxLjIxNi43NjgtMS4zNDQgMS43OTItMi44MTYgMS4wODgtMS41MzYgMi4wNDgtMi44OHYtMS4wODhoLTIuOTQ0di0zLjA3MmgyLjk0NHYtMi44OGgyLjk0NHYyLjg4aDIuNzUydjMuMDcyaC0yLjc1MnYxLjA4OHEuODk2IDEuMzQ0IDEuODU2IDIuODE2IDEuMDI0IDEuNDA4IDEuNzkyIDIuNzUyLjQ0OC0uMzIuODk2LS41NzYuNTEyLS4yNTYuOTYtLjUxMiAzLjMyOC0uODk2IDcuNzQ0LS40NDggNC40OC40NDggNi4xNDQgMS4yMTYgMS40NzIuNzA0IDQuMDMyIDMuMDcyIDIuNTYgMi4zNjggMy42NDggNS4yNDguODk2IDIuNzUyIDEuMjE2IDQuOTI4LjMyIDIuMTc2LjMyIDMuNTIuMTI4IDMuMi0xLjIxNiA4LS43NjggMi44OC0yLjExMiA0LjkyOC0xLjI4IDIuMDQ4LTMuOTA0IDQuMTYtMS45MiAxLjUzNi0zLjUyIDIuMjQtMS42LjY0LTMuMTM2LjgzMnptLTE2LjEyOC0uMzItMy4yIDMuMjY0IDMuMiAzLjIgMy4wNzItMy4yem0xMy4yNDggMi4zMDQtMS41MzYgMS4yMTYgMS44NTYgMS43Mjh6bS0xMi4wMzItOC4xMjhxMS42IDAgNC4xNi4yNTZ0My44NC44MzJsMi4wNDggMS4wMjRxMS4xNTIuNTc2IDIuMzA0IDEuMjggMS43MjgtLjEyOCAzLjQ1Ni0uNTc2IDEuNzkyLS41MTIgMy45MDQtMi4yNCAzLjkwNC0zLjI2NCA0LjkyOC03LjM2IDEuMjE2LTQuNTQ0IDEuMDg4LTcuMTA0IDAtMS4yMTYtLjI1Ni0zLjEzNi0uMjU2LTEuOTItMS4xNTItNC4zNTItLjgzMi0yLjMwNC0yLjg4LTQuMTYtMi4wNDgtMS45Mi0zLjI2NC0yLjYyNC0xLjM0NC0uNTc2LTQuOTkyLS44OTYtMy42NDgtLjMyLTYuNTI4LjQ0OC0yLjU2Ljc2OC0zLjk2OCA2LjAxNi0xLjM0NCA1LjI0OC0yLjQ5NiAxMS4yeiIvPjxwYXRoIGQ9Im0yMi4wMyA1OS41NTVjMS4wMzYtMS4xMjUgMS45NTItMi4wOTYgMi4wMzYtMi4xNTguMDg0LS4wNjEgMS4xMDctLjE1NiAyLjI3My0uMjExbDIuMTItLjEgMiAxLjk1OWMxLjEgMS4wNzcgMi4yMDIgMi4wOTMgMi40NSAyLjI1Ny40Mi4yNzkuMDI2LjI5OC02LjE1Ny4yOThoLTYuNjA2em0tMS45NjYtMi45NjdjLjA2NS0uMzkzLjExOS0uOTAzLjEyLTEuMTMzbC4wMDItLjQxOS42NC40ODhjLjcwNi41MzkuNjc0LjY3Mi0uMzM1IDEuMzlsLS41NDUuMzg5em0xMi41MjcuNDE3LTEuNDk2LTEuNTAzIDEuNTkxLTEuNTgyIDEuNTkxLTEuNTggMS40ODcgMS42MDEgMS40ODcgMS42MDItMS40OSAxLjQ4M2MtLjgyLjgxNi0xLjUzMyAxLjQ4My0xLjU4MyAxLjQ4M3MtLjc2NC0uNjc2LTEuNTg3LTEuNTA0em0yLjc5OCA0LjIwM2MuMjg4LS4yMTYgMS4zNDYtMS4yIDIuMzUxLTIuMTg3bDEuODI3LTEuNzk1IDIuMDgyLjEyMiAyLjA4My4xMjMgMS43ODggMS43NDdjLjk4My45NiAxLjg2NiAxLjg4OSAxLjk2IDIuMDY0LjE2NC4zLS4xODYuMzE4LTYuMjIxLjMxOGgtNi4zOTV6bTExLjM4Ny00Ljc0OC0uNzUxLS43NjkuNzAyLS41MDEuNzAzLS41MDIuMTI3IDEuMTkyYy4wNy42NTUuMDkyIDEuMjI3LjA0OSAxLjI3cy0uNDE3LS4yNjctLjgzLS42OXptLTUuNjM4LTIuMzA3LTEuMzIxLS4xMjItMi4zNTktMi4zMzQtMi4zNTgtMi4zMzMgMi4xMzQuMTIzYzIuOTI1LjE2NyA0LjMxLjQ5NiA2LjE3NiAxLjQ2Ny44NzcuNDU2IDEuNzEuOTAzIDEuODUuOTkzLjIwNC4xMy4wNzMuMzktLjYzNiAxLjI2Mi0uOTkzIDEuMjIyLS44NTkgMS4xODUtMy40ODYuOTQ0em0tMTguMzgzLS44MDItLjk2NC0uOTc2IDEuMzM0LS41NTFjMS43MTUtLjcwOCAyLjY3NS0xLjAyNyA0LjUtMS40OTMgMS4yNTktLjMyMSA0LjYwNy0uOTA4IDUuMi0uOTEyLjEwMiAwLS44NCAxLjAzMi0yLjA5IDIuMjk0bC0yLjI3NiAyLjI5NS0xLjgxOC4xNTJjLTIuOTc0LjI0OC0yLjgwOC4yODItMy44ODYtLjgwOXptLTQuNTY5LTMuOTU1Yy0uOTUtLjE5OS0yLjEzNi0uNTUtMi42MzYtLjc4LTEuOTQxLS44OTMtNS4wMDMtMy42OS02LjE2NC01LjYzLTEuMTQtMS45MDUtMi4xOC01Ljg4LTIuNDA3LTkuMjA0LS4xODktMi43NzUuNzA1LTcuNzQyIDEuNzc2LTkuODc3Ljg3OS0xLjc1IDMuMjM1LTQuMTcgNS4xODQtNS4zMjUgMi4wMi0xLjE5NyA4Ljc0LTEuNjM1IDExLjk2My0uNzggMS4xMy4zIDIuNDQ0IDEuNzU3IDMuMTggMy41MjQuNjY0IDEuNTk0IDEuODIzIDYuMDM4IDIuODE2IDEwLjc5NmwuNjUyIDMuMTI1djExLjA2NmwtLjY4Mi4xMDRjLTQuMTAyLjYzLTguNzQ4IDEuODktMTAuODEyIDIuOTMzLS40NzIuMjM5LS45MjIuNDI4LTEgLjQyMS0uMDc5LS4wMDctLjkyLS4xNzUtMS44Ny0uMzczem0yNy44MTgtLjY0MmMtMi45MTUtMS42NDYtNC40NC0yLjA2LTguNTgyLTIuMzM4bC0xLjk0NS0uMTMuMTAyLTUuNjYyLjEwMS01LjY2LjcxMi0zLjM2YzEuOTU4LTkuMjM3IDMuMDkzLTEyLjI5MiA0Ljk2My0xMy4zNTcuOTAzLS41MTUgMS4yNTItLjU5OSAzLjQwOS0uODI0IDEuODcyLS4xOTUgNS4xNi4wMTQgNy4zMjYuNDY1IDEuNjE2LjMzNyAyLjc0NyAxLjA4NiA0LjkxNyAzLjI1NSAxLjg0NCAxLjg0NCAyLjQ4OSAyLjk2NSAzLjI1MyA1LjY1OSAxLjIyMiA0LjMxIDEuMDQxIDguOTQzLS41MzMgMTMuNjUyLS42MzYgMS45MDMtMS43ODMgMy42ODgtMy4zOTIgNS4yOC0yLjE2OCAyLjE0NC0zLjc1NiAzLjExOC01LjgzIDMuNTc3LTIuNDM0LjUzOC0yLjU5Ni41MTgtNC41LS41NTd6bS0xMi4wNzUtMjEuMzM2Yy0uMzQyLTEuNTktMS4yODItNC42MTMtMS45NS02LjI3Mi0uNTMtMS4zMTgtLjcwOC0xLjk5NS0uNjQ4LTIuNDYuMDktLjY5NCAxLjIxOS0yLjgyOSAyLjI0Mi00LjIzN2wuNjM4LS44NzguNTkuOTcgMS4xNDggMS44NzdjMS4wNDYgMS43MDYgMS4wNzYgMi4wMzguMzUxIDMuODU3LS41ODkgMS40NzgtMS4zNDQgNC4wMzctMS45NzUgNi42ODlsLS4yNiAxLjA5eiIgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9zdmc+')} +.is2d .pawn.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTI3Ljc5MiAyOS4zMjhxMC0xLjA4OC43NjgtMS42NjQuNDQ4LS4xOTIgMS44NTYtMS43OTItMi4yNC0xLjAyNC0zLjcxMi0zLjA3Mi0xLjQwOC0yLjExMi0xLjQwOC00LjggMC0zLjU4NCAyLjU2LTYuMDggMi42MjQtMi41NiA2LjA4LTIuNTYgMy41MiAwIDYuMDE2IDIuNTYgMi41NiAyLjQ5NiAyLjU2IDYuMDggMCAyLjY4OC0xLjQ3MiA0LjgtMS40MDggMi4wNDgtMy41ODQgMy4wNzIgMS4zNDQgMS42IDEuODU2IDEuNzkyLjY0LjU3Ni42NCAxLjY2NHQtLjY0IDEuNzI4bC0uNzY4Ljc2OHExLjE1MiAyLjgxNiAyLjE3NiA1LjUwNCAxLjAyNCAyLjY4OCAxLjk4NCA0LjguNzY4IDEuOTIgMi4xMTIgMi40OTZsMS40MDguNTc2IDIuNzUyIDEuNjY0cTIuNzUyIDEuNjY0IDMuMjY0IDMuMDA4LjQ0OCAxLjI4LjU3NiAzLjcxMi4xOTIgMi4zNjguMzIgNS4wNTZoLTM4LjI3MnEwLTIuNjg4LjEyOC01LjA1Ni4xMjgtMi40MzIuNjQtMy43MTIuMzg0LTEuMzQ0IDMuMi0zLjAwOGwyLjgxNi0xLjY2NCAxLjM0NC0uNTc2cTEuMzQ0LS41NzYgMi4xNzYtMi40OTYuODk2LTIuMTEyIDEuOTg0LTQuOCAxLjA4OC0yLjY4OCAyLjE3Ni01LjUwNGwtLjc2OC0uNzY4cS0uNzY4LS42NC0uNzY4LTEuNzI4em01Ljk1Mi0zLjAwOHEtMi42ODggMi44OC0yLjg4IDMuMDcyLjE5Mi4yNTYgMS40NzIgMS42IDEuMzQ0IDEuMjggMS42IDEuNi4xOTItLjMyIDEuNDcyLTEuNiAxLjM0NC0xLjM0NCAxLjcyOC0xLjYtLjM4NC0uMTkyLTEuODU2LTEuNi0xLjQwOC0xLjQ3Mi0xLjUzNi0xLjQ3MnoiLz48cGF0aCBkPSJtMzIuNDE5IDMwLjkzMi0xLjQzNi0xLjUxNiAxLjI2NS0xLjM5NmMuNjk1LS43NjkgMS4zNDgtMS40MjUgMS40NTItMS40Ni4xMDMtLjAzNC44ODQuNjE1IDEuNzM2IDEuNDQzbDEuNTQ4IDEuNTA2LTEuNTY1IDEuNDctMS41NjUgMS40Njl6IiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=')} +.is2d .knight.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTQyIDUwLjcyN2MtLjA3IDEuOTcyLjM0MyAzLjkuNzI3IDUuODE4bC4zNjQgMS42MzdjLjA2LjA2LjE0My4xMDUuMTgyLjE4Mi4wMjcuMDU0LS4wNTQuMTU0IDAgLjE4MS4xMDguMDU1LjI0MiAwIC4zNjMgMGg3LjYzN2MuMzAzIDAgLjYwNy4wMjguOTA5IDAgLjM2Ny0uMDMzLjcyNS0uMTM2IDEuMDktLjE4MS4xMjEtLjAxNS4yNDUuMDIuMzY0IDAgLjI0Ny0uMDQxLjQ4LS4xNDcuNzI4LS4xODIuMjQ3LS4wMzYgMS4wODQuMDQ3IDEuMjcyIDAgLjA2LS4wMTUtLjA2LS4xODIgMC0uMTgyczAgLjI0MiAwIC4xODJ2LTIuMzY1YzAtLjA2LjAzNC0uMTMxIDAtLjE4Mi0uMDk1LS4xNDItLjI2OC0uMjItLjM2My0uMzYzLS4wMzQtLjA1IDAtLjEyMSAwLS4xODItLjEyMS0uMTIxLS4yNjktLjIyMS0uMzY0LS4zNjQtLjAzNC0uMDUgMC0uMTIgMC0uMTgydi0xLjA5YzAtLjEyMi4wMy0uMjQ2IDAtLjM2NC0uMDMzLS4xMzItLjE0OS0uMjMyLS4xODItLjM2NC0uMDMtLjExNy4wNTQtLjI1NSAwLS4zNjMtLjAyNy0uMDU1LS4xODIuMDYtLjE4MiAwIDAtLjA1NS42MDMuMTIgMC0uMTgyLS4wNTQtLjAyNy0uMTM5LjA0My0uMTgxIDAtLjA0My0uMDQzLS4wNjEtLjE4MiAwLS4xODIuMTEyIDAgLjY2OC45NzMgMC0uMzY0LS4wMzktLjA3Ni0uMjQzLS4xMi0uMTgyLS4xODEuMDYtLjA2MS4xODIuMjY3LjE4Mi4xODEgMC0uMTkxLS4wNzYtLjM4Ni0uMTgyLS41NDUtLjAzNC0uMDUtLjEyMSAwLS4xODIgMGgtLjE4MmMuMTIxIDAgLjQ3Mi4wNTQuMzY0IDAtLjIyNC0uMTEyLS40OS0uMTAzLS43MjctLjE4Mi0uMTI5LS4wNDMtLjI0My0uMTIxLS4zNjQtLjE4Mi0uNTQ2LS4wNi0xLjA5NS0uMDkxLTEuNjM2LS4xODItLjE5LS4wMzEtLjM1NS0uMTYtLjU0Ni0uMTgxLS4zNjEtLjA0LS43MjcgMC0xLjA5IDBoLTEuODE5Yy0uMTgyIDAtLjM2NS4wMjUtLjU0NSAwLTEuNzg4LS4yNTYuNDUxLS4xODItMS42MzctLjE4Mi0uOTMxIDAgLjM2MS4wMi0xLjQ1NC0uMTgyLS4xODEtLjAyLS4zNjQgMC0uNTQ2IDAtLjA2IDAtLjEyNy0uMDI3LS4xODIgMC0uMTk1LjA5OC0uMzQ1LjI3NS0uNTQ1LjM2NC0uMzUuMTU1LS45LjAzLTEuMDkxLjM2My0uMTYyLjI4NC4zMS41ODcuMzY0LjkxLjAxNC4wODQtLjE4Mi4wOTUtLjE4Mi4xODEgMCAuMDYuMTIxIDAgLjE4MiAwIiBmaWxsPSIjZmZmIiBzdHJva2U9IiMwMDAiLz48cGF0aCBkPSJtMjQuODQ4IDM5LjcyOHEtLjM4NC43MDQuMTkyIDEuMjguNTc2LjU3Ni0uMTkyIDEuNDcyLS43MDQgMS4wMjQtMi42MjQgMi43NTItMS44NTYgMS43MjgtMy4yIDIuMzA0LTIuMTc2IDEuMjgtNC40OC4xOTItMS4xNTItLjU3Ni0yLjg4LTIuMjQtMS42NjQtMS42NjQtMi4zMDQtMi42ODgtLjc2OC0xLjAyNC0uNTc2LTEuNzI4LjE5Mi0uNzA0LjA2NC0xLjY2NCAwLS43NjgtLjM4NC0xLjA4OC0uMzg0LS4zODQuMzg0LTIuNDk2Ljc2OC0xLjkyIDMuMjY0LTYuMzM2IDIuNDk2LTQuNDE2IDMuMi02LjUyOC43MDQtMS45Mi0uMjU2LTEuNzI4LS44OTYuMTI4LS41MTItLjg5Ni4zODQtMS4xNTIgMS40MDgtMy4wNzIgMS4wMjQtMS45ODQgMS44NTYtMi45NDQuODk2LS44OTYgMS44NTYtLjcwNCAxLjAyNC4xMjggMS43OTItMS4xNTIuNzA0LTEuMjE2IDEuMzQ0LTMuNzc2LjcwNC0yLjU2IDEuNDcyLTQuNjcyLjk2IDEuOTg0IDIuMDQ4IDMuNzc2IDEuMDg4IDEuNzkyIDIuMjQgMi4yNCAyLjg4LTEuMDg4IDYuOTEyLS41MTIgNS43Ni43NjggOC41MTIgMi4zMDQgMi43NTIgMS40NzIgNi41OTIgNi4yMDggMS40NzIgMS44NTYgMi4zNjggMy45NjguODk2IDIuMDQ4IDEuNiA0LjQ4LjcwNCAyLjQzMiAxLjA4OCA1LjU2OC40NDggMy4xMzYuNjQgNS42MzIgMCAyLjY4OC0uMTkyIDQuOTkyLS4xMjggMi4yNCAwIDQuNTQ0djMuNzc2cTAgMS40MDguNTEyIDMuNzc2LjMyIDEuOTg0IDEuMjggNC40MTYuOTYgMi40MzIgMS43OTIgNC44aC00MC4xOTJxLS44MzItMS42NjQtLjU3Ni0zLjY0OCAwLTEuMjguMzItMy4xMzZ0MS4wMjQtMy41MnEuNTc2LTEuNDcyIDEuNTM2LTIuODE2Ljk2LTEuNDA4IDIuMDQ4LTIuNjg4IDIuMDQ4LTMuMiAzLjg0LTUuMTIgMS41MzYtMS43MjggMy4zMjgtMy4yNjQgMS44NTYtMS42IDMuMzkyLTMuNDU2IDEuMjgtMS44NTYgMS43MjgtMy4zOTIuMzItMS4wMjQtLjA2NC0yLjc1Mi0uMzg0LTEuNzkyLS43MDQtMS43MjgtLjI1Ni4xMjgtMS4wMjQgMi4zNjgtLjc2OCAyLjI0LTEuNDcyIDMuMDA4LS43MDQgMS4wODgtMS41MzYgMS41MzYtLjc2OC4zODQtMS4zNDQuNzY4LS43NjguMzg0LTEuMjE2LjM4NC0uMzg0IDAtLjk2LjM4NC0uNzA0LjUxMi0xLjY2NCAxLjM0NC0uODk2Ljc2OC0xLjI4IDEuNDcyem0tMi4zMDQgMTYuMjU2cTEuNi4zODQgNC45MjguMzg0IDMuMzkyLS4wNjQgNC40OC0uMDY0bC4xMjgtMy4ycS0uOTYgMC0zLjk2OC0uMTI4LTIuOTQ0LS4xMjgtNC4yODgtLjM4NHptMjEuNTY4LjUxMnEyLjA0OC0uMTI4IDQuODY0LS4zODQgMi44OC0uMjU2IDQuOTkyLS4zODRsLS42NC0zLjI2NHEtMS43MjguMzg0LTUuMDU2LjU3Ni0zLjMyOC4xMjgtNC4zNTIuMTkyem0tNi4xNDQtNS4xMi0zLjM5MiAzLjM5MiAzLjM5MiAzLjUyIDMuMzkyLTMuNTJ6bS0xNS4yMzItMjguMjg4cS0uNzY4LS4xMjgtMi40OTYtLjEyOC0uNDQ4IDAtLjg5Ni41MTItLjM4NC41MTItLjQ0OC44MzJ2Ljg5NnEuMDY0LjY0LjQ0OC45Ni4xMjguMTI4IDEuMzQ0LjEyOC4zODQtLjA2NC45Ni0uMzIuNTc2LS4zMiAxLjA4OC0uNTc2IDEuMzQ0LS43MDQgMS4zNDQtMS4yMTYuMTI4LS43MDQtLjMyLS43NjgtLjM4NC0uMDY0LTEuMDI0LS4zMnptLTEyLjE2IDEzLjY5NnExLjA4OCAxLjA4OCAxLjA4OCAyLjMwNC4wNjQuMjU2LS4xMjggMS4yOC0uMTkyLjk2LS4xOTIgMS4wMjQuMTkyLjI1NiAxLjM0NC0xLjA4OCAxLjIxNi0xLjM0NCAxLjA4OC0xLjg1NiAwLS4zODQtMS4yOC0xLjA4OC0xLjI4LS43MDQtMS45Mi0uNTc2em0xOS4yLTI1LjA4OHEzLjg0LjU3NiA4IDEuNzI4IDQuMTYgMS4wODggNi45MTIgMy44NCAyLjQ5NiAyLjg4IDMuMzkyIDQuMjI0Ljg5NiAxLjI4IDIuMDQ4IDMuOTA0Ljg5NiAzLjAwOCAxLjM0NCA2LjMzNi41MTIgMy4zMjguNzY4IDYuMjcyLjE5MiAyLjQ5Ni4xOTIgNC45MjggMCAyLjM2OCAxLjUzNiA2Ljc4NC0uMTkyLTMuMjY0IDAtNi4wMTYuMjU2LTIuODE2LjEyOC01LjgyNC0uMTI4LTMuMzI4LS44MzItNy40ODh0LTEuNDcyLTYuMDhxLS45Ni0yLjM2OC0yLjU2LTQuNDE2LTEuNTM2LTIuMDQ4LTMuNDU2LTQuMTYtMS43MjgtMS44NTYtMy43NzYtMi42ODgtMi4wNDgtLjg5Ni01LjMxMi0xLjQ3Mi0yLjE3Ni0uNDQ4LTMuNjQ4LS4xOTItMS40MDguMjU2LTMuMjY0LjMyeiIvPjxwYXRoIGQ9Im0yMy43OCA1Ni4xNTljLS40Ny0uMDY2LS45MDktLjE3Mi0uOTczLS4yMzYtLjA2NC0uMDY1LjE1LS44MjUuNDc3LTEuNjlsLjU5My0xLjU3Mi41NzcuMTA5Yy40NzUuMDg5IDYuMTIzLjQ1IDcuMjI3LjQ2My4yNzIuMDAzLjMxOC4xODYuMzE4IDEuMjYxIDAgMS45OC4zMDMgMS44MzctMy43OTIgMS44MDktMS45NjQtLjAxNC0zLjk1Ni0uMDc4LTQuNDI3LS4xNDR6bTEyLjQ5Mi4zNS0xLjYzMi0xLjYzOSAxLjY3OC0xLjY3OCAxLjY3OC0xLjY3OCAxLjYzIDEuNjIyIDEuNjMgMS42MjMtMS41MDYgMS42MzdjLS44MjguOS0xLjU4MyAxLjY2My0xLjY3NyAxLjY5NC0uMDk0LjAzMi0uOTA1LS42OC0xLjgwMi0xLjU4MXptMTAuNzY5LS4zMDFjLjEyNC0uMDUuMzY5LS4wNTMuNTQ2LS4wMDdzLjA3Ni4wODctLjIyNC4wOWMtLjMuMDA0LS40NDUtLjAzMy0uMzIyLS4wODN6bTYuMTYzLTkuMTU0Yy0uNDMyLTEuNTc0LS41NTItMi40ODMtLjY4Ny01LjE4MS0uMzQ4LTYuOTQ0LTEuMzgzLTEzLjg0OC0yLjUxNi0xNi43ODYtLjY4Ny0xLjc4My0xLjg1NS0zLjY3OS0zLjU1Mi01Ljc3LTIuMjgyLTIuODExLTMuOTM5LTQuMTM2LTYuNDg1LTUuMTg2LTEuMzMyLS41NS01LjMyMS0xLjYwMi03LjU2Mi0xLjk5Ni0uNzI4LS4xMjctMS4yNTUtLjMwMS0xLjE3LS4zODZzMS4wNDktLjIwMiAyLjE0My0uMjYxYzIuMjM1LS4xMjEgNC4zNy4yMjYgNy40MiAxLjIwNyAyLjgyMy45MDggNC4zNyAyLjE3NSA3LjU4NSA2LjIxIDIuNjkzIDMuMzggMy43NjkgNS43OTYgNC42IDEwLjMzMS45ODUgNS4zNyAxLjE5IDkuNDQxLjg2IDE3LjA5MWwtLjExMyAyLjYzNnptLTMzLjU2Mi0yMC44ODhjLS44MTItLjIyNi0uOTY1LTEuNzE3LS4yNjMtMi41NTIuNDMzLS41MTQuNTYyLS41NiAxLjU5MS0uNTU2IDEuNjcuMDA1IDIuOTI0LjM3NCAyLjk5OC44ODEuMDg3LjU5OC0uMjU4LjkxLTEuODY4IDEuNjktMS40NzQuNzEyLTEuNjczLjc1Ni0yLjQ1OC41Mzd6bS04LjA1OCAxMy43MDVjLjA4NC0xLjUzMy4wNi0xLjY3Ny0uMzc4LTIuMzE3LS4zNzQtLjU0NS0uNDEtLjY4MS0uMTgxLS42ODEuNDEgMCAyLjQ1IDEuMTE2IDIuNTU5IDEuNC4xODUuNDgzLS4xNiAxLjE2LTEuMTExIDIuMTgzbC0uOTc4IDEuMDUuMDktMS42MzV6IiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=')} +.is2d .bishop.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTI3Ljk4NCA1NS40NzJxLTIuNzUyLS4wNjQtNC41NDQtLjA2NC0xLjc5Mi0uMDY0LTEuOTItLjI1Ni0uODMyLS43NjgtLjg5Ni0xLjg1Ni0uMDY0LTEuMDg4Ljc2OC0xLjc5Mi4wNjQtLjEyOCAxLjA4OC0xLjUzNiAxLjAyNC0xLjQ3MiAyLjQzMi0zLjU4NC0yLjQzMi0zLjA3Mi00LjYwOC02LjAxNi0yLjE3Ni0zLjAwOC0yLjYyNC0zLjUyLTEuNDA4LTEuMjE2LTEuNDA4LTMuMDA4IDAtMS44NTYgMS40MDgtMy4yNjQuMzg0LS4zODQgMi4zMDQtMi45NDQgMS45ODQtMi41NiA0LjIyNC01LjU2OCAyLjMwNC0zLjAwOCA0LjIyNC01LjU2OCAxLjk4NC0yLjYyNCAyLjI0LTIuODguMjU2LS4yNTYuMzg0LS40NDgtLjcwNC0uNzY4LTEuNDcyLTEuNDcyLS43MDQtLjcwNC0uODMyLS45Ni0yLjA0OC0xLjc5MiAwLTMuNTg0LjE5Mi0uMzIgMS43MjgtMS43OTIgMS42LTEuNDcyIDEuODU2LTEuODU2IDEuNzI4LTEuNjY0IDMuMzI4IDBMMzcuNTIgNS4zNnExLjQ3MiAxLjQ3MiAxLjg1NiAxLjc5MiAxLjc5MiAxLjc5MiAwIDMuNTg0LS4yNTYuMjU2LTEuMDI0Ljk2dC0xLjQwOCAxLjQ3MnEuMDY0IDAgLjMyLjE5Mi40NDguNTEyIDIuMzY4IDMuMTM2IDEuOTIgMi41NiA0LjA5NiA1LjU2OCAyLjI0IDMuMDA4IDQuMDk2IDUuNTY4IDEuOTIgMi41NiAyLjMwNCAyLjk0NCAxLjM0NCAxLjQwOCAxLjM0NCAzLjI2NCAwIDEuNzkyLTEuMzQ0IDMuMDA4LS40NDguNTEyLTIuNTYgMy4zOTItMi4wNDggMi44MTYtNC4zNTIgNS44ODggMS42IDIuMTEyIDIuNjg4IDMuNzEyIDEuMTUyIDEuNTM2IDEuMzQ0IDEuNjY0IDEuNzI4IDEuNzkyLS4xOTIgMy42NDgtLjEyOC4xOTItMi4xMTIuMjU2LTEuOTIgMC00LjguMDY0LS4xOTIgMS40MDgtLjEyOCAxLjQwOC4zMi4zMiAyLjE3Ni4zMiAxLjg1Ni0uMDY0IDQuMDk2LS4xMjh0NC4yODgtLjA2NHEyLjExMi0uMDY0IDIuOTQ0LjE5MiAyLjExMi43MDQgMi45NDQgMy4yNjQuODMyIDIuNDk2IDEuNDA4IDQuODY0SDQwLjc4NHEtMS4zNDQgMC0yLjU2LS4wNjQtMS4xNTItLjEyOC0yLjM2OC0uNzA0LTEuMTUyLS41NzYtMS40NzItLjgzMi0uMzItLjMyLS4zODQtLjcwNCAwIC4zODQtLjI1Ni43MDQtLjI1Ni4yNTYtMS40MDguODMyLTEuMzQ0LjU3Ni0yLjU2LjcwNC0xLjIxNi4wNjQtMi4zNjguMDY0aC0xNy4yOHEuNzA0LTIuMzY4IDEuNjY0LTQuODY0IDEuMDI0LTIuNTYgMy4xMzYtMy4yNjQuNzY4LS4yNTYgMi43NTItLjE5MiAyLjA0OCAwIDQuMTYuMDY0IDIuMTc2LjA2NCAzLjkwNC4xMjggMS43OTIgMCAyLjExMi0uMzIuMzItLjE5Mi4xOTItLjM4NC0uMDY0LS4yNTYtLjA2NC0xLjAyNHptNy41NTItMjAuNDE2aDMuNTJ2LTIuOTQ0aC0zLjUydi00LjI4OGgtMi45NDR2NC4yODhoLTMuNTJ2Mi45NDRoMy41MnYxMS4wNzJoMi45NDR6TTM0IDUuNjE2cS0uMjU2LjM4NC0xLjYgMS43MjgtMS4yOCAxLjM0NC0xLjQ3MiAxLjUzNi4xOTIuMzg0IDEuNDcyIDEuNzI4IDEuMzQ0IDEuMjggMS42IDEuNDcyLjE5Mi0uMTkyIDEuNTM2LTEuNDcybDEuNzI4LTEuNzI4cS0uMzg0LS4xOTItMS43MjgtMS41MzZRMzQuMTkyIDYgMzQgNS42MTZ6bS0yLjk0NCA0OS43MjhoNS44ODhsLjU3Ni0yLjQ5NmgtNy4wNHoiLz48cGF0aCBkPSJNMzAuODg2IDU0LjQ0M2MtLjQwNS0xLjc1OC0uNjctMS42MjIgMy4xNzQtMS42MjJoMy4zODZsLS4xMTYuNThjLS4wNjQuMzItLjIuODkzLS4zMDMgMS4yNzNsLS4xODYuNjkySDMxLjF6bTEuNzg3LTEzLjg5NXYtNS41NDVIMjkuMjJ2LTIuOTFoMy40NTR2LTQuMTgxaDIuNzI4djQuMTgxaDMuNjM2djIuODk2bC0xLjc3My4wNTItMS43NzMuMDUyLS4wNDggNS41LS4wNDggNS41aC0yLjcyM3YtNS41NDV6bS0uMjU3LTMwLjA4NkwzMSA5LjAwNWwuOTEyLTEuMDQ3Yy41MDEtLjU3NSAxLjE4NS0xLjI5NCAxLjUxOS0xLjU5N2wuNjA3LS41NSAxLjU3MSAxLjYgMS41NzIgMS42LTEuNTQgMS40MDVjLS44NDguNzcyLTEuNiAxLjQyNy0xLjY3MyAxLjQ1NC0uMDczLjAyNy0uNzctLjYwNy0xLjU1LTEuNDA4eiIgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIi8+PHBhdGggZD0iTTI3Ljk4NCA1NS40NzJxLTIuNzUyLS4wNjQtNC41NDQtLjA2NC0xLjc5Mi0uMDY0LTEuOTItLjI1Ni0uODMyLS43NjgtLjg5Ni0xLjg1Ni0uMDY0LTEuMDg4Ljc2OC0xLjc5Mi4wNjQtLjEyOCAxLjA4OC0xLjUzNiAxLjAyNC0xLjQ3MiAyLjQzMi0zLjU4NC0yLjQzMi0zLjA3Mi00LjYwOC02LjAxNi0yLjE3Ni0zLjAwOC0yLjYyNC0zLjUyLTEuNDA4LTEuMjE2LTEuNDA4LTMuMDA4IDAtMS44NTYgMS40MDgtMy4yNjQuMzg0LS4zODQgMi4zMDQtMi45NDQgMS45ODQtMi41NiA0LjIyNC01LjU2OCAyLjMwNC0zLjAwOCA0LjIyNC01LjU2OCAxLjk4NC0yLjYyNCAyLjI0LTIuODguMjU2LS4yNTYuMzg0LS40NDgtLjcwNC0uNzY4LTEuNDcyLTEuNDcyLS43MDQtLjcwNC0uODMyLS45Ni0yLjA0OC0xLjc5MiAwLTMuNTg0LjE5Mi0uMzIgMS43MjgtMS43OTIgMS42LTEuNDcyIDEuODU2LTEuODU2IDEuNzI4LTEuNjY0IDMuMzI4IDBMMzcuNTIgNS4zNnExLjQ3MiAxLjQ3MiAxLjg1NiAxLjc5MiAxLjc5MiAxLjc5MiAwIDMuNTg0LS4yNTYuMjU2LTEuMDI0Ljk2dC0xLjQwOCAxLjQ3MnEuMDY0IDAgLjMyLjE5Mi40NDguNTEyIDIuMzY4IDMuMTM2IDEuOTIgMi41NiA0LjA5NiA1LjU2OCAyLjI0IDMuMDA4IDQuMDk2IDUuNTY4IDEuOTIgMi41NiAyLjMwNCAyLjk0NCAxLjM0NCAxLjQwOCAxLjM0NCAzLjI2NCAwIDEuNzkyLTEuMzQ0IDMuMDA4LS40NDguNTEyLTIuNTYgMy4zOTItMi4wNDggMi44MTYtNC4zNTIgNS44ODggMS42IDIuMTEyIDIuNjg4IDMuNzEyIDEuMTUyIDEuNTM2IDEuMzQ0IDEuNjY0IDEuNzI4IDEuNzkyLS4xOTIgMy42NDgtLjEyOC4xOTItMi4xMTIuMjU2LTEuOTIgMC00LjguMDY0LS4xOTIgMS40MDgtLjEyOCAxLjQwOC4zMi4zMiAyLjE3Ni4zMiAxLjg1Ni0uMDY0IDQuMDk2LS4xMjh0NC4yODgtLjA2NHEyLjExMi0uMDY0IDIuOTQ0LjE5MiAyLjExMi43MDQgMi45NDQgMy4yNjQuODMyIDIuNDk2IDEuNDA4IDQuODY0SDQwLjc4NHEtMS4zNDQgMC0yLjU2LS4wNjQtMS4xNTItLjEyOC0yLjM2OC0uNzA0LTEuMTUyLS41NzYtMS40NzItLjgzMi0uMzItLjMyLS4zODQtLjcwNCAwIC4zODQtLjI1Ni43MDQtLjI1Ni4yNTYtMS40MDguODMyLTEuMzQ0LjU3Ni0yLjU2LjcwNC0xLjIxNi4wNjQtMi4zNjguMDY0aC0xNy4yOHEuNzA0LTIuMzY4IDEuNjY0LTQuODY0IDEuMDI0LTIuNTYgMy4xMzYtMy4yNjQuNzY4LS4yNTYgMi43NTItLjE5MiAyLjA0OCAwIDQuMTYuMDY0IDIuMTc2LjA2NCAzLjkwNC4xMjggMS43OTIgMCAyLjExMi0uMzIuMzItLjE5Mi4xOTItLjM4NC0uMDY0LS4yNTYtLjA2NC0xLjAyNHptNy41NTItMjAuNDE2aDMuNTJ2LTIuOTQ0aC0zLjUydi00LjI4OGgtMi45NDR2NC4yODhoLTMuNTJ2Mi45NDRoMy41MnYxMS4wNzJoMi45NDR6TTM0IDUuNjE2cS0uMjU2LjM4NC0xLjYgMS43MjgtMS4yOCAxLjM0NC0xLjQ3MiAxLjUzNi4xOTIuMzg0IDEuNDcyIDEuNzI4IDEuMzQ0IDEuMjggMS42IDEuNDcyLjE5Mi0uMTkyIDEuNTM2LTEuNDcybDEuNzI4LTEuNzI4cS0uMzg0LS4xOTItMS43MjgtMS41MzZRMzQuMTkyIDYgMzQgNS42MTZ6bS0yLjk0NCA0OS43MjhoNS44ODhsLjU3Ni0yLjQ5NmgtNy4wNHoiLz48cGF0aCBkPSJNMzAuODg2IDU0LjQ0M2MtLjQwNS0xLjc1OC0uNjctMS42MjIgMy4xNzQtMS42MjJoMy4zODZsLS4xMTYuNThjLS4wNjQuMzItLjIuODkzLS4zMDMgMS4yNzNsLS4xODYuNjkySDMxLjF6bTEuNzg3LTEzLjg5NXYtNS41NDVIMjkuMjJ2LTIuOTFoMy40NTR2LTQuMTgxaDIuNzI4djQuMTgxaDMuNjM2djIuODk2bC0xLjc3My4wNTItMS43NzMuMDUyLS4wNDggNS41LS4wNDggNS41aC0yLjcyM3YtNS41NDV6bS0uMjU3LTMwLjA4NkwzMSA5LjAwNWwuOTEyLTEuMDQ3Yy41MDEtLjU3NSAxLjE4NS0xLjI5NCAxLjUxOS0xLjU5N2wuNjA3LS41NSAxLjU3MSAxLjYgMS41NzIgMS42LTEuNTQgMS40MDVjLS44NDguNzcyLTEuNiAxLjQyNy0xLjY3MyAxLjQ1NC0uMDczLjAyNy0uNzctLjYwNy0xLjU1LTEuNDA4eiIgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9zdmc+')} +.is2d .rook.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTMwLjI4OCAzNS4zMTJsMy41MiAzLjcxMiAzLjcxMi0zLjcxMi0zLjcxMi0zLjUyem0xOC4xNzYtMTAuMzA0bDIuNDMyIDE5LjUyIDIuODE2IDYuMDE2djEyLjkyOEgxNC4xNlY1MC41NDRsMi42MjQtNi4wMTYgMi40MzItMTkuNTItNC45MjgtMTAuNzUyIDMuMDcyLTkuNzI4SDI2djguMzJoMy43MTJ2LTguMzJoOC43Njh2OC4zMmgzLjY0OHYtOC4zMmg4LjY0bDMuMDcyIDkuNzI4ek0xOS4wODggNDYuMzg0bC0xLjQwOCAzLjA3Mkg1MGwtMS41MzYtMy4wNzJ6bTI3LjItMjIuNzg0SDIxLjcxMmwuNTc2IDIuOTQ0aDIzLjY4eiIvPjxwYXRoIGQ9Ik0yMi4xMzIgMjUuNDY0Yy0uMTEtLjU3NS0uMjQtMS4yMy0uMjg5LTEuNDU1bC0uMDg3LS40MWgyNC4zNzF2LjYxMmMwIC4zMzYtLjA1Mi45OS0uMTE2IDEuNDU0bC0uMTE2Ljg0NGgtMjMuNTZ6bTkuODcgMTEuNjEybC0xLjY3LTEuNzc5IDEuNzEtMS43MDMgMS43MS0xLjcwNC41MDYuNDRhNzMuMDIzIDczLjAyMyAwIDAgMSAxLjgyNCAxLjcxNUwzNy40IDM1LjMybC0xLjc3IDEuNzc3Yy0uOTc0Ljk3Ny0xLjgxMyAxLjc3My0xLjg2NCAxLjc2OC0uMDUyLS4wMDUtLjg0Ny0uODEtMS43NjUtMS43ODh6TTE4LjE5NiA0OC40NjRjLjIzNi0uNTI1LjUzNS0xLjE4LjY2NC0xLjQ1NWwuMjM0LS41aDI5LjM5MmwuNzMyIDEuNDU1LjczMSAxLjQ1NEgxNy43Njh6IiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=')} +.is2d .queen.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTIxLjA4OCA1MS4zMTItMS42NjQgNS4xODQgMy42NDgtMy4zMjh6bTI1LjA4OC4xMjgtMi4xNzYgMS44NTYgMy4yNjQgMi43NTJ6bS0xOC4xNzYtLjc2OC0yLjYyNC42NC4zMiAyLjg4IDIuNjI0LS40NDh6bTE0LjE0NC42NC0yLjU2LS42NC0uNTEyIDMuMDcyIDIuNDk2LjMyem0tMjMuMDQtMy4yNjQtMTAuNzUyLTI0LjMycS0xLjQwOC4zODQtMi4zMDQtLjU3NmwtMS40MDgtMS41MzZxLTEuOTItMS42NjQgMC0zLjU4NGwxLjQwOC0xLjM0NHExLjY2NC0yLjA0OCAzLjUyIDBsMS41MzYgMS4zNDRxMS41MzYgMS45MiAwIDMuNTg0bC0uNzY4Ljc2OCAxMC45NDQgOC41NzYtLjk2LTEzLjgyNHEtLjgzMi0uMTkyLTEuNDA4LS43NjhsLTEuMzQ0LTEuNDA4cS0xLjk4NC0xLjc5MiAwLTMuNTJsMS4zNDQtMS41MzZxMS43OTItMS42NjQgMy41ODQgMGwxLjUzNiAxLjUzNnExLjUzNiAxLjcyOCAwIDMuNTJsLTEuNTM2IDEuNDA4IDYuNTkyIDExLjI2NCAzLjUyLTEyLjkyOC0uNTc2LS4zMi0xLjQwOC0xLjUzNnEtMS43MjgtMS43OTIgMC0zLjU4NGwxLjQwOC0xLjUzNnExLjcyOC0xLjQwOCAzLjUyIDBsMS40MDggMS41MzZxMS45ODQgMS43OTIgMCAzLjU4NGwtMS40MDggMS41MzYtLjY0LjMyIDMuNTg0IDEzLjA1NiA2LjU5Mi0xMS4wNzItMS41MzYtMS41MzZxLTEuNTM2LTEuODU2IDAtMy43MTJsMS40MDgtMS40MDhxMS44NTYtMS41MzYgMy42NDggMGwxLjQwOCAxLjQwOHExLjg1NiAxLjg1NiAwIDMuNzEybC0xLjQwOCAxLjM0NC0xLjIxNi43NjgtLjc2OCAxMy41NjggMTEuMjY0LTkuOTg0LS45Ni0uNzY4cS0xLjUzNi0xLjg1NiAwLTMuNzEybDEuNTM2LTEuNDA4cTEuNzkyLTEuNjY0IDMuNTg0IDBsMS4zNDQgMS40MDhxMS44NTYgMS44NTYgMCAzLjcxMmwtMS4zNDQgMS4zNDRxLTEuMDg4IDEuMDg4LTIuMzY4Ljc2OGwtMTEuMiAyNi4zMDQgMy4wNzIgMTIuNDhoLTM2LjkyOHptMTQuNzg0LjY0LTMuMjY0IDMuMiAzLjI2NCAzLjI2NCAzLjA3Mi0zLjI2NHptLTEzLjU2OC01LjA1NiAxLjIxNiAyLjU2cTIuNjg4LTEuMjE2IDUuODI0LTIuMzA0IDMuMi0xLjA4OCA2LjY1Ni0xLjA4OCAzLjMyOCAwIDUuODI0LjgzMnQ2LjMzNiAyLjc1MmwxLjA4OC0yLjYyNHEtMy40NTYtMS45Mi02LjUyOC0yLjg4LTMuMDcyLS45Ni02LjcyLS45Ni0zLjU4NCAwLTcuMjk2Ljk2LTMuNjQ4Ljg5Ni02LjQgMi43NTJ6bS0xMi42MDgtMjQuOTYtMS40MDggMS4yMTYgMS40MDggMS40MDggMS4yMTYtMS40MDh6bTEzLjA1Ni02Ljc4NC0xLjM0NCAxLjI4IDEuMzQ0IDEuMzQ0IDEuMjgtMS4zNDR6bTEzLjEyLTIuMzA0LTEuNTM2IDEuNTM2IDEuNTM2IDEuNTM2IDEuMzQ0LTEuNTM2em0xMi45MjggMi4zMDQtMS40MDggMS40MDggMS40MDggMS40MDggMS4yMTYtMS40MDh6bTEzLjM3NiA0LjkyOC0xLjI4IDEuMjggMS4yOCAxLjM0NCAxLjI4LTEuMzQ0eiIvPjxwYXRoIGQ9Im0xOS43NDggNTUuODU5YzAtLjA2NS4yOTgtMS4wODIuNjYzLTIuMjZsLjY2My0yLjE0NC45NzQuODQxLjk3NC44NDEtMS41IDEuNDFjLTEuNDA5IDEuMzI0LTEuNzc0IDEuNTk0LTEuNzc0IDEuMzEyem01LjkxMi0yLjczM2MtLjA2NC0uNTgzLS4xMzItMS4yMTctLjE1LTEuNDEtLjAyOS0uMjg4LjE4Mi0uNDA1IDEuMTg1LS42NmwxLjIyLS4zMDkuMTA0Ljg0Mi4xODggMS41MDIuMDg0LjY2MS0xLjAyNy4xMjljLS41NjUuMDctMS4xMy4xNjgtMS4yNTcuMjE2LS4xNjEuMDYyLS4yNjQtLjIyNy0uMzQ3LS45NzF6bTYuNTczLjMzOS0xLjYwNy0xLjYxOCAxLjU2OS0xLjQzNmMuODYyLS43OSAxLjY1Ni0xLjQzNSAxLjc2NC0xLjQzNXMuODA3LjY3IDEuNTU0IDEuNDkxbDEuMzU3IDEuNDkyLTEuNTE1IDEuNTYyLTEuNTE2IDEuNTYzem03LjY1MS4zNzhjLS43NzQtLjA4LS43NzEtLjA3LS40NzctMS44NTJsLjIwNC0xLjIzNyAxLjIwNS4zMDhjLjgxNC4yMDggMS4xOTQuMzkxIDEuMTcyLjU2NWEzNS4xMSAzNS4xMSAwIDAgMSAtLjI0IDEuMzAzYy0uMjI4IDEuMTUtLjExNyAxLjA5Ni0xLjg2NC45MTN6bTUuNjI4LjcxLTEuNDE4LTEuMjE0Ljk1OC0uODUzYy41MjctLjQ3IDEuMDAyLS44MTEgMS4wNTUtLjc1OS4xNTEuMTUxIDEuMDUyIDQuMDY4LjkzMSA0LjA1NC0uMDYtLjAwOC0uNzQ2LS41Ni0xLjUyNi0xLjIyOHptLTEuNDkyLTkuMjE5Yy00LjQyMy0yLjE1Mi04LjA4NS0yLjkwNy0xMS45ODUtMi40NjgtMi41NjMuMjg5LTQuMTk1LjczOC03LjYyNyAyLjFsLTIuODg2IDEuMTQ0LS41MzMtMS4xNzRjLS40MDEtLjg4Ni0uNDgyLTEuMjM0LS4zMy0xLjQxNy4zMTUtLjM4IDMuMDMyLTEuNjYgNC41OTctMi4xNjYgMy43My0xLjIwNiA4LjUyLTEuNjQ5IDEyLjEwMi0xLjExOSAyLjY5NS4zOTkgNC40OS45NzQgNy40MzYgMi4zODMgMi4yODYgMS4wOTQgMi40IDEuMTc0IDIuMjQ0IDEuNTc0LS4zNTIuOTAxLS45MTYgMi4xNDgtLjk2NSAyLjEzMi0uMDI5LS4wMDgtLjk1Mi0uNDUzLTIuMDUyLS45ODl6bTE1LjQ3NS0yNi42NzQtLjQ2MS0uNTkuNTc1LS41OTMuNTc1LS41OTMuNTg5LjU3LjU4OC41Ny0uNDg4LjYxMmMtLjI2OS4zMzctLjU4NS42MTItLjcwMy42MTJzLS40MjEtLjI2NS0uNjc1LS41ODl6bS0xMy4zODMtNC43NzUtLjYxNy0uNjM3LjYyNi0uNjQ3LjYyNy0uNjQ2LjU5Ny42NS41OTcuNjUyLS40ODIuNjMyYy0uMjY1LjM0OC0uNTM5LjYzMi0uNjA3LjYzMi0uMDY5IDAtLjQwMi0uMjg2LS43NDEtLjYzNnptLTEyLjk2NC0yLjA1NC0uNjc0LS42OS43MzYtLjcxOC43MzYtLjcxOC42MDkuNzI1LjYxLjcyNi0uNTczLjY2N2MtLjMxNC4zNjctLjYxNi42NzQtLjY3LjY4My0uMDU1LjAwOC0uNDAzLS4yOTUtLjc3NC0uNjc1em0tMTMuMDc1IDEuODg4LS40OTMtLjU5NS41OS0uNTcyLjU5LS41NzEuNTcyLjU3Mi41NzIuNTcyLS40NjMuNjA3Yy0uMjU1LjMzNC0uNTU2LjYwMS0uNjcuNTk0LS4xMTItLjAwNy0uNDI3LS4yOC0uNjk4LS42MDd6bS0xMy4wNDIgNi45MDctLjYyNS0uNjQ5LjUyMy0uNTQ2Yy42NDYtLjY3NS44MDYtLjY3OSAxLjQyNC0uMDM0bC40OS41MTMtLjU5My42ODItLjU5My42ODN6IiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=')} +.is2d .king.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTIzLjkxNCA1NC4zODQuMzIgMi44OHExLjE1MiAwIDIuMTc2LS4wNjQgMS4wMjQtLjA2NCAyLjExMi0uMTkydi0yLjk0NHEtMi4wNDggMC00LjYwOC4zMnptMTkuOTY4IDBxLS45NiAwLTIuMTEyLS4xMjgtMS4wODgtLjE5Mi0xLjk4NC0uMTkydjMuMDcycS45NiAwIDEuODU2LjA2NC44OTYuMDY0IDEuOTg0LjA2NHptLTIzLjY4LTQuNjA4cS43MDQtLjM4NCAxLjcyOC0uNzY4IDEuMDI0LS40NDggMi43NTItLjk2IDIuMzA0LS43NjggNC4zNTItMS4xNTIgMi4xMTItLjM4NCAzLjY0OC0uNTEydi0xMS4zOTJxLTEuMjgtNS45NTItMi42ODgtMTEuMi0xLjQwOC01LjI0OC0zLjkwNC02LjAxNi0yLjg4LS43NjgtNi43Mi0uNDQ4LTMuNzc2LjMyLTQuOTkyLjg5Ni0xLjM0NC43MDQtMy4zOTIgMi42MjQtMS45ODQgMS44NTYtMi43NTIgNC4xNi0uODMyIDIuNDMyLTEuMDg4IDQuMzUyLS4xOTIgMS45Mi0uMzIgMy4xMzYgMCAyLjQ5NiAxLjA4OCA3LjEwNC42NCAyLjMwNCAxLjcyOCAzLjk2OCAxLjE1MiAxLjY2NCAzLjMyOCAzLjM5MiAxLjkyIDEuNjY0IDMuNzEyIDIuMTc2IDEuNzkyLjQ0OCAzLjUyLjY0em0xMy44ODgtMjEuNDRxLjU3Ni0yLjY4OCAxLjIxNi01LjEyLjcwNC0yLjQ5NiAxLjY2NC00LjQxNiAwLS42NC0uNTc2LTEuNzkyLS41MTItLjk2LTEuMTUyLTEuNzkyLS41NzYtLjgzMi0xLjAyNC0xLjc5Mi0xLjYgMi4xNzYtMi4zMDQgMy41ODQtLjU3NiAxLjAyNC0uNzA0IDEuNDcyLS4wNjQuNDQ4LS4wNjQuODMyIDEuNzI4IDMuNTIgMi45NDQgOS4wMjR6bTE2LjI1NiAyNC4xOTJxLjUxMiA1LjUwNCAxLjI4IDEyLjE2aC0zNS41ODRxLjM4NC0zLjMyOC43MDQtNi40NjQuMzItMy4xMzYuNzA0LTUuNjk2LTEuNTM2LS4zMi0zLjA3Mi0uOTYtMS41MzYtLjcwNC0zLjM5Mi0yLjExMi0yLjU2LTIuMTEyLTMuOTA0LTQuMTYtMS4zNDQtMi4wNDgtMi4xMTItNC45MjgtMS4yMTYtNC43MzYtMS4yMTYtOCAuMDY0LTEuMzQ0LjMyLTMuNTIuMzItMi4xNzYgMS40MDgtNC45MjguODk2LTIuODggMy40NTYtNS4yNDggMi41Ni0yLjM2OCA0LjIyNC0zLjA3MiAxLjQ3Mi0uNzY4IDUuOTUyLTEuMjE2IDQuNDgtLjQ0OCA3Ljc0NC40NDggMS41MzYuNjQgMS45ODQgMS4yMTYuNzY4LTEuMzQ0IDEuNzkyLTIuODE2IDEuMDg4LTEuNTM2IDIuMDQ4LTIuODh2LTEuMDg4aC0yLjk0NHYtMy4wNzJoMi45NDR2LTIuODhoMi45NDR2Mi44OGgyLjc1MnYzLjA3MmgtMi43NTJ2MS4wODhxLjg5NiAxLjM0NCAxLjg1NiAyLjgxNiAxLjAyNCAxLjQwOCAxLjc5MiAyLjc1Mi40NDgtLjMyLjg5Ni0uNTc2LjUxMi0uMjU2Ljk2LS41MTIgMy4zMjgtLjg5NiA3Ljc0NC0uNDQ4IDQuNDguNDQ4IDYuMTQ0IDEuMjE2IDEuNDcyLjcwNCA0LjAzMiAzLjA3MiAyLjU2IDIuMzY4IDMuNjQ4IDUuMjQ4Ljg5NiAyLjc1MiAxLjIxNiA0LjkyOC4zMiAyLjE3Ni4zMiAzLjUyLjEyOCAzLjItMS4yMTYgOC0uNzY4IDIuODgtMi4xMTIgNC45MjgtMS4yOCAyLjA0OC0zLjkwNCA0LjE2LTEuOTIgMS41MzYtMy41MiAyLjI0LTEuNi42NC0zLjEzNi44MzJ6bS0xNi4xMjgtLjMyLTEuNzI4IDEuNzI4cS0xLjI4IDEuMzQ0LTEuNDcyIDEuNTM2LjE5Mi4zODQgMS40NzIgMS43MjggMS4zNDQgMS4yOCAxLjcyOCAxLjQ3Mi4wNjQtLjE5MiAxLjM0NC0xLjQ3MmwxLjcyOC0xLjcyOHEtLjM4NC0uMTkyLTEuNzI4LTEuNTM2LTEuMjgtMS4zNDQtMS4zNDQtMS43Mjh6bTEuMjE2LTUuODI0cTEuNiAwIDQuMTYuMjU2dDMuODQuODMybDIuMDQ4IDEuMDI0cTEuMTUyLjU3NiAyLjMwNCAxLjI4IDEuNzI4LS4xMjggMy40NTYtLjU3NiAxLjc5Mi0uNTEyIDMuOTA0LTIuMjQgMy45MDQtMy4yNjQgNC45MjgtNy4zNiAxLjIxNi00LjU0NCAxLjA4OC03LjEwNCAwLTEuMjE2LS4yNTYtMy4xMzYtLjI1Ni0xLjkyLTEuMTUyLTQuMzUyLS44MzItMi4zMDQtMi44OC00LjE2LTIuMDQ4LTEuOTItMy4yNjQtMi42MjQtMS4zNDQtLjU3Ni00Ljk5Mi0uODk2LTMuNjQ4LS4zMi02LjUyOC40NDgtMi41Ni43NjgtMy45NjggNi4wMTYtMS4zNDQgNS4yNDgtMi42ODggMTEuMnptLTE2LjMyLS4xOTItMi4xNzYtLjg5NnEtMi4xMTItLjg5Ni0zLjAwOC0yLjMwNC0xLjM0NC0xLjI4LTIuNjI0LTQuMTYtMS4wODgtMi40MzItMS4yMTYtNi4zMzYtLjI1Ni0yLjA0OC41MTItNC43MzYuNzY4LTIuNjg4IDEuNi0zLjg0IDEuOTItMi42ODggNS44ODgtMy4zOTIgMi4wNDgtLjE5MiA0LjE2LS4wNjQgMi4xNzYuMDY0IDIuODguODMyLjM4NC40NDggMS4wMjQgMi40OTZ0MS4yOCA0LjQ4cS43MDQgMi40MzIgMS4yMTYgNC43MzYuNTEyIDIuMjQuNjQgMy4wNzIuMzIgMS43MjguMjU2IDMuNzEyLS4wNjQgMS45Mi0uMDY0IDMuNTJ6bTMwLjAxNi4zMi0xMC4zMDQtMi43NTJxMC0xLjYtLjEyOC0zLjUyLS4wNjQtMS45ODQuMzItMy45MDQuMDY0LS44MzIuNTc2LTMuMDcydDEuMTUyLTQuNjA4cS42NC0yLjQzMiAxLjI4LTQuNDE2LjcwNC0yLjA0OCAxLjA4OC0yLjQ5Ni43MDQtLjc2OCAyLjg4LS44OTYgMi4yNC0uMTkyIDQuMjI0LjEyOCA0LjA5Ni41MTIgNS44MjQgMy4zOTIuNzY4IDEuMTUyIDEuNTM2IDMuODQuODMyIDIuNjg4LjY0IDQuOC0uMTkyIDMuODQtMS4yMTYgNi4xNDQtLjUxMiAxLjQwOC0xLjM0NCAyLjU2LS44MzIgMS4xNTItMS4yOCAxLjcyOC0uOTYgMS4yOC0zLjEzNiAyLjE3NnptLTI3LjA3MiAxMS41Mi0uNTc2LTMuMDcyLTIuMTc2LjY0LS4xOTIgMy4zOTJ6bTIzLjU1Mi0uMTI4IDMuMDcyLjg5Ni0uMzItMy4yLTIuMTEyLS42NHoiLz48cGF0aCBkPSJtMTkuMjc3IDU3LjI4NnYtMS42MjZsMS4wNDMtLjI5Yy41NzMtLjE2IDEuMDYzLS4yNyAxLjA4OS0uMjQ0LjEzNy4xMzcuNTQ0IDIuNzY1LjQ0MyAyLjg2LS4wNjYuMDY0LS41Ny4yNi0xLjEyLjQzNi0uNTUuMTc3LTEuMTAzLjM2LTEuMjI4LjQwNi0uMTcuMDYzLS4yMjctLjMxOC0uMjI3LTEuNTQyem01LjAxOC0uMjUyYy0uMDQ0LS4xMzktLjEzLS43NTQtLjE5Mi0xLjM2Ni0uMDg5LS44ODYtLjA1Ny0xLjEzNi4xNTUtMS4yMTcuMTQ2LS4wNTYgMS4xNzItLjE2IDIuMjgtLjIzbDIuMDEyLS4xMjd2MS4zNzljMCAuNzU4LS4wNjMgMS40MTctLjE0IDEuNDY1LS4wNzguMDQ4LTEuMDE3LjE0NS0yLjA4OC4yMTctMS41ODMuMTA2LTEuOTYyLjA4NC0yLjAyNy0uMTIxem04LjE4Ny4wMDctMS40NDMtMS40NjggMS41MjUtMS41MzNjLjgzOS0uODQzIDEuNTY3LTEuNTEyIDEuNjItMS40ODYuMDUuMDI1Ljc0My43MjMgMS41MzggMS41NTFsMS40NDYgMS41MDUtMS40NDEgMS40NWMtLjc5My43OTctMS41MjMgMS40NS0xLjYyMiAxLjQ1LS4xIDAtLjgzLS42NjEtMS42MjMtMS40Njl6bTguMTEzLjA2Mi0uNzczLS4wN3YtMi45MzNsMS4zMTkuMTI0YTQ2Ljg4IDQ2Ljg4IDAgMCAxIDIuMDIuMjMyYy42OS4xMDUuNjk5LjExNy41OTIuNzYyLS4wNi4zNi0uMTEuOTYzLS4xMSAxLjMzOGwtLjAwMi42ODEtMS4xMzctLjAzMWEzOC41ODMgMzguNTgzIDAgMCAxIC0xLjkwOS0uMTAyem02LjM1NSAxLjE3OWMtLjk1My0uMjcxLTEuMjk5LS40NDctMS4yMy0uNjI2LjA1My0uMTM4LjE5My0uNzguMzEzLTEuNDI4LjE3LS45MjcuMjc4LTEuMTYuNTAzLTEuMDk2IDEuNzk4LjUxMSAxLjgzMi41MjkgMS44MzIuOTI1IDAgLjIyLjA1Mi45MDIuMTE3IDEuNTE2LjA2NS42MjUuMDQ1IDEuMTEtLjA0NiAxLjEwMi0uMDg5LS4wMDktLjc1OS0uMTg2LTEuNDg4LS4zOTN6bS0uOTQ2LTkuNTI4Yy0yLjkxNy0xLjY0Ny00LjQzOC0yLjA2LTguNTktMi4zMzlsLTEuOTU1LS4xMzF2LTExLjE5bC44MjQtMy41MmMyLjI5NC05LjggMy4yMzktMTIuMjgzIDUuMDcyLTEzLjMyNy45MDMtLjUxNSAxLjI1Mi0uNTk5IDMuNDA5LS44MjQgMS44NzItLjE5NSA1LjE2LjAxNCA3LjMyNi40NjUgMS42MTYuMzM3IDIuNzQ3IDEuMDg2IDQuOTE3IDMuMjU1IDEuODQ0IDEuODQ0IDIuNDg5IDIuOTY1IDMuMjUzIDUuNjU5IDEuMjIyIDQuMzEgMS4wNDEgOC45NDMtLjUzMyAxMy42NTItLjYzNiAxLjkwMy0xLjc4MyAzLjY4OC0zLjM5MiA1LjI4LTIuMTY4IDIuMTQ0LTMuNzU2IDMuMTE4LTUuODMgMy41NzctMi40MzQuNTM4LTIuNTk2LjUxOC00LjUtLjU1N3ptNC44MTEtMi44ODFjMi4xMDQtLjkxOSAyLjk2Ni0xLjU4IDQuMjMtMy4yNDggMS44OTgtMi41MDYgMi43ODgtNC45NCAzLjE0OC04LjYxMy4yMzYtMi40MS4wNTItNC4wMDYtLjc0My02LjQ0LS45NDUtMi44OS0yLjA3LTQuNTYtMy43MjQtNS41My0xLjcwOC0xLjAwMS01LjcyNC0xLjU4LTguMjQtMS4xODctMS42OTQuMjY0LTIuMzAxLjU4Mi0yLjczIDEuNDMtLjg4NyAxLjc0OC0zLjE5NiAxMC4yMjYtMy43NTQgMTMuNzgtLjE5NSAxLjI0Mi0uMjY4IDIuNzQxLS4yMzIgNC43OWwuMDUyIDIuOTggNC45MSAxLjMyNWMyLjcuNzI5IDUuMDcyIDEuMzMgNS4yNzIgMS4zMzVzMS4wMTUtLjI3NSAxLjgxMS0uNjIyem0tMzIuNjI5IDMuNTIzYy0uOTUtLjE5OS0yLjEzNi0uNTUtMi42MzYtLjc4LTEuOTQxLS44OTMtNS4wMDMtMy42OS02LjE2NC01LjYzLTEuMTQtMS45MDUtMi4xOC01Ljg4LTIuNDA3LTkuMjA0LS4xODktMi43NzUuNzA1LTcuNzQyIDEuNzc2LTkuODc3Ljg3OS0xLjc1IDMuMjM1LTQuMTcgNS4xODQtNS4zMjUgMi4wMTMtMS4xOTIgOC43Ny0xLjYzNyAxMS45MzQtLjc4NC4zOS4xMDUgMS4wNzQuNTI2IDEuNTIuOTM3IDEuNTE3IDEuMzk5IDIuMzM2IDMuNyA0LjIzOSAxMS45MmwuOTE4IDMuOTY0djExLjY5NGwtLjY4Mi4xMDRjLTQuMTAyLjYzLTguNzQ4IDEuODktMTAuODEyIDIuOTMzLS40NzIuMjM5LS45MjIuNDI4LTEgLjQyMS0uMDc5LS4wMDctLjkyLS4xNzUtMS44Ny0uMzczem02LjI0Ny00LjYwNGMyLjY4Ni0uNzQ0IDQuOTMtMS4zOTggNC45ODUtMS40NTQuMjEyLS4yMTIuMjU4LTQuODI5LjA2Mi02LjI4NS0uNDE2LTMuMDk3LTIuODk4LTEyLjY3OC0zLjg2NS0xNC45MjctLjMwNi0uNzEtLjUzNy0uOTU1LTEuMjIxLTEuMjkxLS43NjItLjM3NS0xLjEwMi0uNDE2LTMuNDgtLjQxNi0yLjkwNiAwLTMuOTkzLjE5NC01Ljc2OCAxLjAyOC0yLjM1IDEuMTAzLTMuNzUyIDMuMTI2LTQuNzAzIDYuNzkxLS40MzQgMS42NzMtLjQ2MyAyLjAxOC0uMzY3IDQuMzYyLjA2NiAxLjU5My4yNDMgMy4xMTQuNDczIDQuMDY1LjY4MyAyLjgyIDMuMTMzIDYuODAyIDQuODMgNy44NTEuOTc2LjYwMyAzLjc0IDEuNzkgMy45NjggMS43MDUuMTEyLS4wNDEgMi40LS42ODQgNS4wODYtMS40Mjl6bTkuNDk2LTE3LjM3NGMtLjM0Mi0xLjU5LTEuMjgyLTQuNjEzLTEuOTUtNi4yNzItLjUzLTEuMzE4LS43MDgtMS45OTUtLjY0OC0yLjQ2LjA5LS42OTQgMS4yMTktMi44MjkgMi4yNDItNC4yMzdsLjYzOC0uODc4LjU5Ljk3IDEuMTQ4IDEuODc3YzEuMDQ2IDEuNzA2IDEuMDc2IDIuMDM4LjM1MSAzLjg1Ny0uNTg5IDEuNDc4LTEuMzQ0IDQuMDM3LTEuOTc1IDYuNjg5bC0uMjYgMS4wOXoiIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==')} diff --git a/public/piece-css/chessnut.css b/public/piece-css/chessnut.css new file mode 100644 index 0000000000..3c538cb221 --- /dev/null +++ b/public/piece-css/chessnut.css @@ -0,0 +1,12 @@ +.is2d .pawn.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Im00OTcuOSAyNDBjMCA1My42LTQ0IDkzLjktOTguMSA5My45cy05OC4xLTQwLjMtOTguMS05My45IDQ0LTkzLjkgOTguMS05My45YzU0LjIuMSA5OC4xIDQwLjQgOTguMSA5My45em0yOC41IDk3LjZ2NTUuM2MtMzAuMiAzLTQyLjggMTIuMS00Mi44IDI4IDAgNTYuOSAzNiAxMjMuNCAxMDkuMSAxODcuOXY2MC45YzAgMTcuNC04Ny41IDMwLjgtMTkyLjcgMzAuOHMtMTkyLjctMTMuNC0xOTIuNy0zMC44bC0uMS02MC42YzczLjEtNjQuNSAxMDguMS0xMzEuMSAxMDguMS0xODggMC0xNS45LTEzLjYtMjUuMi00My44LTI4LjJ2LTU1LjN6IiBmaWxsPSIjZmZmIiBzdHJva2Utd2lkdGg9IjMwLjI0Ii8+PHBhdGggZD0ibTIwNy4yIDYwOGMwIDE3LjQgODcuNSAzMC4zIDE5Mi43IDMwLjNzMTkyLjYtMTIuOSAxOTIuNi0zMC4yIiBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjE2LjIiLz48cGF0aCBkPSJtMjcyLjYgMzg2LjdoMjUyLjciIGZpbGw9Im5vbmUiIHN0cm9rZS13aWR0aD0iMTQuMDQiLz48L2c+PC9zdmc+')} +.is2d .knight.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik02NDUuMjU0IDY5Mi4yVjI4MC42Yy01Ny4yLTQxLjgtMTQyLjMtODUuOC0xOTYuNi05OC4xLTQyLjYtOS43LTEwMS4zLTIuMS0xNDguNiAxMy4yLTEzLjMtMzQuOS00OC01OC42LTgxLjUtNjAuNCA2LjMgMjkuNiA1LjkgNzQuMyAyNC4zIDk3LjctNyAxNi4yLTMyLjEgNjkuNC00OC43IDExOS4zdjM5LjRjLTEzLjkgNTkuMS0zNC45IDE2Ni4yLTQzLjQgMjEyLjhsMTIwLjkgNTEuNSAyMi40LTU4LjFjMTUuMi0yMi43IDQ1LjctNjAuOSA2NS4xLTc4LjIgMjQuNC0xMC4zIDU1LjgtMjkuNCA2Ni42LTU5LjIgMTQtMzguNCA2LjMtODQuMy0xMC41LTExOS45IDMxIDMwLjIgNTAgNzcgNTAgMTI3LjggMCA2OC4xLTM4LjEgMTQ1LjktMTA0LjcgMjIzLjdoMjg0Ljd6IiBmaWxsPSIjZmZmIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS13aWR0aD0iMjkuMTYiLz48cGF0aCBkPSJNMTc5Ljc1NCA1NzQuOGMxOS40LTEwLjkgMzMuOSAzLjggMjIuNCAyNS4yeiIgc3Ryb2tlLXdpZHRoPSI5LjE2OSIvPjxwYXRoIGQ9Ik0yMzEuNDU0IDM1Ny45Yy02LjkgOS41LS42IDI5LjMgNiAzNC41IDQuNS0uNiAxNC4xLTQuNCAxOC42LThsMjEuNS0yNC45LTQuNS0zLjdjLTguOC0uMS0zMC43LS4xLTQxLjYgMi4xeiIgc3Ryb2tlLXdpZHRoPSIuOTUyIi8+PHBhdGggZD0iTTMyMC4wNTQgMTg2Yy0xMi41LTE3LjktOS45LTQ5LjcgNy03NS4xIDI4LjIgMTQuMyAzOS43IDQ3LjQgMzUuMSA3MC42IiBmaWxsPSIjZmZmIiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIiBzdHJva2Utd2lkdGg9IjIzLjc2Ii8+PC9nPjwvc3ZnPg==')} +.is2d .bishop.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIzOC45IDcwMS44Yy00MS44IDAtNzctMTQuOC0xMDEuOC00Mi44LTIyLjktMjUuOC0zNS41LTYyLjEtMzUuNS0xMDIuMiAwLTU4LjkgNDEuMS03Mi45IDc3LjEtNzguNWwxNS42LTIuNS00LjggMTVjLTYuNSAyMC41LTEwLjIgNDMtMTAuMiA2MS4zIDAgNTQuMyAyNC41IDg4LjEgNjQuMiA4OC4xIDI5LjUgMCA1Ny4yLTI0LjIgNzEuNC02MS4xLTMzLTYuNi00OS41LTE2LjQtNTAuMS0yOS45bC03LjMtNTUuN3YtLjVjMC05LjEgNS45LTE1LjMgMTMuMi0yMC4zLTEuNi00LjQtMy4zLTkuMS01LjEtMTMuOC0xNi42LTQ0LjktMzcuMy0xMDAuOC0zNy4zLTE0My42IDAtNTAuMiAyMi4xLTk1LjEgNjIuMy0xMjYuNSAyMi45LTMyIDY5LjItNjguNSAxMDUuMy05MC42bDUuMS0zLjEgNS4xIDMuMWMzNiAyMiA4Mi4zIDU4LjUgMTA1LjMgOTAuNyA0MC4yIDMxLjQgNjIuMyA3Ni4xIDYyLjMgMTI2IDAgNDMtMjAuNyA5OS40LTM3LjQgMTQ0LjYtMS43IDQuNS0zLjMgOS00LjkgMTMuMiA3LjIgNSAxMy4yIDExLjMgMTMuMiAyMC4zdi42bC03LjIgNTUuNWMtLjUgMTMuNS0xNyAyMy40LTUwIDI5LjkgMTQuMSAzNi45IDQxLjkgNjEuMSA3MS40IDYxLjEgMzkuNSAwIDY0LjItMzMuOCA2NC4yLTg4LjEgMC0xOC41LTMuNy00MC44LTEwLjItNjEuM2wtNC44LTE1IDE1LjYgMi41YzI1LjIgNCA0Mi42IDEwLjggNTQuOSAyMS42IDE0LjkgMTMuMSAyMi4yIDMxLjggMjIuMiA1Ni45IDAgNDAuMS0xMi42IDc2LjQtMzUuNSAxMDIuMi0yNC44IDI4LTU5LjkgNDIuOC0xMDEuOCA0Mi44LTY1LjQgMC0xMTguNi00NS4xLTEzNy40LTExNS44LTguMi4zLTE2LjUuNS0yNC44LjVzLTE2LjYtLjItMjQuOC0uNWMtMTkgNzAuOC03Mi4xIDExNS45LTEzNy41IDExNS45eiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik00MDEuMSAxMDYuNGMzMy41IDIwLjUgODAuNiA1Ni44IDEwMy4yIDg5LjNDNTQwLjIgMjIzLjIgNTY0IDI2NCA1NjQgMzE1YzAgNDguMy0yOC41IDExNy42LTQ0LjQgMTYxLjkgOS43IDUuNCAxNS4yIDEwLjIgMTUuMiAxNi4ybC03LjIgNTUuNGMwIDkuNS0yMSAxNy45LTUzLjEgMjMuMSAxMy4yIDQ0LjcgNDUuOSA3OC40IDg0LjIgNzguNCA0NS43IDAgNzMuOS0zOC45IDczLjktOTcuOCAwLTIwLTQtNDMuMy0xMC43LTY0LjMgNDEuNSA2LjYgNjguOSAyMS45IDY4LjkgNjguOSAwIDc1LTQ1LjYgMTM1LjItMTI3LjUgMTM1LjItNjIgMC0xMTMuNi00My42LTEyOS45LTExNi4xLTEwLjQuNi0yMS4yIDEtMzIuNCAxcy0yMi0uMy0zMi40LTFjLTE2LjIgNzIuNS02OCAxMTYuMS0xMzAgMTE2LjEtODIgMC0xMjcuNS02MC4zLTEyNy41LTEzNS4yIDAtNDcgMjcuNC02Mi40IDY4LjktNjguOS02LjYgMjEtMTAuNyA0NC40LTEwLjcgNjQuMyAwIDU5IDI4LjEgOTcuOCA3My45IDk3LjggMzguMyAwIDcxLjEtMzMuNyA4NC4yLTc4LjQtMzIuMi01LjItNTMuMS0xMy41LTUzLjEtMjNMMjY3IDQ5M2MwLTUuOSA1LjUtMTAuOCAxNS4yLTE2LjItMTUuOC00NC4zLTQ0LjQtMTEzLjMtNDQuNC0xNjEuNiAwLTUxIDIzLjktOTIuMiA1OS43LTExOS43IDIzLTMyLjQgNzAuMS02OC41IDEwMy42LTg5LjFtMC0yMi44bC0xMC4yIDYuM0MzNTcgMTEwLjYgMzA5LjEgMTQ3IDI4My42IDE4MmMtNDEuOSAzMy4zLTY1IDgwLjUtNjUgMTMzLjMgMCA0NC42IDIxIDEwMS4zIDM3LjggMTQ3IC45IDIuNSAxLjcgNC45IDIuNiA3LjEtNiA1LjUtMTEuMyAxMy4yLTExLjMgMjMuN3YxLjNsLjIgMS4zIDcuMSA1NC44Yy4zIDUuNSAyLjYgMTIuOSAxMC4zIDE5LjggNC4xIDMuNyA5LjQgNi44IDE2LjEgOS43IDUuNiAyLjQgMTIuMiA0LjUgMTkuOCA2LjUtNS4zIDEwLjctMTIgMjAuMS0xOS43IDI3LjQtOC4xIDcuOC0yMS4zIDE3LjEtMzguMSAxNy4xLTE2LjEgMC0yOS4xLTYuNC0zOC40LTE5LTEwLjQtMTMuOS0xNS45LTM0LjYtMTUuOS01OS40IDAtMTcuNSAzLjYtMzguOCA5LjctNTguNGw5LjQtMjkuOS0zMSA0LjljLTI3LjEgNC4zLTQ2IDExLjktNTkuNyAyMy45LTE3IDE0LjgtMjUuNSAzNi40LTI1LjUgNjQuMyAwIDIxIDMuMSA0MC44IDkuNSA1OS4xIDYuNSAxOC45IDE2LjEgMzUuNSAyOC41IDQ5LjYgMjYuNyAzMC4xIDY0LjQgNDYgMTA5LjEgNDYgNjcuNiAwIDEyMy00NC44IDE0NC42LTExNS41IDUuOC4yIDExLjcuMiAxNy42LjJzMTEuOC0uMSAxNy42LS4yYzIxLjcgNzAuNiA3NyAxMTUuNSAxNDQuNiAxMTUuNSA0NC43IDAgODIuNC0xNS45IDEwOS4xLTQ2IDEyLjQtMTQgMjItMzAuNyAyOC41LTQ5LjYgNi4zLTE4LjMgOS41LTM4LjEgOS41LTU5LjEgMC0yNy44LTguNS00OS41LTI1LjUtNjQuMy0xMy43LTEyLTMyLjctMTkuNy01OS43LTIzLjlsLTMxLTQuOSA5LjQgMjkuOWM2LjIgMTkuNyA5LjcgNDAuOSA5LjcgNTguNCAwIDI0LjgtNS41IDQ1LjUtMTUuOSA1OS40LTkuNCAxMi42LTIyLjQgMTktMzguNCAxOS0xNi44IDAtMzAtOS4zLTM4LjEtMTcuMS03LjctNy4zLTE0LjQtMTYuNy0xOS43LTI3LjUgNy42LTEuOSAxNC4xLTQuMSAxOS44LTYuNSA2LjctMi45IDEyLTYgMTYuMS05LjcgNy43LTYuOSA5LjgtMTQuMyAxMC4yLTE5LjhsNy4xLTU0LjUuMS0xLjN2LTEuNGMwLTEwLjUtNS4zLTE4LjEtMTEuMy0yMy43LjgtMi4yIDEuNi00LjMgMi40LTYuNSAxNy00NiAzOC0xMDMuMSAzOC0xNDggMC01Mi42LTIzLTk5LjctNjUtMTMyLjgtMTEuNC0xNS43LTI4LTMyLjYtNDkuNC01MC40LTE4LjItMTUuMi0zOC44LTMwLTU4LTQxLjh6Ii8+PGcgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik01MjcuOCA1NDguNWw3LjItNTUuN2MwLTE5LjctNTguOS0zNS4yLTEzMy45LTM1LjItNzUuMSAwLTEzMy45IDE1LjctMTMzLjkgMzUuMmw3LjIgNTUuNyIgZmlsbD0ibm9uZSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2Utd2lkdGg9IjE2LjkwNiIvPjxlbGxpcHNlIGN4PSI0MDEuMSIgY3k9IjU0OC41IiBmaWxsPSJub25lIiByeD0iMTI2LjciIHJ5PSIyOC40IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS13aWR0aD0iMTUuOTExIi8+PHBhdGggZD0iTTMzMy45IDUyNy4xYzAgNjQuNC00MC40IDEyMS45LTkwLjUgMTIxLjktNDUuNyAwLTczLjktMzguOS03My45LTk3LjggMC0yMCA0LTQzLjMgMTAuNy02NC4zLTQxLjUgNi42LTY4LjkgMjEuOS02OC45IDY4LjkgMCA3NSA0NS42IDEzNS4yIDEyNy41IDEzNS4yIDc0LjUgMCAxMzQuMi02My4yIDEzNS4yLTE2My42bTk0LjQtLjNjMCA2NC40IDQwLjQgMTIxLjkgOTAuNSAxMjEuOSA0NS43IDAgNzMuOS0zOC45IDczLjktOTcuOCAwLTIwLTQtNDMuMy0xMC43LTY0LjMgNDEuNSA2LjYgNjguOSAyMS45IDY4LjkgNjguOSAwIDc1LTQ1LjYgMTM1LjItMTI3LjUgMTM1LjItNzQuNSAwLTEzNC4yLTYzLjItMTM1LjItMTYzLjYiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMTguMzYiLz48ZyBmaWxsPSJub25lIj48cGF0aCBkPSJNNTE5LjggNDc2LjJjMTUuOC00NC43IDQ0LjQtMTEzLjMgNDQuNC0xNjEuNiAwLTUxLTIzLjktOTIuNC01OS43LTExOS45LTIyLjctMzIuNC02OS45LTY5LjItMTAzLjItODkuNy0zMy41IDIwLjUtODAuNiA1Ny4yLTEwMy4yIDg5LjctMzUuOSAyNy40LTU5LjcgNjguOC01OS43IDExOS44IDAgNDguMyAyOC42IDExNyA0NC40IDE2MS43IiBzdHJva2Utd2lkdGg9IjIwLjUyIi8+PHBhdGggZD0iTTQwMS4xIDIxMS4ydjE4NC43bS03MC4yLTk0aDE0MC40IiBzdHJva2Utd2lkdGg9IjE5LjQ0Ii8+PC9nPjwvZz48L3N2Zz4=')} +.is2d .rook.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTQwMC40IDcwOC4zYy01Ny4xIDAtMTEwLjgtNS44LTE1MS4yLTE2LjUtNDUuNS0xMi02OC41LTI4LjQtNjguNS00OC42VjU4MmMwLTI4LjQgNDQuMS00Ni4yIDc0LjctNTUuM2w4LjEtMTcyLjRjLTMuMi0yLjYtNS42LTUuMy03LjMtOC4xbC0uMi0uMy0yNC43LTUyLjhjLTE5LjMtOS41LTE5LjMtMTktMTkuMy0yMi4yVjE0NS4zaDc0LjV2NTAuOGg0My4ydi01MC4zbDEzNy4yLjF2NTAuMkg1MTB2LTUwLjhoNzUuNnYxMjUuNGMwIDcuOC00LjIgMTQuNS0xMyAxOS45bC0yNCA1NS40LS40LjhjLTIuMSAzLjEtNSA2LTguNSA4LjZsNy42IDE3MC45YzIxLjEgNiAzOC44IDEzLjUgNTEuNSAyMS42IDE2LjUgMTAuNSAyNC44IDIxLjkgMjQuOCAzNC4xIDAgLjggMCAxLjYtLjEgMi41bC0uMSA1OC42YzAgMjAuMi0yMy40IDM2LjYtNjkuNiA0OC42LTQwLjkgMTAuNy05NS41IDE2LjYtMTUzLjQgMTYuNnoiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNNTc2IDE1NXYxMTUuN2MwIDQuNS0zLjIgOS0xMC45IDEzLjFsLTI0LjkgNTcuN2MtMi4yIDMuMi01LjYgNi4yLTEwLjQgOUw1MzggNTM0YzQ3LjIgMTIuNSA3NiAzMC44IDc2IDQ4LjIgMCAuNiAwIDEuMy0uMSAxLjlsLS4xIDU5LjNjMCAzMC42LTk1IDU1LjQtMjEzLjMgNTUuNC0xMTYuNiAwLTIxMC0yNC43LTIxMC01NS40di02MS4yYzAtMTcuMiAyOC4yLTM1LjMgNzQuNC00Ny44bDguNi0xODQuN2MtNC4xLTIuNi03LjItNS4zLTguOS04LjFsLTI2LTU1LjdjLTEwLjQtNC41LTE2LjgtOS42LTE2LjgtMTVWMTU1SDI3N3Y1MC44aDYyLjZ2LTUwLjNsMTE3LjcuMXY1MC4ySDUyMFYxNTV6bTE5LjUtMTkuNGgtOTUuMXY1MC43aC0yMy44di01MC4yaC0xOS40bC0xMTcuNS0uMUgzMjB2NTAuM2gtMjMuOHYtNTAuN2gtOTMuOXYxMzUuMWMwIDE1LjQgMTIuNSAyNC42IDIxLjYgMjkuNWwyMy4xIDQ5LjQuMy44LjQuOGMxLjUgMi42IDMuNSA1LjEgNS44IDcuNWwtNy42IDE2MC44Yy0xOC43IDUuOS0zNC4yIDEyLjktNDYuMiAyMC41LTguMyA1LjMtMTQuOSAxMS4xLTE5LjUgMTcuMS02LjIgNy45LTkuMyAxNi4yLTkuMyAyNC45djYxLjNjMCAxOC4zIDEzLjkgMzAuOCAyNS41IDM4IDEyLjIgNy43IDI5LjEgMTQuNCA1MC4yIDIwIDQxLjEgMTAuOSA5NS43IDE2LjggMTUzLjcgMTYuOCA1OC44IDAgMTE0LTUuOSAxNTUuOC0xNi44IDIxLjQtNS42IDM4LjYtMTIuMyA1MC45LTE5LjkgMTEuOS03LjMgMjUuOS0xOS45IDI1LjktMzguMWwuMS01OC4yYy4xLTEuMS4xLTIuMS4xLTMgMC04LjctMy4xLTE3LjMtOS40LTI1LjItNC44LTYtMTEuNC0xMS44LTE5LjktMTcuMi0xMi4zLTcuOC0yOC4yLTE0LjctNDcuMy0yMC42bC03LTE1OS4xYzIuNy0yLjQgNS01IDYuOC03LjhsMS0xLjQuNi0xLjYgMjIuNS01Mi4xYzEyLjMtOC43IDE0LjktMTguOSAxNC45LTI2LjRWMTM1LjZ6Ii8+PGcgZmlsbD0iI2ZmZiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0xOTEgNTgxLjZ2NjEuNmMwIDMwLjYgOTMuMSA1NS40IDIwOS42IDU1LjQgMTE4LjMgMCAyMTMuMi0yNC44IDIxMy4yLTU1LjRsLS4zLTYxLjMiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxOC4zNiIvPjxwYXRoIGQ9Ik02MTMuOSA1ODJjMCAzMC42LTk0LjUgNTUuNC0yMTEuMSA1NS40UzE5MS43IDYxMi42IDE5MS43IDU4MnM4Ny41LTY0IDIxMS4xLTY0YzEyMS42LS4xIDIxMS4xIDMzLjMgMjExLjEgNjR6IiBzdHJva2Utd2lkdGg9IjIxLjYiLz48cGF0aCBkPSJNMjc1LjggMjYwLjlsLTEwLjUgMjgwLjZjMCAxOS43IDYyLjEgMzQuMSAxMzYuOCAzNC4xIDc0LjggMCAxMzYuMS0xNC40IDEzNi4xLTMzLjlsLTE0LjktMjgwLjh6IiBzdHJva2Utd2lkdGg9IjE1LjEyIi8+PHBhdGggZD0iTTIzMS4zIDI2OC4xbDMzLjggNzMuMWM5LjUgMTYuNSA2MS42IDI4LjUgMTM3LjYgMjguNXMxMjYuNC0xMS43IDEzNy42LTI4LjVsMzIuOC03My4xIiBzdHJva2Utd2lkdGg9IjE1LjEyIi8+PHBhdGggZD0iTTUyMiAxNTR2NTAuOGgtNjMuN3YtNDkuMWwtMTE2LjYtLjF2NDkuMkgyNzhWMTU0aC01NS4xdjExNi43YzAgMjAuMSA4My4xIDM2LjQgMTc4LjUgMzYuNCA5NS41IDAgMTc2LjgtMTYuMyAxNzYuOC0zNi40VjE1NHoiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMTkuNDQiLz48L2c+PC9zdmc+')} +.is2d .queen.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0iI2ZmZiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik00MDEuMSA3MDQuNGMtNjIgMC0xMjAuNS01LjUtMTY0LjgtMTUuNC00OS42LTExLjEtNzQuMS0yNS44LTc1LTQ0LjdsLTEwLjItNTR2LS45YzAtNS40IDEuNi0xMy4yIDguNi0yMS40LTgtNDYuNS0yNS45LTEyNS4yLTQ0LjYtMTk1LjUtMTguNC02LjktMzAuOC0yNC41LTMwLjgtNDQuNiAwLTI2LjQgMjEuNC00Ny43IDQ3LjctNDcuN3M0Ny43IDIxLjQgNDcuNyA0Ny43YzAgMTEuMS0zLjcgMjEuNS0xMC42IDI5LjlDMTkwLjIgNDI0LjkgMjE2IDQ5NC41IDIzNCA1MzNsNS4zLTEuM2MtLjUtNTUuMy05LjEtMTY0LjMtMjAuNi0yNjEuNi0xOC42LTgtMzEtMjYuNi0zMS00Ny4xIDAtMjguMyAyMy01MS4zIDUxLjMtNTEuM3M1MS4zIDIzIDUxLjMgNTEuM2MwIDEzLjgtNS40IDI2LjctMTUgMzYuMyAxNy45IDkzLjUgNDcuNyAyMTEuNiA2NS4zIDI1OC45bDUuNC0uM2M4LjYtNjYgMTkuNC0xODQuNSAyNC42LTI5NC41LTE0LjktMTAtMjMuOC0yNi42LTIzLjgtNDQuNiAwLTI5LjggMjQuMi01NCA1NC01NHM1NCAyNC4yIDU0IDU0YzAgMTgtOC45IDM0LjYtMjMuNSA0NC42IDUuMiAxMTAuMSAxNiAyMjguNSAyNC42IDI5NC41bDUuNC4zYzE3LjYtNDcuMyA0Ny40LTE2NS4zIDY1LjMtMjU4LjktOS42LTkuNi0xNS0yMi41LTE1LTM2LjMgMC0yOC4zIDIzLTUxLjMgNTEuMy01MS4zczUxLjMgMjMgNTEuMyA1MS4zYzAgMjAuNi0xMi40IDM5LjEtMzEgNDcuMS0xMS42IDk3LjMtMjAuMiAyMDYuMy0yMC42IDI2MS42bDUuMyAxLjNjMTgtMzguNCA0My44LTEwOC4xIDY0LjktMTc1LjItNi45LTguNC0xMC42LTE4LjktMTAuNi0yOS45IDAtMjYuNCAyMS40LTQ3LjcgNDcuNy00Ny43czQ3LjcgMjEuNCA0Ny43IDQ3LjdjMCAyMC4xLTEyLjQgMzcuNy0zMC44IDQ0LjYtMTguNyA3MC4zLTM2LjUgMTQ4LjktNDQuNiAxOTUuNSA1LjcgNi43IDguNiAxMy44IDguNiAyMS4zdi45bC0xMC4zIDU0LjNjLTEuMiAxOC45LTI1LjcgMzMuNS03NSA0NC42LTQzLjggOS44LTEwMi4zIDE1LjMtMTY0LjQgMTUuM3ptLTE4OS40LTkwLjdjMS40IDMgMTMuNyAxMi40IDU0LjYgMjAuMyAzNi41IDcgODQuMiAxMSAxMzQuNiAxMSA1MC4zIDAgOTguMi0zLjkgMTM0LjYtMTEgNDAuOS04IDUzLjQtMTcuMyA1NC42LTIwLjMtMS40LTMtMTMuNy0xMi40LTU0LjYtMjAuMy0zNi41LTctODQuMi0xMS0xMzQuNi0xMS01MC4zIDAtOTguMiAzLjktMTM0LjYgMTEtNDAuOCA3LjktNTMuMSAxNy4zLTU0LjYgMjAuM3oiIHN0cm9rZS13aWR0aD0iMjAuNTIiLz48cGF0aCBkPSJNNTkyLjkgNjA3LjZjLTQxLjggMTMuOC0xMTIuMyAyMy4yLTE5MS44IDIzLjItODAuNCAwLTE0OC45LTkuNS0xOTAuNi0yMy41QzE5NyA2MTAuOCAxNzEgNjI4LjQgMTcxIDY0M2MwIDI4LjUgMTAzIDUxLjYgMjMwIDUxLjZzMjMwLTIzLjEgMjMwLTUxLjZjLjEtMTQuMi0yNC40LTMxLjctMzguMS0zNS40eiIgc3Ryb2tlLXdpZHRoPSIxNi4yIi8+PHBhdGggZD0iTTQwMS4xIDU5MS40YzEyNy4xIDAgMjMwLjEgMjMuMSAyMzAuMSA1MS42bDEwLjItNjAuM2MwLTYuMy0zLjItMTIuMy05LjQtMTguMSA3LjUtNDQuOSAyNi4xLTEyMS45IDQ3LTE5OS45IDE2LjYtNCAyOS4xLTE5IDI5LjEtMzYuOSAwLTIxLTE3LTM4LTM4LTM4LTIxLjEgMC0zOCAxNy0zOCAzOCAwIDEwLjggNC41IDIwLjYgMTEuOCAyNy41LTIwLjggNjctNTAuMSAxNDEuNC03MC40IDE4Mi40bC0yMC40LTQuOWMtLjMtNTQuMiA5LjItMTY3LjggMjEuNS0yNjkuOSAxNy40LTUgMzAuMi0yMSAzMC4yLTQwIDAtMjMtMTguNi00MS42LTQxLjYtNDEuNlM1MjEuNSAyMDAgNTIxLjUgMjIzYzAgMTMuMyA2LjMgMjUuMSAxNS45IDMyLjctMTggOTUuOC01MS4yIDIyMS40LTY5LjQgMjY2LjFsLTIwLjQtMS4zYy05LjEtNjYuNS0yMC44LTE4OC42LTI2LTMwMi42IDE0LjEtNy41IDIzLjgtMjIuMSAyMy44LTM5LjIgMC0yNC40LTE5LjktNDQuMy00NC4zLTQ0LjNzLTQ0LjMgMTkuOS00NC4zIDQ0LjNjMCAxNy4xIDkuNiAzMS45IDIzLjggMzkuMi01LjEgMTE0LTE2LjggMjM2LjEtMjYgMzAyLjZsLTIwLjQgMS4zYy0xOC4xLTQ0LjctNTEuNC0xNzAuMy02OS40LTI2Ni4xIDkuNy03LjYgMTUuOS0xOS40IDE1LjktMzIuNyAwLTIzLTE4LjYtNDEuNi00MS42LTQxLjZTMTk3LjMgMjAwIDE5Ny4zIDIyM2MwIDE5IDEyLjcgMzUgMzAuMiA0MCAxMi4zIDEwMiAyMS44IDIxNS41IDIxLjUgMjY5LjhsLTIwLjQgNC45Yy0yMC4zLTQxLjEtNDkuNy0xMTUuNS03MC40LTE4Mi40IDcuMi02LjkgMTEuOC0xNi42IDExLjgtMjcuNSAwLTIxLTE3LTM4LTM4LTM4LTIxLjEgMC0zOCAxNy0zOCAzOCAwIDE3LjkgMTIuNCAzMi45IDI5LjEgMzYuOSAyMC44IDc4IDM5LjUgMTU1IDQ3IDE5OS45LTYgNS43LTkuNCAxMS44LTkuNCAxOC4xbDEwLjIgNjAuM2MwLTI4LjUgMTAzLjEtNTEuNiAyMzAuMi01MS42eiIgc3Ryb2tlLXdpZHRoPSIxNy4yOCIvPjwvZz48Y2lyY2xlIGN4PSI0MDEuMSIgY3k9IjExMi45IiByPSIyNS45Ii8+PGNpcmNsZSBjeD0iMjI2LjEiIGN5PSIxNjQuOCIgcj0iMjMiLz48Y2lyY2xlIGN4PSIxMTQuOSIgY3k9IjI3My44IiByPSIyMi40Ii8+PGNpcmNsZSBjeD0iNTc2IiBjeT0iMTY0LjgiIHI9IjIzIi8+PGNpcmNsZSBjeD0iNjg4LjQiIGN5PSIyNzMuOCIgcj0iMjIuNCIvPjwvc3ZnPg==')} +.is2d .king.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTQwNS4zIDcwMGMtNTkuOCAwLTExNi4xLTUuMy0xNTguNy0xNC44LTQ3LjQtMTAuNi03MS4xLTI0LjYtNzIuMS00Mi44TDE1OC4xIDU3NnYtMS4xYzAtOS4xIDUuMi0xOCAxNS4yLTI2LjUtNi4yLTIxLjktMjEuNi00NS41LTM2LjYtNjguNC0xOC40LTI4LTM1LjctNTQuNC0zNS43LTc3LjcgMC0yNS41IDE4LjQtNDEuNCA0Ny44LTQxLjRoMS4zYzIuMiAwIDQuNS4xIDcgLjEgNiAuMSAxMi45LjIgMTkuMy4yLTUuNC0yNi43LTMuOC00NS45IDUtNTkuOSAxMy4zLTIxLjUgMzYuOS0yNCA1My42LTI0IDE0LjEgMCAyOS44IDIuMSA0Ni40IDQuNCAxLjgtMTYuMyA3LjUtMjguNSAxNy4yLTM2LjkgNy44LTYuOCAxNy0xMC4zIDI3LTEwLjMgMjEuMyAwIDQyLjIgMTQuOSA2MC44IDI4IDcgNSAxMy42IDkuNyAxOSAxMi41IDUuNC0yLjkgMTIuMS03LjYgMTktMTIuNSAxOC41LTEzLjEgMzkuNS0yOCA2MC43LTI4IDEwLjIgMCAxOS4yIDMuNSAyNyAxMC4zIDkuNiA4LjQgMTUuMyAyMC41IDE3LjEgMzYuOSAxNi42LTIuMyAzMi4zLTQuNCA0Ni40LTQuNCAxNi42IDAgNDAuMyAyLjUgNTMuNiAyNCA4LjYgMTQgMTAuMyAzMy4zIDQuOSA2MCA2LjYgMCAxMy42LS4xIDE5LjgtLjIgMi4zIDAgNC40LS4xIDYuNS0uMWgxLjNjMjkuNSAwIDQ3LjEgMTUuNCA0Ny4xIDQxLjQgMCAyMy4yLTE3LjYgNDkuNy0zNi4zIDc3LjctMTUuMiAyMi44LTMwLjggNDYuMy0zNyA2OC4xIDEwLjcgOC4yIDE2LjEgMTcuMyAxNi4xIDI2Ljh2MS4xbC0xNS44IDY3LjJjLTEuNiAxNy45LTI1LjUgMzEuOS03Mi44IDQyLjMtNDIuMyA5LjItOTguNCAxNC40LTE1Ny43IDE0LjR6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTMyNS42IDI0My44YzI4LjIgMCA2MC40IDMzLjYgNzkuOCA0MS41IDE5LjQtOCA1MS42LTQxLjUgNzkuOC00MS41IDcuMyAwIDE0LjUgMi4zIDIxLjEgOCAxMC4yIDguOSAxNC4zIDIyLjkgMTQuNiA0MC40IDIwLTIuOCAzOC44LTUuNyA1NS01LjcgMjAuMiAwIDM2LjQgNC41IDQ1LjggMTkuN3M3LjkgMzggMS4yIDY0LjNjMi41IDAgNS4xLjEgNy44LjEgMTAuMyAwIDIxLjctLjIgMzAuMS0uM2gxLjJjMjEuNCAwIDM3LjkgOS4yIDM3LjkgMzIuMiAwIDM5LjEtNjAuOSA5NS43LTczLjkgMTQ2Ljd2My4zYzEwLjggNi45IDE2LjUgMTQuNSAxNi41IDIyLjVsLTE1LjYgNjYuOWMtMS4zIDI3LjItMTAwIDQ5LjEtMjIxLjUgNDkuMS0xMjIuMyAwLTIyMS41LTIyLjItMjIxLjUtNDkuN0wxNjcuNiA1NzVjMC03LjkgNS44LTE1LjYgMTUuNi0yMi41di0zLjZjLTExLjktNTEtNzIuOC0xMDcuNi03Mi44LTE0Ni43IDAtMjMgMTcuMy0zMi4yIDM4LjctMzIuMmgxLjJjOC41LjEgMjAuMy40IDMwLjYuNCAyLjYgMCA1LjEgMCA3LjUtLjEtNi43LTI2LjQtOC4xLTQ5LjEgMS4zLTY0LjMgOS40LTE1LjEgMjUuNS0xOS43IDQ1LjgtMTkuNyAxNi4yIDAgMzUgMi45IDU1IDUuNy4zLTE3LjUgNC40LTMxLjYgMTQuNi00MC40IDYtNS41IDEzLjEtNy44IDIwLjUtNy44bTAtMTguM2MtMTIuNCAwLTIzLjUgNC4yLTMzIDEyLjUtOS40IDguMS0xNS42IDE5LjMtMTguNyAzMy41LTEzLjctMS44LTI2LjctMy4yLTM4LjktMy4yLTEzLjMgMC0yNC4zIDEuNy0zMy43IDUuNC0xMS45IDQuNi0yMS4yIDEyLjMtMjcuOCAyMi45LTguNiAxNC0xMS4zIDMyLTguMSA1NS41LTIuOCAwLTUuNi0uMS04LjItLjEtMi41IDAtNC45LS4xLTctLjFoLTEuNGMtMTUuMiAwLTI4LjUgMy44LTM4LjIgMTEtOC41IDYuNC0xOC44IDE4LjQtMTguOCAzOS40IDAgMjYgMTguMSA1My42IDM3LjMgODIuNyAxMy40IDIwLjQgMjcuMyA0MS40IDM0IDYwLjUtOS4yIDkuMi0xMy42IDE5LTEzLjYgMjkuNHYyLjNsLjMgMi4yIDE1LjggNjQuNmMxLjEgMTIuOSAxMC4yIDI0IDI3IDMyLjggMTIuNiA2LjcgMzAuMSAxMi41IDUyLjEgMTcuNSA0My4xIDkuNiAxMDAuMiAxNSAxNjAuNiAxNSA2MCAwIDExNi43LTUuMyAxNTkuNy0xNC44IDIxLjgtNC45IDM5LjQtMTAuNyA1Mi4xLTE3LjMgMTctOC45IDI2LjQtMTkuOCAyNy44LTMyLjVsMTUuMS02NS42LjMtMi4xdi0yLjJjMC0xMC44LTQuOC0yMC43LTE0LjQtMjkuOCA2LjgtMTkgMjAuNy0zOS45IDM0LjItNjAgMTkuNC0yOS4yIDM3LjgtNTYuNyAzNy44LTgyLjcgMC0yMS4xLTkuOC0zMy0xOC4xLTM5LjMtOS44LTcuNS0yMi42LTExLjItMzgtMTEuMmgtMS40Yy0yLjEgMC00LjIuMS02LjUuMS0yLjggMC01LjcuMS04LjcuMSAzLjMtMjMuNS42LTQxLjYtOC01NS41LTYuNi0xMC42LTE1LjktMTguMy0yNy44LTIyLjktOS4zLTMuNy0yMC4zLTUuNC0zMy42LTUuNC0xMi4yIDAtMjUuMiAxLjQtMzguOSAzLjItMy4xLTE0LjEtOS4zLTI1LjQtMTguNy0zMy41LTkuNS04LjMtMjAuNi0xMi41LTMzLTEyLjUtMjQuMiAwLTQ3LjQgMTYuNC02Ni4xIDI5LjctNC44IDMuMy05LjYgNi44LTEzLjcgOS40LTQuMS0yLjYtOS02LTEzLjctOS40LTE4LjctMTMuMi00MS45LTI5LjYtNjYuMS0yOS42eiIvPjxnIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIj48ZyBmaWxsPSJub25lIiBzdHJva2UtbGluZWNhcD0icm91bmQiPjxnIHN0cm9rZS13aWR0aD0iMTguMzYiPjxwYXRoIGQ9Ik0xODcuNCAzNzAuNGMtMTEuOS4zLTI1LjktLjEtMzcuNS0uMy0yMS45LS4zLTM5LjQgOC43LTM5LjQgMzIuMiAwIDM5LjEgNjAuNiA5NS43IDczLjMgMTQ2LjciLz48cGF0aCBkPSJNMjg5LjUgMjkyLjRjLTQ1LjYtNi4zLTgzLjMtMTMuOC0xMDAuMyAxMy43LTI3IDQzLjYgMzUuNiAxNTAuNyA1NS4xIDIyMi40Ii8+PHBhdGggZD0iTTQwNC4zIDI4NS43Yy0yNC4zLTktNjcuOS02MS43LTk5LjgtMzMuOS00My42IDM3LjkgMjIuOSAxNzMuOSAzOC4xIDI2MC41bTI4MC43LTE0MS45YzExLjkuMyAyNS45LS4xIDM3LjUtLjMgMjEuOS0uMyAzOS40IDguNyAzOS40IDMyLjIgMCAzOS4xLTYwLjYgOTUuNy03My4zIDE0Ni43Ii8+PHBhdGggZD0iTTUyMS4zIDI5Mi40YzQ1LjYtNi4zIDgzLjMtMTMuOCAxMDAuMyAxMy43IDI3IDQzLjYtMzUuNiAxNTAuNy01NS4xIDIyMi40Ii8+PHBhdGggZD0iTTQwNi41IDI4NS43YzI0LjMtOSA2Ny45LTYxLjcgOTkuOC0zMy45IDQzLjYgMzcuOS0yMi45IDE3My45LTM4LjEgMjYwLjUiLz48L2c+PHBhdGggZD0iTTQwNS40IDI3MS43djE4NC41IiBzdHJva2Utd2lkdGg9IjE1LjEyIi8+PC9nPjxwYXRoIGQ9Ik02MzIuOSA1NTIuNWwyNy44LTY4LjhjLTExLjEgMTQuNi0yNC44IDE2LjgtMzMuOSAxNC4zLTI3LTgtMjYuNS00MC42LTI0LjQtNjYuNS0xNi40IDI5LjUtMzkuMyA0NC43LTYzLjkgMzkuNS0yNC45LTUuMy00MC00MC41LTM5LTY4LjYtMTcuNSAzNS42LTQ5LjQgNTQuMS05NC4xIDU0LjFzLTc2LjYtMTguNS05NC4xLTU0LjFjMS4xIDI4LjEtMTQgNjMuMy0zOSA2OC42LTI0LjYgNS4yLTQ3LjQtMTAtNjMuOS0zOS41IDEuOSAyNS45IDIuNiA1OC41LTI0LjQgNjYuNS05LjEgMi43LTIyLjkuMy0zMy45LTE0LjNsMjcuOCA2OC44IiBmaWxsPSIjZmZmIiBzdHJva2Utd2lkdGg9IjE4LjM2Ii8+PGcgZmlsbD0ibm9uZSI+PGcgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2Utd2lkdGg9IjIxLjYiPjxwYXRoIGQ9Ik0xNjcuOSA1NzQuOGMwLTM0LjMgMTA2LjMtNjEuNyAyMzcuNC02MS43czIzNy40IDI3LjMgMjM3LjQgNjEuN20tNDc1IDEuOWwxNi4yIDY1bTQ1OS4yLTY1bC0xNi4yIDY1Ii8+PGVsbGlwc2UgY3g9IjQwNS40IiBjeT0iNjQxLjEiIHJ4PSIyMjEuNCIgcnk9IjQ5LjciLz48L2c+PHBhdGggZD0iTTQwNC4zIDk0LjZ2MTg5bS02MS41LTEyNC4ySDQ2OCIgc3Ryb2tlLXdpZHRoPSIzMC4yNCIvPjwvZz48L2c+PC9zdmc+')} +.is2d .pawn.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTQ4OS4zIDQxOC4zYy4xLTE3IDEyLTI1LjEgNjUuMS0yOS45VjMzMGgtOTAuN2MzMi0xOS41IDUyLjgtNTMuNSA1Mi44LTkyLjkgMC02MS45LTUxLjMtMTEwLjQtMTE2LjctMTEwLjRzLTExNi43IDQ4LjUtMTE2LjcgMTEwLjRjMCAzOS40IDIwLjcgNzMuMyA1Mi44IDkyLjloLTkxLjR2NTguNGM1My43IDQuOCA2NS4yIDEyLjkgNjUuMiAyOS44IDAgNjAuNy0zNy42IDEzMS41LTExNS41IDIwMC4xbC4xIDY0YzAgMTguNiA5My4yIDMyIDIwNS4zIDMyczIwNS40LTEzLjUgMjA1LjQtMzJsLjEtNjRjLTc3LjktNjguNS0xMTUuOC0xMzkuNC0xMTUuOC0yMDB6Ii8+PHBhdGggZD0iTTIzMi4xIDYyNy4yYzAgMTMuNyA3NiAyNS43IDE2Ny42IDI1LjcgOTEuNSAwIDE2Ny40LTExIDE2Ny40LTI0LjYiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2YyZjJmMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iMTkuNDQiLz48cGF0aCBkPSJNNDAwLjkgMTUwLjNjLTI0LS4yLTQ3LjYgOC42LTY2LjMgMjcuMy0yNi43IDI2LjgtMzIuNSA2My4yLTIwIDk1LjMiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2YyZjJmMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iMTYuMiIvPjwvc3ZnPg==')} +.is2d .knight.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTEzNy44IDYwNS45YzgtNDMgMjguOS0xNTEgNDMuMy0yMTJ2LTQwbC41LTEuNmMxMy45LTQxLjkgMzMuNi04NS41IDQ0LjEtMTA5IDEtMi4yIDEuOC00IDIuNi01LjctMTEuOS0xOS0xNS4yLTQ1LjctMTguNC02OS40LTEuMy05LjktMi41LTE5LjMtNC4yLTI3LjNsLTIuOS0xMy43IDE0IC44YzMzLjcgMS43IDY2LjEgMjIuNCA4My42IDUxLjktNS45LTIxLjYtLjktNDkuNCAxNC40LTcyLjFsNS44LTguNyA5LjQgNC44YzI3LjUgMTMuOSA0MS44IDQzLjIgNDIuNiA2OC43IDEwLjctMS4xIDIxLjItMS42IDMxLjEtMS42IDE2LjcgMCAzMiAxLjUgNDUuMyA0LjUgNTMgMTIgMTM5LjQgNTUgMjAwLjkgOTkuOWw0LjQgMy4ydjQyOC4zSDMzNC44TDM1MCA2ODljNjYuNy03OC4xIDEwMi4xLTE1MyAxMDIuMS0yMTYuOSAwLTIyLTMuOS00My43LTExLjEtNjMuNSAxLjQgMjEuMS0xIDQxLjMtNy41IDU5LjEtMTIuNiAzNC45LTQ5LjEgNTUuMy03MC44IDY0LjctMTcuNyAxNi4yLTQ2IDUxLjItNjEuMyA3NGwtMjUuOSA2Ny40LTEzOS4xLTU5LjN6Ii8+PHBhdGggZD0iTTE3Ny40IDU3OC4xYzE5LjQtMTAuOSAzMy45IDMuOCAyMi40IDI1LjJ6bTUxLjYtMjE3Yy02LjkgOS41LS42IDI5LjMgNiAzNC41IDQuNS0uNiAxNC4xLTQuNCAxOC42LThsMjEuNS0yNC45LTQuNS0zLjdjLTguNy0uMS0zMC43LS4xLTQxLjYgMi4xem05MC44LTE2MC44bC42LTIuOWMzMS4xLTUuMSA3My02IDk3LjMtNiA0NS43IDAgMTQ4IDU4LjggMjA5LjUgMTA0LjF2NTUuMWMtNDUtNDMuNS0xNDEuMi0xMTguOC0xOTYuMy0xMzUuOC0zNy4yLTExLjUtNzQuMS0xNS43LTExMS4xLTE0LjV6IiBmaWxsPSIjZjJmMmYyIi8+PC9zdmc+')} +.is2d .bishop.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIzNy44IDcwMi40Yy00MiAwLTc3LjMtMTQuOS0xMDIuMi00My0yMy0yNS45LTM1LjYtNjIuMy0zNS42LTEwMi41IDAtNTkuMiA0MS41LTczLjMgNzcuNS03OS4xbDE2LjQtMi42LTUgMTUuOGMtNi41IDIwLjUtMTAuMiA0Mi45LTEwLjIgNjEuMiAwIDU0IDI0LjQgODcuNiA2My42IDg3LjYgMjkuMiAwIDU2LjYtMjMuOCA3MC43LTYwLjItMTEuOC0yLjQtMjEuNS01LjItMjkuMS04LjQtMTMuNC01LjYtMjAuMS0xMy0yMC41LTIxLjhsLTctNTUuN3YtLjZjMC05LjEgNS42LTE1LjYgMTIuOS0yMC41LTEuNi00LjMtMy4zLTguOS01LjEtMTMuNS0xNi42LTQ0LjktMzcuMy0xMDAuOS0zNy4zLTE0My43IDAtNTAuNCAyMi4xLTk1LjQgNjIuNC0xMjYuOSAxMC45LTE1LjMgMjcuMi0zMiA0OC41LTQ5LjcgMTcuOC0xNC44IDM4LTI5LjMgNTYuOS00MC45bDUuNC0zLjIgNS40IDMuMmMzNi4xIDIyLjEgODIuNCA1OC42IDEwNS40IDkwLjcgNDAuMyAzMS41IDYyLjUgNzYuNCA2Mi41IDEyNi41IDAgNDMuMS0yMC43IDk5LjUtMzcuNSAxNDQuNy0xLjYgNC40LTIuOSA4LjYtNC40IDEyLjcgNy4yIDUgMTMuMyAxMS40IDEzLjMgMjAuNXYuNmwtNy42IDU1LjZjLS42IDEzLjctMTcuMSAyMy43LTUwIDMwLjMgMTQuMSAzNi40IDQxLjUgNjAuMiA3MC42IDYwLjIgMzkuMiAwIDYzLjUtMzMuNiA2My41LTg3LjYgMC0xOC40LTMuNy00MC43LTEwLjItNjEuMmwtNS0xNS44IDE2LjMgMi42YzI1LjMgNCA0Mi44IDEwLjkgNTUuMiAyMS43IDE1IDEzLjIgMjIuNCAzMiAyMi40IDU3LjMgMCA0MC4yLTEyLjYgNzYuNi0zNS42IDEwMi41LTI0LjggMjguMS02MC4zIDQzLTEwMi4yIDQzLTY1LjYgMC0xMTguOC00NS4xLTEzNy44LTExNS43LTggLjMtMTYuMi41LTI0LjQuNXMtMTYuNC0uMi0yNC40LS41Yy0xOC45IDcwLjctNzIuMyAxMTUuOS0xMzcuOCAxMTUuOXoiLz48cGF0aCBkPSJNNDAwIDEwNi41YzMzLjUgMjAuNSA4MC42IDU2LjcgMTAzLjIgODkuMkM1MzkuMSAyMjMuMiA1NjMgMjY0IDU2MyAzMTVjMCA0OC4zLTI4LjUgMTE3LjYtNDQuNCAxNjEuOSA5LjcgNS40IDE1LjIgMTAuMiAxNS4yIDE2LjJsLTcuMiA1NS40YzAgOS41LTIxIDE3LjktNTMuMSAyMy4xIDEzLjIgNDQuNyA0NS45IDc4LjQgODQuMiA3OC40IDQ1LjcgMCA3My45LTM4LjkgNzMuOS05Ny44IDAtMjAtNC00My4zLTEwLjctNjQuMyA0MS41IDYuNiA2OC45IDIxLjkgNjguOSA2OC45IDAgNzUtNDUuNiAxMzUuMi0xMjcuNSAxMzUuMi02MiAwLTExMy42LTQzLjYtMTI5LjktMTE2LjEtMTAuNC42LTIxLjIgMS0zMi40IDFzLTIyLS4zLTMyLjQtMWMtMTYuMyA3Mi41LTY4IDExNi4xLTEzMCAxMTYuMS04MiAwLTEyNy41LTYwLjMtMTI3LjUtMTM1LjIgMC00NyAyNy40LTYyLjQgNjguOS02OC45LTYuNiAyMS0xMC43IDQ0LjQtMTAuNyA2NC4zIDAgNTkgMjguMSA5Ny44IDczLjkgOTcuOCAzOC4zIDAgNzEuMS0zMy43IDg0LjItNzguNC0zMi4yLTUuMi01My4xLTEzLjUtNTMuMS0yM0wyNjYgNDkzYzAtNS45IDUuNS0xMC44IDE1LjItMTYuMi0xNS44LTQ0LjMtNDQuNC0xMTMuMy00NC40LTE2MS42IDAtNTEgMjMuOS05Mi4yIDU5LjctMTE5LjcgMjIuOS0zMi40IDcwLTY4LjQgMTAzLjUtODltMC0yNEwzODkuMyA4OWMtMzQgMjAuOC04MiA1Ny4xLTEwNy42IDkyLjEtNDIuMSAzMy41LTY1LjIgODAuOS02NS4yIDEzNCAwIDQ0LjcgMjEuMSAxMDEuNiAzNy45IDE0Ny4zLjkgMi4yIDEuNiA0LjMgMi40IDYuNS02IDUuNy0xMS4yIDEzLjUtMTEuMiAyNC4xdjEuM2wuMiAxLjMgNy4xIDU0LjhjLjMgNS43IDIuNyAxMy40IDEwLjYgMjAuNCA0LjIgMy44IDkuNSA2LjkgMTYuNCA5LjggNS4zIDIuMyAxMS42IDQuMyAxOC42IDYuMi01LjIgMTAuMi0xMS42IDE5LTE4LjkgMjYtOCA3LjctMjEgMTYuNy0zNy40IDE2LjctMTUuOCAwLTI4LjQtNi4zLTM3LjYtMTguNi0xMC4zLTEzLjgtMTUuNy0zNC4xLTE1LjctNTguOCAwLTE3LjQgMy42LTM4LjYgOS43LTU4LjFsOS45LTMxLjYtMzIuNyA1LjJjLTM3IDUuOC04Ni4yIDIxLjUtODYuMiA4OS4yIDAgMjEuMSAzLjIgNDEgOS41IDU5LjQgNi41IDE5IDE2LjIgMzUuNyAyOC43IDQ5LjkgMjYuOSAzMC4zIDY0LjkgNDYuNCAxMDkuOCA0Ni40IDY3LjkgMCAxMjMuNC00NC43IDE0NS41LTExNS41IDUuNS4xIDExLjEuMiAxNi44LjIgNS42IDAgMTEuMi0uMSAxNi44LS4yIDIxLjkgNzAuNyA3Ny41IDExNS41IDE0NS41IDExNS41IDQ1IDAgODIuOS0xNi4xIDEwOS44LTQ2LjQgMTIuNS0xNC4xIDIyLjEtMzAuOSAyOC43LTQ5LjkgNi4zLTE4LjQgOS41LTM4LjMgOS41LTU5LjQgMC02Ny43LTQ5LjEtODMuNC04Ni4yLTg5LjJsLTMyLjctNS4yIDkuOSAzMS42YzYuMiAxOS41IDkuNyA0MC43IDkuNyA1OC4xIDAgMjQuNi01LjQgNDQuOS0xNS43IDU4LjgtOS4yIDEyLjMtMjEuOCAxOC42LTM3LjYgMTguNi0xNi40IDAtMjkuNC05LjEtMzcuNC0xNi43LTcuMi03LTEzLjctMTUuOS0xOC45LTI2IDcuMS0xLjggMTMuMy0zLjkgMTguNy02LjIgNi44LTIuOSAxMi4yLTYuMiAxNi40LTkuOSA3LjktNy4xIDEwLjItMTQuNyAxMC42LTIwLjRsNy4xLTU0LjUuMS0xLjN2LTEuNGMwLTEwLjYtNS4yLTE4LjQtMTEuMS0yNCAuNi0xLjkgMS40LTMuOSAyLjItNS44IDE3LTQ2IDM4LTEwMy40IDM4LTE0OC4zIDAtNTIuOS0yMy4xLTEwMC4yLTY1LjItMTMzLjYtMTEuMS0xNS43LTI3LjctMzIuNi00OS4xLTUwLjQtMTguMy0xNS4yLTM4LjktMzAtNTguMS00MS45eiIvPjxnIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2YyZjJmMiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIj48ZyBzdHJva2Utd2lkdGg9IjE1LjEyIj48ZyBzdHJva2UtbGluZWNhcD0icm91bmQiPjxwYXRoIGQ9Ik01MjYuNyA1NDguNWw3LjItNTUuN2MwLTE5LjctNTguOS0zNS4yLTEzMy45LTM1LjItNzUuMSAwLTEzMy45IDE1LjctMTMzLjkgMzUuMmw3LjIgNTUuNyIvPjxwYXRoIGQ9Ik0yNzMuNCA1NDguNWMwLTE1LjcgNTYuNy0yOC40IDEyNi43LTI4LjRzMTI2LjcgMTIuNyAxMjYuNyAyOC40Ii8+PHBhdGggZD0iTTE2OS44IDQ5MS4yYy0zNS4yIDYuMy01OC41IDIxLjEtNTguNSA2Ni4yIDAgNzIgMzguOCAxMjYuNyAxMDguMyAxMjYuNyA2My4zIDAgMTEzLjktNTkuNiAxMTQuOC0xNTYuMm0yOTUuNy0zNi43YzM1LjIgNi4zIDU4LjUgMjEuMSA1OC41IDY2LjIgMCA3Mi0zOC44IDEyNi43LTEwOC4zIDEyNi43LTYzLjMgMC0xMTMuOS01OS42LTExNC44LTE1Ni4yIi8+PC9nPjxwYXRoIGQ9Ik01MTguNyA0NzYuMmMxNS44LTQ0LjcgNDQuNC0xMTMuMyA0NC40LTE2MS42IDAtNTEtMjMuOS05Mi4xLTU5LjctMTE5LjctMjIuNy0zMi40LTY5LjktNjktMTAzLjItODkuNS0zMy41IDIwLjUtODAuNiA1Ny4xLTEwMy4yIDg5LjUtMzUuOSAyNy40LTU5LjcgNjguNi01OS43IDExOS43IDAgNDguMyAyOC42IDExNi45IDQ0LjQgMTYxLjYiLz48L2c+PHBhdGggZD0iTTM5OC45IDIxMS4ydjE4NC43bS02OS4xLTk0aDE0MC40IiBzdHJva2Utd2lkdGg9IjE3LjI4Ii8+PC9nPjwvc3ZnPg==')} +.is2d .rook.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTM5OC4zIDcwOC4yYy01Ni4yIDAtMTA4LjYtNS44LTE0OC4zLTE2LjUtNDQuNi0xMi4xLTY3LjEtMjguNC02Ny4xLTQ4LjVWNTgyYzAtMjguMyA0My4xLTQ2LjEgNzMuMi01NS4ybDcuOS0xNzIuNWMtMy4yLTIuNi01LjYtNS4zLTcuMi04LjJsLS4yLS4zLTI0LjMtNTIuOGMtNy0zLjUtMTktMTAuNy0xOS0yMi4yVjE0NS4zaDczLjR2NTAuOGg0Mi4xdi01MC4ybDEzNSAuMXY1MC4xaDQyLjF2LTUwLjhoNzQuNXYxMjUuNGMwIDcuNy00LjEgMTQuNC0xMi43IDE5LjhMNTQ0LjEgMzQ2bC0uNC44Yy0yLjEgMy4xLTQuOSA2LTguNCA4LjdsNy41IDE3MS4xYzIwLjYgNiAzOCAxMy41IDUwLjUgMjEuNiAxNi4yIDEwLjUgMjQuMyAyMS44IDI0LjMgMzQgMCAuOCAwIDEuNi0uMSAyLjVsLS4xIDU4LjhjMCAyMC4yLTIzIDM2LjUtNjguNCA0OC41LTQwLjQgMTAuMy05My44IDE2LjItMTUwLjcgMTYuMnoiLz48cGF0aCBkPSJNNTcwLjYgMTU1djExNS43YzAgNC41LTMuMSA5LTEwLjcgMTMuMWwtMjQuNSA1Ny43Yy0yLjEgMy4yLTUuNSA2LjItMTAuMiA5bDggMTgzLjVjNDYuMyAxMi41IDc0LjYgMzAuOCA3NC42IDQ4LjIgMCAuNiAwIDEuMy0uMSAxLjlsLS4xIDU5LjNjMCAzMC42LTkzLjEgNTUuNC0yMDkuMiA1NS40LTExNC41IDAtMjA1LjgtMjQuNy0yMDUuOC01NS40di02MS4yYzAtMTcuMiAyNy40LTM1LjMgNzIuOC00Ny44bDguNC0xODQuN2MtNC0yLjYtNy4xLTUuMy04LjctOC4xbC0yNS42LTU1LjdjLTEwLjItNC41LTE2LjYtOS42LTE2LjYtMTVWMTU1aDU0djUwLjhoNjEuNnYtNTAuM2wxMTUuNi4xdjUwLjJoNjEuNlYxNTV6bTE5LjUtMTkuNGgtOTIuOXY1MC43aC0yMy44di01MGgtMTkuM2wtMTE1LS4xSDMyMHY1MC4xaC0yMy44di01MC43aC05Mi43djEzNS4xYzAgMTUuMyAxMi40IDI0LjQgMjEuMyAyOS4zbDIyLjggNDkuNS4zLjguNC44YzEuNSAyLjcgMy41IDUuMiA1LjcgNy41bC03LjMgMTYxLjFjLTE4LjQgNS45LTMzLjUgMTIuOS00NS40IDIwLjYtMTIuOSA4LjQtMjguMSAyMi42LTI4LjEgNDEuOHY2MS4yYzAgMTggMTMuNSAzMC42IDI0LjggMzcuOCAxMiA3LjcgMjguNSAxNC40IDQ5LjQgMjAgNDAuNCAxMC45IDk0IDE2LjggMTUxIDE2LjggNTcuNyAwIDExMi4xLTYgMTUzLjEtMTYuOCAyMS4xLTUuNiAzNy45LTEyLjMgNTAuMS0yMCAxMS42LTcuMiAyNS40LTE5LjggMjUuNC0zNy45bC4xLTU4LjJjLjEtMS4xLjEtMi4xLjEtMyAwLTguNi0zLjEtMTcuMS05LjItMjQuOS00LjYtNi0xMS4yLTExLjktMTkuNS0xNy4yLTEyLjEtNy44LTI3LjYtMTQuOC00Ni40LTIwLjdsLTYuOS0xNTkuNWMyLjctMi41IDQuOS01LjEgNi43LTcuOGwxLTEuNC42LTEuNSAyMi4xLTUyLjFjMTIuMS04LjYgMTQuNy0xOC44IDE0LjctMjYuMVYxMzUuNnoiLz48ZyBmaWxsPSJub25lIiBzdHJva2U9IiNmMmYyZjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIj48cGF0aCBkPSJNNjA2LjEgNTg2LjZjLTguOSAyOC40LTk2LjkgNTAuOC0yMDUuNCA1MC44LTExNC41IDAtMjA4LjMtMjUuMS0yMDguMy01NS42IiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjE2LjA1MSIvPjxwYXRoIGQ9Ik01MzQuMyA1NDEuMmMwIDE5LjctNjAuOSAzMy45LTEzNC40IDMzLjloLjFjLTczLjQgMC0xMzQuNC0xNC4zLTEzNC40LTMzLjlsNi41LTE5MC43IiBzdHJva2Utd2lkdGg9IjEyLjk2Ii8+PHBhdGggZD0iTTUzNC42IDM0MS4zQzUyNS4yIDM1Ny45IDQ3Mi45IDM3MCA0MDAgMzcwaC4xYy03Mi45IDAtMTI1LjMtMTIuMS0xMzQuNy0yOC42bC0yNC41LTU0LjUiIHN0cm9rZS13aWR0aD0iMTAuOCIvPjxwYXRoIGQ9Ik01NzIuOCAyNzAuNlYxNTRoLTU3LjJ2NTAuOEg0NTR2LTQ5LjFsLTExNS42LS4xdjQ5LjJoLTYxLjZWMTU0SDIyNHYxMTYuNmMwIDIwLjEgODEuNSAzNi40IDE3NS4zIDM2LjQgOTMuNyAwIDE3My41LTE2LjIgMTczLjUtMzYuNHoiIHN0cm9rZS13aWR0aD0iMTUuMTIiLz48L2c+PC9zdmc+')} +.is2d .queen.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTQwMCA3MDQuNGMtNjIgMC0xMjAuNS01LjUtMTY0LjgtMTUuNC00OS43LTExLjEtNzQuMi0yNS44LTc1LTQ0LjhMMTUwIDU4N3YtLjljMC01LjQgMS42LTEzLjIgOC42LTIxLjQtNy41LTQzLjEtMjQuNi0xMTcuMi00NC42LTE5Mi4yLTE4LjQtNi45LTMwLjgtMjQuNS0zMC44LTQ0LjYgMC0yNi40IDIxLjQtNDcuNyA0Ny43LTQ3LjdzNDcuNyAyMS40IDQ3LjcgNDcuN2MwIDExLjEtMy43IDIxLjUtMTAuNiAyOS45IDIxLjEgNjcuMSA0Ni45IDEzNi43IDY0LjkgMTc1LjJsNS4zLTEuM2MtLjUtNTUuMy05LjEtMTY0LjMtMjAuNi0yNjEuNi0xOC42LTgtMzEtMjYuNi0zMS00Ny4xIDAtMjguMyAyMy01MS4zIDUxLjMtNTEuM3M1MS4zIDIzIDUxLjMgNTEuM2MwIDEzLjgtNS40IDI2LjctMTUgMzYuMyAxNy45IDkzLjUgNDcuNyAyMTEuNiA2NS4zIDI1OC45bDUuNC0uM2M4LjYtNjYgMTkuNC0xODQuNSAyNC42LTI5NC41LTE0LjktOS45LTIzLjgtMjYuNS0yMy44LTQ0LjUgMC0yOS44IDI0LjItNTQgNTQtNTRzNTQgMjQuMiA1NCA1NGMwIDE4LTguOSAzNC42LTIzLjUgNDQuNiA1LjIgMTEwLjEgMTYgMjI4LjUgMjQuNiAyOTQuNWw1LjQuM2MxNy42LTQ3LjMgNDcuNC0xNjUuMyA2NS4zLTI1OC45LTkuNi05LjYtMTUtMjIuNS0xNS0zNi4zIDAtMjguMyAyMy01MS4zIDUxLjMtNTEuM3M1MS4zIDIzIDUxLjMgNTEuM2MwIDIwLjYtMTIuNCAzOS4xLTMxIDQ3LjEtMTEuNiA5Ny4zLTIwLjIgMjA2LjMtMjAuNiAyNjEuNmw1LjMgMS4zYzE4LTM4LjQgNDMuOC0xMDguMSA2NC45LTE3NS4yLTYuOS04LjQtMTAuNi0xOC45LTEwLjYtMjkuOSAwLTI2LjQgMjEuNC00Ny43IDQ3LjctNDcuN3M0Ny43IDIxLjQgNDcuNyA0Ny43YzAgMjAuMS0xMi40IDM3LjctMzAuOCA0NC42LTE5LjkgNzUuMS0zNyAxNDkuMS00NC42IDE5Mi4yIDUuNyA2LjcgOC42IDEzLjggOC42IDIxLjN2LjlsLTEwLjMgNTcuN2MtMS4yIDE4LjktMjUuNyAzMy41LTc1IDQ0LjYtNDMuOCA5LjYtMTAyLjMgMTUuMS0xNjQuNCAxNS4xem0tMTg1LTcxLjdjMTAuOCA3LjIgMzQuOSAxNC4zIDY2LjIgMTkuMSAzNC4zIDUuNCA3NS40IDguMiAxMTguOCA4LjIgOTggMCAxNjMuOS0xMy44IDE4NC4yLTI2LjlsMy4zLTIuOWMtNC4yLTQuMi0xNy0xMS40LTQ4LjctMTcuNy0zNS4zLTYuOS04NC43LTEwLjctMTM4LjktMTAuNy01MC4zIDAtOTguMiAzLjktMTM0LjYgMTEtMzMuMiA2LjUtNDcuNSAxMy44LTUyLjYgMTcuOXoiLz48cGF0aCBkPSJNNDAwIDEzNC41YzI0LjQgMCA0NC4zIDE5LjkgNDQuMyA0NC4zIDAgMTcuMS05LjYgMzEuOS0yMy44IDM5LjIgNS4xIDExNCAxNi44IDI0Mi42IDI2IDMwOS4xbDIwLjQgMS4zYzE4LjEtNDQuNyA1MS40LTE3Ni44IDY5LjQtMjcyLjYtOS43LTcuNi0xNS45LTE5LjQtMTUuOS0zMi43IDAtMjMgMTguNi00MS42IDQxLjYtNDEuNnM0MS42IDE4LjYgNDEuNiA0MS42YzAgMTktMTIuNyAzNS0zMC4yIDQwLTEyLjMgMTAyLjEtMjEuOCAyMjItMjEuNSAyNzYuNGwyMC40IDQuOWMyMC4zLTQxLjEgNDkuNy0xMjEuOSA3MC40LTE4OC45LTcuMi02LjktMTEuOC0xNi42LTExLjgtMjcuNSAwLTIxIDE3LTM4IDM4LTM4czM4IDE3IDM4IDM4YzAgMTcuOS0xMi40IDMyLjktMjkuMSAzNi45LTIwLjggNzgtMzkuNSAxNTguMi00NyAyMDMuMSA2IDUuNyA5LjQgMTEuOCA5LjQgMTguMWwtMTAuMiA1Ny0uMS4xYzAgMjguNS0xMDMgNTEuNi0yMzAgNTEuNi0xMjcuMSAwLTIzMC0yMy40LTIzMC01MS41bC0xMC4yLTU3LjFjMC02LjMgMy4yLTEyLjUgOS40LTE4LjMtNy41LTQ0LjktMjYuMS0xMjUuMi00Ny0yMDMuMS0xNi42LTQtMjkuMS0xOS0yOS4xLTM2LjkgMC0yMSAxNy0zOCAzOC0zOCAyMS4xIDAgMzggMTcgMzggMzggMCAxMC44LTQuNSAyMC42LTExLjggMjcuNSAyMC44IDY3IDUwLjEgMTQ3LjkgNzAuNCAxODguOWwyMC40LTQuOWMuMy01NC4yLTkuMi0xNzQuMy0yMS41LTI3Ni40LTE3LjQtNS0zMC4yLTIxLTMwLjItNDAgMC0yMyAxOC42LTQxLjYgNDEuNi00MS42czQxLjYgMTguNiA0MS42IDQxLjZjMCAxMy4zLTYuMyAyNS4xLTE1LjkgMzIuNyAxOCA5NS44IDUxLjIgMjI3LjkgNjkuNCAyNzIuNmwyMC40LTEuM2M5LjEtNjYuNSAyMC44LTE5NSAyNi0zMDkuMS0xNC4xLTcuNS0yMy44LTIyLjEtMjMuOC0zOS4yLjEtMjQuMyAyMC00NC4yIDQ0LjQtNDQuMm0wIDUzNS4zYzg5LjQgMCAxNjUtMTIuMSAxOTAuMi0yOC44bDktNy45YzAtMjUuNi04OS4xLTQxLTE5OS00MXMtMTk5IDE4LjQtMTk5IDQxbDguMSA3LjJjMjQgMTcgMTAwLjMgMjkuNSAxOTAuNyAyOS41bTAtNTU0LjdjLTM1LjEgMC02My43IDI4LjYtNjMuNyA2My43IDAgMTkuMyA4LjYgMzcuMyAyMy4yIDQ5LjItNC40IDkyLjgtMTIuOSAxOTAuOC0yMC41IDI1Ny44LTE3LTU1LjQtMzkuNi0xNDguMS01NC4zLTIyMy41IDkuMi0xMC45IDE0LjQtMjQuNyAxNC40LTM5LjMgMC0zMy43LTI3LjMtNjEtNjEtNjFzLTYxIDI3LjMtNjEgNjFjMCAxMy41IDQuMyAyNi40IDEyLjYgMzcuMiA1LjIgNi43IDExLjcgMTIuMyAxOS4xIDE2LjQgOS4xIDc3LjQgMTYuMiAxNjEuNSAxOC45IDIxOS4yLTE1LjMtMzcuNi0zMy4yLTg3LjQtNDguNi0xMzYuMyA2LjItOS4zIDkuNi0yMC40IDkuNi0zMS42IDAtMzEuNi0yNS44LTU3LjUtNTcuNS01Ny41LTMxLjYgMC01Ny42IDI1LjctNTcuNiA1Ny4zIDAgMjIuNSAxMi45IDQyLjIgMzIuMyA1MS42IDE4LjcgNzAuOCAzNC44IDE0MC4yIDQyLjQgMTgyLjYtNi41IDkuMS04LjEgMTcuNy04LjEgMjR2MS43bC4zIDEuNyA5LjkgNTUuOGMuNCA1LjcgMi42IDEzLjUgOS43IDIxLjQgNC42IDUgMTAuNyA5LjQgMTguNyAxMy42IDEzLjEgNi45IDMxLjMgMTMuMSA1NC4xIDE4LjEgNDUgMTAuMiAxMDQuMyAxNS43IDE2NyAxNS43IDYyLjkgMCAxMjIuMS01LjUgMTY3LTE1LjcgMjIuOC01LjEgNDEtMTEuMiA1NC4xLTE4LjMgOC00LjIgMTQtOC43IDE4LjctMTMuNyA0LjEtNC41IDYuNi05LjEgOC0xMy4ybC4zLS4zLjMtMS44Yy41LTEuOS45LTMuOCAxLTUuNWwxMC01Ni40LjMtMS43VjU4NmMwLTYuMi0xLjYtMTQuOC04LjEtMjMuOSA3LjYtNDIuNCAyMy44LTExMS44IDQyLjQtMTgyLjYgMTkuNC05LjQgMzIuMy0yOS4zIDMyLjMtNTEuNiAwLTMxLjYtMjUuOC01Ny41LTU3LjUtNTcuNS0zMS42IDAtNTcuNSAyNS44LTU3LjUgNTcuNSAwIDExLjMgMy4zIDIyLjQgOS42IDMxLjYtMTUuNCA0OC45LTMzLjQgOTguNy00OC42IDEzNi4zIDIuNy01Ny44IDkuOC0xNDEuOCAxOC45LTIxOS4yIDcuMy00LjEgMTMuOS05LjYgMTkuMS0xNi40IDguMi0xMC43IDEyLjYtMjMuNSAxMi42LTM3LjIgMC0zMy43LTI3LjMtNjEtNjEtNjFzLTYxIDI3LjMtNjEgNjFjMCAxNC42IDUuMSAyOC40IDE0LjQgMzkuMy0xNC43IDc1LjQtMzcuNCAxNjgtNTQuMyAyMjMuNS03LjctNjctMTYuMS0xNjQuOS0yMC41LTI1Ny44IDE0LjUtMTEuOSAyMy4xLTI5LjggMjMuMS00OS4xLjItMzUuMi0yOC40LTYzLjgtNjMuNS02My44ek0yMzQgNjMxYzguNS0zIDIxLjYtNi43IDQxLjMtMTAgMzQuNy02IDc4LjktOS4zIDEyNC43LTkuMyA0OCAwIDkxLjIgMi45IDEyNS4xIDguNCAyMS4xIDMuNSAzNC4zIDcuMSA0Mi43IDEwLjQtOS41IDMuNi0yNS41IDguMS01MS41IDEyLjEtMzMuNyA1LjItNzMuOSA3LjktMTE2LjIgNy45LTQyLjkgMC04My40LTIuOC0xMTcuMy04LjEtMjQtMy44LTM5LjItOC4xLTQ4LjgtMTEuNHoiLz48Y2lyY2xlIGN4PSI0MDAiIGN5PSIxMTIuOSIgcj0iMjUuOSIvPjxjaXJjbGUgY3g9IjIyNSIgY3k9IjE2NC44IiByPSIyMyIvPjxjaXJjbGUgY3g9IjExMy44IiBjeT0iMjczLjgiIHI9IjIyLjQiLz48Y2lyY2xlIGN4PSI1NzUiIGN5PSIxNjQuOCIgcj0iMjMiLz48Y2lyY2xlIGN4PSI2ODcuMyIgY3k9IjI3My44IiByPSIyMi40Ii8+PGcgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZjJmMmYyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCI+PHBhdGggZD0iTTExNy42IDI4Ny45bC00LjUtMTUiIHN0cm9rZS13aWR0aD0iMTcuMjgiLz48cGF0aCBkPSJNMjI4LjggMTgwLjdsLTQuNC0xOCIgc3Ryb2tlLXdpZHRoPSIxOC4zNiIvPjxwYXRoIGQ9Ik02ODIuNyAyODcuOWw0LjYtMTUiIHN0cm9rZS13aWR0aD0iMTcuMjgiLz48cGF0aCBkPSJNNTcwLjQgMTgwLjdsNC42LTE4IiBzdHJva2Utd2lkdGg9IjE4LjM2Ii8+PHBhdGggZD0iTTM5OS41IDEwOC42VjEyNyIgc3Ryb2tlLXdpZHRoPSIyMC41MiIvPjxnIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMTUuMTIiPjxwYXRoIGQ9Ik0yNjMuNyAyNTUuOGM5LjctNy42IDE1LjktMTkuNCAxNS45LTMyLjcgMC0yMy0xOC42LTQxLjYtNDEuNi00MS42cy00MS42IDE4LjYtNDEuNiA0MS42YzAgMTkgMTIuNyAzNSAzMC4yIDQwIDEyLjMgMTAyLjEgMjEuOCAyMTUuNiAyMS41IDI2OS45bC0yMC40IDQuOU00MjAuNSAyMThjMTQuMS03LjUgMjMuOC0yMi4xIDIzLjgtMzkuMiAwLTI0LjQtMTkuOS00NC4zLTQ0LjMtNDQuM3MtNDQuMyAxOS45LTQ0LjMgNDQuM2MwIDE3LjEgOS42IDMxLjkgMjMuOCAzOS4yLTUuMSAxMTQtMTYuOCAyMzYuMS0yNiAzMDIuNmwtMjAuNCAxLjNNNTczLjMgMjYzYzE3LjQtNSAzMC4yLTIxIDMwLjItNDAgMC0yMy0xOC42LTQxLjYtNDEuNi00MS42UzUyMC4zIDIwMCA1MjAuMyAyMjNjMCAxMy4zIDYuMyAyNS4xIDE1LjkgMzIuNy0xOCA5NS44LTUxLjIgMjIxLjQtNjkuNCAyNjYuMWwtMjAuNC0xLjNtMjMxLjUtMTU1LjdjMTYuNi00IDI5LjEtMTkgMjkuMS0zNi45IDAtMjEtMTctMzgtMzgtMzhzLTM4IDE3LTM4IDM4YzAgMTAuOCA0LjUgMjAuNiAxMS44IDI3LjUtMjAuOCA2Ny01MC4xIDE0MS40LTcwLjQgMTgyLjRsLTIwLjQtNC45Ii8+PHBhdGggZD0iTTE1Ny4yIDM1NS40YzcuMi02LjkgMTEuOC0xNi42IDExLjgtMjcuNSAwLTIxLTE3LTM4LTM4LTM4LTIxLjEgMC0zOCAxNy0zOCAzOCAwIDE3LjkgMTIuNCAzMi45IDI5LjEgMzYuOSAyMC44IDc4IDM5LjUgMTU1IDQ3IDE5OS45LTYgNS43LTkuNCAxMS44LTkuNCAxOC4xbDEwLjIgNjAuM2MwLTI4LjUgMTAzLTUxLjYgMjMwLjEtNTEuNnMyMzAuMSAyMy4xIDIzMC4xIDUxLjZsMTAuMi02MC4zYzAtNi4zLTMuMi0xMi4zLTkuNC0xOC4xIi8+PC9nPjwvZz48L3N2Zz4=')} +.is2d .king.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTY5NC43IDM2My4yYy05LjctNy41LTIyLjYtMTEuMi0zOC0xMS4yaC0xLjRjLTIuMSAwLTQuMi4xLTYuNS4xLTIuNyAwLTUuNi4xLTguNS4xIDMuMy0yMy43LjYtNDEuNi04LTU1LjUtNi42LTEwLjYtMTUuOS0xOC4zLTI3LjgtMjIuOS05LjMtMy43LTIwLjMtNS40LTMzLjYtNS40LTEyLjIgMC0yNS4yIDEuNC0zOC44IDMuMi0zLTE0LjEtOS4zLTI1LjQtMTguNy0zMy41LTkuNS04LjMtMjAuNi0xMi41LTMzLTEyLjUtMjQuMSAwLTQ3LjIgMTYuMy02NS45IDI5LjZ2LTgwLjdoNDkuN3YtMzAuMmgtNDkuN1Y5NC42aC0zMC4ydjQ5LjdoLTQ2LjR2MzAuMmg0Ni40djc4LjljLTE4LjMtMTMtNDAuNC0yOC02My41LTI4LTEyLjQgMC0yMy41IDQuMi0zMyAxMi41LTkuNCA4LjEtMTUuNiAxOS4zLTE4LjcgMzMuNS0xMy43LTEuOC0yNi43LTMuMi0zOC45LTMuMi0xMy4zIDAtMjQuMyAxLjctMzMuNyA1LjQtMTEuOSA0LjYtMjEuMiAxMi4zLTI3LjggMjIuOS04LjYgMTQtMTEuMyAzMi04LjEgNTUuNS0yLjggMC01LjYtLjEtOC4yLS4xLTIuNSAwLTQuOS0uMS03LS4xSDE0NGMtMTUuMiAwLTI4LjQgMy45LTM4LjIgMTEuMS04LjUgNi40LTE4LjYgMTguMy0xOC42IDM5LjQgMCAyNi4xIDE4LjMgNTMuOCAzNy41IDgzLjJsNS43IDguNyAyNS42IDUzLjljLTcuNiA4LjMtMTEuMyAxNy4zLTExLjMgMjYuOHYyLjJsLjQgMi4yIDE1LjcgNjQuNmMxLjEgMTIuOSAxMC4yIDI0IDI3IDMyLjkgMTIuNiA2LjcgMzAuMSAxMi41IDUyLjEgMTcuNSA0My4xIDkuNyAxMDAuMSAxNSAxNjAuNiAxNSA2MCAwIDExNi43LTUuMyAxNTkuNy0xNC44IDIxLjgtNC45IDM5LjMtMTAuNyA1Mi4xLTE3LjMgMTcuMS04LjkgMjYuNS0xOS45IDI3LjktMzIuNmwxNC43LTY1LjcuNi0xLjl2LTIuMWMwLTkuNC00LTE4LjEtMTEuNi0yNi4xbDIzLjgtNTIuNmMyLjUtMy43IDQuOS03LjUgNy4zLTExIDE5LjQtMjkuMiAzNy44LTU2LjcgMzcuOC04Mi43IDAtMjEuMS05LjktMzMtMTguMS0zOS4zeiIvPjxnIHN0cm9rZT0iI2YyZjJmMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxnIGZpbGw9Im5vbmUiIHN0cm9rZS13aWR0aD0iMTUuMTIiPjxwYXRoIGQ9Ik0xODIgMzcxLjVjLTExLjkuMy0yNS45LS4xLTM3LjUtLjMtMjEuOS0uMy0zOS40IDguNy0zOS40IDMyLjIgMCAzOS4xIDYwLjYgOTUuNyA3My4zIDE0Ni43Ii8+PHBhdGggZD0iTTI4NC4xIDI5My41Yy00NS42LTYuMy04My4zLTEzLjgtMTAwLjMgMTMuNy0yNyA0My42IDM1LjYgMTUwLjcgNTUuMSAyMjIuNCIvPjxwYXRoIGQ9Ik0zOTguOSAyODYuOGMtMjQuMy05LTY3LjktNjEuNy05OS44LTMzLjktNDMuNiAzNy45IDIyLjkgMTczLjkgMzguMSAyNjAuNW0yODAuNy0xNDEuOWMxMS45LjMgMjUuOS0uMSAzNy41LS4zIDIxLjktLjMgMzkuNCA4LjcgMzkuNCAzMi4yIDAgMzkuMS02MC42IDk1LjctNzMuMyAxNDYuNyIvPjxwYXRoIGQ9Ik01MTUuOSAyOTMuNWM0NS42LTYuMyA4My4zLTEzLjggMTAwLjMgMTMuNyAyNyA0My42LTM1LjYgMTUwLjctNTUuMSAyMjIuNCIvPjxwYXRoIGQ9Ik00MDEuMSAyODYuOGMyNC4zLTkgNjcuOS02MS43IDk5LjgtMzMuOSA0My42IDM3LjktMjIuOSAxNzMuOS0zOC4xIDI2MC41Ii8+PC9nPjxwYXRoIGQ9Ik0xNzcuOSA1NTRjMzQtMjMuMyAxMjAuNi0zOS42IDIyMi0zOS42IDEwMi41IDAgMTkwLjMgMTYuMyAyMjMuNiA0MGwzMS44LTc4LjFjLTExLjggMTMuMS0yMy43IDE4LjUtMzMuOSAxNS4zLTI2LjktOC40LTI2LjUtNDAuNi0yNC40LTY2LjUtMTYuNCAyOS41LTM5LjMgNDQuNy02My45IDM5LjUtMjQuOS01LjMtNDAtNDAuNS0zOS02OC42LTE3LjUgMzUuNi00OS40IDU0LjEtOTQuMSA1NC4xcy03Ni42LTE4LjYtOTQuMS01NC4yYzEuMSAyOC4xLTE0IDYzLjMtMzkgNjguNi0yNC42IDUuMi00Ny40LTEwLTYzLjktMzkuNSAxLjkgMjUuOSAyLjYgNTguNS0yNC40IDY2LjUtOS4xIDIuNy0yMi4xLTMuOC0zMy45LTE1LjN6IiBzdHJva2Utd2lkdGg9IjEyLjk2Ii8+PGcgZmlsbD0ibm9uZSI+PHBhdGggZD0iTTE2Mi41IDU3NS45YzAtMzQuMyAxMDYuMy02MS43IDIzNy40LTYxLjdzMjM3LjQgMjcuMyAyMzcuNCA2MS43bS00NzUgMS44bDE2LjIgNjUuMW00NTkuMi02NS4xbC0xNi4yIDY1LjEiIHN0cm9rZS13aWR0aD0iMTIuOTYiLz48cGF0aCBkPSJNMTc4LjYgNjQyLjJjMC0yNy40IDk5LjEtNDkuNyAyMjEuNC00OS43czIyMS40IDIyLjIgMjIxLjQgNDkuNyIgc3Ryb2tlLXdpZHRoPSIxNS4xMiIvPjxwYXRoIGQ9Ik00MDAgMjg2Ljh2MTYwLjkiIHN0cm9rZS13aWR0aD0iNi40OCIvPjwvZz48L2c+PC9zdmc+')} diff --git a/public/piece-css/companion.css b/public/piece-css/companion.css new file mode 100644 index 0000000000..f479d973b6 --- /dev/null +++ b/public/piece-css/companion.css @@ -0,0 +1,12 @@ +.is2d .pawn.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMjcuNzA1IDMwLjcyNGMxLjcxMzMtMi45NjYxIDYuMzI5NS0zLjI0MjggOC4zNTE5LS40NjAxNyAxLjc1OTQgMS44OTU3LjkyNDM0IDQuNTQ4Ni4zOTcxNyA2Ljc1NDEgMi44MDkgMS4zNDI4IDYuMDk5IDEuODkxOSA4LjQyODggNC4wODU4IDEuNzE2NiAxLjUyNjYgMS45MDkyIDMuOTI3OSAyLjI2OTcgNi4wNDYxLTMuNjIyNy4xMjIxNC03LjI0NzQuMDU3NTUtMTAuODcxLjA4MjA1LjAyMzIxIDIuMDUzNS4xOTEzOCA0LjEzODggMS4yNzY3IDUuOTQxMyAxLjczODMgMy4zNzk2IDMuMDc3NiA3LjcxOTkuNDY0NzIgMTEuMDQ0LS4wMjE3NC40NTcxLS4wNjUyMSAxLjM3MTMtLjA4Njk0IDEuODI4NCAzLjE5OTUuMjY3MTQgNi43NzAxLjQ0NDE2IDkuMjY2NiAyLjczNjkgMS41MzY5IDEuMjg2NCAxLjgwNTcgMy4zNjc3IDIuMjY1MiA1LjE5My0xMS4xOTMuMTYyMjctMjIuMzg5LjAyNjY1LTMzLjU4My4wNzExMnYtNC4xMTk4YzIuNDgtMy4xMTExIDYuNTg3MS0zLjY3MDcgMTAuMjk2LTMuODg3MS4wMTYwMS0uNDM3My4wNDgwNi0xLjMxMTkuMDY0MDctMS43NDkyLS43Mjk3My0xLjM5NzktMS44MzA1LTIuNzcyOS0xLjY3NjctNC40NDg0LS4wMDU4LTQuNTA2MyAzLjc4MzgtOC4wMjc1IDMuMjY3MS0xMi42MS0zLjU2OTYtLjAyMjU3LTcuMTM5Ni4wMjczNy0xMC43MDgtLjA2MTc3LjQ4NzEtMi41ODAzIDEuMzQ5Mi01LjM0NzMgMy42MzA3LTYuOTA0IDIuMTk3My0xLjQ2MTkgNC42OTQ0LTIuMzg5NiA2Ljk5MTYtMy42NzktLjQ3NjQ3LTEuODkyMi0xLjM4OTMtNC4wOTQtLjA0NDg4LTUuODYzNHoiIGZpbGw9IiNmZmYiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wNzg4OTUiLz48cGF0aCBkPSJtMjcuNzA1IDMwLjcyNGMxLjcxMzMtMi45NjYxIDYuMzI5NS0zLjI0MjggOC4zNTE5LS40NjAxNyAxLjc1OTQgMS44OTU3LjkyNDM0IDQuNTQ4Ni4zOTcxNyA2Ljc1NDEgMi44MDkgMS4zNDI4IDYuMDk5IDEuODkxOSA4LjQyODggNC4wODU4IDEuNzE2NiAxLjUyNjYgMS45MDkyIDMuOTI3OSAyLjI2OTcgNi4wNDYxLTMuNjIyNy4xMjIxNC03LjI0NzQuMDU3NTUtMTAuODcxLjA4MjA1LjAyMzIxIDIuMDUzNS4xOTEzOCA0LjEzODggMS4yNzY3IDUuOTQxMyAxLjczODMgMy4zNzk2IDMuMDc3NiA3LjcxOTkuNDY0NzIgMTEuMDQ0LS4wMjE3NC40NTcxLS4wNjUyMSAxLjM3MTMtLjA4Njk0IDEuODI4NCAzLjE5OTUuMjY3MTQgNy4yNDYyLjUwODg0IDkuMjY2NiAyLjczNjkgMi4wNDgxIDIuMjU4NyAxLjgwNTcgMy4zNjc3IDIuMjY1MiA1LjE5My0xMS4xOTMuMTYyMjctMjMuODA0LjEyOTUtMzQuOTk4LjE3Mzk4LjI4ODIxLTEuNzQzMS4xOTkxNC0xLjczMjggMS40MjYtNC4zNzg4IDEuMjE2MS0yLjYyMjggNi41NzY1LTMuNTE0NiAxMC4yODYtMy43MzEuMDE2MDEtLjQzNzMuMDQ4MDYtMS4zMTE5LjA2NDA3LTEuNzQ5Mi0uNzMtMS4zOTctMS44MzEtMi43NzItMS42NzctNC40NDctLjAwNTgtNC41MDYzIDMuNzgzOC04LjAyNzUgMy4yNjcxLTEyLjYxLTMuNTY5Ni0uMDIyNTctNy4xMzk2LjAyNzM3LTEwLjcwOC0uMDYxNzcuNDg3MS0yLjU4MDMgMS4zNDkyLTUuMzQ3MyAzLjYzMDctNi45MDQgMi4xOTczLTEuNDYxOSA0LjY5NDQtMi4zODk2IDYuOTkxNi0zLjY3OS0uNDc2NDctMS44OTIyLTEuMzg5My00LjA5NC0uMDQ0ODgtNS44NjM0eiIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im0zMC41OTcgMzYuODc4Yy0xLjk2NTYtMS45NjQ5LTEuNzQyNS02LjUzMDIgMS43ODE4LTYuMjExMSAzLjA5MjcuNDEwMjMgMi43MjU5IDQuMjI5MiAxLjMyMzIgNi4xNjQ1IDIuOTggMy42NTE0IDkuMjQ4MSAyLjk1NjUgMTAuODc2IDcuODgxMS04LjI1ODIuMjM4MTItMTYuNTM4LjIzMjE4LTI0Ljc5Ni4wMDAxOTIgMS43MTgtNC44NTE0IDcuODEzOS00LjI1OTIgMTAuODE1LTcuODM0N3oiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wNzg4OTUiLz48cGF0aCBkPSJtMzAuNTk3IDM2Ljg3OGMtMS45NjU2LTEuOTY0OS0xLjc0MjUtNi41MzAyIDEuNzgxOC02LjIxMTEgMy4wOTI3LjQxMDIzIDIuNzI1OSA0LjIyOTIgMS4zMjMyIDYuMTY0NSAyLjk4IDMuNjUxNCA5LjI0ODEgMi45NTY1IDEwLjg3NiA3Ljg4MTEtOC4yNTgyLjIzODEyLTE2LjUzOC4yMzIxOC0yNC43OTYuMDAwMTkyIDEuNzE4LTQuODUxNCA3LjgxMzktNC4yNTkyIDEwLjgxNS03LjgzNDd6Ii8+PHBhdGggZD0ibTMwLjEyNyA0Ny4yMjNjMS4yODcyLS4wMDAwOTYgMi41NzQ1LS4wMDAwOTYgMy44NjIxLS4wMDAxNDQtLjkzNTI3IDQuODU2NSAzLjQ4MjkgOC40OTE4IDMuMTU1MSAxMy4yNzEtLjAzNzYyIDEuMTk2Ni0uNzY1ODcgMi4xODQ3LTEuMzIyMyAzLjE5MDEuMjEyNzQgMS4zNTE1LjQyODcgMi43MDI1LjY0MTgyIDQuMDU0OCAzLjU0MDMuMjQzMzcgOC4wMjMxLjIyOTY4IDkuOTMzOSAzLjg0NTQtOS41OTU1LjE0MjI2LTE5LjIwNC4xOTQxNy0yOC43OTgtLjAyNzUxIDIuMDc0NC0zLjU1ODcgNi41Nzg1LTMuNTcyNyAxMC4xODgtMy44MTYzLjIyNDM4LTEuMzczOC40NTEzOC0yLjc0NjUuNjgzMDUtNC4xMTgtLjgyMTE1LTEuMTI2OS0xLjgxOTEtMi4yODg4LTEuNzEzMy0zLjc4NjItLjA3MzAzLTQuNTY4NSA0LjM2OTQtNy45MDAxIDMuMzY5Mi0xMi42MTN6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDc4ODk1Ii8+PHBhdGggZD0ibTMwLjEyNyA0Ny4yMjNjMS4yODcyLS4wMDAwOTYgMi41NzQ1LS4wMDAwOTYgMy44NjIxLS4wMDAxNDQtLjkzNTI3IDQuODU2NSAzLjQ4MjkgOC40OTE4IDMuMTU1MSAxMy4yNzEtLjAzNzYyIDEuMTk2Ni0uNzY1ODcgMi4xODQ3LTEuMzIyMyAzLjE5MDEuMjEyNzQgMS4zNTE1LjQyODcgMi43MDI1LjY0MTgyIDQuMDU0OCAzLjU0MDMuMjQzMzcgOC4wMjMxLjIyOTY4IDkuOTMzOSAzLjg0NTQtOS41OTU1LjE0MjI2LTE5LjIwNC4xOTQxNy0yOC43OTgtLjAyNzUxIDIuMDc0NC0zLjU1ODcgNi41Nzg1LTMuNTcyNyAxMC4xODgtMy44MTYzLjIyNDM4LTEuMzczOC40NTEzOC0yLjc0NjUuNjgzMDUtNC4xMTgtLjgyMTE1LTEuMTI2OS0xLjgxOTEtMi4yODg4LTEuNzEzMy0zLjc4NjItLjA3MzAzLTQuNTY4NSA0LjM2OTQtNy45MDAxIDMuMzY5Mi0xMi42MTN6Ii8+PC9nPjwvZz48L3N2Zz4=')} +.is2d .knight.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMjEuNDcgMzAuMDA0Yy4zMzYzNS0yLjI3MjQuOTU2MjMtNC40ODg4IDEuODY5NS02LjU5NzEgMS40NzYxIDEuNzkzMSAyLjk0NzQgMy41OTI3IDQuNTQ5NyA1LjI3NjkgOC4wMDU4LS4yODM2IDE1Ljg2NyAzLjU4MjkgMjAuNTA5IDEwLjEwNCA3LjE3NDcgMTAuMDE1IDEwLjAzNCAyMy4zMzMgNi43MDY1IDM1LjI5LTExLjA4Ny4wMDQ5LTIyLjE3NC0uMDE0Ny0zMy4yNjEuMDEwNDEtMi4yODMyLTIuMTE5Mi0zLjExNDktNS43OTA2LS45MjEzOC04LjI4NDEgMy4zOTM4LTMuNTYzNSA3Ljg5MTYtNi4xNTYyIDEwLjI2My0xMC42MzQtMi41ODAyLjI3ODA5LTUuMTc0OC40Njg3Mi03Ljc2NzUuMjY1NzItMS41OTE5IDIuNTQyOS0zLjU4MzMgNS45MTkyLTcuMDQ2NyA1LjY3NDYtMi4zMTktLjI5MTU1LTQuODgwMi40NDQyMy02Ljk1MS0uOTQ5MjItMi4wMzc2LTEuMjQwMS0yLjE2MTMtNC4wMzctMS42NTg1LTYuMTIwOCAxLjIzMjctNC41NjU5IDYuMzE2OC02LjgwNzEgNy4zODctMTEuNDU0LjQwMzktMi4yMTE2IDIuMDgtMy43NTg0IDMuNjA3Ni01LjI1ODQtLjQ3Mzg4LTMuMzgyLS44NzA5NS02Ljc4MDgtLjg5NDIzLTEwLjIgMS4yMTE2Ljk0NjkgMi40MTcyIDEuOTAyNyAzLjYwNzcgMi44Nzc0eiIgZmlsbD0iI2ZmZiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4MDQ0MSIvPjxwYXRoIGQ9Im0yMS40NyAzMC4wMDRjLjMzNjM1LTIuMjcyNC45NTYyMy00LjQ4ODggMS44Njk1LTYuNTk3MSAxLjQ3NjEgMS43OTMxIDIuOTQ3NCAzLjU5MjcgNC41NDk3IDUuMjc2OSA4LjAwNTgtLjI4MzYgMTUuODY3IDMuNTgyOSAyMC41MDkgMTAuMTA0IDcuMTc0NyAxMC4wMTUgMTAuMDM0IDIzLjMzMyA2LjcwNjUgMzUuMjktMTEuMDg3LjAwNDktMjIuMTc0LS4wMTQ3LTMzLjI2MS4wMTA0MS0yLjI4MzItMi4xMTkyLTMuMTE0OS01Ljc5MDYtLjkyMTM4LTguMjg0MSAzLjM5MzgtMy41NjM1IDcuODkxNi02LjE1NjIgMTAuMjYzLTEwLjYzNC0yLjU4MDIuMjc4MDktNS4xNzQ4LjQ2ODcyLTcuNzY3NS4yNjU3Mi0xLjU5MTkgMi41NDI5LTMuNTgzMyA1LjkxOTItNy4wNDY3IDUuNjc0Ni0yLjMxOS0uMjkxNTUtNC44ODAyLjQ0NDIzLTYuOTUxLS45NDkyMi0yLjAzNzYtMS4yNDAxLTIuMTYxMy00LjAzNy0xLjY1ODUtNi4xMjA4IDEuMjMyNy00LjU2NTkgNi4zMTY4LTYuODA3MSA3LjM4Ny0xMS40NTQuNDAzOS0yLjIxMTYgMi4wOC0zLjc1ODQgMy42MDc2LTUuMjU4NC0uNDczODgtMy4zODItLjg3MDk1LTYuNzgwOC0uODk0MjMtMTAuMiAxLjIxMTYuOTQ2OSAyLjQxNzIgMS45MDI3IDMuNjA3NyAyLjg3NzR6Ii8+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0ibTIzLjY2NyAyOC4zNWMxLjY0MiAxLjI1OTggMy4yNTA2IDIuNTY1MyA0Ljk3MDUgMy43MjE0IDEuMzg0OS0uMjg2MSAyLjc2OS0uNTc0MSA0LjE1NTYtLjg2MTgxLjMzNTc5LjY1Mzc5LjY3MjUgMS4zMDc3IDEuMDEwMSAxLjk2MTdsMi45NjYyLS43MTQ5NyAxLjA1NjIgMi4yNTg2Yy4yMjEzOS40NzM0MyAxLjQzOTEtLjI3NzYyIDEuOTE4Ny0uMzcwMTcuMjYzMjcuODQ4MzEuNTI3NTkgMS42OTY4Ljc5Mjk1IDIuNTQ1NCAxLjEyNzYuMTUzNTkgMi4yNTc1LjMwNzM2IDMuMzg3OC40NjA4Ni4xOTg3NiAxLjA4OTQuMzk5MTQgMi4xNzg5LjYwMDAyIDMuMjY4OCAxLjE2ODEuMTg0NzkgMi4zMzczLjM2OTYyIDMuNTA3Ny41NTQ0OS0uMjgyNzcgMS4xMjUzLS41NjQzNiAyLjI1MDgtLjg0NDc2IDMuMzc2NSAxLjI4NDkuODIyNzEgMi41NzA4IDEuNjQ0OSAzLjg1ODEgMi40NjY5LS41MDE1NiAxLjI1NjctMS4wMDQxIDIuNTEyOS0xLjUwNDIgMy43Njk5IDEuMzQ2OS45MDUyOSAyLjY5NTUgMS44MDkgNC4wNDUyIDIuNzEzMi0uNzAzMjcgMS4yMDY3LTEuNDA3NiAyLjQxMjUtMi4xMDkxIDMuNjE5OC45MDY2OC45NDc3NSAxLjgxNTEgMS44OTQ5IDIuNzI1MyAyLjg0MTktLjgzMDY2IDEuMzUzOC0xLjY2MDcgMi43MDc3LTIuNDg5IDQuMDYyNy43NjkwNC44MTk3MSAxLjU0MDMgMS42NCAyLjMxMjYgMi40NjAyLS41MDI3NiAxLjgxMjItMS4wMDQxIDMuNjI0OS0xLjUwNTcgNS40Mzc4LTEwLjI2Ny0uMzg1OTktMjAuNTQzLS4yMzAwMy0zMC44MTUtLjI1NTgxLS4yMTM5OS0xLjMzNy0uOTA0NzYtMi45ODg4LjI2OTI0LTQuMDg2MiAzLjM0NjItMy4wNTA4IDcuMjcyOS01LjY0MDIgOS42Njc0LTkuNTkxNCAxLjI2NDQtMi4wMzY5IDEuNzIyOC00LjQxNzEgMi4zMTktNi43MDM2LTQuMDQxMSAyLjgwNjQtOC4zNDg5IDIuMzgwNC0xMi44NzQgMS41MzQ2IDEuMzk5OSAzLjQzNjYtMS44Nzk2IDUuNTIxLTUuMDQwMSA2LjI3MjcuMDEzMDUtLjc1ODk0LjAzOTEyLTIuMjc2OC4wNTIxNy0zLjAzNTgtMS4yNjY0Ljk1NzQ0LTIuNDk0MSAxLjk2NDEtMy43MTM0IDIuOTc5Ny0yLjQ5ODQtLjkxODczLTMuMDkxMi0zLjg5MjEtMS44NTUzLTYuMDc4IDEuNjIyMy0yLjM0NzggNC4xMDg4LTQuMDM2MiA1LjQxMzEtNi42MTY1LjgwNjk3LTIuMDkyMSAxLjE2MTMtNC40NDA4IDIuNzA5MS02LjE2NzkgMS41MTM5LTEuNzIxMSAyLjcwNzUtMy42NzU3IDMuODAwOS01LjY4MjMgMS4xNzg2LjczODYyIDIuMzU3NCAxLjQ3OSAzLjU3ODcgMi4xNDgzLS43MjI3MS0yLjg1OTctMy40NDU4LTUuMTA3LTIuMzY1OS04LjI5MTF6Ii8+PHBhdGggZD0ibTE5LjgyOCAzMS41MzljMS42MzgtLjc3NzYyIDIuMzY0OC45MTczNCAyLjI3MTkgMi4yNzQyLTEuNTIzMSAxLjU3NjYtMy4yMTY5LS43NTY0Mi0yLjI3MTktMi4yNzQyeiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4MDQ0MSIvPjxwYXRoIGQ9Im0xOS44MjggMzEuNTM5YzEuNjM4LS43Nzc2MiAyLjM2NDguOTE3MzQgMi4yNzE5IDIuMjc0Mi0xLjUyMzEgMS41NzY2LTMuMjE2OS0uNzU2NDItMi4yNzE5LTIuMjc0MnoiLz48L2c+PHBhdGggZD0ibTIyLjAxMiA0Mi41MTFjMS41MDg1LTEuMzYwMiAzLjg5NTMuMjI4MjMgNS42OTU5Ljc2NzI5LTEuOTkyMyAxLjExNTItNC44NTIzIDMuMDM1My02LjQ0ODcgMi4wNzQzLS42NDY2MS0uMzg5MjYuMDYxLTIuMjE3OC43NTI3Ny0yLjg0MTZ6Ii8+PHBhdGggZD0ibTEyLjY0IDUzLjk5NWMuNjc3OTYtLjY0NDMgMi43MDY3LS4xNTQwOSAxLjczMDguOTY1NDUtLjkwMzY5IDEuNTQwOC0zLjkwNjkuMjE3MjMtMS43MzA4LS45NjU0NXoiIGZpbGw9IiNmZmYiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODA0NDEiLz48cGF0aCBkPSJtMTIuNjQgNTMuOTk1Yy42Nzc5Ni0uNjQ0MyAyLjcwNjctLjE1NDA5IDEuNzMwOC45NjU0NS0uOTAzNjkgMS41NDA4LTMuOTA2OS4yMTcyMy0xLjczMDgtLjk2NTQ1eiIvPjwvZz48L3N2Zz4=')} +.is2d .bishop.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJtMjEuNDcgNzQuMTQ5Yy4zMzYzNS0uMDAwMDQ1Ljk1NjIzLS4wMDAwODggMS44Njk1LS4wMDAxMyAxLjQ3NjEuMDAwMDM1IDIuOTQ3NC4wMDAwNzEgNC41NDk3LjAwMDEwNCA4LjAwNTgtLjAwMDAwNiAxNS44NjcuMDAwMDcxIDIwLjUwOS4wMDAxOTkgNy4xNzQ3LjAwMDE5NyAxMC4wMzQuMDAwNDU5IDYuNzA2Ni4wMDA2OTUtMTEuMDg3IDAtMjIuMTc0LS4wMDAwMDEtMzMuMjYxIDAtMi4yODMyLS4wMDAwNDItMy4xMTQ5LS4wMDAxMTQtLjkyMTM4LS4wMDAxNjMgMy4zOTM4LS4wMDAwNyA3Ljg5MTYtLjAwMDEyMSAxMC4yNjMtLjAwMDIxLTIuNTgwMi4wMDAwMDYtNS4xNzQ4LjAwMDAxLTcuNzY3NS4wMDAwMDYtMS41OTE5LjAwMDA1LTMuNTgzMy4wMDAxMTYtNy4wNDY4LjAwMDExMS0yLjMxOS0uMDAwMDA1LTQuODgwMi4wMDAwMDktNi45NTExLS4wMDAwMTgtMi4wMzc2LS4wMDAwMjUtMi4xNjEzLS4wMDAwOC0xLjY1ODUtLjAwMDEyMSAxLjIzMjctLjAwMDA5IDYuMzE2OC0uMDAwMTM0IDcuMzg3LS4wMDAyMjUuNDAzOS0uMDAwMDQ0IDIuMDgtLjAwMDA3NCAzLjYwNzYtLjAwMDEwNC0uNDczODgtLjAwMDA2Ni0uODcwOTUtLjAwMDEzMy0uODk0MjMtLjAwMDIwMSAxLjIxMTYuMDAwMDE5IDIuNDE3Mi4wMDAwMzggMy42MDc3LjAwMDA1N3oiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wMDAzNTciLz48cGF0aCBkPSJtMjEuNDcgNzQuMTQ5Yy4zMzYzNS0uMDAwMDQ1Ljk1NjIzLS4wMDAwODggMS44Njk1LS4wMDAxMyAxLjQ3NjEuMDAwMDM1IDIuOTQ3NC4wMDAwNzEgNC41NDk3LjAwMDEwNCA4LjAwNTgtLjAwMDAwNiAxNS44NjcuMDAwMDcxIDIwLjUwOS4wMDAxOTkgNy4xNzQ3LjAwMDE5NyAxMC4wMzQuMDAwNDU5IDYuNzA2Ni4wMDA2OTUtMTEuMDg3IDAtMjIuMTc0LS4wMDAwMDEtMzMuMjYxIDAtMi4yODMyLS4wMDAwNDItMy4xMTQ5LS4wMDAxMTQtLjkyMTM4LS4wMDAxNjMgMy4zOTM4LS4wMDAwNyA3Ljg5MTYtLjAwMDEyMSAxMC4yNjMtLjAwMDIxLTIuNTgwMi4wMDAwMDYtNS4xNzQ4LjAwMDAxLTcuNzY3NS4wMDAwMDYtMS41OTE5LjAwMDA1LTMuNTgzMy4wMDAxMTYtNy4wNDY4LjAwMDExMS0yLjMxOS0uMDAwMDA1LTQuODgwMi4wMDAwMDktNi45NTExLS4wMDAwMTgtMi4wMzc2LS4wMDAwMjUtMi4xNjEzLS4wMDAwOC0xLjY1ODUtLjAwMDEyMSAxLjIzMjctLjAwMDA5IDYuMzE2OC0uMDAwMTM0IDcuMzg3LS4wMDAyMjUuNDAzOS0uMDAwMDQ0IDIuMDgtLjAwMDA3NCAzLjYwNzYtLjAwMDEwNC0uNDczODgtLjAwMDA2Ni0uODcwOTUtLjAwMDEzMy0uODk0MjMtLjAwMDIwMSAxLjIxMTYuMDAwMDE5IDIuNDE3Mi4wMDAwMzggMy42MDc3LjAwMDA1N3oiLz48cGF0aCBkPSJtMjMuNjY3IDc0LjE0OWMxLjY0Mi4wMDAwMjUgMy4yNTA2LjAwMDA1MSA0Ljk3MDUuMDAwMDc0IDEuMzg0OS0uMDAwMDA2IDIuNzY5LS4wMDAwMTIgNC4xNTU2LS4wMDAwMTcuMzM1NzkuMDAwMDEzLjY3MjUuMDAwMDI2IDEuMDEwMS4wMDAwMzhsMi45NjYyLS4wMDAwMTQgMS4wNTYyLjAwMDA0NWMuMjIxMzkuMDAwMDA5IDEuNDM5MS0uMDAwMDA2IDEuOTE4Ny0uMDAwMDA4LjI2MzI3LjAwMDAxNy41Mjc1OS4wMDAwMzQuNzkyOTUuMDAwMDUxIDEuMTI3Ni4wMDAwMDMgMi4yNTc1LjAwMDAwNiAzLjM4NzguMDAwMDA5LjE5ODc2LjAwMDAyMS4zOTkxNC4wMDAwNDMuNjAwMDIuMDAwMDY0IDEuMTY4MS4wMDAwMDQgMi4zMzczLjAwMDAwNyAzLjUwNzcuMDAwMDExLS4yODI3Ny4wMDAwMjItLjU2NDM2LjAwMDA0NC0uODQ0NzYuMDAwMDY2IDEuMjg0OS4wMDAwMTcgMi41NzA4LjAwMDAzMyAzLjg1ODEuMDAwMDQ5LS41MDE1Ni4wMDAwMjUtMS4wMDQxLjAwMDA0OS0xLjUwNDIuMDAwMDc0IDEuMzQ2OS4wMDAwMTggMi42OTU1LjAwMDAzNiA0LjA0NTIuMDAwMDU0LS43MDMyNy4wMDAwMjMtMS40MDc2LjAwMDA0Ny0yLjEwOTEuMDAwMDcxLjkwNjY4LjAwMDAxOCAxLjgxNTEuMDAwMDM3IDIuNzI1NC4wMDAwNTYtLjgzMDY2LjAwMDAyNi0xLjY2MDcuMDAwMDUzLTIuNDg5LjAwMDA4Ljc2OTA1LjAwMDAxNiAxLjU0MDMuMDAwMDMyIDIuMzEyNi4wMDAwNDgtLjUwMjc2LjAwMDAzNi0xLjAwNDEuMDAwMDcxLTEuNTA1Ny4wMDAxMDctMTAuMjY3LS4wMDAwMDctMjAuNTQzLS4wMDAwMDQtMzAuODE1LS4wMDAwMDUtLjIxMzk5LS4wMDAwMjYtLjkwNDc2LS4wMDAwNTkuMjY5MjQtLjAwMDA4IDMuMzQ2Mi0uMDAwMDYgNy4yNzI5LS4wMDAxMTEgOS42Njc0LS4wMDAxODkgMS4yNjQ0LS4wMDAwNCAxLjcyMjgtLjAwMDA4NyAyLjMxOS0uMDAwMTMyLTQuMDQxMS4wMDAwNTUtOC4zNDkuMDAwMDQ3LTEyLjg3NC4wMDAwMyAxLjM5OTkuMDAwMDY4LTEuODc5Ni4wMDAxMDktNS4wNDAxLjAwMDEyNC4wMTMwNS0uMDAwMDE1LjAzOTEyLS4wMDAwNDUuMDUyMTctLjAwMDA2LTEuMjY2NC4wMDAwMTktMi40OTQxLjAwMDAzOS0zLjcxMzQuMDAwMDU5LTIuNDk4NC0uMDAwMDE5LTMuMDkxMi0uMDAwMDc3LTEuODU1My0uMDAwMTIgMS42MjIzLS4wMDAwNDYgNC4xMDg4LS4wMDAwOCA1LjQxMzEtLjAwMDEzLjgwNjk3LS4wMDAwNDIgMS4xNjEzLS4wMDAwODggMi43MDkxLS4wMDAxMjIgMS41MTM5LS4wMDAwMzQgMi43MDc1LS4wMDAwNzIgMy44MDA5LS4wMDAxMTIgMS4xNzg2LjAwMDAxNSAyLjM1NzQuMDAwMDMgMy41Nzg3LjAwMDA0My0uNzIyNzEtLjAwMDA1Ny0zLjQ0NTgtLjAwMDEwMS0yLjM2NTktLjAwMDE2NHoiLz48cGF0aCBkPSJtMTkuODI4IDc0LjE0OWMxLjYzOC0uMDAwMDE1IDIuMzY0OC4wMDAwMTggMi4yNzE5LjAwMDA0NS0xLjUyMzEuMDAwMDMxLTMuMjE2OS0uMDAwMDE1LTIuMjcxOS0uMDAwMDQ1eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjAwMDM1NyIvPjxwYXRoIGQ9Im0xOS44MjggNzQuMTQ5YzEuNjM4LS4wMDAwMTUgMi4zNjQ4LjAwMDAxOCAyLjI3MTkuMDAwMDQ1LTEuNTIzMS4wMDAwMzEtMy4yMTY5LS4wMDAwMTUtMi4yNzE5LS4wMDAwNDV6Ii8+PHBhdGggZD0ibTIyLjAxMiA3NC4xNDljMS41MDg1LS4wMDAwMjcgMy44OTUzLjAwMDAwNSA1LjY5Ni4wMDAwMTUtMS45OTIzLjAwMDAyMi00Ljg1MjMuMDAwMDYtNi40NDg3LjAwMDA0MS0uNjQ2NjEtLjAwMDAwOC4wNjEtLjAwMDA0My43NTI3Ny0uMDAwMDU2eiIvPjxwYXRoIGQ9Im0xMi42NCA3NC4xNWMuNjc3OTYtLjAwMDAxMiAyLjcwNjctLjAwMDAwMyAxLjczMDguMDAwMDE5LS45MDM2OS4wMDAwMzEtMy45MDY5LjAwMDAwNS0xLjczMDgtLjAwMDAxOXoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wMDAzNTciLz48cGF0aCBkPSJtMTIuNjQgNzQuMTVjLjY3Nzk2LS4wMDAwMTIgMi43MDY3LS4wMDAwMDMgMS43MzA4LjAwMDAxOS0uOTAzNjkuMDAwMDMxLTMuOTA2OS4wMDAwMDUtMS43MzA4LS4wMDAwMTl6Ii8+PHBhdGggZD0ibTI1LjE0IDI0LjdjMS4yNjI2LTIuMjAwMyA0LjkyOTItMS44NjYgNS43NjQ0LjU0MTYuNzExMTEgMS41OTAyLS41OTA0MyAzLjAxNDQtMS4xNTEzIDQuNDE1My44MTYzNi43NzQgMS42MzUgMS41NDc1IDIuNDU2NiAyLjMyMDEuODY2NjgtLjg5NDQ3IDEuNzI5Mi0xLjc5MzUgMi41ODktMi42OTc0LS4zNjE2Mi0xLjQwMjctMS41MjYxLTIuOTUzMi0uNjE1MjgtNC4zNzkgMS4wNTI1LTIuMTE3NiA0LjQ3NDktMi4yOTQ4IDUuNjQxNS0uMTg3ODEgMS4wNzc3IDEuNDQxNS0uMDMzMzUgMy4xMDMxLS40NTE1MiA0LjU1NiAyLjU1ODQgMy40MjY1IDQuOTY3NCA3LjA5MzEgNi4wNTgxIDExLjI3OSAxLjQzMTkgNS4yMTgzLjUzNTcyIDEwLjc3OC0xLjI0NDYgMTUuNzk1LTEuMzAxIDMuMTI1My0uNzg0NzggNi41ODkxLTEuMzg4MyA5Ljg1OTYgNC41MTcyLS41NjgyIDkuNjkzNy0xLjU2NjQgMTMuNzYyIDEuMDgzMiAyLjI1MjIgMS41MDY5IDIuMDE0MSA0LjQzODQgMS45NTkzIDYuODAxNWgtLjkwOTM3Yy02LjE1NS0xLjc5Mi0xMi42MDItMS4zNS0xOC45MjEtMS4xOTItMy4xOTYtNC4xMjYtMTAuMDIzLTQuMDg5LTEzLjIzMyAwLTYuMzA0LS4xNTEtMTIuNzQ1LS42MDctMTguODggMS4xOTJoLTEuMTI5M2MuMTY0OC0yLjM1NS0uMTAzNC01LjI5NSAyLjE0MjQtNi43OTcgNC4wNjY5LTIuNjUgOS4yNDI5LTEuNjU5IDEzLjc2MS0xLjA4OC0uMzY5LTIuNTMzLS41NDEtNS4wODktLjU0Ni03LjY0OC0yLjM1MS00LjI2NC00LjQzOS05LjEzNC0zLjQ5My0xNC4xMDMgMS4xNjgtNS42NTkgNC44NDQtMTAuMzIgOC4zMjctMTQuNzYyLS4zODItMS41OTMtMS42MDItMy40MTctLjQ5OC00Ljk5eiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4MDIyIi8+PC9nPjxwYXRoIGQ9Im0yNS4xNCAyNC43YzEuMjYyNi0yLjIwMDMgNC45MjkyLTEuODY2IDUuNzY0NC41NDE2LjcxMTExIDEuNTkwMi0uNTkwNDMgMy4wMTQ0LTEuMTUxMyA0LjQxNTMuODE2MzYuNzc0IDEuNjM1IDEuNTQ3NSAyLjQ1NjYgMi4zMjAxLjg2NjY4LS44OTQ0NyAxLjcyOTItMS43OTM1IDIuNTg5LTIuNjk3NC0uMzYxNjItMS40MDI3LTEuNTI2MS0yLjk1MzItLjYxNTI4LTQuMzc5IDEuMDUyNS0yLjExNzYgNC40NzQ5LTIuMjk0OCA1LjY0MTUtLjE4NzgxIDEuMDc3NyAxLjQ0MTUtLjAzMzM1IDMuMTAzMS0uNDUxNTIgNC41NTYgMi41NTg0IDMuNDI2NSA0Ljk2NzQgNy4wOTMxIDYuMDU4MSAxMS4yNzkgMS40MzE5IDUuMjE4My41MzU3MiAxMC43NzgtMS4yNDQ2IDE1Ljc5NS0xLjMwMSAzLjEyNTMtLjc4NDc4IDYuNTg5MS0xLjM4ODMgOS44NTk2IDQuNTE3Mi0uNTY4MiA5LjY5MzctMS41NjY0IDEzLjc2MiAxLjA4MzIgMi4yNTIyIDEuNTA2OSAyLjAxNDEgNC40Mzg0IDEuOTU5MyA2LjgwMTVoLS45MDkzN2MtNi4xNTUtMS43OTItMTIuNjAyLTEuMzUtMTguOTIxLTEuMTkyLTMuMTk2LTQuMTI2LTEwLjAyMy00LjA4OS0xMy4yMzMgMC02LjMwNC0uMTUxLTEyLjc0NS0uNjA3LTE4Ljg4IDEuMTkyaC0xLjEyOTNjLjE2NDgtMi4zNTUtLjEwMzQtNS4yOTUgMi4xNDI0LTYuNzk3IDQuMDY2OS0yLjY1IDkuMjQyOS0xLjY1OSAxMy43NjEtMS4wODgtLjM2OS0yLjUzMy0uNTQxLTUuMDg5LS41NDYtNy42NDgtMi4zNTEtNC4yNjQtNC40MzktOS4xMzQtMy40OTMtMTQuMTAzIDEuMTY4LTUuNjU5IDQuODQ0LTEwLjMyIDguMzI3LTE0Ljc2Mi0uMzgyLTEuNTkzLTEuNjAyLTMuNDE3LS40OTgtNC45OXoiLz48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJtMjYuNjA3IDI1LjQ3NWMuODYzNzYtLjc2OTQ5IDIuNTY2My0uNzU1MTQgMi40NDk5Ljc0MTAxLjA2Mjc3IDIuMjUtMy4zNjA4IDEuMjk0OS0yLjQ0OTktLjc0MTAxeiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4MDIyIi8+PHBhdGggZD0ibTI2LjYwNyAyNS40NzVjLjg2Mzc2LS43Njk0OSAyLjU2NjMtLjc1NTE0IDIuNDQ5OS43NDEwMS4wNjI3NyAyLjI1LTMuMzYwOCAxLjI5NDktMi40NDk5LS43NDEwMXoiLz48cGF0aCBkPSJtMzUuODU1IDI1LjY3OWMxLjM0MDgtMS45MzgyIDIuODkxOC4xODYwMSAyLjQzNTUgMS43ODk1LTEuMjcwMS4xMjkzNi0yLjkxNDgtLjEzMjAzLTIuNDM1NS0xLjc4OTV6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDgwMjIiLz48cGF0aCBkPSJtMzUuODU1IDI1LjY3OWMxLjM0MDgtMS45MzgyIDIuODkxOC4xODYwMSAyLjQzNTUgMS43ODk1LTEuMjcwMS4xMjkzNi0yLjkxNDgtLjEzMjAzLTIuNDM1NS0xLjc4OTV6Ii8+PHBhdGggZD0ibTMzLjMxIDMzLjc5M2MxLjI3ODMtMS4zMzMyIDIuNTQ2MS0yLjY3NyAzLjgwODEtNC4wMjczIDIuODAzNCA0LjAyMTEgNS42NTgzIDguMjM2OCA2LjU1NjQgMTMuMTUyLjY2NDQyIDMuMzI5Ni4yMDU3MyA2Ljc0ODgtLjY0MDA5IDkuOTk5Ny0uODA0MTktNy4zNTI5LTQuNTY2NC0xMy45NDctOS43MjQzLTE5LjEyNXoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODAyMiIvPjxwYXRoIGQ9Im0zMy4zMSAzMy43OTNjMS4yNzgzLTEuMzMzMiAyLjU0NjEtMi42NzcgMy44MDgxLTQuMDI3MyAyLjgwMzQgNC4wMjExIDUuNjU4MyA4LjIzNjggNi41NTY0IDEzLjE1Mi42NjQ0MiAzLjMyOTYuMjA1NzMgNi43NDg4LS42NDAwOSA5Ljk5OTctLjgwNDE5LTcuMzUyOS00LjU2NjQtMTMuOTQ3LTkuNzI0My0xOS4xMjV6Ii8+PHBhdGggZD0ibTI3LjczMSAzMC40M2M1LjE2NjQgNS4wNjM0IDkuOTIzNiAxMC44MzcgMTIuNDk2IDE3LjY3Ny45ODgyOSAyLjQ0ODUuOTE2NzYgNS4xMzg3LjIxNjMzIDcuNjQ5OC01Ljc2ODUtMi4xNzAyLTEyLjI5MS0yLjA5MjYtMTguMDktLjA3MTc5LTIuMzgxMi0yLjg4MDEtMy45OTIyLTYuNjc1Ny0yLjk4MzgtMTAuNDQ2IDEuNDE4OS01LjUzMjYgNC4xODQtMTAuODUzIDguMzYwOS0xNC44MDl6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDgwMjIiLz48cGF0aCBkPSJtMjcuNzMxIDMwLjQzYzUuMTY2NCA1LjA2MzQgOS45MjM2IDEwLjgzNyAxMi40OTYgMTcuNjc3Ljk4ODI5IDIuNDQ4NS45MTY3NiA1LjEzODcuMjE2MzMgNy42NDk4LTUuNzY4NS0yLjE3MDItMTIuMjkxLTIuMDkyNi0xOC4wOS0uMDcxNzktMi4zODEyLTIuODgwMS0zLjk5MjItNi42NzU3LTIuOTgzOC0xMC40NDYgMS40MTg5LTUuNTMyNiA0LjE4NC0xMC44NTMgOC4zNjA5LTE0LjgwOXoiLz48cGF0aCBkPSJtMjMuMDM3IDU4LjAwOWM0LjAyMDEtMi4xMDUgOC43ODc4LTEuNjk1IDEzLjE2Ny0xLjQzODMgMS43MjU1LjM1ODQyIDQuMjE0My4yNDc5MyA0Ljk4NzYgMi4xOTExLS4zNDEwNS40MzM3Mi0xLjAyMzEgMS4zMDEyLTEuMzY0MiAxLjczNDkuNzI4MDUgMS4wNTM0IDEuMTA4NCAyLjI2OTUgMS40NDcxIDMuNDkzMi02LjA3NDYtMS4wOTEzLTEyLjMyOC0xLjA5LTE4LjQwMi0uMDAwMDI1LjMzMDU1LTEuMjExNy43MTAxMS0yLjQxNjcgMS40MzMzLTMuNDU5LS42OTk3OC0uNzE0MTMtMS4xMjI4LTEuNTU0Ny0xLjI2OTEtMi41MjE5eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4MDIyIi8+PHBhdGggZD0ibTIzLjAzNyA1OC4wMDljNC4wMjAxLTIuMTA1IDguNzg3OC0xLjY5NSAxMy4xNjctMS40MzgzIDEuNzI1NS4zNTg0MiA0LjIxNDMuMjQ3OTMgNC45ODc2IDIuMTkxMS0uMzQxMDUuNDMzNzItMS4wMjMxIDEuMzAxMi0xLjM2NDIgMS43MzQ5LjcyODA1IDEuMDUzNCAxLjEwODQgMi4yNjk1IDEuNDQ3MSAzLjQ5MzItNi4wNzQ2LTEuMDkxMy0xMi4zMjgtMS4wOS0xOC40MDItLjAwMDAyNS4zMzA1NS0xLjIxMTcuNzEwMTEtMi40MTY3IDEuNDMzMy0zLjQ1OS0uNjk5NzgtLjcxNDEzLTEuMTIyOC0xLjU1NDctMS4yNjkxLTIuNTIxOXoiLz48cGF0aCBkPSJtMzAuNzExIDU5LjEzNWMxLjI2ODctLjQ4Mjk2IDMuMTc1Ny0uNDM1NzggMy41MzE1IDEuMTczNC0xLjI5MjIuODI0OTQtMi45MDE1LjgwMTk1LTQuMjQ4OS4xMjc5NS4xNzkzNS0uMzI1MzQuNTM4MDYtLjk3Ni43MTc0MS0xLjMwMTN6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDgwMjIiLz48L2c+PHBhdGggZD0ibTMwLjcxMSA1OS4xMzVjMS4yNjg3LS40ODI5NiAzLjE3NTctLjQzNTc4IDMuNTMxNSAxLjE3MzQtMS4yOTIyLjgyNDk0LTIuOTAxNS44MDE5NS00LjI0ODkuMTI3OTUuMTc5MzUtLjMyNTM0LjUzODA2LS45NzYuNzE3NDEtMS4zMDEzeiIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im0yMy44MzggNjYuMTI0YzUuMjQzOS0xLjczNDIgMTEuMjI1LTEuNzM1NyAxNi40NjguMDAzNC0yLjI0MDIgMi4wNDgzLTUuNDMzMSAxLjYzNzQtOC4yMjUzIDEuNzYxNi0yLjc5OTctLjEyMzMyLTYuMDAyOS4yOTE0NS04LjI0MjktMS43NjUxeiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4MDIyIi8+PHBhdGggZD0ibTIzLjgzOCA2Ni4xMjRjNS4yNDM5LTEuNzM0MiAxMS4yMjUtMS43MzU3IDE2LjQ2OC4wMDM0LTIuMjQwMiAyLjA0ODMtNS40MzMxIDEuNjM3NC04LjIyNTMgMS43NjE2LTIuNzk5Ny0uMTIzMzItNi4wMDI5LjI5MTQ1LTguMjQyOS0xLjc2NTF6Ii8+PHBhdGggZD0ibTYuODc4MSA3MS4zMzFjLjYzNzU3LTEuOTc2IDIuMjE3OC0zLjQxOTcgNC4zMjY4LTMuNTQxOSA1LjU5MjMtLjY3NjEyIDExLjI2OC4zMDA0IDE2LjY5MyAxLjY1MjEtNi43MTM1IDIuMzc2OS0xNC4wMjQgMS41NjI5LTIxLjAyIDEuODg5OHoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODAyMiIvPjxwYXRoIGQ9Im02Ljg3ODEgNzEuMzMxYy42Mzc1Ny0xLjk3NiAyLjIxNzgtMy40MTk3IDQuMzI2OC0zLjU0MTkgNS41OTIzLS42NzYxMiAxMS4yNjguMzAwNCAxNi42OTMgMS42NTIxLTYuNzEzNSAyLjM3NjktMTQuMDI0IDEuNTYyOS0yMS4wMiAxLjg4OTh6Ii8+PHBhdGggZD0ibTM2LjI1NSA2OS40MjhjNS42NTUyLTEuMzM4OSAxMS41OTctMi40ODIzIDE3LjM5Ny0xLjQ5MzEgMS44ODc2LjE5OTY5IDIuOTU1NiAxLjc3MDkgMy42MjI2IDMuMzk1Ni02Ljk5MzQtLjMzNjM3LTE0LjMxOC41MDk5NC0yMS4wMi0xLjkwMjV6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDgwMjIiLz48cGF0aCBkPSJtMzYuMjU1IDY5LjQyOGM1LjY1NTItMS4zMzg5IDExLjU5Ny0yLjQ4MjMgMTcuMzk3LTEuNDkzMSAxLjg4NzYuMTk5NjkgMi45NTU2IDEuNzcwOSAzLjYyMjYgMy4zOTU2LTYuOTkzNC0uMzM2MzctMTQuMzE4LjUwOTk0LTIxLjAyLTEuOTAyNXoiLz48L2c+PC9nPjwvc3ZnPg==')} +.is2d .rook.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMTUuMDM5IDI2Ljc4NWMyLjEwMzctLjAwMDA5NiA0LjIwODgtLjAwMDEzMiA2LjMxNTQtLjAwMDEzMi0uMDAxOSAxLjU3OS0uMDAyNSAzLjE1NzgtLjAwMDUzNiA0LjczNjkgMi4xMDQtLjAwMDIxNyA0LjIwOTMtLjAwMDI1MiA2LjMxNjQtLjAwMDI4OS0uMDAyMS0xLjU3OS0uMDAyNS0zLjE1NzgtLjAwMDU2LTQuNzM2NyAyLjkzMDYuMDAwMTQ1IDUuODYyMi4wMDAyMDUgOC43OTUxLjAwMDYwMi0uMDAxOSAxLjU3ODYtLjAwMjMgMy4xNTctLjAwMDMzOSA0LjczNTcgMi4wNjY3LjAwMDA4NCA0LjEzNDcuMDAwNDkzIDYuMjA0Ni4wMDA4NzYtLjAwMjEtMS41NzkyLS4wMDI3LTMuMTU4MS0uMDAwNDUtNC43MzcxIDIuMTAzNS4wMDAwNzEgNC4yMDg1LjAwMDA3MSA2LjMxNTQuMDAwMDU5LS4wMDE3IDMuMTc3Ni0uMDAxNiA2LjM1NSAwIDkuNTMyNi0xLjMxOCAxLjQ3NzUtMi42MzQxIDIuOTU1NS0zLjk0OTEgNC40MzM2LjAwNTcgNi4yODkzLS4wMDQ1IDEyLjU3OS4wMDUgMTguODY4IDIuNDgxNCAyLjc4MDIgMy41NTk1IDUuNTYyOSA2LjI4OTIgOC4wNzIyLS4wMDA0OTYgMi4xNTIzLjAwMDU0NiA0LjMwNDkuMDAxNCA2LjQ1ODEtMTIuODg3LjAwMS0yNS43NzMuMDAxLTM4LjY2LjAwMS0uMDAwODc2LTIuMTQ2NS0uMDAwODc2LTQuMjkyNi4wMDA4NzYtNi40MzgzIDMuMDk3My0xLjkzOTEgMy42MjI3LTUuNzY0IDYuMzA5My04LjEwNzkuMDEyNTgtNi4yMzg4LjAwMTItMTIuNDc3LjAwNjEtMTguNzE2LTEuMzE4Ny0xLjQ2OTMtMi42MzUtMi45Mzk1LTMuOTUwMS00LjQwOTkuMDAzNC0zLjIzMDkuMDAyLTYuNDYxNi4wMDIzLTkuNjkyNHoiLz48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJtMTcuNDA4IDI5LjE1MmMuNTA4NTcuMDAwNzEgMS41MjU3LjAwMjEgMi4wMzQzLjAwMjgtLjAwMjcgMS41NzgxLS4wMDMzIDMuMTU2MS0uMDAxMyA0LjczNDQgMy41MzE1LjAwMDYwMyA3LjA2MzguMDAwMTIgMTAuNTk3LjAwMDQyMi0uMDAyLTEuNTc5MS0uMDAyMy0zLjE1NzktLjAwMDIxNC00LjczNjggMS4zOTk0LjAwMDEzMiAyLjc5OTkuMDAwMjc4IDQuMjA0My4wMDA3MS0uMDAxOSAxLjU3ODUtLjAwMjUgMy4xNTY5LS4wMDA4MDMgNC43MzU2IDMuNTk3Ni4wMDA2NTEgNy4xOTYuMDAwMzYyIDEwLjc5NS4wMDAzNS0uMDAyMi0xLjU3ODktLjAwMjMtMy4xNTc2LjAwMDA3Mi00LjczNjMuMzk0NzEtLjAwMDA3MyAxLjE4NDEtLjAwMDE5MiAxLjU3ODgtLjAwMDI2NS0uMDAxMiAyLjI1NTItLjAwMTIgNC41MTAzLS4wMDIyIDYuNzY1Ni0xLjMwOTUgMS4xNjQ5LTIuNjE2MiAyLjMzMDUtMy45MjE2IDMuNDk3LTcuNjM5LS4wMDAxNDUtMTUuMjc3LS4wMDAyOS0yMi45MTYuMDAwMDYtLjc5MTQzLS44ODE5NS0xLjU4MTQtMS43NjQxLTIuMzY4Ni0yLjY0NjEtLjAwMDgwMy0yLjUzOTMtLjAwMjgtNS4wNzg0LjAwMDMtNy42MTc1eiIvPjxwYXRoIGQ9Im0yMS4zNTQgNDEuNzg0YzcuMTA0My0uMDAwMDEyIDE0LjIwOS0uMDAwMDk2IDIxLjMxNC4wMDAwMzYtLjAwMDUwNSA1LjUyNTktLjAwMDY4NyAxMS4wNTIuMDAwMTAyIDE2LjU3OC03LjEwNTMtLjAwMDI0MS0xNC4yMS0uMDAwMDYtMjEuMzE0LS4wMDAwOTYtLjAwMDU2Mi01LjUyNi0uMDAwNTE0LTExLjA1Mi0uMDAwMDQxLTE2LjU3OHoiLz48cGF0aCBkPSJtMjAuODE0IDYwLjcxOWM3LjQ3ODUuMDIzOTggMTQuOTU3LjAwNzcgMjIuNDM3LjAwODYgMi4zMjA0IDIuMTkxMSAzLjM0MzMgNC44MDQzIDUuNzMyMiA2Ljk4NDQtLjAwMzEgMS4zNTYxLS4wMDIxIDIuNzEyOC4wMDIyIDQuMDcwMi0xMS4zMTYtLjAwMDIxNi0yMi42MzItLjAwMDMyNS0zMy45NDcuMDAwMDQ4LS4wMDA5NDktMS4zNTY4LS4wMDA2MTYtMi43MTI4LjAwMjMtNC4wNjg0IDIuNzY2OC0xLjY3NzYgMy4zNDUtNS4wMDc5IDUuNzczOC02Ljk5NDl6Ii8+PC9nPjwvZz48L3N2Zz4=')} +.is2d .queen.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMTkuNzEgMjYuNTAzYy4yNDg2Ni0zLjQzMjQgNS4yNTU2LTQuNTQ2NCA3LjEzODItMS43OTQ3IDEuMjc4OSAxLjUyNTUuNDE5MDggMy40ODE5LS4xNTg3MiA1LjA5NTEgMS42OTQ4IDMuNTEzNSAzLjQzODQgNy4wMDM1IDUuMTY1MiAxMC41MDIgMS44MzYtMy41MTg3IDMuNjY0OC03LjA0MTQgNS41MDYxLTEwLjU1OC0uNTQzMjQtMS40OTc3LTEuNDMzMy0zLjIwMDctLjQyNzM0LTQuNzI2MSAxLjY5NTItMy4wODc3IDcuMjEwNC0yLjE1MzYgNy40MzE0IDEuNDg5NC4zNzMwOCAxLjk4NC0xLjMxNTUgMy4yNDQ4LTIuNjM3OSA0LjM0NzIgMS4yNjMgNS4xOTE5IDIuNTMzNyAxMC4zODIgMy44MDQ5IDE1LjU3MiAyLjQzNDMtMS44Nzc0IDQuODgzNS0zLjczNjkgNy4yOTU4LTUuNjQ1NS0uMDE0MTUtMS42MTI3LS4zMzE0NC0zLjY3NzMgMS4zNDI3LTQuNjI0OSAyLjA5NTctMS41Njg4IDUuNDE0MS4zMjU3NCA1LjEyNDEgMi45MjgxLjA4NDU1IDIuMDE0My0xLjk1OSAyLjc3Mi0zLjQxNDMgMy41NDMyLTEuOTQ5NCA0LjMwODctNC4wODUyIDguNTQ1Mi01LjgxNyAxMi45NDQtLjc1NDQ5IDQuODE1NC0uOTI5NzIgOS43MDg2LTEuNTMxOCAxNC41NDctNi40NDA4IDQuMDEzNC0xNC4zMzYgNC4zMDgxLTIxLjY4OCAzLjc0ODktNC4wMTgtLjI3Ny04LjA0Mi0xLjMyMy0xMS4zNTEtMy42OTUtLjcwMS00Ljg2NC0uOTkyLTkuNzg5LTEuODUyLTE0LjYyNS0xLjY1NS00LjM5OS0zLjY3ODgtOC42NTUtNS41NDk1LTEyLjk2NS0xLjQ2NDQtLjcxOC0zLjQyMjctMS40ODYtMy4zNzk0LTMuNDUyLS4zNjA3LTIuODA2IDMuNDE4NS00LjY4NiA1LjQ0MzktMi43MjQgMS40NDcxIDEuMDEzMS45NjU4OSAyLjg3MDMuOTM0NjEgNC4zNTM3IDIuMzY1NCAxLjg4MzYgNC43MjE2IDMuNzc5MiA3LjA4NDMgNS42NjkxIDEuMzY3NC01LjIwMiAyLjc0NjUtMTAuNDAxIDQuMTA1OC0xNS42MDUtMS4zMjI1LTEuMDg5Ni0yLjk0NjItMi4zNjYtMi41NzA3LTQuMzIyNXoiIGZpbGw9IiNmZmYiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODQyNDciLz48cGF0aCBkPSJtMTkuNzEgMjYuNTAzYy4yNDg2Ni0zLjQzMjQgNS4yNTU2LTQuNTQ2NCA3LjEzODItMS43OTQ3IDEuMjc4OSAxLjUyNTUuNDE5MDggMy40ODE5LS4xNTg3MiA1LjA5NTEgMS42OTQ4IDMuNTEzNSAzLjQzODQgNy4wMDM1IDUuMTY1MiAxMC41MDIgMS44MzYtMy41MTg3IDMuNjY0OC03LjA0MTQgNS41MDYxLTEwLjU1OC0uNTQzMjQtMS40OTc3LTEuNDMzMy0zLjIwMDctLjQyNzM0LTQuNzI2MSAxLjY5NTItMy4wODc3IDcuMjEwNC0yLjE1MzYgNy40MzE0IDEuNDg5NC4zNzMwOCAxLjk4NC0xLjMxNTUgMy4yNDQ4LTIuNjM3OSA0LjM0NzIgMS4yNjMgNS4xOTE5IDIuNTMzNyAxMC4zODIgMy44MDQ5IDE1LjU3MiAyLjQzNDMtMS44Nzc0IDQuODgzNS0zLjczNjkgNy4yOTU4LTUuNjQ1NS0uMDE0MTUtMS42MTI3LS4zMzE0NC0zLjY3NzMgMS4zNDI3LTQuNjI0OSAyLjA5NTctMS41Njg4IDUuNDE0MS4zMjU3NCA1LjEyNDEgMi45MjgxLjA4NDU1IDIuMDE0My0xLjk1OSAyLjc3Mi0zLjQxNDMgMy41NDMyLTEuOTQ5NCA0LjMwODctNC4wODUyIDguNTQ1Mi01LjgxNyAxMi45NDQtLjc1NDQ5IDQuODE1NC0uOTI5NzIgOS43MDg2LTEuNTMxOCAxNC41NDctNi40NDA4IDQuMDEzNC0xNC4zMzYgNC4zMDgxLTIxLjY4OCAzLjc0ODktNC4wMTgtLjI3Ny04LjA0Mi0xLjMyMy0xMS4zNTEtMy42OTUtLjcwMS00Ljg2NC0uOTkyLTkuNzg5LTEuODUyLTE0LjYyNS0xLjY1NS00LjM5OS0zLjY3ODgtOC42NTUtNS41NDk1LTEyLjk2NS0xLjQ2NDQtLjcxOC0zLjQyMjctMS40ODYtMy4zNzk0LTMuNDUyLS4zNjA3LTIuODA2IDMuNDE4NS00LjY4NiA1LjQ0MzktMi43MjQgMS40NDcxIDEuMDEzMS45NjU4OSAyLjg3MDMuOTM0NjEgNC4zNTM3IDIuMzY1NCAxLjg4MzYgNC43MjE2IDMuNzc5MiA3LjA4NDMgNS42NjkxIDEuMzY3NC01LjIwMiAyLjc0NjUtMTAuNDAxIDQuMTA1OC0xNS42MDUtMS4zMjI1LTEuMDg5Ni0yLjk0NjItMi4zNjYtMi41NzA3LTQuMzIyNXoiLz48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJtMjIuOTUzIDI1LjEwMmMyLjY1MjItMS4zMDM0IDMuOTUxNCAzLjQ1MDMgMS4yMDg0IDMuODIxNi0yLjQ1MzcuNzY0MzYtMy41MDQ3LTMuMDA2Ni0xLjIwODQtMy44MjE2eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4NDI0NyIvPjxwYXRoIGQ9Im0yMi45NTMgMjUuMTAyYzIuNjUyMi0xLjMwMzQgMy45NTE0IDMuNDUwMyAxLjIwODQgMy44MjE2LTIuNDUzNy43NjQzNi0zLjUwNDctMy4wMDY2LTEuMjA4NC0zLjgyMTZ6Ii8+PHBhdGggZD0ibTM5LjA4MiAyNS4zMDdjMS40NDgzLS45Mjk3OCAzLjc3NzguMDAzMiAzLjM1NDQgMS45MzA2LS4wMjgwOCAxLjc3MzYtMi4yMDgyIDIuMDg3NC0zLjQ2OCAxLjM0ODUtLjY0MDI2LS45NjgyNi0uODE0ODctMi40MjU0LjExMzU1LTMuMjc5MXoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODQyNDciLz48cGF0aCBkPSJtMzkuMDgyIDI1LjMwN2MxLjQ0ODMtLjkyOTc4IDMuNzc3OC4wMDMyIDMuMzU0NCAxLjkzMDYtLjAyODA4IDEuNzczNi0yLjIwODIgMi4wODc0LTMuNDY4IDEuMzQ4NS0uNjQwMjYtLjk2ODI2LS44MTQ4Ny0yLjQyNTQuMTEzNTUtMy4yNzkxeiIvPjxwYXRoIGQ9Im0xOS4xNDggNDkuNzA3YzIuMDM0LTYuNDA5IDMuMDYzOS0xMy4xNzUgNS44MjIyLTE5LjMyNiAyLjQ0OTUgNC42MTI3IDQuNTcxOSA5LjM4OTEgNi44ODM2IDE0LjA3MiAyLjMzNDQtNC42NTE0IDQuNTI4NC05LjM3NDQgNi45Njg0LTEzLjk3MyAxLjA0MzQgMS4wOTM4IDEuNTA4IDIuNTI2MyAxLjg1NjggMy45NjAxIDEuMjc2MSA1LjA5NjYgMi42MDEzIDEwLjE4MSAzLjkxNTkgMTUuMjY4IDMuMTA3NC0yLjQzODYgNi4yMTEzLTQuODgyNSA5LjMyMi03LjMxOTEtMS44MjU3IDMuOTAyOC0zLjY5MDYgNy43ODY2LTUuNTA4MyAxMS42OTMtMTAuNTA0LTQuMzE3NS0yMi41ODEtNC4xNDA3LTMzLjEwNy4wMDY0LTEuODc2MS00LjExMDgtMy43ODcxLTguMjA1LTUuNjctMTIuMzEyIDMuMTc2NCAyLjYzNzYgNi4zNDMzIDUuMjg3NSA5LjUxNjUgNy45MzExeiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4NDI0NyIvPjxwYXRoIGQ9Im0xOS4xNDggNDkuNzA3YzIuMDM0LTYuNDA5IDMuMDYzOS0xMy4xNzUgNS44MjIyLTE5LjMyNiAyLjQ0OTUgNC42MTI3IDQuNTcxOSA5LjM4OTEgNi44ODM2IDE0LjA3MiAyLjMzNDQtNC42NTE0IDQuNTI4NC05LjM3NDQgNi45Njg0LTEzLjk3MyAxLjA0MzQgMS4wOTM4IDEuNTA4IDIuNTI2MyAxLjg1NjggMy45NjAxIDEuMjc2MSA1LjA5NjYgMi42MDEzIDEwLjE4MSAzLjkxNTkgMTUuMjY4IDMuMTA3NC0yLjQzODYgNi4yMTEzLTQuODgyNSA5LjMyMi03LjMxOTEtMS44MjU3IDMuOTAyOC0zLjY5MDYgNy43ODY2LTUuNTA4MyAxMS42OTMtMTAuNTA0LTQuMzE3NS0yMi41ODEtNC4xNDA3LTMzLjEwNy4wMDY0LTEuODc2MS00LjExMDgtMy43ODcxLTguMjA1LTUuNjctMTIuMzEyIDMuMTc2NCAyLjYzNzYgNi4zNDMzIDUuMjg3NSA5LjUxNjUgNy45MzExeiIvPjxwYXRoIGQ9Im02LjY5NDMgMzcuNjE0YzEuOTcwNC0xLjAwNTcgMy4zNTMzLjYwMTg1IDIuNTk4MyAyLjQ3NzgtMS44MjE5IDEuMzI4Mi0zLjgxMzctLjYzMzkyLTIuNTk4My0yLjQ3Nzh6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDg0MjQ3Ii8+PHBhdGggZD0ibTYuNjk0MyAzNy42MTRjMS45NzA0LTEuMDA1NyAzLjM1MzMuNjAxODUgMi41OTgzIDIuNDc3OC0xLjgyMTkgMS4zMjgyLTMuODEzNy0uNjMzOTItMi41OTgzLTIuNDc3OHoiLz48cGF0aCBkPSJtNTQuNDU4IDQwLjU5OWMuMDQyNy0xLjE5MTQtLjI0MjA5LTMuNTExNyAxLjcxOS0zLjAyMTUgMS4xMzY5LS4zNTE2NCAxLjQ1MTggMS4yMjEgMS4yOTY3IDIuMDAxMi0uMTIzMjQgMS40NTQtMi4xMTg3LjczMzkxLTMuMDE1NyAxLjAyMDN6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDg0MjQ3Ii8+PHBhdGggZD0ibTU0LjQ1OCA0MC41OTljLjA0MjctMS4xOTE0LS4yNDIwOS0zLjUxMTcgMS43MTktMy4wMjE1IDEuMTM2OS0uMzUxNjQgMS40NTE4IDEuMjIxIDEuMjk2NyAyLjAwMTItLjEyMzI0IDEuNDU0LTIuMTE4Ny43MzM5MS0zLjAxNTcgMS4wMjAzeiIvPjxwYXRoIGQ9Im0xNi4yMTEgNTYuMTM0YzkuODAyMy00LjM1ODQgMjEuNTEzLTQuMzc1NSAzMS4zMTIuMDAxMy0uMTAwNTEgMS4zMjI3LS4xOTgxMSAyLjY0NTYtLjI5MTU1IDMuOTY5My0xLjE0MzIuMDAxOC0yLjI4MjQuMDA0NS0zLjQxNzcuMDA3OS45ODEwMyAxLjExMDcgMS45Njk5IDIuMjIxMiAyLjk1NTEgMy4zMzM5LjAxMTQ3LjcxMzAxLjAzNDQgMi4xMzkuMDQ1ODggMi44NTItMy4wNzItMS40OTUzLTYuNDIwMi0yLjM0MTItOS44MjI0LTIuNTgxMi02LjczNTQtLjUzMTU4LTEzLjg4Ni0uNTg4MzktMjAuMDQ5IDIuNTc2OC4wMDctLjcxMDA4LjAyMDk2LTIuMTMwMi4wMjc5NC0yLjg0MDMuOTgzNC0xLjExNTMgMS45Njg3LTIuMjI4IDIuOTU4Ni0zLjM0MTMtMS4xNTU4LS4wMDM0LTIuMzA4MS0uMDA1OS0zLjQ1NjctLjAwNzYtLjA5MDk1LTEuMzI0Mi0uMTc5MTYtMi42NDc3LS4yNjMxLTMuOTcwOXoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODQyNDciLz48cGF0aCBkPSJtMTYuMjExIDU2LjEzNGM5LjgwMjMtNC4zNTg0IDIxLjUxMy00LjM3NTUgMzEuMzEyLjAwMTMtLjEwMDUxIDEuMzIyNy0uMTk4MTEgMi42NDU2LS4yOTE1NSAzLjk2OTMtMS4xNDMyLjAwMTgtMi4yODI0LjAwNDUtMy40MTc3LjAwNzkuOTgxMDMgMS4xMTA3IDEuOTY5OSAyLjIyMTIgMi45NTUxIDMuMzMzOS4wMTE0Ny43MTMwMS4wMzQ0IDIuMTM5LjA0NTg4IDIuODUyLTMuMDcyLTEuNDk1My02LjQyMDItMi4zNDEyLTkuODIyNC0yLjU4MTItNi43MzU0LS41MzE1OC0xMy44ODYtLjU4ODM5LTIwLjA0OSAyLjU3NjguMDA3LS43MTAwOC4wMjA5Ni0yLjEzMDIuMDI3OTQtMi44NDAzLjk4MzQtMS4xMTUzIDEuOTY4Ny0yLjIyOCAyLjk1ODYtMy4zNDEzLTEuMTU1OC0uMDAzNC0yLjMwODEtLjAwNTktMy40NTY3LS4wMDc2LS4wOTA5NS0xLjMyNDItLjE3OTE2LTIuNjQ3Ny0uMjYzMS0zLjk3MDl6Ii8+PHBhdGggZD0ibTI5LjY1IDU3LjMxNmMxLjgyOTMtLjQ4MjYxIDMuODExMy0uMzMwNjUgNS41Njg4LjM3MTc2LjQ2NDk3IDIuMTczLTEuOTE5IDIuMDIxNy0zLjM4ODcgMi4xMDE1LTEuNDU4Mi0uMDc2LTMuNzgxOC4wMzg4Ni0zLjMzMDctMi4wOTIxLjI4NzY0LS4wOTUzLjg2Mjk0LS4yODU5IDEuMTUwNi0uMzgxMTl6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDg0MjQ3Ii8+PC9nPjxwYXRoIGQ9Im0yOS42NSA1Ny4zMTZjMS44MjkzLS40ODI2MSAzLjgxMTMtLjMzMDY1IDUuNTY4OC4zNzE3Ni40NjQ5NyAyLjE3My0xLjkxOSAyLjAyMTctMy4zODg3IDIuMTAxNS0xLjQ1ODItLjA3Ni0zLjc4MTguMDM4ODYtMy4zMzA3LTIuMDkyMS4yODc2NC0uMDk1My44NjI5NC0uMjg1OSAxLjE1MDYtLjM4MTE5eiIvPjxwYXRoIGQ9Im0yMy44NzcgNjUuOTIxYzUuNzQyNi0uODUxOTggMTEuNjIxLS43OTE5NCAxNy4zMzcuMjQ1NTYgMS42NDc1LjMzOTk3IDMuNDE0NS43MDU0NiA0LjcwMjcgMS44Nzc0Ljc3NTU0IDEuNzU5Mi0xLjQ2NDggMi4zMTY1LTIuNjk1NyAyLjc2MTQtNy40MjU0IDEuNzM2NS0xNS4yOTQgMS43MjE4LTIyLjcyNC4wMjUwNS0xLjI4MjQtLjQ2MTQ1LTMuNjIzMy0xLjAwMjUtMi43NjI4LTIuODM0OCAxLjcxNjYtMS40MjAyIDQuMDIwNi0xLjcwMzggNi4xNDIzLTIuMDc0NnoiIGZpbGw9IiNmZmYiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODQyNDciLz48cGF0aCBkPSJtMjMuODc3IDY1LjkyMWM1Ljc0MjYtLjg1MTk4IDExLjYyMS0uNzkxOTQgMTcuMzM3LjI0NTU2IDEuNjQ3NS4zMzk5NyAzLjQxNDUuNzA1NDYgNC43MDI3IDEuODc3NC43NzU1NCAxLjc1OTItMS40NjQ4IDIuMzE2NS0yLjY5NTcgMi43NjE0LTcuNDI1NCAxLjczNjUtMTUuMjk0IDEuNzIxOC0yMi43MjQuMDI1MDUtMS4yODI0LS40NjE0NS0zLjYyMzMtMS4wMDI1LTIuNzYyOC0yLjgzNDggMS43MTY2LTEuNDIwMiA0LjAyMDYtMS43MDM4IDYuMTQyMy0yLjA3NDZ6IiBmaWxsPSIjZmZmIi8+PC9nPjwvc3ZnPg==')} +.is2d .king.white {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMjQuMjg1IDIzLjEzOWM1LjE3OTYtLjAwMDg2MSAxMC4zNi0uMDAwOTcxIDE1LjU0Mi4wMDAwNjMtLjAwNTUgMy44NjI4LjAyNDA4IDcuNzI1Ny0uMDI5IDExLjU4OCAyLjkwODItMS44MTE4IDYuMTU5Ny0zLjQ3MzQgOS43LTMuMTg0NCA0LjQ3MTEuMDY4MzYgOS4wOTQ1IDMuNDQ1NSA5LjM2NDggOC4xMzQuNTI2MzcgNi44MTY1LTMuOTMwNSAxMi44NTctOC45ODYyIDE2Ljk0My0uMzA1NzcgNC4yNTE4LS4zNDA3MiA4LjUyOC0uODExODYgMTIuNzY1LTEuMDAxOSAyLjE4ODMtMy41OTUzIDMuMDgzMi01Ljc1NDEgMy43MjM4LTUuNjQ4MSAxLjI2NTktMTEuNTAzIDEuMDI4OS0xNy4yNDYuNzg5MS0zLjgwNzgtLjM1MDktOC4yMzczLS44NDI2MS0xMC44MjYtNC4wMDg2LS44NjU2OS00LjM0NC0uNTk5LTguODg2NC0xLjAxNzctMTMuMzA3LTQuOTc3Ni0zLjgyODUtOC45ODI2LTkuNjM0MS05LjEyNTItMTYuMDc2LS4wNjE2My00Ljk5NiA0LjcwNjUtOC45MDg5IDkuNDkwNC04Ljk2NjcgMy41NDU2LS4yNzIyNCA2LjgwODMgMS4zNzQ5IDkuNzI5OCAzLjE4OTYtLjA2MDI0LTMuODYyOC0uMDI4MTUtNy43MjU5LS4wMzExOS0xMS41ODl6IiBmaWxsPSIjZmZmIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDgyNzU3Ii8+PHBhdGggZD0ibTI0LjI5MyAyMy4xNDdjLjAwMzEgMy44NjMtLjAzNzQzIDcuNzI1OS4wMjI4MSAxMS41ODktMi45MjE1LTEuODE0Ny02LjE5NTQtMy40NjYtOS43NDA5LTMuMTkzOC00Ljc4MzkuMDU3NzYtOS41NTE2IDMuOTY5My05LjQ5IDguOTY1My4xNDI2NCA2LjQ0MjIgNC4xNDc0IDEyLjI1NCA5LjEyNSAxNi4wODMuNDE4NzEgNC40MjA4LjE2MDg3IDguOTU1NyAxLjAyNjYgMTMuMyAyLjU4ODYgMy4xNjYgNy4wMjgxIDMuNjY0MSAxMC44MzYgNC4wMTUgNS43NDIyLjIzOTc4IDExLjU5OC40Njc0NSAxNy4yNDYtLjc5ODQ0IDIuMTU4OC0uNjQwNjQgNC43NDY4LTEuNTMwMiA1Ljc0ODgtMy43MTg0LjQ3MTE0LTQuMjM2Ni40OTI2Ni04LjUyMzIuNzk4NDQtMTIuNzc1IDUuMDU1Ny00LjA4NiA5LjUxNDUtMTAuMTEgOC45ODgxLTE2LjkyNy0uMjcwMzItNC42ODg0LTQuODgyLTguMDc1Ny05LjM1MzEtOC4xNDQxLTMuNTQwMy0uMjg5MDEtNi43ODcxIDEuMzgxOS05LjY5NTMgMy4xOTM4LjA1MzA4LTMuODYyNy4wMTczLTcuNzI1OS4wMjI4MS0xMS41ODktNS4xODE4LS4wMDEtMTAuMzU2LS4wMDA4NjEtMTUuNTM1IDB6bTMuMTI1IDE1LjIxNmMzLjA4NzQuMDE5MjcgNi4xNzA1LjAyMDg2IDkuMjYxOSAwLTEuODQzNyAyLjQ1OTMtMy4zNTk2IDUuMTQ1Mi00LjYzMDkgNy45Mzg4LTEuMjcxNS0yLjc5NjEtMi43OTA5LTUuNDc4LTQuNjMwOS03LjkzODh6Ii8+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0ibTI3LjQ3NCAyNS40NjFjMy4wNTIyLS4wMDI3IDYuMTA2NS0uMDAzMSA5LjE2MzIuMDAwNTE3LTEuNTI4NSAxLjQ1MzgtMy4wNTY0IDIuOTAzLTQuNTgzNyA0LjM1MzMtMS41Mjg2LTEuNDUwNi0zLjA1ODEtMi45MDA0LTQuNTc5NS00LjM1Mzh6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDgyNzU3Ii8+PHBhdGggZD0ibTI3LjQ3NCAyNS40NjFjMy4wNTIyLS4wMDI3IDYuMTA2NS0uMDAzMSA5LjE2MzIuMDAwNTE3LTEuNTI4NSAxLjQ1MzgtMy4wNTY0IDIuOTAzLTQuNTgzNyA0LjM1MzMtMS41Mjg2LTEuNDUwNi0zLjA1ODEtMi45MDA0LTQuNTc5NS00LjM1Mzh6Ii8+PHBhdGggZD0ibTI2LjM5MiAyNi42MjZjMS40NTAxIDEuNDY3NyAyLjkwMDMgMi45MzU3IDQuMzUzMyA0LjQwNDctMS40NTIzIDEuNDc4My0yLjkwNCAyLjk1NTItNC4zNTMzIDQuNDMyOS0uMDAxNC0yLjk0Ni0uMDAyOC01Ljg5MTgtLjAwMDAxNi04LjgzNzZ6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDgyNzU3Ii8+PHBhdGggZD0ibTI2LjM5MiAyNi42MjZjMS40NTAxIDEuNDY3NyAyLjkwMDMgMi45MzU3IDQuMzUzMyA0LjQwNDctMS40NTIzIDEuNDc4My0yLjkwNCAyLjk1NTItNC4zNTMzIDQuNDMyOS0uMDAxNC0yLjk0Ni0uMDAyOC01Ljg5MTgtLjAwMDAxNi04LjgzNzZ6Ii8+PHBhdGggZD0ibTMzLjM2MiAzMS4wMjljMS40NDk4LTEuNDY5NiAyLjkwMjgtMi45Mzg2IDQuMzU3MS00LjQwNzgtLjAwMTggMi45NDg1LS4wMDIzIDUuODk2OS4wMDAxNDIgOC44NDU2LTEuNDU0NS0xLjQ3OTMtMi45MDc2LTIuOTU3OC00LjM1NzMtNC40Mzc4eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4Mjc1NyIvPjxwYXRoIGQ9Im0zMy4zNjIgMzEuMDI5YzEuNDQ5OC0xLjQ2OTYgMi45MDI4LTIuOTM4NiA0LjM1NzEtNC40MDc4LS4wMDE4IDIuOTQ4NS0uMDAyMyA1Ljg5NjkuMDAwMTQyIDguODQ1Ni0xLjQ1NDUtMS40NzkzLTIuOTA3Ni0yLjk1NzgtNC4zNTczLTQuNDM3OHoiLz48cGF0aCBkPSJtMjcuNTk0IDM2LjUwN2MxLjQ4MDctMS40NDkzIDIuOTcwMy0yLjg5NCA0LjQ1OTktNC4zMzg1IDEuNDg3NiAxLjQ0NTUgMi45NzQ5IDIuODkwNSA0LjQ2NDcgNC4zMzg4LTIuOTc3My4wMDM3LTUuOTUxOS4wMDM5LTguOTI0Ni0uMDAwMzUzeiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4Mjc1NyIvPjxwYXRoIGQ9Im0yNy41OTQgMzYuNTA3YzEuNDgwNy0xLjQ0OTMgMi45NzAzLTIuODk0IDQuNDU5OS00LjMzODUgMS40ODc2IDEuNDQ1NSAyLjk3NDkgMi44OTA1IDQuNDY0NyA0LjMzODgtMi45NzczLjAwMzctNS45NTE5LjAwMzktOC45MjQ2LS4wMDAzNTN6Ii8+PHBhdGggZD0ibTcuNDUyMSA0Mi4yMjNjLS41ODE1NS0zLjM1MTUgMS42MjEzLTYuOTQwOSA0Ljg4NjctNy45MDUyIDMuOTU5NC0xLjE2MDggOC4zNTM2LjIxMTEyIDExLjMxMSAyLjk5NDggMy45MzQ3IDMuNjAyOCA2LjAzOTcgOC42NjI3IDcuNjQxMyAxMy42NDItNS41MzMzLjIxNzE1LTExLjI1NC43MTYxNi0xNi4xODUgMy40NjY2LTMuNjI0LTMuMjExLTcuMDU2OS03LjIwOC03LjY1MzktMTIuMTk4eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4Mjc1NyIvPjxwYXRoIGQ9Im03LjQ1MjEgNDIuMjIzYy0uNTgxNTUtMy4zNTE1IDEuNjIxMy02Ljk0MDkgNC44ODY3LTcuOTA1MiAzLjk1OTQtMS4xNjA4IDguMzUzNi4yMTExMiAxMS4zMTEgMi45OTQ4IDMuOTM0NyAzLjYwMjggNi4wMzk3IDguNjYyNyA3LjY0MTMgMTMuNjQyLTUuNTMzMy4yMTcxNS0xMS4yNTQuNzE2MTYtMTYuMTg1IDMuNDY2Ni0zLjYyNC0zLjIxMS03LjA1NjktNy4yMDgtNy42NTM5LTEyLjE5OHoiLz48cGF0aCBkPSJtNDAuNDcgMzcuMzAxYzIuOTE0NS0yLjczNTggNy4yMTE3LTQuMTA0IDExLjEyOC0zLjAyOCAzLjMyNjEuOTA4ODMgNS41OTg2IDQuNTE0IDUuMDY4OCA3LjkxMDgtLjUwNzYzIDUuMDI5Ny00LjAwMzYgOS4wMjg2LTcuNjQ0OSAxMi4yMzEtNC45NzUtMi42NDk5LTEwLjY3Mi0zLjIyMDYtMTYuMjA4LTMuNDYyOCAxLjYwMzMtNC45ODI1IDMuNzA4NS0xMC4wNTEgNy42NTU2LTEzLjY1MXoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODI3NTciLz48cGF0aCBkPSJtNDAuNDcgMzcuMzAxYzIuOTE0NS0yLjczNTggNy4yMTE3LTQuMTA0IDExLjEyOC0zLjAyOCAzLjMyNjEuOTA4ODMgNS41OTg2IDQuNTE0IDUuMDY4OCA3LjkxMDgtLjUwNzYzIDUuMDI5Ny00LjAwMzYgOS4wMjg2LTcuNjQ0OSAxMi4yMzEtNC45NzUtMi42NDk5LTEwLjY3Mi0zLjIyMDYtMTYuMjA4LTMuNDYyOCAxLjYwMzMtNC45ODI1IDMuNzA4NS0xMC4wNTEgNy42NTU2LTEzLjY1MXoiLz48cGF0aCBkPSJtMTYuNTcxIDU2LjM3N2M5LjcyNzItNC4yMDA2IDIxLjIzNi00LjIwMDIgMzAuOTY1LS4wMDE5LS4wODkxOSAxLjI5MTQtLjE3NDkyIDIuNTgzLS4yNTU5OCAzLjg3NTMtMS4xMzI3LjAwMTYtMi4yNjA5LjAwMzktMy4zODQ1LjAwNy45MzYyMyAxLjA5NDEgMS44ODI0IDIuMTg3OCAyLjgyMyAzLjI4NDYuMDI2NjQuNjcyMDYuMDc5OTQgMi4wMTYyLjEwNjU5IDIuNjg4My00LjQxNDctMi43MDc5LTkuNzMyNi0yLjkyMjktMTQuNzYzLTIuOTU3NC01LjAzNy4wMzMzOS0xMC4zNTYuMjQ3ODMtMTQuNzc1IDIuOTUyNC4wMjY1Mi0uNjcxNDcuMDc5NTYtMi4wMTQ0LjEwNjEtMi42ODU4LjkzNjQxLTEuMDk1OSAxLjg3NTYtMi4xODg2IDIuODE5Ni0zLjI4MjItMS4xMzE4LS4wMDMtMi4yNTkzLS4wMDU0LTMuMzgyNi0uMDA3LS4wOTA3Ny0xLjI5MTYtLjE3ODAzLTIuNTgyNS0uMjU5Ni0zLjg3MzF6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDgyNzU3Ii8+PHBhdGggZD0ibTE2LjU3MSA1Ni4zNzdjOS43MjcyLTQuMjAwNiAyMS4yMzYtNC4yMDAyIDMwLjk2NS0uMDAxOS0uMDg5MTkgMS4yOTE0LS4xNzQ5MiAyLjU4My0uMjU1OTggMy44NzUzLTEuMTMyNy4wMDE2LTIuMjYwOS4wMDM5LTMuMzg0NS4wMDcuOTM2MjMgMS4wOTQxIDEuODgyNCAyLjE4NzggMi44MjMgMy4yODQ2LjAyNjY0LjY3MjA2LjA3OTk0IDIuMDE2Mi4xMDY1OSAyLjY4ODMtNC40MTQ3LTIuNzA3OS05LjczMjYtMi45MjI5LTE0Ljc2My0yLjk1NzQtNS4wMzcuMDMzMzktMTAuMzU2LjI0NzgzLTE0Ljc3NSAyLjk1MjQuMDI2NTItLjY3MTQ3LjA3OTU2LTIuMDE0NC4xMDYxLTIuNjg1OC45MzY0MS0xLjA5NTkgMS44NzU2LTIuMTg4NiAyLjgxOTYtMy4yODIyLTEuMTMxOC0uMDAzLTIuMjU5My0uMDA1NC0zLjM4MjYtLjAwNy0uMDkwNzctMS4yOTE2LS4xNzgwMy0yLjU4MjUtLjI1OTYtMy44NzMxeiIvPjxwYXRoIGQ9Im0yOS43NjUgNTcuMjc1YzEuOTgzLS40MDQ2MyA1LjAxNzUtLjg2ODM3IDYuMDQ2MiAxLjQwMDctMS43NTY4IDEuODA5OS00LjY4MDggMS40ODE2LTYuODU2Ny43Mjc3Mi0uNzMzMDEtMS4xNjc0LS40NjI4Ny0xLjg3NjguODEwNDUtMi4xMjg0eiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4Mjc1NyIvPjwvZz48cGF0aCBkPSJtMjkuNzY1IDU3LjI3NWMxLjk4My0uNDA0NjMgNS4wMTc1LS44NjgzNyA2LjA0NjIgMS40MDA3LTEuNzU2OCAxLjgwOTktNC42ODA4IDEuNDgxNi02Ljg1NjcuNzI3NzItLjczMzAxLTEuMTY3NC0uNDYyODctMS44NzY4LjgxMDQ1LTIuMTI4NHoiLz48cGF0aCBkPSJtMjQuMjExIDY1Ljk5N2M2LjMyNzItLjg1NzI1IDEyLjg0My0uNzg5MjUgMTkuMDc3LjY3MzE0IDEuMjg4OC40MjMwOCAzLjI0Ni45MjM0NCAyLjgyMzYgMi43MDExLTEuODY5MyAxLjQ4NTktNC4zMDk4IDEuODE2Ni02LjU5MzggMi4xNTU5LTUuNTU4OC43ODUxNC0xMS4yMzIuNjc3NjYtMTYuNzU5LS4yODc5OC0xLjY4NTMtLjMwNzA4LTMuNDAxMy0uNzcyNzYtNC43NjA0LTEuODU5Ni0uMDkzMDYtMi45ODYyIDQuMDkyNi0yLjgwNjIgNi4yMTIyLTMuMzgyNnoiIGZpbGw9IiNmZmYiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODI3NTciLz48cGF0aCBkPSJtMjQuMjExIDY1Ljk5N2M2LjMyNzItLjg1NzI1IDEyLjg0My0uNzg5MjUgMTkuMDc3LjY3MzE0IDEuMjg4OC40MjMwOCAzLjI0Ni45MjM0NCAyLjgyMzYgMi43MDExLTEuODY5MyAxLjQ4NTktNC4zMDk4IDEuODE2Ni02LjU5MzggMi4xNTU5LTUuNTU4OC43ODUxNC0xMS4yMzIuNjc3NjYtMTYuNzU5LS4yODc5OC0xLjY4NTMtLjMwNzA4LTMuNDAxMy0uNzcyNzYtNC43NjA0LTEuODU5Ni0uMDkzMDYtMi45ODYyIDQuMDkyNi0yLjgwNjIgNi4yMTIyLTMuMzgyNnoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+')} +.is2d .pawn.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTQ5LjI0NiA3NC4xNGgtMzQuNTQzYy0uMDk1OTUtMy4wMTMgMS4wNzQ3LTUuMjAwNyAzLjUxMTktNi41NjMyIDEuODk5OS0xLjA1NTUgNC40NzE0LTEuNTczNiA3LjcxNDctMS41NTQ0bC4xNzI3Mi0yLjQ0NjhjLTEuMTg5OC0uNjUyNDgtMS43ODQ4LTEuOTQ3OS0xLjc4NDctMy44ODYxLS4wMDAwMTUtMi40MzcyIDEuMDM2My01LjU2NTMgMy4xMDg5LTkuMzg0M3YtMy43NzFoLTEwLjM5MmMtLjE1MzUzLTEuMTMyMi4xNDM5My0yLjQxOC44OTIzNy0zLjg1NzMgMS44OTMxLTQuMTExNSA2LjgzODUtNC4xODI2IDkuODczNi02LjczNi0uNDAzMDUtLjYxNDA4LS42NTI1MS0xLjAyNjctLjc0ODQ0LTEuMjM3OC0uMjQ5NDgtLjUxODEyLS4zODM4MS0uOTY5MS0uNDAzLTEuMzUzLS4wMzg0LTEuNDIwMS40Nzk3Mi0yLjYxOTUgMS41NTQ1LTMuNTk4MyAxLjA3NDctLjk5Nzg4IDIuMzMxNi0xLjQ5NjggMy43NzEtMS40OTY5IDEuNDIwMS4wMDAwMzcgMi42Njc1LjQ5OSAzLjc0MjIgMS40OTY5IDEuMDkzOC45Nzg3NiAxLjYyMTYgMi4xNzgyIDEuNTgzMiAzLjU5ODMtLjAzODQgMS4yODU4LS40MjIyNSAyLjE0OTQtMS4xNTE0IDIuNTkwOC4xOTE4Ni43ODY4NSAxLjM3MjEgMS40NjgxIDMuNTQwNyAyLjA0MzggNC44NzQ0IDEuMzA1IDcuMzExNiAzLjg1NzQgNy4zMTE3IDcuNjU3MS0uMDAwMDQuMzgzODEtLjAyODguNjgxMy0uMDg2NC44OTIzN2gtMTAuMzkydjMuNzcxYzIuMDkxOCAzLjgxOSAzLjEzNzYgNi45NDcxIDMuMTM3NyA5LjM4NDMtLjAwMDAzIDEuOTM4My0uNjA0NTQgMy4yMzM2LTEuODEzNSAzLjg4NjFsLjE3MjcyIDIuNDQ2OGM0LjQxMzgtLjAzODQgNy41NzA3LjkzMDc0IDkuNDcwNiAyLjkwNzQgMS4yMDkgMS4yNjY2IDEuODEzNSAyLjc3MyAxLjgxMzUgNC41MTk0LS4wMDAwNC4yODc4Ni0uMDE5Mi41MTgxNC0uMDU3Ni42OTA4NyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIi8+PHBhdGggZD0ibTE0Ljk2OTQ5MiA1Ni44OTM5MjNjMC0uNTY5ODguMzE4NzA1LTEuNjcxMDU3LjcxMjE1NC0yLjQ2MDYwOCAxLjIyMzQzOC0yLjQ1NTExOCAzLjg1MDQzNi0zLjc3MTkxNiA4LjQ0MDM4OC00LjIzMDc4OGwxLjk2NjEwMi0uMTk2NTU1di0xLjI5NTIwNmMwLS44NzQ0NDktLjE0NTc5MS0xLjQxNjExMS0uNDQ4Nzg4LTEuNjY3MzkyLTEuNzg0NjQ4LTEuNDgwMDQ0LTEuNDk3MjA1LTUuNDQ2NzguNzQyMDQyLTEwLjI0MDIzNS45MzM4NjctMS45OTkwODggMS4wNjI2NzgtMi41MTY4MTIgMS4wNjI2NzgtNC4yNzExODZ2LTEuOTk2MzZoLTUuMTUyNTQzLTUuMTUyNTQybC4wMDAyMTQtLjg4MTM1NmMuMDAwMzI1LTEuMjkwNDA3IDEuMzg1Mjg3LTQuMDAyODU3IDIuNTc5MDE3LTUuMDUwOTY2LjU3MDMxNS0uNTAwNzQzIDIuNDQ2OTA1LTEuNTcyOTQ4IDQuMTcwMi0yLjM4MjY3NyAxLjcyMzI5Ni0uODA5NzI5IDMuMzQxNzYtMS42NjA5MjEgMy41OTY1ODgtMS44OTE1MzcuNDM2MjExLS4zOTQ3NjYuNDMyNzYtLjQ2OTQyNi0uMDU4OTgtMS4yNzU4NzQtLjY4Njk2LTEuMTI2NjEyLS42ODMwODQtMy4wMzM1NTguMDA4NS00LjE2Nzc1MyAxLjE3MTMtMS45MjEwMTEgMy45NzIwMjEtMi45NTQxNTcgNi4xMDIzNy0yLjI1MTA3OCAyLjc5MjQxMy45MjE1NzkgNC40ODE1NSA0LjE0NTIyNiAzLjI2OTc3MyA2LjI0MDIyNC0uNzc0NTM1IDEuMzM5MDY1LS43ODM1NTcgMS40MzM1MjMtLjE4MzMzMyAxLjkxOTU1NS4zMjU0NDQuMjYzNTI5IDEuNzMyMjgxLjg1OTEyMyAzLjEyNjMwNCAxLjMyMzU0MiAzLjA1NjQ4OSAxLjAxODI3IDQuNzU1NjMyIDIuMDQ5NjEzIDUuODM3NjkgMy41NDMzNS44MTAwMDcgMS4xMTgxODEgMS41NTk3NjcgMy43NDk0NzIgMS4yNzc3NzEgNC40ODQzNDItLjEyMzAyNC4zMjA1OTgtMS4wNzA2NTIuMzkwMjI4LTUuMzEwNzk4LjM5MDIyOGgtNS4xNjEwNTN2MS45MDUwNzVjMCAxLjYyNDgyMS4xMzUwMjIgMi4xNzMzNjQuOTE3ODMxIDMuNzI4ODE0IDIuMDE4NjczIDQuMDExMTIgMi43NDAwMzUgOC4zNDExMjEgMS42NjQ3NTEgOS45OTI3MjUtLjI3OTM2MS40MjkwOTEtLjY3NzkzMy45MDY2MjYtLjg4NTcxNCAxLjA2MTE4Ni0uMjUwODA2LjE4NjU2NS0uMzQ4ODA1LjY4Nzg5MS0uMjkxNTY0IDEuNDkxNTI1bC4wODYyMiAxLjIxMDUwNiAyLjQ2MTMzNy4zMjUxNTJjMy40MjU5ODIuNDUyNTg2IDUuMzYxMjg4IDEuMjM0MzYgNi45MjM4MjYgMi43OTY4OTUgMS4yNzQxNTkgMS4yNzQxNTkgMS44NjQ0MTUgMi41ODAxNjYgMS44Njc1NjEgNC4xMzIxOWwuMDAxNS43NDU3NjNoLTE3LjA4NDc0Ni0xNy4wODQ3NDV2LTEuMDMxNTAxeiIgZmlsbD0iIzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii45ODc4MDIiLz48L3N2Zz4=')} +.is2d .knight.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMTEuNjk4IDYwLjg1MmMuOTI0NzYuOTI5NTEgMy4yMzQ2Ljk1MjQgNC4zOC4xMjU0OC45MDc1OC0xLjExNzYgMi4yMjkzLTEuNjk0MSAyLjU4MzktMy4xNzQyLjYxNzM5LTEuOTUxOC0xLjkxNzktMy4wODM3LTMuMjIyLTEuNzAxMi0xLjQ5MDEgMS40MTA0LTQuNzU5NCAzLjg1MjMtMy43NDE4IDQuNzQ5OXoiIGZpbGw9IiNmZmYiIHN0cm9rZT0iIzIwMTkxNyIgc3Ryb2tlLXdpZHRoPSIxLjQyMiIvPjxwYXRoIGQ9Im0yMi4yNDUgMjkuMDcxYy4yMDU5Ny0xLjk3ODguMzM0OS0zLjk2NDYuNDMxMjMtNS45NTE3IDEuOTg4MyAzLjAwMTYgNC41MDE5IDYuMjA2NiA4LjM3NjIgNi41ODIzIDcuNzc5MSAxLjE3MzEgMTUuMTI1IDUuNjQ1NiAxOS4xNzMgMTIuNDc1IDUuODAyOCA5LjUzMTMgNi4yNjY1IDIxLjM3MiAzLjQ5NzcgMzEuOTY4LTEwLjMwNC0uMDA2Ni0yMC42MDcuMDE2MzYtMzAuOTA5LS4wMDItMS4yMjM0LS4wMzQxMS0zLjQ1MzEuMDYwNTYtMy4xNDU2LTEuODIxMi43NDk2NS0zLjk3MzMgMy44MDU1LTcuMTY4NCA3LjI5NjktOS4wMjQyIDQuNDI0MS0yLjY1MDYgNS42NDA5LTguMTE0IDUuNzAxMS0xMi45MTItMi40NzQ2IDIuMjkxNi02LjYwNTkgNC45MzYyLTEwLjMxNCA0Ljg1ODYtMi4xNTI3IDMuNDYyOC0yLjc3MjkgNS42MzUyLTcuMzQyOCA2LjgxMTktLjYxMTE2LS42Nzk0Ni4wNzE0LTEuNTAwOC45Mzg5OC0zLjkxNDctMS4wMTQ0IDEuMDYxNi0yLjQ5NjMgMi40NjUyLTQuNjE1MyAzLjMzNC0yLjE4NDctMS45MjEtMy4zOTkzLTQuNjI4My0yLjI2MjYtNy44NDM5LjkzODIzLTEuNDExMi41NjYzMS0xLjcxNTggMS44MzgyLTIuOTA3NyAxLjY1MDktMS41NDcgNC4wMDQyLTUuMjkxMSA0LjQ4MjEtOC4xMDA1LjQ2MjgzLTMuMTU3NCAyLjE4NDMtNS44ODY0IDQuMDQyMS04LjQwMzMtMS4yMDQ1LTIuNzk5Mi0xLjcyMTQtNS44MTg3LTEuNjQ2MS04Ljg1ODcgMS40ODk5IDEuMjI5NyAyLjkyODUgMi41MjI0IDQuNDU3OSAzLjcwOTV6Ii8+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0ibTI0LjM1NSAyOC40MjZjLjc4NyAxLjA3MjEgMi4wMTE3IDIuMTc1OSAzLjEzOTMgMi45MTU1LjA0OTkuOTg4ODYuNTg5NDIgMi43NjItMS4wMjI3IDIuNjg5OC0yLjk3NjMuMjkzNTQtMi41MTY5LTMuODE0Mi0yLjExNjYtNS42MDUzeiIvPjxwYXRoIGQ9Im0zMi4wNDIgMzIuMzI0YzYuMzM0MS0uMDI5NzMgMTMuMTE3IDYuNTMxNSAxNS4wMSA5LjE5NDQgNi41NzIzIDcuOTA2NyA2Ljc5MTYgMTkuMTYyIDUuMzA4NyAyOS4wOTUuMzI5NDkgMS44MTMtMS42NDY3IDEuNTgyNy0yLjc5NzkgMS45NzE4LjExNDE4LTguMTc1OC44NTA3My0xNi43Mi0yLjY4NjMtMjQuMzc3LTMuMDUxLTYuMzY1LTguNjY5MS0xMS4zMTctMTUuMTQyLTE0LjAyNi4wNzctLjQ2NDYuMjMwODUtMS4zOTM4LjMwNzgtMS44NTg0eiIvPjxwYXRoIGQ9Im0xMC44NzggNTUuMzcyYy42MzE3LTEuMDAyOSAxLjk3ODctLjk4OTg2IDIuOTc3OC0xLjM3MDctLjY0ODQ2IDEuMzIxNS0uOTUzNSAzLjE5NTQtMi41MTY4IDMuNzIwMi0uNDUyMTYtLjY0MDY2LTEuMDc2My0xLjYwMzEtLjQ2MTA2LTIuMzQ5NXoiLz48cGF0aCBkPSJtMjAuNDM0IDQyLjk5YzEuODA2MS0xLjM2MjMgMy41NzE4LS41MTUyIDUuNTAxNS4wNjI0OC0yLjEzNSAxLjE5NTEtNC42OTI5IDMuMzQ0OS02LjQwMzYgMi4zMTUtLjY5MjkyLS40MTcxNC0uMTEwNDUtMS42MTM4LjkwMjE0LTIuMzc3NXoiLz48L2c+PC9nPjxwYXRoIGQ9Im0yMC41ODg1MjQgNTcuNjY5MDMxYy0uODYwNDg1LS4zNzM1MzUtLjkwNjU0OC0uNDU5NTgzLS43NTI4OTEtMS40MDY0Ni4yNjE4MTItMS42MTMzNTYgMS43Mjk5NzUtNC4yOTg1IDMuMTQ0MTUtNS43NTAzODEuNzE4NTA2LS43Mzc2NiAyLjE3NTE5MS0xLjkwMzIzOCAzLjIzNzA4LTIuNTkwMTcgMS4wNjE4ODktLjY4NjkzNCAyLjM3NTE4My0xLjcwMDkxNCAyLjkxODQzMi0yLjI1MzI5MSAxLjk0MDk5LTEuOTczNjA1IDMuNTg0ODM2LTYuNjU3MzE3IDMuNjE0NTY2LTEwLjI5ODc2M2wuMDA5NS0xLjE1ODg0OS0xLjM4MTc4MSAxLjA5MjIzNWMtMi42Nzg5IDIuMTE3NTQ4LTYuNDA0Njc4IDMuODAxNzMzLTguNDEwMjQ5IDMuODAxNzMzLS42MjIxMjcgMC0uODkwODkyLjI1NjE5Mi0xLjYzNTg0NCAxLjU1OTMyMi0xLjIwNjg5NyAyLjExMTItMi43OTU3NjEgMy43Nzk2NDItNC4zNDg4MzQgNC41NjY2NDQtMi4yMTk0MjcgMS4xMjQ2NjctMi41MzQ3OTIuODQ5MDQ3LTEuNTc5MjI0LTEuMzgwMjA0Ljc1NjA0Mi0xLjc2Mzc3NC42ODA0NTQtMS45OTc2MzItLjMzODk4My0xLjA0ODc0OC0xLjE3NDQxNiAxLjA5MzEzNi0zLjIyMjg4IDIuNTQyMzQtMy41Nzg4NDggMi41MzE4ODktLjM3MTMwMS0uMDEwOS0xLjkyOTY4OTgtMi4wODUwOTMtMi4zMDE2Nzc2LTMuMDYzNDk2LS41MDUxMzctMS4zMjg2MS0uMzQ0MDc0Ni0zLjcxMzY1MS4zNTE2ODE2LTUuMjA3NzY0LjM0OTQ0MjEtLjc1MDQxNi44MTIxNTgtMS41NDM2MzYgMS4wMjgyNTctMS43NjI3MTIgMi40ODM5MjMtMi41MTgxNDUgNC4yMDUxMzctNS42MTI4MzQgNS4wNzU2MzgtOS4xMjU4NDEuNTg1MDQ3LTIuMzYxMDI0IDEuNDExNjcyLTQuMTg5OTI0IDIuOTIxNjM1LTYuNDY0MDk0bC45MzE3NzItMS40MDMzNDktLjY1NzMxNy0yLjI3ODc5Yy0uNjU2MTg2LTIuMjc0ODcxLTEuMjA2MTQyLTYuMjEwOTkyOC0uODY3ODAyLTYuMjEwOTkyOC4wOTgzIDAgMS4wNDg1ODIuNzMyMjAzOCAyLjExMTc0MiAxLjYyNzExODggMS4wNjMxNTkuODk0OTE1IDIuMDIyNjI2IDEuNjI3MTE4IDIuMTMyMTQ5IDEuNjI3MTE4cy4yODc1OTUtMS4yNDc3NzIuMzk1NzE2LTIuNzcyODI3Yy4xODkwODktMi42NjcxMTYuMjEzMDM4LTIuNzQ3MjQxNC42MjgxNjktMi4xMDE2OTUxLjgwNjA1NyAxLjI1MzQ1NDcgMy40MTc0OTEgMy44NDMyODExIDQuNTM3MjI2IDQuNDk5Njg2MS42MTMzMTcuMzU5NTM1IDIuMzIxNzkyLjkwODE5OSAzLjc5NjYxMSAxLjIxOTI1NSA1LjAzMzk3NyAxLjA2MTcxOSA4LjU4OTEwMSAyLjYyMjkzMiAxMi4yNDM2ODggNS4zNzY3NDYgMy40MzU2NDUgMi41ODg4MzcgNS43Njk5MzMgNS41NDUzMTUgNy43ODk3NzkgOS44NjYwOTkgMi42MzU5NDMgNS42Mzg3MTEgMy40NzEwMDcgOS41Mzg3NTkgMy40OTQyODYgMTYuMzE5NTE2LjAxNjMgNC43NDU4NjYtLjE5ODY1MiA2Ljg4MzQwMS0xLjA4Mzk3MyAxMC43Nzk2NjFsLS40MTU5MzUgMS44MzA1MDktMTYuMDQ2MDU4LS4wMTA2Yy0xMy40ODk0ODItLjAwODkyNi0xNi4xOTIxMzYtLjA3NDAxMy0xNi45NjI2NjEtLjQwODQ5NXptMzEuMTUzODQ5LTEuNTgzMjY4Yy42MjE0ODMtLjI4MzMwOS43MDQwNjUtLjUzNDcyLjk5MTIzNS0zLjAxNzc0OS40NzIwODQtNC4wODE5MDcuNDQ0MTI4LTExLjgwNjg4OS0uMDUzMS0xNC42NzMxNjktMS4wNzAwNjYtNi4xNjgzNzMtMy4xMzE0MzgtMTAuNDY1NTI5LTcuMDUxNDQxLTE0LjY5OTQ5NS0zLjg4NjMzNS00LjE5NzYwMS05LjMxNTc3OC03LjM2MzMyOS0xMi42MzczMzctNy4zNjg0MTQtLjY1MTcyOS0uMDAxLTEuMDQzOTUzLjE0NDQ2OC0xLjE1MjU0My40Mjc0NDctLjQyNjYzMyAxLjExMTc4OC0uMTY3NDQ0IDEuNDQwNDEzIDIuMDQzMTMyIDIuNTkwNDgxIDYuNTMwMjg0IDMuMzk3NDI3IDExLjYxMDEgOS4wMjgxNzIgMTMuODA5ODc1IDE1LjMwNzYyMSAxLjMyNzk4NCAzLjc5MDg0MiAxLjY0Njg3MiA2LjM0NDIzMSAxLjgwMDM1IDE0LjQxNTY3OGwuMTQ1NjE2IDcuNjU3OTkuNzEzMTI1LS4xNjU2NjhjLjM5MjIyLS4wOTExMiAxLjAxODIxMS0uMzA0NzQzIDEuMzkxMDkyLS40NzQ3MjJ6bS0zOS40OTU1NTctMTQuODc4OTgzYy4zNjg2NTQtLjMzNTU5NC45MjM2OC0xLjIwMzIzOCAxLjIzMzM5MS0xLjkyODA5OGwuNTYzMTEtMS4zMTc5MjgtMS4wMTQ4NzkuMTc5NDc3Yy0xLjE5MTI3NC4yMTA2NzEtMi4zMzI3Ljk2Mzk1OS0yLjQ2MjYyMyAxLjYyNTIxNC0uMTA4NTc5LjU1MjYyNC40NjY4MjkgMi4wNTE1MDQuNzg3NTU2IDIuMDUxNTA0LjEyMjc0IDAgLjUyNDc5LS4yNzQ1NzYuODkzNDQ1LS42MTAxNjl6bTExLjI5MjE2Ny0xMi41OTY3NzNjMi43MDQxNDItMS40NDQwNTYgMi43Nzc0OS0xLjU4NzI3OCAxLjA3MjIzLTIuMDkzNjg2LS43OTMwMjItLjIzNTUwMi0xLjc1NTMwMi0uNDI3NzI5LTIuMTM4NC0uNDI3MTcyLS43NTczNDkuMDAxMS0yLjM4NDIxOS44ODgzMTEtMi45MjA0MSAxLjU5MjYzNi0uNTQ4MDE5LjcxOTg2My0uNDIyODU2IDEuNjUwNTE4LjI1Nzc2NiAxLjkxNjY0Ljg0MTk4NC4zMjkyMTQgMS42NzQ4MTYuMTA4NDUxIDMuNzI4ODE0LS45ODg0MTh6bTMuNzQyMzczLTEwLjcxMTcwMmMuMTc4OTgzLS4xNzg5ODMuMzI1NDI0LS44MDc1MjEuMzI1NDI0LTEuMzk2NzUxIDAtLjk2MDI0My0uMTcwMTcxLTEuMjMwNzYyLTEuNjQxMTgzLTIuNjA4OTc0LS45MDI2NTEtLjg0NTcwNy0xLjY4MzEwNy0xLjQ2ODAxNi0xLjczNDM0OC0xLjM4MjkxMS0uMTE5NjU4LjE5ODczOS0uMjMzNTEyIDIuMzMwODktLjE4NjMxMiAzLjQ4OTA5OC4wNjcxMiAxLjY0NzAyNCAyLjIyMzM3MyAyLjkxMjU4NCAzLjIzNjQxOSAxLjg5OTUzOHoiIGZpbGw9IiMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuOTg3ODAyIi8+PC9zdmc+')} +.is2d .bishop.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMjUuNDg3IDI0LjQ4M2MxLjIzNjctMi4xMDYzIDQuNzIwNi0xLjY2MTIgNS40OTkxLjYwOTguODY3MjUgMS41NjYtLjY4NTU3IDIuODE4MS0xLjQwMjMgNC4wNDI5Ljg2MzM0Ljc0ODA0IDEuNzI1MyAxLjQ5OCAyLjU5MjEgMi4yNDY2Ljg2MjgtLjg2MzUzIDEuNzI1NS0xLjcyODkgMi41NzkxLTIuNjA0Ny0xLjIzNDQtMi4wNDExLTEuMDU4Mi01LjIzMTEgMS43OTQ0LTUuNjI5IDMuMzkzNy0uNjIwOTMgNC40MTEyIDMuNjQyNyAyLjc3NDYgNS45MjU1IDMuMDQyIDMuODI1IDUuODE0NCA4LjA3MjQgNi43NTYzIDEyLjk0NyAxLjA2MzkgNS41ODM3LS4zNTI5MiAxMS4zNDMtMi43NjM5IDE2LjM5My4wNzk1NiAyLjUwMzgtLjExODcgNS4wMDQ1LS41MTY5NyA3LjQ3NjggNC4yNjgxLTEuNjc5NSA5LjUxODMtMi40ODEzIDEzLjU3Ny4xMzg0OCAyLjY0MTcgMS43Nzg5IDIuNTA2MSA1LjI2MTMgMi4xOTgxIDguMDU3OS02LjE2NS0zLjMwNi0xMy40MTItMi44NjktMjAuMDkyLTEuNzY2LTMuMzIxLTMuNTg5LTkuNjcyLTMuNTIzLTEzLjAxMi4wMTMtNi42ODgtMS4xODEtMTMuODg4LTEuNDU2LTIwLjExMiAxLjY5Ny0uMTk1NC0yLjgzMS0uMzQ4MS02LjM2MiAyLjM5NzMtOC4wOTEgNC4wNjk3LTIuNDk3IDkuMjUzNy0xLjczNiAxMy40NzctLjAxNy0uNDM0LTIuNTA2LS42MjEtNS4wNDYtLjUzNS03LjU4Ny0yLjQ2OC00LjM2NS00LjYzMS05LjQ0MS0zLjQ3NC0xNC41NDcgMS4zNTUtNS41MyA0Ljk2Ny0xMC4xMTYgOC40OC0xNC40NTctLjQyOC0xLjU1MS0xLjMxOS0zLjM2NS0uMjE2LTQuODQ5eiIgZmlsbD0iI2ZmZiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4OTYzMyIvPjxwYXRoIGQ9Im0yNS40ODcgMjQuNDgzYzEuMjM2Ny0yLjEwNjMgNC43MjA2LTEuNjYxMiA1LjQ5OTEuNjA5OC44NjcyNSAxLjU2Ni0uNjg1NTcgMi44MTgxLTEuNDAyMyA0LjA0MjkuODYzMzQuNzQ4MDQgMS43MjUzIDEuNDk4IDIuNTkyMSAyLjI0NjYuODYyOC0uODYzNTMgMS43MjU1LTEuNzI4OSAyLjU3OTEtMi42MDQ3LTEuMjM0NC0yLjA0MTEtMS4wNTgyLTUuMjMxMSAxLjc5NDQtNS42MjkgMy4zOTM3LS42MjA5MyA0LjQxMTIgMy42NDI3IDIuNzc0NiA1LjkyNTUgMy4wNDIgMy44MjUgNS44MTQ0IDguMDcyNCA2Ljc1NjMgMTIuOTQ3IDEuMDYzOSA1LjU4MzctLjM1MjkyIDExLjM0My0yLjc2MzkgMTYuMzkzLjA3OTU2IDIuNTAzOC0uMTE4NyA1LjAwNDUtLjUxNjk3IDcuNDc2OCA0LjI2ODEtMS42Nzk1IDkuNTE4My0yLjQ4MTMgMTMuNTc3LjEzODQ4IDIuNjQxNyAxLjc3ODkgMi41MDYxIDUuMjYxMyAyLjE5ODEgOC4wNTc5LTYuMTY1LTMuMzA2LTEzLjQxMi0yLjg2OS0yMC4wOTItMS43NjYtMy4zMjEtMy41ODktOS42NzItMy41MjMtMTMuMDEyLjAxMy02LjY4OC0xLjE4MS0xMy44ODgtMS40NTYtMjAuMTEyIDEuNjk3LS4xOTU0LTIuODMxLS4zNDgxLTYuMzYyIDIuMzk3My04LjA5MSA0LjA2OTgtMi40OTc5IDkuMjUzOC0xLjczNjUgMTMuNDc3LS4wMTcyOS0uNDMzNzYtMi41MDU5LS42MjExNC01LjA0NTktLjUzNDkzLTcuNTg3LTIuNDY4LTQuMzY1NC00LjYzMDktOS40NDExLTMuNDczNC0xNC41NDcgMS4zNTQ0LTUuNTMwOSA0Ljk2Ni0xMC4xMTYgOC40Nzk5LTE0LjQ1Ny0uNDI4NzYtMS41NTEtMS4zMTkyLTMuMzY1OC0uMjE2MTItNC44NDkxeiIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im0zMi4yMzQgMzMuMTkzYzIuOTI4Mi0xLjU5ODEgNS40MTE3IDEuNDE3NCA2Ljc4MDkgMy42NTMyIDIuNzkzNCA0LjUwNjkgNS4yMDM4IDEwLjQyOCAyLjk2MDYgMTUuNjE1LTIuNzQ3LTEuOTc0LTIuNzIyLTUuNzQ4LTMuODU0LTguNjYzLS45MjItNC4wNzQtNC41MzItNi43NTQtNS44ODgtMTAuNjA1eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4OTYzMyIvPjxwYXRoIGQ9Im0zMi4yMzQgMzMuMTkzYzIuOTI4Mi0xLjU5ODEgNS40MTE3IDEuNDE3NCA2Ljc4MDkgMy42NTMyIDIuNzkzNCA0LjUwNjkgNS4yMDM4IDEwLjQyOCAyLjk2MDYgMTUuNjE1LTIuNzQ3LTEuOTc0LTIuNzIyLTUuNzQ4LTMuODU0LTguNjYzLS45MjItNC4wNzQtNC41MzItNi43NTQtNS44ODgtMTAuNjA1eiIvPjxwYXRoIGQ9Im0yMi4yMjYgNTYuMTdjLjE2OTQ3LTIuNjgxOSAzLjI1MzYtMi45NzI2IDUuMjk4NC0zLjM5MDEgMy45NzYxLS40NjYwNiA4LjE1NTQtLjYwMTQ3IDEyLjAwMi42Nzc4OS45MjQzNy40MzExMSAzLjM1NDYgMS41NDQgMS42NDg3IDIuNzMyNC02LjMwMDYtLjk0ODY3LTEyLjY0NS0uOTEzMzMtMTguOTQ5LS4wMjAyOHoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODk2MzMiLz48cGF0aCBkPSJtMjIuMjI2IDU2LjE3Yy4xNjk0Ny0yLjY4MTkgMy4yNTM2LTIuOTcyNiA1LjI5ODQtMy4zOTAxIDMuOTc2MS0uNDY2MDYgOC4xNTU0LS42MDE0NyAxMi4wMDIuNjc3ODkuOTI0MzcuNDMxMTEgMy4zNTQ2IDEuNTQ0IDEuNjQ4NyAyLjczMjQtNi4zMDA2LS45NDg2Ny0xMi42NDUtLjkxMzMzLTE4Ljk0OS0uMDIwMjh6Ii8+PHBhdGggZD0ibTI5LjE1OSA1Ny41OTljMi4wMTczLS40NzY4MyA0LjE0MTQtLjYwNjkxIDYuMDI0Ni40NDUzNS0xLjg3NC45MzI3LTQuNjMxOCAxLjYyNzgtNi4wMjQ2LS40NDUzNXoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODk2MzMiLz48cGF0aCBkPSJtMjkuMTU5IDU3LjU5OWMyLjAxNzMtLjQ3NjgzIDQuMTQxNC0uNjA2OTEgNi4wMjQ2LjQ0NTM1LTEuODc0LjkzMjctNC42MzE4IDEuNjI3OC02LjAyNDYtLjQ0NTM1eiIvPjxwYXRoIGQ9Im0yMy4wNjIgNjUuMTE5Yy0uMjcyNDItMy4wNTQ4IDMuMTY0Ni0zLjQ0NTUgNS4zOTU0LTQuMDI4MiA0LjA3OTgtLjYwNzY4IDguOTA1NS0uNjU1MzIgMTIuMjE4IDIuMTYxNC4wMDUzLjUxOTIuMDE1OTEgMS41NTc2LjAyMTIgMi4wNzY4LTUuODA3Ny0xLjQ4NTctMTEuNzc1LS45NjU3Mi0xNy42MzQtLjIxMDA2eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4OTYzMyIvPjxwYXRoIGQ9Im0yMy4wNjIgNjUuMTE5Yy0uMjcyNDItMy4wNTQ4IDMuMTY0Ni0zLjQ0NTUgNS4zOTU0LTQuMDI4MiA0LjA3OTgtLjYwNzY4IDguOTA1NS0uNjU1MzIgMTIuMjE4IDIuMTYxNC4wMDUzLjUxOTIuMDE1OTEgMS41NTc2LjAyMTIgMi4wNzY4LTUuODA3Ny0xLjQ4NTctMTEuNzc1LS45NjU3Mi0xNy42MzQtLjIxMDA2eiIvPjwvZz48L2c+PHBhdGggZD0ibTUuNDgzOTIxOSA1NS41NTI1NDJjLjAwOTc4LTMuNDUwMDkgMS4zNDMwNzMzLTUuNDIzNDkgNC4zNzYwNzU3LTYuNDc2OTkyIDIuMjA4NzY4NC0uNzY3MjA2IDYuNDk0Mjk0NC0uNjU3MTI2IDkuMjMxNjU4NC4yMzcxMjhsMi4wODgyNjYuNjgyMjA1LS4xNDYwNjItMy42OTU3NDUtLjE0NjA2My0zLjY5NTc0OC0xLjMxNjU5My0yLjcxMTg2NWMtMS43NzUyMjQtMy42NTY1MzQtMi40MzMxMzQtNi4xNTI4NjYtMi40Mjg1OTMtOS4yMTQ4ODguMDA2My00LjI0MjczMyAxLjcxMDE4Ny04LjA4OTE5MiA2LjI4NTExOS0xNC4xODgzNTEgMS4zMDkwMzctMS43NDUxNjggMi4zMjY2MjctMy4zNTYwODMgMi4yNjEzMTItMy41Nzk4MTEtLjY5NDkyOC0yLjM4MDM5OS0uNzMyMTA4LTIuOTM4Nzc4Mi0uMjYxNjg5LTMuOTMwMTEyMiAxLjE3NTI5OS0yLjQ3Njc1OTUgNC41MDI0NDktMi4yMDY2MjQxIDUuNTA3NzQxLjQ0NzE4MDMuMjc0NDkuNzI0NjA3OS4wNTIzIDEuMzg0ODU1OS0xLjA2MzQ1NyAzLjE2MDE1MzktLjM3MzUzMS41OTQzMy0uMzMxMjM5LjY4MDYyOC44MjY2NjggMS42ODY4MjMuNjcxMTg3LjU4MzI0NiAxLjM0NzQ3MyAxLjA2NDA4OSAxLjUwMjg1OCAxLjA2ODU0LjE1NTM4OC4wMDQ1LjgxMTUzNC0uNTMwOTMyIDEuNDU4MTA1LTEuMTg5NzQgMS4xMTkzMTktMS4xNDA1MDMgMS4xNjA5Ni0xLjIzOTc4NC44NzAwMjMtMi4wNzQzNjUtLjQ0OTAwNi0xLjI4ODAxNC0uMzY3MDg0LTMuMDA5ODQ1OS4xNzUwNDUtMy42NzkxMTM2IDEuMTMxMzE3LTEuMzk2NjM0NiAyLjg3MTk3My0xLjU3MzM3ODMgNC4xNjAxMjUtLjQyMjQxMzUuNjg1ODE0LjYxMjc3MzguODc4MzAyIDEuMDI4NTQ2OC45ODM2MTggMi4xMjQ1ODIxLjA4NzQ0LjkxMDA0OC0uMDA0OCAxLjYyNTM1OS0uMjc3NzI4IDIuMTUzMzg2LS40MDIzMTguNzc4Mzg0LS4zODM4MjEuODI0Mzg4IDEuMTkwMTQgMi45NjAxNjMgMS44NjU2MjIgMi41MzE1NDIgNC4wNzYwMDUgNi42ODQ0OCA0LjY5MDk4IDguODEzNTYgMS40Mzg4NjEgNC45ODE0MTcuOTE1NjU4IDEwLjkwNDU3Ny0xLjQ1NTM5NSAxNi40NzY0NzItLjY2MTgwOSAxLjU1NTIyNy0uODI0MjYzIDIuMzIyODQyLS44Mjg2NDggMy45MTU0NDQtLjAwMyAxLjA4OTUyOS0uMTE5NDMxIDIuNzY5NjE5LS4yNTg3MzYgMy43MzM1MjYtLjEzOTMwNi45NjM5MTEtLjIyNzIzNiAxLjc3ODYxMi0uMTk1Mzk4IDEuODEwNDQ5LjAzMTg0LjAzMTg0Ljc3NDcyOC0uMTg0MTE0IDEuNjUwODYzLS40Nzk4OTcgNi41ODA5MDktMi4yMjE3IDEyLjgwMDAyMi0uNTc1NzM0IDEzLjk2NzAyMSAzLjY5NjU0OC4zNTQ5MzcgMS4yOTkzODcuMzk3ODE3IDQuNDc0NTc2LjA2MDQzIDQuNDc0NTc2LS4xMzEzOTUgMC0xLjAzMTMwOC0uMjk4MjYxLTEuOTk5ODA3LS42NjI4MDQtMy40MjEzNjEtMS4yODc3OTYtNS44Mjc0NTUtMS41OTg4NDItMTAuOTA5NDM3LTEuNDEwMzA1LTIuNTM4MDEyLjA5NDE2LTUuMTAyNzA0LjI2NjkzNy01LjY5OTMxNC4zODM5NTQtLjk3OTgzNS4xOTIxODItMS4yMjMzNzYuMTE2MDY1LTIuNTE4MTI0LS43ODcwMjEtLjc4ODM2LS41NDk4NzktMi4wNTI3NzUtMS4xNDgzNzItMi44MDk4MTQtMS4zMjk5ODItMi43NjcwNzYtLjY2MzgxMS02Ljg4Njk1NS4xOTY4NDgtOC4zMzg1IDEuNzQxOTQ3LS41NTM4MDEuNTg5NDk0LS42MjM1OTkuNTk1ODMyLTIuOTQxOTM2LjI2NzEzNy01LjU0MzUwNC0uNzg1OTYzLTExLjgzNjIyOS0uMzMxMDM3LTE1LjczODU4MzEgMS4xMzc4MDYtLjk2MzMzMzcuMzYyNTk4LTEuNzk4MDAzNi42NTkyNjgtMS44NTQ4MjE4LjY1OTI2OC0uMDU2ODE4IDAtLjEwMDYyNTktLjk0NTc2Mi0uMDk3MzUtMi4xMDE2OTV6bTM1LjI0ODI4MTEtNy4yMzQ1NTRjMC0xLjQyODA4Mi0uNTYwMTQ5LTEuOTc5Njg2LTIuOTM3NzYtMi44OTI5NDEtMy4xODE1NTYtMS4yMjIwNTktOS44MTc0ODctLjkwOTc5My0xMy4wMDE4NDEuNjExODI0LTEuMTg3MDc1LjU2NzIzNS0xLjk1ODcwNCAxLjYyNjgzMS0xLjk1ODcwNCAyLjY4OTY4NCAwIC41NTU3NzIuMDg0MjQuNTc5NjAxIDEuNDIxNzc0LjQwMjE3MiA1LjA5MTU5Ni0uNjc1NDI1IDEyLjIyNjg5OS0uNjMwMDMxIDE1LjEyMDU5OS4wOTYxOS41MjIwMzQuMTMxMDEzIDEuMDQwNjc4LjI1MDY5OSAxLjE1MjU0My4yNjU5NjYuMTExODY0LjAxNTI3LjIwMzM4OS0uNTEyNTM3LjIwMzM4OS0xLjE3Mjg5N3ptLTYuNTgwMzMzLTUuNjY3NDMzYzEuMjIxMjE1LS40NDMxNTQgMS4yMDI3NDQtLjc5NzM4My0uMDYzNzMtMS4yMjIzMjItMS4wOTM2ODctLjM2Njk2MS00LjU2OTUwNC0uMzEyMzEyLTQuOTU4ODM1LjA3Nzk3LS4xMDY1MzkuMTA2Nzk5LjE0ODY5MS40ODg4ODIuNTY3MTc3Ljg0OTA3NC42MDM0MTUuNTE5MzYgMS4wNTI0MDYuNjUwNjI4IDIuMTY5NDkyLjYzNDI2NS43NzQ3MzItLjAxMTM0IDEuODAzMzg5LS4xNjM4ODkgMi4yODU5LS4zMzg5ODN6bS0yLjM2ODgxOS0yLjc1OTAzYzMuMDU3NjI3IDAgNi41MzU1OTMuMDYxMDIgNy43Mjg4MTMuMTM1NTk0IDIuMTExODQuMTMxOTg5IDIuMTcxODczLjExODc4NSAyLjI1OTA4MS0uNDk2OTQxLjE5NzI4Ni0xLjM5MjkxNy0yLjAzMjg2NS0yLjUwODUwNy02LjA5NTQ2LTMuMDQ5MTM5LTMuODc2ODM2LS41MTU5MTEtOS44MTg0MzcuMDk4MzctMTIuMDM0MTcxIDEuMjQ0MTczLS43NDU2MjMuMzg1NTc2LTEuNjIwOTc1IDEuNjI3NDc3LTEuNjIwOTc1IDIuMjk5NzQ4IDAgLjIwNjgzNC42MzI5MTMuMjMxMzA4IDIuMTAxNjk1LjA4MTI2IDEuMTU1OTMyLS4xMTgwODMgNC42MDMzOS0uMjE0Njk5IDcuNjYxMDE3LS4yMTQ2OTl6bTEwLjgwMzcwNy00LjYzMDkyM2MuMjUwNDA1LS43MzM4OTguMzI0NDk0LTEuOTQ3MzkxLjIzODgxNS0zLjkxMTQ0OS0uMTM4MDU4LTMuMTY0Nzg4LS44MjUzMzctNS40ODg0NTEtMi41NjY3MTUtOC42Nzc5NjctMi4yOTU5MTgtNC4yMDUyMTMtNC4xNTM1ODktNS45NjkwMjUtNi4yNzkyMDgtNS45NjE5NDktMS43OTI0ODMuMDA2LTIuMDU5MjQ1LjI0MDEwMy0xLjU3MjUyOSAxLjM4MDIwMi4yMTYxODcuNTA2NDAyIDEuNDI2ODM0IDIuNDY2Njc1IDIuNjkwMzI3IDQuMzU2MTY0IDIuMDcwNTMgMy4wOTYzNjYgMi4zODM2ODYgMy43Mzg3MzMgMy4xNzI5MTEgNi41MDg0NzQuNDgxNjA2IDEuNjkwMTczIDEuMDc0NTE3IDMuNjU1MjU5IDEuMzE3NTgxIDQuMzY2ODU5LjQ5NDExNiAxLjQ0NjU5MiAxLjg1MzEwNCAzLjI1OTg3OCAyLjMyNjkwNyAzLjEwNDc3NS4xNjk4ODUtLjA1NTYxLjQ3MjI0NS0uNTc5OTEuNjcxOTExLTEuMTY1MTA5eiIgZmlsbD0iIzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii45ODc4MDIiLz48L3N2Zz4=')} +.is2d .rook.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMTQuNjg0IDI2LjY5NGMyLjI5NzQtLjAwMDUyNSA0LjU5NTItLjAwMDUyNSA2Ljg5MzctLjAwMDExOC0uMDAxIDEuNzIzNC0uMDAxIDMuNDQ2Ny0uMDAwODEgNS4xNzAzIDIuMDEwNC4wMDAzMTYgNC4wMjE0LjAwMDMzIDYuMDMzMy4wMDAwMTMtLjAwMS0xLjcyMzYtLjAwMS0zLjQ0Ny0uMDAwODctNS4xNzA1IDIuODcyLjAwMDE1OCA1Ljc0NDQuMDAwMTQ0IDguNjE3NS4wMDAwNTItLjAwMSAxLjcyMzUtLjAwMiAzLjQ0NjgtLjAwMDk1IDUuMTcwNSAyLjAxMDMuMDAwMjg5IDQuMDIxNC4wMDAzNDIgNi4wMzM1LjAwMDE0NS0uMDAxLTEuNzIzNi0uMDAyLTMuNDQ3LS4wMDEtNS4xNzA0IDIuMjk3Mi0uMDAwMzgyIDQuNTk1MS0uMDAwMzgyIDYuODk0LjAwMDA5Mi0uMDAxIDMuMTczLS4wMDEgNi4zNDU4LjAwMDIgOS41MTg5LTEuNDM2MiAxLjQ4MTctMi44NzM3IDIuOTYxNS00LjMwOTMgNC40NDI4LjAwNiA2LjI3MjYtLjAxMTggMTIuNTQ1LjAxIDE4LjgxOCAyLjYxNjEgMi4zNTM0IDMuMzc5NiA1Ljk5NTkgNi4xNDk1IDguMTkzMi4wMzkzIDIuMTM5Ny4wMzc3IDQuMjgwMS4wMzkzIDYuNDIxLTEyLjY5NS0uMDAwMjkxLTI1LjM5LS4wMDA4NzYtMzguMDg1LjAwMDIyMy0uMDAwNDctMi4xMzYuMDAwMTMtNC4yNzE1LjAyNzctNi40MDY1IDIuNzEyOS0yLjQwOTQgMy44MDA1LTYuMDc3MiA2Ljg2NC04LjE4My4wMTIyLTYuMjc5OS4wMDItMTIuNTYuMDA2LTE4LjgzOS0xLjcyNDEtMS40ODE3LTMuNDQ4Ni0yLjk2MjItNS4xNzExLTQuNDQ0Ni4wMDA1OS0zLjE3MzYtLjAwMDA1LTYuMzQ2OS4wMDA0NS05LjUyMDN6IiBmaWxsPSIjZmZmIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDg2MTcxIi8+PHBhdGggZD0ibTE0LjY4NCAyNi42OTRjMi4yOTc0LS4wMDA1MjUgNC41OTUyLS4wMDA1MjUgNi44OTM3LS4wMDAxMTgtLjAwMSAxLjcyMzQtLjAwMSAzLjQ0NjctLjAwMDgxIDUuMTcwMyAyLjAxMDQuMDAwMzE2IDQuMDIxNC4wMDAzMyA2LjAzMzMuMDAwMDEzLS4wMDEtMS43MjM2LS4wMDEtMy40NDctLjAwMDg3LTUuMTcwNSAyLjg3Mi4wMDAxNTggNS43NDQ0LjAwMDE0NCA4LjYxNzUuMDAwMDUyLS4wMDEgMS43MjM1LS4wMDIgMy40NDY4LS4wMDA5NSA1LjE3MDUgMi4wMTAzLjAwMDI4OSA0LjAyMTQuMDAwMzQyIDYuMDMzNS4wMDAxNDUtLjAwMS0xLjcyMzYtLjAwMi0zLjQ0Ny0uMDAxLTUuMTcwNCAyLjI5NzItLjAwMDM4MiA0LjU5NTEtLjAwMDM4MiA2Ljg5NC4wMDAwOTItLjAwMSAzLjE3My0uMDAxIDYuMzQ1OC4wMDAyIDkuNTE4OS0xLjQzNjIgMS40ODE3LTIuODczNyAyLjk2MTUtNC4zMDkzIDQuNDQyOC4wMDYgNi4yNzI2LS4wMTE4IDEyLjU0NS4wMSAxOC44MTggMi42MTYxIDIuMzUzNCAzLjM3OTYgNS45OTU5IDYuMTQ5NSA4LjE5MzIuMDM5MyAyLjEzOTcuMDM3NyA0LjI4MDEuMDM5MyA2LjQyMS0xMi42OTUtLjAwMDI5MS0yNS4zOS0uMDAwODc2LTM4LjA4NS4wMDAyMjMtLjAwMDQ3LTIuMTM2LjAwMDEzLTQuMjcxNS4wMjc3LTYuNDA2NSAyLjcxMjktMi40MDk0IDMuODAwNS02LjA3NzIgNi44NjQtOC4xODMuMDEyMi02LjI3OTkuMDAyLTEyLjU2LjAwNi0xOC44MzktMS43MjQxLTEuNDgxNy0zLjQ0ODYtMi45NjIyLTUuMTcxMS00LjQ0NDYuMDAwNTktMy4xNzM2LS4wMDAwNS02LjM0NjkuMDAwNDUtOS41MjAzeiIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im0yMS41NzggMzguNzU3YzcuMTgwNi0uMDAwMDQgMTQuMzYxLS4wMDAwNjYgMjEuNTQyLjAwMDAxMi0uMDAwOTUgMS40MzYtLjAwMDk1IDIuODcyLjAwMDA4IDQuMzA4NS03LjE4MTEuMDAwMDU0LTE0LjM2Mi0uMDAwMTMxLTIxLjU0My4wMDAwOTMtLjAwMS0xLjQzNjUtLjAwMS0yLjg3MjYuMDAwMDgtNC4zMDg2eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4NjE3MSIvPjxwYXRoIGQ9Im0yMS41NzggMzguNzU3YzcuMTgwNi0uMDAwMDQgMTQuMzYxLS4wMDAwNjYgMjEuNTQyLjAwMDAxMi0uMDAwOTUgMS40MzYtLjAwMDk1IDIuODcyLjAwMDA4IDQuMzA4NS03LjE4MTEuMDAwMDU0LTE0LjM2Mi0uMDAwMTMxLTIxLjU0My4wMDAwOTMtLjAwMS0xLjQzNjUtLjAwMS0yLjg3MjYuMDAwMDgtNC4zMDg2eiIvPjxwYXRoIGQ9Im0yMS41NzggNTguNTc3YzcuMTgwNy0uMDAwMzQyIDE0LjM2MS0uMDAwMTE5IDIxLjU0My0uMDAwMTE5LS4wMDEgMS4xNDg0LS4wMDEgMi4yOTc0LjAwMDA3IDMuNDQ2OC03LjE4MTItLjAwMDA1Mi0xNC4zNjIgMC0yMS41NDMtLjAwMDAyNS0uMDAwODgtMS4xNDk0LS4wMDA4LTIuMjk4My4wMDAxOC0zLjQ0Njd6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDg2MTcxIi8+PHBhdGggZD0ibTIxLjU3OCA1OC41NzdjNy4xODA3LS4wMDAzNDIgMTQuMzYxLS4wMDAxMTkgMjEuNTQzLS4wMDAxMTktLjAwMSAxLjE0ODQtLjAwMSAyLjI5NzQuMDAwMDcgMy40NDY4LTcuMTgxMi0uMDAwMDUyLTE0LjM2MiAwLTIxLjU0My0uMDAwMDI1LS4wMDA4OC0xLjE0OTQtLjAwMDgtMi4yOTgzLjAwMDE4LTMuNDQ2N3oiLz48L2c+PC9nPjxwYXRoIGQ9Im0xMy4wNzExODYgNTQuODM5OTg0YzAtMi40NzM4MzMuMDg0NDUtMy4xNTU1MjguNDI2MDYxLTMuNDM5MDM4LjIzNDMzMy0uMTk0NDc4IDEuNDI0MTYzLTEuNzUzNDg2IDIuNjQ0MDY3LTMuNDY0NDU4IDEuMjE5OTA1LTEuNzEwOTc1IDIuNTUzNjAxLTMuMzU5MjM4IDIuOTYzNzcxLTMuNjYyODA5bC43NDU3NjItLjU1MTk0OS0uMDA1OC05LjY0MzkxNS0uMDA1OC05LjY0MzkxNy0yLjU2MjA5OS0yLjE2OTQ5MS0yLjU2MjA5OC0yLjE2OTQ5Mi0uMDA4My00LjY3Nzk2Ni0uMDA4My00LjY3Nzk2NmgzLjM4OTgzMSAzLjM4OTgzdjIuNTc2MjcxIDIuNTc2MjcxaDMuMTE4NjQ0IDMuMTE4NjQ0di0yLjU3NjI3MS0yLjU3NjI3MWg0LjIwMzM5IDQuMjAzMzl2Mi41NzYyNzEgMi41NzYyNzFoMy4xMTg2NDQgMy4xMTg2NDR2LTIuNTc2MjcxLTIuNTc2MjcxaDMuMzg5ODMxIDMuMzg5ODN2NC42ODQzMjggNC42ODQzMjhsLTIuMTY5NDkxIDIuMTU2NzY4LTIuMTY5NDkyIDIuMTU2NzY3djkuNjU5MjQ3YzAgOS40Mzg5OTMuMDEyODUgOS42NzA4ODcuNTY0MTI1IDEwLjE2OTc3My4zMTAyNy4yODA3ODkgMS4yMzkxMjkgMS42MTE1NjkgMi4wNjQxMzMgMi45NTcyODUuODI1MDAzIDEuMzQ1NzE3IDEuODk5NjE1IDIuODczODc3IDIuMzg4MDI3IDMuMzk1OTExLjg2ODc2Mi45Mjg1NjkuODkyMDU0IDEuMDE4MjUxIDEuMDc0MTAxIDQuMTM1NTkzbC4xODYwODMgMy4xODY0NDFoLTE5LjAwMjY0MS0xOS4wMDI2NDJ2LTMuMDg1NDR6bTMwLjEwMTY5NS0xMC40NzM4ODJ2LTEuODk4MzA1aC0xMC44NDc0NTctMTAuODQ3NDU4djEuODk4MzA1IDEuODk4MzA1aDEwLjg0NzQ1OCAxMC44NDc0NTd6bTAtMTkuMzg5ODMxdi0yLjMwNTA4NWgtMTAuODQ3NDU3LTEwLjg0NzQ1OHYyLjMwNTA4NSAyLjMwNTA4NWgxMC44NDc0NTggMTAuODQ3NDU3eiIgZmlsbD0iIzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii45ODc4MDIiLz48L3N2Zz4=')} +.is2d .queen.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMjIuMzIyIDI3Ljc3NWMtLjE2MzU0LTMuMTg3OSAxLjE0MDctMy42MTIzIDMuMjM0NC0xLjE0NTkgMS45NzEgMS44Nzk1LjIyOTg2IDIuNTQ5MiAxLjQ0MzIgNC43MDIyIDEuNDY3NiAzLjIxOTkgMy4wNjU2IDYuMzc4OCA0LjU1OTkgOS41ODY4IDEuNjE4Ny0zLjMxMTUgMy4zODQ3LTYuNTUwNyA0Ljk1MzgtOS44ODU3IDEuMDc3OC0yLjI0NjIuNzc4MTgtMy41NzY1IDMuMTI3LTUuMTk5MSAyLjI3MjgtMS43NjA2LjkzNjgxLTIuNzU4OS43ODUxNC4xMzIxMi4yNTkyMSAyLjA2OTguNTc2MTggMi45NjYzLjg5MDk5IDUuMTgzMiAxLjMyNzMgNS4yNjUyIDIuNTI0NCAxMC41NjIgMy43OTk4IDE1Ljg0IDIuNDgwNi0xLjkxMjUgNC45NjQ2LTMuODIwNyA3LjQyOTQtNS43NTM4LjMzNTc1LTEuNTE5OCAxLjU0NDktLjA2MzAyIDMuMTIxNS0uOTcyMjYgMi4xNjctMS42MTQ2LjE3MTAxLTIuNTMxNy0uMzI2NS4xMTgwNS0uMTgyODMgMS44NTMxIDEuNzY4MiAxLjk5Ny4zODAxOCAyLjczNzktMS43OTAyIDQuMjAzMS0zLjk2MSA4LjI0MTQtNS42MjUxIDEyLjQ5Ni0uOTExMTQgNC44MDk2LTEuMDI1NyA5Ljc0MTQtMS42MzA5IDE0LjU5OS02LjQ0NCAzLjk5NC0xNC4zNDMgNC4yNzQtMjEuNjg5IDMuNzIyLTQuMDE2LS4yNzQtOC4wMzQtMS4zMjMtMTEuMzYzLTMuNjU5LS42NzctNC44MTMtLjk4MS05LjY4NC0xLjg2NS0xNC40NjItMS42MDMtNC4yOTktMy42OTU3LTguNC01LjQyMzItMTIuNjUxLTEuNzMxMS0uNzA2LS44MjYxLTIuNTk1LS40MjcyLTQuODQ3LjI2MTYxLTMuMjE5Ny0uMTEwMDItMi4yNzIuOTk5NDUuNzMxMjQuMDM4Ny43OTExOCAyLjMyODQgMS41NDM5IDIuMzY3MiAyLjMzNTEgMi4zMDQzIDEuODgyOCA0LjYyMjQgMy43NDg2IDYuOTM4OSA1LjYxNjcgMi4xNDk1LTcuNTYyOSAzLjM5ODYtMTMuMDY2IDQuMzItMTkuMjI1eiIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im0yMC45MDMgNTMuNTYxYzguMDczOC0xLjYyMjIgMTYuODIyLTEuODE4NiAyNC42MjIgMS4xMTk1IDEuNTQzMi4zMjYzOSAxLjUzNjMgMi4wODgxIDIuMDY4MyAzLjI1MzktNC43NjQzLS4yNjk2Ny05LjQ1MTEtMS40MDM5LTE0LjI0My0xLjMzNjEtNS43NjkxLS4yNjc3NC0xMS40OC42MjAyNi0xNy4xNzEgMS40MDM0LTEuNDM4NC0zLjE0ODMgMi41OTg4LTMuNzYzOCA0LjcyNDMtNC40NDA2eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA5MjQ5NiIvPjxwYXRoIGQ9Im0yMC45MDMgNTMuNTYxYzguMDczOC0xLjYyMjIgMTYuODIyLTEuODE4NiAyNC42MjIgMS4xMTk1IDEuNTQzMi4zMjYzOSAxLjUzNjMgMi4wODgxIDIuMDY4MyAzLjI1MzktNC43NjQzLS4yNjk2Ny05LjQ1MTEtMS40MDM5LTE0LjI0My0xLjMzNjEtNS43NjkxLS4yNjc3NC0xMS40OC42MjAyNi0xNy4xNzEgMS40MDM0LTEuNDM4NC0zLjE0ODMgMi41OTg4LTMuNzYzOCA0LjcyNDMtNC40NDA2eiIvPjxwYXRoIGQ9Im0yOS4xNCA1OC45MTZjMS44OTg4LS43NzgwNiA0Ljg3NDktLjkzNTU2IDUuNzcxIDEuMzU2NS0uODQxNjMgMy4yOTU3LTguNTk1MiAyLjAyNTEtNS43NzEtMS4zNTY1eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA5MjQ5NiIvPjxwYXRoIGQ9Im0yOS4xNCA1OC45MTZjMS44OTg4LS43NzgwNiA0Ljg3NDktLjkzNTU2IDUuNzcxIDEuMzU2NS0uODQxNjMgMy4yOTU3LTguNTk1MiAyLjAyNTEtNS43NzEtMS4zNTY1eiIvPjxwYXRoIGQ9Im0xNi40NzggNjIuMTE4YzEuNDE4My0uOTYzMDggMy4wMTU0LS44MzM2MyA0LjUyNTctLjEzNzg2LTEuMzE1OC41NTA3Mi00LjQ2MSAzLjAyMjctNC41MjU3LjEzNzg2eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA5MjQ5NiIvPjxwYXRoIGQ9Im0xNi40NzggNjIuMTE4YzEuNDE4My0uOTYzMDggMy4wMTU0LS44MzM2MyA0LjUyNTctLjEzNzg2LTEuMzE1OC41NTA3Mi00LjQ2MSAzLjAyMjctNC41MjU3LjEzNzg2eiIvPjxwYXRoIGQ9Im00Mi4zNzggNjIuMDExYzEuODk5Ny0xLjE5MyAzLjgwOC0uNDc2ODggNS4xMDExIDEuMTk3MS0xLjg0NzkuNDcwNDctMy41OTAyLS4xNDE1My01LjEwMTEtMS4xOTcxeiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA5MjQ5NiIvPjxwYXRoIGQ9Im00Mi4zNzggNjIuMDExYzEuODk5Ny0xLjE5MyAzLjgwOC0uNDc2ODggNS4xMDExIDEuMTk3MS0xLjg0NzkuNDcwNDctMy41OTAyLS4xNDE1My01LjEwMTEtMS4xOTcxeiIvPjxwYXRoIGQ9Im0yMC41MDkgNjUuMjU2YzYuMjEwOS0xLjcxMiAxMi44MjgtMS41MDUzIDE5LjE2OS0uNzA2OTMgMi40MzE1LjM5MDA5IDYuMjM5OSAxLjE1ODUgNS40MjI2IDQuNDk3LTguNjkzNC0zLjA3OTctMTguNDAyLTMuMTA3Ny0yNy4wODYuMDE5NjMtLjQxNzIxLTEuODczNS42Njg4OC0zLjQyMjkgMi40OTQzLTMuODA5N3oiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wOTI0OTYiLz48cGF0aCBkPSJtMjAuNTA5IDY1LjI1NmM2LjIxMDktMS43MTIgMTIuODI4LTEuNTA1MyAxOS4xNjktLjcwNjkzIDIuNDMxNS4zOTAwOSA2LjIzOTkgMS4xNTg1IDUuNDIyNiA0LjQ5Ny04LjY5MzQtMy4wNzk3LTE4LjQwMi0zLjEwNzctMjcuMDg2LjAxOTYzLS40MTcyMS0xLjg3MzUuNjY4ODgtMy40MjI5IDIuNDk0My0zLjgwOTd6Ii8+PC9nPjxnIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggZD0ibTEyLjUgMTIuNWE0LjgyMTQgMy43NSAwIDEgMSAtLjAwMDI1NS0uMDM4NTciIHRyYW5zZm9ybT0ibWF0cml4KC43NDM1MiAwIDAgLjkwMzgxIDIuMzI2NyAyOC41OTEpIi8+PHBhdGggZD0ibTEyLjUgMTIuNWE0LjgyMTQgMy43NSAwIDEgMSAtLjAwMDMxNi0uMDQyOTYiIHRyYW5zZm9ybT0ibWF0cml4KC43NDM1MiAwIDAgLjkwMzgxIDUwLjI1NSAyOC43NikiLz48cGF0aCBkPSJtMTIuNSAxMi41YTQuODIxNCAzLjc1IDAgMSAxIC0uMDAwMDg3LS4wMjI1NCIgdHJhbnNmb3JtPSJtYXRyaXgoLjgzODE1IDAgMCAxLjAyNTUgMTcuMjYzIDEzLjg0NikiLz48cGF0aCBkPSJtMTIuNSAxMi41YTQuODIxNCAzLjc1IDAgMSAxIC0uMDAwMjI3LS4wMzYzNyIgdHJhbnNmb3JtPSJtYXRyaXgoLjgzODE1IDAgMCAxLjAyNTUgMzMuMjYxIDEyLjg3NykiLz48L2c+PC9nPjxwYXRoIGQ9Im0yNS4xMzEzOTkgNTcuNjQyODc3Yy0yLjM1MzEzNS0uMzA3NzItNC44Njc5MjEtMS4wMDI3NjktNi43NTYzODktMS44NjczNjItMi45NTY3ODYtMS4zNTM2OTUtMi43OTQ4MjQtMS4wMTMwODUtMy41NTU0NDctNy40NzcyMS0uOTQyNzU5LTguMDEyLTEuMDQwOTU4LTguNDM0ODk2LTMuMDE4MzEtMTIuOTk4NDQ2LS45NzM4MS0yLjI0NzQ2Ni0yLjE0ODIxNjUtNC45NzI5MzMtMi42MDk3OTI3LTYuMDU2NTk1LS43NjU1NDQxLTEuNzk3MzAyLS45Mjc1MjAyLTEuOTk0MDctMS44NDQ4MS0yLjI0MTA3MS0xLjM2OTU0MDQtLjM2ODc3OC0yLjY4MjI0MzUtMS44OTExNTUtMi42ODIyNDM1LTMuMTEwNjY4IDAtMi4wMTQ3MzcgMi42OTYyMTYxLTMuNzk1MDU1IDQuNzMwNjIyNC0zLjEyMzY0MSAxLjQ5NjgzOTguNDk0MDAyIDEuOTA5ODkzOCAxLjE3ODIyMSAxLjk0MDExNDggMy4yMTM3NzZsLjAyNjY3IDEuNzk2MzQ1IDMuMzAwNTEzIDIuNjkwMDI5YzEuODE1MjgzIDEuNDc5NTE3IDMuMzU2OTY3IDIuNjMzNTc3IDMuNDI1OTY1IDIuNTY0NTc5LjI0MjcyNi0uMjQyNzI2IDMuMDcwNzA0LTExLjc4MzA3MyAzLjUzODkxNS0xNC40NDE1MThsLjQ3MzgxNC0yLjY5MDI2MS0uNjUwNTA5LS41MjYyMDZjLTEuNzIxMDk3LTEuMzkyMjE5LTIuMDYxODYxLTMuMTI5NDg1LS44ODc1ODQtNC41MjUwMzQ4IDEuNTg5NTUxLTEuODg5MDczOSA0LjY0NjU1Ni0yLjUzOTM0MDQgNS45MjU0NjktMS4yNjA0Mjc2IDEuMzAzMjI3IDEuMzAzMjI2OCAxLjQ5MzU4MSA0LjA3NjA0MTQuMzg3NzEgNS42NDc2Mzg0LS41MDkwMS43MjMzNzQtLjUwODk2Mi43NTU4NDMuMDAzIDIuMDMzODk4LjI4NjEzLjcxNDMzNCAxLjQ1ODc3MiAzLjI1MTMzMiAyLjYwNTg3IDUuNjM3NzczbDIuMDg1NjMyIDQuMzM4OTgzIDIuNTMyMDQ2LTUuMDE2OTVjMS4zOTI2MjctMi43NTkzMjIgMi43MzcyNDUtNS42MTM2MTcgMi45ODgwNDEtNi4zNDI4NzkuNDIwMzM5LTEuMjIyMjQ3LjQyMTQ5OS0xLjM0NTIzNC4wMTQ4Ni0xLjU3MjgtLjY2Mzk4OS0uMzcxNTg4LTEuMjU0NjgtMS42OTY2ODItMS4yNTQ2OC0yLjgxNDYyMjEgMC0uNzg5MzM4Ni4yMTE4NC0xLjIwNjM2NDMgMS4wMjY3OC0yLjAyMTMwNDMgMi4zOTExOTUtMi4zOTExOTUgNS43NzExNzMtMS44NjI4MDkxIDYuNTQ4NDMxIDEuMDIzNzA0My41MjA1MjQgMS45MzMwNzgxLS4xMzQyOTEgMy43Nzg4MDMxLTEuNjExNjYzIDQuNTQyNzgxMS0uNDQ2MDUzLjIzMDY2NC0uODExMDA1LjYxNjYyLS44MTEwMDUuODU3NjgxIDAgLjYzMTQxNCAzLjg1MjA0OSAxNi43Mjc4MDQgNC4wNjI0NDMgMTYuOTc1NTU0LjA5Njg5LjExNDA5IDEuODE1Njk0LTEuMDcwMTAxIDMuODE5NTY5LTIuNjMxNTM2IDMuNTYzOTU3LTIuNzc3MDYxIDMuNjQzOTU3LTIuODYyNTE2IDMuNjY4MzgtMy45MTg0ODYuMDgwMzgtMy40NzU0NzMgNC45NTU3NzItNC44ODI5MTQgNi41MDkxMi0xLjg3OTA3MSAxLjA5NzcxNiAyLjEyMjc1MS0uMzMxMDg2IDQuODMxODI2LTIuNTQ4Mzc1IDQuODMxODI2aC0xLjAyMjY3NmwtMS40NTkyOTIgMy4xODY0NDFjLTQuNTQ1NzAxIDkuOTI1Nzg0LTQuMjYzNzQzIDguOTM1MDk3LTUuMTQ3NjEgMTguMDg2NTE2LS42MDE2ODkgNi4yMjk4MDktLjM3NzgxNyA1LjgwNzgyOS0zLjgxMzc2MyA3LjE4ODU4OS0yLjM2MjQ3OC45NDkzOC00LjUyMTAxNyAxLjUyMDMwNi03LjE4NjQ0IDEuOTAwNzk3LTIuMTk2MjU4LjMxMzUxMy0xMC4zNTM2NDYuMzEyOTktMTIuNzUzMzQ3LS4wMDA4MTR2LS4wMDAwMDh6bS0uNTM0Nzg5LTYuMTQ4NDIzYzEuNzM2MzExLS4zMjgyNTIgMy44MTAyODItLjQ1Nzg4NSA3LjE4NjQ0MS0uNDQ5MTgyIDQuOTE5NjEyLjAxMjY5IDcuNzUwOTk0LjQyMDM2OSAxMS43OTY2MSAxLjY5ODU4MmwxLjYyNzExOS41MTQwODguMDg2ODctLjk2NTg2OWMuMTcwMjY5LTEuODkzMTE0LTEuMjYxNjktMy4wMDk1MDItNC44MzI2MzUtMy43Njc2MzEtMy4zNDI3OTYtLjcwOTY5NS0xNC4zMDcwMjMtLjcxMzU3LTE3LjYyNzExOS0uMDA2Mi0xLjI2Nzc5Ni4yNzAxMDEtMi43MzIyMDMuNjk3MjItMy4yNTQyMzcuOTQ5MTUyLTEuMTA2MzI1LjUzMzkxMi0yLjAzNzU0IDIuMTcxNDcxLTEuNzkxNzQxIDMuMTUwODEybC4xNjA0OTUuNjM5NDY2IDIuMTAzNzU5LS42NTA4ODVjMS4xNTcwNjctLjM1Nzk4IDMuMjAyMDYzLS44NTg1MTcgNC41NDQ0MzYtMS4xMTIyOTZ6bS00Ljg4NzM2NC00LjYwODU3NWMuODIzNjQ0LS40MDM5NTEgMS40OTc1MzQtLjgyMjMxOCAxLjQ5NzUzNC0uOTI5NzAzIDAtLjEwNzM4NC0uNjQzNDczLS4zMzkyNDktMS40Mjk5NC0uNTE1MjUxLTEuMTk3NjUyLS4yNjgwMjUtMS41OTQxMy0uMjUxNDA0LTIuNDQwNjc4LjEwMjMwOC0xLjA0NTU3Mi40MzY4NjctMS4zMTQwMDYgMS4xMjI5OTEtLjY4NTMxNSAxLjc1MTY4Mi41MTA0ODkuNTEwNDkgMS40MzU4NzMuMzg2NzI2IDMuMDU4Mzk5LS40MDkwMzZ6bTI3LjUzMTQzMi40NTEyM2MuMzQwNDg1LS4yMzAxMTguMjU4NjQ0LS40MDIxNS0uNTAyMTgtMS4wNTU1OS0xLjA4NDEzMy0uOTMxMTE0LTIuMzM2MzQyLTEuMjE4NTYzLTMuNTE2MzkxLS44MDcxOTUtMS4wOTE0NTIuMzgwNDgtMS4wODc2MzQuNjU5ODgxLjAxNjgxIDEuMjMxMDEzIDEuNzE5MzMuODg5MTAxIDMuMjYwOTA4IDEuMTMyNDc3IDQuMDAxNzU0LjYzMTc3MnptLTEyLjgxOTQ0Ny0xLjk2MDQ5OWMuNjE0MjQ2LS42MTQyNDUuNjg1OTc0LS44MzYzOTguNDY3NDMzLTEuNDQ3NzE4LS4xNDE5ODUtLjM5NzE3MS0uNjgzMzctLjk0OTQxMy0xLjIwMzA3OC0xLjIyNzIwNS0yLjU5OTM5OS0xLjM4OTQyNC02LjM0ODcxNy4zNTQzNjItNS4wNDM4MzggMi4zNDU4Ni42Mzg4NTMuOTc1MDEgMS4zNzU0NTQgMS4yMjQwMDMgMy4zNTE4MzYgMS4xMzMwMTIgMS40MjUzNTMtLjA2NTYyIDEuODIwMDE5LS4xOTYzMiAyLjQyNzY0Ny0uODAzOTQ5em0tMTMuNDg1NjM4LTMuODg1MDA2YzEuNzE1MjU0LS4yMzYwNyA1LjgwMzM5LS40OTMwNjggOS4wODQ3NDYtLjU3MTExIDUuNzU3ODg3LS4xMzY5NDEgOC45ODU5MjguMDgzNTEgMTYuNzQ1NzYzIDEuMTQzNTk4LjU1OTMyMi4wNzY0MSAxLjAxNjk0OS4wODEwNSAxLjAxNjk0OS4wMTAzIDAtLjA3MDc0LS4yNTA0NDktLjc5ODAwOS0uNTU2NTUzLTEuNjE2MTQzLS41MjkzMDUtMS40MTQ2OTktLjYzMTczNy0xLjUxNTY1MS0yLjA5MjM1My0yLjA2MjEzNy01LjcwMzQ0OS0yLjEzMzkzNy0xNC4wNzY2MTYtMi43MTMxOTEtMjEuNDg2Njg3LTEuNDg2NDQ2LTUuNjY1NTQxLjkzNzkzMy03Ljg2NDQwNyAyLjAzMTEzNC03Ljg2NDQwNyAzLjkwOTkxNyAwIDEuMjYwMDYyLjE1NDI2NCAxLjQxOTY0MiAxLjIwMDk0NyAxLjI0MjMzNS40NTgxMjMtLjA3NzYxIDIuMjM2MzQxLS4zMzQyNDggMy45NTE1OTUtLjU3MDMxOXoiIGZpbGw9IiMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuOTg3ODAyIi8+PC9zdmc+')} +.is2d .king.black {background-image:url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMjQuMjUxIDIzLjIxMmM1LjE4MDMtLjAwMzQgMTAuMzYxLS4wMDM1IDE1LjU0My4wMDAwMjguMDAwNzMgMy44NjU5LS4wMDEyIDcuNzMxNy0uMDAwNTA0IDExLjU5OCAzLjAyMTYtMS45Mzc3IDYuNDgzMy0zLjU5MjUgMTAuMTgxLTMuMTcwNSA0LjY0ODYuMjI4ODQgOS4wMDEgNC4yMDU4IDguOTM2NSA4Ljk5NzktLjA1MTg5IDYuNDU4Ny00LjIzMDcgMTIuMDc5LTkuMDU5MiAxNi4wMDEtLjI5MTA4IDQuNDExNC0uNTIwOTkgOC44MjY1LS43NzEzOCAxMy4yNDEtNC4xMjIgNC4wNjYtMTAuMjY4IDQuMDgzLTE1LjY3IDQuMTk5LTUuMDM5LS4wNTgtMTAuMzEyLjE4Ny0xNS4wNTItMS44MDMtMS40NTQtLjczNS0zLjM0OS0xLjcyLTMuNDI1LTMuNTY4LS4zNjYtNC4wMjEtLjQ0OS04LjA2My0uNzQ3LTEyLjA4OS00LjkxMDQtMy44MjctOC44OTMtOS41NTUtOS4wOTY5LTE1Ljk0LS4xMjUyNS00Ljg0OTcgNC4zNTQ2LTguNzk3IDkuMDExLTkuMDQ2IDMuNjgyMi0uMzg4MzIgNy4xMzMgMS4yNTIgMTAuMTUgMy4xODEyLS4wMDEyLTMuODY3MS0uMDAzMS03LjczMzktLjAwMDI2Ni0xMS42MDF6IiBmaWxsPSIjZmZmIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDkxNTYzIi8+PHBhdGggZD0ibTI0LjI0NyAyMy4yMWMtLjAwMjggMy44NjctLjAwMTIgNy43NDQ1IDAgMTEuNjEyLTMuMDE3MS0xLjkyOTItNi40NjkzLTMuNTgyMS0xMC4xNTItMy4xOTM4LTQuNjU2NC4yNDg5Ny05LjEzNjIgNC4yMDY4LTkuMDEwOSA5LjA1NjYuMjAzODggNi4zODQ2IDQuMTkyMSAxMi4wOTcgOS4xMDIyIDE1LjkyMy4yOTgwNCA0LjAyNjQuMzg2MjMgOC4wNjk1Ljc1MjgxIDEyLjA5MS4wNzU2NiAxLjg0NzYgMS45Njg0IDIuODQ3IDMuNDIxOSAzLjU4MTYgNC43NCAxLjk5MDYgMTAuMDE3IDEuNzQ0OSAxNS4wNTYgMS44MDIyIDUuNDAxOC0uMTE1ODggMTEuNTUtLjEzMTU2IDE1LjY3Mi00LjE5NzUuMjUwMzktNC40MTQxLjQ2MTczLTguODQyNy43NTI4MS0xMy4yNTQgNC44Mjg1LTMuOTIxOSA5LjAyNzUtOS41MzI5IDkuMDc5NC0xNS45OTIuMDY0NS00Ljc5MjEtNC4yOTM5LTguNzU5My04Ljk0MjUtOC45ODgxLTMuNjk4MS0uNDIxOTItNy4xNTI3IDEuMjMzMy0xMC4xNzQgMy4xNzA5LS4wMDA3My0zLjg2NjEuMDAwNzMtNy43NDU2IDAtMTEuNjEyLTUuMTgyLS4wMDM1LTEwLjM3OC0uMDAzNC0xNS41NTggMHptNy40MTQgMTQuNTc3YzEuNjk5MS0uMTQxODEgMy41NjQzIDEuMDA2NCAzLjYwNDQgMi44Mjg4LjM3NzIxIDIuNjg5NS0zLjMwNTggNC4yOTE0LTUuMjY5NyAyLjY0NjItMS42OTg3LTEuMDQ4My0xLjYzMjktMy44ODM5LjA5MTI1LTQuODgxOS40NTgwNy0uMzU4MTkgMS4wMDc3LS41NDU4NSAxLjU3NDEtLjU5MzEyeiIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im0yNi4xODggMjYuNjUyYy42MDY3NS0uNzcwNzUgMS4yMTc4LTEuNTQgMS44MzMyLTIuMzA3OSAxLjM1MzYgMS4xMjM0IDIuNjgwNCAyLjI4MDcgMy45OTc5IDMuNDUwNSAxLjMxNzEtMS4xNjkxIDIuNjQ1NC0yLjMyNjEgNC4wMDQ4LTMuNDUuNjA4ODguNzY3MjUgMS4yMTg4IDEuNTM2IDEuODI5NyAyLjMwNjItMS4xNTQ3IDEuMDQ5Ny0yLjMxMzIgMi4wOTU0LTMuNDY3NiAzLjE0MDMgMS4yMDk5IDEuMTA0NCAyLjQxODkgMi4yMTIzIDMuNjEzOCAzLjMzODMtLjQ3OTEyLjU1MDQ1LTEuNDM3NCAxLjY1MTQtMS45MTY1IDIuMjAxOC0xLjM2ODEtMS4xNDIyLTIuNzE4Mi0yLjMwNTMtNC4wNTc3LTMuNDc2LTEuMzQ5IDEuMTY3Mi0yLjcwMDIgMi4zMjk3LTQuMDY3MSAzLjQ3Mi0uNDc4ODItLjU0OTQtMS40MzY1LTEuNjQ4Mi0xLjkxNTMtMi4xOTc2IDEuMTg5Ni0xLjEyNjUgMi4zOTg0LTIuMjM0NCAzLjYxNDQtMy4zMzY5LTEuMTYxNC0xLjA0NTItMi4zMTY5LTIuMDkxMy0zLjQ2OTYtMy4xNDA5eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA5MTU2MyIvPjxwYXRoIGQ9Im0yNi4xODggMjYuNjUyYy42MDY3NS0uNzcwNzUgMS4yMTc4LTEuNTQgMS44MzMyLTIuMzA3OSAxLjM1MzYgMS4xMjM0IDIuNjgwNCAyLjI4MDcgMy45OTc5IDMuNDUwNSAxLjMxNzEtMS4xNjkxIDIuNjQ1NC0yLjMyNjEgNC4wMDQ4LTMuNDUuNjA4ODguNzY3MjUgMS4yMTg4IDEuNTM2IDEuODI5NyAyLjMwNjItMS4xNTQ3IDEuMDQ5Ny0yLjMxMzIgMi4wOTU0LTMuNDY3NiAzLjE0MDMgMS4yMDk5IDEuMTA0NCAyLjQxODkgMi4yMTIzIDMuNjEzOCAzLjMzODMtLjQ3OTEyLjU1MDQ1LTEuNDM3NCAxLjY1MTQtMS45MTY1IDIuMjAxOC0xLjM2ODEtMS4xNDIyLTIuNzE4Mi0yLjMwNTMtNC4wNTc3LTMuNDc2LTEuMzQ5IDEuMTY3Mi0yLjcwMDIgMi4zMjk3LTQuMDY3MSAzLjQ3Mi0uNDc4ODItLjU0OTQtMS40MzY1LTEuNjQ4Mi0xLjkxNTMtMi4xOTc2IDEuMTg5Ni0xLjEyNjUgMi4zOTg0LTIuMjM0NCAzLjYxNDQtMy4zMzY5LTEuMTYxNC0xLjA0NTItMi4zMTY5LTIuMDkxMy0zLjQ2OTYtMy4xNDA5eiIvPjxwYXRoIGQ9Im0xMS45NjkgNDMuNDI1Yy4xMjYxNy0zLjY5NjcgNC43NDM4LTQuNzA4MSA3LjU5NDktMy41MDM1IDUuMjg3OCAxLjY4NzggNy45MDQxIDcuMDYzOSA5Ljc0NzEgMTEuODczIDEuODIyNi0uMDIwNjggMy42NDg5LS4wMzgxIDUuNDc2NS0uMDcxNDggMS43NDcxLTQuODI5OSA0LjU2MzEtOS45NjY4IDkuNjg1Ni0xMS43OTggMi44MzY2LTEuMjMzNCA3LjQ3NzEtLjE4MjM0IDcuNTk4OSAzLjUwNDQtLjE1MDg3IDQuMTIyOC0yLjcwNzMgNy42NTQ5LTUuODA3NSAxMC4xNzEuNzY2MTQgMS4xMDI4IDEuMzA4IDIuMzA3NiAxLjI2MjcgMy42ODYyLTQuNjgwNS0uOTg4MzctOS4zMzA4LTIuMzAyNi0xNC4xNDctMi4zOTQ3LTUuNzMxNS0uMzA0OTgtMTEuMzE1IDEuMTU4Ni0xNi44NTQgMi4zOTQ1LS4wNjEzMS0xLjM4LjQ2NDE0LTIuNTg2NSAxLjI3MjUtMy42NzE2LTMuMTI2My0yLjUwNTYtNS43MDg5LTYuMDQ2Ny01LjgzLTEwLjE5eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA5MTU2MyIvPjxwYXRoIGQ9Im0xMS45NjkgNDMuNDI1Yy4xMjYxNy0zLjY5NjcgNC43NDM4LTQuNzA4MSA3LjU5NDktMy41MDM1IDUuMjg3OCAxLjY4NzggNy45MDQxIDcuMDYzOSA5Ljc0NzEgMTEuODczIDEuODIyNi0uMDIwNjggMy42NDg5LS4wMzgxIDUuNDc2NS0uMDcxNDggMS43NDcxLTQuODI5OSA0LjU2MzEtOS45NjY4IDkuNjg1Ni0xMS43OTggMi44MzY2LTEuMjMzNCA3LjQ3NzEtLjE4MjM0IDcuNTk4OSAzLjUwNDQtLjE1MDg3IDQuMTIyOC0yLjcwNzMgNy42NTQ5LTUuODA3NSAxMC4xNzEuNzY2MTQgMS4xMDI4IDEuMzA4IDIuMzA3NiAxLjI2MjcgMy42ODYyLTQuNjgwNS0uOTg4MzctOS4zMzA4LTIuMzAyNi0xNC4xNDctMi4zOTQ3LTUuNzMxNS0uMzA0OTgtMTEuMzE1IDEuMTU4Ni0xNi44NTQgMi4zOTQ1LS4wNjEzMS0xLjM4LjQ2NDE0LTIuNTg2NSAxLjI3MjUtMy42NzE2LTMuMTI2My0yLjUwNTYtNS43MDg5LTYuMDQ2Ny01LjgzLTEwLjE5eiIvPjxwYXRoIGQ9Im0xNS45ODkgNDUuMjAxYy0uMjE3MzktMS41Nzc3IDEuMjU2NS0yLjIxOTggMi41NzI5LTEuNjk1NyAzLjg2MDYuOTY0MDYgNS42MTMgNC45NzQzIDcuMDg4OCA4LjI2OTEtMS41NDIyLjI1NTM2LTMuMDg0Ni41MDEwNy00LjYyNjkuNzI3MDQtMS43OTItMi4zMzYxLTQuMDg3Ny00LjQ0MjYtNS4wMzQ5LTcuMzAwNHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wOTE1NjMiLz48L2c+PHBhdGggZD0ibTE1Ljk4OSA0NS4yMDFjLS4yMTczOS0xLjU3NzcgMS4yNTY1LTIuMjE5OCAyLjU3MjktMS42OTU3IDMuODYwNi45NjQwNiA1LjYxMyA0Ljk3NDMgNy4wODg4IDguMjY5MS0xLjU0MjIuMjU1MzYtMy4wODQ2LjUwMTA3LTQuNjI2OS43MjcwNC0xLjc5Mi0yLjMzNjEtNC4wODc3LTQuNDQyNi01LjAzNDktNy4zMDA0eiIvPjxwYXRoIGQ9Im0zOC4zODkgNTEuNzU3YzEuNTExOC0zLjQ4NjMgMy40NTQ1LTguMDE3MiA3LjgxMS04LjM5OTIgMS41NTc4LS40NzA3MSAyLjI0MjIgMS40MTc2IDEuNjE1IDIuNTQ3My0xLjE0MDggMi41MS0zLjEzNzUgNC40ODQxLTQuODQxNiA2LjYwODUtMS41MzMzLS4yNDAwMS0zLjA1ODUtLjUwMzc0LTQuNTg0NS0uNzU2NTR6IiBmaWxsPSIjZmZmIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDkxNTYzIi8+PHBhdGggZD0ibTM4LjM4OSA1MS43NTdjMS41MTE4LTMuNDg2MyAzLjQ1NDUtOC4wMTcyIDcuODExLTguMzk5MiAxLjU1NzgtLjQ3MDcxIDIuMjQyMiAxLjQxNzYgMS42MTUgMi41NDczLTEuMTQwOCAyLjUxLTMuMTM3NSA0LjQ4NDEtNC44NDE2IDYuNjA4NS0xLjUzMzMtLjI0MDAxLTMuMDU4NS0uNTAzNzQtNC41ODQ1LS43NTY1NHoiLz48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJtMjkuMTY2IDU4LjQzYzEuNjY0OS0xLjA5NTYgMy45NzA0LTEuMDgxMyA1LjY2NzEtLjA1MjE3IDEuNTE2NiAzLjQyMDItNi45ODg1IDMuNDgzMi01LjY2NzEuMDUyMTd6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDkxNTYzIi8+PHBhdGggZD0ibTI5LjE2NiA1OC40M2MxLjY2NDktMS4wOTU2IDMuOTcwNC0xLjA4MTMgNS42NjcxLS4wNTIxNyAxLjUxNjYgMy40MjAyLTYuOTg4NSAzLjQ4MzItNS42NjcxLjA1MjE3eiIvPjxwYXRoIGQ9Im0xNi42ODggNjIuNjJjLjMxNjItMi40MDEzIDIuNzgwNy0yLjE5NzUgNC41NTY3LTEuOTcyLTEuMTE3MyAxLjQ0NTgtMi44MDQ0IDEuOTI5OS00LjU1NjcgMS45NzJ6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDkxNTYzIi8+PHBhdGggZD0ibTE2LjY4OCA2Mi42MmMuMzE2Mi0yLjQwMTMgMi43ODA3LTIuMTk3NSA0LjU1NjctMS45NzItMS4xMTczIDEuNDQ1OC0yLjgwNDQgMS45Mjk5LTQuNTU2NyAxLjk3MnoiLz48cGF0aCBkPSJtNDIuOTEzIDYxLjU4MWMxLjI3MTItMS44MjQ1IDQuNDQ1My0xLjI5NzcgNC4yMzQ1IDEuMjMxLTEuNDMxMy0uMzUyMjgtMi44NDUtLjc1NDM0LTQuMjM0NS0xLjIzMXoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wOTE1NjMiLz48cGF0aCBkPSJtNDIuOTEzIDYxLjU4MWMxLjI3MTItMS44MjQ1IDQuNDQ1My0xLjI5NzcgNC4yMzQ1IDEuMjMxLTEuNDMxMy0uMzUyMjgtMi44NDUtLjc1NDM0LTQuMjM0NS0xLjIzMXoiLz48cGF0aCBkPSJtMTcuMzg0IDY2LjMwMmMzLjcxODQtMi4xNjQzIDguMjEyOC0xLjkxIDEyLjM2My0yLjIyMjEgNS43NzI2LS4wMDIgMTEuODY2LS4yMzUxOCAxNy4yMyAyLjI0MzQtLjQ1NzU1LjM5MTM3LTEuMzcyNiAxLjE3NDEtMS44MzAyIDEuNTY1NS03LjY2OTUtMS43Nzc4LTE1Ljc3NC0yLjA4NjYtMjMuNTA0LS41MjY1My0xLjU5NDIuMjMyNzgtNC4wMzMzIDEuNDQ0My00LjI1OTYtMS4wNjAzeiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA5MTU2MyIvPjxwYXRoIGQ9Im0xNy4zODQgNjYuMzAyYzMuNzE4NC0yLjE2NDMgOC4yMTI4LTEuOTEgMTIuMzYzLTIuMjIyMSA1Ljc3MjYtLjAwMiAxMS44NjYtLjIzNTE4IDE3LjIzIDIuMjQzNC0uNDU3NTUuMzkxMzctMS4zNzI2IDEuMTc0MS0xLjgzMDIgMS41NjU1LTcuNjY5NS0xLjc3NzgtMTUuNzc0LTIuMDg2Ni0yMy41MDQtLjUyNjUzLTEuNTk0Mi4yMzI3OC00LjAzMzMgMS40NDQzLTQuMjU5Ni0xLjA2MDN6Ii8+PC9nPjwvZz48ZyBmaWxsPSIjMzMzIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjk4NzgwMiI+PHBhdGggZD0ibTI0LjMxNzg0IDU3LjY1OTMxN2MtMy45NDI0NzgtLjU1NTIwOS02LjkyOTYyNi0xLjcwNDE3Ny04LjM2NzAzOC0zLjIxODI3LS44ODQ0MjMtLjkzMTYwNy0xLjA0MTc5MS0yLjAyMzc3LTEuMzk5NTc1LTkuNzEzMjc1bC0uMTkxMzY4LTQuMTEyOTAzLTEuNDg3MDU5LTEuMjgzODM0Yy00LjQ0MzgzODktMy44MzY1MzItNy42NDM2NTAyLTEwLjAyNTg4Mi03LjY2MTMxMTYtMTQuODE5MTY3LS4wMTE2MTA3LTMuMTUxMTQ5IDIuMTk2MjMzNC02LjI3NzgwMSA1LjUzNDk5MTYtNy44Mzg0MTMgMS42OTQxNDMtLjc5MTg4MSAyLjEyMDM1Ny0uODc3MDY3IDQuMzM4OTgzLS44NjcyMjMgMi43NDgyMzUuMDEyMTkgNC40NTEzMzYuNTAwNDU1IDcuNDAwOTg3IDIuMTIxNzg3Ljk0NzEyOC41MjA2MDYgMS43Nzg4NjcuOTQ2NTU3IDEuODQ4MzA5Ljk0NjU1Ny4wNjk0NCAwIC4xMjYyNTgtMi42MjM3MjkuMTI2MjU4LTUuODMwNTA4di01LjgzMDUwODdoNy41OTMyMiA3LjU5MzIyMXY1LjgzMDUwODdjMCAzLjIwNjc3OS4wNTY4MiA1LjgzMDUwOC4xMjYyNTkgNS44MzA1MDguMDY5NDQgMCAuOTAxMTc5LS40MjU5NTEgMS44NDgzMDktLjk0NjU1NyAzLjQzMDY2OC0xLjg4NTczMyA2LjEyOTEwMy0yLjQ5NjQ3NyA5LjAwMjIxNS0yLjAzNzQ5NSAyLjMwMTA3Ny4zNjc1OTkgMy43MTkyMDYgMS4wNzE2NzIgNS4zODQxMDMgMi42NzMxMDQgMi4zMTcwMjMgMi4yMjg2OTYgMy4wOTMxNTggNC41ODMyNCAyLjYxNzE0MiA3LjkzOTU4Mi0uNTkyNzQgNC4xNzkzNjgtMi43NzE0NTggOC4xMDU4NjQtNi42MTc0MzIgMTEuOTI1OTcybC0yLjI5Njc1NCAyLjI4MTMwNy0uMzczNTA1IDYuNTkyNzA4LS4zNzM1MDIgNi41OTI3MDUtLjc5NDAxLjY0MTk4M2MtMS4yNzU3NjkgMS4wMzE0OTgtMy4zNDU3MDggMS45ODAzMzMtNS42NzUzNjggMi42MDE1MTgtMS45MDI5MzcuNTA3NDA0LTMuMDUyNDU1LjU4OTAyMy05LjM1NTkzMi42NjQzMDEtMy45NTI1NDIuMDQ3Mi03LjkyMjA1Ny0uMDE3NzYtOC44MjExNDMtLjE0NDM4N3ptLTEuMDc3MTYyLTYuNDEyODY1YzEuOTI1Mjg2LS4zODc4MjcgMy43NTc3OTEtLjQ5MzMxNiA4LjY3Nzk2Ni0uNDk5NTU2IDUuNDI5MjMxLS4wMDY5IDYuNzA1NDkyLjA3NjY0IDkuODUxMjg3LjY0NDc1NGwzLjYxMzk5OC42NTI2Ny45NDg5MjgtLjk0ODkyNy45NDg5MjctLjk0ODkzMS0yLjEzNjYzNC0uNzA2MTY0Yy0zLjA0NTkxNy0xLjAwNjY4Ny01LjAxMzEzNC0xLjI4NzU5Ni0xMC4yNDM0NTUtMS40NjI3MDYtNy41MTEzOTgtLjI1MTQ4NS0xMy44MTE1ODEuMzkyMTk4LTE2Ljc1MDMxNCAxLjcxMTM2My0uODM2NjE1LjM3NTU0Ny0uOTkwMTI4LjU2MTE0OS0uODQ4MTY2IDEuMDI1NDY5LjQ0NjEzMSAxLjQ1OTE3MyAxLjA2MTIxMSAxLjUxNDI4OSA1LjkzNzQ2My41MzIwMjh6bTIzLjMzMDgzMS02LjI2MzYwNWMtLjk1OTc1OC0uODI1NTUxLTIuMzI4NDYxLS44MTE0NTQtMy4zMTE0ODUuMDM0MTFsLS43NTY2NTkuNjUwODUzIDIuMDI5Njc0LjU5MzE5YzEuMTE2MzIuMzI2MjU3IDIuMTUxNzA3LjYyNDM3NCAyLjMwMDg1OS42NjI0ODcuMTQ5MTUzLjAzODExLjMxMjQ1OS0uMjQ0MTc0LjM2MjkwNS0uNjI3Mjk4LjA2NDQ3LS40ODk3LS4xMjEyNC0uODc5NzY5LS42MjUyOTQtMS4zMTMzMzd6bS0yNi44OTU1ODQgMS4xMDU1MDhjMS4wMDIyMDQtLjUwNzMwOCAxLjgwMjA0MS0xLjE3MDAyIDEuODAyMDQxLTEuNDkzMDk4IDAtLjM0NTI0NS0yLjkzMjM2Mi0uMjc1MTQzLTMuNjExMDQ4LjA4NjMzLS43NzI0NDQuNDExNDA2LTEuMjUwOTMzIDEuMDUwNTQzLTEuMjYxNjgzIDEuNjg1MjgtLjAwNzUuNDQ1MTY2LjEzMTQzNy40ODY4MzkgMS4xMDQ1ODguMzMxMjI0LjYxMjI2Ny0uMDk3OSAxLjQ5NzAxMy0uMzcyMjg1IDEuOTY2MTAyLS42MDk3MzN6bTE0LjE1NDAxNy0xLjMwMzQyNWMuOTYyODA0LS40MDIyODYgMS40OTE4NTktMS4yNTg0NDYgMS4yNzk0ODItMi4wNzA1NzMtLjI2NDQ5Ny0xLjAxMTQzOS0zLjA5NjkxMS0xLjU5NDk4OS00LjgwMjEwOC0uOTg5MzU0LTEuMzY2MzczLjQ4NTI5NC0xLjcxNjcwNyAxLjAxNjY3Ni0xLjI4OTA2OCAxLjk1NTI0MS42MDgyMTUgMS4zMzQ4ODggMi45NjU0ODkgMS44NzYwNzkgNC44MTE2OTQgMS4xMDQ2ODZ6bS0xMy4zNjY5MzEtNC4xOTM2MTFjOS4xMDE3MzEtMi4wMDY1OSAxMy41NDg3NjEtMi4wMzU5MzUgMjIuMzMwOTgyLS4xNDczNDkgMi40MDE3ODIuNTE2NDk0IDQuNTEyMzk2LjkzOTA4MSA0LjY5MDI1Ni45MzkwODEuNDMyODUyIDAgLjEyMTc0Mi0xLjc2NDI1OC0uNTAyMTItMi44NDc0NThsLS40Njg1NjctLjgxMzU1OSAxLjgyODAyNy0xLjkzODQzNWMyLjM3MzQyNC0yLjUxNjc3NCAzLjU1Mzk2OS00LjkxNTUzIDMuNzE1OS03LjU1MDM1Ni4xMDIwOTktMS42NjEyODcuMDM2MTMtMi4wMjA3NDMtLjUyMzA1OS0yLjg1MDE5Mi0uOTE1NDA0LTEuMzU3ODE3LTIuNDE5MTU0LTIuMDI1NzY3LTQuNTcwNjQyLTIuMDMwMjMtNC40NTc1MS0uMDA5Mi05LjAwMDM1NyA0LjEwNTk4OS0xMS41OTI2NjcgMTAuNTAxNDY1bC0uNzQwNjEzIDEuODI3MTY4LTIuNTk0NjU3LjAwMzMtMi41OTQ2NTkuMDAzMy0uODg5NzYzLTIuMTU1MDY0Yy0xLjExODUyMS0yLjcwOTEzMi0zLjEzNzEzMi01LjgwMzg3OC00Ljc2MzU5My03LjMwMzA5Ny0xLjQ0MDE5Ni0xLjMyNzUyOC00LjA1MjcyOS0yLjY0ODAxOS01LjczOTM5OS0yLjkwMDk1MS0yLjY1MTk0OS0uMzk3Njg0LTUuNTA2MjI4IDEuMDc0ODA4LTYuMDU4NDE1IDMuMTI1NDcyLS42NDM5ODQgMi4zOTE1NzQgMS4wNzAyODYgNi42Nzg3MjQgMy44MDYwMDcgOS41MTgyOTZsMS42NDE5NDQgMS43MDQyNzYtLjU1NjI3NSAxLjI5MzA5M2MtLjYwMDc1OSAxLjM5NjUwMi0uNzIwMDA3IDIuNDEyODktLjI4MzA5NCAyLjQxMjg5LjE1MDI0OSAwIDEuODg5MjMyLS4zNTYyNzkgMy44NjQ0MDctLjc5MTczMnptMTIuODA0My0xMi43NjQ4MjhjMi43MDYwNC0xLjAyODgzNSAyLjc2ODg0MS00Ljc1MDkyLjA5ODE5LTUuODE5NTAzLTIuMDQ0NDI0LS44MTgwMTYtNC4wMDM4MzMuMDM4NTEtNC41OTM5NjIgMi4wMDgxOTEtLjc0MTQ2MSAyLjQ3NDc3NCAxLjk2ODUxOSA0Ljc3MjE3MiA0LjQ5NTc3MyAzLjgxMTMxMnptLTMuMTY3OTIxLTEwLjA2Mjk1NyAxLjk0OTczNS0xLjY1MzQxNSAxLjkxNjMxIDEuNjUzNDE1YzEuMDUzOTY4LjkwOTM3OCAyLjAyMTEzNiAxLjY1MzQxNSAyLjE0OTI1OCAxLjY1MzQxNS4yNjkxNjkgMCAxLjkwNTY0Ni0yLjAwMjk5NyAxLjkwNTY0Ni0yLjMzMjQ0OSAwLS4xMjEyNzYtLjc0OTM2MS0uODk5MTE2LTEuNjY1MjQ3LTEuNzI4NTM2bC0xLjY2NTI1MS0xLjUwODAzNCAxLjY3OTAzOC0xLjYyMjgyOSAxLjY3OTAzNy0xLjYyMjgyOS0uODg1MzgzLTEuMTUxOTgzNmMtLjQ4Njk1OS0uNjMzNTkwOC0xLjAxMTgwOC0xLjE0OTg2MjEtMS4xNjYzMy0xLjE0NzI2OTUtLjE1NDUyMi4wMDI1OS0xLjExNTMwNS43Mzc5NDE3LTIuMTM1MDc1IDEuNjM0MTA5bC0xLjg1NDEyMyAxLjYyOTM5NTEtMS44NDMxODgtMS42MzQxMDg5Yy0xLjAxMzc1My0uODk4NzU5OS0xLjk1ODk3My0xLjYzNDEwOS0yLjEwMDQ4OC0xLjYzNDEwOS0uMjc0Nzc3IDAtMS45NzUxOTMgMi4wMDY3Mjc5LTEuOTc1MTkzIDIuMzMxMDAzOSAwIC4xMDYzMjQuNzQzNDc5Ljg2NjEyNiAxLjY1MjE3NiAxLjY4ODQ1bDEuNjUyMTc2IDEuNDk1MTMzLTEuNzkzNTM4IDEuNjQ5NDg2LTEuNzkzNTM3IDEuNjQ5NDg2Ljk3NzQxMSAxLjE1MjU0M2MuNTM3NTc3LjYzMzg5OCAxLjA2NTAzMSAxLjE1MjU0MiAxLjE3MjEyMSAxLjE1MjU0MnMxLjA3MjA5LS43NDQwMzcgMi4xNDQ0NDUtMS42NTM0MTV6Ii8+PHBhdGggZD0ibTE5LjE1OTA1MiAzNC4wMDM0MTdjLTEuNzcyNzExLTIuMTk1NjE4LTMuMTA0ODE1LTQuNDI3NTczLTMuMTA0ODE1LTUuMjAyMTUgMC0uNjU4ODA1LjgwMTQzOS0xLjI0ODcyNSAxLjY5NjQ2Mi0xLjI0ODcyNSAyLjIyMDEwMSAwIDQuNzY2NzY5IDIuMjYyMDU0IDYuNjc0MTIgNS45MjgyMjNsMS4xMTk1NiAyLjE1MTkzNC0xLjcxNjQzNy4yOTg5MDVjLTIuNzY2MTEuNDgxNjk3LTIuNzAxNzExLjUwODI5My00LjY2ODg5LTEuOTI4MTg3eiIvPjxwYXRoIGQ9Im00MC4wMDM3NjIgMzUuOTA5MTc5LTEuNDA2NDA3LS4yNTY4OTguNTM5MzgtMS4yNTgzMjFjMS4zOTU3MDQtMy4yNTYwNDUgMy4zNzMyMy01LjY2NTI0MSA1LjMxNjcwNi02LjQ3NzI3NyAxLjIzMTAwNy0uNTE0MzQ3IDIuNzc0ODYxLS41NDk0NTUgMy4wNzgzNDctLjA3Ljc2MzEzNCAxLjIwNTYxMS0uMDU2MjQgMy4wMjIyMTItMi45NDk0NDkgNi41MzkwNjQtMS42Njg3OTQgMi4wMjg1MTMtMS43MjAwNzUgMi4wNDU1NzYtNC41Nzg1NzcgMS41MjM0MzV6Ii8+PC9nPjwvc3ZnPg==')} diff --git a/public/piece-css/fantasy.css b/public/piece-css/fantasy.css new file mode 100644 index 0000000000..51cdccb367 --- /dev/null +++ b/public/piece-css/fantasy.css @@ -0,0 +1,12 @@ +.is2d .pawn.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZDBiMDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNTg2LjUyNiIgeDI9IjExMjYuMDIyIiB4bGluazpocmVmPSIjYSIgeTE9IjMyOC4wNDMiIHkyPSI1MzQuMjAzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjI3NS4yNDQiIHgyPSI4NjIuNjUyIiB4bGluazpocmVmPSIjYSIgeTE9IjQ1OC42NTYiIHkyPSI1NjAuNzQ3Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMwMC4yNzMiIHgyPSI3NzQuMDQ2IiB4bGluazpocmVmPSIjYSIgeTE9IjYyMy43ODIiIHkyPSI3NjQuODk5Ii8+PGcgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxnIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggZD0iTTkyNi42NjcgMzczLjMzM2ExNjYuNjY3IDE1MCAwIDEgMS0zMzMuMzM0IDAgMTY2LjY2NyAxNTAgMCAxIDEgMzMzLjMzNCAweiIgZmlsbD0idXJsKCNiKSIgc3Ryb2tlLXdpZHRoPSIyMS43NjIiIHRyYW5zZm9ybT0ibWF0cml4KC43MzQ0NyAwIDAgLjczNiAtMTIwLjY2IDMwLjQzNikiLz48cGF0aCBkPSJNMzk3LjQxNyA0NjcuMDFjMS40NjkgMTcwLjE3NS04Ni43MzMgMjIxLjA5OC0xMjcuOTY3IDI1MC4yNDYtMzQuMTkyIDI0LjE3LTI1LjQ2MyA4Mi4zNDIgMTkuOTA2IDg1LjMxMSAyOC4xMTMgMS44NCAyNzYuNjEzIDIuMzYxIDMwNS42NTEtLjg0MyA1MS4zOC01LjY3IDUyLjg0Ni02Ni43IDE5LjY4OC04Ny4zMTEtNTIuNjA5LTMyLjcwMy0xMzYuMTkxLTY5LjUzOC0xMzguNDk4LTI0Ny4wOS0uNDQxLTMzLjMxMi03OS4wNDItMzAuMDA5LTc4Ljc4LS4zMTJ6IiBmaWxsPSJ1cmwoI2MpIiBzdHJva2Utd2lkdGg9IjE2Ii8+PHBhdGggZD0iTTM0MC4zNTMgNDMyLjczNWMtNzQuMTk1IDE5LjA2Ni0xMDAuMTEgNjYuMDE5LTEwMC4xMSA2Ni4wMTlINjQ5LjA5cy00My40MzItNTEuODM1LTExMC4wMjUtNjYuNjg0Yy04NS4yNC0xOS4wMDctMTI5LjE3My0xNy4yMDQtMTk4LjcxMi42NjV6IiBmaWxsPSJ1cmwoI2QpIiBzdHJva2Utd2lkdGg9IjE2Ii8+PC9nPjxwYXRoIGQ9Ik0zMzkuMTIxIDcxMy42NzVoMTg3LjkwMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxNiIvPjwvZz48L3N2Zz4=')} +.is2d .knight.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSIwIDAgOTAwIDkwMCIgd2lkdGg9IjcwMHB0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48bGluZWFyR3JhZGllbnQgaWQ9ImEiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iI2ZmZiIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI2QwYjA5MCIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJmIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjcwNS4yOTEiIHgyPSI3ODcuMTI2IiB4bGluazpocmVmPSIjYSIgeTE9IjM4Mi4yODgiIHkyPSI0NjkuNjI0Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJlIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjY3MS4wMzMiIHgyPSI3NDMuMTU0IiB4bGluazpocmVmPSIjYSIgeTE9IjMwMy4zMjciIHkyPSIzNTIuNDIiLz48bGluZWFyR3JhZGllbnQgaWQ9ImQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNTk4LjY3OSIgeDI9IjcwNS41MzIiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjEzLjc2MSIgeTI9IjIzNi4yODgiLz48bGluZWFyR3JhZGllbnQgaWQ9ImMiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNDk3Ljc5MiIgeDI9IjYyOS44NTMiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTU1LjkwNiIgeTI9IjE1Ny40ODkiLz48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjY1LjY0NiIgeDI9Ijc1My4yMDgiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjU5Ljk0IiB5Mj0iODU4LjMyOCIvPjxnIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjE2Ij48cGF0aCBkPSJNNTI4LjU5IDQwMS44MDhjLjIxNCA3Ni40OTMtODguMjI3IDE0Mi42NTMtMTc1LjQ1NiAxMDkuMzM0LTEzLjM2LTUuMTAyLTEzNC41NjggMTA0LjgwMy0xNTMuOTk0IDg5Ljc2Ni0xNS4zMjUtMTEuODYzIDE2Ljk3OS02MC43NjkgMTQuNjMtNTQuNTIyLTExLjE4MSAyOS43NC02MC41NDcgNjIuODQ0LTEwMC4xOSAyMC4xMTItMTUuNTAzLTE2LjcxLTEwLjcwOS02NC43NzYgMjIuNjg0LTEwMy45MzMgMzQuNzc3LTQwLjc4IDcwLjA4OS0xMDMuNTc3IDgzLjc1Ny0xMzkuNzk2IDI3LjQ5Mi03Mi44NSAxNi43MDUtNzQuNDQgNjkuMzkxLTE0MC41MDYgOS44OTgtMTIuNDEtMTYuMDg4LTYwLjU5NS02LjY0My05Mi4wNDcgMzcuMzA3IDYuNjUzIDUxLjY5IDQ0LjE2MiA2OC44NDUgNTkuOTAzIDEwLTIzLjE1MSAzLjI4MS04NS4zNiAyMS4wNi04Mi40NjIgMTcuNzc3IDIuODk5IDM4LjIyNyA1Ni43OTIgNjcuNTU0IDgwLjQ2MkM3OTEuNDkxIDI1Ni4yMTUgNzg4LjYyIDgxOC4zMjMgNjkwLjQ1IDgyMC4xNDRjLTEyMS4xNzIgMi4yNDgtMjY2LjI0IDEuNzQtMzg4LjEwNS0uMjAyLTI5LjUyOC0uNDctNDMuMTk3LTM4LjY3Mi0zNy41MDMtNjEuNSAyNy4xNTUtMTA4Ljg3OSAxNDEuODMzLTE4NS4wODcgMTk4LjAwOC0yMjIuODU0IDU3LjY5Ny0zOC43OSA2OC4yNjEtNzYuOTEgNjUuNzQtMTMzLjc4eiIgZmlsbD0idXJsKCNiKSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PHBhdGggZD0iTTM0NS4wMDYgMjk0LjA5OWMtMjkuMDczLTUuMzY2LTU0LjU2NCAzLjA3OC03NS42MTcgMjQuMDNtMjguNzQ5IDcuNjc0YzEwLjQ0MyAxMC42NCAyMy43MzQgMTEuMDg0IDI1LjkyMy02Ljk5N00xNTAuNzcxIDUxOC4yOWMtMTMuODU1LTQuNzg2LTIzLjg3OCAxNy41MzctMTUuMDM4IDE4LjQ0N20xODEuMTQzLTYyLjQzM2w5LjQ4OCAxMS43OW0yMDIuMzg5LTExNi44NThsLjI5LTI0LjkxOE0zMjUuODc5IDE2Mi42NWwtMTAuMTEzIDUuMjhtNjMuNTA0LTU5LjA1NmMzMC4xNTIgNDIuMTIgNDEuMDQgNTAuNjQgNS4xODcgNDQuNTk3IiBmaWxsPSJub25lIi8+PGcgZmlsbC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJNNDU0LjQ0NCAxMzEuMTI2Yzg2LjU3MiAyNS4zODQgNzEuOTcgNy4wNjIgOTAuMjI5IDM2Ljc5NiAxMC4yMyAxNi42NTggMjQuNDAzLTUuNjc4IDU4LjE0Ni0zLjU2NSAxOC4yMjMgMS4xNDEtNTAtMjcuMjIxLTU4Ljg5OS0zOC41NjMtMTIuMzUzLTE1Ljc0NS0xMDIuMTc4IDEuNjA4LTg5LjQ3NiA1LjMzMnoiIGZpbGw9InVybCgjYykiLz48cGF0aCBkPSJNNTc5LjU1MSAxOTkuNzIzYzI3LjE5MiAyMC42NzIgNDcuMTEtLjMyNSA0Ni4wMzYgMzUuNTQ1LS43MzggMjQuNjMgMzIuNTA2IDguMTc0IDQ4LjY1IDE4LjQ0OCAxNC44NzMgOS40NjUgMjkuNzktMjguNzE1IDIwLjMzLTI4LjcxNS0xNC4yMzIgMC0zOC40IDYuNjc3LTM0LjAyNy05LjM5NSA5LjU5OC0zNS4yNzgtODguNzk5LTIxLjgyMS04MC45ODktMTUuODgzeiIgZmlsbD0idXJsKCNkKSIvPjxwYXRoIGQ9Ik02NTkuNTMyIDI3Ny43MTZjNS4yOTIgMS44NTEgMzQuMTIgMjEuMzcgMzIuNzg1IDMwLjY1LTYuODg0IDQ3Ljg3NCAyOC40MTYgNDQuNzcgNDMuNjA4IDQ5LjgzMSAyMS4yODggNy4wOTItLjk5Mi0xOC4zMjMtMTEuNzM0LTMxLjM5LTEwLjc0MS0xMy4wNjggNy4zNC0xOC45MTggNi4wNzQtMjcuMjA3LTQuNDUzLTI5LjE1Ni03My40OTctMjIuODUxLTcwLjczMy0yMS44ODR6IiBmaWxsPSJ1cmwoI2UpIi8+PHBhdGggZD0iTTcxMC4zOSAzNzguNjQ3YzUuMDU4IDguODIgMTYuOTE4IDE4LjgxIDIwLjY3NyAzMi42NDUgMy43NiAxMy44MzYgNS4xNzUgMjYuMTcxIDEyLjY5NCA0MS4wMzJzMzcuNzczIDEyLjkyMyA1MC44MTggOC41NjJjMTcuNTc4LTUuODc3LTQyLjQ5Ni0yNC4xMjctMjguOTYtNTEuOTUyIDguNTY3LTE3LjYxLTU3Ljk1OS0zNS4wNDctNTUuMjMtMzAuMjg3eiIgZmlsbD0idXJsKCNmKSIvPjwvZz48cGF0aCBkPSJNNDM4LjE0NyA3MjkuNTAxbC0yNS43OCA2MS40OTIiIGZpbGw9Im5vbmUiLz48L2c+PC9zdmc+')} +.is2d .bishop.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZDBiMDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTM2LjA5NyIgeDI9Ijc4NC43ODEiIHhsaW5rOmhyZWY9IiNhIiB5MT0iNjI5LjYyIiB5Mj0iODY1LjEwMyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzMjEuMTU4IiB4Mj0iMzk1LjQzMiIgeGxpbms6aHJlZj0iI2EiIHkxPSI5MC4xNjEiIHkyPSIxMjguNDYzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjQ2MC40NTQiIHgyPSI1MzQuNzI4IiB4bGluazpocmVmPSIjYSIgeTE9Ijg2LjI2OSIgeTI9IjEyNC41NyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIxOTIuMyIgeDI9IjgyNS43NzkiIHhsaW5rOmhyZWY9IiNhIiB5MT0iNDQ2LjAxMyIgeTI9IjcxNy4zMzYiLz48bGluZWFyR3JhZGllbnQgaWQ9ImYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNzIxLjYyMiIgeDI9IjU0MS4yNjYiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjIwLjA0MiIgeTI9IjU5OS4zOCIvPjxnIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjE2Ij48ZyBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Im00MzUuOTA2IDIxNi44N2MxMC44Mi0xOC4yNTggMzkuMTU4LTUwLjQ5IDY4LjM3OC02Ny4yNTMgMzYuMjMzIDM0LjA1NiA4NS42NCAxMTMuMzcgMTEwLjA4IDE4OS41ODYgMTkuMDQ4IDU5LjQwMSAyMi45OTggODYuMDkyIDIzLjk5IDE0OS41NDlzLTMyLjM4MSAxMjUuOTY2LTUyLjg2NSAxNDkuMDkiIGZpbGw9InVybCgjZikiLz48cGF0aCBkPSJtNTY1LjQ3IDY4Ny4wNThjNi4wMzgtNTMuNDY5LTI5NC4xMjItNDkuNTIyLTI4MS44NDggMy4wMDYgOS45MTcgMjEuODg4IDIuMDk2IDUwLjAzNSAyLjA5NiA1MC4wMzVzNjkuMjc3LTkuODMgMTQ2LjM4My04LjYwNWM3Ny4xMDUgMS4yMjUgMTI5LjI5IDcuMzM5IDEyOS4yOSA3LjMzOXMtMS45Ni0zNi4wMTggNC4wNzgtNTEuNzc1eiIgZmlsbD0idXJsKCNlKSIvPjxwYXRoIGQ9Im0yNzkuNDM0IDY4Mi4yODRjLTIyLjc5LTguMDg1LTM5LjM4Mi00MC40MzYtNTMuNzYtNjEuMDctMjIuOTUtMzIuOTM1LTM2LjQ4LTEwMS40MjktMjMuMDQtMTc4LjIzNCAxMy40NDEtNzYuODA2IDg2LjQ4OC0yMjUuMjIgMTYxLjI4Ny0yOTEuMDUzIDkxLjE2MiA2NS44MzMgMTQ5Ljk1MiAxNjUuMzYyIDE5Ni4zNDkgMjk3Ljk4MyAyNC44MjkgNzAuOTcxIDM3LjE1MyAxNDguNjM5IDE0LjM2MiAyMzAuMDY0LTUzLjE3Ny0xMC45NzItMjMzLjI1LTIxLjM4LTI5NS4xOTggMi4zMXoiIGZpbGw9InVybCgjZSkiLz48cGF0aCBkPSJtMzUwLjQzIDEzOC43MTljMTIuNDc5LTIxLjE5Ni0xOS43MzItMzQuNzE5LTIuODgzLTQ5LjUyMiA5LjQ2Mi04LjMxMyAyNS42NDktOS4xNDUgMzQuNzM3IDEuNjM4IDEzLjEwNCAxNS41NDgtMjIuNzQ1IDI5LjAzNS01LjEwNyA0Ny42NzciIGZpbGw9InVybCgjYykiLz48L2c+PHBhdGggZD0ibTQzNi4zOCA3MTIuMzQ5Yy05LjUzMy0yLjU3NC0xOC4xMDIgMS45NTYtMjEuNTk4LS45NC00LjI4OS0zLjU1NC00LjAzOC0xOC4zNC0xLjE5OC0yMi4wOTQgMi40MjgtMy4yMSAzMy42MzEtMy42MSAzNi42OTMtLjY1MyAyLjg1NSAyLjc1MS0uMDgyIDIwLjY2NS0yLjcyNyAyNS4xOTciIGZpbGw9Im5vbmUiLz48ZyBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Im0zODEuMzEzIDM0OC41NjNjLTExLjQyOCAxLjgxMi0xNy4xMTYgMTQuMzQyLTE1LjY4NSAyNC45NjgtLjE5NyA5LjA4NCAzLjc4MiAyMC43ODgtMy42OSAyNy45MDctMTAuMTEgMy4zNjMtMjEuMDQ4LS44NS0zMS4zNDktMS43My04LjQ4LS43NzQtMTguNzA2LTMuOTgtMjYuMjQ1IDEuNDgtNS43NyA2LjgzNS45NyAxNy4xNjUgOC40MDYgMTkuNDY4IDE0Ljk1MyA2LjUwNSAzMi43MDYgMy4xMTIgNDcuMDk0IDEwLjgxMyA0Ljk2NyA0LjU4MiAzLjk1IDEyLjU2MiA1LjQ2OSAxOC42NTYgNC42NzcgMzYuMzAyIDQuNDMgNzMuNjE4IDE1LjQwNiAxMDguNzgxIDIuODczIDcuNzIgNy4zNiAxOC40MzIgMTYuOTY5IDE4LjUgNy40MTctMi41MzggNi40OC0xMi4zOSA2Ljg3NS0xOC43NS0uODk5LTM5Ljg3Mi0xMS45NjQtNzguNzM2LTEzLjcyLTExOC41MzEtLjE5Ny0zLjkxOC4xNTQtOC44MzQgNS4yMi05LjI1IDE3Ljk2Mi01LjE3IDM4Ljk0OS41OCA1NS4yOC0xMC4zNDQgNi43MDgtMy42MzQgMTIuMzA2LTE3LjE5NSAxLjQzOC0xOC45NjktMTkuMTU3LTIuODE5LTM4LjUyIDUuNDM4LTU3LjU2MiAxLjg0NC01Ljg5NS0yLjA4Ny01LjM3OS0xMC4yNDctNi4wNjMtMTUuMzc1LTEuMTE2LTEyLjA4IDIuNTU1LTI0LjkzOS0yLjAzMS0zNi40NjktMS4xNS0yLjAxLTMuNDYxLTMuMjktNS44MTMtM3oiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJtMzE3Ljg2NyA4MDMuMjg5YzU1LjgyNC0uNjI1IDgyLjY5OC0zMi4zODIgMTA3LjQwOC0zMi40MTkgMjQuNzA5LS4wMzggNDcuMjUzIDMxLjY0MyAxMDcuMzUyIDMxLjc0OSAzMi4yNDUuMDU3IDIwMS45OTggMy40NDUgMTkyLjU2NC0yMi4yODVzLTExNi42NCA4LjgyMy0xNTIuNTM2LTkuNDc3Yy0xOC43OS05LjU3OS0yNC4zMDItMTEuODQ5LTQ4LjYwOC0xNS41MzEtNjUuNTY5LTkuOTM0LTEzMi42MS05LjUzOC0xOTEuOS0uMzc2LTI2LjM5NCA0LjA4LTM3LjEzIDguNjIxLTUxLjk5NyAxOC42MjctMjUuMDA2IDE2LjgzMi0xMzAuMzQzLTE4LjE2NS0xMzguNjM0IDYuNDIyLTguMjkxIDI0LjU4NiAxMDguNTE5IDI0LjA1IDE3Ni4zNTEgMjMuMjl6IiBmaWxsPSJ1cmwoI2IpIi8+PHBhdGggZD0ibTYzNS42ODggOTEuMTU2Yy0yMC41ODYuMTk4LTM1Ljk0MyAxNy4wOTMtNDQuNDgxIDM0LjI2NS01LjY0OSAxMC45MDYtMTUuNjEgMTguODQ1LTIxLjE0NSAyOS43MzUtMS4xNjQgNi41NiA4LjE5IDguNjk3IDEzLjEyNSA3LjI4MSAxMi4wNDktMi41NDkgMjEuNTkyLTEyLjA3NCAyNS42NjEtMjMuNTIyIDQuODI4LTExLjc4NyAxNS43My0yMS4wNiAyOC42NTItMjEuOTE1IDEyLjY5LTIuMjMxIDI0LjQxMyA3Ljc0NCAyNi45NjkgMTkuODc1IDMuNjk0IDEyLjcxNiAyLjAyMiAyNy43MDYtOC4yMTkgMzYuOTM4LTE1Ljk4NSAxNi43NjctNDAuMjMyIDI0LjI3LTUzLjY4OCA0My43MTgtNzMuODQ2IDE0NS43MjktMTQ3LjU4IDI5MS41NTItMjIwLjQzNSA0MzcuNzgyLTI1Ljg2MyA1My4wMzgtNTMuMTkyIDEwNS40NzgtNzUuODQ2IDE1OS45NjgtMS43NjIgNi44LTcuMDUyIDE0LjMzOC00LjIxOSAyMS40MDcgNC40NyAzLjQ3MiAxMC4xLTEuODk4IDEzLjk3LTQuMjUgMTUuOTI2LTE0LjUzOSAyNC43NTYtMzUuMDc3IDM1LjMxMi01My41OTQgNDQuNDc1LTg2LjI5IDg2LjE1Ny0xNzQuMDAzIDEyOS40NDYtMjYwLjkgNDcuMDAyLTk0Ljg5NiA5NC4wMDgtMTg5LjgyMyAxNDIuMDIyLTI4NC4xOTQgMTMuNTg0LTIwLjEwNCAzOS4zNjUtMjYuODQgNTQuNTk1LTQ1LjQxIDkuNjk5LTEwLjY0NSAxNS45MDQtMjQuNzM4IDE0LjM0My0zOS4zNC0xLTI0LjI5OC0xNS4wNy01MC41OTQtNDAuMjE5LTU2LjM3NS01LjE2LTEuMzA4LTEwLjUtMS43MDctMTUuODQzLTEuNDY5eiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Im00ODkuNzI2IDEzNC44MjZjMTIuNDgtMjEuMTk2LTE5LjczMS0zNC43MTgtMi44ODItNDkuNTIyIDkuNDYxLTguMzEzIDI1LjY0OC05LjE0NCAzNC43MzcgMS42MzkgMTMuMTAzIDE1LjU0Ny0yMi43NDUgMjkuMDM1LTUuMTA3IDQ3LjY3NyIgZmlsbD0idXJsKCNkKSIvPjwvZz48L2c+PC9zdmc+')} +.is2d .rook.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZDBiMDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoMS4wNDUyMSAwIDAgMS4wMTQ1IC0zMy44MjkgLTExLjgzNSkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNy4zMzgiIHgyPSI2ODkuNzQ1IiB4bGluazpocmVmPSIjYSIgeTE9IjIwNy42NjUiIHkyPSIyNzQuMzMxIi8+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDEuMDQ1MjEgMCAwIDEuMDE0NSAtMzMuODI5IC0xMS44MzUpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxOC41MDIiIHgyPSI5MDYuMDk1IiB4bGluazpocmVmPSIjYSIgeTE9IjUyMS41MyIgeTI9IjY0My4xOTciLz48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoMS4wNDUyMSAwIDAgMS4wMTQ1IC0zMy44MjkgLTExLjgzNSkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTUzLjQxNCIgeDI9Ijk2Ni41ODYiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjI5LjA2OCIgeTI9IjQwMC43MzQiLz48bGluZWFyR3JhZGllbnQgaWQ9ImMiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoMS4wNDUyMSAwIDAgMS4wMTQ1IC0zMy44MjkgLTExLjgzNSkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTkzLjE1IiB4Mj0iODc4LjU5NSIgeGxpbms6aHJlZj0iI2EiIHkxPSI3MTUuNDA2IiB5Mj0iNzgyLjA3MiIvPjxnIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxNiI+PGcgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIj48cGF0aCBkPSJNMjAwLjMwMyAzMjMuMzU1czMuMjUtMTE3LjIzMyAxNy42NTUtMTU2LjIwNmMzMC4wOTgtNi40OTggODkuMzUtOS41NjMgMTI2LjE1Ni00LjE5MS40MTIgMjMuODQyLTUuNDMzIDczLjk5LTEuNTkxIDk2LjkxNSAzMy40NDUtMS41ODUgMTAxLjIgMi40NzcgMTQ0LjMxNi0yLjM3MS45Ni0yNy45Ny03LjI3LTY3LjU3Ljg5My05OC43NSAyNy4zNjgtMi4wNTYgODkuMjM4LTQuMjMxIDExOC4wNDcgOC4xNDgtMy44NCAzOS44OS41NjMgOTQuNzMuNTYzIDk0LjczbDc1LjUzMiAyLjYxNC0xMS4yNDcgNjBjLTk0LjMwNCAzNS4zNDgtNDExLjMzIDMwLjEtNDcwLjMyNC0uODl6IiBmaWxsPSJ1cmwoI2IpIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBkPSJNMjUwLjcxNyA3MDIuNDc2Yy0yMy45ODggMjMuOTUzLTc0LjExNCA0OC4wNTYtMTA5Ljg1NyA1NS42MjItNS4xODQgMTcuMTEyLTEwLjI4NCAzNi44OTguMjQgNTguMTc0IDEyNy4zOTcgMS4xNTUgNDYzLjc5LS4zMjQgNTg1LjUxNi0uNzQ3IDYuNTY4LTIzLjczMSAxMS41MzUtNDAuODk4IDQuOTY3LTU5LjU1LTM3LjQ3OS03LjQyLTgyLjc0My0xOC42MjQtMTE2LjI1LTUzLjQ5NiIgZmlsbD0idXJsKCNjKSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PHBhdGggZD0iTTE5OC4wNDEgNzY4LjYyM2MxNDkuNDU4LjA3MiAzMTEuNjY0LTUuNTEzIDQ3MS41MTIuNTgiIGZpbGw9Im5vbmUiLz48L2c+PHBhdGggZD0iTTI1Mi43NDMgMzEwLjg3Yy0zLjc2OCA0NC44NTEtNC44NTQgMzU3LjI4OC0zLjgxNyAzOTQuNTA0IDU1LjE3Ny00LjY2NiAzMTEuNjEyLTQuOTYgMzY4LjE2Mi0uNTY3LTMuMjAyLTcwLjAzLTIuMzE2LTM5Mi45NTItMi4zMTYtMzkyLjk1MiIgZmlsbD0idXJsKCNkKSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PGcgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIj48cGF0aCBkPSJNMjkxLjM4IDYzNC44MzNjMzkuODg5LTIuOTQgMTIzLjQ3LTYuMjUyIDIxNS40MzktMy4yOTVtLTIxNi43OTYtNjEuMzljNTAuNzUyLTQuODg2IDk5Ljg0OC02LjQ5NSAxNzEuMy01Ljc1Mk0yOTAuNTU4IDUwNC45NWM3Mi4yNjgtNC45OTcgNzQuMzA0LTQuNDY2IDE1Mi41MTYtNS41OTRtLTE1Mi41MTYtNTguMzQ0YzM2LjY4NS0zLjAzMyA1OC4yNTgtNC42MSAxMDIuMTYtMy41NW0tNTcuOTU4IDIwLjI0MmMuODggMjkuOTMyLS4xNzUtMS4zMzYuNzA0IDI0LjU1bTU0Ljk3NyAzOC45OTZjLjg4IDI5LjkzMi0uMTc1LTEuMzM2LjcwNCAyNC41NW0tNTYuMzg1IDM5LjcyOWMuODggMjkuOTMxLS4xNzUtMS4zMzcuNzA0IDI0LjU1bTExNi4wOS0yNi41NzljLjg3OSAyOS45MzEtLjE3Ni42OTIuNzAzIDI2LjU3OW0tNjEuODE2IDQyLjE1NGMuODggMjkuOTMyLS4xNzUuNjkzLjcwNCAyNi41OG0tOTkuMzI2LTI5NS42MDljMjcuODU3LTMuMDMzIDQyLjA1Mi00LjAwNyA2NS43NzYtMy41NSIgZmlsbD0ibm9uZSIvPjxwYXRoIGQ9Ik0xMzEuNzQ4IDE2MS4yNzhjNS4xNTYgMjguMjIzIDkuMDUyIDU0Ljk5OSAxNC4wNDggOTUuNTQgMzIuMDc3IDIyLjM2NiA1MC4wMzMgMzAuMTc3IDUzLjQ2OCA2Ny42NTcgOTYuMzUyLTE3LjM2MSAzODYuOTY4LTEzLjM2IDQ3NC4zNTMtLjM1MiA2LjA5LTMzLjc4MiAxNi4wNTMtMzkuNTU1IDYzLjEzLTY3LjkxIDUuOTQ3LTQ0LjM2MSAxMS4xNjktNjUuNzUgMTEuNTA1LTkyLjI3My0xNC4xMDctMy40My0xMTUuNDY4LTMzLjc4NC0xMjcuOTg5LTI5LjQyNC00LjQ1MyAyNi4zOTMgMS44NDQgNDkuMDY3LTQuMDE1IDczLjg4OC0zNy45NDMgMS45MDItNzEuNzQ1LjQ1OC0xMTEuMDEzLTkuNzYzLjE5NS0zMy4xNzguMTQ2LTUxLjM3MyAxLjc3Ni03Ny4wNTItMTYuNTgzLTUuOTA2LTExNS4yMDgtNi45NTYtMTMzLjgxNi0uODY1LTMuMjA3IDMxLjk3OC44NDcgNDkuMzk5LTEuNzIzIDc3LjgzLTMzLjY4MyA5LjUyOS02NS42MjcgNy4wNTctMTA1LjgzOCA5LjMxNi0zLjI0LTMzLjgwNSAyLjc0My00NS42NjcgMS45ODItNjkuMzk2LTE2LjU5LTQuNTM2LTEyMC4yMDQgMTcuOTg3LTEzNS44NjggMjIuODA0eiIgZmlsbD0idXJsKCNlKSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PHBhdGggZD0iTTE4OC43NCAyNjIuMjQ3YzE0OC42NTQtMTQuNjk1IDM2OC41MTMtMTUuNjEgNDk2LjA5NiAzLjU0NCIgZmlsbD0ibm9uZSIvPjwvZz48L2c+PC9zdmc+')} +.is2d .queen.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZDBiMDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImciIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNzg1LjE0MSIgeDI9Ijg0MC45MTEiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjk0Ljc1OSIgeTI9IjM2My4wODkiLz48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNjQ5Ljg2MyIgeDI9IjcxMS4xMTciIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTcxLjE4IiB5Mj0iMjI3Ljc0OSIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0MDYuMDEyIiB4Mj0iNDcwLjgzNSIgeGxpbms6aHJlZj0iI2EiIHkxPSIxMDMuNTMyIiB5Mj0iMTMyLjk5NCIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIxNjcuODcyIiB4Mj0iMjM0LjYyIiB4bGluazpocmVmPSIjYSIgeTE9IjE3NC45OTciIHkyPSIxNzQuOTk3Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJrIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIzLjQ1OCIgeDI9Ijg3LjM3MSIgeGxpbms6aHJlZj0iI2EiIHkxPSIzMzcuODU1IiB5Mj0iMzE1LjQ2MyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzMzkuNDcxIiB4Mj0iNTE0LjU0IiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1NzEuNTkzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMzOS40NzEiIHgyPSI0OTUuMDIyIiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1ODQuNzU4Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJmIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMzOS40NzEiIHgyPSI0ODcuMjE1IiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1ODQuNzU4Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJoIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMzOS40NzEiIHgyPSI0OTguOTI2IiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1ODQuNzU4Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJsIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMzOS40NzEiIHgyPSI1MTAuNjM3IiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1ODQuNzU4Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJiIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjE1My42MDQiIHgyPSI3NjEuMzY0IiB4bGluazpocmVmPSIjYSIgeTE9IjM4MC41NCIgeTI9IjY4Mi4yMDciLz48ZyBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxnIGZpbGw9InVybCgjYikiPjxwYXRoIGQ9Ik0yNDMuOTM1IDgyNC44OWwtNTAuMzc4LTE2Ni4yMTIgNDMzLjc2OCAxLjMxOC00OS41MTkgMTY5LjY4MXoiLz48ZyBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxNiI+PHBhdGggZD0iTTYxMi43MTMgNzE2LjI4Yy0xMjIuMi00My42NjktMjgzLjQwNi00My45MjMtNDAyLjM5NC0uMTA0IDEyLjU4NSAzMC41MyAxNS45MTkgOTIuOTk4IDE1LjkxOSA5Mi45OTggMTAwLjcxOS0yOC4xNzMgMjcxLjk1NC0yNy4zMTcgMzcxLjg4NSA0LjE4OCAwIDAgMi4zMS02Ni43MDcgMTQuNTktOTcuMDgyeiIvPjxwYXRoIGQ9Ik0xOTUuMTA0IDY5Ny45MTVjMTIxLjg1LTUyLjY4NiAzMTIuNTgtNTMuNTIgNDM1LjU3Ny40MUM2NDIuODA3IDU5My4yOSA2ODEuMDMgNDYzLjYzIDc1My4zNjQgMzcwLjYyN2MtNTQuODQ4IDIxLjQ2Mi0xMzQuNDggMTU4Ljg2My0xODAuNzc1IDE4NC43NTgtMzYuMzA0LTc2LjI2MyAzNS41NDQtMjc0LjIwNCA2My40NzgtMzE2LjEyOS00Ni44OTkgMjguMjE5LTE0Ni4xNDcgMjAzLjAxNi0xNzUuNDcgMjg0Ljc4NS00Mi4yNjUtOTQuNDQ1LTMyLjM3Mi0yNzEuMDgyLTMzLjM4My0zNDUuMTA4LTMxLjc5NiA2OS41NTMtNzMuNTE4IDIyOS4zNzMtNzcuNzg4IDM0Mi4zMTQtODEuMTkzLTYwLjg2NC0xMDkuODQ2LTIyNS4yNy0xMzEuNTAxLTI5MC40MDYtMTEuOTI0IDkzLjc5OCA4Ljg4NCAyNTcuMTczIDIyLjYyMyAzMjMuMjI3LTUyLjc5Mi0zNS41OTMtMTE0LjQ0LTExMy45Mi0xNjUuNjExLTE4MC4zMDUgNjUuMDYgMTU1LjU3NCA4OC42MDggMjAyLjY5MyAxMjAuMTY3IDMyNC4xNTN6bTIxMi42NTkgMS44NjdjLTE4Ljk5OC0uMDk4LTguNTg1IDE0LjYzNS0xMi4zMTggMjEuMTE1LTguNTM4IDQuOTQ5LTM2LjI0Ni0zLjgzMi0yNy4zMjcgMTQuMzQgNi4zMTkgMTIuODc0IDE1Ljc2NiA2LjgxMyAyNi4zNzcgMTAuOTYxIDUuMjc2IDcuMjY3LTMuNjQzIDI5LjM2NiAxNS4wMzcgMjguOTAzIDE1LjQyNy0uMzgzIDcuMDE4LTIyLjQzMSAxMC4zMTYtMjguMzcyIDkuMzI2LTYuMDk0IDIxLjU2MiAyLjE2NSAyNy43MzQtMTMuNDUyIDQuNjg2LTExLjg1Ni0xOC41MTItNy40NTgtMjcuNjczLTEyLjU2NC0zLjgzNy01LjczMSA3LjYyLTIwLjgyOC0xMi4xNDYtMjAuOTMxem0tMTYzLjE5IDEyNS40OTFjODguODIzIDEwLjU5OSAyMzIuNzIyIDE0LjM2IDMzMi45NTggNC40MDctNTYuNTY4LTI1LjI4MS0yNTkuODktMjUuMDY4LTMzMi45NTgtNC40MDd6Ii8+PC9nPjwvZz48ZyBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0iTTQ3NC42MiA4Mi41MThjLTguNTYuMTg4LTM0Ljk0MyA0LjYyLTUwLjc5OCAxMi41MjgtNC44MSAxMi4xMS0yLjMxMiA0Ny42MDYuMTMxIDc2LjY0IDE1LjE4NS0yNC4zNyA0OC43MzctNjYuMjU0IDUwLjY2Ny04OS4xNjh6IiBmaWxsPSJ1cmwoI2MpIiBzdHJva2Utd2lkdGg9IjE2Ii8+PHBhdGggZD0iTTQ0MC43NjMgNTMwLjYwNmE0NS45NjIgNDQuNzgzIDAgMSAxLTkxLjkyNCAwIDQ1Ljk2MiA0NC43ODMgMCAxIDEgOTEuOTI0IDB6IiBmaWxsPSJ1cmwoI2QpIiBzdHJva2Utd2lkdGg9IjE4LjczNyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoODcuMjM1IC0yNzEuNTA2KSBzY2FsZSguODUzOTMpIi8+PHBhdGggZD0iTTcxNC45MDIgMjA2LjAwNWMtNC43MTctNS42NTMtMS43MS0xNi00MC4wMDMtMzcuMDU1bC00OC44NTYgNjEuMDI5YzI3LjQxLTguNTUgNzAuNzY0LTIxLjQ2IDg4Ljg2LTIzLjk3NHoiIGZpbGw9InVybCgjZSkiIHN0cm9rZS13aWR0aD0iMTYiLz48cGF0aCBkPSJNNDQwLjc2MyA1MzAuNjA2YTQ1Ljk2MiA0NC43ODMgMCAxIDEtOTEuOTI0IDAgNDUuOTYyIDQ0Ljc4MyAwIDEgMSA5MS45MjQgMHoiIGZpbGw9InVybCgjZikiIHN0cm9rZS13aWR0aD0iMTguNzM3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyOTUuMjM1IC0yMTEuNTA2KSBzY2FsZSguODUzOTMpIi8+PHBhdGggZD0iTTg0NS41NiAzNTEuODkxYzIuNjc0LTEzLjgyNy0xMi4xNy0xOC4yNjgtMjYuNDExLTM3LjMyNC0xOS44MzYgOC4xMjItNDIuODE3IDE3LjgxLTU5LjAwNiA0MC41MjIgNDAuODY3LTguNDI4IDU5LjQ0NCA0LjA1OCA4NS40MTctMy4xOTh6IiBmaWxsPSJ1cmwoI2cpIiBzdHJva2Utd2lkdGg9IjE2Ii8+PHBhdGggZD0iTTQ0MC43NjMgNTMwLjYwNmE0NS45NjIgNDQuNzgzIDAgMSAxLTkxLjkyNCAwIDQ1Ljk2MiA0NC43ODMgMCAxIDEgOTEuOTI0IDB6IiBmaWxsPSJ1cmwoI2gpIiBzdHJva2Utd2lkdGg9IjE4LjczNyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDE3Ljg1IC04NS43NDkpIHNjYWxlKC44NTM5MykiLz48cGF0aCBkPSJNMjI2LjYyIDE1NC41MThjLTEwLjU2LTExLjgxMi0yMi44OTMtMTAuMTE3LTUwLjc0OC0xNC4yMDguOTcyIDMzLjcyNiAyMS4xMDQgNDMuMTM1IDMzLjA4MSA2OS4zNzUgMTUuMTg1LTI0LjM3IDEyLjczNy0yNS4yNTMgMTcuNjY3LTU1LjE2N3oiIGZpbGw9InVybCgjaSkiIHN0cm9rZS13aWR0aD0iMTYiLz48cGF0aCBkPSJNNDQwLjc2MyA1MzAuNjA2YTQ1Ljk2MiA0NC43ODMgMCAxIDEtOTEuOTI0IDAgNDUuOTYyIDQ0Ljc4MyAwIDEgMSA5MS45MjQgMHoiIGZpbGw9InVybCgjaikiIHN0cm9rZS13aWR0aD0iMTguNzM3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTIzLjc2NSAtMjE5LjUwNikgc2NhbGUoLjg1MzkzKSIvPjxwYXRoIGQ9Ik01MC4yNjMgMjg5Ljc4MmMtMTMuNDQ3IDIuOC0xNC41ODUgMzAuMzEyLTE4LjgwNSA0NC40MjYgMTUuMDU3IDE2LjU5NSAzMC4zNjcgMjYuMDUgNDMuNTIgNTEuNzIgMTQuMDY1LTI1LjAzMy04Ljc1OS03Ni45MzYtMjQuNzE1LTk2LjE0NnoiIGZpbGw9InVybCgjaykiIHN0cm9rZS13aWR0aD0iMTYiLz48cGF0aCBkPSJNNDQwLjc2MyA1MzAuNjA2YTQ1Ljk2MiA0NC43ODMgMCAxIDEtOTEuOTI0IDAgNDUuOTYyIDQ0Ljc4MyAwIDEgMSA5MS45MjQgMHoiIGZpbGw9InVybCgjbCkiIHN0cm9rZS13aWR0aD0iMTguNzM3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjQ5LjEwOCAtNjguOTIpIHNjYWxlKC44NTM5MykiLz48L2c+PC9nPjwvc3ZnPg==')} +.is2d .king.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZDBiMDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjk3LjU1NCIgeDI9IjM2OC41NjIiIHhsaW5rOmhyZWY9IiNhIiB5MT0iNDI3LjA1IiB5Mj0iNTIxLjIxNiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0OTUuMjk2IiB4Mj0iNTk1Ljk3MSIgeGxpbms6aHJlZj0iI2EiIHkxPSI0NDguNTQ3IiB5Mj0iNTI4LjU0NyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIyMjEuNTUxIiB4Mj0iNjMzLjQ5MSIgeGxpbms6aHJlZj0iI2EiIHkxPSI3NzQuOTM3IiB5Mj0iODU5LjM1MSIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzNDIuNTMiIHgyPSI2MDkuODQ4IiB4bGluazpocmVmPSIjYSIgeTE9IjE0NS42NzQiIHkyPSIyODAuNjc0Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJmIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjM3OS4xOTciIHgyPSI1NzkuODQ4IiB4bGluazpocmVmPSIjYSIgeTE9IjE2MC4yNTMiIHkyPSIyODYuOTE5Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJnIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjM2OC40NjkiIHgyPSI0OTQuNTUxIiB4bGluazpocmVmPSIjYSIgeTE9IjMxOS4yNzUiIHkyPSIzMTkuMjc1Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJoIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjEyOS45NjIiIHgyPSI4MTIuMzY5IiB4bGluazpocmVmPSIjYSIgeTE9IjQyOC42NTkiIHkyPSI4MzYuMzEzIi8+PGcgZmlsbC1ydWxlPSJldmVub2RkIj48ZyBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxNiI+PHBhdGggZD0ibTI4OC42MzUgNjEyLjQ4NWMyMy4xOTItMzMuNTEtNy4wNTEtMTI1LjgzOS4wMTgtMTY4LjA1MiAxMS40NzMtNjguNTA4IDEwMS40OS0xMTQuNDkgMTEzLjUwNS03NC43NzEgMTQuMjUzIDQ3LjExNi00My42MTIgNTEuNTYzLTU5LjcxMiA5MC44OTMtMTQuNzg4IDM2LjEyNi0xMS42MjQgOTYuNDgzIDE3LjE2NiAxMzIuODEiIGZpbGw9InVybCgjYikiLz48cGF0aCBkPSJtNTg2Ljg5IDYxNy4zMTZjLTIzLjE5Mi0zMy41MSA3LjA1Mi0xMjUuODM5LS4wMTgtMTY4LjA1Mi0xMS40NzMtNjguNTA4LTEwMS40OS0xMTQuNDktMTEzLjUwNS03NC43NzEtMTQuMjUzIDQ3LjExNiA0My42MTIgNTEuNTYzIDU5LjcxMiA5MC44OTMgMTQuNzg4IDM2LjEyNiAxMS42MjQgOTYuNDgzLTE3LjE2NiAxMzIuODEiIGZpbGw9InVybCgjYykiLz48ZyBmaWxsPSJ1cmwoI2UpIj48cGF0aCBkPSJtNDAxLjIxNyAyODguMTE1YzUuMjU3LTE1IDE4LjkwNC03MC45MjUgMTMuOTE2LTg3LjQtMjIuMzE0LTEuNzY2LTY4LjkzNSAxOC43MDItOTkuMTUyIDEyLjE0NS04LjUxLTE1LjM4Ni0xMy44MjQtNDguNDk0LTEuNi02Ni42NjggMjcuMzU2LTguMzI0IDg3LjczMSA2LjI2OSAxMDQuNDIgOC41MDUgNS45MTUtMTYuODUzLTE0LjQ5NS02Ny42MzgtMTAuNTQxLTg2LjAyNyAxOC43NS04Ljk2MyA2NS4zMTQtOC4wNzcgNzkuMTUzIDEuMDM0LS43MDUgMTkuMzE0LTI4Ljg5NSA2Ni4yMjUtMjkuNTc5IDgyLjI2NCAxOC43ODQtLjk2MyA3Ny4yOTQtMTYuODc1IDk3LjI2OC0xMi45ODkgOC42MTYgMTYuNzEgMTAuNDg2IDQ2LjU2NS0zLjQxNCA2NS42NDYtMjEuMjk1IDcuMDkzLTc3LjY3NS04LjkzLTEwMS4xNjctNC4yNy05LjkgMTkuOTY3IDUuNDkxIDcxLjUyMyA5LjI3OCA4Ni42MDUiIGZpbGw9InVybCgjZikiLz48cGF0aCBkPSJtNDA4LjQxIDM3MS44MzJjLTI0LjczNS0yMS40MTgtMzUuNjM0LTIxLjU5Ni0zMC44MzMtNzUuMjA2IDQuMS00NS43ODEgMTA2LjI1Ny00My40MiAxMDguNjM0LTEuOTkxIDIuOTgxIDUxLjk0Ny0xNC4yOSA1NS44MzctMjYuMyA4MC45OSIgZmlsbD0idXJsKCNnKSIvPjwvZz48L2c+PGcgZmlsbD0idXJsKCNoKSI+PHBhdGggZD0ibTI3MC45NjIgODMwLjMtNjMuOTc1LTE5Ni4yNDQgNDcxLjIzMy0yLjA2Ny03NC44OSAyMDQuMzI0eiIvPjxnIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjE2Ij48cGF0aCBkPSJtNjQzLjQ1NiA3MTcuMTFjLTkzLjY3Ni00OC4wMTUtMzA3LjEzOS01MC4yNy00MDcuNjA2IDEuODc1IDE0LjA3NCA0NC40NzMgMTkuNzA0IDkzLjk3MyAxOS43MDQgOTMuOTczIDkxLjY2Ni0yOC40NjQgMjc3Ljg3My0yOS42IDM2Ny44NzMgNC4xNDMgMCAwIDkuMjgtNjYuNjggMjAuMDMtOTkuOTkyeiIvPjxwYXRoIGQ9Im01NTMuNTMxIDU3NC4wMzFjLTI4Ljc2LTE1LjU0Ny04OS4xNy01My41NC0xMjEuOTY0LTU0Ljg5NS0yNS4wNjYtMS4wMzctNzYuODA2IDMyLjQ3OS0xMDMuNDEgNTMuMDgzLTExNS4yNzQtNTIuNDY3LTExMy44OTYtMTUyLjg5Mi0zMy4yNS0xNzEuMzEzIDEzLjEzNC0zIDUyLjIzLjQ2NCA3OC4wNjItLjcxOS04LjIyNi0yMi43MTUtMTcuMTkyLTM4LjgyMy04LjY4OC02OS4wNjItMTguMjI4LTExLjczMi00Mi40ODgtMjAuMTQ0LTcwLjEyNS0yMS43ODFhMzUxLjAyMyAzNTEuMDIzIDAgMCAwIC0yNS4wMzEtLjU5NGMtODEuMjAxIDEtMTY1LjQ1MSAzMC41MzYtMTc3LjQwNiAxMDUuMjUtMTcuNDQ5IDEwOS4wNDggNzkuMDkxIDE3My4zMTUgMTEzLjg0NCAyODguNjU2IDExMC4zMDctNjIuOTA4IDM2NC42NjQtNTguOTAyIDQ3MC4zNDMtNC41MzEgMjguMDQ4LTg5LjE2MiAxMzkuODUxLTE5My4zNiAxMTQuODQ0LTI4NC4yNS0yMy4xNTgtODQuMTctMTM1Ljc0Mi0xMDguODAxLTIxMC4wMzEtMTA0LjU5NC0zMC4xMDkgMS43MDYtNTkuMDEzIDExLjQ1My04MC43MTkgMjQuODQ0IDQuMjAyIDIzLjk3MS00LjMxNSA0My41Ny0xMS4zNzUgNjQuMjgxIDM0LjM0NS4wMTUgOTQuNjAyLTcuOTcyIDExOC4yNSA1LjQwNiA1Mi4yMyAyOS41NDcgNTYuMjEyIDEzNS44OTctNTMuMzQ0IDE3MC4yMnoiLz48cGF0aCBkPSJtMzI4LjQ4OCA1NzIuNTI4YzM3Ljk5NS0yNi42NzggNTUuOTk4LTc5LjY2MSA1NC40NzktMTIyLjQzNS0yLjE5MS02MS42NzYtMzUuMTgtNzIuNDI2LTE2LjM0LTEyNi40MTQgMTIuNzc0LTM2LjYwNyAxMTkuMTYzLTM4LjQ4OSAxMzEuMTc5IDEuMjMgMTQuMjUzIDQ3LjExNi0yMi4zNDMgNzYuNDUtMTYuNjM4IDEyNC4xNDUgNi42NTQgNTUuNjQgNy4wNjcgOTIuNTIzIDcyLjI5NCAxMjYuNTczIi8+PC9nPjwvZz48ZyBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0ibTI3NS42OTEgODMyLjY3OGM4Ny44NjUgMTAuNDg0IDIyOC4yMTIgMTIuMjA1IDMyNy4zNjcgMi4zNi02OC41OTctMjcuOTgtMjU2LjU1NS0yNy42NzctMzI3LjM2Ny0yLjM2eiIgZmlsbD0idXJsKCNkKSIgc3Ryb2tlLXdpZHRoPSIxNiIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im00NTMuNjIyIDczNy4wMzVhMTYuOTA4IDE2LjEwMyAwIDEgMSAtMzMuODE3IDAgMTYuOTA4IDE2LjEwMyAwIDEgMSAzMy44MTcgMHoiIHN0cm9rZS13aWR0aD0iMTYiLz48cGF0aCBkPSJtODE1IDkxNWExNy41IDE2LjY2NyAwIDEgMSAtMzUgMCAxNy41IDE2LjY2NyAwIDEgMSAzNSAweiIgc3Ryb2tlLXdpZHRoPSIxOC4wODciIHRyYW5zZm9ybT0ibWF0cml4KDEuMDYyNjIgLS4xOTI0NCAuMTI5MTMgLjcxMzA0IC02MjguMDcyIDI0OS41NDkpIi8+PHBhdGggZD0ibTgxNSA5MTVhMTcuNSAxNi42NjcgMCAxIDEgLTM1IDAgMTcuNSAxNi42NjcgMCAxIDEgMzUgMHoiIHN0cm9rZS13aWR0aD0iMTguMzIiIHRyYW5zZm9ybT0ibWF0cml4KDEuMDM4OTggLjE2ODYxIC0uMTE2MDggLjcxNTI4IC0xODguNjUyIC00MC40NDUpIi8+PC9nPjwvZz48L2c+PC9zdmc+')} +.is2d .pawn.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTA1MDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNTg2LjUyNiIgeDI9IjExMjYuMDIyIiB4bGluazpocmVmPSIjYSIgeTE9IjMyOC4wNDMiIHkyPSI1MzQuMjAzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjI3NS4yNDQiIHgyPSI4NjIuNjUyIiB4bGluazpocmVmPSIjYSIgeTE9IjQ1OC42NTYiIHkyPSI1NjAuNzQ3Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMwMC4yNzMiIHgyPSI3NzQuMDQ2IiB4bGluazpocmVmPSIjYSIgeTE9IjYyMy43ODIiIHkyPSI3NjQuODk5Ii8+PGcgc3Ryb2tlPSJncmF5IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxnIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggZD0iTTkyNi42NjcgMzczLjMzM2ExNjYuNjY3IDE1MCAwIDEgMS0zMzMuMzM0IDAgMTY2LjY2NyAxNTAgMCAxIDEgMzMzLjMzNCAweiIgZmlsbD0idXJsKCNiKSIgc3Ryb2tlLXdpZHRoPSIyMS43NjIiIHRyYW5zZm9ybT0ibWF0cml4KC43MzQ0NyAwIDAgLjczNiAtMTIwLjY2IDMwLjQzNikiLz48cGF0aCBkPSJNMzk3LjQxNyA0NjcuMDFjMS40NjkgMTcwLjE3NS04Ni43MzMgMjIxLjA5OC0xMjcuOTY3IDI1MC4yNDYtMzQuMTkyIDI0LjE3LTI1LjQ2MyA4Mi4zNDIgMTkuOTA2IDg1LjMxMSAyOC4xMTMgMS44NCAyNzYuNjEzIDIuMzYxIDMwNS42NTEtLjg0MyA1MS4zOC01LjY3IDUyLjg0Ni02Ni43IDE5LjY4OC04Ny4zMTEtNTIuNjA5LTMyLjcwMy0xMzYuMTkxLTY5LjUzOC0xMzguNDk4LTI0Ny4wOS0uNDQxLTMzLjMxMi03OS4wNDItMzAuMDA5LTc4Ljc4LS4zMTJ6IiBmaWxsPSJ1cmwoI2MpIiBzdHJva2Utd2lkdGg9IjE2Ii8+PHBhdGggZD0iTTM0MC4zNTMgNDMyLjczNWMtNzQuMTk1IDE5LjA2Ni0xMDAuMTEgNjYuMDE5LTEwMC4xMSA2Ni4wMTlINjQ5LjA5cy00My40MzItNTEuODM1LTExMC4wMjUtNjYuNjg0Yy04NS4yNC0xOS4wMDctMTI5LjE3My0xNy4yMDQtMTk4LjcxMi42NjV6IiBmaWxsPSJ1cmwoI2QpIiBzdHJva2Utd2lkdGg9IjE2Ii8+PC9nPjxwYXRoIGQ9Ik0zMzkuMTIxIDcxMy42NzVoMTg3LjkwMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxNiIvPjwvZz48L3N2Zz4=')} +.is2d .knight.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSIwIDAgOTAwIDkwMCIgd2lkdGg9IjcwMHB0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48bGluZWFyR3JhZGllbnQgaWQ9ImEiPjxzdG9wIG9mZnNldD0iMCIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzUwNTA3MCIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJmIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjcwNS4yOTEiIHgyPSI3ODcuMTI2IiB4bGluazpocmVmPSIjYSIgeTE9IjM4Mi4yODgiIHkyPSI0NjkuNjI0Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJlIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjY3MS4wMzMiIHgyPSI3NDMuMTU0IiB4bGluazpocmVmPSIjYSIgeTE9IjMwMy4zMjciIHkyPSIzNTIuNDIiLz48bGluZWFyR3JhZGllbnQgaWQ9ImQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNTk4LjY3OSIgeDI9IjcwNS41MzIiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjEzLjc2MSIgeTI9IjIzNi4yODgiLz48bGluZWFyR3JhZGllbnQgaWQ9ImMiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNDk3Ljc5MiIgeDI9IjYyOS44NTMiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTU1LjkwNiIgeTI9IjE1Ny40ODkiLz48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjY1LjY0NiIgeDI9Ijc1My4yMDgiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjU5Ljk0IiB5Mj0iODU4LjMyOCIvPjxnIHN0cm9rZT0iZ3JheSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjE2Ij48cGF0aCBkPSJNNTI4LjU5IDQwMS44MDhjLjIxNCA3Ni40OTMtODguMjI3IDE0Mi42NTMtMTc1LjQ1NiAxMDkuMzM0LTEzLjM2LTUuMTAyLTEzNC41NjggMTA0LjgwMy0xNTMuOTk0IDg5Ljc2Ni0xNS4zMjUtMTEuODYzIDE2Ljk3OS02MC43NjkgMTQuNjMtNTQuNTIyLTExLjE4MSAyOS43NC02MC41NDcgNjIuODQ0LTEwMC4xOSAyMC4xMTItMTUuNTAzLTE2LjcxLTEwLjcwOS02NC43NzYgMjIuNjg0LTEwMy45MzMgMzQuNzc3LTQwLjc4IDcwLjA4OS0xMDMuNTc3IDgzLjc1Ny0xMzkuNzk2IDI3LjQ5Mi03Mi44NSAxNi43MDUtNzQuNDQgNjkuMzkxLTE0MC41MDYgOS44OTgtMTIuNDEtMTYuMDg4LTYwLjU5NS02LjY0My05Mi4wNDcgMzcuMzA3IDYuNjUzIDUxLjY5IDQ0LjE2MiA2OC44NDUgNTkuOTAzIDEwLTIzLjE1MSAzLjI4MS04NS4zNiAyMS4wNi04Mi40NjIgMTcuNzc3IDIuODk5IDM4LjIyNyA1Ni43OTIgNjcuNTU0IDgwLjQ2MkM3OTEuNDkxIDI1Ni4yMTUgNzg4LjYyIDgxOC4zMjMgNjkwLjQ1IDgyMC4xNDRjLTEyMS4xNzIgMi4yNDgtMjY2LjI0IDEuNzQtMzg4LjEwNS0uMjAyLTI5LjUyOC0uNDctNDMuMTk3LTM4LjY3Mi0zNy41MDMtNjEuNSAyNy4xNTUtMTA4Ljg3OSAxNDEuODMzLTE4NS4wODcgMTk4LjAwOC0yMjIuODU0IDU3LjY5Ny0zOC43OSA2OC4yNjEtNzYuOTEgNjUuNzQtMTMzLjc4eiIgZmlsbD0idXJsKCNiKSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PHBhdGggZD0iTTM0NS4wMDYgMjk0LjA5OWMtMjkuMDczLTUuMzY2LTU0LjU2NCAzLjA3OC03NS42MTcgMjQuMDNtMjguNzQ5IDcuNjc0YzEwLjQ0MyAxMC42NCAyMy43MzQgMTEuMDg0IDI1LjkyMy02Ljk5N00xNTAuNzcxIDUxOC4yOWMtMTMuODU1LTQuNzg2LTIzLjg3OCAxNy41MzctMTUuMDM4IDE4LjQ0N20xODEuMTQzLTYyLjQzM2w5LjQ4OCAxMS43OW0yMDIuMzg5LTExNi44NThsLjI5LTI0LjkxOE0zMjUuODc5IDE2Mi42NWwtMTAuMTEzIDUuMjhtNjMuNTA0LTU5LjA1NmMzMC4xNTIgNDIuMTIgNDEuMDQgNTAuNjQgNS4xODcgNDQuNTk3IiBmaWxsPSJub25lIi8+PGcgZmlsbC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJNNDU0LjQ0NCAxMzEuMTI2Yzg2LjU3MiAyNS4zODQgNzEuOTcgNy4wNjIgOTAuMjI5IDM2Ljc5NiAxMC4yMyAxNi42NTggMjQuNDAzLTUuNjc4IDU4LjE0Ni0zLjU2NSAxOC4yMjMgMS4xNDEtNTAtMjcuMjIxLTU4Ljg5OS0zOC41NjMtMTIuMzUzLTE1Ljc0NS0xMDIuMTc4IDEuNjA4LTg5LjQ3NiA1LjMzMnoiIGZpbGw9InVybCgjYykiLz48cGF0aCBkPSJNNTc5LjU1MSAxOTkuNzIzYzI3LjE5MiAyMC42NzIgNDcuMTEtLjMyNSA0Ni4wMzYgMzUuNTQ1LS43MzggMjQuNjMgMzIuNTA2IDguMTc0IDQ4LjY1IDE4LjQ0OCAxNC44NzMgOS40NjUgMjkuNzktMjguNzE1IDIwLjMzLTI4LjcxNS0xNC4yMzIgMC0zOC40IDYuNjc3LTM0LjAyNy05LjM5NSA5LjU5OC0zNS4yNzgtODguNzk5LTIxLjgyMS04MC45ODktMTUuODgzeiIgZmlsbD0idXJsKCNkKSIvPjxwYXRoIGQ9Ik02NTkuNTMyIDI3Ny43MTZjNS4yOTIgMS44NTEgMzQuMTIgMjEuMzcgMzIuNzg1IDMwLjY1LTYuODg0IDQ3Ljg3NCAyOC40MTYgNDQuNzcgNDMuNjA4IDQ5LjgzMSAyMS4yODggNy4wOTItLjk5Mi0xOC4zMjMtMTEuNzM0LTMxLjM5LTEwLjc0MS0xMy4wNjggNy4zNC0xOC45MTggNi4wNzQtMjcuMjA3LTQuNDUzLTI5LjE1Ni03My40OTctMjIuODUxLTcwLjczMy0yMS44ODR6IiBmaWxsPSJ1cmwoI2UpIi8+PHBhdGggZD0iTTcxMC4zOSAzNzguNjQ3YzUuMDU4IDguODIgMTYuOTE4IDE4LjgxIDIwLjY3NyAzMi42NDUgMy43NiAxMy44MzYgNS4xNzUgMjYuMTcxIDEyLjY5NCA0MS4wMzJzMzcuNzczIDEyLjkyMyA1MC44MTggOC41NjJjMTcuNTc4LTUuODc3LTQyLjQ5Ni0yNC4xMjctMjguOTYtNTEuOTUyIDguNTY3LTE3LjYxLTU3Ljk1OS0zNS4wNDctNTUuMjMtMzAuMjg3eiIgZmlsbD0idXJsKCNmKSIvPjwvZz48cGF0aCBkPSJNNDM4LjE0NyA3MjkuNTAxbC0yNS43OCA2MS40OTIiIGZpbGw9Im5vbmUiLz48L2c+PC9zdmc+')} +.is2d .bishop.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTA1MDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTM2LjA5NyIgeDI9Ijc4NC43ODEiIHhsaW5rOmhyZWY9IiNhIiB5MT0iNjI5LjYyIiB5Mj0iODY1LjEwMyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzMjEuMTU4IiB4Mj0iMzk1LjQzMiIgeGxpbms6aHJlZj0iI2EiIHkxPSI5MC4xNjEiIHkyPSIxMjguNDYzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjQ2MC40NTQiIHgyPSI1MzQuNzI4IiB4bGluazpocmVmPSIjYSIgeTE9Ijg2LjI2OSIgeTI9IjEyNC41NyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIxOTIuMyIgeDI9IjgyNS43NzkiIHhsaW5rOmhyZWY9IiNhIiB5MT0iNDQ2LjAxMyIgeTI9IjcxNy4zMzYiLz48bGluZWFyR3JhZGllbnQgaWQ9ImYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNzIxLjYyMiIgeDI9IjU0MS4yNjYiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjIwLjA0MiIgeTI9IjU5OS4zOCIvPjxnIHN0cm9rZT0iIzgwODA4MCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjE2Ij48ZyBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Im00MzUuOTA2IDIxNi44N2MxMC44Mi0xOC4yNTggMzkuMTU4LTUwLjQ5IDY4LjM3OC02Ny4yNTMgMzYuMjMzIDM0LjA1NiA4NS42NCAxMTMuMzcgMTEwLjA4IDE4OS41ODYgMTkuMDQ4IDU5LjQwMSAyMi45OTggODYuMDkyIDIzLjk5IDE0OS41NDlzLTMyLjM4MSAxMjUuOTY2LTUyLjg2NSAxNDkuMDkiIGZpbGw9InVybCgjZikiLz48cGF0aCBkPSJtNTY1LjQ3IDY4Ny4wNThjNi4wMzgtNTMuNDY5LTI5NC4xMjItNDkuNTIyLTI4MS44NDggMy4wMDYgOS45MTcgMjEuODg4IDIuMDk2IDUwLjAzNSAyLjA5NiA1MC4wMzVzNjkuMjc3LTkuODMgMTQ2LjM4My04LjYwNWM3Ny4xMDUgMS4yMjUgMTI5LjI5IDcuMzM5IDEyOS4yOSA3LjMzOXMtMS45Ni0zNi4wMTggNC4wNzgtNTEuNzc1eiIgZmlsbD0idXJsKCNlKSIvPjxwYXRoIGQ9Im0yNzkuNDM0IDY4Mi4yODRjLTIyLjc5LTguMDg1LTM5LjM4Mi00MC40MzYtNTMuNzYtNjEuMDctMjIuOTUtMzIuOTM1LTM2LjQ4LTEwMS40MjktMjMuMDQtMTc4LjIzNCAxMy40NDEtNzYuODA2IDg2LjQ4OC0yMjUuMjIgMTYxLjI4Ny0yOTEuMDUzIDkxLjE2MiA2NS44MzMgMTQ5Ljk1MiAxNjUuMzYyIDE5Ni4zNDkgMjk3Ljk4MyAyNC44MjkgNzAuOTcxIDM3LjE1MyAxNDguNjM5IDE0LjM2MiAyMzAuMDY0LTUzLjE3Ny0xMC45NzItMjMzLjI1LTIxLjM4LTI5NS4xOTggMi4zMXoiIGZpbGw9InVybCgjZSkiLz48cGF0aCBkPSJtMzUwLjQzIDEzOC43MTljMTIuNDc5LTIxLjE5Ni0xOS43MzItMzQuNzE5LTIuODgzLTQ5LjUyMiA5LjQ2Mi04LjMxMyAyNS42NDktOS4xNDUgMzQuNzM3IDEuNjM4IDEzLjEwNCAxNS41NDgtMjIuNzQ1IDI5LjAzNS01LjEwNyA0Ny42NzciIGZpbGw9InVybCgjYykiLz48L2c+PHBhdGggZD0ibTQzNi4zOCA3MTIuMzQ5Yy05LjUzMy0yLjU3NC0xOC4xMDIgMS45NTYtMjEuNTk4LS45NC00LjI4OS0zLjU1NC00LjAzOC0xOC4zNC0xLjE5OC0yMi4wOTQgMi40MjgtMy4yMSAzMy42MzEtMy42MSAzNi42OTMtLjY1MyAyLjg1NSAyLjc1MS0uMDgyIDIwLjY2NS0yLjcyNyAyNS4xOTciIGZpbGw9Im5vbmUiLz48ZyBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Im0zODEuMzEzIDM0OC41NjNjLTExLjQyOCAxLjgxMi0xNy4xMTYgMTQuMzQyLTE1LjY4NSAyNC45NjgtLjE5NyA5LjA4NCAzLjc4MiAyMC43ODgtMy42OSAyNy45MDctMTAuMTEgMy4zNjMtMjEuMDQ4LS44NS0zMS4zNDktMS43My04LjQ4LS43NzQtMTguNzA2LTMuOTgtMjYuMjQ1IDEuNDgtNS43NyA2LjgzNS45NyAxNy4xNjUgOC40MDYgMTkuNDY4IDE0Ljk1MyA2LjUwNSAzMi43MDYgMy4xMTIgNDcuMDk0IDEwLjgxMyA0Ljk2NyA0LjU4MiAzLjk1IDEyLjU2MiA1LjQ2OSAxOC42NTYgNC42NzcgMzYuMzAyIDQuNDMgNzMuNjE4IDE1LjQwNiAxMDguNzgxIDIuODczIDcuNzIgNy4zNiAxOC40MzIgMTYuOTY5IDE4LjUgNy40MTctMi41MzggNi40OC0xMi4zOSA2Ljg3NS0xOC43NS0uODk5LTM5Ljg3Mi0xMS45NjQtNzguNzM2LTEzLjcyLTExOC41MzEtLjE5Ny0zLjkxOC4xNTQtOC44MzQgNS4yMi05LjI1IDE3Ljk2Mi01LjE3IDM4Ljk0OS41OCA1NS4yOC0xMC4zNDQgNi43MDgtMy42MzQgMTIuMzA2LTE3LjE5NSAxLjQzOC0xOC45NjktMTkuMTU3LTIuODE5LTM4LjUyIDUuNDM4LTU3LjU2MiAxLjg0NC01Ljg5NS0yLjA4Ny01LjM3OS0xMC4yNDctNi4wNjMtMTUuMzc1LTEuMTE2LTEyLjA4IDIuNTU1LTI0LjkzOS0yLjAzMS0zNi40NjktMS4xNS0yLjAxLTMuNDYxLTMuMjktNS44MTMtM3oiLz48cGF0aCBkPSJtMzE3Ljg2NyA4MDMuMjg5YzU1LjgyNC0uNjI1IDgyLjY5OC0zMi4zODIgMTA3LjQwOC0zMi40MTkgMjQuNzA5LS4wMzggNDcuMjUzIDMxLjY0MyAxMDcuMzUyIDMxLjc0OSAzMi4yNDUuMDU3IDIwMS45OTggMy40NDUgMTkyLjU2NC0yMi4yODVzLTExNi42NCA4LjgyMy0xNTIuNTM2LTkuNDc3Yy0xOC43OS05LjU3OS0yNC4zMDItMTEuODQ5LTQ4LjYwOC0xNS41MzEtNjUuNTY5LTkuOTM0LTEzMi42MS05LjUzOC0xOTEuOS0uMzc2LTI2LjM5NCA0LjA4LTM3LjEzIDguNjIxLTUxLjk5NyAxOC42MjctMjUuMDA2IDE2LjgzMi0xMzAuMzQzLTE4LjE2NS0xMzguNjM0IDYuNDIyLTguMjkxIDI0LjU4NiAxMDguNTE5IDI0LjA1IDE3Ni4zNTEgMjMuMjl6IiBmaWxsPSJ1cmwoI2IpIi8+PHBhdGggZD0ibTYzNS42ODggOTEuMTU2Yy0yMC41ODYuMTk4LTM1Ljk0MyAxNy4wOTMtNDQuNDgxIDM0LjI2NS01LjY0OSAxMC45MDYtMTUuNjEgMTguODQ1LTIxLjE0NSAyOS43MzUtMS4xNjQgNi41NiA4LjE5IDguNjk3IDEzLjEyNSA3LjI4MSAxMi4wNDktMi41NDkgMjEuNTkyLTEyLjA3NCAyNS42NjEtMjMuNTIyIDQuODI4LTExLjc4NyAxNS43My0yMS4wNiAyOC42NTItMjEuOTE1IDEyLjY5LTIuMjMxIDI0LjQxMyA3Ljc0NCAyNi45NjkgMTkuODc1IDMuNjk0IDEyLjcxNiAyLjAyMiAyNy43MDYtOC4yMTkgMzYuOTM4LTE1Ljk4NSAxNi43NjctNDAuMjMyIDI0LjI3LTUzLjY4OCA0My43MTgtNzMuODQ2IDE0NS43MjktMTQ3LjU4IDI5MS41NTItMjIwLjQzNSA0MzcuNzgyLTI1Ljg2MyA1My4wMzgtNTMuMTkyIDEwNS40NzgtNzUuODQ2IDE1OS45NjgtMS43NjIgNi44LTcuMDUyIDE0LjMzOC00LjIxOSAyMS40MDcgNC40NyAzLjQ3MiAxMC4xLTEuODk4IDEzLjk3LTQuMjUgMTUuOTI2LTE0LjUzOSAyNC43NTYtMzUuMDc3IDM1LjMxMi01My41OTQgNDQuNDc1LTg2LjI5IDg2LjE1Ny0xNzQuMDAzIDEyOS40NDYtMjYwLjkgNDcuMDAyLTk0Ljg5NiA5NC4wMDgtMTg5LjgyMyAxNDIuMDIyLTI4NC4xOTQgMTMuNTg0LTIwLjEwNCAzOS4zNjUtMjYuODQgNTQuNTk1LTQ1LjQxIDkuNjk5LTEwLjY0NSAxNS45MDQtMjQuNzM4IDE0LjM0My0zOS4zNC0xLTI0LjI5OC0xNS4wNy01MC41OTQtNDAuMjE5LTU2LjM3NS01LjE2LTEuMzA4LTEwLjUtMS43MDctMTUuODQzLTEuNDY5eiIvPjxwYXRoIGQ9Im00ODkuNzI2IDEzNC44MjZjMTIuNDgtMjEuMTk2LTE5LjczMS0zNC43MTgtMi44ODItNDkuNTIyIDkuNDYxLTguMzEzIDI1LjY0OC05LjE0NCAzNC43MzcgMS42MzkgMTMuMTAzIDE1LjU0Ny0yMi43NDUgMjkuMDM1LTUuMTA3IDQ3LjY3NyIgZmlsbD0idXJsKCNkKSIvPjwvZz48L2c+PC9zdmc+')} +.is2d .rook.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTA1MDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoMS4wNDUyMSAwIDAgMS4wMTQ1IC0zMy44MjkgLTExLjgzNSkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNy4zMzgiIHgyPSI2ODkuNzQ1IiB4bGluazpocmVmPSIjYSIgeTE9IjIwNy42NjUiIHkyPSIyNzQuMzMxIi8+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDEuMDQ1MjEgMCAwIDEuMDE0NSAtMzMuODI5IC0xMS44MzUpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxOC41MDIiIHgyPSI5MDYuMDk1IiB4bGluazpocmVmPSIjYSIgeTE9IjUyMS41MyIgeTI9IjY0My4xOTciLz48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoMS4wNDUyMSAwIDAgMS4wMTQ1IC0zMy44MjkgLTExLjgzNSkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTUzLjQxNCIgeDI9Ijk2Ni41ODYiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjI5LjA2OCIgeTI9IjQwMC43MzQiLz48bGluZWFyR3JhZGllbnQgaWQ9ImMiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoMS4wNDUyMSAwIDAgMS4wMTQ1IC0zMy44MjkgLTExLjgzNSkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTkzLjE1IiB4Mj0iODc4LjU5NSIgeGxpbms6aHJlZj0iI2EiIHkxPSI3MTUuNDA2IiB5Mj0iNzgyLjA3MiIvPjxnIHN0cm9rZT0iZ3JheSIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxNiI+PGcgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIj48cGF0aCBkPSJNMjAwLjMwMyAzMjMuMzU1czMuMjUtMTE3LjIzMyAxNy42NTUtMTU2LjIwNmMzMC4wOTgtNi40OTggODkuMzUtOS41NjMgMTI2LjE1Ni00LjE5MS40MTIgMjMuODQyLTUuNDMzIDczLjk5LTEuNTkxIDk2LjkxNSAzMy40NDUtMS41ODUgMTAxLjIgMi40NzcgMTQ0LjMxNi0yLjM3MS45Ni0yNy45Ny03LjI3LTY3LjU3Ljg5My05OC43NSAyNy4zNjgtMi4wNTYgODkuMjM4LTQuMjMxIDExOC4wNDcgOC4xNDgtMy44NCAzOS44OS41NjMgOTQuNzMuNTYzIDk0LjczbDc1LjUzMiAyLjYxNC0xMS4yNDcgNjBjLTk0LjMwNCAzNS4zNDgtNDExLjMzIDMwLjEtNDcwLjMyNC0uODl6IiBmaWxsPSJ1cmwoI2IpIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBkPSJNMjUwLjcxNyA3MDIuNDc2Yy0yMy45ODggMjMuOTUzLTc0LjExNCA0OC4wNTYtMTA5Ljg1NyA1NS42MjItNS4xODQgMTcuMTEyLTEwLjI4NCAzNi44OTguMjQgNTguMTc0IDEyNy4zOTcgMS4xNTUgNDYzLjc5LS4zMjQgNTg1LjUxNi0uNzQ3IDYuNTY4LTIzLjczMSAxMS41MzUtNDAuODk4IDQuOTY3LTU5LjU1LTM3LjQ3OS03LjQyLTgyLjc0My0xOC42MjQtMTE2LjI1LTUzLjQ5NiIgZmlsbD0idXJsKCNjKSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PHBhdGggZD0iTTE5OC4wNDEgNzY4LjYyM2MxNDkuNDU4LjA3MiAzMTEuNjY0LTUuNTEzIDQ3MS41MTIuNTgiIGZpbGw9Im5vbmUiLz48L2c+PHBhdGggZD0iTTI1Mi43NDMgMzEwLjg3Yy0zLjc2OCA0NC44NTEtNC44NTQgMzU3LjI4OC0zLjgxNyAzOTQuNTA0IDU1LjE3Ny00LjY2NiAzMTEuNjEyLTQuOTYgMzY4LjE2Mi0uNTY3LTMuMjAyLTcwLjAzLTIuMzE2LTM5Mi45NTItMi4zMTYtMzkyLjk1MiIgZmlsbD0idXJsKCNkKSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PGcgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIj48cGF0aCBkPSJNMjkxLjM4IDYzNC44MzNjMzkuODg5LTIuOTQgMTIzLjQ3LTYuMjUyIDIxNS40MzktMy4yOTVtLTIxNi43OTYtNjEuMzljNTAuNzUyLTQuODg2IDk5Ljg0OC02LjQ5NSAxNzEuMy01Ljc1Mk0yOTAuNTU4IDUwNC45NWM3Mi4yNjgtNC45OTcgNzQuMzA0LTQuNDY2IDE1Mi41MTYtNS41OTRtLTE1Mi41MTYtNTguMzQ0YzM2LjY4NS0zLjAzMyA1OC4yNTgtNC42MSAxMDIuMTYtMy41NW0tNTcuOTU4IDIwLjI0MmMuODggMjkuOTMyLS4xNzUtMS4zMzYuNzA0IDI0LjU1bTU0Ljk3NyAzOC45OTZjLjg4IDI5LjkzMi0uMTc1LTEuMzM2LjcwNCAyNC41NW0tNTYuMzg1IDM5LjcyOWMuODggMjkuOTMxLS4xNzUtMS4zMzcuNzA0IDI0LjU1bTExNi4wOS0yNi41NzljLjg3OSAyOS45MzEtLjE3Ni42OTIuNzAzIDI2LjU3OW0tNjEuODE2IDQyLjE1NGMuODggMjkuOTMyLS4xNzUuNjkzLjcwNCAyNi41OG0tOTkuMzI2LTI5NS42MDljMjcuODU3LTMuMDMzIDQyLjA1Mi00LjAwNyA2NS43NzYtMy41NSIgZmlsbD0ibm9uZSIvPjxwYXRoIGQ9Ik0xMzEuNzQ4IDE2MS4yNzhjNS4xNTYgMjguMjIzIDkuMDUyIDU0Ljk5OSAxNC4wNDggOTUuNTQgMzIuMDc3IDIyLjM2NiA1MC4wMzMgMzAuMTc3IDUzLjQ2OCA2Ny42NTcgOTYuMzUyLTE3LjM2MSAzODYuOTY4LTEzLjM2IDQ3NC4zNTMtLjM1MiA2LjA5LTMzLjc4MiAxNi4wNTMtMzkuNTU1IDYzLjEzLTY3LjkxIDUuOTQ3LTQ0LjM2MSAxMS4xNjktNjUuNzUgMTEuNTA1LTkyLjI3My0xNC4xMDctMy40My0xMTUuNDY4LTMzLjc4NC0xMjcuOTg5LTI5LjQyNC00LjQ1MyAyNi4zOTMgMS44NDQgNDkuMDY3LTQuMDE1IDczLjg4OC0zNy45NDMgMS45MDItNzEuNzQ1LjQ1OC0xMTEuMDEzLTkuNzYzLjE5NS0zMy4xNzguMTQ2LTUxLjM3MyAxLjc3Ni03Ny4wNTItMTYuNTgzLTUuOTA2LTExNS4yMDgtNi45NTYtMTMzLjgxNi0uODY1LTMuMjA3IDMxLjk3OC44NDcgNDkuMzk5LTEuNzIzIDc3LjgzLTMzLjY4MyA5LjUyOS02NS42MjcgNy4wNTctMTA1LjgzOCA5LjMxNi0zLjI0LTMzLjgwNSAyLjc0My00NS42NjcgMS45ODItNjkuMzk2LTE2LjU5LTQuNTM2LTEyMC4yMDQgMTcuOTg3LTEzNS44NjggMjIuODA0eiIgZmlsbD0idXJsKCNlKSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PHBhdGggZD0iTTE4OC43NCAyNjIuMjQ3YzE0OC42NTQtMTQuNjk1IDM2OC41MTMtMTUuNjEgNDk2LjA5NiAzLjU0NCIgZmlsbD0ibm9uZSIvPjwvZz48L2c+PC9zdmc+')} +.is2d .queen.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTA1MDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImciIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNzg1LjE0MSIgeDI9Ijg0MC45MTEiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjk0Ljc1OSIgeTI9IjM2My4wODkiLz48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNjQ5Ljg2MyIgeDI9IjcxMS4xMTciIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTcxLjE4IiB5Mj0iMjI3Ljc0OSIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0MDYuMDEyIiB4Mj0iNDcwLjgzNSIgeGxpbms6aHJlZj0iI2EiIHkxPSIxMDMuNTMyIiB5Mj0iMTMyLjk5NCIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIxNjcuODcyIiB4Mj0iMjM0LjYyIiB4bGluazpocmVmPSIjYSIgeTE9IjE3NC45OTciIHkyPSIxNzQuOTk3Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJrIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIzLjQ1OCIgeDI9Ijg3LjM3MSIgeGxpbms6aHJlZj0iI2EiIHkxPSIzMzcuODU1IiB5Mj0iMzE1LjQ2MyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzMzkuNDcxIiB4Mj0iNTE0LjU0IiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1NzEuNTkzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMzOS40NzEiIHgyPSI0OTUuMDIyIiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1ODQuNzU4Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJmIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMzOS40NzEiIHgyPSI0ODcuMjE1IiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1ODQuNzU4Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJoIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMzOS40NzEiIHgyPSI0OTguOTI2IiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1ODQuNzU4Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJsIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMzOS40NzEiIHgyPSI1MTAuNjM3IiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1ODQuNzU4Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJiIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjE1My42MDQiIHgyPSI3NjEuMzY0IiB4bGluazpocmVmPSIjYSIgeTE9IjM4MC41NCIgeTI9IjY4Mi4yMDciLz48ZyBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yNDMuOTM1IDgyNC44OWwtNTAuMzc4LTE2Ni4yMTIgNDMzLjc2OCAxLjMxOC00OS41MTkgMTY5LjY4MXoiIGZpbGw9InVybCgjYikiLz48ZyBzdHJva2U9ImdyYXkiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PGcgc3Ryb2tlLXdpZHRoPSIxNiI+PGcgZmlsbD0idXJsKCNiKSI+PHBhdGggZD0iTTYxMi43MTMgNzE2LjI4Yy0xMjIuMi00My42NjktMjgzLjQwNi00My45MjMtNDAyLjM5NC0uMTA0IDEyLjU4NSAzMC41MyAxNS45MTkgOTIuOTk4IDE1LjkxOSA5Mi45OTggMTAwLjcxOS0yOC4xNzMgMjcxLjk1NC0yNy4zMTcgMzcxLjg4NSA0LjE4OCAwIDAgMi4zMS02Ni43MDcgMTQuNTktOTcuMDgyeiIvPjxwYXRoIGQ9Ik0xOTUuMTA0IDY5Ny45MTVjMTIxLjg1LTUyLjY4NiAzMTIuNTgtNTMuNTIgNDM1LjU3Ny40MUM2NDIuODA3IDU5My4yOSA2ODEuMDMgNDYzLjYzIDc1My4zNjQgMzcwLjYyN2MtNTQuODQ4IDIxLjQ2Mi0xMzQuNDggMTU4Ljg2My0xODAuNzc1IDE4NC43NTgtMzYuMzA0LTc2LjI2MyAzNS41NDQtMjc0LjIwNCA2My40NzgtMzE2LjEyOS00Ni44OTkgMjguMjE5LTE0Ni4xNDcgMjAzLjAxNi0xNzUuNDcgMjg0Ljc4NS00Mi4yNjUtOTQuNDQ1LTMyLjM3Mi0yNzEuMDgyLTMzLjM4My0zNDUuMTA4LTMxLjc5NiA2OS41NTMtNzMuNTE4IDIyOS4zNzMtNzcuNzg4IDM0Mi4zMTQtODEuMTkzLTYwLjg2NC0xMDkuODQ2LTIyNS4yNy0xMzEuNTAxLTI5MC40MDYtMTEuOTI0IDkzLjc5OCA4Ljg4NCAyNTcuMTczIDIyLjYyMyAzMjMuMjI3LTUyLjc5Mi0zNS41OTMtMTE0LjQ0LTExMy45Mi0xNjUuNjExLTE4MC4zMDUgNjUuMDYgMTU1LjU3NCA4OC42MDggMjAyLjY5MyAxMjAuMTY3IDMyNC4xNTN6bTIxMi42NTkgMS44NjdjLTE4Ljk5OC0uMDk4LTguNTg1IDE0LjYzNS0xMi4zMTggMjEuMTE1LTguNTM4IDQuOTQ5LTM2LjI0Ni0zLjgzMi0yNy4zMjcgMTQuMzQgNi4zMTkgMTIuODc0IDE1Ljc2NiA2LjgxMyAyNi4zNzcgMTAuOTYxIDUuMjc2IDcuMjY3LTMuNjQzIDI5LjM2NiAxNS4wMzcgMjguOTAzIDE1LjQyNy0uMzgzIDcuMDE4LTIyLjQzMSAxMC4zMTYtMjguMzcyIDkuMzI2LTYuMDk0IDIxLjU2MiAyLjE2NSAyNy43MzQtMTMuNDUyIDQuNjg2LTExLjg1Ni0xOC41MTItNy40NTgtMjcuNjczLTEyLjU2NC0zLjgzNy01LjczMSA3LjYyLTIwLjgyOC0xMi4xNDYtMjAuOTMxem0tMTYzLjE5IDEyNS40OTFjODguODIzIDEwLjU5OSAyMzIuNzIyIDE0LjM2IDMzMi45NTggNC40MDctNTYuNTY4LTI1LjI4MS0yNTkuODktMjUuMDY4LTMzMi45NTgtNC40MDd6Ii8+PC9nPjxwYXRoIGQ9Ik00NzQuNjIgODIuNTE4Yy04LjU2LjE4OC0zNC45NDMgNC42Mi01MC43OTggMTIuNTI4LTQuODEgMTIuMTEtMi4zMTIgNDcuNjA2LjEzMSA3Ni42NCAxNS4xODUtMjQuMzcgNDguNzM3LTY2LjI1NCA1MC42NjctODkuMTY4eiIgZmlsbD0idXJsKCNjKSIvPjwvZz48cGF0aCBkPSJNNDQwLjc2MyA1MzAuNjA2YTQ1Ljk2MiA0NC43ODMgMCAxIDEtOTEuOTI0IDAgNDUuOTYyIDQ0Ljc4MyAwIDEgMSA5MS45MjQgMHoiIGZpbGw9InVybCgjZCkiIHN0cm9rZS13aWR0aD0iMTguNzM3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg4Ny4yMzUgLTI3MS41MDYpIHNjYWxlKC44NTM5MykiLz48cGF0aCBkPSJNNzE0LjkwMiAyMDYuMDA1Yy00LjcxNy01LjY1My0xLjcxLTE2LTQwLjAwMy0zNy4wNTVsLTQ4Ljg1NiA2MS4wMjljMjcuNDEtOC41NSA3MC43NjQtMjEuNDYgODguODYtMjMuOTc0eiIgZmlsbD0idXJsKCNlKSIgc3Ryb2tlLXdpZHRoPSIxNiIvPjxwYXRoIGQ9Ik00NDAuNzYzIDUzMC42MDZhNDUuOTYyIDQ0Ljc4MyAwIDEgMS05MS45MjQgMCA0NS45NjIgNDQuNzgzIDAgMSAxIDkxLjkyNCAweiIgZmlsbD0idXJsKCNmKSIgc3Ryb2tlLXdpZHRoPSIxOC43MzciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI5NS4yMzUgLTIxMS41MDYpIHNjYWxlKC44NTM5MykiLz48cGF0aCBkPSJNODQ1LjU2IDM1MS44OTFjMi42NzQtMTMuODI3LTEyLjE3LTE4LjI2OC0yNi40MTEtMzcuMzI0LTE5LjgzNiA4LjEyMi00Mi44MTcgMTcuODEtNTkuMDA2IDQwLjUyMiA0MC44NjctOC40MjggNTkuNDQ0IDQuMDU4IDg1LjQxNy0zLjE5OHoiIGZpbGw9InVybCgjZykiIHN0cm9rZS13aWR0aD0iMTYiLz48cGF0aCBkPSJNNDQwLjc2MyA1MzAuNjA2YTQ1Ljk2MiA0NC43ODMgMCAxIDEtOTEuOTI0IDAgNDUuOTYyIDQ0Ljc4MyAwIDEgMSA5MS45MjQgMHoiIGZpbGw9InVybCgjaCkiIHN0cm9rZS13aWR0aD0iMTguNzM3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MTcuODUgLTg1Ljc0OSkgc2NhbGUoLjg1MzkzKSIvPjxwYXRoIGQ9Ik0yMjYuNjIgMTU0LjUxOGMtMTAuNTYtMTEuODEyLTIyLjg5My0xMC4xMTctNTAuNzQ4LTE0LjIwOC45NzIgMzMuNzI2IDIxLjEwNCA0My4xMzUgMzMuMDgxIDY5LjM3NSAxNS4xODUtMjQuMzcgMTIuNzM3LTI1LjI1MyAxNy42NjctNTUuMTY3eiIgZmlsbD0idXJsKCNpKSIgc3Ryb2tlLXdpZHRoPSIxNiIvPjxwYXRoIGQ9Ik00NDAuNzYzIDUzMC42MDZhNDUuOTYyIDQ0Ljc4MyAwIDEgMS05MS45MjQgMCA0NS45NjIgNDQuNzgzIDAgMSAxIDkxLjkyNCAweiIgZmlsbD0idXJsKCNqKSIgc3Ryb2tlLXdpZHRoPSIxOC43MzciIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMjMuNzY1IC0yMTkuNTA2KSBzY2FsZSguODUzOTMpIi8+PHBhdGggZD0iTTUwLjI2MyAyODkuNzgyYy0xMy40NDcgMi44LTE0LjU4NSAzMC4zMTItMTguODA1IDQ0LjQyNiAxNS4wNTcgMTYuNTk1IDMwLjM2NyAyNi4wNSA0My41MiA1MS43MiAxNC4wNjUtMjUuMDMzLTguNzU5LTc2LjkzNi0yNC43MTUtOTYuMTQ2eiIgZmlsbD0idXJsKCNrKSIgc3Ryb2tlLXdpZHRoPSIxNiIvPjxwYXRoIGQ9Ik00NDAuNzYzIDUzMC42MDZhNDUuOTYyIDQ0Ljc4MyAwIDEgMS05MS45MjQgMCA0NS45NjIgNDQuNzgzIDAgMSAxIDkxLjkyNCAweiIgZmlsbD0idXJsKCNsKSIgc3Ryb2tlLXdpZHRoPSIxOC43MzciIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yNDkuMTA4IC02OC45Mikgc2NhbGUoLjg1MzkzKSIvPjwvZz48L2c+PC9zdmc+')} +.is2d .king.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTA1MDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjk3LjU1NCIgeDI9IjM2OC41NjIiIHhsaW5rOmhyZWY9IiNhIiB5MT0iNDI3LjA1IiB5Mj0iNTIxLjIxNiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0OTUuMjk2IiB4Mj0iNTk1Ljk3MSIgeGxpbms6aHJlZj0iI2EiIHkxPSI0NDguNTQ3IiB5Mj0iNTI4LjU0NyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIyMjEuNTUxIiB4Mj0iNjMzLjQ5MSIgeGxpbms6aHJlZj0iI2EiIHkxPSI3NzQuOTM3IiB5Mj0iODU5LjM1MSIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIxMjkuOTYyIiB4Mj0iODEyLjM2OSIgeGxpbms6aHJlZj0iI2EiIHkxPSI0MjguNjU5IiB5Mj0iODM2LjMxMyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzNjguNDY5IiB4Mj0iNDk0LjU1MSIgeGxpbms6aHJlZj0iI2EiIHkxPSIzMTkuMjc1IiB5Mj0iMzE5LjI3NSIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzNzkuMTk3IiB4Mj0iNTc5Ljg0OCIgeGxpbms6aHJlZj0iI2EiIHkxPSIxNjAuMjUzIiB5Mj0iMjg2LjkxOSIvPjxnIGZpbGwtcnVsZT0iZXZlbm9kZCI+PGcgc3Ryb2tlPSJncmF5IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMTYiPjxwYXRoIGQ9Ik0yODguNjM1IDYxMi40ODVjMjMuMTkyLTMzLjUxLTcuMDUxLTEyNS44MzkuMDE4LTE2OC4wNTIgMTEuNDczLTY4LjUwOCAxMDEuNDktMTE0LjQ5IDExMy41MDUtNzQuNzcxIDE0LjI1MyA0Ny4xMTYtNDMuNjEyIDUxLjU2My01OS43MTIgOTAuODkzLTE0Ljc4OCAzNi4xMjYtMTEuNjI0IDk2LjQ4MyAxNy4xNjYgMTMyLjgxIiBmaWxsPSJ1cmwoI2IpIi8+PHBhdGggZD0iTTU4Ni44OSA2MTcuMzE2Yy0yMy4xOTItMzMuNTEgNy4wNTItMTI1LjgzOS0uMDE4LTE2OC4wNTItMTEuNDczLTY4LjUwOC0xMDEuNDktMTE0LjQ5LTExMy41MDUtNzQuNzcxLTE0LjI1MyA0Ny4xMTYgNDMuNjEyIDUxLjU2MyA1OS43MTIgOTAuODkzIDE0Ljc4OCAzNi4xMjYgMTEuNjI0IDk2LjQ4My0xNy4xNjYgMTMyLjgxIiBmaWxsPSJ1cmwoI2MpIi8+PHBhdGggZD0iTTQwMS4yMTcgMjg4LjExNWM1LjI1Ny0xNSAxOC45MDQtNzAuOTI1IDEzLjkxNi04Ny40LTIyLjMxNC0xLjc2Ni02OC45MzUgMTguNzAyLTk5LjE1MiAxMi4xNDUtOC41MS0xNS4zODYtMTMuODI0LTQ4LjQ5NC0xLjYtNjYuNjY4IDI3LjM1Ni04LjMyNCA4Ny43MzEgNi4yNjkgMTA0LjQyIDguNTA1IDUuOTE1LTE2Ljg1My0xNC40OTUtNjcuNjM4LTEwLjU0MS04Ni4wMjcgMTguNzUtOC45NjMgNjUuMzE0LTguMDc3IDc5LjE1MyAxLjAzNC0uNzA1IDE5LjMxNC0yOC44OTUgNjYuMjI1LTI5LjU3OSA4Mi4yNjQgMTguNzg0LS45NjMgNzcuMjk0LTE2Ljg3NSA5Ny4yNjgtMTIuOTg5IDguNjE2IDE2LjcxIDEwLjQ4NiA0Ni41NjUtMy40MTQgNjUuNjQ2LTIxLjI5NSA3LjA5My03Ny42NzUtOC45My0xMDEuMTY3LTQuMjctOS45IDE5Ljk2NyA1LjQ5MSA3MS41MjMgOS4yNzggODYuNjA1IiBmaWxsPSJ1cmwoI2QpIi8+PHBhdGggZD0iTTQwOC40MSAzNzEuODMyYy0yNC43MzUtMjEuNDE4LTM1LjYzNC0yMS41OTYtMzAuODMzLTc1LjIwNiA0LjEtNDUuNzgxIDEwNi4yNTctNDMuNDIgMTA4LjYzNC0xLjk5MSAyLjk4MSA1MS45NDctMTQuMjkgNTUuODM3LTI2LjMgODAuOTkiIGZpbGw9InVybCgjZSkiLz48L2c+PHBhdGggZD0iTTI3MC45NjIgODMwLjNsLTYzLjk3NS0xOTYuMjQ0IDQ3MS4yMzMtMi4wNjctNzQuODkgMjA0LjMyNHoiIGZpbGw9InVybCgjZikiLz48ZyBzdHJva2U9ImdyYXkiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PGcgc3Ryb2tlLXdpZHRoPSIxNiI+PGcgZmlsbD0idXJsKCNmKSI+PHBhdGggZD0iTTY0My40NTYgNzE3LjExYy05My42NzYtNDguMDE1LTMwNy4xMzktNTAuMjctNDA3LjYwNiAxLjg3NSAxNC4wNzQgNDQuNDczIDE5LjcwNCA5My45NzMgMTkuNzA0IDkzLjk3MyA5MS42NjYtMjguNDY0IDI3Ny44NzMtMjkuNiAzNjcuODczIDQuMTQzIDAgMCA5LjI4LTY2LjY4IDIwLjAzLTk5Ljk5MnoiLz48cGF0aCBkPSJNNTUzLjUzMSA1NzQuMDMxYy0zNi4yNC0xNS4zMTMtNzYuNzA0LTU4LjgyNi0xMjEuOTc4LTYwLjIyMi00My41NzQgMS4wMS03OC41NTYgMzguNTY0LTEwMy4zOTcgNTguNDEtMTE1LjI3My01Mi40NjctMTEzLjg5NS0xNTIuODkyLTMzLjI1LTE3MS4zMTMgMTMuMTM1LTMgNTIuMjMyLjQ2NCA3OC4wNjMtLjcxOS04LjIyNi0yMi43MTUtMTcuMTkyLTM4LjgyMy04LjY4OC02OS4wNjItMTguMjI4LTExLjczMi00Mi40ODgtMjAuMTQ0LTcwLjEyNS0yMS43ODFhMzUxLjAyMyAzNTEuMDIzIDAgMCAwLTI1LjAzMS0uNTk0Yy04MS4yMDEgMS0xNjUuNDUxIDMwLjUzNi0xNzcuNDA2IDEwNS4yNUM3NC4yNyA1MjMuMDQ4IDE3MC44MSA1ODcuMzE1IDIwNS41NjMgNzAyLjY1NmMxMTAuMzA3LTYyLjkwOCAzNjQuNjY0LTU4LjkwMiA0NzAuMzQzLTQuNTMxIDI4LjA0OC04OS4xNjIgMTM5Ljg1MS0xOTMuMzYgMTE0Ljg0NC0yODQuMjUtMjMuMTU4LTg0LjE3LTEzNS43NDItMTA4LjgwMS0yMTAuMDMxLTEwNC41OTQtMzAuMTA5IDEuNzA2LTU5LjAxMyAxMS40NTMtODAuNzE5IDI0Ljg0NCA0LjIwMiAyMy45NzEtNC4zMTUgNDMuNTctMTEuMzc1IDY0LjI4MSAzNC4zNDUuMDE1IDk0LjYwMi03Ljk3MiAxMTguMjUgNS40MDYgNTIuMjMgMjkuNTQ3IDU2LjIxMiAxMzUuODk3LTUzLjM0NCAxNzAuMjJ6Ii8+PHBhdGggZD0iTTMyOC40ODggNTcyLjUyOGMzNy45OTUtMjYuNjc4IDU1Ljk5OC03OS42NjEgNTQuNDc5LTEyMi40MzUtMi4xOTEtNjEuNjc2LTM1LjE4LTcyLjQyNi0xNi4zNC0xMjYuNDE0IDEyLjc3NC0zNi42MDcgMTE5LjE2My0zOC40ODkgMTMxLjE3OSAxLjIzIDE0LjI1MyA0Ny4xMTYtMjIuMzQzIDc2LjQ1LTE2LjYzOCAxMjQuMTQ1IDYuNjU0IDU1LjY0IDcuMDY3IDkyLjUyMyA3Mi4yOTQgMTI2LjU3MyIvPjwvZz48cGF0aCBkPSJNMjc1LjY5MSA4MzIuNjc4Yzg3Ljg2NSAxMC40ODQgMjI4LjIxMiAxMi4yMDUgMzI3LjM2NyAyLjM2LTY4LjU5Ny0yNy45OC0yNTYuNTU1LTI3LjY3Ny0zMjcuMzY3LTIuMzZ6IiBmaWxsPSJ1cmwoI2cpIi8+PC9nPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Ik00NTMuNjIyIDczNy4wMzVhMTYuOTA4IDE2LjEwMyAwIDEgMS0zMy44MTcgMCAxNi45MDggMTYuMTAzIDAgMSAxIDMzLjgxNyAweiIgc3Ryb2tlLXdpZHRoPSIxNiIvPjxwYXRoIGQ9Ik04MTUgOTE1YTE3LjUgMTYuNjY3IDAgMSAxLTM1IDAgMTcuNSAxNi42NjcgMCAxIDEgMzUgMHoiIHN0cm9rZS13aWR0aD0iMTguMDg3IiB0cmFuc2Zvcm09Im1hdHJpeCgxLjA2MjYyIC0uMTkyNDQgLjEyOTEzIC43MTMwNCAtNjI4LjA3MiAyNDkuNTQ5KSIvPjxwYXRoIGQ9Ik04MTUgOTE1YTE3LjUgMTYuNjY3IDAgMSAxLTM1IDAgMTcuNSAxNi42NjcgMCAxIDEgMzUgMHoiIHN0cm9rZS13aWR0aD0iMTguMzIiIHRyYW5zZm9ybT0ibWF0cml4KDEuMDM4OTggLjE2ODYxIC0uMTE2MDggLjcxNTI4IC0xODguNjUyIC00MC40NDUpIi8+PC9nPjwvZz48L2c+PC9zdmc+')} diff --git a/public/piece-css/kosal.css b/public/piece-css/kosal.css new file mode 100644 index 0000000000..91dce52f19 --- /dev/null +++ b/public/piece-css/kosal.css @@ -0,0 +1,12 @@ +.is2d .pawn.white {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDojRkZGRkZGO30KCS5zdDF7ZmlsbDojQ0ZDRUNGO30KCS5zdDJ7ZmlsbDpub25lO30KCS5zdDN7ZmlsbDojMDEwMTAxO30KPC9zdHlsZT4KPGc+Cgk8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMjkuNywzNy44aDIxLjZsLTUuMS02aDAuN2MyLjYtMS45LDQuMy01LjEsNC4zLTguNmMwLTYtNC44LTEwLjctMTAuNy0xMC43cy0xMC43LDQuOC0xMC43LDEwLjcKCQljMCwzLjUsMS43LDYuNyw0LjMsOC42aDAuN0wyOS43LDM3Ljh6Ii8+Cgk8cG9seWdvbiBjbGFzcz0ic3QwIiBwb2ludHM9IjQ5LjQsNjAuNSA0NS4xLDM5LjggMzUuMSwzOS44IDMxLjYsNjAuNSAyMSw2OS45IDYwLDY5LjkgCSIvPgo8L2c+Cjxwb2x5Z29uIGNsYXNzPSJzdDEiIHBvaW50cz0iNDAuNSw1OS43IDQ3LjgsNzEgNjEuNiw3MSA1MS4yLDYwIDQ5LjgsNTkuMSA0Ni45LDM4LjkgNDAuNSwzOC45ICIvPgo8cG9seWdvbiBjbGFzcz0ic3QxIiBwb2ludHM9IjQ0LjQsMzggNTIuNSwzOCA0Ny4yLDMxLjUgNDEsMzEuNSAiLz4KPHBhdGggY2xhc3M9InN0MSIgZD0iTTQ1LDEzLjNjMy43LDUuNSwxLjEsMTcuNi0xMC4yLDE3LjZjLTAuMiwwLDEyLjEsMC42LDEzLjEtMC4zYzEuOS0xLjksMy4xLTQuNCwzLjEtNy4zCglDNTEuMSwxNy4zLDQ0LjgsMTIuMSw0NSwxMy4zeiIvPgo8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjMxLjksNjAuNiAyMS42LDY5LjcgNTkuNCw2OS43IDQ5LjIsNjAuNyA0OS4xLDYwLjYgNDQuOSw0MCAzNS4zLDQwICIvPgo8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjQ2LjEsMzIgMzQuOSwzMiAzMC4yLDM3LjkgNTAuOCwzNy45ICIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNNDcuNSwyOS41YzEuNi0xLjcsMi41LTQsMi41LTYuNGMwLTUuMy00LjItOS41LTkuNS05LjVjLTUuMiwwLTkuNSw0LjItOS41LDkuNWMwLDIuNCwwLjksNC42LDIuNSw2LjRINDcuNXoiCgkvPgo8cGF0aCBjbGFzcz0ic3QzIiBkPSJNMTUsNzIuMkg2Nkw1MS41LDU5LjRsLTQuMi0yMGg4LjJsLTcuMS04YzIuOS0yLjIsMy42LTUuNiwzLjYtOC4xYzAtNi40LTUtMTEuNC0xMS40LTExLjQKCWMtNi4zLDAtMTEuNCw1LjEtMTEuNCwxMS40YzAsMi41LDAuNiw1LjksMy42LDguMWwtNy4xLDhIMzNsLTMuNCwyMEwxNSw3Mi4yeiBNMzEuNCwyMy4zYzAtNSw0LjEtOS4xLDkuMS05LjFjNS4xLDAsOS4xLDQsOS4xLDkuMQoJYzAsMi4zLTAuOCw0LjQtMi40LDYuMUgzMy44QzMyLjMsMjcuNywzMS40LDI1LjUsMzEuNCwyMy4zeiBNMzUuMiwzMS43aDEwLjdsNC41LDUuNkgzMC43TDM1LjIsMzEuN3ogTTM1LjQsMzkuNGgwLjFoOS4yaDAuMQoJbDQuNCwyMS4ybDAsMC4xbDEwLjIsOUgyMS42bDEwLjItOS4xTDM1LjQsMzkuNHoiLz4KPC9zdmc+Cg==')} +.is2d .knight.white {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzJfMV8iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDojRkZGRkZGO30KCS5zdDF7ZmlsbDojQ0ZDRUNGO30KPC9zdHlsZT4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTQ4LDQ1LjFjLTMuMywxLjYtNy4yLDEuOS0xMSwwLjdsLTAuNC0wLjFsLTAuMywwLjJjLTAuMSwwLjEtMTIsOS45LTE1LjgsMjMuN2wtMC4zLDAuOUg2NUw2My4yLDY1di0wLjEKCWMwLTAuMS0wLjEtMTQuOC0wLjEtMjMuOGMwLTE2LjktNy42LTI1LjYtMTUtMjguNmMtMy43LTEuNC05LjItMi41LTEyLjQtMi41aC0xLjJsMy4yLDYuMkwxMy4zLDM2LjVsMSwxMC44bDUsMS40bDUuMS0zLjlIMjYKCWwtNC4zLDQuNWwxLjEsMC40bDYuNywxLjlsNS41LTYuOGMzLjUsMS41LDcuNywxLjMsMTIuNS0wLjZjMi44LTEuMiw1LjEtMy42LDYuNS01LjZDNTMuMSw0MS40LDUxLDQzLjcsNDgsNDUuMXoiLz4KPHBhdGggZD0iTTM4LDIyLjFsLTcuNyw2LjJjLTAuNSwwLjUtMC42LDEuMy0wLjIsMS45YzAuMywwLjQsMC43LDAuNiwxLjEsMC42YzAuMiwwLDAuNCwwLDAuNi0wLjFsOS4xLTMuNkwzOCwyMi4xeiIvPgo8cGF0aCBjbGFzcz0ic3QxIiBkPSJNMzguNyw3MC43TDU2LjQsNzFoOC41YzAsMC0yLjEtNS4yLTIuMS03LjJjMC04LjIsMC0yOS45LDAtMzUuMmMwLDguNC0yLjcsMTgtOS41LDI0LjgKCUM0MC41LDU3LDM4LjcsNzAuNywzOC43LDcwLjd6Ii8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0zNC42LDQ3LjNsMS4zLTEuOGw4LjgsMC44bDQuOC0yLjJsMy45LTMuNGwyLjQtNi41Yy0wLjgtMS4zLTIuMi0yLjEtNC0yLjhjLTIsNy43LTguMSwxMi4zLTE2LjMsMTAuNAoJYy0wLjQsMS4xLTAuNywxLjktMC43LDEuOWwtNywwLjNMMjIsNDguOGw3LDQuNUwzNC42LDQ3LjN6Ii8+CjxwYXRoIGQ9Ik0xOC4yLDcyLjJoNDkuMWwtMi41LTcuNWMwLTEuOSwwLTE1LjEsMC0yMy42YzAtNi44LTAuOS0yMy45LTE2LTMwLjFjLTUuOC0yLjQtMTQuNi0yLjYtMTUtMi41TDMyLDguNmwzLjcsNy4ybC0yNC4yLDIwCglsMS4zLDEyLjhsMTQuNSw0LjJjLTMuNSw0LjUtNy4zLDEwLjctOC45LDE4TDE4LjIsNzIuMnogTTM2LjcsNDYuNWMxLjUsMC41LDMuMSwwLjgsNC44LDAuOGMyLjQsMCw0LjctMC41LDYuOC0xLjUKCWM0LjEtMiw2LjgtNS42LDcuMy0xMC4xbDAuMi0xLjRsLTAuNiwxLjJjMCwwLjEtMyw1LjgtNy45LDhjLTMuOSwxLjYtOC40LDIuNC0xMi40LDAuNGwtNS42LDYuOWwtNS44LTEuN0wyMy4xLDQ5bDQuNy00LjloLTMuNwoJbC01LDMuOEwxNSw0Ni43bC0wLjktOS45bDI0LjYtMjAuNGwtMi45LTUuNmMyLjksMCw4LjMsMC45LDEyLjEsMi40YzUuNywyLjMsMTQuNSw5LjYsMTQuNSwyNy45YzAsOS4xLDAuMSwyMy44LDAuMSwyMy44djAuMgoJbDEuNSw0LjdIMjEuMkMyNC44LDU2LjYsMzUuOSw0Ny4xLDM2LjcsNDYuNXoiLz4KPC9zdmc+Cg==')} +.is2d .bishop.white {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojRkZGRkZGO30KCS5zdDJ7ZmlsbDojQ0ZDRUNGO30KPC9zdHlsZT4KPHJlY3QgY2xhc3M9InN0MCIgd2lkdGg9IjgxIiBoZWlnaHQ9IjgxIi8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik02MS40LDcxbC0xMS45LTkuMWwxMC42LTE0LjZjMC0xMS00LjktMTkuOS0xMS45LTI2LjNsLTEuNy0wLjhsLTcuOSwxNC4zbC0xLjUtMS42bDcuOC0xNC43bDAsMGwyLjctNS4xCgljMC0wLjEsMC0wLjIsMC0wLjJjMC0zLjYtMi45LTYuNi02LjYtNi42Yy0zLjYsMC02LjYsMi45LTYuNiw2LjZjMCwwLjEsMCwwLjIsMCwwLjJsMi4zLDQuNEMyOCwyNC4xLDIwLjksMzQuMSwyMC45LDQ3LjNsMTAuNiwxNC42CglMMTkuNiw3MUg2MS40eiIvPgo8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjQ1LjYsNzAuNyA2MCw3MC43IDQ5LjYsNjEuMiA0Mi44LDYxLjIgIi8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik01MC44LDI1LjFDNTQuNyw0Mi4xLDM2LDU1LjgsMzYsNTUuOGw3LjMsNC43aDcuNGwxMC4yLTEzLjJsLTEuNS04LjZsLTMuNi04LjNMNTMuMiwyNkw1MC44LDI1LjF6Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik00NC41LDguNmMwLjgsMi40LTMuNCw0LjQtMy40LDQuNHY1LjFsMy4zLDAuMWwzLTQuM2wtMC4zLTMuNEw0NSw4LjZINDQuNXoiLz4KPHBhdGggZD0iTTY1LDcyLjJMNTAuOSw2MS42bDEwLjItMTR2LTAuNGMwLTE0LjEtNy42LTIzLjEtMTIuMi0yNy4zbC0yLjMtMi4zbDIuMS0zLjlsMC4xLTAuM3YtMC41YzAtNC4zLTMuNS03LjktNy45LTcuOQoJYy00LjMsMC03LjgsMy41LTcuOCw3Ljl2MC41bDEuOSwzLjdjLTUuOSw0LjYtMTUuNSwxNC42LTE1LjUsMzAuMXYwLjRsMTAuMiwxNEwxNiw3Mi4ySDY1eiBNMjIuNSw0Ni45Yy0wLjMtMTQuNiw5LjMtMjQsMTUtMjguMgoJbDAuOS0wLjZMMzUuNywxM2MwLTIuOSwyLjQtNS4zLDUuMy01LjNjMi45LDAsNS4zLDIuNCw1LjQsNS4zTDM1LjgsMzQuNnYwLjFsMi4yLDUuOGw5LjMtMTguOGwxLjEsMWM0LjgsNC43LDEwLjQsMTIuNywxMC4xLDI0LjEKCWwtOS4yLDEzSDMxLjhMMjIuNSw0Ni45eiBNMzIuOSw2Mi41SDQ4bDkuOCw3LjNIMjMuMkwzMi45LDYyLjV6Ii8+Cjxwb2x5bGluZSBwb2ludHM9IjM2LjIsMTggNDEuMSwxOCAzOC40LDIwLjEgMzQuNiwyMC4xICIvPgo8L3N2Zz4K')} +.is2d .rook.white {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDojRkZGRkZGO30KCS5zdDF7ZmlsbDojQ0ZDRUNGO30KPC9zdHlsZT4KPHBvbHlnb24gY2xhc3M9InN0MCIgcG9pbnRzPSI1OC43LDU5LjQgNTUuNSwzMi4xIDY0LjEsMjMuOSA2NC4xLDIzLjkgNjQuMSwxMi44IDUzLDEyLjggNTMsMjAuOSA0Ni4zLDIwLjkgNDYuMywxMi44IDM0LjcsMTIuOCAKCTM0LjcsMjAuOSAyOCwyMC45IDI4LDEyLjggMTYuOSwxMi44IDE2LjksMjMuOSAyNS41LDMyLjEgMjIuMyw1OS40IDE1LjcsNTkuNCAxNS43LDcxIDE5LjgsNzEgNjEuMSw3MSA2MS4yLDcxIDY1LjMsNzEgNjUuMyw1OS40IAoJIi8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik01OC41LDU5LjdsLTQuMi0yNy4yaDIuMmw3LjYtOC42VjEyLjhsLTUuOCw0LjZ2OC4ySDMybDExLjYsNi45aDMuMmMwLDEyLjEtMi44LDIxLjMtMTEuNywyNy4yaDEzLjNMNTQuNSw3MAoJaDkuOVY1OS43SDU4LjV6Ii8+CjxwYXRoIGQ9Ik01OS4xLDU4LjFsLTIuNi0yNC44bDguNy05VjExLjVINTEuOHY4LjJoLTQuMnYtOC4ySDMzLjV2OC4yaC00LjJ2LTguMkgxNS42djEyLjlsOC43LDlsLTIuNiwyNC44bDAsMGgtNy4zdjE0LjFoNTEuOFY3MgoJbDAsMGgwLjJWNTguMUg1OS4xeiBNMzYsMjIuMlYxNGg5djguMmg5LjJWMTRoOC41djkuM0w1NC40LDMySDI2LjVsLTguNC04LjZWMTRoOC42djguMkgzNnogTTU0LDM0LjRsMi42LDIzLjdIMjQuM2wyLjYtMjMuN0g1NHoKCSBNNTYuOSw2MC42SDYwaDR2OS4xSDE3di05LjFoNC44SDI0QzI0LDYwLjYsNTYuOSw2MC42LDU2LjksNjAuNnoiLz4KPC9zdmc+Cg==')} +.is2d .queen.white {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojRkZGRkZGO30KCS5zdDJ7ZmlsbDojQ0ZDRUNGO30KCS5zdDN7ZmlsbDojMjMxRjIwO30KPC9zdHlsZT4KPHJlY3QgY2xhc3M9InN0MCIgd2lkdGg9IjgxIiBoZWlnaHQ9IjgxIi8+CjxnPgoJPGNpcmNsZSBjbGFzcz0ic3QxIiBjeD0iMjEuOSIgY3k9IjE2LjUiIHI9IjUuMiIvPgoJPHBhdGggY2xhc3M9InN0MSIgZD0iTTU5LjEsMjEuOGMyLjksMCw1LjItMi4zLDUuMi01LjJzLTIuMy01LjItNS4yLTUuMnMtNS4yLDIuMy01LjIsNS4yUzU2LjIsMjEuOCw1OS4xLDIxLjh6Ii8+Cgk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNNzIuMSwyNi40Yy0yLjksMC01LjIsMi4zLTUuMiw1LjJjMCwxLjQsMC42LDIuOCwxLjUsMy43TDU1LjIsNTAuNWwzLjMtMjguN2wtMi4xLTAuNmwtOS44LDE2LjlsLTUuMS0yMS43CgkJaC0xLjFoLTEuMWwtNS4xLDIxLjdsLTkuOC0xNi45bC0yLjEsMC42bDMuMywyOC43bC0xMy0xNS4yYzAuOS0wLjksMS41LTIuMywxLjUtMy43YzAtMi45LTIuMy01LjItNS4yLTUuMnMtNS4yLDIuMy01LjIsNS4yCgkJczIuMyw1LjIsNS4yLDUuMmMwLjUsMCwxLTAuMSwxLjUtMC4yTDE5LjUsNzFoNDIuMWw5LjEtMzQuNGMwLjUsMC4xLDEsMC4yLDEuNSwwLjJjMi45LDAsNS4yLTIuMyw1LjItNS4yUzc1LDI2LjQsNzIuMSwyNi40eiIvPgoJPGNpcmNsZSBjbGFzcz0ic3QxIiBjeD0iNDAuNSIgY3k9IjExLjMiIHI9IjUuMiIvPgo8L2c+CjxnPgoJPHBhdGggY2xhc3M9InN0MiIgZD0iTTQ4LjQsMzMuNiIvPgoJPHBhdGggY2xhc3M9InN0MiIgZD0iTTM0LjUsMzMuNiIvPgoJPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSI0MS40LDIwLjMgNDYuNywzOC4yIDQxLjQsNDUuNSAJIi8+Cgk8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjI3LjEsNTMuNiAyMy42LDYwLjQgMTMuOSwzOC4zIAkiLz4KCTxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iMzQsNTAuNSAyNC44LDIyLjggNDAuNSw1MC45IAkiLz4KCTxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iNDguMiw1MC41IDU3LjUsMjUuOCA1My45LDUzLjYgCSIvPgoJPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSI1Mi45LDcwLjQgNjguNSwzNi43IDcwLDM3IDYwLjcsNzAuNCAJIi8+CjwvZz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTczLjMsMzYuN2MzLjQtMC45LDMuOS0zLjQsNC02LjdjMC0wLjYtMC45LTEuOC0xLjMtMS44Yy0wLjQsMC4xLTAuOCwwLjEtMS4yLDAuM2MwLjMsMi41LTEuMyw1LTMuOCw1LjcKCWMtMS4xLDAuMy0yLjEsMC4yLTMuMS0wLjFDNjcuMywzNS4xLDcxLjgsMzcuMSw3My4zLDM2Ljd6Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik02MCwyMS4zYzMuNC0wLjksMy45LTMuNCw0LTYuN2MwLTAuNi0wLjktMS44LTEuMy0xLjhjLTAuNCwwLjEtMC44LDAuMS0xLjIsMC4zYzAuMywyLjUtMS4zLDUtMy44LDUuNwoJYy0xLjEsMC4zLTIuMSwwLjItMy4xLTAuMUM1NCwxOS43LDU4LjUsMjEuNyw2MCwyMS4zeiIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNMTAuMSwzNi43YzMuNC0wLjksMy45LTMuNCw0LTYuN2MwLTAuNi0wLjktMS44LTEuMy0xLjhjLTAuNCwwLjEtMC44LDAuMS0xLjIsMC4zYzAuMywyLjUtMS4zLDUtMy44LDUuNwoJYy0xLjEsMC4zLTIuMSwwLjItMy4xLTAuMUM0LjEsMzUuMSw4LjYsMzcuMSwxMC4xLDM2Ljd6Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0yMy4xLDIxLjNjMy40LTAuOSwzLjktMy40LDQtNi43YzAtMC42LTAuOS0xLjgtMS4zLTEuOGMtMC40LDAuMS0wLjgsMC4xLTEuMiwwLjNjMC4zLDIuNS0xLjMsNS0zLjgsNS43CgljLTEuMSwwLjMtMi4xLDAuMi0zLjEtMC4xQzE3LjEsMTkuNywyMS42LDIxLjcsMjMuMSwyMS4zeiIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNNDEuNiwxNi4xYzMuNC0wLjksMy45LTMuNCw0LTYuN2MwLTAuNi0wLjktMS44LTEuMy0xLjhjLTAuNCwwLjEtMC44LDAuMS0xLjIsMC4zYzAuMywyLjUtMS4zLDUtMy44LDUuNwoJYy0xLjEsMC4zLTIuMSwwLjItMy4xLTAuMUMzNS42LDE0LjYsNDAuMSwxNi41LDQxLjYsMTYuMXoiLz4KPHBvbHlnb24gY2xhc3M9InN0MyIgcG9pbnRzPSI0MC41LDY1LjcgMzYuNiw1OS44IDQwLjUsNTQgNDQuNCw1OS44ICIvPgo8Zz4KCTxjaXJjbGUgY2xhc3M9InN0MSIgY3g9IjIxLjkiIGN5PSIxNi41IiByPSI1LjIiLz4KCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik01OS4xLDIxLjhjMi45LDAsNS4yLTIuMyw1LjItNS4ycy0yLjMtNS4yLTUuMi01LjJzLTUuMiwyLjMtNS4yLDUuMlM1Ni4yLDIxLjgsNTkuMSwyMS44eiIvPgoJPHBhdGggY2xhc3M9InN0MSIgZD0iTTcyLjEsMjYuNGMtMi45LDAtNS4yLDIuMy01LjIsNS4yYzAsMS40LDAuNiwyLjgsMS41LDMuN0w1NS4yLDUwLjVsMy4zLTI4LjdsLTIuMS0wLjZsLTkuOCwxNi45bC01LjEtMjEuNwoJCWgtMS4xaC0xLjFsLTUuMSwyMS43bC05LjgtMTYuOWwtMi4xLDAuNmwzLjMsMjguN2wtMTMtMTUuMmMwLjktMC45LDEuNS0yLjMsMS41LTMuN2MwLTIuOS0yLjMtNS4yLTUuMi01LjJzLTUuMiwyLjMtNS4yLDUuMgoJCXMyLjMsNS4yLDUuMiw1LjJjMC41LDAsMS0wLjEsMS41LTAuMkwxOS41LDcxaDQyLjFsOS4xLTM0LjRjMC41LDAuMSwxLDAuMiwxLjUsMC4yYzIuOSwwLDUuMi0yLjMsNS4yLTUuMlM3NSwyNi40LDcyLjEsMjYuNHoiLz4KCTxjaXJjbGUgY2xhc3M9InN0MSIgY3g9IjQwLjUiIGN5PSIxMS4zIiByPSI1LjIiLz4KPC9nPgo8Zz4KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik00OC40LDMzLjYiLz4KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0zNC41LDMzLjYiLz4KCTxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iNDEuNCwyMC4zIDQ2LjcsMzguMiA0MS40LDQ1LjUgCSIvPgoJPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSIyNy4xLDUzLjYgMjMuNiw2MC40IDEzLjksMzguMyAJIi8+Cgk8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjM0LDUwLjUgMjQuOCwyMi44IDQwLjUsNTAuOSAJIi8+Cgk8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjQ4LjIsNTAuNSA1Ny41LDI1LjggNTMuOSw1My42IAkiLz4KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik00Mi4xLDcwLjRDNjIsNjUuNyw2OC41LDM2LjcsNjguNSwzNi43TDcwLDM3bC05LjMsMzMuNEM2MC43LDcwLjQsNTIuOCw3MC40LDQyLjEsNzAuNHoiLz4KPC9nPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNNzMuMywzNi43YzMuNC0wLjksMy45LTMuNCw0LTYuN2MwLTAuNi0wLjktMS44LTEuMy0xLjhjLTAuNCwwLjEtMC44LDAuMS0xLjIsMC4zYzAuMywyLjUtMS4zLDUtMy44LDUuNwoJYy0xLjEsMC4zLTIuMSwwLjItMy4xLTAuMUM2Ny4zLDM1LjEsNzEuOCwzNy4xLDczLjMsMzYuN3oiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTYwLDIxLjNjMy40LTAuOSwzLjktMy40LDQtNi43YzAtMC42LTAuOS0xLjgtMS4zLTEuOGMtMC40LDAuMS0wLjgsMC4xLTEuMiwwLjNjMC4zLDIuNS0xLjMsNS0zLjgsNS43CgljLTEuMSwwLjMtMi4xLDAuMi0zLjEtMC4xQzU0LDE5LjcsNTguNSwyMS43LDYwLDIxLjN6Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0xMC4xLDM2LjdjMy40LTAuOSwzLjktMy40LDQtNi43YzAtMC42LTAuOS0xLjgtMS4zLTEuOGMtMC40LDAuMS0wLjgsMC4xLTEuMiwwLjNjMC4zLDIuNS0xLjMsNS0zLjgsNS43CgljLTEuMSwwLjMtMi4xLDAuMi0zLjEtMC4xQzQuMSwzNS4xLDguNiwzNy4xLDEwLjEsMzYuN3oiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTIzLjEsMjEuM2MzLjQtMC45LDMuOS0zLjQsNC02LjdjMC0wLjYtMC45LTEuOC0xLjMtMS44Yy0wLjQsMC4xLTAuOCwwLjEtMS4yLDAuM2MwLjMsMi41LTEuMyw1LTMuOCw1LjcKCWMtMS4xLDAuMy0yLjEsMC4yLTMuMS0wLjFDMTcuMSwxOS43LDIxLjYsMjEuNywyMy4xLDIxLjN6Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik00MS42LDE2LjFjMy40LTAuOSwzLjktMy40LDQtNi43YzAtMC42LTAuOS0xLjgtMS4zLTEuOGMtMC40LDAuMS0wLjgsMC4xLTEuMiwwLjNjMC4zLDIuNS0xLjMsNS0zLjgsNS43CgljLTEuMSwwLjMtMi4xLDAuMi0zLjEtMC4xQzM1LjYsMTQuNiw0MC4xLDE2LjUsNDEuNiwxNi4xeiIvPgo8cG9seWdvbiBwb2ludHM9IjQwLjUsNjUuNyAzNi42LDU5LjggNDAuNSw1NCA0NC40LDU5LjggIi8+CjxwYXRoIGQ9Ik03Mi4xLDI1LjFjLTMuNiwwLTYuNCwyLjktNi40LDYuNWMwLDEuMywwLjQsMi42LDEuMSwzLjdsLTEwLjUsMTNsMy40LTI1LjRjMy4zLTAuMyw1LjktMy4xLDUuOS02LjRjMC0zLjYtMi45LTYuNS02LjUtNi41CglzLTYuNSwyLjktNi41LDYuNWMwLDEuOSwwLjgsMy43LDIuMyw1bC03LjgsMTMuNEw0MywxNy4zYzIuMy0xLDMuOS0zLjQsMy45LTZjMC0zLjYtMi45LTYuNC02LjQtNi40Yy0zLjYsMC02LjUsMi45LTYuNSw2LjQKCWMwLDIuNiwxLjUsNC45LDMuOSw2bC00LjEsMTcuNkwyNiwyMS41YzEuNS0xLjIsMi4zLTMuMSwyLjMtNWMwLTMuNi0yLjktNi41LTYuNS02LjVzLTYuNSwyLjktNi41LDYuNWMwLDMuMywyLjYsNi4xLDUuOSw2LjQKCWwzLjQsMjUuNGwtMTAuNC0xM2MwLjctMSwxLjEtMi4zLDEuMS0zLjdjMC0zLjYtMi45LTYuNS02LjUtNi41UzIuNCwyOCwyLjQsMzEuNlM1LjMsMzgsOC44LDM4aDAuNWw5LDM0djAuMmg0NGw5LTM0LjJoMC41CgljMy42LDAsNi40LTIuOSw2LjQtNi40Qzc4LjMsMjgsNzUuNiwyNS4xLDcyLjEsMjUuMXogTTEzLjEsMzEuNmMwLDIuMy0xLjksNC4xLTQuMiw0LjFzLTQuMS0xLjgtNC4xLTQuMXMxLjktNC4yLDQuMS00LjIKCUMxMS4yLDI3LjQsMTMuMSwyOS4zLDEzLjEsMzEuNnogTTIxLjksMjAuOGMtMi4zLDAtNC4xLTEuOS00LjEtNC4yczEuOS00LjIsNC4xLTQuMmMyLjMsMCw0LjIsMS45LDQuMiw0LjIKCUMyNi4xLDE4LjgsMjQuMiwyMC44LDIxLjksMjAuOHogTTU1LDE2LjVjMC0yLjMsMS45LTQuMiw0LjEtNC4yYzIuMywwLDQuMiwxLjksNC4yLDQuMnMtMS45LDQuMi00LjIsNC4yQzU2LjgsMjAuOCw1NSwxOC45LDU1LDE2LjUKCXogTTIwLjQsNjkuOGwtOC42LTMyLjRjMC4xLTAuMSwwLjItMC4xLDAuMy0wLjFzMC4yLTAuMSwwLjMtMC4xbDE1LjEsMTcuM2wtMy43LTMxLjZoMC4xTDQwLjMsNTFsMC4yLDAuNGwxNi42LTI4LjdoMC4xbC0zLjcsMzEuNgoJTDY4LjYsMzdjMC4yLDAuMSwwLjQsMC4yLDAuNiwwLjNsLTguNiwzMi41SDIwLjR6IE03Ni4zLDMxLjZjMCwyLjMtMS45LDQuMS00LjIsNC4xYy0yLjMsMC00LjEtMS44LTQuMS00LjFzMS45LTQuMiw0LjEtNC4yCglDNzQuNCwyNy40LDc2LjMsMjkuMyw3Ni4zLDMxLjZ6IE00MC41LDQ2LjNMMzUuNywzOGw0LjctMjAuMmgwLjNMNDUuMywzOEw0MC41LDQ2LjN6IE00MC41LDE1LjVjLTIuMywwLTQuMi0xLjktNC4yLTQuMgoJczEuOS00LjEsNC4yLTQuMXM0LjIsMS45LDQuMiw0LjFDNDQuOCwxMy42LDQyLjgsMTUuNSw0MC41LDE1LjV6Ii8+Cjwvc3ZnPgo=')} +.is2d .king.white {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojRkZGRkZGO30KCS5zdDJ7ZmlsbDojQ0ZDRUNGO30KPC9zdHlsZT4KPHJlY3QgY2xhc3M9InN0MCIgd2lkdGg9IjgxIiBoZWlnaHQ9IjgxIi8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik01OCwyNS45Yy02LDAtOS4xLDIuNi0xMC42LDQuMWwtNywxMi4ybC03LTEyLjJDMzIsMjguNSwyOSwyNS45LDIzLDI1LjljLTkuNCwwLTE0LjksNy43LTE0LjksMTUuMwoJYzAsOC42LDMuNywxMS41LDguNiwyMS43VjcxaDIzLjhoMjMuOHYtOC4xYzQuOS0xMC4xLDguNi0xMy4xLDguNi0yMS43QzcyLjksMzMuNiw2Ny40LDI1LjksNTgsMjUuOXoiLz4KPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSIzNS4zLDMyLjggNDAuNSw0My41IDQ1LjcsMzIuOCA0Mi42LDIxLjggNTAuNSwyNC4yIDUwLjUsMTYuNiA0Mi42LDE3LjYgNDQuMywxMC4zIDM2LjcsMTAuMyAKCTM4LjQsMTcuNiAzMC41LDE2LjYgMzAuNSwyNC4yIDM4LjQsMjEuOCAiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTY0LjcsMjcuNEM3MS44LDQwLDU4LDU4LjYsNDUuOSw1OS45bDE5LjQsMi42bDYuNi0xMy40bDEtOS45TDcxLjIsMzRsLTIuNi0zLjZMNjQuNywyNy40eiIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNMzMuNiwzMC4xYzEuMSw1LjQtMS42LDE0LjYtNS40LDIwLjVTMTcuNyw2MS40LDE3LjcsNjEuNGwyMi44LTEuNlY0Mi42TDMzLjYsMzAuMXoiLz4KPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSI1My4xLDYwLjYgNTMuMSw3MC41IDY0LDcwLjUgNjQsNjIuOSAiLz4KPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSI0OS41LDE3LjcgNDguMiwyMC41IDQxLjEsMjAuMyA0OS41LDIzLjYgNTAuNSwyMy42ICIvPgo8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjQzLjEsMTEuMyA0MC41LDEzIDQwLjUsMTkuMiA0Mi4xLDE4LjIgIi8+Cjxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iNDEuOCwyMS41IDQxLjgsMzMuMiA0MC41LDQwLjIgNDUsMzQgIi8+Cjxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iMzkuOSwyMC42IDMwLjUsMjAuNiAzMC41LDI0LjIgIi8+CjxnPgoJPHBvbHlnb24gcG9pbnRzPSIzNi40LDUxLjIgNDAuNSw1Ny4yIDQ0LjYsNTEuMiA0MC41LDQ1LjIgCSIvPgoJPHBhdGggZD0iTTY5LjgsMjkuOWMtMy0zLjQtNy4yLTUuMi0xMS44LTUuMmMtNC44LDAtOC42LDEuNS0xMS41LDQuNUw0NiwzMGwtMS45LTYuN2w3LjQsMi4yVjE1LjRsLTcuNiwxbDEuNy03LjFIMzUuNGwxLjcsNy4xCgkJbC03LjYtMXYxMC4xbDcuNC0yLjJMMzUsMzAuMWwtMC40LTAuN2wtMC4xLTAuMmwwLTAuMWMtMi45LTMtNi43LTQuNS0xMS41LTQuNWMtMTAuMSwwLTE2LjEsOC40LTE2LjEsMTYuNmMwLDYuNCwyLDEwLDQuOCwxNC45CgkJbDAuNiwxYzEsMS43LDIuMSwzLjcsMy4yLDZ2OS4xaDUwLjF2LTkuMWMxLjItMi4zLDIuMi00LjMsMy4yLTZsMC42LTFjMi44LTQuOSw0LjgtOC41LDQuOC0xNC45Qzc0LjIsMzcuMSw3Mi42LDMzLDY5LjgsMjkuOXoKCQkgTTM5LjksMjAuM2wtOC40LDIuNXYtNS4xbDguMiwxbC0xLjgtNy40aDUuMmwtMS44LDcuNGw4LjItMXY1LjFsLTguNC0yLjVsMy41LDEyLjJsLTQuMSw3LjJsLTQuMS03LjJMMzkuOSwyMC4zeiBNNjMsNjkuOEgxNy44CgkJdi02LjVDMjEuNiw2Mi42LDMxLDYxLDQwLjUsNjFjOS4zLDAsMTguNiwxLjUsMjIuNSwyLjJWNjkuOHogTTY3LjIsNTQuOUw2Ny4yLDU0LjljLTEsMS42LTMsNC43LTMuOCw1LjljLTQuMS0wLjctMTMuNC0yLjItMjMtMi4yCgkJYy05LjcsMC0xOS4yLDEuNS0yMy4xLDIuMmMtMC44LTEuMi0yLjgtNC4yLTMuNy01LjlsLTAuMS0wLjFDMTAuOCw1MCw5LjEsNDcsOS4xLDQxLjNjMC05LjEsNy0xNCwxMy42LTE0YzQsMCw3LjIsMS4yLDkuNiwzLjYKCQlsOCwxMy45bDgtMTMuOWMyLjQtMi40LDUuNi0zLjYsOS42LTMuNmM4LjksMCwxMy43LDcuMiwxMy43LDE0QzcxLjcsNDcsNzAsNTAsNjcuMiw1NC45eiIvPgo8L2c+Cjwvc3ZnPgo=')} +.is2d .pawn.black {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojMDEwMTAxO30KCS5zdDJ7ZmlsbDojNkQ2RTZFO30KCS5zdDN7ZGlzcGxheTpub25lO30KCS5zdDR7ZGlzcGxheTppbmxpbmU7ZmlsbDpub25lO30KCS5zdDV7ZGlzcGxheTppbmxpbmU7ZmlsbDojRkZGRkZGO30KCS5zdDZ7ZGlzcGxheTppbmxpbmU7ZmlsbDojQ0ZDRUNGO30KCS5zdDd7ZGlzcGxheTppbmxpbmU7ZmlsbDojMjMxRjIwO3N0cm9rZTojMDAwMDAwO3N0cm9rZS13aWR0aDowLjU7c3Ryb2tlLW1pdGVybGltaXQ6MTA7fQoJLnN0OHtkaXNwbGF5OmlubGluZTtzdHJva2U6IzAwMDAwMDtzdHJva2Utd2lkdGg6MC41O3N0cm9rZS1taXRlcmxpbWl0OjEwO30KCS5zdDl7ZGlzcGxheTppbmxpbmU7fQo8L3N0eWxlPgo8cmVjdCBjbGFzcz0ic3QwIiB3aWR0aD0iODEiIGhlaWdodD0iODEiLz4KPHBhdGggY2xhc3M9InN0MSIgZD0iTTQwLjUsMTIuNWMtNiwwLTEwLjcsNC44LTEwLjcsMTAuN2MwLDMuNiwxLjgsNi45LDQuNiw4LjhoMTIuM2MyLjgtMS45LDQuNi01LjIsNC42LTguOAoJQzUxLjIsMTcuMiw0Ni41LDEyLjUsNDAuNSwxMi41Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik00My4yLDE2LjRjLTEuNS0wLjktMy4zLTEuMS01LjItMC42Yy0zLjYsMS01LjYsNC42LTQuNyw4LjJjMCwwLjEsMC4xLDAuMiwwLjEsMC4zQzM5LjIsMjUsNDQsMTkuMSw0My4yLDE2LjR6CgkiLz4KPHBhdGggY2xhc3M9InN0MSIgZD0iTTM0LjUsMzEuN2wtMC4zLDcuN2wtMy41LDIxLjdMMTguMyw3Mmg0NC4zTDUwLjMsNjEuMUw0NiwzOS40bC0wLjMtNy43Ii8+Cjxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iMzcuNywzOS42IDMzLjgsNjIuMSAyNy4yLDY5LjIgMzQuOCw2OS4yIDQwLDYzLjggNDAuMSwzOS42ICIvPgo8cG9seWdvbiBjbGFzcz0ic3QxIiBwb2ludHM9IjI2LjYsMzguOCA1NC40LDM4LjggNDcuNywzMC44IDMzLjMsMzAuOCAiLz4KPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSIzMi4zLDM2LjUgNDEuMSwzNi41IDM5LDMyLjUgMzUuMiwzMi41ICIvPgo8ZyBpZD0iTGF5ZXJfMl8xXyIgY2xhc3M9InN0MyI+Cgk8cmVjdCBjbGFzcz0ic3Q0IiB3aWR0aD0iODEiIGhlaWdodD0iODEiLz4KCTxwYXRoIGNsYXNzPSJzdDUiIGQ9Ik0zNC4zLDMzLjJjLTIuOC0yLTQuNy01LjItNC43LTguOWMwLTYsNC45LTEwLjksMTAuOS0xMC45czEwLjksNC45LDEwLjksMTAuOWMwLDMuNy0xLjksNy00LjcsOC45bDAuNSw4LjMKCQlsMy40LDE4LjdMNjMuMyw3MUgxNy43bDEyLjctMTAuOGwzLjQtMTguNyIvPgoJPHBhdGggY2xhc3M9InN0NiIgZD0iTTQ1LDE0LjRDNDguNywxOS45LDQ2LjEsMzMsMzQuOCwzM2MtMC4yLDAsMTIuMSwwLjYsMTMuMS0wLjNjMS45LTEuOSwzLjEtNC40LDMuMS03LjMKCQlDNTEuMSwxOS40LDQ0LjgsMTMuMiw0NSwxNC40eiIvPgoJPHBvbHlnb24gY2xhc3M9InN0NiIgcG9pbnRzPSI0MC41LDYwLjggNDcuOCw3MCA2Mi4xLDcwIDUxLjIsNjEuMSA0OS44LDYwLjIgNDYuOSw0MSA0MC41LDQxIAkiLz4KCTxwYXRoIGNsYXNzPSJzdDciIGQ9Ik00MC41LDExLjdjLTcsMC0xMi43LDUuNy0xMi43LDEyLjdjMCw0LjMsMi4yLDguMSw1LjUsMTAuNGg3LjNjLTUuNywwLTEwLjQtNC43LTEwLjQtMTAuNFMzNC45LDE0LDQwLjYsMTQKCQlTNTEsMTguNiw1MSwyNC4zcy00LjcsMTAuNC0xMC40LDEwLjRoNy4zYzMuMy0yLjMsNS41LTYuMiw1LjUtMTAuNEM1My4xLDE3LjQsNDcuNCwxMS43LDQwLjUsMTEuN3oiLz4KCTxwYXRoIGNsYXNzPSJzdDgiIGQ9Ik00OC4yLDQybDMuMiwxNy42TDY2LDcySDE1bDE0LjUtMTIuNEwzMi44LDQyIE0zNSw0MWwtMy42LDE5LjdsLTExLDkuM2g0MC4xbC0xMC45LTkuM0w0Niw0MSIvPgoJPHBhdGggY2xhc3M9InN0NSIgZD0iTTM0LjMsMzMuMiIvPgoJPHBvbHlnb24gY2xhc3M9InN0OSIgcG9pbnRzPSI1MC4zLDMyLjggMzAuNywzMi44IDIyLjUsNDMuMiA1OC41LDQzLjIgCSIvPgoJPHBvbHlnb24gY2xhc3M9InN0NSIgcG9pbnRzPSIyNy41LDQxIDUzLjUsNDEgNDguOSwzNS4yIDMyLjEsMzUuMiAJIi8+Cgk8cG9seWdvbiBjbGFzcz0ic3Q2IiBwb2ludHM9IjQ0LjEsNDEgNTMuNSw0MSA0OC45LDM1LjIgNDAuNywzNS4yIAkiLz4KPC9nPgo8L3N2Zz4K')} +.is2d .knight.black {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojMDEwMTAxO30KCS5zdDJ7ZmlsbDojNkQ2RTZFO30KPC9zdHlsZT4KPHJlY3QgY2xhc3M9InN0MCIgd2lkdGg9IjgxIiBoZWlnaHQ9IjgxIi8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0xOS42LDcyQzM4LjIsNzIsNjcsNzIsNjcsNzJsLTItNi4xYzAsMC0wLjEtMTctMC4xLTI2LjFjMC0xNy4zLTguNS0yNS4zLTE2LTI4LjRjLTUuNi0yLjMtMTQuNi0xLjgtMTQuNi0xLjgKCWwzLjMsNi41TDEyLDM2LjRsMiwxMi4ybDEzLjQsMy41bDYuMS01LjFjMS4yLDAuNSwyLjUsMC44LDMuNywxLjF2MC4zQzM3LjIsNDguNCwyMi45LDU3LDE5LjYsNzJ6IE0zMS40LDMxLjMKCWMtMC42LDAuMy0xLjEtMC41LTAuNi0xbDcuMi02LjJsMi4yLDMuN0wzMS40LDMxLjN6Ii8+Cjxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iMTUuOCwzOCAxNy4xLDQ1LjkgMjEuOCw0NyAyMS43LDQyLjQgMTguOCw0MS45ICIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNMzAuOCwzMy40bDE1LjYtMy44bDIuMi0zLjhjMCwwLDIuOCwxLjEsMi4xLDYuM3MtNi44LDguMy0xMi4xLDcuNkMzMS43LDM4LjgsMzAuOCwzMy40LDMwLjgsMzMuNHoiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTM2LDY3LjljNS4xLTE2LjQsMTYuNC0xMywxNi44LTIyLjRjLTMuMyw1LjktMTAuNyw1LjYtMTAuNyw1LjZzLTExLjYsNS4xLTE1LjgsMTYuOAoJQzI2LjMsNjcuOSwzNiw2Ny45LDM2LDY3Ljl6Ii8+Cjwvc3ZnPgo=')} +.is2d .bishop.black {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojMDEwMTAxO30KCS5zdDJ7ZmlsbDojNkQ2RTZFO30KPC9zdHlsZT4KPHJlY3QgeD0iMCIgeT0iMCIgY2xhc3M9InN0MCIgd2lkdGg9IjgxIiBoZWlnaHQ9IjgxIi8+Cjxwb2x5Z29uIGNsYXNzPSJzdDEiIHBvaW50cz0iMTguOSw3MiA2Mi4xLDcyIDUwLjMsNjIuNSAzMC43LDYyLjUgIi8+CjxnPgoJPHBhdGggY2xhc3M9InN0MSIgZD0iTTQxLDE4LjljMS41LDAsMi45LTAuNSw0LTEuM2wyLjgtNS4yYzAtMC4xLDAtMC4yLDAtMC4zYzAtMy43LTMtNi44LTYuOC02LjhjLTMuNywwLTYuOCwzLTYuOCw2LjgKCQljMCwwLjEsMCwwLjIsMCwwLjNsMi44LDUuMkMzOC4yLDE4LjQsMzkuNiwxOC45LDQxLDE4LjkiLz4KCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik00OC40LDIwLjRsLTkuNywxOC4yTDM3LDMyLjdsOC4xLTE1LjJjLTEtMC44LTItMS41LTMtMi4yaC0zLjFjLTEwLDYuNi0xOS4xLDE3LjUtMTkuMSwzMi4ybDEwLjksMTUuMmgyLjdoMTQKCQloMi43bDEwLjktMTUuMkM2MS4xLDM2LjEsNTUuNiwyNyw0OC40LDIwLjQiLz4KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik00OC42LDI3LjlsLTcuMiwxM2MwLDAsNSwxLjMsNy4yLTEuOUM1MC44LDM1LjksNTAuMiwyOC45LDQ4LjYsMjcuOXoiLz4KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0zMS4yLDU1LjFjLTEuNi0xMy45LDEuNC0yOC4xLDcuOS0zNC44bC0wLjUtMC43Yy03LjEsNi4zLTE0LDE1LjYtMTQsMjYuNkwzMS4yLDU1LjF6Ii8+CjwvZz4KPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSIzNy45LDY5IDM3LjksNjMuMyAzNS40LDYzLjMgMjguOCw2OSAiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTQyLjQsNy45Yy0wLjgtMC41LTEuOC0wLjYtMi43LTAuM2MtMS45LDAuNS0zLDIuNS0yLjUsNC40YzAsMC4xLDAsMC4xLDAuMSwwLjJDNDAuMywxMi40LDQyLjgsOS4zLDQyLjQsNy45eiIKCS8+Cjwvc3ZnPgo=')} +.is2d .rook.black {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojMDEwMTAxO30KCS5zdDJ7ZmlsbDojNkQ2RTZFO30KPC9zdHlsZT4KPHJlY3QgY2xhc3M9InN0MCIgd2lkdGg9IjgxIiBoZWlnaHQ9IjgxIi8+Cjxwb2x5Z29uIGNsYXNzPSJzdDEiIHBvaW50cz0iNTYuOSwzMS4xIDI0LjEsMzEuMSAxOS4yLDcyIDYxLjgsNzIgNjEuOCw3MiAiLz4KPHJlY3QgeD0iMTQuMiIgeT0iNTguNSIgY2xhc3M9InN0MSIgd2lkdGg9IjUyLjUiIGhlaWdodD0iMTMuNSIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNNDEuMSwzNC4xYy0wLjEsNy4yLTYuNiwyNC40LTE0LjIsMjQuNGMtMS4yLDAtMi4zLDAtMi4zLDBsMy44LTI0LjRINDEuMXoiLz4KPHJlY3QgeD0iMTguNCIgeT0iNjIuMyIgY2xhc3M9InN0MiIgd2lkdGg9IjE3LjkiIGhlaWdodD0iNi4xIi8+Cjxwb2x5Z29uIGNsYXNzPSJzdDEiIHBvaW50cz0iNTMuNCwxMiA1My40LDE4LjkgNDYuNSwxOC45IDQ2LjUsMTIgMzQuNSwxMiAzNC41LDE4LjkgMjcuNiwxOC45IDI3LjYsMTIgMTUuNiwxMiAxNS42LDIzLjQgCgkyNC42LDMyLjUgNTYuNCwzMi41IDY1LjQsMjMuNCA2NS40LDIzLjQgNjUuNCwxMiAiLz4KPGc+Cgk8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjYyLjQsMTUgNTYuNCwxNSA1Ni40LDIyLjIgCSIvPgoJPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSI0My41LDE1IDM3LjUsMTUgMzcuNSwyMi4yIAkiLz4KCTxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iMjQuNiwxNSAxOC42LDE1IDE4LjYsMjIuMiAJIi8+CjwvZz4KPC9zdmc+Cg==')} +.is2d .queen.black {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojMDEwMTAxO30KCS5zdDJ7ZmlsbDojNkQ2RTZFO30KPC9zdHlsZT4KPHJlY3QgY2xhc3M9InN0MCIgd2lkdGg9IjgxIiBoZWlnaHQ9IjgxIi8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik01NS43LDUwLjlsNC0zNC45TDQwLjUsNDkuMkwyMS4zLDE2bDQuMSwzNC45TDcuOSwzMC44TDE4LjgsNzJoNDMuNGwxMC45LTQxLjJMNTUuNyw1MC45eiBNNDAuNSw2Ni45bC0zLjYtNi40CglsMy42LTYuNGwzLjYsNi40TDQwLjUsNjYuOXoiLz4KPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSI0MC41LDExLjcgMzQuOSwzNS4yIDQwLjUsNDQuNyA0Ni4xLDM1LjIgIi8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0zMy42LDMzLjYiLz4KPHBhdGggY2xhc3M9InN0MSIgZD0iTTQ3LjQsMzMuNiIvPgo8Y2lyY2xlIGNsYXNzPSJzdDEiIGN4PSI0MC41IiBjeT0iMTAuNiIgcj0iNS40Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik00MS42LDcuMmMtMC44LTAuNC0xLjctMC42LTIuNi0wLjNjLTEuOCwwLjUtMi45LDIuNC0yLjQsNC4yYzAsMC4xLDAsMC4xLDAuMSwwLjJDMzkuNiwxMS42LDQyLDguNSw0MS42LDcuMnoiCgkvPgo8Y2lyY2xlIGNsYXNzPSJzdDEiIGN4PSI1OS41IiBjeT0iMTYiIHI9IjUuNCIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNNjAuNiwxMi42Yy0wLjgtMC40LTEuNy0wLjYtMi42LTAuM2MtMS44LDAuNS0yLjksMi40LTIuNCw0LjJjMCwwLjEsMCwwLjEsMC4xLDAuMgoJQzU4LjYsMTYuOSw2MSwxMy45LDYwLjYsMTIuNnoiLz4KPGNpcmNsZSBjbGFzcz0ic3QxIiBjeD0iMjEuNSIgY3k9IjE2IiByPSI1LjQiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTIyLjYsMTIuNmMtMC44LTAuNC0xLjctMC42LTIuNi0wLjNjLTEuOCwwLjUtMi45LDIuNC0yLjQsNC4yYzAsMC4xLDAsMC4xLDAuMSwwLjIKCUMyMC42LDE2LjksMjMsMTMuOSwyMi42LDEyLjZ6Ii8+CjxjaXJjbGUgY2xhc3M9InN0MSIgY3g9IjczLjEiIGN5PSIzMS40IiByPSI1LjQiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTc0LjIsMjhjLTAuOC0wLjQtMS43LTAuNi0yLjYtMC4zYy0xLjgsMC41LTIuOSwyLjQtMi40LDQuMmMwLDAuMSwwLDAuMSwwLjEsMC4yQzcyLjIsMzIuMyw3NC42LDI5LjMsNzQuMiwyOHoKCSIvPgo8Y2lyY2xlIGNsYXNzPSJzdDEiIGN4PSI3LjkiIGN5PSIzMS40IiByPSI1LjQiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTksMjhjLTAuOC0wLjQtMS43LTAuNi0yLjYtMC4zQzQuNiwyOC4xLDMuNSwzMCw0LDMxLjhjMCwwLjEsMCwwLjEsMC4xLDAuMkM3LDMyLjMsOS40LDI5LjMsOSwyOHoiLz4KPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSI0MC41LDIwLjkgMzcuNCwzNC4zIDQwLjUsMzkuNiAiLz4KPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSI1Ni42LDU0LjcgNTguNCw2MC4zIDY4LDM4LjMgIi8+Cjxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iNDcuOSw1MC41IDU1LjksMjkuMyA0My42LDUwLjEgIi8+Cjxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iMzMuMyw1MC41IDI1LDI5LjEgMjguMSw1MSAiLz4KPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSIyMy4xLDU4LjcgMTIuNiw0MC45IDIwLjUsNjcuMyAiLz4KPC9zdmc+Cg==')} +.is2d .king.black {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojMDEwMTAxO30KCS5zdDJ7ZmlsbDojNkQ2RTZFO30KPC9zdHlsZT4KPHJlY3QgY2xhc3M9InN0MCIgd2lkdGg9IjgxIiBoZWlnaHQ9IjgxIi8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik01OC42LDI1LjVjLTYuMiwwLTkuMywyLjYtMTAuOSw0LjJsLTcuMiwxMi42bC03LjItMTIuNmMtMS42LTEuNi00LjctNC4yLTEwLjktNC4yYy05LjcsMC0xNS4zLDgtMTUuMywxNS44CgljMCw4LjgsMy44LDExLjksOC45LDIyLjNWNzJoMjQuNUg2NXYtOC40YzUuMS0xMC41LDguOS0xMy41LDguOS0yMi4zQzczLjksMzMuNSw2OC4zLDI1LjUsNTguNiwyNS41eiBNNDAuNSw2MS42bC0zLjYtNi40bDMuNi02LjQKCWwzLjYsNi40TDQwLjUsNjEuNnoiLz4KPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSI1MC43LDIxLjQgNTAuNywxMy43IDQyLjcsMTQuNiA0NC40LDcuMiAzNi42LDcuMiAzOC4zLDE0LjYgMzAuMywxMy43IDMwLjMsMjEuNCAzOC4zLDE5IDM1LjIsMjcuOSAKCTQwLjUsMzguOSA0NS44LDI3LjkgNDIuNywxOSAiLz4KPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSI0MC41LDE5LjkgMzcuNiwyNy41IDQwLjUsMzMuOSAiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTIyLjgsMjkuMWMtNy4yLDAtMTEuNyw2LjQtMTEuNywxMi45YzAsNCwyLjksOC4yLDUuOCwxMmMwLTEyLjQsNC42LTE3LjQsMTIuNS0yMi42CglDMjkuNCwzMS40LDI3LjQsMjkuMSwyMi44LDI5LjF6Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik00My41LDQ0bDcuNC0xMi43YzAsMCwzLjYtMi42LDgtMi42czQuNSwwLjUsNC41LDAuNUw0My41LDQ0eiIvPgo8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjMxLjgsMTUuMSAzNS42LDE3LjQgMzEuOCwxOS43ICIvPgo8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjQ5LjIsMTUuMSA0Mi44LDE2LjMgNDcuNSwxNy40ICIvPgo8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjQyLjYsOC45IDQwLjUsMTAuOCAzOC40LDguOSAiLz4KPC9zdmc+Cg==')} diff --git a/public/piece-css/leipzig.css b/public/piece-css/leipzig.css new file mode 100644 index 0000000000..69d8b9040a --- /dev/null +++ b/public/piece-css/leipzig.css @@ -0,0 +1,12 @@ +.is2d .pawn.white {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjUwLjgwMDAwM21tIiBoZWlnaHQ9IjUwLjc3NTE5Mm1tIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1MC44MDAwMDMgNTAuNzc1MTkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02Mi45MzMwMzcsLTI3LjE4NzU5NykiPg0KCQk8ZyBmaWxsPSIjZmZmIj4NCgkJCTxwYXRoIGQ9Im04OC4zMzI1OSA3Mi45MDI4NzJoMTEuNDU5NzY2cS0wLjc0NDE0MS0yLjk1MTc1OC0yLjg1MjUzOS01LjIzMzc4OS0wLjgxODU1NS0wLjk0MjU3OC0xLjUzNzg5MS0xLjU2MjY5NS0yLjM4MTI1LTEuOTM0NzY2LTMuODk0MzM2LTQuNTY0MDYzLTEuNTg3NSAwLjU5NTMxMy0zLjE3NSAwLjU5NTMxMy0xLjYzNzEwOSAwLTMuMTc1LTAuNTk1MzEzLTEuNjEyMzA1IDIuNjc4OTA2LTMuODk0MzM2IDQuNTY0MDYzLTAuNzQ0MTQgMC42MjAxMTctMS41Mzc4OSAxLjU2MjY5NS0yLjEzMzIwMyAyLjI4MjAzMS0yLjg1MjUzOSA1LjIzMzc4OXoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im04OC4zMzI1OSA2MC40NzU3MjRxMi44MDI5MyAwIDQuNzg3MzA1LTEuOTg0Mzc1dDEuOTg0Mzc1LTQuODEyMTFxMC0yLjMwNjgzNi0xLjQzODY3Mi00LjE0MjM4Mi0xLjY2MTkxNC0yLjEzMzIwNC0yLjU1NDg4My00LjUxNDQ1NC0xLjQ4ODI4MS0wLjE5ODQzNy0yLjc3ODEyNS0wLjE5ODQzNy0xLjM2NDI1OCAwLTIuNzc4MTI1IDAuMTk4NDM3LTEuMDE2OTkyIDIuNTMwMDc5LTIuNTc5Njg3IDQuNTE0NDU0LTEuNDM4NjcyIDEuODM1NTQ2LTEuNDM4NjcyIDQuMTQyMzgyIDAgMi44Mjc3MzUgMS45ODQzNzUgNC44MTIxMXQ0LjgxMjEwOSAxLjk4NDM3NXoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im04OC4zMzI1OSAzNy4yODMzNDFxMi41MzAwNzggMCAyLjUzMDA3OC0yLjUzMDA3OHQtMi41MzAwNzgtMi41MzAwNzgtMi41MzAwNzggMi41MzAwNzggMi41MzAwNzggMi41MzAwNzh6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtODguMzMyNTkgNDMuMTM3MjQ3cTEuODg1MTU2IDAgMy4zNDg2MzMgMC40NzEyODktMC41NzA1MDgtMS4wNDE3OTctMS4xOTA2MjUtMi4zMDY4MzYtMC41OTUzMTMtMS4yODk4NDMtMC43Njg5NDUtMi41NTQ4ODItMC42OTQ1MzIgMC4xOTg0MzctMS4zODkwNjMgMC4xOTg0MzctMC43NDQxNDEgMC0xLjQxMzg2Ny0wLjE5ODQzNy0wLjE5ODQzOCAxLjI2NTAzOS0wLjc5Mzc1IDIuNTU0ODgyLTAuNTk1MzEzIDEuMjY1MDM5LTEuMTQxMDE2IDIuMzA2ODM2IDEuOTU5NTcxLTAuNDcxMjg5IDMuMzQ4NjMzLTAuNDcxMjg5eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTg4LjMzMjU5IDc0LjU2NDc4NmgtMTMuNTE4NTU0cTAuNDcxMjg5LTUuMzMzMDA4IDQuNTM5MjU3LTkuMDA0MTAyIDAuNjY5NzI3LTAuNjIwMTE3IDAuNzQ0MTQxLTAuNjY5NzI2IDIuMTA4Mzk4LTEuNzM2MzI4IDMuNTk2NjgtNC4xNDIzODMtMy44MTk5MjItMi41MDUyNzMtMy44MTk5MjItNy4wNjkzMzYgMC0yLjgyNzczNCAxLjcxMTUyMy01LjA4NDk2MSAwLjU3MDUwOC0wLjcxOTMzNiAxLjIxNTQzLTEuNjM3MTA5IDAuNjY5NzI2LTAuOTE3NzczIDEuMDY2NjAxLTEuNzg1OTM3LTAuNTk1MzEyIDAuMTQ4ODI4LTEuODEwNzQyIDAuNDcxMjg5LTEuMTkwNjI1IDAuMzIyNDYxLTEuNzYxMTMzIDAuNTQ1NzAzIDEuNzExNTI0LTEuNTg3NSAzLjI0OTQxNC0zLjc3MDMxMyAxLjU2MjY5Ni0yLjE4MjgxMiAxLjgzNTU0Ny00LjYzODQ3Ni0xLjI2NTAzOS0xLjI4OTg0NC0xLjI2NTAzOS0zLjAyNjE3MnQxLjIxNTQzLTIuOTc2NTYycTEuMjQwMjM0LTEuMjQwMjM1IDMuMDAxMzY3LTEuMjQwMjM1IDEuNzExNTI0IDAgMi45NTE3NTggMS4yNDAyMzUgMS4yNDAyMzQgMS4yNDAyMzQgMS4yNDAyMzQgMi45NzY1NjIgMCAxLjc2MTEzMy0xLjI2NTAzOSAzLjAyNjE3MiAwLjI3Mjg1MiAyLjQ1NTY2NCAxLjgzNTU0NyA0LjYzODQ3NiAxLjU4NzUgMi4xODI4MTMgMy4yOTkwMjMgMy43NzAzMTMtMC41NzA1MDctMC4yMjMyNDItMS44MTA3NDItMC41NDU3MDMtMS4yMTU0MjktMC4zMjI0NjEtMS44MTA3NDItMC40NzEyODkgMC4zOTY4NzUgMC44NjgxNjQgMS4wNDE3OTcgMS43ODU5MzcgMC42Njk3MjcgMC45MTc3NzMgMS4yNjUwMzkgMS42MzcxMDkgMS43MTE1MjMgMi4yNTcyMjcgMS43MTE1MjMgNS4wODQ5NjEgMCA0LjU2NDA2My0zLjgxOTkyMSA3LjA2OTMzNiAxLjQxMzg2NyAyLjM4MTI1IDMuNTcxODc1IDQuMTQyMzgzIDAuMzcyMDcgMC4yOTc2NTYgMC43NDQxNCAwLjY2OTcyNiA0LjA5Mjc3OCAzLjY3MTA5NCA0LjUzOTI1OCA5LjAwNDEwMnoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJPC9nPg0KCQk8ZyBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIiBhcmlhLWxhYmVsPSJwIj4NCgkJCTxwYXRoIGQ9Im04OC4zMzI1OSA3Mi45MDI4NzJoMTEuNDU5NzY2cS0wLjc0NDE0MS0yLjk1MTc1OC0yLjg1MjUzOS01LjIzMzc4OS0wLjgxODU1NS0wLjk0MjU3OC0xLjUzNzg5MS0xLjU2MjY5NS0yLjM4MTI1LTEuOTM0NzY2LTMuODk0MzM2LTQuNTY0MDYzLTEuNTg3NSAwLjU5NTMxMy0zLjE3NSAwLjU5NTMxMy0xLjYzNzEwOSAwLTMuMTc1LTAuNTk1MzEzLTEuNjEyMzA1IDIuNjc4OTA2LTMuODk0MzM2IDQuNTY0MDYzLTAuNzQ0MTQgMC42MjAxMTctMS41Mzc4OSAxLjU2MjY5NS0yLjEzMzIwMyAyLjI4MjAzMS0yLjg1MjUzOSA1LjIzMzc4OXptMC0xMi40MjcxNDhxMi44MDI5MyAwIDQuNzg3MzA1LTEuOTg0Mzc1dDEuOTg0Mzc1LTQuODEyMTFxMC0yLjMwNjgzNi0xLjQzODY3Mi00LjE0MjM4Mi0xLjY2MTkxNC0yLjEzMzIwNC0yLjU1NDg4My00LjUxNDQ1NC0xLjQ4ODI4MS0wLjE5ODQzNy0yLjc3ODEyNS0wLjE5ODQzNy0xLjM2NDI1OCAwLTIuNzc4MTI1IDAuMTk4NDM3LTEuMDE2OTkyIDIuNTMwMDc5LTIuNTc5Njg3IDQuNTE0NDU0LTEuNDM4NjcyIDEuODM1NTQ2LTEuNDM4NjcyIDQuMTQyMzgyIDAgMi44Mjc3MzUgMS45ODQzNzUgNC44MTIxMXQ0LjgxMjEwOSAxLjk4NDM3NXptMC0yMy4xOTIzODNxMi41MzAwNzggMCAyLjUzMDA3OC0yLjUzMDA3OHQtMi41MzAwNzgtMi41MzAwNzgtMi41MzAwNzggMi41MzAwNzggMi41MzAwNzggMi41MzAwNzh6bTAgNS44NTM5MDZxMS44ODUxNTYgMCAzLjM0ODYzMyAwLjQ3MTI4OS0wLjU3MDUwOC0xLjA0MTc5Ny0xLjE5MDYyNS0yLjMwNjgzNi0wLjU5NTMxMy0xLjI4OTg0My0wLjc2ODk0NS0yLjU1NDg4Mi0wLjY5NDUzMiAwLjE5ODQzNy0xLjM4OTA2MyAwLjE5ODQzNy0wLjc0NDE0MSAwLTEuNDEzODY3LTAuMTk4NDM3LTAuMTk4NDM4IDEuMjY1MDM5LTAuNzkzNzUgMi41NTQ4ODItMC41OTUzMTMgMS4yNjUwMzktMS4xNDEwMTYgMi4zMDY4MzYgMS45NTk1NzEtMC40NzEyODkgMy4zNDg2MzMtMC40NzEyODl6bTAgMzEuNDI3NTM5aC0xMy41MTg1NTRxMC40NzEyODktNS4zMzMwMDggNC41MzkyNTctOS4wMDQxMDIgMC42Njk3MjctMC42MjAxMTcgMC43NDQxNDEtMC42Njk3MjYgMi4xMDgzOTgtMS43MzYzMjggMy41OTY2OC00LjE0MjM4My0zLjgxOTkyMi0yLjUwNTI3My0zLjgxOTkyMi03LjA2OTMzNiAwLTIuODI3NzM0IDEuNzExNTIzLTUuMDg0OTYxIDAuNTcwNTA4LTAuNzE5MzM2IDEuMjE1NDMtMS42MzcxMDkgMC42Njk3MjYtMC45MTc3NzMgMS4wNjY2MDEtMS43ODU5MzctMC41OTUzMTIgMC4xNDg4MjgtMS44MTA3NDIgMC40NzEyODktMS4xOTA2MjUgMC4zMjI0NjEtMS43NjExMzMgMC41NDU3MDMgMS43MTE1MjQtMS41ODc1IDMuMjQ5NDE0LTMuNzcwMzEzIDEuNTYyNjk2LTIuMTgyODEyIDEuODM1NTQ3LTQuNjM4NDc2LTEuMjY1MDM5LTEuMjg5ODQ0LTEuMjY1MDM5LTMuMDI2MTcydDEuMjE1NDMtMi45NzY1NjJxMS4yNDAyMzQtMS4yNDAyMzUgMy4wMDEzNjctMS4yNDAyMzUgMS43MTE1MjQgMCAyLjk1MTc1OCAxLjI0MDIzNSAxLjI0MDIzNCAxLjI0MDIzNCAxLjI0MDIzNCAyLjk3NjU2MiAwIDEuNzYxMTMzLTEuMjY1MDM5IDMuMDI2MTcyIDAuMjcyODUyIDIuNDU1NjY0IDEuODM1NTQ3IDQuNjM4NDc2IDEuNTg3NSAyLjE4MjgxMyAzLjI5OTAyMyAzLjc3MDMxMy0wLjU3MDUwNy0wLjIyMzI0Mi0xLjgxMDc0Mi0wLjU0NTcwMy0xLjIxNTQyOS0wLjMyMjQ2MS0xLjgxMDc0Mi0wLjQ3MTI4OSAwLjM5Njg3NSAwLjg2ODE2NCAxLjA0MTc5NyAxLjc4NTkzNyAwLjY2OTcyNyAwLjkxNzc3MyAxLjI2NTAzOSAxLjYzNzEwOSAxLjcxMTUyMyAyLjI1NzIyNyAxLjcxMTUyMyA1LjA4NDk2MSAwIDQuNTY0MDYzLTMuODE5OTIxIDcuMDY5MzM2IDEuNDEzODY3IDIuMzgxMjUgMy41NzE4NzUgNC4xNDIzODMgMC4zNzIwNyAwLjI5NzY1NiAwLjc0NDE0IDAuNjY5NzI2IDQuMDkyNzc4IDMuNjcxMDk0IDQuNTM5MjU4IDkuMDA0MTAyeiIgc3Ryb2tlLXdpZHRoPSIuMjY0NTgzMzIiLz4NCgkJPC9nPg0KCTwvZz4NCjwvc3ZnPg0K')} +.is2d .knight.white {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjUwLjgwMDAwN21tIiBoZWlnaHQ9IjUwLjc3NTE5Mm1tIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1MC44MDAwMDcgNTAuNzc1MTkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC04My44NTU4MTIsLTkyLjgxMjA4NikiPg0KCQk8ZyBmaWxsPSIjZmZmIj4NCgkJCTxwYXRoIGQ9Im05My44MDI3ODIgMTIyLjUwMjkzcS0wLjE5ODQzOCAwLjI0ODA1LTAuNTIwODk5IDAuNDcxMjktMC42OTQ1MzEgMC41MjA5LTAuOTkyMTg3LTAuMDk5Mi0wLjE3MzYzMy0wLjI5NzY2IDAuMDI0OC0wLjkxNzc3IDAuMzQ3MjY2LTAuMjk3NjYgMC40NzEyODktMC4zOTY4OCAwLjc2ODk0Ni0wLjkxNzc3IDEuMjY1MDM5LTEuNjEyMyAwLjI0ODA0Ny0wLjA0OTYgMC4zNzIwNzEtMC4wMjQ4IDAuODY4MTY0IDAuMTQ4ODMgMC40NDY0ODQgMS4wNjY2LTAuMjIzMjQyIDAuNDQ2NDktMC41NDU3MDMgMC44MTg1Ni0wLjI5NzY1NiAwLjM0NzI2LTAuNTIwODk4IDAuNjk0NTN6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtMTAxLjE0NDk3IDExMS40ODk2NXEwLjQ5NjA5LTEuNTM3ODkgMS44ODUxNi0xLjY2MTkyIDAuOTQyNTctMC4wNzQ0IDEuNjM3MS0wLjA3NDQgMC42OTQ1NCAwIDEuNDg4MjktMC4yNDgwNS0wLjc5Mzc1IDIuMjMyNDMtMS44MTA3NSAyLjkwMjE1LTAuNTQ1NyAwLjMyMjQ2LTEuNTEzMDggMC4zOTY4OC0wLjcxOTM0IDAuMDQ5Ni0xLjExNjIxLTAuMDk5Mi0wLjM5Njg4LTAuMTQ4ODMtMC41NzA1MS0xLjIxNTQzeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTk5LjUwNzg2IDEyNC42ODU3NHExLjE5MDYyLTAuODQzMzYgMS42ODY3Mi0xLjc2MTEzIDAuNTIwOS0wLjk0MjU4IDEuNDEzODctMS43ODU5NCAwLjAyNDgtMC4yOTc2NSAwLjA3NDQtMC42Njk3MnQwLjA5OTItMC43OTM3NXEwLjE3MzYzLTAuMTczNjQgMC4yNzI4NS0wLjE5ODQ0IDAuNzE5MzQtMC4yMjMyNCAwLjg0MzM2IDAuNjQ0OTIgMCAwLjI0ODA1LTAuMDQ5NiAwLjQ5NjA5LTAuMDI0OCAwLjIyMzI1IDAuMDI0OCAwLjM5Njg4IDAuMTQ4ODMgMC4xNzM2MyAxLjExNjIyIDAuMzcyMDcgMy41NzE4NyAwLjEyNDAyIDYuNTczMjQtMi42Nzg5MSAwLTAuMDI0OCAwLjE0ODgzLTAuMjIzMjQgMC4xNzM2My0wLjE5ODQ0IDAuMTk4NDMtMC4yNDgwNSAwLjc0NDE0LTEuMTE2MjEgMS4xOTA2My00LjYzODQ3IDAuMDQ5Ni0wLjA5OTIgMC4yNzI4NS0wLjIyMzI0IDAuNjQ0OTItMC4yMjMyNSAwLjgxODU1IDAuNjQ0OTItMC4yMjMyNCAzLjE5OTgtMC45NjczOCA0LjU2NDA2LTAuMzk2ODcgMC43MTkzNC0wLjg5Mjk3IDEuMjY1MDQgMC40MjE2OC0wLjIyMzI0IDAuODQzMzYtMC40MjE2OHQwLjgxODU2LTAuNDQ2NDlxMS4yNjUwNC0wLjc2ODk0IDEuODEwNzQtMi45NzY1NiAwLjI3Mjg1LTAuNDcxMjkgMC43OTM3NS0wLjQyMTY4IDAuNTQ1NyAwLjA5OTIgMC40MjE2OCAwLjgxODU2LTAuNTcwNTEgMy4xMDA1OC0yLjQzMDg2IDQuMDE4MzYtMC41OTUzMSAwLjI5NzY1LTEuMjE1NDMgMC41NDU3LTAuNTk1MzEgMC4yMjMyNC0xLjE2NTgyIDAuNDQ2NDggMS40NjM0OC0wLjA3NDQgMy4xNzUtMC40NzEyOSAwLjMyMjQ2IDAgMC40NDY0OCAwLjI3Mjg2IDAuMjIzMjUgMC40OTYwOS0wLjQ3MTI5IDAuODkyOTctMy40OTc0NiAwLjk2NzM4LTQuNDQwMDMgMC44NjgxNi0wLjY2OTczIDIuMTA4NC0zLjI3NDIyIDQuNjM4NDgtMS40Mzg2NyAxLjM4OTA2LTIuOTc2NTcgMi43MDM3MS0xLjUzNzg5IDEuMjg5ODQtMy4wMjYxNyAyLjU3OTY4LTMuMjk5MDIxIDIuOTAyMTUtNC4wMTgzNTcgNS42NTU0NyA1LjY4MDI3NyAwLjAyNDggOS40MjU3NzcgMC4wMjQ4IDMuNzcwMzIgMCA2LjkyMDUxIDAgMy4xNTAyIDAgNi4zNSAwIDMuMTk5ODEtMC4wMjQ4IDcuNzg4NjctMC4wMjQ4IDAuMzQ3MjcgMCAwLjI3Mjg2LTEuMjQwMjMtMC4wNDk2LTEuMjQwMjQtMC4xNzM2NC0yLjMwNjg0LTEuMzM5NDUgMC4xNDg4My0yLjUzMDA4LTEuMzg5MDYtMS4xOTA2Mi0xLjU2MjctMS4wOTE0LTMuNTcxODggMC4wMjQ4LTUuMjA4OTgtMC42Njk3My05LjM3NjE3LTAuNjY5NzItNC4xOTE5OS0yLjY3ODktNy4yNjc3Ny0zLjI3NDIyLTQuOTYwOTQtMTAuMzkzMTctOC40MzM1OS0wLjA5OTIgMC42MjAxMS0wLjIyMzI0IDEuMTQxMDEtMC4xOTg0NCAwLjc5Mzc1LTAuNzQ0MTQgMC41MjA5LTAuNTIwOS0wLjE3MzYzLTAuNTQ1Ny0wLjY2OTczIDAuMDk5Mi0wLjQ0NjQ4IDAuMTI0MDItMC42Njk3Mi0wLjAyNDgtMC4wNzQ0LTAuMDQ5Ni0wLjE3MzY0LTAuMDI0OC0wLjEyNDAyLTAuMDI0OC0wLjIyMzI0LTAuMjQ4MDUtMS4yODk4NC0xLjQxMzg3LTIuOTI2OTUtMC4xOTg0NCAxLjA0MTgtMC4zOTY4OCAxLjQxMzg3LTAuMTk4NDMgMC4zNzIwNy0wLjM0NzI2IDAuNjQ0OTItMC4yNzI4NSAwLjM5Njg3LTAuNDk2MSAwLjc2ODk0LTAuMTk4NDMgMC4zNzIwNy0wLjQ3MTI5IDAuODE4NTYtMC4yNzI4NS0wLjI5NzY2LTAuNTk1MzEtMC42OTQ1My0wLjI5NzY1LTAuNDIxNjgtMC41NDU3LTAuNzE5MzQtMC4yMjMyNC0wLjIyMzI0LTAuNDQ2NDktMC40MjE2OC0wLjE5ODQzLTAuMjIzMjQtMC43OTM3NS0wLjM3MjA3IDAuNTIwOSAxLjkzNDc3LTAuMjcyODUgMi42NTQxLTAuMzk2ODcgMC4zOTY4OC0wLjg2ODE2IDEuMDY2Ni0wLjQ3MTI5IDAuNjQ0OTMtMS4wNjY2IDEuMTkwNjMtMC4zNDcyNyAwLjM3MjA3LTAuODY4MTcgMC44NjgxNi0wLjQ5NjA5IDAuNDcxMjktMC44NDMzNTYgMS4yNDAyNC0wLjQ3MTI4OSAxLjQzODY3LTEuODYwMzUyIDIuOTAyMTUtMS4zNjQyNTcgMS40Mzg2Ny0zLjAwMTM2NyAyLjkwMjE0LTMuNTcxODc1IDMuMTc1LTQuMDQzMTY0IDQuNjEzNjgtMC42NDQ5MjIgMS43MzYzMiAwLjA3NDQxIDMuMzczNDMgMC42Njk3MjcgMS40NjM0OCAxLjgzNTU0NyAxLjkwOTk2IDAuNjk0NTMxIDAuMjcyODYgMS43MTE1MjQtMS4wNDE3OSAxLjA5MTQwNi0xLjMxNDY1IDEuNDM4NjcxLTEuMjE1NDMgMC42NDQ5MjIgMC4xNzM2MyAwLjQyMTY4IDAuOTE3NzctMC4xMjQwMjMgMC40MjE2OC0wLjc5Mzc1IDEuMjE1NDMtMC42OTQ1MzEgMC43Njg5NS0wLjcxOTMzNiAxLjAxNjk5LTAuMTI0MDIzIDAuMjk3NjYgMC40OTYwOTQgMC40NzEyOSAwLjc2ODk0NSAwLjE5ODQ0IDIuODc3MzQ0LTEuODYwMzUgMC4yNDgwNDctMC4yNDgwNSAwLjUyMDg5OC0wLjQ0NjQ4IDAuMjk3NjU2LTAuMjIzMjUgMC41OTUzMTMtMC40OTYxeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwMC4zMjY0MSAxMjUuODc2MzdxLTAuMzQ3MjYxIDAuMzcyMDctMC41NzA1MDQgMC41NDU3LTAuMTk4NDM3IDAuMTQ4ODMtMC4zNzIwNyAwLjI5NzY2LTAuMjIzMjQyIDAuMTk4NDMtMS41ODc1IDEuNjM3MTEtMC41NzA1MDggMC41OTUzMS0xLjM2NDI1OCAwLjc5Mzc1LTAuNTcwNTA3IDAuMTQ4ODItMS40NjM0NzYtMC4xMjQwMy0zLjEwMDU4Ni0wLjgxODU1LTQuODg2NTI0LTMuMjc0MjItMC43MTkzMzUtMC45MTc3Ny0xLjAxNjk5Mi0yLjIwNzYxLTAuMjcyODUxLTEuMzE0NjUgMC4yOTc2NTctMy4zMjM4MyAwLjU0NTcwMy0yLjA1ODc5IDMuOTE5MTQtNC42Mzg0OCAzLjY5NTg5OC0yLjgwMjkzIDQuMzY1NjI1LTQuNDg5NjUgMC41NDU3MDMtMC45NjczOCAxLjI0MDIzNC0yLjEzMzIgMC42OTQ1MzItMS4xNjU4MiAxLjY2MTkxOC0yLjI1NzIzIDAuNTk1MzEtMC40MjE2OCAxLjExNjIxLTAuOTY3MzggMC41NDU3LTAuNTcwNTEgMS4wOTE0LTEuMTY1ODJ2LTMuMDUwOThxMS4zODkwNyAwLjI3Mjg2IDEuOTg0MzggMC43OTM3NSAwLjI5NzY1IDAuMzIyNDcgMC42Njk3MyAwLjU5NTMyIDAuMzcyMDcgMC4yNzI4NSAwLjY2OTcyIDAuNTk1MzEgMC42MjAxMi0xLjExNjIxIDAuNzkzNzUtMS44NjAzNSAwLjAyNDgtMC4xNzM2MyAwLjE0ODgzLTAuNjk0NTMgMC4xNDg4My0wLjUyMDkgMC4yOTc2Ni0xLjcxMTUyNyAwLjM3MjA3LTAuMDc0NDEgMC42NDQ5MiAwLjE5ODQzOCAxLjE2NTgyIDEuMjY1MDM5IDIuMTgyODEgMi44NzczMzkgNC41MzkyNiAxLjgxMDc1IDguMjg0NzcgNC4yOTEyMiAzLjc3MDMxIDIuNDgwNDYgNS43NTQ2OCA1LjE1OTM3IDUuNzA1MDggNy43MzkwNiA1LjcwNTA4IDIyLjcyMTA5IDAgMy4xNTAyLTAuMzIyNDYgNS43NTQ2OWgtMzMuODU4Mzk4cS0wLjMyMjQ2LTMuMjI0NjEgMy40MjMwNDctNi44NDYwOSAxLjY4NjcyMS0xLjYzNzExIDMuNDk3NDYxLTMuMTc1IDEuODM1NTUtMS41Mzc4OSAzLjU3MTg4LTMuMTI1MzkgMy4yMjQ2LTIuOTc2NTcgMy41NzE4Ny00Ljc2MjUtMC4xMjQwMi0wLjI5NzY2LTAuNDcxMjktMC4zOTY4OC0wLjg2ODE2IDAuNTIwOS0xLjczNjMzIDAuNjY5NzMtMC44NjgxNiAwLjE0ODgzLTEuNzExNTIgMC4xOTg0NC0wLjU0NTcgMC4wMjQ4LTEuMDkxNDEgMC4wNDk2LTAuNTIwOSAwLTEuMjQwMjMtMC4yNDgwNS0wLjk2NzM4IDEuMDkxNC0xLjY2MTkyIDEuODg1MTUtMC42Njk3MiAwLjc2ODk1LTEuNTM3ODkgMS4zODkwN3oiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJPC9nPg0KCQk8ZyBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIiBhcmlhLWxhYmVsPSJuIj4NCgkJCTxwYXRoIGQ9Im05My44MDI3ODIgMTIyLjUwMjkzcS0wLjE5ODQzOCAwLjI0ODA1LTAuNTIwODk5IDAuNDcxMjktMC42OTQ1MzEgMC41MjA5LTAuOTkyMTg3LTAuMDk5Mi0wLjE3MzYzMy0wLjI5NzY2IDAuMDI0OC0wLjkxNzc3IDAuMzQ3MjY2LTAuMjk3NjYgMC40NzEyODktMC4zOTY4OCAwLjc2ODk0Ni0wLjkxNzc3IDEuMjY1MDM5LTEuNjEyMyAwLjI0ODA0Ny0wLjA0OTYgMC4zNzIwNzEtMC4wMjQ4IDAuODY4MTY0IDAuMTQ4ODMgMC40NDY0ODQgMS4wNjY2LTAuMjIzMjQyIDAuNDQ2NDktMC41NDU3MDMgMC44MTg1Ni0wLjI5NzY1NiAwLjM0NzI2LTAuNTIwODk4IDAuNjk0NTN6bTcuMzQyMTg4LTExLjAxMzI4cTAuNDk2MDktMS41Mzc4OSAxLjg4NTE2LTEuNjYxOTIgMC45NDI1Ny0wLjA3NDQgMS42MzcxLTAuMDc0NCAwLjY5NDU0IDAgMS40ODgyOS0wLjI0ODA1LTAuNzkzNzUgMi4yMzI0My0xLjgxMDc1IDIuOTAyMTUtMC41NDU3IDAuMzIyNDYtMS41MTMwOCAwLjM5Njg4LTAuNzE5MzQgMC4wNDk2LTEuMTE2MjEtMC4wOTkyLTAuMzk2ODgtMC4xNDg4My0wLjU3MDUxLTEuMjE1NDN6bS0xLjYzNzExIDEzLjE5NjA5cTEuMTkwNjItMC44NDMzNiAxLjY4NjcyLTEuNzYxMTMgMC41MjA5LTAuOTQyNTggMS40MTM4Ny0xLjc4NTk0IDAuMDI0OC0wLjI5NzY1IDAuMDc0NC0wLjY2OTcydDAuMDk5Mi0wLjc5Mzc1cTAuMTczNjMtMC4xNzM2NCAwLjI3Mjg1LTAuMTk4NDQgMC43MTkzNC0wLjIyMzI0IDAuODQzMzYgMC42NDQ5MiAwIDAuMjQ4MDUtMC4wNDk2IDAuNDk2MDktMC4wMjQ4IDAuMjIzMjUgMC4wMjQ4IDAuMzk2ODggMC4xNDg4MyAwLjE3MzYzIDEuMTE2MjIgMC4zNzIwNyAzLjU3MTg3IDAuMTI0MDIgNi41NzMyNC0yLjY3ODkxIDAtMC4wMjQ4IDAuMTQ4ODMtMC4yMjMyNCAwLjE3MzYzLTAuMTk4NDQgMC4xOTg0My0wLjI0ODA1IDAuNzQ0MTQtMS4xMTYyMSAxLjE5MDYzLTQuNjM4NDcgMC4wNDk2LTAuMDk5MiAwLjI3Mjg1LTAuMjIzMjQgMC42NDQ5Mi0wLjIyMzI1IDAuODE4NTUgMC42NDQ5Mi0wLjIyMzI0IDMuMTk5OC0wLjk2NzM4IDQuNTY0MDYtMC4zOTY4NyAwLjcxOTM0LTAuODkyOTcgMS4yNjUwNCAwLjQyMTY4LTAuMjIzMjQgMC44NDMzNi0wLjQyMTY4dDAuODE4NTYtMC40NDY0OXExLjI2NTA0LTAuNzY4OTQgMS44MTA3NC0yLjk3NjU2IDAuMjcyODUtMC40NzEyOSAwLjc5Mzc1LTAuNDIxNjggMC41NDU3IDAuMDk5MiAwLjQyMTY4IDAuODE4NTYtMC41NzA1MSAzLjEwMDU4LTIuNDMwODYgNC4wMTgzNi0wLjU5NTMxIDAuMjk3NjUtMS4yMTU0MyAwLjU0NTctMC41OTUzMSAwLjIyMzI0LTEuMTY1ODIgMC40NDY0OCAxLjQ2MzQ4LTAuMDc0NCAzLjE3NS0wLjQ3MTI5IDAuMzIyNDYgMCAwLjQ0NjQ4IDAuMjcyODYgMC4yMjMyNSAwLjQ5NjA5LTAuNDcxMjkgMC44OTI5Ny0zLjQ5NzQ2IDAuOTY3MzgtNC40NDAwMyAwLjg2ODE2LTAuNjY5NzMgMi4xMDg0LTMuMjc0MjIgNC42Mzg0OC0xLjQzODY3IDEuMzg5MDYtMi45NzY1NyAyLjcwMzcxLTEuNTM3ODkgMS4yODk4NC0zLjAyNjE3IDIuNTc5NjgtMy4yOTkwMjEgMi45MDIxNS00LjAxODM1NyA1LjY1NTQ3IDUuNjgwMjc3IDAuMDI0OCA5LjQyNTc3NyAwLjAyNDggMy43NzAzMiAwIDYuOTIwNTEgMCAzLjE1MDIgMCA2LjM1IDAgMy4xOTk4MS0wLjAyNDggNy43ODg2Ny0wLjAyNDggMC4zNDcyNyAwIDAuMjcyODYtMS4yNDAyMy0wLjA0OTYtMS4yNDAyNC0wLjE3MzY0LTIuMzA2ODQtMS4zMzk0NSAwLjE0ODgzLTIuNTMwMDgtMS4zODkwNi0xLjE5MDYyLTEuNTYyNy0xLjA5MTQtMy41NzE4OCAwLjAyNDgtNS4yMDg5OC0wLjY2OTczLTkuMzc2MTctMC42Njk3Mi00LjE5MTk5LTIuNjc4OS03LjI2Nzc3LTMuMjc0MjItNC45NjA5NC0xMC4zOTMxNy04LjQzMzU5LTAuMDk5MiAwLjYyMDExLTAuMjIzMjQgMS4xNDEwMS0wLjE5ODQ0IDAuNzkzNzUtMC43NDQxNCAwLjUyMDktMC41MjA5LTAuMTczNjMtMC41NDU3LTAuNjY5NzMgMC4wOTkyLTAuNDQ2NDggMC4xMjQwMi0wLjY2OTcyLTAuMDI0OC0wLjA3NDQtMC4wNDk2LTAuMTczNjQtMC4wMjQ4LTAuMTI0MDItMC4wMjQ4LTAuMjIzMjQtMC4yNDgwNS0xLjI4OTg0LTEuNDEzODctMi45MjY5NS0wLjE5ODQ0IDEuMDQxOC0wLjM5Njg4IDEuNDEzODctMC4xOTg0MyAwLjM3MjA3LTAuMzQ3MjYgMC42NDQ5Mi0wLjI3Mjg1IDAuMzk2ODctMC40OTYxIDAuNzY4OTQtMC4xOTg0MyAwLjM3MjA3LTAuNDcxMjkgMC44MTg1Ni0wLjI3Mjg1LTAuMjk3NjYtMC41OTUzMS0wLjY5NDUzLTAuMjk3NjUtMC40MjE2OC0wLjU0NTctMC43MTkzNC0wLjIyMzI0LTAuMjIzMjQtMC40NDY0OS0wLjQyMTY4LTAuMTk4NDMtMC4yMjMyNC0wLjc5Mzc1LTAuMzcyMDcgMC41MjA5IDEuOTM0NzctMC4yNzI4NSAyLjY1NDEtMC4zOTY4NyAwLjM5Njg4LTAuODY4MTYgMS4wNjY2LTAuNDcxMjkgMC42NDQ5My0xLjA2NjYgMS4xOTA2My0wLjM0NzI3IDAuMzcyMDctMC44NjgxNyAwLjg2ODE2LTAuNDk2MDkgMC40NzEyOS0wLjg0MzM1NiAxLjI0MDI0LTAuNDcxMjg5IDEuNDM4NjctMS44NjAzNTIgMi45MDIxNS0xLjM2NDI1NyAxLjQzODY3LTMuMDAxMzY3IDIuOTAyMTQtMy41NzE4NzUgMy4xNzUtNC4wNDMxNjQgNC42MTM2OC0wLjY0NDkyMiAxLjczNjMyIDAuMDc0NDEgMy4zNzM0MyAwLjY2OTcyNyAxLjQ2MzQ4IDEuODM1NTQ3IDEuOTA5OTYgMC42OTQ1MzEgMC4yNzI4NiAxLjcxMTUyNC0xLjA0MTc5IDEuMDkxNDA2LTEuMzE0NjUgMS40Mzg2NzEtMS4yMTU0MyAwLjY0NDkyMiAwLjE3MzYzIDAuNDIxNjggMC45MTc3Ny0wLjEyNDAyMyAwLjQyMTY4LTAuNzkzNzUgMS4yMTU0My0wLjY5NDUzMSAwLjc2ODk1LTAuNzE5MzM2IDEuMDE2OTktMC4xMjQwMjMgMC4yOTc2NiAwLjQ5NjA5NCAwLjQ3MTI5IDAuNzY4OTQ1IDAuMTk4NDQgMi44NzczNDQtMS44NjAzNSAwLjI0ODA0Ny0wLjI0ODA1IDAuNTIwODk4LTAuNDQ2NDggMC4yOTc2NTYtMC4yMjMyNSAwLjU5NTMxMy0wLjQ5NjF6bTAuODE4NTUgMS4xOTA2M3EtMC4zNDcyNjEgMC4zNzIwNy0wLjU3MDUwNCAwLjU0NTctMC4xOTg0MzcgMC4xNDg4My0wLjM3MjA3IDAuMjk3NjYtMC4yMjMyNDIgMC4xOTg0My0xLjU4NzUgMS42MzcxMS0wLjU3MDUwOCAwLjU5NTMxLTEuMzY0MjU4IDAuNzkzNzUtMC41NzA1MDcgMC4xNDg4Mi0xLjQ2MzQ3Ni0wLjEyNDAzLTMuMTAwNTg2LTAuODE4NTUtNC44ODY1MjQtMy4yNzQyMi0wLjcxOTMzNS0wLjkxNzc3LTEuMDE2OTkyLTIuMjA3NjEtMC4yNzI4NTEtMS4zMTQ2NSAwLjI5NzY1Ny0zLjMyMzgzIDAuNTQ1NzAzLTIuMDU4NzkgMy45MTkxNC00LjYzODQ4IDMuNjk1ODk4LTIuODAyOTMgNC4zNjU2MjUtNC40ODk2NSAwLjU0NTcwMy0wLjk2NzM4IDEuMjQwMjM0LTIuMTMzMiAwLjY5NDUzMi0xLjE2NTgyIDEuNjYxOTE4LTIuMjU3MjMgMC41OTUzMS0wLjQyMTY4IDEuMTE2MjEtMC45NjczOCAwLjU0NTctMC41NzA1MSAxLjA5MTQtMS4xNjU4MnYtMy4wNTA5OHExLjM4OTA3IDAuMjcyODYgMS45ODQzOCAwLjc5Mzc1IDAuMjk3NjUgMC4zMjI0NyAwLjY2OTczIDAuNTk1MzIgMC4zNzIwNyAwLjI3Mjg1IDAuNjY5NzIgMC41OTUzMSAwLjYyMDEyLTEuMTE2MjEgMC43OTM3NS0xLjg2MDM1IDAuMDI0OC0wLjE3MzYzIDAuMTQ4ODMtMC42OTQ1MyAwLjE0ODgzLTAuNTIwOSAwLjI5NzY2LTEuNzExNTI3IDAuMzcyMDctMC4wNzQ0MSAwLjY0NDkyIDAuMTk4NDM4IDEuMTY1ODIgMS4yNjUwMzkgMi4xODI4MSAyLjg3NzMzOSA0LjUzOTI2IDEuODEwNzUgOC4yODQ3NyA0LjI5MTIyIDMuNzcwMzEgMi40ODA0NiA1Ljc1NDY4IDUuMTU5MzcgNS43MDUwOCA3LjczOTA2IDUuNzA1MDggMjIuNzIxMDkgMCAzLjE1MDItMC4zMjI0NiA1Ljc1NDY5aC0zMy44NTgzOThxLTAuMzIyNDYtMy4yMjQ2MSAzLjQyMzA0Ny02Ljg0NjA5IDEuNjg2NzIxLTEuNjM3MTEgMy40OTc0NjEtMy4xNzUgMS44MzU1NS0xLjUzNzg5IDMuNTcxODgtMy4xMjUzOSAzLjIyNDYtMi45NzY1NyAzLjU3MTg3LTQuNzYyNS0wLjEyNDAyLTAuMjk3NjYtMC40NzEyOS0wLjM5Njg4LTAuODY4MTYgMC41MjA5LTEuNzM2MzMgMC42Njk3My0wLjg2ODE2IDAuMTQ4ODMtMS43MTE1MiAwLjE5ODQ0LTAuNTQ1NyAwLjAyNDgtMS4wOTE0MSAwLjA0OTYtMC41MjA5IDAtMS4yNDAyMy0wLjI0ODA1LTAuOTY3MzggMS4wOTE0LTEuNjYxOTIgMS44ODUxNS0wLjY2OTcyIDAuNzY4OTUtMS41Mzc4OSAxLjM4OTA3eiIgc3Ryb2tlLXdpZHRoPSIuMjY0NTgzMzIiLz4NCgkJPC9nPg0KCTwvZz4NCjwvc3ZnPg0K')} +.is2d .bishop.white {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjUwLjc5OTk5OW1tIiBoZWlnaHQ9IjUwLjc3NTIwNG1tIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1MC43OTk5OTkgNTAuNzc1MjA0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00Mi42Mjk0ODYsLTg5LjYwNDg1NikiPg0KCQk8ZyBmaWxsPSIjZmZmIj4NCgkJCTxwYXRoIGQ9Im02OC4yMDMwNjEgMTI1LjAwMDc5cS0yLjgwMjkyOSAwLTQuNzg3MzA0IDAuNDk2MS0xLjk4NDM3NSAwLjQ5NjA5LTEuOTg0Mzc1IDEuMTkwNjJ0MS45ODQzNzUgMS4xOTA2M3ExLjk4NDM3NSAwLjQ3MTI5IDQuNzg3MzA0IDAuNDcxMjkgMi44MDI5MyAwIDQuNzg3MzA1LTAuNDcxMjkgMi4wMDkxOC0wLjQ5NjEgMi4wMDkxOC0xLjE5MDYzdC0yLjAwOTE4LTEuMTkwNjJxLTEuOTg0Mzc1LTAuNDk2MS00Ljc4NzMwNS0wLjQ5NjF6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtNzMuODA4OTIxIDk0LjQ0MTQxOXEtMS4wNjY2MDIgMC0xLjA2NjYwMiAxLjA0MTc5NyAwIDEuMDY2NjAyIDEuMDY2NjAyIDEuMDY2NjAyIDEuMDY2NjAxIDAgMS4wNjY2MDEtMS4wNjY2MDIgMC0xLjA0MTc5Ny0xLjA2NjYwMS0xLjA0MTc5N3oiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im02Ny44NTU3OTYgOTQuMzY3MDA5cS0xLjAxNjk5MyAwLTEuMDE2OTkzIDEuMDE2OTkydDEuMDE2OTkzIDEuMDE2OTkycTEuMDE2OTkyIDAgMS4wMTY5OTItMS4wMTY5OTJ0LTEuMDE2OTkyLTEuMDE2OTkyeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTcxLjg5ODk2IDEwOC40ODA4N3YtMS4yNjUwNGgtMy4xNzV2LTQuMjQxNmgtMS4yNjUwMzl2NC4yNDE2aC0zLjE3NXYxLjI2NTA0aDMuMTc1djUuOTI4MzJoMS4yNjUwMzl2LTUuOTI4MzJ6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtNzIuOTY1NTYxIDEwOS41NDc0N2gtMy4xNzV2NS45MjgzMmgtMy4zOTgyNDJ2LTUuOTI4MzJoLTMuMTc1di0zLjM3MzQzaDMuMTc1di00LjI0MTYxaDMuMzk4MjQydjQuMjQxNjFoMy4xNzV6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtNzAuNDg1MDkzIDEyMy4wNDEyMi0yLjQwNjA1NS0wLjk5MjE4LTIuMzgxMjUgMC45OTIxOCAyLjM4MTI1IDAuOTkyMTl6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtNzcuNzI4MDYxIDEwOS43MjExMXEwLjI3Mjg1Mi0xLjMzOTQ2LTAuODQzMzU5LTQuOTM2MTQtMS4wOTE0MDYtMy42MjE0OC0zLjI0OTQxNC02LjAwMjcyNy0wLjMyMjQ2MS0wLjE5ODQzNy0wLjU3MDUwOC0wLjE3MzYzMi0wLjM3MjA3IDAuMDQ5NjEtMC42OTQ1MzEgMC4zNzIwNy0wLjI5NzY1NyAwLjMyMjQ2MS0wLjA3NDQxIDAuNzY4OTQ1IDIuNjI5Mjk3IDEuNzg1OTM0IDQuMDE4MzU5IDUuMTM0NTY0IDEuMzg5MDYyIDMuMzQ4NjQgMS40MTM4NjcgNC44MzY5MnoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im02Mi41NDc1OTMgMTE5LjIyMTNxMi4zODEyNS0wLjc5Mzc1IDUuNTMxNDQ1LTAuNzkzNzUgMy4yNzQyMTkgMCA1LjU4MTA1NCAwLjc5Mzc1IDMuMDI2MTcyLTYuMTAxOTUgMy4wMjYxNzItOS41NzQ2MSAwLTUuODc4NzEtOC41MDgwMDctMTEuNDM0OTU0LTguNDgzMjAzIDUuNTU2MjQ0LTguNDgzMjAzIDExLjQzNDk1NCAwIDMuNzQ1NTEgMi44NTI1MzkgOS41NzQ2MXoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im03My4xODg4MDMgMTIxLjc1MTM4LTAuNDQ2NDg0LTEuNTYyN3EtMi4wODM1OTQtMC40OTYwOS00LjY4ODA4Ni0wLjQ5NjA5LTIuNTU0ODgzIDAtNC40ODk2NDggMC40NDY0OWwtMC40OTYwOTQgMS41ODc0OXEyLjA1ODc4OS0wLjU0NTcgNC45ODU3NDItMC41NDU3IDMuMDc1NzgxIDAgNS4xMzQ1NyAwLjU3MDUxeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTc0LjA4MTc3MiAxMjQuNDA1NDgtMC41NDU3MDMtMS43NjExMy0yLjIwNzYxNyAwLjQ3MTI5IDIuMTgyODEyIDEuNDEzODZ6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtNjIuMjI1MTMyIDEyNC40MzAyOCAwLjQ0NjQ4NCAwLjA5OTIgMi4xODI4MTMtMS40MTM4Ni0yLjEwODM5OS0wLjQ3MTI5eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTY4LjA1NDIzMyAxMzQuMzc2OTZxLTEuODM1NTQ3IDIuNjU0MS00Ljk2MDkzNyAyLjY1NDEtMC4zMjI0NjEgMC0wLjY0NDkyMi0wLjAyNDgtMC4yOTc2NTYtMC4wNDk2LTAuNTk1MzEzLTAuMDc0NC0wLjcxOTMzNi0wLjAyNDgtMi4xMDgzOTgtMC4yNDgwNS0xLjM4OTA2Mi0wLjI0ODA1LTMuMTAwNTg2LTEuMTE2MjEtMS41MTMwODYtMS4zMTQ2NS0zLjg0NDcyNi0xLjMxNDY1LTEuNzg1OTM4IDAtMy4xMDA1ODYgMC44NDMzNi0wLjM3MjA3MSAwLjE3MzYzLTAuOTE3Nzc0IDAuNzE5MzQtMC45OTIxODcgMS4wNjY2LTEuNjEyMzA0IDEuMTY1ODItMC40OTYwOTQtMC4yNDgwNS0wLjUyMDg5OS0wLjg0MzM2LTAuMTI0MDIzLTEuMTY1ODIgMS43MTE1MjQtMy4wMDEzNy0wLjMyMjQ2MSAwLjA0OTYtMS4yMTU0MyAwLjI5NzY2LTAuNzQ0MTQxIDAuMjIzMjQtMC45OTIxODggMC4yMjMyNC0wLjgxODU1NCAwLjEyNDAyLTAuODY4MTY0IDAuMDI0OC0wLjI3Mjg1MS0wLjI3Mjg1IDAuMTk4NDM4LTEuMTE2MjEgMC4zOTY4NzUtMC43MTkzMyAxLjUzNzg5LTEuMjY1MDQgMC4xNDg4MjktMC4wNzQ0IDAuOTQyNTc5LTAuNDIxNjggMi4zMDY4MzUtMS4yMTU0MyA0LjgzNjkxNC0xLjIxNTQzIDMuNjk1ODk4IDAgNi42NzI0NiAyLjUwNTI4IDEuMTkwNjI1IDAuMzk2ODcgMi40MDYwNTUgMC4zOTY4NyAzLjcyMDcwMyAwIDMuODQ0NzI3LTMuMDc1NzgtMi40MDYwNTUtMC4yMjMyNC00LjAxODM2LTAuODE4NTUtMS41ODc1LTAuNTk1MzItMS41ODc1LTEuMzg5MDdsMS45ODQzNzUtNi41OTgwNHEtMS43MzYzMjgtMi43Mjg1Mi0yLjg3NzM0My01LjU1NjI1LTEuMTQxMDE2LTIuODI3NzQtMS4xNDEwMTYtNS4zNTc4MSAwLTcuNTkwMjQgOC4yMzUxNTYtMTEuNjU4MjAzIDAtMC4zMjI0NjEgMC4wNzQ0MS0wLjk2NzM4My0wLjg0MzM1OS0wLjY5NDUzMS0wLjg0MzM1OS0xLjc2MTEzMyAwLTIuMjgyMDMxIDIuMzA2ODM2LTIuMjgyMDMxIDIuMjgyMDMxIDAgMi4yODIwMzEgMi4yODIwMzEgMCAwLjk5MjE4OC0wLjcxOTMzNiAxLjY2MTkxNCAwIDAuNzY4OTQ2IDAuMTk4NDM3IDEuMDQxNzk3IDAuNDIxNjggMC41OTUzMTMgMS4xMTYyMTEgMC42MjAxMTcgMC43MTkzMzYtMC4wMjQ4IDEuMTkwNjI1LTAuNjQ0OTIyIDAuMDk5MjItMC4xNDg4MjggMC4xOTg0MzgtMC45MTc3NzMtMC42NDQ5MjItMC42Njk3MjctMC42NDQ5MjItMS42NjE5MTQgMC0yLjMzMTY0MSAyLjMzMTY0MS0yLjMzMTY0MSAyLjMzMTY0IDAgMi4zMzE2NCAyLjMzMTY0MSAwIDEuMzE0NjQ4LTEuMTQxMDE1IDIuMDMzOTg0LTAuMDk5MjIgMC40OTYwOTQtMC4wNDk2MSAwLjc5Mzc1IDQuMTkxOTkyIDQuOTYwOTM2IDMuNjQ2Mjg5IDExLjQ1OTc2Ni0wLjE3MzYzMyAxLjg2MDM1LTAuNTcwNTA4IDMuNjcxMDktMC4zOTY4NzUgMS43ODU5NC0xLjM4OTA2MiAzLjM3MzQ0LTAuMzcyMDcgMC44NDMzNi0xLjE2NTgyIDEuOTA5OTYtMC43Njg5NDYgMS4wNDE3OS0xLjMzOTQ1MyAxLjk1OTU3bDEuOTU5NTcgNi41OTgwNHEtMC4wMjQ4MSAwLjc5Mzc1LTEuNjM3MTEgMS4zODkwNy0xLjYxMjMwNCAwLjU5NTMxLTQuMDY3OTY4IDAuODE4NTUgMC4xMjQwMjMgMy4wNzU3OCAzLjg2OTUzMSAzLjA3NTc4IDEuMjE1NDMgMCAyLjQwNjA1NS0wLjM5Njg3IDIuOTUxNzU3LTIuNTA1MjggNi42NzI0Ni0yLjUwNTI4IDIuNTMwMDc5IDAgNC44MTIxMSAxLjIxNTQzIDAuMjk3NjU2IDAuMTQ4ODMgMC41MjA4OTggMC4yNDgwNSAwLjIyMzI0MiAwLjA5OTIgMC40NDY0ODUgMC4xNzM2MyAxLjExNjIxIDAuNTcwNTEgMS41Mzc4OSAxLjI2NTA0IDAuMDc0NDEgMC4yMjMyNSAwLjIyMzI0MiAwLjU3MDUxIDAuMTQ4ODI4IDAuMzQ3MjctMC4wMjQ4IDAuNTQ1Ny0wLjA3NDQxIDAuMDk5Mi0wLjg2ODE2NC0wLjAyNDgtMC4yNDgwNDcgMC0wLjk5MjE4OC0wLjIyMzI0LTAuOTE3NzczLTAuMjQ4MDUtMS4yNDAyMzQtMC4yOTc2NiAxLjgzNTU0NyAxLjg2MDM1IDEuNzM2MzI4IDMuMDAxMzctMC4wNDk2MSAwLjU3MDUxLTAuNTQ1NzAzIDAuODQzMzYtMC42MjAxMTctMC4wOTkyLTEuNjEyMzA1LTEuMTY1ODItMC40OTYwOTQtMC40OTYxLTAuODkyOTY5LTAuNzE5MzQtMS4zODkwNjItMC44NDMzNi0zLjEwMDU4Ni0wLjg0MzM2LTIuMzgxMjUgMC0zLjg2OTUzMSAxLjMxNDY1LTEuNzExNTIzIDAuODY4MTYtMy4xMDA1ODYgMS4xMTYyMS0xLjM4OTA2MiAwLjIyMzI0LTIuMDgzNTkzIDAuMjQ4MDUtMC4yOTc2NTcgMC4wMjQ4LTAuNjIwMTE4IDAuMDc0NC0wLjMyMjQ2IDAuMDI0OC0wLjYyMDExNyAwLjAyNDgtMy4xOTk4MDQgMC00Ljk4NTc0Mi0yLjY1NDF6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtNjguMDU0MjMzIDEzMi41NjYyMXEwLjA3NDQxIDAgMS42MzcxMSAxLjUxMzA5IDEuNDM4NjcxIDEuMzY0MjYgMy41MjIyNjUgMS4zNjQyNiAwLjE3MzYzMyAwIDAuNDk2MDk0IDB0MC41MjA4OTggMHExLjA2NjYwMi0wLjA3NDQgMi4wMzM5ODUtMC4yNDgwNSAwLjk2NzM4Mi0wLjE5ODQ0IDIuMzA2ODM2LTAuNzQ0MTQgMi41Nzk2ODctMS43ODU5NCA0Ljc2MjQ5OS0xLjc4NTk0IDAuOTQyNTc5IDAgMS43MzYzMjkgMC4yMjMyNCAwLjMyMjQ2IDAuMDc0NCAwLjM3MjA3IDAuMTczNjQgMC4wNzQ0MSAwLjA3NDQgMC41NzA1MDggMC4yOTc2NSAxLjUzNzg5IDAuNzkzNzUgMC43Njg5NDUgMC4xNzM2NC0wLjc0NDE0MS0wLjY0NDkzLTAuNTcwNTA4LTAuOTQyNTggMC4xNDg4MjgtMC4zMjI0NiAxLjE0MTAxNi0wLjY5NDUzIDEuMDE2OTkyLTAuMzcyMDctMS40Mzg2NzItMC41OTUzMi0xLjI0MDIzNC0wLjQyMTY4LTIuNTc5Njg4LTAuNDIxNjgtMi45NzY1NjIgMC02LjA3NzE0OCAyLjQwNjA2LTEuMDkxNDA2IDAuNTk1MzEtMS44NjAzNTEgMC42Njk3My0wLjc0NDE0MSAwLjA3NDQtMS40MTM4NjggMC4wMjQ4LTEuOTM0NzY1LTAuMDc0NC0yLjYwNDQ5Mi0wLjUyMDktMC42NDQ5MjItMC40NzEyOS0xLjE2NTgyLTEuMDQxNzktMC40OTYwOTQtMC41MjA5LTAuOTY3MzgzLTIuMDA5MTgtMC4yNDgwNDctMC43OTM3NS0xLjE5MDYyNS0wLjg5Mjk3LTAuOTY3MzgzIDAuMDk5Mi0xLjE5MDYyNSAwLjg5Mjk3LTAuNDQ2NDg0IDEuNDg4MjgtMC45NjczODMgMi4wMDkxOC0wLjUyMDg5OCAwLjU3MDUtMS4xOTA2MjUgMS4wNDE3OS0wLjY0NDkyMSAwLjQ0NjQ5LTIuNTU0ODgyIDAuNTIwOS0wLjY5NDUzMiAwLjA0OTYtMS40NjM0NzctMC4wMjQ4LTAuNzQ0MTQxLTAuMDc0NC0xLjgxMDc0Mi0wLjY2OTczLTMuMTUwMTk1LTIuNDA2MDYtNi4wNzcxNDgtMi40MDYwNi0xLjM2NDI1OCAwLTIuNTc5Njg4IDAuNDIxNjgtMi40ODA0NjkgMC4yMjMyNS0xLjQ4ODI4MSAwLjU5NTMyIDEuMDE2OTkyIDAuMzcyMDcgMS4xOTA2MjUgMC42OTQ1MyAwLjE0ODgyOCAwLjI5NzY1LTAuNjIwMTE3IDAuOTQyNTgtMC43NDQxNDEgMC42MjAxMSAwLjgxODU1NC0wLjE3MzY0IDAuNDQ2NDg1LTAuMjIzMjQgMC41MjA4OTktMC4yOTc2NSAwLjA3NDQxLTAuMDk5MiAwLjM5Njg3NS0wLjE3MzY0IDAuNzY4OTQ1LTAuMjIzMjQgMS43NjExMzMtMC4yMjMyNCAyLjE1ODAwNyAwIDQuNzM3Njk1IDEuNzg1OTQgMS4zMzk0NTMgMC41NDU3IDIuMjgyMDMxIDAuNzQ0MTQgMC45NjczODMgMC4xNzM2MyAyLjA4MzU5NCAwLjI0ODA1IDAuMTczNjMzIDAgMC40NzEyODkgMCAwLjMyMjQ2MSAwIDAuNTQ1NzAzIDAgMi4wNTg3ODkgMCAzLjUyMjI2Ni0xLjM2NDI2IDEuNTM3ODktMS41MTMwOSAxLjYxMjMwNC0xLjUxMzA5eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQk8L2c+DQoJCTxnIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiIGFyaWEtbGFiZWw9ImIiPg0KCQkJPHBhdGggZD0ibTY4LjIwMzA2MSAxMjUuMDAwNzlxLTIuODAyOTI5IDAtNC43ODczMDQgMC40OTYxLTEuOTg0Mzc1IDAuNDk2MDktMS45ODQzNzUgMS4xOTA2MnQxLjk4NDM3NSAxLjE5MDYzcTEuOTg0Mzc1IDAuNDcxMjkgNC43ODczMDQgMC40NzEyOSAyLjgwMjkzIDAgNC43ODczMDUtMC40NzEyOSAyLjAwOTE4LTAuNDk2MSAyLjAwOTE4LTEuMTkwNjN0LTIuMDA5MTgtMS4xOTA2MnEtMS45ODQzNzUtMC40OTYxLTQuNzg3MzA1LTAuNDk2MXptNS42MDU4Ni0zMC41NTkzNzFxLTEuMDY2NjAyIDAtMS4wNjY2MDIgMS4wNDE3OTcgMCAxLjA2NjYwMiAxLjA2NjYwMiAxLjA2NjYwMiAxLjA2NjYwMSAwIDEuMDY2NjAxLTEuMDY2NjAyIDAtMS4wNDE3OTctMS4wNjY2MDEtMS4wNDE3OTd6bS01Ljk1MzEyNS0wLjA3NDQxcS0xLjAxNjk5MyAwLTEuMDE2OTkzIDEuMDE2OTkydDEuMDE2OTkzIDEuMDE2OTkycTEuMDE2OTkyIDAgMS4wMTY5OTItMS4wMTY5OTJ0LTEuMDE2OTkyLTEuMDE2OTkyem00LjA0MzE2NCAxNC4xMTM4NjV2LTEuMjY1MDRoLTMuMTc1di00LjI0MTZoLTEuMjY1MDM5djQuMjQxNmgtMy4xNzV2MS4yNjUwNGgzLjE3NXY1LjkyODMyaDEuMjY1MDM5di01LjkyODMyem0xLjA2NjYwMSAxLjA2NjZoLTMuMTc1djUuOTI4MzJoLTMuMzk4MjQydi01LjkyODMyaC0zLjE3NXYtMy4zNzM0M2gzLjE3NXYtNC4yNDE2MWgzLjM5ODI0MnY0LjI0MTYxaDMuMTc1em0tMi40ODA0NjggMTMuNDkzNzUtMi40MDYwNTUtMC45OTIxOC0yLjM4MTI1IDAuOTkyMTggMi4zODEyNSAwLjk5MjE5em03LjI0Mjk2OC0xMy4zMjAxMXEwLjI3Mjg1Mi0xLjMzOTQ2LTAuODQzMzU5LTQuOTM2MTQtMS4wOTE0MDYtMy42MjE0OC0zLjI0OTQxNC02LjAwMjczMS0wLjMyMjQ2MS0wLjE5ODQzNy0wLjU3MDUwOC0wLjE3MzYzMi0wLjM3MjA3IDAuMDQ5NjEtMC42OTQ1MzEgMC4zNzIwNy0wLjI5NzY1NyAwLjMyMjQ2MS0wLjA3NDQxIDAuNzY4OTQ1IDIuNjI5Mjk3IDEuNzg1OTM4IDQuMDE4MzU5IDUuMTM0NTY4IDEuMzg5MDYyIDMuMzQ4NjQgMS40MTM4NjcgNC44MzY5MnptLTE1LjE4MDQ2OCA5LjUwMDE5cTIuMzgxMjUtMC43OTM3NSA1LjUzMTQ0NS0wLjc5Mzc1IDMuMjc0MjE5IDAgNS41ODEwNTQgMC43OTM3NSAzLjAyNjE3Mi02LjEwMTk1IDMuMDI2MTcyLTkuNTc0NjEgMC01Ljg3ODcxLTguNTA4MDA3LTExLjQzNDk1OC04LjQ4MzIwMyA1LjU1NjI0OC04LjQ4MzIwMyAxMS40MzQ5NTggMCAzLjc0NTUxIDIuODUyNTM5IDkuNTc0NjF6bTEwLjY0MTIxIDIuNTMwMDgtMC40NDY0ODQtMS41NjI3cS0yLjA4MzU5NC0wLjQ5NjA5LTQuNjg4MDg2LTAuNDk2MDktMi41NTQ4ODMgMC00LjQ4OTY0OCAwLjQ0NjQ5bC0wLjQ5NjA5NCAxLjU4NzQ5cTIuMDU4Nzg5LTAuNTQ1NyA0Ljk4NTc0Mi0wLjU0NTcgMy4wNzU3ODEgMCA1LjEzNDU3IDAuNTcwNTF6bTAuODkyOTY5IDIuNjU0MS0wLjU0NTcwMy0xLjc2MTEzLTIuMjA3NjE3IDAuNDcxMjkgMi4xODI4MTIgMS40MTM4NnptLTExLjg1NjY0IDAuMDI0OCAwLjQ0NjQ4NCAwLjA5OTIgMi4xODI4MTMtMS40MTM4Ni0yLjEwODM5OS0wLjQ3MTI5em01LjgyOTEwMSA5Ljk0NjY4cS0xLjgzNTU0NyAyLjY1NDEtNC45NjA5MzcgMi42NTQxLTAuMzIyNDYxIDAtMC42NDQ5MjItMC4wMjQ4LTAuMjk3NjU2LTAuMDQ5Ni0wLjU5NTMxMy0wLjA3NDQtMC43MTkzMzYtMC4wMjQ4LTIuMTA4Mzk4LTAuMjQ4MDUtMS4zODkwNjItMC4yNDgwNS0zLjEwMDU4Ni0xLjExNjIxLTEuNTEzMDg2LTEuMzE0NjUtMy44NDQ3MjYtMS4zMTQ2NS0xLjc4NTkzOCAwLTMuMTAwNTg2IDAuODQzMzYtMC4zNzIwNzEgMC4xNzM2My0wLjkxNzc3NCAwLjcxOTM0LTAuOTkyMTg3IDEuMDY2Ni0xLjYxMjMwNCAxLjE2NTgyLTAuNDk2MDk0LTAuMjQ4MDUtMC41MjA4OTktMC44NDMzNi0wLjEyNDAyMy0xLjE2NTgyIDEuNzExNTI0LTMuMDAxMzctMC4zMjI0NjEgMC4wNDk2LTEuMjE1NDMgMC4yOTc2Ni0wLjc0NDE0MSAwLjIyMzI0LTAuOTkyMTg4IDAuMjIzMjQtMC44MTg1NTQgMC4xMjQwMi0wLjg2ODE2NCAwLjAyNDgtMC4yNzI4NTEtMC4yNzI4NSAwLjE5ODQzOC0xLjExNjIxIDAuMzk2ODc1LTAuNzE5MzMgMS41Mzc4OS0xLjI2NTA0IDAuMTQ4ODI5LTAuMDc0NCAwLjk0MjU3OS0wLjQyMTY4IDIuMzA2ODM1LTEuMjE1NDMgNC44MzY5MTQtMS4yMTU0MyAzLjY5NTg5OCAwIDYuNjcyNDYgMi41MDUyOCAxLjE5MDYyNSAwLjM5Njg3IDIuNDA2MDU1IDAuMzk2ODcgMy43MjA3MDMgMCAzLjg0NDcyNy0zLjA3NTc4LTIuNDA2MDU1LTAuMjIzMjQtNC4wMTgzNi0wLjgxODU1LTEuNTg3NS0wLjU5NTMyLTEuNTg3NS0xLjM4OTA3bDEuOTg0Mzc1LTYuNTk4MDRxLTEuNzM2MzI4LTIuNzI4NTItMi44NzczNDMtNS41NTYyNS0xLjE0MTAxNi0yLjgyNzc0LTEuMTQxMDE2LTUuMzU3ODEgMC03LjU5MDI0IDguMjM1MTU2LTExLjY1ODIwNyAwLTAuMzIyNDYxIDAuMDc0NDEtMC45NjczODMtMC44NDMzNTktMC42OTQ1MzEtMC44NDMzNTktMS43NjExMzMgMC0yLjI4MjAzMSAyLjMwNjgzNi0yLjI4MjAzMSAyLjI4MjAzMSAwIDIuMjgyMDMxIDIuMjgyMDMxIDAgMC45OTIxODgtMC43MTkzMzYgMS42NjE5MTQgMCAwLjc2ODk0NiAwLjE5ODQzNyAxLjA0MTc5NyAwLjQyMTY4IDAuNTk1MzEzIDEuMTE2MjExIDAuNjIwMTE3IDAuNzE5MzM2LTAuMDI0OCAxLjE5MDYyNS0wLjY0NDkyMiAwLjA5OTIyLTAuMTQ4ODI4IDAuMTk4NDM4LTAuOTE3NzczLTAuNjQ0OTIyLTAuNjY5NzI3LTAuNjQ0OTIyLTEuNjYxOTE0IDAtMi4zMzE2NDEgMi4zMzE2NDEtMi4zMzE2NDEgMi4zMzE2NCAwIDIuMzMxNjQgMi4zMzE2NDEgMCAxLjMxNDY0OC0xLjE0MTAxNSAyLjAzMzk4NC0wLjA5OTIyIDAuNDk2MDk0LTAuMDQ5NjEgMC43OTM3NSA0LjE5MTk5MiA0Ljk2MDk0IDMuNjQ2Mjg5IDExLjQ1OTc3LTAuMTczNjMzIDEuODYwMzUtMC41NzA1MDggMy42NzEwOS0wLjM5Njg3NSAxLjc4NTk0LTEuMzg5MDYyIDMuMzczNDQtMC4zNzIwNyAwLjg0MzM2LTEuMTY1ODIgMS45MDk5Ni0wLjc2ODk0NiAxLjA0MTc5LTEuMzM5NDUzIDEuOTU5NTdsMS45NTk1NyA2LjU5ODA0cS0wLjAyNDgxIDAuNzkzNzUtMS42MzcxMSAxLjM4OTA3LTEuNjEyMzA0IDAuNTk1MzEtNC4wNjc5NjggMC44MTg1NSAwLjEyNDAyMyAzLjA3NTc4IDMuODY5NTMxIDMuMDc1NzggMS4yMTU0MyAwIDIuNDA2MDU1LTAuMzk2ODcgMi45NTE3NTctMi41MDUyOCA2LjY3MjQ2LTIuNTA1MjggMi41MzAwNzkgMCA0LjgxMjExIDEuMjE1NDMgMC4yOTc2NTYgMC4xNDg4MyAwLjUyMDg5OCAwLjI0ODA1IDAuMjIzMjQyIDAuMDk5MiAwLjQ0NjQ4NSAwLjE3MzYzIDEuMTE2MjEgMC41NzA1MSAxLjUzNzg5IDEuMjY1MDQgMC4wNzQ0MSAwLjIyMzI1IDAuMjIzMjQyIDAuNTcwNTEgMC4xNDg4MjggMC4zNDcyNy0wLjAyNDggMC41NDU3LTAuMDc0NDEgMC4wOTkyLTAuODY4MTY0LTAuMDI0OC0wLjI0ODA0NyAwLTAuOTkyMTg4LTAuMjIzMjQtMC45MTc3NzMtMC4yNDgwNS0xLjI0MDIzNC0wLjI5NzY2IDEuODM1NTQ3IDEuODYwMzUgMS43MzYzMjggMy4wMDEzNy0wLjA0OTYxIDAuNTcwNTEtMC41NDU3MDMgMC44NDMzNi0wLjYyMDExNy0wLjA5OTItMS42MTIzMDUtMS4xNjU4Mi0wLjQ5NjA5NC0wLjQ5NjEtMC44OTI5NjktMC43MTkzNC0xLjM4OTA2Mi0wLjg0MzM2LTMuMTAwNTg2LTAuODQzMzYtMi4zODEyNSAwLTMuODY5NTMxIDEuMzE0NjUtMS43MTE1MjMgMC44NjgxNi0zLjEwMDU4NiAxLjExNjIxLTEuMzg5MDYyIDAuMjIzMjQtMi4wODM1OTMgMC4yNDgwNS0wLjI5NzY1NyAwLjAyNDgtMC42MjAxMTggMC4wNzQ0LTAuMzIyNDYgMC4wMjQ4LTAuNjIwMTE3IDAuMDI0OC0zLjE5OTgwNCAwLTQuOTg1NzQyLTIuNjU0MXptMC0xLjgxMDc1cTAuMDc0NDEgMCAxLjYzNzExIDEuNTEzMDkgMS40Mzg2NzEgMS4zNjQyNiAzLjUyMjI2NSAxLjM2NDI2IDAuMTczNjMzIDAgMC40OTYwOTQgMHQwLjUyMDg5OCAwcTEuMDY2NjAyLTAuMDc0NCAyLjAzMzk4NS0wLjI0ODA1IDAuOTY3MzgyLTAuMTk4NDQgMi4zMDY4MzYtMC43NDQxNCAyLjU3OTY4Ny0xLjc4NTk0IDQuNzYyNDk5LTEuNzg1OTQgMC45NDI1NzkgMCAxLjczNjMyOSAwLjIyMzI0IDAuMzIyNDYgMC4wNzQ0IDAuMzcyMDcgMC4xNzM2NCAwLjA3NDQxIDAuMDc0NCAwLjU3MDUwOCAwLjI5NzY1IDEuNTM3ODkgMC43OTM3NSAwLjc2ODk0NSAwLjE3MzY0LTAuNzQ0MTQxLTAuNjQ0OTMtMC41NzA1MDgtMC45NDI1OCAwLjE0ODgyOC0wLjMyMjQ2IDEuMTQxMDE2LTAuNjk0NTMgMS4wMTY5OTItMC4zNzIwNy0xLjQzODY3Mi0wLjU5NTMyLTEuMjQwMjM0LTAuNDIxNjgtMi41Nzk2ODgtMC40MjE2OC0yLjk3NjU2MiAwLTYuMDc3MTQ4IDIuNDA2MDYtMS4wOTE0MDYgMC41OTUzMS0xLjg2MDM1MSAwLjY2OTczLTAuNzQ0MTQxIDAuMDc0NC0xLjQxMzg2OCAwLjAyNDgtMS45MzQ3NjUtMC4wNzQ0LTIuNjA0NDkyLTAuNTIwOS0wLjY0NDkyMi0wLjQ3MTI5LTEuMTY1ODItMS4wNDE3OS0wLjQ5NjA5NC0wLjUyMDktMC45NjczODMtMi4wMDkxOC0wLjI0ODA0Ny0wLjc5Mzc1LTEuMTkwNjI1LTAuODkyOTctMC45NjczODMgMC4wOTkyLTEuMTkwNjI1IDAuODkyOTctMC40NDY0ODQgMS40ODgyOC0wLjk2NzM4MyAyLjAwOTE4LTAuNTIwODk4IDAuNTcwNS0xLjE5MDYyNSAxLjA0MTc5LTAuNjQ0OTIxIDAuNDQ2NDktMi41NTQ4ODIgMC41MjA5LTAuNjk0NTMyIDAuMDQ5Ni0xLjQ2MzQ3Ny0wLjAyNDgtMC43NDQxNDEtMC4wNzQ0LTEuODEwNzQyLTAuNjY5NzMtMy4xNTAxOTUtMi40MDYwNi02LjA3NzE0OC0yLjQwNjA2LTEuMzY0MjU4IDAtMi41Nzk2ODggMC40MjE2OC0yLjQ4MDQ2OSAwLjIyMzI1LTEuNDg4MjgxIDAuNTk1MzIgMS4wMTY5OTIgMC4zNzIwNyAxLjE5MDYyNSAwLjY5NDUzIDAuMTQ4ODI4IDAuMjk3NjUtMC42MjAxMTcgMC45NDI1OC0wLjc0NDE0MSAwLjYyMDExIDAuODE4NTU0LTAuMTczNjQgMC40NDY0ODUtMC4yMjMyNCAwLjUyMDg5OS0wLjI5NzY1IDAuMDc0NDEtMC4wOTkyIDAuMzk2ODc1LTAuMTczNjQgMC43Njg5NDUtMC4yMjMyNCAxLjc2MTEzMy0wLjIyMzI0IDIuMTU4MDA3IDAgNC43Mzc2OTUgMS43ODU5NCAxLjMzOTQ1MyAwLjU0NTcgMi4yODIwMzEgMC43NDQxNCAwLjk2NzM4MyAwLjE3MzYzIDIuMDgzNTk0IDAuMjQ4MDUgMC4xNzM2MzMgMCAwLjQ3MTI4OSAwIDAuMzIyNDYxIDAgMC41NDU3MDMgMCAyLjA1ODc4OSAwIDMuNTIyMjY2LTEuMzY0MjYgMS41Mzc4OS0xLjUxMzA5IDEuNjEyMzA0LTEuNTEzMDl6IiBzdHJva2Utd2lkdGg9Ii4yNjQ1ODMzMiIvPg0KCQk8L2c+DQoJPC9nPg0KPC9zdmc+DQo=')} +.is2d .rook.white {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjUwLjc5OTk5OW1tIiBoZWlnaHQ9IjUwLjc3NTE4OG1tIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1MC43OTk5OTkgNTAuNzc1MTg4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC03Ni44Mzk5ODksLTEwOC43MTQ2MykiPg0KCQk8ZyBmaWxsPSIjZmZmIj4NCgkJCTxwYXRoIGQ9Im0xMDIuMjM5ODQgMTEyLjExMjVoMy40MjMwNXYzLjM3MzQ0aDUuMTM0NTd2LTMuMzczNDRoNS45MDM1MnY4Ljg1NTI4bC0zLjk5MzU2IDQuNjEzNjdxMS4yODk4NSAxLjYzNzExIDAuMDQ5NiAzLjQ0Nzg1LTAuMTk4NDQgMC4zMjI0Ni0wLjE5ODQ0IDAuNTk1MzEgMCAwLjMyMjQ2IDAuMTk4NDQgMC42MjAxMiAwLjUyMDkgMC43Njg5NSAwLjQ5NjA5IDIuMTgyODEgMCAxLjM4OTA2LTAuNTIwODkgMi4xODI4MS0wLjE3MzY0IDAuMjQ4MDUtMC4xNzM2NCAwLjUyMDkgMCAwLjM0NzI3IDAuMjIzMjUgMC42NDQ5MyAxLjE2NTgyIDEuNzYxMTMtMC4wNDk2IDMuNDcyNjUtMC4xNzM2NCAwLjI5NzY2LTAuMTczNjQgMC41NzA1MXQwLjE3MzY0IDAuNTcwNTFxMC41NDU3IDAuODE4NTUgMC41NDU3IDIuMjgyMDMgMCAxLjQzODY3LTAuNTk1MzEgMi4xMzMybDQuMDE4MzYgMi4wMDkxOHYyLjEzMzJoMS42NjE5MXY3LjE5MzM2aC0zMi4yNzA4OTh2LTcuMTY4NTVoMS42ODY3MTl2LTIuMTMzMmwzLjk5MzU1NC0yLjAzMzk5cS0wLjU5NTMxMi0wLjY5NDUzLTAuNTk1MzEyLTIuMTMzMnQwLjU0NTcwMy0yLjI1NzIzcTAuMTk4NDM4LTAuMjcyODUgMC4xOTg0MzgtMC41NzA1MSAwLTAuMjQ4MDQtMC4xOTg0MzgtMC41NzA1LTEuMjE1NDMtMS43MzYzMy0wLjAyNDgxLTMuNDcyNjYgMC4yMjMyNDMtMC4zOTY4OCAwLjIyMzI0My0wLjY0NDkyIDAtMC4yNDgwNS0wLjE3MzYzMy0wLjU0NTcxLTAuNTQ1NzAzLTAuNzkzNzUtMC41NzA1MDgtMi4xODI4MSAwLTEuNDEzODYgMC41MjA4OTgtMi4xODI4MSAwLjIyMzI0My0wLjI5NzY2IDAuMjIzMjQzLTAuNjIwMTIgMC0wLjI3Mjg1LTAuMTk4NDM4LTAuNTcwNS0xLjI2NTAzOS0xLjgxMDc1IDAuMDQ5NjEtMy40NzI2NmwtMy45OTM1NTQtNC41ODg4N3YtOC44NTUyN2g1LjkwMzUxNXYzLjM0ODYzbDUuMTA5NzY2IDAuMDI0OHYtMy4zNzM0NHoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im05My4wODY5MTQgMTI0LjM2NjAycTQuMjQxNjAxLTAuNjY5NzMgOS4xNTI5MjYtMC42Njk3MyA0Ljk4NTc1IDAgOS4yMjczNSAwLjY2OTczbDEuNDM4NjctMS44MTA3NHEtNS4wNjAxNi0wLjg5Mjk3LTEwLjY2NjAyLTAuODkyOTctNS42NTU0NjUgMC0xMC42OTA4MTcgMC44OTI5N3oiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im04Ny44NTMxMjUgMTUwLjY1ODk5djMuNzk1MTFoMjguNzQ4NjM1di0zLjc5NTExeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwMi4yMzk4NCAxNDUuNTk4ODNxLTUuMTU5MzcyIDAtOS4zNTEzNjQgMC4zNDcyN2wtMy4zNDg2MzIgMS43ODU5M3YxLjI0MDI0aDI1LjM5OTk5NnYtMS4yNDAyNHEtMC44NDMzNi0wLjQ0NjQ4LTEuNjg2NzItMC44OTI5Ni0wLjg0MzM1LTAuNDQ2NDktMS42NjE5MS0wLjg5Mjk3LTQuNDY0ODQtMC4zNDcyNy05LjM1MTM3LTAuMzQ3Mjd6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtMTE0LjkzOTg0IDExMy43OTkyMmgtMi41NTQ4OHYzLjQ3MjY2aC04LjQ4MzJ2LTMuNDQ3ODVoLTMuMzQ4NjR2My40NDc4NWgtOC40NTgzOTR2LTMuNDcyNjZoLTIuNTU0ODgycTAgMS41ODc1IDAgMy4xNzUgMCAxLjU2MjcgMCAzLjEyNTM5IDMuMTc1LTAuMTk4NDMgNi4zMjUxOTUtMC4zNzIwNyAzLjE3NS0wLjE3MzYzIDYuMzc0ODAxLTAuMTczNjMgNi4wMjc1NCAwIDEyLjcgMC41NDU3eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwNi43Mjk0OSAxMjUuNjgwNjdxLTAuODE4NTUgMC41OTUzMS0wLjgxODU1IDEuNjg2NzIgMCAxLjA5MTQgMC44MTg1NSAxLjY4NjcyIDAuNzY4OTUgMC41OTUzMSAyLjI4MjAzIDAuNTk1MzEgMS41MTMwOSAwIDIuMzA2ODQtMC41OTUzMSAwLjc5Mzc1LTAuNTk1MzIgMC43OTM3NS0xLjY4NjcyIDAtMS4wOTE0MS0wLjc5Mzc1LTEuNjg2NzItMC43OTM3NS0wLjU3MDUxLTIuMzA2ODQtMC41NzA1MS0xLjUxMzA4IDAtMi4yODIwMyAwLjU3MDUxeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwMC4wNTcwMyAxMjUuNjgwNjdxLTAuNzY4OTQ0IDAuNTk1MzEtMC43Njg5NDQgMS42ODY3MiAwIDEuMDkxNCAwLjc2ODk0NCAxLjY4NjcyIDAuNzQ0MTQgMC41OTUzMSAyLjE1ODAxIDAuNTk1MzEgMS40Mzg2NyAwIDIuMjA3NjItMC41OTUzMSAwLjc0NDE0LTAuNTk1MzIgMC43NDQxNC0xLjY4NjcyIDAtMS4wOTE0MS0wLjc0NDE0LTEuNjg2NzItMC43Njg5NS0wLjU3MDUxLTIuMjA3NjItMC41NzA1MS0xLjQxMzg3IDAtMi4xNTgwMSAwLjU3MDUxeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTkzLjE2MTMyOCAxMjUuNjgwNjdxLTAuODE4NTU1IDAuNTk1MzEtMC44MTg1NTUgMS42ODY3MiAwIDEuMDkxNCAwLjgxODU1NSAxLjY4NjcyIDAuNzY4OTQ1IDAuNTk1MzEgMi4yNTcyMjYgMC41OTUzMSAxLjUxMzA4NiAwIDIuMzMxNjQxLTAuNTk1MzEgMC43OTM3NS0wLjU5NTMyIDAuNzkzNzUtMS42ODY3MiAwLTEuMDkxNDEtMC43OTM3NS0xLjY4NjcyLTAuODE4NTU1LTAuNTcwNTEtMi4zMzE2NDEtMC41NzA1MS0xLjQ4ODI4MSAwLTIuMjU3MjI2IDAuNTcwNTF6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtMTA5LjgzMDA4IDEzMC43MTYwMnEtMC4yOTc2NiAwLjU5NTMxLTAuMjk3NjYgMS43MTE1MiAwIDEuMDkxNDEgMC4yOTc2NiAxLjY2MTkyIDAuMjcyODUgMC41OTUzMSAwLjg2ODE2IDAuNTk1MzF0MC44OTI5Ny0wLjU5NTMxcTAuMjk3NjYtMC41NzA1MSAwLjI5NzY2LTEuNjYxOTIgMC0xLjExNjIxLTAuMjk3NjYtMS43MTE1Mi0wLjI5NzY2LTAuNTQ1Ny0wLjg5Mjk3LTAuNTQ1N3QtMC44NjgxNiAwLjU0NTd6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtMTAzLjQ4MDA4IDEzMC43MTYwMnEtMC43NDQxNCAwLjU5NTMxLTAuNzQ0MTQgMS43MTE1MiAwIDEuMDkxNDEgMC43NDQxNCAxLjY2MTkyIDAuNzQ0MTQgMC41OTUzMSAyLjEzMzIgMC41OTUzMSAxLjQxMzg3IDAgMi4xNTgwMS0wLjU5NTMxIDAuNzQ0MTQtMC41NzA1MSAwLjc0NDE0LTEuNjYxOTIgMC0xLjExNjIxLTAuNzQ0MTQtMS43MTE1Mi0wLjc0NDE0LTAuNTcwNTEtMi4xNTgwMS0wLjU3MDUxLTEuMzg5MDYgMC0yLjEzMzIgMC41NzA1MXoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im05Ni43MDgzOTggMTMwLjcxNjAycS0wLjc0NDE0IDAuNTk1MzEtMC43NDQxNCAxLjcxMTUyIDAgMS4wOTE0MSAwLjc0NDE0IDEuNjYxOTIgMC43MTkzMzYgMC41OTUzMSAyLjEzMzIwMyAwLjU5NTMxIDEuNDEzODY5IDAgMi4xNTgwMDktMC41OTUzMSAwLjcxOTMzLTAuNTcwNTEgMC43MTkzMy0xLjY2MTkyIDAtMS4xMTYyMS0wLjcxOTMzLTEuNzExNTItMC43NDQxNC0wLjU3MDUxLTIuMTU4MDA5LTAuNTcwNTEtMS40MTM4NjcgMC0yLjEzMzIwMyAwLjU3MDUxeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTkyLjg4ODQ3NiAxMzAuNzE2MDJxLTAuMjk3NjU2IDAuNTk1MzEtMC4yOTc2NTYgMS43MTE1MiAwIDEuMDkxNDEgMC4yOTc2NTYgMS42NjE5MiAwLjI5NzY1NyAwLjU5NTMxIDAuODY4MTY0IDAuNTk1MzEgMC41OTUzMTMgMCAwLjg5Mjk2OS0wLjU5NTMxIDAuMjk3NjU2LTAuNTcwNTEgMC4yOTc2NTYtMS42NjE5MiAwLTEuMTE2MjEtMC4yOTc2NTYtMS43MTE1Mi0wLjI5NzY1Ni0wLjU0NTctMC44OTI5NjktMC41NDU3LTAuNTcwNTA3IDAtMC44NjgxNjQgMC41NDU3eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwOS44MzAwOCAxNDAuOTEwNzVxLTAuMjk3NjYgMC41NzA1LTAuMjk3NjYgMS42ODY3MSAwIDEuMTE2MjIgMC4yOTc2NiAxLjY4NjcyIDAuMjcyODUgMC41NzA1MSAwLjg2ODE2IDAuNTcwNTF0MC44OTI5Ny0wLjU3MDUxcTAuMjk3NjYtMC41NzA1IDAuMjk3NjYtMS42ODY3MiAwLTEuMTE2MjEtMC4yOTc2Ni0xLjY4NjcxLTAuMjk3NjYtMC41NDU3MS0wLjg5Mjk3LTAuNTQ1NzF0LTAuODY4MTYgMC41NDU3MXoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im05Mi44ODg0NzYgMTQwLjkxMDc1cS0wLjI5NzY1NiAwLjU3MDUtMC4yOTc2NTYgMS42ODY3MSAwIDEuMTE2MjIgMC4yOTc2NTYgMS42ODY3MiAwLjI5NzY1NyAwLjU3MDUxIDAuODY4MTY0IDAuNTcwNTEgMC41OTUzMTMgMCAwLjg5Mjk2OS0wLjU3MDUxIDAuMjk3NjU2LTAuNTcwNSAwLjI5NzY1Ni0xLjY4NjcyIDAtMS4xMTYyMS0wLjI5NzY1Ni0xLjY4NjcxLTAuMjk3NjU2LTAuNTQ1NzEtMC44OTI5NjktMC41NDU3MS0wLjU3MDUwNyAwLTAuODY4MTY0IDAuNTQ1NzF6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtOTYuNzA4Mzk4IDE0MC45MTA3NXEtMC43NDQxNCAwLjU5NTMxLTAuNzQ0MTQgMS43ODU5MyAwIDEuMTkwNjMgMC43NDQxNCAxLjU4NzUgMC42OTQ1MzEgMC4zOTY4OCAyLjE4MjgxMyAwLjM5Njg4IDEuNTEzMDg5IDAgMi4xMDgzOTktMC4zOTY4OCAwLjU3MDUxLTAuMzk2ODcgMC42NDQ5Mi0xLjU4NzUgMC4wNzQ0LTEuMTkwNjItMC42NDQ5Mi0xLjc4NTkzLTAuNzQ0MTQtMC41NzA1MS0yLjE1ODAwOS0wLjU3MDUxLTEuNDEzODY3IDAtMi4xMzMyMDMgMC41NzA1MXoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im0xMDMuNDgwMDggMTQwLjkxMDc1cS0wLjc0NDE0IDAuNTk1MzEtMC43NDQxNCAxLjc4NTkzIDAgMS4xOTA2MyAwLjc0NDE0IDEuNTg3NSAwLjcxOTMzIDAuMzk2ODggMi4xMzMyIDAuMzk2ODggMS40Mzg2NyAwIDIuMTU4MDEtMC4zOTY4OCAwLjY5NDUzLTAuMzk2ODcgMC43MTkzMy0xLjU4NzUgMC4wMjQ4LTEuMTkwNjItMC43MTkzMy0xLjc4NTkzLTAuNzQ0MTQtMC41NzA1MS0yLjE1ODAxLTAuNTcwNTEtMS4zODkwNiAwLTIuMTMzMiAwLjU3MDUxeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwNi43Mjk0OSAxMzUuODUwNTlxLTAuODE4NTUgMC41OTUzMS0wLjgxODU1IDEuNzExNTIgMCAxLjA5MTQxIDAuODE4NTUgMS42NjE5MiAwLjc2ODk1IDAuNTk1MzEgMi4yODIwMyAwLjU5NTMxIDEuNTEzMDkgMCAyLjMwNjg0LTAuNTk1MzEgMC43OTM3NS0wLjU3MDUxIDAuNzkzNzUtMS42NjE5MiAwLTEuMTE2MjEtMC43OTM3NS0xLjcxMTUyLTAuNzkzNzUtMC41NzA1MS0yLjMwNjg0LTAuNTcwNTEtMS41MTMwOCAwLTIuMjgyMDMgMC41NzA1MXoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im0xMDAuMDU3MDMgMTM1Ljg1MDU5cS0wLjc2ODk0NCAwLjU5NTMxLTAuNzY4OTQ0IDEuNzExNTIgMCAxLjA5MTQxIDAuNzY4OTQ0IDEuNjYxOTIgMC43NDQxNCAwLjU5NTMxIDIuMTU4MDEgMC41OTUzMSAxLjQzODY3IDAgMi4yMDc2Mi0wLjU5NTMxIDAuNzQ0MTQtMC41NzA1MSAwLjc0NDE0LTEuNjYxOTIgMC0xLjExNjIxLTAuNzQ0MTQtMS43MTE1Mi0wLjc2ODk1LTAuNTcwNTEtMi4yMDc2Mi0wLjU3MDUxLTEuNDEzODcgMC0yLjE1ODAxIDAuNTcwNTF6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtOTMuMTYxMzI4IDEzNS44NTA1OXEtMC44MTg1NTUgMC41OTUzMS0wLjgxODU1NSAxLjcxMTUyIDAgMS4wOTE0MSAwLjgxODU1NSAxLjY2MTkyIDAuNzY4OTQ1IDAuNTk1MzEgMi4yNTcyMjYgMC41OTUzMSAxLjUxMzA4NiAwIDIuMzMxNjQxLTAuNTk1MzEgMC43OTM3NS0wLjU3MDUxIDAuNzkzNzUtMS42NjE5MiAwLTEuMTE2MjEtMC43OTM3NS0xLjcxMTUyLTAuODE4NTU1LTAuNTcwNTEtMi4zMzE2NDEtMC41NzA1MS0xLjQ4ODI4MSAwLTIuMjU3MjI2IDAuNTcwNTF6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCTwvZz4NCgkJPGcgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIgYXJpYS1sYWJlbD0iciI+DQoJCQk8cGF0aCBkPSJtMTAyLjIzOTg0IDExMi4xMTI1aDMuNDIzMDV2My4zNzM0NGg1LjEzNDU3di0zLjM3MzQ0aDUuOTAzNTJ2OC44NTUyOGwtMy45OTM1NiA0LjYxMzY3cTEuMjg5ODUgMS42MzcxMSAwLjA0OTYgMy40NDc4NS0wLjE5ODQ0IDAuMzIyNDYtMC4xOTg0NCAwLjU5NTMxIDAgMC4zMjI0NiAwLjE5ODQ0IDAuNjIwMTIgMC41MjA5IDAuNzY4OTUgMC40OTYwOSAyLjE4MjgxIDAgMS4zODkwNi0wLjUyMDg5IDIuMTgyODEtMC4xNzM2NCAwLjI0ODA1LTAuMTczNjQgMC41MjA5IDAgMC4zNDcyNyAwLjIyMzI1IDAuNjQ0OTMgMS4xNjU4MiAxLjc2MTEzLTAuMDQ5NiAzLjQ3MjY1LTAuMTczNjQgMC4yOTc2Ni0wLjE3MzY0IDAuNTcwNTF0MC4xNzM2NCAwLjU3MDUxcTAuNTQ1NyAwLjgxODU1IDAuNTQ1NyAyLjI4MjAzIDAgMS40Mzg2Ny0wLjU5NTMxIDIuMTMzMmw0LjAxODM2IDIuMDA5MTh2Mi4xMzMyaDEuNjYxOTF2Ny4xOTMzNmgtMzIuMjcwODk4di03LjE2ODU1aDEuNjg2NzE5di0yLjEzMzJsMy45OTM1NTQtMi4wMzM5OXEtMC41OTUzMTItMC42OTQ1My0wLjU5NTMxMi0yLjEzMzJ0MC41NDU3MDMtMi4yNTcyM3EwLjE5ODQzOC0wLjI3Mjg1IDAuMTk4NDM4LTAuNTcwNTEgMC0wLjI0ODA0LTAuMTk4NDM4LTAuNTcwNS0xLjIxNTQzLTEuNzM2MzMtMC4wMjQ4MS0zLjQ3MjY2IDAuMjIzMjQzLTAuMzk2ODggMC4yMjMyNDMtMC42NDQ5MiAwLTAuMjQ4MDUtMC4xNzM2MzMtMC41NDU3MS0wLjU0NTcwMy0wLjc5Mzc1LTAuNTcwNTA4LTIuMTgyODEgMC0xLjQxMzg2IDAuNTIwODk4LTIuMTgyODEgMC4yMjMyNDMtMC4yOTc2NiAwLjIyMzI0My0wLjYyMDEyIDAtMC4yNzI4NS0wLjE5ODQzOC0wLjU3MDUtMS4yNjUwMzktMS44MTA3NSAwLjA0OTYxLTMuNDcyNjZsLTMuOTkzNTU0LTQuNTg4ODd2LTguODU1MjdoNS45MDM1MTV2My4zNDg2M2w1LjEwOTc2NiAwLjAyNDh2LTMuMzczNDR6bS05LjE1MjkyNiAxMi4yNTM1MnE0LjI0MTYwMS0wLjY2OTczIDkuMTUyOTI2LTAuNjY5NzMgNC45ODU3NSAwIDkuMjI3MzUgMC42Njk3M2wxLjQzODY3LTEuODEwNzRxLTUuMDYwMTYtMC44OTI5Ny0xMC42NjYwMi0wLjg5Mjk3LTUuNjU1NDY1IDAtMTAuNjkwODE3IDAuODkyOTd6bS01LjIzMzc4OSAyNi4yOTI5N3YzLjc5NTExaDI4Ljc0ODYzNXYtMy43OTUxMXptMTQuMzg2NzE1LTUuMDYwMTZxLTUuMTU5MzcyIDAtOS4zNTEzNjQgMC4zNDcyN2wtMy4zNDg2MzIgMS43ODU5M3YxLjI0MDI0aDI1LjM5OTk5NnYtMS4yNDAyNHEtMC44NDMzNi0wLjQ0NjQ4LTEuNjg2NzItMC44OTI5Ni0wLjg0MzM1LTAuNDQ2NDktMS42NjE5MS0wLjg5Mjk3LTQuNDY0ODQtMC4zNDcyNy05LjM1MTM3LTAuMzQ3Mjd6bTEyLjctMzEuNzk5NjFoLTIuNTU0ODh2My40NzI2NmgtOC40ODMydi0zLjQ0Nzg1aC0zLjM0ODY0djMuNDQ3ODVoLTguNDU4Mzk0di0zLjQ3MjY2aC0yLjU1NDg4MnEwIDEuNTg3NSAwIDMuMTc1IDAgMS41NjI3IDAgMy4xMjUzOSAzLjE3NS0wLjE5ODQzIDYuMzI1MTk1LTAuMzcyMDcgMy4xNzUtMC4xNzM2MyA2LjM3NDgwMS0wLjE3MzYzIDYuMDI3NTQgMCAxMi43IDAuNTQ1N3ptLTguMjEwMzUgMTEuODgxNDVxLTAuODE4NTUgMC41OTUzMS0wLjgxODU1IDEuNjg2NzIgMCAxLjA5MTQgMC44MTg1NSAxLjY4NjcyIDAuNzY4OTUgMC41OTUzMSAyLjI4MjAzIDAuNTk1MzEgMS41MTMwOSAwIDIuMzA2ODQtMC41OTUzMSAwLjc5Mzc1LTAuNTk1MzIgMC43OTM3NS0xLjY4NjcyIDAtMS4wOTE0MS0wLjc5Mzc1LTEuNjg2NzItMC43OTM3NS0wLjU3MDUxLTIuMzA2ODQtMC41NzA1MS0xLjUxMzA4IDAtMi4yODIwMyAwLjU3MDUxem0tNi42NzI0NiAwcS0wLjc2ODk0NCAwLjU5NTMxLTAuNzY4OTQ0IDEuNjg2NzIgMCAxLjA5MTQgMC43Njg5NDQgMS42ODY3MiAwLjc0NDE0IDAuNTk1MzEgMi4xNTgwMSAwLjU5NTMxIDEuNDM4NjcgMCAyLjIwNzYyLTAuNTk1MzEgMC43NDQxNC0wLjU5NTMyIDAuNzQ0MTQtMS42ODY3MiAwLTEuMDkxNDEtMC43NDQxNC0xLjY4NjcyLTAuNzY4OTUtMC41NzA1MS0yLjIwNzYyLTAuNTcwNTEtMS40MTM4NyAwLTIuMTU4MDEgMC41NzA1MXptLTYuODk1NzAyIDBxLTAuODE4NTU1IDAuNTk1MzEtMC44MTg1NTUgMS42ODY3MiAwIDEuMDkxNCAwLjgxODU1NSAxLjY4NjcyIDAuNzY4OTQ1IDAuNTk1MzEgMi4yNTcyMjYgMC41OTUzMSAxLjUxMzA4NiAwIDIuMzMxNjQxLTAuNTk1MzEgMC43OTM3NS0wLjU5NTMyIDAuNzkzNzUtMS42ODY3MiAwLTEuMDkxNDEtMC43OTM3NS0xLjY4NjcyLTAuODE4NTU1LTAuNTcwNTEtMi4zMzE2NDEtMC41NzA1MS0xLjQ4ODI4MSAwLTIuMjU3MjI2IDAuNTcwNTF6bTE2LjY2ODc1MiA1LjAzNTM1cS0wLjI5NzY2IDAuNTk1MzEtMC4yOTc2NiAxLjcxMTUyIDAgMS4wOTE0MSAwLjI5NzY2IDEuNjYxOTIgMC4yNzI4NSAwLjU5NTMxIDAuODY4MTYgMC41OTUzMXQwLjg5Mjk3LTAuNTk1MzFxMC4yOTc2Ni0wLjU3MDUxIDAuMjk3NjYtMS42NjE5MiAwLTEuMTE2MjEtMC4yOTc2Ni0xLjcxMTUyLTAuMjk3NjYtMC41NDU3LTAuODkyOTctMC41NDU3dC0wLjg2ODE2IDAuNTQ1N3ptLTYuMzUgMHEtMC43NDQxNCAwLjU5NTMxLTAuNzQ0MTQgMS43MTE1MiAwIDEuMDkxNDEgMC43NDQxNCAxLjY2MTkyIDAuNzQ0MTQgMC41OTUzMSAyLjEzMzIgMC41OTUzMSAxLjQxMzg3IDAgMi4xNTgwMS0wLjU5NTMxIDAuNzQ0MTQtMC41NzA1MSAwLjc0NDE0LTEuNjYxOTIgMC0xLjExNjIxLTAuNzQ0MTQtMS43MTE1Mi0wLjc0NDE0LTAuNTcwNTEtMi4xNTgwMS0wLjU3MDUxLTEuMzg5MDYgMC0yLjEzMzIgMC41NzA1MXptLTYuNzcxNjgyIDBxLTAuNzQ0MTQgMC41OTUzMS0wLjc0NDE0IDEuNzExNTIgMCAxLjA5MTQxIDAuNzQ0MTQgMS42NjE5MiAwLjcxOTMzNiAwLjU5NTMxIDIuMTMzMjAzIDAuNTk1MzEgMS40MTM4NjkgMCAyLjE1ODAwOS0wLjU5NTMxIDAuNzE5MzMtMC41NzA1MSAwLjcxOTMzLTEuNjYxOTIgMC0xLjExNjIxLTAuNzE5MzMtMS43MTE1Mi0wLjc0NDE0LTAuNTcwNTEtMi4xNTgwMDktMC41NzA1MS0xLjQxMzg2NyAwLTIuMTMzMjAzIDAuNTcwNTF6bS0zLjgxOTkyMiAwcS0wLjI5NzY1NiAwLjU5NTMxLTAuMjk3NjU2IDEuNzExNTIgMCAxLjA5MTQxIDAuMjk3NjU2IDEuNjYxOTIgMC4yOTc2NTcgMC41OTUzMSAwLjg2ODE2NCAwLjU5NTMxIDAuNTk1MzEzIDAgMC44OTI5NjktMC41OTUzMSAwLjI5NzY1Ni0wLjU3MDUxIDAuMjk3NjU2LTEuNjYxOTIgMC0xLjExNjIxLTAuMjk3NjU2LTEuNzExNTItMC4yOTc2NTYtMC41NDU3LTAuODkyOTY5LTAuNTQ1Ny0wLjU3MDUwNyAwLTAuODY4MTY0IDAuNTQ1N3ptMTYuOTQxNjA0IDEwLjE5NDczcS0wLjI5NzY2IDAuNTcwNS0wLjI5NzY2IDEuNjg2NzEgMCAxLjExNjIyIDAuMjk3NjYgMS42ODY3MiAwLjI3Mjg1IDAuNTcwNTEgMC44NjgxNiAwLjU3MDUxdDAuODkyOTctMC41NzA1MXEwLjI5NzY2LTAuNTcwNSAwLjI5NzY2LTEuNjg2NzIgMC0xLjExNjIxLTAuMjk3NjYtMS42ODY3MS0wLjI5NzY2LTAuNTQ1NzEtMC44OTI5Ny0wLjU0NTcxdC0wLjg2ODE2IDAuNTQ1NzF6bS0xNi45NDE2MDQgMHEtMC4yOTc2NTYgMC41NzA1LTAuMjk3NjU2IDEuNjg2NzEgMCAxLjExNjIyIDAuMjk3NjU2IDEuNjg2NzIgMC4yOTc2NTcgMC41NzA1MSAwLjg2ODE2NCAwLjU3MDUxIDAuNTk1MzEzIDAgMC44OTI5NjktMC41NzA1MSAwLjI5NzY1Ni0wLjU3MDUgMC4yOTc2NTYtMS42ODY3MiAwLTEuMTE2MjEtMC4yOTc2NTYtMS42ODY3MS0wLjI5NzY1Ni0wLjU0NTcxLTAuODkyOTY5LTAuNTQ1NzEtMC41NzA1MDcgMC0wLjg2ODE2NCAwLjU0NTcxem0zLjgxOTkyMiAwcS0wLjc0NDE0IDAuNTk1MzEtMC43NDQxNCAxLjc4NTkzIDAgMS4xOTA2MyAwLjc0NDE0IDEuNTg3NSAwLjY5NDUzMSAwLjM5Njg4IDIuMTgyODEzIDAuMzk2ODggMS41MTMwODkgMCAyLjEwODM5OS0wLjM5Njg4IDAuNTcwNTEtMC4zOTY4NyAwLjY0NDkyLTEuNTg3NSAwLjA3NDQtMS4xOTA2Mi0wLjY0NDkyLTEuNzg1OTMtMC43NDQxNC0wLjU3MDUxLTIuMTU4MDA5LTAuNTcwNTEtMS40MTM4NjcgMC0yLjEzMzIwMyAwLjU3MDUxem02Ljc3MTY4MiAwcS0wLjc0NDE0IDAuNTk1MzEtMC43NDQxNCAxLjc4NTkzIDAgMS4xOTA2MyAwLjc0NDE0IDEuNTg3NSAwLjcxOTMzIDAuMzk2ODggMi4xMzMyIDAuMzk2ODggMS40Mzg2NyAwIDIuMTU4MDEtMC4zOTY4OCAwLjY5NDUzLTAuMzk2ODcgMC43MTkzMy0xLjU4NzUgMC4wMjQ4LTEuMTkwNjItMC43MTkzMy0xLjc4NTkzLTAuNzQ0MTQtMC41NzA1MS0yLjE1ODAxLTAuNTcwNTEtMS4zODkwNiAwLTIuMTMzMiAwLjU3MDUxem0zLjI0OTQxLTUuMDYwMTZxLTAuODE4NTUgMC41OTUzMS0wLjgxODU1IDEuNzExNTIgMCAxLjA5MTQxIDAuODE4NTUgMS42NjE5MiAwLjc2ODk1IDAuNTk1MzEgMi4yODIwMyAwLjU5NTMxIDEuNTEzMDkgMCAyLjMwNjg0LTAuNTk1MzEgMC43OTM3NS0wLjU3MDUxIDAuNzkzNzUtMS42NjE5MiAwLTEuMTE2MjEtMC43OTM3NS0xLjcxMTUyLTAuNzkzNzUtMC41NzA1MS0yLjMwNjg0LTAuNTcwNTEtMS41MTMwOCAwLTIuMjgyMDMgMC41NzA1MXptLTYuNjcyNDYgMHEtMC43Njg5NDQgMC41OTUzMS0wLjc2ODk0NCAxLjcxMTUyIDAgMS4wOTE0MSAwLjc2ODk0NCAxLjY2MTkyIDAuNzQ0MTQgMC41OTUzMSAyLjE1ODAxIDAuNTk1MzEgMS40Mzg2NyAwIDIuMjA3NjItMC41OTUzMSAwLjc0NDE0LTAuNTcwNTEgMC43NDQxNC0xLjY2MTkyIDAtMS4xMTYyMS0wLjc0NDE0LTEuNzExNTItMC43Njg5NS0wLjU3MDUxLTIuMjA3NjItMC41NzA1MS0xLjQxMzg3IDAtMi4xNTgwMSAwLjU3MDUxem0tNi44OTU3MDIgMHEtMC44MTg1NTUgMC41OTUzMS0wLjgxODU1NSAxLjcxMTUyIDAgMS4wOTE0MSAwLjgxODU1NSAxLjY2MTkyIDAuNzY4OTQ1IDAuNTk1MzEgMi4yNTcyMjYgMC41OTUzMSAxLjUxMzA4NiAwIDIuMzMxNjQxLTAuNTk1MzEgMC43OTM3NS0wLjU3MDUxIDAuNzkzNzUtMS42NjE5MiAwLTEuMTE2MjEtMC43OTM3NS0xLjcxMTUyLTAuODE4NTU1LTAuNTcwNTEtMi4zMzE2NDEtMC41NzA1MS0xLjQ4ODI4MSAwLTIuMjU3MjI2IDAuNTcwNTF6IiBzdHJva2Utd2lkdGg9Ii4yNjQ1ODMzMiIvPg0KCQk8L2c+DQoJPC9nPg0KPC9zdmc+DQo=')} +.is2d .queen.white {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjUwLjgwMDAwN21tIiBoZWlnaHQ9IjUwLjc3NTIwOG1tIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1MC44MDAwMDcgNTAuNzc1MjA4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC03MS4xNjA1MTUsLTk5LjA5MjkxNCkiPg0KCQk8ZyBmaWxsPSIjZmZmIj4NCgkJCTxwYXRoIGQ9Im04Ni4zNjUzMDcgMTI2LjQ1MjU0cS0wLjY5NDUzMS0wLjU5NTMxLTIuMTMzMjAzLTIuMzU2NDUtMi41MDUyNzMtMi44Mjc3My0yLjgwMjkyOS0yLjgyNzczLTAuMjQ4MDQ3IDAtMC4yNDgwNDcgMC4zNDcyNyAwIDAuNDQ2NDggMC43OTM3NSAxLjgxMDc0IDAuNjk0NTMxIDEuOTU5NTcgMS4xNDEwMTUgMy41OTY2OCAxLjExNjIxMS0wLjIyMzI0IDMuMjQ5NDE0LTAuNTcwNTF6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtOTIuMjE5MjE0IDEyNS45NTY0NXEtMC42NDQ5MjItMC41NDU3MS0xLjI0MDIzNS0xLjgxMDc1LTAuNzE5MzM2LTEuNDYzNDctMS43MzYzMjgtNC41MzkyNS0wLjM5Njg3NS0xLjIxNTQzLTAuNzQ0MTQxLTIuMDU4NzktMC4zNDcyNjUtMC44NDMzNi0wLjQ5NjA5My0wLjgxODU2LTAuMDc0NDEgMC4wMjQ4LTAuMDc0NDEgMC4zOTY4OCAwLjAyNDggMC4zNzIwNyAwLjAyNDggMC41OTUzMSAwIDAuNjY5NzMgMC42MjAxMTggMy4zOTgyNCAwLjU5NTMxMiAyLjgyNzc0IDAuNTk1MzEyIDQuMDQzMTcgMC4wMjQ4MSAwLjc0NDE0LTAuMTQ4ODI4IDEuMDY2NiAxLjI4OTg0NC0wLjE3MzY0IDMuMTk5ODA1LTAuMjcyODV6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtOTguNTk0MDE4IDEyNS44ODIwNXEtMC43MTkzMzYtMC44MTg1NS0wLjk0MjU3OC0yLjc1MzMyLTAuMDk5MjItMC43Njg5NC0wLjI3Mjg1Mi0yLjIwNzYyLTAuMTQ4ODI4LTEuNDYzNDctMC4yMjMyNDItMy42MjE0OC0wLjA3NDQxLTEuNTYyNy0wLjI0ODA0Ny0yLjcwMzcxLTAuMTczNjMyLTEuMTQxMDItMC4zNDcyNjUtMS4xOTA2My0wLjE5ODQzOCAwLjA0OTYtMC4zNDcyNjYgMS4xOTA2My0wLjEyNDAyMyAxLjE0MTAxLTAuMTk4NDM3IDIuNzAzNzEtMC4xMjQwMjQgMi4xNTgwMS0wLjI5NzY1NyAzLjYyMTQ4LTAuMTczNjMyIDEuNDM4NjgtMC4yNDgwNDYgMi4yMDc2Mi0wLjIyMzI0MyAyLjA4MzYtMC45NDI1NzkgMi43NTMzMiAwLjQ5NjA5NCAwIDAuOTkyMTg4LTAuMDc0NCAwLjUyMDg5OC0wLjA5OTIgMS4wNDE3OTctMC4wOTkyIDAuNTIwODk4IDAgMS4wMTY5OTIgMC4wOTkyIDAuNTIwODk4IDAuMDc0NCAxLjAxNjk5MiAwLjA3NDR6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtMTA0LjEyNTQ2IDEyNi4yMDQ1MXEtMC4xNzM2My0wLjM3MjA3LTAuMTczNjMtMS4wNDE3OSAwLTEuMjY1MDQgMC42MjAxMi00LjA0MzE3IDAuNTk1MzEtMi43NzgxMiAwLjU5NTMxLTMuMzk4MjQgMC0wLjc5Mzc1LTAuMDI0OC0wLjgxODU2LTAuMzQ3MjctMC4wNzQ0LTEuMjY1MDQgMi43MDM3Mi0wLjk0MjU4IDIuODc3MzQtMS43MzYzMyA0LjUzOTI1LTAuNTcwNTEgMS4xOTA2My0xLjIxNTQzIDEuODM1NTUgMS4xNjU4MiAwLjA0OTYgMy4xOTk4IDAuMjIzMjR6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtMTEwLjA3ODU5IDEyNy4wMjMwN3EwLjIyMzI0LTAuOTE3NzggMC40OTYwOS0xLjgxMDc0IDAuMjk3NjYtMC45MTc3OCAwLjU5NTMxLTEuODEwNzUgMC43OTM3NS0xLjQ2MzQ3IDAuNzkzNzUtMS43ODU5MyAwLTAuMzQ3MjctMC4yNDgwNC0wLjM0NzI3LTAuMzk2ODggMC0yLjgwMjkzIDIuODAyOTMtMC43NDQxNCAwLjg2ODE2LTEuMjY1MDQgMS40ODgyOC0wLjUyMDkgMC41OTUzMS0wLjg2ODE3IDAuOTQyNTggMS42ODY3MiAwLjIyMzI0IDMuMjk5MDMgMC41MjA5eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTc3LjY4MzY2NyAxMTQuMjk4MjRxLTEuNjYxOTE0IDAtMS42NjE5MTQgMS42NjE5MiAwIDEuNjg2NzIgMS42NjE5MTQgMS42ODY3MiAxLjY4NjcxOSAwIDEuNjg2NzE5LTEuNjg2NzIgMC0xLjY2MTkyLTEuNjg2NzE5LTEuNjYxOTJ6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtOTcuNzc1NDYzIDEwOC4xOTYyOXEwLjM3MjA3MSA0LjAxODM2IDAuNzQ0MTQxIDguMDM2NzIgMC4zOTY4NzUgMy45OTM1NSAwLjc5Mzc1IDcuOTg3MTEgMC4wMjQ4MSAwLjU3MDUxIDAuNTcwNTA4IDAuNTcwNTEgMC4zOTY4NzgtMC4wMjQ4IDAuNTQ1Njk4LTAuMzQ3MjcgMi4xNTgwMS01LjIwODk4IDMuMTc1LTguMDYxNTIgMS4wNDE4LTIuODc3MzUgMS4yNjUwNC0zLjU0NzA3LTEuMTQxMDEtMS4wOTE0MS0xLjE0MTAxLTIuNDU1NjcgMC0xLjE5MDYyIDAuODQzMzYtMi4wMzM5OCAwLjg2ODE2LTAuODY4MTcgMi4wODM1OS0wLjg2ODE3IDEuMTkwNjMgMCAyLjAzMzk5IDAuODY4MTcgMC44NjgxNiAwLjg0MzM2IDAuODY4MTYgMi4wMzM5OCAwIDIuMTU4MDEtMi4yMzI0MiAyLjkyNjk2bC0xLjgxMDc0IDEwLjgxNDg0cS0wLjEyNDAzIDAuNzQ0MTQgMC41MjA4OSAwLjc0NDE0IDAuNTIwOSAwIDAuNzkzNzUtMC4yNzI4NSAyLjk3NjU3LTIuOTc2NTYgNC4yNjY0MS00LjYxMzY3IDEuMzE0NjUtMS42MzcxMSAxLjgzNTU1LTIuMjgyMDQtMC41NDU3MS0wLjcxOTMzLTAuNTQ1NzEtMS43MzYzMiAwLTIuOTAyMTUgMi45MDIxNS0yLjkwMjE1IDEuMTkwNjMgMCAyLjAzMzk5IDAuODY4MTYgMC44NjgxNiAwLjg0MzM2IDAuODY4MTYgMi4wMzM5OSAwIDEuMjE1NDMtMC44NjgxNiAyLjA1ODc5LTAuODQzMzYgMC44NDMzNi0yLjAzMzk5IDAuODQzMzYtMC4zNzIwNyAwLTAuNjY5NzItMC4wNzQ0LTEuOTg0MzggNC4yOTEyMS0zLjE3NSA4Ljc4MDg2LTEuMDE3IDMuNjQ2MjktMS4yNjUwNCA2LjkyMDUxIDAuMTQ4ODMgMC42OTQ1MyAwLjE3MzYzIDAuNzE5MzMtMC4wNzQ0LTAuMjk3NjUgMC4wOTkyIDAuNTcwNTEgMC4wOTkyIDAuMzk2ODggMC4wOTkyIDAuNzY4OTUtMC4xNDg4MyAwLjM5Njg3LTAuNjIwMTIgMC44OTI5Ny0wLjQyMTY4IDAuNDcxMjgtMC42MjAxMiAxLjg2MDM1IDAuOTE3NzggMS4yODk4NCAwLjkxNzc4IDIuMDgzNTkgMCAyLjA4MzU5LTQuMDE4MzYgMy41NzE4OC00LjAxODM2IDEuNDg4MjgtOS42NDkwMjYgMS40ODgyOC01LjY1NTQ2OSAwLTkuNjczODI4LTEuNDg4MjgtMy45OTM1NTUtMS40ODgyOS0zLjk5MzU1NS0zLjU3MTg4IDAtMC44MTg1NSAwLjk2NzM4My0yLjEzMzItMC4yOTc2NTYtMS40MTM4Ny0wLjY0NDkyMi0xLjgxMDc0LTAuNDk2MDk0LTAuNDk2MS0wLjY0NDkyMi0wLjg5Mjk3IDAtMC4zMjI0NiAwLjA3NDQxLTAuNzQ0MTQgMC4wNDk2MS0wLjE5ODQ0IDAuMDc0NDEtMC4zNDcyNyAwLjAyNDgxLTAuMTczNjMgMC4wNDk2MS0wLjI0ODA1IDAuMDk5MjItMC4yNzI4NSAwLjE5ODQzNy0wLjc2ODk0LTAuMjQ4MDQ3LTMuMTI1MzktMS4yMTU0MjktNi44NzA5LTEuMjg5ODQ0LTQuNzEyODktMy4xOTk4MDUtOC44MzA0Ny0wLjQyMTY4IDAuMTI0MDMtMC44NjgxNjQgMC4xMjQwMy0yLjkwMjE0OCAwLTIuOTAyMTQ4LTIuOTAyMTV0Mi45MDIxNDgtMi45MDIxNSAyLjkwMjE0OCAyLjkwMjE1cTAgMC44OTI5Ny0wLjQ0NjQ4NCAxLjYxMjMgMS40NjM0NzYgMS44NjAzNSAyLjkyNjk1MyAzLjQ3MjY2IDEuNDg4MjgxIDEuNTg3NSAzLjI3NDIxOSAzLjQ5NzQ2IDAuMjIzMjQyIDAuMzIyNDYgMC42NDQ5MjIgMC4zMjI0NiAwLjcxOTMzNSAwIDAuNjQ0OTIxLTAuNzQ0MTQtMC4wNDk2MS0wLjIyMzI0LTAuNjIwMTE3LTMuNTQ3MDctMC41NzA1MDgtMy4zMjM4My0xLjI0MDIzNC03LjI0Mjk3LTIuMzU2NDQ1LTAuNjQ0OTItMi4zNTY0NDUtMi45NTE3NiAwLTEuMTkwNjIgMC44NDMzNTktMi4wMzM5OCAwLjg2ODE2NC0wLjg2ODE3IDIuMDU4Nzg5LTAuODY4MTcgMi45MDIxNDggMCAyLjkwMjE0OCAyLjkwMjE1IDAgMS4yODk4NS0wLjk5MjE4NyAyLjM1NjQ1IDAuMTI0MDIzIDAuNTIwOSAwLjYyMDExNyAyLjA4MzU5IDAuNDk2MDk0IDEuNTM3ODkgMS41Mzc4OTEgNC4wNjc5NyAwLjU3MDUwOCAxLjM4OTA2IDEuMTQxMDE1IDIuODAyOTMgMC41OTUzMTMgMS4zODkwNiAxLjE5MDYyNSAyLjc1MzMyIDAuMTQ4ODI4IDAuMzIyNDYgMC41MjA4OTkgMC4zMjI0NiAwLjUyMDg5OC0wLjAyNDggMC41OTUzMTItMC41NDU3IDAuMDQ5NjEtMC4yOTc2NiAxLjUxMzA4Ni0xNS45OTkwMy0xLjc2MTEzMy0wLjk0MjU3LTEuNzYxMTMzLTIuODAyOTMgMC0xLjE5MDYyIDAuODQzMzYtMi4wNTg3OCAwLjg0MzM1OS0wLjg2ODE3IDIuMDU4Nzg5LTAuODY4MTcgMS4xOTA2MjUgMCAyLjAzMzk4NCAwLjg2ODE3IDAuODY4MTY0IDAuODY4MTYgMC44NjgxNjQgMi4wNTg3OCAwIDEuNjg2NzItMS42MTIzMDUgMi43NzgxM3oiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im05MS4wNzgxOTggMTMzLjg0NDM0cS0xLjMxNDY0OCAwLTEuMzE0NjQ4IDEuMzg5MDZ0MS4zMTQ2NDggMS4zODkwNnExLjMzOTQ1MyAwIDEuMzM5NDUzLTEuMzg5MDZ0LTEuMzM5NDUzLTEuMzg5MDZ6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtODMuNTEyNzY4IDEyOC44ODM0cTAuMjk3NjU3IDEuMjE1NDMgMC41MjA4OTkgMi4yMDc2MiAwLjI0ODA0NyAwLjk2NzM4IDAuNDIxNjc5IDIuMTA4MzkgMC4xOTg0MzggMC4wOTkyIDAuNDQ2NDg1IDAuMDk5MiA0LjQxNTIzNC0xLjY2MTkxIDExLjYzMzM5OC0xLjY2MTkxIDcuMzE3MzgxIDAgMTEuODMxODMxIDEuNjg2NzIgMC4yNDgwNS0wLjA0OTYgMC4zNzIwOC0wLjEyNDAzIDAuMTQ4ODItMS4xMTYyMSAwLjM5Njg3LTIuMDMzOTggMC4yNDgwNS0wLjk0MjU4IDAuNTQ1Ny0yLjE4MjgxLTIuODI3NzMtMC43OTM3NS02LjE3NjM2LTEuMzE0NjUtMy4zNDg2NC0wLjU0NTctNi45NDUzMTYtMC41NDU3LTMuNTk2NjggMC02Ljg3MDg5OSAwLjUyMDg5LTMuMjc0MjE4IDAuNTIwOS02LjE3NjM2NyAxLjI0MDI0eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwOC40MTY2NyAxMzYuMzk5MjItMS43ODU5My0xLjcxMTUyLTIuMjgyMDMgMC45MTc3NyAxLjgxMDc0IDEuNzExNTJ6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtOTkuNzEwMjI5IDEzNC42MzgwOS0zLjE5OTgwNS0xLjY2MTkyLTMuMDc1NzgxIDEuNjYxOTIgMy4xOTk4MDUgMS42ODY3MXoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im04OC45OTQ2MDQgMTM1LjYzMDI3LTIuNTA1MjczLTAuODQzMzYtMS45ODQzNzUgMS41NjI3IDIuNDgwNDY5IDAuODQzMzZ6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtMTE1LjI4NzU3IDExNC4yOTgyNHEtMS42ODY3MiAwLTEuNjg2NzIgMS42NjE5MiAwIDEuNjg2NzIgMS42ODY3MiAxLjY4NjcyIDEuNjYxOTIgMCAxLjY2MTkyLTEuNjg2NzIgMC0xLjY2MTkyLTEuNjYxOTItMS42NjE5MnoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im04Ni4zMTU2OTggMTA4LjY5MjM4cS0xLjY2MTkxNCAwLTEuNjYxOTE0IDEuNjg2NzIgMCAxLjY2MTkyIDEuNjYxOTE0IDEuNjYxOTIgMS42ODY3MTkgMCAxLjY4NjcxOS0xLjY2MTkyIDAtMS42ODY3Mi0xLjY4NjcxOS0xLjY4NjcyeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTk2LjQ4NTYyIDEwMy43MzE0NXEtMS42NjE5MTQgMC0xLjY2MTkxNCAxLjY4NjcxIDAgMS42NjE5MiAxLjY2MTkxNCAxLjY2MTkydDEuNjYxOTE0LTEuNjYxOTJxMC0xLjY4NjcxLTEuNjYxOTE0LTEuNjg2NzF6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtMTA2LjY1NTU0IDEwOC42OTIzOHEtMS42ODY3MiAwLTEuNjg2NzIgMS42ODY3MiAwIDEuNjYxOTIgMS42ODY3MiAxLjY2MTkyIDEuNjYxOTIgMCAxLjY2MTkyLTEuNjYxOTIgMC0xLjY4NjcyLTEuNjYxOTItMS42ODY3MnoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im0xMDIuMDE3MDYgMTMzLjg0NDM0cS0xLjMxNDY0IDAtMS4zMTQ2NCAxLjM4OTA2dDEuMzE0NjQgMS4zODkwNnExLjMzOTQ2IDAgMS4zMzk0Ni0xLjM4OTA2dC0xLjMzOTQ2LTEuMzg5MDZ6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtOTYuNTYwMDM0IDEzOC4yODQzOHEtNC43MTI4OTEgMC04LjAxMTkxNCAwLjcxOTMzLTMuMjc0MjE5IDAuNzE5MzQtMy4yNzQyMTkgMi4wNTg3OSAwIDEuMzg5MDYgMy4yNzQyMTkgMi4yMzI0MiAzLjI5OTAyMyAwLjg0MzM2IDguMDExOTE0IDAuODQzMzYgNC42ODgwODYgMCA4LjA2MTUyNi0wLjg0MzM2IDMuMzk4MjQtMC44NDMzNiAzLjM5ODI0LTIuMjMyNDIgMC0xLjMzOTQ1LTMuMzk4MjQtMi4wNTg3OS0zLjM3MzQ0LTAuNzE5MzMtOC4wNjE1MjYtMC43MTkzM3oiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJPC9nPg0KCQk8ZyBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIiBhcmlhLWxhYmVsPSJxIj4NCgkJCTxwYXRoIGQ9Im04Ni4zNjUzMDcgMTI2LjQ1MjU0cS0wLjY5NDUzMS0wLjU5NTMxLTIuMTMzMjAzLTIuMzU2NDUtMi41MDUyNzMtMi44Mjc3My0yLjgwMjkyOS0yLjgyNzczLTAuMjQ4MDQ3IDAtMC4yNDgwNDcgMC4zNDcyNyAwIDAuNDQ2NDggMC43OTM3NSAxLjgxMDc0IDAuNjk0NTMxIDEuOTU5NTcgMS4xNDEwMTUgMy41OTY2OCAxLjExNjIxMS0wLjIyMzI0IDMuMjQ5NDE0LTAuNTcwNTF6bTUuODUzOTA3LTAuNDk2MDlxLTAuNjQ0OTIyLTAuNTQ1NzEtMS4yNDAyMzUtMS44MTA3NS0wLjcxOTMzNi0xLjQ2MzQ3LTEuNzM2MzI4LTQuNTM5MjUtMC4zOTY4NzUtMS4yMTU0My0wLjc0NDE0MS0yLjA1ODc5LTAuMzQ3MjY1LTAuODQzMzYtMC40OTYwOTMtMC44MTg1Ni0wLjA3NDQxIDAuMDI0OC0wLjA3NDQxIDAuMzk2ODggMC4wMjQ4IDAuMzcyMDcgMC4wMjQ4IDAuNTk1MzEgMCAwLjY2OTczIDAuNjIwMTE4IDMuMzk4MjQgMC41OTUzMTIgMi44Mjc3NCAwLjU5NTMxMiA0LjA0MzE3IDAuMDI0ODEgMC43NDQxNC0wLjE0ODgyOCAxLjA2NjYgMS4yODk4NDQtMC4xNzM2NCAzLjE5OTgwNS0wLjI3Mjg1em02LjM3NDgwNC0wLjA3NDRxLTAuNzE5MzM2LTAuODE4NTUtMC45NDI1NzgtMi43NTMzMi0wLjA5OTIyLTAuNzY4OTQtMC4yNzI4NTItMi4yMDc2Mi0wLjE0ODgyOC0xLjQ2MzQ3LTAuMjIzMjQyLTMuNjIxNDgtMC4wNzQ0MS0xLjU2MjctMC4yNDgwNDctMi43MDM3MS0wLjE3MzYzMi0xLjE0MTAyLTAuMzQ3MjY1LTEuMTkwNjMtMC4xOTg0MzggMC4wNDk2LTAuMzQ3MjY2IDEuMTkwNjMtMC4xMjQwMjMgMS4xNDEwMS0wLjE5ODQzNyAyLjcwMzcxLTAuMTI0MDI0IDIuMTU4MDEtMC4yOTc2NTcgMy42MjE0OC0wLjE3MzYzMiAxLjQzODY4LTAuMjQ4MDQ2IDIuMjA3NjItMC4yMjMyNDMgMi4wODM2LTAuOTQyNTc5IDIuNzUzMzIgMC40OTYwOTQgMCAwLjk5MjE4OC0wLjA3NDQgMC41MjA4OTgtMC4wOTkyIDEuMDQxNzk3LTAuMDk5MiAwLjUyMDg5OCAwIDEuMDE2OTkyIDAuMDk5MiAwLjUyMDg5OCAwLjA3NDQgMS4wMTY5OTIgMC4wNzQ0em01LjUzMTQ0MiAwLjMyMjQ2cS0wLjE3MzYzLTAuMzcyMDctMC4xNzM2My0xLjA0MTc5IDAtMS4yNjUwNCAwLjYyMDEyLTQuMDQzMTcgMC41OTUzMS0yLjc3ODEyIDAuNTk1MzEtMy4zOTgyNCAwLTAuNzkzNzUtMC4wMjQ4LTAuODE4NTYtMC4zNDcyNy0wLjA3NDQtMS4yNjUwNCAyLjcwMzcyLTAuOTQyNTggMi44NzczNC0xLjczNjMzIDQuNTM5MjUtMC41NzA1MSAxLjE5MDYzLTEuMjE1NDMgMS44MzU1NSAxLjE2NTgyIDAuMDQ5NiAzLjE5OTggMC4yMjMyNHptNS45NTMxMyAwLjgxODU2cTAuMjIzMjQtMC45MTc3OCAwLjQ5NjA5LTEuODEwNzQgMC4yOTc2Ni0wLjkxNzc4IDAuNTk1MzEtMS44MTA3NSAwLjc5Mzc1LTEuNDYzNDcgMC43OTM3NS0xLjc4NTkzIDAtMC4zNDcyNy0wLjI0ODA0LTAuMzQ3MjctMC4zOTY4OCAwLTIuODAyOTMgMi44MDI5My0wLjc0NDE0IDAuODY4MTYtMS4yNjUwNCAxLjQ4ODI4LTAuNTIwOSAwLjU5NTMxLTAuODY4MTcgMC45NDI1OCAxLjY4NjcyIDAuMjIzMjQgMy4yOTkwMyAwLjUyMDl6bS0zMi4zOTQ5MjMtMTIuNzI0ODNxLTEuNjYxOTE0IDAtMS42NjE5MTQgMS42NjE5MiAwIDEuNjg2NzIgMS42NjE5MTQgMS42ODY3MiAxLjY4NjcxOSAwIDEuNjg2NzE5LTEuNjg2NzIgMC0xLjY2MTkyLTEuNjg2NzE5LTEuNjYxOTJ6bTIwLjA5MTc5Ni02LjEwMTk1cTAuMzcyMDcxIDQuMDE4MzYgMC43NDQxNDEgOC4wMzY3MiAwLjM5Njg3NSAzLjk5MzU1IDAuNzkzNzUgNy45ODcxMSAwLjAyNDgxIDAuNTcwNTEgMC41NzA1MDggMC41NzA1MSAwLjM5Njg3OC0wLjAyNDggMC41NDU2OTgtMC4zNDcyNyAyLjE1ODAxLTUuMjA4OTggMy4xNzUtOC4wNjE1MiAxLjA0MTgtMi44NzczNSAxLjI2NTA0LTMuNTQ3MDctMS4xNDEwMS0xLjA5MTQxLTEuMTQxMDEtMi40NTU2NyAwLTEuMTkwNjIgMC44NDMzNi0yLjAzMzk4IDAuODY4MTYtMC44NjgxNyAyLjA4MzU5LTAuODY4MTcgMS4xOTA2MyAwIDIuMDMzOTkgMC44NjgxNyAwLjg2ODE2IDAuODQzMzYgMC44NjgxNiAyLjAzMzk4IDAgMi4xNTgwMS0yLjIzMjQyIDIuOTI2OTZsLTEuODEwNzQgMTAuODE0ODRxLTAuMTI0MDMgMC43NDQxNCAwLjUyMDg5IDAuNzQ0MTQgMC41MjA5IDAgMC43OTM3NS0wLjI3Mjg1IDIuOTc2NTctMi45NzY1NiA0LjI2NjQxLTQuNjEzNjcgMS4zMTQ2NS0xLjYzNzExIDEuODM1NTUtMi4yODIwNC0wLjU0NTcxLTAuNzE5MzMtMC41NDU3MS0xLjczNjMyIDAtMi45MDIxNSAyLjkwMjE1LTIuOTAyMTUgMS4xOTA2MyAwIDIuMDMzOTkgMC44NjgxNiAwLjg2ODE2IDAuODQzMzYgMC44NjgxNiAyLjAzMzk5IDAgMS4yMTU0My0wLjg2ODE2IDIuMDU4NzktMC44NDMzNiAwLjg0MzM2LTIuMDMzOTkgMC44NDMzNi0wLjM3MjA3IDAtMC42Njk3Mi0wLjA3NDQtMS45ODQzOCA0LjI5MTIxLTMuMTc1IDguNzgwODYtMS4wMTcgMy42NDYyOS0xLjI2NTA0IDYuOTIwNTEgMC4xNDg4MyAwLjY5NDUzIDAuMTczNjMgMC43MTkzMy0wLjA3NDQtMC4yOTc2NSAwLjA5OTIgMC41NzA1MSAwLjA5OTIgMC4zOTY4OCAwLjA5OTIgMC43Njg5NS0wLjE0ODgzIDAuMzk2ODctMC42MjAxMiAwLjg5Mjk3LTAuNDIxNjggMC40NzEyOC0wLjYyMDEyIDEuODYwMzUgMC45MTc3OCAxLjI4OTg0IDAuOTE3NzggMi4wODM1OSAwIDIuMDgzNTktNC4wMTgzNiAzLjU3MTg4LTQuMDE4MzYgMS40ODgyOC05LjY0OTAyNiAxLjQ4ODI4LTUuNjU1NDY5IDAtOS42NzM4MjgtMS40ODgyOC0zLjk5MzU1NS0xLjQ4ODI5LTMuOTkzNTU1LTMuNTcxODggMC0wLjgxODU1IDAuOTY3MzgzLTIuMTMzMi0wLjI5NzY1Ni0xLjQxMzg3LTAuNjQ0OTIyLTEuODEwNzQtMC40OTYwOTQtMC40OTYxLTAuNjQ0OTIyLTAuODkyOTcgMC0wLjMyMjQ2IDAuMDc0NDEtMC43NDQxNCAwLjA0OTYxLTAuMTk4NDQgMC4wNzQ0MS0wLjM0NzI3IDAuMDI0ODEtMC4xNzM2MyAwLjA0OTYxLTAuMjQ4MDUgMC4wOTkyMi0wLjI3Mjg1IDAuMTk4NDM3LTAuNzY4OTQtMC4yNDgwNDctMy4xMjUzOS0xLjIxNTQyOS02Ljg3MDktMS4yODk4NDQtNC43MTI4OS0zLjE5OTgwNS04LjgzMDQ3LTAuNDIxNjggMC4xMjQwMy0wLjg2ODE2NCAwLjEyNDAzLTIuOTAyMTQ4IDAtMi45MDIxNDgtMi45MDIxNXQyLjkwMjE0OC0yLjkwMjE1IDIuOTAyMTQ4IDIuOTAyMTVxMCAwLjg5Mjk3LTAuNDQ2NDg0IDEuNjEyMyAxLjQ2MzQ3NiAxLjg2MDM1IDIuOTI2OTUzIDMuNDcyNjYgMS40ODgyODEgMS41ODc1IDMuMjc0MjE5IDMuNDk3NDYgMC4yMjMyNDIgMC4zMjI0NiAwLjY0NDkyMiAwLjMyMjQ2IDAuNzE5MzM1IDAgMC42NDQ5MjEtMC43NDQxNC0wLjA0OTYxLTAuMjIzMjQtMC42MjAxMTctMy41NDcwNy0wLjU3MDUwOC0zLjMyMzgzLTEuMjQwMjM0LTcuMjQyOTctMi4zNTY0NDUtMC42NDQ5Mi0yLjM1NjQ0NS0yLjk1MTc2IDAtMS4xOTA2MiAwLjg0MzM1OS0yLjAzMzk4IDAuODY4MTY0LTAuODY4MTcgMi4wNTg3ODktMC44NjgxNyAyLjkwMjE0OCAwIDIuOTAyMTQ4IDIuOTAyMTUgMCAxLjI4OTg1LTAuOTkyMTg3IDIuMzU2NDUgMC4xMjQwMjMgMC41MjA5IDAuNjIwMTE3IDIuMDgzNTkgMC40OTYwOTQgMS41Mzc4OSAxLjUzNzg5MSA0LjA2Nzk3IDAuNTcwNTA4IDEuMzg5MDYgMS4xNDEwMTUgMi44MDI5MyAwLjU5NTMxMyAxLjM4OTA2IDEuMTkwNjI1IDIuNzUzMzIgMC4xNDg4MjggMC4zMjI0NiAwLjUyMDg5OSAwLjMyMjQ2IDAuNTIwODk4LTAuMDI0OCAwLjU5NTMxMi0wLjU0NTcgMC4wNDk2MS0wLjI5NzY2IDEuNTEzMDg2LTE1Ljk5OTAzLTEuNzYxMTMzLTAuOTQyNTctMS43NjExMzMtMi44MDI5MyAwLTEuMTkwNjIgMC44NDMzNi0yLjA1ODc4IDAuODQzMzU5LTAuODY4MTcgMi4wNTg3ODktMC44NjgxNyAxLjE5MDYyNSAwIDIuMDMzOTg0IDAuODY4MTcgMC44NjgxNjQgMC44NjgxNiAwLjg2ODE2NCAyLjA1ODc4IDAgMS42ODY3Mi0xLjYxMjMwNSAyLjc3ODEzem0tNi42OTcyNjUgMjUuNjQ4MDVxLTEuMzE0NjQ4IDAtMS4zMTQ2NDggMS4zODkwNnQxLjMxNDY0OCAxLjM4OTA2cTEuMzM5NDUzIDAgMS4zMzk0NTMtMS4zODkwNnQtMS4zMzk0NTMtMS4zODkwNnptLTcuNTY1NDMtNC45NjA5NHEwLjI5NzY1NyAxLjIxNTQzIDAuNTIwODk5IDIuMjA3NjIgMC4yNDgwNDcgMC45NjczOCAwLjQyMTY3OSAyLjEwODM5IDAuMTk4NDM4IDAuMDk5MiAwLjQ0NjQ4NSAwLjA5OTIgNC40MTUyMzQtMS42NjE5MSAxMS42MzMzOTgtMS42NjE5MSA3LjMxNzM4MSAwIDExLjgzMTgzMSAxLjY4NjcyIDAuMjQ4MDUtMC4wNDk2IDAuMzcyMDgtMC4xMjQwMyAwLjE0ODgyLTEuMTE2MjEgMC4zOTY4Ny0yLjAzMzk4IDAuMjQ4MDUtMC45NDI1OCAwLjU0NTctMi4xODI4MS0yLjgyNzczLTAuNzkzNzUtNi4xNzYzNi0xLjMxNDY1LTMuMzQ4NjQtMC41NDU3LTYuOTQ1MzE2LTAuNTQ1Ny0zLjU5NjY4IDAtNi44NzA4OTkgMC41MjA4OS0zLjI3NDIxOCAwLjUyMDktNi4xNzYzNjcgMS4yNDAyNHptMjQuOTAzOTAyIDcuNTE1ODItMS43ODU5My0xLjcxMTUyLTIuMjgyMDMgMC45MTc3NyAxLjgxMDc0IDEuNzExNTJ6bS04LjcwNjQ0MS0xLjc2MTEzLTMuMTk5ODA1LTEuNjYxOTItMy4wNzU3ODEgMS42NjE5MiAzLjE5OTgwNSAxLjY4Njcxem0tMTAuNzE1NjI1IDAuOTkyMTgtMi41MDUyNzMtMC44NDMzNi0xLjk4NDM3NSAxLjU2MjcgMi40ODA0NjkgMC44NDMzNnptMjYuMjkyOTY2LTIxLjMzMjAzcS0xLjY4NjcyIDAtMS42ODY3MiAxLjY2MTkyIDAgMS42ODY3MiAxLjY4NjcyIDEuNjg2NzIgMS42NjE5MiAwIDEuNjYxOTItMS42ODY3MiAwLTEuNjYxOTItMS42NjE5Mi0xLjY2MTkyem0tMjguOTcxODcyLTUuNjA1ODZxLTEuNjYxOTE0IDAtMS42NjE5MTQgMS42ODY3MiAwIDEuNjYxOTIgMS42NjE5MTQgMS42NjE5MiAxLjY4NjcxOSAwIDEuNjg2NzE5LTEuNjYxOTIgMC0xLjY4NjcyLTEuNjg2NzE5LTEuNjg2NzJ6bTEwLjE2OTkyMi00Ljk2MDkzcS0xLjY2MTkxNCAwLTEuNjYxOTE0IDEuNjg2NzEgMCAxLjY2MTkyIDEuNjYxOTE0IDEuNjYxOTJ0MS42NjE5MTQtMS42NjE5MnEwLTEuNjg2NzEtMS42NjE5MTQtMS42ODY3MXptMTAuMTY5OTIgNC45NjA5M3EtMS42ODY3MiAwLTEuNjg2NzIgMS42ODY3MiAwIDEuNjYxOTIgMS42ODY3MiAxLjY2MTkyIDEuNjYxOTIgMCAxLjY2MTkyLTEuNjYxOTIgMC0xLjY4NjcyLTEuNjYxOTItMS42ODY3MnptLTQuNjM4NDggMjUuMTUxOTZxLTEuMzE0NjQgMC0xLjMxNDY0IDEuMzg5MDZ0MS4zMTQ2NCAxLjM4OTA2cTEuMzM5NDYgMCAxLjMzOTQ2LTEuMzg5MDZ0LTEuMzM5NDYtMS4zODkwNnptLTUuNDU3MDI2IDQuNDQwMDRxLTQuNzEyODkxIDAtOC4wMTE5MTQgMC43MTkzMy0zLjI3NDIxOSAwLjcxOTM0LTMuMjc0MjE5IDIuMDU4NzkgMCAxLjM4OTA2IDMuMjc0MjE5IDIuMjMyNDIgMy4yOTkwMjMgMC44NDMzNiA4LjAxMTkxNCAwLjg0MzM2IDQuNjg4MDg2IDAgOC4wNjE1MjYtMC44NDMzNiAzLjM5ODI0LTAuODQzMzYgMy4zOTgyNC0yLjIzMjQyIDAtMS4zMzk0NS0zLjM5ODI0LTIuMDU4NzktMy4zNzM0NC0wLjcxOTMzLTguMDYxNTI2LTAuNzE5MzN6IiBzdHJva2Utd2lkdGg9Ii4yNjQ1ODMzMiIvPg0KCQk8L2c+DQoJPC9nPg0KPC9zdmc+DQo=')} +.is2d .king.white {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjUwLjc5OTk5OW1tIiBoZWlnaHQ9IjUwLjc3NTIxMW1tIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1MC43OTk5OTkgNTAuNzc1MjExIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02Ni44MTczNzksLTk0Ljk1MDIzOSkiPg0KCQk8ZyBmaWxsPSIjZmZmIj4NCgkJCTxwYXRoIGQ9Im04NC41NTMxMzEgMTMwLjk5MTUxLTIuNDA2MDU1LTAuNzkzNzUtMS44NjAzNTEgMS40ODgyOCAyLjM1NjQ0NSAwLjc5Mzc1eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwNi4wMDkxOSAxMzEuMDY1OTFxMC4xNzM2MyAwLjUyMDkgMC4xNzM2MyAwLjk5MjE5IDAgMS40NjM0OC0xLjA2NjYgMi4yNTcyMy0wLjA5OTIgMC40MjE2OC0wLjE0ODgzIDAuODQzMzYgMC45MTc3NyAxLjI4OTg0IDAuOTE3NzcgMi4wODM1OSAwIDIuMDgzNi00LjAxODM2IDMuNTcxODgtNC4wMTgzNTcgMS40ODgyOC05LjY0OTAyMSAxLjQ4ODI4LTUuNjU1NDY5IDAtOS42NzM4MjgtMS40ODgyOC0zLjk5MzU1NC0xLjQ4ODI4LTMuOTkzNTU0LTMuNTcxODggMC0wLjgxODU1IDAuOTY3MzgyLTIuMTMzMi0wLjA0OTYxLTAuMjcyODUtMC4xNDg4MjgtMC43Njg5NS0xLjA5MTQwNi0wLjc5Mzc1LTEuMDkxNDA2LTIuMjgyMDMgMC0wLjQ3MTI5IDAuMTQ4ODI4LTAuOTY3MzggMC4yNDgwNDctMC42MjAxMi0wLjA5OTIyLTAuOTY3MzgtMC4zNDcyNjUtMC4zNDcyNy0wLjc5Mzc1LTAuOTY3MzktMC4zOTY4NzUtMS4yNDAyMy0wLjM5Njg3NS0xLjcxMTUyIDAuMDI0ODEtMC4yMjMyNCAwLjA3NDQxLTAuNDk2MDkgMC4wNzQ0Mi0wLjI3Mjg2IDAuMDc0NDItMC42NDQ5My0xLjA5MTQwNy0xLjA5MTQtMi4yODIwMzItMi4wNTg3OC0xLjE2NTgyLTAuOTkyMTktMS44MzU1NDctMi4zODEyNS0wLjc5Mzc1LTEuNjM3MTEtMS40NjM0NzYtMy4yOTkwMy0wLjY0NDkyMi0xLjY4NjcyLTAuNjQ0OTIyLTMuMjk5MDIgMC0zLjA1MDk4IDEuNjEyMzA1LTUuMTU5MzggMS42MTIzMDQtMi4xMDgzOSA0LjM2NTYyNS0zLjI5OTAyIDMuNjcxMDkzLTAuMjQ4MDUgMy4xMDA1ODYtMC4yNDgwNSA0LjMxNjAxNSAwIDcuODM4MjgxIDMuMTk5ODF2LTguNzA2NDVoOC40NTgzOTh2OC43MzEyNXEzLjUyMjI2Ni0zLjIyNDYxIDcuODg3ODk0LTMuMjI0NjEtMC42MjAxMiAwIDMuMTAwNTggMC4yNDgwNSAyLjcwMzcxIDEuMTkwNjMgNC4zMTYwMiAzLjI5OTAyIDEuNjM3MTEgMi4xMDg0IDEuNjM3MTEgNS4xNTkzOCAwIDEuNjEyMy0wLjY2OTczIDMuMjc0MjItMC42NDQ5MiAxLjY2MTkxLTEuNDEzODcgMy4yOTkwMi0wLjY2OTcyIDEuNDEzODctMS44NjAzNSAyLjQ1NTY2LTEuMTkwNjIgMS4wNDE4LTIuMjU3MjIgMi4wODM2LTAuMDI0OCAwLjI5NzY1IDAuMDI0OCAwLjU3MDUxIDAuMDc0NCAwLjI3Mjg1IDAuMDk5MiAwLjQ5NjA5IDAuMDI0OCAwLjM0NzI3LTAuMzk2ODggMS43MTE1Mi0wLjQ0NjQ4IDAuNjIwMTItMC43OTM3NSAwLjk2NzM5LTAuMzIyNDYgMC4zNDcyNi0wLjA5OTIgMC45NDI1N3oiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im05Mi4yMTc3NzkgMTA5LjU2MDI2cS0yLjU1NDg4MyAwLTIuNTU0ODgzIDIuNTU0ODggMCAyLjU1NDg5IDIuNTU0ODgzIDIuNTU0ODl0Mi41NTQ4ODMtMi41NTQ4OXEwLTIuNTU0ODgtMi41NTQ4ODMtMi41NTQ4OHoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im05MS4yMjU1OTIgMTA1LjA3MDYxLTEuNzYxMTMzLTEuNzExNTJ2My43OTUxMmwxLjc2MTEzMy0xLjQxMzg3cS0wLjA3NDQxLTAuMDk5Mi0wLjA3NDQxLTAuMzIyNDYgMC0wLjE0ODgzIDAuMDc0NDEtMC4zNDcyN3oiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im05MS43OTYwOTkgMTA2LjM4NTI2LTEuNDg4MjgxIDEuNjEyMzFoMy44MTk5MjJsLTEuNTg3NS0xLjU4NzVxLTAuMjQ4MDQ3IDAuMDQ5Ni0wLjMyMjQ2MSAwLjA0OTYtMC4yNDgwNDcgMC0wLjQyMTY4LTAuMDc0NHoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im05My4yMDk5NjcgMTA1LjgxNDc1IDEuNzYxMTMyIDEuMzM5NDZ2LTMuNzk1MTJsLTEuNzg1OTM3IDEuNjM3MTFxMC4wNzQ0MSAwLjE5ODQ0IDAuMDc0NDEgMC40MjE2OCAwIDAuMTQ4ODMtMC4wNDk2MSAwLjM5Njg3eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTkyLjUxNTQzNSAxMDQuNDAwODkgMS42MTIzMDUtMS45MDk5N2gtMy44MTk5MjJsMS41MTMwODYgMS45MzQ3N3EwLjE0ODgyOC0wLjA3NDQgMC4zOTY4NzUtMC4wNzQ0IDAuMDk5MjIgMCAwLjI5NzY1NiAwLjA0OTZ6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtOTUuMjE5MTQ2IDEzMC4yMjI1Ni0zLjA1MDk3Ni0xLjQ2MzQ3LTIuOTI2OTUzIDEuNDYzNDcgMy4wMjYxNzIgMS40NjM0OHoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im05MC4yNTgyMDkgMTIzLjQ3NTY5cS0wLjAyNDgxLTMuMDUwOTgtMC41MjA4OTktNi4xMjY3Ni0wLjQ5NjA5My0zLjEwMDU4LTAuOTkyMTg3LTMuNzcwMzEtMy4wNzU3ODEtMy4zOTgyNC02Ljk0NTMxMi0zLjM5ODI0LTMuMzIzODI5IDAtNS4wNjAxNTcgMi4yMzI0Mi0xLjE0MTAxNSAxLjQ2MzQ4LTEuMTQxMDE1IDMuODQ0NzMgMCA0Ljk2MDkzIDMuNjk1ODk4IDkuMjc2OTUgMC40MjE2OC0wLjE5ODQ0IDAuODE4NTU1LTAuMzQ3MjcgMC40MjE2OC0wLjE0ODgyIDAuODQzMzU5LTAuMjk3NjUtMC4yMjMyNDItMC40OTYxLTAuNDQ2NDg0LTAuOTQyNTgtMC4yMjMyNDItMC40NDY0OS0wLjQ3MTI4OS0xLjE2NTgyLTAuNDcxMjg5LTEuMzg5MDYtMC4zNzIwNzEtMi42MjkzIDAuMTczNjMzLTAuNzY4OTQgMC44NDMzNi0wLjc2ODk0IDAuMjk3NjU2IDAgMC43OTM3NSAwLjUyMDktMC4xMjQwMjQtMC42Njk3My0wLjEyNDAyNC0wLjg0MzM2IDAtMi4zMDY4NCAxLjk1OTU3MS0yLjg1MjU0IDIuMDU4Nzg5IDAuMDk5MiAyLjcyODUxNSAzLjA3NTc4IDAuMjIzMjQyLTAuNzQ0MTQgMC42MjAxMTctMC44NDMzNiAwLjM5Njg3NS0wLjA5OTIgMC41MjA4OTktMC4wOTkyIDAuMjk3NjU2IDAgMC41MjA4OTggMC4xNDg4MyAwLjg0MzM2IDEuMDQxNzkgMS4wNDE3OTcgMy4wMjYxNyAwLjA0OTYxIDAuNDQ2NDggMC4wNDk2MSAwLjg2ODE2IDAuMDI0OCAwLjQyMTY4IDAuMDk5MjIgMS4xOTA2MyAwLjc2ODk0Ni0wLjE0ODgzIDEuNTM3ODkxLTAuMDk5MnoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im04Mi44NDE2MDcgMTI0LjMxOTA1cS0wLjIyMzI0Mi0wLjU3MDUxLTAuNDcxMjg5LTEuMjY1MDQtMC4yMjMyNDItMC42OTQ1My0wLjU5NTMxMi0xLjQ4ODI4LTAuMTk4NDM4LTAuMzk2ODgtMC40OTYwOTQtMC4zOTY4OC0wLjQyMTY4IDAtMC40NDY0ODQgMC42OTQ1NC0wLjA0OTYxIDAuNTk1MzEgMS4yMTU0MjkgMi43Mjg1MSAwLjE5ODQzOC0wLjA3NDQgMC4zOTY4NzUtMC4xMjQwMiAwLjIyMzI0My0wLjA3NDQgMC4zOTY4NzUtMC4xNDg4M3oiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im04NS4zMjIwNzYgMTIzLjk0Njk4cS0wLjA5OTIyLTMuMjQ5NDEtMC45NjczODMtNS4yNTg1OS0wLjI5NzY1Ni0wLjUyMDktMC44NjgxNjQtMC41MjA5LTAuNzE5MzM2IDAtMC43MTkzMzYgMC43MTkzMy0wLjAyNDggMC4wMjQ4LTAuMDI0OCAwLjY0NDkyIDAgMS4wNjY2MSAxLjIxNTQyOSA0LjY2MzI5IDEuMDQxNzk3LTAuMTk4NDQgMS4zNjQyNTgtMC4yNDgwNXoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im04Ny42NTM3MTcgMTIzLjY5ODkzcTAuMTI0MDIzLTEuOTA5OTYtMC4xOTg0MzgtMy4yMjQ2MS0wLjA5OTIyLTAuNDIxNjgtMC40NzEyODktMC41MjA5LTAuNTIwODk4LTAuMDc0NC0wLjY5NDUzMSAwLjU3MDUxLTAuMTk4NDM4IDEuMDY2NiAwLjM0NzI2NiAzLjI5OTAzIDAuNDk2MDkzLTAuMTI0MDMgMS4wMTY5OTItMC4xMjQwM3oiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im0xMDMuMjgwNjcgMTM2LjAwMjA2cS0wLjE5ODQ0LTEuNzg1OTQtNC45NjA5MzgtMi43Mjg1Mi0xLjQ4ODI4MS0wLjI5NzY1LTMuMDAxMzY3LTAuMzQ3MjYtMS41MTMwODYtMC4wNDk2LTMuMTAwNTg2LTAuMTI0MDMtMS41NjI2OTUgMC4xNDg4My0yLjk1MTc1OCAwLjIyMzI0LTEuMzY0MjU3IDAuMDc0NC0yLjQ4MDQ2OCAwLjI5NzY2LTUuNDgxODM2IDEuMTE2MjEtNS42MDU4NiAyLjY3ODkxLTAuMTk4NDM3IDAuMjk3NjUtMC4xOTg0MzcgMC42MjAxMSAwIDEuMTE2MjIgMS43ODU5MzcgMi4yMzI0MyAwLTEuMTQxMDIgMC4zOTY4NzUtMS43MTE1MyAwLjIyMzI0My0wLjI3Mjg1IDAuNDQ2NDg1LTAuNTQ1NyAwLjI0ODA0Ny0wLjI5NzY2IDAuNDk2MDkzLTAuNTk1MzEgMi4yMzI0MjItMS4zMzk0NiA4LjE2MDc0My0xLjE5MDYzIDUuODA0Mjk2LTAuMTQ4ODMgOC4wODYzMzEgMS4xOTA2MyAwLjU0NTcgMC42OTQ1MyAwLjk0MjU3IDEuMTQxMDEgMC4zOTY4OCAwLjYyMDEyIDAuMzk2ODggMS43MTE1MyAxLjc4NTk0LTEuMTE2MjEgMS43ODU5NC0yLjIzMjQzIDAtMC4zMjI0Ni0wLjE5ODQ0LTAuNjIwMTF6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtMTAwLjQwMzMzIDEzOC4zMDg4OXEwLTIuMjMyNDItOC4yMzUxNi0yLjIzMjQyLTguMTExMTMzIDAtOC4xMTExMzMgMi4yMzI0MiAwLjUyMDg5OSAyLjIwNzYyIDguMjEwMzUyIDIuMjA3NjIgNy41NjU0MjkgMCA4LjEzNTk0MS0yLjIwNzYyeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwMC4xMDU2NyAxMzAuOTkxNTEgMS44ODUxNiAxLjQ4ODI4IDIuMzgxMjUtMC43OTM3NS0xLjg4NTE2LTEuNDg4Mjh6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtMTA1LjExNjIyIDEyNS41MDk2N3EzLjU0NzA3LTQuMzkwNDMgMy41NDcwNy05LjI1MjE0IDAtMi4zODEyNS0xLjE0MTAyLTMuODQ0NzMtMS43NjExMy0yLjIzMjQyLTUuMDYwMTYtMi4yMzI0Mi0zLjg5NDMzMSAwLTYuOTQ1MzA3IDMuMzk4MjQtMC41MjA4OTkgMC42Njk3My0xLjAxNjk5MyAzLjc3MDMxLTAuNDk2MDkzIDMuMDc1NzgtMC41MjA4OTggNi4xMjY3NiAwLjg5Mjk2OS0wLjA3NDQgMS41ODc1IDAuMDk5MiAwLjAyNDgxLTAuNzY4OTUgMC4wMjQ4MS0xLjE5MDYzIDAuMDI0OC0wLjQyMTY4IDAuMDk5MjItMC44NjgxNiAwLjE3MzYzMy0xLjk4NDM4IDEuMDQxNzk3LTMuMDI2MTcgMC4xOTg0MzgtMC4xNDg4MyAwLjUyMDg5OS0wLjE0ODgzIDAuMTI0MDIzIDAgMC41MjA4OTggMC4wOTkydDAuNjIwMTE3IDAuODQzMzZxMC42NDQ5MjItMi45NzY1NiAyLjcyODUxNy0zLjA3NTc4IDEuOTU5NTcgMC41NDU3IDEuOTU5NTcgMi44NTI1NCAwIDAuMTczNjMtMC4xMjQwMiAwLjg0MzM2IDAuNDcxMjktMC41MjA5IDAuNzkzNzUtMC41MjA5IDAuNjQ0OTIgMCAwLjg0MzM2IDAuNzY4OTQgMC4wNzQ0IDEuMjQwMjQtMC4zNzIwNyAyLjYyOTMtMC4yNzI4NSAwLjcxOTMzLTAuNDk2MSAxLjE2NTgyLTAuMTk4NDMgMC40NDY0OC0wLjQyMTY4IDAuODkyOTcgMC40NDY0OSAwLjE3MzYzIDAuODkyOTcgMC4zNDcyNiAwLjQ3MTI5IDAuMTQ4ODMgMC45MTc3OCAwLjMyMjQ2eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwMS40MjAzMiAxMjQuMzE5MDVxMC4xNDg4MyAwLjA3NDQgMC4zNDcyNiAwLjE0ODgzIDAuMjIzMjUgMC4wNDk2IDAuNDQ2NDkgMC4xMjQwMiAxLjI0MDIzLTIuMTMzMiAxLjIxNTQzLTIuNzI4NTEtMC4wNDk2LTAuNjk0NTQtMC40NDY0OS0wLjY5NDU0LTAuMzIyNDYgMC0wLjQ5NjA5IDAuMzk2ODgtMC4zOTY4OCAwLjc5Mzc1LTAuNjQ0OTIgMS40ODgyOC0wLjIyMzI0IDAuNjk0NTMtMC40MjE2OCAxLjI2NTA0eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTk4LjkzOTg0OSAxMjMuOTQ2OThxMC4yOTc2NTcgMC4wNDk2IDEuMzY0MjYxIDAuMjQ4MDUgMS4yMTU0My0zLjU5NjY4IDEuMjE1NDMtNC42NjMyOSAwLTAuNjIwMTEtMC4wMjQ4LTAuNjQ0OTIgMC0wLjcxOTMzLTAuNzE5MzMtMC43MTkzMy0wLjU5NTMyIDAtMC44NjgxNjggMC41MjA5LTAuODkyOTY5IDIuMDA5MTgtMC45NjczODMgNS4yNTg1OXoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im05Ni42MDgyMDkgMTIzLjY5ODkzcTAuNTIwODk4IDAgMS4wMTY5OTIgMC4xMjQwMyAwLjUyMDg5OC0yLjIzMjQzIDAuMzQ3MjY2LTMuMjk5MDMtMC4xOTg0MzgtMC42NDQ5Mi0wLjY5NDUzMi0wLjU3MDUxLTAuMzk2ODc1IDAuMDk5Mi0wLjQ3MTI4OSAwLjUyMDktMC4zNDcyNjUgMS4zMTQ2NS0wLjE5ODQzNyAzLjIyNDYxeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwNC4wMjQ4MSAxMjkuMTgwNzdxMS4xMTYyMS0wLjEyNDAzIDEuMTE2MjEtMS4yNDAyNCAwLTAuNzE5MzMtMC42NDQ5Mi0xLjA5MTQtMi4wODM1OS0wLjg0MzM2LTUuMzA4MjA0LTEuMzY0MjYtMy4xOTk4MDQtMC41NDU3LTYuOTk0OTIyLTAuNTQ1Ny03Ljk2MjMwNCAwLTEyLjM1MjczNCAxLjk1OTU3LTAuNTQ1NzAzIDAuNDIxNjgtMC41NDU3MDMgMS4wNDE3OSAwIDEuMjY1MDQgMS4yNjUwMzkgMS4yMTU0MyA0LjQxNTIzNS0xLjY2MTkxIDExLjYzMzM5OC0xLjY2MTkxIDcuMzE3MzgzIDAgMTEuODMxODM2IDEuNjg2NzJ6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCTwvZz4NCgkJPGcgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIgYXJpYS1sYWJlbD0iayI+DQoJCQk8cGF0aCBkPSJtODQuNTUzMTMxIDEzMC45OTE1MS0yLjQwNjA1NS0wLjc5Mzc1LTEuODYwMzUxIDEuNDg4MjggMi4zNTY0NDUgMC43OTM3NXptMjEuNDU2MDU5IDAuMDc0NHEwLjE3MzYzIDAuNTIwOSAwLjE3MzYzIDAuOTkyMTkgMCAxLjQ2MzQ4LTEuMDY2NiAyLjI1NzIzLTAuMDk5MiAwLjQyMTY4LTAuMTQ4ODMgMC44NDMzNiAwLjkxNzc3IDEuMjg5ODQgMC45MTc3NyAyLjA4MzU5IDAgMi4wODM2LTQuMDE4MzYgMy41NzE4OC00LjAxODM1NyAxLjQ4ODI4LTkuNjQ5MDIxIDEuNDg4MjgtNS42NTU0NjkgMC05LjY3MzgyOC0xLjQ4ODI4LTMuOTkzNTU0LTEuNDg4MjgtMy45OTM1NTQtMy41NzE4OCAwLTAuODE4NTUgMC45NjczODItMi4xMzMyLTAuMDQ5NjEtMC4yNzI4NS0wLjE0ODgyOC0wLjc2ODk1LTEuMDkxNDA2LTAuNzkzNzUtMS4wOTE0MDYtMi4yODIwMyAwLTAuNDcxMjkgMC4xNDg4MjgtMC45NjczOCAwLjI0ODA0Ny0wLjYyMDEyLTAuMDk5MjItMC45NjczOC0wLjM0NzI2NS0wLjM0NzI3LTAuNzkzNzUtMC45NjczOS0wLjM5Njg3NS0xLjI0MDIzLTAuMzk2ODc1LTEuNzExNTIgMC4wMjQ4MS0wLjIyMzI0IDAuMDc0NDEtMC40OTYwOSAwLjA3NDQyLTAuMjcyODYgMC4wNzQ0Mi0wLjY0NDkzLTEuMDkxNDA3LTEuMDkxNC0yLjI4MjAzMi0yLjA1ODc4LTEuMTY1ODItMC45OTIxOS0xLjgzNTU0Ny0yLjM4MTI1LTAuNzkzNzUtMS42MzcxMS0xLjQ2MzQ3Ni0zLjI5OTAzLTAuNjQ0OTIyLTEuNjg2NzItMC42NDQ5MjItMy4yOTkwMiAwLTMuMDUwOTggMS42MTIzMDUtNS4xNTkzOCAxLjYxMjMwNC0yLjEwODM5IDQuMzY1NjI1LTMuMjk5MDIgMy42NzEwOTMtMC4yNDgwNSAzLjEwMDU4Ni0wLjI0ODA1IDQuMzE2MDE1IDAgNy44MzgyODEgMy4xOTk4MXYtOC43MDY0NWg4LjQ1ODM5OHY4LjczMTI1cTMuNTIyMjY2LTMuMjI0NjEgNy44ODc4OTQtMy4yMjQ2MS0wLjYyMDEyIDAgMy4xMDA1OCAwLjI0ODA1IDIuNzAzNzEgMS4xOTA2MyA0LjMxNjAyIDMuMjk5MDIgMS42MzcxMSAyLjEwODQgMS42MzcxMSA1LjE1OTM4IDAgMS42MTIzLTAuNjY5NzMgMy4yNzQyMi0wLjY0NDkyIDEuNjYxOTEtMS40MTM4NyAzLjI5OTAyLTAuNjY5NzIgMS40MTM4Ny0xLjg2MDM1IDIuNDU1NjYtMS4xOTA2MiAxLjA0MTgtMi4yNTcyMiAyLjA4MzYtMC4wMjQ4IDAuMjk3NjUgMC4wMjQ4IDAuNTcwNTEgMC4wNzQ0IDAuMjcyODUgMC4wOTkyIDAuNDk2MDkgMC4wMjQ4IDAuMzQ3MjctMC4zOTY4OCAxLjcxMTUyLTAuNDQ2NDggMC42MjAxMi0wLjc5Mzc1IDAuOTY3MzktMC4zMjI0NiAwLjM0NzI2LTAuMDk5MiAwLjk0MjU3em0tMTMuNzkxNDExLTIxLjUwNTY1cS0yLjU1NDg4MyAwLTIuNTU0ODgzIDIuNTU0ODggMCAyLjU1NDg5IDIuNTU0ODgzIDIuNTU0ODl0Mi41NTQ4ODMtMi41NTQ4OXEwLTIuNTU0ODgtMi41NTQ4ODMtMi41NTQ4OHptLTAuOTkyMTg3LTQuNDg5NjUtMS43NjExMzMtMS43MTE1MnYzLjc5NTEybDEuNzYxMTMzLTEuNDEzODdxLTAuMDc0NDEtMC4wOTkyLTAuMDc0NDEtMC4zMjI0NiAwLTAuMTQ4ODMgMC4wNzQ0MS0wLjM0NzI3em0wLjU3MDUwNyAxLjMxNDY1LTEuNDg4MjgxIDEuNjEyMzFoMy44MTk5MjJsLTEuNTg3NS0xLjU4NzVxLTAuMjQ4MDQ3IDAuMDQ5Ni0wLjMyMjQ2MSAwLjA0OTYtMC4yNDgwNDcgMC0wLjQyMTY4LTAuMDc0NHptMS40MTM4NjgtMC41NzA1MSAxLjc2MTEzMiAxLjMzOTQ2di0zLjc5NTEybC0xLjc4NTkzNyAxLjYzNzExcTAuMDc0NDEgMC4xOTg0NCAwLjA3NDQxIDAuNDIxNjggMCAwLjE0ODgzLTAuMDQ5NjEgMC4zOTY4N3ptLTAuNjk0NTMyLTEuNDEzODYgMS42MTIzMDUtMS45MDk5N2gtMy44MTk5MjJsMS41MTMwODYgMS45MzQ3N3EwLjE0ODgyOC0wLjA3NDQgMC4zOTY4NzUtMC4wNzQ0IDAuMDk5MjIgMCAwLjI5NzY1NiAwLjA0OTZ6bTIuNzAzNzExIDI1LjgyMTY3LTMuMDUwOTc2LTEuNDYzNDctMi45MjY5NTMgMS40NjM0NyAzLjAyNjE3MiAxLjQ2MzQ4em0tNC45NjA5MzctNi43NDY4N3EtMC4wMjQ4MS0zLjA1MDk4LTAuNTIwODk5LTYuMTI2NzYtMC40OTYwOTMtMy4xMDA1OC0wLjk5MjE4Ny0zLjc3MDMxLTMuMDc1NzgxLTMuMzk4MjQtNi45NDUzMTItMy4zOTgyNC0zLjMyMzgyOSAwLTUuMDYwMTU3IDIuMjMyNDItMS4xNDEwMTUgMS40NjM0OC0xLjE0MTAxNSAzLjg0NDczIDAgNC45NjA5MyAzLjY5NTg5OCA5LjI3Njk1IDAuNDIxNjgtMC4xOTg0NCAwLjgxODU1NS0wLjM0NzI3IDAuNDIxNjgtMC4xNDg4MiAwLjg0MzM1OS0wLjI5NzY1LTAuMjIzMjQyLTAuNDk2MS0wLjQ0NjQ4NC0wLjk0MjU4LTAuMjIzMjQyLTAuNDQ2NDktMC40NzEyODktMS4xNjU4Mi0wLjQ3MTI4OS0xLjM4OTA2LTAuMzcyMDcxLTIuNjI5MyAwLjE3MzYzMy0wLjc2ODk0IDAuODQzMzYtMC43Njg5NCAwLjI5NzY1NiAwIDAuNzkzNzUgMC41MjA5LTAuMTI0MDI0LTAuNjY5NzMtMC4xMjQwMjQtMC44NDMzNiAwLTIuMzA2ODQgMS45NTk1NzEtMi44NTI1NCAyLjA1ODc4OSAwLjA5OTIgMi43Mjg1MTUgMy4wNzU3OCAwLjIyMzI0Mi0wLjc0NDE0IDAuNjIwMTE3LTAuODQzMzYgMC4zOTY4NzUtMC4wOTkyIDAuNTIwODk5LTAuMDk5MiAwLjI5NzY1NiAwIDAuNTIwODk4IDAuMTQ4ODMgMC44NDMzNiAxLjA0MTc5IDEuMDQxNzk3IDMuMDI2MTcgMC4wNDk2MSAwLjQ0NjQ4IDAuMDQ5NjEgMC44NjgxNiAwLjAyNDggMC40MjE2OCAwLjA5OTIyIDEuMTkwNjMgMC43Njg5NDYtMC4xNDg4MyAxLjUzNzg5MS0wLjA5OTJ6bS03LjQxNjYwMiAwLjg0MzM2cS0wLjIyMzI0Mi0wLjU3MDUxLTAuNDcxMjg5LTEuMjY1MDQtMC4yMjMyNDItMC42OTQ1My0wLjU5NTMxMi0xLjQ4ODI4LTAuMTk4NDM4LTAuMzk2ODgtMC40OTYwOTQtMC4zOTY4OC0wLjQyMTY4IDAtMC40NDY0ODQgMC42OTQ1NC0wLjA0OTYxIDAuNTk1MzEgMS4yMTU0MjkgMi43Mjg1MSAwLjE5ODQzOC0wLjA3NDQgMC4zOTY4NzUtMC4xMjQwMiAwLjIyMzI0My0wLjA3NDQgMC4zOTY4NzUtMC4xNDg4M3ptMi40ODA0NjktMC4zNzIwN3EtMC4wOTkyMi0zLjI0OTQxLTAuOTY3MzgzLTUuMjU4NTktMC4yOTc2NTYtMC41MjA5LTAuODY4MTY0LTAuNTIwOS0wLjcxOTMzNiAwLTAuNzE5MzM2IDAuNzE5MzMtMC4wMjQ4IDAuMDI0OC0wLjAyNDggMC42NDQ5MiAwIDEuMDY2NjEgMS4yMTU0MjkgNC42NjMyOSAxLjA0MTc5Ny0wLjE5ODQ0IDEuMzY0MjU4LTAuMjQ4MDV6bTIuMzMxNjQxLTAuMjQ4MDVxMC4xMjQwMjMtMS45MDk5Ni0wLjE5ODQzOC0zLjIyNDYxLTAuMDk5MjItMC40MjE2OC0wLjQ3MTI4OS0wLjUyMDktMC41MjA4OTgtMC4wNzQ0LTAuNjk0NTMxIDAuNTcwNTEtMC4xOTg0MzggMS4wNjY2IDAuMzQ3MjY2IDMuMjk5MDMgMC40OTYwOTMtMC4xMjQwMyAxLjAxNjk5Mi0wLjEyNDAzem0xNS42MjY5NTMgMTIuMzAzMTNxLTAuMTk4NDQtMS43ODU5NC00Ljk2MDkzOC0yLjcyODUyLTEuNDg4MjgxLTAuMjk3NjUtMy4wMDEzNjctMC4zNDcyNi0xLjUxMzA4Ni0wLjA0OTYtMy4xMDA1ODYtMC4xMjQwMy0xLjU2MjY5NSAwLjE0ODgzLTIuOTUxNzU4IDAuMjIzMjQtMS4zNjQyNTcgMC4wNzQ0LTIuNDgwNDY4IDAuMjk3NjYtNS40ODE4MzYgMS4xMTYyMS01LjYwNTg2IDIuNjc4OTEtMC4xOTg0MzcgMC4yOTc2NS0wLjE5ODQzNyAwLjYyMDExIDAgMS4xMTYyMiAxLjc4NTkzNyAyLjIzMjQzIDAtMS4xNDEwMiAwLjM5Njg3NS0xLjcxMTUzIDAuMjIzMjQzLTAuMjcyODUgMC40NDY0ODUtMC41NDU3IDAuMjQ4MDQ3LTAuMjk3NjYgMC40OTYwOTMtMC41OTUzMSAyLjIzMjQyMi0xLjMzOTQ2IDguMTYwNzQzLTEuMTkwNjMgNS44MDQyOTYtMC4xNDg4MyA4LjA4NjMzMSAxLjE5MDYzIDAuNTQ1NyAwLjY5NDUzIDAuOTQyNTcgMS4xNDEwMSAwLjM5Njg4IDAuNjIwMTIgMC4zOTY4OCAxLjcxMTUzIDEuNzg1OTQtMS4xMTYyMSAxLjc4NTk0LTIuMjMyNDMgMC0wLjMyMjQ2LTAuMTk4NDQtMC42MjAxMXptLTIuODc3MzQgMi4zMDY4M3EwLTIuMjMyNDItOC4yMzUxNi0yLjIzMjQyLTguMTExMTMzIDAtOC4xMTExMzMgMi4yMzI0MiAwLjUyMDg5OSAyLjIwNzYyIDguMjEwMzUyIDIuMjA3NjIgNy41NjU0MjkgMCA4LjEzNTk0MS0yLjIwNzYyem0tMC4yOTc2Ni03LjMxNzM4IDEuODg1MTYgMS40ODgyOCAyLjM4MTI1LTAuNzkzNzUtMS44ODUxNi0xLjQ4ODI4em01LjAxMDU1LTUuNDgxODRxMy41NDcwNy00LjM5MDQzIDMuNTQ3MDctOS4yNTIxNCAwLTIuMzgxMjUtMS4xNDEwMi0zLjg0NDczLTEuNzYxMTMtMi4yMzI0Mi01LjA2MDE2LTIuMjMyNDItMy44OTQzMzEgMC02Ljk0NTMwNyAzLjM5ODI0LTAuNTIwODk5IDAuNjY5NzMtMS4wMTY5OTMgMy43NzAzMS0wLjQ5NjA5MyAzLjA3NTc4LTAuNTIwODk4IDYuMTI2NzYgMC44OTI5NjktMC4wNzQ0IDEuNTg3NSAwLjA5OTIgMC4wMjQ4MS0wLjc2ODk1IDAuMDI0ODEtMS4xOTA2MyAwLjAyNDgtMC40MjE2OCAwLjA5OTIyLTAuODY4MTYgMC4xNzM2MzMtMS45ODQzOCAxLjA0MTc5Ny0zLjAyNjE3IDAuMTk4NDM4LTAuMTQ4ODMgMC41MjA4OTktMC4xNDg4MyAwLjEyNDAyMyAwIDAuNTIwODk4IDAuMDk5MnQwLjYyMDExNyAwLjg0MzM2cTAuNjQ0OTIyLTIuOTc2NTYgMi43Mjg1MTQtMy4wNzU3OCAxLjk1OTU3IDAuNTQ1NyAxLjk1OTU3IDIuODUyNTQgMCAwLjE3MzYzLTAuMTI0MDIgMC44NDMzNiAwLjQ3MTI5LTAuNTIwOSAwLjc5Mzc1LTAuNTIwOSAwLjY0NDkyIDAgMC44NDMzNiAwLjc2ODk0IDAuMDc0NCAxLjI0MDI0LTAuMzcyMDcgMi42MjkzLTAuMjcyODUgMC43MTkzMy0wLjQ5NjEgMS4xNjU4Mi0wLjE5ODQzIDAuNDQ2NDgtMC40MjE2OCAwLjg5Mjk3IDAuNDQ2NDkgMC4xNzM2MyAwLjg5Mjk3IDAuMzQ3MjYgMC40NzEyOSAwLjE0ODgzIDAuOTE3NzggMC4zMjI0NnptLTMuNjk1OS0xLjE5MDYycTAuMTQ4ODMgMC4wNzQ0IDAuMzQ3MjYgMC4xNDg4MyAwLjIyMzI1IDAuMDQ5NiAwLjQ0NjQ5IDAuMTI0MDIgMS4yNDAyMy0yLjEzMzIgMS4yMTU0My0yLjcyODUxLTAuMDQ5Ni0wLjY5NDU0LTAuNDQ2NDktMC42OTQ1NC0wLjMyMjQ2IDAtMC40OTYwOSAwLjM5Njg4LTAuMzk2ODggMC43OTM3NS0wLjY0NDkyIDEuNDg4MjgtMC4yMjMyNCAwLjY5NDUzLTAuNDIxNjggMS4yNjUwNHptLTIuNDgwNDcxLTAuMzcyMDdxMC4yOTc2NTcgMC4wNDk2IDEuMzY0MjYxIDAuMjQ4MDUgMS4yMTU0My0zLjU5NjY4IDEuMjE1NDMtNC42NjMyOSAwLTAuNjIwMTEtMC4wMjQ4LTAuNjQ0OTIgMC0wLjcxOTMzLTAuNzE5MzMtMC43MTkzMy0wLjU5NTMyIDAtMC44NjgxNjggMC41MjA5LTAuODkyOTY5IDIuMDA5MTgtMC45NjczODMgNS4yNTg1OXptLTIuMzMxNjQtMC4yNDgwNXEwLjUyMDg5OCAwIDEuMDE2OTkyIDAuMTI0MDMgMC41MjA4OTgtMi4yMzI0MyAwLjM0NzI2Ni0zLjI5OTAzLTAuMTk4NDM4LTAuNjQ0OTItMC42OTQ1MzItMC41NzA1MS0wLjM5Njg3NSAwLjA5OTItMC40NzEyODkgMC41MjA5LTAuMzQ3MjY1IDEuMzE0NjUtMC4xOTg0MzcgMy4yMjQ2MXptNy40MTY2MDEgNS40ODE4NHExLjExNjIxLTAuMTI0MDMgMS4xMTYyMS0xLjI0MDI0IDAtMC43MTkzMy0wLjY0NDkyLTEuMDkxNC0yLjA4MzU5LTAuODQzMzYtNS4zMDgyMDQtMS4zNjQyNi0zLjE5OTgwNC0wLjU0NTctNi45OTQ5MjItMC41NDU3LTcuOTYyMzA0IDAtMTIuMzUyNzM0IDEuOTU5NTctMC41NDU3MDMgMC40MjE2OC0wLjU0NTcwMyAxLjA0MTc5IDAgMS4yNjUwNCAxLjI2NTAzOSAxLjIxNTQzIDQuNDE1MjM1LTEuNjYxOTEgMTEuNjMzMzk4LTEuNjYxOTEgNy4zMTczODMgMCAxMS44MzE4MzYgMS42ODY3MnoiIHN0cm9rZS13aWR0aD0iLjI2NDU4MzMyIi8+DQoJCTwvZz4NCgk8L2c+DQo8L3N2Zz4NCg==')} +.is2d .pawn.black {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjUwLjc5OTk5OW1tIiBoZWlnaHQ9IjUwLjc3NTE5Mm1tIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1MC43OTk5OTkgNTAuNzc1MTkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00MS45NjEzMTUsLTg4LjY2OTQxNikiPg0KCQk8ZyBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIiBhcmlhLWxhYmVsPSJvIj4NCgkJCTxwYXRoIGQ9Im02Ny4zNjA4NjggMTM2LjA0NjYxaC0xMy41MTg1NTRxMC40NzEyODktNS4zMzMwMSA0LjUzOTI1OC05LjAwNDEgMC42Njk3MjYtMC42MjAxMiAwLjc0NDE0LTAuNjY5NzMgMi4xMDgzOTktMS43MzYzMiAzLjU5NjY4LTQuMTQyMzgtMy44MTk5MjItMi41MDUyNy0zLjgxOTkyMi03LjA2OTMzIDAtMi44Mjc3NCAxLjcxMTUyNC01LjA4NDk2IDAuNTcwNTA3LTAuNzE5MzQgMS4yMTU0MjktMS42MzcxMSAwLjY2OTcyNy0wLjkxNzc4IDEuMDY2NjAyLTEuNzg1OTQtMC41OTUzMTMgMC4xNDg4My0xLjgxMDc0MiAwLjQ3MTI5LTEuMTkwNjI1IDAuMzIyNDYtMS43NjExMzMgMC41NDU3IDEuNzExNTIzLTEuNTg3NSAzLjI0OTQxNC0zLjc3MDMxIDEuNTYyNjk1LTIuMTgyODEgMS44MzU1NDctNC42Mzg0NzgtMS4yNjUwMzktMS4yODk4NDQtMS4yNjUwMzktMy4wMjYxNzJ0MS4yMTU0MjktMi45NzY1NjNxMS4yNDAyMzUtMS4yNDAyMzQgMy4wMDEzNjctMS4yNDAyMzQgMS43MTE1MjQgMCAyLjk1MTc1OCAxLjI0MDIzNCAxLjI0MDIzNSAxLjI0MDIzNSAxLjI0MDIzNSAyLjk3NjU2MyAwIDEuNzYxMTMzLTEuMjY1MDM5IDMuMDI2MTcyIDAuMjcyODUxIDIuNDU1NjY4IDEuODM1NTQ2IDQuNjM4NDc4IDEuNTg3NSAyLjE4MjgxIDMuMjk5MDI0IDMuNzcwMzEtMC41NzA1MDgtMC4yMjMyNC0xLjgxMDc0Mi0wLjU0NTctMS4yMTU0My0wLjMyMjQ2LTEuODEwNzQzLTAuNDcxMjkgMC4zOTY4NzUgMC44NjgxNiAxLjA0MTc5NyAxLjc4NTk0IDAuNjY5NzI3IDAuOTE3NzcgMS4yNjUwMzkgMS42MzcxMSAxLjcxMTUyNCAyLjI1NzIyIDEuNzExNTI0IDUuMDg0OTYgMCA0LjU2NDA2LTMuODE5OTIyIDcuMDY5MzMgMS40MTM4NjcgMi4zODEyNSAzLjU3MTg3NSA0LjE0MjM4IDAuMzcyMDcgMC4yOTc2NiAwLjc0NDE0MSAwLjY2OTczIDQuMDkyNzczIDMuNjcxMDkgNC41MzkyNTcgOS4wMDQxeiIgc3Ryb2tlLXdpZHRoPSIuMjY0NTgzMzIiLz4NCgkJPC9nPg0KCTwvZz4NCjwvc3ZnPg0K')} +.is2d .knight.black {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjUwLjgwMDAwN21tIiBoZWlnaHQ9IjUwLjc3NTJtbSIgdmVyc2lvbj0iMS4xIiB2aWV3Qm94PSIwIDAgNTAuODAwMDA3IDUwLjc3NTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+DQoJPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTkxLjg3Mzg5NCwtODcuOTM0NDMxKSI+DQoJCTxnIGZpbGw9IiNmZmYiPg0KCQkJPHBhdGggZD0ibTEyMC41NDgyNyAxMTcuOTcyNTRxMC42MjAxMi0wLjEyNDAyIDEuMzg5MDYtMC4yNzI4NSAwLjc5Mzc1LTAuMTczNjMgMS42ODY3Mi0wLjQ3MTI5IDAuNzkzNzUtMC4yNDgwNSAwLjUyMDktMC44OTI5Ny0wLjE3MzYzLTAuMjcyODUtMC40OTYwOS0wLjI3Mjg1LTEuNzYxMTMgMC4zOTY4Ny0zLjMyMzgzIDAuNDcxMjkgMC41OTUzMS0wLjIyMzI0IDEuMjQwMjMtMC40NDY0OSAwLjY0NDkzLTAuMjQ4MDQgMS4yNjUwNC0wLjU0NTcgMS45MzQ3Ny0wLjkxNzc3IDIuNTU0ODktNC4wMTgzNiAwLjEyNDAyLTAuNzE5MzMtMC40NzEyOS0wLjgxODU1LTAuNTIwOS0wLjA0OTYtMC44MTg1NiAwLjQyMTY4LTAuNTk1MzEgMi4yMDc2MS0xLjg4NTE1IDIuOTc2NTYtMC40MjE2OCAwLjI0ODA1LTAuODY4MTcgMC40NDY0OC0wLjQ0NjQ4IDAuMTk4NDQtMC44OTI5NyAwLjQyMTY4IDAuNDk2MS0wLjUyMDg5IDAuOTE3NzgtMS4yNjUwNCAwLjc2ODk0LTEuMjg5ODQgMS4wNDE3OS00LjU2NDA2LTAuMTczNjMtMC44NjgxNi0wLjg2ODE2LTAuNjQ0OTItMC4yMjMyNCAwLjEyNDAyLTAuMjk3NjYgMC4yMjMyNC0wLjQ0NjQ4IDMuNTIyMjctMS4yMTU0MyA0LjYzODQ4LTAuMjcyODUgMC4yNzI4NS0wLjM3MjA3IDAuNDcxMjktMC4yMjMyNCAwLjE3MzYzLTAuNDIxNjggMC4zNDcyNi0wLjE3MzYzIDAuMTQ4ODMtMC4zNDcyNiAwLjI5NzY2LTAuNDIxNjggMC41NDU3LTAuNDIxNjggMS4yNDAyMyAwIDAuODQzMzYgMC40NzEyOSAxLjUzNzg5IDAuNDk2MDkgMC42OTQ1NCAxLjYxMjMgMC43MTkzNHoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im0xMTguNzg3MTQgMTAxLjI1NDE4cTYuODcwOSAzLjM3MzQ0IDEwLjE0NTEyIDguMjg0NzcgMi4wMDkxOCAzLjA1MDk3IDIuNjc4OSA3LjI0Mjk3IDAuNjY5NzMgNC4xOTE5OSAwLjY2OTczIDkuNDAwOTctMC4xMjQwMiAyLjAwOTE4IDEuMTE2MjEgMy41MjIyNyAxLjI2NTA0IDEuNTEzMDggMi44Mjc3MyAxLjE5MDYyIDAuNDcxMjktMTUuMDgxMjUtNS4zNTc4MS0yMi45OTM5NC0xLjc4NTk0LTIuMzgxMjUtNC45ODU3NC00LjYxMzY3LTMuMTk5OC0yLjIzMjQzLTcuMTQzNzUtMy45OTM1NTkgMCAwLjUyMDg5OSAwLjAyNDggMS4wNjY1OTkgMC4wMjQ4IDAuNTIwOSAwLjAyNDggMC44OTI5N3oiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im0xMDQuMjAxOTggMTIyLjAxNTdxMC4yNzI4Ni0wLjQ0NjQ4IDAuNjIwMTItMC44NjgxNiAwLjM3MjA3LTAuNDQ2NDggMC42Njk3My0wLjk5MjE5IDAuNTQ1Ny0xLjExNjIxLTAuNTQ1NzEtMS4zMTQ2NS0wLjE5ODQzLTAuMDQ5Ni0wLjQ0NjQ4IDAuMDQ5Ni0wLjcxOTM0IDAuOTY3MzktMS41NjI3IDEuOTU5NTctMC4xMjQwMiAwLjA5OTItMC41NzA1IDAuNDk2MS0wLjIyMzI1IDAuNzQ0MTQtMC4wMjQ4IDEuMTQxMDEgMC4zMjI0NiAwLjc0NDE0IDEuMjE1NDMgMC4wOTkyIDAuNDQ2NDktMC4zNDcyNiAwLjY0NDkyLTAuNTcwNTF6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtMTEyLjkzMzIzIDExNS42NDA5cTAuMDc0NC0wLjI5NzY2IDAuMTczNjQtMC41OTUzMSAwLjEyNDAyLTAuMjk3NjYgMC4xOTg0My0wLjU5NTMxIDAuMjIzMjUtMC45NjczOS0wLjU0NTctMC45NjczOS0wLjI3Mjg1IDAtMC42Njk3MyAwLjQ0NjQ5LTAuMTczNjMgMC4zOTY4Ny0wLjM0NzI2IDAuNzkzNzUtMC4xNzM2MyAwLjM3MjA3LTAuMjcyODUgMC42OTQ1My0wLjA3NDQgMC4yNDgwNC0wLjIyMzI1IDAuNjk0NTMtMC4wNDk2IDAuMzcyMDcgMC4yOTc2NiAwLjU0NTcgMC41MjA5IDAuMjk3NjYgMS4wNjY2LTAuNDcxMjkgMC4xNzM2NC0wLjE3MzYzIDAuMzIyNDYtMC41NDU3eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwMS4zNDk0NCAxMTcuNjI1MjdxMC4yNDgwNS0wLjM0NzI2IDAuNTcwNTEtMC42OTQ1MyAwLjMyMjQ2LTAuMzcyMDcgMC41NzA1MS0wLjgxODU1IDAuNDk2MDktMC45MTc3Ny0wLjQ3MTI5LTEuMDY2Ni0wLjE0ODgzLTAuMDI0OC0wLjQyMTY4IDAuMDI0OC0wLjU5NTMxIDAuNzY4OTUtMS4zODkwNiAxLjYxMjMxLTAuMjk3NjU3IDAuMjIzMjQtMC40OTYwOTUgMC4zOTY4Ny0wLjE5ODQzNyAwLjYyMDEyLTAuMDI0ODEgMC45MTc3OCAwLjI5NzY1NyAwLjYyMDExIDEuMDkxNDE1IDAuMDk5MiAwLjM5Njg3LTAuMjk3NjUgMC41NzA1LTAuNDcxMjl6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtMTA4LjY2NjgzIDEwNi42MTE5OXEwLjE3MzYzIDEuMDY2NjEgMC41NzA1IDEuMjE1NDMgMC4zOTY4OCAwLjE0ODgzIDEuMTE2MjIgMC4wOTkyIDAuOTY3MzgtMC4wNzQ0IDEuNDg4MjgtMC4zOTY4NyAxLjA0MTc5LTAuNjY5NzMgMS44MzU1NC0yLjkwMjE1LTAuNzkzNzUgMC4yNDgwNS0xLjQ4ODI4IDAuMjQ4MDV0LTEuNjYxOTEgMC4wNzQ0cS0xLjM2NDI2IDAuMTI0MDItMS44NjAzNSAxLjY2MTkxeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwOC4zNDQzNyAxMjAuOTk4NzFxLTAuMzQ3MjcgMC4zNzIwNy0wLjU3MDUxIDAuNTQ1NzEtMC4xOTg0NCAwLjE0ODgyLTAuMzQ3MjcgMC4yOTc2NS0wLjEyNDAyIDAuMTI0MDMtMS42MTIzIDEuNjM3MTEtMC41NzA1MSAwLjYyMDEyLTEuMzY0MjYgMC43OTM3NS0wLjUyMDkgMC4xNDg4My0xLjQ2MzQ4LTAuMTI0MDItMy4xMDA1ODItMC44MTg1Ni00Ljg4NjUyLTMuMjc0MjItMC42OTQ1MzEtMC45MTc3Ny0wLjk5MjE4Ny0yLjIwNzYyLTAuMjcyODUyLTEuMzE0NjUgMC4yNzI4NTEtMy4zMjM4MyAwLjU0NTcwNC0yLjAzMzk4IDMuOTQzOTQ2LTQuNjM4NDcgMy42OTU5LTIuODI3NzQgNC4zNDA4Mi00LjQ4OTY1IDAuNTQ1Ny0wLjk2NzM4IDEuMjQwMjMtMi4xMzMyIDAuNzE5MzQtMS4xNjU4MiAxLjY4NjcyLTIuMjU3MjMgMC41OTUzMi0wLjQyMTY4IDEuMTE2MjEtMC45NjczOCAwLjU0NTcxLTAuNTcwNTEgMS4wNjY2MS0xLjE2NTgyNHYtMy4wNTA5NzZxMS4zNjQyNSAwLjI3Mjg1MSAyLjAwOTE4IDAuNzkzNzUgMC4yOTc2NSAwLjMyMjQ2MSAwLjY0NDkyIDAuNTk1MzEyIDAuMzcyMDcgMC4yNzI4NTIgMC42Njk3MiAwLjU5NTMxMyAwLjYyMDEyLTEuMTE2MjExIDAuNzkzNzUtMS44NjAzNTIgMC4wMjQ4LTAuMTczNjMzIDAuMTczNjQtMC42OTQ1MzEgMC4xNDg4Mi0wLjUyMDg5OSAwLjI5NzY1LTEuNzExNTI0IDAuMzcyMDctMC4wOTkyMiAwLjY0NDkyIDAuMTk4NDM4IDEuMTQxMDIgMS4yODk4NDQgMi4xNTgwMSAyLjg3NzM0NCA0LjUzOTI2IDEuODEwNzQyIDguMjg0NzcgNC4yOTEyMSAzLjc3MDMxIDIuNDgwNDcgNS43Nzk0OSA1LjE1OTM4IDUuNjgwMjcgNy43MTQyNSA1LjY4MDI3IDIyLjcyMTA5IDAgMy4xNTAxOS0wLjMyMjQ2IDUuNzU0NjloLTMzLjg1ODRxLTAuMzIyNDYtMy4yMjQ2MSAzLjQyMzA1LTYuODQ2MSAxLjY4NjcyLTEuNjM3MTEgMy40OTc0Ni0zLjE3NSAxLjgzNTU1LTEuNTM3ODkgMy41NzE4OC0zLjEyNTM5IDMuMjI0NjEtMi45NzY1NiAzLjU3MTg3LTQuNzYyNS0wLjEyNDAyLTAuMjk3NjUtMC40NzEyOS0wLjM5Njg3LTAuODY4MTYgMC41MjA5LTEuNzM2MzMgMC42Njk3Mi0wLjg2ODE2IDAuMTQ4ODMtMS43MTE1MiAwLjE5ODQ0LTAuNTQ1NyAwLjAyNDgtMS4wOTE0IDAuMDQ5Ni0wLjUyMDkgMC0xLjI0MDI0LTAuMjQ4MDUtMC45NjczOCAxLjA5MTQxLTEuNjYxOTEgMS44ODUxNi0wLjY2OTczIDAuNzY4OTUtMS41Mzc4OSAxLjM4OTA2eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQk8L2c+DQoJCTxnIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiIGFyaWEtbGFiZWw9Im0iPg0KCQkJPHBhdGggZD0ibTEyMC41NDgyNyAxMTcuOTcyNTRxMC42MjAxMi0wLjEyNDAyIDEuMzg5MDYtMC4yNzI4NSAwLjc5Mzc1LTAuMTczNjMgMS42ODY3Mi0wLjQ3MTI5IDAuNzkzNzUtMC4yNDgwNSAwLjUyMDktMC44OTI5Ny0wLjE3MzYzLTAuMjcyODUtMC40OTYwOS0wLjI3Mjg1LTEuNzYxMTMgMC4zOTY4Ny0zLjMyMzgzIDAuNDcxMjkgMC41OTUzMS0wLjIyMzI0IDEuMjQwMjMtMC40NDY0OSAwLjY0NDkzLTAuMjQ4MDQgMS4yNjUwNC0wLjU0NTcgMS45MzQ3Ny0wLjkxNzc3IDIuNTU0ODktNC4wMTgzNiAwLjEyNDAyLTAuNzE5MzMtMC40NzEyOS0wLjgxODU1LTAuNTIwOS0wLjA0OTYtMC44MTg1NiAwLjQyMTY4LTAuNTk1MzEgMi4yMDc2MS0xLjg4NTE1IDIuOTc2NTYtMC40MjE2OCAwLjI0ODA1LTAuODY4MTcgMC40NDY0OC0wLjQ0NjQ4IDAuMTk4NDQtMC44OTI5NyAwLjQyMTY4IDAuNDk2MS0wLjUyMDg5IDAuOTE3NzgtMS4yNjUwNCAwLjc2ODk0LTEuMjg5ODQgMS4wNDE3OS00LjU2NDA2LTAuMTczNjMtMC44NjgxNi0wLjg2ODE2LTAuNjQ0OTItMC4yMjMyNCAwLjEyNDAyLTAuMjk3NjYgMC4yMjMyNC0wLjQ0NjQ4IDMuNTIyMjctMS4yMTU0MyA0LjYzODQ4LTAuMjcyODUgMC4yNzI4NS0wLjM3MjA3IDAuNDcxMjktMC4yMjMyNCAwLjE3MzYzLTAuNDIxNjggMC4zNDcyNi0wLjE3MzYzIDAuMTQ4ODMtMC4zNDcyNiAwLjI5NzY2LTAuNDIxNjggMC41NDU3LTAuNDIxNjggMS4yNDAyMyAwIDAuODQzMzYgMC40NzEyOSAxLjUzNzg5IDAuNDk2MDkgMC42OTQ1NCAxLjYxMjMgMC43MTkzNHptLTEuNzYxMTMtMTYuNzE4MzZxNi44NzA5IDMuMzczNDQgMTAuMTQ1MTIgOC4yODQ3NyAyLjAwOTE4IDMuMDUwOTcgMi42Nzg5IDcuMjQyOTcgMC42Njk3MyA0LjE5MTk5IDAuNjY5NzMgOS40MDA5Ny0wLjEyNDAyIDIuMDA5MTggMS4xMTYyMSAzLjUyMjI3IDEuMjY1MDQgMS41MTMwOCAyLjgyNzczIDEuMTkwNjIgMC40NzEyOS0xNS4wODEyNS01LjM1NzgxLTIyLjk5Mzk0LTEuNzg1OTQtMi4zODEyNS00Ljk4NTc0LTQuNjEzNjctMy4xOTk4LTIuMjMyNDMtNy4xNDM3NS0zLjk5MzU1OSAwIDAuNTIwODk5IDAuMDI0OCAxLjA2NjU5OSAwLjAyNDggMC41MjA5IDAuMDI0OCAwLjg5Mjk3em0tMTQuNTg1MTYgMjAuNzYxNTJxMC4yNzI4Ni0wLjQ0NjQ4IDAuNjIwMTItMC44NjgxNiAwLjM3MjA3LTAuNDQ2NDggMC42Njk3My0wLjk5MjE5IDAuNTQ1Ny0xLjExNjIxLTAuNTQ1NzEtMS4zMTQ2NS0wLjE5ODQzLTAuMDQ5Ni0wLjQ0NjQ4IDAuMDQ5Ni0wLjcxOTM0IDAuOTY3MzktMS41NjI3IDEuOTU5NTctMC4xMjQwMiAwLjA5OTItMC41NzA1IDAuNDk2MS0wLjIyMzI1IDAuNzQ0MTQtMC4wMjQ4IDEuMTQxMDEgMC4zMjI0NiAwLjc0NDE0IDEuMjE1NDMgMC4wOTkyIDAuNDQ2NDktMC4zNDcyNiAwLjY0NDkyLTAuNTcwNTF6bTguNzMxMjUtNi4zNzQ4cTAuMDc0NC0wLjI5NzY2IDAuMTczNjQtMC41OTUzMSAwLjEyNDAyLTAuMjk3NjYgMC4xOTg0My0wLjU5NTMxIDAuMjIzMjUtMC45NjczOS0wLjU0NTctMC45NjczOS0wLjI3Mjg1IDAtMC42Njk3MyAwLjQ0NjQ5LTAuMTczNjMgMC4zOTY4Ny0wLjM0NzI2IDAuNzkzNzUtMC4xNzM2MyAwLjM3MjA3LTAuMjcyODUgMC42OTQ1My0wLjA3NDQgMC4yNDgwNC0wLjIyMzI1IDAuNjk0NTMtMC4wNDk2IDAuMzcyMDcgMC4yOTc2NiAwLjU0NTcgMC41MjA5IDAuMjk3NjYgMS4wNjY2LTAuNDcxMjkgMC4xNzM2NC0wLjE3MzYzIDAuMzIyNDYtMC41NDU3em0tMTEuNTgzNzkgMS45ODQzN3EwLjI0ODA1LTAuMzQ3MjYgMC41NzA1MS0wLjY5NDUzIDAuMzIyNDYtMC4zNzIwNyAwLjU3MDUxLTAuODE4NTUgMC40OTYwOS0wLjkxNzc3LTAuNDcxMjktMS4wNjY2LTAuMTQ4ODMtMC4wMjQ4LTAuNDIxNjggMC4wMjQ4LTAuNTk1MzEgMC43Njg5NS0xLjM4OTA2IDEuNjEyMzEtMC4yOTc2NTcgMC4yMjMyNC0wLjQ5NjA5NSAwLjM5Njg3LTAuMTk4NDM3IDAuNjIwMTItMC4wMjQ4MSAwLjkxNzc4IDAuMjk3NjU3IDAuNjIwMTEgMS4wOTE0MSAwLjA5OTIgMC4zOTY4Ny0wLjI5NzY1IDAuNTcwNS0wLjQ3MTI5em03LjMxNzM5LTExLjAxMzI4cTAuMTczNjMgMS4wNjY2MSAwLjU3MDUgMS4yMTU0MyAwLjM5Njg4IDAuMTQ4ODMgMS4xMTYyMiAwLjA5OTIgMC45NjczOC0wLjA3NDQgMS40ODgyOC0wLjM5Njg3IDEuMDQxNzktMC42Njk3MyAxLjgzNTU0LTIuOTAyMTUtMC43OTM3NSAwLjI0ODA1LTEuNDg4MjggMC4yNDgwNXQtMS42NjE5MSAwLjA3NDRxLTEuMzY0MjYgMC4xMjQwMi0xLjg2MDM1IDEuNjYxOTF6bS0wLjMyMjQ2IDE0LjM4NjcycS0wLjM0NzI3IDAuMzcyMDctMC41NzA1MSAwLjU0NTcxLTAuMTk4NDQgMC4xNDg4Mi0wLjM0NzI3IDAuMjk3NjUtMC4xMjQwMiAwLjEyNDAzLTEuNjEyMyAxLjYzNzExLTAuNTcwNTEgMC42MjAxMi0xLjM2NDI2IDAuNzkzNzUtMC41MjA5IDAuMTQ4ODMtMS40NjM0OC0wLjEyNDAyLTMuMTAwNTgyLTAuODE4NTYtNC44ODY1Mi0zLjI3NDIyLTAuNjk0NTMxLTAuOTE3NzctMC45OTIxODctMi4yMDc2Mi0wLjI3Mjg1Mi0xLjMxNDY1IDAuMjcyODUxLTMuMzIzODMgMC41NDU3MDQtMi4wMzM5OCAzLjk0Mzk0Ni00LjYzODQ3IDMuNjk1OS0yLjgyNzc0IDQuMzQwODItNC40ODk2NSAwLjU0NTctMC45NjczOCAxLjI0MDIzLTIuMTMzMiAwLjcxOTM0LTEuMTY1ODIgMS42ODY3Mi0yLjI1NzIzIDAuNTk1MzItMC40MjE2OCAxLjExNjIxLTAuOTY3MzggMC41NDU3MS0wLjU3MDUxIDEuMDY2NjEtMS4xNjU4MjR2LTMuMDUwOTc2cTEuMzY0MjUgMC4yNzI4NTEgMi4wMDkxOCAwLjc5Mzc1IDAuMjk3NjUgMC4zMjI0NjEgMC42NDQ5MiAwLjU5NTMxMiAwLjM3MjA3IDAuMjcyODUyIDAuNjY5NzIgMC41OTUzMTMgMC42MjAxMi0xLjExNjIxMSAwLjc5Mzc1LTEuODYwMzUyIDAuMDI0OC0wLjE3MzYzMyAwLjE3MzY0LTAuNjk0NTMxIDAuMTQ4ODItMC41MjA4OTkgMC4yOTc2NS0xLjcxMTUyNCAwLjM3MjA3LTAuMDk5MjIgMC42NDQ5MiAwLjE5ODQzOCAxLjE0MTAyIDEuMjg5ODQ0IDIuMTU4MDEgMi44NzczNDQgNC41MzkyNiAxLjgxMDc0MiA4LjI4NDc3IDQuMjkxMjEgMy43NzAzMSAyLjQ4MDQ3IDUuNzc5NDkgNS4xNTkzOCA1LjY4MDI3IDcuNzE0MjUgNS42ODAyNyAyMi43MjEwOSAwIDMuMTUwMTktMC4zMjI0NiA1Ljc1NDY5aC0zMy44NTg0cS0wLjMyMjQ2LTMuMjI0NjEgMy40MjMwNS02Ljg0NjEgMS42ODY3Mi0xLjYzNzExIDMuNDk3NDYtMy4xNzUgMS44MzU1NS0xLjUzNzg5IDMuNTcxODgtMy4xMjUzOSAzLjIyNDYxLTIuOTc2NTYgMy41NzE4Ny00Ljc2MjUtMC4xMjQwMi0wLjI5NzY1LTAuNDcxMjktMC4zOTY4Ny0wLjg2ODE2IDAuNTIwOS0xLjczNjMzIDAuNjY5NzItMC44NjgxNiAwLjE0ODgzLTEuNzExNTIgMC4xOTg0NC0wLjU0NTcgMC4wMjQ4LTEuMDkxNCAwLjA0OTYtMC41MjA5IDAtMS4yNDAyNC0wLjI0ODA1LTAuOTY3MzggMS4wOTE0MS0xLjY2MTkxIDEuODg1MTYtMC42Njk3MyAwLjc2ODk1LTEuNTM3ODkgMS4zODkwNnoiIHN0cm9rZS13aWR0aD0iLjI2NDU4MzMyIi8+DQoJCTwvZz4NCgk8L2c+DQo8L3N2Zz4NCg==')} +.is2d .bishop.black {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjUwLjc5OTk5OW1tIiBoZWlnaHQ9IjUwLjc3NTIxMW1tIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1MC43OTk5OTkgNTAuNzc1MjExIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC03Ny4yNDA4OTEsLTEwNy40NDUwOCkiPg0KCQk8ZyBmaWxsPSIjZmZmIj4NCgkJCTxwYXRoIGQ9Im0xMDUuOTE1MDYgMTUxLjI5OTQycS0wLjM5Njg4LTAuMjQ4MDUtMS4xMTYyMi0xLjA0MTgtMC4xMjQwMi0wLjEyNDAyLTAuMjQ4MDQtMC4yMjMyNC0wLjEyNDAzLTAuMTI0MDMtMC4yNDgwNS0wLjI3Mjg1LTAuMTk4NDQtMC4xMjQwMy0wLjM5Njg3LTAuMTI0MDMtMS4yODk4NSAwLTAuOTY3MzkgMC45NjczOSAwLjE0ODgzIDAuMjIzMjQgMC4xMjQwMyAwLjE5ODQzIDAuMTczNjMgMC4xNzM2NCAxLjE5MDYyIDEuMTE2MjEgMC40NzEyOSAwLjQ0NjQ5IDAuODkyOTcgMC42NDQ5MyAwLjIyMzI0IDAuMTQ4ODIgMC40NDY0OCAwLjE0ODgyIDAuNzQ0MTUgMCAwLjc0NDE1LTAuNzQ0MTQgMC0wLjI5NzY1LTAuNDIxNjgtMC42Njk3MnoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im0xMDcuODAwMjEgMTM4LjY3MzgzLTAuNDQ2NDgtMS43MTE1MnEtMS45NTk1Ny0wLjU0NTcxLTQuNjg4MDktMC41NDU3MS0yLjUwNTI3IDAtNC40ODk2NDcgMC40OTYxbC0wLjQ5NjA5NCAxLjcxMTUycTIuMTU4MDA4LTAuNTcwNTEgNC45ODU3NDEtMC41NzA1MSAzLjAyNjE3IDAgNS4xMzQ1NyAwLjYyMDEyeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwNS4wOTY1IDE0MS4zNzc1NC0yLjQwNjA1IDAuOTkyMTktMi4zODEyNS0wLjk5MjE5IDIuMzgxMjUtMC45OTIxOXoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im0xMDcuODk5NDMgMTQwLjA4NzdxLTIuMTA4NC0wLjU3MDUxLTUuMTU5MzctMC41NzA1MS0yLjg1MjU0NCAwLTUuMDM1MzU2IDAuNTIwOWwtMC4zNDcyNjYgMC45NjczOCAyLjEwODM5OSAwLjQ3MTI5LTIuMTgyODEzIDEuMzg5MDYtMC40NzEyODktMC4wOTkyLTAuNTk1MzEyIDEuNzg1OTRxMC41MjA4OTgtMC41NDU3IDIuMzU2NDQ1LTAuOTE3NzcgMS44MzU1NDItMC4zNzIwNyA0LjI0MTYwMi0wLjM3MjA3IDIuMzU2NDQgMCA0LjE2NzE5IDAuMzcyMDcgMS44MzU1NCAwLjM3MjA3IDIuMzgxMjUgMC44OTI5N2wtMC42MjAxMi0xLjc4NTk0LTAuNjIwMTIgMC4xMjQwMi0yLjE4MjgxLTEuMzg5MDYgMi4yMzI0Mi0wLjQ3MTI5eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwNy4wODA4OCAxMjcuMTE0ODV2LTIuNzc4MTNoLTIuOTc2NTd2LTMuODY5NTNoLTIuNzUzMzJ2My44Njk1M2gtMy4wMjYxNjl2Mi43NzgxM2gzLjAyNjE2OXY1LjUzMTQ0aDIuNzUzMzJ2LTUuNTMxNDR6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtOTkuMzY2NjE4IDE1MS4yOTk0MnEtMC4yNzI4NTIgMC4yNzI4NS0wLjI3Mjg1MiAwLjYyMDExIDAgMC43NDQxNSAwLjc0NDE0MSAwLjc0NDE1IDAuMjIzMjQzIDAgMC4zOTY4NzMtMC4xMjQwMyAwLjQyMTY4LTAuMjIzMjQgMC44MTg1Ni0wLjYyMDEyIDAuODkyOTctMC44NDMzNSAxLjI0MDIzLTEuMTQxMDEgMC4wNDk2LTAuMDQ5NiAwLjA0OTYtMC4xNzM2MyAwLTAuOTY3MzktMC45NjczOC0wLjk2NzM5LTAuMTczNjQgMC0wLjMyMjQ2IDAuMTQ4ODMtMC4yMjMyNSAwLjIyMzI0LTAuNTQ1NzEgMC40NzEyOS0wLjI5NzY1IDAuMjIzMjQtMC41NDU2OTkgMC41MjA5LTAuMjIzMjQzIDAuMjcyODUtMC41OTUzMTMgMC41MjA5eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTExMS45OTIyIDEyOC42Nzc1NHEwLjM0NzI3LTEuMzM5NDUtMC43Njg5NC00Ljk4NTc0dC0zLjQ3MjY2LTYuMTAxOTVxLTAuMjk3NjUtMC4yMjMyNC0wLjYyMDExLTAuMTk4NDQtMC40MjE2OCAwLjAyNDgtMC43OTM3NSAwLjM0NzI3LTAuMzcyMDggMC4zMjI0Ni0wLjA5OTIgMC43Njg5NCAyLjkwMjE0IDEuOTA5OTYgNC4zNDA4MiA1LjMwODIgMS40Mzg2NyAzLjM3MzQ0IDEuNDEzODYgNC44NjE3MnoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im0xMDIuNjY1NjQgMTUyLjIxNzE5cS0xLjgzNTU1IDIuNjU0MS00Ljk2MDkzNiAyLjY1NDEtMC4zMjI0NjEgMC0wLjY0NDkyMi0wLjAyNDgtMC4yOTc2NTYtMC4wNDk2LTAuNTk1MzEyLTAuMDc0NC0wLjcxOTMzNi0wLjAyNDgtMi4xMDgzOTktMC4yNDgwNC0xLjM4OTA2Mi0wLjI0ODA1LTMuMTAwNTg2LTEuMTE2MjEtMS41MTMwODYtMS4zMTQ2NS0zLjg0NDcyNi0xLjMxNDY1LTEuNzg1OTM4IDAtMy4xMDA1ODYgMC44NDMzNi0wLjM3MjA3IDAuMTczNjMtMC45MTc3NzMgMC43MTkzMy0wLjk5MjE4OCAxLjA2NjYtMS42MTIzMDUgMS4xNjU4Mi0wLjQ5NjA5NC0wLjI0ODA0LTAuNTIwODk5LTAuODQzMzYtMC4xMjQwMjMtMS4xNjU4MiAxLjcxMTUyNC0zLjAwMTM2LTAuMzIyNDYxIDAuMDQ5Ni0xLjIxNTQzIDAuMjk3NjUtMC43NDQxNCAwLjIyMzI0LTAuOTkyMTg3IDAuMjIzMjQtMC44MTg1NTUgMC4xMjQwMy0wLjg2ODE2NCAwLjAyNDgtMC4yNzI4NTItMC4yNzI4NSAwLjE5ODQzNy0xLjExNjIxIDAuMzk2ODc1LTAuNzE5MzQgMS41Mzc4OTEtMS4yNjUwNCAwLjE0ODgyOC0wLjA3NDQgMC45NDI1NzgtMC40MjE2OCAyLjMwNjgzNi0xLjIxNTQzIDQuODM2OTE0LTEuMjE1NDMgMy42OTU4OTggMCA2LjY3MjQ2MSAyLjUwNTI3IDEuMTkwNjI1IDAuMzk2ODggMi40MDYwNTQgMC4zOTY4OCAzLjcyMDcwNiAwIDMuODQ0NzI2LTMuMDc1NzgtMi40MDYwNTQtMC4yMjMyNC00LjAxODM1OS0wLjgxODU2LTEuNTg3NDk5LTAuNTk1MzEtMS41ODc0OTktMS4zODkwNmwxLjk4NDM3NC02LjU5ODA1cS0xLjczNjMyOC0yLjcyODUxLTIuODc3MzQzLTUuNTU2MjUtMS4xNDEwMTYtMi44Mjc3My0xLjE0MTAxNi01LjM1NzgxIDAtNy41OTAyMyA4LjIzNTE1My0xMS42NTgyIDAtMC4zMjI0NiAwLjA3NDQtMC45NjczOC0wLjg0MzM2LTAuNjk0NTQtMC44NDMzNi0xLjc2MTE0IDAtMi4yODIwMyAyLjMwNjgzLTIuMjgyMDMgMi4yODIwNCAwIDIuMjgyMDQgMi4yODIwMyAwIDAuOTkyMTktMC43MTkzNCAxLjY2MTkyIDAgMC43Njg5NCAwLjE5ODQ0IDEuMDQxNzkgMC40MjE2OCAwLjU5NTMyIDEuMTE2MjEgMC42MjAxMiAwLjcxOTMzLTAuMDI0OCAxLjE5MDYyLTAuNjQ0OTIgMC4wOTkyLTAuMTQ4ODMgMC4xOTg0NC0wLjkxNzc3LTAuNjQ0OTItMC42Njk3My0wLjY0NDkyLTEuNjYxOTIgMC0yLjMzMTY0IDIuMzMxNjQtMi4zMzE2NHQyLjMzMTY0IDIuMzMxNjRxMCAxLjMxNDY1LTEuMTQxMDIgMi4wMzM5OS0wLjA5OTIgMC40OTYwOS0wLjA0OTYgMC43OTM3NSA0LjE5MiA0Ljk2MDkzIDMuNjQ2MjkgMTEuNDU5NzYtMC4xNzM2MyAxLjg2MDM1LTAuNTcwNSAzLjY3MTA5LTAuMzk2ODggMS43ODU5NC0xLjM4OTA3IDMuMzczNDQtMC4zNzIwNyAwLjg0MzM2LTEuMTY1ODIgMS45MDk5Ni0wLjc2ODk0IDEuMDQxOC0xLjMzOTQ1IDEuOTU5NTdsMS45NTk1NyA2LjU5ODA1cS0wLjAyNDggMC43OTM3NS0xLjYzNzExIDEuMzg5MDYtMS42MTIzIDAuNTk1MzItNC4wNjc5NyAwLjgxODU2IDAuMTI0MDMgMy4wNzU3OCAzLjg2OTUzIDMuMDc1NzggMS4yMTU0MyAwIDIuNDA2MDYtMC4zOTY4OCAyLjk1MTc2LTIuNTA1MjcgNi42NzI0Ni0yLjUwNTI3IDIuNTMwMDggMCA0LjgxMjExIDEuMjE1NDMgMC4yOTc2NSAwLjE0ODgzIDAuNTIwOSAwLjI0ODA1IDAuMjIzMjQgMC4wOTkyIDAuNDQ2NDggMC4xNzM2MyAxLjExNjIxIDAuNTcwNTEgMS41Mzc4OSAxLjI2NTA0IDAuMDc0NCAwLjIyMzI0IDAuMjIzMjQgMC41NzA1MSAwLjE0ODgzIDAuMzQ3MjYtMC4wMjQ4IDAuNTQ1Ny0wLjA3NDQgMC4wOTkyLTAuODY4MTctMC4wMjQ4LTAuMjQ4MDQgMC0wLjk5MjE4LTAuMjIzMjQtMC45MTc3OC0wLjI0ODA0LTEuMjQwMjQtMC4yOTc2NSAxLjgzNTU1IDEuODYwMzUgMS43MzYzMyAzLjAwMTM2LTAuMDQ5NiAwLjU3MDUxLTAuNTQ1NyAwLjg0MzM2LTAuNjIwMTItMC4wOTkyLTEuNjEyMzEtMS4xNjU4Mi0wLjQ5NjA5LTAuNDk2MDktMC44OTI5Ny0wLjcxOTMzLTEuMzg5MDYtMC44NDMzNi0zLjEwMDU4LTAuODQzMzYtMi4zODEyNSAwLTMuODY5NTMgMS4zMTQ2NS0xLjcxMTUzIDAuODY4MTYtMy4xMDA1OSAxLjExNjIxLTEuMzg5MDYgMC4yMjMyNC0yLjA4MzU5IDAuMjQ4MDQtMC4yOTc2NiAwLjAyNDgtMC42MjAxMiAwLjA3NDQtMC4zMjI0NiAwLjAyNDgtMC42MjAxMiAwLjAyNDgtMy4xOTk4IDAtNC45ODU3NC0yLjY1NDF6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCTwvZz4NCgkJPGcgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIgYXJpYS1sYWJlbD0idiI+DQoJCQk8cGF0aCBkPSJtMTA1LjkxNTA2IDE1MS4yOTk0MnEtMC4zOTY4OC0wLjI0ODA1LTEuMTE2MjItMS4wNDE4LTAuMTI0MDItMC4xMjQwMi0wLjI0ODA0LTAuMjIzMjQtMC4xMjQwMy0wLjEyNDAzLTAuMjQ4MDUtMC4yNzI4NS0wLjE5ODQ0LTAuMTI0MDMtMC4zOTY4Ny0wLjEyNDAzLTEuMjg5ODUgMC0wLjk2NzM5IDAuOTY3MzkgMC4xNDg4MyAwLjIyMzI0IDAuMTI0MDMgMC4xOTg0MyAwLjE3MzYzIDAuMTczNjQgMS4xOTA2MiAxLjExNjIxIDAuNDcxMjkgMC40NDY0OSAwLjg5Mjk3IDAuNjQ0OTMgMC4yMjMyNCAwLjE0ODgyIDAuNDQ2NDggMC4xNDg4MiAwLjc0NDE1IDAgMC43NDQxNS0wLjc0NDE0IDAtMC4yOTc2NS0wLjQyMTY4LTAuNjY5NzJ6bTEuODg1MTUtMTIuNjI1NTktMC40NDY0OC0xLjcxMTUycS0xLjk1OTU3LTAuNTQ1NzEtNC42ODgwOS0wLjU0NTcxLTIuNTA1MjcgMC00LjQ4OTY0NyAwLjQ5NjFsLTAuNDk2MDk0IDEuNzExNTJxMi4xNTgwMDgtMC41NzA1MSA0Ljk4NTc0MS0wLjU3MDUxIDMuMDI2MTcgMCA1LjEzNDU3IDAuNjIwMTJ6bS0yLjcwMzcxIDIuNzAzNzEtMi40MDYwNSAwLjk5MjE5LTIuMzgxMjUtMC45OTIxOSAyLjM4MTI1LTAuOTkyMTl6bTIuODAyOTMtMS4yODk4NHEtMi4xMDg0LTAuNTcwNTEtNS4xNTkzNy0wLjU3MDUxLTIuODUyNTQ0IDAtNS4wMzUzNTYgMC41MjA5bC0wLjM0NzI2NiAwLjk2NzM4IDIuMTA4Mzk5IDAuNDcxMjktMi4xODI4MTMgMS4zODkwNi0wLjQ3MTI4OS0wLjA5OTItMC41OTUzMTIgMS43ODU5NHEwLjUyMDg5OC0wLjU0NTcgMi4zNTY0NDUtMC45MTc3NyAxLjgzNTU0Mi0wLjM3MjA3IDQuMjQxNjAyLTAuMzcyMDcgMi4zNTY0NCAwIDQuMTY3MTkgMC4zNzIwNyAxLjgzNTU0IDAuMzcyMDcgMi4zODEyNSAwLjg5Mjk3bC0wLjYyMDEyLTEuNzg1OTQtMC42MjAxMiAwLjEyNDAyLTIuMTgyODEtMS4zODkwNiAyLjIzMjQyLTAuNDcxMjl6bS0wLjgxODU1LTEyLjk3Mjg1di0yLjc3ODEzaC0yLjk3NjU3di0zLjg2OTUzaC0yLjc1MzMydjMuODY5NTNoLTMuMDI2MTY5djIuNzc4MTNoMy4wMjYxNjl2NS41MzE0NGgyLjc1MzMydi01LjUzMTQ0em0tNy43MTQyNjIgMjQuMTg0NTdxLTAuMjcyODUyIDAuMjcyODUtMC4yNzI4NTIgMC42MjAxMSAwIDAuNzQ0MTUgMC43NDQxNDEgMC43NDQxNSAwLjIyMzI0MyAwIDAuMzk2ODczLTAuMTI0MDMgMC40MjE2OC0wLjIyMzI0IDAuODE4NTYtMC42MjAxMiAwLjg5Mjk3LTAuODQzMzUgMS4yNDAyMy0xLjE0MTAxIDAuMDQ5Ni0wLjA0OTYgMC4wNDk2LTAuMTczNjMgMC0wLjk2NzM5LTAuOTY3MzgtMC45NjczOS0wLjE3MzY0IDAtMC4zMjI0NiAwLjE0ODgzLTAuMjIzMjUgMC4yMjMyNC0wLjU0NTcxIDAuNDcxMjktMC4yOTc2NSAwLjIyMzI0LTAuNTQ1Njk5IDAuNTIwOS0wLjIyMzI0MyAwLjI3Mjg1LTAuNTk1MzEzIDAuNTIwOXptMTIuNjI1NTgyLTIyLjYyMTg4cTAuMzQ3MjctMS4zMzk0NS0wLjc2ODk0LTQuOTg1NzR0LTMuNDcyNjYtNi4xMDE5NXEtMC4yOTc2NS0wLjIyMzI0LTAuNjIwMTEtMC4xOTg0NC0wLjQyMTY4IDAuMDI0OC0wLjc5Mzc1IDAuMzQ3MjctMC4zNzIwOCAwLjMyMjQ2LTAuMDk5MiAwLjc2ODk0IDIuOTAyMTQgMS45MDk5NiA0LjM0MDgyIDUuMzA4MiAxLjQzODY3IDMuMzczNDQgMS40MTM4NiA0Ljg2MTcyem0tOS4zMjY1NiAyMy41Mzk2NXEtMS44MzU1NSAyLjY1NDEtNC45NjA5MzYgMi42NTQxLTAuMzIyNDYxIDAtMC42NDQ5MjItMC4wMjQ4LTAuMjk3NjU2LTAuMDQ5Ni0wLjU5NTMxMi0wLjA3NDQtMC43MTkzMzYtMC4wMjQ4LTIuMTA4Mzk5LTAuMjQ4MDQtMS4zODkwNjItMC4yNDgwNS0zLjEwMDU4Ni0xLjExNjIxLTEuNTEzMDg2LTEuMzE0NjUtMy44NDQ3MjYtMS4zMTQ2NS0xLjc4NTkzOCAwLTMuMTAwNTg2IDAuODQzMzYtMC4zNzIwNyAwLjE3MzYzLTAuOTE3NzczIDAuNzE5MzMtMC45OTIxODggMS4wNjY2LTEuNjEyMzA1IDEuMTY1ODItMC40OTYwOTQtMC4yNDgwNC0wLjUyMDg5OS0wLjg0MzM2LTAuMTI0MDIzLTEuMTY1ODIgMS43MTE1MjQtMy4wMDEzNi0wLjMyMjQ2MSAwLjA0OTYtMS4yMTU0MyAwLjI5NzY1LTAuNzQ0MTQgMC4yMjMyNC0wLjk5MjE4NyAwLjIyMzI0LTAuODE4NTU1IDAuMTI0MDMtMC44NjgxNjQgMC4wMjQ4LTAuMjcyODUyLTAuMjcyODUgMC4xOTg0MzctMS4xMTYyMSAwLjM5Njg3NS0wLjcxOTM0IDEuNTM3ODkxLTEuMjY1MDQgMC4xNDg4MjgtMC4wNzQ0IDAuOTQyNTc4LTAuNDIxNjggMi4zMDY4MzYtMS4yMTU0MyA0LjgzNjkxNC0xLjIxNTQzIDMuNjk1ODk4IDAgNi42NzI0NjEgMi41MDUyNyAxLjE5MDYyNSAwLjM5Njg4IDIuNDA2MDU0IDAuMzk2ODggMy43MjA3MDYgMCAzLjg0NDcyNi0zLjA3NTc4LTIuNDA2MDU0LTAuMjIzMjQtNC4wMTgzNTktMC44MTg1Ni0xLjU4NzQ5OS0wLjU5NTMxLTEuNTg3NDk5LTEuMzg5MDZsMS45ODQzNzQtNi41OTgwNXEtMS43MzYzMjgtMi43Mjg1MS0yLjg3NzM0My01LjU1NjI1LTEuMTQxMDE2LTIuODI3NzMtMS4xNDEwMTYtNS4zNTc4MSAwLTcuNTkwMjMgOC4yMzUxNTMtMTEuNjU4MiAwLTAuMzIyNDYgMC4wNzQ0LTAuOTY3MzgtMC44NDMzNi0wLjY5NDU0LTAuODQzMzYtMS43NjExNCAwLTIuMjgyMDMgMi4zMDY4My0yLjI4MjAzIDIuMjgyMDQgMCAyLjI4MjA0IDIuMjgyMDMgMCAwLjk5MjE5LTAuNzE5MzQgMS42NjE5MiAwIDAuNzY4OTQgMC4xOTg0NCAxLjA0MTc5IDAuNDIxNjggMC41OTUzMiAxLjExNjIxIDAuNjIwMTIgMC43MTkzMy0wLjAyNDggMS4xOTA2Mi0wLjY0NDkyIDAuMDk5Mi0wLjE0ODgzIDAuMTk4NDQtMC45MTc3Ny0wLjY0NDkyLTAuNjY5NzMtMC42NDQ5Mi0xLjY2MTkyIDAtMi4zMzE2NCAyLjMzMTY0LTIuMzMxNjR0Mi4zMzE2NCAyLjMzMTY0cTAgMS4zMTQ2NS0xLjE0MTAyIDIuMDMzOTktMC4wOTkyIDAuNDk2MDktMC4wNDk2IDAuNzkzNzUgNC4xOTIgNC45NjA5MyAzLjY0NjI5IDExLjQ1OTc2LTAuMTczNjMgMS44NjAzNS0wLjU3MDUgMy42NzEwOS0wLjM5Njg4IDEuNzg1OTQtMS4zODkwNyAzLjM3MzQ0LTAuMzcyMDcgMC44NDMzNi0xLjE2NTgyIDEuOTA5OTYtMC43Njg5NCAxLjA0MTgtMS4zMzk0NSAxLjk1OTU3bDEuOTU5NTcgNi41OTgwNXEtMC4wMjQ4IDAuNzkzNzUtMS42MzcxMSAxLjM4OTA2LTEuNjEyMyAwLjU5NTMyLTQuMDY3OTcgMC44MTg1NiAwLjEyNDAzIDMuMDc1NzggMy44Njk1MyAzLjA3NTc4IDEuMjE1NDMgMCAyLjQwNjA2LTAuMzk2ODggMi45NTE3Ni0yLjUwNTI3IDYuNjcyNDYtMi41MDUyNyAyLjUzMDA4IDAgNC44MTIxMSAxLjIxNTQzIDAuMjk3NjUgMC4xNDg4MyAwLjUyMDkgMC4yNDgwNSAwLjIyMzI0IDAuMDk5MiAwLjQ0NjQ4IDAuMTczNjMgMS4xMTYyMSAwLjU3MDUxIDEuNTM3ODkgMS4yNjUwNCAwLjA3NDQgMC4yMjMyNCAwLjIyMzI0IDAuNTcwNTEgMC4xNDg4MyAwLjM0NzI2LTAuMDI0OCAwLjU0NTctMC4wNzQ0IDAuMDk5Mi0wLjg2ODE3LTAuMDI0OC0wLjI0ODA0IDAtMC45OTIxOC0wLjIyMzI0LTAuOTE3NzgtMC4yNDgwNC0xLjI0MDI0LTAuMjk3NjUgMS44MzU1NSAxLjg2MDM1IDEuNzM2MzMgMy4wMDEzNi0wLjA0OTYgMC41NzA1MS0wLjU0NTcgMC44NDMzNi0wLjYyMDEyLTAuMDk5Mi0xLjYxMjMxLTEuMTY1ODItMC40OTYwOS0wLjQ5NjA5LTAuODkyOTctMC43MTkzMy0xLjM4OTA2LTAuODQzMzYtMy4xMDA1OC0wLjg0MzM2LTIuMzgxMjUgMC0zLjg2OTUzIDEuMzE0NjUtMS43MTE1MyAwLjg2ODE2LTMuMTAwNTkgMS4xMTYyMS0xLjM4OTA2IDAuMjIzMjQtMi4wODM1OSAwLjI0ODA0LTAuMjk3NjYgMC4wMjQ4LTAuNjIwMTIgMC4wNzQ0LTAuMzIyNDYgMC4wMjQ4LTAuNjIwMTIgMC4wMjQ4LTMuMTk5OCAwLTQuOTg1NzQtMi42NTQxeiIgc3Ryb2tlLXdpZHRoPSIuMjY0NTgzMzIiLz4NCgkJPC9nPg0KCTwvZz4NCjwvc3ZnPg0K')} +.is2d .rook.black {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjUwLjc5OTk5OW1tIiBoZWlnaHQ9IjUwLjc3NTE5Mm1tIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1MC43OTk5OTkgNTAuNzc1MTkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC03NS40MzY4MjksLTkyLjAxMDI2NykiPg0KCQk8ZyBmaWxsPSIjZmZmIj4NCgkJCTxwYXRoIGQ9Im0xMDAuODM2NjggOTUuNDA4MTQzaDMuNDIzMDV2My4zNzM0MzdoNS4xMzQ1N3YtMy4zNzM0MzdoNS45MDM1MnY4Ljg1NTI3N2wtMy45OTM1NiA0LjYxMzY3cTEuMjg5ODQgMS42MzcxMSAwLjA0OTYgMy40NDc4NS0wLjE5ODQ0IDAuMzIyNDYtMC4xOTg0NCAwLjU5NTMxIDAgMC4zMjI0NiAwLjE5ODQ0IDAuNjIwMTIgMC41MjA5IDAuNzY4OTQgMC40OTYwOSAyLjE4MjgxIDAgMS4zODkwNi0wLjUyMDg5IDIuMTgyODEtMC4xNzM2NCAwLjI0ODA1LTAuMTczNjQgMC41MjA5IDAgMC4zNDcyNyAwLjIyMzI1IDAuNjQ0OTIgMS4xNjU4MiAxLjc2MTE0LTAuMDQ5NiAzLjQ3MjY2LTAuMTczNjQgMC4yOTc2Ni0wLjE3MzY0IDAuNTcwNTF0MC4xNzM2NCAwLjU3MDUxcTAuNTQ1NyAwLjgxODU1IDAuNTQ1NyAyLjI4MjAzIDAgMS40Mzg2Ny0wLjU5NTMxIDIuMTMzMmw0LjAxODM2IDIuMDA5MTh2Mi4xMzMyaDEuNjYxOTF2Ny4xOTMzNmgtMzIuMjcwODk4di03LjE2ODU1aDEuNjg2NzE5di0yLjEzMzIxbDMuOTkzNTU0LTIuMDMzOThxLTAuNTk1MzEyLTAuNjk0NTMtMC41OTUzMTItMi4xMzMydDAuNTQ1NzAzLTIuMjU3MjNxMC4xOTg0MzctMC4yNzI4NSAwLjE5ODQzNy0wLjU3MDUxIDAtMC4yNDgwNC0wLjE5ODQzNy0wLjU3MDUtMS4yMTU0My0xLjczNjMzLTAuMDI0ODEtMy40NzI2NiAwLjIyMzI0Mi0wLjM5Njg4IDAuMjIzMjQyLTAuNjQ0OTIgMC0wLjI0ODA1LTAuMTczNjMyLTAuNTQ1NzEtMC41NDU3MDMtMC43OTM3NS0wLjU3MDUwOC0yLjE4MjgxIDAtMS40MTM4NyAwLjUyMDg5OC0yLjE4MjgxIDAuMjIzMjQyLTAuMjk3NjYgMC4yMjMyNDItMC42MjAxMiAwLTAuMjcyODUtMC4xOTg0MzctMC41NzA1MS0xLjI2NTAzOS0xLjgxMDc0IDAuMDQ5NjEtMy40NzI2NWwtMy45OTM1NTQtNC41ODg4N3YtOC44NTUyNzNoNS45MDM1MTV2My4zNDg2MzNsNS4xMDk3NjYgMC4wMjQ4MXYtMy4zNzM0Mzh6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtODguMTM2NjgzIDEwMS43MDg1M3YyLjE1ODAxcTMuMTc1LTAuMTQ4ODMgNi4zMjUxOTYtMC4yOTc2NiAzLjE3NS0wLjE3MzYzIDYuMzc0ODAxLTAuMTczNjMgMy4xMjUzOSAwIDYuMzAwMzkgMC4xOTg0NCAzLjE5OTgxIDAuMTk4NDQgNi4zOTk2MSAwLjI3Mjg1IDAtMC44MTg1NSAwLTEuMDY2NiAwLTAuMjcyODUgMC0xLjA5MTQxeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTg5LjIwMzI4NSAxMzAuOTI4NDVxLTEuMDY2NjAyIDAuMDk5Mi0xLjA2NjYwMiAxLjA2NjYxIDAgMS4wNjY2IDEuMDY2NjAyIDEuMDY2NmwxMS42MzMzOTUtMC4zOTY4OCAxMS42MzM0IDAuMzk2ODhxMS4wNjY2IDAgMS4wNjY2LTEuMDY2NiAwLTAuOTY3MzktMS4wNjY2LTEuMDY2NjEtMi45MDIxNS0wLjE3MzYzLTUuODI5MS0wLjI5NzY1LTIuOTAyMTUtMC4xNDg4My01LjgwNDMtMC4xNDg4My0yLjkwMjE0NSAwLTUuODI5MDk4IDAuMTQ4ODMtMi45MDIxNDkgMC4xMjQwMi01LjgwNDI5NyAwLjI5NzY1eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwMi4xMDE3MiAxMjQuMjA2MzhxMC43MTkzNC0wLjU3MDUgMi4xMDg0LTAuNTcwNSAxLjQxMzg3IDAgMi4xNTgwMSAwLjU3MDUgMC43NDQxNCAwLjU5NTMyIDAuNzQ0MTQgMS43ODU5NCAwLjAyNDggMS4xOTA2My0wLjc0NDE0IDEuNTYyNy0wLjc5Mzc1IDAuNDIxNjgtMi4xNTgwMSAwLjQyMTY4dC0yLjEwODQtMC40MjE2OHEtMC43OTM3NS0wLjM3MjA3LTAuNzY4OTQtMS41NjI3IDAuMDI0OC0xLjE5MDYyIDAuNzY4OTQtMS43ODU5NHoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im05NS4zMDUyMzggMTI0LjIwNjM4cTAuNzQ0MTQxLTAuNTcwNSAyLjEzMzIwMy0wLjU3MDUgMS4zODkwNjMgMCAyLjEzMzIwMyAwLjU3MDUgMC43NDQxMzYgMC41OTUzMiAwLjY2OTcyNiAxLjc4NTk0LTAuMDQ5NiAxLjE5MDYzLTAuNjY5NzI2IDEuNTYyNy0wLjY0NDkyMiAwLjQyMTY4LTIuMTgyODEyIDAuMzk2ODctMS41MTMwODYtMC4wNDk2LTIuMDgzNTk0LTAuMzk2ODctMC41OTUzMTItMC4zMjI0Ni0wLjY2OTcyNy0xLjUzNzg5LTAuMDc0NDEtMS4yMTU0MyAwLjY2OTcyNy0xLjgxMDc1eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwMC44MzY2OCAxMDYuMzIyMjFxLTIuMzU2NDQyIDAtNS40NTcwMjggMC4zMjI0Ni0zLjEwMDU4NiAwLjI5NzY1LTMuODk0MzM2IDAuNTQ1Ny0wLjgxODU1NCAwLjI5NzY2LTAuNzQ0MTQgMC45NDI1OCAwLjA3NDQxIDAuNjQ0OTIgMC43NDQxNCAwLjg0MzM2IDAuNjY5NzI3IDAuMjIzMjQgMi42NTQxMDItMC4wNDk2IDEuOTg0Mzc1LTAuMjcyODUgMi40NTU2NjQgMC4wNDk2IDAuNDQ2NDg0IDAuMzQ3MjYgMC40NDY0ODQgMS42MzcxMSAwIDEuMjY1MDQtMC40NDY0ODQgMS43MzYzMi0wLjQ3MTI4OSAwLjQ3MTI5LTIuNTU0ODgzIDAuMTI0MDMtMi4wNTg3ODktMC4zNDcyNy0yLjU1NDg4My0wLjEyNDAzLTAuNDk2MDk0IDAuMjIzMjUtMC4zOTY4NzUgMC44MTg1NiAwLjA5OTIyIDAuNTcwNTEgMC4zOTY4NzUgMC44NDMzNiAwLjI5NzY1NiAwLjI5NzY1IDAuODY4MTY0LTAuMTI0MDMgMC41OTUzMTMtMC40MjE2NyAwLjg5Mjk2OSAwLjEyNDAzIDAuMjk3NjU2IDAuNTk1MzEgMC4yOTc2NTYgMS43MTE1MnQtMC4yOTc2NTYgMS42NjE5MnEtMC4yOTc2NTYgMC41NzA1LTAuODkyOTY5IDAuMTQ4ODItMC41NzA1MDgtMC40NDY0OC0wLjg2ODE2NC0wLjE0ODgyLTAuMzIyNDYxIDAuMzIyNDYtMC4zNDcyNjUgMC45NjczOCAwIDAuNjIwMTIgMC4zNDcyNjUgMC43OTM3NSAwLjMyMjQ2MSAwLjIyMzI0IDIuNDgwNDY5LTAuMDk5MiAyLjE1ODAwOC0wLjM0NzI3IDIuNjI5Mjk3IDAuMDk5MiAwLjQ0NjQ4NCAwLjQ3MTI5IDAuNDQ2NDg0IDEuNjYxOTEgMCAxLjE5MDYzLTAuNDQ2NDg0IDEuNzExNTMtMC40NzEyODkgMC41NDU3LTIuNjU0MTAyIDAuMTczNjMtMi4xNTgwMDgtMC4zOTY4OC0yLjQ1NTY2NC0wLjE3MzYzLTAuOTY3MzgzIDAuNzkzNzUgMCAxLjY4NjcxIDAuMjk3NjU2IDAuMjk3NjYgMC44NjgxNjQtMC4xMjQwMiAwLjU5NTMxMy0wLjQyMTY4IDAuODkyOTY5IDAuMTI0MDIgMC4yOTc2NTYgMC41NzA1MSAwLjI5NzY1NiAxLjY4NjcydC0wLjI5NzY1NiAxLjY2MTkycS0wLjI5NzY1NiAwLjU5NTMxLTAuODkyOTY5IDAuMTczNjMtMC41NzA1MDgtMC40NDY0OC0wLjg2ODE2NC0wLjE3MzYzLTAuMjk3NjU2IDAuMjk3NjUtMC40NzEyODkgMC44OTI5Ny0wLjE3MzYzMyAwLjU3MDUgMC40NzEyODkgMC43OTM3NSAwLjQ5NjA5NCAwLjE5ODQzIDMuMjc0MjE5LTAuMDc0NCAyLjc3ODEyNS0wLjI3Mjg1IDYuMDc3MTQ1LTAuMjcyODUgMy4yNzQyMiAwIDYuMTI2NzYgMC4yMjMyNCAyLjg1MjU0IDAuMTk4NDQgMy4yMjQ2MSAwLjEyNDAzIDAuNTIwOS0wLjA3NDQgMC4zOTY4OC0wLjcxOTM0LTAuMDk5Mi0wLjY2OTczLTAuMzk2ODgtMC45NjczOC0wLjMyMjQ2LTAuMjcyODUtMC45MTc3NyAwLjE3MzYzLTAuNTcwNTEgMC40MjE2OC0wLjg0MzM2LTAuMTczNjMtMC4yOTc2Ni0wLjU0NTcxLTAuMjk3NjYtMS42NjE5MnQwLjI5NzY2LTEuNjg2NzJxMC4yNzI4NS0wLjU0NTcgMC44NjgxNi0wLjEyNDAydDAuODkyOTcgMC4xMjQwMnEwLjkxNzc3LTAuOTE3NzcgMC0xLjY4NjcxLTAuMjk3NjYtMC4yMjMyNS0yLjU1NDg4IDAuMTI0MDItMi4yNTcyMyAwLjM0NzI2LTIuNTc5NjktMC4xMjQwMi0wLjMyMjQ2LTAuNDQ2NDktMC4zNzIwNy0xLjU2MjctMC4wMjQ4LTEuMTQxMDIgMC4zNzIwNy0xLjgxMDc0IDAuMzk2ODgtMC42Njk3MyAyLjU3OTY5LTAuMjQ4MDUgMi4yMDc2MSAwLjQyMTY4IDIuNTU0ODggMC4yNDgwNSAwLjI5NzY2LTAuMTQ4ODMgMC4yOTc2Ni0wLjc5Mzc1dC0wLjI5NzY2LTAuOTY3MzhxLTAuMzIyNDYtMC4yOTc2Ni0wLjkxNzc3IDAuMTQ4ODItMC41NzA1MSAwLjQyMTY4LTAuODQzMzYtMC4xNDg4Mi0wLjI5NzY2LTAuNTQ1NzEtMC4yOTc2Ni0xLjY2MTkydDAuMjk3NjYtMS43MTE1MnEwLjI3Mjg1LTAuNTQ1NyAwLjg0MzM2LTAuMTI0MDMgMC41OTUzMSAwLjQyMTY4IDAuOTE3NzcgMC4xMjQwMyAwLjI5NzY2LTAuMjcyODUgMC4zMjI0Ni0wLjg0MzM2IDAuMDQ5Ni0wLjU5NTMxLTAuMzIyNDYtMC44MTg1Ni0wLjQyMTY4LTAuMjIzMjQtMi41Nzk2OSAwLjEyNDAzLTIuMTU4IDAuMzQ3MjYtMi41NTQ4OC0wLjEyNDAzLTAuMzk2ODctMC40NzEyOC0wLjM5Njg3LTEuNjg2NzF0MC4zOTY4Ny0xLjY4NjcycTAuMzk2ODgtMC40NDY0OSAyLjQzMDg2LTAuMDQ5NiAyLjAzMzk4IDAuMzk2ODcgMi43MDM3MSAwLjA0OTYgMC42NDQ5Mi0wLjMyMjQ2IDAuNjk0NTMtMC44OTI5NyAwLjA3NDQtMC41OTUzMS0wLjY5NDUzLTAuODkyOTctMC44MTg1NS0wLjI0ODA1LTMuOTQzOTQtMC41NDU3LTMuMTAwNTktMC4zMjI0Ni01LjQwNzQzLTAuMzIyNDZ6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtOTguNzc3ODk0IDEwOC45NzYzMXEwLjY5NDUzMS0wLjU3MDUxIDIuMDMzOTg2LTAuNTcwNTEgMS4zNjQyNiAwIDIuMDgzNTkgMC41NzA1MSAwLjcxOTM0IDAuNTk1MzEgMC43MTkzNCAxLjY4NjcyIDAgMS4wOTE0LTAuNzE5MzQgMS42ODY3MS0wLjcxOTMzIDAuNTk1MzItMi4wODM1OSAwLjU5NTMyLTEuMzM5NDU1IDAtMi4wMzM5ODYtMC41OTUzMi0wLjcxOTMzNi0wLjU5NTMxLTAuNzE5MzM2LTEuNjg2NzEgMC0xLjA5MTQxIDAuNzE5MzM2LTEuNjg2NzJ6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtMTAyLjEwMTcyIDExNC4wMTE2NnEwLjcxOTM0LTAuNTcwNTEgMi4xMDg0LTAuNTcwNTEgMS40MTM4NyAwIDIuMTU4MDEgMC41NzA1MSAwLjc0NDE0IDAuNTk1MzEgMC43NDQxNCAxLjcxMTUyIDAgMS4wOTE0MS0wLjc0NDE0IDEuNjYxOTItMC43NDQxNCAwLjU5NTMxLTIuMTU4MDEgMC41OTUzMS0xLjM4OTA2IDAtMi4xMDg0LTAuNTk1MzEtMC43NDQxNC0wLjU3MDUxLTAuNzQ0MTQtMS42NjE5MiAwLTEuMTE2MjEgMC43NDQxNC0xLjcxMTUyeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTk1LjMwNTIzOCAxMTQuMDExNjZxMC43NDQxNDEtMC41NzA1MSAyLjEzMzIwMy0wLjU3MDUxIDEuMzg5MDYzIDAgMi4xMzMyMDMgMC41NzA1MSAwLjc0NDEzNiAwLjU5NTMxIDAuNzQ0MTM2IDEuNzExNTIgMCAxLjA5MTQxLTAuNzQ0MTM2IDEuNjYxOTItMC43NDQxNCAwLjU5NTMxLTIuMTMzMjAzIDAuNTk1MzEtMS4zODkwNjIgMC0yLjEzMzIwMy0wLjU5NTMxLTAuNzQ0MTQxLTAuNTcwNTEtMC43NDQxNDEtMS42NjE5MiAwLTEuMTE2MjEgMC43NDQxNDEtMS43MTE1MnoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im05OC43Nzc4OTQgMTE5LjE0NjIzcTAuNjk0NTMxLTAuNTcwNTEgMi4wMzM5ODYtMC41NzA1MSAxLjM2NDI2IDAgMi4wODM1OSAwLjU3MDUxIDAuNzE5MzQgMC41OTUzMSAwLjcxOTM0IDEuNzExNTIgMCAxLjA5MTQxLTAuNzE5MzQgMS42NjE5Mi0wLjcxOTMzIDAuNTk1MzEtMi4wODM1OSAwLjU5NTMxLTEuMzM5NDU1IDAtMi4wMzM5ODYtMC41OTUzMS0wLjcxOTMzNi0wLjU3MDUxLTAuNzE5MzM2LTEuNjYxOTIgMC0xLjExNjIxIDAuNzE5MzM2LTEuNzExNTJ6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtODYuNDQ5OTY1IDEzNC43NDgzOHYxLjY4NjcyaDI4Ljc5ODI0NXYtMS42ODY3MnoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJPC9nPg0KCQk8ZyBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIiBhcmlhLWxhYmVsPSJ0Ij4NCgkJCTxwYXRoIGQ9Im0xMDAuODM2NjggOTUuNDA4MTQzaDMuNDIzMDV2My4zNzM0MzdoNS4xMzQ1N3YtMy4zNzM0MzdoNS45MDM1MnY4Ljg1NTI3N2wtMy45OTM1NiA0LjYxMzY3cTEuMjg5ODQgMS42MzcxMSAwLjA0OTYgMy40NDc4NS0wLjE5ODQ0IDAuMzIyNDYtMC4xOTg0NCAwLjU5NTMxIDAgMC4zMjI0NiAwLjE5ODQ0IDAuNjIwMTIgMC41MjA5IDAuNzY4OTQgMC40OTYwOSAyLjE4MjgxIDAgMS4zODkwNi0wLjUyMDg5IDIuMTgyODEtMC4xNzM2NCAwLjI0ODA1LTAuMTczNjQgMC41MjA5IDAgMC4zNDcyNyAwLjIyMzI1IDAuNjQ0OTIgMS4xNjU4MiAxLjc2MTE0LTAuMDQ5NiAzLjQ3MjY2LTAuMTczNjQgMC4yOTc2Ni0wLjE3MzY0IDAuNTcwNTF0MC4xNzM2NCAwLjU3MDUxcTAuNTQ1NyAwLjgxODU1IDAuNTQ1NyAyLjI4MjAzIDAgMS40Mzg2Ny0wLjU5NTMxIDIuMTMzMmw0LjAxODM2IDIuMDA5MTh2Mi4xMzMyaDEuNjYxOTF2Ny4xOTMzNmgtMzIuMjcwODk4di03LjE2ODU1aDEuNjg2NzE5di0yLjEzMzIxbDMuOTkzNTU0LTIuMDMzOThxLTAuNTk1MzEyLTAuNjk0NTMtMC41OTUzMTItMi4xMzMydDAuNTQ1NzAzLTIuMjU3MjNxMC4xOTg0MzctMC4yNzI4NSAwLjE5ODQzNy0wLjU3MDUxIDAtMC4yNDgwNC0wLjE5ODQzNy0wLjU3MDUtMS4yMTU0My0xLjczNjMzLTAuMDI0ODEtMy40NzI2NiAwLjIyMzI0Mi0wLjM5Njg4IDAuMjIzMjQyLTAuNjQ0OTIgMC0wLjI0ODA1LTAuMTczNjMyLTAuNTQ1NzEtMC41NDU3MDMtMC43OTM3NS0wLjU3MDUwOC0yLjE4MjgxIDAtMS40MTM4NyAwLjUyMDg5OC0yLjE4MjgxIDAuMjIzMjQyLTAuMjk3NjYgMC4yMjMyNDItMC42MjAxMiAwLTAuMjcyODUtMC4xOTg0MzctMC41NzA1MS0xLjI2NTAzOS0xLjgxMDc0IDAuMDQ5NjEtMy40NzI2NWwtMy45OTM1NTQtNC41ODg4N3YtOC44NTUyNzNoNS45MDM1MTV2My4zNDg2MzNsNS4xMDk3NjYgMC4wMjQ4MXYtMy4zNzM0Mzh6bS0xMi42OTk5OTcgNi4zMDAzODd2Mi4xNTgwMXEzLjE3NS0wLjE0ODgzIDYuMzI1MTk2LTAuMjk3NjYgMy4xNzUtMC4xNzM2MyA2LjM3NDgwMS0wLjE3MzYzIDMuMTI1MzkgMCA2LjMwMDM5IDAuMTk4NDQgMy4xOTk4MSAwLjE5ODQ0IDYuMzk5NjEgMC4yNzI4NSAwLTAuODE4NTUgMC0xLjA2NjYgMC0wLjI3Mjg1IDAtMS4wOTE0MXptMS4wNjY2MDIgMjkuMjE5OTJxLTEuMDY2NjAyIDAuMDk5Mi0xLjA2NjYwMiAxLjA2NjYxIDAgMS4wNjY2IDEuMDY2NjAyIDEuMDY2NmwxMS42MzMzOTUtMC4zOTY4OCAxMS42MzM0IDAuMzk2ODhxMS4wNjY2IDAgMS4wNjY2LTEuMDY2NiAwLTAuOTY3MzktMS4wNjY2LTEuMDY2NjEtMi45MDIxNS0wLjE3MzYzLTUuODI5MS0wLjI5NzY1LTIuOTAyMTUtMC4xNDg4My01LjgwNDMtMC4xNDg4My0yLjkwMjE0NSAwLTUuODI5MDk4IDAuMTQ4ODMtMi45MDIxNDkgMC4xMjQwMi01LjgwNDI5NyAwLjI5NzY1em0xMi44OTg0MzUtNi43MjIwN3EwLjcxOTM0LTAuNTcwNSAyLjEwODQtMC41NzA1IDEuNDEzODcgMCAyLjE1ODAxIDAuNTcwNSAwLjc0NDE0IDAuNTk1MzIgMC43NDQxNCAxLjc4NTk0IDAuMDI0OCAxLjE5MDYzLTAuNzQ0MTQgMS41NjI3LTAuNzkzNzUgMC40MjE2OC0yLjE1ODAxIDAuNDIxNjh0LTIuMTA4NC0wLjQyMTY4cS0wLjc5Mzc1LTAuMzcyMDctMC43Njg5NC0xLjU2MjcgMC4wMjQ4LTEuMTkwNjIgMC43Njg5NC0xLjc4NTk0em0tNi43OTY0ODIgMHEwLjc0NDE0MS0wLjU3MDUgMi4xMzMyMDMtMC41NzA1IDEuMzg5MDYzIDAgMi4xMzMyMDMgMC41NzA1IDAuNzQ0MTM2IDAuNTk1MzIgMC42Njk3MjYgMS43ODU5NC0wLjA0OTYgMS4xOTA2My0wLjY2OTcyNiAxLjU2MjctMC42NDQ5MjIgMC40MjE2OC0yLjE4MjgxMiAwLjM5Njg3LTEuNTEzMDg2LTAuMDQ5Ni0yLjA4MzU5NC0wLjM5Njg3LTAuNTk1MzEyLTAuMzIyNDYtMC42Njk3MjctMS41Mzc4OS0wLjA3NDQxLTEuMjE1NDMgMC42Njk3MjctMS44MTA3NXptNS41MzE0NDItMTcuODg0MTdxLTIuMzU2NDQyIDAtNS40NTcwMjggMC4zMjI0Ni0zLjEwMDU4NiAwLjI5NzY1LTMuODk0MzM2IDAuNTQ1Ny0wLjgxODU1NCAwLjI5NzY2LTAuNzQ0MTQgMC45NDI1OCAwLjA3NDQxIDAuNjQ0OTIgMC43NDQxNCAwLjg0MzM2IDAuNjY5NzI3IDAuMjIzMjQgMi42NTQxMDItMC4wNDk2IDEuOTg0Mzc1LTAuMjcyODUgMi40NTU2NjQgMC4wNDk2IDAuNDQ2NDg0IDAuMzQ3MjYgMC40NDY0ODQgMS42MzcxMSAwIDEuMjY1MDQtMC40NDY0ODQgMS43MzYzMi0wLjQ3MTI4OSAwLjQ3MTI5LTIuNTU0ODgzIDAuMTI0MDMtMi4wNTg3ODktMC4zNDcyNy0yLjU1NDg4My0wLjEyNDAzLTAuNDk2MDk0IDAuMjIzMjUtMC4zOTY4NzUgMC44MTg1NiAwLjA5OTIyIDAuNTcwNTEgMC4zOTY4NzUgMC44NDMzNiAwLjI5NzY1NiAwLjI5NzY1IDAuODY4MTY0LTAuMTI0MDMgMC41OTUzMTMtMC40MjE2NyAwLjg5Mjk2OSAwLjEyNDAzIDAuMjk3NjU2IDAuNTk1MzEgMC4yOTc2NTYgMS43MTE1MnQtMC4yOTc2NTYgMS42NjE5MnEtMC4yOTc2NTYgMC41NzA1LTAuODkyOTY5IDAuMTQ4ODItMC41NzA1MDgtMC40NDY0OC0wLjg2ODE2NC0wLjE0ODgyLTAuMzIyNDYxIDAuMzIyNDYtMC4zNDcyNjUgMC45NjczOCAwIDAuNjIwMTIgMC4zNDcyNjUgMC43OTM3NSAwLjMyMjQ2MSAwLjIyMzI0IDIuNDgwNDY5LTAuMDk5MiAyLjE1ODAwOC0wLjM0NzI3IDIuNjI5Mjk3IDAuMDk5MiAwLjQ0NjQ4NCAwLjQ3MTI5IDAuNDQ2NDg0IDEuNjYxOTEgMCAxLjE5MDYzLTAuNDQ2NDg0IDEuNzExNTMtMC40NzEyODkgMC41NDU3LTIuNjU0MTAyIDAuMTczNjMtMi4xNTgwMDgtMC4zOTY4OC0yLjQ1NTY2NC0wLjE3MzYzLTAuOTY3MzgzIDAuNzkzNzUgMCAxLjY4NjcxIDAuMjk3NjU2IDAuMjk3NjYgMC44NjgxNjQtMC4xMjQwMiAwLjU5NTMxMy0wLjQyMTY4IDAuODkyOTY5IDAuMTI0MDIgMC4yOTc2NTYgMC41NzA1MSAwLjI5NzY1NiAxLjY4NjcydC0wLjI5NzY1NiAxLjY2MTkycS0wLjI5NzY1NiAwLjU5NTMxLTAuODkyOTY5IDAuMTczNjMtMC41NzA1MDgtMC40NDY0OC0wLjg2ODE2NC0wLjE3MzYzLTAuMjk3NjU2IDAuMjk3NjUtMC40NzEyODkgMC44OTI5Ny0wLjE3MzYzMyAwLjU3MDUgMC40NzEyODkgMC43OTM3NSAwLjQ5NjA5NCAwLjE5ODQzIDMuMjc0MjE5LTAuMDc0NCAyLjc3ODEyNS0wLjI3Mjg1IDYuMDc3MTQ1LTAuMjcyODUgMy4yNzQyMiAwIDYuMTI2NzYgMC4yMjMyNCAyLjg1MjU0IDAuMTk4NDQgMy4yMjQ2MSAwLjEyNDAzIDAuNTIwOS0wLjA3NDQgMC4zOTY4OC0wLjcxOTM0LTAuMDk5Mi0wLjY2OTczLTAuMzk2ODgtMC45NjczOC0wLjMyMjQ2LTAuMjcyODUtMC45MTc3NyAwLjE3MzYzLTAuNTcwNTEgMC40MjE2OC0wLjg0MzM2LTAuMTczNjMtMC4yOTc2Ni0wLjU0NTcxLTAuMjk3NjYtMS42NjE5MnQwLjI5NzY2LTEuNjg2NzJxMC4yNzI4NS0wLjU0NTcgMC44NjgxNi0wLjEyNDAydDAuODkyOTcgMC4xMjQwMnEwLjkxNzc3LTAuOTE3NzcgMC0xLjY4NjcxLTAuMjk3NjYtMC4yMjMyNS0yLjU1NDg4IDAuMTI0MDItMi4yNTcyMyAwLjM0NzI2LTIuNTc5NjktMC4xMjQwMi0wLjMyMjQ2LTAuNDQ2NDktMC4zNzIwNy0xLjU2MjctMC4wMjQ4LTEuMTQxMDIgMC4zNzIwNy0xLjgxMDc0IDAuMzk2ODgtMC42Njk3MyAyLjU3OTY5LTAuMjQ4MDUgMi4yMDc2MSAwLjQyMTY4IDIuNTU0ODggMC4yNDgwNSAwLjI5NzY2LTAuMTQ4ODMgMC4yOTc2Ni0wLjc5Mzc1dC0wLjI5NzY2LTAuOTY3MzhxLTAuMzIyNDYtMC4yOTc2Ni0wLjkxNzc3IDAuMTQ4ODItMC41NzA1MSAwLjQyMTY4LTAuODQzMzYtMC4xNDg4Mi0wLjI5NzY2LTAuNTQ1NzEtMC4yOTc2Ni0xLjY2MTkydDAuMjk3NjYtMS43MTE1MnEwLjI3Mjg1LTAuNTQ1NyAwLjg0MzM2LTAuMTI0MDMgMC41OTUzMSAwLjQyMTY4IDAuOTE3NzcgMC4xMjQwMyAwLjI5NzY2LTAuMjcyODUgMC4zMjI0Ni0wLjg0MzM2IDAuMDQ5Ni0wLjU5NTMxLTAuMzIyNDYtMC44MTg1Ni0wLjQyMTY4LTAuMjIzMjQtMi41Nzk2OSAwLjEyNDAzLTIuMTU4IDAuMzQ3MjYtMi41NTQ4OC0wLjEyNDAzLTAuMzk2ODctMC40NzEyOC0wLjM5Njg3LTEuNjg2NzF0MC4zOTY4Ny0xLjY4NjcycTAuMzk2ODgtMC40NDY0OSAyLjQzMDg2LTAuMDQ5NiAyLjAzMzk4IDAuMzk2ODcgMi43MDM3MSAwLjA0OTYgMC42NDQ5Mi0wLjMyMjQ2IDAuNjk0NTMtMC44OTI5NyAwLjA3NDQtMC41OTUzMS0wLjY5NDUzLTAuODkyOTctMC44MTg1NS0wLjI0ODA1LTMuOTQzOTQtMC41NDU3LTMuMTAwNTktMC4zMjI0Ni01LjQwNzQzLTAuMzIyNDZ6bS0yLjA1ODc4NiAyLjY1NDFxMC42OTQ1MzEtMC41NzA1MSAyLjAzMzk4Ni0wLjU3MDUxIDEuMzY0MjYgMCAyLjA4MzU5IDAuNTcwNTEgMC43MTkzNCAwLjU5NTMxIDAuNzE5MzQgMS42ODY3MiAwIDEuMDkxNC0wLjcxOTM0IDEuNjg2NzEtMC43MTkzMyAwLjU5NTMyLTIuMDgzNTkgMC41OTUzMi0xLjMzOTQ1NSAwLTIuMDMzOTg2LTAuNTk1MzItMC43MTkzMzYtMC41OTUzMS0wLjcxOTMzNi0xLjY4NjcxIDAtMS4wOTE0MSAwLjcxOTMzNi0xLjY4Njcyem0zLjMyMzgyNiA1LjAzNTM1cTAuNzE5MzQtMC41NzA1MSAyLjEwODQtMC41NzA1MSAxLjQxMzg3IDAgMi4xNTgwMSAwLjU3MDUxIDAuNzQ0MTQgMC41OTUzMSAwLjc0NDE0IDEuNzExNTIgMCAxLjA5MTQxLTAuNzQ0MTQgMS42NjE5Mi0wLjc0NDE0IDAuNTk1MzEtMi4xNTgwMSAwLjU5NTMxLTEuMzg5MDYgMC0yLjEwODQtMC41OTUzMS0wLjc0NDE0LTAuNTcwNTEtMC43NDQxNC0xLjY2MTkyIDAtMS4xMTYyMSAwLjc0NDE0LTEuNzExNTJ6bS02Ljc5NjQ4MiAwcTAuNzQ0MTQxLTAuNTcwNTEgMi4xMzMyMDMtMC41NzA1MSAxLjM4OTA2MyAwIDIuMTMzMjAzIDAuNTcwNTEgMC43NDQxMzYgMC41OTUzMSAwLjc0NDEzNiAxLjcxMTUyIDAgMS4wOTE0MS0wLjc0NDEzNiAxLjY2MTkyLTAuNzQ0MTQgMC41OTUzMS0yLjEzMzIwMyAwLjU5NTMxLTEuMzg5MDYyIDAtMi4xMzMyMDMtMC41OTUzMS0wLjc0NDE0MS0wLjU3MDUxLTAuNzQ0MTQxLTEuNjYxOTIgMC0xLjExNjIxIDAuNzQ0MTQxLTEuNzExNTJ6bTMuNDcyNjU2IDUuMTM0NTdxMC42OTQ1MzEtMC41NzA1MSAyLjAzMzk4Ni0wLjU3MDUxIDEuMzY0MjYgMCAyLjA4MzU5IDAuNTcwNTEgMC43MTkzNCAwLjU5NTMxIDAuNzE5MzQgMS43MTE1MiAwIDEuMDkxNDEtMC43MTkzNCAxLjY2MTkyLTAuNzE5MzMgMC41OTUzMS0yLjA4MzU5IDAuNTk1MzEtMS4zMzk0NTUgMC0yLjAzMzk4Ni0wLjU5NTMxLTAuNzE5MzM2LTAuNTcwNTEtMC43MTkzMzYtMS42NjE5MiAwLTEuMTE2MjEgMC43MTkzMzYtMS43MTE1MnptLTEyLjMyNzkyOSAxNS42MDIxNXYxLjY4NjcyaDI4Ljc5ODI0NXYtMS42ODY3MnoiIHN0cm9rZS13aWR0aD0iLjI2NDU4MzMyIi8+DQoJCTwvZz4NCgk8L2c+DQo8L3N2Zz4NCg==')} +.is2d .queen.black {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjUwLjgwMDAxOG1tIiBoZWlnaHQ9IjUwLjc3NTE4OG1tIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1MC44MDAwMTggNTAuNzc1MTg4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC05My44MTE2LC0xNDMuNjYwMTEpIj4NCgkJPGcgZmlsbD0iI2ZmZiI+DQoJCQk8cGF0aCBkPSJtMTIwLjQyNjU1IDE1Mi43NjM0N3EwLjM3MjA3IDQuMDE4MzYgMC43NDQxNCA4LjAzNjcyIDAuMzk2ODcgMy45OTM1NiAwLjc5Mzc1IDcuOTg3MTEgMC4wMjQ4IDAuNTcwNTEgMC41NzA1MSAwLjU3MDUxIDAuMzk2ODctMC4wMjQ4IDAuNTQ1Ny0wLjM0NzI3IDIuMTU4MDEtNS4yMDg5OCAzLjE3NS04LjA2MTUyIDEuMDQxOC0yLjg3NzM0IDEuMjY1MDQtMy41NDcwNy0xLjE0MTAyLTEuMDkxNDEtMS4xNDEwMi0yLjQ1NTY2IDAtMS4xOTA2MyAwLjg0MzM2LTIuMDMzOTkgMC44NjgxNy0wLjg2ODE2IDIuMDgzNi0wLjg2ODE2IDEuMTkwNjIgMCAyLjAzMzk4IDAuODY4MTYgMC44NjgxNiAwLjg0MzM2IDAuODY4MTYgMi4wMzM5OSAwIDIuMTU4LTIuMjMyNDIgMi45MjY5NWwtMS44MTA3NCAxMC44MTQ4NHEtMC4xMjQwMiAwLjc0NDE0IDAuNTIwOSAwLjc0NDE0IDAuNTIwOSAwIDAuNzkzNzUtMC4yNzI4NSAyLjk3NjU2LTIuOTc2NTYgNC4yNjY0MS00LjYxMzY3IDEuMzE0NjQtMS42MzcxMSAxLjgzNTU0LTIuMjgyMDMtMC41NDU3LTAuNzE5MzQtMC41NDU3LTEuNzM2MzMgMC0yLjkwMjE1IDIuOTAyMTUtMi45MDIxNSAxLjE5MDYyIDAgMi4wMzM5OCAwLjg2ODE3IDAuODY4MTcgMC44NDMzNiAwLjg2ODE3IDIuMDMzOTggMCAxLjIxNTQzLTAuODY4MTcgMi4wNTg3OS0wLjg0MzM2IDAuODQzMzYtMi4wMzM5OCAwLjg0MzM2LTAuMzcyMDcgMC0wLjY2OTczLTAuMDc0NC0xLjk4NDM3IDQuMjkxMjEtMy4xNzUgOC43ODA4NS0xLjAxNjk5IDMuNjQ2MjktMS4yNjUwNCA2LjkyMDUxIDAuMTQ4ODMgMC42OTQ1MyAwLjE3MzYzIDAuNzE5MzQtMC4wNzQ0LTAuMjk3NjYgMC4wOTkyIDAuNTcwNTEgMC4wOTkyIDAuMzk2ODcgMC4wOTkyIDAuNzY4OTQtMC4xNDg4MyAwLjM5Njg4LTAuNjIwMTEgMC44OTI5Ny0wLjQyMTY4IDAuNDcxMjktMC42MjAxMiAxLjg2MDM1IDAuOTE3NzcgMS4yODk4NSAwLjkxNzc3IDIuMDgzNiAwIDIuMDgzNTktNC4wMTgzNiAzLjU3MTg3dC05LjY0OTAyIDEuNDg4MjhxLTUuNjU1NDcgMC05LjY3MzgzLTEuNDg4MjgtMy45OTM1NS0xLjQ4ODI4LTMuOTkzNTUtMy41NzE4NyAwLTAuODE4NTYgMC45NjczOC0yLjEzMzIxLTAuMjk3NjYtMS40MTM4Ni0wLjY0NDkyLTEuODEwNzQtMC40OTYxLTAuNDk2MDktMC42NDQ5Mi0wLjg5Mjk3IDAtMC4zMjI0NiAwLjA3NDQtMC43NDQxNCAwLjA0OTYtMC4xOTg0NCAwLjA3NDQtMC4zNDcyNiAwLjAyNDgtMC4xNzM2NCAwLjA0OTYtMC4yNDgwNSAwLjA5OTItMC4yNzI4NSAwLjE5ODQ0LTAuNzY4OTUtMC4yNDgwNS0zLjEyNTM5LTEuMjE1NDMtNi44NzA5LTEuMjg5ODQtNC43MTI4OS0zLjE5OTgtOC44MzA0Ni0wLjQyMTY4IDAuMTI0MDItMC44NjgxNyAwLjEyNDAyLTIuOTAyMTQ3IDAtMi45MDIxNDctMi45MDIxNXQyLjkwMjE0Ny0yLjkwMjE1cTIuOTAyMTUgMCAyLjkwMjE1IDIuOTAyMTUgMCAwLjg5Mjk3LTAuNDQ2NDggMS42MTIzMSAxLjQ2MzQ3IDEuODYwMzUgMi45MjY5NSAzLjQ3MjY1IDEuNDg4MjggMS41ODc1IDMuMjc0MjIgMy40OTc0NiAwLjIyMzI0IDAuMzIyNDYgMC42NDQ5MiAwLjMyMjQ2IDAuNzE5MzQgMCAwLjY0NDkyLTAuNzQ0MTQtMC4wNDk2LTAuMjIzMjQtMC42MjAxMi0zLjU0NzA3LTAuNTcwNS0zLjMyMzgzLTEuMjQwMjMtNy4yNDI5Ny0yLjM1NjQ1LTAuNjQ0OTItMi4zNTY0NS0yLjk1MTc1IDAtMS4xOTA2MyAwLjg0MzM2LTIuMDMzOTkgMC44NjgxNy0wLjg2ODE2IDIuMDU4NzktMC44NjgxNiAyLjkwMjE1IDAgMi45MDIxNSAyLjkwMjE1IDAgMS4yODk4NC0wLjk5MjE5IDIuMzU2NDQgMC4xMjQwMyAwLjUyMDkgMC42MjAxMiAyLjA4MzYgMC40OTYwOSAxLjUzNzg5IDEuNTM3ODkgNC4wNjc5NiAwLjU3MDUxIDEuMzg5MDcgMS4xNDEwMiAyLjgwMjkzIDAuNTk1MzEgMS4zODkwNyAxLjE5MDYyIDIuNzUzMzIgMC4xNDg4MyAwLjMyMjQ3IDAuNTIwOSAwLjMyMjQ3IDAuNTIwOS0wLjAyNDggMC41OTUzMS0wLjU0NTcxIDAuMDQ5Ni0wLjI5NzY1IDEuNTEzMDktMTUuOTk5MDItMS43NjExMy0wLjk0MjU4LTEuNzYxMTMtMi44MDI5MyAwLTEuMTkwNjMgMC44NDMzNi0yLjA1ODc5IDAuODQzMzUtMC44NjgxNiAyLjA1ODc4LTAuODY4MTYgMS4xOTA2MyAwIDIuMDMzOTkgMC44NjgxNiAwLjg2ODE2IDAuODY4MTYgMC44NjgxNiAyLjA1ODc5IDAgMS42ODY3Mi0xLjYxMjMgMi43NzgxMnoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im0xMTMuNzI5MjggMTc4LjM2MTkxcS0xLjM2NDI1IDAtMS4zNjQyNSAxLjQzODY3IDAgMS40NjM0OCAxLjM2NDI1IDEuNDYzNDggMS4zODkwNyAwIDEuMzg5MDctMS40NjM0OCAwLTEuNDM4NjctMS4zODkwNy0xLjQzODY3eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEwNi4xNjM4NSAxNzMuMTUyOTNxMC4yOTc2NiAxLjAxNjk5IDAuNTIwOSAxLjgzNTU0IDAuMjQ4MDUgMC43OTM3NSAwLjQyMTY4IDEuNzM2MzMgMC4xNDg4MyAwLjA3NDQgMC40NDY0OSAwLjA3NDQgMi4wODM1OS0wLjYyMDEyIDUuMTA5NzYtMS4wOTE0MSAzLjA1MDk4LTAuNDcxMjkgNi41NDg0NC0wLjQ3MTI5IDMuNTcxODcgMCA2LjY0NzY1IDAuNDk2MDkgMy4wNzU3OSAwLjQ3MTI5IDUuMTU5MzggMS4wOTE0MSAwLjEyNDAyIDAgMC4zNzIwNy0wLjA5OTIgMC4xNDg4My0wLjg5Mjk3IDAuMzk2ODgtMS42NjE5MSAwLjI0ODA0LTAuNzkzNzUgMC41NDU3LTEuODM1NTUtMi44Mjc3NC0wLjY0NDkyLTYuMTc2MzctMS4yNjUwNHQtNi45NDUzMS0wLjYyMDEyLTYuODcwOSAwLjYyMDEycS0zLjI3NDIyIDAuNTk1MzEtNi4xNzYzNyAxLjE5MDYzeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEzMS4wNjc3NiAxODAuOTY2NC0xLjc4NTk0LTEuNzExNTItMi4yODIwMyAwLjkxNzc3IDEuODEwNzQgMS43MTE1M3oiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im0xMjIuMzYxMzEgMTc5LjIwNTI3LTMuMTk5OC0xLjY2MTkxLTMuMDc1NzggMS42NjE5MSAzLjE5OTggMS42ODY3MnoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im0xMTEuNjQ1NjkgMTgwLjE5NzQ2LTIuNTA1MjctMC44NDMzNi0xLjk4NDM4IDEuNTYyNjkgMi40ODA0NyAwLjg0MzM2eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTEyNC42NjgxNSAxNzguMzYxOTFxLTEuMzg5MDYgMC0xLjM4OTA2IDEuNDM4NjcgMCAxLjQ2MzQ4IDEuMzg5MDYgMS40NjM0OHQxLjM4OTA2LTEuNDYzNDhxMC0xLjQzODY3LTEuMzg5MDYtMS40Mzg2N3oiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im0xMzAuMTAwMzggMTg2Ljk2OTE0cS0wLjE0ODgzLTAuNzQ0MTQtMC4zNDcyNy0xLjI0MDI0LTAuMjk3NjYtMC42NDQ5Mi0wLjU5NTMxLTAuODQzMzYtMC4yOTc2Ni0wLjIyMzI0LTAuNTQ1Ny0wLjU3MDUtMS4zMTQ2NS0wLjg0MzM2LTMuNjk1OS0xLjQzODY4LTIuMzU2NDUtMC42MjAxMS01LjcwNTA4LTAuNTQ1Ny0zLjQyMzA1LTAuMDc0NC01Ljc1NDY5IDAuNTQ1Ny0yLjMzMTY0IDAuNTk1MzItMy42MjE0OCAxLjQzODY4LTAuMzIyNDYgMC4yOTc2NS0wLjYyMDEyIDAuNTQ1Ny0wLjI5NzY2IDAuMjIzMjQtMC41MjA5IDAuODQzMzYtMC4yNDgwNSAwLjc0NDE0LTAuMzQ3MjYgMS4yNjUwNC0wLjA0OTYgMC44NDMzNiAwLjc0NDE0IDAuODQzMzYgMC43NDQxNCAwIDAuNzQ0MTQtMC44MTg1NiAwLjIyMzI0LTIuNTc5NjkgOS4zMjY1Ni0yLjU3OTY5IDkuMjAyNTQgMCA5LjQ1MDU5IDIuNTc5NjktMC4wNDk2IDAuODE4NTYgMC43NDQxNCAwLjgxODU2IDAuNzQ0MTQgMCAwLjc0NDE0LTAuODQzMzZ6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCTwvZz4NCgkJPGcgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIgYXJpYS1sYWJlbD0idyI+DQoJCQk8cGF0aCBkPSJtMTIwLjQyNjU1IDE1Mi43NjM0N3EwLjM3MjA3IDQuMDE4MzYgMC43NDQxNCA4LjAzNjcyIDAuMzk2ODcgMy45OTM1NiAwLjc5Mzc1IDcuOTg3MTEgMC4wMjQ4IDAuNTcwNTEgMC41NzA1MSAwLjU3MDUxIDAuMzk2ODctMC4wMjQ4IDAuNTQ1Ny0wLjM0NzI3IDIuMTU4MDEtNS4yMDg5OCAzLjE3NS04LjA2MTUyIDEuMDQxOC0yLjg3NzM0IDEuMjY1MDQtMy41NDcwNy0xLjE0MTAyLTEuMDkxNDEtMS4xNDEwMi0yLjQ1NTY2IDAtMS4xOTA2MyAwLjg0MzM2LTIuMDMzOTkgMC44NjgxNy0wLjg2ODE2IDIuMDgzNi0wLjg2ODE2IDEuMTkwNjIgMCAyLjAzMzk4IDAuODY4MTYgMC44NjgxNiAwLjg0MzM2IDAuODY4MTYgMi4wMzM5OSAwIDIuMTU4LTIuMjMyNDIgMi45MjY5NWwtMS44MTA3NCAxMC44MTQ4NHEtMC4xMjQwMiAwLjc0NDE0IDAuNTIwOSAwLjc0NDE0IDAuNTIwOSAwIDAuNzkzNzUtMC4yNzI4NSAyLjk3NjU2LTIuOTc2NTYgNC4yNjY0MS00LjYxMzY3IDEuMzE0NjQtMS42MzcxMSAxLjgzNTU0LTIuMjgyMDMtMC41NDU3LTAuNzE5MzQtMC41NDU3LTEuNzM2MzMgMC0yLjkwMjE1IDIuOTAyMTUtMi45MDIxNSAxLjE5MDYyIDAgMi4wMzM5OCAwLjg2ODE3IDAuODY4MTcgMC44NDMzNiAwLjg2ODE3IDIuMDMzOTggMCAxLjIxNTQzLTAuODY4MTcgMi4wNTg3OS0wLjg0MzM2IDAuODQzMzYtMi4wMzM5OCAwLjg0MzM2LTAuMzcyMDcgMC0wLjY2OTczLTAuMDc0NC0xLjk4NDM3IDQuMjkxMjEtMy4xNzUgOC43ODA4NS0xLjAxNjk5IDMuNjQ2MjktMS4yNjUwNCA2LjkyMDUxIDAuMTQ4ODMgMC42OTQ1MyAwLjE3MzYzIDAuNzE5MzQtMC4wNzQ0LTAuMjk3NjYgMC4wOTkyIDAuNTcwNTEgMC4wOTkyIDAuMzk2ODcgMC4wOTkyIDAuNzY4OTQtMC4xNDg4MyAwLjM5Njg4LTAuNjIwMTEgMC44OTI5Ny0wLjQyMTY4IDAuNDcxMjktMC42MjAxMiAxLjg2MDM1IDAuOTE3NzcgMS4yODk4NSAwLjkxNzc3IDIuMDgzNiAwIDIuMDgzNTktNC4wMTgzNiAzLjU3MTg3dC05LjY0OTAyIDEuNDg4MjhxLTUuNjU1NDcgMC05LjY3MzgzLTEuNDg4MjgtMy45OTM1NS0xLjQ4ODI4LTMuOTkzNTUtMy41NzE4NyAwLTAuODE4NTYgMC45NjczOC0yLjEzMzIxLTAuMjk3NjYtMS40MTM4Ni0wLjY0NDkyLTEuODEwNzQtMC40OTYxLTAuNDk2MDktMC42NDQ5Mi0wLjg5Mjk3IDAtMC4zMjI0NiAwLjA3NDQtMC43NDQxNCAwLjA0OTYtMC4xOTg0NCAwLjA3NDQtMC4zNDcyNiAwLjAyNDgtMC4xNzM2NCAwLjA0OTYtMC4yNDgwNSAwLjA5OTItMC4yNzI4NSAwLjE5ODQ0LTAuNzY4OTUtMC4yNDgwNS0zLjEyNTM5LTEuMjE1NDMtNi44NzA5LTEuMjg5ODQtNC43MTI4OS0zLjE5OTgtOC44MzA0Ni0wLjQyMTY4IDAuMTI0MDItMC44NjgxNyAwLjEyNDAyLTIuOTAyMTQ3IDAtMi45MDIxNDctMi45MDIxNXQyLjkwMjE0Ny0yLjkwMjE1cTIuOTAyMTUgMCAyLjkwMjE1IDIuOTAyMTUgMCAwLjg5Mjk3LTAuNDQ2NDggMS42MTIzMSAxLjQ2MzQ3IDEuODYwMzUgMi45MjY5NSAzLjQ3MjY1IDEuNDg4MjggMS41ODc1IDMuMjc0MjIgMy40OTc0NiAwLjIyMzI0IDAuMzIyNDYgMC42NDQ5MiAwLjMyMjQ2IDAuNzE5MzQgMCAwLjY0NDkyLTAuNzQ0MTQtMC4wNDk2LTAuMjIzMjQtMC42MjAxMi0zLjU0NzA3LTAuNTcwNS0zLjMyMzgzLTEuMjQwMjMtNy4yNDI5Ny0yLjM1NjQ1LTAuNjQ0OTItMi4zNTY0NS0yLjk1MTc1IDAtMS4xOTA2MyAwLjg0MzM2LTIuMDMzOTkgMC44NjgxNy0wLjg2ODE2IDIuMDU4NzktMC44NjgxNiAyLjkwMjE1IDAgMi45MDIxNSAyLjkwMjE1IDAgMS4yODk4NC0wLjk5MjE5IDIuMzU2NDQgMC4xMjQwMyAwLjUyMDkgMC42MjAxMiAyLjA4MzYgMC40OTYwOSAxLjUzNzg5IDEuNTM3ODkgNC4wNjc5NiAwLjU3MDUxIDEuMzg5MDcgMS4xNDEwMiAyLjgwMjkzIDAuNTk1MzEgMS4zODkwNyAxLjE5MDYyIDIuNzUzMzIgMC4xNDg4MyAwLjMyMjQ3IDAuNTIwOSAwLjMyMjQ3IDAuNTIwOS0wLjAyNDggMC41OTUzMS0wLjU0NTcxIDAuMDQ5Ni0wLjI5NzY1IDEuNTEzMDktMTUuOTk5MDItMS43NjExMy0wLjk0MjU4LTEuNzYxMTMtMi44MDI5MyAwLTEuMTkwNjMgMC44NDMzNi0yLjA1ODc5IDAuODQzMzUtMC44NjgxNiAyLjA1ODc4LTAuODY4MTYgMS4xOTA2MyAwIDIuMDMzOTkgMC44NjgxNiAwLjg2ODE2IDAuODY4MTYgMC44NjgxNiAyLjA1ODc5IDAgMS42ODY3Mi0xLjYxMjMgMi43NzgxMnptLTYuNjk3MjcgMjUuNTk4NDRxLTEuMzY0MjUgMC0xLjM2NDI1IDEuNDM4NjcgMCAxLjQ2MzQ4IDEuMzY0MjUgMS40NjM0OCAxLjM4OTA3IDAgMS4zODkwNy0xLjQ2MzQ4IDAtMS40Mzg2Ny0xLjM4OTA3LTEuNDM4Njd6bS03LjU2NTQzLTUuMjA4OThxMC4yOTc2NiAxLjAxNjk5IDAuNTIwOSAxLjgzNTU0IDAuMjQ4MDUgMC43OTM3NSAwLjQyMTY4IDEuNzM2MzMgMC4xNDg4MyAwLjA3NDQgMC40NDY0OSAwLjA3NDQgMi4wODM1OS0wLjYyMDEyIDUuMTA5NzYtMS4wOTE0MSAzLjA1MDk4LTAuNDcxMjkgNi41NDg0NC0wLjQ3MTI5IDMuNTcxODcgMCA2LjY0NzY1IDAuNDk2MDkgMy4wNzU3OSAwLjQ3MTI5IDUuMTU5MzggMS4wOTE0MSAwLjEyNDAyIDAgMC4zNzIwNy0wLjA5OTIgMC4xNDg4My0wLjg5Mjk3IDAuMzk2ODgtMS42NjE5MSAwLjI0ODA0LTAuNzkzNzUgMC41NDU3LTEuODM1NTUtMi44Mjc3NC0wLjY0NDkyLTYuMTc2MzctMS4yNjUwNHQtNi45NDUzMS0wLjYyMDEyLTYuODcwOSAwLjYyMDEycS0zLjI3NDIyIDAuNTk1MzEtNi4xNzYzNyAxLjE5MDYzem0yNC45MDM5MSA3LjgxMzQ3LTEuNzg1OTQtMS43MTE1Mi0yLjI4MjAzIDAuOTE3NzcgMS44MTA3NCAxLjcxMTUzem0tOC43MDY0NS0xLjc2MTEzLTMuMTk5OC0xLjY2MTkxLTMuMDc1NzggMS42NjE5MSAzLjE5OTggMS42ODY3MnptLTEwLjcxNTYyIDAuOTkyMTktMi41MDUyNy0wLjg0MzM2LTEuOTg0MzggMS41NjI2OSAyLjQ4MDQ3IDAuODQzMzZ6bTEzLjAyMjQ2LTEuODM1NTVxLTEuMzg5MDYgMC0xLjM4OTA2IDEuNDM4NjcgMCAxLjQ2MzQ4IDEuMzg5MDYgMS40NjM0OHQxLjM4OTA2LTEuNDYzNDhxMC0xLjQzODY3LTEuMzg5MDYtMS40Mzg2N3ptNS40MzIyMyA4LjYwNzIzcS0wLjE0ODgzLTAuNzQ0MTQtMC4zNDcyNy0xLjI0MDI0LTAuMjk3NjYtMC42NDQ5Mi0wLjU5NTMxLTAuODQzMzYtMC4yOTc2Ni0wLjIyMzI0LTAuNTQ1Ny0wLjU3MDUtMS4zMTQ2NS0wLjg0MzM2LTMuNjk1OS0xLjQzODY4LTIuMzU2NDUtMC42MjAxMS01LjcwNTA4LTAuNTQ1Ny0zLjQyMzA1LTAuMDc0NC01Ljc1NDY5IDAuNTQ1Ny0yLjMzMTY0IDAuNTk1MzItMy42MjE0OCAxLjQzODY4LTAuMzIyNDYgMC4yOTc2NS0wLjYyMDEyIDAuNTQ1Ny0wLjI5NzY2IDAuMjIzMjQtMC41MjA5IDAuODQzMzYtMC4yNDgwNSAwLjc0NDE0LTAuMzQ3MjYgMS4yNjUwNC0wLjA0OTYgMC44NDMzNiAwLjc0NDE0IDAuODQzMzYgMC43NDQxNCAwIDAuNzQ0MTQtMC44MTg1NiAwLjIyMzI0LTIuNTc5NjkgOS4zMjY1Ni0yLjU3OTY5IDkuMjAyNTQgMCA5LjQ1MDU5IDIuNTc5NjktMC4wNDk2IDAuODE4NTYgMC43NDQxNCAwLjgxODU2IDAuNzQ0MTQgMCAwLjc0NDE0LTAuODQzMzZ6IiBzdHJva2Utd2lkdGg9Ii4yNjQ1ODMzMiIvPg0KCQk8L2c+DQoJPC9nPg0KPC9zdmc+DQo=')} +.is2d .king.black {background-image:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4NCjxzdmcgd2lkdGg9IjUwLjgwMDAwM21tIiBoZWlnaHQ9IjUwLjc3NTIwNG1tIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCA1MC44MDAwMDMgNTAuNzc1MjA0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KCTxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0zNy45NTIyNywtNzkuODQ5NTA2KSI+DQoJCTxnIGZpbGw9IiNmZmYiPg0KCQkJPHBhdGggZD0ibTcxLjAxNzMxNSAxMTYuMzg2ODcgMi4wODM1OTQgMS42MTIzIDIuNjA0NDkyLTAuODkyOTctMi4wNTg3ODktMS42MTIzeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTc3LjE0NDA3MyAxMTUuOTY1MTlxMC4xNzM2MzMgMC41MjA4OSAwLjE3MzYzMyAwLjk5MjE4IDAgMS40NjM0OC0xLjA2NjYwMiAyLjI1NzIzLTAuMDk5MjIgMC40MjE2OC0wLjE0ODgyOCAwLjg0MzM2IDAuOTE3NzczIDEuMjg5ODQgMC45MTc3NzMgMi4wODM1OSAwIDIuMDgzNi00LjAxODM1OSAzLjU3MTg4dC05LjY0OTAyMyAxLjQ4ODI4cS01LjY1NTQ2OSAwLTkuNjczODI4LTEuNDg4MjgtMy45OTM1NTUtMS40ODgyOC0zLjk5MzU1NS0zLjU3MTg4IDAtMC44MTg1NSAwLjk2NzM4My0yLjEzMzItMC4wNDk2MS0wLjI3Mjg1LTAuMTQ4ODI4LTAuNzY4OTUtMS4wOTE0MDYtMC43OTM3NS0xLjA5MTQwNi0yLjI4MjAzIDAtMC40NzEyOSAwLjE0ODgyOC0wLjk2NzM4IDAuMjQ4MDQ3LTAuNjIwMTItMC4wOTkyMi0wLjk2NzM4LTAuMzQ3MjY2LTAuMzQ3MjctMC43OTM3NS0wLjk2NzM5LTAuMzk2ODc1LTEuMjQwMjMtMC4zOTY4NzUtMS43MTE1MiAwLjAyNDgxLTAuMjIzMjQgMC4wNzQ0MS0wLjQ5NjA5IDAuMDc0NDEtMC4yNzI4NSAwLjA3NDQxLTAuNjQ0OTItMS4wOTE0MDYtMS4wOTE0MS0yLjI4MjAzMS0yLjA1ODc5LTEuMTY1ODItMC45OTIxOS0xLjgzNTU0Ny0yLjM4MTI1LTAuNzkzNzUtMS42MzcxMS0xLjQ2MzQ3Ni0zLjI5OTAzLTAuNjQ0OTIyLTEuNjg2NzItMC42NDQ5MjItMy4yOTkwMiAwLTMuMDUwOTc2IDEuNjEyMzA0LTUuMTU5Mzc1IDEuNjEyMzA1LTIuMTA4Mzk4IDQuMzY1NjI1LTMuMjk5MDIzIDMuNjcxMDk0LTAuMjQ4MDQ3IDMuMTAwNTg2LTAuMjQ4MDQ3IDQuMzE2MDE2IDAgNy44MzgyODEgMy4xOTk4MDV2LTguNzA2NDQ2aDguNDU4Mzk5djguNzMxMjVxMy41MjIyNjUtMy4yMjQ2MDkgNy44ODc4OS0zLjIyNDYwOS0wLjYyMDExNyAwIDMuMTAwNTg2IDAuMjQ4MDQ3IDIuNzAzNzExIDEuMTkwNjI1IDQuMzE2MDE2IDMuMjk5MDIzIDEuNjM3MTA5IDIuMTA4Mzk5IDEuNjM3MTA5IDUuMTU5Mzc1IDAgMS42MTIzLTAuNjY5NzI3IDMuMjc0MjItMC42NDQ5MjEgMS42NjE5MS0xLjQxMzg2NyAzLjI5OTAyLTAuNjY5NzI2IDEuNDEzODctMS44NjAzNTEgMi40NTU2Ny0xLjE5MDYyNSAxLjA0MTc5LTIuMjU3MjI3IDIuMDgzNTktMC4wMjQ4IDAuMjk3NjYgMC4wMjQ4MSAwLjU3MDUxIDAuMDc0NDEgMC4yNzI4NSAwLjA5OTIyIDAuNDk2MDkgMC4wMjQ4IDAuMzQ3MjctMC4zOTY4NzUgMS43MTE1Mi0wLjQ0NjQ4NSAwLjYyMDEyLTAuNzkzNzUgMC45NjczOS0wLjMyMjQ2MSAwLjM0NzI2LTAuMDk5MjIgMC45NDI1OHoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im03My43MjEwMjYgMTIzLjA4NDEzcS0wLjA5OTIyLTAuNTQ1Ny0wLjM0NzI2Ni0xLjE5MDYyLTAuMjcyODUxLTAuNTk1MzItMC41NzA1MDctMC43OTM3NS0wLjI3Mjg1Mi0wLjIyMzI1LTAuNDk2MDk0LTAuNTcwNTEtMi41MDUyNzMtMS41ODc1LTguOTA0ODgzLTEuNDEzODctNi40OTg4MjgtMC4xNzM2My04Ljk3OTI5NyAxLjQxMzg3LTAuMjk3NjU2IDAuMjk3NjUtMC41OTUzMTIgMC41MjA5LTAuMjcyODUyIDAuMjIzMjQtMC40NzEyODkgMC44MTg1NS0wLjI3Mjg1MiAwLjYyMDEyLTAuMzQ3MjY2IDEuMjE1NDMtMC4wNDk2MSAwLjc5Mzc1IDAuNjk0NTMyIDAuNzkzNzUgMC43MTkzMzUgMCAwLjY5NDUzMS0wLjc2ODk0IDAuMjIzMjQyLTIuNDgwNDcgOC45MDQ4ODItMi40ODA0NyA4Ljc1NjA1NSAwIDkuMDA0MTAyIDIuNDgwNDctMC4wNDk2MSAwLjc2ODk0IDAuNjk0NTMxIDAuNzY4OTQgMC43MTkzMzYgMCAwLjcxOTMzNi0wLjc5Mzc1eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTY2LjA4MTE4MiAxMDguNDQ5MzdxMC4zMjI0NjEgMCAwLjY0NDkyMiAwLjA0OTYgMC4zMjI0NjEgMC4wMjQ4IDAuNjIwMTE3IDAuMDI0OC0wLjE5ODQzNy0yLjI1NzIzIDAuMTk4NDM4LTMuNjk1OSAwLjE0ODgyOC0wLjU0NTcgMC41NDU3MDMtMC41OTUzMSAwLjU3MDUwOC0wLjA5OTIgMC44MTg1NTUgMC42MjAxMiAwLjE5ODQzNyAxLjE5MDYyLTAuMzk2ODc1IDMuNzk1MTEgMC45OTIxODcgMC4xNzM2NCAxLjQ2MzQ3NiAwLjE3MzY0IDAuMTQ4ODI4LTMuODE5OTMgMS4xNjU4MjEtNi4wNzcxNSAwLjI5NzY1Ni0wLjU5NTMxIDAuOTkyMTg3LTAuNTk1MzEgMC44NDMzNTkgMCAwLjc5Mzc1IDAuODE4NTUgMC4wNDk2MSAwLjA0OTYgMC4wNDk2MSAwLjc2ODk1IDAgMS4yNjUwMy0xLjQxMzg2NyA1LjM4MjYxIDAuNzE5MzM2IDAuMjQ4MDUgMS4yNDAyMzUgMC4xOTg0NCAwLjI3Mjg1MS0wLjcxOTM0IDAuNTQ1NzAzLTEuNTEzMDkgMC4yOTc2NTYtMC44MTg1NSAwLjc0NDE0LTEuNzM2MzIgMC4xOTg0MzgtMC40NzEyOSAwLjU3MDUwOC0wLjQ3MTI5IDAuNDIxNjggMCAwLjUyMDg5OSAwLjgxODU1IDAuMDI0OCAwLjY5NDUzLTEuNDYzNDc3IDMuMTc1IDAuNjIwMTE3IDAuMjk3NjYgMS4yNDAyMzQgMC4zMjI0NiAwLjI5NzY1Ny0wLjU5NTMxIDAuNTQ1NzA0LTEuMTE2MjEgMC4yNzI4NTEtMC41MjA5IDAuNTcwNTA3LTEuMzM5NDUgMC41NDU3MDMtMS41ODc1IDAuNDQ2NDg1LTMuMDI2MTctMC4xOTg0MzgtMC44NjgxNy0wLjk2NzM4My0wLjg2ODE3LTAuMzcyMDcgMC0wLjkxNzc3NCAwLjU5NTMxIDAuMTI0MDI0LTAuNzkzNzUgMC4xMjQwMjQtMC45OTIxOCAwLTEuMDQxOC0wLjUyMDg5OC0xLjk1OTU3LTAuNDk2MDk0LTAuOTQyNTgtMS43MTE1MjQtMS4yODk4NDctMC44OTI5NjkgMC4wNDk2MS0xLjg2MDM1MSAxLjA5MTQwNy0wLjk2NzM4MyAxLjA0MTgtMS4yODk4NDQgMi40NTU2Ni0wLjI3Mjg1Mi0wLjg2ODE2LTAuNzE5MzM2LTAuOTkyMTgtMC40NDY0ODQtMC4xMjQwMy0wLjU5NTMxMy0wLjEyNDAzLTAuMjk3NjU2IDAtMC41NzA1MDcgMC4xNzM2NC0wLjk5MjE4OCAxLjE0MTAxLTEuMjE1NDMgMy40NzI2NS0wLjA3NDQxIDAuNTIwOS0wLjA5OTIyIDEuMDE2OTktMC4wMjQ4IDAuNDk2MS0wLjA5OTIyIDEuNDM4Njh6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtNjAuNTQ5NzM3IDEwOC40NzQxN3EtMC4wNzQ0MS0wLjkxNzc3LTAuMDk5MjItMS40MTM4Ny0wLjAyNDgtMC40OTYwOS0wLjA3NDQxLTEuMDE2OTktMC4yOTc2NTYtMi4zODEyNS0xLjIxNTQyOS0zLjQ3MjY2LTAuMjQ4MDQ3LTAuMTczNjMtMC41OTUzMTMtMC4xNzM2My0wLjE0ODgyOCAwLTAuNjIwMTE3IDAuMTI0MDMtMC40NDY0ODQgMC4xMjQwMi0wLjY2OTcyNiAwLjk2NzM4LTAuMzQ3MjY2LTEuNDEzODctMS4zMTQ2NDktMi40NTU2Ny0wLjk0MjU3OC0xLjA0MTc5My0xLjgzNTU0Ny0xLjA5MTQwMi0xLjI0MDIzNCAwLjM3MjA3Mi0xLjczNjMyOCAxLjMxNDY1Mi0wLjQ5NjA5NCAwLjkxNzc3LTAuNDk2MDk0IDEuOTU5NTcgMCAwLjQ3MTI5IDAuMTI0MDI0IDAuOTkyMTgtMC41OTUzMTMtMC42MjAxMS0wLjkxNzc3NC0wLjYyMDExLTAuNzkzNzUgMC0wLjk2NzM4MiAwLjg5Mjk3LTAuMTI0MDI0IDEuNTM3ODkgMC40NDY0ODQgMy4wMDEzNiAwLjI3Mjg1MiAwLjgxODU2IDAuNTIwODk4IDEuMzY0MjYgMC4yNzI4NTIgMC41MjA5IDAuNTk1MzEzIDEuMTE2MjEgMC41OTUzMTItMC4wMjQ4IDEuMjQwMjM0LTAuMzIyNDYtMS41MTMwODYtMi40NTU2Ni0xLjQ2MzQ3Ni0zLjE3NSAwLjAyNDgtMC44MTg1NSAwLjQ5NjA5My0wLjgxODU1IDAuMzcyMDcxIDAgMC41OTUzMTMgMC40NzEyOCAwLjQyMTY4IDAuODkyOTcgMC42OTQ1MzEgMS43MTE1MyAwLjI5NzY1NiAwLjgxODU1IDAuNTk1MzEzIDEuNTM3ODkgMC41OTUzMTIgMCAxLjI0MDIzNC0wLjE5ODQ0LTEuNDM4NjcyLTQuMTkxOTktMS40Mzg2NzItNS40MDc0MiAwLTAuNjY5NzMgMC4wNDk2MS0wLjc0NDE0IDAtMC44NDMzNiAwLjc5Mzc1LTAuODQzMzYgMC42OTQ1MzEgMCAxLjAxNjk5MiAwLjYyMDEyIDAuOTkyMTg3IDIuMjU3MjIgMS4xNjU4MiA2LjA3NzE1IDAuNDk2MDk0LTAuMDI0OCAxLjQzODY3Mi0wLjE3MzY0LTAuNTk1MzEzLTIuNjU0MS0wLjM3MjA3LTMuNzk1MTEgMC4yMjMyNDItMC43NDQxNSAwLjc5Mzc1LTAuNjQ0OTMgMC40MjE2NzkgMC4wOTkyIDAuNTQ1NzAzIDAuNTk1MzIgMC4zOTY4NzUgMS41NjI2OSAwLjE5ODQzNyAzLjcyMDcgMC4zOTY4NzUtMC4wNDk2IDEuMjY1MDM5LTAuMDk5MnoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im02My4zNTI2NjcgOTQuNTU4NzQxcS0xLjIxNTQzIDAtMi4wODM1OTQgMC44NjgxNjR0LTAuODY4MTY0IDIuMDgzNTk0cTAgMS4yNDAyMzQgMC44NjgxNjQgMi4xMDgzOTggMC44NjgxNjQgMC44NDMzNjMgMi4wODM1OTQgMC44NDMzNjMgMi45NTE3NTggMCAyLjk1MTc1OC0yLjk1MTc2MSAwLTIuOTUxNzU4LTIuOTUxNzU4LTIuOTUxNzU4eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTYzLjY1MDMyMyA4OS4yMjU3MzNxLTAuMTQ4ODI4LTAuMDc0NDEtMC4yOTc2NTYtMC4wNzQ0MS0wLjI3Mjg1MiAwLTAuMzk2ODc1IDAuMDk5MjJsLTEuNTg3NS0xLjYxMjMwNWgtMC41NzA1MDh2MC42OTQ1MzFsMS41NjI2OTUgMS41NjI2OTZxLTAuMDc0NDEgMC4xNDg4MjgtMC4wNzQ0MSAwLjMyMjQ2MSAwIDAuMTQ4ODI4IDAuMDc0NDEgMC4yOTc2NTZsLTEuNTYyNjk1IDEuNTg3NXYwLjY0NDkyMmgwLjU3MDUwOGwxLjU2MjY5NS0xLjU2MjY5NnEwLjE3MzYzMyAwLjA3NDQxIDAuNDIxNjggMC4wNzQ0MSAwLjE5ODQzNyAwIDAuMzIyNDYxLTAuMDQ5NjFsMS41NjI2OTUgMS41Mzc4OTFoMC42Njk3Mjd2LTAuNTcwNTA4bC0xLjU4NzUtMS41Mzc4OTFxMC4wNzQ0MS0wLjE3MzYzMyAwLjA3NDQxLTAuNDIxNjc5IDAtMC4yMjMyNDMtMC4wOTkyMi0wLjM5Njg3NWwxLjYxMjMwNS0xLjU4NzV2LTAuNTk1MzEzaC0wLjY5NDUzMnoiIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiLz4NCgkJCTxwYXRoIGQ9Im02Ni42NTE2OSAxMTUuNjE3OTItMy4zNDg2MzMtMS41ODc1LTMuMjI0NjA5IDEuNTg3NSAzLjM0ODYzMyAxLjYxMjN6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtNTUuODg2NDU2IDExNi4zODY4Ny0yLjYyOTI5Ny0wLjg5Mjk3LTIuMDU4Nzg5IDEuNjEyMyAyLjYwNDQ5MiAwLjg5Mjk3eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTc1LjE1OTY5OCAxMTQuMDgwMDNxMS4xMTYyMTEtMC4xMjQwMiAxLjExNjIxMS0xLjI0MDIzIDAtMC43MTkzNC0wLjY0NDkyMi0xLjA5MTQxLTIuMDgzNTk0LTAuODQzMzYtNS4zMDgyMDMtMS4zNjQyNi0zLjE5OTgwNS0wLjU0NTctNi45OTQ5MjItMC41NDU3LTcuOTYyMzA0IDAtMTIuMzUyNzM0IDEuOTU5NTctMC41NDU3MDMgMC40MjE2OC0wLjU0NTcwMyAxLjA0MTggMCAxLjI2NTAzIDEuMjY1MDM5IDEuMjE1NDIgNC40MTUyMzQtMS42NjE5MSAxMS42MzMzOTgtMS42NjE5MSA3LjMxNzM4MyAwIDExLjgzMTgzNiAxLjY4NjcyeiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQkJPHBhdGggZD0ibTU4Ljk2MjIzNyA5Ny4xMTM2MjRxLTIuODc3MzQzLTMuMDUwOTc3LTYuNTIzNjMyLTMuMDUwOTc3LTMuMzQ4NjMzIDAtNS4wODQ5NjEgMi4yMzI0MjItMS4xMTYyMTEgMS40MTM4NjctMS4xMTYyMTEgMy44NDQ3MzEgMCAxLjkwOTk2IDAuNTQ1NzAzIDMuNjQ2MjggMC4wMjQ4MSAwLjQ5NjEgMC42MjAxMTcgMC40OTYxIDAuNTk1MzEzIDAgMC42NDQ5MjItMC41OTUzMS0wLjE5ODQzOC0xLjI2NTA0LTAuMTk4NDM4LTIuMjU3MjMgMC0yLjA1ODc5IDAuOTY3MzgzLTMuMjQ5NDE1IDEuMzg5MDYzLTEuODg1MTU2IDQuMzE2MDE2LTEuODg1MTU2IDIuODc3MzQzIDAgNS4zODI2MTcgMi4yODIwMzEgMC40OTYwOTQgMCAwLjQ5NjA5NC0wLjkxNzc3MyAwLTAuMTk4NDM4LTAuMDQ5NjEtMC41NDU3MDN6IiBzdHlsZT0iZm9udC1mZWF0dXJlLXNldHRpbmdzOm5vcm1hbDtmb250LXZhcmlhbnQtY2Fwczpub3JtYWw7Zm9udC12YXJpYW50LWxpZ2F0dXJlczpub3JtYWw7Zm9udC12YXJpYW50LW51bWVyaWM6bm9ybWFsIi8+DQoJCQk8cGF0aCBkPSJtNjcuNjE5MDczIDk3LjExMzYyNHEtMC4wNDk2MSAwLjM0NzI2NS0wLjA0OTYxIDAuNTQ1NzAzIDAgMC45MTc3NzMgMC40OTYwOTMgMC45MTc3NzMgMi40ODA0NjktMi4yODIwMzEgNS40MDc0MjItMi4yODIwMzEgMi44NzczNDQgMCA0LjI5MTIxMSAxLjg4NTE1NiAwLjk2NzM4MyAxLjE5MDYyNSAwLjk2NzM4MyAzLjI0OTQxNSAwIDAuOTkyMTktMC4xOTg0MzggMi4yNTcyMyAwLjAyNDgxIDAuNTk1MzEgMC42NDQ5MjIgMC41OTUzMSAwLjYyMDExNyAwIDAuNjIwMTE3LTAuNDk2MSAwLjU0NTcwNC0xLjczNjMyIDAuNTQ1NzA0LTMuNjQ2MjggMC0yLjQzMDg2NC0xLjExNjIxMS0zLjg0NDczMS0xLjc2MTEzMy0yLjIzMjQyMi01LjA4NDk2MS0yLjIzMjQyMi0zLjY3MTA5NCAwLTYuNTIzNjMzIDMuMDUwOTc3eiIgc3R5bGU9ImZvbnQtZmVhdHVyZS1zZXR0aW5nczpub3JtYWw7Zm9udC12YXJpYW50LWNhcHM6bm9ybWFsO2ZvbnQtdmFyaWFudC1saWdhdHVyZXM6bm9ybWFsO2ZvbnQtdmFyaWFudC1udW1lcmljOm5vcm1hbCIvPg0KCQk8L2c+DQoJCTxnIHN0eWxlPSJmb250LWZlYXR1cmUtc2V0dGluZ3M6bm9ybWFsO2ZvbnQtdmFyaWFudC1jYXBzOm5vcm1hbDtmb250LXZhcmlhbnQtbGlnYXR1cmVzOm5vcm1hbDtmb250LXZhcmlhbnQtbnVtZXJpYzpub3JtYWwiIGFyaWEtbGFiZWw9ImwiPg0KCQkJPHBhdGggZD0ibTcxLjAxNzMxNSAxMTYuMzg2ODcgMi4wODM1OTQgMS42MTIzIDIuNjA0NDkyLTAuODkyOTctMi4wNTg3ODktMS42MTIzem02LjEyNjc1OC0wLjQyMTY4cTAuMTczNjMzIDAuNTIwODkgMC4xNzM2MzMgMC45OTIxOCAwIDEuNDYzNDgtMS4wNjY2MDIgMi4yNTcyMy0wLjA5OTIyIDAuNDIxNjgtMC4xNDg4MjggMC44NDMzNiAwLjkxNzc3MyAxLjI4OTg0IDAuOTE3NzczIDIuMDgzNTkgMCAyLjA4MzYtNC4wMTgzNTkgMy41NzE4OHQtOS42NDkwMjMgMS40ODgyOHEtNS42NTU0NjkgMC05LjY3MzgyOC0xLjQ4ODI4LTMuOTkzNTU1LTEuNDg4MjgtMy45OTM1NTUtMy41NzE4OCAwLTAuODE4NTUgMC45NjczODMtMi4xMzMyLTAuMDQ5NjEtMC4yNzI4NS0wLjE0ODgyOC0wLjc2ODk1LTEuMDkxNDA2LTAuNzkzNzUtMS4wOTE0MDYtMi4yODIwMyAwLTAuNDcxMjkgMC4xNDg4MjgtMC45NjczOCAwLjI0ODA0Ny0wLjYyMDEyLTAuMDk5MjItMC45NjczOC0wLjM0NzI2Ni0wLjM0NzI3LTAuNzkzNzUtMC45NjczOS0wLjM5Njg3NS0xLjI0MDIzLTAuMzk2ODc1LTEuNzExNTIgMC4wMjQ4MS0wLjIyMzI0IDAuMDc0NDEtMC40OTYwOSAwLjA3NDQxLTAuMjcyODUgMC4wNzQ0MS0wLjY0NDkyLTEuMDkxNDA2LTEuMDkxNDEtMi4yODIwMzEtMi4wNTg3OS0xLjE2NTgyLTAuOTkyMTktMS44MzU1NDctMi4zODEyNS0wLjc5Mzc1LTEuNjM3MTEtMS40NjM0NzYtMy4yOTkwMy0wLjY0NDkyMi0xLjY4NjcyLTAuNjQ0OTIyLTMuMjk5MDIgMC0zLjA1MDk3NiAxLjYxMjMwNC01LjE1OTM3NSAxLjYxMjMwNS0yLjEwODM5OCA0LjM2NTYyNS0zLjI5OTAyMyAzLjY3MTA5NC0wLjI0ODA0NyAzLjEwMDU4Ni0wLjI0ODA0NyA0LjMxNjAxNiAwIDcuODM4MjgxIDMuMTk5ODA1di04LjcwNjQ0Nmg4LjQ1ODM5OXY4LjczMTI1cTMuNTIyMjY1LTMuMjI0NjA5IDcuODg3ODktMy4yMjQ2MDktMC42MjAxMTcgMCAzLjEwMDU4NiAwLjI0ODA0NyAyLjcwMzcxMSAxLjE5MDYyNSA0LjMxNjAxNiAzLjI5OTAyMyAxLjYzNzEwOSAyLjEwODM5OSAxLjYzNzEwOSA1LjE1OTM3NSAwIDEuNjEyMy0wLjY2OTcyNyAzLjI3NDIyLTAuNjQ0OTIxIDEuNjYxOTEtMS40MTM4NjcgMy4yOTkwMi0wLjY2OTcyNiAxLjQxMzg3LTEuODYwMzUxIDIuNDU1NjctMS4xOTA2MjUgMS4wNDE3OS0yLjI1NzIyNyAyLjA4MzU5LTAuMDI0OCAwLjI5NzY2IDAuMDI0ODEgMC41NzA1MSAwLjA3NDQxIDAuMjcyODUgMC4wOTkyMiAwLjQ5NjA5IDAuMDI0OCAwLjM0NzI3LTAuMzk2ODc1IDEuNzExNTItMC40NDY0ODUgMC42MjAxMi0wLjc5Mzc1IDAuOTY3MzktMC4zMjI0NjEgMC4zNDcyNi0wLjA5OTIyIDAuOTQyNTh6bS0zLjQyMzA0NyA3LjExODk0cS0wLjA5OTIyLTAuNTQ1Ny0wLjM0NzI2Ni0xLjE5MDYyLTAuMjcyODUxLTAuNTk1MzItMC41NzA1MDctMC43OTM3NS0wLjI3Mjg1Mi0wLjIyMzI1LTAuNDk2MDk0LTAuNTcwNTEtMi41MDUyNzMtMS41ODc1LTguOTA0ODgzLTEuNDEzODctNi40OTg4MjgtMC4xNzM2My04Ljk3OTI5NyAxLjQxMzg3LTAuMjk3NjU2IDAuMjk3NjUtMC41OTUzMTIgMC41MjA5LTAuMjcyODUyIDAuMjIzMjQtMC40NzEyODkgMC44MTg1NS0wLjI3Mjg1MiAwLjYyMDEyLTAuMzQ3MjY2IDEuMjE1NDMtMC4wNDk2MSAwLjc5Mzc1IDAuNjk0NTMyIDAuNzkzNzUgMC43MTkzMzUgMCAwLjY5NDUzMS0wLjc2ODk0IDAuMjIzMjQyLTIuNDgwNDcgOC45MDQ4ODItMi40ODA0NyA4Ljc1NjA1NSAwIDkuMDA0MTAyIDIuNDgwNDctMC4wNDk2MSAwLjc2ODk0IDAuNjk0NTMxIDAuNzY4OTQgMC43MTkzMzYgMCAwLjcxOTMzNi0wLjc5Mzc1em0tNy42Mzk4NDQtMTQuNjM0NzZxMC4zMjI0NjEgMCAwLjY0NDkyMiAwLjA0OTYgMC4zMjI0NjEgMC4wMjQ4IDAuNjIwMTE3IDAuMDI0OC0wLjE5ODQzNy0yLjI1NzIzIDAuMTk4NDM4LTMuNjk1OSAwLjE0ODgyOC0wLjU0NTcgMC41NDU3MDMtMC41OTUzMSAwLjU3MDUwOC0wLjA5OTIgMC44MTg1NTUgMC42MjAxMiAwLjE5ODQzNyAxLjE5MDYyLTAuMzk2ODc1IDMuNzk1MTEgMC45OTIxODcgMC4xNzM2NCAxLjQ2MzQ3NiAwLjE3MzY0IDAuMTQ4ODI4LTMuODE5OTMgMS4xNjU4MjEtNi4wNzcxNSAwLjI5NzY1Ni0wLjU5NTMxIDAuOTkyMTg3LTAuNTk1MzEgMC44NDMzNTkgMCAwLjc5Mzc1IDAuODE4NTUgMC4wNDk2MSAwLjA0OTYgMC4wNDk2MSAwLjc2ODk1IDAgMS4yNjUwMy0xLjQxMzg2NyA1LjM4MjYxIDAuNzE5MzM2IDAuMjQ4MDUgMS4yNDAyMzUgMC4xOTg0NCAwLjI3Mjg1MS0wLjcxOTM0IDAuNTQ1NzAzLTEuNTEzMDkgMC4yOTc2NTYtMC44MTg1NSAwLjc0NDE0LTEuNzM2MzIgMC4xOTg0MzgtMC40NzEyOSAwLjU3MDUwOC0wLjQ3MTI5IDAuNDIxNjggMCAwLjUyMDg5OSAwLjgxODU1IDAuMDI0OCAwLjY5NDUzLTEuNDYzNDc3IDMuMTc1IDAuNjIwMTE3IDAuMjk3NjYgMS4yNDAyMzQgMC4zMjI0NiAwLjI5NzY1Ny0wLjU5NTMxIDAuNTQ1NzA0LTEuMTE2MjEgMC4yNzI4NTEtMC41MjA5IDAuNTcwNTA3LTEuMzM5NDUgMC41NDU3MDMtMS41ODc1IDAuNDQ2NDg1LTMuMDI2MTctMC4xOTg0MzgtMC44NjgxNy0wLjk2NzM4My0wLjg2ODE3LTAuMzcyMDcgMC0wLjkxNzc3NCAwLjU5NTMxIDAuMTI0MDI0LTAuNzkzNzUgMC4xMjQwMjQtMC45OTIxOCAwLTEuMDQxOC0wLjUyMDg5OC0xLjk1OTU3LTAuNDk2MDk0LTAuOTQyNTgtMS43MTE1MjQtMS4yODk4NDctMC44OTI5NjkgMC4wNDk2MS0xLjg2MDM1MSAxLjA5MTQwNy0wLjk2NzM4MyAxLjA0MTgtMS4yODk4NDQgMi40NTU2Ni0wLjI3Mjg1Mi0wLjg2ODE2LTAuNzE5MzM2LTAuOTkyMTgtMC40NDY0ODQtMC4xMjQwMy0wLjU5NTMxMy0wLjEyNDAzLTAuMjk3NjU2IDAtMC41NzA1MDcgMC4xNzM2NC0wLjk5MjE4OCAxLjE0MTAxLTEuMjE1NDMgMy40NzI2NS0wLjA3NDQxIDAuNTIwOS0wLjA5OTIyIDEuMDE2OTktMC4wMjQ4IDAuNDk2MS0wLjA5OTIyIDEuNDM4Njh6bS01LjUzMTQ0NSAwLjAyNDhxLTAuMDc0NDEtMC45MTc3Ny0wLjA5OTIyLTEuNDEzODctMC4wMjQ4LTAuNDk2MDktMC4wNzQ0MS0xLjAxNjk5LTAuMjk3NjU2LTIuMzgxMjUtMS4yMTU0MjktMy40NzI2Ni0wLjI0ODA0Ny0wLjE3MzYzLTAuNTk1MzEzLTAuMTczNjMtMC4xNDg4MjggMC0wLjYyMDExNyAwLjEyNDAzLTAuNDQ2NDg0IDAuMTI0MDItMC42Njk3MjYgMC45NjczOC0wLjM0NzI2Ni0xLjQxMzg3LTEuMzE0NjQ5LTIuNDU1NjctMC45NDI1NzgtMS4wNDE3OTMtMS44MzU1NDctMS4wOTE0MDItMS4yNDAyMzQgMC4zNzIwNzItMS43MzYzMjggMS4zMTQ2NTItMC40OTYwOTQgMC45MTc3Ny0wLjQ5NjA5NCAxLjk1OTU3IDAgMC40NzEyOSAwLjEyNDAyNCAwLjk5MjE4LTAuNTk1MzEzLTAuNjIwMTEtMC45MTc3NzQtMC42MjAxMS0wLjc5Mzc1IDAtMC45NjczODIgMC44OTI5Ny0wLjEyNDAyNCAxLjUzNzg5IDAuNDQ2NDg0IDMuMDAxMzYgMC4yNzI4NTIgMC44MTg1NiAwLjUyMDg5OCAxLjM2NDI2IDAuMjcyODUyIDAuNTIwOSAwLjU5NTMxMyAxLjExNjIxIDAuNTk1MzEyLTAuMDI0OCAxLjI0MDIzNC0wLjMyMjQ2LTEuNTEzMDg2LTIuNDU1NjYtMS40NjM0NzYtMy4xNzUgMC4wMjQ4LTAuODE4NTUgMC40OTYwOTMtMC44MTg1NSAwLjM3MjA3MSAwIDAuNTk1MzEzIDAuNDcxMjggMC40MjE2OCAwLjg5Mjk3IDAuNjk0NTMxIDEuNzExNTMgMC4yOTc2NTYgMC44MTg1NSAwLjU5NTMxMyAxLjUzNzg5IDAuNTk1MzEyIDAgMS4yNDAyMzQtMC4xOTg0NC0xLjQzODY3Mi00LjE5MTk5LTEuNDM4NjcyLTUuNDA3NDIgMC0wLjY2OTczIDAuMDQ5NjEtMC43NDQxNCAwLTAuODQzMzYgMC43OTM3NS0wLjg0MzM2IDAuNjk0NTMxIDAgMS4wMTY5OTIgMC42MjAxMiAwLjk5MjE4NyAyLjI1NzIyIDEuMTY1ODIgNi4wNzcxNSAwLjQ5NjA5NC0wLjAyNDggMS40Mzg2NzItMC4xNzM2NC0wLjU5NTMxMy0yLjY1NDEtMC4zNzIwNy0zLjc5NTExIDAuMjIzMjQyLTAuNzQ0MTUgMC43OTM3NS0wLjY0NDkzIDAuNDIxNjc5IDAuMDk5MiAwLjU0NTcwMyAwLjU5NTMyIDAuMzk2ODc1IDEuNTYyNjkgMC4xOTg0MzcgMy43MjA3IDAuMzk2ODc1LTAuMDQ5NiAxLjI2NTAzOS0wLjA5OTJ6bTIuODAyOTMtMTMuOTE1NDI5cS0xLjIxNTQzIDAtMi4wODM1OTQgMC44NjgxNjR0LTAuODY4MTY0IDIuMDgzNTk0cTAgMS4yNDAyMzQgMC44NjgxNjQgMi4xMDgzOTggMC44NjgxNjQgMC44NDMzNjMgMi4wODM1OTQgMC44NDMzNjMgMi45NTE3NTggMCAyLjk1MTc1OC0yLjk1MTc2MSAwLTIuOTUxNzU4LTIuOTUxNzU4LTIuOTUxNzU4em0wLjI5NzY1Ni01LjMzMzAwOHEtMC4xNDg4MjgtMC4wNzQ0MS0wLjI5NzY1Ni0wLjA3NDQxLTAuMjcyODUyIDAtMC4zOTY4NzUgMC4wOTkyMmwtMS41ODc1LTEuNjEyMzA1aC0wLjU3MDUwOHYwLjY5NDUzMWwxLjU2MjY5NSAxLjU2MjY5NnEtMC4wNzQ0MSAwLjE0ODgyOC0wLjA3NDQxIDAuMzIyNDYxIDAgMC4xNDg4MjggMC4wNzQ0MSAwLjI5NzY1NmwtMS41NjI2OTUgMS41ODc1djAuNjQ0OTIyaDAuNTcwNTA4bDEuNTYyNjk1LTEuNTYyNjk2cTAuMTczNjMzIDAuMDc0NDEgMC40MjE2OCAwLjA3NDQxIDAuMTk4NDM3IDAgMC4zMjI0NjEtMC4wNDk2MWwxLjU2MjY5NSAxLjUzNzg5MWgwLjY2OTcyN3YtMC41NzA1MDhsLTEuNTg3NS0xLjUzNzg5MXEwLjA3NDQxLTAuMTczNjMzIDAuMDc0NDEtMC40MjE2NzkgMC0wLjIyMzI0My0wLjA5OTIyLTAuMzk2ODc1bDEuNjEyMzA1LTEuNTg3NXYtMC41OTUzMTNoLTAuNjk0NTMyem0zLjAwMTM2NyAyNi4zOTIxODctMy4zNDg2MzMtMS41ODc1LTMuMjI0NjA5IDEuNTg3NSAzLjM0ODYzMyAxLjYxMjN6bS0xMC43NjUyMzQgMC43Njg5NS0yLjYyOTI5Ny0wLjg5Mjk3LTIuMDU4Nzg5IDEuNjEyMyAyLjYwNDQ5MiAwLjg5Mjk3em0xOS4yNzMyNDItMi4zMDY4NHExLjExNjIxMS0wLjEyNDAyIDEuMTE2MjExLTEuMjQwMjMgMC0wLjcxOTM0LTAuNjQ0OTIyLTEuMDkxNDEtMi4wODM1OTQtMC44NDMzNi01LjMwODIwMy0xLjM2NDI2LTMuMTk5ODA1LTAuNTQ1Ny02Ljk5NDkyMi0wLjU0NTctNy45NjIzMDQgMC0xMi4zNTI3MzQgMS45NTk1Ny0wLjU0NTcwMyAwLjQyMTY4LTAuNTQ1NzAzIDEuMDQxOCAwIDEuMjY1MDMgMS4yNjUwMzkgMS4yMTU0MiA0LjQxNTIzNC0xLjY2MTkxIDExLjYzMzM5OC0xLjY2MTkxIDcuMzE3MzgzIDAgMTEuODMxODM2IDEuNjg2NzJ6bS0xNi4xOTc0NjEtMTYuOTY2NDA2cS0yLjg3NzM0My0zLjA1MDk3Ny02LjUyMzYzMi0zLjA1MDk3Ny0zLjM0ODYzMyAwLTUuMDg0OTYxIDIuMjMyNDIyLTEuMTE2MjExIDEuNDEzODY3LTEuMTE2MjExIDMuODQ0NzMxIDAgMS45MDk5NiAwLjU0NTcwMyAzLjY0NjI4IDAuMDI0ODEgMC40OTYxIDAuNjIwMTE3IDAuNDk2MSAwLjU5NTMxMyAwIDAuNjQ0OTIyLTAuNTk1MzEtMC4xOTg0MzgtMS4yNjUwNC0wLjE5ODQzOC0yLjI1NzIzIDAtMi4wNTg3OSAwLjk2NzM4My0zLjI0OTQxNSAxLjM4OTA2My0xLjg4NTE1NiA0LjMxNjAxNi0xLjg4NTE1NiAyLjg3NzM0MyAwIDUuMzgyNjE3IDIuMjgyMDMxIDAuNDk2MDk0IDAgMC40OTYwOTQtMC45MTc3NzMgMC0wLjE5ODQzOC0wLjA0OTYxLTAuNTQ1NzAzem04LjY1NjgzNiAwcS0wLjA0OTYxIDAuMzQ3MjY1LTAuMDQ5NjEgMC41NDU3MDMgMCAwLjkxNzc3MyAwLjQ5NjA5MyAwLjkxNzc3MyAyLjQ4MDQ2OS0yLjI4MjAzMSA1LjQwNzQyMi0yLjI4MjAzMSAyLjg3NzM0NCAwIDQuMjkxMjExIDEuODg1MTU2IDAuOTY3MzgzIDEuMTkwNjI1IDAuOTY3MzgzIDMuMjQ5NDE1IDAgMC45OTIxOS0wLjE5ODQzOCAyLjI1NzIzIDAuMDI0ODEgMC41OTUzMSAwLjY0NDkyMiAwLjU5NTMxIDAuNjIwMTE3IDAgMC42MjAxMTctMC40OTYxIDAuNTQ1NzA0LTEuNzM2MzIgMC41NDU3MDQtMy42NDYyOCAwLTIuNDMwODY0LTEuMTE2MjExLTMuODQ0NzMxLTEuNzYxMTMzLTIuMjMyNDIyLTUuMDg0OTYxLTIuMjMyNDIyLTMuNjcxMDk0IDAtNi41MjM2MzMgMy4wNTA5Nzd6IiBzdHJva2Utd2lkdGg9Ii4yNjQ1ODMzMiIvPg0KCQk8L2c+DQoJPC9nPg0KPC9zdmc+DQo=')} diff --git a/public/piece-css/letter.css b/public/piece-css/letter.css new file mode 100644 index 0000000000..f45b944e18 --- /dev/null +++ b/public/piece-css/letter.css @@ -0,0 +1,12 @@ +.is2d .pawn.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGNpcmNsZSBjeD0iMTUwIiBjeT0iMTUwIiBmaWxsPSIjYzhjOGM4IiBvcGFjaXR5PSIuOTg4IiByPSI0NC45OTUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSI1Ii8+PC9zdmc+')} +.is2d .knight.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIxNC4yMzEgMjI3Ljg1OHEwIDIuNTYzLS44OTcgNC4zNTgtLjc3IDEuNzk0LTIuMTc5IDIuOTQ3LTEuMjgxIDEuMTU0LTIuOTQ3IDEuNjY2LTEuNjY2LjUxMy0zLjMzMi41MTNoLTcuMDQ5cS0zLjMzMiAwLTUuODk1LS42NC0yLjQzNS0uNzctNC43NDItMi41NjQtMi4xNzgtMS45MjItNC40ODUtNS4xMjYtMi4xNzktMy4yMDQtNC44Ny04LjIwMmwtNTIuMjg4LTk0LjMyM3EtNC4xLTcuMzA1LTguMzMtMTUuMjUtNC4xLTguMDc0LTcuNjktMTUuNjM1aC0uMjU1cS4yNTYgOS4yMjcuMzg0IDE4LjgzOS4xMjggOS42MTEuMTI4IDE5LjA5NXYxMDAuMDlxMCAuODk2LS41MTIgMS43OTQtLjUxMy43NjgtMS43OTUgMS4yODEtMS4xNTMuMzg1LTMuMjAzLjY0LTEuOTIzLjM4NS00Ljk5OS4zODUtMy4wNzUgMC01LjEyNi0uMzg0LTEuOTIyLS4yNTYtMy4wNzYtLjY0LTEuMTUzLS41MTQtMS42NjYtMS4yODItLjUxMi0uODk4LS41MTItMS43OTVWODAuNjA4cTAtNS4xMjcgMi44Mi03LjMwNSAyLjgxOS0yLjE3OSA2LjE1LTIuMTc5aDEwLjUxcTMuNzE2IDAgNi4xNTEuNjQxIDIuNTYzLjY0IDQuNDg1IDIuMTc5IDIuMDUgMS40MSAzLjg0NSA0LjEgMS45MjIgMi41NjQgNC4xMDEgNi41MzdsNDAuMjQgNzIuNzkycTMuNzE3IDYuNjY0IDcuMTc4IDEzLjA3MiAzLjQ2IDYuMjggNi42NjQgMTIuNDMgMy4yMDQgNi4xNTIgNi4yOCAxMi4xNzYgMy4yMDMgNS44OTUgNi4yNzkgMTEuOTE4aC4xMjhxLS4yNTYtMTAuMTI0LS4zODQtMjEuMDE3Vjc0Ljg0cTAtLjg5Ny41MTItMS42NjYuNTEzLS43NyAxLjY2Ni0xLjI4MiAxLjI4Mi0uNjQgMy4yMDQtLjg5NyAyLjA1LS4yNTYgNS4yNTUtLjI1NiAyLjgxOSAwIDQuODcuMjU2IDIuMDUuMjU2IDMuMjAzLjg5NyAxLjE1NC41MTMgMS42NjYgMS4yODIuNTEzLjc2OS41MTMgMS42NjZ6IiBmaWxsPSIjYzhjOGM4IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iNSIvPjwvc3ZnPg==')} +.is2d .bishop.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIwNS43OTYgMTg5LjgyNXEwIDcuODE3LTIuMDUgMTQuNDgxLTEuOTIzIDYuNTM2LTUuNTExIDExLjc5LTMuNTg5IDUuMjU1LTguNzE1IDkuMjI4LTQuOTk4IDMuOTczLTExLjQwNiA2LjY2NC02LjI4IDIuNjkxLTEzLjU4NCA0LjEwMS03LjE3NyAxLjI4Mi0xNi41MzIgMS4yODJIMTA0LjY4cS0yLjk0NyAwLTUuNjM5LTEuOTIzLTIuNTYzLTIuMDUtMi41NjMtNy4wNDhWODAuNTA4cTAtNC45OTggMi41NjMtNi45MiAyLjY5Mi0yLjA1IDUuNjQtMi4wNWgzNy42NzdxMTQuODY2IDAgMjQuMzUgMi44MTkgOS40ODMgMi44MiAxNS43NjMgOC4yMDIgNi40MDcgNS4zODIgOS42MTEgMTMuMiAzLjIwNCA3LjgxNyAzLjIwNCAxNy42ODUgMCA1Ljg5NS0xLjQxIDExLjI3OC0xLjQxIDUuMzgyLTQuMjI5IDkuOTk2LTIuNjkgNC40ODUtNi45MiA4LjA3NC00LjEwMSAzLjU4OC05LjQ4MyA1Ljg5NSA2Ljc5MiAxLjI4MSAxMi42ODcgNC43NDIgNS44OTUgMy4zMzIgMTAuMjUyIDguNTg2IDQuNDg2IDUuMjU0IDcuMDQ5IDEyLjMwMyAyLjU2MyA3LjA0OSAyLjU2MyAxNS41MDd6bS0zMy4xOTItNzQuMjAycTAtNi4wMjQtMS42NjYtMTAuODkzLTEuNjY2LTQuODctNS4yNTUtOC4yMDItMy41ODgtMy40Ni05LjM1NS01LjI1NS01Ljc2Ny0xLjc5NC0xNS4yNS0xLjc5NGgtMjIuODEydjUzLjY5N2gyNS4xMThxOC41ODcgMCAxMy44NDEtMi4xNzggNS4yNTQtMi4zMDcgOC43MTUtNi4wMjQgMy40Ni0zLjg0NCA0Ljk5OC04Ljg0MiAxLjY2Ni01LjEyNyAxLjY2Ni0xMC41MXptOS45OTYgNzUuNDgzcTAtNy40MzMtMi40MzUtMTMuMDcxLTIuMzA3LTUuNjQtNi45Mi05LjQ4NC00LjQ4Ni0zLjg0NS0xMS40MDYtNS43NjctNi43OTMtMi4wNS0xNy4xNzMtMi4wNWgtMjYuNHY1OC40MzhoMzIuMDM5cTcuNTYgMCAxMy4yLTEuNzk0IDUuNjM5LTEuNzk0IDkuODY4LTUuMjU0IDQuMzU3LTMuNTg4IDYuNzkyLTguODQzIDIuNDM1LTUuMjU0IDIuNDM1LTEyLjE3NXoiIGZpbGw9IiNjOGM4YzgiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSI1Ii8+PC9zdmc+')} +.is2d .rook.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIwOC44NDMgOTk3LjYzcTAgMS4wMjUtLjM4NSAxLjc5NC0uMzg0Ljc2OS0xLjY2NiAxLjI4MS0xLjI4MS41MTMtMy41ODguNzctMi4zMDcuMjU2LTYuMTUyLjI1Ni0zLjMzMiAwLTUuNTEtLjI1Ny0yLjA1LS4yNTYtMy4zMzItLjc2OS0xLjI4Mi0uNjQtMi4wNS0xLjY2Ni0uNjQxLTEuMDI1LTEuMTU0LTIuNTYzbC0xNS4yNS0zOS4wODdxLTIuNjkyLTYuNjY0LTUuNjM5LTEyLjE3NC0yLjgyLTUuNjM5LTYuNzkyLTkuNjEyLTMuOTczLTQuMS05LjM1NS02LjI4LTUuMzgzLTIuMzA2LTEyLjk0NC0yLjMwNmgtMTQuNzM4djcwLjYxM3EwIDEuMDI1LS42NCAxLjc5NC0uNTEzLjc2OS0xLjc5NCAxLjI4MS0xLjE1NC4zODUtMy4zMzIuNjQxLTIuMDUuMzg1LTUuMjU1LjM4NS0zLjIwNCAwLTUuMzgyLS4zODUtMi4wNS0uMjU2LTMuMzMyLS42NC0xLjI4Mi0uNTEzLTEuNzk0LTEuMjgyLS41MTMtLjc3LS41MTMtMS43OTRWODQ0LjEwMnEwLTQuOTk4IDIuNTYzLTYuOTIgMi42OTEtMi4wNTEgNS42MzktMi4wNTFoMzUuMjQycTYuMjggMCAxMC4zOC4zODQgNC4yMy4yNTcgNy41NjIuNjQxIDkuNjExIDEuNjY2IDE2LjkxNiA1LjI1NSA3LjQzMyAzLjU4OCAxMi40MyA5LjA5OCA0Ljk5OSA1LjUxMSA3LjQzNCAxMi42ODggMi41NjMgNy4wNDggMi41NjMgMTUuNjM0IDAgOC4zMy0yLjMwNyAxNC45OTQtMi4xNzkgNi41MzYtNi40MDggMTEuNjYyLTQuMjI5IDQuOTk4LTEwLjEyNCA4LjcxNS01Ljg5NSAzLjcxNi0xMy4yIDYuMjggNC4xMDEgMS43OTMgNy40MzMgNC42MTMgMy4zMzIgMi42OTEgNi4xNTIgNi41MzYgMi45NDcgMy44NDQgNS41MSA4Ljg0MiAyLjU2MyA0Ljk5OCA1LjEyNiAxMS4yNzhsMTQuODY2IDM2LjUyM3ExLjc5NCA0LjYxNCAyLjMwNyA2LjUzNi41MTMgMS43OTQuNTEzIDIuODJ6TTE3NS42NSA4ODEuMTM4cTAtOS43NC00LjM1Ny0xNi40MDQtNC4zNTgtNi43OTItMTQuNjEtOS43NC0zLjIwNC0uODk2LTcuMzA1LTEuMjgtMy45NzItLjM4NS0xMC41MDgtLjM4NWgtMTguNTgzdjU1Ljg3NWgyMS41M3E4LjcxNSAwIDE0Ljk5NC0yLjA1IDYuNDA4LTIuMTggMTAuNjM3LTUuODk2IDQuMjI5LTMuODQ0IDYuMTUxLTguOTcgMi4wNS01LjEyNyAyLjA1LTExLjE1eiIgZmlsbD0iI2M4YzhjOCIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjUiIHRyYW5zZm9ybT0ibWF0cml4KDEuMDEwOTcgMCAwIC45ODkxNSAtNC4yNjkgLTc1NC4zODMpIi8+PC9zdmc+')} +.is2d .queen.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTI0NS4wOTEgMjQ4LjUxcTAgMi45NDgtLjM4NCA0Ljg3LS4yNTcgMi4wNS0uODk3IDMuMDc2LS42NDEgMS4xNTMtMS40MSAxLjUzOC0uNzcuMzg0LTEuNTM4LjM4NC0yLjU2MyAwLTguMzMtMi4xNzgtNS42MzktMi4wNS0xMy4wNzItNi4xNTItNy40MzMtMy45NzMtMTUuODkxLTkuNzQtOC40NTktNS43NjctMTYuNDA0LTEzLjQ1Ni02LjI4IDMuODQ1LTE1Ljg5MSA2LjY2NC05LjYxMiAyLjgyLTIyLjMgMi44Mi0xOC43MSAwLTMyLjQyMy01LjUxMS0xMy41ODQtNS41MS0yMi41NTUtMTYuMTQ4LTguODQzLTEwLjYzNy0xMy4yLTI2LjQtNC4zNTgtMTUuODkxLTQuMzU4LTM2LjM5NiAwLTE5LjczNiA0Ljc0Mi0zNS42MjcgNC43NDItMTYuMDIgMTQuMjI1LTI3LjE2OSA5LjQ4NC0xMS4yNzggMjMuNzEtMTcuMzAxIDE0LjIyNS02LjE1MiAzMy4xOTItNi4xNTIgMTcuODEzIDAgMzEuMjcgNS41MTEgMTMuNTg0IDUuNTEgMjIuNjgzIDE2LjE0OCA5LjIyNyAxMC41MDkgMTMuODQgMjYuMDE1IDQuNjE0IDE1LjUwNyA0LjYxNCAzNS42MjggMCAxMC4zOC0xLjI4MSAxOS44NjQtMS4xNTQgOS40ODMtMy44NDUgMTcuOTQxLTIuNTYzIDguNDU5LTYuNTM2IDE1LjYzNS0zLjk3MyA3LjE3Ny05LjM1NSAxMi45NDQgOS4zNTUgNy42OSAxNi40MDQgMTIuMDQ3IDcuMDQ4IDQuMjI5IDExLjY2MiA2LjQwOCA0LjYxNCAyLjE3OCA3LjE3NyAzLjA3NSAyLjU2MyAxLjAyNiAzLjg0NCAyLjE3OSAxLjI4MiAxLjI4MSAxLjc5NSAzLjQ2LjUxMiAyLjMwNy41MTIgNi4wMjN6bS00My41NzMtOTguMDM5cTAtMTQuMDk3LTIuNTYzLTI2LjE0My0yLjQzNS0xMi4wNDctOC4zMy0yMC44OS01Ljc2Ny04Ljk3LTE1LjUwNy0xMy45NjktOS43NC00Ljk5OC0yNC4wOTMtNC45OTh0LTI0LjA5MyA1LjM4M3EtOS43NCA1LjI1NC0xNS44OTIgMTQuMzUzLTYuMDIzIDguOTcxLTguNzE0IDIwLjg5LTIuNTYzIDExLjkxOC0yLjU2MyAyNS4yNDYgMCAxNC42MSAyLjQzNSAyNi45MTMgMi40MzUgMTIuMTc1IDguMjAyIDIxLjE0NiA1Ljc2NyA4Ljk3IDE1LjM3OCAxMy45NjkgOS43NCA0Ljg3IDI0LjM1IDQuODcgMTQuNDgxIDAgMjQuMzUtNS4zODMgOS44NjctNS4zODMgMTUuODktMTQuNDgyIDYuMDI0LTkuMjI3IDguNTg3LTIxLjI3MyAyLjU2My0xMi4xNzUgMi41NjMtMjUuNjMyeiIgZmlsbD0iI2M4YzhjOCIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjUiLz48L3N2Zz4=')} +.is2d .king.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIwNC4zMyAyMzMuNTNxMCAxLjAyNS0uNTEyIDEuOTIyLS4zODUuNzY5LTEuNjY2IDEuMjgyLTEuMjgyLjUxMi0zLjQ2Ljc2OS0yLjE4LjM4NC01LjY0LjM4NC00LjQ4NSAwLTcuMzA0LS4zODQtMi44Mi0uMzg1LTQuMjMtMS40MS0xLjQwOS0xLjAyNS0yLjMwNi0yLjMwN2wtNjEuMDAyLTgyLjkxN3Y4Mi45MTdxMCAuODk3LS41MTMgMS43OTQtLjUxMi43Ny0xLjc5NCAxLjI4Mi0xLjI4MS4zODQtMy40Ni42NC0yLjA1LjM4NS01LjI1NC4zODUtMy4wNzYgMC01LjI1NS0uMzg0LTIuMTc5LS4yNTctMy40Ni0uNjQxLTEuMjgyLS41MTMtMS43OTQtMS4yODItLjUxMy0uODk3LS41MTMtMS43OTRWNzQuNjE2cTAtMS4wMjQuNTEzLTEuNzkzLjUxMi0uNzcgMS43OTQtMS4xNTQgMS4yODEtLjUxMiAzLjQ2LS43NjkgMi4xNzktLjM4NCA1LjI1NS0uMzg0IDMuMjAzIDAgNS4yNTQuMzg0IDIuMTc5LjI1NyAzLjQ2Ljc3IDEuMjgyLjM4NCAxLjc5NCAxLjE1My41MTMuNzY5LjUxMyAxLjc5NHY3My42OWw1OC42OTUtNzMuNjlxLjc2OS0xLjE1NCAxLjc5NC0xLjkyMiAxLjAyNi0uNzcgMi40MzUtMS4xNTQgMS41MzgtLjUxMyAzLjU4OS0uNzY5IDIuMTc4LS4yNTYgNS41MS0uMjU2dDUuMzgzLjM4NHEyLjA1LjI1NyAzLjIwNC43NyAxLjI4MS41MTIgMS42NjYgMS4yOC41MTIuNzcuNTEyIDEuNjY3IDAgMS42NjYtLjg5NyAzLjMzMi0uNzY5IDEuNjY2LTMuMDc1IDQuNjEzbC01NC45OCA2NS43NDQgNTkuMjA5IDc4LjY4OHEyLjE3OCAzLjMzMiAyLjU2MyA0LjYxMy41MTIgMS4xNTQuNTEyIDEuOTIzeiIgZmlsbD0iI2M4YzhjOCIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjUiLz48L3N2Zz4=')} +.is2d .pawn.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGNpcmNsZSBjeD0iMTUwIiBjeT0iMTUwIiBvcGFjaXR5PSIuOTg4IiByPSI0NC45OTUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVqb2luPSJiZXZlbCIgc3Ryb2tlLXdpZHRoPSIxMC4wMSIvPjwvc3ZnPg==')} +.is2d .knight.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIxNC4yMzEgMjI3Ljg1OHEwIDIuNTYzLS44OTcgNC4zNTgtLjc3IDEuNzk0LTIuMTc5IDIuOTQ3LTEuMjgxIDEuMTU0LTIuOTQ3IDEuNjY2LTEuNjY2LjUxMy0zLjMzMi41MTNoLTcuMDQ5cS0zLjMzMiAwLTUuODk1LS42NC0yLjQzNS0uNzctNC43NDItMi41NjQtMi4xNzgtMS45MjItNC40ODUtNS4xMjYtMi4xNzktMy4yMDQtNC44Ny04LjIwMmwtNTIuMjg4LTk0LjMyM3EtNC4xLTcuMzA1LTguMzMtMTUuMjUtNC4xLTguMDc0LTcuNjktMTUuNjM1aC0uMjU1cS4yNTYgOS4yMjcuMzg0IDE4LjgzOS4xMjggOS42MTEuMTI4IDE5LjA5NXYxMDAuMDlxMCAuODk2LS41MTIgMS43OTQtLjUxMy43NjgtMS43OTUgMS4yODEtMS4xNTMuMzg1LTMuMjAzLjY0LTEuOTIzLjM4NS00Ljk5OS4zODUtMy4wNzUgMC01LjEyNi0uMzg0LTEuOTIyLS4yNTYtMy4wNzYtLjY0LTEuMTUzLS41MTQtMS42NjYtMS4yODItLjUxMi0uODk4LS41MTItMS43OTVWODAuNjA4cTAtNS4xMjcgMi44Mi03LjMwNSAyLjgxOS0yLjE3OSA2LjE1LTIuMTc5aDEwLjUxcTMuNzE2IDAgNi4xNTEuNjQxIDIuNTYzLjY0IDQuNDg1IDIuMTc5IDIuMDUgMS40MSAzLjg0NSA0LjEgMS45MjIgMi41NjQgNC4xMDEgNi41MzdsNDAuMjQgNzIuNzkycTMuNzE3IDYuNjY0IDcuMTc4IDEzLjA3MiAzLjQ2IDYuMjggNi42NjQgMTIuNDMgMy4yMDQgNi4xNTIgNi4yOCAxMi4xNzYgMy4yMDMgNS44OTUgNi4yNzkgMTEuOTE4aC4xMjhxLS4yNTYtMTAuMTI0LS4zODQtMjEuMDE3Vjc0Ljg0cTAtLjg5Ny41MTItMS42NjYuNTEzLS43NyAxLjY2Ni0xLjI4MiAxLjI4Mi0uNjQgMy4yMDQtLjg5NyAyLjA1LS4yNTYgNS4yNTUtLjI1NiAyLjgxOSAwIDQuODcuMjU2IDIuMDUuMjU2IDMuMjAzLjg5NyAxLjE1NC41MTMgMS42NjYgMS4yODIuNTEzLjc2OS41MTMgMS42NjZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lam9pbj0iYmV2ZWwiIHN0cm9rZS13aWR0aD0iMTAiLz48L3N2Zz4=')} +.is2d .bishop.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIwNS43OTYgMTg5LjgyNXEwIDcuODE3LTIuMDUgMTQuNDgxLTEuOTIzIDYuNTM2LTUuNTExIDExLjc5LTMuNTg5IDUuMjU1LTguNzE1IDkuMjI4LTQuOTk4IDMuOTczLTExLjQwNiA2LjY2NC02LjI4IDIuNjkxLTEzLjU4NCA0LjEwMS03LjE3NyAxLjI4Mi0xNi41MzIgMS4yODJIMTA0LjY4cS0yLjk0NyAwLTUuNjM5LTEuOTIzLTIuNTYzLTIuMDUtMi41NjMtNy4wNDhWODAuNTA4cTAtNC45OTggMi41NjMtNi45MiAyLjY5Mi0yLjA1IDUuNjQtMi4wNWgzNy42NzdxMTQuODY2IDAgMjQuMzUgMi44MTkgOS40ODMgMi44MiAxNS43NjMgOC4yMDIgNi40MDcgNS4zODIgOS42MTEgMTMuMiAzLjIwNCA3LjgxNyAzLjIwNCAxNy42ODUgMCA1Ljg5NS0xLjQxIDExLjI3OC0xLjQxIDUuMzgyLTQuMjI5IDkuOTk2LTIuNjkgNC40ODUtNi45MiA4LjA3NC00LjEwMSAzLjU4OC05LjQ4MyA1Ljg5NSA2Ljc5MiAxLjI4MSAxMi42ODcgNC43NDIgNS44OTUgMy4zMzIgMTAuMjUyIDguNTg2IDQuNDg2IDUuMjU0IDcuMDQ5IDEyLjMwMyAyLjU2MyA3LjA0OSAyLjU2MyAxNS41MDd6bS0zMy4xOTItNzQuMjAycTAtNi4wMjQtMS42NjYtMTAuODkzLTEuNjY2LTQuODctNS4yNTUtOC4yMDItMy41ODgtMy40Ni05LjM1NS01LjI1NS01Ljc2Ny0xLjc5NC0xNS4yNS0xLjc5NGgtMjIuODEydjUzLjY5N2gyNS4xMThxOC41ODcgMCAxMy44NDEtMi4xNzggNS4yNTQtMi4zMDcgOC43MTUtNi4wMjQgMy40Ni0zLjg0NCA0Ljk5OC04Ljg0MiAxLjY2Ni01LjEyNyAxLjY2Ni0xMC41MXptOS45OTYgNzUuNDgzcTAtNy40MzMtMi40MzUtMTMuMDcxLTIuMzA3LTUuNjQtNi45Mi05LjQ4NC00LjQ4Ni0zLjg0NS0xMS40MDYtNS43NjctNi43OTMtMi4wNS0xNy4xNzMtMi4wNWgtMjYuNHY1OC40MzhoMzIuMDM5cTcuNTYgMCAxMy4yLTEuNzk0IDUuNjM5LTEuNzk0IDkuODY4LTUuMjU0IDQuMzU3LTMuNTg4IDYuNzkyLTguODQzIDIuNDM1LTUuMjU0IDIuNDM1LTEyLjE3NXoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVqb2luPSJiZXZlbCIgc3Ryb2tlLXdpZHRoPSIxMCIvPjwvc3ZnPg==')} +.is2d .rook.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIwOC44NDMgOTk3LjYzcTAgMS4wMjUtLjM4NSAxLjc5NC0uMzg0Ljc2OS0xLjY2NiAxLjI4MS0xLjI4MS41MTMtMy41ODguNzctMi4zMDcuMjU2LTYuMTUyLjI1Ni0zLjMzMiAwLTUuNTEtLjI1Ny0yLjA1LS4yNTYtMy4zMzItLjc2OS0xLjI4Mi0uNjQtMi4wNS0xLjY2Ni0uNjQxLTEuMDI1LTEuMTU0LTIuNTYzbC0xNS4yNS0zOS4wODdxLTIuNjkyLTYuNjY0LTUuNjM5LTEyLjE3NC0yLjgyLTUuNjM5LTYuNzkyLTkuNjEyLTMuOTczLTQuMS05LjM1NS02LjI4LTUuMzgzLTIuMzA2LTEyLjk0NC0yLjMwNmgtMTQuNzM4djcwLjYxM3EwIDEuMDI1LS42NCAxLjc5NC0uNTEzLjc2OS0xLjc5NCAxLjI4MS0xLjE1NC4zODUtMy4zMzIuNjQxLTIuMDUuMzg1LTUuMjU1LjM4NS0zLjIwNCAwLTUuMzgyLS4zODUtMi4wNS0uMjU2LTMuMzMyLS42NC0xLjI4Mi0uNTEzLTEuNzk0LTEuMjgyLS41MTMtLjc3LS41MTMtMS43OTRWODQ0LjEwMnEwLTQuOTk4IDIuNTYzLTYuOTIgMi42OTEtMi4wNTEgNS42MzktMi4wNTFoMzUuMjQycTYuMjggMCAxMC4zOC4zODQgNC4yMy4yNTcgNy41NjIuNjQxIDkuNjExIDEuNjY2IDE2LjkxNiA1LjI1NSA3LjQzMyAzLjU4OCAxMi40MyA5LjA5OCA0Ljk5OSA1LjUxMSA3LjQzNCAxMi42ODggMi41NjMgNy4wNDggMi41NjMgMTUuNjM0IDAgOC4zMy0yLjMwNyAxNC45OTQtMi4xNzkgNi41MzYtNi40MDggMTEuNjYyLTQuMjI5IDQuOTk4LTEwLjEyNCA4LjcxNS01Ljg5NSAzLjcxNi0xMy4yIDYuMjggNC4xMDEgMS43OTMgNy40MzMgNC42MTMgMy4zMzIgMi42OTEgNi4xNTIgNi41MzYgMi45NDcgMy44NDQgNS41MSA4Ljg0MiAyLjU2MyA0Ljk5OCA1LjEyNiAxMS4yNzhsMTQuODY2IDM2LjUyM3ExLjc5NCA0LjYxNCAyLjMwNyA2LjUzNi41MTMgMS43OTQuNTEzIDIuODJ6TTE3NS42NSA4ODEuMTM4cTAtOS43NC00LjM1Ny0xNi40MDQtNC4zNTgtNi43OTItMTQuNjEtOS43NC0zLjIwNC0uODk2LTcuMzA1LTEuMjgtMy45NzItLjM4NS0xMC41MDgtLjM4NWgtMTguNTgzdjU1Ljg3NWgyMS41M3E4LjcxNSAwIDE0Ljk5NC0yLjA1IDYuNDA4LTIuMTggMTAuNjM3LTUuODk2IDQuMjI5LTMuODQ0IDYuMTUxLTguOTcgMi4wNS01LjEyNyAyLjA1LTExLjE1eiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49ImJldmVsIiBzdHJva2Utd2lkdGg9IjEwIiB0cmFuc2Zvcm09Im1hdHJpeCgxLjAxMDk3IDAgMCAuOTg5MTUgLTQuMjY5IC03NTQuMzgzKSIvPjwvc3ZnPg==')} +.is2d .queen.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTI0NS4wOTEgMjQ4LjUxcTAgMi45NDgtLjM4NCA0Ljg3LS4yNTcgMi4wNS0uODk3IDMuMDc2LS42NDEgMS4xNTMtMS40MSAxLjUzOC0uNzcuMzg0LTEuNTM4LjM4NC0yLjU2MyAwLTguMzMtMi4xNzgtNS42MzktMi4wNS0xMy4wNzItNi4xNTItNy40MzMtMy45NzMtMTUuODkxLTkuNzQtOC40NTktNS43NjctMTYuNDA0LTEzLjQ1Ni02LjI4IDMuODQ1LTE1Ljg5MSA2LjY2NC05LjYxMiAyLjgyLTIyLjMgMi44Mi0xOC43MSAwLTMyLjQyMy01LjUxMS0xMy41ODQtNS41MS0yMi41NTUtMTYuMTQ4LTguODQzLTEwLjYzNy0xMy4yLTI2LjQtNC4zNTgtMTUuODkxLTQuMzU4LTM2LjM5NiAwLTE5LjczNiA0Ljc0Mi0zNS42MjcgNC43NDItMTYuMDIgMTQuMjI1LTI3LjE2OSA5LjQ4NC0xMS4yNzggMjMuNzEtMTcuMzAxIDE0LjIyNS02LjE1MiAzMy4xOTItNi4xNTIgMTcuODEzIDAgMzEuMjcgNS41MTEgMTMuNTg0IDUuNTEgMjIuNjgzIDE2LjE0OCA5LjIyNyAxMC41MDkgMTMuODQgMjYuMDE1IDQuNjE0IDE1LjUwNyA0LjYxNCAzNS42MjggMCAxMC4zOC0xLjI4MSAxOS44NjQtMS4xNTQgOS40ODMtMy44NDUgMTcuOTQxLTIuNTYzIDguNDU5LTYuNTM2IDE1LjYzNS0zLjk3MyA3LjE3Ny05LjM1NSAxMi45NDQgOS4zNTUgNy42OSAxNi40MDQgMTIuMDQ3IDcuMDQ4IDQuMjI5IDExLjY2MiA2LjQwOCA0LjYxNCAyLjE3OCA3LjE3NyAzLjA3NSAyLjU2MyAxLjAyNiAzLjg0NCAyLjE3OSAxLjI4MiAxLjI4MSAxLjc5NSAzLjQ2LjUxMiAyLjMwNy41MTIgNi4wMjN6bS00My41NzMtOTguMDM5cTAtMTQuMDk3LTIuNTYzLTI2LjE0My0yLjQzNS0xMi4wNDctOC4zMy0yMC44OS01Ljc2Ny04Ljk3LTE1LjUwNy0xMy45NjktOS43NC00Ljk5OC0yNC4wOTMtNC45OTh0LTI0LjA5MyA1LjM4M3EtOS43NCA1LjI1NC0xNS44OTIgMTQuMzUzLTYuMDIzIDguOTcxLTguNzE0IDIwLjg5LTIuNTYzIDExLjkxOC0yLjU2MyAyNS4yNDYgMCAxNC42MSAyLjQzNSAyNi45MTMgMi40MzUgMTIuMTc1IDguMjAyIDIxLjE0NiA1Ljc2NyA4Ljk3IDE1LjM3OCAxMy45NjkgOS43NCA0Ljg3IDI0LjM1IDQuODcgMTQuNDgxIDAgMjQuMzUtNS4zODMgOS44NjctNS4zODMgMTUuODktMTQuNDgyIDYuMDI0LTkuMjI3IDguNTg3LTIxLjI3MyAyLjU2My0xMi4xNzUgMi41NjMtMjUuNjMyeiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49ImJldmVsIiBzdHJva2Utd2lkdGg9IjEwIi8+PC9zdmc+')} +.is2d .king.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIwNC4zMyAyMzMuNTNxMCAxLjAyNS0uNTEyIDEuOTIyLS4zODUuNzY5LTEuNjY2IDEuMjgyLTEuMjgyLjUxMi0zLjQ2Ljc2OS0yLjE4LjM4NC01LjY0LjM4NC00LjQ4NSAwLTcuMzA0LS4zODQtMi44Mi0uMzg1LTQuMjMtMS40MS0xLjQwOS0xLjAyNS0yLjMwNi0yLjMwN2wtNjEuMDAyLTgyLjkxN3Y4Mi45MTdxMCAuODk3LS41MTMgMS43OTQtLjUxMi43Ny0xLjc5NCAxLjI4Mi0xLjI4MS4zODQtMy40Ni42NC0yLjA1LjM4NS01LjI1NC4zODUtMy4wNzYgMC01LjI1NS0uMzg0LTIuMTc5LS4yNTctMy40Ni0uNjQxLTEuMjgyLS41MTMtMS43OTQtMS4yODItLjUxMy0uODk3LS41MTMtMS43OTRWNzQuNjE2cTAtMS4wMjQuNTEzLTEuNzkzLjUxMi0uNzcgMS43OTQtMS4xNTQgMS4yODEtLjUxMiAzLjQ2LS43NjkgMi4xNzktLjM4NCA1LjI1NS0uMzg0IDMuMjAzIDAgNS4yNTQuMzg0IDIuMTc5LjI1NyAzLjQ2Ljc3IDEuMjgyLjM4NCAxLjc5NCAxLjE1My41MTMuNzY5LjUxMyAxLjc5NHY3My42OWw1OC42OTUtNzMuNjlxLjc2OS0xLjE1NCAxLjc5NC0xLjkyMiAxLjAyNi0uNzcgMi40MzUtMS4xNTQgMS41MzgtLjUxMyAzLjU4OS0uNzY5IDIuMTc4LS4yNTYgNS41MS0uMjU2dDUuMzgzLjM4NHEyLjA1LjI1NyAzLjIwNC43NyAxLjI4MS41MTIgMS42NjYgMS4yOC41MTIuNzcuNTEyIDEuNjY3IDAgMS42NjYtLjg5NyAzLjMzMi0uNzY5IDEuNjY2LTMuMDc1IDQuNjEzbC01NC45OCA2NS43NDQgNTkuMjA5IDc4LjY4OHEyLjE3OCAzLjMzMiAyLjU2MyA0LjYxMy41MTIgMS4xNTQuNTEyIDEuOTIzeiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49ImJldmVsIiBzdHJva2Utd2lkdGg9IjEwIi8+PC9zdmc+')} diff --git a/public/piece-css/merida.css b/public/piece-css/merida.css new file mode 100644 index 0000000000..4fa1600857 --- /dev/null +++ b/public/piece-css/merida.css @@ -0,0 +1,12 @@ +.is2d .pawn.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDEgMCAwIC45NzMyNCAwIDEuMjQzKSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIyMS4xMyIgeDI9Ijc3Ljc2NCIgeTE9IjM3LjM0NiIgeTI9IjM3LjQ2OSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Ik0yNSA0Ni40NDhIMTEuNjA2YTEzLjEzOSAxMy4xMzkgMCAwIDEtLjk5LTUuMDQzYzAtMi45NzUuODYzLTUuNjQ0IDIuNTk4LTguMDE4IDEuNzM2LTIuMzY1IDMuOTcxLTQuMDU0IDYuNjk3LTUuMDY3YTYuODI0IDYuODI0IDAgMCAxLTIuODYxLTIuMzk4Yy0uNzM3LTEuMDcxLTEuMS0yLjI4My0xLjEtMy42MzQgMC0xLjY5LjU3NS0zLjE1NiAxLjczNS00LjM5MiAxLjE1MS0xLjI0NCAyLjU3NC0xLjk2MSA0LjI2Ny0yLjE1LTEuMzQ2LS45ODEtMi4wMTUtMi4yODMtMi4wMTUtMy44OSAwLTEuMzUxLjQ5MS0yLjUxMyAxLjQ4Mi0zLjQ3Ny45ODItLjk2NCAyLjE3Ni0xLjQ0MiAzLjU4MS0xLjQ0MiAxLjM4OSAwIDIuNTgyLjQ3OCAzLjU3MyAxLjQ0Mi45OS45NjQgMS40OSAyLjEyNiAxLjQ5IDMuNDc3IDAgMS42MDctLjY2OSAyLjkwOS0yLjAxNSAzLjg5IDEuNjkzLjE4OSAzLjExNi45MDYgNC4yNjcgMi4xNSAxLjE2IDEuMjM2IDEuNzM2IDIuNzAzIDEuNzM2IDQuMzkyIDAgMS4zNTEtLjM3MyAyLjU2My0xLjEyNiAzLjYzNGE3LjAzNiA3LjAzNiAwIDAgMS0yLjg2MiAyLjM5OGMyLjcyNiAxLjAxMyA0Ljk2MiAyLjcwMiA2LjY5NyA1LjA2NyAxLjczNiAyLjM3NCAyLjYgNS4wNDMgMi42IDguMDE4IDAgMS43MzktLjMyMiAzLjQyLS45NjYgNS4wNDN6IiBmaWxsPSIjMWYxYTE3Ii8+PHBhdGggZD0iTTI1IDQ0LjgwOGgxMi4xNzVhMTEuNzkgMTEuNzkgMCAwIDAgLjUyNS0zLjQwM2MwLTIuNTEzLS43MTEtNC43ODctMi4xNDItNi44MzEtMS40My0yLjA0NC0zLjI3Ny0zLjU1Mi01LjUyLTQuNTE2LTEuNTg0LS42Mi0xLjY0My0uNjU5LTEuNjQzLTEuNzM4IDAtLjg0OS41NTktMS40NzUgMS42NjgtMS44NzkgMS41MzMtMS4wNDYgMi4zMDMtMi40MyAyLjMwMy00LjE1MyAwLTEuMjQ0LS40MzItMi4zMjQtMS4yODctMy4yNjMtLjg2NC0uOTMxLTEuOTA1LTEuNDY3LTMuMTI0LTEuNjE1LTEtLjA4My0xLjQ5LS42MjYtMS40OS0xLjY0IDAtLjQ1My4xNzgtLjg3My41NDItMS4yNi44OTctLjY3NiAxLjM0Ni0xLjU1OCAxLjM0Ni0yLjY1NCAwLS44OTgtLjMzOS0xLjY3My0xLTIuMzE1LS42Ni0uNjQzLTEuNDQ3LS45NjQtMi4zNTMtLjk2NC0uOTQgMC0xLjc0NC4zMi0yLjM5Ni45NjRhMy4xMzYgMy4xMzYgMCAwIDAtLjk3NCAyLjMxNWMwIDEuMDguNDQgMS45NjEgMS4zMzggMi42NTMuMzY0LjM1NS41NDIuNzc1LjU0MiAxLjI2MSAwIDEuMDE0LS40ODMgMS41NTctMS40NjUgMS42NGE0LjkgNC45IDAgMCAwLTMuMTMzIDEuNjE1Yy0uODU1Ljk0LTEuMjc4IDIuMDE5LTEuMjc4IDMuMjYzIDAgMS43MjIuNzcgMy4xMDcgMi4zMDMgNC4xNTMgMS4xMS40MTIgMS42NjggMS4wNDYgMS42NjggMS44NzkgMCAxLjA4LS4wNjggMS4xMTgtMS42NjggMS43MzgtMi4yNDQuOTY0LTQuMDgxIDIuNDcyLTUuNTAzIDQuNTE2LTEuNDIzIDIuMDQ0LTIuMTM0IDQuMzE4LTIuMTM0IDYuODMxIDAgMS4xOTUuMTc4IDIuMzI0LjUyNSAzLjQwM3oiIGZpbGw9InVybCgjYSkiLz48L3N2Zz4=')} +.is2d .knight.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjQwNSIgeDI9Ijc3LjY0MSIgeTE9IjM3LjM0NiIgeTI9IjM3LjM0NiI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Ik0yNi4xNzggOS4zOTVjMi42LjE3IDUuMDA0LjgzOCA3LjIyMiAyLjAxNSAyLjIxIDEuMTY5IDQuMDk4IDIuNjc2IDUuNjU2IDQuNTEzIDEuMDkyIDEuMjg3IDIuMTE3IDIuODQ1IDMuMDgyIDQuNjY1YTI4LjY4NCAyOC42ODQgMCAwIDEgMi4zMiA1Ljc3NCAzNi41MTEgMzYuNTExIDAgMCAxIDEuMjUzIDcuNDZjLjE3NyAyLjU5OS4yNjIgNS4wMTIuMjYyIDcuMjN2NS40MDJIMTUuNDY4Yy0uMTUzIDAtLjIyLS40MDctLjIxMi0xLjIxLjAwOS0uODE0LjA2LTEuNDY2LjE2LTEuOTY1LjA2LS4zOTguMjIxLS45NTcuNDY3LTEuNjg1LjI1NC0uNzI4LjY2LTEuNjA5IDEuMjQ0LTIuNjUuMjYzLS41MzQuODktMS4zMDQgMS44OC0yLjMyLjk5OS0xLjAxNiAyLjEzMy0yLjIwMSAzLjQyOS0zLjUzOS43NDUtLjc2MiAxLjMyLTEuNzE5IDEuNzQ0LTIuODc5LjQyMy0xLjE1MS42MDEtMi4yMDEuNTMzLTMuMTVhOC4zNyA4LjM3IDAgMCAxLTIuMDA2IDEuMjJjLTMuNTA1IDEuMjUzLTYuMDQ1IDMuMDczLTcuNjEyIDUuNDUyLS4xMTguMTUzLS40OS44MjItMS4xMTcgMi4wMTUtLjMzLjYyNy0uNjE4IDEuMDU5LS44NDcgMS4yODctLjMxMy4zMTQtLjc3LjQ5MS0xLjM2My41MjUtLjkyMy4wNDMtMS42NDMtLjM5OC0yLjE2LTEuMzQ2LS42OTMuMjAzLTEuMzEyLjI4OC0xLjg2Mi4yNTQtLjkyMy0uMzQ3LTEuNTkyLS43Mi0yLjAwNi0xLjExNy0uODQ3LS44NDctMS4zODktMS42ODUtMS42NTEtMi41MzJhOS40MyA5LjQzIDAgMCAxLS4zODEtMi43MjZjMC0xLjM4OS44NTUtMy4yMjYgMi41ODItNS41MTIgMi4wMTUtMi42MjUgMy4wOS00LjYzMSAzLjIxNy02LjAwMyAwLS41OTMuMDYtMS4yNjEuMTc4LTIuMDA3YTQuMTk4IDQuMTk4IDAgMCAxIC42MTgtMS40OWMuMjItLjMzLjM2NC0uNTU4LjQzMi0uNjc3LjA3Ni0uMTI3LjIxMi0uMzEzLjQxNS0uNTU5LjE0NC0uMjAzLjI3LS4zNTUuMzcyLS40NTcuMDkzLS4xMS4yMi0uMjU0LjM3My0uNDQuMTc4LS4yMTIuNDA2LS40NTcuNjk0LS43NDVhMTguMDYgMTguMDYgMCAwIDEtMS4wNjctNy40NmMzLjI4NSAxLjE2OSA2LjA1NCAzLjAxNSA4LjI4IDUuNTMuNTUxLTEuODcyIDEuNjI2LTMuMzg3IDMuMjI2LTQuNTM5IDEuMzIxLjkyMyAyLjM3MSAyLjE1IDMuMTUgMy42NjZ6IiBmaWxsPSIjMWYxYTE3Ii8+PHBhdGggZD0iTTQyLjk3NiA0NC42OTNjLS4wMTcgMCAwLS40NDkuMDQyLTEuMzQ2LjA1MS0uOTA2LjA3Ni0xLjg4LjA3Ni0yLjkyMS4wMTctMi4wNjYuMDE3LTQuMiAwLTYuNDFhMjYuODM3IDI2LjgzNyAwIDAgMC0uODg5LTYuNjEyYy0uNTY3LTIuMTE3LTEuMTg1LTMuOTItMS44NjItNS40MTktLjY3OC0xLjQ5OC0xLjQxNC0yLjc4NS0yLjIxLTMuODc4LTEuMTg1LTEuNzg2LTIuODExLTMuMzAyLTQuODYtNC41MzgtMi4wNDktMS4yNDQtNC4xOS0yLjA1Ny02LjQyNi0yLjQzOC4xNTIuODEzLjIyIDEuNjA5LjIwMyAyLjM4Ny0uMDM0LjU5My0uMzEzLjg5LS44NDcuODktLjYxIDAtLjg4LS4yOTctLjgyLS44OS4wNS0yLjE4NC0uNzI5LTQuMDU1LTIuMzMtNS42MDQtMS4yNTIgMS4zMi0xLjkzOCAyLjg1My0yLjAzMSA0LjYwNS0uMDM0LjU4NS0uMzMuODM5LS44OTguNzctLjUyNS0uMDE2LS43ODctLjMyLS43ODctLjkxNCAwIDAgLjAxNy0uMDY3LjA0Mi0uMjAzLS42NzcuMjItMS4zODguNTI1LTIuMTMzLjkyMy0uNDc0LjMzLS44NjQuMjQ2LTEuMTYtLjI0NS0uMjk3LS41LS4xNy0uODkuMzk4LTEuMTY5LjcxLS4zNjQgMS4yNDQtLjYzNSAxLjYwOC0uODIxYTE3LjYzNCAxNy42MzQgMCAwIDAtNC44Ni0zLjUyMiAxNy4zMSAxNy4zMSAwIDAgMCAxLjg4OSA2LjUyOGMuMjc5LjQyMy4yMTEuODA0LS4yMDQgMS4xMzQtLjQ2NS4zNjQtLjg1NS4zMTMtMS4xNjgtLjE3YTguODcgOC44NyAwIDAgMS0uNDkxLS44OTdjLS4zNDcuMzQ3LS41ODQuNjEtLjY5NC43Ny0uMTE5LjE1My0uMzIyLjQ4My0uNjEuOTkxLS4yODguNTE3LS41Ljk0LS42MzUgMS4yNy0uMTQ0LjQxNS0uMjEyLjc0NS0uMTg2IDEuMDA4LjAyNS4yNTQuMDUuNTMzLjA2Ny44NTVhNy42MSA3LjYxIDAgMCAxLTEuMDA3IDIuNzUyIDEzMy43MSAxMzMuNzEgMCAwIDEtMS45OTggMy4xNSAxMjcuNjA3IDEyNy42MDcgMCAwIDEtMS43ODcgMi42NzVjLS40MTUuNjAxLS43MjggMS4zNTQtLjk0IDIuMjg2LS4xNTIuNTU5LS4xNTIgMS4yNDQgMCAyLjA0LjE0NC44MDUuNDc1IDEuNDMxLjk2NiAxLjg4Ljc2Mi43NyAxLjQ5OCAxLjEyNiAyLjIxIDEuMDY3LjIyOCAwIC41NDEtLjA5My45My0uMjguMzktLjE3OC42ODctLjUyNS45MDctMS4wNDEuNDIzLS45NC43NzktMS40MTQgMS4wNjctMS40MTQuNDA2IDAgLjYzNS4yMzcuNjY4LjY5NCAwIC4xMDItLjEzNS41MTctLjM5NyAxLjI0NS0uMTUzLjMzLS4zNDguNjc3LS41OTMgMS4wNDEtLjMyMi40MzItLjQ1Ny42MS0uNDIzLjU0Mi4yNjIuOTQ4LjcwMiAxLjExIDEuMzEyLjUuMTc4LS4xNzguMzktLjUyNS42MTgtMS4wMTYuMjM3LS41LjYwMS0xLjE2OSAxLjA5Mi0yLjAwNy41ODQtLjk4MiAxLjIwMi0xLjc3IDEuODYzLTIuMzg4LjY2LS42MSAxLjI0NC0xLjEwOSAxLjc2LTEuNDgxLjI5Ny0uMjIuNjYxLS40NjYgMS4wOTMtLjc0NS40MzItLjI4OCAxLjAwOC0uNTc2IDEuNzM2LS44NzIuNTc2LS4yMjkgMS4yMTktLjUxNyAxLjkyMi0uODU2czEuMzI5LS43NyAxLjg3LTEuMzAzYy43NjMtLjc0NSAxLjM0Ny0xLjY2IDEuNzYyLTIuNzUyLjIyLS42MS4yOTYtMS4zNjMuMjQ1LTIuMjYtLjE0NC0uNTYuMTM2LS44MzkuODQ3LS44MzkuNTMzIDAgLjgzLjI3MS44OTguODIxIDAgMS44NjMtLjUzNCAzLjU2NS0xLjU5MiA1LjEwNi4zNDcgMS4wNTguNDQgMi4yMTguMjcgMy40NzEtLjE0MyAxLjAwOC0uNDk5IDIuMDkxLTEuMDUgMy4yNDMtLjU1OCAxLjE0My0xLjY3NiAyLjQyMS0zLjM2IDMuODI3LTMuNDMgMi44NDUtNS4wNDYgNS43NzQtNC44NiA4Ljc4aDEyLjE3NXpNOS4zMzggMjkuNjEzYy0uNDgzLjI5Ny0uNzcuNjk1LS44NzIgMS4xOTQuMDE3LjU0Mi0uMjM3LjgzOS0uNzYyLjg5LS41ODQuMDY3LS44OC0uMTc4LS44OTgtLjc0Ni4wNjgtMS4wOTIuNTUtMS45NTUgMS40NjUtMi41OTkuNDMyLS4zNDcuODMtLjMyMiAxLjE5NC4wOTMuMzY0LjQ0OS4zMjIuODM4LS4xMjcgMS4xNjl6bTcuMzY2LTExLjgyN2MuMjEyLjMzLjI5Ni42NzcuMjQ1IDEuMDQxLS4xNiAxLjA1OC0uNzUzIDEuNDk5LTEuNzYgMS4zMzhhMS41OTYgMS41OTYgMCAwIDEtLjcyLS4yOTZjLS4wNi4wNzYtLjE2MS4yNjItLjI5Ny41NDEtLjE3OC41MzQtLjUyNS43MTItMS4wNDEuNTUtLjUwOC0uMjAyLS43MTEtLjU3NS0uNTkzLTEuMTE3Ljc0NS0xLjkwNSAyLjA5MS0zLjIwOSA0LjAzOS0zLjkyLjU2Ny0uMTcuOTQgMCAxLjExNy40OTEuMjA0LjUzNC4wNTEuODk4LS40NDggMS4wOTJhMi43NDUgMi43NDUgMCAwIDEtLjI3MS4xMzZjLS4wODUuMDQyLS4xNy4wOTMtLjI3MS4xNDR6IiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+')} +.is2d .bishop.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjEzIiB4Mj0iNzcuNjQxIiB5MT0iMzcuNTkyIiB5Mj0iMzcuNDY5Ij48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNmZmYiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iMCIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZD0iTTI1LjQ0NyA0Mi4wMDhjLS4yMjguOTQtLjUxNiAxLjU5Mi0uODQ2IDEuOTU2LS4zMy4zNjQtLjc2Mi43NDUtMS4zMTMgMS4xNDMtLjU5Mi40MTUtMS4yOTUuNzYyLTIuMTA4IDEuMDUtLjgxMy4yODgtMS43MS4zNjQtMi43LjIxMWwtNi45NjktLjk2NWEyLjg1OCAyLjg1OCAwIDAgMC0uNzYyIDBjLS4yMi4wMzQtLjQzMi4wNTEtLjYzNS4wNTEtLjM0NyAwLS43ODcuMDc2LTEuMzIuMjM3LS41NDIuMTUyLS45NTcuMzgxLTEuMjU0LjY3N2wtMi40MDQtMy45NDVjLjI5Ni0uMzMuNTU5LS41NTkuNzg3LS42OTQuMjM3LS4xMjcuNTA4LS4yNzEuODIxLS40MTVhOS4xNzkgOS4xNzkgMCAwIDEgMy4wNzQtLjgyMmMuNDY2LS4wMzMuOTIzLS4wNDIgMS4zNjMtLjAyNWE5LjggOS44IDAgMCAwIDEuMzk3LS4wNWMuODkuMTUyIDEuNzg2LjI4NyAyLjY4NC40MDYuOTA2LjEyNyAxLjgxMi4yNTQgMi43MTguMzkuOTkgMCAxLjY2LS4xMDIgMi4wMDYtLjI5Ny4xODctLjEwMi40NzQtLjI4OC44NzItLjU1LjM5OC0uMjYzLjc5Ni0uNjUyIDEuMTk0LTEuMTY5LS44OC0uMDkzLTEuNzctLjI2Mi0yLjY4NC0uNTA4YTI0LjA5NCAyNC4wOTQgMCAwIDEtMi40MDQtLjc1M2wyLjU4Mi02LjQwMWMtMS4yOTUtLjc0NS0yLjE5My0xLjMzOC0yLjcxLTEuNzk1YTUuMyA1LjMgMCAwIDEtMS4yMS0xLjU3NWMtLjQzMi0uNzYyLS43MTEtMS40OTktLjgzLTIuMjFhOS4zNDEgOS4zNDEgMCAwIDEtLjE2LTEuOTEzYy4wMTYtLjk5LjI0NS0yLjA4My43MDItMy4yODUuNDU3LTEuMTk0IDEuMzEyLTIuMjcgMi41NjYtMy4yMWE3OS4wOTEgNzkuMDkxIDAgMCAwIDMuMDU2LTIuNDU1IDI3Ljc0NiAyNy43NDYgMCAwIDAgMi45NDYtMi45NTRjLTEuMjE5LS42MjctMS44MjgtMS42MjYtMS44MjgtMi45OTggMC0uOTMuMzIxLTEuNzE4Ljk3My0yLjM4Ny42NTItLjY2IDEuNDU3LS45OSAyLjM5Ni0uOTkuOTIzIDAgMS43Mi4zMyAyLjM4Ljk5LjY2LjY2OS45OSAxLjQ1Ni45OSAyLjM4NyAwIDEuMzU1LS42MSAyLjM1NC0xLjgyOSAyLjk5OGEyNi43OTYgMjYuNzk2IDAgMCAwIDIuOTEzIDIuOTU0Yy45ODIuODM5IDIuMDE1IDEuNjYgMy4wOSAyLjQ1NiAxLjIzNi45NCAyLjA4MyAyLjAxNSAyLjUyMyAzLjIwOS40NDkgMS4yMDIuNjk0IDIuMjk0LjcyIDMuMjg1IDAgLjU2Ny0uMDUgMS4yMDItLjE3IDEuOTEzcy0uMzggMS40NDgtLjc5NSAyLjIxYTYuMDg0IDYuMDg0IDAgMCAxLTEuMjUzIDEuNTc1Yy0uNS40NTctMS4zODkgMS4wNS0yLjY2NyAxLjc5NWwyLjU4MiA2LjRhMjguNTcgMjguNTcgMCAwIDEtMi40NTUuNzU0Yy0uOTE1LjI0Ni0xLjc4Ny40MTUtMi42MzQuNTA4LjM4MS41MTcuNzcxLjkwNiAxLjE2OSAxLjE2OC4zOTguMjYzLjY5NC40NS44OTcuNTUuMzQ3LjE5NiAxLjAxNi4yOTcgMi4wMDcuMjk3YTI2My4zNSAyNjMuMzUgMCAwIDEgMi42OTItLjM5IDgxLjEzIDgxLjEzIDAgMCAwIDIuNzE4LS40MDZjLjQ0LjA1MS44OS4wNjggMS4zNDYuMDUxYTEzLjEyIDEzLjEyIDAgMCAxIDEuNDA2LjAyNSA5LjYyNyA5LjYyNyAwIDAgMSAzLjA3My44MjJjLjI5Ny4xNDQuNTY3LjI4OC44MDUuNDE1LjI0NS4xMzUuNTA4LjM2NC44MDQuNjk0bC0yLjQzIDMuOTQ1Yy0uMjk2LS4yOTYtLjcxMS0uNTI1LTEuMjUzLS42NzctLjUzNC0uMTYtLjk2NS0uMjM3LTEuMjk2LS4yMzctLjIyIDAtLjQ0LS4wMTctLjY2LS4wNWEyLjc5NCAyLjc5NCAwIDAgMC0uNzUzIDBsLTYuOTUyLjk2NGMtLjk5LjE1My0xLjkxMy4wODUtMi43Ni0uMTk0LS44NTUtLjI4LTEuNTU4LS42NTItMi4xLTEuMTE4YTIwLjA0IDIwLjA0IDAgMCAxLTEuMzAzLTEuMTUxYy0uMzIyLS4zMjItLjU5My0uOTU3LS44MDUtMS44OTd6IiBmaWxsPSIjMWYxYTE3Ii8+PHBhdGggZD0iTTI2LjMyIDM5LjE5N2MwIDEuMDkyLjI0NSAyLjAyNC43NTMgMi43OTQuNS43NyAxLjA0MSAxLjM3MiAxLjYyNiAxLjc5NS45MDUuNjY5IDIuMjM1IDEgMy45ODcgMSAuNDMyIDAgMS4yNzktLjA5NCAyLjUzMi0uMjhhNzQuNzM3IDc0LjczNyAwIDAgMSAyLjQ4LS4zNTZjLjYyNy0uMDc2IDEuMDUtLjEzNSAxLjI3LS4xODZhNi41MyA2LjUzIDAgMCAxIDEuOTgyLjA1Yy4yNjIuMDY4LjU1OS4xMjguODguMTg3YTEuNiAxLjYgMCAwIDEgLjgwNS4zOGwxLjE5NC0xLjkzYTcuMzcyIDcuMzcyIDAgMCAwLTIuMTYtLjcyYy0xLjI1Mi0uMjItMi4zNTMtLjI2Mi0zLjMwMS0uMTUxLS4yOC4wMzMtLjY0NC4xMTgtMS4xMDEuMjQ1LS40NTcuMTM2LTEuMDY3LjI2My0xLjg0Ni4zNzItMS42NzYuMjcyLTIuNTU3LjM5OS0yLjY1OC4zOTktLjY0NCAwLTEuMjAzLS4wNzctMS42ODUtLjI0NmExMC4zNyAxMC4zNyAwIDAgMS0xLjI4Ny0uNTQyYy0uODgtLjM5OC0xLjc3LTEuMzM4LTIuNjg0LTIuODF6bS0xLjc2MiAwaC0uNzk1Yy0uOTMyIDEuNDktMS44MTIgMi40My0yLjY1OSAyLjgxMS0uMzk4LjE5NS0uODMuMzczLTEuMzEyLjU0Mi0uNDgzLjE3LTEuMDMzLjI0Ni0xLjY2LjI0Ni0uMTE4IDAtLjk5OS0uMTI3LTIuNjU4LS4zOTgtLjc4OC0uMTEtMS40MjMtLjIzOC0xLjg4LS4zNzNhOC44MjggOC44MjggMCAwIDAtMS4wOTItLjI0NWMtLjk0OC0uMTEtMi4wNC0uMDY4LTMuMzAyLjE1MmE3LjA1NiA3LjA1NiAwIDAgMC0yLjEzNC43MmwxLjE5NCAxLjkzYy4xOTUtLjE5NS40NTctLjMyMi43NzktLjM4MS4zMjItLjA2LjYxOC0uMTE5Ljg4LS4xODZhNi41MyA2LjUzIDAgMCAxIDEuOTgyLS4wNTFjLjIyLjA1LjY0My4xMSAxLjI3LjE4Ni42MjYuMDc2IDEuNDY1LjE5NSAyLjUwNi4zNTYgMS4yMzYuMTg2IDIuMDgzLjI4IDIuNTMxLjI4IDEuNzM2IDAgMy4wNjUtLjMzMSAzLjk4OC0xIC41NjctLjQyMyAxLjEtMS4wMjQgMS42LTEuNzk1LjUwOC0uNzcuNzYyLTEuNzAyLjc2Mi0yLjc5NHptLjg5LTkuMzQ3YzEuNiAwIDMuMTQuMTI3IDQuNjE0LjM3MiAxLjYxNy0uNTc1IDIuNzk0LTEuNDgxIDMuNTIyLTIuN2E2Ljc0NSA2Ljc0NSAwIDAgMCAuOTQtMy40OTdjMC0uNzYyLS4xODctMS42LS41NjgtMi41MjMtLjM4LS45MTUtLjk5OS0xLjc0NC0xLjg2Mi0yLjQ5LS45NzQtLjgxMi0yLjA0LTEuNzAxLTMuMi0yLjY2NmEzMy4wOTMgMzMuMDkzIDAgMCAxLTMuNDQ3LTMuMzg3Yy0xLjE2IDEuMjg3LTIuMzExIDIuNDIxLTMuNDcgMy4zODdhNDA2LjU1IDQwNi41NSAwIDAgMC0zLjE3NiAyLjY2N2MtLjg4Ljc0NS0xLjQ5OSAxLjU3NC0xLjg3MSAyLjQ4OS0uMzczLjkyMy0uNTU5IDEuNzYtLjU1OSAyLjUyMyAwIDEuMjcuMzA1IDIuNDM4LjkxNCAzLjQ5Ny43MTIgMS4yMTkgMS44OTcgMi4xMjUgMy41NDggMi43YTI3Ljc0OSAyNy43NDkgMCAwIDEgNC42MTQtLjM3MnptMCA0LjUxM2MxLjkzOCAwIDMuNzkzLjE5NCA1LjU3OS41NzVsLTEuMTg1LTMuMDU2YTI4LjI5NyAyOC4yOTcgMCAwIDAtNC4zOTUtLjM0N2MtMS41MDcgMC0yLjk4LjExOC00LjQxLjM0N2wtMS4xOTQgMy4wNTZjMS43NjktLjM4IDMuNjQtLjU3NSA1LjYwNC0uNTc1em0wLTIzLjUzOGMxLjEyNiAwIDEuNjg0LS41NTkgMS42ODQtMS42ODVzLS41NTktMS42OTMtMS42ODUtMS42OTMtMS42ODQuNTY3LTEuNjg0IDEuNjkzYzAgMS4xMjYuNTU4IDEuNjg1IDEuNjg0IDEuNjg1em0wIDI3LjAwOWExOC45NyAxOC45NyAwIDAgMCAzLjI4NS0uMjhjMS4wNjYtLjE5NCAyLjEtLjQyMyAzLjA5LS42ODUtMS45NC0uNTA4LTQuMDY0LS43Ny02LjM3Ni0uNzctMi4zNDUgMC00LjQ3LjI2Mi02LjM3NS43Ny45NTcuMjYyIDEuOTczLjQ5IDMuMDQ4LjY4NmExOS40NiAxOS40NiAwIDAgMCAzLjMyNy4yNzl6bS0uODktMTQuMzM0bC0yLjA2NS0uMDI2Yy0uNTYgMC0uODM5LS4yNzktLjgzOS0uODQ2IDAtLjU1OS4yOC0uODM4LjgzOS0uODM4aDIuMDY1di0yLjEzNGMwLS41NzYuMjk3LS44NzIuODktLjg3Mi41NzUgMCAuODcyLjI5Ni44NzIuODcydjIuMTM0aDIuMTMzYy41NDIgMCAuODEzLjI4LjgxMy44MzggMCAuNTY3LS4yNzEuODQ2LS44MTMuODQ2SDI2LjMydjIuMDMyYzAgLjYwMi0uMjk3Ljg5OC0uODczLjg5OC0uNTkyIDAtLjg4OS0uMjk2LS44ODktLjg5OHoiIGZpbGw9InVybCgjYSkiLz48L3N2Zz4=')} +.is2d .rook.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjM3NiIgeDI9Ijc3LjY0MSIgeTE9IjM3LjQ2OSIgeTI9IjM3LjQ2OSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Ik0yOC40MDggOS4yMmg0LjIxNlY1LjgyNWg2Ljc5OXY5LjI5NmwtNS41MDMgNC4yNDJ2MTEuODYybDQuMjE2IDQuMjE2djUuMDhoMy43OTN2NS45MjdIOC4wNzFWNDAuNTJoMy43OTN2LTUuMDhsNC4yNDItNC4yMTZWMTkuMzYzbC01LjUwNC00LjI0MlY1LjgyNWg2Ljc3NFY5LjIyaDQuMjQyVjUuODI1aDYuNzl6IiBmaWxsPSIjMWYxYTE3Ii8+PHBhdGggZD0iTTMzLjA3MyAxNy42NzhsMy4xNS0yLjU1N2gtMjIuNDJsMy4xNzUgMi41NTd6bTcuMTk3IDI0LjUyOEg5Ljc1NnYyLjU1N0g0MC4yN3ptLTMuODQ0LTUuMDU1SDEzLjZ2My4zN2gyMi44MjZ6bS00LjIxNy0xNy43ODhIMTcuODE2djExLjg2MmgxNC4zOTN6bTUuNTA0LTUuOTI3VjcuNTFoLTMuMzk1djMuMzk1aC03LjY0NlY3LjUxaC0zLjM0NHYzLjM5NWgtNy42MlY3LjUxaC0zLjM5NXY1LjkyNnptLTEuOTE0IDIyLjAwNWwtMi41NDgtMi41MzFIMTYuOGwtMi42IDIuNTMxeiIgZmlsbD0idXJsKCNhKSIvPjwvc3ZnPg==')} +.is2d .queen.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjI1MyIgeDI9Ijc3LjY0MSIgeTE9IjM3LjIyNCIgeTI9IjM3LjM0NiI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Ik00NC41NDEgMTQuNzIzYy0uOTQgMC0xLjc0NC0uMzMtMi40MDQtLjk4Mi0uNjYtLjY1Mi0uOTkxLTEuNDQ4LS45OTEtMi4zOTYgMC0uOTIzLjMzLTEuNzE5Ljk5LTIuMzg4LjY2LS42NzcgMS40NjUtMS4wMDcgMi40MDUtMS4wMDcuOTMxIDAgMS43MjcuMzMgMi4zODggMS4wMDcuNjYuNjcuOTkgMS40NjUuOTkgMi4zODggMCAuOTQ4LS4zMyAxLjc0NC0uOTkgMi4zOTZhMy4yOCAzLjI4IDAgMCAxLTIuMzg4Ljk4MnptLTQuMzEgMjkuMjE5Yy0uODEyLjcxLTIuNjMzIDEuMzA0LTUuNDYgMS43ODYtMi44MjguNDc0LTYuMDg4LjcyLTkuNzcxLjcyLTMuNzUgMC03LjA1My0uMjU0LTkuODk4LS43NDUtMi44NDQtLjUtNC42NC0xLjExOC01LjM4NC0xLjg2M2wxLjU2Ni01Ljk1Mi0uNjk0LTMuODk1TDguNDA1IDMwLjIgNi4yOTcgMTQuNzc0bDEuMjEtLjQ3NCA2LjggMTEuNDU1LjE1Mi0xMy42NCAxLjY4NS0uMjk2IDUuMTgyIDEzLjcxNiAyLjc3Ni0xNC43NTdoMS43MmwyLjc3NiAxNC43MDZMMzMuNzMgMTEuODJsMS43MS4yOTYuMTUzIDEzLjY0IDYuODI0LTExLjQ4IDEuMTYuNTQxLTIuMDU4IDE1LjM1OS0yLjIxIDMuNzkzLS42OTQgMy45NDV6TTE0LjUzNSAxMS45ODhjLS45NDggMC0xLjc1Mi0uMzIxLTIuNDEzLS45NzMtLjY2LS42NTItLjk5LTEuNDU2LS45OS0yLjM5NiAwLS45MjMuMzMtMS43MTkuOTktMi4zOHMxLjQ2NS0uOTkgMi40MTMtLjk5Yy45MjMgMCAxLjcxOS4zMyAyLjM4Ljk5cy45OSAxLjQ1Ny45OSAyLjM4YzAgLjk0LS4zMyAxLjc0NC0uOTkgMi4zOTZhMy4yNjYgMy4yNjYgMCAwIDEtMi4zOC45NzN6TTUuNCAxNC43MjNjLS45NCAwLTEuNzM2LS4zMy0yLjM4OC0uOTgyLS42NTItLjY1Mi0uOTgyLTEuNDQ4LS45ODItMi4zOTYgMC0uOTIzLjMzLTEuNzE5Ljk4Mi0yLjM4OEMzLjY2NCA4LjI4IDQuNDYgNy45NSA1LjQgNy45NWMuOTQ4IDAgMS43NDQuMzMgMi40MTMgMS4wMDcuNjYuNjcuOTkgMS40NjUuOTkgMi4zODggMCAuOTQ4LS4zMyAxLjc0NC0uOTkgMi4zOTZhMy4zMjMgMy4zMjMgMCAwIDEtMi40MTMuOTgyem0xOS41NS0zLjk3Yy0uOTQgMC0xLjc0NS0uMzMtMi4zOTctLjk5MS0uNjUyLS42Ni0uOTc0LTEuNDY1LS45NzQtMi40MDUgMC0uOTMxLjMyMi0xLjcyNy45NzQtMi4zODcuNjUyLS42NiAxLjQ1Ni0uOTkgMi4zOTYtLjk5LjkyMyAwIDEuNzI3LjMzIDIuMzk2Ljk5YTMuMjMgMy4yMyAwIDAgMSAxIDIuMzg3YzAgLjk0LS4zMyAxLjc0NC0xIDIuNDA1LS42NjkuNjYtMS40NzMuOTktMi4zOTYuOTl6bTEwLjQxMyAxLjIzNWMtLjk0IDAtMS43MzYtLjMyMS0yLjM4Ny0uOTczLS42NTItLjY1Mi0uOTgzLTEuNDU2LS45ODMtMi4zOTYgMC0uOTIzLjMzLTEuNzE5Ljk4My0yLjM4czEuNDQ3LS45OSAyLjM4Ny0uOTljLjk0OCAwIDEuNzUzLjMzIDIuNDEzLjk5cy45OSAxLjQ1Ny45OSAyLjM4YzAgLjk0LS4zMyAxLjc0NC0uOTkgMi4zOTYtLjY2LjY1Mi0xLjQ2NS45NzMtMi40MTMuOTczeiIgZmlsbD0iIzFmMWExNyIgc3Ryb2tlPSIjMWYxYTE3IiBzdHJva2Utd2lkdGg9Ii4wNzYiLz48cGF0aCBkPSJNMzguMjE3IDQzLjA0NGMtMy4wMjMtMS4yNTMtNy40MTctMS44OC0xMy4xNjYtMS44OC01Ljg3NiAwLTEwLjMxMy42NDQtMTMuMzI3IDEuOTMxIDIuODk2IDEuMTQzIDcuMzE2IDEuNzEgMTMuMjUgMS43MSAyLjg0NSAwIDUuNDQ1LS4xNTIgNy43OTgtLjQ2NSAyLjM2My0uMzE0IDQuMTc1LS43NDUgNS40NDUtMS4yOTZ6TTI0Ljk0OSA5LjAxN2MxLjExIDAgMS42Ni0uNTYgMS42Ni0xLjY2IDAtMS4wOTItLjU1LTEuNjQyLTEuNjYtMS42NDItMS4wOTIgMC0xLjYzNC41NS0xLjYzNCAxLjY0MiAwIDEuMS41NDIgMS42NiAxLjYzNCAxLjY2em0xMi42MjQgMjQuOTc2Yy0zLjE5Mi0uODEyLTcuMzY2LTEuMjEtMTIuNTIyLTEuMjEtNS4yOTIgMC05LjUxNy40MDYtMTIuNjc1IDEuMjM2bC4zNzMgMi4zNzljMy4yMTctLjc2MiA3LjMyMy0xLjE0MyAxMi4zMDItMS4xNDMgNC45NDQgMCA4Ljk3NS4zNzIgMTIuMDk5IDEuMTE3em0uNjE4LTEuNDlsMS42MTctMi44NTNhNi40MzIgNi40MzIgMCAwIDEtMi40My40NzRjLTIuMjE4IDAtMy45ODctLjg5Ny01LjMwOC0yLjctLjk5LjgyLTIuMSAxLjIzNS0zLjMyOCAxLjIzNS0xLjU4MyAwLTIuODUzLS42MTgtMy43OTMtMS44NjItMS4wNTggMS4xNi0yLjMyIDEuNzQ0LTMuNzkzIDEuNzQ0LTEuMTk0IDAtMi4yODYtLjQwNi0zLjI3Ni0xLjIyLTEuMzg5IDEuNzctMy4xODQgMi42NS01LjM4NSAyLjY1YTcuMDU1IDcuMDU1IDAgMCAxLTIuNTA2LS40NjVsMS43MzUgMi45NzJjMy4yMS0uOTIzIDcuNjItMS4zODkgMTMuMjI1LTEuMzg5IDUuNzA3IDAgMTAuMTE4LjQ3NCAxMy4yNDIgMS40MTR6bS0xMS4xMDgtNS45MjZsLTIuMTA4LTEyLjEzMy0yLjEwOSAxMS45ODljLjA1MS0uMDM0LjE2MS0uMTE5LjM0OC0uMjU0LjM4LS43NDUuOTU2LTEuMTE4IDEuNzM1LTEuMTE4Ljg0NyAwIDEuMzg5LjM3MyAxLjYzNCAxLjExOC4xMDIuMTAxLjI3MS4yMzcuNS4zOTh6bTYuODY2LjQ3NFYxNS41NmwtNC4wOSAxMS4yNjFjLjMxNC0uMTEuNTc3LS4yNjIuNzk3LS40NC4zMy0uNDE1Ljc3OS0uNjI3IDEuMzM4LS42MjcuNjYgMCAxLjE5My4yOTcgMS41OTEuODcyLjA0My4wNjguMTAyLjEzNi4xNy4yMTIuMDY3LjA3Ni4xMzUuMTQ0LjE5NC4yMTJ6bS0xMy45MzYtLjM0N0wxNS45NSAxNS41NjJ2MTEuMzM2Yy4wNDMtLjA2Ny4xMTktLjE0NC4yMi0uMjQ1LjMzLS42OTQuODcyLTEuMDQyIDEuNjM0LTEuMDQyLjYyNyAwIDEuMTQzLjI2MyAxLjU0MS43OTYuNDQ5LjE5NS42Ny4yOTcuNjcuMjk3em0tNi4zIDEuMzg4TDguMzggMTguODlsMS4zNjMgOC4zODJjLjk0LjY2IDEuODYzLjk5IDIuNzUyLjk5LjM0NyAwIC43NTMtLjA1OSAxLjIxOS0uMTY5em0yMi4zOTUuMTE5Yy4zODEuMTE4LjgwNS4xNzggMS4yNy4xNzggMS4wMDggMCAxLjk0OC0uMzE0IDIuODI4LS45NGwxLjM2My04LjU4NXptMS40OSAxMi41NTZsLS43NDUtMi44MDNjLTMuMjQyLS43MS03LjIwNS0xLjA2Ni0xMS45MDQtMS4wNjYtNC42NDggMC04LjYxLjM1NS0xMS44NzggMS4wNjZsLS43NzEgMi44MjhjMy4wNzMtLjkzMSA3LjI5OC0xLjM4OCAxMi42NzUtMS4zODggNS4yNCAwIDkuNDQ4LjQ0OCAxMi42MjMgMS4zNjN6TTE0LjUzNSAxMC4yNTNjMS4wODQgMCAxLjYzNC0uNTQyIDEuNjM0LTEuNjM0cy0uNTUtMS42MzQtMS42MzQtMS42MzRjLTEuMTA5IDAtMS42NjguNTQyLTEuNjY4IDEuNjM0cy41NiAxLjYzNCAxLjY2OCAxLjYzNHptMjAuODI4IDBjMS4xMSAwIDEuNjY4LS41NDIgMS42NjgtMS42MzRzLS41NTktMS42MzQtMS42NjgtMS42MzRjLTEuMDgzIDAtMS42MzQuNTQyLTEuNjM0IDEuNjM0cy41NSAxLjYzNCAxLjYzNCAxLjYzNHpNNS40IDEyLjk4OGMxLjEwOSAwIDEuNjY4LS41NSAxLjY2OC0xLjY0MyAwLTEuMTEtLjU2LTEuNjYtMS42NjgtMS42Ni0xLjA4NCAwLTEuNjM0LjU1LTEuNjM0IDEuNjYgMCAxLjA5Mi41NSAxLjY0MyAxLjYzNCAxLjY0M3ptMzkuMTQxIDBjMS4wOTIgMCAxLjY0My0uNTUgMS42NDMtMS42NDMgMC0xLjExLS41NS0xLjY2LTEuNjQzLTEuNjYtMS4xIDAtMS42Ni41NS0xLjY2IDEuNjYgMCAxLjA5Mi41NiAxLjY0MyAxLjY2IDEuNjQzeiIgZmlsbD0idXJsKCNhKSIgc3Ryb2tlPSIjMWYxYTE3IiBzdHJva2Utd2lkdGg9Ii4wNzYiLz48L3N2Zz4=')} +.is2d .king.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjM3NiIgeDI9Ijc3LjY0MSIgeTE9IjM3LjM0NiIgeTI9IjM3LjM0NiI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Ik0yNS44MjEgMTIuMDIyaC0xLjc2di0zLjI1aC0yLjA2N2MtLjU1OCAwLS44MzgtLjI3Mi0uODM4LS44MjJ2LS4wMjVjMC0uNTQyLjI4LS44MTMuODM4LS44MTNoMi4wNjZWNS4wMDRjMC0uNTg1LjI5Ny0uODcyLjg5LS44NzIuNTc1IDAgLjg3MS4yODcuODcxLjg3MnYyLjEwOGgyLjEzNGMuNTQyIDAgLjgxMy4yNy44MTMuODEzdi4wMjVjMCAuNTUtLjI3MS44MjEtLjgxMy44MjFsLTIuMTE3LjAyNnpNMTEuMDMgMzcuNzQ0bC0uODEzLTQuNjRjLS4wMTcgMC0uMDQyLS4wMzMtLjA3Ni0uMTAxLS4wODUtLjExOS0uMzIyLS4yNzEtLjcxMS0uNDU3LS4zODEtLjE5NS0uODM4LS41MTctMS4zNDYtLjk4MmE0MS45OSA0MS45OSAwIDAgMS0xLjcwMi0xLjQ5IDguNTA5IDguNTA5IDAgMCAxLTEuMS0xLjIzN0M0LjI3MyAyNy40NSAzLjcwNSAyNS43NzIgMy41OTUgMjMuOGMtLjE3LTEuODk3LjYwMS0zLjc5NCAyLjMwMy01LjY4MiAxLjcxOS0xLjg4IDQuMDQ3LTIuNzY4IDYuOTY4LTIuNjUgMS4wOTIuMDY4IDIuMzguMzMgMy44NDQuNzk2LjQ4My4xOTUuOTc0LjM5IDEuNDgyLjU3NmwxLjQ5OC41ODRjLjI2My4xMzYuNS4yNzEuNjk1LjM5OGE0LjM4IDQuMzggMCAwIDEtLjEyNy0xLjA0MWMwLTEuMjg3LjQ1Ny0yLjM4OCAxLjM4LTMuMzAyLjkxNC0uOTA2IDIuMDIzLTEuMzcyIDMuMzEtMS4zODkgMS4yODcgMCAyLjM4OC40NjYgMy4zMDIgMS4zOC45MDYuOTE1IDEuMzYzIDIuMDE1IDEuMzYzIDMuMjg1IDAgLjI2My0uMDM0LjYxLS4xMDEgMS4wNDIuMjI4LS4xNDQuNDU3LS4yNzEuNjY5LS4zNzMuNzYyLS4zMyAxLjc2LS43MiAzLjAwNS0xLjE2IDEuNDIzLS40ODIgMi43MDEtLjc1MyAzLjg0NC0uODIxIDIuOTIxLS4xMzYgNS4yNDEuNzUzIDYuOTQzIDIuNjUgMS42NjggMS44ODggMi40NDcgMy43ODUgMi4zMjggNS42ODEtLjEyNyAxLjk3My0uNzAzIDMuNjUtMS43MSA1LjAzOC0uMzMuNDQ5LS43MDMuODYzLTEuMTE4IDEuMjUzYTQwLjUgNDAuNSAwIDAgMS0xLjY2IDEuNDczYy0uNTQxLjQ2Ni0xLjAwNy43OTYtMS4zODguOTgyLS4zOC4xODYtLjYuMzQ3LS42NjkuNDU3YS4yOTQuMjk0IDAgMCAxLS4wNS4wNzdjLS4wMTcuMDE3LS4wMjYuMDM0LS4wMjYuMDVsLS43OTYgNC42NjYgMS42NDMgNi4xMjFjLS44My43NDUtMi42ODQgMS4zNTUtNS41NTQgMS44MzctMi44NzkuNDgzLTYuMjA2LjcyLTkuOTc0LjcyLTMuODM1IDAtNy4yMTQtLjI1NC0xMC4xMTgtLjc1NC0yLjkxMi0uNTA4LTQuNzQxLTEuMTQzLTUuNDg2LTEuODk2eiIgZmlsbD0iIzFmMWExNyIvPjxwYXRoIGQ9Ik0yNS43OTYgMjkuNTMyYzIuODQ1LjAzMyA1LjQ0NC4yMDMgNy44MDYuNTA4IDIuMzcuMzA0IDQuMjI1LjY5NCA1LjU2MyAxLjE1MWExMjYuMzIgMTI2LjMyIDAgMCAwIDIuMDU3LTEuNjUxIDEyLjAxOCAxMi4wMTggMCAwIDAgMS44NjMtMS44NDZjLjc4Ny0xLjAwNyAxLjE4NS0yLjMzNyAxLjE4NS0zLjk5NiAwLTEuNDgyLS4zNTYtMi43MjYtMS4wNjctMy43MTctMS4yNy0xLjg1NC0zLjIwOS0yLjc3Ny01LjgtMi43NzctMS41NTcgMC0zLjE0OS4zMjItNC43OTIuOTY1LTEuNDM5LjU4NC0yLjUzMSAxLjIyOC0zLjI2OCAxLjk0LTEuMzg4IDEuMzg4LTIuNDIxIDMuMTc0LTMuMDgyIDUuMzUtLjIyOC43NzktLjM2NCAxLjQ5LS40MDYgMi4xMjUtLjA0Mi42MzUtLjA2IDEuMjg3LS4wNiAxLjk0N3ptLTEzLjI1IDYuNjk3YzMuMTQtLjc5NiA3LjMwNi0xLjE5NCAxMi41MDUtMS4xOTQgNS4wODggMCA5LjIwMy4zOCAxMi4zMjcgMS4xNDNsLjYxOC0zLjY1Yy0zLjMyNy0uODcxLTcuNjctMS4zMTItMTMuMDQ3LTEuMzEyLTUuNDEgMC05Ljc0NS40NS0xMy4wMjIgMS4zMzh6bTI1LjI5OCA0LjQxbC0uNzM3LTIuODQ0Yy0zLjI3Ni0uNzI4LTcuMzMyLTEuMDkyLTEyLjE1OC0xLjA5Mi00LjgwOSAwLTguODU2LjM2NC0xMi4xMzMgMS4wOTJsLS43ODcgMi44N2MzLjE1OC0uOTIzIDcuNDY4LTEuMzg4IDEyLjk0Ni0xLjM4OCA1LjQ0NCAwIDkuNzI4LjQ1NyAxMi44NjkgMS4zNjN6bS42NTIgMi4zMzhjLTMuMTkyLTEuMjg3LTcuNjgtMS45NC0xMy40NDUtMS45NC01Ljk4NiAwLTEwLjUxNi42NjEtMTMuNTk4IDEuOTkgMi45MTMgMS4xNTIgNy40MTcgMS43MzYgMTMuNTIyIDEuNzM2IDIuOTEyIDAgNS41NjItLjE2IDcuOTU4LS40ODMgMi40MDUtLjMyMSA0LjI1LS43NjIgNS41NjMtMS4zMDN6TTI0LjA3NyAyOS41MzJjLS4wMDgtLjY0NC0uMDM0LTEuMjg3LS4wNjgtMS45MjJzLS4xNi0xLjM0Ny0uMzcyLTIuMTI2Yy0uNjc3LTIuMjEtMS43MDItMy45OTYtMy4wODItNS4zNS0uNzExLS42OTUtMS43OTUtMS4zNDctMy4yNjgtMS45NC0xLjY4NS0uNjYtMy4yODUtLjk5LTQuNzkyLS45OS0yLjYwOCAwLTQuNTQ3LjkzMS01LjggMi44MDMtLjcxMS45OS0xLjA2NyAyLjIzNS0xLjA2NyAzLjcxNiAwIDEuNjI2LjM5OCAyLjk1NSAxLjE4NiAzLjk5Ny40ODIuNjEgMS4wOTIgMS4yMjcgMS44MzcgMS44MzcuNzQ1LjYxIDEuNDQgMS4xNjggMi4wODMgMS42NiAyLjg5NS0xLjA0MiA3LjM0LTEuNiAxMy4zNDMtMS42ODV6bS44NzItNC42MTVjLjExOS0uNDY1LjIxMi0uNzg3LjI5Ni0uOTY1LjE3LS42NDMuMzU2LTEuMTk0LjU3Ni0xLjY0My4wOTMtLjI3OS4yMzctLjYuNDMyLS45NzMuMTg2LS4zNzMuMzktLjgwNS42MS0xLjI3OS4xMjctLjI4LjI3LS42MjYuNDE1LTEuMDMzLjE1Mi0uNDA2LjMwNC0uODA0LjQ0OC0xLjIwMi4xMzYtLjMzLjIwMy0uNjg2LjIwMy0xLjA2NyAwLS44MTMtLjI5Ni0xLjQ5OC0uODcyLTIuMDY2LS41NzUtLjU3NS0xLjI3OC0uODYzLTIuMTA4LS44NjMtMS45NjQgMC0yLjk1NS45OS0yLjk1NSAyLjk1NSAwIC4zOC4wNjguNzM2LjIwMyAxLjA2Ny4zNjUgMS4wNzUuNjQ0IDEuODIuODM5IDIuMjM1LjIyLjQ3NC40MTUuOTA2LjYgMS4yNzguMTc5LjM3My4zNC42OTQuNDY2Ljk3NC4yMi41NS4zOTggMS4wOTIuNTUgMS42NDIuMDM1LjA5NC4xMjguNDE1LjI5Ny45NHoiIGZpbGw9InVybCgjYSkiLz48L3N2Zz4=')} +.is2d .pawn.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTI1IDQ2LjQ0OEgxMS42MDZhMTMuMTM5IDEzLjEzOSAwIDAgMS0uOTktNS4wNDNjMC0yLjk3NS44NjMtNS42NDQgMi41OTgtOC4wMTggMS43MzYtMi4zNjUgMy45NzEtNC4wNTQgNi42OTctNS4wNjdhNi44MjQgNi44MjQgMCAwIDEtMi44NjEtMi4zOThjLS43MzctMS4wNzEtMS4xLTIuMjgzLTEuMS0zLjYzNCAwLTEuNjkuNTc1LTMuMTU2IDEuNzM1LTQuMzkyIDEuMTUxLTEuMjQ0IDIuNTc0LTEuOTYxIDQuMjY3LTIuMTUtMS4zNDYtLjk4MS0yLjAxNS0yLjI4My0yLjAxNS0zLjg5IDAtMS4zNTEuNDkxLTIuNTEzIDEuNDgyLTMuNDc3Ljk4Mi0uOTY0IDIuMTc2LTEuNDQyIDMuNTgxLTEuNDQyIDEuMzg5IDAgMi41ODIuNDc4IDMuNTczIDEuNDQyczEuNDkgMi4xMjYgMS40OSAzLjQ3N2MwIDEuNjA3LS42NjkgMi45MDktMi4wMTUgMy44OSAxLjY5My4xODkgMy4xMTYuOTA2IDQuMjY3IDIuMTUgMS4xNiAxLjIzNiAxLjczNiAyLjcwMyAxLjczNiA0LjM5MiAwIDEuMzUxLS4zNzMgMi41NjMtMS4xMjYgMy42MzRhNy4wMzYgNy4wMzYgMCAwIDEtMi44NjIgMi4zOThjMi43MjYgMS4wMTMgNC45NjIgMi43MDIgNi42OTcgNS4wNjcgMS43MzYgMi4zNzQgMi42IDUuMDQzIDIuNiA4LjAxOCAwIDEuNzM5LS4zMjIgMy40Mi0uOTY2IDUuMDQzeiIgZmlsbD0iIzFmMWExNyIvPjwvc3ZnPg==')} +.is2d .knight.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjI1MyIgeDI9Ijc3LjY0MSIgeTE9IjM3LjU5MiIgeTI9IjM3LjQ2OSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Ik0yNi4xNzggOS4zOTVjMi42LjE3IDUuMDA0LjgzOCA3LjIyMiAyLjAxNSAyLjIxIDEuMTY5IDQuMDk4IDIuNjc2IDUuNjU2IDQuNTEzIDEuMDkyIDEuMjg3IDIuMTE3IDIuODQ1IDMuMDgyIDQuNjY1YTI4LjY4NCAyOC42ODQgMCAwIDEgMi4zMiA1Ljc3NCAzNi41MTEgMzYuNTExIDAgMCAxIDEuMjUzIDcuNDZjLjE3NyAyLjU5OS4yNjIgNS4wMTIuMjYyIDcuMjN2NS40MDJIMTUuNDY4Yy0uMTUzIDAtLjIyLS40MDctLjIxMi0xLjIxLjAwOS0uODE0LjA2LTEuNDY2LjE2LTEuOTY1LjA2LS4zOTguMjIxLS45NTcuNDY3LTEuNjg1LjI1NC0uNzI4LjY2LTEuNjA5IDEuMjQ0LTIuNjUuMjYzLS41MzQuODktMS4zMDQgMS44OC0yLjMyLjk5OS0xLjAxNiAyLjEzMy0yLjIwMSAzLjQyOS0zLjUzOS43NDUtLjc2MiAxLjMyLTEuNzE5IDEuNzQ0LTIuODc5LjQyMy0xLjE1MS42MDEtMi4yMDEuNTMzLTMuMTVhOC4zNyA4LjM3IDAgMCAxLTIuMDA2IDEuMjJjLTMuNTA1IDEuMjUzLTYuMDQ1IDMuMDczLTcuNjEyIDUuNDUyLS4xMTguMTUzLS40OS44MjItMS4xMTcgMi4wMTUtLjMzLjYyNy0uNjE4IDEuMDU5LS44NDcgMS4yODctLjMxMy4zMTQtLjc3LjQ5MS0xLjM2My41MjUtLjkyMy4wNDMtMS42NDMtLjM5OC0yLjE2LTEuMzQ2LS42OTMuMjAzLTEuMzEyLjI4OC0xLjg2Mi4yNTQtLjkyMy0uMzQ3LTEuNTkyLS43Mi0yLjAwNi0xLjExNy0uODQ3LS44NDctMS4zODktMS42ODUtMS42NTEtMi41MzJhOS40MyA5LjQzIDAgMCAxLS4zODEtMi43MjZjMC0xLjM4OS44NTUtMy4yMjYgMi41ODItNS41MTIgMi4wMTUtMi42MjUgMy4wOS00LjYzMSAzLjIxNy02LjAwMyAwLS41OTMuMDYtMS4yNjEuMTc4LTIuMDA3YTQuMTk4IDQuMTk4IDAgMCAxIC42MTgtMS40OWMuMjItLjMzLjM2NC0uNTU4LjQzMi0uNjc3LjA3Ni0uMTI3LjIxMi0uMzEzLjQxNS0uNTU5LjE0NC0uMjAzLjI3LS4zNTUuMzcyLS40NTcuMDkzLS4xMS4yMi0uMjU0LjM3My0uNDQuMTc4LS4yMTIuNDA2LS40NTcuNjk0LS43NDVhMTguMDYgMTguMDYgMCAwIDEtMS4wNjctNy40NmMzLjI4NSAxLjE2OSA2LjA1NCAzLjAxNSA4LjI4IDUuNTMuNTUxLTEuODcyIDEuNjI2LTMuMzg3IDMuMjI2LTQuNTM5IDEuMzIxLjkyMyAyLjM3MSAyLjE1IDMuMTUgMy42NjZ6IiBmaWxsPSIjMWYxYTE3Ii8+PHBhdGggZD0iTTE1LjY4OCAxNy43ODZsLjU0Mi0uMjhjLjUtLjE5NC42NTItLjU1OS40NzQtMS4wOTItLjE5NS0uNDkxLS41NzYtLjY2LTEuMTQzLS40OTEtMS45NDcuNzExLTMuMjk0IDIuMDE1LTQuMDM5IDMuOTItLjExOC41NDIuMDc2LjkxNC41OTMgMS4xMTguNTE2LjE2Ljg2NC0uMDE3IDEuMDQxLS41NS4xMzYtLjI4LjIyOS0uNDY2LjI5Ny0uNTQzLjE4Ni4xNDQuNDIzLjI0Ni43Mi4yOTcgMS4wMDcuMTYgMS42LS4yOCAxLjc2LTEuMzM4YTEuNDk4IDEuNDk4IDAgMCAwLS4yNDUtMS4wNDF6TTExLjU3MyAzNC41NWMuMDYtLjE1My4xNy0uMzczLjMyMi0uNjcuMjgtLjY5My40MTUtMS4xMDguNDE1LTEuMjQ0LS4wMjYtLjQ1Ny0uMjcxLS42OTQtLjcyLS42OTQtLjMzIDAtLjcxMS40NzQtMS4xNiAxLjQxNGEuOTcuOTcgMCAwIDEtLjI5Ni4zNDdjLS40NDkuNDY2LS4zODEuODU1LjE5NCAxLjE2OC41MzQuMzE0Ljk0LjIxMiAxLjI0NS0uMzIxem0xNC42My05LjIwNGMxLjE2LTEuNTI0IDEuNzI4LTMuMjE3IDEuNzEtNS4wOC0uMDY3LS41NS0uMzgtLjgyLS45NC0uODItLjc2MSAwLTEuMDU3LjI3OS0uODk3LjgzNy4wNTEuOTE1LS4wMzMgMS42NjgtLjI3IDIuMjYxLS4zODIuOTQtLjgwNSAxLjY0My0xLjI2MiAyLjEwOC0uMjU0LjUtLjEwMi44NjQuNDQ5IDEuMDkyLjUyNS4yNDYuOTMxLjExOSAxLjIxLS4zOTh6TTE5LjcyNiAxMy4yNGE2Ljc5OCA2Ljc5OCAwIDAgMSAuMDUxLTEuOTNjLS45OS4xOTQtMS45MjIuNjYtMi44MDIgMS4zODgtLjUyNS4yOC0uNjUyLjY3LS4zNzMgMS4xNjkuMjguNTA4LjY3LjU5MiAxLjE2OS4yNDUuMzQ3LS4xODYuNjY5LS4zNTUuOTU2LS41MDguMjg4LS4xNi42MTgtLjI4IDEtLjM2NHptMjMuMjUgMzEuNDU0Yy0uMDE3IDAgMC0uNDQ5LjA0Mi0xLjM0Ni4xMzEtMy4xMDguMDk2LTYuMjIxLjA3Ni05LjMzYTI2LjgzNyAyNi44MzcgMCAwIDAtLjg4OS02LjYxM2MtLjg0LTMuMzEtMi4xMjQtNi40ODUtNC4wNzItOS4yOTctMi42MzQtMy44NDUtNi44MTQtNi4wMzMtMTEuMjg2LTYuOTc2LjEyNi43NjYuMDMzIDEuNTQuMDc2IDIuMzExYTI1LjgyIDI1LjgyIDAgMCAxIDQuNTM4IDIuMDMyYzQuMjQxIDIuNTU1IDYuNDE0IDcuMjc2IDcuMTk3IDExLjkzIDEuMjcyIDYuMTU0LjQ1MyAxMS41NTcuODEzIDE3LjI4OXpNOS40MzkgMzAuMTM5Yy40NzUtLjM0LjUyNS0uNzI5LjE0NC0xLjE5NC0uMzk4LS4zODEtLjgzLS40MTUtMS4zMTItLjEwMi0xLjAwNy42Ni0xLjU1IDEuNTMzLTEuNjE3IDIuNjA4LjAxNy41NDIuMzQ3LjgwNC45NzQuNzcuNTkyLS4wNS44OC0uMzU1Ljg2My0uOTIyLjEzNi0uNTI1LjQ0OS0uOTE1Ljk0OC0xLjE2eiIgZmlsbD0idXJsKCNhKSIvPjwvc3ZnPg==')} +.is2d .bishop.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjA5NCIgeDI9Ijc3LjY2OSIgeTE9IjM3LjEwMSIgeTI9IjM3LjQ2OSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Ik0yNSA0Mi4xNjJjLS4yMjkuOTQtLjUxNiAxLjU5Mi0uODQ3IDEuOTU2LS4zMy4zNjQtLjc2Mi43NDUtMS4zMTIgMS4xNDMtLjU5My40MTUtMS4yOTUuNzYyLTIuMTA4IDEuMDUtLjgxMy4yODgtMS43MS4zNjQtMi43MDEuMjExbC02Ljk2OC0uOTY1YTIuODU4IDIuODU4IDAgMCAwLS43NjIgMGMtLjIyLjAzNC0uNDMyLjA1MS0uNjM1LjA1MS0uMzQ3IDAtLjc4Ny4wNzYtMS4zMi4yMzctLjU0My4xNTMtLjk1OC4zODEtMS4yNTQuNjc3bC0yLjQwNS0zLjk0NWMuMjk3LS4zMy41Ni0uNTU5Ljc4OC0uNjk0LjIzNy0uMTI3LjUwOC0uMjcxLjgyMS0uNDE1YTkuMTc5IDkuMTc5IDAgMCAxIDMuMDczLS44MjFjLjQ2Ni0uMDM0LjkyMy0uMDQzIDEuMzY0LS4wMjZhOS44IDkuOCAwIDAgMCAxLjM5Ny0uMDVjLjg4OS4xNTIgMS43ODYuMjg3IDIuNjg0LjQwNi45MDUuMTI3IDEuODExLjI1NCAyLjcxNy4zOS45OTEgMCAxLjY2LS4xMDIgMi4wMDctLjI5Ny4xODYtLjEwMi40NzQtLjI4OC44NzItLjU1LjM5OC0uMjYzLjc5Ni0uNjUyIDEuMTk0LTEuMTY5LS44OC0uMDkzLTEuNzctLjI2Mi0yLjY4NC0uNTA4YTI0LjA5NCAyNC4wOTQgMCAwIDEtMi40MDUtLjc1M2wyLjU4My02LjQwMWMtMS4yOTYtLjc0NS0yLjE5My0xLjMzOC0yLjcxLTEuNzk1YTUuMyA1LjMgMCAwIDEtMS4yMS0xLjU3NWMtLjQzMi0uNzYyLS43MTItMS40OTgtLjgzLTIuMjFhOS4zNDEgOS4zNDEgMCAwIDEtLjE2LTEuOTEzYy4wMTYtLjk5LjI0NS0yLjA4My43MDItMy4yODUuNDU3LTEuMTk0IDEuMzEyLTIuMjcgMi41NjUtMy4yMDlhNzkuMDkxIDc5LjA5MSAwIDAgMCAzLjA1Ny0yLjQ1NSAyNy43NDYgMjcuNzQ2IDAgMCAwIDIuOTQ2LTIuOTU1Yy0xLjIyLS42MjctMS44MjktMS42MjYtMS44MjktMi45OTcgMC0uOTMyLjMyMi0xLjcyLjk3NC0yLjM4OC42NTItLjY2IDEuNDU2LS45OSAyLjM5Ni0uOTkuOTIzIDAgMS43MTkuMzMgMi4zOC45OS42Ni42NjkuOTkgMS40NTYuOTkgMi4zODggMCAxLjM1NC0uNjEgMi4zNTMtMS44MyAyLjk5N2EyNi43OTYgMjYuNzk2IDAgMCAwIDIuOTE0IDIuOTU1IDU2Ljc0IDU2Ljc0IDAgMCAwIDMuMDkgMi40NTVjMS4yMzYuOTQgMi4wODMgMi4wMTUgMi41MjMgMy4yMDkuNDQ5IDEuMjAyLjY5NCAyLjI5NC43MiAzLjI4NSAwIC41NjctLjA1MSAxLjIwMi0uMTcgMS45MTNzLS4zOCAxLjQ0OC0uNzk2IDIuMjFhNi4wODQgNi4wODQgMCAwIDEtMS4yNTMgMS41NzVjLS41LjQ1Ny0xLjM4OCAxLjA1LTIuNjY3IDEuNzk1bDIuNTgzIDYuNGMtLjcyOS4yNjMtMS41NS41MTctMi40NTYuNzU0LS45MTQuMjQ2LTEuNzg2LjQxNS0yLjYzMy41MDguMzgxLjUxNy43Ny45MDYgMS4xNjggMS4xNjkuMzk4LjI2Mi42OTUuNDQ4Ljg5OC41NS4zNDcuMTk1IDEuMDE2LjI5NiAyLjAwNy4yOTZhMjYzLjM1IDI2My4zNSAwIDAgMSAyLjY5Mi0uMzkgODEuMTMgODEuMTMgMCAwIDAgMi43MTgtLjQwNmMuNDQuMDUxLjg4OS4wNjggMS4zNDYuMDUxYTEzLjEyIDEzLjEyIDAgMCAxIDEuNDA1LjAyNiA5LjYyNyA5LjYyNyAwIDAgMSAzLjA3NC44MmMuMjk2LjE0NS41NjcuMjg5LjgwNC40MTYuMjQ2LjEzNS41MDguMzY0LjgwNC42OTRsLTIuNDMgMy45NDVjLS4yOTYtLjI5Ni0uNzEtLjUyNC0xLjI1My0uNjc3LS41MzMtLjE2LS45NjUtLjIzNy0xLjI5NS0uMjM3LS4yMiAwLS40NC0uMDE3LS42Ni0uMDVhMi43OTQgMi43OTQgMCAwIDAtLjc1NCAwbC02Ljk1Ljk2NGMtLjk5Mi4xNTMtMS45MTQuMDg1LTIuNzYxLS4xOTQtLjg1NS0uMjgtMS41NTgtLjY1Mi0yLjEtMS4xMTgtLjU0Mi0uNDQ5LS45ODItLjgzLTEuMzA0LTEuMTUxLS4zMjEtLjMyMi0uNTkyLS45NTctLjgwNC0xLjg5N3oiIGZpbGw9IiMxZjFhMTciLz48cGF0aCBkPSJNMjQuMDg2IDIzLjcwNXYyLjEwOGMwIC42MS4zMDQuOTE0LjkxNC45MTRzLjkxNC0uMzA0LjkxNC0uOTE0di0yLjEzNGgyLjIzNmMuNTc1IDAgLjg3Mi0uMjk2Ljg3Mi0uODk3IDAtLjU5My0uMjk3LS44ODktLjg3Mi0uODg5aC0yLjIzNnYtMi4yMzVjMC0uNjEtLjMwNC0uOTE1LS45MTQtLjkxNXMtLjkxNC4zMDUtLjkxNC45MTV2Mi4yMzVIMjEuOWMtLjU4NCAwLS44NzIuMjk2LS44NzIuODg5IDAgLjYwMS4yODguODk3Ljg3Mi44OTd6bTcuNTEgMTMuNzQxbC0xLjA0Mi0yLjUzMWMtMS42ODUtLjM2NC0zLjUzOS0uNTQyLTUuNTU0LS41NDItMS45OTggMC0zLjgzNS4xNzgtNS41MDMuNTQybC0xLjA0MiAyLjUwNmMyLjA1LS41MTcgNC4yMzQtLjc3IDYuNTQ1LS43NyAyLjI4NiAwIDQuNDc5LjI2MiA2LjU5Ni43OTV6bS0yLjA4My01LjExNGwtLjcyLTEuNzM1di0uNjdhMjcuMDMgMjcuMDMgMCAwIDAtMy43OTMtLjI3IDI3LjM1IDI3LjM1IDAgMCAwLTMuNzY4LjI3bC0uMDI1LjY3LS42NjkgMS43MzVBMjUuODUgMjUuODUgMCAwIDEgMjUgMzEuOTZjMS41OTIgMCAzLjA5LjEyNyA0LjUxMy4zNzJ6bS0uODY0IDkuMzgxYy0uNjYtLjUtMS4zMy0xLjI4Ny0xLjk5LTIuMzYyaC0uNzg3YzAgLjgxMy4xODYgMS42LjU2NyAyLjM2MnptLTUuMTE0IDBjLjM4MS0uODEyLjU3Ni0xLjYuNTc2LTIuMzYyaC0uNzk2Yy0uNjQzIDEuMDU5LTEuMzEyIDEuODQ2LTIuMDE1IDIuMzYyeiIgZmlsbD0idXJsKCNhKSIvPjwvc3ZnPg==')} +.is2d .rook.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjE5MiIgeDI9Ijc3LjczNiIgeTE9IjM3LjU1MiIgeTI9IjM3LjQyOSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Ik0yOC40MDggOS4yMmg0LjIxNlY1LjgyNWg2Ljc5OXY5LjI5NmwtNS41MDMgNC4yNDJ2MTEuODYybDQuMjE2IDQuMjE2djUuMDhoMy43OTN2NS45MjdIOC4wNzFWNDAuNTJoMy43OTN2LTUuMDhsNC4yNDItNC4yMTZWMTkuMzYzbC01LjUwNC00LjI0MlY1LjgyNWg2Ljc3NFY5LjIyaDQuMjQyVjUuODI1aDYuNzl6IiBmaWxsPSIjMWYxYTE3Ii8+PHBhdGggZD0iTTI1LjAxMyAzNS4wNDNoLTEwLjI3TDEzLjYgMzYuMTF2MS40NGgyMi44MjZ2LTEuNDRsLTEuMTQzLTEuMDY3ek0xMy42IDQwLjEyM3YyLjUzMmgyMi44MjZ2LTIuNTMyek0yNS4wMTMgMTMuMDRoLTEyLjd2MS4xNDJsMS44MTIgMS4zNjRoMjEuODAxbDEuNzYxLTEuMzY0VjEzLjA0em0wIDQuMTloLTguNjc5bDEuNDgyIDEuMTY5djEuNDE0aDE0LjM5M3YtMS40MTRsMS40ODItMS4xNjh6bTAgMTMuNTQ3aC03LjE5N3YxLjE0M2wtMS40ODIgMS40NGgxNy4zNTdsLTEuNDgyLTEuNDR2LTEuMTQzeiIgZmlsbD0idXJsKCNhKSIvPjwvc3ZnPg==')} +.is2d .queen.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjI1MyIgeDI9Ijc3Ljc2NCIgeTE9IjM3LjIyNCIgeTI9IjM3LjM2Ij48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNmZmYiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iMCIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZD0iTTI0Ljk1IDEwLjc1MmMtLjk0IDAtMS43NDUtLjMzLTIuMzk3LS45OS0uNjUyLS42Ni0uOTc0LTEuNDY1LS45NzQtMi40MDUgMC0uOTMxLjMyMi0xLjcyNy45NzQtMi4zODcuNjUyLS42NiAxLjQ1Ni0uOTkgMi4zOTYtLjk5LjkyMyAwIDEuNzI3LjMzIDIuMzk2Ljk5YTMuMjMgMy4yMyAwIDAgMSAxIDIuMzg3YzAgLjk0LS4zMyAxLjc0NC0xIDIuNDA1LS42NjkuNjYtMS40NzMuOTktMi4zOTYuOTl6bTE1LjI4MSAzMy4xOWMtLjgxMi43MS0yLjYzMyAxLjMwNC01LjQ2IDEuNzg2LTIuODI4LjQ3NC02LjA4OC43Mi05Ljc3MS43Mi0zLjc1IDAtNy4wNTMtLjI1NC05Ljg5OC0uNzQ1LTIuODQ0LS41LTQuNjQtMS4xMTgtNS4zODQtMS44NjNsMS41NjYtNS45NTItLjY5NC0zLjg5NUw4LjQwNSAzMC4yIDYuMjk3IDE0Ljc3NGwxLjIxLS40NzQgNi44IDExLjQ1NS4xNTItMTMuNjQgMS42ODUtLjI5NiA1LjE4MiAxMy43MTYgMi43NzYtMTQuNzU3aDEuNzJsMi43NzYgMTQuNzA2TDMzLjczIDExLjgybDEuNzEuMjk2LjE1MyAxMy42NCA2LjgyNC0xMS40OCAxLjE2LjU0MS0yLjA1OCAxNS4zNTktMi4yMSAzLjc5My0uNjk0IDMuOTQ1ek0xNC41MzUgMTEuOTg5Yy0uOTQ4IDAtMS43NTItLjMyMi0yLjQxMy0uOTc0LS42Ni0uNjUyLS45OS0xLjQ1Ni0uOTktMi4zOTYgMC0uOTIzLjMzLTEuNzE5Ljk5LTIuMzhzMS40NjUtLjk5IDIuNDEzLS45OWMuOTIzIDAgMS43MTkuMzMgMi4zOC45OXMuOTkgMS40NTcuOTkgMi4zOGMwIC45NC0uMzMgMS43NDQtLjk5IDIuMzk2YTMuMjY2IDMuMjY2IDAgMCAxLTIuMzguOTc0em0yMC44MjggMGMtLjk0IDAtMS43MzYtLjMyMi0yLjM4Ny0uOTc0LS42NTItLjY1Mi0uOTgyLTEuNDU2LS45ODItMi4zOTYgMC0uOTIzLjMzLTEuNzE5Ljk4Mi0yLjM4czEuNDQ3LS45OSAyLjM4Ny0uOTljLjk0OCAwIDEuNzUzLjMzIDIuNDEzLjk5cy45OSAxLjQ1Ny45OSAyLjM4YzAgLjk0LS4zMyAxLjc0NC0uOTkgMi4zOTYtLjY2LjY1Mi0xLjQ2NS45NzQtMi40MTMuOTc0ek01LjQgMTQuNzIzYy0uOTQgMC0xLjczNi0uMzMtMi4zODgtLjk4Mi0uNjUyLS42NTItLjk4Mi0xLjQ0OC0uOTgyLTIuMzk2IDAtLjkyMy4zMy0xLjcxOS45ODItMi4zODhDMy42NjQgOC4yOCA0LjQ2IDcuOTUgNS40IDcuOTVjLjk0OCAwIDEuNzQ0LjMzIDIuNDEzIDEuMDA3LjY2LjY3Ljk5IDEuNDY1Ljk5IDIuMzg4IDAgLjk0OC0uMzMgMS43NDQtLjk5IDIuMzk2YTMuMzIzIDMuMzIzIDAgMCAxLTIuNDEzLjk4MnptMzkuMTQxIDBjLS45NCAwLTEuNzQ0LS4zMy0yLjQwNC0uOTgyLS42Ni0uNjUyLS45OTEtMS40NDgtLjk5MS0yLjM5NiAwLS45MjMuMzMtMS43MTkuOTktMi4zODguNjYtLjY3NyAxLjQ2NS0xLjAwNyAyLjQwNS0xLjAwNy45MzEgMCAxLjcyNy4zMyAyLjM4OCAxLjAwNy42Ni42Ny45OSAxLjQ2NS45OSAyLjM4OCAwIC45NDgtLjMzIDEuNzQ0LS45OSAyLjM5NmEzLjI4IDMuMjggMCAwIDEtMi4zODguOTgyeiIgZmlsbD0iIzFmMWExNyIvPjxwYXRoIGQ9Ik0zNy4yIDM1LjczYy0zLjA0LS44NC03LjA5NS0xLjI2Mi0xMi4xNS0xLjI2Mi01LjA5NiAwLTkuMTk0LjQzMS0xMi4zMDEgMS4yODZsLjM3MiAyLjUwN2MzLjEyNC0uODEzIDcuMDk1LTEuMjIgMTEuOTMtMS4yMiA0LjgwOSAwIDguNzI5LjM5OCAxMS43NTIgMS4xOTR6bTEuNzM2LTQuNDM3Yy0xLjM3Mi0uNS0zLjMwMi0uOTA2LTUuNzkxLTEuMjI4LTIuNDktLjMyMi01LjIzMy0uNDgzLTguMjQ3LS40ODMtMi45NDYgMC01LjYzOC4xNTMtOC4wODUuNDU4LTIuNDQ3LjMwNC00LjM3OC43MDItNS43ODMgMS4yMDJsMS4yNDUgMi4yNTJjMS4zODgtLjQwNiAzLjE5MS0uNzAzIDUuNDEtLjg5IDIuMjEtLjE3NyA0LjYzMS0uMjcgNy4yNjQtLjI3czUuMDYzLjA5MyA3LjI5LjI3YzIuMjM1LjE4NyA0LjA0Ny40OTIgNS40MzYuOTE1em0tMS4wOTIgMTEuODUzbC0uNzM3LTIuOTNjLTMuMjI2LS43MzYtNy4yODEtMS4xMDktMTIuMTU4LTEuMTA5LTQuODI2IDAtOC44NjQuMzczLTEyLjEwNyAxLjExbC0uNzg4IDIuOTU0YzMuMTQyLS45NTYgNy40NDMtMS40NCAxMi45Mi0xLjQ0IDIuNjI1IDAgNS4wNzIuMTM2IDcuMzE2LjM5OSAyLjI1Mi4yNjIgNC4xMDYuNjAxIDUuNTU0IDEuMDE2eiIgZmlsbD0idXJsKCNhKSIvPjwvc3ZnPg==')} +.is2d .king.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjEzIiB4Mj0iNzcuNzY0IiB5MT0iMzcuMjI0IiB5Mj0iMzcuNDY5Ij48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNmZmYiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iMCIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZD0iTTI1LjgyMSAxMi4wMjJoLTEuNzZ2LTMuMjVoLTIuMDY3Yy0uNTU4IDAtLjgzOC0uMjcyLS44MzgtLjgyMnYtLjAyNWMwLS41NDIuMjgtLjgxMy44MzgtLjgxM2gyLjA2NlY1LjAwNGMwLS41ODUuMjk3LS44NzIuODktLjg3Mi41NzUgMCAuODcxLjI4Ny44NzEuODcydjIuMTA4aDIuMTM0Yy41NDIgMCAuODEzLjI3LjgxMy44MTN2LjAyNWMwIC41NS0uMjcxLjgyMS0uODEzLjgyMWwtMi4xMTcuMDI2ek0xMS4wMyAzNy43NDRsLS44MTMtNC42NGMtLjAxNyAwLS4wNDItLjAzMy0uMDc2LS4xMDEtLjA4NS0uMTE5LS4zMjItLjI3MS0uNzExLS40NTctLjM4MS0uMTk1LS44MzgtLjUxNy0xLjM0Ni0uOTgyYTQxLjk5IDQxLjk5IDAgMCAxLTEuNzAyLTEuNDkgOC41MDkgOC41MDkgMCAwIDEtMS4xLTEuMjM3QzQuMjczIDI3LjQ1IDMuNzA1IDI1Ljc3MiAzLjU5NSAyMy44Yy0uMTctMS44OTcuNjAxLTMuNzk0IDIuMzAzLTUuNjgyIDEuNzE5LTEuODggNC4wNDctMi43NjggNi45NjgtMi42NSAxLjA5Mi4wNjggMi4zOC4zMyAzLjg0NC43OTYuNDgzLjE5NS45NzQuMzkgMS40ODIuNTc2bDEuNDk4LjU4NGMuMjYzLjEzNi41LjI3MS42OTUuMzk4YTQuMzggNC4zOCAwIDAgMS0uMTI3LTEuMDQxYzAtMS4yODcuNDU3LTIuMzg4IDEuMzgtMy4zMDIuOTE0LS45MDYgMi4wMjMtMS4zNzIgMy4zMS0xLjM4OSAxLjI4NyAwIDIuMzg4LjQ2NiAzLjMwMiAxLjM4LjkwNi45MTUgMS4zNjMgMi4wMTUgMS4zNjMgMy4yODUgMCAuMjYzLS4wMzQuNjEtLjEwMSAxLjA0Mi4yMjgtLjE0NC40NTctLjI3MS42NjktLjM3My43NjItLjMzIDEuNzYtLjcyIDMuMDA1LTEuMTYgMS40MjMtLjQ4MiAyLjcwMS0uNzUzIDMuODQ0LS44MjEgMi45MjEtLjEzNiA1LjI0MS43NTMgNi45NDMgMi42NSAxLjY2OCAxLjg4OCAyLjQ0NyAzLjc4NSAyLjMyOCA1LjY4MS0uMTI3IDEuOTczLS43MDMgMy42NS0xLjcxIDUuMDM4LS4zMy40NDktLjcwMy44NjMtMS4xMTggMS4yNTNhNDAuNSA0MC41IDAgMCAxLTEuNjYgMS40NzNjLS41NDEuNDY2LTEuMDA3Ljc5Ni0xLjM4OC45ODItLjM4LjE4Ni0uNi4zNDctLjY2OS40NTdhLjI5NC4yOTQgMCAwIDEtLjA1LjA3N2MtLjAxNy4wMTctLjAyNi4wMzQtLjAyNi4wNWwtLjc5NiA0LjY2NiAxLjY0MyA2LjEyMWMtLjgzLjc0NS0yLjY4NCAxLjM1NS01LjU1NCAxLjgzNy0yLjg3OS40ODMtNi4yMDYuNzItOS45NzQuNzItMy44MzUgMC03LjIxNC0uMjU0LTEwLjExOC0uNzU0LTIuOTEyLS41MDgtNC43NDEtMS4xNDMtNS40ODYtMS44OTZ6IiBmaWxsPSIjMWYxYTE3Ii8+PHBhdGggZD0iTTI0Ljk1IDIwLjY3NWEyLjI5NSAyLjI5NSAwIDAgMC0uMTI4LS40MjMgNS42MDYgNS42MDYgMCAwIDAtLjI0NS0uNzJjLS4wNTEtLjExLS4xMTktLjI1NC0uMTk1LS40MzFhOS4wMjggOS4wMjggMCAwIDEtLjI1NC0uNTZjLS4wNS0uMTE4LS4xMS0uMjctLjE4Ni0uNDU2LS4wNjgtLjE5NS0uMTM2LS4zNzMtLjE4Ny0uNTM0YTEuNzM1IDEuNzM1IDAgMCAxLS4wNjctLjQ3NGMwLS44NzIuNDE1LTEuMzEyIDEuMjYxLTEuMzEyLjg4IDAgMS4zMTMuNDMxIDEuMzEzIDEuMjg3IDAgLjIyLS4wMzQuMzcyLS4wOTQuNDc0LS4yMzcuNjI2LS4zNTUuOTY1LS4zNzIgMS4wMTYtLjI1NC41LS40MDYuODIxLS40NzQuOTY1LS4xMTkuMjctLjE5NS41MDgtLjIyLjcyLS4wNTEuMTAxLS4wODUuMTg2LS4xMDIuMjYycy0uMDM0LjEzNi0uMDUuMTg2em0tMi43NzggOC41NmMtMi4wNjYuMDM0LTMuOTU0LjEzNi01LjY3My4zMjItMS43MS4xNzgtMy4wMy40NC0zLjk3OS43N2ExOC45NzMgMTguOTczIDAgMCAwLTEuNzE5LTEuODU0IDMzLjAwNyAzMy4wMDcgMCAwIDEtMS43MjctMS43NDRjLS44My0uODQ3LTEuMjM2LTEuNzctMS4yMzYtMi43NzcgMC0xLjI0NS4yMDMtMi4xNS42MTgtMi43MjYuNDQtLjY3IDEuMTM1LTEuMTYgMi4wNTgtMS40ODJhOC40ODYgOC40ODYgMCAwIDEgMi44MDItLjQ4M2MxLjE5NCAwIDIuMzI4LjI2MyAzLjQyLjc5NiAxLjA3Ni41NiAxLjc4NyAxLjAwOCAyLjEzNCAxLjMzOCAxLjEyNiAxLjE0MyAyLjAwNyAyLjM4IDIuNjMzIDMuNzE3LjIxMi41LjM3MyAxLjE5NC40ODMgMi4wNzQuMTEuODkuMTcgMS41NjcuMTg2IDIuMDV6bTIuNzc3LTQuMzE4Yy4xMTktLjQ2Ni4yMTItLjc4Ny4yOTYtLjk2NS4xNy0uNjQzLjM1Ni0xLjE5NC41NzYtMS42NDMuMDkzLS4yNzkuMjM3LS42LjQzMi0uOTczLjE4Ni0uMzczLjM5LS44MDUuNjEtMS4yNzkuMTI3LS4yOC4yNy0uNjI2LjQxNS0xLjAzMy4xNTItLjQwNi4zMDQtLjgwNC40NDgtMS4yMDIuMTM2LS4zMy4yMDMtLjY4Ni4yMDMtMS4wNjcgMC0uODEzLS4yOTYtMS40OTgtLjg3Mi0yLjA2Ni0uNTc1LS41NzUtMS4yNzgtLjg2My0yLjEwOC0uODYzLTEuOTY0IDAtMi45NTUuOTktMi45NTUgMi45NTUgMCAuMzguMDY4LjczNi4yMDMgMS4wNjYuMzY1IDEuMDc2LjY0NCAxLjgyLjgzOSAyLjIzNi4yMi40NzQuNDE1LjkwNi42IDEuMjc4LjE3OS4zNzMuMzQuNjk0LjQ2Ni45NzQuMjIuNTUuMzk4IDEuMDkyLjU1IDEuNjQyLjAzNS4wOTMuMTI4LjQxNS4yOTcuOTR6bS0uODg5IDYuMjIzYzAtLjY2LS4wMTctMS41NzUtLjA1LTIuNzM1LS4wMzQtMS4xNjgtLjE2MS0yLjE0Mi0uMzczLTIuOTItLjY3Ny0yLjIxLTEuNzAyLTMuOTk3LTMuMDgyLTUuMzUxLS43MTEtLjY5NS0xLjc5NS0xLjM0Ny0zLjI2OC0xLjk0LTEuNjg1LS42Ni0zLjI4NS0uOTktNC43OTItLjk5LTIuNjA4IDAtNC41NDcuOTMxLTUuOCAyLjgwMy0uNzExLjk5LTEuMDY3IDIuMjM1LTEuMDY3IDMuNzE2IDAgMS42MjYuMzk4IDIuOTU1IDEuMTg2IDMuOTk3LjQxNS41OTIgMS4yMSAxLjMyOSAyLjM4NyAyLjIxIDEuMTY5Ljg3MiAyLjE2OCAxLjY4NCAyLjk3MiAyLjQzIDEuNDQtLjMxNCAzLjA2NS0uNTg1IDQuODc3LS44MjIgMS44MTItLjIyOSA0LjE0OS0uMzY0IDcuMDEtLjM5OHptMTMuNzg0IDExLjczNWwtLjczNy0yLjkzYy0zLjIyNS0uNzM2LTcuMjgxLTEuMTA5LTEyLjE1OC0xLjEwOS00LjgyNiAwLTguODY0LjM3My0xMi4xMDcgMS4xMWwtLjc4NyAyLjk1NGMzLjE0LS45NTYgNy40NDItMS40MzkgMTIuOTItMS40MzkgMi42MjQgMCA1LjA3MS4xMzYgNy4zMTUuMzk4IDIuMjUyLjI2MiA0LjEwNi42MDEgNS41NTQgMS4wMTZ6bS0uNjQzLTcuNDE3Yy0zLjA0LS44MzgtNy4wOTYtMS4yNjEtMTIuMTUtMS4yNjEtNS4wOTcgMC05LjE5NS40MzEtMTIuMzAyIDEuMjg3bC4zNzIgMi41MDZjMy4xMjUtLjgxMyA3LjA5NS0xLjIyIDExLjkzLTEuMjIgNC44MDkgMCA4LjcyOS4zOTggMTEuNzUyIDEuMTk0em0tMTEuMzYzLTQuMjkyYzIuODQ1LjA1IDUuMTgyLjE5NCA3LjAwMi40MjMgMS44MTIuMjI5IDMuNDU1LjUwOCA0LjkxLjgyMS45MDctLjg5NyAxLjkxNC0xLjc0NCAzLjAyMy0yLjU1N3MxLjg4OC0xLjUwNyAyLjMzNy0yLjA4M2MuNzg4LTEuMDc1IDEuMTg2LTIuNDEzIDEuMTg2LTQuMDIxIDAtMS40NjUtLjM1Ni0yLjcwMS0xLjA2Ny0zLjY5Mi0xLjI3LTEuODctMy4yMTgtMi44MDItNS44MjUtMi44MDItMS41MjQgMC0zLjEwOC4zMy00Ljc2Ny45OS0xLjUwNy41OTMtMi41OSAxLjIzNy0zLjI3NyAxLjkzLTEuNDA1IDEuMzY0LTIuNDMgMy4xNS0zLjA3MyA1LjM2LS4yNDYuNzYyLS4zODEgMS43MjctLjQwNyAyLjkwNHMtLjA0MiAyLjA4My0uMDQyIDIuNzI3em0xLjgxMi0xLjkzYzAtLjQ4My4wNi0xLjE2LjE2LTIuMDUuMTExLS44OC4yOC0xLjU3NS41MDktMi4wNzQuNjE4LTEuMzM4IDEuNDktMi41NzQgMi42MzMtMy43MTcuMzMtLjMzIDEuMDQyLS43NzkgMi4xMzQtMS4zMzhhNy42NTUgNy42NTUgMCAwIDEgMy40NDYtLjc5NmMuOTMgMCAxLjg0NS4xNjEgMi43NjguNDgzLjkxNS4zMjIgMS42MDkuODEzIDIuMDY2IDEuNDgyLjQxNS41NTkuNjI3IDEuNDY0LjYyNyAyLjcyNiAwIC45OS0uNDA3IDEuOTEzLTEuMjIgMi43NzdhNDAuMzUgNDAuMzUgMCAwIDEtMS43MSAxLjY1MWMtLjYxLjU1LTEuMjAyIDEuMjAyLTEuNzYgMS45NDctLjk1OC0uMzMtMi4yOTUtLjU5Mi00LjAwNi0uNzctMS43MS0uMTg2LTMuNTktLjI4OC01LjY0Ny0uMzIyeiIgZmlsbD0idXJsKCNhKSIvPjwvc3ZnPg==')} diff --git a/public/piece-css/pirouetti.css b/public/piece-css/pirouetti.css new file mode 100644 index 0000000000..2d98ebe5c2 --- /dev/null +++ b/public/piece-css/pirouetti.css @@ -0,0 +1,12 @@ +.is2d .pawn.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJNOTUzIDMyMzloMTkwN3YyMDRIOTUzeiIvPjxwYXRoIGQ9Ik0xMDk5IDMzODZoMTYyMXYxNTNIMTA5OXoiLz48cGF0aCBkPSJNOTUwIDM1MDZoMTkwN3YyMDRIOTUweiIvPjwvZz48cGF0aCBkPSJNMTA5OSAzNDQzaDE2MjF2NjNIMTA5OXoiIGZpbGw9IiNkMWQxZDEiLz48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJNMTY1OSAyMDU5bDI5Ni00IDEgMTI4Mi02MTgtOXoiLz48cGF0aCBkPSJNMjE0MCAyMDU5bC0yNjQtNHYxMjgybDYxNy05eiIvPjxwYXRoIGQ9Ik0xMzU1IDE5MDdoMTExNXYxNThIMTM1NXoiLz48ZWxsaXBzZSBjeD0iMTg5MCIgY3k9IjE1NDkiIHJ4PSI0MTQiIHJ5PSI0MzMiLz48L2c+PGcgZmlsbD0iI2QxZDFkMSI+PHBhdGggZD0iTTE5ODAgMTEyNnMxOTUgMTQ3IDIxOCAzNDljMzYgMzE1LTE2MiA0MTgtNDQ2IDM1MS0xNDMtMzQtMjQ0LTExMC0yMzEtODIgMCAwIDIxIDUxIDU5IDkwIDM3IDM5IDgyIDc1IDgyIDc1aDQ1N3M3NC00MSAxMTQtMTE3YzQwLTc3IDcyLTEzNyA3Mi0yNDRzLTQxLTE5OS02OC0yMzctNTYtNzEtMTA1LTExNGMtNDgtNDQtMTUyLTcxLTE1Mi03MXoiLz48cGF0aCBkPSJNMjA3NCAxOTA3bDY5IDE1OGgzMjZ2LTE1OHptLTUxNiAxNThoNTg1bDM0NiAxMjQyaC0yNTVsLTE2OC0xMDk1eiIvPjxwYXRoIGQ9Ik0yNDY2IDMyMzlsNzAgNDcxaDMyMXYtMjA0aC0xMzd2LTYzaDE0MHYtMjA0eiIvPjwvZz48L3N2Zz4=')} +.is2d .knight.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJNODI4IDEzNzhjLTE4MyAxNjktMTMyIDE1NS02MCAyODZzMTk1IDIyNyA1MDMgNzcgMzkwLTEzMyA1MTctMTAzIDE1OSA5MSAxNjcgMTU3LTE4NiAyMjctNDAwIDQzM2MtMjE0IDIwNS00MDIgMjQzLTM3MyA2NzEgMzAgNDI4IDE5IDUyNS00MiA1OTJzMTA3NCAyNjMgMTIyMSAxOTZjMTQ3LTY4IDU0My01NSA0NjUtNDYwLTc4LTQwNi0yMDgtOTAwLTEwLTEyMzhzMzk4LTEwNDItNTI3LTE0MjMtNTU4IDM1LTY0OCA4M2MtOTAgNDctMTIxIDU3LTE3NSA4My05OCA0Ny00NjMgNDg1LTYzOSA2NDd6Ii8+PHBhdGggZD0iTTg5MCAzMjM5aDIyMTd2MjA0SDg5MHoiLz48cGF0aCBkPSJNMTA1OSAzMzg2aDE4ODV2MTUzSDEwNTl6Ii8+PHBhdGggZD0iTTg4NiAzNTA2aDIyMTd2MjA0SDg4NnoiLz48L2c+PGcgZmlsbD0iI2QxZDFkMSI+PHBhdGggZD0iTTE2MTUgMTY0NHM4NS0xMjQgMjYyLTEzMWMxNzYtNyA3NS0zMzEgNzUtMzMxczIyNyAyOTMgMjI3IDQ0NC0yMzkgMjE3LTIzOSAyMTctMzAtMTgyLTMyNC0yMDB6bTEwMDQtOTAwczQyNSAyMzggMjIxIDg0Mi01NjAgOTE1LTQ5OCAxMjI2IDkgMzY0IDMxIDM5MSA5MyAyNyAxOTUtNCA4NCA0NCA5MyA4OWM5IDQ0IDcyIDQyMSA3MiA0MjFoMzY5di0yMDRoLTE1OXYtNjNoMTYzdi0yMDRoLTI3N3MtOTUtNDQ4LTExNi03MjggNTgtNDU0IDE3MC02NTNjMTExLTIwMCAyMzEtNzc3LTI2NS0xMTEzeiIvPjxwYXRoIGQ9Ik0xMDYwIDM0NDNoMTg4NXY2M0gxMDYweiIvPjwvZz48L3N2Zz4=')} +.is2d .bishop.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJNMTg3MCA0ODJzNjIxIDI2OSA0NTggODgzLTU3MCAyNjAtNTcwIDI2MGwxMTMtMTE0MnpNNzk4IDMyMzhoMjIxN3YyMDRINzk4eiIvPjxwYXRoIGQ9Ik05NjcgMzM4NWgxODg1djE1M0g5Njd6Ii8+PHBhdGggZD0iTTc5NCAzNTA1aDIyMTd2MjA0SDc5NHptNzg2LTE5NTJoNTk4bDUwMSAxNzA0SDExMjR6Ii8+PHBhdGggZD0iTTEyODYgMTUxMWgxMjAwdjE1MkgxMjg2eiIvPjxwYXRoIGQ9Ik0xODg1IDQ4M3MtNjIzIDI2OS00NTkgODgzIDU3MiAyNjAgNTcyIDI2MEwxODg1IDQ4NHoiLz48ZWxsaXBzZSBjeD0iMTg4MCIgY3k9IjQ0OCIgcng9IjE3NCIgcnk9IjE0MyIvPjwvZz48ZyBmaWxsPSIjZDFkMWQxIj48cGF0aCBkPSJNMTk3MCAzMjVzMzggNTEgMzggMTEzYzAgNjEtMTQgMTE4LTE0IDExOHMxNjItMTE1LTI0LTIzMXpNOTY3IDM0NDJoMTg4NXY2M0g5Njd6TTE5OTQgNTU2czIyMSAxNDQgMzAwIDMzMyA2NiAyNTkgNTAgMzk3LTY4IDIyNC02OCAyMjRoMjA5djE1MmgtMzIxbC0xNy0xNTJzLTItNDItMTItNzdjLTEwLTM2IDkzLTg1IDEwNC0yNDAgMTAtMTU1IDEtMjUzLTUzLTM2OC01My0xMTYtMTk0LTI2OS0xOTQtMjY5eiIvPjxwYXRoIGQ9Ik0xNTQxIDE2NjNoNjY5bDQ2NSAxNTc1aDM0MXYyMDRoLTE2NHY2M2gxNjB2MjA0aC00ODF2LTI2N2wtODQtMjA0LTMxMi0xNDI5eiIvPjwvZz48L3N2Zz4=')} +.is2d .rook.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJNMTI1OSAxNjk0bDEyODMgNCAyMDkgMTU5MC0xNjg4LTIzeiIvPjxwYXRoIGQ9Ik0xMDAyIDE3NDdoMTgwMmwyMTctMTE1MS01MjQgMzF2MjgyaC0zMDdWNjM2aC01NDl2MjczaC0zMjBsLTMtMjcyLTUyMS00MXpNNzkzIDMyMzVoMjIxN3YyMDRINzkzeiIvPjxwYXRoIGQ9Ik05NjIgMzM4MmgxODg1djE1M0g5NjJ6Ii8+PHBhdGggZD0iTTc4OSAzNTAyaDIyMTd2MjA0SDc4OXoiLz48L2c+PGcgZmlsbD0iI2QxZDFkMSI+PHBhdGggZD0iTTI4NTIgNjA2cy0xNDYgOTE5LTE2OCA5ODYtOTQgMTU1LTk0IDE1NWgyMTNsMjE3LTExNTEtMTY5IDEwek0xMzg2IDE3NDdoMTE2MmwxOTUgMTQ4OGgyNjZ2MjA0bC0xNjEtM3Y2M2wxNTcgM3YyMDRoLTMxNnMtMjQtMTcxLTY3LTI2OWMtNDItOTktOTAtNzgtMTM5LTQ0NS00OS0zNjgtMTUzLTEwMjAtMTUzLTEwMjBsLTk0NS0yMjN6Ii8+PHBhdGggZD0iTTk2NCAzNDM2aDE4ODV2NjNIOTY0eiIvPjwvZz48L3N2Zz4=')} +.is2d .queen.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJNMTQ0NSAxNjI2bDg5MiA0IDQxOSAxNjU4LTE2ODgtMjR6Ii8+PHBhdGggZD0iTTc5OCAzMjM1aDIyMTd2MjA0SDc5OHoiLz48cGF0aCBkPSJNOTY3IDMzODJoMTg4NXYxNTNIOTY3eiIvPjxwYXRoIGQ9Ik03OTQgMzUwMWgyMjE3djIwNEg3OTR6Ii8+PC9nPjxwYXRoIGQ9Ik0xNDAxIDE3NDVoOTY1bDM4MyAxNDg5aDI2NnYyMDRoLTE2MXY2MGwxNTcgM3YyMDRoLTMxNnMtMjYtMTQ5LTcxLTI2N2MtNDUtMTE3LTg1LTgwLTEzNS00NDgtNDktMzY4LTI1My0xMTE3LTI1My0xMTE3bC04MzYtMTI5eiIgZmlsbD0iI2QxZDFkMSIvPjxwYXRoIGQ9Ik05NzAgMzQzNmgxODg0djYzSDk3MHoiIGZpbGw9IiNkMWQxZDEiLz48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJNMTA4OCAxNTI2aDE2Mzh2MjIwSDEwODh6Ii8+PHBhdGggZD0iTTEzNTIgMTU2M0w5NDkgNzk4bDQ5NyAyNjAtNDAtNjg0IDQ3OCA1NTcgMzIgNjMyeiIvPjxwYXRoIGQ9Ik0yNDE2IDE1NjNsNDAzLTc2NC00OTggMjU5IDQwLTY4My00NzggNTU2LTE4IDYzMnoiLz48Y2lyY2xlIGN4PSI5NDkiIGN5PSI3OTgiIHI9IjEwMCIvPjxjaXJjbGUgY3g9IjE0MDYiIGN5PSIzNzQiIHI9IjEwMCIvPjxjaXJjbGUgY3g9IjIzNjEiIGN5PSIzNzUiIHI9IjEwMCIvPjwvZz48ZyBmaWxsPSIjZDFkMWQxIj48Y2lyY2xlIGN4PSIyODE5IiBjeT0iNzk5IiByPSIxMDAiLz48cGF0aCBkPSJNMjQyMSAyOTVsLTk3IDE3My0yNDAgMTA1OGgzNTFsMzM3LTYzOS00Mi00Mi00MDkgMjEzIDQzLTU4NHMxODItMzIgNTctMTgwem0tMTYxIDEyMzF2MjE5aDQ2NnYtMjE5eiIvPjwvZz48L3N2Zz4=')} +.is2d .king.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTM0MiAxNjMybDEwOTggOSAzMTYgMTY1My0xNjg4LTI0eiIgZmlsbD0iI2ZlZmVmZSIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Ik03OTggMzI0MWgyMjE3djIwNEg3OTh6Ii8+PHBhdGggZD0iTTk2NyAzMzg3aDE4ODV2MTUzSDk2N3oiLz48cGF0aCBkPSJNNzk0IDM1MDdoMjIxN3YyMDRINzk0eiIvPjwvZz48cGF0aCBkPSJNMTQwMSAxNzUxaDEwNjFsMjg4IDE0ODloMjY2djIwNGwtMTYxLTN2NjNsMTU3IDN2MjA0aC0zMTZzLTI2LTE0OS03MS0yNjdjLTQ1LTExNy04NS04MC0xMzUtNDQ4LTQ5LTM2OC0xNTAtMTEwMS0xNTAtMTEwMWwtOTM5LTE0NXoiIGZpbGw9IiNkMWQxZDEiLz48cGF0aCBkPSJNOTcwIDM0NDJoMTg4NHY2M0g5NzB6IiBmaWxsPSIjZDFkMWQxIi8+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTEwODggMTUzMWgxNjM4djIyMEgxMDg4eiIvPjxwYXRoIGQ9Ik0xMjc4IDE2MTFzLTI0MS0zMjgtMTk5LTU3MmM1MC0yODUgMzgyLTQwOCA4NzUtNDM1IDE0OC04IDk4IDEwMDcgOTggMTAwN3oiLz48cGF0aCBkPSJNMjUxNSAxNjExczI0MS0zMjggMTk5LTU3MmMtNTAtMjg1LTM4Mi00MDgtODc1LTQzNS0xNDgtOC05OCAxMDA3LTk4IDEwMDd6Ii8+PHBhdGggZD0iTTE1NjAgNjU1czI1My02MyAyMjYtMTY5IDExNC0xOSAxMTQtMTlsMTAgMTQ2LTM1MCA0M3oiLz48cGF0aCBkPSJNMjE3MiA2NDdzLTE1NC03NS0xNTktMTYxLTExNC0xOS0xMTQtMTlsLTEwIDE0NyAyODIgMzR6Ii8+PGVsbGlwc2UgY3g9IjE3NTUiIGN5PSIyNzkiIHJ4PSI5MSIgcnk9Ijg5Ii8+PGVsbGlwc2UgY3g9IjE3ODQiIGN5PSI0MTciIHJ4PSI2NCIgcnk9IjYyIi8+PGVsbGlwc2UgY3g9IjIwMzkiIGN5PSIyNzkiIHJ4PSI5MSIgcnk9Ijg5Ii8+PGVsbGlwc2UgY3g9IjIwMTAiIGN5PSI0MTciIHJ4PSI2NCIgcnk9IjYyIi8+PGVsbGlwc2UgY3g9IjE5MDAiIGN5PSIyMDAiIHJ4PSI5NyIgcnk9IjEwMSIvPjxwYXRoIGQ9Ik0xODM2IDUyNmwtODEtMjQ3IDE0NS03OSAxMzkgNzktNzUgMjUxeiIvPjwvZz48cGF0aCBkPSJNMjAxNCA0ODZzLTQ5IDk0IDE4IDE0NGM2NiA1MCAyMzEgODEgMzE5IDEzOSA4OSA1OCAyNDAgMTIwIDI0MSAyODQgMiAxNjQtMzMgMjM2LTEzOSAzNTEtMTA3IDExNi0xNzUgMTI2LTE3NSAxMjZoMjg4czg3LTE1MiAxMTAtMjI2IDUyLTE2NyAzNi0yNjctOTAtMjI1LTIwNi0yODBjLTExNi01Ni04Ni01MS0xNzAtNzUtODMtMjQtOTQtMjYtMTAzLTI4cy05NS0yNy05NS0yNy00NS0yNS03MC01MS01NS05MS01NS05MXptMjY0IDEwNDVsMzQgMjIwaDQxNHYtMjIweiIgZmlsbD0iI2QxZDFkMSIvPjwvc3ZnPg==')} +.is2d .pawn.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMzgzODM4Ij48cGF0aCBkPSJNOTUzIDMyMzloMTkwN3YyMDRIOTUzeiIvPjxwYXRoIGQ9Ik0xMDk5IDMzODZoMTYyMXYxNTNIMTA5OXoiLz48cGF0aCBkPSJNOTUwIDM1MDZoMTkwN3YyMDRIOTUweiIvPjwvZz48cGF0aCBkPSJNMTA5OSAzNDQzaDE2MjF2NjNIMTA5OXoiIGZpbGw9IiMxMTEiLz48ZyBmaWxsPSIjMzgzODM4Ij48cGF0aCBkPSJNMTY1OSAyMDU5bDI5Ni00IDEgMTI4Mi02MTgtOXoiLz48cGF0aCBkPSJNMjE0MCAyMDU5bC0yNjQtNHYxMjgybDYxNy05eiIvPjxwYXRoIGQ9Ik0xMzU1IDE5MDdoMTExNXYxNThIMTM1NXoiLz48ZWxsaXBzZSBjeD0iMTg5MCIgY3k9IjE1NDkiIHJ4PSI0MTQiIHJ5PSI0MzMiLz48L2c+PGcgZmlsbD0iIzExMSI+PHBhdGggZD0iTTE5ODAgMTEyNnMxOTUgMTQ3IDIxOCAzNDljMzYgMzE1LTE2MiA0MTgtNDQ2IDM1MS0xNDMtMzQtMjQ0LTExMC0yMzEtODIgMCAwIDIxIDUxIDU5IDkwIDM3IDM5IDgyIDc1IDgyIDc1aDQ1N3M3NC00MSAxMTQtMTE3YzQwLTc3IDcyLTEzNyA3Mi0yNDRzLTQxLTE5OS02OC0yMzctNTYtNzEtMTA1LTExNGMtNDgtNDQtMTUyLTcxLTE1Mi03MXoiLz48cGF0aCBkPSJNMjA3NCAxOTA3bDY5IDE1OGgzMjZ2LTE1OHptLTUxNiAxNThoNTg1bDM0NiAxMjQyaC0yNTVsLTE2OC0xMDk1eiIvPjxwYXRoIGQ9Ik0yNDY2IDMyMzlsNzAgNDcxaDMyMXYtMjA0aC0xMzd2LTYzaDE0MHYtMjA0eiIvPjwvZz48L3N2Zz4=')} +.is2d .knight.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMzgzODM4Ij48cGF0aCBkPSJNODI5IDEzNzhjLTE2NSAxNTEtMTQ1IDE0MC03MiAyNzEgNzIgMTMxIDI0MSAxODggNDAwIDE0MiAxNTgtNDYgNTA2LTE4MyA2MzMtMTU0IDEyNyAzMCAxNTkgOTEgMTY3IDE1N3MtMTg2IDIyNy00MDAgNDMzYy0yMTQgMjA1LTQwMiAyNDMtMzczIDY3MSAzMCA0MjggMTkgNTI1LTQyIDU5MnMxMDc0IDI2MyAxMjIxIDE5NmMxNDctNjggNTQzLTU1IDQ2NS00NjAtNzgtNDA2LTIwOC05MDAtMTAtMTIzOHMzOTgtMTA0Mi01MjctMTQyMy01NTggMzUtNjQ4IDgzYy05MCA0Ny0xMjEgNTctMTc1IDgzLTk4IDQ3LTQ2MiA0ODYtNjM5IDY0N3oiLz48cGF0aCBkPSJNODkwIDMyMzloMjIxN3YyMDRIODkweiIvPjxwYXRoIGQ9Ik0xMDU5IDMzODZoMTg4NXYxNTNIMTA1OXoiLz48cGF0aCBkPSJNODg2IDM1MDZoMjIxN3YyMDRIODg2eiIvPjwvZz48ZyBmaWxsPSIjMTExIj48cGF0aCBkPSJNMTYxNSAxNjQ0czg1LTEyNCAyNjItMTMxYzE3Ni03IDc1LTMzMSA3NS0zMzFzMjI3IDI5MyAyMjcgNDQ0LTIzOSAyMTctMjM5IDIxNy0zMC0xODItMzI0LTIwMHptMTAwNC05MDBzNDI1IDIzOCAyMjEgODQyLTU2MCA5MTUtNDk4IDEyMjYgOSAzNjQgMzEgMzkxIDkzIDI3IDE5NS00IDg0IDQ0IDkzIDg5YzkgNDQgNzIgNDIxIDcyIDQyMWgzNjl2LTIwNGgtMTU5di02M2gxNjN2LTIwNGgtMjc3cy05NS00NDgtMTE2LTcyOCA1OC00NTQgMTcwLTY1M2MxMTEtMjAwIDIzMS03NzctMjY1LTExMTN6Ii8+PHBhdGggZD0iTTEwNjAgMzQ0M2gxODg1djYzSDEwNjB6Ii8+PC9nPjwvc3ZnPg==')} +.is2d .bishop.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTg3MCA0ODJzNjIxIDI2OSA0NTggODgzLTU3MCAyNjAtNTcwIDI2MGwxMTMtMTE0MnpNNzk4IDMyMzhoMjIxN3YyMDRINzk4eiIgZmlsbD0iIzM4MzgzOCIvPjxwYXRoIGQ9Ik05NjcgMzM4NWgxODg1djE1M0g5Njd6IiBmaWxsPSIjMmUyZTJlIi8+PGcgZmlsbD0iIzM4MzgzOCI+PHBhdGggZD0iTTc5NCAzNTA1aDIyMTd2MjA0SDc5NHptNzg2LTE5NTJoNTk4bDUwMSAxNzA0SDExMjR6Ii8+PHBhdGggZD0iTTEyODYgMTUxMWgxMjAwdjE1MkgxMjg2eiIvPjxwYXRoIGQ9Ik0xODg1IDQ4M3MtNjIzIDI2OS00NTkgODgzIDU3MiAyNjAgNTcyIDI2MEwxODg1IDQ4NHoiLz48ZWxsaXBzZSBjeD0iMTg4MCIgY3k9IjQ0OCIgcng9IjE3NCIgcnk9IjE0MyIvPjwvZz48ZyBmaWxsPSIjMTExIj48cGF0aCBkPSJNMTk2NSAzMjNzNDMgNTQgNDMgMTE1LTE0IDExOC0xNCAxMTggMTUzLTExOC0yOS0yMzN6TTk2NyAzNDQyaDE4ODV2NjNIOTY3ek0xOTk0IDU1NnMyMjEgMTQ0IDMwMCAzMzMgNjYgMjU5IDUwIDM5Ny02OCAyMjQtNjggMjI0aDIwOXYxNTJoLTMyMWwtMTctMTUycy0yLTQyLTEyLTc3Yy0xMC0zNiA5My04NSAxMDQtMjQwIDEwLTE1NSAxLTI1My01My0zNjgtNTMtMTE2LTE5NC0yNjktMTk0LTI2OXoiLz48cGF0aCBkPSJNMTU0MSAxNjYzaDY2OWw0NjUgMTU3NWgzNDF2MjA0aC0xNjR2NjNoMTYwdjIwNGgtNDgxdi0yNjdsLTg0LTIwNC0zMTItMTQyOXoiLz48L2c+PC9zdmc+')} +.is2d .rook.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMzgzODM4Ij48cGF0aCBkPSJNMTI1OSAxNjk0bDEyODMgNCAyMDkgMTU5MC0xNjg4LTIyeiIvPjxwYXRoIGQ9Ik0xMDAyIDE3NDdoMTgwMmwyMTctMTE1MS01MjQgMzF2MjgyaC0zMDdWNjM2aC01NDl2MjczaC0zMjBsLTMtMjcyLTUyMS00MXpNNzkzIDMyMzVoMjIxN3YyMDRINzkzeiIvPjxwYXRoIGQ9Ik05NjIgMzM4MmgxODg1djE1M0g5NjJ6Ii8+PHBhdGggZD0iTTc4OSAzNTAyaDIyMTd2MjA0SDc4OXoiLz48L2c+PGcgZmlsbD0iIzExMSI+PHBhdGggZD0iTTI4NTIgNjA2cy0xNDYgOTE5LTE2OCA5ODYtOTQgMTU1LTk0IDE1NWgyMTNsMjE3LTExNTEtMTY5IDEwek0xMzg2IDE3NDdoMTE2MmwxOTUgMTQ4OGgyNjZ2MjA0bC0xNjEtM3Y2M2wxNTcgM3YyMDRoLTMxNnMtMjQtMTcxLTY3LTI2OWMtNDItOTktOTAtNzgtMTM5LTQ0NS00OS0zNjgtMTUzLTEwMjAtMTUzLTEwMjBsLTk0NS0yMjN6Ii8+PHBhdGggZD0iTTk2NCAzNDM2aDE4ODV2NjNIOTY0eiIvPjwvZz48L3N2Zz4=')} +.is2d .queen.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMzgzODM4Ij48cGF0aCBkPSJNMTQ0NSAxNjI2bDg5MiA0IDQxOSAxNjU4LTE2ODgtMjR6Ii8+PHBhdGggZD0iTTc5OCAzMjM1aDIyMTd2MjA0SDc5OHoiLz48cGF0aCBkPSJNOTY3IDMzODJoMTg4NXYxNTNIOTY3eiIvPjxwYXRoIGQ9Ik03OTQgMzUwMWgyMjE3djIwNEg3OTR6Ii8+PC9nPjxwYXRoIGQ9Ik0xNDAxIDE3NDVoOTY1bDM4MyAxNDg5aDI2NnYyMDRoLTE2MXY2MGwxNTcgM3YyMDRoLTMxNnMtMjYtMTQ5LTcxLTI2N2MtNDUtMTE3LTg1LTgwLTEzNS00NDgtNDktMzY4LTI1My0xMTE3LTI1My0xMTE3bC04MzYtMTI5eiIgZmlsbD0iIzExMSIvPjxwYXRoIGQ9Ik05NzAgMzQzNmgxODg0djYzSDk3MHoiIGZpbGw9IiMxMTEiLz48ZyBmaWxsPSIjMzgzODM4Ij48cGF0aCBkPSJNMTA4OCAxNTI2aDE2Mzh2MjIwSDEwODh6Ii8+PHBhdGggZD0iTTEzNTIgMTU2M0w5NDkgNzk4bDQ5NyAyNjAtNDAtNjg0IDQ3OCA1NTcgMzIgNjMyeiIvPjxwYXRoIGQ9Ik0yNDE2IDE1NjNsNDAzLTc2NS00OTggMjYwIDQwLTY4My00NzggNTU2LTE4IDYzMnoiLz48Y2lyY2xlIGN4PSI5NDkiIGN5PSI3OTgiIHI9IjEwMCIvPjxjaXJjbGUgY3g9IjE0MDYiIGN5PSIzNzQiIHI9IjEwMCIvPjxjaXJjbGUgY3g9IjIzNjEiIGN5PSIzNzUiIHI9IjEwMCIvPjwvZz48ZyBmaWxsPSIjMTExIj48Y2lyY2xlIGN4PSIyODE5IiBjeT0iNzk4IiByPSIxMDAiLz48cGF0aCBkPSJNMjQyMSAyOTVsLTk3IDE3My0yNDAgMTA1OGgzNTFsMzM3LTYzOS00Mi00Mi00MDkgMjEzIDQwLTU4NHMxNzMtMzQgNjAtMTgwem0tMTYxIDEyMzF2MjE5aDQ2NnYtMjE5eiIvPjwvZz48L3N2Zz4=')} +.is2d .king.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMzgzODM4Ij48cGF0aCBkPSJNMTM0MiAxNjMybDEwOTggOSAzMTYgMTY1My0xNjg4LTI0eiIvPjxwYXRoIGQ9Ik03OTggMzI0MWgyMjE3djIwNEg3OTh6Ii8+PHBhdGggZD0iTTk2NyAzMzg4aDE4ODV2MTUzSDk2N3oiLz48cGF0aCBkPSJNNzk0IDM1MDdoMjIxN3YyMDRINzk0eiIvPjwvZz48cGF0aCBkPSJNMTQwMSAxNzUxaDEwNjFsMjg4IDE0ODloMjY2djIwNGwtMTYxLTN2NjNsMTU3IDN2MjA0aC0zMTZzLTI2LTE0OS03MS0yNjdjLTQ1LTExNy04NS04MC0xMzUtNDQ4LTQ5LTM2OC0xNTAtMTEwMS0xNTAtMTEwMWwtOTM5LTE0NXoiIGZpbGw9IiMxMTEiLz48cGF0aCBkPSJNOTcwIDM0NDJoMTg4NHY2M0g5NzB6IiBmaWxsPSIjMTExIi8+PGcgZmlsbD0iIzM4MzgzOCI+PHBhdGggZD0iTTEwODggMTUzMWgxNjM4djIyMEgxMDg4eiIvPjxwYXRoIGQ9Ik0xMjc4IDE2MTFzLTI0MS0zMjgtMTk5LTU3MmM1MC0yODUgMzgyLTQwOCA4NzUtNDM1IDE0OC04IDk4IDEwMDcgOTggMTAwN3oiLz48cGF0aCBkPSJNMjUxNSAxNjExczI0MS0zMjggMTk5LTU3MmMtNTAtMjg1LTM4Mi00MDgtODc1LTQzNS0xNDgtOC05OCAxMDA3LTk4IDEwMDd6Ii8+PHBhdGggZD0iTTE1NjAgNjU1czI1My02MyAyMjYtMTY5IDExNC0xOSAxMTQtMTlsMTAgMTQ2LTM1MCA0M3oiLz48cGF0aCBkPSJNMjE3MiA2NDdzLTE1NC03NS0xNTgtMTYxYy01LTg2LTExNC0xOS0xMTQtMTlsLTEwIDE0NyAyODIgMzR6Ii8+PGVsbGlwc2UgY3g9IjE3NTUiIGN5PSIyNzkiIHJ4PSI5MSIgcnk9Ijg5Ii8+PGVsbGlwc2UgY3g9IjE3ODQiIGN5PSI0MTciIHJ4PSI2NCIgcnk9IjYyIi8+PGVsbGlwc2UgY3g9IjIwMzkiIGN5PSIyNzkiIHJ4PSI5MSIgcnk9Ijg5Ii8+PGVsbGlwc2UgY3g9IjIwMTAiIGN5PSI0MTciIHJ4PSI2NCIgcnk9IjYyIi8+PGVsbGlwc2UgY3g9IjE5MDAiIGN5PSIyMDAiIHJ4PSI5NyIgcnk9IjEwMSIvPjxwYXRoIGQ9Ik0xODM2IDUyNmwtODEtMjQ3IDE0NS03OSAxMzkgNzktNzUgMjUxeiIvPjwvZz48cGF0aCBkPSJNMjAxNCA0ODZzLTQ5IDk0IDE4IDE0NGM2NiA1MCAyMzEgODEgMzE5IDEzOSA4OSA1OCAyNDAgMTIwIDI0MSAyODQgMiAxNjQtMzMgMjM2LTEzOSAzNTEtMTA3IDExNi0xNzUgMTI2LTE3NSAxMjZoMjg4czg3LTE1MiAxMTAtMjI2IDUyLTE2NyAzNi0yNjctOTAtMjI1LTIwNi0yODBjLTExNi01Ni04Ni01MS0xNzAtNzUtODMtMjQtOTQtMjYtMTAzLTI4cy05NS0yNy05NS0yNy00NS0yNS03MC01MS01NS05MS01NS05MXptMjY0IDEwNDVsMzQgMjIwaDQxNHYtMjIweiIgZmlsbD0iIzExMSIvPjwvc3ZnPg==')} diff --git a/public/piece-css/reillycraig.css b/public/piece-css/reillycraig.css new file mode 100644 index 0000000000..36b6837b70 --- /dev/null +++ b/public/piece-css/reillycraig.css @@ -0,0 +1,12 @@ +.is2d .pawn.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii01Ni45IC0xMCAyMjAgMjIwIiB3aWR0aD0iMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48c3dpdGNoPjxnPjxwYXRoIGQ9Ik01MyAxNzYuNkg2Ljd2MTUuN2g5Mi42di0xNS43SDYuN3YtNy45YzI5LjQtMzYuNyAyNy4yLTYyLjEgMjItNzUuNS0yLjgtNy4zLTYuNS0xMS02LjUtMTFoNjEuNHMtMjkuNyAyOS45IDE1LjYgODYuNXY3LjkiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNNTMgMTc2LjZINi43djE1LjdoOTIuNnYtMTUuN0g2Ljd2LTcuOWMyOS40LTM2LjcgMjcuMi02Mi4xIDIyLTc1LjUtMi44LTcuMy02LjUtMTEtNi41LTExaDYxLjRzLTI5LjcgMjkuOSAxNS42IDg2LjV2Ny45IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTgzLjcgMzQuOGMwIDE3LjMtMTMuOCAzMS40LTMwLjggMzEuNHMtMzAuNy0xNC0zMC43LTMxLjRDMjIuMiAxNy41IDM2IDMuNCA1Mi45IDMuNGMxNyAuMSAzMC44IDE0LjEgMzAuOCAzMS40IiBmaWxsPSIjZmZmIi8+PGVsbGlwc2UgY3g9IjUyLjkiIGN5PSIzNC44IiBmaWxsPSJub25lIiByeD0iMzAuOCIgcnk9IjMxLjQiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNNTMgNjYuMnMzMyAuMSA0Ni4yIDE2SDYuOEMyMCA2Ni4zIDUzIDY2LjIgNTMgNjYuMiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik01MyA2Ni4yczMzIC4xIDQ2LjIgMTZINi44QzIwIDY2LjMgNTMgNjYuMiA1MyA2Ni4yIiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTMwLjMgOThoNDUuNCIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0zMC4zIDk4aDQ1LjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjQiLz48cGF0aCBkPSJNNi43IDE2OC43aDkyLjYiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNNi43IDE2OC43aDkyLjYiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48L2c+PC9zd2l0Y2g+PC9zdmc+')} +.is2d .knight.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii0zMi40NSAtMTAgMjIwIDIyMCIgd2lkdGg9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHN3aXRjaD48Zz48cGF0aCBkPSJNOTcuOSAxNzAuNGM5LjcgMCA5LjctMTUgMC0xNS05LjYgMC05LjYgMTUgMCAxNU0zOS4xIDMwLjVjLTItMy00LjUtNC40LTcuOC01LjctMy41LTEuMy02LjUtMy40LTEwLTQuNy02LjctMi41LTE4LjQtNS40LTE5IDUuNS0uMiAzLjEgMS4yIDUuOCAyLjMgOC43IDEuNSAzLjcgMyA3LjYgNS44IDEwLjYgMi42IDIuOSA1LjYgNC41IDkuMiA1LjkgMS45LjggNC43LjggNi43LjMgMS4xLS4yIDIuMS0uNiAzLjEtMS4xIDEuNi0uOCAxLjgtLjkuNi0uNCAyLjktMS4yIDUuOS0zLjcgNS41LTcuMi0uNi01LjUtNC40LTkuMS05LjUtMTAuNy02LjgtMi4xLTEzLjMgNy43LTcuMyAxMi41QzI0LjYgNDkgMzUgNTguOSA0MS42IDQ5LjVjNC45LTYuOS0xLjItMTcuNi01LjItMjMuMy0yLjggMy43LTUuNiA3LjMtOC41IDExIDMuNy43IDcgMy4xIDEwLjggMy44IDUuNi45IDExLjEtMS4xIDEzLjYtNi41IDEuOS00LjEuNy0xMC00LjUtMTEtMi43LS41LTUtLjMtNy43LS4zLTkuNy4xLTkuNyAxNSAwIDE1IDcuNiAwIDE0LjktLjcgMjEuMS01LjUgMi42LTIgNi43LTEuOCA5LjgtMi42IDQuOC0xLjMgOC4xLTIuNiAxMy0xLjIgNi40IDEuOCAxMS40IDYuMSAxOC40IDQuNiAzLjYtLjggNi4zLTQuMiA3LjEtNy42LjUtMi4xLjEtNC0uMi02LS43IDEuOC0uNiAyLjEuMiAxIC45LS42LjgtLjctLjQtLjItMS4zLS4zLTIuNS0uNy0zLjgtMSAxLjIuNiAyLjQgNC42IDMuNSA2LjIgMi4xIDMuMSA0LjMgNiA2LjIgOS4ybC45IDEuOC0uMS0uMWMuNSAyLjcgMS41IDEuMSAyLjktNC42LTIgLjgtNC4yIDEuMS02LjIgMS45IDEuMy0uNSAxLjkgMy4yLjItLjYtLjQtMS0uNy0yLjEtMS0zLjItLjYtMi41IDIuMi0uMS0xLjcgMi4xLTEuMy4zLTIuNS43LTMuOCAxLTMuOS41LTEuOC01LS44LTUuOC0xLjcgMS4yLTMuNSAyLjQtNS4yIDMuNS0zLjQgMi4yLTcgNC4xLTEwLjUgNi4xLTcuNCA0LjMtMTQuNCA5LjMtMjEuNiAxMy45LTYuOSA0LjQtMTMuMSA5LjMtMjEuMiAxMS00IC45LTcuNy0uNS0xMS40LTEuNy0zLjktMS4zLTguMi0xLjgtMTEuNi00LjEtMS4zIDQuNy0yLjUgOS4zLTMuOCAxNCA5LjQgMS4yIDE2LjMtMS4xIDIzLjctNy4xIDMuNS0yLjkgNi4yLTYuMiA2LjUtMTAuOS4yLTIuMS0uMi00LjEtLjgtNi4xLS4yLS41LS40LTEtLjYtMS42LS4xLS4zLS4yLS42LS4yLS45LjEgMS42LS41IDIuOS0xLjkgMy45LTEuMy4zLTIuNS43LTMuOCAxIDIuNS0uMSAxLjYtLjktMi44LTIuNC0uNC0yLjItLjYtMi42LS41LTEuMiAwIC45LS4xIDEtLjQgMi40LS42IDIuNy0xLjYgNS40LTIuMyA4LjEtMi4xIDcuMiAxLjQgMTYgMTAuNCAxMy43IDMuNC0uOSA2LjItNC4zIDguMi02LjkgMy4xLTMuOSA0LjgtOC42IDUuMS0xMy41LjEtMiAwLTQtLjEtNnYtNC4yYzAtLjYuMS0xLjMuMS0xLjkgMCAuMSAwIC4zLS4xLjQuNi0yLS4zLTEuMS0yLjcgMi44LTEuMy4zLTIuNS43LTMuOCAxaC40Yy0xLjMtLjMtMi41LS43LTMuOC0xIC45LjQgMy44IDMuNSAzLjkgNS43LjIgMi40LS44IDUuMi0xLjEgNy42LS4zIDMuMy45IDYuOCAyLjYgOS41IDMuNyA2IDExLjMgNCAxMy43LTEuOCAzLjItNy44IDMuOS0xNi4yIDMuMy0yNC41LS4xLS45LS4xLTEuNyAwLTIuNi00LjUgMi01LjUgMy4yLTIuNyAzLjUuNC4xLjkuMiAxLjMuNCAxLjggMS4yIDEuNS4xLS45LTMuMi0uNSAyLjQtMi4xIDQuOS0zIDcuMi0yLjggNy41IDMuNSAxNS4yIDExLjQgMTEuNCAzLjQtMS42IDUuOC00LjYgOC4xLTcuNiAxLjItMS42IDItMy40IDIuNy01LjIuNC0uOC43LTEuNyAxLTIuNSAxLTIuNyAyLjEtMy4xLTEtLjgtMS4zLjMtMi41LjctMy44IDEtMi4zLjItMS42LS41LS4xLjcgMS4yIDEgMi40IDEuOSAzLjggMi44IDMuMSAyLjEgNi40IDEuMyA5LjcuNWwtOS4yLTkuMmMtLjcgNC45LTEuOCA5LjYtMS44IDE0LjYtLjEgMy44LTMuMiA2LjItNS42IDguOC0yLjkgMy4xLTUuNSA2LjctNy44IDEwLjMtLjggMS4zLTEuNSAyLjctMi4xIDQuMi0uMy42LS41IDEuMi0uOCAxLjgtMS4zIDIuNy0xLjYuNyAxLjIuMWg0YzIuNiAzLjEgMy40IDMuNSAyLjYgMS4yLS40LTEuNS0xLTIuOC0xLjgtNC4xcy0yLTIuNC0zLjMtMy4yYy0yLjQtMS42LTEuMi0xLjkgMCAxLjN2NGMuMS0uMy4yLS41LjMtLjggMS4zLTMuOS0xLjQtOC4yLTUuMi05LjItMS4yLS4zLTIuNS0uNC0zLjctLjkuNiA0LjYgMS4yIDkuMSAxLjggMTMuNyA1LjMtMyAxMS4xLTUgMTYuMy04LTMuOC0yLjItNy41LTQuMy0xMS4zLTYuNS4zIDIuOS0xLjQgNi4zLTIuNSA4LjktLjkgMi4xLTEuNyA0LjEtMi4xIDYuMy0uMiAxLS4zIDIuMS0uMiAzLjEuMi0uNi40LTEuMS42LTEuN2wtMS44IDIuNGMtNS40IDggNy42IDE1LjUgMTMgNy42IDEuMi0xLjggMi4yLTMuMSAyLjktNS4yLjQtMS4zIDAtMi41LjMtMy44LjMtMS41IDEuMS0zIDEuNy00LjUgMS42LTQuMSAzLjgtOC43IDMuMi0xMy4yLS43LTUuNC01LjktOS42LTExLjMtNi41LTUuMyAzLjEtMTEgNS4xLTE2LjMgOC02LjEgMy40LTQgMTEuNiAxLjggMTMuNyAxLjIuNSAyLjUuNSAzLjcuOS0xLjctMy4xLTMuNS02LjItNS4yLTkuMi0xLjIgMy42LjEgNi44IDIuNiA5LjVsMi40IDEuOGMxLjMuOSAxLjIuOC0uMS0uNS42IDEuOCAxLjEgMy41IDIuMiA1LjEgNS4zIDcuNyAxMy45IDQgMTcuNS0yLjkgMS42LTIuOSAyLjgtNS44IDQuNy04LjYgMi4yLTMuMiA1LjEtNS45IDcuNy04LjkgNi41LTcuMyA2LjEtMTYuNSA3LjMtMjUuNy44LTUuNy0zLjEtMTAuNi05LjItOS4yLTIuNS42IDIuNyAxLjcuMi0uMi0xLjQtMS4xLTIuOC0yLjItNC40LTMuMS0yLjktMS43LTYuOC0xLjgtOS41LjItMy4zIDIuNC00LjEgNS43LTUuMyA5LjQtLjUgMS41LTEuMyAyLjgtMi4yIDQuMi0uNyAxLjEtMi45IDEuNy0xLjQgMS41IDEuOS4zIDMuOS41IDUuOC44LjguNyAxLjUgMS41IDIuMyAyLjIuMyAxLjMuNyAyLjUgMSAzLjguMSAxLjkgMCAuMy4yLS41LjMtLjguNC0uOS45LTIgMS4yLTIuNiAyLjctNS40IDIuNy04LjMtLjEtNy42LTYuNy0xMi0xMy43LTEzLTguNy0xLjItMTMuNyA0LjItMTQgMTIuNi0uMSAzIC41IDUuOS4zIDguOS0uMyA0LjUtMS4zIDguOC0zIDEzbDEzLjctMS44Yy0xLjUtMi40LjQtNi44LjUtOS42LjItMy41LTEuMS03LjEtMy0xMC0zLTQuNC0xMC0xMy40LTE2LjMtOC43LTUuMiAzLjktNC45IDEwLTQuOCAxNS45IDAgMS43LjMgNC4yLjEgNS42LS4yIDEuNi0uNyAzLjMtMS43IDQuNS0uOCAxLTMuNyAyLjctMS40IDIuMSAxLjkuMyAzLjkuNSA1LjguOGwtLjYtLjNjMS4xIDEuNSAyLjMgMyAzLjQgNC41LjMuNy0uNiAyLjYtLjEuNC4zLTEuMS42LTIuMi45LTMuMi44LTIuNSAxLjUtNC45IDItNy41IDEuMi02LjYtLjItMTMuNS03LjMtMTUuNy05LjYtMi45LTE0LjMgNy0xMi40IDE0LjcuMi41LjMgMS4xLjUgMS42LjQgMS44LjYgMS45LjUuNC0xLjQgMS0zLjMgMi4zLTQuOCAzLjMtMy40IDIuNC03LjEgMS41LTEwLjggMS04LjEtMS05LjIgMTAuMi0zLjggMTQgNS4zIDMuNyAxMi41IDQuOCAxOC42IDYuOCA3LjUgMi40IDE1LjYgMS4zIDIyLjktMS4zIDYuNC0yLjMgMTIuMi03IDE3LjktMTAuNkM4Mi41IDU5LjcgODkgNTUuMSA5NS45IDUxYzkuNC01LjcgMjktMTIuNyAyMS0yNi45LTMuMS01LjQtOS43LTcuNC0xNS4xLTQuM3MtNS4zIDEwLjEtNC4xIDE1LjRjMS4xIDQuNiAzLjggOS41IDcuNyAxMi4zIDUuMiAzLjggMTMuMS44IDE4LjUtMS40IDEyLjItNS4xIDUuNC0xNy4zIDAtMjQuOS01LjMtNy40LTkuNi0yMC4zLTIxLjMtMTMuOC01LjUgMy4xLTkuMSA5LjEtNy45IDE1LjQuNyAzLjcgNy4yLTMuMSAzLjQtNC4zLTEtLjMtMi0uOS0zLTEuNC0zLjMtMS42LTYuOC0yLjgtMTAuNC0zLjYtOC40LTEuOS0xNS45IDIuMi0yNCAzLjMtMy43LjUtNi4yIDIuNC05LjIgNC41LTMuMiAyLjItNy43IDEuOC0xMS4zIDEuOHYxNWMxLjEgMCAyLjYtLjUgMy43LS4yLTEuNS0zLjctMy03LjMtNC41LTExLTEuMyAyLjguNC0uOCAyLjQtLjUtMS4xLS4yLTIuMi0uNi0zLjItMS0yLjItLjktNC4zLTIuMS02LjctMi42LTUuOC0xLjEtMTIuNiA1LjEtOC41IDExIDEgMS40IDIuNSAyLjcgMy4xIDQuMi40IDEgLjggMiAxLjEgMyAuNyAyLjEtLjEgMi43IDEuMSAxIDEuNS0xLjEgMy0yLjMgNC41LTMuNC0uMi4xLS41LjEtLjcuMmg0Yy0yLjYtLjYtNS0zLjQtNy01LjEtMi40IDQuMi00LjkgOC40LTcuMyAxMi41LjQuMS4yIDAtLjUtLjQtLjMtMS4zLS43LTIuNS0xLTMuOHYuNGMxLjgtMi40IDMuNy00LjggNS41LTcuMi0uNy4zLTMuMSAxLjEtMi40IDEuMi0xLjQtLjMtMi4zLTEuNy0yLjktMi43LTEuMi0xLjktMy40LTYuOC0zLjMtOC0uMyAxLjMtLjcgMi41LTEgMy44LjEtLjIuMi0uMy4zLS41LTEuNSAxLjEtMyAyLjMtNC41IDMuNC0yLjYgMS4xLjggMSAyIDEuMyAyLjEuNSAzLjcgMS41IDUuNiAyLjUgMS44IDEgMy42IDEuOCA1LjUgMi41IDIuNC45IDIuNCAxLjYuOS0uNSA1LjEgNy45IDE4LjEuNCAxMi43LTcuNyIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0xMDIgNTRjMy40IDEuMyA2LjIgMy44IDEwLjEgMy44IDIuMiAwIDQuNC0uMyA2LjUtLjguOC0uMiAxLjctLjQgMi41LS40LTIuMS0xLjEtMi41LTEtMS4yLjEgMS44IDEuOCAyLjcgNS4yIDMuNyA3LjUuNCAxIC45IDEuOSAxLjMgMi44LTEuNi00LjIgNS4yLTUuOC4zLTQuMS0zLjMgMS4xLTYuNSAxLjgtOS43IDMuMi0zLjggMS42LTcuNCAzLjgtMTEgNS45LTMuNSAyLTcgNC4xLTEwLjcgNS41LTEuOS44LTQgMS4yLTYgMS43LjgtLjEuNi0uMS0uNSAwLTIuMS0uMi0xLjUuNCAxLjcgMS42LjMgMS45LjUgMy45LjggNS44LjYtMi42IDQuNS02LjIgNi41LTguNSAzLjUtNCA1LjMtOC40IDcuNi0xMy4yIDEuOS0zLjkgNC0xIDcuNi4zIDEuNC41IDIuOSAxIDQuMyAxLjUuNC4yLjkuMyAxLjMuNSAxLjkuOCAxLjggMS45LjMtLjYtLjMtMS4zLS43LTIuNS0xLTMuOC4yLTEuNS44LTIuNyAxLjgtMy41LS44LjUtLjcuNC0xLjYuNy0xLjkuNy0zLjggMS4xLTUuNyAxLjUtNS4zIDEuMi0xMC4xIDMuMi0xNSA1LjQgMyAzLjkgNi4xIDcuOSA5LjEgMTEuOCAxLTEuMSAyLTIuMyAzLTMuNS43LS44IDEuNC0xLjUgMi4xLTIuMyAxLjMtMSAxLjYtMS4zLjgtLjktMS45LS4zLTMuOS0uNS01LjgtLjgtMi41LTEuMi0yLjMtMi41LS42LjEuOCAxLjMgMS44IDIuMyAyLjkgMy4zIDIuMyAyLjEgNSAzLjIgNy44IDQuNCA0LjYgMS45IDkuOSAxLjMgMTIuOCA1LjkgMS40IDIuMyAyLjUgNC44IDMuOCA3LjIuNyAxLjIgMS40IDIuNCAxLjkgMy43LjEuNS4zIDEgLjQgMS41IDAgMi4yIDEuMSAxLjcgMy40LTEuMy0xLjYuMS0zLjQtLjYtNS0uOC00LjEtLjYtOC4yLS4zLTEyLjItLjggMS44IDQuMyAzLjUgOC41IDUuMyAxMi44IDEuMy0xLjIgMy4yLTEuOSA0LjYtMyAyLjYtMiA0LjctNC42IDUuOC03LjcgMi01LjUtLjQtMTAuNC0zLjktMTQuNi02LTcuMi0yMi4xLTExLjMtMjQuOCAxLjQtMS45IDguOCA0LjEgMTUgOC40IDIxLjkgMi4yIDMuNiAyLjcgOC4zIDQuMSAxMi4zIDEuOSA1IDQuOSA5LjEgOS41IDExLjkgMi4xIDEuMyA1LjUgMS41IDcuNiAwIDUuOS00LjQgOC4zLTEwLjQgOC45LTE3LjYuNy04LjYtOC40LTEzLjMtMTUuMy05LjEtNC42IDIuOC01LjIgMTAuNCAwIDEzIDEuNC43IDIuNiAxLjMgNC4xIDEuNSAxLjEuMiAyLjIuMyAzLjIuMy0yLjYtMi4zLTMuMy0yLjYtMi4xLS44IDEuNCAyLjYgMS40IDcuNCAxLjcgMTAuMy4yIDEuOS40IDMuOC42IDUuNi4yLjguMyAxLjcuMyAyLjUgMy42LTIuMyA0LjEtMy4zIDEuNi0zLTQgMC03LjcgMC0xMS43LjYtNS42LjktMTQgMi41LTE1LjcgOC44LTIuNSA4LjkgNi40IDExLjQgMTIuNiAxMy45bC0zLjMtMTIuNWMtMi40IDIuNC00LjQgNS4xLTYuNCA3LjgtLjggMS4yLTEuOCAyLjMtMi44IDMuM2wxLjUtLjNjLS43LS4zLTEuNS0uNi0yLjMtLjgtOS4zLTMtMTIuOSAxMS4xLTQgMTQuNSA0LjEgMS41IDEwLjQgNC4yIDE0LjctLjYgNC44LTUuMy42LTExLjYtLjctMTcuMy0yLjEtOC45IDEzLjYtMTEuNiAxOS0xMy41IDYuNC0yLjIgNy4xLTkuOSAxLjgtMTMuNy0zLjQtMi40LTgtMi4yLTEyLTIuMS0xLjggMC0xMS0uNi0xMS41LTEuNy0yLjUtNi0yLjMtMTMtMi45LTE5LjMtLjUtNS41LS45LTEzLjItNC4xLTE3LjktMy45LTUuOS0xNC4zLTQuMS0xNCAzLjguMiA2LjQgNCAxMi45IDYuOCAxOC42IDEuNSAzIDMuNSA1LjcgNS42IDguNCAxIDEuMyA0LjYgNC43IDQuNSA2LjEuMy0xLjMuNy0yLjUgMS0zLjggMS0uNy45LS43LS40LjFsLTIuMSAxLjJjLTIuMSAxLjItNC4xIDIuOS02IDQuNS00LjQgMy43LTYuMiA4LjQtNi45IDEzLjktLjYgNS0uNiAxMC42LjQgMTUuNS42IDIuOC0uOCA2LjUtMyA4LjgtNi43IDcgMy45IDE3LjYgMTAuNiAxMC42IDQuOC01IDguOC0xMy40IDcuNS0yMC40LS44LTQuMy0uOC04LjQtLjctMTIuOC4xLTQgMy40LTUuOSA2LjYtNy44IDMuMy0xLjkgNi41LTMuOSA3LjYtNy44IDEuMi00LjQtMS4xLTguNi0zLjUtMTIuMS0yLjUtMy42LTUuNC02LjYtNy42LTEwLjQtMS45LTMuMi01LjUtOC43LTUuNi0xMi41LTQuNyAxLjMtOS4zIDIuNS0xNCAzLjggMS4zIDIgMS4xIDUgMS41IDcuMy42IDMuMy44IDYuNiAxIDEwIC41IDYuNiAxLjIgMTQuNSA0LjggMjAuMyAzLjIgNS4yIDkuNSA2LjggMTUuMSA3LjcgMi45LjUgNiAuOSA5IC45IDEuMiAwIDQuNCAwIDQuNC4xLjYtNC42IDEuMi05LjEgMS44LTEzLjctOS40IDMuMi0yMC4yIDUuNy0yNi4yIDE0LjMtMy4yIDQuNi00LjQgMTAuNC0zLjUgMTYgLjQgMi43IDEuMiA1LjEgMi4yIDcuNiAxLjggNC4yIDEwLjMtMy42IDYtNS0xLjItLjQtMi4zLTEtMy41LTEuNC0xLjMgNC44LTIuNyA5LjYtNCAxNC41IDUuMyAxLjcgOS43IDIgMTQuMi0xLjggNC4xLTMuNSA2LjQtOC40IDEwLjMtMTIuMSA0LjUtNC4zIDEuNy0xMC41LTMuMy0xMi41LS42LS4zLTEuMi0uNS0xLjktLjdsLTEuMi0uM2MtMS43LS42LTEuNi0uNS4yLjUuMyAxLjMuNyAyLjUgMSAzLjh2LS43Yy0uMyAxLjMtLjcgMi41LTEgMy44LS45IDEuNC0zIDItLjkgMS42LjgtLjIgMS41LS4zIDIuMy0uNSAzLjQtLjkgNi4zLTEuNiA5LjktMS40IDcuNS4zIDE0LjYtMS45IDE1LjctMTAuNS40LTMuMS0uNC02LjMtLjctOS41LS40LTQuMS0xLjEtOC4xLTEuOC0xMi4xLS41LTIuOS0xLjktNy4zLTQuNC05LjItMS4zLTEuMS0yLjQtMi4xLTQuMS0yLjYtLjktLjMtNC41LS41LTQuMS0uNHYxM2MuNC0uMi44LS41IDEuMi0uNy0xLjMuMy0yLjUuNy0zLjggMSAuMyAwIC43LS4xIDEtLjEtMS4zLS4zLTIuNS0uNy0zLjgtMS0yLjktMS40LTEuNC00LjgtMi4yLTEuMy0uMi43LS44IDIuNi0xLjIgMi45aDcuNmMtMy42LTIuMi00LjEtNy43LTUuMi0xMS41LTEuNC00LjgtMy44LTguNS02LjYtMTIuNS0xLjEtMS41LTIuMy0zLjEtMy00LjgtLjYtMS40LS4xLS45LS44LjctMS40IDMuMy01LjQuMS0yLjEgMi4xLjkuNSAxLjYgMS40IDIuMyAyLjIuOS45LS40LjMuMi0uNy0xIDEuNy01LjIgMy4zLTYuNyA0LjctNS4yIDUtLjggMTIuMSA1LjMgMTIuOCA0LjQuNSA4LjcuNCAxMy4xIDEuMSA0LjcuOCA5LjEuNCAxMi42LTMuMSA4LjMtOC4yLS43LTIyLjMtNS4xLTMwLjEtMi4zLTQtNS43LTcuNC05LjktOS4yLTQuNC0xLjktOS40LTIuMS0xMy42LTQuNS0xLjMtLjctMS45LTIuOS0yLjktMy45LTItMi01LjEtMi45LTcuOC0yLjItNS40IDEuNS04LjkgNi41LTEyLjUgMTAuNS01LjkgNi43IDEuNCAxNS4yIDkuMSAxMS44IDQuMS0xLjggOC0zLjIgMTIuMy00LjEgMy43LS44IDcuNS0xLjkgMTAuNy00IDQuMS0yLjcgNi43LTguMiAzLjktMTIuOC0yLjQtNC4xLTcuNC01LjctMTEuNy03LjItNC0xLjQtOC4xLTQuMi0xMi40LTQuMi02LjcgMC0xMi4yIDMuOS0xNS41IDkuNi0xLjIgMi4yLTIgNC42LTMuMSA2LjktMS4zIDIuNi0zLjQgNC42LTUuMyA2LjgtMy4zIDMuNy04LjggMTAuMS03LjMgMTUuNSAzLjUgMTIuNyAyMC44IDYuNCAyOC42IDIuOCA1LjItMi40IDEwLTUuNiAxNS04LjMgNC44LTIuNiAxMC0zLjMgMTQuOS01LjYgMTAuOS01LjEgMy45LTE3LjUtLjMtMjUuMS0yLjUtNC41LTYuMy04LjEtMTEuNi04LjctMi45LS40LTUuNi43LTguNCAxLTIuMi4zLTUuNi0yLjQtNy43LTMuMi0zLjgtMS41LTguMiAxLjYtOS4yIDUuMi0uMiA0LjIgMi40IDcuNyA2LjIgOS4yIiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTc1LjcgODEuM2MtNS41LjktMTAuNyA2LjUtMTUuMSA5LjctNS44IDQuMi0xMC41IDkuMy0xNC41IDE1LjItNCA1LjctNi43IDEyLjEtOS4zIDE4LjYtMi45IDcuMS01LjYgMTQuMS02LjUgMjEuNy0uNCAzLjIuMSA2LjYtLjggOS42LS44IDIuOC0xLjEgNS45LjQgOC41IDQuNSA3LjcgMTIuMiAzLjIgMTguNyAyLjggMTQuNy0uOCAyOS41IDMuOSA0NC4xIDEuNCAxNS45LTIuOCAxNS41LTIxLjMgMTcuNS0zMy42IDIuMi0xMy42IDcuMy0zMC4xLjgtNDMuMy03LjktMTYuMS0yNS44LTIuOS0zNS44IDMuMi0xMS44IDcuMy0yMi40IDE4LjItMjguMiAzMC45LTMuOSA4LjUtMTAuNyAxOS44LTMuMSAyOC4xIDUuNSA2IDE0LjMgNy4yIDIxLjkgOC4yIDkuNiAxLjIgMjIuOCAzIDMxLjItMi43IDguOS02LjEgMTMuNy0xOC42IDE1LjItMjguOCAxLjQtOS45IDEuNC0yMS42LTItMzEuMS0xLjktNS4zLTUuMy04LjktMTAuNS0xMS01LjctMi4zLTEyIDIuMy0xNi40IDUuNS05LjcgNi44LTE0IDE5LTIxLjcgMjcuNy00LjMgNC44LTkgOS4zLTEzLjYgMTMuOC0zLjkgMy44LTcgOC40LTEwLjMgMTIuMi01IDUuOS0uMiAxMy45IDcuMyAxMi41IDcuMy0xLjMgMTMuNi01IDIwLjUtNy42IDcuNC0yLjggMTQuMS0xLjEgMjEuNi0uMSAxNC45IDIgMTcuNS0xNC45IDE4LjUtMjUuOC43LTcuMiAxLjctMTYuMS0uNy0yMy0yLjUtNy41LTEwLjgtOC4xLTE2LjMtMy40LTQuNCAzLjgtNy41IDkuMi0xMC41IDE0LjEtMi4xIDMuNC00LjIgNi44LTYuOCA5LjgtMi4xIDIuNS02LjIgNC04LjggNi4xLTMuOSAzLjEtMi4zIDkuNSAxLjUgMTEuOCAzLjYgMi4yIDggMS44IDEyLjEgMiA1LjMuMyAxMC4zLS41IDE0LjgtMy4zIDcuNC00LjUgNi45LTE2LjcgMy4zLTIzLjYtNC40LTguNi0xNy40LTEtMTMgNy42LS42LTEuMiAwIDEuOCAwIDIgMCAuOC4xIDEuNi4yIDIuNCAwIDEuOC4yIDEuNi42LS42LTEuNyAxLTQuMy42LTYuMS41LS43IDAtNS4zLS41LTQuNSAwIC41IDMuOSAxIDcuOSAxLjUgMTEuOCAyLjgtMi4zIDYuMS0zLjUgOC44LTYgMi45LTIuOCA1LjEtNi42IDcuMy05LjkgMi4yLTMuNCA0LjMtNi45IDYuNi0xMC4yLjYtLjkgMy4xLTMuMSAyLjMtMi45aC00Yy0xLjEtMS0yLjItMi4xLTMuMy0zLjEuMSAxIC4yIDIgLjIgMy4xLjEgMS45LjEgMy43LjEgNS42IDAgNC4zLS40IDguNy0uOSAxMy0uMiAxLjktLjcgNC4xLTEuMyA2LjItLjMgMS0uNSAxLjItMS4xIDIuMS40LS42IDEtLjkgMS43LS44LTEtLjItMi0uNS0yLjktLjctNy43LTEuOS0xNS43LTEuNC0yMy40LjVzLTE0LjIgNi42LTIyLjIgOC4xbDcuMyAxMi41YzEuOC0yLjEgMy44LTMuNiA1LjItNi4yIDEuNS0yLjggNC01IDYuMi03LjIgNS41LTUuNSAxMS4xLTEwLjkgMTYuMS0xNi45IDQuMy01LjEgNy41LTExLjEgMTEuMy0xNi42IDEuNy0yLjUgMy44LTQuNiA2LjMtNi4zIDEuMS0uOCAyLjMtMS43IDMuNi0yLjEtMi4xLjgtMS43LTEtLjcgMS43IDEuOCA1IDEuOCAxMC43IDEuOCAxNS45IDAgNi43LTEgMTMuNC00LjMgMTkuMy0xLjIgMi4xLTIuNCA0LjMtNCA2LjEtMS43IDItMy43IDEuOS02LjEgMi01LjYuMy0xMy40LS4yLTE3LjYtLjgtMy41LS41LTcuNC0xLjEtMTAuNC0yLjgtMS4zLS43LS4zLS40LS40LjYuNi0zLjQgMi45LTYuOCA0LjItMTAgNS4xLTEzLjIgMTUuNi0yMi42IDI3LjQtMjkuNiAzLjEtMS44IDYuMy0zLjcgOS41LTUuNC41LS4zIDEuMS0uNiAxLjYtLjggMS42LS40IDEuNS0uOC0uNC0xIC42LjguNyAyLjIuOSAzLjEgMS43IDcuMy0uMiAxNC45LTEuNCAyMi4xLTEuMyA3LjYtMi41IDE1LjMtMy43IDIyLjktLjMgMS44LS4yIDQuOS0xLjUgNi4zLTIuMSAyLjMtNi4xIDEuNy04LjggMS42LTcuOC0uNC0xNS41LTEuMS0yMy4zLTEuNy0zLjctLjMtNy41LS4zLTExLjItLjItMS44IDAtMy41LjMtNS4yLjYtMSAuMy0xLjkuNS0yLjkuOS0zLjIuNS0yLjIgMS44IDIuOSA0LjF2NGMuNS0yLjkgMS4zLTUuNiAxLjUtOC42LjItMy41LjMtNi42IDEuMS0xMCAxLjctNy4yIDQuOS0xNC4zIDgtMjEgMi43LTUuNyA2LjItMTAuOSAxMC42LTE1LjQgMi40LTIuNSA1LjMtNC40IDguMS02LjMgMS45LTEuMyA0LjctNC42IDYuOS00LjkgOS44LTEuOCA1LjctMTYuMy0zLjctMTQuNyIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0zMC41IDE3Ni41di03LjlIMTIzdjcuOSIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0zMC41IDE3Ni41di03LjlIMTIzdjcuOSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik00NC4yIDE4Mi41Yy0uMS0uMy0uMS0uNi0uMi0uOS0uNiAyLjQtMS4zIDQuOS0xLjkgNy4zbC42LS42SDMyYzQuNSA1IDEwLjggNC41IDE2LjkgMy43IDcuNC0xIDE1LjMtMS4xIDIyLjctLjQgNy45LjcgMTUuNi0uMyAyMy40LS4xIDQuMS4xIDggLjUgMTIuMS4zIDIuOS0uMSA2LjItMS41IDguOS0uNSA5LjEgMy4zIDEzLTExLjIgNC0xNC41LTUuNy0yLTEyLjIuMS0xOC4xLjEtMy41IDAtNy0uNC0xMC41LS40LTQuMiAwLTguNC42LTEyLjYuNi03LjUuMS0xNC42LTEuMi0yMi4xLS42LTMuMi4yLTYuNC4yLTkuNi43LS45LjEtMS45LjMtMi44LjQtLjguMS0xLjYuMS0yLjQuMS0uNC0uMi0uMy0uMS41LjEtMi43LTMtNy45LTIuOS0xMC42IDAtMi41IDIuNi0zLjIgNS4yLTIuMyA4LjggMi41IDkuMyAxNyA1LjMgMTQuNy00LjEiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNNzYuNyAxNzYuNUgzMC41djE1LjdIMTIzdi0xNS43em01LTkyLjJjLTUzLjcgOC41LTUxLjMgODQuMy01MS4zIDg0LjMiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTEzLjQgNDguN2MxMy41LTIuNiAxNy4xLTEyLjIgMTcuMS0xMi4yLTcuOC0yMS40LTIzLjEtMzIuNi0yMy4xLTMyLjZTOTYuNSAxNC4yIDk2LjMgMTljMCAwLTE0LjMtOS40LTMyLjYtMS40IDAgMC0yMCAxMC40LTM2LjkgNC4zIDAgMC0yMS4yLTguNS0yMi42LTIuNyAwIDAtMy4zIDEwLjUgMi41IDIwLjUgMCAwIDUuOCA5LjMgOC40IDkuMyAwIDAgMjEuNiAyLjUgMTguNSAzLjUgMCAwLTEuNCA0LjYtMTYuMiAzLjggMCAwLTUuMy0uMS00LjMgNSAxIDUuMyA0LjggMTAuNSAxNS4xIDEyLjUgMCAwIDkuNyAyLjkgMjYgLjVzMTMgMTQuNCAxMyAxNC40IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTEyMC41IDc0LjNjMTMuNS43IDE5LjktNi4zIDE5LjktNi4zcy0zLjQtMTQuMi0xNC0yNS43IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTgwLjEgMzQuOGMwIDItMS42IDMuNi0zLjUgMy42cy0zLjUtMS42LTMuNS0zLjYgMS42LTMuNiAzLjUtMy42IDMuNSAxLjYgMy41IDMuNiIvPjxlbGxpcHNlIGN4PSI3Ni42IiBjeT0iMzQuOCIgZmlsbD0ibm9uZSIgcng9IjMuNSIgcnk9IjMuNiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNCIvPjxwYXRoIGQ9Ik03Ni4yIDMxLjJzLTMuOC0uMS03LjYgMy43Ii8+PHBhdGggZD0iTTc2LjIgMzEuMnMtMy44LS4xLTcuNiAzLjciIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjQiLz48cGF0aCBkPSJNMTM2LjggNzEuMmMxMS42IDE1LjcgMTMuMiAzMi45IDEzLjIgMzIuOXMtOS43IDYuNy0yNyAyLjkiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTIyLjcgMTQzLjFjMTcuMSA3LjMgMjguNyAxLjcgMjguNyAxLjdzMi40LTE5LjQtNS43LTM4LjhNMTIzIDE2OC42czIuMi0xOS42IDIyLTIyLjEiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTAzLjggMTE1LjFjLTEuMS44LS44LjcuNy0uNCAxLjMtLjkgMi44LTEuNiA0LjItMi4zIDMtMS41IDYuMi0yLjUgOS4zLTMuOCA1LjMtMi4zIDExLTUuOSAxNi44LTYgNy40LS4xIDEwLjQtMTAuMiAzLjgtMTQtNi4xLTMuNS0xMi44LTQuOC0xOS40LTYuOS03LjUtMi4zLTEzLjgtNi4yLTIwLjYtMTAtOC40LTQuOC0xNiA4LjEtNy42IDEzIDYuOCAzLjkgMTMuNCA3LjkgMjAuOCAxMC41IDYuMyAyLjIgMTMuMyAzLjEgMTkuMSA2LjUgMS4zLTQuNyAyLjUtOS4zIDMuOC0xNC04LjUuMi0xNS4xIDQuMS0yMi44IDcuMy02LjYgMi44LTE3LjggNS40LTIxLjIgMTIuNS00IDguOCA4LjkgMTYuNCAxMy4xIDcuNiIgZmlsbD0iI2ZmZiIvPjwvZz48L3N3aXRjaD48L3N2Zz4=')} +.is2d .bishop.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii00Ny44NSAtMTAgMjIwIDIyMCIgd2lkdGg9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHN3aXRjaD48Zz48cGF0aCBkPSJNMzAuOCAxNjguOEMxNyAxNTkuNSA3LjEgMTQzIDQuNSAxMjYuNCAxLjYgMTA4LjYgNyA5MC43IDE1LjMgNzUuMWM0LjYtOC41IDEwLjEtMTYuNSAxNi4xLTI0bDIyLjcgMzEgMTYtMTYuMy0yMy43LTMxLjVjNS01LjIgMTAuMy0xMC4xIDE1LjYtMTUgMTA5LjYgOTguMiAzMS4zIDE0OS41IDMxLjMgMTQ5LjUiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNMzAuOCAxNjguOEMxNyAxNTkuNSA3LjEgMTQzIDQuNSAxMjYuNCAxLjYgMTA4LjYgNyA5MC43IDE1LjMgNzUuMWM0LjYtOC41IDEwLjEtMTYuNSAxNi4xLTI0bDIyLjcgMzEgMTYtMTYuMy0yMy43LTMxLjVjNS01LjIgMTAuMy0xMC4xIDE1LjYtMTUgMTA5LjYgOTguMiAzMS4zIDE0OS41IDMxLjMgMTQ5LjUiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNNjkuOSAxMS40YzAgNC40LTMuNSA4LTcuOSA4LTQuMyAwLTcuOS0zLjYtNy45LThzMy41LTggNy45LThjNC4zLS4xIDcuOSAzLjUgNy45IDgiIGZpbGw9IiNmZmYiLz48ZWxsaXBzZSBjeD0iNjIiIGN5PSIxMS40IiBmaWxsPSJub25lIiByeD0iNy45IiByeT0iOCIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0xNS44IDE3Ni43di03LjloOTIuNXY3LjkiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNMTUuOCAxNzYuN3YtNy45aDkyLjV2Ny45IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTYyLjEgMTc2LjdIMTUuOHYxNS43aDkyLjV2LTE1Ljd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTYyLjEgMTc2LjdIMTUuOHYxNS43aDkyLjV2LTE1Ljd6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PC9nPjwvc3dpdGNoPjwvc3ZnPg==')} +.is2d .rook.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii02MC4yIC0xMCAyMjAgMjIwIiB3aWR0aD0iMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48c3dpdGNoPjxnPjxwYXRoIGQ9Ik05Ni4xIDE2OC45Qzk2IDExMCA4MC45IDY3IDgwLjkgNjdsMTUuMi04LjNWMy42SDcyLjl2MTUuN0g2MS40VjMuNkgzOC4ydjE1LjdIMjYuN1YzLjZIMy42djU1LjFMMTguOCA2N1MzLjcgMTEwIDMuNiAxNjguOSIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik05Ni4xIDE2OC45Qzk2IDExMCA4MC45IDY3IDgwLjkgNjdsMTUuMi04LjNWMy42SDcyLjl2MTUuN0g2MS40VjMuNkgzOC4ydjE1LjdIMjYuN1YzLjZIMy42djU1LjFMMTguOCA2N1MzLjcgMTEwIDMuNiAxNjguOSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0zLjYgMTc2Ljd2LTcuOGg5Mi41djcuOCIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0zLjYgMTc2Ljd2LTcuOGg5Mi41djcuOCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik00OS44IDE3Ni43SDMuNnYxNS43aDkyLjV2LTE1Ljd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTQ5LjggMTc2LjdIMy42djE1LjdoOTIuNXYtMTUuN3oiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTguOCA2N2g2Mi4xTTMuNiA1Ny44aDkyLjUiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjQiLz48L2c+PC9zd2l0Y2g+PC9zdmc+')} +.is2d .queen.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii0xNC4xIC0xMCAyMjAgMjIwIiB3aWR0aD0iMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48c3dpdGNoPjxnPjxwYXRoIGQ9Ik0xNDIuMSAxNjcuM3MuNi03LjMtMy42LTguMmMtMjMuOC00LjYgMzYuOS05Ni40IDM2LjktOTYuNHMtNTUuMiA2Mi4xLTUxLjgtNDUuNWwtLjgtLjVjLTI3LjggOTguMS01My43IDAtNTMuNyAwbC0xIC42YzMuNCAxMDcuNi01MS44IDQ1LjUtNTEuOCA0NS41czYwLjcgOTEuOCAzNi45IDk2LjRjLTQuMi44LTMuNiA4LjItMy42IDguMiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0xNDIuMSAxNjcuM3MuNi03LjMtMy42LTguMmMtMjMuOC00LjYgMzYuOS05Ni40IDM2LjktOTYuNHMtNTUuMiA2Mi4xLTUxLjgtNDUuNWwtLjgtLjVjLTI3LjggOTguMS01My43IDAtNTMuNyAwbC0xIC42YzMuNCAxMDcuNi01MS44IDQ1LjUtNTEuOCA0NS41czYwLjcgOTEuOCAzNi45IDk2LjRjLTQuMi44LTMuNiA4LjItMy42IDguMiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik00OS41IDE3Ni4zdi03LjloOTIuNnY3LjkiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNNDkuNSAxNzYuM3YtNy45aDkyLjZ2Ny45IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTc0LjMgOS44Yy45IDUuNC0zLjcgMTAtOSA5LjEtMy4yLS41LTUuOC0zLjItNi4zLTYuNS0uOS01LjQgMy43LTEwIDktOS4xIDMuMS42IDUuNyAzLjIgNi4zIDYuNSIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik03NC4zIDkuOGMuOSA1LjQtMy43IDEwLTkgOS4xLTMuMi0uNS01LjgtMy4yLTYuMy02LjUtLjktNS40IDMuNy0xMCA5LTkuMSAzLjEuNiA1LjcgMy4yIDYuMyA2LjV6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTE4LjYgNTYuM2MuOSA1LjQtMy43IDEwLTkgOS4xLTMuMi0uNS01LjgtMy4yLTYuMy02LjUtLjktNS40IDMuNi0xMCA5LTkuMSAzLjIuNiA1LjggMy4yIDYuMyA2LjUiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNMTguNiA1Ni4zYy45IDUuNC0zLjcgMTAtOSA5LjEtMy4yLS41LTUuOC0zLjItNi4zLTYuNS0uOS01LjQgMy42LTEwIDktOS4xIDMuMi42IDUuOCAzLjIgNi4zIDYuNXoiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNNTggMTU2LjloNzUuNiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNSIvPjxwYXRoIGQ9Ik0xMTcuNCA5LjdjLS45IDUuNCAzLjcgMTAgOSA5LjEgMy4yLS41IDUuOC0zLjIgNi4zLTYuNS45LTUuNC0zLjYtMTAtOS05LjEtMy4yLjYtNS44IDMuMi02LjMgNi41IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTExNy40IDkuN2MtLjkgNS40IDMuNyAxMCA5IDkuMSAzLjItLjUgNS44LTMuMiA2LjMtNi41LjktNS40LTMuNi0xMC05LTkuMS0zLjIuNi01LjggMy4yLTYuMyA2LjV6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTE3MyA1Ni4yYy0uOSA1LjQgMy43IDEwIDkgOS4xIDMuMi0uNSA1LjgtMy4yIDYuMy02LjUuOS01LjQtMy43LTEwLTktOS4xLTMuMi42LTUuOCAzLjItNi4zIDYuNSIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0xNzMgNTYuMmMtLjkgNS40IDMuNyAxMCA5IDkuMSAzLjItLjUgNS44LTMuMiA2LjMtNi41LjktNS40LTMuNy0xMC05LTkuMS0zLjIuNi01LjggMy4yLTYuMyA2LjV6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTk1LjggMTc2SDQ5LjV2MTUuN2g5Mi42VjE3NnoiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNOTUuOCAxNzZINDkuNXYxNS43aDkyLjZWMTc2eiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0xNjQuNiA3Ni40bC02Ny41IDc4LjljLS40LjUtMS4zLjItMS4zLS41bC0yNS4yLTEyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNCIvPjxwYXRoIGQ9Ik0xMjAuNyAzMC44TDk2LjYgMTUzLjNjLS4zIDEuNC0yLjEgMS45LTMgLjhMMjYuOSA3Ni41IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI0Ii8+PC9nPjwvc3dpdGNoPjwvc3ZnPg==')} +.is2d .king.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii0xNC4xNSAtMTAgMjIwIDIyMCIgd2lkdGg9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHN3aXRjaD48Zz48cGF0aCBkPSJNOTUuOSAxNzYuNkg0OS42djE1LjdoOTIuNXYtMTUuN3oiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNOTUuOSAxNzYuNkg0OS42djE1LjdoOTIuNXYtMTUuN3oiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNNDkuNiAxNjguN3Y3LjloOTIuNXYtNy45IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTQ5LjYgMTY4Ljd2Ny45aDkyLjV2LTcuOSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0xMDMuNSA2OC43VjQyLjhoMjMuMlYyN2gtMjMuMmwuMS0yMy42SDg4LjFWMjdINjV2MTUuN2gyMy4xdjI2IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTEwMy41IDY4LjdWNDIuOGgyMy4yVjI3aC0yMy4ybC4xLTIzLjZIODguMVYyN0g2NXYxNS43aDIzLjF2MjYiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTg3LjEgNzUuOWMtNy4xLTI4LjctMzQuNS0zMS43LTM0LjUtMzEuNy0zOC41LTUuNC01Ni4zIDM2LjgtNTYuOCAzNy45LS40LTEtMTguMy00My4zLTU2LjgtMzcuOSAwIDAtMjcuNCAzLTM0LjUgMzEuNyAwIDAtMTMuOCA1MS44IDQ1IDkyLjhIMTQyYzU4LjktNDAuOSA0NS4xLTkyLjggNDUuMS05Mi44IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTE4Ny4xIDc1LjljLTcuMS0yOC43LTM0LjUtMzEuNy0zNC41LTMxLjctMzguNS01LjQtNTYuMyAzNi44LTU2LjggMzcuOS0uNC0xLTE4LjMtNDMuMy01Ni44LTM3LjkgMCAwLTI3LjQgMy0zNC41IDMxLjcgMCAwLTEzLjggNTEuOCA0NSA5Mi44SDE0MmM1OC45LTQwLjkgNDUuMS05Mi44IDQ1LjEtOTIuOHoiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTQ3LjMgNjcuNGMtMjUuMS0yLjItNDMuNiA1MC45LTQzLjYgNTAuOXYzMi44czI2LjItLjYgNDYuNi0yMS44YzIwLjQtMjEuMyAyMi4xLTU5LjctMy02MS45em0tMTAzIDBjLTI1LjEgMi4yLTIzLjQgNDAuNi0zIDYxLjlzNDYuOCAyMS44IDQ2LjggMjEuOHYtMzIuOHMtMTguNy01My00My44LTUwLjl6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTk1LjggMTkuMXYzOS40TTgwLjQgMzQuOWgzMC45IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI0Ii8+PHBhdGggZD0iTTg4LjEgNjguN2gxNS40IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PC9nPjwvc3dpdGNoPjwvc3ZnPg==')} +.is2d .pawn.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii01Ny4xIC0xMCAyMjAgMjIwIiB3aWR0aD0iMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48c3dpdGNoPjxnPjxwYXRoIGQ9Ik01Mi44IDE3Ni4zSDYuNVYxOTJoOTIuNnYtMTUuN0g2LjV2LTcuOWMyOS40LTM2LjcgMjcuMi02Mi4xIDIyLTc1LjUtMi44LTcuMy02LjUtMTEtNi41LTExaDYxLjRTNTMuNyAxMTEuOCA5OSAxNjguNHY3LjkiLz48cGF0aCBkPSJNNTIuOCAxNzYuM0g2LjVWMTkyaDkyLjZ2LTE1LjdINi41di03LjljMjkuNC0zNi43IDI3LjItNjIuMSAyMi03NS41LTIuOC03LjMtNi41LTExLTYuNS0xMWg2MS40UzUzLjcgMTExLjggOTkgMTY4LjR2Ny45IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTgzLjUgMzQuNWMwIDE3LjMtMTMuOCAzMS40LTMwLjggMzEuNHMtMzAuOC0xNC0zMC44LTMxLjRDMjIgMTcuMiAzNS43IDMuMiA1Mi43IDMuMnMzMC44IDE0IDMwLjggMzEuMyIvPjxlbGxpcHNlIGN4PSI1Mi43IiBjeT0iMzQuNSIgZmlsbD0ibm9uZSIgcng9IjMwLjgiIHJ5PSIzMS40IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTUyLjggNjUuOXMzMyAuMSA0Ni4yIDE2SDYuNmMxMy4yLTE1LjkgNDYuMi0xNiA0Ni4yLTE2Ii8+PHBhdGggZD0iTTUyLjggNjUuOXMzMyAuMSA0Ni4yIDE2SDYuNmMxMy4yLTE1LjkgNDYuMi0xNiA0Ni4yLTE2IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTMwLjEgOTcuN2g0NS40IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTMwLjEgOTcuN2g0NS40IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI0Ii8+PHBhdGggZD0iTTYuNSAxNjguNGg5Mi42IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTYuNSAxNjguNGg5Mi42IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTkuMSAxNzIuM2g4Ny40IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTkuMSAxNzIuM2g4Ny40IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIyIi8+PC9nPjwvc3dpdGNoPjwvc3ZnPg==')} +.is2d .knight.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii0zMi40NSAtMTAgMjIwIDIyMCIgd2lkdGg9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHN3aXRjaD48Zz48cGF0aCBkPSJNOTcuOCAxNzAuNWM5LjcgMCA5LjctMTUgMC0xNXMtOS43IDE1IDAgMTVNMzkgMzAuNmMtMi0zLTQuNS00LjQtNy44LTUuNy0zLjUtMS4zLTYuNS0zLjQtMTAtNC43LTYuNy0yLjUtMTguNC01LjQtMTkgNS41LS4yIDMuMSAxLjIgNS44IDIuMyA4LjdDNiAzOC4xIDcuNSA0MiAxMC4zIDQ1YzIuNiAyLjkgNS42IDQuNSA5LjIgNS45IDEuOS44IDQuNy44IDYuNy4zIDEuMS0uMiAyLjEtLjYgMy4xLTEuMSAxLjYtLjggMS44LS45LjYtLjQgMi45LTEuMiA1LjktMy43IDUuNS03LjItLjYtNS41LTQuNC05LjEtOS41LTEwLjctNi44LTIuMS0xMy4zIDcuNy03LjMgMTIuNUMyNC40IDQ5IDM0LjggNTkgNDEuNCA0OS42YzQuOS02LjktMS4yLTE3LjYtNS4yLTIzLjMtMi44IDMuNy01LjYgNy4zLTguNSAxMSAzLjcuNyA3IDMuMSAxMC44IDMuOCA1LjYuOSAxMS4xLTEuMSAxMy42LTYuNSAxLjktNC4xLjctMTAtNC41LTExLTIuNy0uNS01LS4zLTcuNy0uMy05LjcuMS05LjcgMTUgMCAxNSA3LjYgMCAxNC45LS43IDIxLjEtNS41IDIuNi0yIDYuNy0xLjggOS44LTIuNiA0LjgtMS4zIDguMS0yLjYgMTMtMS4yIDYuNCAxLjggMTEuNCA2LjEgMTguNCA0LjYgMy42LS44IDYuMy00LjIgNy4xLTcuNi41LTIuMS4xLTQtLjItNi0uNyAxLjgtLjYgMi4xLjIgMSAuOS0uNi44LS43LS40LS4yLTEuMy0uMy0yLjUtLjctMy44LTEgMS4yLjYgMi40IDQuNiAzLjUgNi4yIDIuMSAzLjEgNC4zIDYgNi4yIDkuMmwuOSAxLjgtLjEtLjFjLjUgMi43IDEuNSAxLjEgMi45LTQuNi0yIC44LTQuMiAxLjEtNi4yIDEuOSAxLjMtLjUgMS45IDMuMi4yLS42LS40LTEtLjctMi4xLTEtMy4yLS42LTIuNSAyLjItLjEtMS43IDIuMS0xLjMuMy0yLjUuNy0zLjggMS0zLjkuNS0xLjgtNS0uOC01LjgtMS43IDEuMi0zLjUgMi40LTUuMiAzLjUtMy40IDIuMi03IDQuMS0xMC41IDYuMS03LjQgNC4zLTE0LjQgOS4zLTIxLjYgMTMuOS02LjkgNC40LTEzLjEgOS4zLTIxLjIgMTEtMy45LjktNy43LS41LTExLjQtMS43LTMuOS0xLjMtOC4yLTEuOC0xMS42LTQuMS0xLjMgNC43LTIuNSA5LjMtMy44IDE0IDkuNCAxLjIgMTYuMy0xLjEgMjMuNy03LjEgMy41LTIuOSA2LjItNi4yIDYuNS0xMC45LjItMi4xLS4yLTQuMS0uOC02LjEtLjItLjUtLjQtMS0uNi0xLjYtLjEtLjMtLjItLjYtLjItLjkuMSAxLjYtLjUgMi45LTEuOSAzLjktMS4zLjMtMi41LjctMy44IDEgMi41LS4xIDEuNi0uOS0yLjgtMi40LS40LTIuMi0uNi0yLjYtLjUtMS4yIDAgLjktLjEgMS0uNCAyLjQtLjYgMi43LTEuNiA1LjQtMi4zIDguMS0yLjEgNy4yIDEuNCAxNiAxMC40IDEzLjcgMy40LS45IDYuMi00LjMgOC4yLTYuOSAzLjEtMy45IDQuOC04LjYgNS4xLTEzLjUuMS0yIDAtNC0uMS02di00LjJjMC0uNi4xLTEuMy4xLTEuOSAwIC4xIDAgLjMtLjEuNC42LTItLjMtMS4xLTIuNyAyLjgtMS4zLjMtMi41LjctMy44IDFoLjRjLTEuMy0uMy0yLjUtLjctMy44LTEgLjkuNCAzLjggMy41IDMuOSA1LjcuMiAyLjQtLjggNS4yLTEuMSA3LjYtLjMgMy4zLjkgNi44IDIuNiA5LjUgMy43IDYgMTEuMyA0IDEzLjctMS44IDMuMi03LjggMy45LTE2LjIgMy4zLTI0LjUtLjEtLjktLjEtMS43IDAtMi42LTQuNSAyLTUuNSAzLjItMi43IDMuNS40LjEuOS4yIDEuMy40IDEuOCAxLjIgMS41LjEtLjktMy4yLS41IDIuNC0yLjEgNC45LTMgNy4yQzY0LjggNDkuMyA3MS4xIDU3IDc5IDUzLjJjMy40LTEuNiA1LjgtNC42IDguMS03LjYgMS4yLTEuNiAyLTMuNCAyLjctNS4yLjQtLjguNy0xLjcgMS0yLjUgMS0yLjcgMi4xLTMuMS0xLS44LTEuMy4zLTIuNS43LTMuOCAxLTIuMy4yLTEuNi0uNS0uMS43IDEuMiAxIDIuNCAxLjkgMy44IDIuOCAzLjEgMi4xIDYuNCAxLjMgOS43LjVsLTkuMi05LjJjLS43IDQuOS0xLjggOS42LTEuOCAxNC42LS4xIDMuOC0zLjIgNi4yLTUuNiA4LjgtMi45IDMuMS01LjUgNi43LTcuOCAxMC4zLS44IDEuMy0xLjUgMi43LTIuMSA0LjItLjMuNi0uNSAxLjItLjggMS44LTEuMyAyLjctMS42LjcgMS4yLjFoNGMyLjYgMy4xIDMuNCAzLjUgMi42IDEuMi0uNC0xLjUtMS0yLjgtMS44LTQuMXMtMi0yLjQtMy4zLTMuMmMtMi40LTEuNi0xLjItMS45IDAgMS4zdjRjLjEtLjMuMi0uNS4zLS44IDEuMy0zLjktMS40LTguMi01LjItOS4yLTEuMi0uMy0yLjUtLjQtMy43LS45LjYgNC42IDEuMiA5LjEgMS44IDEzLjcgNS4zLTMgMTEuMS01IDE2LjMtOC0zLjgtMi4yLTcuNS00LjMtMTEuMy02LjUuMyAyLjktMS40IDYuMy0yLjUgOC45LS45IDIuMS0xLjcgNC4xLTIuMSA2LjMtLjIgMS0uMyAyLjEtLjIgMy4xLjItLjYuNC0xLjEuNi0xLjdMNjcgNzkuMmMtNS40IDggNy42IDE1LjUgMTMgNy42IDEuMi0xLjggMi4yLTMuMSAyLjktNS4yLjQtMS4zIDAtMi41LjMtMy44LjMtMS41IDEuMS0zIDEuNy00LjUgMS42LTQuMSAzLjgtOC43IDMuMi0xMy4yLS43LTUuNC01LjktOS42LTExLjMtNi41LTUuMyAzLjEtMTEgNS4xLTE2LjMgOC02LjEgMy40LTQgMTEuNiAxLjggMTMuNyAxLjIuNSAyLjUuNSAzLjcuOS0xLjctMy4xLTMuNS02LjItNS4yLTkuMi0xLjIgMy42LjEgNi44IDIuNiA5LjVsMi40IDEuOGMxLjMuOSAxLjIuOC0uMS0uNS42IDEuOCAxLjEgMy41IDIuMiA1LjEgNS4zIDcuNyAxMy45IDQgMTcuNS0yLjkgMS42LTIuOSAyLjgtNS44IDQuNy04LjYgMi4yLTMuMiA1LjEtNS45IDcuNy04LjkgNi41LTcuMyA2LjEtMTYuNSA3LjMtMjUuNy44LTUuNy0zLjEtMTAuNi05LjItOS4yLTIuNS42IDIuNyAxLjcuMi0uMi0xLjQtMS4xLTIuOC0yLjItNC40LTMuMS0yLjktMS43LTYuOC0xLjgtOS41LjItMy4zIDIuNC00LjEgNS43LTUuMyA5LjQtLjUgMS41LTEuMyAyLjgtMi4yIDQuMi0uNyAxLjEtMi45IDEuNy0xLjQgMS41IDEuOS4zIDMuOS41IDUuOC44bDIuMyAyLjJjLjMgMS4zLjcgMi41IDEgMy44LjEgMS45IDAgLjMuMi0uNS4zLS44LjQtLjkuOS0yIDEuMi0yLjYgMi43LTUuNCAyLjctOC4zLS4xLTcuNi02LjctMTItMTMuNy0xMy04LjctMS4yLTEzLjcgNC4yLTE0IDEyLjYtLjEgMyAuNSA1LjkuMyA4LjktLjMgNC41LTEuMyA4LjgtMyAxM2wxMy43LTEuOGMtMS41LTIuNC40LTYuOC41LTkuNi4yLTMuNS0xLjEtNy4xLTMtMTAtMy00LjQtMTAtMTMuNC0xNi4zLTguNy01LjIgMy45LTQuOSAxMC00LjggMTUuOSAwIDEuNy4zIDQuMi4xIDUuNi0uMiAxLjYtLjcgMy4zLTEuNyA0LjUtLjggMS0zLjcgMi43LTEuNCAyLjEgMS45LjMgMy45LjUgNS44LjhsLS42LS4zIDMuNCA0LjVjLjMuNy0uNiAyLjYtLjEuNC4zLTEuMS42LTIuMi45LTMuMi44LTIuNSAxLjUtNC45IDItNy41IDEuMi02LjYtLjItMTMuNS03LjMtMTUuNy05LjYtMi45LTE0LjMgNy0xMi40IDE0LjcuMi41LjMgMS4xLjUgMS42LjQgMS44LjYgMS45LjUuNC0xLjIgMS40LTMuMSAyLjctNC42IDMuNy0zLjQgMi40LTcuMSAxLjUtMTAuOCAxLTguMS0xLTkuMiAxMC4yLTMuOCAxNCA1LjMgMy43IDEyLjUgNC44IDE4LjYgNi44IDcuNSAyLjQgMTUuNiAxLjMgMjIuOS0xLjMgNi40LTIuMyAxMi4yLTcgMTcuOS0xMC42IDYuNy00LjIgMTMuMi04LjggMjAuMS0xMi45IDkuNC01LjcgMjktMTIuNyAyMS0yNi45LTMuMS01LjQtOS43LTcuNC0xNS4xLTQuM3MtNS4zIDEwLjEtNC4xIDE1LjRjMS4xIDQuNiAzLjggOS41IDcuNyAxMi4zIDUuMiAzLjggMTMuMS44IDE4LjUtMS40IDEyLjItNS4xIDUuNC0xNy4zIDAtMjQuOS01LjMtNy40LTkuNi0yMC4zLTIxLjMtMTMuOC01LjUgMy4xLTkuMSA5LjEtNy45IDE1LjQuNyAzLjcgNy4yLTMuMSAzLjQtNC4zLTEtLjMtMi0uOS0zLTEuNC0zLjMtMS42LTYuOC0yLjgtMTAuNC0zLjYtOC40LTEuOS0xNS45IDIuMi0yNCAzLjMtMy43LjUtNi4yIDIuNC05LjIgNC41LTMuMiAyLjItNy43IDEuOC0xMS4zIDEuOHYxNWMxLjEgMCAyLjYtLjUgMy43LS4yLTEuNS0zLjctMy03LjMtNC41LTExLTEuMyAyLjguNC0uOCAyLjQtLjUtMS4xLS4yLTIuMi0uNi0zLjItMS0yLjItLjktNC4zLTIuMS02LjctMi42LTUuOC0xLjEtMTIuNiA1LjEtOC41IDExIDEgMS40IDIuNSAyLjcgMy4xIDQuMi40IDEgLjggMiAxLjEgMyAuNyAyLjEtLjEgMi43IDEuMSAxbDQuNS0zLjRjLS4yLjEtLjUuMS0uNy4yaDRjLTIuNi0uNi01LTMuNC03LTUuMS0yLjQgNC4yLTQuOSA4LjQtNy4zIDEyLjUuNC4xLjIgMC0uNS0uNC0uMy0xLjMtLjctMi41LTEtMy44di40YzEuOC0yLjQgMy43LTQuOCA1LjUtNy4yLS43LjMtMy4xIDEuMS0yLjQgMS4yLTEuNC0uMy0yLjMtMS43LTIuOS0yLjctMS4yLTEuOS0zLjQtNi44LTMuMy04LS4zIDEuMy0uNyAyLjUtMSAzLjguMS0uMi4yLS4zLjMtLjVMMTIgMzIuNGMtMi42IDEuMS44IDEgMiAxLjMgMi4xLjUgMy43IDEuNSA1LjYgMi41IDEuOCAxIDMuNiAxLjggNS41IDIuNSAyLjQuOSAyLjQgMS42LjktLjUgNS40IDcuOSAxOC40LjQgMTMtNy42Ii8+PHBhdGggZD0iTTEwMS44IDU0YzMuNCAxLjMgNi4yIDMuOCAxMC4xIDMuOCAyLjIgMCA0LjQtLjMgNi41LS44LjgtLjIgMS43LS40IDIuNS0uNC0yLjEtMS4xLTIuNS0xLTEuMi4xIDEuOCAxLjggMi43IDUuMiAzLjcgNy41LjQgMSAuOSAxLjkgMS4zIDIuOC0xLjYtNC4yIDUuMi01LjguMy00LjEtMy4zIDEuMS02LjUgMS44LTkuNyAzLjItMy44IDEuNi03LjQgMy44LTExIDUuOS0zLjUgMi03IDQuMS0xMC43IDUuNS0xLjkuOC00IDEuMi02IDEuNy44LS4xLjYtLjEtLjUgMC0yLjEtLjItMS41LjQgMS43IDEuNi4zIDEuOS41IDMuOS44IDUuOC42LTIuNiA0LjUtNi4yIDYuNS04LjUgMy41LTQgNS4zLTguNCA3LjYtMTMuMiAxLjktMy45IDQtMSA3LjYuMyAxLjQuNSAyLjkgMSA0LjMgMS41LjQuMi45LjMgMS4zLjUgMS45LjggMS44IDEuOS4zLS42LS4zLTEuMy0uNy0yLjUtMS0zLjguMi0xLjUuOC0yLjcgMS44LTMuNS0uOC41LS43LjQtMS42LjctMS45LjctMy44IDEuMS01LjcgMS41LTUuMyAxLjItMTAuMSAzLjItMTUgNS40IDMgMy45IDYuMSA3LjkgOS4xIDExLjggMS0xLjEgMi0yLjMgMy0zLjUuNy0uOCAxLjQtMS41IDIuMS0yLjMgMS4zLTEgMS42LTEuMy44LS45LTEuOS0uMy0zLjktLjUtNS44LS44LTIuNS0xLjItMi4zLTIuNS0uNi4xLjggMS4zIDEuOCAyLjMgMi45IDMuMyAyLjMgMi4xIDUgMy4yIDcuOCA0LjQgNC42IDEuOSA5LjkgMS4zIDEyLjggNS45IDEuNCAyLjMgMi41IDQuOCAzLjggNy4yLjcgMS4yIDEuNCAyLjQgMS45IDMuNy4xLjUuMyAxIC40IDEuNSAwIDIuMiAxLjEgMS43IDMuNC0xLjMtMS42LjEtMy40LS42LTUtLjgtNC4xLS42LTguMi0uMy0xMi4yLS44IDEuOCA0LjMgMy41IDguNSA1LjMgMTIuOCAxLjMtMS4yIDMuMi0xLjkgNC42LTMgMi42LTIgNC43LTQuNiA1LjgtNy43IDItNS41LS40LTEwLjQtMy45LTE0LjYtNi03LjItMjIuMS0xMS4zLTI0LjggMS40LTEuOSA4LjggNC4xIDE1IDguNCAyMS45IDIuMiAzLjYgMi43IDguMyA0LjEgMTIuMyAxLjkgNSA0LjkgOS4xIDkuNSAxMS45IDIuMSAxLjMgNS41IDEuNSA3LjYgMCA1LjktNC40IDguMy0xMC40IDguOS0xNy42LjctOC42LTguNC0xMy4zLTE1LjMtOS4xLTQuNiAyLjgtNS4yIDEwLjQgMCAxMyAxLjQuNyAyLjYgMS4zIDQuMSAxLjUgMS4xLjIgMi4yLjMgMy4yLjMtMi42LTIuMy0zLjMtMi42LTIuMS0uOCAxLjQgMi42IDEuNCA3LjQgMS43IDEwLjMuMiAxLjkuNCAzLjguNiA1LjYuMi44LjMgMS43LjMgMi41IDMuNi0yLjMgNC4xLTMuMyAxLjYtMy00IDAtNy43IDAtMTEuNy42LTUuNi45LTE0IDIuNS0xNS43IDguOC0yLjUgOC45IDYuNCAxMS40IDEyLjYgMTMuOS0xLjEtNC4yLTIuMi04LjQtMy4zLTEyLjUtMi40IDIuNC00LjQgNS4xLTYuNCA3LjgtLjggMS4yLTEuOCAyLjMtMi44IDMuM2wxLjUtLjNjLS43LS4zLTEuNS0uNi0yLjMtLjgtOS4zLTMtMTIuOSAxMS4xLTQgMTQuNSA0LjEgMS41IDEwLjQgNC4yIDE0LjctLjYgNC44LTUuMy42LTExLjYtLjctMTcuMy0yLjEtOC45IDEzLjYtMTEuNiAxOS0xMy41IDYuNC0yLjIgNy4xLTkuOSAxLjgtMTMuNy0zLjQtMi40LTgtMi4yLTEyLTIuMS0xLjggMC0xMS0uNi0xMS41LTEuNy0yLjUtNi0yLjMtMTMtMi45LTE5LjMtLjUtNS41LS45LTEzLjItNC4xLTE3LjktMy45LTUuOS0xNC4zLTQuMS0xNCAzLjguMiA2LjQgNCAxMi45IDYuOCAxOC42IDEuNSAzIDMuNSA1LjcgNS42IDguNCAxIDEuMyA0LjYgNC43IDQuNSA2LjEuMy0xLjMuNy0yLjUgMS0zLjggMS0uNy45LS43LS40LjFsLTIuMSAxLjJjLTIuMSAxLjItNC4xIDIuOS02IDQuNS00LjQgMy43LTYuMiA4LjQtNi45IDEzLjktLjYgNS0uNiAxMC42LjQgMTUuNS42IDIuOC0uOCA2LjUtMyA4LjgtNi43IDcgMy45IDE3LjYgMTAuNiAxMC42IDQuOC01IDguOC0xMy40IDcuNS0yMC40LS44LTQuMy0uOC04LjQtLjctMTIuOC4xLTQgMy40LTUuOSA2LjYtNy44IDMuMy0xLjkgNi41LTMuOSA3LjYtNy44IDEuMi00LjQtMS04LjYtMy41LTEyLjEtMi41LTMuNi01LjQtNi42LTcuNi0xMC40LTEuOS0zLjItNS41LTguNy01LjYtMTIuNS00LjcgMS4zLTkuMyAyLjUtMTQgMy44IDEuMyAyIDEuMSA1IDEuNSA3LjMuNiAzLjMuOCA2LjYgMSAxMCAuNSA2LjYgMS4yIDE0LjUgNC44IDIwLjMgMy4yIDUuMiA5LjUgNi44IDE1LjEgNy43IDIuOS41IDYgLjkgOSAuOSAxLjIgMCA0LjQgMCA0LjQuMS42LTQuNiAxLjItOS4xIDEuOC0xMy43LTkuNCAzLjItMjAuMiA1LjctMjYuMiAxNC4zLTMuMiA0LjYtNC40IDEwLjQtMy41IDE2IC40IDIuNyAxLjIgNS4xIDIuMiA3LjYgMS44IDQuMiAxMC4zLTMuNiA2LTUtMS4yLS40LTIuMy0xLTMuNS0xLjQtMS4zIDQuOC0yLjcgOS42LTQgMTQuNSA1LjMgMS43IDkuNyAyIDE0LjItMS44IDQuMS0zLjUgNi40LTguNCAxMC4zLTEyLjEgNC41LTQuMyAxLjctMTAuNS0zLjMtMTIuNS0uNi0uMy0xLjItLjUtMS45LS43bC0xLjItLjNjLTEuNy0uNi0xLjYtLjUuMi41LjMgMS4zLjcgMi41IDEgMy44di0uN2MtLjMgMS4zLS43IDIuNS0xIDMuOC0uOSAxLjQtMyAyLS45IDEuNi44LS4yIDEuNS0uMyAyLjMtLjUgMy40LS45IDYuMy0xLjYgOS45LTEuNCA3LjUuMyAxNC42LTEuOSAxNS43LTEwLjUuNC0zLjEtLjQtNi4zLS43LTkuNS0uNC00LjEtMS4xLTguMS0xLjgtMTIuMS0uNS0yLjktMS45LTcuMy00LjQtOS4yLTEuMy0xLjEtMi40LTIuMS00LjEtMi42LS45LS4zLTQuNS0uNS00LjEtLjR2MTNjLjQtLjIuOC0uNSAxLjItLjctMS4zLjMtMi41LjctMy44IDEgLjMgMCAuNy0uMSAxLS4xLTEuMy0uMy0yLjUtLjctMy44LTEtMi45LTEuNC0xLjQtNC44LTIuMi0xLjMtLjIuNy0uOCAyLjYtMS4yIDIuOWg3LjZjLTMuNi0yLjItNC4xLTcuNy01LjItMTEuNS0xLjQtNC44LTMuOC04LjUtNi42LTEyLjUtMS4xLTEuNS0yLjMtMy4xLTMtNC44LS42LTEuNC0uMS0uOS0uOC43LTEuNCAzLjMtNS40LjEtMi4xIDIuMS45LjUgMS42IDEuNCAyLjMgMi4yLjkuOS0uNC4zLjItLjctMSAxLjctNS4yIDMuMy02LjcgNC43LTUuMiA1LS44IDEyLjEgNS4zIDEyLjggNC40LjUgOC43LjQgMTMuMSAxLjEgNC43LjggOS4xLjQgMTIuNy0zLjEgOC4zLTguMi0uNy0yMi4zLTUuMS0zMC4xLTIuMy00LTUuNy03LjQtOS45LTkuMi00LjQtMS45LTkuNC0yLjEtMTMuNi00LjUtMS4zLS43LTEuOS0yLjktMi45LTMuOS0yLTItNS4xLTIuOS03LjgtMi4yLTUuNCAxLjUtOC45IDYuNS0xMi41IDEwLjUtNS45IDYuNyAxLjQgMTUuMiA5LjEgMTEuOCA0LjEtMS44IDgtMy4yIDEyLjMtNC4xIDMuNy0uOCA3LjUtMS45IDEwLjctNCA0LjEtMi43IDYuNy04LjIgMy45LTEyLjgtMS43LTQuMy02LjctNS44LTEwLjktNy4zLTQtMS40LTguMS00LjItMTIuNC00LjItNi43IDAtMTIuMiAzLjktMTUuNSA5LjYtMS4yIDIuMi0yIDQuNi0zLjEgNi45LTEuMyAyLjYtMy40IDQuNi01LjMgNi44LTMuMyAzLjctOC44IDEwLjEtNy4zIDE1LjUgMy41IDEyLjcgMjAuOCA2LjQgMjguNiAyLjggNS4yLTIuNCAxMC01LjYgMTUtOC4zIDQuOC0yLjYgMTAtMy4zIDE0LjktNS42IDEwLjktNS4xIDMuOS0xNy41LS4zLTI1LjEtMi41LTQuNS02LjMtOC4xLTExLjYtOC43LTIuOS0uNC01LjYuNy04LjQgMS0yLjIuMy01LjYtMi40LTcuNy0zLjItMy44LTEuNS04LjIgMS42LTkuMiA1LjItMS4xIDQuNCAxLjUgNy45IDUuMyA5LjMiLz48cGF0aCBkPSJNNzUuNSA4MS4zYy01LjUuOS0xMC43IDYuNS0xNS4xIDkuNy01LjggNC4yLTEwLjUgOS4zLTE0LjUgMTUuMi00IDUuNy02LjcgMTIuMS05LjMgMTguNi0yLjkgNy4xLTUuNiAxNC4xLTYuNSAyMS43LS40IDMuMi4xIDYuNi0uOCA5LjYtLjggMi44LTEuMSA1LjkuNCA4LjUgNC41IDcuNyAxMi4zIDMuMiAxOC43IDIuOCAxNC43LS44IDI5LjUgMy45IDQ0LjEgMS40IDE1LjktMi44IDE1LjUtMjEuMyAxNy41LTMzLjYgMi4yLTEzLjYgNy4zLTMwLjEuOC00My4zQzEwMi45IDc1LjggODUgODkgNzUgOTUuMWMtMTEuOCA3LjItMjIuNCAxOC4yLTI4LjIgMzAuOS0zLjkgOC41LTEwLjcgMTkuOC0zLjEgMjguMSA1LjUgNiAxNC4zIDcuMiAyMS45IDguMiA5LjYgMS4yIDIyLjggMyAzMS4yLTIuNyA4LjktNi4xIDEzLjctMTguNiAxNS4yLTI4LjggMS40LTkuOSAxLjUtMjEuNi0yLTMxLjEtMS45LTUuMy01LjMtOC45LTEwLjUtMTEtNS44LTIuMy0xMi4xIDIuMy0xNi41IDUuNC05LjcgNi44LTE0IDE5LTIxLjcgMjcuNy00LjMgNC44LTkgOS4zLTEzLjYgMTMuOC0zLjkgMy44LTcgOC40LTEwLjMgMTIuMi01IDUuOS0uMiAxMy45IDcuMyAxMi41IDcuMy0xLjMgMTMuNi01IDIwLjUtNy42IDcuNC0yLjggMTQuMS0xLjEgMjEuNi0uMSAxNC45IDIgMTcuNS0xNC45IDE4LjUtMjUuOC43LTcuMiAxLjctMTYuMS0uNy0yMy0yLjUtNy41LTEwLjgtOC4xLTE2LjMtMy40LTQuNCAzLjgtNy41IDkuMi0xMC41IDE0LjEtMi4xIDMuNC00LjIgNi44LTYuOCA5LjgtMi4xIDIuNS02LjIgNC04LjggNi4xLTMuOSAzLjEtMi4zIDkuNSAxLjUgMTEuOCAzLjYgMi4yIDggMS44IDEyLjEgMiA1LjMuMyAxMC4zLS41IDE0LjgtMy4zIDcuNC00LjUgNi45LTE2LjcgMy4zLTIzLjYtNC40LTguNi0xNy40LTEtMTMgNy42LS42LTEuMiAwIDEuOCAwIDIgMCAuOC4xIDEuNi4yIDIuNCAwIDEuOC4yIDEuNi42LS42LTEuNyAxLTQuMy42LTYuMS41LS43IDAtNS4zLS41LTQuNSAwIC41IDMuOSAxIDcuOSAxLjUgMTEuOCAyLjgtMi4zIDYuMS0zLjUgOC44LTYgMi45LTIuOCA1LjEtNi42IDcuMy05LjkgMi4yLTMuNCA0LjMtNi45IDYuNi0xMC4yLjYtLjkgMy4xLTMuMSAyLjMtMi45aC00Yy0xLjEtMS0yLjItMi4xLTMuMy0zLjEuMSAxIC4yIDIgLjIgMy4xLjEgMS45LjEgMy43LjEgNS42IDAgNC4zLS40IDguNy0uOSAxMy0uMiAxLjktLjcgNC4xLTEuMyA2LjItLjMgMS0uNSAxLjItMS4xIDIuMS40LS42IDEtLjkgMS43LS44LTEtLjItMi0uNS0yLjktLjctNy43LTEuOS0xNS43LTEuNC0yMy40LjVzLTE0LjIgNi42LTIyLjIgOC4xYzIuNCA0LjIgNC45IDguNCA3LjMgMTIuNSAxLjgtMi4xIDMuOC0zLjYgNS4yLTYuMiAxLjUtMi44IDQtNSA2LjItNy4yIDUuNS01LjUgMTEuMS0xMC45IDE2LjEtMTYuOSA0LjMtNS4xIDcuNS0xMS4xIDExLjMtMTYuNiAxLjctMi41IDMuOC00LjYgNi4zLTYuMyAxLjEtLjggMi4zLTEuNyAzLjYtMi4xLTIuMS44LTEuNy0xLS43IDEuNyAxLjggNSAxLjggMTAuNyAxLjggMTUuOSAwIDYuNy0xIDEzLjQtNC4zIDE5LjMtMS4yIDIuMS0yLjQgNC4zLTQgNi4xLTEuNyAyLTMuNyAxLjktNi4xIDItNS42LjMtMTMuNC0uMi0xNy42LS44LTMuNS0uNS03LjQtMS4xLTEwLjQtMi44LTEuMy0uNy0uMy0uNC0uNC42LjYtMy40IDIuOS02LjggNC4yLTEwIDUuMS0xMy4yIDE1LjYtMjIuNiAyNy40LTI5LjYgMy4xLTEuOCA2LjMtMy43IDkuNS01LjQuNS0uMyAxLjEtLjYgMS42LS44IDEuNi0uNCAxLjUtLjgtLjQtMSAuNi44LjcgMi4yLjkgMy4xIDEuNyA3LjMtLjIgMTQuOS0xLjQgMjIuMS0xLjMgNy42LTIuNSAxNS4zLTMuNyAyMi45LS4zIDEuOC0uMiA0LjktMS41IDYuMy0yLjEgMi4zLTYuMSAxLjctOC44IDEuNi03LjgtLjQtMTUuNS0xLjEtMjMuMy0xLjctMy43LS4zLTcuNS0uMy0xMS4yLS4yLTEuOCAwLTMuNS4zLTUuMi42LTEgLjMtMS45LjUtMi45LjktMy4yLjUtMi4yIDEuOCAyLjkgNC4xdjRjLjUtMi45IDEuMy01LjYgMS41LTguNi4yLTMuNS4zLTYuNiAxLjEtMTAgMS43LTcuMiA0LjktMTQuMyA4LTIxIDIuNy01LjcgNi4yLTEwLjkgMTAuNi0xNS40IDIuNC0yLjUgNS4zLTQuNCA4LjEtNi4zIDEuOS0xLjMgNC43LTQuNiA2LjktNC45IDkuOS0xLjcgNS44LTE2LjItMy42LTE0LjYiLz48cGF0aCBkPSJNMzAuMyAxNzYuNXYtNy44aDkyLjZ2Ny44IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTMwLjMgMTc2LjV2LTcuOGg5Mi42djcuOCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik00NCAxODIuNWMtLjEtLjMtLjEtLjYtLjItLjktLjYgMi40LTEuMyA0LjktMS45IDcuM2wuNi0uNkgzMS44YzQuNSA1IDEwLjggNC41IDE2LjkgMy43IDcuNC0xIDE1LjMtMS4xIDIyLjctLjQgNy45LjcgMTUuNi0uMyAyMy40LS4xIDQuMS4xIDggLjUgMTIuMS4zIDIuOS0uMSA2LjItMS41IDguOS0uNSA5LjEgMy4zIDEzLTExLjIgNC0xNC41LTUuNy0yLTEyLjIuMS0xOC4xLjEtMy41IDAtNy0uNC0xMC41LS40LTQuMiAwLTguNC42LTEyLjYuNi03LjUuMS0xNC42LTEuMi0yMi4xLS42LTMuMi4yLTYuNC4yLTkuNi43LS45LjEtMS45LjMtMi44LjQtLjguMS0xLjYuMS0yLjQuMS0uNC0uMi0uMy0uMS41LjEtMi43LTMtNy45LTIuOS0xMC42IDAtMi41IDIuNi0zLjIgNS4yLTIuMyA4LjggMi41IDkuMyAxNyA1LjMgMTQuNy00LjEiLz48cGF0aCBkPSJNNzYuNiAxNzYuNUgzMC4zdjE1LjhoOTIuNnYtMTUuOHptNS05Mi4yYy01My43IDguNS01MS4zIDg0LjMtNTEuMyA4NC4zIiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTExMy4zIDQ4LjhjMTMuNS0yLjYgMTcuMS0xMi4yIDE3LjEtMTIuMkMxMjIuNiAxNS4xIDEwNy4zIDQgMTA3LjMgNHMtMTEgMTAuMi0xMS4yIDE1LjFjMCAwLTE0LjMtOS40LTMyLjYtMS40IDAgMC0yMCAxMC40LTM2LjkgNC4zIDAgMC0yMS4yLTguNS0yMi42LTIuNyAwIDAtMy4zIDEwLjUgMi41IDIwLjUgMCAwIDUuOCA5LjMgOC40IDkuMyAwIDAgMjEuNiAyLjUgMTguNSAzLjUgMCAwLTEuNCA0LjYtMTYuMiAzLjggMCAwLTUuMy0uMS00LjMgNUMxNCA2Ni44IDE3LjcgNzIgMjggNzMuOWMwIDAgOS43IDIuOSAyNiAuNXMxMyAxNC40IDEzIDE0LjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTIwLjMgNzQuM2MxMy41LjcgMTkuOS02LjMgMTkuOS02LjNzLTMuNC0xNC4yLTE0LTI1LjciIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNNzkuOSAzNC44YzAgMi0xLjYgMy42LTMuNSAzLjZzLTMuNS0xLjYtMy41LTMuNiAxLjYtMy42IDMuNS0zLjZjMiAuMSAzLjUgMS43IDMuNSAzLjYiIGZpbGw9IiNmZmYiLz48ZWxsaXBzZSBjeD0iNzYuNCIgY3k9IjM0LjgiIGZpbGw9Im5vbmUiIHJ4PSIzLjUiIHJ5PSIzLjYiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjQiLz48cGF0aCBkPSJNNzYuMSAzMS4zcy0zLjgtLjEtNy42IDMuNyIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNCIvPjxwYXRoIGQ9Ik0xMzYuNiA3MS4yYzExLjYgMTUuNyAxMy4yIDMyLjkgMTMuMiAzMi45cy05LjcgNi43LTI3IDIuOSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0xMjIuNiAxNDMuMmMxNy4xIDcuMyAyOC43IDEuNyAyOC43IDEuN3MyLjQtMTkuNC01LjctMzguOG0tMjIuNyA2Mi42czIuMi0xOS42IDIyLTIyLjEiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTAzLjYgMTE1LjJjLTEuMS44LS44LjcuNy0uNCAxLjMtLjkgMi44LTEuNiA0LjItMi4zIDMtMS41IDYuMi0yLjUgOS4zLTMuOCA1LjMtMi4zIDExLTUuOSAxNi44LTYgNy40LS4xIDEwLjQtMTAuMiAzLjgtMTQtNi4xLTMuNS0xMi44LTQuOC0xOS40LTYuOS03LjUtMi4zLTEzLjgtNi4yLTIwLjYtMTAtOC40LTQuOC0xNiA4LjEtNy42IDEzIDYuOCAzLjkgMTMuNCA3LjkgMjAuOCAxMC41IDYuMyAyLjIgMTMuMyAzLjEgMTkuMSA2LjUgMS4zLTQuNyAyLjUtOS4zIDMuOC0xNC04LjUuMi0xNS4xIDQuMS0yMi44IDcuMy02LjYgMi44LTE3LjggNS40LTIxLjIgMTIuNS0zLjkgOC43IDkgMTYuMyAxMy4xIDcuNiIvPjwvZz48L3N3aXRjaD48L3N2Zz4=')} +.is2d .bishop.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii00OC4zNSAtMTAgMjIwIDIyMCIgd2lkdGg9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHN3aXRjaD48Zz48cGF0aCBkPSJNMzAuNCAxNjguN2MtMTMuOC05LjQtMjMuNy0yNS44LTI2LjMtNDIuNEMxLjMgMTA4LjUgNi42IDkwLjUgMTUgNzVjNC42LTguNSAxMC4xLTE2LjUgMTYuMS0yNGwyMi43IDMxIDE2LTE2LjMtMjMuNy0zMS41YzUtNS4yIDEwLjMtMTAuMSAxNS42LTE1aC0uMWMxMDkuNiA5OC4yIDMxLjMgMTQ5LjUgMzEuMyAxNDkuNSIvPjxwYXRoIGQ9Ik0zMC40IDE2OC43Yy0xMy44LTkuNC0yMy43LTI1LjgtMjYuMy00Mi40QzEuMyAxMDguNSA2LjYgOTAuNSAxNSA3NWM0LjYtOC41IDEwLjEtMTYuNSAxNi4xLTI0bDIyLjcgMzEgMTYtMTYuMy0yMy43LTMxLjVjNS01LjIgMTAuMy0xMC4xIDE1LjYtMTVoLS4xYzEwOS42IDk4LjIgMzEuMyAxNDkuNSAzMS4zIDE0OS41IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTY5LjUgMTEuMmMwIDQuNC0zLjUgOC03LjkgOHMtNy45LTMuNi03LjktOCAzLjUtOCA3LjktOCA3LjkgMy42IDcuOSA4Ii8+PGVsbGlwc2UgY3g9IjYxLjYiIGN5PSIxMS4yIiBmaWxsPSJub25lIiByeD0iNy45IiByeT0iOCIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0xNS40IDE3Ni42di03LjlIMTA4djcuOSIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0xNS40IDE3Ni42di03LjlIMTA4djcuOSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik02MS43IDE3Ni42SDE1LjR2MTUuN0gxMDh2LTE1Ljd6Ii8+PHBhdGggZD0iTTYxLjcgMTc2LjZIMTUuNHYxNS43SDEwOHYtMTUuN3oiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48L2c+PC9zd2l0Y2g+PC9zdmc+')} +.is2d .rook.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii02My4zNSAtMTAgMjIwIDIyMCIgd2lkdGg9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHN3aXRjaD48Zz48cGF0aCBkPSJNOTYgMTY4LjVjLS4yLTU4LjgtMTUuMi0xMDEuOS0xNS4yLTEwMS45TDk2IDU4LjRWMy4zSDcyLjhWMTlINjEuM1YzLjNIMzguMVYxOUgyNi42VjMuM0gzLjR2NTUuMWwxNS4yIDguM3MtMTUuMSA0My0xNS4yIDEwMS45Ii8+PHBhdGggZD0iTTk2IDE2OC41Yy0uMi01OC44LTE1LjItMTAxLjktMTUuMi0xMDEuOUw5NiA1OC40VjMuM0g3Mi44VjE5SDYxLjNWMy4zSDM4LjFWMTlIMjYuNlYzLjNIMy40djU1LjFsMTUuMiA4LjNzLTE1LjEgNDMtMTUuMiAxMDEuOSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0zLjQgMTc2LjR2LTcuOUg5NnY3LjkiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNMy40IDE3Ni40di03LjlIOTZ2Ny45IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTQ5LjcgMTc2LjRIMy40djE1LjdIOTZ2LTE1Ljd6Ii8+PHBhdGggZD0iTTQ5LjcgMTc2LjRIMy40djE1LjdIOTZ2LTE1Ljd6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTE4LjYgNjYuNmg2Mi4yTTMuNCA1Ny41SDk2IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI0Ii8+PC9nPjwvc3dpdGNoPjwvc3ZnPg==')} +.is2d .queen.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii0xNC4xNSAtMTAgMjIwIDIyMCIgd2lkdGg9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHN3aXRjaD48Zz48cGF0aCBkPSJNMTQyLjIgMTY3LjNzLjYtNy4zLTMuNi04LjJjLTIzLjgtNC42IDM2LjktOTYuNCAzNi45LTk2LjRzLTU1LjIgNjIuMS01MS44LTQ1LjVsLS44LS41Yy0yNy44IDk4LjEtNTMuNyAwLTUzLjcgMGwtMSAuNmMzLjQgMTA3LjYtNTEuOCA0NS41LTUxLjggNDUuNXM2MC43IDkxLjggMzYuOSA5Ni40Yy00LjIuOC0zLjYgOC4yLTMuNiA4LjIiLz48cGF0aCBkPSJNMTQyLjIgMTY3LjNzLjYtNy4zLTMuNi04LjJjLTIzLjgtNC42IDM2LjktOTYuNCAzNi45LTk2LjRzLTU1LjIgNjIuMS01MS44LTQ1LjVsLS44LS41Yy0yNy44IDk4LjEtNTMuNyAwLTUzLjcgMGwtMSAuNmMzLjQgMTA3LjYtNTEuOCA0NS41LTUxLjggNDUuNXM2MC43IDkxLjggMzYuOSA5Ni40Yy00LjIuOC0zLjYgOC4yLTMuNiA4LjIiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNNDkuNiAxNzYuM3YtNy45aDkyLjZ2Ny45IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTQ5LjYgMTc2LjN2LTcuOWg5Mi42djcuOSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik03NC4zIDkuOGMuOSA1LjQtMy43IDEwLTkgOS4xLTMuMi0uNS01LjgtMy4yLTYuMy02LjUtLjktNS40IDMuNy0xMCA5LTkuMSAzLjIuNiA1LjggMy4yIDYuMyA2LjUiLz48cGF0aCBkPSJNNzQuMyA5LjhjLjkgNS40LTMuNyAxMC05IDkuMS0zLjItLjUtNS44LTMuMi02LjMtNi41LS45LTUuNCAzLjctMTAgOS05LjEgMy4yLjYgNS44IDMuMiA2LjMgNi41eiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0xOC43IDU2LjNjLjkgNS40LTMuNyAxMC05IDkuMS0zLjItLjUtNS44LTMuMi02LjMtNi41LS45LTUuNCAzLjYtMTAgOS05LjEgMy4yLjYgNS44IDMuMiA2LjMgNi41Ii8+PHBhdGggZD0iTTE4LjcgNTYuM2MuOSA1LjQtMy43IDEwLTkgOS4xLTMuMi0uNS01LjgtMy4yLTYuMy02LjUtLjktNS40IDMuNi0xMCA5LTkuMSAzLjIuNiA1LjggMy4yIDYuMyA2LjV6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTU4LjEgMTU2LjloNzUuNiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNCIvPjxwYXRoIGQ9Ik0xMTcuNSA5LjdjLS45IDUuNCAzLjcgMTAgOSA5LjEgMy4yLS41IDUuOC0zLjIgNi4zLTYuNS45LTUuNC0zLjctMTAtOS05LjEtMy4yLjYtNS44IDMuMi02LjMgNi41Ii8+PHBhdGggZD0iTTExNy41IDkuN2MtLjkgNS40IDMuNyAxMCA5IDkuMSAzLjItLjUgNS44LTMuMiA2LjMtNi41LjktNS40LTMuNy0xMC05LTkuMS0zLjIuNi01LjggMy4yLTYuMyA2LjV6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTE3My4xIDU2LjJjLS45IDUuNCAzLjcgMTAgOSA5LjEgMy4yLS41IDUuOC0zLjIgNi4zLTYuNS45LTUuNC0zLjctMTAtOS05LjEtMy4yLjYtNS44IDMuMi02LjMgNi41Ii8+PHBhdGggZD0iTTE3My4xIDU2LjJjLS45IDUuNCAzLjcgMTAgOSA5LjEgMy4yLS41IDUuOC0zLjIgNi4zLTYuNS45LTUuNC0zLjctMTAtOS05LjEtMy4yLjYtNS44IDMuMi02LjMgNi41eiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik05NS45IDE3Nkg0OS42djE1LjdoOTIuNlYxNzZ6Ii8+PHBhdGggZD0iTTk1LjkgMTc2SDQ5LjZ2MTUuN2g5Mi42VjE3NnoiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTY0LjcgNzYuNGwtNjcuNSA3OC45Yy0uNC41LTEuMy4yLTEuMy0uNUw3MS41IDM0LjciIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjQiLz48cGF0aCBkPSJNMTIwIDM0LjdMOTYuNyAxNTMuM2MtLjMgMS40LTIuMSAxLjktMyAuOEwyNyA3Ni41IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI0Ii8+PC9nPjwvc3dpdGNoPjwvc3ZnPg==')} +.is2d .king.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii0xNC4wNSAtMTAgMjIwIDIyMCIgd2lkdGg9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHN3aXRjaD48Zz48cGF0aCBkPSJNOTYuMSAxNzYuM0g0OS44djE1LjhoOTIuNXYtMTUuOHoiLz48cGF0aCBkPSJNOTYuMSAxNzYuM0g0OS44djE1LjhoOTIuNXYtMTUuOHoiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNNDkuOCAxNjguNXY3LjhoOTIuNXYtNy44IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTQ5LjggMTY4LjV2Ny44aDkyLjV2LTcuOCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0xMDMuNyA2OC40VjQyLjVoMjMuMlYyNi43aC0yMy4ybC4xLTIzLjZIODguM3YyMy42SDY1LjJ2MTUuOGgyMy4xdjI1LjkiLz48cGF0aCBkPSJNMTAzLjcgNjguNFY0Mi41aDIzLjJWMjYuN2gtMjMuMmwuMS0yMy42SDg4LjN2MjMuNkg2NS4ydjE1LjhoMjMuMXYyNS45IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTE4Ny4zIDc1LjdDMTgwLjEgNDcgMTUyLjggNDQgMTUyLjggNDQgMTE0LjMgMzguNiA5Ni40IDgwLjggOTYgODEuOGMtLjQtMS0xOC4zLTQzLjMtNTYuOC0zNy45IDAgMC0yNy40IDMtMzQuNSAzMS43IDAgMC0xMy44IDUxLjggNDUgOTIuOGg5Mi41YzU4LjgtNDAuOSA0NS4xLTkyLjcgNDUuMS05Mi43Ii8+PHBhdGggZD0iTTE4Ny4zIDc1LjdDMTgwLjEgNDcgMTUyLjggNDQgMTUyLjggNDQgMTE0LjMgMzguNiA5Ni40IDgwLjggOTYgODEuOGMtLjQtMS0xOC4zLTQzLjMtNTYuOC0zNy45IDAgMC0yNy40IDMtMzQuNSAzMS43IDAgMC0xMy44IDUxLjggNDUgOTIuOGg5Mi41YzU4LjgtNDAuOSA0NS4xLTkyLjcgNDUuMS05Mi43em0tOTktNy4zaDE1LjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTQ3LjUgNjcuMmMtMjUuMS0yLjItNDMuNiA1MC45LTQzLjYgNTAuOXYzMi44czI2LjItLjYgNDYuNi0yMS44YzIwLjQtMjEuNCAyMi4xLTU5LjgtMy02MS45em0tMTAzIDBjLTI1LjEgMi4yLTIzLjQgNDAuNi0zIDYxLjlzNDYuOCAyMS44IDQ2LjggMjEuOHYtMzIuOFM2OS42IDY1IDQ0LjUgNjcuMnoiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNOTYgMTguOHYzOS40TTgwLjYgMzQuNmgzMC45IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI0Ii8+PC9nPjwvc3dpdGNoPjwvc3ZnPg==')} diff --git a/public/piece-css/riohacha.css b/public/piece-css/riohacha.css new file mode 100644 index 0000000000..34800bb15b --- /dev/null +++ b/public/piece-css/riohacha.css @@ -0,0 +1,12 @@ +.is2d .pawn.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iNTM1IDEzNTAgMTMzMyAxMzMzIiB3aWR0aD0iMTMzIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Im0xNTkwIDI1MDB2LTk5bC04Ny0zLTg3LTMtNTYtMTgyLTU3LTE4MiAzMC0yOGM2Mi01OCA4Mi0xNDcgNTEtMjIxLTUyLTEyNi0yMTEtMTY2LTMxMS03OS05MSA4MC05NiAyMDctMTIgMjkwbDM5IDM5LTU4IDE4Mi01OCAxODEtODIgMy04MiAzdjE5OWg3NzB6IiBmaWxsPSIjZjhmOGY4Ii8+PHBhdGggZD0ibTgyMCAyNTAwdi05OWw4Mi0zIDgyLTMgNTgtMTgxIDU4LTE4Mi0zOS0zOWMtMzgtMzgtNjEtOTEtNjEtMTQ0IDAtMzAgMTktODkgMjktODkgMyAwIDY1IDU5IDEzNiAxMzAgODQgODQgMTM1IDEyOCAxNDUgMTI1IDE3LTYgMjItMTAtNzcgNjhsLTYwIDQ4LTEyIDExN2MtMTYgMTU0LTE1IDE1Mi01NyAxNTJoLTM0djIwMGgtMjUweiIgZmlsbD0iI2QzZDNkMyIvPjxwYXRoIGQ9Im0xMDcwIDI1MDB2LTEwMGgzNGM0MiAwIDQxIDIgNTctMTUybDEyLTExNyA2NC01MSA2My01MSAxMCAyNmM2IDE1IDEwIDMxIDEwIDM4IDAgMTEgMjQgODcgNzUgMjM3bDIzIDY1IDg2IDMgODYgM3YxOTloLTUyMHptOTEtNjE0LTEzMy0xMzQgNDEtNDBjNTUtNTMgMTE3LTY4IDE5MC00NyAxMTMgMzQgMTcwIDE3NiAxMTUgMjg3LTEzIDI1LTU5IDY4LTczIDY4LTMgMC02Ni02MC0xNDAtMTM0eiIgZmlsbD0iI2Y4ZjhmOCIvPjxwYXRoIGQ9Im0xNTkwIDI1MDB2LTk5bC04Ny0zLTg3LTMtNTYtMTgyLTU3LTE4MiAzMC0yOGM2Mi01OCA4Mi0xNDcgNTEtMjIxLTUyLTEyNi0yMTEtMTY2LTMxMS03OS05MSA4MC05NiAyMDctMTIgMjkwbDM5IDM5LTU4IDE4Mi01OCAxODEtODIgMy04MiAzdjE5OWg3NzB6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMjQiLz48L3N2Zz4=')} +.is2d .knight.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iMjc4MCAxMzUwIDEzMzMgMTMzMyIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtMzgzMCAyNTAwdi05OWwtMTA2LTMtMTA2LTMgODItNjkgODItNjktMTY4LTE2OC0xNjctMTY3IDI2LTE2YzQzLTI5IDkxLTMxIDE0MS02IDI1IDEyIDQ2IDI2IDQ2IDMxIDAgMjIgMjIgNSA2Ny01MyAyOC0zNSA1My02OCA1Ny03NSA0LTgtNjYtNjEtMjEyLTE1OWwtMjIwLTE0Ni00MiAyMmMtMTkwIDk3LTI3MyAzNDAtMTgzIDUzMSAxNiAzNSAzOSA3NSA1MSA4OWwyMSAyNS00NSA0Ni00NSA0NiA4MiA2OSA4MSA2OS0xMDYgMy0xMDYgM3YxOTloNzcweiIgZmlsbD0iI2Y4ZjhmOCIvPjxnIGZpbGw9IiNkM2QzZDMiPjxwYXRoIGQ9Im0zMDYwIDI1MDB2LTk5bDEwNi0zIDEwNi0zLTgxLTY5LTgyLTY5IDQ1LTQ2IDQ1LTQ2LTIxLTI1Yy0xMi0xNC0zNS01NC01MS04OS01NS0xMTYtNDctMjY0IDE5LTM3NyAzMS01MiAxMDgtMTI2IDE2Mi0xNTMgNTMtMjcgNjItMjcgMjYgMi00NiAzNS03MyA2OC0xMDMgMTI3LTEyNCAyMzkgNiA1MjUgMjY3IDU5MSAzNSA4IDYzIDE3IDY0IDIwIDEgMi05IDM0LTIxIDcybC0yMyA2N2gtMTU4djIwMGgtMzAweiIvPjxwYXRoIGQ9Im0zMzUwIDE5MjN2LTk3bDQ4IDQ3YzQwIDM5IDUwIDQ1IDYyIDM1IDEzLTExIDEzLTExIDIgMi0xMCAxMi00IDIyIDM1IDYybDQ3IDQ4aC0xOTR6Ii8+PC9nPjxwYXRoIGQ9Im0zMzYwIDI1MDB2LTEwMGgxNThsMjEtNjJjMTItMzUgMjEtNjcgMjEtNzIgMS01LTI3LTE3LTYyLTI1LTI2MS02Ni0zOTAtMzUwLTI2OC01OTEgMjctNTIgMTAzLTE0MCAxMjItMTQwIDEyIDAgNDI4IDI3OSA0MjggMjg3IDAgNi03NCAxMDYtMTAxIDEzNy01IDUtMTYgMC0yNi0xMS0zNy00My0xMjYtNTUtMTc4LTIzbC0zMCAxOC00Ny00Ni00OC00NnYxOTRoMTk1bDExNSAxMTUgMTE0IDExNC0yMCAyM2MtMTAgMTMtMjUgMjctMzMgMzItNyA0LTMwIDI0LTQ5IDQyLTIwIDE5LTQwIDM0LTQ0IDM0cy04IDUtOCAxMGMwIDYgNDIgMTAgMTA1IDEwaDEwNXYyMDBoLTQ3MHoiIGZpbGw9IiNmOGY4ZjgiLz48cGF0aCBkPSJtMzgzMCAyNTAwdi05OWwtMTA2LTMtMTA2LTMgODItNjkgODItNjktMTY4LTE2OC0xNjctMTY3IDI2LTE2YzQzLTI5IDkxLTMxIDE0MS02IDI1IDEyIDQ2IDI2IDQ2IDMxIDAgMjIgMjIgNSA2Ny01MyAyOC0zNSA1My02OCA1Ny03NSA0LTgtNjYtNjEtMjEyLTE1OWwtMjIwLTE0Ni00MiAyMmMtMTkwIDk3LTI3MyAzNDAtMTgzIDUzMSAxNiAzNSAzOSA3NSA1MSA4OWwyMSAyNS00NSA0Ni00NSA0NiA4MiA2OSA4MSA2OS0xMDYgMy0xMDYgM3YxOTloNzcweiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjI0Ii8+PC9zdmc+')} +.is2d .bishop.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iMzg5MCAxMzUwIDEzMzAgMTMzMCIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNDk1MCAyNTAwdi0xMDBoLTE4NmwtMzgtMTYyYy0yMS05MC00MC0xNjgtNDMtMTc0LTItNiAzMC01NCA3Mi0xMDcgNDEtNTQgNzUtMTAyIDc1LTEwOHMtMjEtMzgtNDctNzFsLTQ3LTYxLTI2IDMxLTI3IDMyLTMyLTQ1LTMyLTQ1IDIwLTI5YzEyLTE2IDIxLTMyIDIxLTM2IDAtMTAtOTItMTI1LTk5LTEyNS0zIDEtMzcgNDItNzYgOTMtMzggNTAtOTkgMTI4LTEzMyAxNzRsLTY0IDgyIDc4IDEwMSA3OCAxMDEtMzIgMTM3Yy0xOCA3NS0zNyAxNTQtNDMgMTc1bC0xMCAzN2gtMTc5djIwMGg3NzB6IiBmaWxsPSIjZjhmOGY4Ii8+PHBhdGggZD0ibTQxODAgMjUwMHYtMTAwaDE3OWwxMC0zN2M2LTIxIDI1LTEwMCA0My0xNzVsMzItMTM3LTc3LTEwMGMtNDItNTUtNzctMTAxLTc3LTEwM3M1NC0xIDExOSAybDExOSA1IDcyIDkzYzM5IDUwIDc0IDkyIDc4IDkyczggMTEgOCAyNWMxIDE0LTIgMjUtNiAyNS01IDAtMzggMTgtNzQgNDFsLTY0IDQwLTcgOTdjLTkgMTM0LTggMTMyLTYxIDEzMmgtNDR2MjAwaC0yNTB6bTQyMi02OTljLTE4LTIyLTMyLTQzLTMyLTQ4IDAtNCAxMC0yMSAyMy0zN2wyMy0yOSAzNiA0OSAzNiA0OC0yMSAyOGMtMTEgMTUtMjQgMjgtMjcgMjgtNCAwLTIxLTE4LTM4LTM5eiIgZmlsbD0iI2QzZDNkMyIvPjxwYXRoIGQ9Im00NDMwIDI1MDB2LTEwMGg0NGM1MyAwIDUyIDIgNjEtMTMybDctOTcgNjQtNDBjMzYtMjMgNjktNDEgNzMtNDEgNyAwIDIwIDQ2IDYzIDIyM2wyMSA4N2gxODd2MjAwaC01MjB6bTE2OC01NTUtNzMtOTVoLTExMmMtNjIgMC0xMTMtMy0xMTItNyAwLTkgMzEtNTAgMTU3LTIwOCA1MC02NCA5Mi0xMjEgOTItMTI2IDAtMjAgMTgtNSA2MyA1Nmw0OCA2NC00NSA1OGMtMjUgMzItNDYgNjItNDYgNjYgMCAxMSA2MSA4NyA3MCA4NyA0IDAgMjYtMjcgNTAtNjAgMjQtMzIgNDYtNTcgNTEtNTUgNCAzIDI2IDMzIDQ5IDY2bDQxIDYxLTQ3IDYxYy0yNyAzNC02MCA3Ny03NCA5NC0xNCAxOC0yOCAzMy0zMiAzM3MtNDAtNDMtODAtOTV6IiBmaWxsPSIjZjhmOGY4Ii8+PHBhdGggZD0ibTQ5NTAgMjUwMHYtMTAwaC0xODZsLTM4LTE2MmMtMjEtOTAtNDAtMTY4LTQzLTE3NC0yLTYgMzAtNTQgNzItMTA3IDQxLTU0IDc1LTEwMiA3NS0xMDhzLTIxLTM4LTQ3LTcxbC00Ny02MS0yNiAzMS0yNyAzMi0zMi00NS0zMi00NSAyMC0yOWMxMi0xNiAyMS0zMiAyMS0zNiAwLTEwLTkyLTEyNS05OS0xMjUtMyAxLTM3IDQyLTc2IDkzLTM4IDUwLTk5IDEyOC0xMzMgMTc0bC02NCA4MiA3OCAxMDEgNzggMTAxLTMyIDEzN2MtMTggNzUtMzcgMTU0LTQzIDE3NWwtMTAgMzdoLTE3OXYyMDBoNzcweiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjI0Ii8+PC9zdmc+')} +.is2d .rook.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iMTY3MCAxMzUwIDEzMzMgMTMzMyIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtMjcxMCAyNTAwdi05OWwtNjItMy02My0zLTIyLTIxMGMtMzAtMjg3LTMzLTI1NiAzNy0yOTlsNjAtMzgtMi0xNjEtMy0xNjItNTctMy01OC0zdjEwMWgtMTA5bC0zLTQ3LTMtNDhoLTE5MGwtMyA0OC0zIDQ3aC0xMDl2LTEwMWwtNTcgMy01OCAzLTMgMTYzLTIgMTYyIDQ2IDI4YzI1IDE1IDUyIDMyIDYwIDM3IDEyIDkgMTEgMzktNiAyMTUtMTEgMTEzLTIzIDIyMC0yNiAyMzhsLTUgMzJoLTEyOXYyMDBoNzcweiIgZmlsbD0iI2Y4ZjhmOCIvPjxnIGZpbGw9IiNkM2QzZDMiPjxwYXRoIGQ9Im0xOTQwIDI1MDB2LTEwMGgxMjlsNS0zMmMzLTE4IDE1LTEyNSAyNi0yMzggMTctMTc2IDE4LTIwNiA2LTIxNS04LTUtMzUtMjItNjAtMzdsLTQ2LTI4IDItMTYyIDMtMTYzIDU4LTMgNTctM3Y1MWMwIDQ5IDEgNTAgMzAgNTBoMzB2MjMwaDIzOGwyMzcgMS01NCAzNGMtMzAgMTktNTcgMzgtNjAgNDItMyA1LTEyIDktMTggMTAtNyAyLTY1IDM1LTEyOCA3NGwtMTE1IDcxLTEgNTFjLTEgMjktNCA5OS04IDE1N2wtNiAxMDUtMzcgMy0zOCAzdjE5OWgtMjUweiIvPjxwYXRoIGQ9Im0yMjMyIDE1NzMgMy00OCA1MC0zIDUwLTMtMyA1MS00IDUwaC05OXoiLz48L2c+PHBhdGggZD0ibTIxOTAgMjUwMXYtMTAwbDM4LTMgMzctMyA2LTEwNWM0LTU4IDctMTI4IDgtMTU3bDEtNTEgMTIyLTc2YzY4LTQxIDEyNi03MiAxMzAtNjggMyA0IDkgMzkgMTMgNzcgNCAzOSA4IDg2IDEwIDEwNSA3IDY4IDE0IDE0NiAxOSAyMDMgMyAzMiA4IDYzIDExIDY4IDQgNSAzMyA5IDY2IDloNTl2MjAwaC01MjB6bS0xMC03NjZ2LTExNWgxNDlsMy00NyAzLTQ4aDkwbDMgNDggMyA0N2gxMDl2LTEwMWw1OCAzIDU3IDMgMyAxNjMgMiAxNjJoLTQ4MHoiIGZpbGw9IiNmOGY4ZjgiLz48cGF0aCBkPSJtMjcxMCAyNTAwdi05OWwtNjItMy02My0zLTIyLTIxMGMtMzAtMjg3LTMzLTI1NiAzNy0yOTlsNjAtMzgtMi0xNjEtMy0xNjItNTctMy01OC0zdjEwMWgtMTA5bC0zLTQ3LTMtNDhoLTE5MGwtMyA0OC0zIDQ3aC0xMDl2LTEwMWwtNTcgMy01OCAzLTMgMTYzLTIgMTYyIDQ2IDI4YzI1IDE1IDUyIDMyIDYwIDM3IDEyIDkgMTEgMzktNiAyMTUtMTEgMTEzLTIzIDIyMC0yNiAyMzhsLTUgMzJoLTEyOXYyMDBoNzcweiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjI0Ii8+PC9zdmc+')} +.is2d .queen.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iNTAxMCAxMzUwIDEzMzMgMTMzMyIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNjA2MCAyNTAwdi0xMDBoLTE3OGwtMTAtNDdjLTYtMjctMTgtODYtMjctMTMzbC0xNy04NSAxMDctMjMzYzU5LTEyOCAxMDUtMjM1IDEwMy0yMzctMi0zLTI0IDEtNDkgOC00MyAxMi00NCAxNC00NyA1OC0zIDQwLTEwIDU0LTYyIDExMGwtNTkgNjQtMS05NGMwLTg5IDItOTcgMjYtMTIybDI3LTI4LTIzLTYxYy0xMi0zMy0yNS02MC0yOS02MHMtMjYgMjAtNTAgNDRsLTQyIDQzIDE1IDM2YzE0IDM1IDEzIDM5LTIyIDEyMS0yMCA0OC0zOSA4Ni00MyA4Ni0zIDAtMjItMzktNDItODYtMzUtODMtMzYtODctMjItMTIybDE2LTM2LTQzLTQzYy0yMy0yNC00NS00My00OS00My03IDAtNDkgOTctNDkgMTE1IDAgNiAxMSAyMiAyNSAzNSAyMyAyMiAyNSAzMCAyNSAxMjJ2OTlsLTYwLTY4Yy01NC02MC02MC03Mi02MC0xMTAgMC00Ny02LTUyLTc3LTY3bC0zMi03IDExMCAyMzggMTEwIDIzOC0xNiA4NWMtOSA0Ny0yMSAxMDYtMjcgMTMzbC0xMCA0N2gtMTc4djIwMGg3NjB6IiBmaWxsPSIjZjhmOGY4Ii8+PGcgZmlsbD0iI2QzZDNkMyI+PHBhdGggZD0ibTUzMDAgMjUwMHYtMTAwaDE3OGwxMC00N2M2LTI3IDE4LTg2IDI3LTEzM2wxNi04NS0xMTAtMjM4LTExMC0yMzggMzIgN2M3MSAxNSA3NyAyMCA3NyA2NyAwIDM4IDYgNTAgNjAgMTEwbDYwIDY4di05OWMwLTkyLTItMTAwLTI1LTEyMi0xNC0xMy0yNS0yOS0yNS0zNSAwLTIyIDQyLTExNSA1Mi0xMTUgNSAwIDcgNCA0IDgtMyA1IDIyIDEzNCA1NCAyODggMzMgMTUzIDYwIDI4MiA2MCAyODYgMCA1IDM4IDggODUgOCA2NyAwIDg1IDMgODUgMTQgMCA4IDMgMjMgNiAzMyA0IDEyIDMgMTQtMyA1LTctOS0zMCAxLTk0IDQwbC04NCA1My0zIDYzLTMgNjJoLTEwOXYyMDBoLTI0MHoiLz48cGF0aCBkPSJtNTcyMCAxOTkyYzAtNy0xMS0zNS0yNS02NC0xNC0yOC0yMS01NC0xNi01NyA0LTMgMjQtNDMgNDQtODkgMzUtODAgMzUtODQgMjEtMTE5bC0xNS0zNiA0Mi00M2MyNC0yNCA0Ni00NCA0OS00NCA4IDAtODMgNDQ3LTkzIDQ1Ni00IDQtNyAyLTctNHoiLz48L2c+PHBhdGggZD0ibTU1NDAgMjUwMHYtMTAwaDEwOWwzLTYyIDMtNjMgODQtNTNjNjEtMzggODctNDkgOTItNDAgMyA3IDEyIDQyIDE4IDc4IDcgMzYgMTcgODIgMjMgMTAzbDExIDM3aDE3N3YyMDBoLTUyMHptMTIwLTM3OGMwLTQtMjctMTMzLTYwLTI4Ny0zMy0xNTMtNTctMjgxLTU0LTI4NCAyLTMgMjMgMTMgNDUgMzVsNDAgNDAtMTYgMzljLTE0IDMxLTE0IDQzLTQgNjQgMTIgMjYgMjkgNjUgNDcgMTExIDUgMTQgMjIgNTEgMzYgODNzMjYgNjMgMjYgNzBjMSA0MCAyMy00NCA2MC0yMzAgMjQtMTE3IDQ3LTIxMCA1MS0yMDcgNSAzIDkgMTMgOSAyMyAwIDkgNCAyMSA5IDI3IDIyIDI0IDIxIDYxLTQgODQtMjMgMjItMjUgMzAtMjUgMTE3IDAgNTEgNCA5MyA4IDkzIDUgMCAyNC0xOSA0Mi00MiAxOS0yNCA0Mi00OSA1Mi01NiAxMy05IDE4LTI2IDE4LTU3IDAtMjQgNi00NyAxMy01MiAxOS0xMiA4MS0zMyA4NS0yOCAzIDItOCAzMC0yMyA2Mi04MyAxNzctMTI2IDI3Mi0xNTkgMzQ2bC0yNSA1N2gtODVjLTQ4IDAtODYtMy04Ni04eiIgZmlsbD0iI2Y4ZjhmOCIvPjxwYXRoIGQ9Im02MDYwIDI1MDB2LTEwMGgtMTc4bC0xMC00N2MtNi0yNy0xOC04Ni0yNy0xMzNsLTE3LTg1IDEwNy0yMzNjNTktMTI4IDEwNS0yMzUgMTAzLTIzNy0yLTMtMjQgMS00OSA4LTQzIDEyLTQ0IDE0LTQ3IDU4LTMgNDAtMTAgNTQtNjIgMTEwbC01OSA2NC0xLTk0YzAtODkgMi05NyAyNi0xMjJsMjctMjgtMjMtNjFjLTEyLTMzLTI1LTYwLTI5LTYwcy0yNiAyMC01MCA0NGwtNDIgNDMgMTUgMzZjMTQgMzUgMTMgMzktMjIgMTIxLTIwIDQ4LTM5IDg2LTQzIDg2LTMgMC0yMi0zOS00Mi04Ni0zNS04My0zNi04Ny0yMi0xMjJsMTYtMzYtNDMtNDNjLTIzLTI0LTQ1LTQzLTQ5LTQzLTcgMC00OSA5Ny00OSAxMTUgMCA2IDExIDIyIDI1IDM1IDIzIDIyIDI1IDMwIDI1IDEyMnY5OWwtNjAtNjhjLTU0LTYwLTYwLTcyLTYwLTExMCAwLTQ3LTYtNTItNzctNjdsLTMyLTcgMTEwIDIzOCAxMTAgMjM4LTE2IDg1Yy05IDQ3LTIxIDEwNi0yNyAxMzNsLTEwIDQ3aC0xNzh2MjAwaDc2MHoiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIyNCIvPjwvc3ZnPg==')} +.is2d .king.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iNjE1MCAxMzUwIDEzMzMgMTMzMyIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNzIwMCAyNTAwdi0xMDBoLTIzN2wtMTctNTctMTYtNTggNzItMTUzIDcyLTE1NC0yNC0xOWMtNTgtNDQtMTMwLTYzLTI0MC02NC05OCAwLTEwOSAyLTE3MCAzMi0zNiAxNy03MSAzNi03OCA0MS0xMSA3IDEgNDEgNTkgMTYxbDczIDE1Mi0xNSA1Ny0xNSA1Ny0xMTcgMy0xMTcgM3YxOTloNzcwem0tMzMzLTcwNWMtNC0yNS05LTU2LTEzLTcwLTYtMjQtNS0yNSA0MC0xOWw0NiA3di0xMDVsLTQ2IDdjLTQxIDYtNDUgNS00MC0xMiAzLTEwIDgtMzAgMTItNDVsNi0yOGgtMTE1bDYgNDUgNyA0NS00MC02LTQwLTd2MTA2bDQxLTcgNDItNy02IDM4Yy00IDIxLTkgNTMtMTMgNzFsLTYgMzJoMTI1eiIgZmlsbD0iI2Y4ZjhmOCIvPjxwYXRoIGQ9Im02NDMwIDI1MDB2LTk5bDExNy0zIDExNy0zIDE1LTU3IDE1LTU3LTcyLTE1MGMtNDAtODMtNzItMTUxLTcyLTE1M3M0NS0yIDk5IDBjNjUgMiAxMDEgNyAxMDQgMTUgMiA3IDE3IDc0IDMyIDE1MGwyOCAxMzdoNThjNDMgMCA1OCA0IDYzIDE2IDggMjEgOCAyNC00IDI0LTUgMC0zOSAxOC03NSA0MC01NSAzNC03NCA0MC0xMjAgNDBoLTU1djIwMGgtMjUwem0zMjQtNjkyYzQtMTggOS01MCAxMy03MWw2LTM4LTQyIDctNDEgN3YtMTA2bDQwIDcgNDAgNi03LTQ1Yy02LTQ0LTUtNDUgMjMtNDVoMjl2MzEwaC0zNGMtMzIgMC0zMy0xLTI3LTMyem0xNzktMTQ4YzAtMzAgMi00MyA0LTI3IDIgMTUgMiAzOSAwIDU1LTIgMTUtNCAyLTQtMjh6IiBmaWxsPSIjZDNkM2QzIi8+PHBhdGggZD0ibTY2ODAgMjUwMHYtMTAwaDU1YzQ2IDAgNjUtNiAxMjAtNDAgMzYtMjIgNjktNDAgNzQtNDAgNCAwIDE0IDE4IDIxIDQwbDEzIDQwaDIzN3YyMDBoLTUyMHptMTA1LTM1N2MtMTUtNzYtMzAtMTQ0LTMzLTE1MC0zLTktMzMtMTMtMTAxLTEzLTg5LTEtOTQtMi03Ni0xNiAyMi0xNyA4MS00NCAxMzEtNjEgNDYtMTUgMTkxLTkgMjQ5IDExIDQ3IDE2IDExNSA1NSAxMTUgNjYgMCAzLTMxIDcwLTY4IDE1MGwtNjcgMTQ1LTYxIDMtNjEgM3ptMjktMzE2Yy0yLTctMy03Ni0yLTE1MmwzLTE0MCAyOS0zYzI2LTMgMjgtMSAyMiAyMi0zIDE0LTkgMzctMTIgNTEtNSAxOS0zIDI0IDcgMjEgOC0yIDI2LTcgNDItMTAgMjctNiAyNy02IDI3IDQ0djUwbC00Mi02LTQxLTcgNiAzOWM0IDIxIDkgNTQgMTMgNzIgNiAzMCA1IDMyLTIwIDMyLTE1IDAtMjktNi0zMi0xM3oiIGZpbGw9IiNmOGY4ZjgiLz48cGF0aCBkPSJtNzIwMCAyNTAwdi0xMDBoLTIzN2wtMTctNTctMTYtNTggNzItMTUzIDcyLTE1NC0yNC0xOWMtNTgtNDQtMTMwLTYzLTI0MC02NC05OCAwLTEwOSAyLTE3MCAzMi0zNiAxNy03MSAzNi03OCA0MS0xMSA3IDEgNDEgNTkgMTYxbDczIDE1Mi0xNSA1Ny0xNSA1Ny0xMTcgMy0xMTcgM3YxOTloNzcwem0tMzMzLTcwNWMtNC0yNS05LTU2LTEzLTcwLTYtMjQtNS0yNSA0MC0xOWw0NiA3di0xMDVsLTQ2IDdjLTQxIDYtNDUgNS00MC0xMiAzLTEwIDgtMzAgMTItNDVsNi0yOGgtMTE1bDYgNDUgNyA0NS00MC02LTQwLTd2MTA2bDQxLTcgNDItNy02IDM4Yy00IDIxLTkgNTMtMTMgNzFsLTYgMzJoMTI1eiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjI0Ii8+PC9zdmc+')} +.is2d .pawn.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iNTM1IDEzNTAgMTMzMyAxMzMzIiB3aWR0aD0iMTMzIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Im0xNTkwIDI1MDB2LTk5bC04Ny0zLTg3LTMtNTYtMTgyLTU3LTE4MiAzMC0yOGM2Mi01OCA4Mi0xNDcgNTEtMjIxLTUyLTEyNi0yMTEtMTY2LTMxMS03OS05MSA4MC05NiAyMDctMTIgMjkwbDM5IDM5LTU4IDE4Mi01OCAxODEtODIgMy04MiAzdjE5OWg3NzB6IiBmaWxsPSIjNTY1MjUyIi8+PHBhdGggZD0ibTgyMCAyNTAwdi05OWw4Mi0zIDgyLTMgNTgtMTgxIDU4LTE4Mi0zOS0zOWMtMzgtMzgtNjEtOTEtNjEtMTQ0IDAtMzAgMTktODkgMjktODkgMyAwIDY1IDU5IDEzNiAxMzAgODQgODQgMTM1IDEyOCAxNDUgMTI1IDE3LTYgMjItMTAtNzcgNjhsLTYwIDQ4LTEyIDExN2MtMTYgMTU0LTE1IDE1Mi01NyAxNTJoLTM0djIwMGgtMjUweiIgZmlsbD0iIzQ0NDI0MiIvPjxwYXRoIGQ9Im0xMDcwIDI1MDB2LTEwMGgzNGM0MiAwIDQxIDIgNTctMTUybDEyLTExNyA2NC01MSA2My01MSAxMCAyNmM2IDE1IDEwIDMxIDEwIDM4IDAgMTEgMjQgODcgNzUgMjM3bDIzIDY1IDg2IDMgODYgM3YxOTloLTUyMHptOTEtNjE0LTEzMy0xMzQgNDEtNDBjNTUtNTMgMTE3LTY4IDE5MC00NyAxMTMgMzQgMTcwIDE3NiAxMTUgMjg3LTEzIDI1LTU5IDY4LTczIDY4LTMgMC02Ni02MC0xNDAtMTM0eiIgZmlsbD0iIzU2NTI1MiIvPjxwYXRoIGQ9Im0xNTkwIDI1MDB2LTk5bC04Ny0zLTg3LTMtNTYtMTgyLTU3LTE4MiAzMC0yOGM2Mi01OCA4Mi0xNDcgNTEtMjIxLTUyLTEyNi0yMTEtMTY2LTMxMS03OS05MSA4MC05NiAyMDctMTIgMjkwbDM5IDM5LTU4IDE4Mi01OCAxODEtODIgMy04MiAzdjE5OWg3NzB6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMjQiLz48L3N2Zz4=')} +.is2d .knight.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iMjc4MCAxMzUwIDEzMzMgMTMzMyIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtMzgzMCAyNTAwdi05OWwtMTA2LTMtMTA2LTMgODItNjkgODItNjktMTY4LTE2OC0xNjctMTY3IDI2LTE2YzQzLTI5IDkxLTMxIDE0MS02IDI1IDEyIDQ2IDI2IDQ2IDMxIDAgMjIgMjIgNSA2Ny01MyAyOC0zNSA1My02OCA1Ny03NSA0LTgtNjYtNjEtMjEyLTE1OWwtMjIwLTE0Ni00MiAyMmMtMTkwIDk3LTI3MyAzNDAtMTgzIDUzMSAxNiAzNSAzOSA3NSA1MSA4OWwyMSAyNS00NSA0Ni00NSA0NiA4MiA2OSA4MSA2OS0xMDYgMy0xMDYgM3YxOTloNzcweiIgZmlsbD0iIzU2NTI1MiIvPjxnIGZpbGw9IiM0NDQyNDIiPjxwYXRoIGQ9Im0zMDYwIDI1MDB2LTk5bDEwNi0zIDEwNi0zLTgxLTY5LTgyLTY5IDQ1LTQ2IDQ1LTQ2LTIxLTI1Yy0xMi0xNC0zNS01NC01MS04OS01NS0xMTYtNDctMjY0IDE5LTM3NyAzMS01MiAxMDgtMTI2IDE2Mi0xNTMgNTMtMjcgNjItMjcgMjYgMi00NiAzNS03MyA2OC0xMDMgMTI3LTEyNCAyMzkgNiA1MjUgMjY3IDU5MSAzNSA4IDYzIDE3IDY0IDIwIDEgMi05IDM0LTIxIDcybC0yMyA2N2gtMTU4djIwMGgtMzAweiIvPjxwYXRoIGQ9Im0zMzUwIDE5MjN2LTk3bDQ4IDQ3YzQwIDM5IDUwIDQ1IDYyIDM1IDEzLTExIDEzLTExIDIgMi0xMCAxMi00IDIyIDM1IDYybDQ3IDQ4aC0xOTR6Ii8+PC9nPjxwYXRoIGQ9Im0zMzYwIDI1MDB2LTEwMGgxNThsMjEtNjJjMTItMzUgMjEtNjcgMjEtNzIgMS01LTI3LTE3LTYyLTI1LTI2MS02Ni0zOTAtMzUwLTI2OC01OTEgMjctNTIgMTAzLTE0MCAxMjItMTQwIDEyIDAgNDI4IDI3OSA0MjggMjg3IDAgNi03NCAxMDYtMTAxIDEzNy01IDUtMTYgMC0yNi0xMS0zNy00My0xMjYtNTUtMTc4LTIzbC0zMCAxOC00Ny00Ni00OC00NnYxOTRoMTk1bDExNSAxMTUgMTE0IDExNC0yMCAyM2MtMTAgMTMtMjUgMjctMzMgMzItNyA0LTMwIDI0LTQ5IDQyLTIwIDE5LTQwIDM0LTQ0IDM0cy04IDUtOCAxMGMwIDYgNDIgMTAgMTA1IDEwaDEwNXYyMDBoLTQ3MHoiIGZpbGw9IiM1NjUyNTIiLz48cGF0aCBkPSJtMzgzMCAyNTAwdi05OWwtMTA2LTMtMTA2LTMgODItNjkgODItNjktMTY4LTE2OC0xNjctMTY3IDI2LTE2YzQzLTI5IDkxLTMxIDE0MS02IDI1IDEyIDQ2IDI2IDQ2IDMxIDAgMjIgMjIgNSA2Ny01MyAyOC0zNSA1My02OCA1Ny03NSA0LTgtNjYtNjEtMjEyLTE1OWwtMjIwLTE0Ni00MiAyMmMtMTkwIDk3LTI3MyAzNDAtMTgzIDUzMSAxNiAzNSAzOSA3NSA1MSA4OWwyMSAyNS00NSA0Ni00NSA0NiA4MiA2OSA4MSA2OS0xMDYgMy0xMDYgM3YxOTloNzcweiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjI0Ii8+PC9zdmc+')} +.is2d .bishop.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iMzg5MCAxMzUwIDEzMzAgMTMzMCIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNDk1MCAyNTAwdi0xMDBoLTE4NmwtMzgtMTYyYy0yMS05MC00MC0xNjgtNDMtMTc0LTItNiAzMC01NCA3Mi0xMDcgNDEtNTQgNzUtMTAyIDc1LTEwOHMtMjEtMzgtNDctNzFsLTQ3LTYxLTI2IDMxLTI3IDMyLTMyLTQ1LTMyLTQ1IDIwLTI5YzEyLTE2IDIxLTMyIDIxLTM2IDAtMTAtOTItMTI1LTk5LTEyNS0zIDEtMzcgNDItNzYgOTMtMzggNTAtOTkgMTI4LTEzMyAxNzRsLTY0IDgyIDc4IDEwMSA3OCAxMDEtMzIgMTM3Yy0xOCA3NS0zNyAxNTQtNDMgMTc1bC0xMCAzN2gtMTc5djIwMGg3NzB6IiBmaWxsPSIjNTY1MjUyIi8+PHBhdGggZD0ibTQxODAgMjUwMHYtMTAwaDE3OWwxMC0zN2M2LTIxIDI1LTEwMCA0My0xNzVsMzItMTM3LTc3LTEwMGMtNDItNTUtNzctMTAxLTc3LTEwM3M1NC0xIDExOSAybDExOSA1IDcyIDkzYzM5IDUwIDc0IDkyIDc4IDkyczggMTEgOCAyNWMxIDE0LTIgMjUtNiAyNS01IDAtMzggMTgtNzQgNDFsLTY0IDQwLTcgOTdjLTkgMTM0LTggMTMyLTYxIDEzMmgtNDR2MjAwaC0yNTB6bTQyMi02OTljLTE4LTIyLTMyLTQzLTMyLTQ4IDAtNCAxMC0yMSAyMy0zN2wyMy0yOSAzNiA0OSAzNiA0OC0yMSAyOGMtMTEgMTUtMjQgMjgtMjcgMjgtNCAwLTIxLTE4LTM4LTM5eiIgZmlsbD0iIzQ0NDI0MiIvPjxwYXRoIGQ9Im00NDMwIDI1MDB2LTEwMGg0NGM1MyAwIDUyIDIgNjEtMTMybDctOTcgNjQtNDBjMzYtMjMgNjktNDEgNzMtNDEgNyAwIDIwIDQ2IDYzIDIyM2wyMSA4N2gxODd2MjAwaC01MjB6bTE2OC01NTUtNzMtOTVoLTExMmMtNjIgMC0xMTMtMy0xMTItNyAwLTkgMzEtNTAgMTU3LTIwOCA1MC02NCA5Mi0xMjEgOTItMTI2IDAtMjAgMTgtNSA2MyA1Nmw0OCA2NC00NSA1OGMtMjUgMzItNDYgNjItNDYgNjYgMCAxMSA2MSA4NyA3MCA4NyA0IDAgMjYtMjcgNTAtNjAgMjQtMzIgNDYtNTcgNTEtNTUgNCAzIDI2IDMzIDQ5IDY2bDQxIDYxLTQ3IDYxYy0yNyAzNC02MCA3Ny03NCA5NC0xNCAxOC0yOCAzMy0zMiAzM3MtNDAtNDMtODAtOTV6IiBmaWxsPSIjNTY1MjUyIi8+PHBhdGggZD0ibTQ5NTAgMjUwMHYtMTAwaC0xODZsLTM4LTE2MmMtMjEtOTAtNDAtMTY4LTQzLTE3NC0yLTYgMzAtNTQgNzItMTA3IDQxLTU0IDc1LTEwMiA3NS0xMDhzLTIxLTM4LTQ3LTcxbC00Ny02MS0yNiAzMS0yNyAzMi0zMi00NS0zMi00NSAyMC0yOWMxMi0xNiAyMS0zMiAyMS0zNiAwLTEwLTkyLTEyNS05OS0xMjUtMyAxLTM3IDQyLTc2IDkzLTM4IDUwLTk5IDEyOC0xMzMgMTc0bC02NCA4MiA3OCAxMDEgNzggMTAxLTMyIDEzN2MtMTggNzUtMzcgMTU0LTQzIDE3NWwtMTAgMzdoLTE3OXYyMDBoNzcweiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjI0Ii8+PC9zdmc+')} +.is2d .rook.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iMTY3MCAxMzUwIDEzMzMgMTMzMyIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtMjcxMCAyNTAwdi05OWwtNjItMy02My0zLTIyLTIxMGMtMzAtMjg3LTMzLTI1NiAzNy0yOTlsNjAtMzgtMi0xNjEtMy0xNjItNTctMy01OC0zdjEwMWgtMTA5bC0zLTQ3LTMtNDhoLTE5MGwtMyA0OC0zIDQ3aC0xMDl2LTEwMWwtNTcgMy01OCAzLTMgMTYzLTIgMTYyIDQ2IDI4YzI1IDE1IDUyIDMyIDYwIDM3IDEyIDkgMTEgMzktNiAyMTUtMTEgMTEzLTIzIDIyMC0yNiAyMzhsLTUgMzJoLTEyOXYyMDBoNzcweiIgZmlsbD0iIzU2NTI1MiIvPjxnIGZpbGw9IiM0NDQyNDIiPjxwYXRoIGQ9Im0xOTQwIDI1MDB2LTEwMGgxMjlsNS0zMmMzLTE4IDE1LTEyNSAyNi0yMzggMTctMTc2IDE4LTIwNiA2LTIxNS04LTUtMzUtMjItNjAtMzdsLTQ2LTI4IDItMTYyIDMtMTYzIDU4LTMgNTctM3Y1MWMwIDQ5IDEgNTAgMzAgNTBoMzB2MjMwaDIzOGwyMzcgMS01NCAzNGMtMzAgMTktNTcgMzgtNjAgNDItMyA1LTEyIDktMTggMTAtNyAyLTY1IDM1LTEyOCA3NGwtMTE1IDcxLTEgNTFjLTEgMjktNCA5OS04IDE1N2wtNiAxMDUtMzcgMy0zOCAzdjE5OWgtMjUweiIvPjxwYXRoIGQ9Im0yMjMyIDE1NzMgMy00OCA1MC0zIDUwLTMtMyA1MS00IDUwaC05OXoiLz48L2c+PHBhdGggZD0ibTIxOTAgMjUwMXYtMTAwbDM4LTMgMzctMyA2LTEwNWM0LTU4IDctMTI4IDgtMTU3bDEtNTEgMTIyLTc2YzY4LTQxIDEyNi03MiAxMzAtNjggMyA0IDkgMzkgMTMgNzcgNCAzOSA4IDg2IDEwIDEwNSA3IDY4IDE0IDE0NiAxOSAyMDMgMyAzMiA4IDYzIDExIDY4IDQgNSAzMyA5IDY2IDloNTl2MjAwaC01MjB6bS0xMC03NjZ2LTExNWgxNDlsMy00NyAzLTQ4aDkwbDMgNDggMyA0N2gxMDl2LTEwMWw1OCAzIDU3IDMgMyAxNjMgMiAxNjJoLTQ4MHoiIGZpbGw9IiM1NjUyNTIiLz48cGF0aCBkPSJtMjcxMCAyNTAwdi05OWwtNjItMy02My0zLTIyLTIxMGMtMzAtMjg3LTMzLTI1NiAzNy0yOTlsNjAtMzgtMi0xNjEtMy0xNjItNTctMy01OC0zdjEwMWgtMTA5bC0zLTQ3LTMtNDhoLTE5MGwtMyA0OC0zIDQ3aC0xMDl2LTEwMWwtNTcgMy01OCAzLTMgMTYzLTIgMTYyIDQ2IDI4YzI1IDE1IDUyIDMyIDYwIDM3IDEyIDkgMTEgMzktNiAyMTUtMTEgMTEzLTIzIDIyMC0yNiAyMzhsLTUgMzJoLTEyOXYyMDBoNzcweiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjI0Ii8+PC9zdmc+')} +.is2d .queen.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iNTAxMCAxMzUwIDEzMzMgMTMzMyIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNjA2MCAyNTAwdi0xMDBoLTE3OGwtMTAtNDdjLTYtMjctMTgtODYtMjctMTMzbC0xNy04NSAxMDctMjMzYzU5LTEyOCAxMDUtMjM1IDEwMy0yMzctMi0zLTI0IDEtNDkgOC00MyAxMi00NCAxNC00NyA1OC0zIDQwLTEwIDU0LTYyIDExMGwtNTkgNjQtMS05NGMwLTg5IDItOTcgMjYtMTIybDI3LTI4LTIzLTYxYy0xMi0zMy0yNS02MC0yOS02MHMtMjYgMjAtNTAgNDRsLTQyIDQzIDE1IDM2YzE0IDM1IDEzIDM5LTIyIDEyMS0yMCA0OC0zOSA4Ni00MyA4Ni0zIDAtMjItMzktNDItODYtMzUtODMtMzYtODctMjItMTIybDE2LTM2LTQzLTQzYy0yMy0yNC00NS00My00OS00My03IDAtNDkgOTctNDkgMTE1IDAgNiAxMSAyMiAyNSAzNSAyMyAyMiAyNSAzMCAyNSAxMjJ2OTlsLTYwLTY4Yy01NC02MC02MC03Mi02MC0xMTAgMC00Ny02LTUyLTc3LTY3bC0zMi03IDExMCAyMzggMTEwIDIzOC0xNiA4NWMtOSA0Ny0yMSAxMDYtMjcgMTMzbC0xMCA0N2gtMTc4djIwMGg3NjB6IiBmaWxsPSIjNTY1MjUyIi8+PGcgZmlsbD0iIzQ0NDI0MiI+PHBhdGggZD0ibTUzMDAgMjUwMHYtMTAwaDE3OGwxMC00N2M2LTI3IDE4LTg2IDI3LTEzM2wxNi04NS0xMTAtMjM4LTExMC0yMzggMzIgN2M3MSAxNSA3NyAyMCA3NyA2NyAwIDM4IDYgNTAgNjAgMTEwbDYwIDY4di05OWMwLTkyLTItMTAwLTI1LTEyMi0xNC0xMy0yNS0yOS0yNS0zNSAwLTIyIDQyLTExNSA1Mi0xMTUgNSAwIDcgNCA0IDgtMyA1IDIyIDEzNCA1NCAyODggMzMgMTUzIDYwIDI4MiA2MCAyODYgMCA1IDM4IDggODUgOCA2NyAwIDg1IDMgODUgMTQgMCA4IDMgMjMgNiAzMyA0IDEyIDMgMTQtMyA1LTctOS0zMCAxLTk0IDQwbC04NCA1My0zIDYzLTMgNjJoLTEwOXYyMDBoLTI0MHoiLz48cGF0aCBkPSJtNTcyMCAxOTkyYzAtNy0xMS0zNS0yNS02NC0xNC0yOC0yMS01NC0xNi01NyA0LTMgMjQtNDMgNDQtODkgMzUtODAgMzUtODQgMjEtMTE5bC0xNS0zNiA0Mi00M2MyNC0yNCA0Ni00NCA0OS00NCA4IDAtODMgNDQ3LTkzIDQ1Ni00IDQtNyAyLTctNHoiLz48L2c+PHBhdGggZD0ibTU1NDAgMjUwMHYtMTAwaDEwOWwzLTYyIDMtNjMgODQtNTNjNjEtMzggODctNDkgOTItNDAgMyA3IDEyIDQyIDE4IDc4IDcgMzYgMTcgODIgMjMgMTAzbDExIDM3aDE3N3YyMDBoLTUyMHptMTIwLTM3OGMwLTQtMjctMTMzLTYwLTI4Ny0zMy0xNTMtNTctMjgxLTU0LTI4NCAyLTMgMjMgMTMgNDUgMzVsNDAgNDAtMTYgMzljLTE0IDMxLTE0IDQzLTQgNjQgMTIgMjYgMjkgNjUgNDcgMTExIDUgMTQgMjIgNTEgMzYgODNzMjYgNjMgMjYgNzBjMSA0MCAyMy00NCA2MC0yMzAgMjQtMTE3IDQ3LTIxMCA1MS0yMDcgNSAzIDkgMTMgOSAyMyAwIDkgNCAyMSA5IDI3IDIyIDI0IDIxIDYxLTQgODQtMjMgMjItMjUgMzAtMjUgMTE3IDAgNTEgNCA5MyA4IDkzIDUgMCAyNC0xOSA0Mi00MiAxOS0yNCA0Mi00OSA1Mi01NiAxMy05IDE4LTI2IDE4LTU3IDAtMjQgNi00NyAxMy01MiAxOS0xMiA4MS0zMyA4NS0yOCAzIDItOCAzMC0yMyA2Mi04MyAxNzctMTI2IDI3Mi0xNTkgMzQ2bC0yNSA1N2gtODVjLTQ4IDAtODYtMy04Ni04eiIgZmlsbD0iIzU2NTI1MiIvPjxwYXRoIGQ9Im02MDYwIDI1MDB2LTEwMGgtMTc4bC0xMC00N2MtNi0yNy0xOC04Ni0yNy0xMzNsLTE3LTg1IDEwNy0yMzNjNTktMTI4IDEwNS0yMzUgMTAzLTIzNy0yLTMtMjQgMS00OSA4LTQzIDEyLTQ0IDE0LTQ3IDU4LTMgNDAtMTAgNTQtNjIgMTEwbC01OSA2NC0xLTk0YzAtODkgMi05NyAyNi0xMjJsMjctMjgtMjMtNjFjLTEyLTMzLTI1LTYwLTI5LTYwcy0yNiAyMC01MCA0NGwtNDIgNDMgMTUgMzZjMTQgMzUgMTMgMzktMjIgMTIxLTIwIDQ4LTM5IDg2LTQzIDg2LTMgMC0yMi0zOS00Mi04Ni0zNS04My0zNi04Ny0yMi0xMjJsMTYtMzYtNDMtNDNjLTIzLTI0LTQ1LTQzLTQ5LTQzLTcgMC00OSA5Ny00OSAxMTUgMCA2IDExIDIyIDI1IDM1IDIzIDIyIDI1IDMwIDI1IDEyMnY5OWwtNjAtNjhjLTU0LTYwLTYwLTcyLTYwLTExMCAwLTQ3LTYtNTItNzctNjdsLTMyLTcgMTEwIDIzOCAxMTAgMjM4LTE2IDg1Yy05IDQ3LTIxIDEwNi0yNyAxMzNsLTEwIDQ3aC0xNzh2MjAwaDc2MHoiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIyNCIvPjwvc3ZnPg==')} +.is2d .king.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iNjE1MCAxMzUwIDEzMzMgMTMzMyIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNzIwMCAyNTAwdi0xMDBoLTIzN2wtMTctNTctMTYtNTggNzItMTUzIDcyLTE1NC0yNC0xOWMtNTgtNDQtMTMwLTYzLTI0MC02NC05OCAwLTEwOSAyLTE3MCAzMi0zNiAxNy03MSAzNi03OCA0MS0xMSA3IDEgNDEgNTkgMTYxbDczIDE1Mi0xNSA1Ny0xNSA1Ny0xMTcgMy0xMTcgM3YxOTloNzcwem0tMzMzLTcwNWMtNC0yNS05LTU2LTEzLTcwLTYtMjQtNS0yNSA0MC0xOWw0NiA3di0xMDVsLTQ2IDdjLTQxIDYtNDUgNS00MC0xMiAzLTEwIDgtMzAgMTItNDVsNi0yOGgtMTE1bDYgNDUgNyA0NS00MC02LTQwLTd2MTA2bDQxLTcgNDItNy02IDM4Yy00IDIxLTkgNTMtMTMgNzFsLTYgMzJoMTI1eiIgZmlsbD0iIzU2NTI1MiIvPjxwYXRoIGQ9Im02NDMwIDI1MDB2LTk5bDExNy0zIDExNy0zIDE1LTU3IDE1LTU3LTcyLTE1MGMtNDAtODMtNzItMTUxLTcyLTE1M3M0NS0yIDk5IDBjNjUgMiAxMDEgNyAxMDQgMTUgMiA3IDE3IDc0IDMyIDE1MGwyOCAxMzdoNThjNDMgMCA1OCA0IDYzIDE2IDggMjEgOCAyNC00IDI0LTUgMC0zOSAxOC03NSA0MC01NSAzNC03NCA0MC0xMjAgNDBoLTU1djIwMGgtMjUwem0zMjQtNjkyYzQtMTggOS01MCAxMy03MWw2LTM4LTQyIDctNDEgN3YtMTA2bDQwIDcgNDAgNi03LTQ1Yy02LTQ0LTUtNDUgMjMtNDVoMjl2MzEwaC0zNGMtMzIgMC0zMy0xLTI3LTMyem0xNzktMTQ4YzAtMzAgMi00MyA0LTI3IDIgMTUgMiAzOSAwIDU1LTIgMTUtNCAyLTQtMjh6IiBmaWxsPSIjNDQ0MjQyIi8+PHBhdGggZD0ibTY2ODAgMjUwMHYtMTAwaDU1YzQ2IDAgNjUtNiAxMjAtNDAgMzYtMjIgNjktNDAgNzQtNDAgNCAwIDE0IDE4IDIxIDQwbDEzIDQwaDIzN3YyMDBoLTUyMHptMTA1LTM1N2MtMTUtNzYtMzAtMTQ0LTMzLTE1MC0zLTktMzMtMTMtMTAxLTEzLTg5LTEtOTQtMi03Ni0xNiAyMi0xNyA4MS00NCAxMzEtNjEgNDYtMTUgMTkxLTkgMjQ5IDExIDQ3IDE2IDExNSA1NSAxMTUgNjYgMCAzLTMxIDcwLTY4IDE1MGwtNjcgMTQ1LTYxIDMtNjEgM3ptMjktMzE2Yy0yLTctMy03Ni0yLTE1MmwzLTE0MCAyOS0zYzI2LTMgMjgtMSAyMiAyMi0zIDE0LTkgMzctMTIgNTEtNSAxOS0zIDI0IDcgMjEgOC0yIDI2LTcgNDItMTAgMjctNiAyNy02IDI3IDQ0djUwbC00Mi02LTQxLTcgNiAzOWM0IDIxIDkgNTQgMTMgNzIgNiAzMCA1IDMyLTIwIDMyLTE1IDAtMjktNi0zMi0xM3oiIGZpbGw9IiM1NjUyNTIiLz48cGF0aCBkPSJtNzIwMCAyNTAwdi0xMDBoLTIzN2wtMTctNTctMTYtNTggNzItMTUzIDcyLTE1NC0yNC0xOWMtNTgtNDQtMTMwLTYzLTI0MC02NC05OCAwLTEwOSAyLTE3MCAzMi0zNiAxNy03MSAzNi03OCA0MS0xMSA3IDEgNDEgNTkgMTYxbDczIDE1Mi0xNSA1Ny0xNSA1Ny0xMTcgMy0xMTcgM3YxOTloNzcwem0tMzMzLTcwNWMtNC0yNS05LTU2LTEzLTcwLTYtMjQtNS0yNSA0MC0xOWw0NiA3di0xMDVsLTQ2IDdjLTQxIDYtNDUgNS00MC0xMiAzLTEwIDgtMzAgMTItNDVsNi0yOGgtMTE1bDYgNDUgNyA0NS00MC02LTQwLTd2MTA2bDQxLTcgNDItNy02IDM4Yy00IDIxLTkgNTMtMTMgNzFsLTYgMzJoMTI1eiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjI0Ii8+PC9zdmc+')} diff --git a/public/piece-css/shapes.css b/public/piece-css/shapes.css new file mode 100644 index 0000000000..ddc712ba03 --- /dev/null +++ b/public/piece-css/shapes.css @@ -0,0 +1,12 @@ +.is2d .pawn.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik00MCA0MHYxMjBoMTIwVjQwem00MCA0MGg0MHY0MEg4MHoiIGZpbGw9IiNmZmYiIGZpbHRlcj0idXJsKCNhKSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49ImJldmVsIiBzdHJva2Utd2lkdGg9IjYiIHRyYW5zZm9ybT0ibWF0cml4KC45IDAgMCAuOSAxMS44IDExLjgpIi8+PC9zdmc+')} +.is2d .knight.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik0zNS41IDEyMi44MzlWNzkuNTY1bDExMi42Ny00Ni41MDggMTUuMjYyIDM2Ljk3My03NS41MTUgMzEuMTcyIDc1LjUxNSAzMS4xNzEtMTUuMjYyIDM2Ljk3NHoiIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjYiIHN0cm9rZS1saW5lam9pbj0iYmV2ZWwiIGZpbHRlcj0idXJsKCNhKSIvPjwvc3ZnPg==')} +.is2d .bishop.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik02OC43ODcgNDAuNTAzTDEwMCA3MS43MTZsMzEuMjEzLTMxLjIxMyAzNS4zNTYtNy4wNzItNy4wNzIgMzUuMzU2TDEyOC4yODQgMTAwbDMxLjIxMyAzMS4yMTMgNy4wNzIgMzUuMzU2LTM1LjM1Ni03LjA3MkwxMDAgMTI4LjI4NGwtMzEuMjEzIDMxLjIxMy0zNS4zNTYgNy4wNzIgNy4wNzItMzUuMzU2TDcxLjcxNiAxMDAgNDAuNTAzIDY4Ljc4NyAzMy40MyAzMy40M3oiIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjYiIHN0cm9rZS1saW5lam9pbj0iYmV2ZWwiIGZpbHRlcj0idXJsKCNhKSIvPjwvc3ZnPg==')} +.is2d .rook.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik03NSAxNWg1MHY2MGg2MHY1MGgtNjB2NjBINzV2LTYwSDE1Vjc1aDYweiIgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iNiIgc3Ryb2tlLWxpbmVqb2luPSJiZXZlbCIgZmlsdGVyPSJ1cmwoI2EpIi8+PC9zdmc+')} +.is2d .queen.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik04MCAyMHYzMS43MTVMNTcuNTc0IDI5LjI4OSAyOS4yOSA1Ny41NzQgNTEuNzE1IDgwSDIwdjQwaDMxLjcxNWwtMjIuNDI2IDIyLjQyNiAyOC4yODUgMjguMjg1TDgwIDE0OC4yODVWMTgwaDQwdi0zMS43MTVsMjIuNDI2IDIyLjQyNiAyOC4yODUtMjguMjg1TDE0OC4yODUgMTIwSDE4MFY4MGgtMzEuNzE1bDIyLjQyNi0yMi40MjYtMjguMjg1LTI4LjI4NUwxMjAgNTEuNzE1VjIwem0yMCA1OC4wMzNBMjEuOTY2IDIxLjk2NiAwIDAgMSAxMjEuOTY3IDEwMCAyMS45NjYgMjEuOTY2IDAgMCAxIDEwMCAxMjEuOTY3IDIxLjk2NiAyMS45NjYgMCAwIDEgNzguMDMzIDEwMCAyMS45NjYgMjEuOTY2IDAgMCAxIDEwMCA3OC4wMzN6IiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSI2IiBzdHJva2UtbGluZWpvaW49ImJldmVsIiBmaWx0ZXI9InVybCgjYSkiLz48L3N2Zz4=')} +.is2d .king.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik02OC43ODcgMjQuNjQ1TDI0LjY0NSA2OC43ODd2NjIuNDI2bDQ0LjE0MiA0NC4xNDJoNjIuNDI2bDQ0LjE0Mi00NC4xNDJWNjguNzg3bC00NC4xNDItNDQuMTQyek04OCA2Ny44NTdoMjRWODhoMjAuMTQzdjI0SDExMnYyMC4xNDNIODhWMTEySDY3Ljg1N1Y4OEg4OHoiIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjYiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGZpbHRlcj0idXJsKCNhKSIvPjwvc3ZnPg==')} +.is2d .pawn.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik00MCA0MHYxMjBoMTIwVjQwem00MCA0MGg0MHY0MEg4MHoiIGZpbGw9IiMzMzMiIGZpbHRlcj0idXJsKCNhKSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49ImJldmVsIiBzdHJva2Utd2lkdGg9IjYiIHRyYW5zZm9ybT0ibWF0cml4KC45IDAgMCAuOSAxMS44IDExLjgpIi8+PC9zdmc+')} +.is2d .knight.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik0zNS41IDEyMi44MzlWNzkuNTY1bDExMi42Ny00Ni41MDggMTUuMjYyIDM2Ljk3My03NS41MTUgMzEuMTcyIDc1LjUxNSAzMS4xNzEtMTUuMjYyIDM2Ljk3NHoiIGZpbGw9IiMzMzMiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjYiIHN0cm9rZS1saW5lam9pbj0iYmV2ZWwiIGZpbHRlcj0idXJsKCNhKSIvPjwvc3ZnPg==')} +.is2d .bishop.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik02OC43ODcgNDAuNTAzTDEwMCA3MS43MTZsMzEuMjEzLTMxLjIxMyAzNS4zNTYtNy4wNzItNy4wNzIgMzUuMzU2TDEyOC4yODQgMTAwbDMxLjIxMyAzMS4yMTMgNy4wNzIgMzUuMzU2LTM1LjM1Ni03LjA3MkwxMDAgMTI4LjI4NGwtMzEuMjEzIDMxLjIxMy0zNS4zNTYgNy4wNzIgNy4wNzItMzUuMzU2TDcxLjcxNiAxMDAgNDAuNTAzIDY4Ljc4NyAzMy40MyAzMy40M3oiIGZpbGw9IiMzMzMiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjYiIHN0cm9rZS1saW5lam9pbj0iYmV2ZWwiIGZpbHRlcj0idXJsKCNhKSIvPjwvc3ZnPg==')} +.is2d .rook.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik03NSAxNWg1MHY2MGg2MHY1MGgtNjB2NjBINzV2LTYwSDE1Vjc1aDYweiIgZmlsbD0iIzMzMyIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iNiIgc3Ryb2tlLWxpbmVqb2luPSJiZXZlbCIgZmlsdGVyPSJ1cmwoI2EpIi8+PC9zdmc+')} +.is2d .queen.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik04MCAyMHYzMS43MTVMNTcuNTc0IDI5LjI4OSAyOS4yOSA1Ny41NzQgNTEuNzE1IDgwSDIwdjQwaDMxLjcxNWwtMjIuNDI2IDIyLjQyNiAyOC4yODUgMjguMjg1TDgwIDE0OC4yODVWMTgwaDQwdi0zMS43MTVsMjIuNDI2IDIyLjQyNiAyOC4yODUtMjguMjg1TDE0OC4yODUgMTIwSDE4MFY4MGgtMzEuNzE1bDIyLjQyNi0yMi40MjYtMjguMjg1LTI4LjI4NUwxMjAgNTEuNzE1VjIwem0yMCA1OC4wMzNBMjEuOTY2IDIxLjk2NiAwIDAgMSAxMjEuOTY3IDEwMCAyMS45NjYgMjEuOTY2IDAgMCAxIDEwMCAxMjEuOTY3IDIxLjk2NiAyMS45NjYgMCAwIDEgNzguMDMzIDEwMCAyMS45NjYgMjEuOTY2IDAgMCAxIDEwMCA3OC4wMzN6IiBmaWxsPSIjMzMzIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSI2IiBzdHJva2UtbGluZWpvaW49ImJldmVsIiBmaWx0ZXI9InVybCgjYSkiLz48L3N2Zz4=')} +.is2d .king.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik02OC43ODcgMjQuNjQ1TDI0LjY0NSA2OC43ODd2NjIuNDI2bDQ0LjE0MiA0NC4xNDJoNjIuNDI2bDQ0LjE0Mi00NC4xNDJWNjguNzg3bC00NC4xNDItNDQuMTQyek04OCA2Ny44NTdoMjRWODhoMjAuMTQzdjI0SDExMnYyMC4xNDNIODhWMTEySDY3Ljg1N1Y4OEg4OHoiIGZpbGw9IiMzMzMiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjYiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGZpbHRlcj0idXJsKCNhKSIvPjwvc3ZnPg==')} diff --git a/public/piece-css/spatial.css b/public/piece-css/spatial.css new file mode 100644 index 0000000000..b9f830a3fc --- /dev/null +++ b/public/piece-css/spatial.css @@ -0,0 +1,12 @@ +.is2d .pawn.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48bGluZWFyR3JhZGllbnQgaWQ9ImEiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjUwLjMzMyIgeDI9IjY3MS4zMzMiIHkxPSI1NDEuNjY3IiB5Mj0iNzE4LjMzMyI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZWRlM2RlIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZDBiMDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjY1LjMzMyIgeDI9IjY0NC42NjciIHkxPSI2MDUiIHkyPSI2MDUiPjxzdG9wIG9mZnNldD0iMCIvPjxzdG9wIG9mZnNldD0iMSIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZD0iTTAgMGgyMDB2MjAwSDB6IiBmaWxsPSJub25lIi8+PHBhdGggZD0iTTYzNi42NjcgNjA1YzAgMTAyLjE3My04MS4zMzUgMTg1LTE4MS42NjcgMTg1cy0xODEuNjY3LTgyLjgyNy0xODEuNjY3LTE4NVMzNTQuNjY4IDQyMCA0NTUgNDIwczE4MS42NjcgODIuODI3IDE4MS42NjcgMTg1eiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTMuMDQ4IC4zODEpIHNjYWxlKC4yMjg1NykiIG9wYWNpdHk9Ii45OSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2Utd2lkdGg9IjE2IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGZpbGw9InVybCgjYSkiIHN0cm9rZT0idXJsKCNiKSIvPjwvc3ZnPg==')} +.is2d .knight.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48bGluZWFyR3JhZGllbnQgaWQ9ImEiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iODM3Ljg2OSIgeDI9Ijk2OS44NjYiIHkxPSIyNTguNTUiIHkyPSIzODguODM2Ij48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNlZGUzZGUiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNkMGIwOTAiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iYiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI4MjcuOTI3IiB4Mj0iOTc0LjU2IiB5MT0iMzA0LjQ0MyIgeTI9IjMwNC40NDMiPjxzdG9wIG9mZnNldD0iMCIvPjxzdG9wIG9mZnNldD0iMSIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZD0iTTAgMGgyMDB2MjAwSDB6IiBmaWxsPSJub25lIi8+PHBhdGggZD0iTTg4Ni4wMDMgMjIwLjIzYy0uMzg2IDI2LjU5NS45NzIgMTYuNTUyLTE1LjgxIDQuMjc0IDIuNTkgMTcuMzQ5LjgzMSAxNy45Mi0zLjY1MiAyNS4zNDUtMi40NTQgNC4wNjMtNC42MTcgMTYuODU2LTYuMTUyIDE5LjY3Ni05LjMwNCAxNy4wODctMzAuNjcgMzkuMzk0LTMwLjYzNCA0Ni42NjYuMDQ3IDkuMjA1IDEwLjk5NSAxNy40NDUgMjEuMDEgNy43MS05LjM3IDEzLjcxNyAxOC45MTgtLjA2MSAzMC43NzMtOC41MjEgMTUuNjkxIDkuNjYgMzcuNjE0LS45MSAzOC4wMjEtMTYuNDMyIDcuMTQxIDM1LjEwOC01OS41NCA0MS4yMDUtNjMuMTAyIDg2Ljc0MyA0OS42OTcgMTEuMzQ1IDc3LjM3Ny0yNS42MTcgMTA3LjY2OCAyLjk2NSAxNS40ODUtNDQuODk3IDE2LjkxNC0xMTkuOTQ2LTU1LjA3Mi0xNDguMDg0LTkuNzg0LTMuODI0LTEzLjg5NS0xMy42NjItMjMuMDUtMjAuMzQzem0tLjMgNDkuNTI1Yy0xLjYyOCAyLjMwOC01LjA1IDYuMDc2LTguMDUxIDUuNTI0LTIuNzc2LS41MS0zLjg5Mi0xLjQ1LTQuMDItNC43MzgtLjEwOC0yLjc2NyA5LjY5OC0yLjY3OCAxMi4wNy0uNzg2eiIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2Utd2lkdGg9IjMuNjU3IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGZpbGw9InVybCgjYSkiIHN0cm9rZT0idXJsKCNiKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTgwMCAtMjAwKSIvPjwvc3ZnPg==')} +.is2d .bishop.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjYzMi4yMjUiIHgyPSI3NjYuODYxIiB4bGluazpocmVmPSIjYSIgeTE9IjMwMi41OTEiIHkyPSIzNDMuMzUzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJhIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNlZGUzZGUiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNkMGIwOTAiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iZCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2MzIuMjI1IiB4Mj0iNjk5LjQ4NSIgeGxpbms6aHJlZj0iI2IiIHkxPSIzNzQuNTg2IiB5Mj0iMzc0LjU4NiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYiI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNjI4LjExIiB4Mj0iNzYyLjc0NyIgeGxpbms6aHJlZj0iI2EiIHkxPSIzMDIuNTkxIiB5Mj0iMzQzLjM1MyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2OTkuMjk3IiB4Mj0iNzY2LjU1NiIgeGxpbms6aHJlZj0iI2IiIHkxPSIzNzQuNTg2IiB5Mj0iMzc0LjU4NiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2MjkuOTM5IiB4Mj0iNzY0LjU3NSIgeGxpbms6aHJlZj0iI2EiIHkxPSIzMDIuNTkxIiB5Mj0iMzQzLjM1MyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2NTYuMjMzIiB4Mj0iNzM3LjY3MiIgeGxpbms6aHJlZj0iI2IiIHkxPSIzNTAuODE3IiB5Mj0iMzUwLjgxNyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2NDQuMjI3IiB4Mj0iNzU0LjAxNSIgeGxpbms6aHJlZj0iI2IiIHkxPSIyOTMuMzY0IiB5Mj0iMjkzLjM2NCIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2NzMuNzQ5IiB4Mj0iNzE0LjUzOCIgeGxpbms6aHJlZj0iI2EiIHkxPSIyMzkuMzUzIiB5Mj0iMjUxLjU0MyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iayIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2ODEuNjkxIiB4Mj0iNzE3Ljk2NiIgeGxpbms6aHJlZj0iI2IiIHkxPSIyMzIuMzAxIiB5Mj0iMjMyLjMwMSIvPjxwYXRoIGQ9Ik0wIDBoMjAwdjIwMEgweiIgZmlsbD0ibm9uZSIvPjxnIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjMuNjU3Ij48cGF0aCBkPSJNNjk3LjY1NiAzNTguMDczYy0xLjIyMyAyLjQ0Ny02My42MDMgMzMuMDI1LTYzLjYwMyAzMy4wMjVsNTEuNTQ1LTYuNTI0eiIgZmlsbD0idXJsKCNjKSIgc3Ryb2tlPSJ1cmwoI2QpIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNjAwIC0yMDApIi8+PHBhdGggZD0iTTcwMS4xMjUgMzU4LjA3M2MxLjIyMyAyLjQ0NyA2My42MDMgMzMuMDI1IDYzLjYwMyAzMy4wMjVsLTU0LjU5My02LjUyNHoiIGZpbGw9InVybCgjZSkiIHN0cm9rZT0idXJsKCNmKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTYwMCAtMjAwKSIvPjxwYXRoIGQ9Ik02NzUuMDMzIDM0Mi4yMjNjLTEuMzc1IDIuNzUtMTYuOTcxIDE5LjMxNy0xNi45NzEgMTkuMzE3bDc3Ljc4MiA1LjM1My0xOS44MjUtMzIuMTUzeiIgZmlsbD0idXJsKCNnKSIgc3Ryb2tlPSJ1cmwoI2gpIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNjAwIC0yMDApIi8+PHBhdGggZD0iTTY5OC43MiAyMzUuNjMzYy0xLjM3NiAyLjc1LTUyLjY2NCAxMTUuNDYyLTUyLjY2NCAxMTUuNDYybDEwNi4xMy05LjM0OHptMTAuMzIyIDM1Ljc0NWw4LjEwNSAxNy43Ni00MS44MSA0MS40MXMzMi4zMy01Ni40MTkgMzMuNzA1LTU5LjE3eiIgZmlsbD0idXJsKCNnKSIgc3Ryb2tlPSJ1cmwoI2kpIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNjAwIC0yMDApIi8+PHBhdGggZD0iTTY5OS4xOCAyMTYuNzVjLTEuMzc2IDIuNzUyLTE1LjY2IDI2LjA3MS0xNS42NiAyNi4wNzFsMzIuNjE4IDUuMDN6IiBmaWxsPSJ1cmwoI2opIiBzdHJva2U9InVybCgjaykiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02MDAgLTIwMCkiLz48L2c+PC9zdmc+')} +.is2d .rook.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJiIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjQyMC4yNzgiIHgyPSI1NzYuNDkiIHkxPSIyNjUuNDI4IiB5Mj0iMzcxLjU2MSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZWRlM2RlIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZDBiMDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImMiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNDUyLjI2NyIgeDI9IjU1MC40IiB4bGluazpocmVmPSIjYSIgeTE9IjMyNS40MSIgeTI9IjMyNS40MSIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNDI2Ljc0MyIgeDI9IjQ2Ni4yMSIgeGxpbms6aHJlZj0iI2EiIHkxPSIyNTguNTUyIiB5Mj0iMjU4LjU1MiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0ODEuMjE5IiB4Mj0iNTE4LjAxOSIgeGxpbms6aHJlZj0iI2EiIHkxPSIyNTUuODg2IiB5Mj0iMjU1Ljg4NiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI1NDAuNjQ4IiB4Mj0iNTczLjI1NyIgeGxpbms6aHJlZj0iI2EiIHkxPSIyNTkuMTI0IiB5Mj0iMjU5LjEyNCIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0MzUuNTA1IiB4Mj0iNTMwLjk3MSIgeGxpbms6aHJlZj0iI2EiIHkxPSIzNzguODE5IiB5Mj0iMzc4LjgxOSIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI1MzkuMTI0IiB4Mj0iNTY0Ljg3NiIgeGxpbms6aHJlZj0iI2EiIHkxPSIzNzEuOTYyIiB5Mj0iMzcxLjk2MiIvPjxwYXRoIGQ9Ik0wIDBoMjAwdjIwMEgweiIgZmlsbD0ibm9uZSIvPjxnIGZpbGw9InVybCgjYikiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjMuNjU3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNDAwIC0yMDApIj48cGF0aCBkPSJNNDU0LjA5NSAyNzAuNTUyaDk0LjQ3NnYxMDkuNzE1aC05NC40NzZ6IiBzdHJva2U9InVybCgjYykiLz48cGF0aCBkPSJNNDI4LjU3MSAyNDAuMDc2aDM1LjgxdjM2Ljk1M2gtMzUuODF6IiBzdHJva2U9InVybCgjZCkiLz48cGF0aCBkPSJNNDgzLjA0OCAyNDguMDc2aDMzLjE0MnYxNS42MmgtMzMuMTQyeiIgc3Ryb2tlPSJ1cmwoI2UpIi8+PHBhdGggZD0iTTU0Mi40NzYgMjMxLjMxNGgyOC45NTN2NTUuNjJoLTI4Ljk1M3oiIHN0cm9rZT0idXJsKCNmKSIvPjxwYXRoIGQ9Ik00MzcuMzMzIDM3MS4yaDkxLjgxdjE1LjIzOGgtOTEuODF6IiBzdHJva2U9InVybCgjZykiLz48cGF0aCBkPSJNNTQwLjk1MiAzNTcuMTA1aDIyLjA5NnYyOS43MTRoLTIyLjA5NnoiIHN0cm9rZT0idXJsKCNoKSIvPjwvZz48L3N2Zz4=')} +.is2d .queen.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjI2NS4yODkiIHgyPSIzMDYuNjY3IiB4bGluazpocmVmPSIjYSIgeTE9IjI2NS42MjciIHkyPSIzMzQuMTk5Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJhIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNlZGUzZGUiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNkMGIwOTAiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iZCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIyNTIuMzM3IiB4Mj0iMzUzLjE0MyIgeGxpbms6aHJlZj0iI2IiIHkxPSIyOTYuMTA0IiB5Mj0iMjk2LjEwNCIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYiI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjM4LjEyMSIgeDI9IjM2NC4zMTciIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjU0LjgzMiIgeTI9IjM3MC42NDIiLz48bGluZWFyR3JhZGllbnQgaWQ9ImYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjE4LjMxMiIgeDI9IjM4Mi45ODMiIHhsaW5rOmhyZWY9IiNiIiB5MT0iMjk1LjIxMyIgeTI9IjI5NS4yMTMiLz48bGluZWFyR3JhZGllbnQgaWQ9ImciIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjQ1LjQ4NiIgeDI9IjM1MS4yMzgiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMzgwLjUzMyIgeTI9IjM4MC41MzMiLz48bGluZWFyR3JhZGllbnQgaWQ9ImgiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjQ1LjQ4NiIgeDI9IjM1MS4yMzgiIHhsaW5rOmhyZWY9IiNiIiB5MT0iMzgwLjUzMyIgeTI9IjM4MC41MzMiLz48cGF0aCBkPSJNMCAwaDIwMHYyMDBIMHoiIGZpbGw9Im5vbmUiLz48ZyBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIzLjY1NyI+PHBhdGggZD0iTTM1MS4zMTQgMjM0LjI2NGMtNDcuODU4IDE0My40LTU1LjI1MyAxNDMuNjY2LTk3LjE0My42NzktLjI1NyA1OC4yNzEgNy40OTIgOTkuMjYgMTguNzIyIDEyM2g1NC40MTRjMTIuMzA3LTIzLjg1MSAyMS44NC02NS4wOTMgMjQuMDA3LTEyMy42Nzl6IiBmaWxsPSJ1cmwoI2MpIiBzdHJva2U9InVybCgjZCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMDAgLTIwMCkiLz48cGF0aCBkPSJNMzAyLjU0OCAyMjQuNDgxYy0xNy4zNjggOTQuMTExLTguODQ3IDE5NC45ODItODIuNDA4IDQyLjU4NiAyLjUxOCA0Ni41OTMgMTMuNDQ1IDc5LjYwNiAzMi44MjIgOTguODc4aDkxLjljMTkuNzQ0LTE5LjAzMiAzMS43MS01MS41MzMgMzYuMjkzLTk3LjY1LTcwLjI0OSAxNTIuNDI5LTY0LjE1IDUwLjM4NC03OC42MDctNDMuODE0eiIgZmlsbD0idXJsKCNlKSIgc3Ryb2tlPSJ1cmwoI2YpIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjAwIC0yMDApIi8+PHBhdGggZD0iTTI0Ny4zMTQgMzczLjEwNUgzNDkuNDF2MTQuODU3SDI0Ny4zMTR6IiBmaWxsPSJ1cmwoI2cpIiBzdHJva2U9InVybCgjaCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMDAgLTIwMCkiLz48L2c+PC9zdmc+')} +.is2d .king.white {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ijg1LjczIiB4Mj0iMTIyLjQxNyIgeGxpbms6aHJlZj0iI2EiIHkxPSIyNDAuMzI0IiB5Mj0iMjcwLjYxNCIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZWRlM2RlIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZDBiMDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNzIuMzIzIiB4Mj0iMTI5Ljg2NiIgeGxpbms6aHJlZj0iI2IiIHkxPSIyNTMuNzMxIiB5Mj0iMjUzLjczMSIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYiI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMzQuMzA0IiB4Mj0iMTU4LjYzIiB4bGluazpocmVmPSIjYSIgeTE9IjI1OC4zNDQiIHkyPSIzNjkuMTU3Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJmIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjE5LjQwNyIgeDI9IjE4Mi40NjUiIHhsaW5rOmhyZWY9IiNiIiB5MT0iMzE5LjcyMyIgeTI9IjMxOS43MjMiLz48bGluZWFyR3JhZGllbnQgaWQ9ImciIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMzcuMjgzIiB4Mj0iMTYwLjYxNiIgeGxpbms6aHJlZj0iI2EiIHkxPSIzNzcuNTE3IiB5Mj0iMzc4LjAxNCIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0My41MDUiIHgyPSIxNTYuODc2IiB4bGluazpocmVmPSIjYiIgeTE9IjM4MC45NTIiIHkyPSIzODAuOTUyIi8+PHBhdGggZD0iTTAgMGgyMDB2MjAwSDB6IiBmaWxsPSJub25lIi8+PGcgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMy42NTciPjxwYXRoIGQ9Ik05Mi4xMTYgMjI1LjE0NXYxMy42MjhINzQuMTV2MTUuNTVoMTcuOTY1djI3Ljk5M2gxNC4zNDJ2LTI3Ljk5M2gyMS41Nzl2LTE1LjU1aC0yMS41Nzl2LTEzLjYyOHoiIGZpbGw9InVybCgjYykiIHN0cm9rZT0idXJsKCNkKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMjAwKSIvPjxwYXRoIGQ9Ik0xMTYuNzY5IDMwNS40MWM0NS42NTQtMjQuNDE4IDMxLjAyNCAyMi4xMDIgOC4zNjcgMzYuNDgzLTE0LjU5OCA5LjI2NS0yMi4yMy0yNS42OTUtMTQuNDg2LTUxLjk1bC0xOS41NjQuMjM2YzcuMjE0IDIzLjIzNCAyLjgxNCA1OC45MzgtMTMuMDU3IDUxLjcxNC0yOC4yNzItMTIuODY3LTM4Ljc4Mi02MC4yMSA2LjM1Ni0zNi40Ni0yNi4wODQtNTMuMzIxLTY2LjcxMS0zMi45MzItNjIuOS01LjgzMyA0LjE0MiAyOS40MzggMzcuNzQgNTUuOTI3IDM3LjA1OCA2Ny43MjloODQuMzA3Yy0xLjM1LTEzLjY3NCAzNi41NTEtNDEuNzkzIDM3Ljc2NC02OC41MjkgMS4xNjUtMjYuMTU5LTQzLjk4Mi00Ni40MTktNjMuODQ1IDYuNjF6IiBmaWxsPSJ1cmwoI2UpIiBzdHJva2U9InVybCgjZikiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTIwMCkiLz48cGF0aCBkPSJNNDUuMzMzIDM3My4zMzNoMTA5LjcxNXYxNS4yMzhINDUuMzMzeiIgZmlsbD0idXJsKCNnKSIgc3Ryb2tlPSJ1cmwoI2gpIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIC0yMDApIi8+PC9nPjwvc3ZnPg==')} +.is2d .pawn.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48bGluZWFyR3JhZGllbnQgaWQ9ImEiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjUwLjMzMyIgeDI9IjY3MS4zMzMiIHkxPSI1NDEuNjY3IiB5Mj0iNzE4LjMzMyI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTA1MDcwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjY1LjMzMyIgeDI9IjY0NC42NjciIHkxPSI2MDUiIHkyPSI2MDUiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iZ3JheSIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iZ3JheSIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZD0iTTAgMGgyMDB2MjAwSDB6IiBmaWxsPSJub25lIi8+PHBhdGggZD0iTTYzNi42NjcgNjA1YzAgMTAyLjE3My04MS4zMzUgMTg1LTE4MS42NjcgMTg1cy0xODEuNjY3LTgyLjgyNy0xODEuNjY3LTE4NVMzNTQuNjY4IDQyMCA0NTUgNDIwczE4MS42NjcgODIuODI3IDE4MS42NjcgMTg1eiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTMuMDQ4IC4zODEpIHNjYWxlKC4yMjg1NykiIG9wYWNpdHk9Ii45OSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2Utd2lkdGg9IjE2IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGZpbGw9InVybCgjYSkiIHN0cm9rZT0idXJsKCNiKSIvPjwvc3ZnPg==')} +.is2d .knight.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48bGluZWFyR3JhZGllbnQgaWQ9ImEiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iODM3Ljg2OSIgeDI9Ijk2OS44NjYiIHkxPSI1OC41NSIgeTI9IjE4OC44MzYiPjxzdG9wIG9mZnNldD0iMCIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzUwNTA3MCIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJiIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjgyNy45MjciIHgyPSI5NzQuNTYiIHkxPSIxMDQuNDQzIiB5Mj0iMTA0LjQ0MyI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSJncmF5Ii8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSJncmF5Ii8+PC9saW5lYXJHcmFkaWVudD48cGF0aCBkPSJNMCAwaDIwMHYyMDBIMHoiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSJNODg2LjAwMyAyMC4yM2MtLjM4NiAyNi41OTUuOTcyIDE2LjU1Mi0xNS44MSA0LjI3NCAyLjU5IDE3LjM0OS44MzEgMTcuOTItMy42NTIgMjUuMzQ1LTIuNDU0IDQuMDYzLTQuNjE3IDE2Ljg1Ni02LjE1MiAxOS42NzYtOS4zMDQgMTcuMDg3LTMwLjY3IDM5LjM5NC0zMC42MzQgNDYuNjY2LjA0NyA5LjIwNSAxMC45OTUgMTcuNDQ1IDIxLjAxIDcuNzEtOS4zNyAxMy43MTcgMTguOTE4LS4wNjEgMzAuNzczLTguNTIxIDE1LjY5MSA5LjY2IDM3LjYxNC0uOTEgMzguMDIxLTE2LjQzMiA3LjE0MSAzNS4xMDgtNTkuNTQgNDEuMjA1LTYzLjEwMiA4Ni43NDMgNDkuNjk3IDExLjM0NSA3Ny4zNzctMjUuNjE3IDEwNy42NjggMi45NjVDOTc5LjYxIDE0My43NiA5ODEuMDQgNjguNzEgOTA5LjA1MyA0MC41NzJjLTkuNzg0LTMuODI0LTEzLjg5NS0xMy42NjItMjMuMDUtMjAuMzQzem0tLjMgNDkuNTI1Yy0xLjYyOCAyLjMwOC01LjA1IDYuMDc2LTguMDUxIDUuNTI0LTIuNzc2LS41MS0zLjg5Mi0xLjQ1LTQuMDItNC43MzgtLjEwOC0yLjc2NyA5LjY5OC0yLjY3OCAxMi4wNy0uNzg2eiIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2Utd2lkdGg9IjMuNjU3IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGZpbGw9InVybCgjYSkiIHN0cm9rZT0idXJsKCNiKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTgwMCkiLz48L3N2Zz4=')} +.is2d .bishop.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjYzMi4yMjUiIHgyPSI3NjYuODYxIiB4bGluazpocmVmPSIjYSIgeTE9IjEwMi41OTEiIHkyPSIxNDMuMzUzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJhIj48c3RvcCBvZmZzZXQ9IjAiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM1MDUwNzAiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iZCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2MzIuMjI1IiB4Mj0iNjk5LjQ4NSIgeGxpbms6aHJlZj0iI2IiIHkxPSIxNzQuNTg2IiB5Mj0iMTc0LjU4NiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYiI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSJncmF5Ii8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSJncmF5Ii8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNjI4LjExIiB4Mj0iNzYyLjc0NyIgeGxpbms6aHJlZj0iI2EiIHkxPSIxMDIuNTkxIiB5Mj0iMTQzLjM1MyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2OTkuMjk3IiB4Mj0iNzY2LjU1NiIgeGxpbms6aHJlZj0iI2IiIHkxPSIxNzQuNTg2IiB5Mj0iMTc0LjU4NiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2MjkuOTM5IiB4Mj0iNzY0LjU3NSIgeGxpbms6aHJlZj0iI2EiIHkxPSIxMDIuNTkxIiB5Mj0iMTQzLjM1MyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2NTYuMjMzIiB4Mj0iNzM3LjY3MiIgeGxpbms6aHJlZj0iI2IiIHkxPSIxNTAuODE3IiB5Mj0iMTUwLjgxNyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2NDQuMjI3IiB4Mj0iNzU0LjAxNSIgeGxpbms6aHJlZj0iI2IiIHkxPSI5My4zNjQiIHkyPSI5My4zNjQiLz48bGluZWFyR3JhZGllbnQgaWQ9ImoiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNjczLjc0OSIgeDI9IjcxNC41MzgiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMzkuMzUzIiB5Mj0iNTEuNTQzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJrIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjY4MS42OTEiIHgyPSI3MTcuOTY2IiB4bGluazpocmVmPSIjYiIgeTE9IjMyLjMwMSIgeTI9IjMyLjMwMSIvPjxwYXRoIGQ9Ik0wIDBoMjAwdjIwMEgweiIgZmlsbD0ibm9uZSIvPjxnIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjMuNjU3Ij48cGF0aCBkPSJNNjk3LjY1NiAxNTguMDczYy0xLjIyMyAyLjQ0Ny02My42MDMgMzMuMDI1LTYzLjYwMyAzMy4wMjVsNTEuNTQ1LTYuNTI0eiIgZmlsbD0idXJsKCNjKSIgc3Ryb2tlPSJ1cmwoI2QpIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNjAwKSIvPjxwYXRoIGQ9Ik03MDEuMTI1IDE1OC4wNzNjMS4yMjMgMi40NDcgNjMuNjAzIDMzLjAyNSA2My42MDMgMzMuMDI1bC01NC41OTMtNi41MjR6IiBmaWxsPSJ1cmwoI2UpIiBzdHJva2U9InVybCgjZikiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02MDApIi8+PHBhdGggZD0iTTY3NS4wMzMgMTQyLjIyM2MtMS4zNzUgMi43NS0xNi45NzEgMTkuMzE3LTE2Ljk3MSAxOS4zMTdsNzcuNzgyIDUuMzUzLTE5LjgyNS0zMi4xNTN6IiBmaWxsPSJ1cmwoI2cpIiBzdHJva2U9InVybCgjaCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02MDApIi8+PHBhdGggZD0iTTY5OC43MiAzNS42MzNjLTEuMzc2IDIuNzUtNTIuNjY0IDExNS40NjItNTIuNjY0IDExNS40NjJsMTA2LjEzLTkuMzQ4em0xMC4zMjIgMzUuNzQ1bDguMTA1IDE3Ljc2LTQxLjgxIDQxLjQxczMyLjMzLTU2LjQxOSAzMy43MDUtNTkuMTd6IiBmaWxsPSJ1cmwoI2cpIiBzdHJva2U9InVybCgjaSkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02MDApIi8+PHBhdGggZD0iTTY5OS4xOCAxNi43NWMtMS4zNzYgMi43NTItMTUuNjYgMjYuMDcxLTE1LjY2IDI2LjA3MWwzMi42MTggNS4wM3oiIGZpbGw9InVybCgjaikiIHN0cm9rZT0idXJsKCNrKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTYwMCkiLz48L2c+PC9zdmc+')} +.is2d .rook.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJiIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjQyMC4yNzgiIHgyPSI1NzYuNDkiIHkxPSI2NS40MjgiIHkyPSIxNzEuNTYxIj48c3RvcCBvZmZzZXQ9IjAiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM1MDUwNzAiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iYyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0NTIuMjY3IiB4Mj0iNTUwLjQiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTI1LjQxIiB5Mj0iMTI1LjQxIi8+PGxpbmVhckdyYWRpZW50IGlkPSJhIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9ImdyYXkiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9ImdyYXkiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iZCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0MjYuNzQzIiB4Mj0iNDY2LjIxIiB4bGluazpocmVmPSIjYSIgeTE9IjU4LjU1MiIgeTI9IjU4LjU1MiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0ODEuMjE5IiB4Mj0iNTE4LjAxOSIgeGxpbms6aHJlZj0iI2EiIHkxPSI1NS44ODYiIHkyPSI1NS44ODYiLz48bGluZWFyR3JhZGllbnQgaWQ9ImYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNTQwLjY0OCIgeDI9IjU3My4yNTciIHhsaW5rOmhyZWY9IiNhIiB5MT0iNTkuMTI0IiB5Mj0iNTkuMTI0Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJnIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjQzNS41MDUiIHgyPSI1MzAuOTcxIiB4bGluazpocmVmPSIjYSIgeTE9IjE3OC44MTkiIHkyPSIxNzguODE5Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJoIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUzOS4xMjQiIHgyPSI1NjQuODc2IiB4bGluazpocmVmPSIjYSIgeTE9IjE3MS45NjIiIHkyPSIxNzEuOTYyIi8+PHBhdGggZD0iTTAgMGgyMDB2MjAwSDB6IiBmaWxsPSJub25lIi8+PGcgZmlsbD0idXJsKCNiKSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMy42NTciIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00MDApIj48cGF0aCBkPSJNNDU0LjA5NSA3MC41NTJoOTQuNDc2djEwOS43MTVoLTk0LjQ3NnoiIHN0cm9rZT0idXJsKCNjKSIvPjxwYXRoIGQ9Ik00MjguNTcxIDQwLjA3NmgzNS44MVY3Ny4wM2gtMzUuODF6IiBzdHJva2U9InVybCgjZCkiLz48cGF0aCBkPSJNNDgzLjA0OCA0OC4wNzZoMzMuMTQydjE1LjYyaC0zMy4xNDJ6IiBzdHJva2U9InVybCgjZSkiLz48cGF0aCBkPSJNNTQyLjQ3NiAzMS4zMTRoMjguOTUzdjU1LjYyaC0yOC45NTN6IiBzdHJva2U9InVybCgjZikiLz48cGF0aCBkPSJNNDM3LjMzMyAxNzEuMmg5MS44MXYxNS4yMzhoLTkxLjgxeiIgc3Ryb2tlPSJ1cmwoI2cpIi8+PHBhdGggZD0iTTU0MC45NTIgMTU3LjEwNWgyMi4wOTZ2MjkuNzE0aC0yMi4wOTZ6IiBzdHJva2U9InVybCgjaCkiLz48L2c+PC9zdmc+')} +.is2d .queen.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjI2NS4yODkiIHgyPSIzMDYuNjY3IiB4bGluazpocmVmPSIjYSIgeTE9IjY1LjYyNyIgeTI9IjEzNC4xOTkiLz48bGluZWFyR3JhZGllbnQgaWQ9ImEiPjxzdG9wIG9mZnNldD0iMCIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzUwNTA3MCIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjI1Mi4zMzciIHgyPSIzNTMuMTQzIiB4bGluazpocmVmPSIjYiIgeTE9Ijk2LjEwNCIgeTI9Ijk2LjEwNCIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYiI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSJncmF5Ii8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSJncmF5Ii8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjM4LjEyMSIgeDI9IjM2NC4zMTciIHhsaW5rOmhyZWY9IiNhIiB5MT0iNTQuODMyIiB5Mj0iMTcwLjY0MiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIyMTguMzEyIiB4Mj0iMzgyLjk4MyIgeGxpbms6aHJlZj0iI2IiIHkxPSI5NS4yMTMiIHkyPSI5NS4yMTMiLz48bGluZWFyR3JhZGllbnQgaWQ9ImciIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjQ1LjQ4NiIgeDI9IjM1MS4yMzgiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTgwLjUzMyIgeTI9IjE4MC41MzMiLz48bGluZWFyR3JhZGllbnQgaWQ9ImgiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjQ1LjQ4NiIgeDI9IjM1MS4yMzgiIHhsaW5rOmhyZWY9IiNiIiB5MT0iMTgwLjUzMyIgeTI9IjE4MC41MzMiLz48cGF0aCBkPSJNMCAwaDIwMHYyMDBIMHoiIGZpbGw9Im5vbmUiLz48ZyBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIzLjY1NyI+PHBhdGggZD0iTTM1MS4zMTQgMzQuMjY0Yy00Ny44NTggMTQzLjQtNTUuMjUzIDE0My42NjYtOTcuMTQzLjY3OS0uMjU3IDU4LjI3MSA3LjQ5MiA5OS4yNiAxOC43MjIgMTIzaDU0LjQxNGMxMi4zMDctMjMuODUxIDIxLjg0LTY1LjA5MyAyNC4wMDctMTIzLjY3OXoiIGZpbGw9InVybCgjYykiIHN0cm9rZT0idXJsKCNkKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTIwMCkiLz48cGF0aCBkPSJNMzAyLjU0OCAyNC40OGMtMTcuMzY4IDk0LjExMi04Ljg0NyAxOTQuOTgzLTgyLjQwOCA0Mi41ODcgMi41MTggNDYuNTkzIDEzLjQ0NSA3OS42MDYgMzIuODIyIDk4Ljg3OGg5MS45YzE5Ljc0NC0xOS4wMzIgMzEuNzEtNTEuNTMzIDM2LjI5My05Ny42NS03MC4yNDkgMTUyLjQyOS02NC4xNSA1MC4zODQtNzguNjA3LTQzLjgxNHoiIGZpbGw9InVybCgjZSkiIHN0cm9rZT0idXJsKCNmKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTIwMCkiLz48cGF0aCBkPSJNMjQ3LjMxNCAxNzMuMTA1SDM0OS40MXYxNC44NTdIMjQ3LjMxNHoiIGZpbGw9InVybCgjZykiIHN0cm9rZT0idXJsKCNoKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTIwMCkiLz48L2c+PC9zdmc+')} +.is2d .king.black {background-image:url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ijg1LjczIiB4Mj0iMTIyLjQxNyIgeGxpbms6aHJlZj0iI2EiIHkxPSI0MC4zMjQiIHkyPSI3MC42MTQiLz48bGluZWFyR3JhZGllbnQgaWQ9ImEiPjxzdG9wIG9mZnNldD0iMCIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzUwNTA3MCIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjcyLjMyMyIgeDI9IjEyOS44NjYiIHhsaW5rOmhyZWY9IiNiIiB5MT0iNTMuNzMxIiB5Mj0iNTMuNzMxIi8+PGxpbmVhckdyYWRpZW50IGlkPSJiIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9ImdyYXkiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9ImdyYXkiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iZSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzNC4zMDQiIHgyPSIxNTguNjMiIHhsaW5rOmhyZWY9IiNhIiB5MT0iNTguMzQ0IiB5Mj0iMTY5LjE1NyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIxOS40MDciIHgyPSIxODIuNDY1IiB4bGluazpocmVmPSIjYiIgeTE9IjExOS43MjMiIHkyPSIxMTkuNzIzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJnIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjM3LjI4MyIgeDI9IjE2MC42MTYiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTc3LjUxNyIgeTI9IjE3OC4wMTQiLz48bGluZWFyR3JhZGllbnQgaWQ9ImgiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNDMuNTA1IiB4Mj0iMTU2Ljg3NiIgeGxpbms6aHJlZj0iI2IiIHkxPSIxODAuOTUyIiB5Mj0iMTgwLjk1MiIvPjxwYXRoIGQ9Ik0wIDBoMjAwdjIwMEgweiIgZmlsbD0ibm9uZSIvPjxnIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjMuNjU3Ij48cGF0aCBkPSJNOTIuMTE2IDI1LjE0NXYxMy42MjhINzQuMTV2MTUuNTVoMTcuOTY1djI3Ljk5M2gxNC4zNDJWNTQuMzIzaDIxLjU3OXYtMTUuNTVoLTIxLjU3OVYyNS4xNDV6IiBmaWxsPSJ1cmwoI2MpIiBzdHJva2U9InVybCgjZCkiLz48cGF0aCBkPSJNMTE2Ljc2OSAxMDUuNDFjNDUuNjU0LTI0LjQxOCAzMS4wMjQgMjIuMTAyIDguMzY3IDM2LjQ4My0xNC41OTggOS4yNjUtMjIuMjMtMjUuNjk1LTE0LjQ4Ni01MS45NWwtMTkuNTY0LjIzNmM3LjIxNCAyMy4yMzQgMi44MTQgNTguOTM4LTEzLjA1NyA1MS43MTQtMjguMjcyLTEyLjg2Ny0zOC43ODItNjAuMjExIDYuMzU2LTM2LjQ2QzU4LjMgNTIuMTExIDE3LjY3NCA3Mi41IDIxLjQ4NSA5OS42YzQuMTQyIDI5LjQzOCAzNy43NCA1NS45MjcgMzcuMDU4IDY3LjcyOWg4NC4zMDdjLTEuMzUtMTMuNjc0IDM2LjU1MS00MS43OTMgMzcuNzY0LTY4LjUyOSAxLjE2NS0yNi4xNTktNDMuOTgyLTQ2LjQxOS02My44NDUgNi42MXoiIGZpbGw9InVybCgjZSkiIHN0cm9rZT0idXJsKCNmKSIvPjxwYXRoIGQ9Ik00NS4zMzMgMTczLjMzM2gxMDkuNzE1djE1LjIzOEg0NS4zMzN6IiBmaWxsPSJ1cmwoI2cpIiBzdHJva2U9InVybCgjaCkiLz48L2c+PC9zdmc+')} diff --git a/public/sound/futuristic/Error.mp3 b/public/sound/futuristic/Error.mp3 new file mode 120000 index 0000000000..261b68e0ca --- /dev/null +++ b/public/sound/futuristic/Error.mp3 @@ -0,0 +1 @@ +../standard/Error.mp3 \ No newline at end of file diff --git a/public/sound/futuristic/Error.ogg b/public/sound/futuristic/Error.ogg new file mode 120000 index 0000000000..ea772099a8 --- /dev/null +++ b/public/sound/futuristic/Error.ogg @@ -0,0 +1 @@ +../standard/Error.ogg \ No newline at end of file diff --git a/public/sound/instrument/Error.mp3 b/public/sound/instrument/Error.mp3 new file mode 120000 index 0000000000..261b68e0ca --- /dev/null +++ b/public/sound/instrument/Error.mp3 @@ -0,0 +1 @@ +../standard/Error.mp3 \ No newline at end of file diff --git a/public/sound/instrument/Error.ogg b/public/sound/instrument/Error.ogg new file mode 120000 index 0000000000..ea772099a8 --- /dev/null +++ b/public/sound/instrument/Error.ogg @@ -0,0 +1 @@ +../standard/Error.ogg \ No newline at end of file diff --git a/public/sound/nes/Error.mp3 b/public/sound/nes/Error.mp3 new file mode 120000 index 0000000000..261b68e0ca --- /dev/null +++ b/public/sound/nes/Error.mp3 @@ -0,0 +1 @@ +../standard/Error.mp3 \ No newline at end of file diff --git a/public/sound/nes/Error.ogg b/public/sound/nes/Error.ogg new file mode 120000 index 0000000000..ea772099a8 --- /dev/null +++ b/public/sound/nes/Error.ogg @@ -0,0 +1 @@ +../standard/Error.ogg \ No newline at end of file diff --git a/public/sound/piano/Error.mp3 b/public/sound/piano/Error.mp3 new file mode 120000 index 0000000000..261b68e0ca --- /dev/null +++ b/public/sound/piano/Error.mp3 @@ -0,0 +1 @@ +../standard/Error.mp3 \ No newline at end of file diff --git a/public/sound/piano/Error.ogg b/public/sound/piano/Error.ogg new file mode 120000 index 0000000000..ea772099a8 --- /dev/null +++ b/public/sound/piano/Error.ogg @@ -0,0 +1 @@ +../standard/Error.ogg \ No newline at end of file diff --git a/public/sound/robot/Error.mp3 b/public/sound/robot/Error.mp3 new file mode 120000 index 0000000000..261b68e0ca --- /dev/null +++ b/public/sound/robot/Error.mp3 @@ -0,0 +1 @@ +../standard/Error.mp3 \ No newline at end of file diff --git a/public/sound/robot/Error.ogg b/public/sound/robot/Error.ogg new file mode 120000 index 0000000000..ea772099a8 --- /dev/null +++ b/public/sound/robot/Error.ogg @@ -0,0 +1 @@ +../standard/Error.ogg \ No newline at end of file diff --git a/public/sound/sfx/Error.mp3 b/public/sound/sfx/Error.mp3 new file mode 120000 index 0000000000..261b68e0ca --- /dev/null +++ b/public/sound/sfx/Error.mp3 @@ -0,0 +1 @@ +../standard/Error.mp3 \ No newline at end of file diff --git a/public/sound/sfx/Error.ogg b/public/sound/sfx/Error.ogg new file mode 120000 index 0000000000..ea772099a8 --- /dev/null +++ b/public/sound/sfx/Error.ogg @@ -0,0 +1 @@ +../standard/Error.ogg \ No newline at end of file diff --git a/public/sound/standard/Error.mp3 b/public/sound/standard/Error.mp3 new file mode 100644 index 0000000000..af769c0e91 Binary files /dev/null and b/public/sound/standard/Error.mp3 differ diff --git a/public/sound/standard/Error.ogg b/public/sound/standard/Error.ogg new file mode 100644 index 0000000000..fc3e45163c Binary files /dev/null and b/public/sound/standard/Error.ogg differ diff --git a/public/sound/standard/GenericNotify.mp3 b/public/sound/standard/GenericNotify.mp3 index d5bfeaace0..61bb1b60fb 100644 Binary files a/public/sound/standard/GenericNotify.mp3 and b/public/sound/standard/GenericNotify.mp3 differ diff --git a/public/sound/standard/GenericNotify.ogg b/public/sound/standard/GenericNotify.ogg index 786cceb55b..8367da9ba0 100644 Binary files a/public/sound/standard/GenericNotify.ogg and b/public/sound/standard/GenericNotify.ogg differ diff --git a/public/stylesheets/account.css b/public/stylesheets/account.css deleted file mode 100644 index 3041ed01a5..0000000000 --- a/public/stylesheets/account.css +++ /dev/null @@ -1,105 +0,0 @@ -form.material.form { - margin-top: 50px; -} - -.security .explanation { - margin: 0 20px 20px 20px; -} -.security .revoke-all, -.security .revoke-all button { - display: inline; -} -.security table td { -} -.security table .ua { - font-size: 0.8em; -} -.security table .icon span { - font-size: 3em; -} -.security table .ip { - font-weight: bold; -} -.security table .current { - color: #d59120; -} - -.twofactor ol li { - list-style: decimal; -} -.twofactor .explanation { - margin-bottom: 2em; -} - -.oauth .top { - display: flex; - align-items: center; -} -.oauth .top h1 { - flex: 1 1 100%; -} -.oauth .top .new_obj { - white-space: nowrap; - margin-right: 10px; -} -.oauth .top .new_obj .button i::before { - color: #759900; - font-size: 40px; -} -.oauth table em, -.oauth table .date { - font-size: 0.8em; -} -.oauth table .action { - display: flex; - justify-content: flex-end; -} - -.oauth .codes { - display: block; - margin: 10px 0 20px 0; - padding: 10px 20px; - background: rgba(128,128,128,0.1); -} -.oauth .codes td { - padding: 0.5em 1em; - font-family: monospace; -} - -.oauth .scopes { - background: rgba(128,128,128,0.1); - padding: .5em 1.5em; - margin-bottom: 4em; -} - -.oauth h2 { - font-size: 1.2em; - margin: -1em 0 0.5em 0; -} -.oauth .scopes input { - vertical-align: middle; - margin-right: 0.5em; -} -.oauth .scopes label { - display: block; - line-height: 2.5em; - cursor: pointer; -} -.oauth form.material.form { - margin-bottom: 40px; -} - -.oauth .brand { - margin: 20px; - display: flex; -} -.oauth .brand i { - font-size: 45px; - margin-right: 15px; -} -.oauth .brand code { - font-weight: bold; - font-size: 1.5em; - margin-top: 10px; - display: block; -} diff --git a/public/stylesheets/activity.css b/public/stylesheets/activity.css deleted file mode 100644 index 1369f750c3..0000000000 --- a/public/stylesheets/activity.css +++ /dev/null @@ -1,133 +0,0 @@ -.activity section { - font-size: 1.4em; - margin-left: 15px; - padding-top: 1em; -} -.activity section h2 time { - padding: 10px; - font-weight: bold; - text-transform: uppercase; - background: #fff; - z-index: 2; -} -.activity .entries { - margin: 30px 50px 30px 50px; - margin-top: 0; - position: relative; - border-left: 2px solid #e6ebf1; - border-top: 1px solid #f6f6f6; -} -.activity .entry { - padding: 23px 0 23px 45px; - border-bottom: 1px solid #f6f6f6; -} -.activity .entry > i { - font-size: 22px; - float: left; - width: 45px; - height: 45px; - margin-top: -11px; - margin-left: -70px; - line-height: 42px; - text-align: center; - background-color: #e6ebf1; - border: 2px solid #fff; - border-radius: 50%; -} -.activity .entry.plan > i { - background-color: #d59120!important; - color: #fff; -} -.activity .entry a:not(.user_link) { - color: #3893E8; -} -.activity .entry .sub { - margin: 3px 0; - font-size: 0.8em; - line-height: 1.7em; - opacity: 0.8; -} -.activity .entry .sub:last-child { - margin-bottom: -7px; -} -.activity .entry .sub > div { - overflow: hidden; -} -.activity .entry .line { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.activity .entry .line .more { - flex: 0 1 auto; -} -.activity .entry .line a { - color: #707070; -} -.activity .entry .line a:hover { - color: #3893E8!important; -} -.activity .entry rating { - margin-left: 12px; - padding: 2px 5px; - opacity: 0.7; - font-family: 'Roboto Mono'; -} -.activity score { - float: right; - font-size: 0.7em; - margin-top: 2px; -} -.activity score > * { - margin-left: 8px; -} -.activity .entry score strong { - color: #fff; - font-size: 1.2em; - padding: 1px 4px; - border-radius: 20%; - min-width: 1em; - display: inline-block; - text-align: center; - opacity: 0.7; -} -.activity .entry .sub score strong { - line-height: 1.6em; - padding: 1px 4px; -} -.activity win strong { - background: #759900; -} -.activity draw strong { - background: #d59120; -} -.activity loss strong { - background: #dc322f; -} - -body.dark .activity section { - color: #aaa; -} -body.dark .activity section h2 time { - background: #2b2b2b; - color: #888; -} -body.dark .activity .entries { - border-color: #444; - border-top-color: #383838; -} -body.dark .activity .entry { - border-bottom-color: #383838; -} -body.dark .activity .entry > i { - background-color: #444; -} -body.dark .activity .entry > i { - border-color: #2b2b2b; -} -body.dark .activity .entry .line a { - color: #aaa; -} -body.dark .activity .entry.plan > i { - background-color: #bf811d!important; -} diff --git a/public/stylesheets/analyse-embed.css b/public/stylesheets/analyse-embed.css deleted file mode 100644 index d43ffcd780..0000000000 --- a/public/stylesheets/analyse-embed.css +++ /dev/null @@ -1,188 +0,0 @@ -body { - overflow: hidden; -} -.is2d { - background: #fff; -} -body.dark, -body.dark .is2d { - background: #2b2b2b; -} -div.lichess_game { - height: 100%; - flex-flow: row nowrap; -} -div.lichess_game div.lichess_ground { - flex: 1 1 100%!important; - padding-left: 0; - width: auto; -} -.cg-512 .cg-board-wrap { - width: 100%; - height: 100%; -} -div.game_control { - border: 1px solid #ccc; - border-width: 0 1px 1px 0; - background: #eaeaea; -} -div.game_control .jumps { - flex: 1 1 100%; - justify-content: center; -} -.action_menu { - border: 1px solid #ccc; - border-width: 1px 1px 0 0; - background: #f8f8f8; -} -.pocket { - border-radius: 0; - background: #888!important; - padding: 2px 0; - margin: 0px!important; - justify-content: space-between; - max-height: 13%; -} -.pocket piece { - flex: 0 1 56px; - height: 100%!important; - background-size: contain; - background-repeat: no-repeat; -} -.pocket.usable piece:first-child:hover { - border-radius: 0; -} -@media (max-width: 739px) { - .pocket, - .pocket piece { - flex-basis: 46px; - } - .pocket piece::after { - line-height: 12px; - padding: 2px 3px 2px 3px; - font-weight: bold; - border-radius: 1px; - font-size: 13px; - } -} -@media (max-width: 599px) { - .pocket, - .pocket piece { - flex-basis: 40px; - } -} -footer { - font-size: 10.5px; - display: flex; - border: 1px solid #ccc; - border-top: none; - box-sizing: border-box; - height: 26px; - align-items: center; - padding: 0 0.7em; - background: #e4e4e4; - color: #888; -} -footer a { - color: #3893E8!important; -} -footer .left { - flex: 1 1 100%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -footer h1 { - display: inline; -} -footer .open { - flex: 0 0 auto; -} -footer > * { - opacity: 0.8; - transition: opacity 0.13s; -} -footer:hover > * { - opacity: 1; -} -body.dark div.game_control { - border-color: #3d3d3d; - background: #333; -} -body.dark .action_menu { - border-color: #3d3d3d; - background: #303030; -} -body.dark footer { - border-color: #3d3d3d; - background: #3a3a3a; -} -.tview2.inline { - font-size: 15px; -} -@media (max-width: 699px) { - body, - .tview2 { - font-size: 12px; - } - .tview2 lines lines move { - font-size: 10.5px; - } - .cg-board-wrap coords { - display: none; - } -} -@media (max-width: 549px) { - body, - .tview2 { - font-size: 11px; - } - .tview2 lines lines move { - font-size: 10px; - } - .cg-board-wrap coords { - display: none; - } -} -@media (max-width: 400px) { - body, - .tview2 { - font-size: 10px; - } - .tview2 lines lines move { - font-size: 9px; - } -} -@media (max-width: 420px) { - div.game_control .jumps button:first-child, - div.game_control .jumps button:last-child { - display: none; - } -} -@media (max-height: 400px) { - div.game_control { - flex: 0 0 30px; - } - div.game_control button { - line-height: 30px; - } -} -.not_found { - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - display: flex; - justify-content: center; - align-items: center; - height: 100%; - background: radial-gradient(circle, #484848, #2F3031); -} -.not_found h1 { - font-family: Roboto; - font-size: 3vw; - text-align: center; - color: rgba(255,255,255,0.3); - text-shadow: 0 0 9px rgba(0,0,0,0.3); -} diff --git a/public/stylesheets/analyse.css b/public/stylesheets/analyse.css deleted file mode 100644 index 693b35e942..0000000000 --- a/public/stylesheets/analyse.css +++ /dev/null @@ -1,1761 +0,0 @@ -div.analysis_menu { - text-align: center; - border-top: 1px solid #c0c0c0; - height: 21px; -} -div.analysis_menu > a { - background: #f0f0f0; - border: 1px solid #c0c0c0; - padding: 2px 8px; - height: 16px; - line-height: 16px; - margin: -1px 0 0 -5px; - display: inline-block; - cursor: pointer; -} -div.analysis_menu > a.active { - background-color: #eee; - border-top: 1px solid #eee; -} -body.base div.analysis_menu > a.active { - border-bottom: 2px solid #d85000; -} -div.analysis_panels { - margin-top: -10px; -} -div.analysis_panels > div { - height: 210px; - max-height: 210px; - display: none; - overflow-x: hidden; - overflow-y: auto; - text-align: left; -} -div.analysis_panels > div.active { - display: block; -} -div.no_computer div.analysis_menu .computer_analysis { - display: none; -} -div.analysis_panels .crosstable table { - margin-top: 60px; -} -div.game_analysis { - padding: 10px; - width: 492px; -} -.view_game_analysis { - display: none; -} -.future_game_analysis { - margin-top: 84px; - text-align: center; -} -form.better_analysis { - margin-top: 20px; - width: 512px; - text-align: center; -} -.underboard_content .quote.panel.active { - display: flex; - align-items: center; -} -.future_game_analysis .button { - display: inline-block; - line-height: 24px; -} -div.fen_pgn > div { - margin: 0.6em 0; - display: flex; - align-items: center; -} -div.fen_pgn a { - color: #3893E8; -} -div.fen_pgn .pgn { - white-space: pre-wrap; - font-family: monospace; -} -div.fen_pgn strong { - font-size: 1.1em; - display: inline-block; - margin-right: 10px; -} -div.fen_pgn .pgn_options div { - display: flex; - flex-flow: row wrap; - margin-left: 5px; -} -div.fen_pgn .pgn_options a { - flex: 0 0 50%; - line-height: 1.6em; -} -div.game_control { - flex: 0 0 36px; - font-size: 1.3em; - display: flex; - justify-content: space-between; -} -div.game_control button, -div.game_control a { - background: none; - border: none; - padding: 0 12px; - outline: none; - line-height: 36px; - margin: 0; /* safari */ -} -div.game_control button.hidden { - visibility: hidden; -} -div.game_control button.disabled { - opacity: 0.5; - cursor: default; -} -div.game_control a:hover, -div.game_control button:hover:not(.disabled) { - background: rgba(56,147,232,0.8); - color: #fff; -} -div.game_control button:active, -div.game_control button.active { - background: #3893E8!important; - color: #fff; -} -div.game_control .features { - white-space: nowrap; /* safari */ -} -div.game_control .jumps { - display: flex; -} -div.game_control .jumps button:first-child, -div.game_control .jumps button:last-child { - font-size: 0.7em; - padding: 0 5px; -} -div.game_control .jumps button:nth-child(2) { - padding: 0 10px 0 14px; -} -div.game_control .jumps button:nth-child(3) { - padding: 0 14px 0 10px; -} -div.lichess_game div.lichess_ground { - position: relative; - margin-bottom: -36px; -} -div.eval_gauge { - position: absolute; - right: -14px; - top: 0; - width: 14px; - height: 100%; - background: #fff; - background-size: 100% 100%; - border-radius: 0 5px 5px 0; - overflow: hidden; -} -div.eval_gauge.reverse { - transform: rotateX(180deg); -} -div.eval_gauge::after { - content: ''; - display: block; - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - box-shadow: 0 0 5px rgba(0,0,0,0.7) inset; - border-radius: 0 5px 5px 0; -} -div.eval_gauge tick { - position: absolute; - top: -1px; - left: 0; - width: 100%; - border-bottom: 2px ridge #eee; - opacity: 0.4; -} -div.eval_gauge tick.zero { - top: 0; - opacity: 1; - border-bottom: 7px solid #dc322f!important; - margin-top: -3px; - opacity: 0.45; -} -div.eval_gauge .black { - width: 100%; - height: 50%; - background: #888; - border-radius: 0 5px 0 0; - transition: height 1s; -} -div.gauge_displayed div.lichess_game div.lichess_ground { - padding-left: 19px; -} -div.gauge_displayed .fork { - margin-left: 7px; -} -.pocket.top { - margin: 0; - border-radius: 3px 3px 0 0; -} -.pocket.bottom { - margin: 0; - border-radius: 0 0 3px 3px; -} -.areplay .opening_box { - padding: 5px; - border-bottom: 1px solid #ccc; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - background: #eaeaea; - font-family: 'Roboto'; -} -.areplay .chapter_name { - padding: 5px; - border-bottom: 1px solid #ccc; - background: #eaeaea; - font-family: 'Roboto'; - line-height: 1.2em; - text-align: center; -} -.pv_box .pv { - height: 2em; - line-height: 2em; - border: 1px solid #ccc; - border-bottom: 0; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; -} -.pv_box .pv[data-uci]:hover { - background: rgba(191, 231, 255, 0.7); - cursor: pointer; -} -.pv_box .pv strong { - display: inline-block; - width: 34px; - text-align: center; -} -.pv_box .pv span { - margin-left: 4px; - font-family: 'ChessSansPiratf', sans-serif; -} -body.piece_letter .pv_box .pv span { - font-family: 'Noto Sans'; -} -.ceval_box { - flex: 0 0 38px; - border: 1px solid #ccc; - border-bottom: 0; - position: relative; - display: flex; - align-items: stretch; -} -.ceval_box .switch { - flex: 0 1 40px; - margin-right: 8px; - display: flex; - align-items: center; -} -.ceval_box pearl { - flex: 0 0 75px; - line-height: 40px; - font-size: 2em; - text-align: center; - font-weight: bold; - background: #e0e0e0; -} -.ceval_box .engine { - opacity: 0.7; - flex: 1 0; - margin: 5px 0 0 5px; -} -.ceval_box .native { - margin-left: 5px; - text-transform: uppercase; - color: #759900; -} -.ceval_box .asmjs { - margin-left: 5px; - text-transform: uppercase; -} -.ceval_box .cloud { - margin-left: 4px; - background: rgba(117, 153, 0, 0.7); - color: #fff; - padding: 0px 3px; - border-radius: 3px; - text-transform: uppercase; - font-size: 9px; -} -.ceval_box .engine .info { - display: block; - font-size: 10px; - white-space: nowrap; -} -.ceval_box .deeper { - color: #3893e8; - margin-left: 4px; -} -.ceval_box .deeper::before { - font-size: 12px; - vertical-align: -2px; -} -.ceval_box help { - opacity: 0.7; - flex: 1 0; - margin: 5px; - font-size: 0.9em; - white-space: nowrap; -} -.ceval_box .bar { - position: absolute; - width: 100%; - height: 3px; - top: 0px; -} -@keyframes bar-anim { - from { background-position: 0 0; } - to { background-position: 100000px 0; } -} -.ceval_box .bar span { - display: block; - height: 3px; - width: 0; - background: #759900; - transition: width 1s; -} -.ceval_box .bar span.threat { - background: #dc322f; -} -.ceval_box.computing .bar span { - background-image: url(../images/bar-highlight.png); - animation: bar-anim 1000s linear infinite; -} -.ceval_box .show-threat { - position: absolute; - right: -41px; - top: -1px; - display: block; - width: 40px; - height: 40px; - box-sizing: border-box; - /* background: #fff; */ - border: 1px solid #ccc; - border-left: 0; - border-radius: 0 5px 5px 0; - text-align: center; - font-size: 17px; - line-height: 36px; -} -.ceval_box .show-threat:hover:not(.hidden) { - background: #3893E8; - color: #fff; -} -.ceval_box .show-threat.active { - background: #dc322f; - color: #fff; -} -.ceval_box .show-threat.hidden { - opacity: 0.3; - cursor: default; -} - -.fork { - position: absolute; - top: 100%; - left: 91px; - width: 130px; - background: #fff; - box-shadow: 0px 0px 5px 0px rgba(0, 0, 0, 0.5); - z-index: 1; -} -.fork move { - font-family: 'ChessSansPiratf', sans-serif; - font-size: 14px; - line-height: 28px; - display: block; - cursor: pointer; - padding: 0 15px; - display: flex!important; - border-bottom: 1px solid #e4e4e4; -} -body.piece_letter .fork move { - font-family: 'Noto Sans'; - font-size: 13px; -} -.fork move:last-child { - border-bottom: none; -} -.fork move:hover, -.fork:not(:hover) move.selected { - background: rgba(56,147,232,0.8); - color: #fff!important; -} -.fork glyph { - font-family: 'Noto Sans'; - margin-left: 2px; -} -.fork eval { - flex: 3 0 auto; - text-align: right; - font-size: 0.8em; - font-family: 'Roboto'; - opacity: 0.8; -} -.no_computer eval { - display: none; -} - -@media (min-width: 1050px) { - - div.analyse div.lichess_game div.lichess_ground { - flex: 0 0 25vw; - max-width: 25vw; - } - div.analyse .fork { left: 90px; } - - .pocket piece { - flex: 0 0 50px; - } -} - -.explorer_box { - position: relative; - flex: 2.5 1 0px; - border: 1px solid #ccc; - border-top: 0; - overflow: hidden; - white-space: nowrap; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - transition: 0.3s; - transition-delay: 0.3s; -} -.explorer_box { - overflow-y: scroll; -} -.explorer_box.config { - flex: 3.5 1 0px; -} -.explorer_box.reduced { - flex: 0.3 3 0px; -} -.explorer_box.reduced:hover { - flex: 1 2 0px; -} -.explorer_box.config { - min-height: 210px; -} -.explorer_box .overlay { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - display: none; -} -.explorer_box.loading .overlay { - display: block; -} -.explorer_box tbody { - transition: opacity 0.13s; -} -.explorer_box.loading tbody { - opacity: 0.4; -} -.explorer_box .empty { - text-align: center; - display: flex; - flex-flow: column; - height: 100%; -} -.explorer_box thead th { - text-transform: capitalize; - padding-left: 7px; -} -.explorer_box thead th, -.explorer_box .title { - font-size: 11px; - line-height: 22px; - background: #3b93da; - color: #fff; - text-align: left; - padding-left: 10px; -} -body.dark .explorer_box thead th, -body.dark .explorer_box .title, -body.dark .retro_box .title, -body.dark .practice_box .title { - background: #215279; - color: #ccc; -} -.explorer_box tr:nth-child(even) { - background: #fafafa; -} -.explorer_box tbody tr { - transition: background-color 0.13s; -} -.explorer_box tbody tr:hover { - background: rgba(191, 231, 255, 0.7); -} -.explorer_box td { - cursor: pointer; - padding-left: 7px; -} -.explorer_box .moves td:first-child { - font-family: 'ChessSansPiratf', sans-serif; - font-size: 14px; - line-height: 30px; - padding-left: 7px; -} -body.piece_letter .explorer_box .moves td:first-child { - font-family: 'Noto Sans'; - font-size: 13px; -} -.explorer_box .moves td:nth-child(2) { - font-size: 10px; - text-align: right; -} -.explorer_box .moves td:last-child { - width: 100%; - padding-right: 7px; -} -.explorer_box .bar span { - text-align: center; - display: inline-block; - overflow: hidden; - vertical-align: middle; - border: 0px solid #ccc; - border-width: 1px 0; - box-sizing: border-box; - height: 16px; - line-height: 16px; - font-size: 11px; -} -body.dark .explorer_box .bar span, -body.dark .action_menu h2:before, -body.dark .action_menu h2:after { - border-color: #555; -} -body.dark .ceval_box .show-threat, -body.dark .pv_box .pv { - border-color: #3d3d3d; -} -.explorer_box .white { - background: #fff; - box-shadow: 0 -5px 7px rgba(0,0,0,0.1) inset; -} -body.dark .explorer_box .white { - background: #bbb; - color: #222; - box-shadow: 0 -5px 7px rgba(0,0,0,0.25) inset; -} -.explorer_box .draws, -.explorer_box .black { - color: #fff; - box-shadow: 0 5px 7px rgba(255,255,255,0.2) inset; -} -.explorer_box .draws { - background: #a0a0a0; -} -body.dark .explorer_box .draws { - background: #666; - color: #ddd; -} -.explorer_box .black { - background: #555; - color: #ddd; -} -body.dark .explorer_box .black { - background: #333; - box-shadow: 0 5px 7px rgba(255,255,255,0.1) inset; -} -.explorer_box .bar span:first-child { - border-top-left-radius: 3px; - border-bottom-left-radius: 3px; - border-left-width: 1px; -} -.explorer_box .bar span:last-child { - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; - border-right-width: 1px; -} -.explorer_box .games { - width: 100%; -} -.explorer_box .games td { - padding: 5px 0 5px 7px; - max-width: 110px; -} -.explorer_box .games td span { - display: block; - overflow: hidden; - text-overflow: ellipsis; -} -.explorer_box .games result { - display: block; - text-align: center; - padding: 3px 5px; - border-radius: 3px; - font-size: 0.9em; -} -.explorer_box td.game_menu { - background: #759900; - cursor: default; - padding: 0; -} -.explorer_box .game_menu .game_title { - text-align: center; - color: #fff; - margin: 3px 0 1px 0; -} -.explorer_box .game_menu .menu { - display: flex; - justify-content: space-between; - text-transform: uppercase; -} -.explorer_box .game_menu .menu a { - color: #fff; - padding: 4px 8px; -} -.explorer_box .game_menu .menu a:hover { - background: rgba(255,255,255,0.2); -} -@media (max-width: 1120px) { -.explorer_box .game_menu { - font-size: 0.8em; - letter-spacing: 0; -} -} -.explorer_box .tablebase { - width: 100%; -} -.explorer_box .tablebase td:first-child { - font-family: 'ChessSansPiratf', sans-serif; - font-size: 14px; - line-height: 30px; - padding-left: 7px; -} -body.piece_letter .tablebase td:first-child { - font-family: 'Noto Sans'; - font-size: 13px; -} -.explorer_box .tablebase td:last-child { - padding-right: 7px; - text-align: right; -} -.explorer_box .tablebase result { - padding: 3px 5px; - margin-left: 5px; - border-radius: 3px; - font-size: 0.9em; -} -.explorer_box .toconf { - position: absolute; - top: 0; - right: 0; - cursor: pointer; - display: block; - font-size: 15px; - color: #fff; - width: 22px; - height: 22px; - line-height: 20px; - text-align: center; - opacity: 0.7; -} -.explorer_box .toconf:hover { - opacity: 1; -} -.explorer_box .message { - text-align: center; - font-style: italic; - flex: 1 1 100%; - display: flex; - flex-flow: column; - justify-content: center; -} -.explorer_box.reduced .message { - justify-content: flex-start; -} -.explorer_box .message h3 { - margin: 8px 0; -} -.explorer_box:not(.reduced) .message h3, -.explorer_box.reduced:hover .message h3 { - font-weight: bold; -} -.explorer_box .message p { - white-space: normal; - padding: 0 8px; - margin: 0 0 8px 0; -} -.explorer_box.reduced .message p, -.explorer_box.reduced .message button { - display: none; -} -.explorer_box.reduced:hover .message p, -.explorer_box.reduced:hover .message button { - display: block; -} -.explorer_box .message button { - margin: 0 30px; -} -.explorer_box .message.masters i { - font-size: 40px; - margin: 10px 0; -} -.explorer_box .config { - overflow: hidden; -} -.explorer_box .config section { - padding: 8px 10px 0 10px; -} -.explorer_box .config section.db { - padding-top: 5px; -} -.explorer_box .config section.save { - text-align: center; - padding: 15px 0 10px 0; -} -.explorer_box .config label { - font-weight: bold; - display: block; - line-height: 2em; -} -.explorer_box .config .choices { - display: flex; -} -.explorer_box .config .choices span { - flex-grow: 1; - padding: 5px 0; - text-align: center; - cursor: pointer; - transition: background 0.13s; - border: 1px solid #ccc; - border-width: 1px 0 1px 1px; - text-transform: capitalize; -} -.explorer_box .config .choices span:first-child { - border-radius: 3px 0 0 3px; -} -.explorer_box .config .choices span:last-child { - border-radius: 0 3px 3px 0; - border-right-width: 1px; -} -.explorer_box .config .choices span:hover { - background: #fff; -} -.explorer_box .config .choices span.selected { - background: #3893E8!important; - color: #fff!important; - text-shadow: 1px 0 0 rgba(0,0,0,0.5); - font-weight: bold; - box-shadow: 0 3px 5px rgba(0,0,0,0.2) inset; -} - -.retro_box, -.practice_box { - flex: 1.5 1 0px; - border: 1px solid #ccc; - border-top: 0; - background: #fff; - display: flex; - flex-flow: column; -} -.retro_box .title, -.practice_box .title { - flex: 0 0 22px; - display: flex; - justify-content: space-between; - font-size: 12px; - line-height: 22px; - background: #3b93da; - color: #fff; - text-align: left; - padding: 0 5px 0 10px; -} -.retro_box .title .close, -.practice_box .title .close { - cursor:pointer; -} -.retro_box .feedback, -.practice_box .feedback { - flex: 1 1 100%; - display: flex; - flex-flow: column; - justify-content: center; -} -.retro_box .progress, -.practice_box .progress { - margin-top: 5px; - opacity: 0.8; - width: 100%; - height: 4px; - background: #ddd; -} -.retro_box .progress div, -.practice_box .progress div { - background: #759900; - height: 4px; - transition: width 0.5s; - max-width: 100%; -} -.retro_box .player, -.practice_box .player { - display: flex; - align-items: center; - margin-left: 10px; -} -.retro_box .player.center { - justify-content: center; -} -.retro_box:not(.find) .player { - height: 100%; -} -.retro_box .no-square, -.practice_box .no-square { - width: 64px; - height: 64px; - margin-right: 10px; -} -.is3d .retro_box div.no-square, -.is3d .practice_box div.no-square { - height: 82px; -} -.retro_box piece, -.practice_box piece { - position: inherit; - display: block; - width: 100%!important; - height: 100%!important; -} -.retro_box .icon, -.practice_box .icon { - display: block; - width: 64px; - height: 64px; - margin-right: 10px; - font-size: 50px; - font-size: 64px; - line-height: 64px; - text-align: center; -} -.retro_box .win .icon:not(.off) { - color: #759900; -} -.retro_box .fail .icon:not(.off) { - color: #dc322f; -} -.retro_box .instruction, -.practice_box .instruction { - font-size: 1.1em; -} -.retro_box .instruction > *, -.practice_box .instruction > * { - display: block; -} -.retro_box .instruction > strong, -.practice_box .instruction > strong { - font-weight: normal; - font-size: 1.3em; -} -.retro_box .instruction move { - display: inline; - cursor: default; -} -.retro_box .instruction glyph { - font-weight: normal; - opacity: 0.7; -} -.retro_box .half { - flex: 1 1 50%; -} -.retro_box .choices, -.practice_box .choices { - line-height: 1.6em; - margin: 5px 0 -5px 0; -} -.retro_box .choices a, -.practice_box .choices a { - display: block; - color: #3893E8; -} -.retro_box .continue { - display: flex; - font-size: 1.3em; - background: rgba(56,147,232,0.8); - color: #fff; - align-items: center; - justify-content: center; - text-transform: uppercase; - padding: 0 10px; -} -.retro_box .continue:hover { - background: rgba(56,147,232,1); -} -.retro_box .continue i::before { - font-size: 2.5em; - margin-right: 10px; -} -body.dark .retro_box, -body.dark .practice_box { - background: #303030; - color: #aaa; -} -body.dark .retro_box .feedback .progress, -body.dark .practice_box .feedback .progress { - background: #666; -} - -.practice_box { - flex: 0 0 135px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; -} -.practice_box .comment { - flex: 0 0 30px; - display: flex; - align-items: stretch; - background: #f8f8f8; - border-top: 1px solid #ddd; - white-space: nowrap; - line-height: 30px; -} -body.dark .practice_box .comment { - background: #404040; - white-space: nowrap; -} -.practice_box .progress div { - background: #aaa; -} -.practice_box.goodMove .title, -.practice_box.goodMove .progress div { - background: #759900!important; - color: #fff!important; -} -.practice_box.inaccuracy .title, -.practice_box.inaccuracy .progress div { - background: #d59120!important; - color: #fff!important; -} -.practice_box.mistake .title, -.practice_box.blunder .title, -.practice_box.mistake .progress div, -.practice_box.blunder .progress div { - background: #dc322f!important; - color: #fff!important; -} -.practice_box .comment .wait { - padding-left: 15px; -} -.practice_box .verdict { - font-weight: bold; - font-size: 1.2em; - margin-right: 10px; - display: flex; -} -.practice_box .verdict::before { - width: 30px; - height: 100%; - color: #fff; - margin-right: 7px; - text-align: center; - font-size: 1.4em; - font-weight: normal; -} -.practice_box.goodMove .verdict { - color: #759900; -} -.practice_box.goodMove .verdict::before { - background: #759900; - content: '✓'; - font-size: 1.7em; -} -.practice_box.inaccuracy .verdict { - color: #d59120; -} -.practice_box.inaccuracy .verdict::before { - background: #d59120; - content: '?'; -} -.practice_box.mistake .verdict, -.practice_box.blunder .verdict { - color: #dc322f; -} -.practice_box.mistake .verdict::before, -.practice_box.blunder .verdict::before { - background: #dc322f; - content: '✗'; -} -.practice_box .comment move { - margin-left: 5px; - color: #3893E8; - transition: 0.3s; -} - -.lichess_ground .areplay, -.action_menu { - overflow: auto; - overflow-x: hidden; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - margin-left: 0; -} -.lichess_ground .areplay { - background: #fff; - border: 1px solid #ccc; - flex: 2 1 0px; - position: relative; /* for autoscroll */ - will-change: scroll-position; -} -.action_menu { - flex: 1 0; - display: flex; - flex-flow: column; - justify-content: flex-end; - padding-bottom: 10px; -} -.explorer_box, .retro_box, .practice_box, .action_menu { - border-bottom: 3px solid #3893E8!important; -} -.action_menu h2 { - text-transform: uppercase; - text-align: center; - white-space: nowrap; - margin: 15px 0 3px 0; - display: table; - padding: 0 10px; -} -.action_menu h2:before, -.action_menu h2:after { - border-top: 1px solid #ccc; - content: ''; - display: table-cell; - position: relative; - top: 0.65em; - width: 45%; -} -.action_menu h2:before { - right: 8px; -} -.action_menu h2:after { - left: 8px; -} -.action_menu .icon { - display: block; - font-size: 2em; -} -.action_menu .autoplay, -.action_menu .tools { - display: flex; -} -.action_menu .tools { - flex-flow: row wrap; -} -.action_menu .tools > * { - flex: 0 0 50%; - text-align: center; - padding: 0; - height: 75px; - display: flex; - flex-flow: column; - justify-content: center; - text-transform: none; -} -.action_menu .tools form .fbt { - width: 100%; -} -.action_menu .tools i { - line-height: 1em; - margin-bottom: 5px; -} -.action_menu .autoplay .fbt { - flex: 1 1 auto; - padding: 7px 0; - text-align: center; -} -.action_menu form.delete { - text-align: right; - margin-top: 6px; -} -.action_menu form.delete .button { - display: inline-block; - padding: 0 8px; -} -.action_menu form.delete .button::before { - font-size: 1.2em; -} -.action_menu .setting { - padding: 4px 0 4px 10px; - line-height: 22px; - display: flex; -} -.action_menu .setting > label { - flex: 1 0; - cursor: pointer; -} -.action_menu input[type=range] { - width: 100px; - height: 22px; - -webkit-appearance: none; - background: none; -} -.action_menu .range_value { - flex: 0 0 42px; - display: block; - text-align: right; -} -.action_menu input[type=range]:focus { - outline: none; -} -.action_menu input[type=range]::-webkit-slider-runnable-track { - width: 100%; - height: 11.4px; - cursor: pointer; - background: rgba(214, 214, 214, 0.78); - border-radius: 6px; -} -.action_menu input[type=range]::-webkit-slider-thumb { - border: 1px solid #aaaaaa; - height: 12px; - width: 18px; - border-radius: 12px; - background: #ffffff; - cursor: pointer; - -webkit-appearance: none; - margin-top: -0.3px; -} -.action_menu input[type=range]::-moz-range-track { - width: 100%; - height: 11.4px; - cursor: pointer; - background: rgba(214, 214, 214, 0.78); - border-radius: 5.9px; -} -.action_menu input[type=range]::-moz-range-thumb { - border: 1px solid #aaaaaa; - height: 12px; - width: 18px; - border-radius: 12px; - background: #ffffff; - cursor: pointer; -} -.action_menu input[type=range]::-ms-track { - width: 100%; - height: 11.4px; - cursor: pointer; - background: transparent; - border-color: transparent; - color: transparent; -} -.action_menu input[type=range]::-ms-fill-lower { - background: rgba(191, 191, 191, 0.78); - border-radius: 11.8px; -} -.action_menu input[type=range]::-ms-fill-upper { - background: rgba(214, 214, 214, 0.78); - border-radius: 11.8px; -} -.action_menu input[type=range]::-ms-thumb { - border: 1px solid #aaaaaa; - height: 12px; - width: 18px; - border-radius: 12px; - background: #ffffff; - cursor: pointer; - height: 11.4px; -} -body.dark .action_menu input[type=range]::-webkit-slider-runnable-track { - background: rgba(70, 70, 70, 0.78); -} -body.dark .action_menu input[type=range]::-moz-range-track { - background: rgba(70, 70, 70, 0.78); -} -body.dark .action_menu input[type=range]::-ms-fill-upper { - background: rgba(70, 70, 70, 0.78); -} - -.lichess_ground .opening { - padding-bottom: 3px; -} - -.aclocks { - position: absolute; - right: -62px; - width: 62px; - top: calc(50% - 32px); - font-family: 'Roboto Mono', 'Roboto'; - box-sizing: border-box; - line-height: 20px; -} -.aclocks .aclock { - height: 20px; - line-height: 20px; - padding: 5px 0; - text-align: center; - border: 1px solid #ccc; -} - -.aclocks .aclock:first-child { - border-width: 1px 1px 1px 0; - border-radius: 0 4px 0 0; -} -.aclocks .aclock:last-child { - border-width: 0 1px 1px 0; - border-radius: 0 0 4px 0; -} -.aclocks .aclock.active { - background: #fafafa; - font-weight: bold; -} -.aclocks .aclock tenths { - font-size: 80%; -} - -body.dark .aclocks .aclock { - border-color: #3d3d3d; -} -body.dark .aclocks .aclock.active { - background: #303030; -} - -.tview2 { - white-space: normal; -} -.tview2.column { - display: flex; - flex-flow: row wrap; - font-size: 13.5px; - line-height: 1.25; -} -.tview2.inline { - padding: 7px 3px 7px 7px; - font-size: 16px; - line-height: 1em; -} -.lichess_ground move { - font-family: 'ChessSansPiratf', sans-serif; - white-space: nowrap; - overflow: hidden; - display: inline-block; - cursor: pointer; -} -body.piece_letter .lichess_ground move { - font-family: 'Noto Sans'; -} -.tview2.column move { - font-size: 1.092em; - padding: 0 2px; -} -.tview2.inline move { - padding: 0.25em 0.17em; - white-space: nowrap; - font-weight: bold; -} -.tview2 move.parent, -.tview2 comment a { - color: #3893e8!important; -} -.tview2 comment a { - vertical-align: top; -} -.tview2 move.current { - border: 1px solid #d85000!important; -} -.tview2 move.active { - font-weight: bold; - background: rgba(56,147,232,0.2); -} -.tview2.inline move.active { - border-radius: 3px; -} -.tview2 move.nongame { - font-style: italic; -} -.tview2 move:not(.empty):hover, -.tview2 move:not(.empty):hover index, -.tview2 move:not(.empty):hover eval { - background: #3893e8!important; - color: #fff!important; -} -.tview2.inline move:hover { - border-radius: 3px; -} -.tview2 move.empty { - color: #aaa; - cursor: default; -} -.tview2 move.context_menu { - background: #d85000!important; - color: #fff!important; -} -.tview2 move index { - font-size: 90%; - color: #999; -} -.tview2.column move index { - padding-left: 5px; -} -.tview2.column move index:first-child { - padding-left: 0; -} -.tview2.inline move index { - padding-right: 0.2em; - line-height: 111.11% -} -.tview2 line move { - color: #606060; -} -.tview2.column > move { - flex: 0 0 43.5%; - max-width: 43.5%; /* required by IE 11 https://github.com/philipwalton/flexbugs/issues/3 */ - display: flex; - box-sizing: border-box; - font-size: 1.185em; - line-height: 1.75em; - padding-left: 7px; - padding-right: 3px; -} -.tview2.column > index + move { - border-right: 1px solid #ddd; -} -.tview2 eval { - flex: 3 0 auto; - text-align: right; - font-size: 0.8em; - font-family: 'Roboto'; - color: #999; -} -.tview2 glyph { - font-family: 'Noto Sans'; - margin-left: 0.08em; -} -.tview2.column > move glyph { - flex: 0 1 auto; - text-align: center; - overflow: hidden; - font-size: 0.82em; -} -.tview2.column > index { - flex: 0 0 13%; - max-width: 13%; /* required by IE 11 https://github.com/philipwalton/flexbugs/issues/3 */ - display: flex; - justify-content: center; - box-sizing: border-box; - border-right: 1px solid #ddd; - background: #f8f8f8; - line-height: 2.07em; - color: #c0c0c0; -} -.tview2 > interrupt { - font-size: 95%; -} -.tview2.column > interrupt { - flex: 0 0 100%; - background: #f8f8f8; - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - box-sizing: border-box; - max-width: 100%; -} -.tview2.column > interrupt > comment { - display: block; - padding: 3px 5px; - word-wrap: break-word; -} -.tview2.inline comment { - vertical-align: 45%; - word-wrap: break-word; - margin: 0 0.2em 0 0.1em; - font-size: 0.9em; -} -.tview2 comment .by { - display: inline-block; - vertical-align: -0.3em; - white-space: nowrap; - font-family: 'Roboto'; - font-size: 0.9em; - opacity: 0.8; - margin-right: 0.4em; - max-width: 9em; - overflow: hidden; - text-overflow: ellipsis; -} -.tview2.column comment.white { - border-left: 3px solid; -} -.tview2.column comment.black { - border-right: 3px solid; - overflow-x: hidden; -} -.tview2.column comment.inaccuracy { - border-color: #56B4E9; -} -.tview2.column comment.mistake { - border-color: #E69F00; -} -.tview2.column comment.blunder { - border-color: #DF5353; -} -.tview2.column comment.undefined { - border-color: #66558C; -} -.tview2 line comment { - font-size: 90%; -} -.tview2.column line comment { - display: inline; - color: #808080; - word-wrap: break-word; - padding: 0 5px 0 3px; - vertical-align: top; -} -.tview2 line comment .by { - font-size: 1em; - vertical-align: top; -} -.tview2 lines { - display: block; - margin-top: 2px; - margin-left: 6px; - margin-bottom: 0.8em; - border-left: 2px solid #ccc; -} -.tview2 > interrupt > lines { - margin-left: 0px; -} -.tview2 lines.single { - border-left: none; -} -.tview2 lines:last-child { - margin-bottom: 0; -} -.tview2 line { - display: block; - padding-left: 7px; -} -.tview2.column line { - margin: 2px 0; -} -.tview2 lines lines move { - font-size: 13px; -} -.tview2 lines lines { - margin-left: 1px; -} -.tview2 lines lines::before { - content: ' '; - border-top: 2px solid #ccc; - position: absolute; - margin-left: -11px; - width: 9px; - height: 6px; -} -.tview2 lines line::before { - margin-top: 0.65em; - margin-left: -8px; - content: ' '; - border-top: 2px solid #ccc; - position: absolute; - width: 8px; - height: 6px; -} -.tview2 lines lines:last-child { - margin-bottom: 0; -} -.tview2 inline { - display: inline; - font-style: italic; - font-size: 0.9em; - opacity: 0.8; -} -.tview2 inline::before, -.tview2 inline::after { - vertical-align: 0.4em; - opacity: 0.7; - font-size: 0.9em; -} -.tview2 inline::before { - content: '('; - margin-left: 2px; -} -.tview2 inline::after { - content: ')'; - margin-right: 2px; -} -.tview2.inline inline::before, -.tview2.inline inline::after { - vertical-align: 0.7em; -} -.tview2 .conceal { - opacity: 0.4; -} -.tview2 .hide { - display: none; -} -body.dark .tview2 > index { - color: #6a6a6a; -} -body.dark .tview2 move { - color: #aaa; -} -body.dark .tview2 move.active { - background: rgba(56,147,232,0.4); - color: #dfdfdf; -} -body.dark .tview2.column comment { - color: #999; -} -body.dark .tview2.column line comment { - color: #888; -} -body.dark .tview2 lines, -body.dark .tview2 lines lines::before, -body.dark .tview2 lines line::before { - border-color: #666; -} -.lichess_ground .areplay .result, -.lichess_ground .areplay .status { - background: #f8f8f8; -} -div.underboard { - margin-top: 25px; -} -div.underboard .center { - padding: 0; -} -div.copyables label.name { - font-weight: bold; -} -div.copyables textarea, -div.copyables label { - display: inline-block; - vertical-align: middle; -} -div.copyables .pgn { - margin-top: 1em; - margin-bottom: 20px; -} -div.copyables .pgn textarea { - color: #747474; - resize: vertical; - min-height: 6em; - white-space: pre-wrap; - overflow-x: hidden; -} -div.copyables .pgn .action { - display: none; - text-align: right; - margin-top: 10px; -} -div.copyables .pgn:hover .action { - display: block; -} -div.advice_summary { - margin-top: 13px; - display: flex; - flex-flow: column; - height: 180px; - justify-content: space-between; - align-items: flex-start; - line-height: 1.15em; -} -div.advice_summary table { - width: 100%; -} -div.advice_summary td { - width: 25px; - padding-right: 5px; - text-align: center; -} -div.advice_summary tbody td { - font-weight: bold; -} -div.advice_summary tr.symbol { - cursor: pointer; -} -div.advice_summary tr.symbol:hover { - color: #3893E8; -} -div.advice_summary .button { - margin-left: 29px; -} - -#adv_chart, -#movetimes_chart { - height: 210px; - background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0) 20%, rgba(128, 128, 128, 0.2) 50%, rgba(255, 255, 255, 0) 80%, rgba(255, 255, 255, 0) 100%); - overflow: hidden; -} -div.panel.computer_analysis { - position: relative; -} -#adv_chart_loader { - position: absolute; - top: 76px; - left: -1px; - background: #fff; - padding: 7px 10px 7px 0; - line-height: 20px; - box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.3); - display: flex; - border: 1px solid #ccc; - border-radius: 0 50px 50px 0; -} -#adv_chart_loader span { - margin-left: 7px; - opacity: 1; - transition: 0.5s; - white-space: nowrap; - overflow: hidden; - width: 90px; - display: block; -} -div.underboard:hover #adv_chart_loader span { - margin-left: 0; - width: 0; - opacity: 0; -} -#adv_chart_loader .spinner { - width: 32px; - height: 32px; - display:inline-block; - margin-left: 10px; -} -span.mod { - display: inline-block; - border-left: 3px solid; - padding-left: 2px; -} -span.blurs { - border-color: #DDCF3F; -} -span.hold { - border-color: #E73B38; -} -.copyables > p { - margin-top: 7px; -} -.copyables .name { - font-size: 1.2em; - display: inline-block; - width: 40px; -} -.copyable { - width: 455px; -} -.analeft { - position: absolute; - top: 53px; - left: -241px; - width: 226px; -} -.back_to_game { - margin-top: 30px; - text-align: center; -} - -.mselect { - margin-top: 20px; - width: 100%; - font-size: 1.2em; - box-sizing: border-box; - display:inline-block; - position: relative; - padding:0; - border:0; -} -.mselect .button { - position: relative; - display: inline-block; - box-sizing: border-box; - width: 100%; - padding: 10px; -} -.mselect .button i { - font-size: 10px; - position: absolute; - right: 5px; - top: 14px; -} -.mselect .list { - width:100%; - margin:0; - padding:0; - position:absolute; - top:0; - text-align: left; - list-style-type:none; - font-weight: normal; - background:#FFF; - box-shadow: 0px 8px 17px 0px rgba(0, 0, 0, 0.2), 0px 6px 20px 0px rgba(0, 0, 0, 0.19); - border-radius: 3px; - display: none; -} -.mselect.shown .list { - display: block; -} -.mselect .list a { - display: block; - padding: 10px; - background:#fff; - transition: 0.13s; - outline:0; - text-decoration:none; - cursor:pointer; -} -.mselect .list a:hover{ - background: #3893E8; - color: #fff; -} -.mselect a[data-icon]:before, -.mselect .button[data-icon]:before { - font-size: 1.5em; - margin-right: 10px; - color: #3893E8; - transition: 0.13s; -} -.mselect a:hover:before { - color: #fff; -} - -#analyse-cm { - position: absolute; - display: none; - z-index: 900000; - cursor: default; - background: #f0f0f0; - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15); -} -#analyse-cm.visible { - display: block; -} -#analyse-cm .title { - padding: 5px; - background: #777; - color: #fff; - text-align: center; - font-family: 'ChessSansPiratf', sans-serif; - font-size: 14px; -} -body.piece_letter #analyse-cm .title { - font-family: 'Noto Sans'; -} -#analyse-cm .action { - display: block; - padding: 10px; -} -#analyse-cm .action::before { - margin-right: 10px; -} -#analyse-cm .action:hover { - background: #fff; -} diff --git a/public/stylesheets/authFailed.css b/public/stylesheets/authFailed.css deleted file mode 100644 index be4a66c92f..0000000000 --- a/public/stylesheets/authFailed.css +++ /dev/null @@ -1,26 +0,0 @@ -div.content_box header { - overflow: hidden; -} -div.content_box header h1 { - font-size: 110px; - float: left; - font-weight: bold; - margin: -30px 30px 0 0; - opacity: 0.3; -} -div.content_box header strong { - text-transform: uppercase; - opacity: 0.5; - font-size: 31px; - margin: 10px 0 10px 0; - display: block; -} -div.content_box a.underline { - text-decoration: underline; -} -div.content_box div.game { - text-align: center; -} -div.content_box .credits { - margin-top: 2em; -} diff --git a/public/stylesheets/autocomplete.css b/public/stylesheets/autocomplete.css deleted file mode 100644 index 2318fb425b..0000000000 --- a/public/stylesheets/autocomplete.css +++ /dev/null @@ -1,48 +0,0 @@ -.tt-menu { - box-sizing: border-box; - width: 198px; - background-color: #fff; - border: 1px solid #ccc; - box-shadow: 2px 5px 6px rgba(0, 0, 0, 0.3); -} -.tt-menu .empty { - padding: 5px 0 5px 10px; -} -.tt-menu .spinner { - margin: 10px auto; - width: 20px; - height: 20px; -} -a.tt-suggestion, -span.tt-suggestion { - color: #555; - padding: 5px 0 5px 5px; - line-height: 24px; - display: block; - cursor: pointer; -} -.tt-suggestion:hover { - background: rgba(56,147,232,0.2); -} -.tt-suggestion.tt-cursor { - background: #3893E8!important; - color: #fff!important; -} -.tt-suggestion.user_link i { - margin-right: 3px; -} -.tt-hint { - color: #aaa; -} -/* .tt-highlight { */ -/* font-weight: bold; */ - /* opacity: 0.5; */ -/* } */ -body.dark .tt-menu { - border-color: #3d3d3d; - background: #343434; -} -body.dark a.tt-suggestion, -body.dark span.tt-suggestion { - color: #aaa; -} diff --git a/public/stylesheets/blog.css b/public/stylesheets/blog.css deleted file mode 100644 index 03cdddcb41..0000000000 --- a/public/stylesheets/blog.css +++ /dev/null @@ -1,114 +0,0 @@ -#lichess_blog .blog_title { - display: block; - text-align: center; - font-size: 2.6em; -} -#lichess_blog h1 a.atom { - color: #ff6600; - float: right; -} -#lichess_blog .meta { - text-align: center; - margin: 20px 0; -} -#lichess_blog .meta span { - display:inline-block; - margin-right: 10px; -} -#lichess_blog .illustration, -#lichess_blog [data-oembed] { - text-align: center; -} -#lichess_blog .illustration img { - max-height: 300px; -} -#Vs0xMTAAAD4We4Ey [data-oembed] iframe, -#V0KrLSkAAMo3hsi4 [data-oembed] iframe { - width: 744px; - height: 417px; -} -#lichess_blog twitter-widget { - margin: 30px auto!important; -} -#lichess_blog .post.no-icon .illustration { - display: none; -} -#lichess_blog .shortlede { - display: block; - text-align: center; - font-size: 1.4em; - font-weight: normal; - font-style: italic; - margin: 20px 0; -} -#lichess_blog .body { - font-size: 1.4em; - line-height: 1.6; - margin: 20px 0 60px 0; - cursor: initial; -} -#lichess_blog .body p { - margin: 15px 0; -} -#lichess_blog .meta a, -#lichess_blog .body a { - text-decoration: underline; -} -#lichess_blog .body a:hover { - text-decoration: none; -} -#lichess_blog .body strong { - font-weight: bold; -} -#lichess_blog .body em { - font-style: italic; -} -#lichess_blog .body .block-img { - text-align: center; -} -#lichess_blog .body .block-img + p > em:first-child { - margin-top: -20px; - display: block; - font-size: 0.8em; - text-align: center; -} -#lichess_blog ol, #lichess_blog ul { - margin: 25px; -} -#lichess_blog li { - list-style: disc outside; -} -#lichess_blog .body h2 { - font-size: 1.4em; - border-bottom: 1px solid #eee; - margin: 35px 0; -} -#lichess_blog .body h3 { - font-size: 1.2em; - font-weight: bold; - margin: 25px 0; -} -#lichess_blog .body img { - padding: 5px; - border: 1px solid #ccc; -} -#lichess_blog .body iframe.study { - border: none; - margin: 1em 0; -} - -#lichess_blog .list h1 { - border-bottom: 1px solid #eee; - margin-top: 35px; -} -#lichess_blog .list .meta { - text-align: center; -} -#lichess_blog .list .more { - text-align: center; -} -#lichess_blog .footer { - text-align: center; - font-size: 1.3em; - margin-bottom: 40px; -} diff --git a/public/stylesheets/board-3d.css b/public/stylesheets/board-3d.css deleted file mode 100644 index 4b0984f3e9..0000000000 --- a/public/stylesheets/board-3d.css +++ /dev/null @@ -1,649 +0,0 @@ -.is3d .cg-512 .cg-board-wrap { - height: 464.5px -} -.is3d .cg-board-wrap coords.files { - bottom: calc(-12px - 3%); -} -.is3d .cg-board-wrap coords.ranks { - height: 100%; -} -.is3d piece { - /* original size: - width: 140.625%; - height: 179.6875%; */ - /* size on 3D board, with height/width = 90.78571% */ - width: 16.741%; - height: 23.563%; - left: -1.85%; - top: -9.1%; -} -.is3d piece.dragging, -.is3d #promotion_choice { - z-index: 70!important; -} -#top .dropdown { - z-index: 71; -} -.is3d .is2d piece { - /* copy of board.css to override miniboards */ - left: 0; - top: 0; - width: 12.5%; - height: 12.5%; -} -.is3d div.lichess_game { - height: 476px; -} -.is3d .cg-board::before { - position: absolute; - top: -0.730688%; - left: 0; - width: 100%; - height: 103.2%; - content: ''; - background-size: cover; -} -.is3d .is2d .cg-board { - /* copy of board.css to override miniboards */ - top: 0; - height: 100%; -} -.is3d .is2d .cg-board::before { - content: none; -} -/* 3D boards */ -.Black-White-Aluminium .is3d .cg-board::before { - background-image: url(../images/staunton/board/Black-White-Aluminium.png); -} -.Brushed-Aluminium .is3d .cg-board::before { - background-image: url(../images/staunton/board/Brushed-Aluminium.png); -} -.China-Blue .is3d .cg-board::before { - background-image: url(../images/staunton/board/China-Blue.png); -} -.China-Green .is3d .cg-board::before { - background-image: url(../images/staunton/board/China-Green.png); -} -.China-Grey .is3d .cg-board::before { - background-image: url(../images/staunton/board/China-Grey.png); -} -.China-Scarlet .is3d .cg-board::before { - background-image: url(../images/staunton/board/China-Scarlet.png); -} -.China-Yellow .is3d .cg-board::before { - background-image: url(../images/staunton/board/China-Yellow.png); -} -.Classic-Blue .is3d .cg-board::before { - background-image: url(../images/staunton/board/Classic-Blue.png); -} -.Transparent-Glass .is3d .cg-board::before { - background-image: url(../images/staunton/board/Glass.png); -} -.Gold-Silver .is3d .cg-board::before { - background-image: url(../images/staunton/board/Gold-Silver.png); -} -.Green-Glass .is3d .cg-board::before { - background-image: url(../images/staunton/board/Green-Glass.png); -} -.Light-Wood .is3d .cg-board::before { - background-image: url(../images/staunton/board/Light-Wood.png); -} -.Power-Coated .is3d .cg-board::before { - background-image: url(../images/staunton/board/Power-Coated.png); -} -.Purple-Black .is3d .cg-board::before { - background-image: url(../images/staunton/board/Purple-Black.png); -} -.Rosewood .is3d .cg-board::before { - background-image: url(../images/staunton/board/Rosewood.png); -} -.Wood-Glass .is3d .cg-board::before { - background-image: url(../images/staunton/board/Wood-Glass.png); -} -.Wax .is3d .cg-board::before { - background-image: url(../images/staunton/board/Wax.png); -} -.Jade .is3d .cg-board::before { - background-image: url(../images/staunton/board/Jade.png); -} -.Marble .is3d .cg-board::before { - background-image: url(../images/board/3d/marble.1024.png); -} -.Woodi .is3d .cg-board::before { - background-image: url(../images/board/3d/woodi.1024.png); -} -/* 3D pieces */ -.Basic .is3d .pawn.white { - background-image: url(../images/staunton/piece/Basic/White-Pawn.png); -} -.Basic .is3d .bishop.white { - background-image: url(../images/staunton/piece/Basic/White-Bishop.png); -} -.Basic .is3d .cg-512 .orientation-black .bishop.white { - background-image: url(../images/staunton/piece/Basic/White-Bishop-Flipped.png); -} -.Basic .is3d .knight.white { - background-image: url(../images/staunton/piece/Basic/White-Knight.png); -} -.Basic .is3d .cg-512 .orientation-black .knight.white { - background-image: url(../images/staunton/piece/Basic/White-Knight-Flipped.png); -} -.Basic .is3d .rook.white { - background-image: url(../images/staunton/piece/Basic/White-Rook.png); -} -.Basic .is3d .queen.white { - background-image: url(../images/staunton/piece/Basic/White-Queen.png); -} -.Basic .is3d .king.white { - background-image: url(../images/staunton/piece/Basic/White-King.png); -} -.Basic .is3d .pawn.black { - background-image: url(../images/staunton/piece/Basic/Black-Pawn.png); -} -.Basic .is3d .bishop.black { - background-image: url(../images/staunton/piece/Basic/Black-Bishop.png); -} -.Basic .is3d .cg-512 .orientation-white .bishop.black { - background-image: url(../images/staunton/piece/Basic/Black-Bishop-Flipped.png); -} -.Basic .is3d .knight.black { - background-image: url(../images/staunton/piece/Basic/Black-Knight.png); -} -.Basic .is3d .cg-512 .orientation-white .knight.black { - background-image: url(../images/staunton/piece/Basic/Black-Knight-Flipped.png); -} -.Basic .is3d .rook.black { - background-image: url(../images/staunton/piece/Basic/Black-Rook.png); -} -.Basic .is3d .queen.black { - background-image: url(../images/staunton/piece/Basic/Black-Queen.png); -} -.Basic .is3d .king.black { - background-image: url(../images/staunton/piece/Basic/Black-King.png); -} -.Glass .is3d .pawn.white { - background-image: url(../images/staunton/piece/Glass/White-Pawn.png); -} -.Glass .is3d .bishop.white { - background-image: url(../images/staunton/piece/Glass/White-Bishop.png); -} -.Glass .is3d .cg-512 .orientation-black .bishop.white { - background-image: url(../images/staunton/piece/Glass/White-Bishop-Flipped.png); -} -.Glass .is3d .knight.white { - background-image: url(../images/staunton/piece/Glass/White-Knight.png); -} -.Glass .is3d .cg-512 .orientation-black .knight.white { - background-image: url(../images/staunton/piece/Glass/White-Knight-Flipped.png); -} -.Glass .is3d .rook.white { - background-image: url(../images/staunton/piece/Glass/White-Rook.png); -} -.Glass .is3d .queen.white { - background-image: url(../images/staunton/piece/Glass/White-Queen.png); -} -.Glass .is3d .king.white { - background-image: url(../images/staunton/piece/Glass/White-King.png); -} -.Glass .is3d .pawn.black { - background-image: url(../images/staunton/piece/Glass/Black-Pawn.png); -} -.Glass .is3d .bishop.black { - background-image: url(../images/staunton/piece/Glass/Black-Bishop.png); -} -.Glass .is3d .cg-512 .orientation-white .bishop.black { - background-image: url(../images/staunton/piece/Glass/Black-Bishop-Flipped.png); -} -.Glass .is3d .knight.black { - background-image: url(../images/staunton/piece/Glass/Black-Knight.png); -} -.Glass .is3d .cg-512 .orientation-white .knight.black { - background-image: url(../images/staunton/piece/Glass/Black-Knight-Flipped.png); -} -.Glass .is3d .rook.black { - background-image: url(../images/staunton/piece/Glass/Black-Rook.png); -} -.Glass .is3d .queen.black { - background-image: url(../images/staunton/piece/Glass/Black-Queen.png); -} -.Glass .is3d .king.black { - background-image: url(../images/staunton/piece/Glass/Black-King.png); -} -.Wood .is3d .pawn.white { - background-image: url(../images/staunton/piece/Wood/White-Pawn.png); -} -.Wood .is3d .bishop.white { - background-image: url(../images/staunton/piece/Wood/White-Bishop.png); -} -.Wood .is3d .cg-512 .orientation-black .bishop.white { - background-image: url(../images/staunton/piece/Wood/White-Bishop-Flipped.png); -} -.Wood .is3d .knight.white { - background-image: url(../images/staunton/piece/Wood/White-Knight.png); -} -.Wood .is3d .cg-512 .orientation-black .knight.white { - background-image: url(../images/staunton/piece/Wood/White-Knight-Flipped.png); -} -.Wood .is3d .rook.white { - background-image: url(../images/staunton/piece/Wood/White-Rook.png); -} -.Wood .is3d .queen.white { - background-image: url(../images/staunton/piece/Wood/White-Queen.png); -} -.Wood .is3d .king.white { - background-image: url(../images/staunton/piece/Wood/White-King.png); -} -.Wood .is3d .pawn.black { - background-image: url(../images/staunton/piece/Wood/Black-Pawn.png); -} -.Wood .is3d .bishop.black { - background-image: url(../images/staunton/piece/Wood/Black-Bishop.png); -} -.Wood .is3d .cg-512 .orientation-white .bishop.black { - background-image: url(../images/staunton/piece/Wood/Black-Bishop-Flipped.png); -} -.Wood .is3d .knight.black { - background-image: url(../images/staunton/piece/Wood/Black-Knight.png); -} -.Wood .is3d .cg-512 .orientation-white .knight.black { - background-image: url(../images/staunton/piece/Wood/Black-Knight-Flipped.png); -} -.Wood .is3d .rook.black { - background-image: url(../images/staunton/piece/Wood/Black-Rook.png); -} -.Wood .is3d .queen.black { - background-image: url(../images/staunton/piece/Wood/Black-Queen.png); -} -.Wood .is3d .king.black { - background-image: url(../images/staunton/piece/Wood/Black-King.png); -} -.Metal .is3d .pawn.white { - background-image: url(../images/staunton/piece/Metal/White-Pawn.png); -} -.Metal .is3d .bishop.white { - background-image: url(../images/staunton/piece/Metal/White-Bishop.png); -} -.Metal .is3d .cg-512 .orientation-black .bishop.white { - background-image: url(../images/staunton/piece/Metal/White-Bishop-Flipped.png); -} -.Metal .is3d .knight.white { - background-image: url(../images/staunton/piece/Metal/White-Knight.png); -} -.Metal .is3d .cg-512 .orientation-black .knight.white { - background-image: url(../images/staunton/piece/Metal/White-Knight-Flipped.png); -} -.Metal .is3d .rook.white { - background-image: url(../images/staunton/piece/Metal/White-Rook.png); -} -.Metal .is3d .queen.white { - background-image: url(../images/staunton/piece/Metal/White-Queen.png); -} -.Metal .is3d .king.white { - background-image: url(../images/staunton/piece/Metal/White-King.png); -} -.Metal .is3d .pawn.black { - background-image: url(../images/staunton/piece/Metal/Black-Pawn.png); -} -.Metal .is3d .bishop.black { - background-image: url(../images/staunton/piece/Metal/Black-Bishop.png); -} -.Metal .is3d .cg-512 .orientation-white .bishop.black { - background-image: url(../images/staunton/piece/Metal/Black-Bishop-Flipped.png); -} -.Metal .is3d .knight.black { - background-image: url(../images/staunton/piece/Metal/Black-Knight.png); -} -.Metal .is3d .cg-512 .orientation-white .knight.black { - background-image: url(../images/staunton/piece/Metal/Black-Knight-Flipped.png); -} -.Metal .is3d .rook.black { - background-image: url(../images/staunton/piece/Metal/Black-Rook.png); -} -.Metal .is3d .queen.black { - background-image: url(../images/staunton/piece/Metal/Black-Queen.png); -} -.Metal .is3d .king.black { - background-image: url(../images/staunton/piece/Metal/Black-King.png); -} -.RedVBlue .is3d .pawn.white { - background-image: url(../images/staunton/piece/RedVBlue/White-Pawn.png); -} -.RedVBlue .is3d .bishop.white { - background-image: url(../images/staunton/piece/RedVBlue/White-Bishop.png); -} -.RedVBlue .is3d .cg-512 .orientation-black .bishop.white { - background-image: url(../images/staunton/piece/RedVBlue/White-Bishop-Flipped.png); -} -.RedVBlue .is3d .knight.white { - background-image: url(../images/staunton/piece/RedVBlue/White-Knight.png); -} -.RedVBlue .is3d .cg-512 .orientation-black .knight.white { - background-image: url(../images/staunton/piece/RedVBlue/White-Knight-Flipped.png); -} -.RedVBlue .is3d .rook.white { - background-image: url(../images/staunton/piece/RedVBlue/White-Rook.png); -} -.RedVBlue .is3d .queen.white { - background-image: url(../images/staunton/piece/RedVBlue/White-Queen.png); -} -.RedVBlue .is3d .king.white { - background-image: url(../images/staunton/piece/RedVBlue/White-King.png); -} -.RedVBlue .is3d .pawn.black { - background-image: url(../images/staunton/piece/RedVBlue/Black-Pawn.png); -} -.RedVBlue .is3d .bishop.black { - background-image: url(../images/staunton/piece/RedVBlue/Black-Bishop.png); -} -.RedVBlue .is3d .cg-512 .orientation-white .bishop.black { - background-image: url(../images/staunton/piece/RedVBlue/Black-Bishop-Flipped.png); -} -.RedVBlue .is3d .knight.black { - background-image: url(../images/staunton/piece/RedVBlue/Black-Knight.png); -} -.RedVBlue .is3d .cg-512 .orientation-white .knight.black { - background-image: url(../images/staunton/piece/RedVBlue/Black-Knight-Flipped.png); -} -.RedVBlue .is3d .rook.black { - background-image: url(../images/staunton/piece/RedVBlue/Black-Rook.png); -} -.RedVBlue .is3d .queen.black { - background-image: url(../images/staunton/piece/RedVBlue/Black-Queen.png); -} -.RedVBlue .is3d .king.black { - background-image: url(../images/staunton/piece/RedVBlue/Black-King.png); -} -.Trimmed .is3d .pawn.white { - background-image: url(../images/staunton/piece/Trimmed/White-Pawn.png); -} -.Trimmed .is3d .bishop.white { - background-image: url(../images/staunton/piece/Trimmed/White-Bishop.png); -} -.Trimmed .is3d .cg-512 .orientation-black .bishop.white { - background-image: url(../images/staunton/piece/Trimmed/White-Bishop-Flipped.png); -} -.Trimmed .is3d .knight.white { - background-image: url(../images/staunton/piece/Trimmed/White-Knight.png); -} -.Trimmed .is3d .cg-512 .orientation-black .knight.white { - background-image: url(../images/staunton/piece/Trimmed/White-Knight-Flipped.png); -} -.Trimmed .is3d .rook.white { - background-image: url(../images/staunton/piece/Trimmed/White-Rook.png); -} -.Trimmed .is3d .queen.white { - background-image: url(../images/staunton/piece/Trimmed/White-Queen.png); -} -.Trimmed .is3d .king.white { - background-image: url(../images/staunton/piece/Trimmed/White-King.png); -} -.Trimmed .is3d .pawn.black { - background-image: url(../images/staunton/piece/Trimmed/Black-Pawn.png); -} -.Trimmed .is3d .bishop.black { - background-image: url(../images/staunton/piece/Trimmed/Black-Bishop.png); -} -.Trimmed .is3d .cg-512 .orientation-white .bishop.black { - background-image: url(../images/staunton/piece/Trimmed/Black-Bishop-Flipped.png); -} -.Trimmed .is3d .knight.black { - background-image: url(../images/staunton/piece/Trimmed/Black-Knight.png); -} -.Trimmed .is3d .cg-512 .orientation-white .knight.black { - background-image: url(../images/staunton/piece/Trimmed/Black-Knight-Flipped.png); -} -.Trimmed .is3d .rook.black { - background-image: url(../images/staunton/piece/Trimmed/Black-Rook.png); -} -.Trimmed .is3d .queen.black { - background-image: url(../images/staunton/piece/Trimmed/Black-Queen.png); -} -.Trimmed .is3d .king.black { - background-image: url(../images/staunton/piece/Trimmed/Black-King.png); -} -.Experimental .is3d .pawn.white { - background-image: url(../images/staunton/piece/Experimental/White-Pawn.png); -} -.Experimental .is3d .bishop.white { - background-image: url(../images/staunton/piece/Experimental/White-Bishop.png); -} -.Experimental .is3d .cg-512 .orientation-black .bishop.white { - background-image: url(../images/staunton/piece/Experimental/White-Bishop-Flipped.png); -} -.Experimental .is3d .knight.white { - background-image: url(../images/staunton/piece/Experimental/White-Knight.png); -} -.Experimental .is3d .cg-512 .orientation-black .knight.white { - background-image: url(../images/staunton/piece/Experimental/White-Knight-Flipped.png); -} -.Experimental .is3d .rook.white { - background-image: url(../images/staunton/piece/Experimental/White-Rook.png); -} -.Experimental .is3d .queen.white { - background-image: url(../images/staunton/piece/Experimental/White-Queen.png); -} -.Experimental .is3d .king.white { - background-image: url(../images/staunton/piece/Experimental/White-King.png); -} -.Experimental .is3d .pawn.black { - background-image: url(../images/staunton/piece/Experimental/Black-Pawn.png); -} -.Experimental .is3d .bishop.black { - background-image: url(../images/staunton/piece/Experimental/Black-Bishop.png); -} -.Experimental .is3d .cg-512 .orientation-white .bishop.black { - background-image: url(../images/staunton/piece/Experimental/Black-Bishop-Flipped.png); -} -.Experimental .is3d .knight.black { - background-image: url(../images/staunton/piece/Experimental/Black-Knight.png); -} -.Experimental .is3d .cg-512 .orientation-white .knight.black { - background-image: url(../images/staunton/piece/Experimental/Black-Knight-Flipped.png); -} -.Experimental .is3d .rook.black { - background-image: url(../images/staunton/piece/Experimental/Black-Rook.png); -} -.Experimental .is3d .queen.black { - background-image: url(../images/staunton/piece/Experimental/Black-Queen.png); -} -.Experimental .is3d .king.black { - background-image: url(../images/staunton/piece/Experimental/Black-King.png); -} -.ModernJade .is3d .pawn.white { - background-image: url(../images/staunton/piece/ModernJade/White-Pawn.png); -} -.ModernJade .is3d .bishop.white { - background-image: url(../images/staunton/piece/ModernJade/White-Bishop.png); -} -.ModernJade .is3d .cg-512 .orientation-black .bishop.white { - background-image: url(../images/staunton/piece/ModernJade/White-Bishop-Flipped.png); -} -.ModernJade .is3d .knight.white { - background-image: url(../images/staunton/piece/ModernJade/White-Knight.png); -} -.ModernJade .is3d .cg-512 .orientation-black .knight.white { - background-image: url(../images/staunton/piece/ModernJade/White-Knight-Flipped.png); -} -.ModernJade .is3d .rook.white { - background-image: url(../images/staunton/piece/ModernJade/White-Rook.png); -} -.ModernJade .is3d .queen.white { - background-image: url(../images/staunton/piece/ModernJade/White-Queen.png); -} -.ModernJade .is3d .king.white { - background-image: url(../images/staunton/piece/ModernJade/White-King.png); -} -.ModernJade .is3d .pawn.black { - background-image: url(../images/staunton/piece/ModernJade/Black-Pawn.png); -} -.ModernJade .is3d .bishop.black { - background-image: url(../images/staunton/piece/ModernJade/Black-Bishop.png); -} -.ModernJade .is3d .cg-512 .orientation-white .bishop.black { - background-image: url(../images/staunton/piece/ModernJade/Black-Bishop-Flipped.png); -} -.ModernJade .is3d .knight.black { - background-image: url(../images/staunton/piece/ModernJade/Black-Knight.png); -} -.ModernJade .is3d .cg-512 .orientation-white .knight.black { - background-image: url(../images/staunton/piece/ModernJade/Black-Knight-Flipped.png); -} -.ModernJade .is3d .rook.black { - background-image: url(../images/staunton/piece/ModernJade/Black-Rook.png); -} -.ModernJade .is3d .queen.black { - background-image: url(../images/staunton/piece/ModernJade/Black-Queen.png); -} -.ModernJade .is3d .king.black { - background-image: url(../images/staunton/piece/ModernJade/Black-King.png); -} -.ModernWood .is3d .pawn.white { - background-image: url(../images/staunton/piece/ModernWood/White-Pawn.png); -} -.ModernWood .is3d .bishop.white { - background-image: url(../images/staunton/piece/ModernWood/White-Bishop.png); -} -.ModernWood .is3d .cg-512 .orientation-black .bishop.white { - background-image: url(../images/staunton/piece/ModernWood/White-Bishop-Flipped.png); -} -.ModernWood .is3d .knight.white { - background-image: url(../images/staunton/piece/ModernWood/White-Knight.png); -} -.ModernWood .is3d .cg-512 .orientation-black .knight.white { - background-image: url(../images/staunton/piece/ModernWood/White-Knight-Flipped.png); -} -.ModernWood .is3d .rook.white { - background-image: url(../images/staunton/piece/ModernWood/White-Rook.png); -} -.ModernWood .is3d .queen.white { - background-image: url(../images/staunton/piece/ModernWood/White-Queen.png); -} -.ModernWood .is3d .king.white { - background-image: url(../images/staunton/piece/ModernWood/White-King.png); -} -.ModernWood .is3d .pawn.black { - background-image: url(../images/staunton/piece/ModernWood/Black-Pawn.png); -} -.ModernWood .is3d .bishop.black { - background-image: url(../images/staunton/piece/ModernWood/Black-Bishop.png); -} -.ModernWood .is3d .cg-512 .orientation-white .bishop.black { - background-image: url(../images/staunton/piece/ModernWood/Black-Bishop-Flipped.png); -} -.ModernWood .is3d .knight.black { - background-image: url(../images/staunton/piece/ModernWood/Black-Knight.png); -} -.ModernWood .is3d .cg-512 .orientation-white .knight.black { - background-image: url(../images/staunton/piece/ModernWood/Black-Knight-Flipped.png); -} -.ModernWood .is3d .rook.black { - background-image: url(../images/staunton/piece/ModernWood/Black-Rook.png); -} -.ModernWood .is3d .queen.black { - background-image: url(../images/staunton/piece/ModernWood/Black-Queen.png); -} -.ModernWood .is3d .king.black { - background-image: url(../images/staunton/piece/ModernWood/Black-King.png); -} -.Staunton .is3d .pawn.white { - background-image: url(../images/staunton/piece/Staunton/White-Pawn.png); -} -.Staunton .is3d .bishop.white { - background-image: url(../images/staunton/piece/Staunton/White-Bishop.png); -} -.Staunton .is3d .knight.white { - background-image: url(../images/staunton/piece/Staunton/White-Knight.png); -} -.Staunton .is3d .rook.white { - background-image: url(../images/staunton/piece/Staunton/White-Rook.png); -} -.Staunton .is3d .queen.white { - background-image: url(../images/staunton/piece/Staunton/White-Queen.png); -} -.Staunton .is3d .king.white { - background-image: url(../images/staunton/piece/Staunton/White-King.png); -} -.Staunton .is3d .pawn.black { - background-image: url(../images/staunton/piece/Staunton/Black-Pawn.png); -} -.Staunton .is3d .bishop.black { - background-image: url(../images/staunton/piece/Staunton/Black-Bishop.png); -} -.Staunton .is3d .knight.black { - background-image: url(../images/staunton/piece/Staunton/Black-Knight.png); -} -.Staunton .is3d .rook.black { - background-image: url(../images/staunton/piece/Staunton/Black-Rook.png); -} -.Staunton .is3d .queen.black { - background-image: url(../images/staunton/piece/Staunton/Black-Queen.png); -} -.Staunton .is3d .king.black { - background-image: url(../images/staunton/piece/Staunton/Black-King.png); -} -.CubesAndPi .is3d .pawn.white { - background-image: url(../images/staunton/piece/CubesAndPi/White-Pawn.png); -} -.CubesAndPi .is3d .bishop.white { - background-image: url(../images/staunton/piece/CubesAndPi/White-Bishop.png); -} -.CubesAndPi .is3d .cg-512 .orientation-black .bishop.white { - background-image: url(../images/staunton/piece/CubesAndPi/White-Bishop-Flipped.png); -} -.CubesAndPi .is3d .knight.white { - background-image: url(../images/staunton/piece/CubesAndPi/White-Knight.png); -} -.CubesAndPi .is3d .cg-512 .orientation-black .knight.white { - background-image: url(../images/staunton/piece/CubesAndPi/White-Knight-Flipped.png); -} -.CubesAndPi .is3d .rook.white { - background-image: url(../images/staunton/piece/CubesAndPi/White-Rook.png); -} -.CubesAndPi .is3d .queen.white { - background-image: url(../images/staunton/piece/CubesAndPi/White-Queen.png); -} -.CubesAndPi .is3d .king.white { - background-image: url(../images/staunton/piece/CubesAndPi/White-King.png); -} -.CubesAndPi .is3d .pawn.black { - background-image: url(../images/staunton/piece/CubesAndPi/Black-Pawn.png); -} -.CubesAndPi .is3d .bishop.black { - background-image: url(../images/staunton/piece/CubesAndPi/Black-Bishop.png); -} -.CubesAndPi .is3d .cg-512 .orientation-white .bishop.black { - background-image: url(../images/staunton/piece/CubesAndPi/Black-Bishop-Flipped.png); -} -.CubesAndPi .is3d .knight.black { - background-image: url(../images/staunton/piece/CubesAndPi/Black-Knight.png); -} -.CubesAndPi .is3d .cg-512 .orientation-white .knight.black { - background-image: url(../images/staunton/piece/CubesAndPi/Black-Knight-Flipped.png); -} -.CubesAndPi .is3d .rook.black { - background-image: url(../images/staunton/piece/CubesAndPi/Black-Rook.png); -} -.CubesAndPi .is3d .queen.black { - background-image: url(../images/staunton/piece/CubesAndPi/Black-Queen.png); -} -.CubesAndPi .is3d .king.black { - background-image: url(../images/staunton/piece/CubesAndPi/Black-King.png); -} - -.is3d #promotion_choice piece { - width: 140.625%; - height: 197.925%; - top: 0; - left: -18%; - transform: scale(0.7) translateY(-45%); - background-position: 0 -6px; -} - -.is3d div.current_player piece { - width: 100%; - height: 132%; - left: 0; - top: -6px; - background-size: cover; - background-position: 0 67%; -} diff --git a/public/stylesheets/board.coords.inner.css b/public/stylesheets/board.coords.inner.css deleted file mode 100644 index 97408f0399..0000000000 --- a/public/stylesheets/board.coords.inner.css +++ /dev/null @@ -1,69 +0,0 @@ -.cg-board-wrap coords { - color: #fff; - text-shadow: 0 1px 2px #000; -} -.cg-board-wrap coords.files { - bottom: 0px; - text-align: left; -} -.cg-board-wrap coords.files coord { - padding-left: 2px; -} -.cg-board-wrap coords.ranks { - right: -4px; - text-align: left; -} -.cg-board-wrap coords.ranks coord { - transform: none; -} -.brown coord, .green coord, .blue coord { - text-shadow: none; -} -.brown .orientation-white .files coords:nth-child(2n+1), -.brown .orientation-white .ranks coords:nth-child(2n), -.brown .orientation-black .files coords:nth-child(2n), -.brown .orientation-black .ranks coords:nth-child(2n+1) { - color: #F0D9B5; -} -.brown .orientation-white .files coord:nth-child(2n), -.brown .orientation-white .ranks coord:nth-child(2n+1), -.brown .orientation-black .files coord:nth-child(2n+1), -.brown .orientation-black .ranks coord:nth-child(2n) { - color: #946f51; -} -.green .orientation-white .files coords:nth-child(2n+1), -.green .orientation-white .ranks coords:nth-child(2n), -.green .orientation-black .files coords:nth-child(2n), -.green .orientation-black .ranks coords:nth-child(2n+1) { - color: #FFFFDD; -} -.green .orientation-white .files coord:nth-child(2n), -.green .orientation-white .ranks coord:nth-child(2n+1), -.green .orientation-black .files coord:nth-child(2n+1), -.green .orientation-black .ranks coord:nth-child(2n) { - color: #6d8753; -} -.blue .orientation-white .files coords:nth-child(2n+1), -.blue .orientation-white .ranks coords:nth-child(2n), -.blue .orientation-black .files coords:nth-child(2n), -.blue .orientation-black .ranks coords:nth-child(2n+1) { - color: #DEE3E6; -} -.blue .orientation-white .files coord:nth-child(2n), -.blue .orientation-white .ranks coord:nth-child(2n+1), -.blue .orientation-black .files coord:nth-child(2n+1), -.blue .orientation-black .ranks coord:nth-child(2n) { - color: #788a94; -} - -/* negate inner coords colors */ -.is3d .cg-board-wrap coords coord { - color: #fff!important; - text-shadow: 0 1px 2px #000!important; -} -.is3d .cg-board-wrap coords.files { - bottom: calc(1px - 2.5%); -} -.is3d .cg-board-wrap coords.files coord { - padding-left: 3px; -} diff --git a/public/stylesheets/board.css b/public/stylesheets/board.css deleted file mode 100644 index c641b528c7..0000000000 --- a/public/stylesheets/board.css +++ /dev/null @@ -1,1161 +0,0 @@ -.cg-board-wrap { - position: relative; -} -.cg-512 .cg-board-wrap { - width: 512px; - height: 512px; - /* Fixes render artifacts after dropping a piece in firefox 47,48 */ - -moz-transform: translate3d(0, 0, 0); -} -.cg-board { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - line-height: 0; - background-size: cover; -} -.cg-board.bh1 piece { - opacity: 0.98; -} -.manipulable .cg-board { - cursor: pointer; -} -.is2d .cg-board { - top: 0; - height: 100%; -} -square { - position: absolute; - top: 0; - left: 0; - width: 12.5%; - height: 12.5%; - pointer-events: none; -} -.cg-board square.move-dest { - background: radial-gradient(rgba(20, 85, 30, 0.3) 17%, #208530 0, rgba(0, 0, 0, 0.3) 0, rgba(0, 0, 0, 0) 0); - cursor: pointer; - pointer-events: auto; -} -.cg-board square.oc.move-dest { - background: radial-gradient(transparent 0%, transparent 80%, rgba(20, 85, 0, 0.3) 80%); -} -.cg-board square.premove-dest { - background: radial-gradient(rgba(20, 30, 85, 0.2) 17%, #203085 0, rgba(0, 0, 0, 0.2) 0, rgba(0, 0, 0, 0) 0); - pointer-events: auto; -} -.cg-board square.oc.premove-dest { - background: radial-gradient(transparent 0%, transparent 80%, rgba(20, 30, 85, 0.2) 80%); -} -.cg-board square.move-dest:hover { - background: rgba(20, 85, 30, 0.3); -} -.cg-board square.premove-dest:hover { - background: rgba(20, 30, 85, 0.2); -} -.cg-board square.check { - background: radial-gradient(ellipse at center, rgba(255, 0, 0, 1) 0%, rgba(231, 0, 0, 1) 25%, rgba(169, 0, 0, 0) 89%, rgba(158, 0, 0, 0) 100%); -} -.cg-board square.selected { - background-color: rgba(20, 85, 30, 0.5); -} -.cg-board square.last-move, -.mini_board .cg-board square.last-move { - will-change: transform; - background-color: rgba(155, 199, 0, 0.41); -} -.cg-board square.current-premove { - background-color: rgba(20, 30, 85, 0.5); -} -.cg-board square.exploding1 { - background-color: rgba(255, 255, 255, 0.5); -} -.cg-board square.exploding2 { - background-color: rgba(255, 0, 0, 0.5); - transition: background-color 0.1s; -} -piece { - position: absolute; - width: 12.5%; - height: 12.5%; - top: 0; - left: 0; - background-size: cover; - z-index: 2; /* no less than 2 */ - pointer-events: none; -} -.cg-512 piece { - will-change: transform, opacity; - transition: opacity .1s; - transition-timing-function: linear; -} -.mini_board piece { - z-index: initial; -} -.blindfold .lichess_board piece, -.blindfold .other_games piece { - opacity: 0; -} -.blindfold .lichess_board square.check { - background: none; -} -piece.dragging { - z-index: 5; - cursor: move; -} -piece.anim { - z-index: 3; - cursor: move; -} -piece.ghost { - will-change: transform; - opacity: 0.3; -} -piece.fading { - z-index: 2!important; - opacity: 0.5; -} -.cg-board-wrap svg { - overflow: hidden; - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - pointer-events: none; - z-index: 4; - opacity: 0.6; -} -.cg-board-wrap svg image { - opacity: 0.5; -} - -.cg-board-wrap coords { - position: absolute; - display: flex; - pointer-events: none; - opacity: 0.8; -} -.cg-board-wrap coords.ranks { - right: -15px; - top: 0; - flex-flow: column-reverse; - height: 100%; - width: 12px; -} -.cg-board-wrap coords.ranks.black { - flex-flow: column; -} -.cg-board-wrap coords.files { - bottom: -15px; - left: 0; - flex-flow: row; - width: 100%; - height: 16px; - text-align: center; -} -.cg-board-wrap coords.files.black { - flex-flow: row-reverse; -} -.cg-board-wrap coords coord { - flex: 1 1 auto; -} -.cg-board-wrap coords.ranks coord { - transform: translateY(39%); -} - -/* lichess */ - -#lichess { - position: relative; - min-height: 512px; -} -div.lichess_game { - display: flex; - /* for safari: */ - height: 512px; -} -div.lichess_game div.lichess_board_wrap { - position: relative; -} -body.blind_mode .cg-board-wrap { - display: none; -} -div.lichess_game div.lichess_ground { - display: flex; - flex-flow: column nowrap; - justify-content: center; - padding-left: 15px; - width: 242px; -} -div.lichess_game div.lichess_ground.for_bot h1 { - font-size: 2em; -} -div.lichess_game div.lichess_ground.for_bot p { - margin: 1em 0; -} -div.lichess_board { - position: relative; -} -div.lichess_board > svg { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; -} -/* 2D boards */ - -.blue .is2d .cg-board { - background-image: url(../images/board/svg/blue.svg); -} -.blue2 .is2d .cg-board { - background-image: url(../images/board/blue2.jpg); -} -.wood2 .is2d .cg-board { - background-image: url(../images/board/wood2.jpg); -} -.wood3 .is2d .cg-board { - background-image: url(../images/board/wood3.jpg); -} -.blue3 .is2d .cg-board { - background-image: url(../images/board/blue3.jpg); -} -.marble .is2d .cg-board { - background-image: url(../images/board/marble.jpg); -} -.brown .is2d .cg-board { - background-image: url(../images/board/svg/brown.svg); -} -.green .is2d .cg-board { - background-image: url(../images/board/svg/green.svg); -} -.olive .is2d .cg-board { - background-image: url(../images/board/olive.jpg); -} -.purple .is2d .cg-board { - background-image: url(../images/board/svg/purple.svg); -} -.grey .is2d .cg-board { - background-image: url(../images/board/grey.jpg); -} -.wood .is2d .cg-board { - background-image: url(../images/board/wood-1024.jpg); -} -.canvas .is2d .cg-board { - background-image: url(../images/board/canvas2-1024.jpg); -} -.leather .is2d .cg-board { - background-image: url(../images/board/leather-1024.jpg); -} -.metal .is2d .cg-board { - background-image: url(../images/board/metal-1024.jpg); -} -.maple .is2d .cg-board { - background-image: url(../images/board/maple.jpg); -} - -.is2d .kingOfTheHill .cg-board::before { - width: 25%; - height: 25%; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.6); - content: ''; - position: absolute; - top: 37.5%; - left: 37.5%; -} - -/* Racing Kings board decorations */ - -.is2d .racingKings .cg-board-wrap.orientation-white::before { - width: 100%; - height: 12.5%; - box-shadow: inset 0 -2px 10px rgba(0, 0, 0, 0.5); - content: ''; - position: absolute; - top: 0; - left: 0; -} - -.is2d .racingKings .cg-board-wrap.orientation-black::before { - width: 100%; - height: 12.5%; - box-shadow: inset 0 2px 10px rgba(0, 0, 0, 0.5); - content: ''; - position: absolute; - bottom: 0; - left: 0; -} - -mono-piece { - width: 32px; - height: 32px; - background-size: cover; - display: inline-block; -} -mono-piece.pawn { - background-image: url(../piece/mono/P.svg); -} -mono-piece.bishop { - background-image: url(../piece/mono/B.svg); -} -mono-piece.knight { - background-image: url(../piece/mono/N.svg); -} -mono-piece.rook { - background-image: url(../piece/mono/R.svg); -} -mono-piece.queen { - background-image: url(../piece/mono/Q.svg); -} -mono-piece.king { - background-image: url(../piece/mono/K.svg); -} -div.lichess_overboard { - position: absolute; - z-index: 66; /* go over 3D pieces */ - width: 400px; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - padding: 15px 0 22px 0; - font-size: 14px; - line-height: 1.8em; - background: #fff; - box-shadow: 0 0 95px 25px rgba(0, 0, 0, 0.6); - text-align: center; - box-sizing: border-box; -} -div.lichess_overboard.padded { - padding: 15px; -} -#promotion_choice { - position: absolute; - top: 0; - left: 0; - box-sizing: border-box; - width: 100%; - height: 100%; - background: rgba(250, 250, 250, 0.7); - text-align: center; - z-index: 5; -} -#promotion_choice square { - cursor: pointer; - border-radius: 50%; - background-color: #b0b0b0; - box-shadow: inset 0 0 25px 3px #808080; - box-sizing: border-box; - transition: 0.2s; -} -#promotion_choice piece { - pointer-events: auto; -} -.is2d #promotion_choice piece { - width: 100%; - height: 100%; - transition: 0.2s; - transform: scale(0.8); -} -#promotion_choice square:hover { - box-shadow: inset 0 0 48px 8px #d85000; - border-radius: 0%; -} -.is2d #promotion_choice square:hover piece { - transform: none; -} -div.table_wrap { - flex: 0 1 auto; - width: 242px; - position: relative; -} -div.table { - border: 1px solid #ccc; - padding: 10px 0; -} -.lichess_ground .replay .moves { - border-top: 1px solid #e2e2e2; - border-bottom: 1px solid #e2e2e2; - height: 100px; - overflow: auto; - position: relative; - will-change: scroll-position; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - display: flex; - flex-flow: row wrap; - align-content: flex-start; -} -.lichess_ground .replay index, -.lichess_ground .replay move { - height: 25px; - line-height: 25px; -} -.lichess_ground .replay index { - display: flex; - flex: 0 0 15%; - max-width: 15%; /* required by IE 11 https://github.com/philipwalton/flexbugs/issues/3 */ - line-height: 27px; - background: #e6e6e6; - justify-content: center; - font-family: 'Roboto'; - font-weight: 300; -} -.lichess_ground .replay move { - flex: 0 0 42.5%; - max-width: 42.5%; /* required by IE 11 https://github.com/philipwalton/flexbugs/issues/3 */ - box-sizing: border-box; - font-family: 'ChessSansPiratf', sans-serif; - font-size: 17px; - line-height: 28px; - padding-left: 8px; -} -body.piece_letter .lichess_ground .replay move { - font-family: 'Noto Sans'; - font-size: 15px; - line-height: 25px; -} -.lichess_ground .replay move:not(.empty) { - cursor: pointer; -} -.lichess_ground .replay move:not(.empty):hover { - background: #e6e6e6; -} -.lichess_ground .replay move.active { - font-weight: bold; - background: rgba(56,147,232,0.1)!important; -} -.lichess_ground .result_wrap { - width: 100%; -} -.lichess_ground .result, -.lichess_ground .status { - text-align: center; -} -.lichess_ground .result { - border-top: 1px solid #ddd; - font-weight: bold; - font-size: 1.3em; - padding: 5px 0 3px 0; -} -.lichess_ground .status { - font-size: 1em; - font-style: italic; - padding-bottom: 7px; -} -.lichess_ground .replay .buttons { - border-top: 1px solid #e2e2e2; - font-size: 11px; - display: flex; - justify-content: space-between; -} -.lichess_ground .replay .fbt { - padding: 5px 10px; -} -.lichess_ground .replay .noop { - width: 30px; -} -.pocket { - border-radius: 3px; - box-shadow: 0 2px 3px rgba(0,0,0,0.3) inset; - width: 100%; - flex: 0 0 56px; - background: #888; - white-space: nowrap; - display: flex; -} -.pocket.top { - margin-bottom: 10px; -} -.pocket.bottom { - margin-top: 10px; -} -.pocket piece { - flex: 0 0 20%; - height: 56px!important; /* 100% fails on older chrome */ - width: auto!important; - position: relative!important; - background-position: center; -} -.pocket.usable piece:first-child:hover { - border-radius: 3px 0 0 3px; -} -.pocket.usable piece { - cursor: pointer; - pointer-events: auto; -} -.pocket.usable piece:hover { - background-color: #999; - transition: background-color 0.13s; -} -.pocket.usable piece.premove { - background-color: #555; -} -.pocket.usable piece.premove:hover { - background-color: #666; -} -.blindfold .pocket:not(.usable) { - opacity: 0; -} -.pocket piece[data-nb='0'] { - cursor: auto; - opacity: 0.1; -} -.pocket piece::after { - content: attr(data-nb); - bottom: 0; - right: 0; - position: absolute; - line-height: 14px; - padding: 3px 5px 4px 5px; - font-weight: bold; - border-radius: 2px; - font-size: 18px; -} -.pocket piece[data-nb='0']::after { - content: none; -} -div.table.spectator { - top: 160px; -} -div.table .ddloader { - margin: 20px auto 10px auto; -} -div.table .username { - white-space: nowrap; - display: flex; - margin: 0 3px; - font-size: 1.25em; -} -div.table .username:first-child { - margin-bottom: 6px; -} -div.table .username:last-child { - padding-top: 6px; -} -div.table .username a { - flex: 1 1 auto; - overflow: hidden; - text-overflow: ellipsis; -} -div.table .username.long a { - letter-spacing: -0.5px; -} -div.table .username rating { - flex: 0 0 auto; - margin: 0 0.25em 0 0.3em; - opacity: 0.6; - letter-spacing: -0.5px; -} -div.table .username .line { - display: flex; - justify-content: center; - align-items: center; -} -@keyframes connecting { - 0% { opacity: 0.1; } - 50% { opacity: 0.3; } - 100% { opacity: 0.1; } -} -div.table .connecting .line { - animation: connecting 0.9s ease-in-out infinite; -} -div.table .username .rp { - margin-right: 0.2em; -} -div.table .message { - margin: 20px 10px; -} -div.table .message::before { - font-size: 3em; - float: left; - margin-right: 10px; -} -div.table_wrap .whos_turn { - height: 2em; - line-height: 2em; - width: 100%; - text-align: center; - font-weight: bold; -} -div.table_wrap .clock { - position: relative; - display: flex; - justify-content: space-between; -} -div.table_wrap .clock .bar { - position: absolute; - width: 242px; - height: 4px; -} -div.table_wrap .clock_top .bar { - bottom: -4px; -} -div.table_wrap .clock_bottom .bar { - top: -4px; -} -div.table_wrap .clock .bar { - display: block; - height: 4px; - background: #759900; - transform-origin: left; -} -div.table_wrap .clock .bar.berserk { - background: #dc322f; -} -div.table_wrap.with_expiration .clock .bar { - display: none; -} -div.table_wrap .clock > .time { - border: 1px solid #ccc; - padding: 0 8px; - font-size: 38px; - font-family: 'Roboto Mono', 'Roboto'; - height: 44px; - line-height: 44px; - white-space: nowrap; - /* ensure updates don't redraw other parts of the document */ - will-change: transform; -} -div.table_wrap .correspondence.clock > .time { - font-size: 20px; -} -div.table_wrap .clock tenths { - font-size: 70%; -} -div.table_wrap .clock huns { - font-size: 80%; -} -div.table_wrap .clock sep { - opacity: 0.5; - font-size: 0.8em; - vertical-align: 4px; - margin-left: -1px; -} -div.table_wrap .clock tenths sep { - vertical-align: baseline; -} -div.table_wrap .clock sep.low { - opacity: 0.15; -} -div.table_wrap .clock.running .time { - background: #fff077; - color: #444; -} -div.table_wrap .clock.running.emerg .time { - background-color: #eFAAAA; - color: #444; -} -div.table_wrap .clock.outoftime .time { - background-color: #eFAAAA; - color: #444; -} -div.table_wrap .clock_top .time { - border-bottom: 0; - border-radius: 2px 2px 0 0; -} -div.table_wrap .clock_bottom .time { - border-top: 0; - border-radius: 0 0 2px 2px; -} -div.table_wrap .berserk.fbt { - font-size: 25px; - padding: 0 12px; -} -div.table_wrap .tournament_rank, -div.table_wrap a.moretime, -div.table_wrap div.berserk_alert { - flex: 0 1 auto; - display: flex; - align-items: center; - font-size: 20px; -} -div.table_wrap a.moretime { - opacity: 0.4; -} -div.table_wrap a.moretime:hover { - opacity: 1; -} - -div.table_wrap div.berserk_alert { - font-size: 34px; - color: #D85000; -} -div.control { - text-align: center; - width: 100%; -} -div.control.icons { - display: flex; - justify-content: center; -} -div.control.icons .fbt { - font-size: 18px; - padding: 8px 17px; -} -div.control.icons .takeback-yes span:before { - display: inline-block; - transform: translateY(1px); -} -div.control.icons .draw-yes span:before { - display: inline-block; - transform: translateY(-1px) rotate(-90deg); -} -div.control.icons .resign span:before { - display: inline-block; - transform: translateY(1px); -} -div.control.icons.confirm > button { - visibility: hidden; -} -div.control.icons .act_confirm { - visibility: visible; - position: relative; - width: 60px; -} -div.control.icons .act_confirm .no { - padding: 8px 0; - width: 30px; - text-align: center; - position: absolute; - top: 0; - right: -34px; -} - -div.control.icons .act_confirm .yes { - position: absolute; - right: 0; - top: -3px; - border-radius: 8px; - color: #FFF; - text-decoration: none; - background: #82BF56!important; - border-bottom: 5px solid #759900; - text-shadow: 0 -1px #759900; - transition: all 0.1s; - transform: translate(0px,0px); -} -div.control.icons .act_confirm .yes:hover { - filter: brightness(1.06); -} -div.control.icons .act_confirm .yes:active { - transform: translate(0px,5px); - border-bottom-width: 1px; - text-shadow: 0 0 #759900; - filter: brightness(1); -} - -div.control .button.disabled { - opacity: 0.5; - cursor: not-allowed; -} -.lichess_ground .suggestion, -.lichess_ground .pending, -.lichess_ground .negotiation { - padding: 8px 7px; - background: #d0d0d0; -} -.lichess_ground .suggestion p { - margin-bottom: 7px; -} -.lichess_ground .suggestion .button { - width: 100%; -} -.lichess_ground .expiration.emerg { - background: #dc322f!important; - color: #fff!important; -} -.lichess_ground .expiration { - display: flex; - justify-content: center; - align-items: center; -} -.lichess_ground .expiration strong { - font-size: 1.3em; - margin-right: .3em; -} -.lichess_ground .pending { - display: flex; - align-items: center; -} -.lichess_ground .pending p { - flex: 3 1; - margin-right: 7px; -} -.lichess_ground .pending .button { - flex: 1 1; -} -.lichess_ground .negotiation { - display: flex; - align-items: center; -} -.lichess_ground .negotiation p { - flex: 1 1 auto; - margin-right: 7px; -} -.lichess_ground .negotiation a { - flex: 0 0 50px; - height: 50px; - line-height: 44px; - font-size: 25px; - display: block; - background: #fff; -} -.lichess_ground .negotiation .accept { - color: #759900; - border-right: 1px solid #d0d0d0; - border-radius: 3px 0 0 3px; -} -.lichess_ground .negotiation .decline { - color: #dc322f; - border-radius: 0 3px 3px 0; -} -.lichess_ground .negotiation a:hover { - color: #fff; - background: #759900!important; -} -.lichess_ground .negotiation a.decline:hover { - background: #dc322f!important; -} -.lichess_ground .follow_up { - position: relative; -} -.lichess_ground .follow_up .button { - display: block; - width: 100%; - box-sizing: border-box; - border-radius: 0; - padding: 12px 0; - border-width: 1px 0 0 0; -} -.lichess_ground .follow_up > .button:first-child { - border-top-width: 0; -} -.lichess_ground .follow_up > .button:last-child { - border-bottom-width: 1px; -} -.variant_crazyhouse .lichess_ground .follow_up .button { - padding: 9px 0; -} -.lichess_ground .rematch.button { - padding: 0; - height: 56px; - font-size: 1.2em; - display: flex; - justify-content: center; - align-items: center; - text-transform: uppercase; - transition: height 0.5s ease; -} -.variant_crazyhouse .lichess_ground .rematch.button { - height: 60px; -} -.lichess_ground .rematch.me { - background: rgba(56,147,232,0.8); -} -@keyframes rubberBand { - from { transform: scale3d(1, 1, 1); } - 6% { transform: scale3d(1.25, 0.75, 1); } - 8% { transform: scale3d(0.75, 1.25, 1); } - 10% { transform: scale3d(1.15, 0.85, 1); } - 13% { transform: scale3d(.95, 1.05, 1); } - 15% { transform: scale3d(1.05, .95, 1); } - 20% { transform: scale3d(1, 1, 1); } -} -.lichess_ground .rematch.them { - background: none; - animation: fbt-glowing 1.5s ease-in-out infinite; -} -.lichess_ground .rematch.them span { - animation: rubberBand 5s infinite; -} -.lichess_ground .rematch.button:not(.disabled):hover { - background: rgba(56,147,232,0.8); - color: #fff!important; - animation: none; - text-shadow: none; -} -.lichess_ground .rematch-decline { - position: absolute; - top: 0; - right: -25px; - width: 25px; - height: 55px; - display: flex; - justify-content: center; - align-items: center; - border: 1px solid #ccc; - border-left: 0; - border-radius: 0 5px 5px 0; - box-sizing: border-box; - opacity: 0.7; - transition: 0.3s; -} -.lichess_ground .rematch-decline:hover { - background: #dc322f; - color: #fff; - right: -36px; - width: 35px; -} -.lichess_ground .follow_up .fbt.strong { - display: block; - padding: 2em 0; - font-size: 1.2em; -} -.lichess_ground .follow_up .weak { - font-weight: normal; - padding: 6px 0; -} -.lichess_ground .follow_up .weak::before { - opacity: 0.7; -} -div.cemetery { - flex: 0 0 32px; - line-height: 0; - white-space: nowrap; - line-height: 0; - height: 32px; - max-height: 32px; /* or else firefox bumps to 35px when adding */ -} -div.cemetery:first-child { - margin-bottom: 5px; -} -div.cemetery:last-child { - margin-top: 5px; -} -div.cemetery tomb { - display: inline-block; - margin-left: 10px; -} -div.cemetery mono-piece { - margin-left: -10px; -} -div.cemetery score { - font-family: 'Roboto'; - font-weight: 300; - font-size: 15px; - line-height: 35px; - vertical-align: top; -} -div.under_chat { - width: 228px; - margin: 10px 0 0 -30px; -} -@media (max-width: 1070px) { - div.under_chat { - margin-left: 0; - width: 198px; - } -} -div.under_chat .watchtv { - display: block; - height: 24px; - line-height: 24px; - text-align: center; - margin-top: -24px; -} -div.under_chat .watchers { - margin-top: 10px; - opacity: 0.65; - transition: 0.13s; - min-height: 5em; - max-height: 9em; - overflow: hidden; -} -div.under_chat .watchers.hidden { - visibility: hidden; -} -div.under_chat .watchers:hover { - opacity: 1; -} -div.game_tournament { - max-height: 300px; - overflow: hidden; -} -div.game_tournament .clock { - text-align: center; - font-size: 20px; - font-family: 'Roboto Mono', 'Roboto'; - margin: 10px 0; -} -div.tourStanding table { - border-bottom: none; -} -div.tourStanding:hover { - overflow-y: auto!important; -} -div.tourStanding td { - padding: 0 10px; - text-align: left; - line-height: 1.8em; - max-width: 150px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -div.tourStanding .slist td:first-child { - padding-left: 10px; -} -div.tourStanding .name span { - display: inline-block; - width: 20px; -} -div.tourStanding .name span::before { - font-size: 0.8em; - opacity: 0.4; -} -div.tourStanding .total { - font-weight: bold; - text-align: right; -} -span.inline_userlist { - display: inline; - color: #9a9a9a; -} -span.inline_userlist a { - color: #aaa; - font-weight: bold; -} -div.underboard { - display: flex; -} -div.underboard .center { - text-align: center; - padding-top: 15px; - width: 512px; - min-height: 81px; - display: flex; - flex-flow: column nowrap; -} -div.underboard .keyboard-move { - text-align: left; - order: -1; - margin-top: 5px; -} -div.underboard .keyboard-move input { - width: 35px; - padding: 4px 8px; - font-size: 1.2em; - font-weight: bold; - margin-right: 10px; - border: 1px solid #ccc; -} -div.underboard .keyboard-move input.wrong { - background: #dc322f; - color: #fff; -} -div.underboard .keyboard-move em { - opacity: 0.7; -} -div.underboard .blurs, -div.underboard .right { - padding-left: 15px; - width: 242px; -} -div.underboard .blurs { - position: relative; - padding-top: 25px; - z-index: 1; -} -div.underboard a { - display: inline-block; -} - -#now_playing.other_games { - width: 512px; -} -#now_playing .switcher { - font-size: 0.7em; - display: flex; - height: 1.5em; - line-height: 22px; -} -#now_playing .switcher label { - cursor: pointer; -} -#now_playing .switcher .switch { - margin-left: 10px; -} -#now_playing.other_games > a { - padding: 5px; -} -#now_playing h3 { - font-size: 1.4em; - flex: 0 0 100%; - display: flex; - justify-content: space-between; -} -#now_playing .simul span { - font-weight: bold; - margin: 0 .5em; -} -#now_playing .simul .win { - color: #759900; -} -#now_playing .simul .draw { - color: #bf811d; -} -#now_playing .simul .loss { - color: #ac524f; -} - -body.playing.zen .table { - padding: 0; -} -body.playing.zen .lichess_ground .replay .buttons { - border: none; -} -body.playing.zen .lichess_ground div.control { - margin-bottom: 8px; -} -body.playing.zen .under_chat, -body.playing.zen .table .moves, -body.playing.zen .table .username, -body.playing.zen rating, -body.playing.zen .tournament_rank, -body.playing.zen #friend_box, -body.playing.zen .board_left .side, -body.playing.zen #chat, -body.playing.zen .underboard .center .crosstable, -body.playing.zen #now_playing, -body.playing.zen .clock .moretime, -body.playing.zen #topmenu, -body.playing.zen #ham-plate, -body.playing.zen .dasher, -body.playing.zen .site_notifications, -body.playing.zen .challenge_notifications, -body.playing.zen .reports, -body.playing.zen #clinput, -body.playing.zen #site_title { - display: none; -} -body.playing.zen .table_wrap .replay .buttons { - opacity: 0!important; -} -body.playing.zen .table_wrap:hover .replay .buttons { - opacity: 1!important; -} -#zentog { - position: absolute; - top: 0; - left: 0; - padding: 10px 15px; - opacity: 0.5; - z-index: 3; - display: none; -} -body.playing.zen #zentog { - display: block; -} -#zentog::before { - font-size: 1.3em; -} -#zentog:hover { - opacity: 1; -} diff --git a/public/stylesheets/boardEditor.css b/public/stylesheets/boardEditor.css deleted file mode 100644 index a33564a82f..0000000000 --- a/public/stylesheets/boardEditor.css +++ /dev/null @@ -1,130 +0,0 @@ -#board_editor { - position: relative; - min-height: 600px; - padding-top: 5px; - -webkit-user-select: none; -} -#board_editor .manipulable .cg-board, #board_editor body.destination .cg-board square.move-dest { - cursor: inherit; -} -#board_editor square.last-move { - background-color: transparent; -} -#board_editor .spare { - height: 64px; - width: 512px; - border-radius: 3px; - box-sizing: border-box; - box-shadow: 0 2px 3px rgba(0,0,0,0.3) inset; -} -#board_editor .spare.black { - background: #888; -} -#board_editor .spare.white { - background: #ccc; -} -#board_editor .spare .selected-square { - background: #3893E8; -} -body.dark #board_editor .spare.white { - background: #aaa; -} -#board_editor .spare.top { - margin-bottom: 15px; -} -#board_editor .spare.bottom { - margin-top: 15px; -} -#board_editor .spare .no-square { - position: relative; - display:inline-block; - width: 64px; - height: 64px; -} -.is3d #board_editor .spare .no-square { - height: 58.102px; -} -#board_editor .spare piece { - cursor: pointer; - width: 100%; - height: 100%; -} -.is3d #board_editor .spare piece { - /* original size: - width: 140.625%; - height: 179.6875%; */ - /* size on 3D board, with height/width = 90.78571% */ - width: 100%; - height: 140.7465%; - left: 0; - top: -36%; -} -#board_editor .editor-side { - position: absolute; - left: 552px; - top: 150px; - width: 228px; -} -#board_editor .editor-side > div { - margin-bottom: 3em; - text-align: center; -} -#board_editor .button { - display: block; - width: 100%; - box-sizing: border-box; - text-align: left; - margin-bottom: 1em; -} -#board_editor .button.disabled { - opacity: 0.5; -} -#board_editor .editor-side select.positions { - width: 100%; -} -#board_editor .editor-side select.positions option:checked { - font-style: italic; -} -#board_editor .copyables > p { - margin-top: 7px; -} -#board_editor .copyables .name { - font-size: 1.2em; - display: inline-block; - width: 40px; -} -#board_editor .copyable { - width: 462px; -} -#board_editor .editor-side > div.metadata { - white-space: nowrap; -} -#board_editor .editor-side > div.metadata div.color { - margin-bottom: 1em; -} -#board_editor .editor-side .castling label, -#board_editor .editor-side .castling input { - display:inline-block; - margin: 3px; - vertical-align: middle; -} -/* -http://www.flaticon.com/free-icon/clicker_99162 -*/ -#board_editor .spare piece.pointer { - background-image: url('/assets/images/icons/pointer.png'); - width: 100%; - height: 100%; -} -#board_editor .spare piece.trash { - font-size: 32pt; - top: 0; - height: 100%; -} -#board_editor .spare .no-square.trash { - color: black; - text-align: center -} -.is3d #board_editor .spare piece.pointer, .is3d #board_editor .spare piece.trash { - top: -15%; -} diff --git a/public/stylesheets/challenge.css b/public/stylesheets/challenge.css deleted file mode 100644 index 91fba74b86..0000000000 --- a/public/stylesheets/challenge.css +++ /dev/null @@ -1,19 +0,0 @@ -#lichess_id_input { - margin-top: 10px; - width: 80%; - text-align: center; - font-size: 1.2em; - padding: 1em 0; -} -#ping_challenge .spinner { - width: 80px; - height: 80px; - margin-bottom: 20px; -} -.user-invite .friend-autocomplete { - border: 1px solid #ccc; - padding: 5px 8px; -} -body.dark .user-invite .friend-autocomplete { - border-color: #3d3d3d; -} diff --git a/public/stylesheets/challengeApp.css b/public/stylesheets/challengeApp.css deleted file mode 100644 index 520abc8157..0000000000 --- a/public/stylesheets/challengeApp.css +++ /dev/null @@ -1,143 +0,0 @@ -#challenge_app { - width: 250px; - z-index: 2; - left: -106px; - text-align: center; -} -#challenge_app.rendered { - background: transparent!important; - box-shadow: none!important; - border: 0!important; -} -#challenge_app .challenge { - padding: 10px 10px; - margin-bottom: 5px; - position: relative; - height: 36px; - transition: 0.13s; - background: #fff; - box-shadow: 0 1px 7px rgba(0, 0, 0, 0.3); -} -#challenge_app .challenge:hover { - height: 76px; - box-shadow: 0 1px 13px rgba(0, 0, 0, 0.7); -} -#challenge_app .challenge.declined { - height: 0; - padding: 0; - opacity: 0; -} -#challenge_app .challenge .buttons { - position: absolute; - opacity: 0; - top: 54px; - left: 0px; - width: 100%; - transition: 0.13s; -} -#challenge_app .challenge:hover .buttons { - opacity: 1; -} -#challenge_app .challenge .buttons > * { - position: absolute; - top: 0; - left: 0; - width: 50%; -} -#challenge_app .challenge .buttons > *:last-child { - left: 50%; -} -#challenge_app .challenge button { - cursor: pointer; - color: #759900; - width: 100%; - display: block; - padding: 0; - background: transparent; - font-size: 18px; - border-radius: 0; - transition: 0.13s; - border-width: 1px 1px 0 0; -} -#challenge_app .challenge button, -#challenge_app .challenge .owner { - height: 42px; - box-sizing: border-box; -} -#challenge_app .challenge .owner { - border: 1px solid #e2e2e2; - border-width: 1px 1px 0 0; - vertical-align: center; - line-height: 42px; -} -#challenge_app .challenge .owner .view, -#challenge_app .challenge .owner:hover .waiting { - display: none; -} -#challenge_app .challenge .owner:hover .view { - display: block; -} -#challenge_app .challenge button::before { - line-height: 42px; -} -#challenge_app .challenge button.decline { - color: #dc322f; - border-right: none; -} -#challenge_app .challenge button:hover { - background: #759900; - color: #fff; -} -#challenge_app .challenge button.decline:hover { - background: #dc322f; -} -#challenge_app .challenge:last-child { - border-bottom: none; -} -#challenge_app .challenge > i { - position: absolute; - top: 6px; - right: 10px; - display: block; - font-size: 28px; -} -#challenge_app .challenge .content { - position: absolute; - top: 10px; - left: 12px; - display: block; - width: 196px; - text-align: left; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -#challenge_app .challenge .head { - display: block; - font-weight: bold; - margin-bottom: 3px; -} -#challenge_app .challenge .head .user_link { - margin-left: -5px; -} - -#challenge_app .create { - display: inline-block; - padding: 0 28px 3px 28px; - margin: auto; - background: rgba(56,147,232,0.5); - color: rgba(255,255,255,0.6); - transition: 0.13s; - border-radius: 0 0 3px 3px; -} -#challenge_app .create:hover { - background: rgba(56,147,232,0.9); - color: rgba(255,255,255,0.6); - padding-top: 4px; -} - -#challenge_app .empty { - padding: 20px 0; - background: #fff; - box-shadow: 0 1px 7px rgba(0, 0, 0, 0.3); -} diff --git a/public/stylesheets/chat.css b/public/stylesheets/chat.css deleted file mode 100644 index 8972e71d6a..0000000000 --- a/public/stylesheets/chat.css +++ /dev/null @@ -1,159 +0,0 @@ -div.mchat { - height: 100%; - display: flex; - flex-flow: column nowrap; -} -body.kid div.mchat { - display: none; -} -div.mchat .spinner { - padding-top: 100px; -} -div.mchat .chat_tabs { - flex: 0 0 auto; - display: flex; -} -div.mchat .chat_tabs .tab { - flex: 1 1 auto; - border: 1px solid #ccc; - border-width: 0 1px 1px 0; - text-align: center; - white-space: nowrap; - overflow: hidden; - padding: 4px 8px 5px 8px; -} -div.mchat .chat_tabs .tab:not(.active) { - background: #e0e0e0; - opacity: 0.7; - cursor: pointer; -} -div.mchat .chat_tabs .tab:not(.active):hover { - opacity: 1; -} -div.mchat .chat_tabs .tab.active h2 { - font-weight: bold; -} -div.mchat .chat_tabs .tab input { - cursor: pointer; -} -div.mchat.optional .chat_tabs .tab.discussion { - display: flex; - justify-content: space-between; - align-items: center; -} -div.mchat .chat_tabs .tab span { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -div.mchat .chat_tabs .tab:last-child { - border-right: none; -} -div.mchat .chat_tabs:not(.nb_1) .tab.active { - border-bottom-color: transparent!important; -} -div.mchat .content { - flex: 1 1 auto; - display: flex; - flex-flow: column nowrap; - overflow: hidden; -} -div.mchat .note textarea { - flex-grow: 1; - padding: 8px; - box-sizing: border-box; - border: none; - background-color: transparent; - color: #707070; - line-height: 1.7em; - outline: none; - resize: none; -} -div.mchat .lichess_say { - border: 0; - border-top: 1px solid #ccc; - padding: 3px 20px 3px 4px; - flex: 0 0 auto; - outline: none; -} -div.mchat .lichess_say.whisper { - color: #759900; - font-weight: bold; - font-style: italic; -} -div.mchat .messages { - display: block; - height: 100%; - overflow: hidden; - overflow-y: auto; - word-wrap: break-word; - padding-bottom: 2px; - cursor: initial; -} -div.mchat .messages li { - padding: 0.4em 0 0.4em 5px; - line-height: 14px; - margin: 0; - overflow-y: hidden; -} -body.no-select div.mchat .messages li { - -moz-user-select: text; - -webkit-user-select: text; -} -div.mchat .messages .deleted { - opacity: 0.5; -} -div.mchat .messages .system { - display: block; - opacity: 0.8; - font-style: italic; - font-size: 0.8em; - margin-left: 0; - text-align: center; -} -div.mchat .messages .color, -div.mchat .messages .user_link { - font-weight: bold; - padding: 0; - color: #888; - word-spacing: 0.3em; - letter-spacing: -1px; -} -body.dark div.mchat .messages .color, -body.dark div.mchat .messages .user_link { - color: #777; -} -div.mchat .messages .title { - margin-right: 3px; -} -div.mchat .messages a:not(.user_link) { - font-family: 'Roboto'; - color: #3893E8; -} -div.mchat .presets { - display: flex; - flex: 0 0 auto; - align-items: center; - flex-flow: row nowrap; -} -div.mchat .presets span { - flex: 1 1 auto; - text-align: center; - display: block; - opacity: 0.7; - border-top: 1px solid #ccc; - border-right: 1px solid #ccc; - font-size: 11px; - text-transform: uppercase; -} -div.mchat .presets span:not(.disabled) { - cursor: pointer; -} -div.mchat .presets span.disabled { - color: transparent; -} -div.mchat .presets span:not(.disabled):hover { - background: #3893E8; - color: #fff; - opacity: 1; -} diff --git a/public/stylesheets/chat.mod.css b/public/stylesheets/chat.mod.css deleted file mode 100644 index 4c0c1d0fe3..0000000000 --- a/public/stylesheets/chat.mod.css +++ /dev/null @@ -1,98 +0,0 @@ -div.mchat.mod div.top { - display: flex; - justify-content: space-between; - align-items: center; -} -div.mchat.mod div.top .toggle_chat { - cursor: pointer; -} -div.mchat.mod li { - position: relative; -} -div.mchat.mod i.mod { - display: none; - position: absolute; - top: 1px; - right: 0; - cursor: pointer; - margin-right: 3px; - padding: 4px 5px; - opacity: 0.5; -} -div.mchat.mod li:hover { - background: rgba(255,255,255,0.6); -} -body.dark div.mchat.mod li:hover { - background: rgba(255,255,255,0.05); -} -div.mchat.mod li:hover i.mod { - display: block; - text-shadow: 0 0 2px #fff, 0 0 5px #fff, 0 0 10px #fff; -} -div.mchat.mod i.mod:hover { - opacity: 1; -} -body.dark div.mchat.mod li i.mod { - text-shadow: 0 0 2px #000, 0 0 5px #000, 0 0 10px #000; -} - -div.mchat.mod .moderation { - overflow: auto; -} - -div.mchat.mod .block { - padding: 0 10px 10px 10px; -} -div.mchat.mod .moderation h2 { - text-transform: uppercase; - letter-spacing: 1px; - margin: 5px 0 10px 0; -} -div.mchat.mod .history table { - width: 100%; -} -div.mchat.mod .history .reason { - font-weight: bold; - text-transform: capitalize; -} -div.mchat.mod .history .mod, -div.mchat.mod .history time { - opacity: 0.8; -} -div.mchat.mod .infos { - padding-top: 10px; -} -div.mchat.mod .infos a { - color: #3893E8; -} -div.mchat.mod .infos > * { - display: inline-block; - margin-right: 5px; -} -div.mchat.mod .timeout a { - display: block; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - color: #3893E8; - padding: 2px 0; - transition: 0.3s; - margin-left: -10px; -} -div.mchat.mod .timeout a::before { - opacity: 0; - transition: 0.3s; -} -div.mchat.mod .timeout a:hover { - margin-left: 0; -} -div.mchat.mod .timeout a:hover::before { - opacity: 1; - margin-right: 2px; -} -div.mchat.mod .shadowban { - margin-top: 10px; -} -div.mchat.mod .shadowban form { - display: inline; -} diff --git a/public/stylesheets/cli.css b/public/stylesheets/cli.css deleted file mode 100644 index 4b2832e735..0000000000 --- a/public/stylesheets/cli.css +++ /dev/null @@ -1,4 +0,0 @@ -#clinput .tt-menu .empty, -#clinput .tt-menu .spinner { - display: none; -} diff --git a/public/stylesheets/coach.css b/public/stylesheets/coach.css deleted file mode 100644 index 6eced7f0ff..0000000000 --- a/public/stylesheets/coach.css +++ /dev/null @@ -1,237 +0,0 @@ -.coach a { - color: #3893E8!important; -} -.coach .top { - /* background: #303F9F; */ - background: #639B24; - color: #fff; - display: flex; -} -.coach .top a { - color: #fff!important; -} -.coach .top a:hover { - color: #fff!important; - border-bottom: 1px dotted #fff; -} -.coach .top img.picture { - flex: 0 0 250px; - background: #888; -} -.coach .top .overview { - padding: 15px 25px; - box-sizing: border-box; - height: 250px; - max-height: 250px; -} -.coach .top h1 { - font-family: 'Roboto'; - font-size: 33px; - text-transform: uppercase; - letter-spacing: 3px; - padding: 6px 0 9px 0!important; - text-shadow: none!important; - white-space: nowrap; -} -.coach .top h1.large { - letter-spacing: 2px; - font-size: 30px; -} -.coach .top .headline { - font-family: 'PT Serif', 'Noto Sans', 'Lucida Grande'; - font-size: 16px; - padding: 0 0 20px 0!important; -} -.coach .top .headline.medium { - font-size: 14px; - padding-bottom: 15px!important; -} -.coach .top .headline.large { - font-size: 13.5px; - padding-bottom: 10px!important; -} -.coach .top table { - line-height: 1.7; -} -.coach .top table th { - opacity: 0.7; - padding-right: 20px; - text-align: right; -} -.coach .top .rating td a > span { - margin-left: 4px; - display: inline-block; -} - -.coach .sections { - margin-top: 20px; - display: flex; - flex-flow: row wrap; - justify-content: space-between; -} - -.coach .sections section { - font-size: 1.2em; - box-sizing: border-box; - width: 50%; - padding: 20px 40px 20px 20px; - text-align: justify; -} -.coach .sections section:nth-child(odd) { - padding: 20px 20px 20px 40px; -} -.coach section h1 { - padding: 0 0 12px 0!important; - color: #639B24; -} -.coach section .content { - overflow: hidden; - text-overflow: ellipsis; -} - -.coach .youtube { - background: #222; - margin-top: 20px; - padding-bottom: 20px; -} -.coach .youtube h1 { - padding: 20px 40px!important; - color: #ccc; -} -.coach .youtube .list { - display: flex; - flex-flow: row wrap; - justify-content: space-between; -} -.coach .youtube .list iframe { - margin-bottom: 10px; - width: 256px; - height: 192px; - background: #000; -} -.coach .studies { - margin-top: 20px; -} -.coach .studies h1 { - color: #777; - padding: 20px 30px!important; -} -body.dark .coach .studies h1 { - color: #aaa; -} - -.review-form { - text-align: center; -} -.review-form .toggle { - box-sizing: border-box; -} -.review-form form { - display: none; -} -.review-form textarea { - width: 100%; - height: 14em; - padding: 5px; - box-sizing: border-box; - resize: vertical; -} -.review-form .button { - display: block; - width: 100%; - margin-top: 5px; -} -.reviews { - margin: 20px 0; -} -.reviews h2 { - font-size: 1.5em; - margin-bottom: -10px; - font-family: Roboto; -} -.reviews .review { - margin-top: 15px; - border-top: 1px solid #dadada; - padding-top: 15px; -} -.reviews .top { - display: flex; - justify-content: space-between; - width: 100%; - margin-bottom: 5px; -} -.reviews .top .user_link { - margin-left: -4px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.reviews .content { - font-style: italic; - opacity: 0.8; - max-height: 10em; - overflow: hidden; - text-overflow: ellipsis; - transition: 0.3s; -} -.reviews .review:hover .content { - max-height: 50em; - opacity: 1; -} -.reviews .br-wrapper { - flex: 0 0; -} - -.coach-side { - margin: 50px 0 0 -35px; - width: 226px; -} -@media (max-width: 1084px) { - .coach-side { - margin-left: 0!important; - width: 196px!important; - } -} -.coach-side .profile { - text-align: right; - margin-bottom: 1em; -} - -/* review score */ -.br-widget { - white-space: nowrap; -} -.br-widget a { - font: 25px "lichess"; - text-rendering: auto; - -webkit-font-smoothing: antialiased; - text-decoration: none; - margin-right: 2px; - display: inline-block; -} -.br-widget a:after { - content: 't'; - color: #ccc; -} -body.dark .br-widget a:after { - color: #555; -} -.br-widget a.br-active:after, -.br-widget a.br-selected:after { - color: #d59120!important; -} -.br-widget .br-current-rating { - display: none; -} -.br-readonly a { - font-size: 10px; - margin-right: 0; - cursor: default; -} -.br-readonly a.br-selected:after { - margin-right: 0; - color: #888!important; -} -body.dark .reviews .review { - border-color: #3d3d3d; -} diff --git a/public/stylesheets/coach.form.css b/public/stylesheets/coach.form.css deleted file mode 100644 index 13a184f929..0000000000 --- a/public/stylesheets/coach.form.css +++ /dev/null @@ -1,219 +0,0 @@ -.coach_edit .top { - display: flex; - line-height: 2; -} -.coach_edit .top h1 { - margin: 0; - padding: 0!important; - font-family: 'Roboto'; - font-size: 32px; - text-transform: uppercase; - letter-spacing: 4px; -} - -.coach_edit .top .picture_wrap { - margin-right: 30px; - width: 250px; - height: 250px; -} -.coach_picture .picture_wrap { - text-align: center; -} - -.coach_edit .top .upload_picture { - text-align: center; - margin-top: 80px; -} - -.coach_edit .overview { - width: 100%; - height: 250px; - display: flex; - flex-flow: column; -} - -.coach_edit .overview .todo, -.coach_edit .overview.with_todo .analytics { - display: none; -} -.coach_edit .overview.with_todo .todo { - display: block; -} -.coach_edit .overview .todo h3 { - margin: 0; - color: #dc3545; - font-weight: bold; -} -.coach_edit .overview .todo li { - list-style: disc inside; -} - -.coach_edit .top a, -body.dark .coach_edit .top a { - color: #3893E8; -} - -.coach_edit .material.form { - margin-top: 0; -} -.coach_edit .material.form .form-group textarea { - height: 12em; -} - -.coach_picture form { - padding: 30px; - border-top: 1px solid #ccc; - text-align: center; -} -.coach_picture form.delete button { - color: red; -} -.coach_picture .cancel { - padding: 40px; - border-top: 1px solid #ccc; -} -.coach_picture .forms > *:first-child { - margin-top: 40px; -} - -.coach_edit .tabs { - display: flex; - cursor: pointer; - margin-bottom: 40px; - text-transform: uppercase; -} -.coach_edit .tabs > div { - flex: 1 1 100%; - padding: 10px 0; - text-align: center; - position: relative; -} -.coach_edit .tabs > div.data-count::after { - padding: 2px 6px; - font-size: 1.2em; - height: auto; - line-height: 1.2em; - top: 6px; -} -.coach_edit .tabs > div:hover { - color: #3893E8; -} -.coach_edit .tabs > .active { - color: #3893E8; - border-bottom: 3px solid #3893E8; -} -.coach_edit .panel { - display: none; -} -.coach_edit .panel.active { - display: block; -} - -.coach_edit .status { - opacity: 0; - transition: 0.5s; - text-align: center; - color: #759900; -} -.coach_edit .status.saved { - opacity: 1; -} -.coach_edit .reviews .help { - margin: -30px 0 20px 0; - text-align: center; -} -.coach_edit .reviews .review { - display: flex; - align-items: center; - justify-content: space-between; - padding-top: 40px; - border-top: 1px solid #ccc; - margin-top: 40px; -} -body.dark .coach_edit .reviews .review, -body.dark .coach_picture form, -body.dark .coach_picture .cancel { - border-color: #3d3d3d; -} -.coach_edit .reviews .user > * { - display: block; -} -.coach_edit .reviews .modded { - background: #dc322f; - color: #fff; - padding: 8px 10px; - margin-bottom: 1em; -} -.coach_edit .reviews .content { - margin: 0 20px; - box-sizing: border-box; - word-break: break-word; -} -.coach_edit .reviews .actions { - font-size: 30px; - display: flex; - align-items: center; - text-align: center; -} -.coach_edit .reviews .actions a { - flex: 0 0 50px; - width: 50px; - height: 50px; - line-height: 44px; - font-size: 25px; - background: #f0f0f0; - border: 1px solid #d0d0d0; -} -body.dark .coach_edit .reviews .actions a { - background: #363636; - border-color: #3d3d3d; -} -.coach_edit .reviews .actions .yes { - color: #759900; - border-radius: 3px 0 0 3px; -} -.coach_edit .reviews .actions .no { - color: #dc322f; - border-radius: 0 3px 3px 0; - border-left: 0; -} -.coach_edit .reviews .actions a:hover { - color: #fff; - background: #759900!important; -} -.coach_edit .reviews .actions a.no:hover { - background: #dc322f!important; -} - -#site_header a.preview { - display: block; - margin-top: 40px; - text-align: center; -} - -/* review score */ -.br-widget { - white-space: nowrap; - margin: 8px 0 5px 0; -} -.br-widget a { - font: 18px "lichess"; - text-rendering: auto; - -webkit-font-smoothing: antialiased; - text-decoration: none; - margin-right: 2px; - cursor: default; -} -.br-widget a:after { - content: 't'; - color: #d2d2d2; -} -body.dark .br-widget a:after { - color: #555; -} -.br-widget a.br-selected:after { - color: #d59120!important; -} -.br-widget .br-current-rating { - display: none; -} diff --git a/public/stylesheets/coach.list.css b/public/stylesheets/coach.list.css deleted file mode 100644 index 5e2026fee3..0000000000 --- a/public/stylesheets/coach.list.css +++ /dev/null @@ -1,137 +0,0 @@ -.coaches > .top { - display: flex; - align-items: center; -} -.coaches > .top h1 { - flex: 1 1 100%; -} -.coaches > .top .orders { - white-space: nowrap; - margin-right: 20px; -} -.coach-side { - margin: 50px 40px 0 -35px; - width: 226px; - text-align: center; -} - -.coaches .coach { - border-top: 1px solid #ccc; - position: relative; - display: flex; -} -.coaches .coach:hover { - background: rgba(191, 231, 255, 0.5); -} -.coaches .coach a.overlay { - position: absolute; - z-index: 2; - top: 0; - left: 0; - width: 100%; - height: 100%; -} -.coaches .coach img.picture { - flex: 0 0 250px; - background: #888; -} -.coaches .overview { - margin: 20px 10px 0 20px; -} -.coaches .coach h1 { - font-family: 'Roboto'; - font-size: 32px; - text-transform: uppercase; - letter-spacing: 3px; - padding: 0 0 11px 0!important; - text-shadow: none!important; -} -.coaches .coach .headline { - font-family: 'PT Serif', 'Noto Sans', 'Lucida Grande'; - font-size: 17px; - padding: 0 0 20px 0!important; -} -.coaches .coach .headline.medium { - font-size: 15px; - padding-bottom: 18px!important; -} -.coaches .coach .headline.large { - font-size: 14px; - padding-bottom: 14px!important; -} -.coaches .coach table { - line-height: 1.7; -} -.coaches .coach table th { - opacity: 0.7; - padding-right: 20px; - text-align: right; -} -.coaches .coach table .seen { - opacity: 0.7; -} -.coaches .coach .rating td a > span { - margin-left: 4px; - display: inline-block; -} -@media (max-width: 1084px) { - .coach-side { - margin-left: 0!important; - width: 196px!important; - } - .coach-intro h2 { - font-size: 1.75em; - } -} -body.dark .coaches .coach { - border-color: #3d3d3d; -} - -.mselect { - display:inline-block; - position: relative; - padding:0; - border:0; -} -.mselect .button { - padding-right: 22px; - position: relative; - display: inline-block; -} -.mselect .button i { - font-size: 10px; - position: absolute; - right: 5px; - top: 7px; -} -.mselect .list { - margin:0; - padding:0; - position:absolute; - z-index: 3; - top:0; - text-align: left; - list-style-type:none; - font-weight: normal; - background: #fff; - box-shadow: 0px 8px 17px 0px rgba(0, 0, 0, 0.2), 0px 6px 20px 0px rgba(0, 0, 0, 0.19); - border-radius: 3px; - display: none; -} -.mselect.shown .list { - display: block; -} -.mselect .list a { - display: block; - padding: 10px; - background:#fff; - transition: 0.13s; - outline:0; - text-decoration:none; - cursor:pointer; -} -.mselect .list a:hover{ - background: #3893E8; - color: #fff; -} - diff --git a/public/stylesheets/common.css b/public/stylesheets/common.css deleted file mode 100644 index 27045b67be..0000000000 --- a/public/stylesheets/common.css +++ /dev/null @@ -1,1912 +0,0 @@ -body, -ul, -ol, -li, -h1, -h2, -form, -legend, -input, -textarea, -p, -th, -td { - margin: 0; - padding: 0; -} -table { - border-collapse: collapse; - border-spacing: 0; -} -img { - border: 0; -} -em, -strong, -th { - font-style: normal; - font-weight: normal; -} -li { - list-style: none; -} -th { - text-align: left; -} -h1, -h2, -h3 { - font-size: 100%; - font-weight: normal; -} -input, -textarea, -select, -button { - font-family: inherit; - font-size: inherit; - font-weight: inherit; -} -time { - display: inline-block; - white-space: nowrap; -} -@font-face { - font-family: "lichess"; - src: url("/assets/font82/fonts/lichess.eot"); - src: url("/assets/font82/fonts/lichess.eot?#iefix") format("embedded-opentype"), url("/assets/font82/fonts/lichess.woff") format("woff"), url("/assets/font82/fonts/lichess.ttf") format("truetype"); - font-display: block; - font-weight: normal; - font-style: normal; -} -@font-face { - font-family: 'PT Serif'; - font-style: italic; - font-weight: 400; - src: local('PT Serif Italic'), local('PTSerif-Italic'), url(https://fonts.gstatic.com/s/ptserif/v8/03aPdn7fFF3H6ngCgAlQzPk_vArhqVIZ0nv9q090hN8.woff2) format('woff2'); - unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; -} -.is::before, -[data-icon]::before, -.user_link .line, -.is-after::after { - font-size: 1.2em; - vertical-align: middle; - font-family: "lichess" !important; - font-style: normal !important; - font-weight: normal !important; - text-transform: none !important; - speak: none; - line-height: 1; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - content: attr(data-icon); -} -.is.text::before, -.text[data-icon]::before { - margin-right: 0.27em; -} -[data-icon].is2::before { - font-size: 20px; -} -[data-icon].is3::before { - font-size: 22px; -} -[data-icon].is4::before { - font-size: 30px; -} -.is4.text::before { - margin-right: 10px; -} -.user_link.online .line, -.is-green::before { - color: #759900; -} -.is-red::before { - color: #dc322f; -} -.is-gold::before { - color: #d59120; -} -a.blue { - color: #3893E8!important; -} -.user_link .line { - opacity: 0.4; - display: inline-block; - width: 1.5em; - text-align: center; - vertical-align: -0.15em; -} -.user_link.online .line, -.user_link .line.patron { - opacity: 0.8; -} -.user_link.online .line.patron { - opacity: 1; -} -.user_link .line::before { - content: ''; -} -.user_link .line.patron::before { - content: ''; -} -.user_link .line.moderator::before { - content: ''; -} - -body.blind_mode .is::before, -body.blind_mode .is::after, -body.blind_mode [data-icon]::before { - content: none; - display: none; - visibility: hidden; -} -body.blind_mode #blind_mode { - text-align: center; - padding: 5px 0; - background: #888; - margin-left: 0; - height: auto; -} -.color-icon.white::before { - content: "K"; -} -.color-icon.black::before { - content: "J"; -} -.color-icon.random::before { - content: "l"; -} -@font-face { - font-family: 'ChessSansPiratf'; - src: url("../fonts/ChessSansPiratf.eot"); - src: url("../fonts/ChessSansPiratf.eot?#iefix") format("embedded-opentype"), url("../fonts/ChessSansPiratf.woff") format("woff"), url("../fonts/ChessSansPiratf.ttf") format("truetype"), url("../fonts/ChessSansPiratf.svg#lichess") format("svg"); -} -.thin { - font-family: 'Roboto'; -} -#blind_mode { - margin-left: -99999px; - height: 0; -} -group.radio { - display: flex; - border-radius: 3px; - overflow: hidden; - border: 1px solid #ccc; -} -group.radio div { - flex: 1 1 auto; - position: relative; -} -group.radio input { - position:absolute; - left: -99999px; -} -group.radio label { - box-sizing: border-box; - padding: 10px; - height: 100%; - background: #fff; - display: flex; - align-items: center; - justify-content: center; - cursor:pointer; - border-right: 1px solid #ccc; - transition: background 0.13s; - -moz-user-select: none; - -webkit-user-select: none; -} -group.radio div:last-child label { - border-right: 0; -} -group.radio input:checked + label { - background: #d81b60; - font-weight: 500; - color: #fff; -} -#infscr-loading .spinner { - margin: 10px auto; -} -@keyframes spinnerRotate { - 100% { transform: rotate(360deg); } -} -@keyframes spinnerDash { - 0%,10% { stroke-dasharray: 1,270; stroke-dashoffset: 0 } - 40% { stroke-dasharray: 89,240; stroke-dashoffset: 0 } - 100% { stroke-dasharray: 1,240; stroke-dashoffset: -110 } -} -@keyframes spinnerColor { - 0%,20%,100% { stroke: #42a5f5 } - 30%,45% { stroke: #f44336 } - 50%,70% { stroke: #fdd835 } - 75%,95% { stroke: #4caf50 } -} -.inf-more { - width: 100%; -} -.spinner { - width: 40px; - height: 40px; - margin: auto; -} -.spinner svg { - animation: spinnerRotate 1.5s linear infinite; -} -.spinner circle { - stroke: #42a5f5; - stroke-width: 4; - animation: spinnerDash 1.275s ease-in-out infinite, spinnerColor 5.1s linear infinite; -} -.white .spinner circle { - animation: spinnerDash 1.275s ease-in-out infinite; - stroke: #fff; -} -/* duckduckgo small horizontal loader */ -@keyframes ddloader { - 0% { background-position: left } - 100% { background-position: right } -} -.ddloader { - background: url(../images/loader/blackx1.png) no-repeat; - animation: ddloader 0.5s steps(15) infinite; - vertical-align: middle; - display: inline-block; - width: 32px; - height: 8px; -} - -#powerTip, -#miniGame { - width: 224px; - min-height: 3em; - cursor: default; - background-color: #fff; - border: 1px solid #c0c0c0; - display: none; - position: absolute; - z-index: 900000; - box-shadow: 0 0.5px 5px rgba(0, 0, 0, 0.25), 0 0.5px 8px rgba(0, 0, 0, 0.15); -} -#miniGame { - min-height: 262px; -} -#powerTip signal { - float: right; - margin-right: 2px; -} -#powerTip > .title { - height: 62px; - padding: 5px 3px; - border-bottom: 1px solid #c0c0c0; -} -#powerTip > .title a.user_link { - display: block; - overflow: hidden; - text-overflow: ellipsis; -} -#powerTip a.mini_board { - border-width: 0 0 1px 0; -} -#powerTip .mod_info_box { - position: relative; - padding: 5px; - background: #888; - color: #eee; - white-space: nowrap; -} -#powerTip .mod_marks { - position: absolute; - top: 0; - right: 0; - padding: 3px 5px; - background: #dc322f; -} -#powerTip .mod_marks i { - padding: 0px; -} -#powerTip .country { - float: right; - font-size: 0.9em; - padding-right: 3px; -} -#powerTip .ratings { - text-align: center; - margin-top: 3px; -} -#powerTip .ratings > span { - padding: 2px 3px; - width: 20%; - text-align: left; -} -#powerTip > .actions { - width: 100%; - display: flex; -} -#powerTip > .actions a { - flex: 0 0 auto; - margin: 0; - border-radius: 0; - font-size: 0.9em; - letter-spacing: -1px; - text-align: center; - padding: 0 12px; - height: 30px; - line-height: 30px; - cursor: pointer; - border-width: 0 1px 0 0; -} -#powerTip > .actions a.relation { - flex: 1 1 100%; - border-right: 0; -} -#powerTip > .actions i { - font-style: normal; -} -#powerTip > .actions i::before { - font-size: 1.5em; -} -#powerTip .confirm { - margin-top: 10px; - width: 100%; - text-align: center; -} -#powerTip > .game_legend { - text-align: center; - border-bottom: 1px solid #c0c0c0; - padding: 3px 0; -} -#powerTip > .score { - display: block; - font-size: 1.2em; - text-align: center; - border-top: 1px solid #c0c0c0; - padding: 3px 0; -} -#powerTip > .info .title { - display: block; - padding: 10px 15px; - border-bottom: 1px solid #c0c0c0; - text-align: center; - text-transform: uppercase; -} -#powerTip > .info .content { - display: block; - padding: 15px 15px; -} -#powerTip .spinner { - margin: 20px auto; -} -#miniGame .spinner { - margin: 82px auto 0 auto; -} -.clearfix::after { - content: "."; - display: block; - height: 0; - clear: both; - visibility: hidden; -} -.clearfix { - display: inline-block; -} -.none { - display: none; -} -html { - min-height: 100%; -} -body { - font: 12px 'Noto Sans', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, Sans-Serif; - color: #707070; - background: #eee; - background-image: linear-gradient(to bottom, #d7d7d7 0%, #eeeeee 116px); - overflow-x: hidden; - cursor: default; -} -@supports (display: grid) { body { --grid: 1; } } -body.no-select { - -moz-user-select: none; - -webkit-user-select: none; -} -body.fixed-scroll { - /* prevents scroll bar flicker when dragging a piece out */ - overflow-y: scroll; -} -a, -a:visited, -button, -input { - color: #747474; -} -a, -a:visited, -button, -.button { - cursor: pointer; -} -a, -a:hover, -a:visited { - text-decoration: none; -} -button.a { - border: none; - background: none; -} -strong { - font-weight: bold; -} -.small { - font-size: 11.5px; -} -#site_header { - width: 200px; - float: left; - position: relative; -} -#site_header a.lang_fallback { - font-weight: bold; - display: inline-block; - margin-right: 1em; -} -body > div.content { - width: 1005px; - margin: 35px auto 30px auto; -} -.data-count::after, -.unread { - padding: 1px 5px 1px 4px; - font-weight: bold; - border-radius: 2px; - font-size: 0.9em; -} -.data-count::after { - content: attr(data-count); - top: 0; - right: 0; - position: absolute; - height: 11px; - padding: 1px 4px 1px 3px; - line-height: 10px; -} -.data-count[data-count='0']::after { - display: none; -} -#top { - position: relative; - height: 24px; - width: 1005px; - margin: 0 auto; - padding-top: 5px; - box-sizing: border-box; - display: flex; - flex-flow: row-reverse; -} -#top:hover { - z-index: 5001; -} -#top .link { - font-size: 13px; - height: 24px; - line-height: 24px; - padding: 0 8px; -} -#top .dasher .anon { - font-size: 16px; - padding: 0 7px; -} -#top > * { - position: relative; -} -#top .dropdown { - display: none; - position: absolute; - right: 0; - top: 28px; - background: #fff; - z-index: 3; - box-shadow: 2px 5px 6px rgba(0, 0, 0, 0.3); -} -#top .shown .dropdown { - display: block; -} -#top .dropdown .initiating .spinner { - padding: 10px 30px; -} -#top .shown a.toggle { - background: #fff; - height: 28px; -} -#top .signin { - margin: 3px .5em 0 .5em; - border-color: #d85000; - padding: 1px 5px; - height: 17px; -} -#top a.toggle { - display: block; - transition: color 0.13s; -} -#top .toggle:hover { - color: #303030; -} -@keyframes pulse-once { - 0% { background: #d85000; } - 100% { background: none; } -} -#top a.toggle.pulse { - animation: pulse-once 1.5s linear; -} -#reconnecting { - opacity: 0; -} -body.offline #reconnecting, -#network_error { - display: inline-block; - opacity: 1; - color: #dc322f; -} -@keyframes reconnected { - 0% { opacity: 1; color: #759900; } - 100% { opacity: 0; color: #759900; transform: translateY(-15px); } -} -body.online.reconnected #reconnecting { - animation: reconnected 2s ease-out 1s backwards; -} -body.online #reconnecting::before { - content: 'J' -} - -#clinput { - display: flex; - height: 24px; -} -#clinput a.link:hover { - color: #303030; -} -#clinput input { - border: 0; - border: none; - border-bottom: 1px solid #888; - background: transparent; - font-size: 14px; - color: #555; - line-height: 24px; - margin-right: 14px; - display: none; -} -#clinput.shown input { - display: inline-block; -} -#clinput input:focus { - outline: none; -} -body.dark #clinput input { - color: #aaa; -} - -#site_description { - position: absolute; - top: -100px; -} -#lichess { - margin-left: 211px; -} -#site_title { - width: 130px; - font-size: 30px; - display: block; - margin-bottom: 3px; - color: #555; - opacity: 0.7; - transition: opacity 0.13s; - white-space: nowrap; -} -#site_title:hover { - opacity: 1; -} -#site_title span.extension { - opacity: 0.7; -} -#site_title span.kiddo { - opacity: 0.7; - margin-right: 5px; - font-size: 0.9em; -} -.country > img { - vertical-align: middle; -} -div.content_box { - border: 1px solid #ccc; - background: #fff; - padding: 20px 24px 24px 24px; - text-align: left; - box-shadow: 0 1px 4px rgba(0, 0, 0, 0.15); -} -div.content_box h1 { - font-size: 1.8em; - font-weight: normal; - display: inline; -} -div.content_box.small_box { - width: 530px; -} -div.content_box.no_padding { - padding: 0; -} -div.content_box.no_padding h1 { - display: block; - padding: 20px 25px; -} -div.content_box_top { - padding: 10px 0 0 20px; - background-color: #f0f0f0; - background-image: linear-gradient(to bottom, #fafafa 0%, #f0f0f0 100%); - text-shadow: 0 1px 0 #FFF; -} -div.content_box_top .link:hover { - background: #fff; -} -div.content_box_top h1.lichess_title { - display: inline; - padding: 0; -} -div.content_box .content_box_content { - padding: 20px; -} -div.content_box_inter { - padding-left: 25px; - background: #f0f0f0; - border-top: 1px solid #ccc; - border-bottom: 1px solid #ccc; - display: block; - white-space: nowrap; -} -div.content_box .lichess_title { - font-size: 2em; - display: block; - margin-bottom: 0.5em; -} -div.content_box table.datatable { - width: 100%; - margin-top: 20px; -} -div.content_box table.datatable td { - padding: 5px 10px 5px 10px; -} -div.content_box table.datatable tr:nth-child(odd) { - background: #eee; -} -table.slist { - width: 100%; - border-bottom: 1px solid #d4d4d4; -} -table.slist thead th { - border-top: 1px solid #d4d4d4; - border-bottom: 1px solid #d4d4d4; - padding: 0.4em 0.6em; -} -table.slist thead th.large { - font-size: 1.4em; -} -table.slist td { - padding: 0.6em; - font-size: 1.1em; -} -table.slist td .label { - font-family: monospace; - font-size: 10px; -} -table.slist tbody tr:nth-child(even) { - background: #f4f4f4; -} -table.slist td:first-child, -table.slist th:first-child { - padding-left: 25px; -} -div.side h2 { - text-align: center; - font-size: 1.5em; -} -.side_box { - margin-top: 12px; - margin-left: -30px; - width: 226px; - box-sizing: border-box; -} -div.side_box, -div.box { - border: 1px solid #ccc; -} -div.side_box.padded { - padding: 7px; -} -div.side_box .top, -div.box .top { - border-bottom: 1px solid #ccc; - padding: 3px 5px; - font-weight: bold; - color: #999; -} -div.side_box .padded { - padding: 7px; -} -@media (max-width: 1070px) { - .side_box, - #site_header a.stream { - margin-left: 0!important; - width: 196px!important; - } -} -.notification .message_infos, -.notification .game_infos, -div.side_box .game_infos { - padding-left: 36px; - position: relative; -} -.notification .message_infos, -.notification .game_infos { - display: block; -} -div.side_box .game_infos { - border-bottom: 1px solid #ccc; - padding-bottom: 8px; - margin-bottom: 6px; -} -div.side_box .players .player { - overflow: hidden; - white-space: nowrap; -} -.notification .message_infos::before, -.notification .game_infos::before, -div.side_box .game_infos::before { - position: absolute; - top: 2px; - left: 0; - font-size: 30px; - opacity: 0.7; -} -.side_box .bookmark { - position: absolute; - right: 0; - z-index: 10; - display: none; -} -.side_box .bookmark, -body.mobile .side_box .bookmark { - display: block; -} -.bookmark:not(.bookmarked) .on, -.bookmark.bookmarked .off { - display: none; -} -div.side_box .game_infos .setup { - display: block; -} -div.side_box .game_infos .variant-link { - border-bottom: 1px dotted #747474; -} -div.side_box div.status { - text-align: center; - margin-top: 5px; -} -div.side_box div.user_tv h2 { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -#chat.side_box { - height: 350px; -} -div.side div.confrontation { - text-align: center; - margin-bottom: 5px; -} -div.side div.confrontation em { - font-style: italic; -} -div.side div.buttons { - width: 228px; - margin-left: -30px; - margin-top: 2em; - text-align: center; -} -div.side form.search { - margin: 1em 0 0 0; -} -div.side form.search input { - box-sizing: border-box; - border: 1px solid #ccc; - padding: 3px 5px; - width: 198px; -} -#site_header div.side_menu { - margin-top: 15px; -} -#site_header div.side_menu a { - padding: 8px 0 8px 8px; - display: block; - width: 203px; - transition: background 0.13s; -} -#site_header div.side_menu a::before { - opacity: 0.8; -} -#site_header div.side_menu a:hover { - background: rgba(255,255,255,0.5); -} -#site_header div.side_menu a.active { - background: white; - border: 1px solid #dadada; - border-right: none; -} -#site_header div.side_menu .sep { - margin: 10px; -} -.context-streamer, -.deep_link { - display: block; - padding: 5px; - margin: 0 0 1px -30px; - color: #fff!important; - background: rgba(117,153,0,0.5); - overflow: hidden; - white-space:nowrap; - border-radius: 0 0 3px 3px; -} -.context-streamer::before { - font-size: 1.5em; -} -.context-streamer:hover { - background: rgba(117,153,0,0.7); -} - -#ham-plate { - cursor: pointer; -} -#hamburger { - font-size: 16px; -} -#topmenu { - position: absolute; - top: 0; - left: -10px; - font-size: 13px; -} -#topmenu section { - position: relative; - float: left; - margin: 0; -} -#topmenu section > a { - color: #888; - display: block; - padding: 7px 12px; - text-transform: uppercase; - text-shadow: 0 1px 1px #fff; -} -#topmenu section:hover > a { - background: #fff; -} -#topmenu.hover section:hover div { - display: block; -} -#topmenu.blind div { - display: block; - margin-left: -9000px; -} -#topmenu div { - display: none; - position: absolute; - top: 100%; - left: 0; - font-size: 12px; - background: #fff; - width: 148px; - box-shadow: 2px 5px 6px rgba(0, 0, 0, 0.3); -} -#topmenu div a { - display: block; - padding: 6px 10px; - transition: background 0.13s; -} -#topmenu div a:hover { - background: #f0f0f0; - color: #444; -} - -#user_tag { - font-weight: bold; -} -#challenge_notifications_tag.none { - display: none!important; -} -#challenge_notifications_tag span:before { - font-size: 1.45em; - padding-left: 3px; -} -#notifications { - position: absolute; - top: -20px; - left: -30px; - width: 228px; - z-index: 2; -} -#notifications a { - font-weight: bold; -} -#notifications > div { - border: 1px solid #c0c0c0; - padding: 6px 8px 7px 8px; - margin-bottom: 8px; - border-radius: 2px; - box-shadow: 0 0 3px 0 #d85000; - transition: box-shadow 1.5s; -} -#notifications .actions { - margin-top: 10px; - display: flex; - justify-content: space-between; -} - -#site_notifications_tag span::before { - font-size: 1.45em; - padding-left: 3px; -} - -span.progress > .positive { - color: #759900; -} -span.progress > .negative { - color: #ac524f; -} -#friend_box { - position: fixed; - bottom: 0; - right: 0; - z-index: 3; - background: #fff; - border: 1px solid #ccc; - border-right: 0; - min-width: 150px; - max-height: 95%; - /* improve scroll perfs */ - backface-visibility: hidden; -} -#friend_box:hover { - overflow-y: auto; -} -#friend_box .friend_box_title { - cursor: pointer; - padding: 3px 5px; - border-bottom: 1px solid #ccc; -} -#friend_box .content div { - display: flex; -} -#friend_box .content a { - flex: 1 1 100%; - padding: 3px 0px; - display: block; - transition: background 0.13s; -} -#friend_box .content a.user_link { - max-width: 150px; - overflow: hidden; - text-overflow: ellipsis; -} -#friend_box .content i.line { - opacity: 0.6; -} -#friend_box .content a.tv { - flex: 0 0 auto; - padding: 0 5px; -} -#friend_box .content a.friend-study { - flex: 0 0 auto; - padding: 2px 5px 0 5px; -} -#friend_box .content a:hover { - background: #F0F0F0; -} -#friend_box .nobody { - text-align: center; - height: 100%; - padding: 3px 5px; -} -#friend_box .nobody span { - display: block; - margin: 5px; -} -#friend_box a.find { - display: none; - margin: 7px; - font-style: normal; -} -#friend_box div.nobody:hover a.find { - display: block; -} -.user_link { - white-space: nowrap; -} -.user_link span.rp:before { - content: " "; -} -.user_link span.rp.up { - color: #759900; -} -.user_link span.rp.down { - color: #ac524f; -} -.user_link span.title { - color: #d59120; - font-weight: bold; -} -.user_link span.title[data-bot] { - color: #cd63d9; -} -div.warning { - padding: 5px; - background: #f2dede; - line-height: 16px; - border: 1px solid #eed3d7; - color: #894a48; -} -div.join_warning { - margin: 1em; -} -/* soft inactive gradient */ - -.crosstable th, -#friend_box .friend_box_title, -div.side_box div.top, -div.box div.top, -.undertable_top, -.button, -a.button, -.button:visited, -group.radio label, -#notifications > div, -div.vstext, -div.user_show div.content_box_inter.tabs, -#qa .answers-header, -table.slist thead { - background: linear-gradient(to bottom, rgba(245, 245, 245, 1) 0%, rgba(240, 240, 240, 1) 100%); - text-shadow: 0 1px 0 #FFF; - color: #848484; -} -.button.big { - font-size: 1.6em; -} -.undertable_top, -.button, -a.button, -.button:visited, -table.slist thead { - font-weight: bold; -} -.button:disabled, -a.button:disabled { - opacity: 0.5; -} -.button, -a.button { - padding: 6px 11px; - white-space: nowrap; - text-decoration: none!important; -} -.button.thin, -a.button.thin { - padding: 0 8px; -} -.button, a.button { - border: 1px solid #e2e2e2; - border-radius: 2px; -} -.button.frameless { - border: 0; - background: none; -} -.button:hover, -a.button:hover, -group.radio label:hover { - border-color: #e2e2e2; - background: rgb(248, 248, 248); - background: linear-gradient(to bottom, rgba(248, 248, 248, 1) 0%, rgba(243, 243, 243, 1) 100%); -} -.button:active, -a.button:active { - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12) inset; -} - -/* active gradient */ - -.button.active, -.button.active:hover, -group.radio input:checked + label, -div.pagination span.current, -.data-count::after, -.pocket piece::after, -.unread, -.progressbar.flashy .current, -#simul .game_list .host.vstext, -#import_game .progression { - color: #fff !important; - text-shadow: 0 1px 0 #000 !important; - background: #d85000 !important; - box-shadow: 0 3px 4px rgba(0, 0, 0, 0.15) inset !important; -} -.fbt { - background: none; - border: none; - outline: none; - padding: 10px 13px; - text-transform: uppercase; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - cursor: pointer; -} -@keyframes fbt-glowing { - 50% { background: rgba(56,147,232,0.3); } -} -.fbt.glowed { - box-shadow: none; - animation: fbt-glowing 1.5s ease-in-out infinite; -} -.fbt:disabled { - opacity: 0.5; - cursor: default; -} -.fbt:disabled * { - opacity: 0.5; -} -.fbt:not(:disabled):hover { - background: rgba(56,147,232,0.8); - color: #fff!important; - animation: none; -} -.fbt:not(:disabled):active, -body.base .fbt.active { - background: #3893E8!important; - color: #fff; -} -.fbt.active span { - color: #fff; -} -.fbt.active-soft, -.fbt.active-soft:hover { - color: #fff !important; - text-shadow: 0 1px 0 #000 !important; - background: #bbb !important; - border-color: #aaa !important; - box-shadow: 0 3px 4px rgba(0, 0, 0, 0.15) inset !important; -} -/* gamelist.css */ - -div.game_row { - display: block; - padding: 15px 20px; - height: 224px; - border-bottom: 1px solid #eaeaea; - position: relative; - cursor: pointer; - transition: background 0.17s; -} -div.game_row:nth-child(odd) { - background: #f4f4f4; -} -div.game_row:hover { - background: rgba(191, 231, 255, 0.5); -} -div.game_row a { - position: relative; - z-index: 3; -} -div.game_row a.game_link_overlay { - position: absolute; - z-index: 2; - top: 0; - left: 0; - width: 100%; - height: 100%; -} -div.game_row a.mini_board { - position: absolute; - top: 15px; - left: 10px; -} -div.game_row div.infos { - position: absolute; - top: 15px; - left: 298px; - width: 476px; - height: 226px; -} -div.game_row div.infos::before { - position: absolute; - top: 0; - left: -45px; - font-size: 40px; - opacity: 0.7; -} -div.game_row div.header strong { - font-size: 1.4em; - text-transform: uppercase; - display: block; - font-family: 'Roboto'; - font-weight: 300; -} -div.game_row div.versus { - overflow: hidden; -} -div.game_row div.versus { - margin: 15px 0 0 -52px; - width: 528px; -} -div.game_row div.versus > div { - float: left; -} -div.game_row div.versus .swords { - width: 60px; - text-align: center; - font-size: 30px; - margin-top: 2px; - opacity: 0.7; -} -div.game_row div.versus .player { - font-size: 1.5em; - width: 234px; - text-align: right; -} -div.game_row div.versus .player.black { - text-align: left; -} -div.game_row div.versus a { - font-weight: bold; -} -div.game_row div.versus span.anon { - line-height: 2.5em; -} -div.game_row div.result { - display: block; - font-size: 1.3em; - margin: 5px 0 20px -52px; - width: 528px; - text-align: center; -} -div.game_row div.opening { - font-weight: bold; -} -div.game_row span.up { - color: #759900; -} -div.game_row span.down { - color: #ac524f; -} -div.game_row div.metadata { - margin-top: 10px; -} -div.game_list.playing { - margin-top: 1.4em; -} -div.game_list.playing > div { - display: inline-block; - margin: 0 10.5px 11px 11px; -} -div.vstext { - width: 212px; - line-height: 1.2em; - height: 2.4em; - overflow: hidden; - white-space: nowrap; - padding: 5px; - border: 1px solid #ccc; - border-width: 0 1px 1px 1px; - position: relative; -} -div.vstext > .center { - width: 100%; - text-align: center; - position: absolute; - bottom: 4px; - left: 0; - font-size: 0.9em; -} -div.vstext .left, -div.vstext .right { - max-width: 50%; - text-overflow: ellipsis; - overflow: hidden; -} -div.vstext .left { - float: left; - text-align: left; -} -div.vstext .right { - float: right; - text-align: right; -} -.mini_board { - display: block; -} -.mini_board .cg-board-wrap { - width: 224px; - height: 224px; -} -#challenge .lichess_overboard .cg-board-wrap { - width: 224px!important; - height: 224px!important; - margin: auto; -} -#now_playing { - padding: 4px 0 0 4px; - display: flex; - flex-flow: row wrap; -} -#now_playing > a { - padding: 4px; - transition: background 0.13s; - background: rgba(255, 255, 255, 0.6); -} -#now_playing > a:hover { - background: rgba(191, 231, 255, 0.7); -} -#now_playing .meta { - display: block; - text-align: center; - width: 160px; - overflow: hidden; -} -#now_playing .indicator { - color: #d85000; - margin-top: -3px; - display: block; -} -#now_playing .cg-board-wrap { - width: 160px; - height: 160px; -} - -div.lichess_overboard h1, -div.lichess_overboard h2 { - margin-bottom: 1em; - font-size: 1.4em; - padding: 0 2em; -} -div.lichess_overboard .target { - display: inline-block; - margin-bottom: 2em; -} -.undertable { - font-size: 11.5px; - margin-top: 15px; -} -.undertable_top { - border: 1px solid #ccc; - padding: 3px 5px; - display: flex; - justify-content: space-between; -} -.undertable_top a.more { - padding-right: 2px; - font-weight: normal; - order:2; -} -.undertable_top span.title { - font-weight: bold; - color: #999; -} -div.undertable_inner { - border: 1px solid #ccc; - border-top: 0; - height: 202px; - width: auto; - overflow: hidden; - background-color: #fff; -} -.undertable_inner:hover { - overflow-y: auto; -} -.undertable a.user_link { - font-weight: bold; - color: #a0a0a0; -} -.undertable table { - width: 100%; - height: 100%; -} -.undertable td { - padding: 6px 5px 6px 5px; - border-top: 1px solid #eaeaea; -} -.undertable tr:first-child td { - border-top: none; -} -.crosstable table { - width: 100%; - margin: 1em 0; -} -.crosstable td { - text-align: center; - background: #fff; - border: 1px solid #eee; - padding: 0; - min-width: 13px; -} -.crosstable td a { - line-height: 2em; - font-size: 1.1em; - display: block; - width: 100%; -} -.crosstable tr:first-child td:hover a, -.crosstable tr:first-child td.current a { - padding-top: 2px; - margin-top: -4px; - border-top: 2px solid #808080; -} -.crosstable tr:last-child td:hover a, -.crosstable tr:last-child td.current a { - padding-bottom: 2px; - margin-bottom: -4px; - border-bottom: 2px solid #808080; -} -.crosstable tr td.current a { - border-color: #d85000!important; -} -.crosstable td.new { - border: 1px solid #ccc; -} -.crosstable tr:first-child td.new, -.crosstable tr:first-child th.matchup { - border-top: 3px solid #ccc; -} -.crosstable tr:last-child td.new, -.crosstable tr:last-child th.matchup { - border-bottom: 3px solid #ccc; -} -.crosstable td.sep, -.crosstable th.user { - border-left: 3px solid #ccc; -} -body.base .crosstable .win { - font-weight: bold; - color: #759900; -} -body.base .crosstable .loss { - color: #ac524f; -} -.crosstable td:nth-last-child(3) { - border-right: 1px solid #ccc; -} -.crosstable th { - border: 1px solid #ccc; - padding: 3px; -} -.crosstable .score, -.crosstable .matchup { - font-size: 1.3em; - text-align: center; -} -.crosstable .matchup { - background: #fff; -} -.crosstable .user { - padding-left: 7px; - max-width: 112px; - overflow: hidden; -} -.crosstable .unavailable { - margin-top: 40px; - opacity: 0.7; -} -.progressbar { - background: #e0e0e0; - border: 1px solid #ddd; - border-radius: 5px; - padding: 1px; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12) inset; -} -.progressbar .current { - background: #d8a050; - height: 12px; - border-radius: 4px; -} -.progressbar.flashy.green .current { - background-color: #759900 !important; -} -.glowed { - box-shadow: 0 0 5px 1px #e89000, 0 0 10px 1px #d85000; -} -a.hover_text > .base, -a.hover_text:hover > .hover { - display: inline-block; -} -a.hover_text > .hover, -a.hover_text:hover > .base { - display: none; -} -::-webkit-input-placeholder { - color: #888; -} -:-ms-input-placeholder { - color: #888; -} -button::-moz-focus-inner { - border: 0; - padding: 0; -} -div.user_actions { - white-space: nowrap; -} -div.user_actions .button { - margin: 0 -3px 0 -3px; -} -input.copyable, -textarea.copyable { - background: #eee; - padding: 3px 5px; - border: 1px solid #ccc; -} -.flag { - display: inline-block; - width: 16px; - height: 16px; - vertical-align: middle; -} -.scroll-shadow-soft { - background: linear-gradient(#eee 30%, rgba(247, 247, 247, 0)), linear-gradient(rgba(247, 247, 247, 0), #eee 70%) 0 100%, radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)), radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)) 0 100%; -} -.scroll-shadow-hard { - background: linear-gradient(#fff 30%, rgba(255, 255, 255, 0)), linear-gradient(rgba(255, 255, 255, 0), #fff 70%) 0 100%, radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)), radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, .2), rgba(0, 0, 0, 0)) 0 100%; -} -.scroll-shadow-soft, -.scroll-shadow-hard { - background-repeat: no-repeat; - background-size: 100% 20px, 100% 20px, 100% 10px, 100% 10px; - background-attachment: local, local, scroll, scroll; -} -[data-hint] { - display: inline-block; - position: relative; -} -[data-hint]:before, -[data-hint]:after { - position: absolute; - will-change: transform; - visibility: hidden; - opacity: 0; - z-index: 900005; - pointer-events: none; - transition: 0.2s ease; -} -[data-hint]:hover:before, -[data-hint]:hover:after { - visibility: visible; - opacity: 1; -} -[data-hint]:before { - content: ''; - position: absolute; - background: transparent; - border: 6px solid transparent; - z-index: 900006; -} -[data-hint]:after { - content: attr(data-hint); - background: #404040; - color: #e0e0e0; - text-shadow: 0 -1px 0 black; - padding: 8px 10px; - line-height: 12px; - white-space: nowrap; - border-radius: 2px; - box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.3); - letter-spacing: normal; - font-size: 12px; - font-weight: normal; - font-style: inherit; - font-family: 'Noto Sans'; - text-transform: none!important; -} -.hint--bottom:before, -.hint--bottom-left:before { - border-bottom-color: #404040; -} -.hint--top:before, -.hint--top-left:before { - border-top-color: #404040; -} -.hint--bottom:before { - margin-top: -12px; -} -.hint--bottom:after { - margin-left: -18px; -} -.hint--bottom:before, -.hint--bottom:after { - top: 100%; - left: 50%; -} -.hint--bottom:hover:after, -.hint--bottom:hover:before { - transform: translateY(8px); -} -.hint--top:before { - margin-bottom: -12px; -} -.hint--top:after { - margin-left: -18px; -} -.hint--top:before, -.hint--top:after { - bottom: 100%; - left: 50%; -} -.hint--top:hover:after, -.hint--top:hover:before { - transform: translateY(-8px); -} -.hint--top-left:before { - margin-bottom: -12px; -} -.hint--top-left:after { - margin-right: -6px; -} -.hint--top-left:before, -.hint--top-left:after { - bottom: 100%; - right: 30%; -} -.hint--top-left:hover:after, -.hint--top-left:hover:before { - transform: translateY(-8px); -} -.hint--bottom-left:before { - margin-top: -12px; -} -.hint--bottom-left:after { - margin-right: -6px; -} -.hint--bottom-left:before, -.hint--bottom-left:after { - top: 100%; - right: 30%; -} -.hint--bottom-left:hover:after, -.hint--bottom-left:hover:before { - transform: translateY(8px); -} -.hint--left:before { - margin-right: -12px; - margin-top: -6px; -} -.hint--left:after { - margin-right: -14px; -} -.hint--left:before, -.hint--left:after { - right: 100%; - bottom: 50%; -} -.hint--left:hover:after, -.hint--left:hover:before { - transform: translateX(-8px); -} -#lichess .continue_with { - display: none; -} -.continue_with .button { - display: inline-block; - margin: 1em; -} -#modal-overlay { - display: block; - position: fixed; - top: 0; - left: 0; - height: 100%; - width: 100%; - overflow: auto; - background: rgba(0, 0, 0, 0.5); - z-index: 5; - cursor: pointer; -} -#modal-wrap { - display: inline-block; - position: relative; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - padding: 20px; - border-radius: 3px; - box-shadow: 0 0 95px 25px rgba(0, 0, 0, 0.8); - background: #fff; - text-align: center; - cursor: default; -} -#modal-wrap a { - color: #3893E8; -} -#modal-wrap .block_buttons .button { - display: block; - margin: 0.8em 0; -} -#modal-wrap .close, -div.lichess_overboard .close { - position:absolute; - top: -13px; - right: -13px; - display: block; - font-size: 16px; - line-height: 27px; - width: 32px; - height: 32px; - background: #fff; - border-radius: 50%; - cursor: pointer; -} -#modal-wrap .close:hover, -div.lichess_overboard .close:hover { - background: #f0f0f0; -} - -@keyframes fire { - 0% { - text-shadow: 0 0 6.66px #fefcc9, - 3.33px -3.33px 10px #fefcc9, - -6.66px -6.66px 13.33px #feec85, - 7.33px -14px 20px #ffae34, - -7.33px -19.33px 16.66px #ec760c, - 0 -27.33px 26.66px #cd4606, - 3.33px -30px 26.66px #973716; - } - 100% { - text-shadow: 0 0.5px 7.66px #fefcc9, - 3.33px -4px 12px #feec85, - -6.66px -7.66px 16.33px #ffae34, - 6.66px -16.33px 24.66px #ec760c, - -6.66px -25px 25px #cd4606, - 0 -32px 34px #973716, - 3.33px -33px 32px #451b0e; - } -} -.fire_trophy { - color: rgba(0, 0, 0, 0.6); - font-size: 60px; - display: block; - text-shadow: 0 0 6.66px #fefcc9, - 3.33px -3.33px 10px #fefcc9, - -6.66px -6.66px 13.33px #feec85, - 7.33px -14px 20px #ffae34, - -7.33px -19.33px 16.66px #ec760c, - 0 -27.33px 26.66px #cd4606, - 3.33px -30px 26.66px #973716; -} -.fire_trophy:hover { - animation: fire 1.5s ease-in-out infinite alternate; -} -/* switch toggle button */ -.cmn-toggle { - position: absolute; - margin-left: -9999px; - visibility: hidden; -} -.cmn-toggle + label { - display: block; - position: relative; - cursor: pointer; - outline: none; - -webkit-user-select: none; - -moz-user-select: none; -} -input.cmn-toggle + label { - padding: 1px; - width: 34px; - height: 20px; - background-color: #aaa; - border-radius: 20px; -} -input.cmn-toggle + label::before, -input.cmn-toggle + label::after { - display: block; - position: absolute; - top: 1px; - left: 1px; - bottom: 1px; - content: ""; -} -input.cmn-toggle + label::before { - right: 1px; - background-color: #ccc; - border-radius: 20px; -} -input.cmn-toggle:hover + label::before { - transition: background 0.2s; -} -input.cmn-toggle + label::after { - width: 20px; - background-color: #fff; - border-radius: 100%; - box-shadow: 0 1px 2.5px rgba(0, 0, 0, 0.3); -} -input.cmn-toggle:hover + label::after { - transition: margin 0.2s; -} -input.cmn-toggle:checked + label::before { - background-color: rgba(117, 153, 0, 0.4)!important; -} -input.cmn-toggle:checked + label::after { - margin-left: 14px; -} -.hopscotch-content a { - text-decoration: underline; -} - -signal { - display: inline-block; - height: 1em; - width: 1.5em; - overflow: visible; - white-space: nowrap; -} -signal > i { - width: 20%; - margin-left: 1px; - display: inline-block; - height: 40%; - background-color: #759900; -} -signal > i:nth-child(2) { height: 60%; } -signal > i:nth-child(3) { height: 80%; } -signal > i:nth-child(4) { height: 100%; } - -signal.q1 > i { - background-color: #dc322f; -} -signal.q2 > i { - background-color: #d59120; -} -signal > i.off { - background-color: #d0d0d0; -} - -.embedding_analyse, -iframe.analyse, -iframe.video { - width: 744px; - height: 460px; - background: rgba(127, 127, 127, 0.05); - display: flex; - align-items: center; - justify-content: center; - box-shadow: 0 0 5px rgba(0,0,0,0.2); - border: none; - margin: 1em 0; -} -img.embed { - max-height: 400px; - max-width: 100%; - background: rgba(127, 127, 127, 0.05); - box-shadow: 0 0 5px rgba(0,0,0,0.2); -} -body ::-webkit-scrollbar, -body ::-webkit-scrollbar-corner { - width: 8px; - background: #eee; -} -body ::-webkit-scrollbar-thumb { - background: rgba(204, 204, 204, 0.7); -} -body ::-webkit-scrollbar-thumb:hover { - background: rgba(50, 50, 50, 0.2); -} -body ::-webkit-scrollbar-thumb:active { - background: rgba(50, 50, 50, 0.3); -} -body ::-webkit-scrollbar-track { - box-shadow: 0 0 6px rgba(50, 50, 50, 0.3) inset; -} diff --git a/public/stylesheets/contact.css b/public/stylesheets/contact.css deleted file mode 100644 index 112b191453..0000000000 --- a/public/stylesheets/contact.css +++ /dev/null @@ -1,52 +0,0 @@ -.contact { - font-size: 1.3em; - margin-top: 3em; -} -.contact h2 { - font-size: 1.2em; - margin-bottom: 1em; - padding-bottom: 0.3em; - border-bottom: 1px solid rgba(128,128,128,0.2); -} -.contact .node { - display: none; - opacity: 0; - transition: 1s opacity; -} -.contact .node:target { - display: block; - opacity: 1; -} - -.contact .node a.back { - color: #3893E8; - width: 25px; - margin-right: 5px; - display: inline-block; -} - -.contact .branch .links a { - display: block; - padding: 1em; - padding-left: 30px; - color: #3893E8; -} -.contact .branch .links a:hover, -.contact a.back:hover { - color: #fff!important; - background: #3893E8; -} - -.contact .leaf a { - color: #3893E8!important; -} -.contact .leaf .content { - padding: 1em 0; -} -.contact .leaf .content p, -.contact .leaf .content ul { - margin-bottom: 1em; -} -.contact .leaf .content li { - list-style: disc inside; -} diff --git a/public/stylesheets/coordinate.css b/public/stylesheets/coordinate.css deleted file mode 100644 index e2b9edb7dc..0000000000 --- a/public/stylesheets/coordinate.css +++ /dev/null @@ -1,204 +0,0 @@ -#trainer { - margin-bottom: 160px; - position: relative; - min-height: 600px; -} -.board_and_ground { - display: flex; - align-items: center; -} -.board_and_ground .cg-board-wrap { - width: 512px; - height: 512px; -} -#trainer div.box { - margin-bottom: 1em; - border: 1px solid #ccc; - padding: 7px; -} -#trainer > .side { - position: absolute; - top: 64px; - left: -222px; - width: 212px; -} -#trainer > .side h1 { - text-align: center; - font-size: 1.4em; - font-weight: bold; - margin-bottom: 10px; -} -#trainer > .side div.box { - margin-bottom: 20px; - padding: 0; -} -#trainer > .side div.box p { - padding: 10px; -} -body.dark #trainer > .side div.box { - border-color: #3d3d3d; -} - -#trainer .right { - display: flex; - flex-flow: column nowrap; - justify-content: center; - padding-left: 15px; - width: 242px; -} -body.transp #trainer .right { - padding: 8px; - margin-left: 10px; - background: rgba(0,0,0,0.6); -} - -form.color .color i { - display: block; - width: 30px; - height: 30px; - background-size: 30px 30px; - background-repeat: no-repeat; - padding: 0; -} -form.color .color_1 i { - background-image: url(../piece/cburnett/wK.svg); -} -form.color .color_2 i { - background-image: url(../images/wbK.svg); -} -form.color .color_3 i { - background-image: url(../piece/cburnett/bK.svg); -} -#trainer .lichess_board { - display: none; - border: 1px solid #ccc; -} -#trainer.white .white .lichess_board, -#trainer.black .black .lichess_board { - display: block; -} -#trainer .overlay_container { - position: absolute; - top: 0; - left: 0; -} -#trainer .score_container { - position: absolute; - top: 0; - left: 0; -} -#trainer .progress_bar_container { - margin: 10px 0 10px 0; - width: 514px; - height: 10px; -} -.is3d #trainer .progress_bar_container { - margin-top: 20px; -} -#trainer .progress_bar { - width: 100%; - height: 10px; - background-color: #759900; - box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12) inset; -} -#trainer .next_coord { - position: absolute; - top: 0; - left: 0; - z-index: 2; - width: 460px; - height: 514px; - line-height: 512px; - text-align: center; - font-size: 150px; - font-family: monospace; - font-weight: bold; - text-transform: uppercase; - opacity: 1; - pointer-events: none; - color: #eee; - text-shadow: 0 10px 10px #444; - opacity: 0.8; - transition: 0.13s; -} -#trainer .next_coord.nope { - color: red !important; -} -#trainer #next_coord0 { - color: #fff; -} -#trainer #next_coord1 { - left: 150px; - top: 50px; - font-size: 65px; - opacity: 0.7; -} -#trainer #next_coord2 { - transition: none; - left: 235px; - top: 66px; - font-size: 30px; - opacity: 0.4; -} -#trainer #next_coord1, -#trainer #next_coord2, -#trainer #next_coord0 { - -webkit-user-select: none; - -moz-user-select: none; -} -#trainer .explanation { - text-align: justify; - margin-bottom: 20px; - width: 242px; -} -#trainer .explanation li { - list-style: outside disc; - margin: 1em 0 1em 25px; -} -#trainer .start { - font-size: 20px; -} -#trainer .score { - position: absolute; - top: 202px; - left: 202px; - z-index: 9; - font-family: 'Roboto Mono'; - font-size: 70px; - display: block; - margin: auto; - width: 110px; - height: 110px; - text-align: center; - line-height: 110px; - color: #fff; - background-color: #759900; - transition: 1s; - opacity: 1; - box-shadow: 0 0 10px #fff; - border-radius: 3px; - transform: rotate(360deg); - cursor: pointer; -} -#trainer.init .score { - opacity: 0; -} -#trainer.play .score { - opacity: 1; - top: 550px; - box-shadow: 0 0 1px #fff; - border-radius: 100px; - transform: rotate(0deg); -} -#trainer.wrong .progress_bar, -#trainer.wrong strong.score { - background-color: #ac524f; -} -#trainer.play .start, -#trainer #next_coord, -#trainer.play form.color { - display: none; -} -#trainer.play #next_coord { - display: block; -} diff --git a/public/stylesheets/dark.css b/public/stylesheets/dark.css deleted file mode 100644 index 8d593fac12..0000000000 --- a/public/stylesheets/dark.css +++ /dev/null @@ -1,549 +0,0 @@ -body.dark { - background-color: #181818; - background-image: linear-gradient(to bottom, #2c2c2c, #181818 116px); - color: #929292; -} -body.dark a, -body.dark a:visited, -body.dark #powerTip > .actions a, -body.dark group.radio label, -body.dark .button, -body.dark .fbt { - color: #8f8f8f; -} -body.dark #video .content_box_top form input, -body.dark .study_box .list div.editing, -body.dark .study_box .list div.config, -body.dark input, -body.dark textarea, -body.dark div.analysis_menu > a.active, -body.dark div.mchat .chat_tabs .tab { - background: #181818; - color: #8f8f8f; -} -body.dark div.analysis_menu > a.active { - border-top-color: #181818; -} -body.dark .crosstable td { - background: #2a2a2a; - border-color: #181818; -} -body.dark #video_side .tag_list a.full:hover { - background: #222; - border-color: #444; -} -body.dark .fork, -body.dark .study_tabs a, -body.dark .lichess_ground .suggestion, -body.dark .lichess_ground .pending, -body.dark .lichess_ground .negotiation, -body.dark #video .tag_list a { - background: #363636; - color: #aaa; -} -body.dark #adv_chart_loader, -body.dark #video .tag_list a:hover { - background: #3a3a3a; - color: #a0a0a0; -} -body.dark #video .card .duration { - background: rgba(0,0,0,0.7); -} -body.dark .fbt.glowed, -body.dark #site_title { - color: #acacac; -} -body.dark .mini_board, -body.dark div.mchat div.top, -body.dark .undertable_top, -body.dark div.undertable_inner, -body.dark .undertable td, -body.dark .study_invite input, -body.dark div.side_box, -body.dark div.side_box .top, -body.dark .box, -body.dark .box .top, -body.dark div.table, -body.dark div.table_wrap > div.clock > div.time, -body.dark #tournament_schedule .schedule, -body.dark #tournament_side .box, -body.dark #tournament_side .player .stats, -body.dark #tournament_side .player tr > *, -body.dark #tournament_side .player tr:hover th, -body.dark .ceval_box, -body.dark .areplay .opening_box, -body.dark .areplay .chapter_name, -body.dark div.content_box, -body.dark div.content_box_inter, -body.dark div.content_box_inter a.active, -body.dark input.copyable, -body.dark textarea.copyable, -body.dark #site_header div.side_menu a.active, -body.dark div.sub_ratings > a.active, -body.dark div.game_row, -body.dark div.side form.search input, -body.dark #lichess_forum div.post, -body.dark .content_box form input, -body.dark .progressbar, -body.dark form.translation_form div.messages, -body.dark form.translation_form input, -body.dark #adv_chart, -body.dark div.search_status, -body.dark #qa input, -body.dark #qa textarea, -body.dark #qa .answers-header, -body.dark #qa .question .comments, -body.dark #qa .comments .comment, -body.dark #qa .answer-wrap, -body.dark #qa .tm-tag, -body.dark .slist, -body.dark .slist thead th, -body.dark #notifications > div, -body.dark form.wide input[type="text"], -body.dark form.wide textarea, -body.dark #team .team-left, -body.dark #team .team-right, -body.dark #team h2, -body.dark #team.team_show div.content_box_top, -body.dark #perfStat div.content_box_top, -body.dark #perfStat .counter tr:first-child, -body.dark #perfStat .result thead tr, -body.dark .leaderboard_title, -body.dark #friend_box, -body.dark #friend_box .friend_box_title, -body.dark div.user_show div.user-infos, -body.dark div.user_show .insight, -body.dark #powerTip, -body.dark #miniGame, -body.dark #powerTip > .title, -body.dark #powerTip > .score, -body.dark #powerTip > .game_legend, -body.dark #hooks_wrap .table_wrap th, -body.dark #hooks_wrap .table_wrap td, -body.dark #hooks_wrap, -body.dark #hooks_wrap div.tabs a, -body.dark #hooks_wrap .hooks_chart > div.grid, -body.dark div.vstext, -body.dark div.user_show div.content_box_inter.tabs, -body.dark #enterable_tournaments table.scheduled, -body.dark div.user_show .mod_zone .listings, -body.dark div.user_show .note_zone, -body.dark div.user_show .note_zone div, -body.dark .lichess_ground .replay, -body.dark .lichess_ground .areplay, -body.dark .lichess_ground .result, -body.dark .lichess_ground .replay .buttons, -body.dark .lichess_ground .replay .moves, -body.dark .tview2.column > index, -body.dark .tview2.column > index + move, -body.dark div.analysis_menu, -body.dark div.analysis_menu > a, -body.dark .explorer_box, -body.dark .retro_box, -body.dark .practice_box, -body.dark .practice_box .comment, -body.dark .explorer_box .config .choices span, -body.dark .lichess_ground .areplay interrupt, -body.dark div.content_box.prefs form li, -body.dark div.content_box.prefs fieldset, -body.dark #claim_draw_zone, -body.dark .crosstable th, -body.dark .crosstable tr:first-child td.new, -body.dark .crosstable tr:first-child th.matchup, -body.dark .crosstable tr:last-child td.new, -body.dark .crosstable tr:last-child th.matchup, -body.dark .crosstable td.sep, -body.dark #lichess_blog .list h1, -body.dark #lichess_blog .body h2, -body.dark #lichess_blog .body img, -body.dark #tournament_side h2, -body.dark div.doc_box h2, -body.dark div.force_resign_zone, -body.dark div.negotiation, -body.dark div.side_box .game_infos, -body.dark #video .content_box_top, -body.dark #simul .half, -body.dark .donation, -body.dark .donation a, -body.dark .studies .study, -body.dark .study_metadata h2 .views, -body.dark .study_invite .users, -body.dark .study_metadata h2 .liking, -body.dark #notify_app .pager.prev, -body.dark div.mchat .presets span, -body.dark div.mchat input.lichess_say, -body.dark #tournament .controls, -body.dark .rematch-decline, -body.dark div.mchat .chat_tabs .tab, -body.dark #team table.requests.for-team { - border-color: #3d3d3d; -} -body.dark .tview2.column > index, -body.dark .tview2.column > interrupt, -body.dark .lichess_ground .areplay .result, -body.dark .lichess_ground .areplay .status, -body.dark .explorer_box .config .choices span:hover, -body.dark #perfStat .counter tr.full td:last-child, -body.dark div.lichess_overboard .close, -body.dark #modal-wrap, -body.dark #modal-wrap .close { - background-color: #303030; -} -body.dark #opening .meter ul, -body.dark #opening .meter li.dubious .step, -body.dark div.lichess_overboard .close:hover, -body.dark #modal-wrap .close:hover { - background-color: #505050; -} - -body.dark hr, -body.dark .fork move, -body.dark #adv_chart_loader, -body.dark .pull-quote p, -body.dark .pull-quote p:after, -body.dark #powerTip > .info .title, -body.dark #tournament_schedule .timeheader, -body.dark #opening .meter .step { - border-color: #505050; -} - -body.dark #tournament_side .featured .vstext strong, -body.dark div.search_status, -body.dark #opening .meter .step, -body.dark #hooks_wrap div.tabs a { - background-color: #3e3e3e; - color: #b0b0b0; -} -body.dark #top a.toggle:hover, -body.dark #clinput a.link:hover, -body.dark #top a.signin, -body.dark #hooks_wrap .hook_filter .checkable { - color: #c0c0c0; -} -body.dark .user_show .trophy.icon3d, -body.dark #timeline a, -body.dark .undertable a.user_link, -body.dark #team .forum a.user_link, -body.dark div.user_show div.content_box_top > span, -body.dark .undertable_top span.title { - color: #838383; -} -body.dark .user_link span.title { - color: #bf811d; -} -body.dark .user_link span.title[data-bot] { - color: #b72fc6; -} -body.dark .user_show .fire_trophy { - color: #666; -} -body.dark #promotion_choice { - background: rgba(0, 0, 0, 0.7); -} -body.dark .areplay, -body.dark .explorer_box tr:nth-child(even), -body.dark div.mchat .messages, -body.dark div.side_box, -body.dark .box, -body.dark div.table, -body.dark div.table_wrap > div.clock > div.time, -body.dark #friend_box .content a:hover, -body.dark div.undertable_inner, -body.dark .donation a, -body.dark div.mchat .chat_tabs .tab.active { - background: #262626; -} -body.dark div.sub_ratings > a.game:hover, -body.dark #hooks_wrap .table_wrap td, -body.dark #now_playing > a { - background: rgba(40, 40, 40, 0.6); - border-color: #242424; -} -body.dark #hooks_wrap .table_wrap tr.cancel td { - background: rgba(0, 80, 0, 0.7); -} -body.dark #site_header div.side_menu a:hover, -body.dark div.doc_box a.variant:hover, -body.dark #hooks_wrap .table_wrap tr.join:hover td, -body.dark #hooks_wrap .pools > div:hover, -body.dark #now_playing > a:hover, -body.dark .explorer_box tr:hover, -body.dark .pv_box .pv[data-uci]:hover, -body.dark #tournament table.standing:not(.created):not(.loading) tbody tr:hover { - background: rgba(27, 51, 68, 0.7); -} -body.dark #hooks_wrap, -body.dark #hooks_wrap div.tabs a:hover, -body.dark #hooks_wrap div.tabs a.active, -body.dark .forecast .entry:hover, -body.dark #tournament_schedule { - background-color: #303030; -} -body.dark #hooks_wrap div.tabs a:hover { - border-top-color: #808080; -} -body.dark #hooks_wrap div.tabs a.active { - border-bottom-color: #303030; - border-top-color: #d85000; -} -body.dark .lichess_ground .replay index, -body.dark .lichess_ground .replay move:not(.empty):hover, -body.dark .ceval_box pearl, -body.dark .areplay .opening_box, -body.dark .areplay .chapter_name, -body.dark #challenge_app div.challenge, -body.dark #challenge_app div.empty, -body.dark #challenge_app div.initiating, -body.dark #notify_app .site_notification, -body.dark #notify_app div.empty, -body.dark div.lichess_overboard, -body.dark div.analysis_menu > a, -body.dark div.content_box, -body.dark div.content_box_inter a.active, -body.dark #site_header div.side_menu a.active, -body.dark div.sub_ratings > a.game.active, -body.dark #tournament_side .stats, -body.dark table.translations tbody tr, -body.dark form.translation_form div.message, -body.dark #lichess_forum table.forum_table thead tr:nth-child(odd), -body.dark #video_side .tag_list a.checked { - background-color: #2b2b2b; -} -body.dark #perfStat .counter tr, -body.dark #perfStat .result tr, -body.dark #video .card .info, -body.dark #video .card .reveal, -body.dark #timeline, -body.dark #timeline .entry { - border-color: #2b2b2b; -} -body.dark #site_header div.side_menu a.active, -body.dark #hooks_wrap .table_wrap, -body.dark div.content_box h1 { - text-shadow: 0 1px 0 #000; -} -body.dark div.game_row:nth-child(odd), -body.dark #lichess_forum table.forum_table tr:nth-child(odd), -body.dark #lichess_message tr:nth-child(even), -body.dark div.content_box_inter, -body.dark .slist tbody tr:nth-child(even), -body.dark #team .forum li:nth-child(odd), -body.dark table.translations tbody tr:nth-child(odd), -body.dark form.translation_form div.message:nth-child(even), -body.dark div.content_box table.datatable tr:nth-child(odd), -body.dark #tournament_side .pairings tr:hover, -body.dark #top .shown a.toggle, -body.dark #top .dropdown, -body.dark #challenge_app div.challenge, -body.dark #notify_app .site_notification, -body.dark #friend_box, -body.dark #powerTip, -body.dark #miniGame { - background: #343434; -} -body.dark .tview2 line move, -body.dark #lichess_forum div.post .message, -body.dark #lichess_blog, -body.dark #lichess_message div.thread_message_body, -body.dark form.translation_form div.message label, -body.dark div.user_show div.content_box_top > span strong { - color: #b0b0b0; -} -body.dark div.table_wrap > div.clock.running > div.time { - background: #505a60; - color: #fff; -} -body.dark .forecast .entry .del, -body.dark div.table_wrap > div.clock.running.emerg > div.time, -body.dark div.table_wrap > div.clock.outoftime > div.time { - background-color: #a00000; - color: #d0d0d0; -} -body.dark div.content_box, -body.dark #powerTip, -body.dark #miniGame { - box-shadow: 0 1px 2px #000; -} -body.dark div.content_box_top { - background-color: #343434; - background-image: linear-gradient(to bottom, #3a3a3a, #343434 100%); - text-shadow: 0 1px 0 #000; -} -/* soft inactive gradient */ - -body.dark .crosstable th, -body.dark #chat div.top, -body.dark div.side_box .top, -body.dark div.box .top, -body.dark #friend_box .friend_box_title, -body.dark .undertable_top, -body.dark .button, -body.dark .button:visited, -body.dark group.radio label, -body.dark #notifications > div, -body.dark div.vstext, -body.dark div.user_show div.content_box_inter.tabs, -body.dark #qa .answers-header, -body.dark #video .card .info, -body.dark #video .card .reveal, -body.dark #tournament .controls, -body.dark .slist thead { - background: linear-gradient(to bottom, rgba(40, 40, 40, 1), rgba(34, 34, 34, 1) 100%); - text-shadow: 0 1px 0 #000; -} -body.dark .button.frameless { - background: none; -} -body.dark .button, -body.dark a.button, -body.dark #challenge_app .owner, -body.dark group.radio, -body.dark group.radio label { - border-color: #323232; -} -body.dark #notify_app .site_notification, -body.dark .lichess_ground .negotiation a, -body.dark group.radio label:hover, -body.dark .button:hover, -body.dark a.button:hover { - border-color: #383838; - background: rgb(44, 44, 44); - background: linear-gradient(to bottom, rgba(44, 44, 44, 1), rgba(40, 40, 40, 1) 100%); -} -body.dark .fbt.active-soft, -body.dark .fbt.active-soft:hover { - color: #ccc !important; - text-shadow: 0 1px 0 #000 !important; - background: #444 !important; - border-color: #404040 !important; - box-shadow: 0 3px 4px rgba(0, 0, 0, 0.35) inset !important; -} -body.dark #hooks_wrap .hooks_chart .plot { - color: #aaa; - text-shadow: 0 0 3px #000; -} -body.dark #hooks_wrap .hooks_chart > span.label { - text-shadow: 0 0 3px #000; -} - -body.dark #top .dropdown { - border: 1px solid #3d3d3d; - border-top: 0; - right: -1px; -} -body.pirouetti.dark div.cemetery piece.black { - filter: brightness(2) contrast(150%) drop-shadow(0 0 0.5px #fff); -} -body.alpha.dark div.cemetery piece.black { - filter: brightness(6) contrast(150%) drop-shadow(0 0 0.5px #fff); -} -body.dark .scroll-shadow-soft, -body.dark .scroll-shadow-hard { - background: linear-gradient(#262626 30%, rgba(36, 36, 36, 0)), linear-gradient(rgba(36, 36, 36, 0), #262626 70%) 0 100%, radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, .7), rgba(0, 0, 0, 0)), radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, .7), rgba(0, 0, 0, 0)) 0 100%; -} -body.dark .scroll-shadow-soft, -body.dark .scroll-shadow-hard { - background-repeat: no-repeat; - background-size: 100% 20px, 100% 20px, 100% 10px, 100% 10px; - background-attachment: local, local, scroll, scroll; -} -body.dark div.user_show div.user-infos.scroll-shadow-hard { - background: linear-gradient(#2b2b2b 30%, rgba(43, 43, 43, 0)), linear-gradient(rgba(43, 43, 43, 0), #2b2b2b 70%) 0 100%, radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, .7), rgba(0, 0, 0, 0)), radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, .7), rgba(0, 0, 0, 0)) 0 100%; - background-repeat: no-repeat; - background-size: 100% 20px, 100% 20px, 100% 10px, 100% 10px; - background-attachment: local, local, scroll, scroll; -} -body.dark div.game_row:hover, -body.dark .studies .study:hover, -body.dark .relays .relay:hover, -body.dark .coaches .coach:hover, -body.dark .streamers .streamer:hover { - background: rgba(27, 51, 68, 0.5)!important; -} -body.dark .color-icon.white::before { - content: 'J'; -} -body.dark .color-icon.black::before { - content: 'K'; -} -body.dark ::-webkit-input-placeholder { - color: #777; -} -body.dark :-ms-input-placeholder { - color: #777; -} -body.dark #topmenu section > a { - color: #777; - text-shadow: 0 1px 1px #000; -} -body.dark #topmenu section:hover > a { - background: #2b2b2b; -} -body.dark #topmenu div { - background: #2b2b2b; - border: 1px solid #3d3d3d; - border-top: 0; - box-shadow: 2px 5px 6px rgba(0, 0, 0, 0.3); -} -body.dark #topmenu div a:hover { - background: #3e3e3e; - color: #b0b0b0; -} -body.dark .variant_icons span { - text-shadow: 0 0 5px #000, - 0 0 10px #000, - 0 0 20px #000; -} -body.dark #tv_channels > a:hover { - background: #333; - color: #c0c0c0; - box-shadow: 0 -1px 1px rgba(255,255,255,0.3); -} -body.dark ol.scheduled_tournaments li.marathon { - background: #2a2a2a; - box-shadow: 0 0 9px rgba(0,0,0,0.9); -} -body.dark div.eval_gauge { - background: #a0a0a0; -} -body.dark div.eval_gauge .black { - background: #666; -} -body.dark div.eval_gauge tick { - border-color: #a0a0a0; -} -body.dark div.side_box .game_infos .variant-link { - border-color: #8c8c8c; -} -body.dark input.cmn-toggle + label { - background-color: #888; -} -body.dark input.cmn-toggle + label:before { - background-color: #555; -} -body.dark input.cmn-toggle + label:after { - background-color: #aaa; - box-shadow: 0 2px 5px rgba(0, 0, 0, 0.6); -} -body.dark signal > i.off { - background-color: #555; -} -body.dark .context-streamer { - color: #ccc!important; -} -body.dark .ddloader { - background-image: url(../images/loader/whitex1.png); -} -body.dark ::-webkit-scrollbar, -body.dark ::-webkit-scrollbar-corner { - background: #262626; -} -body.dark ::-webkit-scrollbar-thumb { - background: rgba(200, 200, 200, 0.15); -} -body.dark ::-webkit-scrollbar-thumb:hover { - background: rgba(200, 200, 200, 0.3); -} -body.dark ::-webkit-scrollbar-thumb:active { - background: rgba(200, 200, 200, 0.4); -} diff --git a/public/stylesheets/dasherApp.css b/public/stylesheets/dasherApp.css deleted file mode 100644 index 68c76577f5..0000000000 --- a/public/stylesheets/dasherApp.css +++ /dev/null @@ -1,386 +0,0 @@ -#dasher_app { - width: 150px; - z-index: 2; -} -#dasher_app .spinner { - margin: 20px auto; -} -#dasher_app .links, -#dasher_app .subs { - padding: 5px 0; -} -#dasher_app .links a, -#dasher_app .links button, -#dasher_app .subs .sub { - display: block; - padding: 5px 10px; - transition: 0.13s; - white-space: nowrap; - overflow: hidden; -} -#dasher_app .links a:hover, -#dasher_app .links button:hover, -#dasher_app .subs .sub:hover, -#dasher_app .langs form > *:hover { - background: #F0F0F0; - color: #444; -} -#dasher_app .links button { - width: 100%; - text-align: left; - border: 0; - background: none; -} -#dasher_app .subs { - border-top: 1px solid #ddd; -} -#dasher_app .subs .sub:before { - float: right; - opacity: 0.5; - font-size: 9px; - margin-top: 4px; - transition: 0.2s; -} -#dasher_app .subs .sub:hover:before { - color: #3893E8; - opacity: 0.8; -} -#dasher_app .status { - display: block; - position: relative; - padding: 5px 0; - border-top: 1px solid #ddd; -} -#dasher_app .status signal { - position: absolute; - right: 10px; - top: 10px; - font-size: 20px; -} -#dasher_app .status .ping, -#dasher_app .status .server { - display: block; - font-family: 'Roboto Mono', 'Roboto'; - padding-left: 10px; -} -#dasher_app .status strong { - padding: 0 5px; -} - -#dasher_app .head { - display: block; - padding: 15px 10px; - background: #F0F0F0; - color: #444; -} -#dasher_app .head::before { - opacity: 0.5; - transition: 0.3s; -} -#dasher_app .head:hover::before { - color: #3893E8; - opacity: 0.9; -} - -#dasher_app .langs form { - max-height: 400px; - overflow: auto; -} -#dasher_app .langs form > * { - display: block; - padding: 0.4em 0.5em; - border: none; - background: none; - width: 100%; - text-align: left; - box-sizing: border-box; -} -#dasher_app .langs .accepted { - border-left: 3px solid #3893E8; -} -#dasher_app .langs .current { - background: #3893E8!important; - color: #fff!important; - border-left: none; -} -#dasher_app .selector { - flex: 1 1 100%; - margin: 5px 0; -} -#dasher_app .selector a { - display: block; - padding: 6px 0 6px 8px; -} -#dasher_app .selector a:hover { - background: #F0F0F0; - color: #444; -} -#dasher_app .selector a.active { - background: #3893E8!important; - color: #fff!important; -} -#dasher_app .selector a::before { - margin-right: 8px; - font-size: 19px; - justify-content: center; - align-items: center; - opacity: 0; -} -#dasher_app .selector a:hover::before { - opacity: 1; - color: #3893E8; -} -#dasher_app .selector a.active::before { - opacity: 1; - color: #fff!important; -} -#dasher_app .zen a::before { - font-size: 18px; - margin-right: 3px; - opacity: 0.5; -} -#dasher_app .zen:hover a::before{ - opacity: 1; -} -#dasher_app .sound .content { - display: flex; - flex-flow: row; -} -#dasher_app .sound .selector a { - border-radius: 3px 0 0 3px; -} -#dasher_app .sound.silent .slider { - opacity: 0.2; -} -#dasher_app .sound .slider { - flex: 0 0 8px; - margin: 10px; -} -#dasher_app .sound .slider .ui-slider-handle { - margin: 0 0 -9px -4px; - border-radius: 50%; - border-color: #3893E8!important; -} -#dasher_app .sound .slider .ui-widget-header { - width: 8px; - bottom: 0; - background: #3893E8!important; -} - -#dasher_app .background .image p { - font-size: 0.9em; - padding: 5px; -} -#dasher_app .background input { - padding: 5px; - border: 1px solid #444; - box-sizing: border-box; - width: 100%; - background-color: #3e3e3e; - color: #fff; -} - -#dasher_app .board .zoom { - margin: 5px 0px; - border-top: 1px solid #ddd; - padding: 10px 10px; -} -#dasher_app .board .slider { - margin-top: 10px; -} - -#dasher_app .theme .list { - margin: 5px 0; - display: flex; - flex-flow: row wrap; -} -#dasher_app .theme .list a { - flex: 0 0 50%; - height: 40px; - display: flex; - justify-content: center; - align-items: center; -} -#dasher_app .theme .list span { - display: block; - width: 64px; - height: 32px; - box-sizing: border-box; -} -#dasher_app .theme.d3 .list span { - width: 66px; - height: 30px; - transition: transform 0.3s; -} -#dasher_app .theme .list a:hover { - filter: brightness(1.1); -} -#dasher_app .theme .list a:hover span { - transform: scale(1.05); -} -#dasher_app .theme .list a.active { - background: #3893E8; -} - -#dasher_app .piece .list { - padding: 5px 0; - display: flex; - flex-flow: row wrap; - background: url(../images/board/darksquares.jpg); - box-shadow: inset 0 0 20px 3px #777; -} -#dasher_app .piece .no-square { - width: 75px; - height: 75px; - position: relative; -} -#dasher_app .piece .no-square:hover { - background: rgba(250, 250, 250, 0.15); -} -#dasher_app .piece .no-square.active { - background: rgba(56, 147, 232, 0.5); -} -#dasher_app .piece piece { - width: 100%; - height: 100%; -} -#dasher_app .piece.d3 piece { - left: 0; - top: 0; - background-size: cover; - background-position: 0 67%; -} - -#dasher_app .theme.d2 .blue { - background-image: url(../images/board/svg/blue.svg); - background-size: 256px; -} -#dasher_app .theme.d2 .blue2 { - background-image: url(../images/board/blue2.thumbnail.jpg); -} -#dasher_app .theme.d2 .wood2 { - background-image: url(../images/board/wood2.thumbnail.jpg); -} -#dasher_app .theme.d2 .wood3 { - background-image: url(../images/board/wood3.thumbnail.jpg); -} -#dasher_app .theme.d2 .blue3 { - background-image: url(../images/board/blue3.thumbnail.jpg); -} -#dasher_app .theme.d2 .marble { - background-image: url(../images/board/marble.thumbnail.jpg); -} -#dasher_app .theme.d2 .brown { - background-image: url(../images/board/svg/brown.svg); - background-size: 256px; -} -#dasher_app .theme.d2 .green { - background-image: url(../images/board/svg/green.svg); - background-size: 256px; -} -#dasher_app .theme.d2 .olive { - background-image: url(../images/board/olive.thumbnail.jpg); -} -#dasher_app .theme.d2 .purple { - background-image: url(../images/board/svg/purple.svg); - background-size: 256px; -} -#dasher_app .theme.d2 .grey { - background-image: url(../images/board/grey.thumbnail.jpg); -} -#dasher_app .theme.d2 .wood { - background-image: url(../images/board/wood.thumbnail.jpg); -} -#dasher_app .theme.d2 .canvas { - background-image: url(../images/board/canvas2.thumbnail.jpg); -} -#dasher_app .theme.d2 .leather { - background-image: url(../images/board/leather.thumbnail.jpg); -} -#dasher_app .theme.d2 .metal { - background-image: url(../images/board/metal.thumbnail.jpg); -} -#dasher_app .theme.d2 .maple { - background-image: url(../images/board/maple.thumbnail.jpg); -} -#dasher_app .theme.d3 .Black-White-Aluminium { - background-image: url(../images/staunton/board/Black-White-Aluminium.thumbnail.png); -} -#dasher_app .theme.d3 .Brushed-Aluminium { - background-image: url(../images/staunton/board/Brushed-Aluminium.thumbnail.png); -} -#dasher_app .theme.d3 .China-Blue { - background-image: url(../images/staunton/board/China-Blue.thumbnail.png); -} -#dasher_app .theme.d3 .China-Green { - background-image: url(../images/staunton/board/China-Green.thumbnail.png); -} -#dasher_app .theme.d3 .China-Grey { - background-image: url(../images/staunton/board/China-Grey.thumbnail.png); -} -#dasher_app .theme.d3 .China-Scarlet { - background-image: url(../images/staunton/board/China-Scarlet.thumbnail.png); -} -#dasher_app .theme.d3 .China-Yellow { - background-image: url(../images/staunton/board/China-Yellow.thumbnail.png); -} -#dasher_app .theme.d3 .Classic-Blue { - background-image: url(../images/staunton/board/Classic-Blue.thumbnail.png); -} -#dasher_app .theme.d3 .Transparent-Glass { - background-image: url(../images/staunton/board/Glass.thumbnail.png); -} -#dasher_app .theme.d3 .Gold-Silver { - background-image: url(../images/staunton/board/Gold-Silver.thumbnail.png); -} -#dasher_app .theme.d3 .Green-Glass { - background-image: url(../images/staunton/board/Green-Glass.thumbnail.png); -} -#dasher_app .theme.d3 .Light-Wood { - background-image: url(../images/staunton/board/Light-Wood.thumbnail.png); -} -#dasher_app .theme.d3 .Power-Coated { - background-image: url(../images/staunton/board/Power-Coated.thumbnail.png); -} -#dasher_app .theme.d3 .Purple-Black { - background-image: url(../images/staunton/board/Purple-Black.thumbnail.png); -} -#dasher_app .theme.d3 .Rosewood { - background-image: url(../images/staunton/board/Rosewood.thumbnail.png); -} -#dasher_app .theme.d3 .Wood-Glass { - background-image: url(../images/staunton/board/Wood-Glass.thumbnail.png); -} -#dasher_app .theme.d3 .Wax { - background-image: url(../images/staunton/board/Wax.thumbnail.png); -} -#dasher_app .theme.d3 .Jade { - background-image: url(../images/staunton/board/Jade.thumbnail.png); -} -#dasher_app .theme.d3 .Marble { - background-image: url(../images/board/3d/marble.thumbnail.png); -} -#dasher_app .theme.d3 .Woodi { - background-image: url(../images/board/3d/woodi.thumbnail.png); -} - -body.dark #dasher_app .subs, -body.dark #dasher_app .status, -body.dark #dasher_app .board .zoom { - border-color: #3d3d3d; -} -body.dark #dasher_app .head, -body.dark #dasher_app .links a:hover, -body.dark #dasher_app .links button:hover, -body.dark #dasher_app .subs a:hover, -body.dark #dasher_app .langs form > *:hover, -body.dark #dasher_app .selector a:hover { - background: #3e3e3e; - color: #b0b0b0; -} -body.dark #dasher_app .links button { - color: #8f8f8f; -} -body.dark #dasher_app .selector a:hover::before { - color: #555; -} diff --git a/public/stylesheets/emailConfirmHelp.css b/public/stylesheets/emailConfirmHelp.css deleted file mode 100644 index ced288d51e..0000000000 --- a/public/stylesheets/emailConfirmHelp.css +++ /dev/null @@ -1,15 +0,0 @@ -.emailConfirmHelp form { - margin-top: 2em; -} -.emailConfirmHelp .form-split { - align-items: center; -} -.emailConfirmHelp .replies { - font-size: 1.2em; -} -.emailConfirmHelp .replies p { - margin-bottom: 1em; -} -.emailConfirmHelp .replies a { - color: #3893E8!important; -} diff --git a/public/stylesheets/event.crud.css b/public/stylesheets/event.crud.css deleted file mode 100644 index faf913bef2..0000000000 --- a/public/stylesheets/event.crud.css +++ /dev/null @@ -1,49 +0,0 @@ -h1.lichess_title { - text-align: center; - margin-bottom: 0!important; -} -h1.lichess_title a.new { - float: right; -} -h1.lichess_title span { - display: block; - font-size: 0.35em; - opacity: 0.8; - margin-top: 10px; - text-transform: uppercase; -} -.event_crud.edit h1.lichess_title { - background: #303F9F; - color: #ddd; - letter-spacing: 0.1em; - padding: 30px!important; - font-size: 27px!important; -} -table.slist { - font-size: 1.2em; - width: 100%; -} -table.slist td { - padding: 20px 10px; -} -table.slist time { - display: block; - font-size: 0.8em; - opacity: 0.8; -} -.material.form button { - font-size: 1.7em; - font-weight: normal; - padding: 10px 20px; -} -.material.form textarea { - height: 10em; -} -.event_crud a { - color: #3893E8!important; -} -.event_crud h2 { - font-size: 1.5em; - margin: 0px 0 30px 0; - text-align: center; -} diff --git a/public/stylesheets/event.css b/public/stylesheets/event.css deleted file mode 100644 index 7de93aad40..0000000000 --- a/public/stylesheets/event.css +++ /dev/null @@ -1,49 +0,0 @@ -#events .datatable td { - padding: 2em!important; -} -#events .datatable a { - color: #3893E8; -} -#events .datatable h2 { - font-size: 1.5em; -} -#events .datatable strong { - font-weight: normal; -} -#events .datatable .date { - display: block; -} - -#event h2 { - font-size: 1.3em; - margin-top: 4em; - text-align: center; -} -#event .when { - margin-top: 2em; - text-align: center; -} -#event .when .button { - display:inline-block; - color: #3893E8; - padding: 20px 30px; - font-size: 1.3em; -} -#event .desc { - margin-top: 4em; -} -#event .countdown { - text-align: center; -} -#event .countdown li { - display: inline-block; - font-size: 1.5em; - list-style-type: none; - padding: 1.5em; - text-transform: uppercase; -} - -#event .countdown li span { - display: block; - font-size: 4.5rem; -} diff --git a/public/stylesheets/faq.css b/public/stylesheets/faq.css deleted file mode 100644 index 6343bd3399..0000000000 --- a/public/stylesheets/faq.css +++ /dev/null @@ -1,42 +0,0 @@ -.faq .question { - border-left: 5px solid white; - padding-left: 10px; -} -.faq .question .answer { - display: none; -} -.faq .question:target { - border-left: 5px solid rgba(128,128,128,0.2); -} -.faq .question:target .answer { - display: block; -} -.faq .question:target h3 { - font-weight: bold; - margin-bottom: 0.3em; -} -.faq h1, .faq h2 { - margin-left: 15px; -} -.faq h2 { - font-size: 1.2em; - margin: 0 1em; - padding-bottom: 0.3em; - border-bottom: 1px solid rgba(128,128,128,0.2); -} -.faq h3 { - font-size: 1.2em; - padding-bottom: 0.3em; -} -.faq .question, .faq p, .faq ul, .faq ol { - margin-bottom: 0.8em; -} -.faq a { - color: #3893e8; -} -.faq ul li { - list-style: disc inside; -} -.faq ol li { - list-style: decimal inside; -} diff --git a/public/stylesheets/features.css b/public/stylesheets/features.css deleted file mode 100644 index 29b413fb12..0000000000 --- a/public/stylesheets/features.css +++ /dev/null @@ -1,80 +0,0 @@ -.check, -.unlimited, -.green { - color: #759900; -} - -table { - font-size: 1.2em; -} -table h1::before { - margin-right: 10px; -} - -table a:not(.button), -table a:not(.button):visited { - border-bottom: 1px dashed #3893E8; -} - -table td, -table th { - padding: 10px 20px; - border-bottom: 1px solid #ddd; -} -body.dark table td, -body.dark table th { - border-color: #3a3a3a; -} - -thead th { - padding-top: 30px; - color: #d59120; - font-weight: bold; - padding-bottom: 20px; -} -thead:first-child th { - padding-top: 10px; -} - -tbody td .is::before { - font-size: 1.4em; -} - -tbody th { - opacity: 0.9; -} -tbody td { - whitespace: nowrap; -} - -.price { - font-size: 1.4em; -} -.price > * { - border: none; - padding-top: 30px; -} -.explanation { - margin: 40px 120px 20px 120px; - padding: 20px 30px; - background: #759900; - color: #fff; - font-size: 1.3em; -} -.explanation strong { - display: block; - text-align: center; -} - -.features_side { - margin: 30px 0; - padding: 30px 20px; - background: #759900; - color: #fff; - text-align: center; - font-size: 1.3em; -} -.features_side a { - display: block; - margin-top: 2em; -} diff --git a/public/stylesheets/forecast.css b/public/stylesheets/forecast.css deleted file mode 100644 index 20d63ba843..0000000000 --- a/public/stylesheets/forecast.css +++ /dev/null @@ -1,115 +0,0 @@ -.forecast { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - transition: opacity 0.13s; - position: relative; -} -.forecast.loading .box, -.forecast.loading .add { - opacity: 0.5; -} -.forecast .overlay { - position: absolute; - top: 0; - left: 0; - width: 100%; - height: 100%; - display: flex; -} -.forecast .entries { - border: 1px solid #ccc; -} -.forecast .entries .top { - border-bottom: 1px solid #ccc; - padding: 3px 5px; - font-weight: bold; - color: #999; -} -.forecast .entry { - padding: 12px 2px 12px 10px; - margin-left: -2px; - transition: 0.13s; - position: relative; - cursor: pointer; -} -.forecast .entry::before { - margin-left: -10px; - opacity: 0.4; -} -.forecast .entry:hover { - background: #e0e0e0; -} -.forecast .entry .del { - position: absolute; - right: 5px; - top: 8px; - width: 10px; - height: 10px; - line-height: 10px; - text-align: center; - display: block; - font-size: 13px; - opacity: 0; - transition: 0.13s; - background: #fff; - padding: 5px; - border-radius: 50%; - color: #dc322f; -} -.forecast .entry:hover .del { - opacity: 0.8; -} -.forecast .entry:hover .del:hover { - opacity: 1; -} -.forecast .add { - display: block; - width: 100%; - text-align: left; - border-width: 1px 0 0 0; - transition: 0.5s; -} -.forecast .add::before { - font-size: 32px; - float: left; - margin: 1px 10px 0 0; - opacity: 0.6; - transition: opacity 0.13s; -} -.forecast .add.enabled::before { - color: #759900; -} -.forecast .add:hover::before { - opacity: 0.9; -} -.forecast .add span { - display: block; - white-space: normal; - font-weight: normal; -} -.forecast sans { - font-family: 'Roboto'; - font-weight: 300; -} -.forecast sans san { - font-family: 'ChessSansPiratf', sans-serif; - font-weight: bold; -} -.forecast sans > * { - display: inline-block; - margin-right: 3px; -} -.forecast .add sans { - display: flex; - flex-flow: row wrap; -} -body.piece_letter .forecast sans san { - font-family: 'Noto Sans'; -} -.forecast button.on-my-turn { - margin-top: 20px; -} -.forecast button.on-my-turn::before { - color: #759900; -} diff --git a/public/stylesheets/form3.css b/public/stylesheets/form3.css deleted file mode 100644 index b5acbfa65a..0000000000 --- a/public/stylesheets/form3.css +++ /dev/null @@ -1,148 +0,0 @@ -.form3 * { - font-size: 14px; - box-sizing: border-box; -} -.form3 .form-group { - margin-bottom: 1rem; -} -.form3 .form-split { - display: flex; - justify-content: space-between; -} -.form3 .form-split .form-half { - flex: 0 0 48%; -} -.form3 .form-split .form-third { - flex: 0 0 31%; -} - -.form3 .form-label { - font-weight: bold; - display: inline-block; - margin-bottom: .5rem; -} -.form3 .form-control { - display: block; - width: 100%; - height: calc(2.25rem + 2px); - padding: 0.375rem 0.75rem; - font-size: 1rem; - line-height: 1.5; - color: #495057; - background-color: #fff; - background-clip: padding-box; - border: 1px solid #ced4da; - border-radius: 0.25rem; - transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; -} -body.dark .form3 .form-control { - background-color: #181818; - color: #999; - border-color: #404040; -} -.form3 textarea.form-control { - overflow: auto; - resize: vertical; - height: auto; -} -.form3 .form-control:invalid, .form3 .form-group.is-invalid .form-control { - border-color: #dc3545; -} -.form3 .error { - width: 100%; - margin-top: 0.25rem; - font-size: 80%; - color: #dc3545; -} - -.form3 .form-help { - font-size: 0.8em; - margin-top: .25rem; - color: #6c757d; - line-height: 1em; -} -body.dark .form3 .form-help { - color: #8a9299; -} - -.form3 .form-check div { - display: flex; -} - -.form3 .form-check-input { - margin-right: 0.5rem; -} - -.form3 .form-check .form-label { - margin-bottom: 0; - cursor: pointer; -} - -.form3 .form-actions { - margin: 1rem 0; - padding-top: 1rem; - border-top: 1px solid rgba(0, 0, 0, 0.1); - display: flex; - justify-content: space-between; - align-items: center; -} -.form3 .form-actions a { - color: #3893E8!important; -} -.form3 .form-actions.single { - justify-content: flex-end; -} - -.form3 hr { - margin-top: 1rem; - margin-bottom: 1rem; - border: 0; - border-top: 1px solid rgba(0, 0, 0, 0.1); -} - -/* CAPTCHA */ -.form3 .captcha { - display: flex; - margin-top: 2em; -} -.form3 .captcha.is-invalid:not(.success) { - border: 1px solid #dc3545; -} -.form3 .captcha .mini_board { - width: 250px; - cursor: pointer; -} -.form3 .captcha .captcha-explanation { - font-size: 0.9em; - margin-left: 1rem; - overflow: hidden; -} -.form3 .captcha.is-invalid .captcha-explanation { - padding: 1em; -} -.form3 .captcha .captcha-explanation .form-label { - display: block; - width: 310px; -} -.form3 .captcha .captcha-explanation .result { - display: none; - height: 48px; - line-height: 48px; - vertical-align: middle; - font-weight: bold; -} -.form3 .captcha .success { - color: #759900; -} -.form3 .captcha .failure { - color: #dc3545; -} -.form3 .captcha.success .success, -.form3 .captcha.failure .failure { - display: block; -} - -/* VENDORS */ -.form3 .twitter-typeahead { - width: 100%; -} diff --git a/public/stylesheets/forum.css b/public/stylesheets/forum.css deleted file mode 100644 index 1d35686d74..0000000000 --- a/public/stylesheets/forum.css +++ /dev/null @@ -1,322 +0,0 @@ -div.post .metas .mod { - margin-left: 1em; - font-size: 0.9em; - visibility: hidden; -} -div.post:hover .metas .mod { - visibility: visible; -} - -ol.crumbs { - padding: 20px 24px 0 24px; -} - -ol.crumbs li { - display: inline; - margin-left: 1em; -} - -ol.crumbs li:after { - content: "›"; - padding-left: 1em; -} - -ol.crumbs li:last-child:after { - display: none; -} -ol.crumbs li:first-child { - margin-left: 0; -} - -#lichess_forum ol.crumbs h1 { - display: inline; - margin: 0; - padding: 0; - vertical-align: middle; -} - -#lichess_forum .warning { - margin: 20px; - background: #f4f4f4; - text-align: center; - font-size: 1.6em; -} -#lichess_forum .warning h1 { - margin: 1em 0 0 0; - padding: 0; - font-weight: bold; -} -#lichess_forum .warning p { - margin: 1.8em 0; - line-height: 1.5em; -} - -#lichess_forum .nb_results { - padding-left: 25px; -} - -#lichess_forum form.search { - float: right; - margin: 20px; - font-size: 1.3em; -} - -#lichess_forum .search_results { - margin-top: 1em; -} -#lichess_forum .search_results time { - font-size: 0.8em; - white-space: nowrap; - display: block; -} -#lichess_forum .search_results a.post { - display: block; - font-size: 1.1em; - margin-bottom: 4px; - padding-bottom: 5px; -} -#lichess_forum .search_results td { - padding-bottom: 1em; - padding-top: 1em; -} - -#lichess_forum table.forum_table { - width: 100%; - margin-bottom: 5px; -} - -#lichess_forum table.forum_table th { - padding: 1em 0 0.5em 0; -} -#lichess_forum table.forum_table th:last-child { - padding-left: 1em; -} - -#lichess_forum table.forum_table td.subject { - padding: 2em 1em; -} - -#lichess_forum table.forum_table td.right, #lichess_forum table.forum_table th.right { - text-align: right; - padding-right: 2em; -} - -#lichess_forum table.forum_table td.last_post { - min-width: 150px; - padding-right: 1em; -} -#lichess_forum table.forum_table td.feed { - padding-right: 1em; -} - -#lichess_forum table.forum_table td.subject a { - font-size: 1.2em; - font-weight: bold; -} - -#lichess_forum table.forum_table td .description { - margin-top: 0.5em; - display: block; -} - -#lichess_forum th { - font-weight: bold; - color: #A0A0A0; -} - -#lichess_forum h1 { - font-size: 1.4em; - margin-bottom: 0.5em; -} -.forum_baseline { - margin-bottom: 1em; -} - -#lichess_forum table.forum_table tr:nth-child(odd) { - background: #F7F7F7; -} -#lichess_forum table.forum_table tr.thead { - background: #fff; -} - -div.post { - font-size: 1.2em; - padding: 2em 24px 1em 24px; - border-top: 1px solid #D4D4D4; - margin-top: 1em; - position: relative; -} -div.post.erased { - background: rgba(128,128,128,0.2); - opacity: 0.5; -} -div.post.erased .message { - font-style: italic; - text-align: center; - margin: 0; -} -div.post:last-child { - border-bottom: 1px solid #D4D4D4; - padding-bottom: 2em; - margin-bottom: 2em; -} - -div.post .anchor { - position: absolute; - top: 2em; - right: 24px; -} - -div.post .author { - font-size: 1.2em; - font-weight: bold; - float: left; -} -div.post .author a { - height: 16px; - display: block; -} - -div.post time { - font-size: 0.8em; - font-style: italic; - color: #aaa; - margin-top: 0.3em; - margin-left: 1em; - float: left; -} - -div.post .message { - margin-top: 1.5em; - color: #555; - line-height: 1.5em; - cursor: initial; -} - -form.edit-post-form { - display: none; - margin-top: 1.5em; -} -form.edit-post-form textarea { - width: 100%; - box-sizing: border-box; - border: 1px solid #D4D4D4; - padding: 0.5em; -} -body.dark form.edit-post-form textarea { - border-color: #3d3d3d; -} -div.post .edit-buttons { - text-align: right; - margin-top: 0.5em; -} -div.post .edit-buttons a { - margin-right: 1em; -} -div.post .post-edited { - font-size: 0.8em; - color: #aaa; - margin-top: 0.3em; - margin-left: 1em; - float: left; -} - -div.topicReply, -div.category .description { - margin: 1em 24px 0 24px; -} - -.postNewTitle { - font-size: 1.5em; - font-style: italic; -} - -#lichess_forum form.create-topic { - margin: 20px; -} -#lichess_forum form.reply { - margin-top: 2em; -} -#lichess_forum form.reply label[for=form3-text] { - display: none; -} - -div.pagination a, div.pagination span { - font-size: 1.1em; - font-weight: bold; - border-radius: 5px; - margin: 0 2px; -} -div.pagination span { - color: #aaa; - padding: 0.1em 0.3em; -} - -div.bar { - margin-top: 1em; - width: 100%; -} -div.bar .button { - float: left; - margin-left: 24px; -} -div.bar div.pagination { - margin: 0.4em 24px 0 0; - float: right; -} - -#lichess_forum div.topic form.mod { - float: right; - margin-right: 24px; -} -#lichess_forum .unsub.on .off, -#lichess_forum .unsub.off .on { - display: none; -} - -.textcomplete-dropdown { - border: 1px solid #ccc; - box-shadow: 0 0.5px 5px rgba(0, 0, 0, 0.25), 0 0.5px 8px rgba(0, 0, 0, 0.15); - background: #fff; -} - -.textcomplete-dropdown li { - list-style: none; - border-top: 1px solid #dfdfdf; - padding: 0.5em; - min-width: 100px; - font-size: 1.2em; - font-weight: bold; - cursor: pointer; -} -.textcomplete-dropdown li.textcomplete-header, -.textcomplete-dropdown li.textcomplete-footer { - display: none; -} -.textcomplete-dropdown li:hover, -.textcomplete-dropdown .active { - background-color: #f0f0f0; -} - -body.dark .textcomplete-dropdown { - box-shadow: 0 1px 2px #000; - background: #343434; -} -body.dark .textcomplete-dropdown, -body.dark .textcomplete-dropdown li { - border-color: #3d3d3d; -} - -body.dark .textcomplete-dropdown li:hover, -body.dark .textcomplete-dropdown .active { - background-color: #3e3e3e; -} - -a.sticky, -body.dark a.sticky { - color: #759900; -} - -a.sticky > span { - margin-right: 0.6em; -} diff --git a/public/stylesheets/fpmenu.css b/public/stylesheets/fpmenu.css deleted file mode 100644 index c369792496..0000000000 --- a/public/stylesheets/fpmenu.css +++ /dev/null @@ -1,235 +0,0 @@ -body.fpmenu > div.content { - display: none; -} -body.fpmenu #top { - z-index: 5001; -} -body.fpmenu #friend_box { - display: none; -} -#fpmenu { - position: fixed; - left: 0; - top: 0; - right: 0; - bottom: 0; - z-index: 5000; - width: 100%; - height: 100%; - font-size: 14px; - display: none; - background: #fff; -} -body.fpmenu #fpmenu { - display: block; -} -#fpmenu section { - margin-top: 50px; -} -#fpmenu h2 { - font-family: 'Roboto'; - font-weight: 300; - font-size: 24px; - color: #2a2a2a; - text-transform: uppercase; - margin-bottom: 9px; -} -#fpmenu .inner { - width: 1005px; - margin: 0 auto; - position: relative; - top: 50%; - transform: translateY(-50%); -} -#fpmenu .body { - overflow: hidden; -} -#fpmenu .user, -#fpmenu .anon { - float: left; - width: 400px; - border-right: 1px solid #cfcfcf; - padding: 0 40px 20px 0; -} -#fpmenu .perf { - display: inline-block; - text-align: left; - width: 49%; - margin: 15px 0; - line-height: 1.2em; -} -#fpmenu .perf::before { - color: #C4A86F; - font-size: 42px; - float: left; - margin-right: 8px; - opacity: 0.8; -} -#fpmenu .perf h3 { - margin: 0 0 5px 0; - color: #d59120; -} -#fpmenu .perf.nope { - opacity: 0.5; -} -#fpmenu .perf strong { - font-family: 'Roboto'; - font-weight: 300; - font-size: 18px; - color: #2a2a2a; -} -#fpmenu .perf .progress { - opacity: 0.6; -} -#fpmenu .anon section { - width: 322px; -} -#fpmenu .anon h2 { - margin-bottom: 22px; -} -#fpmenu .login { - -webkit-appearance: none; - line-height: 47px; - padding: 0 15px; - outline: none; - text-transform: uppercase; - text-align: center; - background: #d59120; - border: none; - color: #fff; - font-weight: bold; - opacity: 0.6; - cursor: pointer; -} -#fpmenu .login:hover { - opacity: 0.65; -} -#fpmenu .forgot { - font-size: 0.8em; - margin-top: 4px; - text-align: center; -} -#fpmenu .forgot a { - color: inherit; - opacity: 0.6; -} -#fpmenu a.signup { - display: block; - line-height: 47px; - padding: 0 15px; - background: #fff; - border: 1px solid #d8d8d8; - color: inherit; - text-transform: uppercase; - text-align: center; - transition: 0.13s; -} -#fpmenu a.signup:hover { - background: #d59120; - color: #fff; -} -#fpmenu .menu { - margin-left: 540px; - overflow: hidden; -} -#fpmenu .menu section { - float: left; - width: 55%; -} -#fpmenu .menu section:nth-child(even) { - width: 45%; -} -#fpmenu section a { - color: #d59120; - display: block; - padding: 7px 0; -} -#fpmenu section .disabled { - opacity: 0.5; - display: block; - padding: 9px 0; -} -#fpmenu .footer { - width: 100%; - padding: 15px 0; - margin-left: -20px; - text-align: center; - font-size: 12px; - opacity: 0.8; - transition: opacity 0.3s; - transform: translateZ(0); -} -#fpmenu .footer:hover { - opacity: 1; -} -#fpmenu .footer a { - display: inline-block; - padding: 5px 12px; - transition: 0.3s; -} -#fpmenu .footer a:hover { - transform: translateY(-2px); -} -@media (max-width: 970px) { - #fpmenu { - position: relative; - } - #fpmenu .inner { - top: 0; - transform: none; - width: auto; - } - #fpmenu .body { - padding-left: 13%; - } - #fpmenu .user { - display: none; - } - #fpmenu .anon { - border: none; - float: none; - margin: auto; - padding-bottom: 0; - } - #fpmenu .menu { - margin: auto; - width: 500px; - } -} -@media (max-width: 1020px) { - #top { - width: calc(100% - 25px); - } -} -@media (max-width: 520px) { - #fpmenu .body { - padding-left: 10px; - } -} - -body.dark #fpmenu { - background: #1c2328; - color: #aeaeae; -} -body.dark #fpmenu h2 { - color: #aeaeae; -} -body.dark #fpmenu .user, -body.dark #fpmenu .anon { - border-color: #444; -} -body.dark #fpmenu a.signup { - background: #1c2328; - border: 1px solid #555; - color: inherit; -} -body.dark #fpmenu a.signup:hover { - background: #d59120; - color: #fff; -} -body.dark #fpmenu .perf strong { - color: #aeaeae; -} -body.dark #fpmenu .perf::before { - color: #8b6523; -} diff --git a/public/stylesheets/gamebook.edit.css b/public/stylesheets/gamebook.edit.css deleted file mode 100644 index 6ffd0abb5e..0000000000 --- a/public/stylesheets/gamebook.edit.css +++ /dev/null @@ -1,73 +0,0 @@ -.gb_edit .lichess_game .lichess_ground { - margin-bottom: -409px; -} -.gb_edit .gamebook_wrap { - height: 500px; -} -.gb_edit .gamebook { - background: #e0e0e0; - display: flex; - flex-flow: column; -} -.gb_edit .gamebook .deviation, -.gb_edit .gamebook .hint { - display: flex; - flex-flow: column; -} -.gb_edit .gamebook label { - display: block; - padding: 0 0 8px 10px; -} -.gb_edit .gamebook textarea { - resize: vertical; - width: 100%; - box-sizing: border-box; - height: 10em; - border-width: 1px 0; - padding: 5px; -} -.gb_edit .gamebook .hint textarea { - height: 7em; -} -.gb_edit .gamebook .legend { - display: flex; - border-bottom: 1px solid #ccc; - min-height: 3.5em; -} -.gb_edit .gamebook .legend i { - flex: 0 0 50px; - font-size: 26px; - opacity: 0.7; - display: flex; - align-items: center; - justify-content: center; -} -.gb_edit .gamebook .legend.clickable:hover { - cursor: pointer; - background: #3893E8; - color: #fff; -} -.gb_edit .gamebook .legend.clickable:hover i { - opacity: 0.9; -} -.gb_edit .gamebook .legend p { - flex: 1 1 100%; - padding: 8px 10px; - display: flex; - align-items: center; -} -.gb_edit .gamebook .todo i { - background: #dc322f; - color: #fff; -} -.gb_edit .gamebook .done i { - background: #759900; -} - -body.dark .gb_edit .gamebook { - background: #262626; -} -body.dark .gb_edit .gamebook textarea, -body.dark .gb_edit .gamebook .legend { - border-color: #3d3d3d; -} diff --git a/public/stylesheets/gamebook.play.css b/public/stylesheets/gamebook.play.css deleted file mode 100644 index 3d5628bf7b..0000000000 --- a/public/stylesheets/gamebook.play.css +++ /dev/null @@ -1,198 +0,0 @@ -.gb_play .lichess_game .lichess_ground { - margin-bottom: 0px; -} -.gb_play .gamebook { - height: 100%; - display: flex; - flex-flow: column; - justify-content: flex-end; - font-size: 1.3em; -} -.gb_play .comment { - font-size: 1.1em; - background: #fff; - border-radius: 10px; - position: relative; - border: 1px solid #aaa; - display: flex; - flex-flow: column; - /* - fixes firefox overflow when comment is long - * https://stackoverflow.com/questions/28636832/firefox-overflow-y-not-working-with-nested-flexbox - */ - min-height: 0; -} -.gb_play .comment::after { - position: absolute; - content: ''; - bottom: -9px; - right: 20%; - width: 15px; - height: 15px; - background: #fff; - border-right: 1px solid #aaa; - border-bottom: 1.5px solid #aaa; - transform: skew(45deg) rotate(45deg); - z-index: 1; -} -.gb_play .comment.hinted::after { - background: #3893E8!important; -} -.gb_play .comment .content { - z-index: 2; - overflow-y: auto; - padding: 12px; - min-height: 2.5em; -} -.gb_play .comment div.hint { - padding: 10px 12px; - background: #3893E8; - color: #fff; - cursor: pointer; - border-radius: 0 0 5px 5px; - font-size: 0.9em; - z-index: 2; -} -.gb_play .comment a.hint { - padding: 0 0 10px 12px; - color: #3893E8; - font-size: 0.8em; -} - -.gb_play .floor { - margin-top: 20px; - flex: 0 0 120px; - display: flex; -} -.gb_play .mascot { - flex: 0 0 120px; - margin-left: 20px; -} -.gb_play .feedback { - flex: 1 1 100%; - height: 120px; - text-align: center; - display: flex; - flex-flow: column; - justify-content: center; -} -.gb_play .feedback.info { - background: #e0e0e0; - font-size: 1.6em; -} -.gb_play .feedback.good.init { - visibility: hidden; -} -.gb_play .feedback.act { - font-size: 2em; - color: #fff; - cursor: pointer; - opacity: 0.85; - transition: 0.13s; - border-radius: 7px; -} -.gb_play .feedback.act:hover { - opacity: 1; -} -.gb_play .feedback.act.com span { - animation: rubberBand 8s infinite; -} -.gb_play .feedback.play { - font-size: 0.8em; - text-align: left; -} -.gb_play .feedback.play strong { - font-size: 1.5em; -} -.gb_play .feedback.play > div { - display: flex; - align-items: center; - margin: 0 10px; -} -.gb_play .feedback.play .no-square { - flex: 0 0 64px; - height: 64px; - margin-right: 10px; -} -.gb_play .feedback .instruction > * { - display: block; -} -.is3d .gb_play .feedback.play div.no-square { - height: 82px; -} -.gb_play .feedback.play piece { - position: inherit; - display: block; - width: 100%; - height: 100%; -} -.gb_play .feedback.bad { - background: #dc322f; -} -.gb_play .feedback.good { - background: #639B24!important; - color: #fff; -} -.gb_play .feedback.end { - flex-flow: row; - font-size: 0.8em; -} -.gb_play .feedback.end a { - flex: 1 1 100%; - background: rgba(56,147,232,0.8); - font-size: 1.2em; - color: #fff; - display: flex; - flex-flow: column; - align-items: center; - text-align: center; - padding: 10px; - border-left: 1px solid rgba(255,255,255,0.3); - line-height: 1.2em; - transition: 0.13s; -} -.gb_play .feedback.end a::before { - font-size: 2.2em; - margin: 12px 0 8px 0; -} -.gb_play .feedback.end a:first-child { - border-radius: 7px 0 0 7px; -} -.gb_play .feedback.end a:last-child { - border-radius: 0 7px 7px 0; -} -.gb_play .feedback.end a:hover { - background: #3893E8; -} -.gb_buttons .button { - margin-left: 10px; -} -.gb_play kbd { - padding: 4px 5px; - margin: 15px auto 0 auto; - font-family: monospace; - font-size: 12px; - line-height: 10px; - color: #444; - background-color: #fcfcfc; - border: solid 1px #ccc; - border-bottom-color: #bbb; - border-radius: 3px; - box-shadow: inset 0 -1px 0 #bbb; -} - -body.dark .gb_play .comment, -body.dark .gb_play .comment::after { - background: #404040; - color: #f0f0f0; -} -body.dark .gb_play .comment, -body.dark .gb_play .comment::after { - border-color: #666; -} -body.dark .gb_play .feedback.info { - background: #303030; -} -body.dark .gb_play .feedback.end a { - border-left: 1px solid rgba(0,0,0,0.2); -} diff --git a/public/stylesheets/gamestats.css b/public/stylesheets/gamestats.css deleted file mode 100644 index 18333a651a..0000000000 --- a/public/stylesheets/gamestats.css +++ /dev/null @@ -1,30 +0,0 @@ -div.content_box .title { - font-size: 1.8em; - color: #666; - font-weight: normal; - margin-bottom: 0.5em; -} -div.content_box .section-title { - font-size: 1.6em; - color: #999; - font-weight: normal; - font-style: italic; - margin: 1.5em 0; - border-top: 1px solid #dadada; - padding: 0.5em 0; - text-align: right; -} -div.content_box .chart-title { - font-size: 1.4em; - color: #666; - font-weight: normal; - margin-bottom: 0.5em; -} -div.content_box .half { - float: left; - width: 49%; - margin-right: 2%; -} -div.content_box .half.last { - margin-right: 0; -} diff --git a/public/stylesheets/home.css b/public/stylesheets/home.css deleted file mode 100644 index 501219a403..0000000000 --- a/public/stylesheets/home.css +++ /dev/null @@ -1,817 +0,0 @@ -#lichess { - position: relative; -} -div.lobby_and_ground { - display: flex; - position: relative; -} -#start_buttons { - padding-left: 15px; - width: 280px; - display: flex; - flex-flow: column nowrap; - justify-content: center; - position: relative; -} -#start_buttons a { - margin: 1.2em 0; - font-size: 1.3em; - padding: 1em; - text-align: center; - display: block; - letter-spacing: -1px; -} -#start_buttons a.disabled { - opacity: 0.2; -} - -#lobby_playban, -#lobby_current_game { - box-sizing: border-box; - position: absolute; - width: 512px; - height: 512px; - text-align: center; - background: rgba(255,255,255,0.8); - font-size: 1.1em; -} -body.dark #lobby_playban, -body.dark #lobby_current_game { - background: rgba(0,0,0,0.8); -} -#lobby_playban h2, -#lobby_current_game h2 { - font-size: 1.5em; - line-height: 2.5em; - margin-top: 1em; -} -#lobby_playban a { - color: #3893E8; -} -#lobby_playban ul { - margin: 10px auto; - display: inline-block; - text-align: left; -} -#lobby_playban ul li { - list-style: disc outside; - font-size: 1.1em; -} -.current_game #hooks_wrap { - visibility: hidden; -} -/********** HOOKS **********/ - -#hooks_wrap { - position: relative; - width: 510px; - min-width: 510px; - min-height: 510px; - border: 1px solid #ccc; - background: #f0f0f0 url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMy41MjkgMzMuNTA0Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNS4yNS02LjI0NikiIG9wYWNpdHk9Ii4xIiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxLjUiPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im0yMiAxMGMxMC41IDEgMTYuNSA4IDE2IDI5aC0yM2MwLTkgMTAtNi41IDgtMjEiLz48cGF0aCBkPSJtMjQgMThjLjM4IDIuOTEtNS41NSA3LjM3LTggOS0zIDItMi44MiA0LjM0LTUgNC0xLjA0Mi0uOTQgMS40MS0zLjA0IDAtMy0xIDAgLjE5IDEuMjMtMSAyLTEgMC00IDEtNC00IDAtMiA2LTEyIDYtMTIgMCAwIDEuODktMS45IDItMy41LS43My0uOTk0LS41LTItLjUtMyAxLTEgMyAyLjUgMyAyLjVoMmMwIDAgLjc4LTEuOTkyIDIuNS0zIDEgMCAxIDMgMSAzIi8+PC9nPjxnIGZpbGw9IiMwMDAiPjxwYXRoIGQ9Im05LjUgMjUuNWEuNSAuNSAwIDEgMSAtMSAwIC41IC41IDAgMSAxIDEgMHoiLz48cGF0aCBkPSJtMTUgMTUuNWEuNSAxLjUgMCAxIDEgLTEgMCAuNSAxLjUgMCAxIDEgMSAweiIgdHJhbnNmb3JtPSJtYXRyaXgoLjg2Ni41LS41Ljg2NiA5LjY5My01LjE3MykiLz48L2c+PC9nPjwvc3ZnPg=='); - background-size: 100% 100%; -} -body.dark #hooks_wrap { - background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMy41MjkgMzMuNTA0Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNS4yNS02LjI0NikiIG9wYWNpdHk9Ii4xIiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxLjUiPjxnIGZpbGw9IiMwMDAiPjxwYXRoIGQ9Im0yMiAxMGMxMC41IDEgMTYuNSA4IDE2IDI5aC0yM2MwLTkgMTAtNi41IDgtMjEiLz48cGF0aCBkPSJtMjQgMThjLjM4IDIuOTEtNS41NSA3LjM3LTggOS0zIDItMi44MiA0LjM0LTUgNC0xLjA0Mi0uOTQgMS40MS0zLjA0IDAtMy0xIDAgLjE5IDEuMjMtMSAyLTEgMC00IDEtNC00IDAtMiA2LTEyIDYtMTIgMCAwIDEuODktMS45IDItMy41LS43My0uOTk0LS41LTItLjUtMyAxLTEgMyAyLjUgMyAyLjVoMmMwIDAgLjc4LTEuOTkyIDIuNS0zIDEgMCAxIDMgMSAzIi8+PC9nPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im05LjUgMjUuNWEuNSAuNSAwIDEgMSAtMSAwIC41IC41IDAgMSAxIDEgMHoiLz48cGF0aCBkPSJtMTUgMTUuNWEuNSAxLjUgMCAxIDEgLTEgMCAuNSAxLjUgMCAxIDEgMSAweiIgdHJhbnNmb3JtPSJtYXRyaXgoLjg2Ni41LS41Ljg2NiA5LjY5My01LjE3MykiLz48L2c+PC9nPjwvc3ZnPg=='); -} -#hooks_wrap .lobby_box { - position: relative; - min-height: 510px; -} -#hooks_wrap .lobby_box.seeks { - max-height: 510px; -} -#hooks_wrap .lobby_box .no_hooks { - text-align: center; - line-height: 2em; - margin-top: 80px; - font-size: 1.3em; -} -#hooks_wrap .tabs { - position: absolute; - top: -23px; - left: 0; - height: 23px; - line-height: 22px; - width: 512px; - text-align: center; - display: flex; - justify-content: center; -} -#hooks_wrap .tabs a { - padding: 0 8px; - margin-right: 3px; - border: 1px solid #ccc; - background: #dadada; - transition: 0.13s; - white-space: nowrap; - overflow: hidden; -} -#hooks_wrap .tabs a:hover { - background: #f0f0f0; -} -#hooks_wrap .tabs a.active { - background: #f0f0f0; - font-weight: bold; - border-bottom-color: #f0f0f0; - border-top: 2px solid #d85000; - margin-top: -1px; -} -#hooks_wrap .tabs a.glow { - animation: fbt-glowing 1s ease-in-out infinite; -} -#hooks_wrap .tabs .unread { - margin-left: 5px; -} -#hooks_wrap .mode_toggle, -#hooks_wrap .filter_toggle { - position: absolute; - top: 10px; - cursor: pointer; - z-index: 2; - font-size: 1.3em; - opacity: 0.7; - transition: 0.13s; -} -#hooks_wrap .mode_toggle { - left: 15px; -} -#hooks_wrap .filter_toggle { - right: 15px; -} -#hooks_wrap .filter_toggle .number { - margin-left: 3px; - font-size: 0.8em; -} -#hooks_wrap .mode_toggle:hover, -#hooks_wrap .filter_toggle:hover { - opacity: 1; -} -#hooks_wrap .hook_filter { - padding: 10px 20px; - background: rgba(255,255,255,0.5); - height: 510px; - box-sizing: border-box; -} -body.dark #hooks_wrap .hook_filter { - background: rgba(0,0,0,0.5); -} -#hooks_wrap .hook_filter table { - width: 100%; - white-space: nowrap; -} -#hooks_wrap .hook_filter td { - padding: 20px 0; -} -#hooks_wrap .hook_filter td:first-child { - font-size: 1.1em; - padding-right: 30px; - width: 120px; - white-space: normal; -} -#hooks_wrap .hook_filter .checkable { - padding: 4.3px 0; - color: #444; -} -#hooks_wrap .hook_filter .checkable { - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -#hooks_wrap .hook_filter tr.variant td:last-child { - display: flex; - flex-flow: row wrap; -} -#hooks_wrap .hook_filter tr.variant .checkable { - width: 33.3%; -} -#hooks_wrap .hook_filter label.hover, -#hooks_wrap .hook_filter input { - vertical-align: middle; - cursor: pointer; -} -#hooks_wrap .hook_filter .range { - display: block; - text-align: center; -} -#hooks_wrap .hook_filter .actions { - margin-top: 20px; - text-align: right; -} -#hooks_wrap .hook_filter .actions button { - padding: 6px; - margin-left: 3px; -} -#hooks_wrap .table_wrap { - text-shadow: 0 1px 0 #FFF; - width: 100%; - min-height: 78px; - overflow: hidden; -} -#hooks_wrap .table_wrap th { - padding: 14px 12px; - border-bottom: transparent; - font-family: 'Roboto'; - font-weight: 300; -} -#hooks_wrap .table_wrap th.sortable { - cursor: pointer; -} -#hooks_wrap .table_wrap th.sortable:hover, -#hooks_wrap .table_wrap th.sort { - font-weight: normal; -} -#hooks_wrap .table_wrap th.sort .is:before { - opacity: 0.7; - margin-right: 3px; - content: "R"; -} -#hooks_wrap .table_wrap th.player { - width: 110px; -} -#hooks_wrap .table_wrap td { - padding: 9px 12px; - border-bottom: 1px solid #ccc; - cursor: pointer; - white-space: nowrap; - overflow: hidden; - background: rgba(255, 255, 255, 0.6); -} -#hooks_wrap .table_wrap tbody.stepping { - opacity: 0.7; -} -#hooks_wrap .table_wrap tr.disabled { - opacity: 0.4; -} -#hooks_wrap .table_wrap tr.disabled td { - cursor: default; - background: transparent!important; - border-color: transparent!important; -} -#hooks_wrap .table_wrap tr.cancel td { - background: rgba(200, 255, 200, 0.7); -} -#hooks_wrap .table_wrap tr.join:hover td { - background: rgba(191, 231, 255, 0.7); -} -#hooks_wrap .table_wrap td:first-child { - width: 16px; -} -#hooks_wrap .table_wrap td:first-child span { - display: block; - padding: 0; - width: 16px; - height: 16px; - opacity: 0.7; -} -#hooks_wrap .table_wrap .varicon::before { - margin-right: 8px; - line-height: 12px; - font-size: 20px; - opacity: 0.7; -} -#hooks_wrap .table_wrap tr:hover .varicon::before, -#hooks_wrap .table_wrap tr:hover td:first-child span { - opacity: 1; -} -#hooks_wrap .table_wrap tr.disabled:hover .varicon::before, -#hooks_wrap .table_wrap tr.disabled:hover td:first-child span { - opacity: 0.7; -} -#hooks_wrap .table_wrap tr.variants td { - text-align: center; - padding: 3px 0; - background: none; - text-transform: uppercase; - letter-spacing: 3px; -} -#hooks_wrap .create { - margin-top: 20px; - text-align: center; -} -#hooks_wrap .hooks_chart { - position: absolute; - top: 0; - left: 0; -} -#hooks_wrap .hooks_chart > span.label { - font-size: 9px; - position: absolute; - left: 3px; - bottom: 1px; - text-shadow: 0 0 3px #fff; - font-weight: bold; -} -#hooks_wrap .hooks_chart > div.grid { - position: absolute; - left: 0; - bottom: 0; -} -#hooks_wrap .hooks_chart > div.grid.horiz { - width: 100%; - border-top: 1px dashed #ccc; -} -#hooks_wrap .hooks_chart > div.grid.vert { - height: 100%; - border-right: 1px dashed #ccc; -} -#hooks_wrap .hooks_chart .canvas { - position: relative; - width: 510px; - height: 510px; -} -#hooks_wrap .hooks_chart .plot { - position: absolute; - cursor: pointer; - z-index: 1; - font-size: 1.4em; - text-shadow: 0 0 3px #fff; - opacity: 0.7; - transition: 0.5s; - transform: scale(1); -} -#hooks_wrap .hooks_chart .plot.rated { - opacity: 0.9; - color: #d59120!important; -} -#hooks_wrap .hooks_chart .plot.cancel { - opacity: 0.9; - color: #0b9c1e!important; -} -#hooks_wrap .hooks_chart .plot.new { - transform: translateY(-7px); - opacity: 0; -} -#hooks_wrap .hooks_chart .plot:hover { - z-index: 2; - opacity: 1; - transform: scale(1.2); -} -#hook { - display: none; - color: #444; - box-shadow: 0 0 9px #333; - background: #d0d0d0; - cursor: default; - position: absolute; - z-index: 900000; -} -#hook .inner { - display: inline-block; - text-align: center; - font-size: 1.25em; - padding-bottom: 5px; -} -#hook .opponent { - background: #666; - color: #eee; - min-width: 120px; - padding: 5px; - margin-bottom: 5px; -} -#hook .opponent, -#hook span { - display: block; -} - -#hooks_wrap .redir { - background: rgba(128,128,128,0.5); - display: flex; -} -#hooks_wrap .redir .spinner { - width: 100px; - height: 100px; -} -/*********** POOLS *********/ - -#hooks_wrap .pools { - padding: 12px 12px 0 12px; - max-height: 510px; - box-sizing: border-box; - display: flex; - flex-flow: row wrap; - justify-content: space-between; - font-family: Roboto; - -webkit-user-select: none; -} -#hooks_wrap .pools > div { - margin-bottom: 12px; - flex: 0 0 31%; - height: 152px; - cursor: pointer; - background: rgba(255,255,255,0.7); - border: 1px solid #ccc; - display: flex; - flex-flow: column; - justify-content: center; - align-items: center; - border-radius: 4px; - transition: opacity 0.7s; -} -body.dark #hooks_wrap .pools > div { - background: rgba(20,20,20,0.5); - border: 1px solid #3d3d3d; -} -#hooks_wrap .pools .active { - background: #fff; - border-radius: 0; - box-shadow: 0 2px 5px rgba(0,0,0,0.3); -} -body.dark #hooks_wrap .pools .active { - background: #202020; - box-shadow-color: #000; -} -#hooks_wrap .pools .transp { - opacity: 0.5; -} -#hooks_wrap .pools .spinner { - margin: 14px 0 0 0; -} -#hooks_wrap .pools .clock { - display: block; - font-size: 2.5em; - line-height: 1.5em; - letter-spacing: 5px; -} -#hooks_wrap .pools .perf, -#hooks_wrap .pools .range { - font-size: 1.5em; -} -#hooks_wrap .pools .custom { - font-size: 1.5em; -} -#hooks_wrap .pools > div:hover { - background: rgba(191, 231, 255, 0.7); -} - -/*********** MISC *********/ - -#site_header .board_left { - position: relative; - height: 515px; - display: flex; - flex-flow: column nowrap; -} -#featured_game { - margin-top: 12px; -} -div.undertable { - width: 512px; -} -.blog.undertable .undertable_inner { - height: auto; - padding: 5px 5px 0 5px; -} -.blog.undertable .undertable_inner:hover { - overflow: hidden; -} -.blog.undertable .post { - overflow: hidden; - display: flex; - justify-content: space-between; - align-items: center; -} -.blog.undertable .post .text { - flex: 1 1 100%; -} -.blog.undertable .post img { - height: 48px; - width: 48px; - margin: 3px 20px 3px 3px; -} -.blog.undertable .post .title { - font-weight: bold; -} -.blog.undertable time { - margin-top: 10px; - float: right; - font-weight: 100; - line-height: 2; - opacity: 0.6; -} -.leaderboards { - margin-bottom: 15px; - display: flex; - justify-content: space-between; - white-space: nowrap; -} -.leaderboards > div { - flex: 0 0 48.5%; - max-width: 48.5%; -} -.leaderboards td:first-child { - max-width: 135px; - overflow: hidden; - text-overflow: ellipsis; -} -.leaderboards td:last-child { - text-align: right; -} -#lichess .enterable_list { - height: auto; - max-height: 193px; -} -#enterable_simuls td { - padding: 10px 5px; -} -#lichess .enterable_list td:first-child { - padding-left: 1em; - overflow: hidden; - max-width: 250px; -} -#enterable_tournaments td:last-child { - padding-right: 10px; -} -#lichess .enterable_list td.name span { - font-size: 17px; - letter-spacing: -5px; -} -#lichess .enterable_list td.name span:last-child { - margin-right: 10px; -} -#lichess .enterable_list td.name a { - font-weight: bold; - white-space: nowrap; - color: #d59120; -} -#lichess .enterable_list td:last-child { - width: 20px; -} -#lichess .enterable_list .rated { - color: #d59120; -} -div.new_posts li { - margin: 0.6em 0; - padding-left: 9px; - line-height: 14px; - white-space: nowrap; -} -div.new_posts li span.extract { - font-family: 'Roboto'; - font-weight: 300; -} -#daily_puzzle { - width: 224px; - position: absolute; - top: 527px; - left: 527px; -} -#daily_puzzle > div.vstext { - text-align: center; -} -div.lichess_overboard .color_submits .spinner { - width: 70px; - height: 70px; - margin: 10px auto 20px auto; -} -#nb_games_in_play { - margin-bottom: 10px; -} -#nb_games_in_play span { - font-weight: bold; -} -#streams_on_air a.stream { - display: block; - margin: 5px 0 5px -30px; - font-size: 0.9em; - font-family: 'Roboto'; - font-weight: 300; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; -} -#streams_on_air a.stream span { - font-family: 'Noto Sans'; - font-weight: bold; -} -#streams_on_air a.stream.highlight span { - color: #d59120; -} -#streams_on_air a.stream span:before { - font-size: 1.5em; -} -.tour_spotlight { - display: flex; - flex: 0 0 auto; - align-items: center; - margin: 5px 0 5px -30px; - padding: 5px; - border-radius: 2px; - opacity: 0.8; - transition: 0.13s; - white-space: nowrap; - overflow: hidden; - background: #ddd; - text-shadow: 0 1px 1px #fff; -} -.tour_spotlight.invert, -.tour_spotlight.event_spotlight, -.tour_spotlight:hover { - color: #fff!important; - background: #3893E8; - text-shadow: none; -} -.tour_spotlight:hover { - opacity: 1; -} -.tour_spotlight::before { - font-size: 33px; - float: left; - margin: 2px 6px 0 0; -} -.tour_spotlight .img { - flex: 0 0 40px; - margin: 0 10px 0 5px; -} -.tour_spotlight img.img { - width: 40px; - filter: brightness(9); - filter: brightness(9); -} -.tour_spotlight i.img, -.tour_spotlight .img.icon { - margin: 0 5px 0 0; -} -.tour_spotlight i.img::before { - color: #fff; - font-size: 40px; - text-shadow: 1px 1px 3px rgba(0,0,0,0.3); -} -.tour_spotlight .content { - display: block; -} -.tour_spotlight > span { - display: block; -} -.tour_spotlight span.name { - font-size: 14px; -} -.tour_spotlight span.headline { - display: block; - font-size: 10px; - margin-bottom: -3px; -} -.tour_spotlight span.more { - font-size: 10px; -} -.tour_spotlight span.more time { - margin-left: 3px; -} -.tour_spotlight.little .img { - flex: 0 0 28px; - height: 28px; - margin: 0 7px 0 3px; -} -.tour_spotlight.little i.img::before { - font-size: 28px; -} -.tour_spotlight.little { - margin: 5px 0 2.5px -30px; - padding: 5px; -} -.tour_spotlight span.name { - margin-top: 1px; - font-size: 13px; - line-height: 13px; - display: block; -} -body.dark a.tour_spotlight { - background: #444; - color: #ccc; - text-shadow: 0 0 2px rgba(0,0,0,0.6); -} -body.dark .tour_spotlight.invert, -body.dark .tour_spotlight.event_spotlight, -body.dark .tour_spotlight:hover { - background: #4166a0; -} -body.dark .tour_spotlight .img { - opacity: 0.5; -} -body.dark .tour_spotlight:hover .img { - opacity: 1; -} -#timeline { - flex: 1 1; - margin-top: 10px; - border-top: 1px solid #e4e4e4; - margin-left: -30px; - width: 230px; - font-size: 0.9em; - overflow: hidden; -} -#timeline:hover { - overflow-y: auto; -} -@media (max-width: 1070px) { - #timeline { - margin-left: 0; - width: 200px; - } - #featured_game { - visibility: hidden; - } -} -#timeline .entry { - padding: 8px 0; - border-bottom: 1px solid #e4e4e4; - font-family: 'Roboto'; - font-weight: 300; -} -#timeline time { - font-size: 0.9em; -} -#timeline a { - font-family: 'Noto Sans'; - text-decoration: none; -} -#timeline .entry:hover a { - color: #3893E8; -} -#timeline a.user_link { - padding-left: 0; -} -#timeline .links { - width: 100%; - text-align: right; -} -#timeline a.more { - margin: 5px; - font-weight: normal; - display: block; -} -.about-side { - margin-top: 15px; -} -.donation { - display: flex; - font-size: 1.3em; - line-height: 1.2em; - border: 1px solid #ccc; - box-sizing: border-box; - background: #fff; -} -.donation a { - flex: 0 0 auto; - position: relative; - box-sizing: border-box; - width: 50%; - height: 60px; -} -.donation strong { - color: #3893E8; - font-weight: normal; - display: block; - margin: 11px 0 1px 0; -} -.donation span { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - display: block; - opacity: 0.8; - font-size: 0.85em; -} -.donation i { - position: absolute; - top: 0; -} -.donation a:first-child i { - right: 15px; -} -.donation a:last-child i { - left: 15px; -} -.donation i::before { - color: #3893E8; - font-size: 40px; - line-height: 60px; - opacity: 0.8; -} -.donation a:first-child { - border-right: 1px solid #ccc; - text-align: right; - padding-right: 67px; -} -.donation a:last-child { - text-align: left; - padding-left: 67px; -} -.donation a:hover { - background: #3893E8; -} -.donation a:hover, -.donation a:hover *, -.donation a:hover i::before { - transition: 0.13s; - color: #fff; -} -.donation a:hover i::before { - opacity: 1; -} -.about-footer { - width: 512px; - margin-top: 15px; - text-align: center; - opacity: 0.8; -} diff --git a/public/stylesheets/impersonate.css b/public/stylesheets/impersonate.css deleted file mode 100644 index 1d999f1fe9..0000000000 --- a/public/stylesheets/impersonate.css +++ /dev/null @@ -1,30 +0,0 @@ -body { - margin-top: 45px; -} - -#impersonate { - height: 40px; - background: #7f1010; - color: #fff!important; - font-size: 1.3em; - display: flex; - flex-flow: row nowrap; - justify-content: center; - align-items: center; - border-bottom: 1px solid #666; - box-shadow: 0 5px 6px rgba(0, 0, 0, 0.3); - position: fixed; - top: 0; - left: 0; - right: 0; - z-index: 100; -} -#impersonate a, -#impersonate .fbt { - color: #fff!important; -} -#impersonate .actions { - margin-left: 2em; - border-left: 1px solid #f0f0f0; - padding-left: 2em; -} diff --git a/public/stylesheets/import.css b/public/stylesheets/import.css deleted file mode 100644 index 3d6540e019..0000000000 --- a/public/stylesheets/import.css +++ /dev/null @@ -1,46 +0,0 @@ -#import_game .explanation { - margin: 40px 0; - font-size: 1.3em; - text-align: center; -} -#import_game form { - font-size: 1.3em; -} -#import_game form label.pgn { - display: block; - margin-bottom: 1em; -} - -#import_game form label.pgn span { - display: block; - margin-bottom: 1em; -} - -#import_game form textarea { - width: 98%; - height: 25em; - padding: 0.5em; - font-size: 0.9em; -} - -#import_game form .analyse > span { - float: left; - margin-right: 10px; -} -#import_game form .analyse > label { - cursor: pointer; -} - -#import_game button.submit { - margin: 1em auto 0 auto; - display: block; - font-size: 2em; -} - -#import_game form p.error { - margin: 10px 0; - color: red; -} -#import_game form .wait { - display: none; -} diff --git a/public/stylesheets/inquiry.css b/public/stylesheets/inquiry.css deleted file mode 100644 index 2edea358c4..0000000000 --- a/public/stylesheets/inquiry.css +++ /dev/null @@ -1,296 +0,0 @@ -body, #mz_menu .inner { - margin-top: 45px!important; -} - -#inquiry { - height: 40px; - background: #484541; - color: #f0f0f0!important; - display: flex; - flex-flow: row nowrap; - justify-content: space-between; - border-bottom: 1px solid #666; - box-shadow: 2px 5px 6px rgba(0, 0, 0, 0.3); - position: fixed; - top: 0; - left: 0; - right: 0; - z-index: 100; -} -@keyframes octopus { - 50% { transform: scale(1.03); background-color: #4a4a4a; } - 100% { transform: scale(1); background-color: #484541; } -} -#inquiry > .costello { - flex: 0 0 160px; - height: 160px; - width: 160px; - margin: -80px 0 0 -80px; - background: #484541 no-repeat url(../images/icons/octopus.svg); - background-size: 35% 35%; - background-position: 81% 81%; - border-radius: 0 0 50% 0; - border: 2px solid #666; - box-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3); - cursor: pointer; -} -#inquiry > .costello:hover { - animation: octopus 0.5s ease-in-out; -} -#inquiry.hidden { - transition: height 0.3s; - height: 0; - border: none; -} -#inquiry.hidden > div { - display: none; -} -#inquiry.hidden > .costello { - transition: opacity 0.3s; - opacity: 0.5; -} -body.no-inquiry { - transition: margin 0.3s; - margin-top: 0; -} -#inquiry a { - color: #f0f0f0!important; -} -#inquiry .meat { - flex: 1 1 100%; - height: 100%; - display: flex; - flex-flow: row nowrap; - align-items: center; -} -#inquiry h2 .user_link { - font-size: 1.3em; -} -#inquiry .docs { - position: relative; - flex: 0 0 43%; - height: 100%; - margin-left: 10px; - overflow: hidden; - color: #ccc; -} -#inquiry .reports { - flex: 4 1 auto; -} -#inquiry .counter { - margin-left: 0.3em; - flex: 0 0 auto; -} -#inquiry .docs .expendable { - padding: 4px 20px 20px 20px; - background: #555; - position: absolute; - top: 0; - left: 0; - right: 0; -} -#inquiry .docs:hover { - overflow: visible; -} -#inquiry .docs:hover .expendable { - z-index: 2; - border-bottom: 1px solid #666; - box-shadow: 0px 3px 7px rgba(0, 0, 0, 0.4); - max-height: 500px; - overflow-y: auto; -} -#inquiry .doc:not(:last-child) { - padding-bottom: 8px; - border-bottom: 1px dotted #777; - margin-bottom: 8px; -} -#inquiry .docs h2 { - line-height: 35px; - margin-bottom: 5px; -} -#inquiry .doc h3 { - margin: 0; -} -#inquiry .report .atom { - margin-bottom: 0.8em; - border-bottom: 1px solid #777; - padding-bottom: 0.8em; -} -#inquiry .report .atom:last-child { - margin-bottom: 0; - padding-bottom: 0; -} -#inquiry .score { - display: inline-block; - white-space: nowrap; - font-weight: bold; - font-size: 0.9em; - padding: 0.1em 0.5em; - border-radius: 0.3em; -} -#inquiry .score.green { - /* actually blue */ - background-color: rgba(32, 119, 192, 0.4); -} -#inquiry .score.yellow { - background-color: rgba(221, 207, 63, 0.4); -} -#inquiry .score.orange { - background-color: rgba(231, 155, 100, 0.4); -} -#inquiry .score.red { - background-color: rgba(231, 59, 56, 0.4); -} -#inquiry form.note textarea { - width: 100%; - box-sizing: border-box; - resize: vertical; - padding: 5px; - height: 80px; -} -#inquiry form.note .submission { - text-align: right; -} -#inquiry .actions, -#inquiry .links { - margin-right: 10px; - white-space: nowrap; - height: 100%; - display: flex; - flex-flow: row nowrap; - align-items: center; - text-align: center; -} -#inquiry .actions:not(.close), -#inquiry .links { - padding-right: 10px; - border-right: 1px solid #666; -} -#inquiry .actions > form { - height: 100%; -} -#inquiry .fbt { - height: 100%; - color: #f0f0f0!important; - background: transparent; -} -#inquiry .fbt:hover { - background: rgba(56,147,232,0.8); -} -#inquiry .fbt.icon::before, -#inquiry .warn span::before { - font-size: 1.7em; -} -#inquiry .fbt.active { - color: #fff!important; -} -#inquiry .links { - padding: 0 10px; - border-left: 1px solid #666; -} -#inquiry .links a { - padding: 0 13px; -} -#inquiry .links a:hover, -#inquiry .report a:hover { - color: #3893E8!important; -} -#inquiry .process button { - background: #555; - font-size: 1.8em; - padding: 0 25px; -} -#inquiry .process button:hover { - background: #639B24; -} -#inquiry .cancel button { - margin-left: 5px; - font-size: 0.8em; - padding: 0 8px; -} -#inquiry .accuracy { - float: right; -} -#inquiry .dropper { - position: relative; - height: 100%; -} -#inquiry .dropper > span { - display: block; - height: 100%; - padding: 0 10px; -} -#inquiry .dropper > div { - display: none; - position: absolute; - top: 100%; - right: 0; - background: #555; - box-shadow: 2px 5px 6px rgba(0, 0, 0, 0.3); -} -#inquiry .dropper:hover > span { - background: #555; -} -#inquiry .dropper:hover div { - display: block; -} -#inquiry .dropper input { - width: 100%; - text-align: left; -} -#inquiry .dropper > span.icon { - line-height: 40px; -} -#inquiry .dropper.warn input { - padding: 6px 20px; - text-transform: initial; -} - -#inquiry .dropper.counter > span { - font-family: Roboto; - display: flex; - flex-flow: column; - align-items: center; - justify-content: center; -} -#inquiry .dropper.counter.empty > span { - opacity: 0.5; -} -#inquiry .dropper.counter:not(.empty) > span { - background: #555; -} -#inquiry .dropper.counter > span count { - font-size: 1.2em; - display: block; - height: 1.1em; -} -#inquiry .dropper.counter > div { - padding: 4px 20px 20px 20px; -} -#inquiry .dropper.counter > div, -#inquiry .dropper.warn > div { - box-sizing: border-box; - width: 360px; - right: -155px; - max-height: 500px; - overflow-y: auto; -} -#inquiry .history li { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - padding: 6px 0; -} - -#inquiry .switcher { - margin-left: -10px; -} -#inquiry .switcher label { - transform: scale(0.6); -} -#inquiry .switcher label::before { - background-color: #999; -} -#inquiry .switcher .cmn-toggle:checked + label::before { - background-color: rgba(117, 153, 0, 1)!important; -} diff --git a/public/stylesheets/insight.css b/public/stylesheets/insight.css deleted file mode 100644 index 35a788b4f7..0000000000 --- a/public/stylesheets/insight.css +++ /dev/null @@ -1,308 +0,0 @@ -#insight .spinner { - display: none; - position: absolute; - width: 80px; - height: 80px; - top: 238px; - left: 342px; - opacity: 0.7; -} -#insight .loading .spinner { - display: block; -} -#insight .broken { - display: flex; - flex-flow: column; - align-items: center; - text-align: center; - padding: 200px 0; - width: 100%; -} -#insight .broken i { - font-size: 50px; -} - -#insight .chart { - width: 850px; - height: 550px; -} -#insight .loading .chart { - filter: blur(3px); - opacity: 0.5; -} -#insight .chart.empty { - width: 100%; - display: flex; - align-items: center; - justify-content: center; - flex-flow: column; - font-size: 1.5em; - opacity: 0.7; -} -#insight .chart.empty i { - margin-bottom: 30px; - display: block; - font-size: 200px; - opacity: 0.5; -} - -#insight .left-side { - position: absolute; - top: 61px; - left: -239px; - width: 240px; -} -#insight .insight-stale { - margin-top: 10px; -} - -#insight header { - background: #333; - color: #ddd; - height: 60px; -} -#insight header h2 { - font-size: 2em; - line-height: 60px; -} -#insight header h2::before { - font-size: 42px; - vertical-align: top; - line-height: 60px; - margin: 0 10px; -} -#insight header > * { - display: inline-block; -} -#insight header .ms-choice { - background: #444; - color: #ddd!important; - border-color: #666; -} -#insight .meat { - background: #fff; - border: 1px solid #ccc; - border-top: 0; -} -body.dark #insight .meat { - background: #202020; - border-color: #3d3d3d; -} -#insight .axis-form { - float: right; -} -#insight .axis-form .by { - padding: 0 20px; -} -#insight .axis-form .ms-choice { - padding: 30px 10px; - border-width: 0 1px; - border-radius: 0; - font-size: 14px; - transition: 0.15s; -} -#insight .axis-form .ms-choice span { - line-height: 60px; - text-align: center; -} -#insight .axis-form .ms-choice div { - top: 18px; -} -#insight .axis-form .ms-drop { - font-size: 14px; -} -#insight .axis-form .ms-drop ul > li label input { - display: none; -} -#insight .axis-form .ms-drop ul > li.selected label { - background: #d87500!important; - color: #fff!important; -} - -div.panel-tabs a.tab { - background: #e0e0e0; - border: 1px solid #c0c0c0; - height: 20px; - padding: 3px 8px 0 8px; - margin: -1px -1px -1px 0; - display: inline-block; -} -div.panel-tabs a.active { - background: #f5f5f5; - border-bottom-color: #f5f5f5; -} -#insight .presets { - background: #f5f5f5; -} -#insight .presets a { - display: block; - padding: 8px; - transition: background 0.13s; -} -#insight .presets a::before { - opacity: 0.7; - transition: opacity 0.13s; -} -#insight .presets a:hover { - background: #fff; -} -#insight .presets a:hover::before { - opacity: 1; -} -#insight .presets a.active { - color: #d87500!important; -} -#insight .panel-tabs { - position: relative; -} -#insight .clear { - position: absolute; - top: 2px; - right: 8px; -} -#insight .filters .box { - border-bottom-width: 0; -} -#insight .filters .box:last-child { - border-bottom-width: 1px -} -#insight .filters .ms-parent { - display: block; -} -#insight .filters .ms-choice { - padding: 15px 10px; - border-width: 0 1px 1px 0; - background: #e0e0e0; - transition: background 0.13s; -} -#insight .filters .ms-parent:last-child .ms-choice { - border-bottom: 0; -} -#insight .filters .ms-parent.selected .ms-choice { - background: linear-gradient(to right, rgba(56,147,232,0.7) 0px, rgba(56,147,232,0.7) 5px, rgba(0,0,0,0) 5px, rgba(0,0,0,0) 100%); -} -#insight .filters .ms-parent:hover .ms-choice { - background-color: #fff; -} -#insight .filters .ms-choice > span.placeholder { - color: #505050; -} -#insight .filters .ms-choice span { - text-align: right; - line-height: 30px; - background: none; -} -#insight .filters .ms-choice div { - top: 4px; -} -#insight .filters .ms-drop ul > li label input { - margin-right: 5px; - cursor: pointer; -} - -#insight .filters .ms-drop { - margin-left: 99%; - top: 0; - left: 0; -} -#insight .ms-parent, -#insight .ms-parent button { - color: #505050; - -webkit-user-select: none; - -moz-user-select: none; -} -#insight .ms-choice { - border-color: #ccc; -} -#insight .ms-choice:focus, -#insight .ms-parent input:focus { - outline: 0; -} -#insight .ms-drop ul { - padding: 0; -} -#insight .ms-drop ul > li label:not(.optgroup) { - padding: 4px 8px; - cursor: pointer; - transition: background 0.13s; - text-indent: 1em; -} -#insight .ms-drop ul > li label:not(.optgroup):hover { - background: #f0f0f0; -} -#insight .ms-drop ul > li label.optgroup { - border-top: 1px solid #ccc; - margin-top: 5px; - text-indent: 0em; - text-transform: uppercase; - font-weight: normal; - opacity: 0.6; - padding: 6px 8px 2px 8px; -} -#insight .ms-drop ul > li:first-child label.optgroup { - margin-top: 0; -} - -#insight .info.box { - margin-bottom: 10px; -} -#insight .box .content { - padding: 7px; -} -#insight .info.box .insight-stale button { - width: 100%; -} -#insight .info.box .help { - float: right; -} -#insight .info .share a { - text-decoration: underline; -} - -#insight .help.box { - margin-top: 20px; -} -#insight .help .dimension { - margin-top: 10px; -} -#insight .help h3 { - margin: 0; - font-weight: bold; -} -#insight .help a { - text-decoration: underline; -} - -#insight table td.data { - font-weight: bold; -} -#insight .game-sample { - margin: 20px 0 10px 0; - border-width: 1px 0 0 0; -} -#insight .game-sample .top { - text-align: center; -} -#insight .game_list .cg-board-wrap { - width: 182px; - height: 182px; - position: relative; -} -#insight .game_list .vstext { - width: 172px; - border: none; - background: none; -} -#insight .game_list { - white-space: nowrap; - display: flex; - flex-flow: row nowrap; - justify-content: space-between; -} -#insight .game_list > div { - display: inline-block; - margin: 0 0 0 14.8px; -} -#insight .game_list > div:first-child { - margin-left: 0; -} diff --git a/public/stylesheets/insight.dark.css b/public/stylesheets/insight.dark.css deleted file mode 100644 index a8a5350807..0000000000 --- a/public/stylesheets/insight.dark.css +++ /dev/null @@ -1,48 +0,0 @@ -body.dark #insight .ms-parent:hover .ms-choice, -body.dark #insight .ms-parent:hover .ms-choice > span.placeholder, -body.dark #insight .ms-drop ul > li:hover label:not(.optgroup), -body.dark #insight .ms-drop ul > li.selected label, -body.dark #insight .ms-parent.selected .ms-choice { - background-color: #404040; - color: #eaeaea; -} -body.dark div.panel-tabs a.tab, -body.dark #insight header, -body.dark #insight .ms-choice, -body.dark #insight .ms-drop, -body.dark #insight .ms-drop input, -body.dark #insight .ms-drop ul > li label.optgroup, -body.dark #insight table { - border-color: #3d3d3d; -} -body.dark #insight .presets, -body.dark #insight header, -body.dark #insight table, -body.dark #insight .ms-choice, -body.dark #insight .ms-drop { - background-color: #2b2b2b; -} -body.dark #insight .ms-choice > span.placeholder, -body.dark #insight .ms-parent, -body.dark #insight .ms-parent button { - color: #a0a0a0; -} -body.dark #insight .ms-drop.bottom { - box-shadow: 0 4px 5px rgba(0, 0, 0, 0.9); -} -body.dark #insight .filters .topless a { - color: #777; - text-shadow: none; -} -body.dark div.panel-tabs a.tab { - background: none; - color: #777; -} -body.dark div.panel-tabs a.tab.active { - color: #aaa; - background-color: #2b2b2b; -} -body.dark #insight .presets a:hover { - color: #a0a0a0; - background-color: #333; -} diff --git a/public/stylesheets/insight.transp.css b/public/stylesheets/insight.transp.css deleted file mode 100644 index 7defa15933..0000000000 --- a/public/stylesheets/insight.transp.css +++ /dev/null @@ -1,7 +0,0 @@ -body.transp #insight .chart { - background: rgba(0,0,0,0.6); - box-shadow: inset 0 0 9px rgba(255,255,255,0.5); -} -body.transp #insight .chart rect[fill="rgba(120,120,120,0.2)"] { - fill: rgba(120,120,120,0.4); -} diff --git a/public/stylesheets/jquery-ui.css b/public/stylesheets/jquery-ui.css deleted file mode 100644 index 4882dc4309..0000000000 --- a/public/stylesheets/jquery-ui.css +++ /dev/null @@ -1,99 +0,0 @@ -ul.ui-autocomplete { - width: 200px; - background: #FAFAFA; - border: 1px solid #DADADA; - max-height: 200px; - overflow: auto; -} -ul.ui-autocomplete li a { - display: block; - padding: 0.6em 1em; -} -ul.ui-autocomplete li a.ui-state-focus { - background: #E1F6F8; - color: #444; -} -.ui-widget-header { - color: #fff !important; - text-shadow: 0 1px 0 #000 !important; - background: #d85000 !important; - border-color: #b84400 !important; - box-shadow: 0 3px 4px rgba(0, 0, 0, 0.15) inset !important; -} -/* slider */ - -.ui-slider { - background: #fff; - position: relative; - text-align: left; - cursor:pointer; -} -.ui-slider-handle { - position: absolute; - z-index: 2; - width: 1.2em; - height: 1.2em; - outline:0; - cursor:pointer; - background: linear-gradient(to bottom, rgba(245, 245, 245, 1) 0%, rgba(240, 240, 240, 1) 100%); - text-shadow: 0 1px 0 #FFF; - color: #848484; -} -.ui-slider-handle, -.ui-widget-content { - border: 1px solid #e2e2e2; - border-radius: 2px; -} -.ui-slider-handle:hover { - border-color: #e2e2e2; - background: rgb(248, 248, 248); - background: linear-gradient(to bottom, rgba(248, 248, 248, 1) 0%, rgba(243, 243, 243, 1) 100%); -} -.ui-slider .ui-slider-range { - position: absolute; - z-index: 1; - font-size: .7em; - display: block; - border: 0; - background-position: 0 0; -} -.ui-slider-horizontal { - height: .8em; -} -.ui-slider-horizontal .ui-slider-handle { - top: -.3em; - margin-left: -.6em; -} -.ui-slider-horizontal .ui-slider-range { - top: 0; - height: 100%; -} -.ui-slider-horizontal .ui-slider-range-min { - left: 0; -} -.ui-slider-horizontal .ui-slider-range-max { - right: 0; -} - -body.dark .ui-slider, -body.dark .progressbar { - background-color: #505050; -} -/* body.dark .ui-state-default { */ -/* border-color: #3d3d3d; */ -/* } */ -body.dark .ui-state-default { - background: linear-gradient(to bottom, rgba(40, 40, 40, 1), rgba(34, 34, 34, 1) 100%); - text-shadow: 0 1px 0 #000; -} -body.dark .ui-slider-handle, -body.dark .ui-widget-content { - border-color: #323232; -} -body.transp .ui-state-hover { - background: rgba(0, 0, 0, 0.5); -} -body.transp .ui-state-default { - background: rgba(0, 0, 0, 0.5); - background: linear-gradient(to bottom, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.7) 100%); -} diff --git a/public/stylesheets/keyboard.css b/public/stylesheets/keyboard.css deleted file mode 100644 index 335c56aa6a..0000000000 --- a/public/stylesheets/keyboard.css +++ /dev/null @@ -1,64 +0,0 @@ -div.lichess_overboard.keyboard_help { - width: 90%; - height: 90%; - display: flex; - flex-flow: column nowrap; - padding: 0; -} -div.lichess_overboard.keyboard_help h2 { - margin: 5px 0 0 0; -} -div.lichess_overboard.keyboard_help .scrollable { - overflow-y: auto; - padding: 10px 0; -} -.keyboard_help table { - width: 100%; -} -.keyboard_help th { -} -.keyboard_help th p { - margin: 15px 0 10px 0; - background: #f4f4f4; - padding: 5px 15px; -} -body.dark .keyboard_help th p { - background: #333; -} -.keyboard_help td { - padding-top: 3px; - padding-bottom: 3px; - line-height: 20px; - text-align: left; -} -.keyboard_help .keys { - padding-right: 15px; - text-align: right; - white-space: nowrap; -} -.keyboard_help .desc:first-letter { - text-transform: uppercase; -} -.keyboard_help or { - margin-left: 3px; - opacity: 0.5; -} -.keyboard_help kbd { - display: inline-block; - padding: 4px 5px; - margin-left: 3px; - font-family: monospace; - line-height: 10px; - color: #444; - vertical-align: middle; - background-color: #fcfcfc; - border: solid 1px #ccc; - border-bottom-color: #bbb; - border-radius: 3px; - box-shadow: inset 0 -1px 0 #bbb; -} -.keyboard_help td.mouse li { - list-style: disc inside; - margin-left: 15px; - line-height: 2em; -} diff --git a/public/stylesheets/lag.css b/public/stylesheets/lag.css deleted file mode 100644 index 76f0822ed7..0000000000 --- a/public/stylesheets/lag.css +++ /dev/null @@ -1,38 +0,0 @@ -.lag { - overflow: hidden; -} -.lag .answer.long { - margin: 40px 0; - text-align: center; -} -.lag .sections { - overflow: hidden; -} -.lag section { - display: block; - float: left; - width: 50%; - box-sizing: border-box; -} -.lag p { - margin: 1em 0; -} -.lag h2 { - font-size: 1.4em; -} -.lag section h2 { - text-align: center; -} -.lag section .meter { - margin: -40px 0; -} -.lag section.server { - padding-right: 20px; - border-right: 2px solid rgba(127,127,127, 0.3); -} -.lag section.network { - padding-left: 20px; -} -.lag .last-word { - margin-top: 30px; -} diff --git a/public/stylesheets/learn.css b/public/stylesheets/learn.css deleted file mode 100644 index 0317302dd5..0000000000 --- a/public/stylesheets/learn.css +++ /dev/null @@ -1,830 +0,0 @@ -#learn_app { -} -#learn_app div.lichess_ground { - width: 267px; - justify-content: center; - -webkit-user-select: none; - -moz-user-select: none; -} -#learn_app .title { - display: flex; - background: #3893E8; - color: #fff; -} -#learn_app .title h2, -#learn_app .title h3 { - font-size: 2.3em; - margin: 15px 0 5px -3px; - white-space: nowrap; -} -#learn_app .title img { - width: 80px; - height: 80px; - margin: 5px 8px 5px 5px; -} -#learn_app .lichess_ground .subtitle { - margin-bottom: 1em; -} -#learn_app .goal { - background: #fff; - border: 1px solid #ccc; - border-top: none; - font-size: 1.3em; - padding: 0 15px; - text-align: center; - height: 135px; - display: flex; - align-items: center; - justify-content: center; -} -#learn_app .result { - display: flex; - align-items: center; - justify-content: center; - flex-flow: column nowrap; - border: 1px solid #ccc; - border-top: none; - text-align: center; - cursor: pointer; - transition: 0.3s; - min-height: 135px; - padding: 0; - font-size: 2em; -} -@keyframes shadow-glow { - 50% { - box-shadow: 0 0 10px 10px rgba(255,255,255,0.5); - transform: scale(1.05); - } -} -@keyframes text-shadow-glow { - 50% { - text-shadow: 0 0 10px #fff; - transform: scale(1.05); - } -} -#learn_app .result h2 { - animation: text-shadow-glow 1s 1; -} -#learn_app .result.failed h2, -#learn_app .result.next h2 { - margin-top: 15px; -} -#learn_app .result:hover { - filter: brightness(1.1); -} -#learn_app .result .stars { - margin-top: 4px; -} -#learn_app .result .stars i { - margin: 3px; - animation: text-shadow-glow 1s 1; -} -#learn_app .result button { - margin: 15px auto 15px auto; - font-size: 30px; - font-weight: bold; - text-transform: uppercase; - background: #fff; - border: none; - border-radius: 5px; - padding: 5px 10px; - box-shadow: 0 0 5px 5px rgba(255,255,255,0.5); - animation: shadow-glow 1s infinite; -} -#learn_app .result.completed { - background: #4caf50; - color: #fff; -} -#learn_app .result.completed button { - color: #4caf50; -} -#learn_app .result.failed { - background: #dc322f; - color: #fff; -} -#learn_app .result.failed button { - color: #dc322f; -} -@keyframes go-home { - from {opacity: 1;} - to {opacity: 0.1;} -} -#learn_app .completed:not(.no-go-home) piece { - animation: 0.7s ease-in-out 0.7s go-home; -} -#learn_app item { - width: 70%; - height: 70%; - bottom: 15%; - left: 15%; - background-size: cover; - position: absolute; - transform: translate3d(0, 0, 0); - z-index: 1; - transition: all 1s; -} -@keyframes soft-hue { - 50%{ - filter: hue-rotate(-20deg); - } -} -@keyframes soft-grow { - 50%{ - transform: scale(1.08); - } -} -@keyframes apple-appear { - 0% { - opacity: 0.5; transform: scale(0) rotate(-360deg); - } - 100% { - opacity: 1; transform: scale(1) rotate(0); - } -} -#learn_app .apple { - background-image: url(../images/learn/star.png); - animation: 0.6s ease-in-out 0s 1 forwards apple-appear, - 1.7s ease-in-out 0.7s infinite none soft-grow, - 0.7s ease-in-out 0.7s infinite none soft-hue; -} -#learn_app .is2d item { - width: 100%; - height: 100%; - left: 0; - bottom: 0; -} -#learn_app square.has-item.move-dest { - background: radial-gradient(transparent 0%, transparent 80%, rgba(20, 85, 0, 0.3) 80%); -} -#learn_app .cg-board square.move-dest.drag-over, -#learn_app .cg-board square.move-dest:hover { - background: rgba(20, 85, 30, 0.3); -} - -#learn_app .screen-overlay { - position: fixed; - top: -80px; - left: 0; - width: 100%; - height: 110%; - background: rgba(79, 195, 247, 0.9); - z-index: 33; - margin: 63px auto; - cursor: pointer; -} -#learn_app .screen-overlay * { - box-sizing: border-box; -} - -#learn_app .screen { - margin: 100px auto; - background-color: #fff; - width: 310px; - overflow: hidden; - text-align: center; - box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 30px; - padding-top: 36px; -} -#learn_app .screen > :nth-child(1) { - animation: slideIn 1s cubic-bezier(0.37, 0.82, 0.2, 1); -} -#learn_app .screen > :nth-child(2) { - animation: slideIn 1.5s cubic-bezier(0.37, 0.82, 0.2, 1); -} -#learn_app .screen > :nth-child(3) { - animation: slideIn 2s cubic-bezier(0.37, 0.82, 0.2, 1); -} -#learn_app .screen > :nth-child(4) { - animation: slideIn 2.5s cubic-bezier(0.37, 0.82, 0.2, 1); -} -#learn_app .screen > :nth-child(5) { - animation: slideIn 3s cubic-bezier(0.37, 0.82, 0.2, 1); -} -#learn_app .screen .stars { - margin-bottom: 20px; -} -@keyframes star-appear { - 0% { - filter: saturate(1); opacity: 0.5; transform: scale(0) rotate(-360deg); - } - 85% { - filter: saturate(1); opacity: 1; transform: scale(1.3) rotate(10deg); - } - 100% { - filter: saturate(1); opacity: 1; transform: scale(1) rotate(0); - } -} -#learn_app .screen .stars .star-wrap { - display: inline-block; - width: 55px; - height: 55px; - margin: 0 5px; - position: relative; -} -#learn_app .screen .stars .star-wrap::before { - position: absolute; - top: 5px; - left: 5px; - display: block; - width: 45px; - height: 45px; - content: ''; - background-image: url(../images/learn/star.png); - background-size: cover; - filter: saturate(0); - opacity: 0.2; -} -#learn_app .screen .stars .star { - display: inline-block; - background-image: url(../images/learn/star.png); - background-size: cover; - width: 55px; - height: 55px; - opacity: 0; - animation: star-appear 2.5s ease-in-out; - animation-delay: 0.1s; - animation-fill-mode: forwards; -} -#learn_app .screen .stars .star-wrap:nth-child(2) .star { - animation-delay: 0.8s; -} -#learn_app .screen .stars .star-wrap:nth-child(3) .star { - animation-delay: 1.6s; -} -#learn_app .screen .no-square { - width: 100px; - height: 100px; - position: relative; - margin: 0 auto 22px auto; -} -#learn_app .screen h1 { - font-weight: bold; - color: #181818; - font-size: 24px; - margin-bottom: 22px; -} -#learn_app .screen .round-svg { - width: 240px; - height: 240px; - padding: 0px; - background: #f57c00; - border-radius: 50%; - margin: 0 auto 10px auto; -} -#learn_app .screen .round-svg img { - width: 240px; - height: 240px; - padding: 20px; -} -#learn_app .screen .score { - text-transform: uppercase; - color: #0288d1; - font-size: 12px; - display: block; - letter-spacing: 1px; - margin-bottom: 17px; -} -#learn_app .screen .score span { - font-weight: bold; - font-family: 'Roboto Mono'; -} -#learn_app .screen p { - color: #999999; - font-size: 15px; - padding: 0 15%; - line-height: 24px; - margin-bottom: 17px; -} -#learn_app .screen .buttons { - width: 100%; - text-align: center; - margin-bottom: 23px; -} -#learn_app .screen .buttons a { - display: block; - text-decoration: none; - text-transform: uppercase; - line-height: 48px; - border-radius: 5px; - margin: 8px 10% 0 10%; - height: 48px; - color: #fff; - transition: all 0.3s; -} -#learn_app .screen .buttons a { - margin-top: 8px; -} -#learn_app .screen .buttons .next { - font-size: 14px; - background: #4fc3f7; -} -#learn_app .screen .buttons .back { - font-size: 12px; - background: #f57c00; -} -#learn_app .screen .buttons a:hover { - filter: brightness(0.9); -} -#learn_app .screen piece { - width: 100%; - height: 100%; -} -@keyframes slideIn { - 0% { - opacity: 0; - filter: blur(15px); - } - 100% { - opacity: 1; - filter: blur(0px); - } -} - -@keyframes rankGlow { - 50% { - background-color: rgba(255, 255, 255, 0.5); - box-shadow: 0 0 40px rgba(255,255,255,0.7); - } -} -.highlight-2nd-rank .cg-board::after, -.highlight-5th-rank .cg-board::after, -.highlight-7th-rank .cg-board::after { - width: 100%; - height: 12.5%; - content: ''; - position: absolute; - bottom: 12.5%; - left: 0; - box-shadow: 0 0 15px rgba(255,255,255,0.2); - background-color: rgba(255, 255, 255, 0.2); - animation: 1s rankGlow ease-in-out infinite; -} -.highlight-7th-rank .cg-board::after { - top: 12.5%; -} -.highlight-5th-rank .cg-board::after { - top: 37.5%; -} -#promotion_choice .explanation { - position: absolute; - top: 25%; - left: 25%; - width: 50%; - height: 50%; - box-sizing: border-box; - background: #fff; - padding: 20px; - box-shadow: 0 3px 25px rgba(0,0,0,0.5); -} -#promotion_choice .explanation h2 { - font-size: 2em; -} -#promotion_choice .explanation p { - font-size: 1.3em; - margin-top: 15px; -} - -#learn_app .cg-board piece.wriggle::after { - content: '!'; -} -#learn_app .cg-board piece.wriggle::after { - content: '!'; - font-size: 40px; - font-weight: bold; - color: #fff; - text-shadow: rgba(0,0,0,0.8) 0 0 3px; -} - -#learn_app .piece-values .cg-board piece::before { - position:absolute; - top: 14px; - right: 4px; - color: #fff; - text-shadow: 0 0 9px rgba(0,0,0,1), 0 0 4px rgba(0,0,0,1); - font-size: 30px; - font-weight: bold; -} -#learn_app .piece-values .cg-board piece.queen::before { - content: '9'; -} -#learn_app .piece-values .cg-board piece.rook::before { - content: '5'; -} -#learn_app .piece-values .cg-board piece.bishop::before, -#learn_app .piece-values .cg-board piece.knight::before { - content: '3'; -} -#learn_app .piece-values .cg-board piece.pawn::before { - content: '1'; -} - -#learn_app .progress { - display: flex; - align-items: center; - text-align: center; - border: 1px solid #ccc; - border-top: 0px; -} -#learn_app .progress a { - flex: 1 1 100%; - display: flex; - align-items: center; - text-align: center; - background: #fff; - height: 40px; - font-size: 11px; - line-height: 11px; - border-left: 1px solid #ccc; - opacity: 0.8; - transition: all 0.13s; -} -#learn_app .progress a:first-child { - border-left: 0; -} -#learn_app .progress a:hover { - opacity: 1; -} -#learn_app .progress a span { - margin: auto; -} -#learn_app .progress .st3 i:first-child { - display: block; -} -#learn_app .progress a.done { - background: #fdd835; -} -#learn_app .progress a.done { - color: #fff!important; - background: #4caf50!important; -} -#learn_app .progress a.active { - opacity: 1; - color: #fff!important; - background: #3893E8!important; -} -body.dark #learn_app .goal, -body.dark #learn_app .progress, -body.dark #learn_app .progress a { - background: #303030; - border-color: #444; - color: #aaa; -} -body.dark #learn_app .goal, -body.dark #learn_app .result { - border-color: #444; - border-width: 1px 0; -} - -#learn_side { - border: none; - background: transparent!important; -} -body.dark #learn_side a { - color: #bbb; -} -#learn_side .home { - width: 220px; - background: #3893E8; - color: #fff; - border-radius: 5px; - text-align: center; - padding-top: 10px; - margin-top: 20px; -} -#learn_side .home h1 { - font-size: 30px; -} -#learn_side .home h2 { - font-size: 20px; - padding-bottom: 15px; -} - -@keyframes fat-glide { - 50%{ - transform: translateY(-4px); - } -} -#learn_side .home i.fat { - display: block; - width: 200px; - height: 200px; - background: url(../images/learn/brutal-helm.svg); - margin: auto; - opacity: 0.8; -} -#learn_side .home:hover i.fat { - animation: 1.2s fat-glide ease-in-out infinite; -} -#learn_side .home .progress { - position: relative; - width: 100%; - height: 30px; - /* border-top: 3px solid #1566b2; */ - background: #1a7edb; - box-shadow: inset 0 1px 1px rgba(0,0,0,0.1); - overflow: hidden; -} -@keyframes animatedBackground { - from { background-position: 0 0; } - to { background-position: 0 1000%; } -} -@keyframes animatedBar { - from { transform: translateX(-100px); } - to { transform: translateX(0px); } -} -#learn_side .home .progress .bar { - height: 100%; - background: #1566b2; - border-radius: 0 5px 5px 0; - background-image: url(../images/grain.png); - transform: translateX(-100px); - animation: animatedBackground 50s linear infinite, animatedBar 1s forwards; -} -#learn_side .home .progress .text { - position: absolute; - top: 0; - left: 0; - width: 100%; - line-height: 30px; - z-index: 3; -} -#learn_side .home .actions { - padding: 20px 10px; - text-align: left; -} -#learn_side .home a { - opacity: 0.6; - color: #fff!important; -} -#learn_side .home a:hover { - opacity: 1; -} - -#learn_side .map { - -webkit-user-select: none; - -moz-user-select: none; -} -#learn_side .map .back, -#learn_side .map .categ > h2 { - display: block; - font-size: 1.5em; - height: 50px; - line-height: 50px; - text-indent: 15px; - cursor: pointer; - opacity: 0.81; -} -#learn_side .map .back { - display: flex; -} -#learn_side .map .back img { - width: 30px; - height: 30px; - opacity: 0.9; - margin-right: 10px; - padding: 10px; - /* background: rgba(56, 147, 232, 1); */ - background: rgba(120, 120, 120, 1); - display: block; -} -#learn_side .map .back:hover { - background: rgba(120, 120, 120, 0.2); -} -#learn_side .map .categ > h2 { - border-top: 1px solid #ccc; -} -body.dark #learn_side .map .categ > h2 { - border-color: #444; -} -#learn_side .map .categ > h2:hover { - background: rgba(56, 147, 232, 0.2); -} -#learn_side .map .categ.active { - border: 1px solid #ccc; - border-width: 0 1px; -} -body.dark #learn_side .map .categ.active { - border-color: #444; -} -#learn_side .map .categ.active:last-child { - border-bottom-width: 1px; -} -#learn_side .map .categ.active > h2 { - cursor: default; - background: rgba(56, 147, 232, 1); - color: #fff; -} -#learn_side .map .categ:not(.active) .categ_stages { - display: none; -} -#learn_side .map .stage { - display: flex; - align-items: center; - transition: 0.13s; - font-size: 1.3em; - font-family: 'Roboto'; - font-weight: 300; - opacity: 0.9; -} -#learn_side .map .stage img, -#learn_side .map .stage i { - width: 30px; - height: 30px; - opacity: 0.9; - margin-right: 10px; - padding: 10px; -} -#learn_side .map .stage i::before { - font-size: 30px; -} -#learn_side .map .stage.active { - background: rgba(56, 147, 232, 0.2); -} -#learn_side .map .stage.active img { - background: rgba(56, 147, 232, 1); -} -#learn_side .map .stage.done:hover { - background: rgba(76, 175, 80, 0.2); -} -#learn_side .map .stage.done img { - background: #4caf50; -} -#learn_side .map .stage.future:hover { - background: rgba(245, 124, 0, 0.2); -} -#learn_side .map .stage.future img { - opacity: 0.7; - background: rgba(245, 124, 0, 1); -} -#learn_side .map .stage:hover { - filter: brightness(0.9); -} -body.dark #learn_side .map .stage:hover { - filter: brightness(1.1); -} -body.dark #learn_side .map .stage.active h2, -body.dark #learn_side .map .stage:hover h2 { - color: #fff; -} - -#learn_app .map .stages { - width: 742px; - padding-top: 10px; -} -#learn_app .map .categ > h2 { - font-size: 2em; - font-family: 'Roboto'; - font-weight: 300; - letter-spacing: 8px; - text-transform: uppercase; - color: #999; - text-shadow: 0 1px 1px #fff; - text-align: center; -} -body.dark #learn_app .map .categ > h2 { - text-shadow: 0 1px 1px #000; -} -#learn_app .map .categ_stages { - display: flex; - flex-flow: row wrap; - justify-content: space-between; - margin: 10px 0 36px 0; -} -#learn_app .map .stage { - position: relative; - display: flex; - align-items: center; - flex: 0 0 49%; - width: 49%; - height: 90px; - color: #fff; - box-sizing: border-box; - margin-top: 13px; - transition: 0.13s; - border-radius: 3px; - box-shadow: 0 3px 5px 0 rgba(0, 0, 0, 0.3), 0 1px 1px 0 rgba(0, 0, 0, 0.2); - font-size: 1.2em; -} -#learn_app .map .stage img { - width: 80px; - height: 80px; - margin: 0 13px; - opacity: 0.9; -} -#learn_app .map .stage h3 { - font-size: 2em; - letter-spacing: 3px; - margin: 0 0 1px -1px; -} -#learn_app .map .stage.vv h3 { - font-size: 1.6em; - letter-spacing: 2px; -} -#learn_app .map .stage.vvv h3 { - font-size: 1.4em; - letter-spacing: 1px; -} -@keyframes soft-bright { - 50%{ - filter: brightness(1.1); - } -} -#learn_app .map .stage.ongoing { - background: #3893E8; - filter: brightness(0.9); -} -#learn_app .map .stage.ongoing { - animation: 1.7s soft-bright ease-in-out infinite; -} -#learn_app .map .stage.ongoing:hover { - filter: brightness(1.2); -} -#learn_app .map .stage.done { - background: #4caf50; -} -#learn_app .map .stage.future { - opacity: 0.7; - background: #f57c00; -} -#learn_app .map .stage.future img { - opacity: 0.7; -} -#learn_app .map a.stage.active, -#learn_app .map a.stage:hover { - filter: brightness(1.08); - transform: scale(1.02); - opacity: 1; -} -#learn_app .map .stage .ribbon-wrapper { - display: block; - width: 85px; - height: 88px; - overflow: hidden; - position: absolute; - top: -3px; - right: -3px; -} -#learn_app .map .stage .ribbon { - display: block; - font-size: 15px; - font-weight: bold; - color: #333; - text-align: center; - text-shadow: rgba(255,255,255,0.5) 0px 1px 0px; - transform: rotate(45deg); - position: relative; - padding: 7px 0; - left: -5px; - top: 15px; - width: 120px; - color: #6a6340; - box-shadow: 0px 0px 3px rgba(0,0,0,0.3); -} -#learn_app .map .stage .ribbon i { - color: #d59120; - animation: 0.6s soft-hue ease-in-out infinite; - text-shadow: 0 -0.5px 1px rgba(0,0,0,0.5); -} -#learn_app .map .stage .ribbon i:nth-child(2) { - animation-delay: 0.2s; -} -#learn_app .map .stage .ribbon i:nth-child(3) { - animation-delay: 0.4s; -} - -#learn_app .map .stage .ribbon:before, -#learn_app .map .stage .ribbon:after { - content: ""; - border-left: 3px solid transparent; - border-right: 3px solid transparent; - position:absolute; - bottom: -3px; -} -#learn_app .map .stage .ribbon:before { - left: 0; -} -#learn_app .map .stage .ribbon:after { - right: 0; -} - -#learn_app .map .stage .ribbon.done { - background-color: #BFDC7A; -} -#learn_app .map .stage .ribbon.done:before, -#learn_app .map .stage .ribbon.done:after { - border-top: 3px solid #6e8900; -} -#learn_app .map .stage .ribbon.ongoing { - background-color: #B3E5FC; -} -#learn_app .map .stage .ribbon.ongoing:before, -#learn_app .map .stage .ribbon.ongoing:after { - border-top: 3px solid #536DFE; -} -#learn_app .map .what_next > p { - width: 100%; - text-align: center; - margin: 20px 0; - font-size: 1.2em; -} diff --git a/public/stylesheets/material.form.css b/public/stylesheets/material.form.css deleted file mode 100644 index 28edb06223..0000000000 --- a/public/stylesheets/material.form.css +++ /dev/null @@ -1,206 +0,0 @@ -.material.form { - margin: 30px 20px 20px 20px; -} -.material.form * { - box-sizing: border-box; -} -.material.form *::after, -.material.form *::before { - box-sizing: border-box; -} - -.material.form .button-container { - text-align: center; - margin: -20px 0 -20px 0; -} -.material.form .button-container .button { - padding: 20px 30px; -} - -.material.form fieldset { - margin: 0 0 3rem; - padding: 0; - border: none; -} - -.material.form .form-group { - position: relative; - margin-bottom: 3.5rem; -} -.material.form .form-group.margin-bottom { - margin-bottom: 4.5rem; -} -.material.form .form-group.little-margin-bottom { - margin-bottom: 2.5rem; -} - -.material.form .form-group.half { - display: inline-block; - width: 47%; - vertical-align: top; -} -.material.form .form-group.half .form-group.half { - width: 46.5%; - margin-bottom: 0; -} -.material.form .form-group.half:nth-child(odd) { - margin-right: 5%; -} - -.material.form .form-group.third { - display: inline-block; - width: 30%; - margin-right: 4%; -} -.material.form .form-group.third:nth-child(3) { - margin-right: 0; -} - -.material.form .form-inline > .form-group, -.material.form .form-inline > .btn { - display: inline-block; - margin-bottom: 0; -} - -.material.form .form-help { - margin-top: 0.125rem; - margin-left: 0.125rem; - opacity: 0.4; - font-size: 0.8rem; -} -.form-group .form-help { - text-align: left; - position: absolute; - left: 0; - width: 100%; -} -.material.form .form-group input:not([type="checkbox"]) { - height: 1.9rem; -} -.material.form .form-group select { - width: 100%; - font-size: 1rem; - height: 1.6rem; - padding: 0.125rem 0.125rem 0.0625rem; - background: none; - border: none; - line-height: 1.6; - box-shadow: none; -} -.material.form .form-group *:disabled { - opacity: 0.6; -} -.material.form .form-group .control-label { - position: absolute; - top: 0.25rem; - pointer-events: none; - padding-left: 0.125rem; - z-index: 1; - opacity: 0.6; - font-size: 1rem; - font-weight: normal; - transition: all 0.28s ease; -} -.material.form .form-group .control-label em { - transition: all 0.28s ease; -} -.material.form .form-group.no-label { - margin-top: -1.5em; -} -.material.form .form-group .bar { - position: relative; - border-bottom: 0.0625rem solid #999; - display: block; -} -.material.form .form-group .bar::before { - content: ''; - height: 0.125rem; - width: 0; - left: 50%; - bottom: -0.0625rem; - position: absolute; - background: #3893E8; - transition: left 0.28s ease, width 0.28s ease; - z-index: 2; -} -.material.form .form-group input:not([type="checkbox"]), -.material.form .form-group textarea { - display: block; - background: none; - padding: 0.125rem 0.125rem 0.0625rem; - font-size: 1rem; - border-width: 0; - line-height: 1.9; - width: 100%; - transition: all 0.28s ease; - box-shadow: none; -} -.material.form .form-group textarea { - line-height: 1.7; - resize: none; -} -body.dark .material.form .form-group textarea, -body.dark .material.form .form-group .bar { - border-color: #3d3d3d; -} -.material.form .form-group input[type="file"] { - line-height: 1; -} -.material.form .form-group input[type="file"] ~ .bar { - display: none; -} -.material.form .form-group * { - color: #333; -} -body.dark .material.form .form-group * { - color: #bbb; -} -.material.form .form-group a { - color: #3893E8; -} -body.dark .material.form .form-group select option { - color: #bbb; - background-color: #2b2b2b; -} -.material.form .form-group select ~ .control-label, -.material.form .form-group input:focus ~ .control-label, -.material.form .form-group input:valid ~ .control-label, -.material.form .form-group input.form-file ~ .control-label, -.material.form .form-group input.has-value ~ .control-label, -.material.form .form-group textarea:focus ~ .control-label, -.material.form .form-group textarea:valid ~ .control-label, -.material.form .form-group textarea.form-file ~ .control-label, -.material.form .form-group textarea.has-value ~ .control-label { - font-size: 0.8rem; - opacity: 0.6; - top: -1rem; - left: 0; -} -.material.form .form-group *:focus { - outline: none; -} -.material.form .form-group *:focus ~ .control-label, -.material.form .form-group *:focus ~ .form-help { - color: #3893E8; - opacity: 0.6; -} -.material.form .form-group *:focus ~ .bar::before { - width: 100%; - left: 0; -} - -.material.form .has-error .legend.legend, -body.base .material.form .has-error .error, -.has-error.form-group .control-label.control-label { - color: #d9534f; -} -.material.form .has-error.form-group .form-help, -.material.form .has-error.form-group label strong, -.material.form .has-error.form-group .helper { - color: #d9534f; -} -.material.form .has-error .bar::before { - background: #d9534f; - left: 0; - width: 100%; -} diff --git a/public/stylesheets/message.css b/public/stylesheets/message.css deleted file mode 100644 index 68879dc076..0000000000 --- a/public/stylesheets/message.css +++ /dev/null @@ -1,164 +0,0 @@ -#lichess_message { - min-height: 300px; -} - -div.sidebar { - margin-top: 30px; -} -div.sidebar a { - display: block; - font-size: 1.1em; - padding: 1em 0 1em 1em; -} - -#lichess_message .head.with_actions { - display: flex; - justify-content: space-between; -} -#lichess_message .head .actions { - display: flex; - align-items: center; -} -#lichess_message .head .actions select { - margin-right: 20px; - padding: 8px 10px; -} -#lichess_message.mod .head h1 { - color: #d59120; -} - -#lichess_message table { - width: 100%; -} -#lichess_message th { - padding: 10px 20px; - text-align: right; -} -#lichess_message tr { - border-top: 1px solid #eaeaea; -} -#lichess_message tr:nth-child(even) { - background: #eee; -} - -#lichess_message td.check { - padding-right: 10px; -} -#lichess_message td.check input { - vertical-align: middle; -} -#lichess_message td.author, td.no_messages { - padding: 1em 1em 1em 20px; - width: 150px; - max-width: 150px; - overflow: hidden; - text-overflow: ellipsis; -} -#lichess_message td.subject a { - color: #3893E8; - display: block; - padding: 1em; -} -#lichess_message td.subject a:hover { - text-decoration: underline; -} -#lichess_message tr.new td.subject a { - font-weight: bold; -} -#lichess_message tr.mod td.subject a { - color: #d59120; -} -#lichess_message td.author, #lichess_message time { - white-space: nowrap; - padding-right: 1em; -} -#lichess_message time { - font-size: 0.8em; -} - -#lichess_message div.thread_actions { - margin-top: 0.4em; - float: right; -} - -#lichess_message div.thread_message { - font-size: 1.2em; - margin-top: 2em; - border-top: 1px solid #d4d4d4; - padding-top: 2em; -} -#lichess_message div.thread_message span.infos { - margin-bottom: 1em; - display: block; -} -#lichess_message div.thread_message_body a { - color: #3893E8; -} -#lichess_message div.thread_message_body iframe.analyse { - margin: 1em 0; -} -#lichess_message div.answer { - margin-top: 3em; -} - -#lichess_message div.form { - font-size: 1.1em; - padding-top: 2em; -} -#lichess_message div.form div.actions, -#lichess_message div.answer div.actions { - padding: 0.5em 0; - font-size: 1.1em; -} -#lichess_message div.form .actions a, -#lichess_message div.answer div.actions a { - margin-left: 1em; -} -#lichess_message form > div > label { - float: left; - width: 100px; - text-align: right; - margin-right: 10px; - vertical-align: middle; - margin-top: 3px; -} -#lichess_message .field_to input, -#lichess_message .field_subject input { - width: 450px; - border: 1px solid #D4D4D4; - padding: 3px 5px; -} -#lichess_message .field_to, -#lichess_message .field_mod, -#lichess_message .field_preset, -#lichess_message .field_subject { - margin-bottom: 1em; -} -#lichess_message .field_mod { - overflow: hidden; -} -#lichess_message .field_mod span { - float: left; -} -#lichess_message form textarea { - width: 547px; - height: 150px; - padding: 10px; - border: 1px solid #D4D4D4; -} -#lichess_message .error { - color: red; - margin-left: 60px; -} -#lichess_message .end { - border-top: 1px solid #d4d4d4; - padding-top: 2em; -} - -body.dark #lichess_message tr, -body.dark #lichess_message div.thread_message, -body.dark #lichess_message textarea, -body.dark #lichess_message input, -body.dark #lichess_message .end { - border-color: #3d3d3d; -} diff --git a/public/stylesheets/mobile.css b/public/stylesheets/mobile.css deleted file mode 100644 index 84404a886f..0000000000 --- a/public/stylesheets/mobile.css +++ /dev/null @@ -1,50 +0,0 @@ -.mobile .right-side { - float: right; - width: 264px; - text-align: center; -} -.mobile .right-side .nexus5-playing { - margin: -40px 0 30px 0; -} -.mobile .right-side .qrcode { - margin-top: 20px; -} -.mobile .left-side { - width: 245px; - text-align: center; -} -.mobile h1 { - font-size: 4em; - display: block!important; - margin-bottom: 0.5em; -} -.mobile .store { - display: inline-block; - margin-top: 1em; -} -.mobile .left-side h2 { - margin-top: 30px; - font-size: 1.5em; -} -.mobile .left-side .block { - text-align: left; - margin: 10px 0 20px 0; -} -.mobile .left-side li { - list-style-type: none; - line-height: 1.5em; - padding-left: 2em; - text-indent: -1em; -} -.mobile .left-side li:before { - vertical-align: middle; - content:'\2713'; - display:inline-block; - color: #759900; - font-weight: bold; - font-size: 1.8em; - padding:0 6px 0 0; -} -.left-side a{ - color: #3893E8 !important; -} diff --git a/public/stylesheets/mod-communication.css b/public/stylesheets/mod-communication.css deleted file mode 100644 index 3ede9085c6..0000000000 --- a/public/stylesheets/mod-communication.css +++ /dev/null @@ -1,144 +0,0 @@ -#communication h1 { - font-size: 1.5em; - display: flex; - justify-content: space-between; -} -#communication .user_link { - margin-left: -.5em; -} -#communication .actions { - display: flex; - align-items: center; -} -#communication .actions .priv { - margin-right: 5px; - font-weight: normal; -} -#communication h2 { - font-size: 1.6em; - margin-top: 1.6em; - border-bottom: 1px solid #ccc; - text-transform: capitalize; - letter-spacing: 2px; -} -#communication .user_link { - font-weight: bold; -} -#communication .public_chats, -#communication .notes, -#communication .history { - margin-top: 0.5em; - max-height: 150px; - overflow-y: auto; - padding-bottom: 0.5em; - border-bottom: 1px solid #ccc; -} -#communication .player_chats { - overflow: hidden; -} -#communication .public_chats li { - list-style: inside disc; -} -#communication .public_chats a { - color: #3893E8; -} -#communication .player_chats .game { - display: block; - float: left; - width: 33.33%; -} -#communication .player_chats .game:nth-child(odd) { - background: #f0f0f0; -} -#communication .player_chats .game .title, -#communication .player_chats .game .chat { - display: block; - padding: 6px; -} -#communication .player_chats .game .friend_title { - color: green; - font-style: italic; -} -#communication .player_chats .game .title { - text-align: center; - border-bottom: 1px solid #ccc; -} -#communication .player_chats .game .chat { - padding-top: 0; - height: 120px; - overflow: hidden; -} -#communication .player_chats .game:hover .chat { - overflow-y: auto; -} -#communication .player_chats .line, -#communication .threads .post { - opacity: 0.5; -} -#communication .player_chats .line.author, -#communication .threads .post.author { - opacity: 1; -} - -#communication .thread { - padding: 20px; - overflow-y: auto; - max-height: 400px; -} -#communication .thread .title { - margin-bottom: 20px; -} -#communication .thread .title strong { - font-size: 1.2em; - display: block; -} -#communication .thread:nth-child(even) { - background: #f0f0f0; -} -#communication .post { - margin: 1em 0; -} -body.dark #communication .player_chats .game:nth-child(odd), -body.dark #communication .thread:nth-child(even) { - background: #202020; -} -body.dark #communication h2, -body.dark #communication .public_chats, -body.dark #communication .notes, -body.dark #communication .history, -body.dark #communication .player_chats, -body.dark #communication .player_chats .game .title { - border-color: #3d3d3d; -} - -#permissions form { - text-align: center; -} -#permissions select { - height: 400px; - margin: 30px; -} -#permissions select option { - padding: 5px 10px; -} - -/* for public-chat */ -#communication.public_chat { - position: relative; -} -.public_chat #auto_refresh { - position: absolute; - top: 30px; - right: 20px; - transition: 0.3s; -} -.public_chat #auto_refresh.active.hold { - opacity: 0.4; -} -#communication.public_chat .player_chats .line, -#communication.public_chat .threads .post { - opacity: 1; -} -#communication.public_chat .chat { - overflow-y: auto!important; -} diff --git a/public/stylesheets/mod-gamify.css b/public/stylesheets/mod-gamify.css deleted file mode 100644 index 4e0e2d542f..0000000000 --- a/public/stylesheets/mod-gamify.css +++ /dev/null @@ -1,106 +0,0 @@ -#mod-gamify h1 { - font-family: 'PT Serif'; - font-size: 3em; - letter-spacing: 5px; - display: block; -} -#mod-gamify.index h1 { - margin-bottom: 30px; - text-align: center; -} -#mod-gamify .third { - float: left; - width: 33.33%; -} -#mod-gamify .champs { - width: 100%; -} -#mod-gamify .champ { - text-align: center; -} -#mod-gamify .champ h2 { - font-family: 'Roboto'; - font-weight: 300; - font-size: 1.8em; - text-transform: uppercase; - opacity: 0.7; -} -#mod-gamify .champ h3 { - font-family: 'PT Serif'; - font-size: 3em; - color: #d59120; - overflow: hidden; - text-overflow: ellipsis; - margin: 15px 0 25px 0; -} -#mod-gamify .champ h3 a { - color: #d59120; -} -#mod-gamify .champ table { - margin: auto; -} -#mod-gamify .champ table tr th { - text-transform: uppercase; -} -#mod-gamify .champ table tr td { - font-size: 2em; - font-family: 'Roboto Mono'; - text-align: right; - line-height: 50px; -} -#mod-gamify .champ table tr:first-child td { - font-size: 3em; -} -#mod-gamify .champ a.current { - display: block; - margin: 30px auto 20px auto; - width: 70%; -} -#mod-gamify .period table { - width: 100%; -} -#mod-gamify .period table thead { - font-family: 'PT Serif'; - font-size: 1.2em; -} -#mod-gamify .period table td, -#mod-gamify .period table thead th { - padding: 7px; -} -#mod-gamify .period table tbody { - font-size: 1.3em; -} -#mod-gamify .period table tbody th { - text-align: left; - font-size: 1.4em; -} -#mod-gamify .period table td.score { - font-size: 1.5em; -} -#mod-gamify .period table thead th:nth-child(n+1), -#mod-gamify .period table tr td { - text-align: right; - padding-right: 25px; -} -#mod-gamify .history { - margin-top: 20px; - font-size: 1.2em; -} -#mod-gamify .history table tr.year th { - font-family: 'PT Serif'; - padding: 20px 0; -} - -#mod-gamify .history table tr.year th:first-child { - padding-left: 25px; - font-size: 2.6em; -} -#mod-gamify .history table tr.year th:nth-child(n+3), -#mod-gamify .history table tr td { - text-align: right; - padding-right: 25px; -} -#mod-gamify .history table a, -#mod-gamify .history table .score { - font-size: 1.2em; -} diff --git a/public/stylesheets/mod-irwin.css b/public/stylesheets/mod-irwin.css deleted file mode 100644 index e341b9897f..0000000000 --- a/public/stylesheets/mod-irwin.css +++ /dev/null @@ -1,53 +0,0 @@ -.irwin .content_box_top { - display: flex; - flex-flow: row; - align-items: center; - justify-content: space-between; - padding-bottom: 1em; - padding-right: 20px; -} -.irwin .content_box_top .lichess_title { - margin: 0; -} -.irwin h1 .up { - text-transform: uppercase; - color: #759900; -} -.irwin h1 .down { - color: #dc322f; -} -.irwin .little { - font-size: 0.8em; - opacity: 0.8; -} -.irwin .slist { - white-space: nowrap; -} -.irwin .slist td { - padding-top: 1.5em; - padding-bottom: 1.5em; -} -.irwin .slist td:first-child, .irwin .slist th:first-child { - padding-left: 15px; -} -.irwin .slist strong { - display: block; - text-align: center; -} -body.dark .irwin .activation { - color: #fff; - text-align: center; -} -.irwin .green { - /* actually blue */ - background-color: rgba(32, 119, 192, 0.3); -} -.irwin .yellow { - background-color: rgba(221, 207, 63, 0.3); -} -.irwin .orange { - background-color: rgba(231, 155, 100, 0.3); -} -.irwin .red { - background-color: rgba(231, 59, 56, 0.3); -} diff --git a/public/stylesheets/mod-practice.css b/public/stylesheets/mod-practice.css deleted file mode 100644 index 9af51a4fbf..0000000000 --- a/public/stylesheets/mod-practice.css +++ /dev/null @@ -1,52 +0,0 @@ -.practice_config .both { - display: flex; -} -.practice_config .both > * { - flex: 1 1 50%; - width: auto; -} -.practice_config .both .preview { - height: 500px; - overflow: hidden; - overflow-y: auto; -} -.practice_config .both ol a { - color: #3893E8; -} -.practice_config .both > ol { - width: 100%; - overflow: hidden; -} -.practice_config .both li { - margin-left: 2em; - list-style: outside disc; -} -.practice_config .both h2 { - display: inline-block; - font-size: 1.4em; -} -.practice_config .both h3 { - display: inline-block; - font-size: 1.2em; - margin: 0; -} -.practice_config .both li li li { - font-size: 0.9em; -} -.practice_config .both em { - display: block; - font-style: italic; - font-size: 0.9em; -} -.practice_config textarea.practice_text { - width: 100%; - height: 500px; - font-family: monospace; - margin-bottom: 2em; - padding: 8px; - box-sizing: border-box; -} -.practice_config .error { - color: red; - margin-bottom: 1em; -} diff --git a/public/stylesheets/mod-streamers.css b/public/stylesheets/mod-streamers.css deleted file mode 100644 index bdb4240fbd..0000000000 --- a/public/stylesheets/mod-streamers.css +++ /dev/null @@ -1,30 +0,0 @@ -.stream_config .both { - display: flex; -} -.stream_config .both > * { - flex: 1 1 50%; - width: auto; -} -.stream_config .both .list { - height: 500px; - overflow: hidden; - overflow-y: auto; -} -.stream_config .both table.slist { - width: 100%; - overflow: hidden; -} -.stream_config .both table.slist td { - white-space: nowrap; - max-width: 130px; - overflow: hidden; - text-overflow: ellipsis; -} -.stream_config textarea.stream_text { - width: 100%; - height: 500px; - font-family: monospace; - margin-bottom: 2em; - padding: 8px; - box-sizing: border-box; -} diff --git a/public/stylesheets/notFound.css b/public/stylesheets/notFound.css deleted file mode 100644 index be4a66c92f..0000000000 --- a/public/stylesheets/notFound.css +++ /dev/null @@ -1,26 +0,0 @@ -div.content_box header { - overflow: hidden; -} -div.content_box header h1 { - font-size: 110px; - float: left; - font-weight: bold; - margin: -30px 30px 0 0; - opacity: 0.3; -} -div.content_box header strong { - text-transform: uppercase; - opacity: 0.5; - font-size: 31px; - margin: 10px 0 10px 0; - display: block; -} -div.content_box a.underline { - text-decoration: underline; -} -div.content_box div.game { - text-align: center; -} -div.content_box .credits { - margin-top: 2em; -} diff --git a/public/stylesheets/notifyApp.css b/public/stylesheets/notifyApp.css deleted file mode 100644 index c31284a119..0000000000 --- a/public/stylesheets/notifyApp.css +++ /dev/null @@ -1,98 +0,0 @@ -#notify_app { - width: 300px; - left: -132px; -} - -#notify_app .spinner { - margin: 50px auto; -} - -#notify_app .notifications { - transition: opacity 0.3s; -} -#notify_app .notifications.scrolling { - opacity: 0.5; -} - -#notify_app .site_notification { - display: flex; - padding: 8px 12px; - background: #fff; - border-bottom: 1px solid #eee; - position: relative; -} -#notify_app .site_notification.new { - background: rgba(191, 231, 255, 0.3); -} -#notify_app .site_notification:hover { - background: #f8f8f8; -} -#notify_app .site_notification.new:hover { - background: rgba(191, 231, 255, 0.5); -} -#notify_app .site_notification i { - font-size: 22px; - opacity: 0.5; - margin-right: 12px; -} -#notify_app .site_notification.new i, -#notify_app .site_notification:hover i { - color: #3893E8!important; - opacity: 0.6; -} -.site_notification .content { - flex: 0 1 100%; - white-space: nowrap; - overflow: hidden; -} -.site_notification .content span:first-child { - display: flex; - justify-content: space-between; -} -.site_notification .content span:last-child { - display: block; - text-overflow: ellipsis; - overflow: hidden; -} -.site_notification .content time { - font-size: 0.9em; - font-family: 'Roboto'; - font-weight: 300; -} -#notify_app .pager { - display: block; - padding: 5px; - text-align: center; - opacity: 0.8; -} -#notify_app .pager.disabled { - opacity: 0.3; -} -#notify_app .pager:not(.disabled) { - cursor: pointer; - color: #3893E8!important; - transition: 0.13s; -} -#notify_app .pager:not(.disabled):hover { - opacity: 1; - background: rgba(191, 231, 255, 0.5); -} -#notify_app .pager.prev { - border-bottom: 1px solid #eee; -} -#notify_app .empty { - text-align: center; - padding: 20px 0; - background: #fff; - box-shadow: 0 1px 7px rgba(0, 0, 0, 0.3); -} -body.dark #notify_app .site_notification:hover { - background: #303030; -} -body.dark #notify_app .site_notification.new { - background: rgba(27, 51, 68, 0.4)!important; -} -body.dark #notify_app .site_notification.new:hover, -body.dark #notify_app .pager:not(.disabled):hover { - background: rgba(27, 51, 68, 0.8)!important; -} diff --git a/public/stylesheets/nvui.css b/public/stylesheets/nvui.css deleted file mode 100644 index 0b4cf9cc05..0000000000 --- a/public/stylesheets/nvui.css +++ /dev/null @@ -1,31 +0,0 @@ -.nvui h2 { - font-weight: bold; - margin-top: 0.5em; -} -.nvui .moves { - max-height: 140px; - overflow-y: auto; -} -.nvui .board { - font-family: monospace; - font-size: 1.5em; - margin: 0; -} -.nvui .pieces h3 { - font-weight: bold; -} -.nvui .pieces h3 { - margin: 0 5px 0 0; - display: inline; -} -.nvui .notify { - color: #dc322f; - font-weight: bold; -} -.nvui .active { - font-weight: bold; - color: #d85000; -} -.nvui .content a { - margin-right: 1em; -} diff --git a/public/stylesheets/page.css b/public/stylesheets/page.css deleted file mode 100644 index 746f392e6f..0000000000 --- a/public/stylesheets/page.css +++ /dev/null @@ -1,43 +0,0 @@ -div.doc_box .body { - font-size: 1.2em; - text-align: justify; -} -div.doc_box .body h2 { - font-size: 1.3em; - margin-top: 1.5em; - border-bottom: 1px solid #eee; -} -div.doc_box .body h3 { - font-size: 1.3em; - font-family: 'Roboto'; - font-weight: 300; -} -div.doc_box .body em { - font-style: italic; -} -div.doc_box .body h3 em { - font-family: 'Roboto'; - font-weight: 300; -} -div.doc_box .body p, -div.doc_box .body ul, -div.doc_box .body ol { - margin: 1em 0; -} -div.doc_box .body ul li { - list-style: disc outside; - margin: 0.5em 0 0 1.5em; -} -div.doc_box .body ol li { - list-style: decimal inside; - margin: 0.5em 0; -} -div.doc_box .body li { - margin-left: 2em; -} -div.doc_box .body a { - color: #3893E8; -} -div.doc_box .body iframe { - width: 100%; -} diff --git a/public/stylesheets/piece/alpha.css b/public/stylesheets/piece/alpha.css deleted file mode 100644 index f546720d1f..0000000000 --- a/public/stylesheets/piece/alpha.css +++ /dev/null @@ -1,12 +0,0 @@ -body.base .is2d piece.pawn.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik01MjAgMTc2OWgxMDA4cTgtOTctMTMyLTE4Mi0xMzItMTAxLTE5Ni41LTIzOS41VDExMjAgMTAzOUg5MjhxLTE1IDE3MC03OS41IDMwOC41VDY1MiAxNTg3cS0xNDEgODUtMTMyIDE4MnptNTA0IDc0SDQ0NnYtNzRxLTQtODAgNDEuNS0xMzdUNjEzIDE1MjRxMTE3LTkxIDE3MS41LTIxNy41VDg2MyAxMDM5SDU3NmwyODQtMjM5cS04Ni03NC04Ni0xODggMC0xMDMgNzMtMTc3dDE3Ny03NHExMDMgMCAxNzYuNSA3NHQ3My41IDE3N3EwIDExNC04NiAxODhsMjg0IDIzOWgtMjg3cTIzIDE0MSA3OCAyNjcuNXQxNzIgMjE3LjVxNzkgNTEgMTI0LjUgMTA4dDQyLjUgMTM3djc0ek03NTYgOTc0aDUzNmwtMjI1LTE5MXExMzQtMzEgMTM0LTE3MSAwLTc2LTUyLjUtMTI2LjVUMTAyNCA0MzVxLTczIDAtMTI1IDUwLjVUODQ3IDYxMnEwIDE0MCAxMzQgMTcxeiIgZmlsbD0iIzEwMTAxMCIvPjxnIGZpbGw9IiNmOWY5ZjkiPjxwYXRoIGQ9Ik04NzMuNDU3IDg4MS4zNDdjNTYuNTQ4LTQ3LjkxMiAxMDMuOTAxLTkwLjIyNSAxMDUuMjMtOTQuMDI4cy0xMy41Ni0xNC4xMTktMzMuMDg2LTIyLjkyNGMtMTUyLjI1Mi02OC42NTYtMTA4LjA5My0zMDIuNTM3IDYwLjktMzIyLjU1MiAzNS41MzctNC4yMDggNTEuMTYtMS4wNDMgOTAuOTYgMTguNDMgMTI5LjI3OCA2My4yNSAxMzIuMjU3IDI0Ni43MDkgNC45MzggMzA0LjEyMi0xOS41MjYgOC44MDUtMzQuNDE1IDE5LjEyLTMzLjA4NiAyMi45MjQgMS4zMjggMy44MDMgNDguNjgyIDQ2LjExNiAxMDUuMjMgOTQuMDI4bDEwMi44MTUgODcuMTE0SDc3MC42NDJ6Ii8+PHBhdGggZD0iTTc4MS4wMTcgOTYxLjg3YzAtMy42MjQgNy4wMjktMTAuOTggMTUuNjItMTYuMzQ1IDIxLjE5Ni0xMy4yMzcgMTc4LjkzMS0xNTIuMDcgMTgyLjQyLTE2MC41NiAxLjUzMi0zLjcyOC03LjI1NC05LjI5OS0xOS41MjUtMTIuMzc5LTEyLjI3Mi0zLjA4LTIyLjMxMi04LjQyMi0yMi4zMTItMTEuODdzLTkuNzIzLTExLjQ3NS0yMS42MDgtMTcuODM2Yy00OS41NzktMjYuNTMzLTcyLjM1Mi0xMjcuNTMtNDQuMDM3LTE5NS4yOTcgNS45ODMtMTQuMzIgMTEuNDg2LTI4Ljk2NiAxMi4yMjgtMzIuNTQ2IDIuMjEyLTEwLjY2NyAzNS4zNzMtNDEuMjIgNDQuNzQtNDEuMjIgNC43NzIgMCA4LjY3Ny0zLjIzNCA4LjY3Ny03LjE4OCAwLTEzLjIgODEuOTQ3LTI2Ljc4NiAxMTUuNjgxLTE5LjE3OCA1MC43MzQgMTEuNDQzIDExNi43OTMgNjIuMTMgMTI2LjIxIDk2Ljg0MiAxOS43MzUgNzIuNzUyIDE5LjQzIDEwMi42NC0xLjQ1NSAxNDIuOTc1LTE1Ljk1NCAzMC44MTItNjYuMDE2IDc3LjQwMy05Mi4wNDYgODUuNjY0LTEwLjU0NiAzLjM0OC0xNy45ODQgOC45NS0xNi41MjggMTIuNDUgMy40MTggOC4yMTcgMTYxLjc1NyAxNDcuMzI2IDE4Mi4yODEgMTYwLjE0MyA4LjU5MSA1LjM2NSAxNS42MiAxMi43MiAxNS42MiAxNi4zNDZzLTEwOS4zNDIgNi41OS0yNDIuOTgzIDYuNTljLTEzMy42NCAwLTI0Mi45ODMtMi45NjYtMjQyLjk4My02LjU5em0tMjYwLjMzOSA3OTYuMDA3YzAtMTUuODUgMjYuMjM2LTcyLjMzNSA0MS41NTEtODkuNDU2IDguMTctOS4xMzQgNTAuMTA3LTQ1LjAyNCA5My4xOTMtNzkuNzU2IDE1Mi45NDEtMTIzLjI5IDIzMy41ODgtMjY2LjUxNSAyNjUuOTc5LTQ3Mi4zNjRsMTAuOTczLTY5LjczOGgxODMuMjUybDEwLjk3MyA2OS43MzhjMzEuMDQgMTk3LjI3IDExMy42ODEgMzQ5LjUzIDI0OC4xMDcgNDU3LjEyMyAxMTUuMDQxIDkyLjA3NyAxMzMuODQgMTEzLjcyNiAxNDcuMjI1IDE2OS41NDVsNS43MjIgMjMuODY1aC01MDMuNDg4Yy0zNDAuMzE4IDAtNTAzLjQ4Ny0yLjkwMy01MDMuNDg3LTguOTU3eiIvPjwvZz48L3N2Zz4='); } -body.base .is2d piece.knight.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMDA0IDEwOTJxMzEgMTcgNTQgNDIgMjEtMTUgMzYuNS0xMy41dDMzLjUtMS41cTc4LTExIDEyOC41LTg1dDUyLjUtMTY1bC0xOS02N3EtNTUgMjM5LTE4OCAyNTctMjEgMy00NSA1LjV0LTUzIDI3LjV6TTc0NiA2NDNsLTQ2LTYwcTYtMzkgMTE1LjUtMTA3LjVUMTAzNiAzMzJsMTE1LTE1NCA5NiAyMTdxMzQyIDE3MiA0MzIuNSA0MTcuNVQxNzI3IDE0MTZxLTE4IDEyOCA0LjUgMjM2LjVUMTc4OSAxODQzSDU0N3EtOS0xNzggMzktMzAxLjVUNzY5IDEzMDRxNzgtMTYgMTE1LTcxdDU1LTg1cS0yMzYtNDItMjkyIDYwbC01NiAxMDItMjE3LTEyMSAxMTUtODItNTEtNTAtMTIyIDg2LTEyLTI5NyAzOTYtMjYzcTEyIDE4IDIzIDMxdDIzIDI5TDM4MCA4ODRsNCAxMjUgNjQtNDEgMTM4IDE0NC03OCA2NSA0NyAyOCAzOC41LTQ1IDEwOC41LTczcTU0LTE4IDE2NS0yN3QxOTEgNzRxLTU2IDYzLTkxIDEzMi41VDgxNSAxMzY5cS05MiA3OS0xNDYgMTc2LjVUNjIxIDE3NjloMTAxOXEtMzUtMTMzLTMyLTIzNC41dDEyLjUtMTk5IDktMjA1VDE1ODkgODc4cS01MS0xMjYtMTM0LTIzNHQtMjYyLTE4OGwtNTktMTMzLTQ5IDY5cS05OSA2Mi0yMDggMTMxVDc0NiA2NDN6bTI5MiAzMGwtMjEyLTIgMTE2LTEwMHEzMC0yNSA4MCAzOC41dDE2IDYzLjV6TTUwMiA4NjhsMzcgMzEtNDYgNTUtNTctMjYgMzMtNTZ6IiBmaWxsPSIjMTAxMDEwIi8+PHBhdGggZD0iTTYyNy45NDcgMTcwNi4zMDZjNy4wNjUtNzYuMDE0IDMwLjY1OC0xMzkuNjg3IDc2LjAxNS0yMDUuMTQyIDU1LjYxMy04MC4yNTcgOTQuMzM1LTExNi4xNDcgMTU1LjE0LTE0My43OTQgNzEuMzA0LTMyLjQyMSA3OS4zODUtMzkuODgxIDEzNC41ODItMTI0LjIzMSA2Mi4yMTEtOTUuMDY5IDc2LjM5LTEwOC40MzUgMTE1LjI2NC0xMDguNjY1IDQyLjMwNy0uMjUgOTQuOTExLTI1LjMyMSAxMjkuMzg3LTYxLjY2NSA1Ni4xNC01OS4xODIgODUuNjUtMTY5Ljk5NyA2My4zMDEtMjM3LjcxMmwtMTAuOTA3LTMzLjA0OC0yMy42NDUgNzAuNDc0Yy0zNC4xMyAxMDEuNzIzLTY1LjQ5NCAxNDYuNTAyLTEyMy40MTYgMTc2LjIwNi0xNy43MDggOS4wODItNDIuMjQgMTYuNTEyLTU0LjUxNiAxNi41MTItMTIuMjc2IDAtMzYuNTQ2IDUuOTQ0LTUzLjkzNCAxMy4yMS0yOC41OSAxMS45NDUtMzUuNzQ4IDExLjgzNi03NC44MDgtMS4xMzgtNDYuNTg2LTE1LjQ3My0xNDQuMDc4LTEyLjM3OC0yMjIuNTYxIDcuMDY2LTQyLjgyMSAxMC42MS0xNTkuNzIgODQuNDg0LTE2OC4wNTQgMTA2LjIwNC02LjExNSAxNS45MzYtMjQuMjEyIDE3LjU4My0zOC4zMDkgMy40ODYtNy41NzMtNy41NzMtMS4zMzktMTcuNzIgMjUuNTM2LTQxLjU3bDM1LjU1NS0zMS41NTItNjkuNjEtNzMuMzUxLTY5LjYxMS03My4zNTItMzAuMzM1IDE0LjQ2Ni0zMC4zMzQgMTQuNDY1LTUuNDI4LTM5LjYwMmMtMi45ODYtMjEuNzgxLTUuNDI4LTQ1LjAxOS01LjQyOC01MS42MzkgMC02LjYyIDgyLjAzLTY2LjMzMyAxODIuMjkxLTEzMi42OTYgMTAwLjI2LTY2LjM2MiAxOTMuMDA2LTEzMy42MjEgMjA2LjEwMi0xNDkuNDY0IDM2LjI1Ny00My44NjIgNDguNDQ4LTUyLjk3NyAxOTAuNzA3LTE0Mi41ODcgOTUuNzY4LTYwLjMyNCAxMzcuNTE4LTkxLjg5NCAxNTEuNTQ2LTExNC41OTFsMTkuMzYyLTMxLjMyOCAyOS41NTYgNjYuMDg1YzI2LjAyIDU4LjE3NSAzMy44MjMgNjguMDAzIDY1LjIgODIuMTIxIDE5MC40MzcgODUuNjg3IDMzMy41MTYgMjczLjM3IDM3OS4zOTMgNDk3LjY2NSAxOS41NTIgOTUuNTg4IDE5LjgyMiAxNDkuMTA2IDIuNjI1IDUyMC42NzgtNC4yMjQgOTEuMjctMi4zIDEzMi4yMTYgOC43MTEgMTg1LjMzNSA3Ljc3NCAzNy41IDE0LjEzNCA3MS42NyAxNC4xMzQgNzUuOTMyIDAgNC40NTktMjE0LjI2NSA3Ljc1LTUwNC41NjkgNy43NUg2MjIuMzIxem0tMTAwLjE1LTgyMS45NDRjLTI3LjE4OC0yOC45NDEtNTUuODc3LTI1Ljg4NC03Ni42MzggOC4xNjctMjIuNTYgMzctMjIuMTI0IDM5LjExMyAxMC45NDMgNTMuMTA0IDI2LjkzMyAxMS4zOTcgMjkuNDcxIDEwLjczNyA1Ni4zNjEtMTQuNjVsMjguMTU4LTI2LjU4NXptNTIzLjU3My0yMzIuNDVjLTQuNjU4LTI2LjYxOC01Mi41My04Mi4wODgtNzUuOTA5LTg3Ljk1NS0yNC42NTYtNi4xODgtNDEuNzc2IDQuMTQtMTA3LjY2NCA2NC45NTVsLTQ3LjczIDQ0LjA1NCAxMTcuMTUzLTEuOTQ4YzExMS40MDctMS44NTEgMTE3LjAwNi0yLjc4OCAxMTQuMTUtMTkuMTA2eiIgZmlsbD0iI2Y5ZjlmOSIvPjwvc3ZnPg=='); } -body.base .is2d piece.bishop.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMDI0IDM1NnE2NiAwIDY0LTY2IDEtNTUtNjQtNTUtNjYgMC02NCA1NS0zIDY2IDY0IDY2em0wIDEyMDRxMCAxMTQtMTAxIDE5OC41VDcwMCAxODQzSDIwNXEwLTExNyA2NS0xNzl0MTQyLTYyaDI1MHE1MSAwIDg4LTd0NzEtNjBxMTItMjAgMTAtMTZoNzZxLTcgMjEtMyAxMy00NSAxMDUtMTA5IDEyNC41VDY0OSAxNjc2SDQwOXEtNTIgMC04NiA0MHQtMzQgNTNoNDI0cTY2IDAgMTU4LjUtNjV0OTMuNS0xODVINjI0cTY3LTExNiA3Mi0yMjktMTE0LTExOS0xNjItMjIzLjVUNTI4IDg0M3EzMy05NiAxMTgtMTg5LjVUOTU4IDQwN3EtMTctMTEtNDYtMzZ0LTI5LTc5cTAtNTggNDEtOTZ0MTAwLTM4cTU4IDAgOTkuNSAzOHQ0MS41IDk2cTAgNTQtMjkuNSA3OXQtNDUuNSAzNnEyMjYgMTUzIDMxMSAyNDYuNVQxNTIwIDg0M3E0MiAxMTktNiAyMjMuNVQxMzUyIDEyOTBxNCAxMTMgNzIgMjI5aC0zNDFxMCAxMjAgOTMgMTg1dDE1OSA2NWg0MjRxMC0xMy0zNC41LTUzdC04NS41LTQwaC0yNDBxLTgzIDAtMTQ2LjUtMTkuNVQxMTQ0IDE1MzJxNCA4LTMtMTNoNzZxLTItNCAxMCAxNiAzMyA1MyA3MCA2MHQ4OSA3aDI1MHE3NiAwIDE0MS41IDYydDY1LjUgMTc5aC00OTVxLTEyMyAwLTIyMy41LTg0LjVUMTAyNCAxNTYwem0wLTExNGgyODNxLTI4LTg0LTI5LTE1NC0xMjAtNDEtMjU0LTM4LTEzNS0zLTI1NCAzOC0yIDcwLTI5IDE1NHptMC0yNjdxMTU5LTEgMjg1IDQyIDE4OS0xODAgMTQyLTM0Ni02MC0xOTMtNDI3LTQzMS0zNjggMjM4LTQyNyA0MzEtNDggMTY2IDE0MiAzNDYgMTI1LTQzIDI4NS00MnptLTQ3LTM2MVY3MTRoOTR2MTA0aDk1djg5aC05NXYxNjVoLTk0VjkwN2gtOTV2LTg5eiIgZmlsbD0iIzEwMTAxMCIvPjxwYXRoIGQ9Ik05ODAuMTggMzMzLjM0NGMtMjIuMTktMjIuMTktMjIuMTktNTUuOTEzIDAtNzguMTAyIDM1LjgzOC0zNS44MzggMTA0LjEzNS0xMC4yMjcgMTA0LjEzNSAzOS4wNSAwIDI5LjQ1OC0yOS4wMjMgNTYuNDA4LTYwLjc0NiA1Ni40MDgtMTQuNDYzIDAtMzMuNzQ3LTcuNzE0LTQzLjM5LTE3LjM1NnptLTI4OC42MjMgODI5LjU4Yy04Ni4wMTYtMTAzLjMwNC0xMTguNDMtMjE3LjUxNS04NS4yMDQtMzAwLjIyNCAyMy40Ni01OC40MDIgODcuNjI1LTE0NS40ODIgMTUyLjg1NC0yMDcuNDQzIDY2LjY1Ni02My4zMTcgMTkzLjgzNy0xNjEuNzE1IDI0My43ODktMTg4LjYxNmwyNy4zMzgtMTQuNzIyIDkwLjc5NCA2Ni4xNjdjMjMwLjMxIDE2Ny44NDEgMzQ3LjIyNiAzMjMuNDQ0IDMzMy4xNjkgNDQzLjQxMS02LjgxIDU4LjExNS00Ni4wNCAxMzguMTY0LTk4LjcxNiAyMDEuNDI3bC00NC4wNDkgNTIuOTAxLTYzLjcxLTE3LjQ2MWMtNTMuMTY2LTE0LjU3Mi05MC4yOC0xNy40NjItMjI0LjI1My0xNy40NjItMTMzLjk3MyAwLTE3MS4wODYgMi44OS0yMjQuMjUyIDE3LjQ2MmwtNjMuNzEgMTcuNDYxem0zODQuMDgtMTY1LjcxNnYtODIuNDRoOTUuNDU4VjgxMC42MzJoLTk1LjQ1OFY3MDYuNDk2SDk3MS41MDF2MTA0LjEzNmgtOTUuNDU4djEwNC4xMzZoOTUuNDU4djE2NC44OGgxMDQuMTM2em0tMzI5LjY2IDQ0NC43NDZjLjA1Ny0xLjE5MyA1Ljg2OC0yMy42NDggMTIuOTE0LTQ5Ljg5OCA3LjA0Ni0yNi4yNTEgMTIuODU4LTU4LjM2IDEyLjkxNC03MS4zNTEuMDkzLTIxLjE1NyA1LjMxLTI1LjIzMiA1MC4wMDItMzkuMDUxIDcwLjg4Ny0yMS45MTkgMzMxLjU4LTIyLjI2MSA0MDEuNzEtLjUyOGw0OC4wODMgMTQuOTAxIDEwLjIyMyA1OS42MThjNS42MjMgMzIuNzkgMTIuNzE1IDY2LjExMiAxNS43NiA3NC4wNDggNS4wOTMgMTMuMjctMTYuODU3IDE0LjQzLTI3My4wODUgMTQuNDMtMTUzLjI0MyAwLTI3OC41NzctLjk3Ni0yNzguNTItMi4xNjl6bS00MzMuNzUxIDI5Ni44NjljMzguMjAzLTUzLjY1IDQ2LjIyNC01NS41NzQgMjU1LjMzMi02MS4yMzYgMTA1LjI2Ni0yLjg1IDIwNS4zMjYtOS42ODcgMjIyLjQ0MS0xNS4xOTkgMzguNjMyLTEyLjQ0IDg3LjMwOC02MC4xNCAxMDcuODQ1LTEwNS42ODUgMTIuNzk0LTI4LjM3MiAxOS44ODYtMzQuNDc4IDQwLjA0Ny0zNC40NzggMjIuOTIgMCAyNC4xNjQgMS44MTggMTkuMzA3IDI4LjIwMy0xNS42MTcgODQuODM2LTU4Ljg2MSAxMzYuNzE3LTE1My45MTMgMTg0LjY1MmwtNTkuNzQzIDMwLjEyOEgyOTMuNDM4em05MzEuNjI4LTMuNzQzYy05NS41OS00OC4yMDctMTM1LjA5NC05NC4wMDMtMTUwLjAyNS0xNzMuOTIzLTcuMTItMzguMTA3LTYuNzkyLTM4LjkyNiAxNS40Ny0zOC42NzQgMTguNDQuMjEgMjguMTcxIDkuNjUzIDUxLjQxNyA0OS44OTggNTMuODU1IDkzLjIzOSA5Mi42MTIgMTA1Ljc5MiAzMjcuMTI0IDEwNS45NTggMTgzLjcxMS4xMyAyMDQuOTk3IDUuMjE2IDI0NS41MiA1OC42NjZsMjEuMzgzIDI4LjIwM2gtNDUxLjE0N3oiIGZpbGw9IiNmOWY5ZjkiLz48L3N2Zz4='); } -body.base .is2d piece.rook.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMDI0IDE1MDFINjQzbDUtNzRoNzUybDUgNzR6bTAtNjYxSDY5Mmw1LTc0aDY1NGw1IDc0em0wIDEwMDNIMzgzbDI5LTI2NCAxNTktMTE4IDUwLTY1OS0xNDktMTA3LTE3LTM0MWgyODl2MTQ3aDEzN1YzNTRoMjg2djE0N2gxMzdWMzU0aDI4OWwtMTcgMzQxLTE0OSAxMDcgNTAgNjU5IDE1OSAxMTggMjkgMjY0em0wLTc0aDU1N2wtMTUtMTQ5LTE2MS0xMTktNTQtNzM1IDE1Mi0xMDkgMTMtMjMwaC0xMzh2MTQ4aC0yODVWNDI3SDk1NXYxNDhINjcwVjQyN0g1MzJsMTMgMjMwIDE1MiAxMDktNTQgNzM1LTE2MSAxMTktMTUgMTQ5eiIgZmlsbD0iIzEwMTAxMCIvPjxwYXRoIGQ9Ik02NTUuODMyIDEzNzguNDk1YzUuMDIzLTQ5LjY4NCAzOC40MDUtNTAwLjU2NyAzOC40MDUtNTE4LjcyMiAwLTExLjA2MSA0NC44NjgtMTIuODA0IDMyOS43NjMtMTIuODA0czMyOS43NjMgMS43NDMgMzI5Ljc2MyAxMi44MDRjMCAxOC4xNTUgMzMuMzgyIDQ2OS4wMzggMzguNDA1IDUxOC43MjJsNC4xNjcgNDEuMjJoLTc0NC42N3ptLTMxLjA0OC02NzAuODQ4bC03My43MzMtNTIuNTQzLTUuNjQ3LTcxLjExOGMtMy4xMDYtMzkuMTE1LTYuMDM1LTg5LjY2Ny02LjUwOS0xMTIuMzM5bC0uODYxLTQxLjIyaDEzMC4xNjl2MTQ3LjUyNmgyOTUuMDUxVjQzMC40MjdoMTIxLjQ5MnYxNDcuNTI2aDI5NS4wNTFWNDMwLjQyN2gxMzAuMTY5bC0uODYgNDEuMjJjLS40NzUgMjIuNjcyLTMuNDAzIDczLjIyNC02LjUxIDExMi4zNGwtNS42NDcgNzEuMTE3LTczLjczMyA1Mi41NDMtNzMuNzM0IDUyLjU0M0g2OTguNTE4ek00NzEuNjY3IDE3NTEuNjQ4YzIuMzI0LTguMzUzIDYuNzUxLTQxLjA2IDkuODM4LTcyLjY4NGw1LjYxMS01Ny40OTcgNzkuMzM1LTU3LjQ4NiA3OS4zMzUtNTcuNDg2aDc1Ni40MjhsNzkuMzM1IDU3LjQ4NiA3OS4zMzUgNTcuNDg2IDUuNjExIDU3LjQ5N2MzLjA4NyAzMS42MjMgNy41MTQgNjQuMzMgOS44MzggNzIuNjgzIDMuOTkzIDE0LjM1LTI2LjQ1MiAxNS4xODctNTUyLjMzMyAxNS4xODdzLTU1Ni4zMjYtLjgzNy01NTIuMzMzLTE1LjE4NnoiIGZpbGw9IiNmOWY5ZjkiLz48L3N2Zz4='); } -body.base .is2d piece.queen.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Im0xMDI0IDE3NjloNDc4cS01My0xMzAtNDMtMjgwLTEwMC0zOS0yMTMtNjcuNXQtMjIyLTI4LjVxLTExMCAwLTIyMyAyOC41dC0yMTIgNjcuNXE5IDE1MC00MyAyODB6bTAtNDUwcTExMSAwIDIyMy41IDI2LjV0MjIwLjUgNjcuNXExNy0xMDUgNjAuNS0yMTIuNXQxMDUuNS0yMTIuNWwtMjIwIDE1NS0xMjMtNjAxLTI2NyA1NTUtMjY3LTU1NS0xMjMgNjAxLTIyMC0xNTVxNjEgMTA1IDEwNC41IDIxMi41dDYxLjUgMjEyLjVxMTA4LTQxIDIyMC41LTY3LjV0MjIzLjUtMjYuNXptMCA1MjRoLTU4M3ExMTQtMjMxIDU3LjUtNDU2LjV0LTIwMi41LTQ0OS41cS0xMiAyLTE5IDItNTQgMC05Mi41LTM4LjV0LTM4LjUtOTIuNSAzOC41LTkyLjUgOTIuNS0zOC41IDkyLjUgMzguNSAzOC41IDkyLjVxMCAyMC02IDM4LTQgMTQtMTUgMzNsMTk2IDEzOSAxMDAtNDg2cS02NC0zMS03Mi0xMDMtNS00NCAyOS05MXQ4OC01M3E1NC01IDk2IDI5dDQ4IDg4cTcgNjgtNDYgMTE0bDE5OCA0MTIgMTk4LTQxMnEtNTQtNDYtNDYtMTE0IDYtNTQgNDgtODh0OTYtMjlxNTQgNiA4Ny41IDUzdDI5LjUgOTFxLTkgNzItNzIgMTAzbDEwMCA0ODYgMTk2LTEzOXEtMTItMTktMTUtMzMtNi0xOC02LTM4IDAtNTQgMzguNS05Mi41dDkyLjUtMzguNSA5Mi41IDM4LjUgMzguNSA5Mi41LTM4LjUgOTIuNS05Mi41IDM4LjVxLTcgMC0xOS0yLTE0NyAyMjQtMjAzIDQ0OS41dDU4IDQ1Ni41em0tNzQ4LTEwOTdxLTYyIDAtNjIgNjJ0NjIgNjJxNjMgMCA2My02MnQtNjMtNjJ6bTQ2Ni0zOTRxLTYyIDAtNjIgNjJ0NjIgNjIgNjItNjItNjItNjJ6bS0xNTIgMTE2NyAxMTkgNzItMTM0IDg2cTE5LTg2IDE1LTE1OHptMTE4Mi03NzNxLTYzIDAtNjMgNjJ0NjMgNjJxNjIgMCA2Mi02MnQtNjItNjJ6bS00NjYtMzk0cS02MiAwLTYyIDYydDYyIDYyIDYyLTYyLTYyLTYyem0xNTIgMTE2Ny0xMTkgNzIgMTM0IDg2cS0yMC04Ni0xNS0xNTh6bS01NzMgNDcgMTM5LTgzIDEzOSA4Ni0xMzkgODR6IiBmaWxsPSIjMTAxMDEwIi8+PGcgZmlsbD0iI2Y5ZjlmOSI+PHBhdGggZD0ibTU3Ni43NzQgMTM3NC4xNTZjLTE0LjI2Ny02Ni43NC01Mi4zMjgtMTczLjQ0MS05MS44MTMtMjU3LjM5My0yMy4zNy00OS42ODgtNDAuODM1LTkxLjk5OS0zOC44MS05NC4wMjQgMi4wMjUtMi4wMjQgNDUuODMgMjYuMTc2IDk3LjM0NCA2Mi42NjhsOTMuNjYzIDY2LjM1IDU4LjQ0Ny0yODQuNzMzYzMyLjE0NS0xNTYuNjA0IDU5LjYzMi0yOTAuMzA0IDYxLjA4Mi0yOTcuMTE0czYwLjk0NCAxMDkuMzY3IDEzMi4yMTIgMjU4LjE3YzcxLjI2NyAxNDguODAyIDEzMi4wNjIgMjcwLjU1IDEzNS4xMDEgMjcwLjU1czYzLjgzNC0xMjEuNzQ4IDEzNS4xMDEtMjcwLjU1YzcxLjI2Ny0xNDguODAzIDEzMC43NjMtMjY0Ljk4IDEzMi4yMTItMjU4LjE3IDEuNDUgNi44MSAyOC45MzYgMTQwLjUxIDYxLjA4MiAyOTcuMTEzbDU4LjQ0NyAyODQuNzMyIDkzLjY2My02Ni4zNDljNTEuNTE0LTM2LjQ5MiA5NS41NDItNjQuNDcgOTcuODM5LTYyLjE3M3MtMTEuOTU3IDM2LjI2NC0zMS42NzUgNzUuNDhjLTM4LjQ3NCA3Ni41MjItNzguMzE2IDE4NC40MDUtOTUuMzE0IDI1OC4wODYtNS43OCAyNS4wNTgtMTMuMDUgNDUuNDktMTYuMTUzIDQ1LjQwNnMtNDEuNjYtMTEuNTIxLTg1LjY4LTI1LjQxNWMtMTQyLjUzNi00NC45ODctMjEyLjk4OC01Ni4zNDQtMzQ5LjUyMi01Ni4zNDRzLTIwNi45ODYgMTEuMzU3LTM0OS41MjEgNTYuMzQ0Yy00NC4wMjEgMTMuODk0LTgyLjY1NyAyNS4zMy04NS44NTcgMjUuNDE1LTMuMi4wODQtOC41MzItMTIuNTM4LTExLjg0OC0yOC4wNXoiLz48cGF0aCBkPSJtNTU4LjkyNiAxNzQ3LjMwOWMzLjA1OC0xMC43NCA3Ljc3MS0yOS41ODkgMTAuNDc0LTQxLjg4OCAzLjU3NC0xNi4yNjEgMjMuNjAzLTM0LjAxNSA3My40MjQtNjUuMDg0IDM3LjY4LTIzLjQ5OCA2OC41NjgtNDUuMjA0IDY4LjY0LTQ4LjIzNi4wNy0zLjAzMi0yNy4yMDYtMjIuMDMtNjAuNjE3LTQyLjIxNi0zMy40MS0yMC4xODctNjAuNzQ1LTQxLjM0LTYwLjc0NS00Ny4wMDUgMC0xMi43NjkgMTQxLjMyLTU5LjgxMiAyNTEuMzU3LTgzLjY3NCAxMTAuOTY0LTI0LjA2MiAyNTQuMTE4LTI0LjA2MiAzNjUuMDgyIDAgMTEwLjAzNyAyMy44NjIgMjUxLjM1NyA3MC45MDUgMjUxLjM1NyA4My42NzQgMCA1LjY2Ni0yNy4zMzUgMjYuODE4LTYwLjc0NSA0Ny4wMDVzLTYwLjY2IDM5LjE4NC02MC41NTQgNDIuMjE2Yy4xMDUgMy4wMzIgMjkuNDI5IDIzLjkgNjUuMTYzIDQ2LjM3NiA2Mi44NDIgMzkuNTIzIDczLjgwNCA1Mi45NTMgODcuMzggMTA3LjA0NWw1LjM1IDIxLjMxMmgtOTQxLjEyNnptNTM4LjUyOS0xMzIuOTljMzUuOTY2LTIxLjgzNSA2NS4zNzMtNDIuMzM2IDY1LjM0OC00NS41NTktLjA1NC03LjE0My0xMjcuNzE0LTg4LjI5OS0xMzguODk3LTg4LjI5OS0xNC43MjggMC0xMzkuNjI1IDc5LjgyNy0xMzcuMDA1IDg3LjU2NiAzLjQwMiAxMC4wNDggMTIwLjk5NiA4NC42NTQgMTM0LjYyMiA4NS40MSA1Ljc5Ny4zMiAzOS45NjYtMTcuMjgyIDc1LjkzMi0zOS4xMTd6bTY0MC43NC03NTYuODc5Yy0yNy45MjQtMTcuNzUxLTI3Ljg1My04MS4zMy4xMS05OS4xMSAzNS4zMzYtMjIuNDY5IDkyLjc0NiA4LjIyNyA5Mi43NDYgNDkuNTg5IDAgNDEuNDMtNTcuNDE0IDcyLjA1LTkyLjg1NiA0OS41MnptLTQ1My44NTYtMzg5LjQ2NWMtMzQuMjc2LTEyLjcyNS00Ni42OTMtNjcuNzE2LTIxLjA3NS05My4zMzUgMTcuNTc2LTE3LjU3NiA2Ny45NjQtMTcuNTc2IDg1LjU0IDAgMTYuMzYyIDE2LjM2MiAxNy44MTcgNTUuNjc1IDIuNzkgNzUuMzQ4LTEyLjE0OSAxNS45MDMtNDcuNDQzIDI1LjM0Mi02Ny4yNTUgMTcuOTg3em0tNTY0LjA2OCAwYy0zNC4yNzYtMTIuNzI1LTQ2LjY5My02Ny43MTYtMjEuMDc1LTkzLjMzNSAxNy41NzYtMTcuNTc2IDY3Ljk2NC0xNy41NzYgODUuNTQgMCAxNi4zNjIgMTYuMzYyIDE3LjgxNyA1NS42NzUgMi43OSA3NS4zNDgtMTIuMTQ4IDE1LjkwMy00Ny40NDIgMjUuMzQyLTY3LjI1NSAxNy45ODd6bS00ODUuOTY2IDM3OC45OTVjLTIyLjE5LTIyLjE5LTIyLjE5LTU1LjkxMyAwLTc4LjEwMiAxNy40NDEtMTcuNDQyIDU2LjEtMjIuODAyIDc1LjUtMTAuNDcgMjcuOTI0IDE3Ljc1IDI3Ljg1MyA4MS4zMjktLjExIDk5LjExLTE5LjMgMTIuMjctNTcuOTg5IDYuODYzLTc1LjM5LTEwLjUzOXoiLz48L2c+PC9zdmc+'); } -body.base .is2d piece.king.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik05NzcgMjk4di05NWg5NHY5NWgxMDd2OTVoLTEwN3YxNTNxLTQ4LTE2LTk0IDBWMzkzSDg3MHYtOTV6bTQ3IDMxNHEtNDcgMC0xMzYgMTIxLTMxLTM2LTUwLTU1IDkzLTE0MCAxODYtMTQwIDkyIDAgMTg2IDE0MC0yMCAxOS01MCA1NS05MC0xMjEtMTM2LTEyMXptLTQ0NyA5MDdsLTI2IDE1NiAxNDUtODR6bTQxMC0yMDZxLTEtMTQ3LTM2LjUtMjc0LjVUODcwIDg0NXEtNDUtODgtMTMxLjUtMTUzVDU3MCA2MjdxLTEwMyAwLTIwOCA5M1QyNTcgOTQ5cTAgMTA5IDg2LjUgMjM2VDU0NiAxNDA4cTIxMi04OCA0NDEtOTV6bTM3IDUzMEg0NDhsNjEtMzY1cS0zMjUtMjgwLTMyNi01MzUtMS0xNTkgMTI1LTI3NC41VDU3NSA1NTNxNzggMCAxNTguNSA0N1Q4NzYgNzE5cTYxIDc0IDk4LjUgMTY0LjVUMTAyNCAxMDM0cTEyLTYwIDQ5LTE1MC41dDk5LTE2NC41cTYxLTcyIDE0Mi0xMTl0MTU5LTQ3cTE0MCAwIDI2NiAxMTUuNVQxODY1IDk0M3EtMiAyNTUtMzI2IDUzNWw2MSAzNjV6bTAtNzRoNDg5bC01MC0yOThxLTIxNi04NC00MzktODR0LTQzOSA4NGwtNTAgMjk4em00NDctMjUwbDI2IDE1Ni0xNDUtODR6bS00MTAtMjA2cTIyOSA3IDQ0MSA5NSAxMTUtOTYgMjAyLTIyM3Q4Ny0yMzZxMC0xMzYtMTA1LjUtMjI5VDE0NzggNjI3cS04MyAwLTE2OS41IDY1VDExNzggODQ1cS00NiA2Ni04MS41IDE5My41VDEwNjEgMTMxM3ptLTE3NiAyMzNsMTQxLTg0IDEzNyA4Ni0xNDEgODR6IiBmaWxsPSIjMTAxMDEwIi8+PGcgZmlsbD0iI2Y5ZjlmOSI+PHBhdGggZD0iTTQ2Ny40NzMgMTMyNC43MzdjLTEzNC43My0xMzkuMzcxLTIwMC40MjgtMjU5LjY0Mi0yMDEuNzI3LTM2OS4yOTMtMS4wNDgtODguNDU1IDE5Ljk5My0xNDEuMjc1IDgzLjE5Mi0yMDguODM1IDEzOC43MTYtMTQ4LjI4OCAyOTYuODAxLTE0OC45NiA0MzcuNjEzLTEuODU5IDYyLjUwMyA2NS4yOTYgMTA3LjMwMiAxNDIuODUzIDE0Mi40OTMgMjQ2LjY4NyAyNy44MjkgODIuMTEzIDUxLjQ3NCAyMDcuNDg3IDUxLjUzMSAyNzMuMjMyLjAzOCA0NC4zNzYtOC4zNTkgNTAuNTI2LTY5LjM4OSA1MC44Mi01NS4yNTIuMjY2LTE4NS4yMiAyNi45NzgtMjc3LjY5NCA1Ny4wNzRsLTkxLjEyIDI5LjY1NXptNTQ0Ljc4LTM0Ny43NTdjLTguODg3LTQ0LjQzNC01OC4xOS0xNTQuODQzLTg5LjQxNy0yMDAuMjRsLTI5LjY5Mi00My4xNjQgMzIuMDYzLTM5LjEzYzc4LjI5Ny05NS41NSAxMTkuMjg5LTk1LjU1IDE5Ny41ODYgMGwzMi4wNjMgMzkuMTMtMjkuNjkyIDQzLjE2NGMtMzEuMjI3IDQ1LjM5Ny04MC41MyAxNTUuODA2LTg5LjQxNyAyMDAuMjQtNi42OTcgMzMuNDgzLTE2Ljc5NyAzMy40ODMtMjMuNDk0IDB6Ii8+PHBhdGggZD0iTTQ3MC4zNzYgMTMyNS42NzljLTE0NC4yLTE2MC44OC0xOTIuNjYxLTI0Ni44NjQtMTk5LjU0LTM1NC4wNDItNS4wNS03OC43MTIgOC43MzktMTMxLjc4OCA0Ny4zOTctMTgyLjQzMyAxNS44ODctMjAuODEzIDI4Ljg4Ni00MS43MTQgMjguODg2LTQ2LjQ0NSAwLTQuNzMyIDQuMzY1LTguNjAzIDkuNzAxLTguNjAzczIzLjcwNy0xMi4yOTcgNDAuODI1LTI3LjMyNmM3Ny4xNDYtNjcuNzM1IDE3NC4yMjctODYuNDg4IDI1OS4xOTItNTAuMDY4IDE1NS45NSA2Ni44NDcgMjY2LjAzIDI0NS4yIDMwOS44MjIgNTAxLjk3NCAyMy43NzQgMTM5LjM5NiAxNy42MiAxNTYuODQ0LTU1LjMyOSAxNTYuODQ0LTU4LjMyIDAtMTYyLjA4OCAyMC45NzgtMjY0Ljc5NSA1My41My00Ny43NDMgMTUuMTMzLTkxLjc0OCAyOC40NjgtOTcuNzg4IDI5LjYzNC02LjA0IDEuMTY1LTQxLjMwNy0zMS43MTQtNzguMzctNzMuMDY1em05MzkuNzMyIDQ1LjYzNmMtODguNjk2LTI4Ljk4Ni0yMTguODA5LTU1LjU2NC0yNzMuMjk0LTU1LjgyNi02Mi41OTgtLjMwMS02OS40MjQtNS44MjctNjkuNDI0LTU2LjE5MSAwLTY3LjM1OSAyMy40NDktMTg5Ljg3OCA1Mi4wMi0yNzEuODA0IDM1LjAzNS0xMDAuNDU3IDgwLjk1LTE3OC45MjUgMTQyLjA0LTI0Mi43NDQgMTQwLjgxLTE0Ny4xIDI5OC44OTUtMTQ2LjQzIDQzNy42MTIgMS44NiA2My4zMDcgNjcuNjc0IDg0LjI5NiAxMjAuNDQzIDgzLjA2NyAyMDguODM0LTEuMDE3IDczLjE4OS0yNi4xNjEgMTQwLjQ5My04NS41NjIgMjI5LjAyOS00MS45NzQgNjIuNTYxLTE2MC40ODEgMTk1LjU4NS0xODUuMzYzIDIwOC4wNjktOS4xNyA0LjYwMS00NS4yMjYtMi45NjktMTAxLjA5Ni0yMS4yMjd6bS04NjUuOTgyIDM2Mi45NzdjNy43NTktNTAuNDk0IDE0Ljc5LTU4LjQyNSA5MC41MzYtMTAyLjExNWw3MC44ODYtNDAuODg4LTQ2Ljg3NS0yOC40NzZjLTcyLjA4NS00My43OS03Ny45MzItNDkuNTk3LTcxLjkyOS03MS40NDIgNi0yMS44MyA4MS40MTgtNDkuMzcxIDIxMi43MTYtNzcuNjggMTAyLjEwMy0yMi4wMTYgMzQ2Ljk3Ny0yMi4wMTYgNDQ5LjA4IDAgMTMxLjI5OCAyOC4zMDkgMjA2LjcxNiA1NS44NSAyMTIuNzE2IDc3LjY4IDYuMDAzIDIxLjg0NS4xNTYgMjcuNjUyLTcxLjkyOSA3MS40NDJsLTQ2Ljg3NiAyOC40NzYgNzAuODg3IDQwLjg4OGM3NS43NDUgNDMuNjkgODIuNzc3IDUxLjYyIDkwLjUzNiAxMDIuMTE1bDUgMzIuNTQySDUzOS4xMjZ6bTU1MC4xMTgtMTM4Ljc3MWMzNy43Ni0yMi42MjkgNjcuNDIyLTQ0Ljg0MSA2NS45MTYtNDkuMzZzLTMyLjIzNC0yNi43MDktNjguMjg0LTQ5LjMwOWwtNjUuNTQ0LTQxLjA5MS02Ny43MjYgNDAuNjRjLTM3LjI0OSAyMi4zNS02OC44NzEgNDQuNTA1LTcwLjI3MiA0OS4yMy0yLjAyNyA2LjgzNyAxMjEuOTkzIDkxLjAzMyAxMzQuMDg5IDkxLjAzMyAxLjc0MSAwIDM0LjA2LTE4LjUxNCA3MS44Mi00MS4xNDN6Ii8+PC9nPjwvc3ZnPg=='); } -body.base .is2d piece.pawn.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMDI0IDE4NDNINDQ2di03NHEtNC04MCA0MS41LTEzN1Q2MTMgMTUyNHExMTctOTEgMTcxLjUtMjE3LjVUODYzIDEwMzlINTc2bDI4NC0yMzlxLTg2LTc0LTg2LTE4OCAwLTEwMyA3My0xNzd0MTc3LTc0cTEwMyAwIDE3Ni41IDc0dDczLjUgMTc3cTAgMTE0LTg2IDE4OGwyODQgMjM5aC0yODdxMjMgMTQxIDc4IDI2Ny41dDE3MiAyMTcuNXE3OSA1MSAxMjQuNSAxMDh0NDIuNSAxMzd2NzR6IiBmaWxsPSIjMTAxMDEwIi8+PC9zdmc+'); } -body.base .is2d piece.knight.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik01MDIgODY4bC01MiAxLTI2IDY0IDY5IDIxIDQ2LTU1em01MzYtMTg3cTM0IDEtMTYtNjh0LTgwLTQyTDgyNiA2ODB6bS0zMzgtOThxNi0zOSAxMTUuNS0xMDcuNVQxMDM2IDMzMmwxMTUtMTU0IDk2IDIxN3EzNDIgMTcyIDQzMi41IDQxNy41VDE3MjcgMTQxNnEtMTggMTI4IDQuNSAyMzZ0NTcuNSAxOTBsLTEyNDIgMXEtOS0xNzggMzktMzAxLjVUNzY5IDEzMDRxNTAtMTEgODIuNS0zOS41VDkwNSAxMjA2bDYyLjUtMSAxMzgtMjkgMTM5LTk3IDY2LjUtMjA3cTAtMTctOC41LTM0dC0xMS41LTM3cS02MiAyMjgtMTYxIDI4OC41VDkzOSAxMTQ4cS0yMzYtNDItMjkyIDYwbC01NiAxMDItMjE3LTEyMSAxMTUtODItNTEtNTAtMTIyIDg2LTEyLTI5N3ptOTgxIDExOTJxLTEwMi0xMzAtODUtMzA4LjV0MjctMzYyLjUtNTAtMzUxLjVUMTI1NyA0NzdxMjIwIDE2NCAyNTIuNSAzNDJ0MTYuNSAzNTAuNS0xMiAzMjkgMTY3IDI3Ni41eiIgZmlsbD0iIzEwMTAxMCIvPjxwYXRoIGQ9Ik0xNjAxLjMwNSAxNjkzLjA0Yy04MS4wOC04OS43NDctOTEuNTg0LTE1Ni41NDEtNzQuMjI3LTQ3Mi4wNSAyMC4zNzktMzcwLjQ1LTguNzUyLTQ5NS4xMTktMTUwLjU1OC02NDQuMzQtMjguMzQ4LTI5LjgzLTQ3LjgxMy01NC4yMzYtNDMuMjU2LTU0LjIzNiAxNy4wMTcgMCAxMDAuMTEgNTguNDM0IDE0NC42NSAxMDEuNzI2IDU3LjA1MiA1NS40NSA4Ni4xNCAxMDcuODkxIDEwOS42MzkgMTk3LjY2MyAzNC45OTQgMTMzLjY4NiAzNy41NDQgMjAxLjk0IDE3LjMyNyA0NjMuODE4LTE5Ljk5IDI1OC45Ni0xNy41NDEgMzEyLjYyIDE4LjA1OCAzOTUuNjcxIDkuNjk5IDIyLjYyNSAxNi4xMyA0Mi42NCAxNC4yOTQgNDQuNDc3LTEuODM3IDEuODM3LTE4LjAwNC0xMi44OS0zNS45MjctMzIuNzI5ek04OTYuNzAzIDYyMS4zM2M1NS42ODMtNTMuMjY4IDYwLjQyMi01NS45NjEgNzguMTAyLTQ0LjM3OCAyNi4wNjggMTcuMDc4IDc2LjQwMyA4NC4wNjYgNzAuNDMgOTMuNzMtMi42OTcgNC4zNjQtNTAuNTU4IDcuODA1LTEwNi4zNTcgNy42NDZsLTEwMS40NTQtLjI4OHpNNDY0LjI3MSA5NDEuNDQ2Yy0yNy40NDEtNi42LTMxLjI3LTE0LjY4NC0yMC45Ni00NC4yNTggNy42ODMtMjIuMDM4IDE0LjQ4NC0yNy42NTYgMzMuNDgxLTI3LjY1NiAxMy4xMTIgMCAzMC4zNjMgNy4yMDggMzguMzM1IDE2LjAxNyAxMy41OTIgMTUuMDIgMTMuMzY3IDE3LjQ1LTMuNjI0IDM5LjA1LTkuOTY1IDEyLjY3LTIwLjc2NCAyMi41ODItMjMuOTk3IDIyLjAyOC0zLjIzMy0uNTUzLTEzLjY4OS0yLjg4NS0yMy4yMzUtNS4xODF6IiBmaWxsPSIjZWNlY2VjIi8+PC9zdmc+'); } -body.base .is2d piece.bishop.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik03NjggMTM2NXEtNSAzOS0yNiA4Mmg1NjRxLTE4LTM2LTI2LTgyem00OTUtNzNsNDYtNzNxLTE0Mi00OS0yODUtNDctMTQ0LTItMjg1IDQ3bDQ2IDczcTExOC00MCAyMzktMzggMTIwLTIgMjM5IDM4em0tNDMyIDIyN0g2MjRxNjctMTE2IDcyLTIyOS0xMTQtMTE5LTE2Mi0yMjMuNVQ1MjggODQzcTMzLTk2IDExOC0xODkuNVQ5NTggNDA3cS0xNy0xMS00Ni0zNnQtMjktNzlxMC01OCA0MS05NnQxMDAtMzhxNTggMCA5OS41IDM4dDQxLjUgOTZxMCA1NC0yOS41IDc5dC00NS41IDM2cTIyNiAxNTMgMzExIDI0Ni41VDE1MjAgODQzcTQyIDExOS02IDIyMy41VDEzNTIgMTI5MHE0IDExMyA3MiAyMjloLTIwN3EtMi00IDEwIDE2IDMzIDUzIDcwIDYwdDg5IDdoMjUwcTc2IDAgMTQxLjUgNjJ0NjUuNSAxNzloLTQ5NXEtMTIzIDAtMjIzLjUtODQuNVQxMDI0IDE1NjBxMCAxMTQtMTAxIDE5OC41VDcwMCAxODQzSDIwNXEwLTExNyA2NS0xNzl0MTQyLTYyaDI1MHE1MSAwIDg4LTd0NzEtNjBxMTItMjAgMTAtMTZ6bTE0Ni03MDFoLTk1djg5aDk1djE2NWg5NFY5MDdoOTV2LTg5aC05NVY3MTRoLTk0eiIgZmlsbD0iIzEwMTAxMCIvPjxwYXRoIGQ9Ik03NjEuNTQgMTQwNi42OThsMTIuODU2LTM5LjA1aDQ5OS4yMDhsMTIuODU2IDM5LjA1IDEyLjg1NiAzOS4wNTFINzQ4LjY4NHptMy41MzgtMTU1Ljc1bC0xNy42NTMtMjkuOTIgNDUtMTMuMDY4Yzg0LjY2NC0yNC41ODYgMTcyLjQxLTMzLjU5NSAyNzQuOTY1LTI4LjIzIDU0Ljg4OCAyLjg3MiAxMTMuNDY0IDguOTggMTMwLjE3IDEzLjU3M3M0Ni43NzggMTIuNjA2IDY2LjgzIDE3LjgwNmwzNi40NiA5LjQ1NC0xNy43OTEgMzAuMTUyYy0yMC4zMjcgMzQuNDUyLTIzLjMxIDM0Ljk5My05MS41ODUgMTYuNTg2LTY4LjcyLTE4LjUyNi0yNjYuMjI4LTE4LjUyNi0zMzQuOTQ4IDAtNjguMjMgMTguMzk1LTcxLjI2NiAxNy44NTItOTEuNDQ4LTE2LjM1M3ptMjE1LjUzMi0yNjkuNDd2LTgyLjQ0aC05NS40NTd2LTc4LjEwMmg5NS40NThWNzE2LjhoODYuNzc5djEwNC4xMzZoOTUuNDU4djc4LjEwMWgtOTUuNDU4djE2NC44ODFoLTg2Ljc4eiIgZmlsbD0iI2VjZWNlYyIvPjwvc3ZnPg=='); } -body.base .is2d piece.rook.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMDI0IDE4NDNIMzgzbDI5LTI2NCAxNTktMTE4IDUwLTY1OS0xNDktMTA3LTE3LTM0MWgyODl2MTQ3aDEzN1YzNTRoMjg2djE0N2gxMzdWMzU0aDI4OWwtMTcgMzQxLTE0OSAxMDcgNTAgNjU5IDE1OSAxMTggMjkgMjY0em0wLTk4OWgzMzNsLTYtODhINjk3bC02IDg4em0wIDY0N2gzODFsLTYtODdINjQ5bC02IDg3eiIgZmlsbD0iIzEwMTAxMCIvPjxwYXRoIGQ9Ik02NTAuODQ3IDE0NTcuMDN2LTM5LjA1aDc0Ni4zMDV2NzguMTAxSDY1MC44NDd6bTQzLjM5LTYxOS4zOWMwLTguOTQ4IDIuNDQxLTI4LjQ3NCA1LjQyNC00My4zOWw1LjQyNC0yNy4xMThoNjM3LjgzbDUuNDI0IDI3LjExOWMxMy4wNjYgNjUuMzI5IDQzLjg4IDU5LjY2LTMyNC4zMzkgNTkuNjYtMzE2LjY1IDAtMzI5Ljc2My0uNjQ2LTMyOS43NjMtMTYuMjd6IiBmaWxsPSIjZWNlY2VjIi8+PC9zdmc+'); } -body.base .is2d piece.queen.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik01OTAgMTUxOXE0IDcyLTE1IDE1OGwxMzQtODZ6bTQzNCAzMjRINDQxcTExNC0yMzEgNTcuNS00NTYuNVQyOTYgOTM3cS0xMiAyLTE5IDItNTQgMC05Mi41LTM4LjVUMTQ2IDgwOHQzOC41LTkyLjVUMjc3IDY3N3Q5Mi41IDM4LjVUNDA4IDgwOHEwIDIwLTYgMzgtNCAxNC0xNSAzM2wxOTYgMTM5IDEwMC00ODZxLTY0LTMxLTcyLTEwMy01LTQ0IDI5LTkxdDg4LTUzcTU0LTUgOTYgMjl0NDggODhxNyA2OC00NiAxMTRsMTk4IDQxMiAxOTgtNDEycS01NC00Ni00Ni0xMTQgNi01NCA0OC04OHQ5Ni0yOXE1NCA2IDg3LjUgNTN0MjkuNSA5MXEtOSA3Mi03MiAxMDNsMTAwIDQ4NiAxOTYtMTM5cS0xMi0xOS0xNS0zMy02LTE4LTYtMzggMC01NCAzOC41LTkyLjVUMTc3MSA2Nzd0OTIuNSAzOC41VDE5MDIgODA4dC0zOC41IDkyLjVUMTc3MSA5MzlxLTcgMC0xOS0yLTE0NyAyMjQtMjAzIDQ0OS41dDU4IDQ1Ni41em0wLTQ1MHExMDkgMCAyMjIgMjguNXQyMTMgNjcuNXEyLTQxIDExLTg5LTEwOC00Mi0yMjEuNS02OHQtMjI0LjUtMjYtMjI1IDI2LTIyMSA2OHE4IDQ4IDExIDg5IDk5LTM5IDIxMi02Ny41dDIyMy0yOC41em0wIDM3Nmg0NzhxLTE1LTM0LTI0LTczSDU3MHEtMTAgMzktMjQgNzN6bTQzNC0yNTBsLTExOSA3MiAxMzQgODZxLTIwLTg2LTE1LTE1OHptLTU3MyA0N2wxMzkgODcgMTM5LTg0LTEzOS04NnoiIGZpbGw9IiMxMDEwMTAiLz48cGF0aCBkPSJNNTU1LjM5IDE3NTguNTgzYzAtMS42NzQgNC4yODctMTUuMzQyIDkuNTI3LTMwLjM3M2w5LjUyNy0yNy4zMjloODk5LjExMmw5LjUyNyAyNy4zM2M1LjI0IDE1LjAzIDkuNTI3IDI4LjY5OCA5LjUyNyAzMC4zNzJzLTIxMC44NzQgMy4wNDQtNDY4LjYxIDMuMDQ0LTQ2OC42MS0xLjM3LTQ2OC42MS0zLjA0NHptMzk2Ljk3My0xNTYuMTUxbC01OC42Mi0zNy4yNTIgNjUuMTM3LTM3LjI3IDY1LjEzNy0zNy4yNjggNjAuNzM3IDM2LjA4NGMzMy40MDYgMTkuODQ1IDYwLjY2MyAzOC44MzcgNjAuNTcxIDQyLjIwNC0uMjMgOC41MS0xMDguODg2IDcxLjI1Ny0xMjIuOTEgNzAuOTgtNi4yODgtLjEyNC0zNy44MTEtMTYuOTktNzAuMDUyLTM3LjQ3OHptNDYwLjU2IDMwLjIzNmMtMjcuMTIzLTE3LjM3MS00OS4zODUtMzUuNDg4LTQ5LjQ3Mi00MC4yNjEtLjA4Ni00Ljc3MyAyMC4xNTMtMjEuNTA3IDQ0Ljk3Ni0zNy4xODZsNDUuMTMyLTI4LjUwOSA1LjIwMyA2Ny41NmMyLjg2MSAzNy4xNTcgNC44MTQgNjguMTAzIDQuMzM5IDY4Ljc2OC0uNDc1LjY2Ni0yMy4wNTUtMTMuMDAyLTUwLjE3OC0zMC4zNzJ6TTU4OC44IDE0NTIuNTMxYy0uNzE2LTE2LjE0LTEuNjkyLTMzLjY0MS0yLjE3LTM4Ljg5My0yLjA5NS0yMy4wNTMgMjAzLjkyMi04MC43ODYgMzQzLjc3NC05Ni4zMzcgNzIuMDI0LTguMDA5IDExNC42ODctOC4wODUgMTg0LjA3Ny0uMzMxIDE0MC41NzMgMTUuNzA4IDM0OC45NjggNzMuNzgyIDM0Ni44ODkgOTYuNjY4LS40NzggNS4yNTItMS40NTQgMjIuNzUzLTIuMTcgMzguODkzbC0xLjMwMiAyOS4zNDUtMTAxLjk2Ni0zMi41OTNjLTEzMy45MTctNDIuODA0LTIxMC44MDYtNTUuNzA5LTMzMS45MzItNTUuNzA5cy0xOTguMDE1IDEyLjkwNS0zMzEuOTMyIDU1LjcxbC0xMDEuOTY2IDMyLjU5MXptLTEuMTUgMTUwLjIyNmMyLjExMi0zNC4zMyA0LjUyNC02NS40MSA1LjM2Mi02OS4wNjcuODM3LTMuNjU3IDI0LjI1IDcuNTY4IDUyLjAzIDI0Ljk0NCAyNy43OCAxNy4zNzYgNDcuMjg0IDM0LjU5MyA0My4zNDMgMzguMjYtMy45NCAzLjY2OC0yOS4wODEgMjAuNTMyLTU1Ljg2OSAzNy40NzVsLTQ4LjcwNCAzMC44MDZ6IiBmaWxsPSIjZWNlY2VjIi8+PC9zdmc+'); } -body.base .is2d piece.king.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjA0OCAyMDQ4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xMDI0IDE3NjloNDg5bC0xMi03M0g1NDdsLTEyIDczem0wLTkyMXEtMjUtNjAtNjItMTExIDMxLTQ4IDYyLTY1IDMwIDE3IDYyIDY1LTM4IDUxLTYyIDExMXptLTk3IDQ1NHEtMTU0IDExLTMwMyA1OC0xMjMtMTA4LTIwMC0yMTMuNVQzNDcgOTQ1cTAtODkgNzMuNS0xNTlUNTY5IDcxNnE2NyAwIDEzNC41IDYyLjVUODA2IDkwOXEzMCA1NCA3NSAxNzV0NDYgMjE4em0tMzUwIDIxN2wtMjYgMTU2IDE0NS04NHptNDQ3LTkwN3EtNDcgMC0xMzYgMTIxLTMxLTM2LTUwLTU1IDkzLTE0MCAxODYtMTQwIDkyIDAgMTg2IDE0MC0yMCAxOS01MCA1NS05MC0xMjEtMTM2LTEyMXptMCA3NzVxLTEtMTI2LTQyLTI2Ny41VDg5OCA4OTNxLTgtMTQtMTQtMjd0LTEyLTIzcS0yOC00My00OC02OS01MS02My0xMjAtMTA1dC0xMzQtNDJxLTEwMyAwLTIwOCA5M1QyNTcgOTQ5cTAgMTIwIDk5IDI1NC41VDYwNSAxNDYzcTIwMS03NCA0MTktNzZ6bTAgNDU2SDQ0OGw2MS0zNjVxLTMyNS0yODAtMzI2LTUzNS0xLTE1OSAxMjUtMjc0LjVUNTc1IDU1M3E3OCAwIDE1OC41IDQ3VDg3NiA3MTlxNjEgNzQgOTguNSAxNjQuNVQxMDI0IDEwMzRxMTItNjAgNDktMTUwLjV0OTktMTY0LjVxNjEtNzIgMTQyLTExOXQxNTktNDdxMTQwIDAgMjY2IDExNS41VDE4NjUgOTQzcS0yIDI1NS0zMjYgNTM1bDYxIDM2NXptOTctNTQxcTAtOTcgNDUtMjE4dDc2LTE3NXEzNC02OCAxMDEuNS0xMzAuNVQxNDc5IDcxNnE3NCAwIDE0Ny41IDcwdDc0LjUgMTU5cTAgOTYtNzcgMjAxLjVUMTQyNCAxMzYwcS0xNTAtNDctMzAzLTU4em0zNTAgMjE3bC0xMTkgNzIgMTQ1IDg0em0tNDQ3LTEzMnEyMTcgMiA0MTkgNzYgMTUwLTEyNSAyNDktMjU5LjV0OTktMjU0LjVxMC0xMzYtMTA1LjUtMjI5VDE0NzggNjI3cS02NiAwLTEzNSA0MnQtMTE5IDEwNXEtMjEgMjYtNDggNjktNiAxMC0xMi41IDIzbC0xMy41IDI3cS00NCA4NS04NSAyMjYuNXQtNDEgMjY3LjV6bS0xMzkgMTU5bDEzOSA4NiAxMzktODQtMTM5LTg2em05Mi0xMjQ4di05NWg5NHY5NWgxMDd2OTVoLTEwN3YxNTNxLTQ4LTE2LTk0IDBWMzkzSDg3MHYtOTV6IiBmaWxsPSIjMTAxMDEwIi8+PHBhdGggZD0iTTE0MDEuNDkyIDE0NDUuMDIyYy03OC44NjYtMjcuOTcyLTI4MC44NS02My40OS0zNjEuMDU1LTYzLjQ5LTEzLjU3MyAwLTguMzctOTIuOTM4IDkuOTMxLTE3Ny40MSA0Ni41NDEtMjE0LjgxNSAxMzQuNDczLTM5Ny42NiAyMzEuNDgtNDgxLjMzNyAxMDQuMjg3LTg5Ljk1OCAyMDIuNDI1LTExMC4yOTIgMzAxLjg4LTYyLjU1IDEwMS43MDcgNDguODIzIDE2OC44NTcgMTI2LjQ3NiAxOTIuNjExIDIyMi43MzYgMTEuOTUzIDQ4LjQzNCAxMi41MDcgNjUuODM1IDMuNjMzIDExMy45OTUtMjAuMDQ3IDEwOC44LTgxLjM3OSAyMDUuMzU5LTIyMS4yMzYgMzQ4LjMwNC0xMDkuOTk3IDExMi40MjUtMTE0LjEyNyAxMTUuMDQ1LTE1Ny4yNDQgOTkuNzUyem0xMjIuODE3LTE3OS42NmMxMzQuNzYxLTE0MS40NjQgMTc1LjQ4My0yMTQuNDYyIDE3Ni4xOTItMzE1LjgzNy40NjgtNjcuMDM3LTEzLjQzNC0xMDEuODM2LTYxLjUyNS0xNTQuMDA4LTE0My40MS0xNTUuNTgxLTMxNS4xMDQtODMuNDUyLTQzNC4zOTggMTgyLjQ5LTQyLjYyIDk1LjAxNS03Ni40ODcgMjA2LjA5Ny04Mi41MTUgMjcwLjY1LTUuNzA3IDYxLjEwOS0xMC4yMzIgNTcuNDkzIDg0LjgwNCA2Ny43NjYgMjYuNTk3IDIuODc1IDgzLjIyMSAxNC4zNzYgMTI1LjgzIDI1LjU1N3M4MS45NzQgMjAuNzUgODcuNDc3IDIxLjI2M2M1LjUwMi41MTMgNTIuMzYzLTQzLjUzMyAxMDQuMTM1LTk3Ljg4em0tMTAwMS42MTYgMTEzLjRjLTIzOS44MzktMjMwLjkzMy0zMDguMTEtNDAyLjY1Ni0yMjUuNjg5LTU2Ny42ODYgMTAuNzA0LTIxLjQzNCA0MS4wMDMtNTguNjcxIDY3LjMzLTgyLjc1IDEwMy4zODctOTQuNTU1IDIwOS4xNzItMTE3LjU3NCAzMDguOTkyLTY3LjIzNyAxMDQuOTQgNTIuOTIgMTc3LjM0OSAxMzcuMjI3IDIzNy45MjYgMjc3LjAyNSA1OC41MjggMTM1LjA2OCAxMDQuMDcgMzEwLjE1NiAxMDQuMDcgNDAwLjEwMXY0MS45MzZsLTU4LjU3NiA1LjMzOWMtMTA0LjAwNiA5LjQ4LTIxNC43ODEgMjkuNTg3LTI4My44NjQgNTEuNTI0bC02Ny40NDUgMjEuNDE4em0xODYuMzgzLTM1Ljg3NGM0Ni43MjctMTEuNzA5IDEwNi40MzYtMjMuNjYgMTMyLjY4Ny0yNi41NTggOTUuMDIzLTEwLjQ5MiA4OS45MTQtNi4yMDcgODMuOTItNzAuMzk4LTYuNjE3LTcwLjg2LTU2LjQ1Ny0yMTguODI4LTEwNi40NTMtMzE2LjA0OC04OC4zNTItMTcxLjgwNC0yMTAuMDY4LTI0OS4wMTUtMzIwLjA4NC0yMDMuMDQ3LTQ0LjE2IDE4LjQ1MS0xMTYuNDM3IDg3LjQ5NS0xMzUuNzUyIDEyOS42NzgtMTkuMDUxIDQxLjYwNy0yMC45ODcgMTMyLjE4NS0zLjg1MiAxODAuMjA4IDIyLjY1NSA2My40OTMgNzEuMDc2IDEzMC45MzcgMTY0LjE0OSAyMjguNjQgNTEuNzcyIDU0LjM0NyA5NS41NDggOTguODEzIDk3LjI4IDk4LjgxMyAxLjczIDAgNDEuMzc4LTkuNTggODguMTA1LTIxLjI4OHptMjk0LjI5OC0zOTMuMTQ4Yy0xNi41MjItNTAuNTU2LTcyLjA1My0xNjQuMTk2LTk3LjMxNC0xOTkuMTQ0LTEzLjM1Mi0xOC40NzItMTEuOTAxLTIxLjEyMSA0MS41NzktNzUuOTMzIDM4LjAwNC0zOC45NSA2MS45OTQtNTYuNzkyIDc2LjM2MS01Ni43OTJzMzguMzU3IDE3Ljg0MyA3Ni4zNjEgNTYuNzkyYzUzLjcxNyA1NS4wNTUgNTQuOTggNTcuMzc5IDQxLjI4IDc1LjkzMy0yNC4wMjEgMzIuNTMyLTk5Ljc0NCAxOTEuMTI4LTEwNS40NyAyMjAuOTAyLTIuOTg0IDE1LjUxMi03LjkxOSAyOC4xNzUtMTAuOTY3IDI4LjE0LTMuMDQ5LS4wMzQtMTIuODcyLTIyLjQ4OC0yMS44My00OS44OTd6bTU2LjY2Ny0xNTcuNjhsMzEuNzAyLTU5LjgxOC0yOC41MzMtMzEuMTUyYy0xNS42OTQtMTcuMTMzLTMzLjMzOC0zMS4xNTEtMzkuMjEtMzEuMTUxcy0yMy41MTYgMTQuMDE4LTM5LjIxIDMxLjE1MWwtMjguNTMzIDMxLjE1MiAzMS43MDIgNTkuODE4YzE3LjQzNiAzMi45IDMzLjY1NSA1OS44MTkgMzYuMDQxIDU5LjgxOXMxOC42MDUtMjYuOTE4IDM2LjA0MS01OS44MTl6bS05OC45NTYgNzk1LjQ5NmMtMzIuMjE3LTIwLjEzNi01OC41NDMtMzguNjA3LTU4LjUwMi00MS4wNDYuMDQtMi40NCAyNy4wNjYtMjEuMDg3IDYwLjA1Ny00MS40MzhsNTkuOTgzLTM3LjAwMyA2MS40MzQgMzYuOTU4YzMzLjc5IDIwLjMyNyA2MS40MzQgMzkuNDYyIDYxLjQzNCA0Mi41MjIgMCA0LjkxNS0xMTUuODQ0IDc3LjIzNS0xMjMuMDA4IDc2Ljc5Mi0xLjU1Mi0uMDk2LTI5LjE4MS0xNi42NS02MS4zOTgtMzYuNzg1em0tNDAyLjMwOCA2NC43NjNjMi4zNjYtOC4xMzMgNi45NjMtMzQuMzEyIDEwLjIxNS01OC4xNzcgOC45OTQtNjYgMTEuMDQtNjcuMTkxIDYyLjMzLTM2LjI4NiAyNS4wNTggMTUuMDk5IDQ1LjU2IDI5LjkxMSA0NS41NiAzMi45MTdzLTI3LjU0MiAyMS40MS02MS4yMDQgNDAuODk4Yy00NS4xMTcgMjYuMTItNjAuMDczIDMxLjU0OC01Ni45MDEgMjAuNjQ4em04NzMuMDg3LTIwLjU5N2MtMzEuMDIzLTE4LjMwNC01Ny4zOTItMzYuMjMtNTguNTk4LTM5LjgzNC0yLjQ0Ny03LjMyMSA4Ni45NDYtNjMuNDA5IDkyLjM4OS01Ny45NjYgMy40MTcgMy40MTcgMjYuNDYzIDEyOC45NzQgMjMuOTI4IDEzMC4zNjItLjcyMS4zOTYtMjYuNjk1LTE0LjI1Ny01Ny43MTktMzIuNTYyek01NDUuMDY1IDE3MzIuOTlsMy41NDYtMzAuMzczaDk1MC43NzlsMy41NDUgMzAuMzczIDMuNTQ2IDMwLjM3M0g1NDEuNTE5eiIgZmlsbD0iI2VjZWNlYyIvPjwvc3ZnPg=='); } diff --git a/public/stylesheets/piece/cburnett.css b/public/stylesheets/piece/cburnett.css deleted file mode 100644 index 236fae8995..0000000000 --- a/public/stylesheets/piece/cburnett.css +++ /dev/null @@ -1,12 +0,0 @@ -body.base .is2d piece.pawn.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PHBhdGggZD0iTTIyLjUgOWMtMi4yMSAwLTQgMS43OS00IDQgMCAuODkuMjkgMS43MS43OCAyLjM4QzE3LjMzIDE2LjUgMTYgMTguNTkgMTYgMjFjMCAyLjAzLjk0IDMuODQgMi40MSA1LjAzLTMgMS4wNi03LjQxIDUuNTUtNy40MSAxMy40N2gyM2MwLTcuOTItNC40MS0xMi40MS03LjQxLTEzLjQ3IDEuNDctMS4xOSAyLjQxLTMgMi40MS01LjAzIDAtMi40MS0xLjMzLTQuNS0zLjI4LTUuNjIuNDktLjY3Ljc4LTEuNDkuNzgtMi4zOCAwLTIuMjEtMS43OS00LTQtNHoiIGZpbGw9IiNmZmYiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPjwvc3ZnPg=='); } -body.base .is2d piece.knight.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0yMiAxMGMxMC41IDEgMTYuNSA4IDE2IDI5SDE1YzAtOSAxMC02LjUgOC0yMSIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0yNCAxOGMuMzggMi45MS01LjU1IDcuMzctOCA5LTMgMi0yLjgyIDQuMzQtNSA0LTEuMDQyLS45NCAxLjQxLTMuMDQgMC0zLTEgMCAuMTkgMS4yMy0xIDItMSAwLTQuMDAzIDEtNC00IDAtMiA2LTEyIDYtMTJzMS44OS0xLjkgMi0zLjVjLS43My0uOTk0LS41LTItLjUtMyAxLTEgMyAyLjUgMyAyLjVoMnMuNzgtMS45OTIgMi41LTNjMSAwIDEgMyAxIDMiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNOS41IDI1LjVhLjUuNSAwIDEgMS0xIDAgLjUuNSAwIDEgMSAxIDB6bTUuNDMzLTkuNzVhLjUgMS41IDMwIDEgMS0uODY2LS41LjUgMS41IDMwIDEgMSAuODY2LjV6IiBmaWxsPSIjMDAwIi8+PC9nPjwvc3ZnPg=='); } -body.base .is2d piece.bishop.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxnIGZpbGw9IiNmZmYiIHN0cm9rZS1saW5lY2FwPSJidXR0Ij48cGF0aCBkPSJNOSAzNmMzLjM5LS45NyAxMC4xMS40MyAxMy41LTIgMy4zOSAyLjQzIDEwLjExIDEuMDMgMTMuNSAyIDAgMCAxLjY1LjU0IDMgMi0uNjguOTctMS42NS45OS0zIC41LTMuMzktLjk3LTEwLjExLjQ2LTEzLjUtMS0zLjM5IDEuNDYtMTAuMTEuMDMtMTMuNSAxLTEuMzU0LjQ5LTIuMzIzLjQ3LTMtLjUgMS4zNTQtMS45NCAzLTIgMy0yeiIvPjxwYXRoIGQ9Ik0xNSAzMmMyLjUgMi41IDEyLjUgMi41IDE1IDAgLjUtMS41IDAtMiAwLTIgMC0yLjUtMi41LTQtMi41LTQgNS41LTEuNSA2LTExLjUtNS0xNS41LTExIDQtMTAuNSAxNC01IDE1LjUgMCAwLTIuNSAxLjUtMi41IDQgMCAwLS41LjUgMCAyeiIvPjxwYXRoIGQ9Ik0yNSA4YTIuNSAyLjUgMCAxIDEtNSAwIDIuNSAyLjUgMCAxIDEgNSAweiIvPjwvZz48cGF0aCBkPSJNMTcuNSAyNmgxME0xNSAzMGgxNW0tNy41LTE0LjV2NU0yMCAxOGg1IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIi8+PC9nPjwvc3ZnPg=='); } -body.base .is2d piece.rook.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik05IDM5aDI3di0zSDl2M3ptMy0zdi00aDIxdjRIMTJ6bS0xLTIyVjloNHYyaDVWOWg1djJoNVY5aDR2NSIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiLz48cGF0aCBkPSJNMzQgMTRsLTMgM0gxNGwtMy0zIi8+PHBhdGggZD0iTTMxIDE3djEyLjVIMTRWMTciIHN0cm9rZS1saW5lY2FwPSJidXR0IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIi8+PHBhdGggZD0iTTMxIDI5LjVsMS41IDIuNWgtMjBsMS41LTIuNSIvPjxwYXRoIGQ9Ik0xMSAxNGgyMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciIvPjwvZz48L3N2Zz4='); } -body.base .is2d piece.queen.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik04IDEyYTIgMiAwIDEgMS00IDAgMiAyIDAgMSAxIDQgMHptMTYuNS00LjVhMiAyIDAgMSAxLTQgMCAyIDIgMCAxIDEgNCAwek00MSAxMmEyIDIgMCAxIDEtNCAwIDIgMiAwIDEgMSA0IDB6TTE2IDguNWEyIDIgMCAxIDEtNCAwIDIgMiAwIDEgMSA0IDB6TTMzIDlhMiAyIDAgMSAxLTQgMCAyIDIgMCAxIDEgNCAweiIvPjxwYXRoIGQ9Ik05IDI2YzguNS0xLjUgMjEtMS41IDI3IDBsMi0xMi03IDExVjExbC01LjUgMTMuNS0zLTE1LTMgMTUtNS41LTE0VjI1TDcgMTRsMiAxMnoiIHN0cm9rZS1saW5lY2FwPSJidXR0Ii8+PHBhdGggZD0iTTkgMjZjMCAyIDEuNSAyIDIuNSA0IDEgMS41IDEgMSAuNSAzLjUtMS41IDEtMS41IDIuNS0xLjUgMi41LTEuNSAxLjUuNSAyLjUuNSAyLjUgNi41IDEgMTYuNSAxIDIzIDAgMCAwIDEuNS0xIDAtMi41IDAgMCAuNS0xLjUtMS0yLjUtLjUtMi41LS41LTIgLjUtMy41IDEtMiAyLjUtMiAyLjUtNC04LjUtMS41LTE4LjUtMS41LTI3IDB6IiBzdHJva2UtbGluZWNhcD0iYnV0dCIvPjxwYXRoIGQ9Ik0xMS41IDMwYzMuNS0xIDE4LjUtMSAyMiAwTTEyIDMzLjVjNi0xIDE1LTEgMjEgMCIgZmlsbD0ibm9uZSIvPjwvZz48L3N2Zz4='); } -body.base .is2d piece.king.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0yMi41IDExLjYzVjZNMjAgOGg1IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIi8+PHBhdGggZD0iTTIyLjUgMjVzNC41LTcuNSAzLTEwLjVjMCAwLTEtMi41LTMtMi41cy0zIDIuNS0zIDIuNWMtMS41IDMgMyAxMC41IDMgMTAuNSIgZmlsbD0iI2ZmZiIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiLz48cGF0aCBkPSJNMTEuNSAzN2M1LjUgMy41IDE1LjUgMy41IDIxIDB2LTdzOS00LjUgNi0xMC41Yy00LTYuNS0xMy41LTMuNS0xNiA0VjI3di0zLjVjLTMuNS03LjUtMTMtMTAuNS0xNi00LTMgNiA1IDEwIDUgMTBWMzd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTExLjUgMzBjNS41LTMgMTUuNS0zIDIxIDBtLTIxIDMuNWM1LjUtMyAxNS41LTMgMjEgMG0tMjEgMy41YzUuNS0zIDE1LjUtMyAyMSAwIi8+PC9nPjwvc3ZnPg=='); } -body.base .is2d piece.pawn.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PHBhdGggZD0iTTIyLjUgOWMtMi4yMSAwLTQgMS43OS00IDQgMCAuODkuMjkgMS43MS43OCAyLjM4QzE3LjMzIDE2LjUgMTYgMTguNTkgMTYgMjFjMCAyLjAzLjk0IDMuODQgMi40MSA1LjAzLTMgMS4wNi03LjQxIDUuNTUtNy40MSAxMy40N2gyM2MwLTcuOTItNC40MS0xMi40MS03LjQxLTEzLjQ3IDEuNDctMS4xOSAyLjQxLTMgMi40MS01LjAzIDAtMi40MS0xLjMzLTQuNS0zLjI4LTUuNjIuNDktLjY3Ljc4LTEuNDkuNzgtMi4zOCAwLTIuMjEtMS43OS00LTQtNHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIxLjUiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIvPjwvc3ZnPg=='); } -body.base .is2d piece.knight.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0yMiAxMGMxMC41IDEgMTYuNSA4IDE2IDI5SDE1YzAtOSAxMC02LjUgOC0yMSIgZmlsbD0iIzAwMCIvPjxwYXRoIGQ9Ik0yNCAxOGMuMzggMi45MS01LjU1IDcuMzctOCA5LTMgMi0yLjgyIDQuMzQtNSA0LTEuMDQyLS45NCAxLjQxLTMuMDQgMC0zLTEgMCAuMTkgMS4yMy0xIDItMSAwLTQuMDAzIDEtNC00IDAtMiA2LTEyIDYtMTJzMS44OS0xLjkgMi0zLjVjLS43My0uOTk0LS41LTItLjUtMyAxLTEgMyAyLjUgMyAyLjVoMnMuNzgtMS45OTIgMi41LTNjMSAwIDEgMyAxIDMiIGZpbGw9IiMwMDAiLz48cGF0aCBkPSJNOS41IDI1LjVhLjUuNSAwIDEgMS0xIDAgLjUuNSAwIDEgMSAxIDB6bTUuNDMzLTkuNzVhLjUgMS41IDMwIDEgMS0uODY2LS41LjUgMS41IDMwIDEgMSAuODY2LjV6IiBmaWxsPSIjZWNlY2VjIiBzdHJva2U9IiNlY2VjZWMiLz48cGF0aCBkPSJNMjQuNTUgMTAuNGwtLjQ1IDEuNDUuNS4xNWMzLjE1IDEgNS42NSAyLjQ5IDcuOSA2Ljc1UzM1Ljc1IDI5LjA2IDM1LjI1IDM5bC0uMDUuNWgyLjI1bC4wNS0uNWMuNS0xMC4wNi0uODgtMTYuODUtMy4yNS0yMS4zNC0yLjM3LTQuNDktNS43OS02LjY0LTkuMTktNy4xNmwtLjUxLS4xeiIgZmlsbD0iI2VjZWNlYyIgc3Ryb2tlPSJub25lIi8+PC9nPjwvc3ZnPg=='); } -body.base .is2d piece.bishop.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxnIGZpbGw9IiMwMDAiIHN0cm9rZS1saW5lY2FwPSJidXR0Ij48cGF0aCBkPSJNOSAzNmMzLjM5LS45NyAxMC4xMS40MyAxMy41LTIgMy4zOSAyLjQzIDEwLjExIDEuMDMgMTMuNSAyIDAgMCAxLjY1LjU0IDMgMi0uNjguOTctMS42NS45OS0zIC41LTMuMzktLjk3LTEwLjExLjQ2LTEzLjUtMS0zLjM5IDEuNDYtMTAuMTEuMDMtMTMuNSAxLTEuMzU0LjQ5LTIuMzIzLjQ3LTMtLjUgMS4zNTQtMS45NCAzLTIgMy0yeiIvPjxwYXRoIGQ9Ik0xNSAzMmMyLjUgMi41IDEyLjUgMi41IDE1IDAgLjUtMS41IDAtMiAwLTIgMC0yLjUtMi41LTQtMi41LTQgNS41LTEuNSA2LTExLjUtNS0xNS41LTExIDQtMTAuNSAxNC01IDE1LjUgMCAwLTIuNSAxLjUtMi41IDQgMCAwLS41LjUgMCAyeiIvPjxwYXRoIGQ9Ik0yNSA4YTIuNSAyLjUgMCAxIDEtNSAwIDIuNSAyLjUgMCAxIDEgNSAweiIvPjwvZz48cGF0aCBkPSJNMTcuNSAyNmgxME0xNSAzMGgxNW0tNy41LTE0LjV2NU0yMCAxOGg1IiBzdHJva2U9IiNlY2VjZWMiIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiLz48L2c+PC9zdmc+'); } -body.base .is2d piece.rook.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik05IDM5aDI3di0zSDl2M3ptMy41LTdsMS41LTIuNWgxN2wxLjUgMi41aC0yMHptLS41IDR2LTRoMjF2NEgxMnoiIHN0cm9rZS1saW5lY2FwPSJidXR0Ii8+PHBhdGggZD0iTTE0IDI5LjV2LTEzaDE3djEzSDE0eiIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiLz48cGF0aCBkPSJNMTQgMTYuNUwxMSAxNGgyM2wtMyAyLjVIMTR6TTExIDE0VjloNHYyaDVWOWg1djJoNVY5aDR2NUgxMXoiIHN0cm9rZS1saW5lY2FwPSJidXR0Ii8+PHBhdGggZD0iTTEyIDM1LjVoMjFtLTIwLTRoMTltLTE4LTJoMTdtLTE3LTEzaDE3TTExIDE0aDIzIiBmaWxsPSJub25lIiBzdHJva2U9IiNlY2VjZWMiIHN0cm9rZS13aWR0aD0iMSIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciIvPjwvZz48L3N2Zz4='); } -body.base .is2d piece.queen.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxnIHN0cm9rZT0ibm9uZSI+PGNpcmNsZSBjeD0iNiIgY3k9IjEyIiByPSIyLjc1Ii8+PGNpcmNsZSBjeD0iMTQiIGN5PSI5IiByPSIyLjc1Ii8+PGNpcmNsZSBjeD0iMjIuNSIgY3k9IjgiIHI9IjIuNzUiLz48Y2lyY2xlIGN4PSIzMSIgY3k9IjkiIHI9IjIuNzUiLz48Y2lyY2xlIGN4PSIzOSIgY3k9IjEyIiByPSIyLjc1Ii8+PC9nPjxwYXRoIGQ9Ik05IDI2YzguNS0xLjUgMjEtMS41IDI3IDBsMi41LTEyLjVMMzEgMjVsLS4zLTE0LjEtNS4yIDEzLjYtMy0xNC41LTMgMTQuNS01LjItMTMuNkwxNCAyNSA2LjUgMTMuNSA5IDI2eiIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiLz48cGF0aCBkPSJNOSAyNmMwIDIgMS41IDIgMi41IDQgMSAxLjUgMSAxIC41IDMuNS0xLjUgMS0xLjUgMi41LTEuNSAyLjUtMS41IDEuNS41IDIuNS41IDIuNSA2LjUgMSAxNi41IDEgMjMgMCAwIDAgMS41LTEgMC0yLjUgMCAwIC41LTEuNS0xLTIuNS0uNS0yLjUtLjUtMiAuNS0zLjUgMS0yIDIuNS0yIDIuNS00LTguNS0xLjUtMTguNS0xLjUtMjcgMHoiIHN0cm9rZS1saW5lY2FwPSJidXR0Ii8+PHBhdGggZD0iTTExIDM4LjVhMzUgMzUgMSAwIDAgMjMgMCIgZmlsbD0ibm9uZSIgc3Ryb2tlLWxpbmVjYXA9ImJ1dHQiLz48cGF0aCBkPSJNMTEgMjlhMzUgMzUgMSAwIDEgMjMgMG0tMjEuNSAyLjVoMjBtLTIxIDNhMzUgMzUgMSAwIDAgMjIgMG0tMjMgM2EzNSAzNSAxIDAgMCAyNCAwIiBmaWxsPSJub25lIiBzdHJva2U9IiNlY2VjZWMiLz48L2c+PC9zdmc+'); } -body.base .is2d piece.king.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0NSIgaGVpZ2h0PSI0NSI+PGcgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMS41IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxwYXRoIGQ9Ik0yMi41IDExLjYzVjYiIHN0cm9rZS1saW5lam9pbj0ibWl0ZXIiLz48cGF0aCBkPSJNMjIuNSAyNXM0LjUtNy41IDMtMTAuNWMwIDAtMS0yLjUtMy0yLjVzLTMgMi41LTMgMi41Yy0xLjUgMyAzIDEwLjUgMyAxMC41IiBmaWxsPSIjMDAwIiBzdHJva2UtbGluZWNhcD0iYnV0dCIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciIvPjxwYXRoIGQ9Ik0xMS41IDM3YzUuNSAzLjUgMTUuNSAzLjUgMjEgMHYtN3M5LTQuNSA2LTEwLjVjLTQtNi41LTEzLjUtMy41LTE2IDRWMjd2LTMuNWMtMy41LTcuNS0xMy0xMC41LTE2LTQtMyA2IDUgMTAgNSAxMFYzN3oiIGZpbGw9IiMwMDAiLz48cGF0aCBkPSJNMjAgOGg1IiBzdHJva2UtbGluZWpvaW49Im1pdGVyIi8+PHBhdGggZD0iTTMyIDI5LjVzOC41LTQgNi4wMy05LjY1QzM0LjE1IDE0IDI1IDE4IDIyLjUgMjQuNWwuMDEgMi4xLS4wMS0yLjFDMjAgMTggOS45MDYgMTQgNi45OTcgMTkuODVjLTIuNDk3IDUuNjUgNC44NTMgOSA0Ljg1MyA5IiBzdHJva2U9IiNlY2VjZWMiLz48cGF0aCBkPSJNMTEuNSAzMGM1LjUtMyAxNS41LTMgMjEgMG0tMjEgMy41YzUuNS0zIDE1LjUtMyAyMSAwbS0yMSAzLjVjNS41LTMgMTUuNS0zIDIxIDAiIHN0cm9rZT0iI2VjZWNlYyIvPjwvZz48L3N2Zz4='); } diff --git a/public/stylesheets/piece/chess7.css b/public/stylesheets/piece/chess7.css deleted file mode 100644 index 82341d9327..0000000000 --- a/public/stylesheets/piece/chess7.css +++ /dev/null @@ -1,12 +0,0 @@ -body.base .is2d piece.pawn.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTIyLjk5MiA0NC43NTJxMS4zNDQtLjY0IDIuMTc2LTIuNDk2Ljg5Ni0yLjE3NiAxLjk4NC00Ljg2NCAxLjA4OC0yLjc1MiAyLjE3Ni01LjYzMi0uMjU2LS4xOTItLjUxMi0uMzItLjE5Mi0uMTI4LS4yNTYtLjI1Ni0xLjc5Mi0xLjk4NCAwLTMuMzkybC43MDQtLjcwNCAxLjE1Mi0xLjE1MnEtMi4yNC0xLjAyNC0zLjcxMi0zLjEzNi0xLjQwOC0yLjE3Ni0xLjQwOC00LjczNiAwLTMuNTIgMi41Ni02LjE0NCAyLjYyNC0yLjYyNCA2LjA4LTIuNjI0IDMuNTIgMCA2LjAxNiAyLjYyNCAyLjU2IDIuNjI0IDIuNTYgNi4xNDQgMCAyLjU2LTEuNDcyIDQuNzM2LTEuNDA4IDIuMTEyLTMuNTg0IDMuMTM2LjU3Ni41NzYgMS4wODggMS4xNTIuNTEyLjUxMi43NjguNzA0IDEuNiAxLjQwOCAwIDMuMzkyLS4xMjguMTI4LS4zODQuMjU2LS4xOTIuMTI4LS4zODQuMzIgMS4xNTIgMi44OCAyLjE3NiA1LjYzMiAxLjAyNCAyLjY4OCAxLjk4NCA0Ljg2NC43NjggMS44NTYgMi4xMTIgMi40OTYgMS40MDguNTc2IDQuMTYgMi4yNCAyLjc1MiAxLjYgMy4yNjQgMi45NDQuNDQ4IDEuMjguNTc2IDMuNzEyLjE5MiAyLjQzMi4zMiA1LjA1NmgtMzguMjcycTAtMi42MjQuMTI4LTUuMDU2dC42NC0zLjcxMnEuMzg0LTEuMzQ0IDMuMi0yLjk0NCAyLjgxNi0xLjY2NCA0LjE2LTIuMjR6bTEwLjc1Mi0xOC40OTZxMCAuMTI4LTEuMzQ0IDEuNTM2bC0xLjUzNiAxLjUzNnEuMTkyLjM4NCAxLjQ3MiAxLjcyOCAxLjM0NCAxLjI4IDEuNiAxLjQ3MmwxLjQ3Mi0xLjQ3MiAxLjcyOC0xLjcyOHEtLjM4NC0uMTkyLTEuODU2LTEuNTM2em01LjY5Ni04LjMycTAtMi4zMDQtMS42LTMuOTA0LTEuNi0xLjY2NC0zLjkwNC0xLjY2NC0yLjI0IDAtMy45MDQgMS43MjgtMS42NjQgMS42NjQtMS42NjQgMy45NjggMCAyLjExMiAxLjM0NCAzLjY0OHQzLjI2NCAxLjcyOHEuODk2LjU3NiAxLjg1NiAwIDEuOTItLjE5MiAzLjI2NC0xLjcyOCAxLjM0NC0xLjUzNiAxLjM0NC0zLjc3NnptLTIxLjA1NiAzMi44OTZxLS40NDggMS45ODQtLjQ0OCA0LjhoMzJxMC0yLjMwNC0uNDQ4LTQuOC0uMzg0LS43NjgtMi4zNjgtMS42NjQtMS45ODQtLjk2LTQuMDMyLTEuOTItMS45ODQtMS4wMjQtMy4xMzYtMy45MDQtLjk2LTEuOTItMS45Mi00LjI4OC0uODk2LTIuMzY4LTEuNzkyLTQuOC0uMjU2LjEyOC0uMzg0LjMyLS4xMjguMTI4LS4yNTYuMTI4LTEuNjY0IDIuMDQ4LTMuMzkyIDAtLjEyOCAwLS4yNTYtLjEyOC0uMTI4LS4xOTItLjMyLS4zMi0uOTYgMi40MzItMS45MiA0LjgtLjg5NiAyLjM2OC0xLjc5MiA0LjI4OC0xLjE1MiAyLjg4LTMuMiAzLjkwNC0yLjA0OC45Ni00LjAzMiAxLjkyLTEuOTg0Ljg5Ni0yLjMwNCAxLjY2NHoiLz48cGF0aCBkPSJtMTcuOTQ1IDU1LjEzN2MwLTEuMDE3LjQwNC00LjAwMi41OS00LjM1LjMxLS41ODQuNTg4LS43NTQgMy44OS0yLjM4NSAyLjQ4Ny0xLjIyNyAzLjI3My0xLjcwNyAzLjg4Ni0yLjM3My45MTgtLjk5NSAyLjE0Ny0zLjUzNCA0LjAxNS04LjI4OGwxLjMzNy0zLjQwNS40NTkuNDIyYzEuMzY4IDEuMjU2IDEuOTc4IDEuMzEzIDMuMjA2LjI5OGwuODc3LS43MjUuMjIyLjU4OWMxLjI0NiAzLjMgMi44MDIgNy4wNzEgMy41MzMgOC41NjUgMS4zMDUgMi42NjMgMS44MyAzLjEzMiA1LjUzIDQuOTM0IDEuNy44MjkgMy4yNzggMS43MDcgMy41MDYgMS45NTIuNDMuNDYyLjYyNSAxLjM1Ny44NTMgMy45MWwuMTE4IDEuMzE4aC0zMi4wMjJ6bTE0LjQyNS0yNC4xOThjLS43MzQtLjc2My0xLjMzNC0xLjQ4MS0xLjMzNC0xLjU5NiAwLS4xMTQuNjA1LS44MDkgMS4zNDUtMS41NDQgMS41NTMtMS41NDIgMS4yOC0xLjU3MyAzLjMzOC4zN2wxLjI3NyAxLjIwNS0xLjQ4NCAxLjQ3NmMtLjgxNi44MTItMS41NTcgMS40NzYtMS42NDUgMS40NzYtLjA5IDAtLjc2Mi0uNjI0LTEuNDk3LTEuMzg3em0tLjIyNC03LjczNWMtMy43My0xLjE1Ny00Ljg5LTUuODc4LTIuMi04Ljk0MiAxLjAwNy0xLjE0NiAyLjAyMi0xLjYyMyAzLjY2Mi0xLjcxOCAxLjc1OS0uMTAyIDIuNzc0LjIzNSAzLjkzMyAxLjMwNCAyLjA1OSAxLjg5NyAyLjQxOCA0Ljk3My44NTcgNy4zMzEtLjcwMyAxLjA2My0xLjc2IDEuNzcyLTMuMjIzIDIuMTYxLTEuMjE4LjMyNC0xLjYwMy4zMDctMy4wMjktLjEzNnoiIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg=='); } -body.base .is2d piece.knight.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTI0Ljg0OCAzOS43MjhxLS4zODQuNzA0LjE5MiAxLjI4LjU3Ni41NzYtLjE5MiAxLjQ3Mi0uNzA0IDEuMDI0LTIuNjI0IDIuNzUyLTEuODU2IDEuNzI4LTMuMiAyLjMwNC0yLjE3NiAxLjI4LTQuNDguMTkyLTEuMTUyLS41NzYtMi44OC0yLjI0LTEuNjY0LTEuNjY0LTIuMzA0LTIuNjg4LS43NjgtMS4wMjQtLjU3Ni0xLjcyOC4xOTItLjcwNC4wNjQtMS42NjQgMC0uNzY4LS4zODQtMS4wODgtLjM4NC0uMzg0LjM4NC0yLjQ5Ni43NjgtMS45MiAzLjI2NC02LjMzNiAyLjQ5Ni00LjQxNiAzLjItNi41MjguNzA0LTEuOTItLjI1Ni0xLjcyOC0uODk2LjEyOC0uNTEyLS44OTYuMzg0LTEuMTUyIDEuNDA4LTMuMDcyIDEuMDI0LTEuOTg0IDEuODU2LTIuOTQ0Ljg5Ni0uODk2IDEuODU2LS43MDQgMS4wMjQuMTI4IDEuNzkyLTEuMTUyLjcwNC0xLjIxNiAxLjM0NC0zLjc3Ni43MDQtMi41NiAxLjQ3Mi00LjY3Mi45NiAxLjk4NCAyLjA0OCAzLjc3NiAxLjA4OCAxLjc5MiAyLjI0IDIuMjQgMi44OC0xLjA4OCA2LjkxMi0uNTEyIDUuNzYuNzY4IDguNTEyIDIuMzA0IDIuNzUyIDEuNDcyIDYuNTkyIDYuMjA4IDEuNDcyIDEuODU2IDIuMzY4IDMuOTY4Ljg5NiAyLjA0OCAxLjYgNC40OC43MDQgMi40MzIgMS4wODggNS41NjguNDQ4IDMuMTM2LjY0IDUuNjMyIDAgMi42ODgtLjE5MiA0Ljk5Mi0uMTI4IDIuMjQgMCA0LjU0NHYzLjc3NnEwIDEuNDA4LjUxMiAzLjc3Ni4zMiAxLjk4NCAxLjI4IDQuNDE2Ljk2IDIuNDMyIDEuNzkyIDQuOGgtNDAuMTkycS0uODMyLTEuNjY0LS41NzYtMy42NDggMC0xLjI4LjMyLTMuMTM2dDEuMDI0LTMuNTJxLjU3Ni0xLjQ3MiAxLjUzNi0yLjgxNi45Ni0xLjQwOCAyLjA0OC0yLjY4OCAyLjA0OC0zLjIgMy44NC01LjEyIDEuNTM2LTEuNzI4IDMuMjY0LTMuMiAxLjc5Mi0xLjQ3MiAzLjMyOC0zLjM5MiAxLjM0NC0yLjExMiAxLjY2NC0zLjcxMi4xOTItLjk2LS4wNjQtMi42MjQtLjE5Mi0xLjcyOC0uNTEyLTEuNjY0LS4yNTYuMTI4LTEuMDI0IDIuMzY4LS43NjggMi4yNC0xLjQ3MiAzLjAwOC0uNzA0IDEuMDg4LTEuNTM2IDEuNTM2LS43NjguMzg0LTEuMzQ0Ljc2OC0uNzY4LjM4NC0xLjIxNi4zODQtLjM4NCAwLS45Ni4zODQtLjcwNC41MTItMS42NjQgMS4zNDQtLjg5Ni43NjgtMS4yOCAxLjQ3MnptMi42MjQgNy40ODgtMy44NCA1LjI0OCA4LjQ0OC42NCAzLjg0LTQuMDMycTEuOTItMS45MiAzLjkwNCAwbDQuMDk2IDQuMTYgOS40MDgtLjY0cTAtMy4yNjQuMjU2LTcuNzQ0LjMyLTQuNTQ0LjE5Mi02Ljk3Ni0uMTI4LTIuNDk2LS41MTItNS40NC0uMzItMy4wMDgtMS4wMjQtNS4xODQtMS4yOC00LjI4OC0zLjY0OC03LjQyNC0xLjQwOC0xLjUzNi0yLjYyNC0yLjc1Mi0xLjE1Mi0xLjIxNi0yLjk0NC0yLjYyNC0yLjExMi0uODk2LTMuOTY4LTEuNi0xLjc5Mi0uNzA0LTMuOTA0LS44MzItMy45MDQtLjQ0OC02LjU5Mi41NzYtMi4xMTItLjc2OC0yLjY4OC0xLjY2NC0uNTEyLS44OTYtLjgzMi0xLjg1NiAwIDIuNzUyLTEuNDA4IDQuNDgtLjcwNC44MzItMS45ODQgMS4yMTYtMS4yMTYuMzItMS45ODQgMS4yMTYtLjgzMi45Ni0xLjY2NCAyLjQ5Ni0uNzY4IDEuNDcyLTEuMTUyIDIuNDMyLS4xOTIgMS4wODguNjQgMS4wODguODMyLS4wNjQuMTI4IDEuODU2LS43MDQgMS45ODQtMy4yNjQgNi41MjgtMi40OTYgNC40OC0zLjIgNi40LS43NjggMS45ODQtLjMyIDEuOTIuNTEyLS4wNjQuNTEyLjUxMiAwIC41NzYtLjMyIDEuMDg4LS4yNTYuNDQ4LjMyIDEuMDg4LjU3Ni44MzIgMi4xMTIgMi4zMDQgMS41MzYgMS40MDggMi4zNjggMS44NTYuNzY4LjQ0OC45Ni40NDguMTkyLS4wNjQgMS4xNTItLjY0Ljc2OC0uMzg0IDIuNTYtMS45MnQyLjM2OC0yLjM2OHEuNzA0LS44OTYuMDY0LTEuMjgtLjU3Ni0uNDQ4LS4xOTItMS4xNTIuMzg0LS43NjggMS42LTEuOTIgMS4yMTYtMS4yMTYgMS45Mi0xLjc5Mi43NjgtLjU3NiAxLjI4LS41MTIuNTc2IDAgMS4xNTItLjM4NHQxLjA4OC0uNTEycS41MTItLjE5MiAxLjA4OC0uODk2LjQ0OC0uNjQgMS4wODgtMS45ODQuNzA0LTEuNDA4IDEuMDg4LTIuNDk2LjE5Mi0uODk2LjQ0OC0xLjY2NC4zMi0uODMyIDAtMS41MzYtLjUxMi0uNzY4LTIuMTEyLTEuNjY0LTEuNi0uODk2LTEuNDA4LTEuMjguMDY0LS4zMiAxLjc5Mi0uMzJ0Mi44MTYuNzY4cS43NjguNzY4IDEuNzkyIDIuNDk2dDEuNDA4IDMuMDcycTEuMDg4IDMuMi41MTIgNS4zNzYtLjUxMiAyLjMwNC0yLjM2OCA0LjQ4LTEuMjggMS45ODQtMy4wMDggMy41ODR0LTMuNDU2IDMuMzI4cS0xLjQwOCAxLjQwOC0xLjk4NCAyLjQzMnptLTUuMDU2IDguNTEycS0uMzg0IDEuMzQ0LS42NCAzLjAwOHQuMzIgMi44MTZoMzMuMjE2bC0xLjY2NC01LjY5Ni05LjcyOC42NC00LjA5NiA0LjA5NnEtMS45ODQgMS43MjgtMy45MDQgMGwtMy45NjgtNC4yODh6bTE1LjU1Mi00LjM1Mi0zLjM5MiAzLjM5MiAzLjM5MiAzLjUyIDMuMzkyLTMuNTJ6bS0xNS4yMzItMjguMjg4cS42NC4yNTYgMS4wMjQuMzIuNDQ4LjA2NC4zMi43NjggMCAuMjU2LS41NzYuNDQ4LS41MTIuMTI4LS45Ni4zMi0uNDQ4LjI1Ni0xLjA4OC40NDgtLjU3Ni4xOTItLjc2OC4zMi0xLjA4OC4zMi0xLjUzNi0uMTkyLS4yNTYtLjI1Ni0uMjU2LTEuMjE2LjA2NC0uMzIuNDQ4LS44MzIuNDQ4LS41MTIuODk2LS41MTIgMS43MjggMCAyLjQ5Ni4xMjh6bS0xMC4zMDQgMTQuMjcycS41NzYgMCAxLjM0NC4xOTIuNzY4LjE5Mi45Ni41NzYgMCAuNTEyLS44MzIgMS40NzItLjgzMi44OTYtMS4yMTYuNzA0IDAtLjE5Mi4xMjgtLjU3Ni4xMjgtLjM4NC4wNjQtLjc2OCAwLS45Ni0uNDQ4LTEuNnoiLz48ZyBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Im0yMS45OTUgNjEuMTMzYy0uMjYyLS42ODktLjIxNi0yLjE1Ni4xMi0zLjg1bC4yOTctMS41IDEuMjAzLjA5NmMxLjkxNS4xNSA2Ljk1My40NDggNy42NTQuNDUuNTg2LjAwMy44MTQuMTk1IDIuNzMgMi4yOTggMS4zNjEgMS40OTMgMi4zNDUgMi40MTEgMi44MTkgMi42My43Mi4zMzIuNjU0LjMzNS02Ljk2LjMzOWwtNy42ODYuMDA0em0xNi45MTQuMTUyYy4zNS0uMTY5IDEuNjU5LTEuMzAxIDIuOTA5LTIuNTE3bDIuMjcyLTIuMjEgNC43MDctLjMwM2MyLjU4OS0uMTY2IDQuNzM3LS4yNzIgNC43NzMtLjIzNi4wNi4wNi42IDEuODQgMS40MDcgNC42MjZsLjI3Ni45NTUtOC40OS0uMDA0Yy04LjA5Ny0uMDA0LTguNDYxLS4wMTktNy44NTQtLjMxMXptLTIuNjM3LTQuNzc2LTEuNjMyLTEuNjM5IDEuNjc4LTEuNjc4IDEuNjc4LTEuNjc4IDEuNjMgMS42MjIgMS42MyAxLjYyMy0xLjUwNiAxLjYzN2MtLjgyOC45LTEuNTgzIDEuNjYzLTEuNjc3IDEuNjk0LS4wOTQuMDMyLS45MDUtLjY4LTEuODAyLTEuNTgxeiIvPjxwYXRoIGQ9Im00MS44ODkgNTEuMTM3Yy0yLjY4My0yLjg3NC0zLjc2LTMuNDQ0LTUuMTQ2LTIuNzI3LS4yODEuMTQ1LTEuNDQ1IDEuMjU3LTIuNTg2IDIuNDdsLTIuMDc1IDIuMjA2LTQuMDg3LS4zMTJjLTIuMjQ3LS4xNzItNC4xMTMtLjMzNS00LjE0NS0uMzYzLS4wMzItLjAyNy45NDEtMS40MjcgMi4xNjMtMy4xMTIgMS43NTYtMi40MjEgMi45My0zLjc4NiA1LjYxLTYuNTE3IDUuNTkzLTUuNyA3LjEyNy04LjMgNi44NjgtMTEuNjM3LS4yMjYtMi45MTUtMi4zMDYtNy40MTktNC4wMzQtOC43MzctLjcxNy0uNTQ3LTIuMzc3LS44NzgtMy41NzMtLjcxNC0xLjM0MS4xODUtMS4xOTEuNTc2LjcwNiAxLjg0MyAyLjAzIDEuMzU2IDIuMjAyIDEuNjggMS43NjQgMy4zMTMtLjQxNCAxLjU0Mi0xLjM3IDMuODM0LTIuMTM0IDUuMTEzLS41LjgzNi0uODA1IDEuMTExLTEuODYzIDEuNjc3LS42OTcuMzcxLTEuNDcxLjY3OS0xLjcyMS42ODItLjYxNS4wMDktMS4zMS40NjYtMi44MDUgMS44NDQtMS4yODYgMS4xODQtMi4yODYgMi41MzQtMi4yODYgMy4wODQgMCAuMTY4LjEyMy40MDcuMjczLjUzMi43MTUuNTk0IDAgMS42NTYtMi41NDkgMy43ODMtLjkzMy43OC0yLjEwOSAxLjY0MS0yLjYxMiAxLjkxNWwtLjkxNi40OTgtLjY4OS0uMzU1Yy0uOTU0LS40OTEtMy4zMjYtMi41NjItNC4yMi0zLjY4NC0uNzgtLjk4LS44Ni0xLjI3OC0uNTU1LTIuMDc5LjIyMS0uNTgxLjA3NS0xLjE3LS4yOS0xLjE3YS4yNjUuMjY1IDAgMCAxIC0uMjYtLjI2OGMwLS43OTQgMS42NDYtNC4yODYgNC4zNzUtOS4yNzcgMS43MjYtMy4xNTcgMi43NC01LjQ3NSAyLjc3Ni02LjM0OC4wMjctLjYyNi0uMDI3LS43MzItLjQyNC0uODI4LS43MTktLjE3NS0uNjY3LS44NjIuMTk0LTIuNTggMS40OTMtMi45NzcgMi40MDYtMy45ODUgNC4xNzctNC42MS40MzItLjE1MiAxLjA1Mi0uNDggMS4zNzgtLjczLjcxMi0uNTQyIDEuNjQyLTIuMzg3IDEuODA5LTMuNTg5bC4xMi0uODY3LjM2Mi42ODVjLjUzIDEuMDAzIDEuMDA3IDEuNDU3IDIuMDU1IDEuOTUyLjkyOC40NC45NDIuNDQgMi4wMS4xMzQuODEtLjIzMSAxLjczMS0uMzAzIDMuNzEzLS4yODggMy4xMTQuMDIzIDQuMTkuMjQ0IDcuNDQgMS41MjYgMS45ODMuNzgyIDIuNDgyIDEuMDY5IDMuNzQ3IDIuMTQ4IDIuODQxIDIuNDIzIDUuMzQ1IDUuNTggNi40NzIgOC4xNTggMi4zNDMgNS4zNiAzLjExNiAxMS41MjUgMi42MiAyMC45MDctLjE1MyAyLjg4Mi0uMjc4IDUuNzg4LS4yNzggNi40NTh2MS4yMmwtLjU5Mi4wOTNjLS4zMjUuMDUxLTIuMDIyLjE3OC0zLjc3Mi4yODJzLTMuNi4yMzQtNC4xMTIuMjg5bC0uOTMuMXptLTI3LjkxMy0xMS42MjRjLjkzNy0xLjAxNi45NjctMS40NzguMTItMS44MzItLjM0Ny0uMTQ0LS44ODEtLjI2My0xLjE4OC0uMjYzLS41MiAwLS41NDMuMDI3LS4zNC40MDYuMTE5LjIyMy4yMTIuODc3LjIwNyAxLjQ1NC0uMDEyIDEuMjk3LjE4NyAxLjMzNiAxLjIwMS4yMzV6bTguMjA1LTE0LjMyNWMxLjcwOS0uNjkgMS45MS0uODE4IDEuOTEtMS4yMjQgMC0uNi0uOTQzLS45MTYtMi44NzYtLjk2NS0xLjM1Ny0uMDM0LTEuNDQ3LS4wMS0xLjg2Ni40NzUtLjU5Mi42ODUtLjYxIDEuODA1LS4wMzYgMi4yMDYuNTY3LjM5OC43MjYuMzcgMi44NjgtLjQ5MnoiLz48L2c+PC9zdmc+'); } -body.base .is2d piece.bishop.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTI3Ljk4NCA1NS40NzJxLTIuNzUyLS4wNjQtNC41NDQtLjA2NC0xLjc5Mi0uMDY0LTEuOTItLjI1Ni0uODMyLS43NjgtLjg5Ni0xLjg1Ni0uMDY0LTEuMDg4Ljc2OC0xLjc5Mi4wNjQtLjEyOCAxLjA4OC0xLjUzNiAxLjAyNC0xLjQ3MiAyLjQzMi0zLjU4NC0yLjQzMi0zLjA3Mi00LjYwOC02LjAxNi0yLjE3Ni0zLjAwOC0yLjYyNC0zLjUyLTEuNDA4LTEuMjE2LTEuNDA4LTMuMDA4IDAtMS44NTYgMS40MDgtMy4yNjQuMzg0LS4zODQgMi4zMDQtMi45NDQgMS45ODQtMi41NiA0LjIyNC01LjU2OCAyLjMwNC0zLjAwOCA0LjIyNC01LjU2OCAxLjk4NC0yLjYyNCAyLjI0LTIuODguMjU2LS4yNTYuMzg0LS40NDgtLjcwNC0uNzY4LTEuNDcyLTEuNDcyLS43MDQtLjcwNC0uODMyLS45Ni0yLjA0OC0xLjc5MiAwLTMuNTg0LjE5Mi0uMzIgMS43MjgtMS43OTIgMS42LTEuNDcyIDEuODU2LTEuODU2IDEuNzI4LTEuNjY0IDMuMzI4IDBsMS44NTYgMS44NTZxMS40NzIgMS40NzIgMS44NTYgMS43OTIgMS43OTIgMS43OTIgMCAzLjU4NC0uMjU2LjI1Ni0xLjAyNC45NnQtMS40MDggMS40NzJxLjA2NCAwIC4wNjQuMTI4LjA2NC4wNjQuMjU2LjA2NC40NDguNTEyIDIuMzY4IDMuMTM2IDEuOTIgMi41NiA0LjA5NiA1LjU2OCAyLjI0IDMuMDA4IDQuMDk2IDUuNTY4IDEuOTIgMi41NiAyLjMwNCAyLjk0NCAxLjM0NCAxLjQwOCAxLjM0NCAzLjI2NCAwIDEuNzkyLTEuMzQ0IDMuMDA4LS40NDguNTEyLTIuNTYgMy4zOTItMi4wNDggMi44MTYtNC4zNTIgNS44ODggMS42IDIuMTEyIDIuNjg4IDMuNzEyIDEuMTUyIDEuNTM2IDEuMzQ0IDEuNjY0IDEuNzI4IDEuNzkyLS4xOTIgMy42NDgtLjEyOC4xOTItMi4xMTIuMjU2LTEuOTIgMC00LjguMDY0LS4xOTIgMS40MDgtLjEyOCAxLjQwOC4zMi4zMiAyLjE3Ni4zMiAxLjg1Ni0uMDY0IDQuMDk2LS4xMjh0NC4yODgtLjA2NHEyLjExMi0uMDY0IDIuOTQ0LjE5MiAyLjExMi43MDQgMi45NDQgMy4yNjQuODMyIDIuNDk2IDEuNDA4IDQuODY0aC0xNy4wODhxLTEuMzQ0IDAtMi41Ni0uMDY0LTEuMTUyLS4xMjgtMi4zNjgtLjcwNC0xLjE1Mi0uNTc2LTEuNDcyLS44MzItLjMyLS4zMi0uMzg0LS43MDQgMCAuMzg0LS4yNTYuNzA0LS4yNTYuMjU2LTEuNDA4LjgzMi0xLjM0NC41NzYtMi41Ni43MDQtMS4yMTYuMDY0LTIuMzY4LjA2NGgtMTcuMjhxLjcwNC0yLjM2OCAxLjY2NC00Ljg2NCAxLjAyNC0yLjU2IDMuMTM2LTMuMjY0Ljc2OC0uMjU2IDIuNzUyLS4xOTIgMi4wNDggMCA0LjE2LjA2NCAyLjE3Ni4wNjQgMy45MDQuMTI4IDEuNzkyIDAgMi4xMTItLjMyLjMyLS4xOTIuMTkyLS4zODQtLjA2NC0uMjU2LS4wNjQtMS4wMjR6bTYuOTEyLS4xMjhxMCAzLjk2OCAxLjA4OCA1LjA1Ni41NzYuODMyLjU3Ni45NnQuNTEyLjQ0OHEyLjA0OC43NjggMy41Mi43NjhoMTMuMjQ4cS0uMTI4LS4zMi0uMzg0LTEuMjh0LTEuMTUyLTEuMzQ0cS0uNzA0LS4xOTItMi44MTYtLjEyOC0yLjA0OCAwLTQuMzUyLjEyOC0yLjMwNC4wNjQtNC4yODguMDY0LTEuOTItLjA2NC0yLjM2OC0uNTEyLTEuMDg4LS44OTYtMS4wODgtMS45MiAwLTEuMDg4LjEyOC0yLjI0em0tMS43OTIgMS45MnEwLTEuOTItLjA2NC0xLjkyaC0yLjU2cS4wNjQgMS4xNTIuMDY0IDIuMTc2IDAgLjk2LTEuMTUyIDEuOTg0LS40NDguNDQ4LTIuMzY4LjUxMi0xLjkyIDAtNC4yMjQtLjA2NC0yLjMwNC0uMTI4LTQuNDE2LS4xMjgtMi4xMTItLjA2NC0yLjgxNi4xMjgtLjgzMi4zODQtMS4xNTIgMS4zNDQtLjMyLjk2LS4zODQgMS4yOGgxMy4zNzZxMS42IDAgMy41Mi0uNzY4LjU3Ni0uMzIuNTEyLS40NDggMC0uMTI4LjcwNC0uOTYuOTYtMS4yMTYuOTYtMy4xMzZ6bTIuNDMyLTIyLjIwOHYxMS4wNzJoLTIuOTQ0di0xMS4wNzJoLTMuNTJ2LTIuOTQ0aDMuNTJ2LTQuMjg4aDIuOTQ0djQuMjg4aDMuNTJ2Mi45NDR6bS02LjkxMiAxMS4zMjhxLTEuOTg0IDIuOTQ0LTMuNTIgNC44NjQtMS40NzIgMS44NTYtMS41MzYgMS45Mi4wNjQuMTI4IDMuMzkyLjE5MnQ3LjI5Ni4wNjRxMy45NjggMCA3LjI5Ni0uMDY0IDMuMzkyLS4wNjQgMy41Mi0uMTkyLS4xMjgtLjA2NC0xLjc5Mi0yLjA0OC0xLjYtMS45ODQtMy43MTItNC45OTIgMi42MjQtMy42NDggNS4yNDgtNy4yMzIgMi42ODgtMy41ODQgMy4yLTQuMTYgMS4wODgtLjgzMiAwLTEuOTg0LS41MTItLjQ0OC0yLjQzMi0zLjAwOC0xLjkyLTIuNjI0LTQuMTYtNS41NjgtMi4xNzYtMy4wMDgtNC4wOTYtNS41NjgtMS44NTYtMi42MjQtMi4yNC0zLjEzNi0uNDQ4LS40NDgtLjk2LS40NDgtLjcwNCAwLTEuMDI0LjQ0OC0uNTEyLjUxMi0yLjQ5NiAzLjEzNi0xLjkyIDIuNTYtNC4yMjQgNS41NjgtMi4yNCAyLjk0NC00LjE2IDUuNTY4LTEuOTIgMi41Ni0yLjM2OCAzLjAwOC0xLjI4IDEuMTUyIDAgMS45ODQuMzg0LjU3NiAzLjEzNiA0LjIyNCAyLjgxNiAzLjY0OCA1LjYzMiA3LjQyNHptNS4zNzYtNDAuNzY4cS0uMjU2LjM4NC0xLjYgMS43MjgtMS4yOCAxLjM0NC0xLjQ3MiAxLjUzNi4xOTIuMzg0IDEuNDcyIDEuNzI4IDEuMzQ0IDEuMjggMS42IDEuNDcyLjE5Mi0uMTkyIDEuNTM2LTEuNDcybDEuNzI4LTEuNzI4cS0uMzg0LS4xOTItMS43MjgtMS41MzYtMS4zNDQtMS4zNDQtMS41MzYtMS43Mjh6Ii8+PHBhdGggZD0ibTE0LjIyOCA2Mi4wNDhjLjMxMy0xLjAyNC42MzItMS41ODUgMS4wNTktMS44NjUuNDE0LS4yNzIgMS4xMzItLjI5NyA2Ljg3OS0uMjQyIDcuMjEuMDcgNy4xNjQuMDc2IDcuOTktMS4yNTIuMzU1LS41NzIuNDIyLS45MDcuMzk4LTIuMDA1bC0uMDI4LTEuMzE4aDIuNTZsLS4wODYgMS43NzVjLS4wODkgMS44NDYtLjE3NiAyLjEyMS0xLjEyIDMuNTMzLTEuMTEzIDEuNjY1LTEuOCAxLjc4LTEwLjUzNyAxLjc4MmwtNy4yNC4wMDF6bTI0LjkuMzE3YTQzLjMyIDQzLjMyIDAgMCAwIC0xLjIyNS0uMzUzYy0uOTU5LS4yNjctMS4wOTUtLjM3NC0xLjcxLTEuMzMyLS44MTMtMS4yNy0xLjE1MS0yLjQ2Ny0xLjE1NC00LjA4N2wtLjAwMi0xLjIyN2gyLjM2M3YxLjQxYy4wMDEgMS42MjcuMzM2IDIuMzY4IDEuMzEgMi45LjU1LjMgMS4xMTQuMzIyIDcuMDcuMjY1bDYuNDcyLS4wNi40ODkuNDI0Yy4yNjkuMjM0LjYwNS44MTMuNzQ3IDEuMjg4bC4yNTguODY0LTcuMjE5LS4wMTRjLTMuOTctLjAwOC03LjMtLjA0My03LjQtLjA3OHptLTE0LjMxOC05LjEyNWMtLjU3NS0uMDQtMS4wNDYtLjExNy0xLjA0Ni0uMTdzLjQ4LS42ODQgMS4wNjctMS40MDJjMS4wMzUtMS4yNjcgMy4zNDUtNC40NDYgMy42NzUtNS4wNTguMTI3LS4yMzYtLjc1LTEuNTA4LTQuMDE0LTUuODE5LTIuMjk4LTMuMDMzLTQuNDI0LTUuODE3LTQuNzI2LTYuMTg1LS4zLS4zNjktLjU0Ny0uNzU3LS41NDctLjg2MyAwLS4xMDcuMjczLS41MDEuNjA2LS44NzYuMzM0LS4zNzYgMS42MTgtMi4wMzMgMi44NTMtMy42ODMgNC4wNjgtNS40MzIgOS4xMzItMTIuMDc0IDkuOTI5LTEzLjAyMi40My0uNTEzLjkzNi0uOTcyIDEuMTIzLTEuMDIxLjc4Ny0uMjA2IDEuMzI1LjM2MiA0LjY4OSA0Ljk1MiA1LjEwMiA2Ljk2MyA4LjQ2MiAxMS40NDQgOS4zMTEgMTIuNDIuNzQ5Ljg2MS45NzIgMS42MS41NTcgMS44NjctLjE5OC4xMjMtNi4wOTIgNy45NzgtNy44NjUgMTAuNDgyLS41MjUuNzQxLS44MTMgMS4zMTUtLjczMiAxLjQ1NS40NC43NiAyLjU0OCAzLjU3IDMuNzY2IDUuMDIuNzg0LjkzNSAxLjM3MiAxLjc1MyAxLjMwNiAxLjgxOS0uMTI5LjEzLTE4LjIzMy4yMDUtMTkuOTUyLjA4NHptMTAuNzMtMTIuNTU2LjA0OC01LjVoMy40NDl2LTMuMDkxaC0zLjQ1NXYtNC4zNjNoLTMuMDkxdjQuMzYzaC0zLjQ1NHYzLjA5MWgzLjQ1NHY1LjQyNWMwIDIuOTgzLjA1OCA1LjQ4Mi4xMjkgNS41NTIuMDcuMDcuNzQ1LjEwNSAxLjUuMDc2bDEuMzcxLS4wNTN6bS0zLjEyNC0zMC4yMjItMS40MTYtMS40NTcuOTEyLTEuMDQ3Yy41MDEtLjU3NSAxLjE4NS0xLjI5NCAxLjUxOS0xLjU5N2wuNjA3LS41NSAxLjU3MSAxLjYgMS41NzIgMS42LTEuNTQgMS40MDVjLS44NDguNzcyLTEuNiAxLjQyNy0xLjY3MyAxLjQ1NHMtLjc3LS42MDctMS41NS0xLjQwOHoiIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg=='); } -body.base .is2d piece.rook.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTQ4LjQ2NCAyNS4wMDhsMi40MzIgMTkuNTIgMi42MjQgNi4wMTZ2MTIuOTI4SDE0LjE2VjUwLjU0NGwyLjYyNC02LjAxNiAyLjQzMi0xOS41Mi00LjkyOC0xMC43NTIgMy4wNzItOS43MjhIMjZ2OC4zMmgzLjcxMnYtOC4zMmg4Ljc2OHY4LjMyaDMuNjQ4di04LjMyaDguNjRsMy4wNzIgOS43Mjh6bS0zMS41NTIgMjcuMnY4LjY0aDMzLjk4NHYtOC42NHptLjc2OC0yLjc1Mkg1MGwtMS40MDgtMy4zOTJIMTkuMDg4em0xNy44NTYtMTkuNTJsNC4xNiA0LjE2aDcuMjMybC0uOTYtNy44NzJoLTI0bC0xLjAyNCA3Ljg3Mmg2LjkxMmw0LjQxNi00LjE2cTEuNDA4LTEuNzkyIDMuMjY0IDB6bS03LjM2IDYuOTEyaC03LjU1MmwtLjk2IDYuNzg0aDI4LjM1MmwtLjc2OC02Ljc4NGgtNy43NDRsLTMuOTY4IDMuOTY4cS0xLjg1NiAxLjg1Ni0zLjI2NCAwek0xNy4wNCAxNC4wNjRsNC42NzIgOS41MzZoMjQuNTc2bDQuOC05LjUzNi0yLjE3Ni02LjkxMmgtNC4xNlYxNS42aC04Ljg5NlY3LjE1MmgtMy41ODRWMTUuNmgtOC44OTZWNy4xNTJoLTQuMDMyem0xMy4yNDggMjEuMjQ4bDMuNTIgMy43MTIgMy43MTItMy43MTItMy43MTItMy41MnoiLz48ZyBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0xNy4wMzYgNTYuNnYtNC4yNzNoMzMuODE4djguNTQ2SDE3LjAzNnptMS4xMTctOC4xMzZsLjY2Mi0xLjYzNy4yNzYtLjY4MiAxNC43NDUuMDAxaDE0Ljc0NWwuNjcgMS42MzYuNjcgMS42MzZIMTcuNzY5em0xLjYxLTUuMDI5YzAtLjA5LjIwNS0xLjU3MS40NTUtMy4yOS4yNS0xLjcxOC40NTQtMy4xNTguNDU0LTMuMTk4IDAtLjA0MSAxLjY4OS0uMDc0IDMuNzUzLS4wNzRoMy43NTJsMi40OTUgMi40NTRjMi42NTUgMi42MTIgMi45MSAyLjc1MyAzLjk2NCAyLjE5NS4yNy0uMTQzIDEuNDcxLTEuMjQ4IDIuNjctMi40NTVsMi4xNzktMi4xOTRoMy44NjZjMi45NzIgMCAzLjg2Ny4wNTIgMy44NjguMjI3IDAgLjEyNS4xNjQgMS41NzcuMzYyIDMuMjI3cy4zNjIgMy4wNjIuMzYzIDMuMTM3YzAgLjA3NS02LjM0LjEzNi0xNC4wOS4xMzYtOC4zMTEgMC0xNC4wOS0uMDY4LTE0LjA5LS4xNjV6Ii8+PHBhdGggZD0iTTMyLjAwMiAzNy4wNzZsLTEuNjctMS43NzkgMS43MS0xLjcwMyAxLjcxLTEuNzA0LjUwNi40NGE3My4wMjMgNzMuMDIzIDAgMCAxIDEuODI0IDEuNzE1TDM3LjQgMzUuMzJsLTEuNzcgMS43NzdjLS45NzQuOTc3LTEuODEzIDEuNzczLTEuODY0IDEuNzY4LS4wNTItLjAwNS0uODQ3LS44MS0xLjc2NS0xLjc4OHoiLz48cGF0aCBkPSJNMjEuMDk2IDMzLjM3M2ExODUuNiAxODUuNiAwIDAgMCAuNTA1LTMuODE5bC40MDQtMy4yMjdoMTEuOTdjNi41ODMgMCAxMS45Ny4wNDcgMTEuOTcuMTA1IDAgLjIuNzI3IDYuMTcyLjgzNCA2Ljg1bC4xMDcuNjgyaC03LjIybC0xLjkwNi0xLjkyOWMtMi4zODQtMi40MTMtMy4xMzYtMi45OC0zLjk0NC0yLjk4LS42NjQgMC0uOTM2LjIxNy00LjI1NyAzLjQwNGwtMS41NjcgMS41MDVoLTYuOTk3em0tMS42NzEtMTQuNTQ2TDE3LjEgMTQuMDU0bDEuMTItMy4zNjMgMS4xMi0zLjM2NCAyLjAzLS4wNTEgMi4wMy0uMDUyVjE1LjZoOC45MDhWNy4yMzZoMy40NTRWMTUuNmg5LjA5MlY3LjIyNGwyLjAyNi4wNTIgMi4wMjYuMDUxIDEuMDUyIDMuMzQzIDEuMDUyIDMuMzQzLTIuMzk0IDQuNzkzTDQ2LjIyIDIzLjZIMjEuNzVsLTIuMzI1LTQuNzczeiIvPjwvZz48L3N2Zz4='); } -body.base .is2d piece.queen.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTIxLjA4OCA1MS4zMTItMS42NjQgNS4xODQgMy42NDgtMy4zMjh6bTI1LjA4OC4xMjgtMi4xNzYgMS44NTYgMy4yNjQgMi43NTJ6bS0xNy43MjggMi4xNzYtMi43NTIuNTc2LTMuMzkyIDQuMTZoMjIuNDY0cS0uNzA0LS42NC0zLjM5Mi00LjE2bC0yLjMwNC0uNDQ4LTMuNTIgMy41MnEtMS43OTIgMS43OTItMy41MiAwem0tOS4zNDQtNS41NjhxLTIuODE2LTYuMDgtNS41MDQtMTIuMTYtMi42MjQtNi4xNDQtNS4yNDgtMTIuMTYtMS40MDguMzg0LTIuMzA0LS41NzZsLTEuNDA4LTEuNTM2cS0xLjkyLTEuNjY0IDAtMy41ODRsMS40MDgtMS4zNDRxMS42NjQtMi4wNDggMy41MiAwbDEuNTM2IDEuMzQ0cTEuNTM2IDEuOTIgMCAzLjU4NGwtLjc2OC43NjggMTAuOTQ0IDguNTc2LS45Ni0xMy44MjRxLS44MzItLjE5Mi0xLjQwOC0uNzY4bC0xLjM0NC0xLjQwOHEtMS45ODQtMS43OTIgMC0zLjUybDEuMzQ0LTEuNTM2cTEuNzkyLTEuNjY0IDMuNTg0IDBsMS41MzYgMS41MzZxMS41MzYgMS43MjggMCAzLjUybC0xLjUzNiAxLjQwOCA2LjU5MiAxMS4yNjQgMy41Mi0xMi45MjhxLjE5MiAwLS41NzYtLjMybC0xLjQwOC0xLjUzNnEtMS43MjgtMS43OTIgMC0zLjU4NGwxLjQwOC0xLjUzNnExLjcyOC0xLjQwOCAzLjUyIDBsMS40MDggMS41MzZxMS45ODQgMS43OTIgMCAzLjU4NGwtMS40MDggMS41MzZxLS4zMi4zMi0uNjQuMzJsMy41ODQgMTMuMDU2IDYuNTkyLTExLjA3Mi0xLjUzNi0xLjUzNnEtMS41MzYtMS44NTYgMC0zLjcxMmwxLjQwOC0xLjQwOHExLjg1Ni0xLjUzNiAzLjY0OCAwbDEuNDA4IDEuNDA4cTEuODU2IDEuODU2IDAgMy43MTJsLTEuNDA4IDEuMzQ0LTEuMjE2Ljc2OC0uNzY4IDEzLjU2OCAxMS4yNjQtOS45ODQtLjk2LS43NjhxLTEuNTM2LTEuODU2IDAtMy43MTJsMS41MzYtMS40MDhxMS43OTItMS42NjQgMy41ODQgMGwxLjM0NCAxLjQwOHExLjg1NiAxLjg1NiAwIDMuNzEybC0xLjM0NCAxLjM0NHEtMS4wODggMS4wODgtMi4zNjguNzY4bC0xMS4yIDI2LjMwNCAzLjA3MiAxMi40OGgtMzYuOTI4em0wLTcuMzZxNi41OTItMy44NCAxNC45MTItMy44NCA3LjU1MiAwIDE0LjMzNiA0LjE2bDUuMzc2LTEyLjM1Mi05LjIxNiA2Ljg0OC0uNjQtMTAuODE2LTYuMzM2IDcuODcyLTMuNjQ4LTEwLjYyNC00LjM1MiAxMC42MjQtNS42OTYtNy44NzItLjUxMiAxMC44MTYtOS4yOC02LjIwOHptMTQuNzg0IDgtMy4yNjQgMy4yIDMuMjY0IDMuMjY0IDMuMDcyLTMuMjY0em0tMTMuNTY4LTUuMDU2cS4zMi43MDQuNjQgMS4zNDQuMzg0LjY0LjU3NiAxLjIxNiAyLjY4OC0xLjIxNiA1LjgyNC0yLjMwNCAzLjItMS4wODggNi42NTYtMS4wODggMy4zMjggMCA1LjgyNC44MzJ0Ni4zMzYgMi43NTJsMS4wODgtMi42MjRxLTMuNDU2LTEuOTItNi41MjgtMi44OC0zLjA3Mi0uOTYtNi43Mi0uOTYtMy41ODQgMC03LjI5Ni45Ni0zLjY0OC44OTYtNi40IDIuNzUyem0tMTIuNDgtMjQuODMyLTEuMDI0IDEuMDg4IDEuMDI0IDEuMDg4IDEuMDg4LTEuMDg4em0xMi45MjgtNi43Mi0xLjA4OCAxLjA4OCAxLjA4OCAxLjAyNCAxLjA4OC0xLjAyNHptMTMuMTItMi4wNDgtMS4wODggMS4wODggMS4wODggMS4wODguODk2LTEuMDg4em0xMi45MjggMi4xNzYtMS4wODggMS4wODggMS4wODggMS4wODggMS4wMjQtMS4wODh6bTEzLjM3NiA0LjkyOC0xLjA4OCAxLjA4OCAxLjA4OCAxLjA4OCAxLjA4OC0xLjA4OHptLTE1Ljg3MiAzMS44NzJxLTMuMDA4LTEuNi01LjE4NC0yLjQzMi0yLjExMi0uODMyLTUuMTItLjgzMnQtNS44ODggMS4wODhxLTIuODggMS4wMjQtNS4xODQgMi4xNzZsMi4zMDQgMi4zMDQgMi45NDQtLjY0IDMuODQtNC4xNnExLjcyOC0xLjQwOCAzLjUyIDBsNC4wMzIgNC4xNiAyLjU2LjY0eiIvPjxnIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggZD0ibTE5Ljc0OCA1NS44NTljMC0uMDY1LjI5OC0xLjA4Mi42NjMtMi4yNmwuNjYzLTIuMTQ0Ljk3NC44NDEuOTc0Ljg0MS0xLjUgMS40MWMtMS40MDkgMS4zMjQtMS43NzQgMS41OTQtMS43NzQgMS4zMTJ6bTMuMDY5IDEuOTgxYTc0LjcxIDc0LjcxIDAgMCAxIDEuNjM0LTIuMDQzbDEuMjY4LTEuNTQzIDEuMzMzLS4yOTUgMS4zMzItLjI5NCAyLjI4OSAyLjI0NmMyLjEwMiAyLjA2NCAyLjM0MyAyLjI0NiAyLjk2NiAyLjI0Ni45NzggMCAxLjI1NC0uMTg4IDMuNDczLTIuMzdsMi0xLjk2OCAxLjExMi4yMTRjMS4xLjIxMyAxLjEyOC4yMzQgMi4yNTIgMS42Ny42MjcuOCAxLjM5IDEuNzIgMS42OTYgMi4wNDVsLjU1Ni41OTFoLTIyLjI3OHoiLz48cGF0aCBkPSJtMzIuMjMzIDUzLjQ2NS0xLjYwNy0xLjYxOCAxLjU2OS0xLjQzNmMuODYyLS43OSAxLjY1Ni0xLjQzNSAxLjc2NC0xLjQzNXMuODA3LjY3IDEuNTU0IDEuNDkxbDEuMzU3IDEuNDkyLTEuNTE1IDEuNTYyLTEuNTE2IDEuNTYzem0xMy4yNzkgMS4wODgtMS40MTgtMS4yMTQuOTU4LS44NTNjLjUyNy0uNDcgMS4wMDItLjgxMSAxLjA1NS0uNzU5LjE1MS4xNTEgMS4wNTIgNC4wNjguOTMxIDQuMDU0LS4wNi0uMDA4LS43NDYtLjU2LTEuNTI2LTEuMjI4em0tNC44MjItMy42MzJjLTEuMTE3LS4yOC0xLjItLjM0My0zLjEzNC0yLjQxLTEuMDkzLTEuMTY5LTIuMjU0LTIuMjU2LTIuNTgtMi40MTdsLS41OTItLjI5Mi41NDYuMDAyYy45NzUuMDA0IDMuMjQ1LjQ4NiA0LjQ1NC45NDUuOTkuMzc3IDQuNDg2IDIuMDQgNC43MDMgMi4yMzguMTEzLjEwNC0xLjg3MyAyLjI1NC0yLjA2NiAyLjIzNy0uMS0uMDEtLjY5OS0uMTQ1LTEuMzMtLjMwM3ptLTE2LjQ3Ny0uNzUxYy0uNTk0LS42MDItMS4wNDQtMS4xMjctMS0xLjE2Ni4xOTctLjE3OCAxLjM5MS0uNzI1IDMuMjEzLTEuNDcgMi4wNDMtLjgzOCA0LjIwNC0xLjQ0OSA1Ljc3Ny0xLjYzNGwuOTA5LS4xMDgtLjU0Ni4zMzZjLS4zLjE4Ni0xLjQyIDEuMjc2LTIuNDkgMi40MjUtMS44OCAyLjAxOS0xLjk3OCAyLjA5NS0zIDIuMzE2LS41OC4xMjYtMS4yMTkuMjY2LTEuNDE5LjMxMi0uMjYzLjA2LS42NjQtLjIyMS0xLjQ0NC0xLjAxMXoiLz48cGF0aCBkPSJtNDQuMDIgNDUuMzM0Yy00LjQyMy0yLjE1Mi04LjA4NS0yLjkwNy0xMS45ODUtMi40NjgtMi41Ni4yODgtNC4xOTUuNzM4LTcuNjA0IDIuMDlsLTIuODYxIDEuMTM0LS41NDktMS4xNzNjLS40MDMtLjg2Mi0uNDk3LTEuMjM1LS4zNTQtMS40MDguMzEtLjM3MiAzLjA0MS0xLjY1NyA0LjU5LTIuMTU3IDMuNzMtMS4yMDYgOC41Mi0xLjY0OSAxMi4xMDItMS4xMTkgMi42OTUuMzk5IDQuNDkuOTc0IDcuNDM2IDIuMzgzIDIuMjg2IDEuMDk0IDIuNCAxLjE3NCAyLjI0NCAxLjU3NC0uMzUyLjkwMS0uOTE2IDIuMTQ4LS45NjUgMi4xMzItLjAyOS0uMDA4LS45NTItLjQ1My0yLjA1Mi0uOTg5eiIvPjxwYXRoIGQ9Im00Ni4yMDMgMzkuODExYTI4LjMwOCAyOC4zMDggMCAwIDAgLTctMi41MDRjLTIuMjA1LS40NzItOC44NjItLjQ3Ni0xMS4wOTEtLjAwNi0yLjQ0OS41MTctNS4wMjcgMS4zNjYtNy4wNzUgMi4zMy0xLjA0MS40OTEtMS45Mi44NjYtMS45NTEuODM0LS4xMjgtLjEyNy00Ljc4Ny0xMC43MzctNC43MzgtMTAuNzg2LjAzLS4wMyAyLjAzNCAxLjI2NiA0LjQ1NSAyLjg3OCAyLjQyIDEuNjEyIDQuNDQyIDIuODkyIDQuNDkgMi44NDMuMDUtLjA0OS4yMDEtMi4zNTYuMzM5LTUuMTI2cy4yODUtNS4wNzQuMzMtNS4xMThjLjA0NC0uMDQ0IDEuMjk0IDEuNTkyIDIuNzc4IDMuNjM2IDEuNDg0IDIuMDQ1IDIuNzU1IDMuNjgyIDIuODI1IDMuNjM5czEuMDYtMi4zNjYgMi4yLTUuMTYzYzEuMTQtMi43OTYgMi4xMjYtNC45ODcgMi4xOS00Ljg3LjA2My4xMTguODc4IDIuNDQ0IDEuODEyIDUuMTdzMS43NTMgNC45MzUgMS44MiA0LjkxYy4wNjgtLjAyNyAxLjQ0Mi0xLjY4NCAzLjA1NC0zLjY4NHMyLjk5Ni0zLjY1OCAzLjA3My0zLjY4NWMuMDc4LS4wMjYuMjcyIDIuMjQ5LjQzMSA1LjA1Ni4xNiAyLjgwNy4zMzYgNS4xNS4zOTMgNS4yMDYuMDU2LjA1NyAyLjA0NC0xLjMzNyA0LjQxNy0zLjA5N3M0LjM1LTMuMTY1IDQuMzkzLTMuMTIyYy4wOTYuMDk1LTQuOTI2IDExLjcyOC01LjA1NSAxMS43MDgtLjA1LS4wMDgtLjk5LS40OC0yLjA5LTEuMDQ5em0tMzguODc2LTE5LjQzNi0uNDktLjUxMi41MTItLjQ5LjUxMS0uNDkuNDkuNTEyLjQ5LjUxMS0uNTExLjQ5LS41MTIuNDl6bTEyLjkwOS02LjcyNy0uNDktLjUxMi41MTItLjQ5LjUxMS0uNDkuNDkuNTExLjQ5LjUxMi0uNTExLjQ5LS41MTEuNDl6bTEzLjA4OC0yLjAwNS0uNDg3LS41MDcuNTEzLS40OTEuNTEzLS40OTEuNDEyLjQzOWMuMzI3LjM0OC4zNzQuNTEyLjIyNi43OS0uMzk4Ljc0My0uNjYuOC0xLjE3Ny4yNnptMTMuMDAzIDIuMjc3Yy0uNS0uNTMzLS40OTgtLjY5Ni4wMjQtMS4xODUuNTMtLjQ5OS41MjUtLjUuOTg4LjEyN2wuMzg2LjUyMi0uNS40OC0uNS40OHptMTMuMzY0IDQuODE4LS40OS0uNTExLjUxMS0uNDkuNTEyLS40OS40OS41MTEuNDkuNTEyLS41MTEuNDktLjUxMi40OXoiLz48L2c+PC9zdmc+'); } -body.base .is2d piece.king.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTM5LjU5NCA1Ny4xMzZxLTMuNTIgMy41Mi0zLjg0IDMuNzEyLTEuNiAxLjQ3Mi0zLjM5MiAwLS4zODQtLjE5Mi0zLjg0LTMuODRsLTQuNDguMjU2LTMuOTY4IDQuMzUyaDI3Ljg0bC00LjAzMi00LjE2em02LjAxNi01LjA1NnEtLjk2LS41NzYtMS44NTYtMS4wMjQtLjg5Ni0uNDQ4LTEuNTM2LS44MzItMS4yOC0uNTc2LTQuMDk2LS43NjgtMi43NTItLjE5Mi0zLjc3Ni0uMjU2LS45Ni4wNjQtMy4zOTIuMzg0LTIuMzY4LjMyLTUuMzc2IDEuMjE2LTMuMTM2IDEuMTUyLTMuODQgMS41MzZsMi4wNDggMi4wNDggNC43MzYtLjMyIDMuODQtNC4wMzJxMS43MjgtMS42IDMuMzkyIDBsNC4wMzIgNC4wMzIgMy45MDQuMzJ6bS0yNS40MDggMi44OC0uMzIgMi40OTYgMS43MjgtMS40MDh6bTAtNS4xODRxLjcwNC0uMzg0IDEuNzI4LS43NjggMS4wMjQtLjQ0OCAyLjc1Mi0uOTYgMi4zMDQtLjc2OCA0LjM1Mi0xLjE1MiAyLjExMi0uMzg0IDMuNjQ4LS41MTJsLS4xMjgtMTEuMzkycS0xLjE1Mi01Ljk1Mi0yLjU2LTExLjItMS40MDgtNS4yNDgtMy45MDQtNi4wMTYtMi44OC0uNzY4LTYuNzItLjQ0OC0zLjc3Ni4zMi00Ljk5Mi44OTYtMS4zNDQuNzA0LTMuMzkyIDIuNjI0LTEuOTg0IDEuODU2LTIuNzUyIDQuMTYtLjgzMiAyLjQzMi0xLjA4OCA0LjM1Mi0uMTkyIDEuOTItLjMyIDMuMTM2IDAgMi40OTYgMS4wODggNy4xMDQuNjQgMi4zMDQgMS43MjggMy45NjggMS4xNTIgMS42NjQgMy4zMjggMy4zOTIgMS45MiAxLjY2NCAzLjcxMiAyLjE3NiAxLjc5Mi40NDggMy41Mi42NHptMTMuODg4LTIxLjQ0cS41NzYtMi42ODggMS4yMTYtNS4xMi43MDQtMi40OTYgMS42NjQtNC40MTYgMC0uNjQtLjU3Ni0xLjc5Mi0uNTEyLS45Ni0xLjE1Mi0xLjc5Mi0uNTc2LS44MzItMS4wMjQtMS43OTItMS42IDIuMTc2LTIuMzA0IDMuNTg0LS41NzYgMS4wMjQtLjcwNCAxLjQ3Mi0uMDY0LjQ0OC0uMDY0LjgzMiAxLjcyOCAzLjUyIDIuOTQ0IDkuMDI0em0xNi4yNTYgMjQuMTkyIDEuMjggMTIuMTZoLTM1LjU4NGwxLjQwOC0xMi4xNnEtMS41MzYtLjMyLTMuMDcyLS45Ni0xLjUzNi0uNzA0LTMuMzkyLTIuMTEyLTIuNTYtMi4xMTItMy45MDQtNC4xNi0xLjM0NC0yLjA0OC0yLjExMi00LjkyOC0xLjIxNi00LjczNi0xLjIxNi04IC4wNjQtMS4zNDQuMzItMy41Mi4zMi0yLjE3NiAxLjQwOC00LjkyOC44OTYtMi44OCAzLjQ1Ni01LjI0OCAyLjU2LTIuMzY4IDQuMjI0LTMuMDcyIDEuNDcyLS43NjggNS45NTItMS4yMTYgNC40OC0uNDQ4IDcuNzQ0LjQ0OCAxLjUzNi42NCAxLjk4NCAxLjIxNi43NjgtMS4zNDQgMS43OTItMi44MTYgMS4wODgtMS41MzYgMi4wNDgtMi44OHYtMS4wODhoLTIuOTQ0di0zLjA3MmgyLjk0NHYtMi44OGgyLjk0NHYyLjg4aDIuNzUydjMuMDcyaC0yLjc1MnYxLjA4OHEuODk2IDEuMzQ0IDEuODU2IDIuODE2IDEuMDI0IDEuNDA4IDEuNzkyIDIuNzUyLjQ0OC0uMzIuODk2LS41NzYuNTEyLS4yNTYuOTYtLjUxMiAzLjMyOC0uODk2IDcuNzQ0LS40NDggNC40OC40NDggNi4xNDQgMS4yMTYgMS40NzIuNzA0IDQuMDMyIDMuMDcyIDIuNTYgMi4zNjggMy42NDggNS4yNDguODk2IDIuNzUyIDEuMjE2IDQuOTI4LjMyIDIuMTc2LjMyIDMuNTIuMTI4IDMuMi0xLjIxNiA4LS43NjggMi44OC0yLjExMiA0LjkyOC0xLjI4IDIuMDQ4LTMuOTA0IDQuMTYtMS45MiAxLjUzNi0zLjUyIDIuMjQtMS42LjY0LTMuMTM2LjgzMnptLTE2LjEyOC0uMzItMy4yIDMuMjY0IDMuMiAzLjIgMy4wNzItMy4yem0xMy4yNDggMi4zMDQtMS41MzYgMS4yMTYgMS44NTYgMS43Mjh6bS0xMi4wMzItOC4xMjhxMS42IDAgNC4xNi4yNTZ0My44NC44MzJsMi4wNDggMS4wMjRxMS4xNTIuNTc2IDIuMzA0IDEuMjggMS43MjgtLjEyOCAzLjQ1Ni0uNTc2IDEuNzkyLS41MTIgMy45MDQtMi4yNCAzLjkwNC0zLjI2NCA0LjkyOC03LjM2IDEuMjE2LTQuNTQ0IDEuMDg4LTcuMTA0IDAtMS4yMTYtLjI1Ni0zLjEzNi0uMjU2LTEuOTItMS4xNTItNC4zNTItLjgzMi0yLjMwNC0yLjg4LTQuMTYtMi4wNDgtMS45Mi0zLjI2NC0yLjYyNC0xLjM0NC0uNTc2LTQuOTkyLS44OTYtMy42NDgtLjMyLTYuNTI4LjQ0OC0yLjU2Ljc2OC0zLjk2OCA2LjAxNi0xLjM0NCA1LjI0OC0yLjQ5NiAxMS4yeiIvPjxwYXRoIGQ9Im0yMi4wMyA1OS41NTVjMS4wMzYtMS4xMjUgMS45NTItMi4wOTYgMi4wMzYtMi4xNTguMDg0LS4wNjEgMS4xMDctLjE1NiAyLjI3My0uMjExbDIuMTItLjEgMiAxLjk1OWMxLjEgMS4wNzcgMi4yMDIgMi4wOTMgMi40NSAyLjI1Ny40Mi4yNzkuMDI2LjI5OC02LjE1Ny4yOThoLTYuNjA2em0tMS45NjYtMi45NjdjLjA2NS0uMzkzLjExOS0uOTAzLjEyLTEuMTMzbC4wMDItLjQxOS42NC40ODhjLjcwNi41MzkuNjc0LjY3Mi0uMzM1IDEuMzlsLS41NDUuMzg5em0xMi41MjcuNDE3LTEuNDk2LTEuNTAzIDEuNTkxLTEuNTgyIDEuNTkxLTEuNTggMS40ODcgMS42MDEgMS40ODcgMS42MDItMS40OSAxLjQ4M2MtLjgyLjgxNi0xLjUzMyAxLjQ4My0xLjU4MyAxLjQ4M3MtLjc2NC0uNjc2LTEuNTg3LTEuNTA0em0yLjc5OCA0LjIwM2MuMjg4LS4yMTYgMS4zNDYtMS4yIDIuMzUxLTIuMTg3bDEuODI3LTEuNzk1IDIuMDgyLjEyMiAyLjA4My4xMjMgMS43ODggMS43NDdjLjk4My45NiAxLjg2NiAxLjg4OSAxLjk2IDIuMDY0LjE2NC4zLS4xODYuMzE4LTYuMjIxLjMxOGgtNi4zOTV6bTExLjM4Ny00Ljc0OC0uNzUxLS43NjkuNzAyLS41MDEuNzAzLS41MDIuMTI3IDEuMTkyYy4wNy42NTUuMDkyIDEuMjI3LjA0OSAxLjI3cy0uNDE3LS4yNjctLjgzLS42OXptLTUuNjM4LTIuMzA3LTEuMzIxLS4xMjItMi4zNTktMi4zMzQtMi4zNTgtMi4zMzMgMi4xMzQuMTIzYzIuOTI1LjE2NyA0LjMxLjQ5NiA2LjE3NiAxLjQ2Ny44NzcuNDU2IDEuNzEuOTAzIDEuODUuOTkzLjIwNC4xMy4wNzMuMzktLjYzNiAxLjI2Mi0uOTkzIDEuMjIyLS44NTkgMS4xODUtMy40ODYuOTQ0em0tMTguMzgzLS44MDItLjk2NC0uOTc2IDEuMzM0LS41NTFjMS43MTUtLjcwOCAyLjY3NS0xLjAyNyA0LjUtMS40OTMgMS4yNTktLjMyMSA0LjYwNy0uOTA4IDUuMi0uOTEyLjEwMiAwLS44NCAxLjAzMi0yLjA5IDIuMjk0bC0yLjI3NiAyLjI5NS0xLjgxOC4xNTJjLTIuOTc0LjI0OC0yLjgwOC4yODItMy44ODYtLjgwOXptLTQuNTY5LTMuOTU1Yy0uOTUtLjE5OS0yLjEzNi0uNTUtMi42MzYtLjc4LTEuOTQxLS44OTMtNS4wMDMtMy42OS02LjE2NC01LjYzLTEuMTQtMS45MDUtMi4xOC01Ljg4LTIuNDA3LTkuMjA0LS4xODktMi43NzUuNzA1LTcuNzQyIDEuNzc2LTkuODc3Ljg3OS0xLjc1IDMuMjM1LTQuMTcgNS4xODQtNS4zMjUgMi4wMi0xLjE5NyA4Ljc0LTEuNjM1IDExLjk2My0uNzggMS4xMy4zIDIuNDQ0IDEuNzU3IDMuMTggMy41MjQuNjY0IDEuNTk0IDEuODIzIDYuMDM4IDIuODE2IDEwLjc5NmwuNjUyIDMuMTI1djExLjA2NmwtLjY4Mi4xMDRjLTQuMTAyLjYzLTguNzQ4IDEuODktMTAuODEyIDIuOTMzLS40NzIuMjM5LS45MjIuNDI4LTEgLjQyMS0uMDc5LS4wMDctLjkyLS4xNzUtMS44Ny0uMzczem0yNy44MTgtLjY0MmMtMi45MTUtMS42NDYtNC40NC0yLjA2LTguNTgyLTIuMzM4bC0xLjk0NS0uMTMuMTAyLTUuNjYyLjEwMS01LjY2LjcxMi0zLjM2YzEuOTU4LTkuMjM3IDMuMDkzLTEyLjI5MiA0Ljk2My0xMy4zNTcuOTAzLS41MTUgMS4yNTItLjU5OSAzLjQwOS0uODI0IDEuODcyLS4xOTUgNS4xNi4wMTQgNy4zMjYuNDY1IDEuNjE2LjMzNyAyLjc0NyAxLjA4NiA0LjkxNyAzLjI1NSAxLjg0NCAxLjg0NCAyLjQ4OSAyLjk2NSAzLjI1MyA1LjY1OSAxLjIyMiA0LjMxIDEuMDQxIDguOTQzLS41MzMgMTMuNjUyLS42MzYgMS45MDMtMS43ODMgMy42ODgtMy4zOTIgNS4yOC0yLjE2OCAyLjE0NC0zLjc1NiAzLjExOC01LjgzIDMuNTc3LTIuNDM0LjUzOC0yLjU5Ni41MTgtNC41LS41NTd6bS0xMi4wNzUtMjEuMzM2Yy0uMzQyLTEuNTktMS4yODItNC42MTMtMS45NS02LjI3Mi0uNTMtMS4zMTgtLjcwOC0xLjk5NS0uNjQ4LTIuNDYuMDktLjY5NCAxLjIxOS0yLjgyOSAyLjI0Mi00LjIzN2wuNjM4LS44NzguNTkuOTcgMS4xNDggMS44NzdjMS4wNDYgMS43MDYgMS4wNzYgMi4wMzguMzUxIDMuODU3LS41ODkgMS40NzgtMS4zNDQgNC4wMzctMS45NzUgNi42ODlsLS4yNiAxLjA5eiIgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9zdmc+'); } -body.base .is2d piece.pawn.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTI3Ljc5MiAyOS4zMjhxMC0xLjA4OC43NjgtMS42NjQuNDQ4LS4xOTIgMS44NTYtMS43OTItMi4yNC0xLjAyNC0zLjcxMi0zLjA3Mi0xLjQwOC0yLjExMi0xLjQwOC00LjggMC0zLjU4NCAyLjU2LTYuMDggMi42MjQtMi41NiA2LjA4LTIuNTYgMy41MiAwIDYuMDE2IDIuNTYgMi41NiAyLjQ5NiAyLjU2IDYuMDggMCAyLjY4OC0xLjQ3MiA0LjgtMS40MDggMi4wNDgtMy41ODQgMy4wNzIgMS4zNDQgMS42IDEuODU2IDEuNzkyLjY0LjU3Ni42NCAxLjY2NHQtLjY0IDEuNzI4bC0uNzY4Ljc2OHExLjE1MiAyLjgxNiAyLjE3NiA1LjUwNCAxLjAyNCAyLjY4OCAxLjk4NCA0LjguNzY4IDEuOTIgMi4xMTIgMi40OTZsMS40MDguNTc2IDIuNzUyIDEuNjY0cTIuNzUyIDEuNjY0IDMuMjY0IDMuMDA4LjQ0OCAxLjI4LjU3NiAzLjcxMi4xOTIgMi4zNjguMzIgNS4wNTZoLTM4LjI3MnEwLTIuNjg4LjEyOC01LjA1Ni4xMjgtMi40MzIuNjQtMy43MTIuMzg0LTEuMzQ0IDMuMi0zLjAwOGwyLjgxNi0xLjY2NCAxLjM0NC0uNTc2cTEuMzQ0LS41NzYgMi4xNzYtMi40OTYuODk2LTIuMTEyIDEuOTg0LTQuOCAxLjA4OC0yLjY4OCAyLjE3Ni01LjUwNGwtLjc2OC0uNzY4cS0uNzY4LS42NC0uNzY4LTEuNzI4em01Ljk1Mi0zLjAwOHEtMi42ODggMi44OC0yLjg4IDMuMDcyLjE5Mi4yNTYgMS40NzIgMS42IDEuMzQ0IDEuMjggMS42IDEuNi4xOTItLjMyIDEuNDcyLTEuNiAxLjM0NC0xLjM0NCAxLjcyOC0xLjYtLjM4NC0uMTkyLTEuODU2LTEuNi0xLjQwOC0xLjQ3Mi0xLjUzNi0xLjQ3MnoiLz48cGF0aCBkPSJtMzIuNDE5IDMwLjkzMi0xLjQzNi0xLjUxNiAxLjI2NS0xLjM5NmMuNjk1LS43NjkgMS4zNDgtMS40MjUgMS40NTItMS40Ni4xMDMtLjAzNC44ODQuNjE1IDEuNzM2IDEuNDQzbDEuNTQ4IDEuNTA2LTEuNTY1IDEuNDctMS41NjUgMS40Njl6IiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4='); } -body.base .is2d piece.knight.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTQyIDUwLjcyN2MtLjA3IDEuOTcyLjM0MyAzLjkuNzI3IDUuODE4bC4zNjQgMS42MzdjLjA2LjA2LjE0My4xMDUuMTgyLjE4Mi4wMjcuMDU0LS4wNTQuMTU0IDAgLjE4MS4xMDguMDU1LjI0MiAwIC4zNjMgMGg3LjYzN2MuMzAzIDAgLjYwNy4wMjguOTA5IDAgLjM2Ny0uMDMzLjcyNS0uMTM2IDEuMDktLjE4MS4xMjEtLjAxNS4yNDUuMDIuMzY0IDAgLjI0Ny0uMDQxLjQ4LS4xNDcuNzI4LS4xODIuMjQ3LS4wMzYgMS4wODQuMDQ3IDEuMjcyIDAgLjA2LS4wMTUtLjA2LS4xODIgMC0uMTgyczAgLjI0MiAwIC4xODJ2LTIuMzY1YzAtLjA2LjAzNC0uMTMxIDAtLjE4Mi0uMDk1LS4xNDItLjI2OC0uMjItLjM2My0uMzYzLS4wMzQtLjA1IDAtLjEyMSAwLS4xODItLjEyMS0uMTIxLS4yNjktLjIyMS0uMzY0LS4zNjQtLjAzNC0uMDUgMC0uMTIgMC0uMTgydi0xLjA5YzAtLjEyMi4wMy0uMjQ2IDAtLjM2NC0uMDMzLS4xMzItLjE0OS0uMjMyLS4xODItLjM2NC0uMDMtLjExNy4wNTQtLjI1NSAwLS4zNjMtLjAyNy0uMDU1LS4xODIuMDYtLjE4MiAwIDAtLjA1NS42MDMuMTIgMC0uMTgyLS4wNTQtLjAyNy0uMTM5LjA0My0uMTgxIDAtLjA0My0uMDQzLS4wNjEtLjE4MiAwLS4xODIuMTEyIDAgLjY2OC45NzMgMC0uMzY0LS4wMzktLjA3Ni0uMjQzLS4xMi0uMTgyLS4xODEuMDYtLjA2MS4xODIuMjY3LjE4Mi4xODEgMC0uMTkxLS4wNzYtLjM4Ni0uMTgyLS41NDUtLjAzNC0uMDUtLjEyMSAwLS4xODIgMGgtLjE4MmMuMTIxIDAgLjQ3Mi4wNTQuMzY0IDAtLjIyNC0uMTEyLS40OS0uMTAzLS43MjctLjE4Mi0uMTI5LS4wNDMtLjI0My0uMTIxLS4zNjQtLjE4Mi0uNTQ2LS4wNi0xLjA5NS0uMDkxLTEuNjM2LS4xODItLjE5LS4wMzEtLjM1NS0uMTYtLjU0Ni0uMTgxLS4zNjEtLjA0LS43MjcgMC0xLjA5IDBoLTEuODE5Yy0uMTgyIDAtLjM2NS4wMjUtLjU0NSAwLTEuNzg4LS4yNTYuNDUxLS4xODItMS42MzctLjE4Mi0uOTMxIDAgLjM2MS4wMi0xLjQ1NC0uMTgyLS4xODEtLjAyLS4zNjQgMC0uNTQ2IDAtLjA2IDAtLjEyNy0uMDI3LS4xODIgMC0uMTk1LjA5OC0uMzQ1LjI3NS0uNTQ1LjM2NC0uMzUuMTU1LS45LjAzLTEuMDkxLjM2My0uMTYyLjI4NC4zMS41ODcuMzY0LjkxLjAxNC4wODQtLjE4Mi4wOTUtLjE4Mi4xODEgMCAuMDYuMTIxIDAgLjE4MiAwIiBmaWxsPSIjZmZmIiBzdHJva2U9IiMwMDAiLz48cGF0aCBkPSJtMjQuODQ4IDM5LjcyOHEtLjM4NC43MDQuMTkyIDEuMjguNTc2LjU3Ni0uMTkyIDEuNDcyLS43MDQgMS4wMjQtMi42MjQgMi43NTItMS44NTYgMS43MjgtMy4yIDIuMzA0LTIuMTc2IDEuMjgtNC40OC4xOTItMS4xNTItLjU3Ni0yLjg4LTIuMjQtMS42NjQtMS42NjQtMi4zMDQtMi42ODgtLjc2OC0xLjAyNC0uNTc2LTEuNzI4LjE5Mi0uNzA0LjA2NC0xLjY2NCAwLS43NjgtLjM4NC0xLjA4OC0uMzg0LS4zODQuMzg0LTIuNDk2Ljc2OC0xLjkyIDMuMjY0LTYuMzM2IDIuNDk2LTQuNDE2IDMuMi02LjUyOC43MDQtMS45Mi0uMjU2LTEuNzI4LS44OTYuMTI4LS41MTItLjg5Ni4zODQtMS4xNTIgMS40MDgtMy4wNzIgMS4wMjQtMS45ODQgMS44NTYtMi45NDQuODk2LS44OTYgMS44NTYtLjcwNCAxLjAyNC4xMjggMS43OTItMS4xNTIuNzA0LTEuMjE2IDEuMzQ0LTMuNzc2LjcwNC0yLjU2IDEuNDcyLTQuNjcyLjk2IDEuOTg0IDIuMDQ4IDMuNzc2IDEuMDg4IDEuNzkyIDIuMjQgMi4yNCAyLjg4LTEuMDg4IDYuOTEyLS41MTIgNS43Ni43NjggOC41MTIgMi4zMDQgMi43NTIgMS40NzIgNi41OTIgNi4yMDggMS40NzIgMS44NTYgMi4zNjggMy45NjguODk2IDIuMDQ4IDEuNiA0LjQ4LjcwNCAyLjQzMiAxLjA4OCA1LjU2OC40NDggMy4xMzYuNjQgNS42MzIgMCAyLjY4OC0uMTkyIDQuOTkyLS4xMjggMi4yNCAwIDQuNTQ0djMuNzc2cTAgMS40MDguNTEyIDMuNzc2LjMyIDEuOTg0IDEuMjggNC40MTYuOTYgMi40MzIgMS43OTIgNC44aC00MC4xOTJxLS44MzItMS42NjQtLjU3Ni0zLjY0OCAwLTEuMjguMzItMy4xMzZ0MS4wMjQtMy41MnEuNTc2LTEuNDcyIDEuNTM2LTIuODE2Ljk2LTEuNDA4IDIuMDQ4LTIuNjg4IDIuMDQ4LTMuMiAzLjg0LTUuMTIgMS41MzYtMS43MjggMy4zMjgtMy4yNjQgMS44NTYtMS42IDMuMzkyLTMuNDU2IDEuMjgtMS44NTYgMS43MjgtMy4zOTIuMzItMS4wMjQtLjA2NC0yLjc1Mi0uMzg0LTEuNzkyLS43MDQtMS43MjgtLjI1Ni4xMjgtMS4wMjQgMi4zNjgtLjc2OCAyLjI0LTEuNDcyIDMuMDA4LS43MDQgMS4wODgtMS41MzYgMS41MzYtLjc2OC4zODQtMS4zNDQuNzY4LS43NjguMzg0LTEuMjE2LjM4NC0uMzg0IDAtLjk2LjM4NC0uNzA0LjUxMi0xLjY2NCAxLjM0NC0uODk2Ljc2OC0xLjI4IDEuNDcyem0tMi4zMDQgMTYuMjU2cTEuNi4zODQgNC45MjguMzg0IDMuMzkyLS4wNjQgNC40OC0uMDY0bC4xMjgtMy4ycS0uOTYgMC0zLjk2OC0uMTI4LTIuOTQ0LS4xMjgtNC4yODgtLjM4NHptMjEuNTY4LjUxMnEyLjA0OC0uMTI4IDQuODY0LS4zODQgMi44OC0uMjU2IDQuOTkyLS4zODRsLS42NC0zLjI2NHEtMS43MjguMzg0LTUuMDU2LjU3Ni0zLjMyOC4xMjgtNC4zNTIuMTkyem0tNi4xNDQtNS4xMi0zLjM5MiAzLjM5MiAzLjM5MiAzLjUyIDMuMzkyLTMuNTJ6bS0xNS4yMzItMjguMjg4cS0uNzY4LS4xMjgtMi40OTYtLjEyOC0uNDQ4IDAtLjg5Ni41MTItLjM4NC41MTItLjQ0OC44MzJ2Ljg5NnEuMDY0LjY0LjQ0OC45Ni4xMjguMTI4IDEuMzQ0LjEyOC4zODQtLjA2NC45Ni0uMzIuNTc2LS4zMiAxLjA4OC0uNTc2IDEuMzQ0LS43MDQgMS4zNDQtMS4yMTYuMTI4LS43MDQtLjMyLS43NjgtLjM4NC0uMDY0LTEuMDI0LS4zMnptLTEyLjE2IDEzLjY5NnExLjA4OCAxLjA4OCAxLjA4OCAyLjMwNC4wNjQuMjU2LS4xMjggMS4yOC0uMTkyLjk2LS4xOTIgMS4wMjQuMTkyLjI1NiAxLjM0NC0xLjA4OCAxLjIxNi0xLjM0NCAxLjA4OC0xLjg1NiAwLS4zODQtMS4yOC0xLjA4OC0xLjI4LS43MDQtMS45Mi0uNTc2em0xOS4yLTI1LjA4OHEzLjg0LjU3NiA4IDEuNzI4IDQuMTYgMS4wODggNi45MTIgMy44NCAyLjQ5NiAyLjg4IDMuMzkyIDQuMjI0Ljg5NiAxLjI4IDIuMDQ4IDMuOTA0Ljg5NiAzLjAwOCAxLjM0NCA2LjMzNi41MTIgMy4zMjguNzY4IDYuMjcyLjE5MiAyLjQ5Ni4xOTIgNC45MjggMCAyLjM2OCAxLjUzNiA2Ljc4NC0uMTkyLTMuMjY0IDAtNi4wMTYuMjU2LTIuODE2LjEyOC01LjgyNC0uMTI4LTMuMzI4LS44MzItNy40ODh0LTEuNDcyLTYuMDhxLS45Ni0yLjM2OC0yLjU2LTQuNDE2LTEuNTM2LTIuMDQ4LTMuNDU2LTQuMTYtMS43MjgtMS44NTYtMy43NzYtMi42ODgtMi4wNDgtLjg5Ni01LjMxMi0xLjQ3Mi0yLjE3Ni0uNDQ4LTMuNjQ4LS4xOTItMS40MDguMjU2LTMuMjY0LjMyeiIvPjxwYXRoIGQ9Im0yMy43OCA1Ni4xNTljLS40Ny0uMDY2LS45MDktLjE3Mi0uOTczLS4yMzYtLjA2NC0uMDY1LjE1LS44MjUuNDc3LTEuNjlsLjU5My0xLjU3Mi41NzcuMTA5Yy40NzUuMDg5IDYuMTIzLjQ1IDcuMjI3LjQ2My4yNzIuMDAzLjMxOC4xODYuMzE4IDEuMjYxIDAgMS45OC4zMDMgMS44MzctMy43OTIgMS44MDktMS45NjQtLjAxNC0zLjk1Ni0uMDc4LTQuNDI3LS4xNDR6bTEyLjQ5Mi4zNS0xLjYzMi0xLjYzOSAxLjY3OC0xLjY3OCAxLjY3OC0xLjY3OCAxLjYzIDEuNjIyIDEuNjMgMS42MjMtMS41MDYgMS42MzdjLS44MjguOS0xLjU4MyAxLjY2My0xLjY3NyAxLjY5NC0uMDk0LjAzMi0uOTA1LS42OC0xLjgwMi0xLjU4MXptMTAuNzY5LS4zMDFjLjEyNC0uMDUuMzY5LS4wNTMuNTQ2LS4wMDdzLjA3Ni4wODctLjIyNC4wOWMtLjMuMDA0LS40NDUtLjAzMy0uMzIyLS4wODN6bTYuMTYzLTkuMTU0Yy0uNDMyLTEuNTc0LS41NTItMi40ODMtLjY4Ny01LjE4MS0uMzQ4LTYuOTQ0LTEuMzgzLTEzLjg0OC0yLjUxNi0xNi43ODYtLjY4Ny0xLjc4My0xLjg1NS0zLjY3OS0zLjU1Mi01Ljc3LTIuMjgyLTIuODExLTMuOTM5LTQuMTM2LTYuNDg1LTUuMTg2LTEuMzMyLS41NS01LjMyMS0xLjYwMi03LjU2Mi0xLjk5Ni0uNzI4LS4xMjctMS4yNTUtLjMwMS0xLjE3LS4zODZzMS4wNDktLjIwMiAyLjE0My0uMjYxYzIuMjM1LS4xMjEgNC4zNy4yMjYgNy40MiAxLjIwNyAyLjgyMy45MDggNC4zNyAyLjE3NSA3LjU4NSA2LjIxIDIuNjkzIDMuMzggMy43NjkgNS43OTYgNC42IDEwLjMzMS45ODUgNS4zNyAxLjE5IDkuNDQxLjg2IDE3LjA5MWwtLjExMyAyLjYzNnptLTMzLjU2Mi0yMC44ODhjLS44MTItLjIyNi0uOTY1LTEuNzE3LS4yNjMtMi41NTIuNDMzLS41MTQuNTYyLS41NiAxLjU5MS0uNTU2IDEuNjcuMDA1IDIuOTI0LjM3NCAyLjk5OC44ODEuMDg3LjU5OC0uMjU4LjkxLTEuODY4IDEuNjktMS40NzQuNzEyLTEuNjczLjc1Ni0yLjQ1OC41Mzd6bS04LjA1OCAxMy43MDVjLjA4NC0xLjUzMy4wNi0xLjY3Ny0uMzc4LTIuMzE3LS4zNzQtLjU0NS0uNDEtLjY4MS0uMTgxLS42ODEuNDEgMCAyLjQ1IDEuMTE2IDIuNTU5IDEuNC4xODUuNDgzLS4xNiAxLjE2LTEuMTExIDIuMTgzbC0uOTc4IDEuMDUuMDktMS42MzV6IiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4='); } -body.base .is2d piece.bishop.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTI3Ljk4NCA1NS40NzJxLTIuNzUyLS4wNjQtNC41NDQtLjA2NC0xLjc5Mi0uMDY0LTEuOTItLjI1Ni0uODMyLS43NjgtLjg5Ni0xLjg1Ni0uMDY0LTEuMDg4Ljc2OC0xLjc5Mi4wNjQtLjEyOCAxLjA4OC0xLjUzNiAxLjAyNC0xLjQ3MiAyLjQzMi0zLjU4NC0yLjQzMi0zLjA3Mi00LjYwOC02LjAxNi0yLjE3Ni0zLjAwOC0yLjYyNC0zLjUyLTEuNDA4LTEuMjE2LTEuNDA4LTMuMDA4IDAtMS44NTYgMS40MDgtMy4yNjQuMzg0LS4zODQgMi4zMDQtMi45NDQgMS45ODQtMi41NiA0LjIyNC01LjU2OCAyLjMwNC0zLjAwOCA0LjIyNC01LjU2OCAxLjk4NC0yLjYyNCAyLjI0LTIuODguMjU2LS4yNTYuMzg0LS40NDgtLjcwNC0uNzY4LTEuNDcyLTEuNDcyLS43MDQtLjcwNC0uODMyLS45Ni0yLjA0OC0xLjc5MiAwLTMuNTg0LjE5Mi0uMzIgMS43MjgtMS43OTIgMS42LTEuNDcyIDEuODU2LTEuODU2IDEuNzI4LTEuNjY0IDMuMzI4IDBMMzcuNTIgNS4zNnExLjQ3MiAxLjQ3MiAxLjg1NiAxLjc5MiAxLjc5MiAxLjc5MiAwIDMuNTg0LS4yNTYuMjU2LTEuMDI0Ljk2dC0xLjQwOCAxLjQ3MnEuMDY0IDAgLjMyLjE5Mi40NDguNTEyIDIuMzY4IDMuMTM2IDEuOTIgMi41NiA0LjA5NiA1LjU2OCAyLjI0IDMuMDA4IDQuMDk2IDUuNTY4IDEuOTIgMi41NiAyLjMwNCAyLjk0NCAxLjM0NCAxLjQwOCAxLjM0NCAzLjI2NCAwIDEuNzkyLTEuMzQ0IDMuMDA4LS40NDguNTEyLTIuNTYgMy4zOTItMi4wNDggMi44MTYtNC4zNTIgNS44ODggMS42IDIuMTEyIDIuNjg4IDMuNzEyIDEuMTUyIDEuNTM2IDEuMzQ0IDEuNjY0IDEuNzI4IDEuNzkyLS4xOTIgMy42NDgtLjEyOC4xOTItMi4xMTIuMjU2LTEuOTIgMC00LjguMDY0LS4xOTIgMS40MDgtLjEyOCAxLjQwOC4zMi4zMiAyLjE3Ni4zMiAxLjg1Ni0uMDY0IDQuMDk2LS4xMjh0NC4yODgtLjA2NHEyLjExMi0uMDY0IDIuOTQ0LjE5MiAyLjExMi43MDQgMi45NDQgMy4yNjQuODMyIDIuNDk2IDEuNDA4IDQuODY0SDQwLjc4NHEtMS4zNDQgMC0yLjU2LS4wNjQtMS4xNTItLjEyOC0yLjM2OC0uNzA0LTEuMTUyLS41NzYtMS40NzItLjgzMi0uMzItLjMyLS4zODQtLjcwNCAwIC4zODQtLjI1Ni43MDQtLjI1Ni4yNTYtMS40MDguODMyLTEuMzQ0LjU3Ni0yLjU2LjcwNC0xLjIxNi4wNjQtMi4zNjguMDY0aC0xNy4yOHEuNzA0LTIuMzY4IDEuNjY0LTQuODY0IDEuMDI0LTIuNTYgMy4xMzYtMy4yNjQuNzY4LS4yNTYgMi43NTItLjE5MiAyLjA0OCAwIDQuMTYuMDY0IDIuMTc2LjA2NCAzLjkwNC4xMjggMS43OTIgMCAyLjExMi0uMzIuMzItLjE5Mi4xOTItLjM4NC0uMDY0LS4yNTYtLjA2NC0xLjAyNHptNy41NTItMjAuNDE2aDMuNTJ2LTIuOTQ0aC0zLjUydi00LjI4OGgtMi45NDR2NC4yODhoLTMuNTJ2Mi45NDRoMy41MnYxMS4wNzJoMi45NDR6TTM0IDUuNjE2cS0uMjU2LjM4NC0xLjYgMS43MjgtMS4yOCAxLjM0NC0xLjQ3MiAxLjUzNi4xOTIuMzg0IDEuNDcyIDEuNzI4IDEuMzQ0IDEuMjggMS42IDEuNDcyLjE5Mi0uMTkyIDEuNTM2LTEuNDcybDEuNzI4LTEuNzI4cS0uMzg0LS4xOTItMS43MjgtMS41MzZRMzQuMTkyIDYgMzQgNS42MTZ6bS0yLjk0NCA0OS43MjhoNS44ODhsLjU3Ni0yLjQ5NmgtNy4wNHoiLz48cGF0aCBkPSJNMzAuODg2IDU0LjQ0M2MtLjQwNS0xLjc1OC0uNjctMS42MjIgMy4xNzQtMS42MjJoMy4zODZsLS4xMTYuNThjLS4wNjQuMzItLjIuODkzLS4zMDMgMS4yNzNsLS4xODYuNjkySDMxLjF6bTEuNzg3LTEzLjg5NXYtNS41NDVIMjkuMjJ2LTIuOTFoMy40NTR2LTQuMTgxaDIuNzI4djQuMTgxaDMuNjM2djIuODk2bC0xLjc3My4wNTItMS43NzMuMDUyLS4wNDggNS41LS4wNDggNS41aC0yLjcyM3YtNS41NDV6bS0uMjU3LTMwLjA4NkwzMSA5LjAwNWwuOTEyLTEuMDQ3Yy41MDEtLjU3NSAxLjE4NS0xLjI5NCAxLjUxOS0xLjU5N2wuNjA3LS41NSAxLjU3MSAxLjYgMS41NzIgMS42LTEuNTQgMS40MDVjLS44NDguNzcyLTEuNiAxLjQyNy0xLjY3MyAxLjQ1NC0uMDczLjAyNy0uNzctLjYwNy0xLjU1LTEuNDA4eiIgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIi8+PHBhdGggZD0iTTI3Ljk4NCA1NS40NzJxLTIuNzUyLS4wNjQtNC41NDQtLjA2NC0xLjc5Mi0uMDY0LTEuOTItLjI1Ni0uODMyLS43NjgtLjg5Ni0xLjg1Ni0uMDY0LTEuMDg4Ljc2OC0xLjc5Mi4wNjQtLjEyOCAxLjA4OC0xLjUzNiAxLjAyNC0xLjQ3MiAyLjQzMi0zLjU4NC0yLjQzMi0zLjA3Mi00LjYwOC02LjAxNi0yLjE3Ni0zLjAwOC0yLjYyNC0zLjUyLTEuNDA4LTEuMjE2LTEuNDA4LTMuMDA4IDAtMS44NTYgMS40MDgtMy4yNjQuMzg0LS4zODQgMi4zMDQtMi45NDQgMS45ODQtMi41NiA0LjIyNC01LjU2OCAyLjMwNC0zLjAwOCA0LjIyNC01LjU2OCAxLjk4NC0yLjYyNCAyLjI0LTIuODguMjU2LS4yNTYuMzg0LS40NDgtLjcwNC0uNzY4LTEuNDcyLTEuNDcyLS43MDQtLjcwNC0uODMyLS45Ni0yLjA0OC0xLjc5MiAwLTMuNTg0LjE5Mi0uMzIgMS43MjgtMS43OTIgMS42LTEuNDcyIDEuODU2LTEuODU2IDEuNzI4LTEuNjY0IDMuMzI4IDBMMzcuNTIgNS4zNnExLjQ3MiAxLjQ3MiAxLjg1NiAxLjc5MiAxLjc5MiAxLjc5MiAwIDMuNTg0LS4yNTYuMjU2LTEuMDI0Ljk2dC0xLjQwOCAxLjQ3MnEuMDY0IDAgLjMyLjE5Mi40NDguNTEyIDIuMzY4IDMuMTM2IDEuOTIgMi41NiA0LjA5NiA1LjU2OCAyLjI0IDMuMDA4IDQuMDk2IDUuNTY4IDEuOTIgMi41NiAyLjMwNCAyLjk0NCAxLjM0NCAxLjQwOCAxLjM0NCAzLjI2NCAwIDEuNzkyLTEuMzQ0IDMuMDA4LS40NDguNTEyLTIuNTYgMy4zOTItMi4wNDggMi44MTYtNC4zNTIgNS44ODggMS42IDIuMTEyIDIuNjg4IDMuNzEyIDEuMTUyIDEuNTM2IDEuMzQ0IDEuNjY0IDEuNzI4IDEuNzkyLS4xOTIgMy42NDgtLjEyOC4xOTItMi4xMTIuMjU2LTEuOTIgMC00LjguMDY0LS4xOTIgMS40MDgtLjEyOCAxLjQwOC4zMi4zMiAyLjE3Ni4zMiAxLjg1Ni0uMDY0IDQuMDk2LS4xMjh0NC4yODgtLjA2NHEyLjExMi0uMDY0IDIuOTQ0LjE5MiAyLjExMi43MDQgMi45NDQgMy4yNjQuODMyIDIuNDk2IDEuNDA4IDQuODY0SDQwLjc4NHEtMS4zNDQgMC0yLjU2LS4wNjQtMS4xNTItLjEyOC0yLjM2OC0uNzA0LTEuMTUyLS41NzYtMS40NzItLjgzMi0uMzItLjMyLS4zODQtLjcwNCAwIC4zODQtLjI1Ni43MDQtLjI1Ni4yNTYtMS40MDguODMyLTEuMzQ0LjU3Ni0yLjU2LjcwNC0xLjIxNi4wNjQtMi4zNjguMDY0aC0xNy4yOHEuNzA0LTIuMzY4IDEuNjY0LTQuODY0IDEuMDI0LTIuNTYgMy4xMzYtMy4yNjQuNzY4LS4yNTYgMi43NTItLjE5MiAyLjA0OCAwIDQuMTYuMDY0IDIuMTc2LjA2NCAzLjkwNC4xMjggMS43OTIgMCAyLjExMi0uMzIuMzItLjE5Mi4xOTItLjM4NC0uMDY0LS4yNTYtLjA2NC0xLjAyNHptNy41NTItMjAuNDE2aDMuNTJ2LTIuOTQ0aC0zLjUydi00LjI4OGgtMi45NDR2NC4yODhoLTMuNTJ2Mi45NDRoMy41MnYxMS4wNzJoMi45NDR6TTM0IDUuNjE2cS0uMjU2LjM4NC0xLjYgMS43MjgtMS4yOCAxLjM0NC0xLjQ3MiAxLjUzNi4xOTIuMzg0IDEuNDcyIDEuNzI4IDEuMzQ0IDEuMjggMS42IDEuNDcyLjE5Mi0uMTkyIDEuNTM2LTEuNDcybDEuNzI4LTEuNzI4cS0uMzg0LS4xOTItMS43MjgtMS41MzZRMzQuMTkyIDYgMzQgNS42MTZ6bS0yLjk0NCA0OS43MjhoNS44ODhsLjU3Ni0yLjQ5NmgtNy4wNHoiLz48cGF0aCBkPSJNMzAuODg2IDU0LjQ0M2MtLjQwNS0xLjc1OC0uNjctMS42MjIgMy4xNzQtMS42MjJoMy4zODZsLS4xMTYuNThjLS4wNjQuMzItLjIuODkzLS4zMDMgMS4yNzNsLS4xODYuNjkySDMxLjF6bTEuNzg3LTEzLjg5NXYtNS41NDVIMjkuMjJ2LTIuOTFoMy40NTR2LTQuMTgxaDIuNzI4djQuMTgxaDMuNjM2djIuODk2bC0xLjc3My4wNTItMS43NzMuMDUyLS4wNDggNS41LS4wNDggNS41aC0yLjcyM3YtNS41NDV6bS0uMjU3LTMwLjA4NkwzMSA5LjAwNWwuOTEyLTEuMDQ3Yy41MDEtLjU3NSAxLjE4NS0xLjI5NCAxLjUxOS0xLjU5N2wuNjA3LS41NSAxLjU3MSAxLjYgMS41NzIgMS42LTEuNTQgMS40MDVjLS44NDguNzcyLTEuNiAxLjQyNy0xLjY3MyAxLjQ1NC0uMDczLjAyNy0uNzctLjYwNy0xLjU1LTEuNDA4eiIgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9zdmc+'); } -body.base .is2d piece.rook.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTMwLjI4OCAzNS4zMTJsMy41MiAzLjcxMiAzLjcxMi0zLjcxMi0zLjcxMi0zLjUyem0xOC4xNzYtMTAuMzA0bDIuNDMyIDE5LjUyIDIuODE2IDYuMDE2djEyLjkyOEgxNC4xNlY1MC41NDRsMi42MjQtNi4wMTYgMi40MzItMTkuNTItNC45MjgtMTAuNzUyIDMuMDcyLTkuNzI4SDI2djguMzJoMy43MTJ2LTguMzJoOC43Njh2OC4zMmgzLjY0OHYtOC4zMmg4LjY0bDMuMDcyIDkuNzI4ek0xOS4wODggNDYuMzg0bC0xLjQwOCAzLjA3Mkg1MGwtMS41MzYtMy4wNzJ6bTI3LjItMjIuNzg0SDIxLjcxMmwuNTc2IDIuOTQ0aDIzLjY4eiIvPjxwYXRoIGQ9Ik0yMi4xMzIgMjUuNDY0Yy0uMTEtLjU3NS0uMjQtMS4yMy0uMjg5LTEuNDU1bC0uMDg3LS40MWgyNC4zNzF2LjYxMmMwIC4zMzYtLjA1Mi45OS0uMTE2IDEuNDU0bC0uMTE2Ljg0NGgtMjMuNTZ6bTkuODcgMTEuNjEybC0xLjY3LTEuNzc5IDEuNzEtMS43MDMgMS43MS0xLjcwNC41MDYuNDRhNzMuMDIzIDczLjAyMyAwIDAgMSAxLjgyNCAxLjcxNUwzNy40IDM1LjMybC0xLjc3IDEuNzc3Yy0uOTc0Ljk3Ny0xLjgxMyAxLjc3My0xLjg2NCAxLjc2OC0uMDUyLS4wMDUtLjg0Ny0uODEtMS43NjUtMS43ODh6TTE4LjE5NiA0OC40NjRjLjIzNi0uNTI1LjUzNS0xLjE4LjY2NC0xLjQ1NWwuMjM0LS41aDI5LjM5MmwuNzMyIDEuNDU1LjczMSAxLjQ1NEgxNy43Njh6IiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4='); } -body.base .is2d piece.queen.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTIxLjA4OCA1MS4zMTItMS42NjQgNS4xODQgMy42NDgtMy4zMjh6bTI1LjA4OC4xMjgtMi4xNzYgMS44NTYgMy4yNjQgMi43NTJ6bS0xOC4xNzYtLjc2OC0yLjYyNC42NC4zMiAyLjg4IDIuNjI0LS40NDh6bTE0LjE0NC42NC0yLjU2LS42NC0uNTEyIDMuMDcyIDIuNDk2LjMyem0tMjMuMDQtMy4yNjQtMTAuNzUyLTI0LjMycS0xLjQwOC4zODQtMi4zMDQtLjU3NmwtMS40MDgtMS41MzZxLTEuOTItMS42NjQgMC0zLjU4NGwxLjQwOC0xLjM0NHExLjY2NC0yLjA0OCAzLjUyIDBsMS41MzYgMS4zNDRxMS41MzYgMS45MiAwIDMuNTg0bC0uNzY4Ljc2OCAxMC45NDQgOC41NzYtLjk2LTEzLjgyNHEtLjgzMi0uMTkyLTEuNDA4LS43NjhsLTEuMzQ0LTEuNDA4cS0xLjk4NC0xLjc5MiAwLTMuNTJsMS4zNDQtMS41MzZxMS43OTItMS42NjQgMy41ODQgMGwxLjUzNiAxLjUzNnExLjUzNiAxLjcyOCAwIDMuNTJsLTEuNTM2IDEuNDA4IDYuNTkyIDExLjI2NCAzLjUyLTEyLjkyOC0uNTc2LS4zMi0xLjQwOC0xLjUzNnEtMS43MjgtMS43OTIgMC0zLjU4NGwxLjQwOC0xLjUzNnExLjcyOC0xLjQwOCAzLjUyIDBsMS40MDggMS41MzZxMS45ODQgMS43OTIgMCAzLjU4NGwtMS40MDggMS41MzYtLjY0LjMyIDMuNTg0IDEzLjA1NiA2LjU5Mi0xMS4wNzItMS41MzYtMS41MzZxLTEuNTM2LTEuODU2IDAtMy43MTJsMS40MDgtMS40MDhxMS44NTYtMS41MzYgMy42NDggMGwxLjQwOCAxLjQwOHExLjg1NiAxLjg1NiAwIDMuNzEybC0xLjQwOCAxLjM0NC0xLjIxNi43NjgtLjc2OCAxMy41NjggMTEuMjY0LTkuOTg0LS45Ni0uNzY4cS0xLjUzNi0xLjg1NiAwLTMuNzEybDEuNTM2LTEuNDA4cTEuNzkyLTEuNjY0IDMuNTg0IDBsMS4zNDQgMS40MDhxMS44NTYgMS44NTYgMCAzLjcxMmwtMS4zNDQgMS4zNDRxLTEuMDg4IDEuMDg4LTIuMzY4Ljc2OGwtMTEuMiAyNi4zMDQgMy4wNzIgMTIuNDhoLTM2LjkyOHptMTQuNzg0LjY0LTMuMjY0IDMuMiAzLjI2NCAzLjI2NCAzLjA3Mi0zLjI2NHptLTEzLjU2OC01LjA1NiAxLjIxNiAyLjU2cTIuNjg4LTEuMjE2IDUuODI0LTIuMzA0IDMuMi0xLjA4OCA2LjY1Ni0xLjA4OCAzLjMyOCAwIDUuODI0LjgzMnQ2LjMzNiAyLjc1MmwxLjA4OC0yLjYyNHEtMy40NTYtMS45Mi02LjUyOC0yLjg4LTMuMDcyLS45Ni02LjcyLS45Ni0zLjU4NCAwLTcuMjk2Ljk2LTMuNjQ4Ljg5Ni02LjQgMi43NTJ6bS0xMi42MDgtMjQuOTYtMS40MDggMS4yMTYgMS40MDggMS40MDggMS4yMTYtMS40MDh6bTEzLjA1Ni02Ljc4NC0xLjM0NCAxLjI4IDEuMzQ0IDEuMzQ0IDEuMjgtMS4zNDR6bTEzLjEyLTIuMzA0LTEuNTM2IDEuNTM2IDEuNTM2IDEuNTM2IDEuMzQ0LTEuNTM2em0xMi45MjggMi4zMDQtMS40MDggMS40MDggMS40MDggMS40MDggMS4yMTYtMS40MDh6bTEzLjM3NiA0LjkyOC0xLjI4IDEuMjggMS4yOCAxLjM0NCAxLjI4LTEuMzQ0eiIvPjxwYXRoIGQ9Im0xOS43NDggNTUuODU5YzAtLjA2NS4yOTgtMS4wODIuNjYzLTIuMjZsLjY2My0yLjE0NC45NzQuODQxLjk3NC44NDEtMS41IDEuNDFjLTEuNDA5IDEuMzI0LTEuNzc0IDEuNTk0LTEuNzc0IDEuMzEyem01LjkxMi0yLjczM2MtLjA2NC0uNTgzLS4xMzItMS4yMTctLjE1LTEuNDEtLjAyOS0uMjg4LjE4Mi0uNDA1IDEuMTg1LS42NmwxLjIyLS4zMDkuMTA0Ljg0Mi4xODggMS41MDIuMDg0LjY2MS0xLjAyNy4xMjljLS41NjUuMDctMS4xMy4xNjgtMS4yNTcuMjE2LS4xNjEuMDYyLS4yNjQtLjIyNy0uMzQ3LS45NzF6bTYuNTczLjMzOS0xLjYwNy0xLjYxOCAxLjU2OS0xLjQzNmMuODYyLS43OSAxLjY1Ni0xLjQzNSAxLjc2NC0xLjQzNXMuODA3LjY3IDEuNTU0IDEuNDkxbDEuMzU3IDEuNDkyLTEuNTE1IDEuNTYyLTEuNTE2IDEuNTYzem03LjY1MS4zNzhjLS43NzQtLjA4LS43NzEtLjA3LS40NzctMS44NTJsLjIwNC0xLjIzNyAxLjIwNS4zMDhjLjgxNC4yMDggMS4xOTQuMzkxIDEuMTcyLjU2NWEzNS4xMSAzNS4xMSAwIDAgMSAtLjI0IDEuMzAzYy0uMjI4IDEuMTUtLjExNyAxLjA5Ni0xLjg2NC45MTN6bTUuNjI4LjcxLTEuNDE4LTEuMjE0Ljk1OC0uODUzYy41MjctLjQ3IDEuMDAyLS44MTEgMS4wNTUtLjc1OS4xNTEuMTUxIDEuMDUyIDQuMDY4LjkzMSA0LjA1NC0uMDYtLjAwOC0uNzQ2LS41Ni0xLjUyNi0xLjIyOHptLTEuNDkyLTkuMjE5Yy00LjQyMy0yLjE1Mi04LjA4NS0yLjkwNy0xMS45ODUtMi40NjgtMi41NjMuMjg5LTQuMTk1LjczOC03LjYyNyAyLjFsLTIuODg2IDEuMTQ0LS41MzMtMS4xNzRjLS40MDEtLjg4Ni0uNDgyLTEuMjM0LS4zMy0xLjQxNy4zMTUtLjM4IDMuMDMyLTEuNjYgNC41OTctMi4xNjYgMy43My0xLjIwNiA4LjUyLTEuNjQ5IDEyLjEwMi0xLjExOSAyLjY5NS4zOTkgNC40OS45NzQgNy40MzYgMi4zODMgMi4yODYgMS4wOTQgMi40IDEuMTc0IDIuMjQ0IDEuNTc0LS4zNTIuOTAxLS45MTYgMi4xNDgtLjk2NSAyLjEzMi0uMDI5LS4wMDgtLjk1Mi0uNDUzLTIuMDUyLS45ODl6bTE1LjQ3NS0yNi42NzQtLjQ2MS0uNTkuNTc1LS41OTMuNTc1LS41OTMuNTg5LjU3LjU4OC41Ny0uNDg4LjYxMmMtLjI2OS4zMzctLjU4NS42MTItLjcwMy42MTJzLS40MjEtLjI2NS0uNjc1LS41ODl6bS0xMy4zODMtNC43NzUtLjYxNy0uNjM3LjYyNi0uNjQ3LjYyNy0uNjQ2LjU5Ny42NS41OTcuNjUyLS40ODIuNjMyYy0uMjY1LjM0OC0uNTM5LjYzMi0uNjA3LjYzMi0uMDY5IDAtLjQwMi0uMjg2LS43NDEtLjYzNnptLTEyLjk2NC0yLjA1NC0uNjc0LS42OS43MzYtLjcxOC43MzYtLjcxOC42MDkuNzI1LjYxLjcyNi0uNTczLjY2N2MtLjMxNC4zNjctLjYxNi42NzQtLjY3LjY4My0uMDU1LjAwOC0uNDAzLS4yOTUtLjc3NC0uNjc1em0tMTMuMDc1IDEuODg4LS40OTMtLjU5NS41OS0uNTcyLjU5LS41NzEuNTcyLjU3Mi41NzIuNTcyLS40NjMuNjA3Yy0uMjU1LjMzNC0uNTU2LjYwMS0uNjcuNTk0LS4xMTItLjAwNy0uNDI3LS4yOC0uNjk4LS42MDd6bS0xMy4wNDIgNi45MDctLjYyNS0uNjQ5LjUyMy0uNTQ2Yy42NDYtLjY3NS44MDYtLjY3OSAxLjQyNC0uMDM0bC40OS41MTMtLjU5My42ODItLjU5My42ODN6IiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4='); } -body.base .is2d piece.king.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjY4IiB3aWR0aD0iNjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTIzLjkxNCA1NC4zODQuMzIgMi44OHExLjE1MiAwIDIuMTc2LS4wNjQgMS4wMjQtLjA2NCAyLjExMi0uMTkydi0yLjk0NHEtMi4wNDggMC00LjYwOC4zMnptMTkuOTY4IDBxLS45NiAwLTIuMTEyLS4xMjgtMS4wODgtLjE5Mi0xLjk4NC0uMTkydjMuMDcycS45NiAwIDEuODU2LjA2NC44OTYuMDY0IDEuOTg0LjA2NHptLTIzLjY4LTQuNjA4cS43MDQtLjM4NCAxLjcyOC0uNzY4IDEuMDI0LS40NDggMi43NTItLjk2IDIuMzA0LS43NjggNC4zNTItMS4xNTIgMi4xMTItLjM4NCAzLjY0OC0uNTEydi0xMS4zOTJxLTEuMjgtNS45NTItMi42ODgtMTEuMi0xLjQwOC01LjI0OC0zLjkwNC02LjAxNi0yLjg4LS43NjgtNi43Mi0uNDQ4LTMuNzc2LjMyLTQuOTkyLjg5Ni0xLjM0NC43MDQtMy4zOTIgMi42MjQtMS45ODQgMS44NTYtMi43NTIgNC4xNi0uODMyIDIuNDMyLTEuMDg4IDQuMzUyLS4xOTIgMS45Mi0uMzIgMy4xMzYgMCAyLjQ5NiAxLjA4OCA3LjEwNC42NCAyLjMwNCAxLjcyOCAzLjk2OCAxLjE1MiAxLjY2NCAzLjMyOCAzLjM5MiAxLjkyIDEuNjY0IDMuNzEyIDIuMTc2IDEuNzkyLjQ0OCAzLjUyLjY0em0xMy44ODgtMjEuNDRxLjU3Ni0yLjY4OCAxLjIxNi01LjEyLjcwNC0yLjQ5NiAxLjY2NC00LjQxNiAwLS42NC0uNTc2LTEuNzkyLS41MTItLjk2LTEuMTUyLTEuNzkyLS41NzYtLjgzMi0xLjAyNC0xLjc5Mi0xLjYgMi4xNzYtMi4zMDQgMy41ODQtLjU3NiAxLjAyNC0uNzA0IDEuNDcyLS4wNjQuNDQ4LS4wNjQuODMyIDEuNzI4IDMuNTIgMi45NDQgOS4wMjR6bTE2LjI1NiAyNC4xOTJxLjUxMiA1LjUwNCAxLjI4IDEyLjE2aC0zNS41ODRxLjM4NC0zLjMyOC43MDQtNi40NjQuMzItMy4xMzYuNzA0LTUuNjk2LTEuNTM2LS4zMi0zLjA3Mi0uOTYtMS41MzYtLjcwNC0zLjM5Mi0yLjExMi0yLjU2LTIuMTEyLTMuOTA0LTQuMTYtMS4zNDQtMi4wNDgtMi4xMTItNC45MjgtMS4yMTYtNC43MzYtMS4yMTYtOCAuMDY0LTEuMzQ0LjMyLTMuNTIuMzItMi4xNzYgMS40MDgtNC45MjguODk2LTIuODggMy40NTYtNS4yNDggMi41Ni0yLjM2OCA0LjIyNC0zLjA3MiAxLjQ3Mi0uNzY4IDUuOTUyLTEuMjE2IDQuNDgtLjQ0OCA3Ljc0NC40NDggMS41MzYuNjQgMS45ODQgMS4yMTYuNzY4LTEuMzQ0IDEuNzkyLTIuODE2IDEuMDg4LTEuNTM2IDIuMDQ4LTIuODh2LTEuMDg4aC0yLjk0NHYtMy4wNzJoMi45NDR2LTIuODhoMi45NDR2Mi44OGgyLjc1MnYzLjA3MmgtMi43NTJ2MS4wODhxLjg5NiAxLjM0NCAxLjg1NiAyLjgxNiAxLjAyNCAxLjQwOCAxLjc5MiAyLjc1Mi40NDgtLjMyLjg5Ni0uNTc2LjUxMi0uMjU2Ljk2LS41MTIgMy4zMjgtLjg5NiA3Ljc0NC0uNDQ4IDQuNDguNDQ4IDYuMTQ0IDEuMjE2IDEuNDcyLjcwNCA0LjAzMiAzLjA3MiAyLjU2IDIuMzY4IDMuNjQ4IDUuMjQ4Ljg5NiAyLjc1MiAxLjIxNiA0LjkyOC4zMiAyLjE3Ni4zMiAzLjUyLjEyOCAzLjItMS4yMTYgOC0uNzY4IDIuODgtMi4xMTIgNC45MjgtMS4yOCAyLjA0OC0zLjkwNCA0LjE2LTEuOTIgMS41MzYtMy41MiAyLjI0LTEuNi42NC0zLjEzNi44MzJ6bS0xNi4xMjgtLjMyLTEuNzI4IDEuNzI4cS0xLjI4IDEuMzQ0LTEuNDcyIDEuNTM2LjE5Mi4zODQgMS40NzIgMS43MjggMS4zNDQgMS4yOCAxLjcyOCAxLjQ3Mi4wNjQtLjE5MiAxLjM0NC0xLjQ3MmwxLjcyOC0xLjcyOHEtLjM4NC0uMTkyLTEuNzI4LTEuNTM2LTEuMjgtMS4zNDQtMS4zNDQtMS43Mjh6bTEuMjE2LTUuODI0cTEuNiAwIDQuMTYuMjU2dDMuODQuODMybDIuMDQ4IDEuMDI0cTEuMTUyLjU3NiAyLjMwNCAxLjI4IDEuNzI4LS4xMjggMy40NTYtLjU3NiAxLjc5Mi0uNTEyIDMuOTA0LTIuMjQgMy45MDQtMy4yNjQgNC45MjgtNy4zNiAxLjIxNi00LjU0NCAxLjA4OC03LjEwNCAwLTEuMjE2LS4yNTYtMy4xMzYtLjI1Ni0xLjkyLTEuMTUyLTQuMzUyLS44MzItMi4zMDQtMi44OC00LjE2LTIuMDQ4LTEuOTItMy4yNjQtMi42MjQtMS4zNDQtLjU3Ni00Ljk5Mi0uODk2LTMuNjQ4LS4zMi02LjUyOC40NDgtMi41Ni43NjgtMy45NjggNi4wMTYtMS4zNDQgNS4yNDgtMi42ODggMTEuMnptLTE2LjMyLS4xOTItMi4xNzYtLjg5NnEtMi4xMTItLjg5Ni0zLjAwOC0yLjMwNC0xLjM0NC0xLjI4LTIuNjI0LTQuMTYtMS4wODgtMi40MzItMS4yMTYtNi4zMzYtLjI1Ni0yLjA0OC41MTItNC43MzYuNzY4LTIuNjg4IDEuNi0zLjg0IDEuOTItMi42ODggNS44ODgtMy4zOTIgMi4wNDgtLjE5MiA0LjE2LS4wNjQgMi4xNzYuMDY0IDIuODguODMyLjM4NC40NDggMS4wMjQgMi40OTZ0MS4yOCA0LjQ4cS43MDQgMi40MzIgMS4yMTYgNC43MzYuNTEyIDIuMjQuNjQgMy4wNzIuMzIgMS43MjguMjU2IDMuNzEyLS4wNjQgMS45Mi0uMDY0IDMuNTJ6bTMwLjAxNi4zMi0xMC4zMDQtMi43NTJxMC0xLjYtLjEyOC0zLjUyLS4wNjQtMS45ODQuMzItMy45MDQuMDY0LS44MzIuNTc2LTMuMDcydDEuMTUyLTQuNjA4cS42NC0yLjQzMiAxLjI4LTQuNDE2LjcwNC0yLjA0OCAxLjA4OC0yLjQ5Ni43MDQtLjc2OCAyLjg4LS44OTYgMi4yNC0uMTkyIDQuMjI0LjEyOCA0LjA5Ni41MTIgNS44MjQgMy4zOTIuNzY4IDEuMTUyIDEuNTM2IDMuODQuODMyIDIuNjg4LjY0IDQuOC0uMTkyIDMuODQtMS4yMTYgNi4xNDQtLjUxMiAxLjQwOC0xLjM0NCAyLjU2LS44MzIgMS4xNTItMS4yOCAxLjcyOC0uOTYgMS4yOC0zLjEzNiAyLjE3NnptLTI3LjA3MiAxMS41Mi0uNTc2LTMuMDcyLTIuMTc2LjY0LS4xOTIgMy4zOTJ6bTIzLjU1Mi0uMTI4IDMuMDcyLjg5Ni0uMzItMy4yLTIuMTEyLS42NHoiLz48cGF0aCBkPSJtMTkuMjc3IDU3LjI4NnYtMS42MjZsMS4wNDMtLjI5Yy41NzMtLjE2IDEuMDYzLS4yNyAxLjA4OS0uMjQ0LjEzNy4xMzcuNTQ0IDIuNzY1LjQ0MyAyLjg2LS4wNjYuMDY0LS41Ny4yNi0xLjEyLjQzNi0uNTUuMTc3LTEuMTAzLjM2LTEuMjI4LjQwNi0uMTcuMDYzLS4yMjctLjMxOC0uMjI3LTEuNTQyem01LjAxOC0uMjUyYy0uMDQ0LS4xMzktLjEzLS43NTQtLjE5Mi0xLjM2Ni0uMDg5LS44ODYtLjA1Ny0xLjEzNi4xNTUtMS4yMTcuMTQ2LS4wNTYgMS4xNzItLjE2IDIuMjgtLjIzbDIuMDEyLS4xMjd2MS4zNzljMCAuNzU4LS4wNjMgMS40MTctLjE0IDEuNDY1LS4wNzguMDQ4LTEuMDE3LjE0NS0yLjA4OC4yMTctMS41ODMuMTA2LTEuOTYyLjA4NC0yLjAyNy0uMTIxem04LjE4Ny4wMDctMS40NDMtMS40NjggMS41MjUtMS41MzNjLjgzOS0uODQzIDEuNTY3LTEuNTEyIDEuNjItMS40ODYuMDUuMDI1Ljc0My43MjMgMS41MzggMS41NTFsMS40NDYgMS41MDUtMS40NDEgMS40NWMtLjc5My43OTctMS41MjMgMS40NS0xLjYyMiAxLjQ1LS4xIDAtLjgzLS42NjEtMS42MjMtMS40Njl6bTguMTEzLjA2Mi0uNzczLS4wN3YtMi45MzNsMS4zMTkuMTI0YTQ2Ljg4IDQ2Ljg4IDAgMCAxIDIuMDIuMjMyYy42OS4xMDUuNjk5LjExNy41OTIuNzYyLS4wNi4zNi0uMTEuOTYzLS4xMSAxLjMzOGwtLjAwMi42ODEtMS4xMzctLjAzMWEzOC41ODMgMzguNTgzIDAgMCAxIC0xLjkwOS0uMTAyem02LjM1NSAxLjE3OWMtLjk1My0uMjcxLTEuMjk5LS40NDctMS4yMy0uNjI2LjA1My0uMTM4LjE5My0uNzguMzEzLTEuNDI4LjE3LS45MjcuMjc4LTEuMTYuNTAzLTEuMDk2IDEuNzk4LjUxMSAxLjgzMi41MjkgMS44MzIuOTI1IDAgLjIyLjA1Mi45MDIuMTE3IDEuNTE2LjA2NS42MjUuMDQ1IDEuMTEtLjA0NiAxLjEwMi0uMDg5LS4wMDktLjc1OS0uMTg2LTEuNDg4LS4zOTN6bS0uOTQ2LTkuNTI4Yy0yLjkxNy0xLjY0Ny00LjQzOC0yLjA2LTguNTktMi4zMzlsLTEuOTU1LS4xMzF2LTExLjE5bC44MjQtMy41MmMyLjI5NC05LjggMy4yMzktMTIuMjgzIDUuMDcyLTEzLjMyNy45MDMtLjUxNSAxLjI1Mi0uNTk5IDMuNDA5LS44MjQgMS44NzItLjE5NSA1LjE2LjAxNCA3LjMyNi40NjUgMS42MTYuMzM3IDIuNzQ3IDEuMDg2IDQuOTE3IDMuMjU1IDEuODQ0IDEuODQ0IDIuNDg5IDIuOTY1IDMuMjUzIDUuNjU5IDEuMjIyIDQuMzEgMS4wNDEgOC45NDMtLjUzMyAxMy42NTItLjYzNiAxLjkwMy0xLjc4MyAzLjY4OC0zLjM5MiA1LjI4LTIuMTY4IDIuMTQ0LTMuNzU2IDMuMTE4LTUuODMgMy41NzctMi40MzQuNTM4LTIuNTk2LjUxOC00LjUtLjU1N3ptNC44MTEtMi44ODFjMi4xMDQtLjkxOSAyLjk2Ni0xLjU4IDQuMjMtMy4yNDggMS44OTgtMi41MDYgMi43ODgtNC45NCAzLjE0OC04LjYxMy4yMzYtMi40MS4wNTItNC4wMDYtLjc0My02LjQ0LS45NDUtMi44OS0yLjA3LTQuNTYtMy43MjQtNS41My0xLjcwOC0xLjAwMS01LjcyNC0xLjU4LTguMjQtMS4xODctMS42OTQuMjY0LTIuMzAxLjU4Mi0yLjczIDEuNDMtLjg4NyAxLjc0OC0zLjE5NiAxMC4yMjYtMy43NTQgMTMuNzgtLjE5NSAxLjI0Mi0uMjY4IDIuNzQxLS4yMzIgNC43OWwuMDUyIDIuOTggNC45MSAxLjMyNWMyLjcuNzI5IDUuMDcyIDEuMzMgNS4yNzIgMS4zMzVzMS4wMTUtLjI3NSAxLjgxMS0uNjIyem0tMzIuNjI5IDMuNTIzYy0uOTUtLjE5OS0yLjEzNi0uNTUtMi42MzYtLjc4LTEuOTQxLS44OTMtNS4wMDMtMy42OS02LjE2NC01LjYzLTEuMTQtMS45MDUtMi4xOC01Ljg4LTIuNDA3LTkuMjA0LS4xODktMi43NzUuNzA1LTcuNzQyIDEuNzc2LTkuODc3Ljg3OS0xLjc1IDMuMjM1LTQuMTcgNS4xODQtNS4zMjUgMi4wMTMtMS4xOTIgOC43Ny0xLjYzNyAxMS45MzQtLjc4NC4zOS4xMDUgMS4wNzQuNTI2IDEuNTIuOTM3IDEuNTE3IDEuMzk5IDIuMzM2IDMuNyA0LjIzOSAxMS45MmwuOTE4IDMuOTY0djExLjY5NGwtLjY4Mi4xMDRjLTQuMTAyLjYzLTguNzQ4IDEuODktMTAuODEyIDIuOTMzLS40NzIuMjM5LS45MjIuNDI4LTEgLjQyMS0uMDc5LS4wMDctLjkyLS4xNzUtMS44Ny0uMzczem02LjI0Ny00LjYwNGMyLjY4Ni0uNzQ0IDQuOTMtMS4zOTggNC45ODUtMS40NTQuMjEyLS4yMTIuMjU4LTQuODI5LjA2Mi02LjI4NS0uNDE2LTMuMDk3LTIuODk4LTEyLjY3OC0zLjg2NS0xNC45MjctLjMwNi0uNzEtLjUzNy0uOTU1LTEuMjIxLTEuMjkxLS43NjItLjM3NS0xLjEwMi0uNDE2LTMuNDgtLjQxNi0yLjkwNiAwLTMuOTkzLjE5NC01Ljc2OCAxLjAyOC0yLjM1IDEuMTAzLTMuNzUyIDMuMTI2LTQuNzAzIDYuNzkxLS40MzQgMS42NzMtLjQ2MyAyLjAxOC0uMzY3IDQuMzYyLjA2NiAxLjU5My4yNDMgMy4xMTQuNDczIDQuMDY1LjY4MyAyLjgyIDMuMTMzIDYuODAyIDQuODMgNy44NTEuOTc2LjYwMyAzLjc0IDEuNzkgMy45NjggMS43MDUuMTEyLS4wNDEgMi40LS42ODQgNS4wODYtMS40Mjl6bTkuNDk2LTE3LjM3NGMtLjM0Mi0xLjU5LTEuMjgyLTQuNjEzLTEuOTUtNi4yNzItLjUzLTEuMzE4LS43MDgtMS45OTUtLjY0OC0yLjQ2LjA5LS42OTQgMS4yMTktMi44MjkgMi4yNDItNC4yMzdsLjYzOC0uODc4LjU5Ljk3IDEuMTQ4IDEuODc3YzEuMDQ2IDEuNzA2IDEuMDc2IDIuMDM4LjM1MSAzLjg1Ny0uNTg5IDEuNDc4LTEuMzQ0IDQuMDM3LTEuOTc1IDYuNjg5bC0uMjYgMS4wOXoiIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg=='); } diff --git a/public/stylesheets/piece/chessnut.css b/public/stylesheets/piece/chessnut.css deleted file mode 100644 index 90f9f984fe..0000000000 --- a/public/stylesheets/piece/chessnut.css +++ /dev/null @@ -1,12 +0,0 @@ -body.base .is2d piece.pawn.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Im00OTcuOSAyNDBjMCA1My42LTQ0IDkzLjktOTguMSA5My45cy05OC4xLTQwLjMtOTguMS05My45IDQ0LTkzLjkgOTguMS05My45YzU0LjIuMSA5OC4xIDQwLjQgOTguMSA5My45em0yOC41IDk3LjZ2NTUuM2MtMzAuMiAzLTQyLjggMTIuMS00Mi44IDI4IDAgNTYuOSAzNiAxMjMuNCAxMDkuMSAxODcuOXY2MC45YzAgMTcuNC04Ny41IDMwLjgtMTkyLjcgMzAuOHMtMTkyLjctMTMuNC0xOTIuNy0zMC44bC0uMS02MC42YzczLjEtNjQuNSAxMDguMS0xMzEuMSAxMDguMS0xODggMC0xNS45LTEzLjYtMjUuMi00My44LTI4LjJ2LTU1LjN6IiBmaWxsPSIjZmZmIiBzdHJva2Utd2lkdGg9IjMwLjI0Ii8+PHBhdGggZD0ibTIwNy4yIDYwOGMwIDE3LjQgODcuNSAzMC4zIDE5Mi43IDMwLjNzMTkyLjYtMTIuOSAxOTIuNi0zMC4yIiBmaWxsPSJub25lIiBzdHJva2Utd2lkdGg9IjE2LjIiLz48cGF0aCBkPSJtMjcyLjYgMzg2LjdoMjUyLjciIGZpbGw9Im5vbmUiIHN0cm9rZS13aWR0aD0iMTQuMDQiLz48L2c+PC9zdmc+'); } -body.base .is2d piece.knight.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik02NDUuMjU0IDY5Mi4yVjI4MC42Yy01Ny4yLTQxLjgtMTQyLjMtODUuOC0xOTYuNi05OC4xLTQyLjYtOS43LTEwMS4zLTIuMS0xNDguNiAxMy4yLTEzLjMtMzQuOS00OC01OC42LTgxLjUtNjAuNCA2LjMgMjkuNiA1LjkgNzQuMyAyNC4zIDk3LjctNyAxNi4yLTMyLjEgNjkuNC00OC43IDExOS4zdjM5LjRjLTEzLjkgNTkuMS0zNC45IDE2Ni4yLTQzLjQgMjEyLjhsMTIwLjkgNTEuNSAyMi40LTU4LjFjMTUuMi0yMi43IDQ1LjctNjAuOSA2NS4xLTc4LjIgMjQuNC0xMC4zIDU1LjgtMjkuNCA2Ni42LTU5LjIgMTQtMzguNCA2LjMtODQuMy0xMC41LTExOS45IDMxIDMwLjIgNTAgNzcgNTAgMTI3LjggMCA2OC4xLTM4LjEgMTQ1LjktMTA0LjcgMjIzLjdoMjg0Ljd6IiBmaWxsPSIjZmZmIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS13aWR0aD0iMjkuMTYiLz48cGF0aCBkPSJNMTc5Ljc1NCA1NzQuOGMxOS40LTEwLjkgMzMuOSAzLjggMjIuNCAyNS4yeiIgc3Ryb2tlLXdpZHRoPSI5LjE2OSIvPjxwYXRoIGQ9Ik0yMzEuNDU0IDM1Ny45Yy02LjkgOS41LS42IDI5LjMgNiAzNC41IDQuNS0uNiAxNC4xLTQuNCAxOC42LThsMjEuNS0yNC45LTQuNS0zLjdjLTguOC0uMS0zMC43LS4xLTQxLjYgMi4xeiIgc3Ryb2tlLXdpZHRoPSIuOTUyIi8+PHBhdGggZD0iTTMyMC4wNTQgMTg2Yy0xMi41LTE3LjktOS45LTQ5LjcgNy03NS4xIDI4LjIgMTQuMyAzOS43IDQ3LjQgMzUuMSA3MC42IiBmaWxsPSIjZmZmIiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIiBzdHJva2Utd2lkdGg9IjIzLjc2Ii8+PC9nPjwvc3ZnPg=='); } -body.base .is2d piece.bishop.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIzOC45IDcwMS44Yy00MS44IDAtNzctMTQuOC0xMDEuOC00Mi44LTIyLjktMjUuOC0zNS41LTYyLjEtMzUuNS0xMDIuMiAwLTU4LjkgNDEuMS03Mi45IDc3LjEtNzguNWwxNS42LTIuNS00LjggMTVjLTYuNSAyMC41LTEwLjIgNDMtMTAuMiA2MS4zIDAgNTQuMyAyNC41IDg4LjEgNjQuMiA4OC4xIDI5LjUgMCA1Ny4yLTI0LjIgNzEuNC02MS4xLTMzLTYuNi00OS41LTE2LjQtNTAuMS0yOS45bC03LjMtNTUuN3YtLjVjMC05LjEgNS45LTE1LjMgMTMuMi0yMC4zLTEuNi00LjQtMy4zLTkuMS01LjEtMTMuOC0xNi42LTQ0LjktMzcuMy0xMDAuOC0zNy4zLTE0My42IDAtNTAuMiAyMi4xLTk1LjEgNjIuMy0xMjYuNSAyMi45LTMyIDY5LjItNjguNSAxMDUuMy05MC42bDUuMS0zLjEgNS4xIDMuMWMzNiAyMiA4Mi4zIDU4LjUgMTA1LjMgOTAuNyA0MC4yIDMxLjQgNjIuMyA3Ni4xIDYyLjMgMTI2IDAgNDMtMjAuNyA5OS40LTM3LjQgMTQ0LjYtMS43IDQuNS0zLjMgOS00LjkgMTMuMiA3LjIgNSAxMy4yIDExLjMgMTMuMiAyMC4zdi42bC03LjIgNTUuNWMtLjUgMTMuNS0xNyAyMy40LTUwIDI5LjkgMTQuMSAzNi45IDQxLjkgNjEuMSA3MS40IDYxLjEgMzkuNSAwIDY0LjItMzMuOCA2NC4yLTg4LjEgMC0xOC41LTMuNy00MC44LTEwLjItNjEuM2wtNC44LTE1IDE1LjYgMi41YzI1LjIgNCA0Mi42IDEwLjggNTQuOSAyMS42IDE0LjkgMTMuMSAyMi4yIDMxLjggMjIuMiA1Ni45IDAgNDAuMS0xMi42IDc2LjQtMzUuNSAxMDIuMi0yNC44IDI4LTU5LjkgNDIuOC0xMDEuOCA0Mi44LTY1LjQgMC0xMTguNi00NS4xLTEzNy40LTExNS44LTguMi4zLTE2LjUuNS0yNC44LjVzLTE2LjYtLjItMjQuOC0uNWMtMTkgNzAuOC03Mi4xIDExNS45LTEzNy41IDExNS45eiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik00MDEuMSAxMDYuNGMzMy41IDIwLjUgODAuNiA1Ni44IDEwMy4yIDg5LjNDNTQwLjIgMjIzLjIgNTY0IDI2NCA1NjQgMzE1YzAgNDguMy0yOC41IDExNy42LTQ0LjQgMTYxLjkgOS43IDUuNCAxNS4yIDEwLjIgMTUuMiAxNi4ybC03LjIgNTUuNGMwIDkuNS0yMSAxNy45LTUzLjEgMjMuMSAxMy4yIDQ0LjcgNDUuOSA3OC40IDg0LjIgNzguNCA0NS43IDAgNzMuOS0zOC45IDczLjktOTcuOCAwLTIwLTQtNDMuMy0xMC43LTY0LjMgNDEuNSA2LjYgNjguOSAyMS45IDY4LjkgNjguOSAwIDc1LTQ1LjYgMTM1LjItMTI3LjUgMTM1LjItNjIgMC0xMTMuNi00My42LTEyOS45LTExNi4xLTEwLjQuNi0yMS4yIDEtMzIuNCAxcy0yMi0uMy0zMi40LTFjLTE2LjIgNzIuNS02OCAxMTYuMS0xMzAgMTE2LjEtODIgMC0xMjcuNS02MC4zLTEyNy41LTEzNS4yIDAtNDcgMjcuNC02Mi40IDY4LjktNjguOS02LjYgMjEtMTAuNyA0NC40LTEwLjcgNjQuMyAwIDU5IDI4LjEgOTcuOCA3My45IDk3LjggMzguMyAwIDcxLjEtMzMuNyA4NC4yLTc4LjQtMzIuMi01LjItNTMuMS0xMy41LTUzLjEtMjNMMjY3IDQ5M2MwLTUuOSA1LjUtMTAuOCAxNS4yLTE2LjItMTUuOC00NC4zLTQ0LjQtMTEzLjMtNDQuNC0xNjEuNiAwLTUxIDIzLjktOTIuMiA1OS43LTExOS43IDIzLTMyLjQgNzAuMS02OC41IDEwMy42LTg5LjFtMC0yMi44bC0xMC4yIDYuM0MzNTcgMTEwLjYgMzA5LjEgMTQ3IDI4My42IDE4MmMtNDEuOSAzMy4zLTY1IDgwLjUtNjUgMTMzLjMgMCA0NC42IDIxIDEwMS4zIDM3LjggMTQ3IC45IDIuNSAxLjcgNC45IDIuNiA3LjEtNiA1LjUtMTEuMyAxMy4yLTExLjMgMjMuN3YxLjNsLjIgMS4zIDcuMSA1NC44Yy4zIDUuNSAyLjYgMTIuOSAxMC4zIDE5LjggNC4xIDMuNyA5LjQgNi44IDE2LjEgOS43IDUuNiAyLjQgMTIuMiA0LjUgMTkuOCA2LjUtNS4zIDEwLjctMTIgMjAuMS0xOS43IDI3LjQtOC4xIDcuOC0yMS4zIDE3LjEtMzguMSAxNy4xLTE2LjEgMC0yOS4xLTYuNC0zOC40LTE5LTEwLjQtMTMuOS0xNS45LTM0LjYtMTUuOS01OS40IDAtMTcuNSAzLjYtMzguOCA5LjctNTguNGw5LjQtMjkuOS0zMSA0LjljLTI3LjEgNC4zLTQ2IDExLjktNTkuNyAyMy45LTE3IDE0LjgtMjUuNSAzNi40LTI1LjUgNjQuMyAwIDIxIDMuMSA0MC44IDkuNSA1OS4xIDYuNSAxOC45IDE2LjEgMzUuNSAyOC41IDQ5LjYgMjYuNyAzMC4xIDY0LjQgNDYgMTA5LjEgNDYgNjcuNiAwIDEyMy00NC44IDE0NC42LTExNS41IDUuOC4yIDExLjcuMiAxNy42LjJzMTEuOC0uMSAxNy42LS4yYzIxLjcgNzAuNiA3NyAxMTUuNSAxNDQuNiAxMTUuNSA0NC43IDAgODIuNC0xNS45IDEwOS4xLTQ2IDEyLjQtMTQgMjItMzAuNyAyOC41LTQ5LjYgNi4zLTE4LjMgOS41LTM4LjEgOS41LTU5LjEgMC0yNy44LTguNS00OS41LTI1LjUtNjQuMy0xMy43LTEyLTMyLjctMTkuNy01OS43LTIzLjlsLTMxLTQuOSA5LjQgMjkuOWM2LjIgMTkuNyA5LjcgNDAuOSA5LjcgNTguNCAwIDI0LjgtNS41IDQ1LjUtMTUuOSA1OS40LTkuNCAxMi42LTIyLjQgMTktMzguNCAxOS0xNi44IDAtMzAtOS4zLTM4LjEtMTcuMS03LjctNy4zLTE0LjQtMTYuNy0xOS43LTI3LjUgNy42LTEuOSAxNC4xLTQuMSAxOS44LTYuNSA2LjctMi45IDEyLTYgMTYuMS05LjcgNy43LTYuOSA5LjgtMTQuMyAxMC4yLTE5LjhsNy4xLTU0LjUuMS0xLjN2LTEuNGMwLTEwLjUtNS4zLTE4LjEtMTEuMy0yMy43LjgtMi4yIDEuNi00LjMgMi40LTYuNSAxNy00NiAzOC0xMDMuMSAzOC0xNDggMC01Mi42LTIzLTk5LjctNjUtMTMyLjgtMTEuNC0xNS43LTI4LTMyLjYtNDkuNC01MC40LTE4LjItMTUuMi0zOC44LTMwLTU4LTQxLjh6Ii8+PGcgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik01MjcuOCA1NDguNWw3LjItNTUuN2MwLTE5LjctNTguOS0zNS4yLTEzMy45LTM1LjItNzUuMSAwLTEzMy45IDE1LjctMTMzLjkgMzUuMmw3LjIgNTUuNyIgZmlsbD0ibm9uZSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2Utd2lkdGg9IjE2LjkwNiIvPjxlbGxpcHNlIGN4PSI0MDEuMSIgY3k9IjU0OC41IiBmaWxsPSJub25lIiByeD0iMTI2LjciIHJ5PSIyOC40IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS13aWR0aD0iMTUuOTExIi8+PHBhdGggZD0iTTMzMy45IDUyNy4xYzAgNjQuNC00MC40IDEyMS45LTkwLjUgMTIxLjktNDUuNyAwLTczLjktMzguOS03My45LTk3LjggMC0yMCA0LTQzLjMgMTAuNy02NC4zLTQxLjUgNi42LTY4LjkgMjEuOS02OC45IDY4LjkgMCA3NSA0NS42IDEzNS4yIDEyNy41IDEzNS4yIDc0LjUgMCAxMzQuMi02My4yIDEzNS4yLTE2My42bTk0LjQtLjNjMCA2NC40IDQwLjQgMTIxLjkgOTAuNSAxMjEuOSA0NS43IDAgNzMuOS0zOC45IDczLjktOTcuOCAwLTIwLTQtNDMuMy0xMC43LTY0LjMgNDEuNSA2LjYgNjguOSAyMS45IDY4LjkgNjguOSAwIDc1LTQ1LjYgMTM1LjItMTI3LjUgMTM1LjItNzQuNSAwLTEzNC4yLTYzLjItMTM1LjItMTYzLjYiIGZpbGw9IiNmZmYiIHN0cm9rZS13aWR0aD0iMTguMzYiLz48ZyBmaWxsPSJub25lIj48cGF0aCBkPSJNNTE5LjggNDc2LjJjMTUuOC00NC43IDQ0LjQtMTEzLjMgNDQuNC0xNjEuNiAwLTUxLTIzLjktOTIuNC01OS43LTExOS45LTIyLjctMzIuNC02OS45LTY5LjItMTAzLjItODkuNy0zMy41IDIwLjUtODAuNiA1Ny4yLTEwMy4yIDg5LjctMzUuOSAyNy40LTU5LjcgNjguOC01OS43IDExOS44IDAgNDguMyAyOC42IDExNyA0NC40IDE2MS43IiBzdHJva2Utd2lkdGg9IjIwLjUyIi8+PHBhdGggZD0iTTQwMS4xIDIxMS4ydjE4NC43bS03MC4yLTk0aDE0MC40IiBzdHJva2Utd2lkdGg9IjE5LjQ0Ii8+PC9nPjwvZz48L3N2Zz4='); } -body.base .is2d piece.rook.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTQwMC40IDcwOC4zYy01Ny4xIDAtMTEwLjgtNS44LTE1MS4yLTE2LjUtNDUuNS0xMi02OC41LTI4LjQtNjguNS00OC42VjU4MmMwLTI4LjQgNDQuMS00Ni4yIDc0LjctNTUuM2w4LjEtMTcyLjRjLTMuMi0yLjYtNS42LTUuMy03LjMtOC4xbC0uMi0uMy0yNC43LTUyLjhjLTE5LjMtOS41LTE5LjMtMTktMTkuMy0yMi4yVjE0NS4zaDc0LjV2NTAuOGg0My4ydi01MC4zbDEzNy4yLjF2NTAuMkg1MTB2LTUwLjhoNzUuNnYxMjUuNGMwIDcuOC00LjIgMTQuNS0xMyAxOS45bC0yNCA1NS40LS40LjhjLTIuMSAzLjEtNSA2LTguNSA4LjZsNy42IDE3MC45YzIxLjEgNiAzOC44IDEzLjUgNTEuNSAyMS42IDE2LjUgMTAuNSAyNC44IDIxLjkgMjQuOCAzNC4xIDAgLjggMCAxLjYtLjEgMi41bC0uMSA1OC42YzAgMjAuMi0yMy40IDM2LjYtNjkuNiA0OC42LTQwLjkgMTAuNy05NS41IDE2LjYtMTUzLjQgMTYuNnoiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNNTc2IDE1NXYxMTUuN2MwIDQuNS0zLjIgOS0xMC45IDEzLjFsLTI0LjkgNTcuN2MtMi4yIDMuMi01LjYgNi4yLTEwLjQgOUw1MzggNTM0YzQ3LjIgMTIuNSA3NiAzMC44IDc2IDQ4LjIgMCAuNiAwIDEuMy0uMSAxLjlsLS4xIDU5LjNjMCAzMC42LTk1IDU1LjQtMjEzLjMgNTUuNC0xMTYuNiAwLTIxMC0yNC43LTIxMC01NS40di02MS4yYzAtMTcuMiAyOC4yLTM1LjMgNzQuNC00Ny44bDguNi0xODQuN2MtNC4xLTIuNi03LjItNS4zLTguOS04LjFsLTI2LTU1LjdjLTEwLjQtNC41LTE2LjgtOS42LTE2LjgtMTVWMTU1SDI3N3Y1MC44aDYyLjZ2LTUwLjNsMTE3LjcuMXY1MC4ySDUyMFYxNTV6bTE5LjUtMTkuNGgtOTUuMXY1MC43aC0yMy44di01MC4yaC0xOS40bC0xMTcuNS0uMUgzMjB2NTAuM2gtMjMuOHYtNTAuN2gtOTMuOXYxMzUuMWMwIDE1LjQgMTIuNSAyNC42IDIxLjYgMjkuNWwyMy4xIDQ5LjQuMy44LjQuOGMxLjUgMi42IDMuNSA1LjEgNS44IDcuNWwtNy42IDE2MC44Yy0xOC43IDUuOS0zNC4yIDEyLjktNDYuMiAyMC41LTguMyA1LjMtMTQuOSAxMS4xLTE5LjUgMTcuMS02LjIgNy45LTkuMyAxNi4yLTkuMyAyNC45djYxLjNjMCAxOC4zIDEzLjkgMzAuOCAyNS41IDM4IDEyLjIgNy43IDI5LjEgMTQuNCA1MC4yIDIwIDQxLjEgMTAuOSA5NS43IDE2LjggMTUzLjcgMTYuOCA1OC44IDAgMTE0LTUuOSAxNTUuOC0xNi44IDIxLjQtNS42IDM4LjYtMTIuMyA1MC45LTE5LjkgMTEuOS03LjMgMjUuOS0xOS45IDI1LjktMzguMWwuMS01OC4yYy4xLTEuMS4xLTIuMS4xLTMgMC04LjctMy4xLTE3LjMtOS40LTI1LjItNC44LTYtMTEuNC0xMS44LTE5LjktMTcuMi0xMi4zLTcuOC0yOC4yLTE0LjctNDcuMy0yMC42bC03LTE1OS4xYzIuNy0yLjQgNS01IDYuOC03LjhsMS0xLjQuNi0xLjYgMjIuNS01Mi4xYzEyLjMtOC43IDE0LjktMTguOSAxNC45LTI2LjRWMTM1LjZ6Ii8+PGcgZmlsbD0iI2ZmZiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik0xOTEgNTgxLjZ2NjEuNmMwIDMwLjYgOTMuMSA1NS40IDIwOS42IDU1LjQgMTE4LjMgMCAyMTMuMi0yNC44IDIxMy4yLTU1LjRsLS4zLTYxLjMiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxOC4zNiIvPjxwYXRoIGQ9Ik02MTMuOSA1ODJjMCAzMC42LTk0LjUgNTUuNC0yMTEuMSA1NS40UzE5MS43IDYxMi42IDE5MS43IDU4MnM4Ny41LTY0IDIxMS4xLTY0YzEyMS42LS4xIDIxMS4xIDMzLjMgMjExLjEgNjR6IiBzdHJva2Utd2lkdGg9IjIxLjYiLz48cGF0aCBkPSJNMjc1LjggMjYwLjlsLTEwLjUgMjgwLjZjMCAxOS43IDYyLjEgMzQuMSAxMzYuOCAzNC4xIDc0LjggMCAxMzYuMS0xNC40IDEzNi4xLTMzLjlsLTE0LjktMjgwLjh6IiBzdHJva2Utd2lkdGg9IjE1LjEyIi8+PHBhdGggZD0iTTIzMS4zIDI2OC4xbDMzLjggNzMuMWM5LjUgMTYuNSA2MS42IDI4LjUgMTM3LjYgMjguNXMxMjYuNC0xMS43IDEzNy42LTI4LjVsMzIuOC03My4xIiBzdHJva2Utd2lkdGg9IjE1LjEyIi8+PHBhdGggZD0iTTUyMiAxNTR2NTAuOGgtNjMuN3YtNDkuMWwtMTE2LjYtLjF2NDkuMkgyNzhWMTU0aC01NS4xdjExNi43YzAgMjAuMSA4My4xIDM2LjQgMTc4LjUgMzYuNCA5NS41IDAgMTc2LjgtMTYuMyAxNzYuOC0zNi40VjE1NHoiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMTkuNDQiLz48L2c+PC9zdmc+'); } -body.base .is2d piece.queen.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgZmlsbD0iI2ZmZiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxwYXRoIGQ9Ik00MDEuMSA3MDQuNGMtNjIgMC0xMjAuNS01LjUtMTY0LjgtMTUuNC00OS42LTExLjEtNzQuMS0yNS44LTc1LTQ0LjdsLTEwLjItNTR2LS45YzAtNS40IDEuNi0xMy4yIDguNi0yMS40LTgtNDYuNS0yNS45LTEyNS4yLTQ0LjYtMTk1LjUtMTguNC02LjktMzAuOC0yNC41LTMwLjgtNDQuNiAwLTI2LjQgMjEuNC00Ny43IDQ3LjctNDcuN3M0Ny43IDIxLjQgNDcuNyA0Ny43YzAgMTEuMS0zLjcgMjEuNS0xMC42IDI5LjlDMTkwLjIgNDI0LjkgMjE2IDQ5NC41IDIzNCA1MzNsNS4zLTEuM2MtLjUtNTUuMy05LjEtMTY0LjMtMjAuNi0yNjEuNi0xOC42LTgtMzEtMjYuNi0zMS00Ny4xIDAtMjguMyAyMy01MS4zIDUxLjMtNTEuM3M1MS4zIDIzIDUxLjMgNTEuM2MwIDEzLjgtNS40IDI2LjctMTUgMzYuMyAxNy45IDkzLjUgNDcuNyAyMTEuNiA2NS4zIDI1OC45bDUuNC0uM2M4LjYtNjYgMTkuNC0xODQuNSAyNC42LTI5NC41LTE0LjktMTAtMjMuOC0yNi42LTIzLjgtNDQuNiAwLTI5LjggMjQuMi01NCA1NC01NHM1NCAyNC4yIDU0IDU0YzAgMTgtOC45IDM0LjYtMjMuNSA0NC42IDUuMiAxMTAuMSAxNiAyMjguNSAyNC42IDI5NC41bDUuNC4zYzE3LjYtNDcuMyA0Ny40LTE2NS4zIDY1LjMtMjU4LjktOS42LTkuNi0xNS0yMi41LTE1LTM2LjMgMC0yOC4zIDIzLTUxLjMgNTEuMy01MS4zczUxLjMgMjMgNTEuMyA1MS4zYzAgMjAuNi0xMi40IDM5LjEtMzEgNDcuMS0xMS42IDk3LjMtMjAuMiAyMDYuMy0yMC42IDI2MS42bDUuMyAxLjNjMTgtMzguNCA0My44LTEwOC4xIDY0LjktMTc1LjItNi45LTguNC0xMC42LTE4LjktMTAuNi0yOS45IDAtMjYuNCAyMS40LTQ3LjcgNDcuNy00Ny43czQ3LjcgMjEuNCA0Ny43IDQ3LjdjMCAyMC4xLTEyLjQgMzcuNy0zMC44IDQ0LjYtMTguNyA3MC4zLTM2LjUgMTQ4LjktNDQuNiAxOTUuNSA1LjcgNi43IDguNiAxMy44IDguNiAyMS4zdi45bC0xMC4zIDU0LjNjLTEuMiAxOC45LTI1LjcgMzMuNS03NSA0NC42LTQzLjggOS44LTEwMi4zIDE1LjMtMTY0LjQgMTUuM3ptLTE4OS40LTkwLjdjMS40IDMgMTMuNyAxMi40IDU0LjYgMjAuMyAzNi41IDcgODQuMiAxMSAxMzQuNiAxMSA1MC4zIDAgOTguMi0zLjkgMTM0LjYtMTEgNDAuOS04IDUzLjQtMTcuMyA1NC42LTIwLjMtMS40LTMtMTMuNy0xMi40LTU0LjYtMjAuMy0zNi41LTctODQuMi0xMS0xMzQuNi0xMS01MC4zIDAtOTguMiAzLjktMTM0LjYgMTEtNDAuOCA3LjktNTMuMSAxNy4zLTU0LjYgMjAuM3oiIHN0cm9rZS13aWR0aD0iMjAuNTIiLz48cGF0aCBkPSJNNTkyLjkgNjA3LjZjLTQxLjggMTMuOC0xMTIuMyAyMy4yLTE5MS44IDIzLjItODAuNCAwLTE0OC45LTkuNS0xOTAuNi0yMy41QzE5NyA2MTAuOCAxNzEgNjI4LjQgMTcxIDY0M2MwIDI4LjUgMTAzIDUxLjYgMjMwIDUxLjZzMjMwLTIzLjEgMjMwLTUxLjZjLjEtMTQuMi0yNC40LTMxLjctMzguMS0zNS40eiIgc3Ryb2tlLXdpZHRoPSIxNi4yIi8+PHBhdGggZD0iTTQwMS4xIDU5MS40YzEyNy4xIDAgMjMwLjEgMjMuMSAyMzAuMSA1MS42bDEwLjItNjAuM2MwLTYuMy0zLjItMTIuMy05LjQtMTguMSA3LjUtNDQuOSAyNi4xLTEyMS45IDQ3LTE5OS45IDE2LjYtNCAyOS4xLTE5IDI5LjEtMzYuOSAwLTIxLTE3LTM4LTM4LTM4LTIxLjEgMC0zOCAxNy0zOCAzOCAwIDEwLjggNC41IDIwLjYgMTEuOCAyNy41LTIwLjggNjctNTAuMSAxNDEuNC03MC40IDE4Mi40bC0yMC40LTQuOWMtLjMtNTQuMiA5LjItMTY3LjggMjEuNS0yNjkuOSAxNy40LTUgMzAuMi0yMSAzMC4yLTQwIDAtMjMtMTguNi00MS42LTQxLjYtNDEuNlM1MjEuNSAyMDAgNTIxLjUgMjIzYzAgMTMuMyA2LjMgMjUuMSAxNS45IDMyLjctMTggOTUuOC01MS4yIDIyMS40LTY5LjQgMjY2LjFsLTIwLjQtMS4zYy05LjEtNjYuNS0yMC44LTE4OC42LTI2LTMwMi42IDE0LjEtNy41IDIzLjgtMjIuMSAyMy44LTM5LjIgMC0yNC40LTE5LjktNDQuMy00NC4zLTQ0LjNzLTQ0LjMgMTkuOS00NC4zIDQ0LjNjMCAxNy4xIDkuNiAzMS45IDIzLjggMzkuMi01LjEgMTE0LTE2LjggMjM2LjEtMjYgMzAyLjZsLTIwLjQgMS4zYy0xOC4xLTQ0LjctNTEuNC0xNzAuMy02OS40LTI2Ni4xIDkuNy03LjYgMTUuOS0xOS40IDE1LjktMzIuNyAwLTIzLTE4LjYtNDEuNi00MS42LTQxLjZTMTk3LjMgMjAwIDE5Ny4zIDIyM2MwIDE5IDEyLjcgMzUgMzAuMiA0MCAxMi4zIDEwMiAyMS44IDIxNS41IDIxLjUgMjY5LjhsLTIwLjQgNC45Yy0yMC4zLTQxLjEtNDkuNy0xMTUuNS03MC40LTE4Mi40IDcuMi02LjkgMTEuOC0xNi42IDExLjgtMjcuNSAwLTIxLTE3LTM4LTM4LTM4LTIxLjEgMC0zOCAxNy0zOCAzOCAwIDE3LjkgMTIuNCAzMi45IDI5LjEgMzYuOSAyMC44IDc4IDM5LjUgMTU1IDQ3IDE5OS45LTYgNS43LTkuNCAxMS44LTkuNCAxOC4xbDEwLjIgNjAuM2MwLTI4LjUgMTAzLjEtNTEuNiAyMzAuMi01MS42eiIgc3Ryb2tlLXdpZHRoPSIxNy4yOCIvPjwvZz48Y2lyY2xlIGN4PSI0MDEuMSIgY3k9IjExMi45IiByPSIyNS45Ii8+PGNpcmNsZSBjeD0iMjI2LjEiIGN5PSIxNjQuOCIgcj0iMjMiLz48Y2lyY2xlIGN4PSIxMTQuOSIgY3k9IjI3My44IiByPSIyMi40Ii8+PGNpcmNsZSBjeD0iNTc2IiBjeT0iMTY0LjgiIHI9IjIzIi8+PGNpcmNsZSBjeD0iNjg4LjQiIGN5PSIyNzMuOCIgcj0iMjIuNCIvPjwvc3ZnPg=='); } -body.base .is2d piece.king.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTQwNS4zIDcwMGMtNTkuOCAwLTExNi4xLTUuMy0xNTguNy0xNC44LTQ3LjQtMTAuNi03MS4xLTI0LjYtNzIuMS00Mi44TDE1OC4xIDU3NnYtMS4xYzAtOS4xIDUuMi0xOCAxNS4yLTI2LjUtNi4yLTIxLjktMjEuNi00NS41LTM2LjYtNjguNC0xOC40LTI4LTM1LjctNTQuNC0zNS43LTc3LjcgMC0yNS41IDE4LjQtNDEuNCA0Ny44LTQxLjRoMS4zYzIuMiAwIDQuNS4xIDcgLjEgNiAuMSAxMi45LjIgMTkuMy4yLTUuNC0yNi43LTMuOC00NS45IDUtNTkuOSAxMy4zLTIxLjUgMzYuOS0yNCA1My42LTI0IDE0LjEgMCAyOS44IDIuMSA0Ni40IDQuNCAxLjgtMTYuMyA3LjUtMjguNSAxNy4yLTM2LjkgNy44LTYuOCAxNy0xMC4zIDI3LTEwLjMgMjEuMyAwIDQyLjIgMTQuOSA2MC44IDI4IDcgNSAxMy42IDkuNyAxOSAxMi41IDUuNC0yLjkgMTIuMS03LjYgMTktMTIuNSAxOC41LTEzLjEgMzkuNS0yOCA2MC43LTI4IDEwLjIgMCAxOS4yIDMuNSAyNyAxMC4zIDkuNiA4LjQgMTUuMyAyMC41IDE3LjEgMzYuOSAxNi42LTIuMyAzMi4zLTQuNCA0Ni40LTQuNCAxNi42IDAgNDAuMyAyLjUgNTMuNiAyNCA4LjYgMTQgMTAuMyAzMy4zIDQuOSA2MCA2LjYgMCAxMy42LS4xIDE5LjgtLjIgMi4zIDAgNC40LS4xIDYuNS0uMWgxLjNjMjkuNSAwIDQ3LjEgMTUuNCA0Ny4xIDQxLjQgMCAyMy4yLTE3LjYgNDkuNy0zNi4zIDc3LjctMTUuMiAyMi44LTMwLjggNDYuMy0zNyA2OC4xIDEwLjcgOC4yIDE2LjEgMTcuMyAxNi4xIDI2Ljh2MS4xbC0xNS44IDY3LjJjLTEuNiAxNy45LTI1LjUgMzEuOS03Mi44IDQyLjMtNDIuMyA5LjItOTguNCAxNC40LTE1Ny43IDE0LjR6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTMyNS42IDI0My44YzI4LjIgMCA2MC40IDMzLjYgNzkuOCA0MS41IDE5LjQtOCA1MS42LTQxLjUgNzkuOC00MS41IDcuMyAwIDE0LjUgMi4zIDIxLjEgOCAxMC4yIDguOSAxNC4zIDIyLjkgMTQuNiA0MC40IDIwLTIuOCAzOC44LTUuNyA1NS01LjcgMjAuMiAwIDM2LjQgNC41IDQ1LjggMTkuN3M3LjkgMzggMS4yIDY0LjNjMi41IDAgNS4xLjEgNy44LjEgMTAuMyAwIDIxLjctLjIgMzAuMS0uM2gxLjJjMjEuNCAwIDM3LjkgOS4yIDM3LjkgMzIuMiAwIDM5LjEtNjAuOSA5NS43LTczLjkgMTQ2Ljd2My4zYzEwLjggNi45IDE2LjUgMTQuNSAxNi41IDIyLjVsLTE1LjYgNjYuOWMtMS4zIDI3LjItMTAwIDQ5LjEtMjIxLjUgNDkuMS0xMjIuMyAwLTIyMS41LTIyLjItMjIxLjUtNDkuN0wxNjcuNiA1NzVjMC03LjkgNS44LTE1LjYgMTUuNi0yMi41di0zLjZjLTExLjktNTEtNzIuOC0xMDcuNi03Mi44LTE0Ni43IDAtMjMgMTcuMy0zMi4yIDM4LjctMzIuMmgxLjJjOC41LjEgMjAuMy40IDMwLjYuNCAyLjYgMCA1LjEgMCA3LjUtLjEtNi43LTI2LjQtOC4xLTQ5LjEgMS4zLTY0LjMgOS40LTE1LjEgMjUuNS0xOS43IDQ1LjgtMTkuNyAxNi4yIDAgMzUgMi45IDU1IDUuNy4zLTE3LjUgNC40LTMxLjYgMTQuNi00MC40IDYtNS41IDEzLjEtNy44IDIwLjUtNy44bTAtMTguM2MtMTIuNCAwLTIzLjUgNC4yLTMzIDEyLjUtOS40IDguMS0xNS42IDE5LjMtMTguNyAzMy41LTEzLjctMS44LTI2LjctMy4yLTM4LjktMy4yLTEzLjMgMC0yNC4zIDEuNy0zMy43IDUuNC0xMS45IDQuNi0yMS4yIDEyLjMtMjcuOCAyMi45LTguNiAxNC0xMS4zIDMyLTguMSA1NS41LTIuOCAwLTUuNi0uMS04LjItLjEtMi41IDAtNC45LS4xLTctLjFoLTEuNGMtMTUuMiAwLTI4LjUgMy44LTM4LjIgMTEtOC41IDYuNC0xOC44IDE4LjQtMTguOCAzOS40IDAgMjYgMTguMSA1My42IDM3LjMgODIuNyAxMy40IDIwLjQgMjcuMyA0MS40IDM0IDYwLjUtOS4yIDkuMi0xMy42IDE5LTEzLjYgMjkuNHYyLjNsLjMgMi4yIDE1LjggNjQuNmMxLjEgMTIuOSAxMC4yIDI0IDI3IDMyLjggMTIuNiA2LjcgMzAuMSAxMi41IDUyLjEgMTcuNSA0My4xIDkuNiAxMDAuMiAxNSAxNjAuNiAxNSA2MCAwIDExNi43LTUuMyAxNTkuNy0xNC44IDIxLjgtNC45IDM5LjQtMTAuNyA1Mi4xLTE3LjMgMTctOC45IDI2LjQtMTkuOCAyNy44LTMyLjVsMTUuMS02NS42LjMtMi4xdi0yLjJjMC0xMC44LTQuOC0yMC43LTE0LjQtMjkuOCA2LjgtMTkgMjAuNy0zOS45IDM0LjItNjAgMTkuNC0yOS4yIDM3LjgtNTYuNyAzNy44LTgyLjcgMC0yMS4xLTkuOC0zMy0xOC4xLTM5LjMtOS44LTcuNS0yMi42LTExLjItMzgtMTEuMmgtMS40Yy0yLjEgMC00LjIuMS02LjUuMS0yLjggMC01LjcuMS04LjcuMSAzLjMtMjMuNS42LTQxLjYtOC01NS41LTYuNi0xMC42LTE1LjktMTguMy0yNy44LTIyLjktOS4zLTMuNy0yMC4zLTUuNC0zMy42LTUuNC0xMi4yIDAtMjUuMiAxLjQtMzguOSAzLjItMy4xLTE0LjEtOS4zLTI1LjQtMTguNy0zMy41LTkuNS04LjMtMjAuNi0xMi41LTMzLTEyLjUtMjQuMiAwLTQ3LjQgMTYuNC02Ni4xIDI5LjctNC44IDMuMy05LjYgNi44LTEzLjcgOS40LTQuMS0yLjYtOS02LTEzLjctOS40LTE4LjctMTMuMi00MS45LTI5LjYtNjYuMS0yOS42eiIvPjxnIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIj48ZyBmaWxsPSJub25lIiBzdHJva2UtbGluZWNhcD0icm91bmQiPjxnIHN0cm9rZS13aWR0aD0iMTguMzYiPjxwYXRoIGQ9Ik0xODcuNCAzNzAuNGMtMTEuOS4zLTI1LjktLjEtMzcuNS0uMy0yMS45LS4zLTM5LjQgOC43LTM5LjQgMzIuMiAwIDM5LjEgNjAuNiA5NS43IDczLjMgMTQ2LjciLz48cGF0aCBkPSJNMjg5LjUgMjkyLjRjLTQ1LjYtNi4zLTgzLjMtMTMuOC0xMDAuMyAxMy43LTI3IDQzLjYgMzUuNiAxNTAuNyA1NS4xIDIyMi40Ii8+PHBhdGggZD0iTTQwNC4zIDI4NS43Yy0yNC4zLTktNjcuOS02MS43LTk5LjgtMzMuOS00My42IDM3LjkgMjIuOSAxNzMuOSAzOC4xIDI2MC41bTI4MC43LTE0MS45YzExLjkuMyAyNS45LS4xIDM3LjUtLjMgMjEuOS0uMyAzOS40IDguNyAzOS40IDMyLjIgMCAzOS4xLTYwLjYgOTUuNy03My4zIDE0Ni43Ii8+PHBhdGggZD0iTTUyMS4zIDI5Mi40YzQ1LjYtNi4zIDgzLjMtMTMuOCAxMDAuMyAxMy43IDI3IDQzLjYtMzUuNiAxNTAuNy01NS4xIDIyMi40Ii8+PHBhdGggZD0iTTQwNi41IDI4NS43YzI0LjMtOSA2Ny45LTYxLjcgOTkuOC0zMy45IDQzLjYgMzcuOS0yMi45IDE3My45LTM4LjEgMjYwLjUiLz48L2c+PHBhdGggZD0iTTQwNS40IDI3MS43djE4NC41IiBzdHJva2Utd2lkdGg9IjE1LjEyIi8+PC9nPjxwYXRoIGQ9Ik02MzIuOSA1NTIuNWwyNy44LTY4LjhjLTExLjEgMTQuNi0yNC44IDE2LjgtMzMuOSAxNC4zLTI3LTgtMjYuNS00MC42LTI0LjQtNjYuNS0xNi40IDI5LjUtMzkuMyA0NC43LTYzLjkgMzkuNS0yNC45LTUuMy00MC00MC41LTM5LTY4LjYtMTcuNSAzNS42LTQ5LjQgNTQuMS05NC4xIDU0LjFzLTc2LjYtMTguNS05NC4xLTU0LjFjMS4xIDI4LjEtMTQgNjMuMy0zOSA2OC42LTI0LjYgNS4yLTQ3LjQtMTAtNjMuOS0zOS41IDEuOSAyNS45IDIuNiA1OC41LTI0LjQgNjYuNS05LjEgMi43LTIyLjkuMy0zMy45LTE0LjNsMjcuOCA2OC44IiBmaWxsPSIjZmZmIiBzdHJva2Utd2lkdGg9IjE4LjM2Ii8+PGcgZmlsbD0ibm9uZSI+PGcgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2Utd2lkdGg9IjIxLjYiPjxwYXRoIGQ9Ik0xNjcuOSA1NzQuOGMwLTM0LjMgMTA2LjMtNjEuNyAyMzcuNC02MS43czIzNy40IDI3LjMgMjM3LjQgNjEuN20tNDc1IDEuOWwxNi4yIDY1bTQ1OS4yLTY1bC0xNi4yIDY1Ii8+PGVsbGlwc2UgY3g9IjQwNS40IiBjeT0iNjQxLjEiIHJ4PSIyMjEuNCIgcnk9IjQ5LjciLz48L2c+PHBhdGggZD0iTTQwNC4zIDk0LjZ2MTg5bS02MS41LTEyNC4ySDQ2OCIgc3Ryb2tlLXdpZHRoPSIzMC4yNCIvPjwvZz48L2c+PC9zdmc+'); } -body.base .is2d piece.pawn.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTQ4OS4zIDQxOC4zYy4xLTE3IDEyLTI1LjEgNjUuMS0yOS45di01OC40aC05MC43YzMyLTE5LjUgNTIuOC01My41IDUyLjgtOTIuOSAwLTYxLjktNTEuMy0xMTAuNC0xMTYuNy0xMTAuNHMtMTE2LjcgNDguNS0xMTYuNyAxMTAuNGMwIDM5LjQgMjAuNyA3My4zIDUyLjggOTIuOWgtOTEuNHY1OC40YzUzLjcgNC44IDY1LjIgMTIuOSA2NS4yIDI5LjggMCA2MC43LTM3LjYgMTMxLjUtMTE1LjUgMjAwLjFsLjEgNjRjMCAxOC42IDkzLjIgMzIgMjA1LjMgMzJzMjA1LjQtMTMuNSAyMDUuNC0zMmwgLjEtNjRjLTc3LjktNjguNS0xMTUuOC0xMzkuNC0xMTUuOC0yMDB6Ii8+PHBhdGggZD0ibTIzMi4xIDYyNy4yYzAgMTMuNyA3NiAyNS43IDE2Ny42IDI1LjcgOTEuNSAwIDE2Ny40LTExIDE2Ny40LTI0LjYiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2YyZjJmMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iMTkuNDQiLz48cGF0aCBkPSJtNDAwLjkgMTUwLjNjLTI0LS4yLTQ3LjYgOC42LTY2LjMgMjcuMy0yNi43IDI2LjgtMzIuNSA2My4yLTIwIDk1LjMiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2YyZjJmMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iMTYuMiIvPjwvc3ZnPg=='); } -body.base .is2d piece.knight.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTEzNy44IDYwNS45YzgtNDMgMjguOS0xNTEgNDMuMy0yMTJ2LTQwbC41LTEuNmMxMy45LTQxLjkgMzMuNi04NS41IDQ0LjEtMTA5IDEtMi4yIDEuOC00IDIuNi01LjctMTEuOS0xOS0xNS4yLTQ1LjctMTguNC02OS40LTEuMy05LjktMi41LTE5LjMtNC4yLTI3LjNsLTIuOS0xMy43IDE0IC44YzMzLjcgMS43IDY2LjEgMjIuNCA4My42IDUxLjktNS45LTIxLjYtLjktNDkuNCAxNC40LTcyLjFsNS44LTguNyA5LjQgNC44YzI3LjUgMTMuOSA0MS44IDQzLjIgNDIuNiA2OC43IDEwLjctMS4xIDIxLjItMS42IDMxLjEtMS42IDE2LjcgMCAzMiAxLjUgNDUuMyA0LjUgNTMgMTIgMTM5LjQgNTUgMjAwLjkgOTkuOWw0LjQgMy4ydjQyOC4zSDMzNC44TDM1MCA2ODljNjYuNy03OC4xIDEwMi4xLTE1MyAxMDIuMS0yMTYuOSAwLTIyLTMuOS00My43LTExLjEtNjMuNSAxLjQgMjEuMS0xIDQxLjMtNy41IDU5LjEtMTIuNiAzNC45LTQ5LjEgNTUuMy03MC44IDY0LjctMTcuNyAxNi4yLTQ2IDUxLjItNjEuMyA3NGwtMjUuOSA2Ny40LTEzOS4xLTU5LjN6Ii8+PHBhdGggZD0iTTE3Ny40IDU3OC4xYzE5LjQtMTAuOSAzMy45IDMuOCAyMi40IDI1LjJ6bTUxLjYtMjE3Yy02LjkgOS41LS42IDI5LjMgNiAzNC41IDQuNS0uNiAxNC4xLTQuNCAxOC42LThsMjEuNS0yNC45LTQuNS0zLjdjLTguNy0uMS0zMC43LS4xLTQxLjYgMi4xem05MC44LTE2MC44bC42LTIuOWMzMS4xLTUuMSA3My02IDk3LjMtNiA0NS43IDAgMTQ4IDU4LjggMjA5LjUgMTA0LjF2NTUuMWMtNDUtNDMuNS0xNDEuMi0xMTguOC0xOTYuMy0xMzUuOC0zNy4yLTExLjUtNzQuMS0xNS43LTExMS4xLTE0LjV6IiBmaWxsPSIjZjJmMmYyIi8+PC9zdmc+'); } -body.base .is2d piece.bishop.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIzNy44IDcwMi40Yy00MiAwLTc3LjMtMTQuOS0xMDIuMi00My0yMy0yNS45LTM1LjYtNjIuMy0zNS42LTEwMi41IDAtNTkuMiA0MS41LTczLjMgNzcuNS03OS4xbDE2LjQtMi42LTUgMTUuOGMtNi41IDIwLjUtMTAuMiA0Mi45LTEwLjIgNjEuMiAwIDU0IDI0LjQgODcuNiA2My42IDg3LjYgMjkuMiAwIDU2LjYtMjMuOCA3MC43LTYwLjItMTEuOC0yLjQtMjEuNS01LjItMjkuMS04LjQtMTMuNC01LjYtMjAuMS0xMy0yMC41LTIxLjhsLTctNTUuN3YtLjZjMC05LjEgNS42LTE1LjYgMTIuOS0yMC41LTEuNi00LjMtMy4zLTguOS01LjEtMTMuNS0xNi42LTQ0LjktMzcuMy0xMDAuOS0zNy4zLTE0My43IDAtNTAuNCAyMi4xLTk1LjQgNjIuNC0xMjYuOSAxMC45LTE1LjMgMjcuMi0zMiA0OC41LTQ5LjcgMTcuOC0xNC44IDM4LTI5LjMgNTYuOS00MC45bDUuNC0zLjIgNS40IDMuMmMzNi4xIDIyLjEgODIuNCA1OC42IDEwNS40IDkwLjcgNDAuMyAzMS41IDYyLjUgNzYuNCA2Mi41IDEyNi41IDAgNDMuMS0yMC43IDk5LjUtMzcuNSAxNDQuNy0xLjYgNC40LTIuOSA4LjYtNC40IDEyLjcgNy4yIDUgMTMuMyAxMS40IDEzLjMgMjAuNXYuNmwtNy42IDU1LjZjLS42IDEzLjctMTcuMSAyMy43LTUwIDMwLjMgMTQuMSAzNi40IDQxLjUgNjAuMiA3MC42IDYwLjIgMzkuMiAwIDYzLjUtMzMuNiA2My41LTg3LjYgMC0xOC40LTMuNy00MC43LTEwLjItNjEuMmwtNS0xNS44IDE2LjMgMi42YzI1LjMgNCA0Mi44IDEwLjkgNTUuMiAyMS43IDE1IDEzLjIgMjIuNCAzMiAyMi40IDU3LjMgMCA0MC4yLTEyLjYgNzYuNi0zNS42IDEwMi41LTI0LjggMjguMS02MC4zIDQzLTEwMi4yIDQzLTY1LjYgMC0xMTguOC00NS4xLTEzNy44LTExNS43LTggLjMtMTYuMi41LTI0LjQuNXMtMTYuNC0uMi0yNC40LS41Yy0xOC45IDcwLjctNzIuMyAxMTUuOS0xMzcuOCAxMTUuOXoiLz48cGF0aCBkPSJNNDAwIDEwNi41YzMzLjUgMjAuNSA4MC42IDU2LjcgMTAzLjIgODkuMkM1MzkuMSAyMjMuMiA1NjMgMjY0IDU2MyAzMTVjMCA0OC4zLTI4LjUgMTE3LjYtNDQuNCAxNjEuOSA5LjcgNS40IDE1LjIgMTAuMiAxNS4yIDE2LjJsLTcuMiA1NS40YzAgOS41LTIxIDE3LjktNTMuMSAyMy4xIDEzLjIgNDQuNyA0NS45IDc4LjQgODQuMiA3OC40IDQ1LjcgMCA3My45LTM4LjkgNzMuOS05Ny44IDAtMjAtNC00My4zLTEwLjctNjQuMyA0MS41IDYuNiA2OC45IDIxLjkgNjguOSA2OC45IDAgNzUtNDUuNiAxMzUuMi0xMjcuNSAxMzUuMi02MiAwLTExMy42LTQzLjYtMTI5LjktMTE2LjEtMTAuNC42LTIxLjIgMS0zMi40IDFzLTIyLS4zLTMyLjQtMWMtMTYuMyA3Mi41LTY4IDExNi4xLTEzMCAxMTYuMS04MiAwLTEyNy41LTYwLjMtMTI3LjUtMTM1LjIgMC00NyAyNy40LTYyLjQgNjguOS02OC45LTYuNiAyMS0xMC43IDQ0LjQtMTAuNyA2NC4zIDAgNTkgMjguMSA5Ny44IDczLjkgOTcuOCAzOC4zIDAgNzEuMS0zMy43IDg0LjItNzguNC0zMi4yLTUuMi01My4xLTEzLjUtNTMuMS0yM0wyNjYgNDkzYzAtNS45IDUuNS0xMC44IDE1LjItMTYuMi0xNS44LTQ0LjMtNDQuNC0xMTMuMy00NC40LTE2MS42IDAtNTEgMjMuOS05Mi4yIDU5LjctMTE5LjcgMjIuOS0zMi40IDcwLTY4LjQgMTAzLjUtODltMC0yNEwzODkuMyA4OWMtMzQgMjAuOC04MiA1Ny4xLTEwNy42IDkyLjEtNDIuMSAzMy41LTY1LjIgODAuOS02NS4yIDEzNCAwIDQ0LjcgMjEuMSAxMDEuNiAzNy45IDE0Ny4zLjkgMi4yIDEuNiA0LjMgMi40IDYuNS02IDUuNy0xMS4yIDEzLjUtMTEuMiAyNC4xdjEuM2wuMiAxLjMgNy4xIDU0LjhjLjMgNS43IDIuNyAxMy40IDEwLjYgMjAuNCA0LjIgMy44IDkuNSA2LjkgMTYuNCA5LjggNS4zIDIuMyAxMS42IDQuMyAxOC42IDYuMi01LjIgMTAuMi0xMS42IDE5LTE4LjkgMjYtOCA3LjctMjEgMTYuNy0zNy40IDE2LjctMTUuOCAwLTI4LjQtNi4zLTM3LjYtMTguNi0xMC4zLTEzLjgtMTUuNy0zNC4xLTE1LjctNTguOCAwLTE3LjQgMy42LTM4LjYgOS43LTU4LjFsOS45LTMxLjYtMzIuNyA1LjJjLTM3IDUuOC04Ni4yIDIxLjUtODYuMiA4OS4yIDAgMjEuMSAzLjIgNDEgOS41IDU5LjQgNi41IDE5IDE2LjIgMzUuNyAyOC43IDQ5LjkgMjYuOSAzMC4zIDY0LjkgNDYuNCAxMDkuOCA0Ni40IDY3LjkgMCAxMjMuNC00NC43IDE0NS41LTExNS41IDUuNS4xIDExLjEuMiAxNi44LjIgNS42IDAgMTEuMi0uMSAxNi44LS4yIDIxLjkgNzAuNyA3Ny41IDExNS41IDE0NS41IDExNS41IDQ1IDAgODIuOS0xNi4xIDEwOS44LTQ2LjQgMTIuNS0xNC4xIDIyLjEtMzAuOSAyOC43LTQ5LjkgNi4zLTE4LjQgOS41LTM4LjMgOS41LTU5LjQgMC02Ny43LTQ5LjEtODMuNC04Ni4yLTg5LjJsLTMyLjctNS4yIDkuOSAzMS42YzYuMiAxOS41IDkuNyA0MC43IDkuNyA1OC4xIDAgMjQuNi01LjQgNDQuOS0xNS43IDU4LjgtOS4yIDEyLjMtMjEuOCAxOC42LTM3LjYgMTguNi0xNi40IDAtMjkuNC05LjEtMzcuNC0xNi43LTcuMi03LTEzLjctMTUuOS0xOC45LTI2IDcuMS0xLjggMTMuMy0zLjkgMTguNy02LjIgNi44LTIuOSAxMi4yLTYuMiAxNi40LTkuOSA3LjktNy4xIDEwLjItMTQuNyAxMC42LTIwLjRsNy4xLTU0LjUuMS0xLjN2LTEuNGMwLTEwLjYtNS4yLTE4LjQtMTEuMS0yNCAuNi0xLjkgMS40LTMuOSAyLjItNS44IDE3LTQ2IDM4LTEwMy40IDM4LTE0OC4zIDAtNTIuOS0yMy4xLTEwMC4yLTY1LjItMTMzLjYtMTEuMS0xNS43LTI3LjctMzIuNi00OS4xLTUwLjQtMTguMy0xNS4yLTM4LjktMzAtNTguMS00MS45eiIvPjxnIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2YyZjJmMiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIj48ZyBzdHJva2Utd2lkdGg9IjE1LjEyIj48ZyBzdHJva2UtbGluZWNhcD0icm91bmQiPjxwYXRoIGQ9Ik01MjYuNyA1NDguNWw3LjItNTUuN2MwLTE5LjctNTguOS0zNS4yLTEzMy45LTM1LjItNzUuMSAwLTEzMy45IDE1LjctMTMzLjkgMzUuMmw3LjIgNTUuNyIvPjxwYXRoIGQ9Ik0yNzMuNCA1NDguNWMwLTE1LjcgNTYuNy0yOC40IDEyNi43LTI4LjRzMTI2LjcgMTIuNyAxMjYuNyAyOC40Ii8+PHBhdGggZD0iTTE2OS44IDQ5MS4yYy0zNS4yIDYuMy01OC41IDIxLjEtNTguNSA2Ni4yIDAgNzIgMzguOCAxMjYuNyAxMDguMyAxMjYuNyA2My4zIDAgMTEzLjktNTkuNiAxMTQuOC0xNTYuMm0yOTUuNy0zNi43YzM1LjIgNi4zIDU4LjUgMjEuMSA1OC41IDY2LjIgMCA3Mi0zOC44IDEyNi43LTEwOC4zIDEyNi43LTYzLjMgMC0xMTMuOS01OS42LTExNC44LTE1Ni4yIi8+PC9nPjxwYXRoIGQ9Ik01MTguNyA0NzYuMmMxNS44LTQ0LjcgNDQuNC0xMTMuMyA0NC40LTE2MS42IDAtNTEtMjMuOS05Mi4xLTU5LjctMTE5LjctMjIuNy0zMi40LTY5LjktNjktMTAzLjItODkuNS0zMy41IDIwLjUtODAuNiA1Ny4xLTEwMy4yIDg5LjUtMzUuOSAyNy40LTU5LjcgNjguNi01OS43IDExOS43IDAgNDguMyAyOC42IDExNi45IDQ0LjQgMTYxLjYiLz48L2c+PHBhdGggZD0iTTM5OC45IDIxMS4ydjE4NC43bS02OS4xLTk0aDE0MC40IiBzdHJva2Utd2lkdGg9IjE3LjI4Ii8+PC9nPjwvc3ZnPg=='); } -body.base .is2d piece.rook.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTM5OC4zIDcwOC4yYy01Ni4yIDAtMTA4LjYtNS44LTE0OC4zLTE2LjUtNDQuNi0xMi4xLTY3LjEtMjguNC02Ny4xLTQ4LjVWNTgyYzAtMjguMyA0My4xLTQ2LjEgNzMuMi01NS4ybDcuOS0xNzIuNWMtMy4yLTIuNi01LjYtNS4zLTcuMi04LjJsLS4yLS4zLTI0LjMtNTIuOGMtNy0zLjUtMTktMTAuNy0xOS0yMi4yVjE0NS4zaDczLjR2NTAuOGg0Mi4xdi01MC4ybDEzNSAuMXY1MC4xaDQyLjF2LTUwLjhoNzQuNXYxMjUuNGMwIDcuNy00LjEgMTQuNC0xMi43IDE5LjhMNTQ0LjEgMzQ2bC0uNC44Yy0yLjEgMy4xLTQuOSA2LTguNCA4LjdsNy41IDE3MS4xYzIwLjYgNiAzOCAxMy41IDUwLjUgMjEuNiAxNi4yIDEwLjUgMjQuMyAyMS44IDI0LjMgMzQgMCAuOCAwIDEuNi0uMSAyLjVsLS4xIDU4LjhjMCAyMC4yLTIzIDM2LjUtNjguNCA0OC41LTQwLjQgMTAuMy05My44IDE2LjItMTUwLjcgMTYuMnoiLz48cGF0aCBkPSJNNTcwLjYgMTU1djExNS43YzAgNC41LTMuMSA5LTEwLjcgMTMuMWwtMjQuNSA1Ny43Yy0yLjEgMy4yLTUuNSA2LjItMTAuMiA5bDggMTgzLjVjNDYuMyAxMi41IDc0LjYgMzAuOCA3NC42IDQ4LjIgMCAuNiAwIDEuMy0uMSAxLjlsLS4xIDU5LjNjMCAzMC42LTkzLjEgNTUuNC0yMDkuMiA1NS40LTExNC41IDAtMjA1LjgtMjQuNy0yMDUuOC01NS40di02MS4yYzAtMTcuMiAyNy40LTM1LjMgNzIuOC00Ny44bDguNC0xODQuN2MtNC0yLjYtNy4xLTUuMy04LjctOC4xbC0yNS42LTU1LjdjLTEwLjItNC41LTE2LjYtOS42LTE2LjYtMTVWMTU1aDU0djUwLjhoNjEuNnYtNTAuM2wxMTUuNi4xdjUwLjJoNjEuNlYxNTV6bTE5LjUtMTkuNGgtOTIuOXY1MC43aC0yMy44di01MGgtMTkuM2wtMTE1LS4xSDMyMHY1MC4xaC0yMy44di01MC43aC05Mi43djEzNS4xYzAgMTUuMyAxMi40IDI0LjQgMjEuMyAyOS4zbDIyLjggNDkuNS4zLjguNC44YzEuNSAyLjcgMy41IDUuMiA1LjcgNy41bC03LjMgMTYxLjFjLTE4LjQgNS45LTMzLjUgMTIuOS00NS40IDIwLjYtMTIuOSA4LjQtMjguMSAyMi42LTI4LjEgNDEuOHY2MS4yYzAgMTggMTMuNSAzMC42IDI0LjggMzcuOCAxMiA3LjcgMjguNSAxNC40IDQ5LjQgMjAgNDAuNCAxMC45IDk0IDE2LjggMTUxIDE2LjggNTcuNyAwIDExMi4xLTYgMTUzLjEtMTYuOCAyMS4xLTUuNiAzNy45LTEyLjMgNTAuMS0yMCAxMS42LTcuMiAyNS40LTE5LjggMjUuNC0zNy45bC4xLTU4LjJjLjEtMS4xLjEtMi4xLjEtMyAwLTguNi0zLjEtMTcuMS05LjItMjQuOS00LjYtNi0xMS4yLTExLjktMTkuNS0xNy4yLTEyLjEtNy44LTI3LjYtMTQuOC00Ni40LTIwLjdsLTYuOS0xNTkuNWMyLjctMi41IDQuOS01LjEgNi43LTcuOGwxLTEuNC42LTEuNSAyMi4xLTUyLjFjMTIuMS04LjYgMTQuNy0xOC44IDE0LjctMjYuMVYxMzUuNnoiLz48ZyBmaWxsPSJub25lIiBzdHJva2U9IiNmMmYyZjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIj48cGF0aCBkPSJNNjA2LjEgNTg2LjZjLTguOSAyOC40LTk2LjkgNTAuOC0yMDUuNCA1MC44LTExNC41IDAtMjA4LjMtMjUuMS0yMDguMy01NS42IiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjE2LjA1MSIvPjxwYXRoIGQ9Ik01MzQuMyA1NDEuMmMwIDE5LjctNjAuOSAzMy45LTEzNC40IDMzLjloLjFjLTczLjQgMC0xMzQuNC0xNC4zLTEzNC40LTMzLjlsNi41LTE5MC43IiBzdHJva2Utd2lkdGg9IjEyLjk2Ii8+PHBhdGggZD0iTTUzNC42IDM0MS4zQzUyNS4yIDM1Ny45IDQ3Mi45IDM3MCA0MDAgMzcwaC4xYy03Mi45IDAtMTI1LjMtMTIuMS0xMzQuNy0yOC42bC0yNC41LTU0LjUiIHN0cm9rZS13aWR0aD0iMTAuOCIvPjxwYXRoIGQ9Ik01NzIuOCAyNzAuNlYxNTRoLTU3LjJ2NTAuOEg0NTR2LTQ5LjFsLTExNS42LS4xdjQ5LjJoLTYxLjZWMTU0SDIyNHYxMTYuNmMwIDIwLjEgODEuNSAzNi40IDE3NS4zIDM2LjQgOTMuNyAwIDE3My41LTE2LjIgMTczLjUtMzYuNHoiIHN0cm9rZS13aWR0aD0iMTUuMTIiLz48L2c+PC9zdmc+'); } -body.base .is2d piece.queen.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTQwMCA3MDQuNGMtNjIgMC0xMjAuNS01LjUtMTY0LjgtMTUuNC00OS43LTExLjEtNzQuMi0yNS44LTc1LTQ0LjhMMTUwIDU4N3YtLjljMC01LjQgMS42LTEzLjIgOC42LTIxLjQtNy41LTQzLjEtMjQuNi0xMTcuMi00NC42LTE5Mi4yLTE4LjQtNi45LTMwLjgtMjQuNS0zMC44LTQ0LjYgMC0yNi40IDIxLjQtNDcuNyA0Ny43LTQ3LjdzNDcuNyAyMS40IDQ3LjcgNDcuN2MwIDExLjEtMy43IDIxLjUtMTAuNiAyOS45IDIxLjEgNjcuMSA0Ni45IDEzNi43IDY0LjkgMTc1LjJsNS4zLTEuM2MtLjUtNTUuMy05LjEtMTY0LjMtMjAuNi0yNjEuNi0xOC42LTgtMzEtMjYuNi0zMS00Ny4xIDAtMjguMyAyMy01MS4zIDUxLjMtNTEuM3M1MS4zIDIzIDUxLjMgNTEuM2MwIDEzLjgtNS40IDI2LjctMTUgMzYuMyAxNy45IDkzLjUgNDcuNyAyMTEuNiA2NS4zIDI1OC45bDUuNC0uM2M4LjYtNjYgMTkuNC0xODQuNSAyNC42LTI5NC41LTE0LjktOS45LTIzLjgtMjYuNS0yMy44LTQ0LjUgMC0yOS44IDI0LjItNTQgNTQtNTRzNTQgMjQuMiA1NCA1NGMwIDE4LTguOSAzNC42LTIzLjUgNDQuNiA1LjIgMTEwLjEgMTYgMjI4LjUgMjQuNiAyOTQuNWw1LjQuM2MxNy42LTQ3LjMgNDcuNC0xNjUuMyA2NS4zLTI1OC45LTkuNi05LjYtMTUtMjIuNS0xNS0zNi4zIDAtMjguMyAyMy01MS4zIDUxLjMtNTEuM3M1MS4zIDIzIDUxLjMgNTEuM2MwIDIwLjYtMTIuNCAzOS4xLTMxIDQ3LjEtMTEuNiA5Ny4zLTIwLjIgMjA2LjMtMjAuNiAyNjEuNmw1LjMgMS4zYzE4LTM4LjQgNDMuOC0xMDguMSA2NC45LTE3NS4yLTYuOS04LjQtMTAuNi0xOC45LTEwLjYtMjkuOSAwLTI2LjQgMjEuNC00Ny43IDQ3LjctNDcuN3M0Ny43IDIxLjQgNDcuNyA0Ny43YzAgMjAuMS0xMi40IDM3LjctMzAuOCA0NC42LTE5LjkgNzUuMS0zNyAxNDkuMS00NC42IDE5Mi4yIDUuNyA2LjcgOC42IDEzLjggOC42IDIxLjN2LjlsLTEwLjMgNTcuN2MtMS4yIDE4LjktMjUuNyAzMy41LTc1IDQ0LjYtNDMuOCA5LjYtMTAyLjMgMTUuMS0xNjQuNCAxNS4xem0tMTg1LTcxLjdjMTAuOCA3LjIgMzQuOSAxNC4zIDY2LjIgMTkuMSAzNC4zIDUuNCA3NS40IDguMiAxMTguOCA4LjIgOTggMCAxNjMuOS0xMy44IDE4NC4yLTI2LjlsMy4zLTIuOWMtNC4yLTQuMi0xNy0xMS40LTQ4LjctMTcuNy0zNS4zLTYuOS04NC43LTEwLjctMTM4LjktMTAuNy01MC4zIDAtOTguMiAzLjktMTM0LjYgMTEtMzMuMiA2LjUtNDcuNSAxMy44LTUyLjYgMTcuOXoiLz48cGF0aCBkPSJNNDAwIDEzNC41YzI0LjQgMCA0NC4zIDE5LjkgNDQuMyA0NC4zIDAgMTcuMS05LjYgMzEuOS0yMy44IDM5LjIgNS4xIDExNCAxNi44IDI0Mi42IDI2IDMwOS4xbDIwLjQgMS4zYzE4LjEtNDQuNyA1MS40LTE3Ni44IDY5LjQtMjcyLjYtOS43LTcuNi0xNS45LTE5LjQtMTUuOS0zMi43IDAtMjMgMTguNi00MS42IDQxLjYtNDEuNnM0MS42IDE4LjYgNDEuNiA0MS42YzAgMTktMTIuNyAzNS0zMC4yIDQwLTEyLjMgMTAyLjEtMjEuOCAyMjItMjEuNSAyNzYuNGwyMC40IDQuOWMyMC4zLTQxLjEgNDkuNy0xMjEuOSA3MC40LTE4OC45LTcuMi02LjktMTEuOC0xNi42LTExLjgtMjcuNSAwLTIxIDE3LTM4IDM4LTM4czM4IDE3IDM4IDM4YzAgMTcuOS0xMi40IDMyLjktMjkuMSAzNi45LTIwLjggNzgtMzkuNSAxNTguMi00NyAyMDMuMSA2IDUuNyA5LjQgMTEuOCA5LjQgMTguMWwtMTAuMiA1Ny0uMS4xYzAgMjguNS0xMDMgNTEuNi0yMzAgNTEuNi0xMjcuMSAwLTIzMC0yMy40LTIzMC01MS41bC0xMC4yLTU3LjFjMC02LjMgMy4yLTEyLjUgOS40LTE4LjMtNy41LTQ0LjktMjYuMS0xMjUuMi00Ny0yMDMuMS0xNi42LTQtMjkuMS0xOS0yOS4xLTM2LjkgMC0yMSAxNy0zOCAzOC0zOCAyMS4xIDAgMzggMTcgMzggMzggMCAxMC44LTQuNSAyMC42LTExLjggMjcuNSAyMC44IDY3IDUwLjEgMTQ3LjkgNzAuNCAxODguOWwyMC40LTQuOWMuMy01NC4yLTkuMi0xNzQuMy0yMS41LTI3Ni40LTE3LjQtNS0zMC4yLTIxLTMwLjItNDAgMC0yMyAxOC42LTQxLjYgNDEuNi00MS42czQxLjYgMTguNiA0MS42IDQxLjZjMCAxMy4zLTYuMyAyNS4xLTE1LjkgMzIuNyAxOCA5NS44IDUxLjIgMjI3LjkgNjkuNCAyNzIuNmwyMC40LTEuM2M5LjEtNjYuNSAyMC44LTE5NSAyNi0zMDkuMS0xNC4xLTcuNS0yMy44LTIyLjEtMjMuOC0zOS4yLjEtMjQuMyAyMC00NC4yIDQ0LjQtNDQuMm0wIDUzNS4zYzg5LjQgMCAxNjUtMTIuMSAxOTAuMi0yOC44bDktNy45YzAtMjUuNi04OS4xLTQxLTE5OS00MXMtMTk5IDE4LjQtMTk5IDQxbDguMSA3LjJjMjQgMTcgMTAwLjMgMjkuNSAxOTAuNyAyOS41bTAtNTU0LjdjLTM1LjEgMC02My43IDI4LjYtNjMuNyA2My43IDAgMTkuMyA4LjYgMzcuMyAyMy4yIDQ5LjItNC40IDkyLjgtMTIuOSAxOTAuOC0yMC41IDI1Ny44LTE3LTU1LjQtMzkuNi0xNDguMS01NC4zLTIyMy41IDkuMi0xMC45IDE0LjQtMjQuNyAxNC40LTM5LjMgMC0zMy43LTI3LjMtNjEtNjEtNjFzLTYxIDI3LjMtNjEgNjFjMCAxMy41IDQuMyAyNi40IDEyLjYgMzcuMiA1LjIgNi43IDExLjcgMTIuMyAxOS4xIDE2LjQgOS4xIDc3LjQgMTYuMiAxNjEuNSAxOC45IDIxOS4yLTE1LjMtMzcuNi0zMy4yLTg3LjQtNDguNi0xMzYuMyA2LjItOS4zIDkuNi0yMC40IDkuNi0zMS42IDAtMzEuNi0yNS44LTU3LjUtNTcuNS01Ny41LTMxLjYgMC01Ny42IDI1LjctNTcuNiA1Ny4zIDAgMjIuNSAxMi45IDQyLjIgMzIuMyA1MS42IDE4LjcgNzAuOCAzNC44IDE0MC4yIDQyLjQgMTgyLjYtNi41IDkuMS04LjEgMTcuNy04LjEgMjR2MS43bC4zIDEuNyA5LjkgNTUuOGMuNCA1LjcgMi42IDEzLjUgOS43IDIxLjQgNC42IDUgMTAuNyA5LjQgMTguNyAxMy42IDEzLjEgNi45IDMxLjMgMTMuMSA1NC4xIDE4LjEgNDUgMTAuMiAxMDQuMyAxNS43IDE2NyAxNS43IDYyLjkgMCAxMjIuMS01LjUgMTY3LTE1LjcgMjIuOC01LjEgNDEtMTEuMiA1NC4xLTE4LjMgOC00LjIgMTQtOC43IDE4LjctMTMuNyA0LjEtNC41IDYuNi05LjEgOC0xMy4ybC4zLS4zLjMtMS44Yy41LTEuOS45LTMuOCAxLTUuNWwxMC01Ni40LjMtMS43VjU4NmMwLTYuMi0xLjYtMTQuOC04LjEtMjMuOSA3LjYtNDIuNCAyMy44LTExMS44IDQyLjQtMTgyLjYgMTkuNC05LjQgMzIuMy0yOS4zIDMyLjMtNTEuNiAwLTMxLjYtMjUuOC01Ny41LTU3LjUtNTcuNS0zMS42IDAtNTcuNSAyNS44LTU3LjUgNTcuNSAwIDExLjMgMy4zIDIyLjQgOS42IDMxLjYtMTUuNCA0OC45LTMzLjQgOTguNy00OC42IDEzNi4zIDIuNy01Ny44IDkuOC0xNDEuOCAxOC45LTIxOS4yIDcuMy00LjEgMTMuOS05LjYgMTkuMS0xNi40IDguMi0xMC43IDEyLjYtMjMuNSAxMi42LTM3LjIgMC0zMy43LTI3LjMtNjEtNjEtNjFzLTYxIDI3LjMtNjEgNjFjMCAxNC42IDUuMSAyOC40IDE0LjQgMzkuMy0xNC43IDc1LjQtMzcuNCAxNjgtNTQuMyAyMjMuNS03LjctNjctMTYuMS0xNjQuOS0yMC41LTI1Ny44IDE0LjUtMTEuOSAyMy4xLTI5LjggMjMuMS00OS4xLjItMzUuMi0yOC40LTYzLjgtNjMuNS02My44ek0yMzQgNjMxYzguNS0zIDIxLjYtNi43IDQxLjMtMTAgMzQuNy02IDc4LjktOS4zIDEyNC43LTkuMyA0OCAwIDkxLjIgMi45IDEyNS4xIDguNCAyMS4xIDMuNSAzNC4zIDcuMSA0Mi43IDEwLjQtOS41IDMuNi0yNS41IDguMS01MS41IDEyLjEtMzMuNyA1LjItNzMuOSA3LjktMTE2LjIgNy45LTQyLjkgMC04My40LTIuOC0xMTcuMy04LjEtMjQtMy44LTM5LjItOC4xLTQ4LjgtMTEuNHoiLz48Y2lyY2xlIGN4PSI0MDAiIGN5PSIxMTIuOSIgcj0iMjUuOSIvPjxjaXJjbGUgY3g9IjIyNSIgY3k9IjE2NC44IiByPSIyMyIvPjxjaXJjbGUgY3g9IjExMy44IiBjeT0iMjczLjgiIHI9IjIyLjQiLz48Y2lyY2xlIGN4PSI1NzUiIGN5PSIxNjQuOCIgcj0iMjMiLz48Y2lyY2xlIGN4PSI2ODcuMyIgY3k9IjI3My44IiByPSIyMi40Ii8+PGcgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZjJmMmYyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCI+PHBhdGggZD0iTTExNy42IDI4Ny45bC00LjUtMTUiIHN0cm9rZS13aWR0aD0iMTcuMjgiLz48cGF0aCBkPSJNMjI4LjggMTgwLjdsLTQuNC0xOCIgc3Ryb2tlLXdpZHRoPSIxOC4zNiIvPjxwYXRoIGQ9Ik02ODIuNyAyODcuOWw0LjYtMTUiIHN0cm9rZS13aWR0aD0iMTcuMjgiLz48cGF0aCBkPSJNNTcwLjQgMTgwLjdsNC42LTE4IiBzdHJva2Utd2lkdGg9IjE4LjM2Ii8+PHBhdGggZD0iTTM5OS41IDEwOC42VjEyNyIgc3Ryb2tlLXdpZHRoPSIyMC41MiIvPjxnIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMTUuMTIiPjxwYXRoIGQ9Ik0yNjMuNyAyNTUuOGM5LjctNy42IDE1LjktMTkuNCAxNS45LTMyLjcgMC0yMy0xOC42LTQxLjYtNDEuNi00MS42cy00MS42IDE4LjYtNDEuNiA0MS42YzAgMTkgMTIuNyAzNSAzMC4yIDQwIDEyLjMgMTAyLjEgMjEuOCAyMTUuNiAyMS41IDI2OS45bC0yMC40IDQuOU00MjAuNSAyMThjMTQuMS03LjUgMjMuOC0yMi4xIDIzLjgtMzkuMiAwLTI0LjQtMTkuOS00NC4zLTQ0LjMtNDQuM3MtNDQuMyAxOS45LTQ0LjMgNDQuM2MwIDE3LjEgOS42IDMxLjkgMjMuOCAzOS4yLTUuMSAxMTQtMTYuOCAyMzYuMS0yNiAzMDIuNmwtMjAuNCAxLjNNNTczLjMgMjYzYzE3LjQtNSAzMC4yLTIxIDMwLjItNDAgMC0yMy0xOC42LTQxLjYtNDEuNi00MS42UzUyMC4zIDIwMCA1MjAuMyAyMjNjMCAxMy4zIDYuMyAyNS4xIDE1LjkgMzIuNy0xOCA5NS44LTUxLjIgMjIxLjQtNjkuNCAyNjYuMWwtMjAuNC0xLjNtMjMxLjUtMTU1LjdjMTYuNi00IDI5LjEtMTkgMjkuMS0zNi45IDAtMjEtMTctMzgtMzgtMzhzLTM4IDE3LTM4IDM4YzAgMTAuOCA0LjUgMjAuNiAxMS44IDI3LjUtMjAuOCA2Ny01MC4xIDE0MS40LTcwLjQgMTgyLjRsLTIwLjQtNC45Ii8+PHBhdGggZD0iTTE1Ny4yIDM1NS40YzcuMi02LjkgMTEuOC0xNi42IDExLjgtMjcuNSAwLTIxLTE3LTM4LTM4LTM4LTIxLjEgMC0zOCAxNy0zOCAzOCAwIDE3LjkgMTIuNCAzMi45IDI5LjEgMzYuOSAyMC44IDc4IDM5LjUgMTU1IDQ3IDE5OS45LTYgNS43LTkuNCAxMS44LTkuNCAxOC4xbDEwLjIgNjAuM2MwLTI4LjUgMTAzLTUxLjYgMjMwLjEtNTEuNnMyMzAuMSAyMy4xIDIzMC4xIDUxLjZsMTAuMi02MC4zYzAtNi4zLTMuMi0xMi4zLTkuNC0xOC4xIi8+PC9nPjwvZz48L3N2Zz4='); } -body.base .is2d piece.king.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjgwMCIgdmlld0JveD0iMCAwIDgwMCA4MDAiIHdpZHRoPSI4MDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTY5NC43IDM2My4yYy05LjctNy41LTIyLjYtMTEuMi0zOC0xMS4yaC0xLjRjLTIuMSAwLTQuMi4xLTYuNS4xLTIuNyAwLTUuNi4xLTguNS4xIDMuMy0yMy43LjYtNDEuNi04LTU1LjUtNi42LTEwLjYtMTUuOS0xOC4zLTI3LjgtMjIuOS05LjMtMy43LTIwLjMtNS40LTMzLjYtNS40LTEyLjIgMC0yNS4yIDEuNC0zOC44IDMuMi0zLTE0LjEtOS4zLTI1LjQtMTguNy0zMy41LTkuNS04LjMtMjAuNi0xMi41LTMzLTEyLjUtMjQuMSAwLTQ3LjIgMTYuMy02NS45IDI5LjZ2LTgwLjdoNDkuN3YtMzAuMmgtNDkuN1Y5NC42aC0zMC4ydjQ5LjdoLTQ2LjR2MzAuMmg0Ni40djc4LjljLTE4LjMtMTMtNDAuNC0yOC02My41LTI4LTEyLjQgMC0yMy41IDQuMi0zMyAxMi41LTkuNCA4LjEtMTUuNiAxOS4zLTE4LjcgMzMuNS0xMy43LTEuOC0yNi43LTMuMi0zOC45LTMuMi0xMy4zIDAtMjQuMyAxLjctMzMuNyA1LjQtMTEuOSA0LjYtMjEuMiAxMi4zLTI3LjggMjIuOS04LjYgMTQtMTEuMyAzMi04LjEgNTUuNS0yLjggMC01LjYtLjEtOC4yLS4xLTIuNSAwLTQuOS0uMS03LS4xSDE0NGMtMTUuMiAwLTI4LjQgMy45LTM4LjIgMTEuMS04LjUgNi40LTE4LjYgMTguMy0xOC42IDM5LjQgMCAyNi4xIDE4LjMgNTMuOCAzNy41IDgzLjJsNS43IDguNyAyNS42IDUzLjljLTcuNiA4LjMtMTEuMyAxNy4zLTExLjMgMjYuOHYyLjJsLjQgMi4yIDE1LjcgNjQuNmMxLjEgMTIuOSAxMC4yIDI0IDI3IDMyLjkgMTIuNiA2LjcgMzAuMSAxMi41IDUyLjEgMTcuNSA0My4xIDkuNyAxMDAuMSAxNSAxNjAuNiAxNSA2MCAwIDExNi43LTUuMyAxNTkuNy0xNC44IDIxLjgtNC45IDM5LjMtMTAuNyA1Mi4xLTE3LjMgMTcuMS04LjkgMjYuNS0xOS45IDI3LjktMzIuNmwxNC43LTY1LjcuNi0xLjl2LTIuMWMwLTkuNC00LTE4LjEtMTEuNi0yNi4xbDIzLjgtNTIuNmMyLjUtMy43IDQuOS03LjUgNy4zLTExIDE5LjQtMjkuMiAzNy44LTU2LjcgMzcuOC04Mi43IDAtMjEuMS05LjktMzMtMTguMS0zOS4zeiIvPjxnIHN0cm9rZT0iI2YyZjJmMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiPjxnIGZpbGw9Im5vbmUiIHN0cm9rZS13aWR0aD0iMTUuMTIiPjxwYXRoIGQ9Ik0xODIgMzcxLjVjLTExLjkuMy0yNS45LS4xLTM3LjUtLjMtMjEuOS0uMy0zOS40IDguNy0zOS40IDMyLjIgMCAzOS4xIDYwLjYgOTUuNyA3My4zIDE0Ni43Ii8+PHBhdGggZD0iTTI4NC4xIDI5My41Yy00NS42LTYuMy04My4zLTEzLjgtMTAwLjMgMTMuNy0yNyA0My42IDM1LjYgMTUwLjcgNTUuMSAyMjIuNCIvPjxwYXRoIGQ9Ik0zOTguOSAyODYuOGMtMjQuMy05LTY3LjktNjEuNy05OS44LTMzLjktNDMuNiAzNy45IDIyLjkgMTczLjkgMzguMSAyNjAuNW0yODAuNy0xNDEuOWMxMS45LjMgMjUuOS0uMSAzNy41LS4zIDIxLjktLjMgMzkuNCA4LjcgMzkuNCAzMi4yIDAgMzkuMS02MC42IDk1LjctNzMuMyAxNDYuNyIvPjxwYXRoIGQ9Ik01MTUuOSAyOTMuNWM0NS42LTYuMyA4My4zLTEzLjggMTAwLjMgMTMuNyAyNyA0My42LTM1LjYgMTUwLjctNTUuMSAyMjIuNCIvPjxwYXRoIGQ9Ik00MDEuMSAyODYuOGMyNC4zLTkgNjcuOS02MS43IDk5LjgtMzMuOSA0My42IDM3LjktMjIuOSAxNzMuOS0zOC4xIDI2MC41Ii8+PC9nPjxwYXRoIGQ9Ik0xNzcuOSA1NTRjMzQtMjMuMyAxMjAuNi0zOS42IDIyMi0zOS42IDEwMi41IDAgMTkwLjMgMTYuMyAyMjMuNiA0MGwzMS44LTc4LjFjLTExLjggMTMuMS0yMy43IDE4LjUtMzMuOSAxNS4zLTI2LjktOC40LTI2LjUtNDAuNi0yNC40LTY2LjUtMTYuNCAyOS41LTM5LjMgNDQuNy02My45IDM5LjUtMjQuOS01LjMtNDAtNDAuNS0zOS02OC42LTE3LjUgMzUuNi00OS40IDU0LjEtOTQuMSA1NC4xcy03Ni42LTE4LjYtOTQuMS01NC4yYzEuMSAyOC4xLTE0IDYzLjMtMzkgNjguNi0yNC42IDUuMi00Ny40LTEwLTYzLjktMzkuNSAxLjkgMjUuOSAyLjYgNTguNS0yNC40IDY2LjUtOS4xIDIuNy0yMi4xLTMuOC0zMy45LTE1LjN6IiBzdHJva2Utd2lkdGg9IjEyLjk2Ii8+PGcgZmlsbD0ibm9uZSI+PHBhdGggZD0iTTE2Mi41IDU3NS45YzAtMzQuMyAxMDYuMy02MS43IDIzNy40LTYxLjdzMjM3LjQgMjcuMyAyMzcuNCA2MS43bS00NzUgMS44bDE2LjIgNjUuMW00NTkuMi02NS4xbC0xNi4yIDY1LjEiIHN0cm9rZS13aWR0aD0iMTIuOTYiLz48cGF0aCBkPSJNMTc4LjYgNjQyLjJjMC0yNy40IDk5LjEtNDkuNyAyMjEuNC00OS43czIyMS40IDIyLjIgMjIxLjQgNDkuNyIgc3Ryb2tlLXdpZHRoPSIxNS4xMiIvPjxwYXRoIGQ9Ik00MDAgMjg2Ljh2MTYwLjkiIHN0cm9rZS13aWR0aD0iNi40OCIvPjwvZz48L2c+PC9zdmc+'); } diff --git a/public/stylesheets/piece/companion.css b/public/stylesheets/piece/companion.css deleted file mode 100644 index 9b37921355..0000000000 --- a/public/stylesheets/piece/companion.css +++ /dev/null @@ -1,12 +0,0 @@ -body.base .is2d piece.pawn.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMjcuNzA1IDMwLjcyNGMxLjcxMzMtMi45NjYxIDYuMzI5NS0zLjI0MjggOC4zNTE5LS40NjAxNyAxLjc1OTQgMS44OTU3LjkyNDM0IDQuNTQ4Ni4zOTcxNyA2Ljc1NDEgMi44MDkgMS4zNDI4IDYuMDk5IDEuODkxOSA4LjQyODggNC4wODU4IDEuNzE2NiAxLjUyNjYgMS45MDkyIDMuOTI3OSAyLjI2OTcgNi4wNDYxLTMuNjIyNy4xMjIxNC03LjI0NzQuMDU3NTUtMTAuODcxLjA4MjA1LjAyMzIxIDIuMDUzNS4xOTEzOCA0LjEzODggMS4yNzY3IDUuOTQxMyAxLjczODMgMy4zNzk2IDMuMDc3NiA3LjcxOTkuNDY0NzIgMTEuMDQ0LS4wMjE3NC40NTcxLS4wNjUyMSAxLjM3MTMtLjA4Njk0IDEuODI4NCAzLjE5OTUuMjY3MTQgNi43NzAxLjQ0NDE2IDkuMjY2NiAyLjczNjkgMS41MzY5IDEuMjg2NCAxLjgwNTcgMy4zNjc3IDIuMjY1MiA1LjE5My0xMS4xOTMuMTYyMjctMjIuMzg5LjAyNjY1LTMzLjU4My4wNzExMnYtNC4xMTk4YzIuNDgtMy4xMTExIDYuNTg3MS0zLjY3MDcgMTAuMjk2LTMuODg3MS4wMTYwMS0uNDM3My4wNDgwNi0xLjMxMTkuMDY0MDctMS43NDkyLS43Mjk3My0xLjM5NzktMS44MzA1LTIuNzcyOS0xLjY3NjctNC40NDg0LS4wMDU4LTQuNTA2MyAzLjc4MzgtOC4wMjc1IDMuMjY3MS0xMi42MS0zLjU2OTYtLjAyMjU3LTcuMTM5Ni4wMjczNy0xMC43MDgtLjA2MTc3LjQ4NzEtMi41ODAzIDEuMzQ5Mi01LjM0NzMgMy42MzA3LTYuOTA0IDIuMTk3My0xLjQ2MTkgNC42OTQ0LTIuMzg5NiA2Ljk5MTYtMy42NzktLjQ3NjQ3LTEuODkyMi0xLjM4OTMtNC4wOTQtLjA0NDg4LTUuODYzNHoiIGZpbGw9IiNmZmYiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wNzg4OTUiLz48cGF0aCBkPSJtMjcuNzA1IDMwLjcyNGMxLjcxMzMtMi45NjYxIDYuMzI5NS0zLjI0MjggOC4zNTE5LS40NjAxNyAxLjc1OTQgMS44OTU3LjkyNDM0IDQuNTQ4Ni4zOTcxNyA2Ljc1NDEgMi44MDkgMS4zNDI4IDYuMDk5IDEuODkxOSA4LjQyODggNC4wODU4IDEuNzE2NiAxLjUyNjYgMS45MDkyIDMuOTI3OSAyLjI2OTcgNi4wNDYxLTMuNjIyNy4xMjIxNC03LjI0NzQuMDU3NTUtMTAuODcxLjA4MjA1LjAyMzIxIDIuMDUzNS4xOTEzOCA0LjEzODggMS4yNzY3IDUuOTQxMyAxLjczODMgMy4zNzk2IDMuMDc3NiA3LjcxOTkuNDY0NzIgMTEuMDQ0LS4wMjE3NC40NTcxLS4wNjUyMSAxLjM3MTMtLjA4Njk0IDEuODI4NCAzLjE5OTUuMjY3MTQgNy4yNDYyLjUwODg0IDkuMjY2NiAyLjczNjkgMi4wNDgxIDIuMjU4NyAxLjgwNTcgMy4zNjc3IDIuMjY1MiA1LjE5My0xMS4xOTMuMTYyMjctMjMuODA0LjEyOTUtMzQuOTk4LjE3Mzk4LjI4ODIxLTEuNzQzMS4xOTkxNC0xLjczMjggMS40MjYtNC4zNzg4IDEuMjE2MS0yLjYyMjggNi41NzY1LTMuNTE0NiAxMC4yODYtMy43MzEuMDE2MDEtLjQzNzMuMDQ4MDYtMS4zMTE5LjA2NDA3LTEuNzQ5Mi0uNzMtMS4zOTctMS44MzEtMi43NzItMS42NzctNC40NDctLjAwNTgtNC41MDYzIDMuNzgzOC04LjAyNzUgMy4yNjcxLTEyLjYxLTMuNTY5Ni0uMDIyNTctNy4xMzk2LjAyNzM3LTEwLjcwOC0uMDYxNzcuNDg3MS0yLjU4MDMgMS4zNDkyLTUuMzQ3MyAzLjYzMDctNi45MDQgMi4xOTczLTEuNDYxOSA0LjY5NDQtMi4zODk2IDYuOTkxNi0zLjY3OS0uNDc2NDctMS44OTIyLTEuMzg5My00LjA5NC0uMDQ0ODgtNS44NjM0eiIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im0zMC41OTcgMzYuODc4Yy0xLjk2NTYtMS45NjQ5LTEuNzQyNS02LjUzMDIgMS43ODE4LTYuMjExMSAzLjA5MjcuNDEwMjMgMi43MjU5IDQuMjI5MiAxLjMyMzIgNi4xNjQ1IDIuOTggMy42NTE0IDkuMjQ4MSAyLjk1NjUgMTAuODc2IDcuODgxMS04LjI1ODIuMjM4MTItMTYuNTM4LjIzMjE4LTI0Ljc5Ni4wMDAxOTIgMS43MTgtNC44NTE0IDcuODEzOS00LjI1OTIgMTAuODE1LTcuODM0N3oiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wNzg4OTUiLz48cGF0aCBkPSJtMzAuNTk3IDM2Ljg3OGMtMS45NjU2LTEuOTY0OS0xLjc0MjUtNi41MzAyIDEuNzgxOC02LjIxMTEgMy4wOTI3LjQxMDIzIDIuNzI1OSA0LjIyOTIgMS4zMjMyIDYuMTY0NSAyLjk4IDMuNjUxNCA5LjI0ODEgMi45NTY1IDEwLjg3NiA3Ljg4MTEtOC4yNTgyLjIzODEyLTE2LjUzOC4yMzIxOC0yNC43OTYuMDAwMTkyIDEuNzE4LTQuODUxNCA3LjgxMzktNC4yNTkyIDEwLjgxNS03LjgzNDd6Ii8+PHBhdGggZD0ibTMwLjEyNyA0Ny4yMjNjMS4yODcyLS4wMDAwOTYgMi41NzQ1LS4wMDAwOTYgMy44NjIxLS4wMDAxNDQtLjkzNTI3IDQuODU2NSAzLjQ4MjkgOC40OTE4IDMuMTU1MSAxMy4yNzEtLjAzNzYyIDEuMTk2Ni0uNzY1ODcgMi4xODQ3LTEuMzIyMyAzLjE5MDEuMjEyNzQgMS4zNTE1LjQyODcgMi43MDI1LjY0MTgyIDQuMDU0OCAzLjU0MDMuMjQzMzcgOC4wMjMxLjIyOTY4IDkuOTMzOSAzLjg0NTQtOS41OTU1LjE0MjI2LTE5LjIwNC4xOTQxNy0yOC43OTgtLjAyNzUxIDIuMDc0NC0zLjU1ODcgNi41Nzg1LTMuNTcyNyAxMC4xODgtMy44MTYzLjIyNDM4LTEuMzczOC40NTEzOC0yLjc0NjUuNjgzMDUtNC4xMTgtLjgyMTE1LTEuMTI2OS0xLjgxOTEtMi4yODg4LTEuNzEzMy0zLjc4NjItLjA3MzAzLTQuNTY4NSA0LjM2OTQtNy45MDAxIDMuMzY5Mi0xMi42MTN6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDc4ODk1Ii8+PHBhdGggZD0ibTMwLjEyNyA0Ny4yMjNjMS4yODcyLS4wMDAwOTYgMi41NzQ1LS4wMDAwOTYgMy44NjIxLS4wMDAxNDQtLjkzNTI3IDQuODU2NSAzLjQ4MjkgOC40OTE4IDMuMTU1MSAxMy4yNzEtLjAzNzYyIDEuMTk2Ni0uNzY1ODcgMi4xODQ3LTEuMzIyMyAzLjE5MDEuMjEyNzQgMS4zNTE1LjQyODcgMi43MDI1LjY0MTgyIDQuMDU0OCAzLjU0MDMuMjQzMzcgOC4wMjMxLjIyOTY4IDkuOTMzOSAzLjg0NTQtOS41OTU1LjE0MjI2LTE5LjIwNC4xOTQxNy0yOC43OTgtLjAyNzUxIDIuMDc0NC0zLjU1ODcgNi41Nzg1LTMuNTcyNyAxMC4xODgtMy44MTYzLjIyNDM4LTEuMzczOC40NTEzOC0yLjc0NjUuNjgzMDUtNC4xMTgtLjgyMTE1LTEuMTI2OS0xLjgxOTEtMi4yODg4LTEuNzEzMy0zLjc4NjItLjA3MzAzLTQuNTY4NSA0LjM2OTQtNy45MDAxIDMuMzY5Mi0xMi42MTN6Ii8+PC9nPjwvZz48L3N2Zz4='); } -body.base .is2d piece.knight.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMjEuNDcgMzAuMDA0Yy4zMzYzNS0yLjI3MjQuOTU2MjMtNC40ODg4IDEuODY5NS02LjU5NzEgMS40NzYxIDEuNzkzMSAyLjk0NzQgMy41OTI3IDQuNTQ5NyA1LjI3NjkgOC4wMDU4LS4yODM2IDE1Ljg2NyAzLjU4MjkgMjAuNTA5IDEwLjEwNCA3LjE3NDcgMTAuMDE1IDEwLjAzNCAyMy4zMzMgNi43MDY1IDM1LjI5LTExLjA4Ny4wMDQ5LTIyLjE3NC0uMDE0Ny0zMy4yNjEuMDEwNDEtMi4yODMyLTIuMTE5Mi0zLjExNDktNS43OTA2LS45MjEzOC04LjI4NDEgMy4zOTM4LTMuNTYzNSA3Ljg5MTYtNi4xNTYyIDEwLjI2My0xMC42MzQtMi41ODAyLjI3ODA5LTUuMTc0OC40Njg3Mi03Ljc2NzUuMjY1NzItMS41OTE5IDIuNTQyOS0zLjU4MzMgNS45MTkyLTcuMDQ2NyA1LjY3NDYtMi4zMTktLjI5MTU1LTQuODgwMi40NDQyMy02Ljk1MS0uOTQ5MjItMi4wMzc2LTEuMjQwMS0yLjE2MTMtNC4wMzctMS42NTg1LTYuMTIwOCAxLjIzMjctNC41NjU5IDYuMzE2OC02LjgwNzEgNy4zODctMTEuNDU0LjQwMzktMi4yMTE2IDIuMDgtMy43NTg0IDMuNjA3Ni01LjI1ODQtLjQ3Mzg4LTMuMzgyLS44NzA5NS02Ljc4MDgtLjg5NDIzLTEwLjIgMS4yMTE2Ljk0NjkgMi40MTcyIDEuOTAyNyAzLjYwNzcgMi44Nzc0eiIgZmlsbD0iI2ZmZiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4MDQ0MSIvPjxwYXRoIGQ9Im0yMS40NyAzMC4wMDRjLjMzNjM1LTIuMjcyNC45NTYyMy00LjQ4ODggMS44Njk1LTYuNTk3MSAxLjQ3NjEgMS43OTMxIDIuOTQ3NCAzLjU5MjcgNC41NDk3IDUuMjc2OSA4LjAwNTgtLjI4MzYgMTUuODY3IDMuNTgyOSAyMC41MDkgMTAuMTA0IDcuMTc0NyAxMC4wMTUgMTAuMDM0IDIzLjMzMyA2LjcwNjUgMzUuMjktMTEuMDg3LjAwNDktMjIuMTc0LS4wMTQ3LTMzLjI2MS4wMTA0MS0yLjI4MzItMi4xMTkyLTMuMTE0OS01Ljc5MDYtLjkyMTM4LTguMjg0MSAzLjM5MzgtMy41NjM1IDcuODkxNi02LjE1NjIgMTAuMjYzLTEwLjYzNC0yLjU4MDIuMjc4MDktNS4xNzQ4LjQ2ODcyLTcuNzY3NS4yNjU3Mi0xLjU5MTkgMi41NDI5LTMuNTgzMyA1LjkxOTItNy4wNDY3IDUuNjc0Ni0yLjMxOS0uMjkxNTUtNC44ODAyLjQ0NDIzLTYuOTUxLS45NDkyMi0yLjAzNzYtMS4yNDAxLTIuMTYxMy00LjAzNy0xLjY1ODUtNi4xMjA4IDEuMjMyNy00LjU2NTkgNi4zMTY4LTYuODA3MSA3LjM4Ny0xMS40NTQuNDAzOS0yLjIxMTYgMi4wOC0zLjc1ODQgMy42MDc2LTUuMjU4NC0uNDczODgtMy4zODItLjg3MDk1LTYuNzgwOC0uODk0MjMtMTAuMiAxLjIxMTYuOTQ2OSAyLjQxNzIgMS45MDI3IDMuNjA3NyAyLjg3NzR6Ii8+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0ibTIzLjY2NyAyOC4zNWMxLjY0MiAxLjI1OTggMy4yNTA2IDIuNTY1MyA0Ljk3MDUgMy43MjE0IDEuMzg0OS0uMjg2MSAyLjc2OS0uNTc0MSA0LjE1NTYtLjg2MTgxLjMzNTc5LjY1Mzc5LjY3MjUgMS4zMDc3IDEuMDEwMSAxLjk2MTdsMi45NjYyLS43MTQ5NyAxLjA1NjIgMi4yNTg2Yy4yMjEzOS40NzM0MyAxLjQzOTEtLjI3NzYyIDEuOTE4Ny0uMzcwMTcuMjYzMjcuODQ4MzEuNTI3NTkgMS42OTY4Ljc5Mjk1IDIuNTQ1NCAxLjEyNzYuMTUzNTkgMi4yNTc1LjMwNzM2IDMuMzg3OC40NjA4Ni4xOTg3NiAxLjA4OTQuMzk5MTQgMi4xNzg5LjYwMDAyIDMuMjY4OCAxLjE2ODEuMTg0NzkgMi4zMzczLjM2OTYyIDMuNTA3Ny41NTQ0OS0uMjgyNzcgMS4xMjUzLS41NjQzNiAyLjI1MDgtLjg0NDc2IDMuMzc2NSAxLjI4NDkuODIyNzEgMi41NzA4IDEuNjQ0OSAzLjg1ODEgMi40NjY5LS41MDE1NiAxLjI1NjctMS4wMDQxIDIuNTEyOS0xLjUwNDIgMy43Njk5IDEuMzQ2OS45MDUyOSAyLjY5NTUgMS44MDkgNC4wNDUyIDIuNzEzMi0uNzAzMjcgMS4yMDY3LTEuNDA3NiAyLjQxMjUtMi4xMDkxIDMuNjE5OC45MDY2OC45NDc3NSAxLjgxNTEgMS44OTQ5IDIuNzI1MyAyLjg0MTktLjgzMDY2IDEuMzUzOC0xLjY2MDcgMi43MDc3LTIuNDg5IDQuMDYyNy43NjkwNC44MTk3MSAxLjU0MDMgMS42NCAyLjMxMjYgMi40NjAyLS41MDI3NiAxLjgxMjItMS4wMDQxIDMuNjI0OS0xLjUwNTcgNS40Mzc4LTEwLjI2Ny0uMzg1OTktMjAuNTQzLS4yMzAwMy0zMC44MTUtLjI1NTgxLS4yMTM5OS0xLjMzNy0uOTA0NzYtMi45ODg4LjI2OTI0LTQuMDg2MiAzLjM0NjItMy4wNTA4IDcuMjcyOS01LjY0MDIgOS42Njc0LTkuNTkxNCAxLjI2NDQtMi4wMzY5IDEuNzIyOC00LjQxNzEgMi4zMTktNi43MDM2LTQuMDQxMSAyLjgwNjQtOC4zNDg5IDIuMzgwNC0xMi44NzQgMS41MzQ2IDEuMzk5OSAzLjQzNjYtMS44Nzk2IDUuNTIxLTUuMDQwMSA2LjI3MjcuMDEzMDUtLjc1ODk0LjAzOTEyLTIuMjc2OC4wNTIxNy0zLjAzNTgtMS4yNjY0Ljk1NzQ0LTIuNDk0MSAxLjk2NDEtMy43MTM0IDIuOTc5Ny0yLjQ5ODQtLjkxODczLTMuMDkxMi0zLjg5MjEtMS44NTUzLTYuMDc4IDEuNjIyMy0yLjM0NzggNC4xMDg4LTQuMDM2MiA1LjQxMzEtNi42MTY1LjgwNjk3LTIuMDkyMSAxLjE2MTMtNC40NDA4IDIuNzA5MS02LjE2NzkgMS41MTM5LTEuNzIxMSAyLjcwNzUtMy42NzU3IDMuODAwOS01LjY4MjMgMS4xNzg2LjczODYyIDIuMzU3NCAxLjQ3OSAzLjU3ODcgMi4xNDgzLS43MjI3MS0yLjg1OTctMy40NDU4LTUuMTA3LTIuMzY1OS04LjI5MTF6Ii8+PHBhdGggZD0ibTE5LjgyOCAzMS41MzljMS42MzgtLjc3NzYyIDIuMzY0OC45MTczNCAyLjI3MTkgMi4yNzQyLTEuNTIzMSAxLjU3NjYtMy4yMTY5LS43NTY0Mi0yLjI3MTktMi4yNzQyeiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4MDQ0MSIvPjxwYXRoIGQ9Im0xOS44MjggMzEuNTM5YzEuNjM4LS43Nzc2MiAyLjM2NDguOTE3MzQgMi4yNzE5IDIuMjc0Mi0xLjUyMzEgMS41NzY2LTMuMjE2OS0uNzU2NDItMi4yNzE5LTIuMjc0MnoiLz48L2c+PHBhdGggZD0ibTIyLjAxMiA0Mi41MTFjMS41MDg1LTEuMzYwMiAzLjg5NTMuMjI4MjMgNS42OTU5Ljc2NzI5LTEuOTkyMyAxLjExNTItNC44NTIzIDMuMDM1My02LjQ0ODcgMi4wNzQzLS42NDY2MS0uMzg5MjYuMDYxLTIuMjE3OC43NTI3Ny0yLjg0MTZ6Ii8+PHBhdGggZD0ibTEyLjY0IDUzLjk5NWMuNjc3OTYtLjY0NDMgMi43MDY3LS4xNTQwOSAxLjczMDguOTY1NDUtLjkwMzY5IDEuNTQwOC0zLjkwNjkuMjE3MjMtMS43MzA4LS45NjU0NXoiIGZpbGw9IiNmZmYiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODA0NDEiLz48cGF0aCBkPSJtMTIuNjQgNTMuOTk1Yy42Nzc5Ni0uNjQ0MyAyLjcwNjctLjE1NDA5IDEuNzMwOC45NjU0NS0uOTAzNjkgMS41NDA4LTMuOTA2OS4yMTcyMy0xLjczMDgtLjk2NTQ1eiIvPjwvZz48L3N2Zz4='); } -body.base .is2d piece.bishop.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJtMjEuNDcgNzQuMTQ5Yy4zMzYzNS0uMDAwMDQ1Ljk1NjIzLS4wMDAwODggMS44Njk1LS4wMDAxMyAxLjQ3NjEuMDAwMDM1IDIuOTQ3NC4wMDAwNzEgNC41NDk3LjAwMDEwNCA4LjAwNTgtLjAwMDAwNiAxNS44NjcuMDAwMDcxIDIwLjUwOS4wMDAxOTkgNy4xNzQ3LjAwMDE5NyAxMC4wMzQuMDAwNDU5IDYuNzA2Ni4wMDA2OTUtMTEuMDg3IDAtMjIuMTc0LS4wMDAwMDEtMzMuMjYxIDAtMi4yODMyLS4wMDAwNDItMy4xMTQ5LS4wMDAxMTQtLjkyMTM4LS4wMDAxNjMgMy4zOTM4LS4wMDAwNyA3Ljg5MTYtLjAwMDEyMSAxMC4yNjMtLjAwMDIxLTIuNTgwMi4wMDAwMDYtNS4xNzQ4LjAwMDAxLTcuNzY3NS4wMDAwMDYtMS41OTE5LjAwMDA1LTMuNTgzMy4wMDAxMTYtNy4wNDY4LjAwMDExMS0yLjMxOS0uMDAwMDA1LTQuODgwMi4wMDAwMDktNi45NTExLS4wMDAwMTgtMi4wMzc2LS4wMDAwMjUtMi4xNjEzLS4wMDAwOC0xLjY1ODUtLjAwMDEyMSAxLjIzMjctLjAwMDA5IDYuMzE2OC0uMDAwMTM0IDcuMzg3LS4wMDAyMjUuNDAzOS0uMDAwMDQ0IDIuMDgtLjAwMDA3NCAzLjYwNzYtLjAwMDEwNC0uNDczODgtLjAwMDA2Ni0uODcwOTUtLjAwMDEzMy0uODk0MjMtLjAwMDIwMSAxLjIxMTYuMDAwMDE5IDIuNDE3Mi4wMDAwMzggMy42MDc3LjAwMDA1N3oiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wMDAzNTY4OCIvPjxwYXRoIGQ9Im0yMS40NyA3NC4xNDljLjMzNjM1LS4wMDAwNDUuOTU2MjMtLjAwMDA4OCAxLjg2OTUtLjAwMDEzIDEuNDc2MS4wMDAwMzUgMi45NDc0LjAwMDA3MSA0LjU0OTcuMDAwMTA0IDguMDA1OC0uMDAwMDA2IDE1Ljg2Ny4wMDAwNzEgMjAuNTA5LjAwMDE5OSA3LjE3NDcuMDAwMTk3IDEwLjAzNC4wMDA0NTkgNi43MDY2LjAwMDY5NS0xMS4wODcgMC0yMi4xNzQtLjAwMDAwMS0zMy4yNjEgMC0yLjI4MzItLjAwMDA0Mi0zLjExNDktLjAwMDExNC0uOTIxMzgtLjAwMDE2MyAzLjM5MzgtLjAwMDA3IDcuODkxNi0uMDAwMTIxIDEwLjI2My0uMDAwMjEtMi41ODAyLjAwMDAwNi01LjE3NDguMDAwMDEtNy43Njc1LjAwMDAwNi0xLjU5MTkuMDAwMDUtMy41ODMzLjAwMDExNi03LjA0NjguMDAwMTExLTIuMzE5LS4wMDAwMDUtNC44ODAyLjAwMDAwOS02Ljk1MTEtLjAwMDAxOC0yLjAzNzYtLjAwMDAyNS0yLjE2MTMtLjAwMDA4LTEuNjU4NS0uMDAwMTIxIDEuMjMyNy0uMDAwMDkgNi4zMTY4LS4wMDAxMzQgNy4zODctLjAwMDIyNS40MDM5LS4wMDAwNDQgMi4wOC0uMDAwMDc0IDMuNjA3Ni0uMDAwMTA0LS40NzM4OC0uMDAwMDY2LS44NzA5NS0uMDAwMTMzLS44OTQyMy0uMDAwMjAxIDEuMjExNi4wMDAwMTkgMi40MTcyLjAwMDAzOCAzLjYwNzcuMDAwMDU3eiIvPjxwYXRoIGQ9Im0yMy42NjcgNzQuMTQ5YzEuNjQyLjAwMDAyNSAzLjI1MDYuMDAwMDUxIDQuOTcwNS4wMDAwNzQgMS4zODQ5LS4wMDAwMDYgMi43NjktLjAwMDAxMiA0LjE1NTYtLjAwMDAxNy4zMzU3OS4wMDAwMTMuNjcyNS4wMDAwMjYgMS4wMTAxLjAwMDAzOGwyLjk2NjItLjAwMDAxNCAxLjA1NjIuMDAwMDQ1Yy4yMjEzOS4wMDAwMDkgMS40MzkxLS4wMDAwMDYgMS45MTg3LS4wMDAwMDguMjYzMjcuMDAwMDE3LjUyNzU5LjAwMDAzNC43OTI5NS4wMDAwNTEgMS4xMjc2LjAwMDAwMyAyLjI1NzUuMDAwMDA2IDMuMzg3OC4wMDAwMDkuMTk4NzYuMDAwMDIxLjM5OTE0LjAwMDA0My42MDAwMi4wMDAwNjQgMS4xNjgxLjAwMDAwNCAyLjMzNzMuMDAwMDA3IDMuNTA3Ny4wMDAwMTEtLjI4Mjc3LjAwMDAyMi0uNTY0MzYuMDAwMDQ0LS44NDQ3Ni4wMDAwNjYgMS4yODQ5LjAwMDAxNyAyLjU3MDguMDAwMDMzIDMuODU4MS4wMDAwNDktLjUwMTU2LjAwMDAyNS0xLjAwNDEuMDAwMDQ5LTEuNTA0Mi4wMDAwNzQgMS4zNDY5LjAwMDAxOCAyLjY5NTUuMDAwMDM2IDQuMDQ1Mi4wMDAwNTQtLjcwMzI3LjAwMDAyMy0xLjQwNzYuMDAwMDQ3LTIuMTA5MS4wMDAwNzEuOTA2NjguMDAwMDE4IDEuODE1MS4wMDAwMzcgMi43MjU0LjAwMDA1Ni0uODMwNjYuMDAwMDI2LTEuNjYwNy4wMDAwNTMtMi40ODkuMDAwMDguNzY5MDUuMDAwMDE2IDEuNTQwMy4wMDAwMzIgMi4zMTI2LjAwMDA0OC0uNTAyNzYuMDAwMDM2LTEuMDA0MS4wMDAwNzEtMS41MDU3LjAwMDEwNy0xMC4yNjctLjAwMDAwNy0yMC41NDMtLjAwMDAwNC0zMC44MTUtLjAwMDAwNS0uMjEzOTktLjAwMDAyNi0uOTA0NzYtLjAwMDA1OS4yNjkyNC0uMDAwMDggMy4zNDYyLS4wMDAwNiA3LjI3MjktLjAwMDExMSA5LjY2NzQtLjAwMDE4OSAxLjI2NDQtLjAwMDA0IDEuNzIyOC0uMDAwMDg3IDIuMzE5LS4wMDAxMzItNC4wNDExLjAwMDA1NS04LjM0OS4wMDAwNDctMTIuODc0LjAwMDAzIDEuMzk5OS4wMDAwNjgtMS44Nzk2LjAwMDEwOS01LjA0MDEuMDAwMTI0LjAxMzA1LS4wMDAwMTUuMDM5MTItLjAwMDA0NS4wNTIxNy0uMDAwMDYtMS4yNjY0LjAwMDAxOS0yLjQ5NDEuMDAwMDM5LTMuNzEzNC4wMDAwNTktMi40OTg0LS4wMDAwMTktMy4wOTEyLS4wMDAwNzctMS44NTUzLS4wMDAxMiAxLjYyMjMtLjAwMDA0NiA0LjEwODgtLjAwMDA4IDUuNDEzMS0uMDAwMTMuODA2OTctLjAwMDA0MiAxLjE2MTMtLjAwMDA4OCAyLjcwOTEtLjAwMDEyMiAxLjUxMzktLjAwMDAzNCAyLjcwNzUtLjAwMDA3MiAzLjgwMDktLjAwMDExMiAxLjE3ODYuMDAwMDE1IDIuMzU3NC4wMDAwMyAzLjU3ODcuMDAwMDQzLS43MjI3MS0uMDAwMDU3LTMuNDQ1OC0uMDAwMTAxLTIuMzY1OS0uMDAwMTY0eiIvPjxwYXRoIGQ9Im0xOS44MjggNzQuMTQ5YzEuNjM4LS4wMDAwMTUgMi4zNjQ4LjAwMDAxOCAyLjI3MTkuMDAwMDQ1LTEuNTIzMS4wMDAwMzEtMy4yMTY5LS4wMDAwMTUtMi4yNzE5LS4wMDAwNDV6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDAwMzU2ODgiLz48cGF0aCBkPSJtMTkuODI4IDc0LjE0OWMxLjYzOC0uMDAwMDE1IDIuMzY0OC4wMDAwMTggMi4yNzE5LjAwMDA0NS0xLjUyMzEuMDAwMDMxLTMuMjE2OS0uMDAwMDE1LTIuMjcxOS0uMDAwMDQ1eiIvPjxwYXRoIGQ9Im0yMi4wMTIgNzQuMTQ5YzEuNTA4NS0uMDAwMDI3IDMuODk1My4wMDAwMDUgNS42OTYuMDAwMDE1LTEuOTkyMy4wMDAwMjItNC44NTIzLjAwMDA2LTYuNDQ4Ny4wMDAwNDEtLjY0NjYxLS4wMDAwMDguMDYxLS4wMDAwNDMuNzUyNzctLjAwMDA1NnoiLz48cGF0aCBkPSJtMTIuNjQgNzQuMTVjLjY3Nzk2LS4wMDAwMTIgMi43MDY3LS4wMDAwMDMgMS43MzA4LjAwMDAxOS0uOTAzNjkuMDAwMDMxLTMuOTA2OS4wMDAwMDUtMS43MzA4LS4wMDAwMTl6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDAwMzU2ODgiLz48cGF0aCBkPSJtMTIuNjQgNzQuMTVjLjY3Nzk2LS4wMDAwMTIgMi43MDY3LS4wMDAwMDMgMS43MzA4LjAwMDAxOS0uOTAzNjkuMDAwMDMxLTMuOTA2OS4wMDAwMDUtMS43MzA4LS4wMDAwMTl6Ii8+PHBhdGggZD0ibTI1LjE0IDI0LjdjMS4yNjI2LTIuMjAwMyA0LjkyOTItMS44NjYgNS43NjQ0LjU0MTYuNzExMTEgMS41OTAyLS41OTA0MyAzLjAxNDQtMS4xNTEzIDQuNDE1My44MTYzNi43NzQgMS42MzUgMS41NDc1IDIuNDU2NiAyLjMyMDEuODY2NjgtLjg5NDQ3IDEuNzI5Mi0xLjc5MzUgMi41ODktMi42OTc0LS4zNjE2Mi0xLjQwMjctMS41MjYxLTIuOTUzMi0uNjE1MjgtNC4zNzkgMS4wNTI1LTIuMTE3NiA0LjQ3NDktMi4yOTQ4IDUuNjQxNS0uMTg3ODEgMS4wNzc3IDEuNDQxNS0uMDMzMzUgMy4xMDMxLS40NTE1MiA0LjU1NiAyLjU1ODQgMy40MjY1IDQuOTY3NCA3LjA5MzEgNi4wNTgxIDExLjI3OSAxLjQzMTkgNS4yMTgzLjUzNTcyIDEwLjc3OC0xLjI0NDYgMTUuNzk1LTEuMzAxIDMuMTI1My0uNzg0NzggNi41ODkxLTEuMzg4MyA5Ljg1OTYgNC41MTcyLS41NjgyIDkuNjkzNy0xLjU2NjQgMTMuNzYyIDEuMDgzMiAyLjI1MjIgMS41MDY5IDIuMDE0MSA0LjQzODQgMS45NTkzIDYuODAxNWgtLjkwOTM3Yy02LjE1NS0xLjc5Mi0xMi42MDItMS4zNS0xOC45MjEtMS4xOTItMy4xOTYtNC4xMjYtMTAuMDIzLTQuMDg5LTEzLjIzMyAwLTYuMzA0LS4xNTEtMTIuNzQ1LS42MDctMTguODggMS4xOTJoLTEuMTI5M2MuMTY0OC0yLjM1NS0uMTAzNC01LjI5NSAyLjE0MjQtNi43OTcgNC4wNjY5LTIuNjUgOS4yNDI5LTEuNjU5IDEzLjc2MS0xLjA4OC0uMzY5LTIuNTMzLS41NDEtNS4wODktLjU0Ni03LjY0OC0yLjM1MS00LjI2NC00LjQzOS05LjEzNC0zLjQ5My0xNC4xMDMgMS4xNjgtNS42NTkgNC44NDQtMTAuMzIgOC4zMjctMTQuNzYyLS4zODItMS41OTMtMS42MDItMy40MTctLjQ5OC00Ljk5eiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4MDIyIi8+PC9nPjxwYXRoIGQ9Im0yNS4xNCAyNC43YzEuMjYyNi0yLjIwMDMgNC45MjkyLTEuODY2IDUuNzY0NC41NDE2LjcxMTExIDEuNTkwMi0uNTkwNDMgMy4wMTQ0LTEuMTUxMyA0LjQxNTMuODE2MzYuNzc0IDEuNjM1IDEuNTQ3NSAyLjQ1NjYgMi4zMjAxLjg2NjY4LS44OTQ0NyAxLjcyOTItMS43OTM1IDIuNTg5LTIuNjk3NC0uMzYxNjItMS40MDI3LTEuNTI2MS0yLjk1MzItLjYxNTI4LTQuMzc5IDEuMDUyNS0yLjExNzYgNC40NzQ5LTIuMjk0OCA1LjY0MTUtLjE4NzgxIDEuMDc3NyAxLjQ0MTUtLjAzMzM1IDMuMTAzMS0uNDUxNTIgNC41NTYgMi41NTg0IDMuNDI2NSA0Ljk2NzQgNy4wOTMxIDYuMDU4MSAxMS4yNzkgMS40MzE5IDUuMjE4My41MzU3MiAxMC43NzgtMS4yNDQ2IDE1Ljc5NS0xLjMwMSAzLjEyNTMtLjc4NDc4IDYuNTg5MS0xLjM4ODMgOS44NTk2IDQuNTE3Mi0uNTY4MiA5LjY5MzctMS41NjY0IDEzLjc2MiAxLjA4MzIgMi4yNTIyIDEuNTA2OSAyLjAxNDEgNC40Mzg0IDEuOTU5MyA2LjgwMTVoLS45MDkzN2MtNi4xNTUtMS43OTItMTIuNjAyLTEuMzUtMTguOTIxLTEuMTkyLTMuMTk2LTQuMTI2LTEwLjAyMy00LjA4OS0xMy4yMzMgMC02LjMwNC0uMTUxLTEyLjc0NS0uNjA3LTE4Ljg4IDEuMTkyaC0xLjEyOTNjLjE2NDgtMi4zNTUtLjEwMzQtNS4yOTUgMi4xNDI0LTYuNzk3IDQuMDY2OS0yLjY1IDkuMjQyOS0xLjY1OSAxMy43NjEtMS4wODgtLjM2OS0yLjUzMy0uNTQxLTUuMDg5LS41NDYtNy42NDgtMi4zNTEtNC4yNjQtNC40MzktOS4xMzQtMy40OTMtMTQuMTAzIDEuMTY4LTUuNjU5IDQuODQ0LTEwLjMyIDguMzI3LTE0Ljc2Mi0uMzgyLTEuNTkzLTEuNjAyLTMuNDE3LS40OTgtNC45OXoiLz48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJtMjYuNjA3IDI1LjQ3NWMuODYzNzYtLjc2OTQ5IDIuNTY2My0uNzU1MTQgMi40NDk5Ljc0MTAxLjA2Mjc3IDIuMjUtMy4zNjA4IDEuMjk0OS0yLjQ0OTktLjc0MTAxeiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4MDIyIi8+PHBhdGggZD0ibTI2LjYwNyAyNS40NzVjLjg2Mzc2LS43Njk0OSAyLjU2NjMtLjc1NTE0IDIuNDQ5OS43NDEwMS4wNjI3NyAyLjI1LTMuMzYwOCAxLjI5NDktMi40NDk5LS43NDEwMXoiLz48cGF0aCBkPSJtMzUuODU1IDI1LjY3OWMxLjM0MDgtMS45MzgyIDIuODkxOC4xODYwMSAyLjQzNTUgMS43ODk1LTEuMjcwMS4xMjkzNi0yLjkxNDgtLjEzMjAzLTIuNDM1NS0xLjc4OTV6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDgwMjIiLz48cGF0aCBkPSJtMzUuODU1IDI1LjY3OWMxLjM0MDgtMS45MzgyIDIuODkxOC4xODYwMSAyLjQzNTUgMS43ODk1LTEuMjcwMS4xMjkzNi0yLjkxNDgtLjEzMjAzLTIuNDM1NS0xLjc4OTV6Ii8+PHBhdGggZD0ibTMzLjMxIDMzLjc5M2MxLjI3ODMtMS4zMzMyIDIuNTQ2MS0yLjY3NyAzLjgwODEtNC4wMjczIDIuODAzNCA0LjAyMTEgNS42NTgzIDguMjM2OCA2LjU1NjQgMTMuMTUyLjY2NDQyIDMuMzI5Ni4yMDU3MyA2Ljc0ODgtLjY0MDA5IDkuOTk5Ny0uODA0MTktNy4zNTI5LTQuNTY2NC0xMy45NDctOS43MjQzLTE5LjEyNXoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODAyMiIvPjxwYXRoIGQ9Im0zMy4zMSAzMy43OTNjMS4yNzgzLTEuMzMzMiAyLjU0NjEtMi42NzcgMy44MDgxLTQuMDI3MyAyLjgwMzQgNC4wMjExIDUuNjU4MyA4LjIzNjggNi41NTY0IDEzLjE1Mi42NjQ0MiAzLjMyOTYuMjA1NzMgNi43NDg4LS42NDAwOSA5Ljk5OTctLjgwNDE5LTcuMzUyOS00LjU2NjQtMTMuOTQ3LTkuNzI0My0xOS4xMjV6Ii8+PHBhdGggZD0ibTI3LjczMSAzMC40M2M1LjE2NjQgNS4wNjM0IDkuOTIzNiAxMC44MzcgMTIuNDk2IDE3LjY3Ny45ODgyOSAyLjQ0ODUuOTE2NzYgNS4xMzg3LjIxNjMzIDcuNjQ5OC01Ljc2ODUtMi4xNzAyLTEyLjI5MS0yLjA5MjYtMTguMDktLjA3MTc5LTIuMzgxMi0yLjg4MDEtMy45OTIyLTYuNjc1Ny0yLjk4MzgtMTAuNDQ2IDEuNDE4OS01LjUzMjYgNC4xODQtMTAuODUzIDguMzYwOS0xNC44MDl6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDgwMjIiLz48cGF0aCBkPSJtMjcuNzMxIDMwLjQzYzUuMTY2NCA1LjA2MzQgOS45MjM2IDEwLjgzNyAxMi40OTYgMTcuNjc3Ljk4ODI5IDIuNDQ4NS45MTY3NiA1LjEzODcuMjE2MzMgNy42NDk4LTUuNzY4NS0yLjE3MDItMTIuMjkxLTIuMDkyNi0xOC4wOS0uMDcxNzktMi4zODEyLTIuODgwMS0zLjk5MjItNi42NzU3LTIuOTgzOC0xMC40NDYgMS40MTg5LTUuNTMyNiA0LjE4NC0xMC44NTMgOC4zNjA5LTE0LjgwOXoiLz48cGF0aCBkPSJtMjMuMDM3IDU4LjAwOWM0LjAyMDEtMi4xMDUgOC43ODc4LTEuNjk1IDEzLjE2Ny0xLjQzODMgMS43MjU1LjM1ODQyIDQuMjE0My4yNDc5MyA0Ljk4NzYgMi4xOTExLS4zNDEwNS40MzM3Mi0xLjAyMzEgMS4zMDEyLTEuMzY0MiAxLjczNDkuNzI4MDUgMS4wNTM0IDEuMTA4NCAyLjI2OTUgMS40NDcxIDMuNDkzMi02LjA3NDYtMS4wOTEzLTEyLjMyOC0xLjA5LTE4LjQwMi0uMDAwMDI1LjMzMDU1LTEuMjExNy43MTAxMS0yLjQxNjcgMS40MzMzLTMuNDU5LS42OTk3OC0uNzE0MTMtMS4xMjI4LTEuNTU0Ny0xLjI2OTEtMi41MjE5eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4MDIyIi8+PHBhdGggZD0ibTIzLjAzNyA1OC4wMDljNC4wMjAxLTIuMTA1IDguNzg3OC0xLjY5NSAxMy4xNjctMS40MzgzIDEuNzI1NS4zNTg0MiA0LjIxNDMuMjQ3OTMgNC45ODc2IDIuMTkxMS0uMzQxMDUuNDMzNzItMS4wMjMxIDEuMzAxMi0xLjM2NDIgMS43MzQ5LjcyODA1IDEuMDUzNCAxLjEwODQgMi4yNjk1IDEuNDQ3MSAzLjQ5MzItNi4wNzQ2LTEuMDkxMy0xMi4zMjgtMS4wOS0xOC40MDItLjAwMDAyNS4zMzA1NS0xLjIxMTcuNzEwMTEtMi40MTY3IDEuNDMzMy0zLjQ1OS0uNjk5NzgtLjcxNDEzLTEuMTIyOC0xLjU1NDctMS4yNjkxLTIuNTIxOXoiLz48cGF0aCBkPSJtMzAuNzExIDU5LjEzNWMxLjI2ODctLjQ4Mjk2IDMuMTc1Ny0uNDM1NzggMy41MzE1IDEuMTczNC0xLjI5MjIuODI0OTQtMi45MDE1LjgwMTk1LTQuMjQ4OS4xMjc5NS4xNzkzNS0uMzI1MzQuNTM4MDYtLjk3Ni43MTc0MS0xLjMwMTN6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDgwMjIiLz48L2c+PHBhdGggZD0ibTMwLjcxMSA1OS4xMzVjMS4yNjg3LS40ODI5NiAzLjE3NTctLjQzNTc4IDMuNTMxNSAxLjE3MzQtMS4yOTIyLjgyNDk0LTIuOTAxNS44MDE5NS00LjI0ODkuMTI3OTUuMTc5MzUtLjMyNTM0LjUzODA2LS45NzYuNzE3NDEtMS4zMDEzeiIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im0yMy44MzggNjYuMTI0YzUuMjQzOS0xLjczNDIgMTEuMjI1LTEuNzM1NyAxNi40NjguMDAzNC0yLjI0MDIgMi4wNDgzLTUuNDMzMSAxLjYzNzQtOC4yMjUzIDEuNzYxNi0yLjc5OTctLjEyMzMyLTYuMDAyOS4yOTE0NS04LjI0MjktMS43NjUxeiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4MDIyIi8+PHBhdGggZD0ibTIzLjgzOCA2Ni4xMjRjNS4yNDM5LTEuNzM0MiAxMS4yMjUtMS43MzU3IDE2LjQ2OC4wMDM0LTIuMjQwMiAyLjA0ODMtNS40MzMxIDEuNjM3NC04LjIyNTMgMS43NjE2LTIuNzk5Ny0uMTIzMzItNi4wMDI5LjI5MTQ1LTguMjQyOS0xLjc2NTF6Ii8+PHBhdGggZD0ibTYuODc4MSA3MS4zMzFjLjYzNzU3LTEuOTc2IDIuMjE3OC0zLjQxOTcgNC4zMjY4LTMuNTQxOSA1LjU5MjMtLjY3NjEyIDExLjI2OC4zMDA0IDE2LjY5MyAxLjY1MjEtNi43MTM1IDIuMzc2OS0xNC4wMjQgMS41NjI5LTIxLjAyIDEuODg5OHoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODAyMiIvPjxwYXRoIGQ9Im02Ljg3ODEgNzEuMzMxYy42Mzc1Ny0xLjk3NiAyLjIxNzgtMy40MTk3IDQuMzI2OC0zLjU0MTkgNS41OTIzLS42NzYxMiAxMS4yNjguMzAwNCAxNi42OTMgMS42NTIxLTYuNzEzNSAyLjM3NjktMTQuMDI0IDEuNTYyOS0yMS4wMiAxLjg4OTh6Ii8+PHBhdGggZD0ibTM2LjI1NSA2OS40MjhjNS42NTUyLTEuMzM4OSAxMS41OTctMi40ODIzIDE3LjM5Ny0xLjQ5MzEgMS44ODc2LjE5OTY5IDIuOTU1NiAxLjc3MDkgMy42MjI2IDMuMzk1Ni02Ljk5MzQtLjMzNjM3LTE0LjMxOC41MDk5NC0yMS4wMi0xLjkwMjV6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDgwMjIiLz48cGF0aCBkPSJtMzYuMjU1IDY5LjQyOGM1LjY1NTItMS4zMzg5IDExLjU5Ny0yLjQ4MjMgMTcuMzk3LTEuNDkzMSAxLjg4NzYuMTk5NjkgMi45NTU2IDEuNzcwOSAzLjYyMjYgMy4zOTU2LTYuOTkzNC0uMzM2MzctMTQuMzE4LjUwOTk0LTIxLjAyLTEuOTAyNXoiLz48L2c+PC9nPjwvc3ZnPg=='); } -body.base .is2d piece.rook.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMTUuMDM5IDI2Ljc4NWMyLjEwMzctLjAwMDA5NiA0LjIwODgtLjAwMDEzMiA2LjMxNTQtLjAwMDEzMi0uMDAxOSAxLjU3OS0uMDAyNSAzLjE1NzgtLjAwMDUzNiA0LjczNjkgMi4xMDQtLjAwMDIxNyA0LjIwOTMtLjAwMDI1MiA2LjMxNjQtLjAwMDI4OS0uMDAyMS0xLjU3OS0uMDAyNS0zLjE1NzgtLjAwMDU2LTQuNzM2NyAyLjkzMDYuMDAwMTQ1IDUuODYyMi4wMDAyMDUgOC43OTUxLjAwMDYwMi0uMDAxOSAxLjU3ODYtLjAwMjMgMy4xNTctLjAwMDMzOSA0LjczNTcgMi4wNjY3LjAwMDA4NCA0LjEzNDcuMDAwNDkzIDYuMjA0Ni4wMDA4NzYtLjAwMjEtMS41NzkyLS4wMDI3LTMuMTU4MS0uMDAwNDUtNC43MzcxIDIuMTAzNS4wMDAwNzEgNC4yMDg1LjAwMDA3MSA2LjMxNTQuMDAwMDU5LS4wMDE3IDMuMTc3Ni0uMDAxNiA2LjM1NSAwIDkuNTMyNi0xLjMxOCAxLjQ3NzUtMi42MzQxIDIuOTU1NS0zLjk0OTEgNC40MzM2LjAwNTcgNi4yODkzLS4wMDQ1IDEyLjU3OS4wMDUgMTguODY4IDIuNDgxNCAyLjc4MDIgMy41NTk1IDUuNTYyOSA2LjI4OTIgOC4wNzIyLS4wMDA0OTYgMi4xNTIzLjAwMDU0NiA0LjMwNDkuMDAxNCA2LjQ1ODEtMTIuODg3LjAwMS0yNS43NzMuMDAxLTM4LjY2LjAwMS0uMDAwODc2LTIuMTQ2NS0uMDAwODc2LTQuMjkyNi4wMDA4NzYtNi40MzgzIDMuMDk3My0xLjkzOTEgMy42MjI3LTUuNzY0IDYuMzA5My04LjEwNzkuMDEyNTgtNi4yMzg4LjAwMTItMTIuNDc3LjAwNjEtMTguNzE2LTEuMzE4Ny0xLjQ2OTMtMi42MzUtMi45Mzk1LTMuOTUwMS00LjQwOTkuMDAzNC0zLjIzMDkuMDAyLTYuNDYxNi4wMDIzLTkuNjkyNHoiLz48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJtMTcuNDA4IDI5LjE1MmMuNTA4NTcuMDAwNzEgMS41MjU3LjAwMjEgMi4wMzQzLjAwMjgtLjAwMjcgMS41NzgxLS4wMDMzIDMuMTU2MS0uMDAxMyA0LjczNDQgMy41MzE1LjAwMDYwMyA3LjA2MzguMDAwMTIgMTAuNTk3LjAwMDQyMi0uMDAyLTEuNTc5MS0uMDAyMy0zLjE1NzktLjAwMDIxNC00LjczNjggMS4zOTk0LjAwMDEzMiAyLjc5OTkuMDAwMjc4IDQuMjA0My4wMDA3MS0uMDAxOSAxLjU3ODUtLjAwMjUgMy4xNTY5LS4wMDA4MDMgNC43MzU2IDMuNTk3Ni4wMDA2NTEgNy4xOTYuMDAwMzYyIDEwLjc5NS4wMDAzNS0uMDAyMi0xLjU3ODktLjAwMjMtMy4xNTc2LjAwMDA3Mi00LjczNjMuMzk0NzEtLjAwMDA3MyAxLjE4NDEtLjAwMDE5MiAxLjU3ODgtLjAwMDI2NS0uMDAxMiAyLjI1NTItLjAwMTIgNC41MTAzLS4wMDIyIDYuNzY1Ni0xLjMwOTUgMS4xNjQ5LTIuNjE2MiAyLjMzMDUtMy45MjE2IDMuNDk3LTcuNjM5LS4wMDAxNDUtMTUuMjc3LS4wMDAyOS0yMi45MTYuMDAwMDYtLjc5MTQzLS44ODE5NS0xLjU4MTQtMS43NjQxLTIuMzY4Ni0yLjY0NjEtLjAwMDgwMy0yLjUzOTMtLjAwMjgtNS4wNzg0LjAwMDMtNy42MTc1eiIvPjxwYXRoIGQ9Im0yMS4zNTQgNDEuNzg0YzcuMTA0My0uMDAwMDEyIDE0LjIwOS0uMDAwMDk2IDIxLjMxNC4wMDAwMzYtLjAwMDUwNSA1LjUyNTktLjAwMDY4NyAxMS4wNTIuMDAwMTAyIDE2LjU3OC03LjEwNTMtLjAwMDI0MS0xNC4yMS0uMDAwMDYtMjEuMzE0LS4wMDAwOTYtLjAwMDU2Mi01LjUyNi0uMDAwNTE0LTExLjA1Mi0uMDAwMDQxLTE2LjU3OHoiLz48cGF0aCBkPSJtMjAuODE0IDYwLjcxOWM3LjQ3ODUuMDIzOTggMTQuOTU3LjAwNzcgMjIuNDM3LjAwODYgMi4zMjA0IDIuMTkxMSAzLjM0MzMgNC44MDQzIDUuNzMyMiA2Ljk4NDQtLjAwMzEgMS4zNTYxLS4wMDIxIDIuNzEyOC4wMDIyIDQuMDcwMi0xMS4zMTYtLjAwMDIxNi0yMi42MzItLjAwMDMyNS0zMy45NDcuMDAwMDQ4LS4wMDA5NDktMS4zNTY4LS4wMDA2MTYtMi43MTI4LjAwMjMtNC4wNjg0IDIuNzY2OC0xLjY3NzYgMy4zNDUtNS4wMDc5IDUuNzczOC02Ljk5NDl6Ii8+PC9nPjwvZz48L3N2Zz4='); } -body.base .is2d piece.queen.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMTkuNzEgMjYuNTAzYy4yNDg2Ni0zLjQzMjQgNS4yNTU2LTQuNTQ2NCA3LjEzODItMS43OTQ3IDEuMjc4OSAxLjUyNTUuNDE5MDggMy40ODE5LS4xNTg3MiA1LjA5NTEgMS42OTQ4IDMuNTEzNSAzLjQzODQgNy4wMDM1IDUuMTY1MiAxMC41MDIgMS44MzYtMy41MTg3IDMuNjY0OC03LjA0MTQgNS41MDYxLTEwLjU1OC0uNTQzMjQtMS40OTc3LTEuNDMzMy0zLjIwMDctLjQyNzM0LTQuNzI2MSAxLjY5NTItMy4wODc3IDcuMjEwNC0yLjE1MzYgNy40MzE0IDEuNDg5NC4zNzMwOCAxLjk4NC0xLjMxNTUgMy4yNDQ4LTIuNjM3OSA0LjM0NzIgMS4yNjMgNS4xOTE5IDIuNTMzNyAxMC4zODIgMy44MDQ5IDE1LjU3MiAyLjQzNDMtMS44Nzc0IDQuODgzNS0zLjczNjkgNy4yOTU4LTUuNjQ1NS0uMDE0MTUtMS42MTI3LS4zMzE0NC0zLjY3NzMgMS4zNDI3LTQuNjI0OSAyLjA5NTctMS41Njg4IDUuNDE0MS4zMjU3NCA1LjEyNDEgMi45MjgxLjA4NDU1IDIuMDE0My0xLjk1OSAyLjc3Mi0zLjQxNDMgMy41NDMyLTEuOTQ5NCA0LjMwODctNC4wODUyIDguNTQ1Mi01LjgxNyAxMi45NDQtLjc1NDQ5IDQuODE1NC0uOTI5NzIgOS43MDg2LTEuNTMxOCAxNC41NDctNi40NDA4IDQuMDEzNC0xNC4zMzYgNC4zMDgxLTIxLjY4OCAzLjc0ODktNC4wMTgtLjI3Ny04LjA0Mi0xLjMyMy0xMS4zNTEtMy42OTUtLjcwMS00Ljg2NC0uOTkyLTkuNzg5LTEuODUyLTE0LjYyNS0xLjY1NS00LjM5OS0zLjY3ODgtOC42NTUtNS41NDk1LTEyLjk2NS0xLjQ2NDQtLjcxOC0zLjQyMjctMS40ODYtMy4zNzk0LTMuNDUyLS4zNjA3LTIuODA2IDMuNDE4NS00LjY4NiA1LjQ0MzktMi43MjQgMS40NDcxIDEuMDEzMS45NjU4OSAyLjg3MDMuOTM0NjEgNC4zNTM3IDIuMzY1NCAxLjg4MzYgNC43MjE2IDMuNzc5MiA3LjA4NDMgNS42NjkxIDEuMzY3NC01LjIwMiAyLjc0NjUtMTAuNDAxIDQuMTA1OC0xNS42MDUtMS4zMjI1LTEuMDg5Ni0yLjk0NjItMi4zNjYtMi41NzA3LTQuMzIyNXoiIGZpbGw9IiNmZmYiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODQyNDciLz48cGF0aCBkPSJtMTkuNzEgMjYuNTAzYy4yNDg2Ni0zLjQzMjQgNS4yNTU2LTQuNTQ2NCA3LjEzODItMS43OTQ3IDEuMjc4OSAxLjUyNTUuNDE5MDggMy40ODE5LS4xNTg3MiA1LjA5NTEgMS42OTQ4IDMuNTEzNSAzLjQzODQgNy4wMDM1IDUuMTY1MiAxMC41MDIgMS44MzYtMy41MTg3IDMuNjY0OC03LjA0MTQgNS41MDYxLTEwLjU1OC0uNTQzMjQtMS40OTc3LTEuNDMzMy0zLjIwMDctLjQyNzM0LTQuNzI2MSAxLjY5NTItMy4wODc3IDcuMjEwNC0yLjE1MzYgNy40MzE0IDEuNDg5NC4zNzMwOCAxLjk4NC0xLjMxNTUgMy4yNDQ4LTIuNjM3OSA0LjM0NzIgMS4yNjMgNS4xOTE5IDIuNTMzNyAxMC4zODIgMy44MDQ5IDE1LjU3MiAyLjQzNDMtMS44Nzc0IDQuODgzNS0zLjczNjkgNy4yOTU4LTUuNjQ1NS0uMDE0MTUtMS42MTI3LS4zMzE0NC0zLjY3NzMgMS4zNDI3LTQuNjI0OSAyLjA5NTctMS41Njg4IDUuNDE0MS4zMjU3NCA1LjEyNDEgMi45MjgxLjA4NDU1IDIuMDE0My0xLjk1OSAyLjc3Mi0zLjQxNDMgMy41NDMyLTEuOTQ5NCA0LjMwODctNC4wODUyIDguNTQ1Mi01LjgxNyAxMi45NDQtLjc1NDQ5IDQuODE1NC0uOTI5NzIgOS43MDg2LTEuNTMxOCAxNC41NDctNi40NDA4IDQuMDEzNC0xNC4zMzYgNC4zMDgxLTIxLjY4OCAzLjc0ODktNC4wMTgtLjI3Ny04LjA0Mi0xLjMyMy0xMS4zNTEtMy42OTUtLjcwMS00Ljg2NC0uOTkyLTkuNzg5LTEuODUyLTE0LjYyNS0xLjY1NS00LjM5OS0zLjY3ODgtOC42NTUtNS41NDk1LTEyLjk2NS0xLjQ2NDQtLjcxOC0zLjQyMjctMS40ODYtMy4zNzk0LTMuNDUyLS4zNjA3LTIuODA2IDMuNDE4NS00LjY4NiA1LjQ0MzktMi43MjQgMS40NDcxIDEuMDEzMS45NjU4OSAyLjg3MDMuOTM0NjEgNC4zNTM3IDIuMzY1NCAxLjg4MzYgNC43MjE2IDMuNzc5MiA3LjA4NDMgNS42NjkxIDEuMzY3NC01LjIwMiAyLjc0NjUtMTAuNDAxIDQuMTA1OC0xNS42MDUtMS4zMjI1LTEuMDg5Ni0yLjk0NjItMi4zNjYtMi41NzA3LTQuMzIyNXoiLz48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJtMjIuOTUzIDI1LjEwMmMyLjY1MjItMS4zMDM0IDMuOTUxNCAzLjQ1MDMgMS4yMDg0IDMuODIxNi0yLjQ1MzcuNzY0MzYtMy41MDQ3LTMuMDA2Ni0xLjIwODQtMy44MjE2eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4NDI0NyIvPjxwYXRoIGQ9Im0yMi45NTMgMjUuMTAyYzIuNjUyMi0xLjMwMzQgMy45NTE0IDMuNDUwMyAxLjIwODQgMy44MjE2LTIuNDUzNy43NjQzNi0zLjUwNDctMy4wMDY2LTEuMjA4NC0zLjgyMTZ6Ii8+PHBhdGggZD0ibTM5LjA4MiAyNS4zMDdjMS40NDgzLS45Mjk3OCAzLjc3NzguMDAzMiAzLjM1NDQgMS45MzA2LS4wMjgwOCAxLjc3MzYtMi4yMDgyIDIuMDg3NC0zLjQ2OCAxLjM0ODUtLjY0MDI2LS45NjgyNi0uODE0ODctMi40MjU0LjExMzU1LTMuMjc5MXoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODQyNDciLz48cGF0aCBkPSJtMzkuMDgyIDI1LjMwN2MxLjQ0ODMtLjkyOTc4IDMuNzc3OC4wMDMyIDMuMzU0NCAxLjkzMDYtLjAyODA4IDEuNzczNi0yLjIwODIgMi4wODc0LTMuNDY4IDEuMzQ4NS0uNjQwMjYtLjk2ODI2LS44MTQ4Ny0yLjQyNTQuMTEzNTUtMy4yNzkxeiIvPjxwYXRoIGQ9Im0xOS4xNDggNDkuNzA3YzIuMDM0LTYuNDA5IDMuMDYzOS0xMy4xNzUgNS44MjIyLTE5LjMyNiAyLjQ0OTUgNC42MTI3IDQuNTcxOSA5LjM4OTEgNi44ODM2IDE0LjA3MiAyLjMzNDQtNC42NTE0IDQuNTI4NC05LjM3NDQgNi45Njg0LTEzLjk3MyAxLjA0MzQgMS4wOTM4IDEuNTA4IDIuNTI2MyAxLjg1NjggMy45NjAxIDEuMjc2MSA1LjA5NjYgMi42MDEzIDEwLjE4MSAzLjkxNTkgMTUuMjY4IDMuMTA3NC0yLjQzODYgNi4yMTEzLTQuODgyNSA5LjMyMi03LjMxOTEtMS44MjU3IDMuOTAyOC0zLjY5MDYgNy43ODY2LTUuNTA4MyAxMS42OTMtMTAuNTA0LTQuMzE3NS0yMi41ODEtNC4xNDA3LTMzLjEwNy4wMDY0LTEuODc2MS00LjExMDgtMy43ODcxLTguMjA1LTUuNjctMTIuMzEyIDMuMTc2NCAyLjYzNzYgNi4zNDMzIDUuMjg3NSA5LjUxNjUgNy45MzExeiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4NDI0NyIvPjxwYXRoIGQ9Im0xOS4xNDggNDkuNzA3YzIuMDM0LTYuNDA5IDMuMDYzOS0xMy4xNzUgNS44MjIyLTE5LjMyNiAyLjQ0OTUgNC42MTI3IDQuNTcxOSA5LjM4OTEgNi44ODM2IDE0LjA3MiAyLjMzNDQtNC42NTE0IDQuNTI4NC05LjM3NDQgNi45Njg0LTEzLjk3MyAxLjA0MzQgMS4wOTM4IDEuNTA4IDIuNTI2MyAxLjg1NjggMy45NjAxIDEuMjc2MSA1LjA5NjYgMi42MDEzIDEwLjE4MSAzLjkxNTkgMTUuMjY4IDMuMTA3NC0yLjQzODYgNi4yMTEzLTQuODgyNSA5LjMyMi03LjMxOTEtMS44MjU3IDMuOTAyOC0zLjY5MDYgNy43ODY2LTUuNTA4MyAxMS42OTMtMTAuNTA0LTQuMzE3NS0yMi41ODEtNC4xNDA3LTMzLjEwNy4wMDY0LTEuODc2MS00LjExMDgtMy43ODcxLTguMjA1LTUuNjctMTIuMzEyIDMuMTc2NCAyLjYzNzYgNi4zNDMzIDUuMjg3NSA5LjUxNjUgNy45MzExeiIvPjxwYXRoIGQ9Im02LjY5NDMgMzcuNjE0YzEuOTcwNC0xLjAwNTcgMy4zNTMzLjYwMTg1IDIuNTk4MyAyLjQ3NzgtMS44MjE5IDEuMzI4Mi0zLjgxMzctLjYzMzkyLTIuNTk4My0yLjQ3Nzh6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDg0MjQ3Ii8+PHBhdGggZD0ibTYuNjk0MyAzNy42MTRjMS45NzA0LTEuMDA1NyAzLjM1MzMuNjAxODUgMi41OTgzIDIuNDc3OC0xLjgyMTkgMS4zMjgyLTMuODEzNy0uNjMzOTItMi41OTgzLTIuNDc3OHoiLz48cGF0aCBkPSJtNTQuNDU4IDQwLjU5OWMuMDQyNy0xLjE5MTQtLjI0MjA5LTMuNTExNyAxLjcxOS0zLjAyMTUgMS4xMzY5LS4zNTE2NCAxLjQ1MTggMS4yMjEgMS4yOTY3IDIuMDAxMi0uMTIzMjQgMS40NTQtMi4xMTg3LjczMzkxLTMuMDE1NyAxLjAyMDN6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDg0MjQ3Ii8+PHBhdGggZD0ibTU0LjQ1OCA0MC41OTljLjA0MjctMS4xOTE0LS4yNDIwOS0zLjUxMTcgMS43MTktMy4wMjE1IDEuMTM2OS0uMzUxNjQgMS40NTE4IDEuMjIxIDEuMjk2NyAyLjAwMTItLjEyMzI0IDEuNDU0LTIuMTE4Ny43MzM5MS0zLjAxNTcgMS4wMjAzeiIvPjxwYXRoIGQ9Im0xNi4yMTEgNTYuMTM0YzkuODAyMy00LjM1ODQgMjEuNTEzLTQuMzc1NSAzMS4zMTIuMDAxMy0uMTAwNTEgMS4zMjI3LS4xOTgxMSAyLjY0NTYtLjI5MTU1IDMuOTY5My0xLjE0MzIuMDAxOC0yLjI4MjQuMDA0NS0zLjQxNzcuMDA3OS45ODEwMyAxLjExMDcgMS45Njk5IDIuMjIxMiAyLjk1NTEgMy4zMzM5LjAxMTQ3LjcxMzAxLjAzNDQgMi4xMzkuMDQ1ODggMi44NTItMy4wNzItMS40OTUzLTYuNDIwMi0yLjM0MTItOS44MjI0LTIuNTgxMi02LjczNTQtLjUzMTU4LTEzLjg4Ni0uNTg4MzktMjAuMDQ5IDIuNTc2OC4wMDctLjcxMDA4LjAyMDk2LTIuMTMwMi4wMjc5NC0yLjg0MDMuOTgzNC0xLjExNTMgMS45Njg3LTIuMjI4IDIuOTU4Ni0zLjM0MTMtMS4xNTU4LS4wMDM0LTIuMzA4MS0uMDA1OS0zLjQ1NjctLjAwNzYtLjA5MDk1LTEuMzI0Mi0uMTc5MTYtMi42NDc3LS4yNjMxLTMuOTcwOXoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODQyNDciLz48cGF0aCBkPSJtMTYuMjExIDU2LjEzNGM5LjgwMjMtNC4zNTg0IDIxLjUxMy00LjM3NTUgMzEuMzEyLjAwMTMtLjEwMDUxIDEuMzIyNy0uMTk4MTEgMi42NDU2LS4yOTE1NSAzLjk2OTMtMS4xNDMyLjAwMTgtMi4yODI0LjAwNDUtMy40MTc3LjAwNzkuOTgxMDMgMS4xMTA3IDEuOTY5OSAyLjIyMTIgMi45NTUxIDMuMzMzOS4wMTE0Ny43MTMwMS4wMzQ0IDIuMTM5LjA0NTg4IDIuODUyLTMuMDcyLTEuNDk1My02LjQyMDItMi4zNDEyLTkuODIyNC0yLjU4MTItNi43MzU0LS41MzE1OC0xMy44ODYtLjU4ODM5LTIwLjA0OSAyLjU3NjguMDA3LS43MTAwOC4wMjA5Ni0yLjEzMDIuMDI3OTQtMi44NDAzLjk4MzQtMS4xMTUzIDEuOTY4Ny0yLjIyOCAyLjk1ODYtMy4zNDEzLTEuMTU1OC0uMDAzNC0yLjMwODEtLjAwNTktMy40NTY3LS4wMDc2LS4wOTA5NS0xLjMyNDItLjE3OTE2LTIuNjQ3Ny0uMjYzMS0zLjk3MDl6Ii8+PHBhdGggZD0ibTI5LjY1IDU3LjMxNmMxLjgyOTMtLjQ4MjYxIDMuODExMy0uMzMwNjUgNS41Njg4LjM3MTc2LjQ2NDk3IDIuMTczLTEuOTE5IDIuMDIxNy0zLjM4ODcgMi4xMDE1LTEuNDU4Mi0uMDc2LTMuNzgxOC4wMzg4Ni0zLjMzMDctMi4wOTIxLjI4NzY0LS4wOTUzLjg2Mjk0LS4yODU5IDEuMTUwNi0uMzgxMTl6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDg0MjQ3Ii8+PC9nPjxwYXRoIGQ9Im0yOS42NSA1Ny4zMTZjMS44MjkzLS40ODI2MSAzLjgxMTMtLjMzMDY1IDUuNTY4OC4zNzE3Ni40NjQ5NyAyLjE3My0xLjkxOSAyLjAyMTctMy4zODg3IDIuMTAxNS0xLjQ1ODItLjA3Ni0zLjc4MTguMDM4ODYtMy4zMzA3LTIuMDkyMS4yODc2NC0uMDk1My44NjI5NC0uMjg1OSAxLjE1MDYtLjM4MTE5eiIvPjxwYXRoIGQ9Im0yMy44NzcgNjUuOTIxYzUuNzQyNi0uODUxOTggMTEuNjIxLS43OTE5NCAxNy4zMzcuMjQ1NTYgMS42NDc1LjMzOTk3IDMuNDE0NS43MDU0NiA0LjcwMjcgMS44Nzc0Ljc3NTU0IDEuNzU5Mi0xLjQ2NDggMi4zMTY1LTIuNjk1NyAyLjc2MTQtNy40MjU0IDEuNzM2NS0xNS4yOTQgMS43MjE4LTIyLjcyNC4wMjUwNS0xLjI4MjQtLjQ2MTQ1LTMuNjIzMy0xLjAwMjUtMi43NjI4LTIuODM0OCAxLjcxNjYtMS40MjAyIDQuMDIwNi0xLjcwMzggNi4xNDIzLTIuMDc0NnoiIGZpbGw9IiNmZmYiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODQyNDciLz48cGF0aCBkPSJtMjMuODc3IDY1LjkyMWM1Ljc0MjYtLjg1MTk4IDExLjYyMS0uNzkxOTQgMTcuMzM3LjI0NTU2IDEuNjQ3NS4zMzk5NyAzLjQxNDUuNzA1NDYgNC43MDI3IDEuODc3NC43NzU1NCAxLjc1OTItMS40NjQ4IDIuMzE2NS0yLjY5NTcgMi43NjE0LTcuNDI1NCAxLjczNjUtMTUuMjk0IDEuNzIxOC0yMi43MjQuMDI1MDUtMS4yODI0LS40NjE0NS0zLjYyMzMtMS4wMDI1LTIuNzYyOC0yLjgzNDggMS43MTY2LTEuNDIwMiA0LjAyMDYtMS43MDM4IDYuMTQyMy0yLjA3NDZ6IiBmaWxsPSIjZmZmIi8+PC9nPjwvc3ZnPg=='); } -body.base .is2d piece.king.white { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMjQuMjg1IDIzLjEzOWM1LjE3OTYtLjAwMDg2MSAxMC4zNi0uMDAwOTcxIDE1LjU0Mi4wMDAwNjMtLjAwNTUgMy44NjI4LjAyNDA4IDcuNzI1Ny0uMDI5IDExLjU4OCAyLjkwODItMS44MTE4IDYuMTU5Ny0zLjQ3MzQgOS43LTMuMTg0NCA0LjQ3MTEuMDY4MzYgOS4wOTQ1IDMuNDQ1NSA5LjM2NDggOC4xMzQuNTI2MzcgNi44MTY1LTMuOTMwNSAxMi44NTctOC45ODYyIDE2Ljk0My0uMzA1NzcgNC4yNTE4LS4zNDA3MiA4LjUyOC0uODExODYgMTIuNzY1LTEuMDAxOSAyLjE4ODMtMy41OTUzIDMuMDgzMi01Ljc1NDEgMy43MjM4LTUuNjQ4MSAxLjI2NTktMTEuNTAzIDEuMDI4OS0xNy4yNDYuNzg5MS0zLjgwNzgtLjM1MDktOC4yMzczLS44NDI2MS0xMC44MjYtNC4wMDg2LS44NjU2OS00LjM0NC0uNTk5LTguODg2NC0xLjAxNzctMTMuMzA3LTQuOTc3Ni0zLjgyODUtOC45ODI2LTkuNjM0MS05LjEyNTItMTYuMDc2LS4wNjE2My00Ljk5NiA0LjcwNjUtOC45MDg5IDkuNDkwNC04Ljk2NjcgMy41NDU2LS4yNzIyNCA2LjgwODMgMS4zNzQ5IDkuNzI5OCAzLjE4OTYtLjA2MDI0LTMuODYyOC0uMDI4MTUtNy43MjU5LS4wMzExOS0xMS41ODl6IiBmaWxsPSIjZmZmIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDgyNzU3Ii8+PHBhdGggZD0ibTI0LjI5MyAyMy4xNDdjLjAwMzEgMy44NjMtLjAzNzQzIDcuNzI1OS4wMjI4MSAxMS41ODktMi45MjE1LTEuODE0Ny02LjE5NTQtMy40NjYtOS43NDA5LTMuMTkzOC00Ljc4MzkuMDU3NzYtOS41NTE2IDMuOTY5My05LjQ5IDguOTY1My4xNDI2NCA2LjQ0MjIgNC4xNDc0IDEyLjI1NCA5LjEyNSAxNi4wODMuNDE4NzEgNC40MjA4LjE2MDg3IDguOTU1NyAxLjAyNjYgMTMuMyAyLjU4ODYgMy4xNjYgNy4wMjgxIDMuNjY0MSAxMC44MzYgNC4wMTUgNS43NDIyLjIzOTc4IDExLjU5OC40Njc0NSAxNy4yNDYtLjc5ODQ0IDIuMTU4OC0uNjQwNjQgNC43NDY4LTEuNTMwMiA1Ljc0ODgtMy43MTg0LjQ3MTE0LTQuMjM2Ni40OTI2Ni04LjUyMzIuNzk4NDQtMTIuNzc1IDUuMDU1Ny00LjA4NiA5LjUxNDUtMTAuMTEgOC45ODgxLTE2LjkyNy0uMjcwMzItNC42ODg0LTQuODgyLTguMDc1Ny05LjM1MzEtOC4xNDQxLTMuNTQwMy0uMjg5MDEtNi43ODcxIDEuMzgxOS05LjY5NTMgMy4xOTM4LjA1MzA4LTMuODYyNy4wMTczLTcuNzI1OS4wMjI4MS0xMS41ODktNS4xODE4LS4wMDEtMTAuMzU2LS4wMDA4NjEtMTUuNTM1IDB6bTMuMTI1IDE1LjIxNmMzLjA4NzQuMDE5MjcgNi4xNzA1LjAyMDg2IDkuMjYxOSAwLTEuODQzNyAyLjQ1OTMtMy4zNTk2IDUuMTQ1Mi00LjYzMDkgNy45Mzg4LTEuMjcxNS0yLjc5NjEtMi43OTA5LTUuNDc4LTQuNjMwOS03LjkzODh6Ii8+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0ibTI3LjQ3NCAyNS40NjFjMy4wNTIyLS4wMDI3IDYuMTA2NS0uMDAzMSA5LjE2MzIuMDAwNTE3LTEuNTI4NSAxLjQ1MzgtMy4wNTY0IDIuOTAzLTQuNTgzNyA0LjM1MzMtMS41Mjg2LTEuNDUwNi0zLjA1ODEtMi45MDA0LTQuNTc5NS00LjM1Mzh6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDgyNzU3Ii8+PHBhdGggZD0ibTI3LjQ3NCAyNS40NjFjMy4wNTIyLS4wMDI3IDYuMTA2NS0uMDAzMSA5LjE2MzIuMDAwNTE3LTEuNTI4NSAxLjQ1MzgtMy4wNTY0IDIuOTAzLTQuNTgzNyA0LjM1MzMtMS41Mjg2LTEuNDUwNi0zLjA1ODEtMi45MDA0LTQuNTc5NS00LjM1Mzh6Ii8+PHBhdGggZD0ibTI2LjM5MiAyNi42MjZjMS40NTAxIDEuNDY3NyAyLjkwMDMgMi45MzU3IDQuMzUzMyA0LjQwNDctMS40NTIzIDEuNDc4My0yLjkwNCAyLjk1NTItNC4zNTMzIDQuNDMyOS0uMDAxNC0yLjk0Ni0uMDAyOC01Ljg5MTgtLjAwMDAxNi04LjgzNzZ6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDgyNzU3Ii8+PHBhdGggZD0ibTI2LjM5MiAyNi42MjZjMS40NTAxIDEuNDY3NyAyLjkwMDMgMi45MzU3IDQuMzUzMyA0LjQwNDctMS40NTIzIDEuNDc4My0yLjkwNCAyLjk1NTItNC4zNTMzIDQuNDMyOS0uMDAxNC0yLjk0Ni0uMDAyOC01Ljg5MTgtLjAwMDAxNi04LjgzNzZ6Ii8+PHBhdGggZD0ibTMzLjM2MiAzMS4wMjljMS40NDk4LTEuNDY5NiAyLjkwMjgtMi45Mzg2IDQuMzU3MS00LjQwNzgtLjAwMTggMi45NDg1LS4wMDIzIDUuODk2OS4wMDAxNDIgOC44NDU2LTEuNDU0NS0xLjQ3OTMtMi45MDc2LTIuOTU3OC00LjM1NzMtNC40Mzc4eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4Mjc1NyIvPjxwYXRoIGQ9Im0zMy4zNjIgMzEuMDI5YzEuNDQ5OC0xLjQ2OTYgMi45MDI4LTIuOTM4NiA0LjM1NzEtNC40MDc4LS4wMDE4IDIuOTQ4NS0uMDAyMyA1Ljg5NjkuMDAwMTQyIDguODQ1Ni0xLjQ1NDUtMS40NzkzLTIuOTA3Ni0yLjk1NzgtNC4zNTczLTQuNDM3OHoiLz48cGF0aCBkPSJtMjcuNTk0IDM2LjUwN2MxLjQ4MDctMS40NDkzIDIuOTcwMy0yLjg5NCA0LjQ1OTktNC4zMzg1IDEuNDg3NiAxLjQ0NTUgMi45NzQ5IDIuODkwNSA0LjQ2NDcgNC4zMzg4LTIuOTc3My4wMDM3LTUuOTUxOS4wMDM5LTguOTI0Ni0uMDAwMzUzeiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4Mjc1NyIvPjxwYXRoIGQ9Im0yNy41OTQgMzYuNTA3YzEuNDgwNy0xLjQ0OTMgMi45NzAzLTIuODk0IDQuNDU5OS00LjMzODUgMS40ODc2IDEuNDQ1NSAyLjk3NDkgMi44OTA1IDQuNDY0NyA0LjMzODgtMi45NzczLjAwMzctNS45NTE5LjAwMzktOC45MjQ2LS4wMDAzNTN6Ii8+PHBhdGggZD0ibTcuNDUyMSA0Mi4yMjNjLS41ODE1NS0zLjM1MTUgMS42MjEzLTYuOTQwOSA0Ljg4NjctNy45MDUyIDMuOTU5NC0xLjE2MDggOC4zNTM2LjIxMTEyIDExLjMxMSAyLjk5NDggMy45MzQ3IDMuNjAyOCA2LjAzOTcgOC42NjI3IDcuNjQxMyAxMy42NDItNS41MzMzLjIxNzE1LTExLjI1NC43MTYxNi0xNi4xODUgMy40NjY2LTMuNjI0LTMuMjExLTcuMDU2OS03LjIwOC03LjY1MzktMTIuMTk4eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4Mjc1NyIvPjxwYXRoIGQ9Im03LjQ1MjEgNDIuMjIzYy0uNTgxNTUtMy4zNTE1IDEuNjIxMy02Ljk0MDkgNC44ODY3LTcuOTA1MiAzLjk1OTQtMS4xNjA4IDguMzUzNi4yMTExMiAxMS4zMTEgMi45OTQ4IDMuOTM0NyAzLjYwMjggNi4wMzk3IDguNjYyNyA3LjY0MTMgMTMuNjQyLTUuNTMzMy4yMTcxNS0xMS4yNTQuNzE2MTYtMTYuMTg1IDMuNDY2Ni0zLjYyNC0zLjIxMS03LjA1NjktNy4yMDgtNy42NTM5LTEyLjE5OHoiLz48cGF0aCBkPSJtNDAuNDcgMzcuMzAxYzIuOTE0NS0yLjczNTggNy4yMTE3LTQuMTA0IDExLjEyOC0zLjAyOCAzLjMyNjEuOTA4ODMgNS41OTg2IDQuNTE0IDUuMDY4OCA3LjkxMDgtLjUwNzYzIDUuMDI5Ny00LjAwMzYgOS4wMjg2LTcuNjQ0OSAxMi4yMzEtNC45NzUtMi42NDk5LTEwLjY3Mi0zLjIyMDYtMTYuMjA4LTMuNDYyOCAxLjYwMzMtNC45ODI1IDMuNzA4NS0xMC4wNTEgNy42NTU2LTEzLjY1MXoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODI3NTciLz48cGF0aCBkPSJtNDAuNDcgMzcuMzAxYzIuOTE0NS0yLjczNTggNy4yMTE3LTQuMTA0IDExLjEyOC0zLjAyOCAzLjMyNjEuOTA4ODMgNS41OTg2IDQuNTE0IDUuMDY4OCA3LjkxMDgtLjUwNzYzIDUuMDI5Ny00LjAwMzYgOS4wMjg2LTcuNjQ0OSAxMi4yMzEtNC45NzUtMi42NDk5LTEwLjY3Mi0zLjIyMDYtMTYuMjA4LTMuNDYyOCAxLjYwMzMtNC45ODI1IDMuNzA4NS0xMC4wNTEgNy42NTU2LTEzLjY1MXoiLz48cGF0aCBkPSJtMTYuNTcxIDU2LjM3N2M5LjcyNzItNC4yMDA2IDIxLjIzNi00LjIwMDIgMzAuOTY1LS4wMDE5LS4wODkxOSAxLjI5MTQtLjE3NDkyIDIuNTgzLS4yNTU5OCAzLjg3NTMtMS4xMzI3LjAwMTYtMi4yNjA5LjAwMzktMy4zODQ1LjAwNy45MzYyMyAxLjA5NDEgMS44ODI0IDIuMTg3OCAyLjgyMyAzLjI4NDYuMDI2NjQuNjcyMDYuMDc5OTQgMi4wMTYyLjEwNjU5IDIuNjg4My00LjQxNDctMi43MDc5LTkuNzMyNi0yLjkyMjktMTQuNzYzLTIuOTU3NC01LjAzNy4wMzMzOS0xMC4zNTYuMjQ3ODMtMTQuNzc1IDIuOTUyNC4wMjY1Mi0uNjcxNDcuMDc5NTYtMi4wMTQ0LjEwNjEtMi42ODU4LjkzNjQxLTEuMDk1OSAxLjg3NTYtMi4xODg2IDIuODE5Ni0zLjI4MjItMS4xMzE4LS4wMDMtMi4yNTkzLS4wMDU0LTMuMzgyNi0uMDA3LS4wOTA3Ny0xLjI5MTYtLjE3ODAzLTIuNTgyNS0uMjU5Ni0zLjg3MzF6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDgyNzU3Ii8+PHBhdGggZD0ibTE2LjU3MSA1Ni4zNzdjOS43MjcyLTQuMjAwNiAyMS4yMzYtNC4yMDAyIDMwLjk2NS0uMDAxOS0uMDg5MTkgMS4yOTE0LS4xNzQ5MiAyLjU4My0uMjU1OTggMy44NzUzLTEuMTMyNy4wMDE2LTIuMjYwOS4wMDM5LTMuMzg0NS4wMDcuOTM2MjMgMS4wOTQxIDEuODgyNCAyLjE4NzggMi44MjMgMy4yODQ2LjAyNjY0LjY3MjA2LjA3OTk0IDIuMDE2Mi4xMDY1OSAyLjY4ODMtNC40MTQ3LTIuNzA3OS05LjczMjYtMi45MjI5LTE0Ljc2My0yLjk1NzQtNS4wMzcuMDMzMzktMTAuMzU2LjI0NzgzLTE0Ljc3NSAyLjk1MjQuMDI2NTItLjY3MTQ3LjA3OTU2LTIuMDE0NC4xMDYxLTIuNjg1OC45MzY0MS0xLjA5NTkgMS44NzU2LTIuMTg4NiAyLjgxOTYtMy4yODIyLTEuMTMxOC0uMDAzLTIuMjU5My0uMDA1NC0zLjM4MjYtLjAwNy0uMDkwNzctMS4yOTE2LS4xNzgwMy0yLjU4MjUtLjI1OTYtMy44NzMxeiIvPjxwYXRoIGQ9Im0yOS43NjUgNTcuMjc1YzEuOTgzLS40MDQ2MyA1LjAxNzUtLjg2ODM3IDYuMDQ2MiAxLjQwMDctMS43NTY4IDEuODA5OS00LjY4MDggMS40ODE2LTYuODU2Ny43Mjc3Mi0uNzMzMDEtMS4xNjc0LS40NjI4Ny0xLjg3NjguODEwNDUtMi4xMjg0eiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4Mjc1NyIvPjwvZz48cGF0aCBkPSJtMjkuNzY1IDU3LjI3NWMxLjk4My0uNDA0NjMgNS4wMTc1LS44NjgzNyA2LjA0NjIgMS40MDA3LTEuNzU2OCAxLjgwOTktNC42ODA4IDEuNDgxNi02Ljg1NjcuNzI3NzItLjczMzAxLTEuMTY3NC0uNDYyODctMS44NzY4LjgxMDQ1LTIuMTI4NHoiLz48cGF0aCBkPSJtMjQuMjExIDY1Ljk5N2M2LjMyNzItLjg1NzI1IDEyLjg0My0uNzg5MjUgMTkuMDc3LjY3MzE0IDEuMjg4OC40MjMwOCAzLjI0Ni45MjM0NCAyLjgyMzYgMi43MDExLTEuODY5MyAxLjQ4NTktNC4zMDk4IDEuODE2Ni02LjU5MzggMi4xNTU5LTUuNTU4OC43ODUxNC0xMS4yMzIuNjc3NjYtMTYuNzU5LS4yODc5OC0xLjY4NTMtLjMwNzA4LTMuNDAxMy0uNzcyNzYtNC43NjA0LTEuODU5Ni0uMDkzMDYtMi45ODYyIDQuMDkyNi0yLjgwNjIgNi4yMTIyLTMuMzgyNnoiIGZpbGw9IiNmZmYiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODI3NTciLz48cGF0aCBkPSJtMjQuMjExIDY1Ljk5N2M2LjMyNzItLjg1NzI1IDEyLjg0My0uNzg5MjUgMTkuMDc3LjY3MzE0IDEuMjg4OC40MjMwOCAzLjI0Ni45MjM0NCAyLjgyMzYgMi43MDExLTEuODY5MyAxLjQ4NTktNC4zMDk4IDEuODE2Ni02LjU5MzggMi4xNTU5LTUuNTU4OC43ODUxNC0xMS4yMzIuNjc3NjYtMTYuNzU5LS4yODc5OC0xLjY4NTMtLjMwNzA4LTMuNDAxMy0uNzcyNzYtNC43NjA0LTEuODU5Ni0uMDkzMDYtMi45ODYyIDQuMDkyNi0yLjgwNjIgNi4yMTIyLTMuMzgyNnoiIGZpbGw9IiNmZmYiLz48L2c+PC9zdmc+'); } -body.base .is2d piece.pawn.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTQ5LjI0NiA3NC4xNGgtMzQuNTQzYy0uMDk1OTUtMy4wMTMgMS4wNzQ3LTUuMjAwNyAzLjUxMTktNi41NjMyIDEuODk5OS0xLjA1NTUgNC40NzE0LTEuNTczNiA3LjcxNDctMS41NTQ0bC4xNzI3Mi0yLjQ0NjhjLTEuMTg5OC0uNjUyNDgtMS43ODQ4LTEuOTQ3OS0xLjc4NDctMy44ODYxLS4wMDAwMTUtMi40MzcyIDEuMDM2My01LjU2NTMgMy4xMDg5LTkuMzg0M3YtMy43NzFoLTEwLjM5MmMtLjE1MzUzLTEuMTMyMi4xNDM5My0yLjQxOC44OTIzNy0zLjg1NzMgMS44OTMxLTQuMTExNSA2LjgzODUtNC4xODI2IDkuODczNi02LjczNi0uNDAzMDUtLjYxNDA4LS42NTI1MS0xLjAyNjctLjc0ODQ0LTEuMjM3OC0uMjQ5NDgtLjUxODEyLS4zODM4MS0uOTY5MS0uNDAzLTEuMzUzLS4wMzg0LTEuNDIwMS40Nzk3Mi0yLjYxOTUgMS41NTQ1LTMuNTk4MyAxLjA3NDctLjk5Nzg4IDIuMzMxNi0xLjQ5NjggMy43NzEtMS40OTY5IDEuNDIwMS4wMDAwMzcgMi42Njc1LjQ5OSAzLjc0MjIgMS40OTY5IDEuMDkzOC45Nzg3NiAxLjYyMTYgMi4xNzgyIDEuNTgzMiAzLjU5ODMtLjAzODQgMS4yODU4LS40MjIyNSAyLjE0OTQtMS4xNTE0IDIuNTkwOC4xOTE4Ni43ODY4NSAxLjM3MjEgMS40NjgxIDMuNTQwNyAyLjA0MzggNC44NzQ0IDEuMzA1IDcuMzExNiAzLjg1NzQgNy4zMTE3IDcuNjU3MS0uMDAwMDQuMzgzODEtLjAyODguNjgxMy0uMDg2NC44OTIzN2gtMTAuMzkydjMuNzcxYzIuMDkxOCAzLjgxOSAzLjEzNzYgNi45NDcxIDMuMTM3NyA5LjM4NDMtLjAwMDAzIDEuOTM4My0uNjA0NTQgMy4yMzM2LTEuODEzNSAzLjg4NjFsLjE3MjcyIDIuNDQ2OGM0LjQxMzgtLjAzODQgNy41NzA3LjkzMDc0IDkuNDcwNiAyLjkwNzQgMS4yMDkgMS4yNjY2IDEuODEzNSAyLjc3MyAxLjgxMzUgNC41MTk0LS4wMDAwNC4yODc4Ni0uMDE5Mi41MTgxNC0uMDU3Ni42OTA4NyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIi8+PHBhdGggZD0ibTE0Ljk2OTQ5MiA1Ni44OTM5MjNjMC0uNTY5ODguMzE4NzA1LTEuNjcxMDU3LjcxMjE1NC0yLjQ2MDYwOCAxLjIyMzQzOC0yLjQ1NTExOCAzLjg1MDQzNi0zLjc3MTkxNiA4LjQ0MDM4OC00LjIzMDc4OGwxLjk2NjEwMi0uMTk2NTU1di0xLjI5NTIwNmMwLS44NzQ0NDktLjE0NTc5MS0xLjQxNjExMS0uNDQ4Nzg4LTEuNjY3MzkyLTEuNzg0NjQ4LTEuNDgwMDQ0LTEuNDk3MjA1LTUuNDQ2NzguNzQyMDQyLTEwLjI0MDIzNS45MzM4NjctMS45OTkwODggMS4wNjI2NzgtMi41MTY4MTIgMS4wNjI2NzgtNC4yNzExODZ2LTEuOTk2MzZoLTUuMTUyNTQzLTUuMTUyNTQybC4wMDAyMTQtLjg4MTM1NmMuMDAwMzI1LTEuMjkwNDA3IDEuMzg1Mjg3LTQuMDAyODU3IDIuNTc5MDE3LTUuMDUwOTY2LjU3MDMxNS0uNTAwNzQzIDIuNDQ2OTA1LTEuNTcyOTQ4IDQuMTcwMi0yLjM4MjY3NyAxLjcyMzI5Ni0uODA5NzI5IDMuMzQxNzYtMS42NjA5MjEgMy41OTY1ODgtMS44OTE1MzcuNDM2MjExLS4zOTQ3NjYuNDMyNzYtLjQ2OTQyNi0uMDU4OTgtMS4yNzU4NzQtLjY4Njk2LTEuMTI2NjEyLS42ODMwODQtMy4wMzM1NTguMDA4NS00LjE2Nzc1MyAxLjE3MTMtMS45MjEwMTEgMy45NzIwMjEtMi45NTQxNTcgNi4xMDIzNy0yLjI1MTA3OCAyLjc5MjQxMy45MjE1NzkgNC40ODE1NSA0LjE0NTIyNiAzLjI2OTc3MyA2LjI0MDIyNC0uNzc0NTM1IDEuMzM5MDY1LS43ODM1NTcgMS40MzM1MjMtLjE4MzMzMyAxLjkxOTU1NS4zMjU0NDQuMjYzNTI5IDEuNzMyMjgxLjg1OTEyMyAzLjEyNjMwNCAxLjMyMzU0MiAzLjA1NjQ4OSAxLjAxODI3IDQuNzU1NjMyIDIuMDQ5NjEzIDUuODM3NjkgMy41NDMzNS44MTAwMDcgMS4xMTgxODEgMS41NTk3NjcgMy43NDk0NzIgMS4yNzc3NzEgNC40ODQzNDItLjEyMzAyNC4zMjA1OTgtMS4wNzA2NTIuMzkwMjI4LTUuMzEwNzk4LjM5MDIyOGgtNS4xNjEwNTN2MS45MDUwNzVjMCAxLjYyNDgyMS4xMzUwMjIgMi4xNzMzNjQuOTE3ODMxIDMuNzI4ODE0IDIuMDE4NjczIDQuMDExMTIgMi43NDAwMzUgOC4zNDExMjEgMS42NjQ3NTEgOS45OTI3MjUtLjI3OTM2MS40MjkwOTEtLjY3NzkzMy45MDY2MjYtLjg4NTcxNCAxLjA2MTE4Ni0uMjUwODA2LjE4NjU2NS0uMzQ4ODA1LjY4Nzg5MS0uMjkxNTY0IDEuNDkxNTI1bC4wODYyMiAxLjIxMDUwNiAyLjQ2MTMzNy4zMjUxNTJjMy40MjU5ODIuNDUyNTg2IDUuMzYxMjg4IDEuMjM0MzYgNi45MjM4MjYgMi43OTY4OTUgMS4yNzQxNTkgMS4yNzQxNTkgMS44NjQ0MTUgMi41ODAxNjYgMS44Njc1NjEgNC4xMzIxOWwuMDAxNS43NDU3NjNoLTE3LjA4NDc0Ni0xNy4wODQ3NDV2LTEuMDMxNTAxeiIgZmlsbD0iIzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii45ODc4MDE5NyIvPjwvc3ZnPg=='); } -body.base .is2d piece.knight.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMTEuNjk4IDYwLjg1MmMuOTI0NzYuOTI5NTEgMy4yMzQ2Ljk1MjQgNC4zOC4xMjU0OC45MDc1OC0xLjExNzYgMi4yMjkzLTEuNjk0MSAyLjU4MzktMy4xNzQyLjYxNzM5LTEuOTUxOC0xLjkxNzktMy4wODM3LTMuMjIyLTEuNzAxMi0xLjQ5MDEgMS40MTA0LTQuNzU5NCAzLjg1MjMtMy43NDE4IDQuNzQ5OXoiIGZpbGw9IiNmZmYiIHN0cm9rZT0iIzIwMTkxNyIgc3Ryb2tlLXdpZHRoPSIxLjQyMiIvPjxwYXRoIGQ9Im0yMi4yNDUgMjkuMDcxYy4yMDU5Ny0xLjk3ODguMzM0OS0zLjk2NDYuNDMxMjMtNS45NTE3IDEuOTg4MyAzLjAwMTYgNC41MDE5IDYuMjA2NiA4LjM3NjIgNi41ODIzIDcuNzc5MSAxLjE3MzEgMTUuMTI1IDUuNjQ1NiAxOS4xNzMgMTIuNDc1IDUuODAyOCA5LjUzMTMgNi4yNjY1IDIxLjM3MiAzLjQ5NzcgMzEuOTY4LTEwLjMwNC0uMDA2Ni0yMC42MDcuMDE2MzYtMzAuOTA5LS4wMDItMS4yMjM0LS4wMzQxMS0zLjQ1MzEuMDYwNTYtMy4xNDU2LTEuODIxMi43NDk2NS0zLjk3MzMgMy44MDU1LTcuMTY4NCA3LjI5NjktOS4wMjQyIDQuNDI0MS0yLjY1MDYgNS42NDA5LTguMTE0IDUuNzAxMS0xMi45MTItMi40NzQ2IDIuMjkxNi02LjYwNTkgNC45MzYyLTEwLjMxNCA0Ljg1ODYtMi4xNTI3IDMuNDYyOC0yLjc3MjkgNS42MzUyLTcuMzQyOCA2LjgxMTktLjYxMTE2LS42Nzk0Ni4wNzE0LTEuNTAwOC45Mzg5OC0zLjkxNDctMS4wMTQ0IDEuMDYxNi0yLjQ5NjMgMi40NjUyLTQuNjE1MyAzLjMzNC0yLjE4NDctMS45MjEtMy4zOTkzLTQuNjI4My0yLjI2MjYtNy44NDM5LjkzODIzLTEuNDExMi41NjYzMS0xLjcxNTggMS44MzgyLTIuOTA3NyAxLjY1MDktMS41NDcgNC4wMDQyLTUuMjkxMSA0LjQ4MjEtOC4xMDA1LjQ2MjgzLTMuMTU3NCAyLjE4NDMtNS44ODY0IDQuMDQyMS04LjQwMzMtMS4yMDQ1LTIuNzk5Mi0xLjcyMTQtNS44MTg3LTEuNjQ2MS04Ljg1ODcgMS40ODk5IDEuMjI5NyAyLjkyODUgMi41MjI0IDQuNDU3OSAzLjcwOTV6Ii8+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0ibTI0LjM1NSAyOC40MjZjLjc4NyAxLjA3MjEgMi4wMTE3IDIuMTc1OSAzLjEzOTMgMi45MTU1LjA0OTkuOTg4ODYuNTg5NDIgMi43NjItMS4wMjI3IDIuNjg5OC0yLjk3NjMuMjkzNTQtMi41MTY5LTMuODE0Mi0yLjExNjYtNS42MDUzeiIvPjxwYXRoIGQ9Im0zMi4wNDIgMzIuMzI0YzYuMzM0MS0uMDI5NzMgMTMuMTE3IDYuNTMxNSAxNS4wMSA5LjE5NDQgNi41NzIzIDcuOTA2NyA2Ljc5MTYgMTkuMTYyIDUuMzA4NyAyOS4wOTUuMzI5NDkgMS44MTMtMS42NDY3IDEuNTgyNy0yLjc5NzkgMS45NzE4LjExNDE4LTguMTc1OC44NTA3My0xNi43Mi0yLjY4NjMtMjQuMzc3LTMuMDUxLTYuMzY1LTguNjY5MS0xMS4zMTctMTUuMTQyLTE0LjAyNi4wNzctLjQ2NDYuMjMwODUtMS4zOTM4LjMwNzgtMS44NTg0eiIvPjxwYXRoIGQ9Im0xMC44NzggNTUuMzcyYy42MzE3LTEuMDAyOSAxLjk3ODctLjk4OTg2IDIuOTc3OC0xLjM3MDctLjY0ODQ2IDEuMzIxNS0uOTUzNSAzLjE5NTQtMi41MTY4IDMuNzIwMi0uNDUyMTYtLjY0MDY2LTEuMDc2My0xLjYwMzEtLjQ2MTA2LTIuMzQ5NXoiLz48cGF0aCBkPSJtMjAuNDM0IDQyLjk5YzEuODA2MS0xLjM2MjMgMy41NzE4LS41MTUyIDUuNTAxNS4wNjI0OC0yLjEzNSAxLjE5NTEtNC42OTI5IDMuMzQ0OS02LjQwMzYgMi4zMTUtLjY5MjkyLS40MTcxNC0uMTEwNDUtMS42MTM4LjkwMjE0LTIuMzc3NXoiLz48L2c+PC9nPjxwYXRoIGQ9Im0yMC41ODg1MjQgNTcuNjY5MDMxYy0uODYwNDg1LS4zNzM1MzUtLjkwNjU0OC0uNDU5NTgzLS43NTI4OTEtMS40MDY0Ni4yNjE4MTItMS42MTMzNTYgMS43Mjk5NzUtNC4yOTg1IDMuMTQ0MTUtNS43NTAzODEuNzE4NTA2LS43Mzc2NiAyLjE3NTE5MS0xLjkwMzIzOCAzLjIzNzA4LTIuNTkwMTcgMS4wNjE4ODktLjY4NjkzNCAyLjM3NTE4My0xLjcwMDkxNCAyLjkxODQzMi0yLjI1MzI5MSAxLjk0MDk5LTEuOTczNjA1IDMuNTg0ODM2LTYuNjU3MzE3IDMuNjE0NTY2LTEwLjI5ODc2M2wuMDA5NS0xLjE1ODg0OS0xLjM4MTc4MSAxLjA5MjIzNWMtMi42Nzg5IDIuMTE3NTQ4LTYuNDA0Njc4IDMuODAxNzMzLTguNDEwMjQ5IDMuODAxNzMzLS42MjIxMjcgMC0uODkwODkyLjI1NjE5Mi0xLjYzNTg0NCAxLjU1OTMyMi0xLjIwNjg5NyAyLjExMTItMi43OTU3NjEgMy43Nzk2NDItNC4zNDg4MzQgNC41NjY2NDQtMi4yMTk0MjcgMS4xMjQ2NjctMi41MzQ3OTIuODQ5MDQ3LTEuNTc5MjI0LTEuMzgwMjA0Ljc1NjA0Mi0xLjc2Mzc3NC42ODA0NTQtMS45OTc2MzItLjMzODk4My0xLjA0ODc0OC0xLjE3NDQxNiAxLjA5MzEzNi0zLjIyMjg4IDIuNTQyMzQtMy41Nzg4NDggMi41MzE4ODktLjM3MTMwMS0uMDEwOS0xLjkyOTY4OTgtMi4wODUwOTMtMi4zMDE2Nzc2LTMuMDYzNDk2LS41MDUxMzctMS4zMjg2MS0uMzQ0MDc0Ni0zLjcxMzY1MS4zNTE2ODE2LTUuMjA3NzY0LjM0OTQ0MjEtLjc1MDQxNi44MTIxNTgtMS41NDM2MzYgMS4wMjgyNTctMS43NjI3MTIgMi40ODM5MjMtMi41MTgxNDUgNC4yMDUxMzctNS42MTI4MzQgNS4wNzU2MzgtOS4xMjU4NDEuNTg1MDQ3LTIuMzYxMDI0IDEuNDExNjcyLTQuMTg5OTI0IDIuOTIxNjM1LTYuNDY0MDk0bC45MzE3NzItMS40MDMzNDktLjY1NzMxNy0yLjI3ODc5Yy0uNjU2MTg2LTIuMjc0ODcxLTEuMjA2MTQyLTYuMjEwOTkyOC0uODY3ODAyLTYuMjEwOTkyOC4wOTgzIDAgMS4wNDg1ODIuNzMyMjAzOCAyLjExMTc0MiAxLjYyNzExODggMS4wNjMxNTkuODk0OTE1IDIuMDIyNjI2IDEuNjI3MTE4IDIuMTMyMTQ5IDEuNjI3MTE4cy4yODc1OTUtMS4yNDc3NzIuMzk1NzE2LTIuNzcyODI3Yy4xODkwODktMi42NjcxMTYuMjEzMDM4LTIuNzQ3MjQxNC42MjgxNjktMi4xMDE2OTUxLjgwNjA1NyAxLjI1MzQ1NDcgMy40MTc0OTEgMy44NDMyODExIDQuNTM3MjI2IDQuNDk5Njg2MS42MTMzMTcuMzU5NTM1IDIuMzIxNzkyLjkwODE5OSAzLjc5NjYxMSAxLjIxOTI1NSA1LjAzMzk3NyAxLjA2MTcxOSA4LjU4OTEwMSAyLjYyMjkzMiAxMi4yNDM2ODggNS4zNzY3NDYgMy40MzU2NDUgMi41ODg4MzcgNS43Njk5MzMgNS41NDUzMTUgNy43ODk3NzkgOS44NjYwOTkgMi42MzU5NDMgNS42Mzg3MTEgMy40NzEwMDcgOS41Mzg3NTkgMy40OTQyODYgMTYuMzE5NTE2LjAxNjMgNC43NDU4NjYtLjE5ODY1MiA2Ljg4MzQwMS0xLjA4Mzk3MyAxMC43Nzk2NjFsLS40MTU5MzUgMS44MzA1MDktMTYuMDQ2MDU4LS4wMTA2Yy0xMy40ODk0ODItLjAwODkyNi0xNi4xOTIxMzYtLjA3NDAxMy0xNi45NjI2NjEtLjQwODQ5NXptMzEuMTUzODQ5LTEuNTgzMjY4Yy42MjE0ODMtLjI4MzMwOS43MDQwNjUtLjUzNDcyLjk5MTIzNS0zLjAxNzc0OS40NzIwODQtNC4wODE5MDcuNDQ0MTI4LTExLjgwNjg4OS0uMDUzMS0xNC42NzMxNjktMS4wNzAwNjYtNi4xNjgzNzMtMy4xMzE0MzgtMTAuNDY1NTI5LTcuMDUxNDQxLTE0LjY5OTQ5NS0zLjg4NjMzNS00LjE5NzYwMS05LjMxNTc3OC03LjM2MzMyOS0xMi42MzczMzctNy4zNjg0MTQtLjY1MTcyOS0uMDAxLTEuMDQzOTUzLjE0NDQ2OC0xLjE1MjU0My40Mjc0NDctLjQyNjYzMyAxLjExMTc4OC0uMTY3NDQ0IDEuNDQwNDEzIDIuMDQzMTMyIDIuNTkwNDgxIDYuNTMwMjg0IDMuMzk3NDI3IDExLjYxMDEgOS4wMjgxNzIgMTMuODA5ODc1IDE1LjMwNzYyMSAxLjMyNzk4NCAzLjc5MDg0MiAxLjY0Njg3MiA2LjM0NDIzMSAxLjgwMDM1IDE0LjQxNTY3OGwuMTQ1NjE2IDcuNjU3OTkuNzEzMTI1LS4xNjU2NjhjLjM5MjIyLS4wOTExMiAxLjAxODIxMS0uMzA0NzQzIDEuMzkxMDkyLS40NzQ3MjJ6bS0zOS40OTU1NTctMTQuODc4OTgzYy4zNjg2NTQtLjMzNTU5NC45MjM2OC0xLjIwMzIzOCAxLjIzMzM5MS0xLjkyODA5OGwuNTYzMTEtMS4zMTc5MjgtMS4wMTQ4NzkuMTc5NDc3Yy0xLjE5MTI3NC4yMTA2NzEtMi4zMzI3Ljk2Mzk1OS0yLjQ2MjYyMyAxLjYyNTIxNC0uMTA4NTc5LjU1MjYyNC40NjY4MjkgMi4wNTE1MDQuNzg3NTU2IDIuMDUxNTA0LjEyMjc0IDAgLjUyNDc5LS4yNzQ1NzYuODkzNDQ1LS42MTAxNjl6bTExLjI5MjE2Ny0xMi41OTY3NzNjMi43MDQxNDItMS40NDQwNTYgMi43Nzc0OS0xLjU4NzI3OCAxLjA3MjIzLTIuMDkzNjg2LS43OTMwMjItLjIzNTUwMi0xLjc1NTMwMi0uNDI3NzI5LTIuMTM4NC0uNDI3MTcyLS43NTczNDkuMDAxMS0yLjM4NDIxOS44ODgzMTEtMi45MjA0MSAxLjU5MjYzNi0uNTQ4MDE5LjcxOTg2My0uNDIyODU2IDEuNjUwNTE4LjI1Nzc2NiAxLjkxNjY0Ljg0MTk4NC4zMjkyMTQgMS42NzQ4MTYuMTA4NDUxIDMuNzI4ODE0LS45ODg0MTh6bTMuNzQyMzczLTEwLjcxMTcwMmMuMTc4OTgzLS4xNzg5ODMuMzI1NDI0LS44MDc1MjEuMzI1NDI0LTEuMzk2NzUxIDAtLjk2MDI0My0uMTcwMTcxLTEuMjMwNzYyLTEuNjQxMTgzLTIuNjA4OTc0LS45MDI2NTEtLjg0NTcwNy0xLjY4MzEwNy0xLjQ2ODAxNi0xLjczNDM0OC0xLjM4MjkxMS0uMTE5NjU4LjE5ODczOS0uMjMzNTEyIDIuMzMwODktLjE4NjMxMiAzLjQ4OTA5OC4wNjcxMiAxLjY0NzAyNCAyLjIyMzM3MyAyLjkxMjU4NCAzLjIzNjQxOSAxLjg5OTUzOHoiIGZpbGw9IiMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuOTg3ODAxOTciLz48L3N2Zz4='); } -body.base .is2d piece.bishop.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMjUuNDg3IDI0LjQ4M2MxLjIzNjctMi4xMDYzIDQuNzIwNi0xLjY2MTIgNS40OTkxLjYwOTguODY3MjUgMS41NjYtLjY4NTU3IDIuODE4MS0xLjQwMjMgNC4wNDI5Ljg2MzM0Ljc0ODA0IDEuNzI1MyAxLjQ5OCAyLjU5MjEgMi4yNDY2Ljg2MjgtLjg2MzUzIDEuNzI1NS0xLjcyODkgMi41NzkxLTIuNjA0Ny0xLjIzNDQtMi4wNDExLTEuMDU4Mi01LjIzMTEgMS43OTQ0LTUuNjI5IDMuMzkzNy0uNjIwOTMgNC40MTEyIDMuNjQyNyAyLjc3NDYgNS45MjU1IDMuMDQyIDMuODI1IDUuODE0NCA4LjA3MjQgNi43NTYzIDEyLjk0NyAxLjA2MzkgNS41ODM3LS4zNTI5MiAxMS4zNDMtMi43NjM5IDE2LjM5My4wNzk1NiAyLjUwMzgtLjExODcgNS4wMDQ1LS41MTY5NyA3LjQ3NjggNC4yNjgxLTEuNjc5NSA5LjUxODMtMi40ODEzIDEzLjU3Ny4xMzg0OCAyLjY0MTcgMS43Nzg5IDIuNTA2MSA1LjI2MTMgMi4xOTgxIDguMDU3OS02LjE2NS0zLjMwNi0xMy40MTItMi44NjktMjAuMDkyLTEuNzY2LTMuMzIxLTMuNTg5LTkuNjcyLTMuNTIzLTEzLjAxMi4wMTMtNi42ODgtMS4xODEtMTMuODg4LTEuNDU2LTIwLjExMiAxLjY5Ny0uMTk1NC0yLjgzMS0uMzQ4MS02LjM2MiAyLjM5NzMtOC4wOTEgNC4wNjk3LTIuNDk3IDkuMjUzNy0xLjczNiAxMy40NzctLjAxNy0uNDM0LTIuNTA2LS42MjEtNS4wNDYtLjUzNS03LjU4Ny0yLjQ2OC00LjM2NS00LjYzMS05LjQ0MS0zLjQ3NC0xNC41NDcgMS4zNTUtNS41MyA0Ljk2Ny0xMC4xMTYgOC40OC0xNC40NTctLjQyOC0xLjU1MS0xLjMxOS0zLjM2NS0uMjE2LTQuODQ5eiIgZmlsbD0iI2ZmZiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4OTYzMyIvPjxwYXRoIGQ9Im0yNS40ODcgMjQuNDgzYzEuMjM2Ny0yLjEwNjMgNC43MjA2LTEuNjYxMiA1LjQ5OTEuNjA5OC44NjcyNSAxLjU2Ni0uNjg1NTcgMi44MTgxLTEuNDAyMyA0LjA0MjkuODYzMzQuNzQ4MDQgMS43MjUzIDEuNDk4IDIuNTkyMSAyLjI0NjYuODYyOC0uODYzNTMgMS43MjU1LTEuNzI4OSAyLjU3OTEtMi42MDQ3LTEuMjM0NC0yLjA0MTEtMS4wNTgyLTUuMjMxMSAxLjc5NDQtNS42MjkgMy4zOTM3LS42MjA5MyA0LjQxMTIgMy42NDI3IDIuNzc0NiA1LjkyNTUgMy4wNDIgMy44MjUgNS44MTQ0IDguMDcyNCA2Ljc1NjMgMTIuOTQ3IDEuMDYzOSA1LjU4MzctLjM1MjkyIDExLjM0My0yLjc2MzkgMTYuMzkzLjA3OTU2IDIuNTAzOC0uMTE4NyA1LjAwNDUtLjUxNjk3IDcuNDc2OCA0LjI2ODEtMS42Nzk1IDkuNTE4My0yLjQ4MTMgMTMuNTc3LjEzODQ4IDIuNjQxNyAxLjc3ODkgMi41MDYxIDUuMjYxMyAyLjE5ODEgOC4wNTc5LTYuMTY1LTMuMzA2LTEzLjQxMi0yLjg2OS0yMC4wOTItMS43NjYtMy4zMjEtMy41ODktOS42NzItMy41MjMtMTMuMDEyLjAxMy02LjY4OC0xLjE4MS0xMy44ODgtMS40NTYtMjAuMTEyIDEuNjk3LS4xOTU0LTIuODMxLS4zNDgxLTYuMzYyIDIuMzk3My04LjA5MSA0LjA2OTgtMi40OTc5IDkuMjUzOC0xLjczNjUgMTMuNDc3LS4wMTcyOS0uNDMzNzYtMi41MDU5LS42MjExNC01LjA0NTktLjUzNDkzLTcuNTg3LTIuNDY4LTQuMzY1NC00LjYzMDktOS40NDExLTMuNDczNC0xNC41NDcgMS4zNTQ0LTUuNTMwOSA0Ljk2Ni0xMC4xMTYgOC40Nzk5LTE0LjQ1Ny0uNDI4NzYtMS41NTEtMS4zMTkyLTMuMzY1OC0uMjE2MTItNC44NDkxeiIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im0zMi4yMzQgMzMuMTkzYzIuOTI4Mi0xLjU5ODEgNS40MTE3IDEuNDE3NCA2Ljc4MDkgMy42NTMyIDIuNzkzNCA0LjUwNjkgNS4yMDM4IDEwLjQyOCAyLjk2MDYgMTUuNjE1LTIuNzQ3LTEuOTc0LTIuNzIyLTUuNzQ4LTMuODU0LTguNjYzLS45MjItNC4wNzQtNC41MzItNi43NTQtNS44ODgtMTAuNjA1eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4OTYzMyIvPjxwYXRoIGQ9Im0zMi4yMzQgMzMuMTkzYzIuOTI4Mi0xLjU5ODEgNS40MTE3IDEuNDE3NCA2Ljc4MDkgMy42NTMyIDIuNzkzNCA0LjUwNjkgNS4yMDM4IDEwLjQyOCAyLjk2MDYgMTUuNjE1LTIuNzQ3LTEuOTc0LTIuNzIyLTUuNzQ4LTMuODU0LTguNjYzLS45MjItNC4wNzQtNC41MzItNi43NTQtNS44ODgtMTAuNjA1eiIvPjxwYXRoIGQ9Im0yMi4yMjYgNTYuMTdjLjE2OTQ3LTIuNjgxOSAzLjI1MzYtMi45NzI2IDUuMjk4NC0zLjM5MDEgMy45NzYxLS40NjYwNiA4LjE1NTQtLjYwMTQ3IDEyLjAwMi42Nzc4OS45MjQzNy40MzExMSAzLjM1NDYgMS41NDQgMS42NDg3IDIuNzMyNC02LjMwMDYtLjk0ODY3LTEyLjY0NS0uOTEzMzMtMTguOTQ5LS4wMjAyOHoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODk2MzMiLz48cGF0aCBkPSJtMjIuMjI2IDU2LjE3Yy4xNjk0Ny0yLjY4MTkgMy4yNTM2LTIuOTcyNiA1LjI5ODQtMy4zOTAxIDMuOTc2MS0uNDY2MDYgOC4xNTU0LS42MDE0NyAxMi4wMDIuNjc3ODkuOTI0MzcuNDMxMTEgMy4zNTQ2IDEuNTQ0IDEuNjQ4NyAyLjczMjQtNi4zMDA2LS45NDg2Ny0xMi42NDUtLjkxMzMzLTE4Ljk0OS0uMDIwMjh6Ii8+PHBhdGggZD0ibTI5LjE1OSA1Ny41OTljMi4wMTczLS40NzY4MyA0LjE0MTQtLjYwNjkxIDYuMDI0Ni40NDUzNS0xLjg3NC45MzI3LTQuNjMxOCAxLjYyNzgtNi4wMjQ2LS40NDUzNXoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wODk2MzMiLz48cGF0aCBkPSJtMjkuMTU5IDU3LjU5OWMyLjAxNzMtLjQ3NjgzIDQuMTQxNC0uNjA2OTEgNi4wMjQ2LjQ0NTM1LTEuODc0LjkzMjctNC42MzE4IDEuNjI3OC02LjAyNDYtLjQ0NTM1eiIvPjxwYXRoIGQ9Im0yMy4wNjIgNjUuMTE5Yy0uMjcyNDItMy4wNTQ4IDMuMTY0Ni0zLjQ0NTUgNS4zOTU0LTQuMDI4MiA0LjA3OTgtLjYwNzY4IDguOTA1NS0uNjU1MzIgMTIuMjE4IDIuMTYxNC4wMDUzLjUxOTIuMDE1OTEgMS41NTc2LjAyMTIgMi4wNzY4LTUuODA3Ny0xLjQ4NTctMTEuNzc1LS45NjU3Mi0xNy42MzQtLjIxMDA2eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4OTYzMyIvPjxwYXRoIGQ9Im0yMy4wNjIgNjUuMTE5Yy0uMjcyNDItMy4wNTQ4IDMuMTY0Ni0zLjQ0NTUgNS4zOTU0LTQuMDI4MiA0LjA3OTgtLjYwNzY4IDguOTA1NS0uNjU1MzIgMTIuMjE4IDIuMTYxNC4wMDUzLjUxOTIuMDE1OTEgMS41NTc2LjAyMTIgMi4wNzY4LTUuODA3Ny0xLjQ4NTctMTEuNzc1LS45NjU3Mi0xNy42MzQtLjIxMDA2eiIvPjwvZz48L2c+PHBhdGggZD0ibTUuNDgzOTIxOSA1NS41NTI1NDJjLjAwOTc4LTMuNDUwMDkgMS4zNDMwNzMzLTUuNDIzNDkgNC4zNzYwNzU3LTYuNDc2OTkyIDIuMjA4NzY4NC0uNzY3MjA2IDYuNDk0Mjk0NC0uNjU3MTI2IDkuMjMxNjU4NC4yMzcxMjhsMi4wODgyNjYuNjgyMjA1LS4xNDYwNjItMy42OTU3NDUtLjE0NjA2My0zLjY5NTc0OC0xLjMxNjU5My0yLjcxMTg2NWMtMS43NzUyMjQtMy42NTY1MzQtMi40MzMxMzQtNi4xNTI4NjYtMi40Mjg1OTMtOS4yMTQ4ODguMDA2My00LjI0MjczMyAxLjcxMDE4Ny04LjA4OTE5MiA2LjI4NTExOS0xNC4xODgzNTEgMS4zMDkwMzctMS43NDUxNjggMi4zMjY2MjctMy4zNTYwODMgMi4yNjEzMTItMy41Nzk4MTEtLjY5NDkyOC0yLjM4MDM5OS0uNzMyMTA4LTIuOTM4Nzc4Mi0uMjYxNjg5LTMuOTMwMTEyMiAxLjE3NTI5OS0yLjQ3Njc1OTUgNC41MDI0NDktMi4yMDY2MjQxIDUuNTA3NzQxLjQ0NzE4MDMuMjc0NDkuNzI0NjA3OS4wNTIzIDEuMzg0ODU1OS0xLjA2MzQ1NyAzLjE2MDE1MzktLjM3MzUzMS41OTQzMy0uMzMxMjM5LjY4MDYyOC44MjY2NjggMS42ODY4MjMuNjcxMTg3LjU4MzI0NiAxLjM0NzQ3MyAxLjA2NDA4OSAxLjUwMjg1OCAxLjA2ODU0LjE1NTM4OC4wMDQ1LjgxMTUzNC0uNTMwOTMyIDEuNDU4MTA1LTEuMTg5NzQgMS4xMTkzMTktMS4xNDA1MDMgMS4xNjA5Ni0xLjIzOTc4NC44NzAwMjMtMi4wNzQzNjUtLjQ0OTAwNi0xLjI4ODAxNC0uMzY3MDg0LTMuMDA5ODQ1OS4xNzUwNDUtMy42NzkxMTM2IDEuMTMxMzE3LTEuMzk2NjM0NiAyLjg3MTk3My0xLjU3MzM3ODMgNC4xNjAxMjUtLjQyMjQxMzUuNjg1ODE0LjYxMjc3MzguODc4MzAyIDEuMDI4NTQ2OC45ODM2MTggMi4xMjQ1ODIxLjA4NzQ0LjkxMDA0OC0uMDA0OCAxLjYyNTM1OS0uMjc3NzI4IDIuMTUzMzg2LS40MDIzMTguNzc4Mzg0LS4zODM4MjEuODI0Mzg4IDEuMTkwMTQgMi45NjAxNjMgMS44NjU2MjIgMi41MzE1NDIgNC4wNzYwMDUgNi42ODQ0OCA0LjY5MDk4IDguODEzNTYgMS40Mzg4NjEgNC45ODE0MTcuOTE1NjU4IDEwLjkwNDU3Ny0xLjQ1NTM5NSAxNi40NzY0NzItLjY2MTgwOSAxLjU1NTIyNy0uODI0MjYzIDIuMzIyODQyLS44Mjg2NDggMy45MTU0NDQtLjAwMyAxLjA4OTUyOS0uMTE5NDMxIDIuNzY5NjE5LS4yNTg3MzYgMy43MzM1MjYtLjEzOTMwNi45NjM5MTEtLjIyNzIzNiAxLjc3ODYxMi0uMTk1Mzk4IDEuODEwNDQ5LjAzMTg0LjAzMTg0Ljc3NDcyOC0uMTg0MTE0IDEuNjUwODYzLS40Nzk4OTcgNi41ODA5MDktMi4yMjE3IDEyLjgwMDAyMi0uNTc1NzM0IDEzLjk2NzAyMSAzLjY5NjU0OC4zNTQ5MzcgMS4yOTkzODcuMzk3ODE3IDQuNDc0NTc2LjA2MDQzIDQuNDc0NTc2LS4xMzEzOTUgMC0xLjAzMTMwOC0uMjk4MjYxLTEuOTk5ODA3LS42NjI4MDQtMy40MjEzNjEtMS4yODc3OTYtNS44Mjc0NTUtMS41OTg4NDItMTAuOTA5NDM3LTEuNDEwMzA1LTIuNTM4MDEyLjA5NDE2LTUuMTAyNzA0LjI2NjkzNy01LjY5OTMxNC4zODM5NTQtLjk3OTgzNS4xOTIxODItMS4yMjMzNzYuMTE2MDY1LTIuNTE4MTI0LS43ODcwMjEtLjc4ODM2LS41NDk4NzktMi4wNTI3NzUtMS4xNDgzNzItMi44MDk4MTQtMS4zMjk5ODItMi43NjcwNzYtLjY2MzgxMS02Ljg4Njk1NS4xOTY4NDgtOC4zMzg1IDEuNzQxOTQ3LS41NTM4MDEuNTg5NDk0LS42MjM1OTkuNTk1ODMyLTIuOTQxOTM2LjI2NzEzNy01LjU0MzUwNC0uNzg1OTYzLTExLjgzNjIyOS0uMzMxMDM3LTE1LjczODU4MzEgMS4xMzc4MDYtLjk2MzMzMzcuMzYyNTk4LTEuNzk4MDAzNi42NTkyNjgtMS44NTQ4MjE4LjY1OTI2OC0uMDU2ODE4IDAtLjEwMDYyNTktLjk0NTc2Mi0uMDk3MzUtMi4xMDE2OTV6bTM1LjI0ODI4MTEtNy4yMzQ1NTRjMC0xLjQyODA4Mi0uNTYwMTQ5LTEuOTc5Njg2LTIuOTM3NzYtMi44OTI5NDEtMy4xODE1NTYtMS4yMjIwNTktOS44MTc0ODctLjkwOTc5My0xMy4wMDE4NDEuNjExODI0LTEuMTg3MDc1LjU2NzIzNS0xLjk1ODcwNCAxLjYyNjgzMS0xLjk1ODcwNCAyLjY4OTY4NCAwIC41NTU3NzIuMDg0MjQuNTc5NjAxIDEuNDIxNzc0LjQwMjE3MiA1LjA5MTU5Ni0uNjc1NDI1IDEyLjIyNjg5OS0uNjMwMDMxIDE1LjEyMDU5OS4wOTYxOS41MjIwMzQuMTMxMDEzIDEuMDQwNjc4LjI1MDY5OSAxLjE1MjU0My4yNjU5NjYuMTExODY0LjAxNTI3LjIwMzM4OS0uNTEyNTM3LjIwMzM4OS0xLjE3Mjg5N3ptLTYuNTgwMzMzLTUuNjY3NDMzYzEuMjIxMjE1LS40NDMxNTQgMS4yMDI3NDQtLjc5NzM4My0uMDYzNzMtMS4yMjIzMjItMS4wOTM2ODctLjM2Njk2MS00LjU2OTUwNC0uMzEyMzEyLTQuOTU4ODM1LjA3Nzk3LS4xMDY1MzkuMTA2Nzk5LjE0ODY5MS40ODg4ODIuNTY3MTc3Ljg0OTA3NC42MDM0MTUuNTE5MzYgMS4wNTI0MDYuNjUwNjI4IDIuMTY5NDkyLjYzNDI2NS43NzQ3MzItLjAxMTM0IDEuODAzMzg5LS4xNjM4ODkgMi4yODU5LS4zMzg5ODN6bS0yLjM2ODgxOS0yLjc1OTAzYzMuMDU3NjI3IDAgNi41MzU1OTMuMDYxMDIgNy43Mjg4MTMuMTM1NTk0IDIuMTExODQuMTMxOTg5IDIuMTcxODczLjExODc4NSAyLjI1OTA4MS0uNDk2OTQxLjE5NzI4Ni0xLjM5MjkxNy0yLjAzMjg2NS0yLjUwODUwNy02LjA5NTQ2LTMuMDQ5MTM5LTMuODc2ODM2LS41MTU5MTEtOS44MTg0MzcuMDk4MzctMTIuMDM0MTcxIDEuMjQ0MTczLS43NDU2MjMuMzg1NTc2LTEuNjIwOTc1IDEuNjI3NDc3LTEuNjIwOTc1IDIuMjk5NzQ4IDAgLjIwNjgzNC42MzI5MTMuMjMxMzA4IDIuMTAxNjk1LjA4MTI2IDEuMTU1OTMyLS4xMTgwODMgNC42MDMzOS0uMjE0Njk5IDcuNjYxMDE3LS4yMTQ2OTl6bTEwLjgwMzcwNy00LjYzMDkyM2MuMjUwNDA1LS43MzM4OTguMzI0NDk0LTEuOTQ3MzkxLjIzODgxNS0zLjkxMTQ0OS0uMTM4MDU4LTMuMTY0Nzg4LS44MjUzMzctNS40ODg0NTEtMi41NjY3MTUtOC42Nzc5NjctMi4yOTU5MTgtNC4yMDUyMTMtNC4xNTM1ODktNS45NjkwMjUtNi4yNzkyMDgtNS45NjE5NDktMS43OTI0ODMuMDA2LTIuMDU5MjQ1LjI0MDEwMy0xLjU3MjUyOSAxLjM4MDIwMi4yMTYxODcuNTA2NDAyIDEuNDI2ODM0IDIuNDY2Njc1IDIuNjkwMzI3IDQuMzU2MTY0IDIuMDcwNTMgMy4wOTYzNjYgMi4zODM2ODYgMy43Mzg3MzMgMy4xNzI5MTEgNi41MDg0NzQuNDgxNjA2IDEuNjkwMTczIDEuMDc0NTE3IDMuNjU1MjU5IDEuMzE3NTgxIDQuMzY2ODU5LjQ5NDExNiAxLjQ0NjU5MiAxLjg1MzEwNCAzLjI1OTg3OCAyLjMyNjkwNyAzLjEwNDc3NS4xNjk4ODUtLjA1NTYxLjQ3MjI0NS0uNTc5OTEuNjcxOTExLTEuMTY1MTA5eiIgZmlsbD0iIzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii45ODc4MDE5NyIvPjwvc3ZnPg=='); } -body.base .is2d piece.rook.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMTQuNjg0IDI2LjY5NGMyLjI5NzQtLjAwMDUyNSA0LjU5NTItLjAwMDUyNSA2Ljg5MzctLjAwMDExOC0uMDAxIDEuNzIzNC0uMDAxIDMuNDQ2Ny0uMDAwODEgNS4xNzAzIDIuMDEwNC4wMDAzMTYgNC4wMjE0LjAwMDMzIDYuMDMzMy4wMDAwMTMtLjAwMS0xLjcyMzYtLjAwMS0zLjQ0Ny0uMDAwODctNS4xNzA1IDIuODcyLjAwMDE1OCA1Ljc0NDQuMDAwMTQ0IDguNjE3NS4wMDAwNTItLjAwMSAxLjcyMzUtLjAwMiAzLjQ0NjgtLjAwMDk1IDUuMTcwNSAyLjAxMDMuMDAwMjg5IDQuMDIxNC4wMDAzNDIgNi4wMzM1LjAwMDE0NS0uMDAxLTEuNzIzNi0uMDAyLTMuNDQ3LS4wMDEtNS4xNzA0IDIuMjk3Mi0uMDAwMzgyIDQuNTk1MS0uMDAwMzgyIDYuODk0LjAwMDA5Mi0uMDAxIDMuMTczLS4wMDEgNi4zNDU4LjAwMDIgOS41MTg5LTEuNDM2MiAxLjQ4MTctMi44NzM3IDIuOTYxNS00LjMwOTMgNC40NDI4LjAwNiA2LjI3MjYtLjAxMTggMTIuNTQ1LjAxIDE4LjgxOCAyLjYxNjEgMi4zNTM0IDMuMzc5NiA1Ljk5NTkgNi4xNDk1IDguMTkzMi4wMzkzIDIuMTM5Ny4wMzc3IDQuMjgwMS4wMzkzIDYuNDIxLTEyLjY5NS0uMDAwMjkxLTI1LjM5LS4wMDA4NzYtMzguMDg1LjAwMDIyMy0uMDAwNDctMi4xMzYuMDAwMTMtNC4yNzE1LjAyNzctNi40MDY1IDIuNzEyOS0yLjQwOTQgMy44MDA1LTYuMDc3MiA2Ljg2NC04LjE4My4wMTIyLTYuMjc5OS4wMDItMTIuNTYuMDA2LTE4LjgzOS0xLjcyNDEtMS40ODE3LTMuNDQ4Ni0yLjk2MjItNS4xNzExLTQuNDQ0Ni4wMDA1OS0zLjE3MzYtLjAwMDA1LTYuMzQ2OS4wMDA0NS05LjUyMDN6IiBmaWxsPSIjZmZmIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDg2MTcxIi8+PHBhdGggZD0ibTE0LjY4NCAyNi42OTRjMi4yOTc0LS4wMDA1MjUgNC41OTUyLS4wMDA1MjUgNi44OTM3LS4wMDAxMTgtLjAwMSAxLjcyMzQtLjAwMSAzLjQ0NjctLjAwMDgxIDUuMTcwMyAyLjAxMDQuMDAwMzE2IDQuMDIxNC4wMDAzMyA2LjAzMzMuMDAwMDEzLS4wMDEtMS43MjM2LS4wMDEtMy40NDctLjAwMDg3LTUuMTcwNSAyLjg3Mi4wMDAxNTggNS43NDQ0LjAwMDE0NCA4LjYxNzUuMDAwMDUyLS4wMDEgMS43MjM1LS4wMDIgMy40NDY4LS4wMDA5NSA1LjE3MDUgMi4wMTAzLjAwMDI4OSA0LjAyMTQuMDAwMzQyIDYuMDMzNS4wMDAxNDUtLjAwMS0xLjcyMzYtLjAwMi0zLjQ0Ny0uMDAxLTUuMTcwNCAyLjI5NzItLjAwMDM4MiA0LjU5NTEtLjAwMDM4MiA2Ljg5NC4wMDAwOTItLjAwMSAzLjE3My0uMDAxIDYuMzQ1OC4wMDAyIDkuNTE4OS0xLjQzNjIgMS40ODE3LTIuODczNyAyLjk2MTUtNC4zMDkzIDQuNDQyOC4wMDYgNi4yNzI2LS4wMTE4IDEyLjU0NS4wMSAxOC44MTggMi42MTYxIDIuMzUzNCAzLjM3OTYgNS45OTU5IDYuMTQ5NSA4LjE5MzIuMDM5MyAyLjEzOTcuMDM3NyA0LjI4MDEuMDM5MyA2LjQyMS0xMi42OTUtLjAwMDI5MS0yNS4zOS0uMDAwODc2LTM4LjA4NS4wMDAyMjMtLjAwMDQ3LTIuMTM2LjAwMDEzLTQuMjcxNS4wMjc3LTYuNDA2NSAyLjcxMjktMi40MDk0IDMuODAwNS02LjA3NzIgNi44NjQtOC4xODMuMDEyMi02LjI3OTkuMDAyLTEyLjU2LjAwNi0xOC44MzktMS43MjQxLTEuNDgxNy0zLjQ0ODYtMi45NjIyLTUuMTcxMS00LjQ0NDYuMDAwNTktMy4xNzM2LS4wMDAwNS02LjM0NjkuMDAwNDUtOS41MjAzeiIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im0yMS41NzggMzguNzU3YzcuMTgwNi0uMDAwMDQgMTQuMzYxLS4wMDAwNjYgMjEuNTQyLjAwMDAxMi0uMDAwOTUgMS40MzYtLjAwMDk1IDIuODcyLjAwMDA4IDQuMzA4NS03LjE4MTEuMDAwMDU0LTE0LjM2Mi0uMDAwMTMxLTIxLjU0My4wMDAwOTMtLjAwMS0xLjQzNjUtLjAwMS0yLjg3MjYuMDAwMDgtNC4zMDg2eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA4NjE3MSIvPjxwYXRoIGQ9Im0yMS41NzggMzguNzU3YzcuMTgwNi0uMDAwMDQgMTQuMzYxLS4wMDAwNjYgMjEuNTQyLjAwMDAxMi0uMDAwOTUgMS40MzYtLjAwMDk1IDIuODcyLjAwMDA4IDQuMzA4NS03LjE4MTEuMDAwMDU0LTE0LjM2Mi0uMDAwMTMxLTIxLjU0My4wMDAwOTMtLjAwMS0xLjQzNjUtLjAwMS0yLjg3MjYuMDAwMDgtNC4zMDg2eiIvPjxwYXRoIGQ9Im0yMS41NzggNTguNTc3YzcuMTgwNy0uMDAwMzQyIDE0LjM2MS0uMDAwMTE5IDIxLjU0My0uMDAwMTE5LS4wMDEgMS4xNDg0LS4wMDEgMi4yOTc0LjAwMDA3IDMuNDQ2OC03LjE4MTItLjAwMDA1Mi0xNC4zNjIgMC0yMS41NDMtLjAwMDAyNS0uMDAwODgtMS4xNDk0LS4wMDA4LTIuMjk4My4wMDAxOC0zLjQ0Njd6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDg2MTcxIi8+PHBhdGggZD0ibTIxLjU3OCA1OC41NzdjNy4xODA3LS4wMDAzNDIgMTQuMzYxLS4wMDAxMTkgMjEuNTQzLS4wMDAxMTktLjAwMSAxLjE0ODQtLjAwMSAyLjI5NzQuMDAwMDcgMy40NDY4LTcuMTgxMi0uMDAwMDUyLTE0LjM2MiAwLTIxLjU0My0uMDAwMDI1LS4wMDA4OC0xLjE0OTQtLjAwMDgtMi4yOTgzLjAwMDE4LTMuNDQ2N3oiLz48L2c+PC9nPjxwYXRoIGQ9Im0xMy4wNzExODYgNTQuODM5OTg0YzAtMi40NzM4MzMuMDg0NDUtMy4xNTU1MjguNDI2MDYxLTMuNDM5MDM4LjIzNDMzMy0uMTk0NDc4IDEuNDI0MTYzLTEuNzUzNDg2IDIuNjQ0MDY3LTMuNDY0NDU4IDEuMjE5OTA1LTEuNzEwOTc1IDIuNTUzNjAxLTMuMzU5MjM4IDIuOTYzNzcxLTMuNjYyODA5bC43NDU3NjItLjU1MTk0OS0uMDA1OC05LjY0MzkxNS0uMDA1OC05LjY0MzkxNy0yLjU2MjA5OS0yLjE2OTQ5MS0yLjU2MjA5OC0yLjE2OTQ5Mi0uMDA4My00LjY3Nzk2Ni0uMDA4My00LjY3Nzk2NmgzLjM4OTgzMSAzLjM4OTgzdjIuNTc2MjcxIDIuNTc2MjcxaDMuMTE4NjQ0IDMuMTE4NjQ0di0yLjU3NjI3MS0yLjU3NjI3MWg0LjIwMzM5IDQuMjAzMzl2Mi41NzYyNzEgMi41NzYyNzFoMy4xMTg2NDQgMy4xMTg2NDR2LTIuNTc2MjcxLTIuNTc2MjcxaDMuMzg5ODMxIDMuMzg5ODN2NC42ODQzMjggNC42ODQzMjhsLTIuMTY5NDkxIDIuMTU2NzY4LTIuMTY5NDkyIDIuMTU2NzY3djkuNjU5MjQ3YzAgOS40Mzg5OTMuMDEyODUgOS42NzA4ODcuNTY0MTI1IDEwLjE2OTc3My4zMTAyNy4yODA3ODkgMS4yMzkxMjkgMS42MTE1NjkgMi4wNjQxMzMgMi45NTcyODUuODI1MDAzIDEuMzQ1NzE3IDEuODk5NjE1IDIuODczODc3IDIuMzg4MDI3IDMuMzk1OTExLjg2ODc2Mi45Mjg1NjkuODkyMDU0IDEuMDE4MjUxIDEuMDc0MTAxIDQuMTM1NTkzbC4xODYwODMgMy4xODY0NDFoLTE5LjAwMjY0MS0xOS4wMDI2NDJ2LTMuMDg1NDR6bTMwLjEwMTY5NS0xMC40NzM4ODJ2LTEuODk4MzA1aC0xMC44NDc0NTctMTAuODQ3NDU4djEuODk4MzA1IDEuODk4MzA1aDEwLjg0NzQ1OCAxMC44NDc0NTd6bTAtMTkuMzg5ODMxdi0yLjMwNTA4NWgtMTAuODQ3NDU3LTEwLjg0NzQ1OHYyLjMwNTA4NSAyLjMwNTA4NWgxMC44NDc0NTggMTAuODQ3NDU3eiIgZmlsbD0iIzMzMyIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9Ii45ODc4MDE5NyIvPjwvc3ZnPg=='); } -body.base .is2d piece.queen.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMjIuMzIyIDI3Ljc3NWMtLjE2MzU0LTMuMTg3OSAxLjE0MDctMy42MTIzIDMuMjM0NC0xLjE0NTkgMS45NzEgMS44Nzk1LjIyOTg2IDIuNTQ5MiAxLjQ0MzIgNC43MDIyIDEuNDY3NiAzLjIxOTkgMy4wNjU2IDYuMzc4OCA0LjU1OTkgOS41ODY4IDEuNjE4Ny0zLjMxMTUgMy4zODQ3LTYuNTUwNyA0Ljk1MzgtOS44ODU3IDEuMDc3OC0yLjI0NjIuNzc4MTgtMy41NzY1IDMuMTI3LTUuMTk5MSAyLjI3MjgtMS43NjA2LjkzNjgxLTIuNzU4OS43ODUxNC4xMzIxMi4yNTkyMSAyLjA2OTguNTc2MTggMi45NjYzLjg5MDk5IDUuMTgzMiAxLjMyNzMgNS4yNjUyIDIuNTI0NCAxMC41NjIgMy43OTk4IDE1Ljg0IDIuNDgwNi0xLjkxMjUgNC45NjQ2LTMuODIwNyA3LjQyOTQtNS43NTM4LjMzNTc1LTEuNTE5OCAxLjU0NDktLjA2MzAyIDMuMTIxNS0uOTcyMjYgMi4xNjctMS42MTQ2LjE3MTAxLTIuNTMxNy0uMzI2NS4xMTgwNS0uMTgyODMgMS44NTMxIDEuNzY4MiAxLjk5Ny4zODAxOCAyLjczNzktMS43OTAyIDQuMjAzMS0zLjk2MSA4LjI0MTQtNS42MjUxIDEyLjQ5Ni0uOTExMTQgNC44MDk2LTEuMDI1NyA5Ljc0MTQtMS42MzA5IDE0LjU5OS02LjQ0NCAzLjk5NC0xNC4zNDMgNC4yNzQtMjEuNjg5IDMuNzIyLTQuMDE2LS4yNzQtOC4wMzQtMS4zMjMtMTEuMzYzLTMuNjU5LS42NzctNC44MTMtLjk4MS05LjY4NC0xLjg2NS0xNC40NjItMS42MDMtNC4yOTktMy42OTU3LTguNC01LjQyMzItMTIuNjUxLTEuNzMxMS0uNzA2LS44MjYxLTIuNTk1LS40MjcyLTQuODQ3LjI2MTYxLTMuMjE5Ny0uMTEwMDItMi4yNzIuOTk5NDUuNzMxMjQuMDM4Ny43OTExOCAyLjMyODQgMS41NDM5IDIuMzY3MiAyLjMzNTEgMi4zMDQzIDEuODgyOCA0LjYyMjQgMy43NDg2IDYuOTM4OSA1LjYxNjcgMi4xNDk1LTcuNTYyOSAzLjM5ODYtMTMuMDY2IDQuMzItMTkuMjI1eiIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im0yMC45MDMgNTMuNTYxYzguMDczOC0xLjYyMjIgMTYuODIyLTEuODE4NiAyNC42MjIgMS4xMTk1IDEuNTQzMi4zMjYzOSAxLjUzNjMgMi4wODgxIDIuMDY4MyAzLjI1MzktNC43NjQzLS4yNjk2Ny05LjQ1MTEtMS40MDM5LTE0LjI0My0xLjMzNjEtNS43NjkxLS4yNjc3NC0xMS40OC42MjAyNi0xNy4xNzEgMS40MDM0LTEuNDM4NC0zLjE0ODMgMi41OTg4LTMuNzYzOCA0LjcyNDMtNC40NDA2eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA5MjQ5NiIvPjxwYXRoIGQ9Im0yMC45MDMgNTMuNTYxYzguMDczOC0xLjYyMjIgMTYuODIyLTEuODE4NiAyNC42MjIgMS4xMTk1IDEuNTQzMi4zMjYzOSAxLjUzNjMgMi4wODgxIDIuMDY4MyAzLjI1MzktNC43NjQzLS4yNjk2Ny05LjQ1MTEtMS40MDM5LTE0LjI0My0xLjMzNjEtNS43NjkxLS4yNjc3NC0xMS40OC42MjAyNi0xNy4xNzEgMS40MDM0LTEuNDM4NC0zLjE0ODMgMi41OTg4LTMuNzYzOCA0LjcyNDMtNC40NDA2eiIvPjxwYXRoIGQ9Im0yOS4xNCA1OC45MTZjMS44OTg4LS43NzgwNiA0Ljg3NDktLjkzNTU2IDUuNzcxIDEuMzU2NS0uODQxNjMgMy4yOTU3LTguNTk1MiAyLjAyNTEtNS43NzEtMS4zNTY1eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA5MjQ5NiIvPjxwYXRoIGQ9Im0yOS4xNCA1OC45MTZjMS44OTg4LS43NzgwNiA0Ljg3NDktLjkzNTU2IDUuNzcxIDEuMzU2NS0uODQxNjMgMy4yOTU3LTguNTk1MiAyLjAyNTEtNS43NzEtMS4zNTY1eiIvPjxwYXRoIGQ9Im0xNi40NzggNjIuMTE4YzEuNDE4My0uOTYzMDggMy4wMTU0LS44MzM2MyA0LjUyNTctLjEzNzg2LTEuMzE1OC41NTA3Mi00LjQ2MSAzLjAyMjctNC41MjU3LjEzNzg2eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA5MjQ5NiIvPjxwYXRoIGQ9Im0xNi40NzggNjIuMTE4YzEuNDE4My0uOTYzMDggMy4wMTU0LS44MzM2MyA0LjUyNTctLjEzNzg2LTEuMzE1OC41NTA3Mi00LjQ2MSAzLjAyMjctNC41MjU3LjEzNzg2eiIvPjxwYXRoIGQ9Im00Mi4zNzggNjIuMDExYzEuODk5Ny0xLjE5MyAzLjgwOC0uNDc2ODggNS4xMDExIDEuMTk3MS0xLjg0NzkuNDcwNDctMy41OTAyLS4xNDE1My01LjEwMTEtMS4xOTcxeiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA5MjQ5NiIvPjxwYXRoIGQ9Im00Mi4zNzggNjIuMDExYzEuODk5Ny0xLjE5MyAzLjgwOC0uNDc2ODggNS4xMDExIDEuMTk3MS0xLjg0NzkuNDcwNDctMy41OTAyLS4xNDE1My01LjEwMTEtMS4xOTcxeiIvPjxwYXRoIGQ9Im0yMC41MDkgNjUuMjU2YzYuMjEwOS0xLjcxMiAxMi44MjgtMS41MDUzIDE5LjE2OS0uNzA2OTMgMi40MzE1LjM5MDA5IDYuMjM5OSAxLjE1ODUgNS40MjI2IDQuNDk3LTguNjkzNC0zLjA3OTctMTguNDAyLTMuMTA3Ny0yNy4wODYuMDE5NjMtLjQxNzIxLTEuODczNS42Njg4OC0zLjQyMjkgMi40OTQzLTMuODA5N3oiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wOTI0OTYiLz48cGF0aCBkPSJtMjAuNTA5IDY1LjI1NmM2LjIxMDktMS43MTIgMTIuODI4LTEuNTA1MyAxOS4xNjktLjcwNjkzIDIuNDMxNS4zOTAwOSA2LjIzOTkgMS4xNTg1IDUuNDIyNiA0LjQ5Ny04LjY5MzQtMy4wNzk3LTE4LjQwMi0zLjEwNzctMjcuMDg2LjAxOTYzLS40MTcyMS0xLjg3MzUuNjY4ODgtMy40MjI5IDIuNDk0My0zLjgwOTd6Ii8+PC9nPjxnIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggZD0ibTEyLjUgMTIuNWE0LjgyMTQgMy43NSAwIDEgMSAtLjAwMDI1NS0uMDM4NTciIHRyYW5zZm9ybT0ibWF0cml4KC43NDM1MiAwIDAgLjkwMzgxIDIuMzI2NyAyOC41OTEpIi8+PHBhdGggZD0ibTEyLjUgMTIuNWE0LjgyMTQgMy43NSAwIDEgMSAtLjAwMDMxNi0uMDQyOTYiIHRyYW5zZm9ybT0ibWF0cml4KC43NDM1MiAwIDAgLjkwMzgxIDUwLjI1NSAyOC43NikiLz48cGF0aCBkPSJtMTIuNSAxMi41YTQuODIxNCAzLjc1IDAgMSAxIC0uMDAwMDg3LS4wMjI1NCIgdHJhbnNmb3JtPSJtYXRyaXgoLjgzODE1IDAgMCAxLjAyNTUgMTcuMjYzIDEzLjg0NikiLz48cGF0aCBkPSJtMTIuNSAxMi41YTQuODIxNCAzLjc1IDAgMSAxIC0uMDAwMjI3LS4wMzYzNyIgdHJhbnNmb3JtPSJtYXRyaXgoLjgzODE1IDAgMCAxLjAyNTUgMzMuMjYxIDEyLjg3NykiLz48L2c+PC9nPjxwYXRoIGQ9Im0yNS4xMzEzOTkgNTcuNjQyODc3Yy0yLjM1MzEzNS0uMzA3NzItNC44Njc5MjEtMS4wMDI3NjktNi43NTYzODktMS44NjczNjItMi45NTY3ODYtMS4zNTM2OTUtMi43OTQ4MjQtMS4wMTMwODUtMy41NTU0NDctNy40NzcyMS0uOTQyNzU5LTguMDEyLTEuMDQwOTU4LTguNDM0ODk2LTMuMDE4MzEtMTIuOTk4NDQ2LS45NzM4MS0yLjI0NzQ2Ni0yLjE0ODIxNjUtNC45NzI5MzMtMi42MDk3OTI3LTYuMDU2NTk1LS43NjU1NDQxLTEuNzk3MzAyLS45Mjc1MjAyLTEuOTk0MDctMS44NDQ4MS0yLjI0MTA3MS0xLjM2OTU0MDQtLjM2ODc3OC0yLjY4MjI0MzUtMS44OTExNTUtMi42ODIyNDM1LTMuMTEwNjY4IDAtMi4wMTQ3MzcgMi42OTYyMTYxLTMuNzk1MDU1IDQuNzMwNjIyNC0zLjEyMzY0MSAxLjQ5NjgzOTguNDk0MDAyIDEuOTA5ODkzOCAxLjE3ODIyMSAxLjk0MDExNDggMy4yMTM3NzZsLjAyNjY3IDEuNzk2MzQ1IDMuMzAwNTEzIDIuNjkwMDI5YzEuODE1MjgzIDEuNDc5NTE3IDMuMzU2OTY3IDIuNjMzNTc3IDMuNDI1OTY1IDIuNTY0NTc5LjI0MjcyNi0uMjQyNzI2IDMuMDcwNzA0LTExLjc4MzA3MyAzLjUzODkxNS0xNC40NDE1MThsLjQ3MzgxNC0yLjY5MDI2MS0uNjUwNTA5LS41MjYyMDZjLTEuNzIxMDk3LTEuMzkyMjE5LTIuMDYxODYxLTMuMTI5NDg1LS44ODc1ODQtNC41MjUwMzQ4IDEuNTg5NTUxLTEuODg5MDczOSA0LjY0NjU1Ni0yLjUzOTM0MDQgNS45MjU0NjktMS4yNjA0Mjc2IDEuMzAzMjI3IDEuMzAzMjI2OCAxLjQ5MzU4MSA0LjA3NjA0MTQuMzg3NzEgNS42NDc2Mzg0LS41MDkwMS43MjMzNzQtLjUwODk2Mi43NTU4NDMuMDAzIDIuMDMzODk4LjI4NjEzLjcxNDMzNCAxLjQ1ODc3MiAzLjI1MTMzMiAyLjYwNTg3IDUuNjM3NzczbDIuMDg1NjMyIDQuMzM4OTgzIDIuNTMyMDQ2LTUuMDE2OTVjMS4zOTI2MjctMi43NTkzMjIgMi43MzcyNDUtNS42MTM2MTcgMi45ODgwNDEtNi4zNDI4NzkuNDIwMzM5LTEuMjIyMjQ3LjQyMTQ5OS0xLjM0NTIzNC4wMTQ4Ni0xLjU3MjgtLjY2Mzk4OS0uMzcxNTg4LTEuMjU0NjgtMS42OTY2ODItMS4yNTQ2OC0yLjgxNDYyMjEgMC0uNzg5MzM4Ni4yMTE4NC0xLjIwNjM2NDMgMS4wMjY3OC0yLjAyMTMwNDMgMi4zOTExOTUtMi4zOTExOTUgNS43NzExNzMtMS44NjI4MDkxIDYuNTQ4NDMxIDEuMDIzNzA0My41MjA1MjQgMS45MzMwNzgxLS4xMzQyOTEgMy43Nzg4MDMxLTEuNjExNjYzIDQuNTQyNzgxMS0uNDQ2MDUzLjIzMDY2NC0uODExMDA1LjYxNjYyLS44MTEwMDUuODU3NjgxIDAgLjYzMTQxNCAzLjg1MjA0OSAxNi43Mjc4MDQgNC4wNjI0NDMgMTYuOTc1NTU0LjA5Njg5LjExNDA5IDEuODE1Njk0LTEuMDcwMTAxIDMuODE5NTY5LTIuNjMxNTM2IDMuNTYzOTU3LTIuNzc3MDYxIDMuNjQzOTU3LTIuODYyNTE2IDMuNjY4MzgtMy45MTg0ODYuMDgwMzgtMy40NzU0NzMgNC45NTU3NzItNC44ODI5MTQgNi41MDkxMi0xLjg3OTA3MSAxLjA5NzcxNiAyLjEyMjc1MS0uMzMxMDg2IDQuODMxODI2LTIuNTQ4Mzc1IDQuODMxODI2aC0xLjAyMjY3NmwtMS40NTkyOTIgMy4xODY0NDFjLTQuNTQ1NzAxIDkuOTI1Nzg0LTQuMjYzNzQzIDguOTM1MDk3LTUuMTQ3NjEgMTguMDg2NTE2LS42MDE2ODkgNi4yMjk4MDktLjM3NzgxNyA1LjgwNzgyOS0zLjgxMzc2MyA3LjE4ODU4OS0yLjM2MjQ3OC45NDkzOC00LjUyMTAxNyAxLjUyMDMwNi03LjE4NjQ0IDEuOTAwNzk3LTIuMTk2MjU4LjMxMzUxMy0xMC4zNTM2NDYuMzEyOTktMTIuNzUzMzQ3LS4wMDA4MTR2LS4wMDAwMDh6bS0uNTM0Nzg5LTYuMTQ4NDIzYzEuNzM2MzExLS4zMjgyNTIgMy44MTAyODItLjQ1Nzg4NSA3LjE4NjQ0MS0uNDQ5MTgyIDQuOTE5NjEyLjAxMjY5IDcuNzUwOTk0LjQyMDM2OSAxMS43OTY2MSAxLjY5ODU4MmwxLjYyNzExOS41MTQwODguMDg2ODctLjk2NTg2OWMuMTcwMjY5LTEuODkzMTE0LTEuMjYxNjktMy4wMDk1MDItNC44MzI2MzUtMy43Njc2MzEtMy4zNDI3OTYtLjcwOTY5NS0xNC4zMDcwMjMtLjcxMzU3LTE3LjYyNzExOS0uMDA2Mi0xLjI2Nzc5Ni4yNzAxMDEtMi43MzIyMDMuNjk3MjItMy4yNTQyMzcuOTQ5MTUyLTEuMTA2MzI1LjUzMzkxMi0yLjAzNzU0IDIuMTcxNDcxLTEuNzkxNzQxIDMuMTUwODEybC4xNjA0OTUuNjM5NDY2IDIuMTAzNzU5LS42NTA4ODVjMS4xNTcwNjctLjM1Nzk4IDMuMjAyMDYzLS44NTg1MTcgNC41NDQ0MzYtMS4xMTIyOTZ6bS00Ljg4NzM2NC00LjYwODU3NWMuODIzNjQ0LS40MDM5NTEgMS40OTc1MzQtLjgyMjMxOCAxLjQ5NzUzNC0uOTI5NzAzIDAtLjEwNzM4NC0uNjQzNDczLS4zMzkyNDktMS40Mjk5NC0uNTE1MjUxLTEuMTk3NjUyLS4yNjgwMjUtMS41OTQxMy0uMjUxNDA0LTIuNDQwNjc4LjEwMjMwOC0xLjA0NTU3Mi40MzY4NjctMS4zMTQwMDYgMS4xMjI5OTEtLjY4NTMxNSAxLjc1MTY4Mi41MTA0ODkuNTEwNDkgMS40MzU4NzMuMzg2NzI2IDMuMDU4Mzk5LS40MDkwMzZ6bTI3LjUzMTQzMi40NTEyM2MuMzQwNDg1LS4yMzAxMTguMjU4NjQ0LS40MDIxNS0uNTAyMTgtMS4wNTU1OS0xLjA4NDEzMy0uOTMxMTE0LTIuMzM2MzQyLTEuMjE4NTYzLTMuNTE2MzkxLS44MDcxOTUtMS4wOTE0NTIuMzgwNDgtMS4wODc2MzQuNjU5ODgxLjAxNjgxIDEuMjMxMDEzIDEuNzE5MzMuODg5MTAxIDMuMjYwOTA4IDEuMTMyNDc3IDQuMDAxNzU0LjYzMTc3MnptLTEyLjgxOTQ0Ny0xLjk2MDQ5OWMuNjE0MjQ2LS42MTQyNDUuNjg1OTc0LS44MzYzOTguNDY3NDMzLTEuNDQ3NzE4LS4xNDE5ODUtLjM5NzE3MS0uNjgzMzctLjk0OTQxMy0xLjIwMzA3OC0xLjIyNzIwNS0yLjU5OTM5OS0xLjM4OTQyNC02LjM0ODcxNy4zNTQzNjItNS4wNDM4MzggMi4zNDU4Ni42Mzg4NTMuOTc1MDEgMS4zNzU0NTQgMS4yMjQwMDMgMy4zNTE4MzYgMS4xMzMwMTIgMS40MjUzNTMtLjA2NTYyIDEuODIwMDE5LS4xOTYzMiAyLjQyNzY0Ny0uODAzOTQ5em0tMTMuNDg1NjM4LTMuODg1MDA2YzEuNzE1MjU0LS4yMzYwNyA1LjgwMzM5LS40OTMwNjggOS4wODQ3NDYtLjU3MTExIDUuNzU3ODg3LS4xMzY5NDEgOC45ODU5MjguMDgzNTEgMTYuNzQ1NzYzIDEuMTQzNTk4LjU1OTMyMi4wNzY0MSAxLjAxNjk0OS4wODEwNSAxLjAxNjk0OS4wMTAzIDAtLjA3MDc0LS4yNTA0NDktLjc5ODAwOS0uNTU2NTUzLTEuNjE2MTQzLS41MjkzMDUtMS40MTQ2OTktLjYzMTczNy0xLjUxNTY1MS0yLjA5MjM1My0yLjA2MjEzNy01LjcwMzQ0OS0yLjEzMzkzNy0xNC4wNzY2MTYtMi43MTMxOTEtMjEuNDg2Njg3LTEuNDg2NDQ2LTUuNjY1NTQxLjkzNzkzMy03Ljg2NDQwNyAyLjAzMTEzNC03Ljg2NDQwNyAzLjkwOTkxNyAwIDEuMjYwMDYyLjE1NDI2NCAxLjQxOTY0MiAxLjIwMDk0NyAxLjI0MjMzNS40NTgxMjMtLjA3NzYxIDIuMjM2MzQxLS4zMzQyNDggMy45NTE1OTUtLjU3MDMxOXoiIGZpbGw9IiMzMzMiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIuOTg3ODAxOTciLz48L3N2Zz4='); } -body.base .is2d piece.king.black { background-image: url('data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNjQgNjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMTYpIj48cGF0aCBkPSJtMjQuMjUxIDIzLjIxMmM1LjE4MDMtLjAwMzQgMTAuMzYxLS4wMDM1IDE1LjU0My4wMDAwMjguMDAwNzMgMy44NjU5LS4wMDEyIDcuNzMxNy0uMDAwNTA0IDExLjU5OCAzLjAyMTYtMS45Mzc3IDYuNDgzMy0zLjU5MjUgMTAuMTgxLTMuMTcwNSA0LjY0ODYuMjI4ODQgOS4wMDEgNC4yMDU4IDguOTM2NSA4Ljk5NzktLjA1MTg5IDYuNDU4Ny00LjIzMDcgMTIuMDc5LTkuMDU5MiAxNi4wMDEtLjI5MTA4IDQuNDExNC0uNTIwOTkgOC44MjY1LS43NzEzOCAxMy4yNDEtNC4xMjIgNC4wNjYtMTAuMjY4IDQuMDgzLTE1LjY3IDQuMTk5LTUuMDM5LS4wNTgtMTAuMzEyLjE4Ny0xNS4wNTItMS44MDMtMS40NTQtLjczNS0zLjM0OS0xLjcyLTMuNDI1LTMuNTY4LS4zNjYtNC4wMjEtLjQ0OS04LjA2My0uNzQ3LTEyLjA4OS00LjkxMDQtMy44MjctOC44OTMtOS41NTUtOS4wOTY5LTE1Ljk0LS4xMjUyNS00Ljg0OTcgNC4zNTQ2LTguNzk3IDkuMDExLTkuMDQ2IDMuNjgyMi0uMzg4MzIgNy4xMzMgMS4yNTIgMTAuMTUgMy4xODEyLS4wMDEyLTMuODY3MS0uMDAzMS03LjczMzktLjAwMDI2Ni0xMS42MDF6IiBmaWxsPSIjZmZmIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDkxNTYzIi8+PHBhdGggZD0ibTI0LjI0NyAyMy4yMWMtLjAwMjggMy44NjctLjAwMTIgNy43NDQ1IDAgMTEuNjEyLTMuMDE3MS0xLjkyOTItNi40NjkzLTMuNTgyMS0xMC4xNTItMy4xOTM4LTQuNjU2NC4yNDg5Ny05LjEzNjIgNC4yMDY4LTkuMDEwOSA5LjA1NjYuMjAzODggNi4zODQ2IDQuMTkyMSAxMi4wOTcgOS4xMDIyIDE1LjkyMy4yOTgwNCA0LjAyNjQuMzg2MjMgOC4wNjk1Ljc1MjgxIDEyLjA5MS4wNzU2NiAxLjg0NzYgMS45Njg0IDIuODQ3IDMuNDIxOSAzLjU4MTYgNC43NCAxLjk5MDYgMTAuMDE3IDEuNzQ0OSAxNS4wNTYgMS44MDIyIDUuNDAxOC0uMTE1ODggMTEuNTUtLjEzMTU2IDE1LjY3Mi00LjE5NzUuMjUwMzktNC40MTQxLjQ2MTczLTguODQyNy43NTI4MS0xMy4yNTQgNC44Mjg1LTMuOTIxOSA5LjAyNzUtOS41MzI5IDkuMDc5NC0xNS45OTIuMDY0NS00Ljc5MjEtNC4yOTM5LTguNzU5My04Ljk0MjUtOC45ODgxLTMuNjk4MS0uNDIxOTItNy4xNTI3IDEuMjMzMy0xMC4xNzQgMy4xNzA5LS4wMDA3My0zLjg2NjEuMDAwNzMtNy43NDU2IDAtMTEuNjEyLTUuMTgyLS4wMDM1LTEwLjM3OC0uMDAzNC0xNS41NTggMHptNy40MTQgMTQuNTc3YzEuNjk5MS0uMTQxODEgMy41NjQzIDEuMDA2NCAzLjYwNDQgMi44Mjg4LjM3NzIxIDIuNjg5NS0zLjMwNTggNC4yOTE0LTUuMjY5NyAyLjY0NjItMS42OTg3LTEuMDQ4My0xLjYzMjktMy44ODM5LjA5MTI1LTQuODgxOS40NTgwNy0uMzU4MTkgMS4wMDc3LS41NDU4NSAxLjU3NDEtLjU5MzEyeiIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im0yNi4xODggMjYuNjUyYy42MDY3NS0uNzcwNzUgMS4yMTc4LTEuNTQgMS44MzMyLTIuMzA3OSAxLjM1MzYgMS4xMjM0IDIuNjgwNCAyLjI4MDcgMy45OTc5IDMuNDUwNSAxLjMxNzEtMS4xNjkxIDIuNjQ1NC0yLjMyNjEgNC4wMDQ4LTMuNDUuNjA4ODguNzY3MjUgMS4yMTg4IDEuNTM2IDEuODI5NyAyLjMwNjItMS4xNTQ3IDEuMDQ5Ny0yLjMxMzIgMi4wOTU0LTMuNDY3NiAzLjE0MDMgMS4yMDk5IDEuMTA0NCAyLjQxODkgMi4yMTIzIDMuNjEzOCAzLjMzODMtLjQ3OTEyLjU1MDQ1LTEuNDM3NCAxLjY1MTQtMS45MTY1IDIuMjAxOC0xLjM2ODEtMS4xNDIyLTIuNzE4Mi0yLjMwNTMtNC4wNTc3LTMuNDc2LTEuMzQ5IDEuMTY3Mi0yLjcwMDIgMi4zMjk3LTQuMDY3MSAzLjQ3Mi0uNDc4ODItLjU0OTQtMS40MzY1LTEuNjQ4Mi0xLjkxNTMtMi4xOTc2IDEuMTg5Ni0xLjEyNjUgMi4zOTg0LTIuMjM0NCAzLjYxNDQtMy4zMzY5LTEuMTYxNC0xLjA0NTItMi4zMTY5LTIuMDkxMy0zLjQ2OTYtMy4xNDA5eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA5MTU2MyIvPjxwYXRoIGQ9Im0yNi4xODggMjYuNjUyYy42MDY3NS0uNzcwNzUgMS4yMTc4LTEuNTQgMS44MzMyLTIuMzA3OSAxLjM1MzYgMS4xMjM0IDIuNjgwNCAyLjI4MDcgMy45OTc5IDMuNDUwNSAxLjMxNzEtMS4xNjkxIDIuNjQ1NC0yLjMyNjEgNC4wMDQ4LTMuNDUuNjA4ODguNzY3MjUgMS4yMTg4IDEuNTM2IDEuODI5NyAyLjMwNjItMS4xNTQ3IDEuMDQ5Ny0yLjMxMzIgMi4wOTU0LTMuNDY3NiAzLjE0MDMgMS4yMDk5IDEuMTA0NCAyLjQxODkgMi4yMTIzIDMuNjEzOCAzLjMzODMtLjQ3OTEyLjU1MDQ1LTEuNDM3NCAxLjY1MTQtMS45MTY1IDIuMjAxOC0xLjM2ODEtMS4xNDIyLTIuNzE4Mi0yLjMwNTMtNC4wNTc3LTMuNDc2LTEuMzQ5IDEuMTY3Mi0yLjcwMDIgMi4zMjk3LTQuMDY3MSAzLjQ3Mi0uNDc4ODItLjU0OTQtMS40MzY1LTEuNjQ4Mi0xLjkxNTMtMi4xOTc2IDEuMTg5Ni0xLjEyNjUgMi4zOTg0LTIuMjM0NCAzLjYxNDQtMy4zMzY5LTEuMTYxNC0xLjA0NTItMi4zMTY5LTIuMDkxMy0zLjQ2OTYtMy4xNDA5eiIvPjxwYXRoIGQ9Im0xMS45NjkgNDMuNDI1Yy4xMjYxNy0zLjY5NjcgNC43NDM4LTQuNzA4MSA3LjU5NDktMy41MDM1IDUuMjg3OCAxLjY4NzggNy45MDQxIDcuMDYzOSA5Ljc0NzEgMTEuODczIDEuODIyNi0uMDIwNjggMy42NDg5LS4wMzgxIDUuNDc2NS0uMDcxNDggMS43NDcxLTQuODI5OSA0LjU2MzEtOS45NjY4IDkuNjg1Ni0xMS43OTggMi44MzY2LTEuMjMzNCA3LjQ3NzEtLjE4MjM0IDcuNTk4OSAzLjUwNDQtLjE1MDg3IDQuMTIyOC0yLjcwNzMgNy42NTQ5LTUuODA3NSAxMC4xNzEuNzY2MTQgMS4xMDI4IDEuMzA4IDIuMzA3NiAxLjI2MjcgMy42ODYyLTQuNjgwNS0uOTg4MzctOS4zMzA4LTIuMzAyNi0xNC4xNDctMi4zOTQ3LTUuNzMxNS0uMzA0OTgtMTEuMzE1IDEuMTU4Ni0xNi44NTQgMi4zOTQ1LS4wNjEzMS0xLjM4LjQ2NDE0LTIuNTg2NSAxLjI3MjUtMy42NzE2LTMuMTI2My0yLjUwNTYtNS43MDg5LTYuMDQ2Ny01LjgzLTEwLjE5eiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA5MTU2MyIvPjxwYXRoIGQ9Im0xMS45NjkgNDMuNDI1Yy4xMjYxNy0zLjY5NjcgNC43NDM4LTQuNzA4MSA3LjU5NDktMy41MDM1IDUuMjg3OCAxLjY4NzggNy45MDQxIDcuMDYzOSA5Ljc0NzEgMTEuODczIDEuODIyNi0uMDIwNjggMy42NDg5LS4wMzgxIDUuNDc2NS0uMDcxNDggMS43NDcxLTQuODI5OSA0LjU2MzEtOS45NjY4IDkuNjg1Ni0xMS43OTggMi44MzY2LTEuMjMzNCA3LjQ3NzEtLjE4MjM0IDcuNTk4OSAzLjUwNDQtLjE1MDg3IDQuMTIyOC0yLjcwNzMgNy42NTQ5LTUuODA3NSAxMC4xNzEuNzY2MTQgMS4xMDI4IDEuMzA4IDIuMzA3NiAxLjI2MjcgMy42ODYyLTQuNjgwNS0uOTg4MzctOS4zMzA4LTIuMzAyNi0xNC4xNDctMi4zOTQ3LTUuNzMxNS0uMzA0OTgtMTEuMzE1IDEuMTU4Ni0xNi44NTQgMi4zOTQ1LS4wNjEzMS0xLjM4LjQ2NDE0LTIuNTg2NSAxLjI3MjUtMy42NzE2LTMuMTI2My0yLjUwNTYtNS43MDg5LTYuMDQ2Ny01LjgzLTEwLjE5eiIvPjxwYXRoIGQ9Im0xNS45ODkgNDUuMjAxYy0uMjE3MzktMS41Nzc3IDEuMjU2NS0yLjIxOTggMi41NzI5LTEuNjk1NyAzLjg2MDYuOTY0MDYgNS42MTMgNC45NzQzIDcuMDg4OCA4LjI2OTEtMS41NDIyLjI1NTM2LTMuMDg0Ni41MDEwNy00LjYyNjkuNzI3MDQtMS43OTItMi4zMzYxLTQuMDg3Ny00LjQ0MjYtNS4wMzQ5LTcuMzAwNHoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wOTE1NjMiLz48L2c+PHBhdGggZD0ibTE1Ljk4OSA0NS4yMDFjLS4yMTczOS0xLjU3NzcgMS4yNTY1LTIuMjE5OCAyLjU3MjktMS42OTU3IDMuODYwNi45NjQwNiA1LjYxMyA0Ljk3NDMgNy4wODg4IDguMjY5MS0xLjU0MjIuMjU1MzYtMy4wODQ2LjUwMTA3LTQuNjI2OS43MjcwNC0xLjc5Mi0yLjMzNjEtNC4wODc3LTQuNDQyNi01LjAzNDktNy4zMDA0eiIvPjxwYXRoIGQ9Im0zOC4zODkgNTEuNzU3YzEuNTExOC0zLjQ4NjMgMy40NTQ1LTguMDE3MiA3LjgxMS04LjM5OTIgMS41NTc4LS40NzA3MSAyLjI0MjIgMS40MTc2IDEuNjE1IDIuNTQ3My0xLjE0MDggMi41MS0zLjEzNzUgNC40ODQxLTQuODQxNiA2LjYwODUtMS41MzMzLS4yNDAwMS0zLjA1ODUtLjUwMzc0LTQuNTg0NS0uNzU2NTR6IiBmaWxsPSIjZmZmIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDkxNTYzIi8+PHBhdGggZD0ibTM4LjM4OSA1MS43NTdjMS41MTE4LTMuNDg2MyAzLjQ1NDUtOC4wMTcyIDcuODExLTguMzk5MiAxLjU1NzgtLjQ3MDcxIDIuMjQyMiAxLjQxNzYgMS42MTUgMi41NDczLTEuMTQwOCAyLjUxLTMuMTM3NSA0LjQ4NDEtNC44NDE2IDYuNjA4NS0xLjUzMzMtLjI0MDAxLTMuMDU4NS0uNTAzNzQtNC41ODQ1LS43NTY1NHoiLz48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJtMjkuMTY2IDU4LjQzYzEuNjY0OS0xLjA5NTYgMy45NzA0LTEuMDgxMyA1LjY2NzEtLjA1MjE3IDEuNTE2NiAzLjQyMDItNi45ODg1IDMuNDgzMi01LjY2NzEuMDUyMTd6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDkxNTYzIi8+PHBhdGggZD0ibTI5LjE2NiA1OC40M2MxLjY2NDktMS4wOTU2IDMuOTcwNC0xLjA4MTMgNS42NjcxLS4wNTIxNyAxLjUxNjYgMy40MjAyLTYuOTg4NSAzLjQ4MzItNS42NjcxLjA1MjE3eiIvPjxwYXRoIGQ9Im0xNi42ODggNjIuNjJjLjMxNjItMi40MDEzIDIuNzgwNy0yLjE5NzUgNC41NTY3LTEuOTcyLTEuMTE3MyAxLjQ0NTgtMi44MDQ0IDEuOTI5OS00LjU1NjcgMS45NzJ6IiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIuMDkxNTYzIi8+PHBhdGggZD0ibTE2LjY4OCA2Mi42MmMuMzE2Mi0yLjQwMTMgMi43ODA3LTIuMTk3NSA0LjU1NjctMS45NzItMS4xMTczIDEuNDQ1OC0yLjgwNDQgMS45Mjk5LTQuNTU2NyAxLjk3MnoiLz48cGF0aCBkPSJtNDIuOTEzIDYxLjU4MWMxLjI3MTItMS44MjQ1IDQuNDQ1My0xLjI5NzcgNC4yMzQ1IDEuMjMxLTEuNDMxMy0uMzUyMjgtMi44NDUtLjc1NDM0LTQuMjM0NS0xLjIzMXoiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9Ii4wOTE1NjMiLz48cGF0aCBkPSJtNDIuOTEzIDYxLjU4MWMxLjI3MTItMS44MjQ1IDQuNDQ1My0xLjI5NzcgNC4yMzQ1IDEuMjMxLTEuNDMxMy0uMzUyMjgtMi44NDUtLjc1NDM0LTQuMjM0NS0xLjIzMXoiLz48cGF0aCBkPSJtMTcuMzg0IDY2LjMwMmMzLjcxODQtMi4xNjQzIDguMjEyOC0xLjkxIDEyLjM2My0yLjIyMjEgNS43NzI2LS4wMDIgMTEuODY2LS4yMzUxOCAxNy4yMyAyLjI0MzQtLjQ1NzU1LjM5MTM3LTEuMzcyNiAxLjE3NDEtMS44MzAyIDEuNTY1NS03LjY2OTUtMS43Nzc4LTE1Ljc3NC0yLjA4NjYtMjMuNTA0LS41MjY1My0xLjU5NDIuMjMyNzgtNC4wMzMzIDEuNDQ0My00LjI1OTYtMS4wNjAzeiIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iLjA5MTU2MyIvPjxwYXRoIGQ9Im0xNy4zODQgNjYuMzAyYzMuNzE4NC0yLjE2NDMgOC4yMTI4LTEuOTEgMTIuMzYzLTIuMjIyMSA1Ljc3MjYtLjAwMiAxMS44NjYtLjIzNTE4IDE3LjIzIDIuMjQzNC0uNDU3NTUuMzkxMzctMS4zNzI2IDEuMTc0MS0xLjgzMDIgMS41NjU1LTcuNjY5NS0xLjc3NzgtMTUuNzc0LTIuMDg2Ni0yMy41MDQtLjUyNjUzLTEuNTk0Mi4yMzI3OC00LjAzMzMgMS40NDQzLTQuMjU5Ni0xLjA2MDN6Ii8+PC9nPjwvZz48ZyBmaWxsPSIjMzMzIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iLjk4NzgwMTk3Ij48cGF0aCBkPSJtMjQuMzE3ODQgNTcuNjU5MzE3Yy0zLjk0MjQ3OC0uNTU1MjA5LTYuOTI5NjI2LTEuNzA0MTc3LTguMzY3MDM4LTMuMjE4MjctLjg4NDQyMy0uOTMxNjA3LTEuMDQxNzkxLTIuMDIzNzctMS4zOTk1NzUtOS43MTMyNzVsLS4xOTEzNjgtNC4xMTI5MDMtMS40ODcwNTktMS4yODM4MzRjLTQuNDQzODM4OS0zLjgzNjUzMi03LjY0MzY1MDItMTAuMDI1ODgyLTcuNjYxMzExNi0xNC44MTkxNjctLjAxMTYxMDctMy4xNTExNDkgMi4xOTYyMzM0LTYuMjc3ODAxIDUuNTM0OTkxNi03LjgzODQxMyAxLjY5NDE0My0uNzkxODgxIDIuMTIwMzU3LS44NzcwNjcgNC4zMzg5ODMtLjg2NzIyMyAyLjc0ODIzNS4wMTIxOSA0LjQ1MTMzNi41MDA0NTUgNy40MDA5ODcgMi4xMjE3ODcuOTQ3MTI4LjUyMDYwNiAxLjc3ODg2Ny45NDY1NTcgMS44NDgzMDkuOTQ2NTU3LjA2OTQ0IDAgLjEyNjI1OC0yLjYyMzcyOS4xMjYyNTgtNS44MzA1MDh2LTUuODMwNTA4N2g3LjU5MzIyIDcuNTkzMjIxdjUuODMwNTA4N2MwIDMuMjA2Nzc5LjA1NjgyIDUuODMwNTA4LjEyNjI1OSA1LjgzMDUwOC4wNjk0NCAwIC45MDExNzktLjQyNTk1MSAxLjg0ODMwOS0uOTQ2NTU3IDMuNDMwNjY4LTEuODg1NzMzIDYuMTI5MTAzLTIuNDk2NDc3IDkuMDAyMjE1LTIuMDM3NDk1IDIuMzAxMDc3LjM2NzU5OSAzLjcxOTIwNiAxLjA3MTY3MiA1LjM4NDEwMyAyLjY3MzEwNCAyLjMxNzAyMyAyLjIyODY5NiAzLjA5MzE1OCA0LjU4MzI0IDIuNjE3MTQyIDcuOTM5NTgyLS41OTI3NCA0LjE3OTM2OC0yLjc3MTQ1OCA4LjEwNTg2NC02LjYxNzQzMiAxMS45MjU5NzJsLTIuMjk2NzU0IDIuMjgxMzA3LS4zNzM1MDUgNi41OTI3MDgtLjM3MzUwMiA2LjU5MjcwNS0uNzk0MDEuNjQxOTgzYy0xLjI3NTc2OSAxLjAzMTQ5OC0zLjM0NTcwOCAxLjk4MDMzMy01LjY3NTM2OCAyLjYwMTUxOC0xLjkwMjkzNy41MDc0MDQtMy4wNTI0NTUuNTg5MDIzLTkuMzU1OTMyLjY2NDMwMS0zLjk1MjU0Mi4wNDcyLTcuOTIyMDU3LS4wMTc3Ni04LjgyMTE0My0uMTQ0Mzg3em0tMS4wNzcxNjItNi40MTI4NjVjMS45MjUyODYtLjM4NzgyNyAzLjc1Nzc5MS0uNDkzMzE2IDguNjc3OTY2LS40OTk1NTYgNS40MjkyMzEtLjAwNjkgNi43MDU0OTIuMDc2NjQgOS44NTEyODcuNjQ0NzU0bDMuNjEzOTk4LjY1MjY3Ljk0ODkyOC0uOTQ4OTI3Ljk0ODkyNy0uOTQ4OTMxLTIuMTM2NjM0LS43MDYxNjRjLTMuMDQ1OTE3LTEuMDA2Njg3LTUuMDEzMTM0LTEuMjg3NTk2LTEwLjI0MzQ1NS0xLjQ2MjcwNi03LjUxMTM5OC0uMjUxNDg1LTEzLjgxMTU4MS4zOTIxOTgtMTYuNzUwMzE0IDEuNzExMzYzLS44MzY2MTUuMzc1NTQ3LS45OTAxMjguNTYxMTQ5LS44NDgxNjYgMS4wMjU0NjkuNDQ2MTMxIDEuNDU5MTczIDEuMDYxMjExIDEuNTE0Mjg5IDUuOTM3NDYzLjUzMjAyOHptMjMuMzMwODMxLTYuMjYzNjA1Yy0uOTU5NzU4LS44MjU1NTEtMi4zMjg0NjEtLjgxMTQ1NC0zLjMxMTQ4NS4wMzQxMWwtLjc1NjY1OS42NTA4NTMgMi4wMjk2NzQuNTkzMTljMS4xMTYzMi4zMjYyNTcgMi4xNTE3MDcuNjI0Mzc0IDIuMzAwODU5LjY2MjQ4Ny4xNDkxNTMuMDM4MTEuMzEyNDU5LS4yNDQxNzQuMzYyOTA1LS42MjcyOTguMDY0NDctLjQ4OTctLjEyMTI0LS44Nzk3NjktLjYyNTI5NC0xLjMxMzMzN3ptLTI2Ljg5NTU4NCAxLjEwNTUwOGMxLjAwMjIwNC0uNTA3MzA4IDEuODAyMDQxLTEuMTcwMDIgMS44MDIwNDEtMS40OTMwOTggMC0uMzQ1MjQ1LTIuOTMyMzYyLS4yNzUxNDMtMy42MTEwNDguMDg2MzMtLjc3MjQ0NC40MTE0MDYtMS4yNTA5MzMgMS4wNTA1NDMtMS4yNjE2ODMgMS42ODUyOC0uMDA3NS40NDUxNjYuMTMxNDM3LjQ4NjgzOSAxLjEwNDU4OC4zMzEyMjQuNjEyMjY3LS4wOTc5IDEuNDk3MDEzLS4zNzIyODUgMS45NjYxMDItLjYwOTczM3ptMTQuMTU0MDE3LTEuMzAzNDI1Yy45NjI4MDQtLjQwMjI4NiAxLjQ5MTg1OS0xLjI1ODQ0NiAxLjI3OTQ4Mi0yLjA3MDU3My0uMjY0NDk3LTEuMDExNDM5LTMuMDk2OTExLTEuNTk0OTg5LTQuODAyMTA4LS45ODkzNTQtMS4zNjYzNzMuNDg1Mjk0LTEuNzE2NzA3IDEuMDE2Njc2LTEuMjg5MDY4IDEuOTU1MjQxLjYwODIxNSAxLjMzNDg4OCAyLjk2NTQ4OSAxLjg3NjA3OSA0LjgxMTY5NCAxLjEwNDY4NnptLTEzLjM2NjkzMS00LjE5MzYxMWM5LjEwMTczMS0yLjAwNjU5IDEzLjU0ODc2MS0yLjAzNTkzNSAyMi4zMzA5ODItLjE0NzM0OSAyLjQwMTc4Mi41MTY0OTQgNC41MTIzOTYuOTM5MDgxIDQuNjkwMjU2LjkzOTA4MS40MzI4NTIgMCAuMTIxNzQyLTEuNzY0MjU4LS41MDIxMi0yLjg0NzQ1OGwtLjQ2ODU2Ny0uODEzNTU5IDEuODI4MDI3LTEuOTM4NDM1YzIuMzczNDI0LTIuNTE2Nzc0IDMuNTUzOTY5LTQuOTE1NTMgMy43MTU5LTcuNTUwMzU2LjEwMjA5OS0xLjY2MTI4Ny4wMzYxMy0yLjAyMDc0My0uNTIzMDU5LTIuODUwMTkyLS45MTU0MDQtMS4zNTc4MTctMi40MTkxNTQtMi4wMjU3NjctNC41NzA2NDItMi4wMzAyMy00LjQ1NzUxLS4wMDkyLTkuMDAwMzU3IDQuMTA1OTg5LTExLjU5MjY2NyAxMC41MDE0NjVsLS43NDA2MTMgMS44MjcxNjgtMi41OTQ2NTcuMDAzMy0yLjU5NDY1OS4wMDMzLS44ODk3NjMtMi4xNTUwNjRjLTEuMTE4NTIxLTIuNzA5MTMyLTMuMTM3MTMyLTUuODAzODc4LTQuNzYzNTkzLTcuMzAzMDk3LTEuNDQwMTk2LTEuMzI3NTI4LTQuMDUyNzI5LTIuNjQ4MDE5LTUuNzM5Mzk5LTIuOTAwOTUxLTIuNjUxOTQ5LS4zOTc2ODQtNS41MDYyMjggMS4wNzQ4MDgtNi4wNTg0MTUgMy4xMjU0NzItLjY0Mzk4NCAyLjM5MTU3NCAxLjA3MDI4NiA2LjY3ODcyNCAzLjgwNjAwNyA5LjUxODI5NmwxLjY0MTk0NCAxLjcwNDI3Ni0uNTU2Mjc1IDEuMjkzMDkzYy0uNjAwNzU5IDEuMzk2NTAyLS43MjAwMDcgMi40MTI4OS0uMjgzMDk0IDIuNDEyODkuMTUwMjQ5IDAgMS44ODkyMzItLjM1NjI3OSAzLjg2NDQwNy0uNzkxNzMyem0xMi44MDQzLTEyLjc2NDgyOGMyLjcwNjA0LTEuMDI4ODM1IDIuNzY4ODQxLTQuNzUwOTIuMDk4MTktNS44MTk1MDMtMi4wNDQ0MjQtLjgxODAxNi00LjAwMzgzMy4wMzg1MS00LjU5Mzk2MiAyLjAwODE5MS0uNzQxNDYxIDIuNDc0Nzc0IDEuOTY4NTE5IDQuNzcyMTcyIDQuNDk1NzczIDMuODExMzEyem0tMy4xNjc5MjEtMTAuMDYyOTU3IDEuOTQ5NzM1LTEuNjUzNDE1IDEuOTE2MzEgMS42NTM0MTVjMS4wNTM5NjguOTA5Mzc4IDIuMDIxMTM2IDEuNjUzNDE1IDIuMTQ5MjU4IDEuNjUzNDE1LjI2OTE2OSAwIDEuOTA1NjQ2LTIuMDAyOTk3IDEuOTA1NjQ2LTIuMzMyNDQ5IDAtLjEyMTI3Ni0uNzQ5MzYxLS44OTkxMTYtMS42NjUyNDctMS43Mjg1MzZsLTEuNjY1MjUxLTEuNTA4MDM0IDEuNjc5MDM4LTEuNjIyODI5IDEuNjc5MDM3LTEuNjIyODI5LS44ODUzODMtMS4xNTE5ODM2Yy0uNDg2OTU5LS42MzM1OTA4LTEuMDExODA4LTEuMTQ5ODYyMS0xLjE2NjMzLTEuMTQ3MjY5NS0uMTU0NTIyLjAwMjU5LTEuMTE1MzA1LjczNzk0MTctMi4xMzUwNzUgMS42MzQxMDlsLTEuODU0MTIzIDEuNjI5Mzk1MS0xLjg0MzE4OC0xLjYzNDEwODljLTEuMDEzNzUzLS44OTg3NTk5LTEuOTU4OTczLTEuNjM0MTA5LTIuMTAwNDg4LTEuNjM0MTA5LS4yNzQ3NzcgMC0xLjk3NTE5MyAyLjAwNjcyNzktMS45NzUxOTMgMi4zMzEwMDM5IDAgLjEwNjMyNC43NDM0NzkuODY2MTI2IDEuNjUyMTc2IDEuNjg4NDVsMS42NTIxNzYgMS40OTUxMzMtMS43OTM1MzggMS42NDk0ODYtMS43OTM1MzcgMS42NDk0ODYuOTc3NDExIDEuMTUyNTQzYy41Mzc1NzcuNjMzODk4IDEuMDY1MDMxIDEuMTUyNTQyIDEuMTcyMTIxIDEuMTUyNTQyczEuMDcyMDktLjc0NDAzNyAyLjE0NDQ0NS0xLjY1MzQxNXoiLz48cGF0aCBkPSJtMTkuMTU5MDUyIDM0LjAwMzQxN2MtMS43NzI3MTEtMi4xOTU2MTgtMy4xMDQ4MTUtNC40Mjc1NzMtMy4xMDQ4MTUtNS4yMDIxNSAwLS42NTg4MDUuODAxNDM5LTEuMjQ4NzI1IDEuNjk2NDYyLTEuMjQ4NzI1IDIuMjIwMTAxIDAgNC43NjY3NjkgMi4yNjIwNTQgNi42NzQxMiA1LjkyODIyM2wxLjExOTU2IDIuMTUxOTM0LTEuNzE2NDM3LjI5ODkwNWMtMi43NjYxMS40ODE2OTctMi43MDE3MTEuNTA4MjkzLTQuNjY4ODktMS45MjgxODd6Ii8+PHBhdGggZD0ibTQwLjAwMzc2MiAzNS45MDkxNzktMS40MDY0MDctLjI1Njg5OC41MzkzOC0xLjI1ODMyMWMxLjM5NTcwNC0zLjI1NjA0NSAzLjM3MzIzLTUuNjY1MjQxIDUuMzE2NzA2LTYuNDc3Mjc3IDEuMjMxMDA3LS41MTQzNDcgMi43NzQ4NjEtLjU0OTQ1NSAzLjA3ODM0Ny0uMDcuNzYzMTM0IDEuMjA1NjExLS4wNTYyNCAzLjAyMjIxMi0yLjk0OTQ0OSA2LjUzOTA2NC0xLjY2ODc5NCAyLjAyODUxMy0xLjcyMDA3NSAyLjA0NTU3Ni00LjU3ODU3NyAxLjUyMzQzNXoiLz48L2c+PC9zdmc+'); } diff --git a/public/stylesheets/piece/fantasy.css b/public/stylesheets/piece/fantasy.css deleted file mode 100644 index 300b43bf9a..0000000000 --- a/public/stylesheets/piece/fantasy.css +++ /dev/null @@ -1,12 +0,0 @@ -body.base .is2d piece.pawn.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZDBiMDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNTg2LjUyNiIgeDI9IjExMjYuMDIyIiB4bGluazpocmVmPSIjYSIgeTE9IjMyOC4wNDMiIHkyPSI1MzQuMjAzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjI3NS4yNDQiIHgyPSI4NjIuNjUyIiB4bGluazpocmVmPSIjYSIgeTE9IjQ1OC42NTYiIHkyPSI1NjAuNzQ3Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMwMC4yNzMiIHgyPSI3NzQuMDQ2IiB4bGluazpocmVmPSIjYSIgeTE9IjYyMy43ODIiIHkyPSI3NjQuODk5Ii8+PGcgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxnIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggZD0iTTkyNi42NjcgMzczLjMzM2ExNjYuNjY3IDE1MCAwIDEgMS0zMzMuMzM0IDAgMTY2LjY2NyAxNTAgMCAxIDEgMzMzLjMzNCAweiIgZmlsbD0idXJsKCNiKSIgc3Ryb2tlLXdpZHRoPSIyMS43NjIiIHRyYW5zZm9ybT0ibWF0cml4KC43MzQ0NyAwIDAgLjczNiAtMTIwLjY2IDMwLjQzNikiLz48cGF0aCBkPSJNMzk3LjQxNyA0NjcuMDFjMS40NjkgMTcwLjE3NS04Ni43MzMgMjIxLjA5OC0xMjcuOTY3IDI1MC4yNDYtMzQuMTkyIDI0LjE3LTI1LjQ2MyA4Mi4zNDIgMTkuOTA2IDg1LjMxMSAyOC4xMTMgMS44NCAyNzYuNjEzIDIuMzYxIDMwNS42NTEtLjg0MyA1MS4zOC01LjY3IDUyLjg0Ni02Ni43IDE5LjY4OC04Ny4zMTEtNTIuNjA5LTMyLjcwMy0xMzYuMTkxLTY5LjUzOC0xMzguNDk4LTI0Ny4wOS0uNDQxLTMzLjMxMi03OS4wNDItMzAuMDA5LTc4Ljc4LS4zMTJ6IiBmaWxsPSJ1cmwoI2MpIiBzdHJva2Utd2lkdGg9IjE2Ii8+PHBhdGggZD0iTTM0MC4zNTMgNDMyLjczNWMtNzQuMTk1IDE5LjA2Ni0xMDAuMTEgNjYuMDE5LTEwMC4xMSA2Ni4wMTlINjQ5LjA5cy00My40MzItNTEuODM1LTExMC4wMjUtNjYuNjg0Yy04NS4yNC0xOS4wMDctMTI5LjE3My0xNy4yMDQtMTk4LjcxMi42NjV6IiBmaWxsPSJ1cmwoI2QpIiBzdHJva2Utd2lkdGg9IjE2Ii8+PC9nPjxwYXRoIGQ9Ik0zMzkuMTIxIDcxMy42NzVoMTg3LjkwMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxNiIvPjwvZz48L3N2Zz4='); } -body.base .is2d piece.knight.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSIwIDAgOTAwIDkwMCIgd2lkdGg9IjcwMHB0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48bGluZWFyR3JhZGllbnQgaWQ9ImEiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iI2ZmZiIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI2QwYjA5MCIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJmIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjcwNS4yOTEiIHgyPSI3ODcuMTI2IiB4bGluazpocmVmPSIjYSIgeTE9IjM4Mi4yODgiIHkyPSI0NjkuNjI0Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJlIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjY3MS4wMzMiIHgyPSI3NDMuMTU0IiB4bGluazpocmVmPSIjYSIgeTE9IjMwMy4zMjciIHkyPSIzNTIuNDIiLz48bGluZWFyR3JhZGllbnQgaWQ9ImQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNTk4LjY3OSIgeDI9IjcwNS41MzIiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjEzLjc2MSIgeTI9IjIzNi4yODgiLz48bGluZWFyR3JhZGllbnQgaWQ9ImMiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNDk3Ljc5MiIgeDI9IjYyOS44NTMiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTU1LjkwNiIgeTI9IjE1Ny40ODkiLz48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjY1LjY0NiIgeDI9Ijc1My4yMDgiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjU5Ljk0IiB5Mj0iODU4LjMyOCIvPjxnIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjE2Ij48cGF0aCBkPSJNNTI4LjU5IDQwMS44MDhjLjIxNCA3Ni40OTMtODguMjI3IDE0Mi42NTMtMTc1LjQ1NiAxMDkuMzM0LTEzLjM2LTUuMTAyLTEzNC41NjggMTA0LjgwMy0xNTMuOTk0IDg5Ljc2Ni0xNS4zMjUtMTEuODYzIDE2Ljk3OS02MC43NjkgMTQuNjMtNTQuNTIyLTExLjE4MSAyOS43NC02MC41NDcgNjIuODQ0LTEwMC4xOSAyMC4xMTItMTUuNTAzLTE2LjcxLTEwLjcwOS02NC43NzYgMjIuNjg0LTEwMy45MzMgMzQuNzc3LTQwLjc4IDcwLjA4OS0xMDMuNTc3IDgzLjc1Ny0xMzkuNzk2IDI3LjQ5Mi03Mi44NSAxNi43MDUtNzQuNDQgNjkuMzkxLTE0MC41MDYgOS44OTgtMTIuNDEtMTYuMDg4LTYwLjU5NS02LjY0My05Mi4wNDcgMzcuMzA3IDYuNjUzIDUxLjY5IDQ0LjE2MiA2OC44NDUgNTkuOTAzIDEwLTIzLjE1MSAzLjI4MS04NS4zNiAyMS4wNi04Mi40NjIgMTcuNzc3IDIuODk5IDM4LjIyNyA1Ni43OTIgNjcuNTU0IDgwLjQ2MkM3OTEuNDkxIDI1Ni4yMTUgNzg4LjYyIDgxOC4zMjMgNjkwLjQ1IDgyMC4xNDRjLTEyMS4xNzIgMi4yNDgtMjY2LjI0IDEuNzQtMzg4LjEwNS0uMjAyLTI5LjUyOC0uNDctNDMuMTk3LTM4LjY3Mi0zNy41MDMtNjEuNSAyNy4xNTUtMTA4Ljg3OSAxNDEuODMzLTE4NS4wODcgMTk4LjAwOC0yMjIuODU0IDU3LjY5Ny0zOC43OSA2OC4yNjEtNzYuOTEgNjUuNzQtMTMzLjc4eiIgZmlsbD0idXJsKCNiKSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PHBhdGggZD0iTTM0NS4wMDYgMjk0LjA5OWMtMjkuMDczLTUuMzY2LTU0LjU2NCAzLjA3OC03NS42MTcgMjQuMDNtMjguNzQ5IDcuNjc0YzEwLjQ0MyAxMC42NCAyMy43MzQgMTEuMDg0IDI1LjkyMy02Ljk5N00xNTAuNzcxIDUxOC4yOWMtMTMuODU1LTQuNzg2LTIzLjg3OCAxNy41MzctMTUuMDM4IDE4LjQ0N20xODEuMTQzLTYyLjQzM2w5LjQ4OCAxMS43OW0yMDIuMzg5LTExNi44NThsLjI5LTI0LjkxOE0zMjUuODc5IDE2Mi42NWwtMTAuMTEzIDUuMjhtNjMuNTA0LTU5LjA1NmMzMC4xNTIgNDIuMTIgNDEuMDQgNTAuNjQgNS4xODcgNDQuNTk3IiBmaWxsPSJub25lIi8+PGcgZmlsbC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJNNDU0LjQ0NCAxMzEuMTI2Yzg2LjU3MiAyNS4zODQgNzEuOTcgNy4wNjIgOTAuMjI5IDM2Ljc5NiAxMC4yMyAxNi42NTggMjQuNDAzLTUuNjc4IDU4LjE0Ni0zLjU2NSAxOC4yMjMgMS4xNDEtNTAtMjcuMjIxLTU4Ljg5OS0zOC41NjMtMTIuMzUzLTE1Ljc0NS0xMDIuMTc4IDEuNjA4LTg5LjQ3NiA1LjMzMnoiIGZpbGw9InVybCgjYykiLz48cGF0aCBkPSJNNTc5LjU1MSAxOTkuNzIzYzI3LjE5MiAyMC42NzIgNDcuMTEtLjMyNSA0Ni4wMzYgMzUuNTQ1LS43MzggMjQuNjMgMzIuNTA2IDguMTc0IDQ4LjY1IDE4LjQ0OCAxNC44NzMgOS40NjUgMjkuNzktMjguNzE1IDIwLjMzLTI4LjcxNS0xNC4yMzIgMC0zOC40IDYuNjc3LTM0LjAyNy05LjM5NSA5LjU5OC0zNS4yNzgtODguNzk5LTIxLjgyMS04MC45ODktMTUuODgzeiIgZmlsbD0idXJsKCNkKSIvPjxwYXRoIGQ9Ik02NTkuNTMyIDI3Ny43MTZjNS4yOTIgMS44NTEgMzQuMTIgMjEuMzcgMzIuNzg1IDMwLjY1LTYuODg0IDQ3Ljg3NCAyOC40MTYgNDQuNzcgNDMuNjA4IDQ5LjgzMSAyMS4yODggNy4wOTItLjk5Mi0xOC4zMjMtMTEuNzM0LTMxLjM5LTEwLjc0MS0xMy4wNjggNy4zNC0xOC45MTggNi4wNzQtMjcuMjA3LTQuNDUzLTI5LjE1Ni03My40OTctMjIuODUxLTcwLjczMy0yMS44ODR6IiBmaWxsPSJ1cmwoI2UpIi8+PHBhdGggZD0iTTcxMC4zOSAzNzguNjQ3YzUuMDU4IDguODIgMTYuOTE4IDE4LjgxIDIwLjY3NyAzMi42NDUgMy43NiAxMy44MzYgNS4xNzUgMjYuMTcxIDEyLjY5NCA0MS4wMzJzMzcuNzczIDEyLjkyMyA1MC44MTggOC41NjJjMTcuNTc4LTUuODc3LTQyLjQ5Ni0yNC4xMjctMjguOTYtNTEuOTUyIDguNTY3LTE3LjYxLTU3Ljk1OS0zNS4wNDctNTUuMjMtMzAuMjg3eiIgZmlsbD0idXJsKCNmKSIvPjwvZz48cGF0aCBkPSJNNDM4LjE0NyA3MjkuNTAxbC0yNS43OCA2MS40OTIiIGZpbGw9Im5vbmUiLz48L2c+PC9zdmc+'); } -body.base .is2d piece.bishop.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZDBiMDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTM2LjA5NyIgeDI9Ijc4NC43ODEiIHhsaW5rOmhyZWY9IiNhIiB5MT0iNjI5LjYyIiB5Mj0iODY1LjEwMyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzMjEuMTU4IiB4Mj0iMzk1LjQzMiIgeGxpbms6aHJlZj0iI2EiIHkxPSI5MC4xNjEiIHkyPSIxMjguNDYzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjQ2MC40NTQiIHgyPSI1MzQuNzI4IiB4bGluazpocmVmPSIjYSIgeTE9Ijg2LjI2OSIgeTI9IjEyNC41NyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIxOTIuMyIgeDI9IjgyNS43NzkiIHhsaW5rOmhyZWY9IiNhIiB5MT0iNDQ2LjAxMyIgeTI9IjcxNy4zMzYiLz48bGluZWFyR3JhZGllbnQgaWQ9ImYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNzIxLjYyMiIgeDI9IjU0MS4yNjYiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjIwLjA0MiIgeTI9IjU5OS4zOCIvPjxnIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjE2Ij48ZyBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Im00MzUuOTA2IDIxNi44N2MxMC44Mi0xOC4yNTggMzkuMTU4LTUwLjQ5IDY4LjM3OC02Ny4yNTMgMzYuMjMzIDM0LjA1NiA4NS42NCAxMTMuMzcgMTEwLjA4IDE4OS41ODYgMTkuMDQ4IDU5LjQwMSAyMi45OTggODYuMDkyIDIzLjk5IDE0OS41NDlzLTMyLjM4MSAxMjUuOTY2LTUyLjg2NSAxNDkuMDkiIGZpbGw9InVybCgjZikiLz48cGF0aCBkPSJtNTY1LjQ3IDY4Ny4wNThjNi4wMzgtNTMuNDY5LTI5NC4xMjItNDkuNTIyLTI4MS44NDggMy4wMDYgOS45MTcgMjEuODg4IDIuMDk2IDUwLjAzNSAyLjA5NiA1MC4wMzVzNjkuMjc3LTkuODMgMTQ2LjM4My04LjYwNWM3Ny4xMDUgMS4yMjUgMTI5LjI5IDcuMzM5IDEyOS4yOSA3LjMzOXMtMS45Ni0zNi4wMTggNC4wNzgtNTEuNzc1eiIgZmlsbD0idXJsKCNlKSIvPjxwYXRoIGQ9Im0yNzkuNDM0IDY4Mi4yODRjLTIyLjc5LTguMDg1LTM5LjM4Mi00MC40MzYtNTMuNzYtNjEuMDctMjIuOTUtMzIuOTM1LTM2LjQ4LTEwMS40MjktMjMuMDQtMTc4LjIzNCAxMy40NDEtNzYuODA2IDg2LjQ4OC0yMjUuMjIgMTYxLjI4Ny0yOTEuMDUzIDkxLjE2MiA2NS44MzMgMTQ5Ljk1MiAxNjUuMzYyIDE5Ni4zNDkgMjk3Ljk4MyAyNC44MjkgNzAuOTcxIDM3LjE1MyAxNDguNjM5IDE0LjM2MiAyMzAuMDY0LTUzLjE3Ny0xMC45NzItMjMzLjI1LTIxLjM4LTI5NS4xOTggMi4zMXoiIGZpbGw9InVybCgjZSkiLz48cGF0aCBkPSJtMzUwLjQzIDEzOC43MTljMTIuNDc5LTIxLjE5Ni0xOS43MzItMzQuNzE5LTIuODgzLTQ5LjUyMiA5LjQ2Mi04LjMxMyAyNS42NDktOS4xNDUgMzQuNzM3IDEuNjM4IDEzLjEwNCAxNS41NDgtMjIuNzQ1IDI5LjAzNS01LjEwNyA0Ny42NzciIGZpbGw9InVybCgjYykiLz48L2c+PHBhdGggZD0ibTQzNi4zOCA3MTIuMzQ5Yy05LjUzMy0yLjU3NC0xOC4xMDIgMS45NTYtMjEuNTk4LS45NC00LjI4OS0zLjU1NC00LjAzOC0xOC4zNC0xLjE5OC0yMi4wOTQgMi40MjgtMy4yMSAzMy42MzEtMy42MSAzNi42OTMtLjY1MyAyLjg1NSAyLjc1MS0uMDgyIDIwLjY2NS0yLjcyNyAyNS4xOTciIGZpbGw9Im5vbmUiLz48ZyBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Im0zODEuMzEzIDM0OC41NjNjLTExLjQyOCAxLjgxMi0xNy4xMTYgMTQuMzQyLTE1LjY4NSAyNC45NjgtLjE5NyA5LjA4NCAzLjc4MiAyMC43ODgtMy42OSAyNy45MDctMTAuMTEgMy4zNjMtMjEuMDQ4LS44NS0zMS4zNDktMS43My04LjQ4LS43NzQtMTguNzA2LTMuOTgtMjYuMjQ1IDEuNDgtNS43NyA2LjgzNS45NyAxNy4xNjUgOC40MDYgMTkuNDY4IDE0Ljk1MyA2LjUwNSAzMi43MDYgMy4xMTIgNDcuMDk0IDEwLjgxMyA0Ljk2NyA0LjU4MiAzLjk1IDEyLjU2MiA1LjQ2OSAxOC42NTYgNC42NzcgMzYuMzAyIDQuNDMgNzMuNjE4IDE1LjQwNiAxMDguNzgxIDIuODczIDcuNzIgNy4zNiAxOC40MzIgMTYuOTY5IDE4LjUgNy40MTctMi41MzggNi40OC0xMi4zOSA2Ljg3NS0xOC43NS0uODk5LTM5Ljg3Mi0xMS45NjQtNzguNzM2LTEzLjcyLTExOC41MzEtLjE5Ny0zLjkxOC4xNTQtOC44MzQgNS4yMi05LjI1IDE3Ljk2Mi01LjE3IDM4Ljk0OS41OCA1NS4yOC0xMC4zNDQgNi43MDgtMy42MzQgMTIuMzA2LTE3LjE5NSAxLjQzOC0xOC45NjktMTkuMTU3LTIuODE5LTM4LjUyIDUuNDM4LTU3LjU2MiAxLjg0NC01Ljg5NS0yLjA4Ny01LjM3OS0xMC4yNDctNi4wNjMtMTUuMzc1LTEuMTE2LTEyLjA4IDIuNTU1LTI0LjkzOS0yLjAzMS0zNi40NjktMS4xNS0yLjAxLTMuNDYxLTMuMjktNS44MTMtM3oiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJtMzE3Ljg2NyA4MDMuMjg5YzU1LjgyNC0uNjI1IDgyLjY5OC0zMi4zODIgMTA3LjQwOC0zMi40MTkgMjQuNzA5LS4wMzggNDcuMjUzIDMxLjY0MyAxMDcuMzUyIDMxLjc0OSAzMi4yNDUuMDU3IDIwMS45OTggMy40NDUgMTkyLjU2NC0yMi4yODVzLTExNi42NCA4LjgyMy0xNTIuNTM2LTkuNDc3Yy0xOC43OS05LjU3OS0yNC4zMDItMTEuODQ5LTQ4LjYwOC0xNS41MzEtNjUuNTY5LTkuOTM0LTEzMi42MS05LjUzOC0xOTEuOS0uMzc2LTI2LjM5NCA0LjA4LTM3LjEzIDguNjIxLTUxLjk5NyAxOC42MjctMjUuMDA2IDE2LjgzMi0xMzAuMzQzLTE4LjE2NS0xMzguNjM0IDYuNDIyLTguMjkxIDI0LjU4NiAxMDguNTE5IDI0LjA1IDE3Ni4zNTEgMjMuMjl6IiBmaWxsPSJ1cmwoI2IpIi8+PHBhdGggZD0ibTYzNS42ODggOTEuMTU2Yy0yMC41ODYuMTk4LTM1Ljk0MyAxNy4wOTMtNDQuNDgxIDM0LjI2NS01LjY0OSAxMC45MDYtMTUuNjEgMTguODQ1LTIxLjE0NSAyOS43MzUtMS4xNjQgNi41NiA4LjE5IDguNjk3IDEzLjEyNSA3LjI4MSAxMi4wNDktMi41NDkgMjEuNTkyLTEyLjA3NCAyNS42NjEtMjMuNTIyIDQuODI4LTExLjc4NyAxNS43My0yMS4wNiAyOC42NTItMjEuOTE1IDEyLjY5LTIuMjMxIDI0LjQxMyA3Ljc0NCAyNi45NjkgMTkuODc1IDMuNjk0IDEyLjcxNiAyLjAyMiAyNy43MDYtOC4yMTkgMzYuOTM4LTE1Ljk4NSAxNi43NjctNDAuMjMyIDI0LjI3LTUzLjY4OCA0My43MTgtNzMuODQ2IDE0NS43MjktMTQ3LjU4IDI5MS41NTItMjIwLjQzNSA0MzcuNzgyLTI1Ljg2MyA1My4wMzgtNTMuMTkyIDEwNS40NzgtNzUuODQ2IDE1OS45NjgtMS43NjIgNi44LTcuMDUyIDE0LjMzOC00LjIxOSAyMS40MDcgNC40NyAzLjQ3MiAxMC4xLTEuODk4IDEzLjk3LTQuMjUgMTUuOTI2LTE0LjUzOSAyNC43NTYtMzUuMDc3IDM1LjMxMi01My41OTQgNDQuNDc1LTg2LjI5IDg2LjE1Ny0xNzQuMDAzIDEyOS40NDYtMjYwLjkgNDcuMDAyLTk0Ljg5NiA5NC4wMDgtMTg5LjgyMyAxNDIuMDIyLTI4NC4xOTQgMTMuNTg0LTIwLjEwNCAzOS4zNjUtMjYuODQgNTQuNTk1LTQ1LjQxIDkuNjk5LTEwLjY0NSAxNS45MDQtMjQuNzM4IDE0LjM0My0zOS4zNC0xLTI0LjI5OC0xNS4wNy01MC41OTQtNDAuMjE5LTU2LjM3NS01LjE2LTEuMzA4LTEwLjUtMS43MDctMTUuODQzLTEuNDY5eiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Im00ODkuNzI2IDEzNC44MjZjMTIuNDgtMjEuMTk2LTE5LjczMS0zNC43MTgtMi44ODItNDkuNTIyIDkuNDYxLTguMzEzIDI1LjY0OC05LjE0NCAzNC43MzcgMS42MzkgMTMuMTAzIDE1LjU0Ny0yMi43NDUgMjkuMDM1LTUuMTA3IDQ3LjY3NyIgZmlsbD0idXJsKCNkKSIvPjwvZz48L2c+PC9zdmc+'); } -body.base .is2d piece.rook.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZDBiMDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoMS4wNDUyMSAwIDAgMS4wMTQ1IC0zMy44MjkgLTExLjgzNSkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNy4zMzgiIHgyPSI2ODkuNzQ1IiB4bGluazpocmVmPSIjYSIgeTE9IjIwNy42NjUiIHkyPSIyNzQuMzMxIi8+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDEuMDQ1MjEgMCAwIDEuMDE0NSAtMzMuODI5IC0xMS44MzUpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxOC41MDIiIHgyPSI5MDYuMDk1IiB4bGluazpocmVmPSIjYSIgeTE9IjUyMS41MyIgeTI9IjY0My4xOTciLz48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoMS4wNDUyMSAwIDAgMS4wMTQ1IC0zMy44MjkgLTExLjgzNSkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTUzLjQxNCIgeDI9Ijk2Ni41ODYiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjI5LjA2OCIgeTI9IjQwMC43MzQiLz48bGluZWFyR3JhZGllbnQgaWQ9ImMiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoMS4wNDUyMSAwIDAgMS4wMTQ1IC0zMy44MjkgLTExLjgzNSkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTkzLjE1IiB4Mj0iODc4LjU5NSIgeGxpbms6aHJlZj0iI2EiIHkxPSI3MTUuNDA2IiB5Mj0iNzgyLjA3MiIvPjxnIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxNiI+PGcgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIj48cGF0aCBkPSJNMjAwLjMwMyAzMjMuMzU1czMuMjUtMTE3LjIzMyAxNy42NTUtMTU2LjIwNmMzMC4wOTgtNi40OTggODkuMzUtOS41NjMgMTI2LjE1Ni00LjE5MS40MTIgMjMuODQyLTUuNDMzIDczLjk5LTEuNTkxIDk2LjkxNSAzMy40NDUtMS41ODUgMTAxLjIgMi40NzcgMTQ0LjMxNi0yLjM3MS45Ni0yNy45Ny03LjI3LTY3LjU3Ljg5My05OC43NSAyNy4zNjgtMi4wNTYgODkuMjM4LTQuMjMxIDExOC4wNDcgOC4xNDgtMy44NCAzOS44OS41NjMgOTQuNzMuNTYzIDk0LjczbDc1LjUzMiAyLjYxNC0xMS4yNDcgNjBjLTk0LjMwNCAzNS4zNDgtNDExLjMzIDMwLjEtNDcwLjMyNC0uODl6IiBmaWxsPSJ1cmwoI2IpIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBkPSJNMjUwLjcxNyA3MDIuNDc2Yy0yMy45ODggMjMuOTUzLTc0LjExNCA0OC4wNTYtMTA5Ljg1NyA1NS42MjItNS4xODQgMTcuMTEyLTEwLjI4NCAzNi44OTguMjQgNTguMTc0IDEyNy4zOTcgMS4xNTUgNDYzLjc5LS4zMjQgNTg1LjUxNi0uNzQ3IDYuNTY4LTIzLjczMSAxMS41MzUtNDAuODk4IDQuOTY3LTU5LjU1LTM3LjQ3OS03LjQyLTgyLjc0My0xOC42MjQtMTE2LjI1LTUzLjQ5NiIgZmlsbD0idXJsKCNjKSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PHBhdGggZD0iTTE5OC4wNDEgNzY4LjYyM2MxNDkuNDU4LjA3MiAzMTEuNjY0LTUuNTEzIDQ3MS41MTIuNTgiIGZpbGw9Im5vbmUiLz48L2c+PHBhdGggZD0iTTI1Mi43NDMgMzEwLjg3Yy0zLjc2OCA0NC44NTEtNC44NTQgMzU3LjI4OC0zLjgxNyAzOTQuNTA0IDU1LjE3Ny00LjY2NiAzMTEuNjEyLTQuOTYgMzY4LjE2Mi0uNTY3LTMuMjAyLTcwLjAzLTIuMzE2LTM5Mi45NTItMi4zMTYtMzkyLjk1MiIgZmlsbD0idXJsKCNkKSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PGcgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIj48cGF0aCBkPSJNMjkxLjM4IDYzNC44MzNjMzkuODg5LTIuOTQgMTIzLjQ3LTYuMjUyIDIxNS40MzktMy4yOTVtLTIxNi43OTYtNjEuMzljNTAuNzUyLTQuODg2IDk5Ljg0OC02LjQ5NSAxNzEuMy01Ljc1Mk0yOTAuNTU4IDUwNC45NWM3Mi4yNjgtNC45OTcgNzQuMzA0LTQuNDY2IDE1Mi41MTYtNS41OTRtLTE1Mi41MTYtNTguMzQ0YzM2LjY4NS0zLjAzMyA1OC4yNTgtNC42MSAxMDIuMTYtMy41NW0tNTcuOTU4IDIwLjI0MmMuODggMjkuOTMyLS4xNzUtMS4zMzYuNzA0IDI0LjU1bTU0Ljk3NyAzOC45OTZjLjg4IDI5LjkzMi0uMTc1LTEuMzM2LjcwNCAyNC41NW0tNTYuMzg1IDM5LjcyOWMuODggMjkuOTMxLS4xNzUtMS4zMzcuNzA0IDI0LjU1bTExNi4wOS0yNi41NzljLjg3OSAyOS45MzEtLjE3Ni42OTIuNzAzIDI2LjU3OW0tNjEuODE2IDQyLjE1NGMuODggMjkuOTMyLS4xNzUuNjkzLjcwNCAyNi41OG0tOTkuMzI2LTI5NS42MDljMjcuODU3LTMuMDMzIDQyLjA1Mi00LjAwNyA2NS43NzYtMy41NSIgZmlsbD0ibm9uZSIvPjxwYXRoIGQ9Ik0xMzEuNzQ4IDE2MS4yNzhjNS4xNTYgMjguMjIzIDkuMDUyIDU0Ljk5OSAxNC4wNDggOTUuNTQgMzIuMDc3IDIyLjM2NiA1MC4wMzMgMzAuMTc3IDUzLjQ2OCA2Ny42NTcgOTYuMzUyLTE3LjM2MSAzODYuOTY4LTEzLjM2IDQ3NC4zNTMtLjM1MiA2LjA5LTMzLjc4MiAxNi4wNTMtMzkuNTU1IDYzLjEzLTY3LjkxIDUuOTQ3LTQ0LjM2MSAxMS4xNjktNjUuNzUgMTEuNTA1LTkyLjI3My0xNC4xMDctMy40My0xMTUuNDY4LTMzLjc4NC0xMjcuOTg5LTI5LjQyNC00LjQ1MyAyNi4zOTMgMS44NDQgNDkuMDY3LTQuMDE1IDczLjg4OC0zNy45NDMgMS45MDItNzEuNzQ1LjQ1OC0xMTEuMDEzLTkuNzYzLjE5NS0zMy4xNzguMTQ2LTUxLjM3MyAxLjc3Ni03Ny4wNTItMTYuNTgzLTUuOTA2LTExNS4yMDgtNi45NTYtMTMzLjgxNi0uODY1LTMuMjA3IDMxLjk3OC44NDcgNDkuMzk5LTEuNzIzIDc3LjgzLTMzLjY4MyA5LjUyOS02NS42MjcgNy4wNTctMTA1LjgzOCA5LjMxNi0zLjI0LTMzLjgwNSAyLjc0My00NS42NjcgMS45ODItNjkuMzk2LTE2LjU5LTQuNTM2LTEyMC4yMDQgMTcuOTg3LTEzNS44NjggMjIuODA0eiIgZmlsbD0idXJsKCNlKSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PHBhdGggZD0iTTE4OC43NCAyNjIuMjQ3YzE0OC42NTQtMTQuNjk1IDM2OC41MTMtMTUuNjEgNDk2LjA5NiAzLjU0NCIgZmlsbD0ibm9uZSIvPjwvZz48L2c+PC9zdmc+'); } -body.base .is2d piece.queen.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZDBiMDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImciIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNzg1LjE0MSIgeDI9Ijg0MC45MTEiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjk0Ljc1OSIgeTI9IjM2My4wODkiLz48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNjQ5Ljg2MyIgeDI9IjcxMS4xMTciIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTcxLjE4IiB5Mj0iMjI3Ljc0OSIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0MDYuMDEyIiB4Mj0iNDcwLjgzNSIgeGxpbms6aHJlZj0iI2EiIHkxPSIxMDMuNTMyIiB5Mj0iMTMyLjk5NCIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIxNjcuODcyIiB4Mj0iMjM0LjYyIiB4bGluazpocmVmPSIjYSIgeTE9IjE3NC45OTciIHkyPSIxNzQuOTk3Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJrIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIzLjQ1OCIgeDI9Ijg3LjM3MSIgeGxpbms6aHJlZj0iI2EiIHkxPSIzMzcuODU1IiB5Mj0iMzE1LjQ2MyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzMzkuNDcxIiB4Mj0iNTE0LjU0IiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1NzEuNTkzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMzOS40NzEiIHgyPSI0OTUuMDIyIiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1ODQuNzU4Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJmIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMzOS40NzEiIHgyPSI0ODcuMjE1IiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1ODQuNzU4Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJoIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMzOS40NzEiIHgyPSI0OTguOTI2IiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1ODQuNzU4Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJsIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMzOS40NzEiIHgyPSI1MTAuNjM3IiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1ODQuNzU4Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJiIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjE1My42MDQiIHgyPSI3NjEuMzY0IiB4bGluazpocmVmPSIjYSIgeTE9IjM4MC41NCIgeTI9IjY4Mi4yMDciLz48ZyBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxnIGZpbGw9InVybCgjYikiPjxwYXRoIGQ9Ik0yNDMuOTM1IDgyNC44OWwtNTAuMzc4LTE2Ni4yMTIgNDMzLjc2OCAxLjMxOC00OS41MTkgMTY5LjY4MXoiLz48ZyBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxNiI+PHBhdGggZD0iTTYxMi43MTMgNzE2LjI4Yy0xMjIuMi00My42NjktMjgzLjQwNi00My45MjMtNDAyLjM5NC0uMTA0IDEyLjU4NSAzMC41MyAxNS45MTkgOTIuOTk4IDE1LjkxOSA5Mi45OTggMTAwLjcxOS0yOC4xNzMgMjcxLjk1NC0yNy4zMTcgMzcxLjg4NSA0LjE4OCAwIDAgMi4zMS02Ni43MDcgMTQuNTktOTcuMDgyeiIvPjxwYXRoIGQ9Ik0xOTUuMTA0IDY5Ny45MTVjMTIxLjg1LTUyLjY4NiAzMTIuNTgtNTMuNTIgNDM1LjU3Ny40MUM2NDIuODA3IDU5My4yOSA2ODEuMDMgNDYzLjYzIDc1My4zNjQgMzcwLjYyN2MtNTQuODQ4IDIxLjQ2Mi0xMzQuNDggMTU4Ljg2My0xODAuNzc1IDE4NC43NTgtMzYuMzA0LTc2LjI2MyAzNS41NDQtMjc0LjIwNCA2My40NzgtMzE2LjEyOS00Ni44OTkgMjguMjE5LTE0Ni4xNDcgMjAzLjAxNi0xNzUuNDcgMjg0Ljc4NS00Mi4yNjUtOTQuNDQ1LTMyLjM3Mi0yNzEuMDgyLTMzLjM4My0zNDUuMTA4LTMxLjc5NiA2OS41NTMtNzMuNTE4IDIyOS4zNzMtNzcuNzg4IDM0Mi4zMTQtODEuMTkzLTYwLjg2NC0xMDkuODQ2LTIyNS4yNy0xMzEuNTAxLTI5MC40MDYtMTEuOTI0IDkzLjc5OCA4Ljg4NCAyNTcuMTczIDIyLjYyMyAzMjMuMjI3LTUyLjc5Mi0zNS41OTMtMTE0LjQ0LTExMy45Mi0xNjUuNjExLTE4MC4zMDUgNjUuMDYgMTU1LjU3NCA4OC42MDggMjAyLjY5MyAxMjAuMTY3IDMyNC4xNTN6bTIxMi42NTkgMS44NjdjLTE4Ljk5OC0uMDk4LTguNTg1IDE0LjYzNS0xMi4zMTggMjEuMTE1LTguNTM4IDQuOTQ5LTM2LjI0Ni0zLjgzMi0yNy4zMjcgMTQuMzQgNi4zMTkgMTIuODc0IDE1Ljc2NiA2LjgxMyAyNi4zNzcgMTAuOTYxIDUuMjc2IDcuMjY3LTMuNjQzIDI5LjM2NiAxNS4wMzcgMjguOTAzIDE1LjQyNy0uMzgzIDcuMDE4LTIyLjQzMSAxMC4zMTYtMjguMzcyIDkuMzI2LTYuMDk0IDIxLjU2MiAyLjE2NSAyNy43MzQtMTMuNDUyIDQuNjg2LTExLjg1Ni0xOC41MTItNy40NTgtMjcuNjczLTEyLjU2NC0zLjgzNy01LjczMSA3LjYyLTIwLjgyOC0xMi4xNDYtMjAuOTMxem0tMTYzLjE5IDEyNS40OTFjODguODIzIDEwLjU5OSAyMzIuNzIyIDE0LjM2IDMzMi45NTggNC40MDctNTYuNTY4LTI1LjI4MS0yNTkuODktMjUuMDY4LTMzMi45NTgtNC40MDd6Ii8+PC9nPjwvZz48ZyBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0iTTQ3NC42MiA4Mi41MThjLTguNTYuMTg4LTM0Ljk0MyA0LjYyLTUwLjc5OCAxMi41MjgtNC44MSAxMi4xMS0yLjMxMiA0Ny42MDYuMTMxIDc2LjY0IDE1LjE4NS0yNC4zNyA0OC43MzctNjYuMjU0IDUwLjY2Ny04OS4xNjh6IiBmaWxsPSJ1cmwoI2MpIiBzdHJva2Utd2lkdGg9IjE2Ii8+PHBhdGggZD0iTTQ0MC43NjMgNTMwLjYwNmE0NS45NjIgNDQuNzgzIDAgMSAxLTkxLjkyNCAwIDQ1Ljk2MiA0NC43ODMgMCAxIDEgOTEuOTI0IDB6IiBmaWxsPSJ1cmwoI2QpIiBzdHJva2Utd2lkdGg9IjE4LjczNyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoODcuMjM1IC0yNzEuNTA2KSBzY2FsZSguODUzOTMpIi8+PHBhdGggZD0iTTcxNC45MDIgMjA2LjAwNWMtNC43MTctNS42NTMtMS43MS0xNi00MC4wMDMtMzcuMDU1bC00OC44NTYgNjEuMDI5YzI3LjQxLTguNTUgNzAuNzY0LTIxLjQ2IDg4Ljg2LTIzLjk3NHoiIGZpbGw9InVybCgjZSkiIHN0cm9rZS13aWR0aD0iMTYiLz48cGF0aCBkPSJNNDQwLjc2MyA1MzAuNjA2YTQ1Ljk2MiA0NC43ODMgMCAxIDEtOTEuOTI0IDAgNDUuOTYyIDQ0Ljc4MyAwIDEgMSA5MS45MjQgMHoiIGZpbGw9InVybCgjZikiIHN0cm9rZS13aWR0aD0iMTguNzM3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyOTUuMjM1IC0yMTEuNTA2KSBzY2FsZSguODUzOTMpIi8+PHBhdGggZD0iTTg0NS41NiAzNTEuODkxYzIuNjc0LTEzLjgyNy0xMi4xNy0xOC4yNjgtMjYuNDExLTM3LjMyNC0xOS44MzYgOC4xMjItNDIuODE3IDE3LjgxLTU5LjAwNiA0MC41MjIgNDAuODY3LTguNDI4IDU5LjQ0NCA0LjA1OCA4NS40MTctMy4xOTh6IiBmaWxsPSJ1cmwoI2cpIiBzdHJva2Utd2lkdGg9IjE2Ii8+PHBhdGggZD0iTTQ0MC43NjMgNTMwLjYwNmE0NS45NjIgNDQuNzgzIDAgMSAxLTkxLjkyNCAwIDQ1Ljk2MiA0NC43ODMgMCAxIDEgOTEuOTI0IDB6IiBmaWxsPSJ1cmwoI2gpIiBzdHJva2Utd2lkdGg9IjE4LjczNyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDE3Ljg1IC04NS43NDkpIHNjYWxlKC44NTM5MykiLz48cGF0aCBkPSJNMjI2LjYyIDE1NC41MThjLTEwLjU2LTExLjgxMi0yMi44OTMtMTAuMTE3LTUwLjc0OC0xNC4yMDguOTcyIDMzLjcyNiAyMS4xMDQgNDMuMTM1IDMzLjA4MSA2OS4zNzUgMTUuMTg1LTI0LjM3IDEyLjczNy0yNS4yNTMgMTcuNjY3LTU1LjE2N3oiIGZpbGw9InVybCgjaSkiIHN0cm9rZS13aWR0aD0iMTYiLz48cGF0aCBkPSJNNDQwLjc2MyA1MzAuNjA2YTQ1Ljk2MiA0NC43ODMgMCAxIDEtOTEuOTI0IDAgNDUuOTYyIDQ0Ljc4MyAwIDEgMSA5MS45MjQgMHoiIGZpbGw9InVybCgjaikiIHN0cm9rZS13aWR0aD0iMTguNzM3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTIzLjc2NSAtMjE5LjUwNikgc2NhbGUoLjg1MzkzKSIvPjxwYXRoIGQ9Ik01MC4yNjMgMjg5Ljc4MmMtMTMuNDQ3IDIuOC0xNC41ODUgMzAuMzEyLTE4LjgwNSA0NC40MjYgMTUuMDU3IDE2LjU5NSAzMC4zNjcgMjYuMDUgNDMuNTIgNTEuNzIgMTQuMDY1LTI1LjAzMy04Ljc1OS03Ni45MzYtMjQuNzE1LTk2LjE0NnoiIGZpbGw9InVybCgjaykiIHN0cm9rZS13aWR0aD0iMTYiLz48cGF0aCBkPSJNNDQwLjc2MyA1MzAuNjA2YTQ1Ljk2MiA0NC43ODMgMCAxIDEtOTEuOTI0IDAgNDUuOTYyIDQ0Ljc4MyAwIDEgMSA5MS45MjQgMHoiIGZpbGw9InVybCgjbCkiIHN0cm9rZS13aWR0aD0iMTguNzM3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjQ5LjEwOCAtNjguOTIpIHNjYWxlKC44NTM5MykiLz48L2c+PC9nPjwvc3ZnPg=='); } -body.base .is2d piece.king.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZDBiMDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjk3LjU1NCIgeDI9IjM2OC41NjIiIHhsaW5rOmhyZWY9IiNhIiB5MT0iNDI3LjA1IiB5Mj0iNTIxLjIxNiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0OTUuMjk2IiB4Mj0iNTk1Ljk3MSIgeGxpbms6aHJlZj0iI2EiIHkxPSI0NDguNTQ3IiB5Mj0iNTI4LjU0NyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIyMjEuNTUxIiB4Mj0iNjMzLjQ5MSIgeGxpbms6aHJlZj0iI2EiIHkxPSI3NzQuOTM3IiB5Mj0iODU5LjM1MSIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzNDIuNTMiIHgyPSI2MDkuODQ4IiB4bGluazpocmVmPSIjYSIgeTE9IjE0NS42NzQiIHkyPSIyODAuNjc0Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJmIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjM3OS4xOTciIHgyPSI1NzkuODQ4IiB4bGluazpocmVmPSIjYSIgeTE9IjE2MC4yNTMiIHkyPSIyODYuOTE5Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJnIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjM2OC40NjkiIHgyPSI0OTQuNTUxIiB4bGluazpocmVmPSIjYSIgeTE9IjMxOS4yNzUiIHkyPSIzMTkuMjc1Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJoIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjEyOS45NjIiIHgyPSI4MTIuMzY5IiB4bGluazpocmVmPSIjYSIgeTE9IjQyOC42NTkiIHkyPSI4MzYuMzEzIi8+PGcgZmlsbC1ydWxlPSJldmVub2RkIj48ZyBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxNiI+PHBhdGggZD0ibTI4OC42MzUgNjEyLjQ4NWMyMy4xOTItMzMuNTEtNy4wNTEtMTI1LjgzOS4wMTgtMTY4LjA1MiAxMS40NzMtNjguNTA4IDEwMS40OS0xMTQuNDkgMTEzLjUwNS03NC43NzEgMTQuMjUzIDQ3LjExNi00My42MTIgNTEuNTYzLTU5LjcxMiA5MC44OTMtMTQuNzg4IDM2LjEyNi0xMS42MjQgOTYuNDgzIDE3LjE2NiAxMzIuODEiIGZpbGw9InVybCgjYikiLz48cGF0aCBkPSJtNTg2Ljg5IDYxNy4zMTZjLTIzLjE5Mi0zMy41MSA3LjA1Mi0xMjUuODM5LS4wMTgtMTY4LjA1Mi0xMS40NzMtNjguNTA4LTEwMS40OS0xMTQuNDktMTEzLjUwNS03NC43NzEtMTQuMjUzIDQ3LjExNiA0My42MTIgNTEuNTYzIDU5LjcxMiA5MC44OTMgMTQuNzg4IDM2LjEyNiAxMS42MjQgOTYuNDgzLTE3LjE2NiAxMzIuODEiIGZpbGw9InVybCgjYykiLz48ZyBmaWxsPSJ1cmwoI2UpIj48cGF0aCBkPSJtNDAxLjIxNyAyODguMTE1YzUuMjU3LTE1IDE4LjkwNC03MC45MjUgMTMuOTE2LTg3LjQtMjIuMzE0LTEuNzY2LTY4LjkzNSAxOC43MDItOTkuMTUyIDEyLjE0NS04LjUxLTE1LjM4Ni0xMy44MjQtNDguNDk0LTEuNi02Ni42NjggMjcuMzU2LTguMzI0IDg3LjczMSA2LjI2OSAxMDQuNDIgOC41MDUgNS45MTUtMTYuODUzLTE0LjQ5NS02Ny42MzgtMTAuNTQxLTg2LjAyNyAxOC43NS04Ljk2MyA2NS4zMTQtOC4wNzcgNzkuMTUzIDEuMDM0LS43MDUgMTkuMzE0LTI4Ljg5NSA2Ni4yMjUtMjkuNTc5IDgyLjI2NCAxOC43ODQtLjk2MyA3Ny4yOTQtMTYuODc1IDk3LjI2OC0xMi45ODkgOC42MTYgMTYuNzEgMTAuNDg2IDQ2LjU2NS0zLjQxNCA2NS42NDYtMjEuMjk1IDcuMDkzLTc3LjY3NS04LjkzLTEwMS4xNjctNC4yNy05LjkgMTkuOTY3IDUuNDkxIDcxLjUyMyA5LjI3OCA4Ni42MDUiIGZpbGw9InVybCgjZikiLz48cGF0aCBkPSJtNDA4LjQxIDM3MS44MzJjLTI0LjczNS0yMS40MTgtMzUuNjM0LTIxLjU5Ni0zMC44MzMtNzUuMjA2IDQuMS00NS43ODEgMTA2LjI1Ny00My40MiAxMDguNjM0LTEuOTkxIDIuOTgxIDUxLjk0Ny0xNC4yOSA1NS44MzctMjYuMyA4MC45OSIgZmlsbD0idXJsKCNnKSIvPjwvZz48L2c+PGcgZmlsbD0idXJsKCNoKSI+PHBhdGggZD0ibTI3MC45NjIgODMwLjMtNjMuOTc1LTE5Ni4yNDQgNDcxLjIzMy0yLjA2Ny03NC44OSAyMDQuMzI0eiIvPjxnIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjE2Ij48cGF0aCBkPSJtNjQzLjQ1NiA3MTcuMTFjLTkzLjY3Ni00OC4wMTUtMzA3LjEzOS01MC4yNy00MDcuNjA2IDEuODc1IDE0LjA3NCA0NC40NzMgMTkuNzA0IDkzLjk3MyAxOS43MDQgOTMuOTczIDkxLjY2Ni0yOC40NjQgMjc3Ljg3My0yOS42IDM2Ny44NzMgNC4xNDMgMCAwIDkuMjgtNjYuNjggMjAuMDMtOTkuOTkyeiIvPjxwYXRoIGQ9Im01NTMuNTMxIDU3NC4wMzFjLTI4Ljc2LTE1LjU0Ny04OS4xNy01My41NC0xMjEuOTY0LTU0Ljg5NS0yNS4wNjYtMS4wMzctNzYuODA2IDMyLjQ3OS0xMDMuNDEgNTMuMDgzLTExNS4yNzQtNTIuNDY3LTExMy44OTYtMTUyLjg5Mi0zMy4yNS0xNzEuMzEzIDEzLjEzNC0zIDUyLjIzLjQ2NCA3OC4wNjItLjcxOS04LjIyNi0yMi43MTUtMTcuMTkyLTM4LjgyMy04LjY4OC02OS4wNjItMTguMjI4LTExLjczMi00Mi40ODgtMjAuMTQ0LTcwLjEyNS0yMS43ODFhMzUxLjAyMyAzNTEuMDIzIDAgMCAwIC0yNS4wMzEtLjU5NGMtODEuMjAxIDEtMTY1LjQ1MSAzMC41MzYtMTc3LjQwNiAxMDUuMjUtMTcuNDQ5IDEwOS4wNDggNzkuMDkxIDE3My4zMTUgMTEzLjg0NCAyODguNjU2IDExMC4zMDctNjIuOTA4IDM2NC42NjQtNTguOTAyIDQ3MC4zNDMtNC41MzEgMjguMDQ4LTg5LjE2MiAxMzkuODUxLTE5My4zNiAxMTQuODQ0LTI4NC4yNS0yMy4xNTgtODQuMTctMTM1Ljc0Mi0xMDguODAxLTIxMC4wMzEtMTA0LjU5NC0zMC4xMDkgMS43MDYtNTkuMDEzIDExLjQ1My04MC43MTkgMjQuODQ0IDQuMjAyIDIzLjk3MS00LjMxNSA0My41Ny0xMS4zNzUgNjQuMjgxIDM0LjM0NS4wMTUgOTQuNjAyLTcuOTcyIDExOC4yNSA1LjQwNiA1Mi4yMyAyOS41NDcgNTYuMjEyIDEzNS44OTctNTMuMzQ0IDE3MC4yMnoiLz48cGF0aCBkPSJtMzI4LjQ4OCA1NzIuNTI4YzM3Ljk5NS0yNi42NzggNTUuOTk4LTc5LjY2MSA1NC40NzktMTIyLjQzNS0yLjE5MS02MS42NzYtMzUuMTgtNzIuNDI2LTE2LjM0LTEyNi40MTQgMTIuNzc0LTM2LjYwNyAxMTkuMTYzLTM4LjQ4OSAxMzEuMTc5IDEuMjMgMTQuMjUzIDQ3LjExNi0yMi4zNDMgNzYuNDUtMTYuNjM4IDEyNC4xNDUgNi42NTQgNTUuNjQgNy4wNjcgOTIuNTIzIDcyLjI5NCAxMjYuNTczIi8+PC9nPjwvZz48ZyBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PHBhdGggZD0ibTI3NS42OTEgODMyLjY3OGM4Ny44NjUgMTAuNDg0IDIyOC4yMTIgMTIuMjA1IDMyNy4zNjcgMi4zNi02OC41OTctMjcuOTgtMjU2LjU1NS0yNy42NzctMzI3LjM2Ny0yLjM2eiIgZmlsbD0idXJsKCNkKSIgc3Ryb2tlLXdpZHRoPSIxNiIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im00NTMuNjIyIDczNy4wMzVhMTYuOTA4IDE2LjEwMyAwIDEgMSAtMzMuODE3IDAgMTYuOTA4IDE2LjEwMyAwIDEgMSAgMzMuODE3IDB6IiBzdHJva2Utd2lkdGg9IjE2Ii8+PHBhdGggZD0ibTgxNSA5MTVhMTcuNSAxNi42NjcgMCAxIDEgLTM1IDAgMTcuNSAxNi42NjcgMCAxIDEgIDM1IDB6IiBzdHJva2Utd2lkdGg9IjE4LjA4NyIgdHJhbnNmb3JtPSJtYXRyaXgoMS4wNjI2MiAtLjE5MjQ0IC4xMjkxMyAuNzEzMDQgLTYyOC4wNzIgMjQ5LjU0OSkiLz48cGF0aCBkPSJtODE1IDkxNWExNy41IDE2LjY2NyAwIDEgMSAtMzUgMCAxNy41IDE2LjY2NyAwIDEgMSAgMzUgMHoiIHN0cm9rZS13aWR0aD0iMTguMzIiIHRyYW5zZm9ybT0ibWF0cml4KDEuMDM4OTggLjE2ODYxIC0uMTE2MDggLjcxNTI4IC0xODguNjUyIC00MC40NDUpIi8+PC9nPjwvZz48L2c+PC9zdmc+'); } -body.base .is2d piece.pawn.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTA1MDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNTg2LjUyNiIgeDI9IjExMjYuMDIyIiB4bGluazpocmVmPSIjYSIgeTE9IjMyOC4wNDMiIHkyPSI1MzQuMjAzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjI3NS4yNDQiIHgyPSI4NjIuNjUyIiB4bGluazpocmVmPSIjYSIgeTE9IjQ1OC42NTYiIHkyPSI1NjAuNzQ3Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMwMC4yNzMiIHgyPSI3NzQuMDQ2IiB4bGluazpocmVmPSIjYSIgeTE9IjYyMy43ODIiIHkyPSI3NjQuODk5Ii8+PGcgc3Ryb2tlPSJncmF5IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiPjxnIGZpbGwtcnVsZT0iZXZlbm9kZCI+PHBhdGggZD0iTTkyNi42NjcgMzczLjMzM2ExNjYuNjY3IDE1MCAwIDEgMS0zMzMuMzM0IDAgMTY2LjY2NyAxNTAgMCAxIDEgMzMzLjMzNCAweiIgZmlsbD0idXJsKCNiKSIgc3Ryb2tlLXdpZHRoPSIyMS43NjIiIHRyYW5zZm9ybT0ibWF0cml4KC43MzQ0NyAwIDAgLjczNiAtMTIwLjY2IDMwLjQzNikiLz48cGF0aCBkPSJNMzk3LjQxNyA0NjcuMDFjMS40NjkgMTcwLjE3NS04Ni43MzMgMjIxLjA5OC0xMjcuOTY3IDI1MC4yNDYtMzQuMTkyIDI0LjE3LTI1LjQ2MyA4Mi4zNDIgMTkuOTA2IDg1LjMxMSAyOC4xMTMgMS44NCAyNzYuNjEzIDIuMzYxIDMwNS42NTEtLjg0MyA1MS4zOC01LjY3IDUyLjg0Ni02Ni43IDE5LjY4OC04Ny4zMTEtNTIuNjA5LTMyLjcwMy0xMzYuMTkxLTY5LjUzOC0xMzguNDk4LTI0Ny4wOS0uNDQxLTMzLjMxMi03OS4wNDItMzAuMDA5LTc4Ljc4LS4zMTJ6IiBmaWxsPSJ1cmwoI2MpIiBzdHJva2Utd2lkdGg9IjE2Ii8+PHBhdGggZD0iTTM0MC4zNTMgNDMyLjczNWMtNzQuMTk1IDE5LjA2Ni0xMDAuMTEgNjYuMDE5LTEwMC4xMSA2Ni4wMTlINjQ5LjA5cy00My40MzItNTEuODM1LTExMC4wMjUtNjYuNjg0Yy04NS4yNC0xOS4wMDctMTI5LjE3My0xNy4yMDQtMTk4LjcxMi42NjV6IiBmaWxsPSJ1cmwoI2QpIiBzdHJva2Utd2lkdGg9IjE2Ii8+PC9nPjxwYXRoIGQ9Ik0zMzkuMTIxIDcxMy42NzVoMTg3LjkwMyIgZmlsbD0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxNiIvPjwvZz48L3N2Zz4='); } -body.base .is2d piece.knight.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSIwIDAgOTAwIDkwMCIgd2lkdGg9IjcwMHB0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj48bGluZWFyR3JhZGllbnQgaWQ9ImEiPjxzdG9wIG9mZnNldD0iMCIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzUwNTA3MCIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJmIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjcwNS4yOTEiIHgyPSI3ODcuMTI2IiB4bGluazpocmVmPSIjYSIgeTE9IjM4Mi4yODgiIHkyPSI0NjkuNjI0Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJlIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjY3MS4wMzMiIHgyPSI3NDMuMTU0IiB4bGluazpocmVmPSIjYSIgeTE9IjMwMy4zMjciIHkyPSIzNTIuNDIiLz48bGluZWFyR3JhZGllbnQgaWQ9ImQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNTk4LjY3OSIgeDI9IjcwNS41MzIiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjEzLjc2MSIgeTI9IjIzNi4yODgiLz48bGluZWFyR3JhZGllbnQgaWQ9ImMiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNDk3Ljc5MiIgeDI9IjYyOS44NTMiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTU1LjkwNiIgeTI9IjE1Ny40ODkiLz48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjY1LjY0NiIgeDI9Ijc1My4yMDgiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjU5Ljk0IiB5Mj0iODU4LjMyOCIvPjxnIHN0cm9rZT0iZ3JheSIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjE2Ij48cGF0aCBkPSJNNTI4LjU5IDQwMS44MDhjLjIxNCA3Ni40OTMtODguMjI3IDE0Mi42NTMtMTc1LjQ1NiAxMDkuMzM0LTEzLjM2LTUuMTAyLTEzNC41NjggMTA0LjgwMy0xNTMuOTk0IDg5Ljc2Ni0xNS4zMjUtMTEuODYzIDE2Ljk3OS02MC43NjkgMTQuNjMtNTQuNTIyLTExLjE4MSAyOS43NC02MC41NDcgNjIuODQ0LTEwMC4xOSAyMC4xMTItMTUuNTAzLTE2LjcxLTEwLjcwOS02NC43NzYgMjIuNjg0LTEwMy45MzMgMzQuNzc3LTQwLjc4IDcwLjA4OS0xMDMuNTc3IDgzLjc1Ny0xMzkuNzk2IDI3LjQ5Mi03Mi44NSAxNi43MDUtNzQuNDQgNjkuMzkxLTE0MC41MDYgOS44OTgtMTIuNDEtMTYuMDg4LTYwLjU5NS02LjY0My05Mi4wNDcgMzcuMzA3IDYuNjUzIDUxLjY5IDQ0LjE2MiA2OC44NDUgNTkuOTAzIDEwLTIzLjE1MSAzLjI4MS04NS4zNiAyMS4wNi04Mi40NjIgMTcuNzc3IDIuODk5IDM4LjIyNyA1Ni43OTIgNjcuNTU0IDgwLjQ2MkM3OTEuNDkxIDI1Ni4yMTUgNzg4LjYyIDgxOC4zMjMgNjkwLjQ1IDgyMC4xNDRjLTEyMS4xNzIgMi4yNDgtMjY2LjI0IDEuNzQtMzg4LjEwNS0uMjAyLTI5LjUyOC0uNDctNDMuMTk3LTM4LjY3Mi0zNy41MDMtNjEuNSAyNy4xNTUtMTA4Ljg3OSAxNDEuODMzLTE4NS4wODcgMTk4LjAwOC0yMjIuODU0IDU3LjY5Ny0zOC43OSA2OC4yNjEtNzYuOTEgNjUuNzQtMTMzLjc4eiIgZmlsbD0idXJsKCNiKSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PHBhdGggZD0iTTM0NS4wMDYgMjk0LjA5OWMtMjkuMDczLTUuMzY2LTU0LjU2NCAzLjA3OC03NS42MTcgMjQuMDNtMjguNzQ5IDcuNjc0YzEwLjQ0MyAxMC42NCAyMy43MzQgMTEuMDg0IDI1LjkyMy02Ljk5N00xNTAuNzcxIDUxOC4yOWMtMTMuODU1LTQuNzg2LTIzLjg3OCAxNy41MzctMTUuMDM4IDE4LjQ0N20xODEuMTQzLTYyLjQzM2w5LjQ4OCAxMS43OW0yMDIuMzg5LTExNi44NThsLjI5LTI0LjkxOE0zMjUuODc5IDE2Mi42NWwtMTAuMTEzIDUuMjhtNjMuNTA0LTU5LjA1NmMzMC4xNTIgNDIuMTIgNDEuMDQgNTAuNjQgNS4xODcgNDQuNTk3IiBmaWxsPSJub25lIi8+PGcgZmlsbC1ydWxlPSJldmVub2RkIj48cGF0aCBkPSJNNDU0LjQ0NCAxMzEuMTI2Yzg2LjU3MiAyNS4zODQgNzEuOTcgNy4wNjIgOTAuMjI5IDM2Ljc5NiAxMC4yMyAxNi42NTggMjQuNDAzLTUuNjc4IDU4LjE0Ni0zLjU2NSAxOC4yMjMgMS4xNDEtNTAtMjcuMjIxLTU4Ljg5OS0zOC41NjMtMTIuMzUzLTE1Ljc0NS0xMDIuMTc4IDEuNjA4LTg5LjQ3NiA1LjMzMnoiIGZpbGw9InVybCgjYykiLz48cGF0aCBkPSJNNTc5LjU1MSAxOTkuNzIzYzI3LjE5MiAyMC42NzIgNDcuMTEtLjMyNSA0Ni4wMzYgMzUuNTQ1LS43MzggMjQuNjMgMzIuNTA2IDguMTc0IDQ4LjY1IDE4LjQ0OCAxNC44NzMgOS40NjUgMjkuNzktMjguNzE1IDIwLjMzLTI4LjcxNS0xNC4yMzIgMC0zOC40IDYuNjc3LTM0LjAyNy05LjM5NSA5LjU5OC0zNS4yNzgtODguNzk5LTIxLjgyMS04MC45ODktMTUuODgzeiIgZmlsbD0idXJsKCNkKSIvPjxwYXRoIGQ9Ik02NTkuNTMyIDI3Ny43MTZjNS4yOTIgMS44NTEgMzQuMTIgMjEuMzcgMzIuNzg1IDMwLjY1LTYuODg0IDQ3Ljg3NCAyOC40MTYgNDQuNzcgNDMuNjA4IDQ5LjgzMSAyMS4yODggNy4wOTItLjk5Mi0xOC4zMjMtMTEuNzM0LTMxLjM5LTEwLjc0MS0xMy4wNjggNy4zNC0xOC45MTggNi4wNzQtMjcuMjA3LTQuNDUzLTI5LjE1Ni03My40OTctMjIuODUxLTcwLjczMy0yMS44ODR6IiBmaWxsPSJ1cmwoI2UpIi8+PHBhdGggZD0iTTcxMC4zOSAzNzguNjQ3YzUuMDU4IDguODIgMTYuOTE4IDE4LjgxIDIwLjY3NyAzMi42NDUgMy43NiAxMy44MzYgNS4xNzUgMjYuMTcxIDEyLjY5NCA0MS4wMzJzMzcuNzczIDEyLjkyMyA1MC44MTggOC41NjJjMTcuNTc4LTUuODc3LTQyLjQ5Ni0yNC4xMjctMjguOTYtNTEuOTUyIDguNTY3LTE3LjYxLTU3Ljk1OS0zNS4wNDctNTUuMjMtMzAuMjg3eiIgZmlsbD0idXJsKCNmKSIvPjwvZz48cGF0aCBkPSJNNDM4LjE0NyA3MjkuNTAxbC0yNS43OCA2MS40OTIiIGZpbGw9Im5vbmUiLz48L2c+PC9zdmc+'); } -body.base .is2d piece.bishop.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTA1MDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTM2LjA5NyIgeDI9Ijc4NC43ODEiIHhsaW5rOmhyZWY9IiNhIiB5MT0iNjI5LjYyIiB5Mj0iODY1LjEwMyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzMjEuMTU4IiB4Mj0iMzk1LjQzMiIgeGxpbms6aHJlZj0iI2EiIHkxPSI5MC4xNjEiIHkyPSIxMjguNDYzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjQ2MC40NTQiIHgyPSI1MzQuNzI4IiB4bGluazpocmVmPSIjYSIgeTE9Ijg2LjI2OSIgeTI9IjEyNC41NyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIxOTIuMyIgeDI9IjgyNS43NzkiIHhsaW5rOmhyZWY9IiNhIiB5MT0iNDQ2LjAxMyIgeTI9IjcxNy4zMzYiLz48bGluZWFyR3JhZGllbnQgaWQ9ImYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNzIxLjYyMiIgeDI9IjU0MS4yNjYiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjIwLjA0MiIgeTI9IjU5OS4zOCIvPjxnIHN0cm9rZT0iIzgwODA4MCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjE2Ij48ZyBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Im00MzUuOTA2IDIxNi44N2MxMC44Mi0xOC4yNTggMzkuMTU4LTUwLjQ5IDY4LjM3OC02Ny4yNTMgMzYuMjMzIDM0LjA1NiA4NS42NCAxMTMuMzcgMTEwLjA4IDE4OS41ODYgMTkuMDQ4IDU5LjQwMSAyMi45OTggODYuMDkyIDIzLjk5IDE0OS41NDlzLTMyLjM4MSAxMjUuOTY2LTUyLjg2NSAxNDkuMDkiIGZpbGw9InVybCgjZikiLz48cGF0aCBkPSJtNTY1LjQ3IDY4Ny4wNThjNi4wMzgtNTMuNDY5LTI5NC4xMjItNDkuNTIyLTI4MS44NDggMy4wMDYgOS45MTcgMjEuODg4IDIuMDk2IDUwLjAzNSAyLjA5NiA1MC4wMzVzNjkuMjc3LTkuODMgMTQ2LjM4My04LjYwNWM3Ny4xMDUgMS4yMjUgMTI5LjI5IDcuMzM5IDEyOS4yOSA3LjMzOXMtMS45Ni0zNi4wMTggNC4wNzgtNTEuNzc1eiIgZmlsbD0idXJsKCNlKSIvPjxwYXRoIGQ9Im0yNzkuNDM0IDY4Mi4yODRjLTIyLjc5LTguMDg1LTM5LjM4Mi00MC40MzYtNTMuNzYtNjEuMDctMjIuOTUtMzIuOTM1LTM2LjQ4LTEwMS40MjktMjMuMDQtMTc4LjIzNCAxMy40NDEtNzYuODA2IDg2LjQ4OC0yMjUuMjIgMTYxLjI4Ny0yOTEuMDUzIDkxLjE2MiA2NS44MzMgMTQ5Ljk1MiAxNjUuMzYyIDE5Ni4zNDkgMjk3Ljk4MyAyNC44MjkgNzAuOTcxIDM3LjE1MyAxNDguNjM5IDE0LjM2MiAyMzAuMDY0LTUzLjE3Ny0xMC45NzItMjMzLjI1LTIxLjM4LTI5NS4xOTggMi4zMXoiIGZpbGw9InVybCgjZSkiLz48cGF0aCBkPSJtMzUwLjQzIDEzOC43MTljMTIuNDc5LTIxLjE5Ni0xOS43MzItMzQuNzE5LTIuODgzLTQ5LjUyMiA5LjQ2Mi04LjMxMyAyNS42NDktOS4xNDUgMzQuNzM3IDEuNjM4IDEzLjEwNCAxNS41NDgtMjIuNzQ1IDI5LjAzNS01LjEwNyA0Ny42NzciIGZpbGw9InVybCgjYykiLz48L2c+PHBhdGggZD0ibTQzNi4zOCA3MTIuMzQ5Yy05LjUzMy0yLjU3NC0xOC4xMDIgMS45NTYtMjEuNTk4LS45NC00LjI4OS0zLjU1NC00LjAzOC0xOC4zNC0xLjE5OC0yMi4wOTQgMi40MjgtMy4yMSAzMy42MzEtMy42MSAzNi42OTMtLjY1MyAyLjg1NSAyLjc1MS0uMDgyIDIwLjY2NS0yLjcyNyAyNS4xOTciIGZpbGw9Im5vbmUiLz48ZyBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Im0zODEuMzEzIDM0OC41NjNjLTExLjQyOCAxLjgxMi0xNy4xMTYgMTQuMzQyLTE1LjY4NSAyNC45NjgtLjE5NyA5LjA4NCAzLjc4MiAyMC43ODgtMy42OSAyNy45MDctMTAuMTEgMy4zNjMtMjEuMDQ4LS44NS0zMS4zNDktMS43My04LjQ4LS43NzQtMTguNzA2LTMuOTgtMjYuMjQ1IDEuNDgtNS43NyA2LjgzNS45NyAxNy4xNjUgOC40MDYgMTkuNDY4IDE0Ljk1MyA2LjUwNSAzMi43MDYgMy4xMTIgNDcuMDk0IDEwLjgxMyA0Ljk2NyA0LjU4MiAzLjk1IDEyLjU2MiA1LjQ2OSAxOC42NTYgNC42NzcgMzYuMzAyIDQuNDMgNzMuNjE4IDE1LjQwNiAxMDguNzgxIDIuODczIDcuNzIgNy4zNiAxOC40MzIgMTYuOTY5IDE4LjUgNy40MTctMi41MzggNi40OC0xMi4zOSA2Ljg3NS0xOC43NS0uODk5LTM5Ljg3Mi0xMS45NjQtNzguNzM2LTEzLjcyLTExOC41MzEtLjE5Ny0zLjkxOC4xNTQtOC44MzQgNS4yMi05LjI1IDE3Ljk2Mi01LjE3IDM4Ljk0OS41OCA1NS4yOC0xMC4zNDQgNi43MDgtMy42MzQgMTIuMzA2LTE3LjE5NSAxLjQzOC0xOC45NjktMTkuMTU3LTIuODE5LTM4LjUyIDUuNDM4LTU3LjU2MiAxLjg0NC01Ljg5NS0yLjA4Ny01LjM3OS0xMC4yNDctNi4wNjMtMTUuMzc1LTEuMTE2LTEyLjA4IDIuNTU1LTI0LjkzOS0yLjAzMS0zNi40NjktMS4xNS0yLjAxLTMuNDYxLTMuMjktNS44MTMtM3oiLz48cGF0aCBkPSJtMzE3Ljg2NyA4MDMuMjg5YzU1LjgyNC0uNjI1IDgyLjY5OC0zMi4zODIgMTA3LjQwOC0zMi40MTkgMjQuNzA5LS4wMzggNDcuMjUzIDMxLjY0MyAxMDcuMzUyIDMxLjc0OSAzMi4yNDUuMDU3IDIwMS45OTggMy40NDUgMTkyLjU2NC0yMi4yODVzLTExNi42NCA4LjgyMy0xNTIuNTM2LTkuNDc3Yy0xOC43OS05LjU3OS0yNC4zMDItMTEuODQ5LTQ4LjYwOC0xNS41MzEtNjUuNTY5LTkuOTM0LTEzMi42MS05LjUzOC0xOTEuOS0uMzc2LTI2LjM5NCA0LjA4LTM3LjEzIDguNjIxLTUxLjk5NyAxOC42MjctMjUuMDA2IDE2LjgzMi0xMzAuMzQzLTE4LjE2NS0xMzguNjM0IDYuNDIyLTguMjkxIDI0LjU4NiAxMDguNTE5IDI0LjA1IDE3Ni4zNTEgMjMuMjl6IiBmaWxsPSJ1cmwoI2IpIi8+PHBhdGggZD0ibTYzNS42ODggOTEuMTU2Yy0yMC41ODYuMTk4LTM1Ljk0MyAxNy4wOTMtNDQuNDgxIDM0LjI2NS01LjY0OSAxMC45MDYtMTUuNjEgMTguODQ1LTIxLjE0NSAyOS43MzUtMS4xNjQgNi41NiA4LjE5IDguNjk3IDEzLjEyNSA3LjI4MSAxMi4wNDktMi41NDkgMjEuNTkyLTEyLjA3NCAyNS42NjEtMjMuNTIyIDQuODI4LTExLjc4NyAxNS43My0yMS4wNiAyOC42NTItMjEuOTE1IDEyLjY5LTIuMjMxIDI0LjQxMyA3Ljc0NCAyNi45NjkgMTkuODc1IDMuNjk0IDEyLjcxNiAyLjAyMiAyNy43MDYtOC4yMTkgMzYuOTM4LTE1Ljk4NSAxNi43NjctNDAuMjMyIDI0LjI3LTUzLjY4OCA0My43MTgtNzMuODQ2IDE0NS43MjktMTQ3LjU4IDI5MS41NTItMjIwLjQzNSA0MzcuNzgyLTI1Ljg2MyA1My4wMzgtNTMuMTkyIDEwNS40NzgtNzUuODQ2IDE1OS45NjgtMS43NjIgNi44LTcuMDUyIDE0LjMzOC00LjIxOSAyMS40MDcgNC40NyAzLjQ3MiAxMC4xLTEuODk4IDEzLjk3LTQuMjUgMTUuOTI2LTE0LjUzOSAyNC43NTYtMzUuMDc3IDM1LjMxMi01My41OTQgNDQuNDc1LTg2LjI5IDg2LjE1Ny0xNzQuMDAzIDEyOS40NDYtMjYwLjkgNDcuMDAyLTk0Ljg5NiA5NC4wMDgtMTg5LjgyMyAxNDIuMDIyLTI4NC4xOTQgMTMuNTg0LTIwLjEwNCAzOS4zNjUtMjYuODQgNTQuNTk1LTQ1LjQxIDkuNjk5LTEwLjY0NSAxNS45MDQtMjQuNzM4IDE0LjM0My0zOS4zNC0xLTI0LjI5OC0xNS4wNy01MC41OTQtNDAuMjE5LTU2LjM3NS01LjE2LTEuMzA4LTEwLjUtMS43MDctMTUuODQzLTEuNDY5eiIvPjxwYXRoIGQ9Im00ODkuNzI2IDEzNC44MjZjMTIuNDgtMjEuMTk2LTE5LjczMS0zNC43MTgtMi44ODItNDkuNTIyIDkuNDYxLTguMzEzIDI1LjY0OC05LjE0NCAzNC43MzcgMS42MzkgMTMuMTAzIDE1LjU0Ny0yMi43NDUgMjkuMDM1LTUuMTA3IDQ3LjY3NyIgZmlsbD0idXJsKCNkKSIvPjwvZz48L2c+PC9zdmc+'); } -body.base .is2d piece.rook.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTA1MDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoMS4wNDUyMSAwIDAgMS4wMTQ1IC0zMy44MjkgLTExLjgzNSkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNy4zMzgiIHgyPSI2ODkuNzQ1IiB4bGluazpocmVmPSIjYSIgeTE9IjIwNy42NjUiIHkyPSIyNzQuMzMxIi8+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDEuMDQ1MjEgMCAwIDEuMDE0NSAtMzMuODI5IC0xMS44MzUpIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxOC41MDIiIHgyPSI5MDYuMDk1IiB4bGluazpocmVmPSIjYSIgeTE9IjUyMS41MyIgeTI9IjY0My4xOTciLz48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoMS4wNDUyMSAwIDAgMS4wMTQ1IC0zMy44MjkgLTExLjgzNSkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTUzLjQxNCIgeDI9Ijk2Ni41ODYiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjI5LjA2OCIgeTI9IjQwMC43MzQiLz48bGluZWFyR3JhZGllbnQgaWQ9ImMiIGdyYWRpZW50VHJhbnNmb3JtPSJtYXRyaXgoMS4wNDUyMSAwIDAgMS4wMTQ1IC0zMy44MjkgLTExLjgzNSkiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTkzLjE1IiB4Mj0iODc4LjU5NSIgeGxpbms6aHJlZj0iI2EiIHkxPSI3MTUuNDA2IiB5Mj0iNzgyLjA3MiIvPjxnIHN0cm9rZT0iZ3JheSIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxNiI+PGcgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIj48cGF0aCBkPSJNMjAwLjMwMyAzMjMuMzU1czMuMjUtMTE3LjIzMyAxNy42NTUtMTU2LjIwNmMzMC4wOTgtNi40OTggODkuMzUtOS41NjMgMTI2LjE1Ni00LjE5MS40MTIgMjMuODQyLTUuNDMzIDczLjk5LTEuNTkxIDk2LjkxNSAzMy40NDUtMS41ODUgMTAxLjIgMi40NzcgMTQ0LjMxNi0yLjM3MS45Ni0yNy45Ny03LjI3LTY3LjU3Ljg5My05OC43NSAyNy4zNjgtMi4wNTYgODkuMjM4LTQuMjMxIDExOC4wNDcgOC4xNDgtMy44NCAzOS44OS41NjMgOTQuNzMuNTYzIDk0LjczbDc1LjUzMiAyLjYxNC0xMS4yNDcgNjBjLTk0LjMwNCAzNS4zNDgtNDExLjMzIDMwLjEtNDcwLjMyNC0uODl6IiBmaWxsPSJ1cmwoI2IpIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBkPSJNMjUwLjcxNyA3MDIuNDc2Yy0yMy45ODggMjMuOTUzLTc0LjExNCA0OC4wNTYtMTA5Ljg1NyA1NS42MjItNS4xODQgMTcuMTEyLTEwLjI4NCAzNi44OTguMjQgNTguMTc0IDEyNy4zOTcgMS4xNTUgNDYzLjc5LS4zMjQgNTg1LjUxNi0uNzQ3IDYuNTY4LTIzLjczMSAxMS41MzUtNDAuODk4IDQuOTY3LTU5LjU1LTM3LjQ3OS03LjQyLTgyLjc0My0xOC42MjQtMTE2LjI1LTUzLjQ5NiIgZmlsbD0idXJsKCNjKSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PHBhdGggZD0iTTE5OC4wNDEgNzY4LjYyM2MxNDkuNDU4LjA3MiAzMTEuNjY0LTUuNTEzIDQ3MS41MTIuNTgiIGZpbGw9Im5vbmUiLz48L2c+PHBhdGggZD0iTTI1Mi43NDMgMzEwLjg3Yy0zLjc2OCA0NC44NTEtNC44NTQgMzU3LjI4OC0zLjgxNyAzOTQuNTA0IDU1LjE3Ny00LjY2NiAzMTEuNjEyLTQuOTYgMzY4LjE2Mi0uNTY3LTMuMjAyLTcwLjAzLTIuMzE2LTM5Mi45NTItMi4zMTYtMzkyLjk1MiIgZmlsbD0idXJsKCNkKSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PGcgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIj48cGF0aCBkPSJNMjkxLjM4IDYzNC44MzNjMzkuODg5LTIuOTQgMTIzLjQ3LTYuMjUyIDIxNS40MzktMy4yOTVtLTIxNi43OTYtNjEuMzljNTAuNzUyLTQuODg2IDk5Ljg0OC02LjQ5NSAxNzEuMy01Ljc1Mk0yOTAuNTU4IDUwNC45NWM3Mi4yNjgtNC45OTcgNzQuMzA0LTQuNDY2IDE1Mi41MTYtNS41OTRtLTE1Mi41MTYtNTguMzQ0YzM2LjY4NS0zLjAzMyA1OC4yNTgtNC42MSAxMDIuMTYtMy41NW0tNTcuOTU4IDIwLjI0MmMuODggMjkuOTMyLS4xNzUtMS4zMzYuNzA0IDI0LjU1bTU0Ljk3NyAzOC45OTZjLjg4IDI5LjkzMi0uMTc1LTEuMzM2LjcwNCAyNC41NW0tNTYuMzg1IDM5LjcyOWMuODggMjkuOTMxLS4xNzUtMS4zMzcuNzA0IDI0LjU1bTExNi4wOS0yNi41NzljLjg3OSAyOS45MzEtLjE3Ni42OTIuNzAzIDI2LjU3OW0tNjEuODE2IDQyLjE1NGMuODggMjkuOTMyLS4xNzUuNjkzLjcwNCAyNi41OG0tOTkuMzI2LTI5NS42MDljMjcuODU3LTMuMDMzIDQyLjA1Mi00LjAwNyA2NS43NzYtMy41NSIgZmlsbD0ibm9uZSIvPjxwYXRoIGQ9Ik0xMzEuNzQ4IDE2MS4yNzhjNS4xNTYgMjguMjIzIDkuMDUyIDU0Ljk5OSAxNC4wNDggOTUuNTQgMzIuMDc3IDIyLjM2NiA1MC4wMzMgMzAuMTc3IDUzLjQ2OCA2Ny42NTcgOTYuMzUyLTE3LjM2MSAzODYuOTY4LTEzLjM2IDQ3NC4zNTMtLjM1MiA2LjA5LTMzLjc4MiAxNi4wNTMtMzkuNTU1IDYzLjEzLTY3LjkxIDUuOTQ3LTQ0LjM2MSAxMS4xNjktNjUuNzUgMTEuNTA1LTkyLjI3My0xNC4xMDctMy40My0xMTUuNDY4LTMzLjc4NC0xMjcuOTg5LTI5LjQyNC00LjQ1MyAyNi4zOTMgMS44NDQgNDkuMDY3LTQuMDE1IDczLjg4OC0zNy45NDMgMS45MDItNzEuNzQ1LjQ1OC0xMTEuMDEzLTkuNzYzLjE5NS0zMy4xNzguMTQ2LTUxLjM3MyAxLjc3Ni03Ny4wNTItMTYuNTgzLTUuOTA2LTExNS4yMDgtNi45NTYtMTMzLjgxNi0uODY1LTMuMjA3IDMxLjk3OC44NDcgNDkuMzk5LTEuNzIzIDc3LjgzLTMzLjY4MyA5LjUyOS02NS42MjcgNy4wNTctMTA1LjgzOCA5LjMxNi0zLjI0LTMzLjgwNSAyLjc0My00NS42NjcgMS45ODItNjkuMzk2LTE2LjU5LTQuNTM2LTEyMC4yMDQgMTcuOTg3LTEzNS44NjggMjIuODA0eiIgZmlsbD0idXJsKCNlKSIgZmlsbC1ydWxlPSJldmVub2RkIi8+PHBhdGggZD0iTTE4OC43NCAyNjIuMjQ3YzE0OC42NTQtMTQuNjk1IDM2OC41MTMtMTUuNjEgNDk2LjA5NiAzLjU0NCIgZmlsbD0ibm9uZSIvPjwvZz48L2c+PC9zdmc+'); } -body.base .is2d piece.queen.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTA1MDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImciIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNzg1LjE0MSIgeDI9Ijg0MC45MTEiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjk0Ljc1OSIgeTI9IjM2My4wODkiLz48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNjQ5Ljg2MyIgeDI9IjcxMS4xMTciIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTcxLjE4IiB5Mj0iMjI3Ljc0OSIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0MDYuMDEyIiB4Mj0iNDcwLjgzNSIgeGxpbms6aHJlZj0iI2EiIHkxPSIxMDMuNTMyIiB5Mj0iMTMyLjk5NCIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIxNjcuODcyIiB4Mj0iMjM0LjYyIiB4bGluazpocmVmPSIjYSIgeTE9IjE3NC45OTciIHkyPSIxNzQuOTk3Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJrIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIzLjQ1OCIgeDI9Ijg3LjM3MSIgeGxpbms6aHJlZj0iI2EiIHkxPSIzMzcuODU1IiB5Mj0iMzE1LjQ2MyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzMzkuNDcxIiB4Mj0iNTE0LjU0IiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1NzEuNTkzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMzOS40NzEiIHgyPSI0OTUuMDIyIiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1ODQuNzU4Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJmIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMzOS40NzEiIHgyPSI0ODcuMjE1IiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1ODQuNzU4Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJoIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMzOS40NzEiIHgyPSI0OTguOTI2IiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1ODQuNzU4Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJsIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjMzOS40NzEiIHgyPSI1MTAuNjM3IiB4bGluazpocmVmPSIjYSIgeTE9IjUzMC42MDYiIHkyPSI1ODQuNzU4Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJiIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjE1My42MDQiIHgyPSI3NjEuMzY0IiB4bGluazpocmVmPSIjYSIgeTE9IjM4MC41NCIgeTI9IjY4Mi4yMDciLz48ZyBmaWxsLXJ1bGU9ImV2ZW5vZGQiPjxwYXRoIGQ9Ik0yNDMuOTM1IDgyNC44OWwtNTAuMzc4LTE2Ni4yMTIgNDMzLjc2OCAxLjMxOC00OS41MTkgMTY5LjY4MXoiIGZpbGw9InVybCgjYikiLz48ZyBzdHJva2U9ImdyYXkiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PGcgc3Ryb2tlLXdpZHRoPSIxNiI+PGcgZmlsbD0idXJsKCNiKSI+PHBhdGggZD0iTTYxMi43MTMgNzE2LjI4Yy0xMjIuMi00My42NjktMjgzLjQwNi00My45MjMtNDAyLjM5NC0uMTA0IDEyLjU4NSAzMC41MyAxNS45MTkgOTIuOTk4IDE1LjkxOSA5Mi45OTggMTAwLjcxOS0yOC4xNzMgMjcxLjk1NC0yNy4zMTcgMzcxLjg4NSA0LjE4OCAwIDAgMi4zMS02Ni43MDcgMTQuNTktOTcuMDgyeiIvPjxwYXRoIGQ9Ik0xOTUuMTA0IDY5Ny45MTVjMTIxLjg1LTUyLjY4NiAzMTIuNTgtNTMuNTIgNDM1LjU3Ny40MUM2NDIuODA3IDU5My4yOSA2ODEuMDMgNDYzLjYzIDc1My4zNjQgMzcwLjYyN2MtNTQuODQ4IDIxLjQ2Mi0xMzQuNDggMTU4Ljg2My0xODAuNzc1IDE4NC43NTgtMzYuMzA0LTc2LjI2MyAzNS41NDQtMjc0LjIwNCA2My40NzgtMzE2LjEyOS00Ni44OTkgMjguMjE5LTE0Ni4xNDcgMjAzLjAxNi0xNzUuNDcgMjg0Ljc4NS00Mi4yNjUtOTQuNDQ1LTMyLjM3Mi0yNzEuMDgyLTMzLjM4My0zNDUuMTA4LTMxLjc5NiA2OS41NTMtNzMuNTE4IDIyOS4zNzMtNzcuNzg4IDM0Mi4zMTQtODEuMTkzLTYwLjg2NC0xMDkuODQ2LTIyNS4yNy0xMzEuNTAxLTI5MC40MDYtMTEuOTI0IDkzLjc5OCA4Ljg4NCAyNTcuMTczIDIyLjYyMyAzMjMuMjI3LTUyLjc5Mi0zNS41OTMtMTE0LjQ0LTExMy45Mi0xNjUuNjExLTE4MC4zMDUgNjUuMDYgMTU1LjU3NCA4OC42MDggMjAyLjY5MyAxMjAuMTY3IDMyNC4xNTN6bTIxMi42NTkgMS44NjdjLTE4Ljk5OC0uMDk4LTguNTg1IDE0LjYzNS0xMi4zMTggMjEuMTE1LTguNTM4IDQuOTQ5LTM2LjI0Ni0zLjgzMi0yNy4zMjcgMTQuMzQgNi4zMTkgMTIuODc0IDE1Ljc2NiA2LjgxMyAyNi4zNzcgMTAuOTYxIDUuMjc2IDcuMjY3LTMuNjQzIDI5LjM2NiAxNS4wMzcgMjguOTAzIDE1LjQyNy0uMzgzIDcuMDE4LTIyLjQzMSAxMC4zMTYtMjguMzcyIDkuMzI2LTYuMDk0IDIxLjU2MiAyLjE2NSAyNy43MzQtMTMuNDUyIDQuNjg2LTExLjg1Ni0xOC41MTItNy40NTgtMjcuNjczLTEyLjU2NC0zLjgzNy01LjczMSA3LjYyLTIwLjgyOC0xMi4xNDYtMjAuOTMxem0tMTYzLjE5IDEyNS40OTFjODguODIzIDEwLjU5OSAyMzIuNzIyIDE0LjM2IDMzMi45NTggNC40MDctNTYuNTY4LTI1LjI4MS0yNTkuODktMjUuMDY4LTMzMi45NTgtNC40MDd6Ii8+PC9nPjxwYXRoIGQ9Ik00NzQuNjIgODIuNTE4Yy04LjU2LjE4OC0zNC45NDMgNC42Mi01MC43OTggMTIuNTI4LTQuODEgMTIuMTEtMi4zMTIgNDcuNjA2LjEzMSA3Ni42NCAxNS4xODUtMjQuMzcgNDguNzM3LTY2LjI1NCA1MC42NjctODkuMTY4eiIgZmlsbD0idXJsKCNjKSIvPjwvZz48cGF0aCBkPSJNNDQwLjc2MyA1MzAuNjA2YTQ1Ljk2MiA0NC43ODMgMCAxIDEtOTEuOTI0IDAgNDUuOTYyIDQ0Ljc4MyAwIDEgMSA5MS45MjQgMHoiIGZpbGw9InVybCgjZCkiIHN0cm9rZS13aWR0aD0iMTguNzM3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg4Ny4yMzUgLTI3MS41MDYpIHNjYWxlKC44NTM5MykiLz48cGF0aCBkPSJNNzE0LjkwMiAyMDYuMDA1Yy00LjcxNy01LjY1My0xLjcxLTE2LTQwLjAwMy0zNy4wNTVsLTQ4Ljg1NiA2MS4wMjljMjcuNDEtOC41NSA3MC43NjQtMjEuNDYgODguODYtMjMuOTc0eiIgZmlsbD0idXJsKCNlKSIgc3Ryb2tlLXdpZHRoPSIxNiIvPjxwYXRoIGQ9Ik00NDAuNzYzIDUzMC42MDZhNDUuOTYyIDQ0Ljc4MyAwIDEgMS05MS45MjQgMCA0NS45NjIgNDQuNzgzIDAgMSAxIDkxLjkyNCAweiIgZmlsbD0idXJsKCNmKSIgc3Ryb2tlLXdpZHRoPSIxOC43MzciIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI5NS4yMzUgLTIxMS41MDYpIHNjYWxlKC44NTM5MykiLz48cGF0aCBkPSJNODQ1LjU2IDM1MS44OTFjMi42NzQtMTMuODI3LTEyLjE3LTE4LjI2OC0yNi40MTEtMzcuMzI0LTE5LjgzNiA4LjEyMi00Mi44MTcgMTcuODEtNTkuMDA2IDQwLjUyMiA0MC44NjctOC40MjggNTkuNDQ0IDQuMDU4IDg1LjQxNy0zLjE5OHoiIGZpbGw9InVybCgjZykiIHN0cm9rZS13aWR0aD0iMTYiLz48cGF0aCBkPSJNNDQwLjc2MyA1MzAuNjA2YTQ1Ljk2MiA0NC43ODMgMCAxIDEtOTEuOTI0IDAgNDUuOTYyIDQ0Ljc4MyAwIDEgMSA5MS45MjQgMHoiIGZpbGw9InVybCgjaCkiIHN0cm9rZS13aWR0aD0iMTguNzM3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MTcuODUgLTg1Ljc0OSkgc2NhbGUoLjg1MzkzKSIvPjxwYXRoIGQ9Ik0yMjYuNjIgMTU0LjUxOGMtMTAuNTYtMTEuODEyLTIyLjg5My0xMC4xMTctNTAuNzQ4LTE0LjIwOC45NzIgMzMuNzI2IDIxLjEwNCA0My4xMzUgMzMuMDgxIDY5LjM3NSAxNS4xODUtMjQuMzcgMTIuNzM3LTI1LjI1MyAxNy42NjctNTUuMTY3eiIgZmlsbD0idXJsKCNpKSIgc3Ryb2tlLXdpZHRoPSIxNiIvPjxwYXRoIGQ9Ik00NDAuNzYzIDUzMC42MDZhNDUuOTYyIDQ0Ljc4MyAwIDEgMS05MS45MjQgMCA0NS45NjIgNDQuNzgzIDAgMSAxIDkxLjkyNCAweiIgZmlsbD0idXJsKCNqKSIgc3Ryb2tlLXdpZHRoPSIxOC43MzciIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0xMjMuNzY1IC0yMTkuNTA2KSBzY2FsZSguODUzOTMpIi8+PHBhdGggZD0iTTUwLjI2MyAyODkuNzgyYy0xMy40NDcgMi44LTE0LjU4NSAzMC4zMTItMTguODA1IDQ0LjQyNiAxNS4wNTcgMTYuNTk1IDMwLjM2NyAyNi4wNSA0My41MiA1MS43MiAxNC4wNjUtMjUuMDMzLTguNzU5LTc2LjkzNi0yNC43MTUtOTYuMTQ2eiIgZmlsbD0idXJsKCNrKSIgc3Ryb2tlLXdpZHRoPSIxNiIvPjxwYXRoIGQ9Ik00NDAuNzYzIDUzMC42MDZhNDUuOTYyIDQ0Ljc4MyAwIDEgMS05MS45MjQgMCA0NS45NjIgNDQuNzgzIDAgMSAxIDkxLjkyNCAweiIgZmlsbD0idXJsKCNsKSIgc3Ryb2tlLXdpZHRoPSIxOC43MzciIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yNDkuMTA4IC02OC45Mikgc2NhbGUoLjg1MzkzKSIvPjwvZz48L2c+PC9zdmc+'); } -body.base .is2d piece.king.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjcwMHB0IiB2aWV3Qm94PSItMjAgMCA5MDAgOTAwIiB3aWR0aD0iNzAwcHQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTA1MDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjk3LjU1NCIgeDI9IjM2OC41NjIiIHhsaW5rOmhyZWY9IiNhIiB5MT0iNDI3LjA1IiB5Mj0iNTIxLjIxNiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0OTUuMjk2IiB4Mj0iNTk1Ljk3MSIgeGxpbms6aHJlZj0iI2EiIHkxPSI0NDguNTQ3IiB5Mj0iNTI4LjU0NyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIyMjEuNTUxIiB4Mj0iNjMzLjQ5MSIgeGxpbms6aHJlZj0iI2EiIHkxPSI3NzQuOTM3IiB5Mj0iODU5LjM1MSIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIxMjkuOTYyIiB4Mj0iODEyLjM2OSIgeGxpbms6aHJlZj0iI2EiIHkxPSI0MjguNjU5IiB5Mj0iODM2LjMxMyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzNjguNDY5IiB4Mj0iNDk0LjU1MSIgeGxpbms6aHJlZj0iI2EiIHkxPSIzMTkuMjc1IiB5Mj0iMzE5LjI3NSIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzNzkuMTk3IiB4Mj0iNTc5Ljg0OCIgeGxpbms6aHJlZj0iI2EiIHkxPSIxNjAuMjUzIiB5Mj0iMjg2LjkxOSIvPjxnIGZpbGwtcnVsZT0iZXZlbm9kZCI+PGcgc3Ryb2tlPSJncmF5IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMTYiPjxwYXRoIGQ9Ik0yODguNjM1IDYxMi40ODVjMjMuMTkyLTMzLjUxLTcuMDUxLTEyNS44MzkuMDE4LTE2OC4wNTIgMTEuNDczLTY4LjUwOCAxMDEuNDktMTE0LjQ5IDExMy41MDUtNzQuNzcxIDE0LjI1MyA0Ny4xMTYtNDMuNjEyIDUxLjU2My01OS43MTIgOTAuODkzLTE0Ljc4OCAzNi4xMjYtMTEuNjI0IDk2LjQ4MyAxNy4xNjYgMTMyLjgxIiBmaWxsPSJ1cmwoI2IpIi8+PHBhdGggZD0iTTU4Ni44OSA2MTcuMzE2Yy0yMy4xOTItMzMuNTEgNy4wNTItMTI1LjgzOS0uMDE4LTE2OC4wNTItMTEuNDczLTY4LjUwOC0xMDEuNDktMTE0LjQ5LTExMy41MDUtNzQuNzcxLTE0LjI1MyA0Ny4xMTYgNDMuNjEyIDUxLjU2MyA1OS43MTIgOTAuODkzIDE0Ljc4OCAzNi4xMjYgMTEuNjI0IDk2LjQ4My0xNy4xNjYgMTMyLjgxIiBmaWxsPSJ1cmwoI2MpIi8+PHBhdGggZD0iTTQwMS4yMTcgMjg4LjExNWM1LjI1Ny0xNSAxOC45MDQtNzAuOTI1IDEzLjkxNi04Ny40LTIyLjMxNC0xLjc2Ni02OC45MzUgMTguNzAyLTk5LjE1MiAxMi4xNDUtOC41MS0xNS4zODYtMTMuODI0LTQ4LjQ5NC0xLjYtNjYuNjY4IDI3LjM1Ni04LjMyNCA4Ny43MzEgNi4yNjkgMTA0LjQyIDguNTA1IDUuOTE1LTE2Ljg1My0xNC40OTUtNjcuNjM4LTEwLjU0MS04Ni4wMjcgMTguNzUtOC45NjMgNjUuMzE0LTguMDc3IDc5LjE1MyAxLjAzNC0uNzA1IDE5LjMxNC0yOC44OTUgNjYuMjI1LTI5LjU3OSA4Mi4yNjQgMTguNzg0LS45NjMgNzcuMjk0LTE2Ljg3NSA5Ny4yNjgtMTIuOTg5IDguNjE2IDE2LjcxIDEwLjQ4NiA0Ni41NjUtMy40MTQgNjUuNjQ2LTIxLjI5NSA3LjA5My03Ny42NzUtOC45My0xMDEuMTY3LTQuMjctOS45IDE5Ljk2NyA1LjQ5MSA3MS41MjMgOS4yNzggODYuNjA1IiBmaWxsPSJ1cmwoI2QpIi8+PHBhdGggZD0iTTQwOC40MSAzNzEuODMyYy0yNC43MzUtMjEuNDE4LTM1LjYzNC0yMS41OTYtMzAuODMzLTc1LjIwNiA0LjEtNDUuNzgxIDEwNi4yNTctNDMuNDIgMTA4LjYzNC0xLjk5MSAyLjk4MSA1MS45NDctMTQuMjkgNTUuODM3LTI2LjMgODAuOTkiIGZpbGw9InVybCgjZSkiLz48L2c+PHBhdGggZD0iTTI3MC45NjIgODMwLjNsLTYzLjk3NS0xOTYuMjQ0IDQ3MS4yMzMtMi4wNjctNzQuODkgMjA0LjMyNHoiIGZpbGw9InVybCgjZikiLz48ZyBzdHJva2U9ImdyYXkiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PGcgc3Ryb2tlLXdpZHRoPSIxNiI+PGcgZmlsbD0idXJsKCNmKSI+PHBhdGggZD0iTTY0My40NTYgNzE3LjExYy05My42NzYtNDguMDE1LTMwNy4xMzktNTAuMjctNDA3LjYwNiAxLjg3NSAxNC4wNzQgNDQuNDczIDE5LjcwNCA5My45NzMgMTkuNzA0IDkzLjk3MyA5MS42NjYtMjguNDY0IDI3Ny44NzMtMjkuNiAzNjcuODczIDQuMTQzIDAgMCA5LjI4LTY2LjY4IDIwLjAzLTk5Ljk5MnoiLz48cGF0aCBkPSJNNTUzLjUzMSA1NzQuMDMxYy0zNi4yNC0xNS4zMTMtNzYuNzA0LTU4LjgyNi0xMjEuOTc4LTYwLjIyMi00My41NzQgMS4wMS03OC41NTYgMzguNTY0LTEwMy4zOTcgNTguNDEtMTE1LjI3My01Mi40NjctMTEzLjg5NS0xNTIuODkyLTMzLjI1LTE3MS4zMTMgMTMuMTM1LTMgNTIuMjMyLjQ2NCA3OC4wNjMtLjcxOS04LjIyNi0yMi43MTUtMTcuMTkyLTM4LjgyMy04LjY4OC02OS4wNjItMTguMjI4LTExLjczMi00Mi40ODgtMjAuMTQ0LTcwLjEyNS0yMS43ODFhMzUxLjAyMyAzNTEuMDIzIDAgMCAwLTI1LjAzMS0uNTk0Yy04MS4yMDEgMS0xNjUuNDUxIDMwLjUzNi0xNzcuNDA2IDEwNS4yNUM3NC4yNyA1MjMuMDQ4IDE3MC44MSA1ODcuMzE1IDIwNS41NjMgNzAyLjY1NmMxMTAuMzA3LTYyLjkwOCAzNjQuNjY0LTU4LjkwMiA0NzAuMzQzLTQuNTMxIDI4LjA0OC04OS4xNjIgMTM5Ljg1MS0xOTMuMzYgMTE0Ljg0NC0yODQuMjUtMjMuMTU4LTg0LjE3LTEzNS43NDItMTA4LjgwMS0yMTAuMDMxLTEwNC41OTQtMzAuMTA5IDEuNzA2LTU5LjAxMyAxMS40NTMtODAuNzE5IDI0Ljg0NCA0LjIwMiAyMy45NzEtNC4zMTUgNDMuNTctMTEuMzc1IDY0LjI4MSAzNC4zNDUuMDE1IDk0LjYwMi03Ljk3MiAxMTguMjUgNS40MDYgNTIuMjMgMjkuNTQ3IDU2LjIxMiAxMzUuODk3LTUzLjM0NCAxNzAuMjJ6Ii8+PHBhdGggZD0iTTMyOC40ODggNTcyLjUyOGMzNy45OTUtMjYuNjc4IDU1Ljk5OC03OS42NjEgNTQuNDc5LTEyMi40MzUtMi4xOTEtNjEuNjc2LTM1LjE4LTcyLjQyNi0xNi4zNC0xMjYuNDE0IDEyLjc3NC0zNi42MDcgMTE5LjE2My0zOC40ODkgMTMxLjE3OSAxLjIzIDE0LjI1MyA0Ny4xMTYtMjIuMzQzIDc2LjQ1LTE2LjYzOCAxMjQuMTQ1IDYuNjU0IDU1LjY0IDcuMDY3IDkyLjUyMyA3Mi4yOTQgMTI2LjU3MyIvPjwvZz48cGF0aCBkPSJNMjc1LjY5MSA4MzIuNjc4Yzg3Ljg2NSAxMC40ODQgMjI4LjIxMiAxMi4yMDUgMzI3LjM2NyAyLjM2LTY4LjU5Ny0yNy45OC0yNTYuNTU1LTI3LjY3Ny0zMjcuMzY3LTIuMzZ6IiBmaWxsPSJ1cmwoI2cpIi8+PC9nPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Ik00NTMuNjIyIDczNy4wMzVhMTYuOTA4IDE2LjEwMyAwIDEgMS0zMy44MTcgMCAxNi45MDggMTYuMTAzIDAgMSAxIDMzLjgxNyAweiIgc3Ryb2tlLXdpZHRoPSIxNiIvPjxwYXRoIGQ9Ik04MTUgOTE1YTE3LjUgMTYuNjY3IDAgMSAxLTM1IDAgMTcuNSAxNi42NjcgMCAxIDEgMzUgMHoiIHN0cm9rZS13aWR0aD0iMTguMDg3IiB0cmFuc2Zvcm09Im1hdHJpeCgxLjA2MjYyIC0uMTkyNDQgLjEyOTEzIC43MTMwNCAtNjI4LjA3MiAyNDkuNTQ5KSIvPjxwYXRoIGQ9Ik04MTUgOTE1YTE3LjUgMTYuNjY3IDAgMSAxLTM1IDAgMTcuNSAxNi42NjcgMCAxIDEgMzUgMHoiIHN0cm9rZS13aWR0aD0iMTguMzIiIHRyYW5zZm9ybT0ibWF0cml4KDEuMDM4OTggLjE2ODYxIC0uMTE2MDggLjcxNTI4IC0xODguNjUyIC00MC40NDUpIi8+PC9nPjwvZz48L2c+PC9zdmc+'); } diff --git a/public/stylesheets/piece/kosal.css b/public/stylesheets/piece/kosal.css deleted file mode 100644 index 0409a468ae..0000000000 --- a/public/stylesheets/piece/kosal.css +++ /dev/null @@ -1,12 +0,0 @@ -body.base .is2d piece.pawn.white { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzMiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDojRkZGRkZGO30KCS5zdDF7ZmlsbDojQ0ZDRUNGO30KCS5zdDJ7ZmlsbDpub25lO30KCS5zdDN7ZmlsbDojMDEwMTAxO30KPC9zdHlsZT4KPGc+Cgk8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMjkuNywzNy44aDIxLjZsLTUuMS02aDAuN2MyLjYtMS45LDQuMy01LjEsNC4zLTguNmMwLTYtNC44LTEwLjctMTAuNy0xMC43cy0xMC43LDQuOC0xMC43LDEwLjcKCQljMCwzLjUsMS43LDYuNyw0LjMsOC42aDAuN0wyOS43LDM3Ljh6Ii8+Cgk8cG9seWdvbiBjbGFzcz0ic3QwIiBwb2ludHM9IjQ5LjQsNjAuNSA0NS4xLDM5LjggMzUuMSwzOS44IDMxLjYsNjAuNSAyMSw2OS45IDYwLDY5LjkgCSIvPgo8L2c+Cjxwb2x5Z29uIGNsYXNzPSJzdDEiIHBvaW50cz0iNDAuNSw1OS43IDQ3LjgsNzEgNjEuNiw3MSA1MS4yLDYwIDQ5LjgsNTkuMSA0Ni45LDM4LjkgNDAuNSwzOC45ICIvPgo8cG9seWdvbiBjbGFzcz0ic3QxIiBwb2ludHM9IjQ0LjQsMzggNTIuNSwzOCA0Ny4yLDMxLjUgNDEsMzEuNSAiLz4KPHBhdGggY2xhc3M9InN0MSIgZD0iTTQ1LDEzLjNjMy43LDUuNSwxLjEsMTcuNi0xMC4yLDE3LjZjLTAuMiwwLDEyLjEsMC42LDEzLjEtMC4zYzEuOS0xLjksMy4xLTQuNCwzLjEtNy4zCglDNTEuMSwxNy4zLDQ0LjgsMTIuMSw0NSwxMy4zeiIvPgo8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjMxLjksNjAuNiAyMS42LDY5LjcgNTkuNCw2OS43IDQ5LjIsNjAuNyA0OS4xLDYwLjYgNDQuOSw0MCAzNS4zLDQwICIvPgo8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjQ2LjEsMzIgMzQuOSwzMiAzMC4yLDM3LjkgNTAuOCwzNy45ICIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNNDcuNSwyOS41YzEuNi0xLjcsMi41LTQsMi41LTYuNGMwLTUuMy00LjItOS41LTkuNS05LjVjLTUuMiwwLTkuNSw0LjItOS41LDkuNWMwLDIuNCwwLjksNC42LDIuNSw2LjRINDcuNXoiCgkvPgo8cGF0aCBjbGFzcz0ic3QzIiBkPSJNMTUsNzIuMkg2Nkw1MS41LDU5LjRsLTQuMi0yMGg4LjJsLTcuMS04YzIuOS0yLjIsMy42LTUuNiwzLjYtOC4xYzAtNi40LTUtMTEuNC0xMS40LTExLjQKCWMtNi4zLDAtMTEuNCw1LjEtMTEuNCwxMS40YzAsMi41LDAuNiw1LjksMy42LDguMWwtNy4xLDhIMzNsLTMuNCwyMEwxNSw3Mi4yeiBNMzEuNCwyMy4zYzAtNSw0LjEtOS4xLDkuMS05LjFjNS4xLDAsOS4xLDQsOS4xLDkuMQoJYzAsMi4zLTAuOCw0LjQtMi40LDYuMUgzMy44QzMyLjMsMjcuNywzMS40LDI1LjUsMzEuNCwyMy4zeiBNMzUuMiwzMS43aDEwLjdsNC41LDUuNkgzMC43TDM1LjIsMzEuN3ogTTM1LjQsMzkuNGgwLjFoOS4yaDAuMQoJbDQuNCwyMS4ybDAsMC4xbDEwLjIsOUgyMS42bDEwLjItOS4xTDM1LjQsMzkuNHoiLz4KPC9zdmc+Cg=='); } -body.base .is2d piece.knight.white { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzJfMV8iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDojRkZGRkZGO30KCS5zdDF7ZmlsbDojQ0ZDRUNGO30KPC9zdHlsZT4KPHBhdGggY2xhc3M9InN0MCIgZD0iTTQ4LDQ1LjFjLTMuMywxLjYtNy4yLDEuOS0xMSwwLjdsLTAuNC0wLjFsLTAuMywwLjJjLTAuMSwwLjEtMTIsOS45LTE1LjgsMjMuN2wtMC4zLDAuOUg2NUw2My4yLDY1di0wLjEKCWMwLTAuMS0wLjEtMTQuOC0wLjEtMjMuOGMwLTE2LjktNy42LTI1LjYtMTUtMjguNmMtMy43LTEuNC05LjItMi41LTEyLjQtMi41aC0xLjJsMy4yLDYuMkwxMy4zLDM2LjVsMSwxMC44bDUsMS40bDUuMS0zLjlIMjYKCWwtNC4zLDQuNWwxLjEsMC40bDYuNywxLjlsNS41LTYuOGMzLjUsMS41LDcuNywxLjMsMTIuNS0wLjZjMi44LTEuMiw1LjEtMy42LDYuNS01LjZDNTMuMSw0MS40LDUxLDQzLjcsNDgsNDUuMXoiLz4KPHBhdGggZD0iTTM4LDIyLjFsLTcuNyw2LjJjLTAuNSwwLjUtMC42LDEuMy0wLjIsMS45YzAuMywwLjQsMC43LDAuNiwxLjEsMC42YzAuMiwwLDAuNCwwLDAuNi0wLjFsOS4xLTMuNkwzOCwyMi4xeiIvPgo8cGF0aCBjbGFzcz0ic3QxIiBkPSJNMzguNyw3MC43TDU2LjQsNzFoOC41YzAsMC0yLjEtNS4yLTIuMS03LjJjMC04LjIsMC0yOS45LDAtMzUuMmMwLDguNC0yLjcsMTgtOS41LDI0LjgKCUM0MC41LDU3LDM4LjcsNzAuNywzOC43LDcwLjd6Ii8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0zNC42LDQ3LjNsMS4zLTEuOGw4LjgsMC44bDQuOC0yLjJsMy45LTMuNGwyLjQtNi41Yy0wLjgtMS4zLTIuMi0yLjEtNC0yLjhjLTIsNy43LTguMSwxMi4zLTE2LjMsMTAuNAoJYy0wLjQsMS4xLTAuNywxLjktMC43LDEuOWwtNywwLjNMMjIsNDguOGw3LDQuNUwzNC42LDQ3LjN6Ii8+CjxwYXRoIGQ9Ik0xOC4yLDcyLjJoNDkuMWwtMi41LTcuNWMwLTEuOSwwLTE1LjEsMC0yMy42YzAtNi44LTAuOS0yMy45LTE2LTMwLjFjLTUuOC0yLjQtMTQuNi0yLjYtMTUtMi41TDMyLDguNmwzLjcsNy4ybC0yNC4yLDIwCglsMS4zLDEyLjhsMTQuNSw0LjJjLTMuNSw0LjUtNy4zLDEwLjctOC45LDE4TDE4LjIsNzIuMnogTTM2LjcsNDYuNWMxLjUsMC41LDMuMSwwLjgsNC44LDAuOGMyLjQsMCw0LjctMC41LDYuOC0xLjUKCWM0LjEtMiw2LjgtNS42LDcuMy0xMC4xbDAuMi0xLjRsLTAuNiwxLjJjMCwwLjEtMyw1LjgtNy45LDhjLTMuOSwxLjYtOC40LDIuNC0xMi40LDAuNGwtNS42LDYuOWwtNS44LTEuN0wyMy4xLDQ5bDQuNy00LjloLTMuNwoJbC01LDMuOEwxNSw0Ni43bC0wLjktOS45bDI0LjYtMjAuNGwtMi45LTUuNmMyLjksMCw4LjMsMC45LDEyLjEsMi40YzUuNywyLjMsMTQuNSw5LjYsMTQuNSwyNy45YzAsOS4xLDAuMSwyMy44LDAuMSwyMy44djAuMgoJbDEuNSw0LjdIMjEuMkMyNC44LDU2LjYsMzUuOSw0Ny4xLDM2LjcsNDYuNXoiLz4KPC9zdmc+Cg=='); } -body.base .is2d piece.bishop.white { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojRkZGRkZGO30KCS5zdDJ7ZmlsbDojQ0ZDRUNGO30KPC9zdHlsZT4KPHJlY3QgY2xhc3M9InN0MCIgd2lkdGg9IjgxIiBoZWlnaHQ9IjgxIi8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik02MS40LDcxbC0xMS45LTkuMWwxMC42LTE0LjZjMC0xMS00LjktMTkuOS0xMS45LTI2LjNsLTEuNy0wLjhsLTcuOSwxNC4zbC0xLjUtMS42bDcuOC0xNC43bDAsMGwyLjctNS4xCgljMC0wLjEsMC0wLjIsMC0wLjJjMC0zLjYtMi45LTYuNi02LjYtNi42Yy0zLjYsMC02LjYsMi45LTYuNiw2LjZjMCwwLjEsMCwwLjIsMCwwLjJsMi4zLDQuNEMyOCwyNC4xLDIwLjksMzQuMSwyMC45LDQ3LjNsMTAuNiwxNC42CglMMTkuNiw3MUg2MS40eiIvPgo8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjQ1LjYsNzAuNyA2MCw3MC43IDQ5LjYsNjEuMiA0Mi44LDYxLjIgIi8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik01MC44LDI1LjFDNTQuNyw0Mi4xLDM2LDU1LjgsMzYsNTUuOGw3LjMsNC43aDcuNGwxMC4yLTEzLjJsLTEuNS04LjZsLTMuNi04LjNMNTMuMiwyNkw1MC44LDI1LjF6Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik00NC41LDguNmMwLjgsMi40LTMuNCw0LjQtMy40LDQuNHY1LjFsMy4zLDAuMWwzLTQuM2wtMC4zLTMuNEw0NSw4LjZINDQuNXoiLz4KPHBhdGggZD0iTTY1LDcyLjJMNTAuOSw2MS42bDEwLjItMTR2LTAuNGMwLTE0LjEtNy42LTIzLjEtMTIuMi0yNy4zbC0yLjMtMi4zbDIuMS0zLjlsMC4xLTAuM3YtMC41YzAtNC4zLTMuNS03LjktNy45LTcuOQoJYy00LjMsMC03LjgsMy41LTcuOCw3Ljl2MC41bDEuOSwzLjdjLTUuOSw0LjYtMTUuNSwxNC42LTE1LjUsMzAuMXYwLjRsMTAuMiwxNEwxNiw3Mi4ySDY1eiBNMjIuNSw0Ni45Yy0wLjMtMTQuNiw5LjMtMjQsMTUtMjguMgoJbDAuOS0wLjZMMzUuNywxM2MwLTIuOSwyLjQtNS4zLDUuMy01LjNjMi45LDAsNS4zLDIuNCw1LjQsNS4zTDM1LjgsMzQuNnYwLjFsMi4yLDUuOGw5LjMtMTguOGwxLjEsMWM0LjgsNC43LDEwLjQsMTIuNywxMC4xLDI0LjEKCWwtOS4yLDEzSDMxLjhMMjIuNSw0Ni45eiBNMzIuOSw2Mi41SDQ4bDkuOCw3LjNIMjMuMkwzMi45LDYyLjV6Ii8+Cjxwb2x5bGluZSBwb2ludHM9IjM2LjIsMTggNDEuMSwxOCAzOC40LDIwLjEgMzQuNiwyMC4xICIvPgo8L3N2Zz4K'); } -body.base .is2d piece.rook.white { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDojRkZGRkZGO30KCS5zdDF7ZmlsbDojQ0ZDRUNGO30KPC9zdHlsZT4KPHBvbHlnb24gY2xhc3M9InN0MCIgcG9pbnRzPSI1OC43LDU5LjQgNTUuNSwzMi4xIDY0LjEsMjMuOSA2NC4xLDIzLjkgNjQuMSwxMi44IDUzLDEyLjggNTMsMjAuOSA0Ni4zLDIwLjkgNDYuMywxMi44IDM0LjcsMTIuOCAKCTM0LjcsMjAuOSAyOCwyMC45IDI4LDEyLjggMTYuOSwxMi44IDE2LjksMjMuOSAyNS41LDMyLjEgMjIuMyw1OS40IDE1LjcsNTkuNCAxNS43LDcxIDE5LjgsNzEgNjEuMSw3MSA2MS4yLDcxIDY1LjMsNzEgNjUuMyw1OS40IAoJIi8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik01OC41LDU5LjdsLTQuMi0yNy4yaDIuMmw3LjYtOC42VjEyLjhsLTUuOCw0LjZ2OC4ySDMybDExLjYsNi45aDMuMmMwLDEyLjEtMi44LDIxLjMtMTEuNywyNy4yaDEzLjNMNTQuNSw3MAoJaDkuOVY1OS43SDU4LjV6Ii8+CjxwYXRoIGQ9Ik01OS4xLDU4LjFsLTIuNi0yNC44bDguNy05VjExLjVINTEuOHY4LjJoLTQuMnYtOC4ySDMzLjV2OC4yaC00LjJ2LTguMkgxNS42djEyLjlsOC43LDlsLTIuNiwyNC44bDAsMGgtNy4zdjE0LjFoNTEuOFY3MgoJbDAsMGgwLjJWNTguMUg1OS4xeiBNMzYsMjIuMlYxNGg5djguMmg5LjJWMTRoOC41djkuM0w1NC40LDMySDI2LjVsLTguNC04LjZWMTRoOC42djguMkgzNnogTTU0LDM0LjRsMi42LDIzLjdIMjQuM2wyLjYtMjMuN0g1NHoKCSBNNTYuOSw2MC42SDYwaDR2OS4xSDE3di05LjFoNC44SDI0QzI0LDYwLjYsNTYuOSw2MC42LDU2LjksNjAuNnoiLz4KPC9zdmc+Cg=='); } -body.base .is2d piece.queen.white { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojRkZGRkZGO30KCS5zdDJ7ZmlsbDojQ0ZDRUNGO30KCS5zdDN7ZmlsbDojMjMxRjIwO30KPC9zdHlsZT4KPHJlY3QgY2xhc3M9InN0MCIgd2lkdGg9IjgxIiBoZWlnaHQ9IjgxIi8+CjxnPgoJPGNpcmNsZSBjbGFzcz0ic3QxIiBjeD0iMjEuOSIgY3k9IjE2LjUiIHI9IjUuMiIvPgoJPHBhdGggY2xhc3M9InN0MSIgZD0iTTU5LjEsMjEuOGMyLjksMCw1LjItMi4zLDUuMi01LjJzLTIuMy01LjItNS4yLTUuMnMtNS4yLDIuMy01LjIsNS4yUzU2LjIsMjEuOCw1OS4xLDIxLjh6Ii8+Cgk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNNzIuMSwyNi40Yy0yLjksMC01LjIsMi4zLTUuMiw1LjJjMCwxLjQsMC42LDIuOCwxLjUsMy43TDU1LjIsNTAuNWwzLjMtMjguN2wtMi4xLTAuNmwtOS44LDE2LjlsLTUuMS0yMS43CgkJaC0xLjFoLTEuMWwtNS4xLDIxLjdsLTkuOC0xNi45bC0yLjEsMC42bDMuMywyOC43bC0xMy0xNS4yYzAuOS0wLjksMS41LTIuMywxLjUtMy43YzAtMi45LTIuMy01LjItNS4yLTUuMnMtNS4yLDIuMy01LjIsNS4yCgkJczIuMyw1LjIsNS4yLDUuMmMwLjUsMCwxLTAuMSwxLjUtMC4yTDE5LjUsNzFoNDIuMWw5LjEtMzQuNGMwLjUsMC4xLDEsMC4yLDEuNSwwLjJjMi45LDAsNS4yLTIuMyw1LjItNS4yUzc1LDI2LjQsNzIuMSwyNi40eiIvPgoJPGNpcmNsZSBjbGFzcz0ic3QxIiBjeD0iNDAuNSIgY3k9IjExLjMiIHI9IjUuMiIvPgo8L2c+CjxnPgoJPHBhdGggY2xhc3M9InN0MiIgZD0iTTQ4LjQsMzMuNiIvPgoJPHBhdGggY2xhc3M9InN0MiIgZD0iTTM0LjUsMzMuNiIvPgoJPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSI0MS40LDIwLjMgNDYuNywzOC4yIDQxLjQsNDUuNSAJIi8+Cgk8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjI3LjEsNTMuNiAyMy42LDYwLjQgMTMuOSwzOC4zIAkiLz4KCTxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iMzQsNTAuNSAyNC44LDIyLjggNDAuNSw1MC45IAkiLz4KCTxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iNDguMiw1MC41IDU3LjUsMjUuOCA1My45LDUzLjYgCSIvPgoJPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSI1Mi45LDcwLjQgNjguNSwzNi43IDcwLDM3IDYwLjcsNzAuNCAJIi8+CjwvZz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTczLjMsMzYuN2MzLjQtMC45LDMuOS0zLjQsNC02LjdjMC0wLjYtMC45LTEuOC0xLjMtMS44Yy0wLjQsMC4xLTAuOCwwLjEtMS4yLDAuM2MwLjMsMi41LTEuMyw1LTMuOCw1LjcKCWMtMS4xLDAuMy0yLjEsMC4yLTMuMS0wLjFDNjcuMywzNS4xLDcxLjgsMzcuMSw3My4zLDM2Ljd6Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik02MCwyMS4zYzMuNC0wLjksMy45LTMuNCw0LTYuN2MwLTAuNi0wLjktMS44LTEuMy0xLjhjLTAuNCwwLjEtMC44LDAuMS0xLjIsMC4zYzAuMywyLjUtMS4zLDUtMy44LDUuNwoJYy0xLjEsMC4zLTIuMSwwLjItMy4xLTAuMUM1NCwxOS43LDU4LjUsMjEuNyw2MCwyMS4zeiIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNMTAuMSwzNi43YzMuNC0wLjksMy45LTMuNCw0LTYuN2MwLTAuNi0wLjktMS44LTEuMy0xLjhjLTAuNCwwLjEtMC44LDAuMS0xLjIsMC4zYzAuMywyLjUtMS4zLDUtMy44LDUuNwoJYy0xLjEsMC4zLTIuMSwwLjItMy4xLTAuMUM0LjEsMzUuMSw4LjYsMzcuMSwxMC4xLDM2Ljd6Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0yMy4xLDIxLjNjMy40LTAuOSwzLjktMy40LDQtNi43YzAtMC42LTAuOS0xLjgtMS4zLTEuOGMtMC40LDAuMS0wLjgsMC4xLTEuMiwwLjNjMC4zLDIuNS0xLjMsNS0zLjgsNS43CgljLTEuMSwwLjMtMi4xLDAuMi0zLjEtMC4xQzE3LjEsMTkuNywyMS42LDIxLjcsMjMuMSwyMS4zeiIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNNDEuNiwxNi4xYzMuNC0wLjksMy45LTMuNCw0LTYuN2MwLTAuNi0wLjktMS44LTEuMy0xLjhjLTAuNCwwLjEtMC44LDAuMS0xLjIsMC4zYzAuMywyLjUtMS4zLDUtMy44LDUuNwoJYy0xLjEsMC4zLTIuMSwwLjItMy4xLTAuMUMzNS42LDE0LjYsNDAuMSwxNi41LDQxLjYsMTYuMXoiLz4KPHBvbHlnb24gY2xhc3M9InN0MyIgcG9pbnRzPSI0MC41LDY1LjcgMzYuNiw1OS44IDQwLjUsNTQgNDQuNCw1OS44ICIvPgo8Zz4KCTxjaXJjbGUgY2xhc3M9InN0MSIgY3g9IjIxLjkiIGN5PSIxNi41IiByPSI1LjIiLz4KCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik01OS4xLDIxLjhjMi45LDAsNS4yLTIuMyw1LjItNS4ycy0yLjMtNS4yLTUuMi01LjJzLTUuMiwyLjMtNS4yLDUuMlM1Ni4yLDIxLjgsNTkuMSwyMS44eiIvPgoJPHBhdGggY2xhc3M9InN0MSIgZD0iTTcyLjEsMjYuNGMtMi45LDAtNS4yLDIuMy01LjIsNS4yYzAsMS40LDAuNiwyLjgsMS41LDMuN0w1NS4yLDUwLjVsMy4zLTI4LjdsLTIuMS0wLjZsLTkuOCwxNi45bC01LjEtMjEuNwoJCWgtMS4xaC0xLjFsLTUuMSwyMS43bC05LjgtMTYuOWwtMi4xLDAuNmwzLjMsMjguN2wtMTMtMTUuMmMwLjktMC45LDEuNS0yLjMsMS41LTMuN2MwLTIuOS0yLjMtNS4yLTUuMi01LjJzLTUuMiwyLjMtNS4yLDUuMgoJCXMyLjMsNS4yLDUuMiw1LjJjMC41LDAsMS0wLjEsMS41LTAuMkwxOS41LDcxaDQyLjFsOS4xLTM0LjRjMC41LDAuMSwxLDAuMiwxLjUsMC4yYzIuOSwwLDUuMi0yLjMsNS4yLTUuMlM3NSwyNi40LDcyLjEsMjYuNHoiLz4KCTxjaXJjbGUgY2xhc3M9InN0MSIgY3g9IjQwLjUiIGN5PSIxMS4zIiByPSI1LjIiLz4KPC9nPgo8Zz4KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik00OC40LDMzLjYiLz4KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0zNC41LDMzLjYiLz4KCTxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iNDEuNCwyMC4zIDQ2LjcsMzguMiA0MS40LDQ1LjUgCSIvPgoJPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSIyNy4xLDUzLjYgMjMuNiw2MC40IDEzLjksMzguMyAJIi8+Cgk8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjM0LDUwLjUgMjQuOCwyMi44IDQwLjUsNTAuOSAJIi8+Cgk8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjQ4LjIsNTAuNSA1Ny41LDI1LjggNTMuOSw1My42IAkiLz4KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik00Mi4xLDcwLjRDNjIsNjUuNyw2OC41LDM2LjcsNjguNSwzNi43TDcwLDM3bC05LjMsMzMuNEM2MC43LDcwLjQsNTIuOCw3MC40LDQyLjEsNzAuNHoiLz4KPC9nPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNNzMuMywzNi43YzMuNC0wLjksMy45LTMuNCw0LTYuN2MwLTAuNi0wLjktMS44LTEuMy0xLjhjLTAuNCwwLjEtMC44LDAuMS0xLjIsMC4zYzAuMywyLjUtMS4zLDUtMy44LDUuNwoJYy0xLjEsMC4zLTIuMSwwLjItMy4xLTAuMUM2Ny4zLDM1LjEsNzEuOCwzNy4xLDczLjMsMzYuN3oiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTYwLDIxLjNjMy40LTAuOSwzLjktMy40LDQtNi43YzAtMC42LTAuOS0xLjgtMS4zLTEuOGMtMC40LDAuMS0wLjgsMC4xLTEuMiwwLjNjMC4zLDIuNS0xLjMsNS0zLjgsNS43CgljLTEuMSwwLjMtMi4xLDAuMi0zLjEtMC4xQzU0LDE5LjcsNTguNSwyMS43LDYwLDIxLjN6Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0xMC4xLDM2LjdjMy40LTAuOSwzLjktMy40LDQtNi43YzAtMC42LTAuOS0xLjgtMS4zLTEuOGMtMC40LDAuMS0wLjgsMC4xLTEuMiwwLjNjMC4zLDIuNS0xLjMsNS0zLjgsNS43CgljLTEuMSwwLjMtMi4xLDAuMi0zLjEtMC4xQzQuMSwzNS4xLDguNiwzNy4xLDEwLjEsMzYuN3oiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTIzLjEsMjEuM2MzLjQtMC45LDMuOS0zLjQsNC02LjdjMC0wLjYtMC45LTEuOC0xLjMtMS44Yy0wLjQsMC4xLTAuOCwwLjEtMS4yLDAuM2MwLjMsMi41LTEuMyw1LTMuOCw1LjcKCWMtMS4xLDAuMy0yLjEsMC4yLTMuMS0wLjFDMTcuMSwxOS43LDIxLjYsMjEuNywyMy4xLDIxLjN6Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik00MS42LDE2LjFjMy40LTAuOSwzLjktMy40LDQtNi43YzAtMC42LTAuOS0xLjgtMS4zLTEuOGMtMC40LDAuMS0wLjgsMC4xLTEuMiwwLjNjMC4zLDIuNS0xLjMsNS0zLjgsNS43CgljLTEuMSwwLjMtMi4xLDAuMi0zLjEtMC4xQzM1LjYsMTQuNiw0MC4xLDE2LjUsNDEuNiwxNi4xeiIvPgo8cG9seWdvbiBwb2ludHM9IjQwLjUsNjUuNyAzNi42LDU5LjggNDAuNSw1NCA0NC40LDU5LjggIi8+CjxwYXRoIGQ9Ik03Mi4xLDI1LjFjLTMuNiwwLTYuNCwyLjktNi40LDYuNWMwLDEuMywwLjQsMi42LDEuMSwzLjdsLTEwLjUsMTNsMy40LTI1LjRjMy4zLTAuMyw1LjktMy4xLDUuOS02LjRjMC0zLjYtMi45LTYuNS02LjUtNi41CglzLTYuNSwyLjktNi41LDYuNWMwLDEuOSwwLjgsMy43LDIuMyw1bC03LjgsMTMuNEw0MywxNy4zYzIuMy0xLDMuOS0zLjQsMy45LTZjMC0zLjYtMi45LTYuNC02LjQtNi40Yy0zLjYsMC02LjUsMi45LTYuNSw2LjQKCWMwLDIuNiwxLjUsNC45LDMuOSw2bC00LjEsMTcuNkwyNiwyMS41YzEuNS0xLjIsMi4zLTMuMSwyLjMtNWMwLTMuNi0yLjktNi41LTYuNS02LjVzLTYuNSwyLjktNi41LDYuNWMwLDMuMywyLjYsNi4xLDUuOSw2LjQKCWwzLjQsMjUuNGwtMTAuNC0xM2MwLjctMSwxLjEtMi4zLDEuMS0zLjdjMC0zLjYtMi45LTYuNS02LjUtNi41UzIuNCwyOCwyLjQsMzEuNlM1LjMsMzgsOC44LDM4aDAuNWw5LDM0djAuMmg0NGw5LTM0LjJoMC41CgljMy42LDAsNi40LTIuOSw2LjQtNi40Qzc4LjMsMjgsNzUuNiwyNS4xLDcyLjEsMjUuMXogTTEzLjEsMzEuNmMwLDIuMy0xLjksNC4xLTQuMiw0LjFzLTQuMS0xLjgtNC4xLTQuMXMxLjktNC4yLDQuMS00LjIKCUMxMS4yLDI3LjQsMTMuMSwyOS4zLDEzLjEsMzEuNnogTTIxLjksMjAuOGMtMi4zLDAtNC4xLTEuOS00LjEtNC4yczEuOS00LjIsNC4xLTQuMmMyLjMsMCw0LjIsMS45LDQuMiw0LjIKCUMyNi4xLDE4LjgsMjQuMiwyMC44LDIxLjksMjAuOHogTTU1LDE2LjVjMC0yLjMsMS45LTQuMiw0LjEtNC4yYzIuMywwLDQuMiwxLjksNC4yLDQuMnMtMS45LDQuMi00LjIsNC4yQzU2LjgsMjAuOCw1NSwxOC45LDU1LDE2LjUKCXogTTIwLjQsNjkuOGwtOC42LTMyLjRjMC4xLTAuMSwwLjItMC4xLDAuMy0wLjFzMC4yLTAuMSwwLjMtMC4xbDE1LjEsMTcuM2wtMy43LTMxLjZoMC4xTDQwLjMsNTFsMC4yLDAuNGwxNi42LTI4LjdoMC4xbC0zLjcsMzEuNgoJTDY4LjYsMzdjMC4yLDAuMSwwLjQsMC4yLDAuNiwwLjNsLTguNiwzMi41SDIwLjR6IE03Ni4zLDMxLjZjMCwyLjMtMS45LDQuMS00LjIsNC4xYy0yLjMsMC00LjEtMS44LTQuMS00LjFzMS45LTQuMiw0LjEtNC4yCglDNzQuNCwyNy40LDc2LjMsMjkuMyw3Ni4zLDMxLjZ6IE00MC41LDQ2LjNMMzUuNywzOGw0LjctMjAuMmgwLjNMNDUuMywzOEw0MC41LDQ2LjN6IE00MC41LDE1LjVjLTIuMywwLTQuMi0xLjktNC4yLTQuMgoJczEuOS00LjEsNC4yLTQuMXM0LjIsMS45LDQuMiw0LjFDNDQuOCwxMy42LDQyLjgsMTUuNSw0MC41LDE1LjV6Ii8+Cjwvc3ZnPgo='); } -body.base .is2d piece.king.white { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojRkZGRkZGO30KCS5zdDJ7ZmlsbDojQ0ZDRUNGO30KPC9zdHlsZT4KPHJlY3QgY2xhc3M9InN0MCIgd2lkdGg9IjgxIiBoZWlnaHQ9IjgxIi8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik01OCwyNS45Yy02LDAtOS4xLDIuNi0xMC42LDQuMWwtNywxMi4ybC03LTEyLjJDMzIsMjguNSwyOSwyNS45LDIzLDI1LjljLTkuNCwwLTE0LjksNy43LTE0LjksMTUuMwoJYzAsOC42LDMuNywxMS41LDguNiwyMS43VjcxaDIzLjhoMjMuOHYtOC4xYzQuOS0xMC4xLDguNi0xMy4xLDguNi0yMS43QzcyLjksMzMuNiw2Ny40LDI1LjksNTgsMjUuOXoiLz4KPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSIzNS4zLDMyLjggNDAuNSw0My41IDQ1LjcsMzIuOCA0Mi42LDIxLjggNTAuNSwyNC4yIDUwLjUsMTYuNiA0Mi42LDE3LjYgNDQuMywxMC4zIDM2LjcsMTAuMyAKCTM4LjQsMTcuNiAzMC41LDE2LjYgMzAuNSwyNC4yIDM4LjQsMjEuOCAiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTY0LjcsMjcuNEM3MS44LDQwLDU4LDU4LjYsNDUuOSw1OS45bDE5LjQsMi42bDYuNi0xMy40bDEtOS45TDcxLjIsMzRsLTIuNi0zLjZMNjQuNywyNy40eiIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNMzMuNiwzMC4xYzEuMSw1LjQtMS42LDE0LjYtNS40LDIwLjVTMTcuNyw2MS40LDE3LjcsNjEuNGwyMi44LTEuNlY0Mi42TDMzLjYsMzAuMXoiLz4KPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSI1My4xLDYwLjYgNTMuMSw3MC41IDY0LDcwLjUgNjQsNjIuOSAiLz4KPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSI0OS41LDE3LjcgNDguMiwyMC41IDQxLjEsMjAuMyA0OS41LDIzLjYgNTAuNSwyMy42ICIvPgo8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjQzLjEsMTEuMyA0MC41LDEzIDQwLjUsMTkuMiA0Mi4xLDE4LjIgIi8+Cjxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iNDEuOCwyMS41IDQxLjgsMzMuMiA0MC41LDQwLjIgNDUsMzQgIi8+Cjxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iMzkuOSwyMC42IDMwLjUsMjAuNiAzMC41LDI0LjIgIi8+CjxnPgoJPHBvbHlnb24gcG9pbnRzPSIzNi40LDUxLjIgNDAuNSw1Ny4yIDQ0LjYsNTEuMiA0MC41LDQ1LjIgCSIvPgoJPHBhdGggZD0iTTY5LjgsMjkuOWMtMy0zLjQtNy4yLTUuMi0xMS44LTUuMmMtNC44LDAtOC42LDEuNS0xMS41LDQuNUw0NiwzMGwtMS45LTYuN2w3LjQsMi4yVjE1LjRsLTcuNiwxbDEuNy03LjFIMzUuNGwxLjcsNy4xCgkJbC03LjYtMXYxMC4xbDcuNC0yLjJMMzUsMzAuMWwtMC40LTAuN2wtMC4xLTAuMmwwLTAuMWMtMi45LTMtNi43LTQuNS0xMS41LTQuNWMtMTAuMSwwLTE2LjEsOC40LTE2LjEsMTYuNmMwLDYuNCwyLDEwLDQuOCwxNC45CgkJbDAuNiwxYzEsMS43LDIuMSwzLjcsMy4yLDZ2OS4xaDUwLjF2LTkuMWMxLjItMi4zLDIuMi00LjMsMy4yLTZsMC42LTFjMi44LTQuOSw0LjgtOC41LDQuOC0xNC45Qzc0LjIsMzcuMSw3Mi42LDMzLDY5LjgsMjkuOXoKCQkgTTM5LjksMjAuM2wtOC40LDIuNXYtNS4xbDguMiwxbC0xLjgtNy40aDUuMmwtMS44LDcuNGw4LjItMXY1LjFsLTguNC0yLjVsMy41LDEyLjJsLTQuMSw3LjJsLTQuMS03LjJMMzkuOSwyMC4zeiBNNjMsNjkuOEgxNy44CgkJdi02LjVDMjEuNiw2Mi42LDMxLDYxLDQwLjUsNjFjOS4zLDAsMTguNiwxLjUsMjIuNSwyLjJWNjkuOHogTTY3LjIsNTQuOUw2Ny4yLDU0LjljLTEsMS42LTMsNC43LTMuOCw1LjljLTQuMS0wLjctMTMuNC0yLjItMjMtMi4yCgkJYy05LjcsMC0xOS4yLDEuNS0yMy4xLDIuMmMtMC44LTEuMi0yLjgtNC4yLTMuNy01LjlsLTAuMS0wLjFDMTAuOCw1MCw5LjEsNDcsOS4xLDQxLjNjMC05LjEsNy0xNCwxMy42LTE0YzQsMCw3LjIsMS4yLDkuNiwzLjYKCQlsOCwxMy45bDgtMTMuOWMyLjQtMi40LDUuNi0zLjYsOS42LTMuNmM4LjksMCwxMy43LDcuMiwxMy43LDE0QzcxLjcsNDcsNzAsNTAsNjcuMiw1NC45eiIvPgo8L2c+Cjwvc3ZnPgo='); } -body.base .is2d piece.pawn.black { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojMDEwMTAxO30KCS5zdDJ7ZmlsbDojNkQ2RTZFO30KCS5zdDN7ZGlzcGxheTpub25lO30KCS5zdDR7ZGlzcGxheTppbmxpbmU7ZmlsbDpub25lO30KCS5zdDV7ZGlzcGxheTppbmxpbmU7ZmlsbDojRkZGRkZGO30KCS5zdDZ7ZGlzcGxheTppbmxpbmU7ZmlsbDojQ0ZDRUNGO30KCS5zdDd7ZGlzcGxheTppbmxpbmU7ZmlsbDojMjMxRjIwO3N0cm9rZTojMDAwMDAwO3N0cm9rZS13aWR0aDowLjU7c3Ryb2tlLW1pdGVybGltaXQ6MTA7fQoJLnN0OHtkaXNwbGF5OmlubGluZTtzdHJva2U6IzAwMDAwMDtzdHJva2Utd2lkdGg6MC41O3N0cm9rZS1taXRlcmxpbWl0OjEwO30KCS5zdDl7ZGlzcGxheTppbmxpbmU7fQo8L3N0eWxlPgo8cmVjdCBjbGFzcz0ic3QwIiB3aWR0aD0iODEiIGhlaWdodD0iODEiLz4KPHBhdGggY2xhc3M9InN0MSIgZD0iTTQwLjUsMTIuNWMtNiwwLTEwLjcsNC44LTEwLjcsMTAuN2MwLDMuNiwxLjgsNi45LDQuNiw4LjhoMTIuM2MyLjgtMS45LDQuNi01LjIsNC42LTguOAoJQzUxLjIsMTcuMiw0Ni41LDEyLjUsNDAuNSwxMi41Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik00My4yLDE2LjRjLTEuNS0wLjktMy4zLTEuMS01LjItMC42Yy0zLjYsMS01LjYsNC42LTQuNyw4LjJjMCwwLjEsMC4xLDAuMiwwLjEsMC4zQzM5LjIsMjUsNDQsMTkuMSw0My4yLDE2LjR6CgkiLz4KPHBhdGggY2xhc3M9InN0MSIgZD0iTTM0LjUsMzEuN2wtMC4zLDcuN2wtMy41LDIxLjdMMTguMyw3Mmg0NC4zTDUwLjMsNjEuMUw0NiwzOS40bC0wLjMtNy43Ii8+Cjxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iMzcuNywzOS42IDMzLjgsNjIuMSAyNy4yLDY5LjIgMzQuOCw2OS4yIDQwLDYzLjggNDAuMSwzOS42ICIvPgo8cG9seWdvbiBjbGFzcz0ic3QxIiBwb2ludHM9IjI2LjYsMzguOCA1NC40LDM4LjggNDcuNywzMC44IDMzLjMsMzAuOCAiLz4KPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSIzMi4zLDM2LjUgNDEuMSwzNi41IDM5LDMyLjUgMzUuMiwzMi41ICIvPgo8ZyBpZD0iTGF5ZXJfMl8xXyIgY2xhc3M9InN0MyI+Cgk8cmVjdCBjbGFzcz0ic3Q0IiB3aWR0aD0iODEiIGhlaWdodD0iODEiLz4KCTxwYXRoIGNsYXNzPSJzdDUiIGQ9Ik0zNC4zLDMzLjJjLTIuOC0yLTQuNy01LjItNC43LTguOWMwLTYsNC45LTEwLjksMTAuOS0xMC45czEwLjksNC45LDEwLjksMTAuOWMwLDMuNy0xLjksNy00LjcsOC45bDAuNSw4LjMKCQlsMy40LDE4LjdMNjMuMyw3MUgxNy43bDEyLjctMTAuOGwzLjQtMTguNyIvPgoJPHBhdGggY2xhc3M9InN0NiIgZD0iTTQ1LDE0LjRDNDguNywxOS45LDQ2LjEsMzMsMzQuOCwzM2MtMC4yLDAsMTIuMSwwLjYsMTMuMS0wLjNjMS45LTEuOSwzLjEtNC40LDMuMS03LjMKCQlDNTEuMSwxOS40LDQ0LjgsMTMuMiw0NSwxNC40eiIvPgoJPHBvbHlnb24gY2xhc3M9InN0NiIgcG9pbnRzPSI0MC41LDYwLjggNDcuOCw3MCA2Mi4xLDcwIDUxLjIsNjEuMSA0OS44LDYwLjIgNDYuOSw0MSA0MC41LDQxIAkiLz4KCTxwYXRoIGNsYXNzPSJzdDciIGQ9Ik00MC41LDExLjdjLTcsMC0xMi43LDUuNy0xMi43LDEyLjdjMCw0LjMsMi4yLDguMSw1LjUsMTAuNGg3LjNjLTUuNywwLTEwLjQtNC43LTEwLjQtMTAuNFMzNC45LDE0LDQwLjYsMTQKCQlTNTEsMTguNiw1MSwyNC4zcy00LjcsMTAuNC0xMC40LDEwLjRoNy4zYzMuMy0yLjMsNS41LTYuMiw1LjUtMTAuNEM1My4xLDE3LjQsNDcuNCwxMS43LDQwLjUsMTEuN3oiLz4KCTxwYXRoIGNsYXNzPSJzdDgiIGQ9Ik00OC4yLDQybDMuMiwxNy42TDY2LDcySDE1bDE0LjUtMTIuNEwzMi44LDQyIE0zNSw0MWwtMy42LDE5LjdsLTExLDkuM2g0MC4xbC0xMC45LTkuM0w0Niw0MSIvPgoJPHBhdGggY2xhc3M9InN0NSIgZD0iTTM0LjMsMzMuMiIvPgoJPHBvbHlnb24gY2xhc3M9InN0OSIgcG9pbnRzPSI1MC4zLDMyLjggMzAuNywzMi44IDIyLjUsNDMuMiA1OC41LDQzLjIgCSIvPgoJPHBvbHlnb24gY2xhc3M9InN0NSIgcG9pbnRzPSIyNy41LDQxIDUzLjUsNDEgNDguOSwzNS4yIDMyLjEsMzUuMiAJIi8+Cgk8cG9seWdvbiBjbGFzcz0ic3Q2IiBwb2ludHM9IjQ0LjEsNDEgNTMuNSw0MSA0OC45LDM1LjIgNDAuNywzNS4yIAkiLz4KPC9nPgo8L3N2Zz4K'); } -body.base .is2d piece.knight.black { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojMDEwMTAxO30KCS5zdDJ7ZmlsbDojNkQ2RTZFO30KPC9zdHlsZT4KPHJlY3QgY2xhc3M9InN0MCIgd2lkdGg9IjgxIiBoZWlnaHQ9IjgxIi8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0xOS42LDcyQzM4LjIsNzIsNjcsNzIsNjcsNzJsLTItNi4xYzAsMC0wLjEtMTctMC4xLTI2LjFjMC0xNy4zLTguNS0yNS4zLTE2LTI4LjRjLTUuNi0yLjMtMTQuNi0xLjgtMTQuNi0xLjgKCWwzLjMsNi41TDEyLDM2LjRsMiwxMi4ybDEzLjQsMy41bDYuMS01LjFjMS4yLDAuNSwyLjUsMC44LDMuNywxLjF2MC4zQzM3LjIsNDguNCwyMi45LDU3LDE5LjYsNzJ6IE0zMS40LDMxLjMKCWMtMC42LDAuMy0xLjEtMC41LTAuNi0xbDcuMi02LjJsMi4yLDMuN0wzMS40LDMxLjN6Ii8+Cjxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iMTUuOCwzOCAxNy4xLDQ1LjkgMjEuOCw0NyAyMS43LDQyLjQgMTguOCw0MS45ICIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNMzAuOCwzMy40bDE1LjYtMy44bDIuMi0zLjhjMCwwLDIuOCwxLjEsMi4xLDYuM3MtNi44LDguMy0xMi4xLDcuNkMzMS43LDM4LjgsMzAuOCwzMy40LDMwLjgsMzMuNHoiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTM2LDY3LjljNS4xLTE2LjQsMTYuNC0xMywxNi44LTIyLjRjLTMuMyw1LjktMTAuNyw1LjYtMTAuNyw1LjZzLTExLjYsNS4xLTE1LjgsMTYuOAoJQzI2LjMsNjcuOSwzNiw2Ny45LDM2LDY3Ljl6Ii8+Cjwvc3ZnPgo='); } -body.base .is2d piece.bishop.black { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojMDEwMTAxO30KCS5zdDJ7ZmlsbDojNkQ2RTZFO30KPC9zdHlsZT4KPHJlY3QgeD0iMCIgeT0iMCIgY2xhc3M9InN0MCIgd2lkdGg9IjgxIiBoZWlnaHQ9IjgxIi8+Cjxwb2x5Z29uIGNsYXNzPSJzdDEiIHBvaW50cz0iMTguOSw3MiA2Mi4xLDcyIDUwLjMsNjIuNSAzMC43LDYyLjUgIi8+CjxnPgoJPHBhdGggY2xhc3M9InN0MSIgZD0iTTQxLDE4LjljMS41LDAsMi45LTAuNSw0LTEuM2wyLjgtNS4yYzAtMC4xLDAtMC4yLDAtMC4zYzAtMy43LTMtNi44LTYuOC02LjhjLTMuNywwLTYuOCwzLTYuOCw2LjgKCQljMCwwLjEsMCwwLjIsMCwwLjNsMi44LDUuMkMzOC4yLDE4LjQsMzkuNiwxOC45LDQxLDE4LjkiLz4KCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik00OC40LDIwLjRsLTkuNywxOC4yTDM3LDMyLjdsOC4xLTE1LjJjLTEtMC44LTItMS41LTMtMi4yaC0zLjFjLTEwLDYuNi0xOS4xLDE3LjUtMTkuMSwzMi4ybDEwLjksMTUuMmgyLjdoMTQKCQloMi43bDEwLjktMTUuMkM2MS4xLDM2LjEsNTUuNiwyNyw0OC40LDIwLjQiLz4KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik00OC42LDI3LjlsLTcuMiwxM2MwLDAsNSwxLjMsNy4yLTEuOUM1MC44LDM1LjksNTAuMiwyOC45LDQ4LjYsMjcuOXoiLz4KCTxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik0zMS4yLDU1LjFjLTEuNi0xMy45LDEuNC0yOC4xLDcuOS0zNC44bC0wLjUtMC43Yy03LjEsNi4zLTE0LDE1LjYtMTQsMjYuNkwzMS4yLDU1LjF6Ii8+CjwvZz4KPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSIzNy45LDY5IDM3LjksNjMuMyAzNS40LDYzLjMgMjguOCw2OSAiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTQyLjQsNy45Yy0wLjgtMC41LTEuOC0wLjYtMi43LTAuM2MtMS45LDAuNS0zLDIuNS0yLjUsNC40YzAsMC4xLDAsMC4xLDAuMSwwLjJDNDAuMywxMi40LDQyLjgsOS4zLDQyLjQsNy45eiIKCS8+Cjwvc3ZnPgo='); } -body.base .is2d piece.rook.black { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojMDEwMTAxO30KCS5zdDJ7ZmlsbDojNkQ2RTZFO30KPC9zdHlsZT4KPHJlY3QgY2xhc3M9InN0MCIgd2lkdGg9IjgxIiBoZWlnaHQ9IjgxIi8+Cjxwb2x5Z29uIGNsYXNzPSJzdDEiIHBvaW50cz0iNTYuOSwzMS4xIDI0LjEsMzEuMSAxOS4yLDcyIDYxLjgsNzIgNjEuOCw3MiAiLz4KPHJlY3QgeD0iMTQuMiIgeT0iNTguNSIgY2xhc3M9InN0MSIgd2lkdGg9IjUyLjUiIGhlaWdodD0iMTMuNSIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNNDEuMSwzNC4xYy0wLjEsNy4yLTYuNiwyNC40LTE0LjIsMjQuNGMtMS4yLDAtMi4zLDAtMi4zLDBsMy44LTI0LjRINDEuMXoiLz4KPHJlY3QgeD0iMTguNCIgeT0iNjIuMyIgY2xhc3M9InN0MiIgd2lkdGg9IjE3LjkiIGhlaWdodD0iNi4xIi8+Cjxwb2x5Z29uIGNsYXNzPSJzdDEiIHBvaW50cz0iNTMuNCwxMiA1My40LDE4LjkgNDYuNSwxOC45IDQ2LjUsMTIgMzQuNSwxMiAzNC41LDE4LjkgMjcuNiwxOC45IDI3LjYsMTIgMTUuNiwxMiAxNS42LDIzLjQgCgkyNC42LDMyLjUgNTYuNCwzMi41IDY1LjQsMjMuNCA2NS40LDIzLjQgNjUuNCwxMiAiLz4KPGc+Cgk8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjYyLjQsMTUgNTYuNCwxNSA1Ni40LDIyLjIgCSIvPgoJPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSI0My41LDE1IDM3LjUsMTUgMzcuNSwyMi4yIAkiLz4KCTxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iMjQuNiwxNSAxOC42LDE1IDE4LjYsMjIuMiAJIi8+CjwvZz4KPC9zdmc+Cg=='); } -body.base .is2d piece.queen.black { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojMDEwMTAxO30KCS5zdDJ7ZmlsbDojNkQ2RTZFO30KPC9zdHlsZT4KPHJlY3QgY2xhc3M9InN0MCIgd2lkdGg9IjgxIiBoZWlnaHQ9IjgxIi8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik01NS43LDUwLjlsNC0zNC45TDQwLjUsNDkuMkwyMS4zLDE2bDQuMSwzNC45TDcuOSwzMC44TDE4LjgsNzJoNDMuNGwxMC45LTQxLjJMNTUuNyw1MC45eiBNNDAuNSw2Ni45bC0zLjYtNi40CglsMy42LTYuNGwzLjYsNi40TDQwLjUsNjYuOXoiLz4KPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSI0MC41LDExLjcgMzQuOSwzNS4yIDQwLjUsNDQuNyA0Ni4xLDM1LjIgIi8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0zMy42LDMzLjYiLz4KPHBhdGggY2xhc3M9InN0MSIgZD0iTTQ3LjQsMzMuNiIvPgo8Y2lyY2xlIGNsYXNzPSJzdDEiIGN4PSI0MC41IiBjeT0iMTAuNiIgcj0iNS40Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik00MS42LDcuMmMtMC44LTAuNC0xLjctMC42LTIuNi0wLjNjLTEuOCwwLjUtMi45LDIuNC0yLjQsNC4yYzAsMC4xLDAsMC4xLDAuMSwwLjJDMzkuNiwxMS42LDQyLDguNSw0MS42LDcuMnoiCgkvPgo8Y2lyY2xlIGNsYXNzPSJzdDEiIGN4PSI1OS41IiBjeT0iMTYiIHI9IjUuNCIvPgo8cGF0aCBjbGFzcz0ic3QyIiBkPSJNNjAuNiwxMi42Yy0wLjgtMC40LTEuNy0wLjYtMi42LTAuM2MtMS44LDAuNS0yLjksMi40LTIuNCw0LjJjMCwwLjEsMCwwLjEsMC4xLDAuMgoJQzU4LjYsMTYuOSw2MSwxMy45LDYwLjYsMTIuNnoiLz4KPGNpcmNsZSBjbGFzcz0ic3QxIiBjeD0iMjEuNSIgY3k9IjE2IiByPSI1LjQiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTIyLjYsMTIuNmMtMC44LTAuNC0xLjctMC42LTIuNi0wLjNjLTEuOCwwLjUtMi45LDIuNC0yLjQsNC4yYzAsMC4xLDAsMC4xLDAuMSwwLjIKCUMyMC42LDE2LjksMjMsMTMuOSwyMi42LDEyLjZ6Ii8+CjxjaXJjbGUgY2xhc3M9InN0MSIgY3g9IjczLjEiIGN5PSIzMS40IiByPSI1LjQiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTc0LjIsMjhjLTAuOC0wLjQtMS43LTAuNi0yLjYtMC4zYy0xLjgsMC41LTIuOSwyLjQtMi40LDQuMmMwLDAuMSwwLDAuMSwwLjEsMC4yQzcyLjIsMzIuMyw3NC42LDI5LjMsNzQuMiwyOHoKCSIvPgo8Y2lyY2xlIGNsYXNzPSJzdDEiIGN4PSI3LjkiIGN5PSIzMS40IiByPSI1LjQiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTksMjhjLTAuOC0wLjQtMS43LTAuNi0yLjYtMC4zQzQuNiwyOC4xLDMuNSwzMCw0LDMxLjhjMCwwLjEsMCwwLjEsMC4xLDAuMkM3LDMyLjMsOS40LDI5LjMsOSwyOHoiLz4KPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSI0MC41LDIwLjkgMzcuNCwzNC4zIDQwLjUsMzkuNiAiLz4KPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSI1Ni42LDU0LjcgNTguNCw2MC4zIDY4LDM4LjMgIi8+Cjxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iNDcuOSw1MC41IDU1LjksMjkuMyA0My42LDUwLjEgIi8+Cjxwb2x5Z29uIGNsYXNzPSJzdDIiIHBvaW50cz0iMzMuMyw1MC41IDI1LDI5LjEgMjguMSw1MSAiLz4KPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSIyMy4xLDU4LjcgMTIuNiw0MC45IDIwLjUsNjcuMyAiLz4KPC9zdmc+Cg=='); } -body.base .is2d piece.king.black { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDIyLjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCA4MSA4MSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgODEgODE7IiB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KCS5zdDB7ZmlsbDpub25lO30KCS5zdDF7ZmlsbDojMDEwMTAxO30KCS5zdDJ7ZmlsbDojNkQ2RTZFO30KPC9zdHlsZT4KPHJlY3QgY2xhc3M9InN0MCIgd2lkdGg9IjgxIiBoZWlnaHQ9IjgxIi8+CjxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik01OC42LDI1LjVjLTYuMiwwLTkuMywyLjYtMTAuOSw0LjJsLTcuMiwxMi42bC03LjItMTIuNmMtMS42LTEuNi00LjctNC4yLTEwLjktNC4yYy05LjcsMC0xNS4zLDgtMTUuMywxNS44CgljMCw4LjgsMy44LDExLjksOC45LDIyLjNWNzJoMjQuNUg2NXYtOC40YzUuMS0xMC41LDguOS0xMy41LDguOS0yMi4zQzczLjksMzMuNSw2OC4zLDI1LjUsNTguNiwyNS41eiBNNDAuNSw2MS42bC0zLjYtNi40bDMuNi02LjQKCWwzLjYsNi40TDQwLjUsNjEuNnoiLz4KPHBvbHlnb24gY2xhc3M9InN0MSIgcG9pbnRzPSI1MC43LDIxLjQgNTAuNywxMy43IDQyLjcsMTQuNiA0NC40LDcuMiAzNi42LDcuMiAzOC4zLDE0LjYgMzAuMywxMy43IDMwLjMsMjEuNCAzOC4zLDE5IDM1LjIsMjcuOSAKCTQwLjUsMzguOSA0NS44LDI3LjkgNDIuNywxOSAiLz4KPHBvbHlnb24gY2xhc3M9InN0MiIgcG9pbnRzPSI0MC41LDE5LjkgMzcuNiwyNy41IDQwLjUsMzMuOSAiLz4KPHBhdGggY2xhc3M9InN0MiIgZD0iTTIyLjgsMjkuMWMtNy4yLDAtMTEuNyw2LjQtMTEuNywxMi45YzAsNCwyLjksOC4yLDUuOCwxMmMwLTEyLjQsNC42LTE3LjQsMTIuNS0yMi42CglDMjkuNCwzMS40LDI3LjQsMjkuMSwyMi44LDI5LjF6Ii8+CjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik00My41LDQ0bDcuNC0xMi43YzAsMCwzLjYtMi42LDgtMi42czQuNSwwLjUsNC41LDAuNUw0My41LDQ0eiIvPgo8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjMxLjgsMTUuMSAzNS42LDE3LjQgMzEuOCwxOS43ICIvPgo8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjQ5LjIsMTUuMSA0Mi44LDE2LjMgNDcuNSwxNy40ICIvPgo8cG9seWdvbiBjbGFzcz0ic3QyIiBwb2ludHM9IjQyLjYsOC45IDQwLjUsMTAuOCAzOC40LDguOSAiLz4KPC9zdmc+Cg=='); } diff --git a/public/stylesheets/piece/leipzig.css b/public/stylesheets/piece/leipzig.css deleted file mode 100644 index b0af4d2b17..0000000000 --- a/public/stylesheets/piece/leipzig.css +++ /dev/null @@ -1,12 +0,0 @@ -body.base .is2d piece.pawn.white { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMTQ0cHQiCiAgIGhlaWdodD0iMTQ0cHQiCiAgIHZpZXdCb3g9IjAgMCA1MC44MDAwMDEgNTAuOCIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnOCIKICAgc29kaXBvZGk6ZG9jbmFtZT0id3Auc3ZnIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkyLjMgKDI0MDU1NDYsIDIwMTgtMDMtMTEpIj4KICA8ZGVmcwogICAgIGlkPSJkZWZzMiIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9ImJhc2UiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEuMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6em9vbT0iMTUuODM5MTkyIgogICAgIGlua3NjYXBlOmN4PSIxNTAuNzg1MTQiCiAgICAgaW5rc2NhcGU6Y3k9IjE3NC43NzE5NyIKICAgICBpbmtzY2FwZTpkb2N1bWVudC11bml0cz0ibW0iCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ibGF5ZXIxIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICB1bml0cz0icHQiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIzODQwIgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjIwMzUiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9Ii0xMyIKICAgICBpbmtzY2FwZTp3aW5kb3cteT0iLTEzIgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiIC8+CiAgPG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhNSI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGUgLz4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGcKICAgICBpbmtzY2FwZTpsYWJlbD0iTGF5ZXIgMSIKICAgICBpbmtzY2FwZTpncm91cG1vZGU9ImxheWVyIgogICAgIGlkPSJsYXllcjEiCiAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwtMjQ2LjIpIj4KICAgIDxnCiAgICAgICBhcmlhLWxhYmVsPSJwIgogICAgICAgc3R5bGU9ImZvbnQtc3R5bGU6bm9ybWFsO2ZvbnQtdmFyaWFudDpub3JtYWw7Zm9udC13ZWlnaHQ6bm9ybWFsO2ZvbnQtc3RyZXRjaDpub3JtYWw7Zm9udC1zaXplOjEwLjU4MzMzMzAycHg7bGluZS1oZWlnaHQ6MS4yNTtmb250LWZhbWlseTonQ2hlc3MgTGVpcHppZyc7LWlua3NjYXBlLWZvbnQtc3BlY2lmaWNhdGlvbjonQ2hlc3MgTGVpcHppZyc7bGV0dGVyLXNwYWNpbmc6MHB4O3dvcmQtc3BhY2luZzowcHg7ZmlsbDojMDAwMDAwO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDowLjI2NDU4MzMyIgogICAgICAgaWQ9InRleHQxMiIKICAgICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuMDAxMTUyLDAuMDc1ODUpIj4KICAgICAgPHBhdGgKICAgICAgICAgZD0ibSAyNS40MTI0MDIsMjkxLjk1MjIzIGggMTEuNDU5NzY2IHEgLTAuNzQ0MTQxLC0yLjk1MTc1IC0yLjg1MjUzOSwtNS4yMzM3OSAtMC44MTg1NTUsLTAuOTQyNTcgLTEuNTM3ODkxLC0xLjU2MjY5IC0yLjM4MTI1LC0xLjkzNDc3IC0zLjg5NDMzNiwtNC41NjQwNiAtMS41ODc1LDAuNTk1MzEgLTMuMTc1LDAuNTk1MzEgLTEuNjM3MTA5LDAgLTMuMTc1LC0wLjU5NTMxIC0xLjYxMjMwNCwyLjY3ODkgLTMuODk0MzM1LDQuNTY0MDYgLTAuNzQ0MTQxLDAuNjIwMTIgLTEuNTM3ODkxLDEuNTYyNjkgLTIuMTMzMjAzLDIuMjgyMDQgLTIuODUyNTM5LDUuMjMzNzkgeiBtIDAsLTEyLjQyNzE0IHEgMi44MDI5MywwIDQuNzg3MzA1LC0xLjk4NDM4IDEuOTg0Mzc1LC0xLjk4NDM3IDEuOTg0Mzc1LC00LjgxMjExIDAsLTIuMzA2ODMgLTEuNDM4NjcyLC00LjE0MjM4IC0xLjY2MTkxNCwtMi4xMzMyIC0yLjU1NDg4MywtNC41MTQ0NSAtMS40ODgyODEsLTAuMTk4NDQgLTIuNzc4MTI1LC0wLjE5ODQ0IC0xLjM2NDI1NywwIC0yLjc3ODEyNSwwLjE5ODQ0IC0xLjAxNjk5MiwyLjUzMDA3IC0yLjU3OTY4Nyw0LjUxNDQ1IC0xLjQzODY3MiwxLjgzNTU1IC0xLjQzODY3Miw0LjE0MjM4IDAsMi44Mjc3NCAxLjk4NDM3NSw0LjgxMjExIDEuOTg0Mzc1LDEuOTg0MzggNC44MTIxMDksMS45ODQzOCB6IG0gMCwtMjMuMTkyMzkgcSAyLjUzMDA3OCwwIDIuNTMwMDc4LC0yLjUzMDA3IDAsLTIuNTMwMDggLTIuNTMwMDc4LC0yLjUzMDA4IC0yLjUzMDA3OCwwIC0yLjUzMDA3OCwyLjUzMDA4IDAsMi41MzAwNyAyLjUzMDA3OCwyLjUzMDA3IHogbSAwLDUuODUzOTEgcSAxLjg4NTE1NywwIDMuMzQ4NjMzLDAuNDcxMjkgLTAuNTcwNTA4LC0xLjA0MTggLTEuMTkwNjI1LC0yLjMwNjg0IC0wLjU5NTMxMiwtMS4yODk4NCAtMC43Njg5NDUsLTIuNTU0ODggLTAuNjk0NTMxLDAuMTk4NDQgLTEuMzg5MDYzLDAuMTk4NDQgLTAuNzQ0MTQsMCAtMS40MTM4NjcsLTAuMTk4NDQgLTAuMTk4NDM3LDEuMjY1MDQgLTAuNzkzNzUsMi41NTQ4OCAtMC41OTUzMTIsMS4yNjUwNCAtMS4xNDEwMTUsMi4zMDY4NCAxLjk1OTU3LC0wLjQ3MTI5IDMuMzQ4NjMyLC0wLjQ3MTI5IHogbSAwLDMxLjQyNzU0IEggMTEuODkzODQ4IHEgMC40NzEyODksLTUuMzMzMDEgNC41MzkyNTgsLTkuMDA0MSAwLjY2OTcyNiwtMC42MjAxMiAwLjc0NDE0LC0wLjY2OTczIDIuMTA4Mzk5LC0xLjczNjMzIDMuNTk2NjgsLTQuMTQyMzggLTMuODE5OTIyLC0yLjUwNTI4IC0zLjgxOTkyMiwtNy4wNjkzNCAwLC0yLjgyNzczIDEuNzExNTIzLC01LjA4NDk2IDAuNTcwNTA4LC0wLjcxOTM0IDEuMjE1NDMsLTEuNjM3MTEgMC42Njk3MjcsLTAuOTE3NzcgMS4wNjY2MDIsLTEuNzg1OTQgLTAuNTk1MzEzLDAuMTQ4ODMgLTEuODEwNzQyLDAuNDcxMjkgLTEuMTkwNjI1LDAuMzIyNDYgLTEuNzYxMTMzLDAuNTQ1NzEgMS43MTE1MjMsLTEuNTg3NSAzLjI0OTQxNCwtMy43NzAzMiAxLjU2MjY5NSwtMi4xODI4MSAxLjgzNTU0NywtNC42Mzg0NyAtMS4yNjUwMzksLTEuMjg5ODUgLTEuMjY1MDM5LC0zLjAyNjE3IDAsLTEuNzM2MzMgMS4yMTU0MjksLTIuOTc2NTcgMS4yNDAyMzUsLTEuMjQwMjMgMy4wMDEzNjcsLTEuMjQwMjMgMS43MTE1MjQsMCAyLjk1MTc1OCwxLjI0MDIzIDEuMjQwMjM0LDEuMjQwMjQgMS4yNDAyMzQsMi45NzY1NyAwLDEuNzYxMTMgLTEuMjY1MDM5LDMuMDI2MTcgMC4yNzI4NTIsMi40NTU2NiAxLjgzNTU0Nyw0LjYzODQ3IDEuNTg3NSwyLjE4MjgyIDMuMjk5MDI0LDMuNzcwMzIgLTAuNTcwNTA4LC0wLjIyMzI1IC0xLjgxMDc0MiwtMC41NDU3MSAtMS4yMTU0MywtMC4zMjI0NiAtMS44MTA3NDMsLTAuNDcxMjkgMC4zOTY4NzUsMC44NjgxNyAxLjA0MTc5NywxLjc4NTk0IDAuNjY5NzI3LDAuOTE3NzcgMS4yNjUwMzksMS42MzcxMSAxLjcxMTUyNCwyLjI1NzIzIDEuNzExNTI0LDUuMDg0OTYgMCw0LjU2NDA2IC0zLjgxOTkyMiw3LjA2OTM0IDEuNDEzODY3LDIuMzgxMjUgMy41NzE4NzUsNC4xNDIzOCAwLjM3MjA3LDAuMjk3NjYgMC43NDQxNCwwLjY2OTczIDQuMDkyNzc0LDMuNjcxMDkgNC41MzkyNTgsOS4wMDQxIHoiCiAgICAgICAgIHN0eWxlPSJmb250LXNpemU6NTAuNzk5OTk5MjRweDtzdHJva2Utd2lkdGg6MC4yNjQ1ODMzMiIKICAgICAgICAgaWQ9InBhdGgxNCIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDwvZz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjE4ODk4ODEiCiAgICAgICBkPSJtIDE0LjE5NDY2NCwyOTEuNDgyMjYgYyAwLjA2OTU5LC0wLjI4NTg0IDAuNDM4NzcyLC0xLjE1NzU1IDAuODIwNDA1LC0xLjkzNzEzIDAuNTczODcsLTEuMTcyMjcgMS4xNTM5OTIsLTEuODkxMzUgMy4zNTQyNjQsLTQuMTU3NzQgMS40NjMyMTQsLTEuNTA3MTcgMi45NDA2MDQsLTMuMTUxMjcgMy4yODMwOSwtMy42NTM1NCAwLjU1MDYwMSwtMC44MDc0OCAwLjY4MDU5LC0wLjg5ODU0IDEuMTIyNjU3LC0wLjc4NjM5IDEuOTI1Nzk5LDAuNDg4NTQgMy40MTYxNywwLjQ4OTg3IDUuMzI3NjAyLDAuMDA1IDAuNDI0NDQ1LC0wLjEwNzcyIDAuNTU2Nzg0LC0wLjAwNCAxLjEyNjg5LDAuODgwODggMC4zNTUyODIsMC41NTE2MiAxLjY3NTY1OSwyLjAyMzQ4IDIuOTM0MTY4LDMuMjcwOCAyLjgyNDIzOSwyLjc5OTEzIDMuODM4MjE4LDQuMjUwNCA0LjQ0Mjk3Myw2LjM1OTA2IGwgMC4xNTQ1ODYsMC41MzkgSCAyNS40MTQ3MTcgMTQuMDY4MTM2IFoiCiAgICAgICBpZD0icGF0aDE3IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjE4ODk4ODEiCiAgICAgICBkPSJtIDIzLjQ4NzQ1NSwyNzkuMjMxNzIgYyAtMS44NzY3NTQsLTAuNjAxMyAtMy4zNzc1ODMsLTEuOTU5OTYgLTQuMjM5NjI0LC0zLjgzODAxIC0wLjM5NjA3NCwtMC44NjI5IC0wLjQ4NzAyNywtMS4zNDU3MSAtMC40ODQ4OTcsLTIuNTc0MDIgMC4wMDMxLC0xLjgxMDIxIDAuMjQ5NzQ0LC0yLjQzMjM5IDEuOTkwOTQ4LC01LjAyMzEyIDAuNjY5MTgzLC0wLjk5NTY4IDEuMzY0MTM1LC0yLjE5NjM4IDEuNTQ0MzM3LC0yLjY2ODIzIDAuMzA5OTg0LC0wLjgxMTY4IDAuMzc0NTY0LC0wLjg2NDM1IDEuMTk4MzIzLC0wLjk3NzI2IDEuMTA4NDY1LC0wLjE1MTkzIDIuOTcwMjM1LC0wLjE0OTg5IDMuOTAzMzMzLDAuMDA0IDAuNjUzMDM0LDAuMTA3OSAwLjc2NTcwMiwwLjIxNTkgMS4xNjM0NSwxLjExNTI5IDAuMjQyMjIsMC41NDc3IDEuMDAyOTI3LDEuODI1NDIgMS42OTA0NiwyLjgzOTM5IDEuNDY3ODgxLDIuMTY0ODEgMS44Nzk4ODUsMy4zNjMwMiAxLjc3Nzc2OSw1LjE3MDIgLTAuMTM3NTE5LDIuNDMzNzkgLTEuNjA4OTIzLDQuNTYwNTEgLTMuODkxOTYsNS42MjUzMiAtMS4yODQ4OCwwLjU5OTI3IC0zLjM0ODE5MSwwLjc0MzkyIC00LjY1MjEzOSwwLjMyNjE1IHoiCiAgICAgICBpZD0icGF0aDE5IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAxNjcwNDM1IgogICAgICAgZD0ibSAyMi4zMzk1ODgsMjYyLjIxNzExIGMgMC4yNTUwMSwtMC40OTg3NSAwLjY4Njg5OSwtMS4zODM5MyAwLjg4MzAwMywtMS44MDk3NSAwLjM2NDIxNiwtMC43OTA4NyAwLjY1MjEwNiwtMS43MDY1NCAwLjc3MjE5OSwtMi40NTYwOSBsIDAuMDEwNzksLTAuMDY3NCAwLjE3ODcxNiwwLjA0NDkgYyAwLjc3NjMwNiwwLjE5NDk1IDEuNjEwMDU4LDAuMTk2MzYgMi40MTQ5MTgsMC4wMDQgMC4xOTA1NzcsLTAuMDQ1NSAwLjIxMDA2NCwtMC4wNDI3IDAuMjEwNzMsMC4wMzA0IDEuMzVlLTQsMC4wMTU1IDAuMDE5MzIsMC4xMzE5OCAwLjA0MjU5LDAuMjU4OTIgMC4xNTc0OTksMC44NTg1OCAwLjQyNTk0NSwxLjYzNDg5IDAuODg1NjA4LDIuNTYxMDUgMC4yOTE4MTIsMC41ODc5NyAwLjgxNDIzNywxLjU5MjQ0IDAuOTcyMjU3LDEuODY5MzYgMC4wMzczNiwwLjA2NTUgMC4wMzg1MywwLjA3MjMgMC4wMTA1MywwLjA2MTMgLTAuMTg0MTIxLC0wLjA3MjIgLTAuODI3NDM2LC0wLjIyNTU5IC0xLjIyOTE2MSwtMC4yOTMxMSAtMS4xOTI2NTIsLTAuMjAwNDYgLTIuNDAxNzYsLTAuMjE3MzEgLTMuNTg4MTI4LC0wLjA1IC0wLjUzNTAwNSwwLjA3NTQgLTEuNTA1OTMyLDAuMjYxOTkgLTEuNzkyNzQ5LDAuMzQ0NDIgLTAuMDIxODcsMC4wMDYgMC4wNDI1NCwtMC4xMzM5OCAwLjIyODY5MSwtMC40OTgwNyB6IgogICAgICAgaWQ9InBhdGgyMSIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMTY3MDQzNSIKICAgICAgIGQ9Im0gMjUuMDg5NjU1LDI1Ni4zOTAzMiBjIC0xLjI0NTc5OCwtMC4wOTggLTEuOTQ5MjAzLC0wLjcwMjA2IC0yLjE0NTczNCwtMS44NDI2NyAtMC4wNjg0NCwtMC4zOTcyMSAtMC4wNjUxNSwtMC45NzM2OSAwLjAwNzksLTEuMzc5MjMgMC4xMzExNDUsLTAuNzI4MzIgMC40OTEzMiwtMS4yNDY1NCAxLjA2MzAzMywtMS41Mjk0OCAwLjI2OTM0OSwtMC4xMzMzIDAuNTg2MTM0LC0wLjIyMDI2IDAuOTQ0NzA2LC0wLjI1OTMxIDAuMjA4NjA3LC0wLjAyMjcgMC43MDMwOTcsLTAuMDIyNyAwLjkxMTcwNCwwIDEuMjI5MjIxLDAuMTMzODkgMS45MDY1ODYsMC44MTEyNiAyLjA0MDQ4NCwyLjA0MDQ4IDAuMDIyNzMsMC4yMDg2MSAwLjAyMjczLDAuNzAzMSAwLDAuOTExNyAtMC4wODQ3MiwwLjc3Nzc1IC0wLjM4MDk1MywxLjMzMDUyIC0wLjg5MjcxOCwxLjY2NTgxIC0wLjE3NTc0MSwwLjExNTE0IC0wLjI2Nzk2NCwwLjE2MDQxIC0wLjQ3MDEzNSwwLjIzMDc4IC0wLjM5NDc2NiwwLjEzNzQxIC0wLjk2NTU3OSwwLjIwMDc1IC0xLjQ1OTIxNywwLjE2MTkyIHoiCiAgICAgICBpZD0icGF0aDIzIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICA8L2c+Cjwvc3ZnPgo='); } -body.base .is2d piece.knight.white { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMTQ0cHQiCiAgIGhlaWdodD0iMTQ0cHQiCiAgIHZpZXdCb3g9IjAgMCA1MC44MDAwMDEgNTAuOCIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnOCIKICAgc29kaXBvZGk6ZG9jbmFtZT0id24uc3ZnIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkyLjMgKDI0MDU1NDYsIDIwMTgtMDMtMTEpIj4KICA8ZGVmcwogICAgIGlkPSJkZWZzMiIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9ImJhc2UiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEuMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6em9vbT0iNy45MTk1OTU5IgogICAgIGlua3NjYXBlOmN4PSIzNC41NDI0NjUiCiAgICAgaW5rc2NhcGU6Y3k9Ijk1LjkwOTI4MiIKICAgICBpbmtzY2FwZTpkb2N1bWVudC11bml0cz0ibW0iCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ibGF5ZXIxIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICB1bml0cz0icHQiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIzODQwIgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjIwMzUiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9Ii0xMyIKICAgICBpbmtzY2FwZTp3aW5kb3cteT0iLTEzIgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiIC8+CiAgPG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhNSI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGUgLz4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGcKICAgICBpbmtzY2FwZTpsYWJlbD0iTGF5ZXIgMSIKICAgICBpbmtzY2FwZTpncm91cG1vZGU9ImxheWVyIgogICAgIGlkPSJsYXllcjEiCiAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwtMjQ2LjIpIj4KICAgIDxnCiAgICAgICBhcmlhLWxhYmVsPSJuIgogICAgICAgc3R5bGU9ImZvbnQtc3R5bGU6bm9ybWFsO2ZvbnQtdmFyaWFudDpub3JtYWw7Zm9udC13ZWlnaHQ6bm9ybWFsO2ZvbnQtc3RyZXRjaDpub3JtYWw7Zm9udC1zaXplOjUwLjc5OTk5OTI0cHg7bGluZS1oZWlnaHQ6MS4yNTtmb250LWZhbWlseTonQ2hlc3MgTGVpcHppZyc7LWlua3NjYXBlLWZvbnQtc3BlY2lmaWNhdGlvbjonQ2hlc3MgTGVpcHppZyc7bGV0dGVyLXNwYWNpbmc6MHB4O3dvcmQtc3BhY2luZzowcHg7ZmlsbDojMDAwMDAwO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDowLjI2NDU4MzMyIgogICAgICAgaWQ9InRleHQ5MiIKICAgICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuMTgzMzk1MjMsMS41NjU5NikiPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDkuNzY3NTc1NSwyNzQuMzczNjkgcSAtMC4xOTg0Mzc1LDAuMjQ4MDQgLTAuNTIwODk4NCwwLjQ3MTI5IC0wLjY5NDUzMTMsMC41MjA5IC0wLjk5MjE4NzUsLTAuMDk5MiAtMC4xNzM2MzI4LC0wLjI5NzY2IDAuMDI0ODA1LC0wLjkxNzc4IDAuMzQ3MjY1NiwtMC4yOTc2NSAwLjQ3MTI4OSwtMC4zOTY4NyAwLjc2ODk0NTMsLTAuOTE3NzcgMS4yNjUwMzg0LC0xLjYxMjMgMC4yNDgwNDcsLTAuMDQ5NiAwLjM3MjA3MSwtMC4wMjQ4IDAuODY4MTY0LDAuMTQ4ODMgMC40NDY0ODQsMS4wNjY2IC0wLjIyMzI0MiwwLjQ0NjQ5IC0wLjU0NTcwMywwLjgxODU2IC0wLjI5NzY1NiwwLjM0NzI2IC0wLjUyMDg5ODIsMC42OTQ1MyB6IG0gNy4zNDIxODc1LC0xMS4wMTMyOCBxIDAuNDk2MDk0LC0xLjUzNzg5IDEuODg1MTU2LC0xLjY2MTkyIDAuOTQyNTc4LC0wLjA3NDQgMS42MzcxMDksLTAuMDc0NCAwLjY5NDUzMiwwIDEuNDg4MjgyLC0wLjI0ODA1IC0wLjc5Mzc1LDIuMjMyNDIgLTEuODEwNzQyLDIuOTAyMTUgLTAuNTQ1NzA0LDAuMzIyNDYgLTEuNTEzMDg2LDAuMzk2ODggLTAuNzE5MzM2LDAuMDQ5NiAtMS4xMTYyMTEsLTAuMDk5MiAtMC4zOTY4NzUsLTAuMTQ4ODMgLTAuNTcwNTA4LC0xLjIxNTQzIHogbSAtMS42MzcxMDksMTMuMTk2MDkgcSAxLjE5MDYyNSwtMC44NDMzNiAxLjY4NjcxOCwtMS43NjExMyAwLjUyMDg5OSwtMC45NDI1OCAxLjQxMzg2NywtMS43ODU5NCAwLjAyNDgxLC0wLjI5NzY2IDAuMDc0NDEsLTAuNjY5NzMgMC4wNDk2MSwtMC4zNzIwNyAwLjA5OTIyLC0wLjc5Mzc1IDAuMTczNjMzLC0wLjE3MzYzIDAuMjcyODUyLC0wLjE5ODQzIDAuNzE5MzM2LC0wLjIyMzI1IDAuODQzMzU5LDAuNjQ0OTIgMCwwLjI0ODA0IC0wLjA0OTYxLDAuNDk2MDkgLTAuMDI0ODEsMC4yMjMyNCAwLjAyNDgsMC4zOTY4OCAwLjE0ODgyOSwwLjE3MzYzIDEuMTE2MjExLDAuMzcyMDcgMy41NzE4NzUsMC4xMjQwMiA2LjU3MzI0MiwtMi42Nzg5MSAwLC0wLjAyNDggMC4xNDg4MjksLTAuMjIzMjQgMC4xNzM2MzIsLTAuMTk4NDQgMC4xOTg0MzcsLTAuMjQ4MDUgMC43NDQxNDEsLTEuMTE2MjEgMS4xOTA2MjUsLTQuNjM4NDcgMC4wNDk2MSwtMC4wOTkyIDAuMjcyODUyLC0wLjIyMzI1IDAuNjQ0OTIyLC0wLjIyMzI0IDAuODE4NTU0LDAuNjQ0OTMgLTAuMjIzMjQyLDMuMTk5OCAtMC45NjczODIsNC41NjQwNiAtMC4zOTY4NzUsMC43MTkzMyAtMC44OTI5NjksMS4yNjUwNCAwLjQyMTY3OSwtMC4yMjMyNSAwLjg0MzM1OSwtMC40MjE2OCAwLjQyMTY4LC0wLjE5ODQ0IDAuODE4NTU1LC0wLjQ0NjQ5IDEuMjY1MDM5LC0wLjc2ODk0IDEuODEwNzQyLC0yLjk3NjU2IDAuMjcyODUyLC0wLjQ3MTI5IDAuNzkzNzUsLTAuNDIxNjggMC41NDU3MDMsMC4wOTkyIDAuNDIxNjgsMC44MTg1NiAtMC41NzA1MDgsMy4xMDA1OCAtMi40MzA4Niw0LjAxODM1IC0wLjU5NTMxMiwwLjI5NzY2IC0xLjIxNTQyOSwwLjU0NTcxIC0wLjU5NTMxMywwLjIyMzI0IC0xLjE2NTgyMSwwLjQ0NjQ4IDEuNDYzNDc3LC0wLjA3NDQgMy4xNzUsLTAuNDcxMjkgMC4zMjI0NjEsMCAwLjQ0NjQ4NSwwLjI3Mjg1IDAuMjIzMjQyLDAuNDk2MSAtMC40NzEyODksMC44OTI5NyAtMy40OTc0NjEsMC45NjczOSAtNC40NDAwMzksMC44NjgxNyAtMC42Njk3MjcsMi4xMDg0IC0zLjI3NDIxOSw0LjYzODQ3IC0xLjQzODY3MiwxLjM4OTA3IC0yLjk3NjU2MywyLjcwMzcxIC0xLjUzNzg5LDEuMjg5ODUgLTMuMDI2MTcxLDIuNTc5NjkgLTMuMjk5MDI0LDIuOTAyMTUgLTQuMDE4MzYsNS42NTU0NyA1LjY4MDI3NCwwLjAyNDggOS40MjU3ODEsMC4wMjQ4IDMuNzcwMzEzLDAgNi45MjA1MDgsMCAzLjE1MDE5NSwwIDYuMzUsMCAzLjE5OTgwNSwtMC4wMjQ4IDcuNzg4NjcyLC0wLjAyNDggMC4zNDcyNjUsMCAwLjI3Mjg1MSwtMS4yNDAyMyAtMC4wNDk2MSwtMS4yNDAyNCAtMC4xNzM2MzIsLTIuMzA2ODQgLTEuMzM5NDU0LDAuMTQ4ODMgLTIuNTMwMDc5LC0xLjM4OTA2IC0xLjE5MDYyNSwtMS41NjI3IC0xLjA5MTQwNiwtMy41NzE4OCAwLjAyNDgxLC01LjIwODk4IC0wLjY2OTcyNiwtOS4zNzYxNyAtMC42Njk3MjcsLTQuMTkxOTkgLTIuNjc4OTA3LC03LjI2Nzc3IC0zLjI3NDIxOCwtNC45NjA5NCAtMTAuMzkzMTYzLC04LjQzMzYgLTAuMDk5MjIsMC42MjAxMiAtMC4yMjMyNDMsMS4xNDEwMiAtMC4xOTg0MzcsMC43OTM3NSAtMC43NDQxNCwwLjUyMDkgLTAuNTIwODk5LC0wLjE3MzYzIC0wLjU0NTcwMywtMC42Njk3MyAwLjA5OTIyLC0wLjQ0NjQ4IDAuMTI0MDIzLC0wLjY2OTcyIC0wLjAyNDgxLC0wLjA3NDQgLTAuMDQ5NjEsLTAuMTczNjQgLTAuMDI0ODEsLTAuMTI0MDIgLTAuMDI0ODEsLTAuMjIzMjQgLTAuMjQ4MDQ3LC0xLjI4OTg0IC0xLjQxMzg2NywtMi45MjY5NSAtMC4xOTg0MzgsMS4wNDE3OSAtMC4zOTY4NzUsMS40MTM4NiAtMC4xOTg0MzgsMC4zNzIwNyAtMC4zNDcyNjYsMC42NDQ5MyAtMC4yNzI4NTEsMC4zOTY4NyAtMC40OTYwOTQsMC43Njg5NCAtMC4xOTg0MzcsMC4zNzIwNyAtMC40NzEyODksMC44MTg1NiAtMC4yNzI4NTEsLTAuMjk3NjYgLTAuNTk1MzEyLC0wLjY5NDU0IC0wLjI5NzY1NiwtMC40MjE2NyAtMC41NDU3MDMsLTAuNzE5MzMgLTAuMjIzMjQyLC0wLjIyMzI0IC0wLjQ0NjQ4NSwtMC40MjE2OCAtMC4xOTg0MzcsLTAuMjIzMjQgLTAuNzkzNzUsLTAuMzcyMDcgMC41MjA4OTksMS45MzQ3NiAtMC4yNzI4NTEsMi42NTQxIC0wLjM5Njg3NSwwLjM5Njg4IC0wLjg2ODE2NCwxLjA2NjYgLTAuNDcxMjg5LDAuNjQ0OTIgLTEuMDY2NjAyLDEuMTkwNjMgLTAuMzQ3MjY1LDAuMzcyMDcgLTAuODY4MTY0LDAuODY4MTYgLTAuNDk2MDkzLDAuNDcxMjkgLTAuODQzMzU5LDEuMjQwMjQgLTAuNDcxMjg5LDEuNDM4NjcgLTEuODYwMzUyLDIuOTAyMTQgLTEuMzY0MjU3LDEuNDM4NjggLTMuMDAxMzY3LDIuOTAyMTUgLTMuNTcxODc0NywzLjE3NSAtNC4wNDMxNjM4LDQuNjEzNjcgLTAuNjQ0OTIxOCwxLjczNjMzIDAuMDc0NDE0LDMuMzczNDQgMC42Njk3MjY1LDEuNDYzNDggMS44MzU1NDY4LDEuOTA5OTYgMC42OTQ1MzEzLDAuMjcyODUgMS43MTE1MjQsLTEuMDQxNzkgMS4wOTE0MDYsLTEuMzE0NjUgMS40Mzg2NzEsLTEuMjE1NDMgMC42NDQ5MjIsMC4xNzM2MyAwLjQyMTY4LDAuOTE3NzcgLTAuMTI0MDIzLDAuNDIxNjggLTAuNzkzNzUsMS4yMTU0MyAtMC42OTQ1MzEsMC43Njg5NCAtMC43MTkzMzYsMS4wMTY5OSAtMC4xMjQwMjMsMC4yOTc2NiAwLjQ5NjA5NCwwLjQ3MTI5IDAuNzY4OTQ1LDAuMTk4NDQgMi44NzczNDQsLTEuODYwMzUgMC4yNDgwNDYsLTAuMjQ4MDUgMC41MjA4OTgsLTAuNDQ2NDkgMC4yOTc2NTYsLTAuMjIzMjQgMC41OTUzMTMsLTAuNDk2MDkgeiBtIDAuODE4NTU0LDEuMTkwNjMgcSAtMC4zNDcyNjUsMC4zNzIwNyAtMC41NzA1MDgsMC41NDU3IC0wLjE5ODQzNywwLjE0ODgzIC0wLjM3MjA3LDAuMjk3NjUgLTAuMjIzMjQyLDAuMTk4NDQgLTEuNTg3NSwxLjYzNzExIC0wLjU3MDUwOCwwLjU5NTMyIC0xLjM2NDI1OCwwLjc5Mzc1IC0wLjU3MDUwNywwLjE0ODgzIC0xLjQ2MzQ3NiwtMC4xMjQwMiAtMy4xMDA1ODYxLC0wLjgxODU1IC00Ljg4NjUyMzYsLTMuMjc0MjIgLTAuNzE5MzM1OSwtMC45MTc3NyAtMS4wMTY5OTIxLC0yLjIwNzYyIC0wLjI3Mjg1MTYsLTEuMzE0NjQgMC4yOTc2NTYyLC0zLjMyMzgyIDAuNTQ1NzAzMSwtMi4wNTg3OSAzLjkxOTE0MDYsLTQuNjM4NDggMy42OTU4OTc5LC0yLjgwMjkzIDQuMzY1NjI0OSwtNC40ODk2NSAwLjU0NTcwMywtMC45NjczOCAxLjI0MDIzNCwtMi4xMzMyIDAuNjk0NTMyLC0xLjE2NTgyIDEuNjYxOTE0LC0yLjI1NzIzIDAuNTk1MzEzLC0wLjQyMTY4IDEuMTE2MjExLC0wLjk2NzM4IDAuNTQ1NzAzLC0wLjU3MDUxIDEuMDkxNDA3LC0xLjE2NTgyIHYgLTMuMDUwOTggcSAxLjM4OTA2MiwwLjI3Mjg1IDEuOTg0Mzc1LDAuNzkzNzUgMC4yOTc2NTYsMC4zMjI0NiAwLjY2OTcyNiwwLjU5NTMyIDAuMzcyMDcsMC4yNzI4NSAwLjY2OTcyNywwLjU5NTMxIDAuNjIwMTE3LC0xLjExNjIxIDAuNzkzNzUsLTEuODYwMzUgMC4wMjQ4LC0wLjE3MzY0IDAuMTQ4ODI4LC0wLjY5NDU0IDAuMTQ4ODI4LC0wLjUyMDg5IDAuMjk3NjU2LC0xLjcxMTUyIDAuMzcyMDcsLTAuMDc0NCAwLjY0NDkyMiwwLjE5ODQ0IDEuMTY1ODIsMS4yNjUwNCAyLjE4MjgxMiwyLjg3NzM0IDQuNTM5MjU4LDEuODEwNzQgOC4yODQ3NjYsNC4yOTEyMSAzLjc3MDMxMiwyLjQ4MDQ3IDUuNzU0Njg3LDUuMTU5MzggNS43MDUwNzgsNy43MzkwNiA1LjcwNTA3OCwyMi43MjEwOSAwLDMuMTUwMiAtMC4zMjI0NjEsNS43NTQ2OSBIIDExLjY3NzUzNiBxIC0wLjMyMjQ2MSwtMy4yMjQ2MSAzLjQyMzA0NywtNi44NDYwOSAxLjY4NjcxOSwtMS42MzcxMSAzLjQ5NzQ2MSwtMy4xNzUgMS44MzU1NDcsLTEuNTM3ODkgMy41NzE4NzUsLTMuMTI1MzkgMy4yMjQ2MDksLTIuOTc2NTcgMy41NzE4NzUsLTQuNzYyNSAtMC4xMjQwMjMsLTAuMjk3NjYgLTAuNDcxMjg5LC0wLjM5Njg4IC0wLjg2ODE2NCwwLjUyMDkgLTEuNzM2MzI4LDAuNjY5NzMgLTAuODY4MTY0LDAuMTQ4ODIgLTEuNzExNTI0LDAuMTk4NDMgLTAuNTQ1NzAzLDAuMDI0OCAtMS4wOTE0MDYsMC4wNDk2IC0wLjUyMDg5OCwwIC0xLjI0MDIzNCwtMC4yNDgwNCAtMC45NjczODMsMS4wOTE0IC0xLjY2MTkxNCwxLjg4NTE1IC0wLjY2OTcyNywwLjc2ODk1IC0xLjUzNzg5MSwxLjM4OTA3IHoiCiAgICAgICAgIHN0eWxlPSJzdHJva2Utd2lkdGg6MC4yNjQ1ODMzMiIKICAgICAgICAgaWQ9InBhdGg5NCIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDwvZz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAxMy43ODYxNTcsMjkxLjk3MzE5IGMgMCwtMC4wMDcgMC4wNTc2MSwtMC4xODM1MiAwLjEyODAzLC0wLjM5MjU1IDAuNDg1NDg5LC0xLjQ0MTEzIDEuMzg1MzMyLC0yLjc3NzU2IDIuODc4MjA4LC00LjI3NDYzIDAuNjUzMDc3LC0wLjY1NDkyIDEuMDc1ODU2LC0xLjAyNjc1IDMuOTI3OTIzLC0zLjQ1NDU5IDEuNzkyODYyLC0xLjUyNjE4IDMuNTgwMDIsLTMuMjI0NyA0LjM3OTAxNSwtNC4xNjE4MyAwLjg4MDgzNSwtMS4wMzMxMSAxLjU2NDk2MSwtMi4xMjAyNSAxLjg4MDU1NCwtMi45ODgzNyAwLjA4NTI0LC0wLjIzNDQ3IDAuMTA2NzQxLC0wLjI2NjY0IDAuMTc1MjE1LC0wLjI2MjEzIDAuMTQ3MDQ3LDAuMDEgMC43Nzk1NzEsLTAuMDU3MyAxLjE3NjU5MSwtMC4xMjQ2NyAwLjU1NDM1LC0wLjA5NCAxLjQ2NzEyLC0wLjMwMjYgMi4zOTg5NTYsLTAuNTQ4MjYgMC44NzAxMjcsLTAuMjI5MzkgMS4wMTM2MTYsLTAuMjk3OTkgMS4yMTExNTksLTAuNTc5MDMgMC4yMTg2ODEsLTAuMzExMTEgMC4wNjY4LC0wLjczMiAtMC4yOTA1MTcsLTAuODA1MDggLTAuMDY5NjUsLTAuMDE0MiAtMC4zMTc0NjYsMC4wMjE0IC0wLjcwOTA5NywwLjEwMjExIC0wLjgyNDczOCwwLjE2OTg5IC0xLjk3NjIzMSwwLjMzMTkxIC0yLjMzNDQ3MiwwLjMyODQ2IC0wLjA3MTMzLC03LjllLTQgMC4wOTg2OCwtMC4wNzk4IDAuNTI5NzI4LC0wLjI0NjQ2IDAuOTkzMjcyLC0wLjM4NDA4IDEuNjMzMjQ2LC0wLjY4MTI4IDEuOTkzNDEzLC0wLjkyNTcxIDAuOTA0NDQ5LC0wLjYxMzgzIDEuNTEyNDE5LC0xLjYxNDA5IDEuOTA1MTAxLC0zLjEzNDM2IDAuMTY1NzgsLTAuNjQxODIgMC4yMDAwNzUsLTEuMDU3NiAwLjEwMjEzOSwtMS4yMzgzIC0wLjEzNjU5OSwtMC4yNTIwNSAtMC41MTAzNywtMC4zMzYxOSAtMC44MzA3MzgsLTAuMTg3MDIgLTAuMjM5NTQxLDAuMTExNTQgLTAuMzMyODMsMC4yNTIwNCAtMC40NjY3NTQsMC43MDMgLTAuMzc5OTM3LDEuMjc5MzIgLTAuOTA0MjU2LDIuMDg4OTQgLTEuNjgyODE0LDIuNTk4NDkgLTAuMjU1OTU1LDAuMTY3NTIgLTEuNTAwNjQsMC44MDk2MSAtMS41MjQwNDUsMC43ODYyMSAtMC4wMDcyLC0wLjAwNyAwLjA3ODA0LC0wLjEzMTg3IDAuMTg5Mzc2LC0wLjI3NzA4IDAuMjU4NzEyLC0wLjMzNzQyIDAuNTQ1NywtMC44MDA5OCAwLjY4NTM4NCwtMS4xMDcwOCAwLjMzNDYyNywtMC43MzMyOSAwLjU4OTcyNywtMS44NDAzOSAwLjc0OTIyMSwtMy4yNTE1MSAwLjEwMDM3NSwtMC44ODgwNyAwLjEwMTMyMiwtMS4xNzYzNCAwLjAwNDYsLTEuMzkwODkgLTAuMTE2MzA1LC0wLjI1NzkgLTAuMjMzNzc4LC0wLjM1NDMyIC0wLjQ1Mzg5OCwtMC4zNzI1OCAtMC4yMDY1MzEsLTAuMDE3MSAtMC40NTU0NTQsMC4wNzgzIC0wLjUzNTczOSwwLjIwNTQzIC0wLjAyNDc5LDAuMDM5MiAtMC4wNzA2NCwwLjI2Njc5IC0wLjEwMTkwNCwwLjUwNTY2IC0wLjA3ODU3LDAuNjAwNCAtMC4yMzIyNjIsMS40ODAxNiAtMC4zNTI4MzUsMi4wMTk3NCAtMC4yNTUwMjcsMS4xNDEzMSAtMC41Mzc2MzMsMS44NjggLTAuOTE2OCwyLjM1NzQ3IC0wLjIyNzY0NSwwLjI5Mzg3IC0wLjMyMjczNiwwLjM4OTYxIC0wLjcyODMwMywwLjczMzI2IC0xLjEyMDUyLDAuOTQ5NDYgLTIuMzk2NjA1LDEuNjI3NSAtMy42ODE0NDIsMS45NTYxIC0wLjYzNDcxMSwwLjE2MjMzIC0xLjEyODYzMiwwLjIzMjEgLTEuODA0MDY5LDAuMjU0ODEgLTAuNTE0NzU5LDAuMDE3MyAtMC41NDg5MjMsMC4wMTQzIC0wLjkyMzIzNiwtMC4wODIgLTAuMjEzNzgzLC0wLjA1NSAtMC40NTgxNDYsLTAuMTMwNzUgLTAuNTQzMDI3LC0wLjE2ODMgLTAuMjE2NTg2LC0wLjA5NTggLTAuMjM3NzQ5LC0wLjE2NjM2IC0wLjE4NjkyNCwtMC42MjMxNSAwLjAzMjI1LC0wLjI4OTg3IDAuMDMyMjUsLTAuMzk5MjEgLTEuOGUtNSwtMC41MTc2NSAtMC4xMjc1NCwtMC40NjgxNSAtMC4zNzkwOTcsLTAuNjM3NjQgLTAuNzc1Mzg5LC0wLjUyMjQzIC0wLjMyMTM5OSwwLjA5MzQgLTAuMzQwNTY0LDAuMTM0MjEgLTAuNDI2MDAyLDAuOTA2NDUgLTAuMDQwNjYsMC4zNjc0OSAtMC4wOTE1MywwLjcwMDQ4IC0wLjExMzA1NiwwLjczOTk3IC0wLjAyMTUyLDAuMDM5NSAtMC4yMDE5ODcsMC4yNTEyNiAtMC40MDEwMzMsMC40NzA2IC0wLjQwNTYyNCwwLjQ0Njk3IC0wLjY3MTM5MywwLjgwNDYzIC0wLjk0ODI5OSwxLjI3NjE3IC0wLjQ2MjQ1MywwLjc4NzUxIC0wLjY5MjI4MywxLjAxODIxIC0yLjI3ODAwNSwyLjI4NjU2IC0wLjE1Nzk2MSwwLjEyNjM0IC0wLjUzNTI2MSwwLjQ2MDUzIC0wLjgzODQ0NSwwLjc0MjYzIC0wLjk1MzkyMiwwLjg4NzU4IC0xLjYyMDIxOSwxLjM3NTkxIC0yLjEwMDk1OSwxLjUzOTc4IC0wLjI2NTEsMC4wOTA0IC0wLjM3NjMxMSwwLjA5NDUgLTAuNTk5NjU5LDAuMDIyNCAtMC4yNDEwNjIsLTAuMDc3OSAtMC4zODQyOTUsLTAuMjA1NzQgLTAuMzgwNDg2LC0wLjMzOTcyIDAuMDA0NCwtMC4xNTUyMiAwLjE1MTcxNywtMC40MDIzMyAwLjQ1NjU0NiwtMC43NjU4OCAwLjY0NDQwNCwtMC43Njg1NCAwLjg1Mzg4NywtMS4wNTc3MiAxLjAwNDQzNywtMS4zODY1NyAwLjEwMTUxMywtMC4yMjE3MyAwLjE0MDIxNCwtMC41MzgxNCAwLjA4NTk0LC0wLjcwMjYgLTAuMDY5NjksLTAuMjExMTYgLTAuMzE2NDQ5LC0wLjM5MjEyIC0wLjUzNDY5MywtMC4zOTIxMiAtMC4yMjA4OTQsMCAtMC43MjQ1NiwwLjQ0ODQyIC0xLjM3NTU2NywxLjIyNDcxIC0wLjQ1MDYzNiwwLjUzNzM1IC0wLjczMDE5MiwwLjgwMDcxIC0xLjAwNjMzMzgsMC45NDgwMiAtMC4zNjM4MTg4LDAuMTk0MDggLTAuNjE0MzYxNSwwLjE2Nzc3IC0xLjA5Nzk1MSwtMC4xMTUzMSAtMC44MDg3NDc2LC0wLjQ3MzQyIC0xLjQ3MTQ1OCwtMS40OTc5IC0xLjcyMTAzOTksLTIuNjYwNTQgLTAuMDgxOTM1LC0wLjM4MTY4IC0wLjA4Mjk1LC0xLjE2OTk2IC0wLjAwMjA0LC0xLjU3ODI2IDAuMDkyMzA5LC0wLjQ2NTc2IDAuMjc5OTYzMywtMC45OTUyMiAwLjQ3MTA0NjEsLTEuMzI5MDEgMC41MDgwNTg4LC0wLjg4NzUxIDEuNjM0OTc3MSwtMi4xMzIyNCAzLjI5MjA3NDYsLTMuNjM2MjMgMS41ODE3LC0xLjQzNTU3IDIuMjIwMzA2LC0yLjA0NTk0IDMuMjczNDUsLTMuMTI4NzQgMS4wMTEyMzEsLTEuMDM5NzEgMS42Mzc5NDEsLTEuOTM4MDQgMS45OTExMDIsLTIuODU0MDcgMC4zMTcyODYsLTAuODIyOTcgMC40NTIwNjQsLTEuMDA2NCAxLjU4MzQ3NiwtMi4xNTUwNSAwLjc5OTEwNSwtMC44MTEyOSAxLjAyNTc0NywtMS4wNjM5NCAxLjM5MzU4MSwtMS41NTM1MSAwLjI0MTYwMSwtMC4zMjE1NSAwLjU2MjQ3LC0wLjcxODEgMC43MTMwNDIsLTAuODgxMjIgMC4zMTMzMTEsLTAuMzM5NDEgMC40NDMwMjQsLTAuNTgwNSAwLjUwMjc1MSwtMC45MzQ0NSAwLjA1MzM0LC0wLjMxNjA5IDAuMDIxMDUsLTAuOTgzNTEgLTAuMDY3MTYsLTEuMzg4MjggLTAuMDM3NjUsLTAuMTcyNzUgLTAuMDY4NDUsLTAuMzI3MTQgLTAuMDY4NDUsLTAuMzQzMDcgMCwtMC4wNDE0IDAuMTUwOTk1LDMuN2UtNCAwLjM5MzQ4LDAuMTA4OTEgMC4yOTE5NjIsMC4xMzA3MSAwLjcxNDkxLDAuNTI1ODkgMS4wNjg1NzgsMC45OTg0MiAwLjMxMjAyOSwwLjQxNjkgMC44MzIzMiwxLjAzNjUzIDAuODcwMzUzLDEuMDM2NTMgMC4wMjg0MiwwIDAuMDQyNTUsLTAuMDIyMyAwLjMwODE3OCwtMC40ODYxOCAwLjExNTE4NiwtMC4yMDExNiAwLjMyNDkwNCwtMC41NDYxNSAwLjQ2NjA0MSwtMC43NjY2NSAwLjUzMDUxNSwtMC44Mjg4MiAwLjcxNjI4NywtMS4yNTQ0NyAwLjg3MjU3LC0xLjk5OTI4IGwgMC4wNzQ1NiwtMC4zNTUzMiAwLjIwNTk0LDAuMzA4NjggYyAwLjcxMjI3OSwxLjA2NzYgMS4wNjQ1OTYsMS44ODEwNyAxLjIxODg5NCwyLjgxNDMyIDAuMDMxOTQsMC4xOTMyMSAwLjAyOTU0LDAuMjgwMzIgLTAuMDEzODUsMC41MDExMyAtMC4wNjk0NSwwLjM1MzQ3IC0wLjA2NjMxLDAuNDY4MjggMC4wMTc1OSwwLjY0MTU5IDAuMTA2OTYzLDAuMjIwOTYgMC40ODI4MzMsMC40NDQyIDAuNzQ3OTA1LDAuNDQ0MiAwLjE2MjUwNCwwIDAuMzI5OTM1LC0wLjE1NjI0IDAuNDE3MTA3LC0wLjM4OTIzIDAuMDY5ODQsLTAuMTg2NjcgMC4yNjc0MzEsLTEuMTAwNiAwLjI2Nzk2OCwtMS4yMzk0NSAxLjY2ZS00LC0wLjA0MTMgMC4wMTg1MiwtMC4wNzUyIDAuMDQwOCwtMC4wNzUyIDAuMDU0NiwwIDEuNTY4NDE4LDAuNzk1NDggMi4xMzEwNDksMS4xMTk4MyAzLjI5NzA4MSwxLjkwMDY3IDUuNzY5MzUxLDMuOTgxMTMgNy41Njc4NTMsNi4zNjg1IDEuNjE1MjQ0LDIuMTQ0MTEgMi42Nzc3LDQuNjQ4NzEgMy4yMjIwOTYsNy41OTU3IDAuNDkwMzM0LDIuNjU0MzIgMC43MTUyNCw1LjMwMjE0IDAuNzY5MDI3LDkuMDUzNzUgMC4wMzA2NiwyLjEzODM3IDAuMDM3MjUsMi4yMDkzNSAwLjI3MTE4LDIuOTIxNDQgMC40MDc5NjMsMS4yNDE4NCAxLjQ0MDYzMiwyLjQ3MDUyIDIuMzcwNjA2LDIuODIwNTYgMC4yNTA3MzcsMC4wOTQ0IDAuNzE3ODgsMC4xNzEyNCAwLjg4MDQxMSwwLjE0NDg3IGwgMC4xMTA2NTIsLTAuMDE4IDAuMDIxMjcsMC4yMjI2NyBjIDAuMDg4NzYsMC45Mjg3MSAwLjEyODU4OCwxLjU5NTUxIDAuMTMzMDI3LDIuMjI3MTkgMC4wMDU1LDAuNzg1OTEgLTAuMDE3NDQsMC45MzkwOSAtMC4xNTUxNjUsMS4wMzU1NiAtMC4wNjM1NCwwLjA0NDUgLTEuODA1NTI3LDAuMDUwMiAtMTUuMzE1MzI5LDAuMDUwMiAtOC4zODM5OTksMCAtMTUuMjQzNjM0LC0wLjAwNiAtMTUuMjQzNjM0LC0wLjAxMjUgeiBNIDkuMTkyNDYxOCwyNzYuNTcyNTUgYyAwLjI0MjEwOTEsLTAuMTEyOTIgMC42NDcxOTgxLC0wLjQ1NDY5IDAuODAxODA4NywtMC42NzY0OCAwLjA3MzQ5NywtMC4xMDU0MyAwLjI3MDc4MjUsLTAuMzYzNjUgMC40Mzg0MDY1LC0wLjU3MzgxIDAuNTA3NTM2LC0wLjYzNjMxIDAuNzI5Njk1LC0xLjA2Nzc5IDAuNzI5NzUzLC0xLjQxNzMxIDMuM2UtNSwtMC4yMjY2MSAtMC4wNjgzNCwtMC4zMzg0MSAtMC4yNzg4NzksLTAuNDU2MDIgLTAuMTQ2MDUxLC0wLjA4MTYgLTAuNDY3MjM3LC0wLjEzMDQxIC0wLjYxNDYwMywtMC4wOTM0IC0wLjA1MjgzLDAuMDEzMyAtMC4xNjkxMTksMC4xMzY4MyAtMC4zMjYzNzQyLDAuMzQ2ODEgLTAuNTE2ODAwNSwwLjY5MDA3IC0xLjAzNDc4NDksMS4zMDA4NyAtMS4yNTg1MTU3LDEuNDg0MDEgLTAuMjU3NzM4NiwwLjIxMDk4IC0wLjMwMDMxNzcsMC4yOTkzNSAtMC4zMzMxOTgzLDAuNjkxNTUgLTAuMDE1NTMxLDAuMTg1MjUgLTAuMDA1ODcsMC4yNTMzNSAwLjA1NjUxLDAuMzk4MzYgMC4wNDEzODQsMC4wOTYyIDAuMTI2NDg2MiwwLjIxOTkgMC4xODkxMTcsMC4yNzQ4OSAwLjE0NTQzMjgsMC4xMjc2OSAwLjM1MjE4OCwwLjEzNTEyIDAuNTk1OTc1LDAuMDIxNCB6IE0gMTkuMjY2MDU4LDI2Ni4yMjU4MyBjIDAuMzkzNTc1LC0wLjA0ODkgMC43NzM3NDUsLTAuMTUwNjkgMS4wNjQ1NSwtMC4yODUwNSAwLjQ3Njc0MiwtMC4yMjAyNyAxLjAwOTM0NiwtMC44NDkyNyAxLjQ0MzM2NywtMS43MDQ2IDAuMTc3NTA2LC0wLjM0OTgxIDAuNTMxMzk4LC0xLjIwMDYyIDAuNTMxMzk4LC0xLjI3NzU1IDAsLTAuMDIzIC0wLjA1NTQ4LC0wLjAxODQgLTAuMTU4NjkyLDAuMDEzMSAtMC40MzYyODIsMC4xMzI5NCAtMC44NjQ2MTIsMC4xODUzOCAtMS43NzMzMzEsMC4yMTcxMiAtMC45NDY5MjcsMC4wMzMxIC0xLjM3MTgzOCwwLjA2ODMgLTEuNjE1Mzk4LDAuMTMzODggLTAuNDE4MDUyLDAuMTEyNTcgLTAuODQwODAzLDAuNDIzOTUgLTEuMTA2NjQxLDAuODE1MSAtMC4xNzAzMjgsMC4yNTA2MiAtMC4zNTYzNjgsMC42Njk4NSAtMC4zNTY2LDAuODAzNTcgLTIuNjRlLTQsMC4xNjMxNiAwLjEyNzY1MiwwLjY0Nzc4IDAuMjE5NTQsMC44MzE2MiAwLjE0NTk1OCwwLjI5MjAzIDAuMzA3NTI1LDAuNDA3ODggMC42NDg0NDQsMC40NjQ5NSAwLjE3MzAxOCwwLjAyOSAwLjgzMDk1NSwwLjAyMTcgMS4xMDMzNjMsLTAuMDEyMSB6IgogICAgICAgaWQ9InBhdGg5NyIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgPC9nPgo8L3N2Zz4K'); } -body.base .is2d piece.bishop.white { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMTQ0cHQiCiAgIGhlaWdodD0iMTQ0cHQiCiAgIHZpZXdCb3g9IjAgMCA1MC44MDAwMDEgNTAuOCIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnOCIKICAgc29kaXBvZGk6ZG9jbmFtZT0id2Iuc3ZnIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkyLjMgKDI0MDU1NDYsIDIwMTgtMDMtMTEpIj4KICA8ZGVmcwogICAgIGlkPSJkZWZzMiIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9ImJhc2UiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEuMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6em9vbT0iNy45MTk1OTU5IgogICAgIGlua3NjYXBlOmN4PSI4My41MzQ4NiIKICAgICBpbmtzY2FwZTpjeT0iOTcuNDI0NTA4IgogICAgIGlua3NjYXBlOmRvY3VtZW50LXVuaXRzPSJtbSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJsYXllcjEiCiAgICAgc2hvd2dyaWQ9ImZhbHNlIgogICAgIHVuaXRzPSJwdCIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjM4NDAiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iMjAzNSIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iLTEzIgogICAgIGlua3NjYXBlOndpbmRvdy15PSItMTMiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIgLz4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGE1Ij4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICAgIDxkYzp0aXRsZSAvPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZwogICAgIGlua3NjYXBlOmxhYmVsPSJMYXllciAxIgogICAgIGlua3NjYXBlOmdyb3VwbW9kZT0ibGF5ZXIiCiAgICAgaWQ9ImxheWVyMSIKICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLC0yNDYuMikiPgogICAgPGcKICAgICAgIGFyaWEtbGFiZWw9ImIiCiAgICAgICBzdHlsZT0iZm9udC1zdHlsZTpub3JtYWw7Zm9udC12YXJpYW50Om5vcm1hbDtmb250LXdlaWdodDpub3JtYWw7Zm9udC1zdHJldGNoOm5vcm1hbDtmb250LXNpemU6NTAuNzk5OTk5MjRweDtsaW5lLWhlaWdodDoxLjI1O2ZvbnQtZmFtaWx5OidDaGVzcyBMZWlwemlnJzstaW5rc2NhcGUtZm9udC1zcGVjaWZpY2F0aW9uOidDaGVzcyBMZWlwemlnJztsZXR0ZXItc3BhY2luZzowcHg7d29yZC1zcGFjaW5nOjBweDtmaWxsOiMwMDAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjAuMjY0NTgzMzIiCiAgICAgICBpZD0idGV4dDEyMCIKICAgICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuMDI5ODc1MTksMC4xMjU0NCkiPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDI1LjUzOTcwMSwyODEuNTM0MjcgcSAtMi44MDI5MjksMCAtNC43ODczMDQsMC40OTYxIC0xLjk4NDM3NSwwLjQ5NjA5IC0xLjk4NDM3NSwxLjE5MDYyIDAsMC42OTQ1MyAxLjk4NDM3NSwxLjE5MDYzIDEuOTg0Mzc1LDAuNDcxMjggNC43ODczMDQsMC40NzEyOCAyLjgwMjkzLDAgNC43ODczMDUsLTAuNDcxMjggMi4wMDkxOCwtMC40OTYxIDIuMDA5MTgsLTEuMTkwNjMgMCwtMC42OTQ1MyAtMi4wMDkxOCwtMS4xOTA2MiAtMS45ODQzNzUsLTAuNDk2MSAtNC43ODczMDUsLTAuNDk2MSB6IG0gNS42MDU4NiwtMzAuNTU5MzcgcSAtMS4wNjY2MDIsMCAtMS4wNjY2MDIsMS4wNDE3OSAwLDEuMDY2NjEgMS4wNjY2MDIsMS4wNjY2MSAxLjA2NjYwMSwwIDEuMDY2NjAxLC0xLjA2NjYxIDAsLTEuMDQxNzkgLTEuMDY2NjAxLC0xLjA0MTc5IHogbSAtNS45NTMxMjUsLTAuMDc0NCBxIC0xLjAxNjk5MywwIC0xLjAxNjk5MywxLjAxNyAwLDEuMDE2OTkgMS4wMTY5OTMsMS4wMTY5OSAxLjAxNjk5MiwwIDEuMDE2OTkyLC0xLjAxNjk5IDAsLTEuMDE3IC0xLjAxNjk5MiwtMS4wMTcgeiBtIDQuMDQzMTY0LDE0LjExMzg3IHYgLTEuMjY1MDQgaCAtMy4xNzUgdiAtNC4yNDE2IGggLTEuMjY1MDM5IHYgNC4yNDE2IGggLTMuMTc1IHYgMS4yNjUwNCBoIDMuMTc1IHYgNS45MjgzMiBIIDI2LjA2MDYgdiAtNS45MjgzMiB6IG0gMS4wNjY2MDEsMS4wNjY2IGggLTMuMTc1IHYgNS45MjgzMiBoIC0zLjM5ODI0MiB2IC01LjkyODMyIGggLTMuMTc1IHYgLTMuMzczNDQgaCAzLjE3NSB2IC00LjI0MTYgaCAzLjM5ODI0MiB2IDQuMjQxNiBoIDMuMTc1IHogbSAtMi40ODA0NjksMTMuNDkzNzUgLTIuNDA2MDU0LC0wLjk5MjE5IC0yLjM4MTI1LDAuOTkyMTkgMi4zODEyNSwwLjk5MjE5IHogbSA3LjI0Mjk2OSwtMTMuMzIwMTIgcSAwLjI3Mjg1MiwtMS4zMzk0NSAtMC44NDMzNTksLTQuOTM2MTMgLTEuMDkxNDA2LC0zLjYyMTQ4IC0zLjI0OTQxNCwtNi4wMDI3MyAtMC4zMjI0NjEsLTAuMTk4NDQgLTAuNTcwNTA4LC0wLjE3MzY0IC0wLjM3MjA3LDAuMDQ5NiAtMC42OTQ1MzEsMC4zNzIwNyAtMC4yOTc2NTcsMC4zMjI0NyAtMC4wNzQ0MSwwLjc2ODk1IDIuNjI5Mjk2LDEuNzg1OTQgNC4wMTgzNTksNS4xMzQ1NyAxLjM4OTA2MiwzLjM0ODYzIDEuNDEzODY3LDQuODM2OTEgeiBtIC0xNS4xODA0NjgsOS41MDAyIHEgMi4zODEyNSwtMC43OTM3NSA1LjUzMTQ0NSwtMC43OTM3NSAzLjI3NDIxOSwwIDUuNTgxMDU0LDAuNzkzNzUgMy4wMjYxNzIsLTYuMTAxOTUgMy4wMjYxNzIsLTkuNTc0NjEgMCwtNS44Nzg3MSAtOC41MDgwMDcsLTExLjQzNDk2IC04LjQ4MzIwMyw1LjU1NjI1IC04LjQ4MzIwMywxMS40MzQ5NiAwLDMuNzQ1NTEgMi44NTI1MzksOS41NzQ2MSB6IG0gMTAuNjQxMjEsMi41MzAwOCAtMC40NDY0ODQsLTEuNTYyNyBxIC0yLjA4MzU5NCwtMC40OTYwOSAtNC42ODgwODYsLTAuNDk2MDkgLTIuNTU0ODgzLDAgLTQuNDg5NjQ4LDAuNDQ2NDggbCAtMC40OTYwOTQsMS41ODc1IHEgMi4wNTg3ODksLTAuNTQ1NyA0Ljk4NTc0MiwtMC41NDU3IDMuMDc1NzgxLDAgNS4xMzQ1NywwLjU3MDUxIHogbSAwLjg5Mjk2OSwyLjY1NDEgLTAuNTQ1NzAzLC0xLjc2MTEzIC0yLjIwNzYxNywwLjQ3MTI5IDIuMTgyODEyLDEuNDEzODYgeiBtIC0xMS44NTY2NCwwLjAyNDggMC40NDY0ODQsMC4wOTkyIDIuMTgyODEzLC0xLjQxMzg2IC0yLjEwODM5OSwtMC40NzEyOSB6IG0gNS44MjkxMDEsOS45NDY2OCBxIC0xLjgzNTU0NywyLjY1NDEgLTQuOTYwOTM3LDIuNjU0MSAtMC4zMjI0NjEsMCAtMC42NDQ5MjIsLTAuMDI0OCAtMC4yOTc2NTYsLTAuMDQ5NiAtMC41OTUzMTMsLTAuMDc0NCAtMC43MTkzMzYsLTAuMDI0OCAtMi4xMDgzOTgsLTAuMjQ4MDUgLTEuMzg5MDYzLC0wLjI0ODA1IC0zLjEwMDU4NiwtMS4xMTYyMSAtMS41MTMwODYsLTEuMzE0NjUgLTMuODQ0NzI2LC0xLjMxNDY1IC0xLjc4NTkzNzksMCAtMy4xMDA1ODYzLDAuODQzMzYgLTAuMzcyMDcwMywwLjE3MzYzIC0wLjkxNzc3MzUsMC43MTkzNCAtMC45OTIxODc0LDEuMDY2NiAtMS42MTIzMDQ2LDEuMTY1ODIgLTAuNDk2MDkzOCwtMC4yNDgwNSAtMC41MjA4OTg0LC0wLjg0MzM2IC0wLjEyNDAyMzUsLTEuMTY1ODIgMS43MTE1MjM0LC0zLjAwMTM3IC0wLjMyMjQ2MSwwLjA0OTYgLTEuMjE1NDI5NywwLjI5NzY2IC0wLjc0NDE0MDYsMC4yMjMyNCAtMC45OTIxODc1LDAuMjIzMjQgLTAuODE4NTU0NywwLjEyNDAyIC0wLjg2ODE2NCwwLjAyNDggLTAuMjcyODUxNiwtMC4yNzI4NSAwLjE5ODQzNzUsLTEuMTE2MjEgMC4zOTY4NzUsLTAuNzE5MzMgMS41Mzc4OTA2LC0xLjI2NTA0IDAuMTQ4ODI4MSwtMC4wNzQ0IDAuOTQyNTc4MSwtMC40MjE2OCAyLjMwNjgzNTksLTEuMjE1NDMgNC44MzY5MTQ0LC0xLjIxNTQzIDMuNjk1ODk4LDAgNi42NzI0NiwyLjUwNTI4IDEuMTkwNjI1LDAuMzk2ODcgMi40MDYwNTUsMC4zOTY4NyAzLjcyMDcwMywwIDMuODQ0NzI3LC0zLjA3NTc4IC0yLjQwNjA1NSwtMC4yMjMyNCAtNC4wMTgzNiwtMC44MTg1NSAtMS41ODc1LC0wLjU5NTMyIC0xLjU4NzUsLTEuMzg5MDcgbCAxLjk4NDM3NSwtNi41OTgwNCBxIC0xLjczNjMyOCwtMi43Mjg1MiAtMi44NzczNDMsLTUuNTU2MjUgLTEuMTQxMDE2LC0yLjgyNzc0IC0xLjE0MTAxNiwtNS4zNTc4MiAwLC03LjU5MDIzIDguMjM1MTU2LC0xMS42NTgyIDAsLTAuMzIyNDYgMC4wNzQ0MSwtMC45NjczOCAtMC44NDMzNTksLTAuNjk0NTMgLTAuODQzMzU5LC0xLjc2MTEzIDAsLTIuMjgyMDQgMi4zMDY4MzYsLTIuMjgyMDQgMi4yODIwMzEsMCAyLjI4MjAzMSwyLjI4MjA0IDAsMC45OTIxOCAtMC43MTkzMzYsMS42NjE5MSAwLDAuNzY4OTQgMC4xOTg0MzcsMS4wNDE4IDAuNDIxNjgsMC41OTUzMSAxLjExNjIxMSwwLjYyMDExIDAuNzE5MzM2LC0wLjAyNDggMS4xOTA2MjUsLTAuNjQ0OTIgMC4wOTkyMiwtMC4xNDg4MyAwLjE5ODQzOCwtMC45MTc3NyAtMC42NDQ5MjIsLTAuNjY5NzMgLTAuNjQ0OTIyLC0xLjY2MTkyIDAsLTIuMzMxNjQgMi4zMzE2NDEsLTIuMzMxNjQgMi4zMzE2NCwwIDIuMzMxNjQsMi4zMzE2NCAwLDEuMzE0NjUgLTEuMTQxMDE1LDIuMDMzOTkgLTAuMDk5MjIsMC40OTYwOSAtMC4wNDk2MSwwLjc5Mzc1IDQuMTkxOTkyLDQuOTYwOTQgMy42NDYyODksMTEuNDU5NzYgLTAuMTczNjMzLDEuODYwMzYgLTAuNTcwNTA4LDMuNjcxMSAtMC4zOTY4NzUsMS43ODU5MyAtMS4zODkwNjIsMy4zNzM0MyAtMC4zNzIwNywwLjg0MzM2IC0xLjE2NTgyLDEuOTA5OTcgLTAuNzY4OTQ2LDEuMDQxNzkgLTEuMzM5NDU0LDEuOTU5NTcgbCAxLjk1OTU3MSw2LjU5ODA0IHEgLTAuMDI0ODEsMC43OTM3NSAtMS42MzcxMSwxLjM4OTA3IC0xLjYxMjMwNCwwLjU5NTMxIC00LjA2Nzk2OCwwLjgxODU1IDAuMTI0MDIzLDMuMDc1NzggMy44Njk1MzEsMy4wNzU3OCAxLjIxNTQzLDAgMi40MDYwNTUsLTAuMzk2ODcgMi45NTE3NTcsLTIuNTA1MjggNi42NzI0NiwtMi41MDUyOCAyLjUzMDA3OSwwIDQuODEyMTEsMS4yMTU0MyAwLjI5NzY1NiwwLjE0ODgzIDAuNTIwODk4LDAuMjQ4MDUgMC4yMjMyNDIsMC4wOTkyIDAuNDQ2NDg1LDAuMTczNjMgMS4xMTYyMSwwLjU3MDUxIDEuNTM3ODksMS4yNjUwNCAwLjA3NDQxLDAuMjIzMjQgMC4yMjMyNDIsMC41NzA1MSAwLjE0ODgyOCwwLjM0NzI2IC0wLjAyNDgsMC41NDU3IC0wLjA3NDQxLDAuMDk5MiAtMC44NjgxNjQsLTAuMDI0OCAtMC4yNDgwNDcsMCAtMC45OTIxODgsLTAuMjIzMjQgLTAuOTE3NzczLC0wLjI0ODA1IC0xLjI0MDIzNCwtMC4yOTc2NiAxLjgzNTU0NywxLjg2MDM1IDEuNzM2MzI4LDMuMDAxMzcgLTAuMDQ5NjEsMC41NzA1IC0wLjU0NTcwMywwLjg0MzM2IC0wLjYyMDExNywtMC4wOTkyIC0xLjYxMjMwNSwtMS4xNjU4MiAtMC40OTYwOTQsLTAuNDk2MSAtMC44OTI5NjksLTAuNzE5MzQgLTEuMzg5MDYyLC0wLjg0MzM2IC0zLjEwMDU4NiwtMC44NDMzNiAtMi4zODEyNSwwIC0zLjg2OTUzMSwxLjMxNDY1IC0xLjcxMTUyMywwLjg2ODE2IC0zLjEwMDU4NiwxLjExNjIxIC0xLjM4OTA2MiwwLjIyMzI0IC0yLjA4MzU5MywwLjI0ODA1IC0wLjI5NzY1NywwLjAyNDggLTAuNjIwMTE4LDAuMDc0NCAtMC4zMjI0NiwwLjAyNDggLTAuNjIwMTE3LDAuMDI0OCAtMy4xOTk4MDQsMCAtNC45ODU3NDIsLTIuNjU0MSB6IG0gMCwtMS44MTA3NCBxIDAuMDc0NDEsMCAxLjYzNzEwOSwxLjUxMzA5IDEuNDM4NjcyLDEuMzY0MjUgMy41MjIyNjYsMS4zNjQyNSAwLjE3MzYzMywwIDAuNDk2MDk0LDAgMC4zMjI0NjEsMCAwLjUyMDg5OCwwIDEuMDY2NjAyLC0wLjA3NDQgMi4wMzM5ODUsLTAuMjQ4MDQgMC45NjczODIsLTAuMTk4NDQgMi4zMDY4MzUsLTAuNzQ0MTQgMi41Nzk2ODgsLTEuNzg1OTQgNC43NjI1LC0xLjc4NTk0IDAuOTQyNTc5LDAgMS43MzYzMjksMC4yMjMyNCAwLjMyMjQ2LDAuMDc0NCAwLjM3MjA3LDAuMTczNjMgMC4wNzQ0MSwwLjA3NDQgMC41NzA1MDgsMC4yOTc2NiAxLjUzNzg5LDAuNzkzNzUgMC43Njg5NDUsMC4xNzM2MyAtMC43NDQxNDEsLTAuNjQ0OTIgLTAuNTcwNTA4LC0wLjk0MjU3IDAuMTQ4ODI4LC0wLjMyMjQ3IDEuMTQxMDE2LC0wLjY5NDU0IDEuMDE2OTkyLC0wLjM3MjA3IC0xLjQzODY3MiwtMC41OTUzMSAtMS4yNDAyMzQsLTAuNDIxNjggLTIuNTc5Njg4LC0wLjQyMTY4IC0yLjk3NjU2MiwwIC02LjA3NzE0OCwyLjQwNjA2IC0xLjA5MTQwNiwwLjU5NTMxIC0xLjg2MDM1MSwwLjY2OTcyIC0wLjc0NDE0MSwwLjA3NDQgLTEuNDEzODY4LDAuMDI0OCAtMS45MzQ3NjUsLTAuMDc0NCAtMi42MDQ0OTIsLTAuNTIwOSAtMC42NDQ5MjIsLTAuNDcxMjkgLTEuMTY1ODIsLTEuMDQxOCAtMC40OTYwOTQsLTAuNTIwOSAtMC45NjczODMsLTIuMDA5MTggLTAuMjQ4MDQ3LC0wLjc5Mzc1IC0xLjE5MDYyNSwtMC44OTI5NyAtMC45NjczODMsMC4wOTkyIC0xLjE5MDYyNSwwLjg5Mjk3IC0wLjQ0NjQ4NCwxLjQ4ODI4IC0wLjk2NzM4MywyLjAwOTE4IC0wLjUyMDg5OCwwLjU3MDUxIC0xLjE5MDYyNSwxLjA0MTggLTAuNjQ0OTIxLDAuNDQ2NDggLTIuNTU0ODgyLDAuNTIwOSAtMC42OTQ1MzIsMC4wNDk2IC0xLjQ2MzQ3NywtMC4wMjQ4IC0wLjc0NDE0MSwtMC4wNzQ0IC0xLjgxMDc0MiwtMC42Njk3MiAtMy4xNTAxOTUsLTIuNDA2MDYgLTYuMDc3MTQ4LC0yLjQwNjA2IC0xLjM2NDI1ODIsMCAtMi41Nzk2ODc5LDAuNDIxNjggLTIuNDgwNDY4NywwLjIyMzI0IC0xLjQ4ODI4MTIsMC41OTUzMSAxLjAxNjk5MjEsMC4zNzIwNyAxLjE5MDYyNSwwLjY5NDU0IDAuMTQ4ODI4MSwwLjI5NzY1IC0wLjYyMDExNzIsMC45NDI1NyAtMC43NDQxNDA2LDAuNjIwMTIgMC44MTg1NTQ3LC0wLjE3MzYzIDAuNDQ2NDg0MywtMC4yMjMyNCAwLjUyMDg5ODQsLTAuMjk3NjYgMC4wNzQ0MTQsLTAuMDk5MiAwLjM5Njg3NSwtMC4xNzM2MyAwLjc2ODk0NTMsLTAuMjIzMjQgMS43NjExMzMyLC0wLjIyMzI0IDIuMTU4MDA3LDAgNC43Mzc2OTUsMS43ODU5NCAxLjMzOTQ1MywwLjU0NTcgMi4yODIwMzEsMC43NDQxNCAwLjk2NzM4MywwLjE3MzYzIDIuMDgzNTk0LDAuMjQ4MDQgMC4xNzM2MzMsMCAwLjQ3MTI4OSwwIDAuMzIyNDYxLDAgMC41NDU3MDMsMCAyLjA1ODc4OSwwIDMuNTIyMjY1LC0xLjM2NDI1IDEuNTM3ODkxLC0xLjUxMzA5IDEuNjEyMzA1LC0xLjUxMzA5IHoiCiAgICAgICAgIHN0eWxlPSJzdHJva2Utd2lkdGg6MC4yNjQ1ODMzMiIKICAgICAgICAgaWQ9InBhdGgxMjIiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8L2c+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMTguNTQzNzEzLDI5Mi4wMjkxOSBjIC0xLjIxODAxLC0wLjEzMDQ1IC0xLjk4Nzc4NCwtMC4zMTAxMSAtMy4wNzIwOTIsLTAuNzE2OTkgLTAuMzY5MjksLTAuMTM4NTcgLTAuNjI2OTkzLC0wLjI1ODQgLTAuNzg1MTA0LC0wLjM2NTA0IC0xLjM3MzMwNywtMC45MjYzIC0yLjcyNzE5NywtMS40NzM1IC0zLjk3NzE0MiwtMS42MDc0NCAtMC45MjUwNzQ3LC0wLjA5OTEgLTIuMjkyNzI1MiwwLjA4MzggLTIuNjk0OTA0NiwwLjM2MDQ1IC0wLjIwMzA1NTMsMC4xMzk2OCAtMS4zMzc0MzU3LDAuNjk5NDggLTEuNDgxMTgxNCwwLjczMDk1IC0wLjA4NDk0MywwLjAxODYgLTAuMDQxMTU0LC0wLjAzNiAwLjI4NzE3OSwtMC4zNTc5NyAwLjM5NDU3MSwtMC4zODY5MyAwLjQ5NzkyNTIsLTAuNTM4OTkgMC40OTc5MjUyLC0wLjczMjU2IDAsLTAuMjA4NTMgLTAuMzQwNTM4MSwtMC40NTA0OCAtMS4wMTYzMDY0LC0wLjcyMjA3IC0wLjM3NjEyODcsLTAuMTUxMTYgLTAuNTAxMzE3OSwtMC4yMjgyNyAtMC40NjUyODExLC0wLjI4NjU3IDAuMDY4Njk3LC0wLjExMTE2IDAuNTE5Mjg3OSwtMC4yMTgzOSAxLjI5NTUyNCwtMC4zMDgzIDAuMjYxNDkyNSwtMC4wMzAzIDAuNjA1NDc4OSwtMC4wOTU1IDAuNzg1MTA0MiwtMC4xNDg4OCAwLjczOTI1NTQsLTAuMjE5NiAxLjM4NDM5MTgsLTAuMzA2OTIgMi4yNTc0MDIxLC0wLjMwNTU2IDEuODU3MzY5LDAuMDAzIDMuNjIxNTE3LDAuNjUzODIgNS42MjkzNjUsMi4wNzcwNyAwLjczMzkxOCwwLjUyMDIzIDEuNDk1NzYyLDAuODY4NTYgMi4xMDQ3NDcsMC45NjIzMiAwLjg0ODYxNiwwLjEzMDY1IDIuNTU2MzI4LDAuMDQwNyAzLjQyODg2NCwtMC4xODA2NiAwLjU0NzAzMiwtMC4xMzg3NyAwLjgyMDQxLC0wLjMwMjI1IDEuNDcxOTI3LC0wLjg4MDI0IDAuNjg3MjgxLC0wLjYwOTcxIDEuMDAwNzQ1LC0xLjEyNjEyIDEuMzYyMTM0LC0yLjI0NCAwLjE1ODU5NywtMC40OTA2IDAuMjE0MjkxLC0wLjU5NDA1IDAuNDE4NzY2LC0wLjc3Nzg5IDAuMjM5ODQ5LC0wLjIxNTY1IDAuNDc5OTY3LC0wLjMwMzQ2IDAuODM1MjY0LC0wLjMwNTQ2IDAuMjUxMTMxLC0xMGUtNCAwLjMwOTY3NCwwLjAxMDYgMC41MDYxODQsMC4xMDM2NyAwLjIzNjk1MiwwLjExMjI3IDAuNDU2NzA5LDAuMzA2MzQgMC41NDkwMjUsMC40ODQ4NiAwLjAzMTA4LDAuMDYwMSAwLjExOTY0MiwwLjI5MDE2IDAuMTk2ODE4LDAuNTExMjYgMC4zNzg5MzEsMS4wODU2IDAuNjQyNjY4LDEuNTQ0MjYgMS4xOTI0OTYsMi4wNzM4NCAwLjY2NzQ5MSwwLjY0MjkxIDEuMDE0MDIxLDAuODcxODQgMS41NDEzMDYsMS4wMTgyOCAwLjgxMTY4MSwwLjIyNTQgMi42MzMxODYsMC4zMjU5OSAzLjUxNDQyMywwLjE5NDA3IDAuNTM2NDc4LC0wLjA4MDMgMS40ODE4NiwtMC40NzMxMyAxLjg4NzU5MSwtMC43ODQzMiAwLjk1MDQyLC0wLjcyODk3IDIuMTYzMzczLC0xLjQwODMzIDMuMTQ2NDg2LC0xLjc2MjMxIDAuOTQ1MTE4LC0wLjM0MDMgMS43NzE5MDQsLTAuNDg4NDkgMi43MzUyODEsLTAuNDkwMjYgMC44NDY0MSwtMC4wMDIgMS41MDg0NDcsMC4wODU5IDIuMTczNjc2LDAuMjg3MTcgMC4yOTA4NjcsMC4wODggMC4zOTIyNTgsMC4xMDYyNyAxLjE5OTA5NCwwLjIxNjAzIDAuNTEyODQ1LDAuMDY5OCAwLjc3Njc5MywwLjEzMzY5IDAuODg1NTgyLDAuMjE0NSAwLjA2NjAxLDAuMDQ5IDAuMDY2MDEsMC4wNDk0IC01LjI5ZS00LDAuMTE1NTMgLTAuMDM2NzUsMC4wMzY1IC0wLjIwMjEyMywwLjEyMTgxIC0wLjM2NzQ5NiwwLjE4OTYzIC0wLjc2NTg2OCwwLjMxNDExIC0xLjA1MjM3MiwwLjUzNDI5IC0xLjA1MjM3MiwwLjgwODc3IDAsMC4xNDgwMyAwLjE3OTAyMiwwLjM5Njk5IDAuNTMwMzM5LDAuNzM3NTMgMC4yMjc4NzcsMC4yMjA4OCAwLjI5NzI0MywwLjMwNTE1IDAuMjM4MDU4LDAuMjg5MjEgLTAuMTI1OTA3LC0wLjAzMzkgLTEuMjY3Mzk2LC0wLjU4MzY5IC0xLjQxNjE2OSwtMC42ODIwNiAtMC4yMTgxMzUsLTAuMTQ0MjMgLTAuMjc0MDU1LC0wLjE2ODY4IC0wLjU0NDU0OSwtMC4yMzgwOSAtMC40MjM2NTksLTAuMTA4NzEgLTAuODMxMTkxLC0wLjE2NTMxIC0xLjM0Njc1MywtMC4xODcwNCAtMS40ODQyNTIsLTAuMDYyNSAtMi45MzM1NTUsMC40MDY2MiAtNC42NTkyMiwxLjUwODMgLTAuNDY1NDg3LDAuMjk3MTggLTAuODE0NDE3LDAuNDUwMzUgLTEuNjIxNjE1LDAuNzExODggLTAuNjI2NjUsMC4yMDMwMyAtMS4wMjQ0NTQsMC4yOTU0IC0xLjY3MDQzNCwwLjM4Nzg4IC0wLjk2NDk3OCwwLjEzODEzIC0xLjM1ODUzNSwwLjE2MjQ5IC0yLjMyNjkwNywwLjE0Mzk4IC0wLjc1MDA1NCwtMC4wMTQzIC0wLjk1MTc3MywtMC4wMjkgLTEuMjMxMTIsLTAuMDg5NSAtMC43MDYxMTIsLTAuMTUyODggLTEuMzQ0MzEzLC0wLjQzMDg1IC0xLjg4ODA1MywtMC44MjIzNSAtMC4xNDUzMzYsLTAuMTA0NjQgLTAuNTMxNjcyLC0wLjQ0NTY5IC0wLjg1ODUzMSwtMC43NTc5IC0wLjc2MzMxOCwtMC43MjkxIC0xLjI3NTcyNSwtMS4xOTQxMiAtMS4zMTU4MTMsLTEuMTk0MTIgLTAuMDQxMTQsMCAtMC4xODM2ODUsMC4xMzAzMyAtMS4xMzk0OTgsMS4wNDE4IC0wLjgzNTQxOSwwLjc5NjY2IC0xLjE0NjU2NCwxLjAzNzA3IC0xLjcwNTU3OCwxLjMxNzgyIC0wLjM1NDc1MiwwLjE3ODE3IC0wLjc1ODYxOSwwLjMxNjY3IC0xLjIxMDgzOCwwLjQxNTI0IC0wLjI5NDI2MiwwLjA2NDEgLTAuNDU1NTUzLDAuMDc0MSAtMS4zNTMwNTIsMC4wODMzIC0wLjcyNDQxNCwwLjAwNyAtMS4xNDkzNCwtMC4wMDMgLTEuNDY5OTgyLC0wLjAzNzggeiIKICAgICAgIGlkPSJwYXRoMTI1IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAyNC41NzM5ODIsMjg0Ljk3Njk3IGMgLTMuMzg0OTI1LC0wLjEzNDI0IC01Ljc2Mjk5OSwtMC44MDY2IC01Ljc2Mjk5OSwtMS42Mjk0IDAsLTAuNzU1ODEgMi4xNjI5MzQsLTEuNDQwMDYgNS4xMzcyNDEsLTEuNjI1MTkgMC44MzQxNCwtMC4wNTE5IDMuMjU1NzMyLC0wLjAyMTEgMy45NjY2MjgsMC4wNTA1IDEuODAzOTQ4LDAuMTgxNjEgMy4zNTEyODEsMC41NjAwMSAzLjk3MTExLDAuOTcxMTIgMC4yMzk1NDMsMC4xNTg4OCAwLjI2ODQyLDAuMTg0ODkgMC4zNjc3MjgsMC4zMzEyMyAwLjE1NTQzLDAuMjI5MDQgMC4wOTQ2MSwwLjUxMTE5IC0wLjE1NjY4MSwwLjcyNjg2IC0wLjkxMDk2MywwLjc4MTgyIC00LjI1NzIzNSwxLjMwNDQzIC03LjUyMzAyNywxLjE3NDkzIHoiCiAgICAgICBpZD0icGF0aDEyNyIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMjQuMjczMzAzLDI4MC4xODY2OCBjIC0wLjYwNjM2NywtMC4yNTUxMiAtMS4xMTYyNTgsLTAuNDY4OTEgLTEuMTMzMDg5LC0wLjQ3NTA5IC0wLjA0MDczLC0wLjAxNDkgMi4yNTQ3MjMsLTAuOTcyMTggMi4zMTkwOTgsLTAuOTY3MDggMC4wNDU2OCwwLjAwNCAyLjI5OTgxNCwwLjkyNjMxIDIuMzI1MzU0LDAuOTUxODUgMC4wMTkzMSwwLjAxOTMgLTIuMjkyMjEsMC45NTk5NiAtMi4zNTE3NDgsMC45NTcgLTAuMDMxNDIsLTAuMDAyIC0wLjU1MzI0NywtMC4yMTE1NiAtMS4xNTk2MTUsLTAuNDY2NjggeiIKICAgICAgIGlkPSJwYXRoMTI5IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAyOS44MTI4OCwyODAuNDc5NzMgYyAtMC41NzMwNjQsLTAuMzcxNSAtMS4wMzE1OTcsLTAuNjg1MDcgLTEuMDE4OTYzLC0wLjY5NjgxIDAuMDIyMjIsLTAuMDIwNyAyLjA4NjQ5MSwtMC40NjY0OSAyLjA5NzYyNCwtMC40NTMwNCAwLjAwMywwLjAwNCAwLjEyNTIwNiwwLjM5MjcgMC4yNzE0OTIsMC44NjQ1IGwgMC4yNjU5NzgsMC44NTc4MyAtMC4yMzI3MywwLjA1MjYgYyAtMC4xMjgwMDMsMC4wMjg5IC0wLjI1NzE5NywwLjA1MjEgLTAuMjg3MDk3LDAuMDUxNSAtMC4wMjk5LC01LjNlLTQgLTAuNTIzMjQsLTAuMzA1MDMgLTEuMDk2MzA0LC0wLjY3NjUyIHoiCiAgICAgICBpZD0icGF0aDEzMSIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMTkuNzUzMTU3LDI4MS4xMTQ4MiBjIC0wLjA3ODk4LC0wLjAxOSAtMC4xMzc4MywtMC4wNTEgLTAuMTMwNzY3LC0wLjA3MTIgMC4wMDcxLC0wLjAyMDIgMC4xMjMwOTksLTAuNDE2NDggMC4yNTc4NTgsLTAuODgwNjkgMC4xOTg5NzUsLTAuNjg1NDMgMC4yNTQ5MzYsLTAuODQxMjYgMC4yOTc4MSwtMC44MjkzMiAwLjAyOTA0LDAuMDA4IDAuNDczNzQzLDAuMTA3NzUgMC45ODgyMzcsMC4yMjE0NyAwLjUxNDQ5NCwwLjExMzcyIDAuOTQ1Nzk0LDAuMjE2MyAwLjk1ODQ0NCwwLjIyNzk2IDAuMDM5MDUsMC4wMzYgLTIuMDYwMTgyLDEuMzc0NzEgLTIuMTQ4NjM1LDEuMzcwMjQgLTAuMDQzNjQsLTAuMDAyIC0wLjE0Mzk2MywtMC4wMTk1IC0wLjIyMjk0NywtMC4wMzg1IHoiCiAgICAgICBpZD0icGF0aDEzMyIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMzAuMTgyNjcsMjc4LjMwMDg0IGMgLTIuNDc0NTA1LC0wLjYyMDEgLTYuODExMjEzLC0wLjYzNDkyIC05LjMzMDQxMSwtMC4wMzE5IC0wLjE5MTA5NSwwLjA0NTcgLTAuMzU0NjE3LDAuMDc2IC0wLjM2MzM4MiwwLjA2NzIgLTAuMDE4ODgsLTAuMDE4OSAwLjQyMzIyNSwtMS40NTkxOSAwLjQ2MDMyOSwtMS40OTk2OCAwLjA2ODg1LC0wLjA3NTEgMS4zMDg1NDIsLTAuMjgyMzEgMi4yNzE3MjQsLTAuMzc5NjMgMC40Njk0MjksLTAuMDQ3NCAwLjg5NzQsLTAuMDU5MSAyLjE3MTU2NSwtMC4wNTkyIDEuNjcyMDI4LC0xLjRlLTQgMi4xNDAwNiwwLjAyNjggMy4yMjM0NTIsMC4xODU2NSAwLjM5MTI5LDAuMDU3NCAxLjQ1Njk0MiwwLjI1NjE1IDEuNDc1ODA3LDAuMjc1MjkgMC4wMDMxLDAuMDAzIDAuMDk3NzIsMC4zMjg5NSAwLjIxMDI2OSwwLjcyNDAxIDAuMTEyNTUxLDAuMzk1MDUgMC4yMTEwOSwwLjczNzA4IDAuMjE4OTc1LDAuNzYwMDQgMC4wMTcxNywwLjA1IDAuMDM4NTIsMC4wNTI2IC0wLjMzODMyOCwtMC4wNDE4IHoiCiAgICAgICBpZD0icGF0aDEzNSIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMTkuNzI2NTI1LDI3NS40NTI3OSBjIC0xLjU5NjIxMiwtMy4zNTkzIC0yLjQ0MjEyMiwtNi4wNzc5OCAtMi42MjIxNDYsLTguNDI3MzQgLTAuMjYxOTU4LC0zLjQxODYyIDEuNDk3MTg0LC02LjY1NjE5IDUuMzY0ODU1LC05Ljg3MzYyIDAuODYzMTAxLC0wLjcxNzk5IDIuNTk5MTcxLC0xLjk5Mzc5IDMuMDE2MDc4LC0yLjIxNjQ1IDAuMDY5NDUsLTAuMDM3MSAwLjEyMjEyNiwtMC4wMDkgMC42MDEzNTcsMC4zMTc4MyAyLjk5ODY2NSwyLjA0NjU2IDUuMDU0MjEzLDQuMDAyNDkgNi4zNzQ4NjUsNi4wNjU5IDAuMzIyNzk3LDAuNTA0MzUgMC44NTIzMTUsMS41NTIzMyAxLjAzMjQ4OSwyLjA0MzQxIDAuMjc1NTU1LDAuNzUxMDcgMC40NDg5NjYsMS41Mzg4NyAwLjUxOTk0MywyLjM2MjExIDAuMTU4NzYzLDEuODQxNDcgLTAuNDczMzEzLDQuNDQ5NjkgLTEuODY2MDE2LDcuNjk5OTggLTAuMzA4NTczLDAuNzIwMTUgLTEuMDcwNjk4LDIuMzUyNzMgLTEuMTI3Njg2LDIuNDE1NjYgLTAuMDA1OCwwLjAwNiAtMC4yMTA3OTQsLTAuMDQ4NCAtMC40NTU1NTIsLTAuMTIxNzcgLTEuNDI1OTUxLC0wLjQyNzQ4IC0zLjEyNTM5MywtMC42NDE3MSAtNS4wODgxMjUsLTAuNjQxNDQgLTEuOTUxNDExLDIuN2UtNCAtMy41NDkxNTgsMC4yMDEwMiAtNS4wNjkxMzcsMC42MzY5IC0wLjI1MTk5MiwwLjA3MjMgLTAuNDY2MzE5LDAuMTMxMzkgLTAuNDc2MjgzLDAuMTMxMzkgLTAuMDEsMCAtMC4xMDIwNTMsLTAuMTc2NjUgLTAuMjA0NjQyLC0wLjM5MjU2IHogbSA3LjQzNjYzLC02LjI3MjQ4IHYgLTIuOTU2NjcgaCAxLjU4NjkxMiAxLjU4NjkxMyB2IC0xLjcwMzg0IC0xLjcwMzg0IGggLTEuNTg2OTEzIC0xLjU4NjkxMiB2IC0yLjEyMTQ2IC0yLjEyMTQ1IGggLTEuNzAzODQzIC0xLjcwMzg0MyB2IDIuMTIxNDUgMi4xMjE0NiBoIC0xLjU4NjkxMyAtMS41ODY5MTMgdiAxLjcwMzg0IDEuNzAzODQgaCAxLjU4NjkxMyAxLjU4NjkxMyB2IDIuOTU2NjcgMi45NTY2NyBoIDEuNzAzODQzIDEuNzAzODQzIHoiCiAgICAgICBpZD0icGF0aDEzNyIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMjQuODI0NTQ3LDI2OC4wOTQ1MyB2IC0yLjk3MzM3IGggLTEuNTg2OTEzIC0xLjU4NjkxMyB2IC0wLjYxODA3IC0wLjYxODA2IGggMS41ODY5MTMgMS41ODY5MTMgdiAtMi4xMjE0NSAtMi4xMjE0NSBoIDAuNjE4MDYxIDAuNjE4MDYxIHYgMi4xMjE0NSAyLjEyMTQ1IGggMS41ODY5MTEgMS41ODY5MTMgdiAwLjYxODA2IDAuNjE4MDcgSCAyNy42NDc1OCAyNi4wNjA2NjkgdiAyLjk3MzM3IDIuOTczMzcgaCAtMC42MTgwNjEgLTAuNjE4MDYxIHoiCiAgICAgICBpZD0icGF0aDEzOSIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMjUuMDI0OTk5LDI1My4wMjM3MyBjIC0wLjM0NDQyMSwtMC4wMzg2IC0wLjU3MzM0OCwtMC4xODY2IC0wLjcwNDg5MSwtMC40NTU2OCAtMC4wNjU5MiwtMC4xMzQ4NSAtMC4wNzc4NywtMC4yMTIgLTAuMDc4OTUsLTAuNTA5NjkgLTAuMDAxMSwtMC4zMTA1NCAwLjAwODgsLTAuMzcyMjkgMC4wODY1NywtMC41MzgxMiAwLjE1MjE4NSwtMC4zMjQ1NCAwLjQxNjgzMiwtMC40NjQxNCAwLjg3OTkwNSwtMC40NjQxNCAwLjMxNTg2OCwwIDAuNTQwNjMxLDAuMDU3OSAwLjcwMTYwNSwwLjE4MDY1IDAuMzQ2NzEsMC4yNjQ0NSAwLjQyMTI1NCwxLjAzMDMgMC4xNDA3NzQsMS40NDYyOSAtMC4xODI4NjYsMC4yNzEyMSAtMC41NTE1NzcsMC4zOTM3NiAtMS4wMjUwMTgsMC4zNDA2OSB6IgogICAgICAgaWQ9InBhdGgxNDEiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDMwLjgyOTI0LDI1My4xNjAwMiBjIC0wLjUwMTU5NywtMC4xMjY2MSAtMC43MTM2OTUsLTAuNDY2MDEgLTAuNjg2MDc4LC0xLjA5Nzg5IDAuMDE2MjcsLTAuMzcyMzMgMC4wNzcwOSwtMC41MjIwOCAwLjI5MDI0NSwtMC43MTQ2NSAwLjE4OTEyNywtMC4xNzA4NyAwLjQzMjQxMiwtMC4yMzU3MSAwLjgyMDY1OSwtMC4yMTg3MyAwLjY2NjM4MiwwLjAyOTIgMC45NTc2OTMsMC4zMzY5MSAwLjk1ODk1OCwxLjAxMzEzIDAuMDAxMywwLjY4NDYgLTAuMzA2Njk3LDEuMDEzNjQgLTAuOTcyNDg0LDEuMDM5MDEgLTAuMTU3MDI1LDAuMDA2IC0wLjM0MjEwOSwtMC4wMDMgLTAuNDExMywtMC4wMjA5IHoiCiAgICAgICBpZD0icGF0aDE0MyIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMzUuMDgxMDE1LDI2Ni4wNDk4NCBjIDAsLTAuODE5MjYgLTAuOTI3NzgsLTMuNjI2MzYgLTEuNzY5OTk5LC01LjM1NTM0IC0wLjgwMjkxLC0xLjY0ODI3IC0xLjkzMTIxNSwtMy4wMzA3OSAtMy4zMjQ4MjYsLTQuMDczOTMgLTAuMzM1ODY3LC0wLjI1MTQgLTAuMzkxMjY4LC0wLjMyODc5IC0wLjM5MzkyMiwtMC41NTAzMSAtMC4wMDMzLC0wLjI3MDU1IDAuMTk4OTA2LC0wLjUyODE0IDAuNTQzOTI4LC0wLjY5MzExIDAuMzUxODQzLC0wLjE2ODIzIDAuNjg3MTUyLC0wLjA5NjQgMC45NjM5NjksMC4yMDY0OCAwLjk3ODg2MywxLjA3MTAzIDEuOTI3ODUsMi42NDcwMyAyLjU4MzcwNyw0LjI5MDggMC41OTE0ODYsMS40ODI0MyAxLjE5MjA0LDMuNjY1MDggMS4zNzkyOTEsNS4wMTI4NiAwLjA1MjM5LDAuMzc3MDkgMC4wNzc4NywxLjIyMDY1IDAuMDM4MDgsMS4yNjA0NCAtMC4wMTExMSwwLjAxMTEgLTAuMDIwMjEsLTAuMDMyOSAtMC4wMjAyMSwtMC4wOTc5IHoiCiAgICAgICBpZD0icGF0aDE0NSIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgPC9nPgo8L3N2Zz4K'); } -body.base .is2d piece.rook.white { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMTQ0cHQiCiAgIGhlaWdodD0iMTQ0cHQiCiAgIHZpZXdCb3g9IjAgMCA1MC44MDAwMDEgNTAuOCIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnOCIKICAgc29kaXBvZGk6ZG9jbmFtZT0id3Iuc3ZnIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkyLjMgKDI0MDU1NDYsIDIwMTgtMDMtMTEpIj4KICA8ZGVmcwogICAgIGlkPSJkZWZzMiIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9ImJhc2UiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEuMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6em9vbT0iNy45MTk1OTU5IgogICAgIGlua3NjYXBlOmN4PSIzMi4zNzg1MzgiCiAgICAgaW5rc2NhcGU6Y3k9IjgyLjA5NDQxNCIKICAgICBpbmtzY2FwZTpkb2N1bWVudC11bml0cz0ibW0iCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ibGF5ZXIxIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICB1bml0cz0icHQiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIzODQwIgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjIwMzUiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9Ii0xMyIKICAgICBpbmtzY2FwZTp3aW5kb3cteT0iLTEzIgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiIC8+CiAgPG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhNSI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGUgLz4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGcKICAgICBpbmtzY2FwZTpsYWJlbD0iTGF5ZXIgMSIKICAgICBpbmtzY2FwZTpncm91cG1vZGU9ImxheWVyIgogICAgIGlkPSJsYXllcjEiCiAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwtMjQ2LjIpIj4KICAgIDxnCiAgICAgICBhcmlhLWxhYmVsPSJyIgogICAgICAgc3R5bGU9ImZvbnQtc3R5bGU6bm9ybWFsO2ZvbnQtdmFyaWFudDpub3JtYWw7Zm9udC13ZWlnaHQ6bm9ybWFsO2ZvbnQtc3RyZXRjaDpub3JtYWw7Zm9udC1zaXplOjUwLjc5OTk5OTI0cHg7bGluZS1oZWlnaHQ6MS4yNTtmb250LWZhbWlseTonQ2hlc3MgTGVpcHppZyc7LWlua3NjYXBlLWZvbnQtc3BlY2lmaWNhdGlvbjonQ2hlc3MgTGVpcHppZyc7bGV0dGVyLXNwYWNpbmc6MHB4O3dvcmQtc3BhY2luZzowcHg7ZmlsbDojMDAwMDAwO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDowLjI2NDU4MzMyIgogICAgICAgaWQ9InRleHQzNCIKICAgICAgIHRyYW5zZm9ybT0ibWF0cml4KDEuMDAwMDAzMiwwLDAsMSw0LjE5MzUzNDRlLTQsMC4wNjA4MykiPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDI1LjQxMjQwMiwyNDkuNTg1ODUgaCAzLjQyMzA0NyB2IDMuMzczNDMgaCA1LjEzNDU3IHYgLTMuMzczNDMgaCA1LjkwMzUxNiB2IDguODU1MjcgbCAtMy45OTM1NTUsNC42MTM2NyBxIDEuMjg5ODQ0LDEuNjM3MTEgMC4wNDk2MSwzLjQ0Nzg1IC0wLjE5ODQzOCwwLjMyMjQ2IC0wLjE5ODQzOCwwLjU5NTMyIDAsMC4zMjI0NiAwLjE5ODQzOCwwLjYyMDExIDAuNTIwODk4LDAuNzY4OTUgMC40OTYwOTMsMi4xODI4MiAwLDEuMzg5MDYgLTAuNTIwODk4LDIuMTgyODEgLTAuMTczNjMzLDAuMjQ4MDQgLTAuMTczNjMzLDAuNTIwOSAwLDAuMzQ3MjYgMC4yMjMyNDIsMC42NDQ5MiAxLjE2NTgyMSwxLjc2MTEzIC0wLjA0OTYxLDMuNDcyNjUgLTAuMTczNjMzLDAuMjk3NjYgLTAuMTczNjMzLDAuNTcwNTEgMCwwLjI3Mjg1IDAuMTczNjMzLDAuNTcwNTEgMC41NDU3MDMsMC44MTg1NSAwLjU0NTcwMywyLjI4MjAzIDAsMS40Mzg2NyAtMC41OTUzMTIsMi4xMzMyIGwgNC4wMTgzNTksMi4wMDkxOCB2IDIuMTMzMjEgaCAxLjY2MTkxNCB2IDcuMTkzMzYgSCAyNS40MTI0MDIgOS4yNjQ1NTEgdiAtNy4xNjg1NiBoIDEuNjg2NzE5IHYgLTIuMTMzMiBsIDMuOTkzNTU0LC0yLjAzMzk5IHEgLTAuNTk1MzEyLC0wLjY5NDUzIC0wLjU5NTMxMiwtMi4xMzMyIDAsLTEuNDM4NjcgMC41NDU3MDMsLTIuMjU3MjMgMC4xOTg0MzcsLTAuMjcyODUgMC4xOTg0MzcsLTAuNTcwNSAwLC0wLjI0ODA1IC0wLjE5ODQzNywtMC41NzA1MSAtMS4yMTU0MywtMS43MzYzMyAtMC4wMjQ4MSwtMy40NzI2NiAwLjIyMzI0MiwtMC4zOTY4NyAwLjIyMzI0MiwtMC42NDQ5MiAwLC0wLjI0ODA1IC0wLjE3MzYzMiwtMC41NDU3IC0wLjU0NTcwMywtMC43OTM3NSAtMC41NzA1MDgsLTIuMTgyODEgMCwtMS40MTM4NyAwLjUyMDg5OCwtMi4xODI4MiAwLjIyMzI0MiwtMC4yOTc2NSAwLjIyMzI0MiwtMC42MjAxMSAwLC0wLjI3Mjg2IC0wLjE5ODQzNywtMC41NzA1MSAtMS4yNjUwMzksLTEuODEwNzQgMC4wNDk2MSwtMy40NzI2NiBsIC0zLjk5MzU1NCwtNC41ODg4NyB2IC04Ljg1NTI3IGggNS45MDM1MTUgdiAzLjM0ODYzIGwgNS4xMDk3NjYsMC4wMjQ4IHYgLTMuMzczNDQgeiBtIC05LjE1MjkyOSwxMi4yNTM1MSBxIDQuMjQxNjAxLC0wLjY2OTcyIDkuMTUyOTI5LC0wLjY2OTcyIDQuOTg1NzQyLDAgOS4yMjczNDQsMC42Njk3MiBsIDEuNDM4NjcyLC0xLjgxMDc0IHEgLTUuMDYwMTU2LC0wLjg5Mjk3IC0xMC42NjYwMTYsLTAuODkyOTcgLTUuNjU1NDY4LDAgLTEwLjY5MDgyLDAuODkyOTcgeiBtIC01LjIzMzc4OSwyNi4yOTI5NyB2IDMuNzk1MTIgaCAyOC43NDg2MzIgdiAtMy43OTUxMiB6IG0gMTQuMzg2NzE4LC01LjA2MDE2IHEgLTUuMTU5Mzc1LDAgLTkuMzUxMzY3LDAuMzQ3MjcgbCAtMy4zNDg2MzIsMS43ODU5NCB2IDEuMjQwMjMgaCAyNS4zOTk5OTkgdiAtMS4yNDAyMyBxIC0wLjg0MzM1OSwtMC40NDY0OSAtMS42ODY3MTksLTAuODkyOTcgLTAuODQzMzU5LC0wLjQ0NjQ5IC0xLjY2MTkxNCwtMC44OTI5NyAtNC40NjQ4NDMsLTAuMzQ3MjcgLTkuMzUxMzY3LC0wLjM0NzI3IHogbSAxMi43LC0zMS43OTk2IGggLTIuNTU0ODgzIHYgMy40NzI2NSBoIC04LjQ4MzIwMyB2IC0zLjQ0Nzg1IGggLTMuMzQ4NjMyIHYgMy40NDc4NSBoIC04LjQ1ODM5OSB2IC0zLjQ3MjY1IGggLTIuNTU0ODgyIHEgMCwxLjU4NzUgMCwzLjE3NSAwLDEuNTYyNjkgMCwzLjEyNTM5IDMuMTc0OTk5LC0wLjE5ODQ0IDYuMzI1MTk1LC0wLjM3MjA3IDMuMTc1LC0wLjE3MzY0IDYuMzc0ODA0LC0wLjE3MzY0IDYuMDI3NTM5LDAgMTIuNywwLjU0NTcxIHogbSAtOC4yMTAzNTEsMTEuODgxNDQgcSAtMC44MTg1NTUsMC41OTUzMSAtMC44MTg1NTUsMS42ODY3MiAwLDEuMDkxNDEgMC44MTg1NTUsMS42ODY3MiAwLjc2ODk0NSwwLjU5NTMxIDIuMjgyMDMxLDAuNTk1MzEgMS41MTMwODYsMCAyLjMwNjgzNiwtMC41OTUzMSAwLjc5Mzc1LC0wLjU5NTMxIDAuNzkzNzUsLTEuNjg2NzIgMCwtMS4wOTE0MSAtMC43OTM3NSwtMS42ODY3MiAtMC43OTM3NSwtMC41NzA1MSAtMi4zMDY4MzYsLTAuNTcwNTEgLTEuNTEzMDg2LDAgLTIuMjgyMDMxLDAuNTcwNTEgeiBtIC02LjY3MjQ2MSwwIHEgLTAuNzY4OTQ1LDAuNTk1MzEgLTAuNzY4OTQ1LDEuNjg2NzIgMCwxLjA5MTQxIDAuNzY4OTQ1LDEuNjg2NzIgMC43NDQxNCwwLjU5NTMxIDIuMTU4MDA4LDAuNTk1MzEgMS40Mzg2NzIsMCAyLjIwNzYxNywtMC41OTUzMSAwLjc0NDE0LC0wLjU5NTMxIDAuNzQ0MTQsLTEuNjg2NzIgMCwtMS4wOTE0MSAtMC43NDQxNCwtMS42ODY3MiAtMC43Njg5NDUsLTAuNTcwNTEgLTIuMjA3NjE3LC0wLjU3MDUxIC0xLjQxMzg2OCwwIC0yLjE1ODAwOCwwLjU3MDUxIHogbSAtNi44OTU3MDMsMCBxIC0wLjgxODU1NSwwLjU5NTMxIC0wLjgxODU1NSwxLjY4NjcyIDAsMS4wOTE0MSAwLjgxODU1NSwxLjY4NjcyIDAuNzY4OTQ1LDAuNTk1MzEgMi4yNTcyMjYsMC41OTUzMSAxLjUxMzA4NiwwIDIuMzMxNjQxLC0wLjU5NTMxIDAuNzkzNzUsLTAuNTk1MzEgMC43OTM3NSwtMS42ODY3MiAwLC0xLjA5MTQxIC0wLjc5Mzc1LC0xLjY4NjcyIC0wLjgxODU1NSwtMC41NzA1MSAtMi4zMzE2NDEsLTAuNTcwNTEgLTEuNDg4MjgxLDAgLTIuMjU3MjI2LDAuNTcwNTEgeiBtIDE2LjY2ODc1LDUuMDM1MzUgcSAtMC4yOTc2NTcsMC41OTUzMSAtMC4yOTc2NTcsMS43MTE1MyAwLDEuMDkxNCAwLjI5NzY1NywxLjY2MTkxIDAuMjcyODUxLDAuNTk1MzEgMC44NjgxNjQsMC41OTUzMSAwLjU5NTMxMiwwIDAuODkyOTY4LC0wLjU5NTMxIDAuMjk3NjU3LC0wLjU3MDUxIDAuMjk3NjU3LC0xLjY2MTkxIDAsLTEuMTE2MjIgLTAuMjk3NjU3LC0xLjcxMTUzIC0wLjI5NzY1NiwtMC41NDU3IC0wLjg5Mjk2OCwtMC41NDU3IC0wLjU5NTMxMywwIC0wLjg2ODE2NCwwLjU0NTcgeiBtIC02LjM1LDAgcSAtMC43NDQxNDEsMC41OTUzMSAtMC43NDQxNDEsMS43MTE1MyAwLDEuMDkxNCAwLjc0NDE0MSwxLjY2MTkxIDAuNzQ0MTQsMC41OTUzMSAyLjEzMzIwMywwLjU5NTMxIDEuNDEzODY3LDAgMi4xNTgwMDgsLTAuNTk1MzEgMC43NDQxNCwtMC41NzA1MSAwLjc0NDE0LC0xLjY2MTkxIDAsLTEuMTE2MjIgLTAuNzQ0MTQsLTEuNzExNTMgLTAuNzQ0MTQxLC0wLjU3MDUxIC0yLjE1ODAwOCwtMC41NzA1MSAtMS4zODkwNjMsMCAtMi4xMzMyMDMsMC41NzA1MSB6IG0gLTYuNzcxNjgsMCBxIC0wLjc0NDE0LDAuNTk1MzEgLTAuNzQ0MTQsMS43MTE1MyAwLDEuMDkxNCAwLjc0NDE0LDEuNjYxOTEgMC43MTkzMzYsMC41OTUzMSAyLjEzMzIwMywwLjU5NTMxIDEuNDEzODY3LDAgMi4xNTgwMDgsLTAuNTk1MzEgMC43MTkzMzYsLTAuNTcwNTEgMC43MTkzMzYsLTEuNjYxOTEgMCwtMS4xMTYyMiAtMC43MTkzMzYsLTEuNzExNTMgLTAuNzQ0MTQxLC0wLjU3MDUxIC0yLjE1ODAwOCwtMC41NzA1MSAtMS40MTM4NjcsMCAtMi4xMzMyMDMsMC41NzA1MSB6IG0gLTMuODE5OTIyLDAgcSAtMC4yOTc2NTYsMC41OTUzMSAtMC4yOTc2NTYsMS43MTE1MyAwLDEuMDkxNCAwLjI5NzY1NiwxLjY2MTkxIDAuMjk3NjU3LDAuNTk1MzEgMC44NjgxNjQsMC41OTUzMSAwLjU5NTMxMywwIDAuODkyOTY5LC0wLjU5NTMxIDAuMjk3NjU2LC0wLjU3MDUxIDAuMjk3NjU2LC0xLjY2MTkxIDAsLTEuMTE2MjIgLTAuMjk3NjU2LC0xLjcxMTUzIC0wLjI5NzY1NiwtMC41NDU3IC0wLjg5Mjk2OSwtMC41NDU3IC0wLjU3MDUwNywwIC0wLjg2ODE2NCwwLjU0NTcgeiBtIDE2Ljk0MTYwMiwxMC4xOTQ3MyBxIC0wLjI5NzY1NywwLjU3MDUxIC0wLjI5NzY1NywxLjY4NjcyIDAsMS4xMTYyMSAwLjI5NzY1NywxLjY4NjcyIDAuMjcyODUxLDAuNTcwNSAwLjg2ODE2NCwwLjU3MDUgMC41OTUzMTIsMCAwLjg5Mjk2OCwtMC41NzA1IDAuMjk3NjU3LC0wLjU3MDUxIDAuMjk3NjU3LC0xLjY4NjcyIDAsLTEuMTE2MjEgLTAuMjk3NjU3LC0xLjY4NjcyIC0wLjI5NzY1NiwtMC41NDU3IC0wLjg5Mjk2OCwtMC41NDU3IC0wLjU5NTMxMywwIC0wLjg2ODE2NCwwLjU0NTcgeiBtIC0xNi45NDE2MDIsMCBxIC0wLjI5NzY1NiwwLjU3MDUxIC0wLjI5NzY1NiwxLjY4NjcyIDAsMS4xMTYyMSAwLjI5NzY1NiwxLjY4NjcyIDAuMjk3NjU3LDAuNTcwNSAwLjg2ODE2NCwwLjU3MDUgMC41OTUzMTMsMCAwLjg5Mjk2OSwtMC41NzA1IDAuMjk3NjU2LC0wLjU3MDUxIDAuMjk3NjU2LC0xLjY4NjcyIDAsLTEuMTE2MjEgLTAuMjk3NjU2LC0xLjY4NjcyIC0wLjI5NzY1NiwtMC41NDU3IC0wLjg5Mjk2OSwtMC41NDU3IC0wLjU3MDUwNywwIC0wLjg2ODE2NCwwLjU0NTcgeiBtIDMuODE5OTIyLDAgcSAtMC43NDQxNCwwLjU5NTMxIC0wLjc0NDE0LDEuNzg1OTQgMCwxLjE5MDYyIDAuNzQ0MTQsMS41ODc1IDAuNjk0NTMxLDAuMzk2ODcgMi4xODI4MTMsMC4zOTY4NyAxLjUxMzA4NSwwIDIuMTA4Mzk4LC0wLjM5Njg3IDAuNTcwNTA4LC0wLjM5Njg4IDAuNjQ0OTIyLC0xLjU4NzUgMC4wNzQ0MSwtMS4xOTA2MyAtMC42NDQ5MjIsLTEuNzg1OTQgLTAuNzQ0MTQxLC0wLjU3MDUxIC0yLjE1ODAwOCwtMC41NzA1MSAtMS40MTM4NjcsMCAtMi4xMzMyMDMsMC41NzA1MSB6IG0gNi43NzE2OCwwIHEgLTAuNzQ0MTQxLDAuNTk1MzEgLTAuNzQ0MTQxLDEuNzg1OTQgMCwxLjE5MDYyIDAuNzQ0MTQxLDEuNTg3NSAwLjcxOTMzNiwwLjM5Njg3IDIuMTMzMjAzLDAuMzk2ODcgMS40Mzg2NzIsMCAyLjE1ODAwOCwtMC4zOTY4NyAwLjY5NDUzMSwtMC4zOTY4OCAwLjcxOTMzNiwtMS41ODc1IDAuMDI0OCwtMS4xOTA2MyAtMC43MTkzMzYsLTEuNzg1OTQgLTAuNzQ0MTQxLC0wLjU3MDUxIC0yLjE1ODAwOCwtMC41NzA1MSAtMS4zODkwNjMsMCAtMi4xMzMyMDMsMC41NzA1MSB6IG0gMy4yNDk0MTQsLTUuMDYwMTYgcSAtMC44MTg1NTUsMC41OTUzMSAtMC44MTg1NTUsMS43MTE1MyAwLDEuMDkxNCAwLjgxODU1NSwxLjY2MTkxIDAuNzY4OTQ1LDAuNTk1MzEgMi4yODIwMzEsMC41OTUzMSAxLjUxMzA4NiwwIDIuMzA2ODM2LC0wLjU5NTMxIDAuNzkzNzUsLTAuNTcwNTEgMC43OTM3NSwtMS42NjE5MSAwLC0xLjExNjIyIC0wLjc5Mzc1LC0xLjcxMTUzIC0wLjc5Mzc1LC0wLjU3MDUxIC0yLjMwNjgzNiwtMC41NzA1MSAtMS41MTMwODYsMCAtMi4yODIwMzEsMC41NzA1MSB6IG0gLTYuNjcyNDYxLDAgcSAtMC43Njg5NDUsMC41OTUzMSAtMC43Njg5NDUsMS43MTE1MyAwLDEuMDkxNCAwLjc2ODk0NSwxLjY2MTkxIDAuNzQ0MTQsMC41OTUzMSAyLjE1ODAwOCwwLjU5NTMxIDEuNDM4NjcyLDAgMi4yMDc2MTcsLTAuNTk1MzEgMC43NDQxNCwtMC41NzA1MSAwLjc0NDE0LC0xLjY2MTkxIDAsLTEuMTE2MjIgLTAuNzQ0MTQsLTEuNzExNTMgLTAuNzY4OTQ1LC0wLjU3MDUxIC0yLjIwNzYxNywtMC41NzA1MSAtMS40MTM4NjgsMCAtMi4xNTgwMDgsMC41NzA1MSB6IG0gLTYuODk1NzAzLDAgcSAtMC44MTg1NTUsMC41OTUzMSAtMC44MTg1NTUsMS43MTE1MyAwLDEuMDkxNCAwLjgxODU1NSwxLjY2MTkxIDAuNzY4OTQ1LDAuNTk1MzEgMi4yNTcyMjYsMC41OTUzMSAxLjUxMzA4NiwwIDIuMzMxNjQxLC0wLjU5NTMxIDAuNzkzNzUsLTAuNTcwNTEgMC43OTM3NSwtMS42NjE5MSAwLC0xLjExNjIyIC0wLjc5Mzc1LC0xLjcxMTUzIC0wLjgxODU1NSwtMC41NzA1MSAtMi4zMzE2NDEsLTAuNTcwNTEgLTEuNDg4MjgxLDAgLTIuMjU3MjI2LDAuNTcwNTEgeiIKICAgICAgICAgc3R5bGU9InN0cm9rZS13aWR0aDowLjI2NDU4MzMyIgogICAgICAgICBpZD0icGF0aDM2IgogICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPC9nPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NzQiCiAgICAgICBkPSJtIDExLjAyNjE1NiwyOTAuMDkzMjkgdiAtMS44NzA4OSBoIDE0LjM2NTc4MiAxNC4zNjU3ODMgdiAxLjg3MDg5IDEuODcwODkgSCAyNS4zOTE5MzggMTEuMDI2MTU2IFoiCiAgICAgICBpZD0icGF0aDM5IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODc0IgogICAgICAgZD0ibSAxMi43Mzc2MDMsMjg1Ljg3NTg5IDAuMDA5MSwtMC42MDkyNiAxLjY3MDQzOSwtMC44ODkzNyAxLjY3MDQ0MSwtMC44ODkzNyAwLjc4NTEwNiwtMC4wNTQ3IGMgMi4yMDcyNjIsLTAuMTUzODQgMy42MDYyNDcsLTAuMjExODYgNi4zMDU4NjUsLTAuMjYxNTQgMy42MzAxMDEsLTAuMDY2OCA3LjM3NzQwNCwwLjAyNzggMTAuOTk5ODkzLDAuMjc3ODEgbCAwLjU1MTI0NCwwLjAzOCAwLjgzNTIxOSwwLjQ0NjEyIGMgMC40NTkzNywwLjI0NTM2IDEuMjE0NTA1LDAuNjQ1NDcgMS42NzgwNzQsMC44ODkxMyBsIDAuODQyODU3LDAuNDQzMDEgNy45NGUtNCwwLjYwOTcgNy45NGUtNCwwLjYwOTcxIEggMjUuNDA3ODkgMTIuNzI4NDk3IFoiCiAgICAgICBpZD0icGF0aDQxIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODc0IgogICAgICAgZD0ibSAyMS4zNzI5MjcsMjgyLjE3NDk1IGMgLTAuNjQxNDA3LC0wLjA1NzggLTEuMTg2MTg5LC0wLjE5NzYyIC0xLjUxNDk1LC0wLjM4ODg5IC0wLjE4MTA2MSwtMC4xMDUzNCAtMC40MTQxNjgsLTAuMzU3NDMgLTAuNTA0OTU2LC0wLjU0NjA3IC0wLjEzOTcxMywtMC4yOTAzMSAtMC4xODg1OTEsLTAuNTU2NjcgLTAuMTg2OTgyLC0xLjAxODk3IDAuMDAyNiwtMC43Mzc3IDAuMTcyNjk5LC0xLjIxNjE3IDAuNTc0OTQ3LC0xLjYxNjk1IDAuNDgzODA5LC0wLjQ4MjA0IDEuMjAzMjkyLC0wLjcwNDc2IDIuMjc2NjY0LC0wLjcwNDc2IDEuMDY4MzIsMCAxLjg2MDY0LDAuMjQ1MDQgMi4yODkyNjYsMC43MDgwMSAwLjM5OTkxNSwwLjQzMTk1IDAuNTQ4Mjg1LDAuOTcwNzYgMC40ODA2MzgsMS43NDU0NSAtMC4wNjU3MSwwLjc1MjU0IC0wLjMxMjM2MSwxLjI3MzI3IC0wLjcxMjQ2OSwxLjUwNDE5IC0wLjE4NzcwNywwLjEwODM0IC0wLjU0MzU0NSwwLjIxMjYyIC0wLjkyMTUzNiwwLjI3MDA2IC0wLjQwMDgzOSwwLjA2MDkgLTEuMzUyMTExLDAuMDg2NSAtMS43ODA2MjIsMC4wNDc5IHoiCiAgICAgICBpZD0icGF0aDQzIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODc0IgogICAgICAgZD0ibSAyOC4xMzg3MTMsMjgyLjE3NjM1IGMgLTAuNDQyOTI0LC0wLjAzOTggLTAuNzEwMTI1LC0wLjA5MTEgLTEuMDYzNDg1LC0wLjIwNDMgLTAuNjA1MTgxLC0wLjE5Mzg2IC0wLjg5NDcxNywtMC40NzgxNiAtMS4wNzAyMDYsLTEuMDUwODcgLTAuMDg1NDUsLTAuMjc4ODYgLTAuMDg1MzEsLTEuMTA3NTUgMi4zOWUtNCwtMS40MTU1NSAwLjI5ODg4MiwtMS4wNzYwOCAxLjIwOTM4NCwtMS42MDU2NCAyLjc2MTg0MiwtMS42MDYzMiAxLjY1MTc1OCwtNy45ZS00IDIuNTkwMTExLDAuNTUzODkgMi44MjU5MSwxLjY3MDI0IDAuMDY4MjEsMC4zMjI5NCAwLjA0Njg0LDEuMDk1OTUgLTAuMDM3ODcsMS4zNjk3NiAtMC4yMjA5MiwwLjcxNDA5IC0wLjYxMTkwNCwwLjk5Nzg4IC0xLjYxMjUyNiwxLjE3MDQgLTAuNDM1NDU1LDAuMDc1MSAtMS4zMzg1NiwwLjEwODQ0IC0xLjgwMzkwNCwwLjA2NjYgeiIKICAgICAgIGlkPSJwYXRoNDUiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NzQiCiAgICAgICBkPSJtIDMzLjU0OTQ1OCwyODIuMzEyMjMgYyAtMC40NjQ3NTEsLTAuMTYwNSAtMC43MjU2OTIsLTAuNzE3MzggLTAuODEwMzExLC0xLjcyOTI4IC0wLjAyNjcxLC0wLjMxOTQxIC0wLjAyNjc2LC0wLjU2NzQxIC0xLjk4ZS00LC0wLjkwNTU0IDAuMDk1NjksLTEuMjE3OSAwLjQ0MzgxOCwtMS43NTEgMS4xNDE5OTYsLTEuNzQ4OCAwLjY2Njk1MywwLjAwMiAxLjAyMTY2NywwLjUwMTQ0IDEuMTM0OTQxLDEuNTk3NjYgMC4wNTE1OSwwLjQ5OTMzIDAuMDIxMTQsMS4yNTUwNSAtMC4wNjc3LDEuNjgwMzEgLTAuMTkwMTgzLDAuOTEwMyAtMC43Mjk2NDYsMS4zMzY3MyAtMS4zOTg3MzEsMS4xMDU2NSB6IgogICAgICAgaWQ9InBhdGg0NyIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg3NCIKICAgICAgIGQ9Im0gMTYuNjI2ODA4LDI4Mi4zMjEzNiBjIC0wLjIwNzQyNiwtMC4wNjM3IC0wLjQ0NDk4OCwtMC4yOTY3OSAtMC41Njg0MTksLTAuNTU3NyAtMC4yODIyOTgsLTAuNTk2NzMgLTAuMzY0MTkyLC0xLjc3ODY3IC0wLjE4NTA3MiwtMi42NzEwNyAwLjE2MDE2NywtMC43OTc5NyAwLjQ5NzU3NiwtMS4xNjU3OCAxLjA2Nzc1OCwtMS4xNjM5OCAwLjcyNzE0MSwwLjAwMiAxLjA5NTkzOSwwLjYxNzA2IDEuMTU0NzYsMS45MjQ5MiAwLjA0OTAyLDEuMDg5ODYgLTAuMTUzNjMsMS45NDI5NSAtMC41NDI5NDgsMi4yODU2NCAtMC4yNTI0ODYsMC4yMjIyNCAtMC41ODM1ODEsMC4yODczOSAtMC45MjYwNzksMC4xODIxOSB6IgogICAgICAgaWQ9InBhdGg0OSIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg3NCIKICAgICAgIGQ9Im0gMTcuODI0ODQ2LDI3Ny4yOTUzNSBjIC0wLjU3MzEzOCwtMC4wNzc3IC0xLjA3Mjc0NywtMC4yNjQxMiAtMS40NzI0MDksLTAuNTQ5MzEgLTAuNTQ5ODExLC0wLjM5MjM0IC0wLjgxNDkzMywtMC45MzAxOSAtMC44MTQ5MzMsLTEuNjUzMjUgMCwtMS4xODU4NCAwLjczMTkwOCwtMS45NDg5IDIuMTAzNTk0LC0yLjE5MzEyIDAuNDMwMzc5LC0wLjA3NjYgMS40NjA0MzksLTAuMDc3IDEuOTA5NTEyLC03LjllLTQgMC43MTMxMjEsMC4xMjExNCAxLjIxNjg3NiwwLjM0MzE2IDEuNTY2NTQ0LDAuNjkwNDIgMC4yNTQ2NjUsMC4yNTI5MSAwLjQzOTI0MywwLjU4MTMyIDAuNTE4Mjg2LDAuOTIyMTQgMC4wNjkyNywwLjI5ODY4IDAuMDY4NjQsMC44OTgzNSAtMC4wMDEyLDEuMTY1OTQgLTAuMjEwMzMxLDAuODA1NjggLTAuODUwNzYyLDEuMzI3NDYgLTEuOTA3MzUxLDEuNTUzOTcgLTAuMzgxNDY5LDAuMDgxOCAtMS40OTQ1OTUsMC4xMTkyIC0xLjkwMjAyNSwwLjA2MzkgeiIKICAgICAgIGlkPSJwYXRoNTEiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NzQiCiAgICAgICBkPSJtIDI0LjYwMzQ1LDI3Ny4yODI1MiBjIC0xLjEyMzkwNywtMC4xNzQ1OSAtMS44ODU2MjEsLTAuNzgwODkgLTIuMDY5MTU5LC0xLjY0Njk4IC0wLjA2OTUzLC0wLjMyODEgLTAuMDYyNSwtMC44NDY0NiAwLjAxNTYyLC0xLjE1MTkxIDAuMTk1NDM5LC0wLjc2NDE2IDAuNzY0MzI1LC0xLjI5NTQxIDEuNjE5NDU2LC0xLjUxMjMzIDAuODE1MTgzLC0wLjIwNjc5IDEuOTY5NjIxLC0wLjE3OTAzIDIuNjg1ODY4LDAuMDY0NiAwLjc0MzU0MSwwLjI1Mjg5IDEuMTkzNTcyLDAuNjk4MDEgMS4zNzkyODksMS4zNjQyNCAwLjA5OTIsMC4zNTU4NCAwLjEwNzM2OCwwLjk5NDEyIDAuMDE2OTksMS4zMjc0MyAtMC4xODM5NTUsMC42Nzg1IC0wLjczNDQzOSwxLjIwMjMzIC0xLjUwNjUzMiwxLjQzMzU5IC0wLjU0MjIxMiwwLjE2MjQgLTEuNTIwNSwwLjIxNzg1IC0yLjE0MTU0NCwwLjEyMTM4IHoiCiAgICAgICBpZD0icGF0aDUzIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODc0IgogICAgICAgZD0ibSAzMS4zMzQzNDUsMjc3LjI3OTc3IGMgLTAuNDEyMjkzLC0wLjA2NDIgLTAuNjc4NjY5LC0wLjEzODcyIC0wLjk1OTE2LC0wLjI2ODE3IC0wLjg5MjE0LC0wLjQxMTc1IC0xLjMxMzMzMiwtMS4wOTYwMyAtMS4yNjMzMjksLTIuMDUyNDUgMC4wMzEyLC0wLjU5NjY3IDAuMTg4NTc4LC0wLjk2Nzk0IDAuNTc1MTk2LC0xLjM1NjkyIDAuNDI1NzQsLTAuNDI4MzQgMS4wNDkzOTcsLTAuNjY3MzYgMS45NTIzMzIsLTAuNzQ4MjMgMC42OTY1NzIsLTAuMDYyNCAxLjUyMDI5OCwwLjAwNiAyLjA1NjAzNiwwLjE2OTcyIDAuNzk0Mzk2LDAuMjQzMzYgMS4zMTk2MjIsMC43NTU5NCAxLjUwNjM4NCwxLjQ3MDEyIDAuMDY4OTEsMC4yNjM1MiAwLjA3NzE0LDAuODczMzYgMC4wMTUyOSwxLjEzMzQ5IC0wLjIyMDY0LDAuOTI4MDYgLTEuMDI3MjIxLDEuNTExNTEgLTIuMzA3MzA5LDEuNjY5MDEgLTAuMzgzNzQ1LDAuMDQ3MiAtMS4yMjI3MywwLjAzODQgLTEuNTc1NDQ4LC0wLjAxNjYgeiIKICAgICAgIGlkPSJwYXRoNTUiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NzQiCiAgICAgICBkPSJtIDMzLjUxMDI3NSwyNzIuMTMzMTEgYyAtMC4yODg4NzMsLTAuMTI0NzggLTAuNTQ5NDIyLC0wLjUyNDQ5IC0wLjY2ODE4NCwtMS4wMjUwOCAtMC4yMjUxNiwtMC45NDkwNiAtMC4xMjI2MzEsLTIuMzQwODIgMC4yMTQ0NzgsLTIuOTExNDcgMC4xOTM0MTQsLTAuMzI3MzkgMC40MzQ1MDUsLTAuNDYzNzMgMC44MjEyMDMsLTAuNDY0MzcgMC41ODU4MSwtOS44ZS00IDAuOTE5NDI3LDAuMzc2ODUgMS4wOTE3ODMsMS4yMzY0NCAwLjA5MDAyLDAuNDQ4OTUgMC4wODIwOSwxLjU3OTE5IC0wLjAxNDIxLDIuMDI1MDcgLTAuMTIyOTEyLDAuNTY5MTggLTAuMzY3NzYzLDAuOTY4MDggLTAuNjg5OTUsMS4xMjQwNSAtMC4xNzQwNjUsMC4wODQzIC0wLjU3NjY1NCwwLjA5MjQgLTAuNzU1MTM1LDAuMDE1NCB6IgogICAgICAgaWQ9InBhdGg1NyIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg3NCIKICAgICAgIGQ9Im0gMjguMzgyMDI1LDI3Mi4xNzk4NiBjIC0xLjMzMTU3OCwtMC4wNzY3IC0yLjIxMzE2MiwtMC43MDM4IC0yLjQwNTk3OCwtMS43MTE1NSAtMC4yMDczNDksLTEuMDgzNzEgMC4yMDcyMjQsLTIuMDEyNTEgMS4wODYzMywtMi40MzM3NyAwLjU1Mzk4NCwtMC4yNjU0NiAxLjAyMTE0NywtMC4zNDE3NSAxLjkzNjMzNiwtMC4zMTYyMiAwLjUyMTM1LDAuMDE0NSAwLjY3MjM0MiwwLjAzMSAwLjk1MzUyNywwLjEwMzk0IDEuMDkxODYyLDAuMjgzMTkgMS42NTQzMDksMC45MzgyNCAxLjcxMDg4OCwxLjk5MjU2IDAuMDQxNDIsMC43NzE4OCAtMC4yMTIwODgsMS4zOTYwMyAtMC43Mjc5NTYsMS43OTIyMyAtMC41ODk2ODksMC40NTI5MSAtMS40MTU5MzIsMC42MzgyOCAtMi41NTMxNDcsMC41NzI4MSB6IgogICAgICAgaWQ9InBhdGg1OSIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg3NCIKICAgICAgIGQ9Im0gMjEuNjAwMDQsMjcyLjE3OTg2IGMgLTEuMDc1NTIyLC0wLjA2MTkgLTEuODYxMjAzLC0wLjQ4NTc2IC0yLjIyMjY2NSwtMS4xOTkwMSAtMC4xNTcyNDgsLTAuMzEwMjkgLTAuMjExMDk5LC0wLjU2OTg1IC0wLjIxMDg1OCwtMS4wMTYzIDIuNThlLTQsLTAuNDc0OTggMC4wNTgxNiwtMC43NDc0NSAwLjIzMjM2MiwtMS4wOTMzNiAwLjMwNjU3NSwtMC42MDg3OCAwLjk0NjEwMiwtMC45OTQ3NiAxLjg2NzA3MywtMS4xMjY4NiAwLjMwMDYzOSwtMC4wNDMxIDEuMjAwOTI3LC0wLjA0MzMgMS41MDMzOTYsLTIuOWUtNCAwLjcwMjY3NiwwLjA5OTkgMS4xNTM3OTksMC4yOTcyNyAxLjUyMTAxLDAuNjY1NDQgMC4yNzkxODYsMC4yNzk5MiAwLjQxODQ5MywwLjUyODA4IDAuNTE2NjIsMC45MjAzMSAwLjA3NjI4LDAuMzA0OTEgMC4wNzg3MywwLjkxODAxIDAuMDA0OSwxLjIyNzc3IC0wLjI3NzczNSwxLjE2NTMyIC0xLjM5MDEsMS43MjcxOCAtMy4yMTE4MzksMS42MjIzIHoiCiAgICAgICBpZD0icGF0aDYxIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODc0IgogICAgICAgZD0ibSAxNi41NDY1NDUsMjcyLjExNTY5IGMgLTAuMTc3ODEsLTAuMDg4IC0wLjM4MTYyOCwtMC4zMTY1IC0wLjQ5Mzc1NCwtMC41NTM1MSAtMC4yMTg0ODgsLTAuNDYxODUgLTAuMzE3MjU1LC0xLjI2NDU2IC0wLjI1Mzg1NywtMi4wNjMxNyAwLjA5NjUyLC0xLjIxNTg1IDAuNDQ0OTYzLC0xLjc2NTA3IDEuMTIxNzI2LC0xLjc2ODA2IDAuNTQyNTg2LC0wLjAwMiAwLjg3NzU1NiwwLjMxNjc5IDEuMDUyNTAzLDEuMDAyOTQgMC4xNjg5MzIsMC42NjI1NiAwLjE3NTUwNiwxLjcyNDAzIDAuMDE0NzYsMi4zODMyNiAtMC4xMjYxMjQsMC41MTcyNSAtMC40MjY3OTUsMC45MzU1NyAtMC43Mzk4NTQsMS4wMjkzNyAtMC4yMTQ4OTEsMC4wNjQ0IC0wLjUzNzg1MSwwLjA1MDIgLTAuNzAxNTI1LC0wLjAzMDggeiIKICAgICAgIGlkPSJwYXRoNjMiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NzQiCiAgICAgICBkPSJtIDE3Ljk1ODQ4MSwyNjcuMTQwNjYgYyAtMC44NTczNDUsLTAuMDk3IC0xLjQ2MTM5OCwtMC4zNjUwNiAtMS45MTQ5MjksLTAuODQ5ODggLTAuMzQyNjUsLTAuMzY2MyAtMC41MDYwNDgsLTAuODE0MzUgLTAuNTA2MDQ4LC0xLjM4NzY0IDAsLTEuMjQ1MjUgMC44NDI4LC0yLjAzNDMyIDIuMzU0MTYsLTIuMjA0MDcgMC42NjM1ODMsLTAuMDc0NSAxLjUxMDgxNCwtMC4wMjcgMi4wNzY0MTgsMC4xMTY0NyAwLjUwNDI2OCwwLjEyNzkyIDAuODQ5NDM4LDAuMzEyMTQgMS4xNTA0MDcsMC42MTQgMC40MTU0MjgsMC40MTY2NCAwLjU2ODQ0OSwwLjgxMzY2IDAuNTY3OTY0LDEuNDczNiAtNC43NmUtNCwwLjY2MjEyIC0wLjE1MzE4NiwxLjA1ODEgLTAuNTY3OTY0LDEuNDcyODMgLTAuMzc4ODU3LDAuMzc4ODEgLTAuODM0ODM1LDAuNTg4NDYgLTEuNTU2Mzg1LDAuNzE1NTggLTAuMzYzMzQ2LDAuMDY0IC0xLjIzNTY3MywwLjA5MDcgLTEuNjAzNjIzLDAuMDQ5MSB6IgogICAgICAgaWQ9InBhdGg2NSIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg3NCIKICAgICAgIGQ9Im0gMjQuOTA3NTExLDI2Ny4xNTE1IGMgLTEuMjA3NDU5LC0wLjExMDE5IC0yLjAxMjA0MywtMC42MjY3MyAtMi4zMTE0NzMsLTEuNDgzOTQgLTAuMTA1MDU2LC0wLjMwMDc2IC0wLjE0MTQ5NiwtMC44NjAzNCAtMC4wNzkzMywtMS4yMTgxNSAwLjIwMTg4OSwtMS4xNjIgMS4yMDQ0NTgsLTEuNzg0MTEgMi44NzUyMjgsLTEuNzg0MTEgMC43NjY0MTEsMCAxLjMxOTk5LDAuMTA3MDMgMS44MzE3ODgsMC4zNTQxNiAwLjUyMTQ5OCwwLjI1MTgxIDAuODczMjI1LDAuNjc5MjIgMS4wMjc3NywxLjI0ODkxIDAuMDgwOTgsMC4yOTg1MiAwLjA4MTE4LDAuOTcwNjMgMi42NGUtNCwxLjI2NzE1IC0wLjIwNzg3OSwwLjc2Mjg3IC0wLjc2NDQ1MywxLjI2ODE5IC0xLjY0MDUyLDEuNDg5NDQgLTAuNDkzNzI3LDAuMTI0NjkgLTEuMTcyMDY2LDAuMTc1MDcgLTEuNzAzODQ5LDAuMTI2NTQgeiIKICAgICAgIGlkPSJwYXRoNjciCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NzQiCiAgICAgICBkPSJtIDMxLjY4OTQ5NywyNjcuMTU0ODkgYyAtMC45MTU1MDEsLTAuMDkzNSAtMS41MDUyNDYsLTAuMzE5NzUgLTEuOTczNTQ1LC0wLjc1NzA5IC0wLjE5NjU4NSwtMC4xODM1OSAtMC4yNzYxMTQsLTAuMjg4NDIgLTAuMzgyNDA4LC0wLjUwNDA4IC0wLjIyNzUyMiwtMC40NjE2MiAtMC4yODgwNDUsLTAuOTU5NDQgLTAuMTgwNTI0LC0xLjQ4NDc3IDAuMDgyMjUsLTAuNDAxODQgMC4yMTk2MjksLTAuNjUwNDcgMC41MzAxOTYsLTAuOTU5NTggMC41MjQ2NDQsLTAuNTIyMTkgMS4xMzQ5NjMsLTAuNzMyNzEgMi4yNDAxNDEsLTAuNzcyNyAxLjMwNzcxNSwtMC4wNDczIDIuMjE3NDE5LDAuMTk1ODcgMi43NjY1MDYsMC43Mzk1NyAwLjM4NDE2NSwwLjM4MDQxIDAuNTY0ODYsMC44NDIyMyAwLjU2ODY5MiwxLjQ1MzQ5IDAuMDAyNywwLjQzNTggLTAuMDQ3MTksMC42NzYwMyAtMC4yMTIyLDEuMDIxMTMgLTAuMTAxOTU3LDAuMjEzMjQgLTAuMTc5ODUzLDAuMzE3OTEgLTAuMzczNDEzLDAuNTAxNzcgLTAuMTM0NTE5LDAuMTI3NzggLTAuMzMxNTY4LDAuMjgxNDIgLTAuNDM3ODgzLDAuMzQxNDIgLTAuMjUxNTk0LDAuMTQxOTkgLTAuNjk4ODE4LDAuMjkwNTIgLTEuMDc1NzIxLDAuMzU3MjYgLTAuMjkyMzA3LDAuMDUxOCAtMS4yMDA4MTMsMC4wOTExIC0xLjQ2OTg0MSwwLjA2MzYgeiIKICAgICAgIGlkPSJwYXRoNjkiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NzQiCiAgICAgICBkPSJtIDE1LjUxODA3NCwyNjAuOTk5MjUgYyAtMC40MTI1MTcsLTAuNDg2NjQgLTAuNzQ1ODQ1LC0wLjg4ODk4IC0wLjc0MDcyNywtMC44OTQxIDAuMDE3ODMsLTAuMDE3OCAxLjIxNTE4MiwtMC4yMTA5MSAxLjkyODMwNCwtMC4zMTA5NSAxLjk4MTkyMSwtMC4yNzgwMiA0LjA1NzI1NSwtMC40NTU0OCA2LjMxMzU1NSwtMC41Mzk4NiAxLjMyMDA1NiwtMC4wNDk0IDQuNzUxNjc3LC0wLjAyMSA1Ljk2NDE3OSwwLjA0OTMgMi40NTkzODQsMC4xNDI1NyA0LjkxMDI5NywwLjQxMzc4IDYuODU3MTM5LDAuNzU4ODEgbCAwLjIwODc4NSwwLjAzNyAtMC4wOTY0NiwwLjEyMTcyIGMgLTAuMDUzMDUsMC4wNjY5IC0wLjM3MjUxOCwwLjQ2Nzg4IC0wLjcwOTkxOSwwLjg5MDk3IGwgLTAuNjEzNDU3LDAuNzY5MjYgLTAuNzM0OTkzLC0wLjEwNjE3IGMgLTEuODI2NDg4LC0wLjI2MzgzIC0zLjgwMjc2MywtMC40MzMwNiAtNi4wMzAyODksLTAuNTE2MzYgLTEuMTk1MjAzLC0wLjA0NDcgLTQuODY5MDE4LC0wLjAyMzEgLTUuODEzMTMsMC4wMzQyIC0yLjE1ODYyNiwwLjEzMDk3IC0zLjgzOTM2OCwwLjI5NjY5IC01LjM4ODc4NCwwLjUzMTMgbCAtMC4zOTQxNywwLjA1OTcgeiIKICAgICAgIGlkPSJwYXRoNzEiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NzQiCiAgICAgICBkPSJtIDEyLjczMDAwNCwyNTQuNDc5NjMgdiAtMy4xNDA0MiBoIDEuMjUyNTMgMS4yNTI1MjkgbCAwLjAwODcsMS43Mjg5IDAuMDA4NywxLjcyODkgNC4yNTEyNywwLjAwOCA0LjI1MTI2OCwwLjAwOCB2IC0xLjcyMDY4IC0xLjcyMDY3IGggMS42NTM3MzcgMS42NTM3MzMgdiAxLjcyMDU1IDEuNzIwNTQgaCA0LjI1OTYyMiA0LjI1OTYyMyB2IC0xLjczNzI1IC0xLjczNzI1IGggMS4yNTI4MyAxLjI1MjgzIHYgMy4xNDI4MiAzLjE0MjgyIGwgLTAuMTc1Mzk5LC0wLjAxOTMgYyAtMC43NjY3MjcsLTAuMDg0NCAtNC4yNjcyOTIsLTAuMzA1MzggLTYuMTIyMTYsLTAuMzg2NTMgLTIuMDYwMDM3LC0wLjA5MDEgLTIuNzIzNDA3LC0wLjEwNTM2IC01LjM2MjExMSwtMC4xMjMxNSAtNC4xNTQwOTYsLTAuMDI4IC01Ljc4MTU2MywwLjAzMTEgLTEyLjYwMzY3NywwLjQ1NzgyIC0wLjU4MzUxNiwwLjAzNjUgLTEuMDY4MzYyLDAuMDY2MyAtMS4wNzc0MzUsMC4wNjYzIC0wLjAwOTEsMCAtMC4wMTY1LC0xLjQxMzE4IC0wLjAxNjUsLTMuMTQwNDEgeiIKICAgICAgIGlkPSJwYXRoNzMiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogIDwvZz4KPC9zdmc+Cg=='); } -body.base .is2d piece.queen.white { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMTQ0cHQiCiAgIGhlaWdodD0iMTQ0cHQiCiAgIHZpZXdCb3g9IjAgMCA1MC44MDAwMDEgNTAuOCIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnOCIKICAgc29kaXBvZGk6ZG9jbmFtZT0id3Euc3ZnIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkyLjMgKDI0MDU1NDYsIDIwMTgtMDMtMTEpIj4KICA8ZGVmcwogICAgIGlkPSJkZWZzMiIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9ImJhc2UiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEuMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6em9vbT0iNy45MTk1OTU5IgogICAgIGlua3NjYXBlOmN4PSI4My41MzQ4NiIKICAgICBpbmtzY2FwZTpjeT0iMTAyLjIyMjciCiAgICAgaW5rc2NhcGU6ZG9jdW1lbnQtdW5pdHM9Im1tIgogICAgIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9ImxheWVyMSIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgdW5pdHM9InB0IgogICAgIGlua3NjYXBlOndpbmRvdy13aWR0aD0iMzg0MCIKICAgICBpbmtzY2FwZTp3aW5kb3ctaGVpZ2h0PSIyMDM1IgogICAgIGlua3NjYXBlOndpbmRvdy14PSItMTMiCiAgICAgaW5rc2NhcGU6d2luZG93LXk9Ii0xMyIKICAgICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPSIxIiAvPgogIDxtZXRhZGF0YQogICAgIGlkPSJtZXRhZGF0YTUiPgogICAgPHJkZjpSREY+CiAgICAgIDxjYzpXb3JrCiAgICAgICAgIHJkZjphYm91dD0iIj4KICAgICAgICA8ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD4KICAgICAgICA8ZGM6dHlwZQogICAgICAgICAgIHJkZjpyZXNvdXJjZT0iaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2UiIC8+CiAgICAgICAgPGRjOnRpdGxlIC8+CiAgICAgIDwvY2M6V29yaz4KICAgIDwvcmRmOlJERj4KICA8L21ldGFkYXRhPgogIDxnCiAgICAgaW5rc2NhcGU6bGFiZWw9IkxheWVyIDEiCiAgICAgaW5rc2NhcGU6Z3JvdXBtb2RlPSJsYXllciIKICAgICBpZD0ibGF5ZXIxIgogICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAsLTI0Ni4yKSI+CiAgICA8ZwogICAgICAgYXJpYS1sYWJlbD0icSIKICAgICAgIHN0eWxlPSJmb250LXN0eWxlOm5vcm1hbDtmb250LXZhcmlhbnQ6bm9ybWFsO2ZvbnQtd2VpZ2h0Om5vcm1hbDtmb250LXN0cmV0Y2g6bm9ybWFsO2ZvbnQtc2l6ZTo1MC43OTk5OTkyNHB4O2xpbmUtaGVpZ2h0OjEuMjU7Zm9udC1mYW1pbHk6J0NoZXNzIExlaXB6aWcnOy1pbmtzY2FwZS1mb250LXNwZWNpZmljYXRpb246J0NoZXNzIExlaXB6aWcnO2xldHRlci1zcGFjaW5nOjBweDt3b3JkLXNwYWNpbmc6MHB4O2ZpbGw6IzAwMDAwMDtmaWxsLW9wYWNpdHk6MTtzdHJva2U6bm9uZTtzdHJva2Utd2lkdGg6MC4yNjQ1ODMzMiIKICAgICAgIGlkPSJ0ZXh0MTY4IgogICAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTAuMDk2ODkzOCwwLjAzODA0KSI+CiAgICAgIDxwYXRoCiAgICAgICAgIGQ9Im0gMTUuMjc5Njg4LDI3My41ODQzOCBxIC0wLjY5NDUzMiwtMC41OTUzMiAtMi4xMzMyMDMsLTIuMzU2NDUgLTIuNTA1Mjc0LC0yLjgyNzczIC0yLjgwMjkzLC0yLjgyNzczIC0wLjI0ODA0NywwIC0wLjI0ODA0NywwLjM0NzI2IDAsMC40NDY0OSAwLjc5Mzc1LDEuODEwNzQgMC42OTQ1MzEsMS45NTk1NyAxLjE0MTAxNiwzLjU5NjY4IDEuMTE2MjExLC0wLjIyMzI0IDMuMjQ5NDE0LC0wLjU3MDUgeiBtIDUuODUzOTA2LC0wLjQ5NjEgcSAtMC42NDQ5MjIsLTAuNTQ1NyAtMS4yNDAyMzUsLTEuODEwNzQgLTAuNzE5MzM1LC0xLjQ2MzQ4IC0xLjczNjMyOCwtNC41MzkyNiAtMC4zOTY4NzUsLTEuMjE1NDMgLTAuNzQ0MTQsLTIuMDU4NzkgLTAuMzQ3MjY2LC0wLjg0MzM2IC0wLjQ5NjA5NCwtMC44MTg1NSAtMC4wNzQ0MSwwLjAyNDggLTAuMDc0NDEsMC4zOTY4NyAwLjAyNDgsMC4zNzIwNyAwLjAyNDgsMC41OTUzMiAwLDAuNjY5NzIgMC42MjAxMTcsMy4zOTgyNCAwLjU5NTMxMiwyLjgyNzczIDAuNTk1MzEyLDQuMDQzMTYgMC4wMjQ4MSwwLjc0NDE0IC0wLjE0ODgyOCwxLjA2NjYgMS4yODk4NDQsLTAuMTczNjMgMy4xOTk4MDUsLTAuMjcyODUgeiBtIDYuMzc0ODA0LC0wLjA3NDQgcSAtMC43MTkzMzYsLTAuODE4NTYgLTAuOTQyNTc4LC0yLjc1MzMyIC0wLjA5OTIyLC0wLjc2ODk1IC0wLjI3Mjg1MSwtMi4yMDc2MiAtMC4xNDg4MjgsLTEuNDYzNDggLTAuMjIzMjQyLC0zLjYyMTQ4IC0wLjA3NDQyLC0xLjU2MjcgLTAuMjQ4MDQ3LC0yLjcwMzcyIC0wLjE3MzYzMywtMS4xNDEwMSAtMC4zNDcyNjYsLTEuMTkwNjIgLTAuMTk4NDM3LDAuMDQ5NiAtMC4zNDcyNjYsMS4xOTA2MiAtMC4xMjQwMjMsMS4xNDEwMiAtMC4xOTg0MzcsMi43MDM3MiAtMC4xMjQwMjMsMi4xNTggLTAuMjk3NjU2LDMuNjIxNDggLTAuMTczNjMzLDEuNDM4NjcgLTAuMjQ4MDQ3LDIuMjA3NjIgLTAuMjIzMjQyLDIuMDgzNTkgLTAuOTQyNTc4LDIuNzUzMzIgMC40OTYwOTMsMCAwLjk5MjE4NywtMC4wNzQ0IDAuNTIwODk5LC0wLjA5OTIgMS4wNDE3OTcsLTAuMDk5MiAwLjUyMDg5OCwwIDEuMDE2OTkyLDAuMDk5MiAwLjUyMDg5OSwwLjA3NDQgMS4wMTY5OTIsMC4wNzQ0IHogbSA1LjUzMTQ0NiwwLjMyMjQ2IHEgLTAuMTczNjMzLC0wLjM3MjA3IC0wLjE3MzYzMywtMS4wNDE4IDAsLTEuMjY1MDQgMC42MjAxMTcsLTQuMDQzMTYgMC41OTUzMTIsLTIuNzc4MTMgMC41OTUzMTIsLTMuMzk4MjQgMCwtMC43OTM3NSAtMC4wMjQ4LC0wLjgxODU2IC0wLjM0NzI2NiwtMC4wNzQ0IC0xLjI2NTAzOSwyLjcwMzcxIC0wLjk0MjU3OCwyLjg3NzM1IC0xLjczNjMyOCw0LjUzOTI2IC0wLjU3MDUwOCwxLjE5MDYyIC0xLjIxNTQzLDEuODM1NTUgMS4xNjU4MiwwLjA0OTYgMy4xOTk4MDUsMC4yMjMyNCB6IG0gNS45NTMxMjUsMC44MTg1NSBxIDAuMjIzMjQyLC0wLjkxNzc3IDAuNDk2MDkzLC0xLjgxMDc0IDAuMjk3NjU3LC0wLjkxNzc3IDAuNTk1MzEzLC0xLjgxMDc0IDAuNzkzNzUsLTEuNDYzNDggMC43OTM3NSwtMS43ODU5NCAwLC0wLjM0NzI2IC0wLjI0ODA0NywtMC4zNDcyNiAtMC4zOTY4NzUsMCAtMi44MDI5MywyLjgwMjkzIC0wLjc0NDE0LDAuODY4MTYgLTEuMjY1MDM5LDEuNDg4MjggLTAuNTIwODk4LDAuNTk1MzEgLTAuODY4MTY0LDAuOTQyNTcgMS42ODY3MTksMC4yMjMyNSAzLjI5OTAyNCwwLjUyMDkgeiBNIDYuNTk4MDQ3MiwyNjEuNDMwMDggcSAtMS42NjE5MTQxLDAgLTEuNjYxOTE0MSwxLjY2MTkxIDAsMS42ODY3MiAxLjY2MTkxNDEsMS42ODY3MiAxLjY4NjcxODcsMCAxLjY4NjcxODcsLTEuNjg2NzIgMCwtMS42NjE5MSAtMS42ODY3MTg3LC0xLjY2MTkxIHogbSAyMC4wOTE3OTY4LC02LjEwMTk1IHEgMC4zNzIwNyw0LjAxODM1IDAuNzQ0MTQsOC4wMzY3MSAwLjM5Njg3NSwzLjk5MzU2IDAuNzkzNzUsNy45ODcxMSAwLjAyNDgsMC41NzA1MSAwLjU3MDUwOCwwLjU3MDUxIDAuMzk2ODc1LC0wLjAyNDggMC41NDU3MDMsLTAuMzQ3MjYgMi4xNTgwMDgsLTUuMjA4OTkgMy4xNzUsLTguMDYxNTMgMS4wNDE3OTcsLTIuODc3MzQgMS4yNjUwMzksLTMuNTQ3MDcgLTEuMTQxMDE1LC0xLjA5MTQgLTEuMTQxMDE1LC0yLjQ1NTY2IDAsLTEuMTkwNjMgMC44NDMzNTksLTIuMDMzOTkgMC44NjgxNjQsLTAuODY4MTYgMi4wODM1OTQsLTAuODY4MTYgMS4xOTA2MjUsMCAyLjAzMzk4NCwwLjg2ODE2IDAuODY4MTY0LDAuODQzMzYgMC44NjgxNjQsMi4wMzM5OSAwLDIuMTU4MDEgLTIuMjMyNDIyLDIuOTI2OTUgbCAtMS44MTA3NDIsMTAuODE0ODQgcSAtMC4xMjQwMjMsMC43NDQxNSAwLjUyMDg5OSwwLjc0NDE1IDAuNTIwODk4LDAgMC43OTM3NSwtMC4yNzI4NiAyLjk3NjU2MiwtMi45NzY1NiA0LjI2NjQwNiwtNC42MTM2NyAxLjMxNDY0OCwtMS42MzcxMSAxLjgzNTU0NywtMi4yODIwMyAtMC41NDU3MDQsLTAuNzE5MzQgLTAuNTQ1NzA0LC0xLjczNjMzIDAsLTIuOTAyMTUgMi45MDIxNDksLTIuOTAyMTUgMS4xOTA2MjUsMCAyLjAzMzk4NCwwLjg2ODE3IDAuODY4MTY0LDAuODQzMzYgMC44NjgxNjQsMi4wMzM5OCAwLDEuMjE1NDMgLTAuODY4MTY0LDIuMDU4NzkgLTAuODQzMzU5LDAuODQzMzYgLTIuMDMzOTg0LDAuODQzMzYgLTAuMzcyMDcsMCAtMC42Njk3MjcsLTAuMDc0NCAtMS45ODQzNzUsNC4yOTEyMSAtMy4xNzUsOC43ODA4NiAtMS4wMTY5OTIsMy42NDYyOSAtMS4yNjUwMzksNi45MjA1IDAuMTQ4ODI4LDAuNjk0NTQgMC4xNzM2MzMsMC43MTkzNCAtMC4wNzQ0MSwtMC4yOTc2NiAwLjA5OTIyLDAuNTcwNTEgMC4wOTkyMiwwLjM5Njg3IDAuMDk5MjIsMC43Njg5NCAtMC4xNDg4MjksMC4zOTY4OCAtMC42MjAxMTgsMC44OTI5NyAtMC40MjE2NzksMC40NzEyOSAtMC42MjAxMTcsMS44NjAzNSAwLjkxNzc3NCwxLjI4OTg1IDAuOTE3Nzc0LDIuMDgzNiAwLDIuMDgzNTkgLTQuMDE4MzYsMy41NzE4NyAtNC4wMTgzNTksMS40ODgyOCAtOS42NDkwMjMsMS40ODgyOCAtNS42NTU0NjksMCAtOS42NzM4MjgsLTEuNDg4MjggLTMuOTkzNTU1LC0xLjQ4ODI4IC0zLjk5MzU1NSwtMy41NzE4NyAwLC0wLjgxODU2IDAuOTY3MzgzLC0yLjEzMzIxIC0wLjI5NzY1NiwtMS40MTM4NiAtMC42NDQ5MjIsLTEuODEwNzQgLTAuNDk2MDkzLC0wLjQ5NjA5IC0wLjY0NDkyMSwtMC44OTI5NyAwLC0wLjMyMjQ2IDAuMDc0NDEsLTAuNzQ0MTQgMC4wNDk2MSwtMC4xOTg0NCAwLjA3NDQxLC0wLjM0NzI2IDAuMDI0OCwtMC4xNzM2NCAwLjA0OTYxLC0wLjI0ODA1IDAuMDk5MjIsLTAuMjcyODUgMC4xOTg0MzgsLTAuNzY4OTUgLTAuMjQ4MDQ3LC0zLjEyNTM5IC0xLjIxNTQzLC02Ljg3MDg5IC0xLjI4OTg0MzksLTQuNzEyODkgLTMuMTk5ODA0OCwtOC44MzA0NyAtMC40MjE2Nzk3LDAuMTI0MDIgLTAuODY4MTY0LDAuMTI0MDIgLTIuOTAyMTQ4NCwwIC0yLjkwMjE0ODQsLTIuOTAyMTUgMCwtMi45MDIxNSAyLjkwMjE0ODQsLTIuOTAyMTUgMi45MDIxNDgzLDAgMi45MDIxNDgzLDIuOTAyMTUgMCwwLjg5Mjk3IC0wLjQ0NjQ4NDMsMS42MTIzMSAxLjQ2MzQ3NjgsMS44NjAzNSAyLjkyNjk1MjgsMy40NzI2NSAxLjQ4ODI4MSwxLjU4NzUgMy4yNzQyMTksMy40OTc0NiAwLjIyMzI0MiwwLjMyMjQ3IDAuNjQ0OTIyLDAuMzIyNDcgMC43MTkzMzYsMCAwLjY0NDkyMiwtMC43NDQxNSAtMC4wNDk2MSwtMC4yMjMyNCAtMC42MjAxMTcsLTMuNTQ3MDcgLTAuNTcwNTA4LC0zLjMyMzgyIC0xLjI0MDIzNSwtNy4yNDI5NiAtMi4zNTY0NDUsLTAuNjQ0OTMgLTIuMzU2NDQ1LC0yLjk1MTc2IDAsLTEuMTkwNjMgMC44NDMzNTksLTIuMDMzOTkgMC44NjgxNjQsLTAuODY4MTYgMi4wNTg3ODksLTAuODY4MTYgMi45MDIxNDksMCAyLjkwMjE0OSwyLjkwMjE1IDAsMS4yODk4NCAtMC45OTIxODgsMi4zNTY0NCAwLjEyNDAyNCwwLjUyMDkgMC42MjAxMTcsMi4wODM2IDAuNDk2MDk0LDEuNTM3ODkgMS41Mzc4OTEsNC4wNjc5NyAwLjU3MDUwOCwxLjM4OTA2IDEuMTQxMDE2LDIuODAyOTMgMC41OTUzMTIsMS4zODkwNiAxLjE5MDYyNSwyLjc1MzMyIDAuMTQ4ODI4LDAuMzIyNDYgMC41MjA4OTgsMC4zMjI0NiAwLjUyMDg5OCwtMC4wMjQ4IDAuNTk1MzEyLC0wLjU0NTcxIDAuMDQ5NjEsLTAuMjk3NjUgMS41MTMwODYsLTE1Ljk5OTAyIC0xLjc2MTEzMiwtMC45NDI1OCAtMS43NjExMzIsLTIuODAyOTMgMCwtMS4xOTA2MiAwLjg0MzM1OSwtMi4wNTg3OSAwLjg0MzM1OSwtMC44NjgxNiAyLjA1ODc4OSwtMC44NjgxNiAxLjE5MDYyNSwwIDIuMDMzOTg0LDAuODY4MTYgMC44NjgxNjQsMC44NjgxNyAwLjg2ODE2NCwyLjA1ODc5IDAsMS42ODY3MiAtMS42MTIzMDQsMi43NzgxMyB6IG0gLTYuNjk3MjY2LDI1LjY0ODA0IHEgLTEuMzE0NjQ4LDAgLTEuMzE0NjQ4LDEuMzg5MDYgMCwxLjM4OTA3IDEuMzE0NjQ4LDEuMzg5MDcgMS4zMzk0NTMsMCAxLjMzOTQ1MywtMS4zODkwNyAwLC0xLjM4OTA2IC0xLjMzOTQ1MywtMS4zODkwNiB6IG0gLTcuNTY1NDI5LC00Ljk2MDk0IHEgMC4yOTc2NTYsMS4yMTU0MyAwLjUyMDg5OCwyLjIwNzYyIDAuMjQ4MDQ3LDAuOTY3MzggMC40MjE2OCwyLjEwODQgMC4xOTg0MzcsMC4wOTkyIDAuNDQ2NDg0LDAuMDk5MiA0LjQxNTIzNCwtMS42NjE5MiAxMS42MzMzOTgsLTEuNjYxOTIgNy4zMTczODMsMCAxMS44MzE4MzYsMS42ODY3MiAwLjI0ODA0NywtMC4wNDk2IDAuMzcyMDcsLTAuMTI0MDIgMC4xNDg4MjksLTEuMTE2MjEgMC4zOTY4NzUsLTIuMDMzOTggMC4yNDgwNDcsLTAuOTQyNTggMC41NDU3MDQsLTIuMTgyODIgLTIuODI3NzM1LC0wLjc5Mzc1IC02LjE3NjM2OCwtMS4zMTQ2NCAtMy4zNDg2MzIsLTAuNTQ1NzEgLTYuOTQ1MzEyLC0wLjU0NTcxIC0zLjU5NjY4LDAgLTYuODcwODk4LDAuNTIwOSAtMy4yNzQyMTksMC41MjA5IC02LjE3NjM2NywxLjI0MDIzIHogbSAyNC45MDM5MDYsNy41MTU4MiAtMS43ODU5MzgsLTEuNzExNTIgLTIuMjgyMDMxLDAuOTE3NzcgMS44MTA3NDIsMS43MTE1MyB6IG0gLTguNzA2NDQ2LC0xLjc2MTEzIC0zLjE5OTgwNCwtMS42NjE5MSAtMy4wNzU3ODIsMS42NjE5MSAzLjE5OTgwNSwxLjY4NjcyIHogbSAtMTAuNzE1NjI1LDAuOTkyMTkgLTIuNTA1MjczLC0wLjg0MzM2IC0xLjk4NDM3NSwxLjU2MjcgMi40ODA0NjksMC44NDMzNSB6IG0gMjYuMjkyOTY5LC0yMS4zMzIwMyBxIC0xLjY4NjcxOSwwIC0xLjY4NjcxOSwxLjY2MTkxIDAsMS42ODY3MiAxLjY4NjcxOSwxLjY4NjcyIDEuNjYxOTE0LDAgMS42NjE5MTQsLTEuNjg2NzIgMCwtMS42NjE5MSAtMS42NjE5MTQsLTEuNjYxOTEgeiBtIC0yOC45NzE4NzUsLTUuNjA1ODYgcSAtMS42NjE5MTQsMCAtMS42NjE5MTQsMS42ODY3MiAwLDEuNjYxOTEgMS42NjE5MTQsMS42NjE5MSAxLjY4NjcxOSwwIDEuNjg2NzE5LC0xLjY2MTkxIDAsLTEuNjg2NzIgLTEuNjg2NzE5LC0xLjY4NjcyIHogTSAyNS40LDI1MC44NjMyOCBxIC0xLjY2MTkxNCwwIC0xLjY2MTkxNCwxLjY4NjcyIDAsMS42NjE5MSAxLjY2MTkxNCwxLjY2MTkxIDEuNjYxOTE0LDAgMS42NjE5MTQsLTEuNjYxOTEgMCwtMS42ODY3MiAtMS42NjE5MTQsLTEuNjg2NzIgeiBtIDEwLjE2OTkyMiw0Ljk2MDk0IHEgLTEuNjg2NzE5LDAgLTEuNjg2NzE5LDEuNjg2NzIgMCwxLjY2MTkxIDEuNjg2NzE5LDEuNjYxOTEgMS42NjE5MTQsMCAxLjY2MTkxNCwtMS42NjE5MSAwLC0xLjY4NjcyIC0xLjY2MTkxNCwtMS42ODY3MiB6IG0gLTQuNjM4NDc3LDI1LjE1MTk1IHEgLTEuMzE0NjQ4LDAgLTEuMzE0NjQ4LDEuMzg5MDYgMCwxLjM4OTA3IDEuMzE0NjQ4LDEuMzg5MDcgMS4zMzk0NTMsMCAxLjMzOTQ1MywtMS4zODkwNyAwLC0xLjM4OTA2IC0xLjMzOTQ1MywtMS4zODkwNiB6IG0gLTUuNDU3MDMxLDQuNDQwMDQgcSAtNC43MTI4OSwwIC04LjAxMTkxNCwwLjcxOTM0IC0zLjI3NDIxOSwwLjcxOTMzIC0zLjI3NDIxOSwyLjA1ODc5IDAsMS4zODkwNiAzLjI3NDIxOSwyLjIzMjQyIDMuMjk5MDI0LDAuODQzMzYgOC4wMTE5MTQsMC44NDMzNiA0LjY4ODA4NiwwIDguMDYxNTIzLC0wLjg0MzM2IDMuMzk4MjQzLC0wLjg0MzM2IDMuMzk4MjQzLC0yLjIzMjQyIDAsLTEuMzM5NDYgLTMuMzk4MjQzLC0yLjA1ODc5IC0zLjM3MzQzNywtMC43MTkzNCAtOC4wNjE1MjMsLTAuNzE5MzQgeiIKICAgICAgICAgc3R5bGU9InN0cm9rZS13aWR0aDowLjI2NDU4MzMyIgogICAgICAgICBpZD0icGF0aDE3MCIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDwvZz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAyMy40OTUwNjUsMjkxLjI1OTA1IGMgLTMuOTIxOTQzLC0wLjE3MjEgLTcuMTQwNzA0LC0wLjg0MDM3IC04LjU1MTgyLC0xLjc3NTQ4IC0wLjgxNzMzLC0wLjU0MTYzIC0xLjA1MTI0OCwtMS4yODA1IC0wLjYwMzM5NSwtMS45MDU5MSAwLjczMTY3MSwtMS4wMjE3NyAzLjYyMTQwMywtMS43NDg0OSA4LjA4NjEzNywtMi4wMzM1MyAwLjg4Mzk5NiwtMC4wNTY0IDQuMDQwMDM5LC0wLjA3NzcgNS4wNjE0MTUsLTAuMDM0MiAyLjQ3NzgsMC4xMDU2OSA0LjM1MzU3OSwwLjMyNzE5IDYuMTQ2ODA4LDAuNzI1ODIgMS42OTQyNjgsMC4zNzY2NCAyLjcxNjMsMC44ODUzNyAzLjA1OTM4OCwxLjUyMjg1IDAuMTAxMzI1LDAuMTg4MjggMC4xMTMyMDIsMC4yMzgxIDAuMTEzODI2LDAuNDc3NDggNS4zZS00LDAuMjI0ODcgLTAuMDEzOTIsMC4yOTcwNiAtMC4wOTEzNywwLjQ1NTA2IC0wLjE5NzU0OCwwLjQwMjk0IC0wLjU3NzY4MywwLjcyMzk2IC0xLjI0Mzk3LDEuMDUwNTMgLTAuNjMyMjYxLDAuMzA5ODkgLTEuMTMxNzQyLDAuNDc5OSAtMi4xNDg5MDEsMC43MzE0MyAtMS41MTQzNjEsMC4zNzQ0OCAtMy4yNzc4NDYsMC42MjEzOCAtNS4zODQ3NTcsMC43NTM4OCAtMC43NDI2NzIsMC4wNDY3IC0zLjYzNDA5NCwwLjA2NzYgLTQuNDQzMzU3LDAuMDMyMSB6IgogICAgICAgaWQ9InBhdGgxNzMiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDE5LjQ2NTQyNiwyODMuNzMxMTEgYyAtMC4yMTY4MDIsLTAuMDU1NSAtMC40NDcxNTgsLTAuMTg5ODkgLTAuNTY1ODc1LC0wLjMzMDI2IC0wLjQyMDQ1NywtMC40OTcxNSAtMC4zOTUwOCwtMS42MTU0MSAwLjA0NjI4LC0yLjAzOTUyIDAuMjYxMDI0LC0wLjI1MDgyIDAuNTY5NTEzLC0wLjM0MTk4IDEuMDc0OTE2LC0wLjMxNzY0IDAuNzA2NDYyLDAuMDM0IDEuMDgzMDcsMC4zODE2MSAxLjE3NzcwNSwxLjA4Njk3IDAuMTAxNDkzLDAuNzU2NDcgLTAuMTY2MTA4LDEuMzQzNjIgLTAuNzA1MjYsMS41NDc0MiAtMC4yMzcxMywwLjA4OTYgLTAuNzc1OTIsMC4xMTc0NCAtMS4wMjc3NzEsMC4wNTMgeiIKICAgICAgIGlkPSJwYXRoMTc1IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAyMy44ODY1NSwyODIuNjUwNTIgYyAtMC44NTg0MzQsLTAuNDUxOTkgLTEuNTYwNzg5LC0wLjgzMTMyIC0xLjU2MDc4OSwtMC44NDI5NSAwLC0wLjAxMTYgMC42NzU3MjEsLTAuMzg1OTEgMS41MDE2MDIsLTAuODMxNzEgbCAxLjUwMTYwMSwtMC44MTA1NiAxLjUzMDIzOCwwLjc5MTY0IGMgMC44NDE2MjksMC40MzU0MSAxLjU0ODQsMC44MDgwOSAxLjU3MDYwMSwwLjgyODE3IDAuMDM3MjEsMC4wMzM3IC0wLjgzNTU2MiwwLjUzMDU3IC0yLjYyODcxNywxLjQ5NjYzIGwgLTAuMzUzNzQ4LDAuMTkwNTggeiIKICAgICAgIGlkPSJwYXRoMTc3IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAzMC40NTMwODMsMjgzLjc0MDgyIGMgLTAuNDczMTg3LC0wLjA5MzQgLTAuNzc4MjkxLC0wLjQxNTEyIC0wLjg3ODk3MywtMC45MjY4OCAtMC4wNTE2OCwtMC4yNjI2OSAtMC4wMjUyMSwtMC44MDA4MyAwLjA1MDQ4LC0xLjAyNjQzIDAuMTY2Mzg2LC0wLjQ5NTg1IDAuNTczODQ1LC0wLjc0OTY2IDEuMjA1MDExLC0wLjc1MDU5IDAuNTE4NjQ3LC03LjllLTQgMC44NzY2OTQsMC4xNTI4NyAxLjA5MTk3OCwwLjQ2ODU3IDAuMTU5OCwwLjIzNDMzIDAuMjI2NDMzLDAuNDk5NiAwLjIyNTkzNSwwLjg5OTQ2IC0wLjAwMTEsMC43Njc4IC0wLjMwMjMxOCwxLjIwMDcgLTAuOTI4MzM4LDEuMzMzNTIgLTAuMjAwOTAxLDAuMDQyNiAtMC41NTY1MDEsMC4wNDM3IC0wLjc2NjA5OCwwLjAwMiB6IgogICAgICAgaWQ9InBhdGgxNzkiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDM0LjA4NTA0NCwyODMuNjIwNjkgYyAtMC40NzgwNDEsLTAuNDUyOTQgLTAuODYwODEzLC0wLjgzMTg3IC0wLjg1MDYwNiwtMC44NDIwOCAwLjAxMDIxLC0wLjAxMDIgMC41MDk4ODcsLTAuMjE3MDMgMS4xMTAzOTgsLTAuNDU5NiBsIDEuMDkxODM4LC0wLjQ0MTAzIDAuNDE4NjA4LDAuMzk2NjMgYyAwLjIzMDIzNSwwLjIxODE0IDAuNjI4MTA3LDAuNTk3MDUgMC44ODQxNiwwLjg0MjAxIGwgMC40NjU1NTYsMC40NDUzOSAtMS4wODM2MTQsMC40NDE1IGMgLTAuNTk1OTksMC4yNDI4MiAtMS4xMDI0MTYsMC40NDEzMiAtMS4xMjUzOTUsMC40NDExIC0wLjAyMjk3LC0yLjJlLTQgLTAuNDMyOTAzLC0wLjM3MDk4IC0wLjkxMDk0NSwtMC44MjM5MiB6IgogICAgICAgaWQ9InBhdGgxODEiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDE0LjYxMTgzLDI4My45NDQ5NyBjIC0wLjYzMjAxOCwtMC4yMTU5MiAtMS4xNjgzODUsLTAuNDA2MTUgLTEuMTkxOTI4LC0wLjQyMjc0IC0wLjAzMDU4LC0wLjAyMTUgMC4yMzMxMTYsLTAuMjQ2NTEgMC45MjMxMzIsLTAuNzg3NTMgbCAwLjk2NTkzNSwtMC43NTczNyAxLjIxOTk4NiwwLjQwNjMyIGMgMC42NzA5OTIsMC4yMjM0OCAxLjIxNjE1NCwwLjQxNzgyIDEuMjExNDcxLDAuNDMxODcgLTAuMDEwODgsMC4wMzI2IC0xLjkzNDg2OCwxLjUyOTU2IC0xLjk2MDM5MywxLjUyNTI0IC0wLjAxMDQ5LC0wLjAwMiAtMC41MzYxODUsLTAuMTc5ODggLTEuMTY4MjAzLC0wLjM5NTc5IHoiCiAgICAgICBpZD0icGF0aDE4MyIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMzYuNTYyNzY5LDI4MC4yNjQyOSBjIC0xLjg4NTI0LC0wLjY0MDg2IC00LjE2MDU0MSwtMS4wNzMzOSAtNi44MjAyNzgsLTEuMjk2NTQgLTEuNTc3MzA1LC0wLjEzMjMzIC0yLjE3MjI0LC0wLjE1MjkxIC00LjQwOTk0OCwtMC4xNTI1MyAtMi4xNTc3ODIsMi43ZS00IC0yLjU2MDY0MywwLjAxMzYgLTQuMTI1OTczLDAuMTM1ODggLTIuNzE2MzAxLDAuMjEyMTMgLTUuMjg4NDI3LDAuNzA2NDEgLTcuMTEzMDE5LDEuMzY2ODkgLTAuMzMxNDA1LDAuMTE5OTYgLTAuNTM0NTgxLDAuMTQzODYgLTAuNzA4MjQ4LDAuMDgzMyAtMC4wOTYwNywtMC4wMzM1IC0wLjA5ODEzLC0wLjAzOTcgLTAuMTg5NTA4LC0wLjU3NjMgLTAuMDgyNzcsLTAuNDg2MDIgLTAuNDUxODA0LC0yLjE0IC0wLjc0MTE2MSwtMy4zMjE4NiBsIC0wLjEwNzkyNCwtMC40NDA4IDAuNDM3NTkyLC0wLjEwMzk0IGMgMi4zMTAyNTEsLTAuNTQ4NzMgNC45NzA4NSwtMS4wNDc1OCA2Ljk1MjI4NSwtMS4zMDM1MyAxLjY3MDIyNCwtMC4yMTU3NSAzLjAzMjAyOCwtMC4zMDI1MiA1LjA4Mzg4NSwtMC4zMjM5MSAyLjIxODIsLTAuMDIzMSAzLjU2ODE0MSwwLjAzNzMgNS40MjMxNDgsMC4yNDI5MyAxLjgxOTE0OCwwLjIwMTYyIDQuMTY3NDQ5LDAuNjA1NjQgNi4wOTcwODcsMS4wNDkgMC44NDEwNzksMC4xOTMyNSAyLjAyNzI3NywwLjQ5ODQgMi4wOTEzNDksMC41MzggMC4wMzc0NCwwLjAyMzEgLTAuMDIwNjQsMC4yOTQyOSAtMC4zMTIyNzUsMS40NTgxMiAtMC4zMzg2MDMsMS4zNTEyMiAtMC40OTIwOSwyLjA2NjUgLTAuNTQ0NzksMi41Mzg3OSBsIC0wLjAyMzEsMC4yMDcwNyAtMC4xNTIxNywwLjA1MTkgYyAtMC4wODM2OSwwLjAyODUgLTAuMTc1ODA1LDAuMDUwMiAtMC4yMDQ2ODcsMC4wNDgyIC0wLjAyODg4LC0wLjAwMiAtMC4zMTMzOTksLTAuMDkyMyAtMC42MzIyNTksLTAuMjAwNjggeiIKICAgICAgIGlkPSJwYXRoMTg1IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAyMy40MjgyNDgsMjczLjAxMTMgYyAwLC0wLjAwOSAwLjA0NjY2LC0wLjA3NTUgMC4xMDM2ODgsLTAuMTQ2OTYgMC4zODg0ODYsLTAuNDg2NiAwLjY0MTQ0LC0xLjM4NTYyIDAuNzk3OTUyLC0yLjgzNTk4IDAuMDM3NjgsLTAuMzQ5MTIgMC4xMjAzODcsLTEuMDg1NzggMC4xODM4MDYsLTEuNjM3MDIgMC4xNjgxOSwtMS40NjE5MyAwLjIzMzYzMSwtMi4yNzkyIDAuMzg1MjE5LC00LjgxMDg1IDAuMTA1Mjg1LC0xLjc1ODM3IDAuMjU2NTc4LC0yLjc3OTc0IDAuNDM1Nzc0LC0yLjk0MTkxIDAuMDU1ODgsLTAuMDUwNiAwLjA2MzEzLC0wLjA0NzggMC4xMDkxNDUsMC4wNDExIDAuMjQwOTM3LDAuNDY1OTMgMC40MzIzMjgsMi4wMzMyMyAwLjUzOTg1MSw0LjQyMDg2IDAuMDUyOSwxLjE3NDc4IDAuMTI2MzgxLDIuMzAzMDggMC4xODcxMDYsMi44NzMxNSAwLjA4Njg5LDAuODE1NjggMC4zMzg1NzMsMi43NTk2OSAwLjM5ODY2NSwzLjA3OTI5IDAuMTI5NzI4LDAuNjg5OTUgMC4zNzIzNDYsMS4zNjQ0NSAwLjYyNDkyMiwxLjczNzM1IDAuMDUzODUsMC4wNzk1IDAuMTEwMzA1LDAuMTY1NjYgMC4xMjU0NTUsMC4xOTE0NiAwLjAyMzI2LDAuMDM5NiAtMC4wMzQyNSwwLjA0MzkgLTAuMzcwMTYyLDAuMDI3NSAtMC4yMTg3MzksLTAuMDEwNyAtMC41NDgwNDgsLTAuMDQ1MiAtMC43MzE3OTYsLTAuMDc2NyAtMC40NDczNjIsLTAuMDc2OCAtMS4yNTU1NzcsLTAuMDc2OSAtMS43MDM4NDMsLTEuOWUtNCAtMC4zMzE5MTUsMC4wNTY4IC0xLjA4NTc4MiwwLjExMTQ5IC0xLjA4NTc4MiwwLjA3ODggeiIKICAgICAgIGlkPSJwYXRoMTg3IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAxNy44ODI0MDUsMjczLjM3MjU3IGMgMCwtMC4wMDggMC4wMjU3NCwtMC4xMDk4MiAwLjA1NzIxLC0wLjIyNjE1IDAuMDQ0MTUsLTAuMTYzMjEgMC4wNTYzMiwtMC4zMzczNiAwLjA1MzMsLTAuNzYyNzQgLTAuMDA3NywtMS4wOTQ0IC0wLjE3OTc4NiwtMi4xNzMyIC0wLjg0MTc3MSwtNS4yNzg1OCAtMC4yOTc1ODQsLTEuMzk1OTcgLTAuMzY3MzgyLC0xLjg4MDc5IC0wLjM3NjQ5OSwtMi42MTUyMSAtMC4wMDY2LC0wLjUzMzM5IDAuMDE2MDIsLTAuNjE5NzEgMC4xMzQ0NTcsLTAuNTEyNTMgMC4xODA2NDMsMC4xNjM0OCAwLjU5MDczOSwxLjE4NjQ3IDEuMjA2OTczLDMuMDEwODEgMS4xNjQ1OTMsMy40NDc3NCAxLjkwODMyNCw1LjA5ODk1IDIuNjUxNDc3LDUuODg2NzQgbCAwLjIyMjk5NSwwLjIzNjM4IC0wLjM3NjQxNSwwLjAyMjMgYyAtMC44OTAzMTEsMC4wNTI3IC0yLjQ0MzA1MywwLjE5MTUgLTIuNjU2NTU4LDAuMjM3NDUgLTAuMDQxMzQsMC4wMDkgLTAuMDc1MTcsMC4wMSAtMC4wNzUxNywwLjAwMiB6IgogICAgICAgaWQ9InBhdGgxODkiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDMxLjk5NzU3NywyNzMuMjg0NzcgYyAtMC4zODU4NzEsLTAuMDMyNCAtMS4wNDE3NywtMC4wNzg0IC0xLjQ1NzU1OCwtMC4xMDIzMSBsIC0wLjc1NTk3NSwtMC4wNDM1IDAuMjAxOTA0LC0wLjIzNDU5IGMgMC43NjYyNDYsLTAuODkwMjkgMS40OTc5MzMsLTIuNTAzMjQgMi41NjMxNTMsLTUuNjUwMjcgMC41NjA5NTcsLTEuNjU3MjYgMC44MDg4MSwtMi4zMDE2NyAxLjA5MTcxNiwtMi44Mzg0MiAwLjA3ODc4LC0wLjE0OTQ2IDAuMjIzODIyLC0wLjMxNzM4IDAuMjc0MTQzLC0wLjMxNzM4IDAuMDQyMTYsMCAwLjA2MTYsMC42OTI5OCAwLjAyOTg1LDEuMDY0NzEgLTAuMDQzMzksMC41MDgxMiAtMC4xNzE3MzUsMS4xOTM4NSAtMC43MDc0MDMsMy43Nzk1NSAtMC4zNTYzMiwxLjcxOTk4IC0wLjQ2NjMyLDIuNTEzODUgLTAuNDY1MjMsMy4zNTc1NyA1LjI5ZS00LDAuNTAzOSAwLjAxMTY3LDAuNjM3OTEgMC4wNjc5NywwLjgyNjg3IGwgMC4wNjcxOSwwLjIyNTUxIC0wLjEwNDA5MiwtMC4wMDQgYyAtMC4wNTcyNSwtMC4wMDIgLTAuNDE5ODA0LC0wLjAzMDkgLTAuODA1Njc1LC0wLjA2MzMgeiIKICAgICAgIGlkPSJwYXRoMTkxIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAzOC40NjIxNTgsMjc0LjA5ODg5IGMgLTAuNDUwNDcyLC0wLjA4MzIgLTIuMjM4MjExLC0wLjM2MjUzIC0yLjUzOTA2MSwtMC4zOTY3NiAtMC4xMDEwNiwtMC4wMTE1IC0wLjIwMzQ1NCwtMC4wMjcxIC0wLjIyNzU0MiwtMC4wMzQ2IC0wLjAyNjY0LC0wLjAwOCAwLjA5MjU1LC0wLjE2MzA2IDAuMzA0MjY2LC0wLjM5NDkyIDAuMTkxNDM0LC0wLjIwOTY0IDAuNjQ2NjU1LC0wLjczMjE5IDEuMDExNjA1LC0xLjE2MTIyIDEuOTU2NzI2LC0yLjMwMDI3IDIuOTkyNjc4LC0zLjQwMTE3IDMuMzkyNDExLC0zLjYwNTEgMC4yMzI4OTksLTAuMTE4ODIgMC4zOTAzMTMsMC4wMjg3IDAuMzUwMjg3LDAuMzI4MjggLTAuMDI2MzMsMC4xOTcxNiAtMC4yMTE0OTUsMC42MzQ5MiAtMC41MTkwODEsMS4yMjcyNSAtMC4yMTk4OTgsMC40MjM0NyAtMC4zMTIzNjcsMC42NTkwNCAtMC41OTY2ODMsMS41MjAxIC0wLjI3NTU4NSwwLjgzNDYgLTAuNTA0ODI1LDEuNjE0ODcgLTAuNzMxOTc4LDIuNDkxNDMgbCAtMC4wMjY2MSwwLjEwMjcgeiIKICAgICAgIGlkPSJwYXRoMTkzIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAxMS44MzcwMDksMjczLjc5MjI0IGMgLTAuMzg2MDQxLC0xLjM4NTEzIC0wLjk3NjgwNCwtMy4xMTI5IC0xLjE5OTU3LC0zLjUwODMxIC0wLjQxNjIyNywtMC43Mzg4IC0wLjYxMDczNywtMS4yMTcxNCAtMC42MTA4MDYsLTEuNTAyMDkgLTYuM2UtNSwtMC4yNjA3NyAwLjEyNTgxMywtMC4zODMxNSAwLjMwMDk0MSwtMC4yOTI1OSAwLjMwNDk2OCwwLjE1NzcxIDEuOTQwNDQ0LDEuODcyMjcgMy4wNDU1NywzLjE5Mjg0IDAuNjEyMDgzLDAuNzMxNDEgMS4wMjYwNjQsMS4xOTYzMSAxLjQwNTY2OCwxLjU3ODU2IDAuMTk2MTYxLDAuMTk3NTMgMC4zNDk2OTksMC4zNTkxNSAwLjM0MTE5NSwwLjM1OTE1IC0wLjA4NTA4LDAgLTMuMDU2NTM4LDAuNTE5NzggLTMuMTM3NjIyLDAuNTQ4ODUgLTAuMDIxOTQsMC4wMDggLTAuMDgwNjMsLTAuMTQ0MSAtMC4xNDUzNzYsLTAuMzc2NDEgeiIKICAgICAgIGlkPSJwYXRoMTk1IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSA2LjAwNDk3OTEsMjY0Ljc1MDgxIGMgLTAuNzM5MjAxOSwtMC4xNjA5NiAtMS4wOTg5Nzg5LC0wLjYyOTQ2IC0xLjE0MTM0NTgsLTEuNDg2MjggLTAuMDM1NzM0LC0wLjcyMjY2IDAuMTczMDUzMSwtMS4yNDY1NiAwLjYwNjI3OTQsLTEuNTIxMjkgMC4yNzQwNzEzLC0wLjE3MzggMC40NTk0NzI4LC0wLjIyMjQ1IDAuOTIxMTM5NSwtMC4yNDE2OSAwLjY2NDkxNzIsLTAuMDI3NyAxLjA5MDA5MzksMC4xMDc0OCAxLjQwMTkzODIsMC40NDU3OSAwLjI1NzgzMzUsMC4yNzk3MiAwLjM2Nzc5NjcsMC42MzY5MiAwLjM2Njk5MjEsMS4xOTIxMyAtMC4wMDEzNSwwLjkzMDYgLTAuMzcwMzQ4NCwxLjQ0NDA5IC0xLjE1NzYyNTMsMS42MTA4OSAtMC4yNzkwMzY4LDAuMDU5MSAtMC43MjY5NzUzLDAuMDU5MyAtMC45OTczNzgxLDQuNWUtNCB6IgogICAgICAgaWQ9InBhdGgxOTciCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDE0LjU0MTUzNiwyNTkuMTI4NyBjIC0wLjUyNTMxLC0wLjE0MjMxIC0wLjg0NDc1NSwtMC40NjYzOCAtMC45ODczMTYsLTEuMDAxNjIgLTAuMDYzMDYsLTAuMjM2NzggLTAuMDcxNDksLTAuODIwOTcgLTAuMDE1NzksLTEuMDk0NyAwLjE1MTg1MSwtMC43NDYyNSAwLjcwMzQ0NiwtMS4xNTA2MyAxLjU3MTA1OSwtMS4xNTE3NiAwLjg5NzE3MSwtMC4wMDEgMS40MzU4NTYsMC4zNTM5OCAxLjYyNTU4MywxLjA3MTc1IDAuMDY5NzgsMC4yNjM5OSAwLjA3Nzc0LDAuODczOTcgMC4wMTQ3OCwxLjEzMjM5IC0wLjEyMzQzOSwwLjUwNjY1IC0wLjQxNjA5OSwwLjgzOTI0IC0wLjg4MzMwNCwxLjAwMzgzIC0wLjI5MTU2OSwwLjEwMjcxIC0xLjAxMzI3MSwwLjEyNDU2IC0xLjMyNTAxMiwwLjA0MDEgeiIKICAgICAgIGlkPSJwYXRoMTk5IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAyNC45MjcyOTUsMjU0LjIwNjk4IGMgLTAuODUwMTMsLTAuMTI0OSAtMS4yNjY1NzIsLTAuNjYyNDcgLTEuMjY0NjA2LC0xLjYzMjQ0IDAuMDAxOCwtMC44NzA5NyAwLjM1NjgxMywtMS40MDQxOCAxLjA1OTEyNywtMS41OTA1OSAwLjI1ODAwMywtMC4wNjg1IDAuODk4Mjc0LC0wLjA2ODcgMS4xNTQxOCwtNGUtNCAwLjU0NzEzOSwwLjE0NjAzIDAuODgxODYzLDAuNDg1NzUgMS4wMDg2NzIsMS4wMjM3MiAwLjAyODgzLDAuMTIyMzEgMC4wNTA3MiwwLjM3MjU1IDAuMDUxLDAuNTgzMDkgNy45NGUtNCwwLjU3NzkyIC0wLjExNzk0MywwLjkzNDMgLTAuNDA5MjM5LDEuMjI4NTEgLTAuMzMxODc2LDAuMzM1MTkgLTAuOTQ1NTQ1LDAuNDg0MTMgLTEuNTk5MTMzLDAuMzg4MTEgeiIKICAgICAgIGlkPSJwYXRoMjAxIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAzNC44NTczNTgsMjU5LjExODgyIGMgLTAuMzAyOTE5LC0wLjA3OTMgLTAuNDgyNiwtMC4xODE1MiAtMC42NjI3MDcsLTAuMzc2OTEgLTAuMjc2OTUsLTAuMzAwNDYgLTAuMzc2MzAxLC0wLjYxNTA5IC0wLjM3NjMwMSwtMS4xOTE2OSAwLC0wLjk0ODA3IDAuMzU4OTY1LC0xLjQ1MjU5IDEuMTUyNjAxLC0xLjYxOTk2IDAuNDQxMTU2LC0wLjA5MyAxLjAwOTEwOCwtMC4wNDY0IDEuMzY3ODgzLDAuMTEyMyAwLjE5NjYzNiwwLjA4NyAwLjQ3MzQzOCwwLjM0ODU3IDAuNTY5NDI4LDAuNTM4MTQgMC4xOTI0NzcsMC4zODAxMSAwLjI1ODg1LDAuOTIwMDQgMC4xNzIwMjIsMS4zOTkzMyAtMC4xMTY3MTMsMC42NDQyNyAtMC40NTUwNiwxLjAxMzE2IC0xLjA2MDA2OSwxLjE1NTc3IC0wLjMwNDM2NiwwLjA3MTggLTAuODU0NzQ1LDAuMDYzNyAtMS4xNjI4NTcsLTAuMDE3IHoiCiAgICAgICBpZD0icGF0aDIwMyIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gNDMuNTc1NjUxLDI2NC43NTAwOSBjIC0wLjI5ODg3OCwtMC4wNjc4IC0wLjUyNzg3LC0wLjE4NzcyIC0wLjcxNDA5NCwtMC4zNzM5NSAtMC4yODI2MSwtMC4yODI2MSAtMC40MjI2MDMsLTAuNjk1NTkgLTAuNDIyNjAzLC0xLjI0NjY3IDAsLTEuMDgwNjUgMC41NTUyNzUsLTEuNjM0ODcgMS42Mzk2NTcsLTEuNjM2NTMgMC4zNjYwNjksLTUuNmUtNCAwLjU2ODc2MSwwLjAzMTUgMC44MzkyODUsMC4xMzI3IDAuMjE5MTMsMC4wODIgMC40OTEwMTYsMC4zMTE4OSAwLjYxMTAyNiwwLjUxNjY3IDAuMTI3MjA5LDAuMjE3MDYgMC4yMTYzMzEsMC42MTcxOSAwLjIxNjMzMSwwLjk3MTI0IDAsMC44NzE3NyAtMC4zMTAxMzksMS4zODE2IC0wLjk2NzQzNiwxLjU5MDMyIC0wLjI4ODY3NiwwLjA5MTcgLTAuODk4NTA2LDAuMTE1MTEgLTEuMjAyMTY2LDAuMDQ2MiB6IgogICAgICAgaWQ9InBhdGgyMDUiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogIDwvZz4KPC9zdmc+Cg=='); } -body.base .is2d piece.king.white { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMTQ0cHQiCiAgIGhlaWdodD0iMTQ0cHQiCiAgIHZpZXdCb3g9IjAgMCA1MC44MDAwMDEgNTAuOCIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnOCIKICAgc29kaXBvZGk6ZG9jbmFtZT0id2suc3ZnIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkyLjMgKDI0MDU1NDYsIDIwMTgtMDMtMTEpIj4KICA8ZGVmcwogICAgIGlkPSJkZWZzMiIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9ImJhc2UiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEuMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6em9vbT0iNy45MTk1OTU5IgogICAgIGlua3NjYXBlOmN4PSI4My41MzQ4NiIKICAgICBpbmtzY2FwZTpjeT0iOTYuMTYxNzUyIgogICAgIGlua3NjYXBlOmRvY3VtZW50LXVuaXRzPSJtbSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJsYXllcjEiCiAgICAgc2hvd2dyaWQ9ImZhbHNlIgogICAgIHVuaXRzPSJwdCIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjM4NDAiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iMjAzNSIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iLTEzIgogICAgIGlua3NjYXBlOndpbmRvdy15PSItMTMiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIgLz4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGE1Ij4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICAgIDxkYzp0aXRsZSAvPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZwogICAgIGlua3NjYXBlOmxhYmVsPSJMYXllciAxIgogICAgIGlua3NjYXBlOmdyb3VwbW9kZT0ibGF5ZXIiCiAgICAgaWQ9ImxheWVyMSIKICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLC0yNDYuMikiPgogICAgPGcKICAgICAgIGFyaWEtbGFiZWw9ImsiCiAgICAgICBzdHlsZT0iZm9udC1zdHlsZTpub3JtYWw7Zm9udC12YXJpYW50Om5vcm1hbDtmb250LXdlaWdodDpub3JtYWw7Zm9udC1zdHJldGNoOm5vcm1hbDtmb250LXNpemU6NTAuNzk5OTk5MjRweDtsaW5lLWhlaWdodDoxLjI1O2ZvbnQtZmFtaWx5OidDaGVzcyBMZWlwemlnJzstaW5rc2NhcGUtZm9udC1zcGVjaWZpY2F0aW9uOidDaGVzcyBMZWlwemlnJztsZXR0ZXItc3BhY2luZzowcHg7d29yZC1zcGFjaW5nOjBweDtmaWxsOiMwMDAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjAuMjY0NTgzMzIiCiAgICAgICBpZD0idGV4dDIzMCIKICAgICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuMDA4NDA3MSwxLjM4OTkyKSI+CiAgICAgIDxwYXRoCiAgICAgICAgIGQ9Im0gMTcuNzM1MzUyLDI4MC45MTQxNSAtMi40MDYwNTUsLTAuNzkzNzUgLTEuODYwMzUyLDEuNDg4MjggMi4zNTY0NDYsMC43OTM3NSB6IG0gMjEuNDU2MDU0LDAuMDc0NCBxIDAuMTczNjMzLDAuNTIwOSAwLjE3MzYzMywwLjk5MjE5IDAsMS40NjM0OCAtMS4wNjY2MDIsMi4yNTcyMyAtMC4wOTkyMiwwLjQyMTY4IC0wLjE0ODgyOCwwLjg0MzM2IDAuOTE3Nzc0LDEuMjg5ODQgMC45MTc3NzQsMi4wODM1OSAwLDIuMDgzNTkgLTQuMDE4MzYsMy41NzE4NyAtNC4wMTgzNTksMS40ODgyOSAtOS42NDkwMjMsMS40ODgyOSAtNS42NTU0NjksMCAtOS42NzM4MjgsLTEuNDg4MjkgLTMuOTkzNTU1LC0xLjQ4ODI4IC0zLjk5MzU1NSwtMy41NzE4NyAwLC0wLjgxODU2IDAuOTY3MzgzLC0yLjEzMzIgLTAuMDQ5NjEsLTAuMjcyODYgLTAuMTQ4ODI4LC0wLjc2ODk1IC0xLjA5MTQwNiwtMC43OTM3NSAtMS4wOTE0MDYsLTIuMjgyMDMgMCwtMC40NzEyOSAwLjE0ODgyOCwtMC45NjczOCAwLjI0ODA0NywtMC42MjAxMiAtMC4wOTkyMiwtMC45NjczOSAtMC4zNDcyNjUsLTAuMzQ3MjYgLTAuNzkzNzUsLTAuOTY3MzggLTAuMzk2ODc1LC0xLjI0MDIzIC0wLjM5Njg3NSwtMS43MTE1MiAwLjAyNDgxLC0wLjIyMzI0IDAuMDc0NDEsLTAuNDk2MSAwLjA3NDQxLC0wLjI3Mjg1IDAuMDc0NDEsLTAuNjQ0OTIgLTEuMDkxNDA1OSwtMS4wOTE0IC0yLjI4MjAzMDksLTIuMDU4NzkgLTEuMTY1ODIwMywtMC45OTIxOCAtMS44MzU1NDY4LC0yLjM4MTI1IC0wLjc5Mzc1LC0xLjYzNzExIC0xLjQ2MzQ3NjYsLTMuMjk5MDIgLTAuNjQ0OTIxOCwtMS42ODY3MiAtMC42NDQ5MjE4LC0zLjI5OTAyIDAsLTMuMDUwOTggMS42MTIzMDQ2LC01LjE1OTM4IDEuNjEyMzA0NywtMi4xMDg0IDQuMzY1NjI0NSwtMy4yOTkwMiAzLjY3MTA5NCwtMC4yNDgwNSAzLjEwMDU4NiwtMC4yNDgwNSA0LjMxNjAxNiwwIDcuODM4MjgyLDMuMTk5ODEgdiAtOC43MDY0NSBoIDguNDU4Mzk4IHYgOC43MzEyNSBxIDMuNTIyMjY1LC0zLjIyNDYxIDcuODg3ODksLTMuMjI0NjEgLTAuNjIwMTE3LDAgMy4xMDA1ODYsMC4yNDgwNSAyLjcwMzcxMSwxLjE5MDYyIDQuMzE2MDE2LDMuMjk5MDIgMS42MzcxMDksMi4xMDg0IDEuNjM3MTA5LDUuMTU5MzggMCwxLjYxMjMgLTAuNjY5NzI2LDMuMjc0MjIgLTAuNjQ0OTIyLDEuNjYxOTEgLTEuNDEzODY4LDMuMjk5MDIgLTAuNjY5NzI2LDEuNDEzODcgLTEuODYwMzUxLDIuNDU1NjYgLTEuMTkwNjI1LDEuMDQxOCAtMi4yNTcyMjcsMi4wODM2IC0wLjAyNDgsMC4yOTc2NSAwLjAyNDgxLDAuNTcwNSAwLjA3NDQxLDAuMjcyODYgMC4wOTkyMiwwLjQ5NjEgMC4wMjQ4LDAuMzQ3MjYgLTAuMzk2ODc1LDEuNzExNTIgLTAuNDQ2NDg1LDAuNjIwMTIgLTAuNzkzNzUsMC45NjczOCAtMC4zMjI0NjEsMC4zNDcyNyAtMC4wOTkyMiwwLjk0MjU4IHogTSAyNS40LDI1OS40ODI5IHEgLTIuNTU0ODgzLDAgLTIuNTU0ODgzLDIuNTU0ODggMCwyLjU1NDg4IDIuNTU0ODgzLDIuNTU0ODggMi41NTQ4ODMsMCAyLjU1NDg4MywtMi41NTQ4OCAwLC0yLjU1NDg4IC0yLjU1NDg4MywtMi41NTQ4OCB6IG0gLTAuOTkyMTg3LC00LjQ4OTY1IC0xLjc2MTEzMywtMS43MTE1MiB2IDMuNzk1MTEgbCAxLjc2MTEzMywtMS40MTM4NiBxIC0wLjA3NDQyLC0wLjA5OTIgLTAuMDc0NDIsLTAuMzIyNDYgMCwtMC4xNDg4MyAwLjA3NDQyLC0wLjM0NzI3IHogbSAwLjU3MDUwNywxLjMxNDY1IC0xLjQ4ODI4MSwxLjYxMjMgaCAzLjgxOTkyMiBsIC0xLjU4NzUsLTEuNTg3NSBxIC0wLjI0ODA0NywwLjA0OTYgLTAuMzIyNDYxLDAuMDQ5NiAtMC4yNDgwNDcsMCAtMC40MjE2OCwtMC4wNzQ0IHogbSAxLjQxMzg2NywtMC41NzA1MSAxLjc2MTEzMywxLjMzOTQ1IHYgLTMuNzk1MTEgbCAtMS43ODU5MzcsMS42MzcxMSBxIDAuMDc0NDEsMC4xOTg0MyAwLjA3NDQxLDAuNDIxNjggMCwwLjE0ODgyIC0wLjA0OTYxLDAuMzk2ODcgeiBtIC0wLjY5NDUzMSwtMS40MTM4NyAxLjYxMjMwNSwtMS45MDk5NiBoIC0zLjgxOTkyMiBsIDEuNTEzMDg2LDEuOTM0NzcgcSAwLjE0ODgyOCwtMC4wNzQ0IDAuMzk2ODc1LC0wLjA3NDQgMC4wOTkyMiwwIDAuMjk3NjU2LDAuMDQ5NiB6IG0gMi43MDM3MTEsMjUuODIxNjggLTMuMDUwOTc2LC0xLjQ2MzQ3IC0yLjkyNjk1MywxLjQ2MzQ3IDMuMDI2MTcxLDEuNDYzNDggeiBtIC00Ljk2MDkzNywtNi43NDY4NyBxIC0wLjAyNDgxLC0zLjA1MDk4IC0wLjUyMDg5OSwtNi4xMjY3NiAtMC40OTYwOTMsLTMuMTAwNTkgLTAuOTkyMTg3LC0zLjc3MDMxIC0zLjA3NTc4MSwtMy4zOTgyNCAtNi45NDUzMTMsLTMuMzk4MjQgLTMuMzIzODI4LDAgLTUuMDYwMTU1OCwyLjIzMjQyIC0xLjE0MTAxNTYsMS40NjM0NyAtMS4xNDEwMTU2LDMuODQ0NzIgMCw0Ljk2MDk0IDMuNjk1ODk4NCw5LjI3Njk2IDAuNDIxNjgsLTAuMTk4NDQgMC44MTg1NTUsLTAuMzQ3MjcgMC40MjE2NzksLTAuMTQ4ODMgMC44NDMzNTksLTAuMjk3NjUgLTAuMjIzMjQyLC0wLjQ5NjEgLTAuNDQ2NDg0LC0wLjk0MjU4IC0wLjIyMzI0MywtMC40NDY0OSAtMC40NzEyODksLTEuMTY1ODIgLTAuNDcxMjg5LC0xLjM4OTA3IC0wLjM3MjA3MSwtMi42MjkzIDAuMTczNjMzLC0wLjc2ODk1IDAuODQzMzYsLTAuNzY4OTUgMC4yOTc2NTYsMCAwLjc5Mzc1LDAuNTIwOSAtMC4xMjQwMjQsLTAuNjY5NzIgLTAuMTI0MDI0LC0wLjg0MzM2IDAsLTIuMzA2ODMgMS45NTk1NzEsLTIuODUyNTQgMi4wNTg3ODksMC4wOTkyIDIuNzI4NTE1LDMuMDc1NzkgMC4yMjMyNDIsLTAuNzQ0MTQgMC42MjAxMTcsLTAuODQzMzYgMC4zOTY4NzUsLTAuMDk5MiAwLjUyMDg5OSwtMC4wOTkyIDAuMjk3NjU2LDAgMC41MjA4OTgsMC4xNDg4MyAwLjg0MzM1OSwxLjA0MTc5IDEuMDQxNzk3LDMuMDI2MTcgMC4wNDk2MSwwLjQ0NjQ4IDAuMDQ5NjEsMC44NjgxNiAwLjAyNDgxLDAuNDIxNjggMC4wOTkyMiwxLjE5MDYzIDAuNzY4OTQ1LC0wLjE0ODgzIDEuNTM3ODkxLC0wLjA5OTIgeiBtIC03LjQxNjYwMiwwLjg0MzM2IHEgLTAuMjIzMjQyLC0wLjU3MDUxIC0wLjQ3MTI4OSwtMS4yNjUwNCAtMC4yMjMyNDIsLTAuNjk0NTMgLTAuNTk1MzEyLC0xLjQ4ODI4IC0wLjE5ODQzOCwtMC4zOTY4OCAtMC40OTYwOTQsLTAuMzk2ODggLTAuNDIxNjgsMCAtMC40NDY0ODQsMC42OTQ1MyAtMC4wNDk2MSwwLjU5NTMyIDEuMjE1NDI5LDIuNzI4NTIgMC4xOTg0MzgsLTAuMDc0NCAwLjM5Njg3NSwtMC4xMjQwMiAwLjIyMzI0MiwtMC4wNzQ0IDAuMzk2ODc1LC0wLjE0ODgzIHogbSAyLjQ4MDQ2OSwtMC4zNzIwNyBxIC0wLjA5OTIyLC0zLjI0OTQyIC0wLjk2NzM4MywtNS4yNTg2IC0wLjI5NzY1NiwtMC41MjA5IC0wLjg2ODE2NCwtMC41MjA5IC0wLjcxOTMzNiwwIC0wLjcxOTMzNiwwLjcxOTM0IC0wLjAyNDgsMC4wMjQ4IC0wLjAyNDgsMC42NDQ5MiAwLDEuMDY2NiAxLjIxNTQyOSw0LjY2MzI4IDEuMDQxNzk3LC0wLjE5ODQzIDEuMzY0MjU4LC0wLjI0ODA0IHogbSAyLjMzMTY0MSwtMC4yNDgwNSBxIDAuMTI0MDIzLC0xLjkwOTk2IC0wLjE5ODQzOCwtMy4yMjQ2MSAtMC4wOTkyMiwtMC40MjE2OCAtMC40NzEyODksLTAuNTIwOSAtMC41MjA4OTgsLTAuMDc0NCAtMC42OTQ1MzEsMC41NzA1MSAtMC4xOTg0MzgsMS4wNjY2IDAuMzQ3MjY1LDMuMjk5MDIgMC40OTYwOTQsLTAuMTI0MDIgMS4wMTY5OTMsLTAuMTI0MDIgeiBtIDE1LjYyNjk1MiwxMi4zMDMxMiBxIC0wLjE5ODQzNywtMS43ODU5MyAtNC45NjA5MzcsLTIuNzI4NTEgLTEuNDg4MjgxLC0wLjI5NzY2IC0zLjAwMTM2NywtMC4zNDcyNyBRIDI2Ljk4NzUsMjgyLjc5OTMgMjUuNCwyODIuNzI0ODkgcSAtMS41NjI2OTUsMC4xNDg4MyAtMi45NTE3NTgsMC4yMjMyNCAtMS4zNjQyNTgsMC4wNzQ0IC0yLjQ4MDQ2OCwwLjI5NzY2IC01LjQ4MTgzNiwxLjExNjIxIC01LjYwNTg2LDIuNjc4OSAtMC4xOTg0MzcsMC4yOTc2NiAtMC4xOTg0MzcsMC42MjAxMiAwLDEuMTE2MjEgMS43ODU5MzcsMi4yMzI0MiAwLC0xLjE0MTAxIDAuMzk2ODc1LC0xLjcxMTUyIDAuMjIzMjQyLC0wLjI3Mjg1IDAuNDQ2NDg1LC0wLjU0NTcgMC4yNDgwNDYsLTAuMjk3NjYgMC40OTYwOTMsLTAuNTk1MzIgMi4yMzI0MjIsLTEuMzM5NDUgOC4xNjA3NDIsLTEuMTkwNjIgNS44MDQyOTcsLTAuMTQ4ODMgOC4wODYzMjgsMS4xOTA2MiAwLjU0NTcwMywwLjY5NDU0IDAuOTQyNTc4LDEuMTQxMDIgMC4zOTY4NzUsMC42MjAxMiAwLjM5Njg3NSwxLjcxMTUyIDEuNzg1OTM4LC0xLjExNjIxIDEuNzg1OTM4LC0yLjIzMjQyIDAsLTAuMzIyNDYgLTAuMTk4NDM4LC0wLjYyMDEyIHogbSAtMi44NzczNDMsMi4zMDY4NCBxIDAsLTIuMjMyNDIgLTguMjM1MTU2LC0yLjIzMjQyIC04LjExMTEzMywwIC04LjExMTEzMywyLjIzMjQyIDAuNTIwODk4LDIuMjA3NjIgOC4yMTAzNTEsMi4yMDc2MiA3LjU2NTQzLDAgOC4xMzU5MzgsLTIuMjA3NjIgeiBtIC0wLjI5NzY1NiwtNy4zMTczOCAxLjg4NTE1NiwxLjQ4ODI4IDIuMzgxMjUsLTAuNzkzNzUgLTEuODg1MTU3LC0xLjQ4ODI4IHogbSA1LjAxMDU0NiwtNS40ODE4NCBxIDMuNTQ3MDcxLC00LjM5MDQzIDMuNTQ3MDcxLC05LjI1MjE1IDAsLTIuMzgxMjUgLTEuMTQxMDE2LC0zLjg0NDcyIC0xLjc2MTEzMywtMi4yMzI0MiAtNS4wNjAxNTYsLTIuMjMyNDIgLTMuODk0MzM2LDAgLTYuOTQ1MzEzLDMuMzk4MjQgLTAuNTIwODk4LDAuNjY5NzIgLTEuMDE2OTkyLDMuNzcwMzEgLTAuNDk2MDk0LDMuMDc1NzggLTAuNTIwODk4LDYuMTI2NzYgMC44OTI5NjksLTAuMDc0NCAxLjU4NzUsMC4wOTkyIDAuMDI0OCwtMC43Njg5NSAwLjAyNDgsLTEuMTkwNjMgMC4wMjQ4LC0wLjQyMTY4IDAuMDk5MjIsLTAuODY4MTYgMC4xNzM2MzMsLTEuOTg0MzggMS4wNDE3OTcsLTMuMDI2MTcgMC4xOTg0MzgsLTAuMTQ4ODMgMC41MjA4OTgsLTAuMTQ4ODMgMC4xMjQwMjQsMCAwLjUyMDg5OSwwLjA5OTIgMC4zOTY4NzUsMC4wOTkyIDAuNjIwMTE3LDAuODQzMzYgMC42NDQ5MjIsLTIuOTc2NTcgMi43Mjg1MTYsLTMuMDc1NzkgMS45NTk1NywwLjU0NTcxIDEuOTU5NTcsMi44NTI1NCAwLDAuMTczNjQgLTAuMTI0MDIzLDAuODQzMzYgMC40NzEyODksLTAuNTIwOSAwLjc5Mzc1LC0wLjUyMDkgMC42NDQ5MjEsMCAwLjg0MzM1OSwwLjc2ODk1IDAuMDc0NDEsMS4yNDAyMyAtMC4zNzIwNywyLjYyOTMgLTAuMjcyODUyLDAuNzE5MzMgLTAuNDk2MDk0LDEuMTY1ODIgLTAuMTk4NDM4LDAuNDQ2NDggLTAuNDIxNjgsMC44OTI5NyAwLjQ0NjQ4NSwwLjE3MzYzIDAuODkyOTY5LDAuMzQ3MjYgMC40NzEyODksMC4xNDg4MyAwLjkxNzc3MywwLjMyMjQ2IHogbSAtMy42OTU4OTgsLTEuMTkwNjIgcSAwLjE0ODgyOCwwLjA3NDQgMC4zNDcyNjYsMC4xNDg4MyAwLjIyMzI0MiwwLjA0OTYgMC40NDY0ODQsMC4xMjQwMiAxLjI0MDIzNCwtMi4xMzMyIDEuMjE1NDMsLTIuNzI4NTIgLTAuMDQ5NjEsLTAuNjk0NTMgLTAuNDQ2NDg1LC0wLjY5NDUzIC0wLjMyMjQ2MSwwIC0wLjQ5NjA5NCwwLjM5Njg4IC0wLjM5Njg3NSwwLjc5Mzc1IC0wLjY0NDkyMSwxLjQ4ODI4IC0wLjIyMzI0MywwLjY5NDUzIC0wLjQyMTY4LDEuMjY1MDQgeiBtIC0yLjQ4MDQ2OSwtMC4zNzIwNyBxIDAuMjk3NjU2LDAuMDQ5NiAxLjM2NDI1OCwwLjI0ODA0IDEuMjE1NDMsLTMuNTk2NjggMS4yMTU0MywtNC42NjMyOCAwLC0wLjYyMDExIC0wLjAyNDgxLC0wLjY0NDkyIDAsLTAuNzE5MzQgLTAuNzE5MzM2LC0wLjcxOTM0IC0wLjU5NTMxMiwwIC0wLjg2ODE2NCwwLjUyMDkgLTAuODkyOTY5LDIuMDA5MTggLTAuOTY3MzgzLDUuMjU4NiB6IG0gLTIuMzMxNjQsLTAuMjQ4MDUgcSAwLjUyMDg5OCwwIDEuMDE2OTkyLDAuMTI0MDIgMC41MjA4OTgsLTIuMjMyNDIgMC4zNDcyNjUsLTMuMjk5MDIgLTAuMTk4NDM3LC0wLjY0NDkyIC0wLjY5NDUzMSwtMC41NzA1MSAtMC4zOTY4NzUsMC4wOTkyIC0wLjQ3MTI4OSwwLjUyMDkgLTAuMzQ3MjY2LDEuMzE0NjUgLTAuMTk4NDM3LDMuMjI0NjEgeiBtIDcuNDE2NjAxLDUuNDgxODQgcSAxLjExNjIxMSwtMC4xMjQwMyAxLjExNjIxMSwtMS4yNDAyNCAwLC0wLjcxOTMzIC0wLjY0NDkyMiwtMS4wOTE0IC0yLjA4MzU5NCwtMC44NDMzNiAtNS4zMDgyMDMsLTEuMzY0MjYgLTMuMTk5ODA1LC0wLjU0NTcxIC02Ljk5NDkyMiwtMC41NDU3MSAtNy45NjIzMDQsMCAtMTIuMzUyNzM0LDEuOTU5NTcgLTAuNTQ1NzAzLDAuNDIxNjggLTAuNTQ1NzAzLDEuMDQxOCAwLDEuMjY1MDQgMS4yNjUwMzksMS4yMTU0MyA0LjQxNTIzNCwtMS42NjE5MSAxMS42MzMzOTgsLTEuNjYxOTEgNy4zMTczODMsMCAxMS44MzE4MzYsMS42ODY3MiB6IgogICAgICAgICBzdHlsZT0ic3Ryb2tlLXdpZHRoOjAuMjY0NTgzMzIiCiAgICAgICAgIGlkPSJwYXRoMjMyIgogICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPC9nPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDIzLjU2NDgzMSwyOTEuNzc3MDkgYyAtMy44MTg4MTEsLTAuMTc1MTQgLTUuODgxNjIxLC0wLjg1ODU2IC02LjI3NjQwNiwtMi4wNzkzOSAtMC4wODg5NywtMC4yNzUxMiAwLjEyMTc2MSwtMC43Mzk3OCAwLjQ2NTA3NiwtMS4wMjU0OSAwLjc4NzkzMSwtMC42NTU3MyAyLjQ0NTA2NCwtMS4wNDMyMyA1LjE3ODY5MSwtMS4yMTEgMC44ODMxMjksLTAuMDU0MiA0LjA0MTI4MywtMC4wNTQgNC45MTEwNzcsMi43ZS00IDMuNDA5NDg0LDAuMjEyODIgNS4xNzQyMjYsMC43NDQ4MSA1LjYxODIyOSwxLjY5MzYyIDAuMTgyMzQ1LDAuMzg5NjYgMC4xMTU3MjEsMC42OTI5OCAtMC4yMzk4MzQsMS4wOTE4NyAtMC43MjQ0NzIsMC44MTI3NyAtMi4zODIyMzIsMS4yODQ1MyAtNS4yNjE0NjUsMS40OTczIC0wLjYwNzU2LDAuMDQ0OSAtMy42Mzg1MTQsMC4wNjc1IC00LjM5NTM2OCwwLjAzMjggeiIKICAgICAgIGlkPSJwYXRoMjM1IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAxNS43MjE2MjcsMjg5Ljk5MDQxIGMgLTEuMDI5ODgxLC0wLjcwMDc2IC0xLjUxNDU4OSwtMS4zNTA4NSAtMS41MjA2MjQsLTIuMDM5NDQgLTAuMDAxOSwtMC4yMjA3OSAwLjAxMjY2LC0wLjI5OTIyIDAuMDgzOTMsLTAuNDUxMDIgMC4wNDc0NSwtMC4xMDEwNiAwLjExMTk0MywtMC4yNjU1MiAwLjE0MzMxNSwtMC4zNjU0NiAwLjI4MzQ5MSwtMC45MDMxOSAxLjkwMjQ3LC0xLjY3NzU3IDQuODk1ODAzLC0yLjM0MTczIDEuMTg5NzM0LC0wLjI2Mzk4IDEuOTEyMTM1LC0wLjM2MTcxIDMuMzI0MTY0LC0wLjQ0OTczIDAuOTE5MTQsLTAuMDU3MyAxLjkxODc0OCwtMC4xMzMwOSAyLjQ0NTIzNiwtMC4xODU0IDAuMjI5MDEzLC0wLjAyMjggMC41NTcxNSwtMC4wMjI5IDEuMDAyMjYsLTIuNmUtNCAwLjM2Mzk3NiwwLjAxODQgMS4wOTc3NTcsMC4wNDg4IDEuNjMwNjI1LDAuMDY3NiAxLjg1ODQ2LDAuMDY1NCAyLjczNjc1LDAuMTU3ODcgMy45Nzg4ODksMC40MTkwNSAyLjE3MjIyNiwwLjQ1Njc1IDMuNTA3NjAyLDAuOTk0NzEgNC4yMjI5NDYsMS43MDEyMSAwLjI2NjEyLDAuMjYyODQgMC40MTQ1MDcsMC41MDIzMiAwLjQ4Njg0NiwwLjc4NTczIDAuMDMwMjYsMC4xMTg1NyAwLjA3NDc1LDAuMjQ2MzYgMC4wOTg4NiwwLjI4Mzk4IDAuMDI0MSwwLjAzNzYgMC4wNjkwOSwwLjE1NjQ0IDAuMDk5OTYsMC4yNjQwNSAwLjEzODAzNCwwLjQ4MTE0IC0wLjEwNTgzLDEuMDgyODcgLTAuNjY2NTQzLDEuNjQ0NzIgLTAuMjA0OTg5LDAuMjA1NDEgLTAuNjg1NjQxLDAuNTg0NzIgLTAuOTU3OTkzLDAuNzU2MDEgbCAtMC4wODY5NSwwLjA1NDcgLTAuMDIxNDMsLTAuMzM5OTggYyAtMC4wNDUwNiwtMC43MTQ1OCAtMC4yMDkwNDksLTEuMTQ4MzggLTAuNjE0NzQ4LC0xLjYyNjIyIC0wLjE0ODIwNywtMC4xNzQ1NiAtMC4zNzIzNDgsLTAuNDQ0MSAtMC40OTgwOTIsLTAuNTk4OTggLTAuMjA5ODUxLC0wLjI1ODQ4IC0wLjI1NDY4MiwtMC4yOTQ3IC0wLjU0NjAwNywtMC40NDEwNyAtMC43MzU3NDMsLTAuMzY5NjYgLTEuOTI1ODY1LC0wLjY4MTk5IC0zLjIyMzkzNywtMC44NDYwOSAtMS4wODg1MzMsLTAuMTM3NiAtMS41OTQ0MzgsLTAuMTU5NjUgLTQuMDM4NDkyLC0wLjE3NjAxIC0yLjQ0MDU5MSwtMC4wMTYzIC0zLjM4MDEzLDAuMDA3IC00LjQ5NzQzLDAuMTA5NTggLTEuNTg2OTUxLDAuMTQ2MzMgLTIuOTUyNjA1LDAuNDY3MTMgLTMuODE1NjI4LDAuODk2MyBsIC0wLjM0Mzc1NCwwLjE3MDk0IC0wLjQ3NjQ0MiwwLjU2Nzk1IGMgLTAuNjcxMzczLDAuODAwMzIgLTAuODEzNTk4LDEuMTE4MyAtMC44NzAxOTEsMS45NDU1NSBsIC0wLjAyMzEyLDAuMzM3OTggeiIKICAgICAgIGlkPSJwYXRoMjM3IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAyNC4wNjUwNzYsMjgyLjMwNzE0IGMgLTAuNzYyNDk0LC0wLjM2ODcyIC0xLjQzNDgwNSwtMC42OTI5NiAtMS40OTQwMjUsLTAuNzIwNTIgbCAtMC4xMDc2NzIsLTAuMDUwMSAxLjQ0ODEwOSwtMC43MjM3NCAxLjQ0ODEwOCwtMC43MjM3MyAxLjM1MDQxNSwwLjY0NzU4IGMgMC43NDI3MjgsMC4zNTYxNiAxLjQyMjIxLDAuNjgxOSAxLjUwOTk2MSwwLjcyMzg2IGwgMC4xNTk1NDcsMC4wNzYzIC0xLjQ2NDA0NiwwLjcyMDQgLTEuNDY0MDQ0LDAuNzIwNCB6IgogICAgICAgaWQ9InBhdGgyMzkiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDE0LjY1NTA3NywyODMuMzgwNTYgYyAtMC42MTEwMjMsLTAuMjA1MzcgLTEuMTA3MTIsLTAuMzg0ODkgLTEuMTAyNDM3LC0wLjM5ODk0IDAuMDA0NywtMC4wMTQgMC40MTA4NjIsLTAuMzQ3MzYgMC45MDI2MjIsLTAuNzQwNjggbCAwLjg5NDEwOCwtMC43MTUxNCAxLjE2ODgyOSwwLjM4OTI1IGMgMC42NDI4NTYsMC4yMTQxIDEuMTY3ODg2LDAuMzk2OTEgMS4xNjY3MzQsMC40MDYyNiAtMC4wMDQ1LDAuMDM2NiAtMS44MTM2OTMsMS40MjA1NCAtMS44NjQ2NzEsMS40MjY0MSAtMC4wMjk4MywwLjAwMyAtMC41NTQxNjIsLTAuMTYxNzkgLTEuMTY1MTg1LC0wLjM2NzE2IHoiCiAgICAgICBpZD0icGF0aDI0MSIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMzQuMjYzNzk0LDI4My4wNDgyNSBjIC0wLjQ5NzU3NiwtMC4zOTA0NyAtMC45MDU0NDcsLTAuNzE3NTkgLTAuOTA2Mzg2LC0wLjcyNjk0IC0wLjAwMTEsLTAuMDA5IDAuNTIwNzI0LC0wLjE5MDkxIDEuMTU5MjQ4LC0wLjQwMzQ2IGwgMS4xNjA5NTIsLTAuMzg2NDYgMC45MDE5NDYsMC43MTIyMyBjIDAuNDk2MDcsMC4zOTE3MiAwLjkwNTc5MywwLjcyMzc2IDAuOTEwNDk3LDAuNzM3ODggMC4wMDgsMC4wMjQxIC0yLjIwNTYyMiwwLjc3NjY4IC0yLjI4NDcwMywwLjc3NjY4IC0wLjAyMDI5LDAgLTAuNDQzOTgxLC0wLjMxOTQ3IC0wLjk0MTU1NCwtMC43MDk5MyB6IgogICAgICAgaWQ9InBhdGgyNDMiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDM2LjY5NjU3NCwyODAuMjk4NTIgYyAtMi4zMjE1OTQsLTAuODA0MTMgLTUuMTg0OTUyLC0xLjI3Njc2IC04LjgxOTg5NiwtMS40NTU4MSAtMS4wNDYzNTgsLTAuMDUxNSAtMy45NTc5NzksLTAuMDUxMyAtNC45Nzc4OTQsNS4yZS00IC0zLjUyODksMC4xNzg5NCAtNi4xMjU0MTYsMC42MDA5OCAtOC40NzIyNjUsMS4zNzcwOSAtMC42OTUyMjgsMC4yMjk5MSAtMC43MzM0MjIsMC4yMzg2NyAtMC45NTgzNDIsMC4yMTk4MSAtMC42MzkyMjcsLTAuMDUzNiAtMC45ODc5NDksLTAuNTAwNTggLTAuOTUzNDUxLC0xLjIyMjE0IDAuMDE2OTIsLTAuMzUzODYgMC4xMjQyODUsLTAuNjA0NjIgMC4zNTk0MzMsLTAuODM5NDYgMC4xNzUwMDQsLTAuMTc0NzggMC42MDYyNzYsLTAuMzY2MiAxLjUzNzgzNiwtMC42ODI1NiAyLjY5NTEwOSwtMC45MTUyOSA1LjkwODg0MiwtMS4zNTg2IDEwLjIyNDA0MSwtMS40MTAzNSAzLjUzNDMzOCwtMC4wNDI0IDYuMTUwMjczLDAuMTgzNjUgOS4yMDIxNzMsMC43OTUxIDEuNTMzNzk3LDAuMzA3MyAzLjQyNjE1LDAuODYyNjggMy45MTQ0MzMsMS4xNDg4MyAwLjE5NzQxOSwwLjExNTcgMC4zOTk0NDUsMC4zNTgxNiAwLjQ4MjcxMiwwLjU3OTM0IDAuMDk3NjksMC4yNTk0OSAwLjA4MTQ1LDAuNzcxOTEgLTAuMDMyNjgsMS4wMzEwMiAtMC4wOTg5NywwLjIyNDcgLTAuMzM4Mjk0LDAuNDQ4MyAtMC41NzIzNTIsMC41MzQ3MyAtMC4zMzA4OTYsMC4xMjIyIC0wLjM3MDkzNiwwLjExODk0IC0wLjkzMzc1MiwtMC4wNzYgeiIKICAgICAgIGlkPSJwYXRoMjQ1IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAzMi43Mzc2NDMsMjc1LjM1ODEyIC0wLjU2Nzk0NywtMC4xMDY3NyAwLjAwNjUsLTAuNDgyMjcgYyAwLjAxOTYxLC0xLjQ2MjggMC4zMTI1NjUsLTMuMTI1ODEgMC43NjE3OTQsLTQuMzI0MjYgMC4xNzI1OTUsLTAuNDYwNDUgMC4yMjI2MiwtMC41NTAyNSAwLjM5NTA2MiwtMC43MDkyIDAuMjM4NzYsLTAuMjIwMDggMC42MzM0NzksLTAuMzAyMTkgMC45MzUyOTIsLTAuMTk0NTUgMC4zMTI2NiwwLjExMTUxIDAuMzkyMzEzLDAuMjk0MjggMC40MTU2ODksMC45NTM3OSAwLjAxMDY0LDAuMzAwNDUgMC4wMDE5LDAuNTk4ODkgLTAuMDIyNzUsMC43NzEyNyAtMC4wOTc5NCwwLjY4NjIxIC0wLjQ1MTM0NywyLjAwMzU1IC0wLjkyMDc3MSwzLjQzMjI1IC0wLjI1MDEsMC43NjExOCAtMC4yNTYwMDMsMC43NzQzOCAtMC4zNDQ2NjIsMC43NzA0OCAtMC4wNDk2MSwtMC4wMDIgLTAuMzQ1NzgyLC0wLjA1MiAtMC42NTgxNTQsLTAuMTEwNzQgeiIKICAgICAgIGlkPSJwYXRoMjQ3IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAzNS4yMDk4ODYsMjc1LjgzNTU4IGMgLTAuMDU1MTIsLTAuMDE4MSAtMC4yMDc5ODksLTAuMDcwNiAtMC4zMzk2OTksLTAuMTE2NjggbCAtMC4yMzk0NzQsLTAuMDgzOCAwLjI2MDUzNSwtMC43NzQzNiBjIDAuMjg1NDU2LC0wLjg0ODQzIDAuMzQ1MDU0LC0xLjAwMDM2IDAuNjQ0NDk4LC0xLjY0Mjk5IDAuMjM0NzEyLC0wLjUwMzcxIDAuMjk2NzMxLC0wLjU5Njc0IDAuNDQ0NTgsLTAuNjY2OSAwLjM0NzM2NiwtMC4xNjQ4NCAwLjYxNjAyMSwwLjExNTU4IDAuNjE2MDIxLDAuNjQyOTggMCwwLjM1MjA5IC0wLjMwMzQsMS4wODE4MyAtMC44OTQ5ODUsMi4xNTI2MyAtMC4xODA5NTYsMC4zMjc1NCAtMC4zMDk5NzgsMC41MjU4NyAtMC4zNDExMzgsMC41MjQzOSAtMC4wMjc1NiwtMC4wMDEgLTAuMDk1MjEsLTAuMDE3MiAtMC4xNTAzMzgsLTAuMDM1MyB6IgogICAgICAgaWQ9InBhdGgyNDkiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDMwLjQ0OTE0OCwyNzUuMDUzMTEgYyAtMC4xMzc4MTEsLTAuMDI0MSAtMC4zMzU2NjEsLTAuMDQ0NyAtMC40Mzk2NjYsLTAuMDQ1OSBsIC0wLjE4OTEwMSwtMC4wMDIgLTAuMDIzODcsLTAuMjg2NDggYyAtMC4wMzczOSwtMC40NDg4MSAwLjAwMzksLTEuNzg2NDEgMC4wNjc0MywtMi4xODU3NyAwLjEyMjY1MywtMC43NzA3MyAwLjIxMzI4NiwtMS4wMjM4NiAwLjQxNTMzOCwtMS4xNjAwMiAwLjE3NjE5OSwtMC4xMTg3NCAwLjMxMTYyOSwtMC4xMjkxNCAwLjQ5NTE1NywtMC4wMzggMC4zMzM1ODksMC4xNjU2NSAwLjQyNzg0NCwwLjQ4MDQ0IDAuMzk4NzI3LDEuMzMxNjcgLTAuMDIzMDIsMC42NzI5NSAtMC4xMDEwOTUsMS4yMDM2OCAtMC4zNDUyNjMsMi4zNDY5NiAtMC4wMjIwMSwwLjEwMzA0IC0wLjAxODM5LDAuMTAyNjYgLTAuMzc4NzY0LDAuMDM5NyB6IgogICAgICAgaWQ9InBhdGgyNTEiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDM3LjgzMjQ2NywyNzYuNjM1MjggYyAtMC43MjM3MjUsLTAuMjU5NTEgLTEuMjcxMjU2LC0wLjQ3MDA1IC0xLjI4NjQ3OCwtMC40OTQ2NyAtMC4wMDc4LC0wLjAxMjYgMC4xMzM1NjcsLTAuMzM3MDkgMC4zMTQwNjMsLTAuNzIxMTYgMC40MDMzMTUsLTAuODU4MiAwLjU3NTU4OCwtMS4yOTc2IDAuNzAxNTgsLTEuNzg5NDMgMC4xNTk3MzcsLTAuNjIzNTggMC4yMTA0MjYsLTAuOTc5MjggMC4yMjc3NTEsLTEuNTk4MjkgMC4wMTQ5NSwtMC41MzQzNSAwLjAxMDQsLTAuNjAwNDYgLTAuMDUzMTIsLTAuNzY4NCAtMC4xNDEzNTcsLTAuMzczODEgLTAuMzk4MDIxLC0wLjU2Nzk1IC0wLjc1MDg5MywtMC41Njc5NSAtMC4yMzE1OTUsMCAtMC4zOTkwMDUsMC4wNzc4IC0wLjYyNzYzMSwwLjI5MTY1IC0wLjE4NjM2OCwwLjE3NDMyIC0wLjE4MzkzMSwwLjE4MTA5IC0wLjEwNzYxMiwtMC4yOTg2NiAwLjA0NjI0LC0wLjI5MDY4IDAuMDQ4ODYsLTAuNDAzNyAwLjAxNjk2LC0wLjczMTcgLTAuMTE0NDksLTEuMTc3MyAtMC42MzQ1MSwtMS45MzcyNyAtMS41OTExMDYsLTIuMzI1MzEgLTAuMzIwMjg0LC0wLjEyOTkyIC0wLjUyMzg2NSwtMC4xMzk4NyAtMC44OTkwMTcsLTAuMDQzOSAtMC43MjIxMjIsMC4xODQ2OSAtMS4zMDg2MTYsMC43MDc1OSAtMS43MDYwMDcsMS41MjEwMyAtMC4xNzA1MTMsMC4zNDkwNCAtMC4zODYzMTMsMC45NTU3OSAtMC40MzY3OTUsMS4yMjgxNCAtMC4wMTI4MSwwLjA2OTEgLTAuMDMzMzcsMC4xMzE4OCAtMC4wNDU3LDAuMTM5NSAtMC4wMTIzMywwLjAwOCAtMC4wNTgxOCwtMC4wNzg0IC0wLjEwMTkwMSwtMC4xOTExNyAtMC4wNTIxNiwtMC4xMzQ1MSAtMC4xMzMzNTYsLTAuMjU4ODggLTAuMjM2MTAxLC0wLjM2MTYyIC0wLjEzODcxNiwtMC4xMzg3MiAtMC4xODY3NDgsLTAuMTYzNTkgLTAuNDIwNDk3LC0wLjIxNzcgLTAuNTEzNjQ2LC0wLjExODkyIC0wLjgxOTgyNSwtMC4wNTQ2IC0xLjAyMDc1NSwwLjIxNDU5IC0wLjM2NjM5NywwLjQ5MDc4IC0wLjY1NTc4OCwxLjE5MjIyIC0wLjgwOTExMSwxLjk2MTE4IC0wLjExMDI2MywwLjU1MyAtMC4yMTkzNDMsMS41ODEzMSAtMC4yNDE5NDMsMi4yODA3OSAtMC4wMjAzMiwwLjYyODg0IC0wLjAyOTExLDAuNzA4NzkgLTAuMDc2MzgsMC42OTQ5NyAtMC4yMDc4OTksLTAuMDYwOCAtMC41NjAzNCwtMC4wOTUxIC0wLjk5ODY4LC0wLjA5NzMgbCAtMC41MTA5NSwtMC4wMDMgMC4wMTc3NSwtMC40MzU3MSBjIDAuMDA5OCwtMC4yMzk2NCAwLjAyNjA0LC0wLjY2MTIyIDAuMDM2MTcsLTAuOTM2ODQgMC4xMDIxOSwtMi43ODI4NiAwLjcwNDMzOSwtNi42OTI2MiAxLjIyNzE2NCwtNy45Njc5NyAwLjE2Mzc0NSwtMC4zOTk0NCAwLjI4MTI0NCwtMC41NTA5OSAwLjg4MDY0MiwtMS4xMzU5IDAuODU4NDE0LC0wLjgzNzY2IDEuNTUzNjIsLTEuMzUxNzggMi40NjgzMDYsLTEuODI1MzggMC44NDMyNjEsLTAuNDM2NjEgMS43NTI3NzQsLTAuNzMyMjMgMi42NzMxNjIsLTAuODY4ODUgMC41NTU4NjUsLTAuMDgyNSAxLjgxNDM0MywtMC4wODI5IDIuMzU0ODQ0LC02LjZlLTQgMS40NDY4NjksMC4yMjAwNiAyLjQ2MDMsMC43MTAyMSAzLjM5MzI2MywxLjY0MTE3IDAuODkwMDQ1LDAuODg4MTMgMS4zMzc2ODMsMS44MTI0MyAxLjUzOTQ0MSwzLjE3ODcxIDAuMDcxMDUsMC40ODExMyAwLjA4MTA4LDEuODI1MzMgMC4wMTgwNSwyLjQxODU5IC0wLjI0OTc0MSwyLjM1MDQ5IC0xLjA0NjgwOSw0LjQ3NzkyIC0yLjQ3ODE4MSw2LjYxNDQzIC0wLjI3Mzg4OCwwLjQwODgyIC0wLjk0OTc3NywxLjMyMzI4IC0wLjk5NDY1NiwxLjM0NTc1IC0wLjAxMzU1LDAuMDA3IC0wLjIyNzU4OSwtMC4wNjA1IC0wLjQ3NTY0OSwtMC4xNDk0IHoiCiAgICAgICBpZD0icGF0aDI1MyIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMTkuNzY1NTY3LDI3NC43OTYzIGMgLTAuMjMwNTIsLTEuMDA1NiAtMC4zMTkzNzQsLTEuNzE5NDEgLTAuMzAxNDgyLC0yLjQyMTk0IDAuMDExNzQsLTAuNDYxMDIgMC4wMjMwNywtMC41NDgxOCAwLjA5MTI1LC0wLjcwMjAyIDAuMTUyMjQ0LC0wLjM0MzUyIDAuNDI1NjE0LC0wLjQ3NjI0IDAuNzE2MTk3LC0wLjM0NzcgMC4yNzA0MjEsMC4xMTk2MiAwLjM2NzQwNywwLjM1MzczIDAuNDkyNDQsMS4xODg3IDAuMDc1MDcsMC41MDEyOSAwLjExOTI2NywxLjY3MDkzIDAuMDgxODYsMi4xNjYwMyBsIC0wLjAyNDYxLDAuMzI1NzMgLTAuMTcyMjc4LDEuNGUtNCBjIC0wLjA5NDc1LDZlLTUgLTAuMzA3NTgzLDAuMDIyNCAtMC40NzI5NTYsMC4wNDk1IC0wLjE2NTM3MywwLjAyNzIgLTAuMzA5NDI5LDAuMDQ5NyAtMC4zMjAxMjMsMC4wNSAtMC4wMTA3LDIuNmUtNCAtMC4wNTEzMiwtMC4xMzg0OCAtMC4wOTAyOSwtMC4zMDg0NSB6IgogICAgICAgaWQ9InBhdGgyNTUiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDE2LjkyMjc2MywyNzQuNzYyODkgYyAtMC40MDU5MzcsLTEuMjMxOCAtMC43MTcwNTYsLTIuMzMzOSAtMC44Nzk0NTEsLTMuMTE1MzYgLTAuMTAzMTExLC0wLjQ5NjE3IC0wLjExMjMxNiwtMS41MTE2NSAtMC4wMTU5NiwtMS43NjEzNiAwLjEzMzA0LC0wLjM0NDc5IDAuNTAxNDIxLC0wLjQ3NTkxIDAuOTU2OTc2LC0wLjM0MDYyIDAuMjg5NDI0LDAuMDg1OSAwLjQ5MTY5OCwwLjMxNTM1IDAuNjYxOTEsMC43NTA3IDAuMzE0MzczLDAuODA0MDYgMC41NTEzMDUsMS44MDQ2NyAwLjY5MTc3MSwyLjkyMTQ5IDAuMDg0OTEsMC42NzUxMiAwLjE2NDk0NSwxLjcyODY2IDAuMTQ1NzA4LDEuOTE4MDggbCAtMC4wMTE1OCwwLjExNDAxIC0wLjYwMTM1NywwLjExMDUxIGMgLTAuMzMwNzQ2LDAuMDYwOCAtMC42MjY3MTMsMC4xMTA5NSAtMC42NTc3MDYsMC4xMTE0OSAtMC4wNDM5Niw4ZS00IC0wLjEwNzc2OSwtMC4xNTUwNCAtMC4yOTAzMDYsLTAuNzA4OTQgeiIKICAgICAgIGlkPSJwYXRoMjU3IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAxNS4wNjc1OTMsMjc1LjU4MDU5IGMgLTAuNzU0MywtMS4zNDE2MyAtMS4wMjIzMSwtMS45Njg4MSAtMS4wMjE5MjYsLTIuMzkxNDMgMi41N2UtNCwtMC4yODM2IDAuMDUzNjgsLTAuNDQ5NTggMC4xODc5MDcsLTAuNTgzOCAwLjEwNDY5MSwtMC4xMDQ2OSAwLjEyNzMwMiwtMC4xMTI5NCAwLjI2NjY4NiwtMC4wOTcyIDAuMzMwNDYsMC4wMzcyIDAuNTA4MzA3LDAuMzYwMTEgMS4wOTQyMjQsMS45ODY0NyAwLjExNzcwNCwwLjMyNjcxIDAuMjU5OTY3LDAuNzE2NzQgMC4zMTYxMzksMC44NjY3MiBsIDAuMTAyMTMxLDAuMjcyNyAtMC4zNjgyNjksMC4xMTk4NSBjIC0wLjIwMjU0OCwwLjA2NTkgLTAuMzc4MzMzLDAuMTE5NSAtMC4zOTA2MzMsMC4xMTkwNSAtMC4wMTIzLC01LjNlLTQgLTAuMDk2MTIsLTAuMTMyIC0wLjE4NjI1OSwtMC4yOTIzMyB6IgogICAgICAgaWQ9InBhdGgyNTkiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDEyLjIzMzU0OCwyNzYuNTE2ODUgYyAtMS4wNDMxMjUsLTEuMjUzNzcgLTEuOTYzNzA0LC0yLjc4Mzg2IC0yLjUwNzUwNjEsLTQuMTY3NzQgLTAuNDQ0NzEyMiwtMS4xMzE3IC0wLjcwMjA2MjYsLTIuMTYyIC0wLjg0NzAwNTMsLTMuMzkwOTggLTAuMDcxNjIxLC0wLjYwNzI4IC0wLjA4MTE3LC0xLjk3NjEzIC0wLjAxNzAxMywtMi40Mzg4MyAwLjE3Nzk5MzQsLTEuMjgzNjYgMC42MDUwNDI4LC0yLjI2OTkyIDEuMzMwNjU5NCwtMy4wNzMxIDAuOTUwMTI4LC0xLjA1MTcgMi4wNTc5NDEsLTEuNjIxMDIgMy42MTg5MzYsLTEuODU5ODMgMC41NDA3NDIsLTAuMDgyNyAxLjgwMzM5MSwtMC4wODMyIDIuMzM4NjA4LC04LjdlLTQgMS41NzE2ODQsMC4yNDE3NSAzLjAwMTYzNCwwLjg4MzkxIDQuMzI2ODcyLDEuOTQzMTEgMC4xODM1MDIsMC4xNDY2NiAwLjU4NDI5OCwwLjUxMjU3IDAuODkwNjU4LDAuODEzMTMgMC42MzE4NzksMC42MTk5MSAwLjcwNTA2MSwwLjczMDI2IDAuOTEyMzM3LDEuMzc1NzQgMC40MDI4ODIsMS4yNTQ2MiAwLjg1NDE5Niw0LjAyMzYyIDEuMDM0NTkzLDYuMzQ3NjUgMC4wNTUzNCwwLjcxMjkgMC4xMTc3NDgsMS45OTUyNiAwLjExODI5MSwyLjQzMDQ5IGwgMy40NGUtNCwwLjI3NTYyIC0wLjQ0MjY2NSwwLjAwMiBjIC0wLjI0MzQ2NiwwLjAwMSAtMC41Nzc5NzEsMC4wMjE3IC0wLjc0MzM0NCwwLjA0NTYgLTAuMTY1MzczLDAuMDIzOSAtMC4zMDUxNjUsMC4wMzk3IC0wLjMxMDY1LDAuMDM1MSAtMC4wMjE0MiwtMC4wMTc4IC0wLjA3NjMxLC0wLjY2NDYgLTAuMTA3NjgzLC0xLjI2ODk4IC0wLjA2ODQ2LC0xLjMxODc1IC0wLjI1MDcxLC0yLjIxOTYgLTAuNjAzNjY1LC0yLjk4MzkgLTAuMTY4MTUyLC0wLjM2NDEyIC0wLjQ0NjMwNCwtMC43ODI3MyAtMC41Njc3NzQsLTAuODU0NDkgLTAuMTgyNTE3LC0wLjEwNzgxIC0wLjQ0MzU4OSwtMC4xMjU3NyAtMC43NzU0NTUsLTAuMDUzMyAtMC40MjM3NzEsMC4wOTI1IC0wLjU4NjgyMywwLjIzNDc5IC0wLjc1NjIzNSwwLjY2MDAxIC0wLjAzODQ4LDAuMDk2NiAtMC4wNjk0NiwwLjEzODYxIC0wLjA3OTYxLDAuMTA3OTkgLTAuMDA5MSwtMC4wMjc2IC0wLjA3MTA2LC0wLjIzNTg3IC0wLjEzNzU5MywtMC40NjI5IC0wLjMyODM0NiwtMS4xMjA0IC0wLjg3ODI0LC0xLjg4ODcyIC0xLjYwNTgyMSwtMi4yNDM2NyAtMC41MzEwODQsLTAuMjU5MSAtMC45MTUzNjYsLTAuMjk0NjIgLTEuMzM2OTg4LC0wLjEyMzU5IC0wLjk1NzQ4MywwLjM4ODQgLTEuNDY5NDg4LDEuMTM1NjggLTEuNTg3ODQsMi4zMTc1MSAtMC4wMzQyNCwwLjM0MTkzIC0wLjAzMjIxLDAuNDQ4MTYgMC4wMTQyMSwwLjc0MTIxIDAuMDc1MDEsMC40NzM1NyAwLjA3NjUzLDAuNDY3NTkgLTAuMDgyNTEsMC4zMjM5IC0wLjI2NDIzMiwtMC4yMzg3MiAtMC40MjQ1MjQsLTAuMzE4NiAtMC42MzkzMjMsLTAuMzE4NiAtMC4zMzI0MTcsMCAtMC41NjA5NTQsMC4xNCAtMC43MDkwMDksMC40MzQzMiAtMC4xMTI1NDUsMC4yMjM3MiAtMC4xMjQ0NDQsMC4zMDU2OCAtMC4xMjEyNTcsMC44MzUyMSAwLjAwNjYsMS4wOTE2MiAwLjI2MzY3LDIuMDQ1MTcgMC45NDQzNzIsMy41MDI1NSAwLjE4MzE0MywwLjM5MjExIDAuMzI4MDY2LDAuNzE3ODMgMC4zMjIwNTEsMC43MjM4NCAtMC4wMDYsMC4wMDYgLTAuMjI4OTI3LDAuMDg5MSAtMC40OTUzNjEsMC4xODQ2NyAtMC4yNjY0MzUsMC4wOTU2IC0wLjYxOTczMSwwLjIzMjA5IC0wLjc4NTEwNCwwLjMwMzQgLTAuMTY1MzczLDAuMDcxMyAtMC4zMTE2MTksMC4xMjk2OCAtMC4zMjQ5OSwwLjEyOTcyIC0wLjAxMzM3LDRlLTUgLTAuMTMzNzU4LC0wLjEzMTQ2IC0wLjI2NzUyNSwtMC4yOTIyNCB6IgogICAgICAgaWQ9InBhdGgyNjEiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDI0LjU5NDE4NiwyNjUuODg2OTYgYyAtMC42OTEzNiwtMC4xNTAzOSAtMS4xNjUwNzgsLTAuNTA0NyAtMS40NDAyMTksLTEuMDc3MiAtMC4yMTgyMDQsLTAuNDU0MDMgLTAuMjcxNTc5LC0wLjczMDgyIC0wLjI2OTQ4NiwtMS4zOTc0NyAwLjAwMTQsLTAuNDUzNjEgMC4wMTQ5MSwtMC42MDQ1IDAuMDc2MTMsLTAuODUxOTIgMC4yNTE4MTcsLTEuMDE3NjUgMC45Mzg0NjEsLTEuNTU5ODIgMi4wOTI0NTIsLTEuNjUyMTggMS4yNjA3MDgsLTAuMTAwOTEgMi4yMDk3NDQsMC4zMDA4IDIuNjAwOTMzLDEuMTAwOTMgMC4yMjI1MzEsMC40NTUxNiAwLjI2ODMyMiwwLjY5NzQ3IDAuMjY4MzIyLDEuNDE5ODcgMCwwLjU0ODUzIC0wLjAwOTksMC42NzEwOCAtMC4wNzI5MSwwLjkwMjA0IC0wLjIxODkxMSwwLjgwMjQ4IC0wLjY5NTcxNCwxLjI5MzgxIC0xLjQ3NjY3MSwxLjUyMTY2IC0wLjM2NTg5NywwLjEwNjc2IC0xLjM1NzQ3OSwwLjEyNTg2IC0xLjc3ODU1NiwwLjAzNDMgeiIKICAgICAgIGlkPSJwYXRoMjYzIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAyMy43MDQzNTEsMjU5LjExMDkyIGMgMC4wOTk1MywtMC4xMDU2NSAwLjQyNzQ2OCwtMC40NTk1MSAwLjcyODc0LC0wLjc4NjM1IGwgMC41NDc3NjksLTAuNTk0MjQgMC4xNTMzMjIsMC4wMjYxIGMgMC4xNTg1MTIsMC4wMjcgMC40MDMwNiwwLjAyNDggMC41MjIxOTgsLTAuMDA1IDAuMDU0MDQsLTAuMDEzNCAwLjIzMDgwNywwLjE0NTg4IDAuODUxNjU2LDAuNzY3MTUgbCAwLjc4MzQ1OCwwLjc4Mzk5IGggLTEuODg0MDU5IC0xLjg4NDA1NyB6IgogICAgICAgaWQ9InBhdGgyNjUiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDI3LjI3MzMwNiwyNTcuNzY5ODggLTAuODUzOTM4LC0wLjY1MTA0IDAuMDI5OTcsLTAuMTk3OTkgYyAwLjAxOTQsLTAuMTI4MTQgMC4wMTcyNSwtMC4yNzAxNSAtMC4wMDYxLC0wLjQwMjU3IC0wLjA0Mjc5LC0wLjI0Mjk1IC0wLjE1NjkwNywtMC4xMDc0MSAwLjkxNTU4MiwtMS4wODc0OCBsIDAuNzY4NCwtMC43MDIxOCAwLjAwODksMC45MTUwNyBjIDAuMDA0OSwwLjUwMzI5IDAuMDA0OSwxLjMzNDA2IDAsMS44NDYxNSBsIC0wLjAwODksMC45MzEwOCB6IgogICAgICAgaWQ9InBhdGgyNjciCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDI0LjI3NzQzLDI1NC43NzE4NCAtMC43NDA4MiwtMC45NDc4NSBoIDEuODc1NjA3IDEuODc1NjA3IGwgLTAuMDg0MTYsMC4wOTE5IGMgLTAuMDQ2MjksMC4wNTA1IC0wLjQwMjAwMywwLjQ2OTI1IC0wLjc5MDQ4LDAuOTMwNDggbCAtMC43MDYzMjEsMC44Mzg2MSAtMC4yNDg3MTMsLTAuMDE2IGMgLTAuMTM2NzkzLC0wLjAwOSAtMC4yOTE3MywtOS44ZS00IC0wLjM0NDMwNiwwLjAxNzQgLTAuMDk1MTIsMC4wMzMyIC0wLjA5OTIzLDAuMDI4NyAtMC44MzY0MTMsLTAuOTE0NTIgeiIKICAgICAgIGlkPSJwYXRoMjY5IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAyMi42NjQ5MjMsMjU2LjU3NDk3IHYgLTEuODU5OSBsIDAuMjQyMjEzLDAuMjI5NTMgYyAwLjEzMzIxNywwLjEyNjI0IDAuNTIzNDM4LDAuNTA1MzEgMC44NjcxNTYsMC44NDIzOCAwLjU4NDE1NywwLjU3Mjg3IDAuNjIyODU5LDAuNjE4MzUgMC41OTMwMDUsMC42OTY4NyAtMC4wNDA2MSwwLjEwNjgxIC0wLjA0MTUsMC40MzM2NyAtMC4wMDE0LDAuNTA4NjIgMC4wMjU0NSwwLjA0NzYgLTAuMTEzOTQ0LDAuMTcyNjcgLTAuODM1MjE3LDAuNzQ5NzQgbCAtMC44NjU3NjIsMC42OTI2NyB6IgogICAgICAgaWQ9InBhdGgyNzEiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogIDwvZz4KPC9zdmc+Cg=='); } -body.base .is2d piece.pawn.black { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMTQ0cHQiCiAgIGhlaWdodD0iMTQ0cHQiCiAgIHZpZXdCb3g9IjAgMCA1MC44MDAwMDEgNTAuOCIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnOCIKICAgc29kaXBvZGk6ZG9jbmFtZT0iYnAuc3ZnIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkyLjMgKDI0MDU1NDYsIDIwMTgtMDMtMTEpIj4KICA8ZGVmcwogICAgIGlkPSJkZWZzMiIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9ImJhc2UiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEuMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6em9vbT0iMy45NTk3OTgiCiAgICAgaW5rc2NhcGU6Y3g9Ii02NC4yMjA1NDUiCiAgICAgaW5rc2NhcGU6Y3k9IjEzMC41NTEyNCIKICAgICBpbmtzY2FwZTpkb2N1bWVudC11bml0cz0ibW0iCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ibGF5ZXIxIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICB1bml0cz0icHQiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIzODQwIgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjIwMzUiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9Ii0xMyIKICAgICBpbmtzY2FwZTp3aW5kb3cteT0iLTEzIgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiIC8+CiAgPG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhNSI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGUgLz4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGcKICAgICBpbmtzY2FwZTpsYWJlbD0iTGF5ZXIgMSIKICAgICBpbmtzY2FwZTpncm91cG1vZGU9ImxheWVyIgogICAgIGlkPSJsYXllcjEiCiAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwtMjQ2LjIpIj4KICAgIDxnCiAgICAgICBhcmlhLWxhYmVsPSJvIgogICAgICAgc3R5bGU9ImZvbnQtc3R5bGU6bm9ybWFsO2ZvbnQtdmFyaWFudDpub3JtYWw7Zm9udC13ZWlnaHQ6bm9ybWFsO2ZvbnQtc3RyZXRjaDpub3JtYWw7Zm9udC1zaXplOjUwLjc5OTk5OTI0cHg7bGluZS1oZWlnaHQ6MS4yNTtmb250LWZhbWlseTonQ2hlc3MgTGVpcHppZyc7LWlua3NjYXBlLWZvbnQtc3BlY2lmaWNhdGlvbjonQ2hlc3MgTGVpcHppZyc7bGV0dGVyLXNwYWNpbmc6MHB4O3dvcmQtc3BhY2luZzowcHg7ZmlsbDojMDAwMDAwO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDowLjI2NDU4MzMyIgogICAgICAgaWQ9InRleHQyNyIKICAgICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuMDAxMTUyLDAuMDc1ODUpIj4KICAgICAgPHBhdGgKICAgICAgICAgZD0iTSAyNS40MTI0MDIsMjkzLjYxNDE1IEggMTEuODkzODQ4IHEgMC40NzEyODksLTUuMzMzMDEgNC41MzkyNTgsLTkuMDA0MSAwLjY2OTcyNiwtMC42MjAxMiAwLjc0NDE0LC0wLjY2OTczIDIuMTA4Mzk5LC0xLjczNjMzIDMuNTk2NjgsLTQuMTQyMzggLTMuODE5OTIyLC0yLjUwNTI4IC0zLjgxOTkyMiwtNy4wNjkzNCAwLC0yLjgyNzczIDEuNzExNTIzLC01LjA4NDk2IDAuNTcwNTA4LC0wLjcxOTM0IDEuMjE1NDMsLTEuNjM3MTEgMC42Njk3MjcsLTAuOTE3NzcgMS4wNjY2MDIsLTEuNzg1OTQgLTAuNTk1MzEzLDAuMTQ4ODMgLTEuODEwNzQyLDAuNDcxMjkgLTEuMTkwNjI1LDAuMzIyNDYgLTEuNzYxMTMzLDAuNTQ1NzEgMS43MTE1MjMsLTEuNTg3NSAzLjI0OTQxNCwtMy43NzAzMiAxLjU2MjY5NSwtMi4xODI4MSAxLjgzNTU0NywtNC42Mzg0NyAtMS4yNjUwMzksLTEuMjg5ODUgLTEuMjY1MDM5LC0zLjAyNjE3IDAsLTEuNzM2MzMgMS4yMTU0MjksLTIuOTc2NTcgMS4yNDAyMzUsLTEuMjQwMjMgMy4wMDEzNjcsLTEuMjQwMjMgMS43MTE1MjQsMCAyLjk1MTc1OCwxLjI0MDIzIDEuMjQwMjM0LDEuMjQwMjQgMS4yNDAyMzQsMi45NzY1NyAwLDEuNzYxMTMgLTEuMjY1MDM5LDMuMDI2MTcgMC4yNzI4NTIsMi40NTU2NiAxLjgzNTU0Nyw0LjYzODQ3IDEuNTg3NSwyLjE4MjgyIDMuMjk5MDI0LDMuNzcwMzIgLTAuNTcwNTA4LC0wLjIyMzI1IC0xLjgxMDc0MiwtMC41NDU3MSAtMS4yMTU0MywtMC4zMjI0NiAtMS44MTA3NDMsLTAuNDcxMjkgMC4zOTY4NzUsMC44NjgxNyAxLjA0MTc5NywxLjc4NTk0IDAuNjY5NzI3LDAuOTE3NzcgMS4yNjUwMzksMS42MzcxMSAxLjcxMTUyNCwyLjI1NzIzIDEuNzExNTI0LDUuMDg0OTYgMCw0LjU2NDA2IC0zLjgxOTkyMiw3LjA2OTM0IDEuNDEzODY3LDIuMzgxMjUgMy41NzE4NzUsNC4xNDIzOCAwLjM3MjA3LDAuMjk3NjYgMC43NDQxNCwwLjY2OTczIDQuMDkyNzc0LDMuNjcxMDkgNC41MzkyNTgsOS4wMDQxIHoiCiAgICAgICAgIHN0eWxlPSJzdHJva2Utd2lkdGg6MC4yNjQ1ODMzMiIKICAgICAgICAgaWQ9InBhdGgyOSIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDwvZz4KICA8L2c+Cjwvc3ZnPgo='); } -body.base .is2d piece.knight.black { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMTQ0cHQiCiAgIGhlaWdodD0iMTQ0cHQiCiAgIHZpZXdCb3g9IjAgMCA1MC44MDAwMDEgNTAuOCIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnOCIKICAgc29kaXBvZGk6ZG9jbmFtZT0iYm4uc3ZnIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkyLjMgKDI0MDU1NDYsIDIwMTgtMDMtMTEpIj4KICA8ZGVmcwogICAgIGlkPSJkZWZzMiIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9ImJhc2UiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEuMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6em9vbT0iNy45MTk1OTU5IgogICAgIGlua3NjYXBlOmN4PSI1NC45OTgwNSIKICAgICBpbmtzY2FwZTpjeT0iMTAxLjIxMjU5IgogICAgIGlua3NjYXBlOmRvY3VtZW50LXVuaXRzPSJtbSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJsYXllcjEiCiAgICAgc2hvd2dyaWQ9ImZhbHNlIgogICAgIHVuaXRzPSJwdCIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjM4NDAiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iMjAzNSIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iLTEzIgogICAgIGlua3NjYXBlOndpbmRvdy15PSItMTMiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIgLz4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGE1Ij4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICAgIDxkYzp0aXRsZSAvPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZwogICAgIGlua3NjYXBlOmxhYmVsPSJMYXllciAxIgogICAgIGlua3NjYXBlOmdyb3VwbW9kZT0ibGF5ZXIiCiAgICAgaWQ9ImxheWVyMSIKICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLC0yNDYuMikiPgogICAgPGcKICAgICAgIGFyaWEtbGFiZWw9Im0iCiAgICAgICBzdHlsZT0iZm9udC1zdHlsZTpub3JtYWw7Zm9udC12YXJpYW50Om5vcm1hbDtmb250LXdlaWdodDpub3JtYWw7Zm9udC1zdHJldGNoOm5vcm1hbDtmb250LXNpemU6NTAuNzk5OTk5MjRweDtsaW5lLWhlaWdodDoxLjI1O2ZvbnQtZmFtaWx5OidDaGVzcyBMZWlwemlnJzstaW5rc2NhcGUtZm9udC1zcGVjaWZpY2F0aW9uOidDaGVzcyBMZWlwemlnJztsZXR0ZXItc3BhY2luZzowcHg7d29yZC1zcGFjaW5nOjBweDtmaWxsOiMwMDAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjAuMjY0NTgzMzIiCiAgICAgICBpZD0idGV4dDEwMSIKICAgICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuMTcyMzMwNDMsMS41NjE1NCkiPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDI4LjQ4NDA0OSwyNzQuNzI1MzggcSAwLjYyMDExOCwtMC4xMjQwMiAxLjM4OTA2MywtMC4yNzI4NSAwLjc5Mzc1LC0wLjE3MzY0IDEuNjg2NzE5LC0wLjQ3MTI5IDAuNzkzNzUsLTAuMjQ4MDUgMC41MjA4OTgsLTAuODkyOTcgLTAuMTczNjMzLC0wLjI3Mjg1IC0wLjQ5NjA5NCwtMC4yNzI4NSAtMS43NjExMzIsMC4zOTY4NyAtMy4zMjM4MjgsMC40NzEyOSAwLjU5NTMxMywtMC4yMjMyNSAxLjI0MDIzNSwtMC40NDY0OSAwLjY0NDkyMSwtMC4yNDgwNCAxLjI2NTAzOSwtMC41NDU3IDEuOTM0NzY1LC0wLjkxNzc3IDIuNTU0ODgyLC00LjAxODM2IDAuMTI0MDI0LC0wLjcxOTM0IC0wLjQ3MTI4OSwtMC44MTg1NSAtMC41MjA4OTgsLTAuMDQ5NiAtMC44MTg1NTQsMC40MjE2OCAtMC41OTUzMTMsMi4yMDc2MSAtMS44ODUxNTcsMi45NzY1NiAtMC40MjE2NzksMC4yNDgwNCAtMC44NjgxNjQsMC40NDY0OCAtMC40NDY0ODQsMC4xOTg0NCAtMC44OTI5NjgsMC40MjE2OCAwLjQ5NjA5MywtMC41MjA5IDAuOTE3NzczLC0xLjI2NTA0IDAuNzY4OTQ1LC0xLjI4OTg0IDEuMDQxNzk3LC00LjU2NDA2IC0wLjE3MzYzMywtMC44NjgxNiAtMC44NjgxNjQsLTAuNjQ0OTIgLTAuMjIzMjQyLDAuMTI0MDIgLTAuMjk3NjU2LDAuMjIzMjQgLTAuNDQ2NDg1LDMuNTIyMjcgLTEuMjE1NDMsNC42Mzg0OCAtMC4yNzI4NTIsMC4yNzI4NSAtMC4zNzIwNywwLjQ3MTI5IC0wLjIyMzI0MiwwLjE3MzYzIC0wLjQyMTY4LDAuMzQ3MjYgLTAuMTczNjMzLDAuMTQ4ODMgLTAuMzQ3MjY2LDAuMjk3NjYgLTAuNDIxNjc5LDAuNTQ1NyAtMC40MjE2NzksMS4yNDAyMyAwLDAuODQzMzYgMC40NzEyODksMS41Mzc4OSAwLjQ5NjA5NCwwLjY5NDUzIDEuNjEyMzA0LDAuNzE5MzQgeiBtIC0xLjc2MTEzMiwtMTYuNzE4MzYgcSA2Ljg3MDg5OCwzLjM3MzQ0IDEwLjE0NTExNyw4LjI4NDc3IDIuMDA5MTc5LDMuMDUwOTcgMi42Nzg5MDYsNy4yNDI5NiAwLjY2OTcyNiw0LjE5MiAwLjY2OTcyNiw5LjQwMDk4IC0wLjEyNDAyMywyLjAwOTE4IDEuMTE2MjExLDMuNTIyMjcgMS4yNjUwMzksMS41MTMwOCAyLjgyNzczNSwxLjE5MDYyIDAuNDcxMjg5LC0xNS4wODEyNSAtNS4zNTc4MTMsLTIyLjk5Mzk0IC0xLjc4NTkzNywtMi4zODEyNSAtNC45ODU3NDIsLTQuNjEzNjggLTMuMTk5ODA0LC0yLjIzMjQyIC03LjE0Mzc1LC0zLjk5MzU1IDAsMC41MjA5IDAuMDI0OCwxLjA2NjYgMC4wMjQ4MSwwLjUyMDkgMC4wMjQ4MSwwLjg5Mjk3IHogbSAtMTQuNTg1MTU2LDIwLjc2MTUyIHEgMC4yNzI4NTEsLTAuNDQ2NDggMC42MjAxMTcsLTAuODY4MTYgMC4zNzIwNywtMC40NDY0OSAwLjY2OTcyNiwtMC45OTIxOSAwLjU0NTcwMywtMS4xMTYyMSAtMC41NDU3MDMsLTEuMzE0NjUgLTAuMTk4NDM3LC0wLjA0OTYgLTAuNDQ2NDg0LDAuMDQ5NiAtMC43MTkzMzYsMC45NjczOCAtMS41NjI2OTUsMS45NTk1NyAtMC4xMjQwMjQsMC4wOTkyIC0wLjU3MDUwOCwwLjQ5NjEgLTAuMjIzMjQyLDAuNzQ0MTQgLTAuMDI0OCwxLjE0MTAxIDAuMzIyNDYxLDAuNzQ0MTQgMS4yMTU0MywwLjA5OTIgMC40NDY0ODQsLTAuMzQ3MjcgMC42NDQ5MjIsLTAuNTcwNTEgeiBtIDguNzMxMjQ5LC02LjM3NDggcSAwLjA3NDQyLC0wLjI5NzY2IDAuMTczNjMzLC0wLjU5NTMxIDAuMTI0MDI0LC0wLjI5NzY2IDAuMTk4NDM4LC0wLjU5NTMyIDAuMjIzMjQyLC0wLjk2NzM4IC0wLjU0NTcwMywtMC45NjczOCAtMC4yNzI4NTIsMCAtMC42Njk3MjcsMC40NDY0OCAtMC4xNzM2MzMsMC4zOTY4OCAtMC4zNDcyNjUsMC43OTM3NSAtMC4xNzM2MzMsMC4zNzIwOCAtMC4yNzI4NTIsMC42OTQ1NCAtMC4wNzQ0MSwwLjI0ODA0IC0wLjIyMzI0MiwwLjY5NDUzIC0wLjA0OTYxLDAuMzcyMDcgMC4yOTc2NTYsMC41NDU3IDAuNTIwODk4LDAuMjk3NjYgMS4wNjY2MDIsLTAuNDcxMjkgMC4xNzM2MzIsLTAuMTczNjMgMC4zMjI0NiwtMC41NDU3IHogbSAtMTEuNTgzNzg4NCwxLjk4NDM3IHEgMC4yNDgwNDY5LC0wLjM0NzI2IDAuNTcwNTA3OCwtMC42OTQ1MyAwLjMyMjQ2MDYsLTAuMzcyMDcgMC41NzA1MDc2LC0wLjgxODU1IDAuNDk2MDk0LC0wLjkxNzc4IC0wLjQ3MTI4ODksLTEuMDY2NiAtMC4xNDg4MjgxLC0wLjAyNDggLTAuNDIxNjc5NiwwLjAyNDggLTAuNTk1MzEyNSwwLjc2ODk1IC0xLjM4OTA2MjUsMS42MTIzIC0wLjI5NzY1NjMsMC4yMjMyNSAtMC40OTYwOTM4LDAuMzk2ODggLTAuMTk4NDM3NSwwLjYyMDEyIC0wLjAyNDgwNSwwLjkxNzc3IDAuMjk3NjU2MiwwLjYyMDEyIDEuMDkxNDA2MiwwLjA5OTIgMC4zOTY4NzUsLTAuMjk3NjUgMC41NzA1MDc4LC0wLjQ3MTI5IHogbSA3LjMxNzM4MjQsLTExLjAxMzI4IHEgMC4xNzM2MzMsMS4wNjY2IDAuNTcwNTA4LDEuMjE1NDMgMC4zOTY4NzUsMC4xNDg4MyAxLjExNjIxMSwwLjA5OTIgMC45NjczODMsLTAuMDc0NCAxLjQ4ODI4MSwtMC4zOTY4NyAxLjA0MTc5NywtMC42Njk3MyAxLjgzNTU0NywtMi45MDIxNSAtMC43OTM3NSwwLjI0ODA0IC0xLjQ4ODI4MSwwLjI0ODA0IC0wLjY5NDUzMSwwIC0xLjY2MTkxNCwwLjA3NDQgLTEuMzY0MjU4LDAuMTI0MDIgLTEuODYwMzUyLDEuNjYxOTEgeiBtIC0wLjMyMjQ2MSwxNC4zODY3MiBxIC0wLjM0NzI2NSwwLjM3MjA3IC0wLjU3MDUwNywwLjU0NTcgLTAuMTk4NDM4LDAuMTQ4ODMgLTAuMzQ3MjY2LDAuMjk3NjYgLTAuMTI0MDIzLDAuMTI0MDIgLTEuNjEyMzA1LDEuNjM3MTEgLTAuNTcwNTA4LDAuNjIwMTIgLTEuMzY0MjU4LDAuNzkzNzUgLTAuNTIwODk4LDAuMTQ4ODMgLTEuNDYzNDc2LC0wLjEyNDAyIC0zLjEwMDU4NTksLTAuODE4NTYgLTQuODg2NTIzNCwtMy4yNzQyMiAtMC42OTQ1MzEzLC0wLjkxNzc4IC0wLjk5MjE4NzUsLTIuMjA3NjIgLTAuMjcyODUxNiwtMS4zMTQ2NSAwLjI3Mjg1MTYsLTMuMzIzODMgMC41NDU3MDMxLC0yLjAzMzk4IDMuOTQzOTQ1MiwtNC42Mzg0NyAzLjY5NTg5ODEsLTIuODI3NzQgNC4zNDA4MjAxLC00LjQ4OTY1IDAuNTQ1NzAzLC0wLjk2NzM5IDEuMjQwMjM1LC0yLjEzMzIxIDAuNzE5MzM1LC0xLjE2NTgyIDEuNjg2NzE4LC0yLjI1NzIyIDAuNTk1MzEzLC0wLjQyMTY4IDEuMTE2MjExLC0wLjk2NzM5IDAuNTQ1NzAzLC0wLjU3MDUgMS4wNjY2MDIsLTEuMTY1ODIgdiAtMy4wNTA5NyBxIDEuMzY0MjU3LDAuMjcyODUgMi4wMDkxNzksMC43OTM3NSAwLjI5NzY1NywwLjMyMjQ2IDAuNjQ0OTIyLDAuNTk1MzEgMC4zNzIwNzEsMC4yNzI4NSAwLjY2OTcyNywwLjU5NTMxIDAuNjIwMTE3LC0xLjExNjIxIDAuNzkzNzUsLTEuODYwMzUgMC4wMjQ4LC0wLjE3MzYzIDAuMTczNjMzLC0wLjY5NDUzIDAuMTQ4ODI4LC0wLjUyMDkgMC4yOTc2NTYsLTEuNzExNTIgMC4zNzIwNywtMC4wOTkyIDAuNjQ0OTIyLDAuMTk4NDMgMS4xNDEwMTUsMS4yODk4NSAyLjE1ODAwNywyLjg3NzM1IDQuNTM5MjU4LDEuODEwNzQgOC4yODQ3NjYsNC4yOTEyMSAzLjc3MDMxMiwyLjQ4MDQ3IDUuNzc5NDkyLDUuMTU5MzcgNS42ODAyNzMsNy43MTQyNiA1LjY4MDI3MywyMi43MjExIDAsMy4xNTAxOSAtMC4zMjI0NjEsNS43NTQ2OCBIIDExLjY2NjQ3MiBxIC0wLjMyMjQ2MSwtMy4yMjQ2IDMuNDIzMDQ2LC02Ljg0NjA5IDEuNjg2NzE5LC0xLjYzNzExIDMuNDk3NDYxLC0zLjE3NSAxLjgzNTU0NywtMS41Mzc4OSAzLjU3MTg3NSwtMy4xMjUzOSAzLjIyNDYxLC0yLjk3NjU2IDMuNTcxODc1LC00Ljc2MjUgLTAuMTI0MDIzLC0wLjI5NzY2IC0wLjQ3MTI4OSwtMC4zOTY4NyAtMC44NjgxNjQsMC41MjA4OSAtMS43MzYzMjgsMC42Njk3MiAtMC44NjgxNjQsMC4xNDg4MyAtMS43MTE1MjMsMC4xOTg0NCAtMC41NDU3MDQsMC4wMjQ4IC0xLjA5MTQwNywwLjA0OTYgLTAuNTIwODk4LDAgLTEuMjQwMjM0LC0wLjI0ODA1IC0wLjk2NzM4MywxLjA5MTQxIC0xLjY2MTkxNCwxLjg4NTE2IC0wLjY2OTcyNywwLjc2ODk0IC0xLjUzNzg5MSwxLjM4OTA2IHoiCiAgICAgICAgIHN0eWxlPSJzdHJva2Utd2lkdGg6MC4yNjQ1ODMzMiIKICAgICAgICAgaWQ9InBhdGgxMDMiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8L2c+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gNDMuMjA4MTQ3LDI4OS4xNzQ1OSBjIC0xLjAwNDEwMSwtMC4yNjk5MyAtMS45OTQxNjEsLTEuMjY2OTkgLTIuNDY5NzI5LC0yLjQ4NzE4IC0wLjI4NjI0NywtMC43MzQ0NSAtMC4zMzYwNTUsLTEuMDk3ODYgLTAuMzM2NzMyLC0yLjQ1Njk1IC0wLjAwMTksLTMuODgyNzggLTAuMzY4Njg0LC03Ljk5NTM2IC0wLjk0MTE0NywtMTAuNTUzNzUgLTAuNDgwNTgxLC0yLjE0Nzc3IC0xLjI5ODQ0OCwtNC4xMzE5IC0yLjM5MDY5OCwtNS43OTk4MSAtMS4wMDExMzMsLTEuNTI4NzUgLTIuNDI1NTI4LC0zLjA5MDcgLTQuMDY4MDQ4LC00LjQ2MDkgLTEuNDk4MDgyLC0xLjI0OTcgLTMuNjc5MjcyLC0yLjY1MzU5IC01LjYzNDExNywtMy42MjYzMyBsIC0wLjQ1NTc3MiwtMC4yMjY3OSAtMC4wMjM1LC0wLjgzNzU5IGMgLTAuMDEyOTEsLTAuNDYwNjcgLTAuMDE4MzEsLTAuODkyMjUgLTAuMDExOTYsLTAuOTU5MDYgbCAwLjAxMTU0LC0wLjEyMTQ5IDAuNTE3ODM1LDAuMjM1OSBjIDAuNzIyOTQyLDAuMzI5MzMgMi4zMzY0NjEsMS4xNDc2MyAzLjA3MzU5OCwxLjU1ODc4IDIuMjYwOTA3LDEuMjYxMDUgNC4xOTM1ODgsMi41ODI0MiA1Ljg0NjUyMiwzLjk5NzI2IDAuNTQyNzQ1LDAuNDY0NTYgMS42NTcxNjcsMS41ODgwNyAyLjA4NDYzMSwyLjEwMTYyIDIuMzI0MTc2LDIuNzkyMjUgNC4wNzM1NjcsNi43NTgyOSA1LjAxMDY4NCwxMS4zNTk3MSAwLjQ1MDE3OCwyLjIxMDQ1IDAuNzEwMTcxLDQuMzQ1MjEgMC44NjI1MDcsNy4wODE4OCAwLjA0NzI1LDAuODQ4NzkgMC4wNjE1LDUuMTcxNTIgMC4wMTcyLDUuMjE1ODQgLTAuMDE0NSwwLjAxNDUgLTAuMjA5OTQxLDAuMDMwOSAtMC40MzQzMTMsMC4wMzYzIC0wLjMyNjgzNSwwLjAwOCAtMC40NTc3NjQsLTAuMDAzIC0wLjY1ODUxMSwtMC4wNTc0IHoiCiAgICAgICBpZD0icGF0aDEwNiIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMjguNDA4MDk3LDI3Ni4yNTc1NSBjIC0wLjc2MTg5NCwtMC4xMTQ0MyAtMS4xNzU2MzEsLTAuMzcwMTggLTEuNDc4Mjg4LC0wLjkxMzggLTAuMDY2NSwtMC4xMTk0NCAtMC4xNjI3NTYsLTAuMzM3NDMgLTAuMjEzOTEzLC0wLjQ4NDQzIC0wLjA4NjEzLC0wLjI0NzUgLTAuMDkzMDQsLTAuMzA1NTYgLTAuMDkzNDYsLTAuNzg1MSAtNC4yM2UtNCwtMC40NzU1NyAwLjAwNjUsLTAuNTM1NTYgMC4wODQyOCwtMC43MzQ5OSAwLjEzMTkyOSwtMC4zMzgxMyAwLjIzODM5MiwtMC40NzcxMiAwLjYwNzE2MywtMC43OTI3MSAwLjcxOTM0OSwtMC42MTU1OSAxLjAyMjQzMiwtMS4wNTAzNiAxLjMwOTgwNCwtMS44Nzg4OCAwLjI2Mzk2MSwtMC43NjEwMyAwLjU3ODAxOSwtMi4yNjQ1OSAwLjcwNzExMiwtMy4zODUzMiAwLjAxMjk3LC0wLjExMjUyIDAuMDQ5NjIsLTAuMjI4NCAwLjA4NzUsLTAuMjc2NTUgMC4xNjY5MTIsLTAuMjEyMiAwLjU1MDYyNCwtMC4yODE4NSAwLjc2MzI1OSwtMC4xMzg1NiAwLjA2NjIxLDAuMDQ0NiAwLjE1NDEyLDAuMTU2NjcgMC4yMTI1NTMsMC4yNzA5MyAwLjExOTEyMSwwLjIzMjkyIDAuMTIwNjk4LDAuMzMwMTQgMC4wMTkzOSwxLjE5NTY2IC0wLjE4OTgzNiwxLjYyMjA3IC0wLjQ4NzA3NywyLjgxMTg0IC0wLjg4ODA2OSwzLjU1NDY2IC0wLjE5NzM4NywwLjM2NTY2IC0wLjUwMzUzOSwwLjgyNzI2IC0wLjcyMDc2NywxLjA4Njc0IC0wLjMwMDMxMywwLjM1ODczIC0wLjI5MjQwNywwLjMzOTgyIC0wLjEwODI1NywwLjI1ODk3IDAuNTAzODkxLC0wLjIyMTIyIDEuNTQ4NzEsLTAuNzQ2OTUgMS43NDg2ODcsLTAuODc5ODkgMC43Mzg4NjUsLTAuNDkxMiAxLjM0MDYyLC0xLjQzNTU1IDEuNzA1MDg5LC0yLjY3NTg2IDAuMDg1MjEsLTAuMjg5OTcgMC4yMjIzNjQsLTAuNDY0MTYgMC40NDgzMiwtMC41NjkzOCAwLjIxOTA2NSwtMC4xMDIgMC40MzE1MDcsLTAuMTAzMjEgMC42MjAwMDYsLTAuMDA0IDAuMzAxMTQxLDAuMTU5MjUgMC4zMzY2MjcsMC40MzI3NCAwLjE1MjkyMiwxLjE3ODU4IC0wLjI3NjUyNywxLjEyMjY4IC0wLjY1Njg3MywxLjkzMzAyIC0xLjIyNDc0OSwyLjYwOTM3IC0wLjU4OTQ5NCwwLjcwMjEgLTEuMTgxMzMyLDEuMDIwOTkgLTMuMzQ1ODU0LDEuODAyOCAtMC4xOTc0MjIsMC4wNzEzIC0wLjM1OTAzNywwLjEzODcyIC0wLjM1OTE0MywwLjE0OTgxIC03Ljk0ZS00LDAuMDcyNiAxLjg1MTA1MSwtMC4xNTM5OCAyLjc1Mjg4MSwtMC4zMzY4MSAwLjI3Mzg5NCwtMC4wNTU1IDAuNTQ5MDEsLTAuMTAwOTUgMC42MTEzNjcsLTAuMTAwOTUgMC4yMjc5MDIsMCAwLjQxNjg2NSwwLjE2MDY2IDAuNDc4NTQ0LDAuNDA2ODkgMC4wNTI2NCwwLjIxMDE1IDAuMDAxMSwwLjM1OTMxIC0wLjE3NjY4NiwwLjUxMTUgLTAuMjM5MzcxLDAuMjA0ODkgLTEuMjQ5MDY5LDAuNTA0NTMgLTIuNjQ1NDQ3LDAuNzg1MDcgLTAuODEwMzc2LDAuMTYyODEgLTAuODc4MzExLDAuMTcyMjEgLTEuMDU0MjY0LDAuMTQ1NzggeiIKICAgICAgIGlkPSJwYXRoMTA4IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAxOS42OTY4MzYsMjc0Ljk3NDY0IGMgLTAuMTc0NjIxLC0wLjA4ODcgLTAuMjk5ODgsLTAuMjMyNzMgLTAuMzI2NjYyLC0wLjM3NTQ5IC0wLjAyODExLC0wLjE0OTgzIDAuMjcwMDcxLC0xLjA0OTAyIDAuNTg4MzY0LC0xLjc3NDI2IDAuMjEyMTQxLC0wLjQ4MzM3IDAuMjcxNTMsLTAuNTg3ODEgMC40MTM0NDMsLTAuNzI3MDYgMC4xNzAwMDgsLTAuMTY2ODIgMC4zOTAwNTYsLTAuMjk1NTUgMC41MDQ2NTIsLTAuMjk1MjIgMC4xMjUxMjgsMy43ZS00IDAuMzE0MTgyLDAuMDcwMSAwLjQxMTA5MywwLjE1MTY1IDAuMjI2MDMsMC4xOTAxOSAwLjIwOTMwMSwwLjUyOTc5IC0wLjA2ODA1LDEuMzgxNTEgLTAuMjUzMzc2LDAuNzc4MSAtMC4zMDgxMjcsMC44OTcxMyAtMC41NTQ3MTQsMS4yMDU5OCAtMC4zNjAwMjIsMC40NTA5MiAtMC42NjQ2MzQsMC41ODcxMyAtMC45NjgxMjUsMC40MzI4OSB6IgogICAgICAgaWQ9InBhdGgxMTAiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDE3LjUzMzU2OCwyNjYuMTc2NDMgYyAtMC4yMzA3NzcsLTAuMDU2NyAtMC4zMDM5NDIsLTAuMTAyMzIgLTAuNDE4ODg3LC0wLjI2MSAtMC4xMDMxNjIsLTAuMTQyNDEgLTAuMjM3MTUxLC0wLjUxOTA4IC0wLjI5MjAwNywtMC44MjA4OSAtMC4wMjg4OCwtMC4xNTg5MiAtMC4wMjIwMywtMC4xOTgxMyAwLjA3ODAxLC0wLjQ0NjIzIDAuMTkzMDQ5LC0wLjQ3ODc4IDAuNTI4MjMzLC0wLjg5NDgxIDAuODkzMzE4LC0xLjEwODc2IDAuMzc4NTk1LC0wLjIyMTg3IDAuNzIxNzgxLC0wLjI3NTMgMi4wNzA5NDQsLTAuMzIyNCAwLjg3ODU2NywtMC4wMzA3IDEuMjA4MDg4LC0wLjA2NzIgMS42NTY5LC0wLjE4MzQ1IDAuMTE2NTQ5LC0wLjAzMDIgMC4yMTY3MjQsLTAuMDUwMSAwLjIyMjYxLC0wLjA0NDIgMC4wMjIyNSwwLjAyMjIgLTAuMzgwNzcxLDAuOTYxOSAtMC41NTYzMTQsMS4yOTcwNyAtMC4yODQwNTUsMC41NDIzNSAtMC40ODI5MDUsMC44MjMyMiAtMC44MzI4MjIsMS4xNzYzMyAtMC4yNzYwNCwwLjI3ODU3IC0wLjM2MzA0MSwwLjM0NDI4IC0wLjYwMzMsMC40NTU2OSAtMC40NzMxMywwLjIxOTQgLTAuOTMwNDAzLDAuMzA0NTQgLTEuNjE3MDkxLDAuMzAxMDkgLTAuMjM4ODcyLC0xMGUtNCAtMC41MDk0ODMsLTAuMDIwNyAtMC42MDEzNTcsLTAuMDQzMiB6IgogICAgICAgaWQ9InBhdGgxMTIiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDguMDg4MzIzNiwyNzYuNTkyODEgYyAtMC4xNTU3MTI4LC0wLjA2NiAtMC4zMTU1MjU5LC0wLjI5OTE3IC0wLjM0NjQ2OTIsLTAuNTA1NTEgLTAuMDEyNjEzLC0wLjA4NDEgLTAuMDA0MzcsLTAuMjU3NDUgMC4wMTg1MTYsLTAuMzg5MTUgMC4wMzk2MzgsLTAuMjI4MTQgMC4wNDg2NzYsLTAuMjQ0MDQgMC4yMjk5Nzg0LC0wLjQwNDUxIDAuMzczMjMwMywtMC4zMzAzNyAwLjgzMzY5NDcsLTAuODE1NDUgMS4yNTQ3ODQ2LC0xLjMyMTg3IDAuMjM1ODA0NiwtMC4yODM1OSAwLjQ1MjM0OTQsLTAuNTM0NDEgMC40ODEyMTEsLTAuNTU3MzcgMC4wNzIwODIsLTAuMDU3NCAwLjM5MjQ5OTYsLTAuMDUyNSAwLjYwMDExODYsMC4wMDkgMC4wOTcwNywwLjAyODggMC4yMjMwOCwwLjA5OTUgMC4yOTAwMzgsMC4xNjI2MyAwLjEwOTY0MiwwLjEwMzQxIDAuMTE4Mzk5LDAuMTI2MjcgMC4xMTgzOTksMC4zMDkxMiAwLDAuMzM1IC0wLjI2NTM4NCwwLjgwMzMgLTAuODMxOTM2NywxLjQ2ODA0IC0wLjE1Nzk4OTQsMC4xODUzOCAtMC4zNDU0MDg4LDAuNDA4MzYgLTAuNDE2NDg3NSwwLjQ5NTUyIC0wLjE3NTgwOCwwLjIxNTU5IC0wLjU5NTg4MTksMC41NDQ1MiAtMC44Mzk2MTc5LDAuNjU3NDUgLTAuMjY0Mjc1MSwwLjEyMjQ1IC0wLjQwNDY0LDAuMTQxNjYgLTAuNTU4NTMzMywwLjA3NjQgeiIKICAgICAgIGlkPSJwYXRoMTE0IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAxMC44MDE3MzQsMjgxLjE1NDUxIGMgLTAuMTI3NjgxLC0wLjA1MzYgLTAuMjMxODAyLC0wLjE2NDYgLTAuMzI2OTExLC0wLjM0ODQ0IC0wLjA3MDk3LC0wLjEzNzE3IC0wLjA4NjgsLTAuMjE0ODQgLTAuMDg4NTcsLTAuNDM0MzIgLTAuMDAxMiwtMC4xNDY5OSAwLjAxOTA1LC0wLjM2Mjg2IDAuMDQ0OTUsLTAuNDc5NzEgMC4wNDYxNywtMC4yMDgyNiAwLjA1MzIyLC0wLjIxNzgxIDAuMzU3MzYxLC0wLjQ4NDQyIDAuMzA5OTExLC0wLjI3MTY4IDAuNzY0NDg5LC0wLjgwMjggMS40NjIzMjEsLTEuNzA4NTYgMC4zOTcyNDEsLTAuNTE1NiAwLjQ2MjQ1OSwtMC41NjI5NyAwLjczMzU2OCwtMC41MzI3OCAwLjQwMDM2NiwwLjA0NDYgMC42ODIyNzcsMC4yMzc3NCAwLjc1ODEyLDAuNTE5NCAwLjA5Nzc0LDAuMzYyOTcgLTAuMTY5Mjg0LDAuOTI3MDEgLTAuODUyNDkyLDEuODAwNzQgLTAuMTUwODYzLDAuMTkyOTQgLTAuMzUwMjY2LDAuNDYzNTUgLTAuNDQzMTE4LDAuNjAxMzYgLTAuNDQ5MzYzLDAuNjY2OTQgLTEuMjkzNjY2LDEuMjE0MzcgLTEuNjQ1MjMzLDEuMDY2NzMgeiIKICAgICAgIGlkPSJwYXRoMTE2IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICA8L2c+Cjwvc3ZnPgo='); } -body.base .is2d piece.bishop.black { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMTQ0cHQiCiAgIGhlaWdodD0iMTQ0cHQiCiAgIHZpZXdCb3g9IjAgMCA1MC44MDAwMDEgNTAuOCIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnOCIKICAgc29kaXBvZGk6ZG9jbmFtZT0iYmIuc3ZnIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkyLjMgKDI0MDU1NDYsIDIwMTgtMDMtMTEpIj4KICA8ZGVmcwogICAgIGlkPSJkZWZzMiIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9ImJhc2UiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEuMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6em9vbT0iNy45MTk1OTU5IgogICAgIGlua3NjYXBlOmN4PSI4My41MzQ4NiIKICAgICBpbmtzY2FwZTpjeT0iMTEzLjU4Njg3IgogICAgIGlua3NjYXBlOmRvY3VtZW50LXVuaXRzPSJtbSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJsYXllcjEiCiAgICAgc2hvd2dyaWQ9ImZhbHNlIgogICAgIHVuaXRzPSJwdCIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjM4NDAiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iMjAzNSIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iLTEzIgogICAgIGlua3NjYXBlOndpbmRvdy15PSItMTMiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIgLz4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGE1Ij4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICAgIDxkYzp0aXRsZSAvPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZwogICAgIGlua3NjYXBlOmxhYmVsPSJMYXllciAxIgogICAgIGlua3NjYXBlOmdyb3VwbW9kZT0ibGF5ZXIiCiAgICAgaWQ9ImxheWVyMSIKICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLC0yNDYuMikiPgogICAgPGcKICAgICAgIGFyaWEtbGFiZWw9InYiCiAgICAgICBzdHlsZT0iZm9udC1zdHlsZTpub3JtYWw7Zm9udC12YXJpYW50Om5vcm1hbDtmb250LXdlaWdodDpub3JtYWw7Zm9udC1zdHJldGNoOm5vcm1hbDtmb250LXNpemU6NTAuNzk5OTk5MjRweDtsaW5lLWhlaWdodDoxLjI1O2ZvbnQtZmFtaWx5OidDaGVzcyBMZWlwemlnJzstaW5rc2NhcGUtZm9udC1zcGVjaWZpY2F0aW9uOidDaGVzcyBMZWlwemlnJztsZXR0ZXItc3BhY2luZzowcHg7d29yZC1zcGFjaW5nOjBweDtmaWxsOiMwMDAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjAuMjY0NTgzMzIiCiAgICAgICBpZD0idGV4dDE0OSIKICAgICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuMDI5ODc1MTksMC4xMjU0NikiPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDI4LjY0MDI4NywyODkuOTkyNjcgcSAtMC4zOTY4NzUsLTAuMjQ4MDUgLTEuMTE2MjExLC0xLjA0MTggLTAuMTI0MDIzLC0wLjEyNDAyIC0wLjI0ODA0NywtMC4yMjMyNCAtMC4xMjQwMjMsLTAuMTI0MDIgLTAuMjQ4MDQ3LC0wLjI3Mjg1IC0wLjE5ODQzNywtMC4xMjQwMiAtMC4zOTY4NzQsLTAuMTI0MDIgLTEuMjg5ODQ0LDAgLTAuOTY3MzgzLDAuOTY3MzggMC4xNDg4MjgsMC4yMjMyNCAwLjEyNDAyMywwLjE5ODQ0IDAuMTczNjMzLDAuMTczNjMgMS4xOTA2MjUsMS4xMTYyMSAwLjQ3MTI4OSwwLjQ0NjQ4IDAuODkyOTY5LDAuNjQ0OTIgMC4yMjMyNDIsMC4xNDg4MyAwLjQ0NjQ4NCwwLjE0ODgzIDAuNzQ0MTQxLDAgMC43NDQxNDEsLTAuNzQ0MTQgMCwtMC4yOTc2NiAtMC40MjE2OCwtMC42Njk3MyB6IG0gMS44ODUxNTYsLTEyLjYyNTU5IC0wLjQ0NjQ4NCwtMS43MTE1MiBxIC0xLjk1OTU3LC0wLjU0NTcgLTQuNjg4MDg2LC0wLjU0NTcgLTIuNTA1MjczLDAgLTQuNDg5NjQ4LDAuNDk2MDkgbCAtMC40OTYwOTQsMS43MTE1MiBxIDIuMTU4MDA4LC0wLjU3MDUgNC45ODU3NDIsLTAuNTcwNSAzLjAyNjE3MiwwIDUuMTM0NTcsMC42MjAxMSB6IG0gLTIuNzAzNzExLDIuNzAzNzEgLTIuNDA2MDU0LDAuOTkyMTkgLTIuMzgxMjUsLTAuOTkyMTkgMi4zODEyNSwtMC45OTIxOCB6IG0gMi44MDI5MywtMS4yODk4NCBxIC0yLjEwODM5OCwtMC41NzA1MSAtNS4xNTkzNzUsLTAuNTcwNTEgLTIuODUyNTM5LDAgLTUuMDM1MzUxLDAuNTIwOSBsIC0wLjM0NzI2NiwwLjk2NzM4IDIuMTA4Mzk5LDAuNDcxMjkgLTIuMTgyODEzLDEuMzg5MDcgLTAuNDcxMjg5LC0wLjA5OTIgLTAuNTk1MzEzLDEuNzg1OTMgcSAwLjUyMDg5OSwtMC41NDU3IDIuMzU2NDQ2LC0wLjkxNzc3IDEuODM1NTQ3LC0wLjM3MjA3IDQuMjQxNjAxLC0wLjM3MjA3IDIuMzU2NDQ2LDAgNC4xNjcxODgsMC4zNzIwNyAxLjgzNTU0NywwLjM3MjA3IDIuMzgxMjUsMC44OTI5NyBsIC0wLjYyMDExOCwtMS43ODU5NCAtMC42MjAxMTcsMC4xMjQwMyAtMi4xODI4MTIsLTEuMzg5MDcgMi4yMzI0MjIsLTAuNDcxMjkgeiBNIDI5LjgwNjEwNywyNjUuODA4MSB2IC0yLjc3ODEzIGggLTIuOTc2NTYyIHYgLTMuODY5NTMgaCAtMi43NTMzMiB2IDMuODY5NTMgaCAtMy4wMjYxNzIgdiAyLjc3ODEzIGggMy4wMjYxNzIgdiA1LjUzMTQ1IGggMi43NTMzMiB2IC01LjUzMTQ1IHogbSAtNy43MTQyNTcsMjQuMTg0NTcgcSAtMC4yNzI4NTIsMC4yNzI4NSAtMC4yNzI4NTIsMC42MjAxMiAwLDAuNzQ0MTQgMC43NDQxNDEsMC43NDQxNCAwLjIyMzI0MiwwIDAuMzk2ODc1LC0wLjEyNDAzIDAuNDIxNjc5LC0wLjIyMzI0IDAuODE4NTU0LC0wLjYyMDExIDAuODkyOTY5LC0wLjg0MzM2IDEuMjQwMjM1LC0xLjE0MTAyIDAuMDQ5NjEsLTAuMDQ5NiAwLjA0OTYxLC0wLjE3MzYzIDAsLTAuOTY3MzggLTAuOTY3MzgzLC0wLjk2NzM4IC0wLjE3MzYzMiwwIC0wLjMyMjQ2MSwwLjE0ODgyIC0wLjIyMzI0MiwwLjIyMzI1IC0wLjU0NTcwMywwLjQ3MTI5IC0wLjI5NzY1NiwwLjIyMzI1IC0wLjU0NTcwMywwLjUyMDkgLTAuMjIzMjQyLDAuMjcyODUgLTAuNTk1MzEzLDAuNTIwOSB6IE0gMzQuNzE3NDM2LDI2Ny4zNzA4IHEgMC4zNDcyNjUsLTEuMzM5NDYgLTAuNzY4OTQ2LC00Ljk4NTc1IC0xLjExNjIxMSwtMy42NDYyOSAtMy40NzI2NTYsLTYuMTAxOTUgLTAuMjk3NjU2LC0wLjIyMzI0IC0wLjYyMDExNywtMC4xOTg0NCAtMC40MjE2OCwwLjAyNDggLTAuNzkzNzUsMC4zNDcyNyAtMC4zNzIwNywwLjMyMjQ2IC0wLjA5OTIyLDAuNzY4OTQgMi45MDIxNDgsMS45MDk5NiA0LjM0MDgyLDUuMzA4MjEgMS40Mzg2NzIsMy4zNzM0MyAxLjQxMzg2OSw0Ljg2MTcyIHogbSAtOS4zMjY1NjMsMjMuNTM5NjQgcSAtMS44MzU1NDcsMi42NTQxIC00Ljk2MDkzNywyLjY1NDEgLTAuMzIyNDYxLDAgLTAuNjQ0OTIyLC0wLjAyNDggLTAuMjk3NjU2LC0wLjA0OTYgLTAuNTk1MzEzLC0wLjA3NDQgLTAuNzE5MzM2LC0wLjAyNDggLTIuMTA4Mzk4LC0wLjI0ODA1IC0xLjM4OTA2MywtMC4yNDgwNSAtMy4xMDA1ODYsLTEuMTE2MjEgLTEuNTEzMDg2LC0xLjMxNDY1IC0zLjg0NDcyNiwtMS4zMTQ2NSAtMS43ODU5Mzc5LDAgLTMuMTAwNTg2MywwLjg0MzM2IC0wLjM3MjA3MDMsMC4xNzM2MyAtMC45MTc3NzM1LDAuNzE5MzQgLTAuOTkyMTg3NCwxLjA2NjYgLTEuNjEyMzA0NiwxLjE2NTgyIC0wLjQ5NjA5MzgsLTAuMjQ4MDUgLTAuNTIwODk4NCwtMC44NDMzNiAtMC4xMjQwMjM1LC0xLjE2NTgyIDEuNzExNTIzNCwtMy4wMDEzNyAtMC4zMjI0NjEsMC4wNDk2IC0xLjIxNTQyOTcsMC4yOTc2NiAtMC43NDQxNDA2LDAuMjIzMjQgLTAuOTkyMTg3NSwwLjIyMzI0IC0wLjgxODU1NDcsMC4xMjQwMiAtMC44NjgxNjQsMC4wMjQ4IC0wLjI3Mjg1MTYsLTAuMjcyODUgMC4xOTg0Mzc1LC0xLjExNjIxIDAuMzk2ODc1LC0wLjcxOTMzIDEuNTM3ODkwNiwtMS4yNjUwNCAwLjE0ODgyODEsLTAuMDc0NCAwLjk0MjU3ODEsLTAuNDIxNjggMi4zMDY4MzU5LC0xLjIxNTQzIDQuODM2OTE0NCwtMS4yMTU0MyAzLjY5NTg5OCwwIDYuNjcyNDYsMi41MDUyOCAxLjE5MDYyNSwwLjM5Njg3IDIuNDA2MDU1LDAuMzk2ODcgMy43MjA3MDMsMCAzLjg0NDcyNywtMy4wNzU3OCAtMi40MDYwNTUsLTAuMjIzMjQgLTQuMDE4MzYsLTAuODE4NTUgLTEuNTg3NSwtMC41OTUzMiAtMS41ODc1LC0xLjM4OTA3IGwgMS45ODQzNzUsLTYuNTk4MDQgcSAtMS43MzYzMjgsLTIuNzI4NTIgLTIuODc3MzQzLC01LjU1NjI1IC0xLjE0MTAxNiwtMi44Mjc3NCAtMS4xNDEwMTYsLTUuMzU3ODIgMCwtNy41OTAyMyA4LjIzNTE1NiwtMTEuNjU4MiAwLC0wLjMyMjQ2IDAuMDc0NDEsLTAuOTY3MzggLTAuODQzMzU5LC0wLjY5NDUzIC0wLjg0MzM1OSwtMS43NjExMyAwLC0yLjI4MjA0IDIuMzA2ODM2LC0yLjI4MjA0IDIuMjgyMDMxLDAgMi4yODIwMzEsMi4yODIwNCAwLDAuOTkyMTggLTAuNzE5MzM2LDEuNjYxOTEgMCwwLjc2ODk0IDAuMTk4NDM3LDEuMDQxOCAwLjQyMTY4LDAuNTk1MzEgMS4xMTYyMTEsMC42MjAxMSAwLjcxOTMzNiwtMC4wMjQ4IDEuMTkwNjI1LC0wLjY0NDkyIDAuMDk5MjIsLTAuMTQ4ODMgMC4xOTg0MzgsLTAuOTE3NzcgLTAuNjQ0OTIyLC0wLjY2OTczIC0wLjY0NDkyMiwtMS42NjE5MiAwLC0yLjMzMTY0IDIuMzMxNjQxLC0yLjMzMTY0IDIuMzMxNjQsMCAyLjMzMTY0LDIuMzMxNjQgMCwxLjMxNDY1IC0xLjE0MTAxNSwyLjAzMzk5IC0wLjA5OTIyLDAuNDk2MDkgLTAuMDQ5NjEsMC43OTM3NSA0LjE5MTk5Miw0Ljk2MDk0IDMuNjQ2Mjg5LDExLjQ1OTc2IC0wLjE3MzYzMywxLjg2MDM2IC0wLjU3MDUwOCwzLjY3MTEgLTAuMzk2ODc1LDEuNzg1OTMgLTEuMzg5MDYyLDMuMzczNDMgLTAuMzcyMDcsMC44NDMzNiAtMS4xNjU4MiwxLjkwOTk3IC0wLjc2ODk0NiwxLjA0MTc5IC0xLjMzOTQ1NCwxLjk1OTU3IGwgMS45NTk1NzEsNi41OTgwNCBxIC0wLjAyNDgxLDAuNzkzNzUgLTEuNjM3MTEsMS4zODkwNyAtMS42MTIzMDQsMC41OTUzMSAtNC4wNjc5NjgsMC44MTg1NSAwLjEyNDAyMywzLjA3NTc4IDMuODY5NTMxLDMuMDc1NzggMS4yMTU0MywwIDIuNDA2MDU1LC0wLjM5Njg3IDIuOTUxNzU3LC0yLjUwNTI4IDYuNjcyNDYsLTIuNTA1MjggMi41MzAwNzksMCA0LjgxMjExLDEuMjE1NDMgMC4yOTc2NTYsMC4xNDg4MyAwLjUyMDg5OCwwLjI0ODA1IDAuMjIzMjQyLDAuMDk5MiAwLjQ0NjQ4NSwwLjE3MzYzIDEuMTE2MjEsMC41NzA1MSAxLjUzNzg5LDEuMjY1MDQgMC4wNzQ0MSwwLjIyMzI0IDAuMjIzMjQyLDAuNTcwNTEgMC4xNDg4MjgsMC4zNDcyNiAtMC4wMjQ4LDAuNTQ1NyAtMC4wNzQ0MSwwLjA5OTIgLTAuODY4MTY0LC0wLjAyNDggLTAuMjQ4MDQ3LDAgLTAuOTkyMTg4LC0wLjIyMzI0IC0wLjkxNzc3MywtMC4yNDgwNSAtMS4yNDAyMzQsLTAuMjk3NjYgMS44MzU1NDcsMS44NjAzNSAxLjczNjMyOCwzLjAwMTM3IC0wLjA0OTYxLDAuNTcwNSAtMC41NDU3MDMsMC44NDMzNiAtMC42MjAxMTcsLTAuMDk5MiAtMS42MTIzMDUsLTEuMTY1ODIgLTAuNDk2MDk0LC0wLjQ5NjEgLTAuODkyOTY5LC0wLjcxOTM0IC0xLjM4OTA2MiwtMC44NDMzNiAtMy4xMDA1ODYsLTAuODQzMzYgLTIuMzgxMjUsMCAtMy44Njk1MzEsMS4zMTQ2NSAtMS43MTE1MjMsMC44NjgxNiAtMy4xMDA1ODYsMS4xMTYyMSAtMS4zODkwNjIsMC4yMjMyNCAtMi4wODM1OTMsMC4yNDgwNSAtMC4yOTc2NTcsMC4wMjQ4IC0wLjYyMDExOCwwLjA3NDQgLTAuMzIyNDYsMC4wMjQ4IC0wLjYyMDExNywwLjAyNDggLTMuMTk5ODA0LDAgLTQuOTg1NzQyLC0yLjY1NDEgeiIKICAgICAgICAgc3R5bGU9InN0cm9rZS13aWR0aDowLjI2NDU4MzMyIgogICAgICAgICBpZD0icGF0aDE1MSIKICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDwvZz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAyNC4xMjI5NjUsMjY4LjY3OTIyIHYgLTIuNzU2MjEgaCAtMS41MjAwOTYgLTEuNTIwMDk2IHYgLTEuMzY5NzYgLTEuMzY5NzYgaCAxLjUyMDA5NiAxLjUyMDA5NiB2IC0xLjkzNzcgLTEuOTM3NzEgaCAxLjM1Mjc4IDEuMzUyNzgxIGwgMC4wMDg2LDEuOTI5MzYgMC4wMDg2LDEuOTI5MzUgMS40OTUwMzksMC4wMDkgMS40OTUwMzksMC4wMDkgdiAxLjM2OTQxIDEuMzY5NDIgaCAtMS41MDMzOTIgLTEuNTAzMzkxIHYgMi43NTYyMSAyLjc1NjIyIGggLTEuMzUzMDUyIC0xLjM1MzA1MiB6IgogICAgICAgaWQ9InBhdGgxNTQiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDM0Ljc1MTM5MSwyNjcuMjA0MjEgYyAtMC4wMTYzOCwtMC42MzEzNSAtMC4zNTEwNjUsLTEuODg3MDkgLTAuODU3OTIyLC0zLjIxODkxIC0wLjk3NDM2MiwtMi41NjAyNCAtMS43NDE1NzIsLTMuODM5MTMgLTMuMTM2NTY0LC01LjIyODQ2IC0wLjUzNzA1MywtMC41MzQ4NyAtMS4wNzQzODgsLTAuOTg2OCAtMS41NDUwNTUsLTEuMjk5NDYgLTAuMzkzMjc5LC0wLjI2MTI3IC0wLjQyMjg2LC0wLjU4OTYgLTAuMDgwOTQsLTAuODk4NSAwLjIyOTgzLC0wLjIwNzY0IDAuNDUxMjM5LC0wLjMwMDQ2IDAuNzU1MDU3LC0wLjMxNjU0IDAuMjQ1MTMxLC0wLjAxMyAwLjI4MTQ5OCwtMC4wMDYgMC40MzkwMzksMC4wODA5IDAuMzM0NDY1LDAuMTg1MDEgMS4yMzcwNjgsMS4yODI2IDEuODQ2OTQ1LDIuMjQ1OTMgMC42NjYyNDIsMS4wNTIzNiAxLjI0MDEyMSwyLjI3NjQ3IDEuNjU0MjM0LDMuNTI4NTYgMC43MjA1MTMsMi4xNzg1IDEuMDk4MDMxLDQuMTk3NjcgMC45NTU2OTMsNS4xMTE1MyBsIC0wLjAyNjAxLDAuMTY3MDQgeiIKICAgICAgIGlkPSJwYXRoMTU2IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAxOS4wNDQ4NDMsMjgzLjIzNjY2IGMgMCwtMC4wMTM2IDAuMTIwNjU3LC0wLjM4NjYxIDAuMjY4MTI2LC0wLjgyOTA0IGwgMC4yNjgxMjYsLTAuODA0NCAwLjIzMDcxNSwwLjA0OTUgMC4yMzA3MTUsMC4wNDk1IDEuMDkwNjUyLC0wLjY5NDE4IGMgMC41OTk4NTksLTAuMzgxNzkgMS4wNzgyMTYsLTAuNzA1NDYgMS4wNjMwMTYsLTAuNzE5MjcgLTAuMDE1MiwtMC4wMTM4IC0wLjQ3NzE3NywtMC4xMjQ0OCAtMS4wMjY2MTUsLTAuMjQ1OTYgLTAuNTQ5NDM3LC0wLjEyMTQ4IC0xLjAwNTkwMywtMC4yMjc4IC0xLjAxNDM2OCwtMC4yMzYyNiAtMC4wMDg1LC0wLjAwOCAwLjA1OTg5LC0wLjIyMjg3IDAuMTUxOTA1LC0wLjQ3NjQ1IGwgMC4xNjcyOTQsLTAuNDYxMDUgMC4yNDU3MTcsLTAuMDU2OCBjIDAuMzcxNjQ0LC0wLjA4NTkgMS4zOTE4NDksLTAuMjUxNCAxLjg5OTQ0NywtMC4zMDgwNiAwLjk3MjkzNiwtMC4xMDg2MSAxLjUxNjQ1NSwtMC4xMzM3NyAyLjg4OTg1MiwtMC4xMzM3NyAxLjY2MjM4MiwwIDIuNTcyMTU0LDAuMDYxMiAzLjcyNTA2OCwwLjI1MDQzIDAuNDYwMjA4LDAuMDc1NiAxLjI5MjQ3NCwwLjI1Njg1IDEuMzY3MTcxLDAuMjk3ODIgMC4wNDAyOCwwLjAyMjEgMC4zMTkyODMsMC44NjQgMC4yOTQ1MjksMC44ODg3NSAtMC4wMDQ3LDAuMDA1IC0wLjQ4OTQ5MywwLjEwOTU2IC0xLjA3NzMzMSwwLjIzMzA0IC0wLjU4NzgzNSwwLjEyMzQ4IC0xLjA4MTIzLDAuMjM1NTEgLTEuMDk2NDMsMC4yNDg5NiAtMC4wMTUyMSwwLjAxMzUgMC40NjIzNDYsMC4zMzYzMyAxLjA2MTIxNywwLjcxNzUgbCAxLjA4ODg1MywwLjY5MzAyIDAuMzAxMzc5LC0wLjA1ODUgYyAwLjE2NTc1OSwtMC4wMzIyIDAuMzA2NTk0LC0wLjA1MjggMC4zMTI5NjgsLTAuMDQ1OCAwLjAyOTc4LDAuMDMyNyAwLjU2MDUwNiwxLjYwNDI0IDAuNTQ2NTA0LDEuNjE4MjUgLTAuMDA4OCwwLjAwOSAtMC4xMDM1MDUsLTAuMDM2OCAtMC4yMTA1MjMsLTAuMTAxMjMgLTAuNTE4OTQzLC0wLjMxMjQ5IC0xLjYxNTMyNCwtMC42MjEwNiAtMi45MDU3MTgsLTAuODE3NzggLTEuODEyMTEzLC0wLjI3NjI3IC00LjI1ODEsLTAuMzAyMzQgLTYuMjMwNzIxLC0wLjA2NjQgLTEuNTcxNzg4LDAuMTg3OTggLTIuODQ5MzQ1LDAuNTI2MDQgLTMuNDU3MDM5LDAuOTE0NzggLTAuMTAxNDc5LDAuMDY0OSAtMC4xODQ1MDksMC4xMDY5NCAtMC4xODQ1MDksMC4wOTM0IHogbSA3LjYyNTc2MywtMi41MzYwNiBjIDAuNjU3MDIyLC0wLjI3MDM3IDEuMTgzMjA5LC0wLjUwMjMzIDEuMTY5MzAzLC0wLjUxNTQ3IC0wLjAxMzkyLC0wLjAxMzEgLTAuNTU3ODg1LC0wLjI0MzQ5IC0xLjIwODg0MiwtMC41MTE5IGwgLTEuMTgzNTU4LC0wLjQ4ODAxIC0xLjE3MTc1NSwwLjQ4Nzg0IGMgLTAuNjQ0NDY1LDAuMjY4MzIgLTEuMTgyOTkyLDAuNDk4NTMgLTEuMTk2NzI4LDAuNTExNTkgLTAuMDI0NDksMC4wMjMzIDIuMjQ4NTMyLDAuOTk1MDIgMi4zNDY4NzcsMS4wMDMzMSAwLjAyNzU2LDAuMDAyIDAuNTg3Njc4LC0wLjIxNjk5IDEuMjQ0NzAzLC0wLjQ4NzM2IHoiCiAgICAgICBpZD0icGF0aDE1OCIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMzAuMzAzNTcxLDI3Ny40MDk1OSBjIC0yLjU5OTU4NCwtMC43MjYxMiAtNy4wOTgzMDYsLTAuNzI5NjMgLTkuNzc1ODIsLTAuMDA4IC0wLjA2NTU1LDAuMDE3NyAtMC4wNTM0NCwtMC4wMzk5IDAuMTY5NDU0LC0wLjgwNTg4IDAuMTM2MzM3LC0wLjQ2ODUxIDAuMjYwNjYxLC0wLjgzNjEgMC4yODc3NTMsLTAuODUwODIgMC4wMjYyNCwtMC4wMTQyIDAuMjI5NzE2LC0wLjA2NDcgMC40NTIxNzcsLTAuMTEyMTQgMi40NjYzODYsLTAuNTI1ODUgNS44Nzg1NzEsLTAuNTA0MzcgOC4yMTkwNjQsMC4wNTE4IGwgMC40Mzg0MDksMC4xMDQxNyAwLjIxODY3MSwwLjgzODI5IGMgMC4xMjAyNjksMC40NjEwNiAwLjIxNjE0NiwwLjgzOTMzIDAuMjEzMDYxLDAuODQwNiAtMC4wMDMxLDAuMDAxIC0wLjEwMzMzMSwtMC4wMjUgLTAuMjIyNzY5LC0wLjA1ODMgeiIKICAgICAgIGlkPSJwYXRoMTYwIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAyNy45NDY0OTMsMjkxLjM4NTQ1IGMgLTAuMzY1NDgyLC0wLjE3NzA0IC0wLjY5MzQ4OCwtMC40MzU4NyAtMS40MzM0NzUsLTEuMTMxMTQgLTAuNzc0MzQxLC0wLjcyNzU1IC0wLjgyOTk2NiwtMC44MDA1NCAtMC44NDc1NzMsLTEuMTEyMTYgLTAuMDE1NTYsLTAuMjc1MzcgMC4wNTAzMSwtMC40MTI1NCAwLjI1MTU4NiwtMC41MjM4OSAwLjI0MDcxLC0wLjEzMzE3IDAuNzEwOTI1LC0wLjE4NTkyIDAuOTQ4ODE0LC0wLjEwNjQ1IDAuMDc2MzYsMC4wMjU1IDAuMzQ4ODk4LDAuMjY5OTggMC44MzE4NSwwLjc0NjE0IDAuMzk1MDU3LDAuMzg5NTIgMC43ODgzNTMsMC43NTU2IDAuODczOTg4LDAuODEzNTMgMC4xNzc5MTYsMC4xMjAzNiAwLjM2NzEzMywwLjMyOTY4IDAuNDQzNTE1LDAuNDkwNjUgMC4xMTczMzgsMC4yNDcyNyAwLjAyODczLDAuNjcwMDYgLTAuMTY5MzYyLDAuODA4MTQgLTAuMjY3ODc3LDAuMTg2NzIgLTAuNTM1ODc3LDAuMTkxMjUgLTAuODk5MzQzLDAuMDE1MiB6IgogICAgICAgaWQ9InBhdGgxNjIiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDIyLjM5MDgzOSwyOTEuNDQ0MjYgYyAtMC4zMzk4NDYsLTAuMDY1NiAtMC41MTkxODEsLTAuMzAwNjEgLTAuNTE4MzI3LC0wLjY3OTE4IDYuMzVlLTQsLTAuMjgyMjQgMC4wOTI1MywtMC40NzI4MyAwLjMxNjc0MSwtMC42NTY5MyAwLjA5ODg2LC0wLjA4MTIgMC4zNDUxMjgsLTAuMzE0MDYgMC41NDcyNTEsLTAuNTE3NTMgMC4yMDIxMjIsLTAuMjAzNDYgMC40NDI2NjUsLTAuNDI4NzIgMC41MzQ1MzksLTAuNTAwNTYgMC4wOTE4NywtMC4wNzE4IDAuMjcyMjgxLC0wLjIyMjc0IDAuNDAwOTA0LC0wLjMzNTMgMC4yODgzNDEsLTAuMjUyMzUgMC4zNDE4OTUsLTAuMjgwODkgMC41MjcwMzMsLTAuMjgwODkgMC41MDE0MTEsMCAwLjgyMDIwOCwwLjI5OTk4IDAuODc4MzY1LDAuODI2NTIgbCAwLjAyMzAyLDAuMjA4NDYgLTAuMTI5ODc4LDAuMTI1NjMgYyAtMC4zNjE3OCwwLjM0OTk0IC0xLjQyMTA1MSwxLjMxNjMgLTEuNTc3MzUsMS40MzkwMSAtMC4yNDk2MTcsMC4xOTU5NSAtMC41NjU0ODIsMC4zNjI4OSAtMC43MjM0NTUsMC4zODIzNCAtMC4wNzM1LDAuMDA5IC0wLjE5ODk4LDAuMDA0IC0wLjI3ODg0NywtMC4wMTE2IHoiCiAgICAgICBpZD0icGF0aDE2NCIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgPC9nPgo8L3N2Zz4K'); } -body.base .is2d piece.rook.black { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMTQ0cHQiCiAgIGhlaWdodD0iMTQ0cHQiCiAgIHZpZXdCb3g9IjAgMCA1MC44MDAwMDEgNTAuOCIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnOCIKICAgc29kaXBvZGk6ZG9jbmFtZT0iYnIuc3ZnIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkyLjMgKDI0MDU1NDYsIDIwMTgtMDMtMTEpIj4KICA8ZGVmcwogICAgIGlkPSJkZWZzMiIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9ImJhc2UiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEuMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6em9vbT0iNy45MTk1OTU5IgogICAgIGlua3NjYXBlOmN4PSIzNC41NDI0NjUiCiAgICAgaW5rc2NhcGU6Y3k9IjkyLjM3Mzc1NCIKICAgICBpbmtzY2FwZTpkb2N1bWVudC11bml0cz0ibW0iCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ibGF5ZXIxIgogICAgIHNob3dncmlkPSJmYWxzZSIKICAgICB1bml0cz0icHQiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIzODQwIgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjIwMzUiCiAgICAgaW5rc2NhcGU6d2luZG93LXg9Ii0xMyIKICAgICBpbmtzY2FwZTp3aW5kb3cteT0iLTEzIgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiIC8+CiAgPG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhNSI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGUgLz4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGcKICAgICBpbmtzY2FwZTpsYWJlbD0iTGF5ZXIgMSIKICAgICBpbmtzY2FwZTpncm91cG1vZGU9ImxheWVyIgogICAgIGlkPSJsYXllcjEiCiAgICAgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCwtMjQ2LjIpIj4KICAgIDxnCiAgICAgICBhcmlhLWxhYmVsPSJ0IgogICAgICAgc3R5bGU9ImZvbnQtc3R5bGU6bm9ybWFsO2ZvbnQtdmFyaWFudDpub3JtYWw7Zm9udC13ZWlnaHQ6bm9ybWFsO2ZvbnQtc3RyZXRjaDpub3JtYWw7Zm9udC1zaXplOjUwLjc5OTk5OTI0cHg7bGluZS1oZWlnaHQ6MS4yNTtmb250LWZhbWlseTonQ2hlc3MgTGVpcHppZyc7LWlua3NjYXBlLWZvbnQtc3BlY2lmaWNhdGlvbjonQ2hlc3MgTGVpcHppZyc7bGV0dGVyLXNwYWNpbmc6MHB4O3dvcmQtc3BhY2luZzowcHg7ZmlsbDojMDAwMDAwO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lO3N0cm9rZS13aWR0aDowLjI2NDU4MzMyIgogICAgICAgaWQ9InRleHQ3NyIKICAgICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQuNDllLTQsMC4wNjA4MykiPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDI1LjQxMjQwMiwyNDkuNTg1ODUgaCAzLjQyMzA0NyB2IDMuMzczNDMgaCA1LjEzNDU3IHYgLTMuMzczNDMgaCA1LjkwMzUxNiB2IDguODU1MjcgbCAtMy45OTM1NTUsNC42MTM2NyBxIDEuMjg5ODQ0LDEuNjM3MTEgMC4wNDk2MSwzLjQ0Nzg1IC0wLjE5ODQzOCwwLjMyMjQ2IC0wLjE5ODQzOCwwLjU5NTMyIDAsMC4zMjI0NiAwLjE5ODQzOCwwLjYyMDExIDAuNTIwODk4LDAuNzY4OTUgMC40OTYwOTMsMi4xODI4MiAwLDEuMzg5MDYgLTAuNTIwODk4LDIuMTgyODEgLTAuMTczNjMzLDAuMjQ4MDQgLTAuMTczNjMzLDAuNTIwOSAwLDAuMzQ3MjYgMC4yMjMyNDIsMC42NDQ5MiAxLjE2NTgyMSwxLjc2MTEzIC0wLjA0OTYxLDMuNDcyNjUgLTAuMTczNjMzLDAuMjk3NjYgLTAuMTczNjMzLDAuNTcwNTEgMCwwLjI3Mjg1IDAuMTczNjMzLDAuNTcwNTEgMC41NDU3MDMsMC44MTg1NSAwLjU0NTcwMywyLjI4MjAzIDAsMS40Mzg2NyAtMC41OTUzMTIsMi4xMzMyIGwgNC4wMTgzNTksMi4wMDkxOCB2IDIuMTMzMjEgaCAxLjY2MTkxNCB2IDcuMTkzMzYgSCAyNS40MTI0MDIgOS4yNjQ1NTEgdiAtNy4xNjg1NiBoIDEuNjg2NzE5IHYgLTIuMTMzMiBsIDMuOTkzNTU0LC0yLjAzMzk5IHEgLTAuNTk1MzEyLC0wLjY5NDUzIC0wLjU5NTMxMiwtMi4xMzMyIDAsLTEuNDM4NjcgMC41NDU3MDMsLTIuMjU3MjMgMC4xOTg0MzcsLTAuMjcyODUgMC4xOTg0MzcsLTAuNTcwNSAwLC0wLjI0ODA1IC0wLjE5ODQzNywtMC41NzA1MSAtMS4yMTU0MywtMS43MzYzMyAtMC4wMjQ4MSwtMy40NzI2NiAwLjIyMzI0MiwtMC4zOTY4NyAwLjIyMzI0MiwtMC42NDQ5MiAwLC0wLjI0ODA1IC0wLjE3MzYzMiwtMC41NDU3IC0wLjU0NTcwMywtMC43OTM3NSAtMC41NzA1MDgsLTIuMTgyODEgMCwtMS40MTM4NyAwLjUyMDg5OCwtMi4xODI4MiAwLjIyMzI0MiwtMC4yOTc2NSAwLjIyMzI0MiwtMC42MjAxMSAwLC0wLjI3Mjg2IC0wLjE5ODQzNywtMC41NzA1MSAtMS4yNjUwMzksLTEuODEwNzQgMC4wNDk2MSwtMy40NzI2NiBsIC0zLjk5MzU1NCwtNC41ODg4NyB2IC04Ljg1NTI3IGggNS45MDM1MTUgdiAzLjM0ODYzIGwgNS4xMDk3NjYsMC4wMjQ4IHYgLTMuMzczNDQgeiBtIC0xMi42OTk5OTksNi4zMDAzOSB2IDIuMTU4IHEgMy4xNzQ5OTksLTAuMTQ4ODIgNi4zMjUxOTUsLTAuMjk3NjUgMy4xNzUsLTAuMTczNjMgNi4zNzQ4MDQsLTAuMTczNjMgMy4xMjUzOTEsMCA2LjMwMDM5MSwwLjE5ODQzIDMuMTk5ODA1LDAuMTk4NDQgNi4zOTk2MDksMC4yNzI4NSAwLC0wLjgxODU1IDAsLTEuMDY2NiAwLC0wLjI3Mjg1IDAsLTEuMDkxNCB6IG0gMS4wNjY2MDEsMjkuMjE5OTIgcSAtMS4wNjY2MDEsMC4wOTkyIC0xLjA2NjYwMSwxLjA2NjYgdiAwIHEgMCwxLjA2NjYgMS4wNjY2MDEsMS4wNjY2IGwgMTEuNjMzMzk4LC0wLjM5Njg3IDExLjYzMzM5OSwwLjM5Njg3IHEgMS4wNjY2MDEsMCAxLjA2NjYwMSwtMS4wNjY2IHYgMCBxIDAsLTAuOTY3MzggLTEuMDY2NjAxLC0xLjA2NjYgLTIuOTAyMTQ5LC0wLjE3MzYzIC01LjgyOTEwMiwtMC4yOTc2NiAtMi45MDIxNDgsLTAuMTQ4ODMgLTUuODA0Mjk3LC0wLjE0ODgzIC0yLjkwMjE0OCwwIC01LjgyOTEwMSwwLjE0ODgzIC0yLjkwMjE0OSwwLjEyNDAzIC01LjgwNDI5NywwLjI5NzY2IHogbSAxMi44OTg0MzcsLTYuNzIyMDcgcSAwLjcxOTMzNiwtMC41NzA1MSAyLjEwODM5OSwtMC41NzA1MSAxLjQxMzg2NywwIDIuMTU4MDA4LDAuNTcwNTEgMC43NDQxNCwwLjU5NTMxIDAuNzQ0MTQsMS43ODU5NCAwLjAyNDgxLDEuMTkwNjIgLTAuNzQ0MTQsMS41NjI2OSAtMC43OTM3NSwwLjQyMTY4IC0yLjE1ODAwOCwwLjQyMTY4IC0xLjM2NDI1OCwwIC0yLjEwODM5OSwtMC40MjE2OCAtMC43OTM3NSwtMC4zNzIwNyAtMC43Njg5NDUsLTEuNTYyNjkgMC4wMjQ4MSwtMS4xOTA2MyAwLjc2ODk0NSwtMS43ODU5NCB6IG0gLTYuNzk2NDg0LDAgcSAwLjc0NDE0MSwtMC41NzA1MSAyLjEzMzIwMywtMC41NzA1MSAxLjM4OTA2MywwIDIuMTMzMjAzLDAuNTcwNTEgMC43NDQxNDEsMC41OTUzMSAwLjY2OTcyNywxLjc4NTk0IC0wLjA0OTYxLDEuMTkwNjIgLTAuNjY5NzI3LDEuNTYyNjkgLTAuNjQ0OTIyLDAuNDIxNjggLTIuMTgyODEyLDAuMzk2ODggLTEuNTEzMDg2LC0wLjA0OTYgLTIuMDgzNTk0LC0wLjM5Njg4IC0wLjU5NTMxMiwtMC4zMjI0NiAtMC42Njk3MjYsLTEuNTM3ODkgLTAuMDc0NDEsLTEuMjE1NDMgMC42Njk3MjYsLTEuODEwNzQgeiBtIDUuNTMxNDQ1LC0xNy44ODQxOCBxIC0yLjM1NjQ0NSwwIC01LjQ1NzAzMSwwLjMyMjQ2IC0zLjEwMDU4NiwwLjI5NzY2IC0zLjg5NDMzNiwwLjU0NTcgLTAuODE4NTU0LDAuMjk3NjYgLTAuNzQ0MTQsMC45NDI1OCAwLjA3NDQxLDAuNjQ0OTIgMC43NDQxNCwwLjg0MzM2IDAuNjY5NzI3LDAuMjIzMjQgMi42NTQxMDIsLTAuMDQ5NiAxLjk4NDM3NSwtMC4yNzI4NSAyLjQ1NTY2NCwwLjA0OTYgMC40NDY0ODQsMC4zNDcyNyAwLjQ0NjQ4NCwxLjYzNzExIDAsMS4yNjUwNCAtMC40NDY0ODQsMS43MzYzMyAtMC40NzEyODksMC40NzEyOSAtMi41NTQ4ODMsMC4xMjQwMiAtMi4wNTg3ODksLTAuMzQ3MjYgLTIuNTU0ODgzLC0wLjEyNDAyIC0wLjQ5NjA5MywwLjIyMzI0IC0wLjM5Njg3NSwwLjgxODU1IDAuMDk5MjIsMC41NzA1MSAwLjM5Njg3NSwwLjg0MzM2IDAuMjk3NjU3LDAuMjk3NjYgMC44NjgxNjQsLTAuMTI0MDIgMC41OTUzMTMsLTAuNDIxNjggMC44OTI5NjksMC4xMjQwMiAwLjI5NzY1NiwwLjU5NTMxIDAuMjk3NjU2LDEuNzExNTMgMCwxLjExNjIxIC0wLjI5NzY1NiwxLjY2MTkxIC0wLjI5NzY1NiwwLjU3MDUxIC0wLjg5Mjk2OSwwLjE0ODgzIC0wLjU3MDUwNywtMC40NDY0OSAtMC44NjgxNjQsLTAuMTQ4ODMgLTAuMzIyNDYxLDAuMzIyNDYgLTAuMzQ3MjY1LDAuOTY3MzggMCwwLjYyMDEyIDAuMzQ3MjY1LDAuNzkzNzUgMC4zMjI0NjEsMC4yMjMyNCAyLjQ4MDQ2OSwtMC4wOTkyIDIuMTU4MDA4LC0wLjM0NzI2IDIuNjI5Mjk3LDAuMDk5MiAwLjQ0NjQ4NCwwLjQ3MTI5IDAuNDQ2NDg0LDEuNjYxOTIgMCwxLjE5MDYyIC0wLjQ0NjQ4NCwxLjcxMTUyIC0wLjQ3MTI4OSwwLjU0NTcgLTIuNjU0MTAyLDAuMTczNjMgLTIuMTU4MDA3LC0wLjM5Njg3IC0yLjQ1NTY2NCwtMC4xNzM2MyAtMC45NjczODMsMC43OTM3NSAwLDEuNjg2NzIgMC4yOTc2NTcsMC4yOTc2NSAwLjg2ODE2NCwtMC4xMjQwMyAwLjU5NTMxMywtMC40MjE2NyAwLjg5Mjk2OSwwLjEyNDAzIDAuMjk3NjU2LDAuNTcwNTEgMC4yOTc2NTYsMS42ODY3MiAwLDEuMTE2MjEgLTAuMjk3NjU2LDEuNjYxOTEgLTAuMjk3NjU2LDAuNTk1MzEgLTAuODkyOTY5LDAuMTczNjMgLTAuNTcwNTA3LC0wLjQ0NjQ4IC0wLjg2ODE2NCwtMC4xNzM2MyAtMC4yOTc2NTYsMC4yOTc2NiAtMC40NzEyODksMC44OTI5NyAtMC4xNzM2MzMsMC41NzA1MSAwLjQ3MTI4OSwwLjc5Mzc1IDAuNDk2MDk0LDAuMTk4NDQgMy4yNzQyMTksLTAuMDc0NCAyLjc3ODEyNSwtMC4yNzI4NiA2LjA3NzE0OCwtMC4yNzI4NiAzLjI3NDIxOSwwIDYuMTI2NzU4LDAuMjIzMjUgMi44NTI1MzksMC4xOTg0MyAzLjIyNDYwOSwwLjEyNDAyIDAuNTIwODk5LC0wLjA3NDQgMC4zOTY4NzUsLTAuNzE5MzQgLTAuMDk5MjIsLTAuNjY5NzIgLTAuMzk2ODc1LC0wLjk2NzM4IC0wLjMyMjQ2MSwtMC4yNzI4NSAtMC45MTc3NzMsMC4xNzM2MyAtMC41NzA1MDgsMC40MjE2OCAtMC44NDMzNTksLTAuMTczNjMgLTAuMjk3NjU3LC0wLjU0NTcgLTAuMjk3NjU3LC0xLjY2MTkxIDAsLTEuMTE2MjEgMC4yOTc2NTcsLTEuNjg2NzIgMC4yNzI4NTEsLTAuNTQ1NyAwLjg2ODE2NCwtMC4xMjQwMyAwLjU5NTMxMiwwLjQyMTY4IDAuODkyOTY4LDAuMTI0MDMgMC45MTc3NzQsLTAuOTE3NzggMCwtMS42ODY3MiAtMC4yOTc2NTYsLTAuMjIzMjQgLTIuNTU0ODgyLDAuMTI0MDIgLTIuMjU3MjI3LDAuMzQ3MjcgLTIuNTc5Njg4LC0wLjEyNDAyIC0wLjMyMjQ2MSwtMC40NDY0OCAtMC4zNzIwNywtMS41NjI3IC0wLjAyNDgxLC0xLjE0MTAxIDAuMzcyMDcsLTEuODEwNzQgMC4zOTY4NzUsLTAuNjY5NzIgMi41Nzk2ODgsLTAuMjQ4MDQgMi4yMDc2MTcsMC40MjE2OCAyLjU1NDg4MiwwLjI0ODA0IDAuMjk3NjU3LC0wLjE0ODgzIDAuMjk3NjU3LC0wLjc5Mzc1IDAsLTAuNjQ0OTIgLTAuMjk3NjU3LC0wLjk2NzM4IC0wLjMyMjQ2MSwtMC4yOTc2NiAtMC45MTc3NzMsMC4xNDg4MyAtMC41NzA1MDgsMC40MjE2OCAtMC44NDMzNTksLTAuMTQ4ODMgLTAuMjk3NjU3LC0wLjU0NTcgLTAuMjk3NjU3LC0xLjY2MTkxIDAsLTEuMTE2MjIgMC4yOTc2NTcsLTEuNzExNTMgMC4yNzI4NTEsLTAuNTQ1NyAwLjg0MzM1OSwtMC4xMjQwMiAwLjU5NTMxMiwwLjQyMTY4IDAuOTE3NzczLDAuMTI0MDIgMC4yOTc2NTcsLTAuMjcyODUgMC4zMjI0NjEsLTAuODQzMzYgMC4wNDk2MSwtMC41OTUzMSAtMC4zMjI0NjEsLTAuODE4NTUgLTAuNDIxNjc5LC0wLjIyMzI0IC0yLjU3OTY4NywwLjEyNDAyIC0yLjE1ODAwOCwwLjM0NzI3IC0yLjU1NDg4MywtMC4xMjQwMiAtMC4zOTY4NzUsLTAuNDcxMjkgLTAuMzk2ODc1LC0xLjY4NjcyIDAsLTEuMjE1NDMgMC4zOTY4NzUsLTEuNjg2NzIgMC4zOTY4NzUsLTAuNDQ2NDggMi40MzA4NTksLTAuMDQ5NiAyLjAzMzk4NSwwLjM5Njg4IDIuNzAzNzExLDAuMDQ5NiAwLjY0NDkyMiwtMC4zMjI0NiAwLjY5NDUzMiwtMC44OTI5NyAwLjA3NDQxLC0wLjU5NTMxIC0wLjY5NDUzMiwtMC44OTI5NyAtMC44MTg1NTQsLTAuMjQ4MDQgLTMuOTQzOTQ1LC0wLjU0NTcgLTMuMTAwNTg2LC0wLjMyMjQ2IC01LjQwNzQyMiwtMC4zMjI0NiB6IG0gLTIuMDU4Nzg5LDIuNjU0MSBxIDAuNjk0NTMyLC0wLjU3MDUxIDIuMDMzOTg1LC0wLjU3MDUxIDEuMzY0MjU3LDAgMi4wODM1OTMsMC41NzA1MSAwLjcxOTMzNiwwLjU5NTMxIDAuNzE5MzM2LDEuNjg2NzIgMCwxLjA5MTQxIC0wLjcxOTMzNiwxLjY4NjcyIC0wLjcxOTMzNiwwLjU5NTMxIC0yLjA4MzU5MywwLjU5NTMxIC0xLjMzOTQ1MywwIC0yLjAzMzk4NSwtMC41OTUzMSAtMC43MTkzMzYsLTAuNTk1MzEgLTAuNzE5MzM2LC0xLjY4NjcyIDAsLTEuMDkxNDEgMC43MTkzMzYsLTEuNjg2NzIgeiBtIDMuMzIzODI4LDUuMDM1MzUgcSAwLjcxOTMzNiwtMC41NzA1MSAyLjEwODM5OSwtMC41NzA1MSAxLjQxMzg2NywwIDIuMTU4MDA4LDAuNTcwNTEgMC43NDQxNCwwLjU5NTMxIDAuNzQ0MTQsMS43MTE1MyAwLDEuMDkxNCAtMC43NDQxNCwxLjY2MTkxIC0wLjc0NDE0MSwwLjU5NTMxIC0yLjE1ODAwOCwwLjU5NTMxIC0xLjM4OTA2MywwIC0yLjEwODM5OSwtMC41OTUzMSAtMC43NDQxNCwtMC41NzA1MSAtMC43NDQxNCwtMS42NjE5MSAwLC0xLjExNjIyIDAuNzQ0MTQsLTEuNzExNTMgeiBtIC02Ljc5NjQ4NCwwIHEgMC43NDQxNDEsLTAuNTcwNTEgMi4xMzMyMDMsLTAuNTcwNTEgMS4zODkwNjMsMCAyLjEzMzIwMywwLjU3MDUxIDAuNzQ0MTQxLDAuNTk1MzEgMC43NDQxNDEsMS43MTE1MyAwLDEuMDkxNCAtMC43NDQxNDEsMS42NjE5MSAtMC43NDQxNCwwLjU5NTMxIC0yLjEzMzIwMywwLjU5NTMxIC0xLjM4OTA2MiwwIC0yLjEzMzIwMywtMC41OTUzMSAtMC43NDQxNCwtMC41NzA1MSAtMC43NDQxNCwtMS42NjE5MSAwLC0xLjExNjIyIDAuNzQ0MTQsLTEuNzExNTMgeiBtIDMuNDcyNjU2LDUuMTM0NTcgcSAwLjY5NDUzMiwtMC41NzA1MSAyLjAzMzk4NSwtMC41NzA1MSAxLjM2NDI1NywwIDIuMDgzNTkzLDAuNTcwNTEgMC43MTkzMzYsMC41OTUzMSAwLjcxOTMzNiwxLjcxMTUzIDAsMS4wOTE0IC0wLjcxOTMzNiwxLjY2MTkxIC0wLjcxOTMzNiwwLjU5NTMxIC0yLjA4MzU5MywwLjU5NTMxIC0xLjMzOTQ1MywwIC0yLjAzMzk4NSwtMC41OTUzMSAtMC43MTkzMzYsLTAuNTcwNTEgLTAuNzE5MzM2LC0xLjY2MTkxIDAsLTEuMTE2MjIgMC43MTkzMzYsLTEuNzExNTMgeiBtIC0xMi4zMjc5MjksMTUuNjAyMTUgdiAxLjY4NjcyIGggMjguNzk4MjQyIHYgLTEuNjg2NzIgeiIKICAgICAgICAgc3R5bGU9InN0cm9rZS13aWR0aDowLjI2NDU4MzMyIgogICAgICAgICBpZD0icGF0aDc5IgogICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPC9nPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDEyLjczNDU4NSwyNTcuMDIxNzUgdiAtMS4wNTIzNyBoIDEyLjY3ODU5OCAxMi42Nzg1OTggdiAxLjA1MjM3IDEuMDUyMzggbCAtMC4zOTI1NTIsLTIuN2UtNCBjIC0wLjc5NzU1NSwtNS41ZS00IC0zLjMyMjEzNSwtMC4xMDY1MyAtNS41NTQxOTQsLTAuMjMzMTUgLTMuMTk0MDQ1LC0wLjE4MTE4IC00LjE3NjU5MywtMC4yMTEzOCAtNi44NDg3ODMsLTAuMjEwNDkgLTIuMTM2MDQ0LDcuMmUtNCAtMy41ODQyMDIsMC4wMzE0IC01LjE5NTA1MSwwLjExMDEzIC0wLjM2NzQ5NiwwLjAxNzkgLTEuNjIyODI3LDAuMDc3NyAtMi43ODk2MjYsMC4xMzI4IC0xLjE2Njc5OCwwLjA1NTEgLTIuNTg4NTYxLDAuMTIyODQgLTMuMTU5NDczLDAuMTUwNTcgLTAuNTcwOTExLDAuMDI3NyAtMS4xMjM0MDcsMC4wNTA0IC0xLjIyNzc2OSwwLjA1MDQgaCAtMC4xODk3NDggeiIKICAgICAgIGlkPSJwYXRoODIiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDE2LjE5MjM4NCwyODMuNDk5NzEgYyAtMC40MDA5MDMsLTAuMSAtMC42MTgwNjEsLTAuMzEwNTQgLTAuNjE4MDYxLC0wLjU5OTI4IDAsLTAuMjc5MzYgMC4yOTAxMjEsLTAuOTA2NzUgMC41MDE1ODgsLTEuMDg0NjkgMC4yMDQzNzksLTAuMTcxOTcgMC4zODA3NjYsLTAuMTQxOTkgMC44MDg4OSwwLjEzNzQ5IDAuMzk3OTU5LDAuMjU5NzkgMC42MDE4NjgsMC4yNjg1NyAwLjgxMjg4LDAuMDM1IDAuMjMxMzE4LC0wLjI1NjA0IDAuMzU5OTcsLTAuNjgxNzggMC40MTg1NDEsLTEuMzg1MDYgMC4wODQ1NSwtMS4wMTUyNSAtMC4xMDYzMDksLTIuMDY5OSAtMC40MjUyNzgsLTIuMzQ5OTYgLTAuMjE5OTE1LC0wLjE5MzA5IC0wLjQwMjY0LC0wLjE3MTk1IC0wLjg0NzA4MywwLjA5OCAtMC40NDcwODYsMC4yNzE1NSAtMC41ODQxODMsMC4yNjc1NCAtMC44Njk5MjIsLTAuMDI1NCAtMC40ODIyMjYsLTAuNDk0NDQgLTAuNDg5NjEyLC0wLjk5MTEyIC0wLjAyMTMzLC0xLjQzNDAxIDAuMTUzMDIsLTAuMTQ0NzIgMC4xOTkxODUsLTAuMTY5MDQgMC4zNTgwNTksLTAuMTg4NjggMC4yOTgwNTUsLTAuMDM2OCAwLjk0MzM2NSwwLjAzMDUgMi4wMzY1NzIsMC4yMTI2NCAwLjg3OTQ4OCwwLjE0NjQ5IDEuMjI0NTE4LDAuMTc3NSAxLjc4Mjc1OCwwLjE2MDIyIDAuNTYxNzAxLC0wLjAxNzQgMC43OTUzMjgsLTAuMDc4MyAxLjAwNDMyNCwtMC4yNjE3OSAwLjE0ODE4OSwtMC4xMzAxMSAwLjI5ODk3NSwtMC40MjQ5MiAwLjM5MTg1MiwtMC43NjYxNSAwLjA2OTQ3LC0wLjI1NTIzIDAuMDc3MzUsLTAuMzU2NjcgMC4wNzc4NSwtMS4wMDIyNiA1LjAzZS00LC0wLjY0ODM1IC0wLjAwNjgsLTAuNzQzNzMgLTAuMDc1MTgsLTAuOTc5NjUgLTAuMDkzMzQsLTAuMzIyMDkgLTAuMTc2NTAzLC0wLjQ4ODQyIC0wLjMyODEzLC0wLjY1NjI2IC0wLjI5NjI2NCwtMC4zMjc5MiAtMS4wNTQzMjgsLTAuMzcyMzEgLTIuNTg2MjA5LC0wLjE1MTQzIC0wLjkyODg2MywwLjEzMzkzIC0xLjQ1MTUwNiwwLjE4NTI5IC0xLjkxNDE1NSwwLjE4ODEgLTAuNDcwMzA2LDAuMDAzIC0wLjYwMTk3NSwtMC4wMjY3IC0wLjc0OTgzMiwtMC4xNjg0NiAtMC4xNjMxMzcsLTAuMTU2MzggLTAuMTkyNDU2LC0wLjI2MTE3IC0wLjE5MjQ1NiwtMC42ODc4NCAwLC0wLjM3ODU5IDAuMDA1NywtMC40MTMgMC4xMDMwMTgsLTAuNjE4MjggMC4xMTg0NywtMC4yNDk5OCAwLjI3MTEyOCwtMC40MTc5OSAwLjQwMjY0MSwtMC40NDMxMyAwLjEzNzQwNSwtMC4wMjYzIDAuMzYwMzEzLDAuMDU0MSAwLjYwODM1NywwLjIxOTM0IDAuMzYzNjcsMC4yNDIyNyAwLjU2MTc5MywwLjI3NDU5IDAuNzcwODM5LDAuMTI1NzMgMC4zNDA2NSwtMC4yNDI1NiAwLjU2MDgyNiwtMS4zMzkwNyAwLjQ3NDkzMywtMi4zNjUyMyAtMC4wODUxOCwtMS4wMTc2MSAtMC4zMDUxNjcsLTEuNTI3MzggLTAuNjc3MjM1LC0xLjU2OTMyIC0wLjE3MTE2MSwtMC4wMTkzIC0wLjMwMzgyMSwwLjAzMiAtMC42NTY5MDEsMC4yNTM3NiAtMC4yNjU0NzgsMC4xNjY3NyAtMC40Mjk3NTYsMC4xOTg0NSAtMC41OTgyNTEsMC4xMTUzNiAtMC4yNTY1OTksLTAuMTI2NTQgLTAuNDc0NjE5LC0wLjU2Nzk0IC0wLjUwMzAwNywtMS4wMTgzOCAtMC4wMTQwMiwtMC4yMjI0NiAtMC4wMDYyLC0wLjI3MzA3IDAuMDYwNjMsLTAuMzkxOTcgMC4wODY0MSwtMC4xNTM3NCAwLjI1ODM3NywtMC4yODEwNyAwLjQ1MjMzOCwtMC4zMzQ5MyAwLjMyNjYxLC0wLjA5MDcgMS4xNzA0OTEsLTAuMDMyOSAyLjQxOTA3OSwwLjE2NTYxIDAuNzY5MTIyLDAuMTIyMjkgMS42OTk1NDksMC4xNjc2OCAyLjA0NDc3MywwLjA5OTggMC40OTE3ODUsLTAuMDk2NyAwLjcwNjIyNiwtMC4zMjcwMiAwLjg2NzU4NCwtMC45MzE2MSAwLjA5NDY5LC0wLjM1NDggMC4xMjQzOSwtMS4zOTc1NCAwLjA1MTUzLC0xLjgwOTIyIC0wLjEwNzQxOSwtMC42MDY5MyAtMC4yODUxNDYsLTAuODgwOTggLTAuNjQxOTgsLTAuOTg5OTQgLTAuMTY0MTIsLTAuMDUwMSAtMC4zMDY0MjEsLTAuMDYwNiAtMC43ODUxMDUsLTAuMDU3NyAtMC41Mzk4ODgsMC4wMDMgLTAuNzczNjcxLDAuMDIzOSAtMS44NzA4ODYsMC4xNjU5IC0wLjIxMTMxLDAuMDI3MyAtMC43MDc0MjksMC4wNTgxIC0xLjEwMjQ4NywwLjA2ODQgLTAuNTg5MzA1LDAuMDE1NCAtMC43NTg4MzUsMC4wMDkgLTAuOTQ0MDk0LC0wLjAzNDYgLTAuNTg0MzQyLC0wLjEzNzg4IC0wLjg5MDk1NiwtMC40NjM4OSAtMC44OTI2NSwtMC45NDkxMiAtMC4wMDE2LC0wLjQ1NTU1IDAuMzE1NjQ4LC0wLjc1MSAwLjk3NjI1NiwtMC45MDkyIDAuNTkzNDY5LC0wLjE0MjEzIDEuOTE0NzY2LC0wLjMxNTAxIDMuODE3MTU3LC0wLjQ5OTQ2IDIuNDI2MDM5LC0wLjIzNTIyIDMuMzI5MjMyLC0wLjI4NDA1IDUuMjYxODY5LC0wLjI4NDQ3IDEuOTk5NjgsLTQuM2UtNCAyLjkyMDE4NCwwLjA1MiA1LjU3Mjg0NywwLjMxNzQgMi40MjY5NTYsMC4yNDI4MyAzLjU5MjUzMSwwLjQxODA3IDMuOTMwNDQ2LDAuNTkwOTEgMC4zODg2NzMsMC4xOTg4MSAwLjU3NjMxLDAuNDcyODEgMC41NDMyMzQsMC43OTMyNyAtMC4wMjU1OSwwLjI0Nzg3IC0wLjEyNTkzMSwwLjQ1NzQyIC0wLjMwMDExNywwLjYyNjcxIC0wLjUxMDM4MywwLjQ5NjA0IC0xLjI0NTk2LDAuNTUwNTMgLTMuMDY0NjcxLDAuMjI3MDMgLTAuODI0MTIxLC0wLjE0NjU4IC0xLjA3Nzg3MywtMC4xNzYxMyAtMS41MzY4LC0wLjE3ODk3IC0wLjY3NTc1NCwtMC4wMDQgLTAuOTE1MzI0LDAuMTA3MTMgLTEuMDkyNDA3LDAuNTA3NTUgLTAuMzExMTU4LDAuNzAzNTggLTAuMzA0NDQzLDIuMjE1OTIgMC4wMTI3LDIuODYxMzcgMC4xMTM4NjYsMC4yMzE3NCAwLjI1OTk3NCwwLjM3MjM3IDAuNDU5MTIxLDAuNDQxOTEgMC4xNDE4MDMsMC4wNDk1IDAuMjgxNzEsMC4wNTg5IDAuODU0NDQ1LDAuMDU3NCAwLjU5NDc3MSwtMC4wMDIgMC43NzcxODgsLTAuMDE1OCAxLjM4NjQ2MiwtMC4xMDgxOCAxLjM5NDkxOCwtMC4yMTE1MiAyLjIwNzM2MywtMC4yNjMyIDIuNDk5NTExLC0wLjE1OTAxIDAuMzMzMDY4LDAuMTE4NzkgMC40NjUxNTEsMC40NDU4MSAwLjM5MjU2MiwwLjk3MTk0IC0wLjA0NDU4LDAuMzIzMTIgLTAuMTY1ODg2LDAuNTg1MjQgLTAuMzI4MDMsMC43MDg4MyAtMC4yMjE2ODEsMC4xNjg5NyAtMC40NzcxMzksMC4xMTg2NCAtMC45MzI1MTQsLTAuMTgzNzEgLTAuMjExODYyLC0wLjE0MDY3IC0wLjQxODU1MiwtMC4xNzUyNCAtMC41NzIzMiwtMC4wOTU3IC0wLjM2NjQyOSwwLjE4OTQ5IC0wLjYwNjI3OSwxLjM1NjUgLTAuNTEwMjM2LDIuNDgyNTkgMC4wNzQyMiwwLjg3MDE2IDAuMzA0NTc4LDEuNDIwMzEgMC42Mjg3ODUsMS41MDE2OSAwLjEyMTEzMiwwLjAzMDQgMC4zMDQ1ODEsLTAuMDM2OSAwLjU2MjQ5MSwtMC4yMDY0MiAwLjQ5Njc1LC0wLjMyNjQ2IDAuNzcyNDIsLTAuMzA0ODMgMC45NzU2OTEsMC4wNzY1IDAuMjQ1OTYyLDAuNDYxNDcgMC4yMTUwMTksMS4yNTEyIC0wLjA1ODU2LDEuNDk0NTEgLTAuMDYwNDgsMC4wNTM4IC0wLjEzMzMxNSwwLjA2OTEgLTAuMzczNjYzLDAuMDc4NiAtMC40MzcyMSwwLjAxNzIgLTEuMDIzODI2LC0wLjA2MDMgLTIuNTAwODc2LC0wLjMzMDI1IC0wLjQ4ODkwMiwtMC4wODk0IC0xLjM4MTY4LC0wLjEyNTE1IC0xLjY3NjIwNywtMC4wNjcyIC0wLjI3MzIxNiwwLjA1MzggLTAuNTAyOTg2LDAuMTcyNjQgLTAuNjEzMzgzLDAuMzE3MzggLTAuMTE3NTQ5LDAuMTU0MTIgLTAuMjYzMTk0LDAuNTM1ODEgLTAuMzM4Mzk5LDAuODg2ODYgLTAuMDkxMjMsMC40MjU4NiAtMC4wODE3MSwxLjMzMDMzIDAuMDE5LDEuODA0MDcgMC4wODM3OSwwLjM5NDE5IDAuMjI5MDAyLDAuNzMwOTkgMC4zNTkzOTEsMC44MzM1NiAwLjMyMTQ5MywwLjI1Mjg5IDEuMDI2NzI0LDAuMjU3MzYgMi43MzQxMTIsMC4wMTc0IDAuOTY3MTg3LC0wLjEzNTk2IDEuNzk0ODE0LC0wLjIwMzQzIDIuMDY3NTMsLTAuMTY4NTQgMC4xNjk4NDIsMC4wMjE3IDAuMjE4MTI2LDAuMDQ1MiAwLjM1MzM5NiwwLjE3MTcyIDAuMjMzNDExLDAuMjE4MzMgMC4zNDgyMjksMC40NTA0MSAwLjM0NTY4NywwLjY5ODc0IC0wLjAwMjQsMC4yMzkwNiAtMC4wNTM3NywwLjM2NzAxIC0wLjI1OTA1MSwwLjY0NTg2IC0wLjMxOTI5NCwwLjQzMzc0IC0wLjUyMDQzMywwLjQ0MDM3IC0xLjE1MTYzNCwwLjAzOCAtMC4xNDc1MTUsLTAuMDk0IC0wLjIxMzI4OCwtMC4xMTUyNSAtMC4zNTcyODgsLTAuMTE1MjUgLTAuMTU1Mjc2LDAgLTAuMTkwNSwwLjAxMzYgLTAuMjkzMDU1LDAuMTEyOTggLTAuMjE5MjQ5LDAuMjEyNSAtMC4zNjQzNjUsMC42ODU5MyAtMC40MjQwOTgsMS4zODM1OSAtMC4wOTk1MiwxLjE2MjMyIDAuMTUyODY2LDIuMjk0NjcgMC41NTQwODgsMi40ODYgMC4xNjEyMzcsMC4wNzY5IDAuMzM2MzcsMC4wMjc4IDAuNjY0MzY2LC0wLjE4NjM2IDAuNTIyMTc0LC0wLjM0MDg3IDAuNzkzNjMxLC0wLjI5MTIxIDEuMDM2OTY2LDAuMTg5NzIgMC4wOTAxMiwwLjE3ODEyIDAuMTg3NzY2LDAuNjA3NTYgMC4xODk3ODgsMC44MzQ2OCAwLjAwMywwLjMzMTcxIC0wLjEyNTkyOSwwLjQ2ODQ1IC0wLjQ4NDI5NiwwLjUxMzg0IC0wLjIzNjg4NCwwLjAzIC0xLjM1MDUzNywtMC4wMTMzIC0yLjc2MDMwOCwtMC4xMDc0IC0yLjkwNzE2MiwtMC4xOTM5OCAtMy4xMDA4ODgsLTAuMjAxNiAtNS42NDYwNjksLTAuMjIyMjggLTIuODkxMjg5LC0wLjAyMzUgLTQuNTc1OTg0LDAuMDMzNCAtNi42MzE2MjUsMC4yMjQwMiAtMS4zNzg0ODksMC4xMjc4MiAtMi4wMTQxMDUsMC4xNjY2NSAtMi42NzI2OTUsMC4xNjMyOCAtMC4zNjc0OTYsLTAuMDAyIC0wLjcxMzI3NSwtMC4wMTQ2IC0wLjc2ODQsLTAuMDI4NCB6IG0gMTMuNjkzMzM5LC0xLjM1NDM2IGMgMC42MTE5NzEsLTAuMTExNjIgMS4xMTMwODksLTAuMzE0NTkgMS4zNzY3ODYsLTAuNTU3NjYgMC4zMTI5NTIsLTAuMjg4NDcgMC40Njg4NTUsLTAuODE5NiAwLjQzNDU4NCwtMS40ODA1MyAtMC4wMzU5NCwtMC42OTMxMyAtMC4yMDU3ODUsLTEuMTM2MjQgLTAuNTgyMDQxLC0xLjUxODUgLTAuNDAxNTQsLTAuNDA3OTQgLTEuMDAxMDA5LC0wLjYzNDA0IC0xLjg4MDkxLC0wLjcwOTQgLTEuMTYwMzQ2LC0wLjA5OTQgLTIuMTg1MjMzLDAuMTYxNTcgLTIuNzE0OTI0LDAuNjkxMjYgLTAuMjM5NDgyLDAuMjM5NDkgLTAuNDQ1OTA0LDAuNjA5OTUgLTAuNTM5NzQ3LDAuOTY4NjkgLTAuMDc0MjcsMC4yODM5IC0wLjEwMDAwMiwwLjkxNDUgLTAuMDQ5NTIsMS4yMTM0IDAuMDU1MTgsMC4zMjY3MSAwLjIyNzY4NiwwLjY2NjE0IDAuNDI4MzA5LDAuODQyNzMgMC4zNTQ5MTgsMC4zMTI0MiAwLjk1Mjc2MywwLjUxNTAxIDEuODExMTQzLDAuNjEzNzUgMC4yNzA5NTEsMC4wMzEyIDEuNDMyNDQ4LC0wLjAxMiAxLjcxNjMyMiwtMC4wNjM3IHogbSAtNi45MTEzNzUsMC4wMTM4IGMgMC44NzcyNjQsLTAuMTA0NTQgMS4zODcyNjQsLTAuMzcwODQgMS42MjE1MjEsLTAuODQ2NjggMC4yMjU0NTcsLTAuNDU3OTcgMC4zMDQ3NTgsLTEuMzYzNzggMC4xNjY2NjUsLTEuOTAzNzIgLTAuMjQ4NDMzLC0wLjk3MTM2IC0xLjA0NDI5NywtMS40NjMxOSAtMi40OTY2MiwtMS41NDI4NyAtMS4wNjc1MzIsLTAuMDU4NiAtMi4wNDU3NTksMC4yMTE4IC0yLjUzNDQxNiwwLjcwMDQ4IC0wLjIyMTEzNywwLjIyMTE0IC0wLjQwNDgyMywwLjU1NjcxIC0wLjQ4NjgwMSwwLjg4OTMgLTAuMDYwOTIsMC4yNDcxNCAtMC4wNTI4MiwxLjAxNTE0IDAuMDEzOTEsMS4zMTk2NCAwLjEyMjM3OCwwLjU1ODQxIDAuMzEyMzg0LDAuODY1MDIgMC42NDYzNzIsMS4wNDMwMyAwLjI2NzY4NywwLjE0MjY4IDAuNjkxMzg4LDAuMjU5OSAxLjExNDk1NywwLjMwODQ2IDAuMTkyOTM1LDAuMDIyMSAwLjM4MDg1OSwwLjA0NDUgMC40MTc2MDgsMC4wNDk3IDAuMTg0MjM4LDAuMDI2MyAxLjI3MzczMiwwLjAxNCAxLjUzNjgsLTAuMDE3NCB6IG0gMi45MjY1NjksLTQuODIzNjMgYyAwLjk0Mzc2MiwtMC4wNTc5IDEuNzYyNjU4LC0wLjUyNTg1IDIuMDc3ODA2LC0xLjE4NzMyIDAuMzMzMTk4LC0wLjY5OTM2IDAuMjg3NTQxLC0xLjcyMDczIC0wLjEwMzkxLC0yLjMyNDUyIC0wLjM2MzMwMiwtMC41NjAzOCAtMC45NzI0MiwtMC44ODE2MyAtMS44NzMwNjQsLTAuOTg3ODUgLTAuMzYyNTAzLC0wLjA0MjcgLTEuMjM1MDM2LC0wLjAyMTMgLTEuNTA3MzA1LDAuMDM3MSAtMS4xOTc5MywwLjI1Njc4IC0xLjgwNzEzMSwwLjkzNTI4IC0xLjg2MTU5NiwyLjA3MzM0IC0wLjA0Mjk1LDAuODk3NTMgMC4yNDczMDIsMS41MjMyIDAuOTEzMjYsMS45Njg2MiAwLjQ0OTMwNCwwLjMwMDUxIDEuMjYyOTkyLDAuNDg4NDIgMS45MzM4OTIsMC40NDY2MSAwLjA3MzUsLTAuMDA1IDAuMjYyOTEyLC0wLjAxNjMgMC40MjA5MTcsLTAuMDI1OSB6IG0gLTMuMzI3NDczLC01LjEzMDg1IGMgMC43Nzg0NzIsLTAuMDg4NCAxLjMzNzkwNCwtMC4zMTg3MiAxLjc0MzI4OCwtMC43MTc1OCAwLjQzMTQ2OSwtMC40MjQ1MiAwLjU5NzY3OSwtMC45MDM2NSAwLjU3MTM5NCwtMS42NDcxMyAtMC4wMTgxNSwtMC41MTMyNiAtMC4xMTM0NjcsLTAuODM2MTUgLTAuMzUwMTM0LC0xLjE4NjA1IC0wLjQ2OTAyLC0wLjY5MzQyIC0xLjQ1OTQzMywtMS4wNDE2OSAtMi43ODMwNjEsLTAuOTc4NjQgLTEuNDQ3NDI2LDAuMDY4OSAtMi4yNzgxNTQsMC41OTcwMiAtMi41NTk1MTMsMS42MjY5OSAtMC4wODEzLDAuMjk3NjMgLTAuMDgxMDMsMS4wMDAyNCA1LjAzZS00LDEuMzAwMSAwLjI0NDAzOSwwLjg5NzQ5IDEuMDI2NTk4LDEuNDYzNzcgMi4yMDgyMTYsMS41OTc5NCAwLjM3NTkxOCwwLjA0MjcgMC44MTc1OSwwLjA0NDMgMS4xNjkzMDQsMC4wMDQgeiBtIDYuNzg4NTQyLC0wLjAwMSBjIDEuMjQ0MjQzLC0wLjEzODc0IDIuMDE4NzEzLC0wLjY4NjI0IDIuMjY4Nzc2LC0xLjYwMzg3IDAuMDc4MjQsLTAuMjg3MSAwLjA3OTY3LC0wLjk2MTUgMC4wMDI3LC0xLjI3NDk4IC0wLjE3Mjk3NiwtMC43MDQ1MyAtMC42NTM0OTEsLTEuMjAxNDUgLTEuNDE1Nzk4LC0xLjQ2NDE2IC0wLjY1ODk0OCwtMC4yMjcwOCAtMS44NDg3MTUsLTAuMjU1NyAtMi42MDgxNDYsLTAuMDYyNyAtMC4zMjUwOTEsMC4wODI2IC0wLjc0MDY3LDAuMjgwNjMgLTAuOTY3ODM4LDAuNDYxMTcgLTAuMjQ2MzkzLDAuMTk1ODIgLTAuNDkyMTEyLDAuNTU5OTEgLTAuNTk4OTYzLDAuODg3NTIgLTAuMDcwMDYsMC4yMTQ4IC0wLjA5MTIzLDAuMzU2MjggLTAuMTAzNzM3LDAuNjkzNDcgLTAuMDE4NywwLjUwMzk2IDAuMDMzOTMsMC43OTI4OSAwLjIxMjE1MSwxLjE2NDc5IDAuNDI5NTA3LDAuODk2MjMgMS42OTMxODMsMS4zNjgwMyAzLjIxMDg1NCwxLjE5ODggeiBtIC0zLjMzMDc0MywtNS4wNDMzNyBjIDEuMzk2NDU0LC0wLjE4MDY0IDIuMTcxNTY2LC0wLjk4MzYzIDIuMTcxNTY2LC0yLjI0OTY3IDAsLTAuODg3MTUgLTAuMzczMDI4LC0xLjU2MTY0IC0xLjA2MTYsLTEuOTE5NTUgLTAuNjk2NTg2LC0wLjM2MjA4IC0xLjkwNjI2MSwtMC40NjUxIC0yLjgzNDMwOSwtMC4yNDEzNyAtMS4wODUwNzMsMC4yNjE1NyAtMS42ODMzNDMsMS4wMjk1OCAtMS42ODMzNDMsMi4xNjA5MiAwLDEuMjQ0MDYgMC43NTE1OTMsMi4wNTE4NSAyLjA5MDgzMiwyLjI0NzE3IDAuMjc0NTE5LDAuMDQgMS4wMTU3OTMsMC4wNDE0IDEuMzE2ODU0LDAuMDAzIHoiCiAgICAgICBpZD0icGF0aDg0IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAxMy4zMzQ5MTgsMjg3LjIyMjAxIGMgLTAuMzYxNjg2LC0wLjExMTUgLTAuNTY1MTU3LC0wLjQxNzI1IC0wLjU5MjU1OCwtMC44OTA0MyAtMC4wMzI5NCwtMC41Njg4NyAwLjE2NjM2LC0wLjg5NzgzIDAuNjQ2MTExLC0xLjA2NjQ1IDAuMjEwMzMyLC0wLjA3MzkgMC45NDAzNjgsLTAuMTI1NzggMy42ODkyNDMsLTAuMjYyMDYgNi4wMDQ5NDMsLTAuMjk3NzEgOS4xOTc3NzYsLTAuMzM5MDEgMTMuMDI5Mzg5LC0wLjE2ODUzIDAuNDEzNDMzLDAuMDE4NCAxLjI2Mjg0OCwwLjA1NiAxLjg4NzU5MywwLjA4MzYgMS40MDMyOTIsMC4wNjIgMy40OTE1NSwwLjE3MDQxIDQuNDk4NzM3LDAuMjMzNTggMC43OTM0OCwwLjA0OTggMS4wMTA3NTgsMC4wOTQgMS4yMzAyMjUsMC4yNTAyNCAwLjI2NzA1MiwwLjE5MDE2IDAuMzg1NDc3LDAuNDk1NjYgMC4zNjAzNDcsMC45Mjk1OSAtMC4wMjc4NCwwLjQ4MDg1IC0wLjIzMTk1LDAuNzgxMTQgLTAuNjA2NTM2LDAuODkyMzggLTAuMjMwMzQ3LDAuMDY4NCAtMC4yNTIwOTMsMC4wNjggLTUuMTkzOTA2LC0wLjEwMTI3IC0yLjQxODk3NCwtMC4wODI5IC00Ljk1NDM5MiwtMC4xNjkzNiAtNS42MzQyNiwtMC4xOTIyNCAtMS4wNjgzOTksLTAuMDM2IC0xLjQ2MDUwNCwtMC4wMzQgLTIuODg5ODUsMC4wMTQzIC0zLjIyODQ4LDAuMTA5MTQgLTMuODM1OTgsMC4xMjk5MyAtNC43NjA3MzksMC4xNjI5MyAtMi44Mjk0OTIsMC4xMDA5NyAtNC44Njg4NzUsMC4xNjUzOSAtNS4xNzA3ODYsMC4xNjMzMyAtMC4xOTA5NzEsLTAuMDAxIC0wLjQwODQwMywtMC4wMjI5IC0wLjQ5MzAxLC0wLjA0OSB6IgogICAgICAgaWQ9InBhdGg4NiIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMTEuMDMwNzQxLDI4OS44MjkwOSB2IC0wLjgxODUyIGggMTQuMzgyNDQyIDE0LjM4MjQ0IHYgMC44MTg1MiAwLjgxODUxIEggMjUuNDEzMTgzIDExLjAzMDc0MSBaIgogICAgICAgaWQ9InBhdGg4OCIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgPC9nPgo8L3N2Zz4K'); } -body.base .is2d piece.queen.black { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMTQ0cHQiCiAgIGhlaWdodD0iMTQ0cHQiCiAgIHZpZXdCb3g9IjAgMCA1MC44MDAwMDEgNTAuOCIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnOCIKICAgc29kaXBvZGk6ZG9jbmFtZT0iYnEuc3ZnIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkyLjMgKDI0MDU1NDYsIDIwMTgtMDMtMTEpIj4KICA8ZGVmcwogICAgIGlkPSJkZWZzMiIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9ImJhc2UiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEuMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6em9vbT0iNy45MTk1OTU5IgogICAgIGlua3NjYXBlOmN4PSI4My41MzQ4NiIKICAgICBpbmtzY2FwZTpjeT0iMTExLjU2NjU4IgogICAgIGlua3NjYXBlOmRvY3VtZW50LXVuaXRzPSJtbSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJsYXllcjEiCiAgICAgc2hvd2dyaWQ9ImZhbHNlIgogICAgIHVuaXRzPSJwdCIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjM4NDAiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iMjAzNSIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iLTEzIgogICAgIGlua3NjYXBlOndpbmRvdy15PSItMTMiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIgLz4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGE1Ij4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICAgIDxkYzp0aXRsZSAvPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZwogICAgIGlua3NjYXBlOmxhYmVsPSJMYXllciAxIgogICAgIGlua3NjYXBlOmdyb3VwbW9kZT0ibGF5ZXIiCiAgICAgaWQ9ImxheWVyMSIKICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLC0yNDYuMikiPgogICAgPGcKICAgICAgIGFyaWEtbGFiZWw9InciCiAgICAgICBzdHlsZT0iZm9udC1zdHlsZTpub3JtYWw7Zm9udC12YXJpYW50Om5vcm1hbDtmb250LXdlaWdodDpub3JtYWw7Zm9udC1zdHJldGNoOm5vcm1hbDtmb250LXNpemU6NTAuNzk5OTk5MjRweDtsaW5lLWhlaWdodDoxLjI1O2ZvbnQtZmFtaWx5OidDaGVzcyBMZWlwemlnJzstaW5rc2NhcGUtZm9udC1zcGVjaWZpY2F0aW9uOidDaGVzcyBMZWlwemlnJztsZXR0ZXItc3BhY2luZzowcHg7d29yZC1zcGFjaW5nOjBweDtmaWxsOiMwMDAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjAuMjY0NTgzMzIiCiAgICAgICBpZD0idGV4dDIwOSIKICAgICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0wLjA5Njg5MzgsMC4wMzgwNCkiPgogICAgICA8cGF0aAogICAgICAgICBkPSJtIDI2LjY4OTg0NCwyNTUuMzI4MTMgcSAwLjM3MjA3LDQuMDE4MzUgMC43NDQxNCw4LjAzNjcxIDAuMzk2ODc1LDMuOTkzNTYgMC43OTM3NSw3Ljk4NzExIDAuMDI0OCwwLjU3MDUxIDAuNTcwNTA4LDAuNTcwNTEgMC4zOTY4NzUsLTAuMDI0OCAwLjU0NTcwMywtMC4zNDcyNiAyLjE1ODAwOCwtNS4yMDg5OSAzLjE3NSwtOC4wNjE1MyAxLjA0MTc5NywtMi44NzczNCAxLjI2NTAzOSwtMy41NDcwNyAtMS4xNDEwMTUsLTEuMDkxNCAtMS4xNDEwMTUsLTIuNDU1NjYgMCwtMS4xOTA2MyAwLjg0MzM1OSwtMi4wMzM5OSAwLjg2ODE2NCwtMC44NjgxNiAyLjA4MzU5NCwtMC44NjgxNiAxLjE5MDYyNSwwIDIuMDMzOTg0LDAuODY4MTYgMC44NjgxNjQsMC44NDMzNiAwLjg2ODE2NCwyLjAzMzk5IDAsMi4xNTgwMSAtMi4yMzI0MjIsMi45MjY5NSBsIC0xLjgxMDc0MiwxMC44MTQ4NCBxIC0wLjEyNDAyMywwLjc0NDE1IDAuNTIwODk5LDAuNzQ0MTUgMC41MjA4OTgsMCAwLjc5Mzc1LC0wLjI3Mjg2IDIuOTc2NTYyLC0yLjk3NjU2IDQuMjY2NDA2LC00LjYxMzY3IDEuMzE0NjQ4LC0xLjYzNzExIDEuODM1NTQ3LC0yLjI4MjAzIC0wLjU0NTcwNCwtMC43MTkzNCAtMC41NDU3MDQsLTEuNzM2MzMgMCwtMi45MDIxNSAyLjkwMjE0OSwtMi45MDIxNSAxLjE5MDYyNSwwIDIuMDMzOTg0LDAuODY4MTcgMC44NjgxNjQsMC44NDMzNiAwLjg2ODE2NCwyLjAzMzk4IDAsMS4yMTU0MyAtMC44NjgxNjQsMi4wNTg3OSAtMC44NDMzNTksMC44NDMzNiAtMi4wMzM5ODQsMC44NDMzNiAtMC4zNzIwNywwIC0wLjY2OTcyNywtMC4wNzQ0IC0xLjk4NDM3NSw0LjI5MTIxIC0zLjE3NSw4Ljc4MDg2IC0xLjAxNjk5MiwzLjY0NjI5IC0xLjI2NTAzOSw2LjkyMDUgMC4xNDg4MjgsMC42OTQ1NCAwLjE3MzYzMywwLjcxOTM0IC0wLjA3NDQxLC0wLjI5NzY2IDAuMDk5MjIsMC41NzA1MSAwLjA5OTIyLDAuMzk2ODcgMC4wOTkyMiwwLjc2ODk0IC0wLjE0ODgyOSwwLjM5Njg4IC0wLjYyMDExOCwwLjg5Mjk3IC0wLjQyMTY3OSwwLjQ3MTI5IC0wLjYyMDExNywxLjg2MDM1IDAuOTE3Nzc0LDEuMjg5ODUgMC45MTc3NzQsMi4wODM2IDAsMi4wODM1OSAtNC4wMTgzNiwzLjU3MTg3IC00LjAxODM1OSwxLjQ4ODI4IC05LjY0OTAyMywxLjQ4ODI4IC01LjY1NTQ2OSwwIC05LjY3MzgyOCwtMS40ODgyOCAtMy45OTM1NTUsLTEuNDg4MjggLTMuOTkzNTU1LC0zLjU3MTg3IDAsLTAuODE4NTYgMC45NjczODMsLTIuMTMzMjEgLTAuMjk3NjU2LC0xLjQxMzg2IC0wLjY0NDkyMiwtMS44MTA3NCAtMC40OTYwOTMsLTAuNDk2MDkgLTAuNjQ0OTIxLC0wLjg5Mjk3IDAsLTAuMzIyNDYgMC4wNzQ0MSwtMC43NDQxNCAwLjA0OTYxLC0wLjE5ODQ0IDAuMDc0NDEsLTAuMzQ3MjYgMC4wMjQ4LC0wLjE3MzY0IDAuMDQ5NjEsLTAuMjQ4MDUgMC4wOTkyMiwtMC4yNzI4NSAwLjE5ODQzOCwtMC43Njg5NSAtMC4yNDgwNDcsLTMuMTI1MzkgLTEuMjE1NDMsLTYuODcwODkgLTEuMjg5ODQzOSwtNC43MTI4OSAtMy4xOTk4MDQ4LC04LjgzMDQ3IC0wLjQyMTY3OTcsMC4xMjQwMiAtMC44NjgxNjQsMC4xMjQwMiAtMi45MDIxNDg0LDAgLTIuOTAyMTQ4NCwtMi45MDIxNSAwLC0yLjkwMjE1IDIuOTAyMTQ4NCwtMi45MDIxNSAyLjkwMjE0ODMsMCAyLjkwMjE0ODMsMi45MDIxNSAwLDAuODkyOTcgLTAuNDQ2NDg0MywxLjYxMjMxIDEuNDYzNDc2OCwxLjg2MDM1IDIuOTI2OTUyOCwzLjQ3MjY1IDEuNDg4MjgxLDEuNTg3NSAzLjI3NDIxOSwzLjQ5NzQ2IDAuMjIzMjQyLDAuMzIyNDcgMC42NDQ5MjIsMC4zMjI0NyAwLjcxOTMzNiwwIDAuNjQ0OTIyLC0wLjc0NDE1IC0wLjA0OTYxLC0wLjIyMzI0IC0wLjYyMDExNywtMy41NDcwNyAtMC41NzA1MDgsLTMuMzIzODIgLTEuMjQwMjM1LC03LjI0Mjk2IC0yLjM1NjQ0NSwtMC42NDQ5MyAtMi4zNTY0NDUsLTIuOTUxNzYgMCwtMS4xOTA2MyAwLjg0MzM1OSwtMi4wMzM5OSAwLjg2ODE2NCwtMC44NjgxNiAyLjA1ODc4OSwtMC44NjgxNiAyLjkwMjE0OSwwIDIuOTAyMTQ5LDIuOTAyMTUgMCwxLjI4OTg0IC0wLjk5MjE4OCwyLjM1NjQ0IDAuMTI0MDI0LDAuNTIwOSAwLjYyMDExNywyLjA4MzYgMC40OTYwOTQsMS41Mzc4OSAxLjUzNzg5MSw0LjA2Nzk3IDAuNTcwNTA4LDEuMzg5MDYgMS4xNDEwMTYsMi44MDI5MyAwLjU5NTMxMiwxLjM4OTA2IDEuMTkwNjI1LDIuNzUzMzIgMC4xNDg4MjgsMC4zMjI0NiAwLjUyMDg5OCwwLjMyMjQ2IDAuNTIwODk4LC0wLjAyNDggMC41OTUzMTIsLTAuNTQ1NzEgMC4wNDk2MSwtMC4yOTc2NSAxLjUxMzA4NiwtMTUuOTk5MDIgLTEuNzYxMTMyLC0wLjk0MjU4IC0xLjc2MTEzMiwtMi44MDI5MyAwLC0xLjE5MDYyIDAuODQzMzU5LC0yLjA1ODc5IDAuODQzMzU5LC0wLjg2ODE2IDIuMDU4Nzg5LC0wLjg2ODE2IDEuMTkwNjI1LDAgMi4wMzM5ODQsMC44NjgxNiAwLjg2ODE2NCwwLjg2ODE3IDAuODY4MTY0LDIuMDU4NzkgMCwxLjY4NjcyIC0xLjYxMjMwNCwyLjc3ODEzIHogbSAtNi42OTcyNjYsMjUuNTk4NDMgcSAtMS4zNjQyNTgsMCAtMS4zNjQyNTgsMS40Mzg2NyAwLDEuNDYzNDggMS4zNjQyNTgsMS40NjM0OCAxLjM4OTA2MywwIDEuMzg5MDYzLC0xLjQ2MzQ4IDAsLTEuNDM4NjcgLTEuMzg5MDYzLC0xLjQzODY3IHogbSAtNy41NjU0MjksLTUuMjA4OTggcSAwLjI5NzY1NiwxLjAxNjk5IDAuNTIwODk4LDEuODM1NTUgMC4yNDgwNDcsMC43OTM3NSAwLjQyMTY4LDEuNzM2MzIgMC4xNDg4MjgsMC4wNzQ0IDAuNDQ2NDg0LDAuMDc0NCAyLjA4MzU5NCwtMC42MjAxMiA1LjEwOTc2NiwtMS4wOTE0MSAzLjA1MDk3NiwtMC40NzEyOSA2LjU0ODQzNywtMC40NzEyOSAzLjU3MTg3NSwwIDYuNjQ3NjU2LDAuNDk2MSAzLjA3NTc4MSwwLjQ3MTI4IDUuMTU5Mzc1LDEuMDkxNCAwLjEyNDAyNCwwIDAuMzcyMDcsLTAuMDk5MiAwLjE0ODgyOSwtMC44OTI5NyAwLjM5Njg3NSwtMS42NjE5MSAwLjI0ODA0NywtMC43OTM3NSAwLjU0NTcwNCwtMS44MzU1NSAtMi44Mjc3MzUsLTAuNjQ0OTIgLTYuMTc2MzY4LC0xLjI2NTA0IC0zLjM0ODYzMiwtMC42MjAxMSAtNi45NDUzMTIsLTAuNjIwMTEgLTMuNTk2NjgsMCAtNi44NzA4OTgsMC42MjAxMSAtMy4yNzQyMTksMC41OTUzMiAtNi4xNzYzNjcsMS4xOTA2MyB6IG0gMjQuOTAzOTA2LDcuODEzNDcgLTEuNzg1OTM4LC0xLjcxMTUyIC0yLjI4MjAzMSwwLjkxNzc3IDEuODEwNzQyLDEuNzExNTMgeiBtIC04LjcwNjQ0NiwtMS43NjExMyAtMy4xOTk4MDQsLTEuNjYxOTEgLTMuMDc1NzgyLDEuNjYxOTEgMy4xOTk4MDUsMS42ODY3MiB6IG0gLTEwLjcxNTYyNSwwLjk5MjE5IC0yLjUwNTI3MywtMC44NDMzNiAtMS45ODQzNzUsMS41NjI3IDIuNDgwNDY5LDAuODQzMzUgeiBtIDEzLjAyMjQ2MSwtMS44MzU1NSBxIC0xLjM4OTA2MiwwIC0xLjM4OTA2MiwxLjQzODY3IDAsMS40NjM0OCAxLjM4OTA2MiwxLjQ2MzQ4IDEuMzg5MDYzLDAgMS4zODkwNjMsLTEuNDYzNDggMCwtMS40Mzg2NyAtMS4zODkwNjMsLTEuNDM4NjcgeiBtIDUuNDMyMjI3LDguNjA3MjMgcSAtMC4xNDg4MjgsLTAuNzQ0MTQgLTAuMzQ3MjY2LC0xLjI0MDI0IC0wLjI5NzY1NiwtMC42NDQ5MiAtMC41OTUzMTIsLTAuODQzMzUgLTAuMjk3NjU3LC0wLjIyMzI1IC0wLjU0NTcwNCwtMC41NzA1MSAtMS4zMTQ2NDgsLTAuODQzMzYgLTMuNjk1ODk4LC0xLjQzODY3IC0yLjM1NjQ0NSwtMC42MjAxMiAtNS43MDUwNzgsLTAuNTQ1NzEgLTMuNDIzMDQ3LC0wLjA3NDQgLTUuNzU0Njg3LDAuNTQ1NzEgLTIuMzMxNjQxLDAuNTk1MzEgLTMuNjIxNDg1LDEuNDM4NjcgLTAuMzIyNDYxLDAuMjk3NjUgLTAuNjIwMTE3LDAuNTQ1NyAtMC4yOTc2NTYsMC4yMjMyNCAtMC41MjA4OTgsMC44NDMzNiAtMC4yNDgwNDcsMC43NDQxNCAtMC4zNDcyNjYsMS4yNjUwNCAtMC4wNDk2MSwwLjg0MzM2IDAuNzQ0MTQxLDAuODQzMzYgMC43NDQxNCwwIDAuNzQ0MTQsLTAuODE4NTYgMC4yMjMyNDMsLTIuNTc5NjggOS4zMjY1NjMsLTIuNTc5NjggOS4yMDI1MzksMCA5LjQ1MDU4NSwyLjU3OTY4IC0wLjA0OTYxLDAuODE4NTYgMC43NDQxNDEsMC44MTg1NiAwLjc0NDE0MSwwIDAuNzQ0MTQxLC0wLjg0MzM2IHoiCiAgICAgICAgIHN0eWxlPSJzdHJva2Utd2lkdGg6MC4yNjQ1ODMzMiIKICAgICAgICAgaWQ9InBhdGgyMTEiCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8L2c+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMTQuOTEwMDI2LDI5MC4zMzgwNyBjIC0wLjQyMzQwNiwtMC4xODM2NSAtMC40NzA0MjMsLTAuNTY5MTEgLTAuMTg3MTEyLC0xLjUzNDAyIDAuMTYzNDgxLC0wLjU1Njc4IDAuMzE1ODE5LC0wLjkxNjU2IDAuNDc2MTExLC0xLjEyNDQyIDAuMTMxNzU4LC0wLjE3MDg2IDAuODI0MDQ5LC0wLjc1ODM3IDEuMDYzOTk0LC0wLjkwMjk1IDEuMTEyMjk2LC0wLjY3MDIyIDMuMjMwMzA3LC0xLjM1MzUxIDQuOTkzNjY0LC0xLjYxMDk5IDEuMTM2MzQ0LC0wLjE2NTkzIDIuMTI5NDQzLC0wLjIxOTI1IDQuMDk1MDIzLC0wLjIxOTg1IDIuNjk4MjE5LC04ZS00IDQuMDEyMjg1LDAuMTIzNzggNS42NjAzMTQsMC41MzY4IDEuMzI0NTg5LDAuMzMxOTUgMi4xNDQxODYsMC42MTY1MSAzLjAzMDUwNiwxLjA1MjE3IGwgMC41NzQ5NjYsMC4yODI2MiAwLjUxMjE0MywwLjUwODg5IGMgMC40NjE2NjEsMC40NTg3MiAwLjUyNzYzLDAuNTM5IDAuNjY5MjY0LDAuODE0NCAwLjE1MTQxMywwLjI5NDQyIDAuMzQxNjE5LDAuODc2OSAwLjQyNTAxMSwxLjMwMTU2IDAuMDc2MjQsMC4zODgyMyAtMC4wNTQ4MSwwLjczMTM5IC0wLjMzNDQ4OSwwLjg3NTg3IC0wLjEyOTU1OSwwLjA2NjkgLTAuMTg3Mzk0LDAuMDc1OCAtMC40MjMxNDgsMC4wNjQ2IC0wLjQ3MTQ1MywtMC4wMjIzIC0wLjYyNzc5MywtMC4xODgyNyAtMC42Nzk0NSwtMC43MjExMyAtMC4wMTU0NSwtMC4xNTkyOCAtMC4wNTA3LC0wLjM1MjQ0IC0wLjA3ODM1LC0wLjQyOTI0IC0wLjM2NDE0NCwtMS4wMTEzMSAtMi4wMDUzMDQsLTEuNjk3NSAtNC44MTU2NDIsLTIuMDEzNDcgLTEuNDM4NzI3LC0wLjE2MTc2IC0yLjAwMDU1NywtMC4xODQ1OCAtNC41NDM1ODMsLTAuMTg0NTUgLTIuNTM2MDgyLDNlLTUgLTMuMTQzNTE1LDAuMDI0NyAtNC41MzgyMTgsMC4xODQwOSAtMi4zNzQ0MzEsMC4yNzE0MSAtMy45MTI2MTEsMC44MTU2IC00LjUwMzg1NiwxLjU5MzQyIC0wLjE5MzY5MiwwLjI1NDgyIC0wLjI4NTg3NCwwLjQ5NzEgLTAuMzI3MDcsMC44NTk2NSAtMC4wMTc2MiwwLjE1NTA4IC0wLjA1NCwwLjMyNDAyIC0wLjA4MDg1LDAuMzc1NDIgLTAuMDcyMjgsMC4xMzg0IC0wLjIyODMwMiwwLjI3NDE2IC0wLjM1Nzc1LDAuMzExMjkgLTAuMTY3NzMsMC4wNDgxIC0wLjQ5ODQ0MywwLjAzNzYgLTAuNjMxNDc2LC0wLjAyMDIgeiIKICAgICAgIGlkPSJwYXRoMjE0IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAyMy44ODY1NSwyODIuNjUwNTMgYyAtMC44NTg0MzQsLTAuNDUxOTkgLTEuNTYwNzg5LC0wLjgzMTMyIC0xLjU2MDc4OSwtMC44NDI5NiAwLC0wLjAxMTYgMC42NzU3MjEsLTAuMzg1OSAxLjUwMTYwMiwtMC44MzE3MSBsIDEuNTAxNjAxLC0wLjgxMDU2IDEuNTMwMjM4LDAuNzkxNjUgYyAwLjg0MTYyOSwwLjQzNTQxIDEuNTQ4NCwwLjgwODA4IDEuNTcwNjAxLDAuODI4MTcgMC4wMzcyMSwwLjAzMzcgLTAuODM1NTYyLDAuNTMwNTcgLTIuNjI4NzE3LDEuNDk2NjMgbCAtMC4zNTM3NDgsMC4xOTA1OCB6IgogICAgICAgaWQ9InBhdGgyMTYiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDE5LjM2MjQyNywyODMuNzc1NDcgYyAtMC41MzgwNDQsLTAuMTc1NjggLTAuODEyNjYyLC0wLjY0MTM0IC0wLjgxMTM1NCwtMS4zNzU3NyA4Ljk5ZS00LC0wLjUwMDY4IDAuMTIyNDE3LC0wLjg0NDg2IDAuMzg5MzE1LC0xLjEwMjYgMC4yNjA4OTEsLTAuMjUxOTQgMC43NDkzMjIsLTAuMzY5OCAxLjIzMzgzOSwtMC4yOTc3NCAwLjc0NDMzMywwLjExMDcgMS4wODI0NTYsMC41NTAxOCAxLjA4MjQ1NiwxLjQwNjkzIDAsMC4zNzU1MyAtMC4wNDY4MiwwLjU5OTc2IC0wLjE3NjY4MywwLjg0NjExIC0wLjIxMTg4NiwwLjQwMTk1IC0wLjUxOTIxNCwwLjU1OTg4IC0xLjEyNjI1NiwwLjU3ODc1IC0wLjMxNzcxMSwwLjAxIC0wLjQyMDA0MywyLjRlLTQgLTAuNTkxMzE3LC0wLjA1NTcgeiIKICAgICAgIGlkPSJwYXRoMjE4IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAzMC4zNTE1MzYsMjgzLjc5MTA3IGMgLTAuNjA5NTg3LC0wLjE2NDEyIC0wLjg3NjgzOCwtMC41ODgwOSAtMC44NzU5MTksLTEuMzg5NiA1LjI5ZS00LC0wLjUxMjI1IDAuMTA2NTE4LC0wLjgzNDg2IDAuMzU2MDg0LC0xLjA4NDQyIDAuNDQyNjA4LC0wLjQ0MjYxIDEuNDk1NDU5LC0wLjQ1MDczIDEuOTkxMzE3LC0wLjAxNTQgMC4yODk4NTEsMC4yNTQ0OSAwLjQ0MDc1MSwwLjgyOTAyIDAuMzY1NDg4LDEuMzkxNTIgLTAuMDgyLDAuNjEyODQgLTAuMzY1MzYzLDAuOTYzNDMgLTAuODkyNTExLDEuMTA0MjQgLTAuMjE1ODA1LDAuMDU3NyAtMC43MTkyNywwLjA1NDMgLTAuOTQ0NDU5LC0wLjAwNiB6IgogICAgICAgaWQ9InBhdGgyMjAiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDM0LjA4NDQ3MywyODMuNjIwMTYgYyAtMC40NzgzNTYsLTAuNDUzMjQgLTAuODU3OTU0LC0wLjgzNDI2IC0wLjg0MzU1MywtMC44NDY3MSAwLjAyNTk4LC0wLjAyMjUgMi4wOTUzODQsLTAuODU3NTkgMi4xNjk3MDMsLTAuODc1NiAwLjA2MzksLTAuMDE1NSAxLjc5Mjk1NCwxLjY1MjI4IDEuNzQyMjM2LDEuNjgwNDkgLTAuMTAzNjQ1LDAuMDU3NiAtMi4xMTQ5NDQsMC44NjU4OCAtMi4xNTQ3MjIsMC44NjU4OCAtMC4wMjQxNiwwIC0wLjQzNTMwOCwtMC4zNzA4MyAtMC45MTM2NjQsLTAuODI0MDYgeiIKICAgICAgIGlkPSJwYXRoMjIyIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAxNC42MTE4MywyODMuOTQ0OTcgYyAtMC42MzIwMTgsLTAuMjE1OTEgLTEuMTY4Mzg1LC0wLjQwNjE0IC0xLjE5MTkyOCwtMC40MjI3MyAtMC4wMzA1OCwtMC4wMjE1IDAuMjMzMTE2LC0wLjI0NjUxIDAuOTIzMTMyLC0wLjc4NzU0IGwgMC45NjU5MzUsLTAuNzU3MzcgMS4yMTk5ODYsMC40MDYzMyBjIDAuNjcwOTkyLDAuMjIzNDcgMS4yMTYxNTQsMC40MTc4MSAxLjIxMTQ3MSwwLjQzMTg2IC0wLjAxMDg4LDAuMDMyNiAtMS45MzQ4NjgsMS41Mjk1NiAtMS45NjAzOTMsMS41MjUyNSAtMC4wMTA0OSwtMC4wMDIgLTAuNTM2MTg1LC0wLjE3OTg4IC0xLjE2ODIwMywtMC4zOTU4IHoiCiAgICAgICBpZD0icGF0aDIyNCIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMTMuNTcyNjg0LDI3OS4zODExNSBjIC0wLjAyNzU2LC0wLjAwNiAtMC4xMDQxMjUsLTAuMDE5NCAtMC4xNzAxMzksLTAuMDMwMSAtMC4xMTk4NjUsLTAuMDE5NCAtMC4xMjAwODQsLTAuMDE5OCAtMC4xNjIzODMsLTAuMjYxMTQgLTAuMDY0NjgsLTAuMzY5MDYgLTAuMjcyNDIsLTEuMTcwODEgLTAuNTk2NTEyLC0yLjMwMjE2IGwgLTAuMjkzNTcsLTEuMDI0OCAxLjcwNTQzNywtMC4zMzUyMyBjIDUuNDU3Njc4LC0xLjA3MjgxIDYuNjcyOTMzLC0xLjI1OTk2IDkuMTcyMjc5LC0xLjQxMjU1IDAuODcyNDE0LC0wLjA1MzMgMy40OTcxNDMsLTAuMDUyOSA0LjMyNjQyNCw1LjNlLTQgMi4zNjI0MzYsMC4xNTI0MSAzLjQ3NDUxNywwLjMwNjMxIDYuNTY0ODA4LDAuOTA4NTEgMS40NjI3MzgsMC4yODUwNCA0LjMwMjA4MiwwLjg4NzMzIDQuMzM5NDM2LDAuOTIwNSAwLjAxNzA0LDAuMDE1MSAtMC4wNDkyMywwLjI1MTI4IC0wLjM2NDcyNSwxLjI5OTYgLTAuMjk1NzcsMC45ODI4IC0wLjM3NTEzNywxLjI4MDgyIC0wLjQ4MDQ0OSwxLjgwNDA3IGwgLTAuMDczOTcsMC4zNjc1IC0wLjEzODYyLDAuMDQ4NiBjIC0wLjE2MDk5MSwwLjA1NjUgLTAuMTAzMjI3LDAuMDY3IC0xLjI0Mzc0NiwtMC4yMjYwOSAtMS45ODk0NzYsLTAuNTExMjEgLTQuNzMyOTc1LC0wLjk2ODg3IC02LjkzMjMwMiwtMS4xNTY0MyAtMS4zMTI4NSwtMC4xMTE5NiAtMi4wMDI0NjUsLTAuMTM2MDkgLTMuODc1NDEsLTAuMTM1NTggLTIuMTkyODM1LDUuM2UtNCAtMy4zMjk4MzEsMC4wNTc5IC01LjAyODAwOCwwLjI1MzMgLTIuMDg4MTEzLDAuMjQwMzEgLTQuNzMzMjY5LDAuNzQ0MzcgLTYuMzAyNTIzLDEuMjAxMDIgLTAuMTg2NDksMC4wNTQzIC0wLjM1MTg2MywwLjA5NjkgLTAuMzY3NDk2LDAuMDk0OCAtMC4wMTU2MywtMC4wMDIgLTAuMDUwOTcsLTAuMDA5IC0wLjA3ODU0LC0wLjAxNDUgeiIKICAgICAgIGlkPSJwYXRoMjI2IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICA8L2c+Cjwvc3ZnPgo='); } -body.base .is2d piece.king.black { background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhLS0gQ3JlYXRlZCB3aXRoIElua3NjYXBlIChodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy8pIC0tPgoKPHN2ZwogICB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iCiAgIHhtbG5zOmNjPSJodHRwOi8vY3JlYXRpdmVjb21tb25zLm9yZy9ucyMiCiAgIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyIKICAgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzb2RpcG9kaT0iaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGQiCiAgIHhtbG5zOmlua3NjYXBlPSJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlIgogICB3aWR0aD0iMTQ0cHQiCiAgIGhlaWdodD0iMTQ0cHQiCiAgIHZpZXdCb3g9IjAgMCA1MC44MDAwMDEgNTAuOCIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnOCIKICAgc29kaXBvZGk6ZG9jbmFtZT0iYmsuc3ZnIgogICBpbmtzY2FwZTp2ZXJzaW9uPSIwLjkyLjMgKDI0MDU1NDYsIDIwMTgtMDMtMTEpIj4KICA8ZGVmcwogICAgIGlkPSJkZWZzMiIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9ImJhc2UiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjNjY2NjY2IgogICAgIGJvcmRlcm9wYWNpdHk9IjEuMCIKICAgICBpbmtzY2FwZTpwYWdlb3BhY2l0eT0iMC4wIgogICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6em9vbT0iNy45MTk1OTU5IgogICAgIGlua3NjYXBlOmN4PSI4My41MzQ4NiIKICAgICBpbmtzY2FwZTpjeT0iOTkuNDQ0NzgzIgogICAgIGlua3NjYXBlOmRvY3VtZW50LXVuaXRzPSJtbSIKICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPSJsYXllcjEiCiAgICAgc2hvd2dyaWQ9ImZhbHNlIgogICAgIHVuaXRzPSJwdCIKICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9IjM4NDAiCiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD0iMjAzNSIKICAgICBpbmtzY2FwZTp3aW5kb3cteD0iLTEzIgogICAgIGlua3NjYXBlOndpbmRvdy15PSItMTMiCiAgICAgaW5rc2NhcGU6d2luZG93LW1heGltaXplZD0iMSIgLz4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGE1Ij4KICAgIDxyZGY6UkRGPgogICAgICA8Y2M6V29yawogICAgICAgICByZGY6YWJvdXQ9IiI+CiAgICAgICAgPGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+CiAgICAgICAgPGRjOnR5cGUKICAgICAgICAgICByZGY6cmVzb3VyY2U9Imh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlIiAvPgogICAgICAgIDxkYzp0aXRsZSAvPgogICAgICA8L2NjOldvcms+CiAgICA8L3JkZjpSREY+CiAgPC9tZXRhZGF0YT4KICA8ZwogICAgIGlua3NjYXBlOmxhYmVsPSJMYXllciAxIgogICAgIGlua3NjYXBlOmdyb3VwbW9kZT0ibGF5ZXIiCiAgICAgaWQ9ImxheWVyMSIKICAgICB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLC0yNDYuMikiPgogICAgPGcKICAgICAgIGFyaWEtbGFiZWw9ImwiCiAgICAgICBzdHlsZT0iZm9udC1zdHlsZTpub3JtYWw7Zm9udC12YXJpYW50Om5vcm1hbDtmb250LXdlaWdodDpub3JtYWw7Zm9udC1zdHJldGNoOm5vcm1hbDtmb250LXNpemU6NTAuNzk5OTk5MjRweDtsaW5lLWhlaWdodDoxLjI1O2ZvbnQtZmFtaWx5OidDaGVzcyBMZWlwemlnJzstaW5rc2NhcGUtZm9udC1zcGVjaWZpY2F0aW9uOidDaGVzcyBMZWlwemlnJztsZXR0ZXItc3BhY2luZzowcHg7d29yZC1zcGFjaW5nOjBweDtmaWxsOiMwMDAwMDA7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7c3Ryb2tlLXdpZHRoOjAuMjY0NTgzMzIiCiAgICAgICBpZD0idGV4dDI3NSIKICAgICAgIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAuMDA4NDA3MSwxLjM4OTkxKSI+CiAgICAgIDxwYXRoCiAgICAgICAgIGQ9Im0gMzMuMDY0NjQ4LDI4MS40MTAyNCAyLjA4MzU5NCwxLjYxMjMxIDIuNjA0NDkyLC0wLjg5Mjk3IC0yLjA1ODc4OSwtMS42MTIzMSB6IG0gNi4xMjY3NTgsLTAuNDIxNjggcSAwLjE3MzYzMywwLjUyMDkgMC4xNzM2MzMsMC45OTIxOSAwLDEuNDYzNDggLTEuMDY2NjAyLDIuMjU3MjMgLTAuMDk5MjIsMC40MjE2OCAtMC4xNDg4MjgsMC44NDMzNiAwLjkxNzc3NCwxLjI4OTg0IDAuOTE3Nzc0LDIuMDgzNTkgMCwyLjA4MzU5IC00LjAxODM2LDMuNTcxODcgLTQuMDE4MzU5LDEuNDg4MjkgLTkuNjQ5MDIzLDEuNDg4MjkgLTUuNjU1NDY5LDAgLTkuNjczODI4LC0xLjQ4ODI5IC0zLjk5MzU1NSwtMS40ODgyOCAtMy45OTM1NTUsLTMuNTcxODcgMCwtMC44MTg1NiAwLjk2NzM4MywtMi4xMzMyIC0wLjA0OTYxLC0wLjI3Mjg2IC0wLjE0ODgyOCwtMC43Njg5NSAtMS4wOTE0MDYsLTAuNzkzNzUgLTEuMDkxNDA2LC0yLjI4MjAzIDAsLTAuNDcxMjkgMC4xNDg4MjgsLTAuOTY3MzggMC4yNDgwNDcsLTAuNjIwMTIgLTAuMDk5MjIsLTAuOTY3MzkgLTAuMzQ3MjY1LC0wLjM0NzI2IC0wLjc5Mzc1LC0wLjk2NzM4IC0wLjM5Njg3NSwtMS4yNDAyMyAtMC4zOTY4NzUsLTEuNzExNTIgMC4wMjQ4MSwtMC4yMjMyNCAwLjA3NDQxLC0wLjQ5NjEgMC4wNzQ0MSwtMC4yNzI4NSAwLjA3NDQxLC0wLjY0NDkyIC0xLjA5MTQwNTksLTEuMDkxNCAtMi4yODIwMzA5LC0yLjA1ODc5IC0xLjE2NTgyMDMsLTAuOTkyMTggLTEuODM1NTQ2OCwtMi4zODEyNSAtMC43OTM3NSwtMS42MzcxMSAtMS40NjM0NzY2LC0zLjI5OTAyIC0wLjY0NDkyMTgsLTEuNjg2NzIgLTAuNjQ0OTIxOCwtMy4yOTkwMiAwLC0zLjA1MDk4IDEuNjEyMzA0NiwtNS4xNTkzOCAxLjYxMjMwNDcsLTIuMTA4NCA0LjM2NTYyNDUsLTMuMjk5MDIgMy42NzEwOTQsLTAuMjQ4MDUgMy4xMDA1ODYsLTAuMjQ4MDUgNC4zMTYwMTYsMCA3LjgzODI4MiwzLjE5OTgxIHYgLTguNzA2NDUgaCA4LjQ1ODM5OCB2IDguNzMxMjUgcSAzLjUyMjI2NSwtMy4yMjQ2MSA3Ljg4Nzg5LC0zLjIyNDYxIC0wLjYyMDExNywwIDMuMTAwNTg2LDAuMjQ4MDUgMi43MDM3MTEsMS4xOTA2MiA0LjMxNjAxNiwzLjI5OTAyIDEuNjM3MTA5LDIuMTA4NCAxLjYzNzEwOSw1LjE1OTM4IDAsMS42MTIzIC0wLjY2OTcyNiwzLjI3NDIyIC0wLjY0NDkyMiwxLjY2MTkxIC0xLjQxMzg2OCwzLjI5OTAyIC0wLjY2OTcyNiwxLjQxMzg3IC0xLjg2MDM1MSwyLjQ1NTY2IC0xLjE5MDYyNSwxLjA0MTggLTIuMjU3MjI3LDIuMDgzNiAtMC4wMjQ4LDAuMjk3NjUgMC4wMjQ4MSwwLjU3MDUgMC4wNzQ0MSwwLjI3Mjg2IDAuMDk5MjIsMC40OTYxIDAuMDI0OCwwLjM0NzI2IC0wLjM5Njg3NSwxLjcxMTUyIC0wLjQ0NjQ4NSwwLjYyMDEyIC0wLjc5Mzc1LDAuOTY3MzggLTAuMzIyNDYxLDAuMzQ3MjcgLTAuMDk5MjIsMC45NDI1OCB6IG0gLTMuNDIzMDQ3LDcuMTE4OTUgcSAtMC4wOTkyMiwtMC41NDU3MSAtMC4zNDcyNjUsLTEuMTkwNjMgLTAuMjcyODUyLC0wLjU5NTMxIC0wLjU3MDUwOCwtMC43OTM3NSAtMC4yNzI4NTIsLTAuMjIzMjQgLTAuNDk2MDk0LC0wLjU3MDUxIC0yLjUwNTI3MywtMS41ODc1IC04LjkwNDg4MywtMS40MTM4NiAtNi40OTg4MjgsLTAuMTczNjQgLTguOTc5Mjk2LDEuNDEzODYgLTAuMjk3NjU3LDAuMjk3NjYgLTAuNTk1MzEzLDAuNTIwOSAtMC4yNzI4NTEsMC4yMjMyNSAtMC40NzEyODksMC44MTg1NiAtMC4yNzI4NTEsMC42MjAxMSAtMC4zNDcyNjYsMS4yMTU0MyAtMC4wNDk2MSwwLjc5Mzc1IDAuNjk0NTMyLDAuNzkzNzUgMC43MTkzMzYsMCAwLjY5NDUzMSwtMC43Njg5NSAwLjIyMzI0MiwtMi40ODA0NyA4LjkwNDg4MywtMi40ODA0NyA4Ljc1NjA1NCwwIDkuMDA0MTAxLDIuNDgwNDcgLTAuMDQ5NjEsMC43Njg5NSAwLjY5NDUzMSwwLjc2ODk1IDAuNzE5MzM2LDAgMC43MTkzMzYsLTAuNzkzNzUgeiBtIC03LjYzOTg0MywtMTQuNjM0NzcgcSAwLjMyMjQ2MSwwIDAuNjQ0OTIxLDAuMDQ5NiAwLjMyMjQ2MSwwLjAyNDggMC42MjAxMTgsMC4wMjQ4IC0wLjE5ODQzOCwtMi4yNTcyMyAwLjE5ODQzNywtMy42OTU5IDAuMTQ4ODI4LC0wLjU0NTcxIDAuNTQ1NzAzLC0wLjU5NTMxIDAuNTcwNTA4LC0wLjA5OTIgMC44MTg1NTUsMC42MjAxMSAwLjE5ODQzNywxLjE5MDYzIC0wLjM5Njg3NSwzLjc5NTEyIDAuOTkyMTg3LDAuMTczNjMgMS40NjM0NzYsMC4xNzM2MyAwLjE0ODgyOSwtMy44MTk5MiAxLjE2NTgyMSwtNi4wNzcxNSAwLjI5NzY1NiwtMC41OTUzMSAwLjk5MjE4NywtMC41OTUzMSAwLjg0MzM2LDAgMC43OTM3NSwwLjgxODU2IDAuMDQ5NjEsMC4wNDk2IDAuMDQ5NjEsMC43Njg5NCAwLDEuMjY1MDQgLTEuNDEzODY4LDUuMzgyNjIgMC43MTkzMzYsMC4yNDgwNSAxLjI0MDIzNSwwLjE5ODQ0IDAuMjcyODUxLC0wLjcxOTM0IDAuNTQ1NzAzLC0xLjUxMzA5IDAuMjk3NjU2LC0wLjgxODU1IDAuNzQ0MTQxLC0xLjczNjMzIDAuMTk4NDM3LC0wLjQ3MTI5IDAuNTcwNTA3LC0wLjQ3MTI5IDAuNDIxNjgsMCAwLjUyMDg5OSwwLjgxODU2IDAuMDI0OCwwLjY5NDUzIC0xLjQ2MzQ3NywzLjE3NSAwLjYyMDExNywwLjI5NzY1IDEuMjQwMjM1LDAuMzIyNDYgMC4yOTc2NTYsLTAuNTk1MzEgMC41NDU3MDMsLTEuMTE2MjEgMC4yNzI4NTEsLTAuNTIwOSAwLjU3MDUwNywtMS4zMzk0NiAwLjU0NTcwNCwtMS41ODc1IDAuNDQ2NDg1LC0zLjAyNjE3IC0wLjE5ODQzOCwtMC44NjgxNiAtMC45NjczODMsLTAuODY4MTYgLTAuMzcyMDcsMCAtMC45MTc3NzMsMC41OTUzMSAwLjEyNDAyMywtMC43OTM3NSAwLjEyNDAyMywtMC45OTIxOSAwLC0xLjA0MTc5IC0wLjUyMDg5OCwtMS45NTk1NyAtMC40OTYwOTQsLTAuOTQyNTcgLTEuNzExNTI0LC0xLjI4OTg0IC0wLjg5Mjk2OCwwLjA0OTYgLTEuODYwMzUxLDEuMDkxNDEgLTAuOTY3MzgzLDEuMDQxNzkgLTEuMjg5ODQ0LDIuNDU1NjYgLTAuMjcyODUyLC0wLjg2ODE2IC0wLjcxOTMzNiwtMC45OTIxOSAtMC40NDY0ODQsLTAuMTI0MDIgLTAuNTk1MzEyLC0wLjEyNDAyIC0wLjI5NzY1NywwIC0wLjU3MDUwOCwwLjE3MzYzIC0wLjk5MjE4OCwxLjE0MTAyIC0xLjIxNTQzLDMuNDcyNjYgLTAuMDc0NDEsMC41MjA5IC0wLjA5OTIyLDEuMDE2OTkgLTAuMDI0OCwwLjQ5NjA5IC0wLjA5OTIyLDEuNDM4NjcgeiBtIC01LjUzMTQ0NiwwLjAyNDggcSAtMC4wNzQ0MSwtMC45MTc3OCAtMC4wOTkyMiwtMS40MTM4NyAtMC4wMjQ4MSwtMC40OTYwOSAtMC4wNzQ0MSwtMS4wMTY5OSAtMC4yOTc2NTcsLTIuMzgxMjUgLTEuMjE1NDMsLTMuNDcyNjYgLTAuMjQ4MDQ3LC0wLjE3MzYzIC0wLjU5NTMxMywtMC4xNzM2MyAtMC4xNDg4MjgsMCAtMC42MjAxMTcsMC4xMjQwMiAtMC40NDY0ODQsMC4xMjQwMyAtMC42Njk3MjYsMC45NjczOCAtMC4zNDcyNjYsLTEuNDEzODYgLTEuMzE0NjQ5LC0yLjQ1NTY2IC0wLjk0MjU3OCwtMS4wNDE4IC0xLjgzNTU0NywtMS4wOTE0MSAtMS4yNDAyMzQsMC4zNzIwNyAtMS43MzYzMjgsMS4zMTQ2NSAtMC40OTYwOTMsMC45MTc3OCAtMC40OTYwOTMsMS45NTk1NyAwLDAuNDcxMjkgMC4xMjQwMjMsMC45OTIxOSAtMC41OTUzMTMsLTAuNjIwMTIgLTAuOTE3NzczLC0wLjYyMDEyIC0wLjc5Mzc1LDAgLTAuOTY3MzgzLDAuODkyOTcgLTAuMTI0MDI0LDEuNTM3ODkgMC40NDY0ODQsMy4wMDEzNyAwLjI3Mjg1MiwwLjgxODU1IDAuNTIwODk5LDEuMzY0MjYgMC4yNzI4NTEsMC41MjA5IDAuNTk1MzEyLDEuMTE2MjEgMC41OTUzMTMsLTAuMDI0OCAxLjI0MDIzNCwtMC4zMjI0NiAtMS41MTMwODYsLTIuNDU1NjcgLTEuNDYzNDc2LC0zLjE3NSAwLjAyNDgxLC0wLjgxODU2IDAuNDk2MDk0LC0wLjgxODU2IDAuMzcyMDcsMCAwLjU5NTMxMiwwLjQ3MTI5IDAuNDIxNjgsMC44OTI5NyAwLjY5NDUzMSwxLjcxMTUyIDAuMjk3NjU3LDAuODE4NTYgMC41OTUzMTMsMS41Mzc5IDAuNTk1MzEyLDAgMS4yNDAyMzQsLTAuMTk4NDQgLTEuNDM4NjcyLC00LjE5MTk5IC0xLjQzODY3MiwtNS40MDc0MiAwLC0wLjY2OTczIDAuMDQ5NjEsLTAuNzQ0MTQgMCwtMC44NDMzNiAwLjc5Mzc1LC0wLjg0MzM2IDAuNjk0NTMxLDAgMS4wMTY5OTIsMC42MjAxMSAwLjk5MjE4NywyLjI1NzIzIDEuMTY1ODIsNi4wNzcxNSAwLjQ5NjA5NCwtMC4wMjQ4IDEuNDM4NjcyLC0wLjE3MzYzIC0wLjU5NTMxMiwtMi42NTQxIC0wLjM3MjA3LC0zLjc5NTEyIDAuMjIzMjQyLC0wLjc0NDE0IDAuNzkzNzUsLTAuNjQ0OTIgMC40MjE2NzksMC4wOTkyIDAuNTQ1NzAzLDAuNTk1MzEgMC4zOTY4NzUsMS41NjI3IDAuMTk4NDM3LDMuNzIwNzEgMC4zOTY4NzUsLTAuMDQ5NiAxLjI2NTAzOSwtMC4wOTkyIHogTSAyNS40LDI1OS41ODIxMiBxIC0xLjIxNTQzLDAgLTIuMDgzNTk0LDAuODY4MTYgLTAuODY4MTY0LDAuODY4MTcgLTAuODY4MTY0LDIuMDgzNiAwLDEuMjQwMjMgMC44NjgxNjQsMi4xMDgzOSAwLjg2ODE2NCwwLjg0MzM2IDIuMDgzNTk0LDAuODQzMzYgMi45NTE3NTgsMCAyLjk1MTc1OCwtMi45NTE3NSAwLC0yLjk1MTc2IC0yLjk1MTc1OCwtMi45NTE3NiB6IG0gMC4yOTc2NTYsLTUuMzMzMDEgUSAyNS41NDg4MjgsMjU0LjE3NDcgMjUuNCwyNTQuMTc0NyBxIC0wLjI3Mjg1MiwwIC0wLjM5Njg3NSwwLjA5OTIgbCAtMS41ODc1LC0xLjYxMjMgaCAtMC41NzA1MDggdiAwLjY5NDUzIGwgMS41NjI2OTYsMS41NjI3IHEgLTAuMDc0NDIsMC4xNDg4MiAtMC4wNzQ0MiwwLjMyMjQ2IDAsMC4xNDg4MyAwLjA3NDQyLDAuMjk3NjUgbCAtMS41NjI2OTYsMS41ODc1IHYgMC42NDQ5MyBoIDAuNTcwNTA4IGwgMS41NjI2OTUsLTEuNTYyNyBxIDAuMTczNjMzLDAuMDc0NCAwLjQyMTY4LDAuMDc0NCAwLjE5ODQzNywwIDAuMzIyNDYxLC0wLjA0OTYgbCAxLjU2MjY5NSwxLjUzNzkgaCAwLjY2OTcyNyB2IC0wLjU3MDUxIGwgLTEuNTg3NSwtMS41Mzc4OSBxIDAuMDc0NDEsLTAuMTczNjQgMC4wNzQ0MSwtMC40MjE2OCAwLC0wLjIyMzI1IC0wLjA5OTIyLC0wLjM5Njg4IGwgMS42MTIzMDUsLTEuNTg3NSB2IC0wLjU5NTMxIGggLTAuNjk0NTMxIHogbSAzLjAwMTM2NywyNi4zOTIxOSAtMy4zNDg2MzIsLTEuNTg3NSAtMy4yMjQ2MSwxLjU4NzUgMy4zNDg2MzMsMS42MTIzIHogbSAtMTAuNzY1MjM0LDAuNzY4OTQgLTIuNjI5Mjk3LC0wLjg5Mjk3IC0yLjA1ODc4OSwxLjYxMjMxIDIuNjA0NDkyLDAuODkyOTcgeiBtIDE5LjI3MzI0MiwtMi4zMDY4MyBxIDEuMTE2MjExLC0wLjEyNDAzIDEuMTE2MjExLC0xLjI0MDI0IDAsLTAuNzE5MzMgLTAuNjQ0OTIyLC0xLjA5MTQgLTIuMDgzNTk0LC0wLjg0MzM2IC01LjMwODIwMywtMS4zNjQyNiAtMy4xOTk4MDUsLTAuNTQ1NzEgLTYuOTk0OTIyLC0wLjU0NTcxIC03Ljk2MjMwNCwwIC0xMi4zNTI3MzQsMS45NTk1NyAtMC41NDU3MDMsMC40MjE2OCAtMC41NDU3MDMsMS4wNDE4IDAsMS4yNjUwNCAxLjI2NTAzOSwxLjIxNTQzIDQuNDE1MjM0LC0xLjY2MTkxIDExLjYzMzM5OCwtMS42NjE5MSA3LjMxNzM4MywwIDExLjgzMTgzNiwxLjY4NjcyIHogTSAyMS4wMDk1NywyNjIuMTM3IHEgLTIuODc3MzQzLC0zLjA1MDk4IC02LjUyMzYzMiwtMy4wNTA5OCAtMy4zNDg2MzMsMCAtNS4wODQ5NjEyLDIuMjMyNDMgLTEuMTE2MjEwOSwxLjQxMzg2IC0xLjExNjIxMDksMy44NDQ3MiAwLDEuOTA5OTYgMC41NDU3MDMxLDMuNjQ2MjkgMC4wMjQ4MDUsMC40OTYwOSAwLjYyMDExNzIsMC40OTYwOSAwLjU5NTMxMjgsMCAwLjY0NDkyMTgsLTAuNTk1MzEgLTAuMTk4NDM3NSwtMS4yNjUwNCAtMC4xOTg0Mzc1LC0yLjI1NzIyIDAsLTIuMDU4NzkgMC45NjczODI1LC0zLjI0OTQyIDEuMzg5MDYzLC0xLjg4NTE1IDQuMzE2MDE2LC0xLjg4NTE1IDIuODc3MzQ0LDAgNS4zODI2MTcsMi4yODIwMyAwLjQ5NjA5NCwwIDAuNDk2MDk0LC0wLjkxNzc4IDAsLTAuMTk4NDMgLTAuMDQ5NjEsLTAuNTQ1NyB6IG0gOC42NTY4MzYsMCBxIC0wLjA0OTYxLDAuMzQ3MjcgLTAuMDQ5NjEsMC41NDU3IDAsMC45MTc3OCAwLjQ5NjA5NCwwLjkxNzc4IDIuNDgwNDY4LC0yLjI4MjAzIDUuNDA3NDIxLC0yLjI4MjAzIDIuODc3MzQ0LDAgNC4yOTEyMTEsMS44ODUxNSAwLjk2NzM4MywxLjE5MDYzIDAuOTY3MzgzLDMuMjQ5NDIgMCwwLjk5MjE4IC0wLjE5ODQzNywyLjI1NzIyIDAuMDI0OCwwLjU5NTMxIDAuNjQ0OTIxLDAuNTk1MzEgMC42MjAxMTgsMCAwLjYyMDExOCwtMC40OTYwOSAwLjU0NTcwMywtMS43MzYzMyAwLjU0NTcwMywtMy42NDYyOSAwLC0yLjQzMDg2IC0xLjExNjIxMSwtMy44NDQ3MiAtMS43NjExMzMsLTIuMjMyNDMgLTUuMDg0OTYxLC0yLjIzMjQzIC0zLjY3MTA5NCwwIC02LjUyMzYzMywzLjA1MDk4IHoiCiAgICAgICAgIHN0eWxlPSJzdHJva2Utd2lkdGg6MC4yNjQ1ODMzMiIKICAgICAgICAgaWQ9InBhdGgyNzciCiAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8L2c+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMTUuNDY1MzUsMjkwLjIzNDczIGMgLTAuMDU1MTIsLTAuMDIwMyAtMC4xNDc1MzgsLTAuMDgxNiAtMC4yMDUzNjQsLTAuMTM2MjQgLTAuMjc0MjgsLTAuMjU5MTYgLTAuMjI3NzUyLC0wLjgwNDM0IDAuMTUxNzA0LC0xLjc3NzU2IDAuMTk3MTUxLC0wLjUwNTY1IDAuMzIxMTIxLC0wLjcwNzI5IDAuNTQ5NjUsLTAuODk0MDMgMC4wOTQ3LC0wLjA3NzQgMC4yNjM2NywtMC4yMjY3OCAwLjM3NTQ4NywtMC4zMzIgMC4xNTg4MjYsLTAuMTQ5NDYgMC4zMDg2NTcsLTAuMjQyMjkgMC42ODQ4NzgsLTAuNDI0MzYgMC41ODI3OCwtMC4yODIwNCAwLjk4NDUyNCwtMC40MjUyOSAxLjY4NjY1NSwtMC42MDE0NCAwLjg5OTEzOSwtMC4yMjU1NiAxLjk4NTgyOSwtMC4zODI4MyAzLjMyMTc5OCwtMC40ODA3MyAwLjgxNjA5OCwtMC4wNTk4IDYuMDQ1MTY0LC0wLjA1OTggNi44MTUzNzEsLTVlLTUgMS4zOTIwNjMsMC4xMDgwNyAyLjM3ODE1NywwLjI1MjE1IDMuMjg2NTMzLDAuNDgwMjEgMC43MDEwOTUsMC4xNzYwMyAxLjEwNTM2LDAuMzE5ODEgMS42Nzc0ODIsMC41OTY2MSAwLjQxNjgyNCwwLjIwMTY3IDAuNDg3MTE2LDAuMjQ4MDIgMC42MTU2ODUsMC40MDU5NSAwLjA3OTgzLDAuMDk4MSAwLjI4MjMyNywwLjMxMzU5IDAuNDQ5OTkzLDAuNDc4OTYgMC4yNTk1NTYsMC4yNTYgMC4zMjgwMjUsMC4zNDc4NCAwLjQ2MDgxMiwwLjYxODA2IDAuMTU3MTMsMC4zMTk3NyAwLjM4MDA3MSwxLjAyMjA2IDAuNDE0NDk4LDEuMzA1NzEgMC4wMjY0NiwwLjIxNzg5IC0wLjA2MDE0LDAuNDkwNjcgLTAuMTk2ODUyLDAuNjIwMTcgLTAuMTQ2MzA0LDAuMTM4NTcgLTAuMzIzMTAxLDAuMTkxMDIgLTAuNTc1NjQ2LDAuMTcwNzQgLTAuNDA5Nzc2LC0wLjAzMjkgLTAuNTQ2OTQ5LC0wLjE3ODM4IC0wLjU5MjA0NSwtMC42Mjc5NiAtMC4wNDk1MywtMC40OTM3OCAtMC4xNzkwMDksLTAuNzU0MjYgLTAuNTQyNTA3LC0xLjA5MTM4IC0wLjg1MjY5NywtMC43OTA4MSAtMi42MjYxNjcsLTEuMjM3NjkgLTUuNzY2MzUsLTEuNDUzMDEgLTAuODQ5MTM1LC0wLjA1ODIgLTQuNTgxNTQ4LC0wLjA1NzkgLTUuNDEyMjA5LDUuM2UtNCAtMy4yMjgyNTIsMC4yMjY4NyAtNC45NTM3NCwwLjY4MzI0IC01Ljc4NzkyLDEuNTMwODEgLTAuMjY0MjkyLDAuMjY4NTMgLTAuMzg2OTY1LDAuNTMxMzIgLTAuNDMwMTUxLDAuOTIxNDcgLTAuMDU4NzQsMC41MzA2OSAtMC4yMDcwOTYsMC42OTU4NSAtMC42NDI3OTksMC43MTU2NCAtMC4xMzExNjIsMC4wMDYgLTAuMjgzNTc5LC0wLjAwNiAtMC4zMzg3MDMsLTAuMDI2MSB6IgogICAgICAgaWQ9InBhdGgyODAiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDIzLjgyNTMxMywyODIuODMwMzEgYyAtMC44OTYwOCwtMC40MzM1MyAtMS42MTc3MDgsLTAuNzk5MzggLTEuNjAzNjE4LC0wLjgxMzAxIDAuMDE0MDksLTAuMDEzNiAwLjcyNTc4NywtMC4zNjkyNCAxLjU4MTU0OCwtMC43OTAyNyBsIDEuNTU1OTI4LC0wLjc2NTQ5IDEuMTY3NzAzLDAuNTU0MTggYyAwLjY0MjIzOSwwLjMwNDc5IDEuMzg1MzI3LDAuNjU3MjkgMS42NTEzMDcsMC43ODMzMiBsIDAuNDgzNjAxLDAuMjI5MTUgLTEuNTg2OTEzLDAuNzk2MzQgYyAtMC44NzI4MDEsMC40Mzc5OSAtMS41OTQ0MjksMC43OTU4MiAtMS42MDM2MTYsMC43OTUxOCAtMC4wMDkyLC01LjNlLTQgLTAuNzQ5ODYxLC0wLjM1NTg3IC0xLjY0NTk0LC0wLjc4OTQgeiIKICAgICAgIGlkPSJwYXRoMjgyIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAxNC41ODYyNzQsMjgzLjk2MDIgYyAtMC42ODU2MTUsLTAuMjM1OTMgLTEuMjUzODU0LC0wLjQzNjI0IC0xLjI2Mjc1NCwtMC40NDUxNCAtMC4wMDg5LC0wLjAwOSAwLjQzNjU3OCwtMC4zNzAzNSAwLjk4OTk1MSwtMC44MDMyMiBsIDEuMDA2MTMzLC0wLjc4NzAzIDEuMjczNzM0LDAuNDMzMTggYyAwLjcwMDU1MywwLjIzODI1IDEuMjc5NDUzLDAuNDM4OSAxLjI4NjQ0MywwLjQ0NTg5IDAuMDA3LDAuMDA3IC0wLjMyMjkyMiwwLjI3MjQ0IC0wLjczMzEzOSwwLjU4OTg4IC0wLjQxMDIxNywwLjMxNzQ0IC0wLjg2ODI4MSwwLjY3MjEyIC0xLjAxNzkxOSwwLjc4ODE3IC0wLjE0OTYzOSwwLjExNjA1IC0wLjI3NzQyNywwLjIxMDE1IC0wLjI4Mzk3NCwwLjIwOTExIC0wLjAwNjUsLTEwZS00IC0wLjU3Mjg2MSwtMC4xOTQ5MSAtMS4yNTg0NzUsLTAuNDMwODQgeiIKICAgICAgIGlkPSJwYXRoMjg0IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAzNC4xMzExNzQsMjgzLjYwMTE3IGMgLTAuNTU2NTQzLC0wLjQzMjg2IC0xLjAwNzU2LC0wLjc5MTM2IC0xLjAwMjI2LC0wLjc5NjY1IDAuMDA1MywtMC4wMDUgMC41ODU5MjgsLTAuMjA1MzYgMS4yOTAyODgsLTAuNDQ0NTkgbCAxLjI4MDY1NSwtMC40MzQ5NSAxLjAxMzM3NSwwLjc5NDc3IDEuMDEzMzc1LDAuNzk0NzcgLTEuMjc4OTIxLDAuNDM5MiBjIC0wLjcwMzQwOCwwLjI0MTU2IC0xLjI4NDcwMywwLjQzODE0IC0xLjI5MTc3LDAuNDM2ODQgLTAuMDA3MSwtMTBlLTQgLTAuNDY4MTk5LC0wLjM1NjUzIC0xLjAyNDc0MiwtMC43ODkzOSB6IgogICAgICAgaWQ9InBhdGgyODYiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDM2LjY5NjU3NCwyODAuMjk4NSBjIC0yLjMyMTU5NCwtMC44MDQxMyAtNS4xODQ5NTIsLTEuMjc2NzYgLTguODE5ODk2LC0xLjQ1NTgxIC0xLjA0NjM1OCwtMC4wNTE2IC0zLjk1Nzk3OSwtMC4wNTEzIC00Ljk3Nzg5NCw1LjNlLTQgLTMuNTI4OSwwLjE3ODk0IC02LjEyNTQxNiwwLjYwMDk3IC04LjQ3MjI2NSwxLjM3NzA4IC0wLjY5NTIyOCwwLjIyOTkxIC0wLjczMzQyMiwwLjIzODY3IC0wLjk1ODM0MiwwLjIxOTgxIC0wLjYzOTIyNywtMC4wNTM2IC0wLjk4Nzk0OSwtMC41MDA1OCAtMC45NTM0NTEsLTEuMjIyMTMgMC4wMTY5MiwtMC4zNTM4NyAwLjEyNDI4NSwtMC42MDQ2MyAwLjM1OTQzMywtMC44Mzk0NyAwLjE3NTAwNCwtMC4xNzQ3OCAwLjYwNjI3NiwtMC4zNjYyIDEuNTM3ODM2LC0wLjY4MjU2IDIuNzAwMjI5LC0wLjkxNzAzIDUuOTA2NzMxLC0xLjM1ODUzIDEwLjI0MDc0NSwtMS40MTAwNCAzLjUyNTI1NiwtMC4wNDE5IDYuMTM3NTM1LDAuMTg0MTQgOS4xODU0NjksMC43OTQ4IDEuNTMzNzk3LDAuMzA3MjkgMy40MjYxNSwwLjg2MjY3IDMuOTE0NDMzLDEuMTQ4ODIgMC4xOTc0MTksMC4xMTU3IDAuMzk5NDQ1LDAuMzU4MTcgMC40ODI3MTIsMC41NzkzNCAwLjA5NzY5LDAuMjU5NDkgMC4wODE0NSwwLjc3MTkxIC0wLjAzMjY4LDEuMDMxMDIgLTAuMDk4OTcsMC4yMjQ3MSAtMC4zMzgyOTQsMC40NDgzIC0wLjU3MjM1MiwwLjUzNDczIC0wLjMzMDg5NiwwLjEyMjE5IC0wLjM3MDkzNiwwLjExODk0IC0wLjkzMzc1MiwtMC4wNzYgeiIKICAgICAgIGlkPSJwYXRoMjg4IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAxMy40NTEzNjYsMjc1Ljc4MDY0IGMgLTAuNDY0Mjk2LC0wLjg3MzY3IC0wLjk5NDY3MSwtMi4yOTU0NiAtMS4xNDI5OTgsLTMuMDY0MDUgLTAuMTA0NTI0LC0wLjU0MTYyIC0wLjE1NDQyMSwtMS4yODA1MiAtMC4xMTI1NTEsLTEuNjY2NzIgMC4wNzU0MiwtMC42OTU2NSAwLjQyNDM2LC0xLjA2MDQ5IDAuOTcwOTIsLTEuMDE1MTcgMC4xOTk0ODUsMC4wMTY1IDAuNDA3NTkyLDAuMTM5MzcgMC43MjAwNTIsMC40MjQ5NyAwLjEwNTY1NSwwLjA5NjYgMC4xOTIwOTgsMC4xNjI4IDAuMTkyMDk1LDAuMTQ3MTcgLTRlLTYsLTAuMDE1NiAtMC4wMjI1NSwtMC4xNDYyNCAtMC4wNTAxMSwtMC4yOTAyNiAtMC4wNjQwMywtMC4zMzQ2NCAtMC4wNjQ2NSwtMS4wMzI0OSAtMC4wMDEyLC0xLjM5NjE3IDAuMTA1Njg2LC0wLjYwNjA1IDAuMzkyNzUxLC0xLjI3MTQxIDAuNzEzNTkzLC0xLjY1Mzk3IDAuMjM4MTIzLC0wLjI4MzkzIDAuNjM0NDg2LC0wLjU3MjggMS4wMDgxODUsLTAuNzM0NzggMC4zNDUzODIsLTAuMTQ5NyAwLjUyNzEsLTAuMTcyMDggMC43ODg1OTUsLTAuMDk3MSAxLjA1NzA4MiwwLjMwMjk5IDIuMjU5OTQyLDEuNzE2NzggMi42ODcxNDMsMy4xNTgzNSAwLjA0MDg0LDAuMTM3ODEgMC4wODUyOSwwLjI2MjggMC4wOTg3OCwwLjI3Nzc2IDAuMDEzNDksMC4wMTQ5IDAuMDUwNDUsLTAuMDUyMSAwLjA4MjEzLC0wLjE0ODkgMC4xMjc1MDUsLTAuMzg5ODIgMC4zMjAzMjQsLTAuNjU5NDEgMC41MzUxMzYsLTAuNzQ4MiAwLjA1NTY4LC0wLjAyMyAwLjIyODY5LC0wLjA2NzcgMC4zODQ0NjgsLTAuMDk5MiAwLjUwODc1OCwtMC4xMDMwNCAwLjc4ODg0MSwtMC4wMTY0IDEuMDMxODkzLDAuMzE5NCAwLjM1NjcsMC40OTI3NCAwLjcxMTg5NCwxLjM4OTYzIDAuODg1NzYxLDIuMjM2NjIgMC4xMzc1NTYsMC42NzAwOSAwLjE4MjU3MiwxLjA1NDQ3IDAuMjU0MzIxLDIuMTcxNTYgMC4wMzcxOCwwLjU3ODgxIDAuMDc1NDQsMS4wOTk5MSAwLjA4NTA0LDEuMTU4MDEgbCAwLjAxNzQ0LDAuMTA1NjQgLTAuMjU5ODgsMC4wMjA3IGMgLTAuMTQyOTM0LDAuMDExNCAtMC40MTczNTUsMC4wMzQ0IC0wLjYwOTgyNSwwLjA1MTEgLTAuMTkyNDcsMC4wMTY3IC0wLjM1NDY1OSwwLjAyNTcgLTAuMzYwNDIsMC4wMTk5IC0wLjAwNTgsLTAuMDA2IDAuMDA2NywtMC4yNzkyNiAwLjAyNzY2LC0wLjYwNzc3IDAuMDYwODgsLTAuOTUzNTkgLTAuMDExMDUsLTIuMDU1NjYgLTAuMTg0Mzg3LC0yLjgyNTE1IC0wLjA0NDUsLTAuMTk3NTYgLTAuMTA0OTc5LC0wLjQwOTkxIC0wLjEzNDM4OCwtMC40NzE4OSAtMC4xNzAzMjYsLTAuMzU4OTMgLTAuNjI4ODMxLC0wLjUxMTUyIC0wLjkzNDc1MSwtMC4zMTEwNyAtMC40MzA2NDYsMC4yODIxNyAtMC41MjM4MjcsMS4xODU3MiAtMC4yODY0ODgsMi43Nzc5NyAwLjA1NzM0LDAuMzg0NjUgMC4yNDUyMDUsMS4zODAyNCAwLjI4NzM0LDEuNTIyNzMgMC4wMTI5MywwLjA0MzcgLTAuMDI5NDUsMC4wNjA5IC0wLjIyNzA3MywwLjA5MjEgLTAuMzY2NTM2LDAuMDU3OCAtMS4xMzQ4MzYsMC4xNDI3IC0xLjE1MDQ3NiwwLjEyNzA2IC0wLjAwNzYsLTAuMDA4IC0wLjAyNzk1LC0wLjIyOTkzIC0wLjA0NTI5LC0wLjQ5NDE0IC0wLjE0MjcyMSwtMi4xNzQ2MyAtMC40NjU2MTgsLTMuODY4NTggLTAuOTkyNjc2LC01LjIwNzcgLTAuMjEzMDQsLTAuNTQxMjggLTAuMzQ4NTIsLTAuNzIwMzMgLTAuNjY2ODM0LC0wLjg4MTI1IC0wLjI3NTIsLTAuMTM5MTMgLTAuNzg1Mjg2LC0wLjEyNTAzIC0xLjAxNjY5MywwLjAyODEgLTAuMTk4ODUyLDAuMTMxNTkgLTAuMjYyNjg3LDAuMjk0OTIgLTAuMzE5MjYzLDAuODE2ODYgLTAuMDk0NTgsMC44NzI1NSAwLjAyNTUyLDEuNjA4NjYgMC41NTY0NTMsMy40MTA1NSAwLjE4MzQ2MSwwLjYyMjY0IDAuNzM4MTE2LDIuMzY1NDYgMC44MjQyMTMsMi41ODk4MyAwLjAyNzk3LDAuMDcyOSAtMC40MTE3NDgsMC4xODAzIC0wLjk2MTI5MywwLjIzNDg1IGwgLTAuMjIxNDI5LDAuMDIyIC0wLjIwMzgxNCwtMC41MTUyOSBjIC0wLjExMjA5NywtMC4yODM0MiAtMC4yODUyOTQsLTAuNzM5NzUgLTAuMzg0ODgxLC0xLjAxNDA3IC0wLjQzOTY3MiwtMS4yMTExMyAtMC43NDM4NjksLTEuODc3MDIgLTAuOTMzMDgyLC0yLjA0MjUyIC0wLjIyODU2NiwtMC4xOTk5MiAtMC41MTUyNzEsLTAuMjEzODkgLTAuNjg0ODQ4LC0wLjAzMzQgLTAuMTg1OTE2LDAuMTk3OSAtMC4yNTU4MDgsMC42ODAwMSAtMC4xNTU5OTIsMS4wNzYwMSAwLjEyMzMwNCwwLjQ4OTE4IDAuNTA1MzcxLDEuMjgzMzUgMS4wOTA0NjYsMi4yNjY2NyAwLjE2MjMyNywwLjI3MjgxIDAuMjk1MTQsMC41MDgwNyAwLjI5NTE0LDAuNTIyOCAwLDAuMDYxNCAtMC42Mzk4NTYsMC4yNTQ1MyAtMC45NzgwNzksMC4yOTUyNSBsIC0wLjIwOTYwMywwLjAyNTIgeiIKICAgICAgIGlkPSJwYXRoMjkwIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSAzNi42MzUyMywyNzYuMjcwNTcgYyAtMC4xODc3NDMsLTAuMDMxMiAtMC42Mjk2NzksLTAuMTcwNzMgLTAuNzU4NDA3LC0wLjIzOTQxIGwgLTAuMDc1OTMsLTAuMDQwNSAwLjIwOTE0NywtMC4zNTEzMSBjIDAuNjA0ODE3LC0xLjAxNTkxIDEuMDcxNjg1LC0xLjk4Nzk1IDEuMTk1MjksLTIuNDg4NjMgbCAwLjA3MDA1LC0wLjI4Mzc3IC0wLjA3MDk4LC0wLjI4NzUxIGMgLTAuMTAzMzI1LC0wLjQxODU0IC0wLjI0NzA3NCwtMC41ODExMiAtMC41MTM4MTEsLTAuNTgxMTIgLTAuMTQyNTQ3LDAgLTAuMzQ2MTcyLDAuMTIzMjggLTAuNDM3MjksMC4yNjQ3NCAtMC4yMTU3ODEsMC4zMzUwMSAtMC42NDA4ODEsMS4zMzU5NSAtMS4wNTEwMzgsMi40NzQ3NyAtMC4xNTU1MiwwLjQzMTgxIC0wLjI5NzgyMywwLjgyNjQ1IC0wLjMxNjIzNiwwLjg3Njk4IC0wLjAzMjU5LDAuMDg5NSAtMC4wNDAxOCwwLjA5MTkgLTAuMjg5MTIxLDAuMDkwNyAtMC4zNzAzOTUsLTAuMDAyIC0wLjk0MDUyNywtMC4xMzUwOCAtMC45NDA1MjcsLTAuMjIwMDMgMCwtMC4wMjQgMC4wMjkxNSwtMC4xMTc1NiAwLjA2NDc5LC0wLjIwNzk2IDAuMDk4MzcsLTAuMjQ5NTggMC41ODU5MDEsLTEuNzg1MTIgMC43NzMyOSwtMi40MzU2MSAwLjQ3MTI4MSwtMS42MzU5NSAwLjYwMjIyMSwtMi40MzI2OCAwLjUzNDE1OSwtMy4yNTAyNiAtMC4wNDkyOCwtMC41OTIwMSAtMC4wODE1NCwtMC43MDY4NCAtMC4yMzgzMzQsLTAuODQ4NSAtMC4xNTIyMjUsLTAuMTM3NTIgLTAuMzA3NzgyLC0wLjE4NTQ5IC0wLjYwMjQwOCwtMC4xODU3NCAtMC41NjI0MTUsLTQuN2UtNCAtMC44NjM3NTksMC4yMzIyIC0xLjEyNDc4MSwwLjg2ODQ0IC0wLjM0NzU5NywwLjg0NzI4IC0wLjY1NDgzMywyLjA1NTc2IC0wLjgyMzg4NiwzLjI0MDY1IC0wLjA5Mzk4LDAuNjU4NjcgLTAuMjE5ODU2LDIuMDU2NTggLTAuMjE5ODU2LDIuNDQxNDkgMCwwLjA5NjIgLTAuMDAyNiwwLjA5NzYgLTAuMTg3NzYxLDAuMDk3NiAtMC4xNjQ5NDQsMCAtMS4xMDA2NDYsLTAuMTE2NjUgLTEuMjA0MDU2LC0wLjE1MDExIC0wLjAyNzg4LC0wLjAwOSAtMC4wMTY4MywtMC4xMTM5OSAwLjAzOTM0LC0wLjM3Mzg4IDAuMjUxMzMzLC0xLjE2MjcgMC4zNjA5LC0yLjA2MzkzIDAuMzQ0MTUxLC0yLjgzMDc1IC0wLjAxMzg5LC0wLjYzNTQzIC0wLjA0NTA1LC0wLjc1MzggLTAuMjY0MjE4LC0xLjAwMzQyIC0wLjEzNjcxLC0wLjE1NTcgLTAuMjc3MDU4LC0wLjIxODgzIC0wLjQ4NjUsLTAuMjE4ODMgLTAuMjMwNDg2LDAgLTAuNDI3Njg1LDAuMTA3MyAtMC41MzU1OTMsMC4yOTE0MyAtMC4zMjM1NTEsMC41NTIxIC0wLjQ4ODQ4NywyLjI5NzEyIC0wLjM1NTgzNiwzLjc2NDcxIGwgMC4wMjA4OCwwLjIzMDg1IC0wLjQ2NDIxNCwtMC4wMjI1IGMgLTAuMjU1MzE1LC0wLjAxMjQgLTAuNTM1OTI5LC0wLjAzMTggLTAuNjIzNTg2LC0wLjA0MzIgLTAuMTU2NTU5LC0wLjAyMDMgLTAuMTU5MDc1LC0wLjAyMjUgLTAuMTQyMzQzLC0wLjEyNDgxIDAuMDA5NCwtMC4wNTczIDAuMDQwMDYsLTAuNDcyNDggMC4wNjgyLC0wLjkyMjY3IDAuMDkwNDIsLTEuNDQ2MzUgMC4yNDkyMywtMi41MDc2OSAwLjQ4OTg5MiwtMy4yNzQwNSAwLjIyMDM3MiwtMC43MDE3NCAwLjcwMzg0NSwtMS41MTcxNyAwLjk3OTc0NCwtMS42NTI0MyAwLjI1MDU0MiwtMC4xMjI4MiAwLjgwOTkxNiwtMC4wODg5IDEuMTIxNzAxLDAuMDY4IDAuMTkzNDY2LDAuMDk3NCAwLjQ1MDAzMywwLjQ3NDYgMC41NjYwMzQsMC44MzIyNCAwLjA1MDU1LDAuMTU1ODUgMC4wNDIzOSwwLjE3MDE5IDAuMTk5MjI5LC0wLjM1MDMxIDAuMTM2Mzg3LC0wLjQ1MjYyIDAuNDQxMzc3LC0xLjA2ODc3IDAuNzI3MDA4LC0xLjQ2ODczIDAuMjY2MDczLC0wLjM3MjU3IDAuODAzNTI0LC0wLjkyNTQzIDEuMTE0MDYsLTEuMTQ2MDEgMC4yOTIzMywtMC4yMDc2NCAwLjY3Mjc3MiwtMC4zODUwNyAwLjkyNzA2NiwtMC40MzIzNiAwLjI1MjIyNywtMC4wNDY5IDAuNDMyNzg0LDZlLTQgMC44OTA3NDMsMC4yMzQ0NSAwLjI0MTI0OCwwLjEyMzE5IDAuMzYwNDg3LDAuMjEzMjcgMC42MDMyNjYsMC40NTU3OCAwLjI2MTU2NSwwLjI2MTI2IDAuMzI3NzksMC4zNTIwNiAwLjQ4ODQ4MiwwLjY2OTc0IDAuNDEyNTY1LDAuODE1NTkgMC41MzgxNzYsMS41MzQzIDAuNDExNjQ0LDIuMzU1MzEgLTAuMDc4MDUsMC41MDY0IC0wLjA4MDE5LDAuNTAwOTUgMC4xMjQ3MTcsMC4zMTY3MiAwLjM3Njc4MiwtMC4zMzg3NiAwLjU5MDI3NywtMC40MzY5OCAwLjg4MzkyOCwtMC40MDY2NyAwLjM0MTU2MSwwLjAzNTMgMC41OTk0OTIsMC4yNTkxMyAwLjc0NDIyNSwwLjY0NTk2IDAuMTI4MTk4LDAuMzQyNjQgMC4wODE3OCwxLjM2MjM0IC0wLjEwMDE2OSwyLjIwMDIgLTAuMTc2OTA1LDAuODE0NjYgLTAuNDExNzM0LDEuNDM5ODEgLTAuOTk0NTI5LDIuNjQ3NTcgLTAuNDQxMDYzLDAuOTE0MDQgLTAuMzY3MDQzLDAuODM5NzIgLTAuNzY5NjI4LDAuNzcyNzggeiIKICAgICAgIGlkPSJwYXRoMjkyIgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSA0MS4wODk4MTYsMjcwLjY2MTg5IGMgLTAuMjEwODMsLTAuMDMyNyAtMC4zMzY3NDYsLTAuMTE2ODcgLTAuNDE0MTg3LC0wLjI3Njg0IC0wLjA4NTg2LC0wLjE3NzM1IC0wLjA4NTk5LC0wLjE5NTYzIC0wLjAwNTcsLTAuNzc2MzggMC4yOTAzMTcsLTIuMTAwMTQgMC4wOTYyMywtMy42MTQzMiAtMC42MDE1MywtNC42OTI5NiAtMC43MDQyODQsLTEuMDg4NzEgLTEuNzU0ODE0LC0xLjgwMjk3IC0zLjA0NTc5OCwtMi4wNzA4NiAtMC40OTk5MjUsLTAuMTAzNzQgLTAuODcxNTc4LC0wLjEzNzg5IC0xLjQ5NDI1NiwtMC4xMzczIC0xLjE4NjAwNSwxMGUtNCAtMi4xODQ3MzksMC4yMzQ1NiAtMy4yNDAyNDYsMC43NTczOCAtMC42OTk2MDMsMC4zNDY1NCAtMS4yNTU4MTYsMC43MjU3MiAtMi4wODA3NzMsMS40MTg1MiBsIC0wLjEyNDksMC4xMDQ5IC0wLjEyNTY2NiwtMC4wNjE0IGMgLTAuMDkwMzQsLTAuMDQ0MSAtMC4xNDkxNDMsLTAuMTA4MzYgLTAuMjA5MTg1LC0wLjIyODQ1IC0wLjA3Nzg3LC0wLjE1NTc0IC0wLjA4MzUyLC0wLjIwMDY5IC0wLjA4MzUyLC0wLjY2NDQ5IHYgLTAuNDk3NDYgbCAwLjQxNzYwOCwtMC40MDAyOSBjIDEuMjYzNDI4LC0xLjIxMTA0IDIuNTk2NzkzLC0yLjAwMTQzIDMuOTkwNTA2LC0yLjM2NTUgMC42OTc2NzUsLTAuMTgyMjUgMS4xMTM3MywtMC4yMzg0OCAxLjg5NzUzNywtMC4yNTY0NiAwLjgwNjAxMywtMC4wMTg1IDEuMjUxNDEzLDAuMDE1MyAxLjg4ODAyOSwwLjE0MzM5IDEuNzU1NjIyLDAuMzUzMTEgMy4xOTI3MDksMS40MTA1MiAzLjkxODEzMywyLjg4Mjk3IDAuNDQ1Mjg4LDAuOTAzODMgMC42MjUyNTIsMS45MTg3IDAuNTkwMjI3LDMuMzI4NDcgLTAuMDI2OTcsMS4wODU3IC0wLjEyMDI3MiwxLjc4NDMgLTAuMzYzNzQ5LDIuNzIzNzUgLTAuMDczODEsMC4yODQ4MSAtMC4xNDc3NjcsMC41ODQ0NSAtMC4xNjQzNDEsMC42NjU4NyAtMC4wMTY1NiwwLjA4MTQgLTAuMDUzOCwwLjE4NDE1IC0wLjA4MjczLDAuMjI4MyAtMC4wOTE3OSwwLjE0MDA4IC0wLjM4Nzk1LDAuMjE3OSAtMC42NjU0NTMsMC4xNzQ4NCB6IgogICAgICAgaWQ9InBhdGgyOTQiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogICAgPHBhdGgKICAgICAgIHN0eWxlPSJmaWxsOiNmZmZmZmY7c3Ryb2tlLXdpZHRoOjAuMDMzNDA4NjkiCiAgICAgICBkPSJtIDI0Ljc5MDUxMSwyNjYuODAwODkgYyAtMC41NDc4NDksLTAuMTIyODEgLTAuOTkwMjM5LC0wLjM1NTgzIC0xLjM4MTk4NSwtMC43Mjc5NSAtMC40MjgyMzksLTAuNDA2NzkgLTAuNzAwOTg1LC0wLjg1OTk1IC0wLjg0NzM0NiwtMS40MDc4NCAtMC4xMDIzOTIsLTAuMzgzMyAtMC4xMDI3NDIsLTEuMDkxOTQgLTcuMTRlLTQsLTEuNDY5OTkgMC4yNzEwNDUsLTEuMDA0NDMgMS4xMDQyNzMsLTEuODUzMTEgMi4wNjc3MDUsLTIuMTA2MDMgMC42NDQxMTMsLTAuMTY5MSAxLjU3NDg3OCwtMC4xMTAyMSAyLjIwNzk1MSwwLjEzOTcgMC45OTQ2ODUsMC4zOTI2NCAxLjUxMTc3MSwxLjMyNDggMS41MDcyNTcsMi43MTcxNSAtMC4wMDUsMS41NDk4MSAtMC42MjU4NDgsMi40NjUzMyAtMS44OTU4ODUsMi43OTU4NCAtMC40MjE5MjIsMC4xMDk4IC0xLjI5MjMyOCwwLjE0MDg1IC0xLjY1Njk3MiwwLjA1OTEgeiIKICAgICAgIGlkPSJwYXRoMjk2IgogICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT0iMCIgLz4KICAgIDxwYXRoCiAgICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO3N0cm9rZS13aWR0aDowLjAzMzQwODY5IgogICAgICAgZD0ibSA5LjI5MSwyNzAuNjU3MyBjIC0wLjIwMTIwOSwtMC4wMjk4IC0wLjMxMzI0OTgsLTAuMTAxODIgLTAuMzcyMDg0OSwtMC4yMzkxOSAtMC4wMjUxOTEsLTAuMDU4OCAtMC4wOTk1NjksLTAuMzA5OSAtMC4xNjUyODA3LC0wLjU1Nzk2IC0wLjU5MzEyNTIsLTIuMjM5MDEgLTAuNTkyNDcyMiwtNC40NjE1NyAwLjAwMTc1LC01Ljk2Mjk1IDAuNDY2OTMyNywtMS4xNzk3NiAxLjQxNjg5NzYsLTIuMTc2ODUgMi42MjYwNTg2LC0yLjc1NjM1IDAuOTM3NjgyLC0wLjQ0OTM5IDEuODQzNzk0LC0wLjYzNTE0IDMuMDk4MzQ5LC0wLjYzNTE0IDAuNjkzMjI0LDAgMS4wODQ1NjcsMC4wMzYyIDEuNjYwNTgsMC4xNTM0MSAxLjU5MzQyMywwLjMyNDM1IDMuMDc5MDA1LDEuMTQ0NDcgNC40MTIxOTIsMi40MzU3NyBsIDAuNDQ4NDAyLDAuNDM0MzEgMC4wMzM5NiwwLjI5NDE2IGMgMC4wNjkyMywwLjU5OTY1IC0wLjA3OTgzLDEuMDY5NjYgLTAuMzYxNjY4LDEuMTQwMzkgLTAuMDY2MzMsMC4wMTY2IC0wLjEzNTg5MSwtMC4wMjY3IC0wLjM4OTI1MSwtMC4yNDI2IC0xLjA1ODA0MiwtMC45MDE2MSAtMi4xNTQxNDEsLTEuNDk0NTIgLTMuMzE1NjA5LC0xLjc5MzUgLTAuNjI1MDIsLTAuMTYwOSAtMS4xMDQ2MDEsLTAuMjIwMDYgLTEuNzg3MDIyLC0wLjIyMDQ2IC0wLjg4NTY0NywtNS4zZS00IC0xLjUxMjk3LDAuMDkzMyAtMi4xODIxNTgsMC4zMjYxOCAtMC44NTczMDIsMC4yOTg0IC0xLjQ4NjQ1NCwwLjczOTA5IC0yLjA0MjkyMSwxLjQzMDk1IC0wLjU4NDA4NywwLjcyNjIgLTAuODc0MDU0LDEuNDI3MzMgLTEuMDA3MjMzOSwyLjQzNTQ1IC0wLjA3Mzc1LDAuNTU4MjcgLTAuMDQ2NTA5LDEuODYyNDQgMC4wNTQxNjEsMi41OTI4OCAwLjAzOTI1LDAuMjg0ODEgMC4wNzEyNiwwLjU3MjkzIDAuMDcxMTMsMC42NDAyNyAtMi45MWUtNCwwLjE1NDE4IC0wLjEwNzM5MzksMC4zNjc1NyAtMC4yMjIyMzY1LDAuNDQyODIgLTAuMTE1NDI2MywwLjA3NTYgLTAuMzYwNTYyOCwwLjExMTI2IC0wLjU2MTExNDEsMC4wODE2IHoiCiAgICAgICBpZD0icGF0aDI5OCIKICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9IjAiIC8+CiAgICA8cGF0aAogICAgICAgc3R5bGU9ImZpbGw6I2ZmZmZmZjtzdHJva2Utd2lkdGg6MC4wMzM0MDg2OSIKICAgICAgIGQ9Im0gMjIuODY1Mzc1LDI1OC44MjcxOCB2IC0wLjMwODc3IGwgMC43ODY3MzUsLTAuNzg3MjUgYyAwLjc2MzQzLC0wLjc2MzkzIDAuNzg1Njk3LC0wLjc4OTk4IDAuNzUxNjk1LC0wLjg3OTQxIC0wLjA0MzE5LC0wLjExMzU5IC0wLjA0NTUyLC0wLjM1NjU4IC0wLjAwNDUsLTAuNDY0NTcgMC4wMjgxMiwtMC4wNzM5IC0wLjAzMjUsLTAuMTQzNDggLTAuNzUxNjk1LC0wLjg2MjE5IGwgLTAuNzgyMjc4LC0wLjc4MTc0IHYgLTAuMzQyNzEgLTAuMzQyNyBoIDAuMjczMDExIDAuMjczMDExIGwgMC43ODg1NzgsMC44MDc2OCAwLjc4ODU3OCwwLjgwNzY5IDAuMTEyNzAxLC0wLjAzOTMgYyAwLjEzODQ0MywtMC4wNDgzIDAuNDUyMDQyLC0wLjA1MTQgMC41MzgwNjIsLTAuMDA1IDAuMDU1MSwwLjAyOTUgMC4xNjc0NTUsLTAuMDcxNSAwLjg1NDUxLC0wLjc2ODQgbCAwLjc5MTA2OCwtMC44MDIzNSBoIDAuMzI5MzAzIDAuMzI5MyB2IDAuMjk3OSAwLjI5NzkxIGwgLTAuODA0MzYyLDAuNzgyMTUgLTAuODA0MzYyLDAuNzgyMTQgMC4wNTcxLDAuMTc0NTkgYyAwLjA1NDgzLDAuMTY3NjQgMC4wNTQ1OCwwLjMwMDE4IC0wLjAwMTEsMC41ODg1NyAtMC4wMTgzMywwLjA5NDkgMC4wMjIzNiwwLjE0MDE5IDAuNzY1MjYyLDAuODUxOTIgbCAwLjc4NDYyMiwwLjc1MTY5IDAuMDAxMywwLjI3NTYyIDAuMDAxMywwLjI3NTYzIGggLTAuMzIwMjMxIC0wLjMyMDIzIGwgLTAuNzg1MzczLC0wLjc2MzY5IC0wLjc4NTM3MywtMC43NjM2OCAtMC4xNTMwMTEsMC4wMzI2IGMgLTAuMTA1MjU4LDAuMDIyNCAtMC4yMjYyNzIsMC4wMjA1IC0wLjM4Nzc1NSwtMC4wMDYgbCAtMC4yMzQ3NDIsLTAuMDM4OCAtMC43NzAzNDEsMC43Njk4MiAtMC43NzAzNDIsMC43Njk4MiBoIC0wLjI3NTM2MSAtMC4yNzUzNiB6IgogICAgICAgaWQ9InBhdGgzMDAiCiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPSIwIiAvPgogIDwvZz4KPC9zdmc+Cg=='); } diff --git a/public/stylesheets/piece/letter.css b/public/stylesheets/piece/letter.css deleted file mode 100644 index 3f9f04042b..0000000000 --- a/public/stylesheets/piece/letter.css +++ /dev/null @@ -1,12 +0,0 @@ -body.base .is2d piece.pawn.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGNpcmNsZSBjeD0iMTUwIiBjeT0iMTUwIiBmaWxsPSIjYzhjOGM4IiBvcGFjaXR5PSIuOTg4IiByPSI0NC45OTUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSI1Ii8+PC9zdmc+'); } -body.base .is2d piece.knight.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIxNC4yMzEgMjI3Ljg1OHEwIDIuNTYzLS44OTcgNC4zNTgtLjc3IDEuNzk0LTIuMTc5IDIuOTQ3LTEuMjgxIDEuMTU0LTIuOTQ3IDEuNjY2LTEuNjY2LjUxMy0zLjMzMi41MTNoLTcuMDQ5cS0zLjMzMiAwLTUuODk1LS42NC0yLjQzNS0uNzctNC43NDItMi41NjQtMi4xNzgtMS45MjItNC40ODUtNS4xMjYtMi4xNzktMy4yMDQtNC44Ny04LjIwMmwtNTIuMjg4LTk0LjMyM3EtNC4xLTcuMzA1LTguMzMtMTUuMjUtNC4xLTguMDc0LTcuNjktMTUuNjM1aC0uMjU1cS4yNTYgOS4yMjcuMzg0IDE4LjgzOS4xMjggOS42MTEuMTI4IDE5LjA5NXYxMDAuMDlxMCAuODk2LS41MTIgMS43OTQtLjUxMy43NjgtMS43OTUgMS4yODEtMS4xNTMuMzg1LTMuMjAzLjY0LTEuOTIzLjM4NS00Ljk5OS4zODUtMy4wNzUgMC01LjEyNi0uMzg0LTEuOTIyLS4yNTYtMy4wNzYtLjY0LTEuMTUzLS41MTQtMS42NjYtMS4yODItLjUxMi0uODk4LS41MTItMS43OTVWODAuNjA4cTAtNS4xMjcgMi44Mi03LjMwNSAyLjgxOS0yLjE3OSA2LjE1LTIuMTc5aDEwLjUxcTMuNzE2IDAgNi4xNTEuNjQxIDIuNTYzLjY0IDQuNDg1IDIuMTc5IDIuMDUgMS40MSAzLjg0NSA0LjEgMS45MjIgMi41NjQgNC4xMDEgNi41MzdsNDAuMjQgNzIuNzkycTMuNzE3IDYuNjY0IDcuMTc4IDEzLjA3MiAzLjQ2IDYuMjggNi42NjQgMTIuNDMgMy4yMDQgNi4xNTIgNi4yOCAxMi4xNzYgMy4yMDMgNS44OTUgNi4yNzkgMTEuOTE4aC4xMjhxLS4yNTYtMTAuMTI0LS4zODQtMjEuMDE3Vjc0Ljg0cTAtLjg5Ny41MTItMS42NjYuNTEzLS43NyAxLjY2Ni0xLjI4MiAxLjI4Mi0uNjQgMy4yMDQtLjg5NyAyLjA1LS4yNTYgNS4yNTUtLjI1NiAyLjgxOSAwIDQuODcuMjU2IDIuMDUuMjU2IDMuMjAzLjg5NyAxLjE1NC41MTMgMS42NjYgMS4yODIuNTEzLjc2OS41MTMgMS42NjZ6IiBmaWxsPSIjYzhjOGM4IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iNSIvPjwvc3ZnPg=='); } -body.base .is2d piece.bishop.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIwNS43OTYgMTg5LjgyNXEwIDcuODE3LTIuMDUgMTQuNDgxLTEuOTIzIDYuNTM2LTUuNTExIDExLjc5LTMuNTg5IDUuMjU1LTguNzE1IDkuMjI4LTQuOTk4IDMuOTczLTExLjQwNiA2LjY2NC02LjI4IDIuNjkxLTEzLjU4NCA0LjEwMS03LjE3NyAxLjI4Mi0xNi41MzIgMS4yODJIMTA0LjY4cS0yLjk0NyAwLTUuNjM5LTEuOTIzLTIuNTYzLTIuMDUtMi41NjMtNy4wNDhWODAuNTA4cTAtNC45OTggMi41NjMtNi45MiAyLjY5Mi0yLjA1IDUuNjQtMi4wNWgzNy42NzdxMTQuODY2IDAgMjQuMzUgMi44MTkgOS40ODMgMi44MiAxNS43NjMgOC4yMDIgNi40MDcgNS4zODIgOS42MTEgMTMuMiAzLjIwNCA3LjgxNyAzLjIwNCAxNy42ODUgMCA1Ljg5NS0xLjQxIDExLjI3OC0xLjQxIDUuMzgyLTQuMjI5IDkuOTk2LTIuNjkgNC40ODUtNi45MiA4LjA3NC00LjEwMSAzLjU4OC05LjQ4MyA1Ljg5NSA2Ljc5MiAxLjI4MSAxMi42ODcgNC43NDIgNS44OTUgMy4zMzIgMTAuMjUyIDguNTg2IDQuNDg2IDUuMjU0IDcuMDQ5IDEyLjMwMyAyLjU2MyA3LjA0OSAyLjU2MyAxNS41MDd6bS0zMy4xOTItNzQuMjAycTAtNi4wMjQtMS42NjYtMTAuODkzLTEuNjY2LTQuODctNS4yNTUtOC4yMDItMy41ODgtMy40Ni05LjM1NS01LjI1NS01Ljc2Ny0xLjc5NC0xNS4yNS0xLjc5NGgtMjIuODEydjUzLjY5N2gyNS4xMThxOC41ODcgMCAxMy44NDEtMi4xNzggNS4yNTQtMi4zMDcgOC43MTUtNi4wMjQgMy40Ni0zLjg0NCA0Ljk5OC04Ljg0MiAxLjY2Ni01LjEyNyAxLjY2Ni0xMC41MXptOS45OTYgNzUuNDgzcTAtNy40MzMtMi40MzUtMTMuMDcxLTIuMzA3LTUuNjQtNi45Mi05LjQ4NC00LjQ4Ni0zLjg0NS0xMS40MDYtNS43NjctNi43OTMtMi4wNS0xNy4xNzMtMi4wNWgtMjYuNHY1OC40MzhoMzIuMDM5cTcuNTYgMCAxMy4yLTEuNzk0IDUuNjM5LTEuNzk0IDkuODY4LTUuMjU0IDQuMzU3LTMuNTg4IDYuNzkyLTguODQzIDIuNDM1LTUuMjU0IDIuNDM1LTEyLjE3NXoiIGZpbGw9IiNjOGM4YzgiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSI1Ii8+PC9zdmc+'); } -body.base .is2d piece.rook.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIwOC44NDMgOTk3LjYzcTAgMS4wMjUtLjM4NSAxLjc5NC0uMzg0Ljc2OS0xLjY2NiAxLjI4MS0xLjI4MS41MTMtMy41ODguNzctMi4zMDcuMjU2LTYuMTUyLjI1Ni0zLjMzMiAwLTUuNTEtLjI1Ny0yLjA1LS4yNTYtMy4zMzItLjc2OS0xLjI4Mi0uNjQtMi4wNS0xLjY2Ni0uNjQxLTEuMDI1LTEuMTU0LTIuNTYzbC0xNS4yNS0zOS4wODdxLTIuNjkyLTYuNjY0LTUuNjM5LTEyLjE3NC0yLjgyLTUuNjM5LTYuNzkyLTkuNjEyLTMuOTczLTQuMS05LjM1NS02LjI4LTUuMzgzLTIuMzA2LTEyLjk0NC0yLjMwNmgtMTQuNzM4djcwLjYxM3EwIDEuMDI1LS42NCAxLjc5NC0uNTEzLjc2OS0xLjc5NCAxLjI4MS0xLjE1NC4zODUtMy4zMzIuNjQxLTIuMDUuMzg1LTUuMjU1LjM4NS0zLjIwNCAwLTUuMzgyLS4zODUtMi4wNS0uMjU2LTMuMzMyLS42NC0xLjI4Mi0uNTEzLTEuNzk0LTEuMjgyLS41MTMtLjc3LS41MTMtMS43OTRWODQ0LjEwMnEwLTQuOTk4IDIuNTYzLTYuOTIgMi42OTEtMi4wNTEgNS42MzktMi4wNTFoMzUuMjQycTYuMjggMCAxMC4zOC4zODQgNC4yMy4yNTcgNy41NjIuNjQxIDkuNjExIDEuNjY2IDE2LjkxNiA1LjI1NSA3LjQzMyAzLjU4OCAxMi40MyA5LjA5OCA0Ljk5OSA1LjUxMSA3LjQzNCAxMi42ODggMi41NjMgNy4wNDggMi41NjMgMTUuNjM0IDAgOC4zMy0yLjMwNyAxNC45OTQtMi4xNzkgNi41MzYtNi40MDggMTEuNjYyLTQuMjI5IDQuOTk4LTEwLjEyNCA4LjcxNS01Ljg5NSAzLjcxNi0xMy4yIDYuMjggNC4xMDEgMS43OTMgNy40MzMgNC42MTMgMy4zMzIgMi42OTEgNi4xNTIgNi41MzYgMi45NDcgMy44NDQgNS41MSA4Ljg0MiAyLjU2MyA0Ljk5OCA1LjEyNiAxMS4yNzhsMTQuODY2IDM2LjUyM3ExLjc5NCA0LjYxNCAyLjMwNyA2LjUzNi41MTMgMS43OTQuNTEzIDIuODJ6TTE3NS42NSA4ODEuMTM4cTAtOS43NC00LjM1Ny0xNi40MDQtNC4zNTgtNi43OTItMTQuNjEtOS43NC0zLjIwNC0uODk2LTcuMzA1LTEuMjgtMy45NzItLjM4NS0xMC41MDgtLjM4NWgtMTguNTgzdjU1Ljg3NWgyMS41M3E4LjcxNSAwIDE0Ljk5NC0yLjA1IDYuNDA4LTIuMTggMTAuNjM3LTUuODk2IDQuMjI5LTMuODQ0IDYuMTUxLTguOTcgMi4wNS01LjEyNyAyLjA1LTExLjE1eiIgZmlsbD0iI2M4YzhjOCIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjUiIHRyYW5zZm9ybT0ibWF0cml4KDEuMDEwOTcgMCAwIC45ODkxNSAtNC4yNjkgLTc1NC4zODMpIi8+PC9zdmc+'); } -body.base .is2d piece.queen.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTI0NS4wOTEgMjQ4LjUxcTAgMi45NDgtLjM4NCA0Ljg3LS4yNTcgMi4wNS0uODk3IDMuMDc2LS42NDEgMS4xNTMtMS40MSAxLjUzOC0uNzcuMzg0LTEuNTM4LjM4NC0yLjU2MyAwLTguMzMtMi4xNzgtNS42MzktMi4wNS0xMy4wNzItNi4xNTItNy40MzMtMy45NzMtMTUuODkxLTkuNzQtOC40NTktNS43NjctMTYuNDA0LTEzLjQ1Ni02LjI4IDMuODQ1LTE1Ljg5MSA2LjY2NC05LjYxMiAyLjgyLTIyLjMgMi44Mi0xOC43MSAwLTMyLjQyMy01LjUxMS0xMy41ODQtNS41MS0yMi41NTUtMTYuMTQ4LTguODQzLTEwLjYzNy0xMy4yLTI2LjQtNC4zNTgtMTUuODkxLTQuMzU4LTM2LjM5NiAwLTE5LjczNiA0Ljc0Mi0zNS42MjcgNC43NDItMTYuMDIgMTQuMjI1LTI3LjE2OSA5LjQ4NC0xMS4yNzggMjMuNzEtMTcuMzAxIDE0LjIyNS02LjE1MiAzMy4xOTItNi4xNTIgMTcuODEzIDAgMzEuMjcgNS41MTEgMTMuNTg0IDUuNTEgMjIuNjgzIDE2LjE0OCA5LjIyNyAxMC41MDkgMTMuODQgMjYuMDE1IDQuNjE0IDE1LjUwNyA0LjYxNCAzNS42MjggMCAxMC4zOC0xLjI4MSAxOS44NjQtMS4xNTQgOS40ODMtMy44NDUgMTcuOTQxLTIuNTYzIDguNDU5LTYuNTM2IDE1LjYzNS0zLjk3MyA3LjE3Ny05LjM1NSAxMi45NDQgOS4zNTUgNy42OSAxNi40MDQgMTIuMDQ3IDcuMDQ4IDQuMjI5IDExLjY2MiA2LjQwOCA0LjYxNCAyLjE3OCA3LjE3NyAzLjA3NSAyLjU2MyAxLjAyNiAzLjg0NCAyLjE3OSAxLjI4MiAxLjI4MSAxLjc5NSAzLjQ2LjUxMiAyLjMwNy41MTIgNi4wMjN6bS00My41NzMtOTguMDM5cTAtMTQuMDk3LTIuNTYzLTI2LjE0My0yLjQzNS0xMi4wNDctOC4zMy0yMC44OS01Ljc2Ny04Ljk3LTE1LjUwNy0xMy45NjktOS43NC00Ljk5OC0yNC4wOTMtNC45OTh0LTI0LjA5MyA1LjM4M3EtOS43NCA1LjI1NC0xNS44OTIgMTQuMzUzLTYuMDIzIDguOTcxLTguNzE0IDIwLjg5LTIuNTYzIDExLjkxOC0yLjU2MyAyNS4yNDYgMCAxNC42MSAyLjQzNSAyNi45MTMgMi40MzUgMTIuMTc1IDguMjAyIDIxLjE0NiA1Ljc2NyA4Ljk3IDE1LjM3OCAxMy45NjkgOS43NCA0Ljg3IDI0LjM1IDQuODcgMTQuNDgxIDAgMjQuMzUtNS4zODMgOS44NjctNS4zODMgMTUuODktMTQuNDgyIDYuMDI0LTkuMjI3IDguNTg3LTIxLjI3MyAyLjU2My0xMi4xNzUgMi41NjMtMjUuNjMyeiIgZmlsbD0iI2M4YzhjOCIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjUiLz48L3N2Zz4='); } -body.base .is2d piece.king.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIwNC4zMyAyMzMuNTNxMCAxLjAyNS0uNTEyIDEuOTIyLS4zODUuNzY5LTEuNjY2IDEuMjgyLTEuMjgyLjUxMi0zLjQ2Ljc2OS0yLjE4LjM4NC01LjY0LjM4NC00LjQ4NSAwLTcuMzA0LS4zODQtMi44Mi0uMzg1LTQuMjMtMS40MS0xLjQwOS0xLjAyNS0yLjMwNi0yLjMwN2wtNjEuMDAyLTgyLjkxN3Y4Mi45MTdxMCAuODk3LS41MTMgMS43OTQtLjUxMi43Ny0xLjc5NCAxLjI4Mi0xLjI4MS4zODQtMy40Ni42NC0yLjA1LjM4NS01LjI1NC4zODUtMy4wNzYgMC01LjI1NS0uMzg0LTIuMTc5LS4yNTctMy40Ni0uNjQxLTEuMjgyLS41MTMtMS43OTQtMS4yODItLjUxMy0uODk3LS41MTMtMS43OTRWNzQuNjE2cTAtMS4wMjQuNTEzLTEuNzkzLjUxMi0uNzcgMS43OTQtMS4xNTQgMS4yODEtLjUxMiAzLjQ2LS43NjkgMi4xNzktLjM4NCA1LjI1NS0uMzg0IDMuMjAzIDAgNS4yNTQuMzg0IDIuMTc5LjI1NyAzLjQ2Ljc3IDEuMjgyLjM4NCAxLjc5NCAxLjE1My41MTMuNzY5LjUxMyAxLjc5NHY3My42OWw1OC42OTUtNzMuNjlxLjc2OS0xLjE1NCAxLjc5NC0xLjkyMiAxLjAyNi0uNzcgMi40MzUtMS4xNTQgMS41MzgtLjUxMyAzLjU4OS0uNzY5IDIuMTc4LS4yNTYgNS41MS0uMjU2dDUuMzgzLjM4NHEyLjA1LjI1NyAzLjIwNC43NyAxLjI4MS41MTIgMS42NjYgMS4yOC41MTIuNzcuNTEyIDEuNjY3IDAgMS42NjYtLjg5NyAzLjMzMi0uNzY5IDEuNjY2LTMuMDc1IDQuNjEzbC01NC45OCA2NS43NDQgNTkuMjA5IDc4LjY4OHEyLjE3OCAzLjMzMiAyLjU2MyA0LjYxMy41MTIgMS4xNTQuNTEyIDEuOTIzeiIgZmlsbD0iI2M4YzhjOCIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjUiLz48L3N2Zz4='); } -body.base .is2d piece.pawn.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGNpcmNsZSBjeD0iMTUwIiBjeT0iMTUwIiBvcGFjaXR5PSIuOTg4IiByPSI0NC45OTUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVqb2luPSJiZXZlbCIgc3Ryb2tlLXdpZHRoPSIxMC4wMSIvPjwvc3ZnPg=='); } -body.base .is2d piece.knight.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIxNC4yMzEgMjI3Ljg1OHEwIDIuNTYzLS44OTcgNC4zNTgtLjc3IDEuNzk0LTIuMTc5IDIuOTQ3LTEuMjgxIDEuMTU0LTIuOTQ3IDEuNjY2LTEuNjY2LjUxMy0zLjMzMi41MTNoLTcuMDQ5cS0zLjMzMiAwLTUuODk1LS42NC0yLjQzNS0uNzctNC43NDItMi41NjQtMi4xNzgtMS45MjItNC40ODUtNS4xMjYtMi4xNzktMy4yMDQtNC44Ny04LjIwMmwtNTIuMjg4LTk0LjMyM3EtNC4xLTcuMzA1LTguMzMtMTUuMjUtNC4xLTguMDc0LTcuNjktMTUuNjM1aC0uMjU1cS4yNTYgOS4yMjcuMzg0IDE4LjgzOS4xMjggOS42MTEuMTI4IDE5LjA5NXYxMDAuMDlxMCAuODk2LS41MTIgMS43OTQtLjUxMy43NjgtMS43OTUgMS4yODEtMS4xNTMuMzg1LTMuMjAzLjY0LTEuOTIzLjM4NS00Ljk5OS4zODUtMy4wNzUgMC01LjEyNi0uMzg0LTEuOTIyLS4yNTYtMy4wNzYtLjY0LTEuMTUzLS41MTQtMS42NjYtMS4yODItLjUxMi0uODk4LS41MTItMS43OTVWODAuNjA4cTAtNS4xMjcgMi44Mi03LjMwNSAyLjgxOS0yLjE3OSA2LjE1LTIuMTc5aDEwLjUxcTMuNzE2IDAgNi4xNTEuNjQxIDIuNTYzLjY0IDQuNDg1IDIuMTc5IDIuMDUgMS40MSAzLjg0NSA0LjEgMS45MjIgMi41NjQgNC4xMDEgNi41MzdsNDAuMjQgNzIuNzkycTMuNzE3IDYuNjY0IDcuMTc4IDEzLjA3MiAzLjQ2IDYuMjggNi42NjQgMTIuNDMgMy4yMDQgNi4xNTIgNi4yOCAxMi4xNzYgMy4yMDMgNS44OTUgNi4yNzkgMTEuOTE4aC4xMjhxLS4yNTYtMTAuMTI0LS4zODQtMjEuMDE3Vjc0Ljg0cTAtLjg5Ny41MTItMS42NjYuNTEzLS43NyAxLjY2Ni0xLjI4MiAxLjI4Mi0uNjQgMy4yMDQtLjg5NyAyLjA1LS4yNTYgNS4yNTUtLjI1NiAyLjgxOSAwIDQuODcuMjU2IDIuMDUuMjU2IDMuMjAzLjg5NyAxLjE1NC41MTMgMS42NjYgMS4yODIuNTEzLjc2OS41MTMgMS42NjZ6IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lam9pbj0iYmV2ZWwiIHN0cm9rZS13aWR0aD0iMTAiLz48L3N2Zz4='); } -body.base .is2d piece.bishop.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIwNS43OTYgMTg5LjgyNXEwIDcuODE3LTIuMDUgMTQuNDgxLTEuOTIzIDYuNTM2LTUuNTExIDExLjc5LTMuNTg5IDUuMjU1LTguNzE1IDkuMjI4LTQuOTk4IDMuOTczLTExLjQwNiA2LjY2NC02LjI4IDIuNjkxLTEzLjU4NCA0LjEwMS03LjE3NyAxLjI4Mi0xNi41MzIgMS4yODJIMTA0LjY4cS0yLjk0NyAwLTUuNjM5LTEuOTIzLTIuNTYzLTIuMDUtMi41NjMtNy4wNDhWODAuNTA4cTAtNC45OTggMi41NjMtNi45MiAyLjY5Mi0yLjA1IDUuNjQtMi4wNWgzNy42NzdxMTQuODY2IDAgMjQuMzUgMi44MTkgOS40ODMgMi44MiAxNS43NjMgOC4yMDIgNi40MDcgNS4zODIgOS42MTEgMTMuMiAzLjIwNCA3LjgxNyAzLjIwNCAxNy42ODUgMCA1Ljg5NS0xLjQxIDExLjI3OC0xLjQxIDUuMzgyLTQuMjI5IDkuOTk2LTIuNjkgNC40ODUtNi45MiA4LjA3NC00LjEwMSAzLjU4OC05LjQ4MyA1Ljg5NSA2Ljc5MiAxLjI4MSAxMi42ODcgNC43NDIgNS44OTUgMy4zMzIgMTAuMjUyIDguNTg2IDQuNDg2IDUuMjU0IDcuMDQ5IDEyLjMwMyAyLjU2MyA3LjA0OSAyLjU2MyAxNS41MDd6bS0zMy4xOTItNzQuMjAycTAtNi4wMjQtMS42NjYtMTAuODkzLTEuNjY2LTQuODctNS4yNTUtOC4yMDItMy41ODgtMy40Ni05LjM1NS01LjI1NS01Ljc2Ny0xLjc5NC0xNS4yNS0xLjc5NGgtMjIuODEydjUzLjY5N2gyNS4xMThxOC41ODcgMCAxMy44NDEtMi4xNzggNS4yNTQtMi4zMDcgOC43MTUtNi4wMjQgMy40Ni0zLjg0NCA0Ljk5OC04Ljg0MiAxLjY2Ni01LjEyNyAxLjY2Ni0xMC41MXptOS45OTYgNzUuNDgzcTAtNy40MzMtMi40MzUtMTMuMDcxLTIuMzA3LTUuNjQtNi45Mi05LjQ4NC00LjQ4Ni0zLjg0NS0xMS40MDYtNS43NjctNi43OTMtMi4wNS0xNy4xNzMtMi4wNWgtMjYuNHY1OC40MzhoMzIuMDM5cTcuNTYgMCAxMy4yLTEuNzk0IDUuNjM5LTEuNzk0IDkuODY4LTUuMjU0IDQuMzU3LTMuNTg4IDYuNzkyLTguODQzIDIuNDM1LTUuMjU0IDIuNDM1LTEyLjE3NXoiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLWxpbmVqb2luPSJiZXZlbCIgc3Ryb2tlLXdpZHRoPSIxMCIvPjwvc3ZnPg=='); } -body.base .is2d piece.rook.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIwOC44NDMgOTk3LjYzcTAgMS4wMjUtLjM4NSAxLjc5NC0uMzg0Ljc2OS0xLjY2NiAxLjI4MS0xLjI4MS41MTMtMy41ODguNzctMi4zMDcuMjU2LTYuMTUyLjI1Ni0zLjMzMiAwLTUuNTEtLjI1Ny0yLjA1LS4yNTYtMy4zMzItLjc2OS0xLjI4Mi0uNjQtMi4wNS0xLjY2Ni0uNjQxLTEuMDI1LTEuMTU0LTIuNTYzbC0xNS4yNS0zOS4wODdxLTIuNjkyLTYuNjY0LTUuNjM5LTEyLjE3NC0yLjgyLTUuNjM5LTYuNzkyLTkuNjEyLTMuOTczLTQuMS05LjM1NS02LjI4LTUuMzgzLTIuMzA2LTEyLjk0NC0yLjMwNmgtMTQuNzM4djcwLjYxM3EwIDEuMDI1LS42NCAxLjc5NC0uNTEzLjc2OS0xLjc5NCAxLjI4MS0xLjE1NC4zODUtMy4zMzIuNjQxLTIuMDUuMzg1LTUuMjU1LjM4NS0zLjIwNCAwLTUuMzgyLS4zODUtMi4wNS0uMjU2LTMuMzMyLS42NC0xLjI4Mi0uNTEzLTEuNzk0LTEuMjgyLS41MTMtLjc3LS41MTMtMS43OTRWODQ0LjEwMnEwLTQuOTk4IDIuNTYzLTYuOTIgMi42OTEtMi4wNTEgNS42MzktMi4wNTFoMzUuMjQycTYuMjggMCAxMC4zOC4zODQgNC4yMy4yNTcgNy41NjIuNjQxIDkuNjExIDEuNjY2IDE2LjkxNiA1LjI1NSA3LjQzMyAzLjU4OCAxMi40MyA5LjA5OCA0Ljk5OSA1LjUxMSA3LjQzNCAxMi42ODggMi41NjMgNy4wNDggMi41NjMgMTUuNjM0IDAgOC4zMy0yLjMwNyAxNC45OTQtMi4xNzkgNi41MzYtNi40MDggMTEuNjYyLTQuMjI5IDQuOTk4LTEwLjEyNCA4LjcxNS01Ljg5NSAzLjcxNi0xMy4yIDYuMjggNC4xMDEgMS43OTMgNy40MzMgNC42MTMgMy4zMzIgMi42OTEgNi4xNTIgNi41MzYgMi45NDcgMy44NDQgNS41MSA4Ljg0MiAyLjU2MyA0Ljk5OCA1LjEyNiAxMS4yNzhsMTQuODY2IDM2LjUyM3ExLjc5NCA0LjYxNCAyLjMwNyA2LjUzNi41MTMgMS43OTQuNTEzIDIuODJ6TTE3NS42NSA4ODEuMTM4cTAtOS43NC00LjM1Ny0xNi40MDQtNC4zNTgtNi43OTItMTQuNjEtOS43NC0zLjIwNC0uODk2LTcuMzA1LTEuMjgtMy45NzItLjM4NS0xMC41MDgtLjM4NWgtMTguNTgzdjU1Ljg3NWgyMS41M3E4LjcxNSAwIDE0Ljk5NC0yLjA1IDYuNDA4LTIuMTggMTAuNjM3LTUuODk2IDQuMjI5LTMuODQ0IDYuMTUxLTguOTcgMi4wNS01LjEyNyAyLjA1LTExLjE1eiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49ImJldmVsIiBzdHJva2Utd2lkdGg9IjEwIiB0cmFuc2Zvcm09Im1hdHJpeCgxLjAxMDk3IDAgMCAuOTg5MTUgLTQuMjY5IC03NTQuMzgzKSIvPjwvc3ZnPg=='); } -body.base .is2d piece.queen.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0ibTI0NS4wOTEgMjQ4LjUxcTAgMi45NDgtLjM4NCA0Ljg3LS4yNTcgMi4wNS0uODk3IDMuMDc2LS42NDEgMS4xNTMtMS40MSAxLjUzOC0uNzcuMzg0LTEuNTM4LjM4NC0yLjU2MyAwLTguMzMtMi4xNzgtNS42MzktMi4wNS0xMy4wNzItNi4xNTItNy40MzMtMy45NzMtMTUuODkxLTkuNzQtOC40NTktNS43NjctMTYuNDA0LTEzLjQ1Ni02LjI4IDMuODQ1LTE1Ljg5MSA2LjY2NC05LjYxMiAyLjgyLTIyLjMgMi44Mi0xOC43MSAwLTMyLjQyMy01LjUxMS0xMy41ODQtNS41MS0yMi41NTUtMTYuMTQ4LTguODQzLTEwLjYzNy0xMy4yLTI2LjQtNC4zNTgtMTUuODkxLTQuMzU4LTM2LjM5NiAwLTE5LjczNiA0Ljc0Mi0zNS42MjcgNC43NDItMTYuMDIgMTQuMjI1LTI3LjE2OSA5LjQ4NC0xMS4yNzggMjMuNzEtMTcuMzAxIDE0LjIyNS02LjE1MiAzMy4xOTItNi4xNTIgMTcuODEzIDAgMzEuMjcgNS41MTEgMTMuNTg0IDUuNTEgMjIuNjgzIDE2LjE0OCA5LjIyNyAxMC41MDkgMTMuODQgMjYuMDE1IDQuNjE0IDE1LjUwNyA0LjYxNCAzNS42MjggMCAxMC4zOC0xLjI4MSAxOS44NjQtMS4xNTQgOS40ODMtMy44NDUgMTcuOTQxLTIuNTYzIDguNDU5LTYuNTM2IDE1LjYzNS0zLjk3MyA3LjE3Ny05LjM1NSAxMi45NDQgOS4zNTUgNy42OSAxNi40MDQgMTIuMDQ3IDcuMDQ4IDQuMjI5IDExLjY2MiA2LjQwOCA0LjYxNCAyLjE3OCA3LjE3NyAzLjA3NSAyLjU2MyAxLjAyNiAzLjg0NCAyLjE3OSAxLjI4MiAxLjI4MSAxLjc5NSAzLjQ2LjUxMiAyLjMwNy41MTIgNi4wMjN6bS00My41NzMtOTguMDM5cTAtMTQuMDk3LTIuNTYzLTI2LjE0My0yLjQzNS0xMi4wNDctOC4zMy0yMC44OS01Ljc2Ny04Ljk3LTE1LjUwNy0xMy45NjktOS43NC00Ljk5OC0yNC4wOTMtNC45OTh0LTI0LjA5MyA1LjM4M3EtOS43NCA1LjI1NC0xNS44OTIgMTQuMzUzLTYuMDIzIDguOTcxLTguNzE0IDIwLjg5LTIuNTYzIDExLjkxOC0yLjU2MyAyNS4yNDYgMCAxNC42MSAyLjQzNSAyNi45MTMgMi40MzUgMTIuMTc1IDguMjAyIDIxLjE0NiA1Ljc2NyA4Ljk3IDE1LjM3OCAxMy45NjkgOS43NCA0Ljg3IDI0LjM1IDQuODcgMTQuNDgxIDAgMjQuMzUtNS4zODMgOS44NjctNS4zODMgMTUuODktMTQuNDgyIDYuMDI0LTkuMjI3IDguNTg3LTIxLjI3MyAyLjU2My0xMi4xNzUgMi41NjMtMjUuNjMyeiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49ImJldmVsIiBzdHJva2Utd2lkdGg9IjEwIi8+PC9zdmc+'); } -body.base .is2d piece.king.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjMwMCIgdmlld0JveD0iMCAwIDMwMCAzMDAiIHdpZHRoPSIzMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTIwNC4zMyAyMzMuNTNxMCAxLjAyNS0uNTEyIDEuOTIyLS4zODUuNzY5LTEuNjY2IDEuMjgyLTEuMjgyLjUxMi0zLjQ2Ljc2OS0yLjE4LjM4NC01LjY0LjM4NC00LjQ4NSAwLTcuMzA0LS4zODQtMi44Mi0uMzg1LTQuMjMtMS40MS0xLjQwOS0xLjAyNS0yLjMwNi0yLjMwN2wtNjEuMDAyLTgyLjkxN3Y4Mi45MTdxMCAuODk3LS41MTMgMS43OTQtLjUxMi43Ny0xLjc5NCAxLjI4Mi0xLjI4MS4zODQtMy40Ni42NC0yLjA1LjM4NS01LjI1NC4zODUtMy4wNzYgMC01LjI1NS0uMzg0LTIuMTc5LS4yNTctMy40Ni0uNjQxLTEuMjgyLS41MTMtMS43OTQtMS4yODItLjUxMy0uODk3LS41MTMtMS43OTRWNzQuNjE2cTAtMS4wMjQuNTEzLTEuNzkzLjUxMi0uNzcgMS43OTQtMS4xNTQgMS4yODEtLjUxMiAzLjQ2LS43NjkgMi4xNzktLjM4NCA1LjI1NS0uMzg0IDMuMjAzIDAgNS4yNTQuMzg0IDIuMTc5LjI1NyAzLjQ2Ljc3IDEuMjgyLjM4NCAxLjc5NCAxLjE1My41MTMuNzY5LjUxMyAxLjc5NHY3My42OWw1OC42OTUtNzMuNjlxLjc2OS0xLjE1NCAxLjc5NC0xLjkyMiAxLjAyNi0uNzcgMi40MzUtMS4xNTQgMS41MzgtLjUxMyAzLjU4OS0uNzY5IDIuMTc4LS4yNTYgNS41MS0uMjU2dDUuMzgzLjM4NHEyLjA1LjI1NyAzLjIwNC43NyAxLjI4MS41MTIgMS42NjYgMS4yOC41MTIuNzcuNTEyIDEuNjY3IDAgMS42NjYtLjg5NyAzLjMzMi0uNzY5IDEuNjY2LTMuMDc1IDQuNjEzbC01NC45OCA2NS43NDQgNTkuMjA5IDc4LjY4OHEyLjE3OCAzLjMzMiAyLjU2MyA0LjYxMy41MTIgMS4xNTQuNTEyIDEuOTIzeiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49ImJldmVsIiBzdHJva2Utd2lkdGg9IjEwIi8+PC9zdmc+'); } diff --git a/public/stylesheets/piece/merida.css b/public/stylesheets/piece/merida.css deleted file mode 100644 index 1848401705..0000000000 --- a/public/stylesheets/piece/merida.css +++ /dev/null @@ -1,12 +0,0 @@ -body.base .is2d piece.pawn.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFRyYW5zZm9ybT0ibWF0cml4KDEgMCAwIC45NzMyNCAwIDEuMjQzKSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIyMS4xMyIgeDI9Ijc3Ljc2NCIgeTE9IjM3LjM0NiIgeTI9IjM3LjQ2OSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Ik0yNSA0Ni40NDhIMTEuNjA2YTEzLjEzOSAxMy4xMzkgMCAwIDEtLjk5LTUuMDQzYzAtMi45NzUuODYzLTUuNjQ0IDIuNTk4LTguMDE4IDEuNzM2LTIuMzY1IDMuOTcxLTQuMDU0IDYuNjk3LTUuMDY3YTYuODI0IDYuODI0IDAgMCAxLTIuODYxLTIuMzk4Yy0uNzM3LTEuMDcxLTEuMS0yLjI4My0xLjEtMy42MzQgMC0xLjY5LjU3NS0zLjE1NiAxLjczNS00LjM5MiAxLjE1MS0xLjI0NCAyLjU3NC0xLjk2MSA0LjI2Ny0yLjE1LTEuMzQ2LS45ODEtMi4wMTUtMi4yODMtMi4wMTUtMy44OSAwLTEuMzUxLjQ5MS0yLjUxMyAxLjQ4Mi0zLjQ3Ny45ODItLjk2NCAyLjE3Ni0xLjQ0MiAzLjU4MS0xLjQ0MiAxLjM4OSAwIDIuNTgyLjQ3OCAzLjU3MyAxLjQ0Mi45OS45NjQgMS40OSAyLjEyNiAxLjQ5IDMuNDc3IDAgMS42MDctLjY2OSAyLjkwOS0yLjAxNSAzLjg5IDEuNjkzLjE4OSAzLjExNi45MDYgNC4yNjcgMi4xNSAxLjE2IDEuMjM2IDEuNzM2IDIuNzAzIDEuNzM2IDQuMzkyIDAgMS4zNTEtLjM3MyAyLjU2My0xLjEyNiAzLjYzNGE3LjAzNiA3LjAzNiAwIDAgMS0yLjg2MiAyLjM5OGMyLjcyNiAxLjAxMyA0Ljk2MiAyLjcwMiA2LjY5NyA1LjA2NyAxLjczNiAyLjM3NCAyLjYgNS4wNDMgMi42IDguMDE4IDAgMS43MzktLjMyMiAzLjQyLS45NjYgNS4wNDN6IiBmaWxsPSIjMWYxYTE3Ii8+PHBhdGggZD0iTTI1IDQ0LjgwOGgxMi4xNzVhMTEuNzkgMTEuNzkgMCAwIDAgLjUyNS0zLjQwM2MwLTIuNTEzLS43MTEtNC43ODctMi4xNDItNi44MzEtMS40My0yLjA0NC0zLjI3Ny0zLjU1Mi01LjUyLTQuNTE2LTEuNTg0LS42Mi0xLjY0My0uNjU5LTEuNjQzLTEuNzM4IDAtLjg0OS41NTktMS40NzUgMS42NjgtMS44NzkgMS41MzMtMS4wNDYgMi4zMDMtMi40MyAyLjMwMy00LjE1MyAwLTEuMjQ0LS40MzItMi4zMjQtMS4yODctMy4yNjMtLjg2NC0uOTMxLTEuOTA1LTEuNDY3LTMuMTI0LTEuNjE1LTEtLjA4My0xLjQ5LS42MjYtMS40OS0xLjY0IDAtLjQ1My4xNzgtLjg3My41NDItMS4yNi44OTctLjY3NiAxLjM0Ni0xLjU1OCAxLjM0Ni0yLjY1NCAwLS44OTgtLjMzOS0xLjY3My0xLTIuMzE1LS42Ni0uNjQzLTEuNDQ3LS45NjQtMi4zNTMtLjk2NC0uOTQgMC0xLjc0NC4zMi0yLjM5Ni45NjRhMy4xMzYgMy4xMzYgMCAwIDAtLjk3NCAyLjMxNWMwIDEuMDguNDQgMS45NjEgMS4zMzggMi42NTMuMzY0LjM1NS41NDIuNzc1LjU0MiAxLjI2MSAwIDEuMDE0LS40ODMgMS41NTctMS40NjUgMS42NGE0LjkgNC45IDAgMCAwLTMuMTMzIDEuNjE1Yy0uODU1Ljk0LTEuMjc4IDIuMDE5LTEuMjc4IDMuMjYzIDAgMS43MjIuNzcgMy4xMDcgMi4zMDMgNC4xNTMgMS4xMS40MTIgMS42NjggMS4wNDYgMS42NjggMS44NzkgMCAxLjA4LS4wNjggMS4xMTgtMS42NjggMS43MzgtMi4yNDQuOTY0LTQuMDgxIDIuNDcyLTUuNTAzIDQuNTE2LTEuNDIzIDIuMDQ0LTIuMTM0IDQuMzE4LTIuMTM0IDYuODMxIDAgMS4xOTUuMTc4IDIuMzI0LjUyNSAzLjQwM3oiIGZpbGw9InVybCgjYSkiLz48L3N2Zz4='); } -body.base .is2d piece.knight.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjQwNSIgeDI9Ijc3LjY0MSIgeTE9IjM3LjM0NiIgeTI9IjM3LjM0NiI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Ik0yNi4xNzggOS4zOTVjMi42LjE3IDUuMDA0LjgzOCA3LjIyMiAyLjAxNSAyLjIxIDEuMTY5IDQuMDk4IDIuNjc2IDUuNjU2IDQuNTEzIDEuMDkyIDEuMjg3IDIuMTE3IDIuODQ1IDMuMDgyIDQuNjY1YTI4LjY4NCAyOC42ODQgMCAwIDEgMi4zMiA1Ljc3NCAzNi41MTEgMzYuNTExIDAgMCAxIDEuMjUzIDcuNDZjLjE3NyAyLjU5OS4yNjIgNS4wMTIuMjYyIDcuMjN2NS40MDJIMTUuNDY4Yy0uMTUzIDAtLjIyLS40MDctLjIxMi0xLjIxLjAwOS0uODE0LjA2LTEuNDY2LjE2LTEuOTY1LjA2LS4zOTguMjIxLS45NTcuNDY3LTEuNjg1LjI1NC0uNzI4LjY2LTEuNjA5IDEuMjQ0LTIuNjUuMjYzLS41MzQuODktMS4zMDQgMS44OC0yLjMyLjk5OS0xLjAxNiAyLjEzMy0yLjIwMSAzLjQyOS0zLjUzOS43NDUtLjc2MiAxLjMyLTEuNzE5IDEuNzQ0LTIuODc5LjQyMy0xLjE1MS42MDEtMi4yMDEuNTMzLTMuMTVhOC4zNyA4LjM3IDAgMCAxLTIuMDA2IDEuMjJjLTMuNTA1IDEuMjUzLTYuMDQ1IDMuMDczLTcuNjEyIDUuNDUyLS4xMTguMTUzLS40OS44MjItMS4xMTcgMi4wMTUtLjMzLjYyNy0uNjE4IDEuMDU5LS44NDcgMS4yODctLjMxMy4zMTQtLjc3LjQ5MS0xLjM2My41MjUtLjkyMy4wNDMtMS42NDMtLjM5OC0yLjE2LTEuMzQ2LS42OTMuMjAzLTEuMzEyLjI4OC0xLjg2Mi4yNTQtLjkyMy0uMzQ3LTEuNTkyLS43Mi0yLjAwNi0xLjExNy0uODQ3LS44NDctMS4zODktMS42ODUtMS42NTEtMi41MzJhOS40MyA5LjQzIDAgMCAxLS4zODEtMi43MjZjMC0xLjM4OS44NTUtMy4yMjYgMi41ODItNS41MTIgMi4wMTUtMi42MjUgMy4wOS00LjYzMSAzLjIxNy02LjAwMyAwLS41OTMuMDYtMS4yNjEuMTc4LTIuMDA3YTQuMTk4IDQuMTk4IDAgMCAxIC42MTgtMS40OWMuMjItLjMzLjM2NC0uNTU4LjQzMi0uNjc3LjA3Ni0uMTI3LjIxMi0uMzEzLjQxNS0uNTU5LjE0NC0uMjAzLjI3LS4zNTUuMzcyLS40NTcuMDkzLS4xMS4yMi0uMjU0LjM3My0uNDQuMTc4LS4yMTIuNDA2LS40NTcuNjk0LS43NDVhMTguMDYgMTguMDYgMCAwIDEtMS4wNjctNy40NmMzLjI4NSAxLjE2OSA2LjA1NCAzLjAxNSA4LjI4IDUuNTMuNTUxLTEuODcyIDEuNjI2LTMuMzg3IDMuMjI2LTQuNTM5IDEuMzIxLjkyMyAyLjM3MSAyLjE1IDMuMTUgMy42NjZ6IiBmaWxsPSIjMWYxYTE3Ii8+PHBhdGggZD0iTTQyLjk3NiA0NC42OTNjLS4wMTcgMCAwLS40NDkuMDQyLTEuMzQ2LjA1MS0uOTA2LjA3Ni0xLjg4LjA3Ni0yLjkyMS4wMTctMi4wNjYuMDE3LTQuMiAwLTYuNDFhMjYuODM3IDI2LjgzNyAwIDAgMC0uODg5LTYuNjEyYy0uNTY3LTIuMTE3LTEuMTg1LTMuOTItMS44NjItNS40MTktLjY3OC0xLjQ5OC0xLjQxNC0yLjc4NS0yLjIxLTMuODc4LTEuMTg1LTEuNzg2LTIuODExLTMuMzAyLTQuODYtNC41MzgtMi4wNDktMS4yNDQtNC4xOS0yLjA1Ny02LjQyNi0yLjQzOC4xNTIuODEzLjIyIDEuNjA5LjIwMyAyLjM4Ny0uMDM0LjU5My0uMzEzLjg5LS44NDcuODktLjYxIDAtLjg4LS4yOTctLjgyLS44OS4wNS0yLjE4NC0uNzI5LTQuMDU1LTIuMzMtNS42MDQtMS4yNTIgMS4zMi0xLjkzOCAyLjg1My0yLjAzMSA0LjYwNS0uMDM0LjU4NS0uMzMuODM5LS44OTguNzctLjUyNS0uMDE2LS43ODctLjMyLS43ODctLjkxNCAwIDAgLjAxNy0uMDY3LjA0Mi0uMjAzLS42NzcuMjItMS4zODguNTI1LTIuMTMzLjkyMy0uNDc0LjMzLS44NjQuMjQ2LTEuMTYtLjI0NS0uMjk3LS41LS4xNy0uODkuMzk4LTEuMTY5LjcxLS4zNjQgMS4yNDQtLjYzNSAxLjYwOC0uODIxYTE3LjYzNCAxNy42MzQgMCAwIDAtNC44Ni0zLjUyMiAxNy4zMSAxNy4zMSAwIDAgMCAxLjg4OSA2LjUyOGMuMjc5LjQyMy4yMTEuODA0LS4yMDQgMS4xMzQtLjQ2NS4zNjQtLjg1NS4zMTMtMS4xNjgtLjE3YTguODcgOC44NyAwIDAgMS0uNDkxLS44OTdjLS4zNDcuMzQ3LS41ODQuNjEtLjY5NC43Ny0uMTE5LjE1My0uMzIyLjQ4My0uNjEuOTkxLS4yODguNTE3LS41Ljk0LS42MzUgMS4yNy0uMTQ0LjQxNS0uMjEyLjc0NS0uMTg2IDEuMDA4LjAyNS4yNTQuMDUuNTMzLjA2Ny44NTVhNy42MSA3LjYxIDAgMCAxLTEuMDA3IDIuNzUyIDEzMy43MSAxMzMuNzEgMCAwIDEtMS45OTggMy4xNSAxMjcuNjA3IDEyNy42MDcgMCAwIDEtMS43ODcgMi42NzVjLS40MTUuNjAxLS43MjggMS4zNTQtLjk0IDIuMjg2LS4xNTIuNTU5LS4xNTIgMS4yNDQgMCAyLjA0LjE0NC44MDUuNDc1IDEuNDMxLjk2NiAxLjg4Ljc2Mi43NyAxLjQ5OCAxLjEyNiAyLjIxIDEuMDY3LjIyOCAwIC41NDEtLjA5My45My0uMjguMzktLjE3OC42ODctLjUyNS45MDctMS4wNDEuNDIzLS45NC43NzktMS40MTQgMS4wNjctMS40MTQuNDA2IDAgLjYzNS4yMzcuNjY4LjY5NCAwIC4xMDItLjEzNS41MTctLjM5NyAxLjI0NS0uMTUzLjMzLS4zNDguNjc3LS41OTMgMS4wNDEtLjMyMi40MzItLjQ1Ny42MS0uNDIzLjU0Mi4yNjIuOTQ4LjcwMiAxLjExIDEuMzEyLjUuMTc4LS4xNzguMzktLjUyNS42MTgtMS4wMTYuMjM3LS41LjYwMS0xLjE2OSAxLjA5Mi0yLjAwNy41ODQtLjk4MiAxLjIwMi0xLjc3IDEuODYzLTIuMzg4LjY2LS42MSAxLjI0NC0xLjEwOSAxLjc2LTEuNDgxLjI5Ny0uMjIuNjYxLS40NjYgMS4wOTMtLjc0NS40MzItLjI4OCAxLjAwOC0uNTc2IDEuNzM2LS44NzIuNTc2LS4yMjkgMS4yMTktLjUxNyAxLjkyMi0uODU2czEuMzI5LS43NyAxLjg3LTEuMzAzYy43NjMtLjc0NSAxLjM0Ny0xLjY2IDEuNzYyLTIuNzUyLjIyLS42MS4yOTYtMS4zNjMuMjQ1LTIuMjYtLjE0NC0uNTYuMTM2LS44MzkuODQ3LS44MzkuNTMzIDAgLjgzLjI3MS44OTguODIxIDAgMS44NjMtLjUzNCAzLjU2NS0xLjU5MiA1LjEwNi4zNDcgMS4wNTguNDQgMi4yMTguMjcgMy40NzEtLjE0MyAxLjAwOC0uNDk5IDIuMDkxLTEuMDUgMy4yNDMtLjU1OCAxLjE0My0xLjY3NiAyLjQyMS0zLjM2IDMuODI3LTMuNDMgMi44NDUtNS4wNDYgNS43NzQtNC44NiA4Ljc4aDEyLjE3NXpNOS4zMzggMjkuNjEzYy0uNDgzLjI5Ny0uNzcuNjk1LS44NzIgMS4xOTQuMDE3LjU0Mi0uMjM3LjgzOS0uNzYyLjg5LS41ODQuMDY3LS44OC0uMTc4LS44OTgtLjc0Ni4wNjgtMS4wOTIuNTUtMS45NTUgMS40NjUtMi41OTkuNDMyLS4zNDcuODMtLjMyMiAxLjE5NC4wOTMuMzY0LjQ0OS4zMjIuODM4LS4xMjcgMS4xNjl6bTcuMzY2LTExLjgyN2MuMjEyLjMzLjI5Ni42NzcuMjQ1IDEuMDQxLS4xNiAxLjA1OC0uNzUzIDEuNDk5LTEuNzYgMS4zMzhhMS41OTYgMS41OTYgMCAwIDEtLjcyLS4yOTZjLS4wNi4wNzYtLjE2MS4yNjItLjI5Ny41NDEtLjE3OC41MzQtLjUyNS43MTItMS4wNDEuNTUtLjUwOC0uMjAyLS43MTEtLjU3NS0uNTkzLTEuMTE3Ljc0NS0xLjkwNSAyLjA5MS0zLjIwOSA0LjAzOS0zLjkyLjU2Ny0uMTcuOTQgMCAxLjExNy40OTEuMjA0LjUzNC4wNTEuODk4LS40NDggMS4wOTJhMi43NDUgMi43NDUgMCAwIDEtLjI3MS4xMzZjLS4wODUuMDQyLS4xNy4wOTMtLjI3MS4xNDR6IiBmaWxsPSJ1cmwoI2EpIi8+PC9zdmc+'); } -body.base .is2d piece.bishop.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjEzIiB4Mj0iNzcuNjQxIiB5MT0iMzcuNTkyIiB5Mj0iMzcuNDY5Ij48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNmZmYiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iMCIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZD0iTTI1LjQ0NyA0Mi4wMDhjLS4yMjguOTQtLjUxNiAxLjU5Mi0uODQ2IDEuOTU2LS4zMy4zNjQtLjc2Mi43NDUtMS4zMTMgMS4xNDMtLjU5Mi40MTUtMS4yOTUuNzYyLTIuMTA4IDEuMDUtLjgxMy4yODgtMS43MS4zNjQtMi43LjIxMWwtNi45NjktLjk2NWEyLjg1OCAyLjg1OCAwIDAgMC0uNzYyIDBjLS4yMi4wMzQtLjQzMi4wNTEtLjYzNS4wNTEtLjM0NyAwLS43ODcuMDc2LTEuMzIuMjM3LS41NDIuMTUyLS45NTcuMzgxLTEuMjU0LjY3N2wtMi40MDQtMy45NDVjLjI5Ni0uMzMuNTU5LS41NTkuNzg3LS42OTQuMjM3LS4xMjcuNTA4LS4yNzEuODIxLS40MTVhOS4xNzkgOS4xNzkgMCAwIDEgMy4wNzQtLjgyMmMuNDY2LS4wMzMuOTIzLS4wNDIgMS4zNjMtLjAyNWE5LjggOS44IDAgMCAwIDEuMzk3LS4wNWMuODkuMTUyIDEuNzg2LjI4NyAyLjY4NC40MDYuOTA2LjEyNyAxLjgxMi4yNTQgMi43MTguMzkuOTkgMCAxLjY2LS4xMDIgMi4wMDYtLjI5Ny4xODctLjEwMi40NzQtLjI4OC44NzItLjU1LjM5OC0uMjYzLjc5Ni0uNjUyIDEuMTk0LTEuMTY5LS44OC0uMDkzLTEuNzctLjI2Mi0yLjY4NC0uNTA4YTI0LjA5NCAyNC4wOTQgMCAwIDEtMi40MDQtLjc1M2wyLjU4Mi02LjQwMWMtMS4yOTUtLjc0NS0yLjE5My0xLjMzOC0yLjcxLTEuNzk1YTUuMyA1LjMgMCAwIDEtMS4yMS0xLjU3NWMtLjQzMi0uNzYyLS43MTEtMS40OTktLjgzLTIuMjFhOS4zNDEgOS4zNDEgMCAwIDEtLjE2LTEuOTEzYy4wMTYtLjk5LjI0NS0yLjA4My43MDItMy4yODUuNDU3LTEuMTk0IDEuMzEyLTIuMjcgMi41NjYtMy4yMWE3OS4wOTEgNzkuMDkxIDAgMCAwIDMuMDU2LTIuNDU1IDI3Ljc0NiAyNy43NDYgMCAwIDAgMi45NDYtMi45NTRjLTEuMjE5LS42MjctMS44MjgtMS42MjYtMS44MjgtMi45OTggMC0uOTMuMzIxLTEuNzE4Ljk3My0yLjM4Ny42NTItLjY2IDEuNDU3LS45OSAyLjM5Ni0uOTkuOTIzIDAgMS43Mi4zMyAyLjM4Ljk5LjY2LjY2OS45OSAxLjQ1Ni45OSAyLjM4NyAwIDEuMzU1LS42MSAyLjM1NC0xLjgyOSAyLjk5OGEyNi43OTYgMjYuNzk2IDAgMCAwIDIuOTEzIDIuOTU0Yy45ODIuODM5IDIuMDE1IDEuNjYgMy4wOSAyLjQ1NiAxLjIzNi45NCAyLjA4MyAyLjAxNSAyLjUyMyAzLjIwOS40NDkgMS4yMDIuNjk0IDIuMjk0LjcyIDMuMjg1IDAgLjU2Ny0uMDUgMS4yMDItLjE3IDEuOTEzcy0uMzggMS40NDgtLjc5NSAyLjIxYTYuMDg0IDYuMDg0IDAgMCAxLTEuMjUzIDEuNTc1Yy0uNS40NTctMS4zODkgMS4wNS0yLjY2NyAxLjc5NWwyLjU4MiA2LjRhMjguNTcgMjguNTcgMCAwIDEtMi40NTUuNzU0Yy0uOTE1LjI0Ni0xLjc4Ny40MTUtMi42MzQuNTA4LjM4MS41MTcuNzcxLjkwNiAxLjE2OSAxLjE2OC4zOTguMjYzLjY5NC40NS44OTcuNTUuMzQ3LjE5NiAxLjAxNi4yOTcgMi4wMDcuMjk3YTI2My4zNSAyNjMuMzUgMCAwIDEgMi42OTItLjM5IDgxLjEzIDgxLjEzIDAgMCAwIDIuNzE4LS40MDZjLjQ0LjA1MS44OS4wNjggMS4zNDYuMDUxYTEzLjEyIDEzLjEyIDAgMCAxIDEuNDA2LjAyNSA5LjYyNyA5LjYyNyAwIDAgMSAzLjA3My44MjJjLjI5Ny4xNDQuNTY3LjI4OC44MDUuNDE1LjI0NS4xMzUuNTA4LjM2NC44MDQuNjk0bC0yLjQzIDMuOTQ1Yy0uMjk2LS4yOTYtLjcxMS0uNTI1LTEuMjUzLS42NzctLjUzNC0uMTYtLjk2NS0uMjM3LTEuMjk2LS4yMzctLjIyIDAtLjQ0LS4wMTctLjY2LS4wNWEyLjc5NCAyLjc5NCAwIDAgMC0uNzUzIDBsLTYuOTUyLjk2NGMtLjk5LjE1My0xLjkxMy4wODUtMi43Ni0uMTk0LS44NTUtLjI4LTEuNTU4LS42NTItMi4xLTEuMTE4YTIwLjA0IDIwLjA0IDAgMCAxLTEuMzAzLTEuMTUxYy0uMzIyLS4zMjItLjU5My0uOTU3LS44MDUtMS44OTd6IiBmaWxsPSIjMWYxYTE3Ii8+PHBhdGggZD0iTTI2LjMyIDM5LjE5N2MwIDEuMDkyLjI0NSAyLjAyNC43NTMgMi43OTQuNS43NyAxLjA0MSAxLjM3MiAxLjYyNiAxLjc5NS45MDUuNjY5IDIuMjM1IDEgMy45ODcgMSAuNDMyIDAgMS4yNzktLjA5NCAyLjUzMi0uMjhhNzQuNzM3IDc0LjczNyAwIDAgMSAyLjQ4LS4zNTZjLjYyNy0uMDc2IDEuMDUtLjEzNSAxLjI3LS4xODZhNi41MyA2LjUzIDAgMCAxIDEuOTgyLjA1Yy4yNjIuMDY4LjU1OS4xMjguODguMTg3YTEuNiAxLjYgMCAwIDEgLjgwNS4zOGwxLjE5NC0xLjkzYTcuMzcyIDcuMzcyIDAgMCAwLTIuMTYtLjcyYy0xLjI1Mi0uMjItMi4zNTMtLjI2Mi0zLjMwMS0uMTUxLS4yOC4wMzMtLjY0NC4xMTgtMS4xMDEuMjQ1LS40NTcuMTM2LTEuMDY3LjI2My0xLjg0Ni4zNzItMS42NzYuMjcyLTIuNTU3LjM5OS0yLjY1OC4zOTktLjY0NCAwLTEuMjAzLS4wNzctMS42ODUtLjI0NmExMC4zNyAxMC4zNyAwIDAgMS0xLjI4Ny0uNTQyYy0uODgtLjM5OC0xLjc3LTEuMzM4LTIuNjg0LTIuODF6bS0xLjc2MiAwaC0uNzk1Yy0uOTMyIDEuNDktMS44MTIgMi40My0yLjY1OSAyLjgxMS0uMzk4LjE5NS0uODMuMzczLTEuMzEyLjU0Mi0uNDgzLjE3LTEuMDMzLjI0Ni0xLjY2LjI0Ni0uMTE4IDAtLjk5OS0uMTI3LTIuNjU4LS4zOTgtLjc4OC0uMTEtMS40MjMtLjIzOC0xLjg4LS4zNzNhOC44MjggOC44MjggMCAwIDAtMS4wOTItLjI0NWMtLjk0OC0uMTEtMi4wNC0uMDY4LTMuMzAyLjE1MmE3LjA1NiA3LjA1NiAwIDAgMC0yLjEzNC43MmwxLjE5NCAxLjkzYy4xOTUtLjE5NS40NTctLjMyMi43NzktLjM4MS4zMjItLjA2LjYxOC0uMTE5Ljg4LS4xODZhNi41MyA2LjUzIDAgMCAxIDEuOTgyLS4wNTFjLjIyLjA1LjY0My4xMSAxLjI3LjE4Ni42MjYuMDc2IDEuNDY1LjE5NSAyLjUwNi4zNTYgMS4yMzYuMTg2IDIuMDgzLjI4IDIuNTMxLjI4IDEuNzM2IDAgMy4wNjUtLjMzMSAzLjk4OC0xIC41NjctLjQyMyAxLjEtMS4wMjQgMS42LTEuNzk1LjUwOC0uNzcuNzYyLTEuNzAyLjc2Mi0yLjc5NHptLjg5LTkuMzQ3YzEuNiAwIDMuMTQuMTI3IDQuNjE0LjM3MiAxLjYxNy0uNTc1IDIuNzk0LTEuNDgxIDMuNTIyLTIuN2E2Ljc0NSA2Ljc0NSAwIDAgMCAuOTQtMy40OTdjMC0uNzYyLS4xODctMS42LS41NjgtMi41MjMtLjM4LS45MTUtLjk5OS0xLjc0NC0xLjg2Mi0yLjQ5LS45NzQtLjgxMi0yLjA0LTEuNzAxLTMuMi0yLjY2NmEzMy4wOTMgMzMuMDkzIDAgMCAxLTMuNDQ3LTMuMzg3Yy0xLjE2IDEuMjg3LTIuMzExIDIuNDIxLTMuNDcgMy4zODdhNDA2LjU1IDQwNi41NSAwIDAgMC0zLjE3NiAyLjY2N2MtLjg4Ljc0NS0xLjQ5OSAxLjU3NC0xLjg3MSAyLjQ4OS0uMzczLjkyMy0uNTU5IDEuNzYtLjU1OSAyLjUyMyAwIDEuMjcuMzA1IDIuNDM4LjkxNCAzLjQ5Ny43MTIgMS4yMTkgMS44OTcgMi4xMjUgMy41NDggMi43YTI3Ljc0OSAyNy43NDkgMCAwIDEgNC42MTQtLjM3MnptMCA0LjUxM2MxLjkzOCAwIDMuNzkzLjE5NCA1LjU3OS41NzVsLTEuMTg1LTMuMDU2YTI4LjI5NyAyOC4yOTcgMCAwIDAtNC4zOTUtLjM0N2MtMS41MDcgMC0yLjk4LjExOC00LjQxLjM0N2wtMS4xOTQgMy4wNTZjMS43NjktLjM4IDMuNjQtLjU3NSA1LjYwNC0uNTc1em0wLTIzLjUzOGMxLjEyNiAwIDEuNjg0LS41NTkgMS42ODQtMS42ODVzLS41NTktMS42OTMtMS42ODUtMS42OTMtMS42ODQuNTY3LTEuNjg0IDEuNjkzYzAgMS4xMjYuNTU4IDEuNjg1IDEuNjg0IDEuNjg1em0wIDI3LjAwOWExOC45NyAxOC45NyAwIDAgMCAzLjI4NS0uMjhjMS4wNjYtLjE5NCAyLjEtLjQyMyAzLjA5LS42ODUtMS45NC0uNTA4LTQuMDY0LS43Ny02LjM3Ni0uNzctMi4zNDUgMC00LjQ3LjI2Mi02LjM3NS43Ny45NTcuMjYyIDEuOTczLjQ5IDMuMDQ4LjY4NmExOS40NiAxOS40NiAwIDAgMCAzLjMyNy4yNzl6bS0uODktMTQuMzM0bC0yLjA2NS0uMDI2Yy0uNTYgMC0uODM5LS4yNzktLjgzOS0uODQ2IDAtLjU1OS4yOC0uODM4LjgzOS0uODM4aDIuMDY1di0yLjEzNGMwLS41NzYuMjk3LS44NzIuODktLjg3Mi41NzUgMCAuODcyLjI5Ni44NzIuODcydjIuMTM0aDIuMTMzYy41NDIgMCAuODEzLjI4LjgxMy44MzggMCAuNTY3LS4yNzEuODQ2LS44MTMuODQ2SDI2LjMydjIuMDMyYzAgLjYwMi0uMjk3Ljg5OC0uODczLjg5OC0uNTkyIDAtLjg4OS0uMjk2LS44ODktLjg5OHoiIGZpbGw9InVybCgjYSkiLz48L3N2Zz4='); } -body.base .is2d piece.rook.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjM3NiIgeDI9Ijc3LjY0MSIgeTE9IjM3LjQ2OSIgeTI9IjM3LjQ2OSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Ik0yOC40MDggOS4yMmg0LjIxNlY1LjgyNWg2Ljc5OXY5LjI5NmwtNS41MDMgNC4yNDJ2MTEuODYybDQuMjE2IDQuMjE2djUuMDhoMy43OTN2NS45MjdIOC4wNzFWNDAuNTJoMy43OTN2LTUuMDhsNC4yNDItNC4yMTZWMTkuMzYzbC01LjUwNC00LjI0MlY1LjgyNWg2Ljc3NFY5LjIyaDQuMjQyVjUuODI1aDYuNzl6IiBmaWxsPSIjMWYxYTE3Ii8+PHBhdGggZD0iTTMzLjA3MyAxNy42NzhsMy4xNS0yLjU1N2gtMjIuNDJsMy4xNzUgMi41NTd6bTcuMTk3IDI0LjUyOEg5Ljc1NnYyLjU1N0g0MC4yN3ptLTMuODQ0LTUuMDU1SDEzLjZ2My4zN2gyMi44MjZ6bS00LjIxNy0xNy43ODhIMTcuODE2djExLjg2MmgxNC4zOTN6bTUuNTA0LTUuOTI3VjcuNTFoLTMuMzk1djMuMzk1aC03LjY0NlY3LjUxaC0zLjM0NHYzLjM5NWgtNy42MlY3LjUxaC0zLjM5NXY1LjkyNnptLTEuOTE0IDIyLjAwNWwtMi41NDgtMi41MzFIMTYuOGwtMi42IDIuNTMxeiIgZmlsbD0idXJsKCNhKSIvPjwvc3ZnPg=='); } -body.base .is2d piece.queen.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjI1MyIgeDI9Ijc3LjY0MSIgeTE9IjM3LjIyNCIgeTI9IjM3LjM0NiI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Ik00NC41NDEgMTQuNzIzYy0uOTQgMC0xLjc0NC0uMzMtMi40MDQtLjk4Mi0uNjYtLjY1Mi0uOTkxLTEuNDQ4LS45OTEtMi4zOTYgMC0uOTIzLjMzLTEuNzE5Ljk5LTIuMzg4LjY2LS42NzcgMS40NjUtMS4wMDcgMi40MDUtMS4wMDcuOTMxIDAgMS43MjcuMzMgMi4zODggMS4wMDcuNjYuNjcuOTkgMS40NjUuOTkgMi4zODggMCAuOTQ4LS4zMyAxLjc0NC0uOTkgMi4zOTZhMy4yOCAzLjI4IDAgMCAxLTIuMzg4Ljk4MnptLTQuMzEgMjkuMjE5Yy0uODEyLjcxLTIuNjMzIDEuMzA0LTUuNDYgMS43ODYtMi44MjguNDc0LTYuMDg4LjcyLTkuNzcxLjcyLTMuNzUgMC03LjA1My0uMjU0LTkuODk4LS43NDUtMi44NDQtLjUtNC42NC0xLjExOC01LjM4NC0xLjg2M2wxLjU2Ni01Ljk1Mi0uNjk0LTMuODk1TDguNDA1IDMwLjIgNi4yOTcgMTQuNzc0bDEuMjEtLjQ3NCA2LjggMTEuNDU1LjE1Mi0xMy42NCAxLjY4NS0uMjk2IDUuMTgyIDEzLjcxNiAyLjc3Ni0xNC43NTdoMS43MmwyLjc3NiAxNC43MDZMMzMuNzMgMTEuODJsMS43MS4yOTYuMTUzIDEzLjY0IDYuODI0LTExLjQ4IDEuMTYuNTQxLTIuMDU4IDE1LjM1OS0yLjIxIDMuNzkzLS42OTQgMy45NDV6TTE0LjUzNSAxMS45ODhjLS45NDggMC0xLjc1Mi0uMzIxLTIuNDEzLS45NzMtLjY2LS42NTItLjk5LTEuNDU2LS45OS0yLjM5NiAwLS45MjMuMzMtMS43MTkuOTktMi4zOHMxLjQ2NS0uOTkgMi40MTMtLjk5Yy45MjMgMCAxLjcxOS4zMyAyLjM4Ljk5cy45OSAxLjQ1Ny45OSAyLjM4YzAgLjk0LS4zMyAxLjc0NC0uOTkgMi4zOTZhMy4yNjYgMy4yNjYgMCAwIDEtMi4zOC45NzN6TTUuNCAxNC43MjNjLS45NCAwLTEuNzM2LS4zMy0yLjM4OC0uOTgyLS42NTItLjY1Mi0uOTgyLTEuNDQ4LS45ODItMi4zOTYgMC0uOTIzLjMzLTEuNzE5Ljk4Mi0yLjM4OEMzLjY2NCA4LjI4IDQuNDYgNy45NSA1LjQgNy45NWMuOTQ4IDAgMS43NDQuMzMgMi40MTMgMS4wMDcuNjYuNjcuOTkgMS40NjUuOTkgMi4zODggMCAuOTQ4LS4zMyAxLjc0NC0uOTkgMi4zOTZhMy4zMjMgMy4zMjMgMCAwIDEtMi40MTMuOTgyem0xOS41NS0zLjk3Yy0uOTQgMC0xLjc0NS0uMzMtMi4zOTctLjk5MS0uNjUyLS42Ni0uOTc0LTEuNDY1LS45NzQtMi40MDUgMC0uOTMxLjMyMi0xLjcyNy45NzQtMi4zODcuNjUyLS42NiAxLjQ1Ni0uOTkgMi4zOTYtLjk5LjkyMyAwIDEuNzI3LjMzIDIuMzk2Ljk5YTMuMjMgMy4yMyAwIDAgMSAxIDIuMzg3YzAgLjk0LS4zMyAxLjc0NC0xIDIuNDA1LS42NjkuNjYtMS40NzMuOTktMi4zOTYuOTl6bTEwLjQxMyAxLjIzNWMtLjk0IDAtMS43MzYtLjMyMS0yLjM4Ny0uOTczLS42NTItLjY1Mi0uOTgzLTEuNDU2LS45ODMtMi4zOTYgMC0uOTIzLjMzLTEuNzE5Ljk4My0yLjM4czEuNDQ3LS45OSAyLjM4Ny0uOTljLjk0OCAwIDEuNzUzLjMzIDIuNDEzLjk5cy45OSAxLjQ1Ny45OSAyLjM4YzAgLjk0LS4zMyAxLjc0NC0uOTkgMi4zOTYtLjY2LjY1Mi0xLjQ2NS45NzMtMi40MTMuOTczeiIgZmlsbD0iIzFmMWExNyIgc3Ryb2tlPSIjMWYxYTE3IiBzdHJva2Utd2lkdGg9Ii4wNzYiLz48cGF0aCBkPSJNMzguMjE3IDQzLjA0NGMtMy4wMjMtMS4yNTMtNy40MTctMS44OC0xMy4xNjYtMS44OC01Ljg3NiAwLTEwLjMxMy42NDQtMTMuMzI3IDEuOTMxIDIuODk2IDEuMTQzIDcuMzE2IDEuNzEgMTMuMjUgMS43MSAyLjg0NSAwIDUuNDQ1LS4xNTIgNy43OTgtLjQ2NSAyLjM2My0uMzE0IDQuMTc1LS43NDUgNS40NDUtMS4yOTZ6TTI0Ljk0OSA5LjAxN2MxLjExIDAgMS42Ni0uNTYgMS42Ni0xLjY2IDAtMS4wOTItLjU1LTEuNjQyLTEuNjYtMS42NDItMS4wOTIgMC0xLjYzNC41NS0xLjYzNCAxLjY0MiAwIDEuMS41NDIgMS42NiAxLjYzNCAxLjY2em0xMi42MjQgMjQuOTc2Yy0zLjE5Mi0uODEyLTcuMzY2LTEuMjEtMTIuNTIyLTEuMjEtNS4yOTIgMC05LjUxNy40MDYtMTIuNjc1IDEuMjM2bC4zNzMgMi4zNzljMy4yMTctLjc2MiA3LjMyMy0xLjE0MyAxMi4zMDItMS4xNDMgNC45NDQgMCA4Ljk3NS4zNzIgMTIuMDk5IDEuMTE3em0uNjE4LTEuNDlsMS42MTctMi44NTNhNi40MzIgNi40MzIgMCAwIDEtMi40My40NzRjLTIuMjE4IDAtMy45ODctLjg5Ny01LjMwOC0yLjctLjk5LjgyLTIuMSAxLjIzNS0zLjMyOCAxLjIzNS0xLjU4MyAwLTIuODUzLS42MTgtMy43OTMtMS44NjItMS4wNTggMS4xNi0yLjMyIDEuNzQ0LTMuNzkzIDEuNzQ0LTEuMTk0IDAtMi4yODYtLjQwNi0zLjI3Ni0xLjIyLTEuMzg5IDEuNzctMy4xODQgMi42NS01LjM4NSAyLjY1YTcuMDU1IDcuMDU1IDAgMCAxLTIuNTA2LS40NjVsMS43MzUgMi45NzJjMy4yMS0uOTIzIDcuNjItMS4zODkgMTMuMjI1LTEuMzg5IDUuNzA3IDAgMTAuMTE4LjQ3NCAxMy4yNDIgMS40MTR6bS0xMS4xMDgtNS45MjZsLTIuMTA4LTEyLjEzMy0yLjEwOSAxMS45ODljLjA1MS0uMDM0LjE2MS0uMTE5LjM0OC0uMjU0LjM4LS43NDUuOTU2LTEuMTE4IDEuNzM1LTEuMTE4Ljg0NyAwIDEuMzg5LjM3MyAxLjYzNCAxLjExOC4xMDIuMTAxLjI3MS4yMzcuNS4zOTh6bTYuODY2LjQ3NFYxNS41NmwtNC4wOSAxMS4yNjFjLjMxNC0uMTEuNTc3LS4yNjIuNzk3LS40NC4zMy0uNDE1Ljc3OS0uNjI3IDEuMzM4LS42MjcuNjYgMCAxLjE5My4yOTcgMS41OTEuODcyLjA0My4wNjguMTAyLjEzNi4xNy4yMTIuMDY3LjA3Ni4xMzUuMTQ0LjE5NC4yMTJ6bS0xMy45MzYtLjM0N0wxNS45NSAxNS41NjJ2MTEuMzM2Yy4wNDMtLjA2Ny4xMTktLjE0NC4yMi0uMjQ1LjMzLS42OTQuODcyLTEuMDQyIDEuNjM0LTEuMDQyLjYyNyAwIDEuMTQzLjI2MyAxLjU0MS43OTYuNDQ5LjE5NS42Ny4yOTcuNjcuMjk3em0tNi4zIDEuMzg4TDguMzggMTguODlsMS4zNjMgOC4zODJjLjk0LjY2IDEuODYzLjk5IDIuNzUyLjk5LjM0NyAwIC43NTMtLjA1OSAxLjIxOS0uMTY5em0yMi4zOTUuMTE5Yy4zODEuMTE4LjgwNS4xNzggMS4yNy4xNzggMS4wMDggMCAxLjk0OC0uMzE0IDIuODI4LS45NGwxLjM2My04LjU4NXptMS40OSAxMi41NTZsLS43NDUtMi44MDNjLTMuMjQyLS43MS03LjIwNS0xLjA2Ni0xMS45MDQtMS4wNjYtNC42NDggMC04LjYxLjM1NS0xMS44NzggMS4wNjZsLS43NzEgMi44MjhjMy4wNzMtLjkzMSA3LjI5OC0xLjM4OCAxMi42NzUtMS4zODggNS4yNCAwIDkuNDQ4LjQ0OCAxMi42MjMgMS4zNjN6TTE0LjUzNSAxMC4yNTNjMS4wODQgMCAxLjYzNC0uNTQyIDEuNjM0LTEuNjM0cy0uNTUtMS42MzQtMS42MzQtMS42MzRjLTEuMTA5IDAtMS42NjguNTQyLTEuNjY4IDEuNjM0cy41NiAxLjYzNCAxLjY2OCAxLjYzNHptMjAuODI4IDBjMS4xMSAwIDEuNjY4LS41NDIgMS42NjgtMS42MzRzLS41NTktMS42MzQtMS42NjgtMS42MzRjLTEuMDgzIDAtMS42MzQuNTQyLTEuNjM0IDEuNjM0cy41NSAxLjYzNCAxLjYzNCAxLjYzNHpNNS40IDEyLjk4OGMxLjEwOSAwIDEuNjY4LS41NSAxLjY2OC0xLjY0MyAwLTEuMTEtLjU2LTEuNjYtMS42NjgtMS42Ni0xLjA4NCAwLTEuNjM0LjU1LTEuNjM0IDEuNjYgMCAxLjA5Mi41NSAxLjY0MyAxLjYzNCAxLjY0M3ptMzkuMTQxIDBjMS4wOTIgMCAxLjY0My0uNTUgMS42NDMtMS42NDMgMC0xLjExLS41NS0xLjY2LTEuNjQzLTEuNjYtMS4xIDAtMS42Ni41NS0xLjY2IDEuNjYgMCAxLjA5Mi41NiAxLjY0MyAxLjY2IDEuNjQzeiIgZmlsbD0idXJsKCNhKSIgc3Ryb2tlPSIjMWYxYTE3IiBzdHJva2Utd2lkdGg9Ii4wNzYiLz48L3N2Zz4='); } -body.base .is2d piece.king.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjM3NiIgeDI9Ijc3LjY0MSIgeTE9IjM3LjM0NiIgeTI9IjM3LjM0NiI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Ik0yNS44MjEgMTIuMDIyaC0xLjc2di0zLjI1aC0yLjA2N2MtLjU1OCAwLS44MzgtLjI3Mi0uODM4LS44MjJ2LS4wMjVjMC0uNTQyLjI4LS44MTMuODM4LS44MTNoMi4wNjZWNS4wMDRjMC0uNTg1LjI5Ny0uODcyLjg5LS44NzIuNTc1IDAgLjg3MS4yODcuODcxLjg3MnYyLjEwOGgyLjEzNGMuNTQyIDAgLjgxMy4yNy44MTMuODEzdi4wMjVjMCAuNTUtLjI3MS44MjEtLjgxMy44MjFsLTIuMTE3LjAyNnpNMTEuMDMgMzcuNzQ0bC0uODEzLTQuNjRjLS4wMTcgMC0uMDQyLS4wMzMtLjA3Ni0uMTAxLS4wODUtLjExOS0uMzIyLS4yNzEtLjcxMS0uNDU3LS4zODEtLjE5NS0uODM4LS41MTctMS4zNDYtLjk4MmE0MS45OSA0MS45OSAwIDAgMS0xLjcwMi0xLjQ5IDguNTA5IDguNTA5IDAgMCAxLTEuMS0xLjIzN0M0LjI3MyAyNy40NSAzLjcwNSAyNS43NzIgMy41OTUgMjMuOGMtLjE3LTEuODk3LjYwMS0zLjc5NCAyLjMwMy01LjY4MiAxLjcxOS0xLjg4IDQuMDQ3LTIuNzY4IDYuOTY4LTIuNjUgMS4wOTIuMDY4IDIuMzguMzMgMy44NDQuNzk2LjQ4My4xOTUuOTc0LjM5IDEuNDgyLjU3NmwxLjQ5OC41ODRjLjI2My4xMzYuNS4yNzEuNjk1LjM5OGE0LjM4IDQuMzggMCAwIDEtLjEyNy0xLjA0MWMwLTEuMjg3LjQ1Ny0yLjM4OCAxLjM4LTMuMzAyLjkxNC0uOTA2IDIuMDIzLTEuMzcyIDMuMzEtMS4zODkgMS4yODcgMCAyLjM4OC40NjYgMy4zMDIgMS4zOC45MDYuOTE1IDEuMzYzIDIuMDE1IDEuMzYzIDMuMjg1IDAgLjI2My0uMDM0LjYxLS4xMDEgMS4wNDIuMjI4LS4xNDQuNDU3LS4yNzEuNjY5LS4zNzMuNzYyLS4zMyAxLjc2LS43MiAzLjAwNS0xLjE2IDEuNDIzLS40ODIgMi43MDEtLjc1MyAzLjg0NC0uODIxIDIuOTIxLS4xMzYgNS4yNDEuNzUzIDYuOTQzIDIuNjUgMS42NjggMS44ODggMi40NDcgMy43ODUgMi4zMjggNS42ODEtLjEyNyAxLjk3My0uNzAzIDMuNjUtMS43MSA1LjAzOC0uMzMuNDQ5LS43MDMuODYzLTEuMTE4IDEuMjUzYTQwLjUgNDAuNSAwIDAgMS0xLjY2IDEuNDczYy0uNTQxLjQ2Ni0xLjAwNy43OTYtMS4zODguOTgyLS4zOC4xODYtLjYuMzQ3LS42NjkuNDU3YS4yOTQuMjk0IDAgMCAxLS4wNS4wNzdjLS4wMTcuMDE3LS4wMjYuMDM0LS4wMjYuMDVsLS43OTYgNC42NjYgMS42NDMgNi4xMjFjLS44My43NDUtMi42ODQgMS4zNTUtNS41NTQgMS44MzctMi44NzkuNDgzLTYuMjA2LjcyLTkuOTc0LjcyLTMuODM1IDAtNy4yMTQtLjI1NC0xMC4xMTgtLjc1NC0yLjkxMi0uNTA4LTQuNzQxLTEuMTQzLTUuNDg2LTEuODk2eiIgZmlsbD0iIzFmMWExNyIvPjxwYXRoIGQ9Ik0yNS43OTYgMjkuNTMyYzIuODQ1LjAzMyA1LjQ0NC4yMDMgNy44MDYuNTA4IDIuMzcuMzA0IDQuMjI1LjY5NCA1LjU2MyAxLjE1MWExMjYuMzIgMTI2LjMyIDAgMCAwIDIuMDU3LTEuNjUxIDEyLjAxOCAxMi4wMTggMCAwIDAgMS44NjMtMS44NDZjLjc4Ny0xLjAwNyAxLjE4NS0yLjMzNyAxLjE4NS0zLjk5NiAwLTEuNDgyLS4zNTYtMi43MjYtMS4wNjctMy43MTctMS4yNy0xLjg1NC0zLjIwOS0yLjc3Ny01LjgtMi43NzctMS41NTcgMC0zLjE0OS4zMjItNC43OTIuOTY1LTEuNDM5LjU4NC0yLjUzMSAxLjIyOC0zLjI2OCAxLjk0LTEuMzg4IDEuMzg4LTIuNDIxIDMuMTc0LTMuMDgyIDUuMzUtLjIyOC43NzktLjM2NCAxLjQ5LS40MDYgMi4xMjUtLjA0Mi42MzUtLjA2IDEuMjg3LS4wNiAxLjk0N3ptLTEzLjI1IDYuNjk3YzMuMTQtLjc5NiA3LjMwNi0xLjE5NCAxMi41MDUtMS4xOTQgNS4wODggMCA5LjIwMy4zOCAxMi4zMjcgMS4xNDNsLjYxOC0zLjY1Yy0zLjMyNy0uODcxLTcuNjctMS4zMTItMTMuMDQ3LTEuMzEyLTUuNDEgMC05Ljc0NS40NS0xMy4wMjIgMS4zMzh6bTI1LjI5OCA0LjQxbC0uNzM3LTIuODQ0Yy0zLjI3Ni0uNzI4LTcuMzMyLTEuMDkyLTEyLjE1OC0xLjA5Mi00LjgwOSAwLTguODU2LjM2NC0xMi4xMzMgMS4wOTJsLS43ODcgMi44N2MzLjE1OC0uOTIzIDcuNDY4LTEuMzg4IDEyLjk0Ni0xLjM4OCA1LjQ0NCAwIDkuNzI4LjQ1NyAxMi44NjkgMS4zNjN6bS42NTIgMi4zMzhjLTMuMTkyLTEuMjg3LTcuNjgtMS45NC0xMy40NDUtMS45NC01Ljk4NiAwLTEwLjUxNi42NjEtMTMuNTk4IDEuOTkgMi45MTMgMS4xNTIgNy40MTcgMS43MzYgMTMuNTIyIDEuNzM2IDIuOTEyIDAgNS41NjItLjE2IDcuOTU4LS40ODMgMi40MDUtLjMyMSA0LjI1LS43NjIgNS41NjMtMS4zMDN6TTI0LjA3NyAyOS41MzJjLS4wMDgtLjY0NC0uMDM0LTEuMjg3LS4wNjgtMS45MjJzLS4xNi0xLjM0Ny0uMzcyLTIuMTI2Yy0uNjc3LTIuMjEtMS43MDItMy45OTYtMy4wODItNS4zNS0uNzExLS42OTUtMS43OTUtMS4zNDctMy4yNjgtMS45NC0xLjY4NS0uNjYtMy4yODUtLjk5LTQuNzkyLS45OS0yLjYwOCAwLTQuNTQ3LjkzMS01LjggMi44MDMtLjcxMS45OS0xLjA2NyAyLjIzNS0xLjA2NyAzLjcxNiAwIDEuNjI2LjM5OCAyLjk1NSAxLjE4NiAzLjk5Ny40ODIuNjEgMS4wOTIgMS4yMjcgMS44MzcgMS44MzcuNzQ1LjYxIDEuNDQgMS4xNjggMi4wODMgMS42NiAyLjg5NS0xLjA0MiA3LjM0LTEuNiAxMy4zNDMtMS42ODV6bS44NzItNC42MTVjLjExOS0uNDY1LjIxMi0uNzg3LjI5Ni0uOTY1LjE3LS42NDMuMzU2LTEuMTk0LjU3Ni0xLjY0My4wOTMtLjI3OS4yMzctLjYuNDMyLS45NzMuMTg2LS4zNzMuMzktLjgwNS42MS0xLjI3OS4xMjctLjI4LjI3LS42MjYuNDE1LTEuMDMzLjE1Mi0uNDA2LjMwNC0uODA0LjQ0OC0xLjIwMi4xMzYtLjMzLjIwMy0uNjg2LjIwMy0xLjA2NyAwLS44MTMtLjI5Ni0xLjQ5OC0uODcyLTIuMDY2LS41NzUtLjU3NS0xLjI3OC0uODYzLTIuMTA4LS44NjMtMS45NjQgMC0yLjk1NS45OS0yLjk1NSAyLjk1NSAwIC4zOC4wNjguNzM2LjIwMyAxLjA2Ny4zNjUgMS4wNzUuNjQ0IDEuODIuODM5IDIuMjM1LjIyLjQ3NC40MTUuOTA2LjYgMS4yNzguMTc5LjM3My4zNC42OTQuNDY2Ljk3NC4yMi41NS4zOTggMS4wOTIuNTUgMS42NDIuMDM1LjA5NC4xMjguNDE1LjI5Ny45NHoiIGZpbGw9InVybCgjYSkiLz48L3N2Zz4='); } -body.base .is2d piece.pawn.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZD0iTTI1IDQ2LjQ0OEgxMS42MDZhMTMuMTM5IDEzLjEzOSAwIDAgMS0uOTktNS4wNDNjMC0yLjk3NS44NjMtNS42NDQgMi41OTgtOC4wMTggMS43MzYtMi4zNjUgMy45NzEtNC4wNTQgNi42OTctNS4wNjdhNi44MjQgNi44MjQgMCAwIDEtMi44NjEtMi4zOThjLS43MzctMS4wNzEtMS4xLTIuMjgzLTEuMS0zLjYzNCAwLTEuNjkuNTc1LTMuMTU2IDEuNzM1LTQuMzkyIDEuMTUxLTEuMjQ0IDIuNTc0LTEuOTYxIDQuMjY3LTIuMTUtMS4zNDYtLjk4MS0yLjAxNS0yLjI4My0yLjAxNS0zLjg5IDAtMS4zNTEuNDkxLTIuNTEzIDEuNDgyLTMuNDc3Ljk4Mi0uOTY0IDIuMTc2LTEuNDQyIDMuNTgxLTEuNDQyIDEuMzg5IDAgMi41ODIuNDc4IDMuNTczIDEuNDQyczEuNDkgMi4xMjYgMS40OSAzLjQ3N2MwIDEuNjA3LS42NjkgMi45MDktMi4wMTUgMy44OSAxLjY5My4xODkgMy4xMTYuOTA2IDQuMjY3IDIuMTUgMS4xNiAxLjIzNiAxLjczNiAyLjcwMyAxLjczNiA0LjM5MiAwIDEuMzUxLS4zNzMgMi41NjMtMS4xMjYgMy42MzRhNy4wMzYgNy4wMzYgMCAwIDEtMi44NjIgMi4zOThjMi43MjYgMS4wMTMgNC45NjIgMi43MDIgNi42OTcgNS4wNjcgMS43MzYgMi4zNzQgMi42IDUuMDQzIDIuNiA4LjAxOCAwIDEuNzM5LS4zMjIgMy40Mi0uOTY2IDUuMDQzeiIgZmlsbD0iIzFmMWExNyIvPjwvc3ZnPg=='); } -body.base .is2d piece.knight.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjI1MyIgeDI9Ijc3LjY0MSIgeTE9IjM3LjU5MiIgeTI9IjM3LjQ2OSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Ik0yNi4xNzggOS4zOTVjMi42LjE3IDUuMDA0LjgzOCA3LjIyMiAyLjAxNSAyLjIxIDEuMTY5IDQuMDk4IDIuNjc2IDUuNjU2IDQuNTEzIDEuMDkyIDEuMjg3IDIuMTE3IDIuODQ1IDMuMDgyIDQuNjY1YTI4LjY4NCAyOC42ODQgMCAwIDEgMi4zMiA1Ljc3NCAzNi41MTEgMzYuNTExIDAgMCAxIDEuMjUzIDcuNDZjLjE3NyAyLjU5OS4yNjIgNS4wMTIuMjYyIDcuMjN2NS40MDJIMTUuNDY4Yy0uMTUzIDAtLjIyLS40MDctLjIxMi0xLjIxLjAwOS0uODE0LjA2LTEuNDY2LjE2LTEuOTY1LjA2LS4zOTguMjIxLS45NTcuNDY3LTEuNjg1LjI1NC0uNzI4LjY2LTEuNjA5IDEuMjQ0LTIuNjUuMjYzLS41MzQuODktMS4zMDQgMS44OC0yLjMyLjk5OS0xLjAxNiAyLjEzMy0yLjIwMSAzLjQyOS0zLjUzOS43NDUtLjc2MiAxLjMyLTEuNzE5IDEuNzQ0LTIuODc5LjQyMy0xLjE1MS42MDEtMi4yMDEuNTMzLTMuMTVhOC4zNyA4LjM3IDAgMCAxLTIuMDA2IDEuMjJjLTMuNTA1IDEuMjUzLTYuMDQ1IDMuMDczLTcuNjEyIDUuNDUyLS4xMTguMTUzLS40OS44MjItMS4xMTcgMi4wMTUtLjMzLjYyNy0uNjE4IDEuMDU5LS44NDcgMS4yODctLjMxMy4zMTQtLjc3LjQ5MS0xLjM2My41MjUtLjkyMy4wNDMtMS42NDMtLjM5OC0yLjE2LTEuMzQ2LS42OTMuMjAzLTEuMzEyLjI4OC0xLjg2Mi4yNTQtLjkyMy0uMzQ3LTEuNTkyLS43Mi0yLjAwNi0xLjExNy0uODQ3LS44NDctMS4zODktMS42ODUtMS42NTEtMi41MzJhOS40MyA5LjQzIDAgMCAxLS4zODEtMi43MjZjMC0xLjM4OS44NTUtMy4yMjYgMi41ODItNS41MTIgMi4wMTUtMi42MjUgMy4wOS00LjYzMSAzLjIxNy02LjAwMyAwLS41OTMuMDYtMS4yNjEuMTc4LTIuMDA3YTQuMTk4IDQuMTk4IDAgMCAxIC42MTgtMS40OWMuMjItLjMzLjM2NC0uNTU4LjQzMi0uNjc3LjA3Ni0uMTI3LjIxMi0uMzEzLjQxNS0uNTU5LjE0NC0uMjAzLjI3LS4zNTUuMzcyLS40NTcuMDkzLS4xMS4yMi0uMjU0LjM3My0uNDQuMTc4LS4yMTIuNDA2LS40NTcuNjk0LS43NDVhMTguMDYgMTguMDYgMCAwIDEtMS4wNjctNy40NmMzLjI4NSAxLjE2OSA2LjA1NCAzLjAxNSA4LjI4IDUuNTMuNTUxLTEuODcyIDEuNjI2LTMuMzg3IDMuMjI2LTQuNTM5IDEuMzIxLjkyMyAyLjM3MSAyLjE1IDMuMTUgMy42NjZ6IiBmaWxsPSIjMWYxYTE3Ii8+PHBhdGggZD0iTTE1LjY4OCAxNy43ODZsLjU0Mi0uMjhjLjUtLjE5NC42NTItLjU1OS40NzQtMS4wOTItLjE5NS0uNDkxLS41NzYtLjY2LTEuMTQzLS40OTEtMS45NDcuNzExLTMuMjk0IDIuMDE1LTQuMDM5IDMuOTItLjExOC41NDIuMDc2LjkxNC41OTMgMS4xMTguNTE2LjE2Ljg2NC0uMDE3IDEuMDQxLS41NS4xMzYtLjI4LjIyOS0uNDY2LjI5Ny0uNTQzLjE4Ni4xNDQuNDIzLjI0Ni43Mi4yOTcgMS4wMDcuMTYgMS42LS4yOCAxLjc2LTEuMzM4YTEuNDk4IDEuNDk4IDAgMCAwLS4yNDUtMS4wNDF6TTExLjU3MyAzNC41NWMuMDYtLjE1My4xNy0uMzczLjMyMi0uNjcuMjgtLjY5My40MTUtMS4xMDguNDE1LTEuMjQ0LS4wMjYtLjQ1Ny0uMjcxLS42OTQtLjcyLS42OTQtLjMzIDAtLjcxMS40NzQtMS4xNiAxLjQxNGEuOTcuOTcgMCAwIDEtLjI5Ni4zNDdjLS40NDkuNDY2LS4zODEuODU1LjE5NCAxLjE2OC41MzQuMzE0Ljk0LjIxMiAxLjI0NS0uMzIxem0xNC42My05LjIwNGMxLjE2LTEuNTI0IDEuNzI4LTMuMjE3IDEuNzEtNS4wOC0uMDY3LS41NS0uMzgtLjgyLS45NC0uODItLjc2MSAwLTEuMDU3LjI3OS0uODk3LjgzNy4wNTEuOTE1LS4wMzMgMS42NjgtLjI3IDIuMjYxLS4zODIuOTQtLjgwNSAxLjY0My0xLjI2MiAyLjEwOC0uMjU0LjUtLjEwMi44NjQuNDQ5IDEuMDkyLjUyNS4yNDYuOTMxLjExOSAxLjIxLS4zOTh6TTE5LjcyNiAxMy4yNGE2Ljc5OCA2Ljc5OCAwIDAgMSAuMDUxLTEuOTNjLS45OS4xOTQtMS45MjIuNjYtMi44MDIgMS4zODgtLjUyNS4yOC0uNjUyLjY3LS4zNzMgMS4xNjkuMjguNTA4LjY3LjU5MiAxLjE2OS4yNDUuMzQ3LS4xODYuNjY5LS4zNTUuOTU2LS41MDguMjg4LS4xNi42MTgtLjI4IDEtLjM2NHptMjMuMjUgMzEuNDU0Yy0uMDE3IDAgMC0uNDQ5LjA0Mi0xLjM0Ni4xMzEtMy4xMDguMDk2LTYuMjIxLjA3Ni05LjMzYTI2LjgzNyAyNi44MzcgMCAwIDAtLjg4OS02LjYxM2MtLjg0LTMuMzEtMi4xMjQtNi40ODUtNC4wNzItOS4yOTctMi42MzQtMy44NDUtNi44MTQtNi4wMzMtMTEuMjg2LTYuOTc2LjEyNi43NjYuMDMzIDEuNTQuMDc2IDIuMzExYTI1LjgyIDI1LjgyIDAgMCAxIDQuNTM4IDIuMDMyYzQuMjQxIDIuNTU1IDYuNDE0IDcuMjc2IDcuMTk3IDExLjkzIDEuMjcyIDYuMTU0LjQ1MyAxMS41NTcuODEzIDE3LjI4OXpNOS40MzkgMzAuMTM5Yy40NzUtLjM0LjUyNS0uNzI5LjE0NC0xLjE5NC0uMzk4LS4zODEtLjgzLS40MTUtMS4zMTItLjEwMi0xLjAwNy42Ni0xLjU1IDEuNTMzLTEuNjE3IDIuNjA4LjAxNy41NDIuMzQ3LjgwNC45NzQuNzcuNTkyLS4wNS44OC0uMzU1Ljg2My0uOTIyLjEzNi0uNTI1LjQ0OS0uOTE1Ljk0OC0xLjE2eiIgZmlsbD0idXJsKCNhKSIvPjwvc3ZnPg=='); } -body.base .is2d piece.bishop.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjA5NCIgeDI9Ijc3LjY2OSIgeTE9IjM3LjEwMSIgeTI9IjM3LjQ2OSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Ik0yNSA0Mi4xNjJjLS4yMjkuOTQtLjUxNiAxLjU5Mi0uODQ3IDEuOTU2LS4zMy4zNjQtLjc2Mi43NDUtMS4zMTIgMS4xNDMtLjU5My40MTUtMS4yOTUuNzYyLTIuMTA4IDEuMDUtLjgxMy4yODgtMS43MS4zNjQtMi43MDEuMjExbC02Ljk2OC0uOTY1YTIuODU4IDIuODU4IDAgMCAwLS43NjIgMGMtLjIyLjAzNC0uNDMyLjA1MS0uNjM1LjA1MS0uMzQ3IDAtLjc4Ny4wNzYtMS4zMi4yMzctLjU0My4xNTMtLjk1OC4zODEtMS4yNTQuNjc3bC0yLjQwNS0zLjk0NWMuMjk3LS4zMy41Ni0uNTU5Ljc4OC0uNjk0LjIzNy0uMTI3LjUwOC0uMjcxLjgyMS0uNDE1YTkuMTc5IDkuMTc5IDAgMCAxIDMuMDczLS44MjFjLjQ2Ni0uMDM0LjkyMy0uMDQzIDEuMzY0LS4wMjZhOS44IDkuOCAwIDAgMCAxLjM5Ny0uMDVjLjg4OS4xNTIgMS43ODYuMjg3IDIuNjg0LjQwNi45MDUuMTI3IDEuODExLjI1NCAyLjcxNy4zOS45OTEgMCAxLjY2LS4xMDIgMi4wMDctLjI5Ny4xODYtLjEwMi40NzQtLjI4OC44NzItLjU1LjM5OC0uMjYzLjc5Ni0uNjUyIDEuMTk0LTEuMTY5LS44OC0uMDkzLTEuNzctLjI2Mi0yLjY4NC0uNTA4YTI0LjA5NCAyNC4wOTQgMCAwIDEtMi40MDUtLjc1M2wyLjU4My02LjQwMWMtMS4yOTYtLjc0NS0yLjE5My0xLjMzOC0yLjcxLTEuNzk1YTUuMyA1LjMgMCAwIDEtMS4yMS0xLjU3NWMtLjQzMi0uNzYyLS43MTItMS40OTgtLjgzLTIuMjFhOS4zNDEgOS4zNDEgMCAwIDEtLjE2LTEuOTEzYy4wMTYtLjk5LjI0NS0yLjA4My43MDItMy4yODUuNDU3LTEuMTk0IDEuMzEyLTIuMjcgMi41NjUtMy4yMDlhNzkuMDkxIDc5LjA5MSAwIDAgMCAzLjA1Ny0yLjQ1NSAyNy43NDYgMjcuNzQ2IDAgMCAwIDIuOTQ2LTIuOTU1Yy0xLjIyLS42MjctMS44MjktMS42MjYtMS44MjktMi45OTcgMC0uOTMyLjMyMi0xLjcyLjk3NC0yLjM4OC42NTItLjY2IDEuNDU2LS45OSAyLjM5Ni0uOTkuOTIzIDAgMS43MTkuMzMgMi4zOC45OS42Ni42NjkuOTkgMS40NTYuOTkgMi4zODggMCAxLjM1NC0uNjEgMi4zNTMtMS44MyAyLjk5N2EyNi43OTYgMjYuNzk2IDAgMCAwIDIuOTE0IDIuOTU1IDU2Ljc0IDU2Ljc0IDAgMCAwIDMuMDkgMi40NTVjMS4yMzYuOTQgMi4wODMgMi4wMTUgMi41MjMgMy4yMDkuNDQ5IDEuMjAyLjY5NCAyLjI5NC43MiAzLjI4NSAwIC41NjctLjA1MSAxLjIwMi0uMTcgMS45MTNzLS4zOCAxLjQ0OC0uNzk2IDIuMjFhNi4wODQgNi4wODQgMCAwIDEtMS4yNTMgMS41NzVjLS41LjQ1Ny0xLjM4OCAxLjA1LTIuNjY3IDEuNzk1bDIuNTgzIDYuNGMtLjcyOS4yNjMtMS41NS41MTctMi40NTYuNzU0LS45MTQuMjQ2LTEuNzg2LjQxNS0yLjYzMy41MDguMzgxLjUxNy43Ny45MDYgMS4xNjggMS4xNjkuMzk4LjI2Mi42OTUuNDQ4Ljg5OC41NS4zNDcuMTk1IDEuMDE2LjI5NiAyLjAwNy4yOTZhMjYzLjM1IDI2My4zNSAwIDAgMSAyLjY5Mi0uMzkgODEuMTMgODEuMTMgMCAwIDAgMi43MTgtLjQwNmMuNDQuMDUxLjg4OS4wNjggMS4zNDYuMDUxYTEzLjEyIDEzLjEyIDAgMCAxIDEuNDA1LjAyNiA5LjYyNyA5LjYyNyAwIDAgMSAzLjA3NC44MmMuMjk2LjE0NS41NjcuMjg5LjgwNC40MTYuMjQ2LjEzNS41MDguMzY0LjgwNC42OTRsLTIuNDMgMy45NDVjLS4yOTYtLjI5Ni0uNzEtLjUyNC0xLjI1My0uNjc3LS41MzMtLjE2LS45NjUtLjIzNy0xLjI5NS0uMjM3LS4yMiAwLS40NC0uMDE3LS42Ni0uMDVhMi43OTQgMi43OTQgMCAwIDAtLjc1NCAwbC02Ljk1Ljk2NGMtLjk5Mi4xNTMtMS45MTQuMDg1LTIuNzYxLS4xOTQtLjg1NS0uMjgtMS41NTgtLjY1Mi0yLjEtMS4xMTgtLjU0Mi0uNDQ5LS45ODItLjgzLTEuMzA0LTEuMTUxLS4zMjEtLjMyMi0uNTkyLS45NTctLjgwNC0xLjg5N3oiIGZpbGw9IiMxZjFhMTciLz48cGF0aCBkPSJNMjQuMDg2IDIzLjcwNXYyLjEwOGMwIC42MS4zMDQuOTE0LjkxNC45MTQuNjEgMCAuOTE0LS4zMDQuOTE0LS45MTR2LTIuMTM0aDIuMjM2Yy41NzUgMCAuODcyLS4yOTYuODcyLS44OTcgMC0uNTkzLS4yOTctLjg4OS0uODcyLS44ODloLTIuMjM2di0yLjIzNWMwLS42MS0uMzA0LS45MTUtLjkxNC0uOTE1LS42MSAwLS45MTQuMzA1LS45MTQuOTE1djIuMjM1SDIxLjljLS41ODQgMC0uODcyLjI5Ni0uODcyLjg4OSAwIC42MDEuMjg4Ljg5Ny44NzIuODk3em03LjUxIDEzLjc0MWwtMS4wNDItMi41MzFjLTEuNjg1LS4zNjQtMy41MzktLjU0Mi01LjU1NC0uNTQyLTEuOTk4IDAtMy44MzUuMTc4LTUuNTAzLjU0MmwtMS4wNDIgMi41MDZjMi4wNS0uNTE3IDQuMjM0LS43NyA2LjU0NS0uNzcgMi4yODYgMCA0LjQ3OS4yNjIgNi41OTYuNzk1em0tMi4wODMtNS4xMTRsLS43Mi0xLjczNXYtLjY3YTI3LjAzIDI3LjAzIDAgMCAwLTMuNzkzLS4yNyAyNy4zNSAyNy4zNSAwIDAgMC0zLjc2OC4yN2wtLjAyNS42Ny0uNjY5IDEuNzM1QTI1Ljg1IDI1Ljg1IDAgMCAxIDI1IDMxLjk2YzEuNTkyIDAgMy4wOS4xMjcgNC41MTMuMzcyem0tLjg2NCA5LjM4MWMtLjY2LS41LTEuMzMtMS4yODctMS45OS0yLjM2MmgtLjc4N2MwIC44MTMuMTg2IDEuNi41NjcgMi4zNjJ6bS01LjExNCAwYy4zODEtLjgxMi41NzYtMS42LjU3Ni0yLjM2MmgtLjc5NmMtLjY0MyAxLjA1OS0xLjMxMiAxLjg0Ni0yLjAxNSAyLjM2MnoiIGZpbGw9InVybCgjYSkiLz48L3N2Zz4='); } -body.base .is2d piece.rook.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjE5MiIgeDI9Ijc3LjczNiIgeTE9IjM3LjU1MiIgeTI9IjM3LjQyOSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmZmIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZmZmIiBzdG9wLW9wYWNpdHk9IjAiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Ik0yOC40MDggOS4yMmg0LjIxNlY1LjgyNWg2Ljc5OXY5LjI5NmwtNS41MDMgNC4yNDJ2MTEuODYybDQuMjE2IDQuMjE2djUuMDhoMy43OTN2NS45MjdIOC4wNzFWNDAuNTJoMy43OTN2LTUuMDhsNC4yNDItNC4yMTZWMTkuMzYzbC01LjUwNC00LjI0MlY1LjgyNWg2Ljc3NFY5LjIyaDQuMjQyVjUuODI1aDYuNzl6IiBmaWxsPSIjMWYxYTE3Ii8+PHBhdGggZD0iTTI1LjAxMyAzNS4wNDNoLTEwLjI3TDEzLjYgMzYuMTF2MS40NGgyMi44MjZ2LTEuNDRsLTEuMTQzLTEuMDY3ek0xMy42IDQwLjEyM3YyLjUzMmgyMi44MjZ2LTIuNTMyek0yNS4wMTMgMTMuMDRoLTEyLjd2MS4xNDJsMS44MTIgMS4zNjRoMjEuODAxbDEuNzYxLTEuMzY0VjEzLjA0em0wIDQuMTloLTguNjc5bDEuNDgyIDEuMTY5djEuNDE0aDE0LjM5M3YtMS40MTRsMS40ODItMS4xNjh6bTAgMTMuNTQ3aC03LjE5N3YxLjE0M2wtMS40ODIgMS40NGgxNy4zNTdsLTEuNDgyLTEuNDR2LTEuMTQzeiIgZmlsbD0idXJsKCNhKSIvPjwvc3ZnPg=='); } -body.base .is2d piece.queen.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjI1MyIgeDI9Ijc3Ljc2NCIgeTE9IjM3LjIyNCIgeTI9IjM3LjM2Ij48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNmZmYiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iMCIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZD0iTTI0Ljk1IDEwLjc1MmMtLjk0IDAtMS43NDUtLjMzLTIuMzk3LS45OS0uNjUyLS42Ni0uOTc0LTEuNDY1LS45NzQtMi40MDUgMC0uOTMxLjMyMi0xLjcyNy45NzQtMi4zODcuNjUyLS42NiAxLjQ1Ni0uOTkgMi4zOTYtLjk5LjkyMyAwIDEuNzI3LjMzIDIuMzk2Ljk5YTMuMjMgMy4yMyAwIDAgMSAxIDIuMzg3YzAgLjk0LS4zMyAxLjc0NC0xIDIuNDA1LS42NjkuNjYtMS40NzMuOTktMi4zOTYuOTl6bTE1LjI4MSAzMy4xOWMtLjgxMi43MS0yLjYzMyAxLjMwNC01LjQ2IDEuNzg2LTIuODI4LjQ3NC02LjA4OC43Mi05Ljc3MS43Mi0zLjc1IDAtNy4wNTMtLjI1NC05Ljg5OC0uNzQ1LTIuODQ0LS41LTQuNjQtMS4xMTgtNS4zODQtMS44NjNsMS41NjYtNS45NTItLjY5NC0zLjg5NUw4LjQwNSAzMC4yIDYuMjk3IDE0Ljc3NGwxLjIxLS40NzQgNi44IDExLjQ1NS4xNTItMTMuNjQgMS42ODUtLjI5NiA1LjE4MiAxMy43MTYgMi43NzYtMTQuNzU3aDEuNzJsMi43NzYgMTQuNzA2TDMzLjczIDExLjgybDEuNzEuMjk2LjE1MyAxMy42NCA2LjgyNC0xMS40OCAxLjE2LjU0MS0yLjA1OCAxNS4zNTktMi4yMSAzLjc5My0uNjk0IDMuOTQ1ek0xNC41MzUgMTEuOTg5Yy0uOTQ4IDAtMS43NTItLjMyMi0yLjQxMy0uOTc0LS42Ni0uNjUyLS45OS0xLjQ1Ni0uOTktMi4zOTYgMC0uOTIzLjMzLTEuNzE5Ljk5LTIuMzhzMS40NjUtLjk5IDIuNDEzLS45OWMuOTIzIDAgMS43MTkuMzMgMi4zOC45OXMuOTkgMS40NTcuOTkgMi4zOGMwIC45NC0uMzMgMS43NDQtLjk5IDIuMzk2YTMuMjY2IDMuMjY2IDAgMCAxLTIuMzguOTc0em0yMC44MjggMGMtLjk0IDAtMS43MzYtLjMyMi0yLjM4Ny0uOTc0LS42NTItLjY1Mi0uOTgyLTEuNDU2LS45ODItMi4zOTYgMC0uOTIzLjMzLTEuNzE5Ljk4Mi0yLjM4czEuNDQ3LS45OSAyLjM4Ny0uOTljLjk0OCAwIDEuNzUzLjMzIDIuNDEzLjk5cy45OSAxLjQ1Ny45OSAyLjM4YzAgLjk0LS4zMyAxLjc0NC0uOTkgMi4zOTYtLjY2LjY1Mi0xLjQ2NS45NzQtMi40MTMuOTc0ek01LjQgMTQuNzIzYy0uOTQgMC0xLjczNi0uMzMtMi4zODgtLjk4Mi0uNjUyLS42NTItLjk4Mi0xLjQ0OC0uOTgyLTIuMzk2IDAtLjkyMy4zMy0xLjcxOS45ODItMi4zODhDMy42NjQgOC4yOCA0LjQ2IDcuOTUgNS40IDcuOTVjLjk0OCAwIDEuNzQ0LjMzIDIuNDEzIDEuMDA3LjY2LjY3Ljk5IDEuNDY1Ljk5IDIuMzg4IDAgLjk0OC0uMzMgMS43NDQtLjk5IDIuMzk2YTMuMzIzIDMuMzIzIDAgMCAxLTIuNDEzLjk4MnptMzkuMTQxIDBjLS45NCAwLTEuNzQ0LS4zMy0yLjQwNC0uOTgyLS42Ni0uNjUyLS45OTEtMS40NDgtLjk5MS0yLjM5NiAwLS45MjMuMzMtMS43MTkuOTktMi4zODguNjYtLjY3NyAxLjQ2NS0xLjAwNyAyLjQwNS0xLjAwNy45MzEgMCAxLjcyNy4zMyAyLjM4OCAxLjAwNy42Ni42Ny45OSAxLjQ2NS45OSAyLjM4OCAwIC45NDgtLjMzIDEuNzQ0LS45OSAyLjM5NmEzLjI4IDMuMjggMCAwIDEtMi4zODguOTgyeiIgZmlsbD0iIzFmMWExNyIvPjxwYXRoIGQ9Ik0zNy4yIDM1LjczYy0zLjA0LS44NC03LjA5NS0xLjI2Mi0xMi4xNS0xLjI2Mi01LjA5NiAwLTkuMTk0LjQzMS0xMi4zMDEgMS4yODZsLjM3MiAyLjUwN2MzLjEyNC0uODEzIDcuMDk1LTEuMjIgMTEuOTMtMS4yMiA0LjgwOSAwIDguNzI5LjM5OCAxMS43NTIgMS4xOTR6bTEuNzM2LTQuNDM3Yy0xLjM3Mi0uNS0zLjMwMi0uOTA2LTUuNzkxLTEuMjI4LTIuNDktLjMyMi01LjIzMy0uNDgzLTguMjQ3LS40ODMtMi45NDYgMC01LjYzOC4xNTMtOC4wODUuNDU4LTIuNDQ3LjMwNC00LjM3OC43MDItNS43ODMgMS4yMDJsMS4yNDUgMi4yNTJjMS4zODgtLjQwNiAzLjE5MS0uNzAzIDUuNDEtLjg5IDIuMjEtLjE3NyA0LjYzMS0uMjcgNy4yNjQtLjI3czUuMDYzLjA5MyA3LjI5LjI3YzIuMjM1LjE4NyA0LjA0Ny40OTIgNS40MzYuOTE1em0tMS4wOTIgMTEuODUzbC0uNzM3LTIuOTNjLTMuMjI2LS43MzYtNy4yODEtMS4xMDktMTIuMTU4LTEuMTA5LTQuODI2IDAtOC44NjQuMzczLTEyLjEwNyAxLjExbC0uNzg4IDIuOTU0YzMuMTQyLS45NTYgNy40NDMtMS40NCAxMi45Mi0xLjQ0IDIuNjI1IDAgNS4wNzIuMTM2IDcuMzE2LjM5OSAyLjI1Mi4yNjIgNC4xMDYuNjAxIDUuNTU0IDEuMDE2eiIgZmlsbD0idXJsKCNhKSIvPjwvc3ZnPg=='); } -body.base .is2d piece.king.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSI1MG1tIiBpbWFnZS1yZW5kZXJpbmc9Im9wdGltaXplUXVhbGl0eSIgc2hhcGUtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHRleHQtcmVuZGVyaW5nPSJnZW9tZXRyaWNQcmVjaXNpb24iIHZpZXdCb3g9IjAgMCA1MCA1MCIgd2lkdGg9IjUwbW0iIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGxpbmVhckdyYWRpZW50IGlkPSJhIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjIxLjEzIiB4Mj0iNzcuNzY0IiB5MT0iMzcuMjI0IiB5Mj0iMzcuNDY5Ij48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNmZmYiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNmZmYiIHN0b3Atb3BhY2l0eT0iMCIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZD0iTTI1LjgyMSAxMi4wMjJoLTEuNzZ2LTMuMjVoLTIuMDY3Yy0uNTU4IDAtLjgzOC0uMjcyLS44MzgtLjgyMnYtLjAyNWMwLS41NDIuMjgtLjgxMy44MzgtLjgxM2gyLjA2NlY1LjAwNGMwLS41ODUuMjk3LS44NzIuODktLjg3Mi41NzUgMCAuODcxLjI4Ny44NzEuODcydjIuMTA4aDIuMTM0Yy41NDIgMCAuODEzLjI3LjgxMy44MTN2LjAyNWMwIC41NS0uMjcxLjgyMS0uODEzLjgyMWwtMi4xMTcuMDI2ek0xMS4wMyAzNy43NDRsLS44MTMtNC42NGMtLjAxNyAwLS4wNDItLjAzMy0uMDc2LS4xMDEtLjA4NS0uMTE5LS4zMjItLjI3MS0uNzExLS40NTctLjM4MS0uMTk1LS44MzgtLjUxNy0xLjM0Ni0uOTgyYTQxLjk5IDQxLjk5IDAgMCAxLTEuNzAyLTEuNDkgOC41MDkgOC41MDkgMCAwIDEtMS4xLTEuMjM3QzQuMjczIDI3LjQ1IDMuNzA1IDI1Ljc3MiAzLjU5NSAyMy44Yy0uMTctMS44OTcuNjAxLTMuNzk0IDIuMzAzLTUuNjgyIDEuNzE5LTEuODggNC4wNDctMi43NjggNi45NjgtMi42NSAxLjA5Mi4wNjggMi4zOC4zMyAzLjg0NC43OTYuNDgzLjE5NS45NzQuMzkgMS40ODIuNTc2bDEuNDk4LjU4NGMuMjYzLjEzNi41LjI3MS42OTUuMzk4YTQuMzggNC4zOCAwIDAgMS0uMTI3LTEuMDQxYzAtMS4yODcuNDU3LTIuMzg4IDEuMzgtMy4zMDIuOTE0LS45MDYgMi4wMjMtMS4zNzIgMy4zMS0xLjM4OSAxLjI4NyAwIDIuMzg4LjQ2NiAzLjMwMiAxLjM4LjkwNi45MTUgMS4zNjMgMi4wMTUgMS4zNjMgMy4yODUgMCAuMjYzLS4wMzQuNjEtLjEwMSAxLjA0Mi4yMjgtLjE0NC40NTctLjI3MS42NjktLjM3My43NjItLjMzIDEuNzYtLjcyIDMuMDA1LTEuMTYgMS40MjMtLjQ4MiAyLjcwMS0uNzUzIDMuODQ0LS44MjEgMi45MjEtLjEzNiA1LjI0MS43NTMgNi45NDMgMi42NSAxLjY2OCAxLjg4OCAyLjQ0NyAzLjc4NSAyLjMyOCA1LjY4MS0uMTI3IDEuOTczLS43MDMgMy42NS0xLjcxIDUuMDM4LS4zMy40NDktLjcwMy44NjMtMS4xMTggMS4yNTNhNDAuNSA0MC41IDAgMCAxLTEuNjYgMS40NzNjLS41NDEuNDY2LTEuMDA3Ljc5Ni0xLjM4OC45ODItLjM4LjE4Ni0uNi4zNDctLjY2OS40NTdhLjI5NC4yOTQgMCAwIDEtLjA1LjA3N2MtLjAxNy4wMTctLjAyNi4wMzQtLjAyNi4wNWwtLjc5NiA0LjY2NiAxLjY0MyA2LjEyMWMtLjgzLjc0NS0yLjY4NCAxLjM1NS01LjU1NCAxLjgzNy0yLjg3OS40ODMtNi4yMDYuNzItOS45NzQuNzItMy44MzUgMC03LjIxNC0uMjU0LTEwLjExOC0uNzU0LTIuOTEyLS41MDgtNC43NDEtMS4xNDMtNS40ODYtMS44OTZ6IiBmaWxsPSIjMWYxYTE3Ii8+PHBhdGggZD0iTTI0Ljk1IDIwLjY3NWEyLjI5NSAyLjI5NSAwIDAgMC0uMTI4LS40MjMgNS42MDYgNS42MDYgMCAwIDAtLjI0NS0uNzJjLS4wNTEtLjExLS4xMTktLjI1NC0uMTk1LS40MzFhOS4wMjggOS4wMjggMCAwIDEtLjI1NC0uNTZjLS4wNS0uMTE4LS4xMS0uMjctLjE4Ni0uNDU2LS4wNjgtLjE5NS0uMTM2LS4zNzMtLjE4Ny0uNTM0YTEuNzM1IDEuNzM1IDAgMCAxLS4wNjctLjQ3NGMwLS44NzIuNDE1LTEuMzEyIDEuMjYxLTEuMzEyLjg4IDAgMS4zMTMuNDMxIDEuMzEzIDEuMjg3IDAgLjIyLS4wMzQuMzcyLS4wOTQuNDc0LS4yMzcuNjI2LS4zNTUuOTY1LS4zNzIgMS4wMTYtLjI1NC41LS40MDYuODIxLS40NzQuOTY1LS4xMTkuMjctLjE5NS41MDgtLjIyLjcyLS4wNTEuMTAxLS4wODUuMTg2LS4xMDIuMjYycy0uMDM0LjEzNi0uMDUuMTg2em0tMi43NzggOC41NmMtMi4wNjYuMDM0LTMuOTU0LjEzNi01LjY3My4zMjItMS43MS4xNzgtMy4wMy40NC0zLjk3OS43N2ExOC45NzMgMTguOTczIDAgMCAwLTEuNzE5LTEuODU0IDMzLjAwNyAzMy4wMDcgMCAwIDEtMS43MjctMS43NDRjLS44My0uODQ3LTEuMjM2LTEuNzctMS4yMzYtMi43NzcgMC0xLjI0NS4yMDMtMi4xNS42MTgtMi43MjYuNDQtLjY3IDEuMTM1LTEuMTYgMi4wNTgtMS40ODJhOC40ODYgOC40ODYgMCAwIDEgMi44MDItLjQ4M2MxLjE5NCAwIDIuMzI4LjI2MyAzLjQyLjc5NiAxLjA3Ni41NiAxLjc4NyAxLjAwOCAyLjEzNCAxLjMzOCAxLjEyNiAxLjE0MyAyLjAwNyAyLjM4IDIuNjMzIDMuNzE3LjIxMi41LjM3MyAxLjE5NC40ODMgMi4wNzQuMTEuODkuMTcgMS41NjcuMTg2IDIuMDV6bTIuNzc3LTQuMzE4Yy4xMTktLjQ2Ni4yMTItLjc4Ny4yOTYtLjk2NS4xNy0uNjQzLjM1Ni0xLjE5NC41NzYtMS42NDMuMDkzLS4yNzkuMjM3LS42LjQzMi0uOTczLjE4Ni0uMzczLjM5LS44MDUuNjEtMS4yNzkuMTI3LS4yOC4yNy0uNjI2LjQxNS0xLjAzMy4xNTItLjQwNi4zMDQtLjgwNC40NDgtMS4yMDIuMTM2LS4zMy4yMDMtLjY4Ni4yMDMtMS4wNjcgMC0uODEzLS4yOTYtMS40OTgtLjg3Mi0yLjA2Ni0uNTc1LS41NzUtMS4yNzgtLjg2My0yLjEwOC0uODYzLTEuOTY0IDAtMi45NTUuOTktMi45NTUgMi45NTUgMCAuMzguMDY4LjczNi4yMDMgMS4wNjYuMzY1IDEuMDc2LjY0NCAxLjgyLjgzOSAyLjIzNi4yMi40NzQuNDE1LjkwNi42IDEuMjc4LjE3OS4zNzMuMzQuNjk0LjQ2Ni45NzQuMjIuNTUuMzk4IDEuMDkyLjU1IDEuNjQyLjAzNS4wOTMuMTI4LjQxNS4yOTcuOTR6bS0uODg5IDYuMjIzYzAtLjY2LS4wMTctMS41NzUtLjA1LTIuNzM1LS4wMzQtMS4xNjgtLjE2MS0yLjE0Mi0uMzczLTIuOTItLjY3Ny0yLjIxLTEuNzAyLTMuOTk3LTMuMDgyLTUuMzUxLS43MTEtLjY5NS0xLjc5NS0xLjM0Ny0zLjI2OC0xLjk0LTEuNjg1LS42Ni0zLjI4NS0uOTktNC43OTItLjk5LTIuNjA4IDAtNC41NDcuOTMxLTUuOCAyLjgwMy0uNzExLjk5LTEuMDY3IDIuMjM1LTEuMDY3IDMuNzE2IDAgMS42MjYuMzk4IDIuOTU1IDEuMTg2IDMuOTk3LjQxNS41OTIgMS4yMSAxLjMyOSAyLjM4NyAyLjIxIDEuMTY5Ljg3MiAyLjE2OCAxLjY4NCAyLjk3MiAyLjQzIDEuNDQtLjMxNCAzLjA2NS0uNTg1IDQuODc3LS44MjIgMS44MTItLjIyOSA0LjE0OS0uMzY0IDcuMDEtLjM5OHptMTMuNzg0IDExLjczNWwtLjczNy0yLjkzYy0zLjIyNS0uNzM2LTcuMjgxLTEuMTA5LTEyLjE1OC0xLjEwOS00LjgyNiAwLTguODY0LjM3My0xMi4xMDcgMS4xMWwtLjc4NyAyLjk1NGMzLjE0LS45NTYgNy40NDItMS40MzkgMTIuOTItMS40MzkgMi42MjQgMCA1LjA3MS4xMzYgNy4zMTUuMzk4IDIuMjUyLjI2MiA0LjEwNi42MDEgNS41NTQgMS4wMTZ6bS0uNjQzLTcuNDE3Yy0zLjA0LS44MzgtNy4wOTYtMS4yNjEtMTIuMTUtMS4yNjEtNS4wOTcgMC05LjE5NS40MzEtMTIuMzAyIDEuMjg3bC4zNzIgMi41MDZjMy4xMjUtLjgxMyA3LjA5NS0xLjIyIDExLjkzLTEuMjIgNC44MDkgMCA4LjcyOS4zOTggMTEuNzUyIDEuMTk0em0tMTEuMzYzLTQuMjkyYzIuODQ1LjA1IDUuMTgyLjE5NCA3LjAwMi40MjMgMS44MTIuMjI5IDMuNDU1LjUwOCA0LjkxLjgyMS45MDctLjg5NyAxLjkxNC0xLjc0NCAzLjAyMy0yLjU1N3MxLjg4OC0xLjUwNyAyLjMzNy0yLjA4M2MuNzg4LTEuMDc1IDEuMTg2LTIuNDEzIDEuMTg2LTQuMDIxIDAtMS40NjUtLjM1Ni0yLjcwMS0xLjA2Ny0zLjY5Mi0xLjI3LTEuODctMy4yMTgtMi44MDItNS44MjUtMi44MDItMS41MjQgMC0zLjEwOC4zMy00Ljc2Ny45OS0xLjUwNy41OTMtMi41OSAxLjIzNy0zLjI3NyAxLjkzLTEuNDA1IDEuMzY0LTIuNDMgMy4xNS0zLjA3MyA1LjM2LS4yNDYuNzYyLS4zODEgMS43MjctLjQwNyAyLjkwNHMtLjA0MiAyLjA4My0uMDQyIDIuNzI3em0xLjgxMi0xLjkzYzAtLjQ4My4wNi0xLjE2LjE2LTIuMDUuMTExLS44OC4yOC0xLjU3NS41MDktMi4wNzQuNjE4LTEuMzM4IDEuNDktMi41NzQgMi42MzMtMy43MTcuMzMtLjMzIDEuMDQyLS43NzkgMi4xMzQtMS4zMzhhNy42NTUgNy42NTUgMCAwIDEgMy40NDYtLjc5NmMuOTMgMCAxLjg0NS4xNjEgMi43NjguNDgzLjkxNS4zMjIgMS42MDkuODEzIDIuMDY2IDEuNDgyLjQxNS41NTkuNjI3IDEuNDY0LjYyNyAyLjcyNiAwIC45OS0uNDA3IDEuOTEzLTEuMjIgMi43NzdhNDAuMzUgNDAuMzUgMCAwIDEtMS43MSAxLjY1MWMtLjYxLjU1LTEuMjAyIDEuMjAyLTEuNzYgMS45NDctLjk1OC0uMzMtMi4yOTUtLjU5Mi00LjAwNi0uNzctMS43MS0uMTg2LTMuNTktLjI4OC01LjY0Ny0uMzIyeiIgZmlsbD0idXJsKCNhKSIvPjwvc3ZnPg=='); } diff --git a/public/stylesheets/piece/pirouetti.css b/public/stylesheets/piece/pirouetti.css deleted file mode 100644 index c0a0efe7e2..0000000000 --- a/public/stylesheets/piece/pirouetti.css +++ /dev/null @@ -1,15 +0,0 @@ -body.base .is2d piece.pawn.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJNOTUzIDMyMzloMTkwN3YyMDRIOTUzeiIvPjxwYXRoIGQ9Ik0xMDk5IDMzODZoMTYyMXYxNTNIMTA5OXoiLz48cGF0aCBkPSJNOTUwIDM1MDZoMTkwN3YyMDRIOTUweiIvPjwvZz48cGF0aCBkPSJNMTA5OSAzNDQzaDE2MjF2NjNIMTA5OXoiIGZpbGw9IiNkMWQxZDEiLz48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJNMTY1OSAyMDU5bDI5Ni00IDEgMTI4Mi02MTgtOXoiLz48cGF0aCBkPSJNMjE0MCAyMDU5bC0yNjQtNHYxMjgybDYxNy05eiIvPjxwYXRoIGQ9Ik0xMzU1IDE5MDdoMTExNXYxNThIMTM1NXoiLz48ZWxsaXBzZSBjeD0iMTg5MCIgY3k9IjE1NDkiIHJ4PSI0MTQiIHJ5PSI0MzMiLz48L2c+PGcgZmlsbD0iI2QxZDFkMSI+PHBhdGggZD0iTTE5ODAgMTEyNnMxOTUgMTQ3IDIxOCAzNDljMzYgMzE1LTE2MiA0MTgtNDQ2IDM1MS0xNDMtMzQtMjQ0LTExMC0yMzEtODIgMCAwIDIxIDUxIDU5IDkwIDM3IDM5IDgyIDc1IDgyIDc1aDQ1N3M3NC00MSAxMTQtMTE3YzQwLTc3IDcyLTEzNyA3Mi0yNDRzLTQxLTE5OS02OC0yMzctNTYtNzEtMTA1LTExNGMtNDgtNDQtMTUyLTcxLTE1Mi03MXoiLz48cGF0aCBkPSJNMjA3NCAxOTA3bDY5IDE1OGgzMjZ2LTE1OHptLTUxNiAxNThoNTg1bDM0NiAxMjQyaC0yNTVsLTE2OC0xMDk1eiIvPjxwYXRoIGQ9Ik0yNDY2IDMyMzlsNzAgNDcxaDMyMXYtMjA0aC0xMzd2LTYzaDE0MHYtMjA0eiIvPjwvZz48L3N2Zz4='); } -body.base .is2d piece.knight.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJNODI4IDEzNzhjLTE4MyAxNjktMTMyIDE1NS02MCAyODZzMTk1IDIyNyA1MDMgNzcgMzkwLTEzMyA1MTctMTAzIDE1OSA5MSAxNjcgMTU3LTE4NiAyMjctNDAwIDQzM2MtMjE0IDIwNS00MDIgMjQzLTM3MyA2NzEgMzAgNDI4IDE5IDUyNS00MiA1OTJzMTA3NCAyNjMgMTIyMSAxOTZjMTQ3LTY4IDU0My01NSA0NjUtNDYwLTc4LTQwNi0yMDgtOTAwLTEwLTEyMzhzMzk4LTEwNDItNTI3LTE0MjMtNTU4IDM1LTY0OCA4M2MtOTAgNDctMTIxIDU3LTE3NSA4My05OCA0Ny00NjMgNDg1LTYzOSA2NDd6Ii8+PHBhdGggZD0iTTg5MCAzMjM5aDIyMTd2MjA0SDg5MHoiLz48cGF0aCBkPSJNMTA1OSAzMzg2aDE4ODV2MTUzSDEwNTl6Ii8+PHBhdGggZD0iTTg4NiAzNTA2aDIyMTd2MjA0SDg4NnoiLz48L2c+PGcgZmlsbD0iI2QxZDFkMSI+PHBhdGggZD0iTTE2MTUgMTY0NHM4NS0xMjQgMjYyLTEzMWMxNzYtNyA3NS0zMzEgNzUtMzMxczIyNyAyOTMgMjI3IDQ0NC0yMzkgMjE3LTIzOSAyMTctMzAtMTgyLTMyNC0yMDB6bTEwMDQtOTAwczQyNSAyMzggMjIxIDg0Mi01NjAgOTE1LTQ5OCAxMjI2IDkgMzY0IDMxIDM5MSA5MyAyNyAxOTUtNCA4NCA0NCA5MyA4OWM5IDQ0IDcyIDQyMSA3MiA0MjFoMzY5di0yMDRoLTE1OXYtNjNoMTYzdi0yMDRoLTI3N3MtOTUtNDQ4LTExNi03MjggNTgtNDU0IDE3MC02NTNjMTExLTIwMCAyMzEtNzc3LTI2NS0xMTEzeiIvPjxwYXRoIGQ9Ik0xMDYwIDM0NDNoMTg4NXY2M0gxMDYweiIvPjwvZz48L3N2Zz4='); } -body.base .is2d piece.bishop.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJNMTg3MCA0ODJzNjIxIDI2OSA0NTggODgzLTU3MCAyNjAtNTcwIDI2MGwxMTMtMTE0MnpNNzk4IDMyMzhoMjIxN3YyMDRINzk4eiIvPjxwYXRoIGQ9Ik05NjcgMzM4NWgxODg1djE1M0g5Njd6Ii8+PHBhdGggZD0iTTc5NCAzNTA1aDIyMTd2MjA0SDc5NHptNzg2LTE5NTJoNTk4bDUwMSAxNzA0SDExMjR6Ii8+PHBhdGggZD0iTTEyODYgMTUxMWgxMjAwdjE1MkgxMjg2eiIvPjxwYXRoIGQ9Ik0xODg1IDQ4M3MtNjIzIDI2OS00NTkgODgzIDU3MiAyNjAgNTcyIDI2MEwxODg1IDQ4NHoiLz48ZWxsaXBzZSBjeD0iMTg4MCIgY3k9IjQ0OCIgcng9IjE3NCIgcnk9IjE0MyIvPjwvZz48ZyBmaWxsPSIjZDFkMWQxIj48cGF0aCBkPSJNMTk3MCAzMjVzMzggNTEgMzggMTEzYzAgNjEtMTQgMTE4LTE0IDExOHMxNjItMTE1LTI0LTIzMXpNOTY3IDM0NDJoMTg4NXY2M0g5Njd6TTE5OTQgNTU2czIyMSAxNDQgMzAwIDMzMyA2NiAyNTkgNTAgMzk3LTY4IDIyNC02OCAyMjRoMjA5djE1MmgtMzIxbC0xNy0xNTJzLTItNDItMTItNzdjLTEwLTM2IDkzLTg1IDEwNC0yNDAgMTAtMTU1IDEtMjUzLTUzLTM2OC01My0xMTYtMTk0LTI2OS0xOTQtMjY5eiIvPjxwYXRoIGQ9Ik0xNTQxIDE2NjNoNjY5bDQ2NSAxNTc1aDM0MXYyMDRoLTE2NHY2M2gxNjB2MjA0aC00ODF2LTI2N2wtODQtMjA0LTMxMi0xNDI5eiIvPjwvZz48L3N2Zz4='); } -body.base .is2d piece.rook.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJNMTI1OSAxNjk0bDEyODMgNCAyMDkgMTU5MC0xNjg4LTIzeiIvPjxwYXRoIGQ9Ik0xMDAyIDE3NDdoMTgwMmwyMTctMTE1MS01MjQgMzF2MjgyaC0zMDdWNjM2aC01NDl2MjczaC0zMjBsLTMtMjcyLTUyMS00MXpNNzkzIDMyMzVoMjIxN3YyMDRINzkzeiIvPjxwYXRoIGQ9Ik05NjIgMzM4MmgxODg1djE1M0g5NjJ6Ii8+PHBhdGggZD0iTTc4OSAzNTAyaDIyMTd2MjA0SDc4OXoiLz48L2c+PGcgZmlsbD0iI2QxZDFkMSI+PHBhdGggZD0iTTI4NTIgNjA2cy0xNDYgOTE5LTE2OCA5ODYtOTQgMTU1LTk0IDE1NWgyMTNsMjE3LTExNTEtMTY5IDEwek0xMzg2IDE3NDdoMTE2MmwxOTUgMTQ4OGgyNjZ2MjA0bC0xNjEtM3Y2M2wxNTcgM3YyMDRoLTMxNnMtMjQtMTcxLTY3LTI2OWMtNDItOTktOTAtNzgtMTM5LTQ0NS00OS0zNjgtMTUzLTEwMjAtMTUzLTEwMjBsLTk0NS0yMjN6Ii8+PHBhdGggZD0iTTk2NCAzNDM2aDE4ODV2NjNIOTY0eiIvPjwvZz48L3N2Zz4='); } -body.base .is2d piece.queen.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJNMTQ0NSAxNjI2bDg5MiA0IDQxOSAxNjU4LTE2ODgtMjR6Ii8+PHBhdGggZD0iTTc5OCAzMjM1aDIyMTd2MjA0SDc5OHoiLz48cGF0aCBkPSJNOTY3IDMzODJoMTg4NXYxNTNIOTY3eiIvPjxwYXRoIGQ9Ik03OTQgMzUwMWgyMjE3djIwNEg3OTR6Ii8+PC9nPjxwYXRoIGQ9Ik0xNDAxIDE3NDVoOTY1bDM4MyAxNDg5aDI2NnYyMDRoLTE2MXY2MGwxNTcgM3YyMDRoLTMxNnMtMjYtMTQ5LTcxLTI2N2MtNDUtMTE3LTg1LTgwLTEzNS00NDgtNDktMzY4LTI1My0xMTE3LTI1My0xMTE3bC04MzYtMTI5eiIgZmlsbD0iI2QxZDFkMSIvPjxwYXRoIGQ9Ik05NzAgMzQzNmgxODg0djYzSDk3MHoiIGZpbGw9IiNkMWQxZDEiLz48ZyBmaWxsPSIjZmZmIj48cGF0aCBkPSJNMTA4OCAxNTI2aDE2Mzh2MjIwSDEwODh6Ii8+PHBhdGggZD0iTTEzNTIgMTU2M0w5NDkgNzk4bDQ5NyAyNjAtNDAtNjg0IDQ3OCA1NTcgMzIgNjMyeiIvPjxwYXRoIGQ9Ik0yNDE2IDE1NjNsNDAzLTc2NC00OTggMjU5IDQwLTY4My00NzggNTU2LTE4IDYzMnoiLz48Y2lyY2xlIGN4PSI5NDkiIGN5PSI3OTgiIHI9IjEwMCIvPjxjaXJjbGUgY3g9IjE0MDYiIGN5PSIzNzQiIHI9IjEwMCIvPjxjaXJjbGUgY3g9IjIzNjEiIGN5PSIzNzUiIHI9IjEwMCIvPjwvZz48ZyBmaWxsPSIjZDFkMWQxIj48Y2lyY2xlIGN4PSIyODE5IiBjeT0iNzk5IiByPSIxMDAiLz48cGF0aCBkPSJNMjQyMSAyOTVsLTk3IDE3My0yNDAgMTA1OGgzNTFsMzM3LTYzOS00Mi00Mi00MDkgMjEzIDQzLTU4NHMxODItMzIgNTctMTgwem0tMTYxIDEyMzF2MjE5aDQ2NnYtMjE5eiIvPjwvZz48L3N2Zz4='); } -body.base .is2d piece.king.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTM0MiAxNjMybDEwOTggOSAzMTYgMTY1My0xNjg4LTI0eiIgZmlsbD0iI2ZlZmVmZSIvPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Ik03OTggMzI0MWgyMjE3djIwNEg3OTh6Ii8+PHBhdGggZD0iTTk2NyAzMzg3aDE4ODV2MTUzSDk2N3oiLz48cGF0aCBkPSJNNzk0IDM1MDdoMjIxN3YyMDRINzk0eiIvPjwvZz48cGF0aCBkPSJNMTQwMSAxNzUxaDEwNjFsMjg4IDE0ODloMjY2djIwNGwtMTYxLTN2NjNsMTU3IDN2MjA0aC0zMTZzLTI2LTE0OS03MS0yNjdjLTQ1LTExNy04NS04MC0xMzUtNDQ4LTQ5LTM2OC0xNTAtMTEwMS0xNTAtMTEwMWwtOTM5LTE0NXoiIGZpbGw9IiNkMWQxZDEiLz48cGF0aCBkPSJNOTcwIDM0NDJoMTg4NHY2M0g5NzB6IiBmaWxsPSIjZDFkMWQxIi8+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0iTTEwODggMTUzMWgxNjM4djIyMEgxMDg4eiIvPjxwYXRoIGQ9Ik0xMjc4IDE2MTFzLTI0MS0zMjgtMTk5LTU3MmM1MC0yODUgMzgyLTQwOCA4NzUtNDM1IDE0OC04IDk4IDEwMDcgOTggMTAwN3oiLz48cGF0aCBkPSJNMjUxNSAxNjExczI0MS0zMjggMTk5LTU3MmMtNTAtMjg1LTM4Mi00MDgtODc1LTQzNS0xNDgtOC05OCAxMDA3LTk4IDEwMDd6Ii8+PHBhdGggZD0iTTE1NjAgNjU1czI1My02MyAyMjYtMTY5IDExNC0xOSAxMTQtMTlsMTAgMTQ2LTM1MCA0M3oiLz48cGF0aCBkPSJNMjE3MiA2NDdzLTE1NC03NS0xNTktMTYxLTExNC0xOS0xMTQtMTlsLTEwIDE0NyAyODIgMzR6Ii8+PGVsbGlwc2UgY3g9IjE3NTUiIGN5PSIyNzkiIHJ4PSI5MSIgcnk9Ijg5Ii8+PGVsbGlwc2UgY3g9IjE3ODQiIGN5PSI0MTciIHJ4PSI2NCIgcnk9IjYyIi8+PGVsbGlwc2UgY3g9IjIwMzkiIGN5PSIyNzkiIHJ4PSI5MSIgcnk9Ijg5Ii8+PGVsbGlwc2UgY3g9IjIwMTAiIGN5PSI0MTciIHJ4PSI2NCIgcnk9IjYyIi8+PGVsbGlwc2UgY3g9IjE5MDAiIGN5PSIyMDAiIHJ4PSI5NyIgcnk9IjEwMSIvPjxwYXRoIGQ9Ik0xODM2IDUyNmwtODEtMjQ3IDE0NS03OSAxMzkgNzktNzUgMjUxeiIvPjwvZz48cGF0aCBkPSJNMjAxNCA0ODZzLTQ5IDk0IDE4IDE0NGM2NiA1MCAyMzEgODEgMzE5IDEzOSA4OSA1OCAyNDAgMTIwIDI0MSAyODQgMiAxNjQtMzMgMjM2LTEzOSAzNTEtMTA3IDExNi0xNzUgMTI2LTE3NSAxMjZoMjg4czg3LTE1MiAxMTAtMjI2IDUyLTE2NyAzNi0yNjctOTAtMjI1LTIwNi0yODBjLTExNi01Ni04Ni01MS0xNzAtNzUtODMtMjQtOTQtMjYtMTAzLTI4cy05NS0yNy05NS0yNy00NS0yNS03MC01MS01NS05MS01NS05MXptMjY0IDEwNDVsMzQgMjIwaDQxNHYtMjIweiIgZmlsbD0iI2QxZDFkMSIvPjwvc3ZnPg=='); } -body.base .is2d piece.pawn.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMzgzODM4Ij48cGF0aCBkPSJNOTUzIDMyMzloMTkwN3YyMDRIOTUzeiIvPjxwYXRoIGQ9Ik0xMDk5IDMzODZoMTYyMXYxNTNIMTA5OXoiLz48cGF0aCBkPSJNOTUwIDM1MDZoMTkwN3YyMDRIOTUweiIvPjwvZz48cGF0aCBkPSJNMTA5OSAzNDQzaDE2MjF2NjNIMTA5OXoiIGZpbGw9IiMxMTEiLz48ZyBmaWxsPSIjMzgzODM4Ij48cGF0aCBkPSJNMTY1OSAyMDU5bDI5Ni00IDEgMTI4Mi02MTgtOXoiLz48cGF0aCBkPSJNMjE0MCAyMDU5bC0yNjQtNHYxMjgybDYxNy05eiIvPjxwYXRoIGQ9Ik0xMzU1IDE5MDdoMTExNXYxNThIMTM1NXoiLz48ZWxsaXBzZSBjeD0iMTg5MCIgY3k9IjE1NDkiIHJ4PSI0MTQiIHJ5PSI0MzMiLz48L2c+PGcgZmlsbD0iIzExMSI+PHBhdGggZD0iTTE5ODAgMTEyNnMxOTUgMTQ3IDIxOCAzNDljMzYgMzE1LTE2MiA0MTgtNDQ2IDM1MS0xNDMtMzQtMjQ0LTExMC0yMzEtODIgMCAwIDIxIDUxIDU5IDkwIDM3IDM5IDgyIDc1IDgyIDc1aDQ1N3M3NC00MSAxMTQtMTE3YzQwLTc3IDcyLTEzNyA3Mi0yNDRzLTQxLTE5OS02OC0yMzctNTYtNzEtMTA1LTExNGMtNDgtNDQtMTUyLTcxLTE1Mi03MXoiLz48cGF0aCBkPSJNMjA3NCAxOTA3bDY5IDE1OGgzMjZ2LTE1OHptLTUxNiAxNThoNTg1bDM0NiAxMjQyaC0yNTVsLTE2OC0xMDk1eiIvPjxwYXRoIGQ9Ik0yNDY2IDMyMzlsNzAgNDcxaDMyMXYtMjA0aC0xMzd2LTYzaDE0MHYtMjA0eiIvPjwvZz48L3N2Zz4='); } -body.base .is2d piece.knight.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMzgzODM4Ij48cGF0aCBkPSJNODI5IDEzNzhjLTE2NSAxNTEtMTQ1IDE0MC03MiAyNzEgNzIgMTMxIDI0MSAxODggNDAwIDE0MiAxNTgtNDYgNTA2LTE4MyA2MzMtMTU0IDEyNyAzMCAxNTkgOTEgMTY3IDE1N3MtMTg2IDIyNy00MDAgNDMzYy0yMTQgMjA1LTQwMiAyNDMtMzczIDY3MSAzMCA0MjggMTkgNTI1LTQyIDU5MnMxMDc0IDI2MyAxMjIxIDE5NmMxNDctNjggNTQzLTU1IDQ2NS00NjAtNzgtNDA2LTIwOC05MDAtMTAtMTIzOHMzOTgtMTA0Mi01MjctMTQyMy01NTggMzUtNjQ4IDgzYy05MCA0Ny0xMjEgNTctMTc1IDgzLTk4IDQ3LTQ2MiA0ODYtNjM5IDY0N3oiLz48cGF0aCBkPSJNODkwIDMyMzloMjIxN3YyMDRIODkweiIvPjxwYXRoIGQ9Ik0xMDU5IDMzODZoMTg4NXYxNTNIMTA1OXoiLz48cGF0aCBkPSJNODg2IDM1MDZoMjIxN3YyMDRIODg2eiIvPjwvZz48ZyBmaWxsPSIjMTExIj48cGF0aCBkPSJNMTYxNSAxNjQ0czg1LTEyNCAyNjItMTMxYzE3Ni03IDc1LTMzMSA3NS0zMzFzMjI3IDI5MyAyMjcgNDQ0LTIzOSAyMTctMjM5IDIxNy0zMC0xODItMzI0LTIwMHptMTAwNC05MDBzNDI1IDIzOCAyMjEgODQyLTU2MCA5MTUtNDk4IDEyMjYgOSAzNjQgMzEgMzkxIDkzIDI3IDE5NS00IDg0IDQ0IDkzIDg5YzkgNDQgNzIgNDIxIDcyIDQyMWgzNjl2LTIwNGgtMTU5di02M2gxNjN2LTIwNGgtMjc3cy05NS00NDgtMTE2LTcyOCA1OC00NTQgMTcwLTY1M2MxMTEtMjAwIDIzMS03NzctMjY1LTExMTN6Ii8+PHBhdGggZD0iTTEwNjAgMzQ0M2gxODg1djYzSDEwNjB6Ii8+PC9nPjwvc3ZnPg=='); } -body.base .is2d piece.bishop.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMTg3MCA0ODJzNjIxIDI2OSA0NTggODgzLTU3MCAyNjAtNTcwIDI2MGwxMTMtMTE0MnpNNzk4IDMyMzhoMjIxN3YyMDRINzk4eiIgZmlsbD0iIzM4MzgzOCIvPjxwYXRoIGQ9Ik05NjcgMzM4NWgxODg1djE1M0g5Njd6IiBmaWxsPSIjMmUyZTJlIi8+PGcgZmlsbD0iIzM4MzgzOCI+PHBhdGggZD0iTTc5NCAzNTA1aDIyMTd2MjA0SDc5NHptNzg2LTE5NTJoNTk4bDUwMSAxNzA0SDExMjR6Ii8+PHBhdGggZD0iTTEyODYgMTUxMWgxMjAwdjE1MkgxMjg2eiIvPjxwYXRoIGQ9Ik0xODg1IDQ4M3MtNjIzIDI2OS00NTkgODgzIDU3MiAyNjAgNTcyIDI2MEwxODg1IDQ4NHoiLz48ZWxsaXBzZSBjeD0iMTg4MCIgY3k9IjQ0OCIgcng9IjE3NCIgcnk9IjE0MyIvPjwvZz48ZyBmaWxsPSIjMTExIj48cGF0aCBkPSJNMTk2NSAzMjNzNDMgNTQgNDMgMTE1LTE0IDExOC0xNCAxMTggMTUzLTExOC0yOS0yMzN6TTk2NyAzNDQyaDE4ODV2NjNIOTY3ek0xOTk0IDU1NnMyMjEgMTQ0IDMwMCAzMzMgNjYgMjU5IDUwIDM5Ny02OCAyMjQtNjggMjI0aDIwOXYxNTJoLTMyMWwtMTctMTUycy0yLTQyLTEyLTc3Yy0xMC0zNiA5My04NSAxMDQtMjQwIDEwLTE1NSAxLTI1My01My0zNjgtNTMtMTE2LTE5NC0yNjktMTk0LTI2OXoiLz48cGF0aCBkPSJNMTU0MSAxNjYzaDY2OWw0NjUgMTU3NWgzNDF2MjA0aC0xNjR2NjNoMTYwdjIwNGgtNDgxdi0yNjdsLTg0LTIwNC0zMTItMTQyOXoiLz48L2c+PC9zdmc+'); } -body.base .is2d piece.rook.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMzgzODM4Ij48cGF0aCBkPSJNMTI1OSAxNjk0bDEyODMgNCAyMDkgMTU5MC0xNjg4LTIyeiIvPjxwYXRoIGQ9Ik0xMDAyIDE3NDdoMTgwMmwyMTctMTE1MS01MjQgMzF2MjgyaC0zMDdWNjM2aC01NDl2MjczaC0zMjBsLTMtMjcyLTUyMS00MXpNNzkzIDMyMzVoMjIxN3YyMDRINzkzeiIvPjxwYXRoIGQ9Ik05NjIgMzM4MmgxODg1djE1M0g5NjJ6Ii8+PHBhdGggZD0iTTc4OSAzNTAyaDIyMTd2MjA0SDc4OXoiLz48L2c+PGcgZmlsbD0iIzExMSI+PHBhdGggZD0iTTI4NTIgNjA2cy0xNDYgOTE5LTE2OCA5ODYtOTQgMTU1LTk0IDE1NWgyMTNsMjE3LTExNTEtMTY5IDEwek0xMzg2IDE3NDdoMTE2MmwxOTUgMTQ4OGgyNjZ2MjA0bC0xNjEtM3Y2M2wxNTcgM3YyMDRoLTMxNnMtMjQtMTcxLTY3LTI2OWMtNDItOTktOTAtNzgtMTM5LTQ0NS00OS0zNjgtMTUzLTEwMjAtMTUzLTEwMjBsLTk0NS0yMjN6Ii8+PHBhdGggZD0iTTk2NCAzNDM2aDE4ODV2NjNIOTY0eiIvPjwvZz48L3N2Zz4='); } -body.base .is2d piece.queen.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMzgzODM4Ij48cGF0aCBkPSJNMTQ0NSAxNjI2bDg5MiA0IDQxOSAxNjU4LTE2ODgtMjR6Ii8+PHBhdGggZD0iTTc5OCAzMjM1aDIyMTd2MjA0SDc5OHoiLz48cGF0aCBkPSJNOTY3IDMzODJoMTg4NXYxNTNIOTY3eiIvPjxwYXRoIGQ9Ik03OTQgMzUwMWgyMjE3djIwNEg3OTR6Ii8+PC9nPjxwYXRoIGQ9Ik0xNDAxIDE3NDVoOTY1bDM4MyAxNDg5aDI2NnYyMDRoLTE2MXY2MGwxNTcgM3YyMDRoLTMxNnMtMjYtMTQ5LTcxLTI2N2MtNDUtMTE3LTg1LTgwLTEzNS00NDgtNDktMzY4LTI1My0xMTE3LTI1My0xMTE3bC04MzYtMTI5eiIgZmlsbD0iIzExMSIvPjxwYXRoIGQ9Ik05NzAgMzQzNmgxODg0djYzSDk3MHoiIGZpbGw9IiMxMTEiLz48ZyBmaWxsPSIjMzgzODM4Ij48cGF0aCBkPSJNMTA4OCAxNTI2aDE2Mzh2MjIwSDEwODh6Ii8+PHBhdGggZD0iTTEzNTIgMTU2M0w5NDkgNzk4bDQ5NyAyNjAtNDAtNjg0IDQ3OCA1NTcgMzIgNjMyeiIvPjxwYXRoIGQ9Ik0yNDE2IDE1NjNsNDAzLTc2NS00OTggMjYwIDQwLTY4My00NzggNTU2LTE4IDYzMnoiLz48Y2lyY2xlIGN4PSI5NDkiIGN5PSI3OTgiIHI9IjEwMCIvPjxjaXJjbGUgY3g9IjE0MDYiIGN5PSIzNzQiIHI9IjEwMCIvPjxjaXJjbGUgY3g9IjIzNjEiIGN5PSIzNzUiIHI9IjEwMCIvPjwvZz48ZyBmaWxsPSIjMTExIj48Y2lyY2xlIGN4PSIyODE5IiBjeT0iNzk4IiByPSIxMDAiLz48cGF0aCBkPSJNMjQyMSAyOTVsLTk3IDE3My0yNDAgMTA1OGgzNTFsMzM3LTYzOS00Mi00Mi00MDkgMjEzIDQwLTU4NHMxNzMtMzQgNjAtMTgwem0tMTYxIDEyMzF2MjE5aDQ2NnYtMjE5eiIvPjwvZz48L3N2Zz4='); } -body.base .is2d piece.king.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgaGVpZ2h0PSIxNDQiIGltYWdlLXJlbmRlcmluZz0ib3B0aW1pemVRdWFsaXR5IiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdmlld0JveD0iMCAwIDM4MTAgMzgxMCIgd2lkdGg9IjE0NCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZyBmaWxsPSIjMzgzODM4Ij48cGF0aCBkPSJNMTM0MiAxNjMybDEwOTggOSAzMTYgMTY1My0xNjg4LTI0eiIvPjxwYXRoIGQ9Ik03OTggMzI0MWgyMjE3djIwNEg3OTh6Ii8+PHBhdGggZD0iTTk2NyAzMzg4aDE4ODV2MTUzSDk2N3oiLz48cGF0aCBkPSJNNzk0IDM1MDdoMjIxN3YyMDRINzk0eiIvPjwvZz48cGF0aCBkPSJNMTQwMSAxNzUxaDEwNjFsMjg4IDE0ODloMjY2djIwNGwtMTYxLTN2NjNsMTU3IDN2MjA0aC0zMTZzLTI2LTE0OS03MS0yNjdjLTQ1LTExNy04NS04MC0xMzUtNDQ4LTQ5LTM2OC0xNTAtMTEwMS0xNTAtMTEwMWwtOTM5LTE0NXoiIGZpbGw9IiMxMTEiLz48cGF0aCBkPSJNOTcwIDM0NDJoMTg4NHY2M0g5NzB6IiBmaWxsPSIjMTExIi8+PGcgZmlsbD0iIzM4MzgzOCI+PHBhdGggZD0iTTEwODggMTUzMWgxNjM4djIyMEgxMDg4eiIvPjxwYXRoIGQ9Ik0xMjc4IDE2MTFzLTI0MS0zMjgtMTk5LTU3MmM1MC0yODUgMzgyLTQwOCA4NzUtNDM1IDE0OC04IDk4IDEwMDcgOTggMTAwN3oiLz48cGF0aCBkPSJNMjUxNSAxNjExczI0MS0zMjggMTk5LTU3MmMtNTAtMjg1LTM4Mi00MDgtODc1LTQzNS0xNDgtOC05OCAxMDA3LTk4IDEwMDd6Ii8+PHBhdGggZD0iTTE1NjAgNjU1czI1My02MyAyMjYtMTY5IDExNC0xOSAxMTQtMTlsMTAgMTQ2LTM1MCA0M3oiLz48cGF0aCBkPSJNMjE3MiA2NDdzLTE1NC03NS0xNTgtMTYxYy01LTg2LTExNC0xOS0xMTQtMTlsLTEwIDE0NyAyODIgMzR6Ii8+PGVsbGlwc2UgY3g9IjE3NTUiIGN5PSIyNzkiIHJ4PSI5MSIgcnk9Ijg5Ii8+PGVsbGlwc2UgY3g9IjE3ODQiIGN5PSI0MTciIHJ4PSI2NCIgcnk9IjYyIi8+PGVsbGlwc2UgY3g9IjIwMzkiIGN5PSIyNzkiIHJ4PSI5MSIgcnk9Ijg5Ii8+PGVsbGlwc2UgY3g9IjIwMTAiIGN5PSI0MTciIHJ4PSI2NCIgcnk9IjYyIi8+PGVsbGlwc2UgY3g9IjE5MDAiIGN5PSIyMDAiIHJ4PSI5NyIgcnk9IjEwMSIvPjxwYXRoIGQ9Ik0xODM2IDUyNmwtODEtMjQ3IDE0NS03OSAxMzkgNzktNzUgMjUxeiIvPjwvZz48cGF0aCBkPSJNMjAxNCA0ODZzLTQ5IDk0IDE4IDE0NGM2NiA1MCAyMzEgODEgMzE5IDEzOSA4OSA1OCAyNDAgMTIwIDI0MSAyODQgMiAxNjQtMzMgMjM2LTEzOSAzNTEtMTA3IDExNi0xNzUgMTI2LTE3NSAxMjZoMjg4czg3LTE1MiAxMTAtMjI2IDUyLTE2NyAzNi0yNjctOTAtMjI1LTIwNi0yODBjLTExNi01Ni04Ni01MS0xNzAtNzUtODMtMjQtOTQtMjYtMTAzLTI4cy05NS0yNy05NS0yNy00NS0yNS03MC01MS01NS05MS01NS05MXptMjY0IDEwNDVsMzQgMjIwaDQxNHYtMjIweiIgZmlsbD0iIzExMSIvPjwvc3ZnPg=='); } - -.is2d piece.white { filter: drop-shadow(0.5px 0.5px 1px #000); } -.is2d piece.black { filter: drop-shadow(-0.5px -0.5px 1px #fff); } diff --git a/public/stylesheets/piece/reillycraig.css b/public/stylesheets/piece/reillycraig.css deleted file mode 100644 index 954d610449..0000000000 --- a/public/stylesheets/piece/reillycraig.css +++ /dev/null @@ -1,12 +0,0 @@ -body.base .is2d piece.pawn.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii01Ni45IC0xMCAyMjAgMjIwIiB3aWR0aD0iMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48c3dpdGNoPjxnPjxwYXRoIGQ9Ik01MyAxNzYuNkg2Ljd2MTUuN2g5Mi42di0xNS43SDYuN3YtNy45YzI5LjQtMzYuNyAyNy4yLTYyLjEgMjItNzUuNS0yLjgtNy4zLTYuNS0xMS02LjUtMTFoNjEuNHMtMjkuNyAyOS45IDE1LjYgODYuNXY3LjkiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNNTMgMTc2LjZINi43djE1LjdoOTIuNnYtMTUuN0g2Ljd2LTcuOWMyOS40LTM2LjcgMjcuMi02Mi4xIDIyLTc1LjUtMi44LTcuMy02LjUtMTEtNi41LTExaDYxLjRzLTI5LjcgMjkuOSAxNS42IDg2LjV2Ny45IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTgzLjcgMzQuOGMwIDE3LjMtMTMuOCAzMS40LTMwLjggMzEuNHMtMzAuNy0xNC0zMC43LTMxLjRDMjIuMiAxNy41IDM2IDMuNCA1Mi45IDMuNGMxNyAuMSAzMC44IDE0LjEgMzAuOCAzMS40IiBmaWxsPSIjZmZmIi8+PGVsbGlwc2UgY3g9IjUyLjkiIGN5PSIzNC44IiBmaWxsPSJub25lIiByeD0iMzAuOCIgcnk9IjMxLjQiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNNTMgNjYuMnMzMyAuMSA0Ni4yIDE2SDYuOEMyMCA2Ni4zIDUzIDY2LjIgNTMgNjYuMiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik01MyA2Ni4yczMzIC4xIDQ2LjIgMTZINi44QzIwIDY2LjMgNTMgNjYuMiA1MyA2Ni4yIiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTMwLjMgOThoNDUuNCIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0zMC4zIDk4aDQ1LjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjQiLz48cGF0aCBkPSJNNi43IDE2OC43aDkyLjYiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNNi43IDE2OC43aDkyLjYiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48L2c+PC9zd2l0Y2g+PC9zdmc+'); } -body.base .is2d piece.knight.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii0zMi40NSAtMTAgMjIwIDIyMCIgd2lkdGg9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHN3aXRjaD48Zz48cGF0aCBkPSJNOTcuOSAxNzAuNGM5LjcgMCA5LjctMTUgMC0xNS05LjYgMC05LjYgMTUgMCAxNU0zOS4xIDMwLjVjLTItMy00LjUtNC40LTcuOC01LjctMy41LTEuMy02LjUtMy40LTEwLTQuNy02LjctMi41LTE4LjQtNS40LTE5IDUuNS0uMiAzLjEgMS4yIDUuOCAyLjMgOC43IDEuNSAzLjcgMyA3LjYgNS44IDEwLjYgMi42IDIuOSA1LjYgNC41IDkuMiA1LjkgMS45LjggNC43LjggNi43LjMgMS4xLS4yIDIuMS0uNiAzLjEtMS4xIDEuNi0uOCAxLjgtLjkuNi0uNCAyLjktMS4yIDUuOS0zLjcgNS41LTcuMi0uNi01LjUtNC40LTkuMS05LjUtMTAuNy02LjgtMi4xLTEzLjMgNy43LTcuMyAxMi41QzI0LjYgNDkgMzUgNTguOSA0MS42IDQ5LjVjNC45LTYuOS0xLjItMTcuNi01LjItMjMuMy0yLjggMy43LTUuNiA3LjMtOC41IDExIDMuNy43IDcgMy4xIDEwLjggMy44IDUuNi45IDExLjEtMS4xIDEzLjYtNi41IDEuOS00LjEuNy0xMC00LjUtMTEtMi43LS41LTUtLjMtNy43LS4zLTkuNy4xLTkuNyAxNSAwIDE1IDcuNiAwIDE0LjktLjcgMjEuMS01LjUgMi42LTIgNi43LTEuOCA5LjgtMi42IDQuOC0xLjMgOC4xLTIuNiAxMy0xLjIgNi40IDEuOCAxMS40IDYuMSAxOC40IDQuNiAzLjYtLjggNi4zLTQuMiA3LjEtNy42LjUtMi4xLjEtNC0uMi02LS43IDEuOC0uNiAyLjEuMiAxIC45LS42LjgtLjctLjQtLjItMS4zLS4zLTIuNS0uNy0zLjgtMSAxLjIuNiAyLjQgNC42IDMuNSA2LjIgMi4xIDMuMSA0LjMgNiA2LjIgOS4ybC45IDEuOC0uMS0uMWMuNSAyLjcgMS41IDEuMSAyLjktNC42LTIgLjgtNC4yIDEuMS02LjIgMS45IDEuMy0uNSAxLjkgMy4yLjItLjYtLjQtMS0uNy0yLjEtMS0zLjItLjYtMi41IDIuMi0uMS0xLjcgMi4xLTEuMy4zLTIuNS43LTMuOCAxLTMuOS41LTEuOC01LS44LTUuOC0xLjcgMS4yLTMuNSAyLjQtNS4yIDMuNS0zLjQgMi4yLTcgNC4xLTEwLjUgNi4xLTcuNCA0LjMtMTQuNCA5LjMtMjEuNiAxMy45LTYuOSA0LjQtMTMuMSA5LjMtMjEuMiAxMS00IC45LTcuNy0uNS0xMS40LTEuNy0zLjktMS4zLTguMi0xLjgtMTEuNi00LjEtMS4zIDQuNy0yLjUgOS4zLTMuOCAxNCA5LjQgMS4yIDE2LjMtMS4xIDIzLjctNy4xIDMuNS0yLjkgNi4yLTYuMiA2LjUtMTAuOS4yLTIuMS0uMi00LjEtLjgtNi4xLS4yLS41LS40LTEtLjYtMS42LS4xLS4zLS4yLS42LS4yLS45LjEgMS42LS41IDIuOS0xLjkgMy45LTEuMy4zLTIuNS43LTMuOCAxIDIuNS0uMSAxLjYtLjktMi44LTIuNC0uNC0yLjItLjYtMi42LS41LTEuMiAwIC45LS4xIDEtLjQgMi40LS42IDIuNy0xLjYgNS40LTIuMyA4LjEtMi4xIDcuMiAxLjQgMTYgMTAuNCAxMy43IDMuNC0uOSA2LjItNC4zIDguMi02LjkgMy4xLTMuOSA0LjgtOC42IDUuMS0xMy41LjEtMiAwLTQtLjEtNnYtNC4yYzAtLjYuMS0xLjMuMS0xLjkgMCAuMSAwIC4zLS4xLjQuNi0yLS4zLTEuMS0yLjcgMi44LTEuMy4zLTIuNS43LTMuOCAxaC40Yy0xLjMtLjMtMi41LS43LTMuOC0xIC45LjQgMy44IDMuNSAzLjkgNS43LjIgMi40LS44IDUuMi0xLjEgNy42LS4zIDMuMy45IDYuOCAyLjYgOS41IDMuNyA2IDExLjMgNCAxMy43LTEuOCAzLjItNy44IDMuOS0xNi4yIDMuMy0yNC41LS4xLS45LS4xLTEuNyAwLTIuNi00LjUgMi01LjUgMy4yLTIuNyAzLjUuNC4xLjkuMiAxLjMuNCAxLjggMS4yIDEuNS4xLS45LTMuMi0uNSAyLjQtMi4xIDQuOS0zIDcuMi0yLjggNy41IDMuNSAxNS4yIDExLjQgMTEuNCAzLjQtMS42IDUuOC00LjYgOC4xLTcuNiAxLjItMS42IDItMy40IDIuNy01LjIuNC0uOC43LTEuNyAxLTIuNSAxLTIuNyAyLjEtMy4xLTEtLjgtMS4zLjMtMi41LjctMy44IDEtMi4zLjItMS42LS41LS4xLjcgMS4yIDEgMi40IDEuOSAzLjggMi44IDMuMSAyLjEgNi40IDEuMyA5LjcuNWwtOS4yLTkuMmMtLjcgNC45LTEuOCA5LjYtMS44IDE0LjYtLjEgMy44LTMuMiA2LjItNS42IDguOC0yLjkgMy4xLTUuNSA2LjctNy44IDEwLjMtLjggMS4zLTEuNSAyLjctMi4xIDQuMi0uMy42LS41IDEuMi0uOCAxLjgtMS4zIDIuNy0xLjYuNyAxLjIuMWg0YzIuNiAzLjEgMy40IDMuNSAyLjYgMS4yLS40LTEuNS0xLTIuOC0xLjgtNC4xcy0yLTIuNC0zLjMtMy4yYy0yLjQtMS42LTEuMi0xLjkgMCAxLjN2NGMuMS0uMy4yLS41LjMtLjggMS4zLTMuOS0xLjQtOC4yLTUuMi05LjItMS4yLS4zLTIuNS0uNC0zLjctLjkuNiA0LjYgMS4yIDkuMSAxLjggMTMuNyA1LjMtMyAxMS4xLTUgMTYuMy04LTMuOC0yLjItNy41LTQuMy0xMS4zLTYuNS4zIDIuOS0xLjQgNi4zLTIuNSA4LjktLjkgMi4xLTEuNyA0LjEtMi4xIDYuMy0uMiAxLS4zIDIuMS0uMiAzLjEuMi0uNi40LTEuMS42LTEuN2wtMS44IDIuNGMtNS40IDggNy42IDE1LjUgMTMgNy42IDEuMi0xLjggMi4yLTMuMSAyLjktNS4yLjQtMS4zIDAtMi41LjMtMy44LjMtMS41IDEuMS0zIDEuNy00LjUgMS42LTQuMSAzLjgtOC43IDMuMi0xMy4yLS43LTUuNC01LjktOS42LTExLjMtNi41LTUuMyAzLjEtMTEgNS4xLTE2LjMgOC02LjEgMy40LTQgMTEuNiAxLjggMTMuNyAxLjIuNSAyLjUuNSAzLjcuOS0xLjctMy4xLTMuNS02LjItNS4yLTkuMi0xLjIgMy42LjEgNi44IDIuNiA5LjVsMi40IDEuOGMxLjMuOSAxLjIuOC0uMS0uNS42IDEuOCAxLjEgMy41IDIuMiA1LjEgNS4zIDcuNyAxMy45IDQgMTcuNS0yLjkgMS42LTIuOSAyLjgtNS44IDQuNy04LjYgMi4yLTMuMiA1LjEtNS45IDcuNy04LjkgNi41LTcuMyA2LjEtMTYuNSA3LjMtMjUuNy44LTUuNy0zLjEtMTAuNi05LjItOS4yLTIuNS42IDIuNyAxLjcuMi0uMi0xLjQtMS4xLTIuOC0yLjItNC40LTMuMS0yLjktMS43LTYuOC0xLjgtOS41LjItMy4zIDIuNC00LjEgNS43LTUuMyA5LjQtLjUgMS41LTEuMyAyLjgtMi4yIDQuMi0uNyAxLjEtMi45IDEuNy0xLjQgMS41IDEuOS4zIDMuOS41IDUuOC44LjguNyAxLjUgMS41IDIuMyAyLjIuMyAxLjMuNyAyLjUgMSAzLjguMSAxLjkgMCAuMy4yLS41LjMtLjguNC0uOS45LTIgMS4yLTIuNiAyLjctNS40IDIuNy04LjMtLjEtNy42LTYuNy0xMi0xMy43LTEzLTguNy0xLjItMTMuNyA0LjItMTQgMTIuNi0uMSAzIC41IDUuOS4zIDguOS0uMyA0LjUtMS4zIDguOC0zIDEzbDEzLjctMS44Yy0xLjUtMi40LjQtNi44LjUtOS42LjItMy41LTEuMS03LjEtMy0xMC0zLTQuNC0xMC0xMy40LTE2LjMtOC43LTUuMiAzLjktNC45IDEwLTQuOCAxNS45IDAgMS43LjMgNC4yLjEgNS42LS4yIDEuNi0uNyAzLjMtMS43IDQuNS0uOCAxLTMuNyAyLjctMS40IDIuMSAxLjkuMyAzLjkuNSA1LjguOGwtLjYtLjNjMS4xIDEuNSAyLjMgMyAzLjQgNC41LjMuNy0uNiAyLjYtLjEuNC4zLTEuMS42LTIuMi45LTMuMi44LTIuNSAxLjUtNC45IDItNy41IDEuMi02LjYtLjItMTMuNS03LjMtMTUuNy05LjYtMi45LTE0LjMgNy0xMi40IDE0LjcuMi41LjMgMS4xLjUgMS42LjQgMS44LjYgMS45LjUuNC0xLjQgMS0zLjMgMi4zLTQuOCAzLjMtMy40IDIuNC03LjEgMS41LTEwLjggMS04LjEtMS05LjIgMTAuMi0zLjggMTQgNS4zIDMuNyAxMi41IDQuOCAxOC42IDYuOCA3LjUgMi40IDE1LjYgMS4zIDIyLjktMS4zIDYuNC0yLjMgMTIuMi03IDE3LjktMTAuNkM4Mi41IDU5LjcgODkgNTUuMSA5NS45IDUxYzkuNC01LjcgMjktMTIuNyAyMS0yNi45LTMuMS01LjQtOS43LTcuNC0xNS4xLTQuM3MtNS4zIDEwLjEtNC4xIDE1LjRjMS4xIDQuNiAzLjggOS41IDcuNyAxMi4zIDUuMiAzLjggMTMuMS44IDE4LjUtMS40IDEyLjItNS4xIDUuNC0xNy4zIDAtMjQuOS01LjMtNy40LTkuNi0yMC4zLTIxLjMtMTMuOC01LjUgMy4xLTkuMSA5LjEtNy45IDE1LjQuNyAzLjcgNy4yLTMuMSAzLjQtNC4zLTEtLjMtMi0uOS0zLTEuNC0zLjMtMS42LTYuOC0yLjgtMTAuNC0zLjYtOC40LTEuOS0xNS45IDIuMi0yNCAzLjMtMy43LjUtNi4yIDIuNC05LjIgNC41LTMuMiAyLjItNy43IDEuOC0xMS4zIDEuOHYxNWMxLjEgMCAyLjYtLjUgMy43LS4yLTEuNS0zLjctMy03LjMtNC41LTExLTEuMyAyLjguNC0uOCAyLjQtLjUtMS4xLS4yLTIuMi0uNi0zLjItMS0yLjItLjktNC4zLTIuMS02LjctMi42LTUuOC0xLjEtMTIuNiA1LjEtOC41IDExIDEgMS40IDIuNSAyLjcgMy4xIDQuMi40IDEgLjggMiAxLjEgMyAuNyAyLjEtLjEgMi43IDEuMSAxIDEuNS0xLjEgMy0yLjMgNC41LTMuNC0uMi4xLS41LjEtLjcuMmg0Yy0yLjYtLjYtNS0zLjQtNy01LjEtMi40IDQuMi00LjkgOC40LTcuMyAxMi41LjQuMS4yIDAtLjUtLjQtLjMtMS4zLS43LTIuNS0xLTMuOHYuNGMxLjgtMi40IDMuNy00LjggNS41LTcuMi0uNy4zLTMuMSAxLjEtMi40IDEuMi0xLjQtLjMtMi4zLTEuNy0yLjktMi43LTEuMi0xLjktMy40LTYuOC0zLjMtOC0uMyAxLjMtLjcgMi41LTEgMy44LjEtLjIuMi0uMy4zLS41LTEuNSAxLjEtMyAyLjMtNC41IDMuNC0yLjYgMS4xLjggMSAyIDEuMyAyLjEuNSAzLjcgMS41IDUuNiAyLjUgMS44IDEgMy42IDEuOCA1LjUgMi41IDIuNC45IDIuNCAxLjYuOS0uNSA1LjEgNy45IDE4LjEuNCAxMi43LTcuNyIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0xMDIgNTRjMy40IDEuMyA2LjIgMy44IDEwLjEgMy44IDIuMiAwIDQuNC0uMyA2LjUtLjguOC0uMiAxLjctLjQgMi41LS40LTIuMS0xLjEtMi41LTEtMS4yLjEgMS44IDEuOCAyLjcgNS4yIDMuNyA3LjUuNCAxIC45IDEuOSAxLjMgMi44LTEuNi00LjIgNS4yLTUuOC4zLTQuMS0zLjMgMS4xLTYuNSAxLjgtOS43IDMuMi0zLjggMS42LTcuNCAzLjgtMTEgNS45LTMuNSAyLTcgNC4xLTEwLjcgNS41LTEuOS44LTQgMS4yLTYgMS43LjgtLjEuNi0uMS0uNSAwLTIuMS0uMi0xLjUuNCAxLjcgMS42LjMgMS45LjUgMy45LjggNS44LjYtMi42IDQuNS02LjIgNi41LTguNSAzLjUtNCA1LjMtOC40IDcuNi0xMy4yIDEuOS0zLjkgNC0xIDcuNi4zIDEuNC41IDIuOSAxIDQuMyAxLjUuNC4yLjkuMyAxLjMuNSAxLjkuOCAxLjggMS45LjMtLjYtLjMtMS4zLS43LTIuNS0xLTMuOC4yLTEuNS44LTIuNyAxLjgtMy41LS44LjUtLjcuNC0xLjYuNy0xLjkuNy0zLjggMS4xLTUuNyAxLjUtNS4zIDEuMi0xMC4xIDMuMi0xNSA1LjQgMyAzLjkgNi4xIDcuOSA5LjEgMTEuOCAxLTEuMSAyLTIuMyAzLTMuNS43LS44IDEuNC0xLjUgMi4xLTIuMyAxLjMtMSAxLjYtMS4zLjgtLjktMS45LS4zLTMuOS0uNS01LjgtLjgtMi41LTEuMi0yLjMtMi41LS42LjEuOCAxLjMgMS44IDIuMyAyLjkgMy4zIDIuMyAyLjEgNSAzLjIgNy44IDQuNCA0LjYgMS45IDkuOSAxLjMgMTIuOCA1LjkgMS40IDIuMyAyLjUgNC44IDMuOCA3LjIuNyAxLjIgMS40IDIuNCAxLjkgMy43LjEuNS4zIDEgLjQgMS41IDAgMi4yIDEuMSAxLjcgMy40LTEuMy0xLjYuMS0zLjQtLjYtNS0uOC00LjEtLjYtOC4yLS4zLTEyLjItLjggMS44IDQuMyAzLjUgOC41IDUuMyAxMi44IDEuMy0xLjIgMy4yLTEuOSA0LjYtMyAyLjYtMiA0LjctNC42IDUuOC03LjcgMi01LjUtLjQtMTAuNC0zLjktMTQuNi02LTcuMi0yMi4xLTExLjMtMjQuOCAxLjQtMS45IDguOCA0LjEgMTUgOC40IDIxLjkgMi4yIDMuNiAyLjcgOC4zIDQuMSAxMi4zIDEuOSA1IDQuOSA5LjEgOS41IDExLjkgMi4xIDEuMyA1LjUgMS41IDcuNiAwIDUuOS00LjQgOC4zLTEwLjQgOC45LTE3LjYuNy04LjYtOC40LTEzLjMtMTUuMy05LjEtNC42IDIuOC01LjIgMTAuNCAwIDEzIDEuNC43IDIuNiAxLjMgNC4xIDEuNSAxLjEuMiAyLjIuMyAzLjIuMy0yLjYtMi4zLTMuMy0yLjYtMi4xLS44IDEuNCAyLjYgMS40IDcuNCAxLjcgMTAuMy4yIDEuOS40IDMuOC42IDUuNi4yLjguMyAxLjcuMyAyLjUgMy42LTIuMyA0LjEtMy4zIDEuNi0zLTQgMC03LjcgMC0xMS43LjYtNS42LjktMTQgMi41LTE1LjcgOC44LTIuNSA4LjkgNi40IDExLjQgMTIuNiAxMy45bC0zLjMtMTIuNWMtMi40IDIuNC00LjQgNS4xLTYuNCA3LjgtLjggMS4yLTEuOCAyLjMtMi44IDMuM2wxLjUtLjNjLS43LS4zLTEuNS0uNi0yLjMtLjgtOS4zLTMtMTIuOSAxMS4xLTQgMTQuNSA0LjEgMS41IDEwLjQgNC4yIDE0LjctLjYgNC44LTUuMy42LTExLjYtLjctMTcuMy0yLjEtOC45IDEzLjYtMTEuNiAxOS0xMy41IDYuNC0yLjIgNy4xLTkuOSAxLjgtMTMuNy0zLjQtMi40LTgtMi4yLTEyLTIuMS0xLjggMC0xMS0uNi0xMS41LTEuNy0yLjUtNi0yLjMtMTMtMi45LTE5LjMtLjUtNS41LS45LTEzLjItNC4xLTE3LjktMy45LTUuOS0xNC4zLTQuMS0xNCAzLjguMiA2LjQgNCAxMi45IDYuOCAxOC42IDEuNSAzIDMuNSA1LjcgNS42IDguNCAxIDEuMyA0LjYgNC43IDQuNSA2LjEuMy0xLjMuNy0yLjUgMS0zLjggMS0uNy45LS43LS40LjFsLTIuMSAxLjJjLTIuMSAxLjItNC4xIDIuOS02IDQuNS00LjQgMy43LTYuMiA4LjQtNi45IDEzLjktLjYgNS0uNiAxMC42LjQgMTUuNS42IDIuOC0uOCA2LjUtMyA4LjgtNi43IDcgMy45IDE3LjYgMTAuNiAxMC42IDQuOC01IDguOC0xMy40IDcuNS0yMC40LS44LTQuMy0uOC04LjQtLjctMTIuOC4xLTQgMy40LTUuOSA2LjYtNy44IDMuMy0xLjkgNi41LTMuOSA3LjYtNy44IDEuMi00LjQtMS4xLTguNi0zLjUtMTIuMS0yLjUtMy42LTUuNC02LjYtNy42LTEwLjQtMS45LTMuMi01LjUtOC43LTUuNi0xMi41LTQuNyAxLjMtOS4zIDIuNS0xNCAzLjggMS4zIDIgMS4xIDUgMS41IDcuMy42IDMuMy44IDYuNiAxIDEwIC41IDYuNiAxLjIgMTQuNSA0LjggMjAuMyAzLjIgNS4yIDkuNSA2LjggMTUuMSA3LjcgMi45LjUgNiAuOSA5IC45IDEuMiAwIDQuNCAwIDQuNC4xLjYtNC42IDEuMi05LjEgMS44LTEzLjctOS40IDMuMi0yMC4yIDUuNy0yNi4yIDE0LjMtMy4yIDQuNi00LjQgMTAuNC0zLjUgMTYgLjQgMi43IDEuMiA1LjEgMi4yIDcuNiAxLjggNC4yIDEwLjMtMy42IDYtNS0xLjItLjQtMi4zLTEtMy41LTEuNC0xLjMgNC44LTIuNyA5LjYtNCAxNC41IDUuMyAxLjcgOS43IDIgMTQuMi0xLjggNC4xLTMuNSA2LjQtOC40IDEwLjMtMTIuMSA0LjUtNC4zIDEuNy0xMC41LTMuMy0xMi41LS42LS4zLTEuMi0uNS0xLjktLjdsLTEuMi0uM2MtMS43LS42LTEuNi0uNS4yLjUuMyAxLjMuNyAyLjUgMSAzLjh2LS43Yy0uMyAxLjMtLjcgMi41LTEgMy44LS45IDEuNC0zIDItLjkgMS42LjgtLjIgMS41LS4zIDIuMy0uNSAzLjQtLjkgNi4zLTEuNiA5LjktMS40IDcuNS4zIDE0LjYtMS45IDE1LjctMTAuNS40LTMuMS0uNC02LjMtLjctOS41LS40LTQuMS0xLjEtOC4xLTEuOC0xMi4xLS41LTIuOS0xLjktNy4zLTQuNC05LjItMS4zLTEuMS0yLjQtMi4xLTQuMS0yLjYtLjktLjMtNC41LS41LTQuMS0uNHYxM2MuNC0uMi44LS41IDEuMi0uNy0xLjMuMy0yLjUuNy0zLjggMSAuMyAwIC43LS4xIDEtLjEtMS4zLS4zLTIuNS0uNy0zLjgtMS0yLjktMS40LTEuNC00LjgtMi4yLTEuMy0uMi43LS44IDIuNi0xLjIgMi45aDcuNmMtMy42LTIuMi00LjEtNy43LTUuMi0xMS41LTEuNC00LjgtMy44LTguNS02LjYtMTIuNS0xLjEtMS41LTIuMy0zLjEtMy00LjgtLjYtMS40LS4xLS45LS44LjctMS40IDMuMy01LjQuMS0yLjEgMi4xLjkuNSAxLjYgMS40IDIuMyAyLjIuOS45LS40LjMuMi0uNy0xIDEuNy01LjIgMy4zLTYuNyA0LjctNS4yIDUtLjggMTIuMSA1LjMgMTIuOCA0LjQuNSA4LjcuNCAxMy4xIDEuMSA0LjcuOCA5LjEuNCAxMi42LTMuMSA4LjMtOC4yLS43LTIyLjMtNS4xLTMwLjEtMi4zLTQtNS43LTcuNC05LjktOS4yLTQuNC0xLjktOS40LTIuMS0xMy42LTQuNS0xLjMtLjctMS45LTIuOS0yLjktMy45LTItMi01LjEtMi45LTcuOC0yLjItNS40IDEuNS04LjkgNi41LTEyLjUgMTAuNS01LjkgNi43IDEuNCAxNS4yIDkuMSAxMS44IDQuMS0xLjggOC0zLjIgMTIuMy00LjEgMy43LS44IDcuNS0xLjkgMTAuNy00IDQuMS0yLjcgNi43LTguMiAzLjktMTIuOC0yLjQtNC4xLTcuNC01LjctMTEuNy03LjItNC0xLjQtOC4xLTQuMi0xMi40LTQuMi02LjcgMC0xMi4yIDMuOS0xNS41IDkuNi0xLjIgMi4yLTIgNC42LTMuMSA2LjktMS4zIDIuNi0zLjQgNC42LTUuMyA2LjgtMy4zIDMuNy04LjggMTAuMS03LjMgMTUuNSAzLjUgMTIuNyAyMC44IDYuNCAyOC42IDIuOCA1LjItMi40IDEwLTUuNiAxNS04LjMgNC44LTIuNiAxMC0zLjMgMTQuOS01LjYgMTAuOS01LjEgMy45LTE3LjUtLjMtMjUuMS0yLjUtNC41LTYuMy04LjEtMTEuNi04LjctMi45LS40LTUuNi43LTguNCAxLTIuMi4zLTUuNi0yLjQtNy43LTMuMi0zLjgtMS41LTguMiAxLjYtOS4yIDUuMi0uMiA0LjIgMi40IDcuNyA2LjIgOS4yIiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTc1LjcgODEuM2MtNS41LjktMTAuNyA2LjUtMTUuMSA5LjctNS44IDQuMi0xMC41IDkuMy0xNC41IDE1LjItNCA1LjctNi43IDEyLjEtOS4zIDE4LjYtMi45IDcuMS01LjYgMTQuMS02LjUgMjEuNy0uNCAzLjIuMSA2LjYtLjggOS42LS44IDIuOC0xLjEgNS45LjQgOC41IDQuNSA3LjcgMTIuMiAzLjIgMTguNyAyLjggMTQuNy0uOCAyOS41IDMuOSA0NC4xIDEuNCAxNS45LTIuOCAxNS41LTIxLjMgMTcuNS0zMy42IDIuMi0xMy42IDcuMy0zMC4xLjgtNDMuMy03LjktMTYuMS0yNS44LTIuOS0zNS44IDMuMi0xMS44IDcuMy0yMi40IDE4LjItMjguMiAzMC45LTMuOSA4LjUtMTAuNyAxOS44LTMuMSAyOC4xIDUuNSA2IDE0LjMgNy4yIDIxLjkgOC4yIDkuNiAxLjIgMjIuOCAzIDMxLjItMi43IDguOS02LjEgMTMuNy0xOC42IDE1LjItMjguOCAxLjQtOS45IDEuNC0yMS42LTItMzEuMS0xLjktNS4zLTUuMy04LjktMTAuNS0xMS01LjctMi4zLTEyIDIuMy0xNi40IDUuNS05LjcgNi44LTE0IDE5LTIxLjcgMjcuNy00LjMgNC44LTkgOS4zLTEzLjYgMTMuOC0zLjkgMy44LTcgOC40LTEwLjMgMTIuMi01IDUuOS0uMiAxMy45IDcuMyAxMi41IDcuMy0xLjMgMTMuNi01IDIwLjUtNy42IDcuNC0yLjggMTQuMS0xLjEgMjEuNi0uMSAxNC45IDIgMTcuNS0xNC45IDE4LjUtMjUuOC43LTcuMiAxLjctMTYuMS0uNy0yMy0yLjUtNy41LTEwLjgtOC4xLTE2LjMtMy40LTQuNCAzLjgtNy41IDkuMi0xMC41IDE0LjEtMi4xIDMuNC00LjIgNi44LTYuOCA5LjgtMi4xIDIuNS02LjIgNC04LjggNi4xLTMuOSAzLjEtMi4zIDkuNSAxLjUgMTEuOCAzLjYgMi4yIDggMS44IDEyLjEgMiA1LjMuMyAxMC4zLS41IDE0LjgtMy4zIDcuNC00LjUgNi45LTE2LjcgMy4zLTIzLjYtNC40LTguNi0xNy40LTEtMTMgNy42LS42LTEuMiAwIDEuOCAwIDIgMCAuOC4xIDEuNi4yIDIuNCAwIDEuOC4yIDEuNi42LS42LTEuNyAxLTQuMy42LTYuMS41LS43IDAtNS4zLS41LTQuNSAwIC41IDMuOSAxIDcuOSAxLjUgMTEuOCAyLjgtMi4zIDYuMS0zLjUgOC44LTYgMi45LTIuOCA1LjEtNi42IDcuMy05LjkgMi4yLTMuNCA0LjMtNi45IDYuNi0xMC4yLjYtLjkgMy4xLTMuMSAyLjMtMi45aC00Yy0xLjEtMS0yLjItMi4xLTMuMy0zLjEuMSAxIC4yIDIgLjIgMy4xLjEgMS45LjEgMy43LjEgNS42IDAgNC4zLS40IDguNy0uOSAxMy0uMiAxLjktLjcgNC4xLTEuMyA2LjItLjMgMS0uNSAxLjItMS4xIDIuMS40LS42IDEtLjkgMS43LS44LTEtLjItMi0uNS0yLjktLjctNy43LTEuOS0xNS43LTEuNC0yMy40LjVzLTE0LjIgNi42LTIyLjIgOC4xbDcuMyAxMi41YzEuOC0yLjEgMy44LTMuNiA1LjItNi4yIDEuNS0yLjggNC01IDYuMi03LjIgNS41LTUuNSAxMS4xLTEwLjkgMTYuMS0xNi45IDQuMy01LjEgNy41LTExLjEgMTEuMy0xNi42IDEuNy0yLjUgMy44LTQuNiA2LjMtNi4zIDEuMS0uOCAyLjMtMS43IDMuNi0yLjEtMi4xLjgtMS43LTEtLjcgMS43IDEuOCA1IDEuOCAxMC43IDEuOCAxNS45IDAgNi43LTEgMTMuNC00LjMgMTkuMy0xLjIgMi4xLTIuNCA0LjMtNCA2LjEtMS43IDItMy43IDEuOS02LjEgMi01LjYuMy0xMy40LS4yLTE3LjYtLjgtMy41LS41LTcuNC0xLjEtMTAuNC0yLjgtMS4zLS43LS4zLS40LS40LjYuNi0zLjQgMi45LTYuOCA0LjItMTAgNS4xLTEzLjIgMTUuNi0yMi42IDI3LjQtMjkuNiAzLjEtMS44IDYuMy0zLjcgOS41LTUuNC41LS4zIDEuMS0uNiAxLjYtLjggMS42LS40IDEuNS0uOC0uNC0xIC42LjguNyAyLjIuOSAzLjEgMS43IDcuMy0uMiAxNC45LTEuNCAyMi4xLTEuMyA3LjYtMi41IDE1LjMtMy43IDIyLjktLjMgMS44LS4yIDQuOS0xLjUgNi4zLTIuMSAyLjMtNi4xIDEuNy04LjggMS42LTcuOC0uNC0xNS41LTEuMS0yMy4zLTEuNy0zLjctLjMtNy41LS4zLTExLjItLjItMS44IDAtMy41LjMtNS4yLjYtMSAuMy0xLjkuNS0yLjkuOS0zLjIuNS0yLjIgMS44IDIuOSA0LjF2NGMuNS0yLjkgMS4zLTUuNiAxLjUtOC42LjItMy41LjMtNi42IDEuMS0xMCAxLjctNy4yIDQuOS0xNC4zIDgtMjEgMi43LTUuNyA2LjItMTAuOSAxMC42LTE1LjQgMi40LTIuNSA1LjMtNC40IDguMS02LjMgMS45LTEuMyA0LjctNC42IDYuOS00LjkgOS44LTEuOCA1LjctMTYuMy0zLjctMTQuNyIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0zMC41IDE3Ni41di03LjlIMTIzdjcuOSIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0zMC41IDE3Ni41di03LjlIMTIzdjcuOSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik00NC4yIDE4Mi41Yy0uMS0uMy0uMS0uNi0uMi0uOS0uNiAyLjQtMS4zIDQuOS0xLjkgNy4zbC42LS42SDMyYzQuNSA1IDEwLjggNC41IDE2LjkgMy43IDcuNC0xIDE1LjMtMS4xIDIyLjctLjQgNy45LjcgMTUuNi0uMyAyMy40LS4xIDQuMS4xIDggLjUgMTIuMS4zIDIuOS0uMSA2LjItMS41IDguOS0uNSA5LjEgMy4zIDEzLTExLjIgNC0xNC41LTUuNy0yLTEyLjIuMS0xOC4xLjEtMy41IDAtNy0uNC0xMC41LS40LTQuMiAwLTguNC42LTEyLjYuNi03LjUuMS0xNC42LTEuMi0yMi4xLS42LTMuMi4yLTYuNC4yLTkuNi43LS45LjEtMS45LjMtMi44LjQtLjguMS0xLjYuMS0yLjQuMS0uNC0uMi0uMy0uMS41LjEtMi43LTMtNy45LTIuOS0xMC42IDAtMi41IDIuNi0zLjIgNS4yLTIuMyA4LjggMi41IDkuMyAxNyA1LjMgMTQuNy00LjEiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNNzYuNyAxNzYuNUgzMC41djE1LjdIMTIzdi0xNS43em01LTkyLjJjLTUzLjcgOC41LTUxLjMgODQuMy01MS4zIDg0LjMiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTEzLjQgNDguN2MxMy41LTIuNiAxNy4xLTEyLjIgMTcuMS0xMi4yLTcuOC0yMS40LTIzLjEtMzIuNi0yMy4xLTMyLjZTOTYuNSAxNC4yIDk2LjMgMTljMCAwLTE0LjMtOS40LTMyLjYtMS40IDAgMC0yMCAxMC40LTM2LjkgNC4zIDAgMC0yMS4yLTguNS0yMi42LTIuNyAwIDAtMy4zIDEwLjUgMi41IDIwLjUgMCAwIDUuOCA5LjMgOC40IDkuMyAwIDAgMjEuNiAyLjUgMTguNSAzLjUgMCAwLTEuNCA0LjYtMTYuMiAzLjggMCAwLTUuMy0uMS00LjMgNSAxIDUuMyA0LjggMTAuNSAxNS4xIDEyLjUgMCAwIDkuNyAyLjkgMjYgLjVzMTMgMTQuNCAxMyAxNC40IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTEyMC41IDc0LjNjMTMuNS43IDE5LjktNi4zIDE5LjktNi4zcy0zLjQtMTQuMi0xNC0yNS43IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTgwLjEgMzQuOGMwIDItMS42IDMuNi0zLjUgMy42cy0zLjUtMS42LTMuNS0zLjYgMS42LTMuNiAzLjUtMy42IDMuNSAxLjYgMy41IDMuNiIvPjxlbGxpcHNlIGN4PSI3Ni42IiBjeT0iMzQuOCIgZmlsbD0ibm9uZSIgcng9IjMuNSIgcnk9IjMuNiIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNCIvPjxwYXRoIGQ9Ik03Ni4yIDMxLjJzLTMuOC0uMS03LjYgMy43Ii8+PHBhdGggZD0iTTc2LjIgMzEuMnMtMy44LS4xLTcuNiAzLjciIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjQiLz48cGF0aCBkPSJNMTM2LjggNzEuMmMxMS42IDE1LjcgMTMuMiAzMi45IDEzLjIgMzIuOXMtOS43IDYuNy0yNyAyLjkiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTIyLjcgMTQzLjFjMTcuMSA3LjMgMjguNyAxLjcgMjguNyAxLjdzMi40LTE5LjQtNS43LTM4LjhNMTIzIDE2OC42czIuMi0xOS42IDIyLTIyLjEiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTAzLjggMTE1LjFjLTEuMS44LS44LjcuNy0uNCAxLjMtLjkgMi44LTEuNiA0LjItMi4zIDMtMS41IDYuMi0yLjUgOS4zLTMuOCA1LjMtMi4zIDExLTUuOSAxNi44LTYgNy40LS4xIDEwLjQtMTAuMiAzLjgtMTQtNi4xLTMuNS0xMi44LTQuOC0xOS40LTYuOS03LjUtMi4zLTEzLjgtNi4yLTIwLjYtMTAtOC40LTQuOC0xNiA4LjEtNy42IDEzIDYuOCAzLjkgMTMuNCA3LjkgMjAuOCAxMC41IDYuMyAyLjIgMTMuMyAzLjEgMTkuMSA2LjUgMS4zLTQuNyAyLjUtOS4zIDMuOC0xNC04LjUuMi0xNS4xIDQuMS0yMi44IDcuMy02LjYgMi44LTE3LjggNS40LTIxLjIgMTIuNS00IDguOCA4LjkgMTYuNCAxMy4xIDcuNiIgZmlsbD0iI2ZmZiIvPjwvZz48L3N3aXRjaD48L3N2Zz4='); } -body.base .is2d piece.bishop.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii00Ny44NSAtMTAgMjIwIDIyMCIgd2lkdGg9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHN3aXRjaD48Zz48cGF0aCBkPSJNMzAuOCAxNjguOEMxNyAxNTkuNSA3LjEgMTQzIDQuNSAxMjYuNCAxLjYgMTA4LjYgNyA5MC43IDE1LjMgNzUuMWM0LjYtOC41IDEwLjEtMTYuNSAxNi4xLTI0bDIyLjcgMzEgMTYtMTYuMy0yMy43LTMxLjVjNS01LjIgMTAuMy0xMC4xIDE1LjYtMTUgMTA5LjYgOTguMiAzMS4zIDE0OS41IDMxLjMgMTQ5LjUiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNMzAuOCAxNjguOEMxNyAxNTkuNSA3LjEgMTQzIDQuNSAxMjYuNCAxLjYgMTA4LjYgNyA5MC43IDE1LjMgNzUuMWM0LjYtOC41IDEwLjEtMTYuNSAxNi4xLTI0bDIyLjcgMzEgMTYtMTYuMy0yMy43LTMxLjVjNS01LjIgMTAuMy0xMC4xIDE1LjYtMTUgMTA5LjYgOTguMiAzMS4zIDE0OS41IDMxLjMgMTQ5LjUiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNNjkuOSAxMS40YzAgNC40LTMuNSA4LTcuOSA4LTQuMyAwLTcuOS0zLjYtNy45LThzMy41LTggNy45LThjNC4zLS4xIDcuOSAzLjUgNy45IDgiIGZpbGw9IiNmZmYiLz48ZWxsaXBzZSBjeD0iNjIiIGN5PSIxMS40IiBmaWxsPSJub25lIiByeD0iNy45IiByeT0iOCIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0xNS44IDE3Ni43di03LjloOTIuNXY3LjkiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNMTUuOCAxNzYuN3YtNy45aDkyLjV2Ny45IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTYyLjEgMTc2LjdIMTUuOHYxNS43aDkyLjV2LTE1Ljd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTYyLjEgMTc2LjdIMTUuOHYxNS43aDkyLjV2LTE1Ljd6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PC9nPjwvc3dpdGNoPjwvc3ZnPg=='); } -body.base .is2d piece.rook.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii02MC4yIC0xMCAyMjAgMjIwIiB3aWR0aD0iMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48c3dpdGNoPjxnPjxwYXRoIGQ9Ik05Ni4xIDE2OC45Qzk2IDExMCA4MC45IDY3IDgwLjkgNjdsMTUuMi04LjNWMy42SDcyLjl2MTUuN0g2MS40VjMuNkgzOC4ydjE1LjdIMjYuN1YzLjZIMy42djU1LjFMMTguOCA2N1MzLjcgMTEwIDMuNiAxNjguOSIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik05Ni4xIDE2OC45Qzk2IDExMCA4MC45IDY3IDgwLjkgNjdsMTUuMi04LjNWMy42SDcyLjl2MTUuN0g2MS40VjMuNkgzOC4ydjE1LjdIMjYuN1YzLjZIMy42djU1LjFMMTguOCA2N1MzLjcgMTEwIDMuNiAxNjguOSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0zLjYgMTc2Ljd2LTcuOGg5Mi41djcuOCIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0zLjYgMTc2Ljd2LTcuOGg5Mi41djcuOCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik00OS44IDE3Ni43SDMuNnYxNS43aDkyLjV2LTE1Ljd6IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTQ5LjggMTc2LjdIMy42djE1LjdoOTIuNXYtMTUuN3oiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTguOCA2N2g2Mi4xTTMuNiA1Ny44aDkyLjUiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjQiLz48L2c+PC9zd2l0Y2g+PC9zdmc+'); } -body.base .is2d piece.queen.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii0xNC4xIC0xMCAyMjAgMjIwIiB3aWR0aD0iMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48c3dpdGNoPjxnPjxwYXRoIGQ9Ik0xNDIuMSAxNjcuM3MuNi03LjMtMy42LTguMmMtMjMuOC00LjYgMzYuOS05Ni40IDM2LjktOTYuNHMtNTUuMiA2Mi4xLTUxLjgtNDUuNWwtLjgtLjVjLTI3LjggOTguMS01My43IDAtNTMuNyAwbC0xIC42YzMuNCAxMDcuNi01MS44IDQ1LjUtNTEuOCA0NS41czYwLjcgOTEuOCAzNi45IDk2LjRjLTQuMi44LTMuNiA4LjItMy42IDguMiIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0xNDIuMSAxNjcuM3MuNi03LjMtMy42LTguMmMtMjMuOC00LjYgMzYuOS05Ni40IDM2LjktOTYuNHMtNTUuMiA2Mi4xLTUxLjgtNDUuNWwtLjgtLjVjLTI3LjggOTguMS01My43IDAtNTMuNyAwbC0xIC42YzMuNCAxMDcuNi01MS44IDQ1LjUtNTEuOCA0NS41czYwLjcgOTEuOCAzNi45IDk2LjRjLTQuMi44LTMuNiA4LjItMy42IDguMiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik00OS41IDE3Ni4zdi03LjloOTIuNnY3LjkiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNNDkuNSAxNzYuM3YtNy45aDkyLjZ2Ny45IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTc0LjMgOS44Yy45IDUuNC0zLjcgMTAtOSA5LjEtMy4yLS41LTUuOC0zLjItNi4zLTYuNS0uOS01LjQgMy43LTEwIDktOS4xIDMuMS42IDUuNyAzLjIgNi4zIDYuNSIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik03NC4zIDkuOGMuOSA1LjQtMy43IDEwLTkgOS4xLTMuMi0uNS01LjgtMy4yLTYuMy02LjUtLjktNS40IDMuNy0xMCA5LTkuMSAzLjEuNiA1LjcgMy4yIDYuMyA2LjV6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTE4LjYgNTYuM2MuOSA1LjQtMy43IDEwLTkgOS4xLTMuMi0uNS01LjgtMy4yLTYuMy02LjUtLjktNS40IDMuNi0xMCA5LTkuMSAzLjIuNiA1LjggMy4yIDYuMyA2LjUiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNMTguNiA1Ni4zYy45IDUuNC0zLjcgMTAtOSA5LjEtMy4yLS41LTUuOC0zLjItNi4zLTYuNS0uOS01LjQgMy42LTEwIDktOS4xIDMuMi42IDUuOCAzLjIgNi4zIDYuNXoiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNNTggMTU2LjloNzUuNiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNSIvPjxwYXRoIGQ9Ik0xMTcuNCA5LjdjLS45IDUuNCAzLjcgMTAgOSA5LjEgMy4yLS41IDUuOC0zLjIgNi4zLTYuNS45LTUuNC0zLjYtMTAtOS05LjEtMy4yLjYtNS44IDMuMi02LjMgNi41IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTExNy40IDkuN2MtLjkgNS40IDMuNyAxMCA5IDkuMSAzLjItLjUgNS44LTMuMiA2LjMtNi41LjktNS40LTMuNi0xMC05LTkuMS0zLjIuNi01LjggMy4yLTYuMyA2LjV6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTE3MyA1Ni4yYy0uOSA1LjQgMy43IDEwIDkgOS4xIDMuMi0uNSA1LjgtMy4yIDYuMy02LjUuOS01LjQtMy43LTEwLTktOS4xLTMuMi42LTUuOCAzLjItNi4zIDYuNSIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0xNzMgNTYuMmMtLjkgNS40IDMuNyAxMCA5IDkuMSAzLjItLjUgNS44LTMuMiA2LjMtNi41LjktNS40LTMuNy0xMC05LTkuMS0zLjIuNi01LjggMy4yLTYuMyA2LjV6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTk1LjggMTc2SDQ5LjV2MTUuN2g5Mi42VjE3NnoiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNOTUuOCAxNzZINDkuNXYxNS43aDkyLjZWMTc2eiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0xNjQuNiA3Ni40bC02Ny41IDc4LjljLS40LjUtMS4zLjItMS4zLS41bC0yNS4yLTEyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNCIvPjxwYXRoIGQ9Ik0xMjAuNyAzMC44TDk2LjYgMTUzLjNjLS4zIDEuNC0yLjEgMS45LTMgLjhMMjYuOSA3Ni41IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI0Ii8+PC9nPjwvc3dpdGNoPjwvc3ZnPg=='); } -body.base .is2d piece.king.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii0xNC4xNSAtMTAgMjIwIDIyMCIgd2lkdGg9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHN3aXRjaD48Zz48cGF0aCBkPSJNOTUuOSAxNzYuNkg0OS42djE1LjdoOTIuNXYtMTUuN3oiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNOTUuOSAxNzYuNkg0OS42djE1LjdoOTIuNXYtMTUuN3oiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNNDkuNiAxNjguN3Y3LjloOTIuNXYtNy45IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTQ5LjYgMTY4Ljd2Ny45aDkyLjV2LTcuOSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0xMDMuNSA2OC43VjQyLjhoMjMuMlYyN2gtMjMuMmwuMS0yMy42SDg4LjFWMjdINjV2MTUuN2gyMy4xdjI2IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTEwMy41IDY4LjdWNDIuOGgyMy4yVjI3aC0yMy4ybC4xLTIzLjZIODguMVYyN0g2NXYxNS43aDIzLjF2MjYiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTg3LjEgNzUuOWMtNy4xLTI4LjctMzQuNS0zMS43LTM0LjUtMzEuNy0zOC41LTUuNC01Ni4zIDM2LjgtNTYuOCAzNy45LS40LTEtMTguMy00My4zLTU2LjgtMzcuOSAwIDAtMjcuNCAzLTM0LjUgMzEuNyAwIDAtMTMuOCA1MS44IDQ1IDkyLjhIMTQyYzU4LjktNDAuOSA0NS4xLTkyLjggNDUuMS05Mi44IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTE4Ny4xIDc1LjljLTcuMS0yOC43LTM0LjUtMzEuNy0zNC41LTMxLjctMzguNS01LjQtNTYuMyAzNi44LTU2LjggMzcuOS0uNC0xLTE4LjMtNDMuMy01Ni44LTM3LjkgMCAwLTI3LjQgMy0zNC41IDMxLjcgMCAwLTEzLjggNTEuOCA0NSA5Mi44SDE0MmM1OC45LTQwLjkgNDUuMS05Mi44IDQ1LjEtOTIuOHoiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTQ3LjMgNjcuNGMtMjUuMS0yLjItNDMuNiA1MC45LTQzLjYgNTAuOXYzMi44czI2LjItLjYgNDYuNi0yMS44YzIwLjQtMjEuMyAyMi4xLTU5LjctMy02MS45em0tMTAzIDBjLTI1LjEgMi4yLTIzLjQgNDAuNi0zIDYxLjlzNDYuOCAyMS44IDQ2LjggMjEuOHYtMzIuOHMtMTguNy01My00My44LTUwLjl6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTk1LjggMTkuMXYzOS40TTgwLjQgMzQuOWgzMC45IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI0Ii8+PHBhdGggZD0iTTg4LjEgNjguN2gxNS40IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PC9nPjwvc3dpdGNoPjwvc3ZnPg=='); } -body.base .is2d piece.pawn.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii01Ny4xIC0xMCAyMjAgMjIwIiB3aWR0aD0iMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48c3dpdGNoPjxnPjxwYXRoIGQ9Ik01Mi44IDE3Ni4zSDYuNVYxOTJoOTIuNnYtMTUuN0g2LjV2LTcuOWMyOS40LTM2LjcgMjcuMi02Mi4xIDIyLTc1LjUtMi44LTcuMy02LjUtMTEtNi41LTExaDYxLjRTNTMuNyAxMTEuOCA5OSAxNjguNHY3LjkiLz48cGF0aCBkPSJNNTIuOCAxNzYuM0g2LjVWMTkyaDkyLjZ2LTE1LjdINi41di03LjljMjkuNC0zNi43IDI3LjItNjIuMSAyMi03NS41LTIuOC03LjMtNi41LTExLTYuNS0xMWg2MS40UzUzLjcgMTExLjggOTkgMTY4LjR2Ny45IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTgzLjUgMzQuNWMwIDE3LjMtMTMuOCAzMS40LTMwLjggMzEuNHMtMzAuOC0xNC0zMC44LTMxLjRDMjIgMTcuMiAzNS43IDMuMiA1Mi43IDMuMnMzMC44IDE0IDMwLjggMzEuMyIvPjxlbGxpcHNlIGN4PSI1Mi43IiBjeT0iMzQuNSIgZmlsbD0ibm9uZSIgcng9IjMwLjgiIHJ5PSIzMS40IiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTUyLjggNjUuOXMzMyAuMSA0Ni4yIDE2SDYuNmMxMy4yLTE1LjkgNDYuMi0xNiA0Ni4yLTE2Ii8+PHBhdGggZD0iTTUyLjggNjUuOXMzMyAuMSA0Ni4yIDE2SDYuNmMxMy4yLTE1LjkgNDYuMi0xNiA0Ni4yLTE2IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTMwLjEgOTcuN2g0NS40IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTMwLjEgOTcuN2g0NS40IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI0Ii8+PHBhdGggZD0iTTYuNSAxNjguNGg5Mi42IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTYuNSAxNjguNGg5Mi42IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTkuMSAxNzIuM2g4Ny40IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTkuMSAxNzIuM2g4Ny40IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSIyIi8+PC9nPjwvc3dpdGNoPjwvc3ZnPg=='); } -body.base .is2d piece.knight.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii0zMi40NSAtMTAgMjIwIDIyMCIgd2lkdGg9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHN3aXRjaD48Zz48cGF0aCBkPSJNOTcuOCAxNzAuNWM5LjcgMCA5LjctMTUgMC0xNXMtOS43IDE1IDAgMTVNMzkgMzAuNmMtMi0zLTQuNS00LjQtNy44LTUuNy0zLjUtMS4zLTYuNS0zLjQtMTAtNC43LTYuNy0yLjUtMTguNC01LjQtMTkgNS41LS4yIDMuMSAxLjIgNS44IDIuMyA4LjdDNiAzOC4xIDcuNSA0MiAxMC4zIDQ1YzIuNiAyLjkgNS42IDQuNSA5LjIgNS45IDEuOS44IDQuNy44IDYuNy4zIDEuMS0uMiAyLjEtLjYgMy4xLTEuMSAxLjYtLjggMS44LS45LjYtLjQgMi45LTEuMiA1LjktMy43IDUuNS03LjItLjYtNS41LTQuNC05LjEtOS41LTEwLjctNi44LTIuMS0xMy4zIDcuNy03LjMgMTIuNUMyNC40IDQ5IDM0LjggNTkgNDEuNCA0OS42YzQuOS02LjktMS4yLTE3LjYtNS4yLTIzLjMtMi44IDMuNy01LjYgNy4zLTguNSAxMSAzLjcuNyA3IDMuMSAxMC44IDMuOCA1LjYuOSAxMS4xLTEuMSAxMy42LTYuNSAxLjktNC4xLjctMTAtNC41LTExLTIuNy0uNS01LS4zLTcuNy0uMy05LjcuMS05LjcgMTUgMCAxNSA3LjYgMCAxNC45LS43IDIxLjEtNS41IDIuNi0yIDYuNy0xLjggOS44LTIuNiA0LjgtMS4zIDguMS0yLjYgMTMtMS4yIDYuNCAxLjggMTEuNCA2LjEgMTguNCA0LjYgMy42LS44IDYuMy00LjIgNy4xLTcuNi41LTIuMS4xLTQtLjItNi0uNyAxLjgtLjYgMi4xLjIgMSAuOS0uNi44LS43LS40LS4yLTEuMy0uMy0yLjUtLjctMy44LTEgMS4yLjYgMi40IDQuNiAzLjUgNi4yIDIuMSAzLjEgNC4zIDYgNi4yIDkuMmwuOSAxLjgtLjEtLjFjLjUgMi43IDEuNSAxLjEgMi45LTQuNi0yIC44LTQuMiAxLjEtNi4yIDEuOSAxLjMtLjUgMS45IDMuMi4yLS42LS40LTEtLjctMi4xLTEtMy4yLS42LTIuNSAyLjItLjEtMS43IDIuMS0xLjMuMy0yLjUuNy0zLjggMS0zLjkuNS0xLjgtNS0uOC01LjgtMS43IDEuMi0zLjUgMi40LTUuMiAzLjUtMy40IDIuMi03IDQuMS0xMC41IDYuMS03LjQgNC4zLTE0LjQgOS4zLTIxLjYgMTMuOS02LjkgNC40LTEzLjEgOS4zLTIxLjIgMTEtMy45LjktNy43LS41LTExLjQtMS43LTMuOS0xLjMtOC4yLTEuOC0xMS42LTQuMS0xLjMgNC43LTIuNSA5LjMtMy44IDE0IDkuNCAxLjIgMTYuMy0xLjEgMjMuNy03LjEgMy41LTIuOSA2LjItNi4yIDYuNS0xMC45LjItMi4xLS4yLTQuMS0uOC02LjEtLjItLjUtLjQtMS0uNi0xLjYtLjEtLjMtLjItLjYtLjItLjkuMSAxLjYtLjUgMi45LTEuOSAzLjktMS4zLjMtMi41LjctMy44IDEgMi41LS4xIDEuNi0uOS0yLjgtMi40LS40LTIuMi0uNi0yLjYtLjUtMS4yIDAgLjktLjEgMS0uNCAyLjQtLjYgMi43LTEuNiA1LjQtMi4zIDguMS0yLjEgNy4yIDEuNCAxNiAxMC40IDEzLjcgMy40LS45IDYuMi00LjMgOC4yLTYuOSAzLjEtMy45IDQuOC04LjYgNS4xLTEzLjUuMS0yIDAtNC0uMS02di00LjJjMC0uNi4xLTEuMy4xLTEuOSAwIC4xIDAgLjMtLjEuNC42LTItLjMtMS4xLTIuNyAyLjgtMS4zLjMtMi41LjctMy44IDFoLjRjLTEuMy0uMy0yLjUtLjctMy44LTEgLjkuNCAzLjggMy41IDMuOSA1LjcuMiAyLjQtLjggNS4yLTEuMSA3LjYtLjMgMy4zLjkgNi44IDIuNiA5LjUgMy43IDYgMTEuMyA0IDEzLjctMS44IDMuMi03LjggMy45LTE2LjIgMy4zLTI0LjUtLjEtLjktLjEtMS43IDAtMi42LTQuNSAyLTUuNSAzLjItMi43IDMuNS40LjEuOS4yIDEuMy40IDEuOCAxLjIgMS41LjEtLjktMy4yLS41IDIuNC0yLjEgNC45LTMgNy4yQzY0LjggNDkuMyA3MS4xIDU3IDc5IDUzLjJjMy40LTEuNiA1LjgtNC42IDguMS03LjYgMS4yLTEuNiAyLTMuNCAyLjctNS4yLjQtLjguNy0xLjcgMS0yLjUgMS0yLjcgMi4xLTMuMS0xLS44LTEuMy4zLTIuNS43LTMuOCAxLTIuMy4yLTEuNi0uNS0uMS43IDEuMiAxIDIuNCAxLjkgMy44IDIuOCAzLjEgMi4xIDYuNCAxLjMgOS43LjVsLTkuMi05LjJjLS43IDQuOS0xLjggOS42LTEuOCAxNC42LS4xIDMuOC0zLjIgNi4yLTUuNiA4LjgtMi45IDMuMS01LjUgNi43LTcuOCAxMC4zLS44IDEuMy0xLjUgMi43LTIuMSA0LjItLjMuNi0uNSAxLjItLjggMS44LTEuMyAyLjctMS42LjcgMS4yLjFoNGMyLjYgMy4xIDMuNCAzLjUgMi42IDEuMi0uNC0xLjUtMS0yLjgtMS44LTQuMXMtMi0yLjQtMy4zLTMuMmMtMi40LTEuNi0xLjItMS45IDAgMS4zdjRjLjEtLjMuMi0uNS4zLS44IDEuMy0zLjktMS40LTguMi01LjItOS4yLTEuMi0uMy0yLjUtLjQtMy43LS45LjYgNC42IDEuMiA5LjEgMS44IDEzLjcgNS4zLTMgMTEuMS01IDE2LjMtOC0zLjgtMi4yLTcuNS00LjMtMTEuMy02LjUuMyAyLjktMS40IDYuMy0yLjUgOC45LS45IDIuMS0xLjcgNC4xLTIuMSA2LjMtLjIgMS0uMyAyLjEtLjIgMy4xLjItLjYuNC0xLjEuNi0xLjdMNjcgNzkuMmMtNS40IDggNy42IDE1LjUgMTMgNy42IDEuMi0xLjggMi4yLTMuMSAyLjktNS4yLjQtMS4zIDAtMi41LjMtMy44LjMtMS41IDEuMS0zIDEuNy00LjUgMS42LTQuMSAzLjgtOC43IDMuMi0xMy4yLS43LTUuNC01LjktOS42LTExLjMtNi41LTUuMyAzLjEtMTEgNS4xLTE2LjMgOC02LjEgMy40LTQgMTEuNiAxLjggMTMuNyAxLjIuNSAyLjUuNSAzLjcuOS0xLjctMy4xLTMuNS02LjItNS4yLTkuMi0xLjIgMy42LjEgNi44IDIuNiA5LjVsMi40IDEuOGMxLjMuOSAxLjIuOC0uMS0uNS42IDEuOCAxLjEgMy41IDIuMiA1LjEgNS4zIDcuNyAxMy45IDQgMTcuNS0yLjkgMS42LTIuOSAyLjgtNS44IDQuNy04LjYgMi4yLTMuMiA1LjEtNS45IDcuNy04LjkgNi41LTcuMyA2LjEtMTYuNSA3LjMtMjUuNy44LTUuNy0zLjEtMTAuNi05LjItOS4yLTIuNS42IDIuNyAxLjcuMi0uMi0xLjQtMS4xLTIuOC0yLjItNC40LTMuMS0yLjktMS43LTYuOC0xLjgtOS41LjItMy4zIDIuNC00LjEgNS43LTUuMyA5LjQtLjUgMS41LTEuMyAyLjgtMi4yIDQuMi0uNyAxLjEtMi45IDEuNy0xLjQgMS41IDEuOS4zIDMuOS41IDUuOC44bDIuMyAyLjJjLjMgMS4zLjcgMi41IDEgMy44LjEgMS45IDAgLjMuMi0uNS4zLS44LjQtLjkuOS0yIDEuMi0yLjYgMi43LTUuNCAyLjctOC4zLS4xLTcuNi02LjctMTItMTMuNy0xMy04LjctMS4yLTEzLjcgNC4yLTE0IDEyLjYtLjEgMyAuNSA1LjkuMyA4LjktLjMgNC41LTEuMyA4LjgtMyAxM2wxMy43LTEuOGMtMS41LTIuNC40LTYuOC41LTkuNi4yLTMuNS0xLjEtNy4xLTMtMTAtMy00LjQtMTAtMTMuNC0xNi4zLTguNy01LjIgMy45LTQuOSAxMC00LjggMTUuOSAwIDEuNy4zIDQuMi4xIDUuNi0uMiAxLjYtLjcgMy4zLTEuNyA0LjUtLjggMS0zLjcgMi43LTEuNCAyLjEgMS45LjMgMy45LjUgNS44LjhsLS42LS4zIDMuNCA0LjVjLjMuNy0uNiAyLjYtLjEuNC4zLTEuMS42LTIuMi45LTMuMi44LTIuNSAxLjUtNC45IDItNy41IDEuMi02LjYtLjItMTMuNS03LjMtMTUuNy05LjYtMi45LTE0LjMgNy0xMi40IDE0LjcuMi41LjMgMS4xLjUgMS42LjQgMS44LjYgMS45LjUuNC0xLjIgMS40LTMuMSAyLjctNC42IDMuNy0zLjQgMi40LTcuMSAxLjUtMTAuOCAxLTguMS0xLTkuMiAxMC4yLTMuOCAxNCA1LjMgMy43IDEyLjUgNC44IDE4LjYgNi44IDcuNSAyLjQgMTUuNiAxLjMgMjIuOS0xLjMgNi40LTIuMyAxMi4yLTcgMTcuOS0xMC42IDYuNy00LjIgMTMuMi04LjggMjAuMS0xMi45IDkuNC01LjcgMjktMTIuNyAyMS0yNi45LTMuMS01LjQtOS43LTcuNC0xNS4xLTQuM3MtNS4zIDEwLjEtNC4xIDE1LjRjMS4xIDQuNiAzLjggOS41IDcuNyAxMi4zIDUuMiAzLjggMTMuMS44IDE4LjUtMS40IDEyLjItNS4xIDUuNC0xNy4zIDAtMjQuOS01LjMtNy40LTkuNi0yMC4zLTIxLjMtMTMuOC01LjUgMy4xLTkuMSA5LjEtNy45IDE1LjQuNyAzLjcgNy4yLTMuMSAzLjQtNC4zLTEtLjMtMi0uOS0zLTEuNC0zLjMtMS42LTYuOC0yLjgtMTAuNC0zLjYtOC40LTEuOS0xNS45IDIuMi0yNCAzLjMtMy43LjUtNi4yIDIuNC05LjIgNC41LTMuMiAyLjItNy43IDEuOC0xMS4zIDEuOHYxNWMxLjEgMCAyLjYtLjUgMy43LS4yLTEuNS0zLjctMy03LjMtNC41LTExLTEuMyAyLjguNC0uOCAyLjQtLjUtMS4xLS4yLTIuMi0uNi0zLjItMS0yLjItLjktNC4zLTIuMS02LjctMi42LTUuOC0xLjEtMTIuNiA1LjEtOC41IDExIDEgMS40IDIuNSAyLjcgMy4xIDQuMi40IDEgLjggMiAxLjEgMyAuNyAyLjEtLjEgMi43IDEuMSAxbDQuNS0zLjRjLS4yLjEtLjUuMS0uNy4yaDRjLTIuNi0uNi01LTMuNC03LTUuMS0yLjQgNC4yLTQuOSA4LjQtNy4zIDEyLjUuNC4xLjIgMC0uNS0uNC0uMy0xLjMtLjctMi41LTEtMy44di40YzEuOC0yLjQgMy43LTQuOCA1LjUtNy4yLS43LjMtMy4xIDEuMS0yLjQgMS4yLTEuNC0uMy0yLjMtMS43LTIuOS0yLjctMS4yLTEuOS0zLjQtNi44LTMuMy04LS4zIDEuMy0uNyAyLjUtMSAzLjguMS0uMi4yLS4zLjMtLjVMMTIgMzIuNGMtMi42IDEuMS44IDEgMiAxLjMgMi4xLjUgMy43IDEuNSA1LjYgMi41IDEuOCAxIDMuNiAxLjggNS41IDIuNSAyLjQuOSAyLjQgMS42LjktLjUgNS40IDcuOSAxOC40LjQgMTMtNy42Ii8+PHBhdGggZD0iTTEwMS44IDU0YzMuNCAxLjMgNi4yIDMuOCAxMC4xIDMuOCAyLjIgMCA0LjQtLjMgNi41LS44LjgtLjIgMS43LS40IDIuNS0uNC0yLjEtMS4xLTIuNS0xLTEuMi4xIDEuOCAxLjggMi43IDUuMiAzLjcgNy41LjQgMSAuOSAxLjkgMS4zIDIuOC0xLjYtNC4yIDUuMi01LjguMy00LjEtMy4zIDEuMS02LjUgMS44LTkuNyAzLjItMy44IDEuNi03LjQgMy44LTExIDUuOS0zLjUgMi03IDQuMS0xMC43IDUuNS0xLjkuOC00IDEuMi02IDEuNy44LS4xLjYtLjEtLjUgMC0yLjEtLjItMS41LjQgMS43IDEuNi4zIDEuOS41IDMuOS44IDUuOC42LTIuNiA0LjUtNi4yIDYuNS04LjUgMy41LTQgNS4zLTguNCA3LjYtMTMuMiAxLjktMy45IDQtMSA3LjYuMyAxLjQuNSAyLjkgMSA0LjMgMS41LjQuMi45LjMgMS4zLjUgMS45LjggMS44IDEuOS4zLS42LS4zLTEuMy0uNy0yLjUtMS0zLjguMi0xLjUuOC0yLjcgMS44LTMuNS0uOC41LS43LjQtMS42LjctMS45LjctMy44IDEuMS01LjcgMS41LTUuMyAxLjItMTAuMSAzLjItMTUgNS40IDMgMy45IDYuMSA3LjkgOS4xIDExLjggMS0xLjEgMi0yLjMgMy0zLjUuNy0uOCAxLjQtMS41IDIuMS0yLjMgMS4zLTEgMS42LTEuMy44LS45LTEuOS0uMy0zLjktLjUtNS44LS44LTIuNS0xLjItMi4zLTIuNS0uNi4xLjggMS4zIDEuOCAyLjMgMi45IDMuMyAyLjMgMi4xIDUgMy4yIDcuOCA0LjQgNC42IDEuOSA5LjkgMS4zIDEyLjggNS45IDEuNCAyLjMgMi41IDQuOCAzLjggNy4yLjcgMS4yIDEuNCAyLjQgMS45IDMuNy4xLjUuMyAxIC40IDEuNSAwIDIuMiAxLjEgMS43IDMuNC0xLjMtMS42LjEtMy40LS42LTUtLjgtNC4xLS42LTguMi0uMy0xMi4yLS44IDEuOCA0LjMgMy41IDguNSA1LjMgMTIuOCAxLjMtMS4yIDMuMi0xLjkgNC42LTMgMi42LTIgNC43LTQuNiA1LjgtNy43IDItNS41LS40LTEwLjQtMy45LTE0LjYtNi03LjItMjIuMS0xMS4zLTI0LjggMS40LTEuOSA4LjggNC4xIDE1IDguNCAyMS45IDIuMiAzLjYgMi43IDguMyA0LjEgMTIuMyAxLjkgNSA0LjkgOS4xIDkuNSAxMS45IDIuMSAxLjMgNS41IDEuNSA3LjYgMCA1LjktNC40IDguMy0xMC40IDguOS0xNy42LjctOC42LTguNC0xMy4zLTE1LjMtOS4xLTQuNiAyLjgtNS4yIDEwLjQgMCAxMyAxLjQuNyAyLjYgMS4zIDQuMSAxLjUgMS4xLjIgMi4yLjMgMy4yLjMtMi42LTIuMy0zLjMtMi42LTIuMS0uOCAxLjQgMi42IDEuNCA3LjQgMS43IDEwLjMuMiAxLjkuNCAzLjguNiA1LjYuMi44LjMgMS43LjMgMi41IDMuNi0yLjMgNC4xLTMuMyAxLjYtMy00IDAtNy43IDAtMTEuNy42LTUuNi45LTE0IDIuNS0xNS43IDguOC0yLjUgOC45IDYuNCAxMS40IDEyLjYgMTMuOS0xLjEtNC4yLTIuMi04LjQtMy4zLTEyLjUtMi40IDIuNC00LjQgNS4xLTYuNCA3LjgtLjggMS4yLTEuOCAyLjMtMi44IDMuM2wxLjUtLjNjLS43LS4zLTEuNS0uNi0yLjMtLjgtOS4zLTMtMTIuOSAxMS4xLTQgMTQuNSA0LjEgMS41IDEwLjQgNC4yIDE0LjctLjYgNC44LTUuMy42LTExLjYtLjctMTcuMy0yLjEtOC45IDEzLjYtMTEuNiAxOS0xMy41IDYuNC0yLjIgNy4xLTkuOSAxLjgtMTMuNy0zLjQtMi40LTgtMi4yLTEyLTIuMS0xLjggMC0xMS0uNi0xMS41LTEuNy0yLjUtNi0yLjMtMTMtMi45LTE5LjMtLjUtNS41LS45LTEzLjItNC4xLTE3LjktMy45LTUuOS0xNC4zLTQuMS0xNCAzLjguMiA2LjQgNCAxMi45IDYuOCAxOC42IDEuNSAzIDMuNSA1LjcgNS42IDguNCAxIDEuMyA0LjYgNC43IDQuNSA2LjEuMy0xLjMuNy0yLjUgMS0zLjggMS0uNy45LS43LS40LjFsLTIuMSAxLjJjLTIuMSAxLjItNC4xIDIuOS02IDQuNS00LjQgMy43LTYuMiA4LjQtNi45IDEzLjktLjYgNS0uNiAxMC42LjQgMTUuNS42IDIuOC0uOCA2LjUtMyA4LjgtNi43IDcgMy45IDE3LjYgMTAuNiAxMC42IDQuOC01IDguOC0xMy40IDcuNS0yMC40LS44LTQuMy0uOC04LjQtLjctMTIuOC4xLTQgMy40LTUuOSA2LjYtNy44IDMuMy0xLjkgNi41LTMuOSA3LjYtNy44IDEuMi00LjQtMS04LjYtMy41LTEyLjEtMi41LTMuNi01LjQtNi42LTcuNi0xMC40LTEuOS0zLjItNS41LTguNy01LjYtMTIuNS00LjcgMS4zLTkuMyAyLjUtMTQgMy44IDEuMyAyIDEuMSA1IDEuNSA3LjMuNiAzLjMuOCA2LjYgMSAxMCAuNSA2LjYgMS4yIDE0LjUgNC44IDIwLjMgMy4yIDUuMiA5LjUgNi44IDE1LjEgNy43IDIuOS41IDYgLjkgOSAuOSAxLjIgMCA0LjQgMCA0LjQuMS42LTQuNiAxLjItOS4xIDEuOC0xMy43LTkuNCAzLjItMjAuMiA1LjctMjYuMiAxNC4zLTMuMiA0LjYtNC40IDEwLjQtMy41IDE2IC40IDIuNyAxLjIgNS4xIDIuMiA3LjYgMS44IDQuMiAxMC4zLTMuNiA2LTUtMS4yLS40LTIuMy0xLTMuNS0xLjQtMS4zIDQuOC0yLjcgOS42LTQgMTQuNSA1LjMgMS43IDkuNyAyIDE0LjItMS44IDQuMS0zLjUgNi40LTguNCAxMC4zLTEyLjEgNC41LTQuMyAxLjctMTAuNS0zLjMtMTIuNS0uNi0uMy0xLjItLjUtMS45LS43bC0xLjItLjNjLTEuNy0uNi0xLjYtLjUuMi41LjMgMS4zLjcgMi41IDEgMy44di0uN2MtLjMgMS4zLS43IDIuNS0xIDMuOC0uOSAxLjQtMyAyLS45IDEuNi44LS4yIDEuNS0uMyAyLjMtLjUgMy40LS45IDYuMy0xLjYgOS45LTEuNCA3LjUuMyAxNC42LTEuOSAxNS43LTEwLjUuNC0zLjEtLjQtNi4zLS43LTkuNS0uNC00LjEtMS4xLTguMS0xLjgtMTIuMS0uNS0yLjktMS45LTcuMy00LjQtOS4yLTEuMy0xLjEtMi40LTIuMS00LjEtMi42LS45LS4zLTQuNS0uNS00LjEtLjR2MTNjLjQtLjIuOC0uNSAxLjItLjctMS4zLjMtMi41LjctMy44IDEgLjMgMCAuNy0uMSAxLS4xLTEuMy0uMy0yLjUtLjctMy44LTEtMi45LTEuNC0xLjQtNC44LTIuMi0xLjMtLjIuNy0uOCAyLjYtMS4yIDIuOWg3LjZjLTMuNi0yLjItNC4xLTcuNy01LjItMTEuNS0xLjQtNC44LTMuOC04LjUtNi42LTEyLjUtMS4xLTEuNS0yLjMtMy4xLTMtNC44LS42LTEuNC0uMS0uOS0uOC43LTEuNCAzLjMtNS40LjEtMi4xIDIuMS45LjUgMS42IDEuNCAyLjMgMi4yLjkuOS0uNC4zLjItLjctMSAxLjctNS4yIDMuMy02LjcgNC43LTUuMiA1LS44IDEyLjEgNS4zIDEyLjggNC40LjUgOC43LjQgMTMuMSAxLjEgNC43LjggOS4xLjQgMTIuNy0zLjEgOC4zLTguMi0uNy0yMi4zLTUuMS0zMC4xLTIuMy00LTUuNy03LjQtOS45LTkuMi00LjQtMS45LTkuNC0yLjEtMTMuNi00LjUtMS4zLS43LTEuOS0yLjktMi45LTMuOS0yLTItNS4xLTIuOS03LjgtMi4yLTUuNCAxLjUtOC45IDYuNS0xMi41IDEwLjUtNS45IDYuNyAxLjQgMTUuMiA5LjEgMTEuOCA0LjEtMS44IDgtMy4yIDEyLjMtNC4xIDMuNy0uOCA3LjUtMS45IDEwLjctNCA0LjEtMi43IDYuNy04LjIgMy45LTEyLjgtMS43LTQuMy02LjctNS44LTEwLjktNy4zLTQtMS40LTguMS00LjItMTIuNC00LjItNi43IDAtMTIuMiAzLjktMTUuNSA5LjYtMS4yIDIuMi0yIDQuNi0zLjEgNi45LTEuMyAyLjYtMy40IDQuNi01LjMgNi44LTMuMyAzLjctOC44IDEwLjEtNy4zIDE1LjUgMy41IDEyLjcgMjAuOCA2LjQgMjguNiAyLjggNS4yLTIuNCAxMC01LjYgMTUtOC4zIDQuOC0yLjYgMTAtMy4zIDE0LjktNS42IDEwLjktNS4xIDMuOS0xNy41LS4zLTI1LjEtMi41LTQuNS02LjMtOC4xLTExLjYtOC43LTIuOS0uNC01LjYuNy04LjQgMS0yLjIuMy01LjYtMi40LTcuNy0zLjItMy44LTEuNS04LjIgMS42LTkuMiA1LjItMS4xIDQuNCAxLjUgNy45IDUuMyA5LjMiLz48cGF0aCBkPSJNNzUuNSA4MS4zYy01LjUuOS0xMC43IDYuNS0xNS4xIDkuNy01LjggNC4yLTEwLjUgOS4zLTE0LjUgMTUuMi00IDUuNy02LjcgMTIuMS05LjMgMTguNi0yLjkgNy4xLTUuNiAxNC4xLTYuNSAyMS43LS40IDMuMi4xIDYuNi0uOCA5LjYtLjggMi44LTEuMSA1LjkuNCA4LjUgNC41IDcuNyAxMi4zIDMuMiAxOC43IDIuOCAxNC43LS44IDI5LjUgMy45IDQ0LjEgMS40IDE1LjktMi44IDE1LjUtMjEuMyAxNy41LTMzLjYgMi4yLTEzLjYgNy4zLTMwLjEuOC00My4zQzEwMi45IDc1LjggODUgODkgNzUgOTUuMWMtMTEuOCA3LjItMjIuNCAxOC4yLTI4LjIgMzAuOS0zLjkgOC41LTEwLjcgMTkuOC0zLjEgMjguMSA1LjUgNiAxNC4zIDcuMiAyMS45IDguMiA5LjYgMS4yIDIyLjggMyAzMS4yLTIuNyA4LjktNi4xIDEzLjctMTguNiAxNS4yLTI4LjggMS40LTkuOSAxLjUtMjEuNi0yLTMxLjEtMS45LTUuMy01LjMtOC45LTEwLjUtMTEtNS44LTIuMy0xMi4xIDIuMy0xNi41IDUuNC05LjcgNi44LTE0IDE5LTIxLjcgMjcuNy00LjMgNC44LTkgOS4zLTEzLjYgMTMuOC0zLjkgMy44LTcgOC40LTEwLjMgMTIuMi01IDUuOS0uMiAxMy45IDcuMyAxMi41IDcuMy0xLjMgMTMuNi01IDIwLjUtNy42IDcuNC0yLjggMTQuMS0xLjEgMjEuNi0uMSAxNC45IDIgMTcuNS0xNC45IDE4LjUtMjUuOC43LTcuMiAxLjctMTYuMS0uNy0yMy0yLjUtNy41LTEwLjgtOC4xLTE2LjMtMy40LTQuNCAzLjgtNy41IDkuMi0xMC41IDE0LjEtMi4xIDMuNC00LjIgNi44LTYuOCA5LjgtMi4xIDIuNS02LjIgNC04LjggNi4xLTMuOSAzLjEtMi4zIDkuNSAxLjUgMTEuOCAzLjYgMi4yIDggMS44IDEyLjEgMiA1LjMuMyAxMC4zLS41IDE0LjgtMy4zIDcuNC00LjUgNi45LTE2LjcgMy4zLTIzLjYtNC40LTguNi0xNy40LTEtMTMgNy42LS42LTEuMiAwIDEuOCAwIDIgMCAuOC4xIDEuNi4yIDIuNCAwIDEuOC4yIDEuNi42LS42LTEuNyAxLTQuMy42LTYuMS41LS43IDAtNS4zLS41LTQuNSAwIC41IDMuOSAxIDcuOSAxLjUgMTEuOCAyLjgtMi4zIDYuMS0zLjUgOC44LTYgMi45LTIuOCA1LjEtNi42IDcuMy05LjkgMi4yLTMuNCA0LjMtNi45IDYuNi0xMC4yLjYtLjkgMy4xLTMuMSAyLjMtMi45aC00Yy0xLjEtMS0yLjItMi4xLTMuMy0zLjEuMSAxIC4yIDIgLjIgMy4xLjEgMS45LjEgMy43LjEgNS42IDAgNC4zLS40IDguNy0uOSAxMy0uMiAxLjktLjcgNC4xLTEuMyA2LjItLjMgMS0uNSAxLjItMS4xIDIuMS40LS42IDEtLjkgMS43LS44LTEtLjItMi0uNS0yLjktLjctNy43LTEuOS0xNS43LTEuNC0yMy40LjVzLTE0LjIgNi42LTIyLjIgOC4xYzIuNCA0LjIgNC45IDguNCA3LjMgMTIuNSAxLjgtMi4xIDMuOC0zLjYgNS4yLTYuMiAxLjUtMi44IDQtNSA2LjItNy4yIDUuNS01LjUgMTEuMS0xMC45IDE2LjEtMTYuOSA0LjMtNS4xIDcuNS0xMS4xIDExLjMtMTYuNiAxLjctMi41IDMuOC00LjYgNi4zLTYuMyAxLjEtLjggMi4zLTEuNyAzLjYtMi4xLTIuMS44LTEuNy0xLS43IDEuNyAxLjggNSAxLjggMTAuNyAxLjggMTUuOSAwIDYuNy0xIDEzLjQtNC4zIDE5LjMtMS4yIDIuMS0yLjQgNC4zLTQgNi4xLTEuNyAyLTMuNyAxLjktNi4xIDItNS42LjMtMTMuNC0uMi0xNy42LS44LTMuNS0uNS03LjQtMS4xLTEwLjQtMi44LTEuMy0uNy0uMy0uNC0uNC42LjYtMy40IDIuOS02LjggNC4yLTEwIDUuMS0xMy4yIDE1LjYtMjIuNiAyNy40LTI5LjYgMy4xLTEuOCA2LjMtMy43IDkuNS01LjQuNS0uMyAxLjEtLjYgMS42LS44IDEuNi0uNCAxLjUtLjgtLjQtMSAuNi44LjcgMi4yLjkgMy4xIDEuNyA3LjMtLjIgMTQuOS0xLjQgMjIuMS0xLjMgNy42LTIuNSAxNS4zLTMuNyAyMi45LS4zIDEuOC0uMiA0LjktMS41IDYuMy0yLjEgMi4zLTYuMSAxLjctOC44IDEuNi03LjgtLjQtMTUuNS0xLjEtMjMuMy0xLjctMy43LS4zLTcuNS0uMy0xMS4yLS4yLTEuOCAwLTMuNS4zLTUuMi42LTEgLjMtMS45LjUtMi45LjktMy4yLjUtMi4yIDEuOCAyLjkgNC4xdjRjLjUtMi45IDEuMy01LjYgMS41LTguNi4yLTMuNS4zLTYuNiAxLjEtMTAgMS43LTcuMiA0LjktMTQuMyA4LTIxIDIuNy01LjcgNi4yLTEwLjkgMTAuNi0xNS40IDIuNC0yLjUgNS4zLTQuNCA4LjEtNi4zIDEuOS0xLjMgNC43LTQuNiA2LjktNC45IDkuOS0xLjcgNS44LTE2LjItMy42LTE0LjYiLz48cGF0aCBkPSJNMzAuMyAxNzYuNXYtNy44aDkyLjZ2Ny44IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTMwLjMgMTc2LjV2LTcuOGg5Mi42djcuOCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik00NCAxODIuNWMtLjEtLjMtLjEtLjYtLjItLjktLjYgMi40LTEuMyA0LjktMS45IDcuM2wuNi0uNkgzMS44YzQuNSA1IDEwLjggNC41IDE2LjkgMy43IDcuNC0xIDE1LjMtMS4xIDIyLjctLjQgNy45LjcgMTUuNi0uMyAyMy40LS4xIDQuMS4xIDggLjUgMTIuMS4zIDIuOS0uMSA2LjItMS41IDguOS0uNSA5LjEgMy4zIDEzLTExLjIgNC0xNC41LTUuNy0yLTEyLjIuMS0xOC4xLjEtMy41IDAtNy0uNC0xMC41LS40LTQuMiAwLTguNC42LTEyLjYuNi03LjUuMS0xNC42LTEuMi0yMi4xLS42LTMuMi4yLTYuNC4yLTkuNi43LS45LjEtMS45LjMtMi44LjQtLjguMS0xLjYuMS0yLjQuMS0uNC0uMi0uMy0uMS41LjEtMi43LTMtNy45LTIuOS0xMC42IDAtMi41IDIuNi0zLjIgNS4yLTIuMyA4LjggMi41IDkuMyAxNyA1LjMgMTQuNy00LjEiLz48cGF0aCBkPSJNNzYuNiAxNzYuNUgzMC4zdjE1LjhoOTIuNnYtMTUuOHptNS05Mi4yYy01My43IDguNS01MS4zIDg0LjMtNTEuMyA4NC4zIiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTExMy4zIDQ4LjhjMTMuNS0yLjYgMTcuMS0xMi4yIDE3LjEtMTIuMkMxMjIuNiAxNS4xIDEwNy4zIDQgMTA3LjMgNHMtMTEgMTAuMi0xMS4yIDE1LjFjMCAwLTE0LjMtOS40LTMyLjYtMS40IDAgMC0yMCAxMC40LTM2LjkgNC4zIDAgMC0yMS4yLTguNS0yMi42LTIuNyAwIDAtMy4zIDEwLjUgMi41IDIwLjUgMCAwIDUuOCA5LjMgOC40IDkuMyAwIDAgMjEuNiAyLjUgMTguNSAzLjUgMCAwLTEuNCA0LjYtMTYuMiAzLjggMCAwLTUuMy0uMS00LjMgNUMxNCA2Ni44IDE3LjcgNzIgMjggNzMuOWMwIDAgOS43IDIuOSAyNiAuNXMxMyAxNC40IDEzIDE0LjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTIwLjMgNzQuM2MxMy41LjcgMTkuOS02LjMgMTkuOS02LjNzLTMuNC0xNC4yLTE0LTI1LjciIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNNzkuOSAzNC44YzAgMi0xLjYgMy42LTMuNSAzLjZzLTMuNS0xLjYtMy41LTMuNiAxLjYtMy42IDMuNS0zLjZjMiAuMSAzLjUgMS43IDMuNSAzLjYiIGZpbGw9IiNmZmYiLz48ZWxsaXBzZSBjeD0iNzYuNCIgY3k9IjM0LjgiIGZpbGw9Im5vbmUiIHJ4PSIzLjUiIHJ5PSIzLjYiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjQiLz48cGF0aCBkPSJNNzYuMSAzMS4zcy0zLjgtLjEtNy42IDMuNyIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNCIvPjxwYXRoIGQ9Ik0xMzYuNiA3MS4yYzExLjYgMTUuNyAxMy4yIDMyLjkgMTMuMiAzMi45cy05LjcgNi43LTI3IDIuOSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0xMjIuNiAxNDMuMmMxNy4xIDcuMyAyOC43IDEuNyAyOC43IDEuN3MyLjQtMTkuNC01LjctMzguOG0tMjIuNyA2Mi42czIuMi0xOS42IDIyLTIyLjEiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTAzLjYgMTE1LjJjLTEuMS44LS44LjcuNy0uNCAxLjMtLjkgMi44LTEuNiA0LjItMi4zIDMtMS41IDYuMi0yLjUgOS4zLTMuOCA1LjMtMi4zIDExLTUuOSAxNi44LTYgNy40LS4xIDEwLjQtMTAuMiAzLjgtMTQtNi4xLTMuNS0xMi44LTQuOC0xOS40LTYuOS03LjUtMi4zLTEzLjgtNi4yLTIwLjYtMTAtOC40LTQuOC0xNiA4LjEtNy42IDEzIDYuOCAzLjkgMTMuNCA3LjkgMjAuOCAxMC41IDYuMyAyLjIgMTMuMyAzLjEgMTkuMSA2LjUgMS4zLTQuNyAyLjUtOS4zIDMuOC0xNC04LjUuMi0xNS4xIDQuMS0yMi44IDcuMy02LjYgMi44LTE3LjggNS40LTIxLjIgMTIuNS0zLjkgOC43IDkgMTYuMyAxMy4xIDcuNiIvPjwvZz48L3N3aXRjaD48L3N2Zz4='); } -body.base .is2d piece.bishop.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii00OC4zNSAtMTAgMjIwIDIyMCIgd2lkdGg9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHN3aXRjaD48Zz48cGF0aCBkPSJNMzAuNCAxNjguN2MtMTMuOC05LjQtMjMuNy0yNS44LTI2LjMtNDIuNEMxLjMgMTA4LjUgNi42IDkwLjUgMTUgNzVjNC42LTguNSAxMC4xLTE2LjUgMTYuMS0yNGwyMi43IDMxIDE2LTE2LjMtMjMuNy0zMS41YzUtNS4yIDEwLjMtMTAuMSAxNS42LTE1aC0uMWMxMDkuNiA5OC4yIDMxLjMgMTQ5LjUgMzEuMyAxNDkuNSIvPjxwYXRoIGQ9Ik0zMC40IDE2OC43Yy0xMy44LTkuNC0yMy43LTI1LjgtMjYuMy00Mi40QzEuMyAxMDguNSA2LjYgOTAuNSAxNSA3NWM0LjYtOC41IDEwLjEtMTYuNSAxNi4xLTI0bDIyLjcgMzEgMTYtMTYuMy0yMy43LTMxLjVjNS01LjIgMTAuMy0xMC4xIDE1LjYtMTVoLS4xYzEwOS42IDk4LjIgMzEuMyAxNDkuNSAzMS4zIDE0OS41IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTY5LjUgMTEuMmMwIDQuNC0zLjUgOC03LjkgOHMtNy45LTMuNi03LjktOCAzLjUtOCA3LjktOCA3LjkgMy42IDcuOSA4Ii8+PGVsbGlwc2UgY3g9IjYxLjYiIGN5PSIxMS4yIiBmaWxsPSJub25lIiByeD0iNy45IiByeT0iOCIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0xNS40IDE3Ni42di03LjlIMTA4djcuOSIgZmlsbD0iI2ZmZiIvPjxwYXRoIGQ9Ik0xNS40IDE3Ni42di03LjlIMTA4djcuOSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik02MS43IDE3Ni42SDE1LjR2MTUuN0gxMDh2LTE1Ljd6Ii8+PHBhdGggZD0iTTYxLjcgMTc2LjZIMTUuNHYxNS43SDEwOHYtMTUuN3oiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48L2c+PC9zd2l0Y2g+PC9zdmc+'); } -body.base .is2d piece.rook.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii02My4zNSAtMTAgMjIwIDIyMCIgd2lkdGg9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHN3aXRjaD48Zz48cGF0aCBkPSJNOTYgMTY4LjVjLS4yLTU4LjgtMTUuMi0xMDEuOS0xNS4yLTEwMS45TDk2IDU4LjRWMy4zSDcyLjhWMTlINjEuM1YzLjNIMzguMVYxOUgyNi42VjMuM0gzLjR2NTUuMWwxNS4yIDguM3MtMTUuMSA0My0xNS4yIDEwMS45Ii8+PHBhdGggZD0iTTk2IDE2OC41Yy0uMi01OC44LTE1LjItMTAxLjktMTUuMi0xMDEuOUw5NiA1OC40VjMuM0g3Mi44VjE5SDYxLjNWMy4zSDM4LjFWMTlIMjYuNlYzLjNIMy40djU1LjFsMTUuMiA4LjNzLTE1LjEgNDMtMTUuMiAxMDEuOSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0zLjQgMTc2LjR2LTcuOUg5NnY3LjkiIGZpbGw9IiNmZmYiLz48cGF0aCBkPSJNMy40IDE3Ni40di03LjlIOTZ2Ny45IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTQ5LjcgMTc2LjRIMy40djE1LjdIOTZ2LTE1Ljd6Ii8+PHBhdGggZD0iTTQ5LjcgMTc2LjRIMy40djE1LjdIOTZ2LTE1Ljd6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTE4LjYgNjYuNmg2Mi4yTTMuNCA1Ny41SDk2IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI0Ii8+PC9nPjwvc3dpdGNoPjwvc3ZnPg=='); } -body.base .is2d piece.queen.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii0xNC4xNSAtMTAgMjIwIDIyMCIgd2lkdGg9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHN3aXRjaD48Zz48cGF0aCBkPSJNMTQyLjIgMTY3LjNzLjYtNy4zLTMuNi04LjJjLTIzLjgtNC42IDM2LjktOTYuNCAzNi45LTk2LjRzLTU1LjIgNjIuMS01MS44LTQ1LjVsLS44LS41Yy0yNy44IDk4LjEtNTMuNyAwLTUzLjcgMGwtMSAuNmMzLjQgMTA3LjYtNTEuOCA0NS41LTUxLjggNDUuNXM2MC43IDkxLjggMzYuOSA5Ni40Yy00LjIuOC0zLjYgOC4yLTMuNiA4LjIiLz48cGF0aCBkPSJNMTQyLjIgMTY3LjNzLjYtNy4zLTMuNi04LjJjLTIzLjgtNC42IDM2LjktOTYuNCAzNi45LTk2LjRzLTU1LjIgNjIuMS01MS44LTQ1LjVsLS44LS41Yy0yNy44IDk4LjEtNTMuNyAwLTUzLjcgMGwtMSAuNmMzLjQgMTA3LjYtNTEuOCA0NS41LTUxLjggNDUuNXM2MC43IDkxLjggMzYuOSA5Ni40Yy00LjIuOC0zLjYgOC4yLTMuNiA4LjIiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNNDkuNiAxNzYuM3YtNy45aDkyLjZ2Ny45IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTQ5LjYgMTc2LjN2LTcuOWg5Mi42djcuOSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik03NC4zIDkuOGMuOSA1LjQtMy43IDEwLTkgOS4xLTMuMi0uNS01LjgtMy4yLTYuMy02LjUtLjktNS40IDMuNy0xMCA5LTkuMSAzLjIuNiA1LjggMy4yIDYuMyA2LjUiLz48cGF0aCBkPSJNNzQuMyA5LjhjLjkgNS40LTMuNyAxMC05IDkuMS0zLjItLjUtNS44LTMuMi02LjMtNi41LS45LTUuNCAzLjctMTAgOS05LjEgMy4yLjYgNS44IDMuMiA2LjMgNi41eiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0xOC43IDU2LjNjLjkgNS40LTMuNyAxMC05IDkuMS0zLjItLjUtNS44LTMuMi02LjMtNi41LS45LTUuNCAzLjYtMTAgOS05LjEgMy4yLjYgNS44IDMuMiA2LjMgNi41Ii8+PHBhdGggZD0iTTE4LjcgNTYuM2MuOSA1LjQtMy43IDEwLTkgOS4xLTMuMi0uNS01LjgtMy4yLTYuMy02LjUtLjktNS40IDMuNi0xMCA5LTkuMSAzLjIuNiA1LjggMy4yIDYuMyA2LjV6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTU4LjEgMTU2LjloNzUuNiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZmZmIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNCIvPjxwYXRoIGQ9Ik0xMTcuNSA5LjdjLS45IDUuNCAzLjcgMTAgOSA5LjEgMy4yLS41IDUuOC0zLjIgNi4zLTYuNS45LTUuNC0zLjctMTAtOS05LjEtMy4yLjYtNS44IDMuMi02LjMgNi41Ii8+PHBhdGggZD0iTTExNy41IDkuN2MtLjkgNS40IDMuNyAxMCA5IDkuMSAzLjItLjUgNS44LTMuMiA2LjMtNi41LjktNS40LTMuNy0xMC05LTkuMS0zLjIuNi01LjggMy4yLTYuMyA2LjV6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTE3My4xIDU2LjJjLS45IDUuNCAzLjcgMTAgOSA5LjEgMy4yLS41IDUuOC0zLjIgNi4zLTYuNS45LTUuNC0zLjctMTAtOS05LjEtMy4yLjYtNS44IDMuMi02LjMgNi41Ii8+PHBhdGggZD0iTTE3My4xIDU2LjJjLS45IDUuNCAzLjcgMTAgOSA5LjEgMy4yLS41IDUuOC0zLjIgNi4zLTYuNS45LTUuNC0zLjctMTAtOS05LjEtMy4yLjYtNS44IDMuMi02LjMgNi41eiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik05NS45IDE3Nkg0OS42djE1LjdoOTIuNlYxNzZ6Ii8+PHBhdGggZD0iTTk1LjkgMTc2SDQ5LjZ2MTUuN2g5Mi42VjE3NnoiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTY0LjcgNzYuNGwtNjcuNSA3OC45Yy0uNC41LTEuMy4yLTEuMy0uNUw3MS41IDM0LjciIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjQiLz48cGF0aCBkPSJNMTIwIDM0LjdMOTYuNyAxNTMuM2MtLjMgMS40LTIuMSAxLjktMyAuOEwyNyA3Ni41IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI0Ii8+PC9nPjwvc3dpdGNoPjwvc3ZnPg=='); } -body.base .is2d piece.king.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEiIHZpZXdCb3g9Ii0xNC4wNSAtMTAgMjIwIDIyMCIgd2lkdGg9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHN3aXRjaD48Zz48cGF0aCBkPSJNOTYuMSAxNzYuM0g0OS44djE1LjhoOTIuNXYtMTUuOHoiLz48cGF0aCBkPSJNOTYuMSAxNzYuM0g0OS44djE1LjhoOTIuNXYtMTUuOHoiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNNDkuOCAxNjguNXY3LjhoOTIuNXYtNy44IiBmaWxsPSIjZmZmIi8+PHBhdGggZD0iTTQ5LjggMTY4LjV2Ny44aDkyLjV2LTcuOCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIHN0cm9rZS13aWR0aD0iNiIvPjxwYXRoIGQ9Ik0xMDMuNyA2OC40VjQyLjVoMjMuMlYyNi43aC0yMy4ybC4xLTIzLjZIODguM3YyMy42SDY1LjJ2MTUuOGgyMy4xdjI1LjkiLz48cGF0aCBkPSJNMTAzLjcgNjguNFY0Mi41aDIzLjJWMjYuN2gtMjMuMmwuMS0yMy42SDg4LjN2MjMuNkg2NS4ydjE1LjhoMjMuMXYyNS45IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI2Ii8+PHBhdGggZD0iTTE4Ny4zIDc1LjdDMTgwLjEgNDcgMTUyLjggNDQgMTUyLjggNDQgMTE0LjMgMzguNiA5Ni40IDgwLjggOTYgODEuOGMtLjQtMS0xOC4zLTQzLjMtNTYuOC0zNy45IDAgMC0yNy40IDMtMzQuNSAzMS43IDAgMC0xMy44IDUxLjggNDUgOTIuOGg5Mi41YzU4LjgtNDAuOSA0NS4xLTkyLjcgNDUuMS05Mi43Ii8+PHBhdGggZD0iTTE4Ny4zIDc1LjdDMTgwLjEgNDcgMTUyLjggNDQgMTUyLjggNDQgMTE0LjMgMzguNiA5Ni40IDgwLjggOTYgODEuOGMtLjQtMS0xOC4zLTQzLjMtNTYuOC0zNy45IDAgMC0yNy40IDMtMzQuNSAzMS43IDAgMC0xMy44IDUxLjggNDUgOTIuOGg5Mi41YzU4LjgtNDAuOSA0NS4xLTkyLjcgNDUuMS05Mi43em0tOTktNy4zaDE1LjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNMTQ3LjUgNjcuMmMtMjUuMS0yLjItNDMuNiA1MC45LTQzLjYgNTAuOXYzMi44czI2LjItLjYgNDYuNi0yMS44YzIwLjQtMjEuNCAyMi4xLTU5LjgtMy02MS45em0tMTAzIDBjLTI1LjEgMi4yLTIzLjQgNDAuNi0zIDYxLjlzNDYuOCAyMS44IDQ2LjggMjEuOHYtMzIuOFM2OS42IDY1IDQ0LjUgNjcuMnoiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2Utd2lkdGg9IjYiLz48cGF0aCBkPSJNOTYgMTguOHYzOS40TTgwLjYgMzQuNmgzMC45IiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIgc3Ryb2tlLXdpZHRoPSI0Ii8+PC9nPjwvc3dpdGNoPjwvc3ZnPg=='); } diff --git a/public/stylesheets/piece/riohacha.css b/public/stylesheets/piece/riohacha.css deleted file mode 100644 index e44b2156e9..0000000000 --- a/public/stylesheets/piece/riohacha.css +++ /dev/null @@ -1,12 +0,0 @@ -body.base .is2d piece.pawn.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iNTM1IDEzNTAgMTMzMyAxMzMzIiB3aWR0aD0iMTMzIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Im0xNTkwIDI1MDB2LTk5bC04Ny0zLTg3LTMtNTYtMTgyLTU3LTE4MiAzMC0yOGM2Mi01OCA4Mi0xNDcgNTEtMjIxLTUyLTEyNi0yMTEtMTY2LTMxMS03OS05MSA4MC05NiAyMDctMTIgMjkwbDM5IDM5LTU4IDE4Mi01OCAxODEtODIgMy04MiAzdjE5OWg3NzB6IiBmaWxsPSIjZjhmOGY4Ii8+PHBhdGggZD0ibTgyMCAyNTAwdi05OWw4Mi0zIDgyLTMgNTgtMTgxIDU4LTE4Mi0zOS0zOWMtMzgtMzgtNjEtOTEtNjEtMTQ0IDAtMzAgMTktODkgMjktODkgMyAwIDY1IDU5IDEzNiAxMzAgODQgODQgMTM1IDEyOCAxNDUgMTI1IDE3LTYgMjItMTAtNzcgNjhsLTYwIDQ4LTEyIDExN2MtMTYgMTU0LTE1IDE1Mi01NyAxNTJoLTM0djIwMGgtMjUweiIgZmlsbD0iI2QzZDNkMyIvPjxwYXRoIGQ9Im0xMDcwIDI1MDB2LTEwMGgzNGM0MiAwIDQxIDIgNTctMTUybDEyLTExNyA2NC01MSA2My01MSAxMCAyNmM2IDE1IDEwIDMxIDEwIDM4IDAgMTEgMjQgODcgNzUgMjM3bDIzIDY1IDg2IDMgODYgM3YxOTloLTUyMHptOTEtNjE0LTEzMy0xMzQgNDEtNDBjNTUtNTMgMTE3LTY4IDE5MC00NyAxMTMgMzQgMTcwIDE3NiAxMTUgMjg3LTEzIDI1LTU5IDY4LTczIDY4LTMgMC02Ni02MC0xNDAtMTM0eiIgZmlsbD0iI2Y4ZjhmOCIvPjxwYXRoIGQ9Im0xNTkwIDI1MDB2LTk5bC04Ny0zLTg3LTMtNTYtMTgyLTU3LTE4MiAzMC0yOGM2Mi01OCA4Mi0xNDcgNTEtMjIxLTUyLTEyNi0yMTEtMTY2LTMxMS03OS05MSA4MC05NiAyMDctMTIgMjkwbDM5IDM5LTU4IDE4Mi01OCAxODEtODIgMy04MiAzdjE5OWg3NzB6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMjQiLz48L3N2Zz4='); } -body.base .is2d piece.knight.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iMjc4MCAxMzUwIDEzMzMgMTMzMyIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtMzgzMCAyNTAwdi05OWwtMTA2LTMtMTA2LTMgODItNjkgODItNjktMTY4LTE2OC0xNjctMTY3IDI2LTE2YzQzLTI5IDkxLTMxIDE0MS02IDI1IDEyIDQ2IDI2IDQ2IDMxIDAgMjIgMjIgNSA2Ny01MyAyOC0zNSA1My02OCA1Ny03NSA0LTgtNjYtNjEtMjEyLTE1OWwtMjIwLTE0Ni00MiAyMmMtMTkwIDk3LTI3MyAzNDAtMTgzIDUzMSAxNiAzNSAzOSA3NSA1MSA4OWwyMSAyNS00NSA0Ni00NSA0NiA4MiA2OSA4MSA2OS0xMDYgMy0xMDYgM3YxOTloNzcweiIgZmlsbD0iI2Y4ZjhmOCIvPjxnIGZpbGw9IiNkM2QzZDMiPjxwYXRoIGQ9Im0zMDYwIDI1MDB2LTk5bDEwNi0zIDEwNi0zLTgxLTY5LTgyLTY5IDQ1LTQ2IDQ1LTQ2LTIxLTI1Yy0xMi0xNC0zNS01NC01MS04OS01NS0xMTYtNDctMjY0IDE5LTM3NyAzMS01MiAxMDgtMTI2IDE2Mi0xNTMgNTMtMjcgNjItMjcgMjYgMi00NiAzNS03MyA2OC0xMDMgMTI3LTEyNCAyMzkgNiA1MjUgMjY3IDU5MSAzNSA4IDYzIDE3IDY0IDIwIDEgMi05IDM0LTIxIDcybC0yMyA2N2gtMTU4djIwMGgtMzAweiIvPjxwYXRoIGQ9Im0zMzUwIDE5MjN2LTk3bDQ4IDQ3YzQwIDM5IDUwIDQ1IDYyIDM1IDEzLTExIDEzLTExIDIgMi0xMCAxMi00IDIyIDM1IDYybDQ3IDQ4aC0xOTR6Ii8+PC9nPjxwYXRoIGQ9Im0zMzYwIDI1MDB2LTEwMGgxNThsMjEtNjJjMTItMzUgMjEtNjcgMjEtNzIgMS01LTI3LTE3LTYyLTI1LTI2MS02Ni0zOTAtMzUwLTI2OC01OTEgMjctNTIgMTAzLTE0MCAxMjItMTQwIDEyIDAgNDI4IDI3OSA0MjggMjg3IDAgNi03NCAxMDYtMTAxIDEzNy01IDUtMTYgMC0yNi0xMS0zNy00My0xMjYtNTUtMTc4LTIzbC0zMCAxOC00Ny00Ni00OC00NnYxOTRoMTk1bDExNSAxMTUgMTE0IDExNC0yMCAyM2MtMTAgMTMtMjUgMjctMzMgMzItNyA0LTMwIDI0LTQ5IDQyLTIwIDE5LTQwIDM0LTQ0IDM0cy04IDUtOCAxMGMwIDYgNDIgMTAgMTA1IDEwaDEwNXYyMDBoLTQ3MHoiIGZpbGw9IiNmOGY4ZjgiLz48cGF0aCBkPSJtMzgzMCAyNTAwdi05OWwtMTA2LTMtMTA2LTMgODItNjkgODItNjktMTY4LTE2OC0xNjctMTY3IDI2LTE2YzQzLTI5IDkxLTMxIDE0MS02IDI1IDEyIDQ2IDI2IDQ2IDMxIDAgMjIgMjIgNSA2Ny01MyAyOC0zNSA1My02OCA1Ny03NSA0LTgtNjYtNjEtMjEyLTE1OWwtMjIwLTE0Ni00MiAyMmMtMTkwIDk3LTI3MyAzNDAtMTgzIDUzMSAxNiAzNSAzOSA3NSA1MSA4OWwyMSAyNS00NSA0Ni00NSA0NiA4MiA2OSA4MSA2OS0xMDYgMy0xMDYgM3YxOTloNzcweiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjI0Ii8+PC9zdmc+'); } -body.base .is2d piece.bishop.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iMzg5MCAxMzUwIDEzMzAgMTMzMCIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNDk1MCAyNTAwdi0xMDBoLTE4NmwtMzgtMTYyYy0yMS05MC00MC0xNjgtNDMtMTc0LTItNiAzMC01NCA3Mi0xMDcgNDEtNTQgNzUtMTAyIDc1LTEwOHMtMjEtMzgtNDctNzFsLTQ3LTYxLTI2IDMxLTI3IDMyLTMyLTQ1LTMyLTQ1IDIwLTI5YzEyLTE2IDIxLTMyIDIxLTM2IDAtMTAtOTItMTI1LTk5LTEyNS0zIDEtMzcgNDItNzYgOTMtMzggNTAtOTkgMTI4LTEzMyAxNzRsLTY0IDgyIDc4IDEwMSA3OCAxMDEtMzIgMTM3Yy0xOCA3NS0zNyAxNTQtNDMgMTc1bC0xMCAzN2gtMTc5djIwMGg3NzB6IiBmaWxsPSIjZjhmOGY4Ii8+PHBhdGggZD0ibTQxODAgMjUwMHYtMTAwaDE3OWwxMC0zN2M2LTIxIDI1LTEwMCA0My0xNzVsMzItMTM3LTc3LTEwMGMtNDItNTUtNzctMTAxLTc3LTEwM3M1NC0xIDExOSAybDExOSA1IDcyIDkzYzM5IDUwIDc0IDkyIDc4IDkyczggMTEgOCAyNWMxIDE0LTIgMjUtNiAyNS01IDAtMzggMTgtNzQgNDFsLTY0IDQwLTcgOTdjLTkgMTM0LTggMTMyLTYxIDEzMmgtNDR2MjAwaC0yNTB6bTQyMi02OTljLTE4LTIyLTMyLTQzLTMyLTQ4IDAtNCAxMC0yMSAyMy0zN2wyMy0yOSAzNiA0OSAzNiA0OC0yMSAyOGMtMTEgMTUtMjQgMjgtMjcgMjgtNCAwLTIxLTE4LTM4LTM5eiIgZmlsbD0iI2QzZDNkMyIvPjxwYXRoIGQ9Im00NDMwIDI1MDB2LTEwMGg0NGM1MyAwIDUyIDIgNjEtMTMybDctOTcgNjQtNDBjMzYtMjMgNjktNDEgNzMtNDEgNyAwIDIwIDQ2IDYzIDIyM2wyMSA4N2gxODd2MjAwaC01MjB6bTE2OC01NTUtNzMtOTVoLTExMmMtNjIgMC0xMTMtMy0xMTItNyAwLTkgMzEtNTAgMTU3LTIwOCA1MC02NCA5Mi0xMjEgOTItMTI2IDAtMjAgMTgtNSA2MyA1Nmw0OCA2NC00NSA1OGMtMjUgMzItNDYgNjItNDYgNjYgMCAxMSA2MSA4NyA3MCA4NyA0IDAgMjYtMjcgNTAtNjAgMjQtMzIgNDYtNTcgNTEtNTUgNCAzIDI2IDMzIDQ5IDY2bDQxIDYxLTQ3IDYxYy0yNyAzNC02MCA3Ny03NCA5NC0xNCAxOC0yOCAzMy0zMiAzM3MtNDAtNDMtODAtOTV6IiBmaWxsPSIjZjhmOGY4Ii8+PHBhdGggZD0ibTQ5NTAgMjUwMHYtMTAwaC0xODZsLTM4LTE2MmMtMjEtOTAtNDAtMTY4LTQzLTE3NC0yLTYgMzAtNTQgNzItMTA3IDQxLTU0IDc1LTEwMiA3NS0xMDhzLTIxLTM4LTQ3LTcxbC00Ny02MS0yNiAzMS0yNyAzMi0zMi00NS0zMi00NSAyMC0yOWMxMi0xNiAyMS0zMiAyMS0zNiAwLTEwLTkyLTEyNS05OS0xMjUtMyAxLTM3IDQyLTc2IDkzLTM4IDUwLTk5IDEyOC0xMzMgMTc0bC02NCA4MiA3OCAxMDEgNzggMTAxLTMyIDEzN2MtMTggNzUtMzcgMTU0LTQzIDE3NWwtMTAgMzdoLTE3OXYyMDBoNzcweiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjI0Ii8+PC9zdmc+'); } -body.base .is2d piece.rook.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iMTY3MCAxMzUwIDEzMzMgMTMzMyIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtMjcxMCAyNTAwdi05OWwtNjItMy02My0zLTIyLTIxMGMtMzAtMjg3LTMzLTI1NiAzNy0yOTlsNjAtMzgtMi0xNjEtMy0xNjItNTctMy01OC0zdjEwMWgtMTA5bC0zLTQ3LTMtNDhoLTE5MGwtMyA0OC0zIDQ3aC0xMDl2LTEwMWwtNTcgMy01OCAzLTMgMTYzLTIgMTYyIDQ2IDI4YzI1IDE1IDUyIDMyIDYwIDM3IDEyIDkgMTEgMzktNiAyMTUtMTEgMTEzLTIzIDIyMC0yNiAyMzhsLTUgMzJoLTEyOXYyMDBoNzcweiIgZmlsbD0iI2Y4ZjhmOCIvPjxnIGZpbGw9IiNkM2QzZDMiPjxwYXRoIGQ9Im0xOTQwIDI1MDB2LTEwMGgxMjlsNS0zMmMzLTE4IDE1LTEyNSAyNi0yMzggMTctMTc2IDE4LTIwNiA2LTIxNS04LTUtMzUtMjItNjAtMzdsLTQ2LTI4IDItMTYyIDMtMTYzIDU4LTMgNTctM3Y1MWMwIDQ5IDEgNTAgMzAgNTBoMzB2MjMwaDIzOGwyMzcgMS01NCAzNGMtMzAgMTktNTcgMzgtNjAgNDItMyA1LTEyIDktMTggMTAtNyAyLTY1IDM1LTEyOCA3NGwtMTE1IDcxLTEgNTFjLTEgMjktNCA5OS04IDE1N2wtNiAxMDUtMzcgMy0zOCAzdjE5OWgtMjUweiIvPjxwYXRoIGQ9Im0yMjMyIDE1NzMgMy00OCA1MC0zIDUwLTMtMyA1MS00IDUwaC05OXoiLz48L2c+PHBhdGggZD0ibTIxOTAgMjUwMXYtMTAwbDM4LTMgMzctMyA2LTEwNWM0LTU4IDctMTI4IDgtMTU3bDEtNTEgMTIyLTc2YzY4LTQxIDEyNi03MiAxMzAtNjggMyA0IDkgMzkgMTMgNzcgNCAzOSA4IDg2IDEwIDEwNSA3IDY4IDE0IDE0NiAxOSAyMDMgMyAzMiA4IDYzIDExIDY4IDQgNSAzMyA5IDY2IDloNTl2MjAwaC01MjB6bS0xMC03NjZ2LTExNWgxNDlsMy00NyAzLTQ4aDkwbDMgNDggMyA0N2gxMDl2LTEwMWw1OCAzIDU3IDMgMyAxNjMgMiAxNjJoLTQ4MHoiIGZpbGw9IiNmOGY4ZjgiLz48cGF0aCBkPSJtMjcxMCAyNTAwdi05OWwtNjItMy02My0zLTIyLTIxMGMtMzAtMjg3LTMzLTI1NiAzNy0yOTlsNjAtMzgtMi0xNjEtMy0xNjItNTctMy01OC0zdjEwMWgtMTA5bC0zLTQ3LTMtNDhoLTE5MGwtMyA0OC0zIDQ3aC0xMDl2LTEwMWwtNTcgMy01OCAzLTMgMTYzLTIgMTYyIDQ2IDI4YzI1IDE1IDUyIDMyIDYwIDM3IDEyIDkgMTEgMzktNiAyMTUtMTEgMTEzLTIzIDIyMC0yNiAyMzhsLTUgMzJoLTEyOXYyMDBoNzcweiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjI0Ii8+PC9zdmc+'); } -body.base .is2d piece.queen.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iNTAxMCAxMzUwIDEzMzMgMTMzMyIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNjA2MCAyNTAwdi0xMDBoLTE3OGwtMTAtNDdjLTYtMjctMTgtODYtMjctMTMzbC0xNy04NSAxMDctMjMzYzU5LTEyOCAxMDUtMjM1IDEwMy0yMzctMi0zLTI0IDEtNDkgOC00MyAxMi00NCAxNC00NyA1OC0zIDQwLTEwIDU0LTYyIDExMGwtNTkgNjQtMS05NGMwLTg5IDItOTcgMjYtMTIybDI3LTI4LTIzLTYxYy0xMi0zMy0yNS02MC0yOS02MHMtMjYgMjAtNTAgNDRsLTQyIDQzIDE1IDM2YzE0IDM1IDEzIDM5LTIyIDEyMS0yMCA0OC0zOSA4Ni00MyA4Ni0zIDAtMjItMzktNDItODYtMzUtODMtMzYtODctMjItMTIybDE2LTM2LTQzLTQzYy0yMy0yNC00NS00My00OS00My03IDAtNDkgOTctNDkgMTE1IDAgNiAxMSAyMiAyNSAzNSAyMyAyMiAyNSAzMCAyNSAxMjJ2OTlsLTYwLTY4Yy01NC02MC02MC03Mi02MC0xMTAgMC00Ny02LTUyLTc3LTY3bC0zMi03IDExMCAyMzggMTEwIDIzOC0xNiA4NWMtOSA0Ny0yMSAxMDYtMjcgMTMzbC0xMCA0N2gtMTc4djIwMGg3NjB6IiBmaWxsPSIjZjhmOGY4Ii8+PGcgZmlsbD0iI2QzZDNkMyI+PHBhdGggZD0ibTUzMDAgMjUwMHYtMTAwaDE3OGwxMC00N2M2LTI3IDE4LTg2IDI3LTEzM2wxNi04NS0xMTAtMjM4LTExMC0yMzggMzIgN2M3MSAxNSA3NyAyMCA3NyA2NyAwIDM4IDYgNTAgNjAgMTEwbDYwIDY4di05OWMwLTkyLTItMTAwLTI1LTEyMi0xNC0xMy0yNS0yOS0yNS0zNSAwLTIyIDQyLTExNSA1Mi0xMTUgNSAwIDcgNCA0IDgtMyA1IDIyIDEzNCA1NCAyODggMzMgMTUzIDYwIDI4MiA2MCAyODYgMCA1IDM4IDggODUgOCA2NyAwIDg1IDMgODUgMTQgMCA4IDMgMjMgNiAzMyA0IDEyIDMgMTQtMyA1LTctOS0zMCAxLTk0IDQwbC04NCA1My0zIDYzLTMgNjJoLTEwOXYyMDBoLTI0MHoiLz48cGF0aCBkPSJtNTcyMCAxOTkyYzAtNy0xMS0zNS0yNS02NC0xNC0yOC0yMS01NC0xNi01NyA0LTMgMjQtNDMgNDQtODkgMzUtODAgMzUtODQgMjEtMTE5bC0xNS0zNiA0Mi00M2MyNC0yNCA0Ni00NCA0OS00NCA4IDAtODMgNDQ3LTkzIDQ1Ni00IDQtNyAyLTctNHoiLz48L2c+PHBhdGggZD0ibTU1NDAgMjUwMHYtMTAwaDEwOWwzLTYyIDMtNjMgODQtNTNjNjEtMzggODctNDkgOTItNDAgMyA3IDEyIDQyIDE4IDc4IDcgMzYgMTcgODIgMjMgMTAzbDExIDM3aDE3N3YyMDBoLTUyMHptMTIwLTM3OGMwLTQtMjctMTMzLTYwLTI4Ny0zMy0xNTMtNTctMjgxLTU0LTI4NCAyLTMgMjMgMTMgNDUgMzVsNDAgNDAtMTYgMzljLTE0IDMxLTE0IDQzLTQgNjQgMTIgMjYgMjkgNjUgNDcgMTExIDUgMTQgMjIgNTEgMzYgODNzMjYgNjMgMjYgNzBjMSA0MCAyMy00NCA2MC0yMzAgMjQtMTE3IDQ3LTIxMCA1MS0yMDcgNSAzIDkgMTMgOSAyMyAwIDkgNCAyMSA5IDI3IDIyIDI0IDIxIDYxLTQgODQtMjMgMjItMjUgMzAtMjUgMTE3IDAgNTEgNCA5MyA4IDkzIDUgMCAyNC0xOSA0Mi00MiAxOS0yNCA0Mi00OSA1Mi01NiAxMy05IDE4LTI2IDE4LTU3IDAtMjQgNi00NyAxMy01MiAxOS0xMiA4MS0zMyA4NS0yOCAzIDItOCAzMC0yMyA2Mi04MyAxNzctMTI2IDI3Mi0xNTkgMzQ2bC0yNSA1N2gtODVjLTQ4IDAtODYtMy04Ni04eiIgZmlsbD0iI2Y4ZjhmOCIvPjxwYXRoIGQ9Im02MDYwIDI1MDB2LTEwMGgtMTc4bC0xMC00N2MtNi0yNy0xOC04Ni0yNy0xMzNsLTE3LTg1IDEwNy0yMzNjNTktMTI4IDEwNS0yMzUgMTAzLTIzNy0yLTMtMjQgMS00OSA4LTQzIDEyLTQ0IDE0LTQ3IDU4LTMgNDAtMTAgNTQtNjIgMTEwbC01OSA2NC0xLTk0YzAtODkgMi05NyAyNi0xMjJsMjctMjgtMjMtNjFjLTEyLTMzLTI1LTYwLTI5LTYwcy0yNiAyMC01MCA0NGwtNDIgNDMgMTUgMzZjMTQgMzUgMTMgMzktMjIgMTIxLTIwIDQ4LTM5IDg2LTQzIDg2LTMgMC0yMi0zOS00Mi04Ni0zNS04My0zNi04Ny0yMi0xMjJsMTYtMzYtNDMtNDNjLTIzLTI0LTQ1LTQzLTQ5LTQzLTcgMC00OSA5Ny00OSAxMTUgMCA2IDExIDIyIDI1IDM1IDIzIDIyIDI1IDMwIDI1IDEyMnY5OWwtNjAtNjhjLTU0LTYwLTYwLTcyLTYwLTExMCAwLTQ3LTYtNTItNzctNjdsLTMyLTcgMTEwIDIzOCAxMTAgMjM4LTE2IDg1Yy05IDQ3LTIxIDEwNi0yNyAxMzNsLTEwIDQ3aC0xNzh2MjAwaDc2MHoiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIyNCIvPjwvc3ZnPg=='); } -body.base .is2d piece.king.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iNjE1MCAxMzUwIDEzMzMgMTMzMyIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNzIwMCAyNTAwdi0xMDBoLTIzN2wtMTctNTctMTYtNTggNzItMTUzIDcyLTE1NC0yNC0xOWMtNTgtNDQtMTMwLTYzLTI0MC02NC05OCAwLTEwOSAyLTE3MCAzMi0zNiAxNy03MSAzNi03OCA0MS0xMSA3IDEgNDEgNTkgMTYxbDczIDE1Mi0xNSA1Ny0xNSA1Ny0xMTcgMy0xMTcgM3YxOTloNzcwem0tMzMzLTcwNWMtNC0yNS05LTU2LTEzLTcwLTYtMjQtNS0yNSA0MC0xOWw0NiA3di0xMDVsLTQ2IDdjLTQxIDYtNDUgNS00MC0xMiAzLTEwIDgtMzAgMTItNDVsNi0yOGgtMTE1bDYgNDUgNyA0NS00MC02LTQwLTd2MTA2bDQxLTcgNDItNy02IDM4Yy00IDIxLTkgNTMtMTMgNzFsLTYgMzJoMTI1eiIgZmlsbD0iI2Y4ZjhmOCIvPjxwYXRoIGQ9Im02NDMwIDI1MDB2LTk5bDExNy0zIDExNy0zIDE1LTU3IDE1LTU3LTcyLTE1MGMtNDAtODMtNzItMTUxLTcyLTE1M3M0NS0yIDk5IDBjNjUgMiAxMDEgNyAxMDQgMTUgMiA3IDE3IDc0IDMyIDE1MGwyOCAxMzdoNThjNDMgMCA1OCA0IDYzIDE2IDggMjEgOCAyNC00IDI0LTUgMC0zOSAxOC03NSA0MC01NSAzNC03NCA0MC0xMjAgNDBoLTU1djIwMGgtMjUwem0zMjQtNjkyYzQtMTggOS01MCAxMy03MWw2LTM4LTQyIDctNDEgN3YtMTA2bDQwIDcgNDAgNi03LTQ1Yy02LTQ0LTUtNDUgMjMtNDVoMjl2MzEwaC0zNGMtMzIgMC0zMy0xLTI3LTMyem0xNzktMTQ4YzAtMzAgMi00MyA0LTI3IDIgMTUgMiAzOSAwIDU1LTIgMTUtNCAyLTQtMjh6IiBmaWxsPSIjZDNkM2QzIi8+PHBhdGggZD0ibTY2ODAgMjUwMHYtMTAwaDU1YzQ2IDAgNjUtNiAxMjAtNDAgMzYtMjIgNjktNDAgNzQtNDAgNCAwIDE0IDE4IDIxIDQwbDEzIDQwaDIzN3YyMDBoLTUyMHptMTA1LTM1N2MtMTUtNzYtMzAtMTQ0LTMzLTE1MC0zLTktMzMtMTMtMTAxLTEzLTg5LTEtOTQtMi03Ni0xNiAyMi0xNyA4MS00NCAxMzEtNjEgNDYtMTUgMTkxLTkgMjQ5IDExIDQ3IDE2IDExNSA1NSAxMTUgNjYgMCAzLTMxIDcwLTY4IDE1MGwtNjcgMTQ1LTYxIDMtNjEgM3ptMjktMzE2Yy0yLTctMy03Ni0yLTE1MmwzLTE0MCAyOS0zYzI2LTMgMjgtMSAyMiAyMi0zIDE0LTkgMzctMTIgNTEtNSAxOS0zIDI0IDcgMjEgOC0yIDI2LTcgNDItMTAgMjctNiAyNy02IDI3IDQ0djUwbC00Mi02LTQxLTcgNiAzOWM0IDIxIDkgNTQgMTMgNzIgNiAzMCA1IDMyLTIwIDMyLTE1IDAtMjktNi0zMi0xM3oiIGZpbGw9IiNmOGY4ZjgiLz48cGF0aCBkPSJtNzIwMCAyNTAwdi0xMDBoLTIzN2wtMTctNTctMTYtNTggNzItMTUzIDcyLTE1NC0yNC0xOWMtNTgtNDQtMTMwLTYzLTI0MC02NC05OCAwLTEwOSAyLTE3MCAzMi0zNiAxNy03MSAzNi03OCA0MS0xMSA3IDEgNDEgNTkgMTYxbDczIDE1Mi0xNSA1Ny0xNSA1Ny0xMTcgMy0xMTcgM3YxOTloNzcwem0tMzMzLTcwNWMtNC0yNS05LTU2LTEzLTcwLTYtMjQtNS0yNSA0MC0xOWw0NiA3di0xMDVsLTQ2IDdjLTQxIDYtNDUgNS00MC0xMiAzLTEwIDgtMzAgMTItNDVsNi0yOGgtMTE1bDYgNDUgNyA0NS00MC02LTQwLTd2MTA2bDQxLTcgNDItNy02IDM4Yy00IDIxLTkgNTMtMTMgNzFsLTYgMzJoMTI1eiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjI0Ii8+PC9zdmc+'); } -body.base .is2d piece.pawn.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iNTM1IDEzNTAgMTMzMyAxMzMzIiB3aWR0aD0iMTMzIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Im0xNTkwIDI1MDB2LTk5bC04Ny0zLTg3LTMtNTYtMTgyLTU3LTE4MiAzMC0yOGM2Mi01OCA4Mi0xNDcgNTEtMjIxLTUyLTEyNi0yMTEtMTY2LTMxMS03OS05MSA4MC05NiAyMDctMTIgMjkwbDM5IDM5LTU4IDE4Mi01OCAxODEtODIgMy04MiAzdjE5OWg3NzB6IiBmaWxsPSIjNTY1MjUyIi8+PHBhdGggZD0ibTgyMCAyNTAwdi05OWw4Mi0zIDgyLTMgNTgtMTgxIDU4LTE4Mi0zOS0zOWMtMzgtMzgtNjEtOTEtNjEtMTQ0IDAtMzAgMTktODkgMjktODkgMyAwIDY1IDU5IDEzNiAxMzAgODQgODQgMTM1IDEyOCAxNDUgMTI1IDE3LTYgMjItMTAtNzcgNjhsLTYwIDQ4LTEyIDExN2MtMTYgMTU0LTE1IDE1Mi01NyAxNTJoLTM0djIwMGgtMjUweiIgZmlsbD0iIzQ0NDI0MiIvPjxwYXRoIGQ9Im0xMDcwIDI1MDB2LTEwMGgzNGM0MiAwIDQxIDIgNTctMTUybDEyLTExNyA2NC01MSA2My01MSAxMCAyNmM2IDE1IDEwIDMxIDEwIDM4IDAgMTEgMjQgODcgNzUgMjM3bDIzIDY1IDg2IDMgODYgM3YxOTloLTUyMHptOTEtNjE0LTEzMy0xMzQgNDEtNDBjNTUtNTMgMTE3LTY4IDE5MC00NyAxMTMgMzQgMTcwIDE3NiAxMTUgMjg3LTEzIDI1LTU5IDY4LTczIDY4LTMgMC02Ni02MC0xNDAtMTM0eiIgZmlsbD0iIzU2NTI1MiIvPjxwYXRoIGQ9Im0xNTkwIDI1MDB2LTk5bC04Ny0zLTg3LTMtNTYtMTgyLTU3LTE4MiAzMC0yOGM2Mi01OCA4Mi0xNDcgNTEtMjIxLTUyLTEyNi0yMTEtMTY2LTMxMS03OS05MSA4MC05NiAyMDctMTIgMjkwbDM5IDM5LTU4IDE4Mi01OCAxODEtODIgMy04MiAzdjE5OWg3NzB6IiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iMjQiLz48L3N2Zz4='); } -body.base .is2d piece.knight.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iMjc4MCAxMzUwIDEzMzMgMTMzMyIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtMzgzMCAyNTAwdi05OWwtMTA2LTMtMTA2LTMgODItNjkgODItNjktMTY4LTE2OC0xNjctMTY3IDI2LTE2YzQzLTI5IDkxLTMxIDE0MS02IDI1IDEyIDQ2IDI2IDQ2IDMxIDAgMjIgMjIgNSA2Ny01MyAyOC0zNSA1My02OCA1Ny03NSA0LTgtNjYtNjEtMjEyLTE1OWwtMjIwLTE0Ni00MiAyMmMtMTkwIDk3LTI3MyAzNDAtMTgzIDUzMSAxNiAzNSAzOSA3NSA1MSA4OWwyMSAyNS00NSA0Ni00NSA0NiA4MiA2OSA4MSA2OS0xMDYgMy0xMDYgM3YxOTloNzcweiIgZmlsbD0iIzU2NTI1MiIvPjxnIGZpbGw9IiM0NDQyNDIiPjxwYXRoIGQ9Im0zMDYwIDI1MDB2LTk5bDEwNi0zIDEwNi0zLTgxLTY5LTgyLTY5IDQ1LTQ2IDQ1LTQ2LTIxLTI1Yy0xMi0xNC0zNS01NC01MS04OS01NS0xMTYtNDctMjY0IDE5LTM3NyAzMS01MiAxMDgtMTI2IDE2Mi0xNTMgNTMtMjcgNjItMjcgMjYgMi00NiAzNS03MyA2OC0xMDMgMTI3LTEyNCAyMzkgNiA1MjUgMjY3IDU5MSAzNSA4IDYzIDE3IDY0IDIwIDEgMi05IDM0LTIxIDcybC0yMyA2N2gtMTU4djIwMGgtMzAweiIvPjxwYXRoIGQ9Im0zMzUwIDE5MjN2LTk3bDQ4IDQ3YzQwIDM5IDUwIDQ1IDYyIDM1IDEzLTExIDEzLTExIDIgMi0xMCAxMi00IDIyIDM1IDYybDQ3IDQ4aC0xOTR6Ii8+PC9nPjxwYXRoIGQ9Im0zMzYwIDI1MDB2LTEwMGgxNThsMjEtNjJjMTItMzUgMjEtNjcgMjEtNzIgMS01LTI3LTE3LTYyLTI1LTI2MS02Ni0zOTAtMzUwLTI2OC01OTEgMjctNTIgMTAzLTE0MCAxMjItMTQwIDEyIDAgNDI4IDI3OSA0MjggMjg3IDAgNi03NCAxMDYtMTAxIDEzNy01IDUtMTYgMC0yNi0xMS0zNy00My0xMjYtNTUtMTc4LTIzbC0zMCAxOC00Ny00Ni00OC00NnYxOTRoMTk1bDExNSAxMTUgMTE0IDExNC0yMCAyM2MtMTAgMTMtMjUgMjctMzMgMzItNyA0LTMwIDI0LTQ5IDQyLTIwIDE5LTQwIDM0LTQ0IDM0cy04IDUtOCAxMGMwIDYgNDIgMTAgMTA1IDEwaDEwNXYyMDBoLTQ3MHoiIGZpbGw9IiM1NjUyNTIiLz48cGF0aCBkPSJtMzgzMCAyNTAwdi05OWwtMTA2LTMtMTA2LTMgODItNjkgODItNjktMTY4LTE2OC0xNjctMTY3IDI2LTE2YzQzLTI5IDkxLTMxIDE0MS02IDI1IDEyIDQ2IDI2IDQ2IDMxIDAgMjIgMjIgNSA2Ny01MyAyOC0zNSA1My02OCA1Ny03NSA0LTgtNjYtNjEtMjEyLTE1OWwtMjIwLTE0Ni00MiAyMmMtMTkwIDk3LTI3MyAzNDAtMTgzIDUzMSAxNiAzNSAzOSA3NSA1MSA4OWwyMSAyNS00NSA0Ni00NSA0NiA4MiA2OSA4MSA2OS0xMDYgMy0xMDYgM3YxOTloNzcweiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjI0Ii8+PC9zdmc+'); } -body.base .is2d piece.bishop.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iMzg5MCAxMzUwIDEzMzAgMTMzMCIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNDk1MCAyNTAwdi0xMDBoLTE4NmwtMzgtMTYyYy0yMS05MC00MC0xNjgtNDMtMTc0LTItNiAzMC01NCA3Mi0xMDcgNDEtNTQgNzUtMTAyIDc1LTEwOHMtMjEtMzgtNDctNzFsLTQ3LTYxLTI2IDMxLTI3IDMyLTMyLTQ1LTMyLTQ1IDIwLTI5YzEyLTE2IDIxLTMyIDIxLTM2IDAtMTAtOTItMTI1LTk5LTEyNS0zIDEtMzcgNDItNzYgOTMtMzggNTAtOTkgMTI4LTEzMyAxNzRsLTY0IDgyIDc4IDEwMSA3OCAxMDEtMzIgMTM3Yy0xOCA3NS0zNyAxNTQtNDMgMTc1bC0xMCAzN2gtMTc5djIwMGg3NzB6IiBmaWxsPSIjNTY1MjUyIi8+PHBhdGggZD0ibTQxODAgMjUwMHYtMTAwaDE3OWwxMC0zN2M2LTIxIDI1LTEwMCA0My0xNzVsMzItMTM3LTc3LTEwMGMtNDItNTUtNzctMTAxLTc3LTEwM3M1NC0xIDExOSAybDExOSA1IDcyIDkzYzM5IDUwIDc0IDkyIDc4IDkyczggMTEgOCAyNWMxIDE0LTIgMjUtNiAyNS01IDAtMzggMTgtNzQgNDFsLTY0IDQwLTcgOTdjLTkgMTM0LTggMTMyLTYxIDEzMmgtNDR2MjAwaC0yNTB6bTQyMi02OTljLTE4LTIyLTMyLTQzLTMyLTQ4IDAtNCAxMC0yMSAyMy0zN2wyMy0yOSAzNiA0OSAzNiA0OC0yMSAyOGMtMTEgMTUtMjQgMjgtMjcgMjgtNCAwLTIxLTE4LTM4LTM5eiIgZmlsbD0iIzQ0NDI0MiIvPjxwYXRoIGQ9Im00NDMwIDI1MDB2LTEwMGg0NGM1MyAwIDUyIDIgNjEtMTMybDctOTcgNjQtNDBjMzYtMjMgNjktNDEgNzMtNDEgNyAwIDIwIDQ2IDYzIDIyM2wyMSA4N2gxODd2MjAwaC01MjB6bTE2OC01NTUtNzMtOTVoLTExMmMtNjIgMC0xMTMtMy0xMTItNyAwLTkgMzEtNTAgMTU3LTIwOCA1MC02NCA5Mi0xMjEgOTItMTI2IDAtMjAgMTgtNSA2MyA1Nmw0OCA2NC00NSA1OGMtMjUgMzItNDYgNjItNDYgNjYgMCAxMSA2MSA4NyA3MCA4NyA0IDAgMjYtMjcgNTAtNjAgMjQtMzIgNDYtNTcgNTEtNTUgNCAzIDI2IDMzIDQ5IDY2bDQxIDYxLTQ3IDYxYy0yNyAzNC02MCA3Ny03NCA5NC0xNCAxOC0yOCAzMy0zMiAzM3MtNDAtNDMtODAtOTV6IiBmaWxsPSIjNTY1MjUyIi8+PHBhdGggZD0ibTQ5NTAgMjUwMHYtMTAwaC0xODZsLTM4LTE2MmMtMjEtOTAtNDAtMTY4LTQzLTE3NC0yLTYgMzAtNTQgNzItMTA3IDQxLTU0IDc1LTEwMiA3NS0xMDhzLTIxLTM4LTQ3LTcxbC00Ny02MS0yNiAzMS0yNyAzMi0zMi00NS0zMi00NSAyMC0yOWMxMi0xNiAyMS0zMiAyMS0zNiAwLTEwLTkyLTEyNS05OS0xMjUtMyAxLTM3IDQyLTc2IDkzLTM4IDUwLTk5IDEyOC0xMzMgMTc0bC02NCA4MiA3OCAxMDEgNzggMTAxLTMyIDEzN2MtMTggNzUtMzcgMTU0LTQzIDE3NWwtMTAgMzdoLTE3OXYyMDBoNzcweiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjI0Ii8+PC9zdmc+'); } -body.base .is2d piece.rook.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iMTY3MCAxMzUwIDEzMzMgMTMzMyIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtMjcxMCAyNTAwdi05OWwtNjItMy02My0zLTIyLTIxMGMtMzAtMjg3LTMzLTI1NiAzNy0yOTlsNjAtMzgtMi0xNjEtMy0xNjItNTctMy01OC0zdjEwMWgtMTA5bC0zLTQ3LTMtNDhoLTE5MGwtMyA0OC0zIDQ3aC0xMDl2LTEwMWwtNTcgMy01OCAzLTMgMTYzLTIgMTYyIDQ2IDI4YzI1IDE1IDUyIDMyIDYwIDM3IDEyIDkgMTEgMzktNiAyMTUtMTEgMTEzLTIzIDIyMC0yNiAyMzhsLTUgMzJoLTEyOXYyMDBoNzcweiIgZmlsbD0iIzU2NTI1MiIvPjxnIGZpbGw9IiM0NDQyNDIiPjxwYXRoIGQ9Im0xOTQwIDI1MDB2LTEwMGgxMjlsNS0zMmMzLTE4IDE1LTEyNSAyNi0yMzggMTctMTc2IDE4LTIwNiA2LTIxNS04LTUtMzUtMjItNjAtMzdsLTQ2LTI4IDItMTYyIDMtMTYzIDU4LTMgNTctM3Y1MWMwIDQ5IDEgNTAgMzAgNTBoMzB2MjMwaDIzOGwyMzcgMS01NCAzNGMtMzAgMTktNTcgMzgtNjAgNDItMyA1LTEyIDktMTggMTAtNyAyLTY1IDM1LTEyOCA3NGwtMTE1IDcxLTEgNTFjLTEgMjktNCA5OS04IDE1N2wtNiAxMDUtMzcgMy0zOCAzdjE5OWgtMjUweiIvPjxwYXRoIGQ9Im0yMjMyIDE1NzMgMy00OCA1MC0zIDUwLTMtMyA1MS00IDUwaC05OXoiLz48L2c+PHBhdGggZD0ibTIxOTAgMjUwMXYtMTAwbDM4LTMgMzctMyA2LTEwNWM0LTU4IDctMTI4IDgtMTU3bDEtNTEgMTIyLTc2YzY4LTQxIDEyNi03MiAxMzAtNjggMyA0IDkgMzkgMTMgNzcgNCAzOSA4IDg2IDEwIDEwNSA3IDY4IDE0IDE0NiAxOSAyMDMgMyAzMiA4IDYzIDExIDY4IDQgNSAzMyA5IDY2IDloNTl2MjAwaC01MjB6bS0xMC03NjZ2LTExNWgxNDlsMy00NyAzLTQ4aDkwbDMgNDggMyA0N2gxMDl2LTEwMWw1OCAzIDU3IDMgMyAxNjMgMiAxNjJoLTQ4MHoiIGZpbGw9IiM1NjUyNTIiLz48cGF0aCBkPSJtMjcxMCAyNTAwdi05OWwtNjItMy02My0zLTIyLTIxMGMtMzAtMjg3LTMzLTI1NiAzNy0yOTlsNjAtMzgtMi0xNjEtMy0xNjItNTctMy01OC0zdjEwMWgtMTA5bC0zLTQ3LTMtNDhoLTE5MGwtMyA0OC0zIDQ3aC0xMDl2LTEwMWwtNTcgMy01OCAzLTMgMTYzLTIgMTYyIDQ2IDI4YzI1IDE1IDUyIDMyIDYwIDM3IDEyIDkgMTEgMzktNiAyMTUtMTEgMTEzLTIzIDIyMC0yNiAyMzhsLTUgMzJoLTEyOXYyMDBoNzcweiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjI0Ii8+PC9zdmc+'); } -body.base .is2d piece.queen.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iNTAxMCAxMzUwIDEzMzMgMTMzMyIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNjA2MCAyNTAwdi0xMDBoLTE3OGwtMTAtNDdjLTYtMjctMTgtODYtMjctMTMzbC0xNy04NSAxMDctMjMzYzU5LTEyOCAxMDUtMjM1IDEwMy0yMzctMi0zLTI0IDEtNDkgOC00MyAxMi00NCAxNC00NyA1OC0zIDQwLTEwIDU0LTYyIDExMGwtNTkgNjQtMS05NGMwLTg5IDItOTcgMjYtMTIybDI3LTI4LTIzLTYxYy0xMi0zMy0yNS02MC0yOS02MHMtMjYgMjAtNTAgNDRsLTQyIDQzIDE1IDM2YzE0IDM1IDEzIDM5LTIyIDEyMS0yMCA0OC0zOSA4Ni00MyA4Ni0zIDAtMjItMzktNDItODYtMzUtODMtMzYtODctMjItMTIybDE2LTM2LTQzLTQzYy0yMy0yNC00NS00My00OS00My03IDAtNDkgOTctNDkgMTE1IDAgNiAxMSAyMiAyNSAzNSAyMyAyMiAyNSAzMCAyNSAxMjJ2OTlsLTYwLTY4Yy01NC02MC02MC03Mi02MC0xMTAgMC00Ny02LTUyLTc3LTY3bC0zMi03IDExMCAyMzggMTEwIDIzOC0xNiA4NWMtOSA0Ny0yMSAxMDYtMjcgMTMzbC0xMCA0N2gtMTc4djIwMGg3NjB6IiBmaWxsPSIjNTY1MjUyIi8+PGcgZmlsbD0iIzQ0NDI0MiI+PHBhdGggZD0ibTUzMDAgMjUwMHYtMTAwaDE3OGwxMC00N2M2LTI3IDE4LTg2IDI3LTEzM2wxNi04NS0xMTAtMjM4LTExMC0yMzggMzIgN2M3MSAxNSA3NyAyMCA3NyA2NyAwIDM4IDYgNTAgNjAgMTEwbDYwIDY4di05OWMwLTkyLTItMTAwLTI1LTEyMi0xNC0xMy0yNS0yOS0yNS0zNSAwLTIyIDQyLTExNSA1Mi0xMTUgNSAwIDcgNCA0IDgtMyA1IDIyIDEzNCA1NCAyODggMzMgMTUzIDYwIDI4MiA2MCAyODYgMCA1IDM4IDggODUgOCA2NyAwIDg1IDMgODUgMTQgMCA4IDMgMjMgNiAzMyA0IDEyIDMgMTQtMyA1LTctOS0zMCAxLTk0IDQwbC04NCA1My0zIDYzLTMgNjJoLTEwOXYyMDBoLTI0MHoiLz48cGF0aCBkPSJtNTcyMCAxOTkyYzAtNy0xMS0zNS0yNS02NC0xNC0yOC0yMS01NC0xNi01NyA0LTMgMjQtNDMgNDQtODkgMzUtODAgMzUtODQgMjEtMTE5bC0xNS0zNiA0Mi00M2MyNC0yNCA0Ni00NCA0OS00NCA4IDAtODMgNDQ3LTkzIDQ1Ni00IDQtNyAyLTctNHoiLz48L2c+PHBhdGggZD0ibTU1NDAgMjUwMHYtMTAwaDEwOWwzLTYyIDMtNjMgODQtNTNjNjEtMzggODctNDkgOTItNDAgMyA3IDEyIDQyIDE4IDc4IDcgMzYgMTcgODIgMjMgMTAzbDExIDM3aDE3N3YyMDBoLTUyMHptMTIwLTM3OGMwLTQtMjctMTMzLTYwLTI4Ny0zMy0xNTMtNTctMjgxLTU0LTI4NCAyLTMgMjMgMTMgNDUgMzVsNDAgNDAtMTYgMzljLTE0IDMxLTE0IDQzLTQgNjQgMTIgMjYgMjkgNjUgNDcgMTExIDUgMTQgMjIgNTEgMzYgODNzMjYgNjMgMjYgNzBjMSA0MCAyMy00NCA2MC0yMzAgMjQtMTE3IDQ3LTIxMCA1MS0yMDcgNSAzIDkgMTMgOSAyMyAwIDkgNCAyMSA5IDI3IDIyIDI0IDIxIDYxLTQgODQtMjMgMjItMjUgMzAtMjUgMTE3IDAgNTEgNCA5MyA4IDkzIDUgMCAyNC0xOSA0Mi00MiAxOS0yNCA0Mi00OSA1Mi01NiAxMy05IDE4LTI2IDE4LTU3IDAtMjQgNi00NyAxMy01MiAxOS0xMiA4MS0zMyA4NS0yOCAzIDItOCAzMC0yMyA2Mi04MyAxNzctMTI2IDI3Mi0xNTkgMzQ2bC0yNSA1N2gtODVjLTQ4IDAtODYtMy04Ni04eiIgZmlsbD0iIzU2NTI1MiIvPjxwYXRoIGQ9Im02MDYwIDI1MDB2LTEwMGgtMTc4bC0xMC00N2MtNi0yNy0xOC04Ni0yNy0xMzNsLTE3LTg1IDEwNy0yMzNjNTktMTI4IDEwNS0yMzUgMTAzLTIzNy0yLTMtMjQgMS00OSA4LTQzIDEyLTQ0IDE0LTQ3IDU4LTMgNDAtMTAgNTQtNjIgMTEwbC01OSA2NC0xLTk0YzAtODkgMi05NyAyNi0xMjJsMjctMjgtMjMtNjFjLTEyLTMzLTI1LTYwLTI5LTYwcy0yNiAyMC01MCA0NGwtNDIgNDMgMTUgMzZjMTQgMzUgMTMgMzktMjIgMTIxLTIwIDQ4LTM5IDg2LTQzIDg2LTMgMC0yMi0zOS00Mi04Ni0zNS04My0zNi04Ny0yMi0xMjJsMTYtMzYtNDMtNDNjLTIzLTI0LTQ1LTQzLTQ5LTQzLTcgMC00OSA5Ny00OSAxMTUgMCA2IDExIDIyIDI1IDM1IDIzIDIyIDI1IDMwIDI1IDEyMnY5OWwtNjAtNjhjLTU0LTYwLTYwLTcyLTYwLTExMCAwLTQ3LTYtNTItNzctNjdsLTMyLTcgMTEwIDIzOCAxMTAgMjM4LTE2IDg1Yy05IDQ3LTIxIDEwNi0yNyAxMzNsLTEwIDQ3aC0xNzh2MjAwaDc2MHoiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIyNCIvPjwvc3ZnPg=='); } -body.base .is2d piece.king.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjEzMyIgdmlld0JveD0iNjE1MCAxMzUwIDEzMzMgMTMzMyIgd2lkdGg9IjEzMyIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNzIwMCAyNTAwdi0xMDBoLTIzN2wtMTctNTctMTYtNTggNzItMTUzIDcyLTE1NC0yNC0xOWMtNTgtNDQtMTMwLTYzLTI0MC02NC05OCAwLTEwOSAyLTE3MCAzMi0zNiAxNy03MSAzNi03OCA0MS0xMSA3IDEgNDEgNTkgMTYxbDczIDE1Mi0xNSA1Ny0xNSA1Ny0xMTcgMy0xMTcgM3YxOTloNzcwem0tMzMzLTcwNWMtNC0yNS05LTU2LTEzLTcwLTYtMjQtNS0yNSA0MC0xOWw0NiA3di0xMDVsLTQ2IDdjLTQxIDYtNDUgNS00MC0xMiAzLTEwIDgtMzAgMTItNDVsNi0yOGgtMTE1bDYgNDUgNyA0NS00MC02LTQwLTd2MTA2bDQxLTcgNDItNy02IDM4Yy00IDIxLTkgNTMtMTMgNzFsLTYgMzJoMTI1eiIgZmlsbD0iIzU2NTI1MiIvPjxwYXRoIGQ9Im02NDMwIDI1MDB2LTk5bDExNy0zIDExNy0zIDE1LTU3IDE1LTU3LTcyLTE1MGMtNDAtODMtNzItMTUxLTcyLTE1M3M0NS0yIDk5IDBjNjUgMiAxMDEgNyAxMDQgMTUgMiA3IDE3IDc0IDMyIDE1MGwyOCAxMzdoNThjNDMgMCA1OCA0IDYzIDE2IDggMjEgOCAyNC00IDI0LTUgMC0zOSAxOC03NSA0MC01NSAzNC03NCA0MC0xMjAgNDBoLTU1djIwMGgtMjUwem0zMjQtNjkyYzQtMTggOS01MCAxMy03MWw2LTM4LTQyIDctNDEgN3YtMTA2bDQwIDcgNDAgNi03LTQ1Yy02LTQ0LTUtNDUgMjMtNDVoMjl2MzEwaC0zNGMtMzIgMC0zMy0xLTI3LTMyem0xNzktMTQ4YzAtMzAgMi00MyA0LTI3IDIgMTUgMiAzOSAwIDU1LTIgMTUtNCAyLTQtMjh6IiBmaWxsPSIjNDQ0MjQyIi8+PHBhdGggZD0ibTY2ODAgMjUwMHYtMTAwaDU1YzQ2IDAgNjUtNiAxMjAtNDAgMzYtMjIgNjktNDAgNzQtNDAgNCAwIDE0IDE4IDIxIDQwbDEzIDQwaDIzN3YyMDBoLTUyMHptMTA1LTM1N2MtMTUtNzYtMzAtMTQ0LTMzLTE1MC0zLTktMzMtMTMtMTAxLTEzLTg5LTEtOTQtMi03Ni0xNiAyMi0xNyA4MS00NCAxMzEtNjEgNDYtMTUgMTkxLTkgMjQ5IDExIDQ3IDE2IDExNSA1NSAxMTUgNjYgMCAzLTMxIDcwLTY4IDE1MGwtNjcgMTQ1LTYxIDMtNjEgM3ptMjktMzE2Yy0yLTctMy03Ni0yLTE1MmwzLTE0MCAyOS0zYzI2LTMgMjgtMSAyMiAyMi0zIDE0LTkgMzctMTIgNTEtNSAxOS0zIDI0IDcgMjEgOC0yIDI2LTcgNDItMTAgMjctNiAyNy02IDI3IDQ0djUwbC00Mi02LTQxLTcgNiAzOWM0IDIxIDkgNTQgMTMgNzIgNiAzMCA1IDMyLTIwIDMyLTE1IDAtMjktNi0zMi0xM3oiIGZpbGw9IiM1NjUyNTIiLz48cGF0aCBkPSJtNzIwMCAyNTAwdi0xMDBoLTIzN2wtMTctNTctMTYtNTggNzItMTUzIDcyLTE1NC0yNC0xOWMtNTgtNDQtMTMwLTYzLTI0MC02NC05OCAwLTEwOSAyLTE3MCAzMi0zNiAxNy03MSAzNi03OCA0MS0xMSA3IDEgNDEgNTkgMTYxbDczIDE1Mi0xNSA1Ny0xNSA1Ny0xMTcgMy0xMTcgM3YxOTloNzcwem0tMzMzLTcwNWMtNC0yNS05LTU2LTEzLTcwLTYtMjQtNS0yNSA0MC0xOWw0NiA3di0xMDVsLTQ2IDdjLTQxIDYtNDUgNS00MC0xMiAzLTEwIDgtMzAgMTItNDVsNi0yOGgtMTE1bDYgNDUgNyA0NS00MC02LTQwLTd2MTA2bDQxLTcgNDItNy02IDM4Yy00IDIxLTkgNTMtMTMgNzFsLTYgMzJoMTI1eiIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjI0Ii8+PC9zdmc+'); } diff --git a/public/stylesheets/piece/shapes.css b/public/stylesheets/piece/shapes.css deleted file mode 100644 index 2c3537a346..0000000000 --- a/public/stylesheets/piece/shapes.css +++ /dev/null @@ -1,12 +0,0 @@ -body.base .is2d piece.pawn.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik00MCA0MHYxMjBoMTIwVjQwem00MCA0MGg0MHY0MEg4MHoiIGZpbGw9IiNmZmYiIGZpbHRlcj0idXJsKCNhKSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49ImJldmVsIiBzdHJva2Utd2lkdGg9IjYiIHRyYW5zZm9ybT0ibWF0cml4KC45IDAgMCAuOSAxMS44IDExLjgpIi8+PC9zdmc+'); } -body.base .is2d piece.knight.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik0zNS41IDEyMi44MzlWNzkuNTY1bDExMi42Ny00Ni41MDggMTUuMjYyIDM2Ljk3My03NS41MTUgMzEuMTcyIDc1LjUxNSAzMS4xNzEtMTUuMjYyIDM2Ljk3NHoiIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjYiIHN0cm9rZS1saW5lam9pbj0iYmV2ZWwiIGZpbHRlcj0idXJsKCNhKSIvPjwvc3ZnPg=='); } -body.base .is2d piece.bishop.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik02OC43ODcgNDAuNTAzTDEwMCA3MS43MTZsMzEuMjEzLTMxLjIxMyAzNS4zNTYtNy4wNzItNy4wNzIgMzUuMzU2TDEyOC4yODQgMTAwbDMxLjIxMyAzMS4yMTMgNy4wNzIgMzUuMzU2LTM1LjM1Ni03LjA3MkwxMDAgMTI4LjI4NGwtMzEuMjEzIDMxLjIxMy0zNS4zNTYgNy4wNzIgNy4wNzItMzUuMzU2TDcxLjcxNiAxMDAgNDAuNTAzIDY4Ljc4NyAzMy40MyAzMy40M3oiIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjYiIHN0cm9rZS1saW5lam9pbj0iYmV2ZWwiIGZpbHRlcj0idXJsKCNhKSIvPjwvc3ZnPg=='); } -body.base .is2d piece.rook.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik03NSAxNWg1MHY2MGg2MHY1MGgtNjB2NjBINzV2LTYwSDE1Vjc1aDYweiIgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iNiIgc3Ryb2tlLWxpbmVqb2luPSJiZXZlbCIgZmlsdGVyPSJ1cmwoI2EpIi8+PC9zdmc+'); } -body.base .is2d piece.queen.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik04MCAyMHYzMS43MTVMNTcuNTc0IDI5LjI4OSAyOS4yOSA1Ny41NzQgNTEuNzE1IDgwSDIwdjQwaDMxLjcxNWwtMjIuNDI2IDIyLjQyNiAyOC4yODUgMjguMjg1TDgwIDE0OC4yODVWMTgwaDQwdi0zMS43MTVsMjIuNDI2IDIyLjQyNiAyOC4yODUtMjguMjg1TDE0OC4yODUgMTIwSDE4MFY4MGgtMzEuNzE1bDIyLjQyNi0yMi40MjYtMjguMjg1LTI4LjI4NUwxMjAgNTEuNzE1VjIwem0yMCA1OC4wMzNBMjEuOTY2IDIxLjk2NiAwIDAgMSAxMjEuOTY3IDEwMCAyMS45NjYgMjEuOTY2IDAgMCAxIDEwMCAxMjEuOTY3IDIxLjk2NiAyMS45NjYgMCAwIDEgNzguMDMzIDEwMCAyMS45NjYgMjEuOTY2IDAgMCAxIDEwMCA3OC4wMzN6IiBmaWxsPSIjZmZmIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSI2IiBzdHJva2UtbGluZWpvaW49ImJldmVsIiBmaWx0ZXI9InVybCgjYSkiLz48L3N2Zz4='); } -body.base .is2d piece.king.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik02OC43ODcgMjQuNjQ1TDI0LjY0NSA2OC43ODd2NjIuNDI2bDQ0LjE0MiA0NC4xNDJoNjIuNDI2bDQ0LjE0Mi00NC4xNDJWNjguNzg3bC00NC4xNDItNDQuMTQyek04OCA2Ny44NTdoMjRWODhoMjAuMTQzdjI0SDExMnYyMC4xNDNIODhWMTEySDY3Ljg1N1Y4OEg4OHoiIGZpbGw9IiNmZmYiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjYiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGZpbHRlcj0idXJsKCNhKSIvPjwvc3ZnPg=='); } -body.base .is2d piece.pawn.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik00MCA0MHYxMjBoMTIwVjQwem00MCA0MGg0MHY0MEg4MHoiIGZpbGw9IiMzMzMiIGZpbHRlcj0idXJsKCNhKSIgc3Ryb2tlPSIjMDAwIiBzdHJva2UtbGluZWpvaW49ImJldmVsIiBzdHJva2Utd2lkdGg9IjYiIHRyYW5zZm9ybT0ibWF0cml4KC45IDAgMCAuOSAxMS44IDExLjgpIi8+PC9zdmc+'); } -body.base .is2d piece.knight.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik0zNS41IDEyMi44MzlWNzkuNTY1bDExMi42Ny00Ni41MDggMTUuMjYyIDM2Ljk3My03NS41MTUgMzEuMTcyIDc1LjUxNSAzMS4xNzEtMTUuMjYyIDM2Ljk3NHoiIGZpbGw9IiMzMzMiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjYiIHN0cm9rZS1saW5lam9pbj0iYmV2ZWwiIGZpbHRlcj0idXJsKCNhKSIvPjwvc3ZnPg=='); } -body.base .is2d piece.bishop.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik02OC43ODcgNDAuNTAzTDEwMCA3MS43MTZsMzEuMjEzLTMxLjIxMyAzNS4zNTYtNy4wNzItNy4wNzIgMzUuMzU2TDEyOC4yODQgMTAwbDMxLjIxMyAzMS4yMTMgNy4wNzIgMzUuMzU2LTM1LjM1Ni03LjA3MkwxMDAgMTI4LjI4NGwtMzEuMjEzIDMxLjIxMy0zNS4zNTYgNy4wNzIgNy4wNzItMzUuMzU2TDcxLjcxNiAxMDAgNDAuNTAzIDY4Ljc4NyAzMy40MyAzMy40M3oiIGZpbGw9IiMzMzMiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjYiIHN0cm9rZS1saW5lam9pbj0iYmV2ZWwiIGZpbHRlcj0idXJsKCNhKSIvPjwvc3ZnPg=='); } -body.base .is2d piece.rook.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik03NSAxNWg1MHY2MGg2MHY1MGgtNjB2NjBINzV2LTYwSDE1Vjc1aDYweiIgZmlsbD0iIzMzMyIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2U9IiMwMDAiIHN0cm9rZS13aWR0aD0iNiIgc3Ryb2tlLWxpbmVqb2luPSJiZXZlbCIgZmlsdGVyPSJ1cmwoI2EpIi8+PC9zdmc+'); } -body.base .is2d piece.queen.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik04MCAyMHYzMS43MTVMNTcuNTc0IDI5LjI4OSAyOS4yOSA1Ny41NzQgNTEuNzE1IDgwSDIwdjQwaDMxLjcxNWwtMjIuNDI2IDIyLjQyNiAyOC4yODUgMjguMjg1TDgwIDE0OC4yODVWMTgwaDQwdi0zMS43MTVsMjIuNDI2IDIyLjQyNiAyOC4yODUtMjguMjg1TDE0OC4yODUgMTIwSDE4MFY4MGgtMzEuNzE1bDIyLjQyNi0yMi40MjYtMjguMjg1LTI4LjI4NUwxMjAgNTEuNzE1VjIwem0yMCA1OC4wMzNBMjEuOTY2IDIxLjk2NiAwIDAgMSAxMjEuOTY3IDEwMCAyMS45NjYgMjEuOTY2IDAgMCAxIDEwMCAxMjEuOTY3IDIxLjk2NiAyMS45NjYgMCAwIDEgNzguMDMzIDEwMCAyMS45NjYgMjEuOTY2IDAgMCAxIDEwMCA3OC4wMzN6IiBmaWxsPSIjMzMzIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSI2IiBzdHJva2UtbGluZWpvaW49ImJldmVsIiBmaWx0ZXI9InVybCgjYSkiLz48L3N2Zz4='); } -body.base .is2d piece.king.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIHdpZHRoPSIyMDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGZpbHRlciBpZD0iYSIgaGVpZ2h0PSIxNTAlIiB3aWR0aD0iMTUwJSI+PGZlR2F1c3NpYW5CbHVyIGluPSJTb3VyY2VBbHBoYSIgcmVzdWx0PSJibHVyIiBzdGREZXZpYXRpb249IjMiLz48ZmVDb2xvck1hdHJpeCBpbj0iYmx1ciIgcmVzdWx0PSJibHVyQWxwaGEiIHZhbHVlcz0iMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMiAwIDAgMCAwIDAgMC41IDAiLz48ZmVPZmZzZXQgZHg9IjQuNSIgZHk9IjQuNSIgaW49ImJsdXJBbHBoYSIgcmVzdWx0PSJvZmZzZXRCbHVyIi8+PGZlQmxlbmQgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0ib2Zmc2V0Qmx1ciIvPjwvZmlsdGVyPjxwYXRoIGQ9Ik02OC43ODcgMjQuNjQ1TDI0LjY0NSA2OC43ODd2NjIuNDI2bDQ0LjE0MiA0NC4xNDJoNjIuNDI2bDQ0LjE0Mi00NC4xNDJWNjguNzg3bC00NC4xNDItNDQuMTQyek04OCA2Ny44NTdoMjRWODhoMjAuMTQzdjI0SDExMnYyMC4xNDNIODhWMTEySDY3Ljg1N1Y4OEg4OHoiIGZpbGw9IiMzMzMiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlPSIjMDAwIiBzdHJva2Utd2lkdGg9IjYiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGZpbHRlcj0idXJsKCNhKSIvPjwvc3ZnPg=='); } diff --git a/public/stylesheets/piece/spatial.css b/public/stylesheets/piece/spatial.css deleted file mode 100644 index 7eb088b7dd..0000000000 --- a/public/stylesheets/piece/spatial.css +++ /dev/null @@ -1,12 +0,0 @@ -body.base .is2d piece.pawn.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48bGluZWFyR3JhZGllbnQgaWQ9ImEiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjUwLjMzMyIgeDI9IjY3MS4zMzMiIHkxPSI1NDEuNjY3IiB5Mj0iNzE4LjMzMyI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZWRlM2RlIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZDBiMDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjY1LjMzMyIgeDI9IjY0NC42NjciIHkxPSI2MDUiIHkyPSI2MDUiPjxzdG9wIG9mZnNldD0iMCIvPjxzdG9wIG9mZnNldD0iMSIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZD0iTTAgMGgyMDB2MjAwSDB6IiBmaWxsPSJub25lIi8+PHBhdGggZD0iTTYzNi42NjcgNjA1YzAgMTAyLjE3My04MS4zMzUgMTg1LTE4MS42NjcgMTg1cy0xODEuNjY3LTgyLjgyNy0xODEuNjY3LTE4NVMzNTQuNjY4IDQyMCA0NTUgNDIwczE4MS42NjcgODIuODI3IDE4MS42NjcgMTg1eiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTMuMDQ4IC4zODEpIHNjYWxlKC4yMjg1NykiIG9wYWNpdHk9Ii45OSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2Utd2lkdGg9IjE2IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGZpbGw9InVybCgjYSkiIHN0cm9rZT0idXJsKCNiKSIvPjwvc3ZnPg=='); } -body.base .is2d piece.knight.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48bGluZWFyR3JhZGllbnQgaWQ9ImEiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iODM3Ljg2OSIgeDI9Ijk2OS44NjYiIHkxPSIyNTguNTUiIHkyPSIzODguODM2Ij48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNlZGUzZGUiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNkMGIwOTAiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iYiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI4MjcuOTI3IiB4Mj0iOTc0LjU2IiB5MT0iMzA0LjQ0MyIgeTI9IjMwNC40NDMiPjxzdG9wIG9mZnNldD0iMCIvPjxzdG9wIG9mZnNldD0iMSIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZD0iTTAgMGgyMDB2MjAwSDB6IiBmaWxsPSJub25lIi8+PHBhdGggZD0iTTg4Ni4wMDMgMjIwLjIzYy0uMzg2IDI2LjU5NS45NzIgMTYuNTUyLTE1LjgxIDQuMjc0IDIuNTkgMTcuMzQ5LjgzMSAxNy45Mi0zLjY1MiAyNS4zNDUtMi40NTQgNC4wNjMtNC42MTcgMTYuODU2LTYuMTUyIDE5LjY3Ni05LjMwNCAxNy4wODctMzAuNjcgMzkuMzk0LTMwLjYzNCA0Ni42NjYuMDQ3IDkuMjA1IDEwLjk5NSAxNy40NDUgMjEuMDEgNy43MS05LjM3IDEzLjcxNyAxOC45MTgtLjA2MSAzMC43NzMtOC41MjEgMTUuNjkxIDkuNjYgMzcuNjE0LS45MSAzOC4wMjEtMTYuNDMyIDcuMTQxIDM1LjEwOC01OS41NCA0MS4yMDUtNjMuMTAyIDg2Ljc0MyA0OS42OTcgMTEuMzQ1IDc3LjM3Ny0yNS42MTcgMTA3LjY2OCAyLjk2NSAxNS40ODUtNDQuODk3IDE2LjkxNC0xMTkuOTQ2LTU1LjA3Mi0xNDguMDg0LTkuNzg0LTMuODI0LTEzLjg5NS0xMy42NjItMjMuMDUtMjAuMzQzem0tLjMgNDkuNTI1Yy0xLjYyOCAyLjMwOC01LjA1IDYuMDc2LTguMDUxIDUuNTI0LTIuNzc2LS41MS0zLjg5Mi0xLjQ1LTQuMDItNC43MzgtLjEwOC0yLjc2NyA5LjY5OC0yLjY3OCAxMi4wNy0uNzg2eiIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2Utd2lkdGg9IjMuNjU3IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGZpbGw9InVybCgjYSkiIHN0cm9rZT0idXJsKCNiKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTgwMCAtMjAwKSIvPjwvc3ZnPg=='); } -body.base .is2d piece.bishop.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjYzMi4yMjUiIHgyPSI3NjYuODYxIiB4bGluazpocmVmPSIjYSIgeTE9IjMwMi41OTEiIHkyPSIzNDMuMzUzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJhIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNlZGUzZGUiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNkMGIwOTAiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iZCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2MzIuMjI1IiB4Mj0iNjk5LjQ4NSIgeGxpbms6aHJlZj0iI2IiIHkxPSIzNzQuNTg2IiB5Mj0iMzc0LjU4NiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYiI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNjI4LjExIiB4Mj0iNzYyLjc0NyIgeGxpbms6aHJlZj0iI2EiIHkxPSIzMDIuNTkxIiB5Mj0iMzQzLjM1MyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2OTkuMjk3IiB4Mj0iNzY2LjU1NiIgeGxpbms6aHJlZj0iI2IiIHkxPSIzNzQuNTg2IiB5Mj0iMzc0LjU4NiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2MjkuOTM5IiB4Mj0iNzY0LjU3NSIgeGxpbms6aHJlZj0iI2EiIHkxPSIzMDIuNTkxIiB5Mj0iMzQzLjM1MyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2NTYuMjMzIiB4Mj0iNzM3LjY3MiIgeGxpbms6aHJlZj0iI2IiIHkxPSIzNTAuODE3IiB5Mj0iMzUwLjgxNyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2NDQuMjI3IiB4Mj0iNzU0LjAxNSIgeGxpbms6aHJlZj0iI2IiIHkxPSIyOTMuMzY0IiB5Mj0iMjkzLjM2NCIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2NzMuNzQ5IiB4Mj0iNzE0LjUzOCIgeGxpbms6aHJlZj0iI2EiIHkxPSIyMzkuMzUzIiB5Mj0iMjUxLjU0MyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iayIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2ODEuNjkxIiB4Mj0iNzE3Ljk2NiIgeGxpbms6aHJlZj0iI2IiIHkxPSIyMzIuMzAxIiB5Mj0iMjMyLjMwMSIvPjxwYXRoIGQ9Ik0wIDBoMjAwdjIwMEgweiIgZmlsbD0ibm9uZSIvPjxnIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjMuNjU3Ij48cGF0aCBkPSJNNjk3LjY1NiAzNTguMDczYy0xLjIyMyAyLjQ0Ny02My42MDMgMzMuMDI1LTYzLjYwMyAzMy4wMjVsNTEuNTQ1LTYuNTI0eiIgZmlsbD0idXJsKCNjKSIgc3Ryb2tlPSJ1cmwoI2QpIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNjAwIC0yMDApIi8+PHBhdGggZD0iTTcwMS4xMjUgMzU4LjA3M2MxLjIyMyAyLjQ0NyA2My42MDMgMzMuMDI1IDYzLjYwMyAzMy4wMjVsLTU0LjU5My02LjUyNHoiIGZpbGw9InVybCgjZSkiIHN0cm9rZT0idXJsKCNmKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTYwMCAtMjAwKSIvPjxwYXRoIGQ9Ik02NzUuMDMzIDM0Mi4yMjNjLTEuMzc1IDIuNzUtMTYuOTcxIDE5LjMxNy0xNi45NzEgMTkuMzE3bDc3Ljc4MiA1LjM1My0xOS44MjUtMzIuMTUzeiIgZmlsbD0idXJsKCNnKSIgc3Ryb2tlPSJ1cmwoI2gpIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNjAwIC0yMDApIi8+PHBhdGggZD0iTTY5OC43MiAyMzUuNjMzYy0xLjM3NiAyLjc1LTUyLjY2NCAxMTUuNDYyLTUyLjY2NCAxMTUuNDYybDEwNi4xMy05LjM0OHptMTAuMzIyIDM1Ljc0NWw4LjEwNSAxNy43Ni00MS44MSA0MS40MXMzMi4zMy01Ni40MTkgMzMuNzA1LTU5LjE3eiIgZmlsbD0idXJsKCNnKSIgc3Ryb2tlPSJ1cmwoI2kpIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNjAwIC0yMDApIi8+PHBhdGggZD0iTTY5OS4xOCAyMTYuNzVjLTEuMzc2IDIuNzUyLTE1LjY2IDI2LjA3MS0xNS42NiAyNi4wNzFsMzIuNjE4IDUuMDN6IiBmaWxsPSJ1cmwoI2opIiBzdHJva2U9InVybCgjaykiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02MDAgLTIwMCkiLz48L2c+PC9zdmc+'); } -body.base .is2d piece.rook.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJiIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjQyMC4yNzgiIHgyPSI1NzYuNDkiIHkxPSIyNjUuNDI4IiB5Mj0iMzcxLjU2MSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZWRlM2RlIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZDBiMDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImMiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNDUyLjI2NyIgeDI9IjU1MC40IiB4bGluazpocmVmPSIjYSIgeTE9IjMyNS40MSIgeTI9IjMyNS40MSIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNDI2Ljc0MyIgeDI9IjQ2Ni4yMSIgeGxpbms6aHJlZj0iI2EiIHkxPSIyNTguNTUyIiB5Mj0iMjU4LjU1MiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0ODEuMjE5IiB4Mj0iNTE4LjAxOSIgeGxpbms6aHJlZj0iI2EiIHkxPSIyNTUuODg2IiB5Mj0iMjU1Ljg4NiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI1NDAuNjQ4IiB4Mj0iNTczLjI1NyIgeGxpbms6aHJlZj0iI2EiIHkxPSIyNTkuMTI0IiB5Mj0iMjU5LjEyNCIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0MzUuNTA1IiB4Mj0iNTMwLjk3MSIgeGxpbms6aHJlZj0iI2EiIHkxPSIzNzguODE5IiB5Mj0iMzc4LjgxOSIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI1MzkuMTI0IiB4Mj0iNTY0Ljg3NiIgeGxpbms6aHJlZj0iI2EiIHkxPSIzNzEuOTYyIiB5Mj0iMzcxLjk2MiIvPjxwYXRoIGQ9Ik0wIDBoMjAwdjIwMEgweiIgZmlsbD0ibm9uZSIvPjxnIGZpbGw9InVybCgjYikiIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjMuNjU3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNDAwIC0yMDApIj48cGF0aCBkPSJNNDU0LjA5NSAyNzAuNTUyaDk0LjQ3NnYxMDkuNzE1aC05NC40NzZ6IiBzdHJva2U9InVybCgjYykiLz48cGF0aCBkPSJNNDI4LjU3MSAyNDAuMDc2aDM1LjgxdjM2Ljk1M2gtMzUuODF6IiBzdHJva2U9InVybCgjZCkiLz48cGF0aCBkPSJNNDgzLjA0OCAyNDguMDc2aDMzLjE0MnYxNS42MmgtMzMuMTQyeiIgc3Ryb2tlPSJ1cmwoI2UpIi8+PHBhdGggZD0iTTU0Mi40NzYgMjMxLjMxNGgyOC45NTN2NTUuNjJoLTI4Ljk1M3oiIHN0cm9rZT0idXJsKCNmKSIvPjxwYXRoIGQ9Ik00MzcuMzMzIDM3MS4yaDkxLjgxdjE1LjIzOGgtOTEuODF6IiBzdHJva2U9InVybCgjZykiLz48cGF0aCBkPSJNNTQwLjk1MiAzNTcuMTA1aDIyLjA5NnYyOS43MTRoLTIyLjA5NnoiIHN0cm9rZT0idXJsKCNoKSIvPjwvZz48L3N2Zz4='); } -body.base .is2d piece.queen.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjI2NS4yODkiIHgyPSIzMDYuNjY3IiB4bGluazpocmVmPSIjYSIgeTE9IjI2NS42MjciIHkyPSIzMzQuMTk5Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJhIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9IiNlZGUzZGUiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiNkMGIwOTAiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iZCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIyNTIuMzM3IiB4Mj0iMzUzLjE0MyIgeGxpbms6aHJlZj0iI2IiIHkxPSIyOTYuMTA0IiB5Mj0iMjk2LjEwNCIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYiI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjM4LjEyMSIgeDI9IjM2NC4zMTciIHhsaW5rOmhyZWY9IiNhIiB5MT0iMjU0LjgzMiIgeTI9IjM3MC42NDIiLz48bGluZWFyR3JhZGllbnQgaWQ9ImYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjE4LjMxMiIgeDI9IjM4Mi45ODMiIHhsaW5rOmhyZWY9IiNiIiB5MT0iMjk1LjIxMyIgeTI9IjI5NS4yMTMiLz48bGluZWFyR3JhZGllbnQgaWQ9ImciIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjQ1LjQ4NiIgeDI9IjM1MS4yMzgiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMzgwLjUzMyIgeTI9IjM4MC41MzMiLz48bGluZWFyR3JhZGllbnQgaWQ9ImgiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjQ1LjQ4NiIgeDI9IjM1MS4yMzgiIHhsaW5rOmhyZWY9IiNiIiB5MT0iMzgwLjUzMyIgeTI9IjM4MC41MzMiLz48cGF0aCBkPSJNMCAwaDIwMHYyMDBIMHoiIGZpbGw9Im5vbmUiLz48ZyBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIzLjY1NyI+PHBhdGggZD0iTTM1MS4zMTQgMjM0LjI2NGMtNDcuODU4IDE0My40LTU1LjI1MyAxNDMuNjY2LTk3LjE0My42NzktLjI1NyA1OC4yNzEgNy40OTIgOTkuMjYgMTguNzIyIDEyM2g1NC40MTRjMTIuMzA3LTIzLjg1MSAyMS44NC02NS4wOTMgMjQuMDA3LTEyMy42Nzl6IiBmaWxsPSJ1cmwoI2MpIiBzdHJva2U9InVybCgjZCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMDAgLTIwMCkiLz48cGF0aCBkPSJNMzAyLjU0OCAyMjQuNDgxYy0xNy4zNjggOTQuMTExLTguODQ3IDE5NC45ODItODIuNDA4IDQyLjU4NiAyLjUxOCA0Ni41OTMgMTMuNDQ1IDc5LjYwNiAzMi44MjIgOTguODc4aDkxLjljMTkuNzQ0LTE5LjAzMiAzMS43MS01MS41MzMgMzYuMjkzLTk3LjY1LTcwLjI0OSAxNTIuNDI5LTY0LjE1IDUwLjM4NC03OC42MDctNDMuODE0eiIgZmlsbD0idXJsKCNlKSIgc3Ryb2tlPSJ1cmwoI2YpIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMjAwIC0yMDApIi8+PHBhdGggZD0iTTI0Ny4zMTQgMzczLjEwNUgzNDkuNDF2MTQuODU3SDI0Ny4zMTR6IiBmaWxsPSJ1cmwoI2cpIiBzdHJva2U9InVybCgjaCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMDAgLTIwMCkiLz48L2c+PC9zdmc+'); } -body.base .is2d piece.king.white { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ijg1LjczIiB4Mj0iMTIyLjQxNyIgeGxpbms6aHJlZj0iI2EiIHkxPSIyNDAuMzI0IiB5Mj0iMjcwLjYxNCIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYSI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZWRlM2RlIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjZDBiMDkwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNzIuMzIzIiB4Mj0iMTI5Ljg2NiIgeGxpbms6aHJlZj0iI2IiIHkxPSIyNTMuNzMxIiB5Mj0iMjUzLjczMSIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYiI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMzQuMzA0IiB4Mj0iMTU4LjYzIiB4bGluazpocmVmPSIjYSIgeTE9IjI1OC4zNDQiIHkyPSIzNjkuMTU3Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJmIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjE5LjQwNyIgeDI9IjE4Mi40NjUiIHhsaW5rOmhyZWY9IiNiIiB5MT0iMzE5LjcyMyIgeTI9IjMxOS43MjMiLz48bGluZWFyR3JhZGllbnQgaWQ9ImciIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMzcuMjgzIiB4Mj0iMTYwLjYxNiIgeGxpbms6aHJlZj0iI2EiIHkxPSIzNzcuNTE3IiB5Mj0iMzc4LjAxNCIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0My41MDUiIHgyPSIxNTYuODc2IiB4bGluazpocmVmPSIjYiIgeTE9IjM4MC45NTIiIHkyPSIzODAuOTUyIi8+PHBhdGggZD0iTTAgMGgyMDB2MjAwSDB6IiBmaWxsPSJub25lIi8+PGcgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMy42NTciPjxwYXRoIGQ9Ik05Mi4xMTYgMjI1LjE0NXYxMy42MjhINzQuMTV2MTUuNTVoMTcuOTY1djI3Ljk5M2gxNC4zNDJ2LTI3Ljk5M2gyMS41Nzl2LTE1LjU1aC0yMS41Nzl2LTEzLjYyOHoiIGZpbGw9InVybCgjYykiIHN0cm9rZT0idXJsKCNkKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAtMjAwKSIvPjxwYXRoIGQ9Ik0xMTYuNzY5IDMwNS40MWM0NS42NTQtMjQuNDE4IDMxLjAyNCAyMi4xMDIgOC4zNjcgMzYuNDgzLTE0LjU5OCA5LjI2NS0yMi4yMy0yNS42OTUtMTQuNDg2LTUxLjk1bC0xOS41NjQuMjM2YzcuMjE0IDIzLjIzNCAyLjgxNCA1OC45MzgtMTMuMDU3IDUxLjcxNC0yOC4yNzItMTIuODY3LTM4Ljc4Mi02MC4yMSA2LjM1Ni0zNi40Ni0yNi4wODQtNTMuMzIxLTY2LjcxMS0zMi45MzItNjIuOS01LjgzMyA0LjE0MiAyOS40MzggMzcuNzQgNTUuOTI3IDM3LjA1OCA2Ny43MjloODQuMzA3Yy0xLjM1LTEzLjY3NCAzNi41NTEtNDEuNzkzIDM3Ljc2NC02OC41MjkgMS4xNjUtMjYuMTU5LTQzLjk4Mi00Ni40MTktNjMuODQ1IDYuNjF6IiBmaWxsPSJ1cmwoI2UpIiBzdHJva2U9InVybCgjZikiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDAgLTIwMCkiLz48cGF0aCBkPSJNNDUuMzMzIDM3My4zMzNoMTA5LjcxNXYxNS4yMzhINDUuMzMzeiIgZmlsbD0idXJsKCNnKSIgc3Ryb2tlPSJ1cmwoI2gpIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwIC0yMDApIi8+PC9nPjwvc3ZnPg=='); } -body.base .is2d piece.pawn.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48bGluZWFyR3JhZGllbnQgaWQ9ImEiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjUwLjMzMyIgeDI9IjY3MS4zMzMiIHkxPSI1NDEuNjY3IiB5Mj0iNzE4LjMzMyI+PHN0b3Agb2Zmc2V0PSIwIi8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjNTA1MDcwIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjY1LjMzMyIgeDI9IjY0NC42NjciIHkxPSI2MDUiIHkyPSI2MDUiPjxzdG9wIG9mZnNldD0iMCIgc3RvcC1jb2xvcj0iZ3JheSIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iZ3JheSIvPjwvbGluZWFyR3JhZGllbnQ+PHBhdGggZD0iTTAgMGgyMDB2MjAwSDB6IiBmaWxsPSJub25lIi8+PHBhdGggZD0iTTYzNi42NjcgNjA1YzAgMTAyLjE3My04MS4zMzUgMTg1LTE4MS42NjcgMTg1cy0xODEuNjY3LTgyLjgyNy0xODEuNjY3LTE4NVMzNTQuNjY4IDQyMCA0NTUgNDIwczE4MS42NjcgODIuODI3IDE4MS42NjcgMTg1eiIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTMuMDQ4IC4zODEpIHNjYWxlKC4yMjg1NykiIG9wYWNpdHk9Ii45OSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2Utd2lkdGg9IjE2IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGZpbGw9InVybCgjYSkiIHN0cm9rZT0idXJsKCNiKSIvPjwvc3ZnPg=='); } -body.base .is2d piece.knight.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48bGluZWFyR3JhZGllbnQgaWQ9ImEiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iODM3Ljg2OSIgeDI9Ijk2OS44NjYiIHkxPSI1OC41NSIgeTI9IjE4OC44MzYiPjxzdG9wIG9mZnNldD0iMCIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzUwNTA3MCIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJiIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjgyNy45MjciIHgyPSI5NzQuNTYiIHkxPSIxMDQuNDQzIiB5Mj0iMTA0LjQ0MyI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSJncmF5Ii8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSJncmF5Ii8+PC9saW5lYXJHcmFkaWVudD48cGF0aCBkPSJNMCAwaDIwMHYyMDBIMHoiIGZpbGw9Im5vbmUiLz48cGF0aCBkPSJNODg2LjAwMyAyMC4yM2MtLjM4NiAyNi41OTUuOTcyIDE2LjU1Mi0xNS44MSA0LjI3NCAyLjU5IDE3LjM0OS44MzEgMTcuOTItMy42NTIgMjUuMzQ1LTIuNDU0IDQuMDYzLTQuNjE3IDE2Ljg1Ni02LjE1MiAxOS42NzYtOS4zMDQgMTcuMDg3LTMwLjY3IDM5LjM5NC0zMC42MzQgNDYuNjY2LjA0NyA5LjIwNSAxMC45OTUgMTcuNDQ1IDIxLjAxIDcuNzEtOS4zNyAxMy43MTcgMTguOTE4LS4wNjEgMzAuNzczLTguNTIxIDE1LjY5MSA5LjY2IDM3LjYxNC0uOTEgMzguMDIxLTE2LjQzMiA3LjE0MSAzNS4xMDgtNTkuNTQgNDEuMjA1LTYzLjEwMiA4Ni43NDMgNDkuNjk3IDExLjM0NSA3Ny4zNzctMjUuNjE3IDEwNy42NjggMi45NjVDOTc5LjYxIDE0My43NiA5ODEuMDQgNjguNzEgOTA5LjA1MyA0MC41NzJjLTkuNzg0LTMuODI0LTEzLjg5NS0xMy42NjItMjMuMDUtMjAuMzQzem0tLjMgNDkuNTI1Yy0xLjYyOCAyLjMwOC01LjA1IDYuMDc2LTguMDUxIDUuNTI0LTIuNzc2LS41MS0zLjg5Mi0xLjQ1LTQuMDItNC43MzgtLjEwOC0yLjc2NyA5LjY5OC0yLjY3OCAxMi4wNy0uNzg2eiIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2Utd2lkdGg9IjMuNjU3IiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGZpbGw9InVybCgjYSkiIHN0cm9rZT0idXJsKCNiKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTgwMCkiLz48L3N2Zz4='); } -body.base .is2d piece.bishop.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjYzMi4yMjUiIHgyPSI3NjYuODYxIiB4bGluazpocmVmPSIjYSIgeTE9IjEwMi41OTEiIHkyPSIxNDMuMzUzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJhIj48c3RvcCBvZmZzZXQ9IjAiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM1MDUwNzAiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iZCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2MzIuMjI1IiB4Mj0iNjk5LjQ4NSIgeGxpbms6aHJlZj0iI2IiIHkxPSIxNzQuNTg2IiB5Mj0iMTc0LjU4NiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYiI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSJncmF5Ii8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSJncmF5Ii8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNjI4LjExIiB4Mj0iNzYyLjc0NyIgeGxpbms6aHJlZj0iI2EiIHkxPSIxMDIuNTkxIiB5Mj0iMTQzLjM1MyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2OTkuMjk3IiB4Mj0iNzY2LjU1NiIgeGxpbms6aHJlZj0iI2IiIHkxPSIxNzQuNTg2IiB5Mj0iMTc0LjU4NiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2MjkuOTM5IiB4Mj0iNzY0LjU3NSIgeGxpbms6aHJlZj0iI2EiIHkxPSIxMDIuNTkxIiB5Mj0iMTQzLjM1MyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2NTYuMjMzIiB4Mj0iNzM3LjY3MiIgeGxpbms6aHJlZj0iI2IiIHkxPSIxNTAuODE3IiB5Mj0iMTUwLjgxNyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iaSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI2NDQuMjI3IiB4Mj0iNzU0LjAxNSIgeGxpbms6aHJlZj0iI2IiIHkxPSI5My4zNjQiIHkyPSI5My4zNjQiLz48bGluZWFyR3JhZGllbnQgaWQ9ImoiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNjczLjc0OSIgeDI9IjcxNC41MzgiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMzkuMzUzIiB5Mj0iNTEuNTQzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJrIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjY4MS42OTEiIHgyPSI3MTcuOTY2IiB4bGluazpocmVmPSIjYiIgeTE9IjMyLjMwMSIgeTI9IjMyLjMwMSIvPjxwYXRoIGQ9Ik0wIDBoMjAwdjIwMEgweiIgZmlsbD0ibm9uZSIvPjxnIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjMuNjU3Ij48cGF0aCBkPSJNNjk3LjY1NiAxNTguMDczYy0xLjIyMyAyLjQ0Ny02My42MDMgMzMuMDI1LTYzLjYwMyAzMy4wMjVsNTEuNTQ1LTYuNTI0eiIgZmlsbD0idXJsKCNjKSIgc3Ryb2tlPSJ1cmwoI2QpIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNjAwKSIvPjxwYXRoIGQ9Ik03MDEuMTI1IDE1OC4wNzNjMS4yMjMgMi40NDcgNjMuNjAzIDMzLjAyNSA2My42MDMgMzMuMDI1bC01NC41OTMtNi41MjR6IiBmaWxsPSJ1cmwoI2UpIiBzdHJva2U9InVybCgjZikiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02MDApIi8+PHBhdGggZD0iTTY3NS4wMzMgMTQyLjIyM2MtMS4zNzUgMi43NS0xNi45NzEgMTkuMzE3LTE2Ljk3MSAxOS4zMTdsNzcuNzgyIDUuMzUzLTE5LjgyNS0zMi4xNTN6IiBmaWxsPSJ1cmwoI2cpIiBzdHJva2U9InVybCgjaCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02MDApIi8+PHBhdGggZD0iTTY5OC43MiAzNS42MzNjLTEuMzc2IDIuNzUtNTIuNjY0IDExNS40NjItNTIuNjY0IDExNS40NjJsMTA2LjEzLTkuMzQ4em0xMC4zMjIgMzUuNzQ1bDguMTA1IDE3Ljc2LTQxLjgxIDQxLjQxczMyLjMzLTU2LjQxOSAzMy43MDUtNTkuMTd6IiBmaWxsPSJ1cmwoI2cpIiBzdHJva2U9InVybCgjaSkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC02MDApIi8+PHBhdGggZD0iTTY5OS4xOCAxNi43NWMtMS4zNzYgMi43NTItMTUuNjYgMjYuMDcxLTE1LjY2IDI2LjA3MWwzMi42MTggNS4wM3oiIGZpbGw9InVybCgjaikiIHN0cm9rZT0idXJsKCNrKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTYwMCkiLz48L2c+PC9zdmc+'); } -body.base .is2d piece.rook.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJiIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjQyMC4yNzgiIHgyPSI1NzYuNDkiIHkxPSI2NS40MjgiIHkyPSIxNzEuNTYxIj48c3RvcCBvZmZzZXQ9IjAiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiM1MDUwNzAiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iYyIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0NTIuMjY3IiB4Mj0iNTUwLjQiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTI1LjQxIiB5Mj0iMTI1LjQxIi8+PGxpbmVhckdyYWRpZW50IGlkPSJhIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9ImdyYXkiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9ImdyYXkiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iZCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0MjYuNzQzIiB4Mj0iNDY2LjIxIiB4bGluazpocmVmPSIjYSIgeTE9IjU4LjU1MiIgeTI9IjU4LjU1MiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSI0ODEuMjE5IiB4Mj0iNTE4LjAxOSIgeGxpbms6aHJlZj0iI2EiIHkxPSI1NS44ODYiIHkyPSI1NS44ODYiLz48bGluZWFyR3JhZGllbnQgaWQ9ImYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNTQwLjY0OCIgeDI9IjU3My4yNTciIHhsaW5rOmhyZWY9IiNhIiB5MT0iNTkuMTI0IiB5Mj0iNTkuMTI0Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJnIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjQzNS41MDUiIHgyPSI1MzAuOTcxIiB4bGluazpocmVmPSIjYSIgeTE9IjE3OC44MTkiIHkyPSIxNzguODE5Ii8+PGxpbmVhckdyYWRpZW50IGlkPSJoIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjUzOS4xMjQiIHgyPSI1NjQuODc2IiB4bGluazpocmVmPSIjYSIgeTE9IjE3MS45NjIiIHkyPSIxNzEuOTYyIi8+PHBhdGggZD0iTTAgMGgyMDB2MjAwSDB6IiBmaWxsPSJub25lIi8+PGcgZmlsbD0idXJsKCNiKSIgZmlsbC1ydWxlPSJldmVub2RkIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS13aWR0aD0iMy42NTciIHRyYW5zZm9ybT0idHJhbnNsYXRlKC00MDApIj48cGF0aCBkPSJNNDU0LjA5NSA3MC41NTJoOTQuNDc2djEwOS43MTVoLTk0LjQ3NnoiIHN0cm9rZT0idXJsKCNjKSIvPjxwYXRoIGQ9Ik00MjguNTcxIDQwLjA3NmgzNS44MVY3Ny4wM2gtMzUuODF6IiBzdHJva2U9InVybCgjZCkiLz48cGF0aCBkPSJNNDgzLjA0OCA0OC4wNzZoMzMuMTQydjE1LjYyaC0zMy4xNDJ6IiBzdHJva2U9InVybCgjZSkiLz48cGF0aCBkPSJNNTQyLjQ3NiAzMS4zMTRoMjguOTUzdjU1LjYyaC0yOC45NTN6IiBzdHJva2U9InVybCgjZikiLz48cGF0aCBkPSJNNDM3LjMzMyAxNzEuMmg5MS44MXYxNS4yMzhoLTkxLjgxeiIgc3Ryb2tlPSJ1cmwoI2cpIi8+PHBhdGggZD0iTTU0MC45NTIgMTU3LjEwNWgyMi4wOTZ2MjkuNzE0aC0yMi4wOTZ6IiBzdHJva2U9InVybCgjaCkiLz48L2c+PC9zdmc+'); } -body.base .is2d piece.queen.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjI2NS4yODkiIHgyPSIzMDYuNjY3IiB4bGluazpocmVmPSIjYSIgeTE9IjY1LjYyNyIgeTI9IjEzNC4xOTkiLz48bGluZWFyR3JhZGllbnQgaWQ9ImEiPjxzdG9wIG9mZnNldD0iMCIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzUwNTA3MCIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjI1Mi4zMzciIHgyPSIzNTMuMTQzIiB4bGluazpocmVmPSIjYiIgeTE9Ijk2LjEwNCIgeTI9Ijk2LjEwNCIvPjxsaW5lYXJHcmFkaWVudCBpZD0iYiI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSJncmF5Ii8+PHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSJncmF5Ii8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImUiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjM4LjEyMSIgeDI9IjM2NC4zMTciIHhsaW5rOmhyZWY9IiNhIiB5MT0iNTQuODMyIiB5Mj0iMTcwLjY0MiIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIyMTguMzEyIiB4Mj0iMzgyLjk4MyIgeGxpbms6aHJlZj0iI2IiIHkxPSI5NS4yMTMiIHkyPSI5NS4yMTMiLz48bGluZWFyR3JhZGllbnQgaWQ9ImciIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjQ1LjQ4NiIgeDI9IjM1MS4yMzgiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTgwLjUzMyIgeTI9IjE4MC41MzMiLz48bGluZWFyR3JhZGllbnQgaWQ9ImgiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMjQ1LjQ4NiIgeDI9IjM1MS4yMzgiIHhsaW5rOmhyZWY9IiNiIiB5MT0iMTgwLjUzMyIgeTI9IjE4MC41MzMiLz48cGF0aCBkPSJNMCAwaDIwMHYyMDBIMHoiIGZpbGw9Im5vbmUiLz48ZyBmaWxsLXJ1bGU9ImV2ZW5vZGQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIzLjY1NyI+PHBhdGggZD0iTTM1MS4zMTQgMzQuMjY0Yy00Ny44NTggMTQzLjQtNTUuMjUzIDE0My42NjYtOTcuMTQzLjY3OS0uMjU3IDU4LjI3MSA3LjQ5MiA5OS4yNiAxOC43MjIgMTIzaDU0LjQxNGMxMi4zMDctMjMuODUxIDIxLjg0LTY1LjA5MyAyNC4wMDctMTIzLjY3OXoiIGZpbGw9InVybCgjYykiIHN0cm9rZT0idXJsKCNkKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTIwMCkiLz48cGF0aCBkPSJNMzAyLjU0OCAyNC40OGMtMTcuMzY4IDk0LjExMi04Ljg0NyAxOTQuOTgzLTgyLjQwOCA0Mi41ODcgMi41MTggNDYuNTkzIDEzLjQ0NSA3OS42MDYgMzIuODIyIDk4Ljg3OGg5MS45YzE5Ljc0NC0xOS4wMzIgMzEuNzEtNTEuNTMzIDM2LjI5My05Ny42NS03MC4yNDkgMTUyLjQyOS02NC4xNSA1MC4zODQtNzguNjA3LTQzLjgxNHoiIGZpbGw9InVybCgjZSkiIHN0cm9rZT0idXJsKCNmKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTIwMCkiLz48cGF0aCBkPSJNMjQ3LjMxNCAxNzMuMTA1SDM0OS40MXYxNC44NTdIMjQ3LjMxNHoiIGZpbGw9InVybCgjZykiIHN0cm9rZT0idXJsKCNoKSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTIwMCkiLz48L2c+PC9zdmc+'); } -body.base .is2d piece.king.black { background-image: url('data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjIwMCIgd2lkdGg9IjIwMCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayI+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ijg1LjczIiB4Mj0iMTIyLjQxNyIgeGxpbms6aHJlZj0iI2EiIHkxPSI0MC4zMjQiIHkyPSI3MC42MTQiLz48bGluZWFyR3JhZGllbnQgaWQ9ImEiPjxzdG9wIG9mZnNldD0iMCIvPjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzUwNTA3MCIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjcyLjMyMyIgeDI9IjEyOS44NjYiIHhsaW5rOmhyZWY9IiNiIiB5MT0iNTMuNzMxIiB5Mj0iNTMuNzMxIi8+PGxpbmVhckdyYWRpZW50IGlkPSJiIj48c3RvcCBvZmZzZXQ9IjAiIHN0b3AtY29sb3I9ImdyYXkiLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9ImdyYXkiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iZSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzNC4zMDQiIHgyPSIxNTguNjMiIHhsaW5rOmhyZWY9IiNhIiB5MT0iNTguMzQ0IiB5Mj0iMTY5LjE1NyIvPjxsaW5lYXJHcmFkaWVudCBpZD0iZiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIxOS40MDciIHgyPSIxODIuNDY1IiB4bGluazpocmVmPSIjYiIgeTE9IjExOS43MjMiIHkyPSIxMTkuNzIzIi8+PGxpbmVhckdyYWRpZW50IGlkPSJnIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjM3LjI4MyIgeDI9IjE2MC42MTYiIHhsaW5rOmhyZWY9IiNhIiB5MT0iMTc3LjUxNyIgeTI9IjE3OC4wMTQiLz48bGluZWFyR3JhZGllbnQgaWQ9ImgiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iNDMuNTA1IiB4Mj0iMTU2Ljg3NiIgeGxpbms6aHJlZj0iI2IiIHkxPSIxODAuOTUyIiB5Mj0iMTgwLjk1MiIvPjxwYXRoIGQ9Ik0wIDBoMjAwdjIwMEgweiIgZmlsbD0ibm9uZSIvPjxnIGZpbGwtcnVsZT0iZXZlbm9kZCIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjMuNjU3Ij48cGF0aCBkPSJNOTIuMTE2IDI1LjE0NXYxMy42MjhINzQuMTV2MTUuNTVoMTcuOTY1djI3Ljk5M2gxNC4zNDJWNTQuMzIzaDIxLjU3OXYtMTUuNTVoLTIxLjU3OVYyNS4xNDV6IiBmaWxsPSJ1cmwoI2MpIiBzdHJva2U9InVybCgjZCkiLz48cGF0aCBkPSJNMTE2Ljc2OSAxMDUuNDFjNDUuNjU0LTI0LjQxOCAzMS4wMjQgMjIuMTAyIDguMzY3IDM2LjQ4My0xNC41OTggOS4yNjUtMjIuMjMtMjUuNjk1LTE0LjQ4Ni01MS45NWwtMTkuNTY0LjIzNmM3LjIxNCAyMy4yMzQgMi44MTQgNTguOTM4LTEzLjA1NyA1MS43MTQtMjguMjcyLTEyLjg2Ny0zOC43ODItNjAuMjExIDYuMzU2LTM2LjQ2QzU4LjMgNTIuMTExIDE3LjY3NCA3Mi41IDIxLjQ4NSA5OS42YzQuMTQyIDI5LjQzOCAzNy43NCA1NS45MjcgMzcuMDU4IDY3LjcyOWg4NC4zMDdjLTEuMzUtMTMuNjc0IDM2LjU1MS00MS43OTMgMzcuNzY0LTY4LjUyOSAxLjE2NS0yNi4xNTktNDMuOTgyLTQ2LjQxOS02My44NDUgNi42MXoiIGZpbGw9InVybCgjZSkiIHN0cm9rZT0idXJsKCNmKSIvPjxwYXRoIGQ9Ik00NS4zMzMgMTczLjMzM2gxMDkuNzE1djE1LjIzOEg0NS4zMzN6IiBmaWxsPSJ1cmwoI2cpIiBzdHJva2U9InVybCgjaCkiLz48L2c+PC9zdmc+'); } diff --git a/public/stylesheets/plan.css b/public/stylesheets/plan.css deleted file mode 100644 index 531485a343..0000000000 --- a/public/stylesheets/plan.css +++ /dev/null @@ -1,249 +0,0 @@ -table.all { - margin-top: 20px; - font-size: 1.2em; - width: 100%; -} -table.all a { - color: #3893E8!important; -} -table.all td, -table.all th { - border-top: 1px solid #ddd; -} -body.dark table.all td, -body.dark table.all th { - border-color: #444; -} -table.all td { - padding: 30px; - line-height: 1.7em; -} -table.all th { - opacity: 0.8; - text-align: right; - white-space: nowrap; -} -table.all .switch.up { - color: #639B24; -} -table.all .switch.down { - color: #ac524f; -} -table.all .id { - font-family: monospace; - font-size: 10px; -} -table.all .change form { - display: none; - margin-top: 1em; - padding: 1em; - background: #f4f4f4; -} -body.dark table.all .change form { - background: #222; -} -table.all .change form input { - width: 5em; - padding: 3px 5px; -} -table.all .change form p { - margin-bottom: 1em; -} -table.all .change form button, -table.all .change form a { - margin-left: 10px; -} -table.all .change form.cancel button { - color: red; -} - -table.payments { - font-size: 0.9em; -} -table.payments th { - text-align: left; - font-weight: bold; -} -table.payments th, -table.payments td { - padding: 10px 5px; -} -table.all .thanks { - color: #639B24; - display: block; -} - -.plan a { - color: #3893E8!important; -} - -.plan { - line-height: 2em; -} - -.plan .banner { - margin-bottom: 60px; - background: #639B24; - color: #fff; - text-align: center; - font-size: 1.3em; - height: 160px; - display: flex; - align-items: center; - justify-content: space-between; -} -.plan .banner > i { - font-size: 80px; - margin: 0 20px; -} -.plan .banner > i:last-child { - transform: scale(-1, 1); -} -.plan .banner h1 { - margin: 0 0 20px 0; - padding: 0!important; -} -.plan .wrapper { - display: flex; - justify-content: space-between; - align-items: center; - font-size: 1.3em; -} -.plan .text, -.plan .content { - flex: 0 0 50%; - display: flex; - align-items: center; -} -.plan .text { - flex: 0 0 46%; - flex-flow: column nowrap; -} -.plan .text p { - margin-bottom: 1em; -} -.plan .plan_checkout { - width: 100%; -} -.plan .plan_checkout h3 { - font-family: Roboto; - display: block; - text-transform: uppercase; - margin: 0; -} -.plan .plan_checkout group { - font-size: 1.1em; - margin-bottom: 20px; - overflow: visible; -} -.plan .plan_checkout group input:checked + label, -.plan .plan_checkout .amount_fixed label, -.plan .plan_checkout .lifetime-check input + label { - background: #639B24!important; - border-color: #ccc!important; - box-shadow: 0 3px 4px rgba(0, 0, 0, 0.15) inset !important; - color: #fff!important; - text-shadow: 0 1px 0 #000 !important; -} -body.dark .plan .plan_checkout group input:checked + label, -body.dark .plan .plan_checkout .amount_fixed label { - border-color: #555!important; -} -.plan .plan_checkout group input:disabled + label { - opacity: 0.5; - cursor: default; -} -.plan .plan_checkout group.freq input:checked + label::before, -.plan .plan_checkout group .lifetime-check input + label::before { - content: "✓"; - padding-right: 5px; -} -.plan .plan_checkout group .lifetime-check input + label { - background: #d59120!important; - opacity: 0.8; - cursor: default; -} -.plan .plan_checkout .service { - display: flex; - justify-content: space-between; - font-size: 1.1em; -} -.plan .plan_checkout .service button { - flex: 1 1 auto; - font-weight: normal; - padding: 20px 0; - border-color: #bbb!important; - box-shadow: 0 0 7px rgba(0,0,0,0.5); -} -.plan .plan_checkout .service button:first-child { - margin-right: 25px; -} -body.dark .plan .plan_checkout .service button { - border-color: #555!important; - box-shadow: 0 0 7px rgba(255,255,255,0.5); -} -.plan .small_team { - text-align: center; - font-style: italic; - font-size: 1.3em; - margin-top: 40px; -} -.faq { - margin: 50px 0 40px 0; - padding: 30px 0; - border-top: 1px solid #ccc; - border-bottom: 1px solid #ccc; - display: flex; - justify-content: space-between; - line-height: 1.8em; -} -body.dark .faq { - border-color: #555; -} -.faq a { - color: #3893E8!important; -} -.faq dl { - flex: 0 0 31%; -} -.faq dt { - font-size: 1.3em; - margin-bottom: 1em; -} -.faq dt:nth-of-type(2) { - margin-top: 1.5em; -} -.faq dd { - margin: 0; -} -.best_patrons h2 { - display: block; - text-align: center; - font-size: 1.5em; - margin-bottom: 30px; -} -.best_patrons .list { - display: flex; - flex-flow: row wrap; - font-size: 1.5em; -} -.best_patrons .list div { - flex: 0 0 33.3%; - overflow: hidden; - text-overflow: ellipsis; - padding: 7px 0; -} -.recent_patrons h2 { - font-size: 1.5em; - margin: 140px 0 5px 0; - border-bottom: 1px solid #ccc; -} -body.dark .recent_patrons h2 { - border-color: #444; -} -.recent_patrons .list div { - font-size: 1.3em; - overflow: hidden; - text-overflow: ellipsis; - padding: 7px 0; -} diff --git a/public/stylesheets/practice.css b/public/stylesheets/practice.css deleted file mode 100644 index fc086914fa..0000000000 --- a/public/stylesheets/practice.css +++ /dev/null @@ -1,448 +0,0 @@ -div.game_control .noop { - width: 30px; -} - -.study_box .title { - display: flex; - padding: 7px; - background: #3893E8; - color: #fff; - white-space: nowrap; -} -.study_box .title .icon { - flex: 0 0 40px; - height: 40px; - margin-right: 10px; - opacity: 0.9; -} -.study_box .title h1 { - font-size: 1.2em; -} -.study_box .title em { - font-size: 0.9em; - opacity: 0.9; -} -.study_box .list { - border-top: 0; - max-height: 800px; -} -.study_box .elem.chapter { - border-top: 0; - border-bottom: 1px solid #ddd; -} -body.dark .study_box .elem.chapter { - border-color: #333; -} -.study_box .chapter h3 { - margin: 12px 0 12px 0px; -} -.study_box .list .status { - width: 28px; - opacity: 1; - font-size: 1.25em; - margin-right: 4px; -} -.study_box .list .status.ongoing { - color: #d0d0d0; -} -body.dark .study_box .list .status.ongoing { - color: #444; -} -.study_box .list .status.done { - color: #3893E8; -} -.study_box .list .active .status.ongoing { - font-size: 1em; -} -.study_box .finally { - padding: 12px 0; - display: flex; - background: #ddd; -} -body.dark .study_box .finally { - background: #404040; -} -.study_box .finally .back { - width: 34px; - text-align: center; - margin-right: 5px; - font-size: 1.2em; -} -div.underboard { - margin-top: 20px; -} -.underboard .spinner { - margin: 15px auto; -} -.underboard .feedback { - width: 100%; - padding: 15px 20px; - box-sizing: border-box; - display: flex; - justify-content: center; - align-items: center; - font-size: 1.4em; - background: #fff; - box-shadow: 0 0 3px rgba(0,0,0,0.3); -} -body.dark .underboard .feedback { - background: #333; -} -.underboard .feedback.win { - background: #759900!important; - color: #fff; - animation: 1.7s soft-bright ease-in-out infinite; - opacity: 0.8; - transition: 0.13s; -} -.underboard .feedback.fail { - background: #dc322f!important; - color: #fff; - animation: 1.7s soft-bright ease-in-out infinite; - opacity: 0.8; - transition: 0.13s; -} -.underboard .feedback:hover { - opacity: 1; -} -.underboard .feedback span { - margin-right: 10px; -} -.underboard .feedback strong { - margin-left: 3px; -} -.underboard .feedback.ongoing { - align-items: flex-start; - flex-flow: column; - text-align: left; -} -.underboard .feedback .goal { - margin-bottom: 10px; - text-align: center; - font-size: 1.2em; - width: 100%; - margin-bottom: 10px; -} -.underboard .feedback .comment { - width: 100%; - display: block; -} -.underboard .feedback .comment iframe { - margin: 10px 0; -} -.underboard .setting { - margin-top: 15px; - text-align: left; - line-height: 22px; - display: flex; -} -.underboard .setting > label { - order: 1; - flex: 1 0; - cursor: pointer; - margin-left: 10px; -} - -#practice_app .section { - width: 742px; - padding-top: 10px; -} -#practice_app .section > h2 { - font-size: 2em; - font-family: 'Roboto'; - font-weight: 300; - letter-spacing: 8px; - text-transform: uppercase; - color: #999; - text-shadow: 0 1px 1px #fff; - text-align: center; -} -body.dark #practice_app .section > h2 { - text-shadow: 0 1px 1px #000; -} -#practice_app .studies { - display: flex; - flex-flow: row wrap; - justify-content: space-between; - margin: 10px 0 36px 0; -} -#practice_app .study { - position: relative; - display: flex; - align-items: center; - flex: 0 0 49%; - width: 49%; - height: 90px; - color: #fff; - box-sizing: border-box; - margin-top: 13px; - transition: 0.13s; - border-radius: 3px; - box-shadow: 0 3px 5px 0 rgba(0, 0, 0, 0.3), 0 1px 1px 0 rgba(0, 0, 0, 0.2); - white-space: nowrap; - font-size: 1.2em; -} -#practice_app .study .icon { - flex: 0 0 70px; - height: 70px; - box-sizing: border-box; - margin: 0 13px; - opacity: 0.9; -} -#practice_app .study h3 { - font-size: 1.4em; - margin: 0 0 5px -1px; -} -@keyframes soft-bright { - 50%{ - filter: brightness(1.2); - } -} -#practice_app .study.ongoing { - background: #3893E8!important; -} -#practice_app .study.ongoing:hover { - animation: 1.7s soft-bright ease-in-out infinite; -} -#practice_app .study.done { - background: #4caf50!important; -} -#practice_app .study.future { - opacity: 0.7; - background: #f57c00; -} -#practice_app .study.future .icon { - opacity: 0.7; -} -#practice_app a.study.active, -#practice_app a.study:hover { - filter: brightness(1.08); - transform: scale(1.02); - opacity: 1; -} -#practice_app .ribbon-wrapper { - display: block; - width: 85px; - height: 88px; - overflow: hidden; - position: absolute; - top: -3px; - right: -3px; -} -#practice_app .ribbon { - display: block; - font-size: 15px; - font-weight: bold; - color: #333; - text-align: center; - text-shadow: rgba(255,255,255,0.5) 0px 1px 0px; - transform: rotate(45deg); - position: relative; - padding: 7px 0; - left: -5px; - top: 15px; - width: 120px; - color: #6a6340; - box-shadow: 0px 0px 3px rgba(0,0,0,0.3); -} - -#practice_app .ribbon:before, -#practice_app .ribbon:after { - content: ""; - border-left: 3px solid transparent; - border-right: 3px solid transparent; - position:absolute; - bottom: -3px; -} -#practice_app .ribbon:before { - left: 0; -} -#practice_app .ribbon:after { - right: 0; -} - -#practice_app .ribbon { - background-color: #B3E5FC; -} -#practice_app .ribbon:before, -#practice_app .ribbon:after { - border-top: 3px solid #536DFE; -} -#practice_app .done .ribbon { - background-color: #BFDC7A; -} -#practice_app .done .ribbon:before, -#practice_app .done .ribbon:after { - border-top: 3px solid #6e8900; -} -#practice_app .what_next > p { - width: 100%; - text-align: center; - margin: 20px 0; - font-size: 1.2em; -} - -#practice_side { - border: none; - background: transparent!important; -} -body.dark #practice_side a { - color: #bbb; -} -#practice_side .home { - width: 220px; - background: #3893E8; - color: #fff; - border-radius: 5px; - text-align: center; - padding-top: 10px; - margin-top: 20px; -} -#practice_side .home h1 { - font-size: 30px; -} -#practice_side .home h2 { - font-size: 14px; - margin-bottom: 15px; -} - -@keyframes fat-glide { - 50%{ - opacity: 1; - } -} -#practice_side .home i.fat { - display: block; - width: 200px; - height: 200px; - background: url(../images/practice/robot-golem.svg); - margin: auto; - opacity: 0.8; -} -#practice_side .home:hover i.fat { - animation: 1.2s fat-glide ease-in-out infinite; -} -#practice_side .home .progress { - position: relative; - width: 100%; - height: 30px; - /* border-top: 3px solid #1566b2; */ - background: #1a7edb; - box-shadow: inset 0 1px 1px rgba(0,0,0,0.1); - overflow: hidden; -} -@keyframes animatedBackground { - from { background-position: 0 0; } - to { background-position: 0 1000%; } -} -@keyframes animatedBar { - from { transform: translateX(-100px); } - to { transform: translateX(0px); } -} -#practice_side .home .progress .bar { - height: 100%; - background: #1566b2; - border-radius: 0 5px 5px 0; - background-image: url(../images/grain.png); - transform: translateX(-100px); - animation: animatedBackground 50s linear infinite, animatedBar 1s forwards; -} -#practice_side .home .progress .text { - position: absolute; - top: 0; - left: 0; - width: 100%; - line-height: 30px; - z-index: 3; -} -#practice_side .home .actions { - padding: 20px 10px; - text-align: left; -} -#practice_side .home a { - opacity: 0.6; - color: #fff!important; -} -#practice_side .home a:hover { - opacity: 1; -} - -i.practice { - background: url('/assets/images/practice/help.svg'); - background-size: cover; -} -i.ptQ1LLvm { - background-image: url('/assets/images/practice/backstab.svg'); -} -i.E1lqtqFt { - background-image: url('/assets/images/practice/arrowed.svg'); -} -i.xebrDvFe { - background-image: url('/assets/images/practice/key.svg'); -} -i.A4ujYOer { - background-image: url('/assets/images/practice/push.svg'); -} -i.\39 ogFv8Ac { - background-image: url('/assets/images/practice/voodoo-doll.svg'); -} -i.Qj281y1p { - background-image: url('/assets/images/practice/trident.svg'); -} -i.tuoBxVE5 { - background-image: url('/assets/images/practice/pierced-body.svg'); -} -i.BJy6fEDf { - background-image: url('/assets/images/practice/stone-pile.svg'); -} -i.Rg2cMBZ6 { - background-image: url('/assets/images/practice/stone-spear.svg'); -} -i.fE4k21MW { - background-image: url('/assets/images/practice/pocket-bow.svg'); -} -i.\38 yadFPpU { - background-image: url('/assets/images/practice/sword-in-stone.svg'); -} -i.PDkQDt6u { - background-image: url('/assets/images/practice/catapult.svg'); -} -i.\39 6Lij7wH { - background-image: url('/assets/images/practice/musket.svg'); -} -i.o734CNqp { - background-image: url('/assets/images/practice/breaking-chain.svg'); -} -i.\39 cKgYrHb { - background-image: url('/assets/images/practice/cement-shoes.svg'); -} -i.MnsJEWnI { - background-image: url('/assets/images/practice/boxing-glove-surprise.svg'); -} -i.ITWY4GN2 { - background-image: url('/assets/images/practice/two-shadows.svg'); -} -i.s5pLU7Of { - background-image: url('/assets/images/practice/trojan-horse.svg'); -} -i.g1fxVZu9 { - background-image: url('/assets/images/practice/bolt-shield.svg'); -} -i.RUQASaZm { - background-image: url('/assets/images/practice/rogue.svg'); -} -i.\39 c6GrCTk { - background-image: url('/assets/images/practice/siege-tower.svg'); -} -i.Z1DKk4Rl { - background-image: url('/assets/images/practice/stone-crafting.svg'); -} -i.ByhlXnmM { - background-image: url('/assets/images/practice/ghost-ally.svg'); -} -i.pt20yRkT { - background-image: url('/assets/images/practice/stone-tower.svg'); -} -i.MkDViieT { - background-image: url('/assets/images/practice/guarded-tower.svg'); -} diff --git a/public/stylesheets/pref.css b/public/stylesheets/pref.css deleted file mode 100644 index 4779b50746..0000000000 --- a/public/stylesheets/pref.css +++ /dev/null @@ -1,13 +0,0 @@ -.content_box.prefs form li { - font-size: 1.3em; - display: block; - list-style: none outside none; - margin: 20px 0; - border-top: 1px solid #eaeaea; - padding: 20px 0 0 0; -} -div.content_box.prefs h2 { - font-weight: bold; - display: block; - margin-bottom: 20px; -} diff --git a/public/stylesheets/puzzle.css b/public/stylesheets/puzzle.css deleted file mode 100644 index e15714e7e8..0000000000 --- a/public/stylesheets/puzzle.css +++ /dev/null @@ -1,268 +0,0 @@ -#puzzle div.lichess_game div.lichess_ground { - flex: 0 0 280px; - max-width: 280px; -} - -#puzzle .game_control { - justify-content: center; -} - -#puzzle .feedback { - flex: 1 1 0; - border: 1px solid #ccc; - border-top: 0; - background: #fff; - display: flex; - flex-flow: column; - justify-content: center; -} -body.dark #puzzle .feedback { - background: #303030; - color: #aaa; - border-color: #3d3d3d; -} -#puzzle .feedback .player { - display: flex; - align-items: center; - margin-left: 10px; -} -#puzzle .feedback .no-square { - flex: 0 0 64px; - height: 64px; - margin-right: 10px; -} -.is3d #puzzle .feedback div.no-square { - height: 82px; -} -#puzzle .feedback piece { - position: inherit; - display: block; - width: 100%; - height: 100%; -} -#puzzle .feedback .icon { - display: block; - width: 64px; - height: 64px; - font-size: 50px; - line-height: 64px; - text-align: center; -} -#puzzle .feedback.good .icon, -#puzzle .feedback.win .icon { - color: #759900; -} -#puzzle .feedback.fail .icon { - color: #dc322f; -} -#puzzle .feedback .instruction > * { - display: block; -} -#puzzle .feedback .instruction strong { - font-size: 1.5em; -} -@keyframes reveal { - 0% { opacity: 0; } - 100% { opacity: 0.8; } -} -#puzzle .feedback .view_solution { - margin-top: 5px; - margin-bottom: -5px; - text-align: center; - opacity: 0; - visibility: hidden; -} -#puzzle .feedback .view_solution.show { - visibility: visible; - opacity: 0.8; - transition: opacity 0.13s; - animation: reveal 1.5s; -} -#puzzle .feedback .view_solution:hover { - opacity: 1; -} - -#puzzle .feedback.after .half { - flex: 1 1 50%; -} - -#puzzle .feedback.after .half.top { - display: flex; - flex-flow: row nowrap; -} - -#puzzle .feedback.after .complete { - flex: 1 0; - display: flex; - align-items: center; - justify-content: center; - font-size: 1.3em; - border: none; -} -#puzzle .feedback.after .complete.win { - align-items: flex-start; -} -#puzzle .feedback.after .vote { - display: flex; - flex-flow: column; - margin: 0 10px; - align-items: center; - justify-content: center; -} -#puzzle .feedback.after .vote a { - cursor: default; - cursor: pointer; - opacity: 0.7; -} -#puzzle .feedback.after .vote a::before { - font-size: 26px; - line-height: 22px; -} -#puzzle .feedback.after .vote a:hover, -#puzzle .feedback.after .vote a.active { - opacity: 1; - color: #d85000; -} -#puzzle .feedback.after .vote span.count { - font-size: 15px; - line-height: 1; -} - -#puzzle .feedback.after .continue { - display: flex; - font-size: 1.3em; - background: #3893E8; - color: #fff; - align-items: center; - justify-content: center; - text-transform: uppercase; - padding: 0 10px; -} -#puzzle .feedback.after .continue:hover { - background: rgba(56,147,232,0.8); -} -#puzzle .feedback.after .continue i::before { - font-size: 2.5em; - margin-right: 10px; -} -#puzzle .feedback.call { - flex: 1.9 1 0; -} -#puzzle .feedback .vote_call { - font-size: 1.1em; - text-align: right; - background: #759900!important; - color: #fff!important; - padding: 8px 10px; -} - -#puzzle move { - justify-content: space-between; -} -#puzzle move.hist { - opacity: 0.7; -} -#puzzle move glyph { - font-size: 1.3em; - width: 25px; -} -#puzzle move.good glyph, -#puzzle move.win glyph { - color: #759900; - font-size: 1.6em; -} -#puzzle move.fail glyph { - color: #dc322f; -} -#puzzle move.retry glyph { - color: #d59120; -} -#puzzle move:hover glyph { - color: #fff; -} - -#puzzle .timeline { - display: flex; - margin-top: 10px; -} -#puzzle .timeline > * { - flex: 1 0; - background: #ccc; - color: #fff; - margin-left: 4px; - box-sizing: border-box; - opacity: 0.7; - height: 30px; - line-height: 30px; -} -body.dark #puzzle .timeline > * { - background: #444; -} -#puzzle .timeline a:first-child { - margin-left: 0; -} -#puzzle .timeline a:hover { - opacity: 1; -} -#puzzle .timeline a.win { - background: #759900!important; -} -#puzzle .timeline a.loss { - background: #dc322f!important; -} -#puzzle .timeline a.current { - background: #3893E8!important; -} -.puzzle_side .side_box.metas { - padding: 0 7px; -} - -.puzzle_side .game_infos { - margin-top: 14px!important; - padding-bottom: 14px!important; -} -.puzzle_side .header a { - color: #3893E8!important; -} -.puzzle_side .header .hidden { - opacity: 0.7; -} -.puzzle_side .game_infos.puzzle { - padding-left: 56px; -} -.puzzle_side .game_infos.puzzle::before { - font-size: 47px; -} -.puzzle_side .puzzle .header a { - font-size: 1.2em; -} -.puzzle_side .game_infos.game { - border: none; - padding-bottom: 0!important; -} -.puzzle_side .players { - padding-bottom: 14px; -} -.puzzle_side .players .color-icon::before { - width: 30px; - display: inline-block; - text-align: center; -} - -.puzzle_side .rating h2 { - padding: 7px; -} -.puzzle_side .rating span.rp { - /* font-size: 1.2em; */ -} -.puzzle_side .rating span.rp.up { - color: #759900; -} -.puzzle_side .rating span.rp.down { - color: #ac524f; -} -@media (max-width: 1070px) { - .side_box.rating canvas { - width: 194px!important; - } -} diff --git a/public/stylesheets/quote.css b/public/stylesheets/quote.css deleted file mode 100644 index 23a1d7145d..0000000000 --- a/public/stylesheets/quote.css +++ /dev/null @@ -1,56 +0,0 @@ -.pull-quote { - margin: 0 auto; - font-family: 'PT Serif', 'Noto Sans', 'Lucida Grande'; - font-size: 15px; - text-align: left; -} -.pull-quote p { - position: relative; - margin: 0 10px; - padding: 15px 0; - border-top: 1px solid #aaa; - border-bottom: 1px solid #aaa; - font-style: italic; -} -.pull-quote.long p { - font-size: 14px; -} -.pull-quote p:after { - content: ''; - position: absolute; - bottom: -9px; - left: 42px; - width: 15px; - height: 15px; - background: #eee; - border-left: 1.5px solid #aaa; - border-bottom: 1px solid #aaa; - transform: skew(45deg) rotate(-45deg); -} -.content_box .pull-quote p:after { - background: #fff; -} -.pull-quote footer { - margin: 10px; - line-height: 20px; - text-align: right; -} -.pull-quote footer:before { - content: '\2014'; -} -body.dark .pull-quote p, -body.dark .pull-quote p:after { - border-color: #505050; -} -body.dark .content_box .pull-quote p:after { - background-color: #2b2b2b; -} -body.dark .pull-quote p:after { - background: #181818; -} - -body.transp .pull-quote p:after, -body.transp .content_box .pull-quote p:after { - background: linear-gradient(45deg, #505050, #505050 55%, transparent 55%, transparent); - border: none; -} diff --git a/public/stylesheets/relay-list.css b/public/stylesheets/relay-list.css deleted file mode 100644 index b791b38192..0000000000 --- a/public/stylesheets/relay-list.css +++ /dev/null @@ -1,96 +0,0 @@ -.relay_form h1.lichess_title { - text-align: center; - margin-bottom: 0!important; -} -.relay_form textarea.description { - height: 10em; -} -.relays .top { - display: flex; - align-items: center; -} -.relays .top h1 { - flex: 1 1 100%; -} -.relays .top .new_relay { - white-space: nowrap; - margin-right: 10px; -} -.relays .top .new_relay i::before { - color: #759900; - font-size: 40px; -} -.relays .list { - border-top: 1px solid #ccc; -} -.relays .norelays { - text-align: center; - font-size: 2em; -} -.relays .norelays p { - opacity: 0.6; -} -.relays section { - margin-bottom: 2em; -} -.relays section h2 { - font-size: 3em; - text-transform: uppercase; - text-align: center; - font-family: Roboto; - line-height: 2em; - letter-spacing: 0.1em; - opacity: 0.5; -} -body.dark .relays .top .search input, -body.dark .relays .list, -body.dark .relays .relay { - border-color: #3d3d3d; -} -.relays .relay { - border-bottom: 1px solid #ccc; - padding: 20px 10px; - position: relative; -} -.relays .relay:hover { - background: rgba(191, 231, 255, 0.5); -} -.relays .relay a.overlay { - position: absolute; - z-index: 2; - top: 0; - left: 0; - width: 100%; - height: 100%; -} -.relays .relay h3 { - display: block; - position: relative; - box-sizing: border-box; - padding-left: 84px -} -.relays .relay h3 strong { - font-size: 2em; - font-weight: normal; - color: #3893E8; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - display: block; - margin-bottom: .1em; -} -.relays .relay h3 span { - display: block; - font-size: 1.3em; -} -.relays h3 .icon { - position: absolute; - top: 0; - left: 15px; -} -.relays h3 .icon::before { - color: #3893E8; - font-size: 49px; - line-height: 62px; - opacity: 0.8; -} diff --git a/public/stylesheets/relay.css b/public/stylesheets/relay.css deleted file mode 100644 index 98533a4990..0000000000 --- a/public/stylesheets/relay.css +++ /dev/null @@ -1,105 +0,0 @@ -.relay_edit .relay_wrap { - position: absolute; - top: 100%; - width: calc(100% - 15px); -} -.relay_edit .relay_wrap h2 { - background: #fff; - font-size: 1.2em; - padding: 5px 10px; - display: flex; - justify-content: space-between; - border: 1px solid #ccc; -} -.relay_edit .relay { - background: #e0e0e0; - display: flex; - flex-flow: column; - border: 1px solid #ccc; - border-top-width: 0; -} -.relay_edit .relay .state { - display: flex; - border-bottom: 1px solid #ccc; - min-height: 3.5em; - color: #555; -} -.relay_edit .relay .state a { - color: #fff; -} -.relay_edit .relay .state i { - flex: 0 0 50px; - font-size: 23px; - display: flex; - align-items: center; - justify-content: center; -} -.relay_edit .relay .state.clickable:hover { - cursor: pointer; - background: #3893E8; - color: #fff; -} -.relay_edit .relay .state > div { - flex: 1 1 100%; - padding: 8px 10px; - overflow: hidden; - text-overflow: ellipsis; -} -.relay_edit .relay .state .fat { - font-size: 1.5em; - text-transform: uppercase; -} -.relay_edit .relay .state.off { - background: rgba(56, 147, 232, 0.8); - color: #fff; -} -.relay_edit .relay .state.on { - background: #759900; - color: #fff; -} -.relay_edit .relay .time { - font-weight: bold; -} - -.relay_edit .relay .log { - background: #fff; - overflow-x: hidden; - overflow-y: auto; - max-height: 180px; - white-space: nowrap; -} -.relay_edit .relay .log > div { - margin: 4px 0; - display: flex; -} -.relay_edit .relay .log time { - display: inline; - font-family: Roboto; - margin-left: 4px; -} -.relay_edit .relay .log i { - flex: 0 0 32px; - color: #759900; - text-align: center; -} -.relay_edit .relay .log .err i { - color: #dc322f; -} -.relay_edit .relay .log .ddloader { - margin-top: 5px; -} - -body.dark .relay_edit .relay { - background: #262626; -} -body.dark .relay_edit .relay, -body.dark .relay_edit .relay .state, -body.dark .relay_edit .relay_wrap h2 { - border-color: #3d3d3d; -} -body.dark .relay_edit .relay_wrap h2 { - background: #3d3d3d; -} -body.dark .relay_edit .relay .log { - background: #262626; -} diff --git a/public/stylesheets/report.css b/public/stylesheets/report.css deleted file mode 100644 index b892995fe8..0000000000 --- a/public/stylesheets/report.css +++ /dev/null @@ -1,129 +0,0 @@ -#report form.create { - margin-top: 2em; -} -#report_list .header { - display: flex; - justify-content: space-between; - align-items: stretch; - background: #484541; - color: #eee!important; -} -#report_list .header .icon { - display: block; - height: 50px; - width: 50px; - margin: 5px 0 5px 8px; - background: #484541 no-repeat url(../images/icons/octopus.svg); - opacity: 0.9; -} -#report_list .tabs { - display: flex; - margin-right: 15px; - font-size: 1.2em; -} -#report_list .tabs a { - color: #eee!important; - text-transform: uppercase; - padding: 6px 20px; - font-family: Roboto; - display: flex; - flex-flow: column; - align-items: center; - justify-content: center; -} -#report_list .tabs a:hover { - background: rgba(56, 147, 232, 0.5); - color: #fff!important; -} -#report_list .tabs a.active { - background: #3893E8; - color: #fff!important; -} -#report_list .tabs a count { - font-size: 0.8em; - display: block; - height: 1.2em; -} -#report_list .score { - display: inline-block; - white-space: nowrap; - font-weight: bold; - font-size: 1.2em; - padding: 0.3em 0.5em; - border-radius: 0.3em; -} -#report_list .score.green { - /* actually blue */ - background-color: rgba(32, 119, 192, 0.4); -} -#report_list .score.yellow { - background-color: rgba(221, 207, 63, 0.4); -} -#report_list .score.orange { - background-color: rgba(231, 155, 100, 0.4); -} -#report_list .score.red { - background-color: rgba(231, 59, 56, 0.4); -} -#report_list table.see { - border-top: 3px solid #3893E8; -} -#report_list table.see td { - padding: 15px 10px 15px 10px; - word-break: break-all; -} -#report_list table.see button { - width: 100px; - box-sizing: border-box; -} -#report_list table.see .inquiry button { - padding: 15px 20px; - font-size: 1.4em; -} -#report_list table.see .inquiry button:hover { - background: rgba(56, 147, 232, 1); - color: #fff!important; -} -#report_list table.see button.thin { - font-size: 0.9em; -} -#report_list .atoms .atom { - font-size: 0.9em; - margin-bottom: 1em; -} -#report_list .atoms .atom:last-child { - margin-bottom: 0; -} -#report_list .atoms .atom .head { - display: block; -} -#report_list .atoms .atom .score { - font-size: 0.9em; - padding: 0.1em 0.4em; -} -#report_list table.see .perfs { - font-size: 0.9em; - white-space: nowrap; -} -#report_list table.see .text { - max-height: 100px; - overflow: hidden; - font-size: 0.9em; -} -#report_list table.see .text.large { - font-size: 0.8em; -} -#report_list tr.new td:first-child { - border-left: 3px solid #3893E8; -} -.user_marks i { - font-size: 0.9em; - background: #dc322f70; - padding: 0.1em 0.4em; - border-radius: 0.3em; - margin: 0 0.2em; -} -body.dark #report_list .score, -body.dark .user_marks i { - color: #ccc; -} diff --git a/public/stylesheets/search.css b/public/stylesheets/search.css deleted file mode 100644 index 241dab4006..0000000000 --- a/public/stylesheets/search.css +++ /dev/null @@ -1,88 +0,0 @@ -form.search { - padding: 10px 25px; -} - -form.search td { - padding: 5px 0; -} - -form.search .half { - float: left; - width: 49%; - padding-right: 1%; - text-align: right; -} - -form.search label { - margin-right: 10px; -} - -form.search input { - width: 86%; - padding: 3% 5%; -} - -form.search select { - padding: 0.5% 1%; - text-transform: capitalize; -} -form.search .user_row select { - text-transform: none; -} - -form.search .single select { - width: 99%; -} - -form.search .half select { - width: 78%; -} - -form.search .half .flatpickr { - width: 74.93%; /* this will make the date picker just as large as the select */ - border: 1px solid rgb(169, 169, 169); - padding: 0.5% 1%; -} - -form.search input.submit { - width: 99%; -} - -form.search div.level { - display: inline; -} - -form.search span.help { - text-decoration: underline #747474; -} - -div.search_status { - margin-top: 10px; - padding: 10px 25px; - background: #f4f4f4; - border-top: 1px solid #e4e4e4; - border-bottom: 1px solid #e4e4e4; -} - -form.search .error { - margin-left: 160px; - color: red; -} - -form.search .submit { - width: 100%; -} -form.search .wait { - display: none; -} -form.search.searching .spinner { - display: inline-block; - vertical-align: middle; - margin-right: 10px; -} -form.search.searching .wait { - display: block; -} -form.search.searching .submit { - display: none; -} diff --git a/public/stylesheets/setup.css b/public/stylesheets/setup.css deleted file mode 100644 index 49d8216b8c..0000000000 --- a/public/stylesheets/setup.css +++ /dev/null @@ -1,169 +0,0 @@ -div.game_config button { - font-size: 1.4em; - padding: 0 2em; -} -div.game_config button { - letter-spacing: 1px; -} -div.game_config { - padding-bottom: 0; -} -div.game_config.error { - padding-bottom: 22px; -} -div.game_config group.radio { - margin: 0 auto 1em auto; - width: 70%; -} -div.game_config group.radio label { - padding: 5px; -} -div.game_config group.radio label.disabled { - opacity: 0.4; - cursor: default; -} -div.game_config div.ui-slider { - font-size: 1.3em; - margin: 0 15px; -} -div.game_config .optional_config { - padding: 8px 0; - border-bottom: solid 1px #e4e4e4; -} -div.game_config .mode_choice { - margin-top: 1em; -} -div.game_config .optional_config, -div.game_config .ratings { - background: #f4f4f4; - border-top: solid 1px #e4e4e4; -} -div.game_config.error .ratings { - border-top: 0; -} - -div.game_config .label_select { - overflow: hidden; - text-align: left; -} -div.game_config .label_select.variant { - margin-bottom: 8px; -} -div.game_config .label_select label { - display: block; - float: left; - width: 144px; - text-align: right; - padding: 5px 0; -} -div.game_config .label_select select { - margin-left: 10px; - font-weight: bold; - padding: 5px 8px; -} -div.game_config .fen_position { - padding: 8px 0; - display: none; -} -div.game_config .fen_position .cg-board-wrap { - margin: 8px auto 0 auto; -} -div.game_config .fen_position .fen_form { - width: 95%; - margin: auto; -} -div.game_config .fen_position .fen_form input { - border: 1px solid #ccc; - width: 320px; - padding: 2px 3px; -} -div.game_config .fen_position .fen_form .button { - float: right; -} -div.game_config input#fen.success { - border-color: #00aa00; -} -div.game_config input#fen.failure { - border-color: #ac524f; -} -div.game_config .slider { - padding-top: 5px; - text-align: left; - text-indent: 15px; -} -div.game_config .slider span { - font-weight: bold; -} -div.game_config .ratings { - line-height: 50px; - width: 100%; - text-align: center; -} -div.game_config .ratings > div { - display: none; -} -div.game_config .color_submits { - margin: 1em auto; - text-align: center; - display: flex; - align-items: flex-end; - justify-content: center; -} -div.game_config button { - margin: 0 8px; -} -div.game_config button.nope { - visibility: hidden; -} -div.game_config button:disabled { - opacity: 0.3; -} -div.game_config button.black, -div.game_config button.white { - width: 50px; - height: 50px; - padding: 5px; -} -div.game_config button.black i, -div.game_config button.white i { - display: block; - width: 40px; - height: 40px; - padding: 0; - background-size: 40px 40px; -} -div.game_config button.white i { - background-image: url(../piece/cburnett/wK.svg); -} -div.game_config button.black i { - background-image: url(../piece/cburnett/bK.svg); -} -div.game_config button.random { - width: 75px; - height: 75px; - padding: 10px; -} -div.game_config .color_submits button.random i { - background-image: url(../images/wbK.svg); - background-size: 55px 55px; - display: block; - width: 55px; - height: 55px; - padding: 0; -} -div.game_config.lichess_overboard { - top: 55%; -} -body.dark div.game_config .optional_config, -body.dark div.game_config input[type="text"], -body.dark div.game_config .ratings { - border-color: #3d3d3d; -} -body.dark div.game_config .optional_config, -body.dark div.game_config .ratings { - background: #343434; -} -body.transp div.game_config .optional_config, -body.transp div.game_config .ratings { - background: rgba(0, 0, 0, 0.3); -} diff --git a/public/stylesheets/shepherd.css b/public/stylesheets/shepherd.css deleted file mode 100644 index 6799830b11..0000000000 --- a/public/stylesheets/shepherd.css +++ /dev/null @@ -1,25 +0,0 @@ -.shepherd-step { - z-index: 5011; - font-size: 1.2em!important; -} -body:not(.dark) .shepherd-cancel-link { - color: #fff!important; -} -.shepherd-text { - padding: 1em 1em 5px 1em!important; -} -.shepherd-text a { - color: #3893E8!important; -} -.shepherd-content footer { - padding: 0!important; -} -.shepherd-buttons li:last-child .shepherd-button { - border-radius: 3px 0 5px 0!important; - background: none!important; - color: #3893E8!important; -} -.shepherd-buttons li:last-child .shepherd-button:hover { - background: #3893E8!important; - color: #fff!important; -} diff --git a/public/stylesheets/simul.css b/public/stylesheets/simul.css deleted file mode 100644 index 9be6bbc15f..0000000000 --- a/public/stylesheets/simul.css +++ /dev/null @@ -1,196 +0,0 @@ -#simul.form h1 { - text-align: center; - display: block; -} -#simul.form .variants { - display: flex; - flex-flow: row wrap; -} -#simul.form .variants .checkable { - flex: 1 1 33%; - white-space: nowrap; -} -#simul .content_box { - min-height: 400px; -} -#simul .halves { - overflow: hidden; -} -#simul .half { - box-sizing: border-box; - float: left; - margin-bottom: 20px; -} -#simul .half:first-child { - border-right: 1px solid #ccc; - width: 50%; -} -#simul .half:last-child { - border-left: 1px solid #ccc; - margin-left: -1px; - width: calc(50% + 1px); -} -#simul .half .variant::before { - font-size: 1.6em; - opacity: 0.8; -} -#simul .half .user_link { - line-height: 2.5em; -} -#simul .half tr.help th { - padding: 60px 20px; -} -#simul .half td.action { - text-align: right; - opacity: 0.6; - transition: opacity 0.13s; -} -#simul .half td.action:hover { - opacity: 1; -} -#simul .half.candidates tr.me { - border-left: 10px solid #d59120; -} -#simul .half.accepted tr.me { - border-right: 10px solid #d59120; -} -#simul .pull-quote { - margin-top: 30px; - width: 300px; -} -#simul .top_right { - float: right; - margin: 20px 25px 0 0; -} -#simul .top_right.finished { - font-size: 20px; -} -#simul .instructions { - text-align: center; - margin-bottom: 1em; -} -#simul h1 .author { - margin-left: 1em; - font-size: 0.7em; -} -#simul a.user_link em { - font-weight: bold; - padding-left: 5px; -} -#simul .results > div { - width: 25%; - display: inline-block; - text-align: center; -} -#simul .results .number { - font-size: 3em; - font-weight: bold; -} -#simul .results .text { - font-family: 'Roboto'; - font-weight: 300; - font-size: 1.5em; - text-transform: uppercase; -} -#simul .game_list { - margin-top: 30px; - text-align: center; -} -#simul .game_list .vstext { - transition: all 1s; -} -.variant_icons { - white-space: nowrap; -} -.variant_icons span { - font-size: 4em; - text-shadow: 0 0 5px #fff, 0 0 10px #fff, 0 0 20px #fff; -} -.variant_icons span:not(:first-child) { - margin-left: -0.5em; -} -.variant_icons.rich span:not(:first-child) { - margin-left: -1em; -} -div.side_box .game_infos { - padding-left: 0; -} -.side_box .variant_icons { - float: left; -} -.side_box .variant_icons span { - font-size: 2.5em; -} -.side_box .clock { - font-size: 1.5em; - line-height: 2em; - margin-left: 10px; -} -.side_box .setup { - margin-top: 10px; -} -#simul .join_choice { - display: none; -} -#simul table.slist td:first-child { - padding-left: 1em; -} - -#simul_list table.slist { - line-height: 2.3em; -} -#simul_list table.slist td { - padding-top: 1em; - padding-bottom: 1em; -} -#simul_list table.slist .header { - letter-spacing: 2px; - cursor: pointer; - transition: transform 0.3s; - padding: 0!important; -} -#simul_list table.slist .header:hover { - transform: translateX(3px); -} -#simul_list table.slist .header a { - padding: 1em; - display: block; -} -#simul_list table.slist .name { - letter-spacing: 3px; - font-size: 1.7em; - display: block; -} -#simul_list table.slist .create td { - padding: 2em; - text-align: center; -} -.setup { - text-transform: uppercase; -} -#simul div.game_list.playing > div { - position: relative; - overflow: hidden; -} -#site_header .help { - margin-top: 20px; -} -#site_header .help a { - color: #3893E8; -} -#modal-wrap.card { - max-width: 500px; - padding: 0; -} -#modal-wrap.card img { - width: 100%; -} -#modal-wrap.card em { - font-style: italic; - margin-top: 10px; - display: block; -} -#modal-wrap.card p { - margin: 30px 20px; - text-align: justify; -} diff --git a/public/stylesheets/stage.css b/public/stylesheets/stage.css deleted file mode 100644 index 4bd74fd425..0000000000 --- a/public/stylesheets/stage.css +++ /dev/null @@ -1,26 +0,0 @@ -body { - margin-top: 45px; -} - -#stage { - height: 40px; - background: #7f1010; - color: #fff!important; - font-size: 1.3em; - display: flex; - flex-flow: row nowrap; - justify-content: center; - align-items: center; - border-bottom: 1px solid #666; - box-shadow: 0 5px 6px rgba(0, 0, 0, 0.3); - position: fixed; - top: 0; - left: 0; - right: 0; - z-index: 100; -} -#stage a { - color: #fff!important; - text-decoration: underline; - margin-left: 1em; -} diff --git a/public/stylesheets/stat.css b/public/stylesheets/stat.css deleted file mode 100644 index 14178d2d47..0000000000 --- a/public/stylesheets/stat.css +++ /dev/null @@ -1,19 +0,0 @@ -.content_box { - min-height: 570px; -} -.content_box .spinner { - width: 150px; - height: 150px; - margin-top: 100px; -} -.content_box .desc { - padding: 0 25px 25px 25px; - font-size: 1.3em; - overflow: hidden; -} -.content_box .desc::before { - font-size: 70px; - float: left; - opacity: 0.7; - margin-right: 10px; -} diff --git a/public/stylesheets/streamer.form.css b/public/stylesheets/streamer.form.css deleted file mode 100644 index 4ca1765055..0000000000 --- a/public/stylesheets/streamer.form.css +++ /dev/null @@ -1,87 +0,0 @@ -.streamer.edit .top .picture_wrap { - margin-right: 30px; - width: 250px; - height: 250px; -} -.streamer_picture .picture_wrap { - text-align: center; -} - -.streamer.edit .top .upload_picture { - text-align: center; - margin-top: 80px; -} - -.streamer.edit #description { - height: 10em; -} - -.streamer_picture form { - padding: 30px; - border-top: 1px solid #ccc; - text-align: center; -} -.streamer_picture form.delete button { - color: red; -} -.streamer_picture .cancel { - padding: 40px; - border-top: 1px solid #ccc; -} -.streamer_picture .forms > *:first-child { - margin-top: 40px; -} - -.streamer.edit .status { - margin: 20px; - padding: 20px; - background: rgba(128,128,128,0.2); -} -.streamer.edit .mod { - margin-bottom: 6em; -} -.streamer.edit .status::before { - font-size: 2em; - margin-right: 0.5em; -} -.streamer.edit .status form { - display: inline; -} - -#site_header a.preview { - display: block; - margin-top: 40px; - text-align: center; -} - -.streamer-new h2 { - font-size: 1.4em; - margin-bottom: 1em; -} -.streamer-new .rules li, -.streamer.edit .rules li { - font-size: 1.2em; - margin: 1em 0 1em 2.2em; - line-height: 1.6em; - text-indent: -2.2em; -} -.streamer-new .rules li::before, -.streamer.edit .rules li::before { - font-family: 'lichess'; - content: 'E'; - font-size: 1.5em; - margin-right: 0.5em; - vertical-align: middle; - opacity: 0.8; -} - -.streamer-new button { - margin: 1.5em auto 0 auto; - display: block; - font-size: 2em; -} - -body.dark .streamer_picture form, -body.dark .streamer_picture .cancel { - border-color: #3d3d3d; -} diff --git a/public/stylesheets/streamer.list.css b/public/stylesheets/streamer.list.css deleted file mode 100644 index 85a112435b..0000000000 --- a/public/stylesheets/streamer.list.css +++ /dev/null @@ -1,124 +0,0 @@ -.streamers .streamer { - border-top: 1px solid #ccc; - position: relative; - display: flex; -} -.streamers .streamer:hover { - background: rgba(191, 231, 255, 0.5); -} -.streamers .streamer a.overlay { - position: absolute; - z-index: 2; - top: 0; - left: 0; - width: 100%; - height: 100%; -} -.streamers .streamer img.picture { - flex: 0 0 250px; -} -.streamers .streamer img.picture.default { - opacity: 0.3; -} -.streamers .overview { - margin: 20px 10px 0 20px; - display: flex; - flex-flow: column; - justify-content: space-between; - padding-bottom: 15px; -} -.streamers .streamer h1 { - font-family: 'Roboto'; - font-size: 32px; - text-transform: uppercase; - letter-spacing: 3px; - padding: 0!important; - text-shadow: none!important; -} -.streamers .streamer .headline { - font-family: 'PT Serif', 'Noto Sans', 'Lucida Grande'; - font-size: 17px; - padding: 0!important; -} -.streamers .streamer .headline.medium { - font-size: 15px; -} -.streamers .streamer .headline.large { - font-size: 14px; -} -.streamers .streamer .services { - margin: 5px 0 10px 0; -} -.streamers .streamer .service { - display: flex; - font-size: 1.5em; - white-space: nowrap; - padding: 3px 0; -} -.streamers .streamer .service svg { - width: 1.4em; - height: 1.4em; - margin-right: 0.4em; - opacity: 0.7; -} - -.streamer .ribbon { - width: 150px; - height: 150px; - overflow: hidden; - position: absolute; - top: -10px; - right: -10px; - z-index: 2; -} -.streamer .ribbon::before, -.streamer .ribbon::after { - position: absolute; - z-index: 0; - content: ''; - display: block; - border: 5px solid #2980b9; - border-top-color: transparent; - border-right-color: transparent; -} -.streamer .ribbon::before { - top: 0; - left: 0; -} -.streamer .ribbon::after { - bottom: 0; - right: 0; -} -.streamer .ribbon span { - position: absolute; - left: -25px; - top: 30px; - transform: rotate(45deg); - display: block; - width: 225px; - padding: 15px 0; - background-color: #3498db; - box-shadow: 0 5px 10px rgba(0,0,0,.1); - color: #fff; - font: 700 18px/1 Roboto; - text-shadow: 0 1px 1px rgba(0,0,0,.2); - text-transform: uppercase; - text-align: center; -} - -body.dark .streamers .streamer .service svg path { - fill: #aaa; -} -@media (max-width: 1084px) { - .streamer-side { - margin-left: 0!important; - width: 196px!important; - } - .streamer-intro h2 { - font-size: 1.75em; - } -} -body.dark .streamers .streamer, -body.dark .streamer-add { - border-color: #3d3d3d; -} diff --git a/public/stylesheets/streamer.show.css b/public/stylesheets/streamer.show.css deleted file mode 100644 index d33e863b0b..0000000000 --- a/public/stylesheets/streamer.show.css +++ /dev/null @@ -1,119 +0,0 @@ -.streamer-side { - margin: 15px 0 0 -35px; -} -.streamer .top { - display: flex; -} -.streamer img.picture { - flex: 0 0 250px; -} -.streamer .overview { - margin: 20px 10px 0 20px; - display: flex; - flex-flow: column; - justify-content: space-between; - width: 100%; -} -.streamer .metas { - display: flex; - justify-content: space-between; - align-content: center; -} -.streamer .follow:disabled { - cursor: default; - opacity: 1; -} -div.content_box.streamer h1 { - font-family: 'Roboto'; - font-size: 32px; - text-transform: uppercase; - letter-spacing: 4px; - padding: 0!important; - text-shadow: none!important; -} -.streamer .headline { - font-family: 'PT Serif', 'Noto Sans', 'Lucida Grande'; - font-size: 17px; - padding: 0!important; -} -.streamer .headline.medium { - font-size: 15px; -} -.streamer .headline.large { - font-size: 14px; -} -.streamer .services { - margin: 5px 0; -} -.streamer .service { - display: flex; - font-size: 1.5em; - white-space: nowrap; - padding: 5px 0; -} -.streamer .service.live { - color: #dc322f; -} -.streamer .service svg { - width: 1.4em; - height: 1.4em; - margin-right: 0.4em; -} -.streamer a.service:hover svg path { - fill: #3893E8!important; -} -.livestream { - margin-bottom: 0px; - line-height: 0; - margin-bottom: 10px; -} -.livestream iframe { - border: none; -} -.nostream { - height: 300px; - background: black; - display: flex; - align-items: center; - justify-content: center; - font-size: 40px; - letter-spacing: 10px; -} -.streamer .description { - padding: 2.5em 50px 2.5em 65px; - font-size: 1.4em; -} -.streamer .services a:hover, -.streamer .description a { - color: #3893E8; -} -.streamer .ratings { - padding: 2em 50px 2em 58px; - font-size: 1.6em; - background: rgba(213,145,32,0.2); - display: flex; - justify-content: space-between; - margin-bottom: 1em; -} -.streamer .ratings span::before { - font-size: 1.6em; - margin-right: 0.1em; -} - -.blocker { - margin-top: 30px; - padding: 15px 0!important; - display: flex; - flex-flow: column; - align-items: center; - text-align: center; - font-weight: normal!important; -} -.blocker i { - font-size: 40px; - margin-bottom: 10px; -} - -body.dark .streamer .service svg path { - fill: #aaa; -} diff --git a/public/stylesheets/study-create.css b/public/stylesheets/study-create.css deleted file mode 100644 index 3199c224af..0000000000 --- a/public/stylesheets/study-create.css +++ /dev/null @@ -1,30 +0,0 @@ -form h2 { - font-size: 1.3em; - margin-bottom: 1em; -} -button.new { - margin: 1.5em auto; - display: block; - font-size: 2em; -} - -.studies { - display: flex; - flex-flow: row nowrap; -} - -.studies > div { - flex: 0 1 50%; - box-sizing: border-box; - overflow: hidden; -} -.studies > div:last-child { - margin-left: 20px; -} - -.studies button { - width: 100%; - text-align: left; - overflow: hidden; - margin-bottom: 3px; -} diff --git a/public/stylesheets/study.css b/public/stylesheets/study.css deleted file mode 100644 index 2b417b4992..0000000000 --- a/public/stylesheets/study.css +++ /dev/null @@ -1,932 +0,0 @@ -.study_tabs { - display: flex; - -moz-user-select: none; - -webkit-user-select: none; -} -.study_tabs a { - text-transform: uppercase; - display: block; - width: 100%; - text-align: center; - padding: 6px 0 4px 0; - background: #fff; - border-bottom: 3px solid transparent; -} -.study_box .study_tabs a { - font-family: 'Roboto'; - font-weight: 300; -} -.study_tabs a.more { - flex: 0 0 32px; -} -.study_tabs a.more i { - opacity: 0.6; -} -.study_tabs a:hover { - color: #3893E8!important; -} -.study_tabs a.active { - color: #3893E8!important; - border-bottom: 3px solid #3893E8; -} -.material.form .study_tabs { - margin-top: -20px; - margin-bottom: 40px; -} -body:not(.dark) .material.form .study_tabs a { - background: #f0f0f0; -} -.study_box { - position: relative; - min-height: 50px; -} -form.chapter_form.material.form .form-group textarea { - height: 100px; - line-height: 1.2em; - font-size: 0.9em; -} -div.underboard { - margin-top: 17px; - min-height: 370px; -} -.underboard_form .title { - background: #e0e0e0; - line-height: 30px; -} -div.underboard .notif { - margin: -20px 0 20px 0; - width: 100%; - height: 50px; - display: flex; - justify-content: center; - align-items: center; - background: #759900; - color: #fff; - font-size: 1.4em; -} -div.underboard .notif.error { - background-color: #d59120; -} -.study_comment_form form.material.form, -.chapter_desc_form form.material.form { - display: flex; - align-items: center; - margin: 0; -} -.study_comment_form form .form-group, -.chapter_desc_form form .form-group { - width: 100%; - margin-bottom: 15px!important; -} -.underboard form.material.form textarea { - height: 150px; - padding: 10px 0; - font-size: 1.1em; - line-height: 1.3em; - resize: vertical; -} -.underboard form.material.form .form-group .bar::before { - background: rgba(99,155,36,0.75); -} -.study_comments { - text-align: left; -} -.study_comments .comment { - font-size: 1.2em; - background: #e0e0e0; - padding: 5px 10px; - margin-bottom: 10px; -} -.study_comments .text { - width: 100%; - overflow: hidden; - word-wrap: break-word; - display: inline-block; -} -.study_comments .text a, -.chapter_desc .text a { - color: #3893E8!important; -} -.study_comments .edit { - float: right; - margin-left: 8px; - opacity: 0.7; - display: none; -} -.study_comments .comment:hover .edit { - display: block; -} -.study_comments .comment .edit:hover { - opacity: 1; -} -.study_comments .user_link, -.study_comments .node { - font-weight: bold; -} - -.chapter_desc { - margin-bottom: 10px; - text-align: left; - font-size: 1.2em; - position: relative; -} -.chapter_desc .contrib { - position: absolute; - top: 0; - right: 0; - background: #fff; - padding: 5px 10px; - display: none; -} -.chapter_desc:hover .contrib { - display: block; -} -.chapter_desc .contrib a { - margin-left: 8px; -} -.chapter_desc_form { - margin-bottom: 10px; -} -.chapter_desc_form textarea { - height: 15em!important; -} - -.study_box .list { - max-height: 180px; - overflow: hidden; - overflow-y: auto; - position: relative; -} -.study_box .list .elem { - display: flex; - justify-content: space-between; - -moz-user-select: none; - -webkit-user-select: none; -} -.study_box .elem .user_link, -.study_box .elem.member .add_text { - overflow: hidden; - text-overflow: ellipsis; - line-height: 26px; - margin-left: 4px; -} -.study_box .list .sortable-ghost { - background: #3893E8; - color: #fff; - opacity: 0.5; -} -.study_box .list .sortable-ghost i::before { - color: #fff; -} -.study_box .list .left, -.study_box .list .right { - display: flex; - align-items: center; - max-width: 200px; -} -.study_box .list .left { - flex: 0 1 auto; - overflow:hidden; -} -.study_box .list .status, -.study_box .list .action { - display: block; - width: 20px; - height: 26px; - line-height: 26px; - text-align: center; - margin: 0; - padding: 0 2px; - flex-shrink: 0; -} -.study_box .list .status i, -.study_box .list .action { - font-size: 14px; - opacity: 0.15; - transition: opacity 0.13s; -} -.study_box .list .action { - cursor: pointer; - display: flex; - align-items: center; - height: auto; -} -.study_box .list .action.leave { - opacity: 0.6; - color: #dc322f; -} -.study_box .list > div:hover .action { - opacity: 1; -} -.study_box .members .status i { - opacity: 0.5; - transition: 2.5s; -} -.study_box .members .contrib i { - opacity: 0.7; -} -.study_box .members .status { - transition: 2.5s; -} -.study_box .members .online i { - opacity: 0.8; - color: #759900; -} -.study_box .members .online.contrib i { - opacity: 1; -} -.study_box .members .status.active { - transition: none; -} -.study_box .members .member:nth-child(4n-3) .status.active { - background: #42a5f5; -} -.study_box .members .member:nth-child(4n-2) .status.active { - background: #f44336; -} -.study_box .members .member:nth-child(4n-1) .status.active { - background: #fdd835; -} -.study_box .members .member:nth-child(4n-0) .status.active { - background: #4caf50; -} -.study_box .members .status.active i { - transition: none; - opacity: 1; - color: #fff; -} -.study_box .add { - border-top: 1px solid #ccc; - cursor: pointer; - background: #fff; - color: #3893E8!important; - opacity: 0.8; -} -.study_box .add i { - color: #3893E8!important; - opacity: 1!important; -} -.study_box .add:hover { - opacity: 1; -} -.study_invite .info { - background: #3893E8; - color: #fff; - padding: 1em; - margin-bottom: 1em; - text-align: left; -} -.study_invite .info::before { - font-size: 3.6em; - float: left; - margin-right: 20px; -} -.study_invite .users { - max-height: 200px; - overflow-y: auto; - border: solid #ccc; - border-width: 1px 0; - padding: 12px 20px 2px 20px; - margin-bottom: 20px; - display: flex; - flex-flow: row wrap; - justify-content: space-between; -} -.study_invite .users .button { - flex: 0 0 48%; - display: block; - box-sizing: border-box; - overflow: hidden; - text-overflow: ellipsis; - margin-bottom: 10px; -} -.study_invite input { - width: 214px; - border: none; - border: 1px solid #ccc; - background: #fff; - padding: 3px 5px; -} -.study_invite .tt-menu { - text-align: left; -} -.study_box .list div.editing, -.study_box .list div.config { - background: #fff; -} -.study_box .list div.config { - padding: 5px 10px 15px 10px; -} -.study_box .list div.config .role { - line-height: 22px; -} -.study_box .list div.config .role label { - cursor: pointer; -} -.study_box .list div.config .switch { - float: left; - margin-right: 10px; -} -.study_box .list div.config .kick, -.study_box .list div.config .delete { - margin-top: 15px; -} -.study_box .chapter:not(.add) { - cursor: pointer; - align-items: stretch; - border: 1px solid transparent; - border-width: 1px 0; -} -.study_box .chapter:not(.add):hover { - border-color: rgba(56, 147, 232, 0.1); -} -.study_box .chapter h3 { - flex: 1 1 100%; - line-height: 1.1em; - margin: 4px 0; - display: flex; - align-items: center; - word-break: break-all; -} -.study_box .chapters .status { - color: #3893E8; - opacity: 1; - font-weight: bold; - width: 20px; - height: auto; - margin-right: 6px; - display: flex; - justify-content: center; - align-items: center; - opacity: 0.8; -} -.study_box .chapter.active:not(.add), -.study_box .chapter:not(.add):hover { - background: rgba(56, 147, 232, 0.1); -} -.study_box .chapter.active .status, -.study_box .chapter:active, -.study_box .chapter:active .status { - color: #fff!important; - background: #3893E8!important; -} -.study_box .chapter .ddloader { - height: auto; - background-size: cover; - color: transparent; -} -.study_box .chapter.add .status { - width: 23px; - margin-right: 3px; -} -.study_box .chapters .status .spinner { - width: 18px; - height: 18px; - margin: 6px 0 0 0; - display: inline-block; -} -.study_overboard.lichess_overboard { - top: 60%; -} -.is3d .study_overboard.lichess_overboard { - top: 65%; -} -.study_overboard .material.form { - margin: 0; - padding: 20px; -} -.study_overboard .align-left { - text-align: left; -} -.study_overboard .form .editor { - margin: -30px 0 30px 0; -} -.study_overboard .form .editor .spinner { - padding-top: 80px; -} -.study_overboard h2 i { - margin-left: 10px; - opacity: 0.5; - cursor: pointer; -} -.study_overboard h2 i:hover { - opacity: 0.7; - color: #3893E8; -} -.material.form a.form-help:hover { - text-decoration: underline; -} -.study_buttons { - display: flex; - justify-content: space-between; - border: 1px solid #ccc; - border-bottom: 2px solid rgba(99,155,36,0.75) !important; -} -.study_buttons .member_buttons { - display: flex; -} -.study_buttons .member_buttons .fbt { - display: inline-block; - font-weight: normal; - text-transform: uppercase; -} -.study_buttons .behind { - background: #dc322f; - color: #fff; - padding: 0 5px; - border-radius: 9px; - margin-right: 4px; -} -.study_buttons .fbt { - padding: 5px 13px; -} -.study_buttons .fbt i { - height: 16px; - display: inline-block; -} -.study_buttons .fbt .data-count::after, -.study_buttons .fbt:not(:disabled):hover { - background: #639B24!important; -} -body.base .study_buttons .fbt:not(:disabled):active, -body.base .study_buttons .fbt.active { - background: rgba(99,155,36,0.75)!important; - border-top: 1px solid #639B24; - margin-top: -1px; -} -.study_buttons .mode { - padding: 5px 10px; - text-transform: uppercase; - opacity: 0.8; -} -.study_buttons .mode i::before { - font-size: 19px; - content: 'L'; - color: #dc322f; - margin-right: 4px; -} -.study_buttons .mode.on i::before { - content: 'E'; - color: #639B24!important; -} -.study_buttons .mode:hover { - background: rgba(128,128,128,0.15); - opacity: 1; -} - -.underboard .message { - height: 100px; - width: 100%; - display: flex; - flex-flow: column; - align-items: center; - justify-content: center; -} - -.glyph-icon::before { - content: '⁉'; - font-size: 1.3em; - vertical-align: middle; - width: 14px; - display: inline-block; - font-style: normal; -} -.glyph_form { - text-align: left; - width: 100%; - display: flex; - white-space: nowrap; - margin-bottom: 15px; - -moz-user-select: none; - -webkit-user-select: none; -} -.glyph_form > * { - flex: 1 0 30%; -} -.glyph_form a { - display: flex!important; - cursor: pointer; - transition: 0.13s; - align-items: center; -} -.glyph_form i::before { - content: attr(data-symbol); - font-size: 1.2em; - font-style: normal; - font-weight: bold; - display: block; - width: 20px; - text-align: center; - background: #ddd; - padding: 2px 10px; - margin-right: 6px; - transition: 0.13s; -} -.glyph_form a:hover, -.glyph_form a.active { - background: #fff; - color: #639B24; -} -.glyph_form a:hover i::before { - background: #eee; -} -.glyph_form a.active i::before { - background: #639B24!important; - color: #fff!important; -} -.study_share input { - font-size: 13px!important; -} -.study_share .ply-wrap { - margin-top: -5px; - text-align: left; - opacity: 0.7; - font-size: 0.8rem; -} -.study_share .ply { - cursor: pointer; -} -.study_share .ply input { - margin-right: 5px; - vertical-align: middle; -} -.study_share .fen { - overflow: hidden; - font-family: monospace; - font-size: 11px; - line-heigth: 2em; - white-space: nowrap; - margin: -1rem 0 1rem 0; - padding: 1em; - background: #f0f0f0; - border-radius: 5px; -} -.study_share .downloads { - display: flex; - justify-content: space-between; - margin: 20px 20px 20px 20px; -} - -.server_eval, -.server_eval .message { - height: 200px; -} -.server_eval .request { - margin-top: 2em; -} - -.multi_board .spinner { - margin: 50px auto; -} -.multi_board.loading { - opacity: 0.7; -} -.multi_board .top { - justify-content: space-between; - align-items: center; - display: flex; -} -.multi_board .playing { - cursor: pointer; -} -.multi_board .playing input { - vertical-align: middle; - margin-right: 3px; -} -.multi_board .pager .page { - margin: 0 3px; -} -#now_playing { - padding: 0 0 0 1px; -} -#now_playing > a { - flex: 0 0 160px; - overflow: hidden; - padding: 5px; - transition: none; -} -#now_playing a:nth-child(even) { - background: rgba(128, 128, 128, 0.2); -} -body.dark #now_playing a { - background: #000; -} -body.dark #now_playing a:nth-child(even) { - background: #333; - color: #aaa; -} -body.base #now_playing > a:hover { - background: rgba(56, 147, 232, 0.7); - color: #fff; -} -#now_playing a.active, -#now_playing a:active { - background: rgba(99,155,36,0.8)!important; - color: #fff!important; -} -#now_playing .player { - height: 1.5em; - white-space: nowrap; - display: flex; - justify-content: space-between; -} -#now_playing .name { - display: flex; - align-items: center; - justify-content: center; - height: 3em; -} - -div.advice_summary { - margin-top: 42px; -} - -body.dark .underboard_form .title, -body.dark .study_comments .comment, -body.dark .glyph_form i::before { - background: #262626; -} -body.dark .study_share .fen, -body.dark .chapter_desc .contrib, -body.dark .study_box .add, -body.dark .glyph_form a.active, -body.dark .glyph_form a:hover, -body.dark .glyph_form a:hover i::before { - background: #303030; -} - -.destructive { - margin-top: 20px; -} -.destructive form { - display:inline-block; -} -.destructive button { - color: #dc322f!important; - opacity: 0.5; - font-weight: normal; -} -.destructive button:hover { - opacity: 1; -} - -form .editor_wrap { - min-height: 280px; -} -form .editor_wrap .spinner { - padding-top: 90px; -} -form .editor { - position: relative; -} -form .editor .manipulable .cg-board, #board_editor body.destination .cg-board square.move-dest { - cursor: inherit; -} -form .editor .spare { - height: 28px; - width: 224px; - margin: 3px 0; -} -form .editor .spare.black { - background: #888; -} -form .editor .spare.white { - background: #ccc; -} -form .editor .spare .selected-square { - background: #3893E8; -} -form .editor .spare .no-square { - position: relative; - display:inline-block; - width: 28px; - height: 26px; -} -form .editor .spare piece { - cursor: pointer; - width: 100%; - height: 100%; -} -/* http://www.flaticon.com/free-icon/clicker_99162 */ -form .editor .spare piece.pointer { - background-image: url('/assets/images/icons/pointer.png'); - width: 100%; - height: 100%; -} -form .editor .spare piece.trash { - font-size: 12pt; - top: 10%; - height: 100%; -} -form .editor .spare .no-square.trash { - color: black; - text-align: center -} -form .editor .cg-board-wrap { - width: 224px!important; - height: 224px!important; -} -form .editor square.last-move { - background-color: transparent!important; -} -form .editor .editor-side { - position: absolute; - left: 233px; - top: 35px; - text-align: left; -} -form .editor .editor-side .content_box { - background: none; - border: 0; - padding: 0; - box-shadow: none; - margin-bottom: 10px; -} -form .editor .castling { - margin-top: 10px; -} -form .editor .castling strong { - display: none; -} -form .editor .castling label { - display: block; - cursor: pointer; -} -form .editor .castling input { - cursor: pointer; - margin-right: 5px; -} -form .editor a.button { - display: block; -} -.study_metadata { - text-align: left; -} -.study_metadata h2 { - font-size: 1.3em; - padding: 7px 12px 7px 12px; - font-weight: normal; - white-space: nowrap; - display: flex; - justify-content: space-between; -} -.study_metadata .name::before { - font-size: 1.3em; - margin-right: 8px; - opacity: 0.7; -} -.study_metadata h2 .name { - overflow: hidden; - text-overflow: ellipsis; -} -.study_metadata h2 .liking { - padding-left: 12px; - margin-left: 12px; - border-left: 1px solid #ccc; - font-weight: bold; - cursor: pointer; - opacity: 0.7; - transition: 0.3s; -} -.study_metadata h2 .liking:hover { - opacity: 1; - color: #dc322f!important; -} -table.tags { - border: none; -} -table.tags th { - text-transform: uppercase; - font-size: 1.1em; - opacity: 0.7; - border-top: 1px solid #eaeaea; - width: 1px; - padding: 0 5px 0 15px!important; -} -body.dark .study_box .add, -body.dark table.tags th, -body.dark .study_buttons { - border-color: #3d3d3d; -} -table.tags tr:first-child th { - border-top: none; -} -table.tags td { - padding: 0; -} -table.tags td input, -table.tags td span, -table.tags td pre { - padding-left: 10px; - line-height: 2.5em; -} -table.tags td input { - border: none; - background: none; - width: 100%; - box-sizing: border-box; -} -table.tags td input:hover, -table.tags td input:focus { - background: rgba(56, 147, 232, 0.08); -} -table.tags #study_fen { - font-size: 0.8em; - margin: 0.3em 0; -} -div.undertable { - margin-top: 0; -} -div.undertable_inner { - height: auto; - max-height: 200px; -} -.board_left.no_chat #chat { - height: auto!important; -} -.board_left.no_chat .study_box .list { - max-height: 500px; -} -div.chapter_embed { - line-height: 0; - margin-bottom: 5px; -} - -.player_bars { - margin-bottom: 32px; -} -.player_bar { - background: #ccc; - color: #555; - text-shadow: 0 .5px 1px #fff; - display: flex; - height: 26px; - justify-content: space-between; - align-items: center; - font-size: 16px; - font-weight: bold; - position: absolute; - left: 0; - right: 0; -} -body.dark .player_bar { - background: #444; - color: #bbb; - text-shadow: 0 .5px 1px #000; -} -.lichess_board_wrap.white .player_bar.black, -.lichess_board_wrap.black .player_bar.white { - border-radius: 4px 4px 0 0; - top: -26px; -} -.lichess_board_wrap.white .player_bar.white, -.lichess_board_wrap.black .player_bar.black { - border-radius: 0 0 4px 4px; - bottom: -26px; -} -.player_bar .left { - flex: 1 1 100%; - display: flex; - justify-content: flex-start; -} -.player_bar .result { - flex: 0 0 auto; - margin-left: 10px; - font-weight: normal; - padding-right: 10px; - border-right: 1px solid rgba(127,127,127,0.5); -} -.player_bar .aclock { - font-family: 'Roboto Mono', 'Roboto'; - font-size: 17px; - height: 26px; - line-height: 26px; - padding: 0 10px; - border-radius: 0 4px 0 0; -} -.lichess_board_wrap.white .player_bar.white .aclock, -.lichess_board_wrap.black .player_bar.black .aclock { - border-radius: 0 0 4px 0; -} -.player_bar.ticking .aclock { - background: #759900; - color: #fff; - text-shadow: none; -} -.player_bar .info { - margin-left: 10px; -} -.player_bar .elo { - margin-left: 0.5em; - font-weight: normal; -} - -.relay_players .cg-board-wrap coords.files { - bottom: 0px; - text-align: left; -} -.relay_players .cg-board-wrap coords.files coord { - padding-left: 2px; - color: #fff; - text-shadow: 0 1px 2px #000; -} diff --git a/public/stylesheets/studyList.css b/public/stylesheets/studyList.css deleted file mode 100644 index 06cd1a401e..0000000000 --- a/public/stylesheets/studyList.css +++ /dev/null @@ -1,191 +0,0 @@ -.studies .top { - display: flex; - align-items: center; -} -.studies .top .search { - flex: 1 1 100%; - margin: 15px 20px; - display: flex; -} -.studies .top .search input { - flex: 1 1 100%; - padding: 0 10px; - font-size: 20px; - line-height: 40px; - border: 1px solid #ccc; -} -.studies .top .search .submit { - padding: 0 30px; - border-radius: 0 3px 3px 0; - border-left: 0; - font-size: 16px; -} -.studies .top .search .submit::before { - opacity: 0.7; -} -.studies .top .search .submit:hover::before { - opacity: 1; -} -.studies .top .new_study, -.studies .top .orders { - white-space: nowrap; - margin-right: 10px; -} -.studies .top .new_study .button i::before { - color: #759900; - font-size: 40px; -} -.studies .list { - display: flex; - flex-flow: row wrap; - border-top: 1px solid #ccc; -} -.studies .nostudies { - text-align: center; - margin: 40px 0 80px; - font-size: 2em; -} -.studies .nostudies p { - opacity: 0.6; -} -.studies .nostudies i { - display: block; - font-size: 180px; - opacity: 0.4; -} -.studies .nostudies form { - margin-top: 20px; -} -.studies .study { - flex: 0 0 50%; - max-width: 50%; - border-bottom: 1px solid #ccc; - box-sizing: border-box; - padding: 10px 10px 20px 10px; - position: relative; -} -body.dark .studies .top .search input, -body.dark .studies .list, -body.dark .studies .study { - border-color: #3d3d3d; -} -.studies .study { - border-right: 1px solid #ccc; -} -.studies .study:hover { - background: rgba(191, 231, 255, 0.5); -} -.studies .study a.overlay { - position: absolute; - z-index: 2; - top: 0; - left: 0; - width: 100%; - height: 100%; -} -.studies .body { - display: flex; - padding-left: 10px; -} -.studies .study ol.chapters { - flex: 0 0 58%; - max-width: 58%; -} -.studies .study ol.members { - flex: 0 0 40%; - max-width: 40%; - margin-left: 2%; -} -.studies .study ol li { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.studies .study ol li::before { - opacity: 0.5; -} -.studies .study h2 { - display: block; - position: relative; - box-sizing: border-box; - height: 60px; - padding-left: 64px -} -.studies .study h2 strong { - font-size: 1.5em; - font-weight: normal; - color: #3893E8; - display: block; - margin: 11px 0 1px 0; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.studies .study h2 span { - font-size: 1em; - display: block; - opacity: 0.8; -} -.studies .study h2 span i { - opacity: 0.5; -} -.studies h2 .icon { - position: absolute; - top: 0; - left: 15px; -} -.studies h2 .icon::before { - color: #3893E8; - font-size: 38px; - line-height: 45px; - opacity: 0.8; -} -.mselect { - display:inline-block; - position: relative; - padding:0; - border:0; -} -.mselect .button { - padding: 0 10px 0 10px; - display: flex; - align-items: center; - line-height: 40px; -} -.mselect .button i { - margin-left: 5px; - font-size: 10px; -} -.mselect .list { - margin:0; - padding:0; - position:absolute; - z-index: 3; - top:0; - text-align: left; - list-style-type:none; - font-weight: normal; - background: #fff; - box-shadow: 0px 8px 17px 0px rgba(0, 0, 0, 0.2), 0px 6px 20px 0px rgba(0, 0, 0, 0.19); - border-radius: 3px; - display: none; -} -.mselect.shown .list { - display: block; -} -.mselect .list a { - display: block; - padding: 10px; - background:#fff; - transition: 0.13s; - outline:0; - text-decoration:none; - cursor:pointer; -} -.mselect .list a:hover{ - background: #3893E8; - color: #fff; -} -.studies #infscr-loading { - width: 100%; -} diff --git a/public/stylesheets/swag.css b/public/stylesheets/swag.css deleted file mode 100644 index c281da769c..0000000000 --- a/public/stylesheets/swag.css +++ /dev/null @@ -1,38 +0,0 @@ -.side { - margin-top: 20px; - margin-left: -30px; - width: 228px; - box-sizing: border-box; -} -div.side h2 { - font-family: 'PT Serif', 'Noto Sans', 'Lucida Grande'; - font-size: 22px; -} -.side p, -.side ul, -.side ol { - font-size: 1.2em; - margin: 1em 0; -} -.side ul li { - list-style: disc inside; - margin: 0.5em 0; -} -.side a, -.swag a { - color: #3893E8!important; -} -.side a:hover, -.swag a:hover { - text-decoration: underline; -} -.swag .spinner { - margin: 100px auto; -} -.swag .loading { - margin: 100px auto; - text-align: center; -} -#myShop #sprd-main { - z-index: auto; -} diff --git a/public/stylesheets/team.css b/public/stylesheets/team.css deleted file mode 100644 index 551b58a7cd..0000000000 --- a/public/stylesheets/team.css +++ /dev/null @@ -1,154 +0,0 @@ -#team .form3 { - margin-top: 2em; -} -#team form.search { - float: right; - margin: 20px; -} -#team table.slist td { - padding-top: 1em; - padding-bottom: 1em; - overflow-wrap: break-word; - max-width: 674px; -} -#team table.slist a.team-name { - font-size: 1.3em; - display: block; - margin-bottom: 4px; - padding-bottom: 5px; -} -#team table.slist a.team-name span.team-icon { - float: left; - margin-top: 4px; -} -#team table.slist .info { - font-size: 0.9em; - white-space: nowrap; -} -#team .team-content { - overflow: hidden; -} -#team.team_show .lichess_title { - font-size: 1.8em; -} -#team.team_show .lichess_title span { - color: #909090; - font-size: 0.8em; -} -#team.team_show .content_box_top { - padding-bottom: 10px; - border-bottom: 1px solid #ccc; -} -#team.team_show .content_box_top .righty { - float: right; - margin-right: 20px; - line-height: 30px; -} -#team .team-left { - float: left; - width: 280px; - font-size: 1.2em; - border-right: 1px solid #ccc; -} -#team .team-left h2 { - font-size: 1.0em; - font-weight: bold; - padding: 0 0 5px 25px; - border-bottom: 1px solid #ccc; -} -#team .team-left .infos { - margin: 20px 0 20px 25px; -} -#team .team-right { - margin-left: 280px; - border-left: 1px solid #ccc; -} -#team .description { - font-size: 1.2em; - margin: 20px 0 20px 20px; -} -#team .best_players { - margin-bottom: 20px; -} -#team .userlist > li, -#team .userlist > div.paginated { - padding: 5px 0 5px 25px; -} -#team .actions { - margin-left: 20px; -} -#team .forum { - margin-top: 30px; - width: 100%; -} -#team .forum h2 { - font-size: 1.2em; - font-weight: bold; - border-bottom: 1px solid #ccc; - padding: 0 0 5px 20px; -} -#team .forum li { - padding: 20px 10px 20px 20px; -} -#team .forum li:nth-child(odd) { - background: none repeat scroll 0 0 #F4F4F4; -} -#team .forum a.user_link { - font-weight: bold; - margin-right: 6px; - color: #aaa; -} -#team .forum time { - font-size: 0.8em; -} -#team .forum .meta > * { - display: block; - float: left; - margin-right: 1em; -} -#team .forum a.more { - display: block; - text-align: right; - margin: 10px 10px 0 0; -} -#team table.requests form { - margin: 0; -} -#team table.requests { - margin: 0; -} -#team table.requests.all { - margin-bottom: 20px; -} -#team table.requests.for-team { - border-top: 1px solid #ccc; - border-bottom: 1px solid #ccc; -} -#team table.requests th { - padding: 0.5em; - text-align: center; - font-size: 1.4em; -} -#team table.requests.all td { - padding: 2.3em 1em; -} -#team table.requests .user_link { - margin-bottom: 0.7em; -} -#team table.requests .process { - white-space: nowrap; -} -#team table.requests button { - font-size: 0.8em; - display: inline; - margin-left: 5px; -} -#team .button.small { - font-size: 12px; -} -#team .undertitle { - margin-top: 1.5em; -} -#team .kick .button { - margin-bottom: 5px; -} diff --git a/public/stylesheets/timeline.css b/public/stylesheets/timeline.css deleted file mode 100644 index c6251bc1a2..0000000000 --- a/public/stylesheets/timeline.css +++ /dev/null @@ -1,15 +0,0 @@ -#timeline_more td { - padding: 1em 25px; -} -#timeline_more time { - font-size: 0.8em; -} -#timeline_more a { - font-weight: bold; - text-decoration: none; -} -#timeline_more a.user_link { - background: none; - padding-left: 0; - display: inline-block; -} diff --git a/public/stylesheets/tournament.crud.css b/public/stylesheets/tournament.crud.css deleted file mode 100644 index 3bdcc26982..0000000000 --- a/public/stylesheets/tournament.crud.css +++ /dev/null @@ -1,52 +0,0 @@ -h1.lichess_title { - text-align: center; - margin-bottom: 0!important; -} -h1.lichess_title a.new { - float: right; -} -h1.lichess_title span { - display: block; - font-size: 0.35em; - opacity: 0.8; - margin-top: 10px; - text-transform: uppercase; -} -h1.lichess_title a { - color: #ddd!important; -} -.tour_crud.edit h1.lichess_title { - background: #303F9F; - color: #ddd; - letter-spacing: 0.1em; - padding: 30px!important; - font-size: 31px!important; -} -table.slist { - font-size: 1.2em; - width: 100%; -} -table.slist td { - padding: 20px 10px; -} -table.slist time { - display: block; - font-size: 0.8em; - opacity: 0.8; -} -.material.form button { - font-size: 1.7em; - font-weight: normal; - padding: 10px 20px; -} -.material.form textarea { - height: 10em; -} -.tour_crud a { - color: #3893E8!important; -} -.tour_crud h2 { - font-size: 1.5em; - margin: 0px 0 30px 0; - text-align: center; -} diff --git a/public/stylesheets/tournament.css b/public/stylesheets/tournament.css deleted file mode 100644 index f2f5496eb9..0000000000 --- a/public/stylesheets/tournament.css +++ /dev/null @@ -1,1099 +0,0 @@ -div.create_tournament { - position: absolute; - top: 26px; - right: 15px; -} -#tournament .content_box_content.spinner { - padding-top: 200px; - margin: 0 auto 0 auto; -} -#tournament .header { - display: flex; - align-items: center; - height: 70px; -} -#tournament .header img { - flex: 0 0 60px; - display: block; - width: 60px; - height: 60px; - box-sizing: border-box; - padding: 6px; -} -#tournament .header .img { - margin: 0 15px; -} -#tournament .header i::before { - font-size: 30px; - line-height: 60px; - margin: auto; -} -#tournament.weekly .header i::before { - font-size: 35px; -} -#tournament.monthly .header i::before, -#tournament.weekend .header i::before { - font-size: 40px; -} -#tournament.yearly .header i::before { - font-size: 45px; -} -#tournament .header h1 { - flex: 9 1 auto; - padding: 0; - overflow: hidden; -} -#tournament.scheduled .header h1 { - letter-spacing: 2px; -} -#tournament.weekend .header h1, -#tournament.yearly .header h1 { - letter-spacing: 3px; -} -#tournament .header .clock { - flex: 1 1 auto; - margin: 0 15px; - display: flex; - flex-flow: column nowrap; - justify-content: center; - text-align: right; -} -#tournament .header .clock span { - display: block; -} -#tournament.scheduled .header h1, -#tournament.scheduled .header .img, -#tournament table tr.standing.scheduled:first-child td:first-child { - color: #d59120; -} -#tournament .finished .header h1 { - text-align: center; -} -#tournament.marathon .finished .header h1 { - padding-left: 0; -} -#tournament .header .time { - font-family: 'Roboto Mono', 'Roboto'; - font-size: 20px; -} -#tournament .header .shy { - line-height: 20px; - font-size: 0.9em; - font-weight: bold; - text-transform: uppercase; - opacity: 0.6; - white-space: nowrap; -} -#tournament .header .created .time { - font-size: 14px; -} -#tournament.marathon h1 { - color: #4166a0!important; - padding-left: 90px; - letter-spacing: 2px; -} -#tournament.marathon .fire_trophy { - position: absolute; - top: 0; - left: 10px; - width: 70px; - height: 80px; - opacity: 0.7; - transition: 1s; - font-family: "lichess" !important; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} -#tournament.marathon .fire_trophy:hover { - opacity: 1; -} -#tournament.marathon .fire_trophy { - filter: hue-rotate(190deg); -} -#tournament.shield h1 { - padding-left: 90px; - letter-spacing: 2px; -} -#tournament .shield_trophy { - position: absolute; - top: -15px; - left: 10px; - display: block; - width: 67px; - height: 80px; - background: url(../images/trophy/shield-gold.png) no-repeat; - background-size: contain; - font-family: "lichess" !important; - font-size: 40px; - line-height: 80px; - text-align: center; - color: #333!important; - text-shadow: 0 0 6px #fff; -} -#tournament .description { - padding: 20px; -} -#tournament .podium > div { - display: inline-block; - text-align: center; - overflow: hidden; - text-overflow: ellipsis; -} -#tournament .podium .first { - width: 44%; - font-size: 1.6em; -} -#tournament .podium .second { - font-size: 1.3em; - width: 31%; -} -#tournament .podium .third { - font-size: 1.2em; - width: 25%; -} -#tournament .podium .first .trophy { - height: 150px; - width: 195px; - background: url(../images/icons/trophy-1.svg) no-repeat; - background-size: cover; -} -#tournament .podium .second .trophy { - height: 85px; - width: calc(1.1056 * 85px); - background: url(../images/icons/trophy-2.min.svg) no-repeat; -} -#tournament .podium .third .trophy { - height: 65px; - width: calc(1.1056 * 65px); - background: url(../images/icons/trophy-3.min.svg) no-repeat; -} -#tournament .podium .trophy { - margin: 0 auto 8px auto; - background-size: contain!important; -} -#tournament .podium .user_link { - font-weight: bold; - letter-spacing: -1px; -} -#tournament .podium .stats { - margin: 0.5em auto 0 auto; - font-size: 0.7em; -} -#tournament .podium .stats th { - letter-spacing: -1px; -} -#tournament .podium .stats td { - font-weight: bold; - padding-left: 5px; - text-align: right; -} -#tournament .podium .third .stats { - font-size: 0.8em; -} -#tournament div.tournament_show { - width: 525px; - min-height: 480px; -} -#tournament div.big_top { - position: relative; - padding-bottom: 20px; -} -#tournament div.big_top #confetti { - position: absolute; - top: 0; - bottom: 0; - left: 0; - right: 0; - width: 100%; - height: 100%; - pointer-events: none; - opacity: 1; - transition: opacity 25s; -} -#tournament div.big_top #confetti.faded { - opacity: 0; -} -#tournament div.tournament_show div.game_list { - margin: 0 0 0 15px; - padding-top: 20px; - overflow: hidden; -} -#tournament a.pov { - display: block; - margin: 0 25px 1em 25px; - text-align: center; - font-size: 1.5em; - position: relative; - border-radius: 100px; - transition: box-shadow 1.5s; -} -#tournament a.pov span { - display: block; - font-weight: bold; -} -#tournament a.pov::before, -#tournament a.pov::after { - content: 'U'; - font-size: 32px; - position: absolute; - top: 16px; -} -#tournament a.pov::before { - left: 15px; -} -#tournament a.pov::after { - right: 15px; -} -#tournament .controls { - padding: 0 0px; - background: linear-gradient(to bottom, rgba(245, 245, 245, 1) 0%, rgba(240, 240, 240, 1) 100%); - text-shadow: 0 1px 0 #FFF; - color: #848484; - border: 1px solid #d8d8d8; - border-width: 1px 0; - display: flex; - justify-content: space-between; - position: relative; -} -@keyframes delay { - 0% { - width: 0%; - } 100% { - width: 100%; - } -} -#tournament .delay { - background: rgba(117, 153, 0, 0.5); - width: 0%; -} -#tournament .delay button { - opacity: 0.7; - color: #666; - mix-blend-mode: luminosity; -} -body.dark #tournament .delay button { - color: #aaa; -} -#tournament .highlight { - position: absolute; - right: 5px; - top: -3px; - padding: 8px 20px; - border-radius: 8px; - color: #FFF; - text-decoration: none; - background: #82BF56; - border-bottom: 5px solid #759900; - text-shadow: 0 -1px #759900; - transition: all 0.1s; - transform: translate(0px,0px); -} -#tournament .highlight:hover { - filter: brightness(1.06); -} -#tournament .highlight:active { - transform: translate(0px,5px); - border-bottom-width: 1px; - text-shadow: 0 0 #759900; - filter: brightness(1); -} -#tournament .controls .spinner { - margin: 9px 10px 0 0; - width: 20px; - height: 20px; - float: right; -} -#tournament .pager { - user-select: none; - -webkit-user-select: none; - display: flex; - align-items: center; -} -#tournament .pager .page { - margin: 0 3px; -} - -#tournament .pager input { - border: none; - background: transparent; - font-size: 14px; - padding-left: 10px; -} -#tournament .pager .search, -#tournament .pager input, -#tournament .twitter-typeahead { - height: 100%; -} -#tournament .search .tt-menu .spinner { - float: none; - margin: 10px auto; -} - -#tournament .notice { - color: #FFF; - background: #639B24; - text-shadow: 0 -1px #639B24; - text-align: center; - padding: 7px 0; - opacity: 0.7; -} -#tournament .notice.closed { - background: #3893E8; -} -#tournament .notice.wait { - position: relative; - overflow: hidden; -} -@keyframes bar-anim { - 0%{transform:translateX(-1500px);} - 100%{transform:translateX(2500px);} -} -#tournament .notice.wait::after { - content: ''; - position: absolute; - top: 0; - bottom: 0; - left: 0; - width: 70px; - background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.3)); - animation: bar-anim 3s linear infinite; -} - -#tournament table.standing { - width: 525px; - border-bottom: none; -} -#tournament table.standing td.player { - padding-left: 0px; - padding-right: 0px; -} -#tournament table.standing td.player .name { - display:inline-block; - vertical-align: middle; - white-space: nowrap; - padding-right: 5px; - max-width: 140px; - overflow: hidden; - text-overflow: ellipsis; -} -#tournament table.standing .user_link { - white-space: normal; -} -#tournament table.standing .user_link.long { - letter-spacing: -0.7px; -} -#tournament table.standing .user_link .rating { - font-style: italic; - font-size: 0.8em; -} -#tournament table.standing tr.long .user_link .rating { - display: block; - padding-left: 0px; -} -#tournament table.standing tbody tr { - transition: 0.13s; - user-select: none; - -moz-user-select: none; - -webkit-user-select: none; -} -#tournament table.standing.loading tbody { - opacity: 0.6; - transition: opacity 0.3s; -} -#tournament table.standing:not(.created):not(.loading) tbody tr:hover { - background: rgba(191, 231, 255, 0.7); - cursor: pointer; -} -#tournament table.standing tr.me td:first-child { - background: linear-gradient(to right, rgba(99,155,36,0.7) 0px, rgba(99,155,36,0.7) 5px, rgba(0,0,0,0) 5px, rgba(0,0,0,0) 100%); -} -#tournament table.standing tr.active td:last-child { - background: linear-gradient(to left, rgba(56,147,232,0.7) 0px, rgba(56,147,232,0.7) 5px, rgba(0,0,0,0) 5px, rgba(0,0,0,0) 100%); -} -#tournament table.slist td.rank { - font-family: 'Roboto'; - padding: 1em 0.5em 1em 10px; - width: 1px; /* helps keeping it as small as possible */ -} -#tournament table.slist td.rank i { - opacity: 0.4; - font-size: 0.8em; -} -#tournament table.standing .sheet { - text-align: right; - padding-right: 0; - padding-left: 0; - font-family: 'Roboto Mono'; - letter-spacing: 0.1em; -} -#tournament table.standing tr.long .sheet { - font-size: 12px; - letter-spacing: 0.06em; -} -#tournament table.standing tr.xlong .sheet { - font-size: 11px; - letter-spacing: 0.04em; -} -#tournament table.standing .sheet > * { - display: inline-block; -} -#tournament table.standing .sheet score { - opacity: 0.7; -} -#tournament double { - color: #d59120; - /* font-weight: bold; */ -} -#tournament streak { - color: #759900; - /* font-weight: bold; */ -} -#tournament div.standing_wrap td.total { - text-align: right; - font-family: 'Roboto Mono'; - padding-right: 15px; -} -#tournament form.plain td { - padding: 0.6em; - white-space: wrap; -} -#tournament form.plain label { - margin-right: 10px; -} -#tournament form.plain input { - width: 96%; - padding: 0.5% 1%; -} -#tournament form.plain input[name=private] { - width: auto; -} -#tournament form.plain select { - padding: 0.5% 1%; - text-transform: capitalize; - width: 99%; -} -#tournament form.plain .inline select { - width: 46%; -} -#tournament form.plain input.submit { - width: 99%; -} -#tournament form.plain .error { - color: red; -} -#tournament form.plain tr.password { - height: 0; - visibility: hidden; -} -#tournament form.plain tr.password td * { - display: none; -} -#tournament form.plain.private tr.password { - visibility: visible; -} -#tournament form.plain.private tr.password td * { - display: block; -} -#tournament h1 .private { - font-size: 12px; -} -#tournament .join_password { - padding-top: 0; -} -#tournament .join_password h2 { - font-size: 1.5em; -} -#tournament .join_password form { - margin-top: 1em; -} -#tournament .join_password input { - padding: 3px 5px; -} -#tournament .pull-quote { - margin-top: 30px; - width: 300px; -} -.header .setup { - text-transform: uppercase; -} -.header .help { - opacity: 0.6; -} -div.side_box .game_infos.spotlight { - padding-left: 0; -} -div.side_box .game_infos.spotlight a { - text-decoration: underline; -} -.defender::before { - font-size: 1.6em; - vertical-align: -0.26em; - margin: 0 0.15em 0 -0.15em; -} -div.side_box .conditions::before { - opacity: 0.6; -} -div.side_box .accepted { - color: #759900; -} -div.side_box .refused { - color: #dc322f; -} -#tournament_side { - position: relative; - float: right; - width: 252px; - text-align: center; - transition: 0.13s; -} -#tournament_side .featured { - margin-bottom: 10px; - line-height: 0; -} -#tournament_side .featured .vstext { - height: 22px; - line-height: 22px; - border-width: 1px 1px 0 0; - width: 100%; - padding: 0; - text-align: left; -} -#tournament_side .featured .vstext.bottom { - border-width: 0 1px 1px 0; -} -#tournament_side .featured .vstext strong { - display: inline-block; - height: 22px; - width: 12.5%; - text-align: center; - background: #ccc; - margin-right: 10px; -} -#tournament_side .featured .vstext i { - float: right; -} -#tournament_side .featured .vstext i::before { - color: #D85000; - margin: 0 5px 0 0; - line-height: 22px; -} -#tournament_side .box { - border: 1px solid #ccc; -} -#tournament_side .cg-board-wrap { - width: 252px; - height: 252px; -} -#tournament_side .vstext { - width: 240px; -} -#tournament_side .scroll-shadow-soft { - max-height: 400px; - overflow-y: auto; - overflow-x: hidden; -} -#tournament_side .spinner { - width: 70px; - height: 70px; - margin: 30px auto; - opacity: 0.8; -} -#tournament_side .player, -#tournament_side .featured { - box-shadow: 0 .5px 2px rgba(0, 0, 0, 0.15); -} -body.dark #tournament_side .player, -body.dark #tournament_side .featured { - box-shadow: 0 1px 2px #000; -} -#tournament_side .user_link .name { - padding-right: 5px; -} -#tournament_side .player close { - position: absolute; - top: 0px; - right: 3px; - cursor: pointer; - opacity: 0.6; - transition: 0.3s; -} -#tournament_side .player close:hover { - opacity: 1; -} -#tournament_side .stats { - font-size: 1.1em; - background: #fff; - padding: 12px 0; - border-bottom: 1px solid #ccc; -} -#tournament_side h2 { - font-size: 1.1em; - padding-bottom: 0.8em; - border-bottom: 1px solid #d0d0d0; - margin-bottom: 0.8em; -} -#tournament_side table { - margin: auto; -} -#tournament_side .stats td { - font-weight: bold; - padding-left: 10px; - text-align: right; - line-height: 1.8em; -} -#tournament_side .stats td:last-child { - font-family: 'Roboto Mono', 'Roboto'; -} -#tournament_side .player .pairings { - text-align: left; - width: 100%; - box-sizing: border-box; -} -#tournament_side .player .pairings tr { - cursor: pointer; - transition: background-color 0.13s; -} -#tournament_side .player .pairings tr:hover { - background: #fff; -} -#tournament_side .player .pairings tr > * { - padding: 3px 5px; - border-bottom: 1px solid #e0e0e0; -} -#tournament_side .player .pairings th { - padding-left: 7px; - border-left: 3px solid transparent; - border-left-color: #fff; - transition: 0.13s; - font-family: 'Roboto'; - font-weight: 300; -} -#tournament_side .player .pairings span.title { - color: #d59120; - font-weight: bold; -} -#tournament_side .player .pairings tr:hover th { - border-left-color: #888!important; -} -#tournament_side .player .pairings tr.win:hover th { - border-left-color: #759900!important; -} -#tournament_side .player .pairings tr.loss:hover th { - border-left-color: #dc322f!important; -} -#tournament_side .player .pairings td:nth-child(2) { - width: 108px; - max-width: 108px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; -} -#tournament_side .player .pairings td:last-child { - font-weight: bold; - text-align: center; - opacity: 0.8; -} -#tournament_side .player .pairings tr.win td:last-child { - color: #759900; - opacity: 1; -} -#tournament_side .player .pairings tr.loss td:last-child { - color: #dc322f; - opacity: 1; -} -#tournament_side .player .color-icon { - opacity: 0.6; -} -#tournament_side .duels h3 { - text-transform: uppercase; - margin-bottom: 4px; - letter-spacing: 2px; - opacity: 0.8; -} -#tournament_side .duels a { - padding: 0.5em 0.7em; - white-space: nowrap; - border: 1px solid rgba(150,150,150,0.25); - display: flex; - flex-flow: column; - line-height: 1.9em; - border-bottom: none; - background: none; -} -#tournament_side .duels a:first-child { - border-top: none; -} -#tournament_side .duels a:nth-child(even) { - border-left: none; -} -#tournament_side .duels a:nth-child(odd) { - border-right: none; -} -#tournament_side .duels a:hover { - background: rgba(191, 231, 255, 0.7); -} -body.dark #tournament_side .duels a:hover { - background: rgba(27, 51, 68, 0.7); -} -#tournament_side .duels line { - display: flex; - justify-content: space-between; - align-items: center; -} -#tournament_side .duels .white { - text-align: left; -} -#tournament_side .duels .black { - text-align: right; -} -#tournament_side .duels em { - font-style: normal; -} -#tournament_side .duels strong { - font-size: 1.2em; - display: block; - max-width: 60%; - overflow: hidden; - text-overflow: ellipsis; -} -#tournament_side .duels span { -} -#tournament_side .duels .title { - color: #d59120; - font-weight: bold; -} -#tournament_side .duels .rank { - padding: 0.1em 0.5em; - background: rgba(128,128,128,0.5); - color: #fff; - border-radius: 2px; -} -body.dark #tournament_side .duels .rank { - color: #ccc; -} -#tournament_side .duels .b .title, -#tournament_side .duels .b .rank { - margin-right: 0.3em; -} -#tournament_side .duels .a .title, -#tournament_side .duels .a .rank { - margin-left: 0.3em; -} - -#tournament_side win { - color: #33aa33; -} -#tournament_side loss { - color: #aa3333; -} -#tournament_side draw { - color: #999933; -} -#tournament_side em { - font-style: italic; -} -#tournament_side .next { - display: flex; - align-items: center; - margin-bottom: 5px; - padding: 6px; - border-radius: 2px; - opacity: 0.8; - transition: 0.13s; - white-space: nowrap; - overflow: hidden; - color: #fff; - background: #3893E8; - text-align: left; -} -#tournament_side .others { - display: block; - margin-bottom: 15px; - color: #3893E8; -} -#tournament_side .next:hover { - opacity: 1; -} -#tournament_side .next i { - flex: 0 0 50px; - color: #fff; -} -#tournament_side .next i::before { - font-size: 50px; - text-shadow: 1px 1px 3px rgba(0,0,0,0.3); -} -#tournament_side .next span { - display: block; -} -#tournament_side .next .name { - font-size: 1.2em; -} - -#tournament article.faq h2 { - font-weight: bold; - font-style: italic; - margin: 20px 0 10px 0; -} -div.faq_page h1 { - display: block; - margin-bottom: 1em; -} -div.faq_box { - margin-top: 15px; -} -.leaderboard_title { - font-size: 1.5em; - margin-top: 30px; - margin-bottom: 6px; - border-bottom: 1px solid #ccc; -} -.tournament_leaderboard li { - width: 100%; - display: flex; - flex-flow: row nowrap; - justify-content: space-between; - line-height: 2em; - white-space: nowrap; -} -.tournament_leaderboard a.user_link { - margin: 0 5px 0 -3px; - overflow: hidden; - text-overflow: ellipsis; -} -.tournament_leaderboard span { - opacity: 0.7; -} -.tournament_leaderboard li:hover a, -.leaderboard_title:hover a { - color: #3893E8; -} -.scheduled_tournaments a { - padding: 6px 0 6px 35px; - display: block; - position: relative; -} -.scheduled_tournaments strong { - display: block; -} -.scheduled_tournaments a::before { - position: absolute; - top: 8px; - left: 0; - font-size: 30px; - opacity: 0.6; - color: #d59120; -} -.scheduled_tournaments a:hover::before { - opacity: 1; -} - -#tournament_schedule { - min-height: 400px; - position: relative; - -moz-user-select: none; - -webkit-user-select: none; -} -#tournament_schedule .spinner { - width: 120px; - height: 120px; - padding-top: 120px; - opacity: 0.7; -} -#tournament_schedule .schedule { - position: relative; - overflow-x: scroll; - padding-top: 30px; - border-top: 1px solid #d4d4d4; - cursor: move; -} -#tournament_schedule .tournament { - display: flex; - position: absolute; - box-sizing: border-box; - padding: 4px 0; - background-color: #303E43; - box-shadow: 0 5px 15px rgba(0,0,0,0.5); - border-radius: 2px; - transition: filter 0.13s; - color: #fff; - white-space: nowrap; - font-size: 13px; -} -#tournament_schedule .tournament.joinable:hover { - filter: brightness(1.08); -} -#tournament_schedule .timeline { - position: absolute; - top: 0; - height: 100%; -} -#tournament_schedule .tournamentline { - position: relative; - height: 3em; -} -#tournament_schedule .tournamentline.large { - height: 5em; -} -#tournament_schedule .timeheader { - position: absolute; - display: inline; - box-sizing: border-box; - height: 100%; - border-left: 1px dashed #bbb; - padding: 2px 5px; -} -#tournament_schedule .timeheader.hour { - font-weight: bold; - border-left-style: solid; -} -#tournament_schedule .timeheader.now { - top: 1.7em; - height: calc(100% - 1.7em); - margin-left: 1px; - border-left: 2px dashed #d85000!important; -} -#tournament_schedule .tournament.finished { - opacity: 0.7; - box-shadow: 0 0 10px rgba(0,0,0,0.3) inset; -} -#tournament_schedule .tournament.user-created { - background-color: #888; -} -#tournament_schedule .tournament.hourly { - background-color: #3D9333; -} -#tournament_schedule .tournament.daily, -#tournament_schedule .tournament.eastern { - background-color: #0072B2; -} -@keyframes animatedBackground { - from { background-position: 0 0; } - to { background-position: 0 1000%; } -} -#tournament_schedule .tournament.weekly, -#tournament_schedule .tournament.weekend, -#tournament_schedule .tournament.monthly, -#tournament_schedule .tournament.marathon, -#tournament_schedule .tournament.yearly { - text-shadow: 0 0 2px rgba(0,0,0,0.7); - letter-spacing: 1px; - background-image: url(../images/grain.png); - animation: animatedBackground 50s linear infinite; -} -#tournament_schedule .tournament.weekly { - background-color: #D55E00; -} -#tournament_schedule .tournament.monthly { - background-color: #C93D3D; -} -#tournament_schedule .tournament.yearly, -#tournament_schedule .tournament.weekend { - background-color: #d59120; -} -#tournament_schedule .tournament.marathon { - background-color: #66558C; -} -#tournament_schedule .tournament.unique { - background-color: #d59120; -} -#tournament_schedule .tournament.max-rating { - background-color: #8572ff; -} -#tournament_schedule .tournament.short.thematic { - letter-spacing: -1px; -} -#tournament_schedule .tournament span { - margin-right: 4px; -} -#tournament_schedule .icon { - font-size: 1.3em; - margin: -4px 2px -1px 4px; -} -#tournament_schedule .tournament .body { - flex: 1 0; - margin-right: 0; - overflow: hidden; - text-overflow: ellipsis; -} -#tournament_schedule .name { - color: white; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - display: inline-block; - vertical-align: top; - max-width: 66%; -} -#tournament_schedule .infos { - display: inline-flex; -} -#tournament_schedule .infos .text { - flex: 1 1; - overflow: hidden; - text-overflow: ellipsis; -} -#tournament_schedule .infos .nb-players { - flex: 0 0 auto; -} - -#tournament_schedule .large .icon { - font-size: 2.4em; - margin: -6px 4px 0 4px; -} -#tournament_schedule .large .name { - display: block; - max-width: none; -} -#tournament_schedule .large .name { - display: flex; -} - -#tournament_list table.slist { - line-height: 2.3em; -} -#tournament_list table.slist td { - padding-top: 1em; - padding-bottom: 1em; -} -#tournament_list table.slist td.duration { - white-space: nowrap; -} -#tournament_list table.slist .header { - letter-spacing: 2px; - cursor: pointer; - transition: transform 0.3s; - padding: 0!important; -} -#tournament_list table.slist .header:hover { - transform: translateX(3px); -} -#tournament_list table.slist .header a { - padding: 1em; - display: block; -} -#tournament_list table.slist .name { - letter-spacing: 3px; - font-size: 1.7em; - display: block; -} -#tournament_list .icon i { - font-size: 4em; - opacity: 0.6; -} -#tournament_list .scheduled .icon i { - color: #d59120; - opacity: 0.8; -} -#miniGame { - line-height: 0; -} -#miniGame .vstext { - text-align: center; - border: 0; -} -#miniGame .win { - color: #33aa33; -} -#miniGame .loss { - color: #aa3333; -} diff --git a/public/stylesheets/tournament.form.css b/public/stylesheets/tournament.form.css deleted file mode 100644 index 98a83c4978..0000000000 --- a/public/stylesheets/tournament.form.css +++ /dev/null @@ -1,26 +0,0 @@ -#form3-name { - width: 48%!important; - display: inline-block; -} -#tournament form.create .conditions { - margin: 1.5em 0; - border-color: rgba(128,128,128,0.3); -} -#tournament form.create .conditions legend { - text-align: center; -} -#tournament form.create .conditions p { - margin: 20px; -} -#tournament form.create .conditions .form { - display: none; -} -#tournament form.create .conditions.visible { - margin: 0; - padding: 0; - border-left: none; - border-right: none; -} -#tournament form.create .conditions.visible .form { - display: block; -} diff --git a/public/stylesheets/tournament_calendar.css b/public/stylesheets/tournament_calendar.css deleted file mode 100644 index 81f1940514..0000000000 --- a/public/stylesheets/tournament_calendar.css +++ /dev/null @@ -1,127 +0,0 @@ -#tournament_calendar { - -moz-user-select: none; - -webkit-user-select: none; -} -#tournament_calendar group { - width: 100%; - position: relative; - display: flex; - flex-flow: column; - padding-top: 20px; -} -#tournament_calendar days { -} -#tournament_calendar day { - display: flex; - align-items: center; -} -#tournament_calendar day:nth-child(even) { - background: rgba(128,128,128,0.15); -} -#tournament_calendar day date { - flex: 0 0 40px; - margin-left: -40px; -} -#tournament_calendar day lanes { - flex: 1 1 100%; - overflow: hidden; - padding: 5px 0; -} -#tournament_calendar day lane { - display: block; - width: 100%; - height: 25px; - position: relative; -} -#tournament_calendar .tournament { - display: flex; - position: absolute; - top: 0; - box-sizing: border-box; - padding: 4px 0; - background-color: #303E43; - box-shadow: 0 3px 10px rgba(0,0,0,0.5); - border-radius: 2px; - transition: filter 0.13s; - color: #fff; - white-space: nowrap; - font-size: 11px; -} -#tournament_calendar .tournament:hover { - filter: brightness(1.08); -} -#tournament_calendar .tournament.hourly { - background-color: #3D9333; -} -#tournament_calendar .tournament.daily, -#tournament_calendar .tournament.eastern { - background-color: #0072B2; -} -@keyframes animatedBackground { - from { background-position: 0 0; } - to { background-position: 0 1000%; } -} -#tournament_calendar .tournament.weekly, -#tournament_calendar .tournament.weekend, -#tournament_calendar .tournament.monthly, -#tournament_calendar .tournament.marathon, -#tournament_calendar .tournament.yearly { - text-shadow: 0 0 2px rgba(0,0,0,0.7); - letter-spacing: 1px; - background-image: url(../images/grain.png); - animation: animatedBackground 50s linear infinite; -} -#tournament_calendar .tournament.weekly { - background-color: #D55E00; -} -#tournament_calendar .tournament.monthly { - background-color: #C93D3D; -} -#tournament_calendar .tournament.yearly, -#tournament_calendar .tournament.weekend { - background-color: #d59120; -} -#tournament_calendar .tournament.marathon { - background-color: #66558C; -} -#tournament_calendar .tournament.unique { - background-color: #d59120; -} -#tournament_calendar .tournament.max-rating { - background-color: #8572ff; -} -#tournament_calendar .tournament.yesterday { - text-align: right; - padding-right: 5px; -} -#tournament_calendar .tournament span.icon { - font-size: 1.3em; - margin: -4px 1px -1px 3px; -} -#tournament_calendar .tournament .body { - flex: 1 0; - margin-right: 0; - overflow: hidden; -} - -#tournament_calendar .timeline { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - height: 100%; - width: 100%; - border-top: 1px solid rgba(128,128,128,0.3); -} -#tournament_calendar .timeheader { - position: absolute; - display: inline; - box-sizing: border-box; - height: 100%; - border-left: 1px dashed rgba(128,128,128,0.3); - padding: 2px 5px; -} -#tournament_calendar .timeheader:first-child { - border: none; -} diff --git a/public/stylesheets/tournament_leaderboard.css b/public/stylesheets/tournament_leaderboard.css deleted file mode 100644 index 52f305a416..0000000000 --- a/public/stylesheets/tournament_leaderboard.css +++ /dev/null @@ -1,58 +0,0 @@ -.content_box { - position: relative; -} -.content_box h1 { - text-align: center; -} -.tournament_leaderboard .winner_lists { - display: flex; - flex-flow: row wrap; -} -.winner_list { - width: 50%; - flex: 0 0 50%; - padding: 20px 25px 30px 20px; - box-sizing: border-box; - border-bottom: 5px solid transparent; -} -.winner_list:hover { - background: #fafafa; - border-bottom: 5px solid #ddd; -} -.winner_list h2 { - font-size: 2em; - letter-spacing: 5px; - font-family: Roboto; - line-height: 2em; - border-bottom: 1px solid #ddd; - margin-bottom: 10px; -} -.winner_list h2.text::before { - opacity: 0.7; - vertical-align: -5px; - margin-right: 8px; -} -.winner_list li { - width: 100%; - display: flex; - flex-flow: row nowrap; - justify-content: space-between; - line-height: 3.5em; - font-size: 1.2em; -} -.winner_list li:hover a { - color: #3893E8; -} -.winner_list a.user_link { - font-size: 1.2em; - margin: 0 10px 0 -3px; - overflow: hidden; - text-overflow: ellipsis; -} -body.dark .winner_list h2 { - border-color: #404040; -} -body.dark .winner_list:hover { - background: #303030; - border-bottom: 5px solid #505050; -} diff --git a/public/stylesheets/tournament_shields.css b/public/stylesheets/tournament_shields.css deleted file mode 100644 index d4e7e2626e..0000000000 --- a/public/stylesheets/tournament_shields.css +++ /dev/null @@ -1,70 +0,0 @@ -.content_box { - position: relative; -} -.content_box h1 { - text-align: center; -} -.tournament_shields .winner_lists { - display: flex; - flex-flow: row wrap; -} -.winner_list { - width: 50%; - flex: 0 0 50%; - padding: 20px 25px 30px 20px; - box-sizing: border-box; - border-bottom: 5px solid transparent; -} -.winner_list:hover { - background: #fafafa; - border-bottom: 5px solid #ddd; -} -.winner_list h2 { - display: flex; - align-items: center; - font-size: 2em; - letter-spacing: 5px; - font-family: Roboto; - line-height: 2em; - border-bottom: 1px solid #ddd; - margin-bottom: 10px; -} -.winner_list .shield_trophy { - margin: 0 20px -15px 0; - display: block; - width: 67px; - height: 80px; - background: url(../images/trophy/shield-gold.png) no-repeat; - background-size: contain; - font-family: "lichess" !important; - font-size: 40px; - line-height: 80px; - text-align: center; - letter-spacing: normal; - color: #333!important; - text-shadow: 0 0 6px #fff; -} -.winner_list li { - width: 100%; - display: flex; - flex-flow: row nowrap; - justify-content: space-between; - line-height: 3.5em; - font-size: 1.2em; -} -.winner_list li:hover a { - color: #3893E8; -} -.winner_list a.user_link { - font-size: 1.2em; - margin: 0 10px 0 -3px; - overflow: hidden; - text-overflow: ellipsis; -} -body.dark .winner_list h2 { - border-color: #404040; -} -body.dark .winner_list:hover { - background: #303030; - border-bottom: 5px solid #505050; -} diff --git a/public/stylesheets/translation.css b/public/stylesheets/translation.css deleted file mode 100644 index 76d12b17f9..0000000000 --- a/public/stylesheets/translation.css +++ /dev/null @@ -1,93 +0,0 @@ -h2 { - margin-top: 1em; - font-size: 1.5em; -} - -table.translations { - margin-top: 1em; - width: 100%; -} -table.translations th { - font-weight: bold; -} -table.translations td, table.translations th { - padding: 5px 5px 5px 5px; -} -table.translations tbody tr:nth-child(odd) { - background: #f4f4f4; -} -table.translations td.progress { - white-space: nowrap; -} -table.translations .progressbar { - width: 200px; -} - -div.locale_menu { - margin-top: 2em; -} - -.error { - color: red; -} - -.notice { - margin: 1em; - padding: 1em; - text-align: center; - font-size: 1.2em; - border: 1px solid #DADADA; - color: #000; - background: #AAFFAA; -} - -div.messages { - margin-bottom:1em; - padding-bottom: 1em; - max-height: 500px; - overflow: auto; - border: 1px solid #dadada; -} -div.message { - padding:1em; - font-size: 1.2em; - position: relative; -} -div.message:nth-child(odd) { - background: #f4f4f4; -} -div.message label { - display: block; - color: #444; - margin-left: 9%; -} -div.message .context { - margin-left: 9%; - font-size: 0.9em; - margin-top: 5px; -} -div.message input { - width: 90%; - margin-left: 9%; - margin-top: 3px; - padding: 3px 5px; - border: 1px solid #dadada; -} -div.message .number { - position: absolute; - top: 25px; - left: 10px; -} - -div.optional { - margin-bottom: 1em; -} -div.optional input { - padding: 3px 5px; - border: 1px solid #dadada; -} - -input.submit { - padding: 5px 10px; - font-size: 1.3em; -} diff --git a/public/stylesheets/transp.css b/public/stylesheets/transp.css deleted file mode 100644 index 3e38132204..0000000000 --- a/public/stylesheets/transp.css +++ /dev/null @@ -1,192 +0,0 @@ -body.transp { - background-color: #181818; - color: #ddd; -} -body.transp a, -body.transp a:visited, -body.transp #powerTip > .actions a, -body.transp .button, -body.transp #video .content_box_top form input, -body.transp input, -body.transp button, -body.transp textarea, -body.transp div.analysis_menu > a.active, -body.transp div.chat_menu > a, -body.transp div.current_player div.player p, -body.transp div.vstext, -body.transp .tview2 move, -body.transp #lichess_forum div.post .message, -body.transp #lichess_blog { - color: #ccc; -} -body.transp::before { - content: ' '; - position: fixed; - width: 100%; - height: 100%; - top: 0; - left: 0; - background-position: center center; - background-repeat: no-repeat; - background-size: cover; - will-change: transform; - z-index: -1; -} -body.transp #timeline, -body.dark .areplay, -body.transp div.training .box, -body.transp div.side_box, -body.transp div.box, -body.transp div.table, -body.transp div.table_wrap > div.clock > div.time, -body.transp #friend_box .content a:hover, -body.transp div.undertable_inner, -body.transp div.chat_menu > a.active, -body.transp #hooks_wrap, -body.transp #hooks_wrap div.tabs a:hover, -body.transp #hooks_wrap div.tabs a.active, -body.transp #tournament_schedule, -body.transp #friend_box, -body.transp .analysis_panels > div, -body.transp .button:hover, -body.transp a.button:hover, -body.transp #topmenu section:hover > a, -body.transp #topmenu div, -body.transp #start_buttons a, -body.transp .analyse div.ceval_box, -body.transp .analyse .lichess_ground .replay, -body.transp .analyse .lichess_ground .explorer_box, -body.transp .lichess_ground .opening_box, -body.transp .lichess_ground .replay index, -body.transp .lichess_ground .analyse .meta, -body.transp .lichess_ground .replay move:hover, -body.transp .lichess_ground .replay td.move:hover, -body.transp #top .dropdown, -body.transp #top .shown a.toggle, -body.transp div.analysis_menu > a, -body.transp div.content_box, -body.transp div.content_box_inter a.active, -body.transp #site_header div.side_menu a.active, -body.transp #tournament_side, -body.transp table.translations tbody tr, -body.transp form.translation_form div.message, -body.transp #video_side .tag_list a.checked, -body.transp #powerTip, -body.transp .study_comment_form .material.form .form-group textarea, -body.transp .chapter_desc, -body.transp div.vstext, -body.transp .action_menu { - background: rgba(0, 0, 0, 0.6); -} -body.transp #board_editor, -body.transp #video .content_box_top form input, -body.transp input, -body.transp textarea, -body.transp div.analysis_menu > a.active, -body.transp div.chat_menu > a, -body.transp div.mselect > div.list > a, -body.transp #opening .meter, -body.transp div.game_row:nth-child(odd), -body.transp #lichess_forum table.forum_table tr:nth-child(odd), -body.transp #lichess_message tr:nth-child(even), -body.transp table.slist tbody tr:nth-child(even), -body.transp #team .forum li:nth-child(odd), -body.transp table.translations tbody tr:nth-child(odd), -body.transp form.translation_form div.message:nth-child(even), -body.transp div.content_box table.datatable tr:nth-child(odd), -body.transp div.search_status { - background: rgba(0, 0, 0, 0.3); -} -body.transp div.mselect > div.list > a:first-child { - background: #333; -} -body.transp #lichess_forum table.forum_table thead tr:nth-child(odd), -body.transp #chat .messages, -body.transp #tournament_schedule, -body.transp div.mselect div.list { - background: none; -} -body.transp div.user_show .trophy.icon3d, -body.transp #timeline a, -body.transp #chat span, -body.transp #chat a.user_link, -body.transp div.undertable a.user_link, -body.transp #team .forum a.user_link, -body.transp div.user_show div.content_box_top > span, -body.transp span.progress > .zero, -body.transp div.undertable_top span.title { - color: #b0b0b0; -} -body.transp #start_buttons a { - transition: 0.13s; - box-shadow: 0 0 9px rgba(255, 255, 255, 0.4); -} -body.transp #start_buttons a:hover { - background: rgba(20, 20, 20, 0.6); -} -body.transp #top a.toggle, -body.transp #tv_channels, -body.transp #video_side, -body.transp #video_side a, -body.transp .side div.user_lists, -body.transp .side div.user_lists a, -body.transp #puzzle .right .retry, -body.transp #trainer .explanation, -body.transp .tournament_home_side, -body.transp .tournament_home_side a, -body.transp #site_header .help, -body.transp #site_header .side_menu, -body.transp .advice_summary, -body.transp .advice_summary a, -body.transp #topmenu section > a, -body.transp .under_chat, -body.transp #now_playing h3, -body.transp div.sub_ratings, -body.transp div.sub_ratings span, -body.transp .cemetery score, -body.transp #site_title, -body.transp #site_header .baseline, -body.transp #streams_on_air a.stream span { - color: #f0f0f0; - text-shadow: 0 0 2px #000, 0 0 5px #000; -} -body.transp .crosstable th.score, -body.transp .crosstable td, -body.transp #chat div.top, -body.transp div.side_box .top, -body.transp div.box .top, -body.transp div.undertable_top, -body.transp .button, -body.transp .button:visited, -body.transp #notifications > div, -body.transp div.vstext, -body.transp div.user_show div.content_box_inter.tabs, -body.transp #qa .answers-header, -body.transp #video .card .info, -body.transp #video .card .reveal, -body.transp table.slist thead { - background: linear-gradient(to bottom, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.7) 100%); -} -body.transp #timeline { - padding-left: 7px; - box-sizing: border-box; -} -body.transp div.lichess_board, -body.transp div.lichess_overboard, -body.transp div.content_box, -body.transp #powerTip { - box-shadow: 0 0 9px rgba(255, 255, 255, 0.5); -} -body.transp #site_title { - opacity: 0.9; -} -body.transp ::-webkit-scrollbar, -body.transp ::-webkit-scrollbar-corner { - background: rgba(0, 0, 0, 0.1); -} -body.transp .action_menu .setting { - margin-right: 10px; -} -body.transp #analyse-cm { - color: #888; -} diff --git a/public/stylesheets/tv.css b/public/stylesheets/tv.css deleted file mode 100644 index 67bcef4c2d..0000000000 --- a/public/stylesheets/tv.css +++ /dev/null @@ -1,93 +0,0 @@ -#tv_channels { - margin: 15px 4px 0 0; -} -#tv_channels > a { - display: block; - text-align: right; - transition: 0.13s; - padding: 6px 5px 5px 5px; - line-height: 1.1em; - border-radius: 25px 0 0 25px; - border-left: 2px solid transparent; - border-bottom: 2px solid transparent; -} -#tv_channels > a:hover { - background: #fafafa; - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3); -} -#tv_channels > a.active { - background: #C4A86F!important; - color: #fff!important; - border-color: rgba(0, 0, 0, 0.3); - text-shadow: 0 1px 0 rgba(0, 0, 0, 0.2); -} -#tv_channels > a::before { - color: #C4A86F; - font-size: 27px; - float: right; - margin: -1px 0 0 8px; - opacity: 0.5; -} -#tv_channels > a.active::before { - color: #fff; - opacity: 1; -} -#tv_channels > a:hover::before { - opacity: 1; -} -#tv_channels > a strong { - display: block; - text-transform: uppercase; -} -#tv_channels > a span { - font-size: 0.9em; - white-space: nowrap; - display: block; -} -#tv_channels table { - width: 100%; -} -#tv_channels a.user_link { - font-weight: bold; - color: #a0a0a0; -} -#tv_channels a.icon { - font-size: 26px; - padding-left: 10px; - opacity: 0.7; - transition: opacity 0.3s; -} -#tv_channels tr:hover a.icon { - opacity: 1; -} -#tv_channels td { - padding: 4px 0; - border-top: 1px solid #eaeaea; - transition: background 0.13s; -} -#tv_channels tr:first-child td { - border-top: none; -} -#tv_channels tr:hover td { - background-color: #f8f8f8; -} - -.tv_stream iframe { - border: none; -} - -div.game_list.playing.tv_history { - width: 512px; - margin-top: 5px; - display: flex; - flex-flow: row wrap; - justify-content: space-around; -} -.tv_history h2 { - font-size: 1.3em; - text-transform: uppercase; - margin-bottom: 10px; - font-family: 'Roboto'; - flex: 0 0 100%; - text-align: center; -} diff --git a/public/stylesheets/user-list.css b/public/stylesheets/user-list.css deleted file mode 100644 index afc9272d28..0000000000 --- a/public/stylesheets/user-list.css +++ /dev/null @@ -1,95 +0,0 @@ -.community.content_box { - position: relative; -} -.com_tabs { - position: absolute; - top: -23px; - left: -1px; - height: 23px; - line-height: 22px; - display: flex; - justify-content: flex-end; -} -.com_tabs a { - padding: 0 8px; - margin-right: 3px; - border: 1px solid #ccc; - background: #f0f0f0; - transition: 0.13s; -} -.com_tabs a:hover { - background: #fff; -} -.com_tabs a.active { - background: #fff; - font-weight: bold; - border-bottom-color: #fff; - border-top: 2px solid #d85000!important; - margin-top: -1px; -} -body.dark .com_tabs a { - background: #393939; - border-color: #3d3d3d; -} -body.dark .com_tabs a:hover, -body.dark .com_tabs a.active { - background: #2b2b2b; -} -body.dark .com_tabs a.active { - border-bottom-color: #2b2b2b; -} -div.user_lists h2 { - font-size: 1.1em; - font-weight: bold; - line-height: 1.5em; - margin-bottom: 0.5em; -} -div.user_lists h2::before { - font-size: 1.5em; -} -#lichess div.user_lists { - overflow: hidden; - width: 100%; - display: flex; - flex-flow: row wrap; - justify-content: space-between; -} -#lichess div.user_lists div.user_top { - flex: 0 0 31%; - width: 31%; - margin-bottom: 2em; -} -div.side div.user_top { - margin-top: 1em; -} -div.side div.user_top li { - display: block; - margin: 5px 0; -} -div.side a.more { - display: block; - text-align: right; - margin-top: 0.5em; -} -div.user_lists div.user_top > div { - width: 100%; - display: flex; - justify-content: space-between; -} -div.user_lists div.user_top div div { - line-height: 22px; - white-space: nowrap; -} -div.user_lists div.user_top .user_link { - overflow: hidden; - text-overflow: ellipsis; -} -#site_header div.user_lists .user_link { - max-width: 160px; -} - -div.big_user_list > a { - float: left; - width: 25%; - margin-bottom: 5px; -} diff --git a/public/stylesheets/user-perf-stat.css b/public/stylesheets/user-perf-stat.css deleted file mode 100644 index 0ec4bba313..0000000000 --- a/public/stylesheets/user-perf-stat.css +++ /dev/null @@ -1,150 +0,0 @@ -#perfStat .content_box_top { - padding-bottom: 10px; - border-bottom: 1px solid #ccc; -} -#perfStat .content_box_content { - min-height: 600px; -} -#perfStat .lichess_title { - font-size: 1.8em; -} -#perfStat .lichess_title span { - color: #909090; - font-size: 0.8em; - text-transform: uppercase; - margin-left: 10px; -} -#perfStat div.content_box_top > .view_games { - float: right; - font-size: 14px; - margin-right: 10px; -} -#perfStat div.content_box_top > .trophy { - float: right; - margin-top: -47px; - margin-right: 10px; -} -#perfStat h2 { - font-size: 1.5em; - text-transform: uppercase; - font-family: 'Roboto'; - font-weight: 300; -} -#perfStat h2 .details { - text-transform: none; -} -#perfStat h3 { - font-size: 1.4em; - margin: 5px 0; -} -#perfStat p { - margin-top: 20px; -} -#perfStat time { - display: inline; -} -#perfStat green { - color: #759900; -} -#perfStat red { - color: #dc322f; -} -#perfStat .content_box_content a { - color: #3893E8; -} -#perfStat .content_box_content a:hover { - text-decoration: underline; -} -#perfStat .content_box_content [title] { - border-bottom: 1px dashed #3893E8; - cursor: help; -} -#perfStat section { - margin-top: 50px; -} -#perfStat section:first-child { - margin-top: 20px; -} -#perfStat .half { - width: calc(50% - 30px); - display: inline-block; -} -#perfStat .half:first-child { - margin-right: 60px; -} -#perfStat table { - margin-top: -15px; - width: 100%; -} -#perfStat .glicko p { - font-size: 1.2em; -} -#perfStat .counter table { - font-size: 1.2em; -} -#perfStat .counter th { - text-indent: 20px; -} -#perfStat .counter td { - text-align: right; - padding: 12px 20px; - font-weight: bold; - font-size: 1.2em; -} -#perfStat .counter tr.full td:last-child { - background: #f6f6f6; -} -#perfStat .counter tr { - border-bottom: 1px solid #eee; -} -#perfStat .counter tr:first-child { - border-bottom: 1px solid #ccc; -} -#perfStat .highlow a, -#perfStat .highlow span { - font-size: 1.2em; - text-indent: 20px; - display: inline-block; -} -#perfStat .result tbody { - font-size: 1.2em; -} -#perfStat .result th, -#perfStat .result td { - padding: 10px 0; -} -#perfStat .result td:first-child { - text-indent: 20px; - white-space: nowrap; -} -#perfStat .result td:last-child { - text-align: right; - font-size: 0.8em; -} -#perfStat .result tr { - border-bottom: 1px solid #eee; -} -#perfStat .result thead tr { - border-bottom: 1px solid #ccc; -} -#perfStat .resultStreak .streak, -#perfStat .playStreak .streak { - margin: 10px 0 10px 20px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -#perfStat .playStreak { - white-space: nowrap; -} -#perfStat .rating_history { - left: -10px; - display: block; - width: 100%; - height: 339px; -} -#perfStat .rating_history .spinner { - width: 90px; - height: 90px; - margin: 120px auto 0 auto; -} \ No newline at end of file diff --git a/public/stylesheets/user-show.css b/public/stylesheets/user-show.css deleted file mode 100644 index 7312db0c2a..0000000000 --- a/public/stylesheets/user-show.css +++ /dev/null @@ -1,554 +0,0 @@ -.user_show .content_box_top { - display: flex; - padding-left: 5px; -} -.user_show .content_box_top h1 { - margin: 0; -} -.user_show .content_box_top .connected { - color: #759900; -} -#lichess .user_show .closed { - color: #aa3333; - font-weight: bold; - margin-right: 1em; -} -.user_show .content_box_top > span { - margin-left: 10px; -} -.user_show .trophies { - margin-top: -47px; - flex: 1 1 100%; - display: flex; - flex-flow: row nowrap; - align-items: flex-end; - justify-content: flex-end; -} -.user_show .trophy.award { - font-family: "lichess" !important; - speak: none; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - line-height: 100%; - height: 60px; - margin-top: 20px; -} -.user_show .trophy { - height: 80px; -} -.user_show .stacked { - display: flex; -} -.user_show .stacked .trophy { - width: 65px; - height: 65px; - font-size: 65px; - margin-top: 15px; -} -.user_show .fire_trophy { - opacity: 0.9; - transition: 0.8s; - height: 80px; - position: relative; -} -.user_show .fire_trophy:hover { - opacity: 1; -} -.user_show .fire_trophy.marathonWinner, -.user_show .fire_trophy.marathonTopTen, -.user_show .fire_trophy.marathonTopFifty, -.user_show .fire_trophy.marathonTopHundred { - filter: hue-rotate(190deg); -} -.user_show .fire_trophy.marathonTopTen { - font-size: 58px; - width: 58px; - height: 58px; - margin-top: 22px; -} -.user_show .fire_trophy.marathonTopFifty, -.user_show .fire_trophy.marathonTopHundred { - font-size: 50px; - height: 50px; - width: 50px; - margin-top: 30px; - animation: none; -} -.user_show .fire_trophy.marathonTopFifty { - text-shadow: 0 0 5px #ffae34, 0 0 6.25px #ec760c, 0 0 7.5px #cd4606; -} -.user_show .fire_trophy.marathonTopHundred { - text-shadow: none; - color: #cd4606!important; -} -.user_show .fire_trophy.bongcloudWarrior { - filter: hue-rotate(70deg); -} -.user_show .packed .trophy { - margin-right: -8px; -} -.user_show .packed .stacked { - margin-right: 30px; -} -.user_show .packed .stacked .trophy { - margin-right: -30px; -} -.user_show .trophy.icon3d { - width: 40px; - height: 40px; - margin-right: 5px; - vertical-align: middle; - font-size: 39px; - color: #ccc; - text-shadow: 0 1px 0 rgba(0,0,0,0.5); - transition: 0.3s; -} -.user_show .trophy.icon3d:not(.patron):hover { - transform: translateY(-3px); -} -.user_show .trophy.streaming { - color: #d59120!important; - animation: fire 1.25s ease-in-out infinite alternate; -} -.user_show .trophy.patron { - font-size: 60px; - margin: -30px 10px 0 25px!important; - transform: scale(-1, 1); - color: #d59120!important; - transition: 0.5s; -} -.user_show .trophy.patron:hover { - margin-top: -34px!important; - animation: fire 1.25s ease-in-out infinite alternate; -} -.user_show .trophy.patron.hint--left:after { - transform: scale(-1, 1); - margin: 0; -} -.user_show .trophy.patron.hint--left:after { - right: -330%; -} -.user_show .trophy.patron.hint--left:hover:after { - transform: scale(-1, 1), translateX(8px); -} -.user_show .combo_trophy { - width: 60px; - height: 60px; - background-size: contain; - font-family: "lichess" !important; - text-align: center; -} -.user_show .shield_trophy { - width: 50px; - background-image: url(../images/trophy/shield-gold.png); - font-size: 30px; - line-height: 60px; - color: #333!important; - text-shadow: 0 0 6px #fff; -} -.user_show .revol_trophy { - background-image: url(../images/trophy/round-star.png); - font-size: 24px; - line-height: 68px; - color: #fff!important; - text-shadow: 0 0 4px #444; -} - -.user_show .honorific { - display: inline-block; - margin-top: 1em; - font-weight: bold; - font-size: 1.4em; -} -.user_show .social { - border-top: 0; - padding: 0 0 5px 10px; - height: 52px; - align-items: center; - justify-content: space-between; -} -.user_show .social .links { - display: flex; -} -.user_show .user_actions { - font-size: 1.2em; - margin: 4px 15px 0 0; -} -.user_show .user_actions form { - display: inline; -} -.user_show .relation_actions { - display: inline; -} -#us_profile { - height: 325px; - position: relative; -} -div.engine_warning { - margin: 10px 0; -} -div.sub_ratings { - margin-top: 10px; - margin-left: -13px; - width: 224px; -} -div.sub_ratings > a { - position: relative; - padding: 10px 0 10px 5px; - white-space: nowrap; - display: block; - transition: 0.13s; - cursor: default; -} -div.sub_ratings > a.empty { - opacity: 0.5; -} -div.sub_ratings > a.game { - cursor: pointer; -} -div.sub_ratings > a::before { - font-size: 40px; - float: left; - margin: -2px 5px 0 0; - opacity: 0.6; -} -div.sub_ratings > a.game:hover { - background: #fafafa; - margin-left: -3px; -} -div.sub_ratings > a.game.active { - background: #fff; - border: 1px solid #ccc; - border-right: 0; - margin-left: -10px; -} -div.sub_ratings > a > span { - display: block; -} -div.sub_ratings > a > i { - position: absolute; - top: calc(50% - 6px); - right: 12px; - font-size: 8px; - opacity: 0.2; -} -div.sub_ratings > a:hover > i { - opacity: 0.6; -} -div.sub_ratings > a.active > i { - display: none; -} -div.sub_ratings > a .shy { - font-size: 0.8em; - opacity: 0.6; - line-height: 1em; -} -div.sub_ratings h3 { - font-weight: 100; - font-size: 1em; - letter-spacing: 2px; - margin: 0; - display: inline-block; -} -#site_header div.sub_ratings strong { - font-weight: bold; - font-size: 1.2em; -} -.user_show .rating_history { - position: absolute; - left: -10px; - display: block; - width: 477px; - height: 339px; -} -.user_show .rating_history .spinner { - width: 90px; - height: 90px; - margin: 120px auto 0 auto; -} -.user_show .user-infos { - position: absolute; - top: 0; - left: 458px; - padding: 0 14px; - border-left: 1px solid #c0c0c0; - overflow: hidden; - width: 305px; - height: 325px; -} -.user_show .with_insights .user-infos { - height: 265px; -} -.user_show .user-infos:hover { - overflow-y: auto; -} -.user_show .insight { - position: absolute; - bottom: 0; - right: 0; - padding: 0 14px; - width: 305px; - height: 60px; - border-top: 1px solid #c0c0c0; - border-left: 1px solid #c0c0c0; -} -.user_show .insight .icon { - position: absolute; - top: 0; - right: 10px; -} -.user_show .insight .icon::before { - color: #3893E8; - font-size: 40px; - line-height: 60px; - opacity: 0.8; -} -.user_show .insight strong { - color: #3893E8; - display: block; - font-weight: normal; - font-size: 1.5em; - margin: 10px 0 1px 0; -} -.user_show .insight em { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - display: block; - width: 275px; -} -.user_show .insight:hover { - background: #3893E8; -} -.user_show .insight:hover, -.user_show .insight:hover *, -.user_show .insight:hover .icon::before { - transition: 0.13s; - color: #fff; -} - -.user_show .name, -.user_show .bio, -.user_show .stats, -.user_show .tournament_points, -.user_show .social_links, -.user_show .teams { - display: block; - margin-top: 16px; -} -.user_show .col2 { - display: flex; - flex-flow: row wrap; - line-height: 1.7em; -} -.user_show .col2 > a { - flex: 0 0 50%; - color: #3893E8!important; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} -.user_show .teams { - margin-bottom: 10px; -} -.user_show .bio { - font-style: italic; -} -.user_show div.games { - padding-top: 10px; -} -.user_show div.games.center { - text-align: center; -} -.user_show .profile { - margin-bottom: 1em; -} -.user_show .claim_title_zone { - padding: 30px; - font-size: 1.2em; - line-height: 1.5em; -} -.user_show .claim_title_zone h2 { - font-size: 1.5em; -} -.user_show .claim_title_zone p { - margin: 2em 0; -} -.user_show .claim_title_zone .actions { - margin: 3em 0; - text-align: center; -} -.user_show .note_zone { - display: none; - margin: 1em 20px; - padding-bottom: 1em; - border-bottom: 1px solid #ccc; -} -.user_show .note_zone textarea { - width: 98%; - margin-bottom: 5px; - padding: 5px 8px; - height: 5em; - resize: vertical; -} -.user_show .note_zone div { - padding-top: 1em; - border-top: 1px dotted #ccc; - margin-top: 1em; -} -.user_show .note_zone p.meta { - float: right; - text-align: right; - margin-left: 1em; - white-space: nowrap; -} -.user_show .note_zone p.text { - min-height: 2.7em; -} -.user_show .note_zone p.text a { - color: #3893E8; -} -.user_show div.content_box_inter.tabs { - margin-left: -8px; - padding-left: 30px; - width: 775px; - border: 1px solid #ccc; -} -div.crosstable { - margin: 25px 10px 15px 10px; -} -.user_show .results .aggregate { - font-weight: bold; - font-size: 1.4em; - text-align: center; - margin-left: -20px; - width: 50px; - transform: rotate(90deg); -} - -.user_show .search { - white-space: nowrap; - margin: 10px 0; -} -.user_show .search table { - display: inline-block; - box-sizing: border-box; - margin-left: 20px; - width: 360px; -} -.user_show .search table tbody { - display: block; -} -.user_show .search table:first-child { - width: 400px; -} -.user_show .search .header { - font-size: 1.3em; -} -.user_show .search td { - padding: 5px 0; -} -.user_show .search label { - margin-right: 10px; -} -.user_show .search .single select { - width: 100%; -} -.user_show .search table .half { - float: left; - width: 49%; - padding-right: 1%; - text-align: right; -} -.user_show .search_status { - text-align: right; - padding: 10px 25px; - border-bottom: 1px solid #e4e4e4; -} -.user_show .new_player { - padding: 20px; -} -.user_show .new_player h2 { - font-size: 1.4em; -} -.user_show .new_player p { - margin: 1em 0; -} -.user_show .new_player li { - list-style: disc inside; - line-height: 1.5em; -} -.user_show .new_player a { - color: #3893E8; -} -div.content_box_inter { - display: flex!important; -} -div.content_box_inter .intertab { - flex: 1 1 auto; - text-align: center; - line-height: 1.4em; - margin-top: 5px; - padding: 0.5em 5px; - text-transform: capitalize; - border: 1px solid transparent; - font-family: 'Roboto'; - font-weight: 300; - white-space: normal; -} -div.content_box_inter.tabs .intertab { - margin-top: 7px; - border-bottom: none; - padding-bottom: 0.8em; -} -div.content_box_inter .intertab:hover { - background: #efefef; -} -div.content_box_inter.angles .intertab:hover { - background: #f9f9f9; -} -div.content_box_inter .intertab strong { - font-family: 'Noto Sans'; - font-weight: normal; - font-size: 1.1em; -} -div.content_box_inter a.intertab.active { - margin-bottom: -1px; - background: #fff!important; -} -div#games.content_box_inter { - border-top: none; -} -div.content_box_inter a.to_games.active, -div#games.content_box_inter { - background: #e8e8e8!important; -} -div.content_box_inter.angles .intertab { - font-size: 1.2em; - padding: 0.9em 5px; -} -div.content_box_inter .intertab.active { - border: 1px solid #ccc; - border-bottom: none; -} -div.content_box_inter .to_games .unread { - opacity: 0.7; - padding: 0 5px; -} -div.content_box_inter .to_playing { - color: #d85000!important; -} -div.content_box_inter .to_playing strong { - font-weight: bold; -} - -body.dark div.content_box_inter .intertab:hover { - background: #2d2d2d; -} -body.dark div.content_box_inter a.intertab.active { - background: #2b2b2b!important; -} -body.dark div.content_box_inter a.to_games.active, -body.dark div#games.content_box_inter { - background: #353535!important; -} diff --git a/public/stylesheets/user-signup.css b/public/stylesheets/user-signup.css deleted file mode 100644 index b9cb2b8c32..0000000000 --- a/public/stylesheets/user-signup.css +++ /dev/null @@ -1,77 +0,0 @@ -div.content_box { - width: 232px; - padding-bottom: 10px; - position: relative; -} - -div.signup_box .explanation { - font-size: 1.2em; - margin-bottom: 2em; -} - -div.signup_box .lichess_title { - margin-bottom: 1em; -} - -div.content_box.login div.alternative { - display: block; - position: absolute; - top: 2em; - left: 312px; - width: 300px; -} -div.content_box.signup div.alternative { - float: right; -} - -div.alternative a { - color: #3893E8; -} - -.email_confirm p { - margin: 1em 0; -} - -.email_confirm h2 { - font-size: 1.5em; - margin-top: 2em; -} -.email_confirm h3 { - font-size: 1.3em; - display: inline; -} - -.email_confirm ol { - font-size: 1.1em; -} -@keyframes appear { - from { opacity: 0; } - 30% { transform: translateY(0); } - to { opacity: 1; transform: translateY(0); } -} -.email_confirm ol li { - margin: 2em 0; - list-style: decimal inside; -} -.email_confirm.anim h2, -.email_confirm.anim ol li { - opacity: 0; - transform: translateY(100px); - animation: appear 3s forwards; - animation-delay: 2s; -} -.email_confirm.anim ol li:nth-child(2) { - animation-delay: 6s; -} -.email_confirm.anim ol li:nth-child(3) { - animation-delay: 10s; -} -.email_confirm.anim ol li:nth-child(4) { - animation-delay: 14s; -} -.email_confirm.anim ol li:nth-child(5) { - animation-delay: 18s; -} -#email_confirm a { - display: none; -} diff --git a/public/stylesheets/user-tournaments.css b/public/stylesheets/user-tournaments.css deleted file mode 100644 index f182b9c968..0000000000 --- a/public/stylesheets/user-tournaments.css +++ /dev/null @@ -1,73 +0,0 @@ -#tournament_list table.slist { - line-height: 2.3em; - white-space: nowrap; -} -#tournament_list table.slist h1 { - padding: 0; - line-height: 72px; -} -#tournament_list table.slist .count { - vertical-align: center; - color: #d59120; - font-size: 40px; - font-family: 'Roboto'; - font-weight: 300; - text-align: center; - line-height: 72px; - width: 80px; -} -#tournament_list table.slist td { - padding-top: 1em; - padding-bottom: 1em; -} -#tournament_list table.slist td.icon { - text-align: center; -} -#tournament_list table.slist .header { - letter-spacing: 2px; - cursor: pointer; - transition: transform 0.3s; - padding: 0!important; - max-width: 400px; - overflow: hidden; - text-overflow: ellipsis; -} -#tournament_list table.slist .header:hover { - transform: translateX(3px); -} -#tournament_list table.slist .header a { - padding: 1em; - display: block; -} -#tournament_list table.slist .name { - letter-spacing: 3px; - font-size: 1.7em; - display: block; -} -#tournament_list table.slist .games, -#tournament_list table.slist .score, -#tournament_list table.slist .rank { - font-size: 1.2em; -} -#tournament_list .icon span { - font-size: 4em; - opacity: 0.7; -} -#tournament_list .scheduled .icon span { - color: #d59120; - opacity: 0.8; -} - -.stats p { - padding: 0 20px 20px 20px; -} -.stats table.perf_results { - height: 300px; -} -.stats table.perf_results thead th, -.stats table.perf_results td { - text-align: right; -} -.stats table.perf_results th span::before { - font-size: 2em; -} diff --git a/public/stylesheets/variant.css b/public/stylesheets/variant.css deleted file mode 100644 index fc6698dfc7..0000000000 --- a/public/stylesheets/variant.css +++ /dev/null @@ -1,45 +0,0 @@ -div.doc_box h2.headline { - font-size: 1.2em; - font-style: italic; - margin-bottom: 30px; -} -div.doc_box div[data-oembed] { - text-align: center; -} -div.doc_box .body.content_box_content { - padding-top: 0; -} -div.doc_box .variants { - margin-top: 0px; -} -div.doc_box a.variant { - text-decoration: none!important; - display: block; - height: 50px; - padding: 10px 20px; - transition: background 0.13s; -} -div.doc_box a.variant:hover { - background: rgba(191, 231, 255, 0.5); -} -div.doc_box a.variant::before { - float: left; - font-size: 40px; - line-height: 50px; - margin-right: 20px; - opacity: 0.7; - transition: opacity 0.13s; -} -div.doc_box a.variant:hover::before { - opacity: 1; -} -div.doc_box a.variant h2 { - font-size: 1.5em; - font-family: 'Roboto'; - font-weight: 300; - text-transform: uppercase; - letter-spacing: 3px; -} -div.doc_box a.variant h3 { - margin: 0; -} diff --git a/public/stylesheets/video.css b/public/stylesheets/video.css deleted file mode 100644 index 7cbeabd1a6..0000000000 --- a/public/stylesheets/video.css +++ /dev/null @@ -1,238 +0,0 @@ -#video { - min-height: 823px; -} -#video .content_box_top { - padding-bottom: 10px; - border-bottom: 1px solid #ccc; -} -#video .content_box_top form { - float: right; - position: relative; -} -#video .content_box_top form span { - position: absolute; - left: 10px; - top: 4px; - font-size: 1.4em; - opacity: 0.6; -} -#video .content_box_top form input { - font-size: 1.2em; - border: none; - -webkit-appearance: none; - line-height: 54px; - padding: 0 15px; - background: none; - outline: none; - margin-top: -10px; - background: #fff; - text-indent: 23px; -} -#video .content_box_top .lichess_title { - display: inline; -} -#video .list { - overflow: hidden; - padding: 8px 0 8px 8px; -} -#video .card { - position: relative; - float: left; - width: 239px; - margin: 10px; - overflow: hidden; - box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.16), 0 1px 10px 0 rgba(0, 0, 0, 0.12); - transition: box-shadow 0.13s; -} -#video .card:hover { - box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.26), 0 6px 15px 0 rgba(0, 0, 0, 0.22); -} -#video .card .img { - width: 100%; - height: 180px; - display: block; - background-size: cover; - transition: opacity 0.13s; -} -#video .card:hover .img { - opacity: 0.5; -} -#video .card .info { - display: block; - padding: 10px 8px; - background: #f0f0f0 linear-gradient(to bottom, #fafafa 0%, #f0f0f0 100%); - text-shadow: 0 1px 0 #FFF; - border: 1px solid #ccc; - border-top: 0; -} -#video .card .title { - font-weight: bold; - display: block; - height: 30px; -} -#video .card .reveal { - position: absolute; - top: 100%; - width: 100%; - height: 80%; - background: #f0f0f0 linear-gradient(to bottom, #fafafa 0%, #f0f0f0 100%); - border-top: 1px solid #ccc; - box-sizing: border-box; - z-index: 1; - padding: 15px 10px 0 10px; - opacity: 0; - transition: transform 0.13s, opacity 0.13s; -} -#video .card:hover .reveal { - transform: translateY(-100%); - opacity: 1; -} -#video .card .duration { - position: absolute; - bottom: 1px; - right: 1px; - z-index: 2; - opacity: 1; - padding: 0 2px; - background: rgba(255,255,255,0.7); -} -#video .card .view { - position: absolute; - top: 5px; - left: 5px; - z-index: 2; - padding: 3px 5px; - background: rgba(0,0,0,0.7); - color: #ddd; - text-transform: uppercase; - font-weight: bold; - border-radius: 3px; -} -#video .card .full-title { - font-weight: bold; - display: block; -} -#video .card .author { - display: block; - margin-bottom: 0.8em; - opacity: 0.8; -} -#video .card .target { - text-transform: uppercase; - text-align: center; - display: block; - margin-bottom: 0.8em; -} -#video .card .tags span { - display: block; -} -#video .show .meta { - padding: 0 25px 10px 25px; -} -#video .show .meta .target { - display: block; - text-align: center; - text-transform: uppercase; - margin-bottom: 1em; -} -#video .show .meta .author { - font-size: 1.5em; - margin-right: 15px; - opacity: 0.7; -} -#video .show .meta .tag { - white-space: nowrap; - font-weight: bold; - display: inline-block; - margin-right: 5px; - opacity: 0.7; - vertical-align: 2px; -} -#video .show .meta .author:hover, -#video .show .meta .tag:hover { - opacity: 1; -} -#video .show .meta .description { - margin-top: 1em; -} -#video_side { - margin-top: 20px; - margin-left: -30px; - width: 241px; -} -@media (max-width: 1070px) { -#video_side { - margin-left: 0; - width: 211px; -} -} -#video_side .tag_list { - text-transform: capitalize; -} -#video_side .tag_list a { - display: block; - padding: 5px 10px 5px 5px; - border-left: 2px solid transparent; - transition: background 0.13s, border 0.13s; -} -#video_side .tag_list a.full:hover { - background: #f8f8f8; - border-color: #ccc; -} -#video_side .tag_list em { - float: right; - font-weight: bold; - opacity: 0.6; -} -#video_side .tag_list a.checked { - font-weight: bold; - background: #fff; - border-color: #d85000!important; -} -#video_side .tag_list a.empty { - opacity: 0.5; - cursor: default; -} -#video_side .under_tags { - margin-top: 2em; - text-align: center; -} - -#video .tag_list { - margin: 10px; - text-align: justify; -} -#video .tag_list a { - display: inline-block; - font-size: 1.2em; - padding: 3px 5px; - margin: 5px 5px; - background: #f0f0f0; - border-radius: 2px; - text-transform: capitalize; -} -#video .tag_list a:hover { - background: #fff; - box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.16), 0 1px 10px 0 rgba(0, 0, 0, 0.12); -} -#video .tag_list a em { - font-weight: bold; - opacity: 0.6; - color: #d59120; -} - -#video .not_found { - margin-top: 200px; - text-align: center; -} -#video .not_much { - margin-top: 100px; - text-align: center; -} -#video .not_much.nb_0 { - margin-top: 200px; -} -#video .explain { - text-align: center; - margin: 50px 0 35px 0; -} diff --git a/translation/dest/site/en-US.xml b/translation/dest/site/en-US.xml index 9e127e4a36..18db9c3fcf 100644 --- a/translation/dest/site/en-US.xml +++ b/translation/dest/site/en-US.xml @@ -163,7 +163,6 @@ Rating Rating stats User name - Only the case of the letters can change. For example "johndoe" -> "JohnDoe". User name or email Change username Only the case of the letters can change. For example \"johndoe\" to \"JohnDoe\". diff --git a/translation/source/site.xml b/translation/source/site.xml index 363c6f46e3..7e45a24b4e 100644 --- a/translation/source/site.xml +++ b/translation/source/site.xml @@ -133,7 +133,6 @@ View in full size Sign out Sign in - New to Lichess? You need an account to do that Register Computers and computer-assisted players are not allowed to play. Please do not get assistance from chess engines, databases, or from other players while playing. Also note that making multiple accounts is strongly discouraged and excessive multi-accounting will lead to being banned. @@ -167,7 +166,6 @@ Only the case of the letters can change. For example "johndoe" to "JohnDoe". Change your username. This can only be done once and you are only allowed to change the case of the letters in your username. Password - Have an account? Change password Change email Email @@ -226,7 +224,7 @@ Play Inbox Chat room - Login to chat + Sign in to chat You have been timed out. Spectator room Compose message @@ -344,8 +342,8 @@ From position Continue from here Import game - When pasting a game PGN you get a browsable replay, -a computer analysis, a game chat and a shareable URL. + Paste a game PGN to get a browsable replay, +computer analysis, game chat and shareable URL. %s imported game %s imported games @@ -587,8 +585,7 @@ a computer analysis, a game chat and a shareable URL. %1$s commented %2$s Victory Defeat - %1$s vs %2$s -in %3$s + %1$s vs %2$s in %3$s Timeline Starting: All information is public and optional. @@ -728,7 +725,7 @@ in %3$s With everybody You have already registered the email: %s Kid mode - This is about safety. In kid mode, all site communications are disabled. Enable this for your children and school students, to protect them from other internet users. + This is about safety. In kid mode, all site communications are disabled. Enable this for your children and school students, to protect them from other Internet users. In kid mode, the lichess logo gets a %s icon, so you know your kids are safe. Enable Kid mode Disable Kid mode diff --git a/ui/@types/lichess/index.d.ts b/ui/@types/lichess/index.d.ts index 031594aa9d..71f3b333e3 100644 --- a/ui/@types/lichess/index.d.ts +++ b/ui/@types/lichess/index.d.ts @@ -4,28 +4,24 @@ interface Lichess { numberFormat(n: number): string once(key: string): boolean quietMode: boolean - desktopNotification(txt: string | (() => string)): void engineName: string; assetUrl(url: string, opts?: AssetUrlOpts): string; storage: LichessStorageHelper reload(): void; redirect(o: string | { url: string, cookie: Cookie }): void; loadScript(url: string, opts?: AssetUrlOpts): any + compiledScript(path: string): string keyboardMove: any slider(): any - reloadOtherTabs(): void - raf(f: () => void): void - requestIdleCallback(f: () => void): void - loadCss(path: string): void - unloadCss(path: string): void - loadedCss: [string]; - escapeHtml(str: string): string - toYouTubeEmbedUrl(url: string): string - fp: { - debounce(func: (...args: any[]) => void, wait: number, immediate?: boolean): (...args: any[]) => void; - contains(list: T[], needle: T): boolean; - contains(str: string, c: string): boolean; + raf(f: () => void): void; + requestIdleCallback(f: () => void): void; + loadCss(path: string): void; + loadCssPath(path: string): void; + loadedCss: { + [key: string]: boolean; } + escapeHtml(str: string): string + debounce(func: (...args: any[]) => void, wait: number, immediate?: boolean): (...args: any[]) => void; sound: any powertip: any userAutocomplete: any @@ -40,27 +36,35 @@ interface Lichess { ab: any; challengeApp: any; hopscotch: any; - makeChat(id: string, data: any, callback?: (chat: any) => void): void; - topMenuIntent(): void; + makeChat(data: any, callback?: (chat: any) => void): void; timeago: { render(nodes: HTMLElement | HTMLElement[]): void; format(date: number | Date): string; absolute(date: number | Date): string; } advantageChart: { - update(data: any): void; + update(data: any, partial: boolean): void; (data: any, trans: Trans, el: HTMLElement): void; } - dispatchEvent(el: HTMLElement, eventName: string): void; - isTrident: boolean; - isMS: boolean; + dispatchEvent(el: HTMLElement | Window, eventName: string): void; RoundNVUI(redraw: () => void): { render(ctrl: any): any; } AnalyseNVUI(redraw: () => void): { render(ctrl: any): any; } - playMusic(): void; + playMusic(): any; + LichessSpeech?: LichessSpeech; + spinnerHtml: string; + movetimeChart: any; + hasTouchEvents: boolean; + mousedownEvent: 'mousedown' | 'touchstart'; + isCol1(): boolean; +} + +interface LichessSpeech { + say(t: string, cut: boolean): void; + step(s: { san?: San }, cut: boolean): void; } interface Cookie { @@ -84,25 +88,35 @@ interface Trans { vdomPlural(key: string, count: number, countArg: T, ...args: T[]): (string | T)[]; } +type PubsubCallback = (...data: any[]) => void; + interface Pubsub { - on(msg: string, f: (...data: any[]) => void): void - emit(msg: string): (...args: any[]) => void + on(msg: string, f: PubsubCallback): void; + off(msg: string, f: PubsubCallback): void; + emit(msg: string): (...args: any[]) => void; } interface LichessStorageHelper { make(k: string): LichessStorage; - get(k: string): string; - set(k: string, v: string): string; + makeBoolean(k: string): LichessBooleanStorage; + get(k: string): string | null; + set(k: string, v: string): void; remove(k: string): void; } interface LichessStorage { - get(): string; - set(v: string): string; + get(): string | null; + set(v: string): void; remove(): void; listen(f: (e: StorageEvent) => void): void; } +interface LichessBooleanStorage { + get(): boolean; + set(v: boolean): boolean; + toggle(): void; +} + interface Window { lichess: Lichess @@ -126,14 +140,6 @@ interface LightUser { patron?: boolean } -interface Array { - find(f: (t: T) => boolean): T | undefined; -} - -interface Math { - log2?: (x: number) => number; -} - interface WebAssemblyStatic { validate(bufferSource: ArrayBuffer | Uint8Array): boolean Memory: any @@ -168,7 +174,7 @@ interface Variant { interface Paginator { currentPage: number maxPerPage: number - currentPageResults: [A] + currentPageResults: Array nbResults: number previousPage?: number nextPage?: number @@ -286,7 +292,7 @@ interface JQueryStatic { } interface LichessModal { - (html: string | JQuery): JQuery; + (html: string | JQuery, cls?: string): JQuery; close(): void; } @@ -322,3 +328,7 @@ declare namespace PowerTip { closeEvents?: string[]; } } + +interface Array { + includes(t: T): boolean; +} diff --git a/ui/README.md b/ui/README.md new file mode 100644 index 0000000000..741e6d978a --- /dev/null +++ b/ui/README.md @@ -0,0 +1,41 @@ +# Client-side modules + +## CSS + + +``` +cd ui/ +yarn install # only the first time +gulp css +``` + +This incrementally rebuilds the sass for all ui/ modules on file change. + +### Hack + +The structure of a CSS module is as follows: + +``` +- css/ + - forum/ + - _forum.scss # imports the files below + - _post.scss + - _search.scss + - ... + - build/ + - _forum.scss # imports dependencies and `../forum/forum`. + - forum.light.scss # generated + - forum.dark.scss # generated + - forum.transp.scss # generated +``` + +## Browser support + +| Name | Version | Notes | +| --------------- | ------- | ----- | +| Firefox | 61+ | Full support | +| Chromium/Chrome | last 10 | Full support | +| Safari | 10.1+ | Reasonable support | +| Opera | last 5 | Reasonable support | +| Edge | last 2 | Reasonable support | +| IE | none | No support | diff --git a/ui/analyse/css/_acpl.scss b/ui/analyse/css/_acpl.scss new file mode 100644 index 0000000000..aa5b095674 --- /dev/null +++ b/ui/analyse/css/_acpl.scss @@ -0,0 +1,43 @@ +.advice-summary { + @extend %flex-column; + color: $c-font-page; + font-size: .9em; + align-items: flex-start; + line-height: 1.15em; + margin-top: 1em; + td { + text-align: center; + &:first-child { + width: 5ch; + } + } + tbody td { + font-weight: bold; + } + .color-icon::before { + vertical-align: text-bottom; + } + tr.symbol { + cursor: pointer; + } + tr.symbol:hover { + color: #3893E8; + } + .button { + margin: .6em 0; + } + @include breakpoint($mq-col1) { + flex-flow: row wrap; + justify-content: center; + padding-bottom: $block-gap; + border-bottom: $border; + margin: 0; + table { + flex: 0 0 calc(50% - #{$block-gap}); + margin-left: $block-gap; + } + > a { + order: 1; + } + } +} diff --git a/ui/analyse/css/_action-menu.scss b/ui/analyse/css/_action-menu.scss new file mode 100644 index 0000000000..a679c30e66 --- /dev/null +++ b/ui/analyse/css/_action-menu.scss @@ -0,0 +1,101 @@ +.action-menu { + @extend %border-bottom-active; + flex: 1 1 0; // 0 size forces vertical scrollbar + display: flex; + flex-flow: column; + overflow: auto; + padding: $block-gap; + h2 { + font-size: 1em; + text-transform: uppercase; + text-align: center; + white-space: nowrap; + margin: $block-gap 0 3px 0; + display: table; + padding: 0 10px; + &:before, + &:after { + border-top: $border; + content: ''; + display: table-cell; + position: relative; + top: .5em; + width: 45%; + } + &:before { + right: 8px; + } + &:after { + left: 8px; + } + } + &__tools { + flex: 0 0 auto; + display: flex; + flex-flow: row wrap; + > * { + @extend %flex-column; + flex: 0 0 50%; + text-align: center; + padding: 0; + height: 75px; + justify-content: center; + } + .button { + color: $c-font; + text-transform: none; + white-space: normal; + &::before { + display: block; + font-size: 2em; + line-height: 1em; + margin-bottom: 5px; + } + } + } + .autoplay { + display: flex; + a { + color: $c-font-dim; + font-size: .9em; + flex: 1 1 auto; + padding: 7px 0; + text-align: center; + } + } + form.delete { + text-align: right; + margin-top: 6px; + .button { + display: inline-block; + padding: 0 8px; + } + .button::before { + font-size: 1.2em; + } + } + .setting { + flex: 0 0 auto; + margin-top: $block-gap; + display: flex; + label { + flex: 4 1 auto; + cursor: pointer; + white-space: nowrap; + } + input[type=range] { + flex: 1 4 auto; + padding: 0 1em; + height: 1.6em; + width: 100%; + } + .range_value { + flex: 0 0 auto; + display: block; + text-align: right; + } + } + @include breakpoint($mq-col1) { + .abset-inline { display: none } // force inline on mobile + } +} diff --git a/ui/analyse/css/_analyse.base.scss b/ui/analyse/css/_analyse.base.scss new file mode 100644 index 0000000000..14f2c4e7de --- /dev/null +++ b/ui/analyse/css/_analyse.base.scss @@ -0,0 +1,18 @@ +@import 'variables'; + +%border-bottom-active { + border-bottom: $border; + @include breakpoint($mq-col2) { + border-bottom: 3px solid $c-secondary; + } +} + +@import 'layout'; +@import 'tools'; +@import 'action-menu'; +@import 'explorer'; +@import 'training'; +@import 'practice'; +@import 'side'; +@import 'context-menu'; +// @import 'side-clock'; diff --git a/ui/analyse/css/_analyse.free.scss b/ui/analyse/css/_analyse.free.scss new file mode 100644 index 0000000000..70c0a3141f --- /dev/null +++ b/ui/analyse/css/_analyse.free.scss @@ -0,0 +1,49 @@ +/* free analysis on /analysis */ +@import 'analyse.base'; + +.copyables { + + .pair { + @extend %flex-center; + position: relative; + .action { + @extend %box-radius-bottom; + position: absolute; + right: 0; + top: 100%; + text-align: right; + opacity: 0; + @include transition(); + } + textarea:focus ~ .action { + opacity: 1; + } + } + .name { + flex: 0 0 5ch; + font-weight: bold; + color: $c-font-dim; + } + .copyable { + flex: 1 1 auto; + } + .pgn { + margin: 1em 0; + textarea { + min-height: 6em; + white-space: pre-wrap; + overflow-x: hidden; + } + } +} + +.mselect { + font-size: 1.5em; + label span, + a { + @extend %flex-center-nowrap; + &::before { + line-height: 0; + } + } +} diff --git a/ui/analyse/css/_analyse.round.scss b/ui/analyse/css/_analyse.round.scss new file mode 100644 index 0000000000..7d89638c4c --- /dev/null +++ b/ui/analyse/css/_analyse.round.scss @@ -0,0 +1,6 @@ +/* analyse a game replay */ +@import 'analyse.base'; +@import 'retro'; +@import 'acpl'; +@import 'round-underboard'; +@import 'player-clock'; diff --git a/ui/analyse/css/_context-menu.scss b/ui/analyse/css/_context-menu.scss new file mode 100644 index 0000000000..9f5db055af --- /dev/null +++ b/ui/analyse/css/_context-menu.scss @@ -0,0 +1,31 @@ +#analyse-cm { + @extend %box-radius, %popup-shadow; + background: $c-bg-box; + position: absolute; + display: none; + z-index: z('context-menu'); + cursor: default; + &.visible { + display: block; + } + .title { + @extend %san, %metal; + padding: .4em; + text-align: center; + font-size: 1.2em; + border-bottom: $border; + margin: 0; + } + a { + @extend %flex-center-nowrap; + color: $c-font; + padding: .5em .6em .5em .3em; + &::before { + width: 2em; + text-align: center; + } + &:hover { + background: mix($c-accent, $c-bg-box, 10%); + } + } +} diff --git a/ui/analyse/css/_explorer.scss b/ui/analyse/css/_explorer.scss new file mode 100644 index 0000000000..765c9d6a88 --- /dev/null +++ b/ui/analyse/css/_explorer.scss @@ -0,0 +1,255 @@ +.explorer-box { + position: relative; + flex: 2.5 1 0px; + white-space: nowrap; + @include transition(); + transition-delay: 0.3s; + overflow-y: scroll; + font-size: .9em; + &.reduced { + flex: 0.3 3 0px; + &:hover { + flex: 1 2 0px; + } + } + .overlay { + @extend %link-overlay; + display: none; + } + &.loading .overlay { + display: block; + } + tbody { + @include transition(opacity); + } + &.loading tbody { + opacity: 0.4; + } + .empty { + text-align: center; + display: flex; + flex-flow: column; + height: 100%; + } + tr { + @include transition(background-color); + &:nth-child(even) { + background: $c-bg-zebra; + } + &:hover { + background: mix($c-secondary, $c-bg-box, 20%); + } + } + td { + cursor: pointer; + padding-left: 7px; + } + .moves td:first-child { + @extend %san; + line-height: 30px; + padding-left: 7px; + } + .moves td:nth-child(2) { + font-size: .75em; + text-align: right; + } + .moves td:last-child { + width: 100%; + padding-right: 7px; + } + .bar span { + text-align: center; + display: inline-block; + overflow: hidden; + vertical-align: middle; + border: 0 solid $c-border; + border-width: 1px 0; + height: 16px; + line-height: 14px; + font-size: .9em; + } + .white { + background: if($theme-light, #fff, #ccc); + box-shadow: 0 -5px 7px rgba(0,0,0,if($theme-light, .1, .25)) inset; + @if $theme-dark { + color: #222; + } + } + .draws, + .black { + color: if($theme-light, #fff, #ddd); + box-shadow: 0 5px 7px rgba(255,255,255, if($theme-light, .2, .1)) inset; + } + .draws { + background: if($theme-light, #a0a0a0, #666); + } + .black { + background: if($theme-light, #555, #333); + color: #ddd; + } + .bar span:first-child { + @extend %box-radius-left; + border-left-width: 1px; + } + .bar span:last-child { + @extend %box-radius-right; + border-right-width: 1px; + } + .games { + width: 100%; + } + .games td { + padding: 5px 0 5px 7px; + max-width: 110px; + } + .games td span { + @extend %ellipsis; + display: block; + } + .games result { + display: block; + text-align: center; + padding: 3px 5px; + border-radius: 3px; + font-size: .9em; + } + .game_menu { + background: $c-secondary; + cursor: default; + padding: 0; + .game_title { + text-align: center; + color: $c-secondary-over; + margin: 3px 0 1px 0; + } + .menu { + display: flex; + justify-content: space-between; + text-transform: uppercase; + a { + color: #fff; + padding: 4px 8px; + } + a:hover { + background: rgba(255,255,255,0.2); + } + } + } + .tablebase { + width: 100%; + td:first-child { + @extend %san; + font-size: 14px; + line-height: 30px; + padding-left: 7px; + } + td:last-child { + padding-right: 7px; + text-align: right; + } + result { + padding: 3px 5px; + margin-left: 5px; + border-radius: 3px; + font-size: 0.9em; + } + } + .toconf { + position: absolute; + top: 0; + right: 0; + cursor: pointer; + display: block; + font-size: 1.2em; + width: 1.5em; + line-height: 1.5em; + text-align: center; + opacity: 0.8; + &:hover { + opacity: 1; + } + } + .message { + text-align: center; + font-style: italic; + flex: 1 1 100%; + display: flex; + flex-flow: column; + justify-content: center; + } + &.reduced .message { + justify-content: flex-start; + } + .message strong { + font-weight: bold; + margin: 1em 0; + } + &:not(.reduced) .message h3, + &.reduced:hover .message h3 { + font-weight: bold; + } + .message p { + white-space: normal; + padding: 0 8px; + margin: 0 0 8px 0; + } + &.reduced .message p, + &.reduced .message button { + display: none; + } + &.reduced:hover .message p, + &.reduced:hover .message button { + display: block; + } + .message button { + margin: 0 30px; + } + .message.masters i { + font-size: 40px; + margin: 10px 0; + } + .config { + section { + margin: .4em $block-gap 0 $block-gap; + } + section.save { + text-align: center; + padding: 15px 0 10px 0; + } + label { + font-weight: bold; + display: block; + line-height: 2em; + } + .choices { + display: flex; + span { + flex-grow: 1; + padding: 5px 0; + text-align: center; + cursor: pointer; + @include transition('background'); + border: $border; + border-width: 1px 0 1px 1px; + text-transform: capitalize; + &:first-child { + @extend %box-radius-left; + } + &:last-child { + @extend %box-radius-right; + border-right-width: 1px; + } + &:hover { + background: #fff; + } + &.selected { + background: $c-secondary; + color: $c-secondary-over; + text-shadow: 1px 0 0 rgba(0,0,0,0.5); + font-weight: bold; + box-shadow: 0 3px 5px rgba(0,0,0,0.2) inset; + } + } + } + } +} diff --git a/ui/analyse/css/_forecast.scss b/ui/analyse/css/_forecast.scss new file mode 100644 index 0000000000..619bbe3583 --- /dev/null +++ b/ui/analyse/css/_forecast.scss @@ -0,0 +1,121 @@ +.forecast { + user-select: none; + @include transition(); + position: relative; + &.loading .box, + &.loading .add { + opacity: .5; + } + .overlay { + @extend %link-overlay, %flex-center; + } + .box { + @extend %box-neat-force; + } + .top { + @extend %metal; + border-bottom: $border; + padding: .5em .7em; + } + .entry { + @extend %flex-center-nowrap; + padding: .7em .1em .7em .6em; + margin-left: -.1em; + @include transition(); + position: relative; + border-bottom: $border; + &::before { + margin-left: -.6em; + opacity: .4; + } + .del { + @extend %button-shadow; + position: absolute; + right: 5px; + top: 8px; + width: 1.5em; + height: 1.5em; + line-height: .8em; + text-align: center; + display: block; + font-size: .9em; + opacity: 0; + @include transition(); + background: $c-bad; + color: $c-bad-over; + padding: .25em; + border-radius: 50%; + z-index: 1; + } + &:hover .del { + opacity: .6; + } + .del:hover { + opacity: 1; + } + } + .add { + @extend %button-none, %flex-center-nowrap; + width: 100%; + padding: .7em; + text-align: left; + color: $c-font-dim; + cursor: inherit; + &::before { + font-size: 2.2em; + opacity: .6; + } + &.enabled { + @extend %metal; + cursor: pointer; + color: $c-font; + @include transition(); + &::before { + opacity: .7; + color: $c-good; + } + &:hover { + @extend %metal-hover; + &::before { + opacity: 1; + } + } + } + > span { + font-size: .9em; + > span { + color: $c-font-dim; + } + } + } + sans { + @extend %roboto, %flex-center; + } + san { + @extend %san; + } + sans > * { + display: inline-block; + margin-right: .2em; + } + .add sans { + @extend %flex-wrap; + } + .on-my-turn { + @extend %flex-center-nowrap; + margin-top: 1.3em; + text-transform: none; + text-align: left; + font-weight: normal; + width: 100%; + &::before { + font-size: 2.2em; + } + strong { + font-weight: bold; + } + > span { + @extend %flex-column; + } + } +} diff --git a/ui/analyse/css/_keyboard.scss b/ui/analyse/css/_keyboard.scss new file mode 100644 index 0000000000..7fe253eb07 --- /dev/null +++ b/ui/analyse/css/_keyboard.scss @@ -0,0 +1,55 @@ +.keyboard-help { + @extend %flex-column; + padding: 0!important; + h2 { + margin: .5em 0 0 0; + } + .scrollable { + overflow-y: auto; + padding: .8em 0; + } + table { + width: 100%; + } + th p { + margin: 1.2em 0 .6em 0; + background: $c-brag; + color: $c-brag-over; + font-weight: bold; + padding: .3em 0; + } + td { + padding: .2em .5em; + text-align: left; + } + .keys { + padding-right: 1em; + text-align: right; + white-space: nowrap; + } + .desc:first-letter { + text-transform: uppercase; + } + or { + margin-left: .2em; + opacity: 0.5; + } + kbd { + display: inline-block; + padding: 4px 5px; + margin-left: 3px; + font-family: monospace; + line-height: 10px; + color: #444; + vertical-align: middle; + background-color: #fcfcfc; + border: solid 1px #ccc; + border-bottom-color: #bbb; + border-radius: 3px; + box-shadow: inset 0 -1px 0 #bbb; + } + td.mouse li { + list-style: disc inside; + margin-left: 1em; + } +} diff --git a/ui/analyse/css/_layout.scss b/ui/analyse/css/_layout.scss new file mode 100644 index 0000000000..68e80f424e --- /dev/null +++ b/ui/analyse/css/_layout.scss @@ -0,0 +1,95 @@ +body { + /* prevents scroll bar flicker on page height changes */ + overflow-y: scroll; +} + +#main-wrap { + --main-max-width: calc(100vh - #{$site-header-outer-height} - #{$col1-uniboard-controls}); + @include breakpoint($mq-col2) { + --main-max-width: auto; + } +} + +.analyse { + grid-area: main; + display: grid; + + &__side { + grid-area: side; + justify-content: start; + margin: $block-gap; + } + &__board { grid-area: board; } + &__tools { grid-area: tools; } + &__controls { grid-area: controls; } + &__underboard { + grid-area: under; + @include breakpoint($mq-col1-uniboard) { + overflow: hidden; // helps truncating long study names + } + } + &__acpl { grid-area: acpl; } + .chat__members { grid-area: uchat; } + .eval-gauge { + grid-area: gauge; + display: none; + } + + --meta-height: auto; + @include proper-grid { + --meta-height: max-content; + } + + grid-template-rows: auto auto minmax(20em, 30vh); + grid-template-areas: + 'board' + 'controls' + 'tools' + 'side' + 'acpl' + 'under' + 'chat' + 'uchat'; + + @include breakpoint($mq-col2) { + grid-template-columns: $col2-uniboard-width var(--gauge-gap) $col2-uniboard-table; + grid-template-rows: fit-content(0); + grid-template-areas: + 'board gauge tools' + 'under . controls' + 'under . acpl' + 'under . side' + 'chat . side' + 'uchat . side'; + grid-row-gap: 0; + + &__side, + .chat__members, + .mchat { + margin: $block-gap 0 0 0; + } + + &__underboard { margin-top: $block-gap; } + + .eval-gauge { display: block } + } + + @include breakpoint($mq-col2-uniboard-squeeze) { + grid-template-columns: $col2-uniboard-squeeze-width var(--gauge-gap) $col2-uniboard-squeeze-table; + } + + @include breakpoint($mq-col3) { + grid-template-columns: $col3-uniboard-side $block-gap $col3-uniboard-width var(--gauge-gap) $col3-uniboard-table; + grid-template-rows: $meta-height $chat-height auto; + grid-template-areas: + 'side . board gauge tools' + 'chat . board gauge tools' + 'uchat . under . controls' + 'uchat . under . acpl'; + + &__side { margin-top: 0 } + .mchat { min-height: 10em } + + @include crosstable-large; + } +} diff --git a/ui/analyse/css/_player-clock.scss b/ui/analyse/css/_player-clock.scss new file mode 100644 index 0000000000..87ac78c8fc --- /dev/null +++ b/ui/analyse/css/_player-clock.scss @@ -0,0 +1,35 @@ +$clock-height: 20px; + +.analyse__clock { + @extend %metal, %box-shadow; + + position: absolute; + right: 0; + padding: 0 .5em; + + height: $clock-height; + + font-weight: bold; + text-align: center; + + &.top { + @extend %box-radius-top; + top: #{-$clock-height}; + } + &.bottom { + @extend %box-radius-bottom; + bottom: #{-$clock-height}; + z-index: 1; // over the board coords + } + &.active { + background: mix($c-primary, $c-bg-box, 30%); + } + tenths { + font-size: 80%; + } + + /* Where to put them in col1 layout? It moves the entire board and controls down for little benefit */ + @include breakpoint($mq-col1) { + display: none; + } +} diff --git a/ui/analyse/css/_practice.scss b/ui/analyse/css/_practice.scss new file mode 100644 index 0000000000..12b99b7ab5 --- /dev/null +++ b/ui/analyse/css/_practice.scss @@ -0,0 +1,79 @@ +.practice-box { + flex: 0 0 135px; + user-select: none; + .comment { + flex: 0 0 30px; + display: flex; + align-items: stretch; + background: $c-bg-zebra; + border-top: 1px solid $border; + white-space: nowrap; + line-height: 30px; + } + .progress div { + background: $c-shade; + } + &.goodMove .progress div { + background: $c-good; + color: #fff; + } + &.inaccuracy .title, + &.inaccuracy .progress div { + background: $c-brag; + color: #fff; + } + &.mistake .title, + &.blunder .title, + &.mistake .progress div, + &.blunder .progress div { + background: $c-bad; + color: #fff; + } + .comment .wait { + padding-left: 15px; + } + .verdict { + font-weight: bold; + margin-right: 10px; + display: flex; + } + .verdict::before { + width: 30px; + height: 100%; + color: #fff; + margin-right: 7px; + text-align: center; + font-size: 1.4em; + font-weight: normal; + } + &.goodMove .verdict { + color: $c-good; + } + &.goodMove .verdict::before { + background: $c-good; + content: '✓'; + font-size: 1.7em; + } + &.inaccuracy .verdict { + color: $c-brag; + } + &.inaccuracy .verdict::before { + background: $c-brag; + content: '?'; + } + &.mistake .verdict, + &.blunder .verdict { + color: $c-bad; + } + &.mistake .verdict::before, + &.blunder .verdict::before { + background: $c-bad; + content: '✗'; + } + .comment move { + cursor: pointer; + margin-left: 5px; + color: $c-link; + transition: 0.3s; + } +} diff --git a/ui/analyse/css/_retro.scss b/ui/analyse/css/_retro.scss new file mode 100644 index 0000000000..5c952b8563 --- /dev/null +++ b/ui/analyse/css/_retro.scss @@ -0,0 +1,42 @@ +.retro-box { + .title { + display: flex; + justify-content: space-between; + } + .player.center { + justify-content: center; + } + &:not(.find) .player { + height: 100%; + } + .win .icon:not(.off) { + color: #759900; + } + .fail .icon:not(.off) { + color: #dc322f; + } + .instruction glyph { + font-weight: normal; + opacity: 0.7; + } + .half { + flex: 1 1 50%; + } + .continue { + display: flex; + font-size: 1.3em; + background: rgba(56,147,232,0.8); + color: #fff; + align-items: center; + justify-content: center; + text-transform: uppercase; + padding: 0 10px; + } + .continue:hover { + background: rgba(56,147,232,1); + } + .continue i::before { + font-size: 2.5em; + margin-right: 10px; + } +} diff --git a/ui/analyse/css/_round-underboard.scss b/ui/analyse/css/_round-underboard.scss new file mode 100644 index 0000000000..df11f70470 --- /dev/null +++ b/ui/analyse/css/_round-underboard.scss @@ -0,0 +1,145 @@ +$col1-panel-height: 30vh; +$col2-panel-height: 240px; + +.comp-off .computer-analysis { + display: none !important; +} + +.analyse__underboard { + &__menu { + @extend %flex-center-nowrap; + justify-content: center; + align-items: flex-start; + border-top: 2px solid $c-border; + > span { + @extend %roboto, %box-radius-bottom; + flex: 1 1 0; + text-align: center; + font-size: .9em; + padding: .4em .1em; + cursor: pointer; + position: relative; + @include transition(color, .25s); + &::after { + content: ""; + background: fade-out($c-accent, .4); + height: 2px; + position: absolute; + width: 96%; + left: 2%; + top: -2px; + @include transition(all, .25s); + transform: scale(0); + } + &.active, + &:hover::after { + transform: scale(1); + } + &.active { + color: $c-accent; + } + } + } + &__panels { + --panel-height: #{$col1-panel-height}; + @include breakpoint($mq-col2) { + --panel-height: #{$col2-panel-height}; + } + > div { + height: var(--panel-height); + display: none; + text-align: left; + &.active { + display: block; + } + } + .crosstable table { + margin-top: 60px; + } + } + .computer-analysis, + .ctable { + align-items: center; + justify-content: center; + position: relative; + &.active { + display: flex; + } + } + .future-game-analysis { + text-align: center; + } + .fen-pgn { + overflow-x: visible; + overflow-y: auto; + font-size: .9em; + > div { + @extend %flex-center-nowrap; + margin-bottom: 1em; + } + .pgn { + white-space: pre-wrap; + font-family: monospace; + } + strong { + display: inline-block; + margin-right: 1em; + } + .pgn-options { + div { + @extend %flex-wrap; + } + a { + flex: 0 0 50%; + line-height: 1.6em; + } + } + } + &__fen { + width: 100%; + border: 0; + background: none; + padding: .3em; + margin-right: .5em; + } +} + +#adv-chart, +#movetimes-chart { + width: 100%; + height: var(--panel-height); + background: linear-gradient(to bottom, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0) 20%, rgba(128, 128, 128, 0.2) 50%, rgba(255, 255, 255, 0) 80%, rgba(255, 255, 255, 0) 100%); + overflow: hidden; +} +#adv-chart-loader { + font-size: .9em; + position: absolute; + top: 81px; + left: -1px; + background: $c-bg-box; + padding: 7px 10px 7px 0; + line-height: 20px; + box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.3); + display: flex; + border: $border; + border-radius: 0 99px 99px 0; + span { + @extend %nowrap-hidden; + margin-left: 7px; + opacity: 1; + transition: 0.5s; + width: 100px; + display: block; + .analyse__underboard:hover & { + margin-left: 0; + width: 0; + opacity: 0; + } + } + .spinner { + width: 32px; + height: 32px; + display:inline-block; + margin-left: 10px; + } +} diff --git a/ui/analyse/css/_side.scss b/ui/analyse/css/_side.scss new file mode 100644 index 0000000000..66803d65ae --- /dev/null +++ b/ui/analyse/css/_side.scss @@ -0,0 +1,14 @@ +.analyse__side { + align-self: start; + + .back-to-game { + margin-top: 2em; + @include breakpoint($mq-col3) { + margin-top: 10vh; + } + text-align: center; + .button { + margin: 0 auto; + } + } +} diff --git a/ui/analyse/css/_tools.scss b/ui/analyse/css/_tools.scss new file mode 100644 index 0000000000..47cc4b7d0d --- /dev/null +++ b/ui/analyse/css/_tools.scss @@ -0,0 +1,69 @@ +.analyse { + + &__tools { + @extend %box-neat-force, %flex-column; + max-height: 100vh; /* magically fixes fit-content on safari 10 */ + background: $c-bg-box; + .ceval { + flex: 0 0 38px; + } + .sub-box { + @extend %border-bottom-active; + user-select: none; + .title { + font-size: .9rem; + line-height: 1.9em; + background: mix($c-secondary, $c-bg-box, 40%); + padding: 0 7px; + } + } + } + + &__moves { + flex: 2 1 0; // 0 size forces vertical scrollbar + overflow-y: auto; + overflow-x: hidden; // else a scrollbar appears sometimes + border-top: $border; + position: relative; /* required so line::before scrolls along the moves! */ + .result, + .status { + background: $c-bg-zebra; + text-align: center; + } + .result { + border-top: $border; + font-weight: bold; + font-size: 1.2em; + padding: 5px 0 3px 0; + } + .status { + font-size: 1em; + font-style: italic; + padding-bottom: 7px; + } + } + + &__controls { + height: $col3-uniboard-controls; + align-items: stretch; + div { + display: flex; + flex: 1 1 auto; + align-items: stretch; + } + .jumps { + flex: 3 1 auto; + } + .fbt { + @extend %page-text; + flex: 0 0 2.5rem; + } + .active { + margin-top: -3px; + padding-top: 3px; + } + ::before { + vertical-align: middle; + } + } +} diff --git a/ui/analyse/css/_training.scss b/ui/analyse/css/_training.scss new file mode 100644 index 0000000000..d0edc02052 --- /dev/null +++ b/ui/analyse/css/_training.scss @@ -0,0 +1,66 @@ +.training-box { + @extend %flex-column; + flex: 1.5 1 0px; + .feedback { + flex: 1 1 100%; + display: flex; + flex-flow: column; + justify-content: center; + } + .progress { + margin-top: 5px; + opacity: 0.8; + width: 100%; + height: 4px; + background: $c-shade; + } + .progress div { + background: $c-good; + height: 4px; + transition: width 0.5s; + max-width: 100%; + } + .player { + display: flex; + align-items: center; + margin-left: 10px; + } + .no-square { + width: 64px; + height: 64px; + margin-right: 10px; + } + .is3d & div.no-square { + height: 82px; + } + piece { + position: inherit; + display: block; + width: 100%!important; + height: 100%!important; + } + .icon { + display: block; + width: 64px; + height: 64px; + margin-right: 10px; + font-size: 50px; + font-size: 64px; + line-height: 64px; + text-align: center; + } + .instruction > * { + display: block; + } + .instruction > strong { + font-weight: normal; + font-size: 1.2em; + } + .choices { + line-height: 1.6em; + margin: 5px 0 -5px 0; + } + .choices a { + display: block; + } +} diff --git a/ui/analyse/css/_variables.scss b/ui/analyse/css/_variables.scss new file mode 100644 index 0000000000..0e89752ce1 --- /dev/null +++ b/ui/analyse/css/_variables.scss @@ -0,0 +1,6 @@ +$mq-col1: $mq-col1-uniboard; +$mq-col2: $mq-col2-uniboard; +$mq-col3: $mq-col3-uniboard; + +$meta-height: var(--meta-height); +$chat-height: fit-content(0); diff --git a/ui/analyse/css/_zh.scss b/ui/analyse/css/_zh.scss new file mode 100644 index 0000000000..3118c2d453 --- /dev/null +++ b/ui/analyse/css/_zh.scss @@ -0,0 +1,56 @@ +@import 'variables'; + +$pocket-col1-height: auto; +$pocket-height: 60px; + +.pocket { + &-top { grid-area: pocket-top; } + &-bottom { grid-area: pocket-bot; } + &-c1 { + max-width: $pocket-height; + } +} + +.analyse { + grid-template-rows: $pocket-col1-height auto $pocket-col1-height auto 50vh; + grid-template-areas: + 'pocket-top' + 'board' + 'pocket-bot' + 'controls' + 'tools' + 'side' + 'acpl' + 'under' + 'chat' + 'uchat'; + @include breakpoint($mq-col2) { + grid-template-rows: $pocket-height auto $pocket-height; + grid-template-areas: + 'board gauge pocket-top' + 'board gauge tools' + 'board gauge pocket-bot' + 'under under controls' + 'under under acpl' + 'under under side' + 'chat chat side' + 'uchat uchat side'; + } + @include breakpoint($mq-col3) { + grid-template-rows: $pocket-height $meta-height $chat-height $pocket-height; + grid-template-areas: + 'side . board gauge pocket-top' + 'side . board gauge tools' + 'chat . board gauge tools' + 'chat . board gauge pocket-bot' + 'uchat . under under controls' + 'uchat . under under acpl'; + } +} + +@include breakpoint($mq-col1) { + .pocket { + &-top { margin-bottom: #{-$block-gap}; } + &-bottom { margin-top: #{-$block-gap}; } + } +} diff --git a/ui/analyse/css/build/_analyse.base.scss b/ui/analyse/css/build/_analyse.base.scss new file mode 100644 index 0000000000..80884d7298 --- /dev/null +++ b/ui/analyse/css/build/_analyse.base.scss @@ -0,0 +1,19 @@ +@import '../../../common/css/plugin'; +@import '../../../common/css/vendor/chessground/coords'; +@import '../../../common/css/layout/uniboard'; +@import '../../../common/css/base/scrollbar'; +@import '../../../common/css/component/board-resize'; +@import '../../../common/css/component/modal'; +@import '../../../common/css/component/continue-with'; +@import '../../../common/css/component/color-icon'; +@import '../../../common/css/component/crosstable'; +@import '../../../common/css/component/fbt'; +@import '../../../common/css/form/cmn-toggle'; +@import '../../../common/css/form/range'; +@import '../../../tree/css/tree'; +@import '../../../ceval/css/ceval'; +@import '../../../ceval/css/eval-gauge'; +@import '../../../chess/css/opening'; +@import '../../../chess/css/control'; +@import '../../../chess/css/promotion'; +@import '../../../chess/css/variant-style'; diff --git a/ui/analyse/css/build/_analyse.embed.scss b/ui/analyse/css/build/_analyse.embed.scss new file mode 100644 index 0000000000..6e965954ec --- /dev/null +++ b/ui/analyse/css/build/_analyse.embed.scss @@ -0,0 +1,23 @@ +@import '../../../common/css/plugin'; + +@import '../../../common/css/abstract/all'; + +@import '../../../common/css/base/elements'; +@import '../../../common/css/base/fonts'; +@import '../../../common/css/base/typography'; +@import '../../../common/css/base/data-icon'; + +@include theme-style; + +@import '../../../common/css/vendor/chessground/chessground'; + +@import '../../../common/css/component/board'; + +@import '../../../common/css/base/scrollbar'; +@import '../../../common/css/component/fbt'; +@import '../../../common/css/form/cmn-toggle'; +@import '../../../tree/css/tree'; +@import '../../../chess/css/opening'; +@import '../../../chess/css/control'; + +@import '../embed/embed'; diff --git a/ui/analyse/css/build/_analyse.forecast.scss b/ui/analyse/css/build/_analyse.forecast.scss new file mode 100644 index 0000000000..91d65952bb --- /dev/null +++ b/ui/analyse/css/build/_analyse.forecast.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/plugin'; +@import '../forecast'; diff --git a/ui/analyse/css/build/_analyse.free.scss b/ui/analyse/css/build/_analyse.free.scss new file mode 100644 index 0000000000..3e8a24dd16 --- /dev/null +++ b/ui/analyse/css/build/_analyse.free.scss @@ -0,0 +1,4 @@ +@import 'analyse.base'; +@import '../../../common/css/component/mselect'; + +@import '../analyse.free'; diff --git a/ui/analyse/css/build/_analyse.gamebook.edit.scss b/ui/analyse/css/build/_analyse.gamebook.edit.scss new file mode 100644 index 0000000000..ebc56a2161 --- /dev/null +++ b/ui/analyse/css/build/_analyse.gamebook.edit.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/plugin'; +@import '../gamebook/edit'; diff --git a/ui/analyse/css/build/_analyse.gamebook.play.scss b/ui/analyse/css/build/_analyse.gamebook.play.scss new file mode 100644 index 0000000000..9e64d17312 --- /dev/null +++ b/ui/analyse/css/build/_analyse.gamebook.play.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/plugin'; +@import '../gamebook/play'; diff --git a/ui/analyse/css/build/_analyse.keyboard.scss b/ui/analyse/css/build/_analyse.keyboard.scss new file mode 100644 index 0000000000..2fbe8ce233 --- /dev/null +++ b/ui/analyse/css/build/_analyse.keyboard.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/plugin'; +@import '../keyboard'; diff --git a/ui/analyse/css/build/_analyse.practice.scss b/ui/analyse/css/build/_analyse.practice.scss new file mode 100644 index 0000000000..67ebc422e5 --- /dev/null +++ b/ui/analyse/css/build/_analyse.practice.scss @@ -0,0 +1,6 @@ +@import 'analyse.base'; +// @import '../../../common/css/form/form3'; +// @import '../../../common/css/component/tabs-horiz'; +// @import '../../../common/css/component/slist'; + +@import '../practice/show'; diff --git a/ui/analyse/css/build/_analyse.relay-admin.scss b/ui/analyse/css/build/_analyse.relay-admin.scss new file mode 100644 index 0000000000..66da4d5d41 --- /dev/null +++ b/ui/analyse/css/build/_analyse.relay-admin.scss @@ -0,0 +1,3 @@ +@import '../../../common/css/plugin'; + +@import '../study/relay/admin'; diff --git a/ui/analyse/css/build/_analyse.round.scss b/ui/analyse/css/build/_analyse.round.scss new file mode 100644 index 0000000000..7620c20f04 --- /dev/null +++ b/ui/analyse/css/build/_analyse.round.scss @@ -0,0 +1,8 @@ +@import 'analyse.base'; + +@import '../../../common/css/component/context-streamer'; + +@import '../../../round/css/meta'; +@import '../../../chat/css/chat'; + +@import '../analyse.round'; diff --git a/ui/analyse/css/build/_analyse.study.scss b/ui/analyse/css/build/_analyse.study.scss new file mode 100644 index 0000000000..76b2ad10be --- /dev/null +++ b/ui/analyse/css/build/_analyse.study.scss @@ -0,0 +1,8 @@ +@import 'analyse.base'; +@import '../../../common/css/form/form3'; +@import '../../../common/css/component/tabs-horiz'; +@import '../../../common/css/component/slist'; +@import '../../../common/css/component/context-streamer'; +@import '../../../chat/css/chat'; + +@import '../study/show'; diff --git a/ui/analyse/css/build/_analyse.zh.scss b/ui/analyse/css/build/_analyse.zh.scss new file mode 100644 index 0000000000..f2e7af4989 --- /dev/null +++ b/ui/analyse/css/build/_analyse.zh.scss @@ -0,0 +1,3 @@ +@import '../../../common/css/plugin'; +@import '../../../chess/css/zh-pocket'; +@import '../zh'; diff --git a/ui/analyse/css/build/_study.create.scss b/ui/analyse/css/build/_study.create.scss new file mode 100644 index 0000000000..0424e38144 --- /dev/null +++ b/ui/analyse/css/build/_study.create.scss @@ -0,0 +1,3 @@ +@import '../../../common/css/plugin'; +@import '../../../common/css/form/form3'; +@import '../study/create'; diff --git a/ui/analyse/css/build/_study.index.scss b/ui/analyse/css/build/_study.index.scss new file mode 100644 index 0000000000..d21908f0c3 --- /dev/null +++ b/ui/analyse/css/build/_study.index.scss @@ -0,0 +1,3 @@ +@import '../../../common/css/plugin'; +@import '../../../common/css/component/mselect'; +@import '../study/index'; diff --git a/ui/analyse/css/build/analyse.base.dark.scss b/ui/analyse/css/build/analyse.base.dark.scss new file mode 100644 index 0000000000..1f3cc00cc9 --- /dev/null +++ b/ui/analyse/css/build/analyse.base.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'analyse.base'; diff --git a/ui/analyse/css/build/analyse.base.light.scss b/ui/analyse/css/build/analyse.base.light.scss new file mode 100644 index 0000000000..5706363de5 --- /dev/null +++ b/ui/analyse/css/build/analyse.base.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'analyse.base'; diff --git a/ui/analyse/css/build/analyse.base.transp.scss b/ui/analyse/css/build/analyse.base.transp.scss new file mode 100644 index 0000000000..21681983f2 --- /dev/null +++ b/ui/analyse/css/build/analyse.base.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'analyse.base'; diff --git a/ui/analyse/css/build/analyse.embed.dark.scss b/ui/analyse/css/build/analyse.embed.dark.scss new file mode 100644 index 0000000000..3b3a418402 --- /dev/null +++ b/ui/analyse/css/build/analyse.embed.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'analyse.embed'; diff --git a/ui/analyse/css/build/analyse.embed.light.scss b/ui/analyse/css/build/analyse.embed.light.scss new file mode 100644 index 0000000000..b6be320c3e --- /dev/null +++ b/ui/analyse/css/build/analyse.embed.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'analyse.embed'; diff --git a/ui/analyse/css/build/analyse.embed.transp.scss b/ui/analyse/css/build/analyse.embed.transp.scss new file mode 100644 index 0000000000..5e5528cc96 --- /dev/null +++ b/ui/analyse/css/build/analyse.embed.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'analyse.embed'; diff --git a/ui/analyse/css/build/analyse.forecast.dark.scss b/ui/analyse/css/build/analyse.forecast.dark.scss new file mode 100644 index 0000000000..7d30d33827 --- /dev/null +++ b/ui/analyse/css/build/analyse.forecast.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'analyse.forecast'; diff --git a/ui/analyse/css/build/analyse.forecast.light.scss b/ui/analyse/css/build/analyse.forecast.light.scss new file mode 100644 index 0000000000..fb3119c84b --- /dev/null +++ b/ui/analyse/css/build/analyse.forecast.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'analyse.forecast'; diff --git a/ui/analyse/css/build/analyse.forecast.transp.scss b/ui/analyse/css/build/analyse.forecast.transp.scss new file mode 100644 index 0000000000..ffb20a58bc --- /dev/null +++ b/ui/analyse/css/build/analyse.forecast.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'analyse.forecast'; diff --git a/ui/analyse/css/build/analyse.free.dark.scss b/ui/analyse/css/build/analyse.free.dark.scss new file mode 100644 index 0000000000..65d9312b14 --- /dev/null +++ b/ui/analyse/css/build/analyse.free.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'analyse.free'; diff --git a/ui/analyse/css/build/analyse.free.light.scss b/ui/analyse/css/build/analyse.free.light.scss new file mode 100644 index 0000000000..9b1fd9ab48 --- /dev/null +++ b/ui/analyse/css/build/analyse.free.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'analyse.free'; diff --git a/ui/analyse/css/build/analyse.free.transp.scss b/ui/analyse/css/build/analyse.free.transp.scss new file mode 100644 index 0000000000..dea950abc3 --- /dev/null +++ b/ui/analyse/css/build/analyse.free.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'analyse.free'; diff --git a/ui/analyse/css/build/analyse.gamebook.edit.dark.scss b/ui/analyse/css/build/analyse.gamebook.edit.dark.scss new file mode 100644 index 0000000000..3344bd6ac0 --- /dev/null +++ b/ui/analyse/css/build/analyse.gamebook.edit.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'analyse.gamebook.edit'; diff --git a/ui/analyse/css/build/analyse.gamebook.edit.light.scss b/ui/analyse/css/build/analyse.gamebook.edit.light.scss new file mode 100644 index 0000000000..c700e25631 --- /dev/null +++ b/ui/analyse/css/build/analyse.gamebook.edit.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'analyse.gamebook.edit'; diff --git a/ui/analyse/css/build/analyse.gamebook.edit.transp.scss b/ui/analyse/css/build/analyse.gamebook.edit.transp.scss new file mode 100644 index 0000000000..d7fe9b6e4f --- /dev/null +++ b/ui/analyse/css/build/analyse.gamebook.edit.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'analyse.gamebook.edit'; diff --git a/ui/analyse/css/build/analyse.gamebook.play.dark.scss b/ui/analyse/css/build/analyse.gamebook.play.dark.scss new file mode 100644 index 0000000000..e7a5db5aae --- /dev/null +++ b/ui/analyse/css/build/analyse.gamebook.play.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'analyse.gamebook.play'; diff --git a/ui/analyse/css/build/analyse.gamebook.play.light.scss b/ui/analyse/css/build/analyse.gamebook.play.light.scss new file mode 100644 index 0000000000..84ef83a86a --- /dev/null +++ b/ui/analyse/css/build/analyse.gamebook.play.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'analyse.gamebook.play'; diff --git a/ui/analyse/css/build/analyse.gamebook.play.transp.scss b/ui/analyse/css/build/analyse.gamebook.play.transp.scss new file mode 100644 index 0000000000..a8f14920f0 --- /dev/null +++ b/ui/analyse/css/build/analyse.gamebook.play.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'analyse.gamebook.play'; diff --git a/ui/analyse/css/build/analyse.keyboard.dark.scss b/ui/analyse/css/build/analyse.keyboard.dark.scss new file mode 100644 index 0000000000..08897667ec --- /dev/null +++ b/ui/analyse/css/build/analyse.keyboard.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'analyse.keyboard'; diff --git a/ui/analyse/css/build/analyse.keyboard.light.scss b/ui/analyse/css/build/analyse.keyboard.light.scss new file mode 100644 index 0000000000..775e72e3b3 --- /dev/null +++ b/ui/analyse/css/build/analyse.keyboard.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'analyse.keyboard'; diff --git a/ui/analyse/css/build/analyse.keyboard.transp.scss b/ui/analyse/css/build/analyse.keyboard.transp.scss new file mode 100644 index 0000000000..cf6109f126 --- /dev/null +++ b/ui/analyse/css/build/analyse.keyboard.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'analyse.keyboard'; diff --git a/ui/analyse/css/build/analyse.practice.dark.scss b/ui/analyse/css/build/analyse.practice.dark.scss new file mode 100644 index 0000000000..408cb1d5ea --- /dev/null +++ b/ui/analyse/css/build/analyse.practice.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'analyse.practice'; diff --git a/ui/analyse/css/build/analyse.practice.light.scss b/ui/analyse/css/build/analyse.practice.light.scss new file mode 100644 index 0000000000..0ec678b459 --- /dev/null +++ b/ui/analyse/css/build/analyse.practice.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'analyse.practice'; diff --git a/ui/analyse/css/build/analyse.practice.transp.scss b/ui/analyse/css/build/analyse.practice.transp.scss new file mode 100644 index 0000000000..0ecdf487cb --- /dev/null +++ b/ui/analyse/css/build/analyse.practice.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'analyse.practice'; diff --git a/ui/analyse/css/build/analyse.relay-admin.dark.scss b/ui/analyse/css/build/analyse.relay-admin.dark.scss new file mode 100644 index 0000000000..12e4d40a98 --- /dev/null +++ b/ui/analyse/css/build/analyse.relay-admin.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'analyse.relay-admin'; diff --git a/ui/analyse/css/build/analyse.relay-admin.light.scss b/ui/analyse/css/build/analyse.relay-admin.light.scss new file mode 100644 index 0000000000..31818b9eaa --- /dev/null +++ b/ui/analyse/css/build/analyse.relay-admin.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'analyse.relay-admin'; diff --git a/ui/analyse/css/build/analyse.relay-admin.transp.scss b/ui/analyse/css/build/analyse.relay-admin.transp.scss new file mode 100644 index 0000000000..c7f6e211d0 --- /dev/null +++ b/ui/analyse/css/build/analyse.relay-admin.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'analyse.relay-admin'; diff --git a/ui/analyse/css/build/analyse.round.dark.scss b/ui/analyse/css/build/analyse.round.dark.scss new file mode 100644 index 0000000000..a97ccf6f1a --- /dev/null +++ b/ui/analyse/css/build/analyse.round.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'analyse.round'; diff --git a/ui/analyse/css/build/analyse.round.light.scss b/ui/analyse/css/build/analyse.round.light.scss new file mode 100644 index 0000000000..9282c0df3d --- /dev/null +++ b/ui/analyse/css/build/analyse.round.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'analyse.round'; diff --git a/ui/analyse/css/build/analyse.round.transp.scss b/ui/analyse/css/build/analyse.round.transp.scss new file mode 100644 index 0000000000..c813bf2ddc --- /dev/null +++ b/ui/analyse/css/build/analyse.round.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'analyse.round'; diff --git a/ui/analyse/css/build/analyse.study.dark.scss b/ui/analyse/css/build/analyse.study.dark.scss new file mode 100644 index 0000000000..ef3ddc79d2 --- /dev/null +++ b/ui/analyse/css/build/analyse.study.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'analyse.study'; diff --git a/ui/analyse/css/build/analyse.study.light.scss b/ui/analyse/css/build/analyse.study.light.scss new file mode 100644 index 0000000000..295e42ec8e --- /dev/null +++ b/ui/analyse/css/build/analyse.study.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'analyse.study'; diff --git a/ui/analyse/css/build/analyse.study.transp.scss b/ui/analyse/css/build/analyse.study.transp.scss new file mode 100644 index 0000000000..a42bb68298 --- /dev/null +++ b/ui/analyse/css/build/analyse.study.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'analyse.study'; diff --git a/ui/analyse/css/build/analyse.zh.dark.scss b/ui/analyse/css/build/analyse.zh.dark.scss new file mode 100644 index 0000000000..bcd659166f --- /dev/null +++ b/ui/analyse/css/build/analyse.zh.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'analyse.zh'; diff --git a/ui/analyse/css/build/analyse.zh.light.scss b/ui/analyse/css/build/analyse.zh.light.scss new file mode 100644 index 0000000000..4be5199aa9 --- /dev/null +++ b/ui/analyse/css/build/analyse.zh.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'analyse.zh'; diff --git a/ui/analyse/css/build/analyse.zh.transp.scss b/ui/analyse/css/build/analyse.zh.transp.scss new file mode 100644 index 0000000000..3f2fa624d6 --- /dev/null +++ b/ui/analyse/css/build/analyse.zh.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'analyse.zh'; diff --git a/ui/analyse/css/build/study.create.dark.scss b/ui/analyse/css/build/study.create.dark.scss new file mode 100644 index 0000000000..bd1cfb0773 --- /dev/null +++ b/ui/analyse/css/build/study.create.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'study.create'; diff --git a/ui/analyse/css/build/study.create.light.scss b/ui/analyse/css/build/study.create.light.scss new file mode 100644 index 0000000000..81befbd958 --- /dev/null +++ b/ui/analyse/css/build/study.create.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'study.create'; diff --git a/ui/analyse/css/build/study.create.transp.scss b/ui/analyse/css/build/study.create.transp.scss new file mode 100644 index 0000000000..012a026313 --- /dev/null +++ b/ui/analyse/css/build/study.create.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'study.create'; diff --git a/ui/analyse/css/build/study.index.dark.scss b/ui/analyse/css/build/study.index.dark.scss new file mode 100644 index 0000000000..a6bfcb197a --- /dev/null +++ b/ui/analyse/css/build/study.index.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'study.index'; diff --git a/ui/analyse/css/build/study.index.light.scss b/ui/analyse/css/build/study.index.light.scss new file mode 100644 index 0000000000..7054d771b9 --- /dev/null +++ b/ui/analyse/css/build/study.index.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'study.index'; diff --git a/ui/analyse/css/build/study.index.transp.scss b/ui/analyse/css/build/study.index.transp.scss new file mode 100644 index 0000000000..4679cc68bc --- /dev/null +++ b/ui/analyse/css/build/study.index.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'study.index'; diff --git a/ui/analyse/css/embed/_embed.scss b/ui/analyse/css/embed/_embed.scss new file mode 100644 index 0000000000..fdb8cd103d --- /dev/null +++ b/ui/analyse/css/embed/_embed.scss @@ -0,0 +1,26 @@ +/* embed a game replay */ + +$mq-col1: 9999px; + +%border-bottom-active { + border-bottom: 3px solid $c-secondary; +} + +@import '../tools'; +@import '../action-menu'; +@import 'layout'; +@import 'footer'; +@import 'not-found'; + +.chapter-name { + @extend %roboto; + padding: .3em; + border-bottom: $border; + background: $c-bg-zebra; + text-align: center; +} + +.cg-board { + border-radius: 0; + box-shadow: none; +} diff --git a/ui/analyse/css/embed/_footer.scss b/ui/analyse/css/embed/_footer.scss new file mode 100644 index 0000000000..a27249476b --- /dev/null +++ b/ui/analyse/css/embed/_footer.scss @@ -0,0 +1,27 @@ +footer { + @extend %flex-center-nowrap, %metal; + font-size: .9em; + border: $border; + border-top: none; + height: 2.5rem; + padding: 0 2vw; + .left { + @extend %nowrap-ellipsis; + flex: 1 1 100%; + } + h1 { + @extend %base-font; + display: inline; + font-size: 1em; + } + .open { + flex: 0 0 auto; + } + > * { + opacity: .8; + @include transition(); + } + &:hover > * { + opacity: 1; + } +} diff --git a/ui/analyse/css/embed/_layout.scss b/ui/analyse/css/embed/_layout.scss new file mode 100644 index 0000000000..5b70448ad2 --- /dev/null +++ b/ui/analyse/css/embed/_layout.scss @@ -0,0 +1,13 @@ +.analyse { + + &__board { grid-area: board; } + &__tools { grid-area: tools; } + &__controls { grid-area: controls; } + + display: grid; + grid-template-columns: minmax(200px, calc(100vh - 2.5rem)) minmax(200px, 1fr); + grid-template-rows: auto 2.5rem; + grid-template-areas: + 'board tools' + 'board controls' +} diff --git a/ui/analyse/css/embed/_not-found.scss b/ui/analyse/css/embed/_not-found.scss new file mode 100644 index 0000000000..cdacc08190 --- /dev/null +++ b/ui/analyse/css/embed/_not-found.scss @@ -0,0 +1,18 @@ +.not-found { + @extend %flex-center; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + justify-content: center; + height: 100%; + background: radial-gradient(circle, #484848, #2F3031); + h1 { + @extend %roboto; + font-size: 7vw; + text-align: center; + color: rgba(255,255,255,0.3); + text-shadow: 0 0 9px rgba(0,0,0,0.3); + } +} diff --git a/ui/analyse/css/gamebook/_edit.scss b/ui/analyse/css/gamebook/_edit.scss new file mode 100644 index 0000000000..30c9274d54 --- /dev/null +++ b/ui/analyse/css/gamebook/_edit.scss @@ -0,0 +1,60 @@ +.study__buttons { + align-items: stretch; + .right { + @extend %flex-center; + align-items: stretch; + justify-content: flex-end; + } + .preview { + @extend %flex-center-nowrap, %box-radius-top; + padding: 0 .5em; + } +} + +.gamebook-edit { + @extend %flex-column; + background: $c-bg-low; + .deviation, + .hint { + @extend %flex-column; + } + label { + display: block; + padding: 0 0 8px 10px; + } + .hint textarea { + height: 7em; + } + .legend { + display: flex; + border-bottom: $border; + min-height: 3.5em; + i { + @extend %flex-center; + flex: 0 0 1.8em; + font-size: 1.8em; + opacity: 0.7; + justify-content: center; + } + &.clickable:hover { + cursor: pointer; + background: $c-primary; + color: $c-primary-over; + i { + opacity: 0.9; + } + } + p { + @extend %flex-center; + flex: 1 1 100%; + padding: 8px 10px; + } + } + .todo i { + background: $c-bad; + color: $c-bad-over; + } + .done i { + background: $c-good; + } +} diff --git a/ui/analyse/css/gamebook/_play.scss b/ui/analyse/css/gamebook/_play.scss new file mode 100644 index 0000000000..fe476ee4da --- /dev/null +++ b/ui/analyse/css/gamebook/_play.scss @@ -0,0 +1,175 @@ +@keyframes rubberBand { + from { transform: scale3d(1, 1, 1); } + 6% { transform: scale3d(1.25, 0.75, 1); } + 8% { transform: scale3d(0.75, 1.25, 1); } + 10% { transform: scale3d(1.15, 0.85, 1); } + 13% { transform: scale3d(.95, 1.05, 1); } + 15% { transform: scale3d(1.05, .95, 1); } + 20% { transform: scale3d(1, 1, 1); } +} +.gamebook { + @extend %flex-column; + grid-area: tools; + justify-content: flex-end; + .comment { + @extend %flex-column, %box-shadow; + font-size: 1.1em; + background: $c-bg-box; + border-radius: 1rem; + position: relative; + /* fixes firefox overflow when comment is long https://stackoverflow.com/questions/28636832/firefox-overflow-y-not-working-with-nested-flexbox */ + min-height: 0; + @if $theme-dark { + border: 1px solid $c-font-dimmer; + } + &::after { + position: absolute; + content: ''; + bottom: -9px; + right: 20%; + width: 15px; + height: 15px; + background: $c-bg-box; + border-right: 1px solid $c-font-dimmer; + border-bottom: 1.5px solid $c-font-dimmer; + transform: skew(45deg) rotate(45deg); + z-index: 1; + } + &.hinted::after { + background: $c-primary; + } + .content { + z-index: 2; + overflow-y: auto; + padding: 1em; + min-height: 2.5em; + } + div.hint { + padding: .8em 1em; + background: $c-primary; + color: $c-primary-over; + border-radius: 0 0 1rem 1rem; + cursor: pointer; + font-size: .9em; + z-index: 2; + } + a.hint { + padding: .8em 1em; + color: $c-primary; + font-size: 1rem; + } + } + + .floor { + margin-top: 1em; + flex: 0 0 8rem; + display: flex; + } + .mascot { + flex: 0 0 8rem; + margin-left: 1em; + } + .feedback { + @extend %flex-column, %box-radius; + flex: 1 1 100%; + height: 8rem; + text-align: center; + justify-content: center; + &.info { + font-size: 1.6em; + } + &.good.init { + visibility: hidden; + } + &.act { + @extend %box-neat; + font-size: 2em; + color: #fff; + cursor: pointer; + opacity: 0.85; + @include transition(); + &:hover { + opacity: 1; + } + &.com span { + animation: rubberBand 7s infinite; + } + } + &.play { + font-size: 0.8em; + text-align: left; + } + &.play strong { + font-size: 1.5em; + } + &.play > div { + display: flex; + align-items: center; + margin: 0 10px; + } + &.play .no-square { + flex: 0 0 64px; + height: 64px; + margin-right: 10px; + } + .instruction > * { + display: block; + } + .is3d &.play div.no-square { + height: 82px; + } + &.play piece { + position: inherit; + display: block; + width: 100%; + height: 100%; + } + &.bad { + background: #dc322f; + } + &.good { + background: #639B24!important; + color: #fff; + } + &.end { + flex-flow: row; + font-size: .8em; + a { + @extend %flex-column; + flex: 1 1 100%; + background: mix($c-primary, $c-bg-box, 80%); + color: $c-primary-over; + font-size: 1.2em; + align-items: center; + justify-content: center; + text-align: center; + padding: .5em; + border-left: 1px solid rgba(255,255,255,0.3); + line-height: 1.2em; + @include transition(); + &::before { + font-size: 2.2em; + margin: .5em 0; + } + &:first-child { + @extend %box-radius-left; + } + &:last-child { + @extend %box-radius-right; + } + &:hover { + background: $c-primary; + } + } + } + } +} +.gamebook-buttons { + @extend %flex-center; + justify-content: flex-end; + .fbt { + @extend %box-radius-top; + padding: .2em .5em; + margin-left: .7em; + } +} diff --git a/ui/analyse/css/practice/_layout.scss b/ui/analyse/css/practice/_layout.scss new file mode 100644 index 0000000000..eb4b967c99 --- /dev/null +++ b/ui/analyse/css/practice/_layout.scss @@ -0,0 +1,36 @@ +.analyse { + + .practice__side { + grid-area: side; + margin-top: $block-gap; + } + + &__acpl { + display: none; + } + + grid-template-rows: auto; + grid-template-areas: + 'board' + 'controls' + 'under' + 'tools' + 'side'; + + @include breakpoint($mq-col2) { + grid-template-areas: + 'board gauge tools' + 'under . controls' + 'side . .'; + } + + @include breakpoint($mq-col3) { + grid-template-rows: fit-content(0); + grid-template-areas: + 'side . board gauge tools' + '. . under . controls'; + .practice__side { + margin-top: 0; + } + } +} diff --git a/ui/analyse/css/practice/_show.scss b/ui/analyse/css/practice/_show.scss new file mode 100644 index 0000000000..875003bb49 --- /dev/null +++ b/ui/analyse/css/practice/_show.scss @@ -0,0 +1,7 @@ +@import '../analyse.base'; +@import '../study/chapter-desc'; +@import '../study/player'; +@import '../../../site/css/practice/icons'; +@import 'layout'; +@import 'side'; +@import 'underboard'; diff --git a/ui/analyse/css/practice/_side.scss b/ui/analyse/css/practice/_side.scss new file mode 100644 index 0000000000..5e20639087 --- /dev/null +++ b/ui/analyse/css/practice/_side.scss @@ -0,0 +1,77 @@ +.practice__side { + @extend %box-neat-force, %flex-column; + background: $c-bg-box; + &__title { + @extend %flex-center-nowrap, %nowrap-hidden; + flex: 0 0 auto; + padding: .7em; + background: $c-primary; + color: $c-primary-over; + i { + flex: 0 0 3.5em; + height: 3.5em; + margin-right: .6rem; + opacity: .9; + } + h1 { + font-size: 1.2em; + margin: 0; + } + em { + font-size: 0.9em; + opacity: 0.9; + } + } + &__chapters { + flex: 1 1 auto; + overflow-y: auto; + } + .finally { + @extend %flex-center-nowrap; + flex: 0 0 auto; + padding: .7em .7em .7em 0; + background: $c-bg-low; + font-size: .9em; + .back { + flex: 0 0 2.5rem; + text-align: center; + margin-right: .3rem; + font-size: 1.25em; + } + select { + flex: 1 1 auto; + } + } +} +.ps__chapter { + @extend %flex-center-nowrap; + border-bottom: $border; + align-items: stretch; + color: $c-font; + @include transition(); + h3 { + @extend %flex-center; + padding: .5rem 0 .5rem .3rem; + } + .status { + @extend %flex-center; + flex: 0 0 2.5rem; + justify-content: center; + opacity: 1; + font-size: 1.25em; + color: $c-shade; + &.done { + color: $c-primary; + } + } + &:hover { + background: mix($c-primary, $c-bg-box, 10%); + } + &.active { + background: mix($c-primary, $c-bg-box, 10%); + .status { + background: $c-primary; + color: $c-primary-over; + } + } +} diff --git a/ui/analyse/css/practice/_underboard.scss b/ui/analyse/css/practice/_underboard.scss new file mode 100644 index 0000000000..233b71bd2c --- /dev/null +++ b/ui/analyse/css/practice/_underboard.scss @@ -0,0 +1,62 @@ +@keyframes soft-bright { + 50%{ + filter: brightness(1.2); + } +} +.feedback { + @extend %box-neat; + display: flex; + background: $c-bg-box; + justify-content: center; + &.win, + &.fail { + padding: 2em 1.5em; + background: $c-good; + color: $c-good-over; + animation: 1.7s soft-bright ease-in-out infinite; + opacity: .8; + @include transition(); + } + &.fail { + background: $c-bad; + } + &:hover { + opacity: 1; + } + span { + margin-right: 1em; + } + &.ongoing { + align-items: flex-start; + flex-flow: column; + text-align: left; + padding: 1em 1.5em; + } + .goal { + margin-bottom: .8em; + text-align: center; + font-size: 1.2em; + width: 100%; + margin-bottom: 10px; + } + .comment { + width: 100%; + display: block; + iframe { + margin: 10px 0; + } + } +} + +.analyse__underboard { + .setting { + @extend %flex-center; + margin-top: 1em; + > label { + order: 1; + flex: 1 0; + cursor: pointer; + margin-left: .8em; + } + } +} diff --git a/ui/analyse/css/study/_buttons.scss b/ui/analyse/css/study/_buttons.scss new file mode 100644 index 0000000000..a43fa107c9 --- /dev/null +++ b/ui/analyse/css/study/_buttons.scss @@ -0,0 +1,51 @@ +$c-study-button: $c-accent; + +.study__buttons { + @extend %flex-between; + border-bottom: 2px solid $c-border; + span { + font-size: 1.15em; + min-width: 0; + } + .left-buttons { + flex: 9 1 auto; + justify-content: flex-start; + border-bottom: 0; + } + .right { + flex: 1 9 10%; + } + .behind { + background: $c-bad; + color: $c-bad-over; + padding: 0 5px; + border-radius: 9px; + margin-right: 4px; + } + .mode { + @extend %flex-center-nowrap, %box-radius-top, %page-text; + align-self: stretch; + padding: 0 .4em; + opacity: .8; + i::before { + font-size: 1.4em; + content: 'L'; + color: $c-bad; + margin-right: .2rem; + } + &.on i::before { + content: 'E'; + color: $c-good; + } + &:hover { + background: $c-bg-zebra; + opacity: 1; + } + } +} + +/* reused by context menu */ +.glyph-icon::before { + content: '⁉'; + font-size: 1.2em; +} diff --git a/ui/analyse/css/study/_chapter-desc.scss b/ui/analyse/css/study/_chapter-desc.scss new file mode 100644 index 0000000000..b08f8cfefd --- /dev/null +++ b/ui/analyse/css/study/_chapter-desc.scss @@ -0,0 +1,42 @@ +.chapter-desc { + @extend %box-neat; + background: $c-bg-box; + padding: .7em 1em; + position: relative; + &.empty { + text-align: center; + .button { + display: inline-block; + margin: 2em auto; + } + } + .contrib { + @extend %popup-shadow; + position: absolute; + top: 0; + right: 0; + background: mix($c-accent, $c-bg-box, 10%); + padding: .5em .8em; + display: none; + z-index: 1; + } + &:hover .contrib { + display: block; + } + .contrib a { + margin-left: 8px; + } + .embed { + @extend %video; + } +} +.chapter-desc-form { + .title { + @extend %flex-between; + width: 100%; + } + textarea { + width: 100%; + height: 12em; + } +} diff --git a/ui/analyse/css/study/_chapters.scss b/ui/analyse/css/study/_chapters.scss new file mode 100644 index 0000000000..c6542ae6ae --- /dev/null +++ b/ui/analyse/css/study/_chapters.scss @@ -0,0 +1,47 @@ +$span-width: 1.7em; + +.study__chapters { + @extend %study-list; + max-height: 18em; + h3 { + @extend %break-word; + flex: 1 1 100%; + font-size: 1em; + line-height: 1; + margin: .5em 0; + align-self: center; + } + > div { + cursor: pointer; + &.active, + &:active { + color: $c-font-clear; + > span { + color: $c-primary-over; + background: $c-primary; + } + } + > span { + @extend %flex-center; + flex: 0 0 $span-width; + justify-content: center; + color: $c-link; + font-weight: bold; + height: auto; + margin-right: .4em; + opacity: .8; + } + } + .ddloader { + width: $span-width; + height: $span-width; + } + .sortable-ghost { + opacity: .7; + &, + .status { + background: $c-secondary!important; + color: $c-secondary-over!important; + } + } +} diff --git a/ui/analyse/css/study/_create.scss b/ui/analyse/css/study/_create.scss new file mode 100644 index 0000000000..f1b6ceffba --- /dev/null +++ b/ui/analyse/css/study/_create.scss @@ -0,0 +1,33 @@ +.study-create { + form h2 { + font-size: 1.6em; + margin-bottom: 1em; + } + button.new { + margin: 1.5em auto; + display: block; + font-size: 2em; + } + + .studies { + display: flex; + flex-flow: row nowrap; + + > div { + flex: 0 1 50%; + overflow: hidden; + &:last-child { + margin-left: 20px; + } + } + + button { + width: 100%; + text-align: left; + overflow: hidden; + margin-bottom: 3px; + text-transform: none; + background: mix($c-link, #000, 70%); + } + } +} diff --git a/ui/analyse/css/study/_editor.scss b/ui/analyse/css/study/_editor.scss new file mode 100644 index 0000000000..bb5a22d2bd --- /dev/null +++ b/ui/analyse/css/study/_editor.scss @@ -0,0 +1,45 @@ +@import '../../../editor/css/spare'; +@import '../../../editor/css/tools'; + +.board-editor-wrap { + min-height: 280px; + margin-bottom: 2em; + .spinner { + padding-top: 90px; + } +} + +.board-editor { + display: grid; + grid-template-columns: 280px 2vmin 210px; + grid-template-rows: min-content auto min-content; + grid-template-areas: + '. . e-tools' + 'spare-top . e-tools' + 'e-board . e-tools' + 'spare-bottom . e-tools' + '. . e-tools'; + user-select: none; + .main-board { + grid-area: e-board; + } + .cg-board { + cursor: inherit; + } + &__tools { + grid-area: e-tools; + } + .spare { + &-top { + margin-bottom: 1vh; + } + &-bottom { + grid-area: spare-bottom; + margin-top: 1vh; + } + } + .metadata { + background: $c-bg-zebra; + font-size: .9em; + } +} diff --git a/ui/analyse/css/study/_index.scss b/ui/analyse/css/study/_index.scss new file mode 100644 index 0000000000..89aaf9cf5b --- /dev/null +++ b/ui/analyse/css/study/_index.scss @@ -0,0 +1,78 @@ +@import 'list-widget'; + +$top-height: 3.2rem; + +.study-index { + .box__top { + @extend %flex-center; + + /* flex gutters, waiting for row-gap to be implemented for flexbox. https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Mastering_Wrapping_of_Flex_Items#Creating_gutters_between_items */ + margin: 0 0 -1em -1em; + > * { margin: 0 0 1em 1em; } + /* end of flex gutter hack */ + + .search { + flex: 3 1 auto; + display: flex; + input { + @extend %box-radius-left; + flex: 1 1 100%; + height: $top-height; + font-size: 1.1em; + @include breakpoint($mq-xx-small) { + font-size: 1.2em; + } + } + .button { + @extend %box-radius-right; + padding: 0 1.5em; + border-left: 0; + } + } + .mselect { + flex: 1 1 auto; + font-size: 1.2em; + &__label::after { + margin-left: .6em; + } + } + .new-study, + .mselect { + height: $top-height; + margin-left: 1rem; + white-space: nowrap; + } + .mselect__label { + height: 100%; + } + .new-study .button { + height: $top-height; + padding: 0 1em; + &::before { + font-size: 2em; + } + } + } + .list { + border-top: $border; + } + .nostudies { + text-align: center; + margin: 40px 0 80px; + font-size: 2em; + p { + opacity: 0.6; + } + i { + display: block; + font-size: 180px; + opacity: 0.4; + } + form { + margin-top: 20px; + } + } + #infscr-loading { + width: 100%; + } +} diff --git a/ui/analyse/css/study/_invite.scss b/ui/analyse/css/study/_invite.scss new file mode 100644 index 0000000000..707d1961c9 --- /dev/null +++ b/ui/analyse/css/study/_invite.scss @@ -0,0 +1,33 @@ +.study__invite { + > div { + overflow: visible !important; // required by user autocomplete + } + .info { + @extend %box-radius, %flex-center-nowrap; + background: $c-accent; + color: $c-primary-over; + padding: 1em; + margin-bottom: 1em; + text-align: left; + &::before { + font-size: 3.6em; + margin-right: 1rem; + } + } + .users { + @extend %flex-between; + margin-bottom: 2em; + .button { + @extend %ellipsis; + flex: 0 0 48%; + margin-bottom: .7em; + text-transform: none; + } + } + .input-wrapper { + overflow: visible!important; + } + .tt-menu { + text-align: left; + } +} diff --git a/ui/analyse/css/study/_layout.scss b/ui/analyse/css/study/_layout.scss new file mode 100644 index 0000000000..82f1299d2e --- /dev/null +++ b/ui/analyse/css/study/_layout.scss @@ -0,0 +1,3 @@ +.analyse__underboard { + margin-top: #{$block-gap / 2}; +} diff --git a/ui/analyse/css/study/_list-widget.scss b/ui/analyse/css/study/_list-widget.scss new file mode 100644 index 0000000000..eda2553891 --- /dev/null +++ b/ui/analyse/css/study/_list-widget.scss @@ -0,0 +1,71 @@ +$c-study: $c-primary; + +.studies { + display: grid; + grid-template-columns: repeat(auto-fill, minmax($viewport-min-width, 1fr)); + @include breakpoint($mq-medium) { + grid-template-columns: repeat(auto-fill, minmax(45ch, 1fr)); + } + .study { + position: relative; + border: $border; + border-width: 0 1px 1px 0; + padding: 1em .6em 1em 1.3em; + overflow: hidden; + @include transition(); + .overlay { + @extend %link-overlay; + } + .body { + display: flex; + font-size: .9em; + } + .chapters { + flex: 0 0 58%; + max-width: 58%; + } + .members { + flex: 0 0 40%; + max-width: 40%; + margin-left: 2%; + } + li { + @extend %nowrap-ellipsis; + color: $c-font-dim; + &::before { + color: $c-font-dimmer; + } + } + .top { + @extend %flex-center-nowrap, %break-word, %roboto; + .study-name { + @extend %nowrap-ellipsis; + font-size: 1.5em; + font-weight: normal; + color: $c-study; + display: block; + margin: 0; + } + span { + font-size: .9rem; + display: block; + color: $c-font-dim; + } + &::before { + color: mix($c-link, $c-bg-box, 80%); + font-size: 4em; + margin-right: .2em; + @include transition(); + @include breakpoint($mq-not-xx-small) { + display: none; + } + } + } + &:hover { + background: mix($c-study, $c-bg-box, 10%); + .top::before { + color: mix($c-link, $c-bg-box, 100%); + } + } + } +} diff --git a/ui/analyse/css/study/_list.scss b/ui/analyse/css/study/_list.scss new file mode 100644 index 0000000000..941a749938 --- /dev/null +++ b/ui/analyse/css/study/_list.scss @@ -0,0 +1,43 @@ +%study-list { + @extend %box-neat; + @include hoverflow; + max-height: 18em; + background: $c-bg-box; + overflow: hidden; + overflow-y: auto; + position: relative; + user-select: none; + > div { + @extend %flex-between-nowrap; + align-items: stretch; + @include transition(); + &:hover, + &.active { + color: $c-font-clear; + background: mix($c-link, $c-bg-box, 10%); + } + } + act { + @extend %flex-center; + cursor: pointer; + border-radius: 99px; + align-self: center; + justify-content: center; + font-size: .9em; + opacity: 0.15; + padding: .4em; + @include transition(); + } + > div:hover act { + opacity: .7; + &:hover { + background: $c-primary; + color: $c-primary-over; + opacity: 1; + } + } + .add { + cursor: pointer; + text-transform: uppercase; + } +} diff --git a/ui/analyse/css/study/_members.scss b/ui/analyse/css/study/_members.scss new file mode 100644 index 0000000000..c6e97d7b1a --- /dev/null +++ b/ui/analyse/css/study/_members.scss @@ -0,0 +1,87 @@ +.study__members { + @extend %study-list; + .left { + @extend %flex-center-nowrap; + align-items: stretch; + flex: 0 1 auto; + overflow: hidden; + } + .user-link { + @extend %ellipsis; + margin: .5em 0; + } + .status { + @extend %flex-center; + justify-content: center; + width: 2.4em; + margin-right: .1em; + transition: 2.5s; + } + i { + font-size: 1.2em; + opacity: 0.5; + transition: 2.5s; + } + .contrib i { + opacity: 0.7; + } + .online i { + opacity: 0.8; + color: $c-good; + } + .online.contrib i { + opacity: 1; + } + > div:nth-child(4n-3) .status.active { + background: #42a5f5; + } + > div:nth-child(4n-2) .status.active { + background: #f44336; + } + > div:nth-child(4n-1) .status.active { + background: #fdd835; + } + > div:nth-child(4n-0) .status.active { + background: #4caf50; + } + .status.active { + transition: none; + i { + transition: none; + opacity: 1; + color: #fff; + } + } + .leave { + color: $c-bad; + opacity: .7; + } + > div:hover .leave:hover { + background-color: $c-bad; + } + .add { + @extend %roboto; + &:hover i { + color: $c-link; + opacity: 1; + transition: none; + } + } + + m-config, .editing { + background: mix($c-accent, $c-bg-box, 10%)!important; + } + m-config { + @extend %flex-between; + padding: .4em .8em 1em .8em; + .role { + @extend %flex-center; + label { + cursor: pointer; + } + } + .switch { + margin-right: .5em; + } + } +} diff --git a/ui/analyse/css/study/_modal.scss b/ui/analyse/css/study/_modal.scss new file mode 100644 index 0000000000..6f30d3aecf --- /dev/null +++ b/ui/analyse/css/study/_modal.scss @@ -0,0 +1,59 @@ +.study__modal { + + &#modal-wrap { + padding: 1rem; + min-width: 80vw; + @include breakpoint($mq-x-small) { + min-width: 500px; + } + } + + > div { + padding: 1rem; + overflow-y: auto; + } + + .form3 { + text-align: left; + .editor { + margin: -30px 0 30px 0; + .spinner { + padding-top: 80px; + } + } + } + h2 { + margin-bottom: .5em; + i { + font-size: .6em; + &, &::before { + vertical-align: top; + } + margin-left: 1rem; + opacity: .5; + cursor: pointer; + &:hover { + opacity: .7; + color: $c-primary; + } + } + } + .destructive { + text-align: left; + font-size: .9em; + form { + display:inline-block; + } + button { + opacity: 0.5; + &:hover { + opacity: 1; + } + } + overflow: hidden; + } + + &.chapter-new .tabs-horiz { + margin: -1em 0 1.6em 0; + } +} diff --git a/ui/analyse/css/study/_player.scss b/ui/analyse/css/study/_player.scss new file mode 100644 index 0000000000..6a109ef940 --- /dev/null +++ b/ui/analyse/css/study/_player.scss @@ -0,0 +1,66 @@ +$player-height: 1.6rem; + +.analyse.has-players { + .cg-board { + border-radius: 0; + } + @include breakpoint($mq-col2) { + .analyse__underboard { + margin-top: calc(#{$player-height / 2} + #{$block-gap / 2}); + } + } + @include breakpoint($mq-col1) { + .analyse__controls { + margin-top: $player-height; + } + } +} + +.study__player { + @extend %flex-between-nowrap, %metal, %box-shadow; + position: absolute; + left: 0; + right: 0; + font-weight: bold; + height: $player-height; + &-top { + @extend %box-radius-top; + top: #{-$player-height}; + } + &-bot { + @extend %box-radius-bottom; + bottom: #{-$player-height}; + } + .left { + flex: 1 1 100%; + display: flex; + } + .result { + flex: 0 0 auto; + margin-left: .8em; + padding-right: .8em; + border-right: $border; + } + .analyse__clock { + @extend %roboto, %flex-center-nowrap; + align-self: stretch; + font-size: 1.2em; + padding: 0 .8em; + border-radius: 0 4px 0 0; + } + &-bot .analyse__clock { + border-radius: 0 0 4px 0; + } + &.ticking .analyse__clock { + background: $c-secondary; + color: $c-secondary-over; + text-shadow: none; + } + .info { + margin-left: 10px; + } + .elo { + margin-left: 0.5em; + font-weight: normal; + } +} diff --git a/ui/analyse/css/study/_show.scss b/ui/analyse/css/study/_show.scss new file mode 100644 index 0000000000..0ba7ce86a5 --- /dev/null +++ b/ui/analyse/css/study/_show.scss @@ -0,0 +1,20 @@ +@import '../analyse.base'; +@import '../acpl'; + +@import 'layout'; +@import 'list'; +@import 'chapters'; +@import 'members'; +@import 'player'; +@import 'modal'; +@import 'editor'; +@import 'buttons'; +@import 'invite'; +@import 'chapter-desc'; +@import 'panel/metadata'; +@import 'panel/comment'; +@import 'panel/glyph'; +@import 'panel/share'; +@import 'panel/multiboard'; +@import 'panel/server-eval'; +@import 'panel/message'; diff --git a/ui/analyse/css/study/panel/_comment.scss b/ui/analyse/css/study/panel/_comment.scss new file mode 100644 index 0000000000..cb8c83ace0 --- /dev/null +++ b/ui/analyse/css/study/panel/_comment.scss @@ -0,0 +1,38 @@ +.study__comments { + form p { + margin: 1em 0; + } + #comment-text { + @extend %box-shadow; + height: 12em; + } +} +.study__comment { + @extend %box-neat; + background: $c-bg-box; + padding: .8em 1em; + margin-bottom: .8em; + .text { + @extend %break-word; + margin-top: .3em; + width: 100%; + overflow: hidden; + display: inline-block; + } + .edit { + float: right; + margin-left: 8px; + opacity: 0.7; + display: none; + } + &:hover .edit { + display: block; + } + .edit:hover { + opacity: 1; + } + .user-link, + .node { + font-weight: bold; + } +} diff --git a/ui/analyse/css/study/panel/_glyph.scss b/ui/analyse/css/study/panel/_glyph.scss new file mode 100644 index 0000000000..657afd5d74 --- /dev/null +++ b/ui/analyse/css/study/panel/_glyph.scss @@ -0,0 +1,40 @@ +.study__glyphs { + @extend %box-neat, %flex-center; + background: $c-bg-box; + white-space: nowrap; + user-select: none; + > div { + flex: 1 0 30%; + } + a { + @extend %flex-center-nowrap; + @include transition(); + color: $c-font; + height: 2.3em; + line-height: 2.3em; + align-items: stretch; + &::before { + @extend %flex-center; + justify-content: center; + content: attr(data-symbol); + font-size: 1.2em; + font-weight: bold; + width: 2em; + background: $c-bg-low; + margin-right: .5em; + @include transition(); + } + &:hover, + &.active { + background: $c-bg-zebra; + color: $c-secondary; + } + &:hover::before { + background: $c-bg-zebra; + } + &.active::before { + background: $c-secondary; + color: $c-secondary-over; + } + } +} diff --git a/ui/analyse/css/study/panel/_message.scss b/ui/analyse/css/study/panel/_message.scss new file mode 100644 index 0000000000..ca009a1f42 --- /dev/null +++ b/ui/analyse/css/study/panel/_message.scss @@ -0,0 +1,13 @@ +.study__message { + @extend %box-neat; + background: $c-bg-box; + padding: 3em; + text-align: center; + .button { + display: inline-block; + margin: 1em auto; + } + .spinner { + margin: 50px auto; + } +} diff --git a/ui/analyse/css/study/panel/_metadata.scss b/ui/analyse/css/study/panel/_metadata.scss new file mode 100644 index 0000000000..732f85b619 --- /dev/null +++ b/ui/analyse/css/study/panel/_metadata.scss @@ -0,0 +1,60 @@ +.study__metadata { + @extend %box-neat; + background: $c-bg-box; + text-align: left; + h2 { + @extend %metal, %flex-between-nowrap; + font-size: 1.3em; + padding: .8rem 1rem; + white-space: nowrap; + border-bottom: $border; + .name { + @extend %ellipsis; + } + .liking { + margin-left: 1rem; + font-weight: bold; + cursor: pointer; + opacity: 0.7; + transition: 0.3s; + } + .liking:hover { + opacity: 1; + color: $c-red; + } + } +} + +.study__tags { + border: none; + th { + font-weight: bold; + color: $c-font-dim; + width: 1px; + padding: 0 .3em 0 1em!important; + } + td { + padding: 0; + } + input, + span { + display: block; + padding: .6em 1em .6em .7em; + line-height: 1.7; + } + input { + border: none; + background: none; + width: 100%; + } + input:hover, + input:focus { + background: mix($c-primary, $c-bg-box, 10%); + } + select { + cursor: pointer; + border: none; + background: none; + padding: 0; + } +} diff --git a/ui/analyse/css/study/panel/_multiboard.scss b/ui/analyse/css/study/panel/_multiboard.scss new file mode 100644 index 0000000000..a4d61d56f2 --- /dev/null +++ b/ui/analyse/css/study/panel/_multiboard.scss @@ -0,0 +1,72 @@ +.study__multiboard { + @extend %box-neat; + background: $c-bg-box; + &.loading { + opacity: 0.7; + } + &.nopager { + padding: 2em; + } + .top { + @extend %flex-between; + padding: .4em 1.5em; + } + .pager { + @extend %flex-center; + .page { + margin: 0 .4em; + } + } + .fbt { + @extend %box-radius; + padding: .6em 1em; + } + .playing { + cursor: pointer; + } + .playing input { + vertical-align: middle; + margin-right: 3px; + } + + .now-playing { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(30%, 1fr)); + a { + @extend %box-radius; + color: $c-font; + padding: .4em; + @include transition(background); + background: fade-out($c-bg-box, 0.6); + overflow: hidden; + &:nth-child(even) { + background: $c-bg-zebra2; + } + &:hover { + background: fade-out($c-link, 0.6); + color: $c-font-clear; + } + &.active, + &:active { + background: $c-secondary; + color: $c-secondary-over; + } + .cg-board { + box-shadow: none; + } + } + .player { + @extend %flex-between-nowrap; + height: 1.5em; + white-space: nowrap; + span { + margin-left: .5em; + } + } + .name { + @extend %flex-center; + justify-content: center; + height: 3em; + } + } +} diff --git a/ui/analyse/css/study/panel/_server-eval.scss b/ui/analyse/css/study/panel/_server-eval.scss new file mode 100644 index 0000000000..7ac43dd26b --- /dev/null +++ b/ui/analyse/css/study/panel/_server-eval.scss @@ -0,0 +1,14 @@ +.study__server-eval { + @extend %box-neat; + background: $c-bg-box; + &.requested { + padding: 4em; + } + &.ready { + height: 15em; + } +} + +.advice-summary table:first-child { + margin-bottom: 1em; +} diff --git a/ui/analyse/css/study/panel/_share.scss b/ui/analyse/css/study/panel/_share.scss new file mode 100644 index 0000000000..7601f1577f --- /dev/null +++ b/ui/analyse/css/study/panel/_share.scss @@ -0,0 +1,26 @@ +.study__share { + @extend %box-neat; + background: $c-bg-box; + padding: 1.5em 1.2em; + input[type="text"] { + font-family: monospace; + width: 100%; + font-size: .9em; + } + .ply-wrap { + color: $c-font-dim; + text-align: left; + font-size: .9em; + } + .ply { + cursor: pointer; + input { + margin-right: .3em; + vertical-align: middle; + } + } + .downloads { + @extend %flex-between; + margin-bottom: 2em; + } +} diff --git a/ui/analyse/css/study/relay/_admin.scss b/ui/analyse/css/study/relay/_admin.scss new file mode 100644 index 0000000000..d660850492 --- /dev/null +++ b/ui/analyse/css/study/relay/_admin.scss @@ -0,0 +1,72 @@ +.analyse__acpl { + display: none; +} +.relay-admin { + grid-area: acpl; + @extend %box-neat, %flex-column; + background: $c-bg-box; + margin-top: $block-gap; + h2 { + @extend %flex-between; + font-size: 1.2em; + padding: .4em .6em; + border-bottom: $border; + } + .state { + @extend %flex-center-nowrap; + border-bottom: $border; + min-height: 3.5em; + @include transition(); + &::before { + @extend %flex-center; + font-size: 1.3em; + margin: 0 .5em 0 .8em; + } + &.clickable:hover { + cursor: pointer; + background: $c-primary; + color: $c-primary-over; + } + > div { + @extend %ellipsis; + } + .fat { + font-size: 1.5em; + text-transform: uppercase; + } + &.off { + background: mix($c-primary, $c-bg-box, 80%); + color: #fff; + } + &.on { + background: $c-good; + color: $c-good-over; + } + } + .time { + font-weight: bold; + } + + .log { + overflow-x: hidden; + overflow-y: auto; + white-space: nowrap; + padding: .3em .7em; + > div { + @extend %flex-center-nowrap; + margin: 4px 0; + &::before { + color: $c-good; + font-size: 1.3em; + margin-right: .5em; + } + } + time { + @extend %roboto; + margin-left: .3em; + } + .err::before { + color: $c-bad; + } + } +} diff --git a/ui/analyse/package.json b/ui/analyse/package.json index b314a66f92..e6d77da7d9 100644 --- a/ui/analyse/package.json +++ b/ui/analyse/package.json @@ -40,7 +40,7 @@ "ceval": "1.0.0", "chat": "2.0.0", "chess": "1.0.0", - "chessground": "^7.3", + "chessground": "^7.5", "common": "1.0.0", "game": "1.0.0", "nvui": "1.0.0", diff --git a/ui/analyse/src/acpl.ts b/ui/analyse/src/acpl.ts index 0ded3e582e..d79e883e13 100644 --- a/ui/analyse/src/acpl.ts +++ b/ui/analyse/src/acpl.ts @@ -1,6 +1,5 @@ import { h, thunk } from 'snabbdom' import { VNode, VNodeData } from 'snabbdom/vnode' -import { MaybeVNode } from './interfaces'; import AnalyseCtrl from './ctrl'; import { findTag } from './study/studyChapters'; import * as game from 'game'; @@ -8,18 +7,18 @@ import { defined } from 'common'; import { bind, dataIcon } from './util'; function renderRatingDiff(rd: number | undefined): VNode | undefined { - if (rd === 0) return h('span.rp.null', '±0'); - if (rd && rd > 0) return h('span.rp.up', '+' + rd); - if (rd && rd < 0) return h('span.rp.down', '−' + (-rd)); + if (rd === 0) return h('span', '±0'); + if (rd && rd > 0) return h('good', '+' + rd); + if (rd && rd < 0) return h('bad', '−' + (-rd)); return; } function renderPlayer(ctrl: AnalyseCtrl, color: Color): VNode { const p = game.getPlayer(ctrl.data, color); - if (p.user) return h('a.user_link.ulpt', { + if (p.user) return h('a.user-link.ulpt', { attrs: { href: '/@/' + p.user.username } }, [ - h('span', p.user.username), + p.user.username, ' ', renderRatingDiff(p.ratingDiff) ]); return h('span', @@ -70,7 +69,7 @@ function playerTable(ctrl: AnalyseCtrl, color: Color): VNode { } function doRender(ctrl: AnalyseCtrl): VNode { - return h('div.advice_summary', { + return h('div.advice-summary', { hook: { insert: vnode => { $(vnode.elm as HTMLElement).on('click', 'tr.symbol', function(this: Element) { @@ -89,14 +88,17 @@ function doRender(ctrl: AnalyseCtrl): VNode { ]); } -export function render(ctrl: AnalyseCtrl): MaybeVNode { +export function render(ctrl: AnalyseCtrl): VNode | undefined { - if (!ctrl.data.analysis || !ctrl.showComputer() || (ctrl.study && ctrl.study.vm.toolTab() !== 'serverEval')) return; + if (ctrl.studyPractice || ctrl.embed) return; + + if (!ctrl.data.analysis || !ctrl.showComputer() || (ctrl.study && ctrl.study.vm.toolTab() !== 'serverEval')) + return h('div.analyse__acpl'); // don't cache until the analysis is complete! const buster = ctrl.data.analysis.partial ? Math.random() : ''; let cacheKey = '' + buster + !!ctrl.retro; if (ctrl.study) cacheKey += ctrl.study.data.chapter.id; - return thunk('div.advice_summary', doRender, [ctrl, cacheKey]); + return h('div.analyse__acpl', thunk('div.advice-summary', doRender, [ctrl, cacheKey])); } diff --git a/ui/analyse/src/actionMenu.ts b/ui/analyse/src/actionMenu.ts index 3c512822d9..8f10e568b5 100644 --- a/ui/analyse/src/actionMenu.ts +++ b/ui/analyse/src/actionMenu.ts @@ -7,7 +7,7 @@ import { AutoplayDelay } from './autoplay'; import { boolSetting, BoolSetting } from './boolSetting'; import AnalyseCtrl from './ctrl'; import { cont as contRoute } from 'game/router'; -import { synthetic, bind, dataIcon } from './util'; +import { bind, dataIcon } from './util'; import * as pgnExport from './pgnExport'; interface AutoplaySpeed { @@ -37,20 +37,20 @@ function deleteButton(ctrl: AnalyseCtrl, userId: string | null): VNode | undefin const g = ctrl.data.game; if (g.source === 'import' && g.importedBy && g.importedBy === userId) - return h('form.delete', { - attrs: { - method: 'post', - action: '/' + g.id + '/delete' - }, - hook: bind('submit', _ => confirm(ctrl.trans.noarg('deleteThisImportedGame'))) - }, [ - h('button.button.text.thin', { + return h('form.delete', { attrs: { - type: 'submit', - 'data-icon': 'q' - } - }, ctrl.trans.noarg('delete')) - ]); + method: 'post', + action: '/' + g.id + '/delete' + }, + hook: bind('submit', _ => confirm(ctrl.trans.noarg('deleteThisImportedGame'))) + }, [ + h('button.button.text.thin', { + attrs: { + type: 'submit', + 'data-icon': 'q' + } + }, ctrl.trans.noarg('delete')) + ]); return; } @@ -62,8 +62,7 @@ function autoplayButtons(ctrl: AnalyseCtrl): VNode { ...(d.analysis ? [cplSpeed] : []) ]; return h('div.autoplay', speeds.map(speed => { - return h('a.fbt', { - class: { active: ctrl.autoplay.active(speed.delay) }, + return h('a.button.button-empty', { hook: bind('click', () => ctrl.togglePlay(speed.delay), ctrl.redraw) }, ctrl.trans.noarg(speed.name)); })); @@ -92,19 +91,14 @@ function hiddenInput(name: string, value: string) { } function studyButton(ctrl: AnalyseCtrl) { - if (ctrl.study && ctrl.embed && !ctrl.ongoing) return h('a.fbt', { + if (ctrl.study && ctrl.embed && !ctrl.ongoing) return h('a.button.button-empty', { attrs: { href: '/study/' + ctrl.study.data.id + '#' + ctrl.study.currentChapter().id, - target: '_blank' + target: '_blank', + 'data-icon': '4' } - }, [ - h('i.icon', { - attrs: dataIcon('4') - }), - ctrl.trans.noarg('openStudy') - ]); - if (ctrl.study || ctrl.ongoing) return; - const realGame = !synthetic(ctrl.data); + }, ctrl.trans.noarg('openStudy')); + if (ctrl.study || ctrl.ongoing || ctrl.embed) return; return h('form', { attrs: { method: 'post', @@ -115,14 +109,16 @@ function studyButton(ctrl: AnalyseCtrl) { if (pgnInput) pgnInput.value = pgnExport.renderFullTxt(ctrl); }) }, [ - realGame ? hiddenInput('gameId', ctrl.data.game.id) : hiddenInput('pgn', ''), + !ctrl.synthetic ? hiddenInput('gameId', ctrl.data.game.id) : hiddenInput('pgn', ''), hiddenInput('orientation', ctrl.chessground.state.orientation), hiddenInput('variant', ctrl.data.game.variant.key), hiddenInput('fen', ctrl.tree.root.fen), - h('button.fbt', { attrs: { type: 'submit' } }, [ - h('i.icon', { attrs: dataIcon('4') }), - 'Study' - ]) + h('button.button.button-empty', { + attrs: { + type: 'submit', + 'data-icon': '4' + } + }, 'Study') ]); } @@ -133,37 +129,29 @@ export class Ctrl { export function view(ctrl: AnalyseCtrl): VNode { const d = ctrl.data, - noarg = ctrl.trans.noarg, - canContinue = !ctrl.ongoing && !ctrl.embed && d.game.variant.key === 'standard', - ceval = ctrl.getCeval(), - mandatoryCeval = ctrl.mandatoryCeval(); + noarg = ctrl.trans.noarg, + canContinue = !ctrl.ongoing && !ctrl.embed && d.game.variant.key === 'standard', + ceval = ctrl.getCeval(), + mandatoryCeval = ctrl.mandatoryCeval(); const tools: MaybeVNodes = [ - h('div.tools', [ - h('a.fbt', { - hook: bind('click', ctrl.flip) - }, [ - h('i.icon', { attrs: dataIcon('B') }), - noarg('flipBoard') - ]), - ctrl.ongoing ? null : h('a.fbt', { + h('div.action-menu__tools', [ + h('a.button.button-empty', { + hook: bind('click', ctrl.flip), + attrs: dataIcon('B') + }, noarg('flipBoard')), + ctrl.ongoing ? null : h('a.button.button-empty', { attrs: { href: d.userAnalysis ? '/editor?fen=' + ctrl.node.fen : '/' + d.game.id + '/edit?fen=' + ctrl.node.fen, rel: 'nofollow', - target: ctrl.embed ? '_blank' : '' + target: ctrl.embed ? '_blank' : '', + 'data-icon': 'm' } - }, [ - h('i.icon', { attrs: dataIcon('m') }), - noarg('boardEditor') - ]), - canContinue ? h('a.fbt', { - hook: bind('click', _ => $.modal($('.continue_with.g_' + d.game.id))) - }, [ - h('i.icon', { - attrs: dataIcon('U') - }), - noarg('continueFromHere') - ]) : null, + }, noarg('boardEditor')), + canContinue ? h('a.button.button-empty', { + hook: bind('click', _ => $.modal($('.continue-with.g_' + d.game.id))), + attrs: dataIcon('U') + }, noarg('continueFromHere')) : null, studyButton(ctrl) ]) ]; @@ -257,44 +245,42 @@ export function view(ctrl: AnalyseCtrl): VNode { ]))('analyse-memory') : null ] : []) : []; - const notationConfig = [ - h('h2', noarg('preferences')), - ctrlBoolSetting({ - name: noarg('inlineNotation'), - title: 'Shift+I', - id: 'inline', - checked: ctrl.treeView.inline(), - change(v) { - ctrl.treeView.set(v); - ctrl.actionMenu.toggle(); - } - }, ctrl) - ]; + const notationConfig = [ + ctrlBoolSetting({ + name: noarg('inlineNotation'), + title: 'Shift+I', + id: 'inline', + checked: ctrl.treeView.inline(), + change(v) { + ctrl.treeView.set(v); + ctrl.actionMenu.toggle(); + } + }, ctrl) + ]; - return h('div.action_menu', - tools - .concat(notationConfig) - .concat(cevalConfig) - .concat(ctrl.mainline.length > 4 ? [h('h2', noarg('replayMode')), autoplayButtons(ctrl)] : []) - .concat([ - deleteButton(ctrl, ctrl.opts.userId), - canContinue ? h('div.continue_with.g_' + d.game.id, [ - h('a.button', { - attrs: { - href: d.userAnalysis ? '/?fen=' + ctrl.encodeNodeFen() + '#ai' : contRoute(d, 'ai') + '?fen=' + ctrl.node.fen, - rel: 'nofollow' - } - }, noarg('playWithTheMachine')), - h('br'), - h('a.button', { - attrs: { - href: d.userAnalysis ? '/?fen=' + ctrl.encodeNodeFen() + '#friend' : contRoute(d, 'friend') + '?fen=' + ctrl.node.fen, - rel: 'nofollow' - } - }, noarg('playWithAFriend')) - ]) : null - ]) - ); + return h('div.action-menu', + tools + .concat(notationConfig) + .concat(cevalConfig) + .concat(ctrl.mainline.length > 4 ? [h('h2', noarg('replayMode')), autoplayButtons(ctrl)] : []) + .concat([ + deleteButton(ctrl, ctrl.opts.userId), + canContinue ? h('div.continue-with.none.g_' + d.game.id, [ + h('a.button', { + attrs: { + href: d.userAnalysis ? '/?fen=' + ctrl.encodeNodeFen() + '#ai' : contRoute(d, 'ai') + '?fen=' + ctrl.node.fen, + rel: 'nofollow' + } + }, noarg('playWithTheMachine')), + h('a.button', { + attrs: { + href: d.userAnalysis ? '/?fen=' + ctrl.encodeNodeFen() + '#friend' : contRoute(d, 'friend') + '?fen=' + ctrl.node.fen, + rel: 'nofollow' + } + }, noarg('playWithAFriend')) + ]) : null + ]) + ); } function ctrlBoolSetting(o: BoolSetting, ctrl: AnalyseCtrl) { diff --git a/ui/analyse/src/boolSetting.ts b/ui/analyse/src/boolSetting.ts index 64d3ac90d9..6be25decf5 100644 --- a/ui/analyse/src/boolSetting.ts +++ b/ui/analyse/src/boolSetting.ts @@ -13,7 +13,7 @@ export interface BoolSetting { export function boolSetting(o: BoolSetting, trans: Trans, redraw: Redraw) { const fullId = 'abset-' + o.id; - return h('div.setting', o.title ? { + return h('div.setting.' + fullId, o.title ? { attrs: { title: trans.noarg(o.title) } } : {}, [ h('label', { attrs: { 'for': fullId } }, trans.noarg(o.name)), diff --git a/ui/analyse/src/boot.js b/ui/analyse/src/boot.js deleted file mode 100644 index b1cb04ee67..0000000000 --- a/ui/analyse/src/boot.js +++ /dev/null @@ -1,189 +0,0 @@ -var defined = require('common').defined; - -module.exports = function(element, cfg) { - var data = cfg.data; - var $watchers = $('#site_header div.watchers').watchers(); - var analyse, $panels; - lichess.socket = lichess.StrongSocket( - data.url.socket, - data.player.version, { - options: { - name: "analyse" - }, - params: { - userTv: data.userTv && data.userTv.id - }, - receive: function(t, d) { - analyse.socketReceive(t, d); - }, - events: { - analysisProgress: function(d) { - var partial = !d.tree.eval; - if (!lichess.advantageChart) startAdvantageChart(); - else if (lichess.advantageChart.update) lichess.advantageChart.update(data, partial); - if (!partial) { - lichess.pubsub.emit('analysis.server.complete')(); - $("#adv_chart_loader").remove(); - } - }, - crowd: function(event) { - $watchers.watchers("set", event.watchers); - } - } - }); - - var $timeChart = $("#movetimes_chart"); - var inputFen = element.querySelector('input.fen'); - var unselect = function(chart) { - chart.getSelectedPoints().forEach(function(point) { - point.select(false); - }); - }; - var lastFen; - - if (!window.lichess.AnalyseNVUI) lichess.pubsub.on('analysis.change', function(fen, path, mainlinePly) { - var chart, point, $chart = $("#adv_chart"); - if (fen && fen !== lastFen) { - inputFen.value = fen; - lastFen = fen; - } - if ($chart.length) { - chart = window.Highcharts && $chart.highcharts(); - if (chart) { - if (mainlinePly != chart.lastPly) { - if (mainlinePly === false) unselect(chart); - else { - point = chart.series[0].data[mainlinePly - 1 - cfg.data.game.startedAtTurn]; - if (defined(point)) point.select(); - else unselect(chart); - } - } - chart.lastPly = mainlinePly; - } - } - if ($timeChart.length) { - chart = window.Highcharts && $timeChart.highcharts(); - if (chart) { - if (mainlinePly != chart.lastPly) { - if (mainlinePly === false) unselect(chart); - else { - var white = mainlinePly % 2 !== 0; - var serie = white ? 0 : 1; - var turn = Math.floor((mainlinePly - 1 - cfg.data.game.startedAtTurn) / 2); - point = chart.series[serie].data[turn]; - if (defined(point)) point.select(); - else unselect(chart); - } - } - chart.lastPly = mainlinePly; - } - } - }); - cfg.onToggleComputer = function(v) { - setTimeout(function() { - if (v) $('div.analysis_menu a.computer_analysis').mousedown(); - else $('div.analysis_menu a:eq(1)').mousedown(); - }, 50); - }; - cfg.trans = lichess.trans(cfg.i18n); - cfg.initialPly = 'url'; - cfg.element = element.querySelector('.analyse'); - cfg.socketSend = lichess.socket.send; - analyse = LichessAnalyse.start(cfg); - cfg.jumpToIndex = analyse.jumpToIndex; - - if (cfg.chat) { - cfg.chat.parseMoves = true; - lichess.makeChat('chat', cfg.chat); - } - - $('.underboard_content', element).appendTo($('.underboard .center', element)).removeClass('none'); - - var chartLoader = function() { - return '
    ' + - '' + lichess.engineName + '
    server analysis
    ' + - lichess.spinnerHtml + - '
    ' - }; - var startAdvantageChart = function() { - if (lichess.advantageChart || lichess.AnalyseNVUI) return; - var loading = !data.treeParts[0].eval || !Object.keys(data.treeParts[0].eval).length; - var $panel = $panels.filter('.computer_analysis'); - if (!$("#adv_chart").length) $panel.html('
    ' + (loading ? chartLoader() : '')); - else if (loading && !$("#adv_chart_loader").length) $panel.append(chartLoader()); - lichess.loadScript('javascripts/chart/acpl.js').then(function() { - lichess.advantageChart(data, cfg.trans, $("#adv_chart")[0]); - }); - }; - - $panels = $('div.analysis_panels > div'); - var $menu = $('div.analysis_menu'); - var storage = lichess.storage.make('analysis.panel'); - var setPanel = function(panel) { - $menu.children('.active').removeClass('active').end().find('.' + panel).addClass('active'); - $panels.removeClass('active').filter('.' + panel).addClass('active'); - if (panel === 'move_times' && !lichess.movetimeChart) try { - lichess.loadScript('javascripts/chart/movetime.js').then(function() { - lichess.movetimeChart(data, cfg.trans); - }); - } catch (e) {} - if (panel === 'computer_analysis' && $("#adv_chart").length) - setTimeout(startAdvantageChart, 200); - }; - $menu.on('mousedown', 'a', function() { - var panel = $(this).data('panel'); - storage.set(panel); - setPanel(panel); - }); - var stored = storage.get(); - if (stored && $menu.children('.' + stored).length) setPanel(stored); - else { - var $ct = $menu.children('.crosstable'); - ($ct.length ? $ct : $menu.children(':first-child')).trigger('mousedown'); - } - if (!cfg.data.analysis) { - $panels.find('form.future_game_analysis').submit(function() { - if ($(this).hasClass('must_login')) { - if (confirm(cfg.trans('youNeedAnAccountToDoThat'))) location.href = '/signup'; - return false; - } - $.ajax({ - method: 'post', - url: $(this).attr('action'), - success: startAdvantageChart, - error: lichess.reload - }); - return false; - }); - } - - $panels.on('click', 'div.pgn', function() { - var range, selection; - if (document.body.createTextRange) { - range = document.body.createTextRange(); - range.moveToElementText($(this)[0]); - range.select(); - } else if (window.getSelection) { - selection = window.getSelection(); - range = document.createRange(); - range.selectNodeContents($(this)[0]); - selection.removeAllRanges(); - selection.addRange(range); - } - }); - $panels.on('click', '.embed_howto', function() { - var url = 'https://lichess.org/embed/' + data.game.id + location.hash; - var iframe = ''; - $.modal($( - '' + $(this).html() + '

    ' + - '
    ' + lichess.escapeHtml(iframe) + '

    ' + - iframe + '

    ' + - '
    Read more about embedding games' - )); - }); - lichess.topMenuIntent(); - if (lichess.isMS) setTimeout(function() { - var prop = 'backgroundImage'; - $('.cg-board').css(prop, $('.cg-board').css(prop).replace(')','?1)')); - }, 1000); -}; diff --git a/ui/analyse/src/boot.ts b/ui/analyse/src/boot.ts new file mode 100644 index 0000000000..441914bb71 --- /dev/null +++ b/ui/analyse/src/boot.ts @@ -0,0 +1,29 @@ +import { AnalyseApi, AnalyseOpts } from './interfaces'; +import { start } from './main'; + +export default function(cfg: AnalyseOpts) { + const li = window.lichess, data = cfg.data; + let analyse: AnalyseApi; + + li.socket = li.StrongSocket( + data.url.socket, + data.player.version, { + options: { + name: 'analyse' + }, + params: { + userTv: data.userTv && data.userTv.id + }, + receive: function(t, d) { + analyse.socketReceive(t, d); + }, + events: { + } + }); + cfg.$side = $('.analyse__side').clone(); + cfg.$underboard = $('.analyse__underboard').clone(); + cfg.trans = li.trans(cfg.i18n); + cfg.initialPly = 'url'; + cfg.socketSend = li.socket.send; + analyse = start(cfg); +}; diff --git a/ui/analyse/src/clocks.ts b/ui/analyse/src/clocks.ts index 4052a6db92..fee6077590 100644 --- a/ui/analyse/src/clocks.ts +++ b/ui/analyse/src/clocks.ts @@ -3,60 +3,49 @@ import { VNode } from 'snabbdom/vnode' import AnalyseCtrl from './ctrl'; import { isFinished } from './study/studyChapters'; -interface ClockOpts { - tenths: boolean; -} - -export default function(ctrl: AnalyseCtrl): VNode | undefined { - const clocks = renderClocks(ctrl); - if (!clocks) return; - if (ctrl.bottomIsWhite()) clocks.reverse(); - return h('div.aclocks', clocks); -} - -export function renderClocks(ctrl: AnalyseCtrl): [VNode, VNode] | undefined { +export default function renderClocks(ctrl: AnalyseCtrl): [VNode, VNode] | undefined { const node = ctrl.node, clock = node.clock; if (!clock && clock !== 0) return; - const parentClock = ctrl.tree.getParentClock(node, ctrl.path), - isWhiteTurn = node.ply % 2 === 0, - centis: Array = [parentClock, clock]; + + const whitePov = ctrl.bottomIsWhite(), + parentClock = ctrl.tree.getParentClock(node, ctrl.path), + isWhiteTurn = node.ply % 2 === 0, + centis: Array = [parentClock, clock]; + if (!isWhiteTurn) centis.reverse(); const study = ctrl.study, - relay = study && study.data.chapter.relay; + relay = study && study.data.chapter.relay; if (relay && relay.lastMoveAt && relay.path === ctrl.path && ctrl.path !== '' && !isFinished(study!.data.chapter)) { const spent = (Date.now() - relay.lastMoveAt) / 10; const i = isWhiteTurn ? 0 : 1; if (centis[i]) centis[i] = Math.max(0, centis[i]! - spent); } - const opts = { - tenths: !ctrl.study || !ctrl.study.relay - }; + const showTenths = !ctrl.study || !ctrl.study.relay; return [ - renderClock(centis[0], isWhiteTurn, opts), - renderClock(centis[1], !isWhiteTurn, opts) + renderClock(centis[0], isWhiteTurn, whitePov ? 'bottom' : 'top', showTenths), + renderClock(centis[1], !isWhiteTurn, whitePov ? 'top' : 'bottom', showTenths) ]; } -function renderClock(centis: number | undefined, active: boolean, opts: ClockOpts): VNode { - return h('div.aclock', { +function renderClock(centis: number | undefined, active: boolean, cls: string, showTenths: boolean): VNode { + return h('div.analyse__clock.' + cls, { class: { active }, - }, clockContent(centis, opts)); + }, clockContent(centis, showTenths)); } -function clockContent(centis: number | undefined, opts: ClockOpts): Array { +function clockContent(centis: number | undefined, showTenths: boolean): Array { if (!centis && centis !== 0) return ['-']; const date = new Date(centis * 10), millis = date.getUTCMilliseconds(), sep = ':', baseStr = pad2(date.getUTCMinutes()) + sep + pad2(date.getUTCSeconds()); - if (!opts.tenths || centis >= 360000) return [Math.floor(centis / 360000) + sep + baseStr]; - const tenthsStr = Math.floor(millis / 100).toString(); - return [ + if (!showTenths || centis >= 360000) return [Math.floor(centis / 360000) + sep + baseStr]; + return centis >= 6000 ? [baseStr] : [ baseStr, - h('tenths', '.' + tenthsStr) + h('tenths', '.' + Math.floor(millis / 100).toString()) ]; } diff --git a/ui/analyse/src/crazy/crazyCtrl.ts b/ui/analyse/src/crazy/crazyCtrl.ts index 2ec4e3ab5c..778be21645 100644 --- a/ui/analyse/src/crazy/crazyCtrl.ts +++ b/ui/analyse/src/crazy/crazyCtrl.ts @@ -26,5 +26,5 @@ export function valid(chessground: ChessgroundApi, possibleDrops: string | undef if (drops === null) return true; - return drops.indexOf(pos) !== -1; + return drops.includes(pos); } diff --git a/ui/analyse/src/crazy/crazyView.ts b/ui/analyse/src/crazy/crazyView.ts index d38f5b6545..466fcb9142 100644 --- a/ui/analyse/src/crazy/crazyView.ts +++ b/ui/analyse/src/crazy/crazyView.ts @@ -1,6 +1,7 @@ import { drag } from './crazyCtrl'; import { h } from 'snabbdom' import { MouchEvent } from 'chessground/types'; +import { onInsert } from '../util'; import AnalyseCtrl from '../ctrl'; const eventNames = ['mousedown', 'touchstart']; @@ -16,29 +17,26 @@ export default function(ctrl: AnalyseCtrl, color: Color, position: Position) { if (captured) captured.role = captured.promoted ? 'pawn' : captured.role; const activeColor = color === ctrl.turnColor(); const usable = !ctrl.embed && activeColor; - return h(`div.pocket.is2d.${position}.pos-${ctrl.bottomColor()}`, { + return h(`div.pocket.is2d.pocket-${position}.pos-${ctrl.bottomColor()}`, { class: { usable }, - hook: { - insert: vnode => { - if (ctrl.embed) return; - eventNames.forEach(name => { - (vnode.elm as HTMLElement).addEventListener(name, e => drag(ctrl, color, e as MouchEvent)); - }); - } - } + hook: onInsert(el => { + if (ctrl.embed) return; + eventNames.forEach(name => { + el.addEventListener(name, e => drag(ctrl, color, e as MouchEvent)); + }); + }) }, oKeys.map(role => { let nb = pocket[role] || 0; if (activeColor) { if (dropped === role) nb--; if (captured && captured.role === role) nb++; } - return h('piece.' + role + '.' + color, { + return h('div.pocket-c1', h('div.pocket-c2', h('piece.' + role + '.' + color, { attrs: { 'data-role': role, 'data-color': color, 'data-nb': nb } - }); - }) - ); + }))); + })); } diff --git a/ui/analyse/src/ctrl.ts b/ui/analyse/src/ctrl.ts index 917d6e5ea0..7da4235536 100644 --- a/ui/analyse/src/ctrl.ts +++ b/ui/analyse/src/ctrl.ts @@ -24,12 +24,12 @@ import { valid as crazyValid } from './crazy/crazyCtrl'; import makeStudy from './study/studyCtrl'; import { StudyCtrl } from './study/interfaces'; import { StudyPracticeCtrl } from './study/practice/interfaces'; -import { make as makeFork, ForkCtrl } from './fork'; import { make as makeRetro, RetroCtrl } from './retrospect/retroCtrl'; import { make as makePractice, PracticeCtrl } from './practice/practiceCtrl'; import { make as makeEvalCache, EvalCache } from './evalCache'; import { compute as computeAutoShapes } from './autoShape'; import { nextGlyphSymbol } from './nodeFinder'; +import * as speech from './speech'; import { AnalyseOpts, AnalyseData, ServerEvalData, Key, CgDests, JustCaptured, NvuiPlugin, Redraw } from './interfaces'; import GamebookPlayCtrl from './study/gamebook/gamebookPlayCtrl'; import { ctrl as treeViewCtrl, TreeView } from './treeView/treeView'; @@ -62,7 +62,6 @@ export default class AnalyseCtrl { explorer: ExplorerCtrl; forecast?: ForecastCtrl; retro?: RetroCtrl; - fork: ForkCtrl; practice?: PracticeCtrl; study?: StudyCtrl; studyPractice?: StudyPracticeCtrl; @@ -170,12 +169,14 @@ export default class AnalyseCtrl { this.jumpToIndex(index); this.redraw() }); + + li.sound && speech.setup(); } initialize(data: AnalyseData, merge: boolean): void { this.data = data; - this.synthetic = util.synthetic(data); - this.ongoing = !this.synthetic && game.playable(data as game.GameData); + this.synthetic = data.game.id === 'synthetic'; + this.ongoing = !this.synthetic && game.playable(data); const prevTree = merge && this.tree.root; this.tree = makeTree(treeOps.reconstruct(this.data.treeParts)); @@ -188,7 +189,6 @@ export default class AnalyseCtrl { this.explorer = explorerCtrl(this, this.opts.explorer, this.explorer ? this.explorer.allowed() : !this.embed); this.gamePath = this.synthetic || this.ongoing ? undefined : treePath.fromNodeList(treeOps.mainlineNodeList(this.tree.root)); - this.fork = makeFork(this); } private setPath = (path: Tree.Path): void => { @@ -312,7 +312,7 @@ export default class AnalyseCtrl { li.pubsub.emit('analysis.change')(this.node.fen, this.path, this.onMainline ? this.node.ply : false); }); - private updateHref: () => void = li.fp.debounce(() => { + private updateHref: () => void = li.debounce(() => { if (!this.opts.study) window.history.replaceState(null, '', '#' + this.node.ply); }, 750); @@ -321,7 +321,7 @@ export default class AnalyseCtrl { } playedLastMoveMyself = () => - !!this.justPlayed && !!this.node.uci && this.node.uci.indexOf(this.justPlayed) === 0; + !!this.justPlayed && !!this.node.uci && this.node.uci.startsWith(this.justPlayed); jump(path: Tree.Path): void { const pathChanged = path !== this.path, @@ -334,7 +334,7 @@ export default class AnalyseCtrl { if (isForwardStep) { if (!this.node.uci) this.sound.move(); // initial position else if (!playedMyself) { - if (this.node.san!.indexOf('x') !== -1) this.sound.capture(); + if (this.node.san!.includes('x')) this.sound.capture(); else this.sound.move(); } if (/\+|\#/.test(this.node.san!)) this.sound.check(); @@ -342,6 +342,7 @@ export default class AnalyseCtrl { this.threatMode(false); this.ceval.stop(); this.startCeval(); + speech.node(this.node); } this.justPlayed = this.justDropped = this.justCaptured = undefined; this.explorer.setNode(); @@ -357,6 +358,7 @@ export default class AnalyseCtrl { } userJump = (path: Tree.Path): void => { + this.autoplay.stop(); this.withCg(cg => cg.selectSquare(null)); if (this.practice) { @@ -719,8 +721,8 @@ export default class AnalyseCtrl { const value = !this.showComputer(); this.showComputer(value); if (!value && this.practice) this.togglePractice(); - if (this.opts.onToggleComputer) this.opts.onToggleComputer(value); this.onToggleComputer(); + li.pubsub.emit('analysis.comp.toggle')(value); } mergeAnalysisData(data: ServerEvalData): void { diff --git a/ui/analyse/src/evalCache.ts b/ui/analyse/src/evalCache.ts index 22bcd425c1..18ea169df0 100644 --- a/ui/analyse/src/evalCache.ts +++ b/ui/analyse/src/evalCache.ts @@ -63,7 +63,7 @@ function toCeval(e) { export function make(opts): EvalCache { const fenFetched: string[] = []; function hasFetched(node): boolean { - return fenFetched.indexOf(node.fen) !== -1; + return fenFetched.includes(node.fen); }; let upgradable = prop(false); return { diff --git a/ui/analyse/src/explorer/explorerConfig.ts b/ui/analyse/src/explorer/explorerConfig.ts index 61c13c875a..da2cf5f4d2 100644 --- a/ui/analyse/src/explorer/explorerConfig.ts +++ b/ui/analyse/src/explorer/explorerConfig.ts @@ -7,6 +7,7 @@ import { Game } from '../interfaces'; import { ExplorerDb, ExplorerSpeed, ExplorerConfigData, ExplorerConfigCtrl } from './interfaces'; const allSpeeds: ExplorerSpeed[] = ['bullet', 'blitz', 'rapid', 'classical']; +const allRatings = [1600, 1800, 2000, 2200, 2500]; export function controller(game: Game, onClose: () => void, trans: Trans, redraw: () => void): ExplorerConfigCtrl { @@ -24,8 +25,8 @@ export function controller(game: Game, onClose: () => void, trans: Trans, redraw } }, rating: { - available: [1600, 1800, 2000, 2200, 2500], - selected: storedJsonProp('explorer.rating', [1600, 1800, 2000, 2200, 2500]) + available: allRatings, + selected: storedJsonProp('explorer.rating', allRatings) }, speed: { available: allSpeeds, @@ -34,7 +35,7 @@ export function controller(game: Game, onClose: () => void, trans: Trans, redraw }; const toggleMany = function(c, value) { - if (c().indexOf(value) === -1) c(c().concat([value])); + if (!c().includes(value)) c(c().concat([value])); else if (c().length > 1) c(c().filter(v => v !== value)); }; @@ -74,14 +75,14 @@ export function view(ctrl: ExplorerConfigCtrl): VNode[] { ]), d.db.selected() === 'masters' ? h('div.masters.message', [ h('i', { attrs: dataIcon('C') }), - h('p', ctrl.trans('masterDbExplanation', 2200, '1952', '2018')) + h('p', ctrl.trans('masterDbExplanation', 2200, '1952', '2019')) ]) : h('div', [ h('section.rating', [ h('label', ctrl.trans.noarg('averageElo')), h('div.choices', d.rating.available.map(function(r) { return h('span', { - class: { selected: d.rating.selected().indexOf(r) > -1 }, + class: { selected: d.rating.selected().includes(r) }, hook: bind('click', _ => ctrl.toggleRating(r), ctrl.redraw) }, r.toString()); }) @@ -92,7 +93,7 @@ export function view(ctrl: ExplorerConfigCtrl): VNode[] { h('div.choices', d.speed.available.map(function(s) { return h('span', { - class: { selected: d.speed.selected().indexOf(s) > -1 }, + class: { selected: d.speed.selected().includes(s) }, hook: bind('click', _ => ctrl.toggleSpeed(s), ctrl.redraw) }, s); }) @@ -100,7 +101,7 @@ export function view(ctrl: ExplorerConfigCtrl): VNode[] { ]) ]), h('section.save', - h('button.button.text', { + h('button.button.button-green.text', { attrs: dataIcon('E'), hook: bind('click', ctrl.toggleOpen) }, ctrl.trans.noarg('allSet')) diff --git a/ui/analyse/src/explorer/explorerCtrl.ts b/ui/analyse/src/explorer/explorerCtrl.ts index 202026704d..180d3a8764 100644 --- a/ui/analyse/src/explorer/explorerCtrl.ts +++ b/ui/analyse/src/explorer/explorerCtrl.ts @@ -4,7 +4,6 @@ import { opposite } from 'chessground/util'; import { controller as configCtrl } from './explorerConfig'; import xhr = require('./explorerXhr'); import { winnerOf, colorOf } from './explorerUtil'; -import { synthetic } from '../util'; import * as gameUtil from 'game'; import AnalyseCtrl from '../ctrl'; import { Hovering, ExplorerCtrl, ExplorerData, OpeningData, TablebaseData, SimpleTablebaseHit } from './interfaces'; @@ -54,11 +53,11 @@ export default function(root: AnalyseCtrl, opts, allow: boolean): ExplorerCtrl { setNode(); } const data = root.data, - withGames = synthetic(data) || gameUtil.replayable(data) || !!data.opponent.ai, + withGames = root.synthetic || gameUtil.replayable(data) || !!data.opponent.ai, effectiveVariant = data.game.variant.key === 'fromPosition' ? 'standard' : data.game.variant.key, config = configCtrl(data.game, onConfigClose, root.trans, root.redraw); - const fetch = window.lichess.fp.debounce(function() { + const fetch = window.lichess.debounce(function() { const fen = root.node.fen; const request: JQueryPromise = (withGames && tablebaseRelevant(effectiveVariant, fen)) ? xhr.tablebase(opts.tablebaseEndpoint, effectiveVariant, fen) : diff --git a/ui/analyse/src/explorer/explorerView.ts b/ui/analyse/src/explorer/explorerView.ts index 7db32596dc..e3ed06f6e7 100644 --- a/ui/analyse/src/explorer/explorerView.ts +++ b/ui/analyse/src/explorer/explorerView.ts @@ -52,9 +52,9 @@ function showMoveTable(ctrl: AnalyseCtrl, moves: OpeningMoveStats[], fen: Fen): return h('table.moves', [ h('thead', [ h('tr', [ - h('th', trans('move')), - h('th', trans('games')), - h('th', trans('whiteDrawBlack')) + h('th.title', trans('move')), + h('th.title', trans('games')), + h('th.title', trans('whiteDrawBlack')) ]) ]), h('tbody', moveTableAttributes(ctrl, fen), moves.map(move => { @@ -85,7 +85,7 @@ function showGameTable(ctrl: AnalyseCtrl, title: string, games: OpeningGame[]): return h('table.games', [ h('thead', [ h('tr', [ - h('th', { attrs: { colspan: 4 } }, title) + h('th.title', { attrs: { colspan: 4 } }, title) ]) ]), h('tbody', { @@ -192,7 +192,7 @@ function showDtz(ctrl: AnalyseCtrl, fen: Fen, move: TablebaseMoveStats): VNode | else if (move.insufficient_material) return h('result.draws', trans('insufficientMaterial')); else if (move.dtz === null) return null; else if (move.dtz === 0) return h('result.draws', trans('draw')); - else if (move.zeroing) return move.san.indexOf('x') !== -1 ? + else if (move.zeroing) return move.san.includes('x') ? h('result.' + winnerOf(fen, move), trans('capture')) : h('result.' + winnerOf(fen, move), trans('pawnMove')); return h('result.' + winnerOf(fen, move), { @@ -203,7 +203,7 @@ function showDtz(ctrl: AnalyseCtrl, fen: Fen, move: TablebaseMoveStats): VNode | } function closeButton(ctrl: AnalyseCtrl): VNode { - return h('button.button.text', { + return h('button.button.button-empty.text', { attrs: dataIcon('L'), hook: bind('click', ctrl.toggleExplorer, ctrl.redraw) }, ctrl.trans.noarg('close')); @@ -213,7 +213,7 @@ function showEmpty(ctrl: AnalyseCtrl): VNode { return h('div.data.empty', [ h('div.title', showTitle(ctrl, ctrl.data.game.variant)), h('div.message', [ - h('h3', ctrl.trans.noarg('noGameFound')), + h('strong', ctrl.trans.noarg('noGameFound')), ctrl.explorer.config.fullHouse() ? null : h('p.explanation', ctrl.trans.noarg('maybeIncludeMoreGamesFromThePreferencesMenu')), @@ -294,7 +294,7 @@ export default function(ctrl: AnalyseCtrl): VNode | undefined { configOpened = config.data.open(), loading = !configOpened && (explorer.loading() || (!data && !explorer.failing())), content = configOpened ? showConfig(ctrl) : (explorer.failing() ? showFailing(ctrl) : show(ctrl)); - return h('div.explorer_box', { + return h('section.explorer-box.sub-box', { class: { loading, config: configOpened, diff --git a/ui/analyse/src/forecast/forecastCtrl.ts b/ui/analyse/src/forecast/forecastCtrl.ts index 2d5d579865..9cb7c27234 100644 --- a/ui/analyse/src/forecast/forecastCtrl.ts +++ b/ui/analyse/src/forecast/forecastCtrl.ts @@ -14,7 +14,7 @@ export function make(cfg: ForecastData, data: AnalyseData, redraw: () => void): } function contains(fc1: ForecastStep[], fc2: ForecastStep[]): boolean { - return fc1.length >= fc2.length && keyOf(fc1).indexOf(keyOf(fc2)) === 0; + return fc1.length >= fc2.length && keyOf(fc1).startsWith(keyOf(fc2)); } function findStartingWithNode(node: ForecastStep): ForecastStep[][] { diff --git a/ui/analyse/src/forecast/forecastView.ts b/ui/analyse/src/forecast/forecastView.ts index ac1431963b..545bba08b7 100644 --- a/ui/analyse/src/forecast/forecastView.ts +++ b/ui/analyse/src/forecast/forecastView.ts @@ -14,14 +14,16 @@ function onMyTurn(ctrl: AnalyseCtrl, fctrl: ForecastCtrl, cNodes: ForecastStep[] var lines = fcs.filter(function(fc) { return fc.length > 1; }); - return h('button.on-my-turn.add.button.text', { + return h('button.on-my-turn.button.text', { attrs: dataIcon('E'), hook: bind('click', _ => fctrl.playAndSave(firstNode)) }, [ - h('span', h('strong', ctrl.trans('playX', fixCrazySan(cNodes[0].san)))), - lines.length ? - h('span', ctrl.trans.plural('andSaveNbPremoveLines', lines.length)) : - h('span', ctrl.trans.noarg('noConditionalPremoves')) + h('span', [ + h('strong', ctrl.trans('playX', fixCrazySan(cNodes[0].san))), + lines.length ? + h('span', ctrl.trans.plural('andSaveNbPremoveLines', lines.length)) : + h('span', ctrl.trans.noarg('noConditionalPremoves')) + ]) ]); } @@ -58,14 +60,15 @@ export default function(ctrl: AnalyseCtrl, fctrl: ForecastCtrl): VNode { h('sans', renderNodesHtml(nodes)) ]) })), - h('button.add.button.text', { + h('button.add.text', { class: { enabled: isCandidate }, attrs: dataIcon(isCandidate ? 'O' : ""), hook: bind('click', _ => fctrl.addNodes(makeCnodes(ctrl, fctrl)), ctrl.redraw) - }, isCandidate ? [ - h('span', ctrl.trans.noarg('addCurrentVariation')), - h('sans', renderNodesHtml(cNodes)) - ] : [ + }, [ + isCandidate ? h('span', [ + h('span', ctrl.trans.noarg('addCurrentVariation')), + h('sans', renderNodesHtml(cNodes)) + ]) : h('span', ctrl.trans.noarg('playVariationToCreateConditionalPremoves')) ]) ]), diff --git a/ui/analyse/src/fork.ts b/ui/analyse/src/fork.ts deleted file mode 100644 index 66949ca94a..0000000000 --- a/ui/analyse/src/fork.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { h } from 'snabbdom' -import { renderIndexAndMove } from './moveView'; -import { defined } from 'common'; -import { ConcealOf } from './interfaces'; -import AnalyseCtrl from './ctrl'; - -export interface ForkCtrl { - state(): { - node: Tree.Node; - selected: number; - displayed: boolean; - }, - next: () => boolean | undefined; - prev: () => boolean | undefined; - proceed: (it?: number) => boolean | undefined; -} - -export function make(root: AnalyseCtrl): ForkCtrl { - let prev: Tree.Node | undefined; - let selected: number = 0; - function displayed() { - return root.node.children.length > 1; - }; - return { - state() { - const node = root.node; - if (!prev || prev!.id !== node.id) { - prev = node; - selected = 0; - } - return { - node, - selected, - displayed: displayed() - }; - }, - next() { - if (displayed()) { - selected = Math.min(root.node.children.length - 1, selected + 1); - return true; - } - }, - prev() { - if (displayed()) { - selected = Math.max(0, selected - 1); - return true; - } - }, - proceed(it) { - if (displayed()) { - it = defined(it) ? it : selected; - root.userJumpIfCan(root.path + root.node.children[it].id); - return true; - } - } - }; -} - -export function view(root: AnalyseCtrl, concealOf?: ConcealOf) { - if (root.embed || root.retro) return; - const state = root.fork.state(); - if (!state.displayed) return; - const isMainline = concealOf && root.onMainline; - return h('div.fork', { - hook: { - insert(vnode) { - (vnode.elm as HTMLElement).addEventListener('click', e => { - const target = e.target as HTMLElement, - it = parseInt( - (target.parentNode as HTMLElement).getAttribute('data-it') || - target.getAttribute('data-it') || '' - ); - root.fork.proceed(it); - root.redraw(); - }); - } - } - }, - state.node.children.map((node, it) => { - const conceal = isMainline && concealOf!(true)(root.path + node.id, node); - if (!conceal) return h('move', { - class: { selected: it === state.selected }, - attrs: { 'data-it': it } - }, renderIndexAndMove({ - withDots: true, - showEval: root.showComputer(), - showGlyphs: root.showComputer() - }, node)); - }) - ); -} diff --git a/ui/analyse/src/gridHack.ts b/ui/analyse/src/gridHack.ts new file mode 100644 index 0000000000..c51975fa3d --- /dev/null +++ b/ui/analyse/src/gridHack.ts @@ -0,0 +1,38 @@ +import throttle from 'common/throttle'; + +let timeout; +let booted = false; + +export function start(container: HTMLElement) { + + /* Detected browsers with a correct grid min-content implementation: + * Chrome, Chromium, Brave, Opera + */ + if (window.chrome) return; + + const resize = throttle(100, () => { + window.requestAnimationFrame(() => { + const chat = container.querySelector('.mchat') as HTMLElement, + board = container.querySelector('.analyse__board') as HTMLElement, + side = container.querySelector('.analyse__side') as HTMLElement; + if (chat && board && side) { + const height = board.offsetHeight - side.offsetHeight; + if (height) chat.style.height = `calc(${height}px - 2vmin)`; + } + schedule(); + }); + }); + + function schedule() { + timeout && clearTimeout(timeout); + timeout = setTimeout(resize, 500); + } + + resize(); + + if (!booted) { + booted = true; + document.body.addEventListener('chessground.resize', resize); + window.lichess.pubsub.on('analyse.grid-hack', resize); + } +} diff --git a/ui/analyse/src/interfaces.ts b/ui/analyse/src/interfaces.ts index 961ece79fc..bb2813791f 100644 --- a/ui/analyse/src/interfaces.ts +++ b/ui/analyse/src/interfaces.ts @@ -16,6 +16,12 @@ export interface NvuiPlugin { render(ctrl: AnalyseController): VNode; } +export interface AnalyseApi { + socketReceive(type: string, data: any): boolean; + path(): Tree.Path; + setChapter(id: string): void; +} + // similar, but not identical, to game/GameData export interface AnalyseData { game: Game; @@ -32,6 +38,12 @@ export interface AnalyseData { practiceGoal?: PracticeGoal; clock?: Clock; pref: any; + url: { + socket: string + } + userTv?: { + id: string + } } export interface ServerEvalData { @@ -47,6 +59,7 @@ export interface Game { status: Status; player: Color; turns: number; + startedAtTurn: number; source: Source; speed: Speed; variant: Variant; @@ -87,7 +100,6 @@ export interface AnalysisSide { export interface AnalyseOpts { element: HTMLElement; - sideElement: HTMLElement; data: AnalyseData; initialPly?: number | string; userId: string | null; @@ -98,8 +110,11 @@ export interface AnalyseOpts { study?: any; tagTypes?: string; practice?: StudyPracticeData; - onToggleComputer?: (v: boolean) => void; relay?: RelayData; + $side?: JQuery; + $underboard?: JQuery; + i18n: any; + chat: any; } export interface CgDests { diff --git a/ui/analyse/src/keyboard.ts b/ui/analyse/src/keyboard.ts index 94232b6999..b9d1c505f0 100644 --- a/ui/analyse/src/keyboard.ts +++ b/ui/analyse/src/keyboard.ts @@ -1,6 +1,7 @@ import * as control from './control'; import AnalyseCtrl from './ctrl'; -import { bind as bindEvent, dataIcon, spinner } from './util'; +import { spinner } from './util'; +import { modal } from './modal'; import { h } from 'snabbdom' import { VNode } from 'snabbdom/vnode' @@ -28,7 +29,7 @@ export function bind(ctrl: AnalyseCtrl): void { ctrl.redraw(); })); kbd.bind(['right', 'j'], preventing(function() { - if (!ctrl.fork.proceed()) control.next(ctrl); + control.next(ctrl); ctrl.redraw(); })); kbd.bind(['shift+right', 'shift+j'], preventing(function() { @@ -36,11 +37,11 @@ export function bind(ctrl: AnalyseCtrl): void { ctrl.redraw(); })); kbd.bind(['up', '0'], preventing(function() { - if (!ctrl.fork.prev()) control.first(ctrl); + control.first(ctrl); ctrl.redraw(); })); kbd.bind(['down', '$'], preventing(function() { - if (!ctrl.fork.next()) control.last(ctrl); + control.last(ctrl); ctrl.redraw(); })); kbd.bind('shift+c', preventing(function() { @@ -92,25 +93,24 @@ export function bind(ctrl: AnalyseCtrl): void { }); })); }; - keyToMousedown('c', '.study_buttons a.comments'); - keyToMousedown('g', '.study_buttons a.glyphs'); + keyToMousedown('c', '.study__buttons a.comments'); + keyToMousedown('g', '.study__buttons a.glyphs'); } } export function view(ctrl: AnalyseCtrl): VNode { - - return h('div.lichess_overboard.keyboard_help', { - hook: { - insert: vnode => { - window.lichess.loadCss('stylesheets/keyboard.css') - $(vnode.elm as HTMLElement).find('.scrollable').load('/analysis/help?study=' + (ctrl.study ? 1 : 0)); - } - } - }, [ - h('a.close.icon', { - attrs: dataIcon('L'), - hook: bindEvent('click', () => ctrl.keyboardHelp = false, ctrl.redraw) - }), - h('div.scrollable', spinner()) - ]); + return modal({ + class: 'keyboard-help', + onInsert(el: HTMLElement) { + window.lichess.loadCssPath('analyse.keyboard') + $(el).find('.scrollable').load('/analysis/help?study=' + (ctrl.study ? 1 : 0)); + }, + onClose() { + ctrl.keyboardHelp = false; + ctrl.redraw(); + }, + content: [ + h('div.scrollable', spinner()) + ] + }); } diff --git a/ui/analyse/src/main.ts b/ui/analyse/src/main.ts index e0c85b51ec..e3e4ee584b 100644 --- a/ui/analyse/src/main.ts +++ b/ui/analyse/src/main.ts @@ -1,12 +1,9 @@ -import { AnalyseOpts } from './interfaces'; +import { AnalyseApi, AnalyseOpts } from './interfaces'; import AnalyseCtrl from './ctrl'; import makeCtrl from './ctrl'; import view from './view'; -import { main as studyView } from './study/studyView'; -import { main as studyPracticeView } from './study/practice/studyPracticeView'; -import { StudyCtrl } from './study/interfaces'; -import boot = require('./boot'); +import boot from './boot'; import { Chessground } from 'chessground'; import * as chat from 'chat'; @@ -14,18 +11,20 @@ import { init } from 'snabbdom'; import { VNode } from 'snabbdom/vnode' import klass from 'snabbdom/modules/class'; import attributes from 'snabbdom/modules/attributes'; +import { menuHover } from 'common/menuHover'; + +menuHover(); export const patch = init([klass, attributes]); -export function start(opts: AnalyseOpts) { +export function start(opts: AnalyseOpts): AnalyseApi { + + opts.element = document.querySelector('main.analyse') as HTMLElement; let vnode: VNode, ctrl: AnalyseCtrl; - let redrawSide = () => {}; - function redraw() { vnode = patch(vnode, view(ctrl)); - redrawSide(); } ctrl = new makeCtrl(opts, redraw); @@ -34,22 +33,8 @@ export function start(opts: AnalyseOpts) { opts.element.innerHTML = ''; vnode = patch(opts.element, blueprint); - const study: StudyCtrl | undefined = ctrl.study; - - if (study && opts.sideElement) { - const sideView = ctrl.studyPractice ? studyPracticeView : studyView; - let sideVnode = patch(opts.sideElement, sideView(study)); - redrawSide = () => { - sideVnode = patch(sideVnode, sideView(study)); - } - } - return { socketReceive: ctrl.socket.receive, - jumpToIndex(index: number): void { - ctrl.jumpToIndex(index); - redraw(); - }, path: () => ctrl.path, setChapter(id: string) { if (ctrl.study) ctrl.study.setChapter(id); diff --git a/ui/analyse/src/modal.ts b/ui/analyse/src/modal.ts new file mode 100644 index 0000000000..c68127f1a5 --- /dev/null +++ b/ui/analyse/src/modal.ts @@ -0,0 +1,38 @@ +import { h } from 'snabbdom' +import { VNode } from 'snabbdom/vnode' +import { MaybeVNodes } from './interfaces'; +import { bind, onInsert } from './util'; + +interface Modal { + class?: string; + content: MaybeVNodes; + onInsert?: (el: HTMLElement) => void; + onClose(): void; +} + +export function modal(d: Modal): VNode { + return h('div#modal-overlay', { + hook: bind('click', d.onClose) + }, [ + h('div#modal-wrap.study__modal.' + d.class, { + hook: onInsert(el => { + el.addEventListener('click', e => e.stopPropagation()); + d.onInsert && d.onInsert(el); + }) + }, [ + h('span.close', { + attrs: { 'data-icon': 'L' }, + hook: bind('click', d.onClose) + }), + h('div', d.content) + ]) + ]); +} + +export function button(name: string): VNode { + return h('div.form-actions.single', + h('button.button', { + attrs: { type: 'submit' }, + }, name) + ); +} diff --git a/ui/analyse/src/plugins/nvui.ts b/ui/analyse/src/plugins/nvui.ts index 258f9a4df5..6027614484 100644 --- a/ui/analyse/src/plugins/nvui.ts +++ b/ui/analyse/src/plugins/nvui.ts @@ -9,15 +9,13 @@ import { Player } from 'game'; import { renderSan, renderPieces, renderBoard, styleSetting } from 'nvui/chess'; import { renderSetting } from 'nvui/setting'; import { Notify } from 'nvui/notify'; -import { loadCss, Style } from 'nvui/chess'; +import { Style } from 'nvui/chess'; import { commands } from 'nvui/command'; import * as moveView from '../moveView'; import { bind } from '../util'; window.lichess.AnalyseNVUI = function(redraw: Redraw) { - loadCss(); - const notify = new Notify(redraw), moveStyle = styleSetting(), analysisInProgress = prop(false); @@ -33,81 +31,83 @@ window.lichess.AnalyseNVUI = function(redraw: Redraw) { drawable: { enabled: false }, coordinates: false }); - return h('div.nvui', [ - h('h1', 'Textual representation'), - h('h2', 'Game info'), - ...(['white', 'black'].map((color: Color) => h('p', [ - color + ' player: ', - renderPlayer(ctrl, playerByColor(d, color)) - ]))), - h('p', `${d.game.rated ? 'Rated' : 'Casual'} ${d.game.perf}`), - d.clock ? h('p', `Clock: ${d.clock.initial / 60} + ${d.clock.increment}`) : null, - h('h2', 'Moves'), - h('p.moves', { - attrs: { - role : 'log', - 'aria-live': 'off' - } - }, renderMainline(ctrl.mainline, ctrl.path, style)), - h('h2', 'Pieces'), - h('div.pieces', renderPieces(ctrl.chessground.state.pieces, style)), - h('h2', 'Current position'), - h('p.position', { - attrs: { - 'aria-live' : 'assertive', - 'aria-atomic' : true - } - }, renderCurrentNode(ctrl.node, style)), - h('h2', 'Move form'), - h('form', { - hook: { - insert(vnode) { - const $form = $(vnode.elm as HTMLFormElement), - $input = $form.find('.move').val('').focus(); - $form.submit(onSubmit(ctrl, notify.set, moveStyle.get, $input)); + return h('main.analyse', [ + h('div.nvui', [ + h('h1', 'Textual representation'), + h('h2', 'Game info'), + ...(['white', 'black'].map((color: Color) => h('p', [ + color + ' player: ', + renderPlayer(ctrl, playerByColor(d, color)) + ]))), + h('p', `${d.game.rated ? 'Rated' : 'Casual'} ${d.game.perf}`), + d.clock ? h('p', `Clock: ${d.clock.initial / 60} + ${d.clock.increment}`) : null, + h('h2', 'Moves'), + h('p.moves', { + attrs: { + role : 'log', + 'aria-live': 'off' } - } - }, [ - h('label', [ - 'Command input', - h('input.move.mousetrap', { - attrs: { - name: 'move', - 'type': 'text', - autocomplete: 'off', - autofocus: true + }, renderMainline(ctrl.mainline, ctrl.path, style)), + h('h2', 'Pieces'), + h('div.pieces', renderPieces(ctrl.chessground.state.pieces, style)), + h('h2', 'Current position'), + h('p.position', { + attrs: { + 'aria-live' : 'assertive', + 'aria-atomic' : true + } + }, renderCurrentNode(ctrl.node, style)), + h('h2', 'Move form'), + h('form', { + hook: { + insert(vnode) { + const $form = $(vnode.elm as HTMLFormElement), + $input = $form.find('.move').val('').focus(); + $form.submit(onSubmit(ctrl, notify.set, moveStyle.get, $input)); } - }) - ]) - ]), - notify.render(), - // h('h2', 'Actions'), - // h('div.actions', tableInner(ctrl)), - h('h2', 'Computer analysis'), - ...(renderAcpl(ctrl, style) || [requestAnalysisButton(ctrl, analysisInProgress, notify.set)]), - h('h2', 'Board'), - h('pre.board', renderBoard(ctrl.chessground.state.pieces, ctrl.data.player.color)), - h('div.content', { - hook: { - insert: vnode => { - $(vnode.elm as HTMLElement).append($('.blind_content').removeClass('none')); } - } - }), - h('h2', 'Settings'), - h('label', [ - 'Move notation', - renderSetting(moveStyle, ctrl.redraw) - ]), - h('h2', 'Keyboard shortcuts'), - h('p', [ - 'Use arrow keys to navigate in the game.' - ]), - h('h2', 'Commands'), - h('p', [ - 'Type these commands in the command input.', h('br'), - commands.piece.help, h('br'), - commands.scan.help, h('br') + }, [ + h('label', [ + 'Command input', + h('input.move.mousetrap', { + attrs: { + name: 'move', + 'type': 'text', + autocomplete: 'off', + autofocus: true + } + }) + ]) + ]), + notify.render(), + // h('h2', 'Actions'), + // h('div.actions', tableInner(ctrl)), + h('h2', 'Computer analysis'), + ...(renderAcpl(ctrl, style) || [requestAnalysisButton(ctrl, analysisInProgress, notify.set)]), + h('h2', 'Board'), + h('pre.board', renderBoard(ctrl.chessground.state.pieces, ctrl.data.player.color)), + h('div.content', { + hook: { + insert: vnode => { + $(vnode.elm as HTMLElement).append($('.blind-content').removeClass('none')); + } + } + }), + h('h2', 'Settings'), + h('label', [ + 'Move notation', + renderSetting(moveStyle, ctrl.redraw) + ]), + h('h2', 'Keyboard shortcuts'), + h('p', [ + 'Use arrow keys to navigate in the game.' + ]), + h('h2', 'Commands'), + h('p', [ + 'Type these commands in the command input.', h('br'), + commands.piece.help, h('br'), + commands.scan.help, h('br') + ]) ]) ]); } @@ -137,7 +137,7 @@ const analysisGlyphs = ['?!', '?', '??']; function renderAcpl(ctrl: AnalyseController, style: Style): MaybeVNodes | undefined { const anal = ctrl.data.analysis; if (!anal) return undefined; - const analysisNodes = ctrl.mainline.filter(n => (n.glyphs || []).find(g => analysisGlyphs.indexOf(g.symbol) > -1)); + const analysisNodes = ctrl.mainline.filter(n => (n.glyphs || []).find(g => analysisGlyphs.includes(g.symbol))); const res: Array = []; ['white', 'black'].forEach((color: Color) => { const acpl = anal[color].acpl; diff --git a/ui/analyse/src/practice/practiceView.ts b/ui/analyse/src/practice/practiceView.ts index e18bf22a87..72365606c7 100644 --- a/ui/analyse/src/practice/practiceView.ts +++ b/ui/analyse/src/practice/practiceView.ts @@ -6,16 +6,6 @@ import { PracticeCtrl, Comment } from './practiceCtrl'; import AnalyseCtrl from '../ctrl'; import { MaybeVNodes } from '../interfaces'; -function renderTitle(root: AnalyseCtrl): VNode { - return h('div.title', [ - h('span', root.trans.noarg('practiceWithComputer')), - root.studyPractice ? null : h('span.close', { - attrs: { 'data-icon': 'L' }, - hook: bind('click', root.togglePractice, root.redraw) - }) - ]); -} - function commentBest(c: Comment, root: AnalyseCtrl, ctrl: PracticeCtrl): MaybeVNodes { return c.best ? root.trans.vdom( c.verdict === 'goodMove' ? 'anotherWasX' : 'bestWasX', @@ -92,8 +82,8 @@ export default function(root: AnalyseCtrl): VNode | undefined { const comment: Comment | null = ctrl.comment(); const running: boolean = ctrl.running(); const end = ctrl.currentNode().threefold ? 'threefoldRepetition' : root.gameOver(); - return h('div.practice_box.' + (comment ? comment.verdict : 'no-verdict'), [ - renderTitle(root), + return h('div.practice-box.training-box.sub-box.' + (comment ? comment.verdict : 'no-verdict'), [ + h('div.title', root.trans.noarg('practiceWithComputer')), h('div.feedback', !running ? renderOffTrack(root, ctrl) : (end ? renderEnd(root, end) : renderRunning(root, ctrl))), running ? h('div.comment', comment ? ([ h('span.verdict', root.trans.noarg(comment.verdict)), diff --git a/ui/analyse/src/promotion.ts b/ui/analyse/src/promotion.ts index 4b44412fd4..e73f34d089 100644 --- a/ui/analyse/src/promotion.ts +++ b/ui/analyse/src/promotion.ts @@ -1,6 +1,6 @@ import { h } from 'snabbdom' import * as ground from './ground'; -import { bind } from './util'; +import { bind, onInsert } from './util'; import * as util from 'chessground/util'; import { Role } from 'chessground/types'; import AnalyseCtrl from './ctrl'; @@ -22,7 +22,7 @@ export function start(ctrl: AnalyseCtrl, orig: Key, dest: Key, capture: JustCapt var piece = s.pieces[dest]; if (piece && piece.role == 'pawn' && ( (dest[1] == '8' && s.turnColor == 'black') || - (dest[1] == '1' && s.turnColor == 'white'))) { + (dest[1] == '1' && s.turnColor == 'white'))) { promoting = { orig, dest, @@ -30,7 +30,7 @@ export function start(ctrl: AnalyseCtrl, orig: Key, dest: Key, capture: JustCapt callback }; ctrl.redraw(); - return true; + return true; } return false; } @@ -59,14 +59,11 @@ function renderPromotion(ctrl: AnalyseCtrl, dest: Key, pieces, color: Color, ori const vertical = color === orientation ? 'top' : 'bottom'; - return h('div#promotion_choice.' + vertical, { - hook: { - insert: vnode => { - const el = (vnode.elm as HTMLElement); - el.addEventListener('click', _ => cancel(ctrl)); - el.oncontextmenu = () => false; - } - } + return h('div#promotion-choice.' + vertical, { + hook: onInsert(el => { + el.addEventListener('click', _ => cancel(ctrl)); + el.oncontextmenu = () => false; + }) }, pieces.map(function(serverRole, i) { const top = (color === orientation ? i : 7 - i) * 12.5; return h('square', { diff --git a/ui/analyse/src/retrospect/retroCtrl.ts b/ui/analyse/src/retrospect/retroCtrl.ts index 79c9e4405a..0efe06101b 100644 --- a/ui/analyse/src/retrospect/retroCtrl.ts +++ b/ui/analyse/src/retrospect/retroCtrl.ts @@ -23,17 +23,16 @@ export function make(root: AnalyseCtrl): RetroCtrl { const current = prop(null); const feedback = prop('find'); - const contains = window.lichess.fp.contains; const redraw = root.redraw; function isPlySolved(ply: Ply): boolean { - return contains(solvedPlies, ply) + return solvedPlies.includes(ply); }; function findNextNode(): Tree.Node | undefined { const colorModulo = root.bottomIsWhite() ? 1 : 0; candidateNodes = evalSwings(root.mainline, function(n) { - return n.ply % 2 === colorModulo && !contains(explorerCancelPlies, n.ply); + return n.ply % 2 === colorModulo && !explorerCancelPlies.includes(n.ply); }); return candidateNodes.find(n => !isPlySolved(n.ply)); }; diff --git a/ui/analyse/src/retrospect/retroView.ts b/ui/analyse/src/retrospect/retroView.ts index 67106a04e4..ba6f22a660 100644 --- a/ui/analyse/src/retrospect/retroView.ts +++ b/ui/analyse/src/retrospect/retroView.ts @@ -156,30 +156,22 @@ function renderFeedback(root: AnalyseCtrl, fb) { const ctrl: RetroCtrl = root.retro!; const current = ctrl.current(); if (ctrl.isSolving() && current && root.path !== current.prev.path) - return feedback.offTrack(ctrl); + return feedback.offTrack(ctrl); if (fb === 'find') return current ? feedback.find(ctrl) : feedback.end(ctrl, root.flip, root.hasFullComputerAnalysis); return feedback[fb](ctrl); } -function renderTitle(ctrl: RetroCtrl): VNode { - var completion = ctrl.completion(); - return h('div.title', [ - h('span', ctrl.trans.noarg('learnFromYourMistakes')), - h('span', Math.min(completion[0] + 1, completion[1]) + ' / ' + completion[1]), - h('span.close', { - attrs: dataIcon('L'), - hook: bind('click', ctrl.close, ctrl.redraw) - }) - ]); -} - export default function(root: AnalyseCtrl): VNode | undefined { const ctrl = root.retro; if (!ctrl) return; - const fb = ctrl.feedback(); - return h('div.retro_box', [ - renderTitle(ctrl), + const fb = ctrl.feedback(), + completion = ctrl.completion(); + return h('div.retro-box.training-box.sub-box', [ + h('div.title', [ + h('span', ctrl.trans.noarg('learnFromYourMistakes')), + h('span', Math.min(completion[0] + 1, completion[1]) + ' / ' + completion[1]) + ]), h('div.feedback.' + fb, renderFeedback(root, fb)) ]); }; diff --git a/ui/analyse/src/serverSideUnderboard.ts b/ui/analyse/src/serverSideUnderboard.ts new file mode 100644 index 0000000000..133855e6ab --- /dev/null +++ b/ui/analyse/src/serverSideUnderboard.ts @@ -0,0 +1,151 @@ +import AnalyseCtrl from './ctrl'; +import { defined } from 'common'; +import { baseUrl } from './util'; + +export default function(element: HTMLElement, ctrl: AnalyseCtrl) { + + const li = window.lichess; + + $(element).replaceWith(ctrl.opts.$underboard!); + + const data = ctrl.data, + $panels = $('.analyse__underboard__panels > div'), + $menu = $('.analyse__underboard__menu'), + $timeChart = $("#movetimes-chart"), + inputFen = document.querySelector('.analyse__underboard__fen') as HTMLInputElement, + unselect = chart => { + chart.getSelectedPoints().forEach(function(point) { + point.select(false); + }); + }; + let lastFen: string; + + if (!li.AnalyseNVUI) { + li.pubsub.on('analysis.comp.toggle', (v: boolean) => { + setTimeout(function() { + (v ? $menu.find('[data-panel="computer-analysis"]') : $menu.find('span:eq(1)')).trigger('mousedown'); + }, 50); + }); + li.pubsub.on('analysis.change', (fen: Fen, _, mainlinePly: Ply | false) => { + let chart, point, $chart = $("#adv-chart"); + if (fen && fen !== lastFen) { + inputFen.value = fen; + lastFen = fen; + } + if ($chart.length) { + chart = window.Highcharts && $chart.highcharts(); + if (chart) { + if (mainlinePly != chart.lastPly) { + if (mainlinePly === false) unselect(chart); + else { + point = chart.series[0].data[mainlinePly - 1 - data.game.startedAtTurn]; + if (defined(point)) point.select(); + else unselect(chart); + } + } + chart.lastPly = mainlinePly; + } + } + if ($timeChart.length) { + chart = window.Highcharts && $timeChart.highcharts(); + if (chart) { + if (mainlinePly != chart.lastPly) { + if (mainlinePly === false) unselect(chart); + else { + const white = mainlinePly % 2 !== 0; + const serie = white ? 0 : 1; + const turn = Math.floor((mainlinePly - 1 - data.game.startedAtTurn) / 2); + point = chart.series[serie].data[turn]; + if (defined(point)) point.select(); + else unselect(chart); + } + } + chart.lastPly = mainlinePly; + } + } + }); + li.pubsub.on('socket.in.analysisProgress', d => { + const partial = !d.tree.eval; + if (!li.advantageChart) startAdvantageChart(); + else if (li.advantageChart.update) li.advantageChart.update(data, partial); + if (!partial) { + li.pubsub.emit('analysis.server.complete')(); + $("#adv-chart-loader").remove(); + } + }); + } + + function chartLoader() { + return '
    ' + + '' + li.engineName + '
    server analysis
    ' + + li.spinnerHtml + + '
    ' + }; + function startAdvantageChart() { + if (li.advantageChart || li.AnalyseNVUI) return; + const loading = !data.treeParts[0].eval || !Object.keys(data.treeParts[0].eval).length; + const $panel = $panels.filter('.computer-analysis'); + if (!$("#adv-chart").length) $panel.html('
    ' + (loading ? chartLoader() : '')); + else if (loading && !$("#adv-chart-loader").length) $panel.append(chartLoader()); + li.loadScript('javascripts/chart/acpl.js').then(function() { + li.advantageChart(data, ctrl.trans, $("#adv-chart")[0] as HTMLElement); + }); + }; + + const storage = li.storage.make('analysis.panel'); + const setPanel = function(panel) { + $menu.children('.active').removeClass('active').end().find(`[data-panel="${panel}"]`).addClass('active'); + $panels.removeClass('active').filter('.' + panel).addClass('active'); + if (panel == 'move-times' && !li.movetimeChart) try { + li.loadScript('javascripts/chart/movetime.js').then(function() { + li.movetimeChart(data, ctrl.trans); + }); + } catch (e) {} + if (panel == 'computer-analysis' && $("#adv-chart").length) + setTimeout(startAdvantageChart, 200); + }; + $menu.on('mousedown', 'span', function(this: HTMLElement) { + const panel = $(this).data('panel'); + storage.set(panel); + setPanel(panel); + }); + const stored = storage.get(); + if (stored && $menu.children(`[data-panel="${stored}"]`).length) setPanel(stored); + else { + const $menuCt = $menu.children('[data-panel="ctable"]'); + ($menuCt.length ? $menuCt : $menu.children(':first-child')).trigger('mousedown'); + } + if (!data.analysis) { + $panels.find('form.future-game-analysis').submit(function(this: HTMLElement) { + if ($(this).hasClass('must-login')) { + if (confirm(ctrl.trans('youNeedAnAccountToDoThat'))) location.href = '/signup'; + return false; + } + $.ajax({ + method: 'post', + url: $(this).attr('action'), + success: startAdvantageChart, + error: li.reload + }); + return false; + }); + } + + $panels.on('click', '.pgn', function(this: HTMLElement) { + const selection = window.getSelection(), + range = document.createRange(); + range.selectNodeContents(this); + selection!.removeAllRanges(); + selection!.addRange(range); + }); + $panels.on('click', '.embed-howto', function(this: HTMLElement) { + const url = `${baseUrl()}/embed/${data.game.id}${location.hash}`; + const iframe = ''; + $.modal($( + '' + $(this).html() + '

    ' + + '
    ' + li.escapeHtml(iframe) + '

    ' + + iframe + '

    ' + + 'Read more about embedding games' + )); + }); +} diff --git a/ui/analyse/src/socket.ts b/ui/analyse/src/socket.ts index 8e41efac1b..c43a981fd6 100644 --- a/ui/analyse/src/socket.ts +++ b/ui/analyse/src/socket.ts @@ -1,4 +1,3 @@ -import { synthetic } from './util'; import { initial as initialBoardFen } from 'chessground/fen'; import AnalyseCtrl from './ctrl'; @@ -49,7 +48,7 @@ export function make(send: SocketSend, ctrl: AnalyseCtrl): Socket { clearCache(); // forecast mode: reload when opponent moves - if (!synthetic(ctrl.data)) setTimeout(function() { + if (!ctrl.synthetic) setTimeout(function() { send("startWatching", ctrl.data.game.id); }, 1000); diff --git a/ui/analyse/src/speech.ts b/ui/analyse/src/speech.ts new file mode 100644 index 0000000000..03a44541ff --- /dev/null +++ b/ui/analyse/src/speech.ts @@ -0,0 +1,18 @@ +export function setup() { + window.lichess.pubsub.on('speech.enabled', onSpeechChange); + onSpeechChange(window.lichess.sound.speech()); +} + +function onSpeechChange(enabled: boolean) { + if (!window.LichessSpeech && enabled) + window.lichess.loadScript(window.lichess.compiledScript('speech')); + else if (window.LichessSpeech && !enabled) window.LichessSpeech = undefined; +} + +export function node(n: Tree.Node) { + withSpeech(s => s.step(n, true)); +} + +function withSpeech(f: (speech: LichessSpeech) => void) { + if (window.LichessSpeech) f(window.LichessSpeech); +} diff --git a/ui/analyse/src/study/chapterDescription.ts b/ui/analyse/src/study/chapterDescription.ts index f755cbda93..208fe1c777 100644 --- a/ui/analyse/src/study/chapterDescription.ts +++ b/ui/analyse/src/study/chapterDescription.ts @@ -1,7 +1,7 @@ import { h } from 'snabbdom' import { VNode } from 'snabbdom/vnode' import { StudyCtrl } from './interfaces'; -import { bind, enrichText, innerHTML } from '../util'; +import { bind, enrichText, innerHTML, onInsert } from '../util'; export type Save = (string) => void; @@ -29,11 +29,11 @@ export const title = 'Chapter pinned comment'; export function view(study: StudyCtrl): VNode | undefined { const desc = study.desc, - contrib = study.members.canContribute() && !study.gamebookPlay(); + contrib = study.members.canContribute() && !study.gamebookPlay(); if (desc.edit) return edit(desc, study.data.chapter.id); const isEmpty = desc.text === '-'; if (!desc.text || (isEmpty && !contrib)) return; - return h('div.chapter_desc', [ + return h('div.chapter-desc' + (isEmpty ? '.empty' : ''), [ contrib && !isEmpty ? h('div.contrib', [ h('span', title), isEmpty ? null : h('a', { @@ -53,7 +53,7 @@ export function view(study: StudyCtrl): VNode | undefined { }) }) ]) : null, - isEmpty ? h('a.text.empty.button', { + isEmpty ? h('a.text.button', { hook: bind('click', _ => { desc.edit = true; }, desc.redraw) }, title) : h('div.text', { hook: innerHTML(desc.text, text => enrichText(text, true)) @@ -62,36 +62,28 @@ export function view(study: StudyCtrl): VNode | undefined { } function edit(ctrl: ChapterDescriptionCtrl, chapterId: string): VNode { - return h('div.chapter_desc_form.underboard_form', { - hook: { - insert: _ => window.lichess.loadCss('stylesheets/material.form.css') - } - }, [ - h('p.title', [ - h('button.button.frameless.close', { + return h('div.chapter-desc-form', [ + h('div.title', [ + title, + h('button.button.button-empty.button-red', { attrs: { 'data-icon': 'L', title: 'Close' }, hook: bind('click', () => ctrl.edit = false, ctrl.redraw) - }), - title, + }) ]), - h('form.material.form', [ + h('form.form3', [ h('div.form-group', [ - h('textarea#desc-text.' + chapterId, { - hook: { - insert(vnode: VNode) { - const el = vnode.elm as HTMLInputElement; - el.value = ctrl.text === '-' ? '' : (ctrl.text || ''); - el.onkeyup = el.onpaste = () => { - ctrl.save(el.value.trim()); - }; - el.focus(); - } - } - }), - h('i.bar') + h('textarea#form-control.desc-text.' + chapterId, { + hook: onInsert(el => { + el.value = ctrl.text === '-' ? '' : (ctrl.text || ''); + el.onkeyup = el.onpaste = () => { + ctrl.save(el.value.trim()); + }; + el.focus(); + }) + }) ]) ]) ]); diff --git a/ui/analyse/src/study/chapterEditForm.ts b/ui/analyse/src/study/chapterEditForm.ts index acf8248e9d..e86f647523 100644 --- a/ui/analyse/src/study/chapterEditForm.ts +++ b/ui/analyse/src/study/chapterEditForm.ts @@ -1,8 +1,8 @@ import { h } from 'snabbdom' import { VNode } from 'snabbdom/vnode' import { prop } from 'common'; -import { bind, bindSubmit, spinner, option } from '../util'; -import * as dialog from './dialog'; +import { bind, bindSubmit, spinner, option, onInsert, emptyRedButton } from '../util'; +import * as modal from '../modal'; import * as chapterForm from './chapterNewForm'; import { StudyChapterMeta } from './interfaces'; @@ -63,7 +63,7 @@ export function view(ctrl): VNode | undefined { const isLoaded = !!data.orientation; const mode = data.practice ? 'practice' : (!isNaN(data.conceal) ? 'conceal' : (data.gamebook ? 'gamebook' : 'normal')); - return dialog.form({ + return modal.modal({ class: 'edit-' + data.id, // full redraw when changing chapter onClose() { ctrl.current(null); @@ -71,7 +71,7 @@ export function view(ctrl): VNode | undefined { }, content: [ h('h2', 'Edit chapter'), - h('form.material.form', { + h('form.form3', { hook: bindSubmit(e => { const o: any = {}; 'name mode orientation description'.split(' ').forEach(field => { @@ -81,63 +81,59 @@ export function view(ctrl): VNode | undefined { }) }, [ h('div.form-group', [ - h('input#chapter-name', { + h('label.form-label', { + attrs: { for: 'chapter-name' } + }, 'Name'), + h('input#chapter-name.form-control', { attrs: { minlength: 2, maxlength: 80 }, - hook: { - insert: vnode => { - const el = vnode.elm as HTMLInputElement; - if (!el.value) { - el.value = data.name; - el.select(); - el.focus(); - } + hook: onInsert(el => { + if (!el.value) { + el.value = data.name; + el.select(); + el.focus(); } - } - }), - h('label.control-label', { - attrs: { for: 'chapter-name' } - }, 'Name'), - h('i.bar') + }) + }) ]) ].concat( isLoaded ? [ - h('div.form-group.little-margin-bottom', [ - h('select#chapter-orientation', ['White', 'Black'].map(function(color) { - const v = color.toLowerCase(); - return option(v, data.orientation, color); - })), - h('label.control-label', { - attrs: { for: 'chapter-orientation' } - }, 'Orientation'), - h('i.bar') - ]), - h('div.form-group.little-margin-bottom', [ - h('select#chapter-mode', chapterForm.modeChoices.map(c => { - return option(c[0], mode, c[1]); - })), - h('label.control-label', { - attrs: { for: 'chapter-mode' } - }, 'Analysis mode'), - h('i.bar') + h('div.form-split', [ + h('div.form-group.form-half', [ + h('label.form-label', { + attrs: { for: 'chapter-orientation' } + }, 'Orientation'), + h('select#chapter-orientation.form-control', ['White', 'Black'].map(function(color) { + const v = color.toLowerCase(); + return option(v, data.orientation, color); + })) + ]), + h('div.form-group.form-half', [ + h('label.form-label', { + attrs: { for: 'chapter-mode' } + }, 'Analysis mode'), + h('select#chapter-mode.form-control', chapterForm.modeChoices.map(c => { + return option(c[0], mode, c[1]); + })) + ]) ]), chapterForm.descriptionGroup(data.description), - dialog.button('Save chapter') + modal.button('Save chapter') ] : [spinner()] )), h('div.destructive', [ - h('button.button.frameless', { + h(emptyRedButton, { hook: bind('click', _ => { if (confirm('Clear all comments and shapes in this chapter?')) - ctrl.clearAnnotations(data.id); + ctrl.clearAnnotations(data.id); }) }, 'Clear annotations'), - h('button.button.frameless', { + h(emptyRedButton, { hook: bind('click', _ => { if (confirm('Delete this chapter? There is no going back!')) - ctrl.delete(data.id); + ctrl.delete(data.id); }) }, 'Delete chapter') ]) diff --git a/ui/analyse/src/study/chapterNewForm.ts b/ui/analyse/src/study/chapterNewForm.ts index a606cea9cc..0efc2db3b4 100644 --- a/ui/analyse/src/study/chapterNewForm.ts +++ b/ui/analyse/src/study/chapterNewForm.ts @@ -2,19 +2,19 @@ import { h } from 'snabbdom' import { VNode } from 'snabbdom/vnode' import { prop, Prop } from 'common'; import { storedProp } from 'common/storage'; -import { bind, bindSubmit, spinner, option } from '../util'; +import { bind, bindSubmit, spinner, option, onInsert } from '../util'; import { variants as xhrVariants, importPgn } from './studyXhr'; -import * as dialog from './dialog'; +import * as modal from '../modal'; import { chapter as chapterTour } from './studyTour'; import { StudyChapterMeta } from './interfaces'; import { title as descTitle } from './chapterDescription'; import AnalyseCtrl from '../ctrl'; export const modeChoices = [ - ['normal', "Normal analysis"], - ['practice', "Practice with computer"], - ['conceal', "Hide next moves"], - ['gamebook', "Interactive lesson"] + ['normal', 'Normal analysis'], + ['practice', 'Practice with computer'], + ['conceal', 'Hide next moves'], + ['gamebook', 'Interactive lesson'] ]; export function fieldValue(e: Event, id: string) { @@ -86,16 +86,16 @@ export function view(ctrl): VNode { const activeTab = ctrl.vm.tab(); const makeTab = function(key: string, name: string, title: string) { - return h('a.hint--top.' + key, { + return h('span.' + key, { class: { active: activeTab === key }, - attrs: { 'data-hint': title }, + attrs: { title }, hook: bind('click', () => ctrl.vm.tab(key), ctrl.root.redraw) }, name); }; const gameOrPgn = activeTab === 'game' || activeTab === 'pgn'; const currentChapterSetup = ctrl.root.study.data.chapter.setup; - return dialog.form({ + return modal.modal({ class: 'chapter-new', onClose() { ctrl.close(); @@ -109,7 +109,7 @@ export function view(ctrl): VNode { hook: bind('click', ctrl.startTour) }) ]), - h('form.chapter_form.material.form', { + h('form.form3', { hook: bindSubmit(e => { const o: any = { fen: fieldValue(e, 'fen') || (ctrl.vm.tab() === 'edit' ? ctrl.vm.editorFen() : null) @@ -121,35 +121,31 @@ export function view(ctrl): VNode { }, ctrl.redraw) }, [ h('div.form-group', [ - h('input#chapter-name', { + h('label.form-label', { + attrs: {for: 'chapter-name' } + }, 'Name'), + h('input#chapter-name.form-control', { attrs: { minlength: 2, maxlength: 80 }, - hook: { - insert: vnode => { - const el = vnode.elm as HTMLInputElement; + hook: onInsert(el => { if (!el.value) { el.value = 'Chapter ' + (ctrl.vm.initial() ? 1 : (ctrl.chapters().length + 1)); el.select(); el.focus(); } - } - } - }), - h('label.control-label', { - attrs: {for: 'chapter-name' } - }, 'Name'), - h('i.bar') + }) + }) ]), - h('div.study_tabs', [ - makeTab('init', 'Init', 'Start from initial position'), - makeTab('edit', 'Edit', 'Start from custom position'), + h('div.tabs-horiz', [ + makeTab('init', 'Empty', 'Start from initial position'), + makeTab('edit', 'Editor', 'Start from custom position'), makeTab('game', 'URL', 'Load a game URL'), makeTab('fen', 'FEN', 'Load a FEN position'), makeTab('pgn', 'PGN', 'Load a PGN game') ]), - activeTab === 'edit' ? h('div.editor_wrap.is2d', { + activeTab === 'edit' ? h('div.board-editor-wrap', { hook: { insert: vnode => { $.when( @@ -174,29 +170,26 @@ export function view(ctrl): VNode { } }, [spinner()]) : null, activeTab === 'game' ? h('div.form-group', [ - h('input#chapter-game', { - attrs: { placeholder: 'URL of the game' } - }), - h('label.control-label', { + h('label.form-label', { attrs: { 'for': 'chapter-game' } }, 'Load a game from lichess.org or chessgames.com'), - h('i.bar') + h('input#chapter-game.form-control', { + attrs: { placeholder: 'URL of the game' } + }) ]) : null, - activeTab === 'fen' ? h('div.form-group.no-label', [ - h('input#chapter-fen', { + activeTab === 'fen' ? h('div.form-group', [ + h('input#chapter-fen.form-control', { attrs: { value: ctrl.root.node.fen, placeholder: 'Initial FEN position' } - }), - h('i.bar') + }) ]) : null, - activeTab === 'pgn' ? h('div.form-group.no-label', [ - h('textarea#chapter-pgn', { + activeTab === 'pgn' ? h('div.form-groupabel', [ + h('textarea#chapter-pgn.form-control', { attrs: { placeholder: 'Paste your PGN text here, up to ' + ctrl.multiPgnMax + ' games' } }), - h('i.bar'), - window.FileReader ? h('input#chapter-pgn-file', { + window.FileReader ? h('input#chapter-pgn-file.form-control', { attrs: { type: 'file', accept: '.pgn' @@ -212,42 +205,39 @@ export function view(ctrl): VNode { }) }) : null ]) : null, - h('div', [ - h('div.form-group.half.little-margin-bottom', [ - h('select#chapter-variant', { + h('div.form-split', [ + h('div.form-group.form-half', [ + h('label.form-label', { + attrs: { 'for': 'chapter-variant' } + }, 'Variant'), + h('select#chapter-variant.form-control', { attrs: { disabled: gameOrPgn } }, gameOrPgn ? [ h('option', 'Automatic') ] : - ctrl.vm.variants.map(v => option(v.key, currentChapterSetup.variant.key, v.name))), - h('label.control-label', { - attrs: { 'for': 'chapter-variant' } - }, 'Variant'), - h('i.bar') + ctrl.vm.variants.map(v => option(v.key, currentChapterSetup.variant.key, v.name))) ]), - h('div.form-group.half.little-margin-bottom', [ - h('select#chapter-orientation', { + h('div.form-group.form-half', [ + h('label.form-label', { + attrs: { 'for': 'chapter-orientation' } + }, 'Orientation'), + h('select#chapter-orientation.form-control', { hook: bind('change', e => { ctrl.vm.editor && ctrl.vm.editor.setOrientation((e.target as HTMLInputElement).value); }) }, ['White', 'Black'].map(function(color) { const c = color.toLowerCase(); return option(c, currentChapterSetup.orientation, color); - })), - h('label.control-label', { - attrs: { 'for': 'chapter-orientation' } - }, 'Orientation'), - h('i.bar') + })) ]) ]), - h('div.form-group.little-margin-bottom', [ - h('select#chapter-mode', modeChoices.map(c => option(c[0], '', c[1]))), - h('label.control-label', { + h('div.form-group', [ + h('label.form-label', { attrs: { 'for': 'chapter-mode' } }, 'Analysis mode'), - h('i.bar') + h('select#chapter-mode.form-control', modeChoices.map(c => option(c[0], '', c[1]))) ]), - dialog.button('Create chapter') + modal.button('Create chapter') ]) ] }); @@ -255,13 +245,12 @@ export function view(ctrl): VNode { export function descriptionGroup(desc?: string) { return h('div.form-group', [ - h('select#chapter-description', [ - ['', 'None'], - ['1', 'Right under the board'] - ].map(v => option(v[0], desc ? '1' : '', v[1]))), - h('label.control-label', { + h('label.form-label', { attrs: { for: 'chapter-description' } }, descTitle), - h('i.bar') + h('select#chapter-description.form-control', [ + ['', 'None'], + ['1', 'Right under the board'] + ].map(v => option(v[0], desc ? '1' : '', v[1]))) ]); } diff --git a/ui/analyse/src/study/commentForm.ts b/ui/analyse/src/study/commentForm.ts index bb6dcb7ea8..c39d32b3c4 100644 --- a/ui/analyse/src/study/commentForm.ts +++ b/ui/analyse/src/study/commentForm.ts @@ -27,8 +27,8 @@ export interface CommentForm { export function ctrl(root: AnalyseCtrl): CommentForm { const current = prop(null), - focus = prop(false), - opening = prop(false); + focus = prop(false), + opening = prop(false); function submit(text: string): void { if (!current()) return; @@ -84,9 +84,9 @@ export function ctrl(root: AnalyseCtrl): CommentForm { } export function viewDisabled(root: AnalyseCtrl, why: string): VNode { - return h('div.study_comment_form', [ + return h('div.study__comments', [ currentComments(root, true), - h('div.message', h('span', why)) + h('div.study__message', why) ]); } @@ -97,29 +97,25 @@ export function view(root: AnalyseCtrl): VNode { function setupTextarea(vnode: VNode) { const el = vnode.elm as HTMLInputElement, - mine = (current!.node.comments || []).find(function(c: any) { - return c.by && c.by.id && c.by.id === ctrl.root.opts.userId; - }); + mine = (current!.node.comments || []).find(function(c: any) { + return c.by && c.by.id && c.by.id === ctrl.root.opts.userId; + }); el.value = mine ? mine.text : ''; if (ctrl.opening() || ctrl.focus()) window.lichess.raf(() => el.focus()); ctrl.opening(false); } - return h('div.study_comment_form.underboard_form', { - hook: { - insert: _ => window.lichess.loadCss('stylesheets/material.form.css') - } - }, [ + return h('div.study__comments', [ currentComments(root, !study.members.canContribute()), - ctrl.focus() && ctrl.root.path !== current.path ? h('p.title', [ - 'Commenting position after ', - h('button.button', { - hook: bind('mousedown', () => ctrl.root.userJump(current.path), ctrl.redraw) - }, nodeFullName(current.node)) - ]) : null, - h('form.material.form', [ + h('form.form3', [ + ctrl.focus() && ctrl.root.path !== current.path ? h('p', [ + 'Commenting position after ', + h('a', { + hook: bind('mousedown', () => ctrl.root.userJump(current.path), ctrl.redraw) + }, nodeFullName(current.node)) + ]) : null, h('div.form-group', [ - h('textarea#comment-text', { + h('textarea#comment-text.form-control', { hook: { insert(vnode) { setupTextarea(vnode); @@ -145,8 +141,7 @@ export function view(root: AnalyseCtrl): VNode { vnode.data!.path = newKey; } } - }), - h('i.bar') + }) ]) ]) ]); diff --git a/ui/analyse/src/study/dialog.ts b/ui/analyse/src/study/dialog.ts deleted file mode 100644 index 6ec05988bc..0000000000 --- a/ui/analyse/src/study/dialog.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { h } from 'snabbdom' -import { VNode } from 'snabbdom/vnode' -import { MaybeVNodes } from '../interfaces'; -import { bind } from '../util'; - -interface Dialog { - class?: string; - content: MaybeVNodes; - onClose(): void; -} - -export function form(d: Dialog): VNode { - return h('div.lichess_overboard.study_overboard.' + d.class, { - hook: { - insert() { window.lichess.loadCss('stylesheets/material.form.css') } - } - }, ([ - h('a.close.icon', { - attrs: { 'data-icon': 'L' }, - hook: bind('click', d.onClose) - }) - ] as MaybeVNodes).concat(d.content)); -} - -export function button(name: string): VNode { - return h('div.button-container', - h('button.submit.button', { - attrs: { type: 'submit' }, - }, name) - ); -} diff --git a/ui/analyse/src/study/gamebook/gamebookButtons.ts b/ui/analyse/src/study/gamebook/gamebookButtons.ts index 167a24d652..feac56d0ab 100644 --- a/ui/analyse/src/study/gamebook/gamebookButtons.ts +++ b/ui/analyse/src/study/gamebook/gamebookButtons.ts @@ -6,24 +6,21 @@ import { StudyCtrl } from '../interfaces'; export function playButtons(root: AnalyseCtrl): VNode | undefined { const study = root.study!, - ctrl = study.gamebookPlay(); + ctrl = study.gamebookPlay(); if (!ctrl) return; const state = ctrl.state, - fb = state.feedback, - myTurn = fb === 'play'; - return h('div.study_buttons', [ - h('div.member_buttons'), - h('div.gb_buttons', [ - root.path ? h('a.fbt.text.back', { - attrs: dataIcon('I'), - hook: bind('click', () => root.userJump(''), ctrl.redraw) - }, 'Back') : null, - myTurn ? h('a.fbt.text.solution', { - attrs: dataIcon('G'), - hook: bind('click', ctrl.solution, ctrl.redraw) - }, 'View the solution') : undefined, - overrideButton(study) - ]) + fb = state.feedback, + myTurn = fb === 'play'; + return h('div.gamebook-buttons', [ + root.path ? h('a.fbt.text.back', { + attrs: dataIcon('I'), + hook: bind('click', () => root.userJump(''), ctrl.redraw) + }, 'Back') : null, + myTurn ? h('a.fbt.text.solution', { + attrs: dataIcon('G'), + hook: bind('click', ctrl.solution, ctrl.redraw) + }, 'View the solution') : undefined, + overrideButton(study) ]); } @@ -39,7 +36,7 @@ export function overrideButton(study: StudyCtrl): VNode | undefined { }, 'Preview'); else { const isAnalyse = o === 'analyse', - ctrl = study.gamebookPlay(); + ctrl = study.gamebookPlay(); if (isAnalyse || (ctrl && ctrl.state.feedback === 'end')) return h('a.fbt.text.preview', { class: { active: isAnalyse }, attrs: dataIcon('A'), diff --git a/ui/analyse/src/study/gamebook/gamebookEdit.ts b/ui/analyse/src/study/gamebook/gamebookEdit.ts index d6c11a1172..4f0c9f5a00 100644 --- a/ui/analyse/src/study/gamebook/gamebookEdit.ts +++ b/ui/analyse/src/study/gamebook/gamebookEdit.ts @@ -22,7 +22,7 @@ export function render(ctrl: AnalyseCtrl): VNode { let content: MaybeVNodes; const commentHook: Hooks = bind('click', () => { - study.commentForm.set(study.vm.chapterId, ctrl.path, ctrl.node); + study.commentForm.start(study.vm.chapterId, ctrl.path, ctrl.node); study.vm.toolTab('comments'); window.lichess.requestIdleCallback(() => $('#comment-text').focus()); }, ctrl.redraw); @@ -91,11 +91,9 @@ export function render(ctrl: AnalyseCtrl): VNode { ]) ]; - return h('div.gamebook_wrap', { - hook: { insert: _ => window.lichess.loadCss('stylesheets/gamebook.edit.css') } - }, [ - h('div.gamebook', content) - ]); + return h('div.gamebook-edit', { + hook: { insert: _ => window.lichess.loadCssPath('analyse.gamebook.edit') } + }, content); } function renderDeviation(ctrl: AnalyseCtrl): VNode { diff --git a/ui/analyse/src/study/gamebook/gamebookPlayView.ts b/ui/analyse/src/study/gamebook/gamebookPlayView.ts index 6519ce9cef..610d2bc576 100644 --- a/ui/analyse/src/study/gamebook/gamebookPlayView.ts +++ b/ui/analyse/src/study/gamebook/gamebookPlayView.ts @@ -16,7 +16,7 @@ export function render(ctrl: GamebookPlayCtrl): VNode { comment = state.comment || defaultComments[state.feedback]; return h('div.gamebook', { - hook: { insert: _ => window.lichess.loadCss('stylesheets/gamebook.play.css') } + hook: { insert: _ => window.lichess.loadCssPath('analyse.gamebook.play') } }, [ comment ? h('div.comment', { class: { hinted: state.showHint } diff --git a/ui/analyse/src/study/interfaces.ts b/ui/analyse/src/study/interfaces.ts index a7a3a4ee80..1d20f8b8d2 100644 --- a/ui/analyse/src/study/interfaces.ts +++ b/ui/analyse/src/study/interfaces.ts @@ -7,6 +7,7 @@ import { ChapterDescriptionCtrl } from './chapterDescription'; import GamebookPlayCtrl from './gamebook/gamebookPlayCtrl'; import { GamebookOverride } from './gamebook/interfaces'; import { GlyphCtrl } from './studyGlyph'; +import { CommentForm } from './commentForm'; import RelayCtrl from './relay/relayCtrl'; import { ServerEvalCtrl } from './serverEval'; import { MultiBoardCtrl } from './multiBoard'; @@ -22,7 +23,7 @@ export interface StudyCtrl { members: any; chapters: StudyChaptersCtrl; notif: NotifCtrl; - commentForm: any; + commentForm: CommentForm; glyphForm: GlyphCtrl; serverEval: ServerEvalCtrl; share: any; diff --git a/ui/analyse/src/study/inviteForm.ts b/ui/analyse/src/study/inviteForm.ts index 65894edca1..1b0845aa5d 100644 --- a/ui/analyse/src/study/inviteForm.ts +++ b/ui/analyse/src/study/inviteForm.ts @@ -1,8 +1,8 @@ import { h } from 'snabbdom' import { VNode } from 'snabbdom/vnode' -import { bind, titleNameToId } from '../util'; +import { bind, titleNameToId, onInsert } from '../util'; import { prop, Prop } from 'common'; -import * as dialog from './dialog'; +import { modal } from '../modal'; import { StudyMemberMap } from './interfaces'; export function ctrl(send: SocketSend, members: Prop, setTab: () => void, redraw: () => void) { @@ -19,7 +19,7 @@ export function ctrl(send: SocketSend, members: Prop, setTab: () const existing = members(); return followings.concat(spectators).filter(function(elem, idx, arr) { return arr.indexOf(elem) >= idx && // remove duplicates - !existing.hasOwnProperty(titleNameToId(elem)); // remove existing members + !existing.hasOwnProperty(titleNameToId(elem)); // remove existing members }).sort(); }, members, @@ -55,8 +55,8 @@ export function ctrl(send: SocketSend, members: Prop, setTab: () export function view(ctrl): VNode { const candidates = ctrl.candidates(); - return dialog.form({ - class: 'study_invite', + return modal({ + class: 'study__invite', onClose() { ctrl.open(false); ctrl.redraw(); @@ -69,29 +69,25 @@ export function view(ctrl): VNode { 'and who actively want to join this study.' ]), candidates.length ? h('div.users', candidates.map(function(username) { - return h('span.user_link.button', { + return h('span.button.button-metal', { key: username, - attrs: { 'data-href': '/@/' + username }, hook: bind('click', _ => ctrl.invite(username)) }, username); })) : undefined, h('div.input-wrapper', [ // because typeahead messes up with snabbdom h('input', { attrs: { placeholder: 'Search by username' }, - hook: { - insert: vnode => { - const el = vnode.elm as HTMLInputElement; - window.lichess.userAutocomplete($(el), { - tag: 'span', - onSelect(v) { - ctrl.invite(v.name); - $(el).typeahead('close'); - el.value = ''; - ctrl.redraw(); - } - }); - } - } + hook: onInsert(el => { + window.lichess.userAutocomplete($(el), { + tag: 'span', + onSelect(v) { + ctrl.invite(v.name); + $(el).typeahead('close'); + el.value = ''; + ctrl.redraw(); + } + }); + }) }) ]) ] diff --git a/ui/analyse/src/study/multiBoard.ts b/ui/analyse/src/study/multiBoard.ts index de1c059d1d..32a6403650 100644 --- a/ui/analyse/src/study/multiBoard.ts +++ b/ui/analyse/src/study/multiBoard.ts @@ -59,10 +59,10 @@ export class MultiBoardCtrl { export function view(ctrl: MultiBoardCtrl, study: StudyCtrl): VNode | undefined { - return h('div.multi_board', { - class: { loading: ctrl.loading }, + return h('div.study__multiboard', { + class: { loading: ctrl.loading, nopager: !ctrl.pager }, hook: { - insert() { ctrl.reload(true); } + insert() { ctrl.reload(true) } } }, ctrl.pager ? renderPager(ctrl.pager, study) : [spinner()]); } @@ -74,7 +74,7 @@ function renderPager(pager: Paginator, study: StudyCtrl): MaybeV renderPagerNav(pager, ctrl), renderPlayingToggle(ctrl) ]), - h('div#now_playing', pager.currentPageResults.map(makePreview(study))) + h('div.now-playing', pager.currentPageResults.map(makePreview(study))) ]; } @@ -106,7 +106,7 @@ function renderPagerNav(pager: Paginator, ctrl: MultiBoardCtrl): } function pagerButton(text: string, icon: string, click: () => void, enable: boolean, ctrl: MultiBoardCtrl): VNode { - return h('button.fbt.is', { + return h('button.fbt', { attrs: { 'data-icon': icon, disabled: !enable, @@ -126,7 +126,7 @@ function makePreview(study: StudyCtrl) { h('div.name', preview.name), makeCg(preview) ]; - return h('a.mini_board.' + preview.id, { + return h('a.' + preview.id, { attrs: { title: preview.name }, class: { active: !study.multiBoard.loading && study.vm.chapterId == preview.id }, hook: bind('mousedown', _ => study.setChapter(preview.id)) @@ -146,7 +146,7 @@ function uciToLastMove(lm?: string): Key[] | undefined { } function makeCg(preview: ChapterPreview): VNode { - return h('div.cg-board-wrap', { + return h('div.mini-board.cg-board-wrap', { hook: { insert(vnode) { const cg = Chessground(vnode.elm as HTMLElement, { diff --git a/ui/analyse/src/study/playerBars.ts b/ui/analyse/src/study/playerBars.ts index 509b8d60d9..4c301e827a 100644 --- a/ui/analyse/src/study/playerBars.ts +++ b/ui/analyse/src/study/playerBars.ts @@ -1,7 +1,7 @@ import { h } from 'snabbdom'; import { VNode } from 'snabbdom/vnode' import { TagArray } from './interfaces'; -import { renderClocks } from '../clocks'; +import renderClocks from '../clocks'; import AnalyseCtrl from '../ctrl'; import { isFinished, findTag, resultOf } from './studyChapters'; @@ -21,14 +21,15 @@ export default function(ctrl: AnalyseCtrl): VNode[] | undefined { if (!playerNames.white || !playerNames.black) return; const clocks = renderClocks(ctrl), ticking = !isFinished(study.data.chapter) && ctrl.turnColor(); - return (['white', 'black'] as Color[]).map(color => renderPlayer(tags, clocks, playerNames, color, ticking === color)); + return (['white', 'black'] as Color[]).map(color => + renderPlayer(tags, clocks, playerNames, color, ticking === color, ctrl.bottomColor() !== color)); } -function renderPlayer(tags: TagArray[], clocks: [VNode, VNode] | undefined, playerNames: PlayerNames, color: Color, ticking: boolean): VNode { +function renderPlayer(tags: TagArray[], clocks: [VNode, VNode] | undefined, playerNames: PlayerNames, color: Color, ticking: boolean, top: boolean): VNode { const title = findTag(tags, `${color}title`), elo = findTag(tags, `${color}elo`), result = resultOf(tags, color === 'white'); - return h(`div.player_bar.${color}`, { + return h(`div.study__player.study__player-${top ? 'top' : 'bot'}`, { class: { ticking } }, [ h('div.left', [ diff --git a/ui/analyse/src/study/practice/studyPracticeView.ts b/ui/analyse/src/study/practice/studyPracticeView.ts index 60ef61ed7a..4a26fa44cd 100644 --- a/ui/analyse/src/study/practice/studyPracticeView.ts +++ b/ui/analyse/src/study/practice/studyPracticeView.ts @@ -2,6 +2,7 @@ import { h, thunk } from 'snabbdom' import { VNode } from 'snabbdom/vnode' import { plural, bind, spinner, innerHTML, enrichText, option } from '../../util'; import { StudyCtrl } from '../interfaces'; +import { MaybeVNodes } from '../../interfaces'; import { StudyPracticeData, StudyPracticeCtrl } from './interfaces'; import { boolSetting } from '../../boolSetting'; import { view as descView } from '../chapterDescription'; @@ -48,82 +49,84 @@ function renderGoal(practice: StudyPracticeCtrl, inMoves: number) { } } -export function underboard(ctrl: StudyCtrl): VNode | undefined { - if (ctrl.vm.loading) return h('div.feedback', spinner()); +export function underboard(ctrl: StudyCtrl): MaybeVNodes { + if (ctrl.vm.loading) return [h('div.feedback', spinner())]; const p = ctrl.practice!, - gb = ctrl.gamebookPlay(), - pinned = ctrl.data.chapter.description; - if (gb) return pinned ? h('div', [ - h('div.feedback.ongoing', [ - pinned ? h('div.comment', { - hook: innerHTML(pinned, text => enrichText(text!, true)) - }) : null - ]) - ]) : undefined; - else if (!ctrl.data.chapter.practice) return descView(ctrl); + gb = ctrl.gamebookPlay(), + pinned = ctrl.data.chapter.description; + if (gb) return pinned ? [h('div.feedback.ongoing', [ + h('div.comment', { + hook: innerHTML(pinned, text => enrichText(text!, true)) + }) + ])] : []; + else if (!ctrl.data.chapter.practice) return [descView(ctrl)]; switch (p.success()) { case true: const next = ctrl.nextChapter(); - return h('a.feedback.win', next ? { - hook: bind('click', p.goToNext) - } : { - attrs: { href: '/practice' } - }, [ - h('span', 'Success!'), - ctrl.nextChapter() ? 'Go to next exercise' : 'Back to practice menu' - ]); - case false: - return h('a.feedback.fail', { - hook: bind('click', p.reset, ctrl.redraw) - }, [ - h('span', [renderGoal(p, p.goal().moves!)]), - h('strong', 'Click to retry') - ]); - default: - return h('div', [ - h('div.feedback.ongoing', [ - h('div.goal', [renderGoal(p, p.goal().moves! - p.nbMoves())]), - pinned ? h('div.comment', { - hook: innerHTML(pinned, text => enrichText(text!, true)) - }) : null - ]), - boolSetting({ - name: 'Load next exercise immediately', - id: 'autoNext', - checked: p.autoNext(), - change: p.autoNext - }, ctrl.trans, ctrl.redraw) - ]); + return [ + h('a.feedback.win', next ? { + hook: bind('click', p.goToNext) + } : { + attrs: { href: '/practice' } + }, [ + h('span', 'Success!'), + ctrl.nextChapter() ? 'Go to next exercise' : 'Back to practice menu' + ]) + ]; + case false: + return [ + h('a.feedback.fail', { + hook: bind('click', p.reset, ctrl.redraw) + }, [ + h('span', [renderGoal(p, p.goal().moves!)]), + h('strong', 'Click to retry') + ]) + ]; + default: + return [ + h('div.feedback.ongoing', [ + h('div.goal', [renderGoal(p, p.goal().moves! - p.nbMoves())]), + pinned ? h('div.comment', { + hook: innerHTML(pinned, text => enrichText(text!, true)) + }) : null + ]), + boolSetting({ + name: 'Load next exercise immediately', + id: 'autoNext', + checked: p.autoNext(), + change: p.autoNext + }, ctrl.trans, ctrl.redraw) + ]; } } -export function main(ctrl: StudyCtrl): VNode { +export function side(ctrl: StudyCtrl): VNode { const current = ctrl.currentChapter(), - data = ctrl.practice!.data; + data = ctrl.practice!.data; - return h('div.side_box.study_box', [ - h('div.title', [ - h('i.practice.icon.' + data.study.id), + return h('div.practice__side', [ + h('div.practice__side__title', [ + h('i.' + data.study.id), h('div.text', [ h('h1', data.study.name), h('em', data.study.desc) ]) ]), - h('div.list.chapters', { + h('div.practice__side__chapters', { hook: bind('click', e => { e.preventDefault(); const target = e.target as HTMLElement, - id = (target.parentNode as HTMLElement).getAttribute('data-id') || target.getAttribute('data-id'); + id = (target.parentNode as HTMLElement).getAttribute('data-id') || target.getAttribute('data-id'); if (id) ctrl.setChapter(id, true); return false; }) }, ctrl.chapters.list().map(function(chapter) { const loading = ctrl.vm.loading && chapter.id === ctrl.vm.nextChapterId, - active = !ctrl.vm.loading && current && current.id === chapter.id, - completion = data.completion[chapter.id] >= 0 ? 'done' : 'ongoing'; + active = !ctrl.vm.loading && current && current.id === chapter.id, + completion = data.completion[chapter.id] >= 0 ? 'done' : 'ongoing'; return [ - h('a.elem.chapter', { + h('a.ps__chapter', { key: chapter.id, attrs: { href: data.url + '/' + chapter.id, diff --git a/ui/analyse/src/study/relay/relayManagerView.ts b/ui/analyse/src/study/relay/relayManagerView.ts index 5610f8d58a..0bee64ddbf 100644 --- a/ui/analyse/src/study/relay/relayManagerView.ts +++ b/ui/analyse/src/study/relay/relayManagerView.ts @@ -1,25 +1,24 @@ import { h } from 'snabbdom'; import { VNode } from 'snabbdom/vnode'; import RelayCtrl from './relayCtrl'; -import { iconTag, dataIcon, bind } from '../../util'; +import { dataIcon, bind, onInsert } from '../../util'; import { LogEvent } from './interfaces'; export default function(ctrl: RelayCtrl): VNode | undefined { - const d = ctrl.data; - if (ctrl.members.canContribute()) return h('div.relay_wrap', [ + if (ctrl.members.canContribute()) return h('div.relay-admin', { + hook: onInsert(_ => window.lichess.loadCssPath('analyse.relay-admin')) + }, [ h('h2', [ h('span.text', { attrs: dataIcon('') }, 'Broadcast manager'), h('a', { attrs: { - href: `/broadcast/${d.slug}/${d.id}/edit`, + href: `/broadcast/${ctrl.data.slug}/${ctrl.data.id}/edit`, 'data-icon': '%' } }) ]), - h('div.relay', [ - (d.sync.ongoing ? stateOn : stateOff)(ctrl), - renderLog(ctrl) - ]) + (ctrl.data.sync.ongoing ? stateOn : stateOff)(ctrl), + renderLog(ctrl) ]); } @@ -40,9 +39,9 @@ function renderLog(ctrl: RelayCtrl) { } }, e.error); return h('div' + (err ? '.err' : ''), { - key: e.at + key: e.at, + attrs: dataIcon(err ? 'j' : 'E') }, [ - iconTag(err ? 'j' : 'E'), h('div', [ ...(err ? [err] : logSuccess(e)), h('time', dateFormatter(new Date(e.at))) @@ -58,9 +57,9 @@ function renderLog(ctrl: RelayCtrl) { function stateOn(ctrl: RelayCtrl) { return h('div.state.on.clickable', { - hook: bind('click', _ => ctrl.setSync(false)) + hook: bind('click', _ => ctrl.setSync(false)), + attrs: dataIcon('B') }, [ - iconTag('B'), h('div', [ 'Connected to source', h('br'), @@ -71,9 +70,9 @@ function stateOn(ctrl: RelayCtrl) { function stateOff(ctrl: RelayCtrl) { return h('div.state.off.clickable', { - hook: bind('click', _ => ctrl.setSync(true)) + hook: bind('click', _ => ctrl.setSync(true)), + attrs: dataIcon('G') }, [ - iconTag('G'), h('div.fat', 'Click to connect') ]); } @@ -90,5 +89,5 @@ function getDateFormatter(): (date: Date) => string { second: 'numeric' }).format : function(d) { return d.toLocaleString(); } - return cachedDateFormatter; + return cachedDateFormatter; } diff --git a/ui/analyse/src/study/serverEval.ts b/ui/analyse/src/study/serverEval.ts index 622ee38b71..e10d82c805 100644 --- a/ui/analyse/src/study/serverEval.ts +++ b/ui/analyse/src/study/serverEval.ts @@ -1,7 +1,7 @@ import { h } from 'snabbdom' import { VNode } from 'snabbdom/vnode' import AnalyseCtrl from '../ctrl'; -import { spinner, bind } from '../util'; +import { spinner, bind, onInsert } from '../util'; import { Prop, prop, defined } from 'common'; export interface ServerEvalCtrl { @@ -20,8 +20,8 @@ const li = window.lichess; export function ctrl(root: AnalyseCtrl, chapterId: () => string): ServerEvalCtrl { const requested = prop(false), - lastPly = prop(false), - chartEl = prop(null); + lastPly = prop(false), + chartEl = prop(null); function unselect(chart) { chart.getSelectedPoints().forEach(p => p.select(false)); @@ -30,7 +30,7 @@ export function ctrl(root: AnalyseCtrl, chapterId: () => string): ServerEvalCtrl li.pubsub.on('analysis.change', (_fen: string, _path: string, mainlinePly: number | false) => { if (!li.advantageChart || lastPly() === mainlinePly) return; const lp = lastPly(typeof mainlinePly === 'undefined' ? lastPly() : mainlinePly), - el = chartEl(); + el = chartEl(); if (el && window.Highcharts) { const $chart = $(el); if ($chart.length) { @@ -55,7 +55,7 @@ export function ctrl(root: AnalyseCtrl, chapterId: () => string): ServerEvalCtrl }, chapterId, onMergeAnalysisData() { - if (li.advantageChart) li.advantageChart.update(root.data); + if (li.advantageChart) li.advantageChart.update(root.data, false); }, request() { root.socket.send('requestAnalysis', chapterId()); @@ -73,44 +73,40 @@ export function view(ctrl: ServerEvalCtrl): VNode { if (!analysis) return ctrl.requested() ? requested() : requestButton(ctrl); - return h('div.server_eval.ready.' + analysis.id, { - hook: { - insert(vnode) { - ctrl.lastPly(false); - li.requestIdleCallback(() => { - li.loadScript('javascripts/chart/acpl.js').then(() => { - li.advantageChart(ctrl.root.data, ctrl.root.trans, vnode.elm as HTMLElement); - ctrl.chartEl(vnode.elm as HTMLElement); - }); + return h('div.study__server-eval.ready.' + analysis.id, { + hook: onInsert(el => { + ctrl.lastPly(false); + li.requestIdleCallback(() => { + li.loadScript('javascripts/chart/acpl.js').then(() => { + li.advantageChart(ctrl.root.data, ctrl.root.trans, el); + ctrl.chartEl(el); }); - } - } - }, [h('div.message', spinner())]); + }); + }) + }, [h('div.study__message', spinner())]); } function requested(): VNode { - return h('div.server_eval.requested', - h('div.message', spinner())); + return h('div.study__server-eval.requested', spinner()); } function requestButton(ctrl: ServerEvalCtrl) { - return h('div.server_eval', [ - h('div.message', - ctrl.root.mainline.length < 5 ? h('p', 'The study is too short to be analysed.') : ( - !ctrl.root.study!.members.canContribute() ? h('p', 'Only the study contributors can request a computer analysis') : [ - h('p', [ - 'Get a full server-side computer analysis of the main line.', - h('br'), - 'Make sure the chapter is complete, for you can only request analysis once.' - ]), - h('a.button.text.request', { - attrs: { - 'data-icon': '', - disabled: ctrl.root.mainline.length < 5 - }, - hook: bind('click', ctrl.request, ctrl.root.redraw) - }, ctrl.root.trans.noarg('requestAComputerAnalysis')) - ]) - )]); + return h('div.study__message', + ctrl.root.mainline.length < 5 ? h('p', 'The study is too short to be analysed.') : ( + !ctrl.root.study!.members.canContribute() ? ['Only the study contributors can request a computer analysis'] : [ + h('p', [ + 'Get a full server-side computer analysis of the main line.', + h('br'), + 'Make sure the chapter is complete, for you can only request analysis once.' + ]), + h('a.button.text', { + attrs: { + 'data-icon': '', + disabled: ctrl.root.mainline.length < 5 + }, + hook: bind('click', ctrl.request, ctrl.root.redraw) + }, ctrl.root.trans.noarg('requestAComputerAnalysis')) + ]) + ); } diff --git a/ui/analyse/src/study/studyChapters.ts b/ui/analyse/src/study/studyChapters.ts index eb43a6cb3e..482830011c 100644 --- a/ui/analyse/src/study/studyChapters.ts +++ b/ui/analyse/src/study/studyChapters.ts @@ -73,7 +73,7 @@ export function resultOf(tags: TagArray[], isWhite: boolean): string | undefined export function view(ctrl: StudyCtrl): VNode { - const configButton = ctrl.members.canContribute() ? h('i.action.config', { attrs: dataIcon('%') }) : null; + const configButton = ctrl.members.canContribute() ? h('act', { attrs: dataIcon('%') }) : null; const current = ctrl.currentChapter(); function update(vnode: VNode) { @@ -90,7 +90,7 @@ export function view(ctrl: StudyCtrl): VNode { if (ch.length) $(el).scrollTo(ch, 200); } vData.count = newCount; - if (ctrl.members.canContribute() && newCount > 1 && !vData.sortable) { + if (!window.lichess.hasTouchEvents && ctrl.members.canContribute() && newCount > 1 && !vData.sortable) { const makeSortable = function() { vData.sortable = window['Sortable'].create(el, { draggable: '.draggable', @@ -104,18 +104,19 @@ export function view(ctrl: StudyCtrl): VNode { } } - return h('div.list.chapters', { + return h('div.study__chapters', { hook: { insert(vnode) { (vnode.elm as HTMLElement).addEventListener('click', e => { const target = e.target as HTMLElement; const id = (target.parentNode as HTMLElement).getAttribute('data-id') || target.getAttribute('data-id'); if (!id) return; - if (target.classList.contains('config')) ctrl.chapters.editForm.toggle(ctrl.chapters.get(id)); + if (target.tagName === 'ACT') ctrl.chapters.editForm.toggle(ctrl.chapters.get(id)); else ctrl.setChapter(id); }); vnode.data!.li = {}; update(vnode); + window.lichess.pubsub.emit('analyse.grid-hack')(); }, postpatch(old, vnode) { vnode.data!.li = old.data!.li; @@ -131,22 +132,22 @@ export function view(ctrl: StudyCtrl): VNode { const editing = ctrl.chapters.editForm.isEditing(chapter.id), loading = ctrl.vm.loading && chapter.id === ctrl.vm.nextChapterId, active = !ctrl.vm.loading && current && current.id === chapter.id; - return h('div.elem.chapter.draggable', { + return h('div.draggable', { key: chapter.id, attrs: { 'data-id': chapter.id }, class: { active, editing, loading } }, [ - h('span.status', loading ? h('span.ddloader') : ['' + (i + 1)]), + h('span', loading ? h('span.ddloader') : ['' + (i + 1)]), h('h3', chapter.name), configButton ]); }).concat( ctrl.members.canContribute() ? [ - h('div.elem.chapter.add', { + h('div.add', { hook: bind('click', ctrl.chapters.toggleNewForm, ctrl.redraw) }, [ - h('span.status', iconTag('O')), - h('h3.add_text', 'Add a new chapter') + h('span', iconTag('O')), + h('h3.add', 'Add a new chapter') ]) ] : [] )); diff --git a/ui/analyse/src/study/studyComments.ts b/ui/analyse/src/study/studyComments.ts index 68bdfc17c1..b716d8d215 100644 --- a/ui/analyse/src/study/studyComments.ts +++ b/ui/analyse/src/study/studyComments.ts @@ -7,7 +7,7 @@ import { StudyCtrl } from './interfaces'; function authorDom(author) { if (!author) return 'Unknown'; if (!author.name) return author; - return h('span.user_link.ulpt', { + return h('span.user-link.ulpt', { attrs: { 'data-href': '/@/' + author.id } }, author.name); } @@ -25,12 +25,12 @@ export function currentComments(ctrl: AnalyseCtrl, includingMine: boolean): VNod chapter = study.currentChapter(), comments = node.comments!; if (!comments.length) return; - return h('div.study_comments', comments.map((comment: Tree.Comment) => { + return h('div', comments.map((comment: Tree.Comment) => { const by: any = comment.by; const isMine = by.id && ctrl.opts.userId === by.id; if (!includingMine && isMine) return; const canDelete = isMine || study.members.isOwner(); - return h('div.comment.' + comment.id, [ + return h('div.study__comment.' + comment.id, [ canDelete && study.vm.mode.write ? h('a.edit', { attrs: { 'data-icon': 'q', @@ -47,7 +47,7 @@ export function currentComments(ctrl: AnalyseCtrl, includingMine: boolean): VNod title: 'Edit' }, hook: bind('click', _ => { - study.commentForm.open(chapter.id, ctrl.path, node); + study.commentForm.start(chapter.id, ctrl.path, node); }, ctrl.redraw) }) : null, authorDom(by), diff --git a/ui/analyse/src/study/studyCtrl.ts b/ui/analyse/src/study/studyCtrl.ts index de8aaa6be1..c0e342df2c 100644 --- a/ui/analyse/src/study/studyCtrl.ts +++ b/ui/analyse/src/study/studyCtrl.ts @@ -274,7 +274,7 @@ export default function(data: StudyData, ctrl: AnalyseCtrl, tagTypes: TagTypes, return obj; } - const likeToggler = window.lichess.fp.debounce(() => send("like", { liked: data.liked }), 1000); + const likeToggler = li.debounce(() => send("like", { liked: data.liked }), 1000); const socketHandlers = { path(d) { diff --git a/ui/analyse/src/study/studyForm.ts b/ui/analyse/src/study/studyForm.ts index 869423e790..0d572fc3d7 100644 --- a/ui/analyse/src/study/studyForm.ts +++ b/ui/analyse/src/study/studyForm.ts @@ -1,8 +1,8 @@ import { h } from 'snabbdom' import { VNode } from 'snabbdom/vnode' -import * as dialog from './dialog'; +import * as modal from '../modal'; import { prop, Prop } from 'common'; -import { bind, bindSubmit } from '../util'; +import { bind, bindSubmit, emptyRedButton } from '../util'; import { StudyData } from './interfaces'; import { MaybeVNodes } from '../interfaces'; import RelayCtrl from './relay/relayCtrl'; @@ -44,18 +44,17 @@ const userSelectionChoices: Choice[] = [ function select(s: Select): MaybeVNodes { return [ - h('select#study-' + s.key, s.choices.map(function(o) { + h('label.form-label', { + attrs: { for: 'study-' + s.key } + }, s.name), + h(`select#study-${s.key}.form-control`, s.choices.map(function(o) { return h('option', { attrs: { value: o[0], selected: s.selected === o[0] } }, o[1]); - })), - h('label.control-label', { - attrs: { for: 'study-' + s.key } - }, s.name), - h('i.bar') + })) ]; }; @@ -97,7 +96,7 @@ export function view(ctrl: StudyFormCtrl): VNode { el.focus(); } } - return dialog.form({ + return modal.modal({ class: 'study-edit', onClose: function() { ctrl.open(false); @@ -105,7 +104,7 @@ export function view(ctrl: StudyFormCtrl): VNode { }, content: [ h('h2', ctrl.relay ? 'Configure live broadcast' : (isNew ? 'Create' : 'Edit') + ' study'), - h('form.material.form.align-left', { + h('form.form3', { hook: bindSubmit(e => { const obj: FormData = {}; 'name visibility computer explorer cloneable chat sticky'.split(' ').forEach(n => { @@ -116,7 +115,8 @@ export function view(ctrl: StudyFormCtrl): VNode { }, ctrl.redraw) }, [ h('div.form-group' + (ctrl.relay ? '.none' : ''), [ - h('input#study-name', { + h('label.form-label', { attrs: { 'for': 'study-name' } }, 'Name'), + h('input#study-name.form-control', { attrs: { minlength: 3, maxlength: 100 @@ -125,42 +125,44 @@ export function view(ctrl: StudyFormCtrl): VNode { insert: vnode => updateName(vnode, false), postpatch: (_, vnode) => updateName(vnode, true) } - }), - h('label.control-label', { attrs: { 'for': 'study-name' } }, 'Name'), - h('i.bar') + }) ]), - h('div', [ - h('div.form-group.half', select({ + h('div.form-split', [ + h('div.form-group.form-half', select({ key: 'visibility', name: 'Visibility', choices: visibilityChoices, selected: data.visibility })), - h('div.form-group.half', select({ + h('div.form-group.form-half', select({ key: 'cloneable', name: 'Allow cloning', choices: userSelectionChoices, selected: data.settings.cloneable - })), - h('div.form-group.half', select({ + })) + ]), + h('div.form-split', [ + h('div.form-group.form-half', select({ key: 'computer', name: 'Computer analysis', choices: userSelectionChoices, selected: data.settings.computer })), - h('div.form-group.half', select({ + h('div.form-group.form-half', select({ key: 'explorer', name: 'Opening explorer', choices: userSelectionChoices, selected: data.settings.explorer - })), - h('div.form-group.half', select({ + })) + ]), + h('div.form-split', [ + h('div.form-group.form-half', select({ key: 'chat', name: 'Chat', choices: userSelectionChoices, selected: data.settings.chat })), - h('div.form-group.half', select({ + h('div.form-group.form-half', select({ key: 'sticky', name: 'Enable sync', choices: [ @@ -170,7 +172,7 @@ export function view(ctrl: StudyFormCtrl): VNode { selected: '' + data.settings.sticky })) ]), - dialog.button(isNew ? 'Start' : 'Save') + modal.button(isNew ? 'Start' : 'Save') ]), h('div.destructive', [ isNew ? null : h('form', { @@ -182,7 +184,7 @@ export function view(ctrl: StudyFormCtrl): VNode { return confirm('Delete the study chat history? There is no going back!'); }) }, [ - h('button.button.frameless', 'Clear chat') + h(emptyRedButton, 'Clear chat') ]), h('form', { attrs: { @@ -193,7 +195,7 @@ export function view(ctrl: StudyFormCtrl): VNode { return isNew || confirm('Delete the entire study? There is no going back!'); }) }, [ - h('button.button.frameless', isNew ? 'Cancel' : 'Delete study') + h(emptyRedButton, isNew ? 'Cancel' : 'Delete study') ]) ]) ] diff --git a/ui/analyse/src/study/studyGlyph.ts b/ui/analyse/src/study/studyGlyph.ts index b4800f8ce1..b72b8bdfe9 100644 --- a/ui/analyse/src/study/studyGlyph.ts +++ b/ui/analyse/src/study/studyGlyph.ts @@ -27,13 +27,11 @@ function renderGlyph(ctrl: GlyphCtrl, node: Tree.Node) { ctrl.toggleGlyph(glyph.id); return false; }, ctrl.redraw), + attrs: { 'data-symbol': glyph.symbol }, class: { active: !!node.glyphs && !!node.glyphs.find(g => g.id === glyph.id) } }, [ - h('i', { - attrs: { 'data-symbol': glyph.symbol } - }), glyph.name ]); }; @@ -66,8 +64,8 @@ export function ctrl(root: AnalyseCtrl) { } export function viewDisabled(why: string): VNode { - return h('div.study_glyph_form', [ - h('div.message', h('span', why)) + return h('div.study__glyphs', [ + h('div.study__message', why) ]); } @@ -75,13 +73,13 @@ export function view(ctrl: GlyphCtrl): VNode { const all = ctrl.all(), node = ctrl.root.node; - return h('div.study_glyph_form.underboard_form', { + return h('div.study__glyphs' + (all ? '' : '.empty'), { hook: { insert: ctrl.loadGlyphs } - }, [ - all ? h('div.glyph_form', [ + }, + all ? [ h('div.move', all.move.map(renderGlyph(ctrl, node))), h('div.position', all.position.map(renderGlyph(ctrl, node))), h('div.observation', all.observation.map(renderGlyph(ctrl, node))) - ]) : h('div.message', spinner()) - ]); + ] : [h('div.study__message', spinner())] + ); } diff --git a/ui/analyse/src/study/studyMembers.ts b/ui/analyse/src/study/studyMembers.ts index c5f6bab830..5a19812797 100644 --- a/ui/analyse/src/study/studyMembers.ts +++ b/ui/analyse/src/study/studyMembers.ts @@ -1,6 +1,6 @@ import { h } from 'snabbdom' import { VNode } from 'snabbdom/vnode' -import { titleNameToId, bind, dataIcon } from '../util'; +import { titleNameToId, bind, dataIcon, iconTag, onInsert } from '../util'; import { prop, Prop } from 'common'; import { ctrl as inviteFormCtrl } from './inviteForm'; import { StudyCtrl, StudyMember, StudyMemberMap, Tab } from './interfaces'; @@ -157,7 +157,7 @@ export function view(ctrl: StudyCtrl): VNode { function username(member: StudyMember) { var u = member.user; - return h('span.user_link.ulpt', { + return h('span.user-link.ulpt', { attrs: { 'data-href': '/@/' + u.name } }, (u.title ? u.title + ' ' : '') + u.name); }; @@ -172,21 +172,21 @@ export function view(ctrl: StudyCtrl): VNode { }, attrs: { title: contrib ? 'Contributor' : 'Viewer' }, }, [ - h('i', { attrs: dataIcon(contrib ? 'r' : 'v') }) + iconTag(contrib ? 'r' : 'v') ]); }; function configButton(ctrl: StudyCtrl, member: StudyMember) { if (isOwner && member.user.id !== ctrl.members.myId) - return h('i.action.config', { - key: 'cfg-' + member.user.id, - attrs: dataIcon('%'), - hook: bind('click', _ => { - ctrl.members.confing(ctrl.members.confing() === member.user.id ? null : member.user.id); - }, ctrl.redraw) - }); + return h('act', { + key: 'cfg-' + member.user.id, + attrs: dataIcon('%'), + hook: bind('click', _ => { + ctrl.members.confing(ctrl.members.confing() === member.user.id ? null : member.user.id); + }, ctrl.redraw) + }); if (!isOwner && member.user.id === ctrl.members.myId) - return h('span.action.leave', { + return h('act.leave', { key: 'leave', attrs: { 'data-icon': 'F', @@ -198,13 +198,9 @@ export function view(ctrl: StudyCtrl): VNode { function memberConfig(member: StudyMember): VNode { const roleId = 'member-role'; - return h('div.config', { + return h('m-config', { key: member.user.id + '-config', - hook: { - insert: vnode => { - $(vnode.elm as HTMLElement).parent('.members').scrollTo(vnode.elm as HTMLElement, 200); - } - } + hook: onInsert(el => $(el).parent('.members').scrollTo(el, 200)) }, [ h('div.role', [ h('div.switch', [ @@ -222,24 +218,27 @@ export function view(ctrl: StudyCtrl): VNode { ]), h('label', { attrs: { 'for': roleId } }, 'Contributor') ]), - h('div.kick', h('a.button.text', { + h('div.kick', h('a.button.button-red.button-empty.text', { attrs: dataIcon('L'), hook: bind('click', _ => ctrl.members.kick(member.user.id), ctrl.redraw) - }, 'Kick from this study')) + }, 'Kick')) ]); }; var ordered = ctrl.members.ordered(); - return h('div.list.members', { + return h('div.study__members', { hook: { - insert: _ => window.lichess.pubsub.emit('content_loaded')() + insert: _ => { + window.lichess.pubsub.emit('content_loaded')(); + window.lichess.pubsub.emit('analyse.grid-hack')(); + } } }, [ ...ordered.map(function(member) { const confing = ctrl.members.confing() === member.user.id; return [ - h('div.elem.member', { + h('div', { key: member.user.id, class: { editing: !!confing } }, [ @@ -252,13 +251,13 @@ export function view(ctrl: StudyCtrl): VNode { confing ? memberConfig(member) : null ]; }).reduce((a, b) => a.concat(b), []), - (isOwner && ordered.length < ctrl.members.max) ? h('div.elem.member.add', { - key: 'invite-someone', + (isOwner && ordered.length < ctrl.members.max) ? h('div.add', { + key: 'add', hook: bind('click', ctrl.members.inviteForm.toggle, ctrl.redraw) }, [ h('div.left', [ - h('span.status', h('i', { attrs: dataIcon('O') })), - h('span.add_text', 'Add members') + h('span.status', iconTag('O')), + h('div.user-link', 'Add members') ]) ]) : null ]); diff --git a/ui/analyse/src/study/studyShare.ts b/ui/analyse/src/study/studyShare.ts index 2ce104ba3d..70da200a5c 100644 --- a/ui/analyse/src/study/studyShare.ts +++ b/ui/analyse/src/study/studyShare.ts @@ -1,12 +1,10 @@ import { h } from 'snabbdom' import { VNode } from 'snabbdom/vnode' -import { bind } from '../util'; +import { bind, baseUrl } from '../util'; import { prop } from 'common'; import { renderIndexAndMove } from '../moveView'; import { StudyData, StudyChapterMeta } from './interfaces'; -const baseUrl = 'https://lichess.org/study/'; - function fromPly(ctrl): VNode { var node = ctrl.currentNode(); return h('div.ply-wrap', h('label.ply', [ @@ -41,19 +39,15 @@ export function ctrl(data: StudyData, currentChapter: () => StudyChapterMeta, cu export function view(ctrl): VNode { const studyId = ctrl.studyId, chapter = ctrl.chapter(); - let fullUrl = baseUrl + studyId + '/' + chapter.id; - let embedUrl = baseUrl + 'embed/' + studyId + '/' + chapter.id; + let fullUrl = `${baseUrl()}/study/${studyId}/${chapter.id}`; + let embedUrl = `${baseUrl()}/study/embed/${studyId}/${chapter.id}`; const isPrivate = ctrl.isPrivate(); if (ctrl.withPly()) { const p = ctrl.currentNode().ply; fullUrl += '#' + p; embedUrl += '#' + p; } - return h('div.study_share.underboard_form.box', { - hook: { - insert() { window.lichess.loadCss('stylesheets/material.form.css') } - } - }, [ + return h('div.study__share', [ h('div.downloads', [ ctrl.cloneable ? h('a.button.text', { attrs: { @@ -74,19 +68,19 @@ export function view(ctrl): VNode { } }, 'Chapter PGN') ]), - h('form.material.form', [ - h('div.form-group.little-margin-bottom', [ - h('input.has-value.autoselect', { + h('form.form3', [ + h('div.form-group', [ + h('label.form-label', 'Study URL'), + h('input.form-control.autoselect', { attrs: { readonly: true, - value: baseUrl + studyId + value: `${baseUrl()}/study/${studyId}` } - }), - h('label.control-label', 'Study URL'), - h('i.bar') + }) ]), h('div.form-group', [ - h('input.has-value.autoselect', { + h('label.form-label', 'Current chapter URL'), + h('input.form-control.autoselect', { attrs: { readonly: true, value: fullUrl @@ -96,11 +90,10 @@ export function view(ctrl): VNode { !isPrivate ? h('p.form-help.text', { attrs: { 'data-icon': '' } }, 'You can paste this in the forum to embed the chapter.') : null, - h('label.control-label', 'Current chapter URL'), - h('i.bar') ]), h('div.form-group', [ - h('input.has-value.autoselect', { + h('label.form-label', 'Embed this chapter in your website or blog'), + h('input.form-control.autoselect', { attrs: { readonly: true, disabled: isPrivate, @@ -116,16 +109,18 @@ export function view(ctrl): VNode { target: '_blank', 'data-icon': '' } - }, 'Read more about embedding a study chapter'), - h('label.control-label', 'Embed current chapter in your website or blog') - ] : []).concat(h('i.bar')) + }, 'Read more about embedding a study chapter.') + ] : []) ), - h('div.fen', { - attrs: { title: 'FEN - click to select' }, - hook: bind('click', e => { - window.getSelection().selectAllChildren((e.target as HTMLElement)) + h('div.form-group', [ + h('label.form-label', 'FEN'), + h('input.form-control.autoselect', { + attrs: { + readonly: true, + value: ctrl.currentNode().fen + }, }) - }, ctrl.currentNode().fen) + ]) ]) ]); } diff --git a/ui/analyse/src/study/studyTags.ts b/ui/analyse/src/study/studyTags.ts index cc20587866..9a798e0b19 100644 --- a/ui/analyse/src/study/studyTags.ts +++ b/ui/analyse/src/study/studyTags.ts @@ -1,7 +1,7 @@ import { h, thunk } from 'snabbdom' import { VNode } from 'snabbdom/vnode' import throttle from 'common/throttle'; -import { option } from '../util'; +import { option, onInsert } from '../util'; import AnalyseCtrl from '../ctrl'; import { StudyCtrl, StudyChapter } from './interfaces'; @@ -12,21 +12,18 @@ function editable(value: string, submit: (v: string, el: HTMLInputElement) => vo spellcheck: false, value }, - hook: { - insert: vnode => { - const el = vnode.elm as HTMLInputElement; - el.onblur = function() { - submit(el.value, el); - }; - el.onkeypress = function(e) { - if ((e.keyCode || e.which) == 13) el.blur(); - } + hook: onInsert(el => { + el.onblur = function() { + submit(el.value, el); + }; + el.onkeypress = function(e) { + if ((e.keyCode || e.which) == 13) el.blur(); } - } + }) }); } -function fixed(text) { +function fixed(text: string) { return h('span', text); } @@ -37,7 +34,7 @@ type TagRow = (string | VNode)[]; function renderPgnTags(chapter: StudyChapter, submit, types: string[]): VNode { let rows: TagRow[] = []; if (chapter.setup.variant.key !== 'standard') - rows.push(['Variant', fixed(chapter.setup.variant.name)]); + rows.push(['Variant', fixed(chapter.setup.variant.name)]); rows = rows.concat(chapter.tags.map(tag => [ tag[0], submit ? editable(tag[1], submit(tag[0])) : fixed(tag[1]) @@ -62,7 +59,7 @@ function renderPgnTags(chapter: StudyChapter, submit, types: string[]): VNode { }, [ h('option', 'New tag'), ...types.map(t => { - if (!window.lichess.fp.contains(existingTypes, t)) return option(t, '', t); + if (!existingTypes.includes(t)) return option(t, '', t); }) ]), editable('', (value, el) => { @@ -74,7 +71,7 @@ function renderPgnTags(chapter: StudyChapter, submit, types: string[]): VNode { ]); } - return h('table.tags.slist', h('tbody', rows.map(function(r) { + return h('table.study__tags.slist', h('tbody', rows.map(function(r) { return h('tr', { key: '' + r[0] }, [ @@ -103,7 +100,7 @@ export function ctrl(root: AnalyseCtrl, getChapter: () => StudyChapter, types) { } } function doRender(root: StudyCtrl): VNode { - return h('div.undertable_inner', renderPgnTags( + return h('div', renderPgnTags( root.tags.getChapter(), root.vm.mode.write && root.tags.submit, root.tags.types)) @@ -111,7 +108,7 @@ function doRender(root: StudyCtrl): VNode { export function view(root: StudyCtrl): VNode { const chapter = root.tags.getChapter(), - tagKey = chapter.tags.map(t => t[1]).join(','), - key = chapter.id + root.data.name + chapter.name + root.data.likes + tagKey + root.vm.mode.write; - return thunk('div.undertable_inner.' + chapter.id, doRender, [root, key]); + tagKey = chapter.tags.map(t => t[1]).join(','), + key = chapter.id + root.data.name + chapter.name + root.data.likes + tagKey + root.vm.mode.write; + return thunk('div.' + chapter.id, doRender, [root, key]); } diff --git a/ui/analyse/src/study/studyTour.ts b/ui/analyse/src/study/studyTour.ts index 4168855e1c..0c1c2a2dc2 100644 --- a/ui/analyse/src/study/studyTour.ts +++ b/ui/analyse/src/study/studyTour.ts @@ -6,6 +6,7 @@ export function study(ctrl: AnalyseCtrl) { window.lichess['studyTour']({ userId: ctrl.opts.userId, isContrib: ctrl.study!.members.canContribute(), + isOwner: ctrl.study!.members.isOwner(), setTab: (tab: Tab) => { ctrl.study!.vm.tab(tab); ctrl.redraw(); diff --git a/ui/analyse/src/study/studyView.ts b/ui/analyse/src/study/studyView.ts index b09d8fd374..c50c94b58f 100644 --- a/ui/analyse/src/study/studyView.ts +++ b/ui/analyse/src/study/studyView.ts @@ -32,8 +32,8 @@ interface ToolButtonOpts { } function toolButton(opts: ToolButtonOpts): VNode { - return h('a.fbt.hint--top.' + opts.tab, { - attrs: { 'data-hint': opts.hint }, + return h('span.' + opts.tab, { + attrs: { title: opts.hint }, class: { active: opts.tab === opts.ctrl.vm.toolTab() }, hook: bind('mousedown', () => { if (opts.onClick) opts.onClick(); @@ -47,24 +47,24 @@ function toolButton(opts: ToolButtonOpts): VNode { function buttons(root: AnalyseCtrl): VNode { const ctrl: StudyCtrl = root.study!, - canContribute = ctrl.members.canContribute(), - showSticky = ctrl.data.features.sticky && (canContribute || (ctrl.vm.behind && ctrl.isUpdatedRecently())); - return h('div.study_buttons', [ - h('div.member_buttons', [ + canContribute = ctrl.members.canContribute(), + showSticky = ctrl.data.features.sticky && (canContribute || (ctrl.vm.behind && ctrl.isUpdatedRecently())); + return h('div.study__buttons', [ + h('div.left-buttons.tabs-horiz', [ // distinct classes (sync, write) allow snabbdom to differentiate buttons - showSticky ? h('a.mode.sync.hint--top', { - attrs: { 'data-hint': 'All sync members remain on the same position' }, + showSticky ? h('a.mode.sync', { + attrs: { title: 'All sync members remain on the same position' }, class: { on: ctrl.vm.mode.sticky }, hook: bind('click', ctrl.toggleSticky) }, [ ctrl.vm.behind ? h('span.behind', '' + ctrl.vm.behind) : h('i.is'), - 'Sync' + 'SYNC' ]) : null, - ctrl.members.canContribute() ? h('a.mode.write.hint--top', { - attrs: { 'data-hint': 'Write changes to the server' }, + ctrl.members.canContribute() ? h('a.mode.write', { + attrs: { title: 'Write changes to the server' }, class: { on: ctrl.vm.mode.write }, hook: bind('click', ctrl.toggleWrite) - }, [ h('i.is'), 'Record' ]) : null, + }, [ h('i.is'), 'REC' ]) : null, toolButton({ ctrl, tab: 'tags', @@ -106,23 +106,22 @@ function buttons(root: AnalyseCtrl): VNode { tab: 'share', hint: 'Share & export', icon: iconTag('$') + }), + h('span.help', { + attrs: { title: 'Need help? Get the tour!', 'data-icon': '' }, + hook: bind('click', ctrl.startTour) }) ]), - gbOverrideButton(ctrl) || helpButton(ctrl) + h('div.right', [ + gbOverrideButton(ctrl) + ]) ]); } -function helpButton(ctrl: StudyCtrl) { - return h('span.fbt.help.hint--top', { - attrs: { 'data-hint': 'Need help? Get the tour!' }, - hook: bind('click', ctrl.startTour) - }, [ iconTag('') ]); -} - function metadata(ctrl: StudyCtrl): VNode { const d = ctrl.data; - return h('div.study_metadata.undertable', [ - h('h2.undertable_top', [ + return h('div.study__metadata', [ + h('h2', [ h('span.name', [ d.name, ': ' + ctrl.currentChapter().name @@ -140,45 +139,41 @@ function metadata(ctrl: StudyCtrl): VNode { ]); } -export function main(ctrl: StudyCtrl): VNode { +export function side(ctrl: StudyCtrl): VNode { const activeTab = ctrl.vm.tab(); const makeTab = function(key: Tab, name: string) { - return h('a.' + key, { + return h('span.' + key, { class: { active: activeTab === key }, hook: bind('mousedown', () => ctrl.vm.tab(key), ctrl.redraw) }, name); }; - const tabs = h('div.study_tabs', [ - makeTab('members', plural('Member', ctrl.members.size())), + const tabs = h('div.tabs-horiz', [ makeTab('chapters', plural(ctrl.relay ? 'Game' : 'Chapter', ctrl.chapters.size())), - ctrl.members.isOwner() ? h('a.more', { + makeTab('members', plural('Member', ctrl.members.size())), + ctrl.members.isOwner() ? h('span.more', { hook: bind('click', () => ctrl.form.open(!ctrl.form.open()), ctrl.redraw) }, [ iconTag('[') ]) : null - ]); + ]); - let panel; - if (activeTab === 'members') panel = memberView(ctrl); - else if (activeTab === 'chapters') panel = chapterView(ctrl); - - return h('div.side_box.study_box', [ + return h('div.study__side', [ tabs, - panel + (activeTab === 'members' ? memberView : chapterView)(ctrl) ]); } export function contextMenu(ctrl: StudyCtrl, path: Tree.Path, node: Tree.Node): VNode[] { return ctrl.vm.mode.write ? [ - h('a.action', { + h('a', { attrs: dataIcon('c'), hook: bind('click', () => { ctrl.vm.toolTab('comments'); - ctrl.commentForm.set(ctrl.currentChapter()!.id, path, node); + ctrl.commentForm.start(ctrl.currentChapter()!.id, path, node); }) }, 'Comment this move'), - h('a.action.glyph-icon', { + h('a.glyph-icon', { hook: bind('click', () => { ctrl.vm.toolTab('glyphs'); ctrl.userJump(path); @@ -196,7 +191,7 @@ export function overboard(ctrl: StudyCtrl) { export function underboard(ctrl: AnalyseCtrl): MaybeVNodes { if (ctrl.embed) return []; - if (ctrl.studyPractice) return [practiceView.underboard(ctrl.study!)]; + if (ctrl.studyPractice) return practiceView.underboard(ctrl.study!); const study = ctrl.study!, toolTab = study.vm.toolTab(); if (study.gamebookPlay()) return [ gbPlayButtons(ctrl), @@ -212,15 +207,15 @@ export function underboard(ctrl: AnalyseCtrl): MaybeVNodes { panel = study.vm.mode.write ? commentForm.view(ctrl) : ( commentForm.viewDisabled(ctrl, study.members.canContribute() ? - 'Press RECORD to comment moves' : + 'Press REC to comment moves' : 'Only the study members can comment on moves') ); - break; + break; case 'glyphs': panel = ctrl.path ? ( study.vm.mode.write ? glyphForm.view(study.glyphForm) : - glyphForm.viewDisabled('Press RECORD to annotate moves') + glyphForm.viewDisabled('Press REC to annotate moves') ) : glyphForm.viewDisabled('Select a move to annotate'); break; case 'serverEval': diff --git a/ui/analyse/src/treeView/columnView.ts b/ui/analyse/src/treeView/columnView.ts index d759946f72..f9ea6df98a 100644 --- a/ui/analyse/src/treeView/columnView.ts +++ b/ui/analyse/src/treeView/columnView.ts @@ -170,9 +170,9 @@ function renderMainlineCommentsOf(ctx: Ctx, node: Tree.Node, conceal: Conceal, w return node.comments!.map(comment => { if (comment.by === 'lichess' && !ctx.showComputer) return; let sel = 'comment' + colorClass; - if (comment.text.indexOf('Inaccuracy.') === 0) sel += '.inaccuracy'; - else if (comment.text.indexOf('Mistake.') === 0) sel += '.mistake'; - else if (comment.text.indexOf('Blunder.') === 0) sel += '.blunder'; + if (comment.text.startsWith('Inaccuracy.')) sel += '.inaccuracy'; + else if (comment.text.startsWith('Mistake.')) sel += '.mistake'; + else if (comment.text.startsWith('Blunder.')) sel += '.blunder'; if (conceal) sel += '.' + conceal; const by = node.comments![1] ? `${commentAuthorText(comment.by)}` : '', truncated = truncateComment(comment.text, 400, ctx); @@ -198,7 +198,7 @@ export default function(ctrl: AnalyseCtrl, concealOf?: ConcealOf): VNode { currentPath: findCurrentPath(ctrl) }; const commentTags = renderMainlineCommentsOf(ctx, root, false, false); - return h('div.tview2.column', { + return h('div.tview2.tview2-column', { hook: mainHook(ctrl) }, ([ empty(commentTags) ? null : h('interrupt', commentTags), diff --git a/ui/analyse/src/treeView/contextMenu.ts b/ui/analyse/src/treeView/contextMenu.ts index cdc51dec1c..9c0cf4c01c 100644 --- a/ui/analyse/src/treeView/contextMenu.ts +++ b/ui/analyse/src/treeView/contextMenu.ts @@ -49,7 +49,7 @@ function positionMenu(menu: HTMLElement, coords: Coords): void { } function action(icon: string, text: string, handler: () => void): VNode { - return h('a.action', { + return h('a', { attrs: { 'data-icon': icon }, hook: bind('click', handler) }, text); diff --git a/ui/analyse/src/treeView/inlineView.ts b/ui/analyse/src/treeView/inlineView.ts index 6543f446a1..c7de2ea1e4 100644 --- a/ui/analyse/src/treeView/inlineView.ts +++ b/ui/analyse/src/treeView/inlineView.ts @@ -112,7 +112,7 @@ export default function(ctrl: AnalyseCtrl): VNode { showEval: !!ctrl.study || ctrl.showComputer(), currentPath: findCurrentPath(ctrl) }; - return h('div.tview2.inline', { + return h('div.tview2.tview2-inline', { hook: mainHook(ctrl) }, [ ...renderInlineCommentsOf(ctx, ctrl.tree.root), diff --git a/ui/analyse/src/treeView/treeView.ts b/ui/analyse/src/treeView/treeView.ts index b13994a015..084248c399 100644 --- a/ui/analyse/src/treeView/treeView.ts +++ b/ui/analyse/src/treeView/treeView.ts @@ -6,7 +6,7 @@ import AnalyseCtrl from '../ctrl'; import contextMenu from './contextMenu'; import { MaybeVNodes, ConcealOf } from '../interfaces'; import { authorText as commentAuthorText } from '../study/studyComments'; -import { synthetic, enrichText, innerHTML } from '../util'; +import { enrichText, innerHTML } from '../util'; import { path as treePath } from 'tree'; import column from './columnView'; import inline from './inlineView'; @@ -33,7 +33,7 @@ export interface Opts { export interface NodeClasses { active: boolean; - context_menu: boolean; + 'context-menu': boolean; current: boolean; nongame: boolean; [key: string]: boolean; @@ -68,20 +68,20 @@ export function ctrl(initialValue: TreeViewKey = 'column'): TreeView { // entry point, dispatching to selected view export function render(ctrl: AnalyseCtrl, concealOf?: ConcealOf): VNode { - return ctrl.treeView.inline() ? inline(ctrl) : column(ctrl, concealOf); + return (ctrl.treeView.inline() || window.lichess.isCol1()) ? inline(ctrl) : column(ctrl, concealOf); } export function nodeClasses(ctx: Ctx, path: Tree.Path): NodeClasses { return { active: path === ctx.ctrl.path, - context_menu: path === ctx.ctrl.contextMenuPath, + 'context-menu': path === ctx.ctrl.contextMenuPath, current: path === ctx.currentPath, nongame: !ctx.currentPath && !!ctx.ctrl.gamePath && treePath.contains(path, ctx.ctrl.gamePath) && path !== ctx.ctrl.gamePath }; } export function findCurrentPath(c: AnalyseCtrl): Tree.Path | undefined { - return (!synthetic(c.data) && playable(c.data) && c.initialPath) || ( + return (!c.synthetic && playable(c.data) && c.initialPath) || ( c.retro && c.retro.current() && c.retro.current().prev.path ) || ( c.study && c.study.data.chapter.relay && c.study.data.chapter.relay.path diff --git a/ui/analyse/src/util.ts b/ui/analyse/src/util.ts index 88d846ec4e..037d1a5d4d 100644 --- a/ui/analyse/src/util.ts +++ b/ui/analyse/src/util.ts @@ -2,27 +2,34 @@ import { h } from 'snabbdom' import { Hooks } from 'snabbdom/hooks' import { Attrs } from 'snabbdom/modules/attributes' import { fixCrazySan } from 'chess'; -import { AnalyseData } from './interfaces'; + +export const emptyRedButton = 'button.button.button-red.button-empty'; export function plyColor(ply: number): Color { return (ply % 2 === 0) ? 'white' : 'black'; } -export function bind(eventName: string, f: (e: Event) => any, redraw?: () => void): Hooks { - return { - insert: vnode => { - (vnode.elm as HTMLElement).addEventListener(eventName, e => { - const res = f(e); - if (res === false) { - if (e.preventDefault) e.preventDefault(); - else e.returnValue = false; // ie - } - if (redraw) redraw(); - return res; - }); - } - }; +export function bindMobileMousedown(el: HTMLElement, f: (e: Event) => any, redraw?: () => void) { + el.addEventListener(window.lichess.mousedownEvent, e => { + f(e); + e.preventDefault(); + if (redraw) redraw(); + }) } + +function listenTo(el: HTMLElement, eventName: string, f: (e: Event) => any, redraw?: () => void) { + el.addEventListener(eventName, e => { + const res = f(e); + if (res === false) e.preventDefault(); + if (redraw) redraw(); + return res; + }) +} + +export function bind(eventName: string, f: (e: Event) => any, redraw?: () => void): Hooks { + return onInsert(el => listenTo(el, eventName, f, redraw)); +} + export function bindSubmit(f: (e: Event) => any, redraw?: () => void): Hooks { return bind('submit', e => { e.preventDefault(); @@ -30,6 +37,12 @@ export function bindSubmit(f: (e: Event) => any, redraw?: () => void): Hooks { }, redraw); } +export function onInsert(f: (element: A) => void): Hooks { + return { + insert: vnode => f(vnode.elm as A) + }; +} + export function readOnlyProp(value: A): () => A { return function(): A { return value; @@ -50,10 +63,6 @@ export function plyToTurn(ply: number): number { return Math.floor((ply - 1) / 2) + 1; } -export function synthetic(data: AnalyseData): boolean { - return data.game.id === 'synthetic'; -} - export function nodeFullName(node: Tree.Node) { if (node.san) return plyToTurn(node.ply) + ( node.ply % 2 === 1 ? '.' : '...' @@ -93,9 +102,32 @@ export function innerHTML(a: A, toHtml: (a: A) => string): Hooks { }; } -export function toYouTubeEmbed(url: string, height: number = 300): string | undefined { - const embedUrl = window.lichess.toYouTubeEmbedUrl(url); - if (embedUrl) return ``; +export function baseUrl() { + return `${window.location.protocol}//${window.location.host}`; +} + +export function toYouTubeEmbed(url: string): string | undefined { + const embedUrl = toYouTubeEmbedUrl(url); + if (embedUrl) return `
    `; +} + +function toYouTubeEmbedUrl(url) { + if (!url) return; + var m = url.match(/(?:https?:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/(?:watch)?(?:\?v=)?([^"&?\/ ]{11})(?:\?|&|)(\S*)/i); + if (!m) return; + var start = 1; + m[2].split('&').forEach(function(p) { + var s = p.split('='); + if (s[0] === 't' || s[0] === 'start') { + if (s[1].match(/^\d+$/)) start = parseInt(s[1]); + else { + var n = s[1].match(/(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?/); + start = (parseInt(n[1]) || 0) * 3600 + (parseInt(n[2]) || 0) * 60 + (parseInt(n[3]) || 0); + } + } + }); + var params = 'modestbranding=1&rel=0&controls=2&iv_load_policy=3&start=' + start; + return 'https://www.youtube.com/embed/' + m[1] + '?' + params; } const commentYoutubeRegex = /(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:.*?(?:[?&]v=)|v\/)|youtu\.be\/)(?:[^"&?\/ ]{11})\b/i; diff --git a/ui/analyse/src/view.ts b/ui/analyse/src/view.ts index 13b8c0d7fc..c3e33dad86 100644 --- a/ui/analyse/src/view.ts +++ b/ui/analyse/src/view.ts @@ -1,11 +1,12 @@ import { h } from 'snabbdom' import { VNode } from 'snabbdom/vnode' import * as chessground from './ground'; -import { synthetic, bind, dataIcon, iconTag, spinner } from './util'; +import { bind, onInsert, dataIcon, spinner, bindMobileMousedown } from './util'; import { getPlayer, playable } from 'game'; import * as router from 'game/router'; import statusView from 'game/view/status'; import { path as treePath } from 'tree'; +import resizeHandle from 'common/resize'; import { render as renderTreeView } from './treeView/treeView'; import * as control from './control'; import { view as actionMenu } from './actionMenu'; @@ -22,12 +23,14 @@ import practiceView from './practice/practiceView'; import * as gbEdit from './study/gamebook/gamebookEdit'; import * as gbPlay from './study/gamebook/gamebookPlayView'; import * as studyView from './study/studyView'; -import { view as forkView } from './fork' +import * as studyPracticeView from './study/practice/studyPracticeView'; import { render as acplView } from './acpl' import AnalyseCtrl from './ctrl'; import { ConcealOf } from './interfaces'; import relayManager from './study/relay/relayManagerView'; import renderPlayerBars from './study/playerBars'; +import serverSideUnderboard from './serverSideUnderboard'; +import * as gridHack from './gridHack'; const li = window.lichess; @@ -70,8 +73,8 @@ function makeConcealOf(ctrl: AnalyseCtrl): ConcealOf | undefined { } function renderAnalyse(ctrl: AnalyseCtrl, concealOf?: ConcealOf) { - return h('div.areplay', [ - renderChapterName(ctrl), + return h('div.analyse__moves.areplay', [ + (ctrl.embed && ctrl.study) ? h('div.chapter-name', ctrl.study.currentChapter().name) : null, renderOpeningBox(ctrl), renderTreeView(ctrl, concealOf), ].concat(renderResult(ctrl))); @@ -91,29 +94,31 @@ function inputs(ctrl: AnalyseCtrl): VNode | undefined { if (ctrl.ongoing || !ctrl.data.userAnalysis) return; if (ctrl.redirecting) return spinner(); return h('div.copyables', [ - h('label.name', 'FEN'), - h('input.copyable.autoselect', { - attrs: { - spellCheck: false, - value: ctrl.node.fen - }, - hook: bind('change', e => { - const value = (e.target as HTMLInputElement).value; - if (value !== ctrl.node.fen) ctrl.changeFen(value); + h('div.pair', [ + h('label.name', 'FEN'), + h('input.copyable.autoselect.analyse__underboard__fen', { + attrs: { + spellCheck: false, + value: ctrl.node.fen + }, + hook: bind('change', e => { + const value = (e.target as HTMLInputElement).value; + if (value !== ctrl.node.fen) ctrl.changeFen(value); + }) }) - }), + ]), h('div.pgn', [ - h('label.name', 'PGN'), - h('textarea.copyable.autoselect', { - attrs: { spellCheck: false }, - hook: { - postpatch: (_, vnode) => { - (vnode.elm as HTMLInputElement).value = pgnExport.renderFullTxt(ctrl); + h('div.pair', [ + h('label.name', 'PGN'), + h('textarea.copyable.autoselect', { + attrs: { spellCheck: false }, + hook: { + postpatch: (_, vnode) => { + (vnode.elm as HTMLInputElement).value = pgnExport.renderFullTxt(ctrl); + } } - } - }), - h('div.action', [ - h('button.button.text', { + }), + h('button.button.button-thin.action.text', { attrs: dataIcon('G'), hook: bind('click', _ => { const pgn = $('.copyables .pgn textarea').val(); @@ -125,24 +130,8 @@ function inputs(ctrl: AnalyseCtrl): VNode | undefined { ]); } -function visualBoard(ctrl: AnalyseCtrl, playerBars: VNode[] | undefined) { - return h('div.lichess_board_wrap' + (playerBars ? '.' + ctrl.bottomColor() : ''), [ - ctrl.keyboardHelp ? keyboardView(ctrl) : null, - ctrl.study ? studyView.overboard(ctrl.study) : null, - playerBars ? playerBars[ctrl.bottomIsWhite() ? 1 : 0] : null, - h('div.lichess_board.' + ctrl.data.game.variant.key, { - hook: ctrl.gamebookPlay() ? undefined : bind('wheel', e => wheel(ctrl, e as WheelEvent)) - }, [ - chessground.render(ctrl), - renderPromotion(ctrl) - ]), - playerBars ? playerBars[ctrl.bottomIsWhite() ? 0 : 1] : null, - cevalView.renderGauge(ctrl) - ]); -} - function jumpButton(icon: string, effect: string, enabled: boolean): VNode { - return h('button', { + return h('button.fbt', { class: { disabled: !enabled }, attrs: { 'data-act': effect, 'data-icon': icon } }); @@ -151,11 +140,11 @@ function jumpButton(icon: string, effect: string, enabled: boolean): VNode { function dataAct(e: Event): string | null { const target = e.target as HTMLElement; return target.getAttribute('data-act') || - (target.parentNode as HTMLElement).getAttribute('data-act'); + (target.parentNode as HTMLElement).getAttribute('data-act'); } -function navClick(ctrl: AnalyseCtrl, action: 'prev' | 'next') { +function repeater(ctrl: AnalyseCtrl, action: 'prev' | 'next') { const repeat = function() { control[action](ctrl); ctrl.redraw(); @@ -165,70 +154,76 @@ function navClick(ctrl: AnalyseCtrl, action: 'prev' | 'next') { let delay = 350; let timeout = setTimeout(repeat, 500); control[action](ctrl); - document.addEventListener('mouseup', function() { - clearTimeout(timeout); - }, {once: true} as any); + const eventName = window.lichess.hasTouchEvents ? 'touchend' : 'mouseup'; + document.addEventListener(eventName, () => clearTimeout(timeout), {once: true}); } -function buttons(ctrl: AnalyseCtrl) { +function controls(ctrl: AnalyseCtrl) { const canJumpPrev = ctrl.path !== '', - canJumpNext = !!ctrl.node.children[0], - menuIsOpen = ctrl.actionMenu.open; - return h('div.game_control', { - hook: bind('mousedown', e => { - const action = dataAct(e); - if (action === 'prev' || action === 'next') navClick(ctrl, action); - else if (action === 'first') control.first(ctrl); - else if (action === 'last') control.last(ctrl); - else if (action === 'explorer') ctrl.toggleExplorer(); - else if (action === 'practice') ctrl.togglePractice(); - else if (action === 'menu') ctrl.actionMenu.toggle(); - }, ctrl.redraw) + canJumpNext = !!ctrl.node.children[0], + menuIsOpen = ctrl.actionMenu.open, + noarg = ctrl.trans.noarg; + return h('div.analyse__controls.analyse-controls', { + hook: onInsert(el => { + bindMobileMousedown(el, e => { + const action = dataAct(e); + if (action === 'prev' || action === 'next') repeater(ctrl, action); + else if (action === 'first') control.first(ctrl); + else if (action === 'last') control.last(ctrl); + else if (action === 'explorer') ctrl.toggleExplorer(); + else if (action === 'practice') ctrl.togglePractice(); + else if (action === 'menu') ctrl.actionMenu.toggle(); + }, ctrl.redraw); + }) }, [ ctrl.embed ? null : h('div.features', ctrl.studyPractice ? [ - h('a.hint--bottom', { + h('a.fbt', { attrs: { - 'data-hint': ctrl.trans.noarg('analysis'), + title: noarg('analysis'), target: '_blank', - href: ctrl.studyPractice.analysisUrl() + href: ctrl.studyPractice.analysisUrl(), + 'data-icon': 'A' } - }, [iconTag('A')]) + }) ] : [ - h('button.hint--bottom', { + h('button.fbt', { attrs: { - 'data-hint': ctrl.trans.noarg('openingExplorerAndTablebase'), - 'data-act': 'explorer' + title: noarg('openingExplorerAndTablebase'), + 'data-act': 'explorer', + 'data-icon': ']' }, class: { hidden: menuIsOpen || !ctrl.explorer.allowed() || !!ctrl.retro, active: ctrl.explorer.enabled() } - }, [iconTag(']')]), - ctrl.ceval.possible && ctrl.ceval.allowed() && !ctrl.isGamebook() ? h('button.hint--bottom', { + }), + ctrl.ceval.possible && ctrl.ceval.allowed() && !ctrl.isGamebook() ? h('button.fbt', { attrs: { - 'data-hint': ctrl.trans.noarg('practiceWithComputer'), - 'data-act': 'practice' + title: noarg('practiceWithComputer'), + 'data-act': 'practice', + 'data-icon': '' }, class: { hidden: menuIsOpen || !!ctrl.retro, active: !!ctrl.practice } - }, [iconTag('')]) : null - ]), + }) : null + ]), h('div.jumps', [ jumpButton('W', 'first', canJumpPrev), jumpButton('Y', 'prev', canJumpPrev), jumpButton('X', 'next', canJumpNext), jumpButton('V', 'last', canJumpNext) ]), - ctrl.studyPractice ? h('div.noop') : h('button.hint--bottom', { + ctrl.studyPractice ? h('div.noop') : h('button.fbt', { class: { active: menuIsOpen }, attrs: { - 'data-hint': ctrl.trans.noarg('menu'), - 'data-act': 'menu' + title: noarg('menu'), + 'data-act': 'menu', + 'data-icon': '[' } - }, [iconTag('[')]) - ]); + }) + ]); } function renderOpeningBox(ctrl: AnalyseCtrl) { @@ -242,17 +237,28 @@ function renderOpeningBox(ctrl: AnalyseCtrl) { ]); } -function renderChapterName(ctrl: AnalyseCtrl) { - if (ctrl.embed && ctrl.study) return h('div.chapter_name', ctrl.study.currentChapter().name); +function innerCoordsCss() { + let board = 'other'; + ['brown', 'green', 'blue'].forEach(b => { + if ($('body').hasClass(b)) board = b; + }); + return `css/coords.inner.${board}.min.css`; } -const innerCoordsCss = 'stylesheets/board.coords.inner.css'; - function forceInnerCoords(ctrl: AnalyseCtrl, v: boolean) { const pref = ctrl.data.pref.coords; if (!pref) return; - if (v) li.loadCss(innerCoordsCss); - else if (pref === 2) li.unloadCss(innerCoordsCss); + if (v) li.loadCss(innerCoordsCss()); + else if (pref === 2) unloadCss(innerCoordsCss()); +} + +function unloadCss(url) { + if (li.loadedCss[url]) { + delete li.loadedCss[url]; + $('head link[rel=stylesheet]') + .filter(function(this: HTMLLinkElement) { return this.href.includes(url) }) + .remove(); + } } let firstRender = true; @@ -260,80 +266,116 @@ let firstRender = true; export default function(ctrl: AnalyseCtrl): VNode { if (ctrl.nvui) return ctrl.nvui.render(ctrl); const concealOf = makeConcealOf(ctrl), - study = ctrl.study, - showCevalPvs = !(ctrl.retro && ctrl.retro.isSolving()) && !ctrl.practice, - menuIsOpen = ctrl.actionMenu.open, - chapter = study && study.data.chapter, - studyStateClass = chapter ? chapter.id + study!.vm.loading : 'nostudy', - gamebookPlay = ctrl.gamebookPlay(), - gamebookPlayView = gamebookPlay && gbPlay.render(gamebookPlay), - gamebookEditView = gbEdit.running(ctrl) ? gbEdit.render(ctrl) : undefined, - relayEdit = study && study.relay && relayManager(study.relay), - playerBars = renderPlayerBars(ctrl), - gaugeDisplayed = ctrl.showEvalGauge(), - needsInnerCoords = !!gaugeDisplayed || !!playerBars; - return h('div.analyse.cg-512', [ - h('div.' + studyStateClass, { - hook: { - insert: _ => { - if (firstRender) { - firstRender = false; - if (ctrl.data.pref.coords === 1) li.loadedCss[innerCoordsCss] = true; - } - else li.pubsub.emit('reset_zoom')(); - forceInnerCoords(ctrl, needsInnerCoords); - }, - update(_, _2) { - forceInnerCoords(ctrl, needsInnerCoords); + study = ctrl.study, + showCevalPvs = !(ctrl.retro && ctrl.retro.isSolving()) && !ctrl.practice, + menuIsOpen = ctrl.actionMenu.open, + chapter = study && study.data.chapter, + gamebookPlay = ctrl.gamebookPlay(), + gamebookPlayView = gamebookPlay && gbPlay.render(gamebookPlay), + gamebookEditView = gbEdit.running(ctrl) ? gbEdit.render(ctrl) : undefined, + playerBars = renderPlayerBars(ctrl), + clocks = !playerBars && renderClocks(ctrl), + gaugeOn = ctrl.showEvalGauge(), + needsInnerCoords = !!gaugeOn || !!playerBars; + return h('main.analyse' + (chapter ? '.' + chapter.id : ''), { + hook: { + insert: _ => { + if (firstRender) { + firstRender = false; + if (ctrl.data.pref.coords === 1) li.loadedCss[innerCoordsCss()] = true; + } + forceInnerCoords(ctrl, needsInnerCoords); + if (!!playerBars != $('body').hasClass('header-margin')) { + li.raf(() => { + $('body').toggleClass('header-margin', !!playerBars); + ctrl.redraw(); + }); } }, - class: { - 'gauge_displayed': gaugeDisplayed, - 'no_computer': !ctrl.showComputer(), - 'gb_edit': !!gamebookEditView, - 'gb_play': !!gamebookPlayView, - 'relay_edit': !!relayEdit, - 'player_bars': !!playerBars, - } - }, [ - h('div.lichess_game', { - hook: { - insert: _ => li.pubsub.emit('content_loaded')() + update(_, _2) { + forceInnerCoords(ctrl, needsInnerCoords); + }, + postpatch(old, vnode) { + if (old.data!.gaugeOn !== gaugeOn) { + li.dispatchEvent(document.body, 'chessground.resize'); } - }, [ - visualBoard(ctrl, playerBars), - h('div.lichess_ground', gamebookPlayView || [ - menuIsOpen || playerBars ? null : renderClocks(ctrl), - menuIsOpen ? null : crazyView(ctrl, ctrl.topColor(), 'top'), - ...(menuIsOpen ? [actionMenu(ctrl)] : [ - cevalView.renderCeval(ctrl), - showCevalPvs ? cevalView.renderPvs(ctrl) : null, - renderAnalyse(ctrl, concealOf), - gamebookEditView ? null : forkView(ctrl, concealOf), - retroView(ctrl) || practiceView(ctrl) || explorerView(ctrl) - ]), - menuIsOpen ? null : crazyView(ctrl, ctrl.bottomColor(), 'bottom'), - buttons(ctrl), - gamebookEditView || relayEdit - ]) + vnode.data!.gaugeOn = gaugeOn; + } + }, + class: { + 'comp-off': !ctrl.showComputer(), + 'gauge-on': gaugeOn, + 'has-players': !!playerBars, + 'has-clocks': !!clocks + } + }, [ + ctrl.keyboardHelp ? keyboardView(ctrl) : null, + ctrl.study ? studyView.overboard(ctrl.study) : null, + h('div.analyse__board.main-board.variant-' + ctrl.data.game.variant.key + '.' + ctrl.bottomColor(), { + hook: (window.lichess.hasTouchEvents || ctrl.gamebookPlay()) ? undefined : bind('wheel', (e: WheelEvent) => wheel(ctrl, e)) + }, [ + ...(clocks || []), + playerBars ? playerBars[ctrl.bottomIsWhite() ? 1 : 0] : null, + chessground.render(ctrl), + playerBars ? playerBars[ctrl.bottomIsWhite() ? 0 : 1] : null, + renderPromotion(ctrl), + h('div.board-resize', { + hook: onInsert(resizeHandle) + }) + ]), + gaugeOn ? cevalView.renderGauge(ctrl) : null, + menuIsOpen ? null : crazyView(ctrl, ctrl.topColor(), 'top'), + gamebookPlayView || h('div.analyse__tools', [ + ...(menuIsOpen ? [actionMenu(ctrl)] : [ + cevalView.renderCeval(ctrl), + showCevalPvs ? cevalView.renderPvs(ctrl) : null, + renderAnalyse(ctrl, concealOf), + gamebookEditView, + retroView(ctrl) || practiceView(ctrl) || explorerView(ctrl) ]) ]), - ctrl.embed ? null : h('div.underboard', { - class: { no_computer: !ctrl.showComputer() } - }, [ - h('div.center', ctrl.study ? studyView.underboard(ctrl) : [inputs(ctrl)]), - h('div.right', [acplView(ctrl)]) - ]), - ctrl.embed || synthetic(ctrl.data) ? null : h('div.analeft', [ - ctrl.forecast ? forecastView(ctrl, ctrl.forecast) : null, - playable(ctrl.data) ? h('div.back_to_game', - h('a.button.text', { - attrs: { - href: ctrl.data.player.id ? router.player(ctrl.data) : router.game(ctrl.data), - 'data-icon': 'i' - } - }, ctrl.trans('backToGame')) - ) : null - ]) + menuIsOpen ? null : crazyView(ctrl, ctrl.bottomColor(), 'bottom'), + gamebookPlayView ? null : controls(ctrl), + ctrl.embed ? null : h('div.analyse__underboard', { + hook: (ctrl.synthetic || playable(ctrl.data)) ? undefined : onInsert(elm => serverSideUnderboard(elm, ctrl)) + }, ctrl.study ? studyView.underboard(ctrl) : [inputs(ctrl)]), + acplView(ctrl), + ctrl.embed ? null : ( + ctrl.studyPractice ? studyPracticeView.side(ctrl.study!) : + h('aside.analyse__side', { + hook: onInsert(elm => { + ctrl.opts.$side && ctrl.opts.$side.length && $(elm).replaceWith(ctrl.opts.$side); + $(elm).append($('.streamers').clone().removeClass('none')); + }) + }, + ctrl.studyPractice ? [studyPracticeView.side(ctrl.study!)] : ( + ctrl.study ? [studyView.side(ctrl.study)] : [ + ctrl.forecast ? forecastView(ctrl, ctrl.forecast) : null, + (!ctrl.synthetic && playable(ctrl.data)) ? h('div.back-to-game', + h('a.button.button-empty.text', { + attrs: { + href: router.game(ctrl.data), + 'data-icon': 'i' + } + }, ctrl.trans.noarg('backToGame')) + ) : null + ] + ) + ) + ), + study && study.relay && relayManager(study.relay), + ctrl.opts.chat && h('section.mchat', { + hook: onInsert(el => { + if (ctrl.opts.chat.instance) ctrl.opts.chat.instance.destroy(); + ctrl.opts.chat.parseMoves = true; + li.makeChat(ctrl.opts.chat, chat => { + ctrl.opts.chat.instance = chat; + }); + gridHack.start(el.parentNode as HTMLElement); + }) + }), + ctrl.embed ? null : h('div.chat__members.none', { + hook: onInsert(el => $(el).watchers()) + }, [h('span.list')]) ]); } diff --git a/ui/analyse/tsconfig.json b/ui/analyse/tsconfig.json index c2839431b2..16b69e7b90 100644 --- a/ui/analyse/tsconfig.json +++ b/ui/analyse/tsconfig.json @@ -2,7 +2,7 @@ "include": ["src/*.ts", "src/*.js"], "exclude": [], "compilerOptions": { - "allowJs": true, + "allowJs": false, "strictNullChecks": true, "noUnusedLocals": true, "noEmitOnError": true, @@ -10,7 +10,8 @@ "noImplicitReturns": false, "noImplicitThis": true, "noUnusedParameters": true, - "target": "es5", - "lib": ["DOM", "ES5"] + "moduleResolution": "node", + "target": "ES5", + "lib": ["DOM", "ES5", "es2015.core", "es2015.Promise"] } } diff --git a/ui/build b/ui/build index db0dd6be72..b0d19bb82a 100755 --- a/ui/build +++ b/ui/build @@ -13,7 +13,7 @@ mkdir -p public/compiled ts_apps1="common chess" ts_apps2="ceval game tree chat nvui" -apps="site chat cli challenge notify learn insight editor puzzle round analyse lobby tournament tournamentSchedule tournamentCalendar simul perfStat dasher" +apps="site chat cli challenge notify learn insight editor puzzle round analyse lobby tournament tournamentSchedule tournamentCalendar simul perfStat dasher speech" if [ $mode == "upgrade" ]; then yarn upgrade --non-interactive @@ -35,6 +35,12 @@ build() { gulp $target } + +if [ $mode != "upgrade" ]; then + echo "build css" + (cd ui && gulp "css-$target") +fi + if type -p parallel; then # parallel execution! if [ -z "$P_OPTS" -a ! -e ~/.parallel/config ]; then P_OPTS="-j+4 --halt 2" diff --git a/ui/ceval/css/_ceval.scss b/ui/ceval/css/_ceval.scss new file mode 100644 index 0000000000..9c2156c8d0 --- /dev/null +++ b/ui/ceval/css/_ceval.scss @@ -0,0 +1,2 @@ +@import 'ctrl'; +@import 'pv'; diff --git a/ui/ceval/css/_ctrl.scss b/ui/ceval/css/_ctrl.scss new file mode 100644 index 0000000000..209ef75f19 --- /dev/null +++ b/ui/ceval/css/_ctrl.scss @@ -0,0 +1,102 @@ +.ceval { + @extend %metal; + position: relative; + display: flex; + align-items: stretch; + &.enabled { + padding-top: 2px; + height: 40px; + } + .switch { + @extend %flex-center; + flex: 0 0 40px; + margin-right: 8px; + } + pearl { + flex: 0 0 75px; + line-height: 38px; + font-size: 1.6em; + text-align: center; + font-weight: bold; + } + help, + .engine { + @extend %nowrap-hidden; + flex: 1 1 auto; + font-size: 12px; + line-height: 16px; + margin-top: 3px; + color: $c-font-dim; + } + .engine { + .cloud { + @extend %roboto, %box-radius; + margin-left: 4px; + background: $c-secondary-dim; + color: $c-secondary-over; + padding: 1px 3px; + text-transform: uppercase; + font-size: 11px; + } + .info { + display: block; + white-space: nowrap; + } + .deeper { + color: $c-primary; + margin-left: 4px; + } + .deeper::before { + vertical-align: -2px; + } + } + .native { + margin-left: 5px; + text-transform: uppercase; + color: $c-good; + } + .asmjs { + margin-left: 5px; + text-transform: uppercase; + } + .bar { + position: absolute; + width: 100%; + height: 3px; + top: 0px; + } + @keyframes bar-anim { + from { background-position: 0 0; } + to { background-position: 100000px 0; } + } + .bar span { + display: block; + height: 3px; + width: 0; + background: $c-good; + transition: width 1s; + &.threat { + background: $c-bad; + } + } + &.computing .bar span { + background-image: img-url('bar-highlight.png'); + animation: bar-anim 1000s linear infinite; + } + .show-threat { + flex: 0 99 auto; + line-height: 38px; + color: $c-font-dim; + font-size: .9em; + padding-right: .5em; + overflow: hidden; + &:hover:not(.hidden), + &.active { + color: $c-red; + } + &.hidden { + opacity: 0.3; + cursor: default; + } + } +} diff --git a/ui/ceval/css/_eval-gauge.scss b/ui/ceval/css/_eval-gauge.scss new file mode 100644 index 0000000000..cdb68e837a --- /dev/null +++ b/ui/ceval/css/_eval-gauge.scss @@ -0,0 +1,53 @@ +main { + @include fluid-size('--gauge-width', 8px, 17px); + --gauge-gap: #{$block-gap}; + &.gauge-on { + --gauge-gap: calc(var(--gauge-width) * 3/2); + } +} + +.eval-gauge { + width: var(--gauge-width); + position: relative; + background: if($theme-light,#fff,#a0a0a0); + border-radius: 0 5px 5px 0; + overflow: hidden; + @include breakpoint($mq-col1-uniboard) { + display: none; + } + &.reverse { + transform: rotateX(180deg); + } + &::after { + content: ''; + display: block; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + box-shadow: 0 0 5px rgba(0,0,0,0.7) inset; + border-radius: 0 5px 5px 0; + } + tick { + position: absolute; + top: 0; + left: 0; + width: 100%; + border-bottom: 2px ridge if($theme-light,#eee,#a0a0a0); + opacity: 0.4; + } + tick.zero { + top: 6px; + opacity: 1; + border-bottom: 7px solid fade-out($c-accent, 0.6); + margin-top: -3px; + } + .black { + width: 100%; + height: 50%; + background: if($theme-light,#888,#666); + border-radius: 0 5px 0 0; + transition: height 1s; + } +} diff --git a/ui/ceval/css/_pv.scss b/ui/ceval/css/_pv.scss new file mode 100644 index 0000000000..1d8fbd2157 --- /dev/null +++ b/ui/ceval/css/_pv.scss @@ -0,0 +1,23 @@ +.pv_box { + background: $c-bg-box; + font-size: 13px; + .pv { + @extend %nowrap-ellipsis; + height: 2em; + line-height: 2em; + border-top: $border; + &[data-uci]:hover { + background: mix($c-secondary, $c-bg-box, 20%); + cursor: pointer; + } + strong { + display: inline-block; + width: 34px; + text-align: center; + } + span { + @extend %san; + margin-left: 4px; + } + } +} diff --git a/ui/ceval/package.json b/ui/ceval/package.json index d457c35eae..eff5530d26 100644 --- a/ui/ceval/package.json +++ b/ui/ceval/package.json @@ -36,7 +36,6 @@ "dependencies": { "chess": "1.0.0", "common": "1.0.0", - "defer-promise": "^1.0.1", "snabbdom": "ornicar/snabbdom#0.7.1-lichess" } } diff --git a/ui/ceval/src/ctrl.ts b/ui/ceval/src/ctrl.ts index 8fba7534a5..bb1c4b1a64 100644 --- a/ui/ceval/src/ctrl.ts +++ b/ui/ceval/src/ctrl.ts @@ -10,11 +10,11 @@ import { povChances } from './winningChances'; const li = window.lichess; function sanIrreversible(variant: VariantKey, san: string): boolean { - if (san.indexOf('O-O') === 0) return true; + if (san.startsWith('O-O')) return true; if (variant === 'crazyhouse') return false; - if (san.indexOf('x') > 0) return true; // capture + if (san.includes('x')) return true; // capture if (san.toLowerCase() === san) return true; // pawn move - return variant === 'threeCheck' && san.indexOf('+') > 0; + return variant === 'threeCheck' && san.includes('+'); } function officialStockfish(variant: VariantKey): boolean { @@ -23,7 +23,7 @@ function officialStockfish(variant: VariantKey): boolean { function is64Bit(): boolean { const x64 = ['x86_64', 'x86-64', 'Win64','x64', 'amd64', 'AMD64']; - for (const substr of x64) if (navigator.userAgent.indexOf(substr) >= 0) return true; + for (const substr of x64) if (navigator.userAgent.includes(substr)) return true; return navigator.platform === 'Linux x86_64' || navigator.platform === 'MacIntel'; } @@ -73,9 +73,9 @@ export default function(opts: CevalOpts): CevalCtrl { const hashSize = storedProp(storageKey('ceval.hash-size'), 128); const infinite = storedProp('ceval.infinite', false); let curEval: Tree.ClientEval | null = null; - const enableStorage = li.storage.make(storageKey('client-eval-enabled')); + const enableStorage = li.storage.makeBoolean(storageKey('client-eval-enabled')); const allowed = prop(true); - const enabled = prop(opts.possible && allowed() && enableStorage.get() == '1' && !document.hidden); + const enabled = prop(opts.possible && allowed() && enableStorage.get() && !document.hidden); let started: Started | false = false; let lastStarted: Started | false = false; // last started object (for going deeper even if stopped) const hovering = prop(null); @@ -246,7 +246,7 @@ export default function(opts: CevalOpts): CevalCtrl { stop(); enabled(!enabled()); if (document.visibilityState !== 'hidden') - enableStorage.set(enabled() ? '1' : '0'); + enableStorage.set(enabled()); }, curDepth(): number { return curEval ? curEval.depth : 0; diff --git a/ui/ceval/src/pv2san.ts b/ui/ceval/src/pv2san.ts index 98c9d4f1f0..dac546d50a 100644 --- a/ui/ceval/src/pv2san.ts +++ b/ui/ceval/src/pv2san.ts @@ -121,7 +121,7 @@ function makeMove(variant: VariantKey, board: Board, uci: string) { if (!board.turn) board.fmvn++; const turn = board.turn = !board.turn; - if (uci.indexOf('@') !== -1) { + if (uci.includes('@')) { board.pieces[square(uci.slice(2, 4))] = (turn ? uci[0].toLowerCase() : uci[0]) as Piece; return; } @@ -178,7 +178,7 @@ function makeMove(variant: VariantKey, board: Board, uci: string) { } function san(board: Board, uci: string): string { - if (uci.indexOf('@') !== -1) return fixCrazySan(uci); + if (uci.includes('@')) return fixCrazySan(uci); var move = decomposeUci(uci); var from = square(move[0]); diff --git a/ui/ceval/src/stockfishProtocol.ts b/ui/ceval/src/stockfishProtocol.ts index 321a9fa19e..aade1832af 100644 --- a/ui/ceval/src/stockfishProtocol.ts +++ b/ui/ceval/src/stockfishProtocol.ts @@ -1,4 +1,3 @@ -import defer = require('defer-promise'); import { WorkerOpts, Work } from './types'; const EVAL_REGEX = new RegExp('' @@ -43,8 +42,8 @@ export default class Protocol { } received(text: string) { - if (text.indexOf('id name ') === 0) this.engineName = text.substring('id name '.length); - else if (text.indexOf('bestmove ') === 0) { + if (text.startsWith('id name ')) this.engineName = text.substring('id name '.length); + else if (text.startsWith('bestmove ')) { if (!this.stopped) this.stopped = defer(); this.stopped.resolve(); if (this.work && this.curEval) this.work.emit(this.curEval); @@ -56,13 +55,13 @@ export default class Protocol { if (!matches) return; let depth = parseInt(matches[1]), - multiPv = parseInt(matches[2]), - isMate = matches[3] === 'mate', - ev = parseInt(matches[4]), - evalType = matches[5], - nodes = parseInt(matches[6]), - elapsedMs: number = parseInt(matches[7]), - moves = matches[8].split(' '); + multiPv = parseInt(matches[2]), + isMate = matches[3] === 'mate', + ev = parseInt(matches[4]), + evalType = matches[5], + nodes = parseInt(matches[6]), + elapsedMs: number = parseInt(matches[7]), + moves = matches[8].split(' '); // Sometimes we get #0. Let's just skip it. if (isMate && !ev) return; @@ -136,3 +135,12 @@ export default class Protocol { return !this.stopped; } }; + +function defer
    (): DeferPromise.Deferred { + const deferred: Partial> = {} + deferred.promise = new Promise(function (resolve, reject) { + deferred.resolve = resolve + deferred.reject = reject + }) + return deferred as DeferPromise.Deferred; +} diff --git a/ui/ceval/src/view.ts b/ui/ceval/src/view.ts index f1e458acad..54b59aa881 100644 --- a/ui/ceval/src/view.ts +++ b/ui/ceval/src/view.ts @@ -107,7 +107,7 @@ export function renderGauge(ctrl: ParentCtrl): VNode | undefined { gaugeLast = ev; } else ev = gaugeLast; const height = 100 - (ev + 1) * 50; - return h('div.eval_gauge', { + return h('div.eval-gauge', { class: { empty: ev === null, reverse: ctrl.getOrientation() === 'black' @@ -136,7 +136,7 @@ export function renderCeval(ctrl: ParentCtrl): VNode | undefined { pearl = '-'; percent = 0; } else { - pearl = enabled ? h('span.ddloader') : h('span'); + pearl = enabled ? h('i.ddloader') : h('i'); percent = 0; } if (threatMode) { @@ -183,7 +183,7 @@ export function renderCeval(ctrl: ParentCtrl): VNode | undefined { const switchButton: VNode | null = mandatoryCeval ? null : h('div.switch', { attrs: { title: trans.noarg('toggleLocalEvaluation') + ' (l)' } }, [ - h('input#analyse-toggle-ceval.cmn-toggle', { + h('input#analyse-toggle-ceval.cmn-toggle.cmn-toggle--subtle', { attrs: { type: 'checkbox', checked: enabled @@ -195,15 +195,15 @@ export function renderCeval(ctrl: ParentCtrl): VNode | undefined { h('label', { attrs: { 'for': 'analyse-toggle-ceval' } }) ]) - return h('div.ceval_box' + (enabled ? '.enabled' : ''), { + return h('div.ceval' + (enabled ? '.enabled' : ''), { class: { computing: percent < 100 && instance.isComputing() } }, [ progressBar, ...body, - switchButton, - threatButton(ctrl) + threatButton(ctrl), + switchButton ]); } diff --git a/ui/ceval/tsconfig.json b/ui/ceval/tsconfig.json index 360a2e712a..f4507d03e4 100644 --- a/ui/ceval/tsconfig.json +++ b/ui/ceval/tsconfig.json @@ -13,7 +13,8 @@ "noImplicitReturns": true, "noImplicitThis": true, "noUnusedParameters": true, - "target": "es5", - "lib": ["DOM", "ES5", "ES2015.Promise"] + "moduleResolution": "node", + "target": "ES5", + "lib": ["DOM", "ES5", "es2015.core", "es2015.Promise"] } } diff --git a/ui/challenge/css/_challenge.scss b/ui/challenge/css/_challenge.scss new file mode 100644 index 0000000000..8a89bcdfef --- /dev/null +++ b/ui/challenge/css/_challenge.scss @@ -0,0 +1,147 @@ +#challenge-app { + width: 20rem; + right: 0; + text-align: center; + + .empty { + @extend %dropdown-shadow; + background: $c-bg-header-dropdown; + padding: 2rem 0; + } + + &.rendered { + background: transparent!important; + box-shadow: none!important; + border: 0!important; + } + .challenge { + @extend %box-radius-force, %dropdown-shadow; + background: $c-bg-header-dropdown; + margin-bottom: 5px; + @include transition(height); + transition-delay: #{$transition-duration * 2 / 3}; + position: relative; + height: 67px; + &:hover { + transition-delay: 0ms; + height: 103px; + > i { + color: $c-primary; + } + } + &.declined { + height: 0; + padding: 0; + opacity: 0; + } + .buttons { + position: absolute; + opacity: 0; + top: 62px; + left: 0px; + width: 100%; + @include transition(opacity); + transition-delay: 0ms; + } + &:hover .buttons { + opacity: 1; + transition-delay: 100ms; + } + .buttons > * { + position: absolute; + top: 0; + left: 0; + width: 50%; + } + .buttons > *:last-child { + left: 50%; + } + button { + cursor: pointer; + color: $c-good; + width: 100%; + display: block; + padding: 0; + background: transparent; + font-size: 1.6rem; + @include transition(); + box-shadow: none; + } + button, + .owner { + height: 42px; + } + .owner { + color: $c-link; + line-height: 42px; + } + .owner .view, + .owner:hover .waiting { + display: none; + } + .owner:hover .view { + display: block; + background: $c-primary; + color: $c-primary-over; + &::before { + vertical-align: middle; + } + } + button::before { + line-height: 42px; + } + button.decline { + color: $c-bad; + border-right: none; + } + button:hover { + background: $c-good; + color: $c-good-over; + } + button.decline:hover { + background: $c-bad; + } + &:last-child { + border-bottom: none; + } + > i { + position: absolute; + top: 6px; + right: 1rem; + display: block; + font-size: 2.6em; + } + .content { + @extend %nowrap-ellipsis; + position: absolute; + top: 10px; + left: 16px; + display: block; + width: 196px; + text-align: left; + } + .head { + display: block; + font-weight: bold; + margin-bottom: 3px; + } + .head .user-link { + margin-left: -5px; + } + } + + .create { + @extend %box-radius-bottom; + display: inline-block; + padding: 0 28px 3px 28px; + margin: auto; + background: rgba(56,147,232,0.5); + color: rgba(255,255,255,0.6); + @include transition(); + } + .create:hover { + background: rgba(56,147,232,0.9); + color: rgba(255,255,255,0.6); + padding-top: 4px; + } +} diff --git a/ui/challenge/css/_page.scss b/ui/challenge/css/_page.scss new file mode 100644 index 0000000000..562c473a1f --- /dev/null +++ b/ui/challenge/css/_page.scss @@ -0,0 +1,78 @@ +$c-challenge: $c-secondary; + +.challenge-page { + + .challenge-id-form { + white-space: nowrap; + } + .invite { + display: flex; + flex-flow: row wrap; + > div { + @extend %box-radius; + padding: 2em 2em 1em 2em; + background: $c-bg-zebra; + margin: 1em; + flex: 1 1 auto; + } + } + .waiting { + text-align: center; + .user-link { + font-size: 2em; + } + .spinner { + width: 13em; + height: 13em; + margin: 2em auto; + } + } + .cancel { + margin: 2em 0; + text-align: center; + } + .details { + @extend %flex-between; + border-radius: 99px; + background: mix($c-challenge, $c-bg-box, 10%); + border: 1px solid $c-challenge; + padding: .5em 1.1em; + margin-bottom: 3rem; + font-size: 2em; + > div { + @extend %flex-center, %roboto; + &::before { + color: $c-challenge; + font-size: 6rem; + margin-right: .2em; + } + div { + line-height: 1.4; + } + .clock { + font-weight: bold; + } + } + .mode { + font-weight: bold; + color: $c-challenge; + text-transform: uppercase; + } + } + .follow-up .button { + display: block; + margin-top: 2em; + } + .board-preview { + margin: 0 auto; + max-width: 300px; + } +} + +.challenge-theirs { + .button-fat { + display: block; + width: 100%; + margin-top: 2em; + } +} diff --git a/ui/challenge/css/build/_challenge.page.scss b/ui/challenge/css/build/_challenge.page.scss new file mode 100644 index 0000000000..f9d30ec510 --- /dev/null +++ b/ui/challenge/css/build/_challenge.page.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/plugin'; +@import '../page'; diff --git a/ui/challenge/css/build/_challenge.scss b/ui/challenge/css/build/_challenge.scss new file mode 100644 index 0000000000..563648a2e5 --- /dev/null +++ b/ui/challenge/css/build/_challenge.scss @@ -0,0 +1,5 @@ +@import '../../../common/css/plugin'; + +$c-new: $c-secondary; + +@import '../challenge'; diff --git a/ui/challenge/css/build/challenge.dark.scss b/ui/challenge/css/build/challenge.dark.scss new file mode 100644 index 0000000000..6a56952e6b --- /dev/null +++ b/ui/challenge/css/build/challenge.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'challenge'; diff --git a/ui/challenge/css/build/challenge.light.scss b/ui/challenge/css/build/challenge.light.scss new file mode 100644 index 0000000000..99ed42ea7b --- /dev/null +++ b/ui/challenge/css/build/challenge.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'challenge'; diff --git a/ui/challenge/css/build/challenge.page.dark.scss b/ui/challenge/css/build/challenge.page.dark.scss new file mode 100644 index 0000000000..89790b67a4 --- /dev/null +++ b/ui/challenge/css/build/challenge.page.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'challenge.page'; diff --git a/ui/challenge/css/build/challenge.page.light.scss b/ui/challenge/css/build/challenge.page.light.scss new file mode 100644 index 0000000000..16de4f90f1 --- /dev/null +++ b/ui/challenge/css/build/challenge.page.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'challenge.page'; diff --git a/ui/challenge/css/build/challenge.page.transp.scss b/ui/challenge/css/build/challenge.page.transp.scss new file mode 100644 index 0000000000..9de27be41c --- /dev/null +++ b/ui/challenge/css/build/challenge.page.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'challenge.page'; diff --git a/ui/challenge/css/build/challenge.transp.scss b/ui/challenge/css/build/challenge.transp.scss new file mode 100644 index 0000000000..699905ce03 --- /dev/null +++ b/ui/challenge/css/build/challenge.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'challenge'; diff --git a/ui/challenge/gulpfile.js b/ui/challenge/gulpfile.js index 6515e9ad0f..482dee14bb 100644 --- a/ui/challenge/gulpfile.js +++ b/ui/challenge/gulpfile.js @@ -1,3 +1,2 @@ -const lilaGulp = require('../gulp/tsProject.js'); - -lilaGulp('LichessChallenge', 'lichess.challenge', __dirname); +require('../gulp/tsProject.js')('LichessChallenge', 'lichess.challenge', __dirname); +require('../gulp/cssProject.js')(__dirname); diff --git a/ui/challenge/src/ctrl.ts b/ui/challenge/src/ctrl.ts index 42e9bd9ef5..40bb509c07 100644 --- a/ui/challenge/src/ctrl.ts +++ b/ui/challenge/src/ctrl.ts @@ -1,5 +1,6 @@ -import * as xhr from './xhr' -import { Ctrl, ChallengeOpts, ChallengeData, ChallengeUser } from './interfaces' +import * as xhr from './xhr'; +import notify from 'common/notification'; +import { Ctrl, ChallengeOpts, ChallengeData, ChallengeUser } from './interfaces'; const li = window.lichess; @@ -26,7 +27,7 @@ export default function(opts: ChallengeOpts, data: ChallengeData, redraw: () => opts.show(); li.sound.newChallenge(); } - c.challenger && li.desktopNotification(showUser(c.challenger) + ' challenges you!'); + c.challenger && notify(showUser(c.challenger) + ' challenges you!'); opts.pulse(); } }); diff --git a/ui/challenge/src/view.ts b/ui/challenge/src/view.ts index f50177c29f..7f5744161c 100644 --- a/ui/challenge/src/view.ts +++ b/ui/challenge/src/view.ts @@ -4,12 +4,12 @@ import { Ctrl, Challenge, ChallengeData, ChallengeDirection, ChallengeUser, Time export function loaded(ctrl: Ctrl): VNode { return ctrl.redirecting() ? - h('div#challenge_app.dropdown', h('div.initiating', spinner())) : - h('div#challenge_app.links.dropdown.rendered', renderContent(ctrl)); + h('div#challenge-app.dropdown', h('div.initiating', spinner())) : + h('div#challenge-app.links.dropdown.rendered', renderContent(ctrl)); } export function loading(): VNode { - return h('div#challenge_app.links.dropdown.rendered', [ + return h('div#challenge-app.links.dropdown.rendered', [ h('div.empty.loading', '-'), create() ]); @@ -126,7 +126,7 @@ function timeControl(c: TimeControl): string { function renderUser(u?: ChallengeUser): VNode { if (!u) return h('span', 'Open challenge'); const rating = u.rating + (u.provisional ? '?' : ''); - return h('a.ulpt.user_link', { + return h('a.ulpt.user-link', { attrs: { href: `/@/${u.name}`}, class: { online: !!u.online } }, [ diff --git a/ui/challenge/tsconfig.json b/ui/challenge/tsconfig.json index 1c393ceda3..17b848bc94 100644 --- a/ui/challenge/tsconfig.json +++ b/ui/challenge/tsconfig.json @@ -8,7 +8,8 @@ "noImplicitReturns": true, "noImplicitThis": true, "noUnusedParameters": true, - "target": "es5", - "lib": ["DOM", "ES5"] + "moduleResolution": "node", + "target": "ES5", + "lib": ["DOM", "ES5", "es2015.core", "es2015.Promise"] } } diff --git a/ui/chat/css/_chat.mod.scss b/ui/chat/css/_chat.mod.scss new file mode 100644 index 0000000000..8ad96551d8 --- /dev/null +++ b/ui/chat/css/_chat.mod.scss @@ -0,0 +1,95 @@ +.mchat-mod { + + li { + position: relative; + } + i.mod { + display: none; + position: absolute; + top: 5px; + right: 0; + cursor: pointer; + margin-right: 3px; + padding: 4px 5px; + opacity: 0.7; + color: $c-accent; + &:hover { + opacity: 1; + } + } + li:hover { + background: mix($c-accent, $c-bg-box, 7%); + i.mod { + display: block; + text-shadow: 0 0 2px $c-bg-box, 0 0 5px $c-bg-box, 0 0 10px $c-bg-box; + } + } + + .top { + @extend %flex-center; + justify-content: space-between; + flex: 0 0 auto; + background: $c-accent; + color: #fff; + padding: .4em 10px; + line-height: 1.4em; + a { + color: #fff; + } + } + .moderation { + background: $c-bg-box; + overflow: auto; + + .block { + padding: 0 10px 10px 10px; + } + .history { + td { + padding: .3rem .5rem .3rem 0; + } + table { + width: 100%; + } + .reason { + text-transform: capitalize; + } + .mod, + time { + opacity: 0.8; + } + } + .infos { + padding-top: 10px; + } + .infos > * { + display: inline-block; + margin-right: 5px; + } + .timeout a { + @extend %nowrap-ellipsis; + color: $c-accent; + display: block; + line-height: 1.5em; + @include transition(); + margin-left: -10px; + } + .timeout a::before { + opacity: 0; + transition: 0.3s; + } + .timeout a:hover { + margin-left: 0; + } + .timeout a:hover::before { + opacity: 1; + margin-right: 2px; + } + .shadowban { + margin-top: 10px; + } + .shadowban form { + display: inline; + } + } +} diff --git a/ui/chat/css/_chat.scss b/ui/chat/css/_chat.scss new file mode 100644 index 0000000000..2449068310 --- /dev/null +++ b/ui/chat/css/_chat.scss @@ -0,0 +1,27 @@ +@import '../../../common/css/base/scrollbar'; + +@import 'tab'; +@import 'members'; +@import 'discussion'; + +.mchat { + @extend %box-neat-force, %flex-column; + grid-area: chat; + justify-content: stretch; + &__content { + @extend %flex-column; + background: $c-bg-box; + flex: 1 1 auto; + overflow: hidden; + &.note textarea { + font-size: .9em; + flex-grow: 1; + border: none; + background-color: transparent; + line-height: 1.7em; + outline: none; + resize: none; + } + } + min-height: 15em; +} diff --git a/ui/chat/css/_discussion.scss b/ui/chat/css/_discussion.scss new file mode 100644 index 0000000000..73ea158024 --- /dev/null +++ b/ui/chat/css/_discussion.scss @@ -0,0 +1,57 @@ +.mchat { + &__messages { + @extend %break-word; + flex: 1 1 auto; + max-height: 50vh; + @include breakpoint($mq-col3-uniboard) { + max-height: none; + } + overflow-y: auto; + overflow-x: hidden; + cursor: initial; + font-size: .9em; + li { + padding: .5em 0 .5em 10px; + line-height: 1.2em; + overflow-y: hidden; + user-select: text; + } + .deleted { + opacity: 0.5; + } + .system { + display: block; + opacity: 0.8; + font-style: italic; + font-size: 0.9em; + margin-left: 0; + text-align: center; + } + .color, + .user-link { + font-weight: bold; + padding: 0; + color: $c-font-dim; + letter-spacing: -1px; + margin-right: .4em; + } + .title { + margin-right: 3px; + } + a:not(.user-link) { + @extend %roboto; + } + } + &__say { + flex: 0 0 auto; + border: 0; + border-top: $border; + border-radius: 0; + padding: 3px 20px 3px 4px; + &.whisper { + color: $c-good; + font-weight: bold; + font-style: italic; + } + } +} diff --git a/ui/chat/css/_members.scss b/ui/chat/css/_members.scss new file mode 100644 index 0000000000..00df6eb3f4 --- /dev/null +++ b/ui/chat/css/_members.scss @@ -0,0 +1,8 @@ +.chat__members { + @extend %page-text; + font-size: .9em; + // min-height: 5em; + // max-height: 9em; + height: 100%; + overflow: hidden; +} diff --git a/ui/chat/css/_preset.scss b/ui/chat/css/_preset.scss new file mode 100644 index 0000000000..c8a6bea7fe --- /dev/null +++ b/ui/chat/css/_preset.scss @@ -0,0 +1,31 @@ +.mchat { + &__presets { + display: flex; + flex: 0 0 auto; + align-items: center; + flex-flow: row nowrap; + line-height: 1.4em; + span { + flex: 1 1 auto; + text-align: center; + display: block; + opacity: 0.8; + border: $border; + border-width: 1px 1px 0 0; + font-size: .9em; + text-transform: uppercase; + cursor: pointer; + @include transition(); + &.disabled { + background: mix($c-accent, $c-bg-box, 15%); + color: transparent; + cursor: default; + } + &:not(.disabled):hover { + background: $c-accent; + color: $c-accent-over; + opacity: 1; + } + } + } +} diff --git a/ui/chat/css/_tab.scss b/ui/chat/css/_tab.scss new file mode 100644 index 0000000000..d1f52f306a --- /dev/null +++ b/ui/chat/css/_tab.scss @@ -0,0 +1,41 @@ +.mchat { + &__tabs { + flex: 0 0 auto; + display: flex; + } + &__tab { + @extend %roboto, %nowrap-hidden, %box-radius-top; + flex: 1 1 auto; + text-align: center; + padding: .4em 10px; + // background: $c-shade; + cursor: pointer; + color: $c-font-page; + @include transition(); + &:hover { + background: mix($c-accent, $c-bg-box, 15%); + } + &-active { + color: $c-font; + background: $c-bg-box !important; + } + input { + cursor: pointer; + display: none; + } + &-active input { + display: block; + } + span { + @extend %nowrap-ellipsis; + } + &:last-child { + border-right: none; + } + } + &-optional .mchat__tab.discussion { + display: flex; + justify-content: space-between; + align-items: center; + } +} diff --git a/ui/chat/css/build/_chat.mod.scss b/ui/chat/css/build/_chat.mod.scss new file mode 100644 index 0000000000..0154799c3e --- /dev/null +++ b/ui/chat/css/build/_chat.mod.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/plugin'; +@import '../chat.mod'; diff --git a/ui/chat/css/build/chat.mod.dark.scss b/ui/chat/css/build/chat.mod.dark.scss new file mode 100644 index 0000000000..4d028b2fec --- /dev/null +++ b/ui/chat/css/build/chat.mod.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'chat.mod'; diff --git a/ui/chat/css/build/chat.mod.light.scss b/ui/chat/css/build/chat.mod.light.scss new file mode 100644 index 0000000000..2dc152179c --- /dev/null +++ b/ui/chat/css/build/chat.mod.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'chat.mod'; diff --git a/ui/chat/css/build/chat.mod.transp.scss b/ui/chat/css/build/chat.mod.transp.scss new file mode 100644 index 0000000000..580cf3253f --- /dev/null +++ b/ui/chat/css/build/chat.mod.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'chat.mod'; diff --git a/ui/chat/src/ctrl.ts b/ui/chat/src/ctrl.ts index 4f17003b3e..eb1f1df81e 100644 --- a/ui/chat/src/ctrl.ts +++ b/ui/chat/src/ctrl.ts @@ -9,19 +9,17 @@ export default function(opts: ChatOpts, redraw: Redraw): Ctrl { const data = opts.data; - const pubsub = li.pubsub; - const allTabs: Tab[] = ['discussion']; if (opts.noteId) allTabs.push('note'); if (opts.plugin) allTabs.push(opts.plugin.tab.key); const tabStorage = li.storage.make('chat.tab'), - storedTab = tabStorage.get(); + storedTab = tabStorage.get(); let moderation: ModerationCtrl | undefined; const vm: ViewModel = { - tab: allTabs.indexOf(storedTab) > -1 ? storedTab : allTabs[0], + tab: allTabs.find(tab => tab === storedTab) || allTabs[0], enabled: opts.alwaysEnabled || !li.storage.get('nochat'), placeholderKey: 'talkInChat', loading: false, @@ -29,15 +27,18 @@ export default function(opts: ChatOpts, redraw: Redraw): Ctrl { writeable: opts.writeable }; - const post = function(text: string): boolean { + /* If discussion is disabled, and we have another chat tab, + * then select that tab over discussion */ + if (allTabs.length > 1 && vm.tab === 'discussion' && li.storage.get('nochat')) vm.tab = allTabs[1]; + + const post = function(text: string): void { text = text.trim(); - if (!text) return false; + if (!text) return; if (text.length > 140) { alert('Max length: 140 chars. ' + text.length + ' chars used.'); - return false; + return; } - pubsub.emit('socket.send')('talk', text); - return false; + li.pubsub.emit('socket.send')('talk', text); }; const onTimeout = function(username: string) { @@ -61,6 +62,18 @@ export default function(opts: ChatOpts, redraw: Redraw): Ctrl { redraw(); }; + const onWriteable = function(v: boolean) { + vm.writeable = v; + redraw(); + } + + const onPermissions = function(obj: Permissions) { + let p: keyof Permissions; + for (p in obj) opts.permissions[p] = obj[p]; + instanciateModeration(); + redraw(); + } + const trans = li.trans(opts.i18n); function canMod() { @@ -74,7 +87,7 @@ export default function(opts: ChatOpts, redraw: Redraw): Ctrl { send: li.pubsub.emit('socket.send'), redraw }) : undefined; - if (canMod()) opts.loadCss('stylesheets/chat.mod.css'); + if (canMod()) opts.loadCss('chat.mod'); } instanciateModeration(); @@ -90,21 +103,20 @@ export default function(opts: ChatOpts, redraw: Redraw): Ctrl { redraw }); - pubsub.on('socket.in.message', onMessage); - pubsub.on('socket.in.chat_timeout', onTimeout); - pubsub.on('socket.in.chat_reinstate', onReinstate); - pubsub.on('chat.writeable', function(v: boolean) { - vm.writeable = v; - redraw(); - }); - pubsub.on('chat.permissions', function(obj: Permissions) { - let p: keyof Permissions; - for (p in obj) opts.permissions[p] = obj[p]; - instanciateModeration(); - redraw(); - }); + const subs: [string, PubsubCallback][] = [ + ['socket.in.message', onMessage], + ['socket.in.chat_timeout', onTimeout], + ['socket.in.chat_reinstate', onReinstate], + ['chat.writeable', onWriteable], + ['chat.permissions', onPermissions] + ]; + subs.forEach(([eventName, callback]) => li.pubsub.on(eventName, callback)); - const emitEnabled = () => pubsub.emit('chat.enabled')(vm.enabled); + const destroy = () => { + subs.forEach(([eventName, callback]) => li.pubsub.off(eventName, callback)); + }; + + const emitEnabled = () => li.pubsub.emit('chat.enabled')(vm.enabled); emitEnabled(); return { @@ -116,7 +128,7 @@ export default function(opts: ChatOpts, redraw: Redraw): Ctrl { vm.tab = t; tabStorage.set(t); // It's a lame way to do it. Give me a break. - if (t === 'discussion') li.requestIdleCallback(() => $('.mchat input.lichess_say').focus()); + if (t === 'discussion') li.requestIdleCallback(() => $('.mchat__say').focus()); redraw(); }, moderation: () => moderation, @@ -132,6 +144,7 @@ export default function(opts: ChatOpts, redraw: Redraw): Ctrl { else li.storage.remove('nochat'); redraw(); }, - redraw + redraw, + destroy }; }; diff --git a/ui/chat/src/discussion.ts b/ui/chat/src/discussion.ts index 8466c19fc8..467683a4e4 100644 --- a/ui/chat/src/discussion.ts +++ b/ui/chat/src/discussion.ts @@ -23,7 +23,7 @@ export default function(ctrl: Ctrl): Array { }, m = ctrl.moderation(); const vnodes = [ - h('ol.messages.content.scroll-shadow-soft' + (m ? '.as-mod' : ''), { + h('ol.mchat__messages', { attrs: { role: 'log', 'aria-live': 'polite', @@ -52,7 +52,7 @@ export default function(ctrl: Ctrl): Array { function renderInput(ctrl: Ctrl): VNode | undefined { if (!ctrl.vm.writeable) return; if ((ctrl.data.loginRequired && !ctrl.data.userId) || ctrl.data.restricted) - return h('input.lichess_say', { + return h('input.mchat__say', { attrs: { placeholder: ctrl.trans('loginToChat'), disabled: true @@ -62,7 +62,7 @@ function renderInput(ctrl: Ctrl): VNode | undefined { if (ctrl.vm.timeout) placeholder = ctrl.trans('youHaveBeenTimedOut'); else if (ctrl.opts.blind) placeholder = 'Chat'; else placeholder = ctrl.trans.noarg(ctrl.vm.placeholderKey); - return h('input.lichess_say', { + return h('input.mchat__say', { attrs: { placeholder, autocomplete: 'off', diff --git a/ui/chat/src/enhance.ts b/ui/chat/src/enhance.ts index 7b9e3572cd..019db139a2 100644 --- a/ui/chat/src/enhance.ts +++ b/ui/chat/src/enhance.ts @@ -8,7 +8,7 @@ export default function(text: string, parseMoves: boolean): string { const linkPattern = /\b(https?:\/\/|lichess\.org\/)[-–—\w+&'@#\/%?=()~|!:,.;]+[\w+&@#\/%=~|]/gi; function linkReplace(url: string, scheme: string) { - if (url.indexOf('"') !== -1) return url; + if (url.includes('"')) return url; const fullUrl = scheme === 'lichess.org/' ? 'https://' + url : url; const minUrl = url.replace(/^https:\/\//, ''); return '' + minUrl + ''; diff --git a/ui/chat/src/interfaces.ts b/ui/chat/src/interfaces.ts index 76a47cc006..41229602da 100644 --- a/ui/chat/src/interfaces.ts +++ b/ui/chat/src/interfaces.ts @@ -61,12 +61,13 @@ export interface Ctrl { preset: PresetCtrl note?: NoteCtrl moderation(): ModerationCtrl | undefined - post(text: string): boolean + post(text: string): void trans: Trans setTab(tab: Tab): void setEnabled(v: boolean): void plugin?: ChatPlugin redraw: Redraw + destroy(): void; } export interface ViewModel { diff --git a/ui/chat/src/main.ts b/ui/chat/src/main.ts index ac97151108..05d1e47082 100644 --- a/ui/chat/src/main.ts +++ b/ui/chat/src/main.ts @@ -26,10 +26,12 @@ export default function LichessChat(element: Element, opts: ChatOpts): { ctrl = makeCtrl(opts, redraw); - vnode = patch(element, view(ctrl)); + const blueprint = view(ctrl); + element.innerHTML = ''; + vnode = patch(element, blueprint); - window.Mousetrap.bind('/', () => { - (container.querySelector('input.lichess_say') as HTMLElement).focus(); + window.Mousetrap.bind('c', () => { + (container.querySelector('.mchat__say') as HTMLElement).focus(); return false; }); diff --git a/ui/chat/src/moderation.ts b/ui/chat/src/moderation.ts index 12527bb91a..399f28aa44 100644 --- a/ui/chat/src/moderation.ts +++ b/ui/chat/src/moderation.ts @@ -93,7 +93,7 @@ export function moderationView(ctrl?: ModerationCtrl): VNode[] | undefined { ] : [])) : undefined; const timeout = perms.timeout ? h('div.timeout.block', [ - h('h2', 'Timeout 10 minutes for'), + h('strong', 'Timeout 10 minutes for'), ...ctrl.reasons.map(r => { return h('a.text', { attrs: { 'data-icon': 'p' }, @@ -103,12 +103,12 @@ export function moderationView(ctrl?: ModerationCtrl): VNode[] | undefined { ...( (data.troll || !perms.shadowban) ? [] : [h('div.shadowban', [ 'Or ', - h('button.button', { + h('button.button.button-red.button-empty', { hook: bind('click', ctrl.shadowban) }, 'shadowban') ])]) ]) : h('div.timeout.block', [ - h('h2', 'Moderation'), + h('strong', 'Moderation'), h('a.text', { attrs: { 'data-icon': 'p' }, hook: bind('click', () => ctrl.timeout(ctrl.reasons[0])) @@ -116,7 +116,7 @@ export function moderationView(ctrl?: ModerationCtrl): VNode[] | undefined { ]); const history = data.history ? h('div.history.block', [ - h('h2', 'Timeout history'), + h('strong', 'Timeout history'), h('table', h('tbody.slist', { hook: { insert: () => window.lichess.pubsub.emit('content_loaded')() @@ -137,12 +137,12 @@ export function moderationView(ctrl?: ModerationCtrl): VNode[] | undefined { h('span.text', { attrs: {'data-icon': '' }, }, [userLink(data.username)]), - h('span.toggle_chat', { + h('a', { attrs: {'data-icon': 'L'}, hook: bind('click', ctrl.close) }) ]), - h('div.content.moderation', [ + h('div.mchat__content.moderation', [ infos, timeout, history diff --git a/ui/chat/src/note.ts b/ui/chat/src/note.ts index 630dea1178..cddcd4a46b 100644 --- a/ui/chat/src/note.ts +++ b/ui/chat/src/note.ts @@ -6,7 +6,7 @@ import { spinner } from './util' export function noteCtrl(opts: NoteOpts): NoteCtrl { let text: string - const doPost = window.lichess.fp.debounce(() => { + const doPost = window.lichess.debounce(() => { xhr.setNote(opts.id, text); }, 1000); return { diff --git a/ui/chat/src/preset.ts b/ui/chat/src/preset.ts index ec64b01f74..cae241a2f5 100644 --- a/ui/chat/src/preset.ts +++ b/ui/chat/src/preset.ts @@ -27,7 +27,7 @@ export interface PresetGroups { export interface PresetOpts { initialGroup?: string redraw: Redraw - post(text: string): boolean + post(text: string): void } const groups: PresetGroups = { @@ -59,7 +59,7 @@ export function presetCtrl(opts: PresetOpts): PresetCtrl { if (!group) return; const sets = groups[group]; if (!sets) return; - if (said.indexOf(preset.key) !== -1) return; + if (said.includes(preset.key)) return; opts.post(preset.text); said.push(preset.key); } @@ -71,14 +71,14 @@ export function presetView(ctrl: PresetCtrl): VNode | undefined { if (!group) return; const sets = groups[group]; const said = ctrl.said(); - return (sets && said.length < 2) ? h('div.presets', sets.map((p: Preset) => { - const disabled = said.indexOf(p.key) !== -1; - return h('span.hint--top', { + return (sets && said.length < 2) ? h('div.mchat__presets', sets.map((p: Preset) => { + const disabled = said.includes(p.key); + return h('span', { class: { disabled }, attrs: { - 'data-hint': p.text, + title: p.text, disabled }, hook: bind('click', () => { !disabled && ctrl.post(p) }) diff --git a/ui/chat/src/util.ts b/ui/chat/src/util.ts index 144e123f63..06fd4d3a78 100644 --- a/ui/chat/src/util.ts +++ b/ui/chat/src/util.ts @@ -2,11 +2,11 @@ import { h } from 'snabbdom' import { VNode } from 'snabbdom/vnode' export function userLink(u: string, title?: string) { - const spaced = u.substring(0, 14) + ' '; + const trunc = u.substring(0, 14); return h('a', { // can't be inlined because of thunks class: { - user_link: true, + 'user-link': true, ulpt: true }, attrs: { @@ -16,8 +16,8 @@ export function userLink(u: string, title?: string) { h( 'span.title', title == 'BOT' ? { attrs: {'data-bot': true } } : {}, - title), spaced - ] : [spaced]); + title), trunc + ] : [trunc]); } export function spinner() { diff --git a/ui/chat/src/view.ts b/ui/chat/src/view.ts index f1c8ad29dd..5298df0155 100644 --- a/ui/chat/src/view.ts +++ b/ui/chat/src/view.ts @@ -10,9 +10,12 @@ export default function(ctrl: Ctrl): VNode { const mod = ctrl.moderation(); - return h('div#chat.side_box.mchat' + (ctrl.opts.alwaysEnabled ? '' : '.optional'), { + return h('section.mchat' + (ctrl.opts.alwaysEnabled ? '' : '.mchat-optional'), { class: { - mod: !!mod + 'mchat-mod': !!mod + }, + hook: { + destroy: ctrl.destroy } }, moderationView(mod) || normalView(ctrl)) } @@ -20,8 +23,8 @@ export default function(ctrl: Ctrl): VNode { function normalView(ctrl: Ctrl) { const active = ctrl.vm.tab; return [ - h('div.chat_tabs.nb_' + ctrl.allTabs.length, ctrl.allTabs.map(t => renderTab(ctrl, t, active))), - h('div.content.' + active, + h('div.mchat__tabs.nb_' + ctrl.allTabs.length, ctrl.allTabs.map(t => renderTab(ctrl, t, active))), + h('div.mchat__content.' + active, (active === 'note' && ctrl.note) ? [noteView(ctrl.note)] : ( ctrl.plugin && active === ctrl.plugin.tab.key ? [ctrl.plugin.view()] : discussionView(ctrl) )) @@ -29,16 +32,16 @@ function normalView(ctrl: Ctrl) { } function renderTab(ctrl: Ctrl, tab: Tab, active: Tab) { - return h('div.tab.' + tab, { - class: { active: tab === active }, + return h('div.mchat__tab.' + tab, { + class: { 'mchat__tab-active': tab === active }, hook: bind('click', () => ctrl.setTab(tab)) }, tabName(ctrl, tab)); } function tabName(ctrl: Ctrl, tab: Tab) { if (tab === 'discussion') return [ - h('h2', ctrl.data.name), - ctrl.opts.alwaysEnabled ? undefined : h('input.toggle_chat', { + h('span', ctrl.data.name), + ctrl.opts.alwaysEnabled ? undefined : h('input', { attrs: { type: 'checkbox', title: ctrl.trans.noarg('toggleTheChat'), @@ -49,7 +52,7 @@ function tabName(ctrl: Ctrl, tab: Tab) { }) }) ]; - if (tab === 'note') return [h('h2', ctrl.trans.noarg('notes'))]; - if (ctrl.plugin && tab === ctrl.plugin.tab.key) return [h('h2', ctrl.plugin.tab.name)]; + if (tab === 'note') return [h('span', ctrl.trans.noarg('notes'))]; + if (ctrl.plugin && tab === ctrl.plugin.tab.key) return [h('span', ctrl.plugin.tab.name)]; return []; } diff --git a/ui/chat/tsconfig.json b/ui/chat/tsconfig.json index 36c1ad6de5..9218714396 100644 --- a/ui/chat/tsconfig.json +++ b/ui/chat/tsconfig.json @@ -12,7 +12,9 @@ "noImplicitReturns": true, "noImplicitThis": true, "noUnusedParameters": true, - "target": "es5", - "lib": ["DOM", "ES5"] + "moduleResolution": "node", + "moduleResolution": "node", + "target": "ES5", + "lib": ["DOM", "ES5", "es2015.core", "es2015.Promise"] } } diff --git a/ui/chess/css/_control.scss b/ui/chess/css/_control.scss new file mode 100644 index 0000000000..0ff4157c1d --- /dev/null +++ b/ui/chess/css/_control.scss @@ -0,0 +1,24 @@ +.analyse-controls { + display: flex; + justify-content: space-between; + align-items: stretch; + font-size: 1.3rem; + .fbt { + @extend %box-radius-bottom; + text-align: center; + } + .hidden { + visibility: hidden; + } + .jumps { + display: flex; + .fbt { + flex: 1 1 30%; + &:first-child, + &:last-child { + flex: 1 1 20%; + font-size: .7em; + } + } + } +} diff --git a/ui/chess/css/_opening.scss b/ui/chess/css/_opening.scss new file mode 100644 index 0000000000..4b191815ed --- /dev/null +++ b/ui/chess/css/_opening.scss @@ -0,0 +1,6 @@ +.opening_box { + @extend %roboto, %nowrap-ellipsis; + padding: 5px; + border-bottom: $border; + background: $c-bg-zebra; +} diff --git a/ui/chess/css/_promotion.scss b/ui/chess/css/_promotion.scss new file mode 100644 index 0000000000..95c0cf5ff1 --- /dev/null +++ b/ui/chess/css/_promotion.scss @@ -0,0 +1,29 @@ +#promotion-choice { + @extend %abs-100; + position: absolute; + background: fade-out($c-bg-page, .3); + z-index: z('cg__promotion'); + square { + cursor: pointer; + border-radius: 50%; + background-color: #b0b0b0; + box-shadow: inset 0 0 25px 3px #808080; + @include transition(); + } + piece { + pointer-events: auto; + } + .is2d & piece { + width: 100%; + height: 100%; + @include transition(); + transform: scale(0.8); + } + square:hover { + box-shadow: inset 0 0 48px 8px $c-accent; + border-radius: 0%; + } + .is2d & square:hover piece { + transform: none; + } +} diff --git a/ui/chess/css/_variant-style.scss b/ui/chess/css/_variant-style.scss new file mode 100644 index 0000000000..73c90393ad --- /dev/null +++ b/ui/chess/css/_variant-style.scss @@ -0,0 +1,35 @@ +.variant-racingKings .cg-board-wrap { + + &.cg-board-wrap::before { + @extend %popup-shadow; + background: hsla(0, 0%, 90%, .2); + width: 100%; + height: 12.5%; + content: ''; + position: absolute; + left: 0; + z-index: 1; + pointer-events: none; + } + + &.orientation-white::before { + top: 0; + } + + &.orientation-black::before { + bottom: 0; + } +} + +.variant-kingOfTheHill .cg-board-wrap::before { + width: 25%; + height: 25%; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.7); + background: hsla(0, 0%, 90%, .2); + content: ''; + position: absolute; + top: 37.5%; + left: 37.5%; + z-index: 1; + pointer-events: none; +} diff --git a/ui/chess/css/_zh-pocket.scss b/ui/chess/css/_zh-pocket.scss new file mode 100644 index 0000000000..a486376ca6 --- /dev/null +++ b/ui/chess/css/_zh-pocket.scss @@ -0,0 +1,59 @@ +.pocket { + @extend %box-radius; + display: flex; + width: 62.5%; + @include breakpoint($mq-col2-uniboard) { + width: 100%; + box-shadow: 0 3px 5px rgba(0,0,0,0.3) inset; + background: #888; + } + &-c1 { + flex: 0 0 20%; + max-width: 10vmin; + } + &-c2 { + @extend %square; + } + piece { + display: block; + width: 100%!important; + height: 100%!important; + @include transition(); + &::after { + @extend %active, %box-radius; + content: attr(data-nb); + bottom: 0; + right: 0; + position: absolute; + line-height: .9em; + padding: 3px .3em; + font-weight: bold; + font-size: 1.1em; + } + &[data-nb='0'] { + cursor: auto; + opacity: 0.1; + &::after { + content: none; + } + } + &.premove { + background-color: #555; + } + } + &.usable { + piece { + cursor: pointer; + pointer-events: auto; + &:hover { + background-color: #aaa; + } + &:first-child:hover { + @extend %box-radius-left; + } + } + } + .blindfold &:not(.usable) { + opacity: 0; + } +} diff --git a/ui/chess/tsconfig.json b/ui/chess/tsconfig.json index 8bc5ab66eb..fd810791ec 100644 --- a/ui/chess/tsconfig.json +++ b/ui/chess/tsconfig.json @@ -12,6 +12,8 @@ "noImplicitReturns": true, "noImplicitThis": true, "noUnusedParameters": true, - "target": "es5" + "moduleResolution": "node", + "target": "ES5", + "lib": ["DOM", "ES5", "es2015.core", "es2015.Promise"] } } diff --git a/ui/cli/css/_clinput.scss b/ui/cli/css/_clinput.scss new file mode 100644 index 0000000000..fbc976dd14 --- /dev/null +++ b/ui/cli/css/_clinput.scss @@ -0,0 +1,42 @@ +#clinput { + display: flex; + height: $site-header-height; + input { + @extend %page-text; + line-height: $site-header-height; + background: none; + padding: 0; + border: 0; + width: 0; + @include breakpoint($mq-x-large) { + @include transition(width); + } + body.clinput & { + width: 20ch; + } + } + input:focus { + outline: none; + } + ::placeholder { + color: $c-font-dim; + } + .tt-menu { + .empty, .spinner { + display: none; + } + } +} + +body.clinput #top { + @include breakpoint($mq-not-x-large) { + #topnav { display: none } + } + @include breakpoint($mq-not-x-small) { + .site-title { display: none } + } + @include breakpoint($mq-not-xx-small) { + .site-buttons > *:not(#clinput) { display: none } + #clinput { width: 75vw; } + } +} diff --git a/ui/cli/css/_help.scss b/ui/cli/css/_help.scss new file mode 100644 index 0000000000..7a74416534 --- /dev/null +++ b/ui/cli/css/_help.scss @@ -0,0 +1,32 @@ +.clinput-help { + width: auto; + h3 { + font-size: 2em; + margin: .5em 0; + color: $c-accent; + &:first-child { + margin-top: 0; + } + } + .command { + display: flex; + flex-flow: row nowrap; + align-items: flex-start; + padding: .7em 0; + border-top: $border; + p { + text-align: left; + font-family: monospace; + margin: 0 2em 0 0; + color: $c-accent; + font-weight: bold; + } + span { + text-align: right; + white-space: nowrap; + } + > * { + flex: 1 1 50%; + } + } +} diff --git a/ui/cli/css/build/_clinput.help.scss b/ui/cli/css/build/_clinput.help.scss new file mode 100644 index 0000000000..21f04eaca6 --- /dev/null +++ b/ui/cli/css/build/_clinput.help.scss @@ -0,0 +1,3 @@ +@import '../../../common/css/plugin'; +@import '../../../common/css/component/modal'; +@import '../help'; diff --git a/ui/cli/css/build/clinput.help.dark.scss b/ui/cli/css/build/clinput.help.dark.scss new file mode 100644 index 0000000000..35a06feb0f --- /dev/null +++ b/ui/cli/css/build/clinput.help.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'clinput.help'; diff --git a/ui/cli/css/build/clinput.help.light.scss b/ui/cli/css/build/clinput.help.light.scss new file mode 100644 index 0000000000..beac84be47 --- /dev/null +++ b/ui/cli/css/build/clinput.help.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'clinput.help'; diff --git a/ui/cli/css/build/clinput.help.transp.scss b/ui/cli/css/build/clinput.help.transp.scss new file mode 100644 index 0000000000..03df5b4bc1 --- /dev/null +++ b/ui/cli/css/build/clinput.help.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'clinput.help'; diff --git a/ui/cli/src/main.js b/ui/cli/src/main.js new file mode 100644 index 0000000000..acaa4c7200 --- /dev/null +++ b/ui/cli/src/main.js @@ -0,0 +1,33 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +function app(wrap, toggle) { + var $wrap = $(wrap), $input = $wrap.find('input'); + window.lichess.userAutocomplete($input, { + focus: 1, + friend: true, + onSelect: function (q) { + execute(q.name || q); + $input.val(''); + } + }).done(function () { + $input.on('blur', function () { return wrap.classList.contains('shown') && toggle; }); + }); +} +exports.app = app; +function execute(q) { + if (!q) + return; + if (q[0] === '/') + command(q.slice(1)); + else + location.href = '/@/' + q; +} +function command(q) { + var parts = q.split(' '), exec = parts[0]; + if (exec === 'tv' || exec === 'follow') + location.href = '/@/' + parts[1] + '/tv'; + else if (exec === 'play' || exec === 'challenge' || exec === 'match') + location.href = '/?user=' + parts[1] + '#friend'; + else + alert('Unknown command: ' + q); +} diff --git a/ui/cli/src/main.ts b/ui/cli/src/main.ts index dddba707b1..5ae99004b6 100644 --- a/ui/cli/src/main.ts +++ b/ui/cli/src/main.ts @@ -1,26 +1,83 @@ -export function app(wrap: HTMLElement, toggle: () => void) { - const $wrap = $(wrap), $input = $wrap.find('input'); - window.lichess.userAutocomplete($input, { +const li = window.lichess; + +export function app($wrap: JQuery, toggle: () => void) { + const $input = $wrap.find('input'); + li.userAutocomplete($input, { focus: 1, friend: true, onSelect(q: any) { - execute(q.name || q); - $input.val(''); + $input.val('').blur(); + execute(q.name || q.trim()); + $('body').hasClass('clinput') && toggle() } }).done(function() { - $input.on('blur', toggle); + $input.on('blur', () => { + $input.val(''); + $('body').hasClass('clinput') && toggle() + }); }); } function execute(q: string) { if (!q) return; - if (q[0] === '/') command(q.slice(1)); + if (q[0] == '/') return command(q.replace(/\//g, '')); else location.href = '/@/' + q; } function command(q: string) { var parts = q.split(' '), exec = parts[0]; - if (exec === 'tv' || exec === 'follow') location.href = '/@/' + parts[1] + '/tv'; - else if (exec === 'play' || exec === 'challenge' || exec === 'match') location.href = '/?user=' + parts[1] + '#friend'; - else alert('Unknown command: ' + q); + + const is = function(commands: string) { + return commands.split(' ').includes(exec); + }; + + if (is('tv follow') && parts[1]) + location.href = '/@/' + parts[1] + '/tv'; + + else if (is('tv')) + location.href = '/tv'; + + else if (is('play challenge match') && parts[1]) + location.href = '/?user=' + parts[1] + '#friend'; + + else if (is('light dark transp')) + getDasher(dasher => dasher.subs.background.set(exec)); + + else if (is('stream') && parts[1]) + location.href = '/streamer/' + parts[1]; + + else if (is('help')) help(); + + else alert(`Unknown command: "${q}". Type /help for the list of commands`); +} + +function commandHelp(aliases: string, args: string, desc: string) { + return '
    ' + + aliases.split(' ').map(a => `

    ${a} ${li.escapeHtml(args)}

    `).join('') + + `
    ${desc}
    `; +} + +function help() { + li.loadCssPath('clinput.help') + $.modal( + '

    Commands

    ' + + commandHelp('/tv /follow', ' ', 'Watch someone play') + + commandHelp('/play /challenge /match', ' ', 'Challenge someone to play') + + commandHelp('/light /dark /transp', '', 'Change the background theme') + + commandHelp('/stream', '', 'Watch someone stream') + + '

    Global hotkeys

    ' + + commandHelp('s', '', 'Search for a user') + + commandHelp('/', '', 'Type a command') + + commandHelp('c', '', 'Focus the chat input') + + commandHelp('esc', '', 'Close modals like this one'), + 'clinput-help' + ); +} + +function getDasher(cb: (dasher: any) => void) { + li.loadScript(li.compiledScript('dasher')).done(function() { + window['LichessDasher'].default(document.createElement('div'), { + playing: $('body').hasClass('playing') + }).then(cb); + }); } diff --git a/ui/cli/tsconfig.json b/ui/cli/tsconfig.json index 728085f0e9..25a6fcf64c 100644 --- a/ui/cli/tsconfig.json +++ b/ui/cli/tsconfig.json @@ -8,7 +8,8 @@ "alwaysStrict": true, "noImplicitReturns": true, "noImplicitThis": true, - "target": "es5", - "lib": ["DOM", "ES5"] + "moduleResolution": "node", + "target": "ES5", + "lib": ["DOM", "ES5", "es2015.core", "es2015.Promise"] } } diff --git a/ui/common/css/_embed.scss b/ui/common/css/_embed.scss new file mode 100644 index 0000000000..a0f69e385d --- /dev/null +++ b/ui/common/css/_embed.scss @@ -0,0 +1,13 @@ +/* Common imports for all embedded widgets */ + +@import '../../../node_modules/breakpoint-sass/stylesheets/breakpoint'; + +@import 'abstract/all'; +@import 'base/elements'; +@import 'base/fonts'; +@import 'base/typography'; +@import 'base/data-icon'; + +@include theme-style; + +@import 'vendor/chessground/chessground'; diff --git a/ui/common/css/_lichess.scss b/ui/common/css/_lichess.scss new file mode 100644 index 0000000000..be60bffbdb --- /dev/null +++ b/ui/common/css/_lichess.scss @@ -0,0 +1,37 @@ +/* Common imports for all pages */ + +@import '../../../node_modules/breakpoint-sass/stylesheets/breakpoint'; + +@import 'abstract/all'; + +@import 'base/elements'; +@import 'base/form'; +@import 'base/fonts'; +@import 'base/typography'; +@import 'base/data-icon'; +@import 'base/unread'; +@import 'base/util'; + +@include theme-style; + +@import 'layout/base'; +@import 'layout/page-menu'; + +@import 'vendor/chessground/chessground'; + +@import 'header/header'; +@import '../../cli/css/clinput'; + +@import 'component/board'; +@import 'component/box'; +@import 'component/button'; +@import 'component/user-link'; +@import 'component/blind-mode'; +@import 'component/friend-box'; +@import 'component/signal'; +@import 'component/power-tip'; +@import 'component/vs'; +@import 'component/btn-rack'; +@import 'component/loader'; +@import 'component/reconnecting'; +@import 'component/announce'; diff --git a/ui/common/css/_plugin.scss b/ui/common/css/_plugin.scss new file mode 100644 index 0000000000..78746297a5 --- /dev/null +++ b/ui/common/css/_plugin.scss @@ -0,0 +1,5 @@ +/* Common imports for all live-loaded CSS (like the dasher) */ + +@import '../../../node_modules/breakpoint-sass/stylesheets/breakpoint'; + +@import 'abstract/all'; diff --git a/ui/common/css/abstract/_all.scss b/ui/common/css/abstract/_all.scss new file mode 100644 index 0000000000..dd42b8b3c3 --- /dev/null +++ b/ui/common/css/abstract/_all.scss @@ -0,0 +1,10 @@ +@import 'functions'; +@import 'z-index'; +@import 'media-queries'; +@import 'variables'; +@import 'uniboard'; +@import 'mixins'; +@import 'extends'; +@import 'flex'; +@import 'box'; +@import 'fluid-size'; diff --git a/ui/common/css/abstract/_box.scss b/ui/common/css/abstract/_box.scss new file mode 100644 index 0000000000..d21fe4b371 --- /dev/null +++ b/ui/common/css/abstract/_box.scss @@ -0,0 +1,28 @@ +%box-radius { + @include box-radius; +} +%box-radius-force { + @extend %box-radius; + overflow: hidden; /* helps with clipping background into border-radius */ +} +%box-radius-left { + border-radius: $box-radius-size 0 0 $box-radius-size; +} +%box-radius-right { + border-radius: 0 $box-radius-size $box-radius-size 0; +} +%box-radius-top { + border-radius: $box-radius-size $box-radius-size 0 0; +} +%box-radius-bottom { + border-radius: 0 0 $box-radius-size $box-radius-size; +} +%box-shadow { + @include box-shadow; +} +%box-neat { + @extend %box-shadow, %box-radius; +} +%box-neat-force { + @extend %box-shadow, %box-radius-force; +} diff --git a/ui/common/css/abstract/_extends.scss b/ui/common/css/abstract/_extends.scss new file mode 100644 index 0000000000..2f6ef083d7 --- /dev/null +++ b/ui/common/css/abstract/_extends.scss @@ -0,0 +1,182 @@ +%base-font-fallback { + font-family: 'Noto Sans', Sans-Serif; +} +%base-font { + font-family: 'Noto Sans'; +} +%roboto { + font-family: 'Roboto'; +} +%roboto-fat { + font-family: 'Roboto'; + font-weight: 600; +} +%chess-font { + font-family: 'Noto Chess', 'Noto Sans'; +} +%san { + @extend %chess-font; + .piece-letter & { + @extend %base-font; + } +} + +/* text printed directly on the page background deserves special treatment (transp theme) */ +%page-font { + color: $c-font-page; +} +%page-text { + @extend %page-font, %page-text-shadow !optional; +} +%page-link { + @extend %page-link-font !optional; + @extend %page-text-shadow !optional; +} + + +%metal { + @include metal; +} +%metal-hover { + @include metal-hover; +} +%page-metal { + @include page-metal; +} +%page-metal-hover { + @include page-metal; +} + +%active-inset-shadow { + box-shadow: 0 3px 4px hsla(0, 0, 0, 0.15) inset; +} + +%active { + @extend %active-inset-shadow; + background: $c-accent; + color: #fff; + text-shadow: 0 1px 1px black!important; +} +%active-hover { + background: mix(white, $c-accent, 20%); +} + +%active-soft { + @extend %active-inset-shadow; + background: $c-shade; + color: $c-font-clearer; + text-shadow: 1px 1px 1px $c-font-shadow!important; + font-weight: bold; +} + +%dropdown-shadow { + box-shadow: -1px 5px 6px rgba(0, 0, 0, 0.3); +} +%popup-shadow { + box-shadow: 0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22); +} +%button-shadow { + box-shadow: 0 2px 5px 0 hsla(0, 0, 0%, 0.225); +} +%button-raised-shadow { + box-shadow: 0 4px 10px 0px hsla(0, 0, 0, 0.225); +} +%button-none { + background: none; + border: none; + outline: none; + color: $c-font; +} + +%nowrap-hidden { + white-space: nowrap; + overflow: hidden; +} +%nowrap-ellipsis { + @extend %ellipsis; + white-space: nowrap; +} + +%box-padding { + padding: 5vh var(--box-padding); +} +%box-padding-horiz { + padding: 0 var(--box-padding); +} + +%break-word { + overflow-wrap: break-word; +} +%break-word-hard { + @extend %break-word; + word-break: break-all; /* support: firefox */ + word-break: break-word; +} +%break-nope { + overflow-wrap: normal; + word-break: normal; +} + +%ellipsis { + @include ellipsis; +} + +%square { + position: relative; + display: block; + height: 0; + padding-bottom: 100%; + width: 100%; +} + +%video { + position: relative; + display: block; + height: 0; + padding-bottom: 56.25%; /* 16/9 */ + // padding-bottom: 75%; /* 4/3 */ + width: 100%; + > * { + @extend %abs-100; + border: none; + } +} + +%data-icon { + font-size: 1.2em; + vertical-align: middle; + font-family: 'lichess'; + font-style: normal; + font-weight: normal; + text-transform: none; + speak: none; + content: attr(data-icon); + opacity: 0.9; +} +%data-icon-top { + &::before { + vertical-align: text-top; + } +} +%fullscreen-mask { + position: fixed; + top: 0; + left: 0; + bottom: 0; + right: 0; + background: $c-page-mask; + z-index: z('fullscreen-mask'); +} +%link-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: z('link-overlay'); +} +%abs-100 { + position: absolute; + width: 100%; + height: 100%; +} diff --git a/ui/common/css/abstract/_flex.scss b/ui/common/css/abstract/_flex.scss new file mode 100644 index 0000000000..005d2a5010 --- /dev/null +++ b/ui/common/css/abstract/_flex.scss @@ -0,0 +1,39 @@ +%flex-wrap { + display: flex; + flex-flow: row wrap; +} +%flex-center { + /* extends %flex-wrap */ + display: flex; + flex-flow: row wrap; + align-items: center; +} +%flex-center-nowrap { + display: flex; + flex-flow: row; + align-items: center; +} +%flex-between { + /* extends %flex-center */ + display: flex; + flex-flow: row wrap; + align-items: center; + justify-content: space-between; +} +%flex-between-nowrap { + /* extends %flex-center */ + display: flex; + flex-flow: row nowrap; + align-items: center; + justify-content: space-between; +} +%flex-between-stretch { + display: flex; + flex-flow: row wrap; + justify-content: space-between; + align-items: stretch; +} +%flex-column { + display: flex; + flex-flow: column; +} diff --git a/ui/common/css/abstract/_fluid-size.scss b/ui/common/css/abstract/_fluid-size.scss new file mode 100644 index 0000000000..f0c74e07ac --- /dev/null +++ b/ui/common/css/abstract/_fluid-size.scss @@ -0,0 +1,28 @@ +$vp-min-width: 320px !default; +$vp-max-width: 1200px !default; + +@function strip-unit($value) { + @return $value / ($value * 0 + 1); +} + +@mixin fluid-size($prop, $min-size, $max-size, $min-vw: $vp-min-width, $max-vw: $vp-max-width) { + $u1: unit($min-vw); + $u2: unit($max-vw); + $u3: unit($min-size); + $u4: unit($max-size); + + @if $u1 == $u2 and $u1 == $u3 and $u1 == $u4 { + & { + #{$prop}: $min-size; + @media (min-width: $min-vw) { + #{$prop}: calc(#{$min-size} + #{strip-unit($max-size - $min-size)} * ((100vw - #{$min-vw}) / #{strip-unit($max-vw - $min-vw)})); + } + @media (min-width: $max-vw) { + #{$prop}: $max-size; + } + } + } + @else { + @error 'fluid-size requires that all values have the same unit'; + } +} diff --git a/ui/common/css/abstract/_functions.scss b/ui/common/css/abstract/_functions.scss new file mode 100644 index 0000000000..82db32e42d --- /dev/null +++ b/ui/common/css/abstract/_functions.scss @@ -0,0 +1,6 @@ +@function c-light($color, $value) { + @return change-color($color, $lightness: $value); +} +@function img-url($path) { + @return url('#{$img-path}/#{$path}'); +} diff --git a/ui/common/css/abstract/_media-queries.scss b/ui/common/css/abstract/_media-queries.scss new file mode 100644 index 0000000000..2145c2184a --- /dev/null +++ b/ui/common/css/abstract/_media-queries.scss @@ -0,0 +1,47 @@ +/* Widths */ + +$mq-xx-small: (min-width 500px); +$mq-x-small: (min-width 650px); +$mq-small: (min-width 800px); +$mq-medium: (min-width 980px); +$mq-large: (min-width 1120px); +$mq-x-large: (min-width 1260px); + +$mq-not-xx-small: (max-width 499px); +$mq-not-x-small: (max-width 649px); +$mq-not-small: (max-width 799px); +$mq-not-medium: (max-width 979px); +$mq-not-x-large: (max-width 1259px); + +/* Heights */ + +$mq-x-short: (min-height 400px); +$mq-short: (min-height 500px); +$mq-tall: (min-height 600px); +$mq-x-tall: (min-height 700px); + +$mq-not-x-short: (max-height 399px); + +/* Orientations */ + +$mq-portrait: (orientation portrait); +$mq-landscape: (orientation landscape); + +/* Capabilities */ + +$mq-hover-yes: 'hover: hover'; +$mq-hover-no: (hover none); + +/* Aliases */ + +$mq-main-margin: $mq-small; + +$mq-topnav-visible: $mq-medium; +$mq-topnav-hidden: $mq-not-medium; + +$mq-site-header-tall: $mq-tall; + +$mq-subnav-top: $mq-not-small; +$mq-subnav-side: $mq-small; + +$mq-zoom-enabled: $mq-small $mq-short; diff --git a/ui/common/css/abstract/_mixins.scss b/ui/common/css/abstract/_mixins.scss new file mode 100644 index 0000000000..be03a3d752 --- /dev/null +++ b/ui/common/css/abstract/_mixins.scss @@ -0,0 +1,70 @@ +@mixin box-radius { + border-radius: $box-radius-size; +} +@mixin box-shadow { + box-shadow: $box-shadow; +} +@mixin box-neat { + @include box-radius; + @include box-shadow; +} + +@mixin debug-zoom-input { + #zoom-input { + display: none; + @include breakpoint($mq-zoom-enabled) { + display: block; + position: fixed; + bottom: 3px; + right: 3px; + width: 10vw; + } + } +} + +@mixin transition($prop: all, $dur: $transition-duration) { + transition: $prop $dur; +} + +@mixin hoverflow { + overflow-y: auto; + @media (hover: hover) { + overflow: hidden; + &:hover { + overflow-y: auto; + } + } +} + +@mixin hide { + display: none; + .blind-mode & { + display: inherit; + } +} + +@mixin ellipsis { + overflow: hidden; + text-overflow: ellipsis; +} + +@mixin crosstable-large { + .crosstable__users { flex: 7 1 auto; } +} +@mixin crosstable-small { + .crosstable__users { flex: 1 1 auto; } +} + +/* atm only chrome supports min-content, max-content */ +@mixin proper-grid { + @supports (height: max-content) { + @content; + } +} + +@mixin body-fixed-scroll { + body { + /* prevents scroll bar flicker when dragging a piece out */ + overflow-y: scroll; + } +} diff --git a/ui/common/css/abstract/_uniboard.scss b/ui/common/css/abstract/_uniboard.scss new file mode 100644 index 0000000000..1740687db8 --- /dev/null +++ b/ui/common/css/abstract/_uniboard.scss @@ -0,0 +1,38 @@ +/* Uniboard: keep the same page layout accross pages */ + +$mq-board-resizable: $mq-small; +$mq-col1-uniboard: $mq-not-small $mq-portrait; +$mq-col2-uniboard: ($mq-small, $mq-landscape); +$mq-col3-uniboard: $mq-x-large; + +/* when the width is appropriate for col1, but landscape prevents it */ +$mq-col2-uniboard-squeeze: $mq-not-small $mq-landscape; + +$col3-uniboard-side: minmax(230px, 20vw); +$col3-uniboard-table: minmax(240px, 400px); +$col3-uniboard-controls: 2.5rem; + +$col3-uniboard-min-width: calc(70vmin * var(--board-scale)); +$col3-uniboard-max-width: calc(100vh * var(--board-scale) - #{$site-header-outer-height} - #{$col3-uniboard-controls}); +$col3-uniboard-width: minmax($col3-uniboard-min-width, $col3-uniboard-max-width); + +$col3-uniboard-default-scale: 0.9; // zoom: 85% +$col3-uniboard-default-min-width: 500px; +$col3-uniboard-default-max-width: calc(100vh * #{$col3-uniboard-default-scale} - #{$site-header-outer-height} - #{$col3-uniboard-controls}); +$col3-uniboard-default-width: minmax(#{$col3-uniboard-default-min-width}, #{$col3-uniboard-default-max-width}); + +$col2-uniboard-table: $col3-uniboard-table; +$col2-uniboard-controls: $col3-uniboard-controls; +$col2-uniboard-width: $col3-uniboard-width; +$col2-uniboard-default-width: $col3-uniboard-default-width; + +$col2-uniboard-squeeze-table: minmax(200px, 240px); +$col2-uniboard-squeeze-width: minmax(calc(55vmin), calc(100vh - #{$site-header-outer-height} - #{$block-gap})); + +$col1-uniboard-controls: $col2-uniboard-controls; + +body { + @include breakpoint($mq-col1-uniboard) { + --col1: 1; + } +} diff --git a/ui/common/css/abstract/_variables.scss b/ui/common/css/abstract/_variables.scss new file mode 100644 index 0000000000..c0bf32f1b6 --- /dev/null +++ b/ui/common/css/abstract/_variables.scss @@ -0,0 +1,29 @@ +$debug: false; + +$font-path: "../font"; +$img-path: "../images"; + +$viewport-min-width: 320px; + +$block-gap: 2vmin; +$block-gap-half: 1vmin; + +$block-gap-h: 2vh; +$block-gap-w: 2vw; +$block-gap-w-half: 1vw; + +$box-radius-size: 3px; + +$site-header-tall-height: 60px; +$site-header-short-height: 40px; + +$transition-duration: 150ms; + +$main-max-width: 1300px !default; + +$main-margin: var(--main-margin); +$site-header-height: var(--site-header-height); + +$site-header-margin: var(--site-header-margin); + +$site-header-outer-height: calc(#{$site-header-height} + #{$site-header-margin}); diff --git a/ui/common/css/abstract/_z-index.scss b/ui/common/css/abstract/_z-index.scss new file mode 100644 index 0000000000..0578cdad15 --- /dev/null +++ b/ui/common/css/abstract/_z-index.scss @@ -0,0 +1,43 @@ +/// Z-indexes map, gathering all Z layers of the application +/// @access private +/// @type Map +/// @prop {String} key - Layer’s name +/// @prop {Number} value - Z value mapped to the key +$z-indexes: ( + 'cg__piece.dragging.3d': 70, + 'cg__promotion': 5, + 'cg__piece.dragging': 4, + 'cg__piece.anim': 3, + 'cg__svg': 2, + 'cg__piece': 2, + 'cg__piece.fading': 1, + + 'powertip': 120, + 'inquiry': 111, + 'zen-toggle': 110, + 'modal': 110, + 'mselect': 110, + 'topnav': 110, + 'fullscreen-mask': 109, + 'dropdown': 108, + 'context-menu': 107, + 'site-header': 106, + 'reconnecting': 105, + 'tour-reminder': 104, + 'nag-circle': 103, + 'above-link-overlay': 3, + 'friend-box': 2, + 'link-overlay': 2, + 'game-bookmark': 2, + 'subnav-side': 2, + 'default': 0 +); + +/// Get a z-index value from a layer name +/// @access public +/// @param {String} $layer - Layer’s name +/// @return {Number} +/// @require $z-indexes +@function z($layer) { + @return map-get($z-indexes, $layer); +} diff --git a/ui/common/css/base/_data-icon.scss b/ui/common/css/base/_data-icon.scss new file mode 100644 index 0000000000..7df4512614 --- /dev/null +++ b/ui/common/css/base/_data-icon.scss @@ -0,0 +1,20 @@ +.is::before, +[data-icon]::before, +.is-after::after { + @extend %data-icon; +} +.is.text::before, +.text[data-icon]::before { + margin-right: .4em; +} + +.user-link.online .line, +.is-green::before { + color: $c-good; +} +.is-red::before { + color: $c-bad; +} +.is-gold::before { + color: $c-brag; +} diff --git a/ui/common/css/base/_elements.scss b/ui/common/css/base/_elements.scss new file mode 100644 index 0000000000..f131684024 --- /dev/null +++ b/ui/common/css/base/_elements.scss @@ -0,0 +1,70 @@ +html { + box-sizing: border-box; + min-height: 100%; +} + +*, *::before, *::after { + box-sizing: inherit; + margin: 0; + padding: 0; +} + +body { + background: $c-bg-page linear-gradient(to bottom, $c-body-gradient, $c-bg-page 116px) no-repeat; + color: $c-font; + overflow-x: hidden; + &.fixed-scroll { + /* prevents scroll bar flicker when dragging a piece out */ + overflow-y: scroll; + } +} + +a { + color: $c-link; + text-decoration: none; + &:hover, + &:active, + &:focus { + color: $c-link-hover; + } +} + +p { + margin-bottom: 1em; +} + +em, i { + font-style: normal; +} + +li { + list-style: none; +} + +time { + font-size: 90%; + opacity: 0.9; /* don't use c-color-dim, it overrides too hard */ +} + +hr { + margin: 1.5rem 0; + border: 0; + height: 1px; + background: $c-border; +} + +small { + font-size: .9em; +} + +table, tbody, tfoot, thead, tr, th, td { + border: 0; + font-size: 100%; + font: inherit; + vertical-align: middle; + text-align: inherit; +} +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/ui/common/css/base/_fonts.scss b/ui/common/css/base/_fonts.scss new file mode 100644 index 0000000000..d02b80471e --- /dev/null +++ b/ui/common/css/base/_fonts.scss @@ -0,0 +1,201 @@ +@function local-font($path) { + @return url(#{$font-path}/#{$path}) +} +@font-face { + font-family: "lichess"; + src: local-font("lichess.woff2") format("woff2"), local-font("lichess.woff") format("woff"); + font-display: block; + font-weight: normal; + font-style: normal; +} +@font-face { + font-family: 'Noto Chess'; + src: local-font("lichess.chess.woff2") format("woff2"), local-font("lichess.chess.woff") format("woff"); +} +/* cyrillic-ext */ +@font-face { + font-family: 'Noto Sans'; + font-style: normal; + font-weight: 400; + src: local('Noto Sans'), local('NotoSans'), url(https://fonts.gstatic.com/s/notosans/v7/o-0IIpQlx3QUlC5A4PNr6DRAW_0.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Noto Sans'; + font-style: normal; + font-weight: 400; + src: local('Noto Sans'), local('NotoSans'), url(https://fonts.gstatic.com/s/notosans/v7/o-0IIpQlx3QUlC5A4PNr4TRAW_0.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* devanagari */ +@font-face { + font-family: 'Noto Sans'; + font-style: normal; + font-weight: 400; + src: local('Noto Sans'), local('NotoSans'), url(https://fonts.gstatic.com/s/notosans/v7/o-0IIpQlx3QUlC5A4PNr5DRAW_0.woff2) format('woff2'); + unicode-range: U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB; +} +/* greek-ext */ +@font-face { + font-family: 'Noto Sans'; + font-style: normal; + font-weight: 400; + src: local('Noto Sans'), local('NotoSans'), url(https://fonts.gstatic.com/s/notosans/v7/o-0IIpQlx3QUlC5A4PNr6TRAW_0.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: 'Noto Sans'; + font-style: normal; + font-weight: 400; + src: local('Noto Sans'), local('NotoSans'), url(https://fonts.gstatic.com/s/notosans/v7/o-0IIpQlx3QUlC5A4PNr5jRAW_0.woff2) format('woff2'); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Noto Sans'; + font-style: normal; + font-weight: 400; + src: local('Noto Sans'), local('NotoSans'), url(https://fonts.gstatic.com/s/notosans/v7/o-0IIpQlx3QUlC5A4PNr6jRAW_0.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Noto Sans'; + font-style: normal; + font-weight: 400; + src: local('Noto Sans'), local('NotoSans'), url(https://fonts.gstatic.com/s/notosans/v7/o-0IIpQlx3QUlC5A4PNr6zRAW_0.woff2) format('woff2'); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Noto Sans'; + font-style: normal; + font-weight: 400; + // src: local('Noto Sans'), local('NotoSans'), url(https://fonts.gstatic.com/s/notosans/v7/o-0IIpQlx3QUlC5A4PNr5TRA.woff2) format('woff2'); + src: local('Noto Sans'), local('NotoSans'), local-font("noto-sans-latin.woff2") format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Noto Sans'; + font-style: normal; + font-weight: 700; + src: local('Noto Sans Bold'), local('NotoSans-Bold'), url(https://fonts.gstatic.com/s/notosans/v7/o-0NIpQlx3QUlC5A4PNjXhFVadyB1Wk.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Noto Sans'; + font-style: normal; + font-weight: 700; + src: local('Noto Sans Bold'), local('NotoSans-Bold'), url(https://fonts.gstatic.com/s/notosans/v7/o-0NIpQlx3QUlC5A4PNjXhFVYNyB1Wk.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* devanagari */ +@font-face { + font-family: 'Noto Sans'; + font-style: normal; + font-weight: 700; + src: local('Noto Sans Bold'), local('NotoSans-Bold'), url(https://fonts.gstatic.com/s/notosans/v7/o-0NIpQlx3QUlC5A4PNjXhFVZdyB1Wk.woff2) format('woff2'); + unicode-range: U+0900-097F, U+1CD0-1CF6, U+1CF8-1CF9, U+200C-200D, U+20A8, U+20B9, U+25CC, U+A830-A839, U+A8E0-A8FB; +} +/* greek-ext */ +@font-face { + font-family: 'Noto Sans'; + font-style: normal; + font-weight: 700; + src: local('Noto Sans Bold'), local('NotoSans-Bold'), url(https://fonts.gstatic.com/s/notosans/v7/o-0NIpQlx3QUlC5A4PNjXhFVaNyB1Wk.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: 'Noto Sans'; + font-style: normal; + font-weight: 700; + src: local('Noto Sans Bold'), local('NotoSans-Bold'), url(https://fonts.gstatic.com/s/notosans/v7/o-0NIpQlx3QUlC5A4PNjXhFVZ9yB1Wk.woff2) format('woff2'); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Noto Sans'; + font-style: normal; + font-weight: 700; + src: local('Noto Sans Bold'), local('NotoSans-Bold'), url(https://fonts.gstatic.com/s/notosans/v7/o-0NIpQlx3QUlC5A4PNjXhFVa9yB1Wk.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Noto Sans'; + font-style: normal; + font-weight: 700; + src: local('Noto Sans Bold'), local('NotoSans-Bold'), url(https://fonts.gstatic.com/s/notosans/v7/o-0NIpQlx3QUlC5A4PNjXhFVatyB1Wk.woff2) format('woff2'); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Noto Sans'; + font-style: normal; + font-weight: 700; + // src: local('Noto Sans Bold'), local('NotoSans-Bold'), url(https://fonts.gstatic.com/s/notosans/v7/o-0NIpQlx3QUlC5A4PNjXhFVZNyB.woff2) format('woff2'); + src: local('Noto Sans Bold'), local('NotoSans-Bold'), local-font("noto-sans-bold-latin.woff2") format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} +/* cyrillic-ext */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + src: local('Roboto Light'), local('Roboto-Light'), url(https://fonts.gstatic.com/s/roboto/v18/KFOlCnqEu92Fr1MmSU5fCRc4EsA.woff2) format('woff2'); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} +/* cyrillic */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + src: local('Roboto Light'), local('Roboto-Light'), url(https://fonts.gstatic.com/s/roboto/v18/KFOlCnqEu92Fr1MmSU5fABc4EsA.woff2) format('woff2'); + unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} +/* greek-ext */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + src: local('Roboto Light'), local('Roboto-Light'), url(https://fonts.gstatic.com/s/roboto/v18/KFOlCnqEu92Fr1MmSU5fCBc4EsA.woff2) format('woff2'); + unicode-range: U+1F00-1FFF; +} +/* greek */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + src: local('Roboto Light'), local('Roboto-Light'), url(https://fonts.gstatic.com/s/roboto/v18/KFOlCnqEu92Fr1MmSU5fBxc4EsA.woff2) format('woff2'); + unicode-range: U+0370-03FF; +} +/* vietnamese */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + src: local('Roboto Light'), local('Roboto-Light'), url(https://fonts.gstatic.com/s/roboto/v18/KFOlCnqEu92Fr1MmSU5fCxc4EsA.woff2) format('woff2'); + unicode-range: U+0102-0103, U+0110-0111, U+1EA0-1EF9, U+20AB; +} +/* latin-ext */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + src: local('Roboto Light'), local('Roboto-Light'), url(https://fonts.gstatic.com/s/roboto/v18/KFOlCnqEu92Fr1MmSU5fChc4EsA.woff2) format('woff2'); + unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} +/* latin */ +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + // src: local('Roboto Light'), local('Roboto-Light'), url(https://fonts.gstatic.com/s/roboto/v18/KFOlCnqEu92Fr1MmSU5fBBc4.woff2) format('woff2'); + src: local('Roboto Light'), local('Roboto-Light'), local-font("roboto-light-latin.woff2") format('woff2'); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} diff --git a/ui/common/css/base/_form.scss b/ui/common/css/base/_form.scss new file mode 100644 index 0000000000..e4edc0889b --- /dev/null +++ b/ui/common/css/base/_form.scss @@ -0,0 +1,29 @@ +button, input, optgroup, select, textarea { + font: inherit; + color: $c-font; + outline-color: $c-primary; +} +option, +optgroup { + background: $c-bg-box-opaque; + color: $c-font-clear; +} +input, textarea, select { + @extend %box-radius; + background: $c-bg-input; + border: $border; + padding: .6em 1em; +} +textarea { + overflow: auto; + resize: vertical; + padding: .8em 1em; +} +button, a { + cursor: pointer; +} + +.copyable { + background: $c-page-input; + color: $c-font-clear; +} diff --git a/ui/common/css/base/_scrollbar.scss b/ui/common/css/base/_scrollbar.scss new file mode 100644 index 0000000000..6f3f79b46b --- /dev/null +++ b/ui/common/css/base/_scrollbar.scss @@ -0,0 +1,12 @@ +body ::-webkit-scrollbar, +body ::-webkit-scrollbar-corner { + width: .5rem; + background: $c-bg-box; +} +body ::-webkit-scrollbar-thumb { + background: $c-shade; +} +body ::-webkit-scrollbar-thumb:hover, +body ::-webkit-scrollbar-thumb:active { + background: $c-font-dimmer; +} diff --git a/ui/common/css/base/_typography.scss b/ui/common/css/base/_typography.scss new file mode 100644 index 0000000000..35eb2767be --- /dev/null +++ b/ui/common/css/base/_typography.scss @@ -0,0 +1,34 @@ +html { + @extend %base-font-fallback; + @include fluid-size('font-size', 13px, 15px); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +h1, +h2, +h3, +h4 { + @extend %roboto; + font-weight: normal; + font-size: 1em; +} +h1 { + @include fluid-size('font-size', 27px, 52px); + margin-bottom: 5vh; + a { + color: $c-link-dim; + &:hover { + color: $c-link; + } + } +} + +h2 { + @include fluid-size('font-size', 23px, 40px); +} + +.ninja-title { + @extend %base-font; + font-size: 1em; +} diff --git a/ui/common/css/base/_unread.scss b/ui/common/css/base/_unread.scss new file mode 100644 index 0000000000..3ec3180f0c --- /dev/null +++ b/ui/common/css/base/_unread.scss @@ -0,0 +1,22 @@ +.data-count { + position: relative; +} +.data-count::after, +.unread { + @extend %active, %box-radius; + padding: 1px 5px 1px 4px; + font-weight: bold; + font-size: 13px; +} +.data-count::after { + content: attr(data-count); + top: -5px; + right: 0; + position: absolute; + padding: 0 3px; + height: 15px; + line-height: 15px; +} +.data-count[data-count='0']::after { + display: none; +} diff --git a/ui/common/css/base/_util.scss b/ui/common/css/base/_util.scss new file mode 100644 index 0000000000..d5a87d7fba --- /dev/null +++ b/ui/common/css/base/_util.scss @@ -0,0 +1,35 @@ +.none { + display: none!important; +} + +.fullscreen-mask { + @extend %fullscreen-mask; + display: none; + .fullscreen-toggle:checked ~ & { + display: block; + } +} + +.rp::before { + @extend %data-icon; + margin-right: .2em; + content: 'N'; +} +bad.rp { + &::before { content: 'M'; } +} + +good { + color: $c-good; +} +bad { + color: $c-bad; +} + +/* infinite scroll */ +.inf-more { + width: 100%; +} +#infscr-loading .spinner { + margin: 10px auto; +} diff --git a/ui/common/css/component/_announce.scss b/ui/common/css/component/_announce.scss new file mode 100644 index 0000000000..34ced94335 --- /dev/null +++ b/ui/common/css/component/_announce.scss @@ -0,0 +1,34 @@ +#announce { + @extend %flex-between, %popup-shadow; + font-size: 1.4em; + position: fixed; + background: $c-primary; + color: $c-primary-over; + position: fixed; + bottom: 0; + left: 0; + padding: .7rem 1rem; + z-index: z('tour-reminder'); + + width: 100%; + @include breakpoint($mq-xx-small) { + width: auto; + border-top-right-radius: 3px; + } + + a { + color: $c-primary-over; + } + + .actions { + a { + font-weight: bold; + margin-left: 1rem; + } + } + + &.announce { + flex-flow: row nowrap; + background: $c-accent; + } +} diff --git a/ui/common/css/component/_bar-glider.scss b/ui/common/css/component/_bar-glider.scss new file mode 100644 index 0000000000..107567a3de --- /dev/null +++ b/ui/common/css/component/_bar-glider.scss @@ -0,0 +1,18 @@ +@keyframes bar-glider-anim { + 0%{transform:translateX(-1300px);} + 100%{transform:translateX(2100px);} +} +.bar-glider { + position: relative; + overflow: hidden; + &::after { + content: ''; + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 70px; + background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.3)); + animation: bar-glider-anim 3s linear infinite; + } +} diff --git a/ui/common/css/component/_blind-mode.scss b/ui/common/css/component/_blind-mode.scss new file mode 100644 index 0000000000..1e2a172e92 --- /dev/null +++ b/ui/common/css/component/_blind-mode.scss @@ -0,0 +1,20 @@ +#blind-mode { + margin-left: -99999px; + height: 0; + .blind-mode & { + text-align: center; + padding: 5px 0; + background: #888; + margin-left: 0; + height: auto; + } +} +.blind-mode { + .is::before, + .is::after, + [data-icon]::before { + content: none; + display: none; + visibility: hidden; + } +} diff --git a/ui/common/css/component/_board-resize.scss b/ui/common/css/component/_board-resize.scss new file mode 100644 index 0000000000..c213a59c9d --- /dev/null +++ b/ui/common/css/component/_board-resize.scss @@ -0,0 +1,43 @@ +body.resizing { + user-select: none; +} + +.board-resize { + $resize-width: 22px; + display: none; + @include breakpoint($mq-board-resizable) { + display: block; + position: absolute; + right: #{13px - $resize-width}; + bottom: #{13px - $resize-width}; + width: $resize-width; + height: $resize-width; + cursor: nwse-resize; + &::before, &::after { + background: #000; + content: ''; + position: absolute; + width: 12px; + height: 1px; + } + &::before { + width: 5px; + transform: + translate(7px, 8px) + rotate(-45deg); + } + &::after { + transform: + translate(1px, 6px) + rotate(-45deg); + } + &:hover { + border-radius: 50%; + background: fade-out($c-accent, 0.5); + } + .resizing & { + border-radius: 50%; + background: fade-out($c-secondary, 0.5); + } + } +} diff --git a/ui/common/css/component/_board.scss b/ui/common/css/component/_board.scss new file mode 100644 index 0000000000..15fe41b429 --- /dev/null +++ b/ui/common/css/component/_board.scss @@ -0,0 +1,13 @@ +.main-board { + @extend %square; + &__preload { + position: absolute; + } + .cg-board-wrap { + @extend %abs-100; + } +} + +.mini-board { + @extend %square; +} diff --git a/ui/common/css/component/_box.scss b/ui/common/css/component/_box.scss new file mode 100644 index 0000000000..de60909f03 --- /dev/null +++ b/ui/common/css/component/_box.scss @@ -0,0 +1,61 @@ +$vp-min-width: 320px; +$vp-max-width: 1200px; + +.box { + @extend %box-shadow; + background: $c-bg-box; + + @include fluid-size('--box-padding', 15px, 60px); + + &-pad { + @extend %box-padding; + .box__top { + padding: 0 0 var(--box-padding) 0; + } + } + + &__top { + @extend %flex-between; + + padding: calc(5vh - 1rem) var(--box-padding); + + h1 { + margin: 0; + } + + /* flex gutters, waiting for row-gap to be implemented for flexbox. https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Mastering_Wrapping_of_Flex_Items#Creating_gutters_between_items */ + > h1, > div, > form { margin-top: 1rem; } + /* end of flex gutter hack */ + + &__actions { + @extend %flex-wrap; + + /* flex gutters, waiting for row-gap to be implemented for flexbox. https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Mastering_Wrapping_of_Flex_Items#Creating_gutters_between_items */ + margin-left: -1rem; + > * { margin-left: 1rem; } + /* end of flex gutter hack */ + + .button { + @extend %flex-center; + } + > :not(:first-child) { + margin-left: 1rem; + } + } + } + + &:not(.box-pad) > h1 { + @extend %box-padding; + margin: 0; + } + + &__pad { + @extend %box-padding-horiz; + } +} + +@include breakpoint($mq-main-margin) { + .box { + @include box-radius; + } +} diff --git a/ui/common/css/component/_btn-rack.scss b/ui/common/css/component/_btn-rack.scss new file mode 100644 index 0000000000..ff07468d81 --- /dev/null +++ b/ui/common/css/component/_btn-rack.scss @@ -0,0 +1,42 @@ +.btn-rack { + @extend %box-radius; + display: inline-flex; + align-items: center; + border: $border; + user-select: none; + .btn-rack { /* embedded racks */ + border: none; + } + &__btn, + form { + @extend %flex-center-nowrap, %metal; + justify-content: center; + text-align: center; + line-height: 2rem; + cursor: pointer; + border-right: $border; + color: $c-font; + &:hover { + @extend %metal-hover; + color: $c-font; + } + &:first-child { + @extend %box-radius-left; + } + &:last-child { + @extend %box-radius-right; + border: 0; + } + i { + @extend %roboto; + letter-spacing: -1px; + } + } + &__btn { + padding: 0 .6em; + &.active { + @extend %active; + color: #fff; + } + } +} diff --git a/ui/common/css/component/_button.scss b/ui/common/css/component/_button.scss new file mode 100644 index 0000000000..1d831c0389 --- /dev/null +++ b/ui/common/css/component/_button.scss @@ -0,0 +1,91 @@ +.button { + @extend %roboto-fat, %button-shadow, %box-radius; + background: $c-primary; + text-transform: uppercase; + padding: .8em 1em; + border: none; + cursor: pointer; + text-align: center; + @include transition(); + white-space: nowrap; + &, + &:visited { + color: $c-primary-over; + } + &:not(.disabled):hover { + @extend %button-raised-shadow; + color: $c-primary-over; + background: lighten($c-primary, 7); + } + &-no-upper { + text-transform: none; + } + &-thin { + padding: .1em 1em; + font-size: 90%; + } + &-fat { + font-size: 1.6rem; + } + &-green { + background: $c-secondary; + &:not(.disabled):hover { + background: lighten($c-secondary, 4); + } + } + &-red { + background: $c-error; + &:not(.disabled):hover { + background: lighten($c-error, 11); + } + } + &.button-empty { + transition: none; + &, + &:hover { + color: $c-primary; + } + background: none; + box-shadow: none; + &:not(.disabled):hover { + @extend %button-shadow; + } + &, + &.button-green, + &.button-red { + &:not(.disabled):hover { + @extend %metal; + } + } + &.button-red, + &.button-red:hover { + color: $c-error; + } + &.button-green, + &.button-green:hover { + color: $c-secondary; + } + } + &.button-metal { + @extend %metal; + &, + &:hover { + color: $c-font-dim; + } + &:not(.disabled):hover { + @extend %metal-hover; + } + } + &.disabled { + opacity: .5; + cursor: not-allowed; + } + &.active { + @extend %active; + color: #fff; + } + &.active:not(.disabled):hover { + @extend %active-hover; + color: #fff; + } +} diff --git a/ui/common/css/component/_color-icon.scss b/ui/common/css/component/_color-icon.scss new file mode 100644 index 0000000000..ae6cc810f5 --- /dev/null +++ b/ui/common/css/component/_color-icon.scss @@ -0,0 +1,20 @@ +.color-icon { + @if $theme-light { + &.white::before { + content: "K"; + } + &.black::before { + content: "J"; + } + } @else { + &.white::before { + content: "J"; + } + &.black::before { + content: "K"; + } + } + &.random::before { + content: "l"; + } +} diff --git a/ui/common/css/component/_context-streamer.scss b/ui/common/css/component/_context-streamer.scss new file mode 100644 index 0000000000..05ae0f6dd9 --- /dev/null +++ b/ui/common/css/component/_context-streamer.scss @@ -0,0 +1,14 @@ +.context-streamer { + @extend %nowrap-hidden, %box-radius-bottom, %box-shadow, %flex-center-nowrap; + height: 2.2em; + color: $c-secondary-over !important; + background: mix($c-secondary, $c-bg-page, 60%); + @include transition(); + &::before { + font-size: 1.3em; + margin-left: .4em; + } + &:hover { + background: mix($c-secondary, $c-bg-page, 80%); + } +} diff --git a/ui/common/css/component/_continue-with.scss b/ui/common/css/component/_continue-with.scss new file mode 100644 index 0000000000..6b8ee3bc49 --- /dev/null +++ b/ui/common/css/component/_continue-with.scss @@ -0,0 +1,6 @@ +.continue-with { + @extend %flex-column; + > *:not(:first-child) { + margin-top: 1em; + } +} diff --git a/ui/common/css/component/_crosstable.scss b/ui/common/css/component/_crosstable.scss new file mode 100644 index 0000000000..e1562679d1 --- /dev/null +++ b/ui/common/css/component/_crosstable.scss @@ -0,0 +1,84 @@ +@include crosstable-small; + +.crosstable { + @extend %box-neat-force; + width: 100%; + line-height: 1.9em; + display: flex; + + fill, + povs { + background: $c-bg-box; + flex: 1 1 auto; + } + povs, + &__users, + &__score, + &__matchup { + @extend %flex-column; + text-align: center; + } + &__users, + &__score { + @extend %metal; + } + &__users { + @extend %ellipsis; + max-width: 40vw; + text-align: left; + a { + padding-left: $block-gap; + } + } + &__score { + flex: 0 0 auto; + font-weight: bold; + span { + padding: 0 $block-gap; + } + } + &__matchup { + flex: 1 1 auto; + font-weight: bold; + background: mix($c-primary, $c-bg-box, 20%); + } + povs { + a { + color: $c-font-dim; + flex: 0 0 50%; + @include transition(); + } + &:hover a { + background: mix($c-accent, $c-bg-box, 12%); + } + &.current a { + background: mix($c-accent, $c-bg-box, 70%); + color: #fff; + } + &.new { + border: $c-border; + } + @include breakpoint($mq-not-x-small) { + display: none; + &:nth-last-child(-n+12) { + display: flex; + } + } + } + .sep { + @extend %box-radius-left; + border-left: $border; + margin-left: .3em; + } + .win { + font-weight: bold; + color: $c-good; + } + .loss { + color: $c-bad; + } + .unavailable { + margin-top: 40px; + opacity: 0.7; + } +} diff --git a/ui/common/css/component/_fbt.scss b/ui/common/css/component/_fbt.scss new file mode 100644 index 0000000000..1fa56adbd8 --- /dev/null +++ b/ui/common/css/component/_fbt.scss @@ -0,0 +1,21 @@ +.fbt { + @extend %button-none; + text-transform: uppercase; + line-height: 1.5; + @include transition(); + @media (hover: hover) { + &:hover:not(.disabled):not([disabled]) { + background: mix($c-secondary, $c-bg-box, 75%); + color: #fff; + } + } + &.active { + background: $c-secondary!important; + color: #fff; + } + &.disabled, + &[disabled] { + opacity: 0.5; + cursor: default; + } +} diff --git a/ui/common/css/component/_fire-trophy.scss b/ui/common/css/component/_fire-trophy.scss new file mode 100644 index 0000000000..adc9864a51 --- /dev/null +++ b/ui/common/css/component/_fire-trophy.scss @@ -0,0 +1,38 @@ +%fire-trophy-shadow { + text-shadow: 0 .008em .127em #fefcc9, + .055em -.066em .2em #feec85, + -.111em -.127em .272em #ffae34, + .111em -.272em .411em #ec760c, + -.111em -.456em .416em #cd4606, + 0 -.533em .577em #973716, + .055em -.55em .533em #451b0e; +} +@keyframes fire-trophy { + 0% { + text-shadow: 0 .008em .127em #fefcc9, + .055em -.066em .2em #feec85, + -.111em -.127em .272em #ffae34, + .111em -.272em .411em #ec760c, + -.111em -.456em .416em #cd4606, + 0 -.533em .577em #973716, + .055em -.55em .533em #451b0e; + } + 100% { + text-shadow: 0 0 .111em #fefcc9, + .055em -.055em .166em #fefcc9, + -.111em -.111em .222em #feec85, + .122em -.233em .333em #ffae34, + -.122em -.322em .277em #ec760c, + 0 -.456em .444em #cd4606, + .055em -.5em .444em #973716; + } +} +.fire-trophy { + @extend %fire-trophy-shadow; + color: $c-font; + font-size: 90px; + display: block; + &:hover { + animation: fire-trophy 1.5s ease-in-out infinite alternate; + } +} diff --git a/ui/common/css/component/_friend-box.scss b/ui/common/css/component/_friend-box.scss new file mode 100644 index 0000000000..855c64f80d --- /dev/null +++ b/ui/common/css/component/_friend-box.scss @@ -0,0 +1,82 @@ +#friend_box { + display: none; + @include breakpoint($mq-topnav-visible $mq-site-header-tall) { + display: block; + } + position: fixed; + bottom: 0; + right: 0; + z-index: z('friend-box'); + background: $c-bg-popup; + border: $border; + border-right: 0; + border-top-left-radius: $box-radius-size; + font-size: .9rem; + min-width: 150px; + max-height: 95%; + /* improve scroll perfs */ + backface-visibility: hidden; + @include hoverflow; + .friend_box_title { + @extend %metal; + cursor: pointer; + padding: 3px 5px; + border-bottom: $border; + &:hover { + @extend %metal-hover; + } + } + .content { + div { + display: flex; + &:hover { + background: mix($c-secondary, $c-bg-popup, 10%); + } + } + a { + flex: 1 1 100%; + padding: 3px 0px; + display: block; + transition: background 0.13s; + &:hover { + color: $c-font; + } + &.user-link { + @extend %ellipsis; + max-width: 150px; + .line::before { + color: $c-good; + content: ''; + } + } + &.tv { + flex: 0 0 auto; + padding: 0 5px; + } + &.friend-study { + flex: 0 0 auto; + padding: 2px 5px 0 5px; + } + } + i.line { + opacity: 0.6; + } + } + .nobody { + text-align: center; + height: 100%; + padding: 3px 5px; + span { + display: block; + margin: 5px; + } + } + a.find { + display: none; + margin: 7px; + font-style: normal; + } + .nobody:hover a.find { + display: block; + } +} diff --git a/ui/common/css/component/_glowing.scss b/ui/common/css/component/_glowing.scss new file mode 100644 index 0000000000..7f7cc3e996 --- /dev/null +++ b/ui/common/css/component/_glowing.scss @@ -0,0 +1,6 @@ +@keyframes glowing { + 50% { background: mix($c-link, $c-bg-box, 60%); } +} +.glowing { + animation: glowing 1.5s ease-in-out infinite; +} diff --git a/ui/common/css/component/_hover-text.scss b/ui/common/css/component/_hover-text.scss new file mode 100644 index 0000000000..fb8a1991ae --- /dev/null +++ b/ui/common/css/component/_hover-text.scss @@ -0,0 +1,8 @@ +.hover-text { + &::after { + content: attr(title); + } + &:hover::after { + content: attr(data-hover-text); + } +} diff --git a/ui/common/css/component/_loader.scss b/ui/common/css/component/_loader.scss new file mode 100644 index 0000000000..0652114a5d --- /dev/null +++ b/ui/common/css/component/_loader.scss @@ -0,0 +1,50 @@ +/* circular loader */ +@keyframes spinner-rotate { + 100% { transform: rotate(360deg); } +} +@keyframes spinner-dash { + 0%,10% { stroke-dasharray: 1,270; stroke-dashoffset: 0 } + 40% { stroke-dasharray: 89,240; stroke-dashoffset: 0 } + 100% { stroke-dasharray: 1,240; stroke-dashoffset: -110 } +} +@keyframes spinner-color { + 0%,20%,100% { stroke: #42a5f5 } + 30%,45% { stroke: #f44336 } + 50%,70% { stroke: #fdd835 } + 75%,95% { stroke: #4caf50 } +} +.spinner { + width: 70px; + height: 70px; + margin: auto; + svg { + animation: spinner-rotate 1.5s linear infinite; + } + circle { + stroke: #42a5f5; + stroke-width: 4; + animation: spinner-dash 1.275s ease-in-out infinite, spinner-color 5.1s linear infinite; + } + .white & circle { + animation: spinner-dash 1.275s ease-in-out infinite; + stroke: #fff; + } +} + +/* small horizontal loader */ +@keyframes ddloader { + 0% { background-position: left } + 100% { background-position: right } +} +.ddloader { + @if $theme-light { + background: img-url('loader/blackx1.png') no-repeat; + } @else { + background: img-url('loader/whitex1.png') no-repeat; + } + animation: ddloader 0.5s steps(15) infinite; + vertical-align: middle; + display: inline-block; + width: 32px; + height: 8px; +} diff --git a/ui/common/css/component/_modal.scss b/ui/common/css/component/_modal.scss new file mode 100644 index 0000000000..474137ee27 --- /dev/null +++ b/ui/common/css/component/_modal.scss @@ -0,0 +1,41 @@ +#modal { + &-overlay { + @extend %fullscreen-mask, %flex-center; + justify-content: center; + } + &-wrap { + @extend %box-radius, %popup-shadow, %flex-column; + background: $c-bg-box; + position: relative; + padding: 2rem; + text-align: center; + max-width: 100vw; + max-height: 96vh; + > div { + overflow: auto; + } + .close { + color: $c-font; + position:absolute; + font-size: 16px; + line-height: 27px; + width: 32px; + height: 32px; + cursor: pointer; + top: 0; + right: 0; + background: none; + @include breakpoint($mq-small) { + top: -12px; + right: -12px; + background: $c-bg-popup; + border-radius: 50%; + } + } + .close:hover { + @extend %box-shadow; + background: $c-bad; + color: #fff; + } + } +} diff --git a/ui/common/css/component/_mselect.scss b/ui/common/css/component/_mselect.scss new file mode 100644 index 0000000000..5574e3fcbd --- /dev/null +++ b/ui/common/css/component/_mselect.scss @@ -0,0 +1,77 @@ +$c-mselect: $c-primary; + +.mselect { + position: relative; + white-space: nowrap; + &__toggle { + @include hide; + } + &__label { + @extend %box-neat, %metal, %flex-between; + flex-flow: row nowrap; + padding: .3rem .3rem .3rem 1rem; + cursor: pointer; + &:hover { + @extend %metal-hover; + } + &::after { + @extend %data-icon; + content: 'u'; + font-size: 70%; + color: $c-mselect; + } + } + &__toggle:checked ~ .mselect__label { + @include transition(opacity); + opacity: 0; + } + &__list { + @extend %base-font, %box-radius, %popup-shadow, %flex-column; + position:absolute; + top:0; + left:0; + min-width: 100%; + z-index: z('mselect'); + background: $c-bg-popup; + transform: scale(1, 0); + transform-origin: top; + @include transition(transform); + .current { + background: $c-bg-zebra; + @extend %flex-between-nowrap; + &::after { + @extend %data-icon; + content: 'E'; + flex: 1 1 100%; + text-align: right; + } + } + > * { + white-space: nowrap; + display: block; + padding: .3em 1em; + @include transition(); + color: $c-mselect; + &:hover{ + background: $c-mselect; + color: #fff; + } + &::before { + margin-right: .4em; + } + opacity: 0; + } + .mselect__toggle:checked ~ & { + transform: scale(1, 1); + @include breakpoint($mq-not-small) { + position: fixed; + top: 50%; + transform: translateY(-50%) scale(1, 1); + } + > * { + opacity: 1; + transition: opacity 125ms ease-in-out 125ms; + } + } + } +} diff --git a/ui/common/css/component/_nag-circle.scss b/ui/common/css/component/_nag-circle.scss new file mode 100644 index 0000000000..850b6dad09 --- /dev/null +++ b/ui/common/css/component/_nag-circle.scss @@ -0,0 +1,66 @@ +$c-circle: 'd64f00'; +$scale-out: 1.15; + +@keyframes inner-circle-loop { + 0% { + opacity: .2; + transform: scale(#{$scale-out}) + } + + 42% { + opacity: .8; + transform: scale(.9) + } + + to { + opacity: .2; + transform: scale(#{$scale-out}) + } +} + +@keyframes outer-circle-loop { + 0% { + opacity: 0; + transform: scale(#{$scale-out}) + } + + 51% { + opacity: .9; + transform: scale(.9) + } + + to { + opacity: 0; + transform: scale(#{$scale-out}) + } +} + +.nag-circle { + position: absolute; + z-index: z('nag-circle'); + top: -8px; + left: -8px; + + &::before { + content: ' '; + animation: inner-circle-loop 1.5s infinite; + position: absolute; + background-image: url("data:image/svg+xml,%3C!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3E%3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 17 17' enable-background='new 0 0 17 17' xml:space='preserve'%3E%3Cg%3E%3Cpath fill='%23#{$c-circle}' d='M8.495,2c0.566,0,1.133,0.075,1.687,0.223c3.461,0.928,5.522,4.498,4.595,7.958 C14.016,13.019,11.437,15,8.505,15c-0.566,0-1.134-0.075-1.687-0.223c-1.677-0.449-3.078-1.524-3.946-3.027 c-0.868-1.503-1.098-3.254-0.649-4.931C2.984,3.981,5.562,2,8.495,2 M8.495,0C4.743,0,1.309,2.504,0.292,6.301 c-1.215,4.533,1.475,9.193,6.009,10.408C7.037,16.906,7.777,17,8.505,17c3.752,0,7.186-2.504,8.203-6.301 c1.215-4.533-1.476-9.193-6.009-10.408C9.963,0.094,9.223,0,8.495,0L8.495,0z'/%3E%3C/g%3E%3C/svg%3E%0A"); + background-size: contain; + width: 30px; + height: 30px; + top: 3px; + left: 3px; + } + + + &::after { + content: ' '; + animation: outer-circle-loop 1.5s infinite; + position: absolute; + background: url("data:image/svg+xml,%3C!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'%3E%3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 20 20' enable-background='new 0 0 20 20' xml:space='preserve'%3E%3Cg%3E%3Cpath fill='%23#{$c-circle}' d='M9.994,1c0.784,0,1.569,0.104,2.335,0.309c4.792,1.284,7.646,6.228,6.362,11.02 C17.638,16.257,14.067,19,10.006,19c-0.784,0-1.57-0.104-2.335-0.309c-2.322-0.622-4.262-2.111-5.463-4.192 c-1.202-2.081-1.521-4.506-0.899-6.828C2.362,3.743,5.933,1,9.994,1 M9.994,0C5.58,0,1.54,2.946,0.343,7.412 c-1.429,5.333,1.736,10.815,7.069,12.244C8.279,19.889,9.15,20,10.006,20c4.414,0,8.454-2.946,9.651-7.412 c1.429-5.333-1.736-10.815-7.069-12.244C11.721,0.111,10.85,0,9.994,0L9.994,0z'/%3E%3C/g%3E%3C/svg%3E ") 50% no-repeat; + background-size: contain; + width: 36px; + height: 36px; + } +} diff --git a/ui/common/css/component/_now-playing.scss b/ui/common/css/component/_now-playing.scss new file mode 100644 index 0000000000..f3ddc520c0 --- /dev/null +++ b/ui/common/css/component/_now-playing.scss @@ -0,0 +1,28 @@ +.now-playing { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + a { + @extend %box-radius; + color: $c-font; + padding: .3em; + @include transition(background); + background: fade-out($c-bg-box, 0.6); + &:hover { + background: fade-out($c-link, 0.6); + color: $c-font-clear; + } + } + .meta { + display: block; + text-align: center; + overflow: hidden; + } + .indicator { + color: $c-accent; + margin-top: -3px; + display: block; + } + .cg-board { + box-shadow: none; + } +} diff --git a/ui/common/css/component/_power-tip.scss b/ui/common/css/component/_power-tip.scss new file mode 100644 index 0000000000..bc93da4af5 --- /dev/null +++ b/ui/common/css/component/_power-tip.scss @@ -0,0 +1,101 @@ +#powerTip, +#miniGame { + @extend %box-radius-force, %popup-shadow; + width: 20rem; + min-height: 3em; + background: $c-bg-popup; + display: none; + position: absolute; + z-index: z('powertip'); +} +#powerTip { + .mini-board { + border-width: 0 0 1px 0; + } +} +.upt { + &__info { + @extend %flex-column; + height: 83px; + padding: 4px 5px 4px 2px; + border-bottom: $border; + overflow: hidden; + &__top { + @extend %flex-between; + .left { + @extend %flex-center-nowrap; + } + &__country { + margin-left: .5em; + } + .user-link { + @extend %ellipsis; + display: block; + .line { + vertical-align: middle; + } + } + &__country { + @extend %flex-center; + font-size: .9em; + img { + margin-right: .3em; + } + } + } + &__ratings { + @extend %flex-between; + margin-top: 3px; + > span { + flex: 0 0 25%; + padding: 2px 3px; + text-align: left; + } + } + } + &__score { + display: block; + font-size: 1rem; + line-height: 1.5rem; + text-align: center; + } + &__actions.btn-rack { + @extend %box-shadow; + width: 100%; + justify-content: stretch; + border: 0; + border-radius: 0; + a { + flex: 0 0 18%; + &.relation-button { + flex: 1 1 auto; + } + } + } + &__mod { + @extend %flex-between; + white-space: nowrap; + &__marks { + padding: 3px 5px; + background: $c-bad; + color: #fff; + } + span { + padding: .2em .5em; + margin: 0; + } + } + &__game-legend { + @extend %flex-between; + padding: .2em 1em; + } +} +#miniGame { + min-height: 262px; + .spinner { + margin: 82px auto 0 auto; + } + .cg-board { + border-radius: 0; + } +} diff --git a/ui/common/css/component/_quote.scss b/ui/common/css/component/_quote.scss new file mode 100644 index 0000000000..ae4a3abb06 --- /dev/null +++ b/ui/common/css/component/_quote.scss @@ -0,0 +1,36 @@ +.pull-quote { + margin: 0 auto; + p { + color: $c-font; + position: relative; + margin: 0 .7em; + padding: 1em 0; + border: $border; + border-width: 1px 0; + font-style: italic; + font-size: 1.1rem; + &:after { + content: ''; + position: absolute; + bottom: -9px; + left: 42px; + width: 15px; + height: 15px; + background: $c-bg-box; + border-left: 2px solid $c-border; + border-bottom: 1px solid $c-border; + transform: skew(45deg) rotate(-45deg); + } + } + &.long p { + font-size: 1rem; + } + footer { + margin: 10px; + line-height: 20px; + text-align: right; + &:before { + content: '\2014'; + } + } +} diff --git a/ui/common/css/component/_reconnecting.scss b/ui/common/css/component/_reconnecting.scss new file mode 100644 index 0000000000..c5df1ceced --- /dev/null +++ b/ui/common/css/component/_reconnecting.scss @@ -0,0 +1,39 @@ +$recon-height: 2.5rem; + +@keyframes reconnected { + 0% { opacity: 1; transform: translateY(0); } + 100% { opacity: 0; transform: translateY($recon-height); } +} + +#reconnecting { + @extend %flex-center-nowrap, %popup-shadow; + font-size: 1.2em; + font-weight: bold; + position: fixed; + background: $c-bad; + color: $c-bad-over; + position: fixed; + bottom: 0; + left: 0; + height: $recon-height; + padding: 0 1rem; + border-top-right-radius: 3px; + z-index: z('reconnecting'); + opacity: 0; + transform: translateY($recon-height); + + &::before { + font-size: 1.3em; + } + .offline & { + transform: translateY(0); + opacity: 1; + } + .online.reconnected & { + background: $c-good; + animation: reconnected 2.5s ease-out 1.5s backwards; + } + .online &::before { + content: 'J' + } +} diff --git a/ui/common/css/component/_signal.scss b/ui/common/css/component/_signal.scss new file mode 100644 index 0000000000..2b66af0e9a --- /dev/null +++ b/ui/common/css/component/_signal.scss @@ -0,0 +1,27 @@ +signal { + display: inline-block; + height: 1em; + width: 1.5em; + overflow: visible; + white-space: nowrap; +} +signal > i { + width: 20%; + margin-left: 1px; + display: inline-block; + height: 40%; + background-color: c-dimmer($c-good); +} +signal > i:nth-child(2) { height: 60%; } +signal > i:nth-child(3) { height: 80%; } +signal > i:nth-child(4) { height: 100%; } + +signal.q1 > i { + background-color: $c-bad; +} +signal.q2 > i { + background-color: $c-warn; +} +signal > i.off { + background-color: $c-shade; +} diff --git a/ui/common/css/component/_slist.scss b/ui/common/css/component/_slist.scss new file mode 100644 index 0000000000..4fca017cda --- /dev/null +++ b/ui/common/css/component/_slist.scss @@ -0,0 +1,39 @@ +.slist { + width: 100%; + border-bottom: $border; + thead { + @extend %metal, %roboto; + th { + border-top: $border; + border-bottom: $border; + padding: .5rem .8rem; + } + th.large { + font-size: 1.2rem; + } + } + td { + padding: 1rem; + .label { + font-family: monospace; + font-size: 0.8rem; + } + } + tbody tr:nth-child(even) { + background: $c-bg-zebra; + } + td:first-child, + th:first-child { + padding-left: 1.5rem; + } + &-pad { + td:first-child, + th:first-child { + padding-left: var(--box-padding); + } + td:last-child, + th:last-child { + padding-right: var(--box-padding); + } + } +} diff --git a/ui/common/css/component/_subnav.scss b/ui/common/css/component/_subnav.scss new file mode 100644 index 0000000000..afebe65f2e --- /dev/null +++ b/ui/common/css/component/_subnav.scss @@ -0,0 +1,70 @@ +.subnav { + a { + @extend %nowrap-hidden, %page-text; + } + + @include breakpoint($mq-subnav-top) { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(17ch, 1fr)); + grid-gap: 3px; + margin-bottom: 3px; + + background: $c-bg-page; + + a { + @include box-neat; + font-family: roboto; + display: flex; + align-items: center; + color: $c-font; + padding: .6rem 0 .6rem .5rem; + letter-spacing: -0.06em; + background: $c-bg-high; + &:hover { + color: $c-link; + } + &.active { + background: $c-primary; + color: $c-primary-over; + } + } + .sep { + display: none; + } + } + + @include breakpoint($mq-subnav-side) { + margin-top: 5px; + z-index: z('subnav-side'); /* active border must go over the page content */ + a { + display: block; + color: $c-font-page; + padding: .7rem 2vw .7rem .8rem; + position: relative; + @include transition(); + &::after { + content: ""; + background: fade-out($c-accent, .4); + width: 3px; + position: absolute; + height: 98%; + top: 1%; + right: -1px; + @include transition(all, .25s); + transform: scale(0); + } + &.active, + &:hover { + &::after { + transform: scale(1); + } + } + &.active { + color: $c-accent; + } + } + .sep { + height: 2em; + } + } +} diff --git a/ui/common/css/component/_tabs-horiz.scss b/ui/common/css/component/_tabs-horiz.scss new file mode 100644 index 0000000000..17ece09f02 --- /dev/null +++ b/ui/common/css/component/_tabs-horiz.scss @@ -0,0 +1,46 @@ +.tabs-horiz { + @extend %flex-center-nowrap, %page-text; + justify-content: center; + align-items: flex-end; + border-bottom: 2px solid $c-border; + @include breakpoint($mq-not-xx-small) { + font-size: .9em; + } + span { + @extend %roboto; + flex: 1 1 auto; + text-align: center; + padding: .5em .2em; + cursor: pointer; + position: relative; + @include transition(color, .25s); + min-width: 15%; + letter-spacing: -.5px; + @include breakpoint($mq-xx-small) { + letter-spacing: inherit; + } + &::after { + content: ''; + background: fade-out($c-accent, .3); + height: 2px; + position: absolute; + width: 96%; + left: 2%; + bottom: -2px; + @include transition(all, .25s); + transform: scale(0); + } + &.active, + &:hover { + &::after { + transform: scale(1); + } + } + &.active { + color: $c-accent; + } + } + .unread { + margin-left: .3em; + } +} diff --git a/ui/common/css/component/_user-link.scss b/ui/common/css/component/_user-link.scss new file mode 100644 index 0000000000..e12d6761d7 --- /dev/null +++ b/ui/common/css/component/_user-link.scss @@ -0,0 +1,45 @@ +.user-link { + @extend %nowrap-hidden; + color: $c-font; + .line { + @extend %data-icon; + color: $c-font; + opacity: 0.5; + display: inline-block; + width: 1.5em; + text-align: center; + vertical-align: text-top; /* not sure about that */ + &.patron { + opacity: 0.8; + } + &::before { + content: 'Ò'; + } + &.patron::before { + content: '' !important; + } + &.moderator::before { + content: ''; + } + } + &.online .line { + &::before { + content: ''; + } + color: $c-good; + opacity: .9; + &.patron { + opacity: 1; + } + } + .title { + color: $c-brag; + font-weight: bold; + &[data-bot] { + color: $c-bot; + } + } +} +a.user-link:hover { + color: $c-link; +} diff --git a/ui/common/css/component/_vs.scss b/ui/common/css/component/_vs.scss new file mode 100644 index 0000000000..cf97c8366f --- /dev/null +++ b/ui/common/css/component/_vs.scss @@ -0,0 +1,20 @@ +.vstext { + @extend %flex-between-nowrap, %nowrap-hidden, %box-neat; + background: $c-bg-box; + padding: .3em .6em; + color: $c-font; + &__center { + text-align: center; + } + &__pl, + &__op { + @extend %ellipsis; + max-width: 45%; + } + &__pl { + text-align: left; + } + &__op { + text-align: right; + } +} diff --git a/ui/common/css/form/_captcha.scss b/ui/common/css/form/_captcha.scss new file mode 100644 index 0000000000..7e4f140614 --- /dev/null +++ b/ui/common/css/form/_captcha.scss @@ -0,0 +1,39 @@ +.form3 .captcha { + @extend %flex-wrap; + margin: 1em 0 0 -1em; + @include breakpoint($mq-xx-small) { + flex-wrap: nowrap; + } + &.is-invalid:not(.success) { + @extend %box-radius; + border: 1px solid $c-error; + background: mix($c-error, $c-bg-high, 10%); + } + .challenge { + flex: 0 0 250px; + margin: 0 0 1em 1em; + } + .captcha-explanation { + flex: 1 1 auto; + overflow: hidden; + margin: 0 0 1em 1em; + } + &.is-invalid .captcha-explanation { + padding: 1em; + } + .captcha-explanation .result { + display: none; + margin-top: 1rem; + font-weight: bold; + } + .success { + color: $c-good; + } + .failure { + color: $c-error; + } + &.success .success, + &.failure .failure { + display: block; + } +} diff --git a/ui/common/css/form/_cmn-toggle.scss b/ui/common/css/form/_cmn-toggle.scss new file mode 100644 index 0000000000..04eb2bb89b --- /dev/null +++ b/ui/common/css/form/_cmn-toggle.scss @@ -0,0 +1,56 @@ +.cmn-toggle { + position: absolute; + margin-left: -9999px; + visibility: hidden; +} +.cmn-toggle + label { + display: block; + position: relative; + cursor: pointer; + outline: none; + -webkit-user-select: none; + -moz-user-select: none; +} +.cmn-toggle + label { + padding: 1px; + width: 40px; + height: 24px; + background-color: $c-border; + border-radius: 24px; +} +.cmn-toggle + label::before, +.cmn-toggle + label::after { + display: block; + position: absolute; + top: 1px; + left: 1px; + bottom: 1px; + content: ""; +} +.cmn-toggle + label::before { + right: 1px; + background-color: $c-bad; + border-radius: 24px; +} +.cmn-toggle--subtle + label::before { + background-color: $c-font-dimmer; +} +.cmn-toggle:hover + label::before { + @include transition(background); +} +.cmn-toggle + label::after { + @extend %metal; + width: 22px; + border-radius: 100%; + box-shadow: 0 1px 2.5px rgba(0, 0, 0, 0.3); +} +.cmn-toggle:hover + label::after { + @extend %metal-hover; + @include transition(margin); +} +.cmn-toggle:checked + label::before { + background-color: $c-good; +} +.cmn-toggle:checked + label::after { + margin-left: 16px; +} diff --git a/ui/common/css/form/_form3.scss b/ui/common/css/form/_form3.scss new file mode 100644 index 0000000000..46d75b2316 --- /dev/null +++ b/ui/common/css/form/_form3.scss @@ -0,0 +1,87 @@ +@import 'cmn-toggle'; + +.form-group { + margin-bottom: 2rem; +} +.form-split { + @extend %flex-between; + align-items: inherit; +} +.form-half { + flex: 1 1 48%; + min-width: 200px; +} +.form-third { + flex: 1 1 31%; +} +@include breakpoint($mq-xx-small) { + .form-half, + .form-third { + flex-grow: 0; + } +} + +.form-label { + font-weight: bold; + display: inline-block; + margin-bottom: .5rem; +} +.form-control { + display: block; + width: 100%; + height: calc(2.7em + 2px); + background-clip: padding-box; +} +textarea.form-control { + height: auto; +} +.form-control:invalid, +.form-group.is-invalid .form-control { + border-color: $c-error; +} +.form3 .error, +.form-help { + font-size: 90%; + margin-top: 0.25rem; +} +.form3 .error { + color: $c-error; +} +.form-help { + color: $c-font-dim; +} + +.form-check div { + display: flex; +} + +.form-check-input { + margin-right: 0.5rem; +} + +.form-check .form-label { + margin-bottom: 0; + cursor: pointer; +} + +.form-actions { + @extend %flex-between; + margin: 1.5rem 0; + padding-top: 1.5rem; + border-top: $border; +} +.form-actions.single { + justify-content: flex-end; +} + +.form3 hr { + margin-top: 1rem; + margin-bottom: 1rem; + border: 0; + border-top: $border; +} + +/* VENDORS */ +.form3 .twitter-typeahead { + width: 100%; +} diff --git a/ui/common/css/form/_radio.scss b/ui/common/css/form/_radio.scss new file mode 100644 index 0000000000..160d67cff8 --- /dev/null +++ b/ui/common/css/form/_radio.scss @@ -0,0 +1,30 @@ +group.radio { + @extend %box-neat, %flex-wrap; + overflow: hidden; + div { + flex: 1 1 auto; + position: relative; + } + input { + position:absolute; + left: -99999px; + } + label { + @extend %metal, %flex-center; + justify-content: center; + padding: 10px; + height: 100%; + cursor:pointer; + border-right: $border; + user-select: none; + &:hover { + @extend %metal-hover; + } + } + div:last-child label { + border-right: 0; + } + input:checked + label { + @extend %active; + } +} diff --git a/ui/common/css/form/_range.scss b/ui/common/css/form/_range.scss new file mode 100644 index 0000000000..7a7d701011 --- /dev/null +++ b/ui/common/css/form/_range.scss @@ -0,0 +1,58 @@ +@mixin range-thumb { + @include metal; + border: 1px solid $c-font-dimmer; + height: 1em; + width: 1.5em; + border-radius: 12px; + background: $c-bg-box; + cursor: pointer; +} +@mixin range-track { + width: 100%; + height: 1em; + cursor: pointer; + background: $c-shade; + border-radius: .5em; +} + +input[type=range] { + -webkit-appearance: none; + background: none; + border: 0; + &:focus { + outline: none; + } + + &::-webkit-slider-runnable-track { + @include range-track; + } + &::-webkit-slider-thumb { + @include range-thumb; + -webkit-appearance: none; + margin-top: -0.3px; + } + + &::-moz-range-track { + @include range-track; + } + &::-moz-range-thumb { + @include range-thumb; + } + + &::-ms-track { + @include range-track; + } + &::-ms-fill-lower { + background: rgba(191, 191, 191, 0.78); + border-radius: 11.8px; + } + &::-ms-fill-upper { + background: rgba(214, 214, 214, 0.78); + border-radius: 11.8px; + } + &::-ms-thumb { + @include range-thumb; + border-color: transparent; + color: transparent; + } +} diff --git a/ui/common/css/form/_ui-slider.scss b/ui/common/css/form/_ui-slider.scss new file mode 100644 index 0000000000..7a10117ee5 --- /dev/null +++ b/ui/common/css/form/_ui-slider.scss @@ -0,0 +1,60 @@ +$c-slider: mix($c-secondary, $c-bg-box, 90%) !default; +$slider-width: 12px; + +.ui-slider { + background: $c-slider; + position: relative; + text-align: left; + cursor:pointer; +} +.ui-widget-header { + @extend %box-radius; + width: $slider-width; + bottom: 0; + background: $c-slider; +} +.ui-widget-content { + @extend %box-radius; + background: c-dimmer($c-slider, 70%); +} +.ui-slider-handle { + background: $c-slider; + position: absolute; + z-index: 2; + width: 23px; + height: 23px; + cursor:pointer; + margin: 0 0 -10px -5.5px; + border-radius: 50%; + &:hover, + &:active, + &:focus { + box-shadow: 0 0 0 9px fade-out($c-slider, .85); + outline: 0; + } +} +.ui-slider .ui-slider-range { + position: absolute; + // z-index: 1; + font-size: .7em; + display: block; + border: 0; + background-position: 0 0; +} +.ui-slider-horizontal { + height: $slider-width; +} +.ui-slider-horizontal .ui-slider-handle { + top: -5.5px; + margin-left: -9px; +} +.ui-slider-horizontal .ui-slider-range { + top: 0; + height: 100%; +} +.ui-slider-horizontal .ui-slider-range-min { + left: 0; +} +.ui-slider-horizontal .ui-slider-range-max { + right: 0; +} diff --git a/ui/common/css/header/_buttons.scss b/ui/common/css/header/_buttons.scss new file mode 100644 index 0000000000..a9c547caa2 --- /dev/null +++ b/ui/common/css/header/_buttons.scss @@ -0,0 +1,79 @@ +%top-icon { + display: block; + height: $site-header-height; + line-height: $site-header-height; +} + +.site-buttons { + @extend %flex-center-nowrap; + + .link { + @extend %top-icon; + /* we don't want a lighter dark font in the top gradient */ + @if $theme == 'transp' { + @extend %page-text; + } @else { + color: $c-font; + } + font-size: 1.1rem; + padding: 0 .7rem; + &:hover { + color: $c-font-clearer; + } + span::before { + vertical-align: middle; + } + } + .toggle { + @extend %top-icon; + } + .initiating { + @extend %flex-center; + justify-content: center; + height: 300px; + width: 225px; + } + .dropdown { + @extend %dropdown-shadow; + display: none; + position: absolute; + right: 0; + top: var(--dropdown-top); + background: $c-bg-header-dropdown; + z-index: z('dropdown'); + a, + button { + color: $c-header-dropdown; + } + } + .shown { + .toggle { + background: $c-bg-header-dropdown; + color: $c-header-dropdown; + } + .dropdown { + display: block; + } + } + .signin { + margin: 0 1rem; + @if $theme == 'transp' { + &.button-empty { + @extend %metal; + color: $c-font-clear; + } + } + } + .link-center { + margin-top: 5px; + height: inherit; + line-height: inherit; + } +} +#user_tag { + padding-right: 1rem; + white-space: nowrap; +} +#notify-app .initiating { + width: 25rem; +} diff --git a/ui/common/css/header/_header.scss b/ui/common/css/header/_header.scss new file mode 100644 index 0000000000..e8d5561645 --- /dev/null +++ b/ui/common/css/header/_header.scss @@ -0,0 +1,22 @@ +@import 'topnav-hidden'; +@import 'topnav-visible'; +@import 'title'; +@import 'buttons'; + +#top { + height: $site-header-height; + display: flex; + justify-content: space-between; + position: relative; + z-index: z('site-header'); + + --dropdown-top: 40px; + @include breakpoint($mq-site-header-tall) { + --dropdown-top: 60px; + } +} + +.site-title-nav { + display: flex; + justify-content: flex-start; +} diff --git a/ui/common/css/header/_title.scss b/ui/common/css/header/_title.scss new file mode 100644 index 0000000000..bc529bdfae --- /dev/null +++ b/ui/common/css/header/_title.scss @@ -0,0 +1,43 @@ +.site-title { + @extend %base-font; + font-size: 25px; + line-height: #{$site-header-short-height - 3}; + text-shadow: $text-shadow; + white-space: nowrap; + margin: 0 .5rem; + display: none; + @include breakpoint($mq-xx-small) { + display: block; + } + @include breakpoint($mq-topnav-hidden) { + /* move away from hamburger */ + margin-left: calc(.5rem + #{$site-header-height}); + } + @include breakpoint($mq-site-header-tall) { + font-size: 30px; + line-height: #{$site-header-tall-height - 3}; + } + @include breakpoint($mq-topnav-visible $mq-site-header-tall) { + line-height: #{$site-header-tall-height - 5}; + margin: 0 1rem; + } + a { + color: $c-font; + text-decoration: none; + &:hover { + color: $c-primary; + span { + color: $c-primary-dim; + } + } + } + span { + color: $c-font-dim; + } + + .kiddo { + color: $c-font-dimmer; + font-weight: bold; + margin-right: .5em; + } +} diff --git a/ui/common/css/header/_topnav-hidden.scss b/ui/common/css/header/_topnav-hidden.scss new file mode 100644 index 0000000000..e596bf3dd0 --- /dev/null +++ b/ui/common/css/header/_topnav-hidden.scss @@ -0,0 +1,154 @@ +@include breakpoint($mq-topnav-hidden) { + + .topnav-toggle { + display: block; + position: absolute; + top: -9999px; + left: -9999px; + } + + .hbg { + position: absolute; + top: 0; + left: 0; + width: $site-header-height; + height: $site-header-height; + cursor: pointer; + z-index: z('topnav'); + + &__in { + &, + &::after, + &::before { + display: block; + margin-top: -1.5px; + position: absolute; + width: 23px; + height: 2px; + border-radius: 3px; + background-color: $c-font-dim; + @include breakpoint($mq-site-header-tall) { + width: 34px; + height: 3px; + } + } + top: 50%; + left: 8.5px; + @include breakpoint($mq-site-header-tall) { + left: 13px; + } + transition: transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19); + &::after, + &::before { + content: ""; + } + &::before { + top: -6px; + @include breakpoint($mq-site-header-tall) { + top: -9px; + } + transition: top 0.1s 0.25s ease-in, + opacity 0.1s ease-in; + } + &::after { + bottom: -7px; + @include breakpoint($mq-site-header-tall) { + bottom: -10px; + } + transition: bottom 0.1s 0.25s ease-in, + transform 0.22s cubic-bezier(0.55, 0.055, 0.675, 0.19); + } + } + .topnav-toggle:checked ~ & { + position: fixed; + background: $c-bg-high; + .hbg__in { + transform: rotate(225deg); + transition-delay: 0.12s; + transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); + &::before { + top: 0; + opacity: 0; + transition: top 0.1s ease-out, + opacity 0.1s 0.12s ease-out; + } + &::after { + bottom: 0; + transform: rotate(-90deg); + transition: bottom 0.1s ease-out, + transform 0.22s 0.12s cubic-bezier(0.215, 0.61, 0.355, 1); + } + } + } + } + + #topnav { + display: flex; + flex-flow: row wrap; + position: fixed; + top: $site-header-height; + bottom: 0; + left: 0; + background: $c-bg-high; + transform: translateX(calc(-100% - 10px)); + @include transition(transform, 200ms); + padding-bottom: 1.2rem; + overflow-y: auto; + overscroll-behavior: contain; + box-shadow: 2px 5px 7px hsla(0, 0, 0%, 0.5); + border-radius: 0 3px 0 0; + max-width: 80%; + @include breakpoint($mq-xx-small) { + max-width: 70%; + } + z-index: z('topnav'); + + a { + color: $c-font; + text-decoration: none; + padding: .7em 0; + opacity: 0; + @include transition(opacity); + } + + section { + flex: 1 0 50%; + margin-top: 1rem; + > a { + font-size: 1.2em; + padding-left: 1.2rem; + font-weight: bold; + display: block; + } + .play { display: none } + div { + display: flex; + flex-flow: column; + a { + padding-left: 2.4rem; + } + } + a:active { + background: $c-primary; + color: $c-primary-over; + } + } + + .topnav-toggle:checked ~ & { + transform: translateX(0); + a { + opacity: 1; + transition: opacity 125ms ease-in-out 125ms; + } + } + } + + body.masked { + /* prevent scrolling while topnav is open */ + overflow: hidden; + /* awkwardly make up for the disappearance of the scroll bar */ + /* actually don't, since on mobile devices the scrool bar + * has no width, and that menu is mainly for mobile. */ + // padding-right: 15px; +} +} diff --git a/ui/common/css/header/_topnav-visible.scss b/ui/common/css/header/_topnav-visible.scss new file mode 100644 index 0000000000..fc15eee6bb --- /dev/null +++ b/ui/common/css/header/_topnav-visible.scss @@ -0,0 +1,79 @@ +@include breakpoint($mq-topnav-visible) { + + .hamburger, + .topnav-mask, + .topnav-toggle { + display: none; + } + + #topnav { + --nav-section: 26px; + --nav-section-hover: 35px; + @include breakpoint($mq-site-header-tall) { + --nav-section: 48px; + --nav-section-hover: 53px; + } + display: flex; + section { + position: relative; + height: var(--nav-section); + > a { + color: $c-font-page; + text-shadow: $text-shadow; + display: block; + height: var(--nav-section); + line-height: $site-header-height; + padding: 0 0.7rem; + text-transform: uppercase; + border-left: 2px solid transparent; + @media (hover: none) { + pointer-events: none; + } + } + .home { display: none } + } + div { + visibility: hidden; + max-height: inherit; + position: absolute; + left: 0; + background: $c-bg-header-dropdown; + min-width: 10rem; + box-shadow: 2px 5px 6px rgba(0, 0, 0, 0.3); + border-radius: 0 3px 3px 3px; + border-left: 2px solid $c-primary; + a { + display: block; + padding: .6rem .7rem; + color: $c-header-dropdown; + &:hover { + background: $c-primary; + color: $c-primary-over; + } + &:first-child { + border-radius: 0 3px 0 0; + } + &:last-child { + border-radius: 0 0 3px 1px ; + } + } + } + &.blind div { + display: block; + margin-left: -9000px; + } + &.hover section:hover, + section:active { + > a { + height: var(--nav-section-hover); + background: $c-bg-header-dropdown; + color: $c-header-dropdown; + border-color: $c-primary; + } + div { + visibility: visible; + max-height: auto; + } + } + } +} diff --git a/ui/common/css/layout/_base.scss b/ui/common/css/layout/_base.scss new file mode 100644 index 0000000000..fdb05998d6 --- /dev/null +++ b/ui/common/css/layout/_base.scss @@ -0,0 +1,78 @@ +$vp-min-width: 320px; +$vp-max-width: 1200px; + +body { + --site-header-height: #{$site-header-short-height}; + @include breakpoint($mq-site-header-tall) { + --site-header-height: #{$site-header-tall-height}; + } + + --site-header-margin: 0px; + &.header-margin { + --site-header-margin: 1em; + } + + --main-margin: 0; + @include breakpoint($mq-main-margin) { + --main-margin: 1vw; + margin-bottom: $block-gap; + } + + /* Feature detection for JS to read */ + @media (hover: hover) { --hoverable: 1; } + @supports (display: grid) { --grid: 1; } +} + +#main-wrap { + display: grid; + grid-template-areas: '. . main . .'; + + --main-max-width: #{$main-max-width}; + grid-template-columns: $main-margin 1fr minmax(auto, var(--main-max-width)) 1fr $main-margin; + + &.full-screen { + --main-max-width: auto; + } + &.full-screen-force { + --main-max-width: 100%; + } + + margin-top: $site-header-margin; + + @media (hover: none) { + body.clinput & { + display: none; + } + } +} + +@if $debug { + #main-wrap::before { + position: absolute; + z-index: 9999; + background: $c-accent; + color: #fff; + font-weight: bold; + padding: 1em; + content: 'COL 1'; + @include breakpoint($mq-col2-uniboard) { + content: 'COL 2'; + } + @include breakpoint($mq-col2-uniboard-squeeze) { + content: 'COL 2 squeezed'; + } + @include breakpoint($mq-col3-uniboard) { + content: 'COL 3'; + } + } +} + +main { + grid-area: main; + + &.page-small { + max-width: 1000px; + margin: auto; + width: 100%; + } +} diff --git a/ui/common/css/layout/_page-menu.scss b/ui/common/css/layout/_page-menu.scss new file mode 100644 index 0000000000..e6954c2160 --- /dev/null +++ b/ui/common/css/layout/_page-menu.scss @@ -0,0 +1,35 @@ +@import '../component/subnav'; + +.page-menu { + + display: grid; + grid-template-areas: + 'menu' + 'content'; + + @include breakpoint($mq-subnav-side) { + grid-template-columns: max-content auto; + grid-template-rows: min-content; + grid-template-areas: + 'menu content'; + } + + &.page-small { + max-width: 1000px; + margin: inherit; + } + + &__menu { + grid-area: menu; + } + &__content { + grid-area: content; + height: 100%; + // overflow: hidden; /* fixes crazy text overflow on Fx */ + } + + &__content.box { + /* ensure the content is as high as the menu */ + min-height: 100%; + } +} diff --git a/ui/common/css/layout/_uniboard.scss b/ui/common/css/layout/_uniboard.scss new file mode 100644 index 0000000000..311902ffdf --- /dev/null +++ b/ui/common/css/layout/_uniboard.scss @@ -0,0 +1,13 @@ +body { + --board-scale: 1; + @include breakpoint($mq-zoom-enabled) { + // --zoom: 80; defined in the HTML, loaded from server + --board-scale: calc((var(--zoom) / 100) * 0.7 + 0.3); + } +} + +@include breakpoint($mq-col1-uniboard) { + .main-board .cg-board { + border-radius: 0; + } +} diff --git a/ui/common/css/theme/_dark.scss b/ui/common/css/theme/_dark.scss new file mode 100644 index 0000000000..5fee6af5fb --- /dev/null +++ b/ui/common/css/theme/_dark.scss @@ -0,0 +1,100 @@ +@import 'default'; + +$theme: 'dark'; +$theme-light: false; +$theme-dark: true; + +@function c-dimmer($color, $weight: 20%) { + @return mix(#000, $color, $weight); +} +@function c-clearer($color, $weight: 20%) { + @return mix(#fff, $color, $weight); +} + +$c-bg-page: hsl($c-site-hue, 10%, 8%); +$c-bg-high: hsl($c-site-hue, 5%, 14%); +$c-bg-low: hsl($c-site-hue, 7%, 22%); + +/* even rows in list or tables, subtle shade of $c-bg-high */ +$c-bg-zebra: hsl($c-site-hue, 5%, 18%); +$c-bg-zebra2: hsl($c-site-hue, 5%, 23%); + +$c-body-gradient: hsl($c-site-hue, 12%, 16%); + +$c-font: hsl(0, 0%, 73%); +$c-font-dim: c-light($c-font, 60%); +$c-font-dimmer: c-light($c-font, 42%); +$c-font-clear: c-light($c-font, 80%); +$c-font-clearer: c-light($c-font, 89%); +$c-shade: c-light($c-font, 30%); +$c-font-page: $c-font-dim; + +/* Primary: blue */ +$c-primary: hsl(209, 79%, 56%); +$c-primary-dim: c-dimmer($c-primary, 15%); +$c-primary-clear: c-clearer($c-primary); + +/* Secondary: green */ +$c-secondary: hsl(88, 62%, 37%); +$c-secondary-dim: c-dimmer($c-secondary); + +/* Brag: gold */ +$c-brag: hsl(37, 74%, 43%); + +/* Fancy: pink */ +$c-fancy: hsl(294, 62%, 48%); + +/* Good: green */ +$c-good: $c-secondary; +$c-good-over: $c-secondary-over; + +/* Warn: orange */ +$c-warn: $c-brag; +$c-warn-over: $c-brag-over; + +/* Bad: red */ +$c-bad: $c-error; +$c-bad-over: $c-error-over; + +$c-link: $c-primary; +$c-link-dim: $c-primary-dim; +$c-link-clear: $c-primary-clear; +$c-link-hover: c-clearer(saturate($c-primary, 100%), 25%); + +$c-bg-box: $c-bg-high; +$c-bg-box-opaque: $c-bg-box; +$c-bg-input: c-light($c-bg-page, 13%); + +$c-bg-popup: $c-bg-low; +$c-popup: $c-font-clear; + +$c-bg-header-dropdown: $c-bg-popup; +$c-header-dropdown: $c-popup; + +$c-bot: $c-fancy; + +$c-page-input: $c-bg-box; + +$c-border: hsl(0, 0%, 25%); +$c-border-page: hsl(0, 0%, 22%); +$border: $border-width $border-style $c-border; + +$c-font-shadow: black; +$text-shadow: none; + +@mixin metal { + background: linear-gradient(to bottom, hsl($c-site-hue, 7%, 22), hsl($c-site-hue, 5%, 19) 100%); +} +@mixin metal-hover { + background: linear-gradient(to bottom, hsl($c-site-hue, 7%, 25), hsl($c-site-hue, 5%, 22) 100%); + color: $c-font-clear; +} + +@mixin page-metal { + @include metal; +} +@mixin page-metal-hover { + @include metal-hover; +} + +@mixin theme-style { } diff --git a/ui/common/css/theme/_default.scss b/ui/common/css/theme/_default.scss new file mode 100644 index 0000000000..8028f6abb8 --- /dev/null +++ b/ui/common/css/theme/_default.scss @@ -0,0 +1,108 @@ +@import '../abstract/functions'; + +/* Colors */ + +@function c-dimmer($color, $weight: 17%) { + @return mix(#fff, $color, $weight); +} +@function c-clearer($color, $weight: 17%) { + @return mix(#000, $color, $weight); +} + +$c-site-hue: 37; + +$c-bg-page: hsl($c-site-hue, 10%, 92%); // hsl(210, 17%, 95%) +$c-bg-high: hsl(0, 0%, 100%); +$c-bg-low: hsl(0, 0%, 89%); + +/* even rows in list or tables, subtle shade of $c-bg-high */ +$c-bg-zebra: hsl($c-site-hue, 12%, 96.5%); +$c-bg-zebra2: hsl($c-site-hue, 12%, 92%); + +$c-body-gradient: hsl($c-site-hue, 12%, 84%); + +$c-font: hsl(0, 0%, 30%); +$c-font-dim: c-light($c-font, 47%); +$c-font-dimmer: c-light($c-font, 70%); +$c-font-clear: c-light($c-font, 12%); +$c-font-clearer: c-light($c-font, 0%); +$c-shade: c-dimmer($c-font, 80%); +$c-font-page: c-light($c-font, 37%); + +/* Primary: blue */ +$c-primary: hsl(209, 79%, 53%); +$c-primary-dim: c-dimmer($c-primary); +$c-primary-clear: c-clearer($c-primary); +$c-primary-over: #fff; /* text over primary background */ + +/* Secondary: green */ +$c-secondary: hsl(88, 62%, 37%); +$c-secondary-dim: c-dimmer($c-secondary); +$c-secondary-over: #fff; /* text over secondary background */ + +/* Accent: orange */ +$c-accent: hsl(22, 100%, 42%); +$c-accent-over: #fff; /* text over accent background */ + +/* Brag: gold */ +$c-brag: hsl(37, 74%, 48%); +$c-brag-over: #fff; /* text over brag background */ + +/* Error: red */ +$c-red: hsl(0, 60%, 50%); +$c-error: $c-red; +$c-error-over: #fff; /* text over brag background */ + +/* Good: green */ +$c-good: $c-secondary; +$c-good-over: $c-secondary-over; + +/* Warn: orange */ +$c-warn: $c-brag; +$c-warn-over: $c-brag-over; + +/* Bad: red */ +$c-bad: $c-error; +$c-bad-over: $c-error-over; + +/* Fancy: pink */ +$c-fancy: hsl(294, 61%, 62%); +$c-fancy-over: white; /* text over brag background */ + +$c-link: $c-primary; +$c-link-dim: $c-primary-dim; +$c-link-clear: $c-primary-clear; +$c-link-hover: c-clearer(saturate($c-primary, 100%), 35%); + +$c-bg-box: $c-bg-high; +$c-bg-box-opaque: $c-bg-box; +$c-bg-input: c-light($c-bg-page, 98%); + +$c-border: hsl(0, 0%, 85%); +$c-border-page: hsl(0, 0%, 80%); + +$c-page-mask: hsla(0, 0, 0%, 0.6); + +$c-bg-popup: $c-bg-high; +$c-popup: $c-font; + +$c-bg-header-dropdown: $c-bg-popup; +$c-header-dropdown: $c-popup; + +$c-font-shadow: white; +$text-shadow: 0 1px 0 $c-font-shadow; + +$c-bot: $c-fancy; + +$c-page-input: $c-bg-low; + +/* Borders */ + +$border-width: 1px; +$border-style: solid; +$border: $border-width $border-style $c-border; + +/* Shadows */ + +$box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.2), 0 1px 5px 0 rgba(0,0,0,.12); +// $box-shadow: 0 2px 2px 0 rgba(0,0,0,.157); diff --git a/ui/common/css/theme/_light.scss b/ui/common/css/theme/_light.scss new file mode 100644 index 0000000000..b8b418572e --- /dev/null +++ b/ui/common/css/theme/_light.scss @@ -0,0 +1,25 @@ +@import 'default'; + +$theme: 'light'; +$theme-light: true; +$theme-dark: false; + +@mixin metal { + background: linear-gradient(to bottom, hsl(0, 0, 96) 0%, hsl(0, 0, 93) 100%); + text-shadow: $text-shadow; +} +@mixin metal-hover { + background: linear-gradient(to bottom, hsl(0, 0, 98) 0%, hsl(0, 0, 95) 100%); + text-shadow: $text-shadow; +} + +@mixin page-metal { + background: linear-gradient(to bottom, mix($c-link, hsl(0, 0%, 100%), 20%) 0%, mix($c-link, hsl(0, 0%, 94%), 20%) 100%); + text-shadow: $text-shadow; +} +@mixin page-metal-hover { + background: linear-gradient(to bottom, mix($c-link, #fff, 25%) 0%, mix($c-link, c-light($c-bg-page, 90%), 25%) 100%); + text-shadow: $text-shadow; +} + +@mixin theme-style { } diff --git a/ui/common/css/theme/_transp.scss b/ui/common/css/theme/_transp.scss new file mode 100644 index 0000000000..4f2eb86b6b --- /dev/null +++ b/ui/common/css/theme/_transp.scss @@ -0,0 +1,64 @@ +@import 'dark'; + +$theme: 'transp'; + +$c-bg-high: hsla(0, 0%, 0%, .6); +$c-bg-low: hsla(0, 0%, 0%, .5); + +$c-font: hsl(0, 0%, 80%); +$c-font-dim: c-light($c-font, 69%); +$c-font-dimmer: c-light($c-font, 48%); +$c-font-clear: c-light($c-font, 89%); +$c-font-clearer: c-light($c-font, 97%); +$c-font-page: $c-font-clearer; + +$c-bg-box: $c-bg-high; +$c-bg-zebra: hsla(0, 0%, 100%, .05); +$c-bg-input: $c-bg-zebra; + +$c-bg-popup: $c-bg-high; + +$c-bg-header-dropdown: hsla(0, 0%, 0%, .75); + +$c-page-input: $c-bg-box; + +$text-shadow: .5px 1px 1px #000; + +%page-text-shadow { + text-shadow: $text-shadow; +} +%page-link-font { + color: $c-font-clearer; +} + +@mixin metal { + background: linear-gradient(to bottom, hsla(0, 0, 0, .4), hsla(0, 0, 0, .5) 100%); +} +@mixin metal-hover { + background: linear-gradient(to bottom, hsla(0, 0, 0, .45), hsla(0, 0, 0, .55) 100%); +} + +@mixin page-metal { + @include metal; +} +@mixin page-metal-hover { + @include metal-hover; +} + +@mixin theme-style { + body.transp { + &::before { + content: ' '; + position: fixed; + width: 100%; + height: 100%; + top: 0; + left: 0; + background-position: center center; + background-repeat: no-repeat; + background-size: cover; + will-change: transform; + z-index: -1; + } + } +} diff --git a/ui/common/css/vendor/_autocomplete.scss b/ui/common/css/vendor/_autocomplete.scss new file mode 100644 index 0000000000..f5cd183730 --- /dev/null +++ b/ui/common/css/vendor/_autocomplete.scss @@ -0,0 +1,28 @@ +.tt-menu { + @extend %box-radius, %popup-shadow; + width: 14em; + background-color: $c-bg-box; +} +.tt-menu .empty { + padding: .5em 0 .5em 1em; +} +.tt-menu .spinner { + margin: 10px auto; + width: 20px; + height: 20px; +} +.tt-suggestion { + color: $c-font; + padding: .4em 0 .4em .4em; + display: block; + cursor: pointer; + @include transition(); + &.tt-cursor, + &:hover { + color: $c-font-clear !important; + background: mix($c-link, $c-bg-box, 20%); + } +} +.tt-hint { + color: $c-font-dimmer; +} diff --git a/public/stylesheets/flatpickr.css b/ui/common/css/vendor/_flatpickr.scss similarity index 100% rename from public/stylesheets/flatpickr.css rename to ui/common/css/vendor/_flatpickr.scss diff --git a/ui/common/css/vendor/_multiple-select.scss b/ui/common/css/vendor/_multiple-select.scss new file mode 100644 index 0000000000..76f6a99412 --- /dev/null +++ b/ui/common/css/vendor/_multiple-select.scss @@ -0,0 +1,152 @@ +.ms-parent { + display: inline-block; + position: relative; + vertical-align: middle; +} + +.ms-choice { + display: block; + width: 100%; + height: 26px; + padding: 0; + overflow: hidden; + cursor: pointer; + border: $border; + text-align: left; + white-space: nowrap; + line-height: 26px; + text-decoration: none; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; + background-color: $c-bg-box; +} + +.ms-choice.disabled { + background-color: $c-shade; + background-image: none; + cursor: default; +} + +.ms-choice > span { + position: absolute; + top: 0; + left: 0; + right: 20px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: block; + padding-left: 8px; +} + +.ms-choice > div { + position: absolute; + top: 0; + right: 0; + width: 20px; + height: 25px; + background: url('../vendor/multiple-select/multiple-select.png') left top no-repeat; +} + +.ms-choice > div.open { + background: url('../vendor/multiple-select/multiple-select.png') right top no-repeat; +} + +.ms-drop { + @extend %box-neat-force; + width: 100%; + display: none; + margin-top: -1px; + padding: 0; + position: absolute; + z-index: 1000; + background: $c-bg-box; + border: $border; +} + +.ms-drop.bottom { + top: 100%; + box-shadow: 0 4px 5px rgba(0, 0, 0, .15); +} + +.ms-drop.top { + bottom: 100%; + box-shadow: 0 -4px 5px rgba(0, 0, 0, .15); +} + +.ms-search { + display: inline-block; + margin: 0; + min-height: 26px; + padding: 4px; + position: relative; + white-space: nowrap; + width: 100%; + z-index: 10000; +} + +.ms-search input { + width: 100%; + height: auto !important; + min-height: 24px; + padding: 0 20px 0 5px; + margin: 0; + outline: 0; + font-size: 1em; + border: $border; + border-radius: 0; + box-shadow: none; + background: img-url('../vendor/multiple-select/multiple-select.png') no-repeat 100% -22px; +} + +.ms-drop ul { + overflow: auto; + margin: 0; + padding: 5px 8px; +} + +.ms-drop ul > li { + list-style: none; + display: list-item; + background-image: none; + position: static; +} + +.ms-drop ul > li .disabled { + opacity: .35; +} + +.ms-drop ul > li.multiple { + display: block; + float: left; +} + +.ms-drop ul > li.group { + clear: both; +} + +.ms-drop ul > li.multiple label { + @extend %nowrap-hidden; + width: 100%; + display: block; + text-overflow: ellipsis; +} + +.ms-drop ul > li label { + font-weight: normal; + display: block; + white-space: nowrap; +} + +.ms-drop ul > li label.optgroup { + font-weight: bold; +} + +.ms-drop input[type="checkbox"] { + vertical-align: middle; +} + +.ms-drop .ms-no-results { + display: none; +} diff --git a/ui/common/css/vendor/chessground/_board-2d.scss b/ui/common/css/vendor/chessground/_board-2d.scss new file mode 100644 index 0000000000..7c4fc042f4 --- /dev/null +++ b/ui/common/css/vendor/chessground/_board-2d.scss @@ -0,0 +1,26 @@ +$board-image-path: "../images/board"; + +$board-files: ( +'blue': 'svg/blue.svg', +'blue2': 'blue2.jpg', +'wood2': 'wood2.jpg', +'wood3': 'wood3.jpg', +'blue3': 'blue3.jpg', +'marble': 'marble.jpg', +'brown': 'svg/brown.svg', +'green': 'svg/green.svg', +'olive': 'olive.jpg', +'purple': 'svg/purple.svg', +'grey': 'grey.jpg', +'wood': 'wood-1024.jpg', +'canvas': 'canvas2-1024.jpg', +'leather': 'leather-1024.jpg', +'metal': 'metal-1024.jpg', +'maple': 'maple.jpg', +); + +@each $color, $file in $board-files { + .#{$color} .is2d .cg-board { + background-image: url(../images/board/#{$file}); + } +} diff --git a/ui/common/css/vendor/chessground/_board-3d.scss b/ui/common/css/vendor/chessground/_board-3d.scss new file mode 100644 index 0000000000..d4d1789838 --- /dev/null +++ b/ui/common/css/vendor/chessground/_board-3d.scss @@ -0,0 +1,136 @@ +$td-outer-height-ratio: 476 / 512; +$td-outer-height-percent: $td-outer-height-ratio * 100%; +$td-inner-height-ratio: 464.5 / 512; +$td-inner-relative-percent: $td-inner-height-ratio / $td-outer-height-ratio * 100%; + +.main-board { + padding-bottom: $td-outer-height-percent; + .cg-board-wrap { + height: $td-inner-relative-percent; + coords.files { + bottom: calc(-12px - 3%); + } + coords.ranks { + height: 100%; + } + } +} + +piece { + /* original size: width: 140.625%; height: 179.6875%; */ + /* size on 3D board, with height/width = 90.78571% */ + width: 16.741%; + height: 23.563%; + left: -1.85%; + top: -9.1%; +} + +piece.dragging, #promotion_choice { + z-index: z('cg__piece.dragging.3d') !important; +} + +.is2d piece { + /* copy of board.css to override miniboards */ + left: 0; + top: 0; + width: 12.5%; + height: 12.5%; +} + +.cg-board::before { + position: absolute; + top: -0.730688%; + left: 0; + width: 100%; + height: 103.2%; + content: ''; + background-size: cover; +} +.is2d .cg-board { + /* override miniboards */ + top: 0; + height: 100%; + &::before { + content: none; + } +} + +$board-files: ( +'Black-White-Aluminium', +'Brushed-Aluminium', +'China-Blue', +'China-Green', +'China-Grey', +'China-Scarlet', +'China-Yellow', +'Classic-Blue', +'Transparent-Glass', +'Gold-Silver', +'Green-Glass', +'Light-Wood', +'Power-Coated', +'Purple-Black', +'Rosewood', +'Wood-Glass', +'Wax', +'Jade', +'Marble', +'Woodi', +); +@each $name in $board-files { + .#{$name} .cg-board::before { + background-image: img-url('staunton/board/#{$name}.png'); + } +} + +$piece-files: ( +'Staunton': false, +'Basic': true, +'Experimental': true, +'Glass': true, +'Metal': true, +'ModernJade': true, +'ModernWood': true, +'RedVBlue': true, +'Trimmed': true, +'Wood': true, +'CubesAndPi': true, +); +@each $name, $flips in $piece-files { + @each $color in ('White', 'Black') { + @each $type in ('Pawn', 'Bishop', 'Knight', 'Rook', 'Queen', 'King') { + .#{$name} .#{to-lower-case($type)}.#{to-lower-case($color)} { + background-image: img-url('staunton/piece/#{$name}/#{$color}-#{$type}.png'); + } + } + @if $flips { + @each $color, $orientation in ('White': 'black', 'Black': 'white') { + @each $type in ('Bishop', 'Knight') { + .#{$name} .main-board .orientation-#{$orientation} .#{to-lower-case($type)}.#{to-lower-case($color)} { + background-image: img-url('staunton/piece/#{$name}/#{$color}-#{$type}-Flipped.png'); + } + } + } + } + } +} + +#promotion_choice piece { + width: 140.625%; + height: 197.925%; + top: 0; + left: -18%; + transform: scale(0.7) translateY(-45%); + background-position: 0 -6px; +} + +.main-board, .eval-gauge { + margin-top: 4vh; +} + +.board-resize { + $resize-width: 20px; + @include breakpoint($mq-col2-uniboard) { + bottom: #{28px - $resize-width}!important; + } +} diff --git a/ui/common/css/vendor/chessground/_chessground.scss b/ui/common/css/vendor/chessground/_chessground.scss new file mode 100644 index 0000000000..b99489aae2 --- /dev/null +++ b/ui/common/css/vendor/chessground/_chessground.scss @@ -0,0 +1,96 @@ +@import 'board-2d'; + +.cg-board { + @extend %box-neat, %abs-100; + user-select: none; + line-height: 0; + background-size: cover; + .manipulable & { + cursor: pointer; + } +} +square { + position: absolute; + width: 12.5%; + height: 12.5%; + pointer-events: none; + &.move-dest { + background: radial-gradient(rgba(20, 85, 30, 0.5) 22%, #208530 0, rgba(0, 0, 0, 0.3) 0, rgba(0, 0, 0, 0) 0); + pointer-events: auto; + } + &.premove-dest { + background: radial-gradient(rgba(20, 30, 85, 0.5) 22%, #203085 0, rgba(0, 0, 0, 0.3) 0, rgba(0, 0, 0, 0) 0); + pointer-events: auto; + } + &.oc.move-dest { + background: radial-gradient(transparent 0%, transparent 80%, rgba(20, 85, 0, 0.3) 80%); + } + &.oc.premove-dest { + background: radial-gradient(transparent 0%, transparent 80%, rgba(20, 30, 85, 0.2) 80%); + } + &.last-move { + will-change: transform; + background-color: rgba(155, 199, 0, 0.41); + } + &.check { + background: radial-gradient(ellipse at center, rgba(255, 0, 0, 1) 0%, rgba(231, 0, 0, 1) 25%, rgba(169, 0, 0, 0) 89%, rgba(158, 0, 0, 0) 100%); + } + &.selected { + background-color: rgba(20, 85, 30, 0.5); + } + &.current-premove { + background-color: rgba(20, 30, 85, 0.5); + } + &.move-dest:hover { + background: rgba(20, 85, 30, 0.3); + } + &.premove-dest:hover { + background: rgba(20, 30, 85, 0.2); + } + &.bh1 piece { + opacity: 0.98; + } +} +piece { + position: absolute; + top: 0; + left: 0; + width: 12.5%; + height: 12.5%; + background-size: cover; + z-index: z('cg__piece'); + will-change: transform; + pointer-events: none; + &.dragging { + cursor: move; + z-index: z('cg__piece.dragging'); + } + &.anim { + z-index: z('cg__piece.anim'); + } + &.fading { + z-index: z('cg__piece.fading'); + opacity: 0.5; + } + &.ghost { + opacity: 0.3; + } +} + +.cg-board-wrap { + // overflow: hidden; /* prevents width issues with rank coords | but prevents dragging pieces in! */ + svg { + overflow: hidden; + position: absolute; + top: 0px; + left: 0px; + width: 100%; + height: 100%; + pointer-events: none; + z-index: z('cg__svg'); + opacity: 0.6; + image { + opacity: 0.5; + } + } +} diff --git a/ui/common/css/vendor/chessground/_coords-colors.scss b/ui/common/css/vendor/chessground/_coords-colors.scss new file mode 100644 index 0000000000..7f5c3212be --- /dev/null +++ b/ui/common/css/vendor/chessground/_coords-colors.scss @@ -0,0 +1,47 @@ +@mixin coords-colors { + .blue { + coord { text-shadow: none; } + .orientation-white .files coords:nth-child(2n+1), + .orientation-white .ranks coords:nth-child(2n), + .orientation-black .files coords:nth-child(2n), + .orientation-black .ranks coords:nth-child(2n+1) { + color: #DEE3E6; + } + .orientation-white .files coord:nth-child(2n), + .orientation-white .ranks coord:nth-child(2n+1), + .orientation-black .files coord:nth-child(2n+1), + .orientation-black .ranks coord:nth-child(2n) { + color: #788a94; + } + } + .brown { + coord { text-shadow: none; } + .orientation-white .files coord:nth-child(2n+1), + .orientation-white .ranks coord:nth-child(2n), + .orientation-black .files coord:nth-child(2n), + .orientation-black .ranks coord:nth-child(2n+1) { + color: #F0D9B5; + } + .orientation-white .files coord:nth-child(2n), + .orientation-white .ranks coord:nth-child(2n+1), + .orientation-black .files coord:nth-child(2n+1), + .orientation-black .ranks coord:nth-child(2n) { + color: #946f51; + } + } + .green { + coord { text-shadow: none; } + .orientation-white .files coords:nth-child(2n+1), + .orientation-white .ranks coords:nth-child(2n), + .orientation-black .files coords:nth-child(2n), + .orientation-black .ranks coords:nth-child(2n+1) { + color: #FFFFDD; + } + .orientation-white .files coord:nth-child(2n), + .orientation-white .ranks coord:nth-child(2n+1), + .orientation-black .files coord:nth-child(2n+1), + .orientation-black .ranks coord:nth-child(2n) { + color: #6d8753; + } + } +} diff --git a/ui/common/css/vendor/chessground/_coords.scss b/ui/common/css/vendor/chessground/_coords.scss new file mode 100644 index 0000000000..a240834839 --- /dev/null +++ b/ui/common/css/vendor/chessground/_coords.scss @@ -0,0 +1,85 @@ +@import 'coords-colors'; + +coords { + + /* handle hidden coords */ + .coords-no & { display: none } + + /* handle inner coords */ + position: absolute; + display: flex; + pointer-events: none; + @include fluid-size('font-size', 8px, 12px); + user-select: none; + color: #fff; + text-shadow: 0 1px 2px #000; + font-weight: bold; + + &.ranks { + flex-flow: column-reverse; + top: 1px; + right: 0; // a negative value creates empty space on the right side in mobile browsers + height: 100%; + width: .8em; + &.black { + flex-flow: column; + } + } + + &.files { + bottom: 0px; + left: 0; + text-align: left; + flex-flow: row; + width: 100%; + height: 1.4em; + text-transform: uppercase; + &.black { + flex-flow: row-reverse; + } + coord { + padding-left: 4px; + } + } + + coord { + flex: 1 1 auto; + } + + /* negate inner coords colors */ + .is3d .cg-board-wrap coords coord { + color: #fff!important; + text-shadow: 0 1px 2px #000!important; + } + .is3d .cg-board-wrap coords.files { + bottom: calc(1px - 2.5%); + coord { + padding-left: 3px; + } + } +} + +@include coords-colors; + +/* handle outer coords */ +@include breakpoint($mq-col2-uniboard) { + .coords-out coords { + text-shadow: none; + &.ranks { + right: -15px; + top: 0; + width: 12px; + coord { + transform: translateY(42%); + } + } + &.files { + bottom: -15px; + left: 0; + text-align: center; + } + coord { + color: $c-font-page !important; + } + } +} diff --git a/ui/common/src/menuHover.ts b/ui/common/src/menuHover.ts new file mode 100644 index 0000000000..3c1c64c2b7 --- /dev/null +++ b/ui/common/src/menuHover.ts @@ -0,0 +1,91 @@ +/* Based on: */ +/*! + * hoverIntent v1.10.0 // 2019.02.25 // jQuery v1.7.0+ + * http://briancherne.github.io/jquery-hoverIntent/ + * + * You may use hoverIntent under the terms of the MIT license. Basically that + * means you are free to use hoverIntent as long as this header is left intact. + * Copyright 2007-2019 Brian Cherne + */ + +type State = any; + +export const menuHover = () => window.lichess.raf(function() { + + if (window.lichess.hasTouchEvents) return; + + let interval: number = 100; + let sensitivity: number = 10; + + // current X and Y position of mouse, updated during mousemove tracking (shared across instances) + let cX: number, cY: number; + + // saves the current pointer position coordinates based on the given mousemove event + let track = function(ev: JQueryEventObject) { + cX = ev.pageX; + cY = ev.pageY; + }; + + // state properties: + // timeoutId = timeout ID, reused for tracking mouse position and delaying "out" handler + // isActive = plugin state, true after `over` is called just until `out` is called + // pX, pY = previously-measured pointer coordinates, updated at each polling interval + // event = string representing the namespaced event used for mouse tracking + let state: State = {}; + + $('#topnav.hover').each(function(this: HTMLElement) { + + const $el = $(this).removeClass('hover'), + handler = () => $(this).toggleClass('hover'); + + // compares current and previous mouse positions + const compare = function() { + // compare mouse positions to see if pointer has slowed enough to trigger `over` function + if ( Math.sqrt( (state.pX-cX)*(state.pX-cX) + (state.pY-cY)*(state.pY-cY) ) < sensitivity ) { + $el.off(state.event, track); + delete state.timeoutId; + // set hoverIntent state as active for this element (permits `out` handler to trigger) + state.isActive = true; + handler(); + } else { + // set previous coordinates for next comparison + state.pX = cX; state.pY = cY; + // use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs) + state.timeoutId = setTimeout(compare, interval ); + } + }; + + // A private function for handling mouse 'hovering' + var handleHover = function(ev: JQueryEventObject) { + + // clear any existing timeout + if (state.timeoutId) { state.timeoutId = clearTimeout(state.timeoutId); } + + // namespaced event used to register and unregister mousemove tracking + var mousemove = state.event = 'mousemove.hoverIntent'; + + // handle the event, based on its type + if (ev.type === 'mouseenter') { + // do nothing if already active or a button is pressed (dragging a piece) + if (state.isActive || ev.which) return; + // set "previous" X and Y position based on initial entry point + state.pX = ev.pageX; state.pY = ev.pageY; + // update "current" X and Y position based on mousemove + $el.off(mousemove,track).on(mousemove,track); + // start polling interval (self-calling timeout) to compare mouse coordinates over time + state.timeoutId = setTimeout(compare, interval ); + } else { // "mouseleave" + // do nothing if not already active + if (!state.isActive) return; + // unbind expensive mousemove event + $el.off(mousemove,track); + // if hoverIntent state is true, then call the mouseOut function after the specified delay + state = {}; + handler(); + } + }; + + // listen for mouseenter and mouseleave + $el.on({'mouseenter.hoverIntent':handleHover,'mouseleave.hoverIntent':handleHover}); + }); +}); diff --git a/ui/common/src/notification.ts b/ui/common/src/notification.ts new file mode 100644 index 0000000000..11268f0897 --- /dev/null +++ b/ui/common/src/notification.ts @@ -0,0 +1,38 @@ +let notifications: Array = []; +let listening = false; + +function listenToFocus() { + if (!listening) { + listening = true; + window.addEventListener('focus', () => { + notifications.forEach(n => n.close()); + notifications = []; + }); + } +} + +function notify(msg: string | (() => string)) { + const storage = window.lichess.storage.make('just-notified'); + if (document.hasFocus() || Date.now() - parseInt(storage.get()!, 10) < 1000) return; + storage.set('' + Date.now()); + if ($.isFunction(msg)) msg = msg(); + const notification = new Notification('lichess.org', { + icon: '//lichess1.org/assets/images/logo.256.png', + body: msg + }); + notification.onclick = () => window.focus(); + notifications.push(notification); + listenToFocus(); +} + +export default function(msg: string | (() => string)) { + if (document.hasFocus() || !('Notification' in window)) return; + if (Notification.permission === 'granted') { + // increase chances that the first tab can put a local storage lock + setTimeout(notify, 10 + Math.random() * 500, msg); + } else if (Notification.permission !== 'denied') { + Notification.requestPermission(function(p) { + if (p === 'granted') notify(msg); + }); + }; +} diff --git a/ui/common/src/resize.ts b/ui/common/src/resize.ts new file mode 100644 index 0000000000..d74fd9ae7a --- /dev/null +++ b/ui/common/src/resize.ts @@ -0,0 +1,64 @@ +export type MouchEvent = MouseEvent & TouchEvent; + +export default function resizeHandle(el: HTMLElement) { + + const mousemoveEvent = window.lichess.hasTouchEvents ? 'touchmove' : 'mousemove'; + const mouseupEvent = window.lichess.hasTouchEvents ? 'touchend' : 'mouseup'; + + el.addEventListener(window.lichess.mousedownEvent, (start: MouchEvent) => { + + start.preventDefault(); + + const startPos = eventPosition(start)!; + const initialZoom = parseInt(getComputedStyle(document.body).getPropertyValue('--zoom')); + let zoom = initialZoom; + + const saveZoom = window.lichess.debounce(() => { + $.ajax({ method: 'post', url: '/pref/zoom?v=' + (100 + zoom) }); + }, 1000); + + const resize = (move: MouchEvent) => { + + const pos = eventPosition(move)!; + const delta = pos[0] - startPos[0] + pos[1] - startPos[1]; + + zoom = Math.round(Math.min(100, Math.max(0, initialZoom + delta / 10))); + + document.body.setAttribute('style', '--zoom:' + zoom); + window.lichess.dispatchEvent(window, 'resize'); + + saveZoom(); + }; + + document.body.classList.add('resizing'); + + document.addEventListener(mousemoveEvent, resize); + + document.addEventListener(mouseupEvent, () => { + document.removeEventListener(mousemoveEvent, resize); + document.body.classList.remove('resizing'); + }, { once: true }); + }); + + addNag(el); +} + +function eventPosition(e: MouchEvent): [number, number] | undefined { + if (e.clientX || e.clientX === 0) return [e.clientX, e.clientY]; + if (e.touches && e.targetTouches[0]) return [e.targetTouches[0].clientX, e.targetTouches[0].clientY]; + return undefined; +} + +function addNag(el: HTMLElement) { + + const storage = window.lichess.storage.makeBoolean('resize-nag'); + if (storage.get()) return; + + window.lichess.loadCssPath('nag-circle'); + el.title = 'Drag to resize'; + el.innerHTML = '
    '; + el.addEventListener(window.lichess.mousedownEvent, () => { + storage.set(true); + el.innerHTML = ''; + }, { once: true }); +} diff --git a/ui/common/src/storage.ts b/ui/common/src/storage.ts index 18404b33c0..5ae08eb487 100644 --- a/ui/common/src/storage.ts +++ b/ui/common/src/storage.ts @@ -41,7 +41,7 @@ export function storedJsonProp(key: string, defaultValue: T): StoredJsonProp< storage.set(key, JSON.stringify(v)); return v; } - const ret = JSON.parse(storage.get(key)); + const ret = JSON.parse(storage.get(key)!); return (ret !== null) ? ret : defaultValue; }; } diff --git a/ui/common/tsconfig.json b/ui/common/tsconfig.json index 0a39027d81..cf26d4969d 100644 --- a/ui/common/tsconfig.json +++ b/ui/common/tsconfig.json @@ -12,7 +12,9 @@ "noImplicitReturns": true, "noImplicitThis": true, "noUnusedParameters": true, - "target": "es5", - "lib": ["DOM", "ES5"] + "moduleResolution": "node", + "moduleResolution": "node", + "target": "ES5", + "lib": ["DOM", "ES5", "es2015.core", "es2015.Promise"] } } diff --git a/ui/dasher/css/_board.scss b/ui/dasher/css/_board.scss new file mode 100644 index 0000000000..662742c142 --- /dev/null +++ b/ui/dasher/css/_board.scss @@ -0,0 +1,114 @@ +#dasher_app .theme { + .list { + @extend %flex-wrap; + margin: 5px 0; + } + .list a { + flex: 0 0 50%; + height: 44px; + @extend %flex-center; + justify-content: center; + } + .list span { + display: block; + width: 64px; + height: 32px; + } + &.d3 .list span { + width: 66px; + height: 30px; + @include transition(transform); + } + .list a:hover { + filter: brightness(1.05); + } + .list a:hover span { + transform: scale(1.05); + } + .list a.active { + background-color: $c-shade; + } + &.d2 { + .blue { + background-image: url(../images/board/svg/blue.svg); + background-size: 256px; + } + .blue2 { + background-image: url(../images/board/blue2.thumbnail.jpg); + } + .wood2 { + background-image: url(../images/board/wood2.thumbnail.jpg); + } + .wood3 { + background-image: url(../images/board/wood3.thumbnail.jpg); + } + .blue3 { + background-image: url(../images/board/blue3.thumbnail.jpg); + } + .marble { + background-image: url(../images/board/marble.thumbnail.jpg); + } + .brown { + background-image: url(../images/board/svg/brown.svg); + background-size: 256px; + } + .green { + background-image: url(../images/board/svg/green.svg); + background-size: 256px; + } + .olive { + background-image: url(../images/board/olive.thumbnail.jpg); + } + .purple { + background-image: url(../images/board/svg/purple.svg); + background-size: 256px; + } + .grey { + background-image: url(../images/board/grey.thumbnail.jpg); + } + .wood { + background-image: url(../images/board/wood.thumbnail.jpg); + } + .canvas { + background-image: url(../images/board/canvas2.thumbnail.jpg); + } + .leather { + background-image: url(../images/board/leather.thumbnail.jpg); + } + .metal { + background-image: url(../images/board/metal.thumbnail.jpg); + } + .maple { + background-image: url(../images/board/maple.thumbnail.jpg); + } + } + &.d3 { + $board-files: ( + 'Black-White-Aluminium', + 'Brushed-Aluminium', + 'China-Blue', + 'China-Green', + 'China-Grey', + 'China-Scarlet', + 'China-Yellow', + 'Classic-Blue', + 'Transparent-Glass', + 'Gold-Silver', + 'Green-Glass', + 'Light-Wood', + 'Power-Coated', + 'Purple-Black', + 'Rosewood', + 'Wood-Glass', + 'Wax', + 'Jade', + 'Marble', + 'Woodi', + ); + @each $name in $board-files { + .#{$name} { + background-image: img-url('staunton/board/#{$name}.thumbnail.png'); + } + } + } +} diff --git a/ui/dasher/css/_dasher.scss b/ui/dasher/css/_dasher.scss new file mode 100644 index 0000000000..213f48405f --- /dev/null +++ b/ui/dasher/css/_dasher.scss @@ -0,0 +1,157 @@ +@import 'link'; +@import 'board'; +@import 'piece'; + +#dasher_app { + @extend %box-radius-left; + width: 225px; + + .spinner { + margin: 20px auto; + } + .status { + display: block; + position: relative; + padding: 0.8rem; + border-top: $border; + signal { + position: absolute; + right: 1rem; + top: 1rem; + font-size: 1.7rem; + } + .ping, + .server { + @extend %roboto; + display: block; + } + strong { + padding: 0 5px; + } + } + + .head { + display: block; + padding: 1rem; + border-bottom: $border; + } + .head::before { + color: $c-dasher; + opacity: 0.8; + } + .head:hover::before { + opacity: 1; + } + + .langs { + form { + max-height: 400px; + overflow: auto; + } + button, + a { + display: block; + padding: .7rem .7rem .7rem 1rem; + border: none; + background: none; + width: 100%; + text-align: left; + &:hover { + background: $c-dasher-light; + } + } + .accepted { + border-left: 4px solid $c-dasher; + } + .current { + background: $c-dasher!important; + color: $c-dasher-over!important; + border-left: none; + } + } + .selector { + flex: 1 1 100%; + margin: 0.5rem 0; + a { + display: block; + padding: 0.7rem 1rem; + @include transition(background); + &:hover { + background: $c-dasher-light; + } + &.active { + background: $c-dasher!important; + color: $c-dasher-over!important; + } + &::before { + margin-right: 8px; + font-size: 19px; + justify-content: center; + align-items: center; + opacity: 0; + @include transition(opacity); + } + &:hover::before { + opacity: 1; + color: $c-dasher; + } + &.active::before { + opacity: 1; + color: $c-dasher-over!important; + } + } + &.large a { + padding: 1rem 1rem; + } + } + .zen { + a::before { + opacity: .5; + } + &:hover a::before{ + opacity: 1; + } + } + .sound { + .content { + display: flex; + margin: 5px 0 5px 5px; + } + .selector a { + border-radius: $box-radius-size 0 0 $box-radius-size; + } + .slider { + flex: 0 0 $slider-width; + margin: 1rem 1.3rem 1rem 1rem; + } + &.silent .slider { + opacity: 0.2; + } + } + + .background { + .image p { + font-size: 0.9em; + padding: 5px; + } + input { + padding: 5px; + border: 1px solid #444; + width: 100%; + background-color: #3e3e3e; + color: #fff; + } + } + + .board .zoom { + display: none; + @include breakpoint($mq-board-resizable) { + display: block; + } + border-top: $border; + padding: 1.5rem; + } + .board .slider { + margin-top: 1rem; + } +} diff --git a/ui/dasher/css/_link.scss b/ui/dasher/css/_link.scss new file mode 100644 index 0000000000..d77877157f --- /dev/null +++ b/ui/dasher/css/_link.scss @@ -0,0 +1,45 @@ +#dasher_app { + .links, + .subs { + padding: 5px 0; + } + .links a, + .links button, + .subs .sub { + @extend %nowrap-hidden; + display: block; + padding: 0.5rem 1rem; + } + .links a:hover, + .links a:hover::before, + .links button:hover, + .subs .sub:hover { + background: $c-dasher; + color: $c-dasher-over; + opacity: 1; + } + .logout button:hover { + background: $c-error; + } + .links button { + width: 100%; + text-align: left; + border: 0; + background: none; + } + .subs { + border-top: $border; + } + .sub { + &::before { + float: right; + font-size: 80%; + margin-top: 0.25rem; + color: $c-dasher; + } + &:hover::before { + color: $c-dasher-over; + opacity: 0.9; + } + } +} diff --git a/ui/dasher/css/_piece.scss b/ui/dasher/css/_piece.scss new file mode 100644 index 0000000000..b519093f02 --- /dev/null +++ b/ui/dasher/css/_piece.scss @@ -0,0 +1,40 @@ +#dasher_app { + .piece { + piece { + position: absolute; + width: 12.5%; + height: 12.5%; + top: 0; + left: 0; + background-size: cover; + z-index: 2; /* no less than 2 */ + pointer-events: none; + } + .list { + @extend %flex-wrap; + background: url(../images/board/darksquares.jpg); + box-shadow: inset 0 7px 20px 3px #777; + } + .no-square { + width: 75px; + height: 75px; + position: relative; + } + .no-square:hover { + background: rgba(250, 250, 250, 0.15); + } + .no-square.active { + background: fade-out($c-dasher, 0.3); + } + piece { + width: 100%; + height: 100%; + } + &.d3 piece { + left: 0; + top: 0; + background-size: cover; + background-position: 0 67%; + } + } +} diff --git a/ui/dasher/css/build/_dasher.scss b/ui/dasher/css/build/_dasher.scss new file mode 100644 index 0000000000..ea853355dc --- /dev/null +++ b/ui/dasher/css/build/_dasher.scss @@ -0,0 +1,9 @@ +@import '../../../common/css/plugin'; + +$c-dasher: $c-secondary; +$c-dasher-over: $c-secondary-over; +$c-dasher-light: mix($c-dasher, $c-bg-header-dropdown, 15%); +$c-slider: $c-dasher; + +@import '../../../common/css/form/ui-slider'; +@import '../dasher'; diff --git a/ui/dasher/css/build/dasher.dark.scss b/ui/dasher/css/build/dasher.dark.scss new file mode 100644 index 0000000000..5c534b73bd --- /dev/null +++ b/ui/dasher/css/build/dasher.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'dasher'; diff --git a/ui/dasher/css/build/dasher.light.scss b/ui/dasher/css/build/dasher.light.scss new file mode 100644 index 0000000000..00965ac0bd --- /dev/null +++ b/ui/dasher/css/build/dasher.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'dasher'; diff --git a/ui/dasher/css/build/dasher.transp.scss b/ui/dasher/css/build/dasher.transp.scss new file mode 100644 index 0000000000..d13c0b8df4 --- /dev/null +++ b/ui/dasher/css/build/dasher.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'dasher'; diff --git a/ui/dasher/gulpfile.js b/ui/dasher/gulpfile.js index c914b63480..f2fc68ab96 100644 --- a/ui/dasher/gulpfile.js +++ b/ui/dasher/gulpfile.js @@ -1,3 +1,3 @@ -const lilaGulp = require('../gulp/tsProject.js'); +require('../gulp/tsProject.js')('LichessDasher', 'lichess.dasher', __dirname); -lilaGulp('LichessDasher', 'lichess.dasher', __dirname); +require('../gulp/cssProject.js')(__dirname); diff --git a/ui/dasher/src/background.ts b/ui/dasher/src/background.ts index a53216ce80..80dd9e0600 100644 --- a/ui/dasher/src/background.ts +++ b/ui/dasher/src/background.ts @@ -6,10 +6,10 @@ import { Redraw, Close, bind, header } from './util' export interface BackgroundCtrl { list: Background[] set(k: string): void - get(): string + get(): string getImage(): string setImage(i: string): void - trans: Trans + trans: Trans close: Close } @@ -58,7 +58,7 @@ export function view(ctrl: BackgroundCtrl): VNode { return h('div.sub.background', [ header(ctrl.trans.noarg('background'), ctrl.close), - h('div.selector', ctrl.list.map(bg => { + h('div.selector.large', ctrl.list.map(bg => { return h('a.text', { class: { active: cur === bg.key }, attrs: { 'data-icon': 'E' }, @@ -80,7 +80,7 @@ function imageInput(ctrl: BackgroundCtrl) { }, hook: { insert: vnode => { - $(vnode.elm as HTMLElement).on('change keyup paste', window.lichess.fp.debounce(function(this: HTMLElement) { + $(vnode.elm as HTMLElement).on('change keyup paste', window.lichess.debounce(function(this: HTMLElement) { ctrl.setImage($(this).val()); }, 200)); } @@ -93,21 +93,20 @@ function applyBackground(data: BackgroundData, list: Background[]) { const key = data.current; - $('body').removeClass(list.map(b => b.key).join(' ')).addClass(key === 'transp' ? 'transp dark' : key); + $('body') + .removeClass(list.map(b => b.key).join(' ')) + .addClass(key === 'transp' ? 'transp dark' : key); - if ((key === 'dark' || key === 'transp') && !$('link[href*="dark.css"]').length) { - - $('link[href*="common.css"]').clone().each(function(this: HTMLElement) { - $(this).attr('href', $(this).attr('href').replace(/common\.css/, 'dark.css')).appendTo('head'); - }); - } - - if (key === 'transp' && !$('link[href*="transp.css"]').length) { - - $('link[href*="common.css"]').clone().each(function(this: HTMLElement) { - $(this).attr('href', $(this).attr('href').replace(/common\.css/, 'transp.css')).appendTo('head'); - }); - } + const prev = $('body').data('theme'); + $('body').data('theme', key); + $('link[href*=".' + prev + '."]').each(function(this: HTMLElement) { + var link = document.createElement('link'); + link.type = 'text/css'; + link.rel = 'stylesheet'; + link.href = $(this).attr('href').replace('.' + prev + '.', '.' + key + '.'); + link.onload = () => setTimeout(() => this.remove(), 100); + document.head.appendChild(link); + }); if (key === 'transp') { const bgData = document.getElementById('bg-data'); @@ -118,5 +117,4 @@ function applyBackground(data: BackgroundData, list: Background[]) { function reloadAllTheThings() { if (window.Highcharts) window.lichess.reload(); - window.lichess.reloadOtherTabs(); } diff --git a/ui/dasher/src/board.ts b/ui/dasher/src/board.ts index 49cab40a7c..a2919d71fa 100644 --- a/ui/dasher/src/board.ts +++ b/ui/dasher/src/board.ts @@ -6,40 +6,39 @@ import { Redraw, Close, bind, header } from './util' export interface BoardCtrl { data: BoardData trans: Trans - setIs3d(v: boolean): void - setZoom(v: number): void - close(): void + setIs3d(v: boolean): void; + readZoom(): number; + setZoom(v: number): void; + close(): void; } export interface BoardData { is3d: boolean - zoom: number } export type PublishZoom = (v: number) => void; -export function ctrl(data: BoardData, trans: Trans, publishZoom: PublishZoom, redraw: Redraw, close: Close): BoardCtrl { +export function ctrl(data: BoardData, trans: Trans, redraw: Redraw, close: Close): BoardCtrl { - data.zoom = data.zoom || 100; + const readZoom = () => parseInt(getComputedStyle(document.body).getPropertyValue('--zoom')) + 100; - const saveZoom = window.lichess.fp.debounce(() => { - $.ajax({ method: 'post', url: '/pref/zoom?v=' + data.zoom }); - }, 500); + const saveZoom = window.lichess.debounce(() => { + $.ajax({ method: 'post', url: '/pref/zoom?v=' + readZoom() }); + }, 1000); return { data, trans, setIs3d(v: boolean) { data.is3d = v; - $.post('/pref/is3d', { is3d: v }, () => { - window.lichess.reloadOtherTabs(); - window.lichess.reload(); - }); + $.post('/pref/is3d', { is3d: v }, window.lichess.reload); redraw(); }, + readZoom, setZoom(v: number) { - data.zoom = v; - publishZoom(v / 100); + document.body.setAttribute('style', '--zoom:' + (v - 100)); + window.lichess.dispatchEvent(window, 'resize'); + redraw(); saveZoom(); }, close @@ -48,9 +47,11 @@ export function ctrl(data: BoardData, trans: Trans, publishZoom: PublishZoom, re export function view(ctrl: BoardCtrl): VNode { + const domZoom = ctrl.readZoom(); + return h('div.sub.board', [ header(ctrl.trans.noarg('boardGeometry'), ctrl.close), - h('div.selector', [ + h('div.selector.large', [ h('a.text', { class: { active: !ctrl.data.is3d }, attrs: { 'data-icon': 'E' }, @@ -62,12 +63,20 @@ export function view(ctrl: BoardCtrl): VNode { hook: bind('click', () => ctrl.setIs3d(true)) }, '3D') ]), - h('div.zoom', [ - h('h2', ctrl.trans.noarg('boardSize')), - h('div.slider', { - hook: { insert: vnode => makeSlider(ctrl, vnode.elm as HTMLElement) } - }) - ]) + h('div.zoom', + isNaN(domZoom) ? [ + h('p', 'No board to zoom here!') + ] : [ + h('p', [ + ctrl.trans.noarg('boardSize'), + ': ', + (domZoom - 100), + '%' + ]), + h('div.slider', { + hook: { insert: vnode => makeSlider(ctrl, vnode.elm as HTMLElement) } + }) + ]) ]); } @@ -79,7 +88,7 @@ function makeSlider(ctrl: BoardCtrl, el: HTMLElement) { max: 200, range: 'min', step: 1, - value: ctrl.data.zoom, + value: ctrl.readZoom(), slide: (_: any, ui: any) => ctrl.setZoom(ui.value) }); }); diff --git a/ui/dasher/src/dasher.ts b/ui/dasher/src/dasher.ts index dfc97c99b8..441a5ec6b4 100644 --- a/ui/dasher/src/dasher.ts +++ b/ui/dasher/src/dasher.ts @@ -2,7 +2,7 @@ import { PingCtrl, ctrl as pingCtrl } from './ping' import { LangsCtrl, ctrl as langsCtrl } from './langs' import { SoundCtrl, ctrl as soundCtrl } from './sound' import { BackgroundCtrl, BackgroundData, ctrl as backgroundCtrl } from './background' -import { BoardCtrl, BoardData, PublishZoom, ctrl as boardCtrl } from './board' +import { BoardCtrl, BoardData, ctrl as boardCtrl } from './board' import { ThemeCtrl, ThemeData, ctrl as themeCtrl } from './theme' import { PieceCtrl, PieceData, ctrl as pieceCtrl } from './piece' import { Redraw, Prop, prop } from './util' @@ -28,6 +28,8 @@ export interface DasherData { export type Mode = 'links' | 'langs' | 'sound' | 'background' | 'board' | 'theme' | 'piece'; +const defaultMode = 'links'; + export interface DasherCtrl { mode: Prop; setMode(m: Mode): void; @@ -41,27 +43,25 @@ export interface DasherCtrl { board: BoardCtrl; theme: ThemeCtrl; piece: PieceCtrl; - }, - enableZen(): void; + }; opts: DasherOpts; } export interface DasherOpts { playing: boolean; - setZoom: PublishZoom; } export function makeCtrl(opts: DasherOpts, data: DasherData, redraw: Redraw): DasherCtrl { const trans = window.lichess.trans(data.i18n); - let mode: Prop = prop('links' as Mode); + let mode: Prop = prop(defaultMode as Mode); function setMode(m: Mode) { mode(m); redraw(); } - function close() { setMode('links'); } + function close() { setMode(defaultMode); } const ping = pingCtrl(trans, redraw); @@ -69,15 +69,12 @@ export function makeCtrl(opts: DasherOpts, data: DasherData, redraw: Redraw): Da langs: langsCtrl(data.lang, trans, redraw, close), sound: soundCtrl(data.sound.list, trans, redraw, close), background: backgroundCtrl(data.background, trans, redraw, close), - board: boardCtrl(data.board, trans, opts.setZoom, redraw, close), + board: boardCtrl(data.board, trans, redraw, close), theme: themeCtrl(data.theme, trans, () => data.board.is3d ? 'd3' : 'd2', redraw, setMode), piece: pieceCtrl(data.piece, trans, () => data.board.is3d ? 'd3' : 'd2', redraw, setMode) }; - function enableZen() { - $('body').addClass('zen'); - $.post('/pref/zen', { zen: 1 }); - } + window.lichess.pubsub.on('top.toggle.user_tag', () => setMode(defaultMode)); return { mode, @@ -86,7 +83,6 @@ export function makeCtrl(opts: DasherOpts, data: DasherData, redraw: Redraw): Da trans, ping, subs, - opts, - enableZen + opts }; }; diff --git a/ui/dasher/src/langs.ts b/ui/dasher/src/langs.ts index a207a21780..0704a47505 100644 --- a/ui/dasher/src/langs.ts +++ b/ui/dasher/src/langs.ts @@ -36,7 +36,7 @@ export function ctrl(data: LangsData, trans: Trans, redraw: Redraw, close: Close const accs: Lang[] = []; const others: Lang[] = []; d.forEach((l: Lang) => { - if (data.accepted.indexOf(l[0]) > -1) accs.push(l); + if (data.accepted.includes(l[0])) accs.push(l); else others.push(l); }); list = accs.concat(others) as Lang[]; @@ -71,7 +71,7 @@ function langLinks(ctrl: LangsCtrl, list: Lang[]) { function langView(current: Code, accepted: Code[]) { return (l: Lang) => - h('button' + (current === l[0] ? '.current' : '') + (accepted.indexOf(l[0]) > -1 ? '.accepted' : ''), { + h('button' + (current === l[0] ? '.current' : '') + (accepted.includes(l[0]) ? '.accepted' : ''), { attrs: { type: 'submit', name: 'lang', diff --git a/ui/dasher/src/links.ts b/ui/dasher/src/links.ts index ead5c20eea..e932166209 100644 --- a/ui/dasher/src/links.ts +++ b/ui/dasher/src/links.ts @@ -12,7 +12,7 @@ export default function(ctrl: DasherCtrl): VNode { function userLinks(): VNode | null { return d.user ? h('div.links', [ h( - 'a.user_link.online.text.is-green', + 'a.user-link.online.text.is-green', linkCfg(`/@/${d.user.name}`, d.user.patron ? '' : ''), noarg('profile')), @@ -36,7 +36,7 @@ export default function(ctrl: DasherCtrl): VNode { linkCfg('/streamer/edit', ''), 'Streamer manager'), - h('form', { + h('form.logout', { attrs: { method: 'post', action: '/logout' } }, [ h('button.text', { @@ -80,12 +80,12 @@ export default function(ctrl: DasherCtrl): VNode { noarg('pieceSet')) const zenToggle = ctrl.opts.playing ? h('div.zen.selector', [ - h('a', { + h('a.text', { attrs: { 'data-icon': 'K', title: 'Keyboard: z' }, - hook: bind('click', ctrl.enableZen) + hook: bind('click', window.lichess.pubsub.emit('zen')) }, noarg('zenMode')) ]) : null; diff --git a/ui/dasher/src/main.ts b/ui/dasher/src/main.ts index 2673b91839..e5b4aa660f 100644 --- a/ui/dasher/src/main.ts +++ b/ui/dasher/src/main.ts @@ -20,8 +20,9 @@ export default function LichessDasher(element: Element, opts: DasherOpts) { redraw(); - get('/dasher').then(data => { + return get('/dasher').then(data => { ctrl = makeCtrl(opts, data, redraw); redraw(); + return ctrl; }); }; diff --git a/ui/dasher/src/piece.ts b/ui/dasher/src/piece.ts index 8602615146..72ca5f07ce 100644 --- a/ui/dasher/src/piece.ts +++ b/ui/dasher/src/piece.ts @@ -39,7 +39,7 @@ export function ctrl(data: PieceData, trans: Trans, dimension: () => keyof Piece applyPiece(t, d.list, dimension() === 'd3'); $.post('/pref/pieceSet' + (dimension() === 'd3' ? '3d' : ''), { set: t - }, window.lichess.reloadOtherTabs); + }); redraw(); }, open @@ -54,13 +54,7 @@ export function view(ctrl: PieceCtrl): VNode { header(ctrl.trans.noarg('pieceSet'), () => ctrl.open('links')), h('div.list', { attrs: { method: 'post', action: '/pref/soundSet' } - }, d.list.map(pieceView(d.current, ctrl.set, ctrl.dimension() == 'd3'))), - h('div.subs', [ - h('a', { - hook: bind('click', () => ctrl.open('theme')), - attrs: { 'data-icon': 'H' } - }, ctrl.trans.noarg('boardTheme')) - ]) + }, d.list.map(pieceView(d.current, ctrl.set, ctrl.dimension() == 'd3'))) ]); } diff --git a/ui/dasher/src/ping.ts b/ui/dasher/src/ping.ts index 019302c3c2..c9dc7404b2 100644 --- a/ui/dasher/src/ping.ts +++ b/ui/dasher/src/ping.ts @@ -52,15 +52,15 @@ export function view(ctrl: PingCtrl): VNode { return h('a.status', { attrs: {href: '/lag'} }, [ signalBars(d), - h('span.ping.hint--left', { - attrs: { 'data-hint': 'PING: ' + ctrl.trans.noarg('networkLagBetweenYouAndLichess') } + h('span.ping', { + attrs: { title: 'PING: ' + ctrl.trans.noarg('networkLagBetweenYouAndLichess') } }, [ h('em', 'PING'), h('strong', defined(d.ping) ? '' + d.ping : '?'), h('em', 'ms') ]), - h('span.server.hint--left', { - attrs: { 'data-hint': 'SERVER: ' + ctrl.trans.noarg('timeToProcessAMoveOnLichessServer') } + h('span.server', { + attrs: { title: 'SERVER: ' + ctrl.trans.noarg('timeToProcessAMoveOnLichessServer') } }, [ h('em', 'SERVER'), h('strong', defined(d.server) ? '' + d.server : '?'), diff --git a/ui/dasher/src/sound.ts b/ui/dasher/src/sound.ts index 390b77ca10..f7a28e95f2 100644 --- a/ui/dasher/src/sound.ts +++ b/ui/dasher/src/sound.ts @@ -13,12 +13,13 @@ export interface SoundData { } export interface SoundCtrl { - list: Sound[] - api: any, - set(k: Key): void - volume(v: number): void - trans: Trans - close: Close + makeList(): Sound[]; + api: any; + set(k: Key): void; + volume(v: number): void; + redraw: Redraw; + trans: Trans; + close: Close; } export function ctrl(raw: string[], trans: Trans, redraw: Redraw, close: Close): SoundCtrl { @@ -28,18 +29,28 @@ export function ctrl(raw: string[], trans: Trans, redraw: Redraw, close: Close): const api = window.lichess.sound; return { - list, + makeList() { + const canSpeech = window.speechSynthesis && window.speechSynthesis.getVoices().length; + return list.filter(s => s[0] != 'speech' || canSpeech); + }, api, set(k: Key) { - api.changeSet(k); - api.genericNotify(); - $.post('/pref/soundSet', { set: k }, window.lichess.reloadOtherTabs); + api.speech(k == 'speech'); + window.lichess.pubsub.emit('speech.enabled')(api.speech()); + if (api.speech()) api.say('Speech synthesis ready'); + else { + api.changeSet(k); + api.genericNotify(); + $.post('/pref/soundSet', { set: k }); + } redraw(); }, volume(v: number) { api.setVolume(v); - api.move(true); + // plays a move sound if speech is off + api.move('knight F 7'); }, + redraw, trans, close }; @@ -47,19 +58,27 @@ export function ctrl(raw: string[], trans: Trans, redraw: Redraw, close: Close): export function view(ctrl: SoundCtrl): VNode { - return h('div.sub.sound.' + ctrl.api.set(), [ + const current = ctrl.api.speech() ? 'speech' : ctrl.api.set(); + + return h('div.sub.sound.' + ctrl.api.set(), { + hook: { + insert() { + window.speechSynthesis.onvoiceschanged = ctrl.redraw; + } + } + }, [ header(ctrl.trans('sound'), ctrl.close), h('div.content', [ h('div.slider', { hook: { insert: vn => makeSlider(ctrl, vn) } }), h('div.selector', { attrs: { method: 'post', action: '/pref/soundSet' } - }, ctrl.list.map(soundView(ctrl, ctrl.api.set()))) + }, ctrl.makeList().map(soundView(ctrl, current))) ]) ]); } function makeSlider(ctrl: SoundCtrl, vnode: VNode) { - const setVolume = window.lichess.fp.debounce(ctrl.volume, 50); + const setVolume = window.lichess.debounce(ctrl.volume, 50); window.lichess.slider().done(() => { $(vnode.elm as HTMLElement).slider({ orientation: 'vertical', diff --git a/ui/dasher/src/theme.ts b/ui/dasher/src/theme.ts index 6be158a77a..543f44dbec 100644 --- a/ui/dasher/src/theme.ts +++ b/ui/dasher/src/theme.ts @@ -39,7 +39,7 @@ export function ctrl(data: ThemeData, trans: Trans, dimension: () => keyof Theme applyTheme(t, d.list); $.post('/pref/theme' + (dimension() === 'd3' ? '3d' : ''), { theme: t - }, window.lichess.reloadOtherTabs); + }); redraw(); }, open @@ -54,13 +54,7 @@ export function view(ctrl: ThemeCtrl): VNode { header(ctrl.trans.noarg('boardTheme'), () => ctrl.open('links')), h('div.list', { attrs: { method: 'post', action: '/pref/soundSet' } - }, d.list.map(themeView(d.current, ctrl.set))), - h('div.subs', [ - h('a', { - hook: bind('click', () => ctrl.open('piece')), - attrs: { 'data-icon': 'H' } - }, ctrl.trans.noarg('pieceSet')) - ]) + }, d.list.map(themeView(d.current, ctrl.set))) ]); } diff --git a/ui/dasher/src/view.ts b/ui/dasher/src/view.ts index 094de4831b..6c817b7f63 100644 --- a/ui/dasher/src/view.ts +++ b/ui/dasher/src/view.ts @@ -12,7 +12,7 @@ import { view as pieceView } from './piece' import { spinner } from './util' export function loading(): VNode { - return h('div#dasher_app.dropdown', spinner()); + return h('div#dasher_app.dropdown', h('div.initiating', spinner())); } export function loaded(ctrl: DasherCtrl): VNode { diff --git a/ui/dasher/tsconfig.json b/ui/dasher/tsconfig.json index 3f5ab803ad..c9dcebc952 100644 --- a/ui/dasher/tsconfig.json +++ b/ui/dasher/tsconfig.json @@ -8,7 +8,8 @@ "alwaysStrict": true, "noImplicitReturns": true, "noImplicitThis": true, - "target": "es5", - "lib": ["DOM", "ES5"] + "moduleResolution": "node", + "target": "ES5", + "lib": ["DOM", "ES5", "es2015.core", "es2015.Promise"] } } diff --git a/ui/editor/css/_editor.scss b/ui/editor/css/_editor.scss new file mode 100644 index 0000000000..34f2ddd5e0 --- /dev/null +++ b/ui/editor/css/_editor.scss @@ -0,0 +1,30 @@ +@import 'layout'; +@import 'spare'; +@import 'tools'; + +@include body-fixed-scroll; + +.board-editor { + + user-select: none; + + .main-board { + grid-area: board; + } + .cg-board { + cursor: inherit; + } + + .copyables { + grid-area: copyables; + margin: 2rem 0 0 1rem; + p { + display: flex; + align-items: center; + input { + margin-left: 1rem; + flex: 1 1 100%; + } + } + } +} diff --git a/ui/editor/css/_layout.scss b/ui/editor/css/_layout.scss new file mode 100644 index 0000000000..a86b47d5ce --- /dev/null +++ b/ui/editor/css/_layout.scss @@ -0,0 +1,30 @@ +#main-wrap { + --main-max-width: auto; +} + +.board-editor { + + $board-width: calc((100vh - 4vmin) * var(--board-scale) * 0.8 - #{$site-header-outer-height}); + + display: grid; + + grid-template-columns: minmax(0, $board-width); + grid-template-areas: + 'spare-top' + 'board' + 'spare-bottom' + 'tools' + 'copyables'; + + @include breakpoint($mq-x-small) { + grid-template-columns: minmax(30vmin, $board-width) 2vmin minmax(200px, 300px); + grid-template-rows: min-content auto min-content; + grid-template-areas: + '. . tools' + 'spare-top . tools' + 'board . tools' + 'spare-bottom . tools' + '. . tools' + 'copyables . . '; + } +} diff --git a/ui/editor/css/_spare.scss b/ui/editor/css/_spare.scss new file mode 100644 index 0000000000..129cf2f781 --- /dev/null +++ b/ui/editor/css/_spare.scss @@ -0,0 +1,78 @@ +.board-editor .spare { + @extend %box-radius; + display: flex; + background: $c-font-dimmer; + box-shadow: 0 3px 5px rgba(0,0,0,0.3) inset; + &-top { + grid-area: spare-top; + margin-bottom: 2vh; + } + &-bottom { + grid-area: spare-bottom; + margin-top: 2vh; + } + .no-square { + flex: 0 0 12.5%; + @include transition(); + &:hover { + background: fade-out($c-primary, .8); + } + &.selected-square { + background: fade-out($c-primary, .5); + } + div { + @extend %square; + } + &.pointer { + @extend %box-radius-left; + &:hover { + background: fade-out($c-good, .8); + } + &.selected-square { + background: fade-out($c-good, .4); + } + piece { + background-image: img-url('icons/pointer.svg'); + } + } + &.trash { + @extend %box-radius-right; + &:hover { + background: fade-out($c-bad, .8); + } + &.selected-square { + background: fade-out($c-bad, .4); + } + piece { + background-image: img-url('icons/trash.svg'); + } + } + } + + .is3d & .no-square div { + padding-bottom: 90.72%; + } + piece { + display: block; + cursor: pointer; + width: 100%; + height: 100%; + .is3d & { + /* original size: width: 140.625%; height: 179.6875%; size on 3D board, with height/width = 90.78571% */ + width: 100%; + height: 140.7465%; + left: 0; + top: -34%; + } + } + piece.pointer, + piece.trash { + margin: 14%; + width: 72%; + height: 72%; + .is3d & { + width: 62%; + top: 0; + } + } +} diff --git a/ui/editor/css/_tools.scss b/ui/editor/css/_tools.scss new file mode 100644 index 0000000000..99cb13349b --- /dev/null +++ b/ui/editor/css/_tools.scss @@ -0,0 +1,46 @@ +.board-editor { + &__tools { + @extend %flex-column; + grid-area: tools; + align-self: center; + > * { + margin: .5rem 0; + } + select { + @extend %page-link !optional; + width: 100%; + &.positions option:checked { + font-style: italic; + } + } + .metadata { + @extend %box-neat; + background: $c-bg-box; + padding: 1rem; + white-space: nowrap; + .color { + margin-bottom: 1em; + } + .castling { + div { + @extend %flex-between; + } + label, + input { + display:inline-block; + margin: 3px; + vertical-align: middle; + } + } + } + .actions { + @extend %flex-column; + justify-content: stretch; + .button { + @extend %page-link !optional; + width: 100%; + text-align: left; + } + } + } +} diff --git a/ui/editor/css/build/_editor.scss b/ui/editor/css/build/_editor.scss new file mode 100644 index 0000000000..25a0220d0f --- /dev/null +++ b/ui/editor/css/build/_editor.scss @@ -0,0 +1,7 @@ +@import '../../../common/css/plugin'; +@import '../../../common/css/vendor/chessground/coords'; +@import '../../../common/css/layout/uniboard'; +@import '../../../common/css/component/board-resize'; +@import '../../../common/css/component/modal'; +@import '../../../common/css/component/continue-with'; +@import '../editor'; diff --git a/ui/editor/css/build/editor.dark.scss b/ui/editor/css/build/editor.dark.scss new file mode 100644 index 0000000000..3a0e7fb82f --- /dev/null +++ b/ui/editor/css/build/editor.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'editor'; diff --git a/ui/editor/css/build/editor.light.scss b/ui/editor/css/build/editor.light.scss new file mode 100644 index 0000000000..af46eab90b --- /dev/null +++ b/ui/editor/css/build/editor.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'editor'; diff --git a/ui/editor/css/build/editor.transp.scss b/ui/editor/css/build/editor.transp.scss new file mode 100644 index 0000000000..f673787526 --- /dev/null +++ b/ui/editor/css/build/editor.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'editor'; diff --git a/ui/editor/gulpfile.js b/ui/editor/gulpfile.js index adb52194c3..6197bfc1f4 100644 --- a/ui/editor/gulpfile.js +++ b/ui/editor/gulpfile.js @@ -1,3 +1,3 @@ -const lilaGulp = require('../gulp/jsProject.js'); +require('../gulp/jsProject.js')('LichessEditor', 'lichess.editor', __dirname); -lilaGulp('LichessEditor', 'lichess.editor', __dirname); +require('../gulp/cssProject.js')(__dirname); diff --git a/ui/editor/package.json b/ui/editor/package.json index 25c1e9996f..1e06f86f0b 100644 --- a/ui/editor/package.json +++ b/ui/editor/package.json @@ -20,18 +20,25 @@ }, "homepage": "https://github.com/ornicar/lila", "devDependencies": { + "breakpoint-sass": "^2.7.1", + "browser-sync": "^2.26.3", "browserify": "^16", - "gulp": "^4", - "gulp-uglify": "^3", - "gulp-size": "^3", "fancy-log": "^1", + "gulp": "^4", + "gulp-autoprefixer": "^6.0.0", + "gulp-rename": "^1.4.0", + "gulp-sass": "^4.0.2", + "gulp-size": "^3", + "gulp-sourcemaps": "^2.6.4", + "gulp-uglify": "^3", "uglify-js": "^3", - "vinyl-source-stream": "^2", "vinyl-buffer": "^1", + "vinyl-source-stream": "^2", "watchify": "^3" }, "dependencies": { - "chessground": "^7.3", - "mithril": "github:ornicar/mithril.js#lila-1" + "chessground": "^7.5", + "mithril": "github:ornicar/mithril.js#lila-1", + "common": "1.0.0" } } diff --git a/ui/editor/src/chessground.js b/ui/editor/src/chessground.js index 2e341ad487..e84ad9dd75 100644 --- a/ui/editor/src/chessground.js +++ b/ui/editor/src/chessground.js @@ -37,7 +37,7 @@ var placeDelete; function onMouseEvent(ctrl) { return function(e) { - var sel = ctrl.vm.selected(); + var sel = ctrl.selected(); if (isLeftClick(e) || e.type === 'touchstart' || e.type === 'touchmove') { if ( @@ -95,7 +95,7 @@ function onMouseEvent(ctrl) { if ( e.type === 'contextmenu' && - ['pointer', 'trash'].indexOf(sel) === -1 && sel.length >= 2 + !['pointer', 'trash'].includes(sel) && sel.length >= 2 ) { ctrl.chessground.cancelMove(); sel[0] = util.opposite(sel[0]); diff --git a/ui/editor/src/ctrl.js b/ui/editor/src/ctrl.js index 54a067f9ce..ff67b36b8d 100644 --- a/ui/editor/src/ctrl.js +++ b/ui/editor/src/ctrl.js @@ -12,10 +12,7 @@ module.exports = function(cfg) { this.trans = lichess.trans(this.data.i18n); - this.vm = { - selected: m.prop('pointer'), - redirecting: false - }; + this.selected = m.prop('pointer'); this.extraPositions = [{ fen: 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -', @@ -88,7 +85,6 @@ module.exports = function(cfg) { }.bind(this); this.changeFen = function(fen) { - this.vm.redirecting = true; window.location = editor.makeUrl(this.data.baseUrl, fen); }.bind(this); diff --git a/ui/editor/src/keyboard.js b/ui/editor/src/keyboard.js index 6f8db8e020..c4d5f1276d 100644 --- a/ui/editor/src/keyboard.js +++ b/ui/editor/src/keyboard.js @@ -1,21 +1,10 @@ var k = Mousetrap; var m = require('mithril'); -function preventing(f) { - return function(e) { - if (e.preventDefault) { - e.preventDefault(); - } else { - // internet explorer - e.returnValue = false; - } - f(); - }; -} - module.exports = function(ctrl) { - k.bind('f', preventing(function() { + k.bind('f', function(e) { + e.preventDefault(); ctrl.chessground.toggleOrientation(); m.redraw(); - })); + }); }; diff --git a/ui/editor/src/main.js b/ui/editor/src/main.js index b56c3d204e..4f7d1aac57 100644 --- a/ui/editor/src/main.js +++ b/ui/editor/src/main.js @@ -1,6 +1,9 @@ var ctrl = require('./ctrl'); var view = require('./view'); var m = require('mithril'); +var menuHover = require('common/menuHover').menuHover; + +menuHover(); module.exports = function(element, config) { var controller = new ctrl(config); diff --git a/ui/editor/src/view.js b/ui/editor/src/view.js index fe61a3d59a..868286a94c 100644 --- a/ui/editor/src/view.js +++ b/ui/editor/src/view.js @@ -1,6 +1,7 @@ var chessground = require('./chessground'); var dragNewPiece = require('chessground/drag').dragNewPiece; var eventPosition = require('chessground/util').eventPosition; +var resizeHandle = require('common/resize').default; var editor = require('./editor'); var m = require('mithril'); @@ -34,12 +35,13 @@ function studyButton(ctrl, fen) { m('input[type=hidden][name=fen]', { value: fen }), - m('button.button.text', { + m('button.button.button-empty.text', { type: 'submit', 'data-icon': '4', - disabled: !ctrl.positionLooksLegit() + disabled: !ctrl.positionLooksLegit(), + class: ctrl.positionLooksLegit() ? '' : 'disabled' }, - 'Study') + 'Study') ]); } @@ -69,7 +71,7 @@ function controls(ctrl, fen) { }; var selectedVariant = ctrl.data.variant; var looksLegit = ctrl.positionLooksLegit(); - return m('div.editor-side', [ + return m('div.board-editor__tools', [ ctrl.embed ? null : m('div', [ ctrl.data.positions ? m('select.positions', { onchange: function(e) { @@ -88,7 +90,7 @@ function controls(ctrl, fen) { ) ]) : null ]), - m('div.metadata.content_box', [ + m('div.metadata', [ m('div.color', m('select', { onchange: m.withAttr('value', ctrl.setColor) @@ -111,62 +113,61 @@ function controls(ctrl, fen) { ]) ]) ]), - m('div', [ - m('select#variants', { - onchange: function(e) { - ctrl.changeVariant(e.target.value); - } - }, [ - ['standard', 'Standard'], - ['antichess', 'Antichess'], - ['atomic', 'Atomic'], - ['crazyhouse', 'Crazyhouse'], - ['horde', 'Horde'], - ['kingOfTheHill', 'King of the Hill'], - ['racingKings', 'Racing Kings'], - ['threeCheck', 'Three-check'] - ].map(function(x) { return variant2option(x[0], x[1], ctrl) }) - ) - ]), - ctrl.embed ? m('div', [ - m('a.button.frameless', { + ctrl.embed ? m('div.actions', [ + m('a.button.button-empty', { onclick: ctrl.startPosition }, 'Initial position'), - m('a.button.frameless', { + m('a.button.button-empty', { onclick: ctrl.clearBoard }, 'Empty board') ]) : [ m('div', [ - m('a.button.text[data-icon=B]', { + m('select#variants', { + onchange: function(e) { + ctrl.changeVariant(e.target.value); + } + }, [ + ['standard', 'Standard'], + ['antichess', 'Antichess'], + ['atomic', 'Atomic'], + ['crazyhouse', 'Crazyhouse'], + ['horde', 'Horde'], + ['kingOfTheHill', 'King of the Hill'], + ['racingKings', 'Racing Kings'], + ['threeCheck', 'Three-check'] + ].map(function(x) { return variant2option(x[0], x[1], ctrl) }) + ) + ]), + m('div.actions', [ + m('a.button.button-empty.text[data-icon=B]', { onclick: function() { ctrl.chessground.toggleOrientation(); } }, ctrl.trans('flipBoard')), - looksLegit ? m('a.button.text[data-icon="A"]', { + looksLegit ? m('a.button.button-empty.text[data-icon="A"]', { href: editor.makeUrl('/analysis/' + selectedVariant + '/', fen), rel: 'nofollow' - }, ctrl.trans('analysis')) : m('span.button.disabled.text[data-icon="A"]', { + }, ctrl.trans('analysis')) : m('span.button.button-empty.disabled.text[data-icon="A"]', { rel: 'nofollow' }, ctrl.trans('analysis')), - m('a.button', { + m('a.button.button-empty', { class: (looksLegit && selectedVariant === 'standard') ? '' : 'disabled', onclick: function() { - if (ctrl.positionLooksLegit() && selectedVariant === 'standard') $.modal($('.continue_with')); + if (ctrl.positionLooksLegit() && selectedVariant === 'standard') $.modal($('.continue-with')); } }, - m('span.text[data-icon=U]', ctrl.trans('continueFromHere'))), + m('span.text[data-icon=U]', ctrl.trans('continueFromHere'))), studyButton(ctrl, fen) ]), - m('div.continue_with', [ + m('div.continue-with.none', [ m('a.button', { href: '/?fen=' + fen + '#ai', rel: 'nofollow' - }, ctrl.trans('playWithTheMachine')), - m('br'), + }, ctrl.trans.noarg('playWithTheMachine')), m('a.button', { href: '/?fen=' + fen + '#friend', rel: 'nofollow' - }, ctrl.trans('playWithAFriend')) + }, ctrl.trans.noarg('playWithAFriend')) ]) ] ]); @@ -174,10 +175,9 @@ function controls(ctrl, fen) { function inputs(ctrl, fen) { if (ctrl.embed) return; - if (ctrl.vm.redirecting) return m.trust(lichess.spinnerHtml); return m('div.copyables', [ m('p', [ - m('strong.name', 'FEN'), + m('strong', 'FEN'), m('input.copyable.autoselect[spellCheck=false]', { value: fen, onchange: function(e) { @@ -203,14 +203,14 @@ var lastTouchMovePos; function sparePieces(ctrl, color, orientation, position) { - var selectedClass = selectedToClass(ctrl.vm.selected()); + var selectedClass = selectedToClass(ctrl.selected()); var pieces = ['king', 'queen', 'rook', 'bishop', 'knight', 'pawn'].map(function(role) { return [color, role]; }); return m('div', { - class: ['spare', position, 'orientation-' + orientation, color].join(' ') + class: ['spare', 'spare-' + position, 'orientation-' + orientation, 'spare-' + color].join(' ') }, ['pointer'].concat(pieces).concat('trash').map(function(s) { var className = selectedToClass(s); @@ -223,44 +223,42 @@ function sparePieces(ctrl, color, orientation, position) { ( ( selectedClass === className && - ( - !ctrl.chessground || - !ctrl.chessground.state.draggable.current || - !ctrl.chessground.state.draggable.current.newPiece - ) + ( + !ctrl.chessground || + !ctrl.chessground.state.draggable.current || + !ctrl.chessground.state.draggable.current.newPiece + ) ) ? ' selected-square' : '' ); - if (s === 'trash') { - attrs['data-icon'] = 'q'; - containerClass += ' trash'; - } else if (s !== 'pointer') { - attrs['data-color'] = s[0]; - attrs['data-role'] = s[1]; - } + if (s === 'pointer') { + containerClass += ' pointer'; + } else if (s === 'trash') { + containerClass += ' trash'; + } else { + attrs['data-color'] = s[0]; + attrs['data-role'] = s[1]; + } - return m('div', { - class: containerClass, - onmousedown: onSelectSparePiece(ctrl, s, 'mouseup'), - ontouchstart: onSelectSparePiece(ctrl, s, 'touchend'), - ontouchmove: function(e) { - lastTouchMovePos = eventPosition(e) - } - }, m('piece', attrs)); + return m('div', { + class: containerClass, + onmousedown: onSelectSparePiece(ctrl, s, 'mouseup'), + ontouchstart: onSelectSparePiece(ctrl, s, 'touchend'), + ontouchmove: function(e) { + lastTouchMovePos = eventPosition(e) + } + }, m('div', m('piece', attrs))); })); } function onSelectSparePiece(ctrl, s, upEvent) { return function(e) { - if (['pointer', 'trash'].indexOf(s) !== -1) { - ctrl.vm.selected(s); + e.preventDefault(); + if (['pointer', 'trash'].includes(s)) { + ctrl.selected(s); } else { - ctrl.vm.selected('pointer'); - - if (e.type === 'touchstart') { - e.preventDefault(); - } + ctrl.selected('pointer'); dragNewPiece(ctrl.chessground.state, { color: s[0], @@ -271,9 +269,9 @@ function onSelectSparePiece(ctrl, s, upEvent) { var eventPos = eventPosition(e) || lastTouchMovePos; if (eventPos && ctrl.chessground.getKeyAtDomPos(eventPos)) { - ctrl.vm.selected('pointer'); + ctrl.selected('pointer'); } else { - ctrl.vm.selected(s); + ctrl.selected(s); } m.redraw(); }, {once: true}); @@ -291,18 +289,23 @@ function makeCursor(selected) { return 'url(' + url + '), default !important'; } -var eventNames = ['mousedown', 'touchstart']; - module.exports = function(ctrl) { var fen = ctrl.computeFen(); var color = ctrl.bottomColor(); var opposite = color === 'white' ? 'black' : 'white'; - return m('div.editor', { - style: 'cursor: ' + makeCursor(ctrl.vm.selected()) + return m('div.board-editor', { + style: 'cursor: ' + makeCursor(ctrl.selected()) }, [ sparePieces(ctrl, opposite, color, 'top'), - chessground(ctrl), + m('div.main-board', [ + chessground(ctrl), + m('div.board-resize', { + config: function(el, isUpdate) { + if (!isUpdate) resizeHandle(el); + } + }) + ]), sparePieces(ctrl, color, color, 'bottom'), controls(ctrl, fen), inputs(ctrl, fen) diff --git a/ui/game/css/_row.scss b/ui/game/css/_row.scss new file mode 100644 index 0000000000..9286090659 --- /dev/null +++ b/ui/game/css/_row.scss @@ -0,0 +1,82 @@ +.game-row { + display: flex; + align-items: stretch; + height: 17rem; + padding: .5em 1em; + border-bottom: $border; + position: relative; + @include transition(background); + &:nth-child(odd) { + background: $c-bg-zebra; + } + &:hover { + background: mix($c-link, $c-bg-box, 20%); + } + &__overlay { + @extend %link-overlay; + } + &__board { + flex: 0 0 16rem; + margin-right: 1em; + } + &__infos { + flex: 1 1 100%; + display: flex; + flex-flow: column; + justify-content: space-between; + margin: .5em 0; + } + .header { + @extend %flex-center; + &::before { + font-size: 3em; + opacity: 0.7; + margin-right: .7rem; + } + &__text { + strong { + @extend %roboto; + font-weight: normal; + font-size: 1.4em; + text-transform: uppercase; + display: block; + } + } + } + .versus { + display: flex; + justify-content: center; + align-items: center; + .swords { + width: 2.5em; + text-align: center; + font-size: 2em; + opacity: 0.7; + } + .player { + font-size: 1.3em; + text-align: right; + } + .player.black { + text-align: left; + } + a { + font-weight: bold; + position: relative; + z-index: z('above-link-overlay'); + } + .anon { + line-height: 2em; + } + } + .result { + display: block; + text-align: center; + } + .win { + color: $c-good; + } + .loss { + color: $c-bad; + } +} diff --git a/ui/game/src/router.ts b/ui/game/src/router.ts index 85d7bcc801..668fd257c5 100644 --- a/ui/game/src/router.ts +++ b/ui/game/src/router.ts @@ -1,9 +1,5 @@ import { GameData, ContinueMode } from './interfaces'; -export function player(data: GameData): string { - return '/' + data.game.id + data.player.id; -} - export function game(data: GameData, color?: Color, embed?: boolean): string; export function game(data: string, color?: Color, embed?: boolean): string; export function game(data: any, color?: Color, embed?: boolean): string { diff --git a/ui/game/tsconfig.json b/ui/game/tsconfig.json index e917441753..1d00f7d6c2 100644 --- a/ui/game/tsconfig.json +++ b/ui/game/tsconfig.json @@ -12,7 +12,8 @@ "noImplicitReturns": true, "noImplicitThis": true, "noUnusedParameters": true, - "target": "es5", - "lib": ["DOM", "ES5"] + "moduleResolution": "node", + "target": "ES5", + "lib": ["DOM", "ES5", "es2015.core", "es2015.Promise"] } } diff --git a/ui/gulp/cssProject.js b/ui/gulp/cssProject.js new file mode 100644 index 0000000000..0a26923cec --- /dev/null +++ b/ui/gulp/cssProject.js @@ -0,0 +1,85 @@ +const gulp = require('gulp'); +const sass = require('gulp-sass'); +const sourcemaps = require('gulp-sourcemaps'); +const autoprefixer = require('gulp-autoprefixer'); +const rename = require('gulp-rename'); +const fs = require('fs'); + +const themes = ['light', 'dark', 'transp']; + +const sassOptions = { + errLogToConsole: true, + outputStyle: 'expanded' +}; +const autoprefixerOptions = { + // https://browserl.ist/?q=last+5+versions%2C+Firefox+ESR%2C+not+IE+<+12%2C+not+<+0.1%25%2C+not+IE_Mob+<+12 + browsers: 'last 5 versions, Firefox ESR, not IE < 12, not < 0.1%, not IE_Mob < 12'.split(', ') +}; +const destination = () => gulp.dest('../../public/css/'); + +module.exports = (dir) => { + + const sourceDir = `${dir}/css`; + const buildDir = `${sourceDir}/build`; + const sourcesGlob = sourceDir + '/**/*.scss'; + const buildsGlob = sourceDir + '/build/*.scss'; + const commonGlob = '../common/css/**/*.scss'; + + createThemedBuilds(buildDir); + + const build = () => gulp + .src(buildsGlob) + .pipe(sourcemaps.init()) + .pipe(sass(sassOptions).on('error', sass.logError)) + .pipe(sourcemaps.write()) + // .pipe(autoprefixer(autoprefixerOptions)) + // .pipe(source(`${fileBaseName}.min.js`)) + .pipe(renameAs('dev')) + .pipe(destination()); + + gulp.task('css', gulp.series([ + build, + () => { + gulp.watch(sourcesGlob, build); + gulp.watch(commonGlob, build); + } + ])); + + gulp.task('css-dev', build); + + gulp.task('css-prod', () => gulp + .src(buildsGlob) + .pipe(sass({ + ...sassOptions, + ...{ outputStyle: 'compressed' } + }).on('error', sass.logError)) + .pipe(autoprefixer(autoprefixerOptions)) + .pipe(renameAs('min')) + .pipe(destination()) + ); +} + +function renameAs(ext) { + return rename(path => { + path.basename = `${path.basename}.${ext}`; + return path; + }); +} + +function createThemedBuilds(buildDir) { + const builds = fs.readdirSync(buildDir); + builds + .filter(fileName => fileName[0] === '_') + .forEach(fileName => { + themes.forEach(theme => { + const themedName = fileName.replace(/^_(.+)\.scss$/, `$1.${theme}.scss`); + const themedPath = `${buildDir}/${themedName}`; + if (!fs.existsSync(themedPath)) { + const buildName = fileName.replace(/^_(.+)\.scss$/, '$1'); + const code = `@import '../../../common/css/theme/${theme}';\n@import '${buildName}';\n`; + console.log(`Create missing SCSS themed build: ${themedPath}`); + fs.writeFileSync(themedPath, code); + } + }); + }); +} diff --git a/ui/gulp/jsProject.js b/ui/gulp/jsProject.js index 9bd358f750..174da9c8d1 100644 --- a/ui/gulp/jsProject.js +++ b/ui/gulp/jsProject.js @@ -15,7 +15,7 @@ module.exports = (standalone, fileBaseName, dir) => { standalone: standalone, debug: debug }); - const destination = () => gulp.dest(`../../public/compiled/`); + const destination = () => gulp.dest('../../public/compiled/'); const prod = () => browserify(browserifyOpts(false)) .bundle() diff --git a/ui/gulp/tsProject.js b/ui/gulp/tsProject.js index 530cb22336..09f7a96ad6 100644 --- a/ui/gulp/tsProject.js +++ b/ui/gulp/tsProject.js @@ -16,7 +16,7 @@ module.exports = (standalone, fileBaseName, dir) => { standalone: standalone, debug: debug }); - const destination = () => gulp.dest(`../../public/compiled/`); + const destination = () => gulp.dest('../../public/compiled/'); const prod = () => browserify(browserifyOpts(false)) .plugin(tsify) diff --git a/ui/gulpfile.js b/ui/gulpfile.js new file mode 100644 index 0000000000..141b605afe --- /dev/null +++ b/ui/gulpfile.js @@ -0,0 +1,90 @@ +const gulp = require('gulp'); +const sass = require('gulp-sass'); +const sourcemaps = require('gulp-sourcemaps'); +const autoprefixer = require('gulp-autoprefixer'); +const sassInheritance = require('gulp-sass-inheritance') +const rename = require('gulp-rename'); +const cached = require('gulp-cached'); +const gulpif = require('gulp-if'); +const filter = require('gulp-filter'); +const fs = require('fs'); +const glob = require('glob'); + +const themes = ['light', 'dark', 'transp']; + +const sassOptions = { + errLogToConsole: true, + outputStyle: 'expanded' +}; +const autoprefixerOptions = { + // https://browserl.ist/?q=last+5+versions%2C+Firefox+ESR%2C+not+IE+<+12%2C+not+<+0.1%25%2C+not+IE_Mob+<+12%2C+not+android+<+4.4 + browsers: 'last 5 versions, Firefox ESR, not IE < 12, not < 0.1%, not IE_Mob < 12, not android < 4.4'.split(', ') +}; +const destination = () => gulp.dest('../public/css/'); + +const sourcesGlob = './*/css/**/*.scss'; +const buildsGlob = './*/css/build/*.scss'; + +const build = () => gulp.src(sourcesGlob) +//filter out unchanged scss files, only works when watching + .pipe(gulpif(global.isWatching, cached('sass'))) +//find files that depend on the files that have changed + .pipe(sassInheritance({dir: '.',debug: false})) +//filter out internal imports (folders and files starting with "_" ) + .pipe(filter(file => !/\/_/.test(file.path) || !/^_/.test(file.relative))) + .pipe(sourcemaps.init()) + .pipe(sass(sassOptions).on('error', sass.logError)) + .pipe(sourcemaps.write()) + .pipe(renameAs('dev')) + .pipe(destination()); + +const setWatching = async () => { global.isWatching = true; }; + +const startWatching = () => gulp.watch(sourcesGlob, build); + +gulp.task('css', gulp.series([ + createThemedBuilds, + setWatching, + build, + startWatching +])); + +gulp.task('css-dev', gulp.series([createThemedBuilds, build])); + +gulp.task('css-prod', () => gulp + .src(sourcesGlob) + .pipe(sass({ + ...sassOptions, + ...{ outputStyle: 'compressed' } + }).on('error', sass.logError)) + .pipe(autoprefixer(autoprefixerOptions)) + .pipe(renameAs('min')) + .pipe(destination()) +); + +function renameAs(ext) { + return rename(path => { + path.dirname = ''; + path.basename = `${path.basename}.${ext}`; + return path; + }); +} + +function createThemedBuilds(cb) { + glob(buildsGlob, {}, (err, files) => { + files + .filter(file => file.match(/\/_.+\.scss$/)) + .forEach(file => { + themes.forEach(theme => { + const themed = file.replace(/\/_(.+)\.scss$/, `/$1.${theme}.scss`); + if (!fs.existsSync(themed)) { + const buildName = file.replace(/.+\/_(.+)\.scss$/, '$1'); + const code = `@import '../../../common/css/theme/${theme}';\n@import '${buildName}';\n`; + console.log(`Create missing SCSS themed build: ${themed}`); + fs.writeFileSync(themed, code); + } + }); + }); + cb(); + }); +} diff --git a/ui/insight/css/_insight.scss b/ui/insight/css/_insight.scss new file mode 100644 index 0000000000..e83171fcbb --- /dev/null +++ b/ui/insight/css/_insight.scss @@ -0,0 +1,346 @@ +#insight { + > div { + display: grid; + grid-template-columns: minmax(280px, 15vw); + grid-template-rows: 60px; + grid-template-areas: + 'side head' + 'side meat'; + grid-gap: 0 $block-gap; + } + + .loading { + .meat { + position: relative; + } + .spinner { + @extend %abs-100, %flex-center; + top: 0; + left: 0; + height: 550px; + opacity: 0.7; + svg { + margin: auto; + width: 80px; + height: 80px; + } + } + } + .broken { + display: flex; + flex-flow: column; + align-items: center; + text-align: center; + padding: 200px 0; + width: 100%; + } + .broken i { + font-size: 50px; + } + + .chart { + height: 550px; + } + .loading .chart { + filter: blur(3px); + opacity: 0.5; + } + .chart.empty { + width: 100%; + display: flex; + align-items: center; + justify-content: center; + flex-flow: column; + font-size: 1.5em; + opacity: 0.7; + } + .chart.empty i { + margin-bottom: 30px; + display: block; + font-size: 200px; + opacity: 0.5; + } + + .left-side { + grid-area: side; + } + + header { + @extend %box-radius-top; + background: #333; + color: #ddd; + height: 100%; + grid-area: head; + h2 { + font-size: 2em; + line-height: 60px; + } + h2::before { + font-size: 42px; + vertical-align: top; + line-height: 60px; + margin: 0 10px; + } + > * { + display: inline-block; + } + .ms-choice { + background: #444; + color: #ddd; + border-color: #666; + } + } + .meat { + background: $c-bg-box; + border: $border; + border-top: 0; + grid-area: meat; + } + .axis-form { + float: right; + } + .axis-form .by { + padding: 0 20px; + } + .axis-form .ms-choice { + padding: 30px 10px; + border-width: 0 1px; + border-radius: 0; + transition: 0.15s; + } + .axis-form .ms-choice span { + line-height: 60px; + text-align: center; + } + .axis-form .ms-choice div { + top: 18px; + } + .axis-form .ms-drop { + color: $c-font; + ul > li label input { + display: none; + } + ul > li.selected label { + background: $c-accent; + color: $c-accent-over; + } + } + + .panel-tabs { + @extend %flex-center-nowrap; + justify-content: center; + align-items: flex-end; + border-bottom: 2px solid $c-border; + .tab { + @extend %roboto; + flex: 1 1 auto; + text-align: center; + padding: .5em .2em; + cursor: pointer; + position: relative; + color: $c-font-page; + @include transition(color, .25s); + min-width: 15%; + &::after { + content: ''; + background: fade-out($c-accent, .4); + height: 2px; + position: absolute; + width: 96%; + left: 2%; + bottom: -2px; + @include transition(all, .25s); + transform: scale(0); + } + &.active, + &:hover { + &::after { + transform: scale(1); + } + } + &.active { + color: $c-accent; + } + } + } + .presets { + @extend %box-neat; + a { + color: $c-font; + display: block; + padding: .7em; + @include transition(); + } + a::before { + opacity: 0.7; + transition: opacity 0.13s; + } + a:hover { + background: mix($c-accent, $c-bg-box, 20%); + } + a:hover::before { + opacity: 1; + } + a.active { + color: $c-accent; + } + } + .clear { + color: $c-bad; + font-size: .9em; + margin-bottom: .5em; + } + + .filters { + .box { + border-bottom-width: 0; + } + .box:last-child { + border-bottom-width: 1px + } + .ms-parent { + display: block; + } + .ms-choice { + padding: 15px 10px; + border-width: 0 0 1px 0; + @include transition(); + } + .ms-parent:last-child .ms-choice { + border-bottom: 0; + } + .ms-parent.selected .ms-choice { + $c-sel-ms-choice: fade-out($c-accent, .3); + background: linear-gradient(to right, $c-sel-ms-choice 0px, $c-sel-ms-choice 5px, rgba(0,0,0,0) 5px, rgba(0,0,0,0) 100%); + } + .ms-parent:hover .ms-choice { + background: mix($c-accent, $c-bg-box, 20%); + } + .ms-choice span { + text-align: right; + line-height: 30px; + background: none; + } + .ms-choice div { + top: 4px; + } + .ms-drop ul > li label input { + margin-right: 5px; + cursor: pointer; + } + + .ms-drop { + margin-left: 99%; + top: 0; + left: 0; + } + } + + .ms-parent, + .ms-parent button { + user-select: none; + } + .ms-choice:focus, + .ms-parent input:focus { + outline: 0; + } + .ms-drop { + font-size: .9em; + ul { + padding: 0; + overflow: hidden; + } + ul > li label:not(.optgroup) { + padding: 4px 8px; + cursor: pointer; + @include transition(); + text-indent: 1em; + } + ul > li label:not(.optgroup):hover { + background: mix($c-accent, $c-bg-box, 20%); + } + ul > li label.optgroup { + border-top: $border; + margin-top: 5px; + text-indent: 0em; + text-transform: uppercase; + font-weight: normal; + opacity: 0.6; + padding: 6px 8px 2px 8px; + } + ul > li:first-child label.optgroup { + margin-top: 0; + } + } + + .box { + @extend %box-neat; + .top { + @extend %metal, %box-radius-top; + padding: #{$block-gap / 2} $block-gap; + font-weight: bold; + border-bottom: $border; + } + .content { + padding: $block-gap; + } + } + .info { + margin-bottom: $block-gap; + p { + margin: 0; + } + .insight-stale { + padding: $block-gap; + button { + width: 100%; + } + } + .help { + float: right; + } + .share a { + text-decoration: underline; + } + } + + .help.box { + margin-top: 20px; + } + .help .dimension { + margin-top: 10px; + } + .help h3 { + margin: 0; + font-weight: bold; + } + .help a { + text-decoration: underline; + } + + td.data { + font-weight: bold; + } + .game-sample { + margin: 2em 0 1em 0; + border-top: $border; + box-shadow: none; + } + .boards { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 25%)); + a { + @extend %box-radius; + @include transition(background); + color: $c-font; + padding: .4em; + span { + box-shadow: none; + background: none; + } + &:hover { + background: mix($c-link, $c-bg-box, 20%); + } + } + } +} diff --git a/ui/insight/css/build/_insight.scss b/ui/insight/css/build/_insight.scss new file mode 100644 index 0000000000..998a92a3ee --- /dev/null +++ b/ui/insight/css/build/_insight.scss @@ -0,0 +1,5 @@ +@import '../../../common/css/plugin'; +@import '../../../common/css/component/slist'; +@import '../../../common/css/component/modal'; +@import '../../../common/css/vendor/multiple-select'; +@import '../insight'; diff --git a/ui/insight/css/build/insight.dark.scss b/ui/insight/css/build/insight.dark.scss new file mode 100644 index 0000000000..665adcd32f --- /dev/null +++ b/ui/insight/css/build/insight.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'insight'; diff --git a/ui/insight/css/build/insight.light.scss b/ui/insight/css/build/insight.light.scss new file mode 100644 index 0000000000..2362e04aa4 --- /dev/null +++ b/ui/insight/css/build/insight.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'insight'; diff --git a/ui/insight/css/build/insight.transp.scss b/ui/insight/css/build/insight.transp.scss new file mode 100644 index 0000000000..a230c1def7 --- /dev/null +++ b/ui/insight/css/build/insight.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'insight'; diff --git a/ui/insight/src/boards.js b/ui/insight/src/boards.js index 73bc2efb72..700eaab596 100644 --- a/ui/insight/src/boards.js +++ b/ui/insight/src/boards.js @@ -1,28 +1,27 @@ var m = require('mithril'); -var boardContent = m('div.cg-board-wrap', m('div.cg-board')); - function miniGame(game) { - return m('div', [ - m('a', { - key: game.id, - href: '/' + game.id + (game.color === 'white' ? '' : '/black'), - class: 'mini_board live_' + game.id + ' parse_fen is2d', + return m('a', { + key: game.id, + href: '/' + game.id + (game.color === 'white' ? '' : '/black') + }, [ + m('span', { + class: 'mini-board cg-board-wrap mini-board-' + game.id + ' parse-fen is2d', 'data-color': game.color, 'data-fen': game.fen, 'data-lastmove': game.lastMove, config: function(el, isUpdate) { if (!isUpdate) lichess.parseFen($(el)); } - }, boardContent), - m('div.vstext.clearfix', [ - m('div.left', [ + }, m('div-cg-board')), + m('span.vstext', [ + m('span.vstext__pl', [ game.user1.name, m('br'), game.user1.title ? game.user1.title + ' ' : '', game.user1.rating ]), - m('div.right', [ + m('span.vstext__op', [ game.user2.name, m('br'), game.user2.rating, @@ -38,6 +37,6 @@ module.exports = function(ctrl) { return m('div.game-sample.box', [ m('div.top', 'Some of the games used to generate this insight'), - m('div.boards.game_list', ctrl.vm.answer.games.map(miniGame)) + m('div.boards', ctrl.vm.answer.games.map(miniGame)) ]); } diff --git a/ui/insight/src/chart.js b/ui/insight/src/chart.js index 128a7be15e..d967bad932 100644 --- a/ui/insight/src/chart.js +++ b/ui/insight/src/chart.js @@ -236,6 +236,6 @@ module.exports = function(ctrl) { makeChart(el, ctrl.vm.answer); } }), - m.trust(lichess.spinnerHtml) + ctrl.vm.loading ? m.trust(lichess.spinnerHtml) : null ]; }; diff --git a/ui/insight/src/filters.js b/ui/insight/src/filters.js index 5d4c49ed95..de78ca420a 100644 --- a/ui/insight/src/filters.js +++ b/ui/insight/src/filters.js @@ -10,7 +10,7 @@ function select(ctrl) { if (isUpdate && ctrl.vm.filters[dimension.key]) return; $(e).multipleSelect({ placeholder: dimension.name, - width: '239px', + width: '100%', selectAll: false, filter: dimension.key === 'opening', single: single, @@ -25,7 +25,7 @@ function select(ctrl) { var selected = ctrl.vm.filters[dimension.key]; return m('option', { value: value.key, - selected: selected && selected.indexOf(value.key) !== -1 + selected: selected && selected.includes(value.key) }, value.name); })); }; diff --git a/ui/insight/src/info.js b/ui/insight/src/info.js index 796888aa1f..ff5dee674e 100644 --- a/ui/insight/src/info.js +++ b/ui/insight/src/info.js @@ -6,16 +6,20 @@ module.exports = function(ctrl) { var shareText = 'Shared with ' + shareStates[ctrl.user.shareId] + '.'; return m('div.info.box', [ m('div.top', [ - m('a.help.hint--top', { - 'data-hint': 'How does this work?', + m('a.help', { + title: 'How does this work?', onclick: lichess.startInsightTour }, '?'), - m('a.username.user_link.insight-ulpt', { + m('a.username.user-link.insight-ulpt', { href: '/@/' + ctrl.user.name }, ctrl.user.name) ]), m('div.content', [ - m('p', 'Insights over ' + ctrl.user.nbGames + ' rated games.'), + m('p', [ + 'Insights over ', + m('strong', ctrl.user.nbGames), + ' rated games.' + ]), m('p.share', ctrl.own ? m('a', { href: '/account/preferences/privacy', target: '_blank' diff --git a/ui/insight/src/main.js b/ui/insight/src/main.js index 1a3fe60e85..a9de4f650d 100644 --- a/ui/insight/src/main.js +++ b/ui/insight/src/main.js @@ -16,3 +16,10 @@ module.exports = function(element, opts) { return controller; }; + +// for multiple-select +jQuery.fn.extend( { + hover: function( fnOver, fnOut ) { + return this.on('mouseenter', fnOver ).on('mouseleave', fnOut || fnOver ); + } +} ); diff --git a/ui/insight/src/view.js b/ui/insight/src/view.js index 5aa83a768e..11fb5c735e 100644 --- a/ui/insight/src/view.js +++ b/ui/insight/src/view.js @@ -45,23 +45,22 @@ module.exports = function(ctrl) { m('div.left-side', [ info(ctrl), m('div.panel-tabs', [ - m('a[data-panel=preset]', { + m('a[data-panel="preset"]', { class: 'tab preset' + (ctrl.vm.panel === 'preset' ? ' active' : ''), onclick: function() { ctrl.setPanel('preset'); } }, 'Presets'), - m('a[data-panel=filter]', { + m('a[data-panel="filter"]', { class: 'tab filter' + (ctrl.vm.panel === 'filter' ? ' active' : ''), onclick: function() { ctrl.setPanel('filter'); } - }, 'Filters'), Object.keys(ctrl.vm.filters).length ? m('a.clear.hint--top', { - 'data-hint': 'Clear all filters', - onclick: ctrl.clearFilters - }, m('span', { + }, 'Filters'), Object.keys(ctrl.vm.filters).length ? m('a.clear', { + title: 'Clear all filters', 'data-icon': 'L', - }, 'CLEAR')) : null, + onclick: ctrl.clearFilters + }, 'CLEAR') : null, ]), ctrl.vm.panel === 'filter' ? filters(ctrl) : null, ctrl.vm.panel === 'preset' ? presets(ctrl) : null, @@ -74,6 +73,6 @@ module.exports = function(ctrl) { 'data-icon': '7' }, 'Chess Insights') ]), - m('div.meat', renderMeat(ctrl)) + m('div.meat.box', renderMeat(ctrl)) ]); }; diff --git a/ui/learn/css/_board.scss b/ui/learn/css/_board.scss new file mode 100644 index 0000000000..e4feb92ad8 --- /dev/null +++ b/ui/learn/css/_board.scss @@ -0,0 +1,132 @@ +.learn__main { + item { + width: 70%; + height: 70%; + bottom: 15%; + left: 15%; + background-size: cover; + position: absolute; + transform: translate3d(0, 0, 0); + z-index: 1; + transition: all 1s; + } + @keyframes soft-hue { + 50%{ + filter: hue-rotate(-20deg); + } + } + @keyframes soft-grow { + 50%{ + transform: scale(1.08); + } + } + @keyframes apple-appear { + 0% { + opacity: 0.5; transform: scale(0) rotate(-360deg); + } + 100% { + opacity: 1; transform: scale(1) rotate(0); + } + } + .apple { + background-image: url(../images/learn/star.png); + animation: 0.6s ease-in-out 0s 1 forwards apple-appear, + 1.7s ease-in-out 0.7s infinite none soft-grow, + 0.7s ease-in-out 0.7s infinite none soft-hue; + } + square.has-item.move-dest { + background: radial-gradient(transparent 0%, transparent 80%, rgba(20, 85, 0, 0.3) 80%); + } + .cg-board square.move-dest.drag-over, + .cg-board square.move-dest:hover { + background: rgba(20, 85, 30, 0.3); + } + + @keyframes slideIn { + 0% { + opacity: 0; + filter: blur(15px); + } + 100% { + opacity: 1; + filter: blur(0px); + } + } + + @keyframes rankGlow { + 50% { + background-color: rgba(255, 255, 255, 0.5); + box-shadow: 0 0 40px rgba(255,255,255,0.7); + } + } + .highlight-2nd-rank & .cg-board::after, + .highlight-5th-rank & .cg-board::after, + .highlight-7th-rank & .cg-board::after { + width: 100%; + height: 12.5%; + content: ''; + position: absolute; + bottom: 12.5%; + left: 0; + box-shadow: 0 0 15px rgba(255,255,255,0.2); + background-color: rgba(255, 255, 255, 0.2); + animation: 1s rankGlow ease-in-out infinite; + } + .highlight-7th-rank & .cg-board::after { + top: 12.5%; + } + .highlight-5th-rank & .cg-board::after { + top: 37.5%; + } + #promotion-choice .explanation { + position: absolute; + top: 25%; + left: 25%; + width: 50%; + height: 50%; + background: #fff; + padding: 20px; + box-shadow: 0 3px 25px rgba(0,0,0,0.5); + h2 { + font-size: 2em; + } + p { + font-size: 1.3em; + margin-top: 15px; + } + } + + .cg-board piece.wriggle::after { + content: '!'; + } + .cg-board piece.wriggle::after { + content: '!'; + font-size: 40px; + font-weight: bold; + color: #fff; + text-shadow: rgba(0,0,0,0.8) 0 0 3px; + } + + .piece-values .cg-board piece::before { + position:absolute; + top: 14px; + right: 4px; + color: #fff; + text-shadow: 0 0 9px rgba(0,0,0,1), 0 0 4px rgba(0,0,0,1); + font-size: 30px; + font-weight: bold; + } + .piece-values .cg-board piece.queen::before { + content: '9'; + } + .piece-values .cg-board piece.rook::before { + content: '5'; + } + .piece-values .cg-board piece.bishop::before, + .piece-values .cg-board piece.knight::before { + content: '3'; + } + .piece-values .cg-board piece.pawn::before { + content: '1'; + } +} diff --git a/ui/learn/css/_layout.scss b/ui/learn/css/_layout.scss new file mode 100644 index 0000000000..d07058824a --- /dev/null +++ b/ui/learn/css/_layout.scss @@ -0,0 +1,56 @@ +$mq-col2: $mq-col2-uniboard; +$mq-col3: $mq-col3-uniboard; + +#main-wrap { + --main-max-width: calc(100vh - #{$site-header-outer-height} - #{$col1-uniboard-controls}); + @include breakpoint($mq-col2) { + --main-max-width: auto; + } +} + +.learn { + grid-area: main; + display: grid; + + &__side { grid-area: side; } + &__main { grid-area: main; } + &__table { grid-area: table; } + + &--run { + grid-template-areas: + 'main' + 'table' + 'side'; + } + &--map { + grid-template-areas: + 'side' + 'main'; + } + grid-gap: $block-gap; + + @include breakpoint($mq-col2) { + &--run { + grid-template-columns: $col2-uniboard-width $col2-uniboard-table; + grid-template-rows: fit-content(0); + grid-template-areas: + 'main table' + 'side .'; + } + &--map { + grid-template-areas: 'side main'; + grid-template-columns: 240px auto; + @include breakpoint($mq-x-large) { + grid-template-columns: 240px 960px; + } + } + } + + @include breakpoint($mq-col3) { + &--run { + grid-template-columns: $col3-uniboard-side $col3-uniboard-width $col3-uniboard-table; + grid-template-areas: + 'side main table'; + } + } +} diff --git a/ui/learn/css/_learn.scss b/ui/learn/css/_learn.scss new file mode 100644 index 0000000000..11a15bc2eb --- /dev/null +++ b/ui/learn/css/_learn.scss @@ -0,0 +1,8 @@ +@import 'layout'; +@import 'map'; +@import 'run'; +@import 'table'; +@import 'board'; +@import 'screen'; +@import 'side-map'; +@import 'side-home'; diff --git a/ui/learn/css/_map.scss b/ui/learn/css/_map.scss new file mode 100644 index 0000000000..89038cce39 --- /dev/null +++ b/ui/learn/css/_map.scss @@ -0,0 +1,156 @@ +.learn-stages { + padding-top: 10px; + + .categ > h2 { + @extend %roboto; + font-size: 2em; + letter-spacing: 8px; + text-transform: uppercase; + color: #999; + text-shadow: $text-shadow; + text-align: center; + } + .categ_stages { + --min-width: 100vw; + @include breakpoint($mq-xx-small) { + --min-width: 400px; + } + display: grid; + grid-template-columns: repeat(auto-fill, minmax(var(--min-width), 1fr)); + grid-gap: 1em; + margin: .8em 0 3em 0; + } + .stage { + @extend %box-radius, %flex-center-nowrap; + @include transition(); + position: relative; + height: 90px; + color: #fff; + margin-top: 13px; + box-shadow: 0 3px 5px 0 rgba(0, 0, 0, 0.3), 0 1px 1px 0 rgba(0, 0, 0, 0.2); + font-size: 1.2em; + + img { + width: 80px; + height: 80px; + margin: 0 13px; + opacity: 0.9; + } + h3 { + font-size: 2em; + letter-spacing: 3px; + margin: 0 0 1px -1px; + } + h3 { + font-size: 1.6em; + letter-spacing: 2px; + } + &.vvv h3 { + font-size: 1.4em; + letter-spacing: 1px; + } + p { + margin: 0; + } + @keyframes soft-bright { + 50%{ + filter: brightness(0.97); + } + } + &.ongoing { + background: $c-primary; + filter: brightness(0.9); + animation: 1.7s soft-bright ease-in-out infinite; + } + &.ongoing:hover { + filter: brightness(1.2); + } + &.done { + background: $c-secondary; + } + &.future { + opacity: 0.7; + background: $c-accent; + } + &.future img { + opacity: 0.7; + } + &.active, + &:hover { + filter: brightness(1.08); + transform: scale(1.02); + opacity: 1; + } + .ribbon-wrapper { + display: block; + width: 85px; + height: 88px; + overflow: hidden; + position: absolute; + top: -3px; + right: -3px; + } + } + .ribbon { + display: block; + font-size: 15px; + font-weight: bold; + color: #333; + text-align: center; + text-shadow: rgba(255,255,255,0.5) 0px 1px 0px; + transform: rotate(45deg); + position: relative; + padding: 7px 0; + left: -5px; + top: 15px; + width: 120px; + color: #6a6340; + box-shadow: 0px 0px 3px rgba(0,0,0,0.3); + i { + color: #d59120; + animation: 0.6s soft-hue ease-in-out infinite; + text-shadow: 0 -0.5px 1px rgba(0,0,0,0.5); + } + i:nth-child(2) { + animation-delay: 0.2s; + } + i:nth-child(3) { + animation-delay: 0.4s; + } + &:before, + &:after { + content: ""; + border-left: 3px solid transparent; + border-right: 3px solid transparent; + position:absolute; + bottom: -3px; + } + &:before { + left: 0; + } + &:after { + right: 0; + } + + &.done { + background-color: #BFDC7A; + } + &.done:before, + &.done:after { + border-top: 3px solid #6e8900; + } + &.ongoing { + background-color: #B3E5FC; + } + &.ongoing:before, + &.ongoing:after { + border-top: 3px solid #536DFE; + } + } + .what_next > p { + width: 100%; + text-align: center; + margin: 20px 0; + font-size: 1.2em; + } +} diff --git a/ui/learn/css/_run.scss b/ui/learn/css/_run.scss new file mode 100644 index 0000000000..e69de29bb2 diff --git a/ui/learn/css/_screen.scss b/ui/learn/css/_screen.scss new file mode 100644 index 0000000000..5afdfb11b0 --- /dev/null +++ b/ui/learn/css/_screen.scss @@ -0,0 +1,158 @@ +.learn__screen-overlay { + @extend %fullscreen-mask; + background: rgba(79, 195, 247, 0.9); + cursor: pointer; +} + +.learn__screen { + @extend %popup-shadow, %box-radius; + margin: 150px auto; + background-color: #fff; + width: 350px; + overflow: hidden; + text-align: center; + padding-top: 36px; + > :nth-child(1) { + animation: slideIn 1s cubic-bezier(0.37, 0.82, 0.2, 1); + } + > :nth-child(2) { + animation: slideIn 1.5s cubic-bezier(0.37, 0.82, 0.2, 1); + } + > :nth-child(3) { + animation: slideIn 2s cubic-bezier(0.37, 0.82, 0.2, 1); + } + > :nth-child(4) { + animation: slideIn 2.5s cubic-bezier(0.37, 0.82, 0.2, 1); + } + > :nth-child(5) { + animation: slideIn 3s cubic-bezier(0.37, 0.82, 0.2, 1); + } + .stars { + margin-bottom: 20px; + } + @keyframes star-appear { + 0% { + filter: saturate(1); opacity: 0.5; transform: scale(0) rotate(-360deg); + } + 85% { + filter: saturate(1); opacity: 1; transform: scale(1.3) rotate(10deg); + } + 100% { + filter: saturate(1); opacity: 1; transform: scale(1) rotate(0); + } + } + .stars .star-wrap { + display: inline-block; + width: 55px; + height: 55px; + margin: 0 5px; + position: relative; + } + .stars .star-wrap::before { + position: absolute; + top: 5px; + left: 5px; + display: block; + width: 45px; + height: 45px; + content: ''; + background-image: url(../images/learn/star.png); + background-size: cover; + filter: saturate(0); + opacity: 0.2; + } + .stars .star { + display: inline-block; + background-image: url(../images/learn/star.png); + background-size: cover; + width: 55px; + height: 55px; + opacity: 0; + animation: star-appear 2.5s ease-in-out; + animation-delay: 0.1s; + animation-fill-mode: forwards; + } + .stars .star-wrap:nth-child(2) .star { + animation-delay: 0.8s; + } + .stars .star-wrap:nth-child(3) .star { + animation-delay: 1.6s; + } + .no-square { + width: 100px; + height: 100px; + position: relative; + margin: 0 auto 22px auto; + } + h1 { + font-weight: bold; + color: #181818; + font-size: 24px; + margin-bottom: 22px; + } + .round-svg { + width: 240px; + height: 240px; + padding: 0px; + background: #f57c00; + border-radius: 50%; + margin: 0 auto 10px auto; + } + .round-svg img { + width: 240px; + height: 240px; + padding: 20px; + } + .score { + text-transform: uppercase; + color: #0288d1; + font-size: .85em; + display: block; + letter-spacing: 1px; + margin-bottom: 17px; + } + .score span { + font-weight: bold; + font-family: 'Roboto Mono'; + } + p { + color: #999999; + padding: 0 15%; + line-height: 24px; + margin-bottom: 17px; + } + .buttons { + width: 100%; + text-align: center; + margin-bottom: 23px; + a { + @extend %box-radius; + display: block; + text-decoration: none; + text-transform: uppercase; + line-height: 48px; + margin: 8px 10% 0 10%; + height: 48px; + color: #fff; + transition: all 0.3s; + } + a { + margin-top: 8px; + } + .next { + font-size: .9em; + background: #4fc3f7; + } + .back { + font-size: .85em; + background: #f57c00; + } + a:hover { + filter: brightness(0.9); + } + } + piece { + width: 100%; + height: 100%; + } +} diff --git a/ui/learn/css/_side-home.scss b/ui/learn/css/_side-home.scss new file mode 100644 index 0000000000..157d245e30 --- /dev/null +++ b/ui/learn/css/_side-home.scss @@ -0,0 +1,77 @@ +.learn__side-home { + @extend %box-neat; + background: $c-primary; + color: $c-primary-over; + text-align: center; + padding: 1em 0; + + h1 { + font-size: 2.5em; + margin: 0; + } + h2 { + font-size: 1.8em; + margin: .4em 0 1em 0; + } + + @keyframes fat-glide { + 50%{ + transform: translateY(-4px); + } + } + i.fat { + display: block; + width: 200px; + height: 200px; + background: img-url('learn/brutal-helm.svg'); + margin: auto; + opacity: 0.8; + } + &:hover i.fat { + animation: 1.2s fat-glide ease-in-out infinite; + } + .progress { + position: relative; + width: 100%; + height: 30px; + /* border-top: 3px solid #1566b2; */ + background: #1a7edb; + box-shadow: inset 0 1px 1px rgba(0,0,0,0.1); + overflow: hidden; + } + @keyframes animatedBackground { + from { background-position: 0 0; } + to { background-position: 0 1000%; } + } + @keyframes animatedBar { + from { transform: translateX(-100px); } + to { transform: translateX(0px); } + } + .progress .bar { + height: 100%; + background: #1566b2; + border-radius: 0 5px 5px 0; + background-image: img-url('grain.png'); + transform: translateX(-100px); + animation: animatedBackground 50s linear infinite, animatedBar 1s forwards; + } + .progress .text { + position: absolute; + top: 0; + left: 0; + width: 100%; + line-height: 30px; + z-index: 3; + } + .actions { + padding: 20px 10px; + text-align: left; + } + a { + opacity: 0.6; + color: #fff;; + &:hover { + opacity: 1; + } + } +} diff --git a/ui/learn/css/_side-map.scss b/ui/learn/css/_side-map.scss new file mode 100644 index 0000000000..dd3ad011a6 --- /dev/null +++ b/ui/learn/css/_side-map.scss @@ -0,0 +1,92 @@ +.learn__side-map { + user-select: none; + .back, + .categ > h2 { + display: block; + font-size: 1.3em; + height: 50px; + line-height: 50px; + text-indent: 15px; + cursor: pointer; + opacity: 0.81; + } + .back { + display: flex; + color: $c-font; + } + .back img { + width: 50px; + height: 50px; + opacity: 0.9; + margin-right: 10px; + padding: 10px; + background: rgba(120, 120, 120, 1); + display: block; + } + .back:hover { + background: rgba(120, 120, 120, 0.2); + } + .categ > h2 { + border-top: $border; + } + .categ > h2:hover { + background: fade-out($c-primary, .8); + } + .categ.active { + border: $border; + border-width: 0 1px; + } + .categ.active:last-child { + border-bottom-width: 1px; + } + .categ.active > h2 { + cursor: default; + background: $c-primary; + color: $c-primary-over; + } + .categ:not(.active) .categ_stages { + display: none; + } + .stage { + @extend %roboto, %flex-center; + @include transition(); + font-size: 1.1em; + opacity: .9; + color: $c-font; + + img, + i { + width: 50px; + height: 50px; + opacity: 0.9; + margin-right: 10px; + padding: 10px; + } + i::before { + font-size: 30px; + } + &.active { + background: fade-out($c-primary, .8); + } + &.active img { + background: $c-primary; + } + &.done:hover { + background: fade-out($c-good, .8); + } + &.done img { + background: $c-good; + } + &.future:hover { + background: fade-out($c-primary, .8); + } + &.future img { + opacity: 0.7; + background: $c-primary; + } + &:hover { + filter: brightness(0.9); + color: $c-font-clearer; + } + } +} diff --git a/ui/learn/css/_table.scss b/ui/learn/css/_table.scss new file mode 100644 index 0000000000..4aea9690f3 --- /dev/null +++ b/ui/learn/css/_table.scss @@ -0,0 +1,153 @@ +.learn__table { + align-self: center; + + .wrap { + @extend %box-neat, %box-radius-force; + } + + .title { + display: flex; + background: $c-primary; + color: $c-primary-over; + h2, + h3 { + font-size: 2.3em; + margin: 15px 0 5px -3px; + white-space: nowrap; + } + img { + width: 80px; + height: 80px; + margin: 5px 8px 5px 5px; + } + } + .subtitle { + margin-bottom: 1em; + } + + .goal { + @extend %flex-center; + background: $c-bg-box; + border: $border; + border-top: none; + padding: $block-gap; + text-align: center; + justify-content: center; + } + .result { + @extend %flex-center; + justify-content: center; + flex-flow: column nowrap; + border: $border; + border-top: none; + text-align: center; + cursor: pointer; + @include transition(); + min-height: 135px; + padding: 0; + font-size: 1.7em; + + @keyframes shadow-glow { + 50% { + box-shadow: 0 0 10px 10px rgba(255,255,255,0.5); + transform: scale(1.05); + } + } + @keyframes text-shadow-glow { + 50% { + text-shadow: 0 0 10px #fff; + transform: scale(1.05); + } + } + h2 { + animation: text-shadow-glow 1s 1; + } + &.failed h2, + &.next h2 { + margin-top: 15px; + } + &:hover { + filter: brightness(1.1); + } + .stars { + margin-top: 4px; + } + .stars i { + margin: 3px; + animation: text-shadow-glow 1s 1; + } + button { + margin: 15px auto 15px auto; + font-size: 30px; + font-weight: bold; + text-transform: uppercase; + background: #fff; + border: none; + border-radius: 5px; + padding: 5px 10px; + box-shadow: 0 0 5px 5px rgba(255,255,255,0.5); + animation: shadow-glow 1s infinite; + } + &.completed { + background: $c-good; + color: $c-good-over; + } + &.completed button { + color: $c-good; + } + &.failed { + background: $c-bad; + color: $c-bad-over; + } + &.failed button { + color: $c-bad; + } + @keyframes go-home { + from {opacity: 1;} + to {opacity: 0.1;} + } + &.completed:not(.no-go-home) piece { + animation: 0.7s ease-in-out 0.7s go-home; + } + } + + .progress { + @extend %flex-center-nowrap; + text-align: center; + border: $border; + border-top: 0; + a { + @extend %flex-center; + align-content: center; + flex: 1 1 100%; + text-align: center; + background: $c-bg-high; + height: 3em; + font-size: .9em; + border-left: $border; + opacity: .8; + @include transition(); + } + a:first-child { + border-left: 0; + } + a:hover { + opacity: 1; + } + a span { + margin: auto; + } + .st3 i:first-child { + display: block; + } + a.done { + color: $c-good-over; + background: $c-good; + } + a.active { + opacity: 1; + color: $c-primary-over; + background: $c-primary; + } + } +} diff --git a/ui/learn/css/build/_learn.scss b/ui/learn/css/build/_learn.scss new file mode 100644 index 0000000000..b1772685b4 --- /dev/null +++ b/ui/learn/css/build/_learn.scss @@ -0,0 +1,5 @@ +@import '../../../common/css/plugin'; +@import '../../../common/css/vendor/chessground/coords'; +@import '../../../common/css/layout/uniboard'; +@import '../../../chess/css/promotion'; +@import '../learn'; diff --git a/ui/learn/css/build/learn.dark.scss b/ui/learn/css/build/learn.dark.scss new file mode 100644 index 0000000000..fad7b8e71e --- /dev/null +++ b/ui/learn/css/build/learn.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'learn'; diff --git a/ui/learn/css/build/learn.light.scss b/ui/learn/css/build/learn.light.scss new file mode 100644 index 0000000000..bedb987074 --- /dev/null +++ b/ui/learn/css/build/learn.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'learn'; diff --git a/ui/learn/css/build/learn.transp.scss b/ui/learn/css/build/learn.transp.scss new file mode 100644 index 0000000000..05c5b965bd --- /dev/null +++ b/ui/learn/css/build/learn.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'learn'; diff --git a/ui/learn/src/assert.js b/ui/learn/src/assert.js index 06fd38a21a..9d50e49c9c 100644 --- a/ui/learn/src/assert.js +++ b/ui/learn/src/assert.js @@ -37,7 +37,7 @@ module.exports = { keys = readKeys(keys); return function(level) { for (var key in level.chess.occupation()) - if (keys.indexOf(key) === -1) return true; + if (!keys.includes(key)) return true; return false; }; }, diff --git a/ui/learn/src/ground.js b/ui/learn/src/ground.js index 7796ed03b3..a20ac06f9e 100644 --- a/ui/learn/src/ground.js +++ b/ui/learn/src/ground.js @@ -110,7 +110,7 @@ module.exports = { }, showCapture: function(move) { raf(function() { - var $square = $('#learn_app piece[data-key=' + move.orig + ']'); + var $square = $('#learn-app piece[data-key=' + move.orig + ']'); $square.addClass('wriggle'); setTimeout(function() { $square.removeClass('wriggle'); diff --git a/ui/learn/src/item.js b/ui/learn/src/item.js index bfbe0ff40a..9e3634b742 100644 --- a/ui/learn/src/item.js +++ b/ui/learn/src/item.js @@ -26,7 +26,7 @@ module.exports = { delete items[key]; }, hasItem: function(item) { - return list().indexOf(item) !== -1; + return list().includes(item); }, appleKeys: function() { var keys = []; diff --git a/ui/learn/src/main.js b/ui/learn/src/main.js index 0000508324..0cb8b2f124 100644 --- a/ui/learn/src/main.js +++ b/ui/learn/src/main.js @@ -15,14 +15,10 @@ module.exports = function(element, opts) { var side = mapSide(opts, trans); var sideCtrl = side.controller(); - opts.setStage = sideCtrl.setStage; - - m.module(opts.sideElement, { - controller: function() { - return sideCtrl; - }, - view: side.view - }); + opts.side = { + ctrl: sideCtrl, + view: function() { return side.view(sideCtrl); } + }; m.route(element, '/', { '/': map(opts, trans), diff --git a/ui/learn/src/map/mapMain.js b/ui/learn/src/map/mapMain.js index e271f8759d..9c300440fd 100644 --- a/ui/learn/src/map/mapMain.js +++ b/ui/learn/src/map/mapMain.js @@ -8,6 +8,7 @@ module.exports = function(opts, trans) { opts.stageId = null; opts.route = 'map'; return { + opts: opts, data: opts.storage.data, trans: trans, isStageIdComplete: function(stageId) { diff --git a/ui/learn/src/map/mapSide.js b/ui/learn/src/map/mapSide.js index 5283431a44..12ef697852 100644 --- a/ui/learn/src/map/mapSide.js +++ b/ui/learn/src/map/mapSide.js @@ -4,7 +4,7 @@ var stages = require('../stage/list'); var scoring = require('../score'); function renderInStage(ctrl) { - return m('div.map', [ + return m('div.learn__side-map', [ m('div.stages', [ m('a.back', { href: '/', @@ -36,7 +36,7 @@ function renderInStage(ctrl) { m('img', { src: s.image }), - m('h3', ctrl.trans.noarg(s.title)) + m('span', ctrl.trans.noarg(s.title)) ]); })) ]); @@ -47,7 +47,7 @@ function renderInStage(ctrl) { function renderHome(ctrl) { var progress = ctrl.progress(); - return m('div.home', [ + return m('div.learn__side-home', [ m('i.fat'), m('h1', ctrl.trans.noarg('learnChess')), m('h2', ctrl.trans.noarg('byPlaying')), diff --git a/ui/learn/src/map/mapView.js b/ui/learn/src/map/mapView.js index 8391e456c9..2585136c6f 100644 --- a/ui/learn/src/map/mapView.js +++ b/ui/learn/src/map/mapView.js @@ -68,8 +68,9 @@ function titleVerbosityClass(title) { } module.exports = function(ctrl) { - return m('div.learn.map', - m('div.stages', [ + return m('div.learn.learn--map', [ + m('div.learn__side', ctrl.opts.side.view()), + m('div.learn__main.learn-stages', [ stages.categs.map(function(categ) { return m('div.categ', [ m('h2', ctrl.trans.noarg(categ.name)), @@ -102,5 +103,5 @@ module.exports = function(ctrl) { }), whatNext(ctrl) ]) - ); + ]); }; diff --git a/ui/learn/src/promotion.js b/ui/learn/src/promotion.js index 5c9c21ae4f..4f70741b75 100644 --- a/ui/learn/src/promotion.js +++ b/ui/learn/src/promotion.js @@ -36,7 +36,7 @@ function renderPromotion(ctrl, dest, pieces, color, orientation, explain) { var vertical = color === orientation ? 'top' : 'bottom'; - return m('div#promotion_choice.' + vertical, [ + return m('div#promotion-choice.' + vertical, [ pieces.map(function(serverRole, i) { return m('square', { style: vertical + ': ' + i * 12.5 + '%;left: ' + left + '%', diff --git a/ui/learn/src/run/runCtrl.js b/ui/learn/src/run/runCtrl.js index 804a6aa4b8..fa859e6a0e 100644 --- a/ui/learn/src/run/runCtrl.js +++ b/ui/learn/src/run/runCtrl.js @@ -8,7 +8,7 @@ module.exports = function(opts, trans) { var stage = stages.byId[m.route.param('stage')]; if (!stage) m.route('/'); - opts.setStage(stage); + opts.side.ctrl.setStage(stage); var levelId = m.route.param('level') || (function() { var result = opts.storage.data.stages[stage.key]; @@ -63,6 +63,7 @@ module.exports = function(opts, trans) { m.redraw.strategy("diff"); return { + opts: opts, stage: stage, level: level, vm: vm, diff --git a/ui/learn/src/run/runView.js b/ui/learn/src/run/runView.js index 903e32d3b9..9c3e8d9ce5 100644 --- a/ui/learn/src/run/runView.js +++ b/ui/learn/src/run/runView.js @@ -34,33 +34,36 @@ module.exports = function(ctrl) { var level = ctrl.level; return m('div', { - class: 'lichess_game' + ' ' + stage.cssClass + ' ' + level.blueprint.cssClass + + class: 'learn learn--run ' + stage.cssClass + ' ' + level.blueprint.cssClass + (level.vm.starting ? ' starting' : '') + (level.vm.completed && !level.blueprint.nextButton ? ' completed' : '') + (level.vm.lastStep ? ' last-step' : '') + (level.blueprint.showPieceValues ? ' piece-values' : '') }, [ - ctrl.vm.stageStarting() ? stageStarting(ctrl) : null, - ctrl.vm.stageCompleted() ? stageComplete(ctrl) : null, - m('div.lichess_board_wrap', [ - m('div.lichess_board', chessground.view(ground.instance)), + m('div.learn__side', ctrl.opts.side.view()), + m('div.learn__main.main-board', [ + ctrl.vm.stageStarting() ? stageStarting(ctrl) : null, + ctrl.vm.stageCompleted() ? stageComplete(ctrl) : null, + chessground.view(ground.instance), renderPromotion(ctrl, level), ]), - m('div.lichess_ground', [ - m('div.title', [ - m('img', { - src: stage.image - }), - m('div.text', [ - m('h2', ctrl.trans.noarg(stage.title)), - m('p.subtitle', ctrl.trans.noarg(stage.subtitle)) - ]) - ]), - level.vm.failed ? renderFailed(ctrl) : ( - level.vm.completed ? renderCompleted(ctrl, level) : - m('div.goal', util.withLinebreaks(ctrl.trans.noarg(level.blueprint.goal))) - ), - renderProgress(ctrl.progress) + m('div.learn__table', [ + m('div.wrap', [ + m('div.title', [ + m('img', { + src: stage.image + }), + m('div.text', [ + m('h2', ctrl.trans.noarg(stage.title)), + m('p.subtitle', ctrl.trans.noarg(stage.subtitle)) + ]) + ]), + level.vm.failed ? renderFailed(ctrl) : ( + level.vm.completed ? renderCompleted(ctrl, level) : + m('div.goal', util.withLinebreaks(ctrl.trans.noarg(level.blueprint.goal))) + ), + renderProgress(ctrl.progress) + ]) ]) ]); }; diff --git a/ui/learn/src/run/stageComplete.js b/ui/learn/src/run/stageComplete.js index c64b2d8f20..0f8c83353a 100644 --- a/ui/learn/src/run/stageComplete.js +++ b/ui/learn/src/run/stageComplete.js @@ -13,12 +13,12 @@ module.exports = function(ctrl) { var stage = ctrl.stage; var next = ctrl.getNext(); var score = ctrl.stageScore(); - return m('div.screen-overlay', { + return m('div.learn__screen-overlay', { onclick: function(e) { - if (e.target.classList.contains('screen-overlay')) m.route('/'); + if (e.target.classList.contains('learn__screen-overlay')) m.route('/'); } }, - m('div.screen', [ + m('div.learn__screen', [ m('div.stars', makeStars(scoring.getStageRank(stage, score))), m('h1', ctrl.trans('stageXComplete', stage.id)), m('span.score', [ diff --git a/ui/learn/src/run/stageStarting.js b/ui/learn/src/run/stageStarting.js index fe2754e346..a38ebf39f1 100644 --- a/ui/learn/src/run/stageStarting.js +++ b/ui/learn/src/run/stageStarting.js @@ -2,10 +2,10 @@ var m = require('mithril'); var util = require('../util'); module.exports = function(ctrl) { - return m('div.screen-overlay', { + return m('div.learn__screen-overlay', { onclick: ctrl.hideStartingPane }, - m('div.screen', [ + m('div.learn__screen', [ m('h1', ctrl.trans('stageX', ctrl.stage.id) + ': ' + ctrl.trans.noarg(ctrl.stage.title)), ctrl.stage.illustration, m('p', util.withLinebreaks(ctrl.trans.noarg(ctrl.stage.intro))), diff --git a/ui/lobby/css/_blog.scss b/ui/lobby/css/_blog.scss new file mode 100644 index 0000000000..9110351cc8 --- /dev/null +++ b/ui/lobby/css/_blog.scss @@ -0,0 +1,27 @@ +.lobby__blog { + .post { + @extend %flex-between; + color: $c-font; + flex-wrap: nowrap; + overflow: hidden; + padding: .2em .5em; + &:hover { + background: mix($c-link, $c-bg-box, 15%); + } + .text { + flex: 1 1 100%; + } + strong { + display: block; + } + img { + height: 4em; + width: 4em; + margin-right: .8em; + } + time { + color: $c-font-dim; + white-space: nowrap; + } + } +} diff --git a/ui/lobby/css/_box.scss b/ui/lobby/css/_box.scss new file mode 100644 index 0000000000..d22c0a2e0e --- /dev/null +++ b/ui/lobby/css/_box.scss @@ -0,0 +1,59 @@ +.lobby { + &__box { + @extend %flex-column, %box-neat-force; + &__top { + @extend %metal, %flex-between; + flex: 0 0 auto; + padding: .3em .5em; + .more { + color: $c-font-dim; + } + .title { + @extend %base-font; + font-size: 1em; + font-weight: bold; + color: $c-font-dim; + padding: .3em; + } + } + &__content { + background: $c-bg-box; + overflow-x: hidden; + overflow-y: auto; + } + .user-link { + font-weight: bold; + color: $c-font-dim; + } + table { + width: 100%; + height: 100%; + } + td { + @extend %nowrap-ellipsis; + padding: .5em .4em; + border-top: $border; + max-width: 21ch; /* prevent leaderboard overflow due to long usernames */ + &:first-child { + padding-left: .7em; + } + } + tr:nth-child(even) { + background: $c-bg-zebra; + } + } + &__leaderboard, + &__winners { + td:first-child { + @extend %ellipsis; + } + td:last-child { + text-align: right; + padding-right: .7em; + } + } + &__forum .lobby__box__top, + &__blog .lobby__box__top { + border-bottom: $border; + } +} diff --git a/ui/lobby/css/_forum.scss b/ui/lobby/css/_forum.scss new file mode 100644 index 0000000000..3dae3e332d --- /dev/null +++ b/ui/lobby/css/_forum.scss @@ -0,0 +1,11 @@ +.lobby__forum { + li { + margin: 0.6em 0; + padding-left: 9px; + line-height: 14px; + white-space: nowrap; + } + .extract { + @extend %roboto; + } +} diff --git a/ui/lobby/css/_layout.scss b/ui/lobby/css/_layout.scss new file mode 100644 index 0000000000..2dfb11eb8e --- /dev/null +++ b/ui/lobby/css/_layout.scss @@ -0,0 +1,127 @@ +$mq-col2: $mq-xx-small; +$mq-col3: $mq-small; +$mq-col4: $mq-x-large; + +$mq-not-col3: $mq-not-small; + +@mixin lobby-app-size { + min-height: 300px; + @include breakpoint($mq-col2) { + min-height: 400px; + } + @include breakpoint($mq-col3) { + height: 600px; + max-height: calc(100vh - #{$site-header-outer-height} - #{$block-gap}); + } +} + +.lobby { + grid-area: main; + display: grid; + + grid-template-areas: + 'app' + 'table' + 'side' + 'tv' + 'puzzle' + 'leader' + 'winner' + 'tours' + 'simuls' + 'forum' + 'blog' + 'support' + 'about' + '.'; + grid-gap: $block-gap; + + &__counters { + margin-top: $block-gap; + } + + @include breakpoint($mq-col2) { + + grid-template-columns: repeat(2, 1fr); + grid-template-rows: auto repeat(3, fit-content(0)); + grid-template-areas: + 'table table' + 'app app' + 'side tv' + 'side puzzle' + 'leader winner' + 'tours tours' + 'simuls simuls' + 'forum forum' + 'blog blog' + 'about support'; + } + + @include breakpoint($mq-col3) { + + grid-template-columns: repeat(3, 1fr); + + grid-template-rows: 12em repeat(2, fit-content(0)); + + grid-template-areas: + 'table app app' + 'side app app' + 'tv leader winner' + 'puzzle tours tours ' + 'about simuls simuls' + 'support forum forum ' + '. blog blog'; + + &__start { + flex-flow: column; + align-items: stretch; + justify-content: center; + } + &__counters { + margin: #{$block-gap / 3} 0 #{$block-gap / -3} 0; + } + .timeline { + margin-left: 0; + } + } + + @include breakpoint($mq-col4) { + + grid-template-columns: repeat(4, 1fr); + + grid-template-rows: repeat(2, fit-content(0)); + + grid-template-areas: + 'side app app table' + 'tv leader winner puzzle' + 'about tours tours support' + '. simuls simuls .' + '. forum forum .' + '. blog blog .'; + + &__tournaments { + max-height: 20em; + } + &__side { + margin-top: 2em; + } + &__counters { + margin: 0; + } + } + + &__side { grid-area: side; } + &__app, + &__nope { grid-area: app; } + &__table { grid-area: table; } + &__tv { grid-area: tv; } + &__leaderboard { grid-area: leader; } + &__winners { grid-area: winner; } + &__puzzle { grid-area: puzzle; } + &__tournaments { grid-area: tours; } + &__simuls { grid-area: simuls; } + &__forum { grid-area: forum; } + &__blog { grid-area: blog; } + &__support { grid-area: support; } + &__about { grid-area: about ; } +} diff --git a/ui/lobby/css/_lobby.scss b/ui/lobby/css/_lobby.scss new file mode 100644 index 0000000000..aa5379ab92 --- /dev/null +++ b/ui/lobby/css/_lobby.scss @@ -0,0 +1,69 @@ +@import 'layout'; +@import 'app/app'; +@import 'puzzle'; +@import 'table'; +@import 'stream'; +@import 'spotlight'; +@import 'timeline'; +@import 'box'; +@import 'forum'; +@import 'blog'; +@import 'support'; + +body { + /* improves preload */ + overflow-y: scroll; +} + +#main-wrap { + --main-max-width: 1400px; +} + +.lobby__side { + @extend %flex-column; + overflow: hidden; +} + +.lobby__about { + display: flex; + align-content: flex-start; + flex-flow: row wrap; + font-size: .85em; + a { + @extend %page-text; + font-weight: bold; + margin-right: 1.2em; + white-space: nowrap; + } +} + +.lobby__nope { + @include lobby-app-size; + text-align: center; + .lobby__app__content { + @extend %flex-column; + height: 100%; + align-items: center; + padding-top: 2em; + } + ul { + margin: .6em auto; + display: inline-block; + text-align: left; + } + li { + list-style: disc outside; + font-size: 1.1em; + } +} +.game-setup { + display: none; +} +.about-side { + margin-top: $block-gap; +} +@include breakpoint($mq-not-col3) { + .about-side, .lobby__streams, .lobby__about { + margin-left: $block-gap; + } +} diff --git a/ui/lobby/css/_lobby.setup.scss b/ui/lobby/css/_lobby.setup.scss new file mode 100644 index 0000000000..357787e660 --- /dev/null +++ b/ui/lobby/css/_lobby.setup.scss @@ -0,0 +1,2 @@ +@import 'setup'; +@import 'app/hook-filter'; diff --git a/ui/lobby/css/_puzzle.scss b/ui/lobby/css/_puzzle.scss new file mode 100644 index 0000000000..50b3d70afb --- /dev/null +++ b/ui/lobby/css/_puzzle.scss @@ -0,0 +1,6 @@ +.lobby__puzzle { + .vstext { + display: block; + text-align: center; + } +} diff --git a/ui/lobby/css/_setup.scss b/ui/lobby/css/_setup.scss new file mode 100644 index 0000000000..ecad49201b --- /dev/null +++ b/ui/lobby/css/_setup.scss @@ -0,0 +1,143 @@ +$c-setup: $c-secondary; +$c-slider: $c-setup; + +.game-setup { + display: block; + #modal-wrap { + width: 30em; + padding: 0; + } + text-align: center; + h2 { + margin: 1.5rem 0; + } + form > div { + padding: .5em 1em; + } + group.radio { + margin: 0 auto 1em auto; + width: 70%; + .disabled { + opacity: 0.4; + cursor: default; + } + input:checked + label { + background: $c-setup; + } + } + .optional_config { + border-bottom: $border; + } + .mode_choice { + margin-top: 1em; + } + .optional_config, + .ratings { + background: $c-bg-zebra; + border-top: $border; + } + + .label_select { + @extend %flex-center; + text-align: left; + &.variant { + margin-bottom: .5em; + } + label { + flex: 0 0 33%; + text-align: right; + } + select { + margin-left: .8em; + font-weight: bold; + } + } + .fen_position { + display: none; + .board_editor { + display: block; + width: 50%; + margin: .5em auto 0 auto; + } + .fen_form { + @extend %flex-center-nowrap; + } + .fen_form input { + flex: 1 1 100%; + } + .fen_form .button { + } + } + input#fen.success { + border-color: $c-good; + } + input#fen.failure { + border-color: $c-bad; + } + .ui-slider { + margin: .5em 1em; + } + .slider { + padding-top: 5px; + text-align: left; + span { + font-weight: bold; + } + } + .ratings { + padding: 1em; + width: 100%; + text-align: center; + } + .ratings div { + display: none; + } + .color-submits { + display: flex; + align-items: flex-end; + justify-content: center; + margin: 1em auto; + text-align: center; + &__button { + margin: 0 .5em; + width: 64px; + height: 64px; + padding: 7px; + i { + display: block; + padding: 0; + width: 50px; + height: 50px; + background-size: 50px 50px; + } + &.white i { + background-image: img-url('../piece/cburnett/wK.svg'); + } + &.black i { + background-image: img-url('../piece/cburnett/bK.svg'); + } + &.random { + width: 85px; + height: 85px; + padding: 10px; + i { + background-image: img-url('wbK.svg'); + background-size: 65px 65px; + width: 65px; + height: 65px; + } + } + &.nope { + visibility: hidden; + } + &:disabled { + opacity: 0.3; + } + } + .spinner { + width: 85px; + height: 85px; + margin: 10px auto 20px auto; + } + } +} diff --git a/ui/lobby/css/_spotlight.scss b/ui/lobby/css/_spotlight.scss new file mode 100644 index 0000000000..4ccd89750d --- /dev/null +++ b/ui/lobby/css/_spotlight.scss @@ -0,0 +1,65 @@ +.lobby__spotlights { + @extend %box-neat-force; + flex: 0 0 auto; +} +.tour-spotlight { + @extend %flex-center-nowrap, %nowrap-hidden, %page-metal; + flex: 0 0 auto; + padding: .3em; + opacity: 0.8; + @include transition(); + text-shadow: $text-shadow; + color: $c-font; + &.invert, + &.event-spotlight, + &:hover { + @extend %page-metal-hover; + text-shadow: none; + } + &:hover { + opacity: 1; + } + .img { + flex: 0 0 50px; + margin: 0 .5em 0 .3em; + } + img.img { + width: 40px; + } + i.img, + .img.icon { + margin: 0 5px 0 0; + } + i.img::before { + color: #fff; + font-size: 50px; + @if $theme-light { + text-shadow: 1px 1px 2px $c-link; + } + } + .name { + margin-top: 1px; + line-height: 13px; + display: block; + } + .headline { + display: block; + font-size: .85em; + margin-bottom: -3px; + } + .more { + font-size: .85em; + time { + margin-left: 3px; + } + } + &.little { + .img { + flex: 0 0 40px; + margin: 0 .5em 0 .3em; + &::before { + font-size: 40px; + } + } + } +} diff --git a/ui/lobby/css/_stream.scss b/ui/lobby/css/_stream.scss new file mode 100644 index 0000000000..f832d40c8d --- /dev/null +++ b/ui/lobby/css/_stream.scss @@ -0,0 +1,19 @@ +.lobby__streams { + .stream { + @extend %roboto, %nowrap-ellipsis, %page-text; + color: $c-font-page; + display: block; + margin-bottom: .5em; + line-height: .9; + strong { + @extend %base-font; + } + &.highlight strong { + color: $c-brag; + } + strong:before { + font-size: 1.5em; + margin-right: .1rem; + } + } +} diff --git a/ui/lobby/css/_support.scss b/ui/lobby/css/_support.scss new file mode 100644 index 0000000000..fc806ca945 --- /dev/null +++ b/ui/lobby/css/_support.scss @@ -0,0 +1,47 @@ +$c-support: $c-brag; + +.lobby__support { + a { + @extend %flex-center-nowrap, %box-neat; + background: $c-bg-box; + font-size: 1.3em; + margin-bottom: $block-gap; + padding: .2em .5em; + @include transition(); + &:hover { + background: $c-support; + } + &:hover, + &:hover * { + color: #fff; + } + &:hover i::before { + opacity: 1; + color: #fff; + } + } + i { + flex: 0 0 auto; + margin: 0 .5em; + &::before { + margin-right: .15em; + color: $c-support; + font-size: 2.6em; + opacity: 0.8; + } + } + &__text { + flex: 1 1 auto; + color: $c-support; + strong { + color: $c-support; + font-weight: normal; + display: block; + } + span { + @extend %nowrap-ellipsis; + display: block; + font-size: .8em; + } + } +} diff --git a/ui/lobby/css/_table.scss b/ui/lobby/css/_table.scss new file mode 100644 index 0000000000..52dea71e7a --- /dev/null +++ b/ui/lobby/css/_table.scss @@ -0,0 +1,49 @@ +.lobby { + &__table { + @extend %flex-column; + position: relative; + } + &__start { + @extend %flex-column; + justify-content: stretch; + flex: 1 1 auto; + margin: 0 1em 0 1em; + @include breakpoint($mq-col2) { + margin: 2em 0 0 0; + } + a { + font-size: 1.1em; + text-align: center; + margin: .2em 0; + padding: .5em; + &.disabled { + opacity: 0.2; + } + } + @include breakpoint($mq-col4) { + justify-content: center; + a { + margin: 1.2em 0; + padding: 1em; + } + } + } + &__counters { + @extend %flex-between, %page-text; + background: $c-bg-zebra; + padding: $block-gap #{$block-gap * 2}; + @include breakpoint($mq-col3) { + background: none; + padding: 0; + } + @include breakpoint($mq-col4) { + flex-flow: column; + align-items: flex-start; + position: absolute; + bottom: 0; + } + a { + color: $c-font-page; + } + } +} diff --git a/ui/lobby/css/_timeline.scss b/ui/lobby/css/_timeline.scss new file mode 100644 index 0000000000..222dc0462c --- /dev/null +++ b/ui/lobby/css/_timeline.scss @@ -0,0 +1,29 @@ +.timeline { + @extend %page-text; + flex: 1 1 auto; + margin: 1em 0 0 $block-gap; + @include hoverflow; + .entry { + @extend %roboto; + a { + @extend %base-font, %page-font; + } + &:hover a { + color: $c-link; + } + &::after { + content: ''; + display: block; + width: 100%; + height: 1px; + background: linear-gradient(to left, $c-border 20%, $c-bg-page); + margin: .7em 0; + } + } + .more { + font-size: .9em; + margin: .5em; + display: block; + text-align: right; + } +} diff --git a/ui/lobby/css/app/_app.scss b/ui/lobby/css/app/_app.scss new file mode 100644 index 0000000000..d8d2117a61 --- /dev/null +++ b/ui/lobby/css/app/_app.scss @@ -0,0 +1,52 @@ +@import 'pool'; +@import 'hook-chart'; +@import 'hook-list'; + +.lobby__app { + @extend %flex-column; + @include lobby-app-size; + user-select: none; + + .lobby-nope & { + display: none; + } + + &__content { + @extend %box-neat; + flex: 1 1 100%; + position: relative; + @if $theme == 'transp' { + background: fade-out($c-bg-box, .2); + } @elseif $theme-light { + background: $c-bg-zebra url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMy41MjkgMzMuNTA0Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNS4yNS02LjI0NikiIG9wYWNpdHk9Ii4xIiBmaWxsPSJub25lIiBzdHJva2U9IiMwMDAiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxLjUiPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im0yMiAxMGMxMC41IDEgMTYuNSA4IDE2IDI5aC0yM2MwLTkgMTAtNi41IDgtMjEiLz48cGF0aCBkPSJtMjQgMThjLjM4IDIuOTEtNS41NSA3LjM3LTggOS0zIDItMi44MiA0LjM0LTUgNC0xLjA0Mi0uOTQgMS40MS0zLjA0IDAtMy0xIDAgLjE5IDEuMjMtMSAyLTEgMC00IDEtNC00IDAtMiA2LTEyIDYtMTIgMCAwIDEuODktMS45IDItMy41LS43My0uOTk0LS41LTItLjUtMyAxLTEgMyAyLjUgMyAyLjVoMmMwIDAgLjc4LTEuOTkyIDIuNS0zIDEgMCAxIDMgMSAzIi8+PC9nPjxnIGZpbGw9IiMwMDAiPjxwYXRoIGQ9Im05LjUgMjUuNWEuNSAuNSAwIDEgMSAtMSAwIC41IC41IDAgMSAxIDEgMHoiLz48cGF0aCBkPSJtMTUgMTUuNWEuNSAxLjUgMCAxIDEgLTEgMCAuNSAxLjUgMCAxIDEgMSAweiIgdHJhbnNmb3JtPSJtYXRyaXgoLjg2Ni41LS41Ljg2NiA5LjY5My01LjE3MykiLz48L2c+PC9nPjwvc3ZnPg=='); + } @elseif $theme-dark { + background: $c-bg-box url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMy41MjkgMzMuNTA0Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtNS4yNS02LjI0NikiIG9wYWNpdHk9Ii4xIiBmaWxsPSJub25lIiBzdHJva2U9IiNmZmYiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIxLjUiPjxnIGZpbGw9IiMwMDAiPjxwYXRoIGQ9Im0yMiAxMGMxMC41IDEgMTYuNSA4IDE2IDI5aC0yM2MwLTkgMTAtNi41IDgtMjEiLz48cGF0aCBkPSJtMjQgMThjLjM4IDIuOTEtNS41NSA3LjM3LTggOS0zIDItMi44MiA0LjM0LTUgNC0xLjA0Mi0uOTQgMS40MS0zLjA0IDAtMy0xIDAgLjE5IDEuMjMtMSAyLTEgMC00IDEtNC00IDAtMiA2LTEyIDYtMTIgMCAwIDEuODktMS45IDItMy41LS43My0uOTk0LS41LTItLjUtMyAxLTEgMyAyLjUgMyAyLjVoMmMwIDAgLjc4LTEuOTkyIDIuNS0zIDEgMCAxIDMgMSAzIi8+PC9nPjxnIGZpbGw9IiNmZmYiPjxwYXRoIGQ9Im05LjUgMjUuNWEuNSAuNSAwIDEgMSAtMSAwIC41IC41IDAgMSAxIDEgMHoiLz48cGF0aCBkPSJtMTUgMTUuNWEuNSAxLjUgMCAxIDEgLTEgMCAuNSAxLjUgMCAxIDEgMSAweiIgdHJhbnNmb3JtPSJtYXRyaXgoLjg2Ni41LS41Ljg2NiA5LjY5My01LjE3MykiLz48L2c+PC9nPjwvc3ZnPg=='); + } + background-size: 100% 100%; + overflow-y: auto; + } + + .lredir { + background: $c-bg-box; + display: flex; + .spinner { + width: 100px; + height: 100px; + } + } + + .toggle { + position: absolute; + padding: .6em; + cursor: pointer; + z-index: 2; + font-size: 1.3em; + &.toggle-filter { + right: 0; + } + @include transition(); + &:hover { + color: $c-accent; + } + } +} diff --git a/ui/lobby/css/app/_hook-chart.scss b/ui/lobby/css/app/_hook-chart.scss new file mode 100644 index 0000000000..5f79c486c7 --- /dev/null +++ b/ui/lobby/css/app/_hook-chart.scss @@ -0,0 +1,76 @@ +.hooks__chart { + @extend %abs-100; + bottom: 0; + right: 0; + .label { + color: $c-font-dim; + font-size: .7em; + position: absolute; + left: 3px; + bottom: 1px; + text-shadow: $text-shadow; + font-weight: bold; + } + .grid { + position: absolute; + left: 0; + bottom: 0; + &.horiz { + width: 100%; + border-top: 1px dashed $c-border; + } + &.vert { + height: 100%; + border-right: 1px dashed $c-border; + } + } + .canvas { + position: relative; + width: 100%; + height: 100%; + } + .plot { + position: absolute; + cursor: pointer; + z-index: 1; + font-size: 1.6em; + opacity: .7; + @include transition(); + transform: scale(1); + &.rated { + opacity: 0.9; + color: $c-brag; + } + &.cancel { + opacity: 0.9; + color: $c-good; + } + &.new { + transform: translateY(-7px); + opacity: 0; + } + &:hover { + z-index: 2; + opacity: 1; + transform: scale(1.15); + } + } +} +#hook { + @extend %box-radius-force, %popup-shadow; + display: none; + background: $c-bg-box; + position: absolute; + z-index: z('popup'); + .inner { + @extend %flex-column; + text-align: center; + padding-bottom: .5em; + } + .opponent { + @extend %metal; + min-width: 120px; + padding: .5em .7em; + margin-bottom: .5em; + } +} diff --git a/ui/lobby/css/app/_hook-filter.scss b/ui/lobby/css/app/_hook-filter.scss new file mode 100644 index 0000000000..915e9ea0c0 --- /dev/null +++ b/ui/lobby/css/app/_hook-filter.scss @@ -0,0 +1,47 @@ +.hook__filters { + padding: $block-gap 1.5em; + background: fade-out($c-bg-high, .5); + height: 100%; + white-space: nowrap; + td { + padding: 1em 0; + } + td:first-child { + font-size: 1.1em; + padding-right: 2rem; + width: 25%; + white-space: normal; + } + .checkable { + padding: 4.3px 0; + } + .checkable { + @extend %nowrap-ellipsis; + label, input { + vertical-align: middle; + cursor: pointer; + } + } + tr.variant td:last-child { + display: flex; + flex-flow: row wrap; + } + tr.variant .checkable { + width: 33.3%; + } + input { + margin-right: .3em; + } + .range { + display: block; + text-align: center; + margin-bottom: 1em; + } + .actions { + margin-top: 1.5em; + text-align: right; + button { + margin-left: .3em; + } + } +} diff --git a/ui/lobby/css/app/_hook-list.scss b/ui/lobby/css/app/_hook-list.scss new file mode 100644 index 0000000000..a648151d07 --- /dev/null +++ b/ui/lobby/css/app/_hook-list.scss @@ -0,0 +1,81 @@ +.hooks__list { + width: 100%; + tr { + &.disabled { + opacity: 0.4; + td { + cursor: default; + background: transparent; + border-color: transparent; + } + } + &.cancel td { + background: fade-out($c-secondary, .6); + } + &.join:hover td { + background: fade-out($c-accent, .2); + color: #fff; + transition: none; + } + + &:not(.disabled):hover ::before { + opacity: 1; + } + &.variants td { + text-align: center; + padding: 3px 0; + background: none; + text-transform: uppercase; + letter-spacing: 3px; + } + } + th { + @extend %roboto; + padding: 1em; + &.sortable { + cursor: pointer; + } + &.sortable:hover, + &.sort { + font-weight: normal; + } + &.sort .is:before { + opacity: 0.7; + margin-right: 3px; + content: "R"; + } + &.player { + width: 110px; + } + } + td { + @extend %nowrap-hidden; + padding: .5em .7em; + border-bottom: $border; + cursor: pointer; + @include transition(); + background: fade-out($c-bg-box, .5); + &:first-child { + width: 16px; + } + &:first-child ::before { + font-size: 1.2em; + line-height: 1.3; + } + &:last-child ::before { + margin-right: 8px; + line-height: 0.9; + font-size: 1.6em; + } + ::before { + opacity: 0.6; + } + } + tbody.stepping { + opacity: 0.7; + } +} +.lseeks .create { + margin-top: 20px; + text-align: center; +} diff --git a/ui/lobby/css/app/_pool.scss b/ui/lobby/css/app/_pool.scss new file mode 100644 index 0000000000..e9bf9c81a1 --- /dev/null +++ b/ui/lobby/css/app/_pool.scss @@ -0,0 +1,57 @@ +.lobby__app-pools { + height: 300px; + @include breakpoint($mq-col2) { + height: 400px; + } +} + +.lpools { + @extend %roboto; + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-template-rows: repeat(3, 1fr); + grid-gap: 9px; + padding: 9px; + @include fluid-size('font-size', 16px, 29px); + > div { + @extend %flex-column, %box-radius, %break-word; + justify-content: center; + align-items: center; + cursor: pointer; + border: $border; + @if $theme-light { + background: fade-out($c-bg-box, .5); + } @else { + background: fade-out($c-font, .95); + } + color: $c-font; + @include transition(); + &:hover { + background: fade-out($c-accent, .8); + opacity: 1; + } + } + .active { + @extend %popup-shadow; + background: $c-bg-popup; + .perf { + display: none; + } + } + .transp { + opacity: 0.4; + } + .spinner { + flex: 0 0 auto; + margin: .1em 0 .6em 0; + width: 2em; + height: 2em; + pointer-events: none; + } + .clock { + display: block; + font-size: 1.5em; + line-height: 1.6em; + letter-spacing: .1em; + } +} diff --git a/ui/lobby/css/build/_lobby.scss b/ui/lobby/css/build/_lobby.scss new file mode 100644 index 0000000000..323e56a0cd --- /dev/null +++ b/ui/lobby/css/build/_lobby.scss @@ -0,0 +1,7 @@ +@import '../../../common/css/plugin'; +@import '../../../common/css/component/now-playing'; +@import '../../../common/css/component/color-icon'; +@import '../../../common/css/component/glowing'; +@import '../../../common/css/component/tabs-horiz'; +@import '../../../common/css/base/scrollbar'; +@import '../lobby'; diff --git a/ui/lobby/css/build/_lobby.setup.scss b/ui/lobby/css/build/_lobby.setup.scss new file mode 100644 index 0000000000..d24927dbd8 --- /dev/null +++ b/ui/lobby/css/build/_lobby.setup.scss @@ -0,0 +1,5 @@ +@import '../../../common/css/plugin'; +@import '../../../common/css/form/ui-slider'; +@import '../../../common/css/form/radio'; +@import '../../../common/css/component/modal'; +@import '../lobby.setup'; diff --git a/ui/lobby/css/build/lobby.dark.scss b/ui/lobby/css/build/lobby.dark.scss new file mode 100644 index 0000000000..b8250b7875 --- /dev/null +++ b/ui/lobby/css/build/lobby.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'lobby'; diff --git a/ui/lobby/css/build/lobby.light.scss b/ui/lobby/css/build/lobby.light.scss new file mode 100644 index 0000000000..1bfd4d1290 --- /dev/null +++ b/ui/lobby/css/build/lobby.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'lobby'; diff --git a/ui/lobby/css/build/lobby.setup.dark.scss b/ui/lobby/css/build/lobby.setup.dark.scss new file mode 100644 index 0000000000..26ca693616 --- /dev/null +++ b/ui/lobby/css/build/lobby.setup.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'lobby.setup'; diff --git a/ui/lobby/css/build/lobby.setup.light.scss b/ui/lobby/css/build/lobby.setup.light.scss new file mode 100644 index 0000000000..f08aa66243 --- /dev/null +++ b/ui/lobby/css/build/lobby.setup.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'lobby.setup'; diff --git a/ui/lobby/css/build/lobby.setup.transp.scss b/ui/lobby/css/build/lobby.setup.transp.scss new file mode 100644 index 0000000000..02af950e3a --- /dev/null +++ b/ui/lobby/css/build/lobby.setup.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'lobby.setup'; diff --git a/ui/lobby/css/build/lobby.transp.scss b/ui/lobby/css/build/lobby.transp.scss new file mode 100644 index 0000000000..1e2754567c --- /dev/null +++ b/ui/lobby/css/build/lobby.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'lobby'; diff --git a/ui/lobby/package.json b/ui/lobby/package.json index f72a03e802..24a4cc3f4c 100644 --- a/ui/lobby/package.json +++ b/ui/lobby/package.json @@ -35,7 +35,7 @@ "watchify": "^3" }, "dependencies": { - "chessground": "^7.3", + "chessground": "^7.5", "common": "1.0.0", "snabbdom": "ornicar/snabbdom#0.7.1-lichess" } diff --git a/ui/lobby/src/boot.js b/ui/lobby/src/boot.js index ebeb0903ce..808a365a2e 100644 --- a/ui/lobby/src/boot.js +++ b/ui/lobby/src/boot.js @@ -2,7 +2,7 @@ module.exports = function(cfg, element) { var pools = [{id:"1+0",lim:1,inc:0,perf:"Bullet"},{id:"2+1",lim:2,inc:1,perf:"Bullet"},{id:"3+0",lim:3,inc:0,perf:"Blitz"},{"id":"3+2","lim":3,"inc":2,"perf":"Blitz"},{id:"5+0",lim:5,inc:0,perf:"Blitz"},{"id":"5+3","lim":5,"inc":3,"perf":"Blitz"},{id:"10+0",lim:10,inc:0,perf:"Rapid"},{id:"15+15",lim:15,inc:15,perf:"Classical"}]; var lobby; var nbRoundSpread = spreadNumber( - document.querySelector('#nb_games_in_play span'), + document.querySelector('#nb_games_in_play > strong'), 8, function() { return lichess.socket.pingInterval(); @@ -31,9 +31,9 @@ module.exports = function(cfg, element) { return l.slice(0, 2).toLowerCase(); }); langs.push($('html').attr('lang')); - $('#streams_on_air a, .event_spotlight').each(function() { + $('.lobby__streams a, .event-spotlight').each(function() { var match = $(this).text().match(/\[(\w{2})\]/mi); - if (match && langs.indexOf(match[1].toLowerCase()) === -1) $(this).hide(); + if (match && !langs.includes(match[1].toLowerCase())) $(this).hide(); }); }; filterStreams(); @@ -60,11 +60,11 @@ module.exports = function(cfg, element) { }); }, streams: function(html) { - $('#streams_on_air').html(html); + $('.lobby__streams').html(html); filterStreams(); }, featured: function(o) { - $('#featured_game').html(o.html); + $('.lobby__tv').html(o.html); lichess.pubsub.emit('content_loaded')(); }, redirect: function(e) { @@ -97,9 +97,9 @@ module.exports = function(cfg, element) { cfg.pools = pools; lobby = LichessLobby.start(cfg); - var blindMode = $('body').hasClass('blind_mode'); + var blindMode = $('body').hasClass('blind-mode'); - var $startButtons = $('#start_buttons'); + var $startButtons = $('.lobby__start'); var sliderTimes = [ 0, 1/4, 1/2, 3/4, 1, 3/2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, @@ -175,8 +175,8 @@ module.exports = function(cfg, element) { }; } - function prepareForm() { - var $form = $('.lichess_overboard'); + function prepareForm($modal) { + var $form = $modal.find('form'); var $timeModeSelect = $form.find('#sf_timeMode'); var $modeChoicesWrap = $form.find('.mode_choice'); var $modeChoices = $modeChoicesWrap.find('input'); @@ -188,10 +188,9 @@ module.exports = function(cfg, element) { var $incrementInput = $form.find('.increment_choice [name=increment]'); var $daysInput = $form.find('.days_choice [name=days]'); var typ = $form.data('type'); - var $ratings = $form.find('.ratings > div'); + var $ratings = $modal.find('.ratings > div'); var randomColorVariants = $form.data('random-color-variants').split(','); - var $submits = $form.find('.color_submits button'); - var $formTag = $form.find('form'); + var $submits = $form.find('.color-submits__button'); var toggleButtons = function() { var variantId = $variantSelect.val(); var timeMode = $timeModeSelect.val(); @@ -211,7 +210,7 @@ module.exports = function(cfg, element) { var aiOk = typ != 'ai' || variantId != '3' || limit >= 1; if (timeOk && ratedOk && aiOk) { $submits.toggleClass('nope', false); - $submits.filter(':not(.random)').toggle(!rated || randomColorVariants.indexOf(variantId) === -1); + $submits.filter(':not(.random)').toggle(!rated || !randomColorVariants.includes(variantId)); } else $submits.toggleClass('nope', true); }; var showRating = function() { @@ -219,6 +218,7 @@ module.exports = function(cfg, element) { var key; switch ($variantSelect.val()) { case '1': + case '3': if (timeMode == '1') { var time = $timeInput.val() * 60 + $incrementInput.val() * 40; if (time < 30) key = 'ultraBullet'; @@ -263,11 +263,11 @@ module.exports = function(cfg, element) { .attr('title', cfg.trans('youNeedAnAccountToDoThat')); } var ajaxSubmit = function(color) { - var poolMember = hookToPoolMember(color, $formTag.serializeArray(), $ratings); - $form.find('a.close').click(); + var poolMember = hookToPoolMember(color, $form.serializeArray(), $ratings); + $.modal.close(); var call = { - url: $formTag.attr('action').replace(/uid-placeholder/, lichess.StrongSocket.sri), - data: $formTag.serialize() + "&color=" + color, + url: $form.attr('action').replace(/uid-placeholder/, lichess.StrongSocket.sri), + data: $form.serialize() + "&color=" + color, type: 'post' }; if (poolMember) { @@ -281,10 +281,10 @@ module.exports = function(cfg, element) { $submits.click(function() { return ajaxSubmit($(this).val()); }).attr('disabled', false); - $formTag.submit(function() { + $form.submit(function() { return ajaxSubmit('random'); }); - } else $formTag.one('submit', function() { + } else $form.one('submit', function() { $submits.hide().end().append(lichess.spinnerHtml); }); if (blindMode) { @@ -329,7 +329,7 @@ module.exports = function(cfg, element) { } })); }); - $form.find('.rating_range').each(function() { + $form.find('.rating-range').each(function() { var $this = $(this); var $input = $this.find("input"); var $span = $this.siblings("span.range"); @@ -360,7 +360,7 @@ module.exports = function(cfg, element) { }).trigger('change'); var $fenInput = $fenPosition.find('input'); - var validateFen = lichess.fp.debounce(function() { + var validateFen = lichess.debounce(function() { $fenInput.removeClass("success failure"); var fen = $fenInput.val(); if (fen) { @@ -375,13 +375,13 @@ module.exports = function(cfg, element) { $fenPosition.find('a.board_editor').each(function() { $(this).attr('href', $(this).attr('href').replace(/editor\/.+$/, "editor/" + fen)); }); - $form.find('.color_submits button').removeClass('nope'); + $submits.removeClass('nope'); lichess.pubsub.emit('content_loaded')(); }, error: function() { $fenInput.addClass("failure"); $fenPosition.find('.preview').html(""); - $form.find('.color_submits button').addClass('nope'); + $submits.addClass('nope'); } }); } @@ -404,33 +404,28 @@ module.exports = function(cfg, element) { $form.find('div.level').each(function() { var $infos = $(this).find('.ai_info > div'); - $(this).find('label').mouseenter(function() { + $(this).find('label').on('mouseenter', function() { $infos.hide().filter('.' + $(this).attr('for')).show(); }); - $(this).find('#config_level').mouseleave(function() { + $(this).find('#config_level').on('mouseleave', function() { var level = $(this).find('input:checked').val(); $infos.hide().filter('.sf_level_' + level).show(); }).trigger('mouseout'); }); - - $form.find('a.close.icon').click(function() { - $form.remove(); - $startButtons.find('a.active').removeClass('active'); - return false; - }); } var clickEvent = blindMode ? 'click' : 'mousedown'; - $startButtons.find('a').not('.disabled').on(clickEvent, function() { - lichess.loadCss('stylesheets/setup.css'); + $startButtons.find('a:not(.disabled)').on(clickEvent, function() { + $(this).addClass('active').siblings().removeClass('active'); + lichess.loadCssPath('lobby.setup'); lobby.leavePool(); $.ajax({ url: $(this).attr('href'), success: function(html) { - $('.lichess_overboard').remove(); - $('#hooks_wrap').prepend(html); - prepareForm(); + prepareForm($.modal(html, 'game-setup', () => { + $startButtons.find('.active').removeClass('active'); + })); lichess.pubsub.emit('content_loaded')(); }, error: function(res) { @@ -438,16 +433,14 @@ module.exports = function(cfg, element) { lichess.reload(); } }); - $(this).addClass('active').siblings().removeClass('active'); - $('.lichess_overboard').remove(); return false; }).on('click', function() { return false; }); - if (['#ai', '#friend', '#hook'].indexOf(location.hash) !== -1) { + if (['#ai', '#friend', '#hook'].includes(location.hash)) { $startButtons - .find('a.config_' + location.hash.replace('#', '')) + .find('.config_' + location.hash.replace('#', '')) .each(function() { $(this).attr("href", $(this).attr("href") + location.search); }).trigger(clickEvent); diff --git a/ui/lobby/src/ctrl.ts b/ui/lobby/src/ctrl.ts index 658e416f48..592309df19 100644 --- a/ui/lobby/src/ctrl.ts +++ b/ui/lobby/src/ctrl.ts @@ -14,7 +14,6 @@ export default class LobbyController { opts: LobbyOpts; data: LobbyData; playban: any; - currentGame: any; isBot: boolean; socket: LobbySocket; stores: Stores; @@ -40,7 +39,6 @@ export default class LobbyController { this.data.hooks = []; this.pools = opts.pools; this.playban = opts.playban; - this.currentGame = opts.currentGame; this.isBot = opts.data.me && opts.data.me.isBot; this.redraw = redraw; @@ -50,14 +48,13 @@ export default class LobbyController { this.stores = makeStores(this.data.me ? this.data.me.username.toLowerCase() : null); this.tab = this.isBot ? 'now_playing' : this.stores.tab.get(), - this.mode = this.stores.mode.get(), - this.sort = this.stores.sort.get(), - this.trans = opts.trans; + this.mode = this.stores.mode.get(), + this.sort = this.stores.sort.get(), + this.trans = opts.trans; this.poolInStorage = li.storage.make('lobby.pool-in'); - this.poolInStorage.listen(e => { // when another tab joins a pool - if (!e.newValue || e.newValue === li.StrongSocket.sri) return; // same tab, doh, IE 11 - this.leavePool(); + this.poolInStorage.listen(() => { // when another tab joins a pool + this.leavePool(); redraw(); }); this.flushHooksSchedule(); @@ -205,7 +202,7 @@ export default class LobbyController { private startWatching() { const newIds = this.data.nowPlaying .map(p => p.gameId) - .filter(id => this.alreadyWatching.indexOf(id) === -1); + .filter(id => !this.alreadyWatching.includes(id)); if (newIds.length) { setTimeout(() => this.socket.send("startWatching", newIds.join(' ')), 2000); newIds.forEach(id => this.alreadyWatching.push(id)); @@ -235,11 +232,11 @@ export default class LobbyController { // after click on round "new opponent" button private onNewOpponent() { - if (location.hash.indexOf('#pool/') === 0) { + if (location.hash.startsWith('#pool/')) { const regex = /^#pool\/(\d+\+\d+)(?:\/(.+))?$/, - match = regex.exec(location.hash), - member: any = { id: match![1], blocking: match![2] }, - range = poolRangeStorage.get(member.id); + match = regex.exec(location.hash), + member: any = { id: match![1], blocking: match![2] }, + range = poolRangeStorage.get(member.id); if (range) member.range = range; if (match) { this.setTab('pools'); diff --git a/ui/lobby/src/filter.ts b/ui/lobby/src/filter.ts index edcb6c3648..818cd275d6 100644 --- a/ui/lobby/src/filter.ts +++ b/ui/lobby/src/filter.ts @@ -8,22 +8,21 @@ interface Filtered { export default function(ctrl: LobbyController, hooks: Hook[]): Filtered { const f = ctrl.data.filter, - seen: string[] = [], - visible: Hook[] = [], - contains = window.lichess.fp.contains; + seen: string[] = [], + visible: Hook[] = []; let variant: string, hidden = 0; hooks.forEach(function(hook) { variant = hook.variant; if (hook.action === 'cancel') visible.push(hook); else { - if (!contains(f.variant, variant) || - !contains(f.mode, hook.ra || 0) || - !contains(f.speed, hook.s || 1 /* ultrabullet = bullet */) || + if (!f.variant.includes(variant) || + !f.mode.includes(hook.ra || 0) || + !f.speed.includes(hook.s || 1 /* ultrabullet = bullet */) || (f.rating && (!hook.rating || (hook.rating < f.rating[0] || hook.rating > f.rating[1])))) { hidden++; } else { - var hash = hook.ra + variant + hook.t + hook.rating; - if (!contains(seen, hash)) visible.push(hook); + const hash = hook.ra + variant + hook.t + hook.rating; + if (!seen.includes(hash)) visible.push(hook); seen.push(hash); } } diff --git a/ui/lobby/src/hookRepo.ts b/ui/lobby/src/hookRepo.ts index cbdfe039f6..62e654d0a7 100644 --- a/ui/lobby/src/hookRepo.ts +++ b/ui/lobby/src/hookRepo.ts @@ -40,7 +40,7 @@ export function remove(ctrl: LobbyController, id) { } export function syncIds(ctrl: LobbyController, ids) { ctrl.data.hooks = ctrl.data.hooks.filter(function(h) { - return ids.indexOf(h.id) !== -1; + return ids.includes(h.id); }); } export function find(ctrl: LobbyController, id) { diff --git a/ui/lobby/src/main.ts b/ui/lobby/src/main.ts index b76e6a97b5..babffe558b 100644 --- a/ui/lobby/src/main.ts +++ b/ui/lobby/src/main.ts @@ -45,5 +45,5 @@ export function start(opts: LobbyOpts) { window.Chessground = Chessground; window.onload = function() { - if (window['lichess_lobby']) boot(window['lichess_lobby'], document.getElementById('hooks_wrap')); + boot(window['lichess_lobby'], document.querySelector('.lobby__app')); }; diff --git a/ui/lobby/src/socket.ts b/ui/lobby/src/socket.ts index d9a1bec19d..6307ae822e 100644 --- a/ui/lobby/src/socket.ts +++ b/ui/lobby/src/socket.ts @@ -13,7 +13,6 @@ export default class LobbySocket { send: SocketSend; handlers: Handlers; - music?: any; constructor(send: SocketSend, ctrl: LobbyController) { @@ -52,15 +51,6 @@ export default class LobbySocket { send('idle', false); ctrl.awake(); }); - - li.pubsub.on('sound_set', (set: string) => { - if (!this.music && set === 'music') - li.loadScript('javascripts/music/lobby.js').then(() => { - this.music = window['lichessLobbyMusic'](); - ctrl.setMode('chart'); - }); - if (this.music && set !== 'music') this.music = undefined; - }); } realTimeIn() { @@ -84,7 +74,6 @@ export default class LobbySocket { }; receive = (type: string, data: any): boolean => { - if (this.music) this.music.receive(type, data); if (this.handlers[type]) { this.handlers[type](data); return true; diff --git a/ui/lobby/src/store.ts b/ui/lobby/src/store.ts index bd55c99c7e..b907ddb63b 100644 --- a/ui/lobby/src/store.ts +++ b/ui/lobby/src/store.ts @@ -13,26 +13,26 @@ export interface Stores { interface Config { key: string; - fix(v: string): A; + fix(v: string | null): A; } const tab: Config = { key: 'lobby.tab', - fix(t: string): Tab { + fix(t: string | null): Tab { if (t) return t as Tab; return 'pools'; } }; const mode: Config = { key: 'lobby.mode', - fix(m: string): Mode { + fix(m: string | null): Mode { if (m) return m as Mode; return 'list'; } }; const sort: Config = { key: 'lobby.sort', - fix(s: string): Sort { + fix(s: string | null): Sort { if (s) return s as Sort; return 'rating'; } diff --git a/ui/lobby/src/view/correspondence.ts b/ui/lobby/src/view/correspondence.ts index 0cffc64d55..e8532ba642 100644 --- a/ui/lobby/src/view/correspondence.ts +++ b/ui/lobby/src/view/correspondence.ts @@ -40,7 +40,7 @@ function createSeek(ctrl: LobbyController): VNode | undefined { export default function(ctrl: LobbyController): MaybeVNodes { return [ - h('table.table_wrap', [ + h('table.hooks__list', [ h('thead', [ h('tr', ['', 'player', 'rating', 'time', 'mode'].map(header => h('th', ctrl.trans(header)))) ]), diff --git a/ui/lobby/src/view/main.ts b/ui/lobby/src/view/main.ts index be5d24348e..911f8e98e2 100644 --- a/ui/lobby/src/view/main.ts +++ b/ui/lobby/src/view/main.ts @@ -10,7 +10,6 @@ import LobbyController from '../ctrl'; export default function(ctrl: LobbyController) { let body, data: VNodeData = {}; - if (ctrl.playban || ctrl.currentGame) return h('div#hooks_wrap'); if (ctrl.redirecting) body = spinner(); else switch (ctrl.tab) { case 'pools': @@ -27,8 +26,8 @@ export default function(ctrl: LobbyController) { body = renderPlaying(ctrl); break; } - return h('div#hooks_wrap', [ - h('div.tabs', renderTabs(ctrl)), - h('div.lobby_box.' + (ctrl.redirecting ? 'redir' : ctrl.tab), data, body) + return h('div.lobby__app.lobby__app-' + ctrl.tab, [ + h('div.tabs-horiz', renderTabs(ctrl)), + h('div.lobby__app__content.l' + (ctrl.redirecting ? 'redir' : ctrl.tab), data, body) ]); }; diff --git a/ui/lobby/src/view/playing.ts b/ui/lobby/src/view/playing.ts index b1b24b50a3..274b02e1b3 100644 --- a/ui/lobby/src/view/playing.ts +++ b/ui/lobby/src/view/playing.ts @@ -14,30 +14,28 @@ function timer(pov) { } export default function(ctrl: LobbyController) { - return h('div#now_playing', + return h('div.now-playing', ctrl.data.nowPlaying.map(function(pov) { - return h('a.mini_board.is2d.' + pov.variant.key + (pov.isMyTurn ? '.my_turn' : ''), { + return h('a.' + pov.variant.key + (pov.isMyTurn ? '.my_turn' : ''), { key: pov.gameId, attrs: { href: '/' + pov.fullId } }, [ - h('div', [ - h('div.cg-board-wrap', { - hook: { - insert(vnode) { - const lm = pov.lastMove; - Chessground(vnode.elm as HTMLElement, { - coordinates: false, - drawable: { enabled: false, visible: false }, - resizable: false, - viewOnly: true, - orientation: pov.variant.key === 'racingKings' ? 'white' : pov.color, - fen: pov.fen, - lastMove: lm && [lm[0] + lm[1], lm[2] + lm[3]] - }); - } + h('div.mini-board.cg-board-wrap.is2d', { + hook: { + insert(vnode) { + const lm = pov.lastMove; + Chessground(vnode.elm as HTMLElement, { + coordinates: false, + drawable: { enabled: false, visible: false }, + resizable: false, + viewOnly: true, + orientation: pov.variant.key === 'racingKings' ? 'white' : pov.color, + fen: pov.fen, + lastMove: lm && [lm[0] + lm[1], lm[2] + lm[3]] + }); } - }, [ h('div.cg-board') ]) - ]), + } + }, [h('div.cg-board')]), h('span.meta', [ pov.opponent.ai ? ctrl.trans('aiNameLevelAiLevel', 'Stockfish', pov.opponent.ai) : pov.opponent.username, h('span.indicator', diff --git a/ui/lobby/src/view/pools.ts b/ui/lobby/src/view/pools.ts index f8e8ffd6b1..7fc5392f69 100644 --- a/ui/lobby/src/view/pools.ts +++ b/ui/lobby/src/view/pools.ts @@ -11,7 +11,7 @@ export function hooks(ctrl: LobbyController): Hooks { return bind('click', e => { const id = (e.target as HTMLElement).getAttribute('data-id') || ((e.target as HTMLElement).parentNode as HTMLElement).getAttribute('data-id'); - if (id === 'custom') $('#start_buttons .config_hook').mousedown(); + if (id === 'custom') $('.config_hook').trigger('mousedown'); else if (id) ctrl.clickPool(id); }, ctrl.redraw); } @@ -21,7 +21,7 @@ export function render(ctrl: LobbyController) { return ctrl.pools.map(pool => { const active = !!member && member.id === pool.id, transp = !!member && !active; - return h('div.pool', { + return h('div', { class: { active, transp: !active && transp diff --git a/ui/lobby/src/view/realTime/chart.ts b/ui/lobby/src/view/realTime/chart.ts index 94605b9fb3..9af07a5a09 100644 --- a/ui/lobby/src/view/realTime/chart.ts +++ b/ui/lobby/src/view/realTime/chart.ts @@ -4,8 +4,8 @@ import LobbyController from '../../ctrl'; import { Hook } from '../../interfaces'; import { bind, perfIcons } from '../util'; -function px(v) { - return v + 'px'; +function percents(v) { + return v + '%'; } function ratingLog(a) { @@ -23,30 +23,31 @@ function ratingY(e) { } else { ratio = mid - (ratingLog(1500 - rating) / ratingLog(500)) * mid; } - return Math.round(ratio * 489); + return Math.round(ratio * 100); } +const clockMax = 2000; + function clockX(dur) { function durLog(a) { return Math.log((a - 30) / 200 + 1); } - var max = 2000; - return Math.round(durLog(Math.min(max, dur || max)) / durLog(max) * 489); + return Math.round(durLog(Math.min(clockMax, dur || clockMax)) / durLog(clockMax) * 100); } function renderPlot(ctrl: LobbyController, hook: Hook) { - const bottom = Math.max(0, ratingY(hook.rating) - 7), - left = Math.max(0, clockX(hook.t) - 4), - klass = [ - 'plot.new', - hook.ra ? 'rated' : 'casual', - hook.action === 'cancel' ? 'cancel' : '' - ].join('.'); + const bottom = Math.max(0, ratingY(hook.rating) - 2), + left = Math.max(0, clockX(hook.t) - 2), + klass = [ + 'plot.new', + hook.ra ? 'rated' : 'casual', + hook.action === 'cancel' ? 'cancel' : '' + ].join('.'); return h('span#' + hook.id + '.' + klass, { key: hook.id, attrs: { 'data-icon': perfIcons[hook.perf], - style: `bottom:${px(bottom)};left:${px(left)}` + style: `bottom:${percents(bottom)};left:${percents(left)}` }, hook: { insert(vnode) { @@ -79,8 +80,8 @@ function renderHook(ctrl: LobbyController, hook: Hook): string { } else { html += '' + ctrl.trans('anonymous') + ''; } - html += ' ' + hook.clock + ''; - html += ' ' + ctrl.trans(hook.ra ? 'rated' : 'casual') + ''; + html += hook.clock; + html += ' ' + ctrl.trans(hook.ra ? 'rated' : 'casual') + ''; html += '
    '; return html; } @@ -89,50 +90,44 @@ const xMarks = [1, 2, 3, 5, 7, 10, 15, 20, 30]; function renderXAxis() { const tags: VNode[] = []; - xMarks.forEach(function(v) { + xMarks.forEach(v => { const l = clockX(v * 60); tags.push(h('span.x.label', { - attrs: { style: 'left:' + px(l) } + attrs: { style: 'left:' + percents(l - 1.5) } }, '' + v)); tags.push(h('div.grid.vert', { - attrs: { style: 'width:' + px(l + 7) } + attrs: { style: 'width:' + percents(l) } })); }); return tags; } -const yMarks = [1000, 1200, 1400, 1500, 1600, 1800, 2000]; +const yMarks = [1000, 1200, 1400, 1500, 1600, 1800]; function renderYAxis() { const tags: VNode[] = []; yMarks.forEach(function(v) { const b = ratingY(v); tags.push(h('span.y.label', { - attrs: { style: 'bottom:' + px(b + 5) } + attrs: { style: 'bottom:' + percents(b + 1) } }, '' + v)); tags.push(h('div.grid.horiz', { - attrs: { style: 'height:' + px(b + 4) } + attrs: { style: 'height:' + percents(b + 0.8) } })); }); return tags; } export function toggle(ctrl: LobbyController) { - return h('span.mode_toggle.hint--bottom', { + return h('i.toggle', { key: 'set-mode-list', - attrs: { 'data-hint': ctrl.trans('list') }, + attrs: { title: ctrl.trans.noarg('list'), 'data-icon': '?' }, hook: bind('mousedown', _ => ctrl.setMode('list'), ctrl.redraw) - }, [ - h('span.chart', { - attrs: { 'data-icon': '?' } - }) - ]); + }); } export function render(ctrl: LobbyController, hooks: Hook[]) { - return h('div.hooks_chart', { - key: 'chart' - }, [ + return h('div.hooks__chart', [ h('div.canvas', { hook: bind('click', e => { if ((e.target as HTMLElement).classList.contains('plot')) ctrl.clickHook((e.target as HTMLElement).id); diff --git a/ui/lobby/src/view/realTime/filter.ts b/ui/lobby/src/view/realTime/filter.ts index 0f42481579..4a5f24d6bb 100644 --- a/ui/lobby/src/view/realTime/filter.ts +++ b/ui/lobby/src/view/realTime/filter.ts @@ -4,9 +4,9 @@ import LobbyController from '../../ctrl'; function initialize(ctrl: LobbyController, el) { const $div = $(el), - $ratingRange = $div.find('.rating_range'); + $ratingRange = $div.find('.rating-range'); - const save = window.lichess.fp.debounce(function() { + const save = window.lichess.debounce(function() { const $form = $div.find('form'); $.ajax({ url: $form.attr('action'), @@ -26,14 +26,15 @@ function initialize(ctrl: LobbyController, el) { $div.find('input').change(save); $div.find('button.reset').click(function() { $div.find('label input').prop('checked', true).trigger('change'); - $div.find('.rating_range').each(function(this: HTMLElement) { + $div.find('.rating-range').each(function(this: HTMLElement) { const s = $(this), - values = [s.slider('option', 'min'), s.slider('option', 'max')]; + values = [s.slider('option', 'min'), s.slider('option', 'max')]; s.slider('values', values); changeRatingRange(values); }); + return false; }); - $div.find('button').click(function() { + $div.find('button.apply').click(function() { ctrl.toggleFilter(); ctrl.redraw(); return false; @@ -62,17 +63,14 @@ function initialize(ctrl: LobbyController, el) { } export function toggle(ctrl: LobbyController, nbFiltered: number) { - return h('span.filter_toggle', { + return h('i.toggle.toggle-filter', { class: { active: ctrl.filterOpen }, - hook: bind('mousedown', ctrl.toggleFilter, ctrl.redraw) - }, [ - ctrl.filterOpen ? h('span', { attrs: { 'data-icon': 'L' }}) : h('span.hint--bottom-left', { - attrs: { 'data-hint': ctrl.trans('filterGames') } - }, [ - h('span', { attrs: { 'data-icon': '%' }}) - ]), - nbFiltered > 0 ? h('span.number', '' + nbFiltered) : null - ]); + hook: bind('mousedown', ctrl.toggleFilter, ctrl.redraw), + attrs: { + 'data-icon': ctrl.filterOpen ? 'L' : '%', + title: ctrl.trans.noarg('filterGames') + } + }, nbFiltered > 0 ? '' + nbFiltered : ''); } export interface FilterNode extends HTMLElement { @@ -80,7 +78,7 @@ export interface FilterNode extends HTMLElement { } export function render(ctrl: LobbyController) { - return h('div.hook_filter', { + return h('div.hook__filters', { hook: { insert(vnode) { const el = vnode.elm as FilterNode; diff --git a/ui/lobby/src/view/realTime/list.ts b/ui/lobby/src/view/realTime/list.ts index a7025e1e1d..10b82d46ee 100644 --- a/ui/lobby/src/view/realTime/list.ts +++ b/ui/lobby/src/view/realTime/list.ts @@ -22,12 +22,9 @@ function renderHook(ctrl: LobbyController, hook: Hook) { }, hook.u) : 'Anonymous'), (hook.rating ? hook.rating : '') + (hook.prov ? '?' : ''), hook.clock, - h('span', [ - h('span.varicon', { - attrs: { 'data-icon': perfIcons[hook.perf] } - }), - noarg(hook.ra ? 'rated' : 'casual') - ]) + h('span', { + attrs: { 'data-icon': perfIcons[hook.perf] } + }, noarg(hook.ra ? 'rated' : 'casual')) ])); } @@ -46,23 +43,19 @@ function isNotMine(hook) { } export function toggle(ctrl: LobbyController) { - return h('span.mode_toggle.hint--bottom', { + return h('i.toggle', { key: 'set-mode-chart', - attrs: { 'data-hint': ctrl.trans('graph') }, + attrs: { title: ctrl.trans.noarg('graph'), 'data-icon': '9' }, hook: bind('mousedown', _ => ctrl.setMode('chart'), ctrl.redraw) - }, [ - h('span.chart', { - attrs: { 'data-icon': '9' } - }) - ]); + }); } export function render(ctrl: LobbyController, allHooks: Hook[]) { const mine = allHooks.find(isMine), - max = mine ? 13 : 14, - hooks = allHooks.slice(0, max), - render = (hook: Hook) => renderHook(ctrl, hook), - standards = hooks.filter(isNotMine).filter(isStandard(true)); + max = mine ? 13 : 14, + hooks = allHooks.slice(0, max), + render = (hook: Hook) => renderHook(ctrl, hook), + standards = hooks.filter(isNotMine).filter(isStandard(true)); hookRepo.sort(ctrl, standards); const variants = hooks.filter(isNotMine).filter(isStandard(false)) .slice(0, Math.max(0, max - standards.length - 1)); @@ -79,9 +72,7 @@ export function render(ctrl: LobbyController, allHooks: Hook[]) { ...variants.map(render) ]; if (mine) renderedHooks.unshift(render(mine)); - return h('table.table_wrap', { - key: 'list' - }, [ + return h('table.hooks__list', [ h('thead', h('tr', [ h('th'), @@ -107,11 +98,11 @@ export function render(ctrl: LobbyController, allHooks: Hook[]) { class: { stepping: ctrl.stepping }, hook: bind('click', e => { let el = e.target as HTMLElement - do { - el = el.parentNode as HTMLElement; - if (el.nodeName === 'TR') return ctrl.clickHook(el.getAttribute('data-id')!); - } - while (el.nodeName !== 'TABLE'); + do { + el = el.parentNode as HTMLElement; + if (el.nodeName === 'TR') return ctrl.clickHook(el.getAttribute('data-id')!); + } + while (el.nodeName !== 'TABLE'); }, ctrl.redraw) }, renderedHooks) ]); diff --git a/ui/lobby/src/view/tabs.ts b/ui/lobby/src/view/tabs.ts index cc35acaa9e..ca50769a20 100644 --- a/ui/lobby/src/view/tabs.ts +++ b/ui/lobby/src/view/tabs.ts @@ -4,10 +4,10 @@ import LobbyController from '../ctrl'; import { MaybeVNodes, Tab } from '../interfaces'; function tab(ctrl: LobbyController, key: Tab, active: Tab, content: MaybeVNodes) { - return h('a', { + return h('span', { class: { active: key === active, - glow: key !== active && key === 'pools' && !!ctrl.poolMember + glowing: key !== active && key === 'pools' && !!ctrl.poolMember }, hook: bind('mousedown', _ => ctrl.setTab(key), ctrl.redraw) }, content); @@ -24,7 +24,7 @@ export default function(ctrl: LobbyController) { ctrl.isBot ? undefined : tab(ctrl, 'seeks', active, [ctrl.trans.noarg('correspondence')]), (active === 'now_playing' || ctrl.data.nbNowPlaying > 0 || ctrl.isBot) ? tab(ctrl, 'now_playing', active, [ ctrl.trans.plural('nbGamesInPlay', ctrl.data.nbNowPlaying), - myTurnPovsNb > 0 ? h('span.unread', myTurnPovsNb) : null + myTurnPovsNb > 0 ? h('i.unread', myTurnPovsNb) : null ]) : null ]; }; diff --git a/ui/lobby/src/xhr.ts b/ui/lobby/src/xhr.ts index e21249e6a5..3682bfd5df 100644 --- a/ui/lobby/src/xhr.ts +++ b/ui/lobby/src/xhr.ts @@ -13,9 +13,7 @@ export function nowPlaying() { return $.ajax({ url: '/account/now-playing', headers: headers - }).then(function(o) { - return o.nowPlaying; - }); + }).then(o => o.nowPlaying); } export function anonPoolSeek(pool) { diff --git a/ui/lobby/tsconfig.json b/ui/lobby/tsconfig.json index 80ef171839..288a14cc53 100644 --- a/ui/lobby/tsconfig.json +++ b/ui/lobby/tsconfig.json @@ -9,7 +9,8 @@ "noImplicitReturns": true, "noImplicitThis": true, "noUnusedParameters": true, - "target": "es5", - "lib": ["DOM", "ES5"] + "moduleResolution": "node", + "target": "ES5", + "lib": ["DOM", "ES5", "es2015.core", "es2015.Promise"] } } diff --git a/ui/notify/css/_notify.scss b/ui/notify/css/_notify.scss new file mode 100644 index 0000000000..2da8fbe6f5 --- /dev/null +++ b/ui/notify/css/_notify.scss @@ -0,0 +1,89 @@ +#notify-app { + @extend %box-radius-left; + overflow: hidden; + width: 25rem; + max-width: 100vw; + right: 0; + + .empty { + text-align: center; + padding: 2rem 0; + } + + .spinner { + margin: 50px auto; + } + + .notifications { + @include transition(opacity); + } + .notifications.scrolling { + opacity: 0.5; + } + + .site_notification { + display: flex; + padding: .6rem 1rem; + border-bottom: $border; + position: relative; + &:hover { + background: $c-bg-zebra; + i { + color: $c-link; + opacity: 0.9; + } + } + &.new { + background: mix($c-new, $c-bg-header-dropdown, 27%); + i { + color: $c-new; + opacity: 0.7; + } + &:hover { + background: mix($c-new, $c-bg-header-dropdown, 36%); + i { + opacity: 1; + } + } + } + i { + font-size: 2em; + opacity: 0.5; + margin-right: 1rem; + } + } + .pager { + display: block; + padding: .5rem; + text-align: center; + &.disabled::before { + opacity: 0.3; + } + &:not(.disabled) { + cursor: pointer; + color: $c-link; + @include transition(); + } + &:not(.disabled):hover { + background: $c-primary; + color: $c-primary-over; + } + &.prev { + border-bottom: $border; + } + } +} +.site_notification .content { + @extend %nowrap-hidden; + flex: 0 1 100%; +} +.site_notification .content span:first-child { + @extend %flex-between; +} +.site_notification .content span:last-child { + @extend %ellipsis; + display: block; +} +.site_notification .content time { + @extend %roboto; +} diff --git a/ui/notify/css/build/_notify.scss b/ui/notify/css/build/_notify.scss new file mode 100644 index 0000000000..556ec07946 --- /dev/null +++ b/ui/notify/css/build/_notify.scss @@ -0,0 +1,5 @@ +@import '../../../common/css/plugin'; + +$c-new: $c-secondary; + +@import '../notify'; diff --git a/ui/notify/css/build/notify.dark.scss b/ui/notify/css/build/notify.dark.scss new file mode 100644 index 0000000000..e867e15a48 --- /dev/null +++ b/ui/notify/css/build/notify.dark.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/dark'; +@import 'notify'; diff --git a/ui/notify/css/build/notify.light.scss b/ui/notify/css/build/notify.light.scss new file mode 100644 index 0000000000..892d2271cb --- /dev/null +++ b/ui/notify/css/build/notify.light.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/light'; +@import 'notify'; diff --git a/ui/notify/css/build/notify.transp.scss b/ui/notify/css/build/notify.transp.scss new file mode 100644 index 0000000000..8350784cd1 --- /dev/null +++ b/ui/notify/css/build/notify.transp.scss @@ -0,0 +1,2 @@ +@import '../../../common/css/theme/transp'; +@import 'notify'; diff --git a/ui/notify/gulpfile.js b/ui/notify/gulpfile.js index af95ae1881..72e5aa34ff 100644 --- a/ui/notify/gulpfile.js +++ b/ui/notify/gulpfile.js @@ -1,3 +1,3 @@ -const lilaGulp = require('../gulp/tsProject.js'); +require('../gulp/tsProject.js')('LichessNotify', 'lichess.notify', __dirname); -lilaGulp('LichessNotify', 'lichess.notify', __dirname); +require('../gulp/cssProject.js')(__dirname); diff --git a/ui/notify/src/ctrl.ts b/ui/notify/src/ctrl.ts index 014e80b6a8..b314f28aec 100644 --- a/ui/notify/src/ctrl.ts +++ b/ui/notify/src/ctrl.ts @@ -1,6 +1,6 @@ -import { Ctrl, NotifyOpts, NotifyData, Redraw } from './interfaces' - -import { asText } from './view' +import { Ctrl, NotifyOpts, NotifyData, Redraw } from './interfaces'; +import notify from 'common/notification'; +import { asText } from './view'; const li = window.lichess; @@ -25,7 +25,7 @@ export default function ctrl(opts: NotifyOpts, redraw: Redraw): Ctrl { if (data.pager.currentPage === 1 && data.unread && opts.isVisible()) { opts.setNotified(); data.unread = 0; - readAllStorage.set('1'); // tell other tabs + readAllStorage.set('' + Math.random()); // tell other tabs } initiating = false; scrolling = false; @@ -36,12 +36,12 @@ export default function ctrl(opts: NotifyOpts, redraw: Redraw): Ctrl { function notifyNew() { if (!data || data.pager.currentPage !== 1) return; - var notif = data.pager.currentPageResults.find(n => !n.read); + const notif = data.pager.currentPageResults.find(n => !n.read); if (!notif) return; opts.pulse(); if (!li.quietMode) li.sound.newPM(); - var text = asText(notif); - if (text) li.desktopNotification(text); + const text = asText(notif); + if (text) notify(text); } function loadPage(page: number) { diff --git a/ui/notify/src/view.ts b/ui/notify/src/view.ts index 5aa34dcd23..3b94d11eae 100644 --- a/ui/notify/src/view.ts +++ b/ui/notify/src/view.ts @@ -7,7 +7,7 @@ export default function(ctrl: Ctrl): VNode { const d = ctrl.data(); - return h('div#notify_app.links.dropdown', + return h('div#notify-app.links.dropdown', d && !ctrl.initiating() ? renderContent(ctrl, d) : [h('div.initiating', spinner())]); } diff --git a/ui/notify/tsconfig.json b/ui/notify/tsconfig.json index 1c393ceda3..17b848bc94 100644 --- a/ui/notify/tsconfig.json +++ b/ui/notify/tsconfig.json @@ -8,7 +8,8 @@ "noImplicitReturns": true, "noImplicitThis": true, "noUnusedParameters": true, - "target": "es5", - "lib": ["DOM", "ES5"] + "moduleResolution": "node", + "target": "ES5", + "lib": ["DOM", "ES5", "es2015.core", "es2015.Promise"] } } diff --git a/ui/nvui/package.json b/ui/nvui/package.json index b1503002a8..04a6f1a0a2 100644 --- a/ui/nvui/package.json +++ b/ui/nvui/package.json @@ -26,8 +26,9 @@ }, "devDependencies": { "@types/lichess": "1.0.0", - "game": "1.0.0", "typescript": "^3" }, - "dependencies": {} + "dependencies": { + "snabbdom": "ornicar/snabbdom#0.7.1-lichess" + } } diff --git a/ui/nvui/src/chess.ts b/ui/nvui/src/chess.ts index a8826eff38..d87350cc90 100644 --- a/ui/nvui/src/chess.ts +++ b/ui/nvui/src/chess.ts @@ -12,14 +12,10 @@ const anna: { [letter: string]: string } = { a: 'anna', b: 'bella', c: 'cesar', const roles: { [letter: string]: string } = { P: 'pawn', R: 'rook', N: 'knight', B: 'bishop', Q: 'queen', K: 'king' }; const letters = { pawn: 'p', rook: 'r', knight: 'n', bishop: 'b', queen: 'q', king: 'k' }; -export function loadCss() { - window.lichess.loadCss('stylesheets/nvui.css'); -} - export function supportedVariant(key: string) { return [ 'standard', 'chess960', 'kingOfTheHill', 'threeCheck', 'fromPosition' - ].indexOf(key) > -1; + ].includes(key); } export function styleSetting(): Setting