From 0831c1aaae3787dc54e4ff4f536c698303a855f0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 Oct 2025 20:01:19 +0000 Subject: [PATCH 001/494] chore(deps): bump actions/setup-node from 3 to 6 Bumps [actions/setup-node](https://github.com/actions/setup-node) from 3 to 6. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v3...v6) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: '6' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a09aa8f7dd2..82466fcb42e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -38,7 +38,7 @@ jobs: steps: - uses: actions/checkout@v4 - name: Setup Node - uses: actions/setup-node@v3 + uses: actions/setup-node@v6 with: node-version-file: ".nvmrc" - name: Kahuna (client-side) From 1206358c2481a81567ebd54a715c66028a73a324 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Thu, 30 Oct 2025 14:28:57 +0000 Subject: [PATCH 002/494] wire up embedder to media api --- .../com/gu/mediaservice/lib/aws/Bedrock.scala | 56 +++++++++++-- .../gu/mediaservice/lib/aws/Embedder.scala | 23 +++++- .../gu/mediaservice/lib/aws/S3Vectors.scala | 30 ++++++- media-api/app/MediaApiComponents.scala | 5 +- media-api/app/controllers/MediaApi.scala | 78 ++++++++++++++++++- media-api/conf/routes | 1 + 6 files changed, 180 insertions(+), 13 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Bedrock.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Bedrock.scala index f1d816466b9..51eb7a2de6e 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Bedrock.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Bedrock.scala @@ -12,12 +12,19 @@ import play.api.libs.json.OFormat.oFormatFromReadsAndOWrites import play.api.libs.json._ object Bedrock { - private case class BedrockRequest( + private case class BedrockImageRequest( input_type: String, embedding_types: List[String], images: List[String] ) - private implicit val bedrockRequestFormat: OFormat[BedrockRequest] = Json.format[BedrockRequest] + private case class BedrockTextRequest( + input_type: String, + embedding_types: List[String], + texts: List[String] + ) + + private implicit val bedrockImageRequestFormat: OFormat[BedrockImageRequest] = Json.format[BedrockImageRequest] + private implicit val bedrockTextRequestFormat: OFormat[BedrockTextRequest] = Json.format[BedrockTextRequest] } import scala.concurrent.{ExecutionContext, Future} @@ -41,7 +48,7 @@ class Bedrock(config: CommonConfig) case CoherePng => List(s"data:image/png;base64,$base64EncodedImage") } - val body = Bedrock.BedrockRequest( + val body = Bedrock.BedrockImageRequest( input_type = "image", embedding_types = List("float"), images = images @@ -60,11 +67,11 @@ class Bedrock(config: CommonConfig) request } - private def sendBedrockEmbeddingRequest(base64EncodedImage: String, fileType: CohereCompatibleMimeType)( + private def sendBedrockEmbeddingRequest(requestBody: InvokeModelRequest)( implicit logMarker: LogMarker ): InvokeModelResponse = { try { - val response = client.invokeModel(createRequestBody(base64EncodedImage, fileType)) + val response = client.invokeModel(requestBody) logger.info( logMarker, s"Bedrock API call to create image embedding completed with status: ${response.sdkHttpResponse().statusCode()}" @@ -79,7 +86,8 @@ class Bedrock(config: CommonConfig) } def createImageEmbedding(base64EncodedImage: String, fileType: CohereCompatibleMimeType)(implicit ec: ExecutionContext, logMarker: LogMarker): Future[List[Float]] = { - val bedrockFuture = Future { sendBedrockEmbeddingRequest(base64EncodedImage, fileType) } + val requestBody = createRequestBody(base64EncodedImage, fileType) + val bedrockFuture = Future { sendBedrockEmbeddingRequest(requestBody) } bedrockFuture.map { response => val responseBody = response.body().asUtf8String() val json = Json.parse(responseBody) @@ -92,4 +100,40 @@ class Bedrock(config: CommonConfig) embedding } } + + def createSearchTermEmbedding(q: String)(implicit ec: ExecutionContext, logMarker: LogMarker): Future[List[Float]] = { + logger.info(logMarker, s"Creating embedding for search term: $q") + + val body = Bedrock.BedrockTextRequest( + input_type = "search_document", + embedding_types = List("float"), + texts = List(q) + ) + val jsonBody = Json.toJson(body).toString() + + val requestBody: InvokeModelRequest = { + InvokeModelRequest + .builder() + .accept("*/*") + .body(SdkBytes.fromUtf8String(jsonBody)) + .contentType("application/json") + .modelId("cohere.embed-english-v3") + .build() + } + + val bedrockFuture = Future { + sendBedrockEmbeddingRequest(requestBody) + } + bedrockFuture.map { response => + val responseBody = response.body().asUtf8String() + val json = Json.parse(responseBody) + // Extract the embedding array (first element since it's an array of arrays) + val embedding = (json \ "embeddings" \ "float")(0).as[List[Float]] + logger.info( + logMarker, + s"Successfully extracted search term embedding. Vector size: ${embedding.size}" + ) + embedding + } + } } diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala index 1a00db5ed02..965b9b2b1f9 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala @@ -1,11 +1,12 @@ package com.gu.mediaservice.lib.aws import com.gu.mediaservice.lib.logging.{GridLogging, LogMarker} import com.gu.mediaservice.model.{Jpeg, MimeType, Png, Tiff} -import software.amazon.awssdk.services.s3vectors.model.PutVectorsResponse +import software.amazon.awssdk.services.s3vectors.model.{PutVectorsResponse, QueryVectorsResponse, VectorData} import java.nio.file.{Files, Path} import java.util.Base64 import scala.concurrent.{ExecutionContext, Future} +import scala.jdk.CollectionConverters.SeqHasAsJava sealed trait CohereCompatibleMimeType case object CohereJpeg extends CohereCompatibleMimeType @@ -41,4 +42,24 @@ class Embedder(s3vectors: S3Vectors, bedrock: Bedrock) extends GridLogging { } } } + + private def convertEmbeddingToVectorData(embedding: List[Float]): VectorData = { + VectorData + .builder() + .float32(embedding.map(float2Float).asJava) + .build() + } + + def createEmbeddingAndSearch(q: String)(implicit ec: ExecutionContext, logMarker: LogMarker): Future[QueryVectorsResponse] = { + + logger.info(logMarker, s"Searching for image embedding for $q") + + val embeddingFuture = bedrock.createSearchTermEmbedding(q: String) + embeddingFuture.map { embedding => +// We need to convert the embedding to a VectorData object for the S3 Vector Store API + val vectorData = convertEmbeddingToVectorData(embedding) + s3vectors.searchVectorStore(vectorData) + } + } + } diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala index 4ea06a03cd6..c9f7d4e401f 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala @@ -1,10 +1,9 @@ package com.gu.mediaservice.lib.aws import com.gu.mediaservice.lib.config.CommonConfig import com.gu.mediaservice.lib.logging.LogMarker - import software.amazon.awssdk.regions.Region import software.amazon.awssdk.services.s3vectors._ -import software.amazon.awssdk.services.s3vectors.model.{PutInputVector, PutVectorsRequest, PutVectorsResponse, VectorData} +import software.amazon.awssdk.services.s3vectors.model.{PutInputVector, PutVectorsRequest, PutVectorsResponse, QueryVectorsRequest, QueryVectorsResponse, VectorData} import java.net.URI import scala.concurrent.{ExecutionContext, Future} @@ -66,4 +65,31 @@ class S3Vectors(config: CommonConfig) } } + def searchVectorStore(queryVector: VectorData)(implicit logMarker: LogMarker + ): QueryVectorsResponse = { + logger.info(logMarker, s"Searching for image embedding") + try { + val request: QueryVectorsRequest = QueryVectorsRequest + .builder() + .indexName("cohere-embed-english-v3") + .vectorBucketName(s"image-embeddings-${config.stage.toLowerCase}") + .topK(30) + .queryVector(queryVector) + .build() + + val response = client.queryVectors(request) + logger.info( + logMarker, + s"S3 Vector Store API call to search image embeddings completed with status: ${response.sdkHttpResponse().statusCode()}" + ) + logger.info(logMarker, s"${response}") + response + } + catch { + case e: Exception => + logger.error(logMarker, s"Exception during S3 Vector Store API call for query [...]", e) + throw e + } + } + } diff --git a/media-api/app/MediaApiComponents.scala b/media-api/app/MediaApiComponents.scala index b77dd908aa7..86081ccfbb7 100644 --- a/media-api/app/MediaApiComponents.scala +++ b/media-api/app/MediaApiComponents.scala @@ -1,4 +1,4 @@ -import com.gu.mediaservice.lib.aws.ThrallMessageSender +import com.gu.mediaservice.lib.aws.{Bedrock, Embedder, S3Vectors, ThrallMessageSender} import com.gu.mediaservice.lib.management.{ElasticSearchHealthCheck, InnerServiceStatusCheckController, Management} import com.gu.mediaservice.lib.metadata.SoftDeletedMetadataTable import com.gu.mediaservice.lib.play.GridComponents @@ -29,8 +29,9 @@ class MediaApiComponents(context: Context) extends GridComponents(context, new M val imageResponse = new ImageResponse(config, s3Client, usageQuota) val softDeletedMetadataTable = new SoftDeletedMetadataTable(config) + val embedder = new Embedder(new S3Vectors(config), new Bedrock(config)) - val mediaApi = new MediaApi(auth, messageSender, softDeletedMetadataTable, elasticSearch, imageResponse, config, controllerComponents, s3Client, mediaApiMetrics, wsClient, authorisation) + val mediaApi = new MediaApi(auth, messageSender, softDeletedMetadataTable, elasticSearch, imageResponse, config, controllerComponents, s3Client, mediaApiMetrics, wsClient, authorisation, embedder) val suggestionController = new SuggestionController(auth, elasticSearch, controllerComponents) val aggController = new AggregationController(auth, elasticSearch, controllerComponents) val usageController = new UsageController(auth, config, elasticSearch, usageQuota, controllerComponents) diff --git a/media-api/app/controllers/MediaApi.scala b/media-api/app/controllers/MediaApi.scala index 940e73fa673..c468e0205f9 100644 --- a/media-api/app/controllers/MediaApi.scala +++ b/media-api/app/controllers/MediaApi.scala @@ -8,7 +8,7 @@ import com.gu.mediaservice.lib.argo.model.{Action, _} import com.gu.mediaservice.lib.auth.Authentication.{Request, _} import com.gu.mediaservice.lib.auth.Permissions.{ArchiveImages, DeleteCropsOrUsages, EditMetadata, UploadImages, DeleteImage => DeleteImagePermission} import com.gu.mediaservice.lib.auth._ -import com.gu.mediaservice.lib.aws.{ContentDisposition, ThrallMessageSender, UpdateMessage} +import com.gu.mediaservice.lib.aws.{ContentDisposition, Embedder, ThrallMessageSender, UpdateMessage} import com.gu.mediaservice.lib.config.Services import com.gu.mediaservice.lib.formatting.printDateTime import com.gu.mediaservice.lib.logging.{LogMarker, MarkerMap} @@ -42,7 +42,8 @@ class MediaApi( s3Client: S3Client, mediaApiMetrics: MediaApiMetrics, ws: WSClient, - authorisation: Authorisation + authorisation: Authorisation, + embedder: Embedder, )(implicit val ec: ExecutionContext) extends BaseController with MessageSubjects with ArgoHelpers with ContentDisposition { val services: Services = new Services(config.domainRoot, config.serviceHosts, Set.empty) @@ -512,6 +513,79 @@ class MediaApi( request.post(Json.toJson(Map("data" -> usagesMetadata))) //fire and forget } + def semanticSearch(q: String) = auth.async { implicit request => + val shouldFlagGraphicImages = request.cookies.get("SHOULD_BLUR_GRAPHIC_IMAGES") + .map(_.value).getOrElse(config.defaultShouldBlurGraphicImages.toString) == "true" + + implicit val logMarker: LogMarker = MarkerMap( + "requestType" -> "semantic-image-search", + "shouldFlagGraphicImages" -> shouldFlagGraphicImages, + "requestId" -> RequestLoggingFilter.getRequestId(request) + ) ++ RequestLoggingFilter.loggablePrincipal(request.user) + + logger.info(logMarker, s"Semantic search: $q from user: ${Authentication.getIdentity(request.user)}") + +// We will send a search to the S3 Vector Store + embedder.createEmbeddingAndSearch(q) + +// We will receive 30 results + val top30Results: List[String] = List( + "59c5f086f010d2ae6da0811acf856df5162a4339", + "ba9fa9a2c484134b4b875dd30a411a66f7f7986e", + ) + + val searchParams = SearchParams( + query = Some(q), + ids = Some(top30Results), + tier = request.user.accessor.tier, + ) + + SearchParams.validate(searchParams).fold( + // TODO: respondErrorCollection? + errors => Future.successful(respondError(UnprocessableEntity, InvalidUriParams.errorKey, + errors.map(_.message).mkString(", ")) + ), + params => respondSuccess(params) + ) + + } + + private def respondSuccess(searchParams: SearchParams)(implicit request: Authentication.Request[AnyContent], logMarker: LogMarker) = { + val shouldFlagGraphicImages = request.cookies.get("SHOULD_BLUR_GRAPHIC_IMAGES") + .map(_.value).getOrElse(config.defaultShouldBlurGraphicImages.toString) == "true" + + implicit val logMarker: LogMarker = MarkerMap( + "requestType" -> "image-search", + "shouldFlagGraphicImages" -> shouldFlagGraphicImages, + "requestId" -> RequestLoggingFilter.getRequestId(request) + ) ++ RequestLoggingFilter.loggablePrincipal(request.user) + + val include = getIncludedFromParams(request) + + def hitToImageEntity(elasticId: String, image: SourceWrapper[Image]): EmbeddedEntity[JsValue] = { + val writePermission = authorisation.isUploaderOrHasPermission(request.user, image.instance.uploadedBy, EditMetadata) + val deletePermission = authorisation.isUploaderOrHasPermission(request.user, image.instance.uploadedBy, DeleteImagePermission) + val deleteCropsOrUsagePermission = canUserDeleteCropsOrUsages(request.user) + + val (imageData, imageLinks, imageActions) = + imageResponse.create(elasticId, image, writePermission, deletePermission, deleteCropsOrUsagePermission, include, request.user.accessor.tier) + val id = (imageData \ "id").as[String] + val imageUri = URI.create(s"${config.rootUri}/images/$id") + EmbeddedEntity(uri = imageUri, data = Some(imageData), imageLinks, imageActions) + } + for { + SearchResults(hits, totalCount, maybeOrgOwnedCount) <- elasticSearch.search( + searchParams.copy( + shouldFlagGraphicImages = shouldFlagGraphicImages, + ) + ) + imageEntities = hits map (hitToImageEntity _).tupled + prevLink = getPrevLink(searchParams) + nextLink = getNextLink(searchParams, totalCount) + links = List(prevLink, nextLink).flatten + } yield respondCollection(imageEntities, Some(searchParams.offset), Some(totalCount), maybeOrgOwnedCount, links) + } + def imageSearch() = auth.async { implicit request => val shouldFlagGraphicImages = request.cookies.get("SHOULD_BLUR_GRAPHIC_IMAGES") .map(_.value).getOrElse(config.defaultShouldBlurGraphicImages.toString) == "true" diff --git a/media-api/conf/routes b/media-api/conf/routes index d868fd4c400..acd0f68f2cd 100644 --- a/media-api/conf/routes +++ b/media-api/conf/routes @@ -13,6 +13,7 @@ GET /images/:id/softDeletedMetadata controllers. GET /images/aggregations/date/:field controllers.AggregationController.dateHistogram(field: String, q: Option[String]) # Images +GET /images/semantic-search controllers.MediaApi.semanticSearch(q: String) GET /images/:id controllers.MediaApi.getImage(id: String) GET /images/:id/_elasticsearch controllers.MediaApi.getImageFromElasticSearch(id: String) GET /images/:id/projection/diff controllers.MediaApi.diffProjection(id: String) From 4e7cfa2f25cbac49ae7bca481b94da02d8cd00ee Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Thu, 30 Oct 2025 15:28:11 +0000 Subject: [PATCH 003/494] return semantic search results --- media-api/app/controllers/MediaApi.scala | 44 +++++++++++++----------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/media-api/app/controllers/MediaApi.scala b/media-api/app/controllers/MediaApi.scala index c468e0205f9..f438003181b 100644 --- a/media-api/app/controllers/MediaApi.scala +++ b/media-api/app/controllers/MediaApi.scala @@ -26,6 +26,8 @@ import play.api.libs.json._ import play.api.libs.ws.WSClient import play.api.mvc.Security.AuthenticatedRequest import play.api.mvc._ +import software.amazon.awssdk.services.s3vectors.model.{QueryOutputVector, QueryVectorsResponse} +import scala.jdk.CollectionConverters._ import java.net.URI import scala.concurrent.{ExecutionContext, Future} @@ -526,28 +528,30 @@ class MediaApi( logger.info(logMarker, s"Semantic search: $q from user: ${Authentication.getIdentity(request.user)}") // We will send a search to the S3 Vector Store - embedder.createEmbeddingAndSearch(q) - -// We will receive 30 results - val top30Results: List[String] = List( - "59c5f086f010d2ae6da0811acf856df5162a4339", - "ba9fa9a2c484134b4b875dd30a411a66f7f7986e", - ) - - val searchParams = SearchParams( - query = Some(q), - ids = Some(top30Results), - tier = request.user.accessor.tier, - ) +// We will receive a maximum of 30 results + val semanticSearchResult: Future[QueryVectorsResponse] = embedder.createEmbeddingAndSearch(q) + + val imageIds = semanticSearchResult.map { result => + logger.info(logMarker, s"Printing the vector results:") + logger.info(logMarker, s"${result.vectors() }") + val results: java.util.List[QueryOutputVector] = result.vectors() + results.asScala.map(_.key()).toList + } - SearchParams.validate(searchParams).fold( - // TODO: respondErrorCollection? - errors => Future.successful(respondError(UnprocessableEntity, InvalidUriParams.errorKey, - errors.map(_.message).mkString(", ")) - ), - params => respondSuccess(params) - ) + imageIds.flatMap { ids => + val searchParams = SearchParams( + query = Some(q), + ids = Some(ids), + tier = request.user.accessor.tier, + ) + SearchParams.validate(searchParams).fold( + errors => Future.successful(respondError(UnprocessableEntity, InvalidUriParams.errorKey, + errors.map(_.message).mkString(", ")) + ), + params => respondSuccess(params) + ) + } } private def respondSuccess(searchParams: SearchParams)(implicit request: Authentication.Request[AnyContent], logMarker: LogMarker) = { From 4ad601f1ad735967e9026cd8d010de9c6707df66 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Tue, 4 Nov 2025 11:24:45 +0000 Subject: [PATCH 004/494] add search for similar endpoint --- .../gu/mediaservice/lib/aws/Embedder.scala | 9 ++++ .../gu/mediaservice/lib/aws/S3Vectors.scala | 30 ++++++++++++- kahuna/app/controllers/KahunaController.scala | 4 +- kahuna/app/lib/FeatureSwitch.scala | 6 +++ media-api/app/controllers/MediaApi.scala | 43 ++++++++----------- media-api/conf/routes | 2 +- 6 files changed, 66 insertions(+), 28 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala index 965b9b2b1f9..a3f35194d74 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala @@ -50,6 +50,15 @@ class Embedder(s3vectors: S3Vectors, bedrock: Bedrock) extends GridLogging { .build() } + def imageToImageSearch(imageId: String)(implicit ec: ExecutionContext, logMarker: LogMarker): QueryVectorsResponse = { +// Find image in vector store +// We are assuming that the image is already in the vector store. +// From image_id --> vectorData + val vector = s3vectors.findVectorForImageId(imageId) +// Run cosine similarity over image + s3vectors.searchVectorStore(vector) + } + def createEmbeddingAndSearch(q: String)(implicit ec: ExecutionContext, logMarker: LogMarker): Future[QueryVectorsResponse] = { logger.info(logMarker, s"Searching for image embedding for $q") diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala index c9f7d4e401f..b42093fd9ed 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala @@ -1,9 +1,10 @@ package com.gu.mediaservice.lib.aws import com.gu.mediaservice.lib.config.CommonConfig import com.gu.mediaservice.lib.logging.LogMarker +import software.amazon.awssdk.core.internal.waiters.ResponseOrException.response import software.amazon.awssdk.regions.Region import software.amazon.awssdk.services.s3vectors._ -import software.amazon.awssdk.services.s3vectors.model.{PutInputVector, PutVectorsRequest, PutVectorsResponse, QueryVectorsRequest, QueryVectorsResponse, VectorData} +import software.amazon.awssdk.services.s3vectors.model.{GetOutputVector, GetVectorsRequest, GetVectorsResponse, PutInputVector, PutVectorsRequest, PutVectorsResponse, QueryVectorsRequest, QueryVectorsResponse, VectorData} import java.net.URI import scala.concurrent.{ExecutionContext, Future} @@ -65,6 +66,33 @@ class S3Vectors(config: CommonConfig) } } + def findVectorForImageId(imageId: String)(implicit logMarker: LogMarker): VectorData = { + val request: GetVectorsRequest = GetVectorsRequest + .builder() + .indexName("cohere-embed-english-v3") + .vectorBucketName(s"image-embeddings-${config.stage.toLowerCase}") + .keys(imageId) + .returnData(true) + .build() + + try { + val response = client.getVectors(request) + logger.info( + logMarker, + s"S3 Vector Store API call to retrieve embedding for imageId ${imageId} completed with status: ${response.sdkHttpResponse().statusCode()}" + ) + logger.info(logMarker, s"${response}") + // See https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3vectors/model/GetVectorsResponse.html#vectors() + // We may want to add more error handling here + response.vectors().asScala.head.data() + } + catch { + case e: Exception => + logger.error(logMarker, s"Exception during vector retrieval for imageId ${imageId}:", e) + throw e + } + } + def searchVectorStore(queryVector: VectorData)(implicit logMarker: LogMarker ): QueryVectorsResponse = { logger.info(logMarker, s"Searching for image embedding") diff --git a/kahuna/app/controllers/KahunaController.scala b/kahuna/app/controllers/KahunaController.scala index 494cdf1cde6..f3462bc5b7f 100644 --- a/kahuna/app/controllers/KahunaController.scala +++ b/kahuna/app/controllers/KahunaController.scala @@ -3,7 +3,7 @@ package controllers import com.gu.mediaservice.lib.argo.ArgoHelpers import com.gu.mediaservice.lib.auth.Authentication.Principal import com.gu.mediaservice.lib.auth.{Authentication, Authorisation, BaseControllerWithLoginRedirects} -import lib.{ExampleSwitch, UseCqlChips, FeatureSwitches, KahunaConfig} +import lib.{ExampleSwitch, FeatureSwitches, KahunaConfig, SemanticSearchEnabled, UseCqlChips} import play.api.mvc.ControllerComponents import play.api.libs.json._ @@ -38,7 +38,7 @@ class KahunaController( val isIFramed = request.headers.get("Sec-Fetch-Dest").contains("iframe") val featureSwitches = new FeatureSwitches( - List(ExampleSwitch, UseCqlChips) + List(ExampleSwitch, UseCqlChips, SemanticSearchEnabled) ) val featureSwitchesWithClientValues = featureSwitches.getClientSwitchValues(featureSwitches.getFeatureSwitchCookies(request.cookies.get)) val featureSwitchesJson = Json.stringify(Json.toJson(featureSwitches.getFeatureSwitchesToStringify(featureSwitchesWithClientValues))) diff --git a/kahuna/app/lib/FeatureSwitch.scala b/kahuna/app/lib/FeatureSwitch.scala index 3177f07bdbd..8e0a645e69d 100644 --- a/kahuna/app/lib/FeatureSwitch.scala +++ b/kahuna/app/lib/FeatureSwitch.scala @@ -16,6 +16,12 @@ object UseCqlChips extends FeatureSwitch( default = false ) +object SemanticSearchEnabled extends FeatureSwitch( + key = "semantic-search-enabled", + title = "Enable semantic search", + default = false +) + class FeatureSwitches(featureSwitches: List[FeatureSwitch]){ // Feature switches are defined here, but updated by setting a cookie following the pattern e.g. "feature-switch-my-key" // for a switch called "my-key". diff --git a/media-api/app/controllers/MediaApi.scala b/media-api/app/controllers/MediaApi.scala index f438003181b..aac8718195c 100644 --- a/media-api/app/controllers/MediaApi.scala +++ b/media-api/app/controllers/MediaApi.scala @@ -515,7 +515,7 @@ class MediaApi( request.post(Json.toJson(Map("data" -> usagesMetadata))) //fire and forget } - def semanticSearch(q: String) = auth.async { implicit request => + def searchForSimilar(imageId: String) = auth.async { implicit request => val shouldFlagGraphicImages = request.cookies.get("SHOULD_BLUR_GRAPHIC_IMAGES") .map(_.value).getOrElse(config.defaultShouldBlurGraphicImages.toString) == "true" @@ -525,33 +525,28 @@ class MediaApi( "requestId" -> RequestLoggingFilter.getRequestId(request) ) ++ RequestLoggingFilter.loggablePrincipal(request.user) - logger.info(logMarker, s"Semantic search: $q from user: ${Authentication.getIdentity(request.user)}") + logger.info(logMarker, s"Image similarity search for imageId: ${imageId} from user: ${Authentication.getIdentity(request.user)}") // We will send a search to the S3 Vector Store // We will receive a maximum of 30 results - val semanticSearchResult: Future[QueryVectorsResponse] = embedder.createEmbeddingAndSearch(q) - - val imageIds = semanticSearchResult.map { result => - logger.info(logMarker, s"Printing the vector results:") - logger.info(logMarker, s"${result.vectors() }") - val results: java.util.List[QueryOutputVector] = result.vectors() - results.asScala.map(_.key()).toList - } - - imageIds.flatMap { ids => - val searchParams = SearchParams( - query = Some(q), - ids = Some(ids), - tier = request.user.accessor.tier, - ) + val semanticSearchResult: QueryVectorsResponse = embedder.imageToImageSearch(imageId) + logger.info(logMarker, s"Printing the vector results:") + logger.info(logMarker, s"${semanticSearchResult }") + val results: java.util.List[QueryOutputVector] = semanticSearchResult.vectors() + val ids = results.asScala.map(_.key()).toList + + val searchParams = SearchParams( + query = Some(""), + ids = Some(ids), + tier = request.user.accessor.tier, + ) - SearchParams.validate(searchParams).fold( - errors => Future.successful(respondError(UnprocessableEntity, InvalidUriParams.errorKey, - errors.map(_.message).mkString(", ")) - ), - params => respondSuccess(params) - ) - } + SearchParams.validate(searchParams).fold( + errors => Future.successful(respondError(UnprocessableEntity, InvalidUriParams.errorKey, + errors.map(_.message).mkString(", ")) + ), + params => respondSuccess(params) + ) } private def respondSuccess(searchParams: SearchParams)(implicit request: Authentication.Request[AnyContent], logMarker: LogMarker) = { diff --git a/media-api/conf/routes b/media-api/conf/routes index acd0f68f2cd..79b0d8f6c4e 100644 --- a/media-api/conf/routes +++ b/media-api/conf/routes @@ -13,11 +13,11 @@ GET /images/:id/softDeletedMetadata controllers. GET /images/aggregations/date/:field controllers.AggregationController.dateHistogram(field: String, q: Option[String]) # Images -GET /images/semantic-search controllers.MediaApi.semanticSearch(q: String) GET /images/:id controllers.MediaApi.getImage(id: String) GET /images/:id/_elasticsearch controllers.MediaApi.getImageFromElasticSearch(id: String) GET /images/:id/projection/diff controllers.MediaApi.diffProjection(id: String) GET /images/:id/fileMetadata controllers.MediaApi.getImageFileMetadata(id: String) +GET /images/:imageId/similar controllers.MediaApi.searchForSimilar(imageId: String) GET /images/:imageId/uploadedBy controllers.MediaApi.uploadedBy(imageId: String) GET /images/:imageId/export/:exportId controllers.MediaApi.getImageExport(imageId: String, exportId: String) GET /images/:imageId/export/:exportId/asset/:width/download controllers.MediaApi.downloadImageExport(imageId: String, exportId: String, width: Int) From 5f9e7126a268cc70df53f77bd2f1800c176a322c Mon Sep 17 00:00:00 2001 From: Andrew Nowak Date: Tue, 4 Nov 2025 11:25:27 +0000 Subject: [PATCH 005/494] more-like-this/similar search frontend button --- .../gr-more-like-this/gr-more-like-this.css | 41 +++++++++++++++++++ .../gr-more-like-this/gr-more-like-this.html | 11 +++++ .../gr-more-like-this/gr-more-like-this.js | 34 +++++++++++++++ kahuna/public/js/image/view.html | 4 ++ kahuna/public/js/search/results.js | 2 + 5 files changed, 92 insertions(+) create mode 100644 kahuna/public/js/components/gr-more-like-this/gr-more-like-this.css create mode 100644 kahuna/public/js/components/gr-more-like-this/gr-more-like-this.html create mode 100644 kahuna/public/js/components/gr-more-like-this/gr-more-like-this.js diff --git a/kahuna/public/js/components/gr-more-like-this/gr-more-like-this.css b/kahuna/public/js/components/gr-more-like-this/gr-more-like-this.css new file mode 100644 index 00000000000..18e7acd1287 --- /dev/null +++ b/kahuna/public/js/components/gr-more-like-this/gr-more-like-this.css @@ -0,0 +1,41 @@ +gr-more-like-thiser .more-like-this { + display: inline-flex; + height: 100%; +} + +button .more-like-this:hover { + color: white; +} + +.top-bar-item .more-like-this a:hover { + background-color: #666666; + color: white; + cursor: pointer; +} + +.top-bar-item .more-like-this a { + display: inline-flex; +} + +.top-bar-item .more-like-this .clickable { + padding-right: 12px; + padding-left: 5px; +} + +.results-toolbar .more-like-this .clickable { + margin-left: 0px; +} + +.results-toolbar .more-like-this a, .results-toolbar .more-like-this span { + display: inline-flex; +} + +.more-like-this-warning { + color: yellow; + padding-left: 5px; + margin-left: -6px; +} + +.more-like-this-button { + height: 36px; +} diff --git a/kahuna/public/js/components/gr-more-like-this/gr-more-like-this.html b/kahuna/public/js/components/gr-more-like-this/gr-more-like-this.html new file mode 100644 index 00000000000..7d13d462a6b --- /dev/null +++ b/kahuna/public/js/components/gr-more-like-this/gr-more-like-this.html @@ -0,0 +1,11 @@ + + + + More like this + + + diff --git a/kahuna/public/js/components/gr-more-like-this/gr-more-like-this.js b/kahuna/public/js/components/gr-more-like-this/gr-more-like-this.js new file mode 100644 index 00000000000..34b26a80ce1 --- /dev/null +++ b/kahuna/public/js/components/gr-more-like-this/gr-more-like-this.js @@ -0,0 +1,34 @@ +import angular from 'angular'; +import './gr-more-like-this.css'; +import template from './gr-more-like-this.html'; + +export const moreLikeThis = angular.module('gr.moreLikeThis', []); + +moreLikeThis.controller('MoreLikeThisCtrl', [ + '$scope', + + function Controller($scope) { + + let ctrl = this; + + ctrl.$onInit = () => { + ctrl.getMoreLikeThisQuery = function() { + return `similar:${ctrl.image.data.id}`; + } + }; + }]); + +moreLikeThis.directive('grMoreLikeThis', function () { + return { + restrict: 'E', + controller: 'MoreLikeThisCtrl', + controllerAs: 'ctrl', + bindToController: true, + scope: { + image: '=', + crop: '=' + }, + template: template + }; +}); + diff --git a/kahuna/public/js/image/view.html b/kahuna/public/js/image/view.html index 3c33273db21..d2931deac16 100644 --- a/kahuna/public/js/image/view.html +++ b/kahuna/public/js/image/view.html @@ -13,6 +13,10 @@ Share with URL + + + diff --git a/kahuna/public/js/search/results.js b/kahuna/public/js/search/results.js index a09d18bfd6a..001df2ed2dd 100644 --- a/kahuna/public/js/search/results.js +++ b/kahuna/public/js/search/results.js @@ -15,6 +15,7 @@ import '../components/gr-archiver/gr-archiver'; import '../components/gr-delete-image/gr-delete-image'; import '../components/gr-undelete-image/gr-un-delete-image'; import '../components/gr-downloader/gr-downloader'; +import '../components/gr-more-like-this/gr-more-like-this'; import '../components/gr-batch-export-original-images/gr-batch-export-original-images'; import '../components/gr-panel-button/gr-panel-button'; import '../components/gr-toggle-button/gr-toggle-button'; @@ -50,6 +51,7 @@ export var results = angular.module('kahuna.search.results', [ 'gu.lazyTableShortcuts', 'gr.archiver', 'gr.downloader', + 'gr.moreLikeThis', 'gr.batchExportOriginalImages', 'gr.deleteImage', 'gr.undeleteImage', From 13e564c33e69a1815b0fb84c50bf9bc715dad10c Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Tue, 4 Nov 2025 12:36:35 +0000 Subject: [PATCH 006/494] integrate search for similar into image search function --- media-api/app/controllers/MediaApi.scala | 93 ++++++------------------ media-api/conf/routes | 1 - 2 files changed, 22 insertions(+), 72 deletions(-) diff --git a/media-api/app/controllers/MediaApi.scala b/media-api/app/controllers/MediaApi.scala index aac8718195c..2096f42d8ff 100644 --- a/media-api/app/controllers/MediaApi.scala +++ b/media-api/app/controllers/MediaApi.scala @@ -515,76 +515,6 @@ class MediaApi( request.post(Json.toJson(Map("data" -> usagesMetadata))) //fire and forget } - def searchForSimilar(imageId: String) = auth.async { implicit request => - val shouldFlagGraphicImages = request.cookies.get("SHOULD_BLUR_GRAPHIC_IMAGES") - .map(_.value).getOrElse(config.defaultShouldBlurGraphicImages.toString) == "true" - - implicit val logMarker: LogMarker = MarkerMap( - "requestType" -> "semantic-image-search", - "shouldFlagGraphicImages" -> shouldFlagGraphicImages, - "requestId" -> RequestLoggingFilter.getRequestId(request) - ) ++ RequestLoggingFilter.loggablePrincipal(request.user) - - logger.info(logMarker, s"Image similarity search for imageId: ${imageId} from user: ${Authentication.getIdentity(request.user)}") - -// We will send a search to the S3 Vector Store -// We will receive a maximum of 30 results - val semanticSearchResult: QueryVectorsResponse = embedder.imageToImageSearch(imageId) - logger.info(logMarker, s"Printing the vector results:") - logger.info(logMarker, s"${semanticSearchResult }") - val results: java.util.List[QueryOutputVector] = semanticSearchResult.vectors() - val ids = results.asScala.map(_.key()).toList - - val searchParams = SearchParams( - query = Some(""), - ids = Some(ids), - tier = request.user.accessor.tier, - ) - - SearchParams.validate(searchParams).fold( - errors => Future.successful(respondError(UnprocessableEntity, InvalidUriParams.errorKey, - errors.map(_.message).mkString(", ")) - ), - params => respondSuccess(params) - ) - } - - private def respondSuccess(searchParams: SearchParams)(implicit request: Authentication.Request[AnyContent], logMarker: LogMarker) = { - val shouldFlagGraphicImages = request.cookies.get("SHOULD_BLUR_GRAPHIC_IMAGES") - .map(_.value).getOrElse(config.defaultShouldBlurGraphicImages.toString) == "true" - - implicit val logMarker: LogMarker = MarkerMap( - "requestType" -> "image-search", - "shouldFlagGraphicImages" -> shouldFlagGraphicImages, - "requestId" -> RequestLoggingFilter.getRequestId(request) - ) ++ RequestLoggingFilter.loggablePrincipal(request.user) - - val include = getIncludedFromParams(request) - - def hitToImageEntity(elasticId: String, image: SourceWrapper[Image]): EmbeddedEntity[JsValue] = { - val writePermission = authorisation.isUploaderOrHasPermission(request.user, image.instance.uploadedBy, EditMetadata) - val deletePermission = authorisation.isUploaderOrHasPermission(request.user, image.instance.uploadedBy, DeleteImagePermission) - val deleteCropsOrUsagePermission = canUserDeleteCropsOrUsages(request.user) - - val (imageData, imageLinks, imageActions) = - imageResponse.create(elasticId, image, writePermission, deletePermission, deleteCropsOrUsagePermission, include, request.user.accessor.tier) - val id = (imageData \ "id").as[String] - val imageUri = URI.create(s"${config.rootUri}/images/$id") - EmbeddedEntity(uri = imageUri, data = Some(imageData), imageLinks, imageActions) - } - for { - SearchResults(hits, totalCount, maybeOrgOwnedCount) <- elasticSearch.search( - searchParams.copy( - shouldFlagGraphicImages = shouldFlagGraphicImages, - ) - ) - imageEntities = hits map (hitToImageEntity _).tupled - prevLink = getPrevLink(searchParams) - nextLink = getNextLink(searchParams, totalCount) - links = List(prevLink, nextLink).flatten - } yield respondCollection(imageEntities, Some(searchParams.offset), Some(totalCount), maybeOrgOwnedCount, links) - } - def imageSearch() = auth.async { implicit request => val shouldFlagGraphicImages = request.cookies.get("SHOULD_BLUR_GRAPHIC_IMAGES") .map(_.value).getOrElse(config.defaultShouldBlurGraphicImages.toString) == "true" @@ -624,7 +554,28 @@ class MediaApi( val _searchParams = SearchParams(request) val hasDeletePermission = authorisation.isUploaderOrHasPermission(request.user, "", DeleteImagePermission) val canViewDeletedImages = _searchParams.query.contains("is:deleted") && !hasDeletePermission - val searchParams = if(canViewDeletedImages) _searchParams.copy(uploadedBy = Some(Authentication.getIdentity(request.user))) else _searchParams + + val searchForSimilar = _searchParams.query.flatMap(_.split(" ").find(_.startsWith("similar:"))) + val searchParams = if (searchForSimilar.isDefined) { + val extractedImageId = searchForSimilar.get.split(":")(1) + + val semanticSearchResult: QueryVectorsResponse = embedder.imageToImageSearch(extractedImageId) + val results: java.util.List[QueryOutputVector] = semanticSearchResult.vectors() + val ids = results.asScala.map(_.key()).toList + + SearchParams( + query = Some(""), + ids = Some(ids), + offset = _searchParams.offset, + length = _searchParams.length, + tier = request.user.accessor.tier + ) + } else if(canViewDeletedImages) { + _searchParams.copy(uploadedBy = Some(Authentication.getIdentity(request.user))) + } + else { + _searchParams + } SearchParams.validate(searchParams).fold( // TODO: respondErrorCollection? diff --git a/media-api/conf/routes b/media-api/conf/routes index 79b0d8f6c4e..d868fd4c400 100644 --- a/media-api/conf/routes +++ b/media-api/conf/routes @@ -17,7 +17,6 @@ GET /images/:id controllers. GET /images/:id/_elasticsearch controllers.MediaApi.getImageFromElasticSearch(id: String) GET /images/:id/projection/diff controllers.MediaApi.diffProjection(id: String) GET /images/:id/fileMetadata controllers.MediaApi.getImageFileMetadata(id: String) -GET /images/:imageId/similar controllers.MediaApi.searchForSimilar(imageId: String) GET /images/:imageId/uploadedBy controllers.MediaApi.uploadedBy(imageId: String) GET /images/:imageId/export/:exportId controllers.MediaApi.getImageExport(imageId: String, exportId: String) GET /images/:imageId/export/:exportId/asset/:width/download controllers.MediaApi.downloadImageExport(imageId: String, exportId: String, width: Int) From cd53e1579e5c2fb09ac4d8d0b7fdf6f1d1736ca0 Mon Sep 17 00:00:00 2001 From: Andrew Nowak Date: Tue, 4 Nov 2025 16:38:44 +0000 Subject: [PATCH 007/494] Order similar search results, using ES pinned query --- .../lib/elasticsearch/filters.scala | 2 + media-api/app/controllers/MediaApi.scala | 44 +++++++++++++------ .../app/lib/elasticsearch/ElasticSearch.scala | 42 ++++++++++++------ 3 files changed, 61 insertions(+), 27 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/elasticsearch/filters.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/elasticsearch/filters.scala index 47f30078c41..98ed3a4d4ba 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/elasticsearch/filters.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/elasticsearch/filters.scala @@ -56,6 +56,8 @@ object filters { def ids(idList: List[String]): Query = idsQuery(idList) + def pinnedIds(idList: List[String]): Query = pinnedQuery(ids = idList, organic = matchNoneQuery()) + def bool() = BoolQuery() def mustNot(queries: Query*): Query = ElasticDsl.not(queries) diff --git a/media-api/app/controllers/MediaApi.scala b/media-api/app/controllers/MediaApi.scala index 2096f42d8ff..6fc30a39e3e 100644 --- a/media-api/app/controllers/MediaApi.scala +++ b/media-api/app/controllers/MediaApi.scala @@ -539,7 +539,7 @@ class MediaApi( EmbeddedEntity(uri = imageUri, data = Some(imageData), imageLinks, imageActions) } - def respondSuccess(searchParams: SearchParams) = for { + def performSearchAndRespond(searchParams: SearchParams) = for { SearchResults(hits, totalCount, maybeOrgOwnedCount) <- elasticSearch.search( searchParams.copy( shouldFlagGraphicImages = shouldFlagGraphicImages, @@ -556,7 +556,8 @@ class MediaApi( val canViewDeletedImages = _searchParams.query.contains("is:deleted") && !hasDeletePermission val searchForSimilar = _searchParams.query.flatMap(_.split(" ").find(_.startsWith("similar:"))) - val searchParams = if (searchForSimilar.isDefined) { + + if (searchForSimilar.isDefined) { val extractedImageId = searchForSimilar.get.split(":")(1) val semanticSearchResult: QueryVectorsResponse = embedder.imageToImageSearch(extractedImageId) @@ -570,20 +571,35 @@ class MediaApi( length = _searchParams.length, tier = request.user.accessor.tier ) - } else if(canViewDeletedImages) { - _searchParams.copy(uploadedBy = Some(Authentication.getIdentity(request.user))) - } - else { - _searchParams + + for { + SearchResults(hits, totalCount, _) <- elasticSearch.lookupIds(ids, offset = _searchParams.offset, length = _searchParams.length) + imageEntities = hits map (hitToImageEntity _).tupled + links = List() + } yield { + respondCollection(imageEntities, Some(_searchParams.offset), Some(totalCount), None, links) + } + + + } else { + + val searchParams = if(canViewDeletedImages) { + _searchParams.copy(uploadedBy = Some(Authentication.getIdentity(request.user))) + } + else { + _searchParams + } + + SearchParams.validate(searchParams).fold( + // TODO: respondErrorCollection? + errors => Future.successful(respondError(UnprocessableEntity, InvalidUriParams.errorKey, + errors.map(_.message).mkString(", ")) + ), + params => performSearchAndRespond(params) + ) } - SearchParams.validate(searchParams).fold( - // TODO: respondErrorCollection? - errors => Future.successful(respondError(UnprocessableEntity, InvalidUriParams.errorKey, - errors.map(_.message).mkString(", ")) - ), - params => respondSuccess(params) - ) + } private def getImageResponseFromES( diff --git a/media-api/app/lib/elasticsearch/ElasticSearch.scala b/media-api/app/lib/elasticsearch/ElasticSearch.scala index 0ea248661ba..a8c13fee1eb 100644 --- a/media-api/app/lib/elasticsearch/ElasticSearch.scala +++ b/media-api/app/lib/elasticsearch/ElasticSearch.scala @@ -118,22 +118,38 @@ class ElasticSearch( ) } - def search(params: SearchParams)(implicit ex: ExecutionContext, request: AuthenticatedRequest[AnyContent, Principal], logMarker: LogMarker = MarkerMap()): Future[SearchResults] = { + private val isPotentiallyGraphicFieldName = "isPotentiallyGraphic" + + + private def resolveHit(hit: SearchHit) = mapImageFrom( + hit.sourceAsString, + hit.id, + hit.index, + fields = hit.fields match { + case null => JsObject.empty + case _ => Json.obj( + isPotentiallyGraphicFieldName -> hit.fields.get(isPotentiallyGraphicFieldName).map(_.asInstanceOf[List[Boolean]].headOption) + ) + } + ) - val isPotentiallyGraphicFieldName = "isPotentiallyGraphic" - - def resolveHit(hit: SearchHit) = mapImageFrom( - hit.sourceAsString, - hit.id, - hit.index, - fields = hit.fields match { - case null => JsObject.empty - case _ => Json.obj( - isPotentiallyGraphicFieldName -> hit.fields.get(isPotentiallyGraphicFieldName).map(_.asInstanceOf[List[Boolean]].headOption) - ) + def lookupIds(ids: List[String], offset: Int, length: Int)(implicit ex: ExecutionContext, logMarker: LogMarker): Future[SearchResults] = { + val query = filters.pinnedIds(ids) + + val searchRequest = prepareSearch(query) + .trackTotalHits(true) + .storedFields("_source") + .from(offset) + .size(length) + + executeAndLog(searchRequest, "ids lookup") + .map { r => + val imageHits = r.result.hits.hits.map(resolveHit).toSeq.flatten.map(i => (i.instance.id, i)) + SearchResults(hits = imageHits, total = r.result.totalHits, maybeOrgOwnedCount = None) } - ) + } + def search(params: SearchParams)(implicit ex: ExecutionContext, request: AuthenticatedRequest[AnyContent, Principal], logMarker: LogMarker = MarkerMap()): Future[SearchResults] = { val query: Query = queryBuilder.makeQuery(params.structuredQuery) val uploadTimeFilter = filters.date("uploadTime", params.since, params.until) From 36deb93d40a765d5a88702bb2c1caa58270928ec Mon Sep 17 00:00:00 2001 From: Andrew Nowak Date: Tue, 4 Nov 2025 17:28:40 +0000 Subject: [PATCH 008/494] force sort order to new option "relevance" --- .../gr-sort-control/gr-sort-control-config.ts | 35 +++++++------------ .../gr-sort-control/gr-sort-control.tsx | 11 ++++-- kahuna/public/js/search/query.js | 2 +- kahuna/public/js/search/results.js | 3 ++ kahuna/public/js/services/api/media-api.js | 4 +-- 5 files changed, 26 insertions(+), 29 deletions(-) diff --git a/kahuna/public/js/components/gr-sort-control/gr-sort-control-config.ts b/kahuna/public/js/components/gr-sort-control/gr-sort-control-config.ts index 4c85c46be62..450266d01b4 100644 --- a/kahuna/public/js/components/gr-sort-control/gr-sort-control-config.ts +++ b/kahuna/public/js/components/gr-sort-control/gr-sort-control-config.ts @@ -1,28 +1,9 @@ import {SortDropdownOption} from "./gr-sort-control"; -export function manageSortSelection(newSelection:string): string { - let newVal; - switch (newSelection) { - case "newest": - newVal = "newest"; - break; - case "oldest": - newVal = "oldest"; - break; - case "-taken": - newVal = "-taken"; - break; - case "taken": - newVal = "taken"; - break; - case "dateAddedToCollection": - newVal = "dateAddedToCollection"; - break; - default: - newVal = "newest"; - break; - } - return newVal; +export function manageSortSelection(newSelection: string): string { + if (["newest", "oldest", "-taken", "taken", "dateAddedToCollection", "relevance"].includes(newSelection)) + return newSelection; + else return "newest" } export const SortOptions: SortDropdownOption[] = [ @@ -58,6 +39,14 @@ export const SortOptions: SortDropdownOption[] = [ } ]; +export const RelevanceSortOption = + { + value: "relevance", + label: "Relevance", + isCollection: false, + isTaken: false, + }; + export const DefaultSortOption: SortDropdownOption = SortOptions[0]; export const CollectionSortOption: SortDropdownOption = SortOptions[4]; export const HAS_DATE_TAKEN = "has:dateTaken"; diff --git a/kahuna/public/js/components/gr-sort-control/gr-sort-control.tsx b/kahuna/public/js/components/gr-sort-control/gr-sort-control.tsx index 962565bae0a..baa9f27e26e 100644 --- a/kahuna/public/js/components/gr-sort-control/gr-sort-control.tsx +++ b/kahuna/public/js/components/gr-sort-control/gr-sort-control.tsx @@ -3,7 +3,7 @@ import * as angular from "angular"; import { react2angular } from "react2angular"; import { useEffect, useState } from "react"; import { BaseSortControl, SortDropdownOption } from "./base-sort-control"; -import { SortOptions, DefaultSortOption } from "./gr-sort-control-config"; +import {SortOptions, DefaultSortOption, RelevanceSortOption} from "./gr-sort-control-config"; export type { SortDropdownOption }; export interface SortProps { @@ -20,13 +20,18 @@ const checkForCollection = (query:string): boolean => /~"[a-zA-Z0-9 #-_.://]+"/. const SortControl: React.FC = ({ props }) => { - const sortOptions = SortOptions; + let sortOptions = SortOptions; const orderBy = props.orderBy; const query = props.query; const startHasCollection = checkForCollection(query); + const isSimilarity = (query ?? '').includes("similar:") let startSortOption = DefaultSortOption; - if (startHasCollection) { + if (isSimilarity) { + startSortOption = RelevanceSortOption; + sortOptions = [RelevanceSortOption]; + props.onSortSelect(RelevanceSortOption); + } else if (startHasCollection) { if ((sortOptions.filter(o => o.isCollection)).length > 0) { startSortOption = sortOptions.find(o => o.isCollection); } diff --git a/kahuna/public/js/search/query.js b/kahuna/public/js/search/query.js index 244677a1d1a..9641e210ea4 100644 --- a/kahuna/public/js/search/query.js +++ b/kahuna/public/js/search/query.js @@ -312,7 +312,7 @@ query.controller('SearchQueryCtrl', [ ctrl.sortProps = { onSortSelect: updateSortChips, - query: ctrl.filter.query, + query: $stateParams.query, orderBy: ctrl.ordering ? ctrl.ordering.orderBy : "" }; //-end sort control- diff --git a/kahuna/public/js/search/results.js b/kahuna/public/js/search/results.js index 001df2ed2dd..d8ac43dfcab 100644 --- a/kahuna/public/js/search/results.js +++ b/kahuna/public/js/search/results.js @@ -382,6 +382,9 @@ results.controller('SearchResultsCtrl', [ // FIXME: this will only add up to 50 images (search capped) function checkForNewImages() { $timeout(() => { + if ($stateParams.orderBy === 'relevance') { + return; + } // Use explicit `until`, or blank it to find new images const until = $stateParams.until || null; const latestTime = lastSearchFirstResultTime; diff --git a/kahuna/public/js/services/api/media-api.js b/kahuna/public/js/services/api/media-api.js index 99b71ae0dd6..9683c100f70 100644 --- a/kahuna/public/js/services/api/media-api.js +++ b/kahuna/public/js/services/api/media-api.js @@ -80,8 +80,8 @@ mediaApi.factory('mediaApi', } function getOrder(orderBy) { - if (orderBy === 'dateAddedToCollection') { - return 'dateAddedToCollection'; + if (orderBy === 'dateAddedToCollection' || orderBy === 'relevance') { + return orderBy; } else if (orderBy && orderBy.includes('taken')) { return orderBy; From e1e2f8a9de84db8d438b82c19fa86d2a871bccc4 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Wed, 5 Nov 2025 10:57:06 +0000 Subject: [PATCH 009/494] add error handling when image is not embedded yet --- .../gu/mediaservice/lib/aws/Embedder.scala | 18 ++++--- .../gu/mediaservice/lib/aws/S3Vectors.scala | 4 +- media-api/app/controllers/MediaApi.scala | 49 ++++++++++--------- 3 files changed, 38 insertions(+), 33 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala index a3f35194d74..1b19143f51c 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala @@ -6,7 +6,7 @@ import software.amazon.awssdk.services.s3vectors.model.{PutVectorsResponse, Quer import java.nio.file.{Files, Path} import java.util.Base64 import scala.concurrent.{ExecutionContext, Future} -import scala.jdk.CollectionConverters.SeqHasAsJava +import scala.jdk.CollectionConverters.{CollectionHasAsScala, SeqHasAsJava} sealed trait CohereCompatibleMimeType case object CohereJpeg extends CohereCompatibleMimeType @@ -50,13 +50,15 @@ class Embedder(s3vectors: S3Vectors, bedrock: Bedrock) extends GridLogging { .build() } - def imageToImageSearch(imageId: String)(implicit ec: ExecutionContext, logMarker: LogMarker): QueryVectorsResponse = { -// Find image in vector store -// We are assuming that the image is already in the vector store. -// From image_id --> vectorData - val vector = s3vectors.findVectorForImageId(imageId) -// Run cosine similarity over image - s3vectors.searchVectorStore(vector) + def imageToImageSearch(imageId: String)(implicit ec: ExecutionContext, logMarker: LogMarker): Option[QueryVectorsResponse] = { + val maybeVector = s3vectors.findVectorForImageId(imageId) + if (maybeVector.vectors().isEmpty) { + logger.error(logMarker, s"No embedding found for ${imageId}") + None + } else { + val vector: VectorData = maybeVector.vectors().asScala.head.data() + Some(s3vectors.searchVectorStore(vector)) + } } def createEmbeddingAndSearch(q: String)(implicit ec: ExecutionContext, logMarker: LogMarker): Future[QueryVectorsResponse] = { diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala index b42093fd9ed..6e092779526 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala @@ -66,7 +66,7 @@ class S3Vectors(config: CommonConfig) } } - def findVectorForImageId(imageId: String)(implicit logMarker: LogMarker): VectorData = { + def findVectorForImageId(imageId: String)(implicit logMarker: LogMarker): GetVectorsResponse = { val request: GetVectorsRequest = GetVectorsRequest .builder() .indexName("cohere-embed-english-v3") @@ -84,7 +84,7 @@ class S3Vectors(config: CommonConfig) logger.info(logMarker, s"${response}") // See https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3vectors/model/GetVectorsResponse.html#vectors() // We may want to add more error handling here - response.vectors().asScala.head.data() + response } catch { case e: Exception => diff --git a/media-api/app/controllers/MediaApi.scala b/media-api/app/controllers/MediaApi.scala index 6fc30a39e3e..3298c5b1737 100644 --- a/media-api/app/controllers/MediaApi.scala +++ b/media-api/app/controllers/MediaApi.scala @@ -26,11 +26,11 @@ import play.api.libs.json._ import play.api.libs.ws.WSClient import play.api.mvc.Security.AuthenticatedRequest import play.api.mvc._ -import software.amazon.awssdk.services.s3vectors.model.{QueryOutputVector, QueryVectorsResponse} -import scala.jdk.CollectionConverters._ +import software.amazon.awssdk.services.s3vectors.model.QueryVectorsResponse import java.net.URI import scala.concurrent.{ExecutionContext, Future} +import scala.jdk.CollectionConverters.IterableHasAsScala import scala.util.Try class MediaApi( @@ -560,27 +560,32 @@ class MediaApi( if (searchForSimilar.isDefined) { val extractedImageId = searchForSimilar.get.split(":")(1) - val semanticSearchResult: QueryVectorsResponse = embedder.imageToImageSearch(extractedImageId) - val results: java.util.List[QueryOutputVector] = semanticSearchResult.vectors() - val ids = results.asScala.map(_.key()).toList - - SearchParams( - query = Some(""), - ids = Some(ids), - offset = _searchParams.offset, - length = _searchParams.length, - tier = request.user.accessor.tier - ) + val semanticSearchResult: Option[QueryVectorsResponse] = embedder.imageToImageSearch(extractedImageId) + + semanticSearchResult match { + case None => + // What behaviour do we want in this case? + logger.info(logMarker, "No result found") + Future.successful(respondError(NotFound, "Not Found", + "The image you have selected is not yet in the S3 Vector Store. We cannot do a similarity search on it yet.")) + case Some(results) => + val ids = results.vectors().asScala.map(_.key()).toList + SearchParams( + query = Some(""), + ids = Some(ids), + offset = _searchParams.offset, + length = _searchParams.length, + tier = request.user.accessor.tier + ) - for { - SearchResults(hits, totalCount, _) <- elasticSearch.lookupIds(ids, offset = _searchParams.offset, length = _searchParams.length) - imageEntities = hits map (hitToImageEntity _).tupled - links = List() - } yield { - respondCollection(imageEntities, Some(_searchParams.offset), Some(totalCount), None, links) + for { + SearchResults(hits, totalCount, _) <- elasticSearch.lookupIds(ids, offset = _searchParams.offset, length = _searchParams.length) + imageEntities = hits map (hitToImageEntity _).tupled + links = List() + } yield { + respondCollection(imageEntities, Some(_searchParams.offset), Some(totalCount), None, links) + } } - - } else { val searchParams = if(canViewDeletedImages) { @@ -598,8 +603,6 @@ class MediaApi( params => performSearchAndRespond(params) ) } - - } private def getImageResponseFromES( From 07e715b27c9cc75911850d5c9e6568281001a54d Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Wed, 5 Nov 2025 11:14:05 +0000 Subject: [PATCH 010/494] fix linting errors from frontend --- .../js/components/gr-more-like-this/gr-more-like-this.js | 4 ++-- .../js/components/gr-sort-control/gr-sort-control-config.ts | 6 +++--- .../js/components/gr-sort-control/gr-sort-control.tsx | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/kahuna/public/js/components/gr-more-like-this/gr-more-like-this.js b/kahuna/public/js/components/gr-more-like-this/gr-more-like-this.js index 34b26a80ce1..90deffc4301 100644 --- a/kahuna/public/js/components/gr-more-like-this/gr-more-like-this.js +++ b/kahuna/public/js/components/gr-more-like-this/gr-more-like-this.js @@ -7,14 +7,14 @@ export const moreLikeThis = angular.module('gr.moreLikeThis', []); moreLikeThis.controller('MoreLikeThisCtrl', [ '$scope', - function Controller($scope) { + function Controller() { let ctrl = this; ctrl.$onInit = () => { ctrl.getMoreLikeThisQuery = function() { return `similar:${ctrl.image.data.id}`; - } + }; }; }]); diff --git a/kahuna/public/js/components/gr-sort-control/gr-sort-control-config.ts b/kahuna/public/js/components/gr-sort-control/gr-sort-control-config.ts index 450266d01b4..74d1b3d8976 100644 --- a/kahuna/public/js/components/gr-sort-control/gr-sort-control-config.ts +++ b/kahuna/public/js/components/gr-sort-control/gr-sort-control-config.ts @@ -1,9 +1,9 @@ import {SortDropdownOption} from "./gr-sort-control"; export function manageSortSelection(newSelection: string): string { - if (["newest", "oldest", "-taken", "taken", "dateAddedToCollection", "relevance"].includes(newSelection)) + if (["newest", "oldest", "-taken", "taken", "dateAddedToCollection", "relevance"].includes(newSelection)) { return newSelection; - else return "newest" + } else { return "newest"; } } export const SortOptions: SortDropdownOption[] = [ @@ -44,7 +44,7 @@ export const RelevanceSortOption = value: "relevance", label: "Relevance", isCollection: false, - isTaken: false, + isTaken: false }; export const DefaultSortOption: SortDropdownOption = SortOptions[0]; diff --git a/kahuna/public/js/components/gr-sort-control/gr-sort-control.tsx b/kahuna/public/js/components/gr-sort-control/gr-sort-control.tsx index baa9f27e26e..e7088493fda 100644 --- a/kahuna/public/js/components/gr-sort-control/gr-sort-control.tsx +++ b/kahuna/public/js/components/gr-sort-control/gr-sort-control.tsx @@ -24,7 +24,7 @@ const SortControl: React.FC = ({ props }) => { const orderBy = props.orderBy; const query = props.query; const startHasCollection = checkForCollection(query); - const isSimilarity = (query ?? '').includes("similar:") + const isSimilarity = (query ?? '').includes("similar:"); let startSortOption = DefaultSortOption; if (isSimilarity) { From 853c918a9e7405680f05552d94386abd28dd4ff5 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Wed, 3 Dec 2025 11:51:56 +0000 Subject: [PATCH 011/494] add new embedder lambda dummy --- image-embedder-lambda/.gitignore | 1 + image-embedder-lambda/README.md | 3 + image-embedder-lambda/package-lock.json | 508 ++++++++++++++++++++++++ image-embedder-lambda/package.json | 16 + image-embedder-lambda/src/handler.ts | 15 + image-embedder-lambda/tsconfig.json | 70 ++++ package-lock.json | 6 + 7 files changed, 619 insertions(+) create mode 100644 image-embedder-lambda/.gitignore create mode 100644 image-embedder-lambda/README.md create mode 100644 image-embedder-lambda/package-lock.json create mode 100644 image-embedder-lambda/package.json create mode 100644 image-embedder-lambda/src/handler.ts create mode 100644 image-embedder-lambda/tsconfig.json create mode 100644 package-lock.json diff --git a/image-embedder-lambda/.gitignore b/image-embedder-lambda/.gitignore new file mode 100644 index 00000000000..4c59576d843 --- /dev/null +++ b/image-embedder-lambda/.gitignore @@ -0,0 +1 @@ +out.js \ No newline at end of file diff --git a/image-embedder-lambda/README.md b/image-embedder-lambda/README.md new file mode 100644 index 00000000000..0eed015b262 --- /dev/null +++ b/image-embedder-lambda/README.md @@ -0,0 +1,3 @@ +# Embedder Lambda + +This is a service responsible for embedding uploaded images to the Grid and writing those embeddings to the S3 Vector Store. \ No newline at end of file diff --git a/image-embedder-lambda/package-lock.json b/image-embedder-lambda/package-lock.json new file mode 100644 index 00000000000..bed2e2beadf --- /dev/null +++ b/image-embedder-lambda/package-lock.json @@ -0,0 +1,508 @@ +{ + "name": "image-embedder-lambda", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "image-embedder-lambda", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "@types/aws-lambda": "^8.10.159", + "esbuild": "0.27.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.0.tgz", + "integrity": "sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.0.tgz", + "integrity": "sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.0.tgz", + "integrity": "sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.0.tgz", + "integrity": "sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.0.tgz", + "integrity": "sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.0.tgz", + "integrity": "sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.0.tgz", + "integrity": "sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.0.tgz", + "integrity": "sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.0.tgz", + "integrity": "sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.0.tgz", + "integrity": "sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.0.tgz", + "integrity": "sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.0.tgz", + "integrity": "sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.0.tgz", + "integrity": "sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.0.tgz", + "integrity": "sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.0.tgz", + "integrity": "sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.0.tgz", + "integrity": "sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.0.tgz", + "integrity": "sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.0.tgz", + "integrity": "sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.0.tgz", + "integrity": "sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.0.tgz", + "integrity": "sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.0.tgz", + "integrity": "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.0.tgz", + "integrity": "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.0.tgz", + "integrity": "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.0.tgz", + "integrity": "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.0.tgz", + "integrity": "sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.0.tgz", + "integrity": "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@types/aws-lambda": { + "version": "8.10.159", + "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.159.tgz", + "integrity": "sha512-SAP22WSGNN12OQ8PlCzGzRCZ7QDCwI85dQZbmpz7+mAk+L7j+wI7qnvmdKh+o7A5LaOp6QnOZ2NJphAZQTTHQg==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.0.tgz", + "integrity": "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.0", + "@esbuild/android-arm": "0.27.0", + "@esbuild/android-arm64": "0.27.0", + "@esbuild/android-x64": "0.27.0", + "@esbuild/darwin-arm64": "0.27.0", + "@esbuild/darwin-x64": "0.27.0", + "@esbuild/freebsd-arm64": "0.27.0", + "@esbuild/freebsd-x64": "0.27.0", + "@esbuild/linux-arm": "0.27.0", + "@esbuild/linux-arm64": "0.27.0", + "@esbuild/linux-ia32": "0.27.0", + "@esbuild/linux-loong64": "0.27.0", + "@esbuild/linux-mips64el": "0.27.0", + "@esbuild/linux-ppc64": "0.27.0", + "@esbuild/linux-riscv64": "0.27.0", + "@esbuild/linux-s390x": "0.27.0", + "@esbuild/linux-x64": "0.27.0", + "@esbuild/netbsd-arm64": "0.27.0", + "@esbuild/netbsd-x64": "0.27.0", + "@esbuild/openbsd-arm64": "0.27.0", + "@esbuild/openbsd-x64": "0.27.0", + "@esbuild/openharmony-arm64": "0.27.0", + "@esbuild/sunos-x64": "0.27.0", + "@esbuild/win32-arm64": "0.27.0", + "@esbuild/win32-ia32": "0.27.0", + "@esbuild/win32-x64": "0.27.0" + } + } + } +} diff --git a/image-embedder-lambda/package.json b/image-embedder-lambda/package.json new file mode 100644 index 00000000000..5099cf4ffc8 --- /dev/null +++ b/image-embedder-lambda/package.json @@ -0,0 +1,16 @@ +{ + "name": "image-embedder-lambda", + "version": "1.0.0", + "description": "This is a service responsible for embedding uploaded images to the Grid and writing those embeddings to the S3 Vector Store.", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "build": "esbuild src/handler.ts --bundle --platform=node --target=node24 --outfile=out.js" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "@types/aws-lambda": "^8.10.159", + "esbuild": "0.27.0" + } +} diff --git a/image-embedder-lambda/src/handler.ts b/image-embedder-lambda/src/handler.ts new file mode 100644 index 00000000000..bd6b7bb6a69 --- /dev/null +++ b/image-embedder-lambda/src/handler.ts @@ -0,0 +1,15 @@ +// We are going to write to an SQS queue in image loader instead +// We want to make sure that we only write to the queue at the very end, +// when the record is successfully in ES +// Then the handler will embed and can do it in batches +// It's not easy to get it to take batches of 10 at a time but we can investigate +// Whether it's worth it to do that +// We can also reuse the lambda for the backfill + +import { Context, S3Event, APIGatewayProxyEvent } from 'aws-lambda'; + +export const handler = async (event: S3Event, context: Context) => { + console.log('Hello world!'); + + // Function code +}; \ No newline at end of file diff --git a/image-embedder-lambda/tsconfig.json b/image-embedder-lambda/tsconfig.json new file mode 100644 index 00000000000..f5f15ba84ef --- /dev/null +++ b/image-embedder-lambda/tsconfig.json @@ -0,0 +1,70 @@ +{ + "exclude": ["**/*.js*"], + "compilerOptions": { + /* Visit https://aka.ms/tsconfig.json to read more about this file */ + + /* Basic Options */ + // "incremental": true, /* Enable incremental compilation */ + "target": "es2020", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ + "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ + "lib": ["esnext"], /* Specify library files to be included in the compilation. */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + // "declaration": true, /* Generates corresponding '.d.ts' file. */ + // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + // "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outDir": "./", /* Redirect output structure to the directory. */ + // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "composite": true, /* Enable project compilation */ + // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ + // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + + /* Additional Checks */ + // "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + + /* Source Map Options */ + // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + + /* Advanced Options */ + "skipLibCheck": true, /* Skip type checking of declaration files. */ + "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ + } + } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000000..fb49cefeab8 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "grid", + "lockfileVersion": 3, + "requires": true, + "packages": {} +} From 6f4071dbe5ef5f2095a0a97590c89e64eae615f7 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Wed, 3 Dec 2025 11:55:16 +0000 Subject: [PATCH 012/494] add cdk skeleton --- cdk/.gitignore | 11 + cdk/README.md | 5 + cdk/bin/cdk.ts | 7 + cdk/cdk.json | 7 + cdk/eslint.config.mjs | 6 + cdk/jest.setup.js | 2 + .../image-embedder-lambda.test.ts.snap | 10 + cdk/lib/image-embedder-lambda.test.ts | 12 + cdk/lib/image-embedder-lambda.ts | 9 + cdk/package-lock.json | 11222 ++++++++++++++++ cdk/package.json | 44 + cdk/tsconfig.json | 12 + 12 files changed, 11347 insertions(+) create mode 100644 cdk/.gitignore create mode 100644 cdk/README.md create mode 100644 cdk/bin/cdk.ts create mode 100644 cdk/cdk.json create mode 100644 cdk/eslint.config.mjs create mode 100644 cdk/jest.setup.js create mode 100644 cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap create mode 100644 cdk/lib/image-embedder-lambda.test.ts create mode 100644 cdk/lib/image-embedder-lambda.ts create mode 100644 cdk/package-lock.json create mode 100644 cdk/package.json create mode 100644 cdk/tsconfig.json diff --git a/cdk/.gitignore b/cdk/.gitignore new file mode 100644 index 00000000000..bcc57feb1ed --- /dev/null +++ b/cdk/.gitignore @@ -0,0 +1,11 @@ +*.js +!jest.config.js +!jest.setup.js +!.eslintrc.js +*.d.ts +node_modules +dist + +# CDK asset staging directory +.cdk.staging +cdk.out diff --git a/cdk/README.md b/cdk/README.md new file mode 100644 index 00000000000..c1cd3a05471 --- /dev/null +++ b/cdk/README.md @@ -0,0 +1,5 @@ +# Infrastructure + +This directory defines the components to be deployed to AWS. + +See [`package.json`](./package.json) for a list of available scripts. diff --git a/cdk/bin/cdk.ts b/cdk/bin/cdk.ts new file mode 100644 index 00000000000..8955a94520a --- /dev/null +++ b/cdk/bin/cdk.ts @@ -0,0 +1,7 @@ +import "source-map-support/register"; +import { GuRoot } from "@guardian/cdk/lib/constructs/root"; +import { ImageEmbedderLambda } from "../lib/image-embedder-lambda"; + +const app = new GuRoot(); +new ImageEmbedderLambda(app, "ImageEmbedderLambda-euwest-1-PROD", { stack: "image-embedder-lambda", stage: "PROD", env: { region: "eu-west-1" } }); +new ImageEmbedderLambda(app, "ImageEmbedderLambda-euwest-1-TEST", { stack: "image-embedder-lambda", stage: "TEST", env: { region: "eu-west-1" } }); diff --git a/cdk/cdk.json b/cdk/cdk.json new file mode 100644 index 00000000000..da639850a5b --- /dev/null +++ b/cdk/cdk.json @@ -0,0 +1,7 @@ +{ + "app": "npx ts-node bin/cdk.ts", + "context": { + "aws-cdk:enableDiffNoFail": "true", + "@aws-cdk/core:stackRelativeExports": "true" + } +} diff --git a/cdk/eslint.config.mjs b/cdk/eslint.config.mjs new file mode 100644 index 00000000000..2003a00bde8 --- /dev/null +++ b/cdk/eslint.config.mjs @@ -0,0 +1,6 @@ +import guardian from '@guardian/eslint-config'; + +export default [ + ...guardian.configs.recommended, + ...guardian.configs.jest +]; \ No newline at end of file diff --git a/cdk/jest.setup.js b/cdk/jest.setup.js new file mode 100644 index 00000000000..78fa78c4c66 --- /dev/null +++ b/cdk/jest.setup.js @@ -0,0 +1,2 @@ +/* eslint-disable no-undef -- jest globals are missing due to guardian.recommended.jest eslint rules not covering jest.setup.js */ +jest.mock("@guardian/cdk/lib/constants/tracking-tag"); diff --git a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap new file mode 100644 index 00000000000..78d659a3ca2 --- /dev/null +++ b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap @@ -0,0 +1,10 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`The ImageEmbedderLambda stack matches the snapshot 1`] = ` +{ + "Metadata": { + "gu:cdk:constructs": [], + "gu:cdk:version": "TEST", + }, +} +`; diff --git a/cdk/lib/image-embedder-lambda.test.ts b/cdk/lib/image-embedder-lambda.test.ts new file mode 100644 index 00000000000..69b3a551d3f --- /dev/null +++ b/cdk/lib/image-embedder-lambda.test.ts @@ -0,0 +1,12 @@ +import { App } from "aws-cdk-lib"; +import { Template } from "aws-cdk-lib/assertions"; +import { ImageEmbedderLambda } from "./image-embedder-lambda"; + +describe("The ImageEmbedderLambda stack", () => { + it("matches the snapshot", () => { + const app = new App(); + const stack = new ImageEmbedderLambda(app, "ImageEmbedderLambda", { stack: "image-embedder-lambda", stage: "TEST" }); + const template = Template.fromStack(stack); + expect(template.toJSON()).toMatchSnapshot(); + }); +}); diff --git a/cdk/lib/image-embedder-lambda.ts b/cdk/lib/image-embedder-lambda.ts new file mode 100644 index 00000000000..e7eaa22f9f3 --- /dev/null +++ b/cdk/lib/image-embedder-lambda.ts @@ -0,0 +1,9 @@ +import type { GuStackProps } from "@guardian/cdk/lib/constructs/core"; +import { GuStack } from "@guardian/cdk/lib/constructs/core"; +import type { App } from "aws-cdk-lib"; + +export class ImageEmbedderLambda extends GuStack { + constructor(scope: App, id: string, props: GuStackProps) { + super(scope, id, props); + } +} diff --git a/cdk/package-lock.json b/cdk/package-lock.json new file mode 100644 index 00000000000..7b886abf84b --- /dev/null +++ b/cdk/package-lock.json @@ -0,0 +1,11222 @@ +{ + "name": "cdk", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "cdk", + "version": "0.0.0", + "devDependencies": { + "@guardian/cdk": "62.1.2", + "@guardian/eslint-config": "^11.0.0", + "@guardian/prettier": "5.0.0", + "@guardian/tsconfig": "^1.0.0", + "@types/jest": "^29.5.14", + "@types/node": "22.15.30", + "aws-cdk": "2.1030.0", + "aws-cdk-lib": "2.219.0", + "constructs": "10.4.2", + "eslint": "^9.34.0", + "jest": "^29.7.0", + "prettier": "^3.6.2", + "source-map-support": "^0.5.20", + "ts-jest": "^29.4.2", + "ts-node": "^10.9.2", + "typescript": "5.1.6" + } + }, + "node_modules/@aws-cdk/asset-awscli-v1": { + "version": "2.2.242", + "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.242.tgz", + "integrity": "sha512-4c1bAy2ISzcdKXYS1k4HYZsNrgiwbiDzj36ybwFVxEWZXVAP0dimQTCaB9fxu7sWzEjw3d+eaw6Fon+QTfTIpQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@aws-cdk/asset-node-proxy-agent-v6": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v6/-/asset-node-proxy-agent-v6-2.1.0.tgz", + "integrity": "sha512-7bY3J8GCVxLupn/kNmpPc5VJz8grx+4RKfnnJiO1LG+uxkZfANZG3RMHhE+qQxxwkyQ9/MfPtTpf748UhR425A==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@aws-cdk/cloud-assembly-schema": { + "version": "48.20.0", + "resolved": "https://registry.npmjs.org/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-48.20.0.tgz", + "integrity": "sha512-+eeiav9LY4wbF/EFuCt/vfvi/Zoxo8bf94PW5clbMraChEliq83w4TbRVy0jB9jE0v1ooFTtIjSQkowSPkfISg==", + "bundleDependencies": [ + "jsonschema", + "semver" + ], + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jsonschema": "~1.4.1", + "semver": "^7.7.2" + }, + "engines": { + "node": ">= 18.0.0" + } + }, + "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/jsonschema": { + "version": "1.4.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/@aws-cdk/cloud-assembly-schema/node_modules/semver": { + "version": "7.7.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-cognito-identity": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.943.0.tgz", + "integrity": "sha512-XkuokRF2IQ+VLBn0AwrwfFOkZ2c1IXACwQdn3CDnpBZpT1s2hgH3MX0DoH9+41w4ar2QCSI09uAJiv9PX4DLoQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/credential-provider-node": "3.943.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.943.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.943.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-ec2": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-ec2/-/client-ec2-3.943.0.tgz", + "integrity": "sha512-YdbGMwqUkNqXyq5plwgrz1Lw7dI7mmSwDooTpYBfEOA/zXMXi5OMgWral8fCqvfafnpxaAGnRpH1gppmldgQQg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/credential-provider-node": "3.943.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-sdk-ec2": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.943.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.943.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "@smithy/util-waiter": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-ssm": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-ssm/-/client-ssm-3.943.0.tgz", + "integrity": "sha512-1sIlqHD/MGqlXMrpYqqF6+hymWRWO8telVElIEujZXA1MMFrrB6X4HX2fx3pT1EdZ/4ume34EG4uSplNves1hA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/credential-provider-node": "3.943.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.943.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.943.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "@smithy/util-waiter": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-sso": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.943.0.tgz", + "integrity": "sha512-kOTO2B8Ks2qX73CyKY8PAajtf5n39aMe2spoiOF5EkgSzGV7hZ/HONRDyADlyxwfsX39Q2F2SpPUaXzon32IGw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.943.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.943.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.943.0.tgz", + "integrity": "sha512-8CBy2hI9ABF7RBVQuY1bgf/ue+WPmM/hl0adrXFlhnhkaQP0tFY5zhiy1Y+n7V+5f3/ORoHBmCCQmcHDDYJqJQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@aws-sdk/xml-builder": "3.930.0", + "@smithy/core": "^3.18.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/signature-v4": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-cognito-identity": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.943.0.tgz", + "integrity": "sha512-jZJ0uHjNlhfjx2ZX7YVYnh1wfSkLAvQmecGCSl9C6LJRNXy4uWFPbGjPqcA0tWp0WWIsUYhqjasgvCOMZIY8nw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-cognito-identity": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.943.0.tgz", + "integrity": "sha512-WnS5w9fK9CTuoZRVSIHLOMcI63oODg9qd1vXMYb7QGLGlfwUm4aG3hdu7i9XvYrpkQfE3dzwWLtXF4ZBuL1Tew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.943.0.tgz", + "integrity": "sha512-SA8bUcYDEACdhnhLpZNnWusBpdmj4Vl67Vxp3Zke7SvoWSYbuxa+tiDiC+c92Z4Yq6xNOuLPW912ZPb9/NsSkA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/util-stream": "^4.5.6", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.943.0.tgz", + "integrity": "sha512-BcLDb8l4oVW+NkuqXMlO7TnM6lBOWW318ylf4FRED/ply5eaGxkQYqdGvHSqGSN5Rb3vr5Ek0xpzSjeYD7C8Kw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.943.0", + "@aws-sdk/credential-provider-env": "3.943.0", + "@aws-sdk/credential-provider-http": "3.943.0", + "@aws-sdk/credential-provider-login": "3.943.0", + "@aws-sdk/credential-provider-process": "3.943.0", + "@aws-sdk/credential-provider-sso": "3.943.0", + "@aws-sdk/credential-provider-web-identity": "3.943.0", + "@aws-sdk/nested-clients": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/credential-provider-imds": "^4.2.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-login": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.943.0.tgz", + "integrity": "sha512-9iCOVkiRW+evxiJE94RqosCwRrzptAVPhRhGWv4osfYDhjNAvUMyrnZl3T1bjqCoKNcETRKEZIU3dqYHnUkcwQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.943.0", + "@aws-sdk/nested-clients": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.943.0.tgz", + "integrity": "sha512-14eddaH/gjCWoLSAELVrFOQNyswUYwWphIt+PdsJ/FqVfP4ay2HsiZVEIYbQtmrKHaoLJhiZKwBQRjcqJDZG0w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.943.0", + "@aws-sdk/credential-provider-http": "3.943.0", + "@aws-sdk/credential-provider-ini": "3.943.0", + "@aws-sdk/credential-provider-process": "3.943.0", + "@aws-sdk/credential-provider-sso": "3.943.0", + "@aws-sdk/credential-provider-web-identity": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/credential-provider-imds": "^4.2.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.943.0.tgz", + "integrity": "sha512-GIY/vUkthL33AdjOJ8r9vOosKf/3X+X7LIiACzGxvZZrtoOiRq0LADppdiKIB48vTL63VvW+eRIOFAxE6UDekw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.943.0.tgz", + "integrity": "sha512-1c5G11syUrru3D9OO6Uk+ul5e2lX1adb+7zQNyluNaLPXP6Dina6Sy6DFGRLu7tM8+M7luYmbS3w63rpYpaL+A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-sso": "3.943.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/token-providers": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.943.0.tgz", + "integrity": "sha512-VtyGKHxICSb4kKGuaqotxso8JVM8RjCS3UYdIMOxUt9TaFE/CZIfZKtjTr+IJ7M0P7t36wuSUb/jRLyNmGzUUA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.943.0", + "@aws-sdk/nested-clients": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-providers": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.943.0.tgz", + "integrity": "sha512-uZurSNsS01ehhrSwEPwcKdqp9lmd/x9q++BYO351bXyjSj1LzA/2lfUIxI2tCz/wAjJWOdnnlUdJj6P9I1uNvw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-cognito-identity": "3.943.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/credential-provider-cognito-identity": "3.943.0", + "@aws-sdk/credential-provider-env": "3.943.0", + "@aws-sdk/credential-provider-http": "3.943.0", + "@aws-sdk/credential-provider-ini": "3.943.0", + "@aws-sdk/credential-provider-login": "3.943.0", + "@aws-sdk/credential-provider-node": "3.943.0", + "@aws-sdk/credential-provider-process": "3.943.0", + "@aws-sdk/credential-provider-sso": "3.943.0", + "@aws-sdk/credential-provider-web-identity": "3.943.0", + "@aws-sdk/nested-clients": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/credential-provider-imds": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.936.0.tgz", + "integrity": "sha512-tAaObaAnsP1XnLGndfkGWFuzrJYuk9W0b/nLvol66t8FZExIAf/WdkT2NNAWOYxljVs++oHnyHBCxIlaHrzSiw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.936.0.tgz", + "integrity": "sha512-aPSJ12d3a3Ea5nyEnLbijCaaYJT2QjQ9iW+zGh5QcZYXmOGWbKVyPSxmVOboZQG+c1M8t6d2O7tqrwzIq8L8qw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.936.0.tgz", + "integrity": "sha512-l4aGbHpXM45YNgXggIux1HgsCVAvvBoqHPkqLnqMl9QVapfuSTjJHfDYDsx1Xxct6/m7qSMUzanBALhiaGO2fA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@aws/lambda-invoke-store": "^0.2.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-ec2": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-ec2/-/middleware-sdk-ec2-3.936.0.tgz", + "integrity": "sha512-8TaXLPUhAsTsJMPRGSVBL+wwqoM7mNLn8Ad2V26H00Ude5pyw1CYe7BxAjO3VY92Z3SCh4pOcxnlbDmB2IT4oQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-format-url": "3.936.0", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/protocol-http": "^5.3.5", + "@smithy/signature-v4": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.943.0.tgz", + "integrity": "sha512-956n4kVEwFNXndXfhSAN5wO+KRgqiWEEY+ECwLvxmmO8uQ0NWOa8l6l65nTtyuiWzMX81c9BvlyNR5EgUeeUvA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@smithy/core": "^3.18.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.943.0.tgz", + "integrity": "sha512-anFtB0p2FPuyUnbOULwGmKYqYKSq1M73c9uZ08jR/NCq6Trjq9cuF5TFTeHwjJyPRb4wMf2Qk859oiVfFqnQiw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.943.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.943.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.943.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.12", + "@smithy/middleware-retry": "^4.4.12", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.8", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.11", + "@smithy/util-defaults-mode-node": "^4.2.14", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.936.0.tgz", + "integrity": "sha512-wOKhzzWsshXGduxO4pqSiNyL9oUtk4BEvjWm9aaq6Hmfdoydq6v6t0rAGHWPjFwy9z2haovGRi3C8IxdMB4muw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.943.0.tgz", + "integrity": "sha512-cRKyIzwfkS+XztXIFPoWORuaxlIswP+a83BJzelX4S1gUZ7FcXB4+lj9Jxjn8SbQhR4TPU3Owbpu+S7pd6IRbQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.943.0", + "@aws-sdk/nested-clients": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.936.0.tgz", + "integrity": "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.936.0.tgz", + "integrity": "sha512-0Zx3Ntdpu+z9Wlm7JKUBOzS9EunwKAb4KdGUQQxDqh5Lc3ta5uBoub+FgmVuzwnmBu9U1Os8UuwVTH0Lgu+P5w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-endpoints": "^3.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-format-url": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.936.0.tgz", + "integrity": "sha512-MS5eSEtDUFIAMHrJaMERiHAvDPdfxc/T869ZjDNFAIiZhyc037REw0aoTNeimNXDNy2txRNZJaAUn/kE4RwN+g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/querystring-builder": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.893.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.893.0.tgz", + "integrity": "sha512-T89pFfgat6c8nMmpI8eKjBcDcgJq36+m9oiXbcUzeU55MP9ZuGgBomGjGnHaEyF36jenW9gmg3NfZDm0AO2XPg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.936.0.tgz", + "integrity": "sha512-eZ/XF6NxMtu+iCma58GRNRxSq4lHo6zHQLOZRIeL/ghqYJirqHdenMOwrzPettj60KWlv827RVebP9oNVrwZbw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.943.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.943.0.tgz", + "integrity": "sha512-gn+ILprVRrgAgTIBk2TDsJLRClzIOdStQFeFTcN0qpL8Z4GBCqMFhw7O7X+MM55Stt5s4jAauQ/VvoqmCADnQg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-user-agent": "3.943.0", + "@aws-sdk/types": "3.936.0", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.930.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.930.0.tgz", + "integrity": "sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "fast-xml-parser": "5.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws/lambda-invoke-store": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.1.tgz", + "integrity": "sha512-sIyFcoPZkTtNu9xFeEoynMef3bPJIAbOfUh+ueYcfhVl6xm2VRtMcMclSxmZCMnHHd4hlYKJeq/aggmBEWynww==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz", + "integrity": "sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@eslint-community/eslint-plugin-eslint-comments": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.4.1.tgz", + "integrity": "sha512-lb/Z/MzbTf7CaVYM9WCFNQZ4L1yi3ev2fsFPF99h31ljhSEyUoyEsKsNWiU+qD1glbYTDJdqgyaLKtyTkkqtuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^4.0.0", + "ignore": "^5.2.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.19.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz", + "integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@guardian/cdk": { + "version": "62.1.2", + "resolved": "https://registry.npmjs.org/@guardian/cdk/-/cdk-62.1.2.tgz", + "integrity": "sha512-JFd9w4luhbmzvlMjkJLdXYr12DSn0PUhTu3k2mgMyxZUQXAnkvcuz9rJr/rZm2I3f8opz2sZsIdFFFZkFeFTWA==", + "dev": true, + "dependencies": { + "@aws-sdk/client-ec2": "^3.908.0", + "@aws-sdk/client-ssm": "^3.925.0", + "@aws-sdk/credential-providers": "^3.925.0", + "@oclif/core": "3.26.6", + "chalk": "^4.1.2", + "codemaker": "^1.114.1", + "git-url-parse": "^16.0.1", + "js-yaml": "^4.1.0", + "read-pkg-up": "7.0.1", + "yargs": "^17.7.2" + }, + "bin": { + "gu-cdk": "bin/gu-cdk" + }, + "peerDependencies": { + "aws-cdk": "^2.1030.0", + "aws-cdk-lib": "^2.219.0", + "constructs": "^10.4.2" + } + }, + "node_modules/@guardian/eslint-config": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/@guardian/eslint-config/-/eslint-config-11.0.0.tgz", + "integrity": "sha512-+3wY4kWT+y1ghH2hmsXqNBfp7UOjafKzRWQoTabHxaqwMcpdiAdxAMJhpx27lk4BRdjiMOglir9oE07u4mDYtQ==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-plugin-eslint-comments": "4.4.1", + "@eslint/js": "9.19.0", + "@stylistic/eslint-plugin": "2.11.0", + "eslint-config-prettier": "9.1.0", + "eslint-import-resolver-typescript": "3.7.0", + "eslint-plugin-import-x": "4.6.1", + "eslint-plugin-jsx-a11y": "6.10.2", + "eslint-plugin-react": "7.37.2", + "eslint-plugin-react-hooks": "5.1.0", + "eslint-plugin-storybook": "0.11.1", + "globals": "15.14.0", + "read-package-up": "11.0.0", + "typescript-eslint": "8.22.0" + }, + "peerDependencies": { + "eslint": "^9.19.0" + } + }, + "node_modules/@guardian/prettier": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@guardian/prettier/-/prettier-5.0.0.tgz", + "integrity": "sha512-gJSQuuP7JVDOWQj4EUrwyJTnMt+frLkw0D2sLg70nHn76L3LmH2xTQtYMPUsqyqn37qocDPzgdvBdmATi50zRQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "prettier": "^3.0.0", + "tslib": "^2.5.3" + } + }, + "node_modules/@guardian/tsconfig": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@guardian/tsconfig/-/tsconfig-1.0.1.tgz", + "integrity": "sha512-PB24nZ6WTBB8aZ9EyxJw1vC5FYkGqwMQ/O5Oogp6P5HCQU5MN0JpUXvpYci7kwV2oXD1Az06UBnLyyVXOVMadQ==", + "dev": true + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/core": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", + "@types/node": "*", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "v8-to-istanbul": "^9.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.18", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.2" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/types": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.4.0" + } + }, + "node_modules/@oclif/core": { + "version": "3.26.6", + "resolved": "https://registry.npmjs.org/@oclif/core/-/core-3.26.6.tgz", + "integrity": "sha512-+FiTw1IPuJTF9tSAlTsY8bGK4sgthehjz7c2SvYdgQncTkxI2xvUch/8QpjNYGLEmUneNygvYMRBax2KJcLccA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cli-progress": "^3.11.5", + "ansi-escapes": "^4.3.2", + "ansi-styles": "^4.3.0", + "cardinal": "^2.1.1", + "chalk": "^4.1.2", + "clean-stack": "^3.0.1", + "cli-progress": "^3.12.0", + "color": "^4.2.3", + "debug": "^4.3.4", + "ejs": "^3.1.10", + "get-package-type": "^0.1.0", + "globby": "^11.1.0", + "hyperlinker": "^1.0.0", + "indent-string": "^4.0.0", + "is-wsl": "^2.2.0", + "js-yaml": "^3.14.1", + "minimatch": "^9.0.4", + "natural-orderby": "^2.0.3", + "object-treeify": "^1.1.33", + "password-prompt": "^1.1.3", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "supports-color": "^8.1.1", + "supports-hyperlinks": "^2.2.0", + "widest-line": "^3.1.0", + "wordwrap": "^1.0.0", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@oclif/core/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/@oclif/core/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } + }, + "node_modules/@smithy/abort-controller": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.5.tgz", + "integrity": "sha512-j7HwVkBw68YW8UmFRcjZOmssE77Rvk0GWAIN1oFBhsaovQmZWYCIcGa9/pwRB0ExI8Sk9MWNALTjftjHZea7VA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/config-resolver": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.3.tgz", + "integrity": "sha512-ezHLe1tKLUxDJo2LHtDuEDyWXolw8WGOR92qb4bQdWq/zKenO5BvctZGrVJBK08zjezSk7bmbKFOXIVyChvDLw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-config-provider": "^4.2.0", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "3.18.6", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.18.6.tgz", + "integrity": "sha512-8Q/ugWqfDUEU1Exw71+DoOzlONJ2Cn9QA8VeeDzLLjzO/qruh9UKFzbszy4jXcIYgGofxYiT0t1TT6+CT/GupQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/middleware-serde": "^4.2.6", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-stream": "^4.5.6", + "@smithy/util-utf8": "^4.2.0", + "@smithy/uuid": "^1.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.5.tgz", + "integrity": "sha512-BZwotjoZWn9+36nimwm/OLIcVe+KYRwzMjfhd4QT7QxPm9WY0HiOV8t/Wlh+HVUif0SBVV7ksq8//hPaBC/okQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.6.tgz", + "integrity": "sha512-3+RG3EA6BBJ/ofZUeTFJA7mHfSYrZtQIrDP9dI8Lf7X6Jbos2jptuLrAAteDiFVrmbEmLSuRG/bUKzfAXk7dhg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.5", + "@smithy/querystring-builder": "^4.2.5", + "@smithy/types": "^4.9.0", + "@smithy/util-base64": "^4.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-node": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.5.tgz", + "integrity": "sha512-DpYX914YOfA3UDT9CN1BM787PcHfWRBB43fFGCYrZFUH0Jv+5t8yYl+Pd5PW4+QzoGEDvn5d5QIO4j2HyYZQSA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.5.tgz", + "integrity": "sha512-2L2erASEro1WC5nV+plwIMxrTXpvpfzl4e+Nre6vBVRR2HKeGGcvpJyyL3/PpiSg+cJG2KpTmZmq934Olb6e5A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.0.tgz", + "integrity": "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.5.tgz", + "integrity": "sha512-Y/RabVa5vbl5FuHYV2vUCwvh/dqzrEY/K2yWPSqvhFUwIY0atLqO4TienjBXakoy4zrKAMCZwg+YEqmH7jaN7A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "4.3.13", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.3.13.tgz", + "integrity": "sha512-X4za1qCdyx1hEVVXuAWlZuK6wzLDv1uw1OY9VtaYy1lULl661+frY7FeuHdYdl7qAARUxH2yvNExU2/SmRFfcg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.18.6", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-middleware": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.13.tgz", + "integrity": "sha512-RzIDF9OrSviXX7MQeKOm8r/372KTyY8Jmp6HNKOOYlrguHADuM3ED/f4aCyNhZZFLG55lv5beBin7nL0Nzy1Dw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/service-error-classification": "^4.2.5", + "@smithy/smithy-client": "^4.9.9", + "@smithy/types": "^4.9.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/uuid": "^1.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.6.tgz", + "integrity": "sha512-VkLoE/z7e2g8pirwisLz8XJWedUSY8my/qrp81VmAdyrhi94T+riBfwP+AOEEFR9rFTSonC/5D2eWNmFabHyGQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-stack": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.5.tgz", + "integrity": "sha512-bYrutc+neOyWxtZdbB2USbQttZN0mXaOyYLIsaTbJhFsfpXyGWUxJpEuO1rJ8IIJm2qH4+xJT0mxUSsEDTYwdQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-config-provider": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.5.tgz", + "integrity": "sha512-UTurh1C4qkVCtqggI36DGbLB2Kv8UlcFdMXDcWMbqVY2uRg0XmT9Pb4Vj6oSQ34eizO1fvR0RnFV4Axw4IrrAg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.5.tgz", + "integrity": "sha512-CMnzM9R2WqlqXQGtIlsHMEZfXKJVTIrqCNoSd/QpAyp+Dw0a1Vps13l6ma1fH8g7zSPNsA59B/kWgeylFuA/lw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/querystring-builder": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/property-provider": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.5.tgz", + "integrity": "sha512-8iLN1XSE1rl4MuxvQ+5OSk/Zb5El7NJZ1td6Tn+8dQQHIjp59Lwl6bd0+nzw6SKm2wSSriH2v/I9LPzUic7EOg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/protocol-http": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.5.tgz", + "integrity": "sha512-RlaL+sA0LNMp03bf7XPbFmT5gN+w3besXSWMkA8rcmxLSVfiEXElQi4O2IWwPfxzcHkxqrwBFMbngB8yx/RvaQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-builder": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.5.tgz", + "integrity": "sha512-y98otMI1saoajeik2kLfGyRp11e5U/iJYH/wLCh3aTV/XutbGT9nziKGkgCaMD1ghK7p6htHMm6b6scl9JRUWg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "@smithy/util-uri-escape": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-parser": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.5.tgz", + "integrity": "sha512-031WCTdPYgiQRYNPXznHXof2YM0GwL6SeaSyTH/P72M1Vz73TvCNH2Nq8Iu2IEPq9QP2yx0/nrw5YmSeAi/AjQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/service-error-classification": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.5.tgz", + "integrity": "sha512-8fEvK+WPE3wUAcDvqDQG1Vk3ANLR8Px979te96m84CbKAjBVf25rPYSzb4xU4hlTyho7VhOGnh5i62D/JVF0JQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.0.tgz", + "integrity": "sha512-5WmZ5+kJgJDjwXXIzr1vDTG+RhF9wzSODQBfkrQ2VVkYALKGvZX1lgVSxEkgicSAFnFhPj5rudJV0zoinqS0bA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.5.tgz", + "integrity": "sha512-xSUfMu1FT7ccfSXkoLl/QRQBi2rOvi3tiBZU2Tdy3I6cgvZ6SEi9QNey+lqps/sJRnogIS+lq+B1gxxbra2a/w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^4.2.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-hex-encoding": "^4.2.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-uri-escape": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/smithy-client": { + "version": "4.9.9", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.9.9.tgz", + "integrity": "sha512-SUnZJMMo5yCmgjopJbiNeo1vlr8KvdnEfIHV9rlD77QuOGdRotIVBcOrBuMr+sI9zrnhtDtLP054bZVbpZpiQA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.18.6", + "@smithy/middleware-endpoint": "^4.3.13", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-stream": "^4.5.6", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.9.0.tgz", + "integrity": "sha512-MvUbdnXDTwykR8cB1WZvNNwqoWVaTRA0RLlLmf/cIFNMM2cKWz01X4Ly6SMC4Kks30r8tT3Cty0jmeWfiuyHTA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/url-parser": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.5.tgz", + "integrity": "sha512-VaxMGsilqFnK1CeBX+LXnSuaMx4sTL/6znSZh2829txWieazdVxr54HmiyTsIbpOTLcf5nYpq9lpzmwRdxj6rQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/querystring-parser": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-base64": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.0.tgz", + "integrity": "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-browser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.0.tgz", + "integrity": "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-node": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.1.tgz", + "integrity": "sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.0.tgz", + "integrity": "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-config-provider": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.0.tgz", + "integrity": "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "4.3.12", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.12.tgz", + "integrity": "sha512-TKc6FnOxFULKxLgTNHYjcFqdOYzXVPFFVm5JhI30F3RdhT7nYOtOsjgaOwfDRmA/3U66O9KaBQ3UHoXwayRhAg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^4.2.5", + "@smithy/smithy-client": "^4.9.9", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-node": { + "version": "4.2.15", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.15.tgz", + "integrity": "sha512-94NqfQVo+vGc5gsQ9SROZqOvBkGNMQu6pjXbnn8aQvBUhc31kx49gxlkBEqgmaZQHUUfdRUin5gK/HlHKmbAwg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/config-resolver": "^4.4.3", + "@smithy/credential-provider-imds": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/smithy-client": "^4.9.9", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-endpoints": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.5.tgz", + "integrity": "sha512-3O63AAWu2cSNQZp+ayl9I3NapW1p1rR5mlVHcF6hAB1dPZUQFfRPYtplWX/3xrzWthPGj5FqB12taJJCfH6s8A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-hex-encoding": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.0.tgz", + "integrity": "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-middleware": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.5.tgz", + "integrity": "sha512-6Y3+rvBF7+PZOc40ybeZMcGln6xJGVeY60E7jy9Mv5iKpMJpHgRE6dKy9ScsVxvfAYuEX4Q9a65DQX90KaQ3bA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-retry": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.5.tgz", + "integrity": "sha512-GBj3+EZBbN4NAqJ/7pAhsXdfzdlznOh8PydUijy6FpNIMnHPSMO2/rP4HKu+UFeikJxShERk528oy7GT79YiJg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-stream": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.6.tgz", + "integrity": "sha512-qWw/UM59TiaFrPevefOZ8CNBKbYEP6wBAIlLqxn3VAIo9rgnTNc4ASbVrqDmhuwI87usnjhdQrxodzAGFFzbRQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/types": "^4.9.0", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-hex-encoding": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-uri-escape": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.0.tgz", + "integrity": "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.0.tgz", + "integrity": "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-waiter": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.5.tgz", + "integrity": "sha512-Dbun99A3InifQdIrsXZ+QLcC0PGBPAdrl4cj1mTgJvyc9N2zf7QSxg8TBkzsCmGJdE3TLbO9ycwpY0EkWahQ/g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/uuid": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.0.tgz", + "integrity": "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@storybook/csf": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.13.tgz", + "integrity": "sha512-7xOOwCLGB3ebM87eemep89MYRFTko+D8qE7EdAAq74lgdqRR5cOUtYWJLjO2dLtP94nqoOdHJo6MdLLKzg412Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^2.19.0" + } + }, + "node_modules/@storybook/csf/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@stylistic/eslint-plugin": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.11.0.tgz", + "integrity": "sha512-PNRHbydNG5EH8NK4c+izdJlxajIR6GxcUhzsYNRsn6Myep4dsZt0qFCz3rCPnkvgO5FYibDcMqgNHUT+zvjYZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/utils": "^8.13.0", + "eslint-visitor-keys": "^4.2.0", + "espree": "^10.3.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", + "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.2" + } + }, + "node_modules/@types/cli-progress": { + "version": "3.11.6", + "resolved": "https://registry.npmjs.org/@types/cli-progress/-/cli-progress-3.11.6.tgz", + "integrity": "sha512-cE3+jb9WRlu+uOSAugewNpITJDt1VF8dHOopPO4IABFc3SXYL5WE/+PTz/FCdZRRfIujiWW3n3aMbv1eIGVRWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/doctrine": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.9.tgz", + "integrity": "sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "29.5.14", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", + "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "^29.0.0", + "pretty-format": "^29.0.0" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.15.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.30.tgz", + "integrity": "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/parse-path": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/@types/parse-path/-/parse-path-7.0.3.tgz", + "integrity": "sha512-LriObC2+KYZD3FzCrgWGv/qufdUy4eXrxcLgQMfYXgPbLIecKIsVBaQgUPmxSSLcjmYbDTQbMgr6qr6l/eb7Bg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/stack-utils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "17.0.35", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.35.tgz", + "integrity": "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.22.0.tgz", + "integrity": "sha512-4Uta6REnz/xEJMvwf72wdUnC3rr4jAQf5jnTkeRQ9b6soxLxhDEbS/pfMPoJLDfFPNVRdryqWUIV/2GZzDJFZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.22.0", + "@typescript-eslint/type-utils": "8.22.0", + "@typescript-eslint/utils": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0", + "graphemer": "^1.4.0", + "ignore": "^5.3.1", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.22.0.tgz", + "integrity": "sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.22.0.tgz", + "integrity": "sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.22.0.tgz", + "integrity": "sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.22.0.tgz", + "integrity": "sha512-T8oc1MbF8L+Bk2msAvCUzjxVB2Z2f+vXYfcucE2wOmYs7ZUwco5Ep0fYZw8quNwOiw9K8GYVL+Kgc2pETNTLOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.22.0", + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/typescript-estree": "8.22.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.22.0.tgz", + "integrity": "sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.22.0.tgz", + "integrity": "sha512-MqtmbdNEdoNxTPzpWiWnqNac54h8JDAmkWtJExBVVnSrSmi9z+sZUt0LfKqk9rjqmKOIeRhO4fHHJ1nQIjduIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.22.0", + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/typescript-estree": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.22.0.tgz", + "integrity": "sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.22.0.tgz", + "integrity": "sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.22.0.tgz", + "integrity": "sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.22.0.tgz", + "integrity": "sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.48.1.tgz", + "integrity": "sha512-HQWSicah4s9z2/HifRPQ6b6R7G+SBx64JlFQpgSSHWPKdvCZX57XCbszg/bapbRsOEv42q5tayTYcEFpACcX1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.48.1", + "@typescript-eslint/types": "^8.48.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.48.1.tgz", + "integrity": "sha512-rj4vWQsytQbLxC5Bf4XwZ0/CKd362DkWMUkviT7DCS057SK64D5lH74sSGzhI6PDD2HCEq02xAP9cX68dYyg1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.48.1", + "@typescript-eslint/visitor-keys": "8.48.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.48.1.tgz", + "integrity": "sha512-k0Jhs4CpEffIBm6wPaCXBAD7jxBtrHjrSgtfCjUvPp9AZ78lXKdTR8fxyZO5y4vWNlOvYXRtngSZNSn+H53Jkw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.22.0.tgz", + "integrity": "sha512-NzE3aB62fDEaGjaAYZE4LH7I1MUwHooQ98Byq0G0y3kkibPJQIXVUspzlFOmOfHhiDLwKzMlWxaNv+/qcZurJA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/typescript-estree": "8.22.0", + "@typescript-eslint/utils": "8.22.0", + "debug": "^4.3.4", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.22.0.tgz", + "integrity": "sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.22.0.tgz", + "integrity": "sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.22.0.tgz", + "integrity": "sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.22.0.tgz", + "integrity": "sha512-T8oc1MbF8L+Bk2msAvCUzjxVB2Z2f+vXYfcucE2wOmYs7ZUwco5Ep0fYZw8quNwOiw9K8GYVL+Kgc2pETNTLOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.22.0", + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/typescript-estree": "8.22.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.22.0.tgz", + "integrity": "sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.48.1.tgz", + "integrity": "sha512-+fZ3LZNeiELGmimrujsDCT4CRIbq5oXdHe7chLiW8qzqyPMnn1puNstCrMNVAqwcl2FdIxkuJ4tOs/RFDBVc/Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.48.1.tgz", + "integrity": "sha512-/9wQ4PqaefTK6POVTjJaYS0bynCgzh6ClJHGSBj06XEHjkfylzB+A3qvyaXnErEZSaxhIo4YdyBgq6j4RysxDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.48.1", + "@typescript-eslint/tsconfig-utils": "8.48.1", + "@typescript-eslint/types": "8.48.1", + "@typescript-eslint/visitor-keys": "8.48.1", + "debug": "^4.3.4", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.48.1.tgz", + "integrity": "sha512-fAnhLrDjiVfey5wwFRwrweyRlCmdz5ZxXz2G/4cLn0YDLjTapmN4gcCsTBR1N2rWnZSDeWpYtgLDsJt+FpmcwA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.48.1", + "@typescript-eslint/types": "8.48.1", + "@typescript-eslint/typescript-estree": "8.48.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.48.1.tgz", + "integrity": "sha512-BmxxndzEWhE4TIEEMBs8lP3MBWN3jFPs/p6gPm/wkv02o41hI6cq9AuSmGAaTTHPtA1FTi2jBre4A9rm5ZmX+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.48.1", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansicolors": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", + "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.9.tgz", + "integrity": "sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz", + "integrity": "sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz", + "integrity": "sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types-flow": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", + "integrity": "sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "dev": true, + "license": "MIT" + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-cdk": { + "version": "2.1030.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1030.0.tgz", + "integrity": "sha512-jYgOy1Hqx8cOTWW9On9xpypXLecjOqSZ4X2q5U0Gzd14xI+HLmpaRJV5ILJ8vYrLKVbqjhiog0pdxAC7vwF9uQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "cdk": "bin/cdk" + }, + "engines": { + "node": ">= 18.0.0" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/aws-cdk-lib": { + "version": "2.219.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.219.0.tgz", + "integrity": "sha512-Rq1/f3exfFEWee1znNq8yvR1TuRQ4xQZz3JNkliBW9dFwyrDe7l/dmlAf6DVvB3nuiZAaUS+vh4ua1LZ7Ec8kg==", + "bundleDependencies": [ + "@balena/dockerignore", + "case", + "fs-extra", + "ignore", + "jsonschema", + "minimatch", + "punycode", + "semver", + "table", + "yaml", + "mime-types" + ], + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@aws-cdk/asset-awscli-v1": "2.2.242", + "@aws-cdk/asset-node-proxy-agent-v6": "^2.1.0", + "@aws-cdk/cloud-assembly-schema": "^48.6.0", + "@balena/dockerignore": "^1.0.2", + "case": "1.6.3", + "fs-extra": "^11.3.1", + "ignore": "^5.3.2", + "jsonschema": "^1.5.0", + "mime-types": "^2.1.35", + "minimatch": "^3.1.2", + "punycode": "^2.3.1", + "semver": "^7.7.2", + "table": "^6.9.0", + "yaml": "1.10.2" + }, + "engines": { + "node": ">= 18.0.0" + }, + "peerDependencies": { + "constructs": "^10.0.0" + } + }, + "node_modules/aws-cdk-lib/node_modules/@balena/dockerignore": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "Apache-2.0" + }, + "node_modules/aws-cdk-lib/node_modules/ajv": { + "version": "8.17.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/aws-cdk-lib/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/aws-cdk-lib/node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/aws-cdk-lib/node_modules/astral-regex": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/aws-cdk-lib/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/brace-expansion": { + "version": "1.1.12", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/aws-cdk-lib/node_modules/case": { + "version": "1.6.3", + "dev": true, + "inBundle": true, + "license": "(MIT OR GPL-3.0-or-later)", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/aws-cdk-lib/node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/aws-cdk-lib/node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/fast-deep-equal": { + "version": "3.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/fast-uri": { + "version": "3.1.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "inBundle": true, + "license": "BSD-3-Clause" + }, + "node_modules/aws-cdk-lib/node_modules/fs-extra": { + "version": "11.3.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/aws-cdk-lib/node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/aws-cdk-lib/node_modules/ignore": { + "version": "5.3.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/aws-cdk-lib/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/aws-cdk-lib/node_modules/json-schema-traverse": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/jsonfile": { + "version": "6.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/aws-cdk-lib/node_modules/jsonschema": { + "version": "1.5.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/aws-cdk-lib/node_modules/lodash.truncate": { + "version": "4.4.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/aws-cdk-lib/node_modules/mime-db": { + "version": "1.52.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/aws-cdk-lib/node_modules/mime-types": { + "version": "2.1.35", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/aws-cdk-lib/node_modules/minimatch": { + "version": "3.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/aws-cdk-lib/node_modules/punycode": { + "version": "2.3.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/aws-cdk-lib/node_modules/require-from-string": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/aws-cdk-lib/node_modules/semver": { + "version": "7.7.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/aws-cdk-lib/node_modules/slice-ansi": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/aws-cdk-lib/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/aws-cdk-lib/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/aws-cdk-lib/node_modules/table": { + "version": "6.9.0", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "dependencies": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/aws-cdk-lib/node_modules/universalify": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/aws-cdk-lib/node_modules/yaml": { + "version": "1.10.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">= 6" + } + }, + "node_modules/axe-core": { + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.0.tgz", + "integrity": "sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ==", + "dev": true, + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/babel-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/transform": "^29.7.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^29.6.3", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz", + "integrity": "sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.12.13", + "@babel/plugin-syntax-class-static-block": "^7.14.5", + "@babel/plugin-syntax-import-attributes": "^7.24.7", + "@babel/plugin-syntax-import-meta": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-private-property-in-object": "^7.14.5", + "@babel/plugin-syntax-top-level-await": "^7.14.5" + }, + "peerDependencies": { + "@babel/core": "^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/babel-preset-jest": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "dev": true, + "license": "MIT", + "dependencies": { + "babel-plugin-jest-hoist": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.32", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.32.tgz", + "integrity": "sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/bowser": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.13.1.tgz", + "integrity": "sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz", + "integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.8.25", + "caniuse-lite": "^1.0.30001754", + "electron-to-chromium": "^1.5.249", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.1.4" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001759", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001759.tgz", + "integrity": "sha512-Pzfx9fOKoKvevQf8oCXoyNRQ5QyxJj+3O0Rqx2V5oxT61KGx8+n6hV/IUyJeifUci2clnmmKVpvtiqRzgiWjSw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/cardinal": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", + "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansicolors": "~0.3.2", + "redeyed": "~2.1.0" + }, + "bin": { + "cdl": "bin/cdl.js" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cjs-module-lexer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/clean-stack": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-3.0.1.tgz", + "integrity": "sha512-lR9wNiMRcVQjSB3a7xXGLuz4cr4wJuuXlaAEbRutGowQTmlp7R72/DOgN21e8jdwblMWl9UOJMJXarX94pzKdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-progress": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/cli-progress/-/cli-progress-3.12.0.tgz", + "integrity": "sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.3" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/codemaker": { + "version": "1.120.0", + "resolved": "https://registry.npmjs.org/codemaker/-/codemaker-1.120.0.tgz", + "integrity": "sha512-WRa7z7dK8bNQYnBGNL31cPtB7Ar/s18IaiJ8HKqGBgNi+HhOJoarAJyV2Uqeras/3mt82/VCGvcrLPzlvk/POw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "camelcase": "^6.3.0", + "decamelize": "^5.0.1", + "fs-extra": "^10.1.0" + }, + "engines": { + "node": ">= 14.17.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", + "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", + "dev": true, + "license": "MIT" + }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/constructs": { + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.4.2.tgz", + "integrity": "sha512-wsNxBlAott2qg8Zv87q3eYZYgheb9lchtBfjHzzLHtXbttwSrHPs1NNQbBrmbb1YZvYg2+Vh0Dor76w4mFxJkA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz", + "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/dedent": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.0.tgz", + "integrity": "sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/dir-glob": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.263", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.263.tgz", + "integrity": "sha512-DrqJ11Knd+lo+dv+lltvfMDLU27g14LMdH2b0O3Pio4uk0x+z7OR+JrmyacTPN2M8w3BrZ7/RTwG3R9B7irPlg==", + "dev": true, + "license": "ISC" + }, + "node_modules/emittery": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/enhanced-resolve": { + "version": "5.18.3", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", + "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", + "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-iterator-helpers": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz", + "integrity": "sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.0.3", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.6", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.4", + "safe-array-concat": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz", + "integrity": "sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.39.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz", + "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.1", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.39.1", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-config-prettier": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", + "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "dev": true, + "license": "MIT", + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.7.0.tgz", + "integrity": "sha512-Vrwyi8HHxY97K5ebydMtffsWAn1SCR9eol49eCd5fJS4O1WV7PaAjbcjmbfJJSMz/t4Mal212Uz/fQZrOB8mow==", + "dev": true, + "license": "ISC", + "dependencies": { + "@nolyfill/is-core-module": "1.0.39", + "debug": "^4.3.7", + "enhanced-resolve": "^5.15.0", + "fast-glob": "^3.3.2", + "get-tsconfig": "^4.7.5", + "is-bun-module": "^1.0.2", + "is-glob": "^4.0.3", + "stable-hash": "^0.0.4" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-import-x": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.6.1.tgz", + "integrity": "sha512-wluSUifMIb7UfwWXqx7Yx0lE/SGCcGXECLx/9bCmbY2nneLwvAZ4vkd1IXDjPKFvdcdUgr1BaRnaRpx3k2+Pfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/doctrine": "^0.0.9", + "@typescript-eslint/scope-manager": "^8.1.0", + "@typescript-eslint/utils": "^8.1.0", + "debug": "^4.3.4", + "doctrine": "^3.0.0", + "enhanced-resolve": "^5.17.1", + "eslint-import-resolver-node": "^0.3.9", + "get-tsconfig": "^4.7.3", + "is-glob": "^4.0.3", + "minimatch": "^9.0.3", + "semver": "^7.6.3", + "stable-hash": "^0.0.4", + "tslib": "^2.6.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", + "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "aria-query": "^5.3.2", + "array-includes": "^3.1.8", + "array.prototype.flatmap": "^1.3.2", + "ast-types-flow": "^0.0.8", + "axe-core": "^4.10.0", + "axobject-query": "^4.1.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "hasown": "^2.0.2", + "jsx-ast-utils": "^3.3.5", + "language-tags": "^1.0.9", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "safe-regex-test": "^1.0.3", + "string.prototype.includes": "^2.0.1" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.37.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.2.tgz", + "integrity": "sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.2", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.1.0", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.0", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.11", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0.tgz", + "integrity": "sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.5", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", + "integrity": "sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-storybook": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-0.11.1.tgz", + "integrity": "sha512-yGKpAYkBm/Q2hZg476vRUAvd9lAccjjSvzU5nYy3BSQbKTPy7uopx7JEpwk2vSuw4weTMZzWF64z9/gp/K5RCg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@storybook/csf": "^0.1.11", + "@typescript-eslint/utils": "^8.8.1", + "ts-dedent": "^2.2.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "eslint": ">=6" + } + }, + "node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/@eslint/js": { + "version": "9.39.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", + "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", + "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-xml-parser": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.2.5.tgz", + "integrity": "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^2.1.0" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", + "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up-simple": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/git-up": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/git-up/-/git-up-8.1.1.tgz", + "integrity": "sha512-FDenSF3fVqBYSaJoYy1KSc2wosx0gCvKP+c+PRBht7cAaiCeQlBtfBDX9vgnNOHmdePlSFITVcn4pFfcgNvx3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-ssh": "^1.4.0", + "parse-url": "^9.2.0" + } + }, + "node_modules/git-url-parse": { + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-16.1.0.tgz", + "integrity": "sha512-cPLz4HuK86wClEW7iDdeAKcCVlWXmrLpb2L+G9goW0Z1dtpNS6BXXSOckUTlJT/LDQViE1QZKstNORzHsLnobw==", + "dev": true, + "license": "MIT", + "dependencies": { + "git-up": "^8.1.0" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/globals": { + "version": "15.14.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz", + "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true, + "license": "MIT" + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", + "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/hyperlinker": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz", + "integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/index-to-position": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-1.2.0.tgz", + "integrity": "sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bun-module": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.3.0.tgz", + "integrity": "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.6.3" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ssh": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.1.tgz", + "integrity": "sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "protocols": "^2.0.1" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/jake": { + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "async": "^3.2.6", + "filelist": "^1.0.4", + "picocolors": "^1.1.1" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", + "import-local": "^3.0.2", + "jest-cli": "^29.7.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "execa": "^5.0.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-circus": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^1.0.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "p-limit": "^3.1.0", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-cli": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "create-jest": "^29.7.0", + "exit": "^0.1.2", + "import-local": "^3.0.2", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-each": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", + "micromatch": "^4.0.4", + "walker": "^1.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^29.6.3", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^29.7.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-mock": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-util": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "resolve": "^1.20.0", + "resolve.exports": "^2.0.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "dev": true, + "license": "MIT", + "dependencies": { + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", + "p-limit": "^3.1.0", + "source-map-support": "0.5.13" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-runner/node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/jest-runtime": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-jsx": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^29.7.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "natural-compare": "^1.4.0", + "pretty-format": "^29.7.0", + "semver": "^7.5.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-util/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-watcher": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.13.1", + "jest-util": "^29.7.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-worker": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-util": "^29.7.0", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", + "integrity": "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/language-subtag-registry": { + "version": "0.3.23", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", + "integrity": "sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/language-tags": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.9.tgz", + "integrity": "sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==", + "dev": true, + "license": "MIT", + "dependencies": { + "language-subtag-registry": "^0.3.20" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/natural-orderby": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/natural-orderby/-/natural-orderby-2.0.3.tgz", + "integrity": "sha512-p7KTHxU0CUrcOXe62Zfrb5Z13nLvPhSWR/so3kFulUQU0sgUll2Z0LwpsLN351eOOD+hRGu/F1g+6xDfPeD++Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-package-data": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", + "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^7.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-treeify": { + "version": "1.1.33", + "resolved": "https://registry.npmjs.org/object-treeify/-/object-treeify-1.1.33.tgz", + "integrity": "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.1.tgz", + "integrity": "sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-path": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.1.0.tgz", + "integrity": "sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "protocols": "^2.0.0" + } + }, + "node_modules/parse-url": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-9.2.0.tgz", + "integrity": "sha512-bCgsFI+GeGWPAvAiUv63ZorMeif3/U0zaXABGJbOWt5OH2KCaPHF6S+0ok4aqM9RuIPGyZdx9tR9l13PsW4AYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/parse-path": "^7.0.0", + "parse-path": "^7.0.0" + }, + "engines": { + "node": ">=14.13.0" + } + }, + "node_modules/password-prompt": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/password-prompt/-/password-prompt-1.1.3.tgz", + "integrity": "sha512-HkrjG2aJlvF0t2BMH0e2LB/EHf3Lcq3fNMzy4GYHcQblAvOl+QQji1Lx7WRBMqpVK8p+KR7bCg7oqAMXtdgqyw==", + "dev": true, + "license": "0BSD", + "dependencies": { + "ansi-escapes": "^4.3.2", + "cross-spawn": "^7.0.3" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pirates": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "3.7.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.7.4.tgz", + "integrity": "sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/protocols": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.2.tgz", + "integrity": "sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", + "dev": true, + "license": "MIT" + }, + "node_modules/read-package-up": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz", + "integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up-simple": "^1.0.0", + "read-pkg": "^9.0.0", + "type-fest": "^4.6.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-package-up/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", + "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.3", + "normalize-package-data": "^6.0.0", + "parse-json": "^8.0.0", + "type-fest": "^4.6.0", + "unicorn-magic": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/parse-json": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.3.0.tgz", + "integrity": "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.26.2", + "index-to-position": "^1.1.0", + "type-fest": "^4.39.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/redeyed": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", + "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esprima": "~4.0.0" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/simple-swizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", + "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/stable-hash": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", + "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", + "dev": true, + "license": "MIT" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string.prototype.includes": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz", + "integrity": "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/strnum": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.1.tgz", + "integrity": "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", + "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", + "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-dedent": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.10" + } + }, + "node_modules/ts-jest": { + "version": "29.4.6", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.6.tgz", + "integrity": "sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bs-logger": "^0.2.6", + "fast-json-stable-stringify": "^2.1.0", + "handlebars": "^4.7.8", + "json5": "^2.2.3", + "lodash.memoize": "^4.1.2", + "make-error": "^1.3.6", + "semver": "^7.7.3", + "type-fest": "^4.41.0", + "yargs-parser": "^21.1.1" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@jest/transform": "^29.0.0 || ^30.0.0", + "@jest/types": "^29.0.0 || ^30.0.0", + "babel-jest": "^29.0.0 || ^30.0.0", + "jest": "^29.0.0 || ^30.0.0", + "jest-util": "^29.0.0 || ^30.0.0", + "typescript": ">=4.3 <6" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@jest/transform": { + "optional": true + }, + "@jest/types": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jest-util": { + "optional": true + } + } + }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", + "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.22.0.tgz", + "integrity": "sha512-Y2rj210FW1Wb6TWXzQc5+P+EWI9/zdS57hLEc0gnyuvdzWo8+Y8brKlbj0muejonhMI/xAZCnZZwjbIfv1CkOw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.22.0", + "@typescript-eslint/parser": "8.22.0", + "@typescript-eslint/utils": "8.22.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.22.0.tgz", + "integrity": "sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.22.0.tgz", + "integrity": "sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.22.0.tgz", + "integrity": "sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/visitor-keys": "8.22.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.22.0.tgz", + "integrity": "sha512-T8oc1MbF8L+Bk2msAvCUzjxVB2Z2f+vXYfcucE2wOmYs7ZUwco5Ep0fYZw8quNwOiw9K8GYVL+Kgc2pETNTLOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.22.0", + "@typescript-eslint/types": "8.22.0", + "@typescript-eslint/typescript-estree": "8.22.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.22.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.22.0.tgz", + "integrity": "sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.22.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/uglify-js": { + "version": "3.19.3", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", + "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", + "dev": true, + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", + "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/widest-line": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", + "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/cdk/package.json b/cdk/package.json new file mode 100644 index 00000000000..a0dbeb0dace --- /dev/null +++ b/cdk/package.json @@ -0,0 +1,44 @@ +{ + "name": "cdk", + "version": "0.0.0", + "private": true, + "scripts": { + "build": "tsc", + "test": "jest", + "test-update": "jest -u", + "format": "prettier --write \"{lib,bin}/**/*.ts\"", + "lint": "eslint lib/** bin/** --no-error-on-unmatched-pattern", + "synth": "cdk synth --path-metadata false --version-reporting false", + "diff": "cdk diff --path-metadata false --version-reporting false" + }, + "devDependencies": { + "@guardian/cdk": "62.1.2", + "@guardian/eslint-config": "^11.0.0", + "@guardian/prettier": "5.0.0", + "@guardian/tsconfig": "^1.0.0", + "@types/jest": "^29.5.14", + "@types/node": "22.15.30", + "aws-cdk": "2.1030.0", + "aws-cdk-lib": "2.219.0", + "constructs": "10.4.2", + "eslint": "^9.34.0", + "jest": "^29.7.0", + "prettier": "^3.6.2", + "source-map-support": "^0.5.20", + "ts-jest": "^29.4.2", + "ts-node": "^10.9.2", + "typescript": "5.1.6" + }, + "prettier": "@guardian/prettier", + "jest": { + "testMatch": [ + "/lib/**/*.test.ts" + ], + "transform": { + "^.+\\.tsx?$": "ts-jest" + }, + "setupFilesAfterEnv": [ + "./jest.setup.js" + ] + } +} \ No newline at end of file diff --git a/cdk/tsconfig.json b/cdk/tsconfig.json new file mode 100644 index 00000000000..d3899d53df6 --- /dev/null +++ b/cdk/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "@guardian/tsconfig/tsconfig.json", + "compilerOptions": { + "module": "CommonJS" + }, + "include": ["lib/**/*", "bin/**/*"], + "exclude": [ + "node_modules", + "cdk.out", + "lib/**/__snapshots__/**" + ] +} From 19a7fdd45ff9d8d56d0b579c79495e2b7d31677d Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Wed, 3 Dec 2025 13:51:29 +0000 Subject: [PATCH 013/494] add cdk lambda definition --- .../image-embedder-lambda.test.ts.snap | 2 +- cdk/lib/image-embedder-lambda.ts | 21 +- cdk/package-lock.json | 4423 ++++++++++++----- cdk/package.json | 20 +- image-embedder-lambda/package.json | 2 +- 5 files changed, 3178 insertions(+), 1290 deletions(-) diff --git a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap index 78d659a3ca2..f6c389aee7f 100644 --- a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap +++ b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`The ImageEmbedderLambda stack matches the snapshot 1`] = ` { diff --git a/cdk/lib/image-embedder-lambda.ts b/cdk/lib/image-embedder-lambda.ts index e7eaa22f9f3..ef148cb62a5 100644 --- a/cdk/lib/image-embedder-lambda.ts +++ b/cdk/lib/image-embedder-lambda.ts @@ -1,9 +1,28 @@ import type { GuStackProps } from "@guardian/cdk/lib/constructs/core"; import { GuStack } from "@guardian/cdk/lib/constructs/core"; +import { GuLambdaFunction } from "@guardian/cdk/lib/constructs/lambda"; import type { App } from "aws-cdk-lib"; +import { aws_lambda as lambda } from "aws-cdk-lib"; +import { Architecture } from "aws-cdk-lib/aws-lambda"; export class ImageEmbedderLambda extends GuStack { constructor(scope: App, id: string, props: GuStackProps) { super(scope, id, props); + + const LAMBDA_NODE_VERSION = lambda.Runtime.NODEJS_24_X; + + new GuLambdaFunction( + this, + 'ImageEmbedderHandler', + { + fileName: 'image-embedder.zip', + functionName: `image-embedder-${props.stage}`, + runtime: LAMBDA_NODE_VERSION, + architecture: Architecture.ARM_64, + handler: 'dist.handler', + app: 'image-embedder-handler', + }, + ); + } -} +} \ No newline at end of file diff --git a/cdk/package-lock.json b/cdk/package-lock.json index 7b886abf84b..a874aceba27 100644 --- a/cdk/package-lock.json +++ b/cdk/package-lock.json @@ -8,24 +8,32 @@ "name": "cdk", "version": "0.0.0", "devDependencies": { - "@guardian/cdk": "62.1.2", - "@guardian/eslint-config": "^11.0.0", - "@guardian/prettier": "5.0.0", + "@guardian/cdk": "^62.1.2", + "@guardian/eslint-config": "^13.0.0", + "@guardian/prettier": "^9.0.0", "@guardian/tsconfig": "^1.0.0", - "@types/jest": "^29.5.14", - "@types/node": "22.15.30", - "aws-cdk": "2.1030.0", - "aws-cdk-lib": "2.219.0", - "constructs": "10.4.2", + "@types/jest": "^30.0.0", + "@types/node": "^24.10.1", + "aws-cdk": "^2.1033.0", + "aws-cdk-lib": "^2.231.0", + "constructs": "^10.4.3", "eslint": "^9.34.0", - "jest": "^29.7.0", + "jest": "^30.2.0", "prettier": "^3.6.2", "source-map-support": "^0.5.20", "ts-jest": "^29.4.2", "ts-node": "^10.9.2", - "typescript": "5.1.6" + "typescript": "^5.9.3" } }, + "node_modules/@adobe/css-tools": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.4.tgz", + "integrity": "sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/@aws-cdk/asset-awscli-v1": { "version": "2.2.242", "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.242.tgz", @@ -1417,6 +1425,17 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", + "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.27.2", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", @@ -1496,238 +1515,743 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, - "node_modules/@eslint-community/eslint-plugin-eslint-comments": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.4.1.tgz", - "integrity": "sha512-lb/Z/MzbTf7CaVYM9WCFNQZ4L1yi3ev2fsFPF99h31ljhSEyUoyEsKsNWiU+qD1glbYTDJdqgyaLKtyTkkqtuQ==", + "node_modules/@emnapi/core": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz", + "integrity": "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "escape-string-regexp": "^4.0.0", - "ignore": "^5.2.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "node_modules/@emnapi/runtime": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", + "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==", "dev": true, "license": "MIT", + "optional": true, "dependencies": { - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "tslib": "^2.4.0" } }, - "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.0.tgz", + "integrity": "sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "peer": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=18" } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.2", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", - "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "node_modules/@esbuild/android-arm": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.0.tgz", + "integrity": "sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">=18" } }, - "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "node_modules/@esbuild/android-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.0.tgz", + "integrity": "sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.7", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "node_modules/@esbuild/android-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.0.tgz", + "integrity": "sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=18" } }, - "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.0.tgz", + "integrity": "sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, "engines": { - "node": "*" + "node": ">=18" } }, - "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.0.tgz", + "integrity": "sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g==", + "cpu": [ + "x64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0" - }, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.0.tgz", + "integrity": "sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", - "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.0.tgz", + "integrity": "sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.1", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "node_modules/@esbuild/linux-arm": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.0.tgz", + "integrity": "sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ==", + "cpu": [ + "arm" + ], "dev": true, "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.0.tgz", + "integrity": "sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ==", + "cpu": [ + "arm64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.0.tgz", + "integrity": "sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { - "node": "*" + "node": ">=18" } }, - "node_modules/@eslint/js": { - "version": "9.19.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.19.0.tgz", - "integrity": "sha512-rbq9/g38qjfqFLOVPvwjIvFFdNziEC5S65jmjPw5r6A//QH+W91akh9irMwjDN8zKUTak6W9EsAv4m/7Wnw0UQ==", + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.0.tgz", + "integrity": "sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg==", + "cpu": [ + "loong64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.0.tgz", + "integrity": "sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg==", + "cpu": [ + "mips64el" + ], "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.0.tgz", + "integrity": "sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/core": "^0.17.0", - "levn": "^0.4.1" - }, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" } }, - "node_modules/@guardian/cdk": { - "version": "62.1.2", - "resolved": "https://registry.npmjs.org/@guardian/cdk/-/cdk-62.1.2.tgz", - "integrity": "sha512-JFd9w4luhbmzvlMjkJLdXYr12DSn0PUhTu3k2mgMyxZUQXAnkvcuz9rJr/rZm2I3f8opz2sZsIdFFFZkFeFTWA==", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.0.tgz", + "integrity": "sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ==", + "cpu": [ + "riscv64" + ], "dev": true, - "dependencies": { - "@aws-sdk/client-ec2": "^3.908.0", - "@aws-sdk/client-ssm": "^3.925.0", - "@aws-sdk/credential-providers": "^3.925.0", - "@oclif/core": "3.26.6", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.0.tgz", + "integrity": "sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.0.tgz", + "integrity": "sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.0.tgz", + "integrity": "sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.0.tgz", + "integrity": "sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.0.tgz", + "integrity": "sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.0.tgz", + "integrity": "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.0.tgz", + "integrity": "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.0.tgz", + "integrity": "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.0.tgz", + "integrity": "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.0.tgz", + "integrity": "sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.0.tgz", + "integrity": "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-plugin-eslint-comments": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.5.0.tgz", + "integrity": "sha512-MAhuTKlr4y/CE3WYX26raZjy+I/kS2PLKSzvfmDCGrBLTFHOYwqROZdr4XwPgXwX3K9rjzMr4pSmUWGnzsUyMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "escape-string-regexp": "^4.0.0", + "ignore": "^5.2.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "9.39.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", + "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@guardian/cdk": { + "version": "62.1.2", + "resolved": "https://registry.npmjs.org/@guardian/cdk/-/cdk-62.1.2.tgz", + "integrity": "sha512-JFd9w4luhbmzvlMjkJLdXYr12DSn0PUhTu3k2mgMyxZUQXAnkvcuz9rJr/rZm2I3f8opz2sZsIdFFFZkFeFTWA==", + "dev": true, + "dependencies": { + "@aws-sdk/client-ec2": "^3.908.0", + "@aws-sdk/client-ssm": "^3.925.0", + "@aws-sdk/credential-providers": "^3.925.0", + "@oclif/core": "3.26.6", "chalk": "^4.1.2", "codemaker": "^1.114.1", "git-url-parse": "^16.0.1", @@ -1745,38 +2269,37 @@ } }, "node_modules/@guardian/eslint-config": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/@guardian/eslint-config/-/eslint-config-11.0.0.tgz", - "integrity": "sha512-+3wY4kWT+y1ghH2hmsXqNBfp7UOjafKzRWQoTabHxaqwMcpdiAdxAMJhpx27lk4BRdjiMOglir9oE07u4mDYtQ==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@guardian/eslint-config/-/eslint-config-13.0.0.tgz", + "integrity": "sha512-/U+EwCpyEX6x/foOSE4ft+wCErbEMmm/H/fF8Xw1R4Y1X9QTgruzPMZ+H/tqJXnuXFH8ElTU1DzPFQ4Ks8CoXw==", "dev": true, "dependencies": { - "@eslint-community/eslint-plugin-eslint-comments": "4.4.1", - "@eslint/js": "9.19.0", - "@stylistic/eslint-plugin": "2.11.0", - "eslint-config-prettier": "9.1.0", - "eslint-import-resolver-typescript": "3.7.0", - "eslint-plugin-import-x": "4.6.1", + "@eslint-community/eslint-plugin-eslint-comments": "4.5.0", + "@eslint/js": "9.39.1", + "@stylistic/eslint-plugin": "5.5.0", + "eslint-config-prettier": "10.1.8", + "eslint-import-resolver-typescript": "4.4.4", + "eslint-plugin-import-x": "4.16.1", "eslint-plugin-jsx-a11y": "6.10.2", - "eslint-plugin-react": "7.37.2", - "eslint-plugin-react-hooks": "5.1.0", - "eslint-plugin-storybook": "0.11.1", - "globals": "15.14.0", - "read-package-up": "11.0.0", - "typescript-eslint": "8.22.0" + "eslint-plugin-react": "7.37.5", + "eslint-plugin-react-hooks": "7.0.1", + "eslint-plugin-storybook": "10.0.6", + "globals": "16.5.0", + "read-package-up": "12.0.0", + "typescript-eslint": "8.46.3" }, "peerDependencies": { - "eslint": "^9.19.0" + "eslint": "^9.39.1" } }, "node_modules/@guardian/prettier": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@guardian/prettier/-/prettier-5.0.0.tgz", - "integrity": "sha512-gJSQuuP7JVDOWQj4EUrwyJTnMt+frLkw0D2sLg70nHn76L3LmH2xTQtYMPUsqyqn37qocDPzgdvBdmATi50zRQ==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@guardian/prettier/-/prettier-9.0.0.tgz", + "integrity": "sha512-iAiNWPW0RAVKmUbMEzvANsYU5sskyi045PG+nH4/I7yGWMEdSmrnytbuaFNnSg/Ug77EZxdWXShvgPNd7qtTAQ==", "dev": true, - "license": "MIT", "peerDependencies": { - "prettier": "^3.0.0", - "tslib": "^2.5.3" + "prettier": "^3.6.2", + "tslib": "^2.8.1" } }, "node_modules/@guardian/tsconfig": { @@ -1837,6 +2360,102 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1965,61 +2584,61 @@ } }, "node_modules/@jest/console": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", - "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.2.0.tgz", + "integrity": "sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", + "@jest/types": "30.2.0", "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", + "chalk": "^4.1.2", + "jest-message-util": "30.2.0", + "jest-util": "30.2.0", "slash": "^3.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/core": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", - "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.2.0.tgz", + "integrity": "sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "^29.7.0", - "@jest/reporters": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/console": "30.2.0", + "@jest/pattern": "30.0.1", + "@jest/reporters": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.7.0", - "jest-config": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-resolve-dependencies": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "jest-watcher": "^29.7.0", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-changed-files": "30.2.0", + "jest-config": "30.2.0", + "jest-haste-map": "30.2.0", + "jest-message-util": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.2.0", + "jest-resolve-dependencies": "30.2.0", + "jest-runner": "30.2.0", + "jest-runtime": "30.2.0", + "jest-snapshot": "30.2.0", + "jest-util": "30.2.0", + "jest-validate": "30.2.0", + "jest-watcher": "30.2.0", + "micromatch": "^4.0.8", + "pretty-format": "30.2.0", + "slash": "^3.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -2030,117 +2649,150 @@ } } }, + "node_modules/@jest/diff-sequences": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", + "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, "node_modules/@jest/environment": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", - "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz", + "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==", "dev": true, "license": "MIT", "dependencies": { - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/fake-timers": "30.2.0", + "@jest/types": "30.2.0", "@types/node": "*", - "jest-mock": "^29.7.0" + "jest-mock": "30.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz", + "integrity": "sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==", "dev": true, "license": "MIT", "dependencies": { - "expect": "^29.7.0", - "jest-snapshot": "^29.7.0" + "expect": "30.2.0", + "jest-snapshot": "30.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", - "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", + "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", "dev": true, "license": "MIT", "dependencies": { - "jest-get-type": "^29.6.3" + "@jest/get-type": "30.1.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", - "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz", + "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "@sinonjs/fake-timers": "^10.0.2", + "@jest/types": "30.2.0", + "@sinonjs/fake-timers": "^13.0.0", "@types/node": "*", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" + "jest-message-util": "30.2.0", + "jest-mock": "30.2.0", + "jest-util": "30.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/globals": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", - "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.2.0.tgz", + "integrity": "sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.2.0", + "@jest/expect": "30.2.0", + "@jest/types": "30.2.0", + "jest-mock": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/pattern": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", + "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/types": "^29.6.3", - "jest-mock": "^29.7.0" + "@types/node": "*", + "jest-regex-util": "30.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/reporters": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", - "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz", + "integrity": "sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==", "dev": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", + "@jest/console": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "@jridgewell/trace-mapping": "^0.3.25", "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", + "chalk": "^4.1.2", + "collect-v8-coverage": "^1.0.2", + "exit-x": "^0.2.2", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", + "istanbul-lib-source-maps": "^5.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", + "jest-message-util": "30.2.0", + "jest-util": "30.2.0", + "jest-worker": "30.2.0", "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", + "string-length": "^4.0.2", "v8-to-istanbul": "^9.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -2152,108 +2804,125 @@ } }, "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/snapshot-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz", + "integrity": "sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==", "dev": true, "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.27.8" + "@jest/types": "30.2.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "natural-compare": "^1.4.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/source-map": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", - "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", + "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.18", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" + "@jridgewell/trace-mapping": "^0.3.25", + "callsites": "^3.1.0", + "graceful-fs": "^4.2.11" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/test-result": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", - "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.2.0.tgz", + "integrity": "sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "^29.7.0", - "@jest/types": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "@jest/console": "30.2.0", + "@jest/types": "30.2.0", + "@types/istanbul-lib-coverage": "^2.0.6", + "collect-v8-coverage": "^1.0.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/test-sequencer": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", - "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz", + "integrity": "sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==", "dev": true, "license": "MIT", "dependencies": { - "@jest/test-result": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", + "@jest/test-result": "30.2.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", "slash": "^3.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/transform": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", - "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", + "integrity": "sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.6.3", - "@jridgewell/trace-mapping": "^0.3.18", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", + "@babel/core": "^7.27.4", + "@jest/types": "30.2.0", + "@jridgewell/trace-mapping": "^0.3.25", + "babel-plugin-istanbul": "^7.0.1", + "chalk": "^4.1.2", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-util": "30.2.0", + "micromatch": "^4.0.8", + "pirates": "^4.0.7", "slash": "^3.0.0", - "write-file-atomic": "^4.0.2" + "write-file-atomic": "^5.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jest/types": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", - "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", + "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", + "@jest/pattern": "30.0.1", + "@jest/schemas": "30.0.5", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/@jridgewell/gen-mapping": { @@ -2306,6 +2975,19 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2344,16 +3026,6 @@ "node": ">= 8" } }, - "node_modules/@nolyfill/is-core-module": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", - "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.4.0" - } - }, "node_modules/@oclif/core": { "version": "3.26.6", "resolved": "https://registry.npmjs.org/@oclif/core/-/core-3.26.6.tgz", @@ -2418,10 +3090,34 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgr/core": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", + "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/pkgr" + } + }, "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "version": "0.34.41", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", + "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", "dev": true, "license": "MIT" }, @@ -2436,13 +3132,13 @@ } }, "node_modules/@sinonjs/fake-timers": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", - "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", + "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^3.0.0" + "@sinonjs/commons": "^3.0.1" } }, "node_modules/@smithy/abort-controller": { @@ -3080,47 +3776,159 @@ "node": ">=18.0.0" } }, - "node_modules/@storybook/csf": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.1.13.tgz", - "integrity": "sha512-7xOOwCLGB3ebM87eemep89MYRFTko+D8qE7EdAAq74lgdqRR5cOUtYWJLjO2dLtP94nqoOdHJo6MdLLKzg412Q==", + "node_modules/@storybook/global": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@storybook/global/-/global-5.0.0.tgz", + "integrity": "sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@storybook/icons": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@storybook/icons/-/icons-2.0.1.tgz", + "integrity": "sha512-/smVjw88yK3CKsiuR71vNgWQ9+NuY2L+e8X7IMrFjexjm6ZR8ULrV2DRkTA61aV6ryefslzHEGDInGpnNeIocg==", + "dev": true, + "license": "MIT", + "peer": true, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@stylistic/eslint-plugin": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.5.0.tgz", + "integrity": "sha512-IeZF+8H0ns6prg4VrkhgL+yrvDXWDH2cKchrbh80ejG9dQgZWp10epHMbgRuQvgchLII/lfh6Xn3lu6+6L86Hw==", "dev": true, "license": "MIT", "dependencies": { - "type-fest": "^2.19.0" + "@eslint-community/eslint-utils": "^4.9.0", + "@typescript-eslint/types": "^8.46.1", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "estraverse": "^5.3.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "peerDependencies": { + "eslint": ">=9.0.0" } }, - "node_modules/@storybook/csf/node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "node_modules/@testing-library/dom": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", + "integrity": "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==", "dev": true, - "license": "(MIT OR CC0-1.0)", + "license": "MIT", + "peer": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^5.0.1", + "aria-query": "5.3.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.5.0", + "picocolors": "1.1.1", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@testing-library/dom/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "peer": true, "engines": { - "node": ">=12.20" + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@stylistic/eslint-plugin": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.11.0.tgz", - "integrity": "sha512-PNRHbydNG5EH8NK4c+izdJlxajIR6GxcUhzsYNRsn6Myep4dsZt0qFCz3rCPnkvgO5FYibDcMqgNHUT+zvjYZw==", + "node_modules/@testing-library/dom/node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "dev": true, + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, + "node_modules/@testing-library/dom/node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@typescript-eslint/utils": "^8.13.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", - "estraverse": "^5.3.0", - "picomatch": "^4.0.2" + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@testing-library/dom/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@testing-library/jest-dom": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz", + "integrity": "sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@adobe/css-tools": "^4.4.0", + "aria-query": "^5.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.6.3", + "picocolors": "^1.1.1", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/node_modules/dom-accessibility-api": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz", + "integrity": "sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@testing-library/user-event": { + "version": "14.6.1", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz", + "integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12", + "npm": ">=6" }, "peerDependencies": { - "eslint": ">=8.40.0" + "@testing-library/dom": ">=7.21.4" } }, "node_modules/@tsconfig/node10": { @@ -3151,6 +3959,25 @@ "dev": true, "license": "MIT" }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/aria-query": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz", + "integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/@types/babel__core": { "version": "7.20.5", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", @@ -3196,6 +4023,18 @@ "@babel/types": "^7.28.2" } }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, "node_modules/@types/cli-progress": { "version": "3.11.6", "resolved": "https://registry.npmjs.org/@types/cli-progress/-/cli-progress-3.11.6.tgz", @@ -3206,12 +4045,13 @@ "@types/node": "*" } }, - "node_modules/@types/doctrine": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/@types/doctrine/-/doctrine-0.0.9.tgz", - "integrity": "sha512-eOIHzCUSH7SMfonMG1LsC2f8vxBFtho6NGBznK41R84YzPuvSBzrhEps33IsQiOW9+VL6NQ9DbjQJznk/S4uRA==", + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", "dev": true, - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@types/estree": { "version": "1.0.8", @@ -3220,16 +4060,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -3258,14 +4088,14 @@ } }, "node_modules/@types/jest": { - "version": "29.5.14", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.5.14.tgz", - "integrity": "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==", + "version": "30.0.0", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-30.0.0.tgz", + "integrity": "sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==", "dev": true, "license": "MIT", "dependencies": { - "expect": "^29.0.0", - "pretty-format": "^29.0.0" + "expect": "^30.0.0", + "pretty-format": "^30.0.0" } }, "node_modules/@types/json-schema": { @@ -3276,13 +4106,13 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.15.30", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.30.tgz", - "integrity": "sha512-6Q7lr06bEHdlfplU6YRbgG1SFBdlsfNC4/lX+SkhiTs0cpJkOElmWls8PxDFv4yY/xKb8Y6SO0OmSX4wgqTZbA==", + "version": "24.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", + "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", "dev": true, "license": "MIT", "dependencies": { - "undici-types": "~6.21.0" + "undici-types": "~7.16.0" } }, "node_modules/@types/normalize-package-data": { @@ -3324,21 +4154,45 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.22.0.tgz", - "integrity": "sha512-4Uta6REnz/xEJMvwf72wdUnC3rr4jAQf5jnTkeRQ9b6soxLxhDEbS/pfMPoJLDfFPNVRdryqWUIV/2GZzDJFZw==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.46.3.tgz", + "integrity": "sha512-sbaQ27XBUopBkRiuY/P9sWGOWUW4rl8fDoHIUmLpZd8uldsTyB4/Zg6bWTegPoTLnKj9Hqgn3QD6cjPNB32Odw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.22.0", - "@typescript-eslint/type-utils": "8.22.0", - "@typescript-eslint/utils": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0", + "@typescript-eslint/scope-manager": "8.46.3", + "@typescript-eslint/type-utils": "8.46.3", + "@typescript-eslint/utils": "8.46.3", + "@typescript-eslint/visitor-keys": "8.46.3", "graphemer": "^1.4.0", - "ignore": "^5.3.1", + "ignore": "^7.0.0", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.0.0" + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.46.3", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/project-service": { + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.3.tgz", + "integrity": "sha512-Fz8yFXsp2wDFeUElO88S9n4w1I4CWDTXDqDr9gYvZgUpwXQqmZBr9+NTTql5R3J7+hrJZPdpiWaB9VNhAKYLuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.3", + "@typescript-eslint/types": "^8.46.3", + "debug": "^4.3.4" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3348,33 +4202,48 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.22.0.tgz", - "integrity": "sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.3.tgz", + "integrity": "sha512-FCi7Y1zgrmxp3DfWfr+3m9ansUUFoy8dkEdeQSgA9gbm8DaHYvZCdkFRQrtKiedFf3Ha6VmoqoAaP68+i+22kg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0" + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/visitor-keys": "8.46.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.3.tgz", + "integrity": "sha512-GLupljMniHNIROP0zE7nCcybptolcH8QZfXOpCfhQDAdwJ/ZTlcaBOYebSOZotpti/3HrHSw7D3PZm75gYFsOA==", + "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.22.0.tgz", - "integrity": "sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.3.tgz", + "integrity": "sha512-G7Ok9WN/ggW7e/tOf8TQYMaxgID3Iujn231hfi0Pc7ZheztIJVpO44ekY00b7akqc6nZcvregk0Jpah3kep6hA==", "dev": true, "license": "MIT", "engines": { @@ -3386,20 +4255,22 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.22.0.tgz", - "integrity": "sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.3.tgz", + "integrity": "sha512-f/NvtRjOm80BtNM5OQtlaBdM5BRFUv7gf381j9wygDNL+qOYSNOgtQ/DCndiYi80iIOv76QqaTmp4fa9hwI0OA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0", + "@typescript-eslint/project-service": "8.46.3", + "@typescript-eslint/tsconfig-utils": "8.46.3", + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/visitor-keys": "8.46.3", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^2.0.0" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3409,20 +4280,20 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.22.0.tgz", - "integrity": "sha512-T8oc1MbF8L+Bk2msAvCUzjxVB2Z2f+vXYfcucE2wOmYs7ZUwco5Ep0fYZw8quNwOiw9K8GYVL+Kgc2pETNTLOg==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.3.tgz", + "integrity": "sha512-VXw7qmdkucEx9WkmR3ld/u6VhRyKeiF1uxWwCy/iuNfokjJ7VhsgLSOTjsol8BunSw190zABzpwdNsze2Kpo4g==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.22.0", - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/typescript-estree": "8.22.0" + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.3", + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/typescript-estree": "8.46.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3433,18 +4304,18 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.22.0.tgz", - "integrity": "sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.3.tgz", + "integrity": "sha512-uk574k8IU0rOF/AjniX8qbLSGURJVUCeM5e4MIMKBFFi8weeiLrG1fyQejyLXQpRZbU/1BuQasleV/RfHC3hHg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.46.3", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3454,17 +4325,27 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/@typescript-eslint/parser": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.22.0.tgz", - "integrity": "sha512-MqtmbdNEdoNxTPzpWiWnqNac54h8JDAmkWtJExBVVnSrSmi9z+sZUt0LfKqk9rjqmKOIeRhO4fHHJ1nQIjduIQ==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.46.3.tgz", + "integrity": "sha512-6m1I5RmHBGTnUGS113G04DMu3CpSdxCAU/UvtjNWL4Nuf3MW9tQhiJqRlHzChIkhy6kZSAQmc+I1bcGjE3yNKg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.22.0", - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/typescript-estree": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0", + "@typescript-eslint/scope-manager": "8.46.3", + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/typescript-estree": "8.46.3", + "@typescript-eslint/visitor-keys": "8.46.3", "debug": "^4.3.4" }, "engines": { @@ -3476,31 +4357,70 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/project-service": { + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.3.tgz", + "integrity": "sha512-Fz8yFXsp2wDFeUElO88S9n4w1I4CWDTXDqDr9gYvZgUpwXQqmZBr9+NTTql5R3J7+hrJZPdpiWaB9VNhAKYLuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.3", + "@typescript-eslint/types": "^8.46.3", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.22.0.tgz", - "integrity": "sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.3.tgz", + "integrity": "sha512-FCi7Y1zgrmxp3DfWfr+3m9ansUUFoy8dkEdeQSgA9gbm8DaHYvZCdkFRQrtKiedFf3Ha6VmoqoAaP68+i+22kg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0" + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/visitor-keys": "8.46.3" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.3.tgz", + "integrity": "sha512-GLupljMniHNIROP0zE7nCcybptolcH8QZfXOpCfhQDAdwJ/ZTlcaBOYebSOZotpti/3HrHSw7D3PZm75gYFsOA==", + "dev": true, + "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.22.0.tgz", - "integrity": "sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.3.tgz", + "integrity": "sha512-G7Ok9WN/ggW7e/tOf8TQYMaxgID3Iujn231hfi0Pc7ZheztIJVpO44ekY00b7akqc6nZcvregk0Jpah3kep6hA==", "dev": true, "license": "MIT", "engines": { @@ -3512,20 +4432,22 @@ } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.22.0.tgz", - "integrity": "sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.3.tgz", + "integrity": "sha512-f/NvtRjOm80BtNM5OQtlaBdM5BRFUv7gf381j9wygDNL+qOYSNOgtQ/DCndiYi80iIOv76QqaTmp4fa9hwI0OA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0", + "@typescript-eslint/project-service": "8.46.3", + "@typescript-eslint/tsconfig-utils": "8.46.3", + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/visitor-keys": "8.46.3", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^2.0.0" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3535,18 +4457,18 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.22.0.tgz", - "integrity": "sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.3.tgz", + "integrity": "sha512-uk574k8IU0rOF/AjniX8qbLSGURJVUCeM5e4MIMKBFFi8weeiLrG1fyQejyLXQpRZbU/1BuQasleV/RfHC3hHg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.46.3", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3614,16 +4536,17 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.22.0.tgz", - "integrity": "sha512-NzE3aB62fDEaGjaAYZE4LH7I1MUwHooQ98Byq0G0y3kkibPJQIXVUspzlFOmOfHhiDLwKzMlWxaNv+/qcZurJA==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.46.3.tgz", + "integrity": "sha512-ZPCADbr+qfz3aiTTYNNkCbUt+cjNwI/5McyANNrFBpVxPt7GqpEYz5ZfdwuFyGUnJ9FdDXbGODUu6iRCI6XRXw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.22.0", - "@typescript-eslint/utils": "8.22.0", + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/typescript-estree": "8.46.3", + "@typescript-eslint/utils": "8.46.3", "debug": "^4.3.4", - "ts-api-utils": "^2.0.0" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3634,18 +4557,40 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/project-service": { + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.3.tgz", + "integrity": "sha512-Fz8yFXsp2wDFeUElO88S9n4w1I4CWDTXDqDr9gYvZgUpwXQqmZBr9+NTTql5R3J7+hrJZPdpiWaB9VNhAKYLuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.3", + "@typescript-eslint/types": "^8.46.3", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.22.0.tgz", - "integrity": "sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.3.tgz", + "integrity": "sha512-FCi7Y1zgrmxp3DfWfr+3m9ansUUFoy8dkEdeQSgA9gbm8DaHYvZCdkFRQrtKiedFf3Ha6VmoqoAaP68+i+22kg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0" + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/visitor-keys": "8.46.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3655,10 +4600,27 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.3.tgz", + "integrity": "sha512-GLupljMniHNIROP0zE7nCcybptolcH8QZfXOpCfhQDAdwJ/ZTlcaBOYebSOZotpti/3HrHSw7D3PZm75gYFsOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.22.0.tgz", - "integrity": "sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.3.tgz", + "integrity": "sha512-G7Ok9WN/ggW7e/tOf8TQYMaxgID3Iujn231hfi0Pc7ZheztIJVpO44ekY00b7akqc6nZcvregk0Jpah3kep6hA==", "dev": true, "license": "MIT", "engines": { @@ -3670,20 +4632,22 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.22.0.tgz", - "integrity": "sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.3.tgz", + "integrity": "sha512-f/NvtRjOm80BtNM5OQtlaBdM5BRFUv7gf381j9wygDNL+qOYSNOgtQ/DCndiYi80iIOv76QqaTmp4fa9hwI0OA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0", + "@typescript-eslint/project-service": "8.46.3", + "@typescript-eslint/tsconfig-utils": "8.46.3", + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/visitor-keys": "8.46.3", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^2.0.0" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3693,20 +4657,20 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.22.0.tgz", - "integrity": "sha512-T8oc1MbF8L+Bk2msAvCUzjxVB2Z2f+vXYfcucE2wOmYs7ZUwco5Ep0fYZw8quNwOiw9K8GYVL+Kgc2pETNTLOg==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.3.tgz", + "integrity": "sha512-VXw7qmdkucEx9WkmR3ld/u6VhRyKeiF1uxWwCy/iuNfokjJ7VhsgLSOTjsol8BunSw190zABzpwdNsze2Kpo4g==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.22.0", - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/typescript-estree": "8.22.0" + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.3", + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/typescript-estree": "8.46.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3717,18 +4681,18 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.22.0.tgz", - "integrity": "sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.3.tgz", + "integrity": "sha512-uk574k8IU0rOF/AjniX8qbLSGURJVUCeM5e4MIMKBFFi8weeiLrG1fyQejyLXQpRZbU/1BuQasleV/RfHC3hHg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.46.3", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3787,39 +4751,377 @@ "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.48.1", - "@typescript-eslint/types": "8.48.1", - "@typescript-eslint/typescript-estree": "8.48.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.48.1", + "@typescript-eslint/types": "8.48.1", + "@typescript-eslint/typescript-estree": "8.48.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.48.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.48.1.tgz", + "integrity": "sha512-BmxxndzEWhE4TIEEMBs8lP3MBWN3jFPs/p6gPm/wkv02o41hI6cq9AuSmGAaTTHPtA1FTi2jBre4A9rm5ZmX+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.48.1", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "dev": true, + "license": "ISC" + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", + "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", + "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", + "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@vitest/expect": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "tinyspy": "^4.0.3" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <6.0.0" + "url": "https://opencollective.com/vitest" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.48.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.48.1.tgz", - "integrity": "sha512-BmxxndzEWhE4TIEEMBs8lP3MBWN3jFPs/p6gPm/wkv02o41hI6cq9AuSmGAaTTHPtA1FTi2jBre4A9rm5ZmX+Q==", + "node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { - "@typescript-eslint/types": "8.48.1", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" + "url": "https://opencollective.com/vitest" } }, "node_modules/acorn": { @@ -4123,6 +5425,31 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/ast-types": { + "version": "0.16.1", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.16.1.tgz", + "integrity": "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/ast-types-flow": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz", @@ -4174,9 +5501,9 @@ } }, "node_modules/aws-cdk": { - "version": "2.1030.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1030.0.tgz", - "integrity": "sha512-jYgOy1Hqx8cOTWW9On9xpypXLecjOqSZ4X2q5U0Gzd14xI+HLmpaRJV5ILJ8vYrLKVbqjhiog0pdxAC7vwF9uQ==", + "version": "2.1033.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1033.0.tgz", + "integrity": "sha512-Pit2k7cVAwxoYI7RMVsOyltuy7/HGENLupJ4KAm/d8mGzOfX+SLOo9YQsx5CKY9J6ErCZ1ViLerklTfjytvQww==", "dev": true, "license": "Apache-2.0", "bin": { @@ -4190,9 +5517,9 @@ } }, "node_modules/aws-cdk-lib": { - "version": "2.219.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.219.0.tgz", - "integrity": "sha512-Rq1/f3exfFEWee1znNq8yvR1TuRQ4xQZz3JNkliBW9dFwyrDe7l/dmlAf6DVvB3nuiZAaUS+vh4ua1LZ7Ec8kg==", + "version": "2.231.0", + "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.231.0.tgz", + "integrity": "sha512-RMt88F1vhsM28j81EjvIXRoPeYQdtk72EGh9xAP6LjuyF8df1hDBIy5cawUvagdp5eCBPVHrPJ2U0eaUUKtjFg==", "bundleDependencies": [ "@balena/dockerignore", "case", @@ -4595,85 +5922,58 @@ } }, "node_modules/babel-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", - "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz", + "integrity": "sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/transform": "^29.7.0", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.6.3", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", + "@jest/transform": "30.2.0", + "@types/babel__core": "^7.20.5", + "babel-plugin-istanbul": "^7.0.1", + "babel-preset-jest": "30.2.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", "slash": "^3.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { - "@babel/core": "^7.8.0" + "@babel/core": "^7.11.0 || ^8.0.0-0" } }, "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz", + "integrity": "sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==", "dev": true, "license": "BSD-3-Clause", + "workspaces": [ + "test/babel-8" + ], "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-instrument": "^6.0.2", "test-exclude": "^6.0.0" }, "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-istanbul/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "node": ">=12" } }, "node_modules/babel-plugin-jest-hoist": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", - "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.2.0.tgz", + "integrity": "sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" + "@types/babel__core": "^7.20.5" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/babel-preset-current-node-syntax": { @@ -4704,20 +6004,20 @@ } }, "node_modules/babel-preset-jest": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", - "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.2.0.tgz", + "integrity": "sha512-US4Z3NOieAQumwFnYdUWKvUKh8+YSnS/gB3t6YBiz0bskpu7Pine8pPCheNxlPEW4wnUkma2a94YuW2q3guvCQ==", "dev": true, "license": "MIT", "dependencies": { - "babel-plugin-jest-hoist": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0" + "babel-plugin-jest-hoist": "30.2.0", + "babel-preset-current-node-syntax": "^1.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.11.0 || ^8.0.0-beta.1" } }, "node_modules/balanced-match": { @@ -4939,6 +6239,24 @@ "cdl": "bin/cdl.js" } }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -4979,10 +6297,21 @@ "node": ">=10" } }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 16" + } + }, "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", + "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", "dev": true, "funding": [ { @@ -4996,9 +6325,9 @@ } }, "node_modules/cjs-module-lexer": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", - "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.1.1.tgz", + "integrity": "sha512-+CmxIZ/L2vNcEfvNtLdU0ZQ6mbq3FZnwAP2PPTiKP+1QOoKwlKlPgb8UKV0Dds7QVaMnHm+FwSft2VB0s/SLjQ==", "dev": true, "license": "MIT" }, @@ -5124,6 +6453,16 @@ "simple-swizzle": "^0.2.2" } }, + "node_modules/comment-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.0.0" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -5132,9 +6471,9 @@ "license": "MIT" }, "node_modules/constructs": { - "version": "10.4.2", - "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.4.2.tgz", - "integrity": "sha512-wsNxBlAott2qg8Zv87q3eYZYgheb9lchtBfjHzzLHtXbttwSrHPs1NNQbBrmbb1YZvYg2+Vh0Dor76w4mFxJkA==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.4.3.tgz", + "integrity": "sha512-3+ZB67qWGM1vEstNpj6pGaLNN1qz4gxC1CBhEUhZDZk0PqzQWY65IzC1Doq17MGPa9xa2wJ1G/DJ3swU8kWAHQ==", "dev": true, "license": "Apache-2.0" }, @@ -5145,28 +6484,6 @@ "dev": true, "license": "MIT" }, - "node_modules/create-jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", - "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "prompts": "^2.0.1" - }, - "bin": { - "create-jest": "bin/create-jest.js" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -5189,6 +6506,14 @@ "node": ">= 8" } }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/damerau-levenshtein": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", @@ -5296,6 +6621,17 @@ } } }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -5349,6 +6685,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -5369,16 +6716,6 @@ "node": ">=0.3.1" } }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -5393,18 +6730,26 @@ } }, "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, "engines": { - "node": ">=6.0.0" + "node": ">=0.10.0" } }, + "node_modules/dom-accessibility-api": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz", + "integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -5420,6 +6765,13 @@ "node": ">= 0.4" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, "node_modules/ejs": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", @@ -5463,20 +6815,6 @@ "dev": true, "license": "MIT" }, - "node_modules/enhanced-resolve": { - "version": "5.18.3", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", - "integrity": "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, "node_modules/error-ex": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", @@ -5664,6 +7002,49 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/esbuild": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.0.tgz", + "integrity": "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "peer": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.0", + "@esbuild/android-arm": "0.27.0", + "@esbuild/android-arm64": "0.27.0", + "@esbuild/android-x64": "0.27.0", + "@esbuild/darwin-arm64": "0.27.0", + "@esbuild/darwin-x64": "0.27.0", + "@esbuild/freebsd-arm64": "0.27.0", + "@esbuild/freebsd-x64": "0.27.0", + "@esbuild/linux-arm": "0.27.0", + "@esbuild/linux-arm64": "0.27.0", + "@esbuild/linux-ia32": "0.27.0", + "@esbuild/linux-loong64": "0.27.0", + "@esbuild/linux-mips64el": "0.27.0", + "@esbuild/linux-ppc64": "0.27.0", + "@esbuild/linux-riscv64": "0.27.0", + "@esbuild/linux-s390x": "0.27.0", + "@esbuild/linux-x64": "0.27.0", + "@esbuild/netbsd-arm64": "0.27.0", + "@esbuild/netbsd-x64": "0.27.0", + "@esbuild/openbsd-arm64": "0.27.0", + "@esbuild/openbsd-x64": "0.27.0", + "@esbuild/openharmony-arm64": "0.27.0", + "@esbuild/sunos-x64": "0.27.0", + "@esbuild/win32-arm64": "0.27.0", + "@esbuild/win32-ia32": "0.27.0", + "@esbuild/win32-x64": "0.27.0" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -5748,61 +7129,66 @@ } }, "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "version": "10.1.8", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz", + "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "dev": true, "license": "MIT", "bin": { "eslint-config-prettier": "bin/cli.js" }, + "funding": { + "url": "https://opencollective.com/eslint-config-prettier" + }, "peerDependencies": { "eslint": ">=7.0.0" } }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "node_modules/eslint-import-context": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", + "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", "dev": true, "license": "MIT", "dependencies": { - "ms": "^2.1.1" + "get-tsconfig": "^4.10.1", + "stable-hash-x": "^0.2.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-context" + }, + "peerDependencies": { + "unrs-resolver": "^1.0.0" + }, + "peerDependenciesMeta": { + "unrs-resolver": { + "optional": true + } } }, "node_modules/eslint-import-resolver-typescript": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.7.0.tgz", - "integrity": "sha512-Vrwyi8HHxY97K5ebydMtffsWAn1SCR9eol49eCd5fJS4O1WV7PaAjbcjmbfJJSMz/t4Mal212Uz/fQZrOB8mow==", + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-4.4.4.tgz", + "integrity": "sha512-1iM2zeBvrYmUNTj2vSC/90JTHDth+dfOfiNKkxApWRsTJYNrc8rOdxxIf5vazX+BiAXTeOT0UvWpGI/7qIWQOw==", "dev": true, "license": "ISC", "dependencies": { - "@nolyfill/is-core-module": "1.0.39", - "debug": "^4.3.7", - "enhanced-resolve": "^5.15.0", - "fast-glob": "^3.3.2", - "get-tsconfig": "^4.7.5", - "is-bun-module": "^1.0.2", - "is-glob": "^4.0.3", - "stable-hash": "^0.0.4" + "debug": "^4.4.1", + "eslint-import-context": "^0.1.8", + "get-tsconfig": "^4.10.1", + "is-bun-module": "^2.0.0", + "stable-hash-x": "^0.2.0", + "tinyglobby": "^0.2.14", + "unrs-resolver": "^1.7.11" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^16.17.0 || >=18.6.0" }, "funding": { - "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + "url": "https://opencollective.com/eslint-import-resolver-typescript" }, "peerDependencies": { "eslint": "*", @@ -5819,31 +7205,40 @@ } }, "node_modules/eslint-plugin-import-x": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.6.1.tgz", - "integrity": "sha512-wluSUifMIb7UfwWXqx7Yx0lE/SGCcGXECLx/9bCmbY2nneLwvAZ4vkd1IXDjPKFvdcdUgr1BaRnaRpx3k2+Pfw==", + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import-x/-/eslint-plugin-import-x-4.16.1.tgz", + "integrity": "sha512-vPZZsiOKaBAIATpFE2uMI4w5IRwdv/FpQ+qZZMR4E+PeOcM4OeoEbqxRMnywdxP19TyB/3h6QBB0EWon7letSQ==", "dev": true, "license": "MIT", "dependencies": { - "@types/doctrine": "^0.0.9", - "@typescript-eslint/scope-manager": "^8.1.0", - "@typescript-eslint/utils": "^8.1.0", - "debug": "^4.3.4", - "doctrine": "^3.0.0", - "enhanced-resolve": "^5.17.1", - "eslint-import-resolver-node": "^0.3.9", - "get-tsconfig": "^4.7.3", + "@typescript-eslint/types": "^8.35.0", + "comment-parser": "^1.4.1", + "debug": "^4.4.1", + "eslint-import-context": "^0.1.9", "is-glob": "^4.0.3", - "minimatch": "^9.0.3", - "semver": "^7.6.3", - "stable-hash": "^0.0.4", - "tslib": "^2.6.3" + "minimatch": "^9.0.3 || ^10.0.1", + "semver": "^7.7.2", + "stable-hash-x": "^0.2.0", + "unrs-resolver": "^1.9.2" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, + "funding": { + "url": "https://opencollective.com/eslint-plugin-import-x" + }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" + "@typescript-eslint/utils": "^8.0.0", + "eslint": "^8.57.0 || ^9.0.0", + "eslint-import-resolver-node": "*" + }, + "peerDependenciesMeta": { + "@typescript-eslint/utils": { + "optional": true + }, + "eslint-import-resolver-node": { + "optional": true + } } }, "node_modules/eslint-plugin-jsx-a11y": { @@ -5901,29 +7296,29 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.37.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.2.tgz", - "integrity": "sha512-EsTAnj9fLVr/GZleBLFbj/sSuXeWmp1eXIN60ceYnZveqEaUCyW4X+Vh4WTdUhCkW4xutXYqTXCUSyqD4rB75w==", + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", "dev": true, "license": "MIT", "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", - "array.prototype.flatmap": "^1.3.2", + "array.prototype.flatmap": "^1.3.3", "array.prototype.tosorted": "^1.1.4", "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.1.0", + "es-iterator-helpers": "^1.2.1", "estraverse": "^5.3.0", "hasown": "^2.0.2", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.8", + "object.entries": "^1.1.9", "object.fromentries": "^2.0.8", - "object.values": "^1.2.0", + "object.values": "^1.2.1", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.11", + "string.prototype.matchall": "^4.0.12", "string.prototype.repeat": "^1.0.0" }, "engines": { @@ -5934,13 +7329,20 @@ } }, "node_modules/eslint-plugin-react-hooks": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0.tgz", - "integrity": "sha512-mpJRtPgHN2tNAvZ35AMfqeB3Xqeo273QxrHJsbBEPWODRM4r0yB6jfoROqKEYrOn27UtRPpcpHc2UqyBSuUNTw==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.1.tgz", + "integrity": "sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/core": "^7.24.4", + "@babel/parser": "^7.24.4", + "hermes-parser": "^0.25.1", + "zod": "^3.25.0 || ^4.0.0", + "zod-validation-error": "^3.5.0 || ^4.0.0" + }, "engines": { - "node": ">=10" + "node": ">=18" }, "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" @@ -5957,19 +7359,6 @@ "concat-map": "0.0.1" } }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/eslint-plugin-react/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -6012,21 +7401,17 @@ } }, "node_modules/eslint-plugin-storybook": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-0.11.1.tgz", - "integrity": "sha512-yGKpAYkBm/Q2hZg476vRUAvd9lAccjjSvzU5nYy3BSQbKTPy7uopx7JEpwk2vSuw4weTMZzWF64z9/gp/K5RCg==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-10.0.6.tgz", + "integrity": "sha512-llPShAqO86PgjswUDXwkxq1hGBjM7NiZE+nScbTjM3NVx0XwqbSZ+FRV2p5nv6vrZeREfhhY/KJF2WuSaYkXiQ==", "dev": true, "license": "MIT", "dependencies": { - "@storybook/csf": "^0.1.11", - "@typescript-eslint/utils": "^8.8.1", - "ts-dedent": "^2.2.0" - }, - "engines": { - "node": ">= 18" + "@typescript-eslint/utils": "^8.8.1" }, "peerDependencies": { - "eslint": ">=6" + "eslint": ">=8", + "storybook": "^10.0.6" } }, "node_modules/eslint-scope": { @@ -6059,19 +7444,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/@eslint/js": { - "version": "9.39.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", - "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - } - }, "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.12", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", @@ -6198,30 +7570,32 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", + "node_modules/exit-x": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz", + "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==", "dev": true, + "license": "MIT", "engines": { "node": ">= 0.8.0" } }, "node_modules/expect": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", - "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz", + "integrity": "sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/expect-utils": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0" + "@jest/expect-utils": "30.2.0", + "@jest/get-type": "30.1.0", + "jest-matcher-utils": "30.2.0", + "jest-message-util": "30.2.0", + "jest-mock": "30.2.0", + "jest-util": "30.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/fast-deep-equal": { @@ -6448,6 +7822,36 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/fs-extra": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", @@ -6670,23 +8074,22 @@ "git-up": "^8.1.0" } }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" }, - "engines": { - "node": "*" + "bin": { + "glob": "dist/esm/bin.mjs" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -6705,34 +8108,10 @@ "node": ">=10.13.0" } }, - "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/globals": { - "version": "15.14.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-15.14.0.tgz", - "integrity": "sha512-OkToC372DtlQeje9/zHIo5CT8lRP/FUgEOKBEhU4e0abL7J7CD24fD9ohiLN5hagG/kWCYj4K5oaxxtj2Z0Dig==", + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz", + "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==", "dev": true, "license": "MIT", "engines": { @@ -6923,25 +8302,45 @@ "node": ">= 0.4" } }, + "node_modules/hermes-estree": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", + "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==", + "dev": true, + "license": "MIT" + }, + "node_modules/hermes-parser": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz", + "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hermes-estree": "0.25.1" + } + }, "node_modules/hosted-git-info": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", - "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", + "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", "dev": true, "license": "ISC", "dependencies": { - "lru-cache": "^10.0.1" + "lru-cache": "^11.1.0" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/hosted-git-info/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", "dev": true, - "license": "ISC" + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } }, "node_modules/html-escaper": { "version": "2.0.2", @@ -7163,13 +8562,13 @@ } }, "node_modules/is-bun-module": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.3.0.tgz", - "integrity": "sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-2.0.0.tgz", + "integrity": "sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==", "dev": true, "license": "MIT", "dependencies": { - "semver": "^7.6.3" + "semver": "^7.7.1" } }, "node_modules/is-callable": { @@ -7635,15 +9034,15 @@ } }, "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", + "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", "dev": true, "license": "BSD-3-Clause", "dependencies": { + "@jridgewell/trace-mapping": "^0.3.23", "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" + "istanbul-lib-coverage": "^3.0.0" }, "engines": { "node": ">=10" @@ -7681,6 +9080,22 @@ "node": ">= 0.4" } }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/jake": { "version": "10.9.4", "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", @@ -7700,22 +9115,22 @@ } }, "node_modules/jest": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", - "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-30.2.0.tgz", + "integrity": "sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==", "dev": true, "license": "MIT", "dependencies": { - "@jest/core": "^29.7.0", - "@jest/types": "^29.6.3", - "import-local": "^3.0.2", - "jest-cli": "^29.7.0" + "@jest/core": "30.2.0", + "@jest/types": "30.2.0", + "import-local": "^3.2.0", + "jest-cli": "30.2.0" }, "bin": { "jest": "bin/jest.js" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -7727,76 +9142,75 @@ } }, "node_modules/jest-changed-files": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", - "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.2.0.tgz", + "integrity": "sha512-L8lR1ChrRnSdfeOvTrwZMlnWV8G/LLjQ0nG9MBclwWZidA2N5FviRki0Bvh20WRMOX31/JYvzdqTJrk5oBdydQ==", "dev": true, "license": "MIT", "dependencies": { - "execa": "^5.0.0", - "jest-util": "^29.7.0", + "execa": "^5.1.1", + "jest-util": "30.2.0", "p-limit": "^3.1.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-circus": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", - "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.2.0.tgz", + "integrity": "sha512-Fh0096NC3ZkFx05EP2OXCxJAREVxj1BcW/i6EWqqymcgYKWjyyDpral3fMxVcHXg6oZM7iULer9wGRFvfpl+Tg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/expect": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/environment": "30.2.0", + "@jest/expect": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/types": "30.2.0", "@types/node": "*", - "chalk": "^4.0.0", + "chalk": "^4.1.2", "co": "^4.6.0", - "dedent": "^1.0.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.7.0", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", + "dedent": "^1.6.0", + "is-generator-fn": "^2.1.0", + "jest-each": "30.2.0", + "jest-matcher-utils": "30.2.0", + "jest-message-util": "30.2.0", + "jest-runtime": "30.2.0", + "jest-snapshot": "30.2.0", + "jest-util": "30.2.0", "p-limit": "^3.1.0", - "pretty-format": "^29.7.0", - "pure-rand": "^6.0.0", + "pretty-format": "30.2.0", + "pure-rand": "^7.0.0", "slash": "^3.0.0", - "stack-utils": "^2.0.3" + "stack-utils": "^2.0.6" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-cli": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", - "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.2.0.tgz", + "integrity": "sha512-Os9ukIvADX/A9sLt6Zse3+nmHtHaE6hqOsjQtNiugFTbKRHYIYtZXNGNK9NChseXy7djFPjndX1tL0sCTlfpAA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/core": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "create-jest": "^29.7.0", - "exit": "^0.1.2", - "import-local": "^3.0.2", - "jest-config": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "yargs": "^17.3.1" + "@jest/core": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/types": "30.2.0", + "chalk": "^4.1.2", + "exit-x": "^0.2.2", + "import-local": "^3.2.0", + "jest-config": "30.2.0", + "jest-util": "30.2.0", + "jest-validate": "30.2.0", + "yargs": "^17.7.2" }, "bin": { "jest": "bin/jest.js" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" @@ -7808,215 +9222,226 @@ } }, "node_modules/jest-config": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", - "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.2.0.tgz", + "integrity": "sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-jest": "^29.7.0", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-circus": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-runner": "^29.7.0", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "micromatch": "^4.0.4", + "@babel/core": "^7.27.4", + "@jest/get-type": "30.1.0", + "@jest/pattern": "30.0.1", + "@jest/test-sequencer": "30.2.0", + "@jest/types": "30.2.0", + "babel-jest": "30.2.0", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "deepmerge": "^4.3.1", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "jest-circus": "30.2.0", + "jest-docblock": "30.2.0", + "jest-environment-node": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.2.0", + "jest-runner": "30.2.0", + "jest-util": "30.2.0", + "jest-validate": "30.2.0", + "micromatch": "^4.0.8", "parse-json": "^5.2.0", - "pretty-format": "^29.7.0", + "pretty-format": "30.2.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "peerDependencies": { "@types/node": "*", + "esbuild-register": ">=3.4.0", "ts-node": ">=9.0.0" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, + "esbuild-register": { + "optional": true + }, "ts-node": { "optional": true } } }, "node_modules/jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.2.0.tgz", + "integrity": "sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" + "@jest/diff-sequences": "30.0.1", + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "pretty-format": "30.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-docblock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", - "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.2.0.tgz", + "integrity": "sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==", "dev": true, "license": "MIT", "dependencies": { - "detect-newline": "^3.0.0" + "detect-newline": "^3.1.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-each": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", - "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.2.0.tgz", + "integrity": "sha512-lpWlJlM7bCUf1mfmuqTA8+j2lNURW9eNafOy99knBM01i5CQeY5UH1vZjgT9071nDJac1M4XsbyI44oNOdhlDQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", - "jest-util": "^29.7.0", - "pretty-format": "^29.7.0" + "@jest/get-type": "30.1.0", + "@jest/types": "30.2.0", + "chalk": "^4.1.2", + "jest-util": "30.2.0", + "pretty-format": "30.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-environment-node": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", - "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.2.0.tgz", + "integrity": "sha512-ElU8v92QJ9UrYsKrxDIKCxu6PfNj4Hdcktcn0JX12zqNdqWHB0N+hwOnnBBXvjLd2vApZtuLUGs1QSY+MsXoNA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/environment": "30.2.0", + "@jest/fake-timers": "30.2.0", + "@jest/types": "30.2.0", "@types/node": "*", - "jest-mock": "^29.7.0", - "jest-util": "^29.7.0" + "jest-mock": "30.2.0", + "jest-util": "30.2.0", + "jest-validate": "30.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-haste-map": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", - "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.2.0.tgz", + "integrity": "sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "@types/graceful-fs": "^4.1.3", + "@jest/types": "30.2.0", "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.6.3", - "jest-util": "^29.7.0", - "jest-worker": "^29.7.0", - "micromatch": "^4.0.4", + "anymatch": "^3.1.3", + "fb-watchman": "^2.0.2", + "graceful-fs": "^4.2.11", + "jest-regex-util": "30.0.1", + "jest-util": "30.2.0", + "jest-worker": "30.2.0", + "micromatch": "^4.0.8", "walker": "^1.0.8" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" }, "optionalDependencies": { - "fsevents": "^2.3.2" + "fsevents": "^2.3.3" + } + }, + "node_modules/jest-haste-map/node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, "node_modules/jest-leak-detector": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", - "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.2.0.tgz", + "integrity": "sha512-M6jKAjyzjHG0SrQgwhgZGy9hFazcudwCNovY/9HPIicmNSBuockPSedAP9vlPK6ONFJ1zfyH/M2/YYJxOz5cdQ==", "dev": true, "license": "MIT", "dependencies": { - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" + "@jest/get-type": "30.1.0", + "pretty-format": "30.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", - "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.2.0.tgz", + "integrity": "sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" + "@jest/get-type": "30.1.0", + "chalk": "^4.1.2", + "jest-diff": "30.2.0", + "pretty-format": "30.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-message-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", - "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.2.0.tgz", + "integrity": "sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.6.3", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.7.0", + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.2.0", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "micromatch": "^4.0.8", + "pretty-format": "30.2.0", "slash": "^3.0.0", - "stack-utils": "^2.0.3" + "stack-utils": "^2.0.6" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-mock": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", - "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.2.0.tgz", + "integrity": "sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", + "@jest/types": "30.2.0", "@types/node": "*", - "jest-util": "^29.7.0" + "jest-util": "30.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-pnp-resolver": { @@ -8038,81 +9463,81 @@ } }, "node_modules/jest-regex-util": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", - "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz", + "integrity": "sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==", "dev": true, "license": "MIT", "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-resolve": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", - "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.2.0.tgz", + "integrity": "sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.7.0", - "jest-validate": "^29.7.0", - "resolve": "^1.20.0", - "resolve.exports": "^2.0.0", - "slash": "^3.0.0" + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "jest-pnp-resolver": "^1.2.3", + "jest-util": "30.2.0", + "jest-validate": "30.2.0", + "slash": "^3.0.0", + "unrs-resolver": "^1.7.11" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-resolve-dependencies": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", - "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.2.0.tgz", + "integrity": "sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w==", "dev": true, "license": "MIT", "dependencies": { - "jest-regex-util": "^29.6.3", - "jest-snapshot": "^29.7.0" + "jest-regex-util": "30.0.1", + "jest-snapshot": "30.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-runner": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", - "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.2.0.tgz", + "integrity": "sha512-PqvZ2B2XEyPEbclp+gV6KO/F1FIFSbIwewRgmROCMBo/aZ6J1w8Qypoj2pEOcg3G2HzLlaP6VUtvwCI8dM3oqQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "^29.7.0", - "@jest/environment": "^29.7.0", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/console": "30.2.0", + "@jest/environment": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", "@types/node": "*", - "chalk": "^4.0.0", + "chalk": "^4.1.2", "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.7.0", - "jest-environment-node": "^29.7.0", - "jest-haste-map": "^29.7.0", - "jest-leak-detector": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-resolve": "^29.7.0", - "jest-runtime": "^29.7.0", - "jest-util": "^29.7.0", - "jest-watcher": "^29.7.0", - "jest-worker": "^29.7.0", + "exit-x": "^0.2.2", + "graceful-fs": "^4.2.11", + "jest-docblock": "30.2.0", + "jest-environment-node": "30.2.0", + "jest-haste-map": "30.2.0", + "jest-leak-detector": "30.2.0", + "jest-message-util": "30.2.0", + "jest-resolve": "30.2.0", + "jest-runtime": "30.2.0", + "jest-util": "30.2.0", + "jest-watcher": "30.2.0", + "jest-worker": "30.2.0", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-runner/node_modules/source-map-support": { @@ -8127,154 +9552,143 @@ } }, "node_modules/jest-runtime": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", - "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.2.0.tgz", + "integrity": "sha512-p1+GVX/PJqTucvsmERPMgCPvQJpFt4hFbM+VN3n8TMo47decMUcJbt+rgzwrEme0MQUA/R+1de2axftTHkKckg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "^29.7.0", - "@jest/fake-timers": "^29.7.0", - "@jest/globals": "^29.7.0", - "@jest/source-map": "^29.6.3", - "@jest/test-result": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/environment": "30.2.0", + "@jest/fake-timers": "30.2.0", + "@jest/globals": "30.2.0", + "@jest/source-map": "30.0.1", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", "@types/node": "*", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-mock": "^29.7.0", - "jest-regex-util": "^29.6.3", - "jest-resolve": "^29.7.0", - "jest-snapshot": "^29.7.0", - "jest-util": "^29.7.0", + "chalk": "^4.1.2", + "cjs-module-lexer": "^2.1.0", + "collect-v8-coverage": "^1.0.2", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "jest-message-util": "30.2.0", + "jest-mock": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-resolve": "30.2.0", + "jest-snapshot": "30.2.0", + "jest-util": "30.2.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-snapshot": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", - "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.7.0", - "@jest/transform": "^29.7.0", - "@jest/types": "^29.6.3", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^29.7.0", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.7.0", - "jest-get-type": "^29.6.3", - "jest-matcher-utils": "^29.7.0", - "jest-message-util": "^29.7.0", - "jest-util": "^29.7.0", - "natural-compare": "^1.4.0", - "pretty-format": "^29.7.0", - "semver": "^7.5.3" + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.2.0.tgz", + "integrity": "sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@babel/generator": "^7.27.5", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1", + "@babel/types": "^7.27.3", + "@jest/expect-utils": "30.2.0", + "@jest/get-type": "30.1.0", + "@jest/snapshot-utils": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "babel-preset-current-node-syntax": "^1.2.0", + "chalk": "^4.1.2", + "expect": "30.2.0", + "graceful-fs": "^4.2.11", + "jest-diff": "30.2.0", + "jest-matcher-utils": "30.2.0", + "jest-message-util": "30.2.0", + "jest-util": "30.2.0", + "pretty-format": "30.2.0", + "semver": "^7.7.2", + "synckit": "^0.11.8" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-util": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", - "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", + "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", + "@jest/types": "30.2.0", "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-util/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-validate": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", - "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.2.0.tgz", + "integrity": "sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "^29.6.3", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.6.3", + "@jest/get-type": "30.1.0", + "@jest/types": "30.2.0", + "camelcase": "^6.3.0", + "chalk": "^4.1.2", "leven": "^3.1.0", - "pretty-format": "^29.7.0" + "pretty-format": "30.2.0" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-watcher": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", - "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.2.0.tgz", + "integrity": "sha512-PYxa28dxJ9g777pGm/7PrbnMeA0Jr7osHP9bS7eJy9DuAjMgdGtxgf0uKMyoIsTWAkIbUW5hSDdJ3urmgXBqxg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/test-result": "^29.7.0", - "@jest/types": "^29.6.3", + "@jest/test-result": "30.2.0", + "@jest/types": "30.2.0", "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", + "ansi-escapes": "^4.3.2", + "chalk": "^4.1.2", "emittery": "^0.13.1", - "jest-util": "^29.7.0", - "string-length": "^4.0.1" + "jest-util": "30.2.0", + "string-length": "^4.0.2" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/jest-worker": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", - "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.2.0.tgz", + "integrity": "sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==", "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", - "jest-util": "^29.7.0", + "@ungap/structured-clone": "^1.3.0", + "jest-util": "30.2.0", "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" + "supports-color": "^8.1.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/js-tokens": { @@ -8390,16 +9804,6 @@ "json-buffer": "3.0.1" } }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/language-subtag-registry": { "version": "0.3.23", "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", @@ -8494,6 +9898,14 @@ "loose-envify": "cli.js" } }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -8504,6 +9916,17 @@ "yallist": "^3.0.2" } }, + "node_modules/lz-string": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz", + "integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, "node_modules/make-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", @@ -8601,6 +10024,17 @@ "node": ">=6" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=4" + } + }, "node_modules/minimatch": { "version": "9.0.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", @@ -8627,6 +10061,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -8634,6 +10078,22 @@ "dev": true, "license": "MIT" }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -8673,18 +10133,18 @@ "license": "MIT" }, "node_modules/normalize-package-data": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", - "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-8.0.0.tgz", + "integrity": "sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==", "dev": true, "license": "BSD-2-Clause", "dependencies": { - "hosted-git-info": "^7.0.0", + "hosted-git-info": "^9.0.0", "semver": "^7.3.5", "validate-npm-package-license": "^3.0.4" }, "engines": { - "node": "^16.14.0 || >=18.0.0" + "node": "^20.17.0 || >=22.9.0" } }, "node_modules/normalize-path": { @@ -8932,6 +10392,13 @@ "node": ">=6" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -9036,6 +10503,30 @@ "dev": true, "license": "MIT" }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -9046,6 +10537,17 @@ "node": ">=8" } }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 14.16" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -9182,18 +10684,18 @@ } }, "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", + "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, "node_modules/pretty-format/node_modules/ansi-styles": { @@ -9209,20 +10711,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -9260,9 +10748,9 @@ } }, "node_modules/pure-rand": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", - "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", + "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", "dev": true, "funding": [ { @@ -9297,6 +10785,31 @@ ], "license": "MIT" }, + "node_modules/react": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", + "integrity": "sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.0.tgz", + "integrity": "sha512-UlbRu4cAiGaIewkPyiRGJk0imDN2T3JjieT6spoL2UeSf5od4n5LB/mQ4ejmxhCFT1tYe8IvaFulzynWovsEFQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "scheduler": "^0.27.0" + }, + "peerDependencies": { + "react": "^19.2.0" + } + }, "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", @@ -9305,51 +10818,54 @@ "license": "MIT" }, "node_modules/read-package-up": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-11.0.0.tgz", - "integrity": "sha512-MbgfoNPANMdb4oRBNg5eqLbB2t2r+o5Ua1pNt8BqGp4I0FJZhuVSOj3PaBPni4azWuSzEdNn2evevzVmEk1ohQ==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/read-package-up/-/read-package-up-12.0.0.tgz", + "integrity": "sha512-Q5hMVBYur/eQNWDdbF4/Wqqr9Bjvtrw2kjGxxBbKLbx8bVCL8gcArjTy8zDUuLGQicftpMuU0riQNcAsbtOVsw==", "dev": true, "license": "MIT", "dependencies": { - "find-up-simple": "^1.0.0", - "read-pkg": "^9.0.0", - "type-fest": "^4.6.0" + "find-up-simple": "^1.0.1", + "read-pkg": "^10.0.0", + "type-fest": "^5.2.0" }, "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/read-package-up/node_modules/type-fest": { - "version": "4.41.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", - "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.3.0.tgz", + "integrity": "sha512-d9CwU93nN0IA1QL+GSNDdwLAu1Ew5ZjTwupvedwg3WdfoH6pIDvYQ2hV0Uc2nKBLPq7NB5apCx57MLS5qlmO5g==", "dev": true, "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, "engines": { - "node": ">=16" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/read-pkg": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz", - "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-10.0.0.tgz", + "integrity": "sha512-A70UlgfNdKI5NSvTTfHzLQj7NJRpJ4mT5tGafkllJ4wh71oYuGm/pzphHcmW4s35iox56KSK721AihodoXSc/A==", "dev": true, "license": "MIT", "dependencies": { - "@types/normalize-package-data": "^2.4.3", - "normalize-package-data": "^6.0.0", - "parse-json": "^8.0.0", - "type-fest": "^4.6.0", - "unicorn-magic": "^0.1.0" + "@types/normalize-package-data": "^2.4.4", + "normalize-package-data": "^8.0.0", + "parse-json": "^8.3.0", + "type-fest": "^5.2.0", + "unicorn-magic": "^0.3.0" }, "engines": { - "node": ">=18" + "node": ">=20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -9513,17 +11029,66 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg/node_modules/type-fest": { + "node_modules/read-pkg/node_modules/parse-json/node_modules/type-fest": { "version": "4.41.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=16" + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.3.0.tgz", + "integrity": "sha512-d9CwU93nN0IA1QL+GSNDdwLAu1Ew5ZjTwupvedwg3WdfoH6pIDvYQ2hV0Uc2nKBLPq7NB5apCx57MLS5qlmO5g==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/recast": { + "version": "0.23.11", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.23.11.tgz", + "integrity": "sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ast-types": "^0.16.1", + "esprima": "~4.0.0", + "source-map": "~0.6.1", + "tiny-invariant": "^1.3.3", + "tslib": "^2.0.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=8" } }, "node_modules/redeyed": { @@ -9654,16 +11219,6 @@ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" } }, - "node_modules/resolve.exports": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", - "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -9754,6 +11309,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/scheduler": { + "version": "0.27.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.27.0.tgz", + "integrity": "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/semver": { "version": "7.7.3", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", @@ -9939,13 +11502,6 @@ "dev": true, "license": "MIT" }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true, - "license": "MIT" - }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -10038,12 +11594,15 @@ "dev": true, "license": "BSD-3-Clause" }, - "node_modules/stable-hash": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.4.tgz", - "integrity": "sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==", + "node_modules/stable-hash-x": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", + "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } }, "node_modules/stack-utils": { "version": "2.0.6", @@ -10082,6 +11641,42 @@ "node": ">= 0.4" } }, + "node_modules/storybook": { + "version": "10.1.4", + "resolved": "https://registry.npmjs.org/storybook/-/storybook-10.1.4.tgz", + "integrity": "sha512-FrBjm8I8O+pYEOPHcdW9xWwgXSZxte7lza9q2lN3jFN4vuW79m5j0OnTQeR8z9MmIbBTvkIpp3yMBebl53Yt5Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@storybook/global": "^5.0.0", + "@storybook/icons": "^2.0.0", + "@testing-library/jest-dom": "^6.6.3", + "@testing-library/user-event": "^14.6.1", + "@vitest/expect": "3.2.4", + "@vitest/spy": "3.2.4", + "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0", + "recast": "^0.23.5", + "semver": "^7.6.2", + "use-sync-external-store": "^1.5.0", + "ws": "^8.18.0" + }, + "bin": { + "storybook": "dist/bin/dispatcher.js" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/storybook" + }, + "peerDependencies": { + "prettier": "^2 || ^3" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + } + } + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -10111,6 +11706,29 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, "node_modules/string-width/node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -10244,6 +11862,20 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -10264,6 +11896,20 @@ "node": ">=6" } }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -10346,18 +11992,33 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tapable": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", - "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", + "node_modules/synckit": { + "version": "0.11.11", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz", + "integrity": "sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==", "dev": true, "license": "MIT", + "dependencies": { + "@pkgr/core": "^0.2.9" + }, "engines": { - "node": ">=6" + "node": "^14.18.0 || >=16.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "url": "https://opencollective.com/synckit" + } + }, + "node_modules/tagged-tag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", + "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/test-exclude": { @@ -10386,6 +12047,28 @@ "concat-map": "0.0.1" } }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/test-exclude/node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -10399,6 +12082,14 @@ "node": "*" } }, + "node_modules/tiny-invariant": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.3.tgz", + "integrity": "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/tinyglobby": { "version": "0.2.15", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", @@ -10416,6 +12107,28 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -10449,16 +12162,6 @@ "typescript": ">=4.8.4" } }, - "node_modules/ts-dedent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz", - "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.10" - } - }, "node_modules/ts-jest": { "version": "29.4.6", "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.6.tgz", @@ -10691,9 +12394,9 @@ } }, "node_modules/typescript": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz", - "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -10705,15 +12408,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.22.0.tgz", - "integrity": "sha512-Y2rj210FW1Wb6TWXzQc5+P+EWI9/zdS57hLEc0gnyuvdzWo8+Y8brKlbj0muejonhMI/xAZCnZZwjbIfv1CkOw==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.46.3.tgz", + "integrity": "sha512-bAfgMavTuGo+8n6/QQDVQz4tZ4f7Soqg53RbrlZQEoAltYop/XR4RAts/I0BrO3TTClTSTFJ0wYbla+P8cEWJA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.22.0", - "@typescript-eslint/parser": "8.22.0", - "@typescript-eslint/utils": "8.22.0" + "@typescript-eslint/eslint-plugin": "8.46.3", + "@typescript-eslint/parser": "8.46.3", + "@typescript-eslint/typescript-estree": "8.46.3", + "@typescript-eslint/utils": "8.46.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10724,18 +12428,40 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/project-service": { + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.46.3.tgz", + "integrity": "sha512-Fz8yFXsp2wDFeUElO88S9n4w1I4CWDTXDqDr9gYvZgUpwXQqmZBr9+NTTql5R3J7+hrJZPdpiWaB9VNhAKYLuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.46.3", + "@typescript-eslint/types": "^8.46.3", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.22.0.tgz", - "integrity": "sha512-/lwVV0UYgkj7wPSw0o8URy6YI64QmcOdwHuGuxWIYznO6d45ER0wXUbksr9pYdViAofpUCNJx/tAzNukgvaaiQ==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.46.3.tgz", + "integrity": "sha512-FCi7Y1zgrmxp3DfWfr+3m9ansUUFoy8dkEdeQSgA9gbm8DaHYvZCdkFRQrtKiedFf3Ha6VmoqoAaP68+i+22kg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0" + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/visitor-keys": "8.46.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10745,10 +12471,27 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.46.3.tgz", + "integrity": "sha512-GLupljMniHNIROP0zE7nCcybptolcH8QZfXOpCfhQDAdwJ/ZTlcaBOYebSOZotpti/3HrHSw7D3PZm75gYFsOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.22.0.tgz", - "integrity": "sha512-0S4M4baNzp612zwpD4YOieP3VowOARgK2EkN/GBn95hpyF8E2fbMT55sRHWBq+Huaqk3b3XK+rxxlM8sPgGM6A==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.46.3.tgz", + "integrity": "sha512-G7Ok9WN/ggW7e/tOf8TQYMaxgID3Iujn231hfi0Pc7ZheztIJVpO44ekY00b7akqc6nZcvregk0Jpah3kep6hA==", "dev": true, "license": "MIT", "engines": { @@ -10760,20 +12503,22 @@ } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.22.0.tgz", - "integrity": "sha512-SJX99NAS2ugGOzpyhMza/tX+zDwjvwAtQFLsBo3GQxiGcvaKlqGBkmZ+Y1IdiSi9h4Q0Lr5ey+Cp9CGWNY/F/w==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.46.3.tgz", + "integrity": "sha512-f/NvtRjOm80BtNM5OQtlaBdM5BRFUv7gf381j9wygDNL+qOYSNOgtQ/DCndiYi80iIOv76QqaTmp4fa9hwI0OA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/visitor-keys": "8.22.0", + "@typescript-eslint/project-service": "8.46.3", + "@typescript-eslint/tsconfig-utils": "8.46.3", + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/visitor-keys": "8.46.3", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", - "ts-api-utils": "^2.0.0" + "ts-api-utils": "^2.1.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10783,20 +12528,20 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.22.0.tgz", - "integrity": "sha512-T8oc1MbF8L+Bk2msAvCUzjxVB2Z2f+vXYfcucE2wOmYs7ZUwco5Ep0fYZw8quNwOiw9K8GYVL+Kgc2pETNTLOg==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.46.3.tgz", + "integrity": "sha512-VXw7qmdkucEx9WkmR3ld/u6VhRyKeiF1uxWwCy/iuNfokjJ7VhsgLSOTjsol8BunSw190zABzpwdNsze2Kpo4g==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.22.0", - "@typescript-eslint/types": "8.22.0", - "@typescript-eslint/typescript-estree": "8.22.0" + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.46.3", + "@typescript-eslint/types": "8.46.3", + "@typescript-eslint/typescript-estree": "8.46.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10807,18 +12552,18 @@ }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.8.0" + "typescript": ">=4.8.4 <6.0.0" } }, "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.22.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.22.0.tgz", - "integrity": "sha512-AWpYAXnUgvLNabGTy3uBylkgZoosva/miNd1I8Bz3SjotmQPbVqhO4Cczo8AsZ44XVErEBPr/CRSgaj8sG7g0w==", + "version": "8.46.3", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.46.3.tgz", + "integrity": "sha512-uk574k8IU0rOF/AjniX8qbLSGURJVUCeM5e4MIMKBFFi8weeiLrG1fyQejyLXQpRZbU/1BuQasleV/RfHC3hHg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.22.0", - "eslint-visitor-keys": "^4.2.0" + "@typescript-eslint/types": "8.46.3", + "eslint-visitor-keys": "^4.2.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10862,16 +12607,16 @@ } }, "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", "dev": true, "license": "MIT" }, "node_modules/unicorn-magic": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz", - "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", "dev": true, "license": "MIT", "engines": { @@ -10891,6 +12636,41 @@ "node": ">= 10.0.0" } }, + "node_modules/unrs-resolver": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.11.1.tgz", + "integrity": "sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.1", + "@unrs/resolver-binding-android-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-x64": "1.11.1", + "@unrs/resolver-binding-freebsd-x64": "1.11.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-musl": "1.11.1", + "@unrs/resolver-binding-wasm32-wasi": "1.11.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + } + }, "node_modules/update-browserslist-db": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", @@ -10932,6 +12712,17 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "dev": true, + "license": "MIT", + "peer": true, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -11128,6 +12919,25 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -11136,17 +12946,53 @@ "license": "ISC" }, "node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", "dev": true, "license": "ISC", "dependencies": { "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/write-file-atomic/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "dev": true, + "license": "MIT", + "peer": true, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } } }, "node_modules/y18n": { @@ -11217,6 +13063,29 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } + }, + "node_modules/zod": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.13.tgz", + "integrity": "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zod-validation-error": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-4.0.2.tgz", + "integrity": "sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "zod": "^3.25.0 || ^4.0.0" + } } } } diff --git a/cdk/package.json b/cdk/package.json index a0dbeb0dace..1f5401b9af1 100644 --- a/cdk/package.json +++ b/cdk/package.json @@ -12,22 +12,22 @@ "diff": "cdk diff --path-metadata false --version-reporting false" }, "devDependencies": { - "@guardian/cdk": "62.1.2", - "@guardian/eslint-config": "^11.0.0", - "@guardian/prettier": "5.0.0", + "@guardian/cdk": "^62.1.2", + "@guardian/eslint-config": "^13.0.0", + "@guardian/prettier": "^9.0.0", "@guardian/tsconfig": "^1.0.0", - "@types/jest": "^29.5.14", - "@types/node": "22.15.30", - "aws-cdk": "2.1030.0", - "aws-cdk-lib": "2.219.0", - "constructs": "10.4.2", + "@types/jest": "^30.0.0", + "@types/node": "^24.10.1", + "aws-cdk": "^2.1033.0", + "aws-cdk-lib": "^2.231.0", + "constructs": "^10.4.3", "eslint": "^9.34.0", - "jest": "^29.7.0", + "jest": "^30.2.0", "prettier": "^3.6.2", "source-map-support": "^0.5.20", "ts-jest": "^29.4.2", "ts-node": "^10.9.2", - "typescript": "5.1.6" + "typescript": "^5.9.3" }, "prettier": "@guardian/prettier", "jest": { diff --git a/image-embedder-lambda/package.json b/image-embedder-lambda/package.json index 5099cf4ffc8..15814798cbe 100644 --- a/image-embedder-lambda/package.json +++ b/image-embedder-lambda/package.json @@ -5,7 +5,7 @@ "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "build": "esbuild src/handler.ts --bundle --platform=node --target=node24 --outfile=out.js" + "build": "esbuild src/handler.ts --bundle --platform=node --target=node24 --outfile=dist/handler.js" }, "author": "", "license": "ISC", From 759013b5f18da0488f069c66ce6aaf54f56a4968 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Wed, 3 Dec 2025 16:31:29 +0000 Subject: [PATCH 014/494] add ci/cd --- .github/workflows/ci.yml | 29 ++- .../image-embedder-lambda.test.ts.snap | 228 +++++++++++++++++- scripts/embedder-deploy/build.sh | 10 + scripts/embedder-deploy/cdk.sh | 11 + 4 files changed, 273 insertions(+), 5 deletions(-) create mode 100755 scripts/embedder-deploy/build.sh create mode 100755 scripts/embedder-deploy/cdk.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e14b8f557b..993b92f6304 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -72,6 +72,30 @@ jobs: npm install-clean npm test npm run build + # Node is needed for CDK + - uses: actions/setup-node@v3 + with: + node-version-file: ".nvmrc" + cache: npm + cache-dependency-path: "cdk/package-lock.json" + - name: Image embedder cdk + run: ./scripts/embedder-deploy/cdk.sh + - name: Image embedder bundling + run: ./scripts/embedder-deploy/build.sh + - uses: guardian/actions-riff-raff@v4 + env: + GU_RIFF_RAFF_ROLE_ARN: ${{ secrets.GU_RIFF_RAFF_ROLE_ARN }} + if: ${{ env.GU_RIFF_RAFF_ROLE_ARN }} + with: + githubToken: ${{ secrets.GITHUB_TOKEN }} + roleArn: ${{ secrets.GU_RIFF_RAFF_ROLE_ARN }} + projectName: media-service::grid::embedder + configPath: cdk/cdk.out/riff-raff.yaml + contentDirectories: | + cdk.out: + - cdk/cdk.out + image-embedder-lambda: + - image-embedder.zip - uses: guardian/actions-riff-raff@v4.2.3 if: "! github.event.pull_request.head.repo.fork" with: @@ -104,8 +128,5 @@ jobs: - thrall/target/thrall.deb usage: - usage/target/usage.deb - image-counter-lambda: - - image-counter-lambda/dist/image-counter-lambda.zip - - + - image-counter-lambda/dist/image-counter-lambda.zip \ No newline at end of file diff --git a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap index f6c389aee7f..80aba5454c7 100644 --- a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap +++ b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap @@ -3,8 +3,234 @@ exports[`The ImageEmbedderLambda stack matches the snapshot 1`] = ` { "Metadata": { - "gu:cdk:constructs": [], + "gu:cdk:constructs": [ + "GuDistributionBucketParameter", + "GuLambdaFunction", + ], "gu:cdk:version": "TEST", }, + "Parameters": { + "DistributionBucketName": { + "Default": "/account/services/artifact.bucket", + "Description": "SSM parameter containing the S3 bucket name holding distribution artifacts", + "Type": "AWS::SSM::Parameter::Value", + }, + }, + "Resources": { + "ImageEmbedderHandler2C9410B9": { + "DependsOn": [ + "ImageEmbedderHandlerServiceRoleDefaultPolicy613DB8F0", + "ImageEmbedderHandlerServiceRoleD4456D21", + ], + "Properties": { + "Architectures": [ + "arm64", + ], + "Code": { + "S3Bucket": { + "Ref": "DistributionBucketName", + }, + "S3Key": "image-embedder-lambda/TEST/image-embedder-handler/image-embedder.zip", + }, + "Environment": { + "Variables": { + "APP": "image-embedder-handler", + "STACK": "image-embedder-lambda", + "STAGE": "TEST", + }, + }, + "FunctionName": "image-embedder-TEST", + "Handler": "dist.handler", + "LoggingConfig": { + "LogFormat": "JSON", + }, + "MemorySize": 512, + "Role": { + "Fn::GetAtt": [ + "ImageEmbedderHandlerServiceRoleD4456D21", + "Arn", + ], + }, + "Runtime": "nodejs24.x", + "Tags": [ + { + "Key": "App", + "Value": "image-embedder-handler", + }, + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/grid", + }, + { + "Key": "Stack", + "Value": "image-embedder-lambda", + }, + { + "Key": "Stage", + "Value": "TEST", + }, + ], + "Timeout": 30, + }, + "Type": "AWS::Lambda::Function", + }, + "ImageEmbedderHandlerServiceRoleD4456D21": { + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com", + }, + }, + ], + "Version": "2012-10-17", + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", + ], + ], + }, + ], + "Tags": [ + { + "Key": "App", + "Value": "image-embedder-handler", + }, + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/grid", + }, + { + "Key": "Stack", + "Value": "image-embedder-lambda", + }, + { + "Key": "Stage", + "Value": "TEST", + }, + ], + }, + "Type": "AWS::IAM::Role", + }, + "ImageEmbedderHandlerServiceRoleDefaultPolicy613DB8F0": { + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:GetObject*", + "s3:GetBucket*", + "s3:List*", + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":s3:::", + { + "Ref": "DistributionBucketName", + }, + ], + ], + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition", + }, + ":s3:::", + { + "Ref": "DistributionBucketName", + }, + "/image-embedder-lambda/TEST/image-embedder-handler/image-embedder.zip", + ], + ], + }, + ], + }, + { + "Action": "ssm:GetParametersByPath", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":parameter/TEST/image-embedder-lambda/image-embedder-handler", + ], + ], + }, + }, + { + "Action": [ + "ssm:GetParameters", + "ssm:GetParameter", + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":parameter/TEST/image-embedder-lambda/image-embedder-handler/*", + ], + ], + }, + }, + ], + "Version": "2012-10-17", + }, + "PolicyName": "ImageEmbedderHandlerServiceRoleDefaultPolicy613DB8F0", + "Roles": [ + { + "Ref": "ImageEmbedderHandlerServiceRoleD4456D21", + }, + ], + }, + "Type": "AWS::IAM::Policy", + }, + }, } `; diff --git a/scripts/embedder-deploy/build.sh b/scripts/embedder-deploy/build.sh new file mode 100755 index 00000000000..9521e35f664 --- /dev/null +++ b/scripts/embedder-deploy/build.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +set -e + +( + cd image-embedder-lambda + npm install + npm run build + zip -r ../image-embedder.zip dist +) \ No newline at end of file diff --git a/scripts/embedder-deploy/cdk.sh b/scripts/embedder-deploy/cdk.sh new file mode 100755 index 00000000000..06ba8a13abd --- /dev/null +++ b/scripts/embedder-deploy/cdk.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -e + +( + cd cdk + npm ci + npm run lint + npm run test + npm run synth +) \ No newline at end of file From 1fc3dc323a0e981f13050b3946f92db63a4e8e99 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Wed, 3 Dec 2025 16:52:08 +0000 Subject: [PATCH 015/494] try and write own riffraff yaml --- .github/workflows/ci.yml | 36 ++++++++++------- cdk/bin/cdk.ts | 6 +-- .../image-embedder-lambda.test.ts.snap | 16 ++++---- cdk/lib/image-embedder-lambda.test.ts | 6 +-- cdk/lib/image-embedder-lambda.ts | 2 +- riff-raff.yaml | 40 +++++++++++++++++++ 6 files changed, 76 insertions(+), 30 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 993b92f6304..80f3fec3d98 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,20 +82,20 @@ jobs: run: ./scripts/embedder-deploy/cdk.sh - name: Image embedder bundling run: ./scripts/embedder-deploy/build.sh - - uses: guardian/actions-riff-raff@v4 - env: - GU_RIFF_RAFF_ROLE_ARN: ${{ secrets.GU_RIFF_RAFF_ROLE_ARN }} - if: ${{ env.GU_RIFF_RAFF_ROLE_ARN }} - with: - githubToken: ${{ secrets.GITHUB_TOKEN }} - roleArn: ${{ secrets.GU_RIFF_RAFF_ROLE_ARN }} - projectName: media-service::grid::embedder - configPath: cdk/cdk.out/riff-raff.yaml - contentDirectories: | - cdk.out: - - cdk/cdk.out - image-embedder-lambda: - - image-embedder.zip + # - uses: guardian/actions-riff-raff@v4 + # env: + # GU_RIFF_RAFF_ROLE_ARN: ${{ secrets.GU_RIFF_RAFF_ROLE_ARN }} + # if: ${{ env.GU_RIFF_RAFF_ROLE_ARN }} + # with: + # githubToken: ${{ secrets.GITHUB_TOKEN }} + # roleArn: ${{ secrets.GU_RIFF_RAFF_ROLE_ARN }} + # projectName: media-service::grid::embedder + # configPath: cdk/cdk.out/riff-raff.yaml + # contentDirectories: | + # cdk.out: + # - cdk/cdk.out + # image-embedder-lambda: + # - image-embedder.zip - uses: guardian/actions-riff-raff@v4.2.3 if: "! github.event.pull_request.head.repo.fork" with: @@ -128,5 +128,11 @@ jobs: - thrall/target/thrall.deb usage: - usage/target/usage.deb + image-counter-lambda: - - image-counter-lambda/dist/image-counter-lambda.zip \ No newline at end of file + - image-counter-lambda/dist/image-counter-lambda.zip + + cdk.out: + - cdk/cdk.out + image-embedder-lambda: + - image-embedder.zip \ No newline at end of file diff --git a/cdk/bin/cdk.ts b/cdk/bin/cdk.ts index 8955a94520a..27a93d21270 100644 --- a/cdk/bin/cdk.ts +++ b/cdk/bin/cdk.ts @@ -1,7 +1,7 @@ import "source-map-support/register"; import { GuRoot } from "@guardian/cdk/lib/constructs/root"; -import { ImageEmbedderLambda } from "../lib/image-embedder-lambda"; +import { MediaService } from "../lib/image-embedder-lambda"; const app = new GuRoot(); -new ImageEmbedderLambda(app, "ImageEmbedderLambda-euwest-1-PROD", { stack: "image-embedder-lambda", stage: "PROD", env: { region: "eu-west-1" } }); -new ImageEmbedderLambda(app, "ImageEmbedderLambda-euwest-1-TEST", { stack: "image-embedder-lambda", stage: "TEST", env: { region: "eu-west-1" } }); +new MediaService(app, "ImageEmbedderLambda-euwest-1-PROD", { stack: "media-service", stage: "PROD", env: { region: "eu-west-1" } }); +new MediaService(app, "ImageEmbedderLambda-euwest-1-TEST", { stack: "media-service", stage: "TEST", env: { region: "eu-west-1" } }); diff --git a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap index 80aba5454c7..96a03d80bc5 100644 --- a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap +++ b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing -exports[`The ImageEmbedderLambda stack matches the snapshot 1`] = ` +exports[`The MediaService stack matches the snapshot 1`] = ` { "Metadata": { "gu:cdk:constructs": [ @@ -30,12 +30,12 @@ exports[`The ImageEmbedderLambda stack matches the snapshot 1`] = ` "S3Bucket": { "Ref": "DistributionBucketName", }, - "S3Key": "image-embedder-lambda/TEST/image-embedder-handler/image-embedder.zip", + "S3Key": "media-service/TEST/image-embedder-handler/image-embedder.zip", }, "Environment": { "Variables": { "APP": "image-embedder-handler", - "STACK": "image-embedder-lambda", + "STACK": "media-service", "STAGE": "TEST", }, }, @@ -67,7 +67,7 @@ exports[`The ImageEmbedderLambda stack matches the snapshot 1`] = ` }, { "Key": "Stack", - "Value": "image-embedder-lambda", + "Value": "media-service", }, { "Key": "Stage", @@ -121,7 +121,7 @@ exports[`The ImageEmbedderLambda stack matches the snapshot 1`] = ` }, { "Key": "Stack", - "Value": "image-embedder-lambda", + "Value": "media-service", }, { "Key": "Stage", @@ -170,7 +170,7 @@ exports[`The ImageEmbedderLambda stack matches the snapshot 1`] = ` { "Ref": "DistributionBucketName", }, - "/image-embedder-lambda/TEST/image-embedder-handler/image-embedder.zip", + "/media-service/TEST/image-embedder-handler/image-embedder.zip", ], ], }, @@ -191,7 +191,7 @@ exports[`The ImageEmbedderLambda stack matches the snapshot 1`] = ` { "Ref": "AWS::AccountId", }, - ":parameter/TEST/image-embedder-lambda/image-embedder-handler", + ":parameter/TEST/media-service/image-embedder-handler", ], ], }, @@ -214,7 +214,7 @@ exports[`The ImageEmbedderLambda stack matches the snapshot 1`] = ` { "Ref": "AWS::AccountId", }, - ":parameter/TEST/image-embedder-lambda/image-embedder-handler/*", + ":parameter/TEST/media-service/image-embedder-handler/*", ], ], }, diff --git a/cdk/lib/image-embedder-lambda.test.ts b/cdk/lib/image-embedder-lambda.test.ts index 69b3a551d3f..28aed1e88e7 100644 --- a/cdk/lib/image-embedder-lambda.test.ts +++ b/cdk/lib/image-embedder-lambda.test.ts @@ -1,11 +1,11 @@ import { App } from "aws-cdk-lib"; import { Template } from "aws-cdk-lib/assertions"; -import { ImageEmbedderLambda } from "./image-embedder-lambda"; +import { MediaService } from "./image-embedder-lambda"; -describe("The ImageEmbedderLambda stack", () => { +describe("The MediaService stack", () => { it("matches the snapshot", () => { const app = new App(); - const stack = new ImageEmbedderLambda(app, "ImageEmbedderLambda", { stack: "image-embedder-lambda", stage: "TEST" }); + const stack = new MediaService(app, "ImageEmbedderLambda", { stack: "media-service", stage: "TEST" }); const template = Template.fromStack(stack); expect(template.toJSON()).toMatchSnapshot(); }); diff --git a/cdk/lib/image-embedder-lambda.ts b/cdk/lib/image-embedder-lambda.ts index ef148cb62a5..4708fde4710 100644 --- a/cdk/lib/image-embedder-lambda.ts +++ b/cdk/lib/image-embedder-lambda.ts @@ -5,7 +5,7 @@ import type { App } from "aws-cdk-lib"; import { aws_lambda as lambda } from "aws-cdk-lib"; import { Architecture } from "aws-cdk-lib/aws-lambda"; -export class ImageEmbedderLambda extends GuStack { +export class MediaService extends GuStack { constructor(scope: App, id: string, props: GuStackProps) { super(scope, id, props); diff --git a/riff-raff.yaml b/riff-raff.yaml index 95a71a754b2..95e194d5d6e 100644 --- a/riff-raff.yaml +++ b/riff-raff.yaml @@ -119,3 +119,43 @@ deployments: fileName: image-counter-lambda.zip functionNames: - "image-counter-lambda-function-" + + lambda-upload-eu-west-1-image-embedder-lambda-image-embedder-handler: + type: aws-lambda + regions: + - eu-west-1 + app: image-embedder-handler + contentDirectory: image-embedder-handler + parameters: + bucketSsmLookup: true + lookupByTags: true + fileName: image-embedder.zip + actions: + - uploadLambda + cfn-eu-west-1-image-embedder-lambda-image-embedder-lambda: + type: cloud-formation + regions: + - eu-west-1 + app: image-embedder-lambda + contentDirectory: cdk.out + parameters: + templateStagePaths: + PROD: ImageEmbedderLambda-euwest-1-PROD.template.json + TEST: ImageEmbedderLambda-euwest-1-TEST.template.json + dependencies: + - lambda-upload-eu-west-1-image-embedder-lambda-image-embedder-handler + lambda-update-eu-west-1-image-embedder-lambda-image-embedder-handler: + type: aws-lambda + regions: + - eu-west-1 + app: image-embedder-handler + contentDirectory: image-embedder-handler + parameters: + bucketSsmLookup: true + lookupByTags: true + fileName: image-embedder.zip + actions: + - updateLambda + dependencies: + - cfn-eu-west-1-image-embedder-lambda-image-embedder-lambda + From ab00d1f924adce06e84d44a4448f044198110a67 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Wed, 3 Dec 2025 17:06:44 +0000 Subject: [PATCH 016/494] fix typo --- .../image-embedder-lambda.test.ts.snap | 14 +++++++------- cdk/lib/image-embedder-lambda.ts | 2 +- riff-raff.yaml | 14 +++++++------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap index 96a03d80bc5..d198a6652c0 100644 --- a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap +++ b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap @@ -30,11 +30,11 @@ exports[`The MediaService stack matches the snapshot 1`] = ` "S3Bucket": { "Ref": "DistributionBucketName", }, - "S3Key": "media-service/TEST/image-embedder-handler/image-embedder.zip", + "S3Key": "media-service/TEST/image-embedder-lambda/image-embedder.zip", }, "Environment": { "Variables": { - "APP": "image-embedder-handler", + "APP": "image-embedder-lambda", "STACK": "media-service", "STAGE": "TEST", }, @@ -55,7 +55,7 @@ exports[`The MediaService stack matches the snapshot 1`] = ` "Tags": [ { "Key": "App", - "Value": "image-embedder-handler", + "Value": "image-embedder-lambda", }, { "Key": "gu:cdk:version", @@ -109,7 +109,7 @@ exports[`The MediaService stack matches the snapshot 1`] = ` "Tags": [ { "Key": "App", - "Value": "image-embedder-handler", + "Value": "image-embedder-lambda", }, { "Key": "gu:cdk:version", @@ -170,7 +170,7 @@ exports[`The MediaService stack matches the snapshot 1`] = ` { "Ref": "DistributionBucketName", }, - "/media-service/TEST/image-embedder-handler/image-embedder.zip", + "/media-service/TEST/image-embedder-lambda/image-embedder.zip", ], ], }, @@ -191,7 +191,7 @@ exports[`The MediaService stack matches the snapshot 1`] = ` { "Ref": "AWS::AccountId", }, - ":parameter/TEST/media-service/image-embedder-handler", + ":parameter/TEST/media-service/image-embedder-lambda", ], ], }, @@ -214,7 +214,7 @@ exports[`The MediaService stack matches the snapshot 1`] = ` { "Ref": "AWS::AccountId", }, - ":parameter/TEST/media-service/image-embedder-handler/*", + ":parameter/TEST/media-service/image-embedder-lambda/*", ], ], }, diff --git a/cdk/lib/image-embedder-lambda.ts b/cdk/lib/image-embedder-lambda.ts index 4708fde4710..12000c339b7 100644 --- a/cdk/lib/image-embedder-lambda.ts +++ b/cdk/lib/image-embedder-lambda.ts @@ -20,7 +20,7 @@ export class MediaService extends GuStack { runtime: LAMBDA_NODE_VERSION, architecture: Architecture.ARM_64, handler: 'dist.handler', - app: 'image-embedder-handler', + app: 'image-embedder-lambda', }, ); diff --git a/riff-raff.yaml b/riff-raff.yaml index 95e194d5d6e..1fbab430336 100644 --- a/riff-raff.yaml +++ b/riff-raff.yaml @@ -120,12 +120,12 @@ deployments: functionNames: - "image-counter-lambda-function-" - lambda-upload-eu-west-1-image-embedder-lambda-image-embedder-handler: + lambda-upload-eu-west-1-image-embedder-lambda-image-embedder-lambda: type: aws-lambda regions: - eu-west-1 - app: image-embedder-handler - contentDirectory: image-embedder-handler + app: image-embedder-lambda + contentDirectory: image-embedder-lambda parameters: bucketSsmLookup: true lookupByTags: true @@ -143,13 +143,13 @@ deployments: PROD: ImageEmbedderLambda-euwest-1-PROD.template.json TEST: ImageEmbedderLambda-euwest-1-TEST.template.json dependencies: - - lambda-upload-eu-west-1-image-embedder-lambda-image-embedder-handler - lambda-update-eu-west-1-image-embedder-lambda-image-embedder-handler: + - lambda-upload-eu-west-1-image-embedder-lambda-image-embedder-lambda + lambda-update-eu-west-1-image-embedder-lambda-image-embedder-lambda: type: aws-lambda regions: - eu-west-1 - app: image-embedder-handler - contentDirectory: image-embedder-handler + app: image-embedder-lambda + contentDirectory: image-embedder-lambda parameters: bucketSsmLookup: true lookupByTags: true From c8ffe1d46eb82b5f91bb46fec3aa5109e34a547c Mon Sep 17 00:00:00 2001 From: Andrew Nowak Date: Mon, 8 Dec 2025 10:35:45 +0000 Subject: [PATCH 017/494] upgrade tika to latest --- build.sbt | 2 +- image-loader/app/model/Projector.scala | 2 +- .../conf/org/apache/tika/mime/custom-mimetypes.xml | 11 ----------- 3 files changed, 2 insertions(+), 13 deletions(-) delete mode 100644 image-loader/conf/org/apache/tika/mime/custom-mimetypes.xml diff --git a/build.sbt b/build.sbt index d5949211f75..df3f1b74500 100644 --- a/build.sbt +++ b/build.sbt @@ -132,7 +132,7 @@ lazy val cropper = playProject("cropper", 9006) lazy val imageLoader = playProject("image-loader", 9003).settings { libraryDependencies ++= Seq( - "org.apache.tika" % "tika-core" % "1.28.5", + "org.apache.tika" % "tika-core" % "3.2.3", "com.drewnoakes" % "metadata-extractor" % "2.19.0" ) } diff --git a/image-loader/app/model/Projector.scala b/image-loader/app/model/Projector.scala index 1cc13d9bf01..a229fb510ee 100644 --- a/image-loader/app/model/Projector.scala +++ b/image-loader/app/model/Projector.scala @@ -16,7 +16,7 @@ import com.gu.mediaservice.model.{Image, MimeType, UploadInfo} import lib.imaging.{MimeTypeDetection, NoSuchImageExistsInS3} import lib.{DigestedFile, ImageLoaderConfig} import model.upload.UploadRequest -import org.apache.tika.io.IOUtils +import org.apache.commons.io.IOUtils import org.joda.time.{DateTime, DateTimeZone} import play.api.libs.ws.WSRequest import software.amazon.awssdk.services.s3vectors.model.PutVectorsResponse diff --git a/image-loader/conf/org/apache/tika/mime/custom-mimetypes.xml b/image-loader/conf/org/apache/tika/mime/custom-mimetypes.xml deleted file mode 100644 index 3f92a6ff6d7..00000000000 --- a/image-loader/conf/org/apache/tika/mime/custom-mimetypes.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - <_comment>Canon raw image - - - - - - - From d0821a733888ab1080e16b023eff62a579c6df25 Mon Sep 17 00:00:00 2001 From: Reetta Vaahtoranta Date: Mon, 8 Dec 2025 15:52:24 +0000 Subject: [PATCH 018/494] Add central workflow which requires CORE4 labels on PRs prior to merging. --- .github/workflows/check-labels.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .github/workflows/check-labels.yaml diff --git a/.github/workflows/check-labels.yaml b/.github/workflows/check-labels.yaml new file mode 100644 index 00000000000..75a4a1445bd --- /dev/null +++ b/.github/workflows/check-labels.yaml @@ -0,0 +1,9 @@ +name: CORE4 label enforcement +permissions: + contents: read +on: + pull_request: + types: [opened, labeled, unlabeled, synchronize, reopened, edited] +jobs: + require-label: + uses: guardian/.github/.github/workflows/require-label.yaml@4cb5024736632ffcc564b7f4b772c38b8e5ce739 # v2.0.0 From 3ba688d32a4f6fa09aa0b9b12b07556d7ad56396 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Dec 2025 20:01:13 +0000 Subject: [PATCH 019/494] chore(deps): bump actions/checkout from 4.3.1 to 6.0.1 Bumps [actions/checkout](https://github.com/actions/checkout) from 4.3.1 to 6.0.1. - [Release notes](https://github.com/actions/checkout/releases) - [Commits](https://github.com/actions/checkout/compare/v4.3.1...v6.0.1) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 6.0.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/ci.yml | 2 +- .github/workflows/push-pr.yml | 2 +- .github/workflows/sbt-dependency-graph.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0e14b8f557b..657c69ce391 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,7 +36,7 @@ jobs: --health-timeout 5s --health-retries 10 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v6.0.1 - name: Setup Node uses: actions/setup-node@v3 with: diff --git a/.github/workflows/push-pr.yml b/.github/workflows/push-pr.yml index d962b4a55cb..862e4e2b305 100644 --- a/.github/workflows/push-pr.yml +++ b/.github/workflows/push-pr.yml @@ -18,7 +18,7 @@ jobs: contents: write actions: write steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@v6.0.1 - name: push-pr env: PR: ${{ inputs.prNumber }} diff --git a/.github/workflows/sbt-dependency-graph.yaml b/.github/workflows/sbt-dependency-graph.yaml index a737228a137..81208fa27e5 100644 --- a/.github/workflows/sbt-dependency-graph.yaml +++ b/.github/workflows/sbt-dependency-graph.yaml @@ -10,7 +10,7 @@ jobs: steps: - name: Checkout branch id: checkout - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - name: Install Java id: java uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.2.0 From b2b978d4f55ada28b55fea2fc8aead04a835b45c Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Tue, 9 Dec 2025 16:56:11 +0000 Subject: [PATCH 020/494] get in sync with main --- .../gu/mediaservice/lib/aws/Embedder.scala | 26 ++--------- .../gu/mediaservice/lib/aws/S3Vectors.scala | 12 +++-- kahuna/app/controllers/KahunaController.scala | 1 - media-api/app/controllers/MediaApi.scala | 46 ++++++++++++------- 4 files changed, 39 insertions(+), 46 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala index ffaec083314..132502d7fe0 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala @@ -45,38 +45,18 @@ class Embedder(s3vectors: S3Vectors, bedrock: Bedrock)(implicit ec: ExecutionCon logger.info(logMarker, s"Searching for image embedding for query: $query") val embeddingFuture = bedrock.createEmbedding(InputType.SearchDocument, query) embeddingFuture.flatMap { embedding => - s3vectors.searchVectorStore(embedding, query) + s3vectors.searchVectorStoreWithQueryString(embedding, query) } } - private def convertEmbeddingToVectorData(embedding: List[Float]): VectorData = { - VectorData - .builder() - .float32(embedding.map(float2Float).asJava) - .build() - } - - def imageToImageSearch(imageId: String)(implicit ec: ExecutionContext, logMarker: LogMarker): Option[QueryVectorsResponse] = { + def imageToImageSearch(imageId: String)(implicit ec: ExecutionContext, logMarker: LogMarker): Option[Future[QueryVectorsResponse]] = { val maybeVector = s3vectors.findVectorForImageId(imageId) if (maybeVector.vectors().isEmpty) { logger.error(logMarker, s"No embedding found for ${imageId}") None } else { val vector: VectorData = maybeVector.vectors().asScala.head.data() - Some(s3vectors.searchVectorStore(vector)) - } - } - - def createEmbeddingAndSearch(q: String)(implicit ec: ExecutionContext, logMarker: LogMarker): Future[QueryVectorsResponse] = { - - logger.info(logMarker, s"Searching for image embedding for $q") - - val embeddingFuture = bedrock.createSearchTermEmbedding(q: String) - embeddingFuture.map { embedding => -// We need to convert the embedding to a VectorData object for the S3 Vector Store API - val vectorData = convertEmbeddingToVectorData(embedding) - s3vectors.searchVectorStore(vectorData) + Some(s3vectors.searchVectorStoreForSimilarImages(vector)) } } - } diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala index 25d9c039efc..d1470440927 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala @@ -1,10 +1,12 @@ package com.gu.mediaservice.lib.aws import com.gu.mediaservice.lib.config.CommonConfig import com.gu.mediaservice.lib.logging.LogMarker - import software.amazon.awssdk.regions.Region import software.amazon.awssdk.services.s3vectors._ -import software.amazon.awssdk.services.s3vectors.model.{PutInputVector, PutVectorsRequest, PutVectorsResponse, VectorData} +import software.amazon.awssdk.services.s3vectors.model.{ + DeleteVectorsRequest, DeleteVectorsResponse, GetOutputVector, GetVectorsRequest, PutInputVector, PutVectorsRequest, + PutVectorsResponse, VectorData, QueryVectorsRequest, QueryVectorsResponse, GetVectorsResponse +} import java.net.URI import scala.concurrent.{ExecutionContext, Future} @@ -124,7 +126,7 @@ class S3Vectors(config: CommonConfig)(implicit ec: ExecutionContext) client.queryVectors(request) } - def searchVectorStore(queryEmbedding: List[Float], query: String)(implicit logMarker: LogMarker): Future[QueryVectorsResponse] = Future { + def searchVectorStoreWithQueryString(queryEmbedding: List[Float], query: String)(implicit logMarker: LogMarker): Future[QueryVectorsResponse] = Future { try { val response = queryVectors(queryEmbedding) logger.info( @@ -167,8 +169,8 @@ class S3Vectors(config: CommonConfig)(implicit ec: ExecutionContext) } } - def searchVectorStore(queryVector: VectorData)(implicit logMarker: LogMarker - ): QueryVectorsResponse = { + def searchVectorStoreForSimilarImages(queryVector: VectorData)(implicit logMarker: LogMarker + ): Future[QueryVectorsResponse] = Future { logger.info(logMarker, s"Searching for image embedding") try { val request: QueryVectorsRequest = QueryVectorsRequest diff --git a/kahuna/app/controllers/KahunaController.scala b/kahuna/app/controllers/KahunaController.scala index 1dd3ebe8a08..769d0a81ed2 100644 --- a/kahuna/app/controllers/KahunaController.scala +++ b/kahuna/app/controllers/KahunaController.scala @@ -4,7 +4,6 @@ import com.gu.mediaservice.lib.argo.ArgoHelpers import com.gu.mediaservice.lib.auth.Authentication.Principal import com.gu.mediaservice.lib.auth.{Authentication, Authorisation, BaseControllerWithLoginRedirects} import lib.{EnableAISearch, ExampleSwitch, FeatureSwitches, KahunaConfig, UseCqlChips} -import lib.{ExampleSwitch, FeatureSwitches, KahunaConfig, SemanticSearchEnabled, UseCqlChips} import play.api.mvc.ControllerComponents import play.api.libs.json._ diff --git a/media-api/app/controllers/MediaApi.scala b/media-api/app/controllers/MediaApi.scala index 52991e7d48a..4c0e293718e 100644 --- a/media-api/app/controllers/MediaApi.scala +++ b/media-api/app/controllers/MediaApi.scala @@ -566,29 +566,41 @@ class MediaApi( case None => "" } - val semanticSearchResult: Future[QueryVectorsResponse] = embedder.createEmbeddingAndSearch(searchTerm) + val searchForSimilar = searchTerm.split(" ").find(_.startsWith("similar:")) - val imageIds = semanticSearchResult.map { result => - val results: java.util.List[QueryOutputVector] = result.vectors() - results.asScala.map(_.key()).toList + val semanticSearchResult: Option[Future[QueryVectorsResponse]] = if (searchForSimilar.isDefined) { + val extractedImageId = searchForSimilar.get.split(":")(1) + embedder.imageToImageSearch(extractedImageId) + } else { + Some(embedder.createEmbeddingAndSearch(searchTerm)) } - imageIds.flatMap { ids => - SearchParams( - query = _searchParams.query, - ids = Some(ids), - tier = request.user.accessor.tier, - ) + semanticSearchResult match { + case None => + Future.successful(respondError(NotFound, "Not Found", + "The image you have selected is not yet in the S3 Vector Store. We cannot do a similarity search on it yet.")) + case Some(results) => + val imageIds = results.map { result => + val results: java.util.List[QueryOutputVector] = result.vectors() + results.asScala.map(_.key()).toList + } - for { - SearchResults(hits, totalCount, _) <- elasticSearch.lookupIds(ids, offset = _searchParams.offset, length = _searchParams.length) - imageEntities = hits map (hitToImageEntity _).tupled - links = List() - } yield { - respondCollection(imageEntities, Some(_searchParams.offset), Some(totalCount), None, links) + imageIds.flatMap { ids => + SearchParams( + query = _searchParams.query, + ids = Some(ids), + tier = request.user.accessor.tier, + ) + + for { + SearchResults(hits, totalCount, _) <- elasticSearch.lookupIds(ids, offset = _searchParams.offset, length = _searchParams.length) + imageEntities = hits map (hitToImageEntity _).tupled + links = List() + } yield { + respondCollection(imageEntities, Some(_searchParams.offset), Some(totalCount), None, links) + } } } - } else { val searchParams = if(canViewDeletedImages) { From c75289f89680ccc06973b07105495ebda2a7bcd4 Mon Sep 17 00:00:00 2001 From: Andrew Nowak Date: Wed, 10 Dec 2025 12:33:43 +0000 Subject: [PATCH 021/494] add in some example values for usage rights config in dev --- dev/script/generate-config/service-config.js | 30 ++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/dev/script/generate-config/service-config.js b/dev/script/generate-config/service-config.js index 5f30d890f32..061a4447a72 100644 --- a/dev/script/generate-config/service-config.js +++ b/dev/script/generate-config/service-config.js @@ -27,6 +27,36 @@ function getCommonConfig(config) { |sqs.ingest.queue.url="${config.coreStackProps.IngestSqsQueue.replace("http://localhost:4576", `https://localstack.media.${config.DOMAIN}`)}" |s3.ingest.bucket="${config.coreStackProps.IngestQueueBucket}" |s3.fail.bucket="${config.coreStackProps.IngestQueueFailBucket}" + |usageRightsConfigProvider.config.freeSuppliers=[ + | "AAP", + | "Alamy", + | "Allstar Picture Library", + | "AP", + | "EPA", + | "Getty Images", + | "PA", + | "Reuters", + | "Rex Features", + | "Ronald Grant Archive", + | "Action Images" + |] + |usageRightsConfigProvider.config.externalStaffPhotographers=[{ + | name="Example publication", + | photographers=["Example External Photographer"], + |}] + |usageRightsConfigProvider.config.internalStaffPhotographers=[{ + | name="Example publication", + | photographers=["Example Internal Photographer"] + |}] + |usageRightsConfigProvider.config.contractedPhotographers=[{ + | name="Example publication", + | photographers=["Example Contracted Photographer"] + |}] + |usageRightsConfigProvider.config.contractIllustrators=[{ + | name="Example publication", + | photographers=["Example Contracted Illustrator"] + |}] + |usageRightsConfigProvider.config.staffIllustrators=["Example Staff Illustrator"] |`; } From d407549f493ef26e49c5ce67df90f692d69b1aa9 Mon Sep 17 00:00:00 2001 From: Andrew Nowak Date: Wed, 26 Nov 2025 15:15:02 +0000 Subject: [PATCH 022/494] WIP upgrading our DynamoDB wrapper --- build.sbt | 1 + .../gu/mediaservice/lib/aws/DynamoDB.scala | 46 ++++++++++++------- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/build.sbt b/build.sbt index df3f1b74500..5b8acc6fe62 100644 --- a/build.sbt +++ b/build.sbt @@ -107,6 +107,7 @@ lazy val commonLib = project("common-lib").settings( "org.scanamo" %% "scanamo" % "2.0.0", // declare explicit dependency on desired version of aws sdk v2 dynamo "software.amazon.awssdk" % "dynamodb" % awsSdkV2Version, + "software.amazon.awssdk" % "dynamodb-enhanced" % awsSdkV2Version, // declare explicit dependency on desired version of aws sdk v2 bedrock runtime "software.amazon.awssdk" % "bedrockruntime" % awsSdkV2Version, "software.amazon.awssdk" % "s3vectors" % awsSdkV2Version, diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala index c7f5066da15..b44f1727908 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala @@ -1,7 +1,6 @@ package com.gu.mediaservice.lib.aws import java.util - import com.amazonaws.AmazonServiceException import com.amazonaws.services.dynamodbv2.document.spec.{DeleteItemSpec, GetItemSpec, PutItemSpec, QuerySpec, UpdateItemSpec} import com.amazonaws.services.dynamodbv2.document.utils.ValueMap @@ -12,10 +11,13 @@ import com.gu.mediaservice.lib.config.CommonConfig import com.gu.mediaservice.lib.logging.GridLogging import org.joda.time.DateTime import play.api.libs.json._ +import software.amazon.awssdk.enhanced.dynamodb._ +import software.amazon.awssdk.enhanced.dynamodb.document.EnhancedDocument +import software.amazon.awssdk.services.dynamodb.DynamoDbClient import scala.annotation.tailrec -import scala.jdk.CollectionConverters._ import scala.concurrent.{ExecutionContext, Future} +import scala.jdk.CollectionConverters._ object NoItemFound extends Throwable("item not found") @@ -27,26 +29,27 @@ object NoItemFound extends Throwable("item not found") * @tparam T The type of this table */ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Option[String] = None) extends GridLogging { + lazy val client2: DynamoDbClient = config.withAWSCredentialsV2(DynamoDbClient.builder()).build() + lazy val dynamo2: DynamoDbEnhancedClient = DynamoDbEnhancedClient.builder().dynamoDbClient(client2).build() + lazy val tableSchema = TableSchema.documentSchemaBuilder() + .addIndexPartitionKey(TableMetadata.primaryIndexName(), IdKey, AttributeValueType.S) + .attributeConverterProviders(AttributeConverterProvider.defaultProvider()) + .build() + lazy val table2 = dynamo2.table(tableName, tableSchema) + lazy val client: AmazonDynamoDBAsync = config.withAWSCredentials(AmazonDynamoDBAsyncClientBuilder.standard()).build() lazy val dynamo = new AwsDynamoDB(client) lazy val table: Table = dynamo.getTable(tableName) - val IdKey = "id" + private val IdKey = "id" - def exists(id: String)(implicit ex: ExecutionContext): Future[Boolean] = Future { - table.getItem(new GetItemSpec().withPrimaryKey(IdKey, id)) - } map(Option(_).isDefined) + private def itemKey(key: String) = Key.builder().partitionValue(key).build() - def get(id: String) - (implicit ex: ExecutionContext): Future[JsObject] = Future { - table.getItem( - new GetItemSpec(). - withPrimaryKey(IdKey, id) - ) - } flatMap itemOrNotFound map asJsObject + def get(id: String)(implicit ex: ExecutionContext): Future[JsObject] = Future { + table2.getItem(itemKey(id)) + } flatMap docOrNotFound map asJsObject - private def get(id: String, key: String) - (implicit ex: ExecutionContext): Future[Item] = Future { + private def get(id: String, key: String)(implicit ex: ExecutionContext): Future[Item] = Future { table.getItem( new GetItemSpec() .withPrimaryKey(IdKey, id) @@ -54,6 +57,13 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti ) } flatMap itemOrNotFound + private def docOrNotFound(docOrNull: EnhancedDocument): Future[EnhancedDocument] = { + Option(docOrNull) match { + case Some(doc) => Future.successful(doc) + case None => Future.failed(NoItemFound) + } + } + private def itemOrNotFound(itemOrNull: Item): Future[Item] = { Option(itemOrNull) match { case Some(item) => Future.successful(item) @@ -294,9 +304,11 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti // FIXME: surely there must be a better way to convert? - def asJsObject(item: Item): JsObject = { + def asJsObject(item: Item): JsObject = jsonWithNullAsEmptyString(Json.parse(item.toJSON)).as[JsObject] - IdKey - } + + def asJsObject(doc: EnhancedDocument): JsObject = + jsonWithNullAsEmptyString(Json.parse(doc.toJson)).as[JsObject] - IdKey def asJsObject(outcome: UpdateItemOutcome): JsObject = Option(outcome.getItem) map asJsObject getOrElse Json.obj() From cb3824818aff1a6aaeb97f34149dfd04facf58c4 Mon Sep 17 00:00:00 2001 From: Andrew Nowak Date: Wed, 26 Nov 2025 16:13:07 +0000 Subject: [PATCH 023/494] WIP all gets in DynamoDB updated --- .../ImageCollectionsController.scala | 4 +- .../gu/mediaservice/lib/aws/DynamoDB.scala | 55 +++++++++++++------ .../app/controllers/EditsController.scala | 24 ++++---- 3 files changed, 53 insertions(+), 30 deletions(-) diff --git a/collections/app/controllers/ImageCollectionsController.scala b/collections/app/controllers/ImageCollectionsController.scala index b46b60e239b..d1e65c464fe 100644 --- a/collections/app/controllers/ImageCollectionsController.scala +++ b/collections/app/controllers/ImageCollectionsController.scala @@ -3,7 +3,7 @@ package controllers import com.gu.mediaservice.lib.argo.ArgoHelpers import com.gu.mediaservice.lib.auth.Authentication import com.gu.mediaservice.lib.auth.Authentication.getIdentity -import com.gu.mediaservice.lib.aws.{DynamoDB, NoItemFound, UpdateMessage} +import com.gu.mediaservice.lib.aws.{NoItemFound, UpdateMessage} import com.gu.mediaservice.lib.collections.CollectionsManager import com.gu.mediaservice.lib.net.{URI => UriOps} import com.gu.mediaservice.model.{ActionData, Collection} @@ -25,8 +25,6 @@ class ImageCollectionsController(authenticated: Authentication, config: Collecti import CollectionsManager.onlyLatest - val dynamo = new DynamoDB[Collection](config, config.imageCollectionsTable) - def getCollections(id: String) = authenticated.async { req => imageCollectionsStore.get(id).map { collections => respond(onlyLatest(collections)) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala index b44f1727908..a30c797fd54 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala @@ -13,6 +13,7 @@ import org.joda.time.DateTime import play.api.libs.json._ import software.amazon.awssdk.enhanced.dynamodb._ import software.amazon.awssdk.enhanced.dynamodb.document.EnhancedDocument +import software.amazon.awssdk.enhanced.dynamodb.model.GetItemEnhancedRequest import software.amazon.awssdk.services.dynamodb.DynamoDbClient import scala.annotation.tailrec @@ -45,18 +46,30 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti private def itemKey(key: String) = Key.builder().partitionValue(key).build() - def get(id: String)(implicit ex: ExecutionContext): Future[JsObject] = Future { + def get(id: String) + (implicit ex: ExecutionContext): Future[JsObject] = Future { + table.getItem( + new GetItemSpec(). + withPrimaryKey(IdKey, id) + ) + } flatMap itemOrNotFound map asJsObject + + def getV2(id: String)(implicit ex: ExecutionContext): Future[JsObject] = Future { table2.getItem(itemKey(id)) } flatMap docOrNotFound map asJsObject - private def get(id: String, key: String)(implicit ex: ExecutionContext): Future[Item] = Future { + private def get(id: String, attribute: String)(implicit ex: ExecutionContext): Future[Item] = Future { table.getItem( new GetItemSpec() .withPrimaryKey(IdKey, id) - .withAttributesToGet(key) + .withAttributesToGet(attribute) ) } flatMap itemOrNotFound +// private def getV2(id: String, key: String)(implicit ex: ExecutionContext): Future[Item] = Future { +// table2.getItem(itemKey(id)). +// } + private def docOrNotFound(docOrNull: EnhancedDocument): Future[EnhancedDocument] = { Option(docOrNull) match { case Some(doc) => Future.successful(doc) @@ -82,13 +95,13 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti table.deleteItem(new DeleteItemSpec().withPrimaryKey(IdKey, id)) } - def booleanGet(id: String, key: String) - (implicit ex: ExecutionContext): Future[Option[Boolean]] = - // TODO: add Option to item as it can be null - get(id, key).map{ item => item.get(key) match { - case b: java.lang.Boolean => Some(b.booleanValue) - case _ => None - }} + def booleanGetV2(id: String, key: String) + (implicit ex: ExecutionContext): Future[Option[Boolean]] = { + Future { + val item = Option(table2.getItem(itemKey(id))) + item.map(_.getBoolean(key).booleanValue()) + } + } def booleanSet(id: String, key: String, value: Boolean) (implicit ex: ExecutionContext): Future[JsObject] = @@ -123,13 +136,14 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti ) } - def setGet(id: String, key: String) - (implicit ex: ExecutionContext): Future[Set[String]] = - get(id, key).map{ item => Option(item.getStringSet(key)) match { - case Some(set) => set.asScala.toSet - case None => Set() - } + def setGetV2(id: String, key: String) + (implicit ex: ExecutionContext): Future[Set[String]] = { + Future { + val item = Option(table2.getItem(itemKey(id))) + item.map(_.getStringSet(key).asScala.toSet) + .getOrElse(Set.empty) } + } def setAdd(id: String, key: String, value: String) (implicit ex: ExecutionContext): Future[JsObject] = @@ -149,9 +163,16 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti def jsonGet(id: String, key: String) - (implicit ex: ExecutionContext): Future[JsValue] = + (implicit ex: ExecutionContext): Future[JsObject] = get(id, key).map(item => asJsObject(item)) + def jsonGetV2(id: String, key: String) + (implicit ex: ExecutionContext): Future[JsObject] = { + Future { + table2.getItem(itemKey(id)) + }.flatMap(docOrNotFound).map(asJsObject) + } + def batchGet(ids: List[String], attributeKey: String) (implicit ex: ExecutionContext, rjs: Reads[T]): Future[Map[String, T]] = { val keyChunkList = ids diff --git a/metadata-editor/app/controllers/EditsController.scala b/metadata-editor/app/controllers/EditsController.scala index 6ee3079fade..9cb94a2cab4 100644 --- a/metadata-editor/app/controllers/EditsController.scala +++ b/metadata-editor/app/controllers/EditsController.scala @@ -73,7 +73,7 @@ class EditsController( // TODO: Think about calling this `overrides` or something that isn't metadata def getAllMetadata(id: String) = auth.async { val emptyResponse = respond(Edits.getEmpty)(editsEntity(id)) - editsStore.get(id) map { dynamoEntry => + editsStore.getV2(id) map { dynamoEntry => dynamoEntry.asOpt[Edits] .map(respond(_)(editsEntity(id))) .getOrElse(emptyResponse) @@ -81,14 +81,14 @@ class EditsController( } def getEdits(id: String) = auth.async { - editsStore.get(id) map { dynamoEntry => + editsStore.getV2(id) map { dynamoEntry => val edits = dynamoEntry.asOpt[Edits] respond(data = edits) } recover { case NoItemFound => NotFound } } def getArchived(id: String) = auth.async { - editsStore.booleanGet(id, Edits.Archived) map { archived => + editsStore.booleanGetV2(id, Edits.Archived) map { archived => respond(archived.getOrElse(false)) } recover { case NoItemFound => respond(false) @@ -114,9 +114,9 @@ class EditsController( def getLabels(id: String) = auth.async { - editsStore.setGet(id, Edits.Labels) + editsStore.setGetV2(id, Edits.Labels) .map(labelsCollection(id, _)) - .map {case (uri, labels) => respondCollection(labels)} recover { + .map {case (_, labels) => respondCollection(labels)} recover { case NoItemFound => respond(Array[String]()) } } @@ -145,7 +145,7 @@ class EditsController( def getMetadata(id: String) = auth.async { - editsStore.jsonGet(id, Edits.Metadata).map { dynamoEntry => + editsStore.getV2(id).map { dynamoEntry => val metadata = (dynamoEntry \ Edits.Metadata).as[ImageMetadata] respond(metadata) } recover { @@ -176,7 +176,8 @@ class EditsController( } def setMetadataFromUsageRights(id: String) = (auth andThen authorisedForEditMetadataOrUploader(id)).async { req => - editsStore.get(id) flatMap { dynamoEntry => + // FIXME figure out why supplier config isn't working on DEV + editsStore.getV2(id) flatMap { dynamoEntry => gridClient.getMetadata(id, auth.getOnBehalfOfPrincipal(req.user)) flatMap { imageMetadata => val edits = dynamoEntry.as[Edits] val originalUserMetadata = edits.metadata @@ -200,12 +201,13 @@ class EditsController( } } } recover { + // TODO think more about this - image may exist but not have been edited?? case NoItemFound => respondError(NotFound, "item-not-found", "Could not find image") } } def getUsageRights(id: String) = auth.async { - editsStore.jsonGet(id, Edits.UsageRights).map { dynamoEntry => + editsStore.getV2(id).map { dynamoEntry => val usageRights = (dynamoEntry \ Edits.UsageRights).as[UsageRights] respond(usageRights) } recover { @@ -225,10 +227,12 @@ class EditsController( editsStore.removeKey(id, Edits.UsageRights).map(publish(id, UpdateImageUserMetadata)).map(edits => Accepted) } - def labelsCollection(id: String, labels: Set[String]): (URI, Seq[EmbeddedEntity[String]]) = + + + private def labelsCollection(id: String, labels: Set[String]): (URI, Seq[EmbeddedEntity[String]]) = (labelsUri(id), labels.map(setUnitEntity(id, Edits.Labels, _)).toSeq) - def metadataAsMap(metadata: ImageMetadata) = { + private def metadataAsMap(metadata: ImageMetadata) = { (Json.toJson(metadata).as[JsObject]).as[Map[String, JsValue]] } From 7a2dec3dc33b7cce94ce8f0b379db141bf91beeb Mon Sep 17 00:00:00 2001 From: Andrew Nowak Date: Wed, 26 Nov 2025 16:28:10 +0000 Subject: [PATCH 024/494] WIP all gets in DynamoDB updated and outdated gets removed --- .../gu/mediaservice/lib/aws/DynamoDB.scala | 39 ------------------- .../controllers/SyndicationController.scala | 12 +++--- metadata-editor/app/lib/Syndication.scala | 4 +- 3 files changed, 8 insertions(+), 47 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala index a30c797fd54..305ca4d9d73 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala @@ -46,14 +46,6 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti private def itemKey(key: String) = Key.builder().partitionValue(key).build() - def get(id: String) - (implicit ex: ExecutionContext): Future[JsObject] = Future { - table.getItem( - new GetItemSpec(). - withPrimaryKey(IdKey, id) - ) - } flatMap itemOrNotFound map asJsObject - def getV2(id: String)(implicit ex: ExecutionContext): Future[JsObject] = Future { table2.getItem(itemKey(id)) } flatMap docOrNotFound map asJsObject @@ -66,10 +58,6 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti ) } flatMap itemOrNotFound -// private def getV2(id: String, key: String)(implicit ex: ExecutionContext): Future[Item] = Future { -// table2.getItem(itemKey(id)). -// } - private def docOrNotFound(docOrNull: EnhancedDocument): Future[EnhancedDocument] = { Option(docOrNull) match { case Some(doc) => Future.successful(doc) @@ -161,18 +149,6 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti new ValueMap().withStringSet(":value", value:_*) ) - - def jsonGet(id: String, key: String) - (implicit ex: ExecutionContext): Future[JsObject] = - get(id, key).map(item => asJsObject(item)) - - def jsonGetV2(id: String, key: String) - (implicit ex: ExecutionContext): Future[JsObject] = { - Future { - table2.getItem(itemKey(id)) - }.flatMap(docOrNotFound).map(asJsObject) - } - def batchGet(ids: List[String], attributeKey: String) (implicit ex: ExecutionContext, rjs: Reads[T]): Future[Map[String, T]] = { val keyChunkList = ids @@ -232,17 +208,6 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti new ValueMap().withStringSet(":value", value) ) - def listGet(id: String, key: String) - (implicit ex: ExecutionContext, reads: Reads[T]): Future[List[T]] = { - - get(id, key) map { item => - Option(item.toJSON) match { - case Some(json) => (Json.parse(json) \ key).as[List[T]] - case None => Nil - } - } - } - def listAdd(id: String, key: String, value: T) (implicit ex: ExecutionContext, tjs: Writes[T], rjs: Reads[T]): Future[List[T]] = { @@ -287,10 +252,6 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti // all we care about is whether it completed. } map (_ => value) - def scan()(implicit ex: ExecutionContext) = Future { - table.scan().iterator.asScala.toList - } map (_.map(asJsObject)) - def scanForId(indexName: String, keyname: String, key: String)(implicit ex: ExecutionContext) = Future { val index = table.getIndex(indexName) diff --git a/metadata-editor/app/controllers/SyndicationController.scala b/metadata-editor/app/controllers/SyndicationController.scala index c2fcb66a8f8..c0b771a3be0 100644 --- a/metadata-editor/app/controllers/SyndicationController.scala +++ b/metadata-editor/app/controllers/SyndicationController.scala @@ -24,7 +24,7 @@ class SyndicationController(auth: Authentication, override val metadataBaseUri: String = config.services.metadataBaseUri def getPhotoshoot(id: String) = auth.async { - editsStore.jsonGet(id, Edits.Photoshoot).map(dynamoEntry => { + editsStore.getV2(id).map(dynamoEntry => { (dynamoEntry \ Edits.Photoshoot).toOption match { case Some(photoshoot) => respond(photoshoot.as[Photoshoot]) case None => respondNotFound("No photoshoot found") @@ -50,11 +50,11 @@ class SyndicationController(auth: Authentication, def getSyndication(id: String): Action[AnyContent] = auth.async { getSyndicationForImage(id) - .map { - case Some(rights) => respond(rights) - // If no rights, send a 404 - no syndication rights for this id. Either id is duff, or it really has none. - case None => NotFound - } + .map { + case Some(rights) => respond(rights) + // If no rights, send a 404 - no syndication rights for this id. Either id is duff, or it really has none. + case None => NotFound + } } def setSyndication(id: String): Action[JsValue] = auth.async(parse.json) { req => { diff --git a/metadata-editor/app/lib/Syndication.scala b/metadata-editor/app/lib/Syndication.scala index 38f484aea3b..3e1ec4e3e62 100644 --- a/metadata-editor/app/lib/Syndication.scala +++ b/metadata-editor/app/lib/Syndication.scala @@ -85,7 +85,7 @@ trait Syndication extends Edit with MessageSubjects with GridLogging { def getSyndicationForImage(id: String) (implicit ec: ExecutionContext): Future[Option[SyndicationRights]] = { - syndicationStore.jsonGet(id, syndicationRightsFieldName) + syndicationStore.getV2(id) // It's OK for the image to _not_ exist in the syndication store, so this needs to be recovered .recover { case NoItemFound => JsNull } .flatMap(dynamoEntry => (dynamoEntry \ syndicationRightsFieldName).toOption match { @@ -156,7 +156,7 @@ trait Syndication extends Edit with MessageSubjects with GridLogging { def getPhotoshootForImage(id: String) (implicit ec: ExecutionContext): Future[Option[Photoshoot]] = - editsStore.jsonGet(id, Edits.Photoshoot) + editsStore.getV2(id) .map(dynamoEntry => (dynamoEntry \ Edits.Photoshoot).toOption map { photoshootJson => photoshootJson.as[Photoshoot] }) From 0b420b91d6a7230746b1bdeac0ad639c020e1b6a Mon Sep 17 00:00:00 2001 From: lindseydew Date: Thu, 4 Dec 2025 16:07:57 +0000 Subject: [PATCH 025/494] Update empty state --- .../gu/mediaservice/lib/aws/DynamoDB.scala | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala index 305ca4d9d73..e2a5b407a77 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala @@ -50,6 +50,13 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti table2.getItem(itemKey(id)) } flatMap docOrNotFound map asJsObject + private def getV2(id: String, attribute: String)(implicit ex: ExecutionContext): Future[EnhancedDocument] = Future { + Option(table2.getItem(itemKey(id))).flatMap(doc => Option.when(doc.isPresent(attribute))(doc)) + } flatMap { + case Some(doc) => Future.successful(doc) + case None => Future.failed(NoItemFound) + } + private def get(id: String, attribute: String)(implicit ex: ExecutionContext): Future[Item] = Future { table.getItem( new GetItemSpec() @@ -84,11 +91,8 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti } def booleanGetV2(id: String, key: String) - (implicit ex: ExecutionContext): Future[Option[Boolean]] = { - Future { - val item = Option(table2.getItem(itemKey(id))) - item.map(_.getBoolean(key).booleanValue()) - } + (implicit ex: ExecutionContext): Future[Boolean] = { + getV2(id, key).map(_.getBoolean(key).booleanValue()) } def booleanSet(id: String, key: String, value: Boolean) @@ -126,11 +130,7 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti def setGetV2(id: String, key: String) (implicit ex: ExecutionContext): Future[Set[String]] = { - Future { - val item = Option(table2.getItem(itemKey(id))) - item.map(_.getStringSet(key).asScala.toSet) - .getOrElse(Set.empty) - } + getV2(id, key).map(_.getStringSet(key).asScala.toSet) } def setAdd(id: String, key: String, value: String) From 85e2cd2c71938d61c789320c32f579ee09d0e451 Mon Sep 17 00:00:00 2001 From: lindseydew Date: Thu, 4 Dec 2025 16:13:46 +0000 Subject: [PATCH 026/494] Update edits controller --- metadata-editor/app/controllers/EditsController.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metadata-editor/app/controllers/EditsController.scala b/metadata-editor/app/controllers/EditsController.scala index 9cb94a2cab4..600d9804da0 100644 --- a/metadata-editor/app/controllers/EditsController.scala +++ b/metadata-editor/app/controllers/EditsController.scala @@ -89,7 +89,7 @@ class EditsController( def getArchived(id: String) = auth.async { editsStore.booleanGetV2(id, Edits.Archived) map { archived => - respond(archived.getOrElse(false)) + respond(archived) } recover { case NoItemFound => respond(false) } From 500bb013bd297edd2f1a77ea776b678f06e448bb Mon Sep 17 00:00:00 2001 From: Andrew Nowak <10963046+andrew-nowak@users.noreply.github.com> Date: Thu, 11 Dec 2025 11:08:22 +0000 Subject: [PATCH 027/494] Apply suggestion from @andrew-nowak --- metadata-editor/app/controllers/EditsController.scala | 1 - 1 file changed, 1 deletion(-) diff --git a/metadata-editor/app/controllers/EditsController.scala b/metadata-editor/app/controllers/EditsController.scala index 600d9804da0..bacf11f7ab3 100644 --- a/metadata-editor/app/controllers/EditsController.scala +++ b/metadata-editor/app/controllers/EditsController.scala @@ -176,7 +176,6 @@ class EditsController( } def setMetadataFromUsageRights(id: String) = (auth andThen authorisedForEditMetadataOrUploader(id)).async { req => - // FIXME figure out why supplier config isn't working on DEV editsStore.getV2(id) flatMap { dynamoEntry => gridClient.getMetadata(id, auth.getOnBehalfOfPrincipal(req.user)) flatMap { imageMetadata => val edits = dynamoEntry.as[Edits] From 6afd18111084d592db977f6c7faaf335cc6eccf5 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Thu, 11 Dec 2025 12:47:59 +0000 Subject: [PATCH 028/494] fix bundling --- .github/workflows/ci.yml | 2 +- .../image-embedder-lambda.test.ts.snap | 2 +- cdk/lib/image-embedder-lambda.ts | 2 +- image-embedder-lambda/index.js | 32 +++++++++++++++++++ image-embedder-lambda/package.json | 2 +- .../src/{handler.ts => index.ts} | 2 +- image-embedder-lambda/tsconfig.json | 4 +-- .../embedder-deploy/{build.sh => bundle.sh} | 4 +-- 8 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 image-embedder-lambda/index.js rename image-embedder-lambda/src/{handler.ts => index.ts} (88%) rename scripts/embedder-deploy/{build.sh => bundle.sh} (55%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80f3fec3d98..d94a1bd736e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,7 +81,7 @@ jobs: - name: Image embedder cdk run: ./scripts/embedder-deploy/cdk.sh - name: Image embedder bundling - run: ./scripts/embedder-deploy/build.sh + run: ./scripts/embedder-deploy/bundle.sh # - uses: guardian/actions-riff-raff@v4 # env: # GU_RIFF_RAFF_ROLE_ARN: ${{ secrets.GU_RIFF_RAFF_ROLE_ARN }} diff --git a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap index d198a6652c0..b65967846be 100644 --- a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap +++ b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap @@ -40,7 +40,7 @@ exports[`The MediaService stack matches the snapshot 1`] = ` }, }, "FunctionName": "image-embedder-TEST", - "Handler": "dist.handler", + "Handler": "index.handler", "LoggingConfig": { "LogFormat": "JSON", }, diff --git a/cdk/lib/image-embedder-lambda.ts b/cdk/lib/image-embedder-lambda.ts index 12000c339b7..fbaf10e146a 100644 --- a/cdk/lib/image-embedder-lambda.ts +++ b/cdk/lib/image-embedder-lambda.ts @@ -19,7 +19,7 @@ export class MediaService extends GuStack { functionName: `image-embedder-${props.stage}`, runtime: LAMBDA_NODE_VERSION, architecture: Architecture.ARM_64, - handler: 'dist.handler', + handler: 'index.handler', app: 'image-embedder-lambda', }, ); diff --git a/image-embedder-lambda/index.js b/image-embedder-lambda/index.js new file mode 100644 index 00000000000..7348e0167dc --- /dev/null +++ b/image-embedder-lambda/index.js @@ -0,0 +1,32 @@ +"use strict"; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// src/index.ts +var index_exports = {}; +__export(index_exports, { + handler: () => handler +}); +module.exports = __toCommonJS(index_exports); +var handler = async (event, context) => { + console.log("Hello world!"); +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (module.exports = { + handler +}); diff --git a/image-embedder-lambda/package.json b/image-embedder-lambda/package.json index 15814798cbe..cb057814c17 100644 --- a/image-embedder-lambda/package.json +++ b/image-embedder-lambda/package.json @@ -5,7 +5,7 @@ "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "build": "esbuild src/handler.ts --bundle --platform=node --target=node24 --outfile=dist/handler.js" + "bundle": "esbuild src/index.ts --bundle --platform=node --target=node24 --format=cjs --outfile=index.js" }, "author": "", "license": "ISC", diff --git a/image-embedder-lambda/src/handler.ts b/image-embedder-lambda/src/index.ts similarity index 88% rename from image-embedder-lambda/src/handler.ts rename to image-embedder-lambda/src/index.ts index bd6b7bb6a69..4b638df83e5 100644 --- a/image-embedder-lambda/src/handler.ts +++ b/image-embedder-lambda/src/index.ts @@ -6,7 +6,7 @@ // Whether it's worth it to do that // We can also reuse the lambda for the backfill -import { Context, S3Event, APIGatewayProxyEvent } from 'aws-lambda'; +import { Context, S3Event } from 'aws-lambda'; export const handler = async (event: S3Event, context: Context) => { console.log('Hello world!'); diff --git a/image-embedder-lambda/tsconfig.json b/image-embedder-lambda/tsconfig.json index f5f15ba84ef..2d65dcf0ecd 100644 --- a/image-embedder-lambda/tsconfig.json +++ b/image-embedder-lambda/tsconfig.json @@ -5,7 +5,7 @@ /* Basic Options */ // "incremental": true, /* Enable incremental compilation */ - "target": "es2020", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ + "target": "esnext", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ "lib": ["esnext"], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ @@ -42,7 +42,7 @@ // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ /* Module Resolution Options */ - "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + "moduleResolution": "nodenext", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ diff --git a/scripts/embedder-deploy/build.sh b/scripts/embedder-deploy/bundle.sh similarity index 55% rename from scripts/embedder-deploy/build.sh rename to scripts/embedder-deploy/bundle.sh index 9521e35f664..d56ed2aa24b 100755 --- a/scripts/embedder-deploy/build.sh +++ b/scripts/embedder-deploy/bundle.sh @@ -5,6 +5,6 @@ set -e ( cd image-embedder-lambda npm install - npm run build - zip -r ../image-embedder.zip dist + npm run bundle + zip -r ../image-embedder.zip index.js ) \ No newline at end of file From 9f6cd76f05f6c56208c12be0ff0808b027b0a6a0 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Thu, 11 Dec 2025 16:30:44 +0000 Subject: [PATCH 029/494] add secret for api key --- .../image-embedder-lambda.test.ts.snap | 82 + cdk/lib/image-embedder-lambda.ts | 36 +- image-embedder-lambda/package-lock.json | 1896 +++++++++++++++++ image-embedder-lambda/package.json | 6 + image-embedder-lambda/src/index.ts | 77 +- 5 files changed, 2092 insertions(+), 5 deletions(-) diff --git a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap index b65967846be..2eb53ca37f2 100644 --- a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap +++ b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap @@ -35,6 +35,26 @@ exports[`The MediaService stack matches the snapshot 1`] = ` "Environment": { "Variables": { "APP": "image-embedder-lambda", + "GRID_API_KEY": { + "Fn::Join": [ + "", + [ + "{{resolve:secretsmanager:arn:", + { + "Ref": "AWS::Partition", + }, + ":secretsmanager:", + { + "Ref": "AWS::Region", + }, + ":", + { + "Ref": "AWS::AccountId", + }, + ":secret:media-service/TEST/image-embedder-lambda/api-key:SecretString:::}}", + ], + ], + }, "STACK": "media-service", "STAGE": "TEST", }, @@ -231,6 +251,68 @@ exports[`The MediaService stack matches the snapshot 1`] = ` }, "Type": "AWS::IAM::Policy", }, + "imageEmbedder9F00A33D": { + "DeletionPolicy": "Delete", + "Properties": { + "QueueName": "image-embedder-TEST", + "RedrivePolicy": { + "deadLetterTargetArn": { + "Fn::GetAtt": [ + "imageEmbedderDLQ4A6F48C5", + "Arn", + ], + }, + "maxReceiveCount": 3, + }, + "Tags": [ + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/grid", + }, + { + "Key": "Stack", + "Value": "media-service", + }, + { + "Key": "Stage", + "Value": "TEST", + }, + ], + "VisibilityTimeout": 60, + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, + "imageEmbedderDLQ4A6F48C5": { + "DeletionPolicy": "Delete", + "Properties": { + "QueueName": "image-embedder-DLQ-TEST", + "Tags": [ + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/grid", + }, + { + "Key": "Stack", + "Value": "media-service", + }, + { + "Key": "Stage", + "Value": "TEST", + }, + ], + }, + "Type": "AWS::SQS::Queue", + "UpdateReplacePolicy": "Delete", + }, }, } `; diff --git a/cdk/lib/image-embedder-lambda.ts b/cdk/lib/image-embedder-lambda.ts index fbaf10e146a..f30a2a07fed 100644 --- a/cdk/lib/image-embedder-lambda.ts +++ b/cdk/lib/image-embedder-lambda.ts @@ -2,8 +2,11 @@ import type { GuStackProps } from "@guardian/cdk/lib/constructs/core"; import { GuStack } from "@guardian/cdk/lib/constructs/core"; import { GuLambdaFunction } from "@guardian/cdk/lib/constructs/lambda"; import type { App } from "aws-cdk-lib"; -import { aws_lambda as lambda } from "aws-cdk-lib"; +import { Duration, aws_lambda as lambda } from "aws-cdk-lib"; import { Architecture } from "aws-cdk-lib/aws-lambda"; +// import { SqsEventSource } from "aws-cdk-lib/aws-lambda-event-sources"; +import { Secret } from "aws-cdk-lib/aws-secretsmanager"; +import { Queue } from "aws-cdk-lib/aws-sqs"; export class MediaService extends GuStack { constructor(scope: App, id: string, props: GuStackProps) { @@ -11,6 +14,13 @@ export class MediaService extends GuStack { const LAMBDA_NODE_VERSION = lambda.Runtime.NODEJS_24_X; + const imageEmbedderApiKey = Secret.fromSecretNameV2( + this, + 'imageEmbedderApiKey', + `media-service/${props.stage}/image-embedder-lambda/api-key`, + ); + + // const imageEmbedderLambda = new GuLambdaFunction( this, 'ImageEmbedderHandler', @@ -21,8 +31,32 @@ export class MediaService extends GuStack { architecture: Architecture.ARM_64, handler: 'index.handler', app: 'image-embedder-lambda', + environment: { + "GRID_API_KEY": imageEmbedderApiKey.secretValue.toString() + } }, ); + const imageEmbedderDLQ = new Queue(this, 'imageEmbedderDLQ', { + queueName: `image-embedder-DLQ-${this.stage}`, + }); + + // const imageEmbedderQueue = + new Queue( + this, + 'imageEmbedder', + { + queueName: `image-embedder-${this.stage}`, + visibilityTimeout: Duration.seconds(60), + deadLetterQueue: { + queue: imageEmbedderDLQ, + maxReceiveCount: 3, + }, + }, + ); + // imageEmbedderLambda.addEventSource( + // new SqsEventSource(imageEmbedderQueue), + // ); + } } \ No newline at end of file diff --git a/image-embedder-lambda/package-lock.json b/image-embedder-lambda/package-lock.json index bed2e2beadf..82a4585f6a5 100644 --- a/image-embedder-lambda/package-lock.json +++ b/image-embedder-lambda/package-lock.json @@ -8,11 +8,1025 @@ "name": "image-embedder-lambda", "version": "1.0.0", "license": "ISC", + "dependencies": { + "@aws-sdk/client-bedrock-runtime": "^3.948.0", + "@aws-sdk/client-s3": "^3.948.0", + "node-fetch": "^3.3.2" + }, "devDependencies": { "@types/aws-lambda": "^8.10.159", + "@types/node": "^25.0.0", "esbuild": "0.27.0" } }, + "node_modules/@aws-crypto/crc32": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", + "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/crc32c": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz", + "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha1-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-5.2.0.tgz", + "integrity": "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", + "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-js": "^5.2.0", + "@aws-crypto/supports-web-crypto": "^5.2.0", + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "@aws-sdk/util-locate-window": "^3.0.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/sha256-js": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", + "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/util": "^5.2.0", + "@aws-sdk/types": "^3.222.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@aws-crypto/supports-web-crypto": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", + "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", + "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "^3.222.0", + "@smithy/util-utf8": "^2.0.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", + "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", + "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", + "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^2.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@aws-sdk/client-bedrock-runtime": { + "version": "3.948.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-bedrock-runtime/-/client-bedrock-runtime-3.948.0.tgz", + "integrity": "sha512-JRlqANr0wY63ZXZPKaWIoH0zYXsllROynPVj8XdOFwiO/pRr/2hol8popfMhD7T5Zb6yZQ/FM8Tu5Mc61l2HHQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.947.0", + "@aws-sdk/credential-provider-node": "3.948.0", + "@aws-sdk/eventstream-handler-node": "3.936.0", + "@aws-sdk/middleware-eventstream": "3.936.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.948.0", + "@aws-sdk/middleware-user-agent": "3.947.0", + "@aws-sdk/middleware-websocket": "3.936.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/token-providers": "3.948.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.947.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.7", + "@smithy/eventstream-serde-browser": "^4.2.5", + "@smithy/eventstream-serde-config-resolver": "^4.3.5", + "@smithy/eventstream-serde-node": "^4.2.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.14", + "@smithy/middleware-retry": "^4.4.14", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.10", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.13", + "@smithy/util-defaults-mode-node": "^4.2.16", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-stream": "^4.5.6", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-s3": { + "version": "3.948.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.948.0.tgz", + "integrity": "sha512-uvEjds8aYA9SzhBS8RKDtsDUhNV9VhqKiHTcmvhM7gJO92q0WTn8/QeFTdNyLc6RxpiDyz+uBxS7PcdNiZzqfA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha1-browser": "5.2.0", + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.947.0", + "@aws-sdk/credential-provider-node": "3.948.0", + "@aws-sdk/middleware-bucket-endpoint": "3.936.0", + "@aws-sdk/middleware-expect-continue": "3.936.0", + "@aws-sdk/middleware-flexible-checksums": "3.947.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-location-constraint": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.948.0", + "@aws-sdk/middleware-sdk-s3": "3.947.0", + "@aws-sdk/middleware-ssec": "3.936.0", + "@aws-sdk/middleware-user-agent": "3.947.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/signature-v4-multi-region": "3.947.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.947.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.7", + "@smithy/eventstream-serde-browser": "^4.2.5", + "@smithy/eventstream-serde-config-resolver": "^4.3.5", + "@smithy/eventstream-serde-node": "^4.2.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-blob-browser": "^4.2.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/hash-stream-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/md5-js": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.14", + "@smithy/middleware-retry": "^4.4.14", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.10", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.13", + "@smithy/util-defaults-mode-node": "^4.2.16", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-stream": "^4.5.6", + "@smithy/util-utf8": "^4.2.0", + "@smithy/util-waiter": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-sso": { + "version": "3.948.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.948.0.tgz", + "integrity": "sha512-iWjchXy8bIAVBUsKnbfKYXRwhLgRg3EqCQ5FTr3JbR+QR75rZm4ZOYXlvHGztVTmtAZ+PQVA1Y4zO7v7N87C0A==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.947.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.948.0", + "@aws-sdk/middleware-user-agent": "3.947.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.947.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.7", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.14", + "@smithy/middleware-retry": "^4.4.14", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.10", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.13", + "@smithy/util-defaults-mode-node": "^4.2.16", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/core": { + "version": "3.947.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.947.0.tgz", + "integrity": "sha512-Khq4zHhuAkvCFuFbgcy3GrZTzfSX7ZIjIcW1zRDxXRLZKRtuhnZdonqTUfaWi5K42/4OmxkYNpsO7X7trQOeHw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@aws-sdk/xml-builder": "3.930.0", + "@smithy/core": "^3.18.7", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/signature-v4": "^5.3.5", + "@smithy/smithy-client": "^4.9.10", + "@smithy/types": "^4.9.0", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-env": { + "version": "3.947.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.947.0.tgz", + "integrity": "sha512-VR2V6dRELmzwAsCpK4GqxUi6UW5WNhAXS9F9AzWi5jvijwJo3nH92YNJUP4quMpgFZxJHEWyXLWgPjh9u0zYOA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.947.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-http": { + "version": "3.947.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.947.0.tgz", + "integrity": "sha512-inF09lh9SlHj63Vmr5d+LmwPXZc2IbK8lAruhOr3KLsZAIHEgHgGPXWDC2ukTEMzg0pkexQ6FOhXXad6klK4RA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.947.0", + "@aws-sdk/types": "3.936.0", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.10", + "@smithy/types": "^4.9.0", + "@smithy/util-stream": "^4.5.6", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.948.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.948.0.tgz", + "integrity": "sha512-Cl//Qh88e8HBL7yYkJNpF5eq76IO6rq8GsatKcfVBm7RFVxCqYEPSSBtkHdbtNwQdRQqAMXc6E/lEB/CZUDxnA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.947.0", + "@aws-sdk/credential-provider-env": "3.947.0", + "@aws-sdk/credential-provider-http": "3.947.0", + "@aws-sdk/credential-provider-login": "3.948.0", + "@aws-sdk/credential-provider-process": "3.947.0", + "@aws-sdk/credential-provider-sso": "3.948.0", + "@aws-sdk/credential-provider-web-identity": "3.948.0", + "@aws-sdk/nested-clients": "3.948.0", + "@aws-sdk/types": "3.936.0", + "@smithy/credential-provider-imds": "^4.2.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-login": { + "version": "3.948.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.948.0.tgz", + "integrity": "sha512-gcKO2b6eeTuZGp3Vvgr/9OxajMrD3W+FZ2FCyJox363ZgMoYJsyNid1vuZrEuAGkx0jvveLXfwiVS0UXyPkgtw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.947.0", + "@aws-sdk/nested-clients": "3.948.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-node": { + "version": "3.948.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.948.0.tgz", + "integrity": "sha512-ep5vRLnrRdcsP17Ef31sNN4g8Nqk/4JBydcUJuFRbGuyQtrZZrVT81UeH2xhz6d0BK6ejafDB9+ZpBjXuWT5/Q==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.947.0", + "@aws-sdk/credential-provider-http": "3.947.0", + "@aws-sdk/credential-provider-ini": "3.948.0", + "@aws-sdk/credential-provider-process": "3.947.0", + "@aws-sdk/credential-provider-sso": "3.948.0", + "@aws-sdk/credential-provider-web-identity": "3.948.0", + "@aws-sdk/types": "3.936.0", + "@smithy/credential-provider-imds": "^4.2.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-process": { + "version": "3.947.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.947.0.tgz", + "integrity": "sha512-WpanFbHe08SP1hAJNeDdBDVz9SGgMu/gc0XJ9u3uNpW99nKZjDpvPRAdW7WLA4K6essMjxWkguIGNOpij6Do2Q==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.947.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.948.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.948.0.tgz", + "integrity": "sha512-gqLhX1L+zb/ZDnnYbILQqJ46j735StfWV5PbDjxRzBKS7GzsiYoaf6MyHseEopmWrez5zl5l6aWzig7UpzSeQQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-sso": "3.948.0", + "@aws-sdk/core": "3.947.0", + "@aws-sdk/token-providers": "3.948.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.948.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.948.0.tgz", + "integrity": "sha512-MvYQlXVoJyfF3/SmnNzOVEtANRAiJIObEUYYyjTqKZTmcRIVVky0tPuG26XnB8LmTYgtESwJIZJj/Eyyc9WURQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.947.0", + "@aws-sdk/nested-clients": "3.948.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/eventstream-handler-node": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/eventstream-handler-node/-/eventstream-handler-node-3.936.0.tgz", + "integrity": "sha512-4zIbhdRmol2KosIHmU31ATvNP0tkJhDlRj9GuawVJoEnMvJA1pd2U3SRdiOImJU3j8pT46VeS4YMmYxfjGHByg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/eventstream-codec": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-bucket-endpoint": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.936.0.tgz", + "integrity": "sha512-XLSVVfAorUxZh6dzF+HTOp4R1B5EQcdpGcPliWr0KUj2jukgjZEcqbBmjyMF/p9bmyQsONX80iURF1HLAlW0qg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-arn-parser": "3.893.0", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-config-provider": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-eventstream": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-eventstream/-/middleware-eventstream-3.936.0.tgz", + "integrity": "sha512-XQSH8gzLkk8CDUDxyt4Rdm9owTpRIPdtg2yw9Y2Wl5iSI55YQSiC3x8nM3c4Y4WqReJprunFPK225ZUDoYCfZA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-expect-continue": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.936.0.tgz", + "integrity": "sha512-Eb4ELAC23bEQLJmUMYnPWcjD3FZIsmz2svDiXEcxRkQU9r7NRID7pM7C5NPH94wOfiCk0b2Y8rVyFXW0lGQwbA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-flexible-checksums": { + "version": "3.947.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.947.0.tgz", + "integrity": "sha512-kXXxS2raNESNO+zR0L4YInVjhcGGNI2Mx0AE1ThRhDkAt2se3a+rGf9equ9YvOqA1m8Jl/GSI8cXYvSxXmS9Ag==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@aws-crypto/crc32c": "5.2.0", + "@aws-crypto/util": "5.2.0", + "@aws-sdk/core": "3.947.0", + "@aws-sdk/types": "3.936.0", + "@smithy/is-array-buffer": "^4.2.0", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-stream": "^4.5.6", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-host-header": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.936.0.tgz", + "integrity": "sha512-tAaObaAnsP1XnLGndfkGWFuzrJYuk9W0b/nLvol66t8FZExIAf/WdkT2NNAWOYxljVs++oHnyHBCxIlaHrzSiw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-location-constraint": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.936.0.tgz", + "integrity": "sha512-SCMPenDtQMd9o5da9JzkHz838w3327iqXk3cbNnXWqnNRx6unyW8FL0DZ84gIY12kAyVHz5WEqlWuekc15ehfw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-logger": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.936.0.tgz", + "integrity": "sha512-aPSJ12d3a3Ea5nyEnLbijCaaYJT2QjQ9iW+zGh5QcZYXmOGWbKVyPSxmVOboZQG+c1M8t6d2O7tqrwzIq8L8qw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.948.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.948.0.tgz", + "integrity": "sha512-Qa8Zj+EAqA0VlAVvxpRnpBpIWJI9KUwaioY1vkeNVwXPlNaz9y9zCKVM9iU9OZ5HXpoUg6TnhATAHXHAE8+QsQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@aws/lambda-invoke-store": "^0.2.2", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-s3": { + "version": "3.947.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.947.0.tgz", + "integrity": "sha512-DS2tm5YBKhPW2PthrRBDr6eufChbwXe0NjtTZcYDfUCXf0OR+W6cIqyKguwHMJ+IyYdey30AfVw9/Lb5KB8U8A==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.947.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-arn-parser": "3.893.0", + "@smithy/core": "^3.18.7", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/signature-v4": "^5.3.5", + "@smithy/smithy-client": "^4.9.10", + "@smithy/types": "^4.9.0", + "@smithy/util-config-provider": "^4.2.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-stream": "^4.5.6", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-ssec": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.936.0.tgz", + "integrity": "sha512-/GLC9lZdVp05ozRik5KsuODR/N7j+W+2TbfdFL3iS+7un+gnP6hC8RDOZd6WhpZp7drXQ9guKiTAxkZQwzS8DA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.947.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.947.0.tgz", + "integrity": "sha512-7rpKV8YNgCP2R4F9RjWZFcD2R+SO/0R4VHIbY9iZJdH2MzzJ8ZG7h8dZ2m8QkQd1fjx4wrFJGGPJUTYXPV3baA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.947.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@smithy/core": "^3.18.7", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/middleware-websocket": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-websocket/-/middleware-websocket-3.936.0.tgz", + "integrity": "sha512-bPe3rqeugyj/MmjP0yBSZox2v1Wa8Dv39KN+RxVbQroLO8VUitBo6xyZ0oZebhZ5sASwSg58aDcMlX0uFLQnTA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-format-url": "3.936.0", + "@smithy/eventstream-codec": "^4.2.5", + "@smithy/eventstream-serde-browser": "^4.2.5", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/protocol-http": "^5.3.5", + "@smithy/signature-v4": "^5.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-hex-encoding": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@aws-sdk/nested-clients": { + "version": "3.948.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.948.0.tgz", + "integrity": "sha512-zcbJfBsB6h254o3NuoEkf0+UY1GpE9ioiQdENWv7odo69s8iaGBEQ4BDpsIMqcuiiUXw1uKIVNxCB1gUGYz8lw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.947.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.948.0", + "@aws-sdk/middleware-user-agent": "3.947.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.947.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.7", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.14", + "@smithy/middleware-retry": "^4.4.14", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.10", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.13", + "@smithy/util-defaults-mode-node": "^4.2.16", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/region-config-resolver": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.936.0.tgz", + "integrity": "sha512-wOKhzzWsshXGduxO4pqSiNyL9oUtk4BEvjWm9aaq6Hmfdoydq6v6t0rAGHWPjFwy9z2haovGRi3C8IxdMB4muw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/signature-v4-multi-region": { + "version": "3.947.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.947.0.tgz", + "integrity": "sha512-UaYmzoxf9q3mabIA2hc4T6x5YSFUG2BpNjAZ207EA1bnQMiK+d6vZvb83t7dIWL/U1de1sGV19c1C81Jf14rrA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-sdk-s3": "3.947.0", + "@aws-sdk/types": "3.936.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/signature-v4": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/token-providers": { + "version": "3.948.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.948.0.tgz", + "integrity": "sha512-V487/kM4Teq5dcr1t5K6eoUKuqlGr9FRWL3MIMukMERJXHZvio6kox60FZ/YtciRHRI75u14YUqm2Dzddcu3+A==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.947.0", + "@aws-sdk/nested-clients": "3.948.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/types": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.936.0.tgz", + "integrity": "sha512-uz0/VlMd2pP5MepdrHizd+T+OKfyK4r3OA9JI+L/lPKg0YFQosdJNCKisr6o70E3dh8iMpFYxF1UN/4uZsyARg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-arn-parser": { + "version": "3.893.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.893.0.tgz", + "integrity": "sha512-u8H4f2Zsi19DGnwj5FSZzDMhytYF/bCh37vAtBsn3cNDL3YG578X5oc+wSX54pM3tOxS+NY7tvOAo52SW7koUA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-endpoints": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.936.0.tgz", + "integrity": "sha512-0Zx3Ntdpu+z9Wlm7JKUBOzS9EunwKAb4KdGUQQxDqh5Lc3ta5uBoub+FgmVuzwnmBu9U1Os8UuwVTH0Lgu+P5w==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-endpoints": "^3.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-format-url": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-format-url/-/util-format-url-3.936.0.tgz", + "integrity": "sha512-MS5eSEtDUFIAMHrJaMERiHAvDPdfxc/T869ZjDNFAIiZhyc037REw0aoTNeimNXDNy2txRNZJaAUn/kE4RwN+g==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/querystring-builder": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-locate-window": { + "version": "3.893.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.893.0.tgz", + "integrity": "sha512-T89pFfgat6c8nMmpI8eKjBcDcgJq36+m9oiXbcUzeU55MP9ZuGgBomGjGnHaEyF36jenW9gmg3NfZDm0AO2XPg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.936.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.936.0.tgz", + "integrity": "sha512-eZ/XF6NxMtu+iCma58GRNRxSq4lHo6zHQLOZRIeL/ghqYJirqHdenMOwrzPettj60KWlv827RVebP9oNVrwZbw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.936.0", + "@smithy/types": "^4.9.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.947.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.947.0.tgz", + "integrity": "sha512-+vhHoDrdbb+zerV4noQk1DHaUMNzWFWPpPYjVTwW2186k5BEJIecAMChYkghRrBVJ3KPWP1+JnZwOd72F3d4rQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-user-agent": "3.947.0", + "@aws-sdk/types": "3.936.0", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/xml-builder": { + "version": "3.930.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.930.0.tgz", + "integrity": "sha512-YIfkD17GocxdmlUVc3ia52QhcWuRIUJonbF8A2CYfcWNV3HzvAqpcPeC0bYUhkK+8e8YO1ARnLKZQE0TlwzorA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "fast-xml-parser": "5.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws/lambda-invoke-store": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.2.2.tgz", + "integrity": "sha512-C0NBLsIqzDIae8HFw9YIrIBsbc0xTiOtt7fAukGPnqQ/+zZNaq+4jhuccltK0QuWHBnNm/a6kLIRA6GFiM10eg==", + "license": "Apache-2.0", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.0.tgz", @@ -455,6 +1469,738 @@ "node": ">=18" } }, + "node_modules/@smithy/abort-controller": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.5.tgz", + "integrity": "sha512-j7HwVkBw68YW8UmFRcjZOmssE77Rvk0GWAIN1oFBhsaovQmZWYCIcGa9/pwRB0ExI8Sk9MWNALTjftjHZea7VA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/chunked-blob-reader": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.2.0.tgz", + "integrity": "sha512-WmU0TnhEAJLWvfSeMxBNe5xtbselEO8+4wG0NtZeL8oR21WgH1xiO37El+/Y+H/Ie4SCwBy3MxYWmOYaGgZueA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/chunked-blob-reader-native": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.2.1.tgz", + "integrity": "sha512-lX9Ay+6LisTfpLid2zZtIhSEjHMZoAR5hHCR4H7tBz/Zkfr5ea8RcQ7Tk4mi0P76p4cN+Btz16Ffno7YHpKXnQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-base64": "^4.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/config-resolver": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.3.tgz", + "integrity": "sha512-ezHLe1tKLUxDJo2LHtDuEDyWXolw8WGOR92qb4bQdWq/zKenO5BvctZGrVJBK08zjezSk7bmbKFOXIVyChvDLw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-config-provider": "^4.2.0", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/core": { + "version": "3.18.7", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.18.7.tgz", + "integrity": "sha512-axG9MvKhMWOhFbvf5y2DuyTxQueO0dkedY9QC3mAfndLosRI/9LJv8WaL0mw7ubNhsO4IuXX9/9dYGPFvHrqlw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/middleware-serde": "^4.2.6", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-stream": "^4.5.6", + "@smithy/util-utf8": "^4.2.0", + "@smithy/uuid": "^1.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/credential-provider-imds": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.5.tgz", + "integrity": "sha512-BZwotjoZWn9+36nimwm/OLIcVe+KYRwzMjfhd4QT7QxPm9WY0HiOV8t/Wlh+HVUif0SBVV7ksq8//hPaBC/okQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-codec": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.2.5.tgz", + "integrity": "sha512-Ogt4Zi9hEbIP17oQMd68qYOHUzmH47UkK7q7Gl55iIm9oKt27MUGrC5JfpMroeHjdkOliOA4Qt3NQ1xMq/nrlA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/crc32": "5.2.0", + "@smithy/types": "^4.9.0", + "@smithy/util-hex-encoding": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-browser": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.2.5.tgz", + "integrity": "sha512-HohfmCQZjppVnKX2PnXlf47CW3j92Ki6T/vkAT2DhBR47e89pen3s4fIa7otGTtrVxmj7q+IhH0RnC5kpR8wtw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-config-resolver": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.3.5.tgz", + "integrity": "sha512-ibjQjM7wEXtECiT6my1xfiMH9IcEczMOS6xiCQXoUIYSj5b1CpBbJ3VYbdwDy8Vcg5JHN7eFpOCGk8nyZAltNQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-node": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.2.5.tgz", + "integrity": "sha512-+elOuaYx6F2H6x1/5BQP5ugv12nfJl66GhxON8+dWVUEDJ9jah/A0tayVdkLRP0AeSac0inYkDz5qBFKfVp2Gg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-serde-universal": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/eventstream-serde-universal": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.2.5.tgz", + "integrity": "sha512-G9WSqbST45bmIFaeNuP/EnC19Rhp54CcVdX9PDL1zyEB514WsDVXhlyihKlGXnRycmHNmVv88Bvvt4EYxWef/Q==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/eventstream-codec": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/fetch-http-handler": { + "version": "5.3.6", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.6.tgz", + "integrity": "sha512-3+RG3EA6BBJ/ofZUeTFJA7mHfSYrZtQIrDP9dI8Lf7X6Jbos2jptuLrAAteDiFVrmbEmLSuRG/bUKzfAXk7dhg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.5", + "@smithy/querystring-builder": "^4.2.5", + "@smithy/types": "^4.9.0", + "@smithy/util-base64": "^4.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-blob-browser": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.2.6.tgz", + "integrity": "sha512-8P//tA8DVPk+3XURk2rwcKgYwFvwGwmJH/wJqQiSKwXZtf/LiZK+hbUZmPj/9KzM+OVSwe4o85KTp5x9DUZTjw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/chunked-blob-reader": "^5.2.0", + "@smithy/chunked-blob-reader-native": "^4.2.1", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-node": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.5.tgz", + "integrity": "sha512-DpYX914YOfA3UDT9CN1BM787PcHfWRBB43fFGCYrZFUH0Jv+5t8yYl+Pd5PW4+QzoGEDvn5d5QIO4j2HyYZQSA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/hash-stream-node": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.2.5.tgz", + "integrity": "sha512-6+do24VnEyvWcGdHXomlpd0m8bfZePpUKBy7m311n+JuRwug8J4dCanJdTymx//8mi0nlkflZBvJe+dEO/O12Q==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/invalid-dependency": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.5.tgz", + "integrity": "sha512-2L2erASEro1WC5nV+plwIMxrTXpvpfzl4e+Nre6vBVRR2HKeGGcvpJyyL3/PpiSg+cJG2KpTmZmq934Olb6e5A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/is-array-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.2.0.tgz", + "integrity": "sha512-DZZZBvC7sjcYh4MazJSGiWMI2L7E0oCiRHREDzIxi/M2LY79/21iXt6aPLHge82wi5LsuRF5A06Ds3+0mlh6CQ==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/md5-js": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.2.5.tgz", + "integrity": "sha512-Bt6jpSTMWfjCtC0s79gZ/WZ1w90grfmopVOWqkI2ovhjpD5Q2XRXuecIPB9689L2+cCySMbaXDhBPU56FKNDNg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-content-length": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.5.tgz", + "integrity": "sha512-Y/RabVa5vbl5FuHYV2vUCwvh/dqzrEY/K2yWPSqvhFUwIY0atLqO4TienjBXakoy4zrKAMCZwg+YEqmH7jaN7A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-endpoint": { + "version": "4.3.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.3.14.tgz", + "integrity": "sha512-v0q4uTKgBM8dsqGjqsabZQyH85nFaTnFcgpWU1uydKFsdyyMzfvOkNum9G7VK+dOP01vUnoZxIeRiJ6uD0kjIg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.18.7", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-middleware": "^4.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-retry": { + "version": "4.4.14", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.14.tgz", + "integrity": "sha512-Z2DG8Ej7FyWG1UA+7HceINtSLzswUgs2np3sZX0YBBxCt+CXG4QUxv88ZDS3+2/1ldW7LqtSY1UO/6VQ1pND8Q==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/service-error-classification": "^4.2.5", + "@smithy/smithy-client": "^4.9.10", + "@smithy/types": "^4.9.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/uuid": "^1.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-serde": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.6.tgz", + "integrity": "sha512-VkLoE/z7e2g8pirwisLz8XJWedUSY8my/qrp81VmAdyrhi94T+riBfwP+AOEEFR9rFTSonC/5D2eWNmFabHyGQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/middleware-stack": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.5.tgz", + "integrity": "sha512-bYrutc+neOyWxtZdbB2USbQttZN0mXaOyYLIsaTbJhFsfpXyGWUxJpEuO1rJ8IIJm2qH4+xJT0mxUSsEDTYwdQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-config-provider": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.5.tgz", + "integrity": "sha512-UTurh1C4qkVCtqggI36DGbLB2Kv8UlcFdMXDcWMbqVY2uRg0XmT9Pb4Vj6oSQ34eizO1fvR0RnFV4Axw4IrrAg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/node-http-handler": { + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.5.tgz", + "integrity": "sha512-CMnzM9R2WqlqXQGtIlsHMEZfXKJVTIrqCNoSd/QpAyp+Dw0a1Vps13l6ma1fH8g7zSPNsA59B/kWgeylFuA/lw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/querystring-builder": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/property-provider": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.5.tgz", + "integrity": "sha512-8iLN1XSE1rl4MuxvQ+5OSk/Zb5El7NJZ1td6Tn+8dQQHIjp59Lwl6bd0+nzw6SKm2wSSriH2v/I9LPzUic7EOg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/protocol-http": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.5.tgz", + "integrity": "sha512-RlaL+sA0LNMp03bf7XPbFmT5gN+w3besXSWMkA8rcmxLSVfiEXElQi4O2IWwPfxzcHkxqrwBFMbngB8yx/RvaQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-builder": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.5.tgz", + "integrity": "sha512-y98otMI1saoajeik2kLfGyRp11e5U/iJYH/wLCh3aTV/XutbGT9nziKGkgCaMD1ghK7p6htHMm6b6scl9JRUWg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "@smithy/util-uri-escape": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/querystring-parser": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.5.tgz", + "integrity": "sha512-031WCTdPYgiQRYNPXznHXof2YM0GwL6SeaSyTH/P72M1Vz73TvCNH2Nq8Iu2IEPq9QP2yx0/nrw5YmSeAi/AjQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/service-error-classification": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.5.tgz", + "integrity": "sha512-8fEvK+WPE3wUAcDvqDQG1Vk3ANLR8Px979te96m84CbKAjBVf25rPYSzb4xU4hlTyho7VhOGnh5i62D/JVF0JQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/shared-ini-file-loader": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.0.tgz", + "integrity": "sha512-5WmZ5+kJgJDjwXXIzr1vDTG+RhF9wzSODQBfkrQ2VVkYALKGvZX1lgVSxEkgicSAFnFhPj5rudJV0zoinqS0bA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/signature-v4": { + "version": "5.3.5", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.5.tgz", + "integrity": "sha512-xSUfMu1FT7ccfSXkoLl/QRQBi2rOvi3tiBZU2Tdy3I6cgvZ6SEi9QNey+lqps/sJRnogIS+lq+B1gxxbra2a/w==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^4.2.0", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-hex-encoding": "^4.2.0", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-uri-escape": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/smithy-client": { + "version": "4.9.10", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.9.10.tgz", + "integrity": "sha512-Jaoz4Jw1QYHc1EFww/E6gVtNjhoDU+gwRKqXP6C3LKYqqH2UQhP8tMP3+t/ePrhaze7fhLE8vS2q6vVxBANFTQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/core": "^3.18.7", + "@smithy/middleware-endpoint": "^4.3.14", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/types": "^4.9.0", + "@smithy/util-stream": "^4.5.6", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/types": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.9.0.tgz", + "integrity": "sha512-MvUbdnXDTwykR8cB1WZvNNwqoWVaTRA0RLlLmf/cIFNMM2cKWz01X4Ly6SMC4Kks30r8tT3Cty0jmeWfiuyHTA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/url-parser": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.5.tgz", + "integrity": "sha512-VaxMGsilqFnK1CeBX+LXnSuaMx4sTL/6znSZh2829txWieazdVxr54HmiyTsIbpOTLcf5nYpq9lpzmwRdxj6rQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/querystring-parser": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-base64": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.3.0.tgz", + "integrity": "sha512-GkXZ59JfyxsIwNTWFnjmFEI8kZpRNIBfxKjv09+nkAWPt/4aGaEWMM04m4sxgNVWkbt2MdSvE3KF/PfX4nFedQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-browser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.2.0.tgz", + "integrity": "sha512-Fkoh/I76szMKJnBXWPdFkQJl2r9SjPt3cMzLdOB6eJ4Pnpas8hVoWPYemX/peO0yrrvldgCUVJqOAjUrOLjbxg==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-body-length-node": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.2.1.tgz", + "integrity": "sha512-h53dz/pISVrVrfxV1iqXlx5pRg3V2YWFcSQyPyXZRrZoZj4R4DeWRDo1a7dd3CPTcFi3kE+98tuNyD2axyZReA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-buffer-from": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.2.0.tgz", + "integrity": "sha512-kAY9hTKulTNevM2nlRtxAG2FQ3B2OR6QIrPY3zE5LqJy1oxzmgBGsHLWTcNhWXKchgA0WHW+mZkQrng/pgcCew==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/is-array-buffer": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-config-provider": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.2.0.tgz", + "integrity": "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-browser": { + "version": "4.3.13", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.13.tgz", + "integrity": "sha512-hlVLdAGrVfyNei+pKIgqDTxfu/ZI2NSyqj4IDxKd5bIsIqwR/dSlkxlPaYxFiIaDVrBy0he8orsFy+Cz119XvA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/property-provider": "^4.2.5", + "@smithy/smithy-client": "^4.9.10", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-defaults-mode-node": { + "version": "4.2.16", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.16.tgz", + "integrity": "sha512-F1t22IUiJLHrxW9W1CQ6B9PN+skZ9cqSuzB18Eh06HrJPbjsyZ7ZHecAKw80DQtyGTRcVfeukKaCRYebFwclbg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/config-resolver": "^4.4.3", + "@smithy/credential-provider-imds": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/smithy-client": "^4.9.10", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-endpoints": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.5.tgz", + "integrity": "sha512-3O63AAWu2cSNQZp+ayl9I3NapW1p1rR5mlVHcF6hAB1dPZUQFfRPYtplWX/3xrzWthPGj5FqB12taJJCfH6s8A==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/node-config-provider": "^4.3.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-hex-encoding": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.2.0.tgz", + "integrity": "sha512-CCQBwJIvXMLKxVbO88IukazJD9a4kQ9ZN7/UMGBjBcJYvatpWk+9g870El4cB8/EJxfe+k+y0GmR9CAzkF+Nbw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-middleware": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.5.tgz", + "integrity": "sha512-6Y3+rvBF7+PZOc40ybeZMcGln6xJGVeY60E7jy9Mv5iKpMJpHgRE6dKy9ScsVxvfAYuEX4Q9a65DQX90KaQ3bA==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-retry": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.5.tgz", + "integrity": "sha512-GBj3+EZBbN4NAqJ/7pAhsXdfzdlznOh8PydUijy6FpNIMnHPSMO2/rP4HKu+UFeikJxShERk528oy7GT79YiJg==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/service-error-classification": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-stream": { + "version": "4.5.6", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.6.tgz", + "integrity": "sha512-qWw/UM59TiaFrPevefOZ8CNBKbYEP6wBAIlLqxn3VAIo9rgnTNc4ASbVrqDmhuwI87usnjhdQrxodzAGFFzbRQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/types": "^4.9.0", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-buffer-from": "^4.2.0", + "@smithy/util-hex-encoding": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-uri-escape": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.2.0.tgz", + "integrity": "sha512-igZpCKV9+E/Mzrpq6YacdTQ0qTiLm85gD6N/IrmyDvQFA4UnU3d5g3m8tMT/6zG/vVkWSU+VxeUyGonL62DuxA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-utf8": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.2.0.tgz", + "integrity": "sha512-zBPfuzoI8xyBtR2P6WQj63Rz8i3AmfAaJLuNG8dWsfvPe8lO4aCPYLn879mEgHndZH1zQ2oXmG8O1GGzzaoZiw==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/util-buffer-from": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/util-waiter": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.2.5.tgz", + "integrity": "sha512-Dbun99A3InifQdIrsXZ+QLcC0PGBPAdrl4cj1mTgJvyc9N2zf7QSxg8TBkzsCmGJdE3TLbO9ycwpY0EkWahQ/g==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/abort-controller": "^4.2.5", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@smithy/uuid": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@smithy/uuid/-/uuid-1.1.0.tgz", + "integrity": "sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@types/aws-lambda": { "version": "8.10.159", "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.159.tgz", @@ -462,6 +2208,31 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/node": { + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.0.tgz", + "integrity": "sha512-rl78HwuZlaDIUSeUKkmogkhebA+8K1Hy7tddZuJ3D0xV8pZSfsYGTsliGUol1JPzu9EKnTxPC4L1fiWouStRew==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/bowser": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.13.1.tgz", + "integrity": "sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw==", + "license": "MIT" + }, + "node_modules/data-uri-to-buffer": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", + "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/esbuild": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.0.tgz", @@ -503,6 +2274,131 @@ "@esbuild/win32-ia32": "0.27.0", "@esbuild/win32-x64": "0.27.0" } + }, + "node_modules/fast-xml-parser": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.2.5.tgz", + "integrity": "sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^2.1.0" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fetch-blob": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", + "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "paypal", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "dependencies": { + "node-domexception": "^1.0.0", + "web-streams-polyfill": "^3.0.3" + }, + "engines": { + "node": "^12.20 || >= 14.13" + } + }, + "node_modules/formdata-polyfill": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", + "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "license": "MIT", + "dependencies": { + "fetch-blob": "^3.1.2" + }, + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/node-domexception": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", + "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", + "deprecated": "Use your platform's native DOMException instead", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/jimmywarting" + }, + { + "type": "github", + "url": "https://paypal.me/jimmywarting" + } + ], + "license": "MIT", + "engines": { + "node": ">=10.5.0" + } + }, + "node_modules/node-fetch": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", + "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "license": "MIT", + "dependencies": { + "data-uri-to-buffer": "^4.0.0", + "fetch-blob": "^3.1.4", + "formdata-polyfill": "^4.0.10" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/node-fetch" + } + }, + "node_modules/strnum": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.1.tgz", + "integrity": "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, + "node_modules/web-streams-polyfill": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", + "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "license": "MIT", + "engines": { + "node": ">= 8" + } } } } diff --git a/image-embedder-lambda/package.json b/image-embedder-lambda/package.json index cb057814c17..0af4de1f055 100644 --- a/image-embedder-lambda/package.json +++ b/image-embedder-lambda/package.json @@ -11,6 +11,12 @@ "license": "ISC", "devDependencies": { "@types/aws-lambda": "^8.10.159", + "@types/node": "^25.0.0", "esbuild": "0.27.0" + }, + "dependencies": { + "@aws-sdk/client-bedrock-runtime": "^3.948.0", + "@aws-sdk/client-s3": "^3.948.0", + "node-fetch": "^3.3.2" } } diff --git a/image-embedder-lambda/src/index.ts b/image-embedder-lambda/src/index.ts index 4b638df83e5..e75983ffd35 100644 --- a/image-embedder-lambda/src/index.ts +++ b/image-embedder-lambda/src/index.ts @@ -6,10 +6,79 @@ // Whether it's worth it to do that // We can also reuse the lambda for the backfill -import { Context, S3Event } from 'aws-lambda'; +import { Context, SQSEvent, SQSRecord } from 'aws-lambda'; +// import { BedrockRuntimeClient, BedrockRuntimeClientConfig, InvokeModelCommand, InvokeModelCommandOutput } from "@aws-sdk/client-bedrock-runtime"; +// import fetch from "node-fetch"; +// import { GetObjectAclCommand, GetObjectCommand, S3Client } from '@aws-sdk/client-s3'; -export const handler = async (event: S3Event, context: Context) => { - console.log('Hello world!'); +// const model: string = "cohere.embed-english-v3"; + +// const bedrockClient = new BedrockRuntimeClient({ +// region: "eu-west-1" +// }); + +const GRID_API_KEY = process.env.GRID_API_KEY || ""; + +// async function getImageFromGrid(imageId: string, apiKey: string) { + +// const imageUri = `https://api.media.gutools.co.uk/images/${imageId}`; +// console.log(`Fetching metadata for image from ${imageUri}`); + +// const response = await fetch(imageUri, { +// headers: { "X-Gu-Media-Key": apiKey } +// }); +// const imageMetadata = await response.json(); + +// const secureUrl = imageMetadata.data.source.secureUrl; +// console.log("Fetching image from secureUrl"); + +// const imageResponse = await fetch(secureUrl); +// const imageBytes = await imageResponse.arrayBuffer(); + +// console.log(`The bytes string are: ${imageBytes}`); +// return imageBytes; +// } + +// async function getCredentials(s3Client: S3Client) { - // Function code +// const params = { +// Bucket: "grid-conf", +// Key: `TEST/image-embedder-lambda/conf.json` +// }; + +// const command = new GetObjectCommand(params) + +// const data = await s3Client.send(command) +// const body = data.Body?.toString("utf8") || ""; + +// return JSON.parse(body); +// } + +// async function embedImage(inputData: Array): Promise { +// const body = { +// inputType: "image", +// embeddingTypes: ["float"], +// images: inputData +// } + +// const input = { +// modelId: model, +// body: body, +// accept: "*/*", +// contentType: "application/json", +// } + +// const command = new InvokeModelCommand(input); + +// const chatCompletion = await bedrockClient.send(command); +// return chatCompletion +// } + +export const handler = async (event: SQSEvent, context: Context) => { + + console.log(`Starting handler embedding pipeline`); + const records: SQSRecord[] = event.Records; + const recordBody = records[0].body + console.log(`recordBody: ${recordBody}`); + console.log(`secret (DUMMY VALUE ATM OBVS BECAUSE PRINTING): ${GRID_API_KEY}`); }; \ No newline at end of file From a63aef4300f00236be40baece3f0886d0284fb31 Mon Sep 17 00:00:00 2001 From: Joseph Smith Date: Thu, 11 Dec 2025 18:06:52 +0000 Subject: [PATCH 030/494] Do not allow empty AI search --- kahuna/public/js/search/results.html | 3 ++- kahuna/public/js/search/results.js | 2 ++ media-api/app/controllers/MediaApi.scala | 20 ++++++++++---------- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/kahuna/public/js/search/results.html b/kahuna/public/js/search/results.html index fc1e9bd1e74..2071c3e167b 100644 --- a/kahuna/public/js/search/results.html +++ b/kahuna/public/js/search/results.html @@ -204,7 +204,8 @@
- No matches, sorry! Try altering your search. + No matches, sorry! Try altering your search. + Please enter a query
diff --git a/kahuna/public/js/search/results.js b/kahuna/public/js/search/results.js index 894bdcb038d..a2f94e82dd2 100644 --- a/kahuna/public/js/search/results.js +++ b/kahuna/public/js/search/results.js @@ -202,6 +202,8 @@ results.controller('SearchResultsCtrl', [ ctrl.newImagesCount = 0; ctrl.newImagesLastCheckedMoment = moment(); + ctrl.needsQuery = $stateParams.useAISearch && (!$stateParams.query || !$stateParams.query.trim()); + // Map to track image->position and help remove duplicates let imagesPositions; diff --git a/media-api/app/controllers/MediaApi.scala b/media-api/app/controllers/MediaApi.scala index 38fbc637897..2150de4ec53 100644 --- a/media-api/app/controllers/MediaApi.scala +++ b/media-api/app/controllers/MediaApi.scala @@ -559,16 +559,16 @@ class MediaApi( if (_searchParams.useAISearch.contains(true)) { - val searchTerm = _searchParams.query match { - case Some(q) => q - case None => "" - } - - val semanticSearchResult: Future[QueryVectorsResponse] = embedder.createEmbeddingAndSearch(searchTerm) - - val imageIds = semanticSearchResult.map { result => - val results: java.util.List[QueryOutputVector] = result.vectors() - results.asScala.map(_.key()).toList + val imageIds: Future[List[String]] = _searchParams.query match { + case Some(q) if !q.isBlank => + embedder.createEmbeddingAndSearch(q).map { result => + val results: java.util.List[QueryOutputVector] = result.vectors() + results.asScala.map(_.key()).toList + } + // Empty queries do not make sense for AI search as we can + // only rank results once we have a meaningful vector to compare with. + // So return 0 results if the query was empty. + case _ => Future(Nil) } imageIds.flatMap { ids => From 5502653d74acb2eb7896c55ee8b0e97e064f5632 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 20:01:20 +0000 Subject: [PATCH 031/494] chore(deps): bump scalacenter/sbt-dependency-submission Bumps [scalacenter/sbt-dependency-submission](https://github.com/scalacenter/sbt-dependency-submission) from 3.1.0 to 3.2.1. - [Release notes](https://github.com/scalacenter/sbt-dependency-submission/releases) - [Commits](https://github.com/scalacenter/sbt-dependency-submission/compare/64084844d2b0a9b6c3765f33acde2fbe3f5ae7d3...f43202114d7522a4b233e052f82c2eea8d658134) --- updated-dependencies: - dependency-name: scalacenter/sbt-dependency-submission dependency-version: 3.2.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/sbt-dependency-graph.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sbt-dependency-graph.yaml b/.github/workflows/sbt-dependency-graph.yaml index a737228a137..f61a727ebed 100644 --- a/.github/workflows/sbt-dependency-graph.yaml +++ b/.github/workflows/sbt-dependency-graph.yaml @@ -22,7 +22,7 @@ jobs: uses: sbt/setup-sbt@3e125ece5c3e5248e18da9ed8d2cce3d335ec8dd # v1.1.14 - name: Submit dependencies id: submit - uses: scalacenter/sbt-dependency-submission@64084844d2b0a9b6c3765f33acde2fbe3f5ae7d3 # v3.1.0 + uses: scalacenter/sbt-dependency-submission@f43202114d7522a4b233e052f82c2eea8d658134 # v3.2.1 - name: Log snapshot for user validation id: validate run: cat ${{ steps.submit.outputs.snapshot-json-path }} | jq From 668acd07737e4de98c9bd23e0938c5cc1c2a0b7b Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Tue, 16 Dec 2025 15:51:04 +0000 Subject: [PATCH 032/494] grab image from S3 --- .../image-embedder-lambda.test.ts.snap | 94 +++++++++++ cdk/lib/image-embedder-lambda.ts | 51 +++++- image-embedder-lambda/src/index.ts | 158 +++++++++++------- scripts/embedder-deploy/send-message.sh | 25 +++ 4 files changed, 259 insertions(+), 69 deletions(-) create mode 100755 scripts/embedder-deploy/send-message.sh diff --git a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap index 2eb53ca37f2..dde3eb3e7e8 100644 --- a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap +++ b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap @@ -239,6 +239,64 @@ exports[`The MediaService stack matches the snapshot 1`] = ` ], }, }, + { + "Action": [ + "sqs:ReceiveMessage", + "sqs:ChangeMessageVisibility", + "sqs:GetQueueUrl", + "sqs:DeleteMessage", + "sqs:GetQueueAttributes", + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "imageEmbedder9F00A33D", + "Arn", + ], + }, + }, + { + "Action": [ + "s3vectors:PutVectors", + "s3vectors:GetVectors", + "s3vectors:QueryVectors", + "s3vectors:ListVectors", + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:s3vectors:eu-central-1:", + { + "Ref": "AWS::AccountId", + }, + ":bucket/image-embeddings-test/index/*", + ], + ], + }, + }, + { + "Action": "bedrock:InvokeModel", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:bedrock:", + { + "Ref": "AWS::Region", + }, + "::foundation-model/cohere.embed-english-v3", + ], + ], + }, + }, + { + "Action": "s3:GetObject", + "Effect": "Allow", + "Resource": "arn:aws:s3:::image-embedding-test/*", + }, ], "Version": "2012-10-17", }, @@ -251,6 +309,42 @@ exports[`The MediaService stack matches the snapshot 1`] = ` }, "Type": "AWS::IAM::Policy", }, + "ImageEmbedderHandlerSqsEventSourceImageEmbedderLambdaimageEmbedder4169931F5A3D671C": { + "Properties": { + "EventSourceArn": { + "Fn::GetAtt": [ + "imageEmbedder9F00A33D", + "Arn", + ], + }, + "FunctionName": { + "Ref": "ImageEmbedderHandler2C9410B9", + }, + "Tags": [ + { + "Key": "App", + "Value": "image-embedder-lambda", + }, + { + "Key": "gu:cdk:version", + "Value": "TEST", + }, + { + "Key": "gu:repo", + "Value": "guardian/grid", + }, + { + "Key": "Stack", + "Value": "media-service", + }, + { + "Key": "Stage", + "Value": "TEST", + }, + ], + }, + "Type": "AWS::Lambda::EventSourceMapping", + }, "imageEmbedder9F00A33D": { "DeletionPolicy": "Delete", "Properties": { diff --git a/cdk/lib/image-embedder-lambda.ts b/cdk/lib/image-embedder-lambda.ts index f30a2a07fed..b9b652f6838 100644 --- a/cdk/lib/image-embedder-lambda.ts +++ b/cdk/lib/image-embedder-lambda.ts @@ -2,9 +2,10 @@ import type { GuStackProps } from "@guardian/cdk/lib/constructs/core"; import { GuStack } from "@guardian/cdk/lib/constructs/core"; import { GuLambdaFunction } from "@guardian/cdk/lib/constructs/lambda"; import type { App } from "aws-cdk-lib"; -import { Duration, aws_lambda as lambda } from "aws-cdk-lib"; +import { Duration, aws_lambda as lambda, Stack } from "aws-cdk-lib"; +import { PolicyStatement } from "aws-cdk-lib/aws-iam"; import { Architecture } from "aws-cdk-lib/aws-lambda"; -// import { SqsEventSource } from "aws-cdk-lib/aws-lambda-event-sources"; +import { SqsEventSource } from "aws-cdk-lib/aws-lambda-event-sources"; import { Secret } from "aws-cdk-lib/aws-secretsmanager"; import { Queue } from "aws-cdk-lib/aws-sqs"; @@ -20,8 +21,7 @@ export class MediaService extends GuStack { `media-service/${props.stage}/image-embedder-lambda/api-key`, ); - // const imageEmbedderLambda = - new GuLambdaFunction( + const imageEmbedderLambda = new GuLambdaFunction( this, 'ImageEmbedderHandler', { @@ -41,8 +41,7 @@ export class MediaService extends GuStack { queueName: `image-embedder-DLQ-${this.stage}`, }); - // const imageEmbedderQueue = - new Queue( + const imageEmbedderQueue = new Queue( this, 'imageEmbedder', { @@ -54,9 +53,43 @@ export class MediaService extends GuStack { }, }, ); - // imageEmbedderLambda.addEventSource( - // new SqsEventSource(imageEmbedderQueue), - // ); + imageEmbedderLambda.addEventSource( + new SqsEventSource(imageEmbedderQueue), + ); + + // Allow reading and writing vectors to S3 vector index + imageEmbedderLambda.role?.addToPrincipalPolicy( + new PolicyStatement({ + actions: [ + 's3vectors:PutVectors', + 's3vectors:GetVectors', + 's3vectors:QueryVectors', + 's3vectors:ListVectors' + ], + resources: [ + `arn:aws:s3vectors:eu-central-1:${Stack.of(this).account}:bucket/image-embeddings-test/index/*`, + ], + }), + ); + // Allow invoking the Bedrock Cohere embeddings model + imageEmbedderLambda.role?.addToPrincipalPolicy( + new PolicyStatement({ + actions: ['bedrock:InvokeModel'], + resources: [ + `arn:aws:bedrock:${Stack.of(this).region}::foundation-model/cohere.embed-english-v3`, + ], + }), + ); + + // Allow fetching the image from S3 + imageEmbedderLambda.role?.addToPrincipalPolicy( + new PolicyStatement({ + actions: ['s3:GetObject'], + resources: [ + `arn:aws:s3:::image-embedding-test/*`, + ], + }), + ); } } \ No newline at end of file diff --git a/image-embedder-lambda/src/index.ts b/image-embedder-lambda/src/index.ts index e75983ffd35..6d854398aec 100644 --- a/image-embedder-lambda/src/index.ts +++ b/image-embedder-lambda/src/index.ts @@ -6,79 +6,117 @@ // Whether it's worth it to do that // We can also reuse the lambda for the backfill +// Send the S3 link to the image via image-loader + import { Context, SQSEvent, SQSRecord } from 'aws-lambda'; -// import { BedrockRuntimeClient, BedrockRuntimeClientConfig, InvokeModelCommand, InvokeModelCommandOutput } from "@aws-sdk/client-bedrock-runtime"; -// import fetch from "node-fetch"; -// import { GetObjectAclCommand, GetObjectCommand, S3Client } from '@aws-sdk/client-s3'; +import { BedrockRuntimeClient, InvokeModelCommand, InvokeModelCommandInput, InvokeModelCommandOutput } from "@aws-sdk/client-bedrock-runtime"; +import { GetObjectCommand, GetObjectCommandOutput, GetObjectRequest, S3Client } from "@aws-sdk/client-s3" -// const model: string = "cohere.embed-english-v3"; +const model: string = "cohere.embed-english-v3"; +const bedrockClient = new BedrockRuntimeClient({ + region: "eu-west-1" +}); +const s3Client = new S3Client({region: "eu-west-1"}) +interface SQSMessageBody { + imageId: string; + bucket: string; + filePath: string; +} -// const bedrockClient = new BedrockRuntimeClient({ -// region: "eu-west-1" -// }); +async function getImageFromS3(bucket: string, filePath: string): Promise { + + const input: GetObjectRequest = { + Bucket: bucket, + Key: filePath, + }; -const GRID_API_KEY = process.env.GRID_API_KEY || ""; + console.log(`Fetching image from S3: bucket=${bucket}, key=${filePath}`); -// async function getImageFromGrid(imageId: string, apiKey: string) { + try { + const command = new GetObjectCommand(input); + const response: GetObjectCommandOutput = await s3Client.send(command); + + if (!response) { + console.log(`Returning undefined: no response object`); + return undefined; + } -// const imageUri = `https://api.media.gutools.co.uk/images/${imageId}`; -// console.log(`Fetching metadata for image from ${imageUri}`); - -// const response = await fetch(imageUri, { -// headers: { "X-Gu-Media-Key": apiKey } -// }); -// const imageMetadata = await response.json(); - -// const secureUrl = imageMetadata.data.source.secureUrl; -// console.log("Fetching image from secureUrl"); - -// const imageResponse = await fetch(secureUrl); -// const imageBytes = await imageResponse.arrayBuffer(); - -// console.log(`The bytes string are: ${imageBytes}`); -// return imageBytes; -// } + // Log response metadata for debugging + console.log(`Response metadata: ${JSON.stringify(response.$metadata)}`); + console.log(`Content-Length: ${response.ContentLength}`); + console.log(`Content-Type: ${response.ContentType}`); + console.log(`Body type: ${response.Body?.constructor.name}`); -// async function getCredentials(s3Client: S3Client) { - -// const params = { -// Bucket: "grid-conf", -// Key: `TEST/image-embedder-lambda/conf.json` -// }; + if (!response.Body) { + console.log(`Returning undefined: response.Body is falsy`); + return undefined; + } -// const command = new GetObjectCommand(params) - -// const data = await s3Client.send(command) -// const body = data.Body?.toString("utf8") || ""; - -// return JSON.parse(body); -// } - -// async function embedImage(inputData: Array): Promise { -// const body = { -// inputType: "image", -// embeddingTypes: ["float"], -// images: inputData -// } + if (response.ContentLength === 0) { + console.log(`Warning: ContentLength is 0, file may be empty`); + } + + const bytes = await response.Body.transformToByteArray(); + console.log(`Bytes array length: ${bytes.length}`); + return bytes; + } catch (error) { + console.error(`Error fetching from S3:`, error); + if (error instanceof Error) { + console.error(`Error name: ${error.name}`); + console.error(`Error message: ${error.message}`); + console.error(`Error stack: ${error.stack}`); + } + throw error; + } +} + +async function embedImage(inputData: String[]): Promise { + const body = { + input_type: "image", + embedding_types: ["float"], + images: inputData + }; + const jsonBody = JSON.stringify(body); -// const input = { -// modelId: model, -// body: body, -// accept: "*/*", -// contentType: "application/json", -// } + const input: InvokeModelCommandInput = { + modelId: model, + body: jsonBody, + accept: "*/*", + contentType: "application/json", + } + console.log(`Invoking Bedrock model: ${model}`); -// const command = new InvokeModelCommand(input); - -// const chatCompletion = await bedrockClient.send(command); -// return chatCompletion -// } + try { + const command = new InvokeModelCommand(input); + const response = await bedrockClient.send(command); + + console.log(`Bedrock response metadata: ${JSON.stringify(response.$metadata)}`); + console.log(`Response body length: ${response.body?.length}`); + + return response; + } catch (error) { + console.error(`Bedrock invocation error:`, error); + if (error instanceof Error) { + console.error(`Error name: ${error.name}`); + console.error(`Error message: ${error.message}`); + } + throw error; + } +} export const handler = async (event: SQSEvent, context: Context) => { console.log(`Starting handler embedding pipeline`); const records: SQSRecord[] = event.Records; - const recordBody = records[0].body - console.log(`recordBody: ${recordBody}`); - console.log(`secret (DUMMY VALUE ATM OBVS BECAUSE PRINTING): ${GRID_API_KEY}`); + const recordBody: SQSMessageBody = JSON.parse(records[0].body); + + const gridImage = await getImageFromS3(recordBody.bucket, recordBody.filePath); + + const base64Image = Buffer.from(gridImage).toString('base64'); + const inputImage = `data:image/jpg;base64,${base64Image}` + + // TODO: downscale image if neceesary + + const embedding = await embedImage([inputImage]); + }; \ No newline at end of file diff --git a/scripts/embedder-deploy/send-message.sh b/scripts/embedder-deploy/send-message.sh new file mode 100755 index 00000000000..fd3952fe046 --- /dev/null +++ b/scripts/embedder-deploy/send-message.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -euo pipefail + +# Fixed stage +STAGE="TEST" + +QUEUE_NAME="image-embedder-${STAGE}" + +QUEUE_URL=$( + aws sqs get-queue-url \ + --queue-name "$QUEUE_NAME" \ + --query 'QueueUrl' \ + --output text \ + --profile media-service \ + --region eu-west-1 +) + +aws sqs send-message \ + --queue-url "$QUEUE_URL" \ + --message-body \ + '{"imageId": "3909f6ce899a70ebaf7065fe10f28fe4ebcff6d3", "bucket": "image-embedding-test", "filePath": "test-folder/Rex_Shutterstock_QuinsvBayonne_16081571ib (6b3eb5ee8562807483e165144d46d0dac0571773).jpg"}' \ + --profile media-service \ + --region eu-west-1 + +echo "Sent message to queue ${QUEUE_NAME}:" From 64b302990eadad3b4f8b436fe115c3935fc6128c Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Tue, 16 Dec 2025 15:51:34 +0000 Subject: [PATCH 033/494] write to s3 vector store --- .../image-embedder-lambda.test.ts.snap | 2 +- cdk/lib/image-embedder-lambda.ts | 2 +- image-embedder-lambda/package-lock.json | 222 ++++++++++++++++++ image-embedder-lambda/package.json | 1 + image-embedder-lambda/src/index.ts | 63 ++++- 5 files changed, 282 insertions(+), 8 deletions(-) diff --git a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap index dde3eb3e7e8..f3d10a6af7c 100644 --- a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap +++ b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap @@ -271,7 +271,7 @@ exports[`The MediaService stack matches the snapshot 1`] = ` { "Ref": "AWS::AccountId", }, - ":bucket/image-embeddings-test/index/*", + ":bucket/image-embeddings-via-lambda/index/*", ], ], }, diff --git a/cdk/lib/image-embedder-lambda.ts b/cdk/lib/image-embedder-lambda.ts index b9b652f6838..a9e58af9c04 100644 --- a/cdk/lib/image-embedder-lambda.ts +++ b/cdk/lib/image-embedder-lambda.ts @@ -67,7 +67,7 @@ export class MediaService extends GuStack { 's3vectors:ListVectors' ], resources: [ - `arn:aws:s3vectors:eu-central-1:${Stack.of(this).account}:bucket/image-embeddings-test/index/*`, + `arn:aws:s3vectors:eu-central-1:${Stack.of(this).account}:bucket/image-embeddings-via-lambda/index/*`, ], }), ); diff --git a/image-embedder-lambda/package-lock.json b/image-embedder-lambda/package-lock.json index 82a4585f6a5..6d6778149a7 100644 --- a/image-embedder-lambda/package-lock.json +++ b/image-embedder-lambda/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "@aws-sdk/client-bedrock-runtime": "^3.948.0", "@aws-sdk/client-s3": "^3.948.0", + "@aws-sdk/client-s3vectors": "^3.952.0", "node-fetch": "^3.3.2" }, "devDependencies": { @@ -345,6 +346,227 @@ "node": ">=18.0.0" } }, + "node_modules/@aws-sdk/client-s3vectors": { + "version": "3.952.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3vectors/-/client-s3vectors-3.952.0.tgz", + "integrity": "sha512-XhPjolHQ59XzLu10/2l0Hx7sgSqnsWTzzfXd15y+PZp2esA+M82+HD9+KBAV4y9kU0kj2efASJgrsnWq23Vdug==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.947.0", + "@aws-sdk/credential-provider-node": "3.952.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.948.0", + "@aws-sdk/middleware-user-agent": "3.947.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.947.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.7", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.14", + "@smithy/middleware-retry": "^4.4.14", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.10", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.13", + "@smithy/util-defaults-mode-node": "^4.2.16", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-s3vectors/node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.952.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.952.0.tgz", + "integrity": "sha512-N5B15SwzMkZ8/LLopNksTlPEWWZn5tbafZAUfMY5Xde4rSHGWmv5H/ws2M3P8L0X77E2wKnOJsNmu+GsArBreQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.947.0", + "@aws-sdk/credential-provider-env": "3.947.0", + "@aws-sdk/credential-provider-http": "3.947.0", + "@aws-sdk/credential-provider-login": "3.952.0", + "@aws-sdk/credential-provider-process": "3.947.0", + "@aws-sdk/credential-provider-sso": "3.952.0", + "@aws-sdk/credential-provider-web-identity": "3.952.0", + "@aws-sdk/nested-clients": "3.952.0", + "@aws-sdk/types": "3.936.0", + "@smithy/credential-provider-imds": "^4.2.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-s3vectors/node_modules/@aws-sdk/credential-provider-login": { + "version": "3.952.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.952.0.tgz", + "integrity": "sha512-jL9zc+e+7sZeJrHzYKK9GOjl1Ktinh0ORU3cM2uRBi7fuH/0zV9pdMN8PQnGXz0i4tJaKcZ1lrE4V0V6LB9NQg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.947.0", + "@aws-sdk/nested-clients": "3.952.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-s3vectors/node_modules/@aws-sdk/credential-provider-node": { + "version": "3.952.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.952.0.tgz", + "integrity": "sha512-pj7nidLrb3Dz9llcUPh6N0Yv1dBYTS9xJqi8u0kI8D5sn72HJMB+fIOhcDQVXXAw/dpVolOAH9FOAbog5JDAMg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.947.0", + "@aws-sdk/credential-provider-http": "3.947.0", + "@aws-sdk/credential-provider-ini": "3.952.0", + "@aws-sdk/credential-provider-process": "3.947.0", + "@aws-sdk/credential-provider-sso": "3.952.0", + "@aws-sdk/credential-provider-web-identity": "3.952.0", + "@aws-sdk/types": "3.936.0", + "@smithy/credential-provider-imds": "^4.2.5", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-s3vectors/node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.952.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.952.0.tgz", + "integrity": "sha512-1CQdP5RzxeXuEfytbAD5TgreY1c9OacjtCdO8+n9m05tpzBABoNBof0hcjzw1dtrWFH7deyUgfwCl1TAN3yBWQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-sso": "3.948.0", + "@aws-sdk/core": "3.947.0", + "@aws-sdk/token-providers": "3.952.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-s3vectors/node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.952.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.952.0.tgz", + "integrity": "sha512-5hJbfaZdHDAP8JlwplNbXJAat9Vv7L0AbTZzkbPIgjHhC3vrMf5r3a6I1HWFp5i5pXo7J45xyuf5uQGZJxJlCg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.947.0", + "@aws-sdk/nested-clients": "3.952.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-s3vectors/node_modules/@aws-sdk/nested-clients": { + "version": "3.952.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.952.0.tgz", + "integrity": "sha512-OtuirjxuOqZyDcI0q4WtoyWfkq3nSnbH41JwJQsXJefduWcww1FQe5TL1JfYCU7seUxHzK8rg2nFxUBuqUlZtg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.947.0", + "@aws-sdk/middleware-host-header": "3.936.0", + "@aws-sdk/middleware-logger": "3.936.0", + "@aws-sdk/middleware-recursion-detection": "3.948.0", + "@aws-sdk/middleware-user-agent": "3.947.0", + "@aws-sdk/region-config-resolver": "3.936.0", + "@aws-sdk/types": "3.936.0", + "@aws-sdk/util-endpoints": "3.936.0", + "@aws-sdk/util-user-agent-browser": "3.936.0", + "@aws-sdk/util-user-agent-node": "3.947.0", + "@smithy/config-resolver": "^4.4.3", + "@smithy/core": "^3.18.7", + "@smithy/fetch-http-handler": "^5.3.6", + "@smithy/hash-node": "^4.2.5", + "@smithy/invalid-dependency": "^4.2.5", + "@smithy/middleware-content-length": "^4.2.5", + "@smithy/middleware-endpoint": "^4.3.14", + "@smithy/middleware-retry": "^4.4.14", + "@smithy/middleware-serde": "^4.2.6", + "@smithy/middleware-stack": "^4.2.5", + "@smithy/node-config-provider": "^4.3.5", + "@smithy/node-http-handler": "^4.4.5", + "@smithy/protocol-http": "^5.3.5", + "@smithy/smithy-client": "^4.9.10", + "@smithy/types": "^4.9.0", + "@smithy/url-parser": "^4.2.5", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.13", + "@smithy/util-defaults-mode-node": "^4.2.16", + "@smithy/util-endpoints": "^3.2.5", + "@smithy/util-middleware": "^4.2.5", + "@smithy/util-retry": "^4.2.5", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@aws-sdk/client-s3vectors/node_modules/@aws-sdk/token-providers": { + "version": "3.952.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.952.0.tgz", + "integrity": "sha512-IpQVC9WOeXQlCEcFVNXWDIKy92CH1Az37u9K0H3DF/HT56AjhyDVKQQfHUy00nt7bHFe3u0K5+zlwErBeKy5ZA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.947.0", + "@aws-sdk/nested-clients": "3.952.0", + "@aws-sdk/types": "3.936.0", + "@smithy/property-provider": "^4.2.5", + "@smithy/shared-ini-file-loader": "^4.4.0", + "@smithy/types": "^4.9.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@aws-sdk/client-sso": { "version": "3.948.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.948.0.tgz", diff --git a/image-embedder-lambda/package.json b/image-embedder-lambda/package.json index 0af4de1f055..225be196ac3 100644 --- a/image-embedder-lambda/package.json +++ b/image-embedder-lambda/package.json @@ -17,6 +17,7 @@ "dependencies": { "@aws-sdk/client-bedrock-runtime": "^3.948.0", "@aws-sdk/client-s3": "^3.948.0", + "@aws-sdk/client-s3vectors": "^3.952.0", "node-fetch": "^3.3.2" } } diff --git a/image-embedder-lambda/src/index.ts b/image-embedder-lambda/src/index.ts index 6d854398aec..71c71ba1494 100644 --- a/image-embedder-lambda/src/index.ts +++ b/image-embedder-lambda/src/index.ts @@ -9,14 +9,16 @@ // Send the S3 link to the image via image-loader import { Context, SQSEvent, SQSRecord } from 'aws-lambda'; -import { BedrockRuntimeClient, InvokeModelCommand, InvokeModelCommandInput, InvokeModelCommandOutput } from "@aws-sdk/client-bedrock-runtime"; +import { BedrockRuntimeClient, InvokeModelCommand, InvokeModelCommandInput, InvokeModelCommandOutput, ServiceInputTypes } from "@aws-sdk/client-bedrock-runtime"; import { GetObjectCommand, GetObjectCommandOutput, GetObjectRequest, S3Client } from "@aws-sdk/client-s3" +import { PutInputVector, PutVectorsCommand, PutVectorsCommandInput, S3VectorsClient, VectorData } from "@aws-sdk/client-s3vectors" + const model: string = "cohere.embed-english-v3"; -const bedrockClient = new BedrockRuntimeClient({ - region: "eu-west-1" -}); -const s3Client = new S3Client({region: "eu-west-1"}) +const config = {region: "eu-west-1"}; +const bedrockClient = new BedrockRuntimeClient(config); +const s3Client = new S3Client(config); +const s3VectorsClient = new S3VectorsClient({ region: "eu-central-1" }); interface SQSMessageBody { imageId: string; bucket: string; @@ -104,6 +106,44 @@ async function embedImage(inputData: String[]): Promise { console.log(`Starting handler embedding pipeline`); @@ -117,6 +157,17 @@ export const handler = async (event: SQSEvent, context: Context) => { // TODO: downscale image if neceesary - const embedding = await embedImage([inputImage]); + const embeddingResponse = await embedImage([inputImage]); + + // Parse the response body (it's a Uint8Array that needs to be decoded) + const responseBody = JSON.parse(new TextDecoder().decode(embeddingResponse.body)); + + // Extract the embedding array (first element since we only sent one image) + const embedding: number[] = responseBody.embeddings.float[0]; + + console.log(`Embedding length: ${embedding.length}`); + console.log(`First 5 values: ${embedding.slice(0, 5)}`); + + const store = await storeEmbedding(embedding, recordBody.imageId); }; \ No newline at end of file From 4321341eec415efcfe318dea006e8d7f3b4ad815 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Tue, 16 Dec 2025 16:11:48 +0000 Subject: [PATCH 034/494] tidy up --- .github/workflows/ci.yml | 14 -------- image-embedder-lambda/index.js | 32 ----------------- image-embedder-lambda/src/index.ts | 2 +- image-embedder-lambda/tsconfig.json | 55 ----------------------------- 4 files changed, 1 insertion(+), 102 deletions(-) delete mode 100644 image-embedder-lambda/index.js diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d94a1bd736e..807f33daa36 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -82,20 +82,6 @@ jobs: run: ./scripts/embedder-deploy/cdk.sh - name: Image embedder bundling run: ./scripts/embedder-deploy/bundle.sh - # - uses: guardian/actions-riff-raff@v4 - # env: - # GU_RIFF_RAFF_ROLE_ARN: ${{ secrets.GU_RIFF_RAFF_ROLE_ARN }} - # if: ${{ env.GU_RIFF_RAFF_ROLE_ARN }} - # with: - # githubToken: ${{ secrets.GITHUB_TOKEN }} - # roleArn: ${{ secrets.GU_RIFF_RAFF_ROLE_ARN }} - # projectName: media-service::grid::embedder - # configPath: cdk/cdk.out/riff-raff.yaml - # contentDirectories: | - # cdk.out: - # - cdk/cdk.out - # image-embedder-lambda: - # - image-embedder.zip - uses: guardian/actions-riff-raff@v4.2.3 if: "! github.event.pull_request.head.repo.fork" with: diff --git a/image-embedder-lambda/index.js b/image-embedder-lambda/index.js deleted file mode 100644 index 7348e0167dc..00000000000 --- a/image-embedder-lambda/index.js +++ /dev/null @@ -1,32 +0,0 @@ -"use strict"; -var __defProp = Object.defineProperty; -var __getOwnPropDesc = Object.getOwnPropertyDescriptor; -var __getOwnPropNames = Object.getOwnPropertyNames; -var __hasOwnProp = Object.prototype.hasOwnProperty; -var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); -}; -var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; -}; -var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - -// src/index.ts -var index_exports = {}; -__export(index_exports, { - handler: () => handler -}); -module.exports = __toCommonJS(index_exports); -var handler = async (event, context) => { - console.log("Hello world!"); -}; -// Annotate the CommonJS export names for ESM import in node: -0 && (module.exports = { - handler -}); diff --git a/image-embedder-lambda/src/index.ts b/image-embedder-lambda/src/index.ts index 71c71ba1494..b3982531f97 100644 --- a/image-embedder-lambda/src/index.ts +++ b/image-embedder-lambda/src/index.ts @@ -119,7 +119,7 @@ async function storeEmbedding(embedding: number[], key: string) { const input: PutVectorsCommandInput = { vectorBucketName: "image-embeddings-via-lambda", - indexName: "cohere.embed-english-v3", + indexName: "cohere-embed-english-v3", vectors: [inputVector], }; diff --git a/image-embedder-lambda/tsconfig.json b/image-embedder-lambda/tsconfig.json index 2d65dcf0ecd..a18d4c5422e 100644 --- a/image-embedder-lambda/tsconfig.json +++ b/image-embedder-lambda/tsconfig.json @@ -1,68 +1,13 @@ { "exclude": ["**/*.js*"], "compilerOptions": { - /* Visit https://aka.ms/tsconfig.json to read more about this file */ - /* Basic Options */ - // "incremental": true, /* Enable incremental compilation */ "target": "esnext", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ "lib": ["esnext"], /* Specify library files to be included in the compilation. */ - // "allowJs": true, /* Allow javascript files to be compiled. */ - // "checkJs": true, /* Report errors in .js files. */ - // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ - // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ - // "outDir": "./", /* Redirect output structure to the directory. */ - // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "composite": true, /* Enable project compilation */ - // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ - // "removeComments": true, /* Do not emit comments to output. */ - // "noEmit": true, /* Do not emit outputs. */ - // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ - // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ - - /* Strict Type-Checking Options */ - "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* Enable strict null checks. */ - // "strictFunctionTypes": true, /* Enable strict checking of function types. */ - // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ - // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ - // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ - // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ - - /* Additional Checks */ - // "noUnusedLocals": true, /* Report errors on unused locals. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - /* Module Resolution Options */ "moduleResolution": "nodenext", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ - // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ - // "typeRoots": [], /* List of folders to include type definitions from. */ - // "types": [], /* Type declaration files to be included in compilation. */ - // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ "esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ - // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ - // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ - - /* Source Map Options */ - // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ - // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ - - /* Experimental Options */ - // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ - // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ - /* Advanced Options */ "skipLibCheck": true, /* Skip type checking of declaration files. */ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ From f250f9ffe00d8bcff61590e93ebf0e15cbcfb055 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Wed, 17 Dec 2025 16:29:10 +0000 Subject: [PATCH 035/494] tidy up --- .github/workflows/ci.yml | 2 +- .../image-embedder-lambda.test.ts.snap | 20 ----- cdk/lib/image-embedder-lambda.ts | 20 ++--- image-embedder-lambda/.gitignore | 2 +- image-embedder-lambda/src/index.ts | 81 ++++++++++--------- scripts/embedder-deploy/send-message.sh | 2 +- 6 files changed, 51 insertions(+), 76 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dfd64777886..60981deeb50 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -114,7 +114,7 @@ jobs: - thrall/target/thrall.deb usage: - usage/target/usage.deb - + image-counter-lambda: - image-counter-lambda/dist/image-counter-lambda.zip diff --git a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap index f3d10a6af7c..edd0aae09d8 100644 --- a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap +++ b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap @@ -35,26 +35,6 @@ exports[`The MediaService stack matches the snapshot 1`] = ` "Environment": { "Variables": { "APP": "image-embedder-lambda", - "GRID_API_KEY": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:arn:", - { - "Ref": "AWS::Partition", - }, - ":secretsmanager:", - { - "Ref": "AWS::Region", - }, - ":", - { - "Ref": "AWS::AccountId", - }, - ":secret:media-service/TEST/image-embedder-lambda/api-key:SecretString:::}}", - ], - ], - }, "STACK": "media-service", "STAGE": "TEST", }, diff --git a/cdk/lib/image-embedder-lambda.ts b/cdk/lib/image-embedder-lambda.ts index a9e58af9c04..522191f3b78 100644 --- a/cdk/lib/image-embedder-lambda.ts +++ b/cdk/lib/image-embedder-lambda.ts @@ -6,7 +6,6 @@ import { Duration, aws_lambda as lambda, Stack } from "aws-cdk-lib"; import { PolicyStatement } from "aws-cdk-lib/aws-iam"; import { Architecture } from "aws-cdk-lib/aws-lambda"; import { SqsEventSource } from "aws-cdk-lib/aws-lambda-event-sources"; -import { Secret } from "aws-cdk-lib/aws-secretsmanager"; import { Queue } from "aws-cdk-lib/aws-sqs"; export class MediaService extends GuStack { @@ -15,12 +14,6 @@ export class MediaService extends GuStack { const LAMBDA_NODE_VERSION = lambda.Runtime.NODEJS_24_X; - const imageEmbedderApiKey = Secret.fromSecretNameV2( - this, - 'imageEmbedderApiKey', - `media-service/${props.stage}/image-embedder-lambda/api-key`, - ); - const imageEmbedderLambda = new GuLambdaFunction( this, 'ImageEmbedderHandler', @@ -31,9 +24,6 @@ export class MediaService extends GuStack { architecture: Architecture.ARM_64, handler: 'index.handler', app: 'image-embedder-lambda', - environment: { - "GRID_API_KEY": imageEmbedderApiKey.secretValue.toString() - } }, ); @@ -61,10 +51,10 @@ export class MediaService extends GuStack { imageEmbedderLambda.role?.addToPrincipalPolicy( new PolicyStatement({ actions: [ - 's3vectors:PutVectors', - 's3vectors:GetVectors', - 's3vectors:QueryVectors', - 's3vectors:ListVectors' + 's3vectors:PutVectors', + 's3vectors:GetVectors', + 's3vectors:QueryVectors', + 's3vectors:ListVectors' ], resources: [ `arn:aws:s3vectors:eu-central-1:${Stack.of(this).account}:bucket/image-embeddings-via-lambda/index/*`, @@ -89,7 +79,7 @@ export class MediaService extends GuStack { resources: [ `arn:aws:s3:::image-embedding-test/*`, ], - }), + }), ); } } \ No newline at end of file diff --git a/image-embedder-lambda/.gitignore b/image-embedder-lambda/.gitignore index 4c59576d843..945ce43a909 100644 --- a/image-embedder-lambda/.gitignore +++ b/image-embedder-lambda/.gitignore @@ -1 +1 @@ -out.js \ No newline at end of file +index.js \ No newline at end of file diff --git a/image-embedder-lambda/src/index.ts b/image-embedder-lambda/src/index.ts index b3982531f97..85429fc8040 100644 --- a/image-embedder-lambda/src/index.ts +++ b/image-embedder-lambda/src/index.ts @@ -1,31 +1,19 @@ -// We are going to write to an SQS queue in image loader instead -// We want to make sure that we only write to the queue at the very end, -// when the record is successfully in ES -// Then the handler will embed and can do it in batches -// It's not easy to get it to take batches of 10 at a time but we can investigate -// Whether it's worth it to do that -// We can also reuse the lambda for the backfill - -// Send the S3 link to the image via image-loader - -import { Context, SQSEvent, SQSRecord } from 'aws-lambda'; +import { Context, PreSignUpTriggerHandler, SQSEvent, SQSRecord } from 'aws-lambda'; import { BedrockRuntimeClient, InvokeModelCommand, InvokeModelCommandInput, InvokeModelCommandOutput, ServiceInputTypes } from "@aws-sdk/client-bedrock-runtime"; import { GetObjectCommand, GetObjectCommandOutput, GetObjectRequest, S3Client } from "@aws-sdk/client-s3" import { PutInputVector, PutVectorsCommand, PutVectorsCommandInput, S3VectorsClient, VectorData } from "@aws-sdk/client-s3vectors" - - -const model: string = "cohere.embed-english-v3"; -const config = {region: "eu-west-1"}; -const bedrockClient = new BedrockRuntimeClient(config); -const s3Client = new S3Client(config); -const s3VectorsClient = new S3VectorsClient({ region: "eu-central-1" }); interface SQSMessageBody { imageId: string; bucket: string; filePath: string; + fileType: string; } -async function getImageFromS3(bucket: string, filePath: string): Promise { +async function getImageFromS3( + bucket: string, + filePath: string, + client: S3Client +): Promise { const input: GetObjectRequest = { Bucket: bucket, @@ -36,18 +24,14 @@ async function getImageFromS3(bucket: string, filePath: string): Promise { +async function embedImage( + inputData: String[], + client: BedrockRuntimeClient +): Promise { + + const model = "cohere.embed-english-v3"; const body = { input_type: "image", embedding_types: ["float"], @@ -90,7 +79,7 @@ async function embedImage(inputData: String[]): Promise { console.log(`Starting handler embedding pipeline`); const records: SQSRecord[] = event.Records; const recordBody: SQSMessageBody = JSON.parse(records[0].body); - - const gridImage = await getImageFromS3(recordBody.bucket, recordBody.filePath); + const config = {region: "eu-west-1"}; + + // Iff it's a Tiff then we should just exit + // It shouldn't end up on the DLQ because we won't be able to process it at all + if (recordBody.fileType === "image/tiff") { + console.log(`Unsupported file type: ${recordBody.fileType}, ending execution`); + return + } + + const s3Client = new S3Client(config); + const gridImage = await getImageFromS3(recordBody.bucket, recordBody.filePath, s3Client); const base64Image = Buffer.from(gridImage).toString('base64'); - const inputImage = `data:image/jpg;base64,${base64Image}` + const inputImage = `data:${recordBody.fileType};base64,${base64Image}` - // TODO: downscale image if neceesary + // TODO: downscale image if necessary + // Currently the image will end up on the DLQ if it's too big + // because the embedding will fail - const embeddingResponse = await embedImage([inputImage]); - - // Parse the response body (it's a Uint8Array that needs to be decoded) + const bedrockClient = new BedrockRuntimeClient(config); + const embeddingResponse = await embedImage([inputImage], bedrockClient); const responseBody = JSON.parse(new TextDecoder().decode(embeddingResponse.body)); - // Extract the embedding array (first element since we only sent one image) const embedding: number[] = responseBody.embeddings.float[0]; console.log(`Embedding length: ${embedding.length}`); console.log(`First 5 values: ${embedding.slice(0, 5)}`); - const store = await storeEmbedding(embedding, recordBody.imageId); + const s3VectorsClient = new S3VectorsClient({ region: "eu-central-1" }); + await storeEmbedding(embedding, recordBody.imageId, s3VectorsClient); + + console.log(`Finished image image pipeline successfully!`) }; \ No newline at end of file diff --git a/scripts/embedder-deploy/send-message.sh b/scripts/embedder-deploy/send-message.sh index fd3952fe046..fed14a2243f 100755 --- a/scripts/embedder-deploy/send-message.sh +++ b/scripts/embedder-deploy/send-message.sh @@ -18,7 +18,7 @@ QUEUE_URL=$( aws sqs send-message \ --queue-url "$QUEUE_URL" \ --message-body \ - '{"imageId": "3909f6ce899a70ebaf7065fe10f28fe4ebcff6d3", "bucket": "image-embedding-test", "filePath": "test-folder/Rex_Shutterstock_QuinsvBayonne_16081571ib (6b3eb5ee8562807483e165144d46d0dac0571773).jpg"}' \ + '{"imageId": "793e7c27f213ed60b32bace6957fac428af8dbe2", "fileType": "image/tiff", "bucket": "image-embedding-test", "filePath": "test-folder/Edita Schubert ca 1983. Photo Marijan Susovski (793e7c27f213ed60b32bace6957fac428af8dbe2).tiff "}' \ --profile media-service \ --region eu-west-1 From 6b2a03acbf9458608ae3ed954ba3bbe995fa3a82 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Thu, 18 Dec 2025 14:10:27 +0000 Subject: [PATCH 036/494] add script to check if image is in S3 vector store --- .../embedder-deploy/get-s3-vector-by-key.sh | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100755 scripts/embedder-deploy/get-s3-vector-by-key.sh diff --git a/scripts/embedder-deploy/get-s3-vector-by-key.sh b/scripts/embedder-deploy/get-s3-vector-by-key.sh new file mode 100755 index 00000000000..70c8e036bcf --- /dev/null +++ b/scripts/embedder-deploy/get-s3-vector-by-key.sh @@ -0,0 +1,26 @@ +#!/bin/bash +set -euo pipefail + +if [ $# -lt 1 ]; then + echo "Error: Index name and vector key arguments are required" + echo "" + echo "Usage: $0 " + echo "" + echo "Example:" + echo " $0 9e3fec5784b8e203b9ee6139477d689cc9162c9a" + exit 1 +fi + +VECTOR_KEY="$1" + +# Write this to stderr so we can pipe get-vectors stdout to jq +>&2 echo "Fetching vector with key: ${VECTOR_KEY} from" + +aws s3vectors get-vectors \ + --vector-bucket-name image-embeddings-via-lambda \ + --index-name cohere-embed-english-v3 \ + --return-data \ + --keys "${VECTOR_KEY}" \ + --return-metadata \ + --profile media-service \ + --region eu-central-1 \ No newline at end of file From 47aacc21c66dd13baf409ee862793dceb4a4ba27 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Thu, 18 Dec 2025 14:10:45 +0000 Subject: [PATCH 037/494] throw error for tiff --- image-embedder-lambda/src/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/image-embedder-lambda/src/index.ts b/image-embedder-lambda/src/index.ts index 85429fc8040..b0ed8d19799 100644 --- a/image-embedder-lambda/src/index.ts +++ b/image-embedder-lambda/src/index.ts @@ -145,11 +145,11 @@ export const handler = async (event: SQSEvent, context: Context) => { const config = {region: "eu-west-1"}; - // Iff it's a Tiff then we should just exit + // If it's a Tiff then we should just exit // It shouldn't end up on the DLQ because we won't be able to process it at all if (recordBody.fileType === "image/tiff") { - console.log(`Unsupported file type: ${recordBody.fileType}, ending execution`); - return + console.error(`Unsupported file type: ${recordBody.fileType}, ending execution`); + throw new Error(`Unsupported file type: ${recordBody.fileType}`); } const s3Client = new S3Client(config); From d848b44001c5f3efe2983cc3c3a215c11dfa723a Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Thu, 18 Dec 2025 14:18:45 +0000 Subject: [PATCH 038/494] fix copy paste error --- scripts/embedder-deploy/get-s3-vector-by-key.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/embedder-deploy/get-s3-vector-by-key.sh b/scripts/embedder-deploy/get-s3-vector-by-key.sh index 70c8e036bcf..5c9a5aad809 100755 --- a/scripts/embedder-deploy/get-s3-vector-by-key.sh +++ b/scripts/embedder-deploy/get-s3-vector-by-key.sh @@ -2,7 +2,7 @@ set -euo pipefail if [ $# -lt 1 ]; then - echo "Error: Index name and vector key arguments are required" + echo "Error: Vector key argument is required" echo "" echo "Usage: $0 " echo "" From 379c2541a5016c891a6e2893d60532d912ebd10d Mon Sep 17 00:00:00 2001 From: Andrew Nowak Date: Mon, 22 Dec 2025 11:42:11 +0000 Subject: [PATCH 039/494] upgrade play to 3.0.10 --- project/plugins.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/plugins.sbt b/project/plugins.sbt index 3f3177253fc..2e922a3d71a 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,6 +1,6 @@ libraryDependencies += "org.vafer" % "jdeb" % "1.3" artifacts (Artifact("jdeb", "jar", "jar")) -addSbtPlugin("org.playframework" % "sbt-plugin" % "3.0.5") +addSbtPlugin("org.playframework" % "sbt-plugin" % "3.0.10") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.9.0") From a4fe72b940606aa49dfb7cf42f900b8940c60915 Mon Sep 17 00:00:00 2001 From: Andrew Nowak Date: Mon, 22 Dec 2025 11:46:59 +0000 Subject: [PATCH 040/494] upgrade scala to 2.13.18 --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 5b8acc6fe62..dbc68489a73 100644 --- a/build.sbt +++ b/build.sbt @@ -21,7 +21,7 @@ ThisBuild / libraryDependencySchemes += "org.scala-lang.modules" %% "scala-java8-compat" % VersionScheme.Always val commonSettings = Seq( - scalaVersion := "2.13.16", + scalaVersion := "2.13.18", description := "grid", organization := "com.gu", version := "0.1", From 4c1e760c712355451940c0a646d28f47beb76aed Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Wed, 7 Jan 2026 11:37:03 +0000 Subject: [PATCH 041/494] update comment --- image-embedder-lambda/src/index.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/image-embedder-lambda/src/index.ts b/image-embedder-lambda/src/index.ts index b0ed8d19799..74d7637c444 100644 --- a/image-embedder-lambda/src/index.ts +++ b/image-embedder-lambda/src/index.ts @@ -145,8 +145,8 @@ export const handler = async (event: SQSEvent, context: Context) => { const config = {region: "eu-west-1"}; - // If it's a Tiff then we should just exit - // It shouldn't end up on the DLQ because we won't be able to process it at all + // If it's a Tiff then we should throw an error + // So that it ends on the DLQ for processing when we add tiff handling if (recordBody.fileType === "image/tiff") { console.error(`Unsupported file type: ${recordBody.fileType}, ending execution`); throw new Error(`Unsupported file type: ${recordBody.fileType}`); From c5be661026139c4ea9f9879159d0dc6302a82618 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Wed, 7 Jan 2026 11:42:19 +0000 Subject: [PATCH 042/494] action https://github.com/guardian/grid/pull/4576\#discussion_r2634421694 --- image-embedder-lambda/src/index.ts | 18 +++++++++--------- scripts/embedder-deploy/send-message.sh | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/image-embedder-lambda/src/index.ts b/image-embedder-lambda/src/index.ts index 74d7637c444..27bb4831fa3 100644 --- a/image-embedder-lambda/src/index.ts +++ b/image-embedder-lambda/src/index.ts @@ -1,26 +1,26 @@ -import { Context, PreSignUpTriggerHandler, SQSEvent, SQSRecord } from 'aws-lambda'; +import { Context, SQSEvent, SQSRecord } from 'aws-lambda'; import { BedrockRuntimeClient, InvokeModelCommand, InvokeModelCommandInput, InvokeModelCommandOutput, ServiceInputTypes } from "@aws-sdk/client-bedrock-runtime"; import { GetObjectCommand, GetObjectCommandOutput, GetObjectRequest, S3Client } from "@aws-sdk/client-s3" import { PutInputVector, PutVectorsCommand, PutVectorsCommandInput, S3VectorsClient, VectorData } from "@aws-sdk/client-s3vectors" interface SQSMessageBody { imageId: string; - bucket: string; - filePath: string; + s3Bucket: string; + s3Key: string; fileType: string; } async function getImageFromS3( - bucket: string, - filePath: string, + s3Bucket: string, + s3Key: string, client: S3Client ): Promise { const input: GetObjectRequest = { - Bucket: bucket, - Key: filePath, + Bucket: s3Bucket, + Key: s3Key, }; - console.log(`Fetching image from S3: bucket=${bucket}, key=${filePath}`); + console.log(`Fetching image from S3: bucket=${s3Bucket}, key=${s3Key}`); try { const command = new GetObjectCommand(input); @@ -153,7 +153,7 @@ export const handler = async (event: SQSEvent, context: Context) => { } const s3Client = new S3Client(config); - const gridImage = await getImageFromS3(recordBody.bucket, recordBody.filePath, s3Client); + const gridImage = await getImageFromS3(recordBody.s3Bucket, recordBody.s3Key, s3Client); const base64Image = Buffer.from(gridImage).toString('base64'); const inputImage = `data:${recordBody.fileType};base64,${base64Image}` diff --git a/scripts/embedder-deploy/send-message.sh b/scripts/embedder-deploy/send-message.sh index fed14a2243f..d9f8e3674d7 100755 --- a/scripts/embedder-deploy/send-message.sh +++ b/scripts/embedder-deploy/send-message.sh @@ -18,7 +18,7 @@ QUEUE_URL=$( aws sqs send-message \ --queue-url "$QUEUE_URL" \ --message-body \ - '{"imageId": "793e7c27f213ed60b32bace6957fac428af8dbe2", "fileType": "image/tiff", "bucket": "image-embedding-test", "filePath": "test-folder/Edita Schubert ca 1983. Photo Marijan Susovski (793e7c27f213ed60b32bace6957fac428af8dbe2).tiff "}' \ + '{"imageId": "793e7c27f213ed60b32bace6957fac428af8dbe2", "fileType": "image/tiff", "s3Bucket": "image-embedding-test", "s3Key": "test-folder/Edita Schubert ca 1983. Photo Marijan Susovski (793e7c27f213ed60b32bace6957fac428af8dbe2).tiff "}' \ --profile media-service \ --region eu-west-1 From 89db663b14767bb7b9bbe01778c8af88e7411fe4 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Wed, 7 Jan 2026 11:56:31 +0000 Subject: [PATCH 043/494] remove fetch and add args to send message script --- image-embedder-lambda/package.json | 3 +-- scripts/embedder-deploy/send-message.sh | 13 ++++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/image-embedder-lambda/package.json b/image-embedder-lambda/package.json index 225be196ac3..72065c3c643 100644 --- a/image-embedder-lambda/package.json +++ b/image-embedder-lambda/package.json @@ -17,7 +17,6 @@ "dependencies": { "@aws-sdk/client-bedrock-runtime": "^3.948.0", "@aws-sdk/client-s3": "^3.948.0", - "@aws-sdk/client-s3vectors": "^3.952.0", - "node-fetch": "^3.3.2" + "@aws-sdk/client-s3vectors": "^3.952.0" } } diff --git a/scripts/embedder-deploy/send-message.sh b/scripts/embedder-deploy/send-message.sh index d9f8e3674d7..b846919c7a8 100755 --- a/scripts/embedder-deploy/send-message.sh +++ b/scripts/embedder-deploy/send-message.sh @@ -1,6 +1,17 @@ #!/bin/bash set -euo pipefail +# Check for required arguments +if [ $# -ne 4 ]; then + echo "Usage: $0 " + exit 1 +fi + +IMAGE_ID="$1" +FILE_TYPE="$2" +S3_BUCKET="$3" +S3_KEY="$4" + # Fixed stage STAGE="TEST" @@ -18,7 +29,7 @@ QUEUE_URL=$( aws sqs send-message \ --queue-url "$QUEUE_URL" \ --message-body \ - '{"imageId": "793e7c27f213ed60b32bace6957fac428af8dbe2", "fileType": "image/tiff", "s3Bucket": "image-embedding-test", "s3Key": "test-folder/Edita Schubert ca 1983. Photo Marijan Susovski (793e7c27f213ed60b32bace6957fac428af8dbe2).tiff "}' \ + "{\"imageId\": \"${IMAGE_ID}\", \"fileType\": \"${FILE_TYPE}\", \"s3Bucket\": \"${S3_BUCKET}\", \"s3Key\": \"${S3_KEY}\"}" \ --profile media-service \ --region eu-west-1 From 006ce57c43eaacca157dabaf24868a58f8d1feea Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Wed, 7 Jan 2026 12:10:35 +0000 Subject: [PATCH 044/494] remove superfluous error logging --- image-embedder-lambda/src/index.ts | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/image-embedder-lambda/src/index.ts b/image-embedder-lambda/src/index.ts index 27bb4831fa3..02ba527461e 100644 --- a/image-embedder-lambda/src/index.ts +++ b/image-embedder-lambda/src/index.ts @@ -47,11 +47,6 @@ async function getImageFromS3( return bytes; } catch (error) { console.error(`Error fetching from S3:`, error); - if (error instanceof Error) { - console.error(`Error name: ${error.name}`); - console.error(`Error message: ${error.message}`); - console.error(`Error stack: ${error.stack}`); - } throw error; } } @@ -87,10 +82,6 @@ async function embedImage( return response; } catch (error) { console.error(`Bedrock invocation error:`, error); - if (error instanceof Error) { - console.error(`Error name: ${error.name}`); - console.error(`Error message: ${error.message}`); - } throw error; } } @@ -128,11 +119,6 @@ async function storeEmbedding( return response; } catch (error) { console.error(`Error storing embedding for key: ${key}`, error); - if (error instanceof Error) { - console.error(`Error name: ${error.name}`); - console.error(`Error message: ${error.message}`); - console.error(`Error stack: ${error.stack}`); - } throw error; } } From 7502635465856a21a4cdb80e687aa166f2072a65 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Wed, 7 Jan 2026 15:19:14 +0000 Subject: [PATCH 045/494] initialise clients outside of handler --- image-embedder-lambda/src/index.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/image-embedder-lambda/src/index.ts b/image-embedder-lambda/src/index.ts index 02ba527461e..952d0ab969f 100644 --- a/image-embedder-lambda/src/index.ts +++ b/image-embedder-lambda/src/index.ts @@ -2,6 +2,13 @@ import { Context, SQSEvent, SQSRecord } from 'aws-lambda'; import { BedrockRuntimeClient, InvokeModelCommand, InvokeModelCommandInput, InvokeModelCommandOutput, ServiceInputTypes } from "@aws-sdk/client-bedrock-runtime"; import { GetObjectCommand, GetObjectCommandOutput, GetObjectRequest, S3Client } from "@aws-sdk/client-s3" import { PutInputVector, PutVectorsCommand, PutVectorsCommandInput, S3VectorsClient, VectorData } from "@aws-sdk/client-s3vectors" + +// Initialise clients at module level (cold start only) +const config = { region: "eu-west-1" }; +const s3Client = new S3Client(config); +const bedrockClient = new BedrockRuntimeClient(config); +const s3VectorsClient = new S3VectorsClient({ region: "eu-central-1" }); + interface SQSMessageBody { imageId: string; s3Bucket: string; @@ -138,7 +145,6 @@ export const handler = async (event: SQSEvent, context: Context) => { throw new Error(`Unsupported file type: ${recordBody.fileType}`); } - const s3Client = new S3Client(config); const gridImage = await getImageFromS3(recordBody.s3Bucket, recordBody.s3Key, s3Client); const base64Image = Buffer.from(gridImage).toString('base64'); const inputImage = `data:${recordBody.fileType};base64,${base64Image}` @@ -147,7 +153,6 @@ export const handler = async (event: SQSEvent, context: Context) => { // Currently the image will end up on the DLQ if it's too big // because the embedding will fail - const bedrockClient = new BedrockRuntimeClient(config); const embeddingResponse = await embedImage([inputImage], bedrockClient); const responseBody = JSON.parse(new TextDecoder().decode(embeddingResponse.body)); // Extract the embedding array (first element since we only sent one image) @@ -156,7 +161,6 @@ export const handler = async (event: SQSEvent, context: Context) => { console.log(`Embedding length: ${embedding.length}`); console.log(`First 5 values: ${embedding.slice(0, 5)}`); - const s3VectorsClient = new S3VectorsClient({ region: "eu-central-1" }); await storeEmbedding(embedding, recordBody.imageId, s3VectorsClient); console.log(`Finished image image pipeline successfully!`) From a42281120a891ffc510d5ae23dfbe7178abd63a8 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Wed, 7 Jan 2026 15:30:26 +0000 Subject: [PATCH 046/494] add type checking --- .github/workflows/ci.yml | 2 +- image-embedder-lambda/package-lock.json | 4282 ++++++++++++++++- image-embedder-lambda/package.json | 10 +- image-embedder-lambda/tsconfig.json | 2 +- image-embedder.zip | Bin 0 -> 294594 bytes .../embedder-deploy/{bundle.sh => build.sh} | 2 +- 6 files changed, 4209 insertions(+), 89 deletions(-) create mode 100644 image-embedder.zip rename scripts/embedder-deploy/{bundle.sh => build.sh} (86%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 60981deeb50..255bdac9776 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -81,7 +81,7 @@ jobs: - name: Image embedder cdk run: ./scripts/embedder-deploy/cdk.sh - name: Image embedder bundling - run: ./scripts/embedder-deploy/bundle.sh + run: ./scripts/embedder-deploy/build.sh - uses: guardian/actions-riff-raff@v4.2.3 if: "! github.event.pull_request.head.repo.fork" with: diff --git a/image-embedder-lambda/package-lock.json b/image-embedder-lambda/package-lock.json index 6d6778149a7..5ba638ba166 100644 --- a/image-embedder-lambda/package-lock.json +++ b/image-embedder-lambda/package-lock.json @@ -11,13 +11,16 @@ "dependencies": { "@aws-sdk/client-bedrock-runtime": "^3.948.0", "@aws-sdk/client-s3": "^3.948.0", - "@aws-sdk/client-s3vectors": "^3.952.0", - "node-fetch": "^3.3.2" + "@aws-sdk/client-s3vectors": "^3.952.0" }, "devDependencies": { "@types/aws-lambda": "^8.10.159", "@types/node": "^25.0.0", - "esbuild": "0.27.0" + "esbuild": "0.27.0", + "install": "^0.13.0", + "npm": "^11.7.0", + "npm-run-all": "^4.1.5", + "typescript": "^5.9.3" } }, "node_modules/@aws-crypto/crc32": { @@ -2440,19 +2443,463 @@ "undici-types": "~7.16.0" } }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", + "integrity": "sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz", + "integrity": "sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", + "integrity": "sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/bowser": { "version": "2.13.1", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.13.1.tgz", "integrity": "sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw==", "license": "MIT" }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", + "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "dev": true, "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, "engines": { - "node": ">= 12" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-spawn": { + "version": "6.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", + "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", + "integrity": "sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz", + "integrity": "sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz", + "integrity": "sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/error-ex": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.1.tgz", + "integrity": "sha512-zHXBLhP+QehSSbsS9Pt23Gg964240DPd6QCf8WpkqEXxQ7fhdZzYsocOr5u7apWonsS5EjZDmTF+/slGMyasvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", + "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/esbuild": { @@ -2497,6 +2944,16 @@ "@esbuild/win32-x64": "0.27.0" } }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/fast-xml-parser": { "version": "5.2.5", "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.2.5.tgz", @@ -2515,111 +2972,3768 @@ "fxparser": "src/cli/cli.js" } }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], + "node_modules/for-each": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", + "dev": true, "license": "MIT", "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" + "is-callable": "^1.2.7" }, "engines": { - "node": "^12.20 || >= 14.13" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", + "node_modules/function.prototype.name": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", + "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "dev": true, "license": "MIT", "dependencies": { - "fetch-blob": "^3.1.2" + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" }, "engines": { - "node": ">=12.20.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "deprecated": "Use your platform's native DOMException instead", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, "license": "MIT", "engines": { - "node": ">=10.5.0" + "node": ">= 0.4" } }, - "node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, "license": "MIT", "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/strnum": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.1.tgz", - "integrity": "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT" - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "license": "0BSD" - }, - "node_modules/undici-types": { - "version": "7.16.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", - "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.1.0.tgz", + "integrity": "sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", + "integrity": "sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.2.0.tgz", + "integrity": "sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/install": { + "version": "0.13.0", + "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz", + "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", + "integrity": "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.5.tgz", + "integrity": "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", + "integrity": "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.1.0.tgz", + "integrity": "sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.2.tgz", + "integrity": "sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.1.0.tgz", + "integrity": "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz", + "integrity": "sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.3.tgz", + "integrity": "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", + "integrity": "sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.3.tgz", + "integrity": "sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz", + "integrity": "sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.1.1.tgz", + "integrity": "sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", + "integrity": "sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.15.tgz", + "integrity": "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.2.tgz", + "integrity": "sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.4.tgz", + "integrity": "sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true, + "license": "MIT" + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/memorystream": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz", + "integrity": "sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==", + "dev": true, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/npm": { + "version": "11.7.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-11.7.0.tgz", + "integrity": "sha512-wiCZpv/41bIobCoJ31NStIWKfAxxYyD1iYnWCtiyns8s5v3+l8y0HCP/sScuH6B5+GhIfda4HQKiqeGZwJWhFw==", + "bundleDependencies": [ + "@isaacs/string-locale-compare", + "@npmcli/arborist", + "@npmcli/config", + "@npmcli/fs", + "@npmcli/map-workspaces", + "@npmcli/metavuln-calculator", + "@npmcli/package-json", + "@npmcli/promise-spawn", + "@npmcli/redact", + "@npmcli/run-script", + "@sigstore/tuf", + "abbrev", + "archy", + "cacache", + "chalk", + "ci-info", + "cli-columns", + "fastest-levenshtein", + "fs-minipass", + "glob", + "graceful-fs", + "hosted-git-info", + "ini", + "init-package-json", + "is-cidr", + "json-parse-even-better-errors", + "libnpmaccess", + "libnpmdiff", + "libnpmexec", + "libnpmfund", + "libnpmorg", + "libnpmpack", + "libnpmpublish", + "libnpmsearch", + "libnpmteam", + "libnpmversion", + "make-fetch-happen", + "minimatch", + "minipass", + "minipass-pipeline", + "ms", + "node-gyp", + "nopt", + "npm-audit-report", + "npm-install-checks", + "npm-package-arg", + "npm-pick-manifest", + "npm-profile", + "npm-registry-fetch", + "npm-user-validate", + "p-map", + "pacote", + "parse-conflict-json", + "proc-log", + "qrcode-terminal", + "read", + "semver", + "spdx-expression-parse", + "ssri", + "supports-color", + "tar", + "text-table", + "tiny-relative-date", + "treeverse", + "validate-npm-package-name", + "which" + ], + "dev": true, + "license": "Artistic-2.0", + "workspaces": [ + "docs", + "smoke-tests", + "mock-globals", + "mock-registry", + "workspaces/*" + ], + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/arborist": "^9.1.9", + "@npmcli/config": "^10.4.5", + "@npmcli/fs": "^5.0.0", + "@npmcli/map-workspaces": "^5.0.3", + "@npmcli/metavuln-calculator": "^9.0.3", + "@npmcli/package-json": "^7.0.4", + "@npmcli/promise-spawn": "^9.0.1", + "@npmcli/redact": "^4.0.0", + "@npmcli/run-script": "^10.0.3", + "@sigstore/tuf": "^4.0.0", + "abbrev": "^4.0.0", + "archy": "~1.0.0", + "cacache": "^20.0.3", + "chalk": "^5.6.2", + "ci-info": "^4.3.1", + "cli-columns": "^4.0.0", + "fastest-levenshtein": "^1.0.16", + "fs-minipass": "^3.0.3", + "glob": "^13.0.0", + "graceful-fs": "^4.2.11", + "hosted-git-info": "^9.0.2", + "ini": "^6.0.0", + "init-package-json": "^8.2.4", + "is-cidr": "^6.0.1", + "json-parse-even-better-errors": "^5.0.0", + "libnpmaccess": "^10.0.3", + "libnpmdiff": "^8.0.12", + "libnpmexec": "^10.1.11", + "libnpmfund": "^7.0.12", + "libnpmorg": "^8.0.1", + "libnpmpack": "^9.0.12", + "libnpmpublish": "^11.1.3", + "libnpmsearch": "^9.0.1", + "libnpmteam": "^8.0.2", + "libnpmversion": "^8.0.3", + "make-fetch-happen": "^15.0.3", + "minimatch": "^10.1.1", + "minipass": "^7.1.1", + "minipass-pipeline": "^1.2.4", + "ms": "^2.1.2", + "node-gyp": "^12.1.0", + "nopt": "^9.0.0", + "npm-audit-report": "^7.0.0", + "npm-install-checks": "^8.0.0", + "npm-package-arg": "^13.0.2", + "npm-pick-manifest": "^11.0.3", + "npm-profile": "^12.0.1", + "npm-registry-fetch": "^19.1.1", + "npm-user-validate": "^4.0.0", + "p-map": "^7.0.4", + "pacote": "^21.0.4", + "parse-conflict-json": "^5.0.1", + "proc-log": "^6.1.0", + "qrcode-terminal": "^0.12.0", + "read": "^5.0.1", + "semver": "^7.7.3", + "spdx-expression-parse": "^4.0.0", + "ssri": "^13.0.0", + "supports-color": "^10.2.2", + "tar": "^7.5.2", + "text-table": "~0.2.0", + "tiny-relative-date": "^2.0.2", + "treeverse": "^3.0.0", + "validate-npm-package-name": "^7.0.0", + "which": "^6.0.0" + }, + "bin": { + "npm": "bin/npm-cli.js", + "npx": "bin/npx-cli.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-run-all": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", + "integrity": "sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "memorystream": "^0.3.1", + "minimatch": "^3.0.4", + "pidtree": "^0.3.0", + "read-pkg": "^3.0.0", + "shell-quote": "^1.6.1", + "string.prototype.padend": "^3.0.0" + }, + "bin": { + "npm-run-all": "bin/npm-run-all/index.js", + "run-p": "bin/run-p/index.js", + "run-s": "bin/run-s/index.js" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm/node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/npm/node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/npm/node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/npm/node_modules/@isaacs/string-locale-compare": { + "version": "1.1.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/@npmcli/agent": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^11.2.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/arborist": { + "version": "9.1.9", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@isaacs/string-locale-compare": "^1.1.0", + "@npmcli/fs": "^5.0.0", + "@npmcli/installed-package-contents": "^4.0.0", + "@npmcli/map-workspaces": "^5.0.0", + "@npmcli/metavuln-calculator": "^9.0.2", + "@npmcli/name-from-folder": "^4.0.0", + "@npmcli/node-gyp": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/query": "^5.0.0", + "@npmcli/redact": "^4.0.0", + "@npmcli/run-script": "^10.0.0", + "bin-links": "^6.0.0", + "cacache": "^20.0.1", + "common-ancestor-path": "^1.0.1", + "hosted-git-info": "^9.0.0", + "json-stringify-nice": "^1.1.4", + "lru-cache": "^11.2.1", + "minimatch": "^10.0.3", + "nopt": "^9.0.0", + "npm-install-checks": "^8.0.0", + "npm-package-arg": "^13.0.0", + "npm-pick-manifest": "^11.0.1", + "npm-registry-fetch": "^19.0.0", + "pacote": "^21.0.2", + "parse-conflict-json": "^5.0.1", + "proc-log": "^6.0.0", + "proggy": "^4.0.0", + "promise-all-reject-late": "^1.0.0", + "promise-call-limit": "^3.0.1", + "semver": "^7.3.7", + "ssri": "^13.0.0", + "treeverse": "^3.0.0", + "walk-up-path": "^4.0.0" + }, + "bin": { + "arborist": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/config": { + "version": "10.4.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/map-workspaces": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "ci-info": "^4.0.0", + "ini": "^6.0.0", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "walk-up-path": "^4.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/fs": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/git": { + "version": "7.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^9.0.0", + "ini": "^6.0.0", + "lru-cache": "^11.2.1", + "npm-pick-manifest": "^11.0.1", + "proc-log": "^6.0.0", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/installed-package-contents": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^5.0.0", + "npm-normalize-package-bin": "^5.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/map-workspaces": { + "version": "5.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/name-from-folder": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "glob": "^13.0.0", + "minimatch": "^10.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { + "version": "9.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "cacache": "^20.0.0", + "json-parse-even-better-errors": "^5.0.0", + "pacote": "^21.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/name-from-folder": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/node-gyp": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/package-json": { + "version": "7.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^7.0.0", + "glob": "^13.0.0", + "hosted-git-info": "^9.0.0", + "json-parse-even-better-errors": "^5.0.0", + "proc-log": "^6.0.0", + "semver": "^7.5.3", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/promise-spawn": { + "version": "9.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/query": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/redact": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@npmcli/run-script": { + "version": "10.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "node-gyp": "^12.1.0", + "proc-log": "^6.0.0", + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@sigstore/bundle": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.5.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@sigstore/core": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@sigstore/protobuf-specs": { + "version": "0.5.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@sigstore/sign": { + "version": "4.0.1", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.0.0", + "@sigstore/protobuf-specs": "^0.5.0", + "make-fetch-happen": "^15.0.2", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@sigstore/sign/node_modules/proc-log": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm/node_modules/@sigstore/tuf": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.5.0", + "tuf-js": "^4.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@sigstore/verify": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.0.0", + "@sigstore/protobuf-specs": "^0.5.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/@tufjs/models": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/@tufjs/models/node_modules/minimatch": { + "version": "9.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/abbrev": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/agent-base": { + "version": "7.1.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/aproba": { + "version": "2.1.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/archy": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/bin-links": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "cmd-shim": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "proc-log": "^6.0.0", + "read-cmd-shim": "^6.0.0", + "write-file-atomic": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/binary-extensions": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/brace-expansion": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/npm/node_modules/cacache": { + "version": "20.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^5.0.0", + "fs-minipass": "^3.0.0", + "glob": "^13.0.0", + "lru-cache": "^11.1.0", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^13.0.0", + "unique-filename": "^5.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/chalk": { + "version": "5.6.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/npm/node_modules/chownr": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/ci-info": { + "version": "4.3.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/cidr-regex": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "ip-regex": "5.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/npm/node_modules/cli-columns": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/npm/node_modules/cmd-shim": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/common-ancestor-path": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/cssesc": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/debug": { + "version": "4.4.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/npm/node_modules/diff": { + "version": "8.0.2", + "dev": true, + "inBundle": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/npm/node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/encoding": { + "version": "0.1.13", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/npm/node_modules/env-paths": { + "version": "2.2.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/npm/node_modules/err-code": { + "version": "2.0.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/exponential-backoff": { + "version": "3.1.3", + "dev": true, + "inBundle": true, + "license": "Apache-2.0" + }, + "node_modules/npm/node_modules/fastest-levenshtein": { + "version": "1.0.16", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/npm/node_modules/fs-minipass": { + "version": "3.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/glob": { + "version": "13.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/npm/node_modules/hosted-git-info": { + "version": "9.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^11.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/http-cache-semantics": { + "version": "4.2.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause" + }, + "node_modules/npm/node_modules/http-proxy-agent": { + "version": "7.0.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/https-proxy-agent": { + "version": "7.0.6", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm/node_modules/ignore-walk": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minimatch": "^10.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/npm/node_modules/ini": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/init-package-json": { + "version": "8.2.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/package-json": "^7.0.0", + "npm-package-arg": "^13.0.0", + "promzard": "^3.0.1", + "read": "^5.0.1", + "semver": "^7.7.2", + "validate-npm-package-license": "^3.0.4", + "validate-npm-package-name": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/ip-address": { + "version": "10.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, + "node_modules/npm/node_modules/ip-regex": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/is-cidr": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "cidr-regex": "5.0.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/npm/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/isexe": { + "version": "3.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/npm/node_modules/json-parse-even-better-errors": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/json-stringify-nice": { + "version": "1.1.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/jsonparse": { + "version": "1.3.1", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff": { + "version": "6.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/just-diff-apply": { + "version": "5.5.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/libnpmaccess": { + "version": "10.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-package-arg": "^13.0.0", + "npm-registry-fetch": "^19.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmdiff": { + "version": "8.0.12", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^9.1.9", + "@npmcli/installed-package-contents": "^4.0.0", + "binary-extensions": "^3.0.0", + "diff": "^8.0.2", + "minimatch": "^10.0.3", + "npm-package-arg": "^13.0.0", + "pacote": "^21.0.2", + "tar": "^7.5.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmexec": { + "version": "10.1.11", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^9.1.9", + "@npmcli/package-json": "^7.0.0", + "@npmcli/run-script": "^10.0.0", + "ci-info": "^4.0.0", + "npm-package-arg": "^13.0.0", + "pacote": "^21.0.2", + "proc-log": "^6.0.0", + "promise-retry": "^2.0.1", + "read": "^5.0.1", + "semver": "^7.3.7", + "signal-exit": "^4.1.0", + "walk-up-path": "^4.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmfund": { + "version": "7.0.12", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^9.1.9" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmorg": { + "version": "8.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^19.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmpack": { + "version": "9.0.12", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/arborist": "^9.1.9", + "@npmcli/run-script": "^10.0.0", + "npm-package-arg": "^13.0.0", + "pacote": "^21.0.2" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmpublish": { + "version": "11.1.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/package-json": "^7.0.0", + "ci-info": "^4.0.0", + "npm-package-arg": "^13.0.0", + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.7", + "sigstore": "^4.0.0", + "ssri": "^13.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmsearch": { + "version": "9.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^19.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmteam": { + "version": "8.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "aproba": "^2.0.0", + "npm-registry-fetch": "^19.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/libnpmversion": { + "version": "8.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^7.0.0", + "@npmcli/run-script": "^10.0.0", + "json-parse-even-better-errors": "^5.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/lru-cache": { + "version": "11.2.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/npm/node_modules/make-fetch-happen": { + "version": "15.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^4.0.0", + "cacache": "^20.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^6.0.0", + "promise-retry": "^2.0.1", + "ssri": "^13.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/minimatch": { + "version": "10.1.1", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/minipass": { + "version": "7.1.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/npm/node_modules/minipass-collect": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/npm/node_modules/minipass-fetch": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/npm/node_modules/minipass-flush": { + "version": "1.0.5", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-pipeline": { + "version": "1.2.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-sized": { + "version": "1.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/minizlib": { + "version": "3.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/npm/node_modules/ms": { + "version": "2.1.3", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/mute-stream": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/negotiator": { + "version": "1.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm/node_modules/node-gyp": { + "version": "12.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^15.0.0", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "tar": "^7.5.2", + "tinyglobby": "^0.2.12", + "which": "^6.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/nopt": { + "version": "9.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "abbrev": "^4.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-audit-report": { + "version": "7.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-bundled": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^5.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-install-checks": { + "version": "8.0.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-normalize-package-bin": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-package-arg": { + "version": "13.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-packlist": { + "version": "10.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^8.0.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-pick-manifest": { + "version": "11.0.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "npm-package-arg": "^13.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-profile": { + "version": "12.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-registry-fetch": { + "version": "19.1.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^4.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^15.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^13.0.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/npm-user-validate": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "BSD-2-Clause", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/p-map": { + "version": "7.0.4", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm/node_modules/pacote": { + "version": "21.0.4", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^7.0.0", + "@npmcli/installed-package-contents": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "@npmcli/run-script": "^10.0.0", + "cacache": "^20.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^13.0.0", + "npm-packlist": "^10.0.1", + "npm-pick-manifest": "^11.0.1", + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^4.0.0", + "ssri": "^13.0.0", + "tar": "^7.4.3" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/parse-conflict-json": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "json-parse-even-better-errors": "^5.0.0", + "just-diff": "^6.0.0", + "just-diff-apply": "^5.2.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/path-scurry": { + "version": "2.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/postcss-selector-parser": { + "version": "7.1.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/npm/node_modules/proc-log": { + "version": "6.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/proggy": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/promise-all-reject-late": { + "version": "1.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-call-limit": { + "version": "3.0.2", + "dev": true, + "inBundle": true, + "license": "ISC", + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/promise-retry": { + "version": "2.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/promzard": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "read": "^5.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/qrcode-terminal": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "bin": { + "qrcode-terminal": "bin/qrcode-terminal.js" + } + }, + "node_modules/npm/node_modules/read": { + "version": "5.0.1", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "mute-stream": "^3.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/read-cmd-shim": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/retry": { + "version": "0.12.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/npm/node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "optional": true + }, + "node_modules/npm/node_modules/semver": { + "version": "7.7.3", + "dev": true, + "inBundle": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm/node_modules/signal-exit": { + "version": "4.1.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm/node_modules/sigstore": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.0.0", + "@sigstore/protobuf-specs": "^0.5.0", + "@sigstore/sign": "^4.0.0", + "@sigstore/tuf": "^4.0.0", + "@sigstore/verify": "^3.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/smart-buffer": { + "version": "4.2.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks": { + "version": "2.8.7", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/npm/node_modules/socks-proxy-agent": { + "version": "8.0.5", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/npm/node_modules/spdx-correct": { + "version": "3.2.0", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-exceptions": { + "version": "2.5.0", + "dev": true, + "inBundle": true, + "license": "CC-BY-3.0" + }, + "node_modules/npm/node_modules/spdx-expression-parse": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/spdx-license-ids": { + "version": "3.0.22", + "dev": true, + "inBundle": true, + "license": "CC0-1.0" + }, + "node_modules/npm/node_modules/ssri": { + "version": "13.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm/node_modules/supports-color": { + "version": "10.2.2", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/npm/node_modules/tar": { + "version": "7.5.2", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/npm/node_modules/text-table": { + "version": "0.2.0", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/tiny-relative-date": { + "version": "2.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/tinyglobby": { + "version": "0.2.15", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/npm/node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "dev": true, + "inBundle": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/npm/node_modules/treeverse": { + "version": "3.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/npm/node_modules/tuf-js": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "4.0.0", + "debug": "^4.4.1", + "make-fetch-happen": "^15.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/unique-filename": { + "version": "5.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/unique-slug": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "inBundle": true, + "license": "MIT" + }, + "node_modules/npm/node_modules/validate-npm-package-license": { + "version": "3.0.4", + "dev": true, + "inBundle": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "dev": true, + "inBundle": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/npm/node_modules/validate-npm-package-name": { + "version": "7.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/walk-up-path": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/npm/node_modules/which": { + "version": "6.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/write-file-atomic": { + "version": "7.0.0", + "dev": true, + "inBundle": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "inBundle": true, + "license": "ISC" + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.7.tgz", + "integrity": "sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/own-keys": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/own-keys/-/own-keys-1.0.1.tgz", + "integrity": "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "license": "MIT", + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pidtree": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.3.1.tgz", + "integrity": "sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==", + "dev": true, + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", + "integrity": "sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz", + "integrity": "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", + "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz", + "integrity": "sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/set-proto/-/set-proto-1.0.0.tgz", + "integrity": "sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", + "integrity": "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/string.prototype.padend": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz", + "integrity": "sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", + "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", + "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strnum": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.1.tgz", + "integrity": "sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], "license": "MIT" }, - "node_modules/web-streams-polyfill": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, "engines": { - "node": ">= 8" + "node": ">=4" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz", + "integrity": "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz", + "integrity": "sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz", + "integrity": "sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", + "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", + "integrity": "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz", + "integrity": "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.2.1.tgz", + "integrity": "sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", + "integrity": "sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } } } diff --git a/image-embedder-lambda/package.json b/image-embedder-lambda/package.json index 72065c3c643..c007ae40d6e 100644 --- a/image-embedder-lambda/package.json +++ b/image-embedder-lambda/package.json @@ -5,14 +5,20 @@ "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "bundle": "esbuild src/index.ts --bundle --platform=node --target=node24 --format=cjs --outfile=index.js" + "type-check": "tsc --noEmit", + "bundle": "esbuild src/index.ts --bundle --platform=node --target=node24 --format=cjs --outfile=index.js", + "build": "run-p --print-label type-check bundle" }, "author": "", "license": "ISC", "devDependencies": { "@types/aws-lambda": "^8.10.159", "@types/node": "^25.0.0", - "esbuild": "0.27.0" + "esbuild": "0.27.0", + "install": "^0.13.0", + "npm": "^11.7.0", + "npm-run-all": "^4.1.5", + "typescript": "^5.9.3" }, "dependencies": { "@aws-sdk/client-bedrock-runtime": "^3.948.0", diff --git a/image-embedder-lambda/tsconfig.json b/image-embedder-lambda/tsconfig.json index a18d4c5422e..3e1ebf6d164 100644 --- a/image-embedder-lambda/tsconfig.json +++ b/image-embedder-lambda/tsconfig.json @@ -3,7 +3,7 @@ "compilerOptions": { /* Basic Options */ "target": "esnext", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */ - "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ + "module": "nodenext", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ "lib": ["esnext"], /* Specify library files to be included in the compilation. */ /* Module Resolution Options */ "moduleResolution": "nodenext", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ diff --git a/image-embedder.zip b/image-embedder.zip new file mode 100644 index 0000000000000000000000000000000000000000..e280e85d188b050357eb523202b5161475f9350a GIT binary patch literal 294594 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%0DV*Z#IbMJF^mU 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%0D3@$za6ccz47=X-p%Bn9nVMa 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

|#O<@}Ps24rI|-mpB~wR8> o2+in>0&TXi3&$@v;domA3HK_VJU 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 lVBN~#}^sp88_6ddpDC` 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�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%0AejP_q6(Kba&%MRLzgUj~ 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 diff --git a/kahuna/package-lock.json b/kahuna/package-lock.json index 3b2d2ee84dd..62c7f89c83e 100644 --- a/kahuna/package-lock.json +++ b/kahuna/package-lock.json @@ -32,7 +32,7 @@ "pandular": "0.1.6", "pikaday": "1.8.2", "pikaday-time": "1.6.1", - "preact": "10.26.9", + "preact": "10.28.2", "react": "17.0.2", "react-dom": "17.0.2", "react2angular": "4.0.6", @@ -2103,6 +2103,64 @@ "node": ">=10.0.0" } }, + "node_modules/@emnapi/core": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", + "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/core/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, "node_modules/@eslint/eslintrc": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", @@ -3236,6 +3294,19 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3426,6 +3497,25 @@ "node": ">=10.13.0" } }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tybys/wasm-util/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, "node_modules/@types/angular": { "version": "1.8.4", "resolved": "https://registry.npmjs.org/@types/angular/-/angular-1.8.4.tgz", @@ -3874,6 +3964,34 @@ "dev": true, "license": "ISC" }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, "node_modules/@unrs/resolver-binding-darwin-arm64": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", @@ -3888,6 +4006,233 @@ "darwin" ] }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", + "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", + "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@webassemblyjs/ast": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", @@ -13063,9 +13408,9 @@ "dev": true }, "node_modules/preact": { - "version": "10.26.9", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.26.9.tgz", - "integrity": "sha512-SSjF9vcnF27mJK1XyFMNJzFd5u3pQiATFqoaDy03XuN00u4ziveVVEGt5RKJrDR8MHE/wJo9Nnad56RLzS2RMA==", + "version": "10.28.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.28.2.tgz", + "integrity": "sha512-lbteaWGzGHdlIuiJ0l2Jq454m6kcpI1zNje6d8MlGAFlYvP2GO4ibnat7P74Esfz4sPTdM6UxtTwh/d3pwM9JA==", "license": "MIT", "funding": { "type": "opencollective", diff --git a/kahuna/package.json b/kahuna/package.json index 72cafb3f836..df720f45d31 100644 --- a/kahuna/package.json +++ b/kahuna/package.json @@ -27,7 +27,7 @@ "pandular": "0.1.6", "pikaday": "1.8.2", "pikaday-time": "1.6.1", - "preact": "10.26.9", + "preact": "10.28.2", "react": "17.0.2", "react-dom": "17.0.2", "react2angular": "4.0.6", diff --git a/s3watcher/lambda/package-lock.json b/s3watcher/lambda/package-lock.json index 336c13f21b2..a8e168d369e 100644 --- a/s3watcher/lambda/package-lock.json +++ b/s3watcher/lambda/package-lock.json @@ -6350,9 +6350,9 @@ "dev": true }, "node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true, "engines": { "node": ">=0.6" @@ -13602,9 +13602,9 @@ "dev": true }, "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true }, "querystring": { From f029f6aef1c2606b0b744cb8b79a11503b3be433 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Tue, 13 Jan 2026 17:49:21 +0000 Subject: [PATCH 068/494] add to git ignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index ddc1910d454..2c7ae6ca997 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ dev/config/permissions.json coverage/ .bsp + +image-embedder.zip \ No newline at end of file From b99fbe3d0e477894cc4e1f6ade3bcb88f89465af Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Tue, 13 Jan 2026 17:52:25 +0000 Subject: [PATCH 069/494] action comments --- cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap | 1 + cdk/lib/image-embedder-lambda.ts | 1 + scripts/embedder-deploy/build.sh | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap index 577811d163a..423b805cbdf 100644 --- a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap +++ b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap @@ -359,6 +359,7 @@ exports[`The MediaService stack matches the snapshot 1`] = ` "imageEmbedderDLQ4A6F48C5": { "DeletionPolicy": "Delete", "Properties": { + "MessageRetentionPeriod": 1209600, "QueueName": "image-embedder-DLQ-TEST", "Tags": [ { diff --git a/cdk/lib/image-embedder-lambda.ts b/cdk/lib/image-embedder-lambda.ts index 9063dd4ec72..801af3cc1ac 100644 --- a/cdk/lib/image-embedder-lambda.ts +++ b/cdk/lib/image-embedder-lambda.ts @@ -29,6 +29,7 @@ export class ImageEmbedder extends GuStack { const imageEmbedderDLQ = new Queue(this, 'imageEmbedderDLQ', { queueName: `image-embedder-DLQ-${this.stage}`, + retentionPeriod: Duration.days(14) }); const imageEmbedderQueue = new Queue( diff --git a/scripts/embedder-deploy/build.sh b/scripts/embedder-deploy/build.sh index b35b7aec19c..98ce0a1e5b3 100755 --- a/scripts/embedder-deploy/build.sh +++ b/scripts/embedder-deploy/build.sh @@ -4,7 +4,7 @@ set -e ( cd image-embedder-lambda - npm install + npm ci npm run build cd dist zip -r ../../image-embedder.zip index.js From 21374fcbd173867f00cc39cad7451a8c1ed7fc17 Mon Sep 17 00:00:00 2001 From: Tony McCrae Date: Tue, 13 Jan 2026 21:49:31 +0000 Subject: [PATCH 070/494] Remove unused OptimiseOps.isTransformedFilePath function. --- image-loader/app/model/upload/OptimiseOps.scala | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/image-loader/app/model/upload/OptimiseOps.scala b/image-loader/app/model/upload/OptimiseOps.scala index f618b47249e..1b753dd38db 100644 --- a/image-loader/app/model/upload/OptimiseOps.scala +++ b/image-loader/app/model/upload/OptimiseOps.scala @@ -1,20 +1,16 @@ package model.upload -import java.io.File - -import com.gu.mediaservice.lib.{ImageWrapper, StorableImage} -import com.gu.mediaservice.lib.logging.{LogMarker, Stopwatch} +import com.gu.mediaservice.lib.ImageWrapper +import com.gu.mediaservice.lib.logging.{LogMarker, MarkerMap, Stopwatch} import com.gu.mediaservice.model.{FileMetadata, MimeType, Png, Tiff} -import com.gu.mediaservice.lib.logging.MarkerMap +import java.io.File import scala.concurrent.{ExecutionContext, Future} import scala.sys.process._ -import scala.jdk.CollectionConverters._ trait OptimiseOps { def toOptimisedFile(file: File, imageWrapper: ImageWrapper, tempDir: File) (implicit ec: ExecutionContext, logMarker: LogMarker): Future[(File, MimeType)] - def isTransformedFilePath(filePath: String): Boolean def shouldOptimise(mimeType: Option[MimeType], fileMetadata: FileMetadata): Boolean def optimiseMimeType: MimeType } @@ -45,8 +41,6 @@ object OptimiseWithPngQuant extends OptimiseOps { } } - def isTransformedFilePath(filePath: String): Boolean = filePath.contains("transformed-") - def shouldOptimise(mimeType: Option[MimeType], fileMetadata: FileMetadata): Boolean = mimeType match { case Some(Png) => From 6ad41d6a7a8d8147aae3b54ac250304e6ffeb089 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Mon, 12 Jan 2026 16:21:43 +0000 Subject: [PATCH 071/494] remove create embedding function and add sqs function --- .../gu/mediaservice/lib/aws/Embedder.scala | 21 ++++------- .../lib/aws/SimpleSqsMessageConsumer.scala | 11 +++++- image-loader/app/ImageLoaderComponents.scala | 6 +++- image-loader/app/model/Projector.scala | 8 ++--- image-loader/app/model/Uploader.scala | 35 +++++++++++-------- .../test/scala/model/ImageUploadTest.scala | 9 ++--- .../test/scala/model/ProjectorTest.scala | 1 - media-api/app/MediaApiComponents.scala | 4 +-- 8 files changed, 51 insertions(+), 44 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala index 60f04baef80..d0ef692e948 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala @@ -1,4 +1,5 @@ package com.gu.mediaservice.lib.aws +import com.amazonaws.services.sqs.model.SendMessageResult import com.gu.mediaservice.lib.logging.{GridLogging, LogMarker} import com.gu.mediaservice.model.{Jpeg, MimeType, Png, Tiff} import software.amazon.awssdk.services.s3vectors.model.QueryVectorsResponse @@ -11,7 +12,7 @@ sealed trait CohereCompatibleMimeType case object CohereJpeg extends CohereCompatibleMimeType case object CoherePng extends CohereCompatibleMimeType -class Embedder(s3vectors: S3Vectors, bedrock: Bedrock)(implicit ec: ExecutionContext) extends GridLogging { +class Embedder(s3vectors: S3Vectors, bedrock: Bedrock, sqs: SimpleSqsMessageConsumer)(implicit ec: ExecutionContext) extends GridLogging { // https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-embed-v3.html#:~:text=The%20image%20must%20be%20in%20either%20image/jpeg%20or%20image/png%20format%20and%20has%20a%20maximum%20size%20of%205MB private def meetsCohereRequirements(fileType: MimeType, imageFilePath: Path): Either[String, CohereCompatibleMimeType]= { val fileSize = Files.size(imageFilePath) @@ -25,20 +26,6 @@ class Embedder(s3vectors: S3Vectors, bedrock: Bedrock)(implicit ec: ExecutionCon } } - def createEmbeddingAndStore(fileType: MimeType, imageFilePath: Path, imageId: String)(implicit logMarker: LogMarker): Future[Unit] = { - meetsCohereRequirements(fileType, imageFilePath) match { - case Left(error) => { - logger.info(logMarker, s"Skipping image embedding for $imageId as it does not meet the requirements: $error") - Future.successful(()) - } - case Right(imageType) => { - val base64EncodedString: String = Base64.getEncoder().encodeToString(Files.readAllBytes(imageFilePath)) - bedrock.createImageEmbedding(base64EncodedString, imageType) - .flatMap(s3vectors.storeEmbedding(_, imageId)) - } - } - } - def createEmbeddingAndSearch(query: String)(implicit logMarker: LogMarker): Future[QueryVectorsResponse] = { logger.info(logMarker, s"Searching for image embedding for query: $query") val embeddingFuture = bedrock.createEmbedding(InputType.SearchDocument, query) @@ -47,4 +34,8 @@ class Embedder(s3vectors: S3Vectors, bedrock: Bedrock)(implicit ec: ExecutionCon } } + def queueImageToEmbed(messageBody: String)(implicit logMarker: LogMarker) = { + val message: SendMessageResult = sqs.sendMessage(messageBody) + logger.info(logMarker, s"Queued image for embedding with message ID: ${message.getMessageId}") + } } diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/SimpleSqsMessageConsumer.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/SimpleSqsMessageConsumer.scala index 11394a5edb3..aeb9d9bc67f 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/SimpleSqsMessageConsumer.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/SimpleSqsMessageConsumer.scala @@ -3,7 +3,7 @@ package com.gu.mediaservice.lib.aws import com.gu.mediaservice.lib.config.CommonConfig import com.amazonaws.services.sqs.AmazonSQS import com.amazonaws.services.sqs.AmazonSQSClientBuilder -import com.amazonaws.services.sqs.model.{ChangeMessageVisibilityRequest, DeleteMessageRequest, ReceiveMessageRequest, Message => SQSMessage} +import com.amazonaws.services.sqs.model.{ChangeMessageVisibilityRequest, DeleteMessageRequest, ReceiveMessageRequest, SendMessageRequest, SendMessageResult, Message => SQSMessage} import scala.jdk.CollectionConverters._ @@ -32,4 +32,13 @@ class SimpleSqsMessageConsumer (queueUrl: String, config: CommonConfig) { "ApproximateNumberOfMessagesNotVisible" ).asJava).getAttributes.asScala.toMap } + + def sendMessage(messageBody: String): SendMessageResult = { + val sendMessageRequest: SendMessageRequest = new SendMessageRequest() + .withQueueUrl(queueUrl) + .withMessageBody(messageBody) + // TODO what should the delay be here? + .withDelaySeconds(5) + client.sendMessage(sendMessageRequest) + } } diff --git a/image-loader/app/ImageLoaderComponents.scala b/image-loader/app/ImageLoaderComponents.scala index cecd93d18bf..bb97c900cc9 100644 --- a/image-loader/app/ImageLoaderComponents.scala +++ b/image-loader/app/ImageLoaderComponents.scala @@ -28,7 +28,11 @@ class ImageLoaderComponents(context: Context) extends GridComponents(context, ne val notifications = new Notifications(config) val downloader = new Downloader()(ec,wsClient) - val maybeEmbedder: Option[Embedder] = if (config.shouldEmbed) Some(new Embedder(new S3Vectors(config), new Bedrock(config))) else None + val maybeEmbedder: Option[Embedder] = if (config.shouldEmbed) Some(new Embedder( + new S3Vectors(config), + new Bedrock(config), + new SimpleSqsMessageConsumer("https://sqs.eu-west-1.amazonaws.com/563563610310/image-embedder-TEST", config) + )) else None val uploader = new Uploader(store, config, imageOperations, notifications, maybeEmbedder, imageProcessor) val projector = Projector(config, imageOperations, imageProcessor, auth, maybeEmbedder) diff --git a/image-loader/app/model/Projector.scala b/image-loader/app/model/Projector.scala index a229fb510ee..ccec327e291 100644 --- a/image-loader/app/model/Projector.scala +++ b/image-loader/app/model/Projector.scala @@ -176,17 +176,17 @@ class ImageUploadProjectionOps(config: ImageUploadOpsCfg, projectOptimisedPNGFileAsS3Model, tryFetchThumbFile = fetchThumbFile, tryFetchOptimisedFile = fetchOptimisedFile, - createEmbeddingAndStore = createEmbeddingAndStore, + queueImageToEmbed = queueImageToEmbed ) fromUploadRequestShared(uploadRequest, dependenciesWithProjectionsOnly, processor) } - private def createEmbeddingAndStore(fileType: MimeType, imageFilePath: Path, imageId: String)(implicit logMarker: LogMarker): Future[Unit] = { + private def queueImageToEmbed(messageBody: String)(implicit logMarker: LogMarker): Unit = { maybeEmbedder match { case Some(embedder) => - embedder.createEmbeddingAndStore(fileType, imageFilePath, imageId) - case None => Future.successful(None) + embedder.queueImageToEmbed(messageBody) + case None => () } } diff --git a/image-loader/app/model/Uploader.scala b/image-loader/app/model/Uploader.scala index 03c053af9a5..fdc13e31633 100644 --- a/image-loader/app/model/Uploader.scala +++ b/image-loader/app/model/Uploader.scala @@ -77,9 +77,10 @@ case class ImageUploadOpsDependencies( storeOrProjectOptimisedImage: StorableOptimisedImage => Future[S3Object], tryFetchThumbFile: (String, File) => Future[Option[(File, MimeType)]] = (_, _) => Future.successful(None), tryFetchOptimisedFile: (String, File) => Future[Option[(File, MimeType)]] = (_, _) => Future.successful(None), - createEmbeddingAndStore: (MimeType, Path, String) => Future[Unit] + queueImageToEmbed: (String) => Unit ) + case class UploadStatusUri (uri: String) extends AnyVal { def toJsObject = Json.obj("uri" -> uri) } @@ -113,7 +114,7 @@ object Uploader extends GridLogging { storeOrProjectOriginalFile, storeOrProjectThumbFile, storeOrProjectOptimisedImage, - createEmbeddingAndStore, + queueImageToEmbed, OptimiseWithPngQuant, uploadRequest, deps, @@ -125,8 +126,9 @@ object Uploader extends GridLogging { private[model] def uploadAndStoreImage(storeOrProjectOriginalFile: StorableOriginalImage => Future[S3Object], storeOrProjectThumbFile: StorableThumbImage => Future[S3Object], storeOrProjectOptimisedFile: StorableOptimisedImage => Future[S3Object], - createEmbeddingAndStore: (MimeType, Path, String) => Future[Unit], + queueImageToEmbed: (String) => Unit, optimiseOps: OptimiseOps, + uploadRequest: UploadRequest, deps: ImageUploadOpsDependencies, fileMetadata: FileMetadata, @@ -155,12 +157,6 @@ object Uploader extends GridLogging { val sourceStoreFuture = storeOrProjectOriginalFile(storableOriginalImage) val eventualBrowserViewableImage = createBrowserViewableFileFuture(uploadRequest, tempDirForRequest, deps) - // We are fetching the embedding and storing it in the S3Vectors bucket - // This should not block the image upload process on failure - createEmbeddingAndStore(originalMimeType, uploadRequest.tempFile.toPath, uploadRequest.imageId).failed.foreach { failure => - logger.error(logMarker, s"Failed to create and store image embedding for ${uploadRequest.imageId}", failure) - } - val eventualImage = for { browserViewableImage <- eventualBrowserViewableImage s3Source <- sourceStoreFuture @@ -182,6 +178,7 @@ object Uploader extends GridLogging { val fullFileMetadata = fileMetadata.copy(colourModel = colourModel) val metadata = ImageMetadataConverter.fromFileMetadata(fullFileMetadata, s3Source.metadata.objectMetadata.lastModified) + logger.info(logMarker, s"s3Source.uri: ${s3Source.uri}, s3Source.metadata: ${s3Source.metadata}") val sourceAsset = Asset.fromS3Object(s3Source, sourceDimensions, sourceOrientationMetadata) val thumbAsset = Asset.fromS3Object(s3Thumb, thumbDimensions) @@ -197,9 +194,12 @@ object Uploader extends GridLogging { originalUsageRights = processedImage.usageRights ) } - eventualImage.onComplete{ _ => + eventualImage.onComplete { _ => tempDirForRequest.listFiles().map(f => f.delete()) tempDirForRequest.delete() + // Now that the image has been uploaded, we can queue it for embedding + logger.info(logMarker, s"Queueing image ${uploadRequest.imageId} for embedding") + queueImageToEmbed(s"{\"imageId\": \"${uploadRequest.imageId}\", \"fileType\": \"${originalMimeType}\", \"s3Bucket\": \"\", \"s3Key\": \"\"}") } eventualImage } @@ -339,18 +339,25 @@ class Uploader(val store: ImageLoaderStore, def fromUploadRequest(uploadRequest: UploadRequest) (implicit logMarker: LogMarker): Future[ImageUpload] = { val sideEffectDependencies = ImageUploadOpsDependencies(toImageUploadOpsCfg(config), imageOps, - storeSource, storeThumbnail, storeOptimisedImage, createEmbeddingAndStore = createEmbeddingAndStore) + storeSource, storeThumbnail, storeOptimisedImage, queueImageToEmbed = queueImageToEmbed) Stopwatch.async("finalImage") { val finalImage = fromUploadRequestShared(uploadRequest, sideEffectDependencies, imageProcessor) finalImage.map(img => ImageUpload(uploadRequest, img)) } } - private def createEmbeddingAndStore(fileType: MimeType, imageFilePath: Path, imageId: String)(implicit logMarker: LogMarker): Future[Unit] = { +// So here (or somewhere at this point in the pipeline) we'll write to SQS instead +// Arguments needed: +// imageId: string; +// s3Bucket: string; +// s3Key: string; +// fileType: string; + + private def queueImageToEmbed(messageBody: String)(implicit logMarker: LogMarker): Unit = { maybeEmbedder match { case Some(embedder) => - embedder.createEmbeddingAndStore(fileType, imageFilePath, imageId) - case None => Future.successful(()) + embedder.queueImageToEmbed(messageBody) + case None => () } } diff --git a/image-loader/test/scala/model/ImageUploadTest.scala b/image-loader/test/scala/model/ImageUploadTest.scala index 5e5b005c638..e9791ccc8c8 100644 --- a/image-loader/test/scala/model/ImageUploadTest.scala +++ b/image-loader/test/scala/model/ImageUploadTest.scala @@ -58,13 +58,10 @@ class ImageUploadTest extends AsyncFunSuite with Matchers with MockitoSugar { S3Object("madeupname", "madeupkey", a.file, Some(a.mimeType), None, a.meta, None) ) - def mockVectorStore = (fileType: MimeType, imagePath: Path, imageId: String) => - Future.successful(()) - def storeOrProjectOriginalFile: StorableOriginalImage => Future[S3Object] = mockStore def storeOrProjectThumbFile: StorableThumbImage => Future[S3Object] = mockStore def storeOrProjectOptimisedPNG: StorableOptimisedImage => Future[S3Object] = mockStore - def createEmbeddingAndStore: (MimeType, Path, String) => Future[Unit] = mockVectorStore + def queueImageToEmbed: String => Unit = (messageBody: String) => () val mockDependencies = ImageUploadOpsDependencies( mockConfig, @@ -72,7 +69,7 @@ class ImageUploadTest extends AsyncFunSuite with Matchers with MockitoSugar { storeOrProjectOriginalFile, storeOrProjectThumbFile, storeOrProjectOptimisedPNG, - createEmbeddingAndStore = createEmbeddingAndStore + queueImageToEmbed = queueImageToEmbed, ) val tempFile = ResourceHelpers.fileAt(fileName) @@ -92,7 +89,7 @@ class ImageUploadTest extends AsyncFunSuite with Matchers with MockitoSugar { mockDependencies.storeOrProjectOriginalFile, mockDependencies.storeOrProjectThumbFile, mockDependencies.storeOrProjectOptimisedImage, - createEmbeddingAndStore, + queueImageToEmbed, OptimiseWithPngQuant, uploadRequest, mockDependencies, diff --git a/image-loader/test/scala/model/ProjectorTest.scala b/image-loader/test/scala/model/ProjectorTest.scala index b0473127ee7..9a60858e21e 100644 --- a/image-loader/test/scala/model/ProjectorTest.scala +++ b/image-loader/test/scala/model/ProjectorTest.scala @@ -7,7 +7,6 @@ import com.amazonaws.services.s3.AmazonS3 import com.amazonaws.services.s3.model.ObjectMetadata import com.gu.mediaservice.GridClient import com.gu.mediaservice.lib.auth.Authentication -import com.gu.mediaservice.lib.aws.{Embedder, S3Vectors} import com.gu.mediaservice.lib.cleanup.ImageProcessor import com.gu.mediaservice.lib.imaging.ImageOperations import com.gu.mediaservice.lib.logging.{LogMarker, MarkerMap} diff --git a/media-api/app/MediaApiComponents.scala b/media-api/app/MediaApiComponents.scala index 86081ccfbb7..68315edb2c0 100644 --- a/media-api/app/MediaApiComponents.scala +++ b/media-api/app/MediaApiComponents.scala @@ -1,4 +1,4 @@ -import com.gu.mediaservice.lib.aws.{Bedrock, Embedder, S3Vectors, ThrallMessageSender} +import com.gu.mediaservice.lib.aws.{Bedrock, Embedder, S3Vectors, SimpleSqsMessageConsumer, ThrallMessageSender} import com.gu.mediaservice.lib.management.{ElasticSearchHealthCheck, InnerServiceStatusCheckController, Management} import com.gu.mediaservice.lib.metadata.SoftDeletedMetadataTable import com.gu.mediaservice.lib.play.GridComponents @@ -29,7 +29,7 @@ class MediaApiComponents(context: Context) extends GridComponents(context, new M val imageResponse = new ImageResponse(config, s3Client, usageQuota) val softDeletedMetadataTable = new SoftDeletedMetadataTable(config) - val embedder = new Embedder(new S3Vectors(config), new Bedrock(config)) + val embedder = new Embedder(new S3Vectors(config), new Bedrock(config), new SimpleSqsMessageConsumer("https://sqs.eu-west-1.amazonaws.com/563563610310/image-embedder-TEST", config)) val mediaApi = new MediaApi(auth, messageSender, softDeletedMetadataTable, elasticSearch, imageResponse, config, controllerComponents, s3Client, mediaApiMetrics, wsClient, authorisation, embedder) val suggestionController = new SuggestionController(auth, elasticSearch, controllerComponents) From 14249f3c9a98b65a4aaf0abdfce5478f4ee6cc58 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Tue, 13 Jan 2026 16:20:40 +0000 Subject: [PATCH 072/494] pull out bucket and key --- .../image-embedder-lambda.test.ts.snap | 6 +++- cdk/lib/image-embedder-lambda.ts | 30 ++++++++++--------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap index 423b805cbdf..1517880d80c 100644 --- a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap +++ b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap @@ -270,7 +270,11 @@ exports[`The MediaService stack matches the snapshot 1`] = ` { "Action": "s3:GetObject", "Effect": "Allow", - "Resource": "arn:aws:s3:::image-embedding-test/*", + "Resource": [ + "arn:aws:s3:::image-embedding-test/*", + "arn:aws:s3:::media-service-test-imagebucket-1qt2lbcwnpgl0/*", + "arn:aws:s3:::media-service-prod-imagebucket-1luk2yux3owkh/*", + ], }, ], "Version": "2012-10-17", diff --git a/cdk/lib/image-embedder-lambda.ts b/cdk/lib/image-embedder-lambda.ts index 801af3cc1ac..ed80aea9a50 100644 --- a/cdk/lib/image-embedder-lambda.ts +++ b/cdk/lib/image-embedder-lambda.ts @@ -51,32 +51,34 @@ export class ImageEmbedder extends GuStack { // Allow writing vectors to S3 vector index imageEmbedderLambda.role?.addToPrincipalPolicy( new PolicyStatement({ - actions: [ - 's3vectors:PutVectors', - ], - resources: [ - `arn:aws:s3vectors:eu-central-1:${Stack.of(this).account}:bucket/image-embeddings-via-lambda/index/*`, - ], + actions: [ + 's3vectors:PutVectors', + ], + resources: [ + `arn:aws:s3vectors:eu-central-1:${Stack.of(this).account}:bucket/image-embeddings-via-lambda/index/*`, + ], }), ); // Allow invoking the Bedrock Cohere embeddings model imageEmbedderLambda.role?.addToPrincipalPolicy( new PolicyStatement({ - actions: ['bedrock:InvokeModel'], - resources: [ - `arn:aws:bedrock:${Stack.of(this).region}::foundation-model/cohere.embed-english-v3`, - ], + actions: ['bedrock:InvokeModel'], + resources: [ + `arn:aws:bedrock:${Stack.of(this).region}::foundation-model/cohere.embed-english-v3`, + ], }), ); // Allow fetching the image from S3 imageEmbedderLambda.role?.addToPrincipalPolicy( new PolicyStatement({ - actions: ['s3:GetObject'], - resources: [ - `arn:aws:s3:::image-embedding-test/*`, - ], + actions: ['s3:GetObject'], + resources: [ + `arn:aws:s3:::image-embedding-test/*`, + `arn:aws:s3:::media-service-test-imagebucket-1qt2lbcwnpgl0/*`, + `arn:aws:s3:::media-service-prod-imagebucket-1luk2yux3owkh/*` + ], }), ); } From 06dd5ddf5548ceab4666a6fe29ec3b58071c7e50 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Wed, 14 Jan 2026 12:34:02 +0000 Subject: [PATCH 073/494] send message before future completes (this prob won't work) --- image-loader/app/model/Uploader.scala | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/image-loader/app/model/Uploader.scala b/image-loader/app/model/Uploader.scala index fdc13e31633..17ddb441c6d 100644 --- a/image-loader/app/model/Uploader.scala +++ b/image-loader/app/model/Uploader.scala @@ -187,6 +187,15 @@ object Uploader extends GridLogging { val processedImage = processor(baseImage) + val s3Bucket = s3Source.uri.getHost.split('.').head + val s3Key = s3Source.uri.getPath.stripPrefix("/") + + // Queue for embedding now that we have s3Source in scope + logger.info(logMarker, s"Queueing image ${uploadRequest.imageId} for embedding") + queueImageToEmbed( + s"{\"imageId\": \"${uploadRequest.imageId}\", \"fileType\": \"${originalMimeType}\", \"s3Bucket\": \"${s3Bucket}\", \"s3Key\": \"${s3Key}\"}" + ) + logger.info(logMarker, s"Ending image ops") // FIXME: dirty hack to sync the originalUsageRights and originalMetadata as well processedImage.copy( @@ -197,9 +206,7 @@ object Uploader extends GridLogging { eventualImage.onComplete { _ => tempDirForRequest.listFiles().map(f => f.delete()) tempDirForRequest.delete() - // Now that the image has been uploaded, we can queue it for embedding - logger.info(logMarker, s"Queueing image ${uploadRequest.imageId} for embedding") - queueImageToEmbed(s"{\"imageId\": \"${uploadRequest.imageId}\", \"fileType\": \"${originalMimeType}\", \"s3Bucket\": \"\", \"s3Key\": \"\"}") + } eventualImage } From ca7c26a4147b6d2c2c89d1614bf4fe53c0d700b2 Mon Sep 17 00:00:00 2001 From: AndyKilmory Date: Wed, 8 Oct 2025 14:28:35 +0100 Subject: [PATCH 074/494] reverting to es6 syntax --- kahuna/public/js/components/gr-cql-input/syntax.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kahuna/public/js/components/gr-cql-input/syntax.ts b/kahuna/public/js/components/gr-cql-input/syntax.ts index eb34db47c0c..8fa9567a464 100644 --- a/kahuna/public/js/components/gr-cql-input/syntax.ts +++ b/kahuna/public/js/components/gr-cql-input/syntax.ts @@ -83,7 +83,8 @@ const combineConsecutiveTextFields = ( query: StructuredQuery, ): StructuredQuery => query.reduce((previousFields, structuredField) => { - const previousField = previousFields.at(-1); + //const previousField = previousFields.at(-1); + const previousField = previousFields[previousFields.length - 1]; const joinedFieldsContainExclusion = structuredField.filterType === "exclusion" || previousField?.filterType === "exclusion"; const joinedFieldsAreBothText = structuredField.type === "text" && previousField?.type === "text"; if (!joinedFieldsAreBothText || joinedFieldsContainExclusion) { From d608721649dc7126ddd47c1c7f765b79a18ca393 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Wed, 14 Jan 2026 17:20:24 +0000 Subject: [PATCH 075/494] send message to queue on future completion --- image-loader/app/model/Uploader.scala | 33 +++++++++++++++++---------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/image-loader/app/model/Uploader.scala b/image-loader/app/model/Uploader.scala index 17ddb441c6d..4bc11d56e52 100644 --- a/image-loader/app/model/Uploader.scala +++ b/image-loader/app/model/Uploader.scala @@ -187,28 +187,37 @@ object Uploader extends GridLogging { val processedImage = processor(baseImage) - val s3Bucket = s3Source.uri.getHost.split('.').head - val s3Key = s3Source.uri.getPath.stripPrefix("/") - - // Queue for embedding now that we have s3Source in scope - logger.info(logMarker, s"Queueing image ${uploadRequest.imageId} for embedding") - queueImageToEmbed( - s"{\"imageId\": \"${uploadRequest.imageId}\", \"fileType\": \"${originalMimeType}\", \"s3Bucket\": \"${s3Bucket}\", \"s3Key\": \"${s3Key}\"}" - ) - logger.info(logMarker, s"Ending image ops") // FIXME: dirty hack to sync the originalUsageRights and originalMetadata as well - processedImage.copy( + val finalImage = processedImage.copy( originalMetadata = processedImage.metadata, originalUsageRights = processedImage.usageRights ) + + val s3Bucket = s3Source.uri.getHost.split('.').head + val s3Key = s3Source.uri.getPath.stripPrefix("/") + + // Return both the image and the S3 path needed for embedding + (finalImage, s3Bucket, s3Key) } - eventualImage.onComplete { _ => + eventualImage.onComplete{ imageFuture => tempDirForRequest.listFiles().map(f => f.delete()) tempDirForRequest.delete() + imageFuture match { + case scala.util.Success((_, s3Bucket, s3Key)) => + logger.info(logMarker, s"Queueing image ${uploadRequest.imageId} for embedding") + queueImageToEmbed( + s"""{"imageId": "${uploadRequest.imageId}", "fileType": "${originalMimeType}", "s3Bucket": "${s3Bucket}", "s3Key": "${s3Key}"}""" + ) + case scala.util.Failure(exception) => + logger.error( + logMarker, s"Image upload failed, not queueing for embedding: ${exception.getMessage}" + ) + } } - eventualImage + // Map to return just the finalImage + eventualImage.map(_._1) } private def getStorableOptimisedImage( From 1e73382f136841503866d7177223727921c16d38 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Thu, 15 Jan 2026 11:58:16 +0000 Subject: [PATCH 076/494] first stab at setting up localstack (with copilot help) --- dev/cloudformation/grid-dev-core.yml | 212 +- image-embedder-lambda/README.md | 72 +- image-embedder-lambda/local-runner.js | 129 + image-embedder-lambda/package-lock.json | 3037 ++++++----------------- image-embedder-lambda/package.json | 6 +- 5 files changed, 1031 insertions(+), 2425 deletions(-) create mode 100644 image-embedder-lambda/local-runner.js diff --git a/dev/cloudformation/grid-dev-core.yml b/dev/cloudformation/grid-dev-core.yml index 9cc2dc03c3e..d2020ae8967 100644 --- a/dev/cloudformation/grid-dev-core.yml +++ b/dev/cloudformation/grid-dev-core.yml @@ -1,4 +1,4 @@ -AWSTemplateFormatVersion: '2010-09-09' +AWSTemplateFormatVersion: "2010-09-09" Description: Core resources for Grid in DEV Resources: ThrallMessageStream: @@ -15,7 +15,7 @@ Resources: RetentionPeriodHours: 168 IngestSqsQueue: - Type: AWS::SQS::Queue # standard queue will suffice (Fifo not worth performance penalty) + Type: AWS::SQS::Queue # standard queue will suffice (Fifo not worth performance penalty) Properties: QueueName: IngestSqsQueue ReceiveMessageWaitTimeSeconds: 20 # maximum - most efficient for long polling @@ -29,15 +29,15 @@ Resources: CorsRules: - Id: AllowUploadsFromBrowser AllowedHeaders: - - '*' + - "*" AllowedMethods: - PUT AllowedOrigins: - - 'https://media.local.dev-gutools.co.uk' + - "https://media.local.dev-gutools.co.uk" NotificationConfiguration: QueueConfigurations: - - Event: "s3:ObjectCreated:*" - Queue: !GetAtt IngestSqsQueue.Arn + - Event: "s3:ObjectCreated:*" + Queue: !GetAtt IngestSqsQueue.Arn IngestQueueFailBucket: Type: AWS::S3::Bucket @@ -47,13 +47,13 @@ Resources: Properties: CorsConfiguration: CorsRules: - - AllowedMethods: - - GET - AllowedOrigins: - - '*' - ExposedHeaders: - - Date - MaxAge: '3600' + - AllowedMethods: + - GET + AllowedOrigins: + - "*" + ExposedHeaders: + - Date + MaxAge: "3600" ThumbBucket: Type: AWS::S3::Bucket @@ -130,19 +130,19 @@ Resources: Projection: ProjectionType: KEYS_ONLY ProvisionedThroughput: - ReadCapacityUnits: '4' - WriteCapacityUnits: '2' + ReadCapacityUnits: "4" + WriteCapacityUnits: "2" CollectionsDynamoTable: Type: AWS::DynamoDB::Table Properties: TableName: CollectionsTable AttributeDefinitions: - - AttributeName: id - AttributeType: S + - AttributeName: id + AttributeType: S KeySchema: - - AttributeName: id - KeyType: HASH + - AttributeName: id + KeyType: HASH ProvisionedThroughput: ReadCapacityUnits: 1 WriteCapacityUnits: 1 @@ -152,11 +152,11 @@ Resources: Properties: TableName: ImageCollectionsTable AttributeDefinitions: - - AttributeName: id - AttributeType: S + - AttributeName: id + AttributeType: S KeySchema: - - AttributeName: id - KeyType: HASH + - AttributeName: id + KeyType: HASH ProvisionedThroughput: ReadCapacityUnits: 1 WriteCapacityUnits: 1 @@ -166,26 +166,26 @@ Resources: Properties: TableName: LeasesTable AttributeDefinitions: - - AttributeName: id - AttributeType: S - - AttributeName: mediaId - AttributeType: S + - AttributeName: id + AttributeType: S + - AttributeName: mediaId + AttributeType: S KeySchema: - - AttributeName: id - KeyType: HASH + - AttributeName: id + KeyType: HASH ProvisionedThroughput: ReadCapacityUnits: 1 WriteCapacityUnits: 1 GlobalSecondaryIndexes: - - IndexName: mediaId - KeySchema: - - AttributeName: mediaId - KeyType: HASH - Projection: - ProjectionType: ALL - ProvisionedThroughput: - ReadCapacityUnits: 1 - WriteCapacityUnits: 1 + - IndexName: mediaId + KeySchema: + - AttributeName: mediaId + KeyType: HASH + Projection: + ProjectionType: ALL + ProvisionedThroughput: + ReadCapacityUnits: 1 + WriteCapacityUnits: 1 IndexedImageMetadataQueue: Type: AWS::SQS::Queue IndexedImageTopic: @@ -193,34 +193,47 @@ Resources: DependsOn: IndexedImageMetadataQueue Properties: Subscription: - - Endpoint: !GetAtt 'IndexedImageMetadataQueue.Arn' - Protocol: sqs + - Endpoint: !GetAtt "IndexedImageMetadataQueue.Arn" + Protocol: sqs + ImageEmbedderDLQ: + Type: AWS::SQS::Queue + Properties: + QueueName: image-embedder-DLQ-DEV + MessageRetentionPeriod: 1209600 # 14 days + ImageEmbedderQueue: + Type: AWS::SQS::Queue + Properties: + QueueName: image-embedder-DEV + VisibilityTimeout: 60 + RedrivePolicy: + deadLetterTargetArn: !GetAtt ImageEmbedderDLQ.Arn + maxReceiveCount: 3 UsageRecordTable: Type: AWS::DynamoDB::Table Properties: TableName: UsageRecordTable AttributeDefinitions: - - AttributeName: usage_id - AttributeType: S - - AttributeName: grouping - AttributeType: S - - AttributeName: media_id - AttributeType: S - KeySchema: - - AttributeName: grouping - KeyType: HASH - - AttributeName: usage_id - KeyType: RANGE - GlobalSecondaryIndexes: - - IndexName: media_id - KeySchema: + - AttributeName: usage_id + AttributeType: S + - AttributeName: grouping + AttributeType: S - AttributeName: media_id + AttributeType: S + KeySchema: + - AttributeName: grouping KeyType: HASH - Projection: - ProjectionType: ALL - ProvisionedThroughput: - ReadCapacityUnits: 1 - WriteCapacityUnits: 1 + - AttributeName: usage_id + KeyType: RANGE + GlobalSecondaryIndexes: + - IndexName: media_id + KeySchema: + - AttributeName: media_id + KeyType: HASH + Projection: + ProjectionType: ALL + ProvisionedThroughput: + ReadCapacityUnits: 1 + WriteCapacityUnits: 1 ProvisionedThroughput: ReadCapacityUnits: 1 WriteCapacityUnits: 1 @@ -230,26 +243,25 @@ Resources: Properties: TableName: LiveContentPollTable AttributeDefinitions: - - AttributeName: id - AttributeType: S + - AttributeName: id + AttributeType: S KeySchema: - - AttributeName: id - KeyType: HASH + - AttributeName: id + KeyType: HASH ProvisionedThroughput: ReadCapacityUnits: 1 WriteCapacityUnits: 1 - PreviewContentPollTable: Type: AWS::DynamoDB::Table Properties: TableName: PreviewContentPollTable AttributeDefinitions: - - AttributeName: id - AttributeType: S + - AttributeName: id + AttributeType: S KeySchema: - - AttributeName: id - KeyType: HASH + - AttributeName: id + KeyType: HASH ProvisionedThroughput: ReadCapacityUnits: 1 WriteCapacityUnits: 1 @@ -259,11 +271,11 @@ Resources: Properties: TableName: UploadStatusTable AttributeDefinitions: - - AttributeName: id - AttributeType: S + - AttributeName: id + AttributeType: S KeySchema: - - AttributeName: id - KeyType: HASH + - AttributeName: id + KeyType: HASH ProvisionedThroughput: ReadCapacityUnits: 1 WriteCapacityUnits: 1 @@ -287,54 +299,58 @@ Resources: Outputs: ImageBucket: - Value: !Ref 'ImageBucket' + Value: !Ref "ImageBucket" ThumbBucket: - Value: !Ref 'ThumbBucket' + Value: !Ref "ThumbBucket" KeyBucket: - Value: !Ref 'KeyBucket' + Value: !Ref "KeyBucket" ImageOriginBucket: - Value: !Ref 'ImageOriginBucket' + Value: !Ref "ImageOriginBucket" ImageOriginWebsite: - Value: !GetAtt 'ImageOriginBucket.WebsiteURL' + Value: !GetAtt "ImageOriginBucket.WebsiteURL" ConfigBucket: - Value: !Ref 'ConfigBucket' + Value: !Ref "ConfigBucket" CollectionsBucket: - Value: !Ref 'CollectionsBucket' + Value: !Ref "CollectionsBucket" S3WatcherIngestBucket: - Value: !Ref 'S3WatcherIngestBucket' + Value: !Ref "S3WatcherIngestBucket" S3WatcherFailBucket: - Value: !Ref 'S3WatcherFailBucket' + Value: !Ref "S3WatcherFailBucket" UsageMailBucket: - Value: !Ref 'UsageMailBucket' + Value: !Ref "UsageMailBucket" SyndicationDynamoTable: - Value: !Ref 'SyndicationDynamoTable' + Value: !Ref "SyndicationDynamoTable" EditsDynamoTable: - Value: !Ref 'EditsDynamoTable' + Value: !Ref "EditsDynamoTable" CollectionsDynamoTable: - Value: !Ref 'CollectionsDynamoTable' + Value: !Ref "CollectionsDynamoTable" ImageCollectionsDynamoTable: - Value: !Ref 'ImageCollectionsDynamoTable' + Value: !Ref "ImageCollectionsDynamoTable" LeasesDynamoTable: - Value: !Ref 'LeasesDynamoTable' + Value: !Ref "LeasesDynamoTable" IndexedImageTopicArn: - Value: !Ref 'IndexedImageTopic' + Value: !Ref "IndexedImageTopic" IndexedImageMetadataQueueUrl: - Value: !Ref 'IndexedImageMetadataQueue' + Value: !Ref "IndexedImageMetadataQueue" UsageRecordTable: - Value: !Ref 'UsageRecordTable' + Value: !Ref "UsageRecordTable" LiveContentPollTable: - Value: !Ref 'LiveContentPollTable' + Value: !Ref "LiveContentPollTable" PreviewContentPollTable: - Value: !Ref 'PreviewContentPollTable' + Value: !Ref "PreviewContentPollTable" UploadStatusTable: - Value: !Ref 'UploadStatusTable' + Value: !Ref "UploadStatusTable" SoftDeletedMetadataTable: - Value: !Ref 'SoftDeletedMetadataTable' + Value: !Ref "SoftDeletedMetadataTable" IngestSqsQueueUrl: - Value: !Ref 'IngestSqsQueue' + Value: !Ref "IngestSqsQueue" IngestSqsQueueArn: - Value: !GetAtt IngestSqsQueue.Arn + Value: !GetAtt IngestSqsQueue.Arn IngestQueueBucket: - Value: !Ref 'IngestQueueBucket' + Value: !Ref "IngestQueueBucket" IngestQueueFailBucket: - Value: !Ref 'IngestQueueFailBucket' + Value: !Ref "IngestQueueFailBucket" + ImageEmbedderQueueUrl: + Value: !Ref "ImageEmbedderQueue" + ImageEmbedderQueueArn: + Value: !GetAtt ImageEmbedderQueue.Arn diff --git a/image-embedder-lambda/README.md b/image-embedder-lambda/README.md index 0eed015b262..a51eac11e4a 100644 --- a/image-embedder-lambda/README.md +++ b/image-embedder-lambda/README.md @@ -1,3 +1,73 @@ # Embedder Lambda -This is a service responsible for embedding uploaded images to the Grid and writing those embeddings to the S3 Vector Store. \ No newline at end of file +This is a service responsible for embedding uploaded images to the Grid and writing those embeddings to the S3 Vector Store. + +## Running Locally with Localstack + +The ImageEmbedder queue can be run locally by polling the localstack SQS queue and **executing the actual lambda code**. + +### What Actually Runs + +The local runner: + +- ✅ **Polls the real localstack SQS queue** for messages +- ✅ **Executes your actual lambda handler code** (not a mock!) +- ✅ **Fetches images from localstack S3** (when running locally) +- ⚠️ **Calls real AWS Bedrock** for embeddings (requires AWS credentials) +- ⚠️ **Stores vectors in real AWS S3 Vectors** (requires AWS credentials) + +**Important:** Bedrock and S3 Vectors are not available in localstack, so the lambda will connect to **real AWS services**. Make sure you have AWS credentials configured with access to TEST environment resources. + +### Prerequisites + +1. Localstack running via `docker-compose up -d` +2. Core CloudFormation stack deployed to localstack (run `dev/script/setup.sh`) +3. Dependencies installed: `npm install` +4. **AWS credentials configured** for Bedrock and S3 Vectors access + +### Start the Local Runner + +```bash +npm run local +``` + +This will: + +- Build the lambda code +- Start polling the localstack SQS queue (`image-embedder-DEV`) +- **Execute the real lambda handler** when messages arrive +- Delete messages from the queue on success +- Allow failed messages to retry or go to the DLQ + +### Configuration + +Environment variables you can set: + +- `LOCALSTACK_ENDPOINT` - Localstack endpoint (default: `http://localhost:4566`) +- `QUEUE_URL` - Full SQS queue URL (default: `http://localhost:4566/000000000000/image-embedder-DEV`) +- `POLL_INTERVAL_MS` - How often to poll for messages (default: `5000`) +- `AWS_PROFILE` - AWS credentials profile to use for Bedrock/S3 Vectors + +Example: + +```bash +AWS_PROFILE=media-service POLL_INTERVAL_MS=2000 npm run local +``` + +### Testing + +To test the lambda locally, send a message to the queue: + +```bash +aws sqs send-message \ + --queue-url http://localhost:4566/000000000000/image-embedder-DEV \ + --message-body '{"imageId":"test-123","s3Bucket":"media-service-test-imagebucket","s3Key":"test/image.jpg","fileType":"image/jpeg"}' \ + --endpoint-url http://localhost:4566 +``` + +The lambda will: + +1. Receive the message from localstack +2. Try to fetch the image from the S3 bucket specified (localstack if bucket exists there, or real AWS) +3. Send the image to AWS Bedrock for embedding +4. Store the embedding in AWS S3 Vectors diff --git a/image-embedder-lambda/local-runner.js b/image-embedder-lambda/local-runner.js new file mode 100644 index 00000000000..e6a20927f2b --- /dev/null +++ b/image-embedder-lambda/local-runner.js @@ -0,0 +1,129 @@ +#!/usr/bin/env node + +/** + * Local runner for the image-embedder lambda + * Polls the localstack SQS queue and invokes the lambda handler when messages arrive + */ + +const { + SQSClient, + ReceiveMessageCommand, + DeleteMessageCommand, +} = require("@aws-sdk/client-sqs"); +const { handler } = require("./dist/index.js"); + +// Configure for localstack +const LOCALSTACK_ENDPOINT = + process.env.LOCALSTACK_ENDPOINT || "http://localhost:4566"; +const QUEUE_URL = + process.env.QUEUE_URL || + "http://localhost:4566/000000000000/image-embedder-DEV"; +const POLL_INTERVAL_MS = parseInt(process.env.POLL_INTERVAL_MS || "5000", 10); + +const sqsClient = new SQSClient({ + region: "eu-west-1", + endpoint: LOCALSTACK_ENDPOINT, + credentials: { + accessKeyId: "test", + secretAccessKey: "test", + }, +}); + +console.log("Image Embedder Local Runner"); +console.log("============================"); +console.log(`Queue URL: ${QUEUE_URL}`); +console.log(`Localstack Endpoint: ${LOCALSTACK_ENDPOINT}`); +console.log(`Poll Interval: ${POLL_INTERVAL_MS}ms`); +console.log(""); +console.log("Waiting for messages..."); +console.log(""); + +let isProcessing = false; + +async function pollQueue() { + if (isProcessing) { + return; + } + + try { + const command = new ReceiveMessageCommand({ + QueueUrl: QUEUE_URL, + MaxNumberOfMessages: 1, + WaitTimeSeconds: 10, // Long polling + VisibilityTimeout: 60, + }); + + const response = await sqsClient.send(command); + + if (response.Messages && response.Messages.length > 0) { + isProcessing = true; + + for (const message of response.Messages) { + console.log(`[${new Date().toISOString()}] Received message`); + console.log(`Message ID: ${message.MessageId}`); + + try { + // Convert SQS message to Lambda SQS event format + const event = { + Records: [ + { + messageId: message.MessageId, + receiptHandle: message.ReceiptHandle, + body: message.Body, + attributes: message.Attributes || {}, + messageAttributes: message.MessageAttributes || {}, + md5OfBody: message.MD5OfBody, + eventSource: "aws:sqs", + eventSourceARN: `arn:aws:sqs:eu-west-1:000000000000:image-embedder-DEV`, + awsRegion: "eu-west-1", + }, + ], + }; + + // Mock Lambda context + const context = { + functionName: "image-embedder-DEV", + invokedFunctionArn: + "arn:aws:lambda:eu-west-1:000000000000:function:image-embedder-DEV", + awsRequestId: Math.random().toString(36).substring(7), + logGroupName: "/aws/lambda/image-embedder-DEV", + logStreamName: new Date().toISOString(), + }; + + console.log("Invoking lambda handler..."); + await handler(event, context); + console.log("✓ Lambda handler completed successfully"); + + // Delete message from queue on success + await sqsClient.send( + new DeleteMessageCommand({ + QueueUrl: QUEUE_URL, + ReceiptHandle: message.ReceiptHandle, + }) + ); + console.log("✓ Message deleted from queue"); + } catch (error) { + console.error("✗ Lambda handler failed:", error); + console.error("Message will be retried or sent to DLQ"); + } + + console.log(""); + } + + isProcessing = false; + } + } catch (error) { + console.error("Error polling queue:", error); + isProcessing = false; + } +} + +// Start polling +setInterval(pollQueue, POLL_INTERVAL_MS); +pollQueue(); // Start immediately + +// Handle graceful shutdown +process.on("SIGINT", () => { + console.log("\nShutting down..."); + process.exit(0); +}); diff --git a/image-embedder-lambda/package-lock.json b/image-embedder-lambda/package-lock.json index 5ba638ba166..de598502131 100644 --- a/image-embedder-lambda/package-lock.json +++ b/image-embedder-lambda/package-lock.json @@ -11,14 +11,13 @@ "dependencies": { "@aws-sdk/client-bedrock-runtime": "^3.948.0", "@aws-sdk/client-s3": "^3.948.0", - "@aws-sdk/client-s3vectors": "^3.952.0" + "@aws-sdk/client-s3vectors": "^3.952.0", + "@aws-sdk/client-sqs": "^3.948.0" }, "devDependencies": { "@types/aws-lambda": "^8.10.159", "@types/node": "^25.0.0", "esbuild": "0.27.0", - "install": "^0.13.0", - "npm": "^11.7.0", "npm-run-all": "^4.1.5", "typescript": "^5.9.3" } @@ -570,6 +569,514 @@ "node": ">=18.0.0" } }, + "node_modules/@aws-sdk/client-sqs": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sqs/-/client-sqs-3.969.0.tgz", + "integrity": "sha512-PkB9p7K6gz1s88V5XRV8BMeu/xsX3o3NPn8DlbOrA3xqUkGS5QCOo0s4yGRG3/Sn4YJKhwJJBb8vw5DrfsmBCA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.969.0", + "@aws-sdk/credential-provider-node": "3.969.0", + "@aws-sdk/middleware-host-header": "3.969.0", + "@aws-sdk/middleware-logger": "3.969.0", + "@aws-sdk/middleware-recursion-detection": "3.969.0", + "@aws-sdk/middleware-sdk-sqs": "3.969.0", + "@aws-sdk/middleware-user-agent": "3.969.0", + "@aws-sdk/region-config-resolver": "3.969.0", + "@aws-sdk/types": "3.969.0", + "@aws-sdk/util-endpoints": "3.969.0", + "@aws-sdk/util-user-agent-browser": "3.969.0", + "@aws-sdk/util-user-agent-node": "3.969.0", + "@smithy/config-resolver": "^4.4.6", + "@smithy/core": "^3.20.5", + "@smithy/fetch-http-handler": "^5.3.9", + "@smithy/hash-node": "^4.2.8", + "@smithy/invalid-dependency": "^4.2.8", + "@smithy/md5-js": "^4.2.8", + "@smithy/middleware-content-length": "^4.2.8", + "@smithy/middleware-endpoint": "^4.4.6", + "@smithy/middleware-retry": "^4.4.22", + "@smithy/middleware-serde": "^4.2.9", + "@smithy/middleware-stack": "^4.2.8", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/node-http-handler": "^4.4.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/smithy-client": "^4.10.7", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.21", + "@smithy/util-defaults-mode-node": "^4.2.24", + "@smithy/util-endpoints": "^3.2.8", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-retry": "^4.2.8", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/client-sso": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.969.0.tgz", + "integrity": "sha512-Qn0Uz6o15q2S+1E6OpwRKmaAMoT4LktEn+Oibk28qb2Mne+emaDawhZXahOJb/wFw5lN2FEH7XoiSNenNNUmCw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.969.0", + "@aws-sdk/middleware-host-header": "3.969.0", + "@aws-sdk/middleware-logger": "3.969.0", + "@aws-sdk/middleware-recursion-detection": "3.969.0", + "@aws-sdk/middleware-user-agent": "3.969.0", + "@aws-sdk/region-config-resolver": "3.969.0", + "@aws-sdk/types": "3.969.0", + "@aws-sdk/util-endpoints": "3.969.0", + "@aws-sdk/util-user-agent-browser": "3.969.0", + "@aws-sdk/util-user-agent-node": "3.969.0", + "@smithy/config-resolver": "^4.4.6", + "@smithy/core": "^3.20.5", + "@smithy/fetch-http-handler": "^5.3.9", + "@smithy/hash-node": "^4.2.8", + "@smithy/invalid-dependency": "^4.2.8", + "@smithy/middleware-content-length": "^4.2.8", + "@smithy/middleware-endpoint": "^4.4.6", + "@smithy/middleware-retry": "^4.4.22", + "@smithy/middleware-serde": "^4.2.9", + "@smithy/middleware-stack": "^4.2.8", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/node-http-handler": "^4.4.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/smithy-client": "^4.10.7", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.21", + "@smithy/util-defaults-mode-node": "^4.2.24", + "@smithy/util-endpoints": "^3.2.8", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-retry": "^4.2.8", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/core": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.969.0.tgz", + "integrity": "sha512-qqmQt4z5rEK1OYVkVkboWgy/58CC5QaQ7oy0tvLe3iri/mfZbgJkA+pkwQyRP827DfCBZ3W7Ki9iwSa+B2U7uQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.969.0", + "@aws-sdk/xml-builder": "3.969.0", + "@smithy/core": "^3.20.5", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/signature-v4": "^5.3.8", + "@smithy/smithy-client": "^4.10.7", + "@smithy/types": "^4.12.0", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/credential-provider-env": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.969.0.tgz", + "integrity": "sha512-yS96heH5XDUqS3qQNcdObKKMOqZaivuNInMVRpRli48aXW8fX1M3fY67K/Onlqa3Wxu6WfDc3ZGF52SywdLvbg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.969.0", + "@aws-sdk/types": "3.969.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/credential-provider-http": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.969.0.tgz", + "integrity": "sha512-QCEFxBiUYFUW5VG6k8jKhT4luZndpC7uUY4u1olwt+OnJrl3N2yC7oS34isVBa3ioXZ4A0YagbXTa/3mXUhlAA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.969.0", + "@aws-sdk/types": "3.969.0", + "@smithy/fetch-http-handler": "^5.3.9", + "@smithy/node-http-handler": "^4.4.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/smithy-client": "^4.10.7", + "@smithy/types": "^4.12.0", + "@smithy/util-stream": "^4.5.10", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/credential-provider-ini": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.969.0.tgz", + "integrity": "sha512-lsXyTDkUrZPxjr0XruZrqdcHY9zHcIuoY3TOCQEm23VTc8Np2BenTtjGAIexkL3ar69K4u3FVLQroLpmFxeXqA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.969.0", + "@aws-sdk/credential-provider-env": "3.969.0", + "@aws-sdk/credential-provider-http": "3.969.0", + "@aws-sdk/credential-provider-login": "3.969.0", + "@aws-sdk/credential-provider-process": "3.969.0", + "@aws-sdk/credential-provider-sso": "3.969.0", + "@aws-sdk/credential-provider-web-identity": "3.969.0", + "@aws-sdk/nested-clients": "3.969.0", + "@aws-sdk/types": "3.969.0", + "@smithy/credential-provider-imds": "^4.2.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/credential-provider-login": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.969.0.tgz", + "integrity": "sha512-bIRFDf54qIUFFLTZNYt40d6EseNeK9w80dHEs7BVEAWoS23c9+MSqkdg/LJBBK9Kgy01vRmjiedfBZN+jGypLw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.969.0", + "@aws-sdk/nested-clients": "3.969.0", + "@aws-sdk/types": "3.969.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/credential-provider-node": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.969.0.tgz", + "integrity": "sha512-lImMjcy/5SGDIBk7PFJCqFO4rFuapKCvo1z2PidD3Cbz2D7wsJnyqUNQIp5Ix0Xc3/uAYG9zXI9kgaMf1dspIQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/credential-provider-env": "3.969.0", + "@aws-sdk/credential-provider-http": "3.969.0", + "@aws-sdk/credential-provider-ini": "3.969.0", + "@aws-sdk/credential-provider-process": "3.969.0", + "@aws-sdk/credential-provider-sso": "3.969.0", + "@aws-sdk/credential-provider-web-identity": "3.969.0", + "@aws-sdk/types": "3.969.0", + "@smithy/credential-provider-imds": "^4.2.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/credential-provider-process": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.969.0.tgz", + "integrity": "sha512-2qQkM0rwd8Hl9nIHtUaqT8Z/djrulovqx/wBHsbRKaISwc2fiT3De1Lk1jx34Jzrz/dTHAMJJi+cML1N4Lk3kw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.969.0", + "@aws-sdk/types": "3.969.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/credential-provider-sso": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.969.0.tgz", + "integrity": "sha512-JHqXw9Ct3dtZB86/zGFJYWyodr961GyIrqTBhV0brrZFPvcinM9abDSK58jt6GNBM2lqfMCvXL6I4ahNsMdkrg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/client-sso": "3.969.0", + "@aws-sdk/core": "3.969.0", + "@aws-sdk/token-providers": "3.969.0", + "@aws-sdk/types": "3.969.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/credential-provider-web-identity": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.969.0.tgz", + "integrity": "sha512-mKCZtqrs3ts3YmIjT4NFlYgT2Oe6syW0nX5m2l7iyrFrLXw26Zo3rx29DjGzycPdJHZZvsIy5y6yqChDuF65ng==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.969.0", + "@aws-sdk/nested-clients": "3.969.0", + "@aws-sdk/types": "3.969.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/middleware-host-header": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.969.0.tgz", + "integrity": "sha512-AWa4rVsAfBR4xqm7pybQ8sUNJYnjyP/bJjfAw34qPuh3M9XrfGbAHG0aiAfQGrBnmS28jlO6Kz69o+c6PRw1dw==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.969.0", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/middleware-logger": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.969.0.tgz", + "integrity": "sha512-xwrxfip7Y2iTtCMJ+iifN1E1XMOuhxIHY9DreMCvgdl4r7+48x2S1bCYPWH3eNY85/7CapBWdJ8cerpEl12sQQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.969.0", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/middleware-recursion-detection": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.969.0.tgz", + "integrity": "sha512-2r3PuNquU3CcS1Am4vn/KHFwLi8QFjMdA/R+CRDXT4AFO/0qxevF/YStW3gAKntQIgWgQV8ZdEtKAoJvLI4UWg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.969.0", + "@aws/lambda-invoke-store": "^0.2.2", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/middleware-user-agent": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.969.0.tgz", + "integrity": "sha512-Y6WkW8QQ2X9jG9HNBWyzp5KlJOCtLqX8VIvGLoGc2wXdZH7dgOy62uFhkfnHbgfiel6fkNYaycjGx/yyxi0JLQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.969.0", + "@aws-sdk/types": "3.969.0", + "@aws-sdk/util-endpoints": "3.969.0", + "@smithy/core": "^3.20.5", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/nested-clients": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.969.0.tgz", + "integrity": "sha512-MJrejgODxVYZjQjSpPLJkVuxnbrue1x1R8+as3anT5V/wk9Qc/Pf5B1IFjM3Ak6uOtzuRYNY4auOvcg4U8twDA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-crypto/sha256-browser": "5.2.0", + "@aws-crypto/sha256-js": "5.2.0", + "@aws-sdk/core": "3.969.0", + "@aws-sdk/middleware-host-header": "3.969.0", + "@aws-sdk/middleware-logger": "3.969.0", + "@aws-sdk/middleware-recursion-detection": "3.969.0", + "@aws-sdk/middleware-user-agent": "3.969.0", + "@aws-sdk/region-config-resolver": "3.969.0", + "@aws-sdk/types": "3.969.0", + "@aws-sdk/util-endpoints": "3.969.0", + "@aws-sdk/util-user-agent-browser": "3.969.0", + "@aws-sdk/util-user-agent-node": "3.969.0", + "@smithy/config-resolver": "^4.4.6", + "@smithy/core": "^3.20.5", + "@smithy/fetch-http-handler": "^5.3.9", + "@smithy/hash-node": "^4.2.8", + "@smithy/invalid-dependency": "^4.2.8", + "@smithy/middleware-content-length": "^4.2.8", + "@smithy/middleware-endpoint": "^4.4.6", + "@smithy/middleware-retry": "^4.4.22", + "@smithy/middleware-serde": "^4.2.9", + "@smithy/middleware-stack": "^4.2.8", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/node-http-handler": "^4.4.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/smithy-client": "^4.10.7", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-base64": "^4.3.0", + "@smithy/util-body-length-browser": "^4.2.0", + "@smithy/util-body-length-node": "^4.2.1", + "@smithy/util-defaults-mode-browser": "^4.3.21", + "@smithy/util-defaults-mode-node": "^4.2.24", + "@smithy/util-endpoints": "^3.2.8", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-retry": "^4.2.8", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/region-config-resolver": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.969.0.tgz", + "integrity": "sha512-scj9OXqKpcjJ4jsFLtqYWz3IaNvNOQTFFvEY8XMJXTv+3qF5I7/x9SJtKzTRJEBF3spjzBUYPtGFbs9sj4fisQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.969.0", + "@smithy/config-resolver": "^4.4.6", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/token-providers": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.969.0.tgz", + "integrity": "sha512-ucs6QczPkvGinbGmhMlPCQnagGJ+xsM6itsSWlJzxo9YsP6jR75cBU8pRdaM7nEbtCDnrUHf8W9g3D2Hd9mgVA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "3.969.0", + "@aws-sdk/nested-clients": "3.969.0", + "@aws-sdk/types": "3.969.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/types": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.969.0.tgz", + "integrity": "sha512-7IIzM5TdiXn+VtgPdVLjmE6uUBUtnga0f4RiSEI1WW10RPuNvZ9U+pL3SwDiRDAdoGrOF9tSLJOFZmfuwYuVYQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/util-endpoints": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.969.0.tgz", + "integrity": "sha512-H2x2UwYiA1pHg40jE+OCSc668W9GXRShTiCWy1UPKtZKREbQ63Mgd7NAj+bEMsZUSCdHywqmSsLqKM9IcqQ3Bg==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.969.0", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-endpoints": "^3.2.8", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/util-user-agent-browser": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.969.0.tgz", + "integrity": "sha512-bpJGjuKmFr0rA6UKUCmN8D19HQFMLXMx5hKBXqBlPFdalMhxJSjcxzX9DbQh0Fn6bJtxCguFmRGOBdQqNOt49g==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.969.0", + "@smithy/types": "^4.12.0", + "bowser": "^2.11.0", + "tslib": "^2.6.2" + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/util-user-agent-node": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.969.0.tgz", + "integrity": "sha512-D11ZuXNXdUMv8XTthMx+LPzkYNQAeQ68FnCTGnFLgLpnR8hVTeZMBBKjQ77wYGzWDk/csHKdCy697gU1On5KjA==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/middleware-user-agent": "3.969.0", + "@aws-sdk/types": "3.969.0", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "aws-crt": ">=1.0.0" + }, + "peerDependenciesMeta": { + "aws-crt": { + "optional": true + } + } + }, + "node_modules/@aws-sdk/client-sqs/node_modules/@aws-sdk/xml-builder": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.969.0.tgz", + "integrity": "sha512-BSe4Lx/qdRQQdX8cSSI7Et20vqBspzAjBy8ZmXVoyLkol3y4sXBXzn+BiLtR+oh60ExQn6o2DU4QjdOZbXaKIQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.0", + "fast-xml-parser": "5.2.5", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/client-sso": { "version": "3.948.0", "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.948.0.tgz", @@ -972,6 +1479,36 @@ "node": ">=18.0.0" } }, + "node_modules/@aws-sdk/middleware-sdk-sqs": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-sqs/-/middleware-sdk-sqs-3.969.0.tgz", + "integrity": "sha512-H/Q24DbK46EZqej7VSIeuBjWkyko1rWog6V+YofngOLxWRg+oDXx01vJM/c3EKbPlrvZ/gdjwvjr4QUEsGTusQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/types": "3.969.0", + "@smithy/smithy-client": "^4.10.7", + "@smithy/types": "^4.12.0", + "@smithy/util-hex-encoding": "^4.2.0", + "@smithy/util-utf8": "^4.2.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/middleware-sdk-sqs/node_modules/@aws-sdk/types": { + "version": "3.969.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.969.0.tgz", + "integrity": "sha512-7IIzM5TdiXn+VtgPdVLjmE6uUBUtnga0f4RiSEI1WW10RPuNvZ9U+pL3SwDiRDAdoGrOF9tSLJOFZmfuwYuVYQ==", + "license": "Apache-2.0", + "dependencies": { + "@smithy/types": "^4.12.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, "node_modules/@aws-sdk/middleware-ssec": { "version": "3.936.0", "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.936.0.tgz", @@ -1695,12 +2232,12 @@ } }, "node_modules/@smithy/abort-controller": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.5.tgz", - "integrity": "sha512-j7HwVkBw68YW8UmFRcjZOmssE77Rvk0GWAIN1oFBhsaovQmZWYCIcGa9/pwRB0ExI8Sk9MWNALTjftjHZea7VA==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.8.tgz", + "integrity": "sha512-peuVfkYHAmS5ybKxWcfraK7WBBP0J+rkfUcbHJJKQ4ir3UAUNQI+Y4Vt/PqSzGqgloJ5O1dk7+WzNL8wcCSXbw==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.9.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -1733,16 +2270,16 @@ } }, "node_modules/@smithy/config-resolver": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.3.tgz", - "integrity": "sha512-ezHLe1tKLUxDJo2LHtDuEDyWXolw8WGOR92qb4bQdWq/zKenO5BvctZGrVJBK08zjezSk7bmbKFOXIVyChvDLw==", + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.4.6.tgz", + "integrity": "sha512-qJpzYC64kaj3S0fueiu3kXm8xPrR3PcXDPEgnaNMRn0EjNSZFoFjvbUp0YUDsRhN1CB90EnHJtbxWKevnH99UQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.5", - "@smithy/types": "^4.9.0", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/types": "^4.12.0", "@smithy/util-config-provider": "^4.2.0", - "@smithy/util-endpoints": "^3.2.5", - "@smithy/util-middleware": "^4.2.5", + "@smithy/util-endpoints": "^3.2.8", + "@smithy/util-middleware": "^4.2.8", "tslib": "^2.6.2" }, "engines": { @@ -1750,18 +2287,18 @@ } }, "node_modules/@smithy/core": { - "version": "3.18.7", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.18.7.tgz", - "integrity": "sha512-axG9MvKhMWOhFbvf5y2DuyTxQueO0dkedY9QC3mAfndLosRI/9LJv8WaL0mw7ubNhsO4IuXX9/9dYGPFvHrqlw==", + "version": "3.20.5", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.20.5.tgz", + "integrity": "sha512-0Tz77Td8ynHaowXfOdrD0F1IH4tgWGUhwmLwmpFyTbr+U9WHXNNp9u/k2VjBXGnSe7BwjBERRpXsokGTXzNjhA==", "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-serde": "^4.2.6", - "@smithy/protocol-http": "^5.3.5", - "@smithy/types": "^4.9.0", + "@smithy/middleware-serde": "^4.2.9", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", - "@smithy/util-middleware": "^4.2.5", - "@smithy/util-stream": "^4.5.6", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-stream": "^4.5.10", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" @@ -1771,15 +2308,15 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.5.tgz", - "integrity": "sha512-BZwotjoZWn9+36nimwm/OLIcVe+KYRwzMjfhd4QT7QxPm9WY0HiOV8t/Wlh+HVUif0SBVV7ksq8//hPaBC/okQ==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.2.8.tgz", + "integrity": "sha512-FNT0xHS1c/CPN8upqbMFP83+ul5YgdisfCfkZ86Jh2NSmnqw/AJ6x5pEogVCTVvSm7j9MopRU89bmDelxuDMYw==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.5", - "@smithy/property-provider": "^4.2.5", - "@smithy/types": "^4.9.0", - "@smithy/url-parser": "^4.2.5", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", "tslib": "^2.6.2" }, "engines": { @@ -1857,14 +2394,14 @@ } }, "node_modules/@smithy/fetch-http-handler": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.6.tgz", - "integrity": "sha512-3+RG3EA6BBJ/ofZUeTFJA7mHfSYrZtQIrDP9dI8Lf7X6Jbos2jptuLrAAteDiFVrmbEmLSuRG/bUKzfAXk7dhg==", + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.3.9.tgz", + "integrity": "sha512-I4UhmcTYXBrct03rwzQX1Y/iqQlzVQaPxWjCjula++5EmWq9YGBrx6bbGqluGc1f0XEfhSkiY4jhLgbsJUMKRA==", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.5", - "@smithy/querystring-builder": "^4.2.5", - "@smithy/types": "^4.9.0", + "@smithy/protocol-http": "^5.3.8", + "@smithy/querystring-builder": "^4.2.8", + "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "tslib": "^2.6.2" }, @@ -1888,12 +2425,12 @@ } }, "node_modules/@smithy/hash-node": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.5.tgz", - "integrity": "sha512-DpYX914YOfA3UDT9CN1BM787PcHfWRBB43fFGCYrZFUH0Jv+5t8yYl+Pd5PW4+QzoGEDvn5d5QIO4j2HyYZQSA==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.2.8.tgz", + "integrity": "sha512-7ZIlPbmaDGxVoxErDZnuFG18WekhbA/g2/i97wGj+wUBeS6pcUeAym8u4BXh/75RXWhgIJhyC11hBzig6MljwA==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.9.0", + "@smithy/types": "^4.12.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" @@ -1917,12 +2454,12 @@ } }, "node_modules/@smithy/invalid-dependency": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.5.tgz", - "integrity": "sha512-2L2erASEro1WC5nV+plwIMxrTXpvpfzl4e+Nre6vBVRR2HKeGGcvpJyyL3/PpiSg+cJG2KpTmZmq934Olb6e5A==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.2.8.tgz", + "integrity": "sha512-N9iozRybwAQ2dn9Fot9kI6/w9vos2oTXLhtK7ovGqwZjlOcxu6XhPlpLpC+INsxktqHinn5gS2DXDjDF2kG5sQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.9.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -1942,12 +2479,12 @@ } }, "node_modules/@smithy/md5-js": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.2.5.tgz", - "integrity": "sha512-Bt6jpSTMWfjCtC0s79gZ/WZ1w90grfmopVOWqkI2ovhjpD5Q2XRXuecIPB9689L2+cCySMbaXDhBPU56FKNDNg==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.2.8.tgz", + "integrity": "sha512-oGMaLj4tVZzLi3itBa9TCswgMBr7k9b+qKYowQ6x1rTyTuO1IU2YHdHUa+891OsOH+wCsH7aTPRsTJO3RMQmjQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.9.0", + "@smithy/types": "^4.12.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" }, @@ -1956,13 +2493,13 @@ } }, "node_modules/@smithy/middleware-content-length": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.5.tgz", - "integrity": "sha512-Y/RabVa5vbl5FuHYV2vUCwvh/dqzrEY/K2yWPSqvhFUwIY0atLqO4TienjBXakoy4zrKAMCZwg+YEqmH7jaN7A==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.2.8.tgz", + "integrity": "sha512-RO0jeoaYAB1qBRhfVyq0pMgBoUK34YEJxVxyjOWYZiOKOq2yMZ4MnVXMZCUDenpozHue207+9P5ilTV1zeda0A==", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.5", - "@smithy/types": "^4.9.0", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -1970,18 +2507,18 @@ } }, "node_modules/@smithy/middleware-endpoint": { - "version": "4.3.14", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.3.14.tgz", - "integrity": "sha512-v0q4uTKgBM8dsqGjqsabZQyH85nFaTnFcgpWU1uydKFsdyyMzfvOkNum9G7VK+dOP01vUnoZxIeRiJ6uD0kjIg==", + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.4.6.tgz", + "integrity": "sha512-dpq3bHqbEOBqGBjRVHVFP3eUSPpX0BYtg1D5d5Irgk6orGGAuZfY22rC4sErhg+ZfY/Y0kPqm1XpAmDZg7DeuA==", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.18.7", - "@smithy/middleware-serde": "^4.2.6", - "@smithy/node-config-provider": "^4.3.5", - "@smithy/shared-ini-file-loader": "^4.4.0", - "@smithy/types": "^4.9.0", - "@smithy/url-parser": "^4.2.5", - "@smithy/util-middleware": "^4.2.5", + "@smithy/core": "^3.20.5", + "@smithy/middleware-serde": "^4.2.9", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", + "@smithy/url-parser": "^4.2.8", + "@smithy/util-middleware": "^4.2.8", "tslib": "^2.6.2" }, "engines": { @@ -1989,18 +2526,18 @@ } }, "node_modules/@smithy/middleware-retry": { - "version": "4.4.14", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.14.tgz", - "integrity": "sha512-Z2DG8Ej7FyWG1UA+7HceINtSLzswUgs2np3sZX0YBBxCt+CXG4QUxv88ZDS3+2/1ldW7LqtSY1UO/6VQ1pND8Q==", + "version": "4.4.22", + "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.4.22.tgz", + "integrity": "sha512-vwWDMaObSMjw6WCC/3Ae9G7uul5Sk95jr07CDk1gkIMpaDic0phPS1MpVAZ6+YkF7PAzRlpsDjxPwRlh/S11FQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.5", - "@smithy/protocol-http": "^5.3.5", - "@smithy/service-error-classification": "^4.2.5", - "@smithy/smithy-client": "^4.9.10", - "@smithy/types": "^4.9.0", - "@smithy/util-middleware": "^4.2.5", - "@smithy/util-retry": "^4.2.5", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/service-error-classification": "^4.2.8", + "@smithy/smithy-client": "^4.10.7", + "@smithy/types": "^4.12.0", + "@smithy/util-middleware": "^4.2.8", + "@smithy/util-retry": "^4.2.8", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" }, @@ -2009,13 +2546,13 @@ } }, "node_modules/@smithy/middleware-serde": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.6.tgz", - "integrity": "sha512-VkLoE/z7e2g8pirwisLz8XJWedUSY8my/qrp81VmAdyrhi94T+riBfwP+AOEEFR9rFTSonC/5D2eWNmFabHyGQ==", + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.2.9.tgz", + "integrity": "sha512-eMNiej0u/snzDvlqRGSN3Vl0ESn3838+nKyVfF2FKNXFbi4SERYT6PR392D39iczngbqqGG0Jl1DlCnp7tBbXQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.3.5", - "@smithy/types": "^4.9.0", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2023,12 +2560,12 @@ } }, "node_modules/@smithy/middleware-stack": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.5.tgz", - "integrity": "sha512-bYrutc+neOyWxtZdbB2USbQttZN0mXaOyYLIsaTbJhFsfpXyGWUxJpEuO1rJ8IIJm2qH4+xJT0mxUSsEDTYwdQ==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.2.8.tgz", + "integrity": "sha512-w6LCfOviTYQjBctOKSwy6A8FIkQy7ICvglrZFl6Bw4FmcQ1Z420fUtIhxaUZZshRe0VCq4kvDiPiXrPZAe8oRA==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.9.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2036,14 +2573,14 @@ } }, "node_modules/@smithy/node-config-provider": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.5.tgz", - "integrity": "sha512-UTurh1C4qkVCtqggI36DGbLB2Kv8UlcFdMXDcWMbqVY2uRg0XmT9Pb4Vj6oSQ34eizO1fvR0RnFV4Axw4IrrAg==", + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.3.8.tgz", + "integrity": "sha512-aFP1ai4lrbVlWjfpAfRSL8KFcnJQYfTl5QxLJXY32vghJrDuFyPZ6LtUL+JEGYiFRG1PfPLHLoxj107ulncLIg==", "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.2.5", - "@smithy/shared-ini-file-loader": "^4.4.0", - "@smithy/types": "^4.9.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/shared-ini-file-loader": "^4.4.3", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2051,15 +2588,15 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.5.tgz", - "integrity": "sha512-CMnzM9R2WqlqXQGtIlsHMEZfXKJVTIrqCNoSd/QpAyp+Dw0a1Vps13l6ma1fH8g7zSPNsA59B/kWgeylFuA/lw==", + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.4.8.tgz", + "integrity": "sha512-q9u+MSbJVIJ1QmJ4+1u+cERXkrhuILCBDsJUBAW1MPE6sFonbCNaegFuwW9ll8kh5UdyY3jOkoOGlc7BesoLpg==", "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^4.2.5", - "@smithy/protocol-http": "^5.3.5", - "@smithy/querystring-builder": "^4.2.5", - "@smithy/types": "^4.9.0", + "@smithy/abort-controller": "^4.2.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/querystring-builder": "^4.2.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2067,12 +2604,12 @@ } }, "node_modules/@smithy/property-provider": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.5.tgz", - "integrity": "sha512-8iLN1XSE1rl4MuxvQ+5OSk/Zb5El7NJZ1td6Tn+8dQQHIjp59Lwl6bd0+nzw6SKm2wSSriH2v/I9LPzUic7EOg==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.2.8.tgz", + "integrity": "sha512-EtCTbyIveCKeOXDSWSdze3k612yCPq1YbXsbqX3UHhkOSW8zKsM9NOJG5gTIya0vbY2DIaieG8pKo1rITHYL0w==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.9.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2080,12 +2617,12 @@ } }, "node_modules/@smithy/protocol-http": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.5.tgz", - "integrity": "sha512-RlaL+sA0LNMp03bf7XPbFmT5gN+w3besXSWMkA8rcmxLSVfiEXElQi4O2IWwPfxzcHkxqrwBFMbngB8yx/RvaQ==", + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.3.8.tgz", + "integrity": "sha512-QNINVDhxpZ5QnP3aviNHQFlRogQZDfYlCkQT+7tJnErPQbDhysondEjhikuANxgMsZrkGeiAxXy4jguEGsDrWQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.9.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2093,12 +2630,12 @@ } }, "node_modules/@smithy/querystring-builder": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.5.tgz", - "integrity": "sha512-y98otMI1saoajeik2kLfGyRp11e5U/iJYH/wLCh3aTV/XutbGT9nziKGkgCaMD1ghK7p6htHMm6b6scl9JRUWg==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.2.8.tgz", + "integrity": "sha512-Xr83r31+DrE8CP3MqPgMJl+pQlLLmOfiEUnoyAlGzzJIrEsbKsPy1hqH0qySaQm4oWrCBlUqRt+idEgunKB+iw==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.9.0", + "@smithy/types": "^4.12.0", "@smithy/util-uri-escape": "^4.2.0", "tslib": "^2.6.2" }, @@ -2107,12 +2644,12 @@ } }, "node_modules/@smithy/querystring-parser": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.5.tgz", - "integrity": "sha512-031WCTdPYgiQRYNPXznHXof2YM0GwL6SeaSyTH/P72M1Vz73TvCNH2Nq8Iu2IEPq9QP2yx0/nrw5YmSeAi/AjQ==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.2.8.tgz", + "integrity": "sha512-vUurovluVy50CUlazOiXkPq40KGvGWSdmusa3130MwrR1UNnNgKAlj58wlOe61XSHRpUfIIh6cE0zZ8mzKaDPA==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.9.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2120,24 +2657,24 @@ } }, "node_modules/@smithy/service-error-classification": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.5.tgz", - "integrity": "sha512-8fEvK+WPE3wUAcDvqDQG1Vk3ANLR8Px979te96m84CbKAjBVf25rPYSzb4xU4hlTyho7VhOGnh5i62D/JVF0JQ==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.2.8.tgz", + "integrity": "sha512-mZ5xddodpJhEt3RkCjbmUQuXUOaPNTkbMGR0bcS8FE0bJDLMZlhmpgrvPNCYglVw5rsYTpSnv19womw9WWXKQQ==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.9.0" + "@smithy/types": "^4.12.0" }, "engines": { "node": ">=18.0.0" } }, "node_modules/@smithy/shared-ini-file-loader": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.0.tgz", - "integrity": "sha512-5WmZ5+kJgJDjwXXIzr1vDTG+RhF9wzSODQBfkrQ2VVkYALKGvZX1lgVSxEkgicSAFnFhPj5rudJV0zoinqS0bA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.4.3.tgz", + "integrity": "sha512-DfQjxXQnzC5UbCUPeC3Ie8u+rIWZTvuDPAGU/BxzrOGhRvgUanaP68kDZA+jaT3ZI+djOf+4dERGlm9mWfFDrg==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.9.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2145,16 +2682,16 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "5.3.5", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.5.tgz", - "integrity": "sha512-xSUfMu1FT7ccfSXkoLl/QRQBi2rOvi3tiBZU2Tdy3I6cgvZ6SEi9QNey+lqps/sJRnogIS+lq+B1gxxbra2a/w==", + "version": "5.3.8", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.3.8.tgz", + "integrity": "sha512-6A4vdGj7qKNRF16UIcO8HhHjKW27thsxYci+5r/uVRkdcBEkOEiY8OMPuydLX4QHSrJqGHPJzPRwwVTqbLZJhg==", "license": "Apache-2.0", "dependencies": { "@smithy/is-array-buffer": "^4.2.0", - "@smithy/protocol-http": "^5.3.5", - "@smithy/types": "^4.9.0", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", "@smithy/util-hex-encoding": "^4.2.0", - "@smithy/util-middleware": "^4.2.5", + "@smithy/util-middleware": "^4.2.8", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" @@ -2164,17 +2701,17 @@ } }, "node_modules/@smithy/smithy-client": { - "version": "4.9.10", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.9.10.tgz", - "integrity": "sha512-Jaoz4Jw1QYHc1EFww/E6gVtNjhoDU+gwRKqXP6C3LKYqqH2UQhP8tMP3+t/ePrhaze7fhLE8vS2q6vVxBANFTQ==", + "version": "4.10.7", + "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.10.7.tgz", + "integrity": "sha512-Uznt0I9z3os3Z+8pbXrOSCTXCA6vrjyN7Ub+8l2pRDum44vLv8qw0qGVkJN0/tZBZotaEFHrDPKUoPNueTr5Vg==", "license": "Apache-2.0", "dependencies": { - "@smithy/core": "^3.18.7", - "@smithy/middleware-endpoint": "^4.3.14", - "@smithy/middleware-stack": "^4.2.5", - "@smithy/protocol-http": "^5.3.5", - "@smithy/types": "^4.9.0", - "@smithy/util-stream": "^4.5.6", + "@smithy/core": "^3.20.5", + "@smithy/middleware-endpoint": "^4.4.6", + "@smithy/middleware-stack": "^4.2.8", + "@smithy/protocol-http": "^5.3.8", + "@smithy/types": "^4.12.0", + "@smithy/util-stream": "^4.5.10", "tslib": "^2.6.2" }, "engines": { @@ -2182,9 +2719,9 @@ } }, "node_modules/@smithy/types": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.9.0.tgz", - "integrity": "sha512-MvUbdnXDTwykR8cB1WZvNNwqoWVaTRA0RLlLmf/cIFNMM2cKWz01X4Ly6SMC4Kks30r8tT3Cty0jmeWfiuyHTA==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.12.0.tgz", + "integrity": "sha512-9YcuJVTOBDjg9LWo23Qp0lTQ3D7fQsQtwle0jVfpbUHy9qBwCEgKuVH4FqFB3VYu0nwdHKiEMA+oXz7oV8X1kw==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -2194,13 +2731,13 @@ } }, "node_modules/@smithy/url-parser": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.5.tgz", - "integrity": "sha512-VaxMGsilqFnK1CeBX+LXnSuaMx4sTL/6znSZh2829txWieazdVxr54HmiyTsIbpOTLcf5nYpq9lpzmwRdxj6rQ==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.2.8.tgz", + "integrity": "sha512-NQho9U68TGMEU639YkXnVMV3GEFFULmmaWdlu1E9qzyIePOHsoSnagTGSDv1Zi8DCNN6btxOSdgmy5E/hsZwhA==", "license": "Apache-2.0", "dependencies": { - "@smithy/querystring-parser": "^4.2.5", - "@smithy/types": "^4.9.0", + "@smithy/querystring-parser": "^4.2.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2271,14 +2808,14 @@ } }, "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.3.13", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.13.tgz", - "integrity": "sha512-hlVLdAGrVfyNei+pKIgqDTxfu/ZI2NSyqj4IDxKd5bIsIqwR/dSlkxlPaYxFiIaDVrBy0he8orsFy+Cz119XvA==", + "version": "4.3.21", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.3.21.tgz", + "integrity": "sha512-DtmVJarzqtjghtGjCw/PFJolcJkP7GkZgy+hWTAN3YLXNH+IC82uMoMhFoC3ZtIz5mOgCm5+hOGi1wfhVYgrxw==", "license": "Apache-2.0", "dependencies": { - "@smithy/property-provider": "^4.2.5", - "@smithy/smithy-client": "^4.9.10", - "@smithy/types": "^4.9.0", + "@smithy/property-provider": "^4.2.8", + "@smithy/smithy-client": "^4.10.7", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2286,17 +2823,17 @@ } }, "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.2.16", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.16.tgz", - "integrity": "sha512-F1t22IUiJLHrxW9W1CQ6B9PN+skZ9cqSuzB18Eh06HrJPbjsyZ7ZHecAKw80DQtyGTRcVfeukKaCRYebFwclbg==", + "version": "4.2.24", + "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.2.24.tgz", + "integrity": "sha512-JelBDKPAVswVY666rezBvY6b0nF/v9TXjUbNwDNAyme7qqKYEX687wJv0uze8lBIZVbg30wlWnlYfVSjjpKYFA==", "license": "Apache-2.0", "dependencies": { - "@smithy/config-resolver": "^4.4.3", - "@smithy/credential-provider-imds": "^4.2.5", - "@smithy/node-config-provider": "^4.3.5", - "@smithy/property-provider": "^4.2.5", - "@smithy/smithy-client": "^4.9.10", - "@smithy/types": "^4.9.0", + "@smithy/config-resolver": "^4.4.6", + "@smithy/credential-provider-imds": "^4.2.8", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/property-provider": "^4.2.8", + "@smithy/smithy-client": "^4.10.7", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2304,13 +2841,13 @@ } }, "node_modules/@smithy/util-endpoints": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.5.tgz", - "integrity": "sha512-3O63AAWu2cSNQZp+ayl9I3NapW1p1rR5mlVHcF6hAB1dPZUQFfRPYtplWX/3xrzWthPGj5FqB12taJJCfH6s8A==", + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.2.8.tgz", + "integrity": "sha512-8JaVTn3pBDkhZgHQ8R0epwWt+BqPSLCjdjXXusK1onwJlRuN69fbvSK66aIKKO7SwVFM6x2J2ox5X8pOaWcUEw==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.3.5", - "@smithy/types": "^4.9.0", + "@smithy/node-config-provider": "^4.3.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2330,12 +2867,12 @@ } }, "node_modules/@smithy/util-middleware": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.5.tgz", - "integrity": "sha512-6Y3+rvBF7+PZOc40ybeZMcGln6xJGVeY60E7jy9Mv5iKpMJpHgRE6dKy9ScsVxvfAYuEX4Q9a65DQX90KaQ3bA==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.2.8.tgz", + "integrity": "sha512-PMqfeJxLcNPMDgvPbbLl/2Vpin+luxqTGPpW3NAQVLbRrFRzTa4rNAASYeIGjRV9Ytuhzny39SpyU04EQreF+A==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.9.0", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2343,13 +2880,13 @@ } }, "node_modules/@smithy/util-retry": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.5.tgz", - "integrity": "sha512-GBj3+EZBbN4NAqJ/7pAhsXdfzdlznOh8PydUijy6FpNIMnHPSMO2/rP4HKu+UFeikJxShERk528oy7GT79YiJg==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.2.8.tgz", + "integrity": "sha512-CfJqwvoRY0kTGe5AkQokpURNCT1u/MkRzMTASWMPPo2hNSnKtF1D45dQl3DE2LKLr4m+PW9mCeBMJr5mCAVThg==", "license": "Apache-2.0", "dependencies": { - "@smithy/service-error-classification": "^4.2.5", - "@smithy/types": "^4.9.0", + "@smithy/service-error-classification": "^4.2.8", + "@smithy/types": "^4.12.0", "tslib": "^2.6.2" }, "engines": { @@ -2357,14 +2894,14 @@ } }, "node_modules/@smithy/util-stream": { - "version": "4.5.6", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.6.tgz", - "integrity": "sha512-qWw/UM59TiaFrPevefOZ8CNBKbYEP6wBAIlLqxn3VAIo9rgnTNc4ASbVrqDmhuwI87usnjhdQrxodzAGFFzbRQ==", + "version": "4.5.10", + "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.5.10.tgz", + "integrity": "sha512-jbqemy51UFSZSp2y0ZmRfckmrzuKww95zT9BYMmuJ8v3altGcqjwoV1tzpOwuHaKrwQrCjIzOib499ymr2f98g==", "license": "Apache-2.0", "dependencies": { - "@smithy/fetch-http-handler": "^5.3.6", - "@smithy/node-http-handler": "^4.4.5", - "@smithy/types": "^4.9.0", + "@smithy/fetch-http-handler": "^5.3.9", + "@smithy/node-http-handler": "^4.4.8", + "@smithy/types": "^4.12.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-buffer-from": "^4.2.0", "@smithy/util-hex-encoding": "^4.2.0", @@ -3234,16 +3771,6 @@ "dev": true, "license": "ISC" }, - "node_modules/install": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz", - "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -3714,163 +4241,6 @@ "validate-npm-package-license": "^3.0.1" } }, - "node_modules/npm": { - "version": "11.7.0", - "resolved": "https://registry.npmjs.org/npm/-/npm-11.7.0.tgz", - "integrity": "sha512-wiCZpv/41bIobCoJ31NStIWKfAxxYyD1iYnWCtiyns8s5v3+l8y0HCP/sScuH6B5+GhIfda4HQKiqeGZwJWhFw==", - "bundleDependencies": [ - "@isaacs/string-locale-compare", - "@npmcli/arborist", - "@npmcli/config", - "@npmcli/fs", - "@npmcli/map-workspaces", - "@npmcli/metavuln-calculator", - "@npmcli/package-json", - "@npmcli/promise-spawn", - "@npmcli/redact", - "@npmcli/run-script", - "@sigstore/tuf", - "abbrev", - "archy", - "cacache", - "chalk", - "ci-info", - "cli-columns", - "fastest-levenshtein", - "fs-minipass", - "glob", - "graceful-fs", - "hosted-git-info", - "ini", - "init-package-json", - "is-cidr", - "json-parse-even-better-errors", - "libnpmaccess", - "libnpmdiff", - "libnpmexec", - "libnpmfund", - "libnpmorg", - "libnpmpack", - "libnpmpublish", - "libnpmsearch", - "libnpmteam", - "libnpmversion", - "make-fetch-happen", - "minimatch", - "minipass", - "minipass-pipeline", - "ms", - "node-gyp", - "nopt", - "npm-audit-report", - "npm-install-checks", - "npm-package-arg", - "npm-pick-manifest", - "npm-profile", - "npm-registry-fetch", - "npm-user-validate", - "p-map", - "pacote", - "parse-conflict-json", - "proc-log", - "qrcode-terminal", - "read", - "semver", - "spdx-expression-parse", - "ssri", - "supports-color", - "tar", - "text-table", - "tiny-relative-date", - "treeverse", - "validate-npm-package-name", - "which" - ], - "dev": true, - "license": "Artistic-2.0", - "workspaces": [ - "docs", - "smoke-tests", - "mock-globals", - "mock-registry", - "workspaces/*" - ], - "dependencies": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^9.1.9", - "@npmcli/config": "^10.4.5", - "@npmcli/fs": "^5.0.0", - "@npmcli/map-workspaces": "^5.0.3", - "@npmcli/metavuln-calculator": "^9.0.3", - "@npmcli/package-json": "^7.0.4", - "@npmcli/promise-spawn": "^9.0.1", - "@npmcli/redact": "^4.0.0", - "@npmcli/run-script": "^10.0.3", - "@sigstore/tuf": "^4.0.0", - "abbrev": "^4.0.0", - "archy": "~1.0.0", - "cacache": "^20.0.3", - "chalk": "^5.6.2", - "ci-info": "^4.3.1", - "cli-columns": "^4.0.0", - "fastest-levenshtein": "^1.0.16", - "fs-minipass": "^3.0.3", - "glob": "^13.0.0", - "graceful-fs": "^4.2.11", - "hosted-git-info": "^9.0.2", - "ini": "^6.0.0", - "init-package-json": "^8.2.4", - "is-cidr": "^6.0.1", - "json-parse-even-better-errors": "^5.0.0", - "libnpmaccess": "^10.0.3", - "libnpmdiff": "^8.0.12", - "libnpmexec": "^10.1.11", - "libnpmfund": "^7.0.12", - "libnpmorg": "^8.0.1", - "libnpmpack": "^9.0.12", - "libnpmpublish": "^11.1.3", - "libnpmsearch": "^9.0.1", - "libnpmteam": "^8.0.2", - "libnpmversion": "^8.0.3", - "make-fetch-happen": "^15.0.3", - "minimatch": "^10.1.1", - "minipass": "^7.1.1", - "minipass-pipeline": "^1.2.4", - "ms": "^2.1.2", - "node-gyp": "^12.1.0", - "nopt": "^9.0.0", - "npm-audit-report": "^7.0.0", - "npm-install-checks": "^8.0.0", - "npm-package-arg": "^13.0.2", - "npm-pick-manifest": "^11.0.3", - "npm-profile": "^12.0.1", - "npm-registry-fetch": "^19.1.1", - "npm-user-validate": "^4.0.0", - "p-map": "^7.0.4", - "pacote": "^21.0.4", - "parse-conflict-json": "^5.0.1", - "proc-log": "^6.1.0", - "qrcode-terminal": "^0.12.0", - "read": "^5.0.1", - "semver": "^7.7.3", - "spdx-expression-parse": "^4.0.0", - "ssri": "^13.0.0", - "supports-color": "^10.2.2", - "tar": "^7.5.2", - "text-table": "~0.2.0", - "tiny-relative-date": "^2.0.2", - "treeverse": "^3.0.0", - "validate-npm-package-name": "^7.0.0", - "which": "^6.0.0" - }, - "bin": { - "npm": "bin/npm-cli.js", - "npx": "bin/npx-cli.js" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, "node_modules/npm-run-all": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/npm-run-all/-/npm-run-all-4.1.5.tgz", @@ -3897,1987 +4267,6 @@ "node": ">= 4" } }, - "node_modules/npm/node_modules/@isaacs/balanced-match": { - "version": "4.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/npm/node_modules/@isaacs/brace-expansion": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@isaacs/balanced-match": "^4.0.1" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/npm/node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/npm/node_modules/@isaacs/string-locale-compare": { - "version": "1.1.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/@npmcli/agent": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^11.2.1", - "socks-proxy-agent": "^8.0.3" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "9.1.9", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/fs": "^5.0.0", - "@npmcli/installed-package-contents": "^4.0.0", - "@npmcli/map-workspaces": "^5.0.0", - "@npmcli/metavuln-calculator": "^9.0.2", - "@npmcli/name-from-folder": "^4.0.0", - "@npmcli/node-gyp": "^5.0.0", - "@npmcli/package-json": "^7.0.0", - "@npmcli/query": "^5.0.0", - "@npmcli/redact": "^4.0.0", - "@npmcli/run-script": "^10.0.0", - "bin-links": "^6.0.0", - "cacache": "^20.0.1", - "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^9.0.0", - "json-stringify-nice": "^1.1.4", - "lru-cache": "^11.2.1", - "minimatch": "^10.0.3", - "nopt": "^9.0.0", - "npm-install-checks": "^8.0.0", - "npm-package-arg": "^13.0.0", - "npm-pick-manifest": "^11.0.1", - "npm-registry-fetch": "^19.0.0", - "pacote": "^21.0.2", - "parse-conflict-json": "^5.0.1", - "proc-log": "^6.0.0", - "proggy": "^4.0.0", - "promise-all-reject-late": "^1.0.0", - "promise-call-limit": "^3.0.1", - "semver": "^7.3.7", - "ssri": "^13.0.0", - "treeverse": "^3.0.0", - "walk-up-path": "^4.0.0" - }, - "bin": { - "arborist": "bin/index.js" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@npmcli/config": { - "version": "10.4.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/map-workspaces": "^5.0.0", - "@npmcli/package-json": "^7.0.0", - "ci-info": "^4.0.0", - "ini": "^6.0.0", - "nopt": "^9.0.0", - "proc-log": "^6.0.0", - "semver": "^7.3.5", - "walk-up-path": "^4.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@npmcli/fs": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@npmcli/git": { - "version": "7.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/promise-spawn": "^9.0.0", - "ini": "^6.0.0", - "lru-cache": "^11.2.1", - "npm-pick-manifest": "^11.0.1", - "proc-log": "^6.0.0", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^6.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@npmcli/installed-package-contents": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-bundled": "^5.0.0", - "npm-normalize-package-bin": "^5.0.0" - }, - "bin": { - "installed-package-contents": "bin/index.js" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@npmcli/map-workspaces": { - "version": "5.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/name-from-folder": "^4.0.0", - "@npmcli/package-json": "^7.0.0", - "glob": "^13.0.0", - "minimatch": "^10.0.3" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@npmcli/metavuln-calculator": { - "version": "9.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "cacache": "^20.0.0", - "json-parse-even-better-errors": "^5.0.0", - "pacote": "^21.0.0", - "proc-log": "^6.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@npmcli/name-from-folder": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@npmcli/node-gyp": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@npmcli/package-json": { - "version": "7.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^7.0.0", - "glob": "^13.0.0", - "hosted-git-info": "^9.0.0", - "json-parse-even-better-errors": "^5.0.0", - "proc-log": "^6.0.0", - "semver": "^7.5.3", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@npmcli/promise-spawn": { - "version": "9.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "which": "^6.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@npmcli/query": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "postcss-selector-parser": "^7.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@npmcli/redact": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@npmcli/run-script": { - "version": "10.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/node-gyp": "^5.0.0", - "@npmcli/package-json": "^7.0.0", - "@npmcli/promise-spawn": "^9.0.0", - "node-gyp": "^12.1.0", - "proc-log": "^6.0.0", - "which": "^6.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@sigstore/bundle": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.5.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@sigstore/core": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@sigstore/protobuf-specs": { - "version": "0.5.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@sigstore/sign": { - "version": "4.0.1", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^4.0.0", - "@sigstore/core": "^3.0.0", - "@sigstore/protobuf-specs": "^0.5.0", - "make-fetch-happen": "^15.0.2", - "proc-log": "^5.0.0", - "promise-retry": "^2.0.1" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@sigstore/sign/node_modules/proc-log": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^18.17.0 || >=20.5.0" - } - }, - "node_modules/npm/node_modules/@sigstore/tuf": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.5.0", - "tuf-js": "^4.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@sigstore/verify": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^4.0.0", - "@sigstore/core": "^3.0.0", - "@sigstore/protobuf-specs": "^0.5.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@tufjs/canonical-json": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/@tufjs/models": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.5" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/@tufjs/models/node_modules/minimatch": { - "version": "9.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/abbrev": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/agent-base": { - "version": "7.1.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/ansi-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/aproba": { - "version": "2.1.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/archy": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/balanced-match": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/bin-links": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "cmd-shim": "^8.0.0", - "npm-normalize-package-bin": "^5.0.0", - "proc-log": "^6.0.0", - "read-cmd-shim": "^6.0.0", - "write-file-atomic": "^7.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/binary-extensions": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=18.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/brace-expansion": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/npm/node_modules/cacache": { - "version": "20.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^5.0.0", - "fs-minipass": "^3.0.0", - "glob": "^13.0.0", - "lru-cache": "^11.1.0", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^7.0.2", - "ssri": "^13.0.0", - "unique-filename": "^5.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/chalk": { - "version": "5.6.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/npm/node_modules/chownr": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/npm/node_modules/ci-info": { - "version": "4.3.1", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/cidr-regex": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "ip-regex": "5.0.0" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/npm/node_modules/cli-columns": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/npm/node_modules/cmd-shim": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/common-ancestor-path": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/cssesc": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm/node_modules/debug": { - "version": "4.4.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/npm/node_modules/diff": { - "version": "8.0.2", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/npm/node_modules/emoji-regex": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/encoding": { - "version": "0.1.13", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/npm/node_modules/env-paths": { - "version": "2.2.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/npm/node_modules/err-code": { - "version": "2.0.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/exponential-backoff": { - "version": "3.1.3", - "dev": true, - "inBundle": true, - "license": "Apache-2.0" - }, - "node_modules/npm/node_modules/fastest-levenshtein": { - "version": "1.0.16", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/npm/node_modules/fs-minipass": { - "version": "3.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/glob": { - "version": "13.0.0", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "minimatch": "^10.1.1", - "minipass": "^7.1.2", - "path-scurry": "^2.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/graceful-fs": { - "version": "4.2.11", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/npm/node_modules/hosted-git-info": { - "version": "9.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^11.1.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/http-cache-semantics": { - "version": "4.2.0", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause" - }, - "node_modules/npm/node_modules/http-proxy-agent": { - "version": "7.0.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/https-proxy-agent": { - "version": "7.0.6", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/iconv-lite": { - "version": "0.6.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm/node_modules/ignore-walk": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minimatch": "^10.0.3" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/imurmurhash": { - "version": "0.1.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/npm/node_modules/ini": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/init-package-json": { - "version": "8.2.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/package-json": "^7.0.0", - "npm-package-arg": "^13.0.0", - "promzard": "^3.0.1", - "read": "^5.0.1", - "semver": "^7.7.2", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^7.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/ip-address": { - "version": "10.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "node_modules/npm/node_modules/ip-regex": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/is-cidr": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "cidr-regex": "5.0.1" - }, - "engines": { - "node": ">=20" - } - }, - "node_modules/npm/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/isexe": { - "version": "3.1.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=16" - } - }, - "node_modules/npm/node_modules/json-parse-even-better-errors": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/json-stringify-nice": { - "version": "1.1.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/jsonparse": { - "version": "1.3.1", - "dev": true, - "engines": [ - "node >= 0.2.0" - ], - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/just-diff": { - "version": "6.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/just-diff-apply": { - "version": "5.5.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/libnpmaccess": { - "version": "10.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-package-arg": "^13.0.0", - "npm-registry-fetch": "^19.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/libnpmdiff": { - "version": "8.0.12", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^9.1.9", - "@npmcli/installed-package-contents": "^4.0.0", - "binary-extensions": "^3.0.0", - "diff": "^8.0.2", - "minimatch": "^10.0.3", - "npm-package-arg": "^13.0.0", - "pacote": "^21.0.2", - "tar": "^7.5.1" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/libnpmexec": { - "version": "10.1.11", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^9.1.9", - "@npmcli/package-json": "^7.0.0", - "@npmcli/run-script": "^10.0.0", - "ci-info": "^4.0.0", - "npm-package-arg": "^13.0.0", - "pacote": "^21.0.2", - "proc-log": "^6.0.0", - "promise-retry": "^2.0.1", - "read": "^5.0.1", - "semver": "^7.3.7", - "signal-exit": "^4.1.0", - "walk-up-path": "^4.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/libnpmfund": { - "version": "7.0.12", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^9.1.9" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/libnpmorg": { - "version": "8.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^19.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/libnpmpack": { - "version": "9.0.12", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/arborist": "^9.1.9", - "@npmcli/run-script": "^10.0.0", - "npm-package-arg": "^13.0.0", - "pacote": "^21.0.2" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/libnpmpublish": { - "version": "11.1.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/package-json": "^7.0.0", - "ci-info": "^4.0.0", - "npm-package-arg": "^13.0.0", - "npm-registry-fetch": "^19.0.0", - "proc-log": "^6.0.0", - "semver": "^7.3.7", - "sigstore": "^4.0.0", - "ssri": "^13.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/libnpmsearch": { - "version": "9.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-registry-fetch": "^19.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/libnpmteam": { - "version": "8.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "aproba": "^2.0.0", - "npm-registry-fetch": "^19.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/libnpmversion": { - "version": "8.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^7.0.0", - "@npmcli/run-script": "^10.0.0", - "json-parse-even-better-errors": "^5.0.0", - "proc-log": "^6.0.0", - "semver": "^7.3.7" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/lru-cache": { - "version": "11.2.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/npm/node_modules/make-fetch-happen": { - "version": "15.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/agent": "^4.0.0", - "cacache": "^20.0.1", - "http-cache-semantics": "^4.1.1", - "minipass": "^7.0.2", - "minipass-fetch": "^5.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^1.0.0", - "proc-log": "^6.0.0", - "promise-retry": "^2.0.1", - "ssri": "^13.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/minimatch": { - "version": "10.1.1", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/brace-expansion": "^5.0.0" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/minipass": { - "version": "7.1.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/npm/node_modules/minipass-collect": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/npm/node_modules/minipass-fetch": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^3.0.1" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/npm/node_modules/minipass-flush": { - "version": "1.0.5", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-pipeline": { - "version": "1.2.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-sized": { - "version": "1.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/minizlib": { - "version": "3.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.1.2" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/npm/node_modules/ms": { - "version": "2.1.3", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/mute-stream": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/negotiator": { - "version": "1.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/npm/node_modules/node-gyp": { - "version": "12.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^15.0.0", - "nopt": "^9.0.0", - "proc-log": "^6.0.0", - "semver": "^7.3.5", - "tar": "^7.5.2", - "tinyglobby": "^0.2.12", - "which": "^6.0.0" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/nopt": { - "version": "9.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "abbrev": "^4.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/npm-audit-report": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/npm-bundled": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-normalize-package-bin": "^5.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/npm-install-checks": { - "version": "8.0.0", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "semver": "^7.1.1" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/npm-normalize-package-bin": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/npm-package-arg": { - "version": "13.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "hosted-git-info": "^9.0.0", - "proc-log": "^6.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^7.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/npm-packlist": { - "version": "10.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "ignore-walk": "^8.0.0", - "proc-log": "^6.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/npm-pick-manifest": { - "version": "11.0.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-install-checks": "^8.0.0", - "npm-normalize-package-bin": "^5.0.0", - "npm-package-arg": "^13.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/npm-profile": { - "version": "12.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "npm-registry-fetch": "^19.0.0", - "proc-log": "^6.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/npm-registry-fetch": { - "version": "19.1.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/redact": "^4.0.0", - "jsonparse": "^1.3.1", - "make-fetch-happen": "^15.0.0", - "minipass": "^7.0.2", - "minipass-fetch": "^5.0.0", - "minizlib": "^3.0.1", - "npm-package-arg": "^13.0.0", - "proc-log": "^6.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/npm-user-validate": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/p-map": { - "version": "7.0.4", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm/node_modules/pacote": { - "version": "21.0.4", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^7.0.0", - "@npmcli/installed-package-contents": "^4.0.0", - "@npmcli/package-json": "^7.0.0", - "@npmcli/promise-spawn": "^9.0.0", - "@npmcli/run-script": "^10.0.0", - "cacache": "^20.0.0", - "fs-minipass": "^3.0.0", - "minipass": "^7.0.2", - "npm-package-arg": "^13.0.0", - "npm-packlist": "^10.0.1", - "npm-pick-manifest": "^11.0.1", - "npm-registry-fetch": "^19.0.0", - "proc-log": "^6.0.0", - "promise-retry": "^2.0.1", - "sigstore": "^4.0.0", - "ssri": "^13.0.0", - "tar": "^7.4.3" - }, - "bin": { - "pacote": "bin/index.js" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/parse-conflict-json": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^5.0.0", - "just-diff": "^6.0.0", - "just-diff-apply": "^5.2.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/path-scurry": { - "version": "2.0.0", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^11.0.0", - "minipass": "^7.1.2" - }, - "engines": { - "node": "20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/postcss-selector-parser": { - "version": "7.1.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm/node_modules/proc-log": { - "version": "6.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/proggy": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/promise-all-reject-late": { - "version": "1.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/promise-call-limit": { - "version": "3.0.2", - "dev": true, - "inBundle": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/promise-retry": { - "version": "2.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/promzard": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "read": "^5.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/qrcode-terminal": { - "version": "0.12.0", - "dev": true, - "inBundle": true, - "bin": { - "qrcode-terminal": "bin/qrcode-terminal.js" - } - }, - "node_modules/npm/node_modules/read": { - "version": "5.0.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "mute-stream": "^3.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/read-cmd-shim": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/retry": { - "version": "0.12.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/npm/node_modules/safer-buffer": { - "version": "2.1.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "optional": true - }, - "node_modules/npm/node_modules/semver": { - "version": "7.7.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/npm/node_modules/signal-exit": { - "version": "4.1.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/npm/node_modules/sigstore": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^4.0.0", - "@sigstore/core": "^3.0.0", - "@sigstore/protobuf-specs": "^0.5.0", - "@sigstore/sign": "^4.0.0", - "@sigstore/tuf": "^4.0.0", - "@sigstore/verify": "^3.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/smart-buffer": { - "version": "4.2.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/npm/node_modules/socks": { - "version": "2.8.7", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ip-address": "^10.0.1", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/npm/node_modules/socks-proxy-agent": { - "version": "8.0.5", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "socks": "^2.8.3" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/npm/node_modules/spdx-correct": { - "version": "3.2.0", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/spdx-correct/node_modules/spdx-expression-parse": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/spdx-exceptions": { - "version": "2.5.0", - "dev": true, - "inBundle": true, - "license": "CC-BY-3.0" - }, - "node_modules/npm/node_modules/spdx-expression-parse": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/spdx-license-ids": { - "version": "3.0.22", - "dev": true, - "inBundle": true, - "license": "CC0-1.0" - }, - "node_modules/npm/node_modules/ssri": { - "version": "13.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/string-width": { - "version": "4.2.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/strip-ansi": { - "version": "6.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npm/node_modules/supports-color": { - "version": "10.2.2", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/npm/node_modules/tar": { - "version": "7.5.2", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.1.0", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/npm/node_modules/tar/node_modules/yallist": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "node_modules/npm/node_modules/text-table": { - "version": "0.2.0", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/tiny-relative-date": { - "version": "2.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/tinyglobby": { - "version": "0.2.15", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "fdir": "^6.5.0", - "picomatch": "^4.0.3" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/SuperchupuDev" - } - }, - "node_modules/npm/node_modules/tinyglobby/node_modules/fdir": { - "version": "6.5.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/npm/node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.3", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/npm/node_modules/treeverse": { - "version": "3.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm/node_modules/tuf-js": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@tufjs/models": "4.0.0", - "debug": "^4.4.1", - "make-fetch-happen": "^15.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/unique-filename": { - "version": "5.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^6.0.0" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/unique-slug": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/util-deprecate": { - "version": "1.0.2", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/npm/node_modules/validate-npm-package-license": { - "version": "3.0.4", - "dev": true, - "inBundle": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/npm/node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { - "version": "3.0.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/npm/node_modules/validate-npm-package-name": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/walk-up-path": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/npm/node_modules/which": { - "version": "6.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/write-file-atomic": { - "version": "7.0.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^20.17.0 || >=22.9.0" - } - }, - "node_modules/npm/node_modules/yallist": { - "version": "4.0.0", - "dev": true, - "inBundle": true, - "license": "ISC" - }, "node_modules/object-inspect": { "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", diff --git a/image-embedder-lambda/package.json b/image-embedder-lambda/package.json index a3d913ca9e4..69c1c845c50 100644 --- a/image-embedder-lambda/package.json +++ b/image-embedder-lambda/package.json @@ -7,7 +7,8 @@ "test": "echo \"Error: no test specified\" && exit 1", "type-check": "tsc --noEmit", "bundle": "esbuild src/index.ts --bundle --platform=node --target=node24 --format=cjs --outfile=dist/index.js", - "build": "run-p --print-label type-check bundle" + "build": "run-p --print-label type-check bundle", + "local": "npm run build && node local-runner.js" }, "author": "", "license": "ISC", @@ -21,6 +22,7 @@ "dependencies": { "@aws-sdk/client-bedrock-runtime": "^3.948.0", "@aws-sdk/client-s3": "^3.948.0", - "@aws-sdk/client-s3vectors": "^3.952.0" + "@aws-sdk/client-s3vectors": "^3.952.0", + "@aws-sdk/client-sqs": "^3.948.0" } } From 918085f3952d38add85f9aa0b0dd5820897cefb3 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Thu, 15 Jan 2026 12:45:56 +0000 Subject: [PATCH 077/494] change local-run script to typescript and get credentials from AWS profile --- .../{local-runner.js => local-runner.ts} | 41 ++-- image-embedder-lambda/package-lock.json | 188 ++++++++++++++++++ image-embedder-lambda/package.json | 3 +- 3 files changed, 218 insertions(+), 14 deletions(-) rename image-embedder-lambda/{local-runner.js => local-runner.ts} (75%) diff --git a/image-embedder-lambda/local-runner.js b/image-embedder-lambda/local-runner.ts similarity index 75% rename from image-embedder-lambda/local-runner.js rename to image-embedder-lambda/local-runner.ts index e6a20927f2b..a46937f38ef 100644 --- a/image-embedder-lambda/local-runner.js +++ b/image-embedder-lambda/local-runner.ts @@ -1,16 +1,17 @@ -#!/usr/bin/env node +#!/usr/bin/env ts-node /** * Local runner for the image-embedder lambda * Polls the localstack SQS queue and invokes the lambda handler when messages arrive */ -const { +import { SQSClient, ReceiveMessageCommand, DeleteMessageCommand, -} = require("@aws-sdk/client-sqs"); -const { handler } = require("./dist/index.js"); +} from "@aws-sdk/client-sqs"; +import { Context, SQSEvent } from "aws-lambda"; +import { handler } from "./src/index"; // Configure for localstack const LOCALSTACK_ENDPOINT = @@ -20,6 +21,8 @@ const QUEUE_URL = "http://localhost:4566/000000000000/image-embedder-DEV"; const POLL_INTERVAL_MS = parseInt(process.env.POLL_INTERVAL_MS || "5000", 10); +process.env.AWS_PROFILE = "media-service"; + const sqsClient = new SQSClient({ region: "eu-west-1", endpoint: LOCALSTACK_ENDPOINT, @@ -40,7 +43,7 @@ console.log(""); let isProcessing = false; -async function pollQueue() { +async function pollQueue(): Promise { if (isProcessing) { return; } @@ -64,15 +67,20 @@ async function pollQueue() { try { // Convert SQS message to Lambda SQS event format - const event = { + const event: SQSEvent = { Records: [ { - messageId: message.MessageId, - receiptHandle: message.ReceiptHandle, - body: message.Body, - attributes: message.Attributes || {}, - messageAttributes: message.MessageAttributes || {}, - md5OfBody: message.MD5OfBody, + messageId: message.MessageId!, + receiptHandle: message.ReceiptHandle!, + body: message.Body!, + attributes: { + ApproximateReceiveCount: "1", + SentTimestamp: Date.now().toString(), + SenderId: "local", + ApproximateFirstReceiveTimestamp: Date.now().toString(), + }, + messageAttributes: {}, + md5OfBody: message.MD5OfBody!, eventSource: "aws:sqs", eventSourceARN: `arn:aws:sqs:eu-west-1:000000000000:image-embedder-DEV`, awsRegion: "eu-west-1", @@ -81,13 +89,20 @@ async function pollQueue() { }; // Mock Lambda context - const context = { + const context: Context = { + callbackWaitsForEmptyEventLoop: true, functionName: "image-embedder-DEV", + functionVersion: "$LATEST", invokedFunctionArn: "arn:aws:lambda:eu-west-1:000000000000:function:image-embedder-DEV", + memoryLimitInMB: "512", awsRequestId: Math.random().toString(36).substring(7), logGroupName: "/aws/lambda/image-embedder-DEV", logStreamName: new Date().toISOString(), + getRemainingTimeInMillis: () => 60000, + done: () => {}, + fail: () => {}, + succeed: () => {}, }; console.log("Invoking lambda handler..."); diff --git a/image-embedder-lambda/package-lock.json b/image-embedder-lambda/package-lock.json index de598502131..0ad9d8db06f 100644 --- a/image-embedder-lambda/package-lock.json +++ b/image-embedder-lambda/package-lock.json @@ -19,6 +19,7 @@ "@types/node": "^25.0.0", "esbuild": "0.27.0", "npm-run-all": "^4.1.5", + "ts-node": "^10.9.2", "typescript": "^5.9.3" } }, @@ -1789,6 +1790,19 @@ "node": ">=18.0.0" } }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", + "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.0", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.0.tgz", @@ -2231,6 +2245,34 @@ "node": ">=18" } }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", + "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, "node_modules/@smithy/abort-controller": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.2.8.tgz", @@ -2963,6 +3005,34 @@ "node": ">=18.0.0" } }, + "node_modules/@tsconfig/node10": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.12.tgz", + "integrity": "sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", + "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", + "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", + "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/aws-lambda": { "version": "8.10.159", "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.159.tgz", @@ -2980,6 +3050,32 @@ "undici-types": "~7.16.0" } }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", + "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -2993,6 +3089,13 @@ "node": ">=4" } }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true, + "license": "MIT" + }, "node_modules/array-buffer-byte-length": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz", @@ -3171,6 +3274,13 @@ "dev": true, "license": "MIT" }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true, + "license": "MIT" + }, "node_modules/cross-spawn": { "version": "6.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", @@ -3278,6 +3388,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -4189,6 +4309,13 @@ "node": ">=4" } }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true, + "license": "ISC" + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -4888,6 +5015,50 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/ts-node": { + "version": "10.9.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", + "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -5012,6 +5183,13 @@ "dev": true, "license": "MIT" }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true, + "license": "MIT" + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -5124,6 +5302,16 @@ "funding": { "url": "https://github.com/sponsors/ljharb" } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } } } } diff --git a/image-embedder-lambda/package.json b/image-embedder-lambda/package.json index 69c1c845c50..7ee0a8ec4ae 100644 --- a/image-embedder-lambda/package.json +++ b/image-embedder-lambda/package.json @@ -8,7 +8,7 @@ "type-check": "tsc --noEmit", "bundle": "esbuild src/index.ts --bundle --platform=node --target=node24 --format=cjs --outfile=dist/index.js", "build": "run-p --print-label type-check bundle", - "local": "npm run build && node local-runner.js" + "local": "ts-node local-runner.ts" }, "author": "", "license": "ISC", @@ -17,6 +17,7 @@ "@types/node": "^25.0.0", "esbuild": "0.27.0", "npm-run-all": "^4.1.5", + "ts-node": "^10.9.2", "typescript": "^5.9.3" }, "dependencies": { From 8b3255a1263f61a5c3ca48704393c69c2482fc2c Mon Sep 17 00:00:00 2001 From: Lindsey Dew Date: Thu, 15 Jan 2026 15:17:14 +0000 Subject: [PATCH 078/494] Revert "Revert "Dynamo sdk writes"" --- .../gu/mediaservice/lib/aws/DynamoDB.scala | 87 ++++++++++++++++++- .../app/controllers/EditsController.scala | 19 ++-- metadata-editor/app/lib/Syndication.scala | 8 +- 3 files changed, 98 insertions(+), 16 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala index e2a5b407a77..22bb3c50bf5 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala @@ -5,7 +5,7 @@ import com.amazonaws.AmazonServiceException import com.amazonaws.services.dynamodbv2.document.spec.{DeleteItemSpec, GetItemSpec, PutItemSpec, QuerySpec, UpdateItemSpec} import com.amazonaws.services.dynamodbv2.document.utils.ValueMap import com.amazonaws.services.dynamodbv2.document.{DynamoDB => AwsDynamoDB, _} -import com.amazonaws.services.dynamodbv2.model.{AttributeValue, KeysAndAttributes, ReturnValue} +import com.amazonaws.services.dynamodbv2.model.{AttributeValue, DeleteItemRequest, KeysAndAttributes, ReturnValue} import com.amazonaws.services.dynamodbv2.{AmazonDynamoDBAsync, AmazonDynamoDBAsyncClientBuilder} import com.gu.mediaservice.lib.config.CommonConfig import com.gu.mediaservice.lib.logging.GridLogging @@ -13,8 +13,9 @@ import org.joda.time.DateTime import play.api.libs.json._ import software.amazon.awssdk.enhanced.dynamodb._ import software.amazon.awssdk.enhanced.dynamodb.document.EnhancedDocument -import software.amazon.awssdk.enhanced.dynamodb.model.GetItemEnhancedRequest +import software.amazon.awssdk.enhanced.dynamodb.model import software.amazon.awssdk.services.dynamodb.DynamoDbClient +import software.amazon.awssdk.services.dynamodb.model.{UpdateItemRequest, AttributeValue => AttributeValueV2, ReturnValue => ReturnValueV2} import scala.annotation.tailrec import scala.concurrent.{ExecutionContext, Future} @@ -86,10 +87,18 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti s"REMOVE $key" ) + def removeKeyV2(id: String, key: String)(implicit ex: ExecutionContext) = Future{ + updateV2(id, s"Remove $key") + } def deleteItem(id: String)(implicit ex: ExecutionContext): Future[Unit] = Future { table.deleteItem(new DeleteItemSpec().withPrimaryKey(IdKey, id)) } + def deleteItemV2(id: String)(implicit ex: ExecutionContext): Future[Unit] = Future { + table2.deleteItem( + Key.builder().partitionValue(id).build() + ) + } def booleanGetV2(id: String, key: String) (implicit ex: ExecutionContext): Future[Boolean] = { getV2(id, key).map(_.getBoolean(key).booleanValue()) @@ -103,11 +112,25 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti new ValueMap().withBoolean(":value", value) ) + def booleanSetV2(id: String, key: String, value: Boolean) + (implicit ex: ExecutionContext): Future[JsObject] = Future { + updateV2( + id, + s"SET $key = :value", + AttributeValueV2.fromBool(value) + ) + } + def booleanSetOrRemove(id: String, key: String, value: Boolean) (implicit ex: ExecutionContext): Future[JsObject] = if (value) booleanSet(id, key, value) else removeKey(id, key) + def booleanSetOrRemoveV2(id: String, key: String, value: Boolean) + (implicit ex: ExecutionContext): Future[JsObject] = + if (value) booleanSetV2(id, key, value) + else removeKeyV2(id, key) + def stringSet(id: String, key: String, value: JsValue) (implicit ex: ExecutionContext): Future[JsObject] = update( @@ -116,6 +139,10 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti valueMapWithNullForEmptyString(Map(":value" -> value)) ) + def stringSetV2(id: String, key: String, value: String)(implicit ex: ExecutionContext): Future[JsObject] = Future { + updateV2(id, s"SET $key = :value", AttributeValueV2.fromS(value)) + } + def stringListSet(id: String, keyValues: (String, JsValue)*) (implicit ex: ExecutionContext): Future[JsObject] = { val keyValueMap = keyValues.toMap @@ -149,6 +176,9 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti new ValueMap().withStringSet(":value", value:_*) ) + def setAddV2(id: String, key: String, value: List[String])(implicit ex: ExecutionContext): Future[JsObject] = Future { + updateV2(id, s"ADD $key :value", AttributeValueV2.fromSs(value.asJava)) + } def batchGet(ids: List[String], attributeKey: String) (implicit ex: ExecutionContext, rjs: Reads[T]): Future[Map[String, T]] = { val keyChunkList = ids @@ -200,6 +230,15 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti new ValueMap().withMap(":value", valueMapWithNullForEmptyString(value)) ) + def jsonAddV2(id: String, key: String, value: Map[String, JsValue]) + (implicit ex: ExecutionContext): Future[JsObject] = Future { + updateV2( + id, + s"SET $key = :value", + AttributeValueV2.fromM(value.view.mapValues(DynamoDB.jsonToAttributeValue).toMap.asJava) + ) + } + def setDelete(id: String, key: String, value: String) (implicit ex: ExecutionContext): Future[JsObject] = update( @@ -208,6 +247,12 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti new ValueMap().withStringSet(":value", value) ) + def setDeleteV2(id: String, key: String, value: String) + (implicit ex: ExecutionContext): Future[JsObject] = Future { + updateV2(id, s"DELETE $key :value", AttributeValueV2.fromSs(List(value).asJava)) + + } + def listAdd(id: String, key: String, value: T) (implicit ex: ExecutionContext, tjs: Writes[T], rjs: Reads[T]): Future[List[T]] = { @@ -264,6 +309,30 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti items map (a => a.getString("id")) } + private def updateRequestBuilder(id: String, expression: String) = { + UpdateItemRequest.builder() + .key(Map(IdKey -> AttributeValueV2.fromS(id)).asJava) + .updateExpression(expression) + .returnValues(ReturnValueV2.ALL_NEW) + .tableName(tableName) + } + + def updateV2(id: String, expression: String, attribute: AttributeValueV2) = { + val updateRequest = updateRequestBuilder(id, expression) + .expressionAttributeValues(Map(":value" -> attribute).asJava) + .build() + val updateItemResponse = client2.updateItem(updateRequest) + val jsonString = EnhancedDocument.fromAttributeValueMap(updateItemResponse.attributes()).toJson + Json.parse(jsonString).as[JsObject] + } + + def updateV2(id: String, expression: String) = { + val updateRequest = updateRequestBuilder(id, expression).build() + val updateItemResponse = client2.updateItem(updateRequest) + val jsonString = EnhancedDocument.fromAttributeValueMap(updateItemResponse.attributes()).toJson + Json.parse(jsonString).as[JsObject] + } + def update(id: String, expression: String, valueMap: ValueMap) (implicit ex: ExecutionContext): Future[JsObject] = update(id, expression, Some(valueMap)) @@ -343,6 +412,20 @@ object DynamoDB { } valueMap } + + def jsonToAttributeValue(json: JsValue): AttributeValueV2 = { + json match { + case JsString(v) => AttributeValueV2.fromS(v) + case JsBoolean(b) => AttributeValueV2.fromBool(b) + case JsTrue => AttributeValueV2.fromBool(true) + case JsFalse => AttributeValueV2.fromBool(false) + case JsNumber(n) => AttributeValueV2.fromN(n.toString()) + case JsNull => AttributeValueV2.fromNul(true) + case JsObject(obj) => AttributeValueV2.fromM(obj.view.mapValues(s => jsonToAttributeValue(s)).toMap.asJava) + case JsArray(arr) => AttributeValueV2.fromL(arr.toList.map(jsonToAttributeValue).asJava) + } + } + def caseClassToMap[T](caseClass: T)(implicit tjs: Writes[T]): Map[String, JsValue] = Json.toJson[T](caseClass).as[JsObject].as[Map[String, JsValue]] diff --git a/metadata-editor/app/controllers/EditsController.scala b/metadata-editor/app/controllers/EditsController.scala index bacf11f7ab3..44be486d4c1 100644 --- a/metadata-editor/app/controllers/EditsController.scala +++ b/metadata-editor/app/controllers/EditsController.scala @@ -100,14 +100,14 @@ class EditsController( errors => Future.successful(BadRequest(errors.toString())), archived => - editsStore.booleanSetOrRemove(id, "archived", archived) + editsStore.booleanSetOrRemoveV2(id, "archived", archived) .map(publish(id, UpdateImageUserMetadata)) .map(edits => respond(edits.archived)) ) } def unsetArchived(id: String) = auth.async { - editsStore.removeKey(id, Edits.Archived) + editsStore.removeKeyV2(id, Edits.Archived) .map(publish(id, UpdateImageUserMetadata)) .map(_ => respond(false)) } @@ -127,7 +127,7 @@ class EditsController( Future.successful(BadRequest(errors.toString())), labels => editsStore - .setAdd(id, Edits.Labels, labels) + .setAddV2(id, Edits.Labels, labels) .map(publish(id, UpdateImageUserMetadata)) .map(edits => labelsCollection(id, edits.labels.toSet)) .map { case (uri, l) => respondCollection(l) } recover { @@ -137,7 +137,7 @@ class EditsController( } def removeLabel(id: String, label: String) = auth.async { - editsStore.setDelete(id, Edits.Labels, decodeUriParam(label)) + editsStore.setDeleteV2(id, Edits.Labels, decodeUriParam(label)) .map(publish(id, UpdateImageUserMetadata)) .map(edits => labelsCollection(id, edits.labels.toSet)) .map {case (uri, labels) => respondCollection(labels, uri=Some(uri))} @@ -168,7 +168,7 @@ class EditsController( }) val validatedMetadata = metadata.copy(domainMetadata = validatedDomainMetadata) - editsStore.jsonAdd(id, Edits.Metadata, metadataAsMap(validatedMetadata)) + editsStore.jsonAddV2(id, Edits.Metadata, metadataAsMap(validatedMetadata)) .map(publish(id, UpdateImageUserMetadata)) .map(edits => respond(edits.metadata)) } @@ -191,7 +191,7 @@ class EditsController( imageType = metadata.imageType orElse originalUserMetadata.imageType ) - editsStore.jsonAdd(id, Edits.Metadata, metadataAsMap(mergedMetadata)) + editsStore.jsonAddV2(id, Edits.Metadata, metadataAsMap(mergedMetadata)) .map(publish(id, UpdateImageUserMetadata)) .map(edits => respond(edits.metadata, uri = Some(metadataUri(id)))) } getOrElse { @@ -216,18 +216,17 @@ class EditsController( def setUsageRights(id: String) = auth.async(parse.json) { req => (req.body \ "data").asOpt[UsageRights].map(usageRight => { - editsStore.jsonAdd(id, Edits.UsageRights, DynamoDB.caseClassToMap(usageRight)) + editsStore.jsonAddV2(id, Edits.UsageRights, DynamoDB.caseClassToMap(usageRight)) .map(publish(id, UpdateImageUserMetadata)) .map(_ => respond(usageRight)) }).getOrElse(Future.successful(respondError(BadRequest, "invalid-form-data", "Invalid form data"))) } + //TODO - remove as a second step def deleteUsageRights(id: String) = auth.async { req => - editsStore.removeKey(id, Edits.UsageRights).map(publish(id, UpdateImageUserMetadata)).map(edits => Accepted) + editsStore.removeKeyV2(id, Edits.UsageRights).map(publish(id, UpdateImageUserMetadata)).map(edits => Accepted) } - - private def labelsCollection(id: String, labels: Set[String]): (URI, Seq[EmbeddedEntity[String]]) = (labelsUri(id), labels.map(setUnitEntity(id, Edits.Labels, _)).toSeq) diff --git a/metadata-editor/app/lib/Syndication.scala b/metadata-editor/app/lib/Syndication.scala index 3e1ec4e3e62..d8a6f767fbf 100644 --- a/metadata-editor/app/lib/Syndication.scala +++ b/metadata-editor/app/lib/Syndication.scala @@ -58,8 +58,8 @@ trait Syndication extends Edit with MessageSubjects with GridLogging { (implicit ec: ExecutionContext): Future[Photoshoot] = { publishChangedSyndicationRightsForPhotoshoot[Photoshoot](id, photoshoot = Some(newPhotoshoot)) { () => for { - editsAsJsonResponse <- editsStore.jsonAdd(id, Edits.Photoshoot, DynamoDB.caseClassToMap(newPhotoshoot)) - _ <- editsStore.stringSet(id, Edits.PhotoshootTitle, JsString(newPhotoshoot.title)) // store - don't care about return + editsAsJsonResponse <- editsStore.jsonAddV2(id, Edits.Photoshoot, DynamoDB.caseClassToMap(newPhotoshoot)) + _ <- editsStore.stringSetV2(id, Edits.PhotoshootTitle, newPhotoshoot.title) // store - don't care about return _ = publish(id, UpdateImagePhotoshootMetadata)(editsAsJsonResponse) } yield newPhotoshoot } @@ -68,7 +68,7 @@ trait Syndication extends Edit with MessageSubjects with GridLogging { def deleteSyndicationAndPublish(id: String) (implicit ec: ExecutionContext): Future[Unit] = { publishChangedSyndicationRightsForPhotoshoot[Unit](id, unchangedPhotoshoot = true) { () => - syndicationStore.deleteItem(id) + syndicationStore.deleteItemV2(id) // Always publish, in case there is no photoshoot publish(Map(id -> None), UpdateImageSyndicationMetadata) } @@ -77,7 +77,7 @@ trait Syndication extends Edit with MessageSubjects with GridLogging { def setSyndicationAndPublish(id: String, syndicationRight: SyndicationRights) (implicit ec: ExecutionContext): Future[SyndicationRights] = publishChangedSyndicationRightsForPhotoshoot[SyndicationRights](id, unchangedPhotoshoot = true) { () => - val result = syndicationStore.jsonAdd (id, syndicationRightsFieldName, DynamoDB.caseClassToMap (syndicationRight)).map(_=>syndicationRight) + val result = syndicationStore.jsonAddV2(id, syndicationRightsFieldName, DynamoDB.caseClassToMap (syndicationRight)).map(_=>syndicationRight) // Always publish, in case there is no photoshoot publish(Map(id -> Some(syndicationRight)), UpdateImageSyndicationMetadata) result From ae6716c7ddff45e23b3abbff4195483eb5902760 Mon Sep 17 00:00:00 2001 From: lindseydew Date: Thu, 15 Jan 2026 17:19:14 +0000 Subject: [PATCH 079/494] Set the last modified --- .../gu/mediaservice/lib/aws/DynamoDB.scala | 37 +++++++++++++++---- .../mediaservice/lib/aws/DynamoDBTest.scala | 36 ++++++++++++++++++ 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala index 22bb3c50bf5..9db022c5258 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala @@ -7,6 +7,7 @@ import com.amazonaws.services.dynamodbv2.document.utils.ValueMap import com.amazonaws.services.dynamodbv2.document.{DynamoDB => AwsDynamoDB, _} import com.amazonaws.services.dynamodbv2.model.{AttributeValue, DeleteItemRequest, KeysAndAttributes, ReturnValue} import com.amazonaws.services.dynamodbv2.{AmazonDynamoDBAsync, AmazonDynamoDBAsyncClientBuilder} +import com.gu.mediaservice.lib.aws.DynamoDB.{deleteExpr, setExpr} import com.gu.mediaservice.lib.config.CommonConfig import com.gu.mediaservice.lib.logging.GridLogging import org.joda.time.DateTime @@ -88,7 +89,7 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti ) def removeKeyV2(id: String, key: String)(implicit ex: ExecutionContext) = Future{ - updateV2(id, s"Remove $key") + updateV2(id, DynamoDB.removeExpr(key, lastModifiedKey)) } def deleteItem(id: String)(implicit ex: ExecutionContext): Future[Unit] = Future { table.deleteItem(new DeleteItemSpec().withPrimaryKey(IdKey, id)) @@ -116,7 +117,7 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti (implicit ex: ExecutionContext): Future[JsObject] = Future { updateV2( id, - s"SET $key = :value", + DynamoDB.setExpr(key, lastModifiedKey), AttributeValueV2.fromBool(value) ) } @@ -140,7 +141,7 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti ) def stringSetV2(id: String, key: String, value: String)(implicit ex: ExecutionContext): Future[JsObject] = Future { - updateV2(id, s"SET $key = :value", AttributeValueV2.fromS(value)) + updateV2(id, DynamoDB.setExpr(key, lastModifiedKey), AttributeValueV2.fromS(value)) } def stringListSet(id: String, keyValues: (String, JsValue)*) @@ -177,7 +178,7 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti ) def setAddV2(id: String, key: String, value: List[String])(implicit ex: ExecutionContext): Future[JsObject] = Future { - updateV2(id, s"ADD $key :value", AttributeValueV2.fromSs(value.asJava)) + updateV2(id, DynamoDB.addExpr(key, lastModifiedKey), AttributeValueV2.fromSs(value.asJava)) } def batchGet(ids: List[String], attributeKey: String) (implicit ex: ExecutionContext, rjs: Reads[T]): Future[Map[String, T]] = { @@ -226,7 +227,7 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti (implicit ex: ExecutionContext): Future[JsObject] = update( id, - s"SET $key = :value", + setExpr(key, lastModifiedKey), new ValueMap().withMap(":value", valueMapWithNullForEmptyString(value)) ) @@ -234,7 +235,7 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti (implicit ex: ExecutionContext): Future[JsObject] = Future { updateV2( id, - s"SET $key = :value", + setExpr(key, lastModifiedKey), AttributeValueV2.fromM(value.view.mapValues(DynamoDB.jsonToAttributeValue).toMap.asJava) ) } @@ -249,8 +250,7 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti def setDeleteV2(id: String, key: String, value: String) (implicit ex: ExecutionContext): Future[JsObject] = Future { - updateV2(id, s"DELETE $key :value", AttributeValueV2.fromSs(List(value).asJava)) - + updateV2(id, deleteExpr(key, lastModifiedKey), AttributeValueV2.fromSs(List(value).asJava)) } def listAdd(id: String, key: String, value: T) @@ -456,4 +456,25 @@ object DynamoDB { .withUpdateExpression(newExpression) .withValueMap(valueMap) } + + def setExpr[T](key: String, lastModifiedKey: Option[String]) = { + val baseExpression = s"SET $key = :value" + lastModifiedKey.fold(baseExpression)(lastModified => s"$baseExpression, $lastModified = :$lastModified") + } + + def removeExpr(key: String, lastModifiedKey: Option[String]) = { + generateExpression(s"REMOVE $key", lastModifiedKey) + } + + def addExpr(key: String, lastModifiedKey: Option[String]) = { + generateExpression(s"ADD $key :value", lastModifiedKey) + } + + def deleteExpr(key: String, lastModifiedKey: Option[String]) = { + generateExpression(s"DELETE $key :value", lastModifiedKey) + } + + def generateExpression(baseExpression: String, lastModifiedKey: Option[String]) = { + lastModifiedKey.fold(baseExpression)(lastModified => s"$baseExpression SET $lastModified = :$lastModified") + } } diff --git a/common-lib/src/test/scala/com/gu/mediaservice/lib/aws/DynamoDBTest.scala b/common-lib/src/test/scala/com/gu/mediaservice/lib/aws/DynamoDBTest.scala index 895d9cb4abb..88c1686b9b1 100644 --- a/common-lib/src/test/scala/com/gu/mediaservice/lib/aws/DynamoDBTest.scala +++ b/common-lib/src/test/scala/com/gu/mediaservice/lib/aws/DynamoDBTest.scala @@ -116,6 +116,42 @@ class DynamoDBTest extends AnyFunSpec with Matchers { } } + describe("removeExpr") { + it("should generate the correction expression when the lastModified is set") { + DynamoDB.removeExpr("key", Some("lastModifiedKey")) shouldBe "REMOVE key SET lastModifiedKey = :lastModifiedKey" + } + it("should generate the correction expression when the lastModified is not set") { + DynamoDB.removeExpr("key", None) shouldBe "REMOVE key" + } + } + + describe("setExpr") { + it("should generate the correction expression when the lastModified is set") { + DynamoDB.setExpr("key", Some("lastModifiedKey")) shouldBe "SET key = :value, lastModifiedKey = :lastModifiedKey" + } + it("should generate the correction expression when the lastModified is not set") { + DynamoDB.setExpr("key", None) shouldBe "SET key = :value" + } + } + + describe("addExpr") { + it("should generate the correction expression when the lastModified is set") { + DynamoDB.addExpr("key", Some("lastModifiedKey")) shouldBe "ADD key :value SET lastModifiedKey = :lastModifiedKey" + } + it("should generate the correction expression when the lastModified is not set") { + DynamoDB.addExpr("key", None) shouldBe "ADD key :value" + } + } + + describe("deleteExpr") { + it("should generate the correction expression when the lastModified is set") { + DynamoDB.deleteExpr("key", Some("lastModifiedKey")) shouldBe + "DELETE key :value SET lastModifiedKey = :lastModifiedKey" + } + it("should generate the correction expression when the lastModified is not set") { + DynamoDB.deleteExpr("key", None) shouldBe "DELETE key :value" + } + } } case class SimpleDynamoDBObj(s: String, d: BigDecimal, b: Boolean, a: List[String]) From c24b6ec671812ea5cf6574c1fe9c68206b561679 Mon Sep 17 00:00:00 2001 From: lindseydew Date: Thu, 15 Jan 2026 17:42:52 +0000 Subject: [PATCH 080/494] Update the dynamo expression --- .../main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala index 9db022c5258..1511007fc6d 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala @@ -318,8 +318,10 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti } def updateV2(id: String, expression: String, attribute: AttributeValueV2) = { + val baseValuesMap = Map(":value" -> attribute) + val valuesMap = lastModifiedKey.fold(baseValuesMap)(key => baseValuesMap ++ Map(s":${key}" -> DateTime.now().toString)) val updateRequest = updateRequestBuilder(id, expression) - .expressionAttributeValues(Map(":value" -> attribute).asJava) + .expressionAttributeValues(valuesMap.asJava) .build() val updateItemResponse = client2.updateItem(updateRequest) val jsonString = EnhancedDocument.fromAttributeValueMap(updateItemResponse.attributes()).toJson @@ -459,7 +461,7 @@ object DynamoDB { def setExpr[T](key: String, lastModifiedKey: Option[String]) = { val baseExpression = s"SET $key = :value" - lastModifiedKey.fold(baseExpression)(lastModified => s"$baseExpression, $lastModified = :$lastModified") + lastModifiedKey.fold(baseExpression)(lastModifiedKey => s"$baseExpression, $lastModifiedKey = :$lastModifiedKey") } def removeExpr(key: String, lastModifiedKey: Option[String]) = { @@ -475,6 +477,6 @@ object DynamoDB { } def generateExpression(baseExpression: String, lastModifiedKey: Option[String]) = { - lastModifiedKey.fold(baseExpression)(lastModified => s"$baseExpression SET $lastModified = :$lastModified") + lastModifiedKey.fold(baseExpression)(lastModifiedKey => s"$baseExpression SET $lastModifiedKey = :$lastModifiedKey") } } From 29ca898dfe7719a42449fa57ada93e0bf273c690 Mon Sep 17 00:00:00 2001 From: lindseydew Date: Thu, 15 Jan 2026 17:47:36 +0000 Subject: [PATCH 081/494] Update attribute value --- .../src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala index 1511007fc6d..610ae60d3fe 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala @@ -319,7 +319,7 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti def updateV2(id: String, expression: String, attribute: AttributeValueV2) = { val baseValuesMap = Map(":value" -> attribute) - val valuesMap = lastModifiedKey.fold(baseValuesMap)(key => baseValuesMap ++ Map(s":${key}" -> DateTime.now().toString)) + val valuesMap = lastModifiedKey.fold(baseValuesMap)(key => baseValuesMap ++ Map(s":${key}" -> AttributeValueV2.fromS(DateTime.now().toString))) val updateRequest = updateRequestBuilder(id, expression) .expressionAttributeValues(valuesMap.asJava) .build() From f4f33f4c55050385f05b354120deaab8c29ed748 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Fri, 16 Jan 2026 11:37:17 +0000 Subject: [PATCH 082/494] set queueUrl based on env --- dev/script/generate-config/service-config.js | 1 + image-loader/app/ImageLoaderComponents.scala | 15 ++++++++++----- image-loader/app/lib/ImageLoaderConfig.scala | 2 +- image-loader/app/model/Uploader.scala | 7 ------- 4 files changed, 12 insertions(+), 13 deletions(-) diff --git a/dev/script/generate-config/service-config.js b/dev/script/generate-config/service-config.js index 061a4447a72..955929c155b 100644 --- a/dev/script/generate-config/service-config.js +++ b/dev/script/generate-config/service-config.js @@ -105,6 +105,7 @@ function getImageLoaderConfig(config) { |metrics.request.enabled=false |transcoded.mime.types="image/tiff" |s3.vectors.shouldEmbed=false + |sqs.image.embedder.queue.url="${config.coreStackProps.ImageEmbedderQueue}" |`; } diff --git a/image-loader/app/ImageLoaderComponents.scala b/image-loader/app/ImageLoaderComponents.scala index bb97c900cc9..0fb969b69a8 100644 --- a/image-loader/app/ImageLoaderComponents.scala +++ b/image-loader/app/ImageLoaderComponents.scala @@ -28,11 +28,16 @@ class ImageLoaderComponents(context: Context) extends GridComponents(context, ne val notifications = new Notifications(config) val downloader = new Downloader()(ec,wsClient) - val maybeEmbedder: Option[Embedder] = if (config.shouldEmbed) Some(new Embedder( - new S3Vectors(config), - new Bedrock(config), - new SimpleSqsMessageConsumer("https://sqs.eu-west-1.amazonaws.com/563563610310/image-embedder-TEST", config) - )) else None + val maybeEmbedder: Option[Embedder] = for { + queueUrl <- config.maybeImageEmbedderQueueUrl + if config.shouldEmbed + } yield { + new Embedder( + new S3Vectors(config), + new Bedrock(config), + new SimpleSqsMessageConsumer(queueUrl, config) + ) + } val uploader = new Uploader(store, config, imageOperations, notifications, maybeEmbedder, imageProcessor) val projector = Projector(config, imageOperations, imageProcessor, auth, maybeEmbedder) diff --git a/image-loader/app/lib/ImageLoaderConfig.scala b/image-loader/app/lib/ImageLoaderConfig.scala index b2ca4985981..a69c58bc7b8 100644 --- a/image-loader/app/lib/ImageLoaderConfig.scala +++ b/image-loader/app/lib/ImageLoaderConfig.scala @@ -32,7 +32,7 @@ class ImageLoaderConfig(resources: GridConfigResources) extends CommonConfig(res val uploadStatusExpiry: FiniteDuration = configuration.get[FiniteDuration]("uploadStatus.recordExpiry") val shouldEmbed: Boolean = boolean("s3.vectors.shouldEmbed") - + val maybeImageEmbedderQueueUrl: Option[String] = stringOpt("sqs.image.embedder.queue.url") /** * Load in the chain of image processors from config. This can be a list of * companion objects, class names, both with and without config. diff --git a/image-loader/app/model/Uploader.scala b/image-loader/app/model/Uploader.scala index 4bc11d56e52..82ed4345d0b 100644 --- a/image-loader/app/model/Uploader.scala +++ b/image-loader/app/model/Uploader.scala @@ -362,13 +362,6 @@ class Uploader(val store: ImageLoaderStore, } } -// So here (or somewhere at this point in the pipeline) we'll write to SQS instead -// Arguments needed: -// imageId: string; -// s3Bucket: string; -// s3Key: string; -// fileType: string; - private def queueImageToEmbed(messageBody: String)(implicit logMarker: LogMarker): Unit = { maybeEmbedder match { case Some(embedder) => From 5ba56a2cf425b1464625f902aa3541e3b5e2e4cb Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Fri, 16 Jan 2026 16:34:49 +0000 Subject: [PATCH 083/494] get image from localstack when running handler locally --- .../gu/mediaservice/lib/aws/Embedder.scala | 1 - image-embedder-lambda/local-runner.ts | 26 +- image-embedder-lambda/src/index.ts | 317 ++++++++++-------- 3 files changed, 191 insertions(+), 153 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala index d0ef692e948..d905a17e001 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Embedder.scala @@ -5,7 +5,6 @@ import com.gu.mediaservice.model.{Jpeg, MimeType, Png, Tiff} import software.amazon.awssdk.services.s3vectors.model.QueryVectorsResponse import java.nio.file.{Files, Path} -import java.util.Base64 import scala.concurrent.{ExecutionContext, Future} sealed trait CohereCompatibleMimeType diff --git a/image-embedder-lambda/local-runner.ts b/image-embedder-lambda/local-runner.ts index a46937f38ef..3a1a274bb90 100644 --- a/image-embedder-lambda/local-runner.ts +++ b/image-embedder-lambda/local-runner.ts @@ -1,19 +1,6 @@ #!/usr/bin/env ts-node -/** - * Local runner for the image-embedder lambda - * Polls the localstack SQS queue and invokes the lambda handler when messages arrive - */ - -import { - SQSClient, - ReceiveMessageCommand, - DeleteMessageCommand, -} from "@aws-sdk/client-sqs"; -import { Context, SQSEvent } from "aws-lambda"; -import { handler } from "./src/index"; - -// Configure for localstack +// Configure for localstack - MUST be set before importing handler const LOCALSTACK_ENDPOINT = process.env.LOCALSTACK_ENDPOINT || "http://localhost:4566"; const QUEUE_URL = @@ -22,6 +9,17 @@ const QUEUE_URL = const POLL_INTERVAL_MS = parseInt(process.env.POLL_INTERVAL_MS || "5000", 10); process.env.AWS_PROFILE = "media-service"; +process.env.IS_LOCAL = "true"; +process.env.LOCALSTACK_ENDPOINT = LOCALSTACK_ENDPOINT; + +// Import handler AFTER setting environment variables +import { + SQSClient, + ReceiveMessageCommand, + DeleteMessageCommand, +} from "@aws-sdk/client-sqs"; +import { Context, SQSEvent } from "aws-lambda"; +import { handler } from "./src/index"; const sqsClient = new SQSClient({ region: "eu-west-1", diff --git a/image-embedder-lambda/src/index.ts b/image-embedder-lambda/src/index.ts index 8b0462b1229..ce814e20edc 100644 --- a/image-embedder-lambda/src/index.ts +++ b/image-embedder-lambda/src/index.ts @@ -1,159 +1,200 @@ -import { Context, SQSEvent, SQSRecord } from 'aws-lambda'; -import { BedrockRuntimeClient, InvokeModelCommand, InvokeModelCommandInput, InvokeModelCommandOutput, ServiceInputTypes } from "@aws-sdk/client-bedrock-runtime"; -import { GetObjectCommand, GetObjectCommandOutput, GetObjectRequest, S3Client } from "@aws-sdk/client-s3" -import { PutInputVector, PutVectorsCommand, PutVectorsCommandInput, S3VectorsClient, VectorData } from "@aws-sdk/client-s3vectors" +import { Context, SQSEvent, SQSRecord } from "aws-lambda"; +import { + BedrockRuntimeClient, + InvokeModelCommand, + InvokeModelCommandInput, + InvokeModelCommandOutput, +} from "@aws-sdk/client-bedrock-runtime"; +import { + GetObjectCommand, + GetObjectCommandOutput, + GetObjectRequest, + S3Client, +} from "@aws-sdk/client-s3"; +import { + PutInputVector, + PutVectorsCommand, + PutVectorsCommandInput, + S3VectorsClient, +} from "@aws-sdk/client-s3vectors"; // Initialise clients at module level (cold start only) -const config = { region: "eu-west-1" }; -const s3Client = new S3Client(config); -const bedrockClient = new BedrockRuntimeClient(config); +const LOCALSTACK_ENDPOINT = + process.env.LOCALSTACK_ENDPOINT || "http://localhost:4566"; +const isLocal = process.env.IS_LOCAL === "true"; + +const s3Config = { + region: "eu-west-1", + ...(isLocal && { + endpoint: LOCALSTACK_ENDPOINT, + forcePathStyle: true, + credentials: { + accessKeyId: "test", + secretAccessKey: "test", + }, + }), +}; + +const s3Client = new S3Client(s3Config); +const bedrockClient = new BedrockRuntimeClient({ region: "eu-west-1" }); const s3VectorsClient = new S3VectorsClient({ region: "eu-central-1" }); interface SQSMessageBody { - imageId: string; - s3Bucket: string; - s3Key: string; - fileType: string; + imageId: string; + s3Bucket: string; + s3Key: string; + fileType: string; } async function getImageFromS3( - s3Bucket: string, - s3Key: string, - client: S3Client + s3Bucket: string, + s3Key: string, + client: S3Client ): Promise { - - const input: GetObjectRequest = { - Bucket: s3Bucket, - Key: s3Key, - }; - - console.log(`Fetching image from S3: bucket=${s3Bucket}, key=${s3Key}`); - - try { - const command = new GetObjectCommand(input); - const response: GetObjectCommandOutput = await client.send(command); - - console.log(`S3 response metadata: ${JSON.stringify(response.$metadata)}`); - - if (!response.Body) { - console.log(`Returning undefined: response.Body is falsy`); - return undefined; - } - - if (response.ContentLength === 0) { - console.log(`Warning: ContentLength is 0, file may be empty`); - } - - const bytes = await response.Body.transformToByteArray(); - console.log(`Bytes array length: ${bytes.length}`); - return bytes; - } catch (error) { - console.error(`Error fetching from S3:`, error); - throw error; + const input: GetObjectRequest = { + Bucket: s3Bucket, + Key: s3Key, + }; + + console.log(`Fetching image from S3: bucket=${s3Bucket}, key=${s3Key}`); + try { + const command = new GetObjectCommand(input); + const response: GetObjectCommandOutput = await client.send(command); + + console.log(`S3 response metadata: ${JSON.stringify(response.$metadata)}`); + + if (!response.Body) { + console.log(`Returning undefined: response.Body is falsy`); + return undefined; + } + + if (response.ContentLength === 0) { + console.log(`Warning: ContentLength is 0, file may be empty`); } + + const bytes = await response.Body.transformToByteArray(); + console.log(`Bytes array length: ${bytes.length}`); + return bytes; + } catch (error) { + console.error(`Error fetching from S3:`, error); + throw error; + } } async function embedImage( - inputData: String[], - client: BedrockRuntimeClient + inputData: String[], + client: BedrockRuntimeClient ): Promise { - - const model = "cohere.embed-english-v3"; - const body = { - input_type: "image", - embedding_types: ["float"], - images: inputData - }; - const jsonBody = JSON.stringify(body); - - const input: InvokeModelCommandInput = { - modelId: model, - body: jsonBody, - accept: "*/*", - contentType: "application/json", - } - console.log(`Invoking Bedrock model: ${model}`); - - try { - const command = new InvokeModelCommand(input); - const response = await client.send(command); - - console.log(`Bedrock response metadata: ${JSON.stringify(response.$metadata)}`); - console.log(`Response body length: ${response.body?.length}`); - - return response; - } catch (error) { - console.error(`Bedrock invocation error:`, error); - throw error; - } + const model = "cohere.embed-english-v3"; + const body = { + input_type: "image", + embedding_types: ["float"], + images: inputData, + }; + const jsonBody = JSON.stringify(body); + + const input: InvokeModelCommandInput = { + modelId: model, + body: jsonBody, + accept: "*/*", + contentType: "application/json", + }; + console.log(`Invoking Bedrock model: ${model}`); + + try { + const command = new InvokeModelCommand(input); + const response = await client.send(command); + + console.log( + `Bedrock response metadata: ${JSON.stringify(response.$metadata)}` + ); + console.log(`Response body length: ${response.body?.length}`); + + return response; + } catch (error) { + console.error(`Bedrock invocation error:`, error); + throw error; + } } async function storeEmbedding( - embedding: number[], - key: string, - client: S3VectorsClient + embedding: number[], + key: string, + client: S3VectorsClient ) { - console.log(`Storing embedding of length ${embedding.length} for key: ${key}`); - - const inputVector: PutInputVector = { - key: key, - data: { - float32: embedding - } - }; - - const input: PutVectorsCommandInput = { - vectorBucketName: "image-embeddings-via-lambda", - indexName: "cohere-embed-english-v3", - vectors: [inputVector], - }; - - console.log(`PutVectorsCommand input: vectorBucketName=${input.vectorBucketName}, indexName=${input.indexName}`); - - try { - const command = new PutVectorsCommand(input); - const response = await client.send(command); - - console.log(`S3 Vectors response metadata: ${JSON.stringify(response.$metadata)}`); - console.log(`Successfully stored embedding for key: ${key}`); - - return response; - } catch (error) { - console.error(`Error storing embedding for key: ${key}`, error); - throw error; - } + console.log( + `Storing embedding of length ${embedding.length} for key: ${key}` + ); + + const inputVector: PutInputVector = { + key: key, + data: { + float32: embedding, + }, + }; + + const input: PutVectorsCommandInput = { + vectorBucketName: "image-embeddings-via-lambda", + indexName: "cohere-embed-english-v3", + vectors: [inputVector], + }; + + console.log( + `PutVectorsCommand input: vectorBucketName=${input.vectorBucketName}, indexName=${input.indexName}` + ); + + try { + const command = new PutVectorsCommand(input); + const response = await client.send(command); + + console.log( + `S3 Vectors response metadata: ${JSON.stringify(response.$metadata)}` + ); + console.log(`Successfully stored embedding for key: ${key}`); + + return response; + } catch (error) { + console.error(`Error storing embedding for key: ${key}`, error); + throw error; + } } export const handler = async (event: SQSEvent, context: Context) => { - - console.log(`Starting handler embedding pipeline`); - const records: SQSRecord[] = event.Records; - const recordBody: SQSMessageBody = JSON.parse(records[0].body); - - // If it's a Tiff then we should throw an error - // So that it ends on the DLQ for processing when we add tiff handling - if (recordBody.fileType === "image/tiff") { - console.error(`Unsupported file type: ${recordBody.fileType}, ending execution`); - throw new Error(`Unsupported file type: ${recordBody.fileType}`); - } - - const gridImage = await getImageFromS3(recordBody.s3Bucket, recordBody.s3Key, s3Client); - const base64Image = Buffer.from(gridImage).toString('base64'); - const inputImage = `data:${recordBody.fileType};base64,${base64Image}` - - // TODO: downscale image if necessary - // Currently the image will end up on the DLQ if it's too big - // because the embedding will fail - - const embeddingResponse = await embedImage([inputImage], bedrockClient); - const responseBody = JSON.parse(new TextDecoder().decode(embeddingResponse.body)); - // Extract the embedding array (first element since we only sent one image) - const embedding: number[] = responseBody.embeddings.float[0]; - - console.log(`First 5 values: ${embedding.slice(0, 5)}`); - - await storeEmbedding(embedding, recordBody.imageId, s3VectorsClient); - - console.log(`Finished image image pipeline successfully!`) - -}; \ No newline at end of file + console.log(`Starting handler embedding pipeline`); + const records: SQSRecord[] = event.Records; + const recordBody: SQSMessageBody = JSON.parse(records[0].body); + + // If it's a Tiff then we should throw an error + // So that it ends on the DLQ for processing when we add tiff handling + if (recordBody.fileType === "image/tiff") { + console.error( + `Unsupported file type: ${recordBody.fileType}, ending execution` + ); + throw new Error(`Unsupported file type: ${recordBody.fileType}`); + } + + const gridImage = await getImageFromS3( + recordBody.s3Bucket, + recordBody.s3Key, + s3Client + ); + const base64Image = Buffer.from(gridImage).toString("base64"); + const inputImage = `data:${recordBody.fileType};base64,${base64Image}`; + + // TODO: downscale image if necessary + // Currently the image will end up on the DLQ if it's too big + // because the embedding will fail + + const embeddingResponse = await embedImage([inputImage], bedrockClient); + const responseBody = JSON.parse( + new TextDecoder().decode(embeddingResponse.body) + ); + // Extract the embedding array (first element since we only sent one image) + const embedding: number[] = responseBody.embeddings.float[0]; + + console.log(`First 5 values: ${embedding.slice(0, 5)}`); + + await storeEmbedding(embedding, recordBody.imageId, s3VectorsClient); + + console.log(`Finished image image pipeline successfully!`); +}; From d161dfae167eb78ac91654d3791f11dc3e4873a3 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Fri, 16 Jan 2026 16:59:57 +0000 Subject: [PATCH 084/494] write to s3 vector bucket for the right environment --- cdk/lib/image-embedder-lambda.ts | 3 +++ image-embedder-lambda/src/index.ts | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/cdk/lib/image-embedder-lambda.ts b/cdk/lib/image-embedder-lambda.ts index ed80aea9a50..1f8b14476f8 100644 --- a/cdk/lib/image-embedder-lambda.ts +++ b/cdk/lib/image-embedder-lambda.ts @@ -24,6 +24,9 @@ export class ImageEmbedder extends GuStack { architecture: Architecture.ARM_64, handler: 'index.handler', app: 'image-embedder-lambda', + environment: { + STAGE: props.stage, + }, }, ); diff --git a/image-embedder-lambda/src/index.ts b/image-embedder-lambda/src/index.ts index ce814e20edc..9796f529ff9 100644 --- a/image-embedder-lambda/src/index.ts +++ b/image-embedder-lambda/src/index.ts @@ -23,6 +23,9 @@ const LOCALSTACK_ENDPOINT = process.env.LOCALSTACK_ENDPOINT || "http://localhost:4566"; const isLocal = process.env.IS_LOCAL === "true"; +// Determine stage: dev for local, otherwise from environment (test or prod) +const STAGE = isLocal ? "dev" : process.env.STAGE; + const s3Config = { region: "eu-west-1", ...(isLocal && { @@ -35,6 +38,9 @@ const s3Config = { }), }; +console.log(`Stage: ${STAGE}`); +console.log(`IS_LOCAL: ${isLocal}`); + const s3Client = new S3Client(s3Config); const bedrockClient = new BedrockRuntimeClient({ region: "eu-west-1" }); const s3VectorsClient = new S3VectorsClient({ region: "eu-central-1" }); @@ -134,7 +140,7 @@ async function storeEmbedding( }; const input: PutVectorsCommandInput = { - vectorBucketName: "image-embeddings-via-lambda", + vectorBucketName: `image-embeddings-${STAGE}`, indexName: "cohere-embed-english-v3", vectors: [inputVector], }; From 38b3b8d759da73b275de0f270e8135c70544b3f9 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Fri, 16 Jan 2026 17:15:34 +0000 Subject: [PATCH 085/494] give lambda permissions to write to s3 vector bucket --- .../image-embedder-lambda.test.ts.snap | 3 +- cdk/lib/image-embedder-lambda.ts | 103 ++++++++---------- 2 files changed, 49 insertions(+), 57 deletions(-) diff --git a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap index 1517880d80c..69786f86fe1 100644 --- a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap +++ b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap @@ -246,7 +246,7 @@ exports[`The MediaService stack matches the snapshot 1`] = ` { "Ref": "AWS::AccountId", }, - ":bucket/image-embeddings-via-lambda/index/*", + ":bucket/image-embeddings-TEST/index/*", ], ], }, @@ -271,7 +271,6 @@ exports[`The MediaService stack matches the snapshot 1`] = ` "Action": "s3:GetObject", "Effect": "Allow", "Resource": [ - "arn:aws:s3:::image-embedding-test/*", "arn:aws:s3:::media-service-test-imagebucket-1qt2lbcwnpgl0/*", "arn:aws:s3:::media-service-prod-imagebucket-1luk2yux3owkh/*", ], diff --git a/cdk/lib/image-embedder-lambda.ts b/cdk/lib/image-embedder-lambda.ts index 1f8b14476f8..446c19898bc 100644 --- a/cdk/lib/image-embedder-lambda.ts +++ b/cdk/lib/image-embedder-lambda.ts @@ -1,69 +1,62 @@ -import type { GuStackProps } from "@guardian/cdk/lib/constructs/core"; -import { GuStack } from "@guardian/cdk/lib/constructs/core"; -import { GuLambdaFunction } from "@guardian/cdk/lib/constructs/lambda"; -import type { App } from "aws-cdk-lib"; -import { Duration, aws_lambda as lambda, Stack } from "aws-cdk-lib"; -import { PolicyStatement } from "aws-cdk-lib/aws-iam"; -import { Architecture } from "aws-cdk-lib/aws-lambda"; -import { SqsEventSource } from "aws-cdk-lib/aws-lambda-event-sources"; -import { Queue } from "aws-cdk-lib/aws-sqs"; +import type { GuStackProps } from '@guardian/cdk/lib/constructs/core'; +import { GuStack } from '@guardian/cdk/lib/constructs/core'; +import { GuLambdaFunction } from '@guardian/cdk/lib/constructs/lambda'; +import type { App } from 'aws-cdk-lib'; +import { Duration, aws_lambda as lambda, Stack } from 'aws-cdk-lib'; +import { PolicyStatement } from 'aws-cdk-lib/aws-iam'; +import { Architecture } from 'aws-cdk-lib/aws-lambda'; +import { SqsEventSource } from 'aws-cdk-lib/aws-lambda-event-sources'; +import { Queue } from 'aws-cdk-lib/aws-sqs'; export class ImageEmbedder extends GuStack { - constructor(scope: App, id: string, props: GuStackProps) { - super(scope, id, props); + constructor(scope: App, id: string, props: GuStackProps) { + super(scope, id, props); - const LAMBDA_NODE_VERSION = lambda.Runtime.NODEJS_24_X; + const LAMBDA_NODE_VERSION = lambda.Runtime.NODEJS_24_X; - const imageEmbedderLambda = new GuLambdaFunction( - this, - 'ImageEmbedderHandler', - { - fileName: 'image-embedder.zip', - functionName: `image-embedder-${props.stage}`, - runtime: LAMBDA_NODE_VERSION, - architecture: Architecture.ARM_64, - handler: 'index.handler', - app: 'image-embedder-lambda', - environment: { - STAGE: props.stage, - }, - }, - ); - - const imageEmbedderDLQ = new Queue(this, 'imageEmbedderDLQ', { - queueName: `image-embedder-DLQ-${this.stage}`, - retentionPeriod: Duration.days(14) - }); - - const imageEmbedderQueue = new Queue( + const imageEmbedderLambda = new GuLambdaFunction( this, - 'imageEmbedder', + 'ImageEmbedderHandler', { - queueName: `image-embedder-${this.stage}`, - visibilityTimeout: Duration.seconds(60), - deadLetterQueue: { - queue: imageEmbedderDLQ, - maxReceiveCount: 3, + fileName: 'image-embedder.zip', + functionName: `image-embedder-${props.stage}`, + runtime: LAMBDA_NODE_VERSION, + architecture: Architecture.ARM_64, + handler: 'index.handler', + app: 'image-embedder-lambda', + environment: { + STAGE: props.stage, }, }, ); - imageEmbedderLambda.addEventSource( - new SqsEventSource(imageEmbedderQueue), - ); - // Allow writing vectors to S3 vector index + const imageEmbedderDLQ = new Queue(this, 'imageEmbedderDLQ', { + queueName: `image-embedder-DLQ-${this.stage}`, + retentionPeriod: Duration.days(14), + }); + + const imageEmbedderQueue = new Queue(this, 'imageEmbedder', { + queueName: `image-embedder-${this.stage}`, + visibilityTimeout: Duration.seconds(60), + deadLetterQueue: { + queue: imageEmbedderDLQ, + maxReceiveCount: 3, + }, + }); + imageEmbedderLambda.addEventSource(new SqsEventSource(imageEmbedderQueue)); + + // Allow writing vectors to S3 vector index imageEmbedderLambda.role?.addToPrincipalPolicy( new PolicyStatement({ - actions: [ - 's3vectors:PutVectors', - ], + actions: ['s3vectors:PutVectors'], resources: [ - `arn:aws:s3vectors:eu-central-1:${Stack.of(this).account}:bucket/image-embeddings-via-lambda/index/*`, + // `arn:aws:s3vectors:eu-central-1:${Stack.of(this).account}:bucket/image-embeddings-via-lambda/index/*`, + `arn:aws:s3vectors:eu-central-1:${Stack.of(this).account}:bucket/image-embeddings-${props.stage}/index/*`, ], }), ); - // Allow invoking the Bedrock Cohere embeddings model + // Allow invoking the Bedrock Cohere embeddings model imageEmbedderLambda.role?.addToPrincipalPolicy( new PolicyStatement({ actions: ['bedrock:InvokeModel'], @@ -73,16 +66,16 @@ export class ImageEmbedder extends GuStack { }), ); - // Allow fetching the image from S3 + // Allow fetching the image from S3 imageEmbedderLambda.role?.addToPrincipalPolicy( new PolicyStatement({ actions: ['s3:GetObject'], resources: [ - `arn:aws:s3:::image-embedding-test/*`, + // `arn:aws:s3:::image-embedding-test/*`, `arn:aws:s3:::media-service-test-imagebucket-1qt2lbcwnpgl0/*`, - `arn:aws:s3:::media-service-prod-imagebucket-1luk2yux3owkh/*` + `arn:aws:s3:::media-service-prod-imagebucket-1luk2yux3owkh/*`, ], - }), + }), ); - } -} \ No newline at end of file + } +} From 91cb4b62bd708bf95be541ac50bda53520584a92 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Mon, 19 Jan 2026 14:51:17 +0000 Subject: [PATCH 086/494] remove unused code --- .../com/gu/mediaservice/lib/aws/Bedrock.scala | 8 -------- .../com/gu/mediaservice/lib/aws/S3Vectors.scala | 14 -------------- 2 files changed, 22 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Bedrock.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Bedrock.scala index 1f43d324e70..0a2bbfbe960 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Bedrock.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/Bedrock.scala @@ -119,12 +119,4 @@ class Bedrock(config: CommonConfig) } } - def createImageEmbedding(base64EncodedImage: String, fileType: CohereCompatibleMimeType) - (implicit ec: ExecutionContext, logMarker: LogMarker): Future[List[Float]] = { - val images = fileType match { - case CohereJpeg => s"data:image/jpg;base64,$base64EncodedImage" - case CoherePng => s"data:image/png;base64,$base64EncodedImage" - } - createEmbedding(InputType.Image, images) - } } diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala index a41b9681814..db1383120a6 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/S3Vectors.scala @@ -95,20 +95,6 @@ class S3Vectors(config: CommonConfig)(implicit ec: ExecutionContext) client.putVectors(request) } - def storeEmbedding(embedding: List[Float], imageId: String)(implicit logMarker: LogMarker): Future[Unit] = Future { - try { - val response = putVector(embedding, imageId) - logger.info( - logMarker, - s"S3 Vector Store API call to store image embedding completed with status: ${response.sdkHttpResponse().statusCode()}" - ) - } catch { - case e: Exception => - logger.error(logMarker, s"Exception during S3 Vector Store API call to store image embedding for $imageId", e) - throw e - } - } - private def queryVectors(embedding: List[Float]): QueryVectorsResponse = { val queryVector: VectorData = convertEmbeddingToVectorData(embedding: List[Float]) From 9d21c35118f63539fb05bb9fb840cfc2bd9e8766 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Mon, 19 Jan 2026 14:51:38 +0000 Subject: [PATCH 087/494] set queue url as config in media api --- media-api/app/MediaApiComponents.scala | 2 +- media-api/app/lib/MediaApiConfig.scala | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/media-api/app/MediaApiComponents.scala b/media-api/app/MediaApiComponents.scala index 68315edb2c0..676e7f1ab62 100644 --- a/media-api/app/MediaApiComponents.scala +++ b/media-api/app/MediaApiComponents.scala @@ -29,7 +29,7 @@ class MediaApiComponents(context: Context) extends GridComponents(context, new M val imageResponse = new ImageResponse(config, s3Client, usageQuota) val softDeletedMetadataTable = new SoftDeletedMetadataTable(config) - val embedder = new Embedder(new S3Vectors(config), new Bedrock(config), new SimpleSqsMessageConsumer("https://sqs.eu-west-1.amazonaws.com/563563610310/image-embedder-TEST", config)) + val embedder = new Embedder(new S3Vectors(config), new Bedrock(config), new SimpleSqsMessageConsumer(config.queueUrl, config)) val mediaApi = new MediaApi(auth, messageSender, softDeletedMetadataTable, elasticSearch, imageResponse, config, controllerComponents, s3Client, mediaApiMetrics, wsClient, authorisation, embedder) val suggestionController = new SuggestionController(auth, elasticSearch, controllerComponents) diff --git a/media-api/app/lib/MediaApiConfig.scala b/media-api/app/lib/MediaApiConfig.scala index fbd43afbab5..210ea5a61eb 100644 --- a/media-api/app/lib/MediaApiConfig.scala +++ b/media-api/app/lib/MediaApiConfig.scala @@ -70,4 +70,6 @@ class MediaApiConfig(resources: GridConfigResources) extends CommonConfigWithEla val restrictDownload: Boolean = boolean("restrictDownload") + val queueUrl: String = string("sqs.embedder.queue.url") + } From 34dad5c719193ccafaaeb6fe7a7efd1c4879f29e Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Mon, 19 Jan 2026 15:07:54 +0000 Subject: [PATCH 088/494] hopefully fix test???? --- media-api/app/lib/MediaApiConfig.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media-api/app/lib/MediaApiConfig.scala b/media-api/app/lib/MediaApiConfig.scala index 210ea5a61eb..b88b9db084d 100644 --- a/media-api/app/lib/MediaApiConfig.scala +++ b/media-api/app/lib/MediaApiConfig.scala @@ -70,6 +70,6 @@ class MediaApiConfig(resources: GridConfigResources) extends CommonConfigWithEla val restrictDownload: Boolean = boolean("restrictDownload") - val queueUrl: String = string("sqs.embedder.queue.url") + val queueUrl: String = stringOpt("sqs.embedder.queue.url").getOrElse("") } From 60c94ad42b24a03d2ce0e4f69020a0a2959b302f Mon Sep 17 00:00:00 2001 From: Tom Richards Date: Fri, 14 Nov 2025 21:11:39 +0000 Subject: [PATCH 089/494] add `is:agency-pick` with 'ticker' (which has breakdown by `usageRights.supplier`) with red border on matching images (definition is in common.conf under `agencyPicks.ingredients`) --- .../mediaservice/lib/argo/ArgoHelpers.scala | 8 +-- .../lib/argo/model/CollectionResponse.scala | 26 ++++++-- .../lib/config/CommonConfig.scala | 4 ++ dev/script/generate-config/service-config.js | 20 +++++++ kahuna/app/controllers/KahunaController.scala | 4 +- kahuna/app/views/main.scala.html | 2 + kahuna/public/js/image/service.js | 1 + kahuna/public/js/preview/image.html | 4 +- kahuna/public/js/search/results.html | 23 +++++-- kahuna/public/js/search/results.js | 30 +++++++--- kahuna/public/js/services/image-logic.js | 15 +++++ kahuna/public/js/window.ts | 3 + kahuna/public/stylesheets/main.css | 8 ++- media-api/app/controllers/MediaApi.scala | 4 +- media-api/app/lib/MediaApiConfig.scala | 15 ++++- .../app/lib/elasticsearch/ElasticSearch.scala | 60 +++++++++++++++---- .../elasticsearch/ElasticSearchModel.scala | 6 +- .../app/lib/elasticsearch/IsQueryFilter.scala | 5 +- 18 files changed, 192 insertions(+), 46 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/argo/ArgoHelpers.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/argo/ArgoHelpers.scala index 1cba74dbbd4..988ff4a327a 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/argo/ArgoHelpers.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/argo/ArgoHelpers.scala @@ -1,7 +1,7 @@ package com.gu.mediaservice.lib.argo import java.net.URI -import play.api.libs.json.{Json, Writes} +import play.api.libs.json.{JsObject, Json, Writes} import play.api.mvc.{Cookie, Result, Results} import com.gu.mediaservice.lib.argo.model._ import com.gu.mediaservice.lib.logging.GridLogging @@ -25,7 +25,7 @@ trait ArgoHelpers extends Results with GridLogging { serializeAndWrap(response, Ok) } - def respondCollection[T](data: Seq[T], offset: Option[Long] = None, total: Option[Long] = None, maybeOrgOwnedCount: Option[Long] = None, + def respondCollection[T](data: Seq[T], offset: Option[Long] = None, total: Option[Long] = None, maybeExtraCounts: Option[ExtraCounts] = None, links: List[Link] = Nil, uri: Option[URI] = None) (implicit writes: Writes[T]): Result = { val response = CollectionResponse( @@ -35,8 +35,8 @@ trait ArgoHelpers extends Results with GridLogging { total = total, data = data, links = links, - //FIXME using actions below is a hack to get the org owned count into the response (until such time as we move theseus into the grid, so client can safely parse the response) - actions = maybeOrgOwnedCount + //FIXME using actions below is a hack to get extra counts into the response (until such time as we move theseus into the grid, so client can safely parse the response) + actions = maybeExtraCounts ) serializeAndWrap(response, Ok) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/argo/model/CollectionResponse.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/argo/model/CollectionResponse.scala index 2b7ce449ac3..bb8af295b12 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/argo/model/CollectionResponse.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/argo/model/CollectionResponse.scala @@ -1,12 +1,27 @@ package com.gu.mediaservice.lib.argo.model import java.net.URI - import play.api.libs.json._ import play.api.libs.functional.syntax._ - import com.gu.mediaservice.lib.argo.WriteHelpers +import com.sksamuel.elastic4s.requests.searches.aggs.AbstractAggregation + +case class ExtraCountConfig( + searchClause: String, + backgroundColour: String, + maybeSubAggregation: Option[AbstractAggregation] = None +) +case class ExtraCount( + value: Long, + searchClause: String, + backgroundColour: String, + subCounts: Option[Map[String, Long]] = None +) + +case class ExtraCounts( + tickerCounts: Map[String, ExtraCount] +) case class CollectionResponse[T]( uri: Option[URI] = None, @@ -16,11 +31,14 @@ case class CollectionResponse[T]( data: Seq[T], links: List[Link] = List(), // FIXME: the 'theseus' library used on the client mandates a strict set of top level keys, so crow-barring something else into 'actions' here (https://github.com/argo-rest/theseus [last updated 2015] needs to move into grid repo, so we can update it for this use-case and others) - actions: Option[Long] = None + actions: Option[ExtraCounts] = None ) object CollectionResponse extends WriteHelpers { + implicit val extraCountWrites: Writes[ExtraCount] = Json.writes[ExtraCount] + implicit val extraCountsWrites: Writes[ExtraCounts] = Json.writes[ExtraCounts] + implicit def collectionResponseWrites[T: Writes]: Writes[CollectionResponse[T]] = ( (__ \ "uri").writeNullable[String].contramap((_: Option[URI]).map(_.toString)) ~ (__ \ "offset").writeNullable[Long] ~ @@ -28,7 +46,7 @@ object CollectionResponse extends WriteHelpers { (__ \ "total").writeNullable[Long] ~ (__ \ "data").write[Seq[T]] ~ (__ \ "links").writeNullable[List[Link]].contramap(someListOrNone[Link]) ~ - (__ \ "actions").writeNullable[Long] + (__ \ "actions").writeNullable[ExtraCounts] )(unlift(CollectionResponse.unapply[T])) } diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/config/CommonConfig.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/config/CommonConfig.scala index f22eda8d648..2f868ead29d 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/config/CommonConfig.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/config/CommonConfig.scala @@ -5,6 +5,7 @@ import com.gu.mediaservice.model.UsageRightsSpec import com.typesafe.config.Config import com.typesafe.scalalogging.StrictLogging import play.api.{ConfigLoader, Configuration} +import scalaz.NonEmptyList import java.net.URI import java.util.UUID @@ -214,6 +215,9 @@ abstract class CommonConfig(resources: GridConfigResources) extends AwsClientV1B val applicableUsageRights: Seq[UsageRightsSpec] = configuration.get[Seq[UsageRightsSpec]]("usageRights.applicable") val stdUserExcludedUsageRights = getStringSet("usageRights.stdUserExcluded") + val agencyPicksIngredients: Option[Map[String, Seq[String]]] = + configuration.getOptional[Map[String, Seq[String]]]("agencyPicks.ingredients") + private def getKinesisConfigForStream(streamName: String) = KinesisSenderConfig(awsRegion, awsCredentials, awsLocalEndpoint, isDev, streamName) final def getOptionalStringSet(key: String): Option[Set[String]] = Try { diff --git a/dev/script/generate-config/service-config.js b/dev/script/generate-config/service-config.js index 061a4447a72..cdd4484852d 100644 --- a/dev/script/generate-config/service-config.js +++ b/dev/script/generate-config/service-config.js @@ -57,6 +57,26 @@ function getCommonConfig(config) { | photographers=["Example Contracted Illustrator"] |}] |usageRightsConfigProvider.config.staffIllustrators=["Example Staff Illustrator"] + |agencyPicks.ingredients={ + | "metadata.description": [ + | "topshot", // Getty + | "topshots", // Getty + | "bestpix", // Getty + | "PABest", // PA + | "TPX IMAGES OF THE DAY", // Reuters + | "epaselect", // EPA + | "APTOPIX", // AP + | ], + | "metadata.keywords": [ + | "epaselect", // EPA + | "aptopix", // AP + | "APTOPIX", // AP + | "SPOTLIGHT", // Rex/Shutterstock + | "spotlight", // Rex/Shutterstock + | "Spotlight" // Rex/Shutterstock + | ] + |} +>>>>>>> 3e403bd7f (add `is:agency-pick` with 'ticker' (which has breakdown by `usageRights.supplier`) with red border on matching images (definition is in common.conf under `agencyPicks.ingredients`)) |`; } diff --git a/kahuna/app/controllers/KahunaController.scala b/kahuna/app/controllers/KahunaController.scala index 769d0a81ed2..7674168c42a 100644 --- a/kahuna/app/controllers/KahunaController.scala +++ b/kahuna/app/controllers/KahunaController.scala @@ -64,6 +64,7 @@ class KahunaController( else Html("undefined") val imageTypes = Json.toJson(config.imageTypes).toString() + val agencyPicksIngredients = Json.toJson(config.agencyPicksIngredients).toString() Ok(views.html.main( s"${config.authUri}/login?redirectUri=$returnUri", @@ -79,7 +80,8 @@ class KahunaController( maybeOrgOwnedValue, config, featureSwitchesJson, - imageTypes + imageTypes, + agencyPicksIngredients )) } diff --git a/kahuna/app/views/main.scala.html b/kahuna/app/views/main.scala.html index b7af9e1af93..167b55aec14 100644 --- a/kahuna/app/views/main.scala.html +++ b/kahuna/app/views/main.scala.html @@ -16,6 +16,7 @@ kahunaConfig: KahunaConfig, featureSwitches: String, imageTypes: String, + agencyPicksIngredients: String ) @@ -88,6 +89,7 @@ maybeUploadLimitInBytes: @kahunaConfig.maybeUploadLimitInBytes.getOrElse(0), announcements: @Html(announcements), imageTypes: @Html(imageTypes), + agencyPicksIngredients: @Html(agencyPicksIngredients), } diff --git a/kahuna/public/js/image/service.js b/kahuna/public/js/image/service.js index a72a728f0bc..47fd7422769 100644 --- a/kahuna/public/js/image/service.js +++ b/kahuna/public/js/image/service.js @@ -36,6 +36,7 @@ imageService.factory('imageService', ['imageLogic', function(imageLogic) { canArchive: imageLogic.canBeArchived(image), persistedReasons: imageLogic.getPersistenceExplanation(image).join('; '), isStaffPhotographer: imageLogic.isStaffPhotographer(image), + isAgencyPick: imageLogic.isAgencyPick(image), syndicationStatus: imageLogic.getSyndicationStatus(image), syndicationReason: imageLogic.getSyndicationReason(image), hasSyndicationRights: imageLogic.hasSyndicationRights(image), diff --git a/kahuna/public/js/preview/image.html b/kahuna/public/js/preview/image.html index 11779c55767..65c47ffdb25 100644 --- a/kahuna/public/js/preview/image.html +++ b/kahuna/public/js/preview/image.html @@ -42,7 +42,7 @@ >

{{::ctrl.imageDescription}} @@ -53,7 +53,7 @@ >
{{::ctrl.image.data.metadata.description}} diff --git a/kahuna/public/js/search/results.html b/kahuna/public/js/search/results.html index 2071c3e167b..20d5fa715e0 100644 --- a/kahuna/public/js/search/results.html +++ b/kahuna/public/js/search/results.html @@ -31,13 +31,28 @@ gr-tooltip-updates> {{ctrl.newImagesCount | toLocaleString}} new - diff --git a/kahuna/public/js/search/results.js b/kahuna/public/js/search/results.js index a2f94e82dd2..6035d511324 100644 --- a/kahuna/public/js/search/results.js +++ b/kahuna/public/js/search/results.js @@ -213,7 +213,7 @@ results.controller('SearchResultsCtrl', [ ctrl.loading = true; ctrl.revealNewImages = revealNewImages; - ctrl.applyOrgOwnedFilter = applyOrgOwnedFilter; + ctrl.applyFilter = applyFilter; ctrl.getLastSeenVal = getLastSeenVal; ctrl.imageHasBeenSeen = imageHasBeenSeen; @@ -234,7 +234,7 @@ results.controller('SearchResultsCtrl', [ ctrl.searched = search({length: 1, orderBy: 'newest'}).then(function(images) { ctrl.totalResults = images.total; // FIXME: https://github.com/argo-rest/theseus has forced us to co-opt the actions field for this - ctrl.orgOwnedCount = images.$response?.$$state?.value?.actions; + ctrl.tickerCounts = images.$response?.$$state?.value?.actions?.tickerCounts; ctrl.hasQuery = !!$stateParams.query; ctrl.initialSearchUri = images.uri; @@ -391,7 +391,22 @@ results.controller('SearchResultsCtrl', [ // displayed image is matching the uploadTime ctrl.newImagesCount = resp.total; // FIXME: https://github.com/argo-rest/theseus has forced us to co-opt the actions field for this - ctrl.newOrgOwnedCount = resp.$response?.$$state?.value?.actions; + const newTickerCounts = resp.$response?.$$state?.value?.actions?.tickerCounts; + if (newTickerCounts) { + Object.entries(newTickerCounts).forEach(([key, {value, subCounts}]) => { + const existing = ctrl.tickerCounts[key]; + existing.value += value; + if (existing.subCounts && subCounts){ + Object.entries(subCounts).forEach(([subKey, subCount]) => { + if (existing.subCounts[subKey]){ + existing.subCounts[subKey] += subCount; + } else { + existing.subCounts["other"] += subCount; + } + }); + } + }); + } if (ctrl.newImagesCount > 0) { $rootScope.$emit('events:new-images', { count: ctrl.newImagesCount}); @@ -418,16 +433,15 @@ results.controller('SearchResultsCtrl', [ } ctrl.maybeOrgOwnedValue = window._clientConfig.maybeOrgOwnedValue; - const isOrgOwnedClause = `is:${ctrl.maybeOrgOwnedValue}`; - function applyOrgOwnedFilter() { + function applyFilter(searchClause) { $window.scrollTo(0,0); - const toParams = $stateParams.query?.includes(isOrgOwnedClause) + const toParams = $stateParams.query?.includes(searchClause) ? $stateParams : { ...$stateParams, query: $stateParams.query - ? `${$stateParams.query} ${isOrgOwnedClause}` - : isOrgOwnedClause + ? `${$stateParams.query} ${searchClause}` + : searchClause }; $state.transitionTo( $state.current, diff --git a/kahuna/public/js/services/image-logic.js b/kahuna/public/js/services/image-logic.js index eebb38fe098..e1d88ca4e59 100644 --- a/kahuna/public/js/services/image-logic.js +++ b/kahuna/public/js/services/image-logic.js @@ -43,6 +43,20 @@ imageLogic.factory('imageLogic', ['imageAccessor', function(imageAccessor) { staffCategories.includes(image.data.usageRights.category); } + + function isAgencyPick(image) { + return Object.entries(window._clientConfig.agencyPicksIngredients || {}).some(([field, values]) => values.some(value => { + const fieldValue = field.split('.').reduce((a, b) => a[b], image.data); + if (typeof fieldValue === 'string'){ + return fieldValue.toLowerCase().includes(value.toLowerCase()); + } + if (Array.isArray(fieldValue)) { + return fieldValue.includes(value); + } + return false; + })); + } + function getPersistenceExplanation(image) { const persistReasons = imageAccessor.readPersistedReasons(image); return persistReasons.map(reason => { @@ -111,6 +125,7 @@ imageLogic.factory('imageLogic', ['imageAccessor', function(imageAccessor) { getArchivedState, getPersistenceExplanation, isStaffPhotographer, + isAgencyPick, getSyndicationStatus, getSyndicationReason, hasSyndicationRights, diff --git a/kahuna/public/js/window.ts b/kahuna/public/js/window.ts index 905cccd4d37..d542f20b2f1 100644 --- a/kahuna/public/js/window.ts +++ b/kahuna/public/js/window.ts @@ -43,6 +43,9 @@ declare global { maybeUploadLimitInBytes: number; imageTypes: string[]; staffPhotographerOrganisation: string; + agencyPicksIngredients: { + [field: string]: string[]; + } }; } } diff --git a/kahuna/public/stylesheets/main.css b/kahuna/public/stylesheets/main.css index 17a2a852ec9..712c588df43 100644 --- a/kahuna/public/stylesheets/main.css +++ b/kahuna/public/stylesheets/main.css @@ -1512,9 +1512,8 @@ textarea.ng-invalid { margin-left: 5px; } -.image-results-count__org-owned { +.image-results-ticker { font-family: inherit; - background-color: #005689; color: white; display: inline-block; padding: 2px 4px; @@ -1653,6 +1652,11 @@ textarea.ng-invalid { box-sizing: border-box; } +.preview__image.preview__image--agency-pick { + border: 10px solid #970201; + box-sizing: border-box; +} + .preview__info { font-size: 1.3rem; padding-left: 10px; diff --git a/media-api/app/controllers/MediaApi.scala b/media-api/app/controllers/MediaApi.scala index 2150de4ec53..5a46d1fbae1 100644 --- a/media-api/app/controllers/MediaApi.scala +++ b/media-api/app/controllers/MediaApi.scala @@ -542,7 +542,7 @@ class MediaApi( } def performSearchAndRespond(searchParams: SearchParams) = for { - SearchResults(hits, totalCount, maybeOrgOwnedCount) <- elasticSearch.search( + SearchResults(hits, totalCount, extraCounts) <- elasticSearch.search( searchParams.copy( shouldFlagGraphicImages = shouldFlagGraphicImages, ) @@ -551,7 +551,7 @@ class MediaApi( prevLink = getPrevLink(searchParams) nextLink = getNextLink(searchParams, totalCount) links = List(prevLink, nextLink).flatten - } yield respondCollection(imageEntities, Some(searchParams.offset), Some(totalCount), maybeOrgOwnedCount, links) + } yield respondCollection(imageEntities, Some(searchParams.offset), Some(totalCount), extraCounts, links) val _searchParams = SearchParams(request) val hasDeletePermission = authorisation.isUploaderOrHasPermission(request.user, "", DeleteImagePermission) diff --git a/media-api/app/lib/MediaApiConfig.scala b/media-api/app/lib/MediaApiConfig.scala index fbd43afbab5..ae80696bb1b 100644 --- a/media-api/app/lib/MediaApiConfig.scala +++ b/media-api/app/lib/MediaApiConfig.scala @@ -1,11 +1,15 @@ package lib -import com.amazonaws.services.cloudfront.util.SignerUtils import com.gu.mediaservice.lib.config.{CommonConfigWithElastic, GridConfigResources} +import com.gu.mediaservice.lib.elasticsearch.filters +import com.sksamuel.elastic4s.ElasticApi.{matchPhraseQuery, should} +import com.sksamuel.elastic4s.ElasticDsl.matchQuery +import com.sksamuel.elastic4s.requests.searches.queries.Query +import com.sksamuel.elastic4s.requests.searches.queries.matches.MatchQuery import org.joda.time.DateTime import scalaz.NonEmptyList -import java.security.PrivateKey +import scala.collection.immutable import scala.util.Try case class StoreConfig( @@ -70,4 +74,11 @@ class MediaApiConfig(resources: GridConfigResources) extends CommonConfigWithEla val restrictDownload: Boolean = boolean("restrictDownload") + val maybeAgencyPickQuery: Option[Query] = agencyPicksIngredients.map { ingredients => + filters.or( + ingredients.flatMap { + case (field, values) => values.map(matchPhraseQuery(field, _)) + }.toList: _* + ) + } } diff --git a/media-api/app/lib/elasticsearch/ElasticSearch.scala b/media-api/app/lib/elasticsearch/ElasticSearch.scala index a8c13fee1eb..6cc1b4910a7 100644 --- a/media-api/app/lib/elasticsearch/ElasticSearch.scala +++ b/media-api/app/lib/elasticsearch/ElasticSearch.scala @@ -2,6 +2,7 @@ package lib.elasticsearch import org.apache.pekko.actor.Scheduler import com.gu.mediaservice.lib.ImageFields +import com.gu.mediaservice.lib.argo.model.{ExtraCount, ExtraCountConfig, ExtraCounts} import com.gu.mediaservice.lib.elasticsearch.filters import com.gu.mediaservice.lib.auth.Authentication.Principal import com.gu.mediaservice.lib.elasticsearch.{CompletionPreview, ElasticSearchClient, ElasticSearchConfig, MigrationStatusProvider, Running} @@ -27,6 +28,7 @@ import scalaz.NonEmptyList import scalaz.syntax.std.list._ import java.util.concurrent.TimeUnit +import scala.collection.immutable.ListMap import scala.concurrent.duration.FiniteDuration import scala.concurrent.{ExecutionContext, Future} @@ -38,7 +40,30 @@ class ElasticSearch( val scheduler: Scheduler ) extends ElasticSearchClient with ImageFields with MatchFields with FutureSyntax with GridLogging with MigrationStatusProvider { - private val orgOwnedAggName = "org-owned" + private val maybeOrgOwnedExtraCount: Option[(String, ExtraCountConfig)] = + if (config.shouldDisplayOrgOwnedCountAndFilterCheckbox) + Some(s"${config.staffPhotographerOrganisation}-owned" -> ExtraCountConfig( + searchClause = s"is:${config.staffPhotographerOrganisation}-owned", + backgroundColour = "#005689" + )) + else + None + + private val maybeAgencyPicksExtraCount: Option[(String, ExtraCountConfig)] = + config.maybeAgencyPickQuery.map(_ => + "agency picks" -> ExtraCountConfig( + searchClause = "is:agency-pick", + backgroundColour = "#970201", + maybeSubAggregation = Some( + termsAgg(name = "byAgency", field = "usageRights.supplier").size(9) + ) + ) + ) + + private val aggregationsNameToSearchClauseMap: Map[String, ExtraCountConfig] = List( + maybeOrgOwnedExtraCount, + maybeAgencyPicksExtraCount + ).flatten.toMap lazy val imagesCurrentAlias = elasticConfig.aliases.current lazy val imagesMigrationAlias = elasticConfig.aliases.migration @@ -120,7 +145,6 @@ class ElasticSearch( private val isPotentiallyGraphicFieldName = "isPotentiallyGraphic" - private def resolveHit(hit: SearchHit) = mapImageFrom( hit.sourceAsString, hit.id, @@ -145,7 +169,7 @@ class ElasticSearch( executeAndLog(searchRequest, "ids lookup") .map { r => val imageHits = r.result.hits.hits.map(resolveHit).toSeq.flatten.map(i => (i.instance.id, i)) - SearchResults(hits = imageHits, total = r.result.totalHits, maybeOrgOwnedCount = None) + SearchResults(hits = imageHits, total = r.result.totalHits, extraCounts = None) } } @@ -270,10 +294,10 @@ class ElasticSearch( .runtimeMappings(runtimeMappings) .storedFields("_source") // this needs to be explicit when using script fields .scriptfields(graphicImagesScriptFields) - .aggregations(if (config.shouldDisplayOrgOwnedCountAndFilterCheckbox) List(filterAgg( - orgOwnedAggName, - queryBuilder.makeQuery(Parser.run(s"is:${config.staffPhotographerOrganisation}-owned")) - )) else Nil) + .aggregations(aggregationsNameToSearchClauseMap.map { + case (name, ExtraCountConfig(searchClause, _, maybeSubAggregation)) => + filterAgg(name, queryBuilder.makeQuery(Parser.run(searchClause))).subAggregations(maybeSubAggregation) + }) .from(params.offset) .size(params.length) .sortBy(sort) @@ -287,11 +311,23 @@ class ElasticSearch( SearchResults( hits = imageHits, total = if (trackTotalHits) r.result.totalHits else 0, - maybeOrgOwnedCount = - if (config.shouldDisplayOrgOwnedCountAndFilterCheckbox) - Some(r.result.aggregations.filter(orgOwnedAggName).docCount) - else - None + extraCounts = Some(ExtraCounts( + tickerCounts = aggregationsNameToSearchClauseMap.map { + case (name, ExtraCountConfig(searchClause, backgroundColour, maybeSubAggregation)) => + val aggResult = r.result.aggregations.filter(name) + val maybeSubAggResult = maybeSubAggregation.map(_.name).map(aggResult.result[Terms]) + name -> ExtraCount( + value = aggResult.docCount, + searchClause, + backgroundColour, + subCounts = maybeSubAggResult.map { termsAgg => + ListMap(termsAgg.buckets.sortBy(_.docCount).reverse.map { bucket => + (bucket.key, bucket.docCount) + }: _*) + ("other" -> termsAgg.otherDocCount) + } + ) + } + )) ) } } diff --git a/media-api/app/lib/elasticsearch/ElasticSearchModel.scala b/media-api/app/lib/elasticsearch/ElasticSearchModel.scala index 37b82cae879..4e710ed2e97 100644 --- a/media-api/app/lib/elasticsearch/ElasticSearchModel.scala +++ b/media-api/app/lib/elasticsearch/ElasticSearchModel.scala @@ -1,5 +1,6 @@ package lib.elasticsearch +import com.gu.mediaservice.lib.argo.model.ExtraCounts import com.gu.mediaservice.lib.auth.{Authentication, Tier} import com.gu.mediaservice.lib.formatting.{parseDateFromQuery, printDateTime} import com.gu.mediaservice.model.usage.UsageStatus @@ -8,14 +9,11 @@ import lib.querysyntax.{Condition, Parser} import org.joda.time.DateTime import play.api.libs.json.{Json, OWrites} import play.api.mvc.{AnyContent, Request} -import scalaz.syntax.applicative._ import scalaz.syntax.std.list._ -import scalaz.syntax.validation._ -import scalaz.{Validation, ValidationNel} import scala.util.Try -case class SearchResults(hits: Seq[(String, SourceWrapper[Image])], total: Long, maybeOrgOwnedCount: Option[Long]) +case class SearchResults(hits: Seq[(String, SourceWrapper[Image])], total: Long, extraCounts: Option[ExtraCounts]) case class AggregateSearchResults(results: Seq[BucketResult], total: Long) diff --git a/media-api/app/lib/elasticsearch/IsQueryFilter.scala b/media-api/app/lib/elasticsearch/IsQueryFilter.scala index d946e65a7ea..6f94f97f2fb 100644 --- a/media-api/app/lib/elasticsearch/IsQueryFilter.scala +++ b/media-api/app/lib/elasticsearch/IsQueryFilter.scala @@ -6,7 +6,6 @@ import com.gu.mediaservice.model._ import com.sksamuel.elastic4s.ElasticDsl.matchAllQuery import com.sksamuel.elastic4s.requests.searches.queries.Query import lib.MediaApiConfig -import org.joda.time.DateTime import scalaz.syntax.std.list._ sealed trait IsQueryFilter extends Query with ImageFields { @@ -19,6 +18,7 @@ sealed trait IsQueryFilter extends Query with ImageFields { case _: IsDeleted => "deleted" case _: IsUnderQuota => "under-quota" case _: IsReapable => "reapable" + case _: IsAgencyPick => "agency-pick" } } @@ -33,6 +33,7 @@ object IsQueryFilter { case "under-quota" => Some(IsUnderQuota(overQuotaAgencies())) case "deleted" => Some(IsDeleted(true)) case "reapable" => Some(IsReapable(config.maybePersistOnlyTheseCollections, config.persistenceIdentifier)) + case "agency-pick" => config.maybeAgencyPickQuery.map(IsAgencyPick) case _ => None } } @@ -71,3 +72,5 @@ case class IsDeleted(isDeleted: Boolean) extends IsQueryFilter { case class IsReapable(maybePersistOnlyTheseCollections: Option[Set[String]], persistenceIdentifier: String) extends IsQueryFilter with ReapableEligibility { } + +case class IsAgencyPick(query: Query) extends IsQueryFilter From d9cd0bf0de8f01ac8d3eab851690d2b64f76b56b Mon Sep 17 00:00:00 2001 From: Tom Richards Date: Mon, 24 Nov 2025 11:49:52 +0000 Subject: [PATCH 090/494] add delay to tooltip on the tickers --- kahuna/public/js/search/results.html | 9 +++++---- kahuna/public/stylesheets/main.css | 4 ++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/kahuna/public/js/search/results.html b/kahuna/public/js/search/results.html index 20d5fa715e0..de4f492a84d 100644 --- a/kahuna/public/js/search/results.html +++ b/kahuna/public/js/search/results.html @@ -32,7 +32,7 @@ {{ctrl.newImagesCount | toLocaleString}} new

|#O<@}Ps24rI|-mpB~wR8> o2+in>0&TXi3&$@v;domA3HK_VJU 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 lVBN~#}^sp88_6ddpDC` zy)?n3(n*%_oRq>D(TL2s-?R&t{7xsCcdne7X-3_r)ZNh!zE7FA78Ggn<19$K zF_}Th5G92~{xhLt!qB0w$k2xgUmm?JZ~dJ;*7Db9@4oEaZT=;1e%ihJ;fH^jpGtQ> zY`zrl3i4og4K+*DP3YL%w1tQsd5e1HJptiHr+qpmQ#JAGKS2GxjasiM9*Y32UD}mA z<@X7`1gW~yMAf*$qzj4h+cKTf#|T!fR3HnhDK3y(!T1n_R`Uz}zNQ&Bo(-r=VT+E~ zA{u3XNO}K0R$Zp{)-v)0#)?Gvs3zZ+T!p%O*p)P9EUy;K4TGnMQpuh&W~HE0&fCh% zV#DbneFQT@4bv#m(lyfrAnJ8U+jvo(D*Ai>LpCt72{N+}WkZkk`UlR_brv}~u->IB zBs}gymcCRqS{3Ov>-IWjNI_5_wsfaf?$!D{IRV?rop>lc69)Quh1;F87{lO$^RI zwL)g#v}e84^>(0Jfl>=kh!lb-RJ;ZzB|aITLRy>Og9I1B7HE=qkyS$tcZ=ZK+{eJE*wQCXPOIV=YyVP}m>h zTW{yeIpLT|N>C_v0y8+I-jGW;>w-Y`hhnd*?}alB4~ibHd(#II4*P z*jh=8H5te8oL=N2cF=T~U_tNLwIT{fHc7qFB%ZC7>b4Qbllx0fPgA_kd$nH7KfxsZe4-}I6`WYPi6NT#4o3++?kHLu_oXMMc zlp+86R}L>AOusWi;NY~T_IVJimx{@-lJP;V-@#|N%eiE;0K;G8EZlS~o#>JP(_46a zE6ZP<`u59@-PT!=`AbGuxAwk~HLLF&$(o+f8yGx!B@wTLp^t}JY;gfo8DtM@yuYTX zD)Mv)8)f-Pn~Cfqp@LTX1pQ&V4E*84=kjOCCe`C|h_wuxc#3}rNx|1;kxrOoQcwHn zut~3x#;9+6jNQB-uZ85I`Qwhzgab$eXu}n$B>avga$zZ(Y?F5zx+kv-OBCQtK1@* z4ri14v=dFQV~u!<%hlQjIPWg)DeVjSk^5_|N%MbEK(Z8*=1DPWniQJBfbH2BItNxg z+Yx=qVay|cfee6j71(SeR?Tt&2X6}zFvAOIi2WF3m}gIdjB@kkY{3q+5xZb^3Bfn< zu)|Nj=?Zjbvh_=jiscdeXScwol9oc%Y$h*gVmYY3H}oacbSL^GPLhZ+l%4c9*>6Yy zE+`Xq)x>gWf6LLl%l+#IvF@b+{`H64jxGPxLZMyt&qTU1VGpR`yec4!b{;kZm-=9} zSioTx7g&ut#wcL-IhlNrM5PLZOlO~nko{Gc5@vFk_00K1DpMgH&#v=A&~neD^lg&A zW%({(msEVZf$Rx+`ymWEc}>w|mo}pD%OYQfVExskRDQ<}CzL#}rAMJaKGl8CZLh$VoeV`uD zx!Bx?6ph9w@iH1l%ZObW1?H}j3Pg=t>di*a9#*E`_<*9L@!lnjT6wGyaMg)oL5M{M zy_I)9{XpjLbmLCzC~sAD583o;t$WZDjIGzcrzX49h?Kk%vxQLP*qCgU!);8X3$9Hi z5@0d$R!*GMXW{iV?|;a&3);mDyXo-M5lmKaz!T@LsU$B5f@qrC)~sV?tjqR=oq4~; zMeX~vEEeticKabM>pZtv@t`4i`|TH`nY(v5ok5=JsQ5R62h;^*)8fvTj4XbXPP%0A zZ(pT*_LQU66W_1GOw;T#W43`wI-61x%(N%x%nimj<)~9k@rYxPu1S%FG?PVTB+t=2 zj~dC~0IWfTdt;O=<0f}q(*r{+Xm=%{AXhsTlArD^nDzgu`>qTyO|I(#*n(vvK} zA&Yd)V@yVSr~F0mykN=u%QPR}wKdu@RbgHHE-DL7_Q6uZ$CF$CT6EasG5&uIt+RV#AyB zQvYc|`pzrR?@;$1c?H5}YljcXC9v+%nhKz(eV)eyDsiJJjhJ+9Y#-uRs!#as4{@6$ z!RmVMu)mV2?y+mdcpa7r1-rA1!*^n`!-Lyz)p!{Xcz}UJAYK^+6lX}sg9aOW22ve`#dy+h@mA-6Y1L*bOW&`%U}G#zy822P1^cK2RgEbfgn8MJhgqvNr{rNBx*Z{MJAhwAUyFJSg~@bVN+tTs)o4uL zEOKZ!tC;BEYE~vBx)RV(WG5tcD?8HTsk*Qw=A0=N9!HmfdPfCqxE>PuV5~HqzlBsS zEUmm-xT{jlYs+TQ1~a#_JlXsjY38}+PU0oaRR=w7UFE^&Q^1H~dG7$q?+QAbbytI% z^Eq5@)4HgCR-Hq+BFGkT5PDU4JohctTu{s;Ulv%LK-i#flK3DRP3Tb`-}39nq7}W2 z`2iC7S19cnJ3umaj1a zT5Df*6f|CC*Yym8qwCq{d+B;s^+|O-Z{q9ddd`Y0EUize6Pe+p2NxP+-NH55>mo>J za+h#7x+a@LLV@_kj9*Ze4;l)DoTnZTgoVhk@JDj=uCv>3<~IvmaYX>TeDchp*YT}0 zfylRe%^tW9{*+V4zHk0?^9DGOO%E+kW~-@bZ?aEobC6YgG6r(=PtQNz{VeROO$Uox z%8?#{YmSl$+{@IMi36<3S{%s}G1}AEQ?uQ}s5KNnkGFS~J}X3c1N3y&7+TO$4QnoQQKJ`sD3 zCZ3wH1}iej@GzdtXM|&eTj`odbae=9UAYdRdMXJIHTmSS9%5Z~M-AUgr8{eUfcJ9P z_>euR)5hEA*Kyo<8JK0T`sEV655QiU-OvllEm|^-#<$DSASq9WtvR^oB{vyZh1ci4 zdn2~a1Z)V%B;lbZ5JF1)JNZL+A?b&!VxHX}A4peUuO_MP~d7yOz zuqy9XRMoDM71gQ+j@oDT{y?%EO z-txi0bHb~o1>NyMn`R&fA3H=E!!I&x6vOM0=+Y_7ux4H(o}jbm%jx~wo7u%LFc z?AVm$Zi%^eeA3+Q)_4ub%>cSQUUWypSnU&zZ+VQ9S#LorEe1D4ts!*u_7%fG>luZ7 z${M{oRt`<$b6InAnmj))*TODn4prBnuvv9nZXN%U?oMT}HL978$Fl)@Axzs$na!S3 z89%P&z;L?*h2*(})zhTXbo>n*#!yJ}UAoklQJtQXPXCgygFS=y=SgG_#wc5MI`qGE%b zT{LSJ)WIHnGy(gPmMx5!s_YL$L|QgcrOIlv7`?6PD4EZak;DAzOoQ?P)db9Fx}uHI zAbb;fc5qU=&xJa=%nHw8k1_gLL3H+w+c7jD!4U?%mh+lq2@vs_)egK4h{3RE6jp5 z+<8Z;_-Vo`gqpBG{isdA8+}$nes`movw42Y_J(GeRfw>$)iFU3#4fw2shd;603Y- zQ)2O=qs=gCr<veBp%7e*-IC}M%Zh9kzAEeDMSkws zP@qO`c+f&l}Vtk14Xp$)hHfzM^l@s`k90CY&MNCyyp(y^XbHoSzDEP zJRmYFx*Z1!5rwW2Th=tfdtHG@Os;TuA?s$@#HJ9x0#IuO;tg@X6z$TsR+ zQ0VT3^|fvy;V%uDTOa_N^6K@e!{Un;FT?mhlT$z_8~xax1G%g<%6o?GYwsW`J!9Iq z#bdUxgYT|4`w&~W^)=S5D|G;kJ4N;{1Y~L(Fm5ZNk)dn;%!aJYS`C!)f%_C@(NrVZ zE?SB*I2q8ft&bvG5&W9DJh%hNq^ zP^*)z8Z!T?$4--#ndxC8AP#5+OKrQF>$xF7 z4sr&CVsv0}C9Uy^OMHI?2tI5`-G zlW9F773{3TC}TFF<}gN##45KDO(>r!SLHUM0gW1oRc<31kO3pH+EkrxMvD)oqq*9w z*~K*?kfw+=J2s4OaGT7Q(m_#cs@jZgICIWWk0^Lc#?h_q60NpW-J!ctthTgr-&Tdh*dh^#e>DjwZ`HlD_uq-b3LljodnTpBX@nQ(Op|@Lh6)< z!-cguuQ9`t`X-MTqv5rGp{+58F}o)p54AdRtXB ztFyssV)<2THAceF@wnDr@gB^Q7&)Y_z4~mI8^ul8EYE;ul(v{!rlTNcqEAQHm=dA~ zcc28g8bUR2t*g)`ELE3TY>o@t@cKrlXO51&?W^?~E`aTWs`Z*KkQIQ$0qL9~|Cki_ zro2A&X1g?elp@)?A$`7?jfWp0kOO6^V##yFeo@zbAc+Y40W(xHLOnIHSxZ*(9WQ(SaY4n*`S~u6e~_a2Stm+qM#;B)8u@r!wqV* z(yL(IY}#u9<}Jf3cG6pPcRHuiy_Z%K;T=?6rc&#vn%+&TMh_o_ut$*A!^gs{i1O8* z-XU)y!rh*ay_vj`r^jbzug_-7(bY&M8uE4e%p%%b4Q;b!wi$GP0(2`3j+bay9lHk3J8E$;|vldp^MSL;899UaL*QzfVF&Z7!{qi z1x*`nN4NG?8bEE#IxLRdrdh9nchcKS6uf6ZBmOo5(!yXca(f*N5^eXwfaG3Kr|FB9 z2MlZdqT>NZ33y`wBMxx_(!yY{rr&fhNUU8JLq>O1C#&%o39CE(kxA4z8W8j6$JwRI zQf7b&;#@c6X{&6M*~WOQ+_KA&PPNodf`cu|8gsc?#@K9ZmD?U*{W_a~?bz*OtZJ#f zhmBLD%6H(G-U=9gA9@o^8jcK%m`)%3OGiuDj2>`|dCFY$R6^-*yfQ1r*U|Wu<=_FR z77m6I@~VRaqXd|UF?=RA6iKIL!EmoMiq6KzVR6JU4s1g83?NJawt6iL2BWWMO_|<| zz6XJVb}*!9M|vF;D-Mf-8Zi6_g1`jN9{{f914Mcxjw>*5jMR=)gq_$7gFNl$Wkuw?q9=fm^4327dnM^{7lv0Ys}Lc!)iFUZVp$M6klKldqXo_N zYo0n#->7-0$vh(Ij*vPFoyGxeUud0rY3o(<+ms;~#-Fh>4O0HmXu)%YRHp+{PZ0lh zy*4#4;0~txi2>yLnCq;kNh4ZXEM`aO$hmpFS?_5@Jm@MOLe6g!uF=#18&R?p$LlU^ zSA*=rlfh3|#DOjt&|th8isLG7ewx_YY`mF%G)t(-R==Lk7BPNNsorLN zPQS6vz&je@$Rw_J1T}>7gb8td+Fs1A?L*Bv?>|u!UHvs76NcRYl>AJ&Gg$AMvj-9! z53N&>I*aJ6C%wgLI*6=;;d+mmu&%GrbCH?5IoI%Rk{XQ+RUC!H{T;G%S^ONN(s@dy z^Ete_kXW^*DYZ=S6TCl&UOMLrArLr2V8kR-P>5o9)6(S7%^$*mrkY}~25vgim4+b& z@S+kF!oT+Sx+rj>k>O)Yl)4Mxk4#d2oRO6`8i!f>BOh!pushU0@}c%tK?eFYoeEZn z_v;G(Sh4T+zpnEVbNzk&nyQ%B6S&1~-GqJJVEX|dUD zzGf>l{7F_I8h384*00+&-Zr~H;o3TM8e%^EM!CsME0~1k@wj=*FHE{@C!kdewn_~b zGHv{ojztCJB4&dhbE;ze5YMU9%2dl0%!W9vOsk7^gj5}6Y8P248vHOz)x~YI#IDrJ zR152A-R`NUE>3OFAvdVPZMu6d;o-mM(U&wk}#D6He^R zP+*&~i(QIZC=kj&jjR&)-IWwEb zyck&)*y@}b&(LIg6jLg;0_8d=WAp)!0!TajXV*XlPPQVAKE@`9=w@gcY*wk0r+F2* zQQYjNglNRMCDA<5D0L;F$yP7&kM*_6KO+sk<`k2ygGnV5h*6S|^%Mv)3YkNvIbU&S zj^*uYwmDX37V-d!Y;hAJ>|vc~hi0$lwvZwEo2@W`v;xiZ1_I%T-g(5kj;v2jUS{tO zo4Np+1qmy0g1eg|Hat`Nq^(IqRPCe(bcb&{xmi?4reKaUmes=x>&oI8OCEPdwz|P9 zyJuB~c*wlBz@iH7xb%dCX$x1j}e&wVC~k+QQ3R`@AisJ5{c<*cpnfHa@2CYSL7 z!Pq@!ggSZYdGTviY&jv$y639Q6}+?ax}<=W)`v*@7d4ZSyfe6+dv>94%F9z2(jJPG zW&s>IhA07Vq`=$rg;bfPRMEldQse}Jvy=MJ`E#pWFZXI1R5%GHt5cDU`Qnav0FfIv zWG(sx?voeL#7M>6?@DjgRVV87mid*H)~&_PLu?S6@ht{LjUdb|#1HH`4+Dfv;Og9C99(EI`^Qr?!_Ri-7 zbZlSOBG8u>uq_)69l#!?GgEE@ukA4SmV%YSW&)IT0SnHVw!-DC77`3U251s{^FE6cxyeoxy(m|ZRzFBS{tRHVPHTa=-d46f`Uo)YqrJRg_Jt3E1@m! zE~M1NyVAk>f`T^9E~V{Z+rm2?tbw+4X10`R*U%Or;OW)SHd|(!K~tdji_m2cEKY=%3KYC&KqHZRZ61(p!=TtM3`jg6 zxy@sY5ik_z8v_`LF>dq7VH*a+#xlQBbH+LHZCAUZkZwG{mU9!pv6EI2<>6ePZP!H$ zr17P5ZqBmq(e`cIp?xNb*dEg?Ynp}bUac)O6=Gww%0`*JknvDvy&O?#ExEjg0*>1) zsb(|m9oj9WVKYbiwp&WMW{>o3^GIJ+3ENV%MWn9_h7$6sg9D=kn20faCN>mFr)9x- zBYoSgj*ZVB=}UlDIIs!TGk`FC!6SWb7>vGN2ZO|@Ya25&9wG)akH{t1f)TlG5n_u0 zVofup;JI+qj^uncKQF|0>+?S~?O+z&vXWbCT1U5IUSKju(@Wb0422-9(nN zMM+m*X3>ZhjUaQPRcpp;(HHFXqMxAPr`5>p%}-_aIbOxq>FG}uRx%?Sh?{5;4J^Om zPt46vs|KC?Kd}vh3z%3?F%D)x)f82=WDw0gw4F#O*E92zB1ivBMa^;Zbjlq%kwoNg zc`S5k(ld@|S&%R<1EQ`?#|lqWEv|C-QeJmhnrR6Z%oN>WsiG}lEZ1{~4VDFoWnu1A zdI+SQC!@oTVl^yKM1zSQoF+9=ZS__?) zQ|#*Q4$p1Hx#tIK>rk}39a%K9RZnjZQNta66UAr{g>%7-^0qdi9BtcaAB);#Tg2A~ zDZIac1;q9 zIRawQ7XMT09CX3Pk!S;gjTlP`taaWf?OGJLYjCHl4>?*sRTAb}^d0s}iq?i5f70n) zAP^VP*wXbqeVm=6F77uDc#AvKnsAaL8Z~#cGLtOclF|_%DrjIMV9i^4CNw0c`!M-$W5LhFF89;?RINhubW-7 zfF-0M5=53-?j=PN5q4jnFkvAg=&Hx=>sXc=-y7^Rc4*dZYQtt9FLjwas~eADsifp^ zGsuEs`PC3OIyy}Dttu@~4R=NEayJ57gr!%~rku0nc6)q1pkY9XZ$0R-oSz7o8(_pP>{wI`n3TIWu)2J9n1`TUp}DQ~ zVHrtHY<#EdZ+CTNO)l2=UUY3h_sZ-m>4~-X?v?5C-kZ%w1H0&$RU-S#rF$OVJ61UP zS(shDX93t-yIw^Q>-b&y9WhE)aLeDT%y7WOf|}!C22_=k10E+dny**oVQwlEg{y+* zXgZp#Cinq&?^JQp&HL9ojjUp$lre&xc{#mrEKF(~02X$KJb=uK&*Tt6Bv>+!%oVkF z78w9WS&OZejBeI(ST&tYh`qJ~b60~N+cx!P%V>=I;Co#@EL}?iyNWp1=Ilj6xXiED z+87%pBf)3$Ypk(9v5FR2nOQVpB^JlHs9FlCr^%-A-5Oi7b#|#94~gngzo9+dXhazj zf_Q%13EQpCgkp1YVDANr>hQdov;9{XmO0t=%)Z>!q2Tll|H7z?1~Lb%2qf$O+%SU1}iJ`9(I3PaOj?CR8wuX9yV z|9(Lysk7O+pq*ETfZkzddEe1o?>w9_5XyKFYXFH^ve1h3k~fqxewyed>kUuPLa*g& ziBjC;I&Vbo6&w^{@SE1Lgl9K?=?j$T7S%vtvtdsBh?IxirG)Zfb|(vlD}N^GX!C z8M|-jSl!H$Wh1(b4Hx}QTU0~(cGH$f*{X^p3%~hEfc&(I&3gkkBT;np?AfPJpNgMK z#o6Ne+3xoC&aN$l7Pqnj?dl5%ZUgR1O7anfpN3#1HZ9*2I~K6IvVj ze#yRn-nw)hu9KlG9g4dZDBK4D_QAT)Fqw;zxosIuR-$O-u9&pi+%aY5)S8;3r}gvc zL=?UM8D0Z(I--7Y|vJ8=~yAl`ihxvtY~XAL`Lc(t^5&NcRsS(ybP~S^QnJMM#eX~ zpZYu*%g|e+^n{n5jH4xCvU%k9`HYv^M*8QoiB{s+_n#xm+|OIlodC1rWF6yzY>u}~T|(dz4U9cxzLhu@{^#gYYnv}e zk+}&aFxLwWh(7wgbuC~0Cd(J%@+P&$QwQ~!ub*2}o5=)x=?AxG0|B40*Gvrf8D03H z+6OW*op5df`V<0uC|<1L<~OhR}k4_65CZyYfk-5O(DG#-rmaJ-f9|d zQE!h%_>*y6(?;n)gO$zcCFcKaOy8YU#0RED>RKwbNj!ODZ+vG1W5EMsr9nkzxy7q$#=>4VEAv zmoo#1J`p1ooNax7j;>-&1zmj_ZqZ!_A%=;dgP81jG)pE2yi!VNXyl|p=6F#i>i9w$tZ z*A5BnLIu~L_CFvE4uh;>k!|78x=Bdz@KqVb5`FkES{u_A*^_R4m?U(0x7TWp z`0~U06pED-(4rd&j$1dFvZ7A2ngr?(xWdkc8#Q+T^D;EnOLnH?o3S551LU)qt}N-q zgz)-Gqv{%t@3yX1<1yy8A;1e8c46gc2ABu~A}iP20{mpdeX^4_1CWD_Lb>R`=c+)( zeq(DSGDL1INA{94nv5q{oiQxTaxZ|@OORTLb!(%7S((#j_Sr-mp zxS!BE)HRn8|Ee*WX+)C+f-6^q>bVAoITx+fC$!kiw9(@YM(EXSdriu+1R2Xuc(t)s znl%=d+03an!>*wNq~2M69X++ziG$u9k-5Ir4f|k?RS;eD^aU@tzAa{R2i4Y$o~jWd zme$sKF?Z3Rd~PAGHb}Mss30%fO?pk7%qW zsb%b-c~>)Rqz(Hgi@D>NI`^<_Y^&y;MhsXPsYnKH%$j5R+|$yryhCeyglsG6UPh57 ztV=hf#Wa`#_R(_af_aw8<^Kv2l_ zD_t6mS;##v%JrZ-F|1(m@Ss|DH)$ReYD!l zyk=slH_thqYPk-Wb{tGreHQUzVribYIF?QYkU;04OE<4bmzXth_bv@F590vL6fT!5 z75E>}4F3}v>xduQ;*Ym|!o>b-LQ(&m@V?(^7w9|Z1@>meI|;}C%~AgE$nW@X+J&E> z3#&Tm08%LWHxCxW%43utnB{a+arcgwvwwAF;i+THA*lGpfgas(-z>Y?n#$u!8)5M& zX{V)F`8L0q`{8dn7OTlR^!W@rRIW6jyE#@)(@CIxl0?w}y)o9Q9`9Al?Ul%Dquu68 z?N+&kbgKM44S!&b-mSDh1HgkG6^v^jvK<>Xw>Km z&l@!I#?u~aNGp6Jm)5;X3F%#>(y72KApeMe&n}uZYB;_s^M7vOUrToz|8qK8nN23M zDGLTPdPtT$)-=dq1-^@rVM=zHMlm-Y)ZWHHM?D)xom~e8JQqQ0 zc@QvmJ(7}fa{xkth_@t#NQnCTbxHf7W@?V^A=D2lK;}>THx(%D69|_1^G5&OGa7Dn zwO^gK_5(IB>Q}v~|2Wfs(JPYH@7MP4W>xU~9=jn+OAz~muZFSK7)4zJN!M6X;AhwTeP)%P>*cl2 z+K$rO=g1 z%6b{n6_skJa-|k5Z3IhuX;wh0nJ}7|0DCS#nkfN?v?(}NNdThuIoJS1*96NKDaBzu z4$(1>YK$0Cw6ps>_ph9&)E4$rkfO;jSiB4ur><;aZo*00?`dBBd#$G8+5tj?@01Wj z5ax}%Iq(3Jdl@W+C?KPJ-!6yHpD>2;%>!(H9>9>zG6CZ;gJFVLy3A)nRv6(A$>u&W zyg_@8LkM%j&2QP|_)N66(`bD-l`e^`PIoOYEv9=fitmVUL}wCrPww~trMLJq;@ z(o=^$O8FH%xP||~DQOLUHp|_xgX`_Vp3>F)ucf!!y zRpN<>b;kJ^8|4NFo^V21E@|N`SI>!xZ|Xq7Idt4chF&At^GaU;WI&t0woM7VXMpqp zNUzW>ENnO6i9dFXp3!5ZnO$L3oZt%r+9iFIfu68u$bLmZ!H@60-8(HDe8j-B2CU( zs`=mC$@B2FgNM&&v~0RqWKGvFYozhwHB~B$47$mg27g3p;`p8X@rF6Q$T|jD*X=I0 zZ1=lOZbzmJKnC7JR+;Q8!ykF9ynOFo&^P1Kc}?IDW}m#O(^!N_fxc=4_BR;lC-9%2 z;Ai=#juzc)`!@@@U5q5;t^|DL0S`Z&ppBUk%vKZx&!j9Lp)hb)J26Mygs^Bp_Y23i z0|Rd0fjFKtZdGH1Rjo@P)A46w4`=JshLoEgI)r76stj-5rVi~B23?|W%E6VtIJ?2jP$zGs%xJJtH##=>~R zIh|1S)b?x8=|0|^PHgA*BQ`6AzY~Gx^Rnr5_I@uy&G)O*34QbR3FYr;nP$7#5YPhy z8d+Rz(*Io4)n;JV*$L2V5;QkUjcAb6OTATfM?tsd#X$vax89%;6{_>v9bUQ9DdhG% zy<^m9v(M~jv*W#_%<8Wbsa-`QwJGChSMWeU-YDJtz7Iqs?zgufXPplSf zaX?j;PqVJMlDE7oxmq!@FO`0iIz^deSyz28(x>(jUbX+KRzT(?3k1|d7!3;OQm-Ur z$mlZ{Vs9TNSd2I+c`gP|$_-KOd5TdKTaWmP&wP6p>ZpqG)IF667vtVBbfI?)ilKL= zIX`tFRp#vSfIW`}3>RM1B?eEV*O8n8_cSqlD&MGm{$B zdQB!NSW1KKhom&XTQ7L1G7=iprbG8KUCncuu1}jYK^F_hc&*HaR1y<^E)I&Q3ONzS zW}bnXNbFIoEZ}Doy9&r^&jzcBLwQw^;|>yZ^ms8EUI!BC)Q&57=V>krP|Dn*!)@GJ z%WvbdG%X@@S5`R@H6ZE7MG5Qhsd!uxl0hM>!s&5YtP16>mYzZ7j-poyy(lv(OVZ5O z)Rl@vJONTR(~J;ZK@K^~72}N4+AwSvaPw+y8nbgYf;6rn#6BDKX{8uF&{{)?F{;azsdEyCH^el+n$)c$zJDY~tLzpW zwq<28rY7i}4qbX5`7(z=Xl8DIRR^#nQJE82IamFB1 zLQ~EvvvRiHt6;n(pB>hww3x!!$2nU){iB_&YW>3wRx=L+J_^_%V9liR{sD)+r+=_R zU)d`>1zJ{)H!v;TsEl+SO_Q*}E98D3Tjoq@{_e6YzxVEN=3#97KH6T~RztTNjaI>6 zKi$2Of1N##gD!iwf2Uqsp0^YtF?;v8(KQm2)f{brq|HmCXbryoF4ip?9FdicO;nA- zch}Skx2Pq~S(Dbx3=YH;e0>gQyFY#Ei9Rv-8@PkXT1h9(jWEe90k}Ow3o^(67TU6g zAly4LhSB%Cii5A~*+|EP0zT)cOQg0~_~gUSap`c@oqWN5IPpDe=nahb%}VTu4AxA# zblf-ch-r!CAJP0en?ZaoTa545wX@&HAaMewvPww{RV^*oNOxLD5s>?aaGieT5H3kD zi{C;my0&m2w`by5(dRKqdcDL^9_$-r=t7vF!q=PL1kw|_jlohc2tpd z#&oa=(?PVVhI<{&x_*4#>DP_V(69koi^VMkvjhEkcl@t6Mmn` zB;On z_31GFEDn-QvsHc+cxEd&{pIeW(1v}zDAd!h8-+@!WCz&U5A|AQ^!U_0)3eS{*E!f* zCXK_<0hJ2X67n6g05+K)*f{aRzDdH1|( zuF-C>9vT^O3VLQ7?E$ZrFB{bTXQiF2Jv=MtcJ@{~uJh|?Td%bcu-3M-9?N7O_ytm)_h&0*}c+#8jp>bubUW22s`>xYp$%Fit%hm#Yhln zta+VEPyeL@URZet*Gyh$BqD5|>FcMNS+IE%SaO1flXK^C&n)e(_Xvbp`y8q5C#B<= z!_>@P_|^XB1k>Y1aw)T5$!skIm!7^NY^DLaEd&hBzYr+R+&pu3QRNj81J(_CdW z$MJ)!cp2En$To~a95}7WwC$ADGw*1;2U-8FyH4kHDBS-Z;!bAAMv@zp2|eE>_K+22 zpEqSCKJ(~hyAr$3g`Ef9i%l8bbOy{83*%@rZS>G+r&+<5aUsJ_1~YcD(!IvO`NFj5 z$UVlCd!$+A+-1%(_Y)6Y|LUi=P zyk~m)V_V!m9=WIVa7tx@i)*E%2)x&^cDPNUW0{a(Lg*v^5~!QeJLZ~qaL1{c7oi=O zT~)XuS}W5-Px7Dh4%L&l#_6&ApLvY@IiYUaG6nakaK~BqmJGW%m<@%rCv<$xS z>9{oibXxxDw0s1orCM{dngoA3E&p^{+J%2QE&o%Tmi1vgna`H-bZ{&8oOmLrdi$vo zL4{~21SvF(kM46fLa`QFT#+Zdt2mSbih=bVD~@jH2=A zw@k^=>Qe3L53P1D3e-f0R~&xqw$5ne+~S`~aq#Fs{#b-|R}G-~HyJ!fwEB{MbI00A zicp>oTXRVN!+IYiy;nxvG~k7@-VL?fnYzEU6prFcN!yT4Blg58cpFam)j)z3Bh_t} zWxe8Q*Ho8Sp&gwFpV#deYaqQxCtjulGyCPK(I3hAQlM|zsG~9A_31|<(cDac+d{FW z30hshCMdCs6fDnQZ{MCb>!<~Xi~>TMr2=TNX4+^}cb-ap8I2Y!A~5>iEZ|1L)m0MP zG`?v)EsEVb5RyWYq8guxG-q=Qv|fu&%z@tnFNx4HGn!G)yXsG? z3ZKKW*z-Q5RjWnw@kHa3Q9K@65!M!Hm+*hM8pqzn6(K&Af7R(ngoE8kjY|>ueofWh})5FBE=B9 z(iiUID#C{{NHVxbPv9hps^yxgkdTW_GhH%#)Lazn|`9_Y4atHr$mi zbgx!HmKx(?y(bBlzjOD^0^mu@#OUmGqXJLy+3%gf-@URuChk>#p6zoDQqSk4<8kWE z2}0}nSK#T7v(|xo@S>$qhS1q3x+{wR#L=1z|a!(t2i%oZ}mbkayOQK7HNasoWYG~ayg7n zR?`8RdN|bK#);27Z_otmwU3}lP5az94Xm8dlS$)32+t1xF}9v*(jNHqBfS+CT=zqbq zD%YFm$YN}z4%6mtHp|H9fVM9RRH1pgN6?0|Rf3afJW-h#u<2k$Vg0pQw z8=aIbs77meL%Ku%he=i1jub{dl<+meQI%fLaPkNxbt zEl_qDdPW_(Tcvqhh@x0;fU2Gmsv<)Kj0lemJ`y%*S%(CF!;udMp)eFBiE`TzxUSZl`a;O@ zJ=Hz`+);mO{%)ZyP5#)5@_ZiNaaCrM$!ywQ#8;!wT3r`@8<`YYg5R+*%qn|ixO|2z zA0Rdauhk&Y(PN`_pGQcjP=;a`;*jq6FbRqJ>YiF>H42AYJ?Ksa49{B61~yvgCaN=X zm;5FS2u+$&VQarNyPB^v&86M6`C;CV$|%ICQ|)U`ko8_HY-zbyjG zeCGT#k1#1F`=LqU37!c}ipNYO6U-!|jm*Vv*4cq2(8H%k)=BZYVw=z1a)!C`hnp2U zYqWUZ8FaCmc@B9q3YwEh&L2JkCoMSuUvEM^c+Q}f*sfl9JL(18HVVIC#d(8|RlJ}keA0NYzeDE};DgH9f-Zr+FwvD-4hNH1^r%oLM z1%5O39L^Q}i3tlV#FM%^XsjAd8(AqcHIKgQyk~YZ3di9`i_v;h>K+?Eo&!=b#!i!{ zY6#ybk9D;Rm=h=S9L1?l9rCObw(Xs->_z#u9NKd|??AzunlaeLgTe2$UR!Yk z;@oj@9WO=tUMrTDma!FuaOh;Vm_$qT^bvhrCXMVS7V7}9HZ01@4)O2?lN9WrLl-0) z!P#PJaA!Ar_?iXWu;?qBe&^wA8KNGJ@yXCV&oe%vleOt`achWRvzGcavHv|76H`w- zpxy0NRZvN{MC&D5r?Vl?I0pD(A0feEJ3>hcyFvk4R^R38;oUNf{_EFe4=dqt#jG2P zn$)=Z$m^j`vR_2wRg559Bb=g{5=~KVmj}3dNDrfMUFq0qlG*!;=svxAU_R>3Yir?0 zI%?BPn%ZwHevB@Obe$xty|8Xt!rnnF9Cq@yr-i=pBOTjjz|VLBK{f_gXp9n@mSC@) zom~K9Xp~9_n+pH2utDsPLPvY4aBe$jyQ{$sJNGa{?$5f%{*e2myojUWZGBoM z!~8LZ2qrp5%*od(*UPHC^)y0!7+-#vCtf^K5f^|D9!zj`+`>n(AomiR3)%YqR#*A#$MMoxbnq-|lxnyBP6aoYy5(S=( z)Op{�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%0AejP_q6(Kba&%MRLzgUj~ z-!h%sa>kKup$bUQ%|KNm#(Sp<9K^xD9`w({>K5U8eY0SBjcgt`H(g|DyrZ&13EY4{ zQ#r)SRV`_-QN~STnp^`8PK$3uW-_`8ChE9Z+-+(7vUb%6@}(M}K82m+pNIq`TM?_p z_{%yQK#R1LBDA-H!4*T~z?SS!;cGd2TH7-l1ly+4WjE`1Q>_VK$?gH)PD{+b+f{W? zOYrwfPtz5T#YqE|s#BkDvT%9oZH#2v2y>R?Pj?ynjGOoz=}Hfi`;aOJM{5);fbcfgm5Dtapsqa<3qO_CKhCSWkTN`9@0yTnrJW_)vdHqt`ekBbp|zbiM9%954wL?mhFNksUD$7$BvscS(mI(PO? z5R-l^ulf1N2Dr=**jn$ZZLDqN?x`L9s!5xp`&VpLMm~yuM-(Sb55yx!?u&`(-r>;> zFUJm(F9cwawMEpBWiNYXp(C&2o&6SN@8a$+sd>yc=A^tb6*!Gm9AV2MU8_X^s}Lwc z9$HQUEa|{SEdoTKxmAMj3lGsh2s#_MdP)H?E7&Di;r%aMxQiiTV?)i{57hDrqh`0{bhr>{J*glD+2m&S}_FN!#ukLj@n#Kf%`)6g4?`_FzpTS4~)?#=Q}n*o6UR zcY8KrHhG{G#dq>)%{q{rc#rXXQpCo9W+>h%Ha6!TR%bh<(~fMF8p|<}1ysm`<$dy^ z!DQ6)TVljs+UOXD2a|kii=(x=UoRwn!)m%pVJNvJl0g1lunbHg;(|t5ahC5Gr?CDE zfu9^BogRrEloCTCx60m6R-fXhrb7%c-eyM}#_pQA@i7Fi?&TE$9(j7ViIlt(64IX_!*+U#;c%qqXWMROs!2^SOd5j_6!8VuVI0$)W2~A^q67366xb*HQb|hb9RcVKQI_uIZ(*vB-j`w&|3m%CBG%OJ5@AwIdpmjlFzbi%Nvf6 zUKcH~bO!z_wf6rjwS?SBzPJ@-0QQ4?84NyM+tT2{(pqy25jHqV!32L{>z_Z6IRq|N zZULEz|9?6y9NnSBjuN$hoYvlt)0$=q2-YU+Ua=`HI)-G>!^L)XZT{=*3r=N!J}e{U z0a<0E+(c_uynar;Tkdu^%6M7IB?c%A@B2(X3fVA9V+M|~u&fx+3bEH+3xiHr>C%)? zBP|n3jc&h@k}I!|M#}Y&tg{($EsW9rkJ1|Qz(|Lh?E_{LlIw^8&#BAA8LeD_)=0mV z@wTA^r-X;KPFeI=X8F~cPg7w?a)iFM3#a?|0Tw01D|(`%Pg;jk0NC&-JQZbJ7dJ?s z&p~@YSF_c5}h4uF;;5@C8eQVO&G-hCJ@9ba;r%&1%*91X%R@X8z`=2 zuHgGe^cQg6Y?qc|NcDd8x~_)#`=AQKYMyR=3$i>62C!u@g{i|aSL#4v`@CkWJ@=R) z$=`G|E6;Yd3>fVjv=t!Ptel4n*B_g8_HLqZ1pH=7lk5&|2IL*avCB=CKhTki%y9KP zGJC^A(oPNhNat`2+BJoZfo-;$fKQEQ4wZ&+j+ zC4^m3(iRx%*+xI4mg}&)MV2nZSf{P}c5kwru9c##l^^v0d~H=z;e|zF^K2J9>W`Ns z8t~ty{&|L&~zBEG@O1Ltfu0#Hx-<_6@ogoG^YjOlzX&u(mC`6>~40);Rc$L;1q zGFenMma+!x*x?j03m)+jqBMqPulJh5hhh3bPg%(q>5Z~!^41_0M6M4}ZPFTWHf*?^a2OQTf~I4Z?0)?!wv4F++U1QBUlbJ*L+C--&A)&UxH$Lf?LhW}|x(bvTR5X$D>Hn&%B*`~z1y z$1s&$hpktGr++6TzrF%WXL$suB)Mv$+K&At?r=;DPZ;DN@Zv}}rR zhlLhwmI;eDl|Bk|4%>EQA$R%R7AwO};S*&VcPCH9T2nb7&-jtDAW6wUPQ_?f0B4$4 zP4C*|Cre0sL*@-5|A{0KQHw0e$2;`EP+^-ks$eLElz~AVf!3g5&^~zR-xynmPhzPO z)tYk=614K90$_0Z4SIvXqiP@Obx|k3WSld$eqA&Jgu2tVA|7Pe9yy-f)^&^4&#l3`0P%^FEs1T`J0 z@`9k3C_6a{g7yWd`6PvL&S%zm_>0SvR1Jw8^QQ~_zy+WJ-cJO{__-7DoMr+B|k>UOLZd^EpSmU!h1A_CvGf-zG&ru=#0{Vnm#h@ z%Aj4z_z`1mYwWhQ#xY!F=I!uIrBJgb^X!5s%_^I7Nh75b*8?$g%3m6uIpTcpfH32s zL*`Dmk(v{cXC|j%+mHN-(`d)|LXM1Gj5+lfzZf1pkUx;Bp%^q&qz(TVnjwcFtHb`6 zhN{2Px3RBA65{9OAu-? z?coCFZP>WZp{A7n0=b13HI)!VX_DS+AzjZo)fSoM5$i%lw^dCnNhi&$DrwrRIJV1@`f<#0E zT|=;+A89$7K5ey^_8MZ=9g#P{zkdx{KztSzQ8-ty%DPW%WWN8!eG1h}JzXk^orCn< zy+;vGt5_{aR`h1cGmTg_b#RkAX}E^o=G_?_`pjk@1-`4mTuf&3LWGLT>99zX53J%G zyo1AdZCz8DnmiH>ROlPTbV3P2w%Oh+=~r`&&{b($?T*n{@{D)}!K*86+l$jwlBjle!}fCzI<`RZ8I~Z!Dw%TrJ)*Y_X0kLn zo{4=er$Lwt5}HaIsa&X%Db+RRrky}HWyG9S&ypX0!ZmZ=mo41vB|e)pP# zIBA?Ul{!dJ1jsxsczA9iSj+s!k$fNG2WVQPcKOF+@ko9EZQz* zBKwg26W0A*ugl-K7ue0s`U6`M^BWReUYGlqmswL;%i9Xaxh^lRC0oH8kF|$bqk<+o zHWydcE^u1k?6yrY?ub+(Ld{wsKXJpX<-NVHylp%*T02;$#_!^$5bq&$cD>9skQ(p7pwhaC0C6hL~P8Y4(#r5H8rJlY?L@NXqJ@v#O~GV?fb2*eAV zZrdbWWP^2bWN_9PrcS~;nuc=rN^j;N4u9=zJkJU+$tzb-W#zX+Y~KZ( zaDP^>djsT)Oxc49I75AF>a7Gabt{8ns0Lcx<@0aiJ6*F+qoL;I+@$C?F!C%wzJ!GqFu zdfCT@61e5f$gc)nTK6aC7+faH>TVOrQxWfh*egE{B$X8h%G`g!_6DhX~K)HeC7 zTJ~IFcLnpkcW70fE&Wh~b)a`M2CZVawp>oE&So$LcwW$fnS@-$N;rR8=e01vUDZ-6 zLS2&H5`E|;KsyKPtPpId!F+@k?bd;C0~CW6_bB;LIkzL2)=>XDGC1pz2KpI}4xzj- zN>z(~qi0{P%Yg<)Y2mzT;w0r>rWr>m#@E}3!b9u_Y`K7y5-?2eLhk9KJ$4@a>v~Mi zv^z1)T?R0?Z(Q&Egxg14E!4}W5WL5PU`qS~L0G@yTaJ9J5DxQ_^tw>wHDL=ru3e$w zuw%&ct;(@(!>clSfP$}oI(Resw^ASod$0u7<1(jFW7sdG0P`b2Y_ZWA6W}z_(RqUI z$9@nUE7~vLzPQ->GIsj0eNyc22e>XeqaZ^2yy9Vl-T1>EK*f#0-3}FUmkT@+fC{e8=OxrWdO?goCDKRzu z8gJ1xLO9rT?PRH)7ib9)%d(ZN^tO-Gi;#a) z-8Rz#w18dF7@l3^TFPNN!xr4lpr98*LZIm_SEuL@FaKQ)~?n&fR) z6QL?5Ov^4*zcucIEW|V|cr+M9y9Mj@inUo!CO6q!23==7tUC|wPQMv z@$WCVP`h^x05;X%+wRya*uKzK+3g1G`{#1d&`wW;eH0~vTowbps{vy>^p=99#Ra&n zJ4t;OE!Zdle5SDgZ9chzY&3@j2DVgK1yhET?SD_CuO~QrgD&5bb}q7 zE34S-)eMsJJc`9@80!rCu!%7yIZX!YPZ_vv))QPSnQ~Umg@&maX4pXsU|MW6Ym7_j zVhzp{PB)rY+lx4U52)r?H}wvK!kmz3QT)kAJe6@+Iqr%CD&^+1GDFFE3ufitUk2I+EVjj#dv6C$AiuDOddzuUtdydg7ld-FNy9EZB-f2% zwc_(y<)x2}v8~4^KIw~@cb?QU4MJ_4FJ$LG45`fU@1Wu{vO1@2VAja{qHhZhj-1bb zNsJL%B#ZPz2a2b11?ABy@ZTVJGgr17Z+II3!u7j!?7_)!ei;O0*hN~F8#D2o(yTE< zPMFDpu1p)#>*V;RvyQZXRBno*wD%~a86C=7XG8>k9-&hN9N%*a;Pk(<{OGxE(%b*` z`Q9cy9DZ}jI8|5NgTkWkyx#op~!}xKc+4Sk&=J-sFji zGj9ZA#iw3@E*qGhxs*B_qUMZMH>Xkvl;MdyEA7 zzJ+y2)C%OVZXBW7ELpz7$9s70y0^^z`tqRmopH5js6dv_zrt*viYysDPaBH=Vx9sQQ#CF|Ng;R~K-b{hk z#C(n{t1(2@?&))5~9^-qc1W%~L)`lS3! z0%SIS*}0osy5Xnt^JuEkU#D!;1kX#t_eiP)q74H;q?l(u-&=_`i~h&9XJL$jTLs@# zU!W9yPQROOYLV~WEzkrz-=FZ@?qAJ%H*xzkWI*TikFY9je@f9eM%Q5N3R0~qp{wX4 z49f%4Q2zIp9uHg<#MDSc5&7Geo~$qHCjE~^Kx?!G_*3^x-4&6rV9SFY6jR}-anI_z zZah{Lrn*sZC zA~9mglge73!e7$h0i9ZUx{^nEt_+7l{3a7nag$}y<@}{k&`H?ta9|Q9LQ4*3ung-h z7jKDie_8>@F}6K@MvHlDt;g&wPhUE3SY`MjZZ$$kKZs^9S>8c2CuKvnBGFZ`P@NjF z1djaI!vFjx#a~;uONV=C5SkGHl(7HwyqQWMBSp;r>Kk+q*uA?Alo)z<;W|C?0n&oR zK#&f5M#0q2THm-iUZckXKG%p|xAXrjh{$wFk$KFFQcxNr!C!F>fYUox zUL(~C8v^^J=0uP3-H@duT??%{tmHG6+}}xSSBim*-4o1pC3Z#=_Z@->^p#6TD5jP3 z4eHgHM3DxG3FvGusD|DAatG-GWcc-5qh7SDU2-%JoOKBT^8wKVFW4&lO;GpMoN(EB8hI};PODS(e z&3h$R<@fjLj4bOOOgkhDcwgp>9E;kYVgH_!0LoXa&U2$rU0qUl?=J0NQ;)U2hGxlK zM4>Gu@YCJQM~Mnpv@9}dM~tt_6**+G`xQC7Pn?h#sTRkRlpDI(x`Wu1!PX;nrodvT9Zu;QK0!eJK78}++-C+0c2zp zXrLGiQ|J!Wo~6doJ&e$$zhxZ7=t*ZiDU%=X8@85Sa*8qCwy-b$Eijm)sxUH@Q`U)^ z(-feI{S*ll0rnHYYV)_lu;B1IkREF#v;fQ2k4&Y~TR6-+8U!H~;g8GlOA%TG@pZMe zIW+5^G<%BLj8Wj}$VPyR(`t*eaSKWGWv77BInP#63UR69cnxAl9BUcr*;H30XNB&Zy-AAQQ~du9=BH{!kv-A!#xU{hpZSL->StM~O8Cg1qFN z@ZdOnW&l^B7M#$?CtazT5p6de&qt3@X2hw^P6$@CJDJAY0CNeMS)v>gOavZm&E9RL=T;66u2E3kf8XYIVUW(6aiCFsp|xLa1Cu((M65po*D z8cm4XZ;77y>y1Qt34x>b7~_4-nJ$J|EUR4llhHyydEHClfhW}(kMVOH0z1w~bUl%&a|x*uZXV9E4YlfzJ^Rh{cp=#=%Q%8LsN8@mq0lj3XoWEm21*blTi;?XvI( z9BL@&j0wmMTh7Q|Smt|m4Jv`~#|`AK3xkP7kU_$Kx=9pFHU@M;d3r0q{Ki2M5z(jV z<1fET@hA3S+D|G3zWUhTtNLBh6gE9Ej=g6v@)JSGnuYPNSL@`4&=04A>{$|UG(u@e z3Y*Rq)R;=VG21V*0$fRmQ~4l7Tm%_=Zt^l0Cc?wZR!FhmGOn#v^0yPB*9U}=Mu;q7 zB+`7poHNoiYF3X~0&7ikdK%=$8wbE=5iS;taw2{Hqepgwte#$ze0b|;{`ksD^PXkdw@SZm_={DizIeHDo;&p1M7g-Zn;>Bch!RpR|#!a}oQZ+w3hMf*xZ&yHjo z%8bc}LXq+4Rod-39}_OpaZF0gv=(ZW^eA~gK>diFs-oaw9gN-F1J;t)MqS>_j}K|L zrk(i8I{vAS)r&E{v&>xmlo8iL`PTe$$l6!)=CMo4H+!fXIrY{J&=hM=#ll0tUVD~h zHJApKRRXq9GNyiM7%UOHR842KwrS>B#Fhb+`CWT%T^S=sr^%r1vN3)^(ywBAteg9T z49ET=7kWZf7O$eeM|c31jEB(x#{?;^!){}Nb+>C&bC(&8^~1{{&YILecMu(=1jQ2g zQBo}IYR5CLk;+^_^rd5CL%$|KmWYY{#@d8GFx|vfcK6OAB@(Wbaix+0GF$(A5B~{Z z(bNB!2HBPt+k_n9lHXrf@8`jY_fH|1e=)}w2h^#wVit4=H+D||AA^DX-3?X?MpyZGQ5Lfyo#0q4YMMiVT&(onIHT*lfL^{f) zyBuRr2KrzYF)2ICamN+ zl`|;yw(Uq?!kni2FD$XULC!jFC}CtWYK`x%!H)MLop~$#X3OK5w}O*5ku)4FQvxUS zr_$-gyS&R^+bWnn;A=*t!^)W)(hr8c7hV(H(su^Q2m1#?ylu6fEbC-i0%gUmP|%O? zOc_K3&I^r+=gqvxuiJfTV}gHKw1bui90nB(l3 zvx~d5qB$O3M_PlMnji{l&0!dYLeE~ySN+KfD z=;u6k#-1Kl9#)du!MGY3r-}2Fe3UOdAk#huhV{s1& zn^*YGa+RT_p{AXttDK^%&Yytxht$ICWaC&qKGkKea$b!uVjq!H=|14oj;tbxQYZ#z zkaa}I+owpCskt`;}qlyk&Eb^F2eqW|KLPbPQAgk0A{)mAv0z!nj@q!PyWIPu=%&jO>VtaAvoZ)n^9BZmW_ zTVn8Oe1zffxaZEzufD3hYbBR>X35FmWa9nsio|7VU#!@3?zkI39%L=s==S$FwD8=)^cQlkUS zUEF+$VgGL1MQn4zS$uEJQ68nYITC1Bxf&5{M{#u5%Uo)P>2~$ybCff>@o-dV#a2xW zrs$`w)O$Bbpy>HZwlSFxD@`QIAjmB>gWe>5i#o$hGQ<$vrzQPPh}FQZwtsz5HEpVv zkdJ4CcL{|bECv(ytcw3jkYTy1ts2De6Q!{@MR3{qrmAkqblCShKH8wd^!UQPw1v2^ zjz>++!1>_eFcVMJ+G7F(sEIC-61Ay&N08+3u%Z{!Bup3}FNG&C$)7@=U>w-yP_3Cg z*^moQ3Me7Q?%;%D8E zRg3&fbuQTJlA->gIwcgSe%yZytG|Zo8GQ2Q+F;WvR<<3XREWGJARA12zra%L-5(dO z`&4)wcy&Z6Q`8V9hh)aIqU4i3<}Sn`lb%D*>qr*&&*Z<{(tNj5rRyi=K%k)|vow%F zWO7JX5bfB$S{fXj7d^e~7uPm-Hnu%X9s(54zp|KQ(mZtcScN@;^KvD)n|I^xK@+d3 zN&Zni%|=00X@|p>=)P12Jl559LGCd-lJU8UeT#@fl`ZsORqYyXorl+#|HhZ5 z|Lz&AqMm&YEYI!naoO!v4A|^Q)n=ar+PGX}A6l=)wL0J)STQJR>gv zK+jHB4k-Wc;iUsWqTUY7Knb@Ruq~#gS|v9u|G5bg)~*+uEUkE{4D|j!DL` zbG>Mn_x2*}jpgN@yPMju8y6J&sSYpOD)7>Y;~&uD1<5lCwogrQ3`*ToIYi+=(zO4} zYX*6PZ~vg82{I5B`hqFxKcFWxM5ohgWIXmhzKf9(hDn&lr9+VmBG#Pq_cK!anuXzg zC49_k?WAW{Y!T+p;7W1*nL9UgN8$9nq2WY%woo7|TVT2xPY=UoYz*QyF(wEwWuIcC z`zVvH6R=_N5PkkDO(SpV|D}2&|4-F3%>S?Ii8F%2W*YvVs;9%~?NdVNpXSoxw$G!` z%Da}09b2QeGpaC8>)^xk4B*fo2KAbRSLjZEnB^M;E<{aG^l95b^`KVLAtj!P3K<4k zmk2pvUVf$;oc716*KD7}SNUz92)ymG8UUrAi@lk>3wqik`{?)b0yB>6c`_;>rs}&l zu=nwdcr5eZIjPx9^|--9-2pL`!vI!&A+@(<2qm-TXUEt^d5EqO_eMtZ9ghDgFHsPo z7yp!(u=szwwgJ&a0YXONNxD(6JVTg2;10FF7`hOM_{X?fVZ4JUKk zxGptR3ujfzy~mc7J5H3yf~~lFAVY1p!8S8TV2zg-V6TY}2XIo@F6(%gL&4z?CacaH z-zOxMT4*wwwQ+g&o*&j@j}*o4Zki0_KV(XSO!cElNpCacgjxqWPswJj>UeraU8^ou zR}WCPE*{@`{Vi$yp~A$hCEv@e;kjL-+pXa<`PgBOv^C-9PsNQQFSmVpDC!ts>ar6Q zc@{)Fh+bQ2aSTfs!}PfycXgT4f+As)Y+whj{!B?5`ktfuiL!vQH;bsdEX$s_Lm4%0 zTeHfwtBd5k-R>rN)5v2rQXVDMTVM26Lu$(#Pys~&g~X`IIiGH+!#+Cw0YVX=!gvp@ zoDgj=w##22l9!3{G?JSNO;5%DI>h&-sD*ka_;9|Z1--3ab?-8;o6SB?TiMlt`>O*x zAJJ6NjHZONkDr&I0Gd05cMc+(4R*Q9T$f5%=-YRAlvb>AOQusy=v52(^1mo zmJ*HRq<~iM%KOljG@txLu{aVLz*P&Y6+~~mNW}N&GEo&msUY@n*EQ|!6v`YQqmLBH zPV=_Yid5;$U_^yTH}=MDdDiJtL}ELy(v8+duS@gxCG3z3*$1T_?_Efxh|Se-7x^W( z?%!-@d>@@v11r{ZJ5z&d7z=bI$fGoR*0JN2WYrh|tIvd)AEFIUkS&8$s~;4^GRzH7+r_}{k7VaK z2LZm%o>bSebbZ`QUGw5_tMaO^VjkTY(KAe$bdk+84nk!iPOi;xa1DAM`Ug`2>phKk zgCbT%h1UJTYf~S0j+}vN0ezUDQv@TC<|i%BY#rXNvI$B;8WyzeY?A=^_m2qp;4w%R zx3OM|L<%Qt4ZjbVKzhSO&tS}25sW}*@E9FQb-)4zIg(ZtDd%Ch{V116bvP-3e5l0 zF9KZhvp3I*V&nSw=@Y4a#rD8K-#)8+nvBl9c0xFviKAlfzU>EX(E4Mj9X zYf{BK&}74en=5&5aQywf)5~WE-~18-{52E&;x_qh9sb)bW>7D#mBja!6Ao_u@623v zZ=V1hN4${VQ*9Uc?{%!s`lly4u1@caloStck&l52ZqC2GViX_ma9?pn?t*WkDB|CJ zRDVWYvaS&2{JDm*BG5j(AfxbXAlC`LY|Z+6;L-8dZP97RyT+#1 zK%XYvp?*n@LE+trj8&dQzuz=B7}q#cKe3817Zv4F{mEmO-18w96sYdiYGr-XVP!t0 zgi2(Qm`MX!g*-_)%~Ds}V*>UZ{q3a&ROEu~=HJj1g^j1GIe9+2mp5vKWyCUJ?=qaQ z_-Fm}v{ERpfWwT@RUQscyERcux(mY=0193Z1|8V(LKUE3#W=vQNuf1H!9YF*-;;Yo zL>mbhSQ|YZ>cyf4{#j9lF{Vd%peD8)W)4yD=j;ukSAOP`9-aRwd9%VulGbcFX#B8m zEog#ds7RBG(I`GDxAQ7@aa#v{+h8Bet z{Z51%eBJ_!JPy{c-#AhvdXrROU|%2k*qp?;el1ZLketOBU<4&|dYeZ(tj|AQm(6G<<{2}>}^HiAs=H35kc%NlwV zEul?SgfnB~=apkzX7bX(Hw=sjoe-9Kb#c1Hs5QsB0$2iUA;y~iN`{Uv^{L4O)}Ir) zXw=|7 z)l8dcMvob^I~IV@lWF{2Z503Ls?Hi-_Cn>H41orIf;vN&paEI;13|S}YpPbT^pf?2 zgNA?P83kpNbLnB+Iv(mL6N-(-+YwmlrM~oknY}6O%pWnA17ssc*!t-~BI!2|H8;n9 zkRhr+d;`&%gN9=iffyA6>iRK(4yDU9#wJ7%FB>i_BMYS1Y|&*>dVac$5E?HGf-R#T z7DkwuNc4;+rD$JkWL>ysSts^H`Uk6Au9rtuZVEV#VV@9n;Wu$fQ5z2tc4&^!48F^L z*s;LvlUogwE&-fM$xEFR?E%z!io{FRxRI<;p{YC|AAISe|XjBKg0gvVnH95O??xisTU72{c|WUJ-lL%l|K!UzF&vD8ZW_1 zj;G16fK}?Gvgt`xG%3%UlJ+8?>UsT9`j;ZKjTtrs=qr$Na?iFD>4>^xvhHl(TccaA zI}nGs&j)cRsua8^lV}r%Eu$8JWxJ;`kv;e?7D_x@(RP9269o97^aZ4{=QVcu?k_4H zTKrcOx4a}qiFSRnzep;FT@9s+EErpvYLj^%A<27GoAdcT{eM-Cs?UuZBOFRt=}5D- zGrIe*9VL@p#|=RHnjW=t%e~ax4EU_f$#kDUS`BF69LadhcCq%V+}gz2tO0?I((ET! zAVSl7AzNjIrVN9&Oy{l)EY)OK$;=~xf+EVJ9I^VS$;cfFhpKWJ#$}RbfkX(Lv=?E5 z)b~%cf4vWi!ucFwE_M#enQpZnq}4u=hU5^@+%PKPY&7$M$~f7Qe|U6v56?YXcl+l*JHPKz94U>#-7{+2j;v^v61FqMsL|NN9CM`XAb0I zUbQA|=`nS1QKlK&1xZ=*vHZ`5l#$rKwk*!)$CmLW*!e8}i_4seYyQDy8_#!W&k|!U z1tzT@xmr{;+~$Gd%rFJ)^+fP+^o~%&+#GjyN9iJ6&9~4>^;@UvnEs0U-2wUs&{j9` z{!QqMe>xne47!T#Ue*BOBYzESRS{LOtOSm%cxl>qe}eH5%tcq1@z$!H_;s}-tT{wR z-veAc(_aKgmluK>)?_7``z;086@vCp(y2jJK*Lv{sCEMv?b`MypF*VXRFB(F#f7Zk zS8~*8@m564CK-NII-D;-O5flUKuX$ORf^*AI|Zllxh$Vv^rkw-P>)LeeUo4w>K+7X ze=64|BfSX*mqxDD<-Lfqzh#N70h`@=qQhWE0Won=2o~95=QEqgPV6YaH>$o0o!A_Z z3FkJ?NVYw}*+hqDhNQ^PL}qv<3fxJYIm10E+~qpW?00Bt)tPZ$&5N>S%Yh@~;#mcG zZlSESdXVZ23~x0$(}FAHvi4Vzy7h#lqD%j&OkGArHZ|?s<)}9i4Cai@uaCowy~RlQiIQ~Gq;y9| zZx}Pe4%^?p8iL>#f@{~u05>tj7yl?J^B^21!v12}R*_+O=WjDKk^@e~KSE z6Q_h_e1eJA6vr#-$9FtBQ#IdhZ$rmDqjv|{8+iB-Y0$l2oGet=YXJe4mRl9Yk=e!E zY4}QI;o#FU8@vAfL1^A3A&)X8Jj9dyz87EljE&255WLd^UbB;!gw%^PX@U%Fvd|HR zJw0iKnbDP}dn=wed$ez?IcY|*@H@ikdQ05S)l6f+PxUod5`*LYZ#ENDdXx27Ya(h~ z5NIjaXv8Ty@^QKT@dj)t6}XN8z^^+F%?kg(-a&IJ?@qzF4+$lqp}Eg|Jyyiu1`ipk z-R9xG>%ustxXDZ~baZ*yN^?H@!VPpI`skr$_+->>9F`@$Q7Q*!F-F_u==;mdc`i${ zcdkig%A00k8(L5I2=PSwGSG{l;jNVnVdnBcP7 zk){n{!x2d)4Vl(~Ss31E#yag?x5z+WFST)HBcvDE&IXwwSpCvody@CvvQz7>QJ*(!)p(=QzgE6A_!GyS{fwXa;6vOWf-8x9FXHpqc6|6GrydA zhu~8(p&^}-iW+I3kfrla#KHL0Le0Wm=LPEo4J~ePKSpt2KSyg0x9M3VjYb=Pns6-( z=tR8TR&OehhIeVpJKk&f>95|0j5BB(hXvkqiWWWjAv`w)dtcSNwV}c32T@Z>mzr1a zvAX`V9DQkh(cH&1zh>SNv(wBO^4>vHYxK5?t!7vLuFz&TehK6@=7!GH#|kpq_U$10 zJ9F+gI@8-e@r7(Zf!c_jfvl_f@67z~6D4Lh2MPqOUdqYskgBJztBz$=Gb1ObZ};oc zh6d1vCxs}KjE*$mEImy+lCPMSI;d99AdQ{5+Q9&9*1?D)6IKbYQ(~XF#B1NOk;R~% zGsCiAOHT+ou0z9+(2NDcc)h1@Snz{&$)DDsq|n!0lI52p*z!dC>uP6Z+o?=`Ak*j1 z49dvX31G|bF;d;cC45J`dBOm^$#r>qZ`&vD&EJl9IuvT5iJ=2TBHQA-UT$at;f7rW zB{wgwWiTyyz&7j2L80w=jK7=jrZL*vm5*9cC47%qHimzNm06%VQ+B@kz3Cdz)EZ)a zZvsxkiaKQSJ40XUG%mx;`PN`@)Y;F7Ksb%8Rh>GkaXpK=zP5s=Cy8lvqO9Tl+~zwJ zNOtiSqE-`l@XV^!yAROqF*E+@JuC}=-yRJFAzVuY+NCA+yyz8C@D}7u{KW+BiTZ#>8QEVx0!=WQBzJm(r7g?hp<-_1TvuHwQ8U`ir@mrv^?! zuSb5zpx+O{y3U)il`*WUJ_22eVln0HgC6;;4tMO`_jDO7t4yifc^C5K5|v}Mt}5+j z!(sp0ZG-V3WsFA;<5*4Ovms8oxJTrb8Z`v*dLp83Tm2>R;(mnmmElJz1UGtSBEmKo zQ&m^j@NEGhH)^&I+1{pz?qZG{t2NO{9;;?FWGS5pQjb2CLz}~DK;3mHExYXTKgv4C z;82=y-6lIWcWm3XZQHh;9ox2T+qP}nc5?HbbN`*1nwqJpt{(j9p04Lz%j038l^3uH zOxVr;ADKV#FBeW}{*ibr7_Ta}C!21A?O=JqBVSWC`>EB-cb6h5=${47C zcT&lcofbU;qw|~HnI|dENA_|WU0+hNgbF61v|s}YUw^`>kELvYz+vBC1wM(=X`gj6 zFntltu0HuRfHIVze%j9574Jl$mSEW?3PHo?Nhzrx29*&((=(D#nuTw6mDET2J4fbZ z_qBHEjL65^f8Bxt?C`AwUq}?NGgOR<3)~+I0$wDzN7rDS_jlAd7w=2(@)we&nZUa_ zP(;I%gA@{0$sa&qp`HJuyaGIfSK%Mi#vc4aggvn!Taqk>UnhI_P?a4Z!VJHD4kOG~jjC)2G6J(#-jt>bimxIDA%_lsx zH)@?(RCevoit8h8>z!?2Z=!|V?mIE+mYY#^M;XidLRM=nxf*9$qJv;iZ&_hhuzUWx zZIH|V>uWM)*@lia2z|Q9_11_2Zjx>@(#jAZ_s1K6?>PjWX~%(5fyF?&xW@A{jJr9K z%lt|DLQsF;{kLY|QO!QdyL4i+jp=1$SL5sxYp#a$V2usOl~4n=%YhRq(>>03CgauT z?7B!HLSaZyeSJFvrkQ`c-trL;sZnq`38qu1M^I6zaP1vG4-DUsXh!c-Q)`oz=gO2C znBZ1d#TAe2f=qdM5HcN=pTt3-s8x%!P!C0MgkM!G(>`F)rb9sWV~|e;KgfmU?-cT&_iD9Qn9tY zwsUc5-D$0U%T{300_=);gXt*pm5~mg4!aU;r<_{&_uOlah;h&EjV(m_#Dt}jqpr=z z!Z3wHolvO<0xSFh7__p1o?`NQ<9Qng{`6#DaRb24|^N*tS$PW0pI&S(n2(F`N$p*781>$wsP zjLRn(v45rBoN)`i{$}@eJgt^tBP4|z*vI5XxPix2!2T;yR}MfU%|uT{V?AJz1rx{7 z8B&L;sDr&ya5+Ik!|CJe*ARfe-2j4RKeu3{_o~mICkn2KB`gA%jBS=WKP!EH*sFDT z3b5=51vGF?zaGh+7x?qn1!DU4al`!wF74WskR|{4Sa8Pw^!_QpjmyK>7*{1 z!T8jhsLHY@KCn-yIk!R`=?I@&lH@`gd2)Q9I8ye!sIwS=x-XlwNjhw|CzHr<0jlL; z0^p`Yo2A$XWZpDqFVa42<14JO_4SXvFkLN(U)SEKp)Bv*_nYLIOI&uzo~pPbOCOiW zHf6@SsJN;gHW6LULdbQAepM6Wx{x-Pm+0KP+4n;ECOw1D?eiKEe%^Wh5#M@GEgnog z%rbdjAT__hEhD<}A*RX(Ft1sG1#gnE_1#(aVzSL1+|O=6v2m%3-S48e@@duBa3%N5 zgK}nMtEoLHXY-tBqa6KK3MF;R#(~4XNxY}FRjt9IcILi9ks_Imr31B6Pn%xZ9(R(q znaq5)bJm-wWPLgkEjB1yAY!W(3MeeU< z^W^C1|I$X^!44kJH1rmQYx#{R!^=sdM|G*cvg+?lQ6OaiRpP}!y+VQ zCs;pA4V|pZLM-j{-@e_{q(td3jkp*2#q-WoP%Zy``ZvBvGrA8YXZ->w%R0<^=Y4bN z>zSan%t?k3Wmynsy>{?u0NbFJFqxV-unUT_{(vx&rbzr5S0}{Ax*o`npuKC^UFrB` z=HgSuimcWx(oVY90(oDRW=HQCyE!31T&;RY-xETMLAa$cR-VDvPWjE13UEcv42_*< zZUiuMMsU(|lp#F<>d9CvnhxeC-)8;0 zQ8}WWQ4j&{oYN0qp&#k<+ff++X1k)x)_cZsGkg!SEKs7g=V zg|{3`y)*-KY{%e#PfrHQkg457w5d{~U9&y3*ZjO`m14|`bJEttg$&joSg?2NJEx|XqVCg0lEbt=<2%ietC3U#}OsjGeVO@&;*gAd!tGz|;&9mM8`}tX0{- zejsqanam-jnVdTN2y8+*G9>(Z#+*zKEU4S!r&0JlT z4f;^9@8OrS)3Z8U2;*v!U$I!>C(=gz94vKa-yTvG4PVK@#@vzOjtreMJh)?9b*u1 zNR}PzH3UOUo!)N}Yh36BYdmlR`I~|^UG$~(+Z5%%HRcbU3%Gkk9L7&Af4wyzZyt(s zfW&2tMu#Xg*w<;;QgYmri8>u-c=(@?Z;?r@MiF&wj39cL(wd4U2uK z7`A)88C8(}TVXih6iKYumt~l7!_`ZWEb-t-RO`Ou25mICa1ZW0K-mM3gZugOX9<_0 zYOiL#sQjcUkyeag0j*A{Fj^d#MgEnfO)}8iNMNaIfyns6ZF{c6?uiyS$_)I>a>kxM zUlx)~e|^iRX+Rdt%4(SmY}AjfNw21ry};&VK;WJLPDsttvPRYT%c$qP8mnxm(XGVT zrRNS~=O!+;ACsCg85TG(zhm)c79l*?vEXa`h3;@|XG*05=F3SrBjdsKcwHC==?gSF z`w=a+;!*;LpRQrks((nYeSaQZO6 zrDKsZS>+v|GgU20huk(6zCjfB$T?|-M{9*dbMS;o6H>sk79_Wm`n#6fFSqIx0jwX6 z(gtB5dN3C~a(E}?=blmdqQC144=X+ax;4|`woKdL+;{WKM;$KplJqKbVMq z7$#Fg8sqr>@6d0Z4L>|qMe4Kfd)FhjfZT@KGmL|Lb(=#ae8HV7A7+xps+$bHyMzt8MDAZ+xgGjvoVBkFvE3SLbN2{IJ3CF43!r zl`Gd@9%@ZvMhL~woi_ZguBkYpHqW1V3exo*P?l-YQYasYK^w}dz$ zPpu?||Fl42&9h7d^p#OEEZMg{p25H*42vHXiYSbXB*CT-mmR*Y*h_;K55gwcG92R$ zmwl}VxHt72d79%QDN|%^ikDOo|Jhk1xp5Qb2h=RJB5#%-ZH;%lK1TL^pqw@U^GXoi zw2w8L$HS8xF9$L#`#>m(p3ldN@6yaOLveNb>+J(jDEG1Vt1C~TR-IlAZOg?CN6N6w z^jN_e>1cYM^9)`KBzR$61@hgmw$Dieb{z8|Js$MyxUuPYwZj8Rp~&DFFvTn|E7*Zr z=cYBlFVN^au!87|AhB80Y868hnq<^)$>iR9XF(Jfi=)A%T$q z<#KgrKn$MMw6HZ&2Z~;}QnGyRWPjCkC5&25v!taxcUm2Z8c6enku6hl*M-i@TTbgt$qA)uuD}Wv+4!+xl>w66yf$B^c zDNE!|ggry~W567RBZHur399bHr3e6m4u*Q-H7#SVmow#Ak^`q+*x;g`*AFRa-r0Ek z=~8v*(>RMcAXBXTlzm+zd<-1j4I*&rkA*x)vA+{g{>FfrZGy*B2>wGSE#^UGmNX(K z(;xHw2acV_@3S;&{ZkjqhgxT+^D%)~SOs;J3tHWn@d!|83(X+Lx#1B~_t0SpA^KBY zrni3ttUb^7UvX?eFfso5h***jK$?6@@)TIUz*6k5L+HL0^T7PXqUuF^2cem@UV3d$ z6T^Gk)7ur!(H~Vtu|8Fi=vMc>w;uicy2lAn-+0By*+kgStG#2ZjkCB9kx|lYM*!Gc zYik~V$n#O=WP&f!1>R91cWWxM#aTmRt*izn{? zbWZactJ*nG8z-Z?^&&k-*#6ZmUZHD(o?*nP<9&!g{wk2V&AmB74M2ux@BRoZ7 z#)7U-oYG!{&;B-?JtJx}@$&b}qZuZCv$KPtCXbJtql_~Mcg!BVQ$9kaYk3>^U{^(^ zuq0s1$4raAv3Nf?rk}1~W{uxB^kLeMX_bgmtY51P(kX!)te3o03_We7C(UM|vu#rV zhe*1dtn&Aah)p2H-RZR#2;pj|_C-w%x;OL)b@X>ci0lBr~pc#qRV_hGbKN zun*S$u&@!mcnN56$ep0y43{ylhXl=tev`Bc3$-@91x1r=$~U6~U@?kf+YB_+4B>1X z2v6#~hrsc6Mp-?t;iYGKH$mfkNrtSL5TCC?emetOkxe2B-XQa4t7F|U zyUw_sm0pGKqnbor8{b9}z4)%hIUdSGud5EB{?UP+vHNNfglQmcR)>LiNSY#4RlnaE zb7=lWHxG@49|qsOMnai#sQoU&Cpc70v39v9!FU#Q@@8_O3qmx1+p#Pg-H%_jEEythEU0XE^7=Q#Aj7nNK(MjRZnm;JPFQ=&)W*(y$|K=~sD{?T3{?p9 z0pYLECSdFvA>G?TP@!$L*;j4X6m8PU3voTWcBY$E3kL_^45{T0|YgZt@ zO>uT`_8$zBW415AjUuyv-XpYGMO7y(yGxkvo!`%==R`4wSo_hL&!8|WFkqXfg-i~4 ze4cJ^k-ADRMLo!&y|x!GvVrVs$fO*b0Q%BUxdn0_FZtZD1iGS=RedksMwOQ4;i$qRaBW3eB%rY1o74L9H*j4w zP0N*~t5t=rO~BTi#18{eY0q^5wj$pAN!mVjm^!~KS?0hsX5 z6q%Y+b|A2y(t)Apj%a`^ znebekloqULRuI@FX7HIP#PJ2vkw%ROnBF|&2K2qNwSMx8wZGkV$gcYDMXF{kh`| zNb$yw;5&)6C8}$(^2m1nXABfznBexLn9iV+y-gbnviiv8+T#+9?I2jHwr!v2emkj4 zC9S_oH=a5Tj-uIA35oxcMQ;pSia5cm?jok4B~+{V{JW~Uf@zea06%NR&|SO}TVF{X zt**eFABm-HwMGfbD0V`CUC(jG5K-~ef#$!dH|n{9ZJ$He57J{$s04nM~)`UaQWCY-b2_`^S2E%Qbfwat)*1 zhl~59#kYr%h$@QnUXAOr@Tu$7!iK0_}U6t)ov#;a7>>bxp+9 zKyyrMB)W^kSVqpkwO6Xja=FhUzjhu(p>dO|6Y_7*ySAlg>D&qnx9j?U^40>QIseCF zTM{=1yl$968S}p$+uT-nleqmeEbxT&EZE&89c@UE@wtW3hw1y59fG_xA5!jX;))74bZ%^K5F86P+4n%Y7@XZ?Q0z0-MsOmo1*^ zD^S3;y=;zQVcBug@YDqR;Pm{yg+BEZS#a@D znqAz_{J=+c!Lku7m@UODh-*r3VKm95%N-dSbhiVD6U%SpepTT7_wmk?ywadk!qN`n z6&~FO&4h6MTn`G_5OE$PoX+e~izNJq+ZFu1(`k-snIhwStnHP7 zW%n@498>=inr|J(__q>Zc+5mSrA7m>tTW|Pf_0AOe2;TF5M{gJ(A4VnnZo%^nMSej zMgr@S4qvT1P`NGqlHbh1l$7sn6y2oR4k@p~Vz{cjMT**+R0yX~!K#x-7>dP7O)LvM z{TVC)8$!cSLqlnQR)tZNTbgs+&gh@M^LT0HsajU31LiPt^E#PX*%jnPDcB8-WO``` z1m|^jpQ9#2%BD0(6HAb10w6o>fS)Xph0-&KatW8c=AtGhYA}9&db>8IvwX}9J{>B1 zlvV!*C}*rX>bVr~GNNvV#Yv!OU4!H~*99bE%pGC*|G*(BophcG%6`1%ykJNx$C9zUd74mV@?^_Eu+e4gDDr64s=mTadKZyy}{VA zsh$cPWR35mFR*@6On72;RS}n2K45Cf6%Ic_WwpBAMomO~p_4e;}I6WWy{?h@edR81k$A7HjDeb1SyIOJiy zCoqi2dRYpCu;_in?>zaumSo|GT{At`-dA#uBGuKaq+ogsSm?GRbkvo$iz$~X({32C)LvkwiyFRWaV%ZEW~y?Po< z7`k}1@v`q_h^3 zTrG%vtp+)Y>5dU9Y^Mr-C)t2x{snX%f))Nw6rs;a@G#z-(|g$@AG>mb+gv1JsnFjT zwft4P!TTg2-Q*tFi2fK6>N=g78|D0eT*UpoMvmXID;1Hwe4%7~7EcgYVM<_BP&ThN zMve(T0JEw<&H_;Z7{%OgXVby{7+|rX7SG*^3o}G17e!ljgx1LPlj^7HnT4>1X&##o zmV8F!CLZQsJ-ymwtf&Y0y(@s1&Gf5}l@8$5V`Z@UbO#+*xMp!?ecF!A0h>bia8-@d zysESgJ`O&Etg_1=onexr&vgxs+uwz&Uu|uoJzl|l6OSw7b;X;#{00PnD)D-tU7yv4 zMmpSj*Ws*GU`jlRUSC1BjDuYPU#{D5yhtF6eJ7mnKox2Yl9lnmzvTiAnPXa-QglLhm z`i*YAHP{5AZA!Q69R-A9wTaGJV`w1j>m_8bjuNiCIEa`NQ(Qax_VV5&0tRYMEa6~t z_?6ZEkxh&9`TBZESQG&aUajKtscb{Mu(JpVd0pW^+Sg0)if?}#rpqdjjZM-yqzdiX zteDCt>YBd}UVN@&|25r*-g4%Ws+s==7-X4OM_$Zo4;Of~F3CZ|*Y$)9w{Mcz!9IH1 zaB`y-wd8l!0zY)=Lg{CzP!YPISsowrtt!7nZNFJ8;-~0&HiKs9kTC5I@CDp76n-L% z>u{-{A%ahO!HJ=1*`OtHJx47+uh}9--U;1~#R1ro83rn?K4adzXl6|rN`^+2eZoxg z?x+*hf0uB?P+wZPCXZKC28E?08?f#itB#3y%*^Z~kZZY)f$y(bq3*-z;lBZ1W7Q<( zmphEdspr35=Vtj0d9%tm?^GLNRV!a6tx6=1cRSm9RXkCtFR`8mZB$usVro_`G3XM3 zZCVX!nfx&d3Alv<{RBwLIy=7RV^YU7+5ue4kV}hud%pJ# z<{nLx((0%M!~muf9^>~#miH$Zt;ol_^-zPtRklR()fl*bO^;}D_WuLay|3K;M}_0h zt;NXrJ-9ouhwjk_Q|G!5DWFg`-mcbyyYP(R=uL=wYZF9NWnpB;d= zxm!`8Utl3PTP_*+SYL%Ji-Rt>PFKSn0%9+p3prYCH~nVxtrlli&%*N9)!C6TM|ZPh zP<#|;C;Mqel}cC>b+5}d7G*CYqg;Orw%t4xLapZpBny+dL#y^Qv9ELO@ zy|3#K085*|sdg$h;wY&UtN~nn{&|r;1K>s7dzK)Oa)%iyIu4RM7H+@gd(461EfGQr0v~SqD(jwU}6pI+(;(+%C@n?DpEI_cLRt_MbuH z%RbHyjr@df{NN?t;)@IE?Vas?ePvKH+S(W-lDWZ1QD z(F)}yM_NcM!`IM{R6*P>ZYye4J1t1P>daKwyu|r9IdQTT!~HlpA@ISIJ^GphH?}-W zc9bTyHy!Sgd>p9J8ga6QSn~U8J}EV z=+<(I@JZ~pAb4PVrD}Habm1GrhE^OIntJh`4QP;fLA2J5aB>6AIM)Xv+^#xBMTpC1 zW-cmi!dTrdCiHID9*?#?6HadDCx@9JJFxYoiAj(?B52gWWNKsJv+nn>BYSHtJRpKAmh+WyZ+!~@{a~Pih$V(!{u3fJGpLO$4S$-)@i!w zyHNZgp{_Ol1b8-}mjaFlxIs@D=8WqpmDKZ`Yl$XRR(rQel4bi{z$z|A@#G{*q|;>G zzMGQni_;lWJPa5b0hrkVnAGiE+}BQPUmUC6z`^gd)6y7Hs3@VIp3$Gb`aGjae&f)s zPH4eJrei+wAP9QziB>ta7P)@Kv@Xx?Q>0cpb!s-@9^FX_uyw-PvBJM}_eHv$0>hS= zDiC8J^%FO0r>+c@HR|Ps^3&{d)iIJeTRs6Dw@CiXoxSW%0t}yJ5TTw9HQ9@4xin|=g&(WwavnUd4S7A zpAX5YeuJ}SM3pzmzrWlbv024t!I=LPc}zF^vC+%%)~hM1&T)c@HS*&qUlI%+JH28;Q>?=3&x8uc<*Bpfev=vpp?eNoOzM zxp1UvP8}IS$ttT`cg2Xa8X+*Z@=U#bdWi%1yfdDdqOcA{QS8;; z2?+4(UiB5eRTS!DsWY{{o_CGF2t(kjBk`#uzG77bSW@4`2~oppBsOp$@4>6K6d9*_ zJ>jVrZrZA}j0RQ6YpeIgq^_D3nduZrHG3j}57u=^%(N&=JrRIN0~?Hv9)0oWl(MA- z!=UVAny)()lGt3~zMHz_iKls`7#eLA7z9poT7YXGev&GNa4y#jkprB*F2spL(1N73 z9$}Zr9&SLA45qfVQj>5LVQ+u&C;deSRSHR$u0;wL68Qu>yTmJ2c^gr#pZY3ioL2b0G#K;1gmcul=VANq3UfO3$_d@*iY1g@Ghnm}8gr~Cu91)T$_YJDtX z4hITG#s0ah#9`s#y9rKWEX_%4cl@n|!?GEk*UmsFDm+B_yF_HMvt}M^ZNG7m#o5tL zXe4C&SKZqFrJj0@TfimC&X;0in2k+VTx*bxjRU$gdbYW9O0qiwH!-@1vtw6KDUkM2 z&Fj(iVj^+*4!@`oxL~JHgnFz;fS)@5Bt<6i2guFg4sI9Xl4dJY0$f%eAq1onhXeKr zz7De|Je^gx`9@ok^gxF3?kTs05B&zQ*}&>&$6^JVTdK*w6Vu4qDirZI9<8x4PCrbY zpgcYkY#qd~=k`)>)Dip<>lHFLUilAi|2AZ+KE=A9puZb$0s*-bHW!rfvYBPJL4!tX zDy3Hr6^KHXH27A8AYN@tnjO&ZS@@7+Qy3-bz&EPhI3kC2{YyA40mNgBo)(N}dC1pk*JL zw7O&voL1k>ETg#--9TF_j~=X{Nd)JuYMrF8n8l0|(Y z)cbFekM~+|@xnSnafAQj6v0EyKEsVpCj_DZ5BbOxn}`#z)YhV2rSGa%{ZqHBToQWY>2iLr7L6&2*d?rdOF=ScG+F0odGYi<$ z#bv@YEer-RWJUR5Rh7zGA^LPFB&+xQNpW6Mah*%+*4RxZgzGQU!uN(3_|+GCSw&9Z zIJs(_E`W=Nc(f&7fIc#LX;J6P0c?&_6YpzIqd>qb|H~`>aET)Fu@Jx+-TfdHD!hJ} z9F#=uGiL@Bh60t3^K>bC_#!}?lgj{l&1MT3mHjk zW;5c%b}#&Udn-=I0jcNT+egkzu3oZ9{j^@X5V9rJWtn8^_ax}f!z53<#B4xRqjGP9 zATLOPskJ4o{)Cu%DJO@dVjD7^>HHWna5Z`&n0QCJ=Oc-QQf%eD*I&*}?^u%#25lcC z3|yy<9!SUV78i12it4i_L(hc1>PbMJOz*78C6?Fyd(uzdam>; zij#Y*Wm(Op@|mlJ>*NZ4&WgHe{Q=zU1ZGXcCm!~{>o$@I17x$c^FQ(!VOo= z>0<9;t^1C^CwiZqbge|J6aXEc<$%)`7wy9*y{> zTZlnyjAnIpZPvj2#h7QffPLvC!*VxTBdo*jZJ0HssI2U6$$twUY`hk2xj!^_P3ul; z|G25EwH_jYbzMfz+0jjluDLmA&+x?D-xcabR(zE%*1H?B{d(tx$pr5L6UxJ+F)qTg z^KTbm92oM8yK;zQy-4+|3DmQqvxTqIsJ=srC6;!GfF|p@!GW_KB^3KkLc#59$j_z1 zbHtMKUx@tOVPT10&MTn!vj}dH#uS*W`#Ke{uIt-?3H)nvA8!R-SQFC*$;{X?$p zJt&rzPwa@oby(z2kLIMSX>?Vj{pX<+K3NPUbrq{2pC`I`>7blz`8 z&Za-PH5Gi45OMhSa55&~8>*`y)9+z`s{fakDZb&`w+_F{4aM~B_4lu8te0i@;ITb=P$1zho=_a07u^og_X5jV@pJhz32WC~D}r<@ zG0a2Z#MY2%3cn5Hk*n!DJH%6LdNEgSV9%Q{ZV1@HP2)X5Dqb;=Grd8w*z(m4MFI9g z-2$4iE9VZCsr^lu#Uzlg&3!qUzo#{|N2B_ylAo7Pw_36A(LHTG30ZA5LU>~% z)H49#TaD~D1;jOE90#JbxG13sq2tCL1aeiJMFh3qeax(&f?tFMKiX@GW+|zw$u6^z zE#O9%8Kq`4@sg`DL3DoXXlrKbULFG9dqgjrJl|4CxP@R2y~JY*8hi^n6-Wj{Lo(uK zJBmKf$!o#zslEzqAs?z(DvBS&>~)Msdj0sR1$=~)dj_Z2>`-I%5ccT4u22bi7P)rA z#cxRnn5_We3FKOt=YE=Yu2VeG*|( zpZr6X*)EO`a8g0A+#lpVT>x*rm?TDoRZ>7?QDicv8;Mv`4WXcoLC6=S>GTH2Ki?eL z-?OFOO--8sN@7BWoPZ6+-xDx-4KP5JFZPTC{l#%_;%3xcA?#T+Y{ht@m-=gfdQ zj>@GJKiP1U?ee@4^)M!jX&koOm{JM}zj9{99rFR5zZ(6dbg%Ou+75$8UJ>$S z(PEFUE$yluvEA(cJi!R6vrOxqW2O)!?XFqrlLXbgCdxG=s%LtT#n?2;be0qqjFjHW z)rY8scJ! z$5-&Xm_Emz{3&ZxKB_WNQt|4RG-)+|^zq*wauV84nD}K-u9e?@faD|r|KI>20{{Sk z1B`l-YSFuAr(yjA254MC`@MqpdmR7(@OLlt`|r%$#>m)>#==oq2?PKL+)KyY*$oN+ f5cv7G1@M1;$Vq~L{?`uhca!-&>iqTu0Pz0+EtYz{ literal 0 HcmV?d00001 diff --git a/scripts/embedder-deploy/bundle.sh b/scripts/embedder-deploy/build.sh similarity index 86% rename from scripts/embedder-deploy/bundle.sh rename to scripts/embedder-deploy/build.sh index d56ed2aa24b..0d708a80e0c 100755 --- a/scripts/embedder-deploy/bundle.sh +++ b/scripts/embedder-deploy/build.sh @@ -5,6 +5,6 @@ set -e ( cd image-embedder-lambda npm install - npm run bundle + npm run build zip -r ../image-embedder.zip index.js ) \ No newline at end of file From 8fe7ed65025676802d44f23f0120a422f70e3345 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 7 Jan 2026 19:40:59 +0000 Subject: [PATCH 047/494] chore(deps): bump preact from 10.26.9 to 10.28.2 in /kahuna Bumps [preact](https://github.com/preactjs/preact) from 10.26.9 to 10.28.2. - [Release notes](https://github.com/preactjs/preact/releases) - [Commits](https://github.com/preactjs/preact/compare/10.26.9...10.28.2) --- updated-dependencies: - dependency-name: preact dependency-version: 10.28.2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- kahuna/package-lock.json | 353 ++++++++++++++++++++++++++++++++++++++- kahuna/package.json | 2 +- 2 files changed, 350 insertions(+), 5 deletions(-) diff --git a/kahuna/package-lock.json b/kahuna/package-lock.json index 3b2d2ee84dd..62c7f89c83e 100644 --- a/kahuna/package-lock.json +++ b/kahuna/package-lock.json @@ -32,7 +32,7 @@ "pandular": "0.1.6", "pikaday": "1.8.2", "pikaday-time": "1.6.1", - "preact": "10.26.9", + "preact": "10.28.2", "react": "17.0.2", "react-dom": "17.0.2", "react2angular": "4.0.6", @@ -2103,6 +2103,64 @@ "node": ">=10.0.0" } }, + "node_modules/@emnapi/core": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", + "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/core/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, "node_modules/@eslint/eslintrc": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", @@ -3236,6 +3294,19 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -3426,6 +3497,25 @@ "node": ">=10.13.0" } }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tybys/wasm-util/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, "node_modules/@types/angular": { "version": "1.8.4", "resolved": "https://registry.npmjs.org/@types/angular/-/angular-1.8.4.tgz", @@ -3874,6 +3964,34 @@ "dev": true, "license": "ISC" }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, "node_modules/@unrs/resolver-binding-darwin-arm64": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", @@ -3888,6 +4006,233 @@ "darwin" ] }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz", + "integrity": "sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz", + "integrity": "sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@webassemblyjs/ast": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", @@ -13063,9 +13408,9 @@ "dev": true }, "node_modules/preact": { - "version": "10.26.9", - "resolved": "https://registry.npmjs.org/preact/-/preact-10.26.9.tgz", - "integrity": "sha512-SSjF9vcnF27mJK1XyFMNJzFd5u3pQiATFqoaDy03XuN00u4ziveVVEGt5RKJrDR8MHE/wJo9Nnad56RLzS2RMA==", + "version": "10.28.2", + "resolved": "https://registry.npmjs.org/preact/-/preact-10.28.2.tgz", + "integrity": "sha512-lbteaWGzGHdlIuiJ0l2Jq454m6kcpI1zNje6d8MlGAFlYvP2GO4ibnat7P74Esfz4sPTdM6UxtTwh/d3pwM9JA==", "license": "MIT", "funding": { "type": "opencollective", diff --git a/kahuna/package.json b/kahuna/package.json index 72cafb3f836..df720f45d31 100644 --- a/kahuna/package.json +++ b/kahuna/package.json @@ -27,7 +27,7 @@ "pandular": "0.1.6", "pikaday": "1.8.2", "pikaday-time": "1.6.1", - "preact": "10.26.9", + "preact": "10.28.2", "react": "17.0.2", "react-dom": "17.0.2", "react2angular": "4.0.6", From 1c806456784d108aee830120e96f6054dd8ae56a Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Thu, 8 Jan 2026 11:25:00 +0000 Subject: [PATCH 048/494] move build into /dist --- .github/workflows/ci.yml | 2 +- image-embedder-lambda/.gitignore | 1 - image-embedder-lambda/package.json | 2 +- project/plugins.sbt | 2 +- scripts/embedder-deploy/build.sh | 2 +- 5 files changed, 4 insertions(+), 5 deletions(-) delete mode 100644 image-embedder-lambda/.gitignore diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 255bdac9776..6590ac70ec1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -121,4 +121,4 @@ jobs: cdk.out: - cdk/cdk.out image-embedder-lambda: - - image-embedder.zip \ No newline at end of file + - image-embedder-lambda/dist/image-embedder.zip \ No newline at end of file diff --git a/image-embedder-lambda/.gitignore b/image-embedder-lambda/.gitignore deleted file mode 100644 index 945ce43a909..00000000000 --- a/image-embedder-lambda/.gitignore +++ /dev/null @@ -1 +0,0 @@ -index.js \ No newline at end of file diff --git a/image-embedder-lambda/package.json b/image-embedder-lambda/package.json index c007ae40d6e..d25269a5a19 100644 --- a/image-embedder-lambda/package.json +++ b/image-embedder-lambda/package.json @@ -6,7 +6,7 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "type-check": "tsc --noEmit", - "bundle": "esbuild src/index.ts --bundle --platform=node --target=node24 --format=cjs --outfile=index.js", + "bundle": "esbuild src/index.ts --bundle --platform=node --target=node24 --format=cjs --outfile=dist/index.js", "build": "run-p --print-label type-check bundle" }, "author": "", diff --git a/project/plugins.sbt b/project/plugins.sbt index 3f3177253fc..2e922a3d71a 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -1,6 +1,6 @@ libraryDependencies += "org.vafer" % "jdeb" % "1.3" artifacts (Artifact("jdeb", "jar", "jar")) -addSbtPlugin("org.playframework" % "sbt-plugin" % "3.0.5") +addSbtPlugin("org.playframework" % "sbt-plugin" % "3.0.10") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.9.0") diff --git a/scripts/embedder-deploy/build.sh b/scripts/embedder-deploy/build.sh index 0d708a80e0c..c4103fab0ec 100755 --- a/scripts/embedder-deploy/build.sh +++ b/scripts/embedder-deploy/build.sh @@ -6,5 +6,5 @@ set -e cd image-embedder-lambda npm install npm run build - zip -r ../image-embedder.zip index.js + zip -r dist/image-embedder.zip dist/index.js ) \ No newline at end of file From 68937b15fd637afebaa70726772acf8377c00b24 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Thu, 8 Jan 2026 14:25:27 +0000 Subject: [PATCH 049/494] move build into /dist --- .github/workflows/ci.yml | 2 +- scripts/embedder-deploy/build.sh | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6590ac70ec1..255bdac9776 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -121,4 +121,4 @@ jobs: cdk.out: - cdk/cdk.out image-embedder-lambda: - - image-embedder-lambda/dist/image-embedder.zip \ No newline at end of file + - image-embedder.zip \ No newline at end of file diff --git a/scripts/embedder-deploy/build.sh b/scripts/embedder-deploy/build.sh index c4103fab0ec..439080e898a 100755 --- a/scripts/embedder-deploy/build.sh +++ b/scripts/embedder-deploy/build.sh @@ -6,5 +6,6 @@ set -e cd image-embedder-lambda npm install npm run build - zip -r dist/image-embedder.zip dist/index.js + cd dist + zip -r ../image-embedder.zip index.js ) \ No newline at end of file From 2be85a474858c58c19b87167cd6f52fbdc6be6ab Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Thu, 8 Jan 2026 14:48:53 +0000 Subject: [PATCH 050/494] remove extra permissions --- cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap | 7 +------ cdk/lib/image-embedder-lambda.ts | 3 --- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap index edd0aae09d8..577811d163a 100644 --- a/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap +++ b/cdk/lib/__snapshots__/image-embedder-lambda.test.ts.snap @@ -236,12 +236,7 @@ exports[`The MediaService stack matches the snapshot 1`] = ` }, }, { - "Action": [ - "s3vectors:PutVectors", - "s3vectors:GetVectors", - "s3vectors:QueryVectors", - "s3vectors:ListVectors", - ], + "Action": "s3vectors:PutVectors", "Effect": "Allow", "Resource": { "Fn::Join": [ diff --git a/cdk/lib/image-embedder-lambda.ts b/cdk/lib/image-embedder-lambda.ts index 522191f3b78..f366859d938 100644 --- a/cdk/lib/image-embedder-lambda.ts +++ b/cdk/lib/image-embedder-lambda.ts @@ -52,9 +52,6 @@ export class MediaService extends GuStack { new PolicyStatement({ actions: [ 's3vectors:PutVectors', - 's3vectors:GetVectors', - 's3vectors:QueryVectors', - 's3vectors:ListVectors' ], resources: [ `arn:aws:s3vectors:eu-central-1:${Stack.of(this).account}:bucket/image-embeddings-via-lambda/index/*`, From 381f6df9cdf89096a47d6a05efc23a35b5cf88b9 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Thu, 8 Jan 2026 15:26:04 +0000 Subject: [PATCH 051/494] fix path stuff --- scripts/embedder-deploy/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/embedder-deploy/build.sh b/scripts/embedder-deploy/build.sh index 439080e898a..b35b7aec19c 100755 --- a/scripts/embedder-deploy/build.sh +++ b/scripts/embedder-deploy/build.sh @@ -7,5 +7,5 @@ set -e npm install npm run build cd dist - zip -r ../image-embedder.zip index.js + zip -r ../../image-embedder.zip index.js ) \ No newline at end of file From 061e6d8c8dbfca9a0d09dd6f60b3f1695645475f Mon Sep 17 00:00:00 2001 From: TJ Silver <15648334+tjsilver@users.noreply.github.com> Date: Fri, 9 Jan 2026 14:13:04 +0000 Subject: [PATCH 052/494] Fix setup-java version comment to match pinned SHA (bulk remediation) --- .github/workflows/sbt-dependency-graph.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/sbt-dependency-graph.yaml b/.github/workflows/sbt-dependency-graph.yaml index 408926ac66f..fdc080bd462 100644 --- a/.github/workflows/sbt-dependency-graph.yaml +++ b/.github/workflows/sbt-dependency-graph.yaml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 - name: Install Java id: java - uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.2.0 + uses: actions/setup-java@b36c23c0d998641eff861008f374ee103c25ac73 # v4.4.0 with: distribution: corretto java-version: 17 From 81e61d2c77ce2431f65c730bf739a394c885935b Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Fri, 9 Jan 2026 15:23:45 +0000 Subject: [PATCH 053/494] small tweaks --- image-embedder-lambda/src/index.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/image-embedder-lambda/src/index.ts b/image-embedder-lambda/src/index.ts index 952d0ab969f..0011432f910 100644 --- a/image-embedder-lambda/src/index.ts +++ b/image-embedder-lambda/src/index.ts @@ -98,8 +98,7 @@ async function storeEmbedding( key: string, client: S3VectorsClient ) { - console.log(`Storing embedding for key: ${key}`); - console.log(`Embedding length: ${embedding.length}`); + console.log(`Storing embedding of length ${embedding.length} for key: ${key}`); const inputVector: PutInputVector = { key: key, @@ -136,8 +135,6 @@ export const handler = async (event: SQSEvent, context: Context) => { const records: SQSRecord[] = event.Records; const recordBody: SQSMessageBody = JSON.parse(records[0].body); - const config = {region: "eu-west-1"}; - // If it's a Tiff then we should throw an error // So that it ends on the DLQ for processing when we add tiff handling if (recordBody.fileType === "image/tiff") { @@ -158,7 +155,6 @@ export const handler = async (event: SQSEvent, context: Context) => { // Extract the embedding array (first element since we only sent one image) const embedding: number[] = responseBody.embeddings.float[0]; - console.log(`Embedding length: ${embedding.length}`); console.log(`First 5 values: ${embedding.slice(0, 5)}`); await storeEmbedding(embedding, recordBody.imageId, s3VectorsClient); From 1afbb9f456c33573ef1dd372b8ac1b528c661e77 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Fri, 9 Jan 2026 15:32:04 +0000 Subject: [PATCH 054/494] Update cdk/lib/image-embedder-lambda.ts Co-authored-by: Joseph Smith --- cdk/lib/image-embedder-lambda.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cdk/lib/image-embedder-lambda.ts b/cdk/lib/image-embedder-lambda.ts index f366859d938..7e70e29b0bb 100644 --- a/cdk/lib/image-embedder-lambda.ts +++ b/cdk/lib/image-embedder-lambda.ts @@ -47,7 +47,7 @@ export class MediaService extends GuStack { new SqsEventSource(imageEmbedderQueue), ); - // Allow reading and writing vectors to S3 vector index + // Allow writing vectors to S3 vector index imageEmbedderLambda.role?.addToPrincipalPolicy( new PolicyStatement({ actions: [ From 6e6cdb8f3d87223875cf29d1b355b2ea3709894d Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Fri, 9 Jan 2026 15:53:29 +0000 Subject: [PATCH 055/494] remove unnecessary packages --- image-embedder-lambda/package.json | 2 -- 1 file changed, 2 deletions(-) diff --git a/image-embedder-lambda/package.json b/image-embedder-lambda/package.json index d25269a5a19..a3d913ca9e4 100644 --- a/image-embedder-lambda/package.json +++ b/image-embedder-lambda/package.json @@ -15,8 +15,6 @@ "@types/aws-lambda": "^8.10.159", "@types/node": "^25.0.0", "esbuild": "0.27.0", - "install": "^0.13.0", - "npm": "^11.7.0", "npm-run-all": "^4.1.5", "typescript": "^5.9.3" }, From 24663aad29fb000a4c375bd50bad3ef66f8d746a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Jan 2026 11:50:56 +0000 Subject: [PATCH 056/494] chore(deps-dev): bump qs from 6.5.2 to 6.5.3 in /s3watcher/lambda Bumps [qs](https://github.com/ljharb/qs) from 6.5.2 to 6.5.3. - [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md) - [Commits](https://github.com/ljharb/qs/compare/v6.5.2...v6.5.3) --- updated-dependencies: - dependency-name: qs dependency-version: 6.5.3 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- s3watcher/lambda/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/s3watcher/lambda/package-lock.json b/s3watcher/lambda/package-lock.json index 336c13f21b2..a8e168d369e 100644 --- a/s3watcher/lambda/package-lock.json +++ b/s3watcher/lambda/package-lock.json @@ -6350,9 +6350,9 @@ "dev": true }, "node_modules/qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true, "engines": { "node": ">=0.6" @@ -13602,9 +13602,9 @@ "dev": true }, "qs": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", "dev": true }, "querystring": { From ebca9498edccf849eff615dd519ca27e87f7562a Mon Sep 17 00:00:00 2001 From: lindseydew Date: Thu, 4 Dec 2025 17:22:51 +0000 Subject: [PATCH 057/494] Update the boolean set --- .../gu/mediaservice/lib/aws/DynamoDB.scala | 37 ++++++++++++++++++- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala index e2a5b407a77..7dec7d2d48c 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala @@ -13,8 +13,9 @@ import org.joda.time.DateTime import play.api.libs.json._ import software.amazon.awssdk.enhanced.dynamodb._ import software.amazon.awssdk.enhanced.dynamodb.document.EnhancedDocument -import software.amazon.awssdk.enhanced.dynamodb.model.GetItemEnhancedRequest +import software.amazon.awssdk.enhanced.dynamodb.model import software.amazon.awssdk.services.dynamodb.DynamoDbClient +import software.amazon.awssdk.services.dynamodb.model.{AttributeValue => AttributeValueV2, UpdateItemRequest, ReturnValue => ReturnValueV2} import scala.annotation.tailrec import scala.concurrent.{ExecutionContext, Future} @@ -103,9 +104,18 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti new ValueMap().withBoolean(":value", value) ) + def booleanSetV2(id: String, key: String, value: Boolean) + (implicit ex: ExecutionContext): Future[JsObject] = Future { + updateV2( + id, + s"SET $key = :value", + value + ) + } + def booleanSetOrRemove(id: String, key: String, value: Boolean) (implicit ex: ExecutionContext): Future[JsObject] = - if (value) booleanSet(id, key, value) + if (value) booleanSetV2(id, key, value) else removeKey(id, key) def stringSet(id: String, key: String, value: JsValue) @@ -264,6 +274,29 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti items map (a => a.getString("id")) } + def updateV2(id: String, expression: String, jsValue: JsValue) = { + val updateRequest = UpdateItemRequest.builder() + .key(Map(IdKey -> AttributeValueV2.fromS(id)).asJava) + .updateExpression(expression) + .expressionAttributeValues(EnhancedDocument.fromJson(jsValue.toString()).toMap) + .tableName(tableName) + .build() + client2.updateItem(updateRequest) + } + + def updateV2(id: String, expression: String, bool: Boolean) = { + val updateRequest = UpdateItemRequest.builder() + .key(Map(IdKey -> AttributeValueV2.fromS(id)).asJava) + .updateExpression(expression) + .expressionAttributeValues(Map(":value" -> AttributeValueV2.fromBool(bool)).asJava) + .returnValues(ReturnValueV2.ALL_NEW) + .tableName(tableName) + .build() + val updateItemResponse = client2.updateItem(updateRequest) + val jsonString = EnhancedDocument.fromAttributeValueMap(updateItemResponse.attributes()).toJson + Json.parse(jsonString).as[JsObject] + } + def update(id: String, expression: String, valueMap: ValueMap) (implicit ex: ExecutionContext): Future[JsObject] = update(id, expression, Some(valueMap)) From e31e2ca61ef53d2e87270695a741fbf23991251c Mon Sep 17 00:00:00 2001 From: lindseydew Date: Mon, 8 Dec 2025 12:17:50 +0000 Subject: [PATCH 058/494] Update archived --- .../gu/mediaservice/lib/aws/DynamoDB.scala | 22 ++++++++++++++++++- .../app/controllers/EditsController.scala | 4 ++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala index 7dec7d2d48c..54e24d1f892 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala @@ -87,6 +87,9 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti s"REMOVE $key" ) + def removeKeyV2(id: String, key: String)(implicit ex: ExecutionContext) = Future{ + updateV2(id, s"Remove $key") + } def deleteItem(id: String)(implicit ex: ExecutionContext): Future[Unit] = Future { table.deleteItem(new DeleteItemSpec().withPrimaryKey(IdKey, id)) } @@ -115,9 +118,14 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti def booleanSetOrRemove(id: String, key: String, value: Boolean) (implicit ex: ExecutionContext): Future[JsObject] = - if (value) booleanSetV2(id, key, value) + if (value) booleanSet(id, key, value) else removeKey(id, key) + def booleanSetOrRemoveV2(id: String, key: String, value: Boolean) + (implicit ex: ExecutionContext): Future[JsObject] = + if (value) booleanSetV2(id, key, value) + else removeKeyV2(id, key) + def stringSet(id: String, key: String, value: JsValue) (implicit ex: ExecutionContext): Future[JsObject] = update( @@ -297,6 +305,18 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti Json.parse(jsonString).as[JsObject] } + def updateV2(id: String, expression: String) = { + val updateRequest = UpdateItemRequest.builder() + .key(Map(IdKey -> AttributeValueV2.fromS(id)).asJava) + .updateExpression(expression) + .returnValues(ReturnValueV2.ALL_NEW) + .tableName(tableName) + .build() + val updateItemResponse = client2.updateItem(updateRequest) + val jsonString = EnhancedDocument.fromAttributeValueMap(updateItemResponse.attributes()).toJson + Json.parse(jsonString).as[JsObject] + } + def update(id: String, expression: String, valueMap: ValueMap) (implicit ex: ExecutionContext): Future[JsObject] = update(id, expression, Some(valueMap)) diff --git a/metadata-editor/app/controllers/EditsController.scala b/metadata-editor/app/controllers/EditsController.scala index bacf11f7ab3..0cc92915498 100644 --- a/metadata-editor/app/controllers/EditsController.scala +++ b/metadata-editor/app/controllers/EditsController.scala @@ -100,14 +100,14 @@ class EditsController( errors => Future.successful(BadRequest(errors.toString())), archived => - editsStore.booleanSetOrRemove(id, "archived", archived) + editsStore.booleanSetOrRemoveV2(id, "archived", archived) .map(publish(id, UpdateImageUserMetadata)) .map(edits => respond(edits.archived)) ) } def unsetArchived(id: String) = auth.async { - editsStore.removeKey(id, Edits.Archived) + editsStore.removeKeyV2(id, Edits.Archived) .map(publish(id, UpdateImageUserMetadata)) .map(_ => respond(false)) } From a15bb9271ebfce5320c481861b039b305087cb1a Mon Sep 17 00:00:00 2001 From: lindseydew Date: Mon, 8 Dec 2025 12:35:53 +0000 Subject: [PATCH 059/494] Migrate the labels editing to v2 --- .../gu/mediaservice/lib/aws/DynamoDB.scala | 21 +++++++++++++++++++ .../app/controllers/EditsController.scala | 4 ++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala index 54e24d1f892..082915a89bc 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala @@ -167,6 +167,9 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti new ValueMap().withStringSet(":value", value:_*) ) + def setAddV2(id: String, key: String, value: List[String])(implicit ex: ExecutionContext): Future[JsObject] = Future { + updateV2(id, s"ADD $key :value", AttributeValueV2.fromSs(value.asJava)) + } def batchGet(ids: List[String], attributeKey: String) (implicit ex: ExecutionContext, rjs: Reads[T]): Future[Map[String, T]] = { val keyChunkList = ids @@ -226,6 +229,12 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti new ValueMap().withStringSet(":value", value) ) + def setDeleteV2(id: String, key: String, value: String) + (implicit ex: ExecutionContext): Future[JsObject] = Future { + updateV2(id, s"DELETE $key :value", AttributeValueV2.fromSs(List(value).asJava)) + + } + def listAdd(id: String, key: String, value: T) (implicit ex: ExecutionContext, tjs: Writes[T], rjs: Reads[T]): Future[List[T]] = { @@ -304,6 +313,18 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti val jsonString = EnhancedDocument.fromAttributeValueMap(updateItemResponse.attributes()).toJson Json.parse(jsonString).as[JsObject] } + def updateV2(id: String, expression: String, attribute: AttributeValueV2) = { + val updateRequest = UpdateItemRequest.builder() + .key(Map(IdKey -> AttributeValueV2.fromS(id)).asJava) + .updateExpression(expression) + .expressionAttributeValues(Map(":value" -> attribute).asJava) + .returnValues(ReturnValueV2.ALL_NEW) + .tableName(tableName) + .build() + val updateItemResponse = client2.updateItem(updateRequest) + val jsonString = EnhancedDocument.fromAttributeValueMap(updateItemResponse.attributes()).toJson + Json.parse(jsonString).as[JsObject] + } def updateV2(id: String, expression: String) = { val updateRequest = UpdateItemRequest.builder() diff --git a/metadata-editor/app/controllers/EditsController.scala b/metadata-editor/app/controllers/EditsController.scala index 0cc92915498..955ee533806 100644 --- a/metadata-editor/app/controllers/EditsController.scala +++ b/metadata-editor/app/controllers/EditsController.scala @@ -127,7 +127,7 @@ class EditsController( Future.successful(BadRequest(errors.toString())), labels => editsStore - .setAdd(id, Edits.Labels, labels) + .setAddV2(id, Edits.Labels, labels) .map(publish(id, UpdateImageUserMetadata)) .map(edits => labelsCollection(id, edits.labels.toSet)) .map { case (uri, l) => respondCollection(l) } recover { @@ -137,7 +137,7 @@ class EditsController( } def removeLabel(id: String, label: String) = auth.async { - editsStore.setDelete(id, Edits.Labels, decodeUriParam(label)) + editsStore.setDeleteV2(id, Edits.Labels, decodeUriParam(label)) .map(publish(id, UpdateImageUserMetadata)) .map(edits => labelsCollection(id, edits.labels.toSet)) .map {case (uri, labels) => respondCollection(labels, uri=Some(uri))} From 355553f9a33f3d6a85f48166afd3e73aac4f9802 Mon Sep 17 00:00:00 2001 From: lindseydew Date: Mon, 8 Dec 2025 12:44:25 +0000 Subject: [PATCH 060/494] Update the delete usage rights --- metadata-editor/app/controllers/EditsController.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/metadata-editor/app/controllers/EditsController.scala b/metadata-editor/app/controllers/EditsController.scala index 955ee533806..cd601b26093 100644 --- a/metadata-editor/app/controllers/EditsController.scala +++ b/metadata-editor/app/controllers/EditsController.scala @@ -222,12 +222,11 @@ class EditsController( }).getOrElse(Future.successful(respondError(BadRequest, "invalid-form-data", "Invalid form data"))) } + //TODO - remove as a second step def deleteUsageRights(id: String) = auth.async { req => - editsStore.removeKey(id, Edits.UsageRights).map(publish(id, UpdateImageUserMetadata)).map(edits => Accepted) + editsStore.removeKeyV2(id, Edits.UsageRights).map(publish(id, UpdateImageUserMetadata)).map(edits => Accepted) } - - private def labelsCollection(id: String, labels: Set[String]): (URI, Seq[EmbeddedEntity[String]]) = (labelsUri(id), labels.map(setUnitEntity(id, Edits.Labels, _)).toSeq) From 275aa26748c4affc6df56d4d0eaaad968ff8cba6 Mon Sep 17 00:00:00 2001 From: lindseydew Date: Mon, 8 Dec 2025 12:56:24 +0000 Subject: [PATCH 061/494] Migrate the db methods in syndication --- .../com/gu/mediaservice/lib/aws/DynamoDB.scala | 14 ++++++++++++-- metadata-editor/app/lib/Syndication.scala | 4 ++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala index 082915a89bc..b5941c2bb46 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala @@ -5,7 +5,7 @@ import com.amazonaws.AmazonServiceException import com.amazonaws.services.dynamodbv2.document.spec.{DeleteItemSpec, GetItemSpec, PutItemSpec, QuerySpec, UpdateItemSpec} import com.amazonaws.services.dynamodbv2.document.utils.ValueMap import com.amazonaws.services.dynamodbv2.document.{DynamoDB => AwsDynamoDB, _} -import com.amazonaws.services.dynamodbv2.model.{AttributeValue, KeysAndAttributes, ReturnValue} +import com.amazonaws.services.dynamodbv2.model.{AttributeValue, DeleteItemRequest, KeysAndAttributes, ReturnValue} import com.amazonaws.services.dynamodbv2.{AmazonDynamoDBAsync, AmazonDynamoDBAsyncClientBuilder} import com.gu.mediaservice.lib.config.CommonConfig import com.gu.mediaservice.lib.logging.GridLogging @@ -15,7 +15,7 @@ import software.amazon.awssdk.enhanced.dynamodb._ import software.amazon.awssdk.enhanced.dynamodb.document.EnhancedDocument import software.amazon.awssdk.enhanced.dynamodb.model import software.amazon.awssdk.services.dynamodb.DynamoDbClient -import software.amazon.awssdk.services.dynamodb.model.{AttributeValue => AttributeValueV2, UpdateItemRequest, ReturnValue => ReturnValueV2} +import software.amazon.awssdk.services.dynamodb.model.{UpdateItemRequest, AttributeValue => AttributeValueV2, ReturnValue => ReturnValueV2} import scala.annotation.tailrec import scala.concurrent.{ExecutionContext, Future} @@ -94,6 +94,12 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti table.deleteItem(new DeleteItemSpec().withPrimaryKey(IdKey, id)) } + + def deleteItemV2(id: String)(implicit ex: ExecutionContext): Future[Unit] = Future { + table2.deleteItem( + Key.builder().partitionValue(id).build() + ) + } def booleanGetV2(id: String, key: String) (implicit ex: ExecutionContext): Future[Boolean] = { getV2(id, key).map(_.getBoolean(key).booleanValue()) @@ -134,6 +140,10 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti valueMapWithNullForEmptyString(Map(":value" -> value)) ) + def stringSetV2(id: String, key: String, value: String)(implicit ex: ExecutionContext): Future[JsObject] = Future { + updateV2(id, s"SET $key = :value", AttributeValueV2.fromS(value)) + } + def stringListSet(id: String, keyValues: (String, JsValue)*) (implicit ex: ExecutionContext): Future[JsObject] = { val keyValueMap = keyValues.toMap diff --git a/metadata-editor/app/lib/Syndication.scala b/metadata-editor/app/lib/Syndication.scala index 3e1ec4e3e62..48bc0ee97df 100644 --- a/metadata-editor/app/lib/Syndication.scala +++ b/metadata-editor/app/lib/Syndication.scala @@ -59,7 +59,7 @@ trait Syndication extends Edit with MessageSubjects with GridLogging { publishChangedSyndicationRightsForPhotoshoot[Photoshoot](id, photoshoot = Some(newPhotoshoot)) { () => for { editsAsJsonResponse <- editsStore.jsonAdd(id, Edits.Photoshoot, DynamoDB.caseClassToMap(newPhotoshoot)) - _ <- editsStore.stringSet(id, Edits.PhotoshootTitle, JsString(newPhotoshoot.title)) // store - don't care about return + _ <- editsStore.stringSetV2(id, Edits.PhotoshootTitle, newPhotoshoot.title) // store - don't care about return _ = publish(id, UpdateImagePhotoshootMetadata)(editsAsJsonResponse) } yield newPhotoshoot } @@ -68,7 +68,7 @@ trait Syndication extends Edit with MessageSubjects with GridLogging { def deleteSyndicationAndPublish(id: String) (implicit ec: ExecutionContext): Future[Unit] = { publishChangedSyndicationRightsForPhotoshoot[Unit](id, unchangedPhotoshoot = true) { () => - syndicationStore.deleteItem(id) + syndicationStore.deleteItemV2(id) // Always publish, in case there is no photoshoot publish(Map(id -> None), UpdateImageSyndicationMetadata) } From a3aa267d03baed4538b2a27cbcc34c8fc1bb07f3 Mon Sep 17 00:00:00 2001 From: lindseydew Date: Mon, 8 Dec 2025 15:14:31 +0000 Subject: [PATCH 062/494] Update the usage rights --- .../gu/mediaservice/lib/aws/DynamoDB.scala | 25 +++++++++++++++++++ .../app/controllers/EditsController.scala | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala index b5941c2bb46..88b42bfd860 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala @@ -231,6 +231,17 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti new ValueMap().withMap(":value", valueMapWithNullForEmptyString(value)) ) + // We cannot update, so make sure you send over the WHOLE document + def jsonAddV2(id: String, key: String, value: Map[String, JsValue]) + (implicit ex: ExecutionContext): Future[JsObject] = Future { + updateV2( + id, + s"SET $key = :value", + AttributeValueV2.fromM(value.view.mapValues(DynamoDB.jsonToAttributeValue).toMap.asJava) + ) + } + + def setDelete(id: String, key: String, value: String) (implicit ex: ExecutionContext): Future[JsObject] = update( @@ -427,6 +438,20 @@ object DynamoDB { } valueMap } + + def jsonToAttributeValue(json: JsValue): AttributeValueV2 = { + json match { + case JsString(v) => AttributeValueV2.fromS(v) + case JsBoolean(b) => AttributeValueV2.fromBool(b) + case JsTrue => AttributeValueV2.fromBool(true) + case JsFalse => AttributeValueV2.fromBool(false) + case JsNumber(n) => AttributeValueV2.fromN(n.toString()) + case JsNull => AttributeValueV2.fromNul(true) + case JsObject(obj) => AttributeValueV2.fromM(obj.view.mapValues(s => jsonToAttributeValue(s)).toMap.asJava) + case JsArray(arr) => AttributeValueV2.fromL(arr.toList.map(jsonToAttributeValue).asJava) + } + } + def caseClassToMap[T](caseClass: T)(implicit tjs: Writes[T]): Map[String, JsValue] = Json.toJson[T](caseClass).as[JsObject].as[Map[String, JsValue]] diff --git a/metadata-editor/app/controllers/EditsController.scala b/metadata-editor/app/controllers/EditsController.scala index cd601b26093..58603122eb6 100644 --- a/metadata-editor/app/controllers/EditsController.scala +++ b/metadata-editor/app/controllers/EditsController.scala @@ -216,7 +216,7 @@ class EditsController( def setUsageRights(id: String) = auth.async(parse.json) { req => (req.body \ "data").asOpt[UsageRights].map(usageRight => { - editsStore.jsonAdd(id, Edits.UsageRights, DynamoDB.caseClassToMap(usageRight)) + editsStore.jsonAddV2(id, Edits.UsageRights, DynamoDB.caseClassToMap(usageRight)) .map(publish(id, UpdateImageUserMetadata)) .map(_ => respond(usageRight)) }).getOrElse(Future.successful(respondError(BadRequest, "invalid-form-data", "Invalid form data"))) From d2c91abd4a0bc7d7ede411cc1267b9f93f4dd7c5 Mon Sep 17 00:00:00 2001 From: lindseydew Date: Mon, 8 Dec 2025 15:40:15 +0000 Subject: [PATCH 063/494] Migrate to use json v2 --- .../src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala | 4 +--- metadata-editor/app/controllers/EditsController.scala | 4 ++-- metadata-editor/app/lib/Syndication.scala | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala index 88b42bfd860..6f2f4086063 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala @@ -231,7 +231,6 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti new ValueMap().withMap(":value", valueMapWithNullForEmptyString(value)) ) - // We cannot update, so make sure you send over the WHOLE document def jsonAddV2(id: String, key: String, value: Map[String, JsValue]) (implicit ex: ExecutionContext): Future[JsObject] = Future { updateV2( @@ -241,7 +240,6 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti ) } - def setDelete(id: String, key: String, value: String) (implicit ex: ExecutionContext): Future[JsObject] = update( @@ -451,7 +449,7 @@ object DynamoDB { case JsArray(arr) => AttributeValueV2.fromL(arr.toList.map(jsonToAttributeValue).asJava) } } - + def caseClassToMap[T](caseClass: T)(implicit tjs: Writes[T]): Map[String, JsValue] = Json.toJson[T](caseClass).as[JsObject].as[Map[String, JsValue]] diff --git a/metadata-editor/app/controllers/EditsController.scala b/metadata-editor/app/controllers/EditsController.scala index 58603122eb6..44be486d4c1 100644 --- a/metadata-editor/app/controllers/EditsController.scala +++ b/metadata-editor/app/controllers/EditsController.scala @@ -168,7 +168,7 @@ class EditsController( }) val validatedMetadata = metadata.copy(domainMetadata = validatedDomainMetadata) - editsStore.jsonAdd(id, Edits.Metadata, metadataAsMap(validatedMetadata)) + editsStore.jsonAddV2(id, Edits.Metadata, metadataAsMap(validatedMetadata)) .map(publish(id, UpdateImageUserMetadata)) .map(edits => respond(edits.metadata)) } @@ -191,7 +191,7 @@ class EditsController( imageType = metadata.imageType orElse originalUserMetadata.imageType ) - editsStore.jsonAdd(id, Edits.Metadata, metadataAsMap(mergedMetadata)) + editsStore.jsonAddV2(id, Edits.Metadata, metadataAsMap(mergedMetadata)) .map(publish(id, UpdateImageUserMetadata)) .map(edits => respond(edits.metadata, uri = Some(metadataUri(id)))) } getOrElse { diff --git a/metadata-editor/app/lib/Syndication.scala b/metadata-editor/app/lib/Syndication.scala index 48bc0ee97df..d8a6f767fbf 100644 --- a/metadata-editor/app/lib/Syndication.scala +++ b/metadata-editor/app/lib/Syndication.scala @@ -58,7 +58,7 @@ trait Syndication extends Edit with MessageSubjects with GridLogging { (implicit ec: ExecutionContext): Future[Photoshoot] = { publishChangedSyndicationRightsForPhotoshoot[Photoshoot](id, photoshoot = Some(newPhotoshoot)) { () => for { - editsAsJsonResponse <- editsStore.jsonAdd(id, Edits.Photoshoot, DynamoDB.caseClassToMap(newPhotoshoot)) + editsAsJsonResponse <- editsStore.jsonAddV2(id, Edits.Photoshoot, DynamoDB.caseClassToMap(newPhotoshoot)) _ <- editsStore.stringSetV2(id, Edits.PhotoshootTitle, newPhotoshoot.title) // store - don't care about return _ = publish(id, UpdateImagePhotoshootMetadata)(editsAsJsonResponse) } yield newPhotoshoot @@ -77,7 +77,7 @@ trait Syndication extends Edit with MessageSubjects with GridLogging { def setSyndicationAndPublish(id: String, syndicationRight: SyndicationRights) (implicit ec: ExecutionContext): Future[SyndicationRights] = publishChangedSyndicationRightsForPhotoshoot[SyndicationRights](id, unchangedPhotoshoot = true) { () => - val result = syndicationStore.jsonAdd (id, syndicationRightsFieldName, DynamoDB.caseClassToMap (syndicationRight)).map(_=>syndicationRight) + val result = syndicationStore.jsonAddV2(id, syndicationRightsFieldName, DynamoDB.caseClassToMap (syndicationRight)).map(_=>syndicationRight) // Always publish, in case there is no photoshoot publish(Map(id -> Some(syndicationRight)), UpdateImageSyndicationMetadata) result From 0fc4819d0452812b8975736f14a181ddfcfdbe8b Mon Sep 17 00:00:00 2001 From: lindseydew Date: Mon, 8 Dec 2025 15:51:24 +0000 Subject: [PATCH 064/494] Use the main update for updating a bool --- .../gu/mediaservice/lib/aws/DynamoDB.scala | 24 +------------------ 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala index 6f2f4086063..0e8fd817d52 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala @@ -118,7 +118,7 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti updateV2( id, s"SET $key = :value", - value + AttributeValueV2.fromBool(value) ) } @@ -310,28 +310,6 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti items map (a => a.getString("id")) } - def updateV2(id: String, expression: String, jsValue: JsValue) = { - val updateRequest = UpdateItemRequest.builder() - .key(Map(IdKey -> AttributeValueV2.fromS(id)).asJava) - .updateExpression(expression) - .expressionAttributeValues(EnhancedDocument.fromJson(jsValue.toString()).toMap) - .tableName(tableName) - .build() - client2.updateItem(updateRequest) - } - - def updateV2(id: String, expression: String, bool: Boolean) = { - val updateRequest = UpdateItemRequest.builder() - .key(Map(IdKey -> AttributeValueV2.fromS(id)).asJava) - .updateExpression(expression) - .expressionAttributeValues(Map(":value" -> AttributeValueV2.fromBool(bool)).asJava) - .returnValues(ReturnValueV2.ALL_NEW) - .tableName(tableName) - .build() - val updateItemResponse = client2.updateItem(updateRequest) - val jsonString = EnhancedDocument.fromAttributeValueMap(updateItemResponse.attributes()).toJson - Json.parse(jsonString).as[JsObject] - } def updateV2(id: String, expression: String, attribute: AttributeValueV2) = { val updateRequest = UpdateItemRequest.builder() .key(Map(IdKey -> AttributeValueV2.fromS(id)).asJava) From eb3be6413a349a7f8d0d87b600250848555274ca Mon Sep 17 00:00:00 2001 From: lindseydew Date: Mon, 8 Dec 2025 15:58:33 +0000 Subject: [PATCH 065/494] Abstract out common update methods --- .../com/gu/mediaservice/lib/aws/DynamoDB.scala | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala index 0e8fd817d52..22bb3c50bf5 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala @@ -94,7 +94,6 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti table.deleteItem(new DeleteItemSpec().withPrimaryKey(IdKey, id)) } - def deleteItemV2(id: String)(implicit ex: ExecutionContext): Future[Unit] = Future { table2.deleteItem( Key.builder().partitionValue(id).build() @@ -310,13 +309,17 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti items map (a => a.getString("id")) } - def updateV2(id: String, expression: String, attribute: AttributeValueV2) = { - val updateRequest = UpdateItemRequest.builder() + private def updateRequestBuilder(id: String, expression: String) = { + UpdateItemRequest.builder() .key(Map(IdKey -> AttributeValueV2.fromS(id)).asJava) .updateExpression(expression) - .expressionAttributeValues(Map(":value" -> attribute).asJava) .returnValues(ReturnValueV2.ALL_NEW) .tableName(tableName) + } + + def updateV2(id: String, expression: String, attribute: AttributeValueV2) = { + val updateRequest = updateRequestBuilder(id, expression) + .expressionAttributeValues(Map(":value" -> attribute).asJava) .build() val updateItemResponse = client2.updateItem(updateRequest) val jsonString = EnhancedDocument.fromAttributeValueMap(updateItemResponse.attributes()).toJson @@ -324,12 +327,7 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti } def updateV2(id: String, expression: String) = { - val updateRequest = UpdateItemRequest.builder() - .key(Map(IdKey -> AttributeValueV2.fromS(id)).asJava) - .updateExpression(expression) - .returnValues(ReturnValueV2.ALL_NEW) - .tableName(tableName) - .build() + val updateRequest = updateRequestBuilder(id, expression).build() val updateItemResponse = client2.updateItem(updateRequest) val jsonString = EnhancedDocument.fromAttributeValueMap(updateItemResponse.attributes()).toJson Json.parse(jsonString).as[JsObject] From bb7b21fa29297eb8fa6927df9a8eae0959710803 Mon Sep 17 00:00:00 2001 From: Andrew Nowak <10963046+andrew-nowak@users.noreply.github.com> Date: Tue, 13 Jan 2026 13:42:57 +0000 Subject: [PATCH 066/494] Revert "Dynamo sdk writes" --- .../gu/mediaservice/lib/aws/DynamoDB.scala | 87 +------------------ .../app/controllers/EditsController.scala | 19 ++-- metadata-editor/app/lib/Syndication.scala | 8 +- 3 files changed, 16 insertions(+), 98 deletions(-) diff --git a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala index 22bb3c50bf5..e2a5b407a77 100644 --- a/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala +++ b/common-lib/src/main/scala/com/gu/mediaservice/lib/aws/DynamoDB.scala @@ -5,7 +5,7 @@ import com.amazonaws.AmazonServiceException import com.amazonaws.services.dynamodbv2.document.spec.{DeleteItemSpec, GetItemSpec, PutItemSpec, QuerySpec, UpdateItemSpec} import com.amazonaws.services.dynamodbv2.document.utils.ValueMap import com.amazonaws.services.dynamodbv2.document.{DynamoDB => AwsDynamoDB, _} -import com.amazonaws.services.dynamodbv2.model.{AttributeValue, DeleteItemRequest, KeysAndAttributes, ReturnValue} +import com.amazonaws.services.dynamodbv2.model.{AttributeValue, KeysAndAttributes, ReturnValue} import com.amazonaws.services.dynamodbv2.{AmazonDynamoDBAsync, AmazonDynamoDBAsyncClientBuilder} import com.gu.mediaservice.lib.config.CommonConfig import com.gu.mediaservice.lib.logging.GridLogging @@ -13,9 +13,8 @@ import org.joda.time.DateTime import play.api.libs.json._ import software.amazon.awssdk.enhanced.dynamodb._ import software.amazon.awssdk.enhanced.dynamodb.document.EnhancedDocument -import software.amazon.awssdk.enhanced.dynamodb.model +import software.amazon.awssdk.enhanced.dynamodb.model.GetItemEnhancedRequest import software.amazon.awssdk.services.dynamodb.DynamoDbClient -import software.amazon.awssdk.services.dynamodb.model.{UpdateItemRequest, AttributeValue => AttributeValueV2, ReturnValue => ReturnValueV2} import scala.annotation.tailrec import scala.concurrent.{ExecutionContext, Future} @@ -87,18 +86,10 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti s"REMOVE $key" ) - def removeKeyV2(id: String, key: String)(implicit ex: ExecutionContext) = Future{ - updateV2(id, s"Remove $key") - } def deleteItem(id: String)(implicit ex: ExecutionContext): Future[Unit] = Future { table.deleteItem(new DeleteItemSpec().withPrimaryKey(IdKey, id)) } - def deleteItemV2(id: String)(implicit ex: ExecutionContext): Future[Unit] = Future { - table2.deleteItem( - Key.builder().partitionValue(id).build() - ) - } def booleanGetV2(id: String, key: String) (implicit ex: ExecutionContext): Future[Boolean] = { getV2(id, key).map(_.getBoolean(key).booleanValue()) @@ -112,25 +103,11 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti new ValueMap().withBoolean(":value", value) ) - def booleanSetV2(id: String, key: String, value: Boolean) - (implicit ex: ExecutionContext): Future[JsObject] = Future { - updateV2( - id, - s"SET $key = :value", - AttributeValueV2.fromBool(value) - ) - } - def booleanSetOrRemove(id: String, key: String, value: Boolean) (implicit ex: ExecutionContext): Future[JsObject] = if (value) booleanSet(id, key, value) else removeKey(id, key) - def booleanSetOrRemoveV2(id: String, key: String, value: Boolean) - (implicit ex: ExecutionContext): Future[JsObject] = - if (value) booleanSetV2(id, key, value) - else removeKeyV2(id, key) - def stringSet(id: String, key: String, value: JsValue) (implicit ex: ExecutionContext): Future[JsObject] = update( @@ -139,10 +116,6 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti valueMapWithNullForEmptyString(Map(":value" -> value)) ) - def stringSetV2(id: String, key: String, value: String)(implicit ex: ExecutionContext): Future[JsObject] = Future { - updateV2(id, s"SET $key = :value", AttributeValueV2.fromS(value)) - } - def stringListSet(id: String, keyValues: (String, JsValue)*) (implicit ex: ExecutionContext): Future[JsObject] = { val keyValueMap = keyValues.toMap @@ -176,9 +149,6 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti new ValueMap().withStringSet(":value", value:_*) ) - def setAddV2(id: String, key: String, value: List[String])(implicit ex: ExecutionContext): Future[JsObject] = Future { - updateV2(id, s"ADD $key :value", AttributeValueV2.fromSs(value.asJava)) - } def batchGet(ids: List[String], attributeKey: String) (implicit ex: ExecutionContext, rjs: Reads[T]): Future[Map[String, T]] = { val keyChunkList = ids @@ -230,15 +200,6 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti new ValueMap().withMap(":value", valueMapWithNullForEmptyString(value)) ) - def jsonAddV2(id: String, key: String, value: Map[String, JsValue]) - (implicit ex: ExecutionContext): Future[JsObject] = Future { - updateV2( - id, - s"SET $key = :value", - AttributeValueV2.fromM(value.view.mapValues(DynamoDB.jsonToAttributeValue).toMap.asJava) - ) - } - def setDelete(id: String, key: String, value: String) (implicit ex: ExecutionContext): Future[JsObject] = update( @@ -247,12 +208,6 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti new ValueMap().withStringSet(":value", value) ) - def setDeleteV2(id: String, key: String, value: String) - (implicit ex: ExecutionContext): Future[JsObject] = Future { - updateV2(id, s"DELETE $key :value", AttributeValueV2.fromSs(List(value).asJava)) - - } - def listAdd(id: String, key: String, value: T) (implicit ex: ExecutionContext, tjs: Writes[T], rjs: Reads[T]): Future[List[T]] = { @@ -309,30 +264,6 @@ class DynamoDB[T](config: CommonConfig, tableName: String, lastModifiedKey: Opti items map (a => a.getString("id")) } - private def updateRequestBuilder(id: String, expression: String) = { - UpdateItemRequest.builder() - .key(Map(IdKey -> AttributeValueV2.fromS(id)).asJava) - .updateExpression(expression) - .returnValues(ReturnValueV2.ALL_NEW) - .tableName(tableName) - } - - def updateV2(id: String, expression: String, attribute: AttributeValueV2) = { - val updateRequest = updateRequestBuilder(id, expression) - .expressionAttributeValues(Map(":value" -> attribute).asJava) - .build() - val updateItemResponse = client2.updateItem(updateRequest) - val jsonString = EnhancedDocument.fromAttributeValueMap(updateItemResponse.attributes()).toJson - Json.parse(jsonString).as[JsObject] - } - - def updateV2(id: String, expression: String) = { - val updateRequest = updateRequestBuilder(id, expression).build() - val updateItemResponse = client2.updateItem(updateRequest) - val jsonString = EnhancedDocument.fromAttributeValueMap(updateItemResponse.attributes()).toJson - Json.parse(jsonString).as[JsObject] - } - def update(id: String, expression: String, valueMap: ValueMap) (implicit ex: ExecutionContext): Future[JsObject] = update(id, expression, Some(valueMap)) @@ -412,20 +343,6 @@ object DynamoDB { } valueMap } - - def jsonToAttributeValue(json: JsValue): AttributeValueV2 = { - json match { - case JsString(v) => AttributeValueV2.fromS(v) - case JsBoolean(b) => AttributeValueV2.fromBool(b) - case JsTrue => AttributeValueV2.fromBool(true) - case JsFalse => AttributeValueV2.fromBool(false) - case JsNumber(n) => AttributeValueV2.fromN(n.toString()) - case JsNull => AttributeValueV2.fromNul(true) - case JsObject(obj) => AttributeValueV2.fromM(obj.view.mapValues(s => jsonToAttributeValue(s)).toMap.asJava) - case JsArray(arr) => AttributeValueV2.fromL(arr.toList.map(jsonToAttributeValue).asJava) - } - } - def caseClassToMap[T](caseClass: T)(implicit tjs: Writes[T]): Map[String, JsValue] = Json.toJson[T](caseClass).as[JsObject].as[Map[String, JsValue]] diff --git a/metadata-editor/app/controllers/EditsController.scala b/metadata-editor/app/controllers/EditsController.scala index 44be486d4c1..bacf11f7ab3 100644 --- a/metadata-editor/app/controllers/EditsController.scala +++ b/metadata-editor/app/controllers/EditsController.scala @@ -100,14 +100,14 @@ class EditsController( errors => Future.successful(BadRequest(errors.toString())), archived => - editsStore.booleanSetOrRemoveV2(id, "archived", archived) + editsStore.booleanSetOrRemove(id, "archived", archived) .map(publish(id, UpdateImageUserMetadata)) .map(edits => respond(edits.archived)) ) } def unsetArchived(id: String) = auth.async { - editsStore.removeKeyV2(id, Edits.Archived) + editsStore.removeKey(id, Edits.Archived) .map(publish(id, UpdateImageUserMetadata)) .map(_ => respond(false)) } @@ -127,7 +127,7 @@ class EditsController( Future.successful(BadRequest(errors.toString())), labels => editsStore - .setAddV2(id, Edits.Labels, labels) + .setAdd(id, Edits.Labels, labels) .map(publish(id, UpdateImageUserMetadata)) .map(edits => labelsCollection(id, edits.labels.toSet)) .map { case (uri, l) => respondCollection(l) } recover { @@ -137,7 +137,7 @@ class EditsController( } def removeLabel(id: String, label: String) = auth.async { - editsStore.setDeleteV2(id, Edits.Labels, decodeUriParam(label)) + editsStore.setDelete(id, Edits.Labels, decodeUriParam(label)) .map(publish(id, UpdateImageUserMetadata)) .map(edits => labelsCollection(id, edits.labels.toSet)) .map {case (uri, labels) => respondCollection(labels, uri=Some(uri))} @@ -168,7 +168,7 @@ class EditsController( }) val validatedMetadata = metadata.copy(domainMetadata = validatedDomainMetadata) - editsStore.jsonAddV2(id, Edits.Metadata, metadataAsMap(validatedMetadata)) + editsStore.jsonAdd(id, Edits.Metadata, metadataAsMap(validatedMetadata)) .map(publish(id, UpdateImageUserMetadata)) .map(edits => respond(edits.metadata)) } @@ -191,7 +191,7 @@ class EditsController( imageType = metadata.imageType orElse originalUserMetadata.imageType ) - editsStore.jsonAddV2(id, Edits.Metadata, metadataAsMap(mergedMetadata)) + editsStore.jsonAdd(id, Edits.Metadata, metadataAsMap(mergedMetadata)) .map(publish(id, UpdateImageUserMetadata)) .map(edits => respond(edits.metadata, uri = Some(metadataUri(id)))) } getOrElse { @@ -216,17 +216,18 @@ class EditsController( def setUsageRights(id: String) = auth.async(parse.json) { req => (req.body \ "data").asOpt[UsageRights].map(usageRight => { - editsStore.jsonAddV2(id, Edits.UsageRights, DynamoDB.caseClassToMap(usageRight)) + editsStore.jsonAdd(id, Edits.UsageRights, DynamoDB.caseClassToMap(usageRight)) .map(publish(id, UpdateImageUserMetadata)) .map(_ => respond(usageRight)) }).getOrElse(Future.successful(respondError(BadRequest, "invalid-form-data", "Invalid form data"))) } - //TODO - remove as a second step def deleteUsageRights(id: String) = auth.async { req => - editsStore.removeKeyV2(id, Edits.UsageRights).map(publish(id, UpdateImageUserMetadata)).map(edits => Accepted) + editsStore.removeKey(id, Edits.UsageRights).map(publish(id, UpdateImageUserMetadata)).map(edits => Accepted) } + + private def labelsCollection(id: String, labels: Set[String]): (URI, Seq[EmbeddedEntity[String]]) = (labelsUri(id), labels.map(setUnitEntity(id, Edits.Labels, _)).toSeq) diff --git a/metadata-editor/app/lib/Syndication.scala b/metadata-editor/app/lib/Syndication.scala index d8a6f767fbf..3e1ec4e3e62 100644 --- a/metadata-editor/app/lib/Syndication.scala +++ b/metadata-editor/app/lib/Syndication.scala @@ -58,8 +58,8 @@ trait Syndication extends Edit with MessageSubjects with GridLogging { (implicit ec: ExecutionContext): Future[Photoshoot] = { publishChangedSyndicationRightsForPhotoshoot[Photoshoot](id, photoshoot = Some(newPhotoshoot)) { () => for { - editsAsJsonResponse <- editsStore.jsonAddV2(id, Edits.Photoshoot, DynamoDB.caseClassToMap(newPhotoshoot)) - _ <- editsStore.stringSetV2(id, Edits.PhotoshootTitle, newPhotoshoot.title) // store - don't care about return + editsAsJsonResponse <- editsStore.jsonAdd(id, Edits.Photoshoot, DynamoDB.caseClassToMap(newPhotoshoot)) + _ <- editsStore.stringSet(id, Edits.PhotoshootTitle, JsString(newPhotoshoot.title)) // store - don't care about return _ = publish(id, UpdateImagePhotoshootMetadata)(editsAsJsonResponse) } yield newPhotoshoot } @@ -68,7 +68,7 @@ trait Syndication extends Edit with MessageSubjects with GridLogging { def deleteSyndicationAndPublish(id: String) (implicit ec: ExecutionContext): Future[Unit] = { publishChangedSyndicationRightsForPhotoshoot[Unit](id, unchangedPhotoshoot = true) { () => - syndicationStore.deleteItemV2(id) + syndicationStore.deleteItem(id) // Always publish, in case there is no photoshoot publish(Map(id -> None), UpdateImageSyndicationMetadata) } @@ -77,7 +77,7 @@ trait Syndication extends Edit with MessageSubjects with GridLogging { def setSyndicationAndPublish(id: String, syndicationRight: SyndicationRights) (implicit ec: ExecutionContext): Future[SyndicationRights] = publishChangedSyndicationRightsForPhotoshoot[SyndicationRights](id, unchangedPhotoshoot = true) { () => - val result = syndicationStore.jsonAddV2(id, syndicationRightsFieldName, DynamoDB.caseClassToMap (syndicationRight)).map(_=>syndicationRight) + val result = syndicationStore.jsonAdd (id, syndicationRightsFieldName, DynamoDB.caseClassToMap (syndicationRight)).map(_=>syndicationRight) // Always publish, in case there is no photoshoot publish(Map(id -> Some(syndicationRight)), UpdateImageSyndicationMetadata) result From ca825a3ae0d3d5911e2bef5190e09fe7ed3d9d81 Mon Sep 17 00:00:00 2001 From: Ellen Muller Date: Tue, 13 Jan 2026 17:48:48 +0000 Subject: [PATCH 067/494] redo commit --- .github/workflows/ci.yml | 8 +- cdk/bin/cdk.ts | 6 +- cdk/lib/image-embedder-lambda.test.ts | 4 +- cdk/lib/image-embedder-lambda.ts | 2 +- image-embedder-lambda/src/index.ts | 5 - image-embedder.zip | Bin 294594 -> 0 bytes kahuna/package-lock.json | 353 +++++++++++++++++++++++++- kahuna/package.json | 2 +- s3watcher/lambda/package-lock.json | 12 +- 9 files changed, 364 insertions(+), 28 deletions(-) delete mode 100644 image-embedder.zip diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 255bdac9776..26d4204e143 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,6 +41,8 @@ jobs: uses: actions/setup-node@v6 with: node-version-file: ".nvmrc" + cache: npm + cache-dependency-path: "cdk/package-lock.json" - name: Kahuna (client-side) working-directory: ./kahuna run: | @@ -72,12 +74,6 @@ jobs: npm install-clean npm test npm run build - # Node is needed for CDK - - uses: actions/setup-node@v3 - with: - node-version-file: ".nvmrc" - cache: npm - cache-dependency-path: "cdk/package-lock.json" - name: Image embedder cdk run: ./scripts/embedder-deploy/cdk.sh - name: Image embedder bundling diff --git a/cdk/bin/cdk.ts b/cdk/bin/cdk.ts index 27a93d21270..56d5ed58e68 100644 --- a/cdk/bin/cdk.ts +++ b/cdk/bin/cdk.ts @@ -1,7 +1,7 @@ import "source-map-support/register"; import { GuRoot } from "@guardian/cdk/lib/constructs/root"; -import { MediaService } from "../lib/image-embedder-lambda"; +import { ImageEmbedder } from "../lib/image-embedder-lambda"; const app = new GuRoot(); -new MediaService(app, "ImageEmbedderLambda-euwest-1-PROD", { stack: "media-service", stage: "PROD", env: { region: "eu-west-1" } }); -new MediaService(app, "ImageEmbedderLambda-euwest-1-TEST", { stack: "media-service", stage: "TEST", env: { region: "eu-west-1" } }); +new ImageEmbedder(app, "ImageEmbedderLambda-euwest-1-PROD", { stack: "media-service", stage: "PROD", env: { region: "eu-west-1" } }); +new ImageEmbedder(app, "ImageEmbedderLambda-euwest-1-TEST", { stack: "media-service", stage: "TEST", env: { region: "eu-west-1" } }); diff --git a/cdk/lib/image-embedder-lambda.test.ts b/cdk/lib/image-embedder-lambda.test.ts index 28aed1e88e7..32d75e61bff 100644 --- a/cdk/lib/image-embedder-lambda.test.ts +++ b/cdk/lib/image-embedder-lambda.test.ts @@ -1,11 +1,11 @@ import { App } from "aws-cdk-lib"; import { Template } from "aws-cdk-lib/assertions"; -import { MediaService } from "./image-embedder-lambda"; +import { ImageEmbedder } from "./image-embedder-lambda"; describe("The MediaService stack", () => { it("matches the snapshot", () => { const app = new App(); - const stack = new MediaService(app, "ImageEmbedderLambda", { stack: "media-service", stage: "TEST" }); + const stack = new ImageEmbedder(app, "ImageEmbedderLambda", { stack: "media-service", stage: "TEST" }); const template = Template.fromStack(stack); expect(template.toJSON()).toMatchSnapshot(); }); diff --git a/cdk/lib/image-embedder-lambda.ts b/cdk/lib/image-embedder-lambda.ts index 7e70e29b0bb..9063dd4ec72 100644 --- a/cdk/lib/image-embedder-lambda.ts +++ b/cdk/lib/image-embedder-lambda.ts @@ -8,7 +8,7 @@ import { Architecture } from "aws-cdk-lib/aws-lambda"; import { SqsEventSource } from "aws-cdk-lib/aws-lambda-event-sources"; import { Queue } from "aws-cdk-lib/aws-sqs"; -export class MediaService extends GuStack { +export class ImageEmbedder extends GuStack { constructor(scope: App, id: string, props: GuStackProps) { super(scope, id, props); diff --git a/image-embedder-lambda/src/index.ts b/image-embedder-lambda/src/index.ts index 0011432f910..8b0462b1229 100644 --- a/image-embedder-lambda/src/index.ts +++ b/image-embedder-lambda/src/index.ts @@ -32,11 +32,6 @@ async function getImageFromS3( try { const command = new GetObjectCommand(input); const response: GetObjectCommandOutput = await client.send(command); - - if (!response) { - console.log(`Returning undefined: no response object`); - return undefined; - } console.log(`S3 response metadata: ${JSON.stringify(response.$metadata)}`); diff --git a/image-embedder.zip b/image-embedder.zip deleted file mode 100644 index e280e85d188b050357eb523202b5161475f9350a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 294594 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%0DV*Z#IbMJF^mU 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%0D3@$za6ccz47=X-p%Bn9nVMa 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