mirror of
https://github.com/praktimarc/kst4contest.git
synced 2026-10-26 16:15:51 +01:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c23982c339 | ||
|
|
834f4b131a | ||
|
|
1868f21c06 | ||
|
|
9d433f9ba4 | ||
|
|
f4f046c04f | ||
|
|
8fc3b9f424 |
No files matched your search
+3
-1
@@ -55,6 +55,7 @@ class CompactControlsVisualRenderingTest(@param:TempDir private val tempDir: Pat
|
|||||||
}
|
}
|
||||||
val filters = StationFilterState()
|
val filters = StationFilterState()
|
||||||
|
|
||||||
|
return onEventThread {
|
||||||
val scene = ImageComposeScene(width = 1366, height = 380, density = Density(scale)) {
|
val scene = ImageComposeScene(width = 1366, height = 380, density = Density(scale)) {
|
||||||
Kst4ContestTheme(darkMode = darkMode, baseFontSizeSp = 12f) {
|
Kst4ContestTheme(darkMode = darkMode, baseFontSizeSp = 12f) {
|
||||||
Surface(
|
Surface(
|
||||||
@@ -90,12 +91,13 @@ class CompactControlsVisualRenderingTest(@param:TempDir private val tempDir: Pat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return try {
|
try {
|
||||||
scene.render().encodeToData()!!.bytes
|
scene.render().encodeToData()!!.bytes
|
||||||
} finally {
|
} finally {
|
||||||
scene.close()
|
scene.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class RenderActions(private val preferences: ChatPreferences) : ChatInputActions {
|
private class RenderActions(private val preferences: ChatPreferences) : ChatInputActions {
|
||||||
override fun panelSelection(): ChatMember? = null
|
override fun panelSelection(): ChatMember? = null
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package kst4contest.view.compose
|
||||||
|
|
||||||
|
import java.awt.EventQueue
|
||||||
|
import java.lang.reflect.InvocationTargetException
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An ImageComposeScene must live on the AWT event thread, the thread the application renders
|
||||||
|
* on. Compose Multiplatform 1.8.2 sends the global snapshot notifications there
|
||||||
|
* (GlobalSnapshotManager), and doing so takes two locks in the opposite order from a render
|
||||||
|
* on any other thread:
|
||||||
|
*
|
||||||
|
* - the render holds the scene's FlushCoroutineDispatcher runLock while a task it runs
|
||||||
|
* (here LazyListState.scrollToItem) measures and wants the SnapshotStateObserver's
|
||||||
|
* observedScopeMapsLock;
|
||||||
|
* - the event thread holds observedScopeMapsLock in drainChanges while a derived state it
|
||||||
|
* re-reads wakes a snapshotFlow collector of that scene, whose dispatch wants runLock.
|
||||||
|
*
|
||||||
|
* Both waited forever in CI runs 40252077018, 40252089738 and 40299943329; the thread dump of
|
||||||
|
* the last one shows both stacks. On one thread the two monitors are simply re-entered, which
|
||||||
|
* is why the application never hangs this way.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs [block] on the AWT event thread, waits for it and returns its result. Whatever
|
||||||
|
* [block] throws is rethrown here unwrapped, so a failed assertion still reads as one.
|
||||||
|
*/
|
||||||
|
internal fun <T> onEventThread(block: () -> T): T {
|
||||||
|
if (EventQueue.isDispatchThread()) return block()
|
||||||
|
|
||||||
|
var result: Result<T>? = null
|
||||||
|
try {
|
||||||
|
EventQueue.invokeAndWait { result = runCatching(block) }
|
||||||
|
} catch (wrapped: InvocationTargetException) {
|
||||||
|
throw wrapped.cause ?: wrapped
|
||||||
|
}
|
||||||
|
return result!!.getOrThrow()
|
||||||
|
}
|
||||||
+3
-1
@@ -84,6 +84,7 @@ class SelectedStationMessageUiVisualRenderingTest {
|
|||||||
replaceRows(listOf(message(member("DL1ABC", 2), member("DL2XYZ", 2), "pse sked")))
|
replaceRows(listOf(message(member("DL1ABC", 2), member("DL2XYZ", 2), "pse sked")))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return onEventThread {
|
||||||
val scene = ImageComposeScene(width = 1366, height = windowHeight, density = Density(scale)) {
|
val scene = ImageComposeScene(width = 1366, height = windowHeight, density = Density(scale)) {
|
||||||
Kst4ContestTheme(darkMode = darkMode, baseFontSizeSp = 12f) {
|
Kst4ContestTheme(darkMode = darkMode, baseFontSizeSp = 12f) {
|
||||||
Surface(
|
Surface(
|
||||||
@@ -111,12 +112,13 @@ class SelectedStationMessageUiVisualRenderingTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return try {
|
try {
|
||||||
scene.render().encodeToData()!!.bytes
|
scene.render().encodeToData()!!.bytes
|
||||||
} finally {
|
} finally {
|
||||||
scene.close()
|
scene.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun messageTable() = DataTableState(
|
private fun messageTable() = DataTableState(
|
||||||
columns = listOf(
|
columns = listOf(
|
||||||
|
|||||||
+3
-1
@@ -87,6 +87,7 @@ class StationWorkspaceVisualRenderingTest {
|
|||||||
RowKeys.byReference<ChatMessage>(),
|
RowKeys.byReference<ChatMessage>(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return onEventThread {
|
||||||
val scene = ImageComposeScene(
|
val scene = ImageComposeScene(
|
||||||
width = 1366,
|
width = 1366,
|
||||||
height = scenario.height,
|
height = scenario.height,
|
||||||
@@ -139,12 +140,13 @@ class StationWorkspaceVisualRenderingTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return try {
|
try {
|
||||||
scene.render().encodeToData()!!.bytes
|
scene.render().encodeToData()!!.bytes
|
||||||
} finally {
|
} finally {
|
||||||
scene.close()
|
scene.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun member(callSign: String, category: Int) = ChatMember().apply {
|
private fun member(callSign: String, category: Int) = ChatMember().apply {
|
||||||
this.callSign = callSign
|
this.callSign = callSign
|
||||||
|
|||||||
+4
@@ -32,6 +32,7 @@ class TopPriorityCandidatesWindowTest {
|
|||||||
/** Runs [block] against a rendered list of [twoCandidates] and reports what it picked. */
|
/** Runs [block] against a rendered list of [twoCandidates] and reports what it picked. */
|
||||||
private fun picking(block: (ImageComposeScene) -> Unit): String? {
|
private fun picking(block: (ImageComposeScene) -> Unit): String? {
|
||||||
var picked: String? = null
|
var picked: String? = null
|
||||||
|
onEventThread {
|
||||||
val scene = ImageComposeScene(width = 360, height = 500, density = Density(1f)) {
|
val scene = ImageComposeScene(width = 360, height = 500, density = Density(1f)) {
|
||||||
TopPriorityCandidatesWindow.CandidateListForTest(twoCandidates) {
|
TopPriorityCandidatesWindow.CandidateListForTest(twoCandidates) {
|
||||||
picked = it.displayCallSign
|
picked = it.displayCallSign
|
||||||
@@ -44,6 +45,7 @@ class TopPriorityCandidatesWindowTest {
|
|||||||
} finally {
|
} finally {
|
||||||
scene.close()
|
scene.close()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return picked
|
return picked
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,6 +80,7 @@ class TopPriorityCandidatesWindowTest {
|
|||||||
@Test
|
@Test
|
||||||
fun `the list renders with candidates and without`() {
|
fun `the list renders with candidates and without`() {
|
||||||
listOf(emptyList(), twoCandidates).forEach { ranking ->
|
listOf(emptyList(), twoCandidates).forEach { ranking ->
|
||||||
|
onEventThread {
|
||||||
val scene = ImageComposeScene(width = 360, height = 500, density = Density(1f)) {
|
val scene = ImageComposeScene(width = 360, height = 500, density = Density(1f)) {
|
||||||
TopPriorityCandidatesWindow.CandidateListForTest(ranking) { }
|
TopPriorityCandidatesWindow.CandidateListForTest(ranking) { }
|
||||||
}
|
}
|
||||||
@@ -88,6 +91,7 @@ class TopPriorityCandidatesWindowTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A double click picks the candidate under it, and picks the right one.
|
* A double click picks the candidate under it, and picks the right one.
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||||||
import androidx.compose.ui.ImageComposeScene
|
import androidx.compose.ui.ImageComposeScene
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.Density
|
import androidx.compose.ui.unit.Density
|
||||||
|
import kst4contest.view.compose.onEventThread
|
||||||
import kst4contest.view.map.MapCallsignRawSnapshot
|
import kst4contest.view.map.MapCallsignRawSnapshot
|
||||||
import kst4contest.view.map.MapViewport
|
import kst4contest.view.map.MapViewport
|
||||||
import kst4contest.view.map.TileFetcher
|
import kst4contest.view.map.TileFetcher
|
||||||
@@ -71,6 +72,7 @@ class ComposeStationMapDrawingTest {
|
|||||||
workedGrossFields: Set<String> = emptySet(),
|
workedGrossFields: Set<String> = emptySet(),
|
||||||
darkMode: Boolean = true,
|
darkMode: Boolean = true,
|
||||||
): BufferedImage {
|
): BufferedImage {
|
||||||
|
return onEventThread {
|
||||||
val scene = ImageComposeScene(canvasWidth, canvasHeight, Density(1f)) {
|
val scene = ImageComposeScene(canvasWidth, canvasHeight, Density(1f)) {
|
||||||
ComposeStationMap(
|
ComposeStationMap(
|
||||||
markers = markers,
|
markers = markers,
|
||||||
@@ -89,11 +91,12 @@ class ComposeStationMapDrawingTest {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
return ImageIO.read(ByteArrayInputStream(scene.render().encodeToData()!!.bytes))
|
ImageIO.read(ByteArrayInputStream(scene.render().encodeToData()!!.bytes))
|
||||||
} finally {
|
} finally {
|
||||||
scene.close()
|
scene.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun countColour(image: BufferedImage, rgb: Int): Int {
|
private fun countColour(image: BufferedImage, rgb: Int): Int {
|
||||||
var count = 0
|
var count = 0
|
||||||
|
|||||||
+3
@@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||||||
import androidx.compose.ui.ImageComposeScene
|
import androidx.compose.ui.ImageComposeScene
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.Density
|
import androidx.compose.ui.unit.Density
|
||||||
|
import kst4contest.view.compose.onEventThread
|
||||||
import kst4contest.view.map.MapCallsignRawSnapshot
|
import kst4contest.view.map.MapCallsignRawSnapshot
|
||||||
import kst4contest.view.map.TileFetcher
|
import kst4contest.view.map.TileFetcher
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
@@ -33,6 +34,7 @@ class ComposeStationMapLayoutTest {
|
|||||||
)
|
)
|
||||||
|
|
||||||
private fun renderAt(widthPx: Int, heightPx: Int, zoom: Float) {
|
private fun renderAt(widthPx: Int, heightPx: Int, zoom: Float) {
|
||||||
|
onEventThread {
|
||||||
val scene = ImageComposeScene(
|
val scene = ImageComposeScene(
|
||||||
width = widthPx,
|
width = widthPx,
|
||||||
height = heightPx,
|
height = heightPx,
|
||||||
@@ -59,6 +61,7 @@ class ComposeStationMapLayoutTest {
|
|||||||
scene.close()
|
scene.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `renders at a normal window size and integer zoom`() = renderAt(900, 600, 6f)
|
fun `renders at a normal window size and integer zoom`() = renderAt(900, 600, 6f)
|
||||||
|
|||||||
+3
@@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.ui.ImageComposeScene
|
import androidx.compose.ui.ImageComposeScene
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.Density
|
import androidx.compose.ui.unit.Density
|
||||||
|
import kst4contest.view.compose.onEventThread
|
||||||
import kst4contest.view.map.PathAnalysisResult
|
import kst4contest.view.map.PathAnalysisResult
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
@@ -25,6 +26,7 @@ class PathAnalysisDetailsLayoutTest {
|
|||||||
private val narrowWidthPx = 120
|
private val narrowWidthPx = 120
|
||||||
|
|
||||||
private fun renderAt(widthPx: Int, result: PathAnalysisResult?) {
|
private fun renderAt(widthPx: Int, result: PathAnalysisResult?) {
|
||||||
|
onEventThread {
|
||||||
val scene = ImageComposeScene(
|
val scene = ImageComposeScene(
|
||||||
width = widthPx,
|
width = widthPx,
|
||||||
height = 600,
|
height = 600,
|
||||||
@@ -42,6 +44,7 @@ class PathAnalysisDetailsLayoutTest {
|
|||||||
scene.close()
|
scene.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `renders when the column is narrower than the assessment label`() {
|
fun `renders when the column is narrower than the assessment label`() {
|
||||||
|
|||||||
+4
-1
@@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
|||||||
import androidx.compose.ui.ImageComposeScene
|
import androidx.compose.ui.ImageComposeScene
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.Density
|
import androidx.compose.ui.unit.Density
|
||||||
|
import kst4contest.view.compose.onEventThread
|
||||||
import kst4contest.view.map.PathAnalysisResult
|
import kst4contest.view.map.PathAnalysisResult
|
||||||
import org.junit.jupiter.api.Assertions.assertTrue
|
import org.junit.jupiter.api.Assertions.assertTrue
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
@@ -31,6 +32,7 @@ class PathAnalysisDetailsWidthTest {
|
|||||||
private val assessmentBackground = 0x33383E
|
private val assessmentBackground = 0x33383E
|
||||||
|
|
||||||
private fun render(paneWidthPx: Int, heightPx: Int = 600): BufferedImage {
|
private fun render(paneWidthPx: Int, heightPx: Int = 600): BufferedImage {
|
||||||
|
return onEventThread {
|
||||||
val scene = ImageComposeScene(width = paneWidthPx, height = heightPx, density = Density(1f)) {
|
val scene = ImageComposeScene(width = paneWidthPx, height = heightPx, density = Density(1f)) {
|
||||||
PathAnalysisDetails(
|
PathAnalysisDetails(
|
||||||
result = PathAnalysisResult.loading("JO50JP", "JN24JB", "F5JMI"),
|
result = PathAnalysisResult.loading("JO50JP", "JN24JB", "F5JMI"),
|
||||||
@@ -40,11 +42,12 @@ class PathAnalysisDetailsWidthTest {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
val png = scene.render().encodeToData()!!.bytes
|
val png = scene.render().encodeToData()!!.bytes
|
||||||
return ImageIO.read(ByteArrayInputStream(png))
|
ImageIO.read(ByteArrayInputStream(png))
|
||||||
} finally {
|
} finally {
|
||||||
scene.close()
|
scene.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** The smallest x at which the assessment background appears, or -1 when it does not. */
|
/** The smallest x at which the assessment background appears, or -1 when it does not. */
|
||||||
private fun assessmentLeftEdge(image: BufferedImage): Int {
|
private fun assessmentLeftEdge(image: BufferedImage): Int {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||||||
import androidx.compose.ui.ImageComposeScene
|
import androidx.compose.ui.ImageComposeScene
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.unit.Density
|
import androidx.compose.ui.unit.Density
|
||||||
|
import kst4contest.view.compose.onEventThread
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -18,6 +19,7 @@ import org.junit.jupiter.api.Test
|
|||||||
class PathProfileChartLayoutTest {
|
class PathProfileChartLayoutTest {
|
||||||
|
|
||||||
private fun renderAt(widthPx: Int, heightPx: Int) {
|
private fun renderAt(widthPx: Int, heightPx: Int) {
|
||||||
|
onEventThread {
|
||||||
val scene = ImageComposeScene(
|
val scene = ImageComposeScene(
|
||||||
width = widthPx,
|
width = widthPx,
|
||||||
height = heightPx,
|
height = heightPx,
|
||||||
@@ -31,6 +33,7 @@ class PathProfileChartLayoutTest {
|
|||||||
scene.close()
|
scene.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `renders at the height the window gives it`() = renderAt(800, 210)
|
fun `renders at the height the window gives it`() = renderAt(800, 210)
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import androidx.compose.ui.unit.dp
|
|||||||
import kst4contest.view.compose.SplitterOrientation
|
import kst4contest.view.compose.SplitterOrientation
|
||||||
import kst4contest.view.compose.SplitterPane
|
import kst4contest.view.compose.SplitterPane
|
||||||
import kst4contest.view.compose.SplitterState
|
import kst4contest.view.compose.SplitterState
|
||||||
|
import kst4contest.view.compose.onEventThread
|
||||||
import kst4contest.view.map.MapCallsignRawSnapshot
|
import kst4contest.view.map.MapCallsignRawSnapshot
|
||||||
import kst4contest.view.map.PathAnalysisResult
|
import kst4contest.view.map.PathAnalysisResult
|
||||||
import kst4contest.view.map.TileFetcher
|
import kst4contest.view.map.TileFetcher
|
||||||
@@ -88,6 +89,7 @@ class StationMapBodyLayoutTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun renderAt(widthPx: Int, heightPx: Int, pathAnalysisVisible: Boolean = true) {
|
private fun renderAt(widthPx: Int, heightPx: Int, pathAnalysisVisible: Boolean = true) {
|
||||||
|
onEventThread {
|
||||||
val scene = ImageComposeScene(width = widthPx, height = heightPx, density = Density(1f)) {
|
val scene = ImageComposeScene(width = widthPx, height = heightPx, density = Density(1f)) {
|
||||||
Body(pathAnalysisVisible)
|
Body(pathAnalysisVisible)
|
||||||
}
|
}
|
||||||
@@ -97,6 +99,7 @@ class StationMapBodyLayoutTest {
|
|||||||
scene.close()
|
scene.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `renders at the window's minimum size`() = renderAt(900, 600)
|
fun `renders at the window's minimum size`() = renderAt(900, 600)
|
||||||
|
|||||||
@@ -151,6 +151,13 @@ subprojects {
|
|||||||
*/
|
*/
|
||||||
systemProperty("junit.jupiter.execution.timeout.default", "2m")
|
systemProperty("junit.jupiter.execution.timeout.default", "2m")
|
||||||
systemProperty("junit.jupiter.execution.timeout.thread.mode.default", "SEPARATE_THREAD")
|
systemProperty("junit.jupiter.execution.timeout.thread.mode.default", "SEPARATE_THREAD")
|
||||||
|
/*
|
||||||
|
* The timed-out thread's stack shows where a test waits, not who it waits for: the
|
||||||
|
* rare CI hang in SelectedStationMessageUiVisualRenderingTest blocks on a monitor
|
||||||
|
* that another thread holds. On a timeout JUnit prints all threads to the test's
|
||||||
|
* standard output, which lands in its XML report (the test-results artifact).
|
||||||
|
*/
|
||||||
|
systemProperty("junit.jupiter.execution.timeout.threaddump.enabled", "true")
|
||||||
// The default short format prints only the first frame of each cause, which for a
|
// The default short format prints only the first frame of each cause, which for a
|
||||||
// timed-out test is the line it hung in but not the call that blocked there.
|
// timed-out test is the line it hung in but not the call that blocked there.
|
||||||
testLogging {
|
testLogging {
|
||||||
|
|||||||
Generated
+19
-19
@@ -7,15 +7,15 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "kst4contest-website",
|
"name": "kst4contest-website",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"engines": {
|
|
||||||
"node": ">=18.19.1"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"markdown-it": "^14.3.0",
|
"markdown-it": "^14.3.3",
|
||||||
"markdown-it-anchor": "^9.2.0"
|
"markdown-it-anchor": "^9.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@11ty/eleventy": "^3.0.0"
|
"@11ty/eleventy": "^3.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.19.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@11ty/dependency-tree": {
|
"node_modules/@11ty/dependency-tree": {
|
||||||
@@ -397,9 +397,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "1.1.15",
|
"version": "1.1.21",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz",
|
||||||
"integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==",
|
"integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -831,9 +831,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/gray-matter/node_modules/js-yaml": {
|
"node_modules/gray-matter/node_modules/js-yaml": {
|
||||||
"version": "3.15.0",
|
"version": "3.15.2",
|
||||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.2.tgz",
|
||||||
"integrity": "sha512-ttBQIIQPDeLjpPOohtUdXuXUVoA2uIB6fEH9HyJ7234s5mBJ5wTx20njxplLZQgLaOfpmPQA7X2t5AX6tIPbog==",
|
"integrity": "sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1026,9 +1026,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/js-yaml": {
|
"node_modules/js-yaml": {
|
||||||
"version": "4.3.0",
|
"version": "4.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz",
|
||||||
"integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==",
|
"integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -1098,9 +1098,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/liquidjs": {
|
"node_modules/liquidjs": {
|
||||||
"version": "10.27.1",
|
"version": "10.30.0",
|
||||||
"resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.27.1.tgz",
|
"resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.30.0.tgz",
|
||||||
"integrity": "sha512-ylE+1q2kSef1UxAyxqbyuWM3FRWS1v48JK1Y3CoW3bD6TSNXZh0+GsVnihujEpKyR+Jejx2aRAFfC3AHm9rElg==",
|
"integrity": "sha512-Fw4wA+8CZsJkaeLEIlPE3AoponfjEZhj7FQvYNcAEcg7jNRik7mEMoaco382FBdrYlykVf6w4vClPNctz2OYjg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -1136,9 +1136,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/markdown-it": {
|
"node_modules/markdown-it": {
|
||||||
"version": "14.3.0",
|
"version": "14.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.3.tgz",
|
||||||
"integrity": "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==",
|
"integrity": "sha512-L//tDAkjTjJCU6pBUSBTgs3Kg4InVaZuUZog/b6V12UKhcDQ7S78877ibbCanRExwPuYP1CZD7Gd2dxSy1GXRg==",
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
"type": "github",
|
"type": "github",
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
"@11ty/eleventy": "^3.0.0"
|
"@11ty/eleventy": "^3.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"markdown-it": "^14.3.0",
|
"markdown-it": "^14.3.3",
|
||||||
"markdown-it-anchor": "^9.2.0"
|
"markdown-it-anchor": "^9.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user