diff --git a/.github/workflows/assets.yml b/.github/workflows/assets.yml index 21fb93273222d..5ff190698c5d9 100644 --- a/.github/workflows/assets.yml +++ b/.github/workflows/assets.yml @@ -39,7 +39,7 @@ jobs: id: ab - run: pnpm link "$GITHUB_WORKSPACE/ab" if: steps.ab.outcome == 'success' - - run: ./ui/build --no-install -ps + - run: ./ui/build --no-install -p - run: cd ui && pnpm run test && cd - - run: mkdir assets && mv public assets/ && cp bin/download-lifat LICENSE COPYING.md README.md assets/ && git log -n 1 --pretty=oneline > assets/commit.txt - run: cd assets && tar --zstd -cvpf ../assets.tar.zst . && cd - diff --git a/.gitignore b/.gitignore index 1a4e89cd05992..d69e05f00f0ee 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ project/.bloop/ conf/application.conf conf/version.conf +conf/manifest.* logs project/metals.sbt @@ -21,6 +22,7 @@ data/ dist/ node_modules/ local/ +gen/ ui/common/**/*.js ui/common/**/*.d.ts ui/chess/**/*.js diff --git a/.ignore b/.ignore index e445169f606cc..9f530961c0b71 100644 --- a/.ignore +++ b/.ignore @@ -1,7 +1,6 @@ # search ignores vendor translation/dest -ui/*/css/build public/font public/sound public/piece diff --git a/app/Env.scala b/app/Env.scala index efcfdc4d82683..c653f8fd8b1ec 100644 --- a/app/Env.scala +++ b/app/Env.scala @@ -23,6 +23,7 @@ final class Env( SessionCookieBaker ): val net: NetConfig = config.get[NetConfig]("net") + export net.{ domain, baseUrl, assetBaseUrlInternal } given Mode = environment.mode @@ -138,6 +139,7 @@ given ConfigLoader[NetConfig] = ConfigLoader(config => assetBaseUrl = get[AssetBaseUrl]("asset.base_url"), assetBaseUrlInternal = get[AssetBaseUrlInternal]("asset.base_url_internal"), minifiedAssets = get[Boolean]("asset.minified"), + externalManifest = get[Boolean]("asset.external_manifest"), stageBanner = get[Boolean]("stage.banner"), siteName = get[String]("site.name"), socketDomains = get[List[String]]("socket.domains"), diff --git a/app/controllers/Plan.scala b/app/controllers/Plan.scala index 9b3b28753ab4c..a30e997eddba1 100644 --- a/app/controllers/Plan.scala +++ b/app/controllers/Plan.scala @@ -84,6 +84,7 @@ final class Plan(env: Env) extends LilaController(env): res <- info match case Some(info: CustomerInfo.Monthly) => Ok.page(html.plan.indexStripe(me, patron, info, env.plan.stripePublicKey, pricing, gifts)) + case Some(CustomerInfo.OneTime(cus)) => renderIndex(cus.email.map { EmailAddress(_) }, patron.some) case None => diff --git a/app/controllers/RelayRound.scala b/app/controllers/RelayRound.scala index 26c9cf99863b4..9b57a6f6fe2f1 100644 --- a/app/controllers/RelayRound.scala +++ b/app/controllers/RelayRound.scala @@ -220,7 +220,9 @@ final class RelayRound( page <- renderPage: html.relay.show(rt.withStudy(sc.study), data, chat, sVersion, crossSiteIsolation) _ = if HTTPRequest.isHuman(req) then lila.mon.http.path(rt.tour.path).increment() - yield if crossSiteIsolation then Ok(page).enforceCrossSiteIsolation else Ok(page) + yield + if crossSiteIsolation then Ok(page).enforceCrossSiteIsolation + else Ok(page).withHeaders(crossOriginPolicy.unsafe*) )( studyC.privateUnauthorizedFu(oldSc.study), studyC.privateForbiddenFu(oldSc.study) diff --git a/app/templating/AssetHelper.scala b/app/templating/AssetHelper.scala index c98e56b69d4eb..05d004985f9e2 100644 --- a/app/templating/AssetHelper.scala +++ b/app/templating/AssetHelper.scala @@ -7,6 +7,7 @@ import lila.core.net.AssetVersion import lila.core.data.SafeJsonStr import lila.common.String.html.safeJsonValue import lila.web.ui.* +import lila.web.Nonce import lila.web.ContentSecurityPolicy trait AssetHelper: @@ -16,6 +17,12 @@ trait AssetHelper: def env: Env case class PageModule(name: String, data: JsValue | SafeJsonStr) + case class EsmInit(key: String, init: Frag) + type EsmList = List[Option[EsmInit]] + given Conversion[EsmInit, EsmList] with + def apply(esmInit: EsmInit): EsmList = List(Some(esmInit)) + given Conversion[Option[EsmInit], EsmList] with + def apply(esmOption: Option[EsmInit]): EsmList = List(esmOption) private lazy val netDomain = env.net.domain private lazy val assetDomain = env.net.assetDomain @@ -30,6 +37,8 @@ trait AssetHelper: def assetVersion = AssetVersion.current + def updateManifest() = if !env.net.isProd then env.web.manifest.update() + // bump flairs version if a flair is changed only (not added or removed) val flairVersion = "______2" @@ -40,26 +49,8 @@ trait AssetHelper: def flairSrc(flair: Flair): String = staticAssetUrl(s"$flairVersion/flair/img/$flair.webp") - def cssTag(name: String)(using ctx: Context): Frag = - cssTagWithTheme(name, ctx.pref.currentBg) - - def cssTagWithTheme(name: String, theme: String): Frag = - if theme == "system" then - frag( - cssTagWithSimpleTheme(name, "light")(media := "(prefers-color-scheme: light)"), - cssTagWithSimpleTheme(name, "dark")(media := "(prefers-color-scheme: dark)") - ) - else cssTagWithSimpleTheme(name, theme) - - private def cssTagWithSimpleTheme(name: String, theme: String): Tag = - cssAt: - s"css/$name.$theme.${if minifiedAssets then "min" else "dev"}.css" - - def cssTagNoTheme(name: String): Frag = - cssAt(s"css/$name.${if minifiedAssets then "min" else "dev"}.css") - - private def cssAt(path: String): Tag = - link(href := assetUrl(path), rel := "stylesheet") + def cssTag(key: String)(using ctx: Context): Frag = + link(href := staticAssetUrl(s"css/${env.web.manifest.css(key).getOrElse(key)}"), rel := "stylesheet") def jsonScript(json: JsValue | SafeJsonStr, id: String = "page-init-data") = script(tpe := "application/json", st.id := id): @@ -68,40 +59,39 @@ trait AssetHelper: case json: JsValue => safeJsonValue(json).value case json => json.toString - val systemThemePolyfillJs = """ -if (window.matchMedia('(prefers-color-scheme: dark)').media === 'not all') - document.querySelectorAll('[media="(prefers-color-scheme: dark)"]').forEach(e=>e.media='') -""" - // load iife scripts in
and defer def iifeModule(path: String): Frag = script(deferAttr, src := assetUrl(path)) - private val loadEsmFunction = "site.asset.loadEsm" - - // jsModule is esm, no defer needed - def jsModule(name: String): Frag = - script(tpe := "module", src := assetUrl(s"compiled/$name${minifiedAssets.so(".min")}.js")) - - def jsModuleInit(name: String)(using PageContext): Frag = - frag(jsModule(name), embedJsUnsafeLoadThen(s"$loadEsmFunction('$name')")) - def jsModuleInit(name: String, json: SafeJsonStr)(using PageContext): Frag = - frag(jsModule(name), embedJsUnsafeLoadThen(s"$loadEsmFunction('$name',{init:$json})")) - def jsModuleInit[A: Writes](name: String, value: A)(using PageContext): Frag = - jsModuleInit(name, safeJsonValue(Json.toJson(value))) - - def jsModuleInit(name: String, text: SafeJsonStr, nonce: lila.web.Nonce): Frag = - frag(jsModule(name), embedJsUnsafeLoadThen(s"$loadEsmFunction('$name',{init:$text})", nonce)) - def jsModuleInit(name: String, json: JsValue, nonce: lila.web.Nonce): Frag = - jsModuleInit(name, safeJsonValue(json), nonce) - - def jsPageModule(name: String)(using PageContext) = - frag(jsModule(name), embedJsUnsafeLoadThen(s"site.asset.loadPageEsm('$name')")) - - def analyseNvuiTag(using ctx: PageContext) = ctx.blind.option(jsModule("analysisBoard.nvui")) + private val load = "site.asset.loadEsm" + + def jsName(key: String): String = + env.web.manifest.js(key).fold(key)(_.name) + def jsTag(key: String): Frag = + script(tpe := "module", src := staticAssetUrl(s"compiled/${jsName(key)}")) + def jsDeps(keys: List[String]): Frag = frag: + env.web.manifest.deps(keys).map { dep => + script(tpe := "module", src := staticAssetUrl(s"compiled/$dep")) + } + def jsModule(key: String): EsmInit = + EsmInit(key, emptyFrag) + def jsModuleInit(key: String)(using PageContext): EsmInit = + EsmInit(key, embedJsUnsafeLoadThen(s"$load('${jsName(key)}')")) + def jsModuleInit(key: String, json: SafeJsonStr)(using PageContext): EsmInit = + EsmInit(key, embedJsUnsafeLoadThen(s"$load('${jsName(key)}',{init:$json})")) + def jsModuleInit[A: Writes](key: String, value: A)(using PageContext): EsmInit = + jsModuleInit(key, safeJsonValue(Json.toJson(value))) + def jsModuleInit(key: String, text: SafeJsonStr, nonce: Nonce): EsmInit = + EsmInit(key, embedJsUnsafeLoadThen(s"$load('${jsName(key)}',{init:$text})", nonce)) + def jsModuleInit(key: String, json: JsValue, nonce: Nonce): EsmInit = + jsModuleInit(key, safeJsonValue(json), nonce) + def jsPageModule(key: String)(using PageContext): EsmInit = + EsmInit(key, embedJsUnsafeLoadThen(s"site.asset.loadPageEsm('${jsName(key)}')")) + + def analyseNvuiTag(using ctx: PageContext) = ctx.blind.option(jsModule("analyse.nvui")) def puzzleNvuiTag(using ctx: PageContext) = ctx.blind.option(jsModule("puzzle.nvui")) def roundNvuiTag(using ctx: PageContext) = ctx.blind.option(jsModule("round.nvui")) - def infiniteScrollTag(using PageContext) = jsModuleInit("infiniteScroll") - def captchaTag = jsModule("captcha") + def infiniteScrollTag(using PageContext) = jsModuleInit("bits.infiniteScroll") + def captchaTag = jsModule("bits.captcha") def cashTag = iifeModule("javascripts/vendor/cash.min.js") def fingerprintTag = iifeModule("javascripts/fipr.js") def chessgroundTag = script(tpe := "module", src := assetUrl("npm/chessground.min.js")) @@ -126,7 +116,7 @@ if (window.matchMedia('(prefers-color-scheme: dark)').media === 'not all') s""" nonce="$nonce"""" s"""""" - def embedJsUnsafe(js: String, nonce: lila.web.Nonce): Frag = raw: + def embedJsUnsafe(js: String, nonce: Nonce): Frag = raw: s"""""" private val onLoadFunction = "site.load.then" @@ -134,5 +124,5 @@ if (window.matchMedia('(prefers-color-scheme: dark)').media === 'not all') def embedJsUnsafeLoadThen(js: String)(using PageContext): Frag = embedJsUnsafe(s"""$onLoadFunction(()=>{$js})""") - def embedJsUnsafeLoadThen(js: String, nonce: lila.web.Nonce): Frag = + def embedJsUnsafeLoadThen(js: String, nonce: Nonce): Frag = embedJsUnsafe(s"""$onLoadFunction(()=>{$js})""", nonce) diff --git a/app/views/account/layout.scala b/app/views/account/layout.scala index fa27ea43198bd..d9680ad3edc69 100644 --- a/app/views/account/layout.scala +++ b/app/views/account/layout.scala @@ -11,12 +11,14 @@ object layout: title: String, active: String, evenMoreCss: Frag = emptyFrag, - evenMoreJs: Frag = emptyFrag + evenMoreJs: Frag = emptyFrag, + modules: EsmList = Nil )(body: Frag)(using ctx: PageContext): Frag = views.html.base.layout( title = title, moreCss = frag(cssTag("account"), evenMoreCss), - moreJs = frag(jsModule("account"), evenMoreJs) + moreJs = evenMoreJs, + modules = jsModule("bits.account") ++ modules ): def activeCls(c: String) = cls := active.activeO(c) main(cls := "account page-menu")( diff --git a/app/views/account/passwd.scala b/app/views/account/passwd.scala index 8d9aa8d5f0fac..ba4943bb36d93 100644 --- a/app/views/account/passwd.scala +++ b/app/views/account/passwd.scala @@ -12,7 +12,7 @@ object passwd: account.layout( title = trans.site.changePassword.txt(), active = "password", - evenMoreJs = jsModuleInit("passwordComplexity") + modules = jsModuleInit("bits.passwordComplexity") ): div(cls := "box box-pad")( h1(cls := "box__top")(trans.site.changePassword()), diff --git a/app/views/analyse/bits.scala b/app/views/analyse/bits.scala index 4546ebc6e6974..b9fa586448dc8 100644 --- a/app/views/analyse/bits.scala +++ b/app/views/analyse/bits.scala @@ -13,12 +13,14 @@ object bits: pageModule: PageModule, moreCss: Frag = emptyFrag, moreJs: Frag = emptyFrag, + modules: EsmList = Nil, openGraph: Option[lila.web.OpenGraph] = None )(body: Frag)(using PageContext): Frag = views.html.base.layout( title = title, moreCss = moreCss, moreJs = moreJs, + modules = modules, pageModule = pageModule.some, openGraph = openGraph, robots = false, @@ -29,4 +31,4 @@ object bits: def csp(using PageContext) = analysisCsp.withPeer.withInlineIconFont.withChessDbCn.some def analyseModule(mode: String, json: JsObject)(using ctx: PageContext) = - PageModule("analysisBoard", Json.obj("mode" -> mode, "cfg" -> json)) + PageModule("analyse", Json.obj("mode" -> mode, "cfg" -> json)) diff --git a/app/views/analyse/embed.scala b/app/views/analyse/embed.scala index b5df43d5464b6..c8214a23ddfb4 100644 --- a/app/views/analyse/embed.scala +++ b/app/views/analyse/embed.scala @@ -16,7 +16,7 @@ object embed: cssModule = "lpv.embed" )( div(cls := "is2d")(div(pgn)), - jsModule("lpv.embed"), + jsTag("site.lpv.embed"), lpvJs(orientation, getPgn) ) diff --git a/app/views/analyse/replay.scala b/app/views/analyse/replay.scala index 5bccc19eb128e..7f6699b5d00e1 100644 --- a/app/views/analyse/replay.scala +++ b/app/views/analyse/replay.scala @@ -122,7 +122,7 @@ object replay: (pov.game.variant == Crazyhouse).option(cssTag("analyse.zh")), ctx.blind.option(cssTag("round.nvui")) ), - moreJs = analyseNvuiTag, + modules = analyseNvuiTag, pageModule = bits.analyseModule( "replay", Json diff --git a/app/views/appeal/bits.scala b/app/views/appeal/bits.scala index 8cb8cc927d3de..d1b40e6f8c2b1 100644 --- a/app/views/appeal/bits.scala +++ b/app/views/appeal/bits.scala @@ -14,8 +14,5 @@ object bits: cssTag("appeal"), isGranted(_.UserModView).option(cssTag("mod.user")) ), - moreJs = frag( - jsModule("appeal"), - isGranted(_.UserModView).option(jsModule("mod.user")) - ) + modules = jsModule("mod.appeal") ++ isGranted(_.UserModView).so(jsModule("mod.user")) )(body) diff --git a/app/views/auth/bits.scala b/app/views/auth/bits.scala index dc7f343674c3c..27b3429ac7a67 100644 --- a/app/views/auth/bits.scala +++ b/app/views/auth/bits.scala @@ -73,7 +73,7 @@ object bits: views.html.base.layout( title = s"${me.username} - ${trans.site.changePassword.txt()}", moreCss = cssTag("form3"), - moreJs = jsModuleInit("passwordComplexity") + modules = jsModuleInit("bits.passwordComplexity") ): main(cls := "page-small box box-pad")( boxTop( diff --git a/app/views/auth/login.scala b/app/views/auth/login.scala index c244ab91cd65d..79aa874ed4658 100644 --- a/app/views/auth/login.scala +++ b/app/views/auth/login.scala @@ -14,7 +14,7 @@ object login: def apply(form: Form[?], referrer: Option[String])(using PageContext) = views.html.base.layout( title = trans.site.signIn.txt(), - moreJs = jsModuleInit("login", "login"), + modules = jsModuleInit("bits.login", "login"), moreCss = cssTag("auth"), withHrefLangs = lila.core.app.LangPath(routes.Auth.login).some ) { diff --git a/app/views/auth/signup.scala b/app/views/auth/signup.scala index c6da53ca13147..c1e62c481d0ea 100644 --- a/app/views/auth/signup.scala +++ b/app/views/auth/signup.scala @@ -14,11 +14,8 @@ object signup: def apply(form: lila.core.security.HcaptchaForm[?])(using ctx: PageContext) = views.html.base.layout( title = trans.site.signUp.txt(), - moreJs = frag( - jsModuleInit("login", "signup"), - lila.web.views.hcaptcha.script(form), - fingerprintTag - ), + modules = jsModuleInit("bits.login", "signup"), + moreJs = frag(lila.web.views.hcaptcha.script(form), fingerprintTag), moreCss = cssTag("auth"), csp = defaultCsp.withHcaptcha.some, withHrefLangs = LangPath(routes.Auth.signup).some diff --git a/app/views/base/embed.scala b/app/views/base/embed.scala index 6c5b76be5c911..e883874fa2a93 100644 --- a/app/views/base/embed.scala +++ b/app/views/base/embed.scala @@ -15,9 +15,10 @@ object embed: layout.bits.viewport, layout.bits.metaCsp(basicCsp.withNonce(ctx.nonce).withInlineIconFont), st.headTitle(title), + layout.bits.systemThemeEmbedScript, layout.bits.pieceSprite(ctx.pieceSet), - cssTagWithTheme(cssModule, ctx.bg), - (ctx.bg == "system").option(embedJsUnsafe(systemThemePolyfillJs, ctx.nonce)) + cssTag("theme-light"), // includes both light & dark colors + cssTag(cssModule) ), st.body(cls := s"${ctx.bg} highlight ${ctx.boardClass}")( layout.dataSoundSet := SoundSet.silent.key, diff --git a/app/views/base/layout.scala b/app/views/base/layout.scala index d0bf0fdbc654d..c13f69d877224 100644 --- a/app/views/base/layout.scala +++ b/app/views/base/layout.scala @@ -16,9 +16,9 @@ object layout: object bits: val doctype = raw("") - def htmlTag(using lang: Lang) = + def htmlTag(using lang: Lang, ctx: Context) = val isRTL = lila.i18n.LangList.isRTL(lang) - html(st.lang := lang.code, dir := isRTL.option("rtl"), cls := (if isRTL then "dir-rtl" else "dir-ltr")) + html(st.lang := lang.code, dir := isRTL.option("rtl")) val topComment = raw("""""") val charset = raw("""""") val viewport = raw: @@ -28,13 +28,20 @@ object layout: def metaCsp(csp: Option[ContentSecurityPolicy])(using ctx: PageContext): Frag = metaCsp(csp.getOrElse(defaultCsp)) def metaThemeColor(using ctx: PageContext): Frag = - if ctx.pref.bg == lila.pref.Pref.Bg.SYSTEM then - raw: - s"""""" + - s"""""" - else - raw: + raw: + s"""""" + + s"""""" + s"""""" + def systemThemeScript(using ctx: PageContext) = + (ctx.pref.bg === lila.pref.Pref.Bg.SYSTEM).option( + embedJsUnsafe( + "if (window.matchMedia('(prefers-color-scheme: light)')?.matches) " + + "document.documentElement.classList.add('light');" + ) + ) + def systemThemeEmbedScript(using ctx: EmbedContext) = + "" def pieceSprite(using ctx: PageContext): Frag = pieceSprite(ctx.pref.currentPieceSet) def pieceSprite(ps: lila.pref.PieceSet): Frag = link( @@ -180,17 +187,23 @@ object layout: style := "display:inline;width:34px;height:34px;vertical-align:top;margin-right:5px;vertical-align:text-top" ) - private def loadScripts(moreJs: Frag)(using ctx: PageContext) = + // consolidate script packaging here to dedup chunk dependencies + private def modulesPreload(modules: EsmList)(using ctx: PageContext) = + val keys: List[String] = "site" :: { + ctx.data.inquiry.isDefined.option("mod.inquiry") + :: (!netConfig.isProd).option("site.devMode") + :: modules.map(_.map(_.key)) + }.flatten // in head frag( - ctx.needsFp.option(fingerprintTag), - ctx.nonce.map(inlineJs.apply), - frag(cashTag, jsModule("site")), - moreJs, - ctx.data.inquiry.isDefined.option(jsModule("mod.inquiry")), - (ctx.pref.bg == lila.pref.Pref.Bg.SYSTEM).option(embedJsUnsafe(systemThemePolyfillJs)), - (!netConfig.isProd).option(jsModule("devMode")) + jsTag("manifest"), + cashTag, + keys.map(jsTag), + env.web.manifest.deps(keys).map(jsTag) ) + private def modulesInit(modules: EsmList)(using ctx: PageContext) = + modules.flatMap(_.map(_.init)) // in body + private def hrefLang(langStr: String, path: String) = s"""""" @@ -245,6 +258,7 @@ object layout: fullTitle: Option[String] = None, robots: Boolean = netConfig.crawlable, moreCss: Frag = emptyFrag, + modules: EsmList = Nil, moreJs: Frag = emptyFrag, pageModule: Option[PageModule] = None, playing: Boolean = false, @@ -257,9 +271,12 @@ object layout: withHrefLangs: Option[LangPath] = None )(body: Frag)(using ctx: PageContext): Frag = import ctx.pref + updateManifest() frag( doctype, htmlTag( + (ctx.data.inquiry.isEmpty && ctx.impersonatedBy.isEmpty && !ctx.blind) + .option(cls := ctx.pref.themeColorClass), topComment, head( charset, @@ -271,11 +288,12 @@ object layout: if netConfig.isProd then prodTitle else s"${ctx.me.so(_.username + " ")} $prodTitle" , + cssTag("theme-all"), cssTag("site"), pref.is3d.option(cssTag("board-3d")), - ctx.data.inquiry.isDefined.option(cssTagNoTheme("mod.inquiry")), - ctx.impersonatedBy.isDefined.option(cssTagNoTheme("mod.impersonate")), - ctx.blind.option(cssTagNoTheme("blind")), + ctx.data.inquiry.isDefined.option(cssTag("mod.inquiry")), + ctx.impersonatedBy.isDefined.option(cssTag("mod.impersonate")), + ctx.blind.option(cssTag("blind")), moreCss, pieceSprite, meta( @@ -290,7 +308,7 @@ object layout: atomLinkTag | dailyNewsAtom, (pref.bg == lila.pref.Pref.Bg.TRANSPARENT).option(pref.bgImgOrDefault).map { img => raw: - s"""""" }, fontPreload, @@ -298,7 +316,9 @@ object layout: piecesPreload, manifests, jsLicense, - withHrefLangs.map(hrefLangs) + withHrefLangs.map(hrefLangs), + modulesPreload(modules ++ pageModule.so(module => jsPageModule(module.name))), + systemThemeScript ), st.body( cls := { @@ -332,7 +352,7 @@ object layout: dataBoardTheme := pref.currentTheme.name, dataPieceSet := pref.currentPieceSet.name, dataAnnounce := lila.web.AnnounceApi.get.map(a => safeJsonValue(a.json)), - style := zoomable.option(s"--zoom:$pageZoom") + style := zoomable.option(s"---zoom:$pageZoom") )( blindModeForm, ctx.data.inquiry.map { views.html.mod.inquiry(_) }, @@ -372,9 +392,12 @@ object layout: ) ), spinnerMask, - loadScripts(moreJs), - pageModule.map: mod => - frag(jsonScript(mod.data), jsPageModule(mod.name)) + div(id := "inline-scripts")( + frag(ctx.needsFp.option(fingerprintTag), ctx.nonce.map(inlineJs.apply)), + modulesInit(modules ++ pageModule.so(module => jsPageModule(module.name))), + moreJs, + pageModule.map { mod => frag(jsonScript(mod.data)) } + ) ) ) ) @@ -500,6 +523,9 @@ object layout: _ => val qty = lila.i18n.JsQuantity(t.lang) val i18n = safeJsonValue(i18nJsObject(i18nKeys)) - s"""site={load:new Promise(r=>document.addEventListener("DOMContentLoaded",r)),quantity:$qty,siteI18n:$i18n}""" + "if (!window.site) window.site={};" + + """window.site.load=new Promise(r=>document.addEventListener("DOMContentLoaded",r));""" + + s"window.site.quantity=$qty;" + + s"window.site.siteI18n=$i18n;" ) end inlineJs diff --git a/app/views/board/userAnalysis.scala b/app/views/board/userAnalysis.scala index 14d39f5531e56..8d89260ed93ac 100644 --- a/app/views/board/userAnalysis.scala +++ b/app/views/board/userAnalysis.scala @@ -24,7 +24,7 @@ object userAnalysis: withForecast.option(cssTag("analyse.forecast")), ctx.blind.option(cssTag("round.nvui")) ), - moreJs = analyseNvuiTag, + modules = analyseNvuiTag, pageModule = views.html.analyse.bits .analyseModule( "userAnalysis", diff --git a/app/views/clas/bits.scala b/app/views/clas/bits.scala index 467837b2c94e7..776c1a4902592 100644 --- a/app/views/clas/bits.scala +++ b/app/views/clas/bits.scala @@ -19,7 +19,8 @@ object bits: views.html.base.layout( title = title, moreCss = cssTag("clas"), - moreJs = frag(jsModule("clas"), moreJs), + modules = jsModule("bits.clas"), + moreJs = moreJs, csp = csp )( if isGranted(_.Teacher) then diff --git a/app/views/cms.scala b/app/views/cms.scala index 5b0af8b61bee0..6c06b14703ec4 100644 --- a/app/views/cms.scala +++ b/app/views/cms.scala @@ -37,7 +37,7 @@ object cms: views.html.base.layout( title = title, moreCss = cssTag("cms"), - moreJs = jsModule("cms") + modules = jsModule("cms") ): main(cls := "page-menu")(mod.menu("cms"), div(cls := "page-menu__content cms box")(body)) diff --git a/app/views/coach/edit.scala b/app/views/coach/edit.scala index 7f625de53802e..8b5d36b6d4c4b 100644 --- a/app/views/coach/edit.scala +++ b/app/views/coach/edit.scala @@ -32,7 +32,7 @@ object edit: views.html.account.layout( title = s"${c.user.titleUsername} coach page", evenMoreCss = frag(cssTag("coach.editor"), cssTag("tagify")), - evenMoreJs = jsModule("coach.form"), + modules = jsModule("bits.coach.form"), active = "coach" ): div(cls := "coach-edit box")( diff --git a/app/views/coach/index.scala b/app/views/coach/index.scala index bbaba09953493..c1ea9398fe482 100644 --- a/app/views/coach/index.scala +++ b/app/views/coach/index.scala @@ -27,7 +27,7 @@ object index: views.html.base.layout( title = lichessCoaches.txt(), moreCss = cssTag("coach"), - moreJs = infiniteScrollTag, + modules = infiniteScrollTag, withHrefLangs = LangPath(routes.Coach.all(1)).some ): val langSelections = ("all", "All languages") :: lila.i18n.LangPicker diff --git a/app/views/dgt.scala b/app/views/dgt.scala index dfa0933d53ea5..1c77c6bed616b 100644 --- a/app/views/dgt.scala +++ b/app/views/dgt.scala @@ -206,7 +206,7 @@ object dgt: private def layout(path: String, token: Option[String] = None)(body: Modifier*)(using PageContext) = views.html.base.layout( moreCss = cssTag("dgt"), - moreJs = token.fold(jsModuleInit("dgt"))(jsModuleInit("dgt", _)), + modules = token.fold(jsModuleInit("dgt"))(jsModuleInit("dgt", _)), title = playWithDgtBoard.txt(), csp = defaultCsp.withAnyWs.some ): diff --git a/app/views/event.scala b/app/views/event.scala index 1079d18aca8ba..88fe81830ec4d 100644 --- a/app/views/event.scala +++ b/app/views/event.scala @@ -48,7 +48,7 @@ object event: views.html.base.layout( title = e.title, moreCss = cssTag("event"), - moreJs = jsModule("eventCountdown") + modules = jsModule("bits.eventCountdown") ): main(cls := "page-small event box box-pad")( boxTop( @@ -205,7 +205,7 @@ object event: views.html.base.layout( title = title, moreCss = cssTag(css), - moreJs = jsModule("flatpickr") + modules = jsModule("bits.flatpickr") ): main(cls := "page-menu")( mod.menu("event"), diff --git a/app/views/feed.scala b/app/views/feed.scala index b328a2e8f5f0d..dced0684d8bbb 100644 --- a/app/views/feed.scala +++ b/app/views/feed.scala @@ -12,12 +12,15 @@ import lila.feed.Feed.Update object feed: private def layout(title: String, edit: Boolean = false)(using PageContext) = - views.html.site.page.layout( - title = title, - active = "news", - moreCss = cssTag("dailyFeed"), - moreJs = frag(infiniteScrollTag, edit.option(jsModule("flatpickr")), edit.option(jsModule("dailyFeed"))) - ) + views.html.site.page + .layout( + title = title, + active = "news", + moreCss = cssTag("dailyFeed"), + modules = infiniteScrollTag + ++ edit.so(jsModule("bits.flatpickr")) + ++ edit.so(jsModule("bits.dailyFeed")) + ) def index(ups: Paginator[Update])(using PageContext) = layout("Updates"): diff --git a/app/views/fide/bits.scala b/app/views/fide/bits.scala index 5a8ecbd363de8..dd889d190e206 100644 --- a/app/views/fide/bits.scala +++ b/app/views/fide/bits.scala @@ -9,7 +9,7 @@ private object bits: views.html.base.layout( moreCss = cssTag("fide"), title = title, - moreJs = frag(infiniteScrollTag) + modules = infiniteScrollTag ): main(cls := "page-menu")( views.html.relay.tour.pageMenu(active), diff --git a/app/views/forum/categ.scala b/app/views/forum/categ.scala index 8df766be10775..440b57b48d62a 100644 --- a/app/views/forum/categ.scala +++ b/app/views/forum/categ.scala @@ -77,7 +77,7 @@ object categ: views.html.base.layout( title = categ.name, moreCss = cssTag("forum"), - moreJs = infiniteScrollTag, + modules = infiniteScrollTag, csp = defaultCsp.withInlineIconFont.some, openGraph = lila.web .OpenGraph( diff --git a/app/views/forum/search.scala b/app/views/forum/search.scala index d268c8238c602..2b5c63d4a1c47 100644 --- a/app/views/forum/search.scala +++ b/app/views/forum/search.scala @@ -12,7 +12,7 @@ object search: val title = s"""${trans.search.search.txt()} "${text.trim}"""" views.html.base.layout( title = title, - moreJs = infiniteScrollTag, + modules = infiniteScrollTag, moreCss = cssTag("forum") )( main(cls := "box search")( diff --git a/app/views/forum/topic.scala b/app/views/forum/topic.scala index 60ccb7da86242..8be24ac57f332 100644 --- a/app/views/forum/topic.scala +++ b/app/views/forum/topic.scala @@ -17,10 +17,7 @@ object topic: views.html.base.layout( title = "New forum topic", moreCss = cssTag("forum"), - moreJs = frag( - jsModule("forum"), - captchaTag - ) + modules = jsModule("bits.forum") ++ captchaTag ): main(cls := "forum forum-topic topic-form page-small box box-pad")( boxTop( @@ -79,11 +76,8 @@ object topic: )(using ctx: PageContext) = views.html.base.layout( title = s"${topic.name} • page ${posts.currentPage}/${posts.nbPages} • ${categ.name}", - moreJs = frag( - jsModule("forum"), - formWithCaptcha.isDefined.option(captchaTag), - jsModule("expandText") - ), + modules = jsModule("bits.forum") ++ jsModule("bits.expandText") ++ + formWithCaptcha.isDefined.so(captchaTag), moreCss = cssTag("forum"), openGraph = lila.web .OpenGraph( @@ -213,10 +207,7 @@ object topic: views.html.base.layout( title = "Diagnostic report", moreCss = cssTag("forum"), - moreJs = frag( - jsModule("forum"), - captchaTag - ) + modules = jsModule("bits.forum") ++ captchaTag ): main(cls := "forum forum-topic topic-form page-small box box-pad")( boxTop(h1(dataIcon := Icon.BubbleConvo, cls := "text")("Diagnostics")), diff --git a/app/views/mod/communication.scala b/app/views/mod/communication.scala index 3e380826df95e..9927ecf5c8883 100644 --- a/app/views/mod/communication.scala +++ b/app/views/mod/communication.scala @@ -31,8 +31,7 @@ object communication: cssTag("mod.communication"), isGranted(_.UserModView).option(cssTag("mod.user")) ), - moreJs = frag: - isGranted(_.UserModView).option(jsModule("mod.user")) + modules = isGranted(_.UserModView).so(jsModule("mod.user")) ): main(id := "communication", cls := "box box-pad")( boxTop( diff --git a/app/views/mod/games.scala b/app/views/mod/games.scala index 986378b6f1c92..558f180c85a7c 100644 --- a/app/views/mod/games.scala +++ b/app/views/mod/games.scala @@ -28,7 +28,7 @@ object games: views.html.base.layout( title = s"${user.username} games", moreCss = cssTag("mod.games"), - moreJs = jsModule("mod.games") + modules = jsModule("mod.games") ) { main(cls := "mod-games box")( boxTop( diff --git a/app/views/mod/publicChat.scala b/app/views/mod/publicChat.scala index 9164232e7746b..cd17da549b4d9 100644 --- a/app/views/mod/publicChat.scala +++ b/app/views/mod/publicChat.scala @@ -15,7 +15,7 @@ object publicChat: views.html.base.layout( title = "Public Chats", moreCss = cssTag("mod.publicChats"), - moreJs = jsModule("publicChats") + modules = jsModule("mod.publicChats") ): main(cls := "page-menu")( views.html.mod.menu("public-chat"), diff --git a/app/views/mod/search.scala b/app/views/mod/search.scala index 87e8952ac586f..82579dcbafa1e 100644 --- a/app/views/mod/search.scala +++ b/app/views/mod/search.scala @@ -20,7 +20,7 @@ object search: views.html.base.layout( title = "Search users", moreCss = cssTag("mod.misc"), - moreJs = jsModule("mod.search") + modules = jsModule("mod.search") ) { main(cls := "page-menu")( views.html.mod.menu("search"), @@ -48,7 +48,7 @@ object search: views.html.base.layout( title = "Fingerprint", moreCss = cssTag("mod.misc"), - moreJs = jsModule("mod.search") + modules = jsModule("mod.search") ): main(cls := "page-menu")( views.html.mod.menu("search"), @@ -90,7 +90,7 @@ object search: views.html.base.layout( title = "IP address", moreCss = cssTag("mod.misc"), - moreJs = jsModule("mod.search") + modules = jsModule("mod.search") ): main(cls := "page-menu")( views.html.mod.menu("search"), @@ -124,7 +124,7 @@ object search: views.html.base.layout( title = "IP address", moreCss = cssTag("mod.misc"), - moreJs = jsModule("mod.search") + modules = jsModule("mod.search") ): main(cls := "page-menu")( views.html.mod.menu("search"), @@ -187,7 +187,7 @@ object search: views.html.base.layout( title = "Mod notes", moreCss = frag(cssTag("mod.misc"), cssTag("slist")), - moreJs = infiniteScrollTag + modules = infiniteScrollTag ) { main(cls := "page-menu")( views.html.mod.menu("notes"), diff --git a/app/views/plan/index.scala b/app/views/plan/index.scala index 5ea198ef278e8..5ef8a25afdbf9 100644 --- a/app/views/plan/index.scala +++ b/app/views/plan/index.scala @@ -45,12 +45,12 @@ object index: namespaceAttr := "paypalSubscription" ) ), - jsModule("checkout"), embedJsUnsafeLoadThen(s"""checkoutStart("$stripePublicKey", ${safeJsonValue( lila.plan.PlanPricingApi.pricingWrites.writes(pricing) )})""") ) ), + modules = jsModule("bits.checkout"), openGraph = lila.web .OpenGraph( title = becomePatron.txt(), diff --git a/app/views/plan/indexPayPal.scala b/app/views/plan/indexPayPal.scala index 072691c3b3395..0f1ee22707c6b 100644 --- a/app/views/plan/indexPayPal.scala +++ b/app/views/plan/indexPayPal.scala @@ -20,7 +20,8 @@ object indexPayPal: views.html.base.layout( title = thankYou.txt(), moreCss = cssTag("plan"), - moreJs = frag(jsModule("plan"), embedJsUnsafeLoadThen("""plan.payPalStart()""")) + modules = jsModule("bits.plan"), + moreJs = embedJsUnsafeLoadThen("""plan.payPalStart()""") ) { main(cls := "box box-pad plan")( boxTop( diff --git a/app/views/plan/indexStripe.scala b/app/views/plan/indexStripe.scala index 47130ffb8f0e2..9d6813af32dfc 100644 --- a/app/views/plan/indexStripe.scala +++ b/app/views/plan/indexStripe.scala @@ -23,9 +23,9 @@ object indexStripe: views.html.base.layout( title = thankYou.txt(), moreCss = cssTag("plan"), + modules = jsModule("bits.plan"), moreJs = frag( index.stripeScript, - jsModule("plan"), embedJsUnsafeLoadThen(s"""plan.stripeStart("$stripePublicKey")""") ), csp = defaultCsp.withStripe.some diff --git a/app/views/practice/show.scala b/app/views/practice/show.scala index 89b7658373c0b..2618e7a1052df 100644 --- a/app/views/practice/show.scala +++ b/app/views/practice/show.scala @@ -15,9 +15,9 @@ object show: views.html.base.layout( title = us.practiceStudy.name.value, moreCss = cssTag("analyse.practice"), - moreJs = analyseNvuiTag, + modules = List(analyseNvuiTag), pageModule = PageModule( - "analysisBoard.study", + "analyse.study", Json.obj( "practice" -> data.practice, "study" -> data.study, diff --git a/app/views/puzzle/dashboard.scala b/app/views/puzzle/dashboard.scala index ba78d325fad42..c645840059dd9 100644 --- a/app/views/puzzle/dashboard.scala +++ b/app/views/puzzle/dashboard.scala @@ -152,7 +152,7 @@ object dashboard: ), div( cls := s"$metricClass $metricClass--win", - style := s"--first:${results.firstWinPercent}%;--win:${results.winPercent}%" + style := s"---first:${results.firstWinPercent}%;---win:${results.winPercent}%" )( trans.puzzle.percentSolved(strong(s"${results.winPercent}%")) ), diff --git a/app/views/puzzle/embed.scala b/app/views/puzzle/embed.scala index 0d5d6a25b8760..a40fb1b8dfd1e 100644 --- a/app/views/puzzle/embed.scala +++ b/app/views/puzzle/embed.scala @@ -20,7 +20,7 @@ object embed: cls := "embedded" ), chessgroundTag, - jsModule("puzzle.embed") + jsTag("puzzle.embed") ) def dailyLink(daily: DailyPuzzle.WithHtml)(using Translate) = a( diff --git a/app/views/puzzle/history.scala b/app/views/puzzle/history.scala index 4061af133174b..f18b6631b1874 100644 --- a/app/views/puzzle/history.scala +++ b/app/views/puzzle/history.scala @@ -18,7 +18,7 @@ object history: views.html.base.layout( title = title, moreCss = cssTag("puzzle.dashboard"), - moreJs = infiniteScrollTag + modules = infiniteScrollTag )( main(cls := "page-menu")( bits.pageMenu("history", user.some), diff --git a/app/views/puzzle/ofPlayer.scala b/app/views/puzzle/ofPlayer.scala index 36c8b192cd74f..d8beb67fab414 100644 --- a/app/views/puzzle/ofPlayer.scala +++ b/app/views/puzzle/ofPlayer.scala @@ -14,7 +14,7 @@ object ofPlayer: views.html.base.layout( title = user.fold(trans.puzzle.lookupOfPlayer.txt())(u => trans.puzzle.fromXGames.txt(u.username)), moreCss = cssTag("puzzle.page"), - moreJs = infiniteScrollTag + modules = infiniteScrollTag )( main(cls := "page-menu")( bits.pageMenu("player", user), diff --git a/app/views/puzzle/opening.scala b/app/views/puzzle/opening.scala index 5855b13c8f897..9a9cfcf1e3372 100644 --- a/app/views/puzzle/opening.scala +++ b/app/views/puzzle/opening.scala @@ -17,7 +17,7 @@ object opening: views.html.base.layout( title = trans.puzzle.puzzlesByOpenings.txt(), moreCss = cssTag("puzzle.page"), - moreJs = jsModule("puzzle.opening") + modules = jsModule("puzzle.opening") ): main(cls := "page-menu")( bits.pageMenu("openings", ctx.me), diff --git a/app/views/puzzle/show.scala b/app/views/puzzle/show.scala index 95b8533c454d1..04fac8aaeee32 100644 --- a/app/views/puzzle/show.scala +++ b/app/views/puzzle/show.scala @@ -25,7 +25,7 @@ object show: ctx.pref.hasVoice.option(cssTag("voice")), ctx.blind.option(cssTag("round.nvui")) ), - moreJs = puzzleNvuiTag, + modules = puzzleNvuiTag, pageModule = PageModule( "puzzle", Json diff --git a/app/views/relation/bits.scala b/app/views/relation/bits.scala index 43a02eb927c85..a46541b1400ef 100644 --- a/app/views/relation/bits.scala +++ b/app/views/relation/bits.scala @@ -67,7 +67,7 @@ object bits: views.html.base.layout( title = title, moreCss = cssTag("relation"), - moreJs = infiniteScrollTag + modules = infiniteScrollTag ): main(cls := "box page-small")(content) diff --git a/app/views/relay/roundForm.scala b/app/views/relay/roundForm.scala index 379fe829324cc..65ad9525cc755 100644 --- a/app/views/relay/roundForm.scala +++ b/app/views/relay/roundForm.scala @@ -51,7 +51,7 @@ object roundForm: views.html.base.layout( title = title, moreCss = cssTag("relay.form"), - moreJs = jsModule("flatpickr") + modules = jsModule("bits.flatpickr") ): main(cls := "page-small box box-pad")(body) diff --git a/app/views/relay/show.scala b/app/views/relay/show.scala index 046ea581b58d4..46ceb65f9a6dc 100644 --- a/app/views/relay/show.scala +++ b/app/views/relay/show.scala @@ -20,9 +20,9 @@ object show: views.html.base.layout( title = rt.fullName, moreCss = cssTag("analyse.relay"), - moreJs = analyseNvuiTag, + modules = analyseNvuiTag, pageModule = PageModule( - "analysisBoard.study", + "analyse.study", Json .obj( "relay" -> data.relay, diff --git a/app/views/relay/tour.scala b/app/views/relay/tour.scala index 9bb8b3fd65300..8986e42ee4f95 100644 --- a/app/views/relay/tour.scala +++ b/app/views/relay/tour.scala @@ -27,7 +27,7 @@ object tour: views.html.base.layout( title = liveBroadcasts.txt(), moreCss = cssTag("relay.index"), - moreJs = infiniteScrollTag, + modules = infiniteScrollTag, withHrefLangs = LangPath(routes.RelayTour.index()).some ): def nonEmptyTier(selector: RelayTour.Tier.Selector, tier: String) = @@ -61,7 +61,7 @@ object tour: views.html.base.layout( title = liveBroadcasts.txt(), moreCss = cssTag("relay.index"), - moreJs = infiniteScrollTag + modules = infiniteScrollTag )(main(cls := "relay-index page-menu")(div(cls := "page-menu__content box box-pad")(body))) def search(pager: Paginator[WithLastRound], query: String)(using PageContext) = diff --git a/app/views/relay/tourForm.scala b/app/views/relay/tourForm.scala index 678e5f19a1ac1..b22480da88bfd 100644 --- a/app/views/relay/tourForm.scala +++ b/app/views/relay/tourForm.scala @@ -76,7 +76,7 @@ object tourForm: views.html.base.layout( title = title, moreCss = cssTag("relay.form"), - moreJs = jsModule("relayForm") + modules = jsModule("bits.relayForm") )(menu match case Some(active) => main(cls := "page page-menu")( diff --git a/app/views/round/bits.scala b/app/views/round/bits.scala index 88ecbbd1eaf10..9788da4f2508d 100644 --- a/app/views/round/bits.scala +++ b/app/views/round/bits.scala @@ -19,6 +19,7 @@ object bits: title: String, pageModule: Option[PageModule], moreJs: Frag = emptyFrag, + modules: EsmList = Nil, openGraph: Option[lila.web.OpenGraph] = None, moreCss: Frag = emptyFrag, playing: Boolean = false, @@ -37,6 +38,7 @@ object bits: ctx.blind.option(cssTag("round.nvui")), moreCss ), + modules = modules, pageModule = pageModule, playing = playing, zenable = zenable, diff --git a/app/views/round/player.scala b/app/views/round/player.scala index 659200834105b..6446df47ca616 100644 --- a/app/views/round/player.scala +++ b/app/views/round/player.scala @@ -48,7 +48,7 @@ object player: bits.layout( variant = pov.game.variant, title = s"${trans.site.play.txt()} $opponentNameOrZen", - moreJs = frag(roundNvuiTag), + modules = roundNvuiTag, pageModule = PageModule( "round", Json diff --git a/app/views/round/watcher.scala b/app/views/round/watcher.scala index d36eaca353223..fe9a0f107b726 100644 --- a/app/views/round/watcher.scala +++ b/app/views/round/watcher.scala @@ -35,7 +35,7 @@ object watcher: bits.layout( variant = pov.game.variant, title = s"${gameVsText(pov.game, withRatings = ctx.pref.showRatings)} • spectator", - moreJs = frag(roundNvuiTag), + modules = roundNvuiTag, pageModule = PageModule( "round", Json.obj( diff --git a/app/views/search/index.scala b/app/views/search/index.scala index f281244f394f8..a596608c25889 100644 --- a/app/views/search/index.scala +++ b/app/views/search/index.scala @@ -18,10 +18,7 @@ object index: import commons.* views.html.base.layout( title = searchInXGames.txt(nbGames.localize, nbGames), - moreJs = frag( - jsModule("gameSearch"), - infiniteScrollTag - ), + modules = jsModule("bits.gameSearch") ++ infiniteScrollTag, moreCss = cssTag("search") ) { main(cls := "box page-small search")( diff --git a/app/views/simul/form.scala b/app/views/simul/form.scala index c265e2d5c72af..960563543ef7f 100644 --- a/app/views/simul/form.scala +++ b/app/views/simul/form.scala @@ -15,7 +15,7 @@ object form: views.html.base.layout( title = trans.site.hostANewSimul.txt(), moreCss = cssTag("simul.form"), - moreJs = jsModule("flatpickr") + modules = jsModule("bits.flatpickr") ) { main(cls := "box box-pad page-small simul-form")( h1(cls := "box__top")(trans.site.hostANewSimul()), @@ -37,7 +37,7 @@ object form: views.html.base.layout( title = s"Edit ${simul.fullName}", moreCss = cssTag("simul.form"), - moreJs = jsModule("flatpickr") + modules = jsModule("bits.flatpickr") ) { main(cls := "box box-pad page-small simul-form")( h1(cls := "box__top")("Edit ", simul.fullName), diff --git a/app/views/simul/hosted.scala b/app/views/simul/hosted.scala index c5c9665035e09..691c7fa3b40ac 100644 --- a/app/views/simul/hosted.scala +++ b/app/views/simul/hosted.scala @@ -13,7 +13,7 @@ object hosted: views.html.base.layout( title = s"${user.username} hosted simuls", moreCss = cssTag("user-simul"), - moreJs = infiniteScrollTag + modules = infiniteScrollTag ) { main(cls := "page-small box simul-list")( if pager.nbResults == 0 then diff --git a/app/views/site/contact.scala b/app/views/site/contact.scala index a81f192dde775..0a4dcf105a234 100644 --- a/app/views/site/contact.scala +++ b/app/views/site/contact.scala @@ -345,7 +345,7 @@ object contact: title = trans.contact.contact.txt(), active = "contact", moreCss = cssTag("contact"), - moreJs = jsModule("contact"), + modules = jsModule("bits.contact"), contentCls = "page box box-pad" )( frag( diff --git a/app/views/site/lag.scala b/app/views/site/lag.scala index d246f8c9e650e..c5ad7630417ef 100644 --- a/app/views/site/lag.scala +++ b/app/views/site/lag.scala @@ -12,7 +12,7 @@ object lag: title = "Is Lichess lagging?", active = "lag", moreCss = cssTag("lag"), - moreJs = jsModuleInit("chart.lag") + modules = jsModuleInit("chart.lag") ): div(cls := "box box-pad lag")( h1(cls := "box__top")( diff --git a/app/views/site/page.scala b/app/views/site/page.scala index 3f04ab013a707..9159cbd3ac85c 100644 --- a/app/views/site/page.scala +++ b/app/views/site/page.scala @@ -223,11 +223,13 @@ $('#asset-version-message').text(site.info.message);""" active: String, contentCls: String = "", moreCss: Frag = emptyFrag, - moreJs: Frag = emptyFrag + moreJs: Frag = emptyFrag, + modules: EsmList = Nil )(body: Frag)(using PageContext) = views.html.base.layout( title = title, moreCss = moreCss, + modules = modules, moreJs = moreJs ): val sep = div(cls := "sep") diff --git a/app/views/site/variant.scala b/app/views/site/variant.scala index a0d91f8830711..4b9b25a506639 100644 --- a/app/views/site/variant.scala +++ b/app/views/site/variant.scala @@ -54,7 +54,7 @@ object variant: views.html.base.layout( title = title, moreCss = cssTag("variant"), - moreJs = jsModule("expandText"), + modules = jsModule("bits.expandText"), openGraph = openGraph ): main(cls := "page-menu")( diff --git a/app/views/storm.scala b/app/views/storm.scala index 896c2b438f8e9..8da7af7bb5b4e 100644 --- a/app/views/storm.scala +++ b/app/views/storm.scala @@ -63,7 +63,7 @@ object storm: views.html.base.layout( title = s"${user.username} Puzzle Storm", moreCss = frag(cssTag("storm.dashboard")), - moreJs = infiniteScrollTag + modules = infiniteScrollTag )( main(cls := "storm-dashboard page-small")( div(cls := "storm-dashboard__high box box-pad")( diff --git a/app/views/streamer/edit.scala b/app/views/streamer/edit.scala index ef7d36b47970c..3f9d044585114 100644 --- a/app/views/streamer/edit.scala +++ b/app/views/streamer/edit.scala @@ -18,7 +18,7 @@ object edit: )(using ctx: PageContext) = views.html.base.layout( title = s"${s.user.titleUsername} ${lichessStreamer.txt()}", - moreJs = jsModule("streamer"), + modules = jsModule("bits.streamer"), moreCss = cssTag("streamer.form") ) { main(cls := "page-menu")( diff --git a/app/views/streamer/index.scala b/app/views/streamer/index.scala index cfe08047d4dc5..d35a510ac34ff 100644 --- a/app/views/streamer/index.scala +++ b/app/views/streamer/index.scala @@ -62,7 +62,7 @@ object index: views.html.base.layout( title = title, moreCss = cssTag("streamer.list"), - moreJs = frag(infiniteScrollTag, jsModule("streamer")) + modules = infiniteScrollTag ++ jsModule("bits.streamer") ) { main(cls := "page-menu")( bits.menu(if requests then "requests" else "index", none)(cls := " page-menu__menu"), diff --git a/app/views/streamer/show.scala b/app/views/streamer/show.scala index 4c7cde057dedb..a027ae2c1028c 100644 --- a/app/views/streamer/show.scala +++ b/app/views/streamer/show.scala @@ -23,7 +23,7 @@ object show: views.html.base.layout( title = s"${s.titleName} streams chess", moreCss = cssTag("streamer.show"), - moreJs = jsModule("streamer"), + modules = jsModule("bits.streamer"), openGraph = lila.web .OpenGraph( title = s"${s.titleName} streams chess", diff --git a/app/views/study/embed.scala b/app/views/study/embed.scala index 4e093e32632ea..c96e613295f44 100644 --- a/app/views/study/embed.scala +++ b/app/views/study/embed.scala @@ -17,7 +17,7 @@ object embed: cssModule = "lpv.embed" )( div(cls := "is2d")(div(pgn)), - jsModule("lpv.embed"), + jsTag("site.lpv.embed"), lpvJs: lpvConfig(orientation = none, getPgn = canGetPgn) ++ Json .obj() diff --git a/app/views/study/list.scala b/app/views/study/list.scala index 59a07d5ab0bde..2313231fa2c26 100644 --- a/app/views/study/list.scala +++ b/app/views/study/list.scala @@ -100,7 +100,7 @@ object list: title = text, moreCss = cssTag("study.index"), wrapClass = "full-screen-force", - moreJs = infiniteScrollTag + modules = infiniteScrollTag ) { main(cls := "page-menu")( menu("search", Order.default), @@ -182,7 +182,7 @@ object list: title = title, moreCss = cssTag("study.index"), wrapClass = "full-screen-force", - moreJs = infiniteScrollTag, + modules = infiniteScrollTag, withHrefLangs = withHrefLangs ): main(cls := "page-menu")( diff --git a/app/views/study/show.scala b/app/views/study/show.scala index 1b608b1066b54..a3428afd27986 100644 --- a/app/views/study/show.scala +++ b/app/views/study/show.scala @@ -20,9 +20,9 @@ object show: views.html.base.layout( title = s.name.value, moreCss = cssTag("analyse.study"), - moreJs = analyseNvuiTag, + modules = analyseNvuiTag, pageModule = PageModule( - "analysisBoard.study", + "analyse.study", Json.obj( "study" -> data.study .add("admin", isGranted(_.StudyAdmin)) diff --git a/app/views/study/topic.scala b/app/views/study/topic.scala index 0c4792a6c5e0e..8c9b4d1f4e87e 100644 --- a/app/views/study/topic.scala +++ b/app/views/study/topic.scala @@ -15,7 +15,7 @@ object topic: views.html.base.layout( title = trans.study.topics.txt(), moreCss = frag(cssTag("study.index"), cssTag("form3"), cssTag("tagify")), - moreJs = jsModule("study.topic.form"), + modules = jsModule("analyse.study.topic.form"), wrapClass = "full-screen-force" ) { main(cls := "page-menu")( @@ -47,7 +47,7 @@ object topic: title = topic.value, moreCss = cssTag("study.index"), wrapClass = "full-screen-force", - moreJs = infiniteScrollTag + modules = infiniteScrollTag ) { val active = s"topic:$topic" val url = (o: String) => routes.Study.byTopic(topic.value, o) diff --git a/app/views/swiss/form.scala b/app/views/swiss/form.scala index 01fac0db86f7a..b4157bdc3cc8e 100644 --- a/app/views/swiss/form.scala +++ b/app/views/swiss/form.scala @@ -15,7 +15,7 @@ object form: views.html.base.layout( title = trans.swiss.newSwiss.txt(), moreCss = cssTag("swiss.form"), - moreJs = jsModule("tourForm") + modules = jsModule("bits.tourForm") ) { val fields = new SwissFields(form, none) main(cls := "page-small")( @@ -56,7 +56,7 @@ object form: views.html.base.layout( title = swiss.name, moreCss = cssTag("swiss.form"), - moreJs = jsModule("tourForm") + modules = jsModule("bits.tourForm") ) { val fields = new SwissFields(form, swiss.some) main(cls := "page-small")( diff --git a/app/views/swiss/show.scala b/app/views/swiss/show.scala index a25b31b062141..689bf848afa62 100644 --- a/app/views/swiss/show.scala +++ b/app/views/swiss/show.scala @@ -28,7 +28,7 @@ object show: val hasScheduleInput = isDirector && s.settings.manualRounds && s.isNotFinished views.html.base.layout( title = fullName(s, team), - moreJs = frag(hasScheduleInput.option(jsModule("flatpickr"))), + modules = hasScheduleInput.so(jsModule("bits.flatpickr")), pageModule = PageModule( "swiss", Json diff --git a/app/views/team/admin.scala b/app/views/team/admin.scala index d87950be32922..4269921df082f 100644 --- a/app/views/team/admin.scala +++ b/app/views/team/admin.scala @@ -21,7 +21,7 @@ object admin: views.html.base.layout( title = s"${t.name} • ${teamLeaders.txt()}", moreCss = frag(cssTag("team"), cssTag("tagify")), - moreJs = jsModule("team.admin") + modules = jsModule("mod.team.admin") ): val dataLabel = attrData("label") main(cls := "page-menu")( @@ -83,7 +83,7 @@ object admin: views.html.base.layout( title = s"${t.name} • ${kickSomeone.txt()}", moreCss = frag(cssTag("team"), cssTag("tagify")), - moreJs = jsModule("team.admin") + modules = jsModule("mod.team.admin") ): main(cls := "page-menu page-small")( bits.menu(none), diff --git a/app/views/team/bits.scala b/app/views/team/bits.scala index 2d66ea42d8dcb..d9f57b53c4350 100644 --- a/app/views/team/bits.scala +++ b/app/views/team/bits.scala @@ -82,12 +82,14 @@ object bits: openGraph: Option[lila.web.OpenGraph] = None, pageModule: Option[PageModule] = None, moreJs: Frag = emptyFrag, + modules: EsmList = Nil, robots: Boolean = netConfig.crawlable )(body: Frag)(using PageContext) = views.html.base.layout( title = title, moreCss = cssTag("team"), - moreJs = frag(infiniteScrollTag, moreJs), + modules = infiniteScrollTag ++ modules, + moreJs = moreJs, pageModule = pageModule, openGraph = openGraph, robots = robots diff --git a/app/views/team/declinedRequest.scala b/app/views/team/declinedRequest.scala index 3da8957a33780..81aa88351e8fa 100644 --- a/app/views/team/declinedRequest.scala +++ b/app/views/team/declinedRequest.scala @@ -17,7 +17,7 @@ object declinedRequest: views.html.base.layout( title = title, moreCss = frag(cssTag("team")), - moreJs = jsModule("team.admin") + modules = jsModule("mod.team.admin") ) { val pager = views.html.base.bits .paginationByQuery(teamRoutes.declinedRequests(team.id, 1), requests, showPost = true) diff --git a/app/views/team/form.scala b/app/views/team/form.scala index 1e541a5838652..cdf152b95b16d 100644 --- a/app/views/team/form.scala +++ b/app/views/team/form.scala @@ -16,7 +16,7 @@ object form: views.html.base.layout( title = newTeam.txt(), moreCss = cssTag("team"), - moreJs = captchaTag + modules = captchaTag ): main(cls := "page-menu page-small")( bits.menu("form".some), @@ -37,7 +37,7 @@ object form: ) def edit(t: Team, form: Form[?], member: Option[TeamMember])(using ctx: PageContext) = - bits.layout(title = s"Edit Team ${t.name}", moreJs = jsModule("team")): + bits.layout(title = s"Edit Team ${t.name}", modules = jsModule("bits.team")): main(cls := "page-menu page-small team-edit")( bits.menu(none), div(cls := "page-menu__content box box-pad")( diff --git a/app/views/tournament/crud.scala b/app/views/tournament/crud.scala index 22fdccbd69236..89fbde54f820d 100644 --- a/app/views/tournament/crud.scala +++ b/app/views/tournament/crud.scala @@ -13,16 +13,19 @@ import lila.tournament.crud.CrudForm object crud: given prefix: tournament.FormPrefix = tournament.FormPrefix.make("setup") - private def layout(title: String, evenMoreJs: Frag = emptyFrag, css: String = "mod.misc")( + private def layout( + title: String, + modules: EsmList = Nil, + evenMoreJs: Frag = emptyFrag, + css: String = "mod.misc" + )( body: Frag )(using PageContext) = views.html.base.layout( title = title, moreCss = cssTag(css), - moreJs = frag( - jsModule("flatpickr"), - evenMoreJs - ) + modules = jsModule("bits.flatpick") ++ modules, + moreJs = evenMoreJs ) { main(cls := "page-menu")( views.html.mod.menu("tour"), @@ -110,7 +113,7 @@ object crud: def index(tours: Paginator[Tournament])(using PageContext) = layout( title = "Tournament manager", - evenMoreJs = infiniteScrollTag + modules = infiniteScrollTag ) { div(cls := "crud page-menu__content box")( boxTop( diff --git a/app/views/tournament/form.scala b/app/views/tournament/form.scala index c0c0819acf6ea..cb02df3c8d5f5 100644 --- a/app/views/tournament/form.scala +++ b/app/views/tournament/form.scala @@ -17,7 +17,7 @@ object form: views.html.base.layout( title = trans.site.newTournament.txt(), moreCss = cssTag("tournament.form"), - moreJs = jsModule("tourForm") + modules = jsModule("bits.tourForm") ): val fields = TourFields(form, none) main(cls := "page-small")( @@ -94,7 +94,7 @@ object form: views.html.base.layout( title = tour.name(), moreCss = cssTag("tournament.form"), - moreJs = jsModule("tourForm") + modules = jsModule("bits.tourForm") ): TourFields(form, tour.some) main(cls := "page-small")( diff --git a/app/views/tournament/history.scala b/app/views/tournament/history.scala index a69ca7e539722..794a7ea3fa27e 100644 --- a/app/views/tournament/history.scala +++ b/app/views/tournament/history.scala @@ -13,7 +13,7 @@ object history: def apply(freq: Freq, pager: Paginator[Tournament])(using PageContext) = views.html.base.layout( title = "Tournament history", - moreJs = infiniteScrollTag, + modules = infiniteScrollTag, moreCss = cssTag("tournament.history") ) { main(cls := "page-menu arena-history")( diff --git a/app/views/tournament/home.scala b/app/views/tournament/home.scala index 731671421aa24..87249e1d609da 100644 --- a/app/views/tournament/home.scala +++ b/app/views/tournament/home.scala @@ -21,7 +21,7 @@ object home: title = trans.site.tournaments.txt(), moreCss = cssTag("tournament.home"), wrapClass = "full-screen-force", - moreJs = infiniteScrollTag, + modules = infiniteScrollTag, pageModule = PageModule( "tournament.schedule", Json.obj("data" -> json, "i18n" -> bits.scheduleJsI18n) diff --git a/app/views/tournament/teamBattle.scala b/app/views/tournament/teamBattle.scala index 166ff68de9e64..d63e612517f52 100644 --- a/app/views/tournament/teamBattle.scala +++ b/app/views/tournament/teamBattle.scala @@ -14,7 +14,7 @@ object teamBattle: views.html.base.layout( title = tour.name(), moreCss = cssTag("tournament.form"), - moreJs = jsModule("teamBattleForm") + modules = jsModule("bits.teamBattleForm") ): main(cls := "page-small")( div(cls := "tour__form box box-pad")( diff --git a/app/views/tutor/bits.scala b/app/views/tutor/bits.scala index c137cd98f5472..9cb566e37d8ec 100644 --- a/app/views/tutor/bits.scala +++ b/app/views/tutor/bits.scala @@ -32,7 +32,7 @@ object bits: )(content: Modifier*)(using PageContext) = views.html.base.layout( moreCss = cssTag("tutor"), - moreJs = jsModule("tutor"), + modules = jsModule("tutor"), title = title, csp = defaultCsp.withInlineIconFont.some ): diff --git a/app/views/tv/embed.scala b/app/views/tv/embed.scala index 1ca7dc2493516..f0864789d0b23 100644 --- a/app/views/tv/embed.scala +++ b/app/views/tv/embed.scala @@ -19,5 +19,5 @@ object embed: ), cashTag, chessgroundTag, - jsModule("tvEmbed") + jsTag("site.tvEmbed") ) diff --git a/app/views/tv/games.scala b/app/views/tv/games.scala index afceda560459f..686ee4b755d11 100644 --- a/app/views/tv/games.scala +++ b/app/views/tv/games.scala @@ -13,7 +13,7 @@ object games: views.html.base.layout( title = s"${channel.name} • ${trans.site.currentGames.txt()}", moreCss = cssTag("tv.games"), - moreJs = jsModule("tvGames") + modules = jsModule("bits.tvGames") ) { main( cls := "page-menu tv-games", diff --git a/app/views/ublog/blog.scala b/app/views/ublog/blog.scala index cfac8bbda264d..4672551401f00 100644 --- a/app/views/ublog/blog.scala +++ b/app/views/ublog/blog.scala @@ -16,10 +16,7 @@ object blog: val title = trans.ublog.xBlog.txt(user.username) views.html.base.layout( moreCss = cssTag("ublog"), - moreJs = frag( - posts.hasNextPage.option(infiniteScrollTag), - ctx.isAuth.option(jsModule("ublog")) - ), + modules = posts.hasNextPage.option(infiniteScrollTag) ++ ctx.isAuth.so(jsModule("bits.ublog")), title = title, atomLinkTag = link( href := routes.Ublog.userAtom(user.username), diff --git a/app/views/ublog/form.scala b/app/views/ublog/form.scala index eff9b30c89dbc..e1d7c42f5cc59 100644 --- a/app/views/ublog/form.scala +++ b/app/views/ublog/form.scala @@ -19,7 +19,7 @@ object form: def create(user: User, f: Form[UblogPostData], captcha: Captcha)(using PageContext) = views.html.base.layout( moreCss = moreCss, - moreJs = frag(jsModule("ublogForm"), captchaTag), + modules = jsModule("bits.ublogForm") ++ captchaTag, title = s"${trans.ublog.xBlog.txt(user.username)} • ${trans.ublog.newPost.txt()}" ): main(cls := "page-menu page-small")( @@ -35,7 +35,7 @@ object form: def edit(post: UblogPost, f: Form[UblogPostData])(using ctx: PageContext) = views.html.base.layout( moreCss = moreCss, - moreJs = jsModule("ublogForm"), + modules = jsModule("bits.ublogForm"), title = s"${trans.ublog.xBlog.txt(titleNameOrId(post.created.by))} • ${post.title}" ): main(cls := "page-menu page-small")( diff --git a/app/views/ublog/index.scala b/app/views/ublog/index.scala index 8de627e104ec0..b5b17f87f4249 100644 --- a/app/views/ublog/index.scala +++ b/app/views/ublog/index.scala @@ -17,7 +17,7 @@ object index: def drafts(user: User, posts: Paginator[UblogPost.PreviewPost])(using PageContext) = views.html.base.layout( moreCss = frag(cssTag("ublog")), - moreJs = posts.hasNextPage.option(infiniteScrollTag), + modules = posts.hasNextPage.option(infiniteScrollTag), title = trans.ublog.drafts.txt() ) { main(cls := "page-menu")( @@ -72,7 +72,7 @@ object index: def community(language: Option[Language], posts: Paginator[UblogPost.PreviewPost])(using ctx: PageContext) = views.html.base.layout( moreCss = cssTag("ublog"), - moreJs = posts.hasNextPage.option(infiniteScrollTag), + modules = posts.hasNextPage.option(infiniteScrollTag), title = "Community blogs", atomLinkTag = link( href := routes.Ublog.communityAtom(language.fold("all")(_.value)), @@ -158,7 +158,7 @@ object index: )(using PageContext) = views.html.base.layout( moreCss = cssTag("ublog"), - moreJs = posts.hasNextPage.option(infiniteScrollTag), + modules = posts.hasNextPage.option(infiniteScrollTag), title = title ) { main(cls := "page-menu")( diff --git a/app/views/ublog/post.scala b/app/views/ublog/post.scala index 99fc989de6472..c4642dab565c1 100644 --- a/app/views/ublog/post.scala +++ b/app/views/ublog/post.scala @@ -22,10 +22,7 @@ object post: )(using ctx: PageContext) = views.html.base.layout( moreCss = cssTag("ublog"), - moreJs = frag( - jsModule("expandText"), - ctx.isAuth.option(jsModule("ublog")) - ), + modules = jsModule("bits.expandText") ++ ctx.isAuth.so(jsModule("bits.ublog")), title = s"${trans.ublog.xBlog.txt(user.username)} • ${post.title}", openGraph = lila.web .OpenGraph( diff --git a/app/views/user/download.scala b/app/views/user/download.scala index 804effc95c9e3..35e6fa4fd4fab 100644 --- a/app/views/user/download.scala +++ b/app/views/user/download.scala @@ -12,7 +12,7 @@ object download: views.html.base.layout( title = s"${user.username} • ${trans.site.exportGames.txt()}", moreCss = cssTag("search"), - moreJs = jsModule("userGamesDownload") + modules = jsModule("bits.userGamesDownload") ) { main(cls := "box page-small search")( boxTop(h1(userLink(user), s" • ${trans.site.exportGames.txt()}")), diff --git a/app/views/user/perfStat.scala b/app/views/user/perfStat.scala index 089e833c39893..69b4a78f579b6 100644 --- a/app/views/user/perfStat.scala +++ b/app/views/user/perfStat.scala @@ -21,14 +21,13 @@ object perfStat: views.html.base.layout( title = s"${user.username} - ${perfStats.txt(perfType.trans)}", robots = false, - moreJs = frag( - jsModule("user"), - ratingChart.map: rc => + modules = jsModule("bits.user") ++ + ratingChart.map { rc => jsModuleInit( "chart.ratingHistory", SafeJsonStr(s"{data:$rc,singlePerfName:'${perfType.trans(using ctxTrans.translator.toDefault)}'}") - ) - ), + ).some + }, moreCss = cssTag("perf-stat") ): main(cls := s"page-menu")( diff --git a/app/views/user/show/page.scala b/app/views/user/show/page.scala index 4abf9c40306cd..623882195eb78 100644 --- a/app/views/user/show/page.scala +++ b/app/views/user/show/page.scala @@ -31,7 +31,7 @@ object page: ) .some, pageModule = pageModule(info), - moreJs = moreJs(info), + modules = esModules(info), moreCss = frag( cssTag("user.show"), isGranted(_.UserModView).option(cssTag("mod.user")) @@ -60,7 +60,7 @@ object page: views.html.base.layout( title = s"${u.username} $filterName$pageName", pageModule = pageModule(info), - moreJs = moreJs(info, filters.current.name == "search"), + modules = esModules(info, filters.current.name == "search"), moreCss = frag( cssTag("user.show"), (filters.current.name == "search").option(cssTag("user.show.search")), @@ -77,14 +77,12 @@ object page: ) } - private def moreJs(info: UserInfo, withSearch: Boolean = false)(using PageContext) = + private def esModules(info: UserInfo, withSearch: Boolean = false)(using PageContext): EsmList = import play.api.libs.json.Json - frag( - infiniteScrollTag, - jsModuleInit("user", Json.obj("i18n" -> i18nJsObject(i18nKeys))), - withSearch.option(jsModule("gameSearch")), - isGranted(_.UserModView).option(jsModule("mod.user")) - ) + infiniteScrollTag + ++ jsModuleInit("bits.user", Json.obj("i18n" -> i18nJsObject(i18nKeys))) + ++ withSearch.so(jsModule("bits.gameSearch")) + ++ isGranted(_.UserModView).so(jsModule("mod.user")) private def pageModule(info: UserInfo)(using PageContext) = info.ratingChart.map: rc => diff --git a/app/views/userTournament/bits.scala b/app/views/userTournament/bits.scala index fae44e1a61c91..808f1352040c4 100644 --- a/app/views/userTournament/bits.scala +++ b/app/views/userTournament/bits.scala @@ -14,7 +14,7 @@ object bits: u, title = s"${u.username} best tournaments", path = "best", - moreJs = infiniteScrollTag + modules = infiniteScrollTag ): views.html.userTournament.list(u, "best", pager, "BEST") @@ -23,17 +23,17 @@ object bits: u, title = s"${u.username} recent tournaments", path = "recent", - moreJs = infiniteScrollTag + modules = infiniteScrollTag ): views.html.userTournament.list(u, "recent", pager, pager.nbResults.toString) - def layout(u: User, title: String, path: String, moreJs: Frag = emptyFrag)( + def layout(u: User, title: String, path: String, modules: EsmList = Nil)( body: Frag )(using ctx: PageContext) = views.html.base.layout( title = title, moreCss = cssTag("user-tournament"), - moreJs = moreJs + modules = modules ): main(cls := "page-menu")( views.html.base.bits.pageMenuSubnav( diff --git a/app/views/userTournament/created.scala b/app/views/userTournament/created.scala index d922f6f4270c2..7c61e787e8170 100644 --- a/app/views/userTournament/created.scala +++ b/app/views/userTournament/created.scala @@ -16,7 +16,7 @@ object created: u = u, title = s"${u.username} created tournaments", path = path, - moreJs = infiniteScrollTag + modules = infiniteScrollTag ): if pager.nbResults == 0 then div(cls := "box-pad")(trans.site.nothingToSeeHere()) else diff --git a/app/views/video/layout.scala b/app/views/video/layout.scala index ab95ee21599d8..c41ed11c7a3f8 100644 --- a/app/views/video/layout.scala +++ b/app/views/video/layout.scala @@ -15,7 +15,7 @@ object layout: views.html.base.layout( title = title, moreCss = cssTag("video"), - moreJs = infiniteScrollTag, + modules = infiniteScrollTag, wrapClass = "full-screen-force", openGraph = openGraph ): diff --git a/conf/base.conf b/conf/base.conf index c9d52bef8bceb..5b31afae8e13b 100644 --- a/conf/base.conf +++ b/conf/base.conf @@ -19,6 +19,7 @@ net { asset.base_url = "http://"${net.asset.domain} asset.base_url_internal = ${net.asset.base_url} asset.minified = false + asset.external_manifest = false # ignored on prod. true will cause dev builds to fetch manifest from asset.base_url_internal base_url = "http://"${net.domain} email = "" crawlable = false diff --git a/modules/api/src/main/Cli.scala b/modules/api/src/main/Cli.scala index f40b8e1fac9db..ce67b10b4720c 100644 --- a/modules/api/src/main/Cli.scala +++ b/modules/api/src/main/Cli.scala @@ -18,7 +18,8 @@ final private[api] class Cli( video: lila.video.Env, puzzle: lila.puzzle.Env, team: lila.team.Env, - notify: lila.notify.Env + notify: lila.notify.Env, + manifest: lila.web.AssetManifest )(using Executor) extends lila.common.Cli: @@ -32,6 +33,7 @@ final private[api] class Cli( def process = case "uptime" :: Nil => fuccess(s"${lila.common.Uptime.seconds} seconds") case "change" :: ("asset" | "assets") :: "version" :: Nil => + manifest.update() import lila.core.net.AssetVersion val current = AssetVersion.change() Bus.publish(AssetVersion.Changed(current), "assetVersion") diff --git a/modules/api/src/main/Env.scala b/modules/api/src/main/Env.scala index 755f88c2e7d2d..1ae50f6534399 100644 --- a/modules/api/src/main/Env.scala +++ b/modules/api/src/main/Env.scala @@ -60,7 +60,8 @@ final class Env( cmsApi: lila.cms.CmsApi, cacheApi: lila.memo.CacheApi, webConfig: lila.web.WebConfig, - realPlayerApi: lila.web.RealPlayerApi + realPlayerApi: lila.web.RealPlayerApi, + manifest: lila.web.AssetManifest )(using val mode: Mode, scheduler: Scheduler)(using Executor, ActorSystem, diff --git a/modules/core/src/main/config.scala b/modules/core/src/main/config.scala index b8667388b4aea..7a682919cbf00 100644 --- a/modules/core/src/main/config.scala +++ b/modules/core/src/main/config.scala @@ -65,6 +65,7 @@ object config: assetBaseUrl: AssetBaseUrl, assetBaseUrlInternal: AssetBaseUrlInternal, minifiedAssets: Boolean, + externalManifest: Boolean, stageBanner: Boolean, siteName: String, socketDomains: List[String], diff --git a/modules/core/src/main/net.scala b/modules/core/src/main/net.scala index 81c897a09bd73..289254b4e74ce 100644 --- a/modules/core/src/main/net.scala +++ b/modules/core/src/main/net.scala @@ -73,6 +73,7 @@ object net: def change() = stored = random current + private def random = AssetVersion(SecureRandom.nextString(6)) case class Changed(version: AssetVersion) diff --git a/modules/pref/src/main/Pref.scala b/modules/pref/src/main/Pref.scala index fa37b18453811..73a59a8117848 100644 --- a/modules/pref/src/main/Pref.scala +++ b/modules/pref/src/main/Pref.scala @@ -57,6 +57,11 @@ case class Pref( val themeColorLight = "#dbd7d1" val themeColorDark = "#2e2a24" def themeColor = if bg == Bg.LIGHT then themeColorLight else themeColorDark + def themeColorClass = + if bg == Bg.LIGHT then "light".some + else if bg == Bg.TRANSPARENT then "transp".some + else if bg == Bg.SYSTEM then none + else "dark".some def realSoundSet = SoundSet(soundSet) diff --git a/modules/web/src/main/AssetManifest.scala b/modules/web/src/main/AssetManifest.scala new file mode 100644 index 0000000000000..fd845e0ab55fc --- /dev/null +++ b/modules/web/src/main/AssetManifest.scala @@ -0,0 +1,103 @@ +package lila.web + +import play.api.Environment +import play.api.libs.ws.StandaloneWSClient +import play.api.libs.ws.JsonBodyReadables.* +import play.api.libs.json.{ JsObject, Json, JsValue, JsString } +import java.nio.file.{ Files, Path, Paths } + +import lila.core.config.NetConfig + +case class SplitAsset(name: String, imports: List[String]) +case class AssetMaps(js: Map[String, SplitAsset], css: Map[String, String]) + +final class AssetManifest(environment: Environment, net: NetConfig)(using ws: StandaloneWSClient)(using + Executor +): + + private var lastModified: Instant = java.time.Instant.MIN + private var maps: AssetMaps = AssetMaps(Map.empty, Map.empty) + private val filename = s"manifest.${if net.minifiedAssets then "prod" else "dev"}.json" + private val logger = lila.log("assetManifest") + + def js(key: String): Option[SplitAsset] = maps.js.get(key) + def css(key: String): Option[String] = maps.css.get(key) + def deps(keys: List[String]): List[String] = keys.flatMap { key => js(key).so(_.imports) }.distinct + def lastUpdate: Instant = lastModified + + def update(): Unit = + if environment.mode.isProd || net.externalManifest then + fetchManifestJson(filename).foreach: + _.foreach: manifestJson => + maps = readMaps(manifestJson) + lastModified = nowInstant + else + val pathname = environment.getFile(s"public/compiled/$filename").toPath + try + val current = Files.getLastModifiedTime(pathname).toInstant + if current.isAfter(lastModified) then + maps = readMaps(Json.parse(Files.newInputStream(pathname))) + lastModified = current + catch + case e: Throwable => + logger.error(s"Error reading $pathname", e) + + update() + + private val keyRe = """^(?!common\.)(\S+)\.([A-Z0-9]{8})\.(?:js|css)""".r + private def keyOf(fullName: String): String = + fullName match + case keyRe(k, _) => k + case _ => fullName + + private def closure( + name: String, + jsMap: Map[String, SplitAsset], + visited: Set[String] = Set.empty + ): List[String] = + val k = keyOf(name) + jsMap.get(k) match + case Some(asset) if !visited.contains(k) => + asset.imports.flatMap: importName => + importName :: closure(importName, jsMap, visited + name) + case _ => Nil + + // throws an Exception if JsValue is not as expected + private def readMaps(manifest: JsValue): AssetMaps = + val js = (manifest \ "js") + .as[JsObject] + .value + .map { (k, value) => + val name = (value \ "hash").asOpt[String].fold(s"$k.js")(h => s"$k.$h.js") + val imports = (value \ "imports").asOpt[List[String]].getOrElse(Nil) + (k, SplitAsset(name, imports)) + } + .toMap + AssetMaps( + js.map { (k, asset) => + k -> (if asset.imports.nonEmpty then asset.copy(imports = closure(asset.name, js).distinct) + else asset) + }, + (manifest \ "css") + .as[JsObject] + .value + .map { (k, asset) => + val hash = (asset \ "hash").as[String] + (k, s"$k.$hash.css") + } + .toMap + ) + + private def fetchManifestJson(filename: String) = + val resource = s"${net.assetBaseUrlInternal}/assets/compiled/$filename" + ws.url(resource) + .get() + .map: + case res if res.status == 200 => res.body[JsValue].some + case res => + logger.error(s"${res.status} fetching $resource") + none + .recoverWith: + case e: Exception => + logger.error(s"fetching $resource", e) + fuccess(none) diff --git a/modules/web/src/main/Env.scala b/modules/web/src/main/Env.scala index a97034c6f84c7..a0dc29ec12809 100644 --- a/modules/web/src/main/Env.scala +++ b/modules/web/src/main/Env.scala @@ -2,20 +2,22 @@ package lila.web import play.api.libs.ws.StandaloneWSClient import com.softwaremill.macwire.* -import lila.core.config.BaseUrl -import play.api.Configuration @Module final class Env( - appConfig: Configuration, + appConfig: play.api.Configuration, + environment: play.api.Environment, cacheApi: lila.memo.CacheApi, settingStore: lila.memo.SettingStore.Builder, ws: StandaloneWSClient, - baseUrl: BaseUrl + net: lila.core.config.NetConfig )(using mode: play.api.Mode, scheduler: Scheduler)(using Executor): val config = WebConfig.loadFrom(appConfig) export config.{ pagerDuty as pagerDutyConfig } + export net.baseUrl + + val manifest = wire[AssetManifest] val realPlayers = wire[RealPlayerApi] diff --git a/package.json b/package.json index 81bda7d067f9d..df44eff1d50f4 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,6 @@ "metals": "tail -F .metals/metals.log | stdbuf -oL cut -c 21- | rg -v '(notification for request|handleCancellation)'", "serverlog": "pnpm journal & pnpm metals", "multilog": "pnpm serverlog & ui/build -r", - "minilog": "pnpm journal | grep -E -v fishnet & ui/build -cdrs" + "minilog": "pnpm journal | grep -E -v fishnet & ui/build -cdr" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 75b5533c5f08f..8ff52ad71420c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13,16 +13,16 @@ importers: version: link:ui/@types/lichess '@types/node': specifier: ^20.11.28 - version: 20.11.28 + version: 20.12.2 '@types/web': specifier: ^0.0.142 version: 0.0.142 '@typescript-eslint/eslint-plugin': specifier: ^7.2.0 - version: 7.2.0(@typescript-eslint/parser@7.2.0)(eslint@8.57.0)(typescript@5.4.2) + version: 7.5.0(@typescript-eslint/parser@7.5.0)(eslint@8.57.0)(typescript@5.4.3) '@typescript-eslint/parser': specifier: ^7.2.0 - version: 7.2.0(eslint@8.57.0)(typescript@5.4.2) + version: 7.5.0(eslint@8.57.0)(typescript@5.4.3) ab: specifier: github:lichess-org/ab-stub version: github.com/lichess-org/ab-stub/94236bf34dbc9c05daf50f4c9842d859b9142be0 @@ -43,7 +43,7 @@ importers: version: 3.0.2 typescript: specifier: ^5.4.2 - version: 5.4.2 + version: 5.4.3 bin: dependencies: @@ -58,7 +58,7 @@ importers: version: 29.5.12 jest: specifier: ^29.7.0 - version: 29.7.0(@types/node@20.11.28) + version: 29.7.0(@types/node@20.12.2) jest-environment-jsdom: specifier: ^29.7.0 version: 29.7.0 @@ -119,6 +119,69 @@ importers: specifier: workspace:* version: link:../tree + ui/bits: + dependencies: + '@fnando/sparkline': + specifier: ^0.3.10 + version: 0.3.10 + '@textcomplete/core': + specifier: ^0.1.13 + version: 0.1.13 + '@textcomplete/textarea': + specifier: ^0.1.13 + version: 0.1.13(@textcomplete/core@0.1.13) + '@toast-ui/editor': + specifier: 3.1.7 + version: 3.1.7 + '@types/debounce-promise': + specifier: ^3.1.6 + version: 3.1.9 + '@types/fnando__sparkline': + specifier: ^0.3.7 + version: 0.3.7 + '@types/yaireo__tagify': + specifier: 4.17.5 + version: 4.17.5 + '@types/zxcvbn': + specifier: ^4.4.4 + version: 4.4.4 + '@yaireo/tagify': + specifier: 4.17.9 + version: 4.17.9(prop-types@15.8.1) + chat: + specifier: workspace:* + version: link:../chat + chess: + specifier: workspace:* + version: link:../chess + common: + specifier: workspace:* + version: link:../common + cropperjs: + specifier: ^1.6.1 + version: 1.6.1 + debounce-promise: + specifier: ^3.1.2 + version: 3.1.2 + emoji-mart: + specifier: ^5.5.2 + version: 5.5.2 + flatpickr: + specifier: ^4.6.13 + version: 4.6.13 + lichess-pgn-viewer: + specifier: ^2.1.0 + version: 2.1.0 + prop-types: + specifier: ^15.8.1 + version: 15.8.1 + tablesort: + specifier: ^5.3.0 + version: 5.3.0 + zxcvbn: + specifier: ^4.4.2 + version: 4.4.2 + ui/board: dependencies: common: @@ -233,8 +296,8 @@ importers: ui/common: dependencies: lichess-pgn-viewer: - specifier: ^2.0.1 - version: 2.0.1 + specifier: ^2.1.0 + version: 2.1.0 snabbdom: specifier: 3.5.1 version: 3.5.1 @@ -372,7 +435,7 @@ importers: dependencies: '@types/debounce-promise': specifier: ^3.1.6 - version: 3.1.6 + version: 3.1.9 '@types/yaireo__tagify': specifier: 4.17.5 version: 4.17.5 @@ -381,7 +444,7 @@ importers: version: 4.17.9(prop-types@15.8.1) apexcharts: specifier: ^3.36.3 - version: 3.44.0 + version: 3.48.0 common: specifier: workspace:* version: link:../common @@ -446,71 +509,8 @@ importers: specifier: ^3.1.2 version: 3.1.2 lichess-pgn-viewer: - specifier: ^2.0.1 - version: 2.0.1 - - ui/pagelets: - dependencies: - '@fnando/sparkline': - specifier: ^0.3.10 - version: 0.3.10 - '@textcomplete/core': - specifier: ^0.1.13 - version: 0.1.13 - '@textcomplete/textarea': - specifier: ^0.1.13 - version: 0.1.13(@textcomplete/core@0.1.13) - '@toast-ui/editor': - specifier: 3.1.7 - version: 3.1.7 - '@types/debounce-promise': - specifier: ^3.1.6 - version: 3.1.6 - '@types/fnando__sparkline': - specifier: ^0.3.7 - version: 0.3.7 - '@types/yaireo__tagify': - specifier: 4.17.5 - version: 4.17.5 - '@types/zxcvbn': - specifier: ^4.4.4 - version: 4.4.4 - '@yaireo/tagify': - specifier: 4.17.9 - version: 4.17.9(prop-types@15.8.1) - chat: - specifier: workspace:* - version: link:../chat - chess: - specifier: workspace:* - version: link:../chess - common: - specifier: workspace:* - version: link:../common - cropperjs: - specifier: ^1.6.1 - version: 1.6.1 - debounce-promise: - specifier: ^3.1.2 - version: 3.1.2 - emoji-mart: - specifier: ^5.5.2 - version: 5.5.2 - flatpickr: - specifier: ^4.6.13 - version: 4.6.13 - lichess-pgn-viewer: - specifier: ^2.0.1 - version: 2.0.1 - prop-types: - specifier: ^15.8.1 - version: 15.8.1 - tablesort: - specifier: ^5.3.0 - version: 5.3.0 - zxcvbn: - specifier: ^4.4.2 - version: 4.4.2 + specifier: ^2.1.0 + version: 2.1.0 ui/palantir: dependencies: @@ -659,8 +659,8 @@ importers: specifier: 0.5.6 version: 0.5.6 lichess-pgn-viewer: - specifier: 2.0.1 - version: 2.0.1 + specifier: ^2.1.0 + version: 2.1.0 tablesort: specifier: ^5.3.0 version: 5.3.0 @@ -706,42 +706,24 @@ importers: ui/tournament: dependencies: + '@types/dragscroll': + specifier: 0.0.0 + version: 0.0.0 chat: specifier: workspace:* version: link:../chat - common: - specifier: workspace:* - version: link:../common - game: - specifier: workspace:* - version: link:../game - snabbdom: - specifier: 3.5.1 - version: 3.5.1 - - ui/tournamentCalendar: - dependencies: common: specifier: workspace:* version: link:../common date-fns: specifier: 2.29.3 version: 2.29.3 - snabbdom: - specifier: 3.5.1 - version: 3.5.1 - - ui/tournamentSchedule: - dependencies: - '@types/dragscroll': - specifier: 0.0.0 - version: 0.0.0 - common: - specifier: workspace:* - version: link:../common dragscroll: specifier: ^0.0.8 version: 0.0.8 + game: + specifier: workspace:* + version: link:../game snabbdom: specifier: 3.5.1 version: 3.5.1 @@ -758,8 +740,8 @@ importers: specifier: workspace:* version: link:../common lichess-pgn-viewer: - specifier: ^2.0.1 - version: 2.0.1 + specifier: ^2.1.0 + version: 2.1.0 ui/voice: dependencies: @@ -786,76 +768,40 @@ packages: engines: {node: '>=0.10.0'} dev: false - /@ampproject/remapping@2.2.0: - resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} + /@ampproject/remapping@2.3.0: + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} dependencies: - '@jridgewell/gen-mapping': 0.1.1 - '@jridgewell/trace-mapping': 0.3.19 - dev: false - - /@babel/code-frame@7.22.10: - resolution: {integrity: sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.22.10 - chalk: 2.4.2 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 dev: false - /@babel/code-frame@7.23.5: - resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} + /@babel/code-frame@7.24.2: + resolution: {integrity: sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/highlight': 7.23.4 - chalk: 2.4.2 - dev: false - - /@babel/compat-data@7.22.9: - resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==} - engines: {node: '>=6.9.0'} - dev: false - - /@babel/compat-data@7.23.5: - resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} - engines: {node: '>=6.9.0'} + '@babel/highlight': 7.24.2 + picocolors: 1.0.0 dev: false - /@babel/core@7.22.10: - resolution: {integrity: sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==} + /@babel/compat-data@7.24.1: + resolution: {integrity: sha512-Pc65opHDliVpRHuKfzI+gSA4zcgr65O4cl64fFJIWEEh8JoHIHh0Oez1Eo8Arz8zq/JhgKodQaxEwUPRtZylVA==} engines: {node: '>=6.9.0'} - dependencies: - '@ampproject/remapping': 2.2.0 - '@babel/code-frame': 7.22.10 - '@babel/generator': 7.22.10 - '@babel/helper-compilation-targets': 7.22.10 - '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.10) - '@babel/helpers': 7.22.10 - '@babel/parser': 7.22.10 - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.10 - '@babel/types': 7.22.10 - convert-source-map: 1.9.0 - debug: 4.3.4 - gensync: 1.0.0-beta.2 - json5: 2.2.2 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color dev: false - /@babel/core@7.24.0: - resolution: {integrity: sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==} + /@babel/core@7.24.3: + resolution: {integrity: sha512-5FcvN1JHw2sHJChotgx8Ek0lyuh4kCKelgMTTqhYJJtloNvUfpAFMeNQUtdlIaktwrSV9LtCdqwk48wL2wBacQ==} engines: {node: '>=6.9.0'} dependencies: - '@ampproject/remapping': 2.2.0 - '@babel/code-frame': 7.23.5 - '@babel/generator': 7.23.6 + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.1 '@babel/helper-compilation-targets': 7.23.6 - '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0) - '@babel/helpers': 7.24.0 - '@babel/parser': 7.24.0 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.3) + '@babel/helpers': 7.24.1 + '@babel/parser': 7.24.1 '@babel/template': 7.24.0 - '@babel/traverse': 7.24.0 + '@babel/traverse': 7.24.1 '@babel/types': 7.24.0 convert-source-map: 2.0.0 debug: 4.3.4 @@ -866,42 +812,21 @@ packages: - supports-color dev: false - /@babel/generator@7.22.10: - resolution: {integrity: sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.10 - '@jridgewell/gen-mapping': 0.3.2 - '@jridgewell/trace-mapping': 0.3.19 - jsesc: 2.5.2 - dev: false - - /@babel/generator@7.23.6: - resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} + /@babel/generator@7.24.1: + resolution: {integrity: sha512-DfCRfZsBcrPEHUfuBMgbJ1Ut01Y/itOs+hY2nFLgqsqXd52/iSiVq5TITtUasIUgm+IIKdY2/1I7auiQOEeC9A==} engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.24.0 - '@jridgewell/gen-mapping': 0.3.2 - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 jsesc: 2.5.2 dev: false - /@babel/helper-compilation-targets@7.22.10: - resolution: {integrity: sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/compat-data': 7.22.9 - '@babel/helper-validator-option': 7.22.5 - browserslist: 4.21.10 - lru-cache: 5.1.1 - semver: 6.3.1 - dev: false - /@babel/helper-compilation-targets@7.23.6: resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/compat-data': 7.23.5 + '@babel/compat-data': 7.24.1 '@babel/helper-validator-option': 7.23.5 browserslist: 4.23.0 lru-cache: 5.1.1 @@ -913,19 +838,6 @@ packages: engines: {node: '>=6.9.0'} dev: false - /@babel/helper-environment-visitor@7.22.5: - resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} - engines: {node: '>=6.9.0'} - dev: false - - /@babel/helper-function-name@7.22.5: - resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.22.5 - '@babel/types': 7.22.10 - dev: false - /@babel/helper-function-name@7.23.0: resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} engines: {node: '>=6.9.0'} @@ -937,59 +849,33 @@ packages: /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.22.10 - dev: false - - /@babel/helper-module-imports@7.22.15: - resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} - engines: {node: '>=6.9.0'} dependencies: '@babel/types': 7.24.0 dev: false - /@babel/helper-module-imports@7.22.5: - resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} + /@babel/helper-module-imports@7.24.3: + resolution: {integrity: sha512-viKb0F9f2s0BCS22QSF308z/+1YWKV/76mwt61NBzS5izMzDPwdq1pTrzf+Li3npBWX9KdQbkeCt1jSAM7lZqg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.10 - dev: false - - /@babel/helper-module-transforms@7.22.9(@babel/core@7.22.10): - resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/core': 7.22.10 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-module-imports': 7.22.5 - '@babel/helper-simple-access': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/helper-validator-identifier': 7.22.5 + '@babel/types': 7.24.0 dev: false - /@babel/helper-module-transforms@7.23.3(@babel/core@7.24.0): + /@babel/helper-module-transforms@7.23.3(@babel/core@7.24.3): resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.24.0 + '@babel/core': 7.24.3 '@babel/helper-environment-visitor': 7.22.20 - '@babel/helper-module-imports': 7.22.15 + '@babel/helper-module-imports': 7.24.3 '@babel/helper-simple-access': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 '@babel/helper-validator-identifier': 7.22.20 dev: false - /@babel/helper-plugin-utils@7.20.2: - resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} - engines: {node: '>=6.9.0'} - dev: false - - /@babel/helper-plugin-utils@7.22.5: - resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} + /@babel/helper-plugin-utils@7.24.0: + resolution: {integrity: sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==} engines: {node: '>=6.9.0'} dev: false @@ -997,23 +883,18 @@ packages: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.10 + '@babel/types': 7.24.0 dev: false /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.22.10 - dev: false - - /@babel/helper-string-parser@7.22.5: - resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} - engines: {node: '>=6.9.0'} + '@babel/types': 7.24.0 dev: false - /@babel/helper-string-parser@7.23.4: - resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} + /@babel/helper-string-parser@7.24.1: + resolution: {integrity: sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==} engines: {node: '>=6.9.0'} dev: false @@ -1022,253 +903,189 @@ packages: engines: {node: '>=6.9.0'} dev: false - /@babel/helper-validator-identifier@7.22.5: - resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} - engines: {node: '>=6.9.0'} - dev: false - - /@babel/helper-validator-option@7.22.5: - resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==} - engines: {node: '>=6.9.0'} - dev: false - /@babel/helper-validator-option@7.23.5: resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} engines: {node: '>=6.9.0'} dev: false - /@babel/helpers@7.22.10: - resolution: {integrity: sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.10 - '@babel/types': 7.22.10 - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/helpers@7.24.0: - resolution: {integrity: sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==} + /@babel/helpers@7.24.1: + resolution: {integrity: sha512-BpU09QqEe6ZCHuIHFphEFgvNSrubve1FtyMton26ekZ85gRGi6LrTF7zArARp2YvyFxloeiRmtSCq5sjh1WqIg==} engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.24.0 - '@babel/traverse': 7.24.0 + '@babel/traverse': 7.24.1 '@babel/types': 7.24.0 transitivePeerDependencies: - supports-color dev: false - /@babel/highlight@7.22.10: - resolution: {integrity: sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.22.5 - chalk: 2.4.2 - js-tokens: 4.0.0 - dev: false - - /@babel/highlight@7.23.4: - resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} + /@babel/highlight@7.24.2: + resolution: {integrity: sha512-Yac1ao4flkTxTteCDZLEvdxg2fZfz1v8M4QpaGypq/WPDqg3ijHYbDfs+LG5hvzSoqaSZ9/Z9lKSP3CjZjv+pA==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-validator-identifier': 7.22.20 chalk: 2.4.2 js-tokens: 4.0.0 + picocolors: 1.0.0 dev: false - /@babel/parser@7.22.10: - resolution: {integrity: sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.22.10 - dev: false - - /@babel/parser@7.24.0: - resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==} + /@babel/parser@7.24.1: + resolution: {integrity: sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.22.10 + '@babel/types': 7.24.0 dev: false - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.22.10): + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.3): resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 dev: false - /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.22.10): + /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.24.3): resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 dev: false - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.22.10): + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.3): resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 dev: false - /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.22.10): + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.24.3): resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 dev: false - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.22.10): + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.3): resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 dev: false - /@babel/plugin-syntax-jsx@7.18.6(@babel/core@7.22.10): - resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} + /@babel/plugin-syntax-jsx@7.24.1(@babel/core@7.24.3): + resolution: {integrity: sha512-2eCtxZXf+kbkMIsXS4poTvT4Yu5rXiRa+9xGVT56raghjmBTKMpFNc9R4IDiB4emao9eO22Ox7CxuJG7BgExqA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 dev: false - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.22.10): + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.3): resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 dev: false - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.22.10): + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.3): resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 dev: false - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.22.10): + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.3): resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 dev: false - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.22.10): + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.3): resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 dev: false - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.22.10): + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.3): resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 dev: false - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.22.10): + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.3): resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 dev: false - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.22.10): + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.3): resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.22.5 + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 dev: false - /@babel/plugin-syntax-typescript@7.20.0(@babel/core@7.22.10): - resolution: {integrity: sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==} + /@babel/plugin-syntax-typescript@7.24.1(@babel/core@7.24.3): + resolution: {integrity: sha512-Yhnmvy5HZEnHUty6i++gcfH1/l68AHnItFHnaCv6hn9dNh0hQvvQJsxpi4BMBFN5DLeHBuucT/0DgzXif/OyRw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.10 - '@babel/helper-plugin-utils': 7.20.2 - dev: false - - /@babel/template@7.22.5: - resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.22.10 - '@babel/parser': 7.22.10 - '@babel/types': 7.22.10 + '@babel/core': 7.24.3 + '@babel/helper-plugin-utils': 7.24.0 dev: false /@babel/template@7.24.0: resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.23.5 - '@babel/parser': 7.24.0 + '@babel/code-frame': 7.24.2 + '@babel/parser': 7.24.1 '@babel/types': 7.24.0 dev: false - /@babel/traverse@7.22.10: - resolution: {integrity: sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==} + /@babel/traverse@7.24.1: + resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.22.10 - '@babel/generator': 7.22.10 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-function-name': 7.22.5 - '@babel/helper-hoist-variables': 7.22.5 - '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.22.10 - '@babel/types': 7.22.10 - debug: 4.3.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: false - - /@babel/traverse@7.24.0: - resolution: {integrity: sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.23.5 - '@babel/generator': 7.23.6 + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.1 '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-function-name': 7.23.0 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.24.0 + '@babel/parser': 7.24.1 '@babel/types': 7.24.0 debug: 4.3.4 globals: 11.12.0 @@ -1276,20 +1093,11 @@ packages: - supports-color dev: false - /@babel/types@7.22.10: - resolution: {integrity: sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.22.5 - '@babel/helper-validator-identifier': 7.22.5 - to-fast-properties: 2.0.0 - dev: false - /@babel/types@7.24.0: resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-string-parser': 7.23.4 + '@babel/helper-string-parser': 7.24.1 '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 dev: false @@ -1320,8 +1128,8 @@ packages: eslint-visitor-keys: 3.4.3 dev: false - /@eslint-community/regexpp@4.6.2: - resolution: {integrity: sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==} + /@eslint-community/regexpp@4.10.0: + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: false @@ -1332,8 +1140,8 @@ packages: ajv: 6.12.6 debug: 4.3.4 espree: 9.6.1 - globals: 13.20.0 - ignore: 5.2.4 + globals: 13.24.0 + ignore: 5.3.1 import-fresh: 3.3.0 js-yaml: 4.1.0 minimatch: 3.1.2 @@ -1347,21 +1155,21 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: false - /@floating-ui/core@1.5.2: - resolution: {integrity: sha512-Ii3MrfY/GAIN3OhXNzpCKaLxHQfJF9qvwq/kEJYdqDxeIHa01K8sldugal6TmeeXl+WMvhv9cnVzUTaFFJF09A==} + /@floating-ui/core@1.6.0: + resolution: {integrity: sha512-PcF++MykgmTj3CIyOQbKA/hDzOAiqI3mhuoN44WRCopIs1sgoDoU4oty4Jtqaj/y3oDU6fnVSm4QG0a3t5i0+g==} dependencies: - '@floating-ui/utils': 0.1.6 + '@floating-ui/utils': 0.2.1 dev: false - /@floating-ui/dom@1.5.3: - resolution: {integrity: sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA==} + /@floating-ui/dom@1.6.3: + resolution: {integrity: sha512-RnDthu3mzPlQ31Ss/BTwQ1zjzIhr3lk1gZB1OC56h/1vEtaXkESrOqL5fQVMfXpwGtRwX+YsZBdyHtJMQnkArw==} dependencies: - '@floating-ui/core': 1.5.2 - '@floating-ui/utils': 0.1.6 + '@floating-ui/core': 1.6.0 + '@floating-ui/utils': 0.2.1 dev: false - /@floating-ui/utils@0.1.6: - resolution: {integrity: sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A==} + /@floating-ui/utils@0.2.1: + resolution: {integrity: sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q==} dev: false /@fnando/sparkline@0.3.10: @@ -1372,7 +1180,7 @@ packages: resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} dependencies: - '@humanwhocodes/object-schema': 2.0.2 + '@humanwhocodes/object-schema': 2.0.3 debug: 4.3.4 minimatch: 3.1.2 transitivePeerDependencies: @@ -1384,8 +1192,8 @@ packages: engines: {node: '>=12.22'} dev: false - /@humanwhocodes/object-schema@2.0.2: - resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} + /@humanwhocodes/object-schema@2.0.3: + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} dev: false /@istanbuljs/load-nyc-config@1.1.0: @@ -1409,7 +1217,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.28 + '@types/node': 20.12.2 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -1430,14 +1238,14 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.28 + '@types/node': 20.12.2 ansi-escapes: 4.3.2 chalk: 4.1.2 - ci-info: 3.7.0 + ci-info: 3.9.0 exit: 0.1.2 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@20.11.28) + jest-config: 29.7.0(@types/node@20.12.2) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -1465,7 +1273,7 @@ packages: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.28 + '@types/node': 20.12.2 jest-mock: 29.7.0 dev: false @@ -1492,7 +1300,7 @@ packages: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 20.11.28 + '@types/node': 20.12.2 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -1524,25 +1332,25 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.19 - '@types/node': 20.11.28 + '@jridgewell/trace-mapping': 0.3.25 + '@types/node': 20.12.2 chalk: 4.1.2 - collect-v8-coverage: 1.0.1 + collect-v8-coverage: 1.0.2 exit: 0.1.2 glob: 7.2.3 - graceful-fs: 4.2.10 - istanbul-lib-coverage: 3.2.0 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 istanbul-lib-instrument: 6.0.2 - istanbul-lib-report: 3.0.0 + istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.5 + istanbul-reports: 3.1.7 jest-message-util: 29.7.0 jest-util: 29.7.0 jest-worker: 29.7.0 slash: 3.0.0 string-length: 4.0.2 strip-ansi: 6.0.1 - v8-to-istanbul: 9.0.1 + v8-to-istanbul: 9.2.0 transitivePeerDependencies: - supports-color dev: false @@ -1558,9 +1366,9 @@ packages: resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.25 callsites: 3.1.0 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 dev: false /@jest/test-result@29.7.0: @@ -1569,8 +1377,8 @@ packages: dependencies: '@jest/console': 29.7.0 '@jest/types': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.4 - collect-v8-coverage: 1.0.1 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.2 dev: false /@jest/test-sequencer@29.7.0: @@ -1578,7 +1386,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/test-result': 29.7.0 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 jest-haste-map: 29.7.0 slash: 3.0.0 dev: false @@ -1587,19 +1395,19 @@ packages: resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/core': 7.22.10 + '@babel/core': 7.24.3 '@jest/types': 29.6.3 - '@jridgewell/trace-mapping': 0.3.19 + '@jridgewell/trace-mapping': 0.3.25 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 convert-source-map: 2.0.0 fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 jest-haste-map: 29.7.0 jest-regex-util: 29.6.3 jest-util: 29.7.0 micromatch: 4.0.5 - pirates: 4.0.5 + pirates: 4.0.6 slash: 3.0.0 write-file-atomic: 4.0.2 transitivePeerDependencies: @@ -1611,49 +1419,41 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/schemas': 29.6.3 - '@types/istanbul-lib-coverage': 2.0.4 - '@types/istanbul-reports': 3.0.1 - '@types/node': 20.11.28 - '@types/yargs': 17.0.17 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 20.12.2 + '@types/yargs': 17.0.32 chalk: 4.1.2 dev: false - /@jridgewell/gen-mapping@0.1.1: - resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} + /@jridgewell/gen-mapping@0.3.5: + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} engines: {node: '>=6.0.0'} dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.14 + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.25 dev: false - /@jridgewell/gen-mapping@0.3.2: - resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} + /@jridgewell/resolve-uri@3.1.2: + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.14 - '@jridgewell/trace-mapping': 0.3.19 dev: false - /@jridgewell/resolve-uri@3.1.0: - resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + /@jridgewell/set-array@1.2.1: + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} engines: {node: '>=6.0.0'} dev: false - /@jridgewell/set-array@1.1.2: - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} - engines: {node: '>=6.0.0'} + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} dev: false - /@jridgewell/sourcemap-codec@1.4.14: - resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} - dev: false - - /@jridgewell/trace-mapping@0.3.19: - resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==} + /@jridgewell/trace-mapping@0.3.25: + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} dependencies: - '@jridgewell/resolve-uri': 3.1.0 - '@jridgewell/sourcemap-codec': 1.4.14 + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 dev: false /@juggle/resize-observer@3.4.0: @@ -1682,15 +1482,15 @@ packages: engines: {node: '>= 8'} dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.15.0 + fastq: 1.17.1 dev: false /@sinclair/typebox@0.27.8: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: false - /@sinonjs/commons@3.0.0: - resolution: {integrity: sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA==} + /@sinonjs/commons@3.0.1: + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} dependencies: type-detect: 4.0.8 dev: false @@ -1698,7 +1498,7 @@ packages: /@sinonjs/fake-timers@10.3.0: resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} dependencies: - '@sinonjs/commons': 3.0.0 + '@sinonjs/commons': 3.0.1 dev: false /@textcomplete/core@0.1.13: @@ -1725,14 +1525,14 @@ packages: /@toast-ui/editor@3.1.7: resolution: {integrity: sha512-SEfahMrrphveuGhOQyYX3UwjJWjCRnnL6pVPc67uVDBS/JsOESJDG2kcfW9MHJhHnOv6m6WV1jRQW9kPatgumw==} dependencies: - dompurify: 2.4.1 - prosemirror-commands: 1.1.12 - prosemirror-history: 1.1.3 - prosemirror-inputrules: 1.1.3 - prosemirror-keymap: 1.1.5 - prosemirror-model: 1.18.3 - prosemirror-state: 1.4.2 - prosemirror-view: 1.29.1 + dompurify: 2.4.9 + prosemirror-commands: 1.5.2 + prosemirror-history: 1.4.0 + prosemirror-inputrules: 1.4.0 + prosemirror-keymap: 1.2.2 + prosemirror-model: 1.19.4 + prosemirror-state: 1.4.3 + prosemirror-view: 1.33.3 dev: false /@tootallnate/once@2.0.0: @@ -1744,43 +1544,39 @@ packages: resolution: {integrity: sha512-WR1XcwT2LhCaUiKDDgHdTjrVjoBZnTz6FhszeIKgY9i2UYfIRKtnNvqToUDnbCPXBpVuu4Qo5+mMJt+wDphRew==} dev: false - /@types/babel__core@7.1.20: - resolution: {integrity: sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==} + /@types/babel__core@7.20.5: + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} dependencies: - '@babel/parser': 7.22.10 - '@babel/types': 7.22.10 - '@types/babel__generator': 7.6.4 - '@types/babel__template': 7.4.1 - '@types/babel__traverse': 7.18.3 + '@babel/parser': 7.24.1 + '@babel/types': 7.24.0 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.5 dev: false - /@types/babel__generator@7.6.4: - resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} + /@types/babel__generator@7.6.8: + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} dependencies: - '@babel/types': 7.22.10 + '@babel/types': 7.24.0 dev: false - /@types/babel__template@7.4.1: - resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} + /@types/babel__template@7.4.4: + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} dependencies: - '@babel/parser': 7.22.10 - '@babel/types': 7.22.10 + '@babel/parser': 7.24.1 + '@babel/types': 7.24.0 dev: false - /@types/babel__traverse@7.18.3: - resolution: {integrity: sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==} + /@types/babel__traverse@7.20.5: + resolution: {integrity: sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==} dependencies: - '@babel/types': 7.22.10 + '@babel/types': 7.24.0 dev: false /@types/chess.js@0.10.1: resolution: {integrity: sha512-cuFMyrUYOWpKm5PRayvk22jLV3BOuWs7iJ7Q4PZJXMWoF7uhjWEojMS4GPk441gn4Ki9BHxbKsll7mrwJ3KT3g==} dev: false - /@types/debounce-promise@3.1.6: - resolution: {integrity: sha512-DowqK95aku+OxMCeG2EQSeXeGeE8OCwLpMsUfIbP7hMF8Otj8eQXnzpwdtIKV+UqQBtkMcF6vbi4Otbh8P/wmg==} - dev: false - /@types/debounce-promise@3.1.9: resolution: {integrity: sha512-awNxydYSU+E2vL7EiOAMtiSOfL5gUM5X4YSE2A92qpxDJQ/rXz6oMPYBFDcDywlUmvIDI6zsqgq17cGm5CITQw==} dev: false @@ -1793,26 +1589,26 @@ packages: resolution: {integrity: sha512-irYrS2clNGbnKBBIBAulPH6hDZ/HlBkNsDbYPfO8B2obcxtC9UzKFS5IBSzrUtfKbwf8U01xHj+5iEJ7TtY04Q==} dev: false - /@types/graceful-fs@4.1.5: - resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} + /@types/graceful-fs@4.1.9: + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} dependencies: - '@types/node': 20.11.28 + '@types/node': 20.12.2 dev: false - /@types/istanbul-lib-coverage@2.0.4: - resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + /@types/istanbul-lib-coverage@2.0.6: + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} dev: false - /@types/istanbul-lib-report@3.0.0: - resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} + /@types/istanbul-lib-report@3.0.3: + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} dependencies: - '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-lib-coverage': 2.0.6 dev: false - /@types/istanbul-reports@3.0.1: - resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} + /@types/istanbul-reports@3.0.4: + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} dependencies: - '@types/istanbul-lib-report': 3.0.0 + '@types/istanbul-lib-report': 3.0.3 dev: false /@types/jest@29.5.12: @@ -1825,53 +1621,42 @@ packages: /@types/jsdom@20.0.1: resolution: {integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==} dependencies: - '@types/node': 20.11.28 - '@types/tough-cookie': 4.0.2 + '@types/node': 20.12.2 + '@types/tough-cookie': 4.0.5 parse5: 7.1.2 dev: false - /@types/json-schema@7.0.12: - resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} - dev: false - - /@types/node@20.11.28: - resolution: {integrity: sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA==} - dependencies: - undici-types: 5.26.5 + /@types/json-schema@7.0.15: + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: false - /@types/node@20.9.1: - resolution: {integrity: sha512-HhmzZh5LSJNS5O8jQKpJ/3ZcrrlG6L70hpGqMIAoM9YVD0YBRNWYsfwcXq8VnSjlNpCpgLzMXdiPo+dxcvSmiA==} + /@types/node@20.12.2: + resolution: {integrity: sha512-zQ0NYO87hyN6Xrclcqp7f8ZbXNbRfoGWNcMvHTPQp9UUrwI0mI7XBz+cu7/W6/VClYo2g63B0cjull/srU7LgQ==} dependencies: undici-types: 5.26.5 dev: false - /@types/prop-types@15.7.5: - resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} + /@types/prop-types@15.7.12: + resolution: {integrity: sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==} dev: false - /@types/react@18.0.26: - resolution: {integrity: sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==} + /@types/react@18.2.74: + resolution: {integrity: sha512-9AEqNZZyBx8OdZpxzQlaFEVCSFUM2YXJH46yPOiOpm078k6ZLOCcuAzGum/zK8YBwY+dbahVNbHrbgrAwIRlqw==} dependencies: - '@types/prop-types': 15.7.5 - '@types/scheduler': 0.16.2 - csstype: 3.1.1 - dev: false - - /@types/scheduler@0.16.2: - resolution: {integrity: sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==} + '@types/prop-types': 15.7.12 + csstype: 3.1.3 dev: false - /@types/semver@7.5.0: - resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} + /@types/semver@7.5.8: + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} dev: false - /@types/stack-utils@2.0.1: - resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==} + /@types/stack-utils@2.0.3: + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} dev: false - /@types/tough-cookie@4.0.2: - resolution: {integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==} + /@types/tough-cookie@4.0.5: + resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} dev: false /@types/web@0.0.142: @@ -1885,26 +1670,26 @@ packages: /@types/yaireo__tagify@4.17.5: resolution: {integrity: sha512-nYk4xqky1ZnbgTlP7dO24GA/Kz4Q7mvNGNOsRPygnaVV8kBXIhROFVLG141Y0EF+TZKbmIMUolaJ+Z69Pr9FwQ==} dependencies: - '@types/react': 18.0.26 + '@types/react': 18.2.74 dev: false - /@types/yargs-parser@21.0.0: - resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} + /@types/yargs-parser@21.0.3: + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} dev: false - /@types/yargs@17.0.17: - resolution: {integrity: sha512-72bWxFKTK6uwWJAVT+3rF6Jo6RTojiJ27FQo8Rf60AL+VZbzoVPnMFhKsUnbjR8A3BTCYQ7Mv3hnl8T0A+CX9g==} + /@types/yargs@17.0.32: + resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} dependencies: - '@types/yargs-parser': 21.0.0 + '@types/yargs-parser': 21.0.3 dev: false /@types/zxcvbn@4.4.4: resolution: {integrity: sha512-Tuk4q7q0DnpzyJDI4aMeghGuFu2iS1QAdKpabn8JfbtfGmVDUgvZv1I7mEjP61Bvnp3ljKCC8BE6YYSTNxmvRQ==} dev: false - /@typescript-eslint/eslint-plugin@7.2.0(@typescript-eslint/parser@7.2.0)(eslint@8.57.0)(typescript@5.4.2): - resolution: {integrity: sha512-mdekAHOqS9UjlmyF/LSs6AIEvfceV749GFxoBAjwAv0nkevfKHWQFDMcBZWUiIC5ft6ePWivXoS36aKQ0Cy3sw==} - engines: {node: ^16.0.0 || >=18.0.0} + /@typescript-eslint/eslint-plugin@7.5.0(@typescript-eslint/parser@7.5.0)(eslint@8.57.0)(typescript@5.4.3): + resolution: {integrity: sha512-HpqNTH8Du34nLxbKgVMGljZMG0rJd2O9ecvr2QLYp+7512ty1j42KnsFwspPXg1Vh8an9YImf6CokUBltisZFQ==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: '@typescript-eslint/parser': ^7.0.0 eslint: ^8.56.0 @@ -1913,27 +1698,27 @@ packages: typescript: optional: true dependencies: - '@eslint-community/regexpp': 4.6.2 - '@typescript-eslint/parser': 7.2.0(eslint@8.57.0)(typescript@5.4.2) - '@typescript-eslint/scope-manager': 7.2.0 - '@typescript-eslint/type-utils': 7.2.0(eslint@8.57.0)(typescript@5.4.2) - '@typescript-eslint/utils': 7.2.0(eslint@8.57.0)(typescript@5.4.2) - '@typescript-eslint/visitor-keys': 7.2.0 + '@eslint-community/regexpp': 4.10.0 + '@typescript-eslint/parser': 7.5.0(eslint@8.57.0)(typescript@5.4.3) + '@typescript-eslint/scope-manager': 7.5.0 + '@typescript-eslint/type-utils': 7.5.0(eslint@8.57.0)(typescript@5.4.3) + '@typescript-eslint/utils': 7.5.0(eslint@8.57.0)(typescript@5.4.3) + '@typescript-eslint/visitor-keys': 7.5.0 debug: 4.3.4 eslint: 8.57.0 graphemer: 1.4.0 - ignore: 5.2.4 + ignore: 5.3.1 natural-compare: 1.4.0 - semver: 7.5.4 - ts-api-utils: 1.0.1(typescript@5.4.2) - typescript: 5.4.2 + semver: 7.6.0 + ts-api-utils: 1.3.0(typescript@5.4.3) + typescript: 5.4.3 transitivePeerDependencies: - supports-color dev: false - /@typescript-eslint/parser@7.2.0(eslint@8.57.0)(typescript@5.4.2): - resolution: {integrity: sha512-5FKsVcHTk6TafQKQbuIVkXq58Fnbkd2wDL4LB7AURN7RUOu1utVP+G8+6u3ZhEroW3DF6hyo3ZEXxgKgp4KeCg==} - engines: {node: ^16.0.0 || >=18.0.0} + /@typescript-eslint/parser@7.5.0(eslint@8.57.0)(typescript@5.4.3): + resolution: {integrity: sha512-cj+XGhNujfD2/wzR1tabNsidnYRaFfEkcULdcIyVBYcXjBvBKOes+mpMBP7hMpOyk+gBcfXsrg4NBGAStQyxjQ==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 typescript: '*' @@ -1941,28 +1726,28 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 7.2.0 - '@typescript-eslint/types': 7.2.0 - '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.4.2) - '@typescript-eslint/visitor-keys': 7.2.0 + '@typescript-eslint/scope-manager': 7.5.0 + '@typescript-eslint/types': 7.5.0 + '@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.3) + '@typescript-eslint/visitor-keys': 7.5.0 debug: 4.3.4 eslint: 8.57.0 - typescript: 5.4.2 + typescript: 5.4.3 transitivePeerDependencies: - supports-color dev: false - /@typescript-eslint/scope-manager@7.2.0: - resolution: {integrity: sha512-Qh976RbQM/fYtjx9hs4XkayYujB/aPwglw2choHmf3zBjB4qOywWSdt9+KLRdHubGcoSwBnXUH2sR3hkyaERRg==} - engines: {node: ^16.0.0 || >=18.0.0} + /@typescript-eslint/scope-manager@7.5.0: + resolution: {integrity: sha512-Z1r7uJY0MDeUlql9XJ6kRVgk/sP11sr3HKXn268HZyqL7i4cEfrdFuSSY/0tUqT37l5zT0tJOsuDP16kio85iA==} + engines: {node: ^18.18.0 || >=20.0.0} dependencies: - '@typescript-eslint/types': 7.2.0 - '@typescript-eslint/visitor-keys': 7.2.0 + '@typescript-eslint/types': 7.5.0 + '@typescript-eslint/visitor-keys': 7.5.0 dev: false - /@typescript-eslint/type-utils@7.2.0(eslint@8.57.0)(typescript@5.4.2): - resolution: {integrity: sha512-xHi51adBHo9O9330J8GQYQwrKBqbIPJGZZVQTHHmy200hvkLZFWJIFtAG/7IYTWUyun6DE6w5InDReePJYJlJA==} - engines: {node: ^16.0.0 || >=18.0.0} + /@typescript-eslint/type-utils@7.5.0(eslint@8.57.0)(typescript@5.4.3): + resolution: {integrity: sha512-A021Rj33+G8mx2Dqh0nMO9GyjjIBK3MqgVgZ2qlKf6CJy51wY/lkkFqq3TqqnH34XyAHUkq27IjlUkWlQRpLHw==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 typescript: '*' @@ -1970,67 +1755,67 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.4.2) - '@typescript-eslint/utils': 7.2.0(eslint@8.57.0)(typescript@5.4.2) + '@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.3) + '@typescript-eslint/utils': 7.5.0(eslint@8.57.0)(typescript@5.4.3) debug: 4.3.4 eslint: 8.57.0 - ts-api-utils: 1.0.1(typescript@5.4.2) - typescript: 5.4.2 + ts-api-utils: 1.3.0(typescript@5.4.3) + typescript: 5.4.3 transitivePeerDependencies: - supports-color dev: false - /@typescript-eslint/types@7.2.0: - resolution: {integrity: sha512-XFtUHPI/abFhm4cbCDc5Ykc8npOKBSJePY3a3s+lwumt7XWJuzP5cZcfZ610MIPHjQjNsOLlYK8ASPaNG8UiyA==} - engines: {node: ^16.0.0 || >=18.0.0} + /@typescript-eslint/types@7.5.0: + resolution: {integrity: sha512-tv5B4IHeAdhR7uS4+bf8Ov3k793VEVHd45viRRkehIUZxm0WF82VPiLgHzA/Xl4TGPg1ZD49vfxBKFPecD5/mg==} + engines: {node: ^18.18.0 || >=20.0.0} dev: false - /@typescript-eslint/typescript-estree@7.2.0(typescript@5.4.2): - resolution: {integrity: sha512-cyxS5WQQCoBwSakpMrvMXuMDEbhOo9bNHHrNcEWis6XHx6KF518tkF1wBvKIn/tpq5ZpUYK7Bdklu8qY0MsFIA==} - engines: {node: ^16.0.0 || >=18.0.0} + /@typescript-eslint/typescript-estree@7.5.0(typescript@5.4.3): + resolution: {integrity: sha512-YklQQfe0Rv2PZEueLTUffiQGKQneiIEKKnfIqPIOxgM9lKSZFCjT5Ad4VqRKj/U4+kQE3fa8YQpskViL7WjdPQ==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: typescript: '*' peerDependenciesMeta: typescript: optional: true dependencies: - '@typescript-eslint/types': 7.2.0 - '@typescript-eslint/visitor-keys': 7.2.0 + '@typescript-eslint/types': 7.5.0 + '@typescript-eslint/visitor-keys': 7.5.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 - semver: 7.5.4 - ts-api-utils: 1.0.1(typescript@5.4.2) - typescript: 5.4.2 + semver: 7.6.0 + ts-api-utils: 1.3.0(typescript@5.4.3) + typescript: 5.4.3 transitivePeerDependencies: - supports-color dev: false - /@typescript-eslint/utils@7.2.0(eslint@8.57.0)(typescript@5.4.2): - resolution: {integrity: sha512-YfHpnMAGb1Eekpm3XRK8hcMwGLGsnT6L+7b2XyRv6ouDuJU1tZir1GS2i0+VXRatMwSI1/UfcyPe53ADkU+IuA==} - engines: {node: ^16.0.0 || >=18.0.0} + /@typescript-eslint/utils@7.5.0(eslint@8.57.0)(typescript@5.4.3): + resolution: {integrity: sha512-3vZl9u0R+/FLQcpy2EHyRGNqAS/ofJ3Ji8aebilfJe+fobK8+LbIFmrHciLVDxjDoONmufDcnVSF38KwMEOjzw==} + engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@types/json-schema': 7.0.12 - '@types/semver': 7.5.0 - '@typescript-eslint/scope-manager': 7.2.0 - '@typescript-eslint/types': 7.2.0 - '@typescript-eslint/typescript-estree': 7.2.0(typescript@5.4.2) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 7.5.0 + '@typescript-eslint/types': 7.5.0 + '@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.3) eslint: 8.57.0 - semver: 7.5.4 + semver: 7.6.0 transitivePeerDependencies: - supports-color - typescript dev: false - /@typescript-eslint/visitor-keys@7.2.0: - resolution: {integrity: sha512-c6EIQRHhcpl6+tO8EMR+kjkkV+ugUNXOmeASA1rlzkd8EPIriavpWoiEz1HR/VLhbVIdhqnV6E7JZm00cBDx2A==} - engines: {node: ^16.0.0 || >=18.0.0} + /@typescript-eslint/visitor-keys@7.5.0: + resolution: {integrity: sha512-mcuHM/QircmA6O7fy6nn2w/3ditQkj+SgtOc8DW3uQ10Yfj42amm2i+6F2K4YAOPNNTmE6iM1ynM6lrSwdendA==} + engines: {node: ^18.18.0 || >=20.0.0} dependencies: - '@typescript-eslint/types': 7.2.0 + '@typescript-eslint/types': 7.5.0 eslint-visitor-keys: 3.4.3 dev: false @@ -2059,25 +1844,25 @@ packages: /acorn-globals@7.0.1: resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} dependencies: - acorn: 8.9.0 - acorn-walk: 8.2.0 + acorn: 8.11.3 + acorn-walk: 8.3.2 dev: false - /acorn-jsx@5.3.2(acorn@8.9.0): + /acorn-jsx@5.3.2(acorn@8.11.3): resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - acorn: 8.9.0 + acorn: 8.11.3 dev: false - /acorn-walk@8.2.0: - resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + /acorn-walk@8.3.2: + resolution: {integrity: sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==} engines: {node: '>=0.4.0'} dev: false - /acorn@8.9.0: - resolution: {integrity: sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==} + /acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} engines: {node: '>=0.4.0'} hasBin: true dev: false @@ -2107,11 +1892,9 @@ packages: type-fest: 0.21.3 dev: false - /ansi-escapes@6.2.0: - resolution: {integrity: sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==} + /ansi-escapes@6.2.1: + resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} engines: {node: '>=14.16'} - dependencies: - type-fest: 3.13.1 dev: false /ansi-regex@5.0.1: @@ -2156,8 +1939,8 @@ packages: picomatch: 2.3.1 dev: false - /apexcharts@3.44.0: - resolution: {integrity: sha512-u7Xzrbcxc2yWznN78Jh5NMCYVAsWDfBjRl5ea++rVzFAqjU2hLz4RgKIFwYOBDRQtW1e/Qz8azJTqIJ1+Vu9Qg==} + /apexcharts@3.48.0: + resolution: {integrity: sha512-Lhpj1Ij6lKlrUke8gf+P+SE6uGUn+Pe1TnCJ+zqrY0YMvbqM3LMb1lY+eybbTczUyk0RmMZomlTa2NgX2EUs4Q==} dependencies: '@yr/monotone-cubic-spline': 1.0.3 svg.draggable.js: 2.2.2 @@ -2191,19 +1974,19 @@ packages: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: false - /babel-jest@29.7.0(@babel/core@7.22.10): + /babel-jest@29.7.0(@babel/core@7.24.3): resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.8.0 dependencies: - '@babel/core': 7.22.10 + '@babel/core': 7.24.3 '@jest/transform': 29.7.0 - '@types/babel__core': 7.1.20 + '@types/babel__core': 7.20.5 babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.22.10) + babel-preset-jest: 29.6.3(@babel/core@7.24.3) chalk: 4.1.2 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 slash: 3.0.0 transitivePeerDependencies: - supports-color @@ -2213,7 +1996,7 @@ packages: resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} engines: {node: '>=8'} dependencies: - '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-plugin-utils': 7.24.0 '@istanbuljs/load-nyc-config': 1.1.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-instrument: 5.2.1 @@ -2226,49 +2009,49 @@ packages: resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/template': 7.22.5 - '@babel/types': 7.22.10 - '@types/babel__core': 7.1.20 - '@types/babel__traverse': 7.18.3 + '@babel/template': 7.24.0 + '@babel/types': 7.24.0 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.20.5 dev: false - /babel-preset-current-node-syntax@1.0.1(@babel/core@7.22.10): + /babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.3): resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.10 - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.10) - '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.10) - '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.10) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.10) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.10) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.10) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.10) - dev: false - - /babel-preset-jest@29.6.3(@babel/core@7.22.10): + '@babel/core': 7.24.3 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.3) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.3) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.24.3) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.3) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.3) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.3) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.3) + dev: false + + /babel-preset-jest@29.6.3(@babel/core@7.24.3): resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.10 + '@babel/core': 7.24.3 babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.10) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.3) dev: false /balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} dev: false - /binary-extensions@2.2.0: - resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + /binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} dev: false @@ -2292,24 +2075,13 @@ packages: fill-range: 7.0.1 dev: false - /browserslist@4.21.10: - resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - dependencies: - caniuse-lite: 1.0.30001521 - electron-to-chromium: 1.4.494 - node-releases: 2.0.13 - update-browserslist-db: 1.0.11(browserslist@4.21.10) - dev: false - /browserslist@4.23.0: resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001599 - electron-to-chromium: 1.4.708 + caniuse-lite: 1.0.30001605 + electron-to-chromium: 1.4.723 node-releases: 2.0.14 update-browserslist-db: 1.0.13(browserslist@4.23.0) dev: false @@ -2339,12 +2111,8 @@ packages: engines: {node: '>=10'} dev: false - /caniuse-lite@1.0.30001521: - resolution: {integrity: sha512-fnx1grfpEOvDGH+V17eccmNjucGUnCbP6KL+l5KqBIerp26WK/+RQ7CIDE37KGJjaPyqWXXlFUyKiWmvdNNKmQ==} - dev: false - - /caniuse-lite@1.0.30001599: - resolution: {integrity: sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==} + /caniuse-lite@1.0.30001605: + resolution: {integrity: sha512-nXwGlFWo34uliI9z3n6Qc0wZaf7zaZWA1CPZ169La5mV3I/gem7bst0vr5XQH5TJXZIMfDeZyOrZnSlVzKxxHQ==} dev: false /chalk@2.4.2: @@ -2432,8 +2200,8 @@ packages: '@badrap/result': 0.2.13 dev: false - /chokidar@3.5.3: - resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + /chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} dependencies: anymatch: 3.1.3 @@ -2447,13 +2215,13 @@ packages: fsevents: 2.3.3 dev: false - /ci-info@3.7.0: - resolution: {integrity: sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==} + /ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} dev: false - /cjs-module-lexer@1.2.2: - resolution: {integrity: sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==} + /cjs-module-lexer@1.2.3: + resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==} dev: false /cli-cursor@4.0.0: @@ -2485,8 +2253,8 @@ packages: engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} dev: false - /collect-v8-coverage@1.0.1: - resolution: {integrity: sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==} + /collect-v8-coverage@1.0.2: + resolution: {integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==} dev: false /color-convert@1.9.3: @@ -2530,15 +2298,11 @@ packages: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} dev: false - /convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - dev: false - /convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} dev: false - /create-jest@29.7.0(@types/node@20.11.28): + /create-jest@29.7.0(@types/node@20.12.2): resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -2546,8 +2310,8 @@ packages: '@jest/types': 29.6.3 chalk: 4.1.2 exit: 0.1.2 - graceful-fs: 4.2.10 - jest-config: 29.7.0(@types/node@20.11.28) + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@20.12.2) jest-util: 29.7.0 prompts: 2.4.2 transitivePeerDependencies: @@ -2585,8 +2349,8 @@ packages: cssom: 0.3.8 dev: false - /csstype@3.1.1: - resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==} + /csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} dev: false /data-urls@3.0.2: @@ -2686,20 +2450,16 @@ packages: webidl-conversions: 7.0.0 dev: false - /dompurify@2.4.1: - resolution: {integrity: sha512-ewwFzHzrrneRjxzmK6oVz/rZn9VWspGFRDb4/rRtIsM1n36t9AKma/ye8syCpcw+XJ25kOK/hOG7t1j2I2yBqA==} + /dompurify@2.4.9: + resolution: {integrity: sha512-iHtnxYMotKgOTvxIqq677JsKHvCOkAFqj9x8Mek2zdeHW1XjuFKwjpmZeMaXQRQ8AbJZDbcRz/+r1QhwvFtmQg==} dev: false /dragscroll@0.0.8: resolution: {integrity: sha512-nMrx/KErHpEkiKZlrghcT/nLWCj8vEJgv6s6TF84gmgn6uROPx2wRvClkcnjSEyvppYY9okOI1DIv573Toql1w==} dev: false - /electron-to-chromium@1.4.494: - resolution: {integrity: sha512-KF7wtsFFDu4ws1ZsSOt4pdmO1yWVNWCFtijVYZPUeW4SV7/hy/AESjLn/+qIWgq7mHscNOKAwN5AIM1+YAy+Ww==} - dev: false - - /electron-to-chromium@1.4.708: - resolution: {integrity: sha512-iWgEEvREL4GTXXHKohhh33+6Y8XkPI5eHihDmm8zUk5Zo7HICEW+wI/j5kJ2tbuNUCXJ/sNXa03ajW635DiJXA==} + /electron-to-chromium@1.4.723: + resolution: {integrity: sha512-rxFVtrMGMFROr4qqU6n95rUi9IlfIm+lIAt+hOToy/9r6CDv0XiEcQdC3VP71y1pE5CFTzKV0RvxOGYCPWWHPw==} dev: false /emittery@0.13.1: @@ -2730,8 +2490,8 @@ packages: is-arrayish: 0.2.1 dev: false - /escalade@3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + /escalade@3.1.2: + resolution: {integrity: sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==} engines: {node: '>=6'} dev: false @@ -2750,15 +2510,14 @@ packages: engines: {node: '>=10'} dev: false - /escodegen@2.0.0: - resolution: {integrity: sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==} + /escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} engines: {node: '>=6.0'} hasBin: true dependencies: esprima: 4.0.1 estraverse: 5.3.0 esutils: 2.0.3 - optionator: 0.8.3 optionalDependencies: source-map: 0.6.1 dev: false @@ -2782,7 +2541,7 @@ packages: hasBin: true dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@eslint-community/regexpp': 4.6.2 + '@eslint-community/regexpp': 4.10.0 '@eslint/eslintrc': 2.1.4 '@eslint/js': 8.57.0 '@humanwhocodes/config-array': 0.11.14 @@ -2804,9 +2563,9 @@ packages: file-entry-cache: 6.0.1 find-up: 5.0.0 glob-parent: 6.0.2 - globals: 13.20.0 + globals: 13.24.0 graphemer: 1.4.0 - ignore: 5.2.4 + ignore: 5.3.1 imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 @@ -2827,8 +2586,8 @@ packages: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - acorn: 8.9.0 - acorn-jsx: 5.3.2(acorn@8.9.0) + acorn: 8.11.3 + acorn-jsx: 5.3.2(acorn@8.11.3) eslint-visitor-keys: 3.4.3 dev: false @@ -2890,7 +2649,7 @@ packages: human-signals: 5.0.0 is-stream: 3.0.0 merge-stream: 2.0.0 - npm-run-path: 5.1.0 + npm-run-path: 5.3.0 onetime: 6.0.0 signal-exit: 4.1.0 strip-final-newline: 3.0.0 @@ -2935,8 +2694,8 @@ packages: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} dev: false - /fastq@1.15.0: - resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + /fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} dependencies: reusify: 1.0.4 dev: false @@ -2951,7 +2710,7 @@ packages: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: - flat-cache: 3.0.4 + flat-cache: 3.2.0 dev: false /fill-range@7.0.1: @@ -2977,11 +2736,12 @@ packages: path-exists: 4.0.0 dev: false - /flat-cache@3.0.4: - resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} + /flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} dependencies: - flatted: 3.2.7 + flatted: 3.3.1 + keyv: 4.5.4 rimraf: 3.0.2 dev: false @@ -2989,8 +2749,8 @@ packages: resolution: {integrity: sha512-97PMG/aywoYpB4IvbvUJi0RQi8vearvU0oov1WW3k0WZPBMrTQVqekSX5CjSG/M4Q3i6A/0FKXC7RyAoAUUSPw==} dev: false - /flatted@3.2.7: - resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + /flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} dev: false /form-data@4.0.0: @@ -3014,8 +2774,8 @@ packages: dev: false optional: true - /function-bind@1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} dev: false /gensync@1.0.0-beta.2: @@ -3078,8 +2838,8 @@ packages: engines: {node: '>=4'} dev: false - /globals@13.20.0: - resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} + /globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} dependencies: type-fest: 0.20.2 @@ -3092,13 +2852,13 @@ packages: array-union: 2.1.0 dir-glob: 3.0.1 fast-glob: 3.3.2 - ignore: 5.2.4 + ignore: 5.3.1 merge2: 1.4.1 slash: 3.0.0 dev: false - /graceful-fs@4.2.10: - resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} dev: false /graphemer@1.4.0: @@ -3120,11 +2880,11 @@ packages: engines: {node: '>=8'} dev: false - /has@1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} dependencies: - function-bind: 1.1.1 + function-bind: 1.1.2 dev: false /html-encoding-sniffer@3.0.0: @@ -3180,8 +2940,8 @@ packages: resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} dev: false - /ignore@5.2.4: - resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + /ignore@5.3.1: + resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} engines: {node: '>= 4'} dev: false @@ -3226,13 +2986,13 @@ packages: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} dependencies: - binary-extensions: 2.2.0 + binary-extensions: 2.3.0 dev: false - /is-core-module@2.11.0: - resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} dependencies: - has: 1.0.3 + hasown: 2.0.2 dev: false /is-extglob@2.1.1: @@ -3297,8 +3057,8 @@ packages: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} dev: false - /istanbul-lib-coverage@3.2.0: - resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} + /istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} dev: false @@ -3306,10 +3066,10 @@ packages: resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} engines: {node: '>=8'} dependencies: - '@babel/core': 7.22.10 - '@babel/parser': 7.22.10 + '@babel/core': 7.24.3 + '@babel/parser': 7.24.1 '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.0 + istanbul-lib-coverage: 3.2.2 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -3319,21 +3079,21 @@ packages: resolution: {integrity: sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==} engines: {node: '>=10'} dependencies: - '@babel/core': 7.24.0 - '@babel/parser': 7.24.0 + '@babel/core': 7.24.3 + '@babel/parser': 7.24.1 '@istanbuljs/schema': 0.1.3 - istanbul-lib-coverage: 3.2.0 - semver: 7.5.4 + istanbul-lib-coverage: 3.2.2 + semver: 7.6.0 transitivePeerDependencies: - supports-color dev: false - /istanbul-lib-report@3.0.0: - resolution: {integrity: sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==} - engines: {node: '>=8'} + /istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} dependencies: - istanbul-lib-coverage: 3.2.0 - make-dir: 3.1.0 + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 supports-color: 7.2.0 dev: false @@ -3342,18 +3102,18 @@ packages: engines: {node: '>=10'} dependencies: debug: 4.3.4 - istanbul-lib-coverage: 3.2.0 + istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: - supports-color dev: false - /istanbul-reports@3.1.5: - resolution: {integrity: sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==} + /istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} engines: {node: '>=8'} dependencies: html-escaper: 2.0.2 - istanbul-lib-report: 3.0.0 + istanbul-lib-report: 3.0.1 dev: false /jest-changed-files@29.7.0: @@ -3373,7 +3133,7 @@ packages: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.28 + '@types/node': 20.12.2 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.1 @@ -3386,7 +3146,7 @@ packages: jest-util: 29.7.0 p-limit: 3.1.0 pretty-format: 29.7.0 - pure-rand: 6.0.2 + pure-rand: 6.1.0 slash: 3.0.0 stack-utils: 2.0.6 transitivePeerDependencies: @@ -3394,7 +3154,7 @@ packages: - supports-color dev: false - /jest-cli@29.7.0(@types/node@20.11.28): + /jest-cli@29.7.0(@types/node@20.12.2): resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -3408,13 +3168,13 @@ packages: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 chalk: 4.1.2 - create-jest: 29.7.0(@types/node@20.11.28) + create-jest: 29.7.0(@types/node@20.12.2) exit: 0.1.2 import-local: 3.1.0 - jest-config: 29.7.0(@types/node@20.11.28) + jest-config: 29.7.0(@types/node@20.12.2) jest-util: 29.7.0 jest-validate: 29.7.0 - yargs: 17.6.2 + yargs: 17.7.2 transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -3422,7 +3182,7 @@ packages: - ts-node dev: false - /jest-config@29.7.0(@types/node@20.11.28): + /jest-config@29.7.0(@types/node@20.12.2): resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -3434,16 +3194,16 @@ packages: ts-node: optional: true dependencies: - '@babel/core': 7.22.10 + '@babel/core': 7.24.3 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.28 - babel-jest: 29.7.0(@babel/core@7.22.10) + '@types/node': 20.12.2 + babel-jest: 29.7.0(@babel/core@7.24.3) chalk: 4.1.2 - ci-info: 3.7.0 + ci-info: 3.9.0 deepmerge: 4.3.1 glob: 7.2.3 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 jest-circus: 29.7.0 jest-environment-node: 29.7.0 jest-get-type: 29.6.3 @@ -3503,7 +3263,7 @@ packages: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 '@types/jsdom': 20.0.1 - '@types/node': 20.11.28 + '@types/node': 20.12.2 jest-mock: 29.7.0 jest-util: 29.7.0 jsdom: 20.0.3 @@ -3520,7 +3280,7 @@ packages: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.28 + '@types/node': 20.12.2 jest-mock: 29.7.0 jest-util: 29.7.0 dev: false @@ -3535,11 +3295,11 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/graceful-fs': 4.1.5 - '@types/node': 20.11.28 + '@types/graceful-fs': 4.1.9 + '@types/node': 20.12.2 anymatch: 3.1.3 fb-watchman: 2.0.2 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 jest-regex-util: 29.6.3 jest-util: 29.7.0 jest-worker: 29.7.0 @@ -3571,11 +3331,11 @@ packages: resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/code-frame': 7.22.10 + '@babel/code-frame': 7.24.2 '@jest/types': 29.6.3 - '@types/stack-utils': 2.0.1 + '@types/stack-utils': 2.0.3 chalk: 4.1.2 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 micromatch: 4.0.5 pretty-format: 29.7.0 slash: 3.0.0 @@ -3587,7 +3347,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.28 + '@types/node': 20.12.2 jest-util: 29.7.0 dev: false @@ -3623,12 +3383,12 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: chalk: 4.1.2 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 jest-haste-map: 29.7.0 jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) jest-util: 29.7.0 jest-validate: 29.7.0 - resolve: 1.22.1 + resolve: 1.22.8 resolve.exports: 2.0.2 slash: 3.0.0 dev: false @@ -3642,10 +3402,10 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.28 + '@types/node': 20.12.2 chalk: 4.1.2 emittery: 0.13.1 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 jest-docblock: 29.7.0 jest-environment-node: 29.7.0 jest-haste-map: 29.7.0 @@ -3673,12 +3433,12 @@ packages: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.28 + '@types/node': 20.12.2 chalk: 4.1.2 - cjs-module-lexer: 1.2.2 - collect-v8-coverage: 1.0.1 + cjs-module-lexer: 1.2.3 + collect-v8-coverage: 1.0.2 glob: 7.2.3 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-mock: 29.7.0 @@ -3696,18 +3456,18 @@ packages: resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@babel/core': 7.22.10 - '@babel/generator': 7.22.10 - '@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.22.10) - '@babel/plugin-syntax-typescript': 7.20.0(@babel/core@7.22.10) - '@babel/types': 7.22.10 + '@babel/core': 7.24.3 + '@babel/generator': 7.24.1 + '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.3) + '@babel/plugin-syntax-typescript': 7.24.1(@babel/core@7.24.3) + '@babel/types': 7.24.0 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.10) + babel-preset-current-node-syntax: 1.0.1(@babel/core@7.24.3) chalk: 4.1.2 expect: 29.7.0 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 jest-diff: 29.7.0 jest-get-type: 29.6.3 jest-matcher-utils: 29.7.0 @@ -3715,7 +3475,7 @@ packages: jest-util: 29.7.0 natural-compare: 1.4.0 pretty-format: 29.7.0 - semver: 7.5.4 + semver: 7.6.0 transitivePeerDependencies: - supports-color dev: false @@ -3725,10 +3485,10 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/node': 20.11.28 + '@types/node': 20.12.2 chalk: 4.1.2 - ci-info: 3.7.0 - graceful-fs: 4.2.10 + ci-info: 3.9.0 + graceful-fs: 4.2.11 picomatch: 2.3.1 dev: false @@ -3750,7 +3510,7 @@ packages: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.11.28 + '@types/node': 20.12.2 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -3762,13 +3522,13 @@ packages: resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 20.11.28 + '@types/node': 20.12.2 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 dev: false - /jest@29.7.0(@types/node@20.11.28): + /jest@29.7.0(@types/node@20.12.2): resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -3781,7 +3541,7 @@ packages: '@jest/core': 29.7.0 '@jest/types': 29.6.3 import-local: 3.1.0 - jest-cli: 29.7.0(@types/node@20.11.28) + jest-cli: 29.7.0(@types/node@20.12.2) transitivePeerDependencies: - '@types/node' - babel-plugin-macros @@ -3818,30 +3578,30 @@ packages: optional: true dependencies: abab: 2.0.6 - acorn: 8.9.0 + acorn: 8.11.3 acorn-globals: 7.0.1 cssom: 0.5.0 cssstyle: 2.3.0 data-urls: 3.0.2 decimal.js: 10.4.3 domexception: 4.0.0 - escodegen: 2.0.0 + escodegen: 2.1.0 form-data: 4.0.0 html-encoding-sniffer: 3.0.0 http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.2 + nwsapi: 2.2.7 parse5: 7.1.2 saxes: 6.0.0 symbol-tree: 3.2.4 - tough-cookie: 4.1.2 + tough-cookie: 4.1.3 w3c-xmlserializer: 4.0.0 webidl-conversions: 7.0.0 whatwg-encoding: 2.0.0 whatwg-mimetype: 3.0.0 whatwg-url: 11.0.0 - ws: 8.11.0 + ws: 8.16.0 xml-name-validator: 4.0.0 transitivePeerDependencies: - bufferutil @@ -3855,6 +3615,10 @@ packages: hasBin: true dev: false + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: false + /json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} dev: false @@ -3867,18 +3631,18 @@ packages: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} dev: false - /json5@2.2.2: - resolution: {integrity: sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==} - engines: {node: '>=6'} - hasBin: true - dev: false - /json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} hasBin: true dev: false + /keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + dependencies: + json-buffer: 3.0.1 + dev: false + /kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} @@ -3889,14 +3653,6 @@ packages: engines: {node: '>=6'} dev: false - /levn@0.3.0: - resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.1.2 - type-check: 0.3.2 - dev: false - /levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -3905,10 +3661,10 @@ packages: type-check: 0.4.0 dev: false - /lichess-pgn-viewer@2.0.1: - resolution: {integrity: sha512-WISw0/08RKQiv2gdAmIcdXNP9mg3e8Ybp31ORu9dKkl9+tRz2Q9Gx6efo5V29Pr+o6hUDTmjB7UFI1H+l4s9Ag==} + /lichess-pgn-viewer@2.1.0: + resolution: {integrity: sha512-mWr/OtdB4D55ZUvZvIvcE3jjhghrAmqgqlOTLLP2U48eMi6wqAbA9sae8mQajg4tDJuN5yNQuvxiJaFXTeiYuw==} dependencies: - '@types/node': 20.9.1 + '@types/node': 20.12.2 chessground: 9.0.4 chessops: 0.12.7 snabbdom: 3.5.1 @@ -3954,7 +3710,7 @@ packages: colorette: 2.0.20 eventemitter3: 5.0.1 log-update: 6.0.0 - rfdc: 1.3.0 + rfdc: 1.3.1 wrap-ansi: 9.0.0 dev: false @@ -3980,7 +3736,7 @@ packages: resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==} engines: {node: '>=18'} dependencies: - ansi-escapes: 6.2.0 + ansi-escapes: 6.2.1 cli-cursor: 4.0.0 slice-ansi: 7.1.0 strip-ansi: 7.1.0 @@ -4007,11 +3763,11 @@ packages: yallist: 4.0.0 dev: false - /make-dir@3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} + /make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} dependencies: - semver: 6.3.1 + semver: 7.6.0 dev: false /makeerror@1.0.12: @@ -4088,10 +3844,6 @@ packages: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} dev: false - /node-releases@2.0.13: - resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} - dev: false - /node-releases@2.0.14: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} dev: false @@ -4112,15 +3864,15 @@ packages: path-key: 3.1.1 dev: false - /npm-run-path@5.1.0: - resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} + /npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: path-key: 4.0.0 dev: false - /nwsapi@2.2.2: - resolution: {integrity: sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==} + /nwsapi@2.2.7: + resolution: {integrity: sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ==} dev: false /object-assign@4.1.1: @@ -4141,9 +3893,9 @@ packages: '@blakeembrey/deque': 1.0.5 '@blakeembrey/template': 1.1.0 arg: 4.1.3 - chokidar: 3.5.3 + chokidar: 3.6.0 cross-spawn: 7.0.3 - ignore: 5.2.4 + ignore: 5.3.1 tree-kill: 1.2.2 dev: false @@ -4161,18 +3913,6 @@ packages: mimic-fn: 4.0.0 dev: false - /optionator@0.8.3: - resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} - engines: {node: '>= 0.8.0'} - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.3.0 - prelude-ls: 1.1.2 - type-check: 0.3.2 - word-wrap: 1.2.3 - dev: false - /optionator@0.9.3: resolution: {integrity: sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==} engines: {node: '>= 0.8.0'} @@ -4185,8 +3925,8 @@ packages: type-check: 0.4.0 dev: false - /orderedmap@2.1.0: - resolution: {integrity: sha512-/pIFexOm6S70EPdznemIz3BQZoJ4VTFrhqzu0ACBqBgeLsLxq8e6Jim63ImIfwW/zAD1AlXpRMlOv3aghmo4dA==} + /orderedmap@2.1.1: + resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} dev: false /p-limit@2.3.0: @@ -4233,7 +3973,7 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} dependencies: - '@babel/code-frame': 7.22.10 + '@babel/code-frame': 7.24.2 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -4289,8 +4029,8 @@ packages: hasBin: true dev: false - /pirates@4.0.5: - resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} + /pirates@4.0.6: + resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} engines: {node: '>= 6'} dev: false @@ -4301,11 +4041,6 @@ packages: find-up: 4.1.0 dev: false - /prelude-ls@1.1.2: - resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} - engines: {node: '>= 0.8.0'} - dev: false - /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -4342,75 +4077,76 @@ packages: react-is: 16.13.1 dev: false - /prosemirror-commands@1.1.12: - resolution: {integrity: sha512-+CrMs3w/ZVPSkR+REg8KL/clyFLv/1+SgY/OMN+CB22Z24j9TZDje72vL36lOZ/E4NeRXuiCcmENcW/vAcG67A==} + /prosemirror-commands@1.5.2: + resolution: {integrity: sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ==} dependencies: - prosemirror-model: 1.18.3 - prosemirror-state: 1.4.2 - prosemirror-transform: 1.7.0 + prosemirror-model: 1.19.4 + prosemirror-state: 1.4.3 + prosemirror-transform: 1.8.0 dev: false - /prosemirror-history@1.1.3: - resolution: {integrity: sha512-zGDotijea+vnfnyyUGyiy1wfOQhf0B/b6zYcCouBV8yo6JmrE9X23M5q7Nf/nATywEZbgRLG70R4DmfSTC+gfg==} + /prosemirror-history@1.4.0: + resolution: {integrity: sha512-UUiGzDVcqo1lovOPdi9YxxUps3oBFWAIYkXLu3Ot+JPv1qzVogRbcizxK3LhHmtaUxclohgiOVesRw5QSlMnbQ==} dependencies: - prosemirror-state: 1.4.2 - prosemirror-transform: 1.7.0 - rope-sequence: 1.3.3 + prosemirror-state: 1.4.3 + prosemirror-transform: 1.8.0 + prosemirror-view: 1.33.3 + rope-sequence: 1.3.4 dev: false - /prosemirror-inputrules@1.1.3: - resolution: {integrity: sha512-ZaHCLyBtvbyIHv0f5p6boQTIJjlD6o2NPZiEaZWT2DA+j591zS29QQEMT4lBqwcLW3qRSf7ZvoKNbf05YrsStw==} + /prosemirror-inputrules@1.4.0: + resolution: {integrity: sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg==} dependencies: - prosemirror-state: 1.4.2 - prosemirror-transform: 1.7.0 + prosemirror-state: 1.4.3 + prosemirror-transform: 1.8.0 dev: false - /prosemirror-keymap@1.1.5: - resolution: {integrity: sha512-8SZgPH3K+GLsHL2wKuwBD9rxhsbnVBTwpHCO4VUO5GmqUQlxd/2GtBVWTsyLq4Dp3N9nGgPd3+lZFKUDuVp+Vw==} + /prosemirror-keymap@1.2.2: + resolution: {integrity: sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==} dependencies: - prosemirror-state: 1.4.2 - w3c-keyname: 2.2.6 + prosemirror-state: 1.4.3 + w3c-keyname: 2.2.8 dev: false - /prosemirror-model@1.18.3: - resolution: {integrity: sha512-yUVejauEY3F1r7PDy4UJKEGeIU+KFc71JQl5sNvG66CLVdKXRjhWpBW6KMeduGsmGOsw85f6EGrs6QxIKOVILA==} + /prosemirror-model@1.19.4: + resolution: {integrity: sha512-RPmVXxUfOhyFdayHawjuZCxiROsm9L4FCUA6pWI+l7n2yCBsWy9VpdE1hpDHUS8Vad661YLY9AzqfjLhAKQ4iQ==} dependencies: - orderedmap: 2.1.0 + orderedmap: 2.1.1 dev: false - /prosemirror-state@1.4.2: - resolution: {integrity: sha512-puuzLD2mz/oTdfgd8msFbe0A42j5eNudKAAPDB0+QJRw8cO1ygjLmhLrg9RvDpf87Dkd6D4t93qdef00KKNacQ==} + /prosemirror-state@1.4.3: + resolution: {integrity: sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==} dependencies: - prosemirror-model: 1.18.3 - prosemirror-transform: 1.7.0 - prosemirror-view: 1.29.1 + prosemirror-model: 1.19.4 + prosemirror-transform: 1.8.0 + prosemirror-view: 1.33.3 dev: false - /prosemirror-transform@1.7.0: - resolution: {integrity: sha512-O4T697Cqilw06Zvc3Wm+e237R6eZtJL/xGMliCi+Uo8VL6qHk6afz1qq0zNjT3eZMuYwnP8ZS0+YxX/tfcE9TQ==} + /prosemirror-transform@1.8.0: + resolution: {integrity: sha512-BaSBsIMv52F1BVVMvOmp1yzD3u65uC3HTzCBQV1WDPqJRQ2LuHKcyfn0jwqodo8sR9vVzMzZyI+Dal5W9E6a9A==} dependencies: - prosemirror-model: 1.18.3 + prosemirror-model: 1.19.4 dev: false - /prosemirror-view@1.29.1: - resolution: {integrity: sha512-OhujVZSDsh0l0PyHNdfaBj6DBkbhYaCfbaxmTeFrMKd/eWS+G6IC+OAbmR9IsLC8Se1HSbphMaXnsXjupHL3UQ==} + /prosemirror-view@1.33.3: + resolution: {integrity: sha512-P4Ao/bc4OrU/2yLIf8dL4lJaEtjLR3QjIvQHgJYp2jUS7kYM4bSR6okbBjkqzOs/FwUon6UGjTLdKMnPL1MZqw==} dependencies: - prosemirror-model: 1.18.3 - prosemirror-state: 1.4.2 - prosemirror-transform: 1.7.0 + prosemirror-model: 1.19.4 + prosemirror-state: 1.4.3 + prosemirror-transform: 1.8.0 dev: false /psl@1.9.0: resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} dev: false - /punycode@2.3.0: - resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + /punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} dev: false - /pure-rand@6.0.2: - resolution: {integrity: sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==} + /pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} dev: false /querystringify@2.2.0: @@ -4467,11 +4203,11 @@ packages: engines: {node: '>=10'} dev: false - /resolve@1.22.1: - resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true dependencies: - is-core-module: 2.11.0 + is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 dev: false @@ -4489,8 +4225,8 @@ packages: engines: {iojs: '>=1.0.0', node: '>=0.10.0'} dev: false - /rfdc@1.3.0: - resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} + /rfdc@1.3.1: + resolution: {integrity: sha512-r5a3l5HzYlIC68TpmYKlxWjmOP6wiPJ1vWv2HeLhNsRZMrCkxeqxiHlQ21oXmQ4F3SiryXBHhAD7JZqvOJjFmg==} dev: false /rimraf@3.0.2: @@ -4500,8 +4236,8 @@ packages: glob: 7.2.3 dev: false - /rope-sequence@1.3.3: - resolution: {integrity: sha512-85aZYCxweiD5J8yTEbw+E6A27zSnLPNDL0WfPdw3YYodq7WjnTKo0q4dtyQ2gz23iPT8Q9CUyJtAaUNcTxRf5Q==} + /rope-sequence@1.3.4: + resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} dev: false /run-parallel@1.2.0: @@ -4514,8 +4250,8 @@ packages: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} dev: false - /sax@1.2.4: - resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==} + /sax@1.3.0: + resolution: {integrity: sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA==} dev: false /saxes@6.0.0: @@ -4530,8 +4266,8 @@ packages: hasBin: true dev: false - /semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + /semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} engines: {node: '>=10'} hasBin: true dependencies: @@ -4554,7 +4290,7 @@ packages: resolution: {integrity: sha512-2hbz3N7GuuTjI7y3sfnoqKnH0cNhExx67IJtCTGQI2KhBEyvegsDYW5qjj5BlvvVtQjmL/O/J1GQEciwfoZWpw==} engines: {node: 16.* || >= 18} dependencies: - '@floating-ui/dom': 1.5.3 + '@floating-ui/dom': 1.6.3 deepmerge: 4.3.1 dev: false @@ -4822,12 +4558,12 @@ packages: is-number: 7.0.0 dev: false - /tough-cookie@4.1.2: - resolution: {integrity: sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==} + /tough-cookie@4.1.3: + resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} engines: {node: '>=6'} dependencies: psl: 1.9.0 - punycode: 2.3.0 + punycode: 2.3.1 universalify: 0.2.0 url-parse: 1.5.10 dev: false @@ -4836,7 +4572,7 @@ packages: resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} engines: {node: '>=12'} dependencies: - punycode: 2.3.0 + punycode: 2.3.1 dev: false /tree-kill@1.2.2: @@ -4844,20 +4580,13 @@ packages: hasBin: true dev: false - /ts-api-utils@1.0.1(typescript@5.4.2): - resolution: {integrity: sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==} - engines: {node: '>=16.13.0'} + /ts-api-utils@1.3.0(typescript@5.4.3): + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' dependencies: - typescript: 5.4.2 - dev: false - - /type-check@0.3.2: - resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.1.2 + typescript: 5.4.3 dev: false /type-check@0.4.0: @@ -4882,17 +4611,12 @@ packages: engines: {node: '>=10'} dev: false - /type-fest@3.13.1: - resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} - engines: {node: '>=14.16'} - dev: false - /types-serviceworker@0.0.1: resolution: {integrity: sha512-EKO/SZ3AsHEZsqv+bsdlTCz5k955riOksnYGlG6JhVwNTVsPWj/TScTbiNVZ5+mmX8TcEXF0C8aSxUw0jTDpIw==} dev: false - /typescript@5.4.2: - resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==} + /typescript@5.4.3: + resolution: {integrity: sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==} engines: {node: '>=14.17'} hasBin: true dev: false @@ -4910,17 +4634,6 @@ packages: engines: {node: '>= 4.0.0'} dev: false - /update-browserslist-db@1.0.11(browserslist@4.21.10): - resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - dependencies: - browserslist: 4.21.10 - escalade: 3.1.1 - picocolors: 1.0.0 - dev: false - /update-browserslist-db@1.0.13(browserslist@4.23.0): resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true @@ -4928,14 +4641,14 @@ packages: browserslist: '>= 4.21.0' dependencies: browserslist: 4.23.0 - escalade: 3.1.1 + escalade: 3.1.2 picocolors: 1.0.0 dev: false /uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: - punycode: 2.3.0 + punycode: 2.3.1 dev: false /url-parse@1.5.10: @@ -4950,13 +4663,13 @@ packages: hasBin: true dev: false - /v8-to-istanbul@9.0.1: - resolution: {integrity: sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==} + /v8-to-istanbul@9.2.0: + resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} engines: {node: '>=10.12.0'} dependencies: - '@jridgewell/trace-mapping': 0.3.19 - '@types/istanbul-lib-coverage': 2.0.4 - convert-source-map: 1.9.0 + '@jridgewell/trace-mapping': 0.3.25 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 dev: false /vosk-browser@0.0.8: @@ -4965,8 +4678,8 @@ packages: uuid: 9.0.0 dev: false - /w3c-keyname@2.2.6: - resolution: {integrity: sha512-f+fciywl1SJEniZHD6H+kUO8gOnwIr7f4ijKA6+ZvJFjeGi1r4PDLl53Ayud9O/rk64RqgoQine0feoeOU0kXg==} + /w3c-keyname@2.2.8: + resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} dev: false /w3c-xmlserializer@4.0.0: @@ -5015,11 +4728,6 @@ packages: isexe: 2.0.0 dev: false - /word-wrap@1.2.3: - resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} - engines: {node: '>=0.10.0'} - dev: false - /wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -5050,12 +4758,12 @@ packages: signal-exit: 3.0.7 dev: false - /ws@8.11.0: - resolution: {integrity: sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==} + /ws@8.16.0: + resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 + utf-8-validate: '>=5.0.2' peerDependenciesMeta: bufferutil: optional: true @@ -5072,7 +4780,7 @@ packages: resolution: {integrity: sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==} engines: {node: '>=4.0.0'} dependencies: - sax: 1.2.4 + sax: 1.3.0 xmlbuilder: 11.0.1 dev: false @@ -5108,12 +4816,12 @@ packages: engines: {node: '>=12'} dev: false - /yargs@17.6.2: - resolution: {integrity: sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==} + /yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} dependencies: cliui: 8.0.1 - escalade: 3.1.1 + escalade: 3.1.2 get-caller-file: 2.0.5 require-directory: 2.1.1 string-width: 4.2.3 diff --git a/public/css/README b/public/css/README deleted file mode 100644 index 7db2043cb4578..0000000000000 --- a/public/css/README +++ /dev/null @@ -1,2 +0,0 @@ -Don't modify these files. -They are generated from SCSS code in ui/ modules. diff --git a/ui/.build/package.json b/ui/.build/package.json index 24a656a1beb35..a276a56dffea3 100644 --- a/ui/.build/package.json +++ b/ui/.build/package.json @@ -6,10 +6,12 @@ "license": "AGPL-3.0-or-later", "type": "commonjs", "dependencies": { - "@types/node": "^20.11.28", - "typescript": "^5.4.2", + "@types/node": "^20.11.30", + "@types/tinycolor2": "^1.4.6", "esbuild": "^0.20.2", - "fast-glob": "^3.3.2" + "fast-glob": "^3.3.2", + "tinycolor2": "^1.6.0", + "typescript": "^5.4.3" }, "scripts": { "dev": "tsc && node dist/main.js" diff --git a/ui/.build/readme b/ui/.build/readme index 9a3c63fd90e4a..d36c0bc9d1bb9 100644 --- a/ui/.build/readme +++ b/ui/.build/readme @@ -22,7 +22,7 @@ Options: Examples: ./build -c # clean build artifacts, exit without building - ./build -d # build client sssets with site.debug = true + ./build -d # build client assets with site.debug = true ./build -wn # build, watch for changes, no pnpm install ./build -r # build, watch, and rebuild on package.json change ./build -rd # build, watch, rebuild on package.json change, site.debug = true diff --git a/ui/.build/src/build.ts b/ui/.build/src/build.ts index fdc5dacee00c1..52e82aba8372b 100644 --- a/ui/.build/src/build.ts +++ b/ui/.build/src/build.ts @@ -6,7 +6,7 @@ import { tsc, stopTsc } from './tsc'; import { sass, stopSass } from './sass'; import { esbuild, stopEsbuild } from './esbuild'; import { copies, stopCopies } from './copies'; -import { startTickling, stopTickling } from './tickler'; +import { startMonitor, stopMonitor } from './monitor'; import { clean } from './clean'; import { LichessModule, env, errorMark, colors as c } from './main'; @@ -30,16 +30,21 @@ export async function build(mods: string[]) { if (mods.length) env.log(`Building ${c.grey(buildModules.map(x => x.name).join(', '))}`); - await Promise.allSettled([fs.promises.mkdir(env.jsDir), fs.promises.mkdir(env.cssDir)]); + await Promise.allSettled([ + fs.promises.mkdir(env.jsDir), + fs.promises.mkdir(env.cssDir), + fs.promises.mkdir(env.themeGenDir), + fs.promises.mkdir(env.cssTempDir), + ]); sass(); await tsc(); await copies(); await esbuild(); - startTickling(mods); + startMonitor(mods); } export async function stop() { - stopTickling(); + stopMonitor(); stopSass(); stopTsc(); stopCopies(); diff --git a/ui/.build/src/clean.ts b/ui/.build/src/clean.ts index 4e0df6824a1e4..ef6912907bcd5 100644 --- a/ui/.build/src/clean.ts +++ b/ui/.build/src/clean.ts @@ -9,23 +9,24 @@ const globOpts: fg.Options = { markDirectories: true, }; +const globs = [ + '**/node_modules', + '**/css/**/gen', + 'ui/.build/dist/css', + 'ui/*/dist', + 'ui/*/tsconfig.tsbuildinfo', + 'public/compiled', + 'public/npm', + 'public/css/*.css*', +]; + export async function clean() { if (!env.clean) return; - const globs = [ - '**/node_modules', - 'ui/*/dist', - 'ui/*/tsconfig.tsbuildinfo', - 'public/compiled', - 'public/npm', - 'public/css/*.css*', - ]; - if (env.cleanTheme) globs.push('**/css/build/gen'); - for (const glob of globs) { env.log(`Cleaning '${c.cyan(glob)}'...`); for await (const f of fg.stream(glob, { cwd: env.rootDir, ...globOpts })) { - if (f.includes('ui/.build')) continue; + if (f.includes('ui/.build') && !f.includes('dist/css')) continue; if (f[f.length - 1] === '/') await fs.rm(f, { recursive: true }); else await fs.unlink(f); } diff --git a/ui/.build/src/copies.ts b/ui/.build/src/copies.ts index c0ff27b7dfd93..c9f36ef80ca19 100644 --- a/ui/.build/src/copies.ts +++ b/ui/.build/src/copies.ts @@ -1,34 +1,34 @@ import * as fs from 'node:fs'; import * as path from 'node:path'; import { globArray } from './parse'; -import { Copy, env, errorMark, colors as c } from './main'; +import { Sync, env, errorMark, colors as c } from './main'; import { buildModules } from './build'; const globRe = /[*?!{}[\]()]|\*\*|\[[^[\]]*\]/; -const copyWatch: fs.FSWatcher[] = []; +const syncWatch: fs.FSWatcher[] = []; let watchTimeout: NodeJS.Timeout | undefined; export function stopCopies() { clearTimeout(watchTimeout); watchTimeout = undefined; - for (const watcher of copyWatch) watcher.close(); - copyWatch.length = 0; + for (const watcher of syncWatch) watcher.close(); + syncWatch.length = 0; } export async function copies() { if (!env.copies) return; - const watched = new Map