Merge branch 'master' into update/kamon-prometheus-2.1.0
|
@ -29,7 +29,7 @@ jobs:
|
|||
- uses: actions/checkout@v2
|
||||
- run: echo "autoformat=false" > ~/.scalariform.conf
|
||||
- name: Work around OverlappingFileLockException
|
||||
run: mount && mkdir -p /tmp/.sbt && ln -s /tmp/.sbt ~/.sbt
|
||||
run: mkdir -p ~/.sbt && sudo mount -t tmpfs -o size=1536m tmpfs ~/.sbt && mount
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.ivy2/cache
|
||||
|
|
|
@ -6,6 +6,9 @@ logs
|
|||
project/project
|
||||
project/target
|
||||
public/compiled
|
||||
public/vendor/bar-rating
|
||||
public/vendor/highcharts-4.2.5
|
||||
public/vendor/hopscotch
|
||||
public/vendor/stockfish.wasm
|
||||
public/vendor/stockfish-mv.wasm
|
||||
public/vendor/stockfish.js
|
||||
|
|
|
@ -4,12 +4,6 @@
|
|||
[submodule "public/vendor/multiple-select"]
|
||||
path = public/vendor/multiple-select
|
||||
url = https://github.com/ornicar/multiple-select
|
||||
[submodule "public/vendor/hopscotch"]
|
||||
path = public/vendor/hopscotch
|
||||
url = https://github.com/linkedin/hopscotch
|
||||
[submodule "public/vendor/shepherd"]
|
||||
path = public/vendor/shepherd
|
||||
url = https://github.com/HubSpot/shepherd
|
||||
[submodule "public/vendor/bar-rating"]
|
||||
path = public/vendor/bar-rating
|
||||
url = https://github.com/antennaio/jquery-bar-rating
|
||||
|
|
|
@ -129,6 +129,9 @@ Allow: /
|
|||
Disallow: /game/export/
|
||||
Disallow: /games/export/
|
||||
Allow: /game/export/gif/thumbnail/
|
||||
|
||||
User-agent: Twitterbot
|
||||
Allow: /
|
||||
"""
|
||||
else "User-agent: *\nDisallow: /"
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ final class Simul(
|
|||
def form = Auth { implicit ctx => me =>
|
||||
NoLameOrBot {
|
||||
apiC.teamsIBelongTo(me) map { teams =>
|
||||
Ok(html.simul.form(forms.create, teams))
|
||||
Ok(html.simul.form(forms.create(me), teams))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -129,16 +129,19 @@ final class Simul(
|
|||
def create = AuthBody { implicit ctx => implicit me =>
|
||||
NoLameOrBot {
|
||||
implicit val req = ctx.body
|
||||
forms.create.bindFromRequest.fold(
|
||||
err =>
|
||||
apiC.teamsIBelongTo(me) map { teams =>
|
||||
BadRequest(html.simul.form(err, teams))
|
||||
},
|
||||
setup =>
|
||||
env.simul.api.create(setup, me) map { simul =>
|
||||
Redirect(routes.Simul.show(simul.id))
|
||||
}
|
||||
)
|
||||
forms
|
||||
.create(me)
|
||||
.bindFromRequest
|
||||
.fold(
|
||||
err =>
|
||||
apiC.teamsIBelongTo(me) map { teams =>
|
||||
BadRequest(html.simul.form(err, teams))
|
||||
},
|
||||
setup =>
|
||||
env.simul.api.create(setup, me) map { simul =>
|
||||
Redirect(routes.Simul.show(simul.id))
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,12 +78,19 @@ final class UserAnalysis(
|
|||
negotiate(
|
||||
html =
|
||||
if (game.replayable) Redirect(routes.Round.watcher(game.id, color)).fuccess
|
||||
else
|
||||
else {
|
||||
val owner = isMyPov(pov)
|
||||
for {
|
||||
initialFen <- env.game.gameRepo initialFen game.id
|
||||
data <- env.api.roundApi
|
||||
.userAnalysisJson(pov, ctx.pref, initialFen, pov.color, owner = isMyPov(pov), me = ctx.me)
|
||||
} yield NoCache(Ok(html.board.userAnalysis(data, pov))),
|
||||
.userAnalysisJson(pov, ctx.pref, initialFen, pov.color, owner = owner, me = ctx.me)
|
||||
} yield NoCache(
|
||||
Ok(
|
||||
html.board
|
||||
.userAnalysis(data, pov, withForecast = owner && !pov.game.synthetic && pov.game.playable)
|
||||
)
|
||||
)
|
||||
},
|
||||
api = apiVersion => mobileAnalysis(pov, apiVersion)
|
||||
)
|
||||
}
|
||||
|
|
|
@ -14,15 +14,13 @@ import controllers.routes
|
|||
|
||||
object userAnalysis {
|
||||
|
||||
def apply(data: JsObject, pov: lila.game.Pov)(implicit ctx: Context) =
|
||||
def apply(data: JsObject, pov: lila.game.Pov, withForecast: Boolean = false)(implicit ctx: Context) =
|
||||
views.html.base.layout(
|
||||
title = trans.analysis.txt(),
|
||||
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"
|
||||
),
|
||||
withForecast option cssTag("analyse.forecast"),
|
||||
ctx.blind option cssTag("round.nvui")
|
||||
),
|
||||
moreJs = frag(
|
||||
|
@ -31,11 +29,7 @@ object userAnalysis {
|
|||
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
|
||||
),
|
||||
"i18n" -> userAnalysisI18n(withForecast = withForecast),
|
||||
"explorer" -> Json.obj(
|
||||
"endpoint" -> explorerEndpoint,
|
||||
"tablebaseEndpoint" -> tablebaseEndpoint
|
||||
|
|
|
@ -34,7 +34,7 @@ object filter {
|
|||
td(trans.timeControl()),
|
||||
td(renderCheckboxes(form, "speed", filter.speed.map(_.id.toString), translatedSpeedChoices))
|
||||
),
|
||||
tr(
|
||||
tr(cls := "inline")(
|
||||
td(trans.increment()),
|
||||
td(
|
||||
renderCheckboxes(
|
||||
|
@ -47,7 +47,7 @@ object filter {
|
|||
)
|
||||
)
|
||||
),
|
||||
ctx.isAuth option tr(
|
||||
ctx.isAuth option tr(cls := "inline")(
|
||||
td(trans.mode()),
|
||||
td(renderCheckboxes(form, "mode", filter.mode.map(_.id.toString), translatedModeChoices))
|
||||
),
|
||||
|
|
|
@ -23,12 +23,19 @@ object form {
|
|||
main(cls := "box box-pad page-small simul-form")(
|
||||
h1(trans.hostANewSimul()),
|
||||
postForm(cls := "form3", action := routes.Simul.create())(
|
||||
br,
|
||||
br,
|
||||
p(trans.whenCreateSimul()),
|
||||
br,
|
||||
br,
|
||||
globalError(form),
|
||||
form3.group(form("name"), trans.name()) { f =>
|
||||
div(
|
||||
form3.input(f),
|
||||
" Simul",
|
||||
br,
|
||||
small(cls := "form-help")(trans.inappropriateNameWarning())
|
||||
)
|
||||
},
|
||||
form3.group(form("variant"), trans.simulVariantsHint()) { _ =>
|
||||
div(cls := "variants")(
|
||||
views.html.setup.filter.renderCheckboxes(
|
||||
|
|
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.1 KiB |
|
@ -34,7 +34,7 @@ case class Hook(
|
|||
|
||||
val isAuth = user.nonEmpty
|
||||
|
||||
val hasIncrement = if (clock.incrementSeconds > 0) 0 else 1
|
||||
val hasIncrement = if (clock.incrementSeconds > 0) 1 else 0
|
||||
|
||||
def compatibleWith(h: Hook) =
|
||||
isAuth == h.isAuth &&
|
||||
|
|
|
@ -142,12 +142,9 @@ object Simul {
|
|||
|
||||
case class OnStart(simul: Simul)
|
||||
|
||||
private def makeName(host: User) =
|
||||
if (host.title.isDefined) host.titleUsername
|
||||
else RandomName()
|
||||
|
||||
def make(
|
||||
host: User,
|
||||
name: String,
|
||||
clock: SimulClock,
|
||||
variants: List[Variant],
|
||||
position: Option[StartingPosition],
|
||||
|
@ -156,7 +153,7 @@ object Simul {
|
|||
team: Option[String]
|
||||
): Simul = Simul(
|
||||
_id = Random nextString 8,
|
||||
name = makeName(host),
|
||||
name = name,
|
||||
status = SimulStatus.Created,
|
||||
clock = clock,
|
||||
hostId = host.id,
|
||||
|
|
|
@ -44,6 +44,7 @@ final class SimulApi(
|
|||
|
||||
def create(setup: SimulForm.Setup, me: User): Fu[Simul] = {
|
||||
val simul = Simul.make(
|
||||
name = setup.name,
|
||||
clock = SimulClock(
|
||||
config = chess.Clock.Config(setup.clockTime * 60, setup.clockIncrement),
|
||||
hostExtraTime = setup.clockExtra * 60
|
||||
|
|
|
@ -2,6 +2,8 @@ package lila.simul
|
|||
|
||||
import play.api.data._
|
||||
import play.api.data.Forms._
|
||||
import play.api.data.validation.{ Constraint, Constraints }
|
||||
import lila.user.User
|
||||
|
||||
import chess.StartingPosition
|
||||
import lila.common.Form._
|
||||
|
@ -28,9 +30,24 @@ object SimulForm {
|
|||
)
|
||||
val colorDefault = "white"
|
||||
|
||||
def create =
|
||||
private val nameType = text.verifying(
|
||||
Constraints minLength 2,
|
||||
Constraints maxLength 40,
|
||||
Constraints.pattern(
|
||||
regex = """[\p{L}\p{N}-\s:,;]+""".r,
|
||||
error = "error.unknown"
|
||||
),
|
||||
Constraint[String] { (t: String) =>
|
||||
if (t.toLowerCase contains "lichess")
|
||||
validation.Invalid(validation.ValidationError("Must not contain \"lichess\""))
|
||||
else validation.Valid
|
||||
}
|
||||
)
|
||||
|
||||
def create(host: User) =
|
||||
Form(
|
||||
mapping(
|
||||
"name" -> nameType,
|
||||
"clockTime" -> numberIn(clockTimeChoices),
|
||||
"clockIncrement" -> numberIn(clockIncrementChoices),
|
||||
"clockExtra" -> numberIn(clockExtraChoices),
|
||||
|
@ -55,6 +72,7 @@ object SimulForm {
|
|||
"team" -> optional(nonEmptyText)
|
||||
)(Setup.apply)(Setup.unapply)
|
||||
) fill Setup(
|
||||
name = host.titleUsername,
|
||||
clockTime = clockTimeDefault,
|
||||
clockIncrement = clockIncrementDefault,
|
||||
clockExtra = clockExtraDefault,
|
||||
|
@ -77,6 +95,7 @@ object SimulForm {
|
|||
def setText = Form(single("text" -> text))
|
||||
|
||||
case class Setup(
|
||||
name: String,
|
||||
clockTime: Int,
|
||||
clockIncrement: Int,
|
||||
clockExtra: Int,
|
||||
|
|
|
@ -2,133 +2,6 @@ package lila
|
|||
|
||||
package object simul extends PackageObject {
|
||||
|
||||
private[simul] object RandomName {
|
||||
|
||||
private val names = IndexedSeq(
|
||||
"Actinium",
|
||||
"Aluminium",
|
||||
"Americium",
|
||||
"Antimony",
|
||||
"Argon",
|
||||
"Arsenic",
|
||||
"Astatine",
|
||||
"Barium",
|
||||
"Berkelium",
|
||||
"Beryllium",
|
||||
"Bismuth",
|
||||
"Bohrium",
|
||||
"Boron",
|
||||
"Bromine",
|
||||
"Cadmium",
|
||||
"Caesium",
|
||||
"Calcium",
|
||||
"Californium",
|
||||
"Carbon",
|
||||
"Cerium",
|
||||
"Chlorine",
|
||||
"Chromium",
|
||||
"Cobalt",
|
||||
"Copernicium",
|
||||
"Copper",
|
||||
"Curium",
|
||||
"Darmstadtium",
|
||||
"Dubnium",
|
||||
"Dysprosium",
|
||||
"Einsteinium",
|
||||
"Erbium",
|
||||
"Europium",
|
||||
"Fermium",
|
||||
"Flerovium",
|
||||
"Fluorine",
|
||||
"Francium",
|
||||
"Gadolinium",
|
||||
"Gallium",
|
||||
"Germanium",
|
||||
"Gold",
|
||||
"Hafnium",
|
||||
"Hassium",
|
||||
"Helium",
|
||||
"Holmium",
|
||||
"Hydrogen",
|
||||
"Indium",
|
||||
"Iodine",
|
||||
"Iridium",
|
||||
"Iron",
|
||||
"Krypton",
|
||||
"Lanthanum",
|
||||
"Lawrencium",
|
||||
"Lead",
|
||||
"Lithium",
|
||||
"Livermorium",
|
||||
"Lutetium",
|
||||
"Magnesium",
|
||||
"Manganese",
|
||||
"Meitnerium",
|
||||
"Mendelevium",
|
||||
"Mercury",
|
||||
"Molybdenum",
|
||||
"Moscovium",
|
||||
"Neodymium",
|
||||
"Neon",
|
||||
"Neptunium",
|
||||
"Nickel",
|
||||
"Nihonium",
|
||||
"Niobium",
|
||||
"Nitrogen",
|
||||
"Nobelium",
|
||||
"Oganesson",
|
||||
"Osmium",
|
||||
"Oxygen",
|
||||
"Palladium",
|
||||
"Phosphorus",
|
||||
"Platinum",
|
||||
"Plutonium",
|
||||
"Polonium",
|
||||
"Potassium",
|
||||
"Praseodymium",
|
||||
"Promethium",
|
||||
"Protactinium",
|
||||
"Radium",
|
||||
"Radon",
|
||||
"Rhenium",
|
||||
"Rhodium",
|
||||
"Roentgenium",
|
||||
"Rubidium",
|
||||
"Ruthenium",
|
||||
"Rutherfordium",
|
||||
"Samarium",
|
||||
"Scandium",
|
||||
"Seaborgium",
|
||||
"Selenium",
|
||||
"Silicon",
|
||||
"Silver",
|
||||
"Sodium",
|
||||
"Strontium",
|
||||
"Sulfur",
|
||||
"Tantalum",
|
||||
"Technetium",
|
||||
"Tellurium",
|
||||
"Tennessine",
|
||||
"Terbium",
|
||||
"Thallium",
|
||||
"Thorium",
|
||||
"Thulium",
|
||||
"Tin",
|
||||
"Titanium",
|
||||
"Tungsten",
|
||||
"Uranium",
|
||||
"Vanadium",
|
||||
"Xenon",
|
||||
"Ytterbium",
|
||||
"Yttrium",
|
||||
"Zinc",
|
||||
"Zirconium"
|
||||
)
|
||||
private val size = names.size
|
||||
|
||||
def apply(): String = names(scala.util.Random nextInt size)
|
||||
}
|
||||
|
||||
private[simul] val logger = lila.log("simul")
|
||||
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ object Dependencies {
|
|||
object kamon {
|
||||
val core = "io.kamon" %% "kamon-core" % "2.0.5"
|
||||
val influxdb = "io.kamon" %% "kamon-influxdb" % "2.0.1-LILA"
|
||||
val metrics = "io.kamon" %% "kamon-system-metrics" % "2.0.2"
|
||||
val metrics = "io.kamon" %% "kamon-system-metrics" % "2.1.0"
|
||||
val prometheus = "io.kamon" %% "kamon-prometheus" % "2.1.0"
|
||||
}
|
||||
|
||||
|
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 177 KiB After Width: | Height: | Size: 176 KiB |
Before Width: | Height: | Size: 662 B After Width: | Height: | Size: 508 B |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 650 B After Width: | Height: | Size: 453 B |
Before Width: | Height: | Size: 488 B After Width: | Height: | Size: 288 B |
Before Width: | Height: | Size: 860 KiB After Width: | Height: | Size: 839 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 511 KiB After Width: | Height: | Size: 252 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 8.4 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 5.1 KiB |
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 80 KiB After Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 736 KiB |
Before Width: | Height: | Size: 812 KiB After Width: | Height: | Size: 607 KiB |
Before Width: | Height: | Size: 486 KiB After Width: | Height: | Size: 353 KiB |
Before Width: | Height: | Size: 469 KiB After Width: | Height: | Size: 343 KiB |
Before Width: | Height: | Size: 387 KiB After Width: | Height: | Size: 288 KiB |
Before Width: | Height: | Size: 420 KiB After Width: | Height: | Size: 298 KiB |
Before Width: | Height: | Size: 483 KiB After Width: | Height: | Size: 350 KiB |
Before Width: | Height: | Size: 909 KiB After Width: | Height: | Size: 614 KiB |
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 629 KiB |
Before Width: | Height: | Size: 837 KiB After Width: | Height: | Size: 605 KiB |
Before Width: | Height: | Size: 652 KiB After Width: | Height: | Size: 334 KiB |
Before Width: | Height: | Size: 684 KiB After Width: | Height: | Size: 417 KiB |
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 641 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 958 KiB After Width: | Height: | Size: 605 KiB |
Before Width: | Height: | Size: 1.6 MiB After Width: | Height: | Size: 855 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 843 KiB After Width: | Height: | Size: 559 KiB |
Before Width: | Height: | Size: 984 KiB After Width: | Height: | Size: 548 KiB |
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 859 KiB After Width: | Height: | Size: 389 KiB |
Before Width: | Height: | Size: 810 KiB After Width: | Height: | Size: 468 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 716 KiB After Width: | Height: | Size: 465 KiB |
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 32 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 68 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 178 KiB After Width: | Height: | Size: 113 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 6.7 KiB |