Merge branch 'master' into 3573-feature-introduce-distributed-semaphore-base-on-redis

This commit is contained in:
einhornimmond 2025-12-02 06:42:49 +01:00
commit 693bbf7c2a
70 changed files with 1178 additions and 456 deletions

View File

@ -1,27 +1,7 @@
import { registerEnumType } from 'type-graphql'
import { ContributionCycleType } from 'database'
// lowercase values are not implemented yet
export enum ContributionCycleType {
ONCE = 'ONCE',
HOUR = 'hour',
TWO_HOURS = 'two_hours',
FOUR_HOURS = 'four_hours',
EIGHT_HOURS = 'eight_hours',
HALF_DAY = 'half_day',
DAILY = 'DAILY',
TWO_DAYS = 'two_days',
THREE_DAYS = 'three_days',
FOUR_DAYS = 'four_days',
FIVE_DAYS = 'five_days',
SIX_DAYS = 'six_days',
WEEK = 'week',
TWO_WEEKS = 'two_weeks',
MONTH = 'month',
TWO_MONTH = 'two_month',
QUARTER = 'quarter',
HALF_YEAR = 'half_year',
YEAR = 'year',
}
export { ContributionCycleType }
registerEnumType(ContributionCycleType, {
name: 'ContributionCycleType', // this one is mandatory

View File

@ -1,12 +1,7 @@
import { registerEnumType } from 'type-graphql'
import { ContributionStatus } from 'database'
export enum ContributionStatus {
PENDING = 'PENDING',
DELETED = 'DELETED',
IN_PROGRESS = 'IN_PROGRESS',
DENIED = 'DENIED',
CONFIRMED = 'CONFIRMED',
}
export { ContributionStatus }
registerEnumType(ContributionStatus, {
name: 'ContributionStatus',

View File

@ -1,10 +1,7 @@
import { registerEnumType } from 'type-graphql'
import { ContributionType } from 'database'
export enum ContributionType {
ADMIN = 'ADMIN',
USER = 'USER',
LINK = 'LINK',
}
export { ContributionType }
registerEnumType(ContributionType, {
name: 'ContributionType',

View File

@ -1,6 +1,8 @@
import { registerEnumType } from 'type-graphql'
import { PendingTransactionState } from 'shared'
export { PendingTransactionState }
registerEnumType(PendingTransactionState, {
name: 'PendingTransactionState', // this one is mandatory
description: 'State of the PendingTransaction', // this one is optional

View File

@ -1,13 +1,7 @@
import { registerEnumType } from 'type-graphql'
import { RoleNames } from 'database'
export enum RoleNames {
UNAUTHORIZED = 'UNAUTHORIZED',
USER = 'USER',
MODERATOR = 'MODERATOR',
MODERATOR_AI = 'MODERATOR_AI',
ADMIN = 'ADMIN',
DLT_CONNECTOR = 'DLT_CONNECTOR_ROLE',
}
export { RoleNames }
registerEnumType(RoleNames, {
name: 'RoleNames', // this one is mandatory

View File

@ -2144,14 +2144,6 @@ describe('ContributionResolver', () => {
})
})
it('stores the EMAIL_CONFIRMATION event in the database', async () => {
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.EMAIL_CONFIRMATION,
}),
)
})
describe('confirm same contribution again', () => {
it('throws an error', async () => {
jest.clearAllMocks()

View File

@ -2261,7 +2261,7 @@ describe('UserResolver', () => {
relations: ['user'],
})
const activationLink = `${
CONFIG.EMAIL_LINK_VERIFICATION
CONFIG.EMAIL_LINK_SETPASSWORD
}${userContact.emailVerificationCode.toString()}`
expect(sendAccountActivationEmail).toBeCalledWith({
firstName: 'Bibi',

View File

@ -1,3 +1,6 @@
export { ContributionLinkInterface } from 'database'
/*
export interface ContributionLinkInterface {
amount: number
name: string
@ -5,3 +8,4 @@ export interface ContributionLinkInterface {
validFrom?: Date
validTo?: Date
}
*/

View File

@ -1,5 +1,6 @@
import { ContributionLinkInterface } from './ContributionLinkInterface'
export { contributionLinks } from 'database'
/*
export const contributionLinks: ContributionLinkInterface[] = [
{
name: 'Dokumenta 2017',
@ -16,3 +17,4 @@ export const contributionLinks: ContributionLinkInterface[] = [
validTo: new Date(2022, 8, 25),
},
]
*/

View File

@ -1,3 +1,5 @@
export { CreationInterface } from 'database'
/*
export interface CreationInterface {
email: string
amount: number
@ -7,3 +9,4 @@ export interface CreationInterface {
// number of months to move the confirmed creation to the past
moveCreationDate?: number
}
*/

View File

@ -1,3 +1,7 @@
export { creations } from 'database'
/*
import { nMonthsBefore } from '@/seeds/factory/creation'
import { CreationInterface } from './CreationInterface'
@ -153,3 +157,4 @@ export const creations: CreationInterface[] = [
confirmed: true,
},
]
*/

View File

@ -1,32 +1,15 @@
import { ApolloServerTestClient } from 'apollo-server-testing'
import {
contributionLinkFactory as contributionLinkFactoryDb,
ContributionLinkInterface
} from 'database'
import { ContributionLink } from '@model/ContributionLink'
import { ContributionLinkInterface } from '@/seeds/contributionLink/ContributionLinkInterface'
import { createContributionLink, login } from '@/seeds/graphql/mutations'
export { ContributionLinkInterface }
export const contributionLinkFactory = async (
client: ApolloServerTestClient,
export async function contributionLinkFactory (
_client: any,
contributionLink: ContributionLinkInterface,
): Promise<ContributionLink> => {
const { mutate } = client
// login as admin
await mutate({
mutation: login,
variables: { email: 'peter@lustig.de', password: 'Aa12345_' },
})
const variables = {
amount: contributionLink.amount,
memo: contributionLink.memo,
name: contributionLink.name,
cycle: 'ONCE',
maxPerCycle: 1,
maxAmountPerMonth: 200,
validFrom: contributionLink.validFrom ? contributionLink.validFrom.toISOString() : undefined,
validTo: contributionLink.validTo ? contributionLink.validTo.toISOString() : undefined,
}
const result = await mutate({ mutation: createContributionLink, variables })
return result.data.createContributionLink
): Promise<ContributionLink> {
return new ContributionLink(await contributionLinkFactoryDb(contributionLink))
}

View File

@ -1,58 +1,15 @@
import { ApolloServerTestClient } from 'apollo-server-testing'
import { Contribution, Transaction } from 'database'
import {
Contribution,
creationFactory as creationFactoryDb,
CreationInterface,
nMonthsBefore
} from 'database'
import { findUserByEmail } from '@/graphql/resolver/UserResolver'
import { CreationInterface } from '@/seeds/creation/CreationInterface'
import { confirmContribution, createContribution, login } from '@/seeds/graphql/mutations'
export const nMonthsBefore = (date: Date, months = 1): string => {
return new Date(date.getFullYear(), date.getMonth() - months, 1).toISOString()
}
export { CreationInterface, nMonthsBefore }
export const creationFactory = async (
client: ApolloServerTestClient,
_client: any,
creation: CreationInterface,
): Promise<Contribution> => {
const { mutate } = client
await mutate({
mutation: login,
variables: { email: creation.email, password: 'Aa12345_' },
})
const {
data: { createContribution: contribution },
} = await mutate({ mutation: createContribution, variables: { ...creation } })
if (creation.confirmed) {
const user = await findUserByEmail(creation.email) // userContact.user
await mutate({ mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' } })
await mutate({ mutation: confirmContribution, variables: { id: contribution.id } })
const confirmedContribution = await Contribution.findOneOrFail({
where: { id: contribution.id },
})
if (creation.moveCreationDate) {
const transaction = await Transaction.findOneOrFail({
where: { userId: user.id, creationDate: new Date(creation.contributionDate) },
order: { balanceDate: 'DESC' },
})
if (transaction.decay.equals(0) && transaction.creationDate) {
confirmedContribution.contributionDate = new Date(
nMonthsBefore(transaction.creationDate, creation.moveCreationDate),
)
transaction.creationDate = new Date(
nMonthsBefore(transaction.creationDate, creation.moveCreationDate),
)
transaction.balanceDate = new Date(
nMonthsBefore(transaction.balanceDate, creation.moveCreationDate),
)
await transaction.save()
await confirmedContribution.save()
}
}
return confirmedContribution
} else {
return contribution
}
return creationFactoryDb(creation)
}

View File

@ -1,46 +1,13 @@
import { ApolloServerTestClient } from 'apollo-server-testing'
import { TransactionLink } from 'database'
import {
transactionLinkFactory as transactionLinkFactoryDb,
TransactionLinkInterface
} from 'database'
import { transactionLinkExpireDate } from '@/graphql/resolver/TransactionLinkResolver'
import { createTransactionLink, login } from '@/seeds/graphql/mutations'
import { TransactionLinkInterface } from '@/seeds/transactionLink/TransactionLinkInterface'
export { TransactionLinkInterface }
export const transactionLinkFactory = async (
client: ApolloServerTestClient,
export async function transactionLinkFactory (
_client: any,
transactionLink: TransactionLinkInterface,
): Promise<void> => {
const { mutate } = client
// login
await mutate({
mutation: login,
variables: { email: transactionLink.email, password: 'Aa12345_' },
})
const variables = {
amount: transactionLink.amount,
memo: transactionLink.memo,
}
// get the transaction links's id
const {
data: {
createTransactionLink: { id },
},
} = await mutate({ mutation: createTransactionLink, variables })
if (transactionLink.createdAt || transactionLink.deletedAt) {
const dbTransactionLink = await TransactionLink.findOneOrFail({ where: { id } })
if (transactionLink.createdAt) {
dbTransactionLink.createdAt = transactionLink.createdAt
dbTransactionLink.validUntil = transactionLinkExpireDate(transactionLink.createdAt)
await dbTransactionLink.save()
}
if (transactionLink.deletedAt) {
dbTransactionLink.deletedAt = new Date(dbTransactionLink.createdAt.getTime() + 1000)
await dbTransactionLink.save()
}
}
): Promise<void> {
await transactionLinkFactoryDb(transactionLink)
}

View File

@ -1,77 +1,35 @@
import { ApolloServerTestClient } from 'apollo-server-testing'
import { User } from 'database'
import { User, userFactory as userFactoryDb, userFactoryBulk as userFactoryBulkDb, Community } from 'database'
import { RoleNames } from '@enum/RoleNames'
import { setUserRole } from '@/graphql/resolver/util/modifyUserRole'
import { writeHomeCommunityEntry } from '@/seeds/community'
import { createUser, setPassword } from '@/seeds/graphql/mutations'
import { UserInterface } from '@/seeds/users/UserInterface'
import { encryptPassword } from '@/password/PasswordEncryptor'
export const userFactory = async (
client: ApolloServerTestClient,
_client: any,
user: UserInterface,
): Promise<User> => {
const { mutate } = client
const homeCom = await writeHomeCommunityEntry()
// console.log('call createUser with', JSON.stringify(user, null, 2))
const response = await mutate({ mutation: createUser, variables: user })
if (!response?.data?.createUser) {
// console.log(JSON.stringify(response, null, 2))
throw new Error('createUser mutation returned unexpected response')
}
const {
data: {
createUser: { id },
},
} = response
// get user from database
let dbUser = await User.findOneOrFail({ where: { id }, relations: ['emailContact', 'userRoles'] })
const emailContact = dbUser.emailContact
const dbUser = await userFactoryDb(user, homeCom)
if (user.emailChecked) {
await mutate({
mutation: setPassword,
variables: { password: 'Aa12345_', code: emailContact.emailVerificationCode },
})
}
// get last changes of user from database
dbUser = await User.findOneOrFail({ where: { id }, relations: { userRoles: true, emailContact: true } })
if (user.createdAt || user.deletedAt || user.role) {
if (user.createdAt) {
dbUser.createdAt = user.createdAt
// make sure emailContact is also updated for e2e test, prevent failing when time between seeding and test run is < 1 minute
dbUser.emailContact.createdAt = user.createdAt
dbUser.emailContact.updatedAt = user.createdAt
await dbUser.emailContact.save()
}
if (user.deletedAt) {
dbUser.deletedAt = user.deletedAt
}
const userRole = user.role as RoleNames
if (userRole && (userRole === RoleNames.ADMIN || userRole === RoleNames.MODERATOR)) {
await setUserRole(dbUser, user.role)
}
const passwortHash = await encryptPassword(dbUser, 'Aa12345_')
dbUser.password = passwortHash
await dbUser.save()
}
try {
if (homeCom.communityUuid) {
dbUser.communityUuid = homeCom.communityUuid
await User.save(dbUser)
}
} catch (_err) {
// no homeCommunity exists
}
// get last changes of user from database
dbUser = await User.findOneOrFail({
where: { id },
withDeleted: true,
relations: ['emailContact', 'userRoles'],
})
return dbUser
}
export async function userFactoryBulk(users: UserInterface[], homeCommunity?: Community | null) {
if (!homeCommunity) {
homeCommunity = await writeHomeCommunityEntry()
}
const dbUsers = await userFactoryBulkDb(users, homeCommunity)
for (const dbUser of dbUsers) {
if (dbUser.emailContact.emailChecked) {
const passwortHash = await encryptPassword(dbUser, 'Aa12345_')
dbUser.password = passwortHash
await dbUser.save()
}
}
return dbUsers
}

View File

@ -1,10 +1,13 @@
import { createTestClient } from 'apollo-server-testing'
import { entities } from 'database'
import { datatype, internet, name } from 'faker'
import {
AppDatabase,
User,
UserInterface,
creationFactoryBulk,
transactionLinkFactoryBulk
} from 'database'
import { internet, name } from 'faker'
import { CONFIG } from '@/config'
import { CONFIG as CORE_CONFIG } from 'core'
import { createServer } from '@/server/createServer'
import { initLogging } from '@/server/logger'
import { getLogger } from 'log4js'
@ -12,95 +15,87 @@ import { writeHomeCommunityEntry } from './community'
import { contributionLinks } from './contributionLink/index'
import { creations } from './creation/index'
import { contributionLinkFactory } from './factory/contributionLink'
import { creationFactory } from './factory/creation'
import { transactionLinkFactory } from './factory/transactionLink'
import { userFactory } from './factory/user'
import { userFactoryBulk } from './factory/user'
import { transactionLinks } from './transactionLink/index'
import { users } from './users/index'
CORE_CONFIG.EMAIL = false
const RANDOM_USER_COUNT = 100
const logger = getLogger('seed')
const context = {
token: '',
setHeaders: {
push: (value: { key: string; value: string }): void => {
context.token = value.value
},
forEach: (): void => {
// do nothing
},
},
clientTimezoneOffset: 0,
}
export const cleanDB = async () => {
// this only works as long we do not have foreign key constraints
for (const entity of entities) {
if (entity.name !== 'Migration') {
await resetEntity(entity)
}
}
}
const resetEntity = async (entity: any) => {
const items = await entity.find({ withDeleted: true })
if (items.length > 0) {
const ids = items.map((e: any) => e.id)
await entity.delete(ids)
}
}
const run = async () => {
initLogging()
const server = await createServer(getLogger('apollo'), context)
const seedClient = createTestClient(server.apollo)
const { con } = server
await cleanDB()
logger.info('##seed## clean database successful...')
const db = AppDatabase.getInstance()
await db.init()
await clearDatabase(db)
logger.info('clean database successful...')
logger.info(`crypto worker enabled: ${CONFIG.USE_CRYPTO_WORKER}`)
// seed home community
await writeHomeCommunityEntry()
const homeCommunity = await writeHomeCommunityEntry()
// seed the standard users
for (const user of users) {
await userFactory(seedClient, user)
// put into map for later direct access
const userCreationIndexedByEmail = new Map<string, User>()
const defaultUsers = await userFactoryBulk(users, homeCommunity)
for (const dbUser of defaultUsers) {
userCreationIndexedByEmail.set(dbUser.emailContact.email, dbUser)
}
logger.info('##seed## seeding all standard users successful...')
logger.info('seeding all standard users successful...')
// seed 100 random users
for (let i = 0; i < 100; i++) {
await userFactory(seedClient, {
const randomUsers = new Array<UserInterface>(RANDOM_USER_COUNT)
for (let i = 0; i < RANDOM_USER_COUNT; i++) {
randomUsers[i] = {
firstName: name.firstName(),
lastName: name.lastName(),
email: internet.email(),
language: datatype.boolean() ? 'en' : 'de',
})
logger.info(`##seed## seed ${i}. random user`)
language: Math.random() < 0.5 ? 'en' : 'de',
}
}
logger.info('##seed## seeding all random users successful...')
await userFactoryBulk(randomUsers, homeCommunity)
logger.info('seeding all random users successful...')
// create GDD
for (const creation of creations) {
await creationFactory(seedClient, creation)
}
logger.info('##seed## seeding all creations successful...')
const moderatorUser = userCreationIndexedByEmail.get('peter@lustig.de')!
await creationFactoryBulk(creations, userCreationIndexedByEmail, moderatorUser)
logger.info('seeding all creations successful...')
// create Transaction Links
for (const transactionLink of transactionLinks) {
await transactionLinkFactory(seedClient, transactionLink)
}
logger.info('##seed## seeding all transactionLinks successful...')
const movedTransactionLinks = transactionLinks.map(transactionLink => {
let createdAt = new Date(new Date().getTime() + 1000)
if (transactionLink.createdAt) {
createdAt = transactionLink.createdAt
}
return {
...transactionLink,
createdAt: createdAt,
}
})
await transactionLinkFactoryBulk(movedTransactionLinks, userCreationIndexedByEmail)
logger.info('seeding all transactionLinks successful...')
// create Contribution Links
for (const contributionLink of contributionLinks) {
await contributionLinkFactory(seedClient, contributionLink)
await contributionLinkFactory(null, contributionLink)
}
logger.info('##seed## seeding all contributionLinks successful...')
logger.info('seeding all contributionLinks successful...')
await con.destroy()
await db.destroy()
}
async function clearDatabase(db: AppDatabase) {
await db.getDataSource().transaction(async trx => {
await trx.query(`SET FOREIGN_KEY_CHECKS = 0`)
await trx.query(`TRUNCATE TABLE contributions`)
await trx.query(`TRUNCATE TABLE contribution_links`)
await trx.query(`TRUNCATE TABLE users`)
await trx.query(`TRUNCATE TABLE user_contacts`)
await trx.query(`TRUNCATE TABLE user_roles`)
await trx.query(`TRUNCATE TABLE transactions`)
await trx.query(`TRUNCATE TABLE transaction_links`)
await trx.query(`TRUNCATE TABLE communities`)
await trx.query(`SET FOREIGN_KEY_CHECKS = 1`)
})
}
run().catch((err) => {

View File

@ -1,3 +1,5 @@
export { TransactionLinkInterface } from 'database'
/*
export interface TransactionLinkInterface {
email: string
amount: number
@ -8,3 +10,4 @@ export interface TransactionLinkInterface {
// redeemedBy?: number
deletedAt?: boolean
}
*/

View File

@ -1,3 +1,5 @@
export { transactionLinks } from 'database'
/*
import { TransactionLinkInterface } from './TransactionLinkInterface'
export const transactionLinks: TransactionLinkInterface[] = [
@ -53,3 +55,4 @@ bei Gradidio sei dabei!`,
deletedAt: true,
},
]
*/

View File

@ -1,3 +1,5 @@
export { UserInterface } from 'database'
/*
export interface UserInterface {
alias?: string
email?: string
@ -11,3 +13,4 @@ export interface UserInterface {
publisherId?: number
role?: string
}
*/

View File

@ -1,3 +1,5 @@
export { bibiBloxberg } from 'database'
/*
import { UserInterface } from './UserInterface'
export const bibiBloxberg: UserInterface = {
@ -12,3 +14,4 @@ export const bibiBloxberg: UserInterface = {
// move user createdAt before transaction link
createdAt: new Date(2021, 9, 17),
}
*/

View File

@ -1,3 +1,5 @@
export { bobBaumeister } from 'database'
/*
import { UserInterface } from './UserInterface'
export const bobBaumeister: UserInterface = {
@ -9,3 +11,4 @@ export const bobBaumeister: UserInterface = {
emailChecked: true,
language: 'de',
}
*/

View File

@ -1,3 +1,6 @@
export { garrickOllivander } from 'database'
/*
import { UserInterface } from './UserInterface'
export const garrickOllivander: UserInterface = {
@ -10,3 +13,4 @@ export const garrickOllivander: UserInterface = {
emailChecked: false,
language: 'en',
}
*/

View File

@ -1,3 +1,5 @@
export { peterLustig } from 'database'
/*
import { RoleNames } from '@enum/RoleNames'
import { UserInterface } from './UserInterface'
@ -12,3 +14,4 @@ export const peterLustig: UserInterface = {
language: 'de',
role: RoleNames.ADMIN,
}
*/

View File

@ -1,3 +1,6 @@
export { raeuberHotzenplotz } from 'database'
/*
import { UserInterface } from './UserInterface'
export const raeuberHotzenplotz: UserInterface = {
@ -8,3 +11,4 @@ export const raeuberHotzenplotz: UserInterface = {
emailChecked: true,
language: 'de',
}
*/

View File

@ -1,3 +1,5 @@
export { stephenHawking } from 'database'
/*
import { UserInterface } from './UserInterface'
export const stephenHawking: UserInterface = {
@ -10,3 +12,4 @@ export const stephenHawking: UserInterface = {
deletedAt: new Date('2018-03-14T09:17:52'),
language: 'en',
}
*/

View File

@ -61,7 +61,7 @@
},
// "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",
"../@types",
"node_modules/@types",
"../node_modules/@types",
],

276
bun.lock
View File

@ -248,7 +248,7 @@
"@types/mysql": "^2.15.27",
"@types/node": "^18.7.14",
"await-semaphore": "^0.1.3",
"crypto-random-bigint": "^2.1.1",
"random-bigint": "^0.0.1",
"ts-node": "^10.9.2",
"typescript": "^4.9.5",
},
@ -653,6 +653,8 @@
"@csstools/css-parser-algorithms": ["@csstools/css-parser-algorithms@3.0.5", "", { "peerDependencies": { "@csstools/css-tokenizer": "^3.0.4" } }, "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ=="],
"@csstools/css-syntax-patches-for-csstree": ["@csstools/css-syntax-patches-for-csstree@1.0.20", "", {}, "sha512-8BHsjXfSciZxjmHQOuVdW2b8WLUPts9a+mfL13/PzEviufUEW2xnvQuOlKs9dRBHgRqJ53SF/DUoK9+MZk72oQ=="],
"@csstools/css-tokenizer": ["@csstools/css-tokenizer@3.0.4", "", {}, "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw=="],
"@csstools/media-query-list-parser": ["@csstools/media-query-list-parser@4.0.3", "", { "peerDependencies": { "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4" } }, "sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ=="],
@ -753,7 +755,7 @@
"@iconify-json/mdi": ["@iconify-json/mdi@1.2.3", "", { "dependencies": { "@iconify/types": "*" } }, "sha512-O3cLwbDOK7NNDf2ihaQOH5F9JglnulNDFV7WprU2dSoZu3h3cWH//h74uQAB87brHmvFVxIOkuBX2sZSzYhScg=="],
"@iconify/json": ["@iconify/json@2.2.411", "", { "dependencies": { "@iconify/types": "*", "pathe": "^2.0.3" } }, "sha512-lbNY5utR46XT2seUTBNiqKwd0uxSq2lJfyg8WRxpThmlS1bk79eSToT9biraG1wzKKt0tCjJos9aZxj5Us9RTw=="],
"@iconify/json": ["@iconify/json@2.2.413", "", { "dependencies": { "@iconify/types": "*", "pathe": "^2.0.3" } }, "sha512-0MpvnDjGoFuVgDLZkaAi3UzUJbfXhiaouLp50/eCJvbiXPtOHpcYkRfT++Zu+YR3meDn9KDRZQF/VS7OFPIMIA=="],
"@iconify/types": ["@iconify/types@2.0.0", "", {}, "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="],
@ -775,10 +777,6 @@
"@ioredis/commands": ["@ioredis/commands@1.4.0", "", {}, "sha512-aFT2yemJJo+TZCmieA7qnYGQooOS7QfNmYrzGtsYd3g9j5iDP8AimYYAesf79ohjbLG12XxC4nG5DyEnC88AsQ=="],
"@isaacs/balanced-match": ["@isaacs/balanced-match@4.0.1", "", {}, "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ=="],
"@isaacs/brace-expansion": ["@isaacs/brace-expansion@5.0.0", "", { "dependencies": { "@isaacs/balanced-match": "^4.0.1" } }, "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA=="],
"@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "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" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
"@istanbuljs/load-nyc-config": ["@istanbuljs/load-nyc-config@1.1.0", "", { "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" } }, "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ=="],
@ -1017,7 +1015,7 @@
"@smithy/config-resolver": ["@smithy/config-resolver@4.4.3", "", { "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" } }, "sha512-ezHLe1tKLUxDJo2LHtDuEDyWXolw8WGOR92qb4bQdWq/zKenO5BvctZGrVJBK08zjezSk7bmbKFOXIVyChvDLw=="],
"@smithy/core": ["@smithy/core@3.18.5", "", { "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" } }, "sha512-6gnIz3h+PEPQGDj8MnRSjDvKBah042jEoPgjFGJ4iJLBE78L4lY/n98x14XyPF4u3lN179Ub/ZKFY5za9GeLQw=="],
"@smithy/core": ["@smithy/core@3.18.6", "", { "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" } }, "sha512-8Q/ugWqfDUEU1Exw71+DoOzlONJ2Cn9QA8VeeDzLLjzO/qruh9UKFzbszy4jXcIYgGofxYiT0t1TT6+CT/GupQ=="],
"@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.5", "", { "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" } }, "sha512-BZwotjoZWn9+36nimwm/OLIcVe+KYRwzMjfhd4QT7QxPm9WY0HiOV8t/Wlh+HVUif0SBVV7ksq8//hPaBC/okQ=="],
@ -1031,9 +1029,9 @@
"@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.5", "", { "dependencies": { "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-Y/RabVa5vbl5FuHYV2vUCwvh/dqzrEY/K2yWPSqvhFUwIY0atLqO4TienjBXakoy4zrKAMCZwg+YEqmH7jaN7A=="],
"@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.3.12", "", { "dependencies": { "@smithy/core": "^3.18.5", "@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" } }, "sha512-9pAX/H+VQPzNbouhDhkW723igBMLgrI8OtX+++M7iKJgg/zY/Ig3i1e6seCcx22FWhE6Q/S61BRdi2wXBORT+A=="],
"@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.3.13", "", { "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" } }, "sha512-X4za1qCdyx1hEVVXuAWlZuK6wzLDv1uw1OY9VtaYy1lULl661+frY7FeuHdYdl7qAARUxH2yvNExU2/SmRFfcg=="],
"@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.12", "", { "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.8", "@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" } }, "sha512-S4kWNKFowYd0lID7/DBqWHOQxmxlsf0jBaos9chQZUWTVOjSW1Ogyh8/ib5tM+agFDJ/TCxuCTvrnlc+9cIBcQ=="],
"@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.13", "", { "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" } }, "sha512-RzIDF9OrSviXX7MQeKOm8r/372KTyY8Jmp6HNKOOYlrguHADuM3ED/f4aCyNhZZFLG55lv5beBin7nL0Nzy1Dw=="],
"@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.6", "", { "dependencies": { "@smithy/protocol-http": "^5.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-VkLoE/z7e2g8pirwisLz8XJWedUSY8my/qrp81VmAdyrhi94T+riBfwP+AOEEFR9rFTSonC/5D2eWNmFabHyGQ=="],
@ -1057,7 +1055,7 @@
"@smithy/signature-v4": ["@smithy/signature-v4@5.3.5", "", { "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" } }, "sha512-xSUfMu1FT7ccfSXkoLl/QRQBi2rOvi3tiBZU2Tdy3I6cgvZ6SEi9QNey+lqps/sJRnogIS+lq+B1gxxbra2a/w=="],
"@smithy/smithy-client": ["@smithy/smithy-client@4.9.8", "", { "dependencies": { "@smithy/core": "^3.18.5", "@smithy/middleware-endpoint": "^4.3.12", "@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" } }, "sha512-8xgq3LgKDEFoIrLWBho/oYKyWByw9/corz7vuh1upv7ZBm0ZMjGYBhbn6v643WoIqA9UTcx5A5htEp/YatUwMA=="],
"@smithy/smithy-client": ["@smithy/smithy-client@4.9.9", "", { "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" } }, "sha512-SUnZJMMo5yCmgjopJbiNeo1vlr8KvdnEfIHV9rlD77QuOGdRotIVBcOrBuMr+sI9zrnhtDtLP054bZVbpZpiQA=="],
"@smithy/types": ["@smithy/types@4.9.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-MvUbdnXDTwykR8cB1WZvNNwqoWVaTRA0RLlLmf/cIFNMM2cKWz01X4Ly6SMC4Kks30r8tT3Cty0jmeWfiuyHTA=="],
@ -1073,9 +1071,9 @@
"@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q=="],
"@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.11", "", { "dependencies": { "@smithy/property-provider": "^4.2.5", "@smithy/smithy-client": "^4.9.8", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-yHv+r6wSQXEXTPVCIQTNmXVWs7ekBTpMVErjqZoWkYN75HIFN5y9+/+sYOejfAuvxWGvgzgxbTHa/oz61YTbKw=="],
"@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.12", "", { "dependencies": { "@smithy/property-provider": "^4.2.5", "@smithy/smithy-client": "^4.9.9", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-TKc6FnOxFULKxLgTNHYjcFqdOYzXVPFFVm5JhI30F3RdhT7nYOtOsjgaOwfDRmA/3U66O9KaBQ3UHoXwayRhAg=="],
"@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.14", "", { "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.8", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-ljZN3iRvaJUgulfvobIuG97q1iUuCMrvXAlkZ4msY+ZuVHQHDIqn7FKZCEj+bx8omz6kF5yQXms/xhzjIO5XiA=="],
"@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.15", "", { "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" } }, "sha512-94NqfQVo+vGc5gsQ9SROZqOvBkGNMQu6pjXbnn8aQvBUhc31kx49gxlkBEqgmaZQHUUfdRUin5gK/HlHKmbAwg=="],
"@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.5", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.5", "@smithy/types": "^4.9.0", "tslib": "^2.6.2" } }, "sha512-3O63AAWu2cSNQZp+ayl9I3NapW1p1rR5mlVHcF6hAB1dPZUQFfRPYtplWX/3xrzWthPGj5FqB12taJJCfH6s8A=="],
@ -1245,7 +1243,7 @@
"@types/semver": ["@types/semver@7.7.1", "", {}, "sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA=="],
"@types/send": ["@types/send@0.17.6", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og=="],
"@types/send": ["@types/send@1.2.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ=="],
"@types/serve-static": ["@types/serve-static@1.15.10", "", { "dependencies": { "@types/http-errors": "*", "@types/node": "*", "@types/send": "<1" } }, "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw=="],
@ -1589,7 +1587,7 @@
"base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
"baseline-browser-mapping": ["baseline-browser-mapping@2.8.31", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-a28v2eWrrRWPpJSzxc+mKwm0ZtVx/G8SepdQZDArnXYU/XS+IF6mp8aB/4E+hH1tyGCoDo3KlUCdlSxGDsRkAw=="],
"baseline-browser-mapping": ["baseline-browser-mapping@2.8.32", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw=="],
"bignumber.js": ["bignumber.js@9.0.0", "", {}, "sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A=="],
@ -1603,7 +1601,7 @@
"bluebird": ["bluebird@3.7.2", "", {}, "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="],
"body-parser": ["body-parser@1.20.3", "", { "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.13.0", "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" } }, "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g=="],
"body-parser": ["body-parser@1.20.4", "", { "dependencies": { "bytes": "~3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "~1.2.0", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "on-finished": "~2.4.1", "qs": "~6.14.0", "raw-body": "~2.5.3", "type-is": "~1.6.18", "unpipe": "~1.0.0" } }, "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA=="],
"bogon": ["bogon@1.1.0", "", { "dependencies": { "compact-encoding": "^2.11.0", "compact-encoding-net": "^1.2.0" } }, "sha512-a6SnToksXHuUlgeMvI/txWmTcKz7c7iBa8f0HbXL4toN1Uza/CTQ4F7n9jSDX49TCpxv3KUP100q4sZfwLyLiw=="],
@ -1615,9 +1613,9 @@
"bootstrap-vue-next": ["bootstrap-vue-next@0.26.8", "", { "peerDependencies": { "vue": "^3.5.13" } }, "sha512-2WolMPi4XB0J/736PPglDCIjUz2pwvOhu3SLjQYP0Rh5IncspMZMkUCa/H28Vh45xQadFtrYeBPyPF3JrpbadA=="],
"bowser": ["bowser@2.13.0", "", {}, "sha512-yHAbSRuT6LTeKi6k2aS40csueHqgAsFEgmrOsfRyFpJnFv5O2hl9FYmWEUZ97gZ/dG17U4IQQcTx4YAFYPuWRQ=="],
"bowser": ["bowser@2.13.1", "", {}, "sha512-OHawaAbjwx6rqICCKgSG0SAnT05bzd7ppyKLVUITZpANBaaMFBAsaNkto3LoQ31tyFP5kNujE8Cdx85G9VzOkw=="],
"brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
@ -1747,9 +1745,9 @@
"convert-source-map": ["convert-source-map@1.9.0", "", {}, "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="],
"cookie": ["cookie@0.7.1", "", {}, "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w=="],
"cookie": ["cookie@0.7.2", "", {}, "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w=="],
"cookie-signature": ["cookie-signature@1.0.6", "", {}, "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ=="],
"cookie-signature": ["cookie-signature@1.0.7", "", {}, "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA=="],
"copy-anything": ["copy-anything@4.0.5", "", { "dependencies": { "is-what": "^5.2.0" } }, "sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA=="],
@ -1771,8 +1769,6 @@
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
"crypto-random-bigint": ["crypto-random-bigint@2.1.1", "", { "dependencies": { "uint-rng": "^1.2.1" } }, "sha512-96+FDrenXybkpnLML/60S8NcG32KgJ5Y8yvNNCYPW02r+ssoXFR5XKenuIQcHLWumnGj8UPqUUHBzXNrDGkDmQ=="],
"css-functions-list": ["css-functions-list@3.2.3", "", {}, "sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA=="],
"css-select": ["css-select@4.3.0", "", { "dependencies": { "boolbase": "^1.0.0", "css-what": "^6.0.1", "domhandler": "^4.3.1", "domutils": "^2.8.0", "nth-check": "^2.0.1" } }, "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ=="],
@ -2033,7 +2029,7 @@
"expect-type": ["expect-type@1.2.2", "", {}, "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA=="],
"express": ["express@4.21.2", "", { "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "1.20.3", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.7.1", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "1.3.1", "fresh": "0.5.2", "http-errors": "2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.12", "proxy-addr": "~2.0.7", "qs": "6.13.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.19.0", "serve-static": "1.16.2", "setprototypeof": "1.2.0", "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" } }, "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA=="],
"express": ["express@4.22.1", "", { "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", "body-parser": "~1.20.3", "content-disposition": "~0.5.4", "content-type": "~1.0.4", "cookie": "~0.7.1", "cookie-signature": "~1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "finalhandler": "~1.3.1", "fresh": "~0.5.2", "http-errors": "~2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", "on-finished": "~2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", "qs": "~6.14.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "~0.19.0", "serve-static": "~1.16.2", "setprototypeof": "1.2.0", "statuses": "~2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" } }, "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g=="],
"express-rate-limit": ["express-rate-limit@7.5.1", "", { "peerDependencies": { "express": ">= 4.11" } }, "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw=="],
@ -2097,7 +2093,7 @@
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
"finalhandler": ["finalhandler@1.3.1", "", { "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "2.4.1", "parseurl": "~1.3.3", "statuses": "2.0.1", "unpipe": "~1.0.0" } }, "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ=="],
"finalhandler": ["finalhandler@1.3.2", "", { "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "on-finished": "~2.4.1", "parseurl": "~1.3.3", "statuses": "~2.0.2", "unpipe": "~1.0.0" } }, "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg=="],
"find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
@ -2237,7 +2233,7 @@
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
"hashery": ["hashery@1.2.0", "", { "dependencies": { "hookified": "^1.13.0" } }, "sha512-43XJKpwle72Ik5Zpam7MuzRWyNdwwdf6XHlh8wCj2PggvWf+v/Dm5B0dxGZOmddidgeO6Ofu9As/o231Ti/9PA=="],
"hashery": ["hashery@1.3.0", "", { "dependencies": { "hookified": "^1.13.0" } }, "sha512-fWltioiy5zsSAs9ouEnvhsVJeAXRybGCNNv0lvzpzNOSDbULXRy7ivFWwCCv4I5Am6kSo75hmbsCduOoc2/K4w=="],
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
@ -2265,7 +2261,7 @@
"http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="],
"http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
"http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="],
"http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="],
@ -2559,7 +2555,7 @@
"libmime": ["libmime@5.3.7", "", { "dependencies": { "encoding-japanese": "2.2.0", "iconv-lite": "0.6.3", "libbase64": "1.3.0", "libqp": "2.1.1" } }, "sha512-FlDb3Wtha8P01kTL3P9M+ZDNDWPKPmKHWaU/cG/lg5pfuAwdflVpZE+wm9m7pKmC5ww6s+zTxBKS1p6yl3KpSw=="],
"libphonenumber-js": ["libphonenumber-js@1.12.29", "", {}, "sha512-P2aLrbeqHbmh8+9P35LXQfXOKc7XJ0ymUKl7tyeyQjdRNfzunXWxQXGc4yl3fUf28fqLRfPY+vIVvFXK7KEBTw=="],
"libphonenumber-js": ["libphonenumber-js@1.12.30", "", {}, "sha512-KxH7uIJFD6+cR6nhdh+wY6prFiH26A3W/W1gTMXnng2PXSwVfi5MhYkdq3Z2Y7vhBVa1/5VJgpNtI76UM2njGA=="],
"libqp": ["libqp@2.1.1", "", {}, "sha512-0Wd+GPz1O134cP62YU2GTOPNA7Qgl09XwCqM5zpBv87ERCXdfDtyKXvV7c9U22yWJh44QZqBocFnXN11K96qow=="],
@ -2681,7 +2677,7 @@
"mimic-response": ["mimic-response@4.0.0", "", {}, "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg=="],
"minimatch": ["minimatch@10.1.1", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ=="],
"minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
@ -2905,7 +2901,7 @@
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
"prettier": ["prettier@3.7.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-RWKXE4qB3u5Z6yz7omJkjWwmTfLdcbv44jUVHC5NpfXwFGzvpQM798FGv/6WNK879tc+Cn0AAyherCl1KjbyZQ=="],
"prettier": ["prettier@3.7.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QgODejq9K3OzoBbuyobZlUhznP5SKwPqp+6Q6xw6o8gnhr4O85L2U915iM2IDcfF2NPXVaM9zlo9tdwipnYwzg=="],
"prettier-linter-helpers": ["prettier-linter-helpers@1.0.0", "", { "dependencies": { "fast-diff": "^1.1.2" } }, "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w=="],
@ -2967,7 +2963,7 @@
"qrcode-generator": ["qrcode-generator@1.5.2", "", {}, "sha512-pItrW0Z9HnDBnFmgiNrY1uxRdri32Uh9EjNYLPVC2zZ3ZRIIEqBoDgm4DkvDwNNDHTK7FNkmr8zAa77BYc9xNw=="],
"qs": ["qs@6.13.0", "", { "dependencies": { "side-channel": "^1.0.6" } }, "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg=="],
"qs": ["qs@6.14.0", "", { "dependencies": { "side-channel": "^1.1.0" } }, "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w=="],
"quansync": ["quansync@0.2.11", "", {}, "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA=="],
@ -2987,7 +2983,7 @@
"range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
"raw-body": ["raw-body@2.5.2", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA=="],
"raw-body": ["raw-body@2.5.3", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "unpipe": "~1.0.0" } }, "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA=="],
"rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="],
@ -3095,7 +3091,7 @@
"semver-truncate": ["semver-truncate@3.0.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-LJWA9kSvMolR51oDE6PN3kALBNaUdkxzAGcexw8gjMA8xr5zUqK0JiR3CgARSqanYF3Z1YHvsErb1KDgh+v7Rg=="],
"send": ["send@0.19.0", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" } }, "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw=="],
"send": ["send@0.19.1", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" } }, "sha512-p4rRk4f23ynFEfcD9LA0xRYngj+IyGiEYyqqOak8kaN0TvNmuxC2dcVeBn62GpCeR2CpWqyHCNScTP91QbAVFg=="],
"seq-queue": ["seq-queue@0.0.5", "", {}, "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q=="],
@ -3175,7 +3171,7 @@
"standard-as-callback": ["standard-as-callback@2.1.0", "", {}, "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="],
"statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
"statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
"std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="],
@ -3219,7 +3215,7 @@
"strtok3": ["strtok3@10.3.4", "", { "dependencies": { "@tokenizer/token": "^0.3.0" } }, "sha512-KIy5nylvC5le1OdaaoCJ07L+8iQzJHGH6pWDuzS+d07Cu7n1MZ2x26P8ZKIWfbK02+XIL8Mp4RkWeqdUCrDMfg=="],
"stylelint": ["stylelint@16.26.0", "", { "dependencies": { "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-tokenizer": "^3.0.4", "@csstools/media-query-list-parser": "^4.0.3", "@csstools/selector-specificity": "^5.0.0", "@dual-bundle/import-meta-resolve": "^4.2.1", "balanced-match": "^2.0.0", "colord": "^2.9.3", "cosmiconfig": "^9.0.0", "css-functions-list": "^3.2.3", "css-tree": "^3.1.0", "debug": "^4.4.3", "fast-glob": "^3.3.3", "fastest-levenshtein": "^1.0.16", "file-entry-cache": "^11.1.0", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", "html-tags": "^3.3.1", "ignore": "^7.0.5", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", "known-css-properties": "^0.37.0", "mathml-tag-names": "^2.1.3", "meow": "^13.2.0", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.5.6", "postcss-resolve-nested-selector": "^0.1.6", "postcss-safe-parser": "^7.0.1", "postcss-selector-parser": "^7.1.0", "postcss-value-parser": "^4.2.0", "resolve-from": "^5.0.0", "string-width": "^4.2.3", "supports-hyperlinks": "^3.2.0", "svg-tags": "^1.0.0", "table": "^6.9.0", "write-file-atomic": "^5.0.1" }, "bin": { "stylelint": "bin/stylelint.mjs" } }, "sha512-Y/3AVBefrkqqapVYH3LBF5TSDZ1kw+0XpdKN2KchfuhMK6lQ85S4XOG4lIZLcrcS4PWBmvcY6eS2kCQFz0jukQ=="],
"stylelint": ["stylelint@16.26.1", "", { "dependencies": { "@csstools/css-parser-algorithms": "^3.0.5", "@csstools/css-syntax-patches-for-csstree": "^1.0.19", "@csstools/css-tokenizer": "^3.0.4", "@csstools/media-query-list-parser": "^4.0.3", "@csstools/selector-specificity": "^5.0.0", "@dual-bundle/import-meta-resolve": "^4.2.1", "balanced-match": "^2.0.0", "colord": "^2.9.3", "cosmiconfig": "^9.0.0", "css-functions-list": "^3.2.3", "css-tree": "^3.1.0", "debug": "^4.4.3", "fast-glob": "^3.3.3", "fastest-levenshtein": "^1.0.16", "file-entry-cache": "^11.1.1", "global-modules": "^2.0.0", "globby": "^11.1.0", "globjoin": "^0.1.4", "html-tags": "^3.3.1", "ignore": "^7.0.5", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", "known-css-properties": "^0.37.0", "mathml-tag-names": "^2.1.3", "meow": "^13.2.0", "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "picocolors": "^1.1.1", "postcss": "^8.5.6", "postcss-resolve-nested-selector": "^0.1.6", "postcss-safe-parser": "^7.0.1", "postcss-selector-parser": "^7.1.0", "postcss-value-parser": "^4.2.0", "resolve-from": "^5.0.0", "string-width": "^4.2.3", "supports-hyperlinks": "^3.2.0", "svg-tags": "^1.0.0", "table": "^6.9.0", "write-file-atomic": "^5.0.1" }, "bin": { "stylelint": "bin/stylelint.mjs" } }, "sha512-v20V59/crfc8sVTAtge0mdafI3AdnzQ2KsWe6v523L4OA1bJO02S7MO2oyXDCS6iWb9ckIPnqAFVItqSBQr7jw=="],
"stylelint-config-html": ["stylelint-config-html@1.1.0", "", { "peerDependencies": { "postcss-html": "^1.0.0", "stylelint": ">=14.0.0" } }, "sha512-IZv4IVESjKLumUGi+HWeb7skgO6/g4VMuAYrJdlqQFndgbj6WJAXPhaysvBiXefX79upBdQVumgYcdd17gCpjQ=="],
@ -3283,8 +3279,6 @@
"tiny-case": ["tiny-case@1.0.3", "", {}, "sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q=="],
"tiny-webcrypto": ["tiny-webcrypto@1.0.3", "", {}, "sha512-LQQdNMAgz9BXNT2SKbYh3eCb+fLV0p7JB7MwUjzY6IOlQLGIadfnFqRpshERsS5Dl2OM/hs0+4I/XmSrF+RBbw=="],
"tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="],
"tinyexec": ["tinyexec@1.0.2", "", {}, "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg=="],
@ -3343,7 +3337,7 @@
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"tsx": ["tsx@4.20.6", "", { "dependencies": { "esbuild": "~0.25.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg=="],
"tsx": ["tsx@4.21.0", "", { "dependencies": { "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "bin": { "tsx": "dist/cli.mjs" } }, "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw=="],
"tua-body-scroll-lock": ["tua-body-scroll-lock@1.6.1", "", {}, "sha512-BKJ8Jg8/SoSeE2GgKXeLKYZesa5cIGUj3jupGtnM3HoZIa5dsa+p6aeHhN6rHlP1KW7bNDsc1fhKkf4fm0krug=="],
@ -3397,8 +3391,6 @@
"uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="],
"uint-rng": ["uint-rng@1.2.1", "", { "dependencies": { "tiny-webcrypto": "^1.0.2" } }, "sha512-swhDg5H+3DX2sIvnYA7VMBMXV/t8mPxvh49CjCDkwFmj/3OZIDOQwJANBgM1MPSUBrUHNIlXmU7/GcL7m4907g=="],
"uint8array-extras": ["uint8array-extras@1.5.0", "", {}, "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A=="],
"unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "^1.0.3", "has-bigints": "^1.0.2", "has-symbols": "^1.1.0", "which-boxed-primitive": "^1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="],
@ -3573,7 +3565,7 @@
"yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="],
"yaml": ["yaml@2.8.1", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw=="],
"yaml": ["yaml@2.8.2", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A=="],
"yaml-eslint-parser": ["yaml-eslint-parser@0.5.0", "", { "dependencies": { "eslint-visitor-keys": "^3.0.0", "lodash": "^4.17.21", "yaml": "^1.10.2" } }, "sha512-nJeyLA3YHAzhBTZbRAbu3W6xrSCucyxExmA+ZDtEdUFpGllxAZpto2Zxo2IG0r0eiuEiBM4e+wiAdxTziTq94g=="],
@ -3597,6 +3589,8 @@
"zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
"@anatine/esbuild-decorators/esbuild": ["esbuild@0.27.0", "", { "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" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA=="],
"@antfu/install-pkg/package-manager-detector": ["package-manager-detector@0.2.11", "", { "dependencies": { "quansync": "^0.2.7" } }, "sha512-BEnLolu+yuz22S56CU1SUKq3XC3PkwD5wv4ikR4MfGvnRVcmzXR9DwSlW2fEamyTPyXHomBJRzgapeuBvRNzJQ=="],
"@antfu/install-pkg/tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="],
@ -3637,7 +3631,7 @@
"@humanwhocodes/config-array/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"@hyperswarm/secret-stream/noise-handshake": ["noise-handshake@4.1.0", "", { "dependencies": { "b4a": "^1.1.0", "nanoassert": "^2.0.0", "sodium-universal": "^5.0.0" } }, "sha512-ZHt2+mOXTvjtaWS2h/JPvQjmknfKrEld2xdSsRYWXnYiJmK/N+dtxrDVSt1cr9wGAlhH7Ek43lIZNsL5bVeX9A=="],
"@hyperswarm/secret-stream/noise-handshake": ["noise-handshake@4.2.0", "", { "dependencies": { "b4a": "^1.1.0", "nanoassert": "^2.0.0", "sodium-universal": "^5.0.0" } }, "sha512-9O/VTNX/E2/AToyMTTDU0J/4WhaXMTdqc2DHs9vf+snoZ0cenSBq0dNYTVV1snYYEkmo6QeRrYMxtqtoYnY+LA=="],
"@hyperswarm/secret-stream/sodium-universal": ["sodium-universal@5.0.1", "", { "dependencies": { "sodium-native": "^5.0.1" }, "peerDependencies": { "sodium-javascript": "~0.8.0" }, "optionalPeers": ["sodium-javascript"] }, "sha512-rv+aH+tnKB5H0MAc2UadHShLMslpJsc4wjdnHRtiSIEYpOetCgu8MS4ExQRia+GL/MK3uuCyZPeEsi+J3h+Q+Q=="],
@ -3727,8 +3721,6 @@
"@swc/cli/commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="],
"@swc/cli/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"@types/accepts/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
"@types/body-parser/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
@ -3739,8 +3731,6 @@
"@types/cors/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
"@types/dotenv/dotenv": ["dotenv@16.6.1", "", {}, "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow=="],
"@types/express-serve-static-core/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
"@types/fs-capacitor/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
@ -3761,14 +3751,14 @@
"@types/serve-static/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
"@types/serve-static/@types/send": ["@types/send@0.17.6", "", { "dependencies": { "@types/mime": "^1", "@types/node": "*" } }, "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og=="],
"@types/sodium-native/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
"@types/source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
"@types/ws/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"@typescript-eslint/utils/@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@7.18.0", "", { "dependencies": { "@typescript-eslint/types": "7.18.0", "@typescript-eslint/visitor-keys": "7.18.0" } }, "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA=="],
"@typescript-eslint/utils/@typescript-eslint/types": ["@typescript-eslint/types@7.18.0", "", {}, "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ=="],
@ -4121,7 +4111,11 @@
"send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
"send/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="],
"send/http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
"send/statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
"serve-static/send": ["send@0.19.0", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", "http-errors": "2.0.0", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "2.4.1", "range-parser": "~1.2.1", "statuses": "2.0.1" } }, "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw=="],
"shared/@types/uuid": ["@types/uuid@10.0.0", "", {}, "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ=="],
@ -4177,14 +4171,14 @@
"test-exclude/glob": ["glob@10.5.0", "", { "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" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
"test-exclude/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"to-buffer/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
"ts-jest/jest": ["jest@27.5.1", "", { "dependencies": { "@jest/core": "^27.5.1", "import-local": "^3.0.2", "jest-cli": "^27.5.1" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, "optionalPeers": ["node-notifier"], "bin": { "jest": "bin/jest.js" } }, "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ=="],
"ts-jest/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
"tsx/esbuild": ["esbuild@0.27.0", "", { "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" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-jd0f4NHbD6cALCyGElNpGAOtWxSq46l9X/sWB0Nzd5er4Kz2YTm+Vl0qKFT9KUJvD8+fiO8AvoHhFvEatfVixA=="],
"type-graphql/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
"typeorm/ansis": ["ansis@3.17.0", "", {}, "sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg=="],
@ -4203,8 +4197,6 @@
"unplugin-vue-components/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
"unplugin-vue-components/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"vee-validate/@vue/devtools-api": ["@vue/devtools-api@7.7.9", "", { "dependencies": { "@vue/devtools-kit": "^7.7.9" } }, "sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g=="],
"vee-validate/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
@ -4249,6 +4241,58 @@
"yaml-eslint-parser/yaml": ["yaml@1.10.2", "", {}, "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.0", "", { "os": "aix", "cpu": "ppc64" }, "sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.0", "", { "os": "android", "cpu": "arm" }, "sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.0", "", { "os": "android", "cpu": "arm64" }, "sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.0", "", { "os": "android", "cpu": "x64" }, "sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.0", "", { "os": "linux", "cpu": "arm" }, "sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.0", "", { "os": "linux", "cpu": "ia32" }, "sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.0", "", { "os": "linux", "cpu": "none" }, "sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.0", "", { "os": "linux", "cpu": "none" }, "sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.0", "", { "os": "linux", "cpu": "none" }, "sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.0", "", { "os": "linux", "cpu": "x64" }, "sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.0", "", { "os": "none", "cpu": "arm64" }, "sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.0", "", { "os": "none", "cpu": "x64" }, "sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.0", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.0", "", { "os": "none", "cpu": "arm64" }, "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.0", "", { "os": "sunos", "cpu": "x64" }, "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ=="],
"@anatine/esbuild-decorators/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.0", "", { "os": "win32", "cpu": "x64" }, "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg=="],
"@apollographql/graphql-upload-8-fork/http-errors/depd": ["depd@1.1.2", "", {}, "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ=="],
"@apollographql/graphql-upload-8-fork/http-errors/statuses": ["statuses@1.5.0", "", {}, "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA=="],
@ -4259,6 +4303,10 @@
"@babel/helper-compilation-targets/lru-cache/yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
"@eslint/eslintrc/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"@humanwhocodes/config-array/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"@hyperswarm/secret-stream/sodium-universal/sodium-native": ["sodium-native@5.0.10", "", { "dependencies": { "require-addon": "^1.1.0", "which-runtime": "^1.2.1" } }, "sha512-UIw+0AbpCQRuTJF88JWrZomP4O+PXhlWvdopiAJOsUivTyHTf3korMyStxkZuPngSbBEtEfDdc4ewEd8/T4/lA=="],
"@intlify/vue-i18n-extensions/vue-i18n/@intlify/core-base": ["@intlify/core-base@10.0.8", "", { "dependencies": { "@intlify/message-compiler": "10.0.8", "@intlify/shared": "10.0.8" } }, "sha512-FoHslNWSoHjdUBLy35bpm9PV/0LVI/DSv9L6Km6J2ad8r/mm0VaGg06C40FqlE8u2ADcGUM60lyoU7Myo4WNZQ=="],
@ -4281,16 +4329,10 @@
"@jest/transform/write-file-atomic/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
"@swc/cli/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"@typescript-eslint/utils/@typescript-eslint/scope-manager/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@7.18.0", "", { "dependencies": { "@typescript-eslint/types": "7.18.0", "eslint-visitor-keys": "^3.4.3" } }, "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg=="],
"@typescript-eslint/utils/@typescript-eslint/typescript-estree/@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@7.18.0", "", { "dependencies": { "@typescript-eslint/types": "7.18.0", "eslint-visitor-keys": "^3.4.3" } }, "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg=="],
"@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"@typescript-eslint/utils/@typescript-eslint/typescript-estree/ts-api-utils": ["ts-api-utils@1.4.3", "", { "peerDependencies": { "typescript": ">=4.2.0" } }, "sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw=="],
"@vue/server-renderer/@vue/compiler-ssr/@vue/compiler-dom": ["@vue/compiler-dom@3.5.13", "", { "dependencies": { "@vue/compiler-core": "3.5.13", "@vue/shared": "3.5.13" } }, "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA=="],
@ -4321,22 +4363,28 @@
"dht-rpc/sodium-universal/sodium-native": ["sodium-native@5.0.10", "", { "dependencies": { "require-addon": "^1.1.0", "which-runtime": "^1.2.1" } }, "sha512-UIw+0AbpCQRuTJF88JWrZomP4O+PXhlWvdopiAJOsUivTyHTf3korMyStxkZuPngSbBEtEfDdc4ewEd8/T4/lA=="],
"editorconfig/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"eslint-plugin-import/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"eslint-plugin-import/tsconfig-paths/json5": ["json5@1.0.2", "", { "dependencies": { "minimist": "^1.2.0" }, "bin": { "json5": "lib/cli.js" } }, "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA=="],
"eslint-plugin-n/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"eslint-plugin-node/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"eslint-plugin-vue/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@2.1.0", "", {}, "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw=="],
"eslint/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"express/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
"federation/ts-jest/yargs-parser": ["yargs-parser@20.2.9", "", {}, "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="],
"filelist/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"finalhandler/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
"fixpack/chalk/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
"glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"html-to-text/htmlparser2/domhandler": ["domhandler@4.3.1", "", { "dependencies": { "domelementtype": "^2.2.0" } }, "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ=="],
"html-to-text/htmlparser2/domutils": ["domutils@2.8.0", "", { "dependencies": { "dom-serializer": "^1.0.1", "domelementtype": "^2.2.0", "domhandler": "^4.2.0" } }, "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A=="],
@ -4387,8 +4435,6 @@
"jest-worker/jest-util/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"js-beautify/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"jsdom/parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
"local-pkg/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="],
@ -4401,6 +4447,8 @@
"mlly/pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="],
"multimatch/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"node-fetch/whatwg-url/tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="],
"node-fetch/whatwg-url/webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
@ -4409,6 +4457,8 @@
"nodemon/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
"nodemon/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"noise-curve-ed/sodium-universal/sodium-native": ["sodium-native@5.0.10", "", { "dependencies": { "require-addon": "^1.1.0", "which-runtime": "^1.2.1" } }, "sha512-UIw+0AbpCQRuTJF88JWrZomP4O+PXhlWvdopiAJOsUivTyHTf3korMyStxkZuPngSbBEtEfDdc4ewEd8/T4/lA=="],
"pkg-dir/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="],
@ -4427,6 +4477,14 @@
"send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
"serve-static/send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
"serve-static/send/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="],
"serve-static/send/http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
"serve-static/send/statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="],
"sodium-secretstream/sodium-universal/sodium-native": ["sodium-native@5.0.10", "", { "dependencies": { "require-addon": "^1.1.0", "which-runtime": "^1.2.1" } }, "sha512-UIw+0AbpCQRuTJF88JWrZomP4O+PXhlWvdopiAJOsUivTyHTf3korMyStxkZuPngSbBEtEfDdc4ewEd8/T4/lA=="],
"streamroller/fs-extra/jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="],
@ -4443,16 +4501,62 @@
"terser-webpack-plugin/jest-worker/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="],
"test-exclude/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"tsx/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.0", "", { "os": "aix", "cpu": "ppc64" }, "sha512-KuZrd2hRjz01y5JK9mEBSD3Vj3mbCvemhT466rSuJYeE/hjuBrHfjjcjMdTm/sz7au+++sdbJZJmuBwQLuw68A=="],
"typeorm/glob/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"tsx/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.0", "", { "os": "android", "cpu": "arm" }, "sha512-j67aezrPNYWJEOHUNLPj9maeJte7uSMM6gMoxfPC9hOg8N02JuQi/T7ewumf4tNvJadFkvLZMlAq73b9uwdMyQ=="],
"tsx/esbuild/@esbuild/android-arm64": ["@esbuild/android-arm64@0.27.0", "", { "os": "android", "cpu": "arm64" }, "sha512-CC3vt4+1xZrs97/PKDkl0yN7w8edvU2vZvAFGD16n9F0Cvniy5qvzRXjfO1l94efczkkQE6g1x0i73Qf5uthOQ=="],
"tsx/esbuild/@esbuild/android-x64": ["@esbuild/android-x64@0.27.0", "", { "os": "android", "cpu": "x64" }, "sha512-wurMkF1nmQajBO1+0CJmcN17U4BP6GqNSROP8t0X/Jiw2ltYGLHpEksp9MpoBqkrFR3kv2/te6Sha26k3+yZ9Q=="],
"tsx/esbuild/@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.27.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-uJOQKYCcHhg07DL7i8MzjvS2LaP7W7Pn/7uA0B5S1EnqAirJtbyw4yC5jQ5qcFjHK9l6o/MX9QisBg12kNkdHg=="],
"tsx/esbuild/@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.27.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-8mG6arH3yB/4ZXiEnXof5MK72dE6zM9cDvUcPtxhUZsDjESl9JipZYW60C3JGreKCEP+p8P/72r69m4AZGJd5g=="],
"tsx/esbuild/@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.27.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-9FHtyO988CwNMMOE3YIeci+UV+x5Zy8fI2qHNpsEtSF83YPBmE8UWmfYAQg6Ux7Gsmd4FejZqnEUZCMGaNQHQw=="],
"tsx/esbuild/@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.27.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-zCMeMXI4HS/tXvJz8vWGexpZj2YVtRAihHLk1imZj4efx1BQzN76YFeKqlDr3bUWI26wHwLWPd3rwh6pe4EV7g=="],
"tsx/esbuild/@esbuild/linux-arm": ["@esbuild/linux-arm@0.27.0", "", { "os": "linux", "cpu": "arm" }, "sha512-t76XLQDpxgmq2cNXKTVEB7O7YMb42atj2Re2Haf45HkaUpjM2J0UuJZDuaGbPbamzZ7bawyGFUkodL+zcE+jvQ=="],
"tsx/esbuild/@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.27.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-AS18v0V+vZiLJyi/4LphvBE+OIX682Pu7ZYNsdUHyUKSoRwdnOsMf6FDekwoAFKej14WAkOef3zAORJgAtXnlQ=="],
"tsx/esbuild/@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.27.0", "", { "os": "linux", "cpu": "ia32" }, "sha512-Mz1jxqm/kfgKkc/KLHC5qIujMvnnarD9ra1cEcrs7qshTUSksPihGrWHVG5+osAIQ68577Zpww7SGapmzSt4Nw=="],
"tsx/esbuild/@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.27.0", "", { "os": "linux", "cpu": "none" }, "sha512-QbEREjdJeIreIAbdG2hLU1yXm1uu+LTdzoq1KCo4G4pFOLlvIspBm36QrQOar9LFduavoWX2msNFAAAY9j4BDg=="],
"tsx/esbuild/@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.27.0", "", { "os": "linux", "cpu": "none" }, "sha512-sJz3zRNe4tO2wxvDpH/HYJilb6+2YJxo/ZNbVdtFiKDufzWq4JmKAiHy9iGoLjAV7r/W32VgaHGkk35cUXlNOg=="],
"tsx/esbuild/@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.27.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-z9N10FBD0DCS2dmSABDBb5TLAyF1/ydVb+N4pi88T45efQ/w4ohr/F/QYCkxDPnkhkp6AIpIcQKQ8F0ANoA2JA=="],
"tsx/esbuild/@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.27.0", "", { "os": "linux", "cpu": "none" }, "sha512-pQdyAIZ0BWIC5GyvVFn5awDiO14TkT/19FTmFcPdDec94KJ1uZcmFs21Fo8auMXzD4Tt+diXu1LW1gHus9fhFQ=="],
"tsx/esbuild/@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.27.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-hPlRWR4eIDDEci953RI1BLZitgi5uqcsjKMxwYfmi4LcwyWo2IcRP+lThVnKjNtk90pLS8nKdroXYOqW+QQH+w=="],
"tsx/esbuild/@esbuild/linux-x64": ["@esbuild/linux-x64@0.27.0", "", { "os": "linux", "cpu": "x64" }, "sha512-1hBWx4OUJE2cab++aVZ7pObD6s+DK4mPGpemtnAORBvb5l/g5xFGk0vc0PjSkrDs0XaXj9yyob3d14XqvnQ4gw=="],
"tsx/esbuild/@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.27.0", "", { "os": "none", "cpu": "arm64" }, "sha512-6m0sfQfxfQfy1qRuecMkJlf1cIzTOgyaeXaiVaaki8/v+WB+U4hc6ik15ZW6TAllRlg/WuQXxWj1jx6C+dfy3w=="],
"tsx/esbuild/@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.27.0", "", { "os": "none", "cpu": "x64" }, "sha512-xbbOdfn06FtcJ9d0ShxxvSn2iUsGd/lgPIO2V3VZIPDbEaIj1/3nBBe1AwuEZKXVXkMmpr6LUAgMkLD/4D2PPA=="],
"tsx/esbuild/@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.27.0", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-fWgqR8uNbCQ/GGv0yhzttj6sU/9Z5/Sv/VGU3F5OuXK6J6SlriONKrQ7tNlwBrJZXRYk5jUhuWvF7GYzGguBZQ=="],
"tsx/esbuild/@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.27.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-aCwlRdSNMNxkGGqQajMUza6uXzR/U0dIl1QmLjPtRbLOx3Gy3otfFu/VjATy4yQzo9yFDGTxYDo1FfAD9oRD2A=="],
"tsx/esbuild/@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.27.0", "", { "os": "none", "cpu": "arm64" }, "sha512-nyvsBccxNAsNYz2jVFYwEGuRRomqZ149A39SHWk4hV0jWxKM0hjBPm3AmdxcbHiFLbBSwG6SbpIcUbXjgyECfA=="],
"tsx/esbuild/@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.27.0", "", { "os": "sunos", "cpu": "x64" }, "sha512-Q1KY1iJafM+UX6CFEL+F4HRTgygmEW568YMqDA5UV97AuZSm21b7SXIrRJDwXWPzr8MGr75fUZPV67FdtMHlHA=="],
"tsx/esbuild/@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.27.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-W1eyGNi6d+8kOmZIwi/EDjrL9nxQIQ0MiGqe/AWc6+IaHloxHSGoeRgDRKHFISThLmsewZ5nHFvGFWdBYlgKPg=="],
"tsx/esbuild/@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.27.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-30z1aKL9h22kQhilnYkORFYt+3wp7yZsHWus+wSKAJR8JtdfI76LJ4SBdMsCopTR3z/ORqVu5L1vtnHZWVj4cQ=="],
"tsx/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.0", "", { "os": "win32", "cpu": "x64" }, "sha512-aIitBcjQeyOhMTImhLZmtxfdOcuNRpwlPNmlFKPcHQYPhEssw75Cl1TSXJXpMkzaua9FUetx/4OQKq7eJul5Cg=="],
"unplugin-vue-components/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"unplugin-vue-components/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
"unplugin-vue-components/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"vite-plugin-html/@rollup/pluginutils/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"vite/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.21.5", "", { "os": "aix", "cpu": "ppc64" }, "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ=="],
@ -4525,27 +4629,33 @@
"@aws-crypto/util/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="],
"@eslint/eslintrc/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"@humanwhocodes/config-array/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"@intlify/vue-i18n-extensions/vue-i18n/@intlify/core-base/@intlify/message-compiler": ["@intlify/message-compiler@10.0.8", "", { "dependencies": { "@intlify/shared": "10.0.8", "source-map-js": "^1.0.2" } }, "sha512-DV+sYXIkHVd5yVb2mL7br/NEUwzUoLBsMkV3H0InefWgmYa34NLZUvMCGi5oWX+Hqr2Y2qUxnVrnOWF4aBlgWg=="],
"@istanbuljs/load-nyc-config/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="],
"@swc/cli/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"@vue/server-renderer/@vue/compiler-ssr/@vue/compiler-dom/@vue/compiler-core": ["@vue/compiler-core@3.5.13", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.13", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q=="],
"apollo-cache-inmemory/optimism/@wry/context/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
"babel-plugin-istanbul/test-exclude/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"cheerio-select/domutils/dom-serializer/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="],
"css-select/domutils/dom-serializer/entities": ["entities@2.2.0", "", {}, "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A=="],
"editorconfig/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"eslint-plugin-import/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"filelist/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"eslint-plugin-n/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"eslint-plugin-node/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"eslint/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"html-to-text/htmlparser2/domutils/dom-serializer": ["dom-serializer@1.4.1", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" } }, "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag=="],
@ -4565,12 +4675,14 @@
"jest-worker/jest-util/@jest/types/@types/yargs": ["@types/yargs@17.0.35", "", { "dependencies": { "@types/yargs-parser": "*" } }, "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg=="],
"js-beautify/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"mailparser/html-to-text/selderee/parseley": ["parseley@0.12.1", "", { "dependencies": { "leac": "^0.6.0", "peberminta": "^0.9.0" } }, "sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw=="],
"multimatch/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"nodemon/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"nodemon/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"pkg-dir/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="],
"run-applescript/execa/cross-spawn/path-key": ["path-key@2.0.1", "", {}, "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw=="],
@ -4583,14 +4695,10 @@
"run-applescript/execa/npm-run-path/path-key": ["path-key@2.0.1", "", {}, "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw=="],
"test-exclude/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"typeorm/glob/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
"serve-static/send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
"unplugin-vue-components/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"unplugin-vue-components/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"vue-apollo/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="],
"web-resource-inliner/htmlparser2/domutils/dom-serializer": ["dom-serializer@1.4.1", "", { "dependencies": { "domelementtype": "^2.0.1", "domhandler": "^4.2.0", "entities": "^2.0.0" } }, "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag=="],
@ -4599,18 +4707,14 @@
"@istanbuljs/load-nyc-config/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="],
"@typescript-eslint/utils/@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"babel-plugin-istanbul/test-exclude/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"jest-worker/jest-util/@jest/types/@jest/schemas/@sinclair/typebox": ["@sinclair/typebox@0.27.8", "", {}, "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA=="],
"js-beautify/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"pkg-dir/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="],
"run-applescript/execa/cross-spawn/shebang-command/shebang-regex": ["shebang-regex@1.0.0", "", {}, "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ=="],
"typeorm/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"vue-apollo/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
}
}

View File

@ -1,13 +1,6 @@
import { registerEnumType } from 'type-graphql'
export enum TransactionTypeId {
CREATION = 1,
SEND = 2,
RECEIVE = 3,
// This is a virtual property, never occurring on the database
DECAY = 4,
LINK_SUMMARY = 5,
}
import { TransactionTypeId } from 'database'
export { TransactionTypeId }
registerEnumType(TransactionTypeId, {
name: 'TransactionTypeId', // this one is mandatory

View File

@ -2,6 +2,7 @@ import { promisify } from 'util'
import { Decimal } from 'decimal.js-light'
import { i18n } from '../locales/localization'
export { fullName } from 'shared'
export const objectValuesToArray = (obj: Record<string, string>): string[] =>
Object.keys(obj).map((key) => obj[key])
@ -14,11 +15,7 @@ export const decimalSeparatorByLanguage = (a: Decimal, language: string): string
return result
}
export const fullName = (firstName: string, lastName: string): string =>
[firstName, lastName].filter(Boolean).join(' ')
// Function to reset an interface by chatGPT
export function resetInterface<T extends Record<string, any>>(obj: T): T {
// Iterate over all properties of the object
for (const key in obj) {

View File

@ -49,8 +49,12 @@
// "paths": { }, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [".", "../database"], /* List of root folders whose combined content represents the structure of the project at runtime. */
/* List of folders to include type definitions from. */
"typeRoots": ["./node_modules/@types", "../node_modules/@types"],
// "types": ["bun-types"], /* Type declaration files to be included in compilation. */
"typeRoots": [
"./node_modules/@types",
"../node_modules/@types",
"../@types"
],
// "types": ["bun-types", "../@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. */

View File

@ -38,7 +38,7 @@
"@types/mysql": "^2.15.27",
"@types/node": "^18.7.14",
"await-semaphore": "^0.1.3",
"crypto-random-bigint": "^2.1.1",
"random-bigint": "^0.0.1",
"ts-node": "^10.9.2",
"typescript": "^4.9.5"
},

View File

@ -0,0 +1,22 @@
// lowercase values are not implemented yet
export enum ContributionCycleType {
ONCE = 'ONCE',
HOUR = 'hour',
TWO_HOURS = 'two_hours',
FOUR_HOURS = 'four_hours',
EIGHT_HOURS = 'eight_hours',
HALF_DAY = 'half_day',
DAILY = 'DAILY',
TWO_DAYS = 'two_days',
THREE_DAYS = 'three_days',
FOUR_DAYS = 'four_days',
FIVE_DAYS = 'five_days',
SIX_DAYS = 'six_days',
WEEK = 'week',
TWO_WEEKS = 'two_weeks',
MONTH = 'month',
TWO_MONTH = 'two_month',
QUARTER = 'quarter',
HALF_YEAR = 'half_year',
YEAR = 'year',
}

View File

@ -0,0 +1,7 @@
export enum ContributionStatus {
PENDING = 'PENDING',
DELETED = 'DELETED',
IN_PROGRESS = 'IN_PROGRESS',
DENIED = 'DENIED',
CONFIRMED = 'CONFIRMED',
}

View File

@ -0,0 +1,5 @@
export enum ContributionType {
ADMIN = 'ADMIN',
USER = 'USER',
LINK = 'LINK',
}

View File

@ -0,0 +1,8 @@
export enum RoleNames {
UNAUTHORIZED = 'UNAUTHORIZED',
USER = 'USER',
MODERATOR = 'MODERATOR',
MODERATOR_AI = 'MODERATOR_AI',
ADMIN = 'ADMIN',
DLT_CONNECTOR = 'DLT_CONNECTOR_ROLE',
}

View File

@ -0,0 +1,8 @@
export enum TransactionTypeId {
CREATION = 1,
SEND = 2,
RECEIVE = 3,
// This is a virtual property, never occurring on the database
DECAY = 4,
LINK_SUMMARY = 5,
}

View File

@ -1 +1,6 @@
export * from './CommunityHandshakeStateType'
export * from './CommunityHandshakeStateType'
export * from './ContributionType'
export * from './ContributionStatus'
export * from './TransactionTypeId'
export * from './ContributionCycleType'
export * from './RoleNames'

View File

@ -4,6 +4,7 @@ export { latestDbVersion }
export * from './entity'
export * from './logging'
export * from './queries'
export * from './seeds'
export * from './util'
export * from './enum'
export { AppDatabase } from './AppDatabase'

View File

@ -0,0 +1,7 @@
export interface ContributionLinkInterface {
amount: number
name: string
memo: string
validFrom?: Date
validTo?: Date
}

View File

@ -0,0 +1,19 @@
import { ContributionLinkInterface } from './ContributionLinkInterface'
export type { ContributionLinkInterface }
export const contributionLinks: ContributionLinkInterface[] = [
{
name: 'Dokumenta 2017',
memo: 'Vielen Dank für deinen Besuch bei der Dokumenta 2017',
amount: 200,
validFrom: new Date(2017, 3, 8),
validTo: new Date(2017, 6, 16),
},
{
name: 'Dokumenta 2022',
memo: 'Vielen Dank für deinen Besuch bei der Dokumenta 2022',
amount: 200,
validFrom: new Date(2022, 5, 18),
validTo: new Date(2022, 8, 25),
},
]

View File

@ -0,0 +1,9 @@
export interface CreationInterface {
email: string
amount: number
memo: string
contributionDate: string
confirmed?: boolean
// number of months to move the confirmed creation to the past
moveCreationDate?: number
}

View File

@ -0,0 +1,156 @@
import { nMonthsBefore } from '../factory/creation'
import { CreationInterface } from './CreationInterface'
export type { CreationInterface }
const bobsSendings = [
{
amount: 10,
memo: 'Herzlich Willkommen bei Gradido!',
},
{
amount: 10,
memo: 'für deine Hilfe, Betty',
},
{
amount: 23.37,
memo: 'für deine Hilfe, David',
},
{
amount: 47,
memo: 'für deine Hilfe, Frau Holle',
},
{
amount: 1.02,
memo: 'für deine Hilfe, Herr Müller',
},
{
amount: 5.67,
memo: 'für deine Hilfe, Maier',
},
{
amount: 72.93,
memo: 'für deine Hilfe, Elsbeth',
},
{
amount: 5.6,
memo: 'für deine Hilfe, Daniel',
},
{
amount: 8.87,
memo: 'für deine Hilfe, Yoda',
},
{
amount: 7.56,
memo: 'für deine Hilfe, Sabine',
},
{
amount: 7.89,
memo: 'für deine Hilfe, Karl',
},
{
amount: 8.9,
memo: 'für deine Hilfe, Darth Vader',
},
{
amount: 56.79,
memo: 'für deine Hilfe, Luci',
},
{
amount: 3.45,
memo: 'für deine Hilfe, Hanne',
},
{
amount: 8.74,
memo: 'für deine Hilfe, Luise',
},
{
amount: 7.85,
memo: 'für deine Hilfe, Annegred',
},
{
amount: 32.7,
memo: 'für deine Hilfe, Prinz von Zamunda',
},
{
amount: 44.2,
memo: 'für deine Hilfe, Charly Brown',
},
{
amount: 38.17,
memo: 'für deine Hilfe, Michael',
},
{
amount: 5.72,
memo: 'für deine Hilfe, Kaja',
},
{
amount: 3.99,
memo: 'für deine Hilfe, Maja',
},
{
amount: 4.5,
memo: 'für deine Hilfe, Martha',
},
{
amount: 8.3,
memo: 'für deine Hilfe, Ursula',
},
{
amount: 2.9,
memo: 'für deine Hilfe, Urs',
},
{
amount: 4.6,
memo: 'für deine Hilfe, Mecedes',
},
{
amount: 74.1,
memo: 'für deine Hilfe, Heidi',
},
{
amount: 4.5,
memo: 'für deine Hilfe, Peter',
},
{
amount: 5.8,
memo: 'für deine Hilfe, Fräulein Rottenmeier',
},
]
const bobsTransactions: CreationInterface[] = []
bobsSendings.forEach((sending) => {
bobsTransactions.push({
email: 'bob@baumeister.de',
amount: sending.amount,
memo: sending.memo,
contributionDate: nMonthsBefore(new Date()),
confirmed: true,
})
})
export const creations: CreationInterface[] = [
{
email: 'bibi@bloxberg.de',
amount: 1000,
memo: 'Herzlich Willkommen bei Gradido!',
contributionDate: nMonthsBefore(new Date()),
confirmed: true,
moveCreationDate: 12,
},
{
email: 'bibi@bloxberg.de',
amount: 1000,
memo: '#Hexen',
contributionDate: nMonthsBefore(new Date()),
confirmed: true,
},
...bobsTransactions,
{
email: 'raeuber@hotzenplotz.de',
amount: 1000,
memo: 'Herzlich Willkommen bei Gradido!',
contributionDate: nMonthsBefore(new Date()),
confirmed: true,
},
]

View File

@ -0,0 +1,31 @@
import Decimal from 'decimal.js-light'
import { ContributionLink } from '../../entity'
import { ContributionLinkInterface } from '../contributionLink/ContributionLinkInterface'
import { transactionLinkCode } from './transactionLink'
import { ContributionCycleType } from '../../enum'
export function contributionLinkFactory(contributionLink: ContributionLinkInterface): Promise<ContributionLink> {
return createContributionLink(contributionLink)
}
export function createContributionLink(contributionLinkData: ContributionLinkInterface): Promise<ContributionLink> {
const contributionLink = new ContributionLink()
contributionLink.amount = new Decimal(contributionLinkData.amount)
contributionLink.name = contributionLinkData.name
contributionLink.memo = contributionLinkData.memo
contributionLink.createdAt = new Date()
contributionLink.code = transactionLinkCode(new Date())
contributionLink.cycle = ContributionCycleType.ONCE
if (contributionLinkData.validFrom) {
contributionLink.validFrom = contributionLinkData.validFrom
}
if (contributionLinkData.validTo) {
contributionLink.validTo = contributionLinkData.validTo
}
contributionLink.maxAmountPerMonth = new Decimal(200)
contributionLink.maxPerCycle = 1
return contributionLink.save()
}

View File

@ -0,0 +1,134 @@
import { Contribution, Transaction, User } from '../../entity'
import { Decimal } from 'decimal.js-light'
import { CreationInterface } from '../creation/CreationInterface'
import { ContributionType, ContributionStatus, TransactionTypeId } from '../../enum'
import { findUserByIdentifier } from '../../queries'
import { createTransaction } from './transaction'
import { AppDatabase } from '../../AppDatabase'
export function nMonthsBefore(date: Date, months = 1): string {
return new Date(date.getFullYear(), date.getMonth() - months, 1).toISOString()
}
export async function creationFactory(
creation: CreationInterface,
user?: User | null,
moderatorUser?: User | null,
): Promise<Contribution> {
if (!user) {
user = await findUserByIdentifier(creation.email)
}
if (!user) {
throw new Error(`User ${creation.email} not found`)
}
let contribution = await createContribution(creation, user)
if (creation.confirmed) {
if (!moderatorUser) {
moderatorUser = await findUserByIdentifier('peter@lustig.de')
}
if (!moderatorUser) {
throw new Error('Moderator user not found')
}
await confirmTransaction(creation, contribution, moderatorUser)
}
return contribution
}
export async function creationFactoryBulk(
creations: CreationInterface[],
userCreationIndexedByEmail: Map<string, User>,
moderatorUser: User,
): Promise<Contribution[]> {
const lastTransaction = await Transaction.findOne({ order: { id: 'DESC' }, select: ['id'], where: {} })
let transactionId = lastTransaction ? lastTransaction.id + 1 : 1
const dbContributions: Contribution[] = []
const dbTransactions: Transaction[] = []
for (const creation of creations) {
const user = userCreationIndexedByEmail.get(creation.email)
if (!user) {
throw new Error(`User ${creation.email} not found`)
}
let contribution = await createContribution(creation, user, false)
if (creation.confirmed) {
const { contribution: _, transaction } = await confirmTransaction(
creation,
contribution,
moderatorUser,
transactionId,
false
)
dbTransactions.push(transaction)
transactionId++
}
dbContributions.push(contribution)
}
const dataSource = AppDatabase.getInstance().getDataSource()
await dataSource.transaction(async (transaction) => {
await dataSource.getRepository(Contribution).insert(dbContributions)
await dataSource.getRepository(Transaction).insert(dbTransactions)
})
return dbContributions
}
export async function createContribution(creation: CreationInterface, user: User, store: boolean = true): Promise<Contribution> {
const contribution = new Contribution()
contribution.user = user
contribution.userId = user.id
contribution.amount = new Decimal(creation.amount)
contribution.createdAt = new Date()
contribution.contributionDate = getContributionDate(creation)
contribution.memo = creation.memo
contribution.contributionType = ContributionType.USER
contribution.contributionStatus = ContributionStatus.PENDING
return store ? contribution.save() : contribution
}
export async function confirmTransaction(
creation: CreationInterface,
contribution: Contribution,
moderatorUser: User,
transactionId?: number,
store: boolean = true
): Promise<{ contribution: Contribution, transaction: Transaction }> {
const balanceDate = getBalanceDate(creation)
const transaction = await createTransaction(
contribution.amount,
contribution.memo,
contribution.user,
moderatorUser,
TransactionTypeId.CREATION,
balanceDate,
contribution.contributionDate,
transactionId,
store,
)
contribution.confirmedAt = balanceDate
contribution.confirmedBy = moderatorUser.id
contribution.transactionId = transaction.id
contribution.transaction = transaction
contribution.contributionStatus = ContributionStatus.CONFIRMED
if (store) {
await contribution.save()
await transaction.save()
}
return { contribution, transaction }
}
function getContributionDate(creation: CreationInterface): Date {
if (creation.moveCreationDate) {
return new Date(nMonthsBefore(new Date(creation.contributionDate), creation.moveCreationDate))
}
return new Date(creation.contributionDate)
}
function getBalanceDate(creation: CreationInterface): Date {
const now = new Date()
if (creation.moveCreationDate) {
return new Date(nMonthsBefore(now, creation.moveCreationDate))
}
return now
}

View File

@ -0,0 +1,6 @@
export * from './contributionLink'
export * from './creation'
export * from './pendingTransaction'
export * from './transaction'
export * from './transactionLink'
export * from './user'

View File

@ -0,0 +1,59 @@
import Decimal from 'decimal.js-light'
import { User, Transaction } from '../../entity'
import { TransactionTypeId } from '../../enum'
import { fullName } from 'shared'
import { getLastTransaction } from '../../queries'
import { calculateDecay, Decay } from 'shared'
export async function createTransaction(
amount: Decimal,
memo: string,
user: User,
linkedUser: User,
type: TransactionTypeId,
balanceDate: Date,
creationDate?: Date,
id?: number,
store: boolean = true,
): Promise<Transaction> {
const lastTransaction = await getLastTransaction(user.id)
// balance and decay calculation
let newBalance = new Decimal(0)
let decay: Decay | null = null
if (lastTransaction) {
decay = calculateDecay(
lastTransaction.balance,
lastTransaction.balanceDate,
balanceDate,
)
newBalance = decay.balance
}
newBalance = newBalance.add(amount.toString())
const transaction = new Transaction()
if (id) {
transaction.id = id
}
transaction.typeId = type
transaction.memo = memo
transaction.userId = user.id
transaction.userGradidoID = user.gradidoID
transaction.userName = fullName(user.firstName, user.lastName)
transaction.userCommunityUuid = user.communityUuid
transaction.linkedUserId = linkedUser.id
transaction.linkedUserGradidoID = linkedUser.gradidoID
transaction.linkedUserName = fullName(linkedUser.firstName, linkedUser.lastName)
transaction.linkedUserCommunityUuid = linkedUser.communityUuid
transaction.previous = lastTransaction ? lastTransaction.id : null
transaction.amount = amount
if (creationDate) {
transaction.creationDate = creationDate
}
transaction.balance = newBalance
transaction.balanceDate = balanceDate
transaction.decay = decay ? decay.decay : new Decimal(0)
transaction.decayStart = decay ? decay.start : null
return store ? transaction.save() : transaction
}

View File

@ -0,0 +1,77 @@
import { TransactionLinkInterface } from '../transactionLink/TransactionLinkInterface'
import { TransactionLink, User } from '../../entity'
import { Decimal } from 'decimal.js-light'
import { findUserByIdentifier } from '../../queries'
import { compoundInterest } from 'shared'
import { randomBytes } from 'node:crypto'
import { AppDatabase } from '../../AppDatabase'
export async function transactionLinkFactory(
transactionLinkData: TransactionLinkInterface,
userId?: number,
): Promise<TransactionLink> {
if (!userId) {
const user = await findUserByIdentifier(transactionLinkData.email)
if (!user) {
throw new Error(`User ${transactionLinkData.email} not found`)
}
userId = user.id
}
return createTransactionLink(transactionLinkData, userId)
}
export async function transactionLinkFactoryBulk(
transactionLinks: TransactionLinkInterface[],
userCreationIndexedByEmail: Map<string, User>
): Promise<TransactionLink[]> {
const dbTransactionLinks: TransactionLink[] = []
for (const transactionLink of transactionLinks) {
const user = userCreationIndexedByEmail.get(transactionLink.email)
if (!user) {
throw new Error(`User ${transactionLink.email} not found`)
}
dbTransactionLinks.push(await createTransactionLink(transactionLink, user.id, false))
}
const dataSource = AppDatabase.getInstance().getDataSource()
await dataSource.getRepository(TransactionLink).insert(dbTransactionLinks)
return dbTransactionLinks
}
export async function createTransactionLink(transactionLinkData: TransactionLinkInterface, userId: number, store: boolean = true): Promise<TransactionLink> {
const holdAvailableAmount = compoundInterest(new Decimal(transactionLinkData.amount.toString()), CODE_VALID_DAYS_DURATION * 24 * 60 * 60)
let createdAt = transactionLinkData.createdAt || new Date()
const validUntil = transactionLinkExpireDate(createdAt)
const transactionLink = new TransactionLink()
transactionLink.userId = userId
transactionLink.amount = new Decimal(transactionLinkData.amount)
transactionLink.memo = transactionLinkData.memo
transactionLink.holdAvailableAmount = holdAvailableAmount
transactionLink.code = transactionLinkCode(createdAt)
transactionLink.createdAt = createdAt
transactionLink.validUntil = validUntil
if (transactionLinkData.deletedAt) {
transactionLink.deletedAt = new Date(createdAt.getTime() + 1000)
}
return store ? transactionLink.save() : transactionLink
}
////// Transaction Link BUSINESS LOGIC //////
// TODO: move business logic to shared
export const CODE_VALID_DAYS_DURATION = 14
export const transactionLinkExpireDate = (date: Date): Date => {
const validUntil = new Date(date)
return new Date(validUntil.setDate(date.getDate() + CODE_VALID_DAYS_DURATION))
}
export const transactionLinkCode = (date: Date): string => {
const time = date.getTime().toString(16)
return (
randomBytes(12)
.toString('hex')
.substring(0, 24 - time.length) + time
)
}

View File

@ -1,16 +1,77 @@
import { UserInterface } from '../users/UserInterface'
import { User, UserContact } from '../../entity'
import { User, UserContact, UserRole } from '../../entity'
import { v4 } from 'uuid'
import { UserContactType, OptInType, PasswordEncryptionType } from 'shared'
import { getHomeCommunity } from '../../queries/communities'
import random from 'crypto-random-bigint'
import random from 'random-bigint'
import { Community } from '../../entity'
import { AppDatabase } from '../..'
import { RoleNames } from '../../enum/RoleNames'
export const userFactory = async (user: UserInterface): Promise<User> => {
let dbUserContact = new UserContact()
export async function userFactory(user: UserInterface, homeCommunity?: Community | null): Promise<User> {
// TODO: improve with cascade
let dbUser = await createUser(user, homeCommunity)
let dbUserContact = await createUserContact(user, dbUser.id)
dbUser.emailId = dbUserContact.id
dbUser.emailContact = dbUserContact
dbUser = await dbUser.save()
dbUserContact.email = user.email ?? ''
dbUserContact.type = UserContactType.USER_CONTACT_EMAIL
const userRole = user.role as RoleNames
if (userRole && (userRole === RoleNames.ADMIN || userRole === RoleNames.MODERATOR)) {
dbUser.userRoles = [await createUserRole(dbUser.id, userRole)]
}
return dbUser
}
// only use in non-parallel environment (seeding for example)
export async function userFactoryBulk(users: UserInterface[], homeCommunity?: Community | null): Promise<User[]> {
const dbUsers: User[] = []
const dbUserContacts: UserContact[] = []
const dbUserRoles: UserRole[] = []
const lastUser = await User.findOne({ order: { id: 'DESC' }, select: ['id'], where: {} })
const lastUserContact = await UserContact.findOne({ order: { id: 'DESC' }, select: ['id'], where: {} })
let userId = lastUser ? lastUser.id + 1 : 1
let emailId = lastUserContact ? lastUserContact.id + 1 : 1
// console.log(`start with userId: ${userId} and emailId: ${emailId}`)
for(const user of users) {
const dbUser = await createUser(user, homeCommunity, false)
dbUser.id = userId
dbUser.emailId = emailId
const dbUserContact = await createUserContact(user, userId, false)
dbUserContact.id = emailId
dbUserContact.userId = userId
dbUser.emailContact = dbUserContact
dbUsers.push(dbUser)
dbUserContacts.push(dbUserContact)
const userRole = user.role as RoleNames
if (userRole && (userRole === RoleNames.ADMIN || userRole === RoleNames.MODERATOR)) {
dbUserRoles.push(await createUserRole(dbUser.id, userRole, false))
}
userId++
emailId++
}
const dataSource = AppDatabase.getInstance().getDataSource()
await dataSource.transaction(async transaction => {
// typeorm change my data what I don't want
// because of manuel id assignment
const dbUsersCopy = dbUsers.map(user => ({ ...user }))
const dbUserContactsCopy = dbUserContacts.map(userContact => ({ ...userContact }))
const dbUserRolesCopy = dbUserRoles.map(userRole => ({ ...userRole }))
await Promise.all([
transaction.getRepository(User).insert(dbUsersCopy),
transaction.getRepository(UserContact).insert(dbUserContactsCopy),
transaction.getRepository(UserRole).insert(dbUserRolesCopy)
])
})
return dbUsers
}
export async function createUser(user: UserInterface, homeCommunity?: Community | null, store: boolean = true): Promise<User> {
let dbUser = new User()
dbUser.firstName = user.firstName ?? ''
dbUser.lastName = user.lastName ?? ''
@ -21,25 +82,50 @@ export const userFactory = async (user: UserInterface): Promise<User> => {
dbUser.createdAt = user.createdAt ?? new Date()
dbUser.deletedAt = user.deletedAt ?? null
dbUser.publisherId = user.publisherId ?? 0
dbUser.humhubAllowed = true
dbUser.gradidoID = v4()
if (user.emailChecked) {
dbUserContact.emailVerificationCode = random(64).toString()
dbUserContact.emailOptInTypeId = OptInType.EMAIL_OPT_IN_REGISTER
dbUserContact.emailChecked = true
dbUser.password = random(64)
// dbUser.password =
dbUser.passwordEncryptionType = PasswordEncryptionType.GRADIDO_ID
}
const homeCommunity = await getHomeCommunity()
if (!homeCommunity) {
homeCommunity = await getHomeCommunity()
}
if (homeCommunity) {
dbUser.community = homeCommunity
dbUser.communityUuid = homeCommunity.communityUuid!
}
// TODO: improve with cascade
dbUser = await dbUser.save()
dbUserContact.userId = dbUser.id
dbUserContact = await dbUserContact.save()
dbUser.emailId = dbUserContact.id
dbUser.emailContact = dbUserContact
return dbUser.save()
return store ? dbUser.save() : dbUser
}
export async function createUserContact(user: UserInterface, userId?: number, store: boolean = true): Promise<UserContact> {
let dbUserContact = new UserContact()
dbUserContact.email = user.email ?? ''
dbUserContact.type = UserContactType.USER_CONTACT_EMAIL
if (user.createdAt) {
dbUserContact.createdAt = user.createdAt
dbUserContact.updatedAt = user.createdAt
}
if (user.emailChecked) {
dbUserContact.emailVerificationCode = random(64).toString()
dbUserContact.emailOptInTypeId = OptInType.EMAIL_OPT_IN_REGISTER
dbUserContact.emailChecked = true
}
if (userId) {
dbUserContact.userId = userId
}
return store ? dbUserContact.save() : dbUserContact
}
export async function createUserRole(userId: number, role: RoleNames, store: boolean = true): Promise<UserRole> {
let dbUserRole = new UserRole()
dbUserRole.userId = userId
dbUserRole.role = role
return store ? dbUserRole.save() : dbUserRole
}

View File

@ -0,0 +1,5 @@
export * from './contributionLink'
export * from './creation'
export * from './factory'
export * from './transactionLink'
export * from './users'

View File

@ -0,0 +1,10 @@
export interface TransactionLinkInterface {
email: string
amount: number
memo: string
createdAt?: Date
// TODO: for testing
// redeemedAt?: Date
// redeemedBy?: number
deletedAt?: boolean
}

View File

@ -0,0 +1,56 @@
import { TransactionLinkInterface } from './TransactionLinkInterface'
export type { TransactionLinkInterface }
export const transactionLinks: TransactionLinkInterface[] = [
{
email: 'bibi@bloxberg.de',
amount: 19.99,
memo: 'Leider wollte niemand meine Gradidos haben :(',
},
{
email: 'bibi@bloxberg.de',
amount: 19.99,
memo: `Kein Trick, keine Zauberrei,
bei Gradidio sei dabei!`,
},
{
email: 'bibi@bloxberg.de',
amount: 19.99,
memo: `Kein Trick, keine Zauberrei,
bei Gradidio sei dabei!`,
},
{
email: 'bibi@bloxberg.de',
amount: 19.99,
memo: `Kein Trick, keine Zauberrei,
bei Gradidio sei dabei!`,
},
{
email: 'bibi@bloxberg.de',
amount: 19.99,
memo: `Kein Trick, keine Zauberrei,
bei Gradidio sei dabei!`,
// TODO: for testing
// memo: `Yeah, eingelöst!`,
// redeemedAt: new Date(2022, 2, 2),
// redeemedBy: not null,
},
{
email: 'bibi@bloxberg.de',
amount: 19.99,
memo: `Kein Trick, keine Zauberrei,
bei Gradidio sei dabei!`,
},
{
email: 'bibi@bloxberg.de',
amount: 19.99,
memo: `Kein Trick, keine Zauberrei,
bei Gradidio sei dabei!`,
},
{
email: 'bibi@bloxberg.de',
amount: 19.99,
memo: 'Da habe ich mich wohl etwas übernommen.',
deletedAt: true,
},
]

View File

@ -9,4 +9,6 @@ export const bibiBloxberg: UserInterface = {
emailChecked: true,
language: 'de',
publisherId: 1234,
// move user createdAt before transaction link
createdAt: new Date(2021, 9, 17),
}

View File

@ -4,8 +4,19 @@ import { garrickOllivander } from './garrick-ollivander'
import { peterLustig } from './peter-lustig'
import { raeuberHotzenplotz } from './raeuber-hotzenplotz'
import { stephenHawking } from './stephen-hawking'
import { UserInterface } from './UserInterface'
export const users = [
export {
type UserInterface,
bibiBloxberg,
bobBaumeister,
garrickOllivander,
peterLustig,
raeuberHotzenplotz,
stephenHawking
}
export const users: UserInterface[] = [
peterLustig,
bibiBloxberg,
bobBaumeister,

View File

@ -1,4 +1,5 @@
import { UserInterface } from './UserInterface'
import { RoleNames } from '../../enum'
export const peterLustig: UserInterface = {
email: 'peter@lustig.de',
@ -7,5 +8,6 @@ export const peterLustig: UserInterface = {
// description: 'Latzhose und Nickelbrille',
createdAt: new Date('2020-11-25T10:48:43'),
emailChecked: true,
language: 'de'
language: 'de',
role: RoleNames.ADMIN,
}

View File

@ -50,7 +50,11 @@
//"@/*": ["src/*"], /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
//},
// "rootDirs": [".", "../database"], /* List of root folders whose combined content represents the structure of the project at runtime. */
"typeRoots": ["node_modules/@types"], /* List of folders to include type definitions from. */
"typeRoots": [
"./node_modules/@types",
"../node_modules/@types",
"../@types"
],
// "types": ["node"], /* 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'. */

View File

@ -52,9 +52,9 @@
},
// "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. */
"src/dht_node/@types",
"node_modules/@types",
"../node_modules/@types"
"../node_modules/@types",
"../@types"
],
// "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'. */

View File

@ -64,6 +64,7 @@
"typeRoots": [ /* List of folders to include type definitions from. */
"node_modules/@types",
"../node_modules/@types",
"../@types"
],
// "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. */

View File

@ -1,15 +1,28 @@
<template>
<transition name="fade-out" @after-leave="resetForm">
<div>
<div v-if="showForm">
<contribution-form
v-if="maxForMonths"
:model-value="form"
:max-gdd-last-month="parseFloat(maxForMonths.openCreations[1].amount)"
:max-gdd-this-month="parseFloat(maxForMonths.openCreations[2].amount)"
:max-gdd-last-month="maxGddLastMonth"
:max-gdd-this-month="maxGddThisMonth"
:success-message="$t('contribution.submitted')"
@upsert-contribution="handleCreateContribution"
/>
</div>
</transition>
<div v-else>
<open-creations-amount
:minimal-date="minimalDate"
:max-gdd-last-month="maxGddLastMonth"
:max-gdd-this-month="maxGddThisMonth"
/>
<div class="mb-3"></div>
<success-message
:message="$t('contribution.submitted')"
@on-back="showForm = true"
></success-message>
</div>
</div>
</template>
<script setup>
@ -18,11 +31,12 @@ import { GDD_PER_HOUR } from '@/constants'
import { useQuery, useMutation } from '@vue/apollo-composable'
import { openCreationsAmounts, createContribution } from '@/graphql/contributions.graphql'
import { useAppToast } from '@/composables/useToast'
import { useI18n } from 'vue-i18n'
import { ref } from 'vue'
import { computed, ref } from 'vue'
import SuccessMessage from '@/components/SuccessMessage.vue'
import OpenCreationsAmount from '@/components/Contributions/OpenCreationsAmount.vue'
import { useMinimalContributionDate } from '@/composables/useMinimalContributionDate'
const { toastError, toastSuccess } = useAppToast()
const { t } = useI18n()
const { toastError } = useAppToast()
const { result: maxForMonths, refetch } = useQuery(
openCreationsAmounts,
@ -34,6 +48,10 @@ const { mutate: createContributionMutation } = useMutation(createContribution)
const form = ref(emptyForm())
const showForm = ref(true)
const maxGddLastMonth = computed(() => parseFloat(maxForMonths.value?.openCreations[1].amount))
const maxGddThisMonth = computed(() => parseFloat(maxForMonths.value?.openCreations[2].amount))
const minimalDate = computed(() => useMinimalContributionDate(new Date()))
function emptyForm() {
return {
contributionDate: undefined,
@ -45,18 +63,14 @@ function emptyForm() {
async function handleCreateContribution(contribution) {
try {
form.value = emptyForm()
await createContributionMutation({ ...contribution })
toastSuccess(t('contribution.submitted'))
await refetch()
showForm.value = false
} catch (err) {
toastError(err.message)
}
}
function resetForm() {
refetch()
showForm.value = true
}
</script>
<style scoped>
.fade-out-enter-active,

View File

@ -95,6 +95,7 @@ import LabeledInput from '@/components/Inputs/LabeledInput'
import OpenCreationsAmount from './OpenCreationsAmount.vue'
import { object, date as dateSchema, number, string } from 'yup'
import { GDD_PER_HOUR } from '../../constants'
import { useMinimalContributionDate } from '@/composables/useMinimalContributionDate'
const amountToHours = (amount) => parseFloat(amount / GDD_PER_HOUR).toFixed(2)
const hoursToAmount = (hours) => parseFloat(hours * GDD_PER_HOUR).toFixed(2)
@ -103,6 +104,7 @@ const props = defineProps({
modelValue: { type: Object, required: true },
maxGddLastMonth: { type: Number, required: true },
maxGddThisMonth: { type: Number, required: true },
successMessage: { type: String, required: true },
})
const emit = defineEmits(['upsert-contribution', 'abort'])
@ -125,6 +127,7 @@ const form = reactive({ ...entityDataToForm.value })
const now = ref(new Date()) // checked every minute, updated if day, month or year changed
const disableSmartValidState = ref(false)
const minimalDate = computed(() => useMinimalContributionDate(now.value))
const isThisMonth = computed(() => {
const formContributionDate = new Date(form.contributionDate)
return (
@ -133,12 +136,6 @@ const isThisMonth = computed(() => {
)
})
const minimalDate = computed(() => {
const minimalDate = new Date(now.value)
minimalDate.setMonth(now.value.getMonth() - 1, 1)
return minimalDate
})
// reactive validation schema, because some boundaries depend on form input and existing data
const validationSchema = computed(() => {
const maxAmounts = Number(

View File

@ -1,9 +1,9 @@
<template>
<div class="bg-white app-box-shadow gradido-border-radius p-3">
<div class="p-4" data-test="send-transaction-success-text">
<div class="p-4" data-test="success-message">
{{ $t('form.thx') }}
<hr />
{{ $t('form.send_transaction_success') }}
{{ message }}
</div>
<div class="text-center mt-5">
<BButton variant="primary" @click="$emit('on-back')">
@ -12,8 +12,15 @@
</div>
</div>
</template>
<script>
export default {
name: 'TransactionResultSendSuccess',
}
<script setup>
import { defineProps, defineEmits } from 'vue'
defineProps({
message: {
type: String,
default: '',
},
})
defineEmits(['on-back'])
</script>

View File

@ -0,0 +1,5 @@
export function useMinimalContributionDate(now) {
const minimalDate = new Date(now)
minimalDate.setMonth(now.getMonth() - 1, 1)
return minimalDate
}

View File

@ -28,7 +28,10 @@
></transaction-confirmation-link>
</template>
<template #transactionResultSendSuccess>
<transaction-result-send-success @on-back="onBack"></transaction-result-send-success>
<success-message
:message="$t('form.send_transaction_success')"
@on-back="onBack"
></success-message>
</template>
<template #transactionResultSendError>
<transaction-result-send-error
@ -58,7 +61,7 @@ import GddSend, { TRANSACTION_STEPS } from '@/components/GddSend'
import TransactionForm from '@/components/GddSend/TransactionForm'
import TransactionConfirmationSend from '@/components/GddSend/TransactionConfirmationSend'
import TransactionConfirmationLink from '@/components/GddSend/TransactionConfirmationLink'
import TransactionResultSendSuccess from '@/components/GddSend/TransactionResultSendSuccess'
import SuccessMessage from '@/components/SuccessMessage'
import TransactionResultSendError from '@/components/GddSend/TransactionResultSendError'
import TransactionResultLink from '@/components/GddSend/TransactionResultLink'
import { sendCoins, createTransactionLink } from '@/graphql/mutations.js'

View File

@ -3,6 +3,7 @@ export * from './enum'
export * from './const'
export * from './helper'
export * from './logic/decay'
export * from './util'
export * from './jwt/JWT'
export * from './jwt/payloadtypes/AuthenticationJwtPayloadType'
export * from './jwt/payloadtypes/AuthenticationResponseJwtPayloadType'

1
shared/src/util/index.ts Normal file
View File

@ -0,0 +1 @@
export * from './utilities'

View File

@ -0,0 +1,2 @@
export const fullName = (firstName: string, lastName: string): string =>
[firstName, lastName].filter(Boolean).join(' ')