feat: image blur hash (#2010)

* feat: image blur hash

Signed-off-by: Innei <i@innei.in>

* fix: split util

Signed-off-by: Innei <i@innei.in>

* feat: refresh image

Signed-off-by: Innei <i@innei.in>

* fix: add logger

Signed-off-by: Innei <i@innei.in>

* chore: cleanup

Signed-off-by: Innei <i@innei.in>

* fix: update

Signed-off-by: Innei <i@innei.in>

---------

Signed-off-by: Innei <i@innei.in>
This commit is contained in:
Innei
2024-08-16 15:20:22 +08:00
committed by GitHub
parent 5d335fcf3f
commit c27ee8c28d
56 changed files with 507 additions and 332 deletions

View File

@@ -48,6 +48,7 @@
},
"dependencies": {
"@algolia/client-search": "^4.22.1",
"@antfu/install-pkg": "0.3.5",
"@aws-sdk/client-s3": "3.632.0",
"@babel/core": "7.25.2",
"@babel/plugin-transform-modules-commonjs": "7.24.8",
@@ -81,6 +82,7 @@
"axios": "^1.7.0",
"axios-retry": "4.5.0",
"bcryptjs": "^2.4.3",
"blurhash": "2.0.5",
"cache-manager": "5.7.6",
"cache-manager-ioredis-yet": "2.1.1",
"class-transformer": "0.5.1",
@@ -91,8 +93,6 @@
"dayjs": "1.11.12",
"ejs": "3.1.10",
"form-data": "4.0.0",
"get-image-colors": "4.0.1",
"image-size": "1.1.1",
"inquirer": "^10.1.0",
"isbot": "5.1.16",
"js-yaml": "^4.1.0",
@@ -158,6 +158,7 @@
"cron": "^3.1.6",
"husky": "9.1.4",
"ioredis": "5.4.1",
"sharp": "0.33.4",
"socket.io": "^4.7.4",
"unplugin-swc": "1.5.1",
"vite": "5.1.7",

View File

@@ -5,7 +5,7 @@ import FastifyMultipart from '@fastify/multipart'
import { Logger } from '@nestjs/common'
import { FastifyAdapter } from '@nestjs/platform-fastify'
import { getIp } from '~/utils'
import { getIp } from '~/utils/ip.util'
const app: FastifyAdapter = new FastifyAdapter({
trustProxy: true,

View File

@@ -3,7 +3,7 @@ import type { Observable } from 'rxjs'
import { applyDecorators, UseGuards } from '@nestjs/common'
import { banInDemo } from '~/utils'
import { banInDemo } from '~/utils/biz.util'
class DemoGuard implements CanActivate {
canActivate(): boolean | Promise<boolean> | Observable<boolean> {

View File

@@ -5,7 +5,7 @@ import { Injectable } from '@nestjs/common'
import { ThrottlerGuard } from '@nestjs/throttler'
import { getNestExecutionContextRequest } from '~/transformers/get-req.transformer'
import { getIp } from '~/utils'
import { getIp } from '~/utils/ip.util'
@Injectable()
export class ExtendThrottlerGuard extends ThrottlerGuard {

View File

@@ -26,9 +26,9 @@ import { OptionModel } from '~/modules/configs/configs.model'
import { CacheService } from '~/processors/redis/cache.service'
import { getNestExecutionContextRequest } from '~/transformers/get-req.transformer'
import { InjectModel } from '~/transformers/model.transformer'
import { scheduleManager } from '~/utils'
import { getIp } from '~/utils/ip.util'
import { getRedisKey } from '~/utils/redis.util'
import { scheduleManager } from '~/utils/schedule.util'
@Injectable()
export class AnalyzeInterceptor implements NestInterceptor {

View File

@@ -23,7 +23,7 @@ import * as META from '~/constants/meta.constant'
import * as SYSTEM from '~/constants/system.constant'
import { CacheService } from '~/processors/redis/cache.service'
import { getNestExecutionContextRequest } from '~/transformers/get-req.transformer'
import { hashString } from '~/utils'
import { hashString } from '~/utils/tool.util'
/**
* @class HttpCacheInterceptor

View File

@@ -20,7 +20,9 @@ import {
} from '~/constants/meta.constant'
import { REFLECTOR } from '~/constants/system.constant'
import { CacheService } from '~/processors/redis/cache.service'
import { getIp, getRedisKey, hashString } from '~/utils'
import { getIp } from '~/utils/ip.util'
import { getRedisKey } from '~/utils/redis.util'
import { hashString } from '~/utils/tool.util'
const IdempotenceHeaderKey = 'x-idempotence'

View File

@@ -2,7 +2,6 @@ import { createLogger, Logger } from '@innei/pretty-logger-nestjs'
import { LOG_DIR } from '~/constants/path.constant'
import { redisSubPub } from '../utils/redis-subpub.util'
import { isTest } from './env.global'
const logger = createLogger({
@@ -19,6 +18,7 @@ if (!isTest) {
logger.warn('wrap console failed')
}
logger.onData((data) => {
const { redisSubPub } = require('../utils/redis-subpub.util')
redisSubPub.publish('log', data)
})
}

View File

@@ -1,7 +1,5 @@
import cluster from 'node:cluster'
import { parseBooleanishValue } from '~/utils/tool.util'
export const isMainCluster =
process.env.NODE_APP_INSTANCE &&
Number.parseInt(process.env.NODE_APP_INSTANCE) === 0
@@ -10,5 +8,5 @@ export const isMainProcess = cluster.isPrimary || isMainCluster
export const isDev = process.env.NODE_ENV == 'development'
export const isTest = !!process.env.TEST
export const isDebugMode = parseBooleanishValue(process.env.DEBUG_MODE) || false
export const isDebugMode = process.env.DEBUG_MODE === '1'
export const cwd = process.cwd()

View File

@@ -1,5 +1,4 @@
import { Module } from '@nestjs/common'
import { DiscoveryModule } from '@nestjs/core'
import { ExtendedValidationPipe } from '~/common/pipes/validation.pipe'
import { VALIDATION_PIPE_INJECTION } from '~/constants/system.constant'
@@ -8,7 +7,7 @@ import { AckController } from './ack.controller'
@Module({
controllers: [AckController],
imports: [DiscoveryModule],
providers: [
{
provide: VALIDATION_PIPE_INJECTION,

View File

@@ -36,7 +36,7 @@ import { CountingService } from '~/processors/helper/helper.counting.service'
import { EventManagerService } from '~/processors/helper/helper.event.service'
import { InjectModel } from '~/transformers/model.transformer'
import { transformDataToPaginate } from '~/transformers/paginate.transformer'
import { checkRefModelCollectionType } from '~/utils'
import { checkRefModelCollectionType } from '~/utils/biz.util'
import { CommentState } from '../comment/comment.model'
import { CommentService } from '../comment/comment.service'

View File

@@ -13,7 +13,7 @@ import { DatabaseService } from '~/processors/database/database.service'
import { CacheService } from '~/processors/redis/cache.service'
import { InjectModel } from '~/transformers/model.transformer'
import { transformDataToPaginate } from '~/transformers/paginate.transformer'
import { md5 } from '~/utils'
import { md5 } from '~/utils/tool.util'
import { ConfigsService } from '../../configs/configs.service'
import { DEFAULT_SUMMARY_LANG, LANGUAGE_CODE_TO_NAME } from '../ai.constants'

View File

@@ -23,7 +23,7 @@ import { RequestContext } from '~/common/contexts/request.context'
import { RedisKeys } from '~/constants/cache.constant'
import { CacheService } from '~/processors/redis/cache.service'
import { InjectModel } from '~/transformers/model.transformer'
import { getRedisKey } from '~/utils'
import { getRedisKey } from '~/utils/redis.util'
import { ConfigsService } from '../configs/configs.service'
import { AuthnModel } from './authn.model'

View File

@@ -22,8 +22,8 @@ import { HTTPDecorators } from '~/common/decorators/http.decorator'
import { BizException } from '~/common/exceptions/biz.exception'
import { ErrorCodeEnum } from '~/constants/error-code.constant'
import { UploadService } from '~/processors/helper/helper.upload.service'
import { getMediumDateTime } from '~/utils'
import { isZipMinetype } from '~/utils/mine.util'
import { getMediumDateTime } from '~/utils/time.util'
import { BackupService } from './backup.service'

View File

@@ -26,8 +26,9 @@ import { BACKUP_DIR, DATA_DIR } from '~/constants/path.constant'
import { migrateDatabase } from '~/migration/migrate'
import { EventManagerService } from '~/processors/helper/helper.event.service'
import { CacheService } from '~/processors/redis/cache.service'
import { getMediumDateTime, scheduleManager } from '~/utils'
import { scheduleManager } from '~/utils/schedule.util'
import { getFolderSize, installPKG } from '~/utils/system.util'
import { getMediumDateTime } from '~/utils/time.util'
import { ConfigsService } from '../configs/configs.service'

View File

@@ -18,7 +18,7 @@ import { BusinessEvents, EventScope } from '~/constants/business-event.constant'
import { EventBusEvents } from '~/constants/event-bus.constant'
import { EventManagerService } from '~/processors/helper/helper.event.service'
import { InjectModel } from '~/transformers/model.transformer'
import { scheduleManager } from '~/utils'
import { scheduleManager } from '~/utils/schedule.util'
import { PostService } from '../post/post.service'
import { SlugTrackerService } from '../slug-tracker/slug-tracker.service'

View File

@@ -31,7 +31,7 @@ import { EventManagerService } from '~/processors/helper/helper.event.service'
import { MongoIdDto } from '~/shared/dto/id.dto'
import { PagerDto } from '~/shared/dto/pager.dto'
import { transformDataToPaginate } from '~/transformers/paginate.transformer'
import { scheduleManager } from '~/utils'
import { scheduleManager } from '~/utils/schedule.util'
import { ConfigsService } from '../configs/configs.service'
import { UserModel } from '../user/user.model'

View File

@@ -10,7 +10,7 @@ import type {
import { Injectable } from '@nestjs/common'
import { getNestExecutionContextRequest } from '~/transformers/get-req.transformer'
import { getAvatar } from '~/utils'
import { getAvatar } from '~/utils/tool.util'
@Injectable()
export class CommentFilterEmailInterceptor implements NestInterceptor {

View File

@@ -29,7 +29,8 @@ import { BarkPushService } from '~/processors/helper/helper.bark.service'
import { EmailService } from '~/processors/helper/helper.email.service'
import { EventManagerService } from '~/processors/helper/helper.event.service'
import { InjectModel } from '~/transformers/model.transformer'
import { getAvatar, hasChinese, scheduleManager } from '~/utils'
import { scheduleManager } from '~/utils/schedule.util'
import { getAvatar, hasChinese } from '~/utils/tool.util'
import { ConfigsService } from '../configs/configs.service'
import { createMockedContextResponse } from '../serverless/mock-response.util'

View File

@@ -23,8 +23,8 @@ import { EventManagerService } from '~/processors/helper/helper.event.service'
import { CacheService } from '~/processors/redis/cache.service'
import { SubPubBridgeService } from '~/processors/redis/subpub.service'
import { InjectModel } from '~/transformers/model.transformer'
import { camelcaseKeys, sleep } from '~/utils'
import { getRedisKey } from '~/utils/redis.util'
import { camelcaseKeys } from '~/utils/tool.util'
import { generateDefaultConfig } from './configs.default'
import { decryptObject, encryptObject } from './configs.encrypt.util'

View File

@@ -7,7 +7,7 @@ import { ApiController } from '~/common/decorators/api-controller.decorator'
import { Auth } from '~/common/decorators/auth.decorator'
import { HTTPDecorators } from '~/common/decorators/http.decorator'
import { DATA_DIR } from '~/constants/path.constant'
import { installPKG } from '~/utils'
import { installPKG } from '~/utils/system.util'
import { ServerlessService } from '../serverless/serverless.service'

View File

@@ -7,7 +7,7 @@ import { Controller, Get, Header } from '@nestjs/common'
import { HTTPDecorators } from '~/common/decorators/http.decorator'
import { CacheKeys } from '~/constants/cache.constant'
import { escapeXml } from '~/utils'
import { escapeXml } from '~/utils/tool.util'
import { AggregateService } from '../aggregate/aggregate.service'
import { ConfigsService } from '../configs/configs.service'

View File

@@ -15,8 +15,8 @@ import { Auth } from '~/common/decorators/auth.decorator'
import { HTTPDecorators } from '~/common/decorators/http.decorator'
import { LOG_DIR } from '~/constants/path.constant'
import { AdapterResponse } from '~/types/request'
import { formatByteSize } from '~/utils'
import { getTodayLogFilePath } from '~/utils/path.util'
import { formatByteSize } from '~/utils/system.util'
import { LogQueryDto, LogTypeDto } from '../health.dto'

View File

@@ -1,13 +1,27 @@
import { FastifyReply } from 'fastify'
import { BadRequestException, Get, Param, Query, Res } from '@nestjs/common'
import {
BadRequestException,
Get,
Param,
Post,
Query,
Res,
} from '@nestjs/common'
import { ModuleRef } from '@nestjs/core'
import { ApiController } from '~/common/decorators/api-controller.decorator'
import { Auth } from '~/common/decorators/auth.decorator'
import { CollectionRefTypes } from '~/constants/db.constant'
import { DatabaseService } from '~/processors/database/database.service'
import { ImageService } from '~/processors/helper/helper.image.service'
import { UrlBuilderService } from '~/processors/helper/helper.url-builder.service'
import { MongoIdDto } from '~/shared/dto/id.dto'
import { AsyncQueue } from '~/utils/queue.util'
import { NoteService } from '../note/note.service'
import { PageService } from '../page/page.service'
import { PostService } from '../post/post.service'
import { HelperService } from './helper.service'
@ApiController('helper')
@@ -17,6 +31,8 @@ export class HelperController {
private readonly urlBulderService: UrlBuilderService,
private readonly databaseService: DatabaseService,
private readonly moduleRef: ModuleRef,
) {}
@Get('/url-builder/:id')
@@ -46,4 +62,31 @@ export class HelperController {
res.send({ data: url })
}
}
@Post('/refresh-images')
@Auth()
async refreshImages() {
const postService = this.moduleRef.get(PostService, { strict: false })
const noteService = this.moduleRef.get(NoteService, { strict: false })
const pageService = this.moduleRef.get(PageService, { strict: false })
const imageService = this.moduleRef.get(ImageService, { strict: false })
const post = await postService.model.find()
const notes = await noteService.model.find()
const pages = await pageService.model.find()
const q = new AsyncQueue(10)
q.addMultiple(
[...post, ...notes, ...pages].map(
(doc) => () =>
imageService.saveImageDimensionsFromMarkdownText(
doc.text,
doc.images,
(images) => {
doc.images = images
return doc.save()
},
),
),
)
}
}

View File

@@ -21,7 +21,7 @@ import {
BaseCrudFactory,
BaseCrudModuleType,
} from '~/transformers/crud-factor.transformer'
import { scheduleManager } from '~/utils'
import { scheduleManager } from '~/utils/schedule.util'
import { AuditReasonDto, LinkDto } from './link.dto'
import { LinkModel, LinkState } from './link.model'

View File

@@ -14,7 +14,7 @@ import { EmailService } from '~/processors/helper/helper.email.service'
import { EventManagerService } from '~/processors/helper/helper.event.service'
import { HttpService } from '~/processors/helper/helper.http.service'
import { InjectModel } from '~/transformers/model.transformer'
import { scheduleManager } from '~/utils'
import { scheduleManager } from '~/utils/schedule.util'
import { ConfigsService } from '../configs/configs.service'
import { UserService } from '../user/user.service'

View File

@@ -15,7 +15,8 @@ import { EventManagerService } from '~/processors/helper/helper.event.service'
import { ImageService } from '~/processors/helper/helper.image.service'
import { TextMacroService } from '~/processors/helper/helper.macro.service'
import { InjectModel } from '~/transformers/model.transformer'
import { getLessThanNow, scheduleManager } from '~/utils'
import { scheduleManager } from '~/utils/schedule.util'
import { getLessThanNow } from '~/utils/time.util'
import { getArticleIdFromRoomName } from '../activity/activity.util'
import { CommentService } from '../comment/comment.service'

View File

@@ -12,7 +12,7 @@ import { EventManagerService } from '~/processors/helper/helper.event.service'
import { ImageService } from '~/processors/helper/helper.image.service'
import { TextMacroService } from '~/processors/helper/helper.macro.service'
import { InjectModel } from '~/transformers/model.transformer'
import { scheduleManager } from '~/utils'
import { scheduleManager } from '~/utils/schedule.util'
import { PageModel } from './page.model'

View File

@@ -22,7 +22,8 @@ import { EventManagerService } from '~/processors/helper/helper.event.service'
import { ImageService } from '~/processors/helper/helper.image.service'
import { TextMacroService } from '~/processors/helper/helper.macro.service'
import { InjectModel } from '~/transformers/model.transformer'
import { getLessThanNow, scheduleManager } from '~/utils'
import { scheduleManager } from '~/utils/schedule.util'
import { getLessThanNow } from '~/utils/time.util'
import { getArticleIdFromRoomName } from '../activity/activity.util'
import { CategoryService } from '../category/category.service'

View File

@@ -17,7 +17,8 @@ import { DatabaseService } from '~/processors/database/database.service'
import { EventManagerService } from '~/processors/helper/helper.event.service'
import { CacheService } from '~/processors/redis/cache.service'
import { InjectModel } from '~/transformers/model.transformer'
import { getRedisKey, scheduleManager } from '~/utils'
import { getRedisKey } from '~/utils/redis.util'
import { scheduleManager } from '~/utils/schedule.util'
import { CommentState } from '../comment/comment.model'
import { CommentService } from '../comment/comment.service'

View File

@@ -23,7 +23,7 @@ import { HttpCache } from '~/common/decorators/cache.decorator'
import { HTTPDecorators } from '~/common/decorators/http.decorator'
import { IsAuthenticated } from '~/common/decorators/role.decorator'
import { MongoIdDto } from '~/shared/dto/id.dto'
import { getShortDateTime } from '~/utils'
import { getShortDateTime } from '~/utils/time.util'
import { ConfigsService } from '../configs/configs.service'
import { MarkdownPreviewDto } from '../markdown/markdown.dto'

View File

@@ -36,14 +36,12 @@ import { EventManagerService } from '~/processors/helper/helper.event.service'
import { HttpService } from '~/processors/helper/helper.http.service'
import { CacheService } from '~/processors/redis/cache.service'
import { InjectModel } from '~/transformers/model.transformer'
import {
getRedisKey,
safePathJoin,
safeProcessEnv,
scheduleManager,
} from '~/utils'
import { EncryptUtil } from '~/utils/encrypt.util'
import { getRedisKey } from '~/utils/redis.util'
import { safeEval } from '~/utils/safe-eval.util'
import { scheduleManager } from '~/utils/schedule.util'
import { safeProcessEnv } from '~/utils/system.util'
import { safePathJoin } from '~/utils/tool.util'
import { ConfigsService } from '../configs/configs.service'
import { SnippetModel, SnippetType } from '../snippet/snippet.model'

View File

@@ -18,7 +18,7 @@ import { EventBusEvents } from '~/constants/event-bus.constant'
import { EventManagerService } from '~/processors/helper/helper.event.service'
import { CacheService } from '~/processors/redis/cache.service'
import { InjectModel } from '~/transformers/model.transformer'
import { getRedisKey } from '~/utils'
import { getRedisKey } from '~/utils/redis.util'
import { ServerlessService } from '../serverless/serverless.service'
import { SnippetModel, SnippetType } from './snippet.model'

View File

@@ -19,7 +19,7 @@ import { EmailService } from '~/processors/helper/helper.email.service'
import { EventManagerService } from '~/processors/helper/helper.event.service'
import { UrlBuilderService } from '~/processors/helper/helper.url-builder.service'
import { InjectModel } from '~/transformers/model.transformer'
import { hashString, md5 } from '~/utils'
import { hashString, md5 } from '~/utils/tool.util'
import { ConfigsService } from '../configs/configs.service'
import { UserService } from '../user/user.service'

View File

@@ -18,7 +18,7 @@ import {
import { DatabaseService } from '~/processors/database/database.service'
import { EventManagerService } from '~/processors/helper/helper.event.service'
import { InjectModel } from '~/transformers/model.transformer'
import { md5 } from '~/utils'
import { md5 } from '~/utils/tool.util'
import { SyncableCollectionNames } from '../sync/sync.constant'
import { SyncUpdateModel } from './sync-update.model'

View File

@@ -17,7 +17,7 @@ import {
} from '~/constants/db.constant'
import { DatabaseService } from '~/processors/database/database.service'
import { InjectModel } from '~/transformers/model.transformer'
import { md5 } from '~/utils'
import { md5 } from '~/utils/tool.util'
import { CategoryService } from '../category/category.service'
import { NoteService } from '../note/note.service'

View File

@@ -9,7 +9,7 @@ import { Injectable } from '@nestjs/common'
import { dashboard } from '~/../package.json'
import { LOCAL_ADMIN_ASSET_PATH } from '~/constants/path.constant'
import { HttpService } from '~/processors/helper/helper.http.service'
import { spawnShell } from '~/utils'
import { spawnShell } from '~/utils/system.util'
import { ConfigsService } from '../configs/configs.service'

View File

@@ -24,7 +24,7 @@ import {
import { BanInDemo } from '~/common/decorators/demo.decorator'
import { IpLocation, IpRecord } from '~/common/decorators/ip.decorator'
import { IsAuthenticated } from '~/common/decorators/role.decorator'
import { getAvatar } from '~/utils'
import { getAvatar } from '~/utils/tool.util'
import { AuthService } from '../auth/auth.service'
import { AuthnService } from '../authn/authn.service'

View File

@@ -16,7 +16,7 @@ import {
} from '~/common/exceptions/biz.exception'
import { ErrorCodeEnum } from '~/constants/error-code.constant'
import { InjectModel } from '~/transformers/model.transformer'
import { getAvatar, sleep } from '~/utils'
import { getAvatar } from '~/utils/tool.util'
import { AuthService } from '../auth/auth.service'
import { UserModel } from './user.model'

View File

@@ -8,7 +8,8 @@ import type {
import { Injectable } from '@nestjs/common'
import { RedisKeys } from '~/constants/cache.constant'
import { getRedisKey, safeJSONParse } from '~/utils'
import { getRedisKey } from '~/utils/redis.util'
import { safeJSONParse } from '~/utils/tool.util'
import { CacheService } from '../redis/cache.service'

View File

@@ -24,8 +24,8 @@ import {
import { BusinessEvents } from '~/constants/business-event.constant'
import { RedisKeys } from '~/constants/cache.constant'
import { CacheService } from '~/processors/redis/cache.service'
import { scheduleManager } from '~/utils'
import { getRedisKey } from '~/utils/redis.util'
import { scheduleManager } from '~/utils/schedule.util'
import { getShortDate } from '~/utils/time.util'
import { BroadcastBaseGateway } from '../base.gateway'

View File

@@ -5,7 +5,7 @@ import { Injectable, Logger } from '@nestjs/common'
import { EventEmitter2 } from '@nestjs/event-emitter'
import { BusinessEvents, EventScope } from '~/constants/business-event.constant'
import { scheduleManager } from '~/utils'
import { scheduleManager } from '~/utils/schedule.util'
import { AdminEventsGateway } from '../gateway/admin/events.gateway'
import { BroadcastBaseGateway } from '../gateway/base.gateway'

View File

@@ -7,7 +7,7 @@ import { Injectable, Logger } from '@nestjs/common'
import { AXIOS_CONFIG, DEBUG_MODE } from '~/app.config'
import { RedisKeys } from '~/constants/cache.constant'
import { getRedisKey } from '~/utils'
import { getRedisKey } from '~/utils/redis.util'
import { version } from '../../../package.json'
import { CacheService } from '../redis/cache.service'

View File

@@ -1,10 +1,12 @@
import imageSize from 'image-size'
import { encode } from 'blurhash'
import sharpTypes from 'sharp'
import type { ImageModel } from '~/shared/model/image.model'
import { Injectable, Logger } from '@nestjs/common'
import { ConfigsService } from '~/modules/configs/configs.service'
import { getAverageRGB, pickImagesFromMarkdown } from '~/utils/pic.util'
import { pickImagesFromMarkdown } from '~/utils/pic.util'
import { requireDepsWithInstall } from '~/utils/tool.util'
import { HttpService } from './helper.http.service'
@@ -16,6 +18,12 @@ export class ImageService {
private readonly configsService: ConfigsService,
) {
this.logger = new Logger(ImageService.name)
if (!isDev) {
requireDepsWithInstall('sharp').catch((error: any) => {
this.logger.error(`sharp install failed: ${error.message}`)
})
}
}
async saveImageDimensionsFromMarkdownText(
@@ -40,7 +48,7 @@ export class ImageService {
if (
originImage &&
originImage.src === src &&
['height', 'width', 'type', 'accent'].every(
['height', 'width', 'type', 'accent', 'blurHash'].every(
(key) => keys.has(key) && originImage[key],
)
) {
@@ -50,13 +58,13 @@ export class ImageService {
const promise = new Promise<ImageModel>((resolve) => {
this.logger.log(`Get --> ${src}`)
this.getOnlineImageSizeAndMeta(src)
.then(({ size, accent }) => {
.then(({ size, accent, blurHash }) => {
const filename = src.split('/').pop()
this.logger.debug(
`[${filename}]: height: ${size.height}, width: ${size.width}, accent: ${accent}`,
)
resolve({ ...size, accent, src })
resolve({ ...size, accent, src, blurHash })
})
.catch((error) => {
this.logger.error(`GET --> ${src} ${error.message}`)
@@ -71,6 +79,7 @@ export class ImageService {
type: undefined,
accent: undefined,
src: undefined,
blurHash: undefined,
})
})
})
@@ -110,11 +119,35 @@ export class ImageService {
const imageType = headers['content-type']!
const buffer = Buffer.from(data)
const size = imageSize(buffer)
const sharp = (await requireDepsWithInstall('sharp')) as typeof sharpTypes
const sharped = sharp(buffer)
const metadata = await sharped.metadata()
const size = {
height: metadata.height,
width: metadata.width,
type: imageType,
}
const { dominant } = await sharped.stats()
// get accent color
const accent = await getAverageRGB(buffer, imageType)
// r g b number to hex
const accent = `#${dominant.r.toString(16).padStart(2, '0')}${dominant.g.toString(16).padStart(2, '0')}${dominant.b.toString(16).padStart(2, '0')}`
return { size, accent }
const blurHash = await encodeImageToBlurhash(sharped)
return { size, accent, blurHash }
}
}
const encodeImageToBlurhash = (sharped: sharpTypes.Sharp) =>
new Promise<string>((resolve, reject) => {
sharped
.raw()
.ensureAlpha()
.resize(32, 32, { fit: 'inside' })
.toBuffer((err, buffer, { width, height }) => {
if (err) return reject(err)
resolve(encode(new Uint8ClampedArray(buffer), width, height, 4, 4))
})
})

View File

@@ -6,7 +6,8 @@ import { Injectable } from '@nestjs/common'
import { CLUSTER, ENCRYPT, SECURITY } from '~/app.config'
import { RedisKeys } from '~/constants/cache.constant'
import { logger } from '~/global/consola.global'
import { getRedisKey, md5 } from '~/utils'
import { getRedisKey } from '~/utils/redis.util'
import { md5 } from '~/utils/tool.util'
import { CacheService } from '../redis/cache.service'

View File

@@ -4,12 +4,12 @@ import { BadRequestException, Injectable, Logger } from '@nestjs/common'
import { RequestContext } from '~/common/contexts/request.context'
import { ConfigsService } from '~/modules/configs/configs.service'
import { deepCloneWithFunction } from '~/utils'
import { safeEval } from '~/utils/safe-eval.util'
import { deepCloneWithFunction } from '~/utils/tool.util'
const RegMap = {
'#': /^#(.*?)$/g,
$: /^\$(.*?)$/g,
'#': /^#(.*)$/g,
$: /^\$(.*)$/g,
'?': /^\?\??(.*?)\??\?$/g,
} as const
@@ -114,7 +114,7 @@ export class TextMacroService {
return text
}
try {
const matchedReg = /\[\[\s(.*?)\s]]/g
const matchedReg = /\[\[\s(.*?)\s\]\]/g
const matched = text.search(matchedReg) != -1

View File

@@ -3,7 +3,7 @@ import type { Redis } from 'ioredis'
import { Injectable } from '@nestjs/common'
import { safeJSONParse } from '~/utils'
import { safeJSONParse } from '~/utils/tool.util'
import { CacheService } from '../redis/cache.service'

View File

@@ -36,4 +36,9 @@ export abstract class ImageModel {
@IsOptional()
@IsUrl()
src?: string
@prop()
@IsOptional()
@IsString()
blurHash?: string
}

View File

@@ -1,9 +0,0 @@
export * from './ip.util'
export * from './jsonschema.util'
export * from './pic.util'
export * from './redis.util'
export * from './system.util'
export * from './time.util'
export * from './tool.util'
export * from './biz.util'
export * from './schedule.util'

View File

@@ -1,4 +1,3 @@
import getColors from 'get-image-colors'
import { marked } from 'marked'
const isVideoExts = ['.mp4', '.webm', '.ogg', '.mov', '.avi', '.flv', '.mkv']
@@ -25,25 +24,6 @@ export const pickImagesFromMarkdown = (text: string) => {
return images
}
export async function getAverageRGB(
buffer: Buffer,
type: string,
): Promise<string | undefined> {
if (!buffer) {
return undefined
}
try {
// NOTE: can not pass image url here, because request package is removed manually.
const colors = await getColors(buffer, type)
return colors[0].hex()
} catch (error) {
console.error(error.message)
return undefined
}
}
function componentToHex(c: number) {
const hex = c.toString(16)
return hex.length == 1 ? `0${hex}` : hex

View File

@@ -0,0 +1,39 @@
export class AsyncQueue {
private maxConcurrent: number
private queue: (() => Promise<any>)[]
private activeCount: number
constructor(maxConcurrent: number) {
this.maxConcurrent = maxConcurrent
this.queue = []
this.activeCount = 0
}
private async runNext() {
if (this.activeCount >= this.maxConcurrent || this.queue.length === 0) {
return
}
this.activeCount++
const request = this.queue.shift()!
try {
return await request()
} catch (error) {
console.error('Request failed', error)
} finally {
this.activeCount--
this.runNext() // Start the next request after this one finishes
}
}
add(request: () => Promise<any>) {
this.queue.push(request)
return this.runNext()
}
addMultiple(requests: (() => Promise<any>)[]) {
this.queue.push(...requests)
this.runNext()
}
}

View File

@@ -2,6 +2,10 @@ import { createHash } from 'node:crypto'
import { join } from 'node:path'
import { cloneDeep } from 'lodash'
import { installPackage } from '@antfu/install-pkg'
import { logger } from '~/global/consola.global'
export const md5 = (text: string) =>
createHash('md5').update(text).digest('hex') as string
@@ -149,3 +153,14 @@ export function escapeXml(unsafe: string) {
return c
})
}
export const requireDepsWithInstall = async (deps: string) => {
try {
return require(require.resolve(deps))
} catch {
logger.info(`Installing ${deps}...`)
await installPackage(deps, { silent: false })
return require(deps)
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
import { camelcaseKeys, safePathJoin } from '~/utils'
import { camelcaseKeys, safePathJoin } from '~/utils/tool.util'
describe('test tools', () => {
describe('safePathJoin', () => {

View File

@@ -9,6 +9,7 @@ export interface Image {
type: string
accent?: string
src: string
blurHash?: string
}
export interface Pager {

524
pnpm-lock.yaml generated
View File

@@ -77,6 +77,9 @@ importers:
'@algolia/client-search':
specifier: ^4.22.1
version: 4.24.0
'@antfu/install-pkg':
specifier: 0.3.5
version: 0.3.5
'@aws-sdk/client-s3':
specifier: 3.632.0
version: 3.632.0
@@ -176,6 +179,9 @@ importers:
bcryptjs:
specifier: ^2.4.3
version: 2.4.3
blurhash:
specifier: 2.0.5
version: 2.0.5
cache-manager:
specifier: 5.7.6
version: 5.7.6
@@ -206,12 +212,6 @@ importers:
form-data:
specifier: 4.0.0
version: 4.0.0
get-image-colors:
specifier: 4.0.1
version: 4.0.1
image-size:
specifier: 1.1.1
version: 1.1.1
inquirer:
specifier: ^10.1.0
version: 10.1.8
@@ -409,6 +409,9 @@ importers:
ioredis:
specifier: 5.4.1
version: 5.4.1
sharp:
specifier: 0.33.4
version: 0.33.4
socket.io:
specifier: ^4.7.4
version: 4.7.5
@@ -557,6 +560,9 @@ packages:
resolution: {integrity: sha512-QRVEYpIfgkprNHc916JlPuNbLzOgrm9DZalHasnLUz4P6g7pR21olb8YCyM2OTJjombNhya9ZpckcADU5Qyvlg==}
engines: {node: ^18.13.0 || >=20.9.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, yarn: '>= 1.13.0'}
'@antfu/install-pkg@0.3.5':
resolution: {integrity: sha512-HwIACY0IzrM7FGafMbWZOqEDBSfCwPcylu+GacaRcxJm4Yvvuh3Dy2vZwqdJAzXponc6aLO9FaH4l75pq8/ZSA==}
'@antfu/utils@0.7.10':
resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==}
@@ -920,6 +926,9 @@ packages:
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
engines: {node: '>=12'}
'@emnapi/runtime@1.2.0':
resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==}
'@es-joy/jsdoccomment@0.43.1':
resolution: {integrity: sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==}
engines: {node: '>=16'}
@@ -1438,6 +1447,119 @@ packages:
'@vue/compiler-sfc':
optional: true
'@img/sharp-darwin-arm64@0.33.4':
resolution: {integrity: sha512-p0suNqXufJs9t3RqLBO6vvrgr5OhgbWp76s5gTRvdmxmuv9E1rcaqGUsl3l4mKVmXPkTkTErXediAui4x+8PSA==}
engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [arm64]
os: [darwin]
'@img/sharp-darwin-x64@0.33.4':
resolution: {integrity: sha512-0l7yRObwtTi82Z6ebVI2PnHT8EB2NxBgpK2MiKJZJ7cz32R4lxd001ecMhzzsZig3Yv9oclvqqdV93jo9hy+Dw==}
engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [x64]
os: [darwin]
'@img/sharp-libvips-darwin-arm64@1.0.2':
resolution: {integrity: sha512-tcK/41Rq8IKlSaKRCCAuuY3lDJjQnYIW1UXU1kxcEKrfL8WR7N6+rzNoOxoQRJWTAECuKwgAHnPvqXGN8XfkHA==}
engines: {macos: '>=11', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [arm64]
os: [darwin]
'@img/sharp-libvips-darwin-x64@1.0.2':
resolution: {integrity: sha512-Ofw+7oaWa0HiiMiKWqqaZbaYV3/UGL2wAPeLuJTx+9cXpCRdvQhCLG0IH8YGwM0yGWGLpsF4Su9vM1o6aer+Fw==}
engines: {macos: '>=10.13', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [x64]
os: [darwin]
'@img/sharp-libvips-linux-arm64@1.0.2':
resolution: {integrity: sha512-x7kCt3N00ofFmmkkdshwj3vGPCnmiDh7Gwnd4nUwZln2YjqPxV1NlTyZOvoDWdKQVDL911487HOueBvrpflagw==}
engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [arm64]
os: [linux]
'@img/sharp-libvips-linux-arm@1.0.2':
resolution: {integrity: sha512-iLWCvrKgeFoglQxdEwzu1eQV04o8YeYGFXtfWU26Zr2wWT3q3MTzC+QTCO3ZQfWd3doKHT4Pm2kRmLbupT+sZw==}
engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [arm]
os: [linux]
'@img/sharp-libvips-linux-s390x@1.0.2':
resolution: {integrity: sha512-cmhQ1J4qVhfmS6szYW7RT+gLJq9dH2i4maq+qyXayUSn9/3iY2ZeWpbAgSpSVbV2E1JUL2Gg7pwnYQ1h8rQIog==}
engines: {glibc: '>=2.28', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [s390x]
os: [linux]
'@img/sharp-libvips-linux-x64@1.0.2':
resolution: {integrity: sha512-E441q4Qdb+7yuyiADVi5J+44x8ctlrqn8XgkDTwr4qPJzWkaHwD489iZ4nGDgcuya4iMN3ULV6NwbhRZJ9Z7SQ==}
engines: {glibc: '>=2.26', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [x64]
os: [linux]
'@img/sharp-libvips-linuxmusl-arm64@1.0.2':
resolution: {integrity: sha512-3CAkndNpYUrlDqkCM5qhksfE+qSIREVpyoeHIU6jd48SJZViAmznoQQLAv4hVXF7xyUB9zf+G++e2v1ABjCbEQ==}
engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [arm64]
os: [linux]
'@img/sharp-libvips-linuxmusl-x64@1.0.2':
resolution: {integrity: sha512-VI94Q6khIHqHWNOh6LLdm9s2Ry4zdjWJwH56WoiJU7NTeDwyApdZZ8c+SADC8OH98KWNQXnE01UdJ9CSfZvwZw==}
engines: {musl: '>=1.2.2', npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [x64]
os: [linux]
'@img/sharp-linux-arm64@0.33.4':
resolution: {integrity: sha512-2800clwVg1ZQtxwSoTlHvtm9ObgAax7V6MTAB/hDT945Tfyy3hVkmiHpeLPCKYqYR1Gcmv1uDZ3a4OFwkdBL7Q==}
engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [arm64]
os: [linux]
'@img/sharp-linux-arm@0.33.4':
resolution: {integrity: sha512-RUgBD1c0+gCYZGCCe6mMdTiOFS0Zc/XrN0fYd6hISIKcDUbAW5NtSQW9g/powkrXYm6Vzwd6y+fqmExDuCdHNQ==}
engines: {glibc: '>=2.28', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [arm]
os: [linux]
'@img/sharp-linux-s390x@0.33.4':
resolution: {integrity: sha512-h3RAL3siQoyzSoH36tUeS0PDmb5wINKGYzcLB5C6DIiAn2F3udeFAum+gj8IbA/82+8RGCTn7XW8WTFnqag4tQ==}
engines: {glibc: '>=2.31', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [s390x]
os: [linux]
'@img/sharp-linux-x64@0.33.4':
resolution: {integrity: sha512-GoR++s0XW9DGVi8SUGQ/U4AeIzLdNjHka6jidVwapQ/JebGVQIpi52OdyxCNVRE++n1FCLzjDovJNozif7w/Aw==}
engines: {glibc: '>=2.26', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [x64]
os: [linux]
'@img/sharp-linuxmusl-arm64@0.33.4':
resolution: {integrity: sha512-nhr1yC3BlVrKDTl6cO12gTpXMl4ITBUZieehFvMntlCXFzH2bvKG76tBL2Y/OqhupZt81pR7R+Q5YhJxW0rGgQ==}
engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [arm64]
os: [linux]
'@img/sharp-linuxmusl-x64@0.33.4':
resolution: {integrity: sha512-uCPTku0zwqDmZEOi4ILyGdmW76tH7dm8kKlOIV1XC5cLyJ71ENAAqarOHQh0RLfpIpbV5KOpXzdU6XkJtS0daw==}
engines: {musl: '>=1.2.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [x64]
os: [linux]
'@img/sharp-wasm32@0.33.4':
resolution: {integrity: sha512-Bmmauh4sXUsUqkleQahpdNXKvo+wa1V9KhT2pDA4VJGKwnKMJXiSTGphn0gnJrlooda0QxCtXc6RX1XAU6hMnQ==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [wasm32]
'@img/sharp-win32-ia32@0.33.4':
resolution: {integrity: sha512-99SJ91XzUhYHbx7uhK3+9Lf7+LjwMGQZMDlO/E/YVJ7Nc3lyDFZPGhjwiYdctoH2BOzW9+TnfqcaMKt0jHLdqw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [ia32]
os: [win32]
'@img/sharp-win32-x64@0.33.4':
resolution: {integrity: sha512-3QLocdTRVIrFNye5YocZl+KKpYKP+fksi1QhmOArgx7GyhIbQp/WrJRu176jm8IxromS7RIkzMiMINVdBtC8Aw==}
engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0', yarn: '>=3.2.0'}
cpu: [x64]
os: [win32]
'@innei/class-validator-jsonschema@3.1.2':
resolution: {integrity: sha512-TtexCmngzF7irt9MB0fbT8M2/CH38tdOrxkaqH6rsgumnHDyxzlevSAoKpcxFG7nz3CtN9OjQ2YbgTC7MOIeaQ==}
peerDependencies:
@@ -1557,6 +1679,10 @@ packages:
'@jridgewell/trace-mapping@0.3.9':
resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==}
'@jsdevtools/ez-spawn@3.0.4':
resolution: {integrity: sha512-f5DRIOZf7wxogefH03RjMPMdBF7ADTWUMoOs9kaJo06EfwF+aFhMZMDZxHg/Xe12hptN9xoZjGso2fdjapBRIA==}
engines: {node: '>=10'}
'@langchain/core@0.2.24':
resolution: {integrity: sha512-+m+0SX0QPwSiTxkbztqCpOEl0YKAy5MAW/u89ZKR+YChS/E3wg+3h+y1ysGq9hoom5spkQQq+SEZ1CwOf+LD8g==}
engines: {node: '>=18'}
@@ -2852,6 +2978,9 @@ packages:
bl@4.1.0:
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
blurhash@2.0.5:
resolution: {integrity: sha512-cRygWd7kGBQO3VEhPiTgq4Wc43ctsM+o46urrmPOiuAe+07fzlSB9OJVdpgDL0jPqXUVQ9ht7aq7kxOeJHRK+w==}
body-parser@1.20.2:
resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
@@ -2923,6 +3052,9 @@ packages:
resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
engines: {node: '>= 0.4'}
call-me-maybe@1.0.2:
resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==}
callsites@3.1.0:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
@@ -2973,13 +3105,6 @@ packages:
check-error@1.0.3:
resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==}
cheerio-select@2.1.0:
resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==}
cheerio@1.0.0-rc.12:
resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==}
engines: {node: '>= 6'}
chokidar@3.6.0:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
@@ -2988,9 +3113,6 @@ packages:
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
engines: {node: '>=10'}
chroma-js@2.4.2:
resolution: {integrity: sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==}
chrome-trace-event@1.0.4:
resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==}
engines: {node: '>=6.0'}
@@ -3065,6 +3187,13 @@ packages:
color-name@1.1.4:
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
color-string@1.9.1:
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
color@4.2.3:
resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
engines: {node: '>=12.5.0'}
colorette@2.0.20:
resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==}
@@ -3206,12 +3335,6 @@ packages:
csstype@3.1.1:
resolution: {integrity: sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==}
cwise-compiler@1.1.3:
resolution: {integrity: sha512-WXlK/m+Di8DMMcCjcWr4i+XzcQra9eCdXIJrgh4TUgh0pIS/yJduLxS9JgefsHJ/YVLdgPtXm9r62W92MvanEQ==}
data-uri-to-buffer@0.0.3:
resolution: {integrity: sha512-Cp+jOa8QJef5nXS5hU7M1DWzXPEIoVR3kbV0dQuVGwROZg8bGf1DcCnkmajBTnvghTtSNMUdRrPjgaT6ZQucbw==}
data-uri-to-buffer@4.0.1:
resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==}
engines: {node: '>= 12'}
@@ -3310,6 +3433,10 @@ packages:
resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==}
engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16}
detect-libc@2.0.3:
resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
engines: {node: '>=8'}
diff-sequences@29.6.3:
resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -3920,23 +4047,14 @@ packages:
get-func-name@2.0.2:
resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==}
get-image-colors@4.0.1:
resolution: {integrity: sha512-UVw9LdFemitTVCpwZY33JUkedmY1kNt0UGoneVMzbD12GkBja67/jX2AJFsJOCDefea0oCFFf9z9pa5fjKhAQw==}
get-intrinsic@1.2.4:
resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
engines: {node: '>= 0.4'}
get-pixels@3.3.3:
resolution: {integrity: sha512-5kyGBn90i9tSMUVHTqkgCHsoWoR+/lGbl4yC83Gefyr0HLIhgSWEx/2F/3YgsZ7UpYNuM6pDhDK7zebrUJ5nXg==}
get-port@5.1.1:
resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==}
engines: {node: '>=8'}
get-rgba-palette@2.0.1:
resolution: {integrity: sha512-rYbQg/u2tGnRYWuYHNMcF/nDg0WakAbQRiYLM86AE96d2MA0oYPaphsuywSoYajG0PImMZEEjKbtY4UuL/620A==}
get-stream@5.2.0:
resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
engines: {node: '>=8'}
@@ -3949,9 +4067,6 @@ packages:
resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==}
engines: {node: '>=16'}
get-svg-colors@2.0.1:
resolution: {integrity: sha512-h1CWd6EO9hs5WOiwSqA1fb2WKoYVxnTlIYIxiZCFndMKN5iE4FXHmb6+U1o6yUbURl+IPcgZEojSQdayXDatsw==}
get-symbol-description@1.0.2:
resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==}
engines: {node: '>= 0.4'}
@@ -4064,9 +4179,6 @@ packages:
html-escaper@3.0.3:
resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
htmlparser2@8.0.2:
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
htmlparser2@9.1.0:
resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==}
@@ -4113,11 +4225,6 @@ packages:
resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
engines: {node: '>= 4'}
image-size@1.1.1:
resolution: {integrity: sha512-541xKlUw6jr/6gGuk92F+mYM5zaFAc5ahphvkqvNe2bQ6gVBkd6bfrmVJ2t4KDAfikAYZyIqTnktX3i6/aQDrQ==}
engines: {node: '>=16.x'}
hasBin: true
immediate@3.0.6:
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==}
@@ -4163,9 +4270,6 @@ packages:
resolution: {integrity: sha512-2YZsvl7jopIa1gaePkeMtd9rAcSjOOjPtpcLlOeusyO+XH2SK5ZcT+UCrElPP+WVIInh2TzeI4XW9ENaSLVVHA==}
engines: {node: '>=12.22.0'}
iota-array@1.0.0:
resolution: {integrity: sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==}
ip-address@9.0.5:
resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==}
engines: {node: '>= 12'}
@@ -4191,6 +4295,9 @@ packages:
is-arrayish@0.2.1:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
is-arrayish@0.3.2:
resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
is-bigint@1.0.4:
resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==}
@@ -4202,9 +4309,6 @@ packages:
resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==}
engines: {node: '>= 0.4'}
is-buffer@1.1.6:
resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==}
is-builtin-module@3.2.1:
resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==}
engines: {node: '>=6'}
@@ -4299,10 +4403,6 @@ packages:
resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==}
engines: {node: '>= 0.4'}
is-svg@4.4.0:
resolution: {integrity: sha512-v+AgVwiK5DsGtT9ng+m4mClp6zDAmwrW8nZi6Gg15qzvBnRWWdfWA1TGaXyCDnWq5g5asofIgMVl3PjKxvk1ug==}
engines: {node: '>=6'}
is-symbol@1.0.4:
resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==}
engines: {node: '>= 0.4'}
@@ -4367,9 +4467,6 @@ packages:
resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==}
engines: {node: '>=10'}
jpeg-js@0.4.4:
resolution: {integrity: sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg==}
js-cookie@3.0.5:
resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==}
engines: {node: '>=14'}
@@ -4723,9 +4820,6 @@ packages:
lodash.clonedeep@4.5.0:
resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==}
lodash.compact@3.0.1:
resolution: {integrity: sha512-2ozeiPi+5eBXW1CLtzjk8XQFhQOEMwwfxblqeq6EGyTxZJ1bPATqilY0e6g2SLQpP4KuMeuioBhEnWz5Pr7ICQ==}
lodash.defaults@4.2.0:
resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==}
@@ -4762,9 +4856,6 @@ packages:
lodash.once@4.1.1:
resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==}
lodash.uniq@4.5.0:
resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==}
lodash@4.17.21:
resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
@@ -5085,12 +5176,6 @@ packages:
natural-compare@1.4.0:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
ndarray-pack@1.2.1:
resolution: {integrity: sha512-51cECUJMT0rUZNQa09EoKsnFeDL4x2dHRT0VR5U2H5ZgEcm95ZDWcMA5JShroXjHOejmAD/fg8+H+OvUnVXz2g==}
ndarray@1.0.19:
resolution: {integrity: sha512-B4JHA4vdyZU30ELBw3g7/p9bZupyew5a7tX1Y/gGeF2hafrPaQZhgrGQfsvgfYbgdFZjYwuEcnaobeM/WMW+HQ==}
negotiator@0.6.3:
resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==}
engines: {node: '>= 0.6'}
@@ -5108,10 +5193,6 @@ packages:
node-abort-controller@3.1.1:
resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==}
node-bitmap@0.0.1:
resolution: {integrity: sha512-Jx5lPaaLdIaOsj2mVLWMWulXF6GQVdyLvNSxmiYCvZ8Ma2hfKX0POoR2kgKOqz+oFsRreq0yYZjQ2wjE9VNzCA==}
engines: {node: '>=v0.6.5'}
node-domexception@1.0.0:
resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==}
engines: {node: '>=10.5.0'}
@@ -5188,9 +5269,6 @@ packages:
obliterator@2.0.4:
resolution: {integrity: sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==}
omggif@1.0.10:
resolution: {integrity: sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw==}
on-finished@2.4.1:
resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==}
engines: {node: '>= 0.8'}
@@ -5291,9 +5369,6 @@ packages:
resolution: {integrity: sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw==}
engines: {node: '>=0.10.0'}
parse-data-uri@0.2.0:
resolution: {integrity: sha512-uOtts8NqDcaCt1rIsO3VFDRsAfgE4c6osG4d9z3l4dCBlxYFzni6Di/oNU270SDrjkfZuUvLZx1rxMyqh46Y9w==}
parse-entities@2.0.0:
resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==}
@@ -5309,12 +5384,6 @@ packages:
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
engines: {node: '>=8'}
parse5-htmlparser2-tree-adapter@7.0.0:
resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==}
parse5@7.1.2:
resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==}
parseurl@1.3.3:
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
engines: {node: '>= 0.8'}
@@ -5387,10 +5456,6 @@ packages:
engines: {node: '>=0.10'}
hasBin: true
pify@5.0.0:
resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==}
engines: {node: '>=10'}
pirates@4.0.6:
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
engines: {node: '>= 6'}
@@ -5409,10 +5474,6 @@ packages:
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
engines: {node: '>=4'}
pngjs@3.4.0:
resolution: {integrity: sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==}
engines: {node: '>=4.0.0'}
possible-typed-array-names@1.0.0:
resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==}
engines: {node: '>= 0.4'}
@@ -5572,19 +5633,12 @@ packages:
resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==}
engines: {node: '>=0.6'}
quantize@1.0.2:
resolution: {integrity: sha512-25P7wI2UoDbIQsQp50ARkt+5pwPsOq7G/BqvT5xAbapnRoNWMN8/p55H9TXd5MuENiJnm5XICB2H2aDZGwts7w==}
engines: {node: '>=0.10.21'}
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
queue-tick@1.0.1:
resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==}
queue@6.0.2:
resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==}
quick-lru@6.1.2:
resolution: {integrity: sha512-AAFUA5O1d83pIHEhJwWCq/RQcRukCkn/NSm2QsTEMle5f2hP0ChI2+3Xb051PZCkLryI/Ir1MVKviT2FIloaTQ==}
engines: {node: '>=12'}
@@ -5820,6 +5874,10 @@ packages:
resolution: {integrity: sha512-/l2UZ5fhGZLVZa16XQM9/Vq/hezGGbdHeVEA01uWjOL1+7Ek/gt6FquW0iKKws4a9AYPYvlz6RyVvjh3JxOteg==}
engines: {node: '>=16.0.0'}
sharp@0.33.4:
resolution: {integrity: sha512-7i/dt5kGl7qR4gwPRD2biwD2/SvBn3O04J77XKFgL2OnZtQw+AG9wnuS/csmu80nPRHLYE9E41fyEiG8nhH6/Q==}
engines: {libvips: '>=8.15.2', node: ^18.17.0 || ^20.3.0 || >=21.0.0}
shebang-command@2.0.0:
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
engines: {node: '>=8'}
@@ -5848,6 +5906,9 @@ packages:
resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
engines: {node: '>=14'}
simple-swizzle@0.2.2:
resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
slash@3.0.0:
resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
engines: {node: '>=8'}
@@ -6351,9 +6412,6 @@ packages:
undici-types@6.18.2:
resolution: {integrity: sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==}
uniq@1.0.1:
resolution: {integrity: sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==}
unist-util-stringify-position@2.0.3:
resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==}
@@ -6802,6 +6860,10 @@ snapshots:
transitivePeerDependencies:
- chokidar
'@antfu/install-pkg@0.3.5':
dependencies:
'@jsdevtools/ez-spawn': 3.0.4
'@antfu/utils@0.7.10': {}
'@aws-crypto/crc32@5.2.0':
@@ -7585,6 +7647,11 @@ snapshots:
dependencies:
'@jridgewell/trace-mapping': 0.3.9
'@emnapi/runtime@1.2.0':
dependencies:
tslib: 2.6.3
optional: true
'@es-joy/jsdoccomment@0.43.1':
dependencies:
'@types/eslint': 8.56.10
@@ -7931,6 +7998,81 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@img/sharp-darwin-arm64@0.33.4':
optionalDependencies:
'@img/sharp-libvips-darwin-arm64': 1.0.2
optional: true
'@img/sharp-darwin-x64@0.33.4':
optionalDependencies:
'@img/sharp-libvips-darwin-x64': 1.0.2
optional: true
'@img/sharp-libvips-darwin-arm64@1.0.2':
optional: true
'@img/sharp-libvips-darwin-x64@1.0.2':
optional: true
'@img/sharp-libvips-linux-arm64@1.0.2':
optional: true
'@img/sharp-libvips-linux-arm@1.0.2':
optional: true
'@img/sharp-libvips-linux-s390x@1.0.2':
optional: true
'@img/sharp-libvips-linux-x64@1.0.2':
optional: true
'@img/sharp-libvips-linuxmusl-arm64@1.0.2':
optional: true
'@img/sharp-libvips-linuxmusl-x64@1.0.2':
optional: true
'@img/sharp-linux-arm64@0.33.4':
optionalDependencies:
'@img/sharp-libvips-linux-arm64': 1.0.2
optional: true
'@img/sharp-linux-arm@0.33.4':
optionalDependencies:
'@img/sharp-libvips-linux-arm': 1.0.2
optional: true
'@img/sharp-linux-s390x@0.33.4':
optionalDependencies:
'@img/sharp-libvips-linux-s390x': 1.0.2
optional: true
'@img/sharp-linux-x64@0.33.4':
optionalDependencies:
'@img/sharp-libvips-linux-x64': 1.0.2
optional: true
'@img/sharp-linuxmusl-arm64@0.33.4':
optionalDependencies:
'@img/sharp-libvips-linuxmusl-arm64': 1.0.2
optional: true
'@img/sharp-linuxmusl-x64@0.33.4':
optionalDependencies:
'@img/sharp-libvips-linuxmusl-x64': 1.0.2
optional: true
'@img/sharp-wasm32@0.33.4':
dependencies:
'@emnapi/runtime': 1.2.0
optional: true
'@img/sharp-win32-ia32@0.33.4':
optional: true
'@img/sharp-win32-x64@0.33.4':
optional: true
'@innei/class-validator-jsonschema@3.1.2(class-transformer@0.5.1)(class-validator@0.13.2)':
dependencies:
class-transformer: 0.5.1
@@ -8129,6 +8271,13 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.4.15
'@jsdevtools/ez-spawn@3.0.4':
dependencies:
call-me-maybe: 1.0.2
cross-spawn: 7.0.3
string-argv: 0.3.2
type-detect: 4.0.8
'@langchain/core@0.2.24(langchain@0.2.16(@aws-sdk/client-s3@3.632.0)(@aws-sdk/credential-provider-node@3.632.0(@aws-sdk/client-sso-oidc@3.632.0(@aws-sdk/client-sts@3.632.0))(@aws-sdk/client-sts@3.632.0))(axios@1.7.4)(encoding@0.1.13)(fast-xml-parser@4.4.1)(ignore@5.3.1)(ioredis@5.4.1)(mongodb@6.7.0(socks@2.8.3))(openai@4.55.9(encoding@0.1.13)(zod@3.23.8))(ws@8.17.1))(openai@4.55.9(encoding@0.1.13)(zod@3.23.8))':
dependencies:
ansi-styles: 5.2.0
@@ -9669,6 +9818,8 @@ snapshots:
inherits: 2.0.4
readable-stream: 3.6.2
blurhash@2.0.5: {}
body-parser@1.20.2:
dependencies:
bytes: 3.1.2
@@ -9758,6 +9909,8 @@ snapshots:
get-intrinsic: 1.2.4
set-function-length: 1.2.2
call-me-maybe@1.0.2: {}
callsites@3.1.0: {}
camelcase-keys@9.1.3:
@@ -9808,25 +9961,6 @@ snapshots:
dependencies:
get-func-name: 2.0.2
cheerio-select@2.1.0:
dependencies:
boolbase: 1.0.0
css-select: 5.1.0
css-what: 6.1.0
domelementtype: 2.3.0
domhandler: 5.0.3
domutils: 3.1.0
cheerio@1.0.0-rc.12:
dependencies:
cheerio-select: 2.1.0
dom-serializer: 2.0.0
domhandler: 5.0.3
domutils: 3.1.0
htmlparser2: 8.0.2
parse5: 7.1.2
parse5-htmlparser2-tree-adapter: 7.0.0
chokidar@3.6.0:
dependencies:
anymatch: 3.1.3
@@ -9842,8 +9976,6 @@ snapshots:
chownr@2.0.0:
optional: true
chroma-js@2.4.2: {}
chrome-trace-event@1.0.4: {}
ci-info@4.0.0: {}
@@ -9908,6 +10040,16 @@ snapshots:
color-name@1.1.4: {}
color-string@1.9.1:
dependencies:
color-name: 1.1.4
simple-swizzle: 0.2.2
color@4.2.3:
dependencies:
color-convert: 2.0.1
color-string: 1.9.1
colorette@2.0.20: {}
combined-stream@1.0.8:
@@ -10035,12 +10177,6 @@ snapshots:
csstype@3.1.1: {}
cwise-compiler@1.1.3:
dependencies:
uniq: 1.0.1
data-uri-to-buffer@0.0.3: {}
data-uri-to-buffer@4.0.1: {}
data-view-buffer@1.0.1:
@@ -10115,6 +10251,8 @@ snapshots:
destroy@1.2.0: {}
detect-libc@2.0.3: {}
diff-sequences@29.6.3: {}
diff@4.0.2: {}
@@ -11007,14 +11145,6 @@ snapshots:
get-func-name@2.0.2: {}
get-image-colors@4.0.1:
dependencies:
chroma-js: 2.4.2
get-pixels: 3.3.3
get-rgba-palette: 2.0.1
get-svg-colors: 2.0.1
pify: 5.0.0
get-intrinsic@1.2.4:
dependencies:
es-errors: 1.3.0
@@ -11023,27 +11153,9 @@ snapshots:
has-symbols: 1.0.3
hasown: 2.0.2
get-pixels@3.3.3:
dependencies:
data-uri-to-buffer: 0.0.3
jpeg-js: 0.4.4
mime-types: 2.1.35
ndarray: 1.0.19
ndarray-pack: 1.2.1
node-bitmap: 0.0.1
omggif: 1.0.10
parse-data-uri: 0.2.0
pngjs: 3.4.0
request: link:external/request
through: 2.3.8
get-port@5.1.1:
optional: true
get-rgba-palette@2.0.1:
dependencies:
quantize: 1.0.2
get-stream@5.2.0:
dependencies:
pump: 3.0.0
@@ -11053,14 +11165,6 @@ snapshots:
get-stream@8.0.1: {}
get-svg-colors@2.0.1:
dependencies:
cheerio: 1.0.0-rc.12
chroma-js: 2.4.2
is-svg: 4.4.0
lodash.compact: 3.0.1
lodash.uniq: 4.5.0
get-symbol-description@1.0.2:
dependencies:
call-bind: 1.0.7
@@ -11178,13 +11282,6 @@ snapshots:
html-escaper@3.0.3: {}
htmlparser2@8.0.2:
dependencies:
domelementtype: 2.3.0
domhandler: 5.0.3
domutils: 3.1.0
entities: 4.5.0
htmlparser2@9.1.0:
dependencies:
domelementtype: 2.3.0
@@ -11238,10 +11335,6 @@ snapshots:
ignore@5.3.1: {}
image-size@1.1.1:
dependencies:
queue: 6.0.2
immediate@3.0.6: {}
import-fresh@3.3.0:
@@ -11339,8 +11432,6 @@ snapshots:
transitivePeerDependencies:
- supports-color
iota-array@1.0.0: {}
ip-address@9.0.5:
dependencies:
jsbn: 1.1.0
@@ -11365,6 +11456,8 @@ snapshots:
is-arrayish@0.2.1: {}
is-arrayish@0.3.2: {}
is-bigint@1.0.4:
dependencies:
has-bigints: 1.0.2
@@ -11378,8 +11471,6 @@ snapshots:
call-bind: 1.0.7
has-tostringtag: 1.0.2
is-buffer@1.1.6: {}
is-builtin-module@3.2.1:
dependencies:
builtin-modules: 3.3.0
@@ -11449,10 +11540,6 @@ snapshots:
dependencies:
has-tostringtag: 1.0.2
is-svg@4.4.0:
dependencies:
fast-xml-parser: 4.4.1
is-symbol@1.0.4:
dependencies:
has-symbols: 1.0.3
@@ -11513,8 +11600,6 @@ snapshots:
joycon@3.1.1: {}
jpeg-js@0.4.4: {}
js-cookie@3.0.5: {}
js-tiktoken@1.0.12:
@@ -11731,8 +11816,6 @@ snapshots:
lodash.clonedeep@4.5.0: {}
lodash.compact@3.0.1: {}
lodash.defaults@4.2.0: {}
lodash.defaultsdeep@4.6.1:
@@ -11758,8 +11841,6 @@ snapshots:
lodash.once@4.1.1: {}
lodash.uniq@4.5.0: {}
lodash@4.17.21: {}
log-symbols@4.1.0:
@@ -12069,16 +12150,6 @@ snapshots:
natural-compare@1.4.0: {}
ndarray-pack@1.2.1:
dependencies:
cwise-compiler: 1.1.3
ndarray: 1.0.19
ndarray@1.0.19:
dependencies:
iota-array: 1.0.0
is-buffer: 1.1.6
negotiator@0.6.3: {}
neo-async@2.6.2: {}
@@ -12097,8 +12168,6 @@ snapshots:
node-abort-controller@3.1.1: {}
node-bitmap@0.0.1: {}
node-domexception@1.0.0: {}
node-emoji@1.11.0:
@@ -12168,8 +12237,6 @@ snapshots:
obliterator@2.0.4: {}
omggif@1.0.10: {}
on-finished@2.4.1:
dependencies:
ee-first: 1.1.1
@@ -12283,10 +12350,6 @@ snapshots:
dependencies:
author-regex: 1.0.0
parse-data-uri@0.2.0:
dependencies:
data-uri-to-buffer: 0.0.3
parse-entities@2.0.0:
dependencies:
character-entities: 1.2.4
@@ -12310,15 +12373,6 @@ snapshots:
json-parse-even-better-errors: 2.3.1
lines-and-columns: 1.2.4
parse5-htmlparser2-tree-adapter@7.0.0:
dependencies:
domhandler: 5.0.3
parse5: 7.1.2
parse5@7.1.2:
dependencies:
entities: 4.5.0
parseurl@1.3.3: {}
path-exists@4.0.0: {}
@@ -12368,8 +12422,6 @@ snapshots:
pidtree@0.6.0: {}
pify@5.0.0: {}
pirates@4.0.6: {}
pkg-dir@4.2.0:
@@ -12391,8 +12443,6 @@ snapshots:
pluralize@8.0.0: {}
pngjs@3.4.0: {}
possible-typed-array-names@1.0.0: {}
postcss-load-config@6.0.1(jiti@1.21.6)(postcss@8.4.38)(tsx@4.16.5)(yaml@2.5.0):
@@ -12497,17 +12547,11 @@ snapshots:
dependencies:
side-channel: 1.0.6
quantize@1.0.2: {}
queue-microtask@1.2.3: {}
queue-tick@1.0.1:
optional: true
queue@6.0.2:
dependencies:
inherits: 2.0.4
quick-lru@6.1.2: {}
randombytes@2.1.0:
@@ -12815,6 +12859,32 @@ snapshots:
dependencies:
tslib: 2.6.3
sharp@0.33.4:
dependencies:
color: 4.2.3
detect-libc: 2.0.3
semver: 7.6.3
optionalDependencies:
'@img/sharp-darwin-arm64': 0.33.4
'@img/sharp-darwin-x64': 0.33.4
'@img/sharp-libvips-darwin-arm64': 1.0.2
'@img/sharp-libvips-darwin-x64': 1.0.2
'@img/sharp-libvips-linux-arm': 1.0.2
'@img/sharp-libvips-linux-arm64': 1.0.2
'@img/sharp-libvips-linux-s390x': 1.0.2
'@img/sharp-libvips-linux-x64': 1.0.2
'@img/sharp-libvips-linuxmusl-arm64': 1.0.2
'@img/sharp-libvips-linuxmusl-x64': 1.0.2
'@img/sharp-linux-arm': 0.33.4
'@img/sharp-linux-arm64': 0.33.4
'@img/sharp-linux-s390x': 0.33.4
'@img/sharp-linux-x64': 0.33.4
'@img/sharp-linuxmusl-arm64': 0.33.4
'@img/sharp-linuxmusl-x64': 0.33.4
'@img/sharp-wasm32': 0.33.4
'@img/sharp-win32-ia32': 0.33.4
'@img/sharp-win32-x64': 0.33.4
shebang-command@2.0.0:
dependencies:
shebang-regex: 3.0.0
@@ -12838,6 +12908,10 @@ snapshots:
signal-exit@4.1.0: {}
simple-swizzle@0.2.2:
dependencies:
is-arrayish: 0.3.2
slash@3.0.0: {}
slash@4.0.0: {}
@@ -13377,8 +13451,6 @@ snapshots:
undici-types@6.18.2: {}
uniq@1.0.1: {}
unist-util-stringify-position@2.0.3:
dependencies:
'@types/unist': 2.0.10