@design-edito/publisher-core 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +265 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5105 -0
- package/dist/index.js.map +7 -0
- package/dist/public/empty.txt +0 -0
- package/dist/types/api/admin/temp/flush/index.d.ts +6 -0
- package/dist/types/api/admin/users/create/index.d.ts +23 -0
- package/dist/types/api/admin/users/delete/index.d.ts +12 -0
- package/dist/types/api/admin/users/get/index.d.ts +18 -0
- package/dist/types/api/admin/users/get-upload-quota/index.d.ts +12 -0
- package/dist/types/api/admin/users/list/index.d.ts +24 -0
- package/dist/types/api/admin/users/reset-upload-quota/index.d.ts +15 -0
- package/dist/types/api/admin/users/revoke-auth-tokens/index.d.ts +10 -0
- package/dist/types/api/admin/users/revoke-email-validation-tokens/index.d.ts +10 -0
- package/dist/types/api/admin/users/revoke-pasword-renewal-tokens/index.d.ts +10 -0
- package/dist/types/api/admin/users/update/index.d.ts +23 -0
- package/dist/types/api/auth/login/index.d.ts +15 -0
- package/dist/types/api/auth/logout/index.d.ts +5 -0
- package/dist/types/api/auth/logout-everywhere/index.d.ts +5 -0
- package/dist/types/api/auth/refresh-token/index.d.ts +5 -0
- package/dist/types/api/auth/request-email-verification-token/index.d.ts +9 -0
- package/dist/types/api/auth/request-new-password/index.d.ts +9 -0
- package/dist/types/api/auth/signup/index.d.ts +13 -0
- package/dist/types/api/auth/submit-new-password/index.d.ts +11 -0
- package/dist/types/api/auth/verify-email/index.d.ts +12 -0
- package/dist/types/api/auth/whoami/index.d.ts +8 -0
- package/dist/types/api/csrf/get-token/index.d.ts +8 -0
- package/dist/types/api/image/format/index.d.ts +28 -0
- package/dist/types/api/image/transform/index.d.ts +11 -0
- package/dist/types/api/index.d.ts +102 -0
- package/dist/types/api/internals.d.ts +270 -0
- package/dist/types/api/system/kill/index.d.ts +3 -0
- package/dist/types/api/system/ping/index.d.ts +6 -0
- package/dist/types/api/system/send-mail/index.d.ts +11 -0
- package/dist/types/api/system/status-check/index.d.ts +22 -0
- package/dist/types/auth/index.d.ts +11 -0
- package/dist/types/csrf/index.d.ts +5 -0
- package/dist/types/database/index.d.ts +69 -0
- package/dist/types/dto/index.d.ts +25 -0
- package/dist/types/email/index.d.ts +6 -0
- package/dist/types/env/index.d.ts +83 -0
- package/dist/types/errors/index.d.ts +295 -0
- package/dist/types/fs/index.d.ts +110 -0
- package/dist/types/index.d.ts +21 -0
- package/dist/types/index.js +1 -0
- package/dist/types/index.js.map +7 -0
- package/dist/types/init/index.d.ts +1 -0
- package/dist/types/jwt/index.d.ts +7 -0
- package/dist/types/logs/index.d.ts +46 -0
- package/dist/types/plugins/index.d.ts +3 -0
- package/dist/types/plugins/internals.d.ts +177 -0
- package/dist/types/schema/index.d.ts +156 -0
- package/dist/types/temp/index.d.ts +7 -0
- package/dist/types/transformers/index.d.ts +3 -0
- package/dist/types/transformers/user/index.d.ts +5 -0
- package/dist/types/transformers/user-upload-quota/index.d.ts +3 -0
- package/dist/types/uploads/index.d.ts +73 -0
- package/dist/types/validation/index.d.ts +4 -0
- package/package.json +280 -0
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"sources": ["../src/index.ts", "../src/api/utils.ts", "../src/auth/index.ts", "../src/database/index.ts", "../src/env/index.ts", "../src/errors/index.ts", "../src/types/errors/index.ts", "../src/logs/index.ts", "../src/email/index.ts", "../src/schema/user/user/index.ts", "../src/types/schema/index.ts", "../src/schema/_history/index.ts", "../src/schema/_meta/index.ts", "../src/schema/_password/index.ts", "../src/schema/user/auth-token/index.ts", "../src/schema/user/revoked-auth-token/index.ts", "../src/schema/user/email-validation-token/index.ts", "../src/schema/user/password-renewal-token/index.ts", "../src/csrf/index.ts", "../src/upload/index.ts", "../src/schema/user/upload-quota/index.ts", "../src/temp/index.ts", "../src/upload/httpClamScanner.ts", "../src/validation/index.ts", "../src/api/admin/temp/flush/authentication.ts", "../src/api/admin/temp/flush/operation.ts", "../src/api/admin/temp/flush/index.ts", "../src/api/admin/temp/index.ts", "../src/api/admin/users/create/authentication.ts", "../src/api/admin/users/create/operation.ts", "../src/transformers/user/index.ts", "../src/api/admin/users/create/validation.ts", "../src/api/admin/users/create/index.ts", "../src/api/admin/users/delete/authentication.ts", "../src/api/admin/users/delete/operation.ts", "../src/api/admin/users/delete/validation.ts", "../src/api/admin/users/delete/index.ts", "../src/api/admin/users/get/authentication.ts", "../src/api/admin/users/get/operation.ts", "../src/api/admin/users/get/validation.ts", "../src/api/admin/users/get/index.ts", "../src/api/admin/users/get-upload-quota/authentication.ts", "../src/transformers/user-upload-quota/index.ts", "../src/api/admin/users/get-upload-quota/operation.ts", "../src/api/admin/users/get-upload-quota/validation.ts", "../src/api/admin/users/get-upload-quota/index.ts", "../src/api/admin/users/list/authentication.ts", "../src/api/admin/users/list/operation.ts", "../src/api/admin/users/list/validation.ts", "../src/api/admin/users/list/index.ts", "../src/api/admin/users/reset-upload-quota/authentication.ts", "../src/api/admin/users/reset-upload-quota/operation.ts", "../src/api/admin/users/reset-upload-quota/validation.ts", "../src/api/admin/users/reset-upload-quota/index.ts", "../src/api/admin/users/revoke-auth-tokens/authentication.ts", "../src/api/admin/users/revoke-auth-tokens/operation.ts", "../src/api/admin/users/revoke-auth-tokens/validation.ts", "../src/api/admin/users/revoke-auth-tokens/index.ts", "../src/api/admin/users/revoke-email-validation-tokens/authentication.ts", "../src/api/admin/users/revoke-email-validation-tokens/operation.ts", "../src/api/admin/users/revoke-email-validation-tokens/validation.ts", "../src/api/admin/users/revoke-email-validation-tokens/index.ts", "../src/api/admin/users/revoke-password-renewal-tokens/authentication.ts", "../src/api/admin/users/revoke-password-renewal-tokens/operation.ts", "../src/api/admin/users/revoke-password-renewal-tokens/validation.ts", "../src/api/admin/users/revoke-password-renewal-tokens/index.ts", "../src/api/admin/users/update/authentication.ts", "../src/api/admin/users/update/operation.ts", "../src/api/admin/users/update/validation.ts", "../src/api/admin/users/update/index.ts", "../src/api/admin/users/index.ts", "../src/api/admin/index.ts", "../src/api/auth/login/validation.ts", "../src/api/auth/login/operation.ts", "../src/api/auth/login/index.ts", "../src/api/auth/logout/authentication.ts", "../src/api/auth/logout/operation.ts", "../src/api/auth/logout/index.ts", "../src/api/auth/logout-everywhere/authentication.ts", "../src/api/auth/logout-everywhere/operation.ts", "../src/api/auth/logout-everywhere/index.ts", "../src/api/auth/refresh-token/operation.ts", "../src/api/auth/refresh-token/index.ts", "../src/api/auth/request-email-verification-token/validation.ts", "../src/api/auth/request-email-verification-token/operation.ts", "../src/api/auth/request-email-verification-token/index.ts", "../src/api/auth/request-new-password/validation.ts", "../src/api/auth/request-new-password/operation.ts", "../src/api/auth/request-new-password/index.ts", "../src/api/auth/signup/valiadtion.ts", "../src/api/auth/signup/operation.ts", "../src/api/auth/signup/index.ts", "../src/api/auth/submit-new-password/validation.ts", "../src/api/auth/submit-new-password/operation.ts", "../src/api/auth/submit-new-password/index.ts", "../src/api/auth/verify-email/validation.ts", "../src/api/auth/verify-email/operation.ts", "../src/api/auth/verify-email/index.ts", "../src/api/auth/whoami/authentication.ts", "../src/api/auth/whoami/operation.ts", "../src/api/auth/whoami/index.ts", "../src/api/auth/index.ts", "../src/api/csrf/get-token/operation.ts", "../src/api/csrf/get-token/index.ts", "../src/api/csrf/index.ts", "../src/api/image/format/index.ts", "../src/api/image/format/authentication.ts", "../src/api/image/format/validation.ts", "../src/api/image/format/operation.ts", "../src/api/image/transform/index.ts", "../src/api/image/transform/authentication.ts", "../src/api/image/transform/validation.ts", "../src/api/image/transform/operation.ts", "../src/api/image/index.ts", "../src/api/system/kill/operation.ts", "../src/api/system/kill/index.ts", "../src/api/system/ping/operation.ts", "../src/api/system/ping/index.ts", "../src/api/system/send-mail/operation.ts", "../src/api/system/send-mail/index.ts", "../src/api/system/status-check/operation.ts", "../src/init/index.ts", "../src/cron/index.ts", "../src/fs/index.ts", "../src/api/system/status-check/index.ts", "../src/api/system/index.ts", "../src/api/index.ts", "../src/plugins/index.ts", "../src/ssl/index.ts", "../src/cors/index.ts", "../src/www/index.ts"],
|
4
|
+
"sourcesContent": ["import path from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport cookieParser from 'cookie-parser'\nimport express from 'express'\nimport { Duration } from '@design-edito/tools/agnostic/time/duration/index.js'\nimport * as Api from './api/index.js'\nimport * as Plugins from './plugins/index.js'\nimport * as Ssl from './ssl/index.js'\nimport * as ApiUtils from './api/utils.js'\nimport * as Auth from './auth/index.js'\nimport { corsMiddleware } from './cors/index.js'\nimport * as Database from'./database/index.js'\nimport * as Init from './init/index.js'\nimport { httpLoggerMiddleware, logInfo } from './logs/index.js'\nimport { Category as LogCategory } from './types/logs/index.js'\nimport { serve } from './www/index.js'\n\nexport async function start () {\n logInfo(LogCategory.INIT, 'Starting server...')\n\n // Prepare to gracefully shutdown the server if needed\n Init.captureTerminationSignals()\n \n // Database, Cron, FS, ...\n const dbConnectResult = await Database.connectWithRetries(5, Duration.seconds(1).toMs())\n if (!dbConnectResult.success) Init.shutdown(1)\n await Init.scheduleCronTasks()\n await Init.ensureSingleRootUser()\n await Init.ensureSingleMainAdminUser()\n \n // App setup\n const app = express()\n app.use(corsMiddleware)\n app.use(httpLoggerMiddleware)\n app.use(express.json())\n app.use(express.urlencoded({ extended: false }))\n app.use(cookieParser())\n \n // Auth, Request meta\n app.use(Ssl.enforceHttpsMiddleware())\n app.use(ApiUtils.setInitMetaMiddleware)\n app.use(Auth.authenticateMiddleware)\n \n // API endpoints\n app.use(Api.router)\n \n // Init plugins\n await Plugins.init(app)\n \n // Static files\n const ROOT = path.dirname(fileURLToPath(import.meta.url))\n const PUBLIC = path.join(ROOT, 'public')\n app.use(express.static(PUBLIC))\n \n // API Catch-alls\n app.use(ApiUtils.fourOhFourMiddleware)\n app.use(ApiUtils.catchAllMiddleware)\n \n serve(app)\n \n // Notify app started\n Init.notifyMainAdminUserServerStarted() \n}\n", "import '../global.d.ts' // Type extensions for Express.Locals.initMeta\nimport { createReadStream } from 'node:fs'\nimport { hrtime } from 'node:process'\nimport { Readable } from 'node:stream'\nimport { randomUUID } from 'node:crypto'\nimport { parse as parseFileName } from 'node:path'\nimport { Router, Request, Response, NextFunction } from 'express'\nimport { fileTypeFromStream } from 'file-type'\nimport { sanitizeUserInput } from '@design-edito/tools/agnostic/sanitization/index.js'\nimport { normalizeExtension } from '@design-edito/tools/agnostic/misc/normalize-extension/index.js'\nimport { useMulterMiddleware } from '@design-edito/tools/node/@express/@multer/index.js'\nimport { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport { mebibytes } from '@design-edito/tools/agnostic/misc/data-size/index.js'\nimport { checkAccessToken, fetchUser } from '../auth/index.js'\nimport { verify as verifyCsrfToken } from '../csrf/index.js'\nimport env from '../env/index.js'\nimport { makeError } from '../errors/index.js'\nimport { logError, logWarning } from '../logs/index.js'\nimport {\n WorkerErrorResponse,\n WorkerVoidResponse,\n WorkerJsonResponse,\n WorkerListResponse,\n WorkerFileResponse,\n InitServerResponseMeta,\n ServerResponseMeta,\n ServerErrorResponse,\n ServerJsonResponse,\n ServerListResponse,\n ProcessContract,\n NoAuthProcessContract,\n WeakAuthProcessContract,\n StrongAuthProcessContract,\n WeakAuthenticatorPayloadGetterResponse,\n StrongAuthenticatorPayloadGetterResponse,\n UploadsDescriptor,\n UploadsProcessorErrCodes\n} from '../types/api/internals.js'\nimport { Codes, DetailsMaker } from '../types/errors/index.js'\nimport { Category as LogCategory } from '../types/logs/index.js'\nimport { ScanFileError } from '../types/uploads/index.js'\nimport { UploadedFile } from '../types/uploads/index.js'\nimport { getFileHash, multerStorage, scanFile, updateUserUploadsQuota } from '../upload/index.js'\n\n/* * * * * * * * * * * * * * * * * *\n *\n * Worker response types\n * \n * * * * * * * * * * * * * * * * */\n\nexport const errorResponse = <C extends Codes>(\n httpStatus: number,\n code: C,\n ...details: Parameters<DetailsMaker<C>>\n): WorkerErrorResponse<C> => {\n const errData = makeError(code, ...details)\n return {\n type: 'error',\n httpStatus,\n code,\n message: errData.message,\n details: errData.details\n }\n}\n\nexport const voidResponse = (): WorkerVoidResponse => ({ type: 'void' })\n\nexport const jsonResponse = <P extends object>(\n httpStatus: number,\n payload: P\n): WorkerJsonResponse<P> => ({\n type: 'json',\n httpStatus,\n payload\n})\n\nexport const listResponse = <P extends object>(\n httpStatus: number,\n payload: P[],\n page: number,\n total: number,\n prev: string | null,\n next: string | null\n): WorkerListResponse<P> => ({\n type: 'list',\n httpStatus,\n payload,\n page,\n total,\n prev,\n next\n})\n\nexport const fileResponse = (\n httpStatus: number,\n filename: string,\n payload: Readable | Buffer,\n contentType: string,\n cacheControl: string,\n contentLengthBytes: number\n): WorkerFileResponse => ({\n type: 'file',\n httpStatus,\n filename,\n payload,\n contentType,\n cacheControl,\n contentLengthBytes\n})\n\n/* * * * * * * * * * * * * * *\n *\n * Response meta data utils\n * \n * * * * * * * * * * * * * * */\n\nexport const getDefaultServerResponseMeta = (): InitServerResponseMeta => ({\n ip: null,\n userId: null,\n requestId: '',\n startHrTimeNs: 0n,\n timestampMs: 0\n})\n\nexport const wrapServerResponseMeta = (initMeta: InitServerResponseMeta): ServerResponseMeta => {\n const { ip, userId, requestId, startHrTimeNs, timestampMs } = initMeta\n const nowNs = hrtime.bigint()\n const elapsedNs = nowNs - startHrTimeNs\n const elapsedMs = Number(elapsedNs / 1_000_000n)\n return {\n ip,\n userId,\n requestId,\n timestampMs,\n elapsedMs\n }\n}\n\nexport const setInitMetaMiddleware = (\n req: Request,\n res: Response,\n next: NextFunction\n) => {\n const { ip } = req\n const { locals } = res\n const { accessTokenPayload = { userId: null } } = locals\n const { userId } = accessTokenPayload\n res.locals.initMeta = {\n ip: ip ?? null,\n userId,\n requestId: randomUUID(),\n startHrTimeNs: hrtime.bigint(),\n timestampMs: Date.now()\n }\n next()\n}\n\nexport const getRequestInitMeta = (res: Response): InitServerResponseMeta => {\n const initMeta = res.locals.initMeta\n if (initMeta === undefined) logWarning(\n LogCategory.REQUEST,\n 'Could not find init meta in response locals'\n )\n return initMeta ?? getDefaultServerResponseMeta()\n}\n\n/* * * * * * * * * * * * * * *\n *\n * Server response senders\n * \n * * * * * * * * * * * * * * */\n\nexport const setDefaultResponseHeaders = (\n res: Response,\n responseMeta: ServerResponseMeta\n) => {\n res.setHeader('Cache-Control', 'no-store')\n .setHeader('Content-Security-Policy', `default-src 'none';`)\n .setHeader('Referrer-Policy', 'no-referrer')\n .setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains')\n .setHeader('X-Content-Type-Options', 'nosniff')\n .setHeader('X-Request-ID', responseMeta.requestId)\n .setHeader('X-Response-Time', `${Date.now() - responseMeta.timestampMs}ms`)\n .setHeader('X-Server-Meta', JSON.stringify({\n userId: responseMeta.userId,\n requestId: responseMeta.requestId,\n timestampMs: responseMeta.timestampMs\n }))\n}\n\nexport const sendServerErrorResponse = <\n C extends Codes,\n S extends number = number\n>(\n res: Response<ServerErrorResponse<C>>,\n errorResponse: WorkerErrorResponse<C>\n): Response<ServerErrorResponse<C>> => {\n const initMeta = getRequestInitMeta(res)\n const responseMeta = wrapServerResponseMeta(initMeta)\n setDefaultResponseHeaders(res, responseMeta)\n const fullResponse: ServerErrorResponse<C> = {\n success: false,\n httpStatus: errorResponse.httpStatus,\n type: 'error',\n error: {\n code: errorResponse.code,\n message: errorResponse.message,\n details: errorResponse.details\n },\n meta: responseMeta\n }\n res.status(fullResponse.httpStatus)\n .type('application/problem+json')\n .setHeader('Content-Disposition', 'inline')\n .json(fullResponse)\n return res\n}\n\nexport const sendServerVoidResponse = (\n res: Response<Record<never, never>>\n): Response<Record<never, never>> => {\n const initMeta = getRequestInitMeta(res)\n const responseMeta = wrapServerResponseMeta(initMeta)\n setDefaultResponseHeaders(res, responseMeta)\n res.status(204)\n .end()\n return res\n}\n\nexport const sendServerJsonResponse = <\n P extends object,\n S extends number = number\n>(\n res: Response<ServerJsonResponse<P>>,\n jsonResponse: WorkerJsonResponse<P>\n): Response<ServerJsonResponse<P>> => {\n const initMeta = getRequestInitMeta(res)\n const responseMeta = wrapServerResponseMeta(initMeta)\n setDefaultResponseHeaders(res, responseMeta)\n const fullResponse: ServerJsonResponse<P> = {\n success: true,\n ...jsonResponse,\n meta: responseMeta,\n }\n res.status(fullResponse.httpStatus)\n .type('application/json; charset=utf-8')\n .setHeader('Content-Disposition', 'inline')\n .json(fullResponse)\n return res\n}\n\nexport const sendServerListResponse = <\n P extends object,\n S extends number = number\n>(\n res: Response<ServerListResponse<P>>,\n listResponse: WorkerListResponse<P>\n): Response<ServerListResponse<P>> => {\n const initMeta = getRequestInitMeta(res)\n const responseMeta = wrapServerResponseMeta(initMeta)\n setDefaultResponseHeaders(res, responseMeta)\n const fullResponse: ServerListResponse<P> = {\n success: true,\n ...listResponse,\n meta: responseMeta\n }\n res.status(fullResponse.httpStatus)\n .type('application/json; charset=utf-8')\n .setHeader('Content-Disposition', 'inline')\n .setHeader('X-Total-Count', fullResponse.total)\n .setHeader('X-Page', fullResponse.page)\n .setHeader('X-Next-Page', fullResponse.next ?? '')\n .setHeader('X-Prev-Page', fullResponse.prev ?? '')\n .json(fullResponse)\n return res\n}\n\nexport const sendServerFileResponse = (\n res: Response<Record<never, never>>,\n fileResponse: WorkerFileResponse\n): Response<Record<never, never> | ServerErrorResponse<Codes.RESPONSE_STREAM_FAILED>> => {\n const initMeta = getRequestInitMeta(res)\n const responseMeta = wrapServerResponseMeta(initMeta)\n setDefaultResponseHeaders(res, responseMeta)\n res.status(fileResponse.httpStatus)\n .type(fileResponse.contentType)\n .setHeader('Content-Disposition', `attachment; filename=\"${fileResponse.filename}\"; filename*=UTF-8''${encodeURIComponent(fileResponse.filename)}`)\n .setHeader('Cache-Control', fileResponse.cacheControl)\n .setHeader('Content-Length', fileResponse.contentLengthBytes)\n if (fileResponse.payload instanceof Readable) {\n const errorMessage = 'Something went wrong while trying to stream the file back to the client'\n fileResponse.payload.on('error', (err) => {\n logError(LogCategory.FILE_RESPONSE_STREAM, errorMessage, { err })\n if (!res.headersSent) {\n sendServerErrorResponse(res, errorResponse(\n 500,\n Codes.RESPONSE_STREAM_FAILED,\n errorMessage\n ))\n } else res.destroy()\n })\n fileResponse.payload.pipe(res)\n }\n else res.send(fileResponse.payload)\n return res\n}\n\n/* * * * * * * * * * * * * * *\n *\n * Router creation\n * \n * * * * * * * * * * * * * * */\n\nexport const processUploads = async (\n req: Request,\n res: Response,\n fields: UploadsDescriptor['fields'],\n limits: UploadsDescriptor['limits'],\n filter: UploadsDescriptor['filter'],\n incrementQuotas: boolean = true\n): Promise<WorkerVoidResponse | WorkerErrorResponse<UploadsProcessorErrCodes>> => {\n\n /* Multer */\n const multerChecked = await useMulterMiddleware(req, res, {\n storage: multerStorage,\n mode: 'fields',\n fields: fields,\n limits: limits,\n fileFilter: filter\n })\n if (!multerChecked.success) {\n const { code } = multerChecked.error\n if (code === 'LIMIT_FILE_SIZE') return errorResponse(400, Codes.FILE_TOO_LARGE, `File is too large: ${multerChecked.error.field}`)\n return errorResponse(400, Codes.INVALID_REQUEST_FILES, unknownToString(multerChecked.error))\n }\n const { files } = req\n if (Array.isArray(files)) {\n logWarning(LogCategory.UPLOAD, 'Multer returned an array of files, which is not expected', { files })\n res.locals.uploads = undefined\n return voidResponse()\n }\n if (files === undefined) {\n res.locals.uploads = {}\n return voidResponse()\n }\n // Express.Multer.Files type is incorrect, stream and buffer are not available using diskStorage,\n // and I just want to omit mimetype since it's later provided by file-type\n const fileFields = Object.entries(files) as [string, Omit<\n Express.Multer.File,\n 'stream' | 'buffer' | 'filename'\n >[]][]\n if (fileFields.length === 0) return voidResponse()\n if (fileFields.every(([_, files]) => files.length === 0)) return voidResponse()\n\n /* Quotas */\n if (incrementQuotas) {\n const { userId } = res.locals.accessTokenPayload ?? {}\n if (userId === undefined) return errorResponse(401, Codes.USER_NOT_AUTHENTICATED, 'User must be authenticated to upload files')\n const totalUploadByteSize = Object.values(files).flat().reduce((acc, file) => acc + file.size, 0)\n if (totalUploadByteSize === 0) return errorResponse(400, Codes.INVALID_REQUEST_FILES, 'Cannot upload empty files')\n const quotasUpdationAttempt = await updateUserUploadsQuota(userId, totalUploadByteSize, {\n daily: mebibytes(env.USER_UPLOAD_DAILY_LIMIT_MEBIBYTES).toBytes(),\n monthly: mebibytes(env.USER_UPLOAD_MONTHLY_LIMIT_MEBIBYTES).toBytes(),\n total: mebibytes(env.USER_UPLOAD_TOTAL_LIMIT_MEBIBYTES).toBytes()\n })\n if (!quotasUpdationAttempt.success) return errorResponse(400, Codes.USER_UPLOAD_QUOTA_EXCEEDED, 'User has exceeded their upload quota')\n }\n\n /* Get stream, scan, hash, get type */\n const processedFilesFlat: Array<{ field: string, file: UploadedFile }> = []\n for (const [field, files] of fileFields) {\n for (const filePos in files) {\n const file = files[filePos]!\n const path = file.path\n const scanResult = await scanFile(createReadStream(path))\n if (!scanResult.success) {\n if (scanResult.error.code === ScanFileError.INFECTED) return errorResponse(400, Codes.FILE_INFECTED, `The file at positon ${filePos} in field ${field} is infected`)\n else return errorResponse(400, Codes.FILE_SCANNER_NOT_REACHABLE, 'Unable to scan the files')\n }\n const inName = file.originalname\n const inMime = file.mimetype\n const { name: inBase, ext: rawInExt } = parseFileName(inName)\n const inExt = rawInExt.replace(/^\\./, '')\n const inExtNormalized = normalizeExtension(inExt.toLowerCase())\n const { ext: detectedExt, mime: detectedMime } = await fileTypeFromStream(createReadStream(path)) ?? {}\n if (detectedExt !== undefined && detectedExt !== inExtNormalized) return errorResponse(400, Codes.INVALID_REQUEST_FILES, `The file at positon ${filePos} in field ${field} has an invalid extension`)\n if (detectedMime !== undefined && detectedMime !== inMime) return errorResponse(400, Codes.INVALID_REQUEST_FILES, `The file at positon ${filePos} in field ${field} has an invalid MIME type`)\n const outExt = detectedExt ?? inExtNormalized\n const allowedExtensions = env.USER_UPLOAD_ALLOWED_EXTENSIONS\n if (!allowedExtensions.includes(outExt)) return errorResponse(400, Codes.INVALID_REQUEST_FILES, `.${outExt} files are not allowed to be uploaded to the server (file at positon ${filePos} in field ${field})`)\n const outBase = inBase\n const outName = outExt === '' ? inBase : `${inBase}.${outExt}`\n const outMime = detectedMime ?? inMime\n const hashOutcome = await getFileHash(createReadStream(path))\n if (!hashOutcome.success) return errorResponse(400, Codes.FILE_HASH_FAILED, `The file at positon ${filePos} in field ${field} failed to hash`)\n const hash = hashOutcome.payload\n processedFilesFlat.push({ field, file: {\n fieldname: file.fieldname,\n size: file.size,\n destination: file.destination,\n path,\n hash,\n inName,\n inBase,\n inExt,\n inMime,\n inExtNormalized,\n detectedExt,\n detectedMime,\n outExt,\n outBase,\n outName,\n outMime\n }})\n }\n }\n const processedFiles: Record<string, UploadedFile[]> = processedFilesFlat.reduce((acc, { field, file }) => {\n if (!acc[field]) acc[field] = []\n acc[field].push(file)\n return acc\n }, {} as Record<string, UploadedFile[]>)\n\n res.locals.uploads = processedFiles\n return voidResponse()\n}\n\ntype ContractorResponse = WorkerJsonResponse<any>\n | WorkerListResponse<any>\n | WorkerFileResponse\n | WorkerVoidResponse\n | WorkerErrorResponse<any>\n\nexport function makeNoAuthContractor<T extends NoAuthProcessContract<any, any, any, any, any, any, any>> (contract: T) {\n return async (req: Request, res: Response): Promise<ContractorResponse> => {\n const validationHooks = {\n body: sanitizeUserInput(\n contract.uploads !== undefined\n ? JSON.parse(req.body._json as string) as unknown\n : req.body as unknown\n ),\n query: sanitizeUserInput(req.query),\n params: sanitizeUserInput(req.params),\n files: res.locals.uploads ?? {},\n headers: sanitizeUserInput(req.headers),\n cookies: sanitizeUserInput(req.cookies),\n originalUrl: sanitizeUserInput(req.originalUrl),\n ip: req.ip ?? null,\n accessTokenSigned: undefined,\n accessTokenPayload: undefined,\n user: null,\n setCookie: (...params: Parameters<typeof res.cookie>) => res.cookie(...params),\n setHeader: (...params: Parameters<typeof res.setHeader>) => res.setHeader(...params),\n _unsafeReq: req,\n _unsafeRes: res\n }\n const { validation, operation } = contract\n const validationResult = await validation(validationHooks)\n if (validationResult.type === 'error') return validationResult\n const { body, params, query } = validationResult.payload\n const operationHooks = {\n ...validationHooks,\n body,\n params,\n query\n }\n const operationResult = await operation(operationHooks)\n return operationResult\n }\n}\n\nexport async function getWeakAuthenticatorPayload (res: Response): Promise<WeakAuthenticatorPayloadGetterResponse> {\n const { accessTokenSigned, accessTokenPayload } = res.locals\n if (accessTokenSigned === undefined) return errorResponse(401, Codes.USER_NOT_AUTHENTICATED, 'Access token is missing')\n if (accessTokenPayload === undefined) return errorResponse(401, Codes.USER_NOT_AUTHENTICATED, 'Access token is corrupted')\n const tokensChecked = await checkAccessToken(accessTokenSigned, accessTokenPayload)\n if (!tokensChecked.success) return errorResponse(401, Codes.USER_NOT_AUTHENTICATED, tokensChecked.error.message)\n return jsonResponse(200, { accessTokenSigned, accessTokenPayload })\n}\n\nexport function makeWeakAuthContractor<T extends WeakAuthProcessContract<any, any, any, any, any, any, any>> (contract: T) {\n return async (req: Request, res: Response): Promise<ContractorResponse> => {\n const authenticatorPayload = await getWeakAuthenticatorPayload(res)\n if (authenticatorPayload.type === 'error') return authenticatorPayload\n let { accessTokenSigned, accessTokenPayload } = authenticatorPayload.payload\n const authenticationHooks = {\n body: sanitizeUserInput(\n contract.uploads !== undefined\n ? JSON.parse(req.body._json as string) as unknown\n : req.body as unknown\n ),\n query: sanitizeUserInput(req.query),\n params: sanitizeUserInput(req.params),\n files: res.locals.uploads ?? {},\n headers: sanitizeUserInput(req.headers),\n cookies: sanitizeUserInput(req.cookies),\n originalUrl: sanitizeUserInput(req.originalUrl),\n ip: req.ip ?? null,\n accessTokenSigned,\n accessTokenPayload: sanitizeUserInput(accessTokenPayload),\n user: null,\n setCookie: (...params: Parameters<typeof res.cookie>) => res.cookie(...params),\n setHeader: (...params: Parameters<typeof res.setHeader>) => res.setHeader(...params),\n _unsafeReq: req,\n _unsafeRes: res\n }\n const { authentication, validation, operation } = contract\n const authenticationResult = await authentication(authenticationHooks)\n if (authenticationResult.type === 'error') return authenticationResult\n accessTokenSigned = authenticationResult.payload.accessTokenSigned\n accessTokenPayload = authenticationResult.payload.accessTokenPayload\n const validationHooks = {\n ...authenticationHooks,\n accessTokenSigned,\n accessTokenPayload\n }\n const validationResult = await validation(validationHooks)\n if (validationResult.type === 'error') return validationResult\n const { body, params, query } = validationResult.payload\n const operationHooks = {\n ...validationHooks,\n body,\n params,\n query\n }\n const operationResult = await operation(operationHooks)\n return operationResult\n }\n}\n\nexport async function getStrongAuthenticatorPayload (res: Response): Promise<StrongAuthenticatorPayloadGetterResponse> {\n const { accessTokenSigned, accessTokenPayload } = res.locals\n if (accessTokenSigned === undefined) return errorResponse(401, Codes.USER_NOT_AUTHENTICATED, 'Access token is missing')\n if (accessTokenPayload === undefined) return errorResponse(401, Codes.USER_NOT_AUTHENTICATED, 'Access token is corrupted')\n const { userId } = accessTokenPayload\n const tokenAndUserFetch = await Promise.all([\n checkAccessToken(accessTokenSigned, accessTokenPayload),\n fetchUser(userId)\n ] as const)\n const [tokenChecked, userFetched] = tokenAndUserFetch\n if (!tokenChecked.success) return errorResponse(401, Codes.USER_NOT_AUTHENTICATED, tokenChecked.error.message)\n if (!userFetched.success) return errorResponse(401, Codes.USER_DOES_NOT_EXIST, userFetched.error.message)\n const user = userFetched.payload\n return jsonResponse(200, {\n user,\n accessTokenSigned,\n accessTokenPayload\n })\n}\n\nexport function makeStrongAuthContractor<T extends StrongAuthProcessContract<any, any, any, any, any, any, any>> (contract: T) { \n return async (req: Request, res: Response): Promise<ContractorResponse> => {\n const authenticatorPayload = await getStrongAuthenticatorPayload(res)\n if (authenticatorPayload.type === 'error') return authenticatorPayload\n let { user, accessTokenSigned, accessTokenPayload } = authenticatorPayload.payload\n const authenticationHooks = {\n body: sanitizeUserInput(\n contract.uploads !== undefined\n ? JSON.parse(req.body._json as string) as unknown\n : req.body as unknown\n ),\n params: sanitizeUserInput(req.params),\n query: sanitizeUserInput(req.query),\n files: res.locals.uploads ?? {},\n headers: sanitizeUserInput(req.headers),\n cookies: sanitizeUserInput(req.cookies),\n originalUrl: sanitizeUserInput(req.originalUrl),\n ip: req.ip ?? null,\n accessTokenSigned,\n accessTokenPayload: sanitizeUserInput(accessTokenPayload),\n user,\n setCookie: (...params: Parameters<typeof res.cookie>) => res.cookie(...params),\n setHeader: (...params: Parameters<typeof res.setHeader>) => res.setHeader(...params),\n _unsafeReq: req,\n _unsafeRes: res\n }\n const { authentication, validation, operation } = contract\n const authenticationResult = await authentication(authenticationHooks)\n if (authenticationResult.type === 'error') return authenticationResult\n accessTokenSigned = authenticationResult.payload.accessTokenSigned\n accessTokenPayload = authenticationResult.payload.accessTokenPayload\n const validationHooks = {\n ...authenticationHooks,\n accessTokenSigned,\n accessTokenPayload\n }\n const validationResult = await validation(validationHooks)\n if (validationResult.type === 'error') return validationResult\n const { body, params, query } = validationResult.payload\n const operationHooks = {\n ...validationHooks,\n body,\n params,\n query\n }\n const operationResult = await operation(operationHooks)\n return operationResult\n }\n}\n\nexport function makeRouter (router: Record<string, ProcessContract<any, any, any, any, any, any, any, any>>): Router {\n const expressRouter = Router()\n Object.entries(router).forEach(([endpointName, _contract]) => {\n endpointName = endpointName as string\n const contract = _contract as ProcessContract<any, any, any, any, any, any, any>\n const method = endpointToMethod(endpointName)\n const path = endpointToPath(endpointName)\n const routerMethodName = method.toLowerCase()\n if (routerMethodName !== 'get'\n && routerMethodName !== 'post'\n && routerMethodName !== 'put'\n && routerMethodName !== 'delete'\n ) throw new Error(`Invalid endpoint name: ${endpointName}`);\n expressRouter[routerMethodName](path, async (req, res) => {\n try {\n const {\n uploads,\n skipCsrfProtection = false,\n _authType\n } = contract\n if (skipCsrfProtection === false\n && _authType !== 'none'\n && routerMethodName !== 'get') {\n const verifyCsrfTokenResult = verifyCsrfToken(req)\n if (!verifyCsrfTokenResult.success) {\n const response = errorResponse(403, Codes.INVALID_CSRF_TOKEN, verifyCsrfTokenResult.error)\n sendServerErrorResponse(res, response)\n return;\n }\n }\n if (uploads !== undefined) {\n const uploadsResult = await processUploads(\n req,\n res,\n uploads.fields,\n uploads.limits,\n uploads.filter,\n uploads.incrementQuotas\n )\n if (uploadsResult.type === 'error') {\n sendServerErrorResponse(res, uploadsResult)\n return\n }\n }\n let response: WorkerJsonResponse<any> | WorkerListResponse<any> | WorkerFileResponse | WorkerVoidResponse | WorkerErrorResponse<any>\n if (contract._authType === 'none') { response = await makeNoAuthContractor(contract)(req, res) }\n else if (contract._authType === 'weak') { response = await makeWeakAuthContractor(contract)(req, res) }\n else if (contract._authType === 'strong') { response = await makeStrongAuthContractor(contract)(req, res) }\n else throw { message: 'Invalid auth type', contract }\n if (response.type === 'error') sendServerErrorResponse(res, response)\n else if (response.type === 'json') sendServerJsonResponse(res, response)\n else if (response.type === 'list') sendServerListResponse(res, response)\n else if (response.type === 'file') sendServerFileResponse(res, response)\n else if (response.type === 'void') sendServerVoidResponse(res)\n else throw { message: 'Operator returned an expected shaped response object', response }\n } catch (err) {\n logError(LogCategory.REQUEST_CATCHALL, 'Uncaught error in a route handler', {\n err,\n method,\n path,\n userId: res.locals.accessTokenPayload?.userId,\n originalUrl: req.originalUrl,\n body: req.body,\n params: req.params,\n query: req.query,\n files: req.files\n })\n sendServerErrorResponse(res, errorResponse(\n 500,\n Codes.UNKNOWN_ERROR,\n 'Server\\'s internal workers encountered an unexpected error'\n ))\n }\n })\n })\n return expressRouter\n}\n\n/* * * * * * * * * * * * * * *\n *\n * Helpers\n * \n * * * * * * * * * * * * * * */\n\nexport const endpointToMethod = (endpoint: string) => {\n const method = endpoint.slice(0, endpoint.indexOf(':'))\n return method\n}\n\nexport const endpointToPath = (endpoint: string) => {\n const path = endpoint.slice(endpoint.indexOf(':') + 1)\n return path\n}\n\nexport const fourOhFourMiddleware = (_: Request, res: Response) => {\n sendServerErrorResponse(res, errorResponse(\n 404,\n Codes.NOT_FOUND,\n 'There is nothing here'\n ))\n}\n\nexport const catchAllMiddleware = (\n err: unknown,\n _req: Request,\n res: Response,\n _next: NextFunction\n) => {\n logError(\n LogCategory.REQUEST_CATCHALL,\n 'The server encountered an unexpected error',\n { err }\n )\n sendServerErrorResponse(res, errorResponse(\n 500,\n Codes.UNKNOWN_ERROR,\n 'The server encountered an unexpected error'\n ))\n}\n", "import '../global.d.ts' // Type extensions for Express.Locals.initMeta\nimport { randomUUID } from 'node:crypto'\nimport { Outcome } from '@design-edito/tools/agnostic/misc/outcome/index.js'\nimport { isNonNullObject } from '@design-edito/tools/agnostic/objects/is-object/index.js'\nimport { Duration } from '@design-edito/tools/agnostic/time/duration/index.js'\nimport { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport { Request, Response, NextFunction } from 'express'\nimport jwt from 'jsonwebtoken'\nimport { Types as MongooseTypes } from 'mongoose'\nimport {\n findOne,\n findMany,\n insertOne,\n insertMany,\n deleteMany\n} from '../database/index.js'\nimport { PartialPOJOInput } from '../types/database/index.js'\nimport * as Email from '../email/index.js'\nimport env from '../env/index.js'\nimport { makeFailureOutcome } from '../errors/index.js'\nimport { Codes, ErrorData } from '../types/errors/index.js'\nimport { BaseUserModel, discriminateUser } from '../schema/user/user/index.js'\nimport { UserAuthTokenModel } from '../schema/user/auth-token/index.js'\nimport { UserRevokedAuthTokenModel } from '../schema/user/revoked-auth-token/index.js'\nimport { UserEmailValidationTokenModel } from '../schema/user/email-validation-token/index.js'\nimport { IBaseUser, UserRole, UserStatus, UserBadge, IUserAuthToken, IUserRevokedAuthToken, IUserEmailValidationToken, IUserPasswordRenewalToken } from '../types/schema/index.js'\nimport { errorResponse, jsonResponse } from '../api/utils.js'\nimport { logError } from '../logs/index.js'\nimport { Category as LogCategory } from '../types/logs/index.js'\nimport { UserPasswordRenewalTokenModel } from '../schema/user/password-renewal-token/index.js'\nimport { Allower } from '../types/auth/index.js'\n\n/* * * * * * * * * * * * * * * * * * * * * * *\n *\n * JWT tokens generation and revocation\n *\n * * * * * * * * * * * * * * * * * * * * * * */\n\ntype Payload = NonNullable<Express.Locals['accessTokenPayload']>\n\nexport function isValidPayload (payload: unknown): payload is Payload {\n if (!isNonNullObject(payload)) return false\n if (!('userId' in payload)) return false\n if (typeof payload.userId !== 'string') return false\n if (!('exp' in payload)) return false\n if (typeof payload.exp !== 'number') return false\n if (!('refreshCount' in payload)) return false\n if (typeof payload.refreshCount !== 'number') return false\n return true\n}\n\nexport async function generateAccessToken (\n userId: string | MongooseTypes.ObjectId,\n refreshCount: number\n) {\n userId = userId.toString()\n const foundUser = await findOne<IBaseUser>(BaseUserModel, { _id: userId }, { initiatorId: env.ROOT_USER_ID })\n if (!foundUser.success) return foundUser\n const userData = foundUser.payload\n const userRole = userData.role\n const userIsAdminOrRoot = userRole === UserRole.ADMIN || userRole === UserRole.ROOT\n const payload: Omit<Payload, 'exp'> = { userId, isAdmin: userIsAdminOrRoot, refreshCount }\n const options: jwt.SignOptions = {\n expiresIn: userIsAdminOrRoot\n ? env.ACCESS_TOKEN_EXPIRATION_SECONDS_ADMIN\n : env.ACCESS_TOKEN_EXPIRATION_SECONDS\n }\n let token: string\n try {\n token = jwt.sign(payload, env.JWT_SECRET, options)\n } catch (err) {\n logError(\n LogCategory.USER_ACCESS_TOKEN_GENERATION,\n 'Failed to generate access token',\n { error: unknownToString(err) }\n )\n return makeFailureOutcome(\n Codes.USER_ACCESS_TOKEN_GENERATION_FAILED,\n 'Failed to generate access token',\n unknownToString(err)\n )\n }\n const inserted = await insertOne<IUserAuthToken>(\n UserAuthTokenModel, {\n userId: new MongooseTypes.ObjectId(userId),\n value: token,\n issuedOn: new Date()\n },\n { initiatorId: env.ROOT_USER_ID }\n )\n if (!inserted.success) return inserted\n return Outcome.makeSuccess(token)\n}\n\nexport async function generateRefreshToken (\n userId: string | MongooseTypes.ObjectId,\n refreshCount: number\n) {\n userId = userId.toString()\n const foundUser = await findOne<IBaseUser>(BaseUserModel, { _id: userId }, { initiatorId: env.ROOT_USER_ID })\n if (!foundUser.success) return foundUser\n const userData = foundUser.payload\n const userRole = userData.role\n const userIsAdminOrRoot = userRole === UserRole.ADMIN || userRole === UserRole.ROOT\n const payload: Omit<Payload, 'exp'> = { userId, isAdmin: userIsAdminOrRoot, refreshCount }\n const options: jwt.SignOptions = {\n expiresIn: userIsAdminOrRoot\n ? env.REFRESH_TOKEN_EXPIRATION_SECONDS_ADMIN\n : env.REFRESH_TOKEN_EXPIRATION_SECONDS\n }\n let token: string\n try {\n token = jwt.sign(payload, env.JWT_SECRET, options)\n } catch (err) {\n logError(\n LogCategory.USER_REFRESH_TOKEN_GENERATION,\n 'Failed to generate refresh token',\n { error: unknownToString(err) }\n )\n return makeFailureOutcome(\n Codes.USER_REFRESH_TOKEN_GENERATION_FAILED,\n 'Failed to generate access token',\n unknownToString(err)\n )\n }\n const inserted = await insertOne<IUserAuthToken>(\n UserAuthTokenModel, {\n userId: new MongooseTypes.ObjectId(userId),\n value: token,\n issuedOn: new Date()\n },\n { initiatorId: env.ROOT_USER_ID }\n )\n if (!inserted.success) return inserted\n return Outcome.makeSuccess(token)\n}\n\nexport const accessTokenHeader = 'X-Access-Token'\n\nexport function attachAccessTokenToRes (\n setHeader: Response['setHeader'],\n token: string\n) {\n return setHeader(accessTokenHeader, `Bearer ${token}`)\n}\n\nexport function attachRefreshTokenToRes (\n setCookie: Response['cookie'],\n token: string,\n admin: boolean\n) {\n const expiresIn = admin\n ? env.REFRESH_TOKEN_EXPIRATION_SECONDS_ADMIN\n : env.REFRESH_TOKEN_EXPIRATION_SECONDS\n return setCookie('refreshToken', token, {\n httpOnly: true,\n secure: env.ALLOW_HTTP === 'false',\n sameSite: 'none',\n expires: new Date(Date.now() + expiresIn * 1000)\n })\n}\n\nexport async function revokeUserTokens (\n userId: string | MongooseTypes.ObjectId,\n tokens: string[]\n) {\n userId = userId.toString()\n const toRevoke = tokens\n if (toRevoke.length === 0) return Outcome.makeSuccess(true)\n const deletionAttempt = await deleteMany<IUserAuthToken>(UserAuthTokenModel, { userId, value: { $in: toRevoke } }, { initiatorId: env.ROOT_USER_ID })\n if (!deletionAttempt.success) {\n const { code } = deletionAttempt.error\n if (code === Codes.DB_NO_DOCUMENT_MATCHES_FILTER) {\n logError(\n LogCategory.USER_TOKENS_REVOCATION,\n 'No tokens to revoke',\n { userId, tokens, error: deletionAttempt.error }\n )\n return deletionAttempt\n } else {\n logError(\n LogCategory.USER_TOKENS_REVOCATION,\n 'Failed to revoke tokens',\n { userId, tokens, error: deletionAttempt.error }\n )\n return deletionAttempt\n }\n }\n const now = new Date()\n const insertionAttempt = await insertMany<IUserRevokedAuthToken>(UserRevokedAuthTokenModel, toRevoke.map(token => ({\n value: token,\n userId: new MongooseTypes.ObjectId(userId),\n revokedOn: now\n })), { initiatorId: env.ROOT_USER_ID })\n if (!insertionAttempt.success) {\n logError(\n LogCategory.USER_TOKENS_REVOCATION,\n 'Tokens deleted but not inserted in revoked tokens collection',\n { userId, tokens, error: insertionAttempt.error }\n )\n return insertionAttempt\n }\n if (insertionAttempt.payload.insertedCount !== toRevoke.length) {\n logError(\n LogCategory.USER_TOKENS_REVOCATION,\n 'THIS SHOULD NOT HAPPEN! Number of tokens deleted and inserted in revoked tokens collection do not match', {\n userId,\n tokens,\n deletedCount: deletionAttempt.payload.deletedCount,\n inserted: insertionAttempt.payload\n })\n return makeFailureOutcome(\n Codes.DB_ERROR,\n 'Failed to revoke all tokens'\n )\n }\n return Outcome.makeSuccess(true)\n}\n\nexport async function revokeAllUserAuthTokens (\n userId: string | MongooseTypes.ObjectId,\n additionalTokens: string[] = []\n) {\n userId = userId.toString()\n const userAuthTokensLookup = await findMany<IUserAuthToken>(\n UserAuthTokenModel,\n { userId },\n { initiatorId: env.ROOT_USER_ID },\n { limit: 1000, sort: { issuedOn: -1 } }\n )\n if (userAuthTokensLookup.success\n && userAuthTokensLookup.payload.found.length === 0) return Outcome.makeSuccess(true)\n if (!userAuthTokensLookup.success) {\n if (userAuthTokensLookup.error.code === Codes.DB_NO_DOCUMENT_MATCHES_FILTER) return Outcome.makeSuccess(true)\n logError(\n LogCategory.USER_TOKENS_REVOCATION,\n 'Failed to retrieve user auth tokens, before revoking',\n { userId, error: userAuthTokensLookup.error }\n )\n return userAuthTokensLookup\n }\n const userAuthTokens = userAuthTokensLookup.payload.found\n const toRevoke = userAuthTokens.map(token => token.value)\n return await revokeUserTokens(userId, [...toRevoke, ...additionalTokens])\n}\n\n/* * * * * * * * * * * * * * * * * * * * * * *\n *\n * Auth middleware\n *\n * * * * * * * * * * * * * * * * * * * * * * */\n\nexport async function authenticateMiddleware (\n req: Request,\n res: Response,\n next: NextFunction\n) {\n const authHeader = req.headers.authorization\n if (authHeader === undefined || !authHeader.startsWith('Bearer ')) return next()\n const token = authHeader.split(' ')[1]\n if (token === undefined) return next()\n let decoded: Payload\n try {\n const verified = jwt.verify(token, env.JWT_SECRET)\n const validated = isValidPayload(verified)\n if (!validated) throw new Error(`Invalid access token payload: ${token}`)\n decoded = verified\n } catch (err) {\n logError(\n LogCategory.USER_ACCESS_TOKEN_VERIFICATION,\n 'Failed to verify access token',\n { error: unknownToString(err) }\n )\n return next()\n }\n const now = Math.floor(Date.now() / 1000)\n const { userId, isAdmin, exp, refreshCount } = decoded\n const accessThreshold = isAdmin\n ? env.ACCESS_TOKEN_RENEWAL_THRESHOLD_SECONDS_ADMIN\n : env.ACCESS_TOKEN_RENEWAL_THRESHOLD_SECONDS\n const accessTokenMaxRefreshCount = isAdmin\n ? env.ACCESS_TOKEN_MAX_REFRESH_COUNT_ADMIN\n : env.ACCESS_TOKEN_MAX_REFRESH_COUNT\n const accessTokenAlmostStale = exp - now < accessThreshold\n const accessTokenCanRenew = refreshCount < accessTokenMaxRefreshCount\n const accessTokenShouldRenew = accessTokenAlmostStale && accessTokenCanRenew\n if (accessTokenShouldRenew) {\n const foundRevokedToken = await findOne<IUserRevokedAuthToken>(\n UserRevokedAuthTokenModel,\n { value: token },\n { initiatorId: env.ROOT_USER_ID }\n )\n if (foundRevokedToken.success) return next()\n const newToken = await generateAccessToken(userId, refreshCount + 1)\n if (!newToken.success) return next()\n let decodedNewToken: Payload\n try {\n const verified = jwt.verify(newToken.payload, env.JWT_SECRET)\n const validated = isValidPayload(verified)\n if (!validated) throw new Error(`Invalid access token payload: ${newToken.payload}`)\n decodedNewToken = verified\n } catch (err) {\n logError(\n LogCategory.USER_ACCESS_TOKEN_VERIFICATION,\n 'Failed to verify access token',\n { error: unknownToString(err) }\n )\n return next()\n }\n attachAccessTokenToRes(res.setHeader, newToken.payload) /* Cf. /src/global.d.ts */\n res.locals.accessTokenSigned = newToken.payload\n res.locals.accessTokenPayload = decodedNewToken\n return next()\n } else {\n res.locals.accessTokenSigned = token\n res.locals.accessTokenPayload = decoded\n return next()\n }\n}\n\n/* * * * * * * * * * * * * * * * * * * * * * *\n *\n * Auth utilities\n *\n * * * * * * * * * * * * * * * * * * * * * * */\n\nexport async function checkAccessToken (\n accessTokenSigned: string | undefined,\n accessTokenPayload: Payload | undefined\n): Promise<Outcome.Either<\n { accessTokenSigned: string, accessTokenPayload: Payload },\n ErrorData<Codes.USER_NOT_AUTHENTICATED | Codes.USER_NOT_AUTHORIZED | Codes.USER_DOES_NOT_EXIST>\n>> {\n if (accessTokenSigned === undefined) return makeFailureOutcome(Codes.USER_NOT_AUTHENTICATED, 'Access token is missing')\n if (accessTokenPayload === undefined) return makeFailureOutcome(Codes.USER_NOT_AUTHENTICATED, 'Access token is invalid')\n const { exp } = accessTokenPayload\n if (exp === undefined) return makeFailureOutcome(Codes.USER_NOT_AUTHENTICATED, 'Access token has expired')\n const now = Math.floor(Date.now() / 1000)\n if (exp <= now) return makeFailureOutcome(Codes.USER_NOT_AUTHENTICATED, 'Access token has expired')\n if (accessTokenSigned === undefined) return makeFailureOutcome(Codes.USER_NOT_AUTHENTICATED, 'User is not authenticated')\n const foundRevokedToken = await findOne<IUserRevokedAuthToken>(UserRevokedAuthTokenModel, { value: accessTokenSigned }, { initiatorId: env.ROOT_USER_ID })\n if (foundRevokedToken.success) return makeFailureOutcome(Codes.USER_NOT_AUTHENTICATED, 'Access token has been revoked')\n return Outcome.makeSuccess({ accessTokenSigned, accessTokenPayload })\n}\n\nexport async function fetchUser (userId: string) {\n const userLookup = await findOne<IBaseUser>(BaseUserModel, { _id: userId }, { initiatorId: env.ROOT_USER_ID })\n if (!userLookup.success) return makeFailureOutcome(Codes.USER_DOES_NOT_EXIST, 'User does not exist')\n const userData = userLookup.payload\n const discriminatedUser = discriminateUser(userData)\n if (discriminatedUser === null) return makeFailureOutcome(Codes.USER_DOES_NOT_EXIST, 'User does not exist')\n return Outcome.makeSuccess(discriminatedUser)\n}\n\n/* * * * * * * * * * * * * * * * * * * * * * *\n *\n * Workers\n *\n * * * * * * * * * * * * * * * * * * * * * * */\nexport const allow: Allower = (options = {}) => async (hooks) => {\n const {\n roles,\n statuses,\n badges,\n verified\n } = options\n const { user, accessTokenSigned, accessTokenPayload } = hooks\n\n // Wildcard case\n if (\n roles === undefined\n && statuses === undefined\n && badges === undefined\n && verified === undefined\n ) return jsonResponse(200 as const, {\n user,\n accessTokenSigned,\n accessTokenPayload\n })\n const discriminatedUser = discriminateUser(user)\n if (discriminatedUser === null) return errorResponse(401, Codes.USER_DOES_NOT_EXIST, 'Invalid user object')\n \n // Role check\n const expectRole = roles !== undefined\n const hasRole = expectRole && roles.includes(discriminatedUser.role)\n if (expectRole && !hasRole) return errorResponse(401, Codes.USER_NOT_AUTHENTICATED, 'User is missing the required role')\n\n // Status check\n const expectStatus = statuses !== undefined\n const hasStatus = expectStatus && statuses.includes(discriminatedUser.status)\n if (expectStatus && !hasStatus) return errorResponse(401, Codes.USER_NOT_AUTHORIZED, 'User is missing the required status')\n\n // Badge check\n const expectBadge = badges !== undefined\n const hasBadge = expectBadge && discriminatedUser.badges.some(userBadge => badges.includes(userBadge))\n if (expectBadge && !hasBadge) return errorResponse(401, Codes.USER_NOT_AUTHORIZED, 'User is missing the required badge')\n \n return jsonResponse(200 as const, {\n user,\n accessTokenSigned,\n accessTokenPayload\n })\n}\n\n/* * * * * * * * * * * * * * * * * * * * * * *\n *\n * EMAIL - VALIDATION TOKEN EMAIL\n *\n * * * * * * * * * * * * * * * * * * * * * * */\n\nexport async function createAndSendUserEmailValidationToken (\n email: string,\n username: string\n) {\n const tokenLifetimeMinutes = env.USER_EMAIL_VALIDATION_TOKEN_LIFETIME_MINUTES\n const tokenLifetimeMs = Duration.minutes(tokenLifetimeMinutes).toMilliseconds()\n const tokenExpiresOnTimestamp = Date.now() + tokenLifetimeMs\n const tokenExpiresOn = new Date(tokenExpiresOnTimestamp)\n const tokenValue = randomUUID()\n const tokenDocument: PartialPOJOInput<IUserEmailValidationToken> = {\n email,\n value: tokenValue,\n expiresOn: tokenExpiresOn,\n }\n const tokenInserted = await insertOne<IUserEmailValidationToken>(UserEmailValidationTokenModel, tokenDocument, { initiatorId: env.ROOT_USER_ID })\n if (!tokenInserted.success) {\n logError(LogCategory.USER_EMAIL_VERIFICATION, 'Failed to insert user email validation token in db', {\n email,\n username,\n error: tokenInserted.error\n })\n }\n const emailBody = `Hey ${username}!`\n + `<br />Here is your account verification code: ${tokenValue}.`\n + `<br />This code is valid for ${env.USER_EMAIL_VALIDATION_TOKEN_LIFETIME_MINUTES} minutes.`\n const senderEmail = env.EMAILER_TYPE === 'mailersend' ? env.EMAILER_MAILERSEND_EMAILER_EMAIL : env.EMAILER_GMAIL_EMAIL\n const senderName = env.EMAILER_TYPE === 'mailersend' ? env.EMAILER_MAILERSEND_EMAILER_NAME : ''\n const sent = await Email.send(\n senderEmail,\n senderName,\n email,\n username,\n 'Validate your email',\n emailBody\n )\n return sent\n}\n\nexport async function createAndSendUserPasswordRenewalToken (email: string, username: string) {\n const tokenLifetimeMinutes = env.USER_PASSWORD_RENEWAL_TOKEN_LIFETIME_MINUTES\n const tokenLifetimeMs = Duration.minutes(tokenLifetimeMinutes).toMilliseconds()\n const tokenExpiresOnTimestamp = Date.now() + tokenLifetimeMs\n const tokenExpiresOn = new Date(tokenExpiresOnTimestamp)\n const tokenValue = randomUUID()\n const tokenDocument: PartialPOJOInput<IUserPasswordRenewalToken> = {\n email,\n value: tokenValue,\n expiresOn: tokenExpiresOn,\n }\n const tokenInserted = await insertOne<IUserPasswordRenewalToken>(UserPasswordRenewalTokenModel, tokenDocument, { initiatorId: env.ROOT_USER_ID })\n if (!tokenInserted.success) {\n logError(LogCategory.USER_PASSWORD_RENEWAL, 'Failed to insert user password renewal token in db', {\n email,\n username,\n error: tokenInserted.error\n })\n }\n const emailBody = `Hey ${username}!`\n + `<br />Here is your password renewal code: ${tokenValue}.`\n + `<br />This code is valid for ${env.USER_PASSWORD_RENEWAL_TOKEN_LIFETIME_MINUTES} minutes.`\n const senderEmail = env.EMAILER_TYPE === 'mailersend' ? env.EMAILER_MAILERSEND_EMAILER_EMAIL : env.EMAILER_GMAIL_EMAIL\n const senderName = env.EMAILER_TYPE === 'mailersend' ? env.EMAILER_MAILERSEND_EMAILER_NAME : ''\n const sent = await Email.send(\n senderEmail,\n senderName,\n email,\n username,\n 'Reset your password',\n emailBody\n )\n return sent\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport { Outcome } from '@design-edito/tools/agnostic/misc/outcome/index.js'\nimport {\n connect as mongooseConnect,\n connections as mongooseConnections,\n disconnect as mongooseDisconnect,\n} from 'mongoose'\nimport env from '../env/index.js'\nimport { makeFailureOutcome } from '../errors/index.js'\nimport { Codes } from '../types/errors/index.js'\nimport {\n logError,\n logInfo,\n logWarning\n} from '../logs/index.js'\nimport { Category as LogCategory } from '../types/logs/index.js'\nimport {\n DeleteMany,\n DeleteOne,\n FindMany,\n FindOne,\n InsertMany,\n InsertOne,\n UpdateMany,\n UpdateOne\n} from '../types/database/index.js'\nimport { wait } from '@design-edito/tools/agnostic/time/wait/index.js'\nimport { Duration } from '@design-edito/tools/agnostic/time/duration/index.js'\n\n/* * * * * * * * * * * * * * * * * *\n *\n * PING\n *\n * * * * * * * * * * * * * * * * * */\n\nexport async function ping (): Promise<Outcome.Either<number, string>> {\n const conn = mongooseConnections[0]\n if (conn === undefined\n || conn.readyState !== 1\n || conn.db === undefined) {\n logError(LogCategory.DB, 'MongoDB connection is not ready', { readyState: conn?.readyState })\n return Outcome.makeFailure('MongoDB connection not ready')\n }\n try {\n const start = process.hrtime.bigint()\n await conn.db.admin().ping()\n const end = process.hrtime.bigint()\n const durationMs = Number(end - start) / 1_000_000 // ns \u2192 ms\n return Outcome.makeSuccess(durationMs)\n } catch (err) {\n logError(LogCategory.DB, 'MongoDB ping failed', { error: unknownToString(err) })\n return Outcome.makeFailure(unknownToString(err))\n }\n}\n\n/* * * * * * * * * * * * * * * * * *\n *\n * CONNECTION / DISCONNECTION\n *\n * * * * * * * * * * * * * * * * * */\n\nlet _connectionString = ''\n_connectionString = `${env.DB_PROTOCOL}://`\n_connectionString += `${env.DB_USR}:${env.DB_PWD}@${env.DB_HOST}`\nif (env.DB_PORT !== undefined && env.DB_PORT !== '') { _connectionString += `:${env.DB_PORT}` }\nif (env.DB_NAME !== undefined && env.DB_NAME !== '') { _connectionString += `/${env.DB_NAME}` }\nif (env.DB_OPT !== undefined && env.DB_OPT !== '') { _connectionString += `?${env.DB_OPT}` }\n\nexport const connectionString = _connectionString\n\nexport async function connect () {\n try {\n await mongooseConnect(connectionString)\n logInfo(LogCategory.DB, 'Mongoose connected')\n return Outcome.makeSuccess(null)\n } catch (err) {\n const errStr = unknownToString(err)\n logError(LogCategory.DB, 'Failed to connect to MongoDB', { error: errStr })\n return Outcome.makeFailure(errStr)\n }\n}\n\nexport async function connectWithRetries (\n retries = 3,\n delayMs = Duration.seconds(1).toMs()\n) {\n for (let i = 0; i < retries; i++) {\n const result = await connect()\n if (result.success) return result\n logInfo(LogCategory.DB, `Retrying (${i + 1}/${retries}) in ${delayMs / 1000} seconds...`)\n await wait(delayMs)\n }\n return Outcome.makeFailure('Failed to connect to MongoDB')\n}\n\nexport async function disconnect() {\n try {\n await mongooseDisconnect()\n logInfo(LogCategory.DB, 'Mongoose disconnected')\n } catch (err) {\n logError(LogCategory.DB, 'Failed to disconnect from MongoDB', { error: unknownToString(err) })\n }\n}\n\n/* * * * * * * * * * * * * * * * * *\n *\n * OPERATIONS\n *\n * * * * * * * * * * * * * * * * * */\n\nexport const insertOne: InsertOne = async (model, data, context) => {\n try {\n const doc = new model(data)\n doc.$locals = { context }\n const saved = await doc.save()\n return Outcome.makeSuccess(saved)\n } catch (err) {\n const strErr = unknownToString(err)\n logError(LogCategory.DB, 'Failed to insert one', {\n error: strErr,\n modelName: model.modelName,\n context,\n data\n })\n return makeFailureOutcome(Codes.DB_ERROR, strErr)\n }\n}\n\nexport const insertMany: InsertMany = async ( model, data, context) => {\n try {\n const docs = data.map(d => {\n const doc = new model(d)\n doc.$locals = { context }\n return doc\n })\n const saved = await model.insertMany(docs)\n return Outcome.makeSuccess({\n inserted: saved,\n insertedCount: saved.length\n }) // [WIP] should return count only ?\n } catch (err) {\n const strErr = unknownToString(err)\n logError(LogCategory.DB, 'Failed to insert many', {\n error: strErr,\n modelName: model.modelName,\n context,\n data\n })\n return makeFailureOutcome(Codes.DB_ERROR, strErr)\n }\n}\n\nexport const findOne: FindOne = async (model, filter, context) => {\n try {\n const found = await model\n .findOne(filter)\n .setOptions({ $locals: { context } })\n .exec()\n if (found === null) {\n logWarning(LogCategory.DB, 'Empty findOne result', {\n modelName: model.modelName,\n context,\n filter\n })\n return makeFailureOutcome(Codes.DB_NO_DOCUMENT_MATCHES_FILTER, model.modelName, filter)\n }\n return Outcome.makeSuccess(found)\n } catch (err) {\n logError(LogCategory.DB, 'Failed to find one', {\n error: unknownToString(err),\n modelName: model.modelName,\n context,\n filter\n })\n return makeFailureOutcome(Codes.DB_ERROR, unknownToString(err))\n }\n}\n\nexport const findMany: FindMany = async (model, filter, context, options) => {\n try {\n const {\n limit = Infinity,\n skip = 0,\n sort = {}\n } = options ?? {}\n if (limit <= 0) return makeFailureOutcome(Codes.DB_ERROR, 'Limit must be greater than 0')\n if (skip < 0) return makeFailureOutcome(Codes.DB_ERROR, 'Skip must be greater than or equal to 0')\n const [count, found] = await Promise.all([\n model.countDocuments(filter),\n model.find(filter)\n .sort(sort)\n .skip(skip)\n .limit(limit)\n .setOptions({ $locals: { context } })\n .exec()\n ])\n if (found.length === 0) {\n logWarning(LogCategory.DB, 'Empty findMany result', {\n modelName: model.modelName,\n context,\n filter\n })\n return makeFailureOutcome(Codes.DB_NO_DOCUMENT_MATCHES_FILTER, model.modelName, filter)\n }\n const hasPrev = skip > 0\n const hasNext = count > skip + found.length\n const prevFunc = !hasPrev\n ? null\n : async () => {\n const newSkip = Math.max(skip - limit, 0)\n const newLimit = newSkip === 0 ? skip : limit\n return await findMany(\n model,\n filter,\n context, {\n ...options,\n skip: newSkip,\n limit: newLimit\n })\n }\n const nextFunc = !hasNext\n ? null\n : async () => await findMany(\n model,\n filter,\n context, {\n ...options,\n skip: skip + limit\n })\n return Outcome.makeSuccess({\n found: found,\n foundCount: found.length,\n totalCount: count,\n next: nextFunc,\n prev: prevFunc,\n })\n } catch (err) {\n logError(LogCategory.DB, 'Failed to find many', {\n error: unknownToString(err),\n modelName: model.modelName,\n context,\n filter\n })\n return makeFailureOutcome(Codes.DB_ERROR, unknownToString(err))\n }\n}\n\nexport const updateOne: UpdateOne = async (model, filter, update, context) => {\n try {\n const updated = await model\n .findOneAndUpdate(filter, update, { new: true })\n .setOptions({ $locals: { context } })\n .exec()\n if (updated === null) {\n logWarning(LogCategory.DB, 'Empty updateOne result', {\n modelName: model.modelName,\n context,\n filter,\n update\n })\n return makeFailureOutcome(Codes.DB_NO_DOCUMENT_MATCHES_FILTER, model.modelName, filter)\n }\n return Outcome.makeSuccess(updated)\n } catch (err) {\n logError(LogCategory.DB, 'Failed to update one', {\n error: unknownToString(err),\n modelName: model.modelName,\n context,\n filter,\n update\n })\n return makeFailureOutcome(Codes.DB_ERROR, unknownToString(err))\n }\n}\n\nexport const updateMany: UpdateMany = async (model, filter, update, context) => {\n try {\n const updated = await model\n .updateMany(filter, update)\n .setOptions({ $locals: { context } })\n .exec()\n if (updated.modifiedCount === 0) {\n logWarning(LogCategory.DB, 'Empty updateMany result', {\n modelName: model.modelName,\n context,\n filter,\n update\n })\n return makeFailureOutcome(Codes.DB_NO_DOCUMENT_MATCHES_FILTER, model.modelName, filter)\n }\n return Outcome.makeSuccess({\n updatedCount: updated.modifiedCount\n })\n } catch (err) {\n logError(LogCategory.DB, 'Failed to update many', {\n error: unknownToString(err),\n modelName: model.modelName,\n context,\n filter,\n update\n })\n return makeFailureOutcome(Codes.DB_ERROR, unknownToString(err))\n }\n}\n\nexport const deleteOne: DeleteOne = async (model, filter, context) => {\n try {\n const deleted = await model\n .findOneAndDelete(filter)\n .setOptions({ $locals: { context } })\n .exec()\n if (deleted === null) {\n logWarning(LogCategory.DB, 'Empty deleteOne result', {\n modelName: model.modelName,\n context,\n filter\n })\n return makeFailureOutcome(Codes.DB_NO_DOCUMENT_MATCHES_FILTER, model.modelName, filter)\n }\n return Outcome.makeSuccess(deleted)\n } catch (err) {\n logError(LogCategory.DB, 'Failed to delete one', {\n error: unknownToString(err),\n modelName: model.modelName,\n context,\n filter\n })\n return makeFailureOutcome(Codes.DB_ERROR, unknownToString(err))\n }\n}\n\nexport const deleteMany: DeleteMany = async (model, filter, context) => {\n try {\n const deleted = await model\n .deleteMany(filter)\n .setOptions({ $locals: { context } })\n .exec()\n if (deleted.deletedCount === 0) {\n logWarning(LogCategory.DB, 'Empty deleteMany result', {\n modelName: model.modelName,\n context,\n filter\n })\n return makeFailureOutcome(Codes.DB_NO_DOCUMENT_MATCHES_FILTER, model.modelName, filter)\n }\n return Outcome.makeSuccess({ deletedCount: deleted.deletedCount })\n } catch (err) {\n logError(LogCategory.DB, 'Failed to delete many', {\n error: unknownToString(err),\n modelName: model.modelName,\n context,\n filter\n })\n return makeFailureOutcome(Codes.DB_ERROR, unknownToString(err))\n }\n}\n", "import dotenv from 'dotenv'\nimport { z } from 'zod'\nimport { Env } from '../types/env/index.js'\n\ndotenv.config()\n\n// Helper to split lists\nconst splitList = (val: string | undefined, separator: string): string[] => (val ?? '')\n .split(separator)\n .map((e) => e.trim())\n .filter((e) => e !== '')\n\n// Base schema\nconst baseSchema = z.object({\n // App metadata\n APP_LABEL: z.string().optional(),\n ALLOW_MAIN_ADMIN_USER_EMAIL_NOTIFICATIONS: z.enum(['true', 'false']),\n \n // HTTP\n ALLOW_HTTP: z.enum(['true', 'false']),\n PORT: z.string().min(1),\n CORS_WHITELIST: z.string().transform(val => splitList(val, ',')).refine(arr => arr.length > 0, { message: 'cannot be empty' }),\n\n // DB\n DB_PROTOCOL: z.enum(['mongodb', 'mongodb+srv']),\n DB_HOST: z.string().min(1),\n DB_PORT: z.string().optional(),\n DB_NAME: z.string().optional(),\n DB_USR: z.string().min(1),\n DB_PWD: z.string().min(1),\n DB_OPT: z.string().min(1),\n DB_RESERVED_AGENDA_JOBS_COLLECTION_NAME: z.string().min(1),\n\n // Root & Admin Users\n ROOT_USER_ID: z.string().min(24),\n ROOT_USER_NAME: z.string().min(1),\n ROOT_USER_EMAIL: z.string().email(),\n ROOT_USER_PWD: z.string().min(1),\n\n MAIN_ADMIN_USER_ID: z.string().min(24),\n MAIN_ADMIN_USER_NAME: z.string().min(1),\n MAIN_ADMIN_USER_EMAIL: z.string().email(),\n MAIN_ADMIN_USER_PWD: z.string().min(1),\n\n // Auth\n USER_EMAIL_VALIDATION_TOKEN_LIFETIME_MINUTES: z.string().transform(v => parseInt(v)).refine(n => !isNaN(n), { message: 'must be a number' }),\n USER_PASSWORD_RENEWAL_TOKEN_LIFETIME_MINUTES: z.string().transform(v => parseInt(v)).refine(n => !isNaN(n), { message: 'must be a number' }),\n\n JWT_SECRET: z.string().min(1),\n\n ACCESS_TOKEN_EXPIRATION_SECONDS: z.string().transform(v => parseFloat(v)).refine(n => !isNaN(n), { message: 'must be a number' }),\n ACCESS_TOKEN_RENEWAL_THRESHOLD_SECONDS: z.string().transform(v => parseFloat(v)).refine(n => !isNaN(n), { message: 'must be a number' }),\n REFRESH_TOKEN_EXPIRATION_SECONDS: z.string().transform(v => parseFloat(v)).refine(n => !isNaN(n), { message: 'must be a number' }),\n ACCESS_TOKEN_MAX_REFRESH_COUNT: z.string().transform(v => parseFloat(v)).refine(n => !isNaN(n), { message: 'must be a number' }),\n REFRESH_TOKEN_MAX_REFRESH_COUNT: z.string().transform(v => parseFloat(v)).refine(n => !isNaN(n), { message: 'must be a number' }),\n\n ACCESS_TOKEN_EXPIRATION_SECONDS_ADMIN: z.string().transform(v => parseFloat(v)).refine(n => !isNaN(n), { message: 'must be a number' }),\n ACCESS_TOKEN_RENEWAL_THRESHOLD_SECONDS_ADMIN: z.string().transform(v => parseFloat(v)).refine(n => !isNaN(n), { message: 'must be a number' }),\n REFRESH_TOKEN_EXPIRATION_SECONDS_ADMIN: z.string().transform(v => parseFloat(v)).refine(n => !isNaN(n), { message: 'must be a number' }),\n ACCESS_TOKEN_MAX_REFRESH_COUNT_ADMIN: z.string().transform(v => parseFloat(v)).refine(n => !isNaN(n), { message: 'must be a number' }),\n REFRESH_TOKEN_MAX_REFRESH_COUNT_ADMIN: z.string().transform(v => parseFloat(v)).refine(n => !isNaN(n), { message: 'must be a number' }),\n\n // Temp\n TEMP_DIR_PREFIX: z.string().min(1),\n TEMP_DIR_MAX_MEBIBYTES_SIZE: z.string().transform(v => parseFloat(v)).refine(n => !isNaN(n), { message: 'must be a number' }),\n\n // CSRF\n CSRF_COOKIE_NAME: z.string().min(1),\n CSRF_TOKEN_HEADER: z.string().min(1),\n\n // User Uploads\n USER_UPLOAD_DAILY_LIMIT_MEBIBYTES: z.string().transform(v => parseInt(v)).refine(n => !isNaN(n), { message: 'must be a number' }),\n USER_UPLOAD_MONTHLY_LIMIT_MEBIBYTES: z.string().transform(v => parseInt(v)).refine(n => !isNaN(n), { message: 'must be a number' }),\n USER_UPLOAD_TOTAL_LIMIT_MEBIBYTES: z.string().transform(v => parseInt(v)).refine(n => !isNaN(n), { message: 'must be a number' }),\n USER_UPLOAD_ALLOWED_EXTENSIONS: z.string().transform(v => splitList(v, ',')).refine(arr => arr.length > 0, { message: 'cannot be empty' }),\n\n // ClamAV\n CLAMAV_PROTOCOL: z.enum(['http', 'https']),\n CLAMAV_HOST: z.string().min(1),\n CLAMAV_PORT: z.string().min(1).transform(v => parseInt(v)).refine(n => !isNaN(n), { message: 'must be a number' }).optional(),\n CLAMAV_AUTH_MODE: z.enum(['none', 'gcp']),\n\n // Build metadata\n ESBUILD_BUILT_ON: z.string()\n})\n\n// Emailer\nconst emailerSchema = z.discriminatedUnion('EMAILER_TYPE', [\n z.object({\n EMAILER_TYPE: z.literal('mailersend'),\n EMAILER_MAILERSEND_API_KEY: z.string().min(1),\n EMAILER_MAILERSEND_EMAILER_EMAIL: z.string().email(),\n EMAILER_MAILERSEND_EMAILER_NAME: z.string().min(1),\n }),\n z.object({\n EMAILER_TYPE: z.literal('gmail'),\n EMAILER_GMAIL_EMAIL: z.string().email(),\n EMAILER_GMAIL_NAME: z.string().min(1),\n EMAILER_GMAIL_PASSWORD: z.string().min(1),\n })\n])\n\n// Storage\nconst storageSchema = z.discriminatedUnion('FS_STORAGE_TYPE', [\n z.object({\n FS_STORAGE_TYPE: z.literal('gcs'),\n FS_STORAGE_GCS_BUCKET_NAME: z.string().min(1),\n FS_STORAGE_GCS_PROJECT_ID: z.string().min(1),\n FS_STORAGE_GCS_CLIENT_EMAIL: z.string().min(1),\n FS_STORAGE_GCS_PRIVATE_KEY: z.string().min(1).transform(v => v.replace(/\\\\n/gm, '\\n')),\n }),\n z.object({\n FS_STORAGE_TYPE: z.literal('aws'),\n FS_STORAGE_AWS_REGION: z.string().min(1),\n FS_STORAGE_AWS_ACCESS_KEY_ID: z.string().min(1),\n FS_STORAGE_AWS_SECRET_ACCESS_KEY: z.string().min(1),\n FS_STORAGE_AWS_BUCKET_NAME: z.string().min(1),\n }),\n z.object({\n FS_STORAGE_TYPE: z.literal('ftps'),\n FS_STORAGE_FTP_HOST: z.string().min(1),\n FS_STORAGE_FTP_PORT: z.string().min(1),\n FS_STORAGE_FTP_USER: z.string().min(1),\n FS_STORAGE_FTP_PASSWORD: z.string().min(1),\n }),\n z.object({\n FS_STORAGE_TYPE: z.literal('sftp'),\n FS_STORAGE_FTP_HOST: z.string().min(1),\n FS_STORAGE_FTP_PORT: z.string().min(1),\n FS_STORAGE_FTP_USER: z.string().min(1),\n FS_STORAGE_FTP_PASSWORD: z.string().min(1),\n }),\n])\n\nconst envSchema = baseSchema\n .and(emailerSchema)\n .and(storageSchema)\nconst parsed = envSchema.safeParse({\n ...process.env,\n ESBUILD_BUILT_ON: process.env.ESBUILD_BUILT_ON // This is set by esbuild at build time\n})\nif (!parsed.success) {\n console.error('\u274C Invalid environment configuration:\\n', parsed.error.format())\n process.exit(1)\n}\n\nconst env: Env = parsed.data\n\nexport default env", "import { Outcome } from '@design-edito/tools/agnostic/misc/outcome/index.js'\nimport {\n Codes,\n register,\n DetailsMaker,\n DetailsOf,\n ErrorData,\n MakeError,\n MakeFailureOutcome\n} from '../types/errors/index.js'\n\nexport const makeError: MakeError = <C extends Codes>(\n code: C,\n ...params: Parameters<DetailsMaker<C>>\n): ErrorData<C> => {\n const message = register[code].message\n const detailsMaker = register[code].detailsMaker as any\n const details = detailsMaker(...params as any[]) as DetailsOf<C>\n return { code, message, details }\n}\n\nexport const makeFailureOutcome: MakeFailureOutcome = <Code extends Codes>(\n code: Code,\n ...params: Parameters<DetailsMaker<Code>>\n) => Outcome.makeFailure(makeError(code, ...params))\n", "import type { Outcome } from '@design-edito/tools/agnostic/misc/outcome/index.js'\n\nexport enum Codes {\n // SSL\n HTTP_FORBIDDEN = 'http-forbidden',\n\n // UNKNOWN\n UNKNOWN_ERROR = 'unknown-error',\n\n // DATABASE\n DB_ERROR = 'db-error',\n DB_NO_DOCUMENT_MATCHES_FILTER = 'db-no-document-matches-filter',\n DB_RECURSION_LIMIT_REACHED = 'db-recursion-limit-reached',\n\n // FILE STREAM RESPONSE\n RESPONSE_STREAM_FAILED = 'response-stream-failed',\n\n // AUTH\n USER_NOT_AUTHENTICATED = 'user-not-authenticated',\n USER_NOT_AUTHORIZED = 'user-not-authorized',\n USER_DOES_NOT_EXIST = 'user-does-not-exist',\n USER_EMAIL_DOES_NOT_EXIST = 'user-email-does-not-exist',\n USERNAME_ALREADY_TAKEN = 'username-already-taken',\n EMAIL_ADDRESS_ALREADY_TAKEN = 'email-address-already-taken',\n USER_EMAIL_VERIFICATION_TOKEN_NOT_PROVIDED = 'user-email-verification-token-not-provided',\n USER_EMAIL_VERIFICATION_TOKEN_DOES_NOT_EXIST = 'user-email-verification-token-does-not-exist',\n USER_EMAIL_VERIFICATION_PROCESS_FAILED = 'user-email-verification-process-failed',\n USER_EMAIL_ALREADY_VERIFIED = 'user-email-already-verified',\n INVALID_CREDENTIALS = 'invalid-credentials',\n USER_PASSWORD_RENEWAL_TOKEN_DOES_NOT_EXIST = 'user-password-renewal-token-does-not-exist',\n USER_REFRESH_TOKEN_MISSING = 'user-refresh-token-missing',\n USER_REFRESH_TOKEN_REVOKED = 'user-refresh-token-revoked',\n USER_REFRESH_TOKEN_MALFORMED = 'user-refresh-token-malformed',\n USER_REFRESH_TOKEN_EXPIRED = 'user-refresh-token-expired',\n USER_TOKENS_REVOCATION_FAILED = 'user-tokens-revocation-failed',\n USER_ACCESS_TOKEN_GENERATION_FAILED = 'user-access-token-generation-failed',\n USER_REFRESH_TOKEN_GENERATION_FAILED = 'user-refresh-token-generation-failed',\n\n // CSRF\n INVALID_CSRF_TOKEN = 'invalid-csrf-token',\n\n // REQUESTS\n INVALID_REQUEST_BODY = 'invalid-request-body',\n INVALID_REQUEST_QUERY = 'invalid-request-query',\n INVALID_REQUEST_FILES = 'invalid-request-files',\n INVALID_RESPONSE_BODY = 'invalid-response-body',\n TOO_MANY_REQUESTS = 'too-many-requests',\n\n // STORAGE\n USER_DAILY_UPLOAD_QUOTA_EXCEEDED = 'user-daily-upload-quota-exceeded',\n USER_MONTHLY_UPLOAD_QUOTA_EXCEEDED = 'user-monthly-upload-quota-exceeded',\n USER_TOTAL_UPLOAD_QUOTA_EXCEEDED = 'user-total-upload-quota-exceeded',\n USER_UPLOAD_QUOTA_EXCEEDED = 'user-upload-quota-exceeded',\n UPLOAD_FAILED = 'upload-failed',\n FILE_PATH_CIRCULAR_PATTERN_DETECTED = 'file-path-circular-pattern-detected',\n FILE_NOT_FOUND = 'file-not-found',\n FILE_ALREADY_IN_TRASH = 'file-already-in-trash',\n FILE_NOT_IN_TRASH = 'file-not-in-trash',\n\n // FILES\n FILE_CORRUPTED = 'file-corrupted',\n FILE_INFECTED = 'file-infected',\n FILE_EMPTY = 'file-empty',\n FILE_TOO_LARGE = 'file-too-large',\n FILE_HASH_FAILED = 'file-hash-failed',\n FILE_SCANNER_NOT_REACHABLE = 'file-scanner-not-reachable',\n\n // IMAGE\n IMAGE_FORMAT_FAILED = 'image-format-failed',\n IMAGE_TRANSFORM_FAILED = 'image-transform-failed',\n\n // 404\n NOT_FOUND = 'not-found'\n}\n\nexport const register = {\n [Codes.HTTP_FORBIDDEN]: {\n message: 'The connection must be made over HTTPS',\n detailsMaker: () => undefined\n },\n\n [Codes.UNKNOWN_ERROR]: {\n message: 'An unknown error occured',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.DB_ERROR]: {\n message: 'The database returned an error',\n detailsMaker: ((dbError: string) => ({ dbError }))\n },\n\n [Codes.DB_NO_DOCUMENT_MATCHES_FILTER]: {\n message: 'No document matches the provided filter',\n detailsMaker: (\n collectionName: string,\n filter: any\n ) => {\n try {\n const stringified = JSON.stringify(filter)\n return {\n collection: collectionName,\n filter: stringified\n }\n } catch (err) {\n return {\n collection: collectionName,\n filter: 'Unable to stringify filter'\n }\n }\n }\n },\n\n [Codes.DB_RECURSION_LIMIT_REACHED]: {\n message: 'The recursion limit has been reached',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.RESPONSE_STREAM_FAILED]: {\n message: 'Failed to stream the file',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.USER_NOT_AUTHENTICATED]: {\n message: 'User must be authenticated',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.USER_NOT_AUTHORIZED]: {\n message: 'User has not sufficient permissions',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.USER_DOES_NOT_EXIST]: {\n message: 'Impossible to retreive user information',\n detailsMaker: (userId: string) => ({ userId })\n },\n\n [Codes.USER_EMAIL_DOES_NOT_EXIST]: {\n message: 'This email is not tied to any user account',\n detailsMaker: (email: string) => ({ email })\n },\n\n [Codes.USERNAME_ALREADY_TAKEN]: {\n message: 'This username is already taken',\n detailsMaker: (username: string) => ({ username })\n },\n\n [Codes.EMAIL_ADDRESS_ALREADY_TAKEN]: {\n message: 'This email address is already taken',\n detailsMaker: (email: string) => ({ email })\n },\n\n [Codes.USER_EMAIL_VERIFICATION_TOKEN_NOT_PROVIDED]: {\n message: 'This endpoint expects a token in the URL to process the validation',\n detailsMaker: () => undefined\n },\n\n [Codes.USER_EMAIL_VERIFICATION_TOKEN_DOES_NOT_EXIST]: {\n message: 'The email verification token provided does not exist',\n detailsMaker: () => undefined\n },\n\n [Codes.USER_EMAIL_VERIFICATION_PROCESS_FAILED]: {\n message: 'Something went wrong while updating the user verification status',\n detailsMaker: (details: string) => details\n },\n\n [Codes.USER_EMAIL_ALREADY_VERIFIED]: {\n message: 'This user already verified their email',\n detailsMaker: (email: string) => ({ email })\n },\n\n [Codes.INVALID_CREDENTIALS]: {\n message: 'The provided credentials are invalid',\n detailsMaker: () => undefined\n },\n\n [Codes.USER_PASSWORD_RENEWAL_TOKEN_DOES_NOT_EXIST]: {\n message: 'The password renewal token provided does not exist',\n detailsMaker: (email: string, token: string) => ({ email, token })\n },\n\n [Codes.USER_REFRESH_TOKEN_MISSING]: {\n message: 'No refresh token provided',\n detailsMaker: () => undefined\n },\n\n [Codes.USER_REFRESH_TOKEN_REVOKED]: {\n message: 'The refresh token provided has been revoked',\n detailsMaker: () => undefined\n },\n\n [Codes.USER_REFRESH_TOKEN_MALFORMED]: {\n message: 'The refresh token provided is malformed',\n detailsMaker: () => undefined\n },\n\n [Codes.USER_REFRESH_TOKEN_EXPIRED]: {\n message: 'The refresh token provided has expired',\n detailsMaker: () => undefined\n },\n\n [Codes.USER_TOKENS_REVOCATION_FAILED]: {\n message: 'The user tokens revocation failed',\n detailsMaker: (userId: string, tokens: string[]) => ({ userId, tokens })\n },\n\n [Codes.USER_ACCESS_TOKEN_GENERATION_FAILED]: {\n message: 'The user access token generation failed',\n detailsMaker: (userId: string, error?: string) => ({ userId, error })\n },\n\n [Codes.USER_REFRESH_TOKEN_GENERATION_FAILED]: {\n message: 'The user refresh token generation failed',\n detailsMaker: (userId: string, error?: string) => ({ userId, error })\n },\n\n [Codes.INVALID_CSRF_TOKEN]: {\n message: 'The CSRF token provided is invalid',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.INVALID_REQUEST_BODY]: {\n message: 'The request body provided could not be used for the operation',\n detailsMaker: ((body: any, error: string) => ({ body, error }))\n },\n\n [Codes.INVALID_REQUEST_QUERY]: {\n message: 'The request query provided could not be used for the operation',\n detailsMaker: ((query: any, error: string) => ({ query, error }))\n },\n\n [Codes.INVALID_REQUEST_FILES]: {\n message: 'The files provided in the request are not valid',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.INVALID_RESPONSE_BODY]: {\n message: 'Internal server error: The response body provided could was not allowoed to be sent',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.TOO_MANY_REQUESTS]: {\n message: 'Too many requests',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.USER_DAILY_UPLOAD_QUOTA_EXCEEDED]: {\n message: 'The user daily upload quota has been exceeded',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.USER_MONTHLY_UPLOAD_QUOTA_EXCEEDED]: {\n message: 'The user monthly upload quota has been exceeded',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.USER_TOTAL_UPLOAD_QUOTA_EXCEEDED]: {\n message: 'The user total upload quota has been exceeded',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.USER_UPLOAD_QUOTA_EXCEEDED]: {\n message: 'The user upload quota has been exceeded',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.UPLOAD_FAILED]: {\n message: 'The upload failed',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.FILE_PATH_CIRCULAR_PATTERN_DETECTED]: {\n message: 'The file path contains a circular pattern',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.FILE_NOT_FOUND]: {\n message: 'The file could not be found',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.FILE_ALREADY_IN_TRASH]: {\n message: 'The file is already in the trash',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.FILE_NOT_IN_TRASH]: {\n message: 'The file is not in the trash',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.FILE_CORRUPTED]: {\n message: 'The file has been damaged and cannot be read',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.FILE_INFECTED]: {\n message: 'The file is infected',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.FILE_EMPTY]: {\n message: 'The file is empty',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.FILE_TOO_LARGE]: {\n message: 'The file is too large',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.FILE_HASH_FAILED]: {\n message: 'The file hash failed',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.FILE_SCANNER_NOT_REACHABLE]: {\n message: 'The file scanner is not reachable',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.IMAGE_FORMAT_FAILED]: {\n message: 'The formatting of the image failed',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.IMAGE_TRANSFORM_FAILED]: {\n message: 'The image transform failed',\n detailsMaker: (details?: string) => details\n },\n\n [Codes.NOT_FOUND]: {\n message: 'The requested resource was not found',\n detailsMaker: (details?: string) => details\n }\n} as const\n\ntype Register = typeof register\nexport type MessageOf<C extends Codes> = Register[C]['message']\nexport type DetailsMaker<C extends Codes> = Register[C]['detailsMaker']\nexport type DetailsOf<C extends Codes> = ReturnType<DetailsMaker<C>>\nexport type ErrorData<C extends Codes> = {\n code: C,\n message: MessageOf<C>,\n details: DetailsOf<C>\n}\n\nexport type MakeError = <C extends Codes>(\n code: C,\n ...params: Parameters<DetailsMaker<C>>\n) => ErrorData<C>\n\nexport type MakeFailureOutcome = <Code extends Codes>(\n code: Code,\n ...params: Parameters<DetailsMaker<Code>>\n) => Outcome.Failure<ErrorData<Code>>\n\n", "import { hrtime } from 'node:process'\nimport chalk from 'chalk'\nimport { Request, Response, NextFunction } from 'express'\nimport {\n Level,\n Category,\n LogFatal,\n LogError,\n LogWarning,\n LogInfo,\n LogHttp,\n LogDebug\n} from '../types/logs/index.js'\n\nexport const log = (level: string, category: Category, message: string, details?: { [key: string]: unknown }) => {\n let coloredLevel: string\n if (level === Level.FATAL) coloredLevel = chalk.bold.hex('#ffffff').bgHex('#FF0000')(level.toUpperCase())\n else if (level === Level.ERROR) coloredLevel = chalk.bold.hex('#ff0000')(level.toUpperCase())\n else if (level === Level.WARN) coloredLevel = chalk.bold.hex('#ef6204')(level.toUpperCase())\n else if (level === Level.INFO) coloredLevel = chalk.bold.hex('#1d86e2')(level.toUpperCase())\n else if (level === Level.HTTP) coloredLevel = chalk.bold.hex('#afafaf')(level.toUpperCase())\n else coloredLevel = chalk.bold.magenta(level.toUpperCase())\n const logMsg = ''\n + ` ${new Date().toISOString()}`\n + ` ${coloredLevel}`\n + ` [${category}]`\n + ` ${message}`\n + ` ${details ? JSON.stringify(details) : ''}`\n console.log(logMsg)\n}\n\nexport const logFatal: LogFatal = (category, message, details): void => log(Level.FATAL, category, message, details)\nexport const logError: LogError = (category, message, details): void => log(Level.ERROR, category, message, details)\nexport const logWarning: LogWarning = (category, message, details): void => log(Level.WARN, category, message, details)\nexport const logInfo: LogInfo = (category, message, details): void => log(Level.INFO, category, message, details)\nexport const logHttp: LogHttp = (category, message, details): void => log(Level.HTTP, category, message, details)\nexport const logDebug: LogDebug = (category, message, details): void => log(Level.DEBUG, category, message, details)\n\nexport const httpLoggerMiddleware = (req: Request, res: Response, next: NextFunction): void => {\n const startNs = hrtime.bigint()\n const timestampMs = Date.now()\n res.on('finish', () => {\n const nowNs = hrtime.bigint()\n const durationNs = nowNs - startNs\n const durationMs = Number(durationNs / 1_000_000n)\n logHttp(Category.REQUEST, `${req.method} ${req.originalUrl}`, {\n statusCode: res.statusCode,\n ip: req.ip,\n userAgent: req.headers['user-agent'],\n userId: res.locals.initMeta?.userId ?? null,\n durationMs,\n timestampMs\n })\n })\n next()\n}\n", "import { Outcome } from '@design-edito/tools/agnostic/misc/outcome/index.js'\nimport { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport { Sender, Recipient, EmailParams, MailerSend } from 'mailersend'\nimport { APIResponse } from 'mailersend/lib/services/request.service.js'\nimport nodemailer, { SentMessageInfo } from 'nodemailer'\nimport env from '../env/index.js'\nimport { logError } from '../logs/index.js'\nimport { Category as LogCategory } from '../types/logs/index.js'\nimport { Send } from '../types/email/index.js'\n\nasync function sendWithMailerSend (\n apiKey: string,\n from: string,\n fromName: string,\n to: string,\n toName: string,\n subject: string,\n htmlBody: string\n): Promise<Outcome.Either<APIResponse, string>> {\n const mailerSend = new MailerSend({ apiKey })\n const sender = new Sender(from, fromName)\n const recipient = new Recipient(to, toName)\n const emailParams = new EmailParams()\n .setFrom(sender)\n .setTo([recipient])\n .setReplyTo(sender)\n .setSubject(subject)\n .setHtml(htmlBody)\n try {\n const sent = await mailerSend.email.send(emailParams)\n return Outcome.makeSuccess(sent)\n } catch (err) {\n logError(LogCategory.EMAIL, 'Failed to send email', {\n from,\n fromName,\n to,\n toName,\n subject,\n htmlBody,\n error: unknownToString(err)\n })\n return Outcome.makeFailure(unknownToString(err))\n }\n}\n\nasync function sendWithGmail (\n gmailEmail: string,\n gmailPassword: string,\n from: string,\n fromName: string,\n to: string,\n toName: string,\n subject: string,\n htmlBody: string\n): Promise<Outcome.Either<SentMessageInfo, string>> {\n try {\n const transporter = nodemailer.createTransport({\n service: 'gmail',\n auth: {\n user: gmailEmail,\n pass: gmailPassword\n }\n })\n\n // Verify the transporter configuration\n try {\n await transporter.verify()\n } catch (verifyErr) {\n logError(LogCategory.EMAIL, 'Gmail transporter verification failed', {\n gmailEmail,\n from,\n fromName,\n to,\n toName,\n subject,\n error: unknownToString(verifyErr)\n })\n const errorMsg = `Gmail transporter verification failed: ${unknownToString(verifyErr)}`\n return Outcome.makeFailure(errorMsg)\n }\n\n const info = await transporter.sendMail({\n from: `${fromName} <${from}>`,\n to: `${toName} <${to}>`,\n subject,\n html: htmlBody\n })\n\n // Check if the email was actually sent successfully\n // nodemailer's SentMessageInfo has various properties we can check\n if (info.rejected && info.rejected.length > 0) {\n const errorMsg = `Email was rejected by Gmail: ${info.rejected.join(', ')}`\n logError(LogCategory.EMAIL, 'Email rejected by Gmail', {\n from,\n fromName,\n to,\n toName,\n subject,\n rejected: info.rejected,\n response: info.response\n })\n return Outcome.makeFailure(errorMsg)\n }\n\n // Additional checks for potential issues\n if (info.pending && info.pending.length > 0) {\n logError(LogCategory.EMAIL, 'Email is pending (may indicate issues)', {\n from,\n fromName,\n to,\n toName,\n subject,\n pending: info.pending,\n response: info.response\n })\n // You might want to treat pending as a failure or success depending on your needs\n // For now, we'll log it but consider it a success\n }\n\n return Outcome.makeSuccess(info)\n } catch (err) {\n logError(LogCategory.EMAIL, 'Failed to send email with Gmail', {\n gmailEmail,\n from,\n fromName,\n to,\n toName,\n subject,\n htmlBody,\n error: unknownToString(err)\n })\n return Outcome.makeFailure(unknownToString(err))\n }\n}\n\nexport const send: Send = async (\n from,\n fromName,\n to,\n toName,\n subject,\n htmlBody\n) => {\n if (env.EMAILER_TYPE === 'mailersend') return sendWithMailerSend(\n env.EMAILER_MAILERSEND_API_KEY,\n from,\n fromName,\n to,\n toName,\n subject,\n htmlBody\n )\n else return sendWithGmail(\n env.EMAILER_GMAIL_EMAIL,\n env.EMAILER_GMAIL_PASSWORD,\n from,\n fromName,\n to,\n toName,\n subject,\n htmlBody\n )\n}\n\nexport function makeUserPasswordRenewalTokenBody (username: string, token: string): string {\n return `Hey ${username}! Here is your password renewal code: ${token}.`\n}\n", "import {\n Schema as MongooseSchema,\n model as mongooseModel,\n ValidatorProps as MongooseValidatorProps,\n} from 'mongoose'\nimport validator from 'validator'\nimport {\n IBaseUserCore,\n IGoogleUserCore,\n ILocalUserCore,\n IBaseUser,\n IGoogleUser,\n ILocalUser,\n UserRole,\n UserStatus,\n UserBadge,\n UserCollectionName,\n IBaseUserCoreSchema,\n ILocalUserCoreSchema,\n IGoogleUserCoreSchema,\n IBaseUserSchema,\n ILocalUserSchema,\n IBaseUserModel,\n ILocalUserModel,\n DiscriminateUser\n} from '../../../types/schema/index.js'\nimport { addHistoryToSchema } from '../../_history/index.js'\nimport { addMetaToSchema } from '../../_meta/index.js'\nimport { addPasswordToSchema } from '../../_password/index.js'\n\n// Collection name\nexport const collectionName: UserCollectionName = 'User'\n\n// Schemas\nconst emailValidator = (input: string) => validator.isEmail(input)\nconst usernameValidator = (input: string) => validator.isSlug(input.toLowerCase())\nconst emailValidationErrMessage = (props: MongooseValidatorProps) => `${props.value} is not a valid email address.`\nconst usernameValidationErrMessage = (props: MongooseValidatorProps) => `${props.value} is not a valid username. Alphanumeric, hyphens and underscore (non starting nor trailing, non consecutive) characters only.`\n\nexport const BaseUserCoreSchema: IBaseUserCoreSchema = new MongooseSchema<IBaseUserCore>({\n username: { type: String, required: true, unique: true, validate: {\n validator: usernameValidator,\n message: usernameValidationErrMessage\n }},\n role: { type: String, enum: Object.values(UserRole), required: true, default: UserRole.USER },\n status: { type: String, enum: Object.values(UserStatus), required: true, default: UserStatus.ACTIVE },\n badges: { type: [String], enum: Object.values(UserBadge), required: true, default: [] }\n}, { discriminatorKey: 'authType', _id: false })\n\nexport const LocalUserCoreSchema: ILocalUserCoreSchema = new MongooseSchema<ILocalUserCore>({\n email: { type: String, required: true, unique: true, validate: {\n validator: emailValidator,\n message: emailValidationErrMessage\n }},\n verified: { type: Boolean, required: true, default: false }\n})\n\nexport const GoogleUserCoreSchema: IGoogleUserCoreSchema = new MongooseSchema<IGoogleUserCore>({\n googleId: { type: String, required: true, unique: true },\n verified: {\n type: Boolean,\n required: true,\n default: true,\n immutable: true,\n validate: {\n validator: (v: boolean) => v === true,\n message: 'verified must always be true'\n }\n }\n})\n\nexport const BaseUserSchema: IBaseUserSchema = addMetaToSchema(addHistoryToSchema(BaseUserCoreSchema))\nexport const LocalUserSchema: ILocalUserSchema = addPasswordToSchema(addMetaToSchema(addHistoryToSchema(LocalUserCoreSchema)))\nexport const GoogleUserSchema: MongooseSchema<IGoogleUser> = addMetaToSchema(addHistoryToSchema(GoogleUserCoreSchema))\n\n// Models\nexport const BaseUserModel: IBaseUserModel = mongooseModel<IBaseUser>(collectionName, BaseUserSchema)\nexport const LocalUserModel: ILocalUserModel = BaseUserModel.discriminator<ILocalUser>('LocalUser', LocalUserSchema)\nexport const GoogleUserModel = BaseUserModel.discriminator<IGoogleUser>('GoogleUser', GoogleUserSchema)\n\n// Helpers\nexport const discriminateUser: DiscriminateUser = (user: IBaseUser): ILocalUser & { authType: 'LocalUser' } | IGoogleUser & { authType: 'GoogleUser' } | null => {\n if (!('authType' in user)) return null\n if (user.authType === 'LocalUser') {\n if (!('email' in user) || typeof user.email !== 'string') return null\n if (!('_password' in user) || typeof user._password !== 'string') return null\n if (!('verified' in user) || typeof user.verified !== 'boolean') return null\n return user as ILocalUser & { authType: 'LocalUser' }\n } else if (user.authType === 'GoogleUser') {\n if (!('googleId' in user) || typeof user.googleId !== 'string') return null\n if (!('verified' in user) || user.verified !== true) return null\n return user as IGoogleUser & { authType: 'GoogleUser' }\n }\n else return null\n}\n", "import type {\n Types as MongooseTypes,\n Schema as MongooseSchema,\n Model as MongooseModel\n} from 'mongoose'\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * Helpers\n *\n * * * * * * * * * * * * * * * * * * * * */\n\n// _History\nexport type IHistoryItem = {\n updationTime: Date\n updaterId: MongooseTypes.ObjectId\n stringifiedDocument: String\n}\nexport type IHistory = Array<IHistoryItem>\nexport type WithHistory<T> = T & { _history: IHistory }\nexport type WithoutHistory<T> = Omit<T, '_history'> & { _history?: undefined }\n\nexport type IHistoryItemSchema = MongooseSchema<IHistoryItem>\nexport interface AddHistoryToSchema {\n <T extends Object>(inputSchema: MongooseSchema<T>): MongooseSchema<WithHistory<T>>\n}\n\n// _Id\nexport type WithId<T> = T & {\n _id: MongooseTypes.ObjectId\n}\n\n// _Meta\nexport type IMeta = {\n creationTime: Date\n creatorId: MongooseTypes.ObjectId\n lastUpdationTime: Date\n lastUpdaterId: MongooseTypes.ObjectId\n currentVersionNumber: number\n}\nexport type WithMeta<T> = T & { _meta: IMeta }\nexport type WithoutMeta<T> = Omit<T, '_meta'> & { _meta?: undefined }\n\nexport type IMetaSchema = MongooseSchema<IMeta>\nexport interface AddMetaToSchema {\n <T extends Object>(inputSchema: MongooseSchema<T>): MongooseSchema<WithMeta<T>>\n}\n\n// _Password\nexport type IPassword = string\nexport type WithPassword<T> = T & { _password: IPassword }\nexport type WithoutPassword<T> = Omit<T, '_password'> & { _password?: undefined }\n\nexport interface AddPasswordToSchema {\n <T extends Object>(inputSchema: MongooseSchema<T>): MongooseSchema<WithPassword<T>>\n}\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * User\n *\n * * * * * * * * * * * * * * * * * * * * */\n\n// UserAuthToken\nexport type IUserAuthToken = WithId<{\n value: string\n userId: MongooseTypes.ObjectId\n issuedOn: Date\n}>\nexport type UserAuthTokenCollectionName = 'UserAuthToken'\nexport type IUserAuthTokenSchema = MongooseSchema<IUserAuthToken>\nexport type IUserAuthTokenModel = MongooseModel<IUserAuthToken>\n\n// UserEmailValidationToken\nexport type IUserEmailValidationToken = WithId<{\n value: string\n email: string\n expiresOn: Date\n}>\nexport type UserEmailValidationTokenCollectionName = 'UserEmailValidationToken'\nexport type IUserEmailValidationTokenSchema = MongooseSchema<IUserEmailValidationToken>\nexport type IUserEmailValidationTokenModel = MongooseModel<IUserEmailValidationToken>\n\n// UserPasswordRenewalToken\nexport type IUserPasswordRenewalToken = WithId<{\n value: string\n email: string\n expiresOn: Date\n}>\nexport type UserPasswordRenewalTokenCollectionName = 'UserPasswordRenewalToken'\nexport type IUserPasswordRenewalTokenSchema = MongooseSchema<IUserPasswordRenewalToken>\nexport type IUserPasswordRenewalTokenModel = MongooseModel<IUserPasswordRenewalToken>\n\n// UserRevokedAuthToken\nexport type IUserRevokedAuthToken = WithId<{\n value: string\n userId: MongooseTypes.ObjectId\n revokedOn: Date\n}>\nexport type UserRevokedAuthTokenCollectionName = 'UserRevokedAuthToken'\nexport type IUserRevokedAuthTokenSchema = MongooseSchema<IUserRevokedAuthToken>\nexport type IUserRevokedAuthTokenModel = MongooseModel<IUserRevokedAuthToken>\n\n// UserUploadQuota\nexport type IUserUploadQuota = WithId<{\n userId: MongooseTypes.ObjectId\n dailyUploadsByteSize: number\n monthlyUploadsByteSize: number\n totalUploadsByteSize: number\n}>\nexport type UserUploadQuotaCollectionName = 'UserUploadQuota'\nexport type IUserUploadQuotaSchema = MongooseSchema<IUserUploadQuota>\nexport type IUserUploadQuotaModel = MongooseModel<IUserUploadQuota>\n\n// User\nexport enum UserRole {\n ROOT = 'root',\n ADMIN = 'admin',\n USER = 'user'\n}\n\nexport enum UserStatus {\n ACTIVE = 'active',\n SUSPENDED = 'suspended',\n BANNED = 'banned'\n}\n\nexport enum UserBadge {\n // System - Send Mail\n CAN_SYSTEM_SEND_MAIL = 'system.send-mail',\n\n // System - Kill\n CAN_SYSTEM_KILL = 'system.kill',\n\n // Storage - Endpoint\n CREATE_STORAGE_ENDPOINT = 'storage.endpoint.create',\n GET_STORAGE_ENDPOINT = 'storage.endpoint.get',\n RENAME_STORAGE_ENDPOINT = 'storage.endpoint.rename',\n ERASE_STORAGE_ENDPOINT = 'storage.endpoint.erase',\n\n // Storage - Credentials\n CREATE_STORAGE_CREDENTIALS = 'storage.credentials.create',\n GET_STORAGE_CREDENTIALS = 'storage.credentials.get',\n RENAME_STORAGE_CREDENTIALS = 'storage.credentials.rename',\n ERASE_STORAGE_CREDENTIALS = 'storage.credentials.erase',\n\n // Storage - File\n UPLOAD_STORAGE_FILE = 'storage.file.upload',\n\n // Image\n FORMAT_IMAGE = 'image.format',\n\n // Admin - Users\n ADMIN_USERS_CAN_GET = 'admin.users.can-get',\n ADMIN_USERS_CAN_LIST = 'admin.users.can-list',\n ADMIN_USERS_CAN_CREATE = 'admin.users.can-create',\n ADMIN_USERS_CAN_UPDATE = 'admin.users.can-update',\n ADMIN_USERS_CAN_DELETE = 'admin.users.can-delete',\n ADMIN_USERS_CAN_REVOKE_AUTH_TOKENS = 'admin.users.can-revoke-auth-tokens',\n ADMIN_USERS_CAN_REVOKE_EMAIL_VALIDATION_TOKENS = 'admin.users.can-revoke-email-validation-tokens',\n ADMIN_USERS_CAN_REVOKE_PASSWORD_RENEWAL_TOKENS = 'admin.users.can-revoke-password-renewal-tokens',\n ADMIN_USERS_CAN_GET_UPLOAD_QUOTA = 'admin.users.can-get-upload-quota',\n ADMIN_USERS_CAN_RESET_USER_UPLOAD_QUOTA = 'admin.users.can-reset-upload-quota',\n\n // Admin - Temp\n ADMIN_TEMP_CAN_FLUSH = 'admin.temp.can-flush'\n}\n\nexport type IBaseUserCore = WithId<{\n username: string\n role: UserRole\n status: UserStatus\n badges: UserBadge[]\n}>\n\nexport type IGoogleUserCore = IBaseUserCore & {\n googleId: string\n verified: true\n}\n\nexport type ILocalUserCore = IBaseUserCore & {\n email: string\n verified: boolean\n}\n\nexport type IBaseUser = WithMeta<WithHistory<IBaseUserCore>>\nexport type IGoogleUser = WithMeta<WithHistory<IGoogleUserCore>>\nexport type ILocalUser = WithMeta<WithHistory<WithPassword<ILocalUserCore>>>\nexport type IUser = IGoogleUser | ILocalUser\n\nexport type UserCollectionName = 'User'\nexport type IBaseUserCoreSchema = MongooseSchema<IBaseUserCore>\nexport type ILocalUserCoreSchema = MongooseSchema<ILocalUserCore>\nexport type IGoogleUserCoreSchema = MongooseSchema<IGoogleUserCore>\nexport type IBaseUserSchema = MongooseSchema<IBaseUser>\nexport type ILocalUserSchema = MongooseSchema<ILocalUser>\nexport type IGoogleUserSchema = MongooseSchema<IGoogleUser>\nexport type IBaseUserModel = MongooseModel<IBaseUser>\nexport type ILocalUserModel = MongooseModel<ILocalUser>\nexport type IGoogleUserModel = MongooseModel<IGoogleUser>\nexport type DiscriminateUser = (user: IBaseUser) => ILocalUser & { authType: 'LocalUser' } | IGoogleUser & { authType: 'GoogleUser' } | null\n", "import Zlib from 'node:zlib'\nimport { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport {\n Types as MongooseTypes,\n Schema as MongooseSchema,\n Document as MongooseDocument,\n CallbackWithoutResultAndOptionalError as MongooseCallbackWithoutResultAndOptionalError\n} from 'mongoose'\nimport { DocumentWithLocals, QueryWithLocals } from '../../types/database/index.js'\nimport { IHistoryItem, IHistoryItemSchema, AddHistoryToSchema, WithHistory } from '../../types/schema/index.js'\n\n// Schema\nexport const HistoryItemSchema: IHistoryItemSchema = new MongooseSchema<IHistoryItem>({\n updationTime: { type: Date, required: true },\n updaterId: { type: MongooseSchema.ObjectId, required: true },\n stringifiedDocument: { type: String, required: true }\n})\n\n// Helpers\nexport async function makeHistoryItem (document: MongooseDocument, initiatorObjectId: MongooseTypes.ObjectId): Promise<IHistoryItem> {\n const docAsObject = document.toObject()\n const coreEntries = Object.entries(docAsObject).filter(([key]) => !key.startsWith('_'))\n const strippedToCore = Object.fromEntries(coreEntries)\n const stringified = JSON.stringify(strippedToCore)\n const compressed = await new Promise<Buffer>((resolve, reject) => {\n Zlib.gzip(stringified, (err, compressed) => {\n if (err !== null) return reject(err)\n return resolve(compressed)\n })\n })\n const base64 = compressed.toString('base64')\n const historyItem: IHistoryItem = {\n updationTime: new Date(),\n updaterId: initiatorObjectId,\n stringifiedDocument: base64\n }\n return historyItem\n}\n\nexport const addHistoryToSchema: AddHistoryToSchema = <T extends Object>(inputSchema: MongooseSchema<T>) => {\n const schema = inputSchema.clone() as MongooseSchema<WithHistory<T>>\n schema.add(new MongooseSchema<WithHistory<{}>>({\n _history: {\n type: [HistoryItemSchema],\n required: true,\n default: []\n }\n }))\n schema.pre('save', handleSave)\n schema.pre('insertMany', handleInsertMany)\n schema.pre('findOneAndUpdate', handleUpdate)\n schema.pre('updateOne', handleUpdate)\n schema.pre('updateMany', handleUpdate)\n\n async function handleSave (\n this: WithHistory<DocumentWithLocals<{}>>,\n next: MongooseCallbackWithoutResultAndOptionalError\n ) {\n const context = this.$locals?.context\n const initiatorId = context?.initiatorId ?? null\n const initiatorObjectId = initiatorId !== null ? new MongooseTypes.ObjectId(initiatorId) : null\n if (initiatorObjectId === null) return next(new Error('initiatorId is required in context for save operation'))\n try {\n const historyItem = await makeHistoryItem(this, initiatorObjectId)\n if (this.isNew) { this._history = [historyItem] }\n else this._history.push(historyItem)\n next()\n } catch (err) {\n const errStr = unknownToString(err)\n next(new Error(errStr))\n }\n }\n\n async function handleInsertMany (\n next: MongooseCallbackWithoutResultAndOptionalError,\n docs: WithHistory<DocumentWithLocals<{}>>[]\n ) {\n try {\n for (const doc of docs) {\n const context = doc.$locals?.context\n const initiatorId = context?.initiatorId ?? null\n const initiatorObjectId = initiatorId !== null ? new MongooseTypes.ObjectId(initiatorId) : null\n if (initiatorObjectId === null) return next(new Error('initiatorId is required in context for insertMany operation'))\n const historyItem = await makeHistoryItem(doc, initiatorObjectId)\n doc._history = [historyItem]\n }\n next()\n } catch (err) {\n const errStr = unknownToString(err)\n next(new Error(errStr))\n }\n }\n\n async function handleUpdate (\n this: QueryWithLocals<WithHistory<{}>>,\n next: MongooseCallbackWithoutResultAndOptionalError\n ) {\n const context = this.getOptions().$locals?.context;\n const initiatorId = context?.initiatorId ?? null;\n const initiatorObjectId = initiatorId !== null ? new MongooseTypes.ObjectId(initiatorId) : null;\n if (initiatorObjectId === null) return next(new Error('initiatorId is required in context for update operation'))\n try {\n const docPromise = this.model.findOne(this.getFilter()).exec() as Promise<WithHistory<MongooseDocument> | null>\n const doc = await docPromise\n if (doc === null) return next(new Error('Document not found for update'))\n const historyItem = await makeHistoryItem(doc, initiatorObjectId)\n doc._history.push(historyItem)\n this.set({ _history: doc._history })\n next()\n } catch (err) {\n const errStr = unknownToString(err)\n next(new Error(errStr))\n }\n }\n return schema\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport {\n Types as MongooseTypes,\n Schema as MongooseSchema,\n CallbackWithoutResultAndOptionalError as MongooseCallbackWithoutResultAndOptionalError,\n UpdateQuery as MongooseUpdateQuery\n} from 'mongoose'\nimport { DocumentWithLocals, QueryWithLocals } from '../../types/database/index.js'\nimport env from '../../env/index.js'\nimport { IMeta, IMetaSchema, AddMetaToSchema, WithMeta } from '../../types/schema/index.js'\n\n// Schema\nexport const MetaSchema: IMetaSchema = new MongooseSchema<IMeta>({\n creationTime: { type: Date, required: true },\n creatorId: { type: MongooseSchema.ObjectId, required: true },\n lastUpdationTime: { type: Date, required: true },\n lastUpdaterId: { type: MongooseSchema.ObjectId, required: true },\n currentVersionNumber: { type: Number, required: true }\n})\n\n// Helpers\nexport const addMetaToSchema: AddMetaToSchema = <T extends Object> (inputSchema: MongooseSchema<T>): MongooseSchema<WithMeta<T>> => {\n const schema = inputSchema.clone() as MongooseSchema<WithMeta<T>>\n schema.add(new MongooseSchema<WithMeta<{}>>({\n _meta: {\n type: MetaSchema,\n required: true,\n default: {\n creationTime: new Date(),\n creatorId: new MongooseTypes.ObjectId(env.ROOT_USER_ID),\n lastUpdationTime: new Date(),\n lastUpdaterId: new MongooseTypes.ObjectId(env.ROOT_USER_ID),\n currentVersionNumber: 0\n }\n }\n }))\n \n schema.pre('save', handleSave)\n schema.pre('insertMany', handleInsertMany)\n schema.pre('findOneAndUpdate', handleUpdate)\n schema.pre('updateOne', handleUpdate)\n schema.pre('updateMany', handleUpdate)\n \n return schema\n\n function handleSave (\n this: WithMeta<DocumentWithLocals<{}>>,\n next: MongooseCallbackWithoutResultAndOptionalError\n ) {\n const context = this.$locals?.context\n const initiatorId = context?.initiatorId ?? null\n const initiatorObjectId = initiatorId !== null ? new MongooseTypes.ObjectId(initiatorId) : null\n if (initiatorObjectId === null) return next(new Error('initiatorId is required in context for save operation'))\n if (this.isNew) {\n this._meta.creationTime = new Date()\n this._meta.creatorId = initiatorObjectId\n }\n this._meta.lastUpdationTime = new Date()\n this._meta.lastUpdaterId = initiatorObjectId\n this._meta.currentVersionNumber = 0\n next()\n }\n\n function handleInsertMany (\n next: MongooseCallbackWithoutResultAndOptionalError,\n docs: Array<WithMeta<DocumentWithLocals<{}>>>\n ) {\n try {\n for (const doc of docs) {\n const context = doc.$locals?.context\n const initiatorId = context?.initiatorId ?? null\n const initiatorObjectId = initiatorId !== null ? new MongooseTypes.ObjectId(initiatorId) : null\n if (initiatorObjectId === null) return next(new Error('initiatorId is required in context for insertMany operation'))\n doc._meta.creationTime = new Date()\n doc._meta.creatorId = initiatorObjectId\n doc._meta.lastUpdationTime = new Date()\n doc._meta.lastUpdaterId = initiatorObjectId\n doc._meta.currentVersionNumber = 0\n }\n next()\n } catch (err) {\n const errStr = unknownToString(err)\n next(new Error(errStr))\n }\n }\n\n function handleUpdate (\n this: QueryWithLocals<WithMeta<{}>>,\n next: MongooseCallbackWithoutResultAndOptionalError\n ) {\n const context = this.getOptions().$locals?.context\n const initiatorId = context?.initiatorId ?? null\n const initiatorObjectId = initiatorId !== null ? new MongooseTypes.ObjectId(initiatorId) : null\n if (initiatorObjectId === null) return next(new Error('initiatorId is required in context for updateMany operation'))\n const rawUpdate = this.getUpdate()\n if (Array.isArray(rawUpdate)) return next(new Error('Aggregation pipeline updates are not supported in this hook'))\n const update: MongooseUpdateQuery<WithMeta<{}>> = (rawUpdate ?? {}) as MongooseUpdateQuery<WithMeta<{}>>\n update.$set = update.$set ?? {}\n update.$inc = update.$inc ?? {}\n update.$set['_meta.lastUpdationTime'] = new Date()\n update.$set['_meta.lastUpdaterId'] = initiatorObjectId\n update.$inc['_meta.currentVersionNumber'] = ((update.$inc['_meta.currentVersionNumber'] as number) ?? 0) + 1\n this.setUpdate(update)\n next()\n }\n}\n", "import { Schema as MongooseSchema } from 'mongoose'\nimport { AddPasswordToSchema, WithPassword } from '../../types/schema/index.js'\n\n// Schema\nexport const addPasswordToSchema: AddPasswordToSchema = <T extends Object> (inputSchema: MongooseSchema<T>): MongooseSchema<WithPassword<T>> => {\n const schema = inputSchema.clone() as MongooseSchema<WithPassword<T>>\n schema.add(new MongooseSchema<WithPassword<{}>>({\n _password: {\n type: String,\n required: true\n }\n }))\n return schema\n}\n", "import {\n Schema as MongooseSchema,\n model as mongooseModel\n} from 'mongoose'\nimport * as User from '../user/index.js'\nimport {\n IUserAuthToken,\n IUserAuthTokenModel,\n IUserAuthTokenSchema,\n UserAuthTokenCollectionName\n} from '../../../types/schema/index.js'\n\n// Collection name\nexport const collectionName: UserAuthTokenCollectionName = 'UserAuthToken'\n\n// Schema\nexport const UserAuthTokenSchema: IUserAuthTokenSchema = new MongooseSchema<IUserAuthToken>({\n value: { type: String, required: true, unique: true },\n userId: { type: MongooseSchema.ObjectId, ref: User.collectionName, required: true },\n issuedOn: { type: Date, required: true }\n})\n\n// Model\nexport const UserAuthTokenModel: IUserAuthTokenModel = mongooseModel<IUserAuthToken>(\n collectionName,\n UserAuthTokenSchema\n)\n", "import {\n Schema as MongooseSchema,\n model as mongooseModel\n} from 'mongoose'\nimport * as User from '../user/index.js'\nimport {\n IUserRevokedAuthToken,\n IUserRevokedAuthTokenModel,\n IUserRevokedAuthTokenSchema,\n UserRevokedAuthTokenCollectionName\n} from '../../../types/schema/index.js'\n\n// Collection name\nexport const collectionName: UserRevokedAuthTokenCollectionName = 'UserRevokedAuthToken'\n\n// Schema\nexport const UserRevokedAuthTokenSchema: IUserRevokedAuthTokenSchema = new MongooseSchema<IUserRevokedAuthToken>({\n value: { type: String, required: true },\n userId: { type: MongooseSchema.ObjectId, ref: User.collectionName, required: true },\n revokedOn: { type: Date, required: true }\n})\n\n// Model\nexport const UserRevokedAuthTokenModel: IUserRevokedAuthTokenModel = mongooseModel<IUserRevokedAuthToken>(\n collectionName,\n UserRevokedAuthTokenSchema\n)\n", "import {\n Schema as MongooseSchema,\n model as mongooseModel\n} from 'mongoose'\nimport {\n IUserEmailValidationToken,\n IUserEmailValidationTokenModel,\n IUserEmailValidationTokenSchema,\n UserEmailValidationTokenCollectionName\n} from '../../../types/schema/index.js'\n\n// Collection name\nexport const collectionName: UserEmailValidationTokenCollectionName = 'UserEmailValidationToken'\n\n// Schema\nexport const UserEmailValidationTokenSchema: IUserEmailValidationTokenSchema = new MongooseSchema<IUserEmailValidationToken>({\n value: { type: String, required: true, unique: true },\n email: { type: String, required: true },\n expiresOn: { type: Date, required: true }\n})\n\n// Model\nexport const UserEmailValidationTokenModel: IUserEmailValidationTokenModel = mongooseModel<IUserEmailValidationToken>(\n collectionName,\n UserEmailValidationTokenSchema\n)\n", "import {\n Schema as MongooseSchema,\n model as mongooseModel\n} from 'mongoose'\nimport {\n IUserPasswordRenewalToken,\n IUserPasswordRenewalTokenModel,\n IUserPasswordRenewalTokenSchema,\n UserPasswordRenewalTokenCollectionName\n} from '../../../types/schema/index.js'\n\n// Collection name\nexport const collectionName: UserPasswordRenewalTokenCollectionName = 'UserPasswordRenewalToken'\n\n// Schema\nexport const UserPasswordRenewalTokenSchema: IUserPasswordRenewalTokenSchema = new MongooseSchema<IUserPasswordRenewalToken>({\n value: { type: String, required: true, unique: true },\n email: { type: String, required: true },\n expiresOn: { type: Date, required: true }\n})\n\n// Model\nexport const UserPasswordRenewalTokenModel: IUserPasswordRenewalTokenModel = mongooseModel<IUserPasswordRenewalToken>(\n collectionName,\n UserPasswordRenewalTokenSchema\n)\n", "import csrf from 'csrf'\nimport { Request } from 'express'\nimport { Outcome } from '@design-edito/tools/agnostic/misc/outcome/index.js'\nimport env from '../env/index.js'\nimport { VerifyErrCodes } from '../types/csrf/index.js'\n\nexport const tokens = new csrf()\n\nexport const verify = (req: Request): Outcome.Either<true, VerifyErrCodes> => {\n const skippedMethods = ['GET', 'HEAD', 'OPTIONS', 'TRACE']\n if (skippedMethods.includes(req.method)) return Outcome.makeSuccess(true)\n const secret = req.cookies[env.CSRF_COOKIE_NAME]\n const token = req.headers[env.CSRF_TOKEN_HEADER] as string\n if (typeof secret !== 'string') return Outcome.makeFailure(VerifyErrCodes.CSRF_SECRET_NOT_FOUND)\n if (typeof token !== 'string') return Outcome.makeFailure(VerifyErrCodes.CSRF_TOKEN_NOT_FOUND)\n const verified = tokens.verify(secret, token)\n if (!verified) return Outcome.makeFailure(VerifyErrCodes.INVALID_CSRF_TOKEN)\n return Outcome.makeSuccess(true)\n}\n", "import { createHash } from 'node:crypto'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport Stream, { Readable } from 'node:stream'\nimport { Outcome } from '@design-edito/tools/agnostic/misc/outcome/index.js'\nimport { mebibytes } from '@design-edito/tools/agnostic/misc/data-size/index.js'\nimport { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport { Types as MongooseTypes } from 'mongoose'\nimport multer from 'multer'\nimport * as Database from '../database/index.js'\nimport env from '../env/index.js'\nimport { Codes } from '../types/errors/index.js'\nimport { logError } from '../logs/index.js'\nimport { Category as LogCategory } from '../types/logs/index.js'\nimport { UserUploadQuotaModel } from '../schema/user/upload-quota/index.js'\nimport { IUserUploadQuota } from '../types/schema/index.js'\nimport {\n generatePath as generateTempPath,\n getRootPath as getTempDirRootPath,\n increaseCurrentByteSize as increaseCurrentTempDirByteSize\n} from '../temp/index.js'\nimport {\n GetFileHash,\n PingScanner,\n PingScannerError,\n ScanFile,\n ScanFileError,\n UpdateUserUploadsQuota\n} from '../types/uploads/index.js'\nimport { HttpClamScanner } from './httpClamScanner.js'\n\n/* Multer */\nexport const multerStorage: multer.StorageEngine = multer.diskStorage({\n destination: (_req, _file, cb) => cb(null, getTempDirRootPath()),\n filename: (_req, file, cb) => {\n const currentTempDirByteSize = increaseCurrentTempDirByteSize(file.size)\n if (currentTempDirByteSize >= mebibytes(env.TEMP_DIR_MAX_MEBIBYTES_SIZE).toBytes()) return cb(new Error('Temp directory is full'), '')\n const tempPath = generateTempPath(file.originalname)\n const fullPath = path.join(getTempDirRootPath(), tempPath)\n const dirPath = path.dirname(fullPath)\n fs.promises.mkdir(dirPath, { recursive: true })\n .then(() => cb(null, tempPath))\n .catch(err => cb(err, ''))\n }\n})\n\n/* Scan */\nexport const scanner = new HttpClamScanner(env.CLAMAV_PROTOCOL, env.CLAMAV_HOST, env.CLAMAV_PORT)\n\nexport const scanFile: ScanFile = async (file, timeout = 5000) => {\n const scanResult = await scanner.scan(file, timeout)\n if (scanResult.success) return Outcome.makeSuccess(true)\n logError(LogCategory.UPLOAD, 'Failed to scan file', {\n error: scanResult.error,\n file: file instanceof Buffer ? 'Buffer' : 'Readable'\n })\n return Outcome.makeFailure({\n code: ScanFileError.INFECTED,\n details: scanResult.error.code\n })\n}\n\nexport const pingScanner: PingScanner = async (timeout: number = 2000) => {\n const pingResult = await scanner.ping(timeout)\n if (pingResult.success) {\n return Outcome.makeSuccess(pingResult.payload)\n }\n logError(LogCategory.UPLOAD, 'Failed to ping ClamAV HTTP service', { error: pingResult.error })\n return Outcome.makeFailure({\n code: PingScannerError.SCANNER_UNREACHABLE,\n details: pingResult.error.details\n })\n}\n\n/* Hash */\nexport const getFileHash: GetFileHash = async (file): Promise<Outcome.Either<string, string>> => {\n const hash = createHash('sha256')\n const hashStream = new Stream.Transform({\n transform: (chunk, _enc, callback) => {\n hash.update(chunk)\n callback()\n }\n })\n const pipableFile: Readable = Buffer.isBuffer(file) ? Readable.from(file) : file\n pipableFile.pipe(hashStream)\n return new Promise<Outcome.Either<string, string>>(resolve => {\n hashStream.on('finish', () => resolve(Outcome.makeSuccess(hash.digest('hex'))))\n hashStream.on('error', (err) => resolve(Outcome.makeFailure(unknownToString(err))))\n })\n}\n\n/* Upload quotas */\nexport const updateUserUploadsQuota: UpdateUserUploadsQuota = async (userId, fileByteSize, limitsInBytes) => {\n const preUpdLookup = await Database.findOne<IUserUploadQuota>(UserUploadQuotaModel, { userId }, { initiatorId: userId })\n if (!preUpdLookup.success\n && preUpdLookup.error.code === Codes.DB_ERROR) return Outcome.makeFailure(Codes.DB_ERROR)\n let preUpdateUserQuota: IUserUploadQuota\n if (!preUpdLookup.success) {\n const inserted = await Database.insertOne<IUserUploadQuota>(UserUploadQuotaModel, {\n userId: new MongooseTypes.ObjectId(userId),\n dailyUploadsByteSize: 0,\n monthlyUploadsByteSize: 0,\n totalUploadsByteSize: 0\n }, { initiatorId: userId })\n if (!inserted.success) return Outcome.makeFailure(Codes.DB_ERROR)\n preUpdateUserQuota = inserted.payload\n } else {\n preUpdateUserQuota = preUpdLookup.payload\n }\n const { dailyUploadsByteSize, monthlyUploadsByteSize, totalUploadsByteSize } = preUpdateUserQuota\n const targetDailyUploadsSize = dailyUploadsByteSize + fileByteSize\n const targetMonthlyUploadsSize = monthlyUploadsByteSize + fileByteSize\n const targetTotalUploadsSize = totalUploadsByteSize + fileByteSize\n if (targetDailyUploadsSize > limitsInBytes.daily) return Outcome.makeFailure(Codes.USER_DAILY_UPLOAD_QUOTA_EXCEEDED)\n if (targetMonthlyUploadsSize > limitsInBytes.monthly) return Outcome.makeFailure(Codes.USER_MONTHLY_UPLOAD_QUOTA_EXCEEDED)\n if (targetTotalUploadsSize > limitsInBytes.total) return Outcome.makeFailure(Codes.USER_TOTAL_UPLOAD_QUOTA_EXCEEDED)\n const userQuotaUpdate = await Database.updateOne<IUserUploadQuota>(UserUploadQuotaModel, { userId }, {\n $inc: {\n dailyUploadsByteSize: fileByteSize,\n monthlyUploadsByteSize: fileByteSize,\n totalUploadsByteSize: fileByteSize\n }\n }, { initiatorId: userId })\n if (userQuotaUpdate.success) return Outcome.makeSuccess(userQuotaUpdate.payload)\n return Outcome.makeFailure(userQuotaUpdate.error.code)\n}\n", "import {\n Schema as MongooseSchema,\n model as mongooseModel,\n Types as MongooseTypes\n} from 'mongoose'\nimport * as User from '../user/index.js'\nimport {\n IUserUploadQuota,\n IUserUploadQuotaModel,\n IUserUploadQuotaSchema,\n UserUploadQuotaCollectionName\n} from '../../../types/schema/index.js'\n\n// Collection name\nexport const collectionName: UserUploadQuotaCollectionName = 'UserUploadQuota'\n\n// Schema\nexport const UserUploadQuotaSchema: IUserUploadQuotaSchema = new MongooseSchema<IUserUploadQuota>({\n _id: {\n type: MongooseSchema.Types.ObjectId,\n default: () => new MongooseTypes.ObjectId()\n },\n userId: {\n type: MongooseSchema.Types.ObjectId,\n ref: User.collectionName,\n required: true,\n unique: true\n },\n dailyUploadsByteSize: { type: Number, required: true, default: 0 },\n monthlyUploadsByteSize: { type: Number, required: true, default: 0 },\n totalUploadsByteSize: { type: Number, required: true, default: 0 }\n})\n\n// Model\nexport const UserUploadQuotaModel: IUserUploadQuotaModel = mongooseModel<IUserUploadQuota>(\n collectionName,\n UserUploadQuotaSchema\n)\n", "import { randomUUID } from 'node:crypto'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { promisify } from 'node:util'\nimport { dir as tmpDir } from 'tmp-promise'\nimport fastFolderSize from 'fast-folder-size'\nimport env from '../env/index.js'\nimport { logError, logInfo } from '../logs/index.js'\nimport { Category as LogCategory } from '../types/logs/index.js'\nimport {\n CleanupOldFiles,\n Flush,\n GeneratePath,\n GetCurrentByteSize,\n GetRootPath,\n IncreaseCurrentByteSize,\n UpdateCurrentByteSize\n} from '../types/temp/index.js'\n\nconst {\n path: ABS_TEMP_DIR_PATH,\n cleanup\n} = await tmpDir({ prefix: env.TEMP_DIR_PREFIX })\n\nexport const getRootPath: GetRootPath = () => ABS_TEMP_DIR_PATH\n\nexport const generatePath: GeneratePath = (fileName?: string): string => {\n const nowStr = Date.now().toString()\n const padded = nowStr.padStart(13, '0')\n const part1 = padded.slice(0, 4)\n const part2 = padded.slice(4, 7)\n const part3 = padded.slice(7, 10)\n const part4 = padded.slice(10, 13)\n const randomPath = randomUUID()\n .replace(/-/g, '')\n .match(/.{1,2}/g)!\n .join('/')\n const parentPath = path.join(`${part1}`, `${part2}`, `${part3}`, `${part4}`, `${randomPath}`)\n if (fileName === undefined) return parentPath\n return path.join(parentPath, fileName)\n}\n\nexport const cleanupOldFiles: CleanupOldFiles = async (maxAgeMs: number) => {\n const thresholdDate = new Date(Date.now() - maxAgeMs)\n const thresholdDateStr = thresholdDate.getTime().toString().padStart(13, '0')\n const thresholdPart1 = thresholdDateStr.slice(0, 4)\n const thresholdPart2 = thresholdDateStr.slice(4, 7)\n const thresholdPart3 = thresholdDateStr.slice(7, 10)\n const thresholdPart4 = thresholdDateStr.slice(10, 13)\n try {\n const part1DirsPath = ABS_TEMP_DIR_PATH\n const part1Dirs = await fs.promises.readdir(part1DirsPath)\n await Promise.all(part1Dirs.map(dirName => {\n const parsedDirName = parseInt(dirName)\n const parsedThreshold = parseInt(thresholdPart1)\n const thisDirPath = path.join(ABS_TEMP_DIR_PATH, dirName)\n const shouldRemove = Number.isNaN(parsedDirName)\n || `${parsedDirName}`.length !== 4\n || parsedDirName < parsedThreshold\n if (shouldRemove) return fs.promises.rm(thisDirPath, { recursive: true, force: true })\n }))\n } catch (err: any) {\n if (err?.code !== 'ENOENT') logError(\n LogCategory.TEMP,\n 'Failed to cleanup old files',\n { error: err }\n )\n }\n try {\n const part2DirsPath = path.join(ABS_TEMP_DIR_PATH, thresholdPart1)\n const part2Dirs = await fs.promises.readdir(part2DirsPath)\n await Promise.all(part2Dirs.map(dirName => {\n const parsedDirName = parseInt(dirName)\n const parsedThreshold = parseInt(thresholdPart2)\n const thisDirPath = path.join(part2DirsPath, dirName)\n const shouldRemove = Number.isNaN(parsedDirName)\n || `${parsedDirName}`.length !== 3\n || parsedDirName < parsedThreshold\n if (shouldRemove) return fs.promises.rm(thisDirPath, { recursive: true, force: true })\n }))\n } catch (err: any) {\n if (err?.code !== 'ENOENT') logError(\n LogCategory.TEMP,\n 'Failed to cleanup old files',\n { error: err }\n )\n }\n try {\n const part3DirsPath = path.join(ABS_TEMP_DIR_PATH, thresholdPart1, thresholdPart2)\n const part3Dirs = await fs.promises.readdir(part3DirsPath)\n await Promise.all(part3Dirs.map(dirName => {\n const parsedDirName = parseInt(dirName)\n const parsedThreshold = parseInt(thresholdPart3)\n const thisDirPath = path.join(part3DirsPath, dirName)\n const shouldRemove = Number.isNaN(parsedDirName)\n || `${parsedDirName}`.length !== 3\n || parsedDirName < parsedThreshold\n if (shouldRemove) return fs.promises.rm(thisDirPath, { recursive: true, force: true })\n }))\n } catch (err: any) {\n if (err?.code !== 'ENOENT') logError(\n LogCategory.TEMP,\n 'Failed to cleanup old files',\n { error: err }\n )\n }\n try {\n const part4DirsPath = path.join(ABS_TEMP_DIR_PATH, thresholdPart1, thresholdPart2, thresholdPart3)\n const part4Dirs = await fs.promises.readdir(part4DirsPath)\n await Promise.all(part4Dirs.map(dirName => {\n const parsedDirName = parseInt(dirName)\n const parsedThreshold = parseInt(thresholdPart4)\n const thisDirPath = path.join(part4DirsPath, dirName)\n const shouldRemove = Number.isNaN(parsedDirName)\n || `${parsedDirName}`.length !== 3\n || parsedDirName < parsedThreshold\n if (shouldRemove) return fs.promises.rm(thisDirPath, { recursive: true, force: true })\n }))\n logInfo(LogCategory.TEMP, 'Cleaned up old files')\n } catch (err: any) {\n if (err?.code !== 'ENOENT') logError(\n LogCategory.TEMP,\n 'Failed to cleanup old files',\n { error: err }\n )\n }\n}\n\nasync function calculateByteSize () {\n const fastFolderSizeAsync = promisify(fastFolderSize as any) // [WIP] there seem to be a problem with fast-folder-size types\n const bytes = await fastFolderSizeAsync(ABS_TEMP_DIR_PATH)\n return bytes ?? Infinity\n}\n\nlet currentByteSize = Infinity\n\nexport const updateCurrentByteSize: UpdateCurrentByteSize = async () => {\n try {\n currentByteSize = await calculateByteSize()\n logInfo(LogCategory.TEMP, 'Updated temp dir current byte size', { currentByteSize })\n } catch (err) {\n logError(LogCategory.TEMP, 'Failed to update temp dir current byte size', { error: err })\n currentByteSize = Infinity\n }\n}\n\nexport const getCurrentByteSize: GetCurrentByteSize = () => currentByteSize\n\nexport const increaseCurrentByteSize: IncreaseCurrentByteSize = (bytes: number) => {\n const newByteSize = currentByteSize + bytes\n currentByteSize = newByteSize\n return newByteSize\n}\n\nexport const flush: Flush = async () => {\n await cleanup()\n await updateCurrentByteSize()\n logInfo(LogCategory.TEMP, 'Flushed temp dir', { ABS_TEMP_DIR_PATH })\n}\n", "import { Readable } from 'node:stream'\nimport { hrtime } from 'node:process'\nimport { AuthClient, GoogleAuth } from 'google-auth-library'\nimport { Outcome } from '@design-edito/tools/agnostic/misc/outcome/index.js'\nimport { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport env from '../env/index.js'\nimport {\n ScanFileError,\n ScanFile,\n PingScanner,\n PingScannerError,\n IHttpClamScanner\n} from '../types/uploads/index.js'\nimport { logInfo } from '../logs/index.js'\nimport { Category as LogCategory } from '../types/logs/index.js'\n\nexport class HttpClamScanner implements IHttpClamScanner {\n private baseUrl: string\n private auth: GoogleAuth | null\n private client: AuthClient | null\n\n constructor (\n protocol: 'http' | 'https',\n host: string,\n port?: string | number\n ) {\n this.baseUrl = port !== undefined\n ? `${protocol}://${host}:${port}`\n : `${protocol}://${host}`\n logInfo(LogCategory.UPLOAD, 'Init HttpClamScanner instance', {\n protocol,\n host,\n port,\n baseUrl: this.baseUrl,\n auth_mode: env.CLAMAV_AUTH_MODE\n })\n if (env.CLAMAV_AUTH_MODE === 'gcp') {\n this.auth = new GoogleAuth()\n this.client = null\n this.initClient()\n } else {\n this.auth = null\n this.client = null\n }\n }\n\n async fetch (url: string, options: RequestInit) {\n const fetchId = Math.random().toString(36).substring(2, 15)\n logInfo(\n LogCategory.UPLOAD,\n `HttpClamScanner instance \u2014 Fetching (${fetchId})...`, {\n url,\n options\n })\n if (this.client === null) {\n const response = await fetch(url, options)\n logInfo(\n LogCategory.UPLOAD,\n `HttpClamScanner instance \u2014 Fetch response (${fetchId})`, {\n url,\n response\n })\n if (!response.ok) throw new Error(`HTTP ${response.status}: ${response.statusText}`)\n return await response.json()\n } else {\n const gaResponse = await this.client.request({ ...options, url })\n logInfo(\n LogCategory.UPLOAD,\n `HttpClamScanner instance \u2014 Fetch response (${fetchId})`, {\n url,\n response: gaResponse\n })\n return gaResponse.data\n }\n }\n\n private async initClient () {\n const { client, auth } = this\n if (client !== null) return\n if (auth === null) return\n this.client = await auth.getIdTokenClient(this.baseUrl) ?? null\n }\n\n async scanBuffer (\n buffer: Buffer,\n timeout: number = 5000\n ): ReturnType<typeof this.scanWithTimeout> {\n return this.scanWithTimeout(buffer, timeout)\n }\n\n async scanStream (\n stream: Readable,\n timeout: number = 5000\n ): ReturnType<typeof this.scanWithTimeout> {\n const chunks: Buffer[] = []\n for await (const chunk of stream) chunks.push(chunk)\n const buffer = Buffer.concat(chunks)\n return this.scanWithTimeout(buffer, timeout)\n }\n\n async scan (\n file: Readable | Buffer,\n timeout: number = 5000\n ): ReturnType<ScanFile> {\n if (file instanceof Readable) return this.scanStream(file, timeout)\n return this.scanBuffer(file, timeout)\n }\n\n private async scanWithTimeout (\n buffer: Buffer,\n timeout: number\n ): ReturnType<ScanFile> {\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n try {\n const boundary = '----formdata-clamav-' + Math.random().toString(36)\n const CRLF = '\\r\\n'\n const filename = 'scan-file'\n let body = ''\n body += `--${boundary}${CRLF}`\n body += `Content-Disposition: form-data; name=\"file\"; filename=\"${filename}\"${CRLF}`\n body += `Content-Type: application/octet-stream${CRLF}`\n body += CRLF\n const header = Buffer.from(body, 'utf8')\n const footer = Buffer.from(`${CRLF}--${boundary}--${CRLF}`, 'utf8')\n const formData = Buffer.concat([header, buffer, footer])\n const response = await this.fetch(`${this.baseUrl}/scan`, {\n method: 'POST',\n body: formData,\n signal: controller.signal,\n headers: {\n 'Content-Type': `multipart/form-data; boundary=${boundary}`\n }\n })\n clearTimeout(timeoutId)\n const result = response as {\n filename: string\n clean: boolean\n result: string\n timestamp: string\n }\n if (result.clean) return Outcome.makeSuccess(true)\n else return Outcome.makeFailure({\n code: ScanFileError.INFECTED,\n details: `stream: ${result.result}`\n })\n } catch (error) {\n clearTimeout(timeoutId)\n if (typeof error === 'object'\n && error !== null\n && 'name' in error\n && error.name === 'AbortError') return Outcome.makeFailure({\n code: ScanFileError.SCAN_TIMED_OUT,\n details: 'Scan timed out'\n })\n return Outcome.makeFailure({\n code: ScanFileError.SCANNER_UNREACHABLE,\n details: unknownToString(error)\n })\n }\n }\n\n async ping (timeout: number = 2000): ReturnType<PingScanner> {\n const start = hrtime.bigint()\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n try {\n const response = await this.fetch(`${this.baseUrl}/ping`, {\n method: 'GET',\n signal: controller.signal,\n headers: {\n 'Content-Type': 'application/json'\n }\n })\n clearTimeout(timeoutId)\n const result = response as {\n status: string;\n clamd: string\n }\n if (result.status !== 'ok') return Outcome.makeFailure({ code: PingScannerError.SCANNER_UNREACHABLE })\n if (result.clamd !== 'connected') return Outcome.makeFailure({ code: PingScannerError.SCANNER_UNREACHABLE })\n const end = hrtime.bigint()\n const durationMs = Number(end - start) / 1_000_000\n return Outcome.makeSuccess(durationMs)\n } catch (error) {\n clearTimeout(timeoutId)\n return Outcome.makeFailure({ code: PingScannerError.SCANNER_UNREACHABLE })\n }\n }\n}\n", "import { jsonResponse } from '../api/utils.js'\nimport {\n NoAuthNullValidation,\n StrongAuthNullValidation,\n WeakAuthNullValidation\n} from '../types/validation/index.js'\n\nexport const noAuthNullValidation: NoAuthNullValidation = async () => jsonResponse(200, {\n body: {},\n params: {},\n query: {}\n})\n\nexport const weakAuthNullValidation: WeakAuthNullValidation = async () => jsonResponse(200, {\n body: {},\n params: {},\n query: {}\n})\n\nexport const strongAuthNullValidation: StrongAuthNullValidation = async () => jsonResponse(200, {\n body: {},\n params: {},\n query: {}\n})\n", "import { allow } from '../../../../auth/index.js'\nimport { AdminTempFlushProcessContract } from '../../../../types/api/admin/temp/flush/index.js'\nimport { UserRole, UserStatus, UserBadge } from '../../../../types/schema/index.js'\n\nexport const authentication: AdminTempFlushProcessContract['authentication'] = allow({\n roles: [UserRole.ADMIN],\n statuses: [UserStatus.ACTIVE],\n badges: [UserBadge.ADMIN_TEMP_CAN_FLUSH],\n verified: true\n})\n", "import { flush } from '../../../../temp/index.js'\nimport { AdminTempFlushProcessContract } from '../../../../types/api/admin/temp/flush/index.js'\nimport { voidResponse } from '../../../utils.js'\n\nexport const operation: AdminTempFlushProcessContract['operation'] = async () => {\n await flush()\n return voidResponse()\n}\n", "import { AdminTempFlushProcessContract } from '../../../../types/api/admin/temp/flush/index.js'\nimport { strongAuthNullValidation } from '../../../../validation/index.js'\nimport { authentication } from './authentication.js'\nimport { operation } from './operation.js'\n\nexport const flush: AdminTempFlushProcessContract = {\n _authType: 'strong',\n _opType: 'void',\n authentication,\n validation: strongAuthNullValidation,\n operation\n}\n", "import { flush } from './flush/index.js'\n\nexport const temp = {\n flush\n}\n", "import { allow } from '../../../../auth/index.js'\nimport { AdminUsersCreateProcessContract } from '../../../../types/api/admin/users/create/index.js'\nimport { UserRole, UserStatus, UserBadge } from '../../../../types/schema/index.js'\n\nexport const authentication: AdminUsersCreateProcessContract['authentication'] = allow({\n roles: [UserRole.ADMIN],\n statuses: [UserStatus.ACTIVE],\n badges: [UserBadge.ADMIN_USERS_CAN_CREATE],\n verified: true\n})\n", "import bcrypt from 'bcrypt'\nimport { insertOne } from '../../../../database/index.js'\nimport { googleUserToDTO, localUserToDTO } from '../../../../transformers/user/index.js'\nimport { LocalUserModel, GoogleUserModel } from '../../../../schema/user/user/index.js'\nimport { IGoogleUser, ILocalUser } from '../../../../types/schema/index.js'\nimport { errorResponse, jsonResponse } from '../../../utils.js'\nimport { AdminUsersCreateProcessContract } from '../../../../types/api/admin/users/create/index.js'\n\nexport const silentOperation: AdminUsersCreateProcessContract['operation'] = async ({ body, accessTokenPayload: { userId } }) => {\n if ('googleId' in body) {\n const insertionAttempt = await insertOne<IGoogleUser>(GoogleUserModel, {\n username: body.username,\n googleId: body.googleId,\n role: body.role,\n status: body.status,\n badges: body.badges,\n verified: body.verified\n }, { initiatorId: userId })\n if (insertionAttempt.success) return jsonResponse(200, googleUserToDTO(insertionAttempt.payload))\n const { code, message } = insertionAttempt.error\n return errorResponse(500, code, message)\n }\n const insertionAttempt = await insertOne<ILocalUser>(LocalUserModel, {\n username: body.username,\n email: body.email,\n _password: await bcrypt.hash(body.password, 10),\n role: body.role,\n status: body.status,\n badges: body.badges,\n verified: body.verified\n }, { initiatorId: userId })\n if (insertionAttempt.success) return jsonResponse(200, localUserToDTO(insertionAttempt.payload))\n const { code, message } = insertionAttempt.error\n return errorResponse(500, code, message)\n}\n\nexport const operation: AdminUsersCreateProcessContract['operation'] = async hooks => {\n const result = await silentOperation(hooks)\n return result\n}\n", "import {\n BaseUserToDTO,\n GoogleUserToDTO,\n LocalUserToDTO\n} from '../../types/transformers/user/index.js'\n\nexport const baseUserToDTO: BaseUserToDTO = user => {\n return {\n _id: user._id.toString(),\n username: user.username,\n role: user.role,\n status: user.status,\n badges: user.badges\n }\n}\n\nexport const localUserToDTO: LocalUserToDTO = user => {\n const base = baseUserToDTO(user)\n return {\n ...base,\n email: user.email,\n verified: user.verified\n }\n}\n\nexport const googleUserToDTO: GoogleUserToDTO = user => {\n const base = baseUserToDTO(user)\n return {\n ...base,\n googleId: user.googleId,\n verified: user.verified\n }\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport zod from 'zod'\nimport { Codes } from '../../../../types/errors/index.js'\nimport { errorResponse, jsonResponse } from '../../../utils.js'\nimport { UserRole, UserStatus, UserBadge } from '../../../../types/schema/index.js'\nimport { AdminUsersCreateProcessContract } from '../../../../types/api/admin/users/create/index.js'\n\nexport const validation: AdminUsersCreateProcessContract['validation'] = async ({ body }) => {\n const coreValidationSchema = zod.object({\n username: zod.string().min(1),\n role: zod.nativeEnum(UserRole),\n status: zod.nativeEnum(UserStatus),\n badges: zod.array(zod.nativeEnum(UserBadge)),\n })\n const emailPasswordValidationSchema = zod.object({\n email: zod.string().email(),\n verified: zod.boolean(),\n password: zod.string().min(8)\n })\n const googleIdValidationSchema = zod.object({\n googleId: zod.string().min(1),\n verified: zod.literal(true)\n })\n const bodyValSchema = zod.union([\n coreValidationSchema.merge(emailPasswordValidationSchema),\n coreValidationSchema.merge(googleIdValidationSchema)\n ])\n try {\n const validated = bodyValSchema.parse(body)\n return jsonResponse(200, {\n body: validated,\n query: {},\n params: {}\n })\n } catch (err) {\n const errStr = unknownToString(err)\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, errStr)\n }\n}\n", "import { AdminUsersCreateProcessContract } from '../../../../types/api/admin/users/create/index.js'\nimport { authentication } from './authentication.js'\nimport { operation } from './operation.js'\nimport { validation } from './validation.js'\n\nexport const create: AdminUsersCreateProcessContract = {\n _authType: 'strong',\n _opType: 'json',\n authentication,\n validation,\n operation\n}\n", "import { allow } from '../../../../auth/index.js'\nimport { AdminUsersDeleteProcessContract } from '../../../../types/api/admin/users/delete/index.js'\nimport { UserRole, UserStatus, UserBadge } from '../../../../types/schema/index.js'\n\nexport const authentication: AdminUsersDeleteProcessContract['authentication'] = allow({\n roles: [UserRole.ADMIN],\n statuses: [UserStatus.ACTIVE],\n badges: [UserBadge.ADMIN_USERS_CAN_DELETE],\n verified: true\n})\n", "import { deleteOne } from '../../../../database/index.js'\nimport { googleUserToDTO,localUserToDTO } from '../../../../transformers/user/index.js'\nimport { Codes } from '../../../../types/errors/index.js'\nimport { BaseUserModel, discriminateUser } from '../../../../schema/user/user/index.js'\nimport { IBaseUser } from '../../../../types/schema/index.js'\nimport { errorResponse, jsonResponse } from '../../../utils.js'\nimport { AdminUsersDeleteProcessContract } from '../../../../types/api/admin/users/delete/index.js'\n\nexport const silentOperation: AdminUsersDeleteProcessContract['operation'] = async ({ body, accessTokenPayload: { userId } }) => {\n const { _id } = body\n const attempt = await deleteOne<IBaseUser>(BaseUserModel, { _id }, { initiatorId: userId })\n if (!attempt.success) {\n const { code, message } = attempt.error\n return errorResponse(500, code, message)\n }\n const discriminated = discriminateUser(attempt.payload)\n if (discriminated === null) return errorResponse(404, Codes.DB_NO_DOCUMENT_MATCHES_FILTER, BaseUserModel.modelName, { _id })\n if (discriminated.authType === 'GoogleUser') return jsonResponse(200, googleUserToDTO(discriminated))\n return jsonResponse(200, localUserToDTO(discriminated))\n}\n\nexport const operation: AdminUsersDeleteProcessContract['operation'] = async hooks => {\n const result = await silentOperation(hooks)\n return result\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport zod from 'zod'\nimport { Codes } from '../../../../types/errors/index.js'\nimport { errorResponse, jsonResponse } from '../../../utils.js'\nimport { AdminUsersDeleteProcessContract } from '../../../../types/api/admin/users/delete/index.js'\n\nexport const validation: AdminUsersDeleteProcessContract['validation'] = async ({ body }) => {\n const bodyValSchema = zod.object({ _id: zod.string() })\n try {\n const validated = bodyValSchema.parse(body)\n return jsonResponse(200, {\n body: validated,\n query: {},\n params: {}\n })\n } catch (err) {\n const errStr = unknownToString(err)\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, errStr)\n }\n}\n", "import { AdminUsersDeleteProcessContract } from '../../../../types/api/admin/users/delete/index.js'\nimport { authentication } from './authentication.js'\nimport { operation } from './operation.js'\nimport { validation } from './validation.js'\n\nexport const deleteUser: AdminUsersDeleteProcessContract = {\n _authType: 'strong',\n _opType: 'json',\n authentication,\n validation,\n operation\n}\n", "import { allow } from '../../../../auth/index.js'\nimport { AdminUsersGetProcessContract } from '../../../../types/api/admin/users/get/index.js'\nimport { UserRole, UserStatus, UserBadge } from '../../../../types/schema/index.js'\n\nexport const authentication: AdminUsersGetProcessContract['authentication'] = allow({\n roles: [UserRole.ADMIN],\n statuses: [UserStatus.ACTIVE],\n badges: [UserBadge.ADMIN_USERS_CAN_GET],\n verified: true\n})\n", "import { findOne } from '../../../../database/index.js'\nimport { googleUserToDTO, localUserToDTO } from '../../../../transformers/user/index.js'\nimport { Codes } from '../../../../types/errors/index.js'\nimport { BaseUserModel, LocalUserModel, GoogleUserModel, discriminateUser } from '../../../../schema/user/user/index.js'\nimport { IGoogleUser, ILocalUser, IBaseUser } from '../../../../types/schema/index.js'\nimport { errorResponse, jsonResponse } from '../../../utils.js'\nimport { AdminUsersGetProcessContract } from '../../../../types/api/admin/users/get/index.js'\n\nexport const silentOperation: AdminUsersGetProcessContract['operation'] = async ({ body, accessTokenPayload: { userId } }) => {\n // _ID || Username\n if ('_id' in body || 'username' in body) {\n const { _id, username } = body as { _id?: string, username?: string }\n const filter = { _id, username }\n const lookup = await findOne<IBaseUser>(BaseUserModel, filter, { initiatorId: userId })\n if (!lookup.success) {\n const { code } = lookup.error\n if (code === Codes.DB_NO_DOCUMENT_MATCHES_FILTER) return errorResponse(404, code, BaseUserModel.modelName, filter)\n return errorResponse(500, code, 'Something went wrong with the db')\n }\n const discriminated = discriminateUser(lookup.payload)\n if (discriminated === null) return errorResponse(404, Codes.DB_NO_DOCUMENT_MATCHES_FILTER, BaseUserModel.modelName, filter)\n if (discriminated.authType === 'LocalUser') return jsonResponse(200, localUserToDTO(discriminated))\n return jsonResponse(200, googleUserToDTO(discriminated))\n\n // Email\n } else if ('email' in body) {\n const filter = { email: body.email }\n const lookup = await findOne<ILocalUser>(LocalUserModel, filter, { initiatorId: userId })\n if (!lookup.success) {\n const { code } = lookup.error\n if (code === Codes.DB_NO_DOCUMENT_MATCHES_FILTER) return errorResponse(404, code, LocalUserModel.modelName, filter)\n return errorResponse(500, code, 'Something went wrong with the db')\n }\n return jsonResponse(200, localUserToDTO(lookup.payload))\n\n // Google ID\n } else {\n const filter = { googleId: body.googleId }\n const lookup = await findOne<IGoogleUser>(GoogleUserModel, filter, { initiatorId: userId })\n if (!lookup.success) {\n const { code } = lookup.error\n if (code === Codes.DB_NO_DOCUMENT_MATCHES_FILTER) return errorResponse(404, code, GoogleUserModel.modelName, filter)\n return errorResponse(500, code, 'Something went wrong with the db')\n }\n return jsonResponse(200, googleUserToDTO(lookup.payload))\n }\n}\n\nexport const operation: AdminUsersGetProcessContract['operation'] = async hooks => {\n const result = await silentOperation(hooks)\n return result\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport zod from 'zod'\nimport { Codes } from '../../../../types/errors/index.js'\nimport { errorResponse, jsonResponse } from '../../../utils.js'\nimport { AdminUsersGetProcessContract } from '../../../../types/api/admin/users/get/index.js'\n\nexport const validation: AdminUsersGetProcessContract['validation'] = async ({ body }) => {\n const bodyValSchema = zod.union([\n zod.object({ _id: zod.string() }),\n zod.object({ username: zod.string() }),\n zod.object({ email: zod.string() }),\n zod.object({ googleId: zod.string() })\n ])\n try {\n const validated = bodyValSchema.parse(body)\n return jsonResponse(200, {\n body: validated,\n query: {},\n params: {}\n })\n } catch (err) {\n const errStr = unknownToString(err)\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, errStr)\n }\n}\n", "import { AdminUsersGetProcessContract } from '../../../../types/api/admin/users/get/index.js'\nimport { authentication } from './authentication.js'\nimport { operation } from './operation.js'\nimport { validation } from './validation.js'\n\nexport const get: AdminUsersGetProcessContract = {\n _authType: 'strong',\n _opType: 'json',\n authentication,\n validation,\n operation\n}\n", "import { allow } from '../../../../auth/index.js'\nimport { AdminUsersGetUplpadQuotaProcessContract } from '../../../../types/api/admin/users/get-upload-quota/index.js'\nimport { UserRole, UserStatus, UserBadge } from '../../../../types/schema/index.js'\n\nexport const authentication: AdminUsersGetUplpadQuotaProcessContract['authentication'] = allow({\n roles: [UserRole.ADMIN],\n statuses: [UserStatus.ACTIVE],\n badges: [UserBadge.ADMIN_USERS_CAN_GET_UPLOAD_QUOTA],\n verified: true\n})\n", "import { UserUploadQuotaToDTO } from '../../types/transformers/user-upload-quota/index.js'\n\nexport const userUploadQuotaToDTO: UserUploadQuotaToDTO = quota => {\n return {\n userId: quota.userId.toString(),\n dailyUploadsByteSize: quota.dailyUploadsByteSize,\n monthlyUploadsByteSize: quota.monthlyUploadsByteSize,\n totalUploadsByteSize: quota.totalUploadsByteSize\n }\n}\n", "import { findOne } from '../../../../database/index.js'\nimport { userUploadQuotaToDTO } from '../../../../transformers/user-upload-quota/index.js'\nimport { UserUploadQuotaModel } from '../../../../schema/user/upload-quota/index.js'\nimport { IUserUploadQuota } from '../../../../types/schema/index.js'\nimport { errorResponse, jsonResponse } from '../../../utils.js'\nimport { AdminUsersGetUplpadQuotaProcessContract } from '../../../../types/api/admin/users/get-upload-quota/index.js'\n\nexport const operation: AdminUsersGetUplpadQuotaProcessContract['operation'] = async ({ body, accessTokenPayload: { userId: adminUserId } }) => {\n const { userId } = body\n const lookup = await findOne<IUserUploadQuota>(\n UserUploadQuotaModel,\n { userId },\n { initiatorId: adminUserId }\n )\n if (!lookup.success) {\n const { code, message } = lookup.error\n return errorResponse(500, code, message)\n }\n return jsonResponse(200, userUploadQuotaToDTO(lookup.payload))\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport zod from 'zod'\nimport { Codes } from '../../../../types/errors/index.js'\nimport { errorResponse, jsonResponse } from '../../../utils.js'\nimport { AdminUsersGetUplpadQuotaProcessContract } from '../../../../types/api/admin/users/get-upload-quota/index.js'\n\nexport const validation: AdminUsersGetUplpadQuotaProcessContract['validation'] = async ({ body }) => {\n const bodyValSchema = zod.object({ userId: zod.string() })\n try {\n const validated = bodyValSchema.parse(body)\n return jsonResponse(200, {\n body: validated,\n query: {},\n params: {}\n })\n } catch (err) {\n const errStr = unknownToString(err)\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, errStr)\n }\n}\n", "import { AdminUsersGetUplpadQuotaProcessContract } from '../../../../types/api/admin/users/get-upload-quota/index.js'\nimport { authentication } from './authentication.js'\nimport { operation } from './operation.js'\nimport { validation } from './validation.js'\n\nexport const getUploadQuota: AdminUsersGetUplpadQuotaProcessContract = {\n _authType: 'strong',\n _opType: 'json',\n authentication,\n validation,\n operation\n}\n", "import { allow } from '../../../../auth/index.js'\nimport { AdminUsersListProcessContract } from '../../../../types/api/admin/users/list/index.js'\nimport { UserRole, UserStatus, UserBadge } from '../../../../types/schema/index.js'\n\nexport const authentication: AdminUsersListProcessContract['authentication'] = allow({\n roles: [UserRole.ADMIN],\n statuses: [UserStatus.ACTIVE],\n badges: [UserBadge.ADMIN_USERS_CAN_LIST],\n verified: true\n})\n", "import { URL } from 'node:url'\nimport { findMany } from '../../../../database/index.js'\nimport { googleUserToDTO, localUserToDTO } from '../../../../transformers/user/index.js'\nimport { LocalUserDTO, GoogleUserDTO } from '../../../../types/dto/index.js'\nimport { Codes } from '../../../../types/errors/index.js'\nimport { BaseUserModel, LocalUserModel, GoogleUserModel, discriminateUser } from '../../../../schema/user/user/index.js'\nimport { ILocalUser, IGoogleUser, IBaseUser } from '../../../../types/schema/index.js'\nimport { errorResponse, listResponse } from '../../../utils.js'\nimport { AdminUsersListProcessContract } from '../../../../types/api/admin/users/list/index.js'\n\nconst LIMIT = 100\n\nexport const silentOperation: AdminUsersListProcessContract['operation'] = async ({ body, query, accessTokenPayload: { userId }, originalUrl }) => {\n const { page: pageString = '0' } = query\n const pageNumber = parseInt(pageString)\n const page = Number.isNaN(pageNumber) ? 0 : pageNumber\n const {\n verified,\n usernameIncludes,\n hasAnyRole,\n hasAnyStatus,\n hasAllBadges,\n emailIncludes,\n googleIdIncludes,\n createdAfterTimestamp,\n createdBeforeTimestamp\n } = body\n\n // Prepare filters\n const verifiedFilter = verified === undefined ? undefined : verified\n const usernameFilter = usernameIncludes === undefined ? undefined : { $regex: usernameIncludes, $options: 'i' }\n const roleFilter = hasAnyRole === undefined ? undefined : { $in: hasAnyRole }\n const statusFilter = hasAnyStatus === undefined ? undefined : { $in: hasAnyStatus }\n const badgesFilter = hasAllBadges === undefined ? undefined : { $all: hasAllBadges }\n const emailFilter = emailIncludes === undefined ? undefined : { $regex: emailIncludes, $options: 'i' }\n const googleIdFilter = googleIdIncludes === undefined ? undefined : { $regex: googleIdIncludes, $options: 'i' }\n const shouldFilterMeta = createdAfterTimestamp !== undefined || createdBeforeTimestamp !== undefined\n const createdAfterFilter = createdAfterTimestamp !== undefined ? { $gte: new Date(createdAfterTimestamp) } : {}\n const createdBeforeFilter = createdBeforeTimestamp !== undefined ? { $lte: new Date(createdBeforeTimestamp) } : {}\n const metaFilter = shouldFilterMeta ? {\n '_meta.creationTime': {\n ...createdAfterFilter,\n ...createdBeforeFilter\n }\n } : {}\n\n const prevPageFullUrl = new URL(originalUrl, 'https://fakeurl.com')\n const nextPageFullUrl = new URL(originalUrl, 'https://fakeurl.com')\n prevPageFullUrl.searchParams.set('page', (page - 1).toString())\n nextPageFullUrl.searchParams.set('page', (page + 1).toString())\n const prevPageUrl = `${prevPageFullUrl.pathname}${prevPageFullUrl.search}`\n const nextPageUrl = `${nextPageFullUrl.pathname}${nextPageFullUrl.search}`\n\n /* * * * * * * * * * * * * * * \n * Local user lookup\n * * * * * * * * * * * * * * */\n if (emailIncludes !== undefined) {\n if (googleIdIncludes !== undefined) return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, 'Cannot filter by both email and googleId')\n const usersLookup = await findMany<ILocalUser>(LocalUserModel, {\n verified: verifiedFilter,\n username: usernameFilter,\n role: roleFilter,\n status: statusFilter,\n badges: badgesFilter,\n email: emailFilter,\n ...metaFilter\n }, { initiatorId: userId }, {\n limit: LIMIT,\n skip: page * LIMIT\n })\n if (!usersLookup.success) {\n const { code, message } = usersLookup.error\n if (code === Codes.DB_NO_DOCUMENT_MATCHES_FILTER) return listResponse(200, [], 0, 0, null, null)\n return errorResponse(500, code, message)\n }\n const {\n found,\n totalCount,\n prev,\n next\n } = usersLookup.payload\n const foundDTO = found.map(localUserToDTO)\n return listResponse(\n 200,\n foundDTO,\n page,\n totalCount,\n prev !== null ? prevPageUrl : null,\n next !== null ? nextPageUrl : null\n )\n\n /* * * * * * * * * * * * * * * \n * Google user lookup\n * * * * * * * * * * * * * * */\n } else if (googleIdIncludes !== undefined) {\n if (emailIncludes !== undefined) return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, 'Cannot filter by both email and googleId')\n const usersLookup = await findMany<IGoogleUser>(GoogleUserModel, {\n verified: verifiedFilter,\n username: usernameFilter,\n role: roleFilter,\n status: statusFilter,\n badges: badgesFilter,\n googleId: googleIdFilter,\n ...metaFilter\n }, { initiatorId: userId }, {\n limit: LIMIT,\n skip: page * LIMIT\n })\n if (!usersLookup.success) {\n const { code, message } = usersLookup.error\n if (code === Codes.DB_NO_DOCUMENT_MATCHES_FILTER) return listResponse(200, [], 0, 0, null, null)\n return errorResponse(500, code, message)\n }\n const {\n found,\n totalCount,\n prev,\n next\n } = usersLookup.payload\n const foundDTO = found.map(googleUserToDTO)\n return listResponse(\n 200,\n foundDTO,\n page,\n totalCount,\n prev !== null ? prevPageUrl : null,\n next !== null ? nextPageUrl : null\n )\n\n /* * * * * * * * * * * * * * * \n * Base user lookup\n * * * * * * * * * * * * * * */\n } else {\n const usersLookup = await findMany<IBaseUser>(BaseUserModel, {\n verified: verifiedFilter,\n username: usernameFilter,\n role: roleFilter,\n status: statusFilter,\n badges: badgesFilter,\n ...metaFilter\n }, { initiatorId: userId }, {\n limit: LIMIT,\n skip: page * LIMIT\n })\n if (!usersLookup.success) {\n const { code, message } = usersLookup.error\n if (code === Codes.DB_NO_DOCUMENT_MATCHES_FILTER) return listResponse(200, [], 0, 0, null, null)\n return errorResponse(500, code, message)\n }\n const {\n found,\n totalCount,\n prev,\n next\n } = usersLookup.payload\n const foundDTO = found.map(baseUser => {\n const discriminated = discriminateUser(baseUser)\n if (discriminated === null) return null\n if (discriminated.authType === 'LocalUser') return localUserToDTO(discriminated)\n return googleUserToDTO(discriminated)\n }).filter((user): user is LocalUserDTO | GoogleUserDTO => user !== null)\n return listResponse(\n 200,\n foundDTO,\n page,\n totalCount,\n prev !== null ? prevPageUrl : null,\n next !== null ? nextPageUrl : null\n )\n }\n}\n\nexport const operation: typeof silentOperation = async hooks => {\n const result = await silentOperation(hooks)\n return result\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport zod from 'zod'\nimport { Codes } from '../../../../types/errors/index.js'\nimport { ExtractExpectedBody, ExtractExpectedQuery } from '../../../../types/api/internals.js'\nimport { errorResponse, jsonResponse } from '../../../utils.js'\nimport { UserRole, UserStatus, UserBadge } from '../../../../types/schema/index.js'\nimport { AdminUsersListProcessContract } from '../../../../types/api/admin/users/list/index.js'\n\nexport const validation: AdminUsersListProcessContract['validation'] = async ({ body, query }) => {\n const bodyValSchema = zod.object({\n verified: zod.boolean().optional(),\n usernameIncludes: zod.string().optional(),\n hasAnyRole: zod.array(zod.nativeEnum(UserRole)).optional(),\n hasAnyStatus: zod.array(zod.nativeEnum(UserStatus)).optional(),\n hasAllBadges: zod.array(zod.nativeEnum(UserBadge)).optional(),\n emailIncludes: zod.string().optional(),\n googleIdIncludes: zod.string().optional(),\n createdAfterTimestamp: zod.number().optional(),\n createdBeforeTimestamp: zod.number().optional(),\n })\n const queryValSchema = zod.object({ page: zod.string().optional() })\n let bodyValidated: ExtractExpectedBody<AdminUsersListProcessContract>\n let queryValidated: ExtractExpectedQuery<AdminUsersListProcessContract>\n try { bodyValidated = bodyValSchema.parse(body) }\n catch (err) { return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, unknownToString(err)) }\n try { queryValidated = queryValSchema.parse(query) }\n catch (err) { return errorResponse(400, Codes.INVALID_REQUEST_QUERY, query, unknownToString(err)) }\n return jsonResponse(200, {\n body: bodyValidated,\n params: {},\n query: queryValidated\n })\n}\n", "import { AdminUsersListProcessContract } from '../../../../types/api/admin/users/list/index.js'\nimport { authentication } from './authentication.js'\nimport { operation } from './operation.js'\nimport { validation } from './validation.js'\n\nexport const list: AdminUsersListProcessContract = {\n _authType: 'strong',\n _opType: 'list',\n authentication,\n validation,\n operation\n}\n", "import { allow } from '../../../../auth/index.js'\nimport { AdminUsersResetUploadQuotaProcessContract } from '../../../../types/api/admin/users/reset-upload-quota/index.js'\nimport { UserRole, UserStatus, UserBadge } from '../../../../types/schema/index.js'\n\nexport const authentication: AdminUsersResetUploadQuotaProcessContract['authentication'] = allow({\n roles: [UserRole.ADMIN],\n statuses: [UserStatus.ACTIVE],\n badges: [UserBadge.ADMIN_USERS_CAN_RESET_USER_UPLOAD_QUOTA],\n verified: true\n})\n", "import { updateOne } from '../../../../database/index.js'\nimport { userUploadQuotaToDTO } from '../../../../transformers/user-upload-quota/index.js'\nimport { UserUploadQuotaModel } from '../../../../schema/user/upload-quota/index.js'\nimport { IUserUploadQuota } from '../../../../types/schema/index.js'\nimport { errorResponse, jsonResponse } from '../../../utils.js'\nimport { AdminUsersResetUploadQuotaProcessContract } from '../../../../types/api/admin/users/reset-upload-quota/index.js'\n\nexport const operation: AdminUsersResetUploadQuotaProcessContract['operation'] = async ({ body, accessTokenPayload: { userId: adminUserId } }) => {\n const updationAttempt = await updateOne<IUserUploadQuota>(\n UserUploadQuotaModel,\n { userId: body.userId }, {\n dailyUploadsByteSize: body.dailyUploadsByteSize ?? 0,\n monthlyUploadsByteSize: body.monthlyUploadsByteSize ?? 0,\n totalUploadsByteSize: body.totalUploadsByteSize ?? 0\n }, { initiatorId: adminUserId }\n )\n if (!updationAttempt.success) {\n const { code, message } = updationAttempt.error\n return errorResponse(500, code, message)\n }\n return jsonResponse(200, userUploadQuotaToDTO(updationAttempt.payload))\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport zod from 'zod'\nimport { Codes } from '../../../../types/errors/index.js'\nimport { errorResponse, jsonResponse } from '../../../utils.js'\nimport { AdminUsersResetUploadQuotaProcessContract } from '../../../../types/api/admin/users/reset-upload-quota/index.js'\n\nexport const validation: AdminUsersResetUploadQuotaProcessContract['validation'] = async ({ body }) => {\n const bodyValSchema = zod.object({\n userId: zod.string(),\n dailyUploadsByteSize: zod.number().optional(),\n monthlyUploadsByteSize: zod.number().optional(),\n totalUploadsByteSize: zod.number().optional()\n })\n try {\n const validated = bodyValSchema.parse(body)\n return jsonResponse(200, {\n body: validated,\n query: {},\n params: {}\n })\n } catch (err) {\n const errStr = unknownToString(err)\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, errStr)\n }\n}\n", "import { AdminUsersResetUploadQuotaProcessContract } from '../../../../types/api/admin/users/reset-upload-quota/index.js'\nimport { authentication } from './authentication.js'\nimport { operation } from './operation.js'\nimport { validation } from './validation.js'\n\nexport const resetUploadQuota: AdminUsersResetUploadQuotaProcessContract = {\n _authType: 'strong',\n _opType: 'json',\n authentication,\n validation,\n operation\n}", "import { allow } from '../../../../auth/index.js'\nimport { AdminUsersRevokeAuthTokensProcessContract } from '../../../../types/api/admin/users/revoke-auth-tokens/index.js'\nimport { UserRole, UserStatus, UserBadge } from '../../../../types/schema/index.js'\n\nexport const authentication: AdminUsersRevokeAuthTokensProcessContract['authentication'] = allow({\n roles: [UserRole.ADMIN],\n statuses: [UserStatus.ACTIVE],\n badges: [UserBadge.ADMIN_USERS_CAN_REVOKE_AUTH_TOKENS],\n verified: true\n})\n", "import { deleteMany, findMany, insertMany } from '../../../../database/index.js'\nimport { Codes } from '../../../../types/errors/index.js'\nimport { UserAuthTokenModel } from '../../../../schema/user/auth-token/index.js'\nimport { UserRevokedAuthTokenModel } from '../../../../schema/user/revoked-auth-token/index.js'\nimport { IUserAuthToken, IUserRevokedAuthToken } from '../../../../types/schema/index.js'\nimport { errorResponse, voidResponse } from '../../../utils.js'\nimport { AdminUsersRevokeAuthTokensProcessContract } from '../../../../types/api/admin/users/revoke-auth-tokens/index.js'\n\nexport const silentOperation: AdminUsersRevokeAuthTokensProcessContract['operation'] = async ({ body, accessTokenPayload: { userId } }) => {\n\n // Find current tokens\n const authTokensLookup = await findMany<IUserAuthToken>(UserAuthTokenModel, { userId: body.userId }, { initiatorId: userId }, { limit: 1000 })\n if (!authTokensLookup.success) {\n const { code, message } = authTokensLookup.error\n if (code === Codes.DB_NO_DOCUMENT_MATCHES_FILTER) return voidResponse()\n return errorResponse(500, code, message)\n }\n const { found: authTokens } = authTokensLookup.payload\n if (authTokens.length === 0) return voidResponse()\n \n // Delete current tokens\n const deletionAttempt = await deleteMany<IUserAuthToken>(UserAuthTokenModel, { userId: body.userId }, { initiatorId: userId })\n if (!deletionAttempt.success) {\n const { code, message } = deletionAttempt.error\n return errorResponse(500, code, message)\n }\n\n // Save to revoked tokens\n const tonInsertInRevoked = authTokens.map(({ value, userId }) => ({ value, userId, revokedOn: new Date() }))\n const insertionToRevoked = await insertMany<IUserRevokedAuthToken>(UserRevokedAuthTokenModel, tonInsertInRevoked, { initiatorId: userId })\n if (insertionToRevoked.success) return voidResponse()\n const { code, message } = insertionToRevoked.error\n return errorResponse(500, code, message)\n}\n\nexport const operation: typeof silentOperation = async hooks => {\n const result = await silentOperation(hooks)\n return result\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport zod from 'zod'\nimport { Codes } from '../../../../types/errors/index.js'\nimport { errorResponse, jsonResponse } from '../../../utils.js'\nimport { AdminUsersRevokeAuthTokensProcessContract } from '../../../../types/api/admin/users/revoke-auth-tokens/index.js'\n\nexport const validation: AdminUsersRevokeAuthTokensProcessContract['validation'] = async ({ body }) => {\n const bodyValSchema = zod.object({ userId: zod.string() })\n try {\n const validated = bodyValSchema.parse(body)\n return jsonResponse(200, {\n body: validated,\n query: {},\n params: {}\n })\n } catch (err) {\n const errStr = unknownToString(err)\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, errStr)\n }\n}\n", "import { AdminUsersRevokeAuthTokensProcessContract } from '../../../../types/api/admin/users/revoke-auth-tokens/index.js'\nimport { authentication } from './authentication.js'\nimport { operation } from './operation.js'\nimport { validation } from './validation.js'\n\nexport const revokeAuthTokens: AdminUsersRevokeAuthTokensProcessContract = {\n _authType: 'strong',\n _opType: 'void',\n authentication,\n validation,\n operation\n}", "import { allow } from '../../../../auth/index.js'\nimport { AdminUsersRevokeEmailValidationTokensProcessContract } from '../../../../types/api/admin/users/revoke-email-validation-tokens/index.js'\nimport { UserRole, UserStatus, UserBadge } from '../../../../types/schema/index.js'\n\nexport const authentication: AdminUsersRevokeEmailValidationTokensProcessContract['authentication'] = allow({\n roles: [UserRole.ADMIN],\n statuses: [UserStatus.ACTIVE],\n badges: [UserBadge.ADMIN_USERS_CAN_REVOKE_EMAIL_VALIDATION_TOKENS],\n verified: true\n})\n", "import { deleteMany } from '../../../../database/index.js'\nimport { UserEmailValidationTokenModel } from '../../../../schema/user/email-validation-token/index.js'\nimport { IUserEmailValidationToken } from '../../../../types/schema/index.js'\nimport { errorResponse, voidResponse } from '../../../utils.js'\nimport { AdminUsersRevokeEmailValidationTokensProcessContract } from '../../../../types/api/admin/users/revoke-email-validation-tokens/index.js'\n\nexport const operation: AdminUsersRevokeEmailValidationTokensProcessContract['operation'] = async ({body, accessTokenPayload: { userId }}) => {\n const deletionAttempt = await deleteMany<IUserEmailValidationToken>(\n UserEmailValidationTokenModel,\n { email: body.email },\n { initiatorId: userId }\n )\n if (!deletionAttempt.success) {\n const { code, message } = deletionAttempt.error\n return errorResponse(500, code, message)\n }\n return voidResponse() \n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport zod from 'zod'\nimport { Codes } from '../../../../types/errors/index.js'\nimport { errorResponse, jsonResponse } from '../../../utils.js'\nimport { AdminUsersRevokeEmailValidationTokensProcessContract } from '../../../../types/api/admin/users/revoke-email-validation-tokens/index.js'\n\nexport const validation: AdminUsersRevokeEmailValidationTokensProcessContract['validation'] = async ({ body }) => {\n const bodyValSchema = zod.object({ email: zod.string() })\n try {\n const validated = bodyValSchema.parse(body)\n return jsonResponse(200, {\n body: validated,\n query: {},\n params: {}\n })\n } catch (err) {\n const errStr = unknownToString(err)\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, errStr)\n }\n}\n", "import { AdminUsersRevokeEmailValidationTokensProcessContract } from '../../../../types/api/admin/users/revoke-email-validation-tokens/index.js'\nimport { authentication } from './authentication.js'\nimport { operation } from './operation.js'\nimport { validation } from './validation.js'\n\nexport const revokeEmailValidationTokens: AdminUsersRevokeEmailValidationTokensProcessContract = {\n _authType: 'strong',\n _opType: 'void',\n authentication,\n validation,\n operation\n}\n", "import { allow } from '../../../../auth/index.js'\nimport { AdminUsersRevokePasswordRenewalTokensProcessContract } from '../../../../types/api/admin/users/revoke-pasword-renewal-tokens/index.js'\nimport { UserRole, UserStatus, UserBadge } from '../../../../types/schema/index.js'\n\nexport const authentication: AdminUsersRevokePasswordRenewalTokensProcessContract['authentication'] = allow({\n roles: [UserRole.ADMIN],\n statuses: [UserStatus.ACTIVE],\n badges: [UserBadge.ADMIN_USERS_CAN_REVOKE_PASSWORD_RENEWAL_TOKENS],\n verified: true\n})\n", "import { deleteMany } from '../../../../database/index.js'\nimport { UserPasswordRenewalTokenModel } from '../../../../schema/user/password-renewal-token/index.js'\nimport { IUserPasswordRenewalToken } from '../../../../types/schema/index.js'\nimport { errorResponse, voidResponse } from '../../../utils.js'\nimport { AdminUsersRevokePasswordRenewalTokensProcessContract } from '../../../../types/api/admin/users/revoke-pasword-renewal-tokens/index.js'\n\nexport const operation: AdminUsersRevokePasswordRenewalTokensProcessContract['operation'] = async ({ body, accessTokenPayload: { userId } }) => {\n const deletionAttempt = await deleteMany<IUserPasswordRenewalToken>(\n UserPasswordRenewalTokenModel,\n { email: body.email },\n { initiatorId: userId }\n )\n if (deletionAttempt.success) return voidResponse()\n const { code, message } = deletionAttempt.error\n return errorResponse(500, code, message)\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport zod from 'zod'\nimport { Codes } from '../../../../types/errors/index.js'\nimport { errorResponse, jsonResponse } from '../../../utils.js'\nimport { AdminUsersRevokePasswordRenewalTokensProcessContract } from '../../../../types/api/admin/users/revoke-pasword-renewal-tokens/index.js'\n\nexport const validation: AdminUsersRevokePasswordRenewalTokensProcessContract['validation'] = async ({ body }) => {\n const bodyValSchema = zod.object({ email: zod.string() })\n try {\n const validated = bodyValSchema.parse(body)\n return jsonResponse(200, {\n body: validated,\n query: {},\n params: {}\n })\n } catch (err) {\n const errStr = unknownToString(err)\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, errStr)\n }\n}\n", "import { AdminUsersRevokePasswordRenewalTokensProcessContract } from '../../../../types/api/admin/users/revoke-pasword-renewal-tokens/index.js'\nimport { authentication } from './authentication.js'\nimport { operation } from './operation.js'\nimport { validation } from './validation.js'\n\nexport const revokePasswordRenewalTokens: AdminUsersRevokePasswordRenewalTokensProcessContract = {\n _authType: 'strong',\n _opType: 'void',\n authentication,\n validation,\n operation\n}\n", "import { allow } from '../../../../auth/index.js'\nimport { AdminUsersUpdateProcessContract } from '../../../../types/api/admin/users/update/index.js'\nimport { UserRole, UserStatus, UserBadge } from '../../../../types/schema/index.js'\n\nexport const authentication: AdminUsersUpdateProcessContract['authentication'] = allow({\n roles: [UserRole.ADMIN],\n statuses: [UserStatus.ACTIVE],\n badges: [UserBadge.ADMIN_USERS_CAN_UPDATE],\n verified: true\n})\n", "import bcrypt from 'bcrypt'\nimport { updateOne } from '../../../../database/index.js'\nimport { googleUserToDTO, localUserToDTO } from '../../../../transformers/user/index.js'\nimport { Codes } from '../../../../types/errors/index.js'\nimport { LocalUserModel, GoogleUserModel } from '../../../../schema/user/user/index.js'\nimport { IGoogleUser, ILocalUser } from '../../../../types/schema/index.js'\nimport { errorResponse, jsonResponse } from '../../../utils.js'\nimport { AdminUsersUpdateProcessContract } from '../../../../types/api/admin/users/update/index.js'\n\nexport const silentOperation: AdminUsersUpdateProcessContract['operation'] = async ({ body, accessTokenPayload: { userId } }) => {\n if ('googleId' in body) {\n if ('verified' in body) return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, 'Cannot set verified for Google users after creation')\n if ('email' in body) return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, 'Cannot set email for Google users')\n if ('password' in body) return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, 'Cannot set password for Google users')\n const updateQuery = {\n username: body.username,\n role: body.role,\n status: body.status,\n googleId: body.googleId\n }\n if (body.setBadges !== undefined) (updateQuery as any).badges = body.setBadges\n if (body.addBadges !== undefined) (updateQuery as any).$push = { badges: { $each: body.addBadges } }\n if (body.removeBadges !== undefined) (updateQuery as any).$pull = { badges: { $in: body.removeBadges } }\n const updationAttempt = await updateOne<IGoogleUser>(GoogleUserModel, { _id: body._id }, updateQuery, { initiatorId: userId })\n if (!updationAttempt.success) {\n const { code, message } = updationAttempt.error\n return errorResponse(500, code, message)\n }\n return jsonResponse(200, googleUserToDTO(updationAttempt.payload))\n } else {\n const updateQuery = {\n username: body.username,\n role: body.role,\n status: body.status,\n email: body.email,\n verified: body.verified,\n _password: body.password !== undefined\n ? await bcrypt.hash(body.password, 10)\n : undefined\n }\n if (body.setBadges !== undefined) (updateQuery as any).badges = body.setBadges\n if (body.addBadges !== undefined) (updateQuery as any).$push = { badges: { $each: body.addBadges } }\n if (body.removeBadges !== undefined) (updateQuery as any).$pull = { badges: { $in: body.removeBadges } }\n const updationAttempt = await updateOne<ILocalUser>(LocalUserModel, { _id: body._id }, updateQuery, { initiatorId: userId })\n if (!updationAttempt.success) {\n const { code, message } = updationAttempt.error\n return errorResponse(500, code, message)\n }\n return jsonResponse(200, localUserToDTO(updationAttempt.payload))\n }\n}\n\nexport const operation: typeof silentOperation = async hooks => {\n const result = await silentOperation(hooks)\n return result\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport zod from 'zod'\nimport { Codes } from '../../../../types/errors/index.js'\nimport { errorResponse, jsonResponse } from '../../../utils.js'\nimport { UserRole, UserStatus, UserBadge } from '../../../../types/schema/index.js'\nimport { AdminUsersUpdateProcessContract } from '../../../../types/api/admin/users/update/index.js'\n\nexport const validation: AdminUsersUpdateProcessContract['validation'] = async ({ body }) => {\n const bodyValSchema = zod.object({\n _id: zod.string(),\n username: zod.string().optional(),\n role: zod.nativeEnum(UserRole).optional(),\n status: zod.nativeEnum(UserStatus).optional(),\n addBadges: zod.array(zod.nativeEnum(UserBadge)).optional(),\n removeBadges: zod.array(zod.nativeEnum(UserBadge)).optional(),\n setBadges: zod.array(zod.nativeEnum(UserBadge)).optional(),\n verified: zod.boolean().optional(),\n email: zod.string().email().optional(),\n password: zod.string().optional(),\n googleId: zod.string().optional()\n })\n try {\n const validated = bodyValSchema.parse(body)\n return jsonResponse(200, {\n body: validated,\n query: {},\n params: {}\n })\n } catch (err) {\n const errStr = unknownToString(err)\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, errStr)\n }\n}\n", "import { AdminUsersUpdateProcessContract } from '../../../../types/api/admin/users/update/index.js'\nimport { authentication } from './authentication.js'\nimport { operation } from './operation.js'\nimport { validation } from './validation.js'\n\nexport const update: AdminUsersUpdateProcessContract = {\n _authType: 'strong',\n _opType: 'json',\n authentication,\n validation,\n operation\n}\n", "import { create } from './create/index.js'\nimport { deleteUser } from './delete/index.js'\nimport { get } from './get/index.js'\nimport { getUploadQuota } from './get-upload-quota/index.js'\nimport { list } from './list/index.js'\nimport { resetUploadQuota } from './reset-upload-quota/index.js'\nimport { revokeAuthTokens } from './revoke-auth-tokens/index.js'\nimport { revokeEmailValidationTokens } from './revoke-email-validation-tokens/index.js'\nimport { revokePasswordRenewalTokens } from './revoke-password-renewal-tokens/index.js'\nimport { update } from './update/index.js'\n\nexport const users = {\n create,\n delete: deleteUser,\n get,\n getUploadQuota,\n list,\n resetUploadQuota,\n revokeAuthTokens,\n revokeEmailValidationTokens,\n revokePasswordRenewalTokens,\n update\n}\n", "import { temp } from './temp/index.js'\nimport { users } from './users/index.js'\n\nexport const admin = {\n temp,\n users\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport { isNonNullObject } from '@design-edito/tools/agnostic/objects/is-object/index.js'\nimport validator from 'validator'\nimport zod from 'zod'\nimport { Codes } from '../../../types/errors/index.js'\nimport { errorResponse, jsonResponse } from '../../utils.js'\nimport { AuthLoginProcessContract } from '../../../types/api/auth/login/index.js'\n\nexport const validation: AuthLoginProcessContract['validation'] = async ({ body, params, query }) => {\n if (!isNonNullObject(body)) return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, 'Invalid request body')\n if ('email' in body) {\n const withEmailSchema = zod.object({\n email: zod\n .string()\n .email('Invalid email format'),\n password: zod\n .string()\n .min(1, 'Password must be at least one character long')\n })\n try {\n const withEmailValidated = withEmailSchema.parse(body)\n return jsonResponse(200, {\n body: withEmailValidated,\n query,\n params\n })\n } catch (err) {\n const errStr = unknownToString(err)\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, errStr)\n }\n } else if ('username' in body) {\n const withUsernameSchema = zod.object({\n username: zod.string()\n .min(1)\n .refine(\n input => validator\n .isSlug(input.toLowerCase()),\n { message: 'Username must contain alphanumeric or non starting, trailing nor consecutive hyphens or underscores' }\n ),\n password: zod\n .string()\n .min(1, 'Password must be at least one character long')\n })\n try {\n const withUsernameValidated = withUsernameSchema.parse(body)\n return jsonResponse(200, {\n body: withUsernameValidated,\n query,\n params\n })\n } catch (err) {\n const errStr = unknownToString(err)\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, errStr)\n }\n } else {\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, 'Missing username or email property')\n }\n}\n", "import bcrypt from 'bcrypt'\nimport {\n attachAccessTokenToRes,\n attachRefreshTokenToRes,\n generateAccessToken,\n generateRefreshToken,\n} from '../../../auth/index.js'\nimport { findOne } from '../../../database/index.js'\nimport env from '../../../env/index.js'\nimport { Codes } from '../../../types/errors/index.js'\nimport {\n logError,\n logInfo\n} from '../../../logs/index.js'\nimport { Category as LogCategory } from '../../../types/logs/index.js'\nimport { LocalUserModel } from '../../../schema/user/user/index.js'\nimport { ILocalUser, UserRole } from '../../../types/schema/index.js'\nimport { errorResponse, jsonResponse } from '../../utils.js'\nimport { localUserToDTO } from '../../../transformers/user/index.js'\nimport { AuthLoginProcessContract } from '../../../types/api/auth/login/index.js'\n\nexport const silentOperation: AuthLoginProcessContract['operation'] = async ({ body, setCookie, setHeader }) => {\n const { password } = body\n const query = 'email' in body ? { email: body.email } : { username: body.username }\n const foundUser = await findOne<ILocalUser>(LocalUserModel, query, { initiatorId: env.ROOT_USER_ID })\n if (!foundUser.success) {\n const err = foundUser.error\n if (err.code === Codes.DB_ERROR) return errorResponse(500, Codes.DB_ERROR, err.details.dbError)\n return errorResponse(401, Codes.INVALID_CREDENTIALS)\n }\n const passwordsMatch = await bcrypt.compare(password, foundUser.payload._password)\n if (!passwordsMatch) return errorResponse(401, Codes.INVALID_CREDENTIALS)\n const userData = foundUser.payload\n const userIsAdmin = userData.role === UserRole.ADMIN || userData.role === UserRole.ROOT\n const userId = userData._id.toString()\n const accessToken = await generateAccessToken(userId, 0)\n const refreshToken = await generateRefreshToken(userId, 0)\n if (!accessToken.success) return errorResponse(500, Codes.USER_ACCESS_TOKEN_GENERATION_FAILED, 'Could not generate access token')\n if (!refreshToken.success) return errorResponse(500, Codes.USER_REFRESH_TOKEN_GENERATION_FAILED, 'Could not generate refresh token')\n attachAccessTokenToRes(setHeader, accessToken.payload)\n attachRefreshTokenToRes(setCookie, refreshToken.payload, userIsAdmin)\n return jsonResponse(200, localUserToDTO(userData))\n}\n\nexport const operation: typeof silentOperation = async hooks => {\n const result = await silentOperation(hooks)\n const providedUsername = 'username' in hooks.body ? hooks.body.username : undefined\n const providedEmail = 'email' in hooks.body ? hooks.body.email : undefined\n const {\n DB_ERROR,\n USER_ACCESS_TOKEN_GENERATION_FAILED: ACCESS_TOKEN_ERR,\n USER_REFRESH_TOKEN_GENERATION_FAILED: REFRESH_TOKEN_ERR\n } = Codes\n if (result.type === 'json') logInfo(LogCategory.USER_LOGIN, 'User logged in', { user: result.payload })\n else if (result.code === DB_ERROR) logError(LogCategory.USER_LOGIN, 'DB error', {\n providedUsername,\n providedEmail,\n error: {\n code: result.code,\n message: result.message,\n details: result.details\n }\n })\n else if (result.code === ACCESS_TOKEN_ERR) logError(LogCategory.USER_LOGIN, 'Access token generation error', {\n providedUsername,\n providedEmail,\n error: {\n code: result.code,\n message: result.message,\n details: result.details\n }\n })\n else if (result.code === REFRESH_TOKEN_ERR) logError(LogCategory.USER_LOGIN, 'Refresh token generation error', {\n providedUsername,\n providedEmail,\n error: {\n code: result.code,\n message: result.message,\n details: result.details\n }\n })\n return result\n}\n", "import { validation } from './validation.js'\nimport { operation } from './operation.js'\nimport { AuthLoginProcessContract } from '../../../types/api/auth/login/index.js'\n\nexport const login: AuthLoginProcessContract = { \n _authType: 'none',\n _opType: 'json',\n validation: validation,\n operation: operation\n}\n", "import { AuthLogoutProcessContract } from '../../../types/api/auth/logout/index.js'\nimport { jsonResponse } from '../../utils.js'\n\nexport const authentication: AuthLogoutProcessContract['authentication'] = async ({\n accessTokenSigned,\n accessTokenPayload\n}) => jsonResponse(200, {\n accessTokenSigned,\n accessTokenPayload\n})\n", "import jwt from 'jsonwebtoken'\nimport { isValidPayload, revokeUserTokens } from '../../../auth/index.js'\nimport env from '../../../env/index.js'\nimport { Codes } from '../../../types/errors/index.js'\nimport { errorResponse, voidResponse } from '../../utils.js'\nimport { logInfo, logError } from '../../../logs/index.js'\nimport { Category as LogCategory } from '../../../types/logs/index.js'\nimport { AuthLogoutProcessContract } from '../../../types/api/auth/logout/index.js'\n\nexport const silentOperation: AuthLogoutProcessContract['operation'] = async ({ cookies, accessTokenSigned }) => {\n const { refreshToken: refreshTokenSigned } = cookies\n const accessTokenDecoded = jwt.verify(accessTokenSigned, env.JWT_SECRET)\n if (!isValidPayload(accessTokenDecoded)) return errorResponse(401, Codes.USER_NOT_AUTHENTICATED, 'Access token is invalid')\n const { userId } = accessTokenDecoded\n const toRevoke: string[] = []\n if (accessTokenSigned !== undefined) toRevoke.push(accessTokenSigned)\n if (refreshTokenSigned !== undefined) toRevoke.push(refreshTokenSigned)\n const revoked = await revokeUserTokens(userId, toRevoke)\n if (!revoked.success) return errorResponse(500, Codes.USER_TOKENS_REVOCATION_FAILED, userId, toRevoke)\n return voidResponse()\n}\n\nexport const operation: typeof silentOperation = async hooks => {\n const result = await silentOperation(hooks)\n const { accessTokenPayload } = hooks\n const { userId } = accessTokenPayload\n if (result.type === 'void') logInfo(LogCategory.USER_LOGOUT, 'User logged out', { userId })\n else if (result.code === Codes.USER_TOKENS_REVOCATION_FAILED) logError(LogCategory.USER_LOGOUT, 'Could not revoke tokens', {\n userId,\n accessToken: hooks.accessTokenSigned,\n refreshToken: hooks.cookies.refreshToken\n })\n return result\n}\n", "import { AuthLogoutProcessContract } from '../../../types/api/auth/logout/index.js'\nimport { authentication } from './authentication.js'\nimport { weakAuthNullValidation } from '../../../validation/index.js'\nimport { operation } from './operation.js'\n\nexport const logout: AuthLogoutProcessContract = {\n _authType: 'weak',\n _opType: 'void',\n authentication: authentication,\n validation: weakAuthNullValidation,\n operation: operation\n}\n", "import { AuthLogoutEverywhereProcessContract } from '../../../types/api/auth/logout-everywhere/index.js'\nimport { jsonResponse } from '../../utils.js'\n\nexport const authentication: AuthLogoutEverywhereProcessContract['authentication'] = async ({\n accessTokenSigned,\n accessTokenPayload\n}) => jsonResponse(200, {\n accessTokenSigned,\n accessTokenPayload\n})\n", "import { Codes } from '../../../types/errors/index.js'\nimport { errorResponse, voidResponse } from '../../utils.js'\nimport { revokeAllUserAuthTokens } from '../../../auth/index.js'\nimport { logError, logInfo } from '../../../logs/index.js'\nimport { Category as LogCategory } from '../../../types/logs/index.js'\nimport { AuthLogoutEverywhereProcessContract } from '../../../types/api/auth/logout-everywhere/index.js'\n\nexport const silentOperation: AuthLogoutEverywhereProcessContract['operation'] = async ({\n accessTokenSigned,\n accessTokenPayload,\n cookies\n}) => {\n if (accessTokenSigned === undefined) return errorResponse(401, Codes.USER_NOT_AUTHENTICATED, 'Access token is missing')\n if (accessTokenPayload === undefined) return errorResponse(401, Codes.USER_NOT_AUTHENTICATED, 'Access token is missing')\n const { userId } = accessTokenPayload\n const { refreshToken: refreshTokenSigned } = cookies\n const toRevoke: string[] = []\n if (typeof accessTokenSigned === 'string') toRevoke.push(accessTokenSigned)\n if (typeof refreshTokenSigned === 'string') toRevoke.push(refreshTokenSigned)\n const revoked = await revokeAllUserAuthTokens(userId, toRevoke)\n if (!revoked.success) return errorResponse(500, Codes.USER_TOKENS_REVOCATION_FAILED, userId, toRevoke)\n return voidResponse()\n}\n\nexport const operation: typeof silentOperation = async hooks => {\n const result = await silentOperation(hooks)\n const { accessTokenPayload } = hooks\n const { userId } = accessTokenPayload\n if (result.type === 'void') logInfo(LogCategory.USER_LOGOUT, 'User logged out', { userId })\n else if (result.code === Codes.USER_TOKENS_REVOCATION_FAILED) logError(LogCategory.USER_LOGOUT, 'Could not revoke tokens', {\n userId,\n accessToken: hooks.accessTokenSigned,\n refreshToken: hooks.cookies.refreshToken\n })\n return result\n}\n", "import { AuthLogoutEverywhereProcessContract } from '../../../types/api/auth/logout-everywhere/index.js'\nimport { weakAuthNullValidation } from '../../../validation/index.js'\nimport { authentication } from './authentication.js'\nimport { operation } from './operation.js'\n\nexport const logoutEverywhere: AuthLogoutEverywhereProcessContract = {\n _authType: 'weak',\n _opType: 'void',\n authentication,\n validation: weakAuthNullValidation,\n operation\n}\n", "import jwt from 'jsonwebtoken'\nimport {\n isValidPayload,\n generateAccessToken,\n generateRefreshToken,\n attachAccessTokenToRes,\n attachRefreshTokenToRes\n} from '../../../auth/index.js'\nimport { findOne } from '../../../database/index.js'\nimport env from '../../../env/index.js'\nimport { Codes } from '../../../types/errors/index.js'\nimport { UserRevokedAuthTokenModel } from '../../../schema/user/revoked-auth-token/index.js'\nimport { BaseUserModel } from '../../../schema/user/user/index.js'\nimport { IBaseUser, IUserRevokedAuthToken, UserRole } from '../../../types/schema/index.js'\nimport { errorResponse, voidResponse } from '../../utils.js'\nimport { logError, logInfo, logWarning } from '../../../logs/index.js'\nimport { Category as LogCategory } from '../../../types/logs/index.js'\nimport { AuthRefreshTokenProcessContract } from '../../../types/api/auth/refresh-token/index.js'\n\nexport const silentOperation: AuthRefreshTokenProcessContract['operation'] = async ({ cookies, setHeader, setCookie }) => {\n const tokenIsString = typeof cookies?.refreshToken === 'string'\n if (!tokenIsString) return errorResponse(401, Codes.USER_REFRESH_TOKEN_MISSING)\n const foundRevokedToken = await findOne<IUserRevokedAuthToken>(UserRevokedAuthTokenModel, { value: cookies.refreshToken }, { initiatorId: env.ROOT_USER_ID })\n if (foundRevokedToken.success) return errorResponse(401, Codes.USER_REFRESH_TOKEN_REVOKED)\n try { // [WIP] should narrow down the try/catch scope to jwt.verify\n const decoded = jwt.verify(cookies.refreshToken, env.JWT_SECRET)\n if (!isValidPayload(decoded)) return errorResponse(401, Codes.USER_REFRESH_TOKEN_MALFORMED)\n const { userId, exp, refreshCount } = decoded\n const now = Math.floor(Date.now() / 1000)\n const tokenHasExpired = now >= exp\n if (tokenHasExpired) return errorResponse(401, Codes.USER_REFRESH_TOKEN_EXPIRED)\n if (refreshCount >= env.REFRESH_TOKEN_MAX_REFRESH_COUNT) return errorResponse(401, Codes.USER_NOT_AUTHENTICATED, 'Refresh token has reached maximum refresh count')\n const foundUser = await findOne<IBaseUser>(BaseUserModel, { _id: userId }, { initiatorId: env.ROOT_USER_ID })\n if (!foundUser.success) return errorResponse(401, Codes.USER_DOES_NOT_EXIST, userId)\n const userData = foundUser.payload\n const userIsAdmin = userData.role === UserRole.ADMIN || userData.role === UserRole.ROOT\n const newAccessToken = await generateAccessToken(userId, 0)\n const newRefreshToken = await generateRefreshToken(userId, refreshCount + 1)\n if (!newAccessToken.success) return errorResponse(500, Codes.USER_ACCESS_TOKEN_GENERATION_FAILED, userId, newAccessToken.error.message)\n if (!newRefreshToken.success) return errorResponse(500, Codes.USER_REFRESH_TOKEN_GENERATION_FAILED, userId, newRefreshToken.error.message)\n attachAccessTokenToRes(setHeader, newAccessToken.payload)\n attachRefreshTokenToRes(setCookie, newRefreshToken.payload, userIsAdmin)\n return voidResponse()\n } catch (err) {\n return errorResponse(401, Codes.USER_NOT_AUTHENTICATED, `Bad refresh token: ${err}`)\n }\n}\n\nexport const operation: typeof silentOperation = async hooks => {\n const result = await silentOperation(hooks)\n if (result.type === 'void') {\n try {\n const decoded = jwt.verify(hooks.cookies.refreshToken, env.JWT_SECRET)\n if (!isValidPayload(decoded)) throw null\n const { userId, exp, refreshCount } = decoded\n logInfo(LogCategory.USER_TOKENS_RENEWAL, 'Successfully refreshed tokens', {\n userId,\n exp,\n refreshCount,\n previousRefreshToken: hooks.cookies.refreshToken\n })\n return result\n }\n catch {\n logWarning(LogCategory.USER_TOKENS_RENEWAL, 'Invalid refresh token when logging but operation was successful, this should not happen')\n return result\n }\n }\n if (\n result.code === Codes.USER_REFRESH_TOKEN_MALFORMED\n || result.code === Codes.USER_REFRESH_TOKEN_EXPIRED\n || result.code === Codes.USER_DOES_NOT_EXIST\n || result.code === Codes.USER_ACCESS_TOKEN_GENERATION_FAILED\n || result.code === Codes.USER_REFRESH_TOKEN_GENERATION_FAILED\n ) logError(LogCategory.USER_TOKENS_RENEWAL, 'Problem while refreshing user tokens', {\n error: {\n code: result.code,\n message: result.message,\n details: result.details\n }\n })\n return result\n}\n", "import { AuthRefreshTokenProcessContract } from '../../../types/api/auth/refresh-token/index.js'\nimport { noAuthNullValidation } from '../../../validation/index.js'\nimport { operation } from './operation.js'\n\nexport const refreshToken: AuthRefreshTokenProcessContract = {\n _authType: 'none',\n _opType: 'void',\n skipCsrfProtection: true,\n validation: noAuthNullValidation,\n operation\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport zod from 'zod'\nimport { Codes } from '../../../types/errors/index.js'\nimport { errorResponse, jsonResponse } from '../../utils.js'\nimport { AuthRequestEmailVerificationTokenProcessContract } from '../../../types/api/auth/request-email-verification-token/index.js'\n\nexport const validation: AuthRequestEmailVerificationTokenProcessContract['validation'] = async ({ body }) => {\n const validationSchema = zod.object({\n email: zod\n .string()\n .email('Invalid email format')\n })\n try {\n const validated = validationSchema.parse(body)\n return jsonResponse(200, {\n body: validated,\n params: {},\n query: {}\n })\n } catch (err) {\n const errStr = unknownToString(err)\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, errStr)\n }\n}\n", "import { createAndSendUserEmailValidationToken } from '../../../auth/index.js'\nimport { findOne, deleteMany } from '../../../database/index.js'\nimport env from '../../../env/index.js'\nimport { Codes } from '../../../types/errors/index.js'\nimport { logInfo } from '../../../logs/index.js'\nimport { Category as LogCategory } from '../../../types/logs/index.js'\nimport { LocalUserModel } from '../../../schema/user/user/index.js'\nimport { UserEmailValidationTokenModel } from '../../../schema/user/email-validation-token/index.js'\nimport { ILocalUser, IUserEmailValidationToken } from '../../../types/schema/index.js'\nimport { errorResponse, voidResponse } from '../../utils.js'\nimport { AuthRequestEmailVerificationTokenProcessContract } from '../../../types/api/auth/request-email-verification-token/index.js'\n\nexport const silentOperation: AuthRequestEmailVerificationTokenProcessContract['operation'] = async ({ body }) => {\n const { email } = body\n const userLookup = await findOne<ILocalUser>(LocalUserModel, { email }, { initiatorId: env.ROOT_USER_ID })\n if (!userLookup.success) return errorResponse(404, Codes.USER_EMAIL_DOES_NOT_EXIST, email)\n await deleteMany<IUserEmailValidationToken>(UserEmailValidationTokenModel, { email }, { initiatorId: env.ROOT_USER_ID }) \n const userData = userLookup.payload\n if (userData.verified === true) return errorResponse(400, Codes.USER_EMAIL_ALREADY_VERIFIED, email)\n await createAndSendUserEmailValidationToken(email, userData.username)\n return voidResponse()\n}\n\nexport const operation: typeof silentOperation = async hooks => {\n const result = await silentOperation(hooks)\n if (result.type === 'void') logInfo(\n LogCategory.USER_EMAIL_VERIFICATION,\n 'Email verification token requested',\n { email: hooks.body.email }\n )\n return result\n}\n", "import { validation } from './validation.js'\nimport { operation } from './operation.js'\nimport { AuthRequestEmailVerificationTokenProcessContract } from '../../../types/api/auth/request-email-verification-token/index.js'\n\nexport const requestEmailVerificationToken: AuthRequestEmailVerificationTokenProcessContract = {\n _authType: 'none',\n _opType: 'void',\n validation,\n operation\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport zod from 'zod'\nimport { Codes } from '../../../types/errors/index.js'\nimport { errorResponse, jsonResponse } from '../../utils.js'\nimport { AuthRequestNewPasswordProcessContract } from '../../../types/api/auth/request-new-password/index.js'\n\nexport const validation: AuthRequestNewPasswordProcessContract['validation'] = async ({ body }) => {\n const validationSchema = zod.object({\n email: zod\n .string()\n .email('Invalid email format')\n })\n try {\n const validated = validationSchema.parse(body)\n return jsonResponse(200, {\n body: validated,\n params: {},\n query: {}\n })\n } catch (err) {\n const errStr = unknownToString(err)\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, errStr)\n }\n}\n", "import { createAndSendUserPasswordRenewalToken } from '../../../auth/index.js'\nimport {\n findOne,\n deleteMany,\n} from '../../../database/index.js'\nimport env from '../../../env/index.js'\nimport { Codes } from '../../../types/errors/index.js'\nimport { LocalUserModel } from '../../../schema/user/user/index.js'\nimport { errorResponse, voidResponse } from '../../utils.js'\nimport { UserPasswordRenewalTokenModel } from '../../../schema/user/password-renewal-token/index.js'\nimport { ILocalUser, IUserPasswordRenewalToken } from '../../../types/schema/index.js'\nimport { logError, logInfo } from '../../../logs/index.js'\nimport { Category as LogCategory } from '../../../types/logs/index.js'\nimport { AuthRequestNewPasswordProcessContract } from '../../../types/api/auth/request-new-password/index.js'\n\nexport const silentOperation: AuthRequestNewPasswordProcessContract['operation'] = async ({ body }) => {\n const { email } = body\n const foundUser = await findOne<ILocalUser>(LocalUserModel, { email }, { initiatorId: env.ROOT_USER_ID })\n if (!foundUser.success) return errorResponse(400, Codes.USER_EMAIL_DOES_NOT_EXIST, email)\n await deleteMany<IUserPasswordRenewalToken>(UserPasswordRenewalTokenModel, { email }, { initiatorId: env.ROOT_USER_ID })\n await createAndSendUserPasswordRenewalToken(email, foundUser.payload.username)\n return voidResponse()\n}\n\nexport const operation: typeof silentOperation = async hooks => {\n const result = await silentOperation(hooks)\n if (result.type === 'void') logInfo(\n LogCategory.USER_PASSWORD_RENEWAL,\n 'Password renewal requested',\n { email: hooks.body.email }\n )\n else logError(LogCategory.USER_PASSWORD_RENEWAL, 'Password renewal request failed', {\n email: hooks.body.email,\n error: {\n code: result.code,\n message: result.message,\n details: result.details\n }\n })\n return result\n}\n", "import { validation } from './validation.js'\nimport { operation } from './operation.js'\nimport { AuthRequestNewPasswordProcessContract } from '../../../types/api/auth/request-new-password/index.js'\n\nexport const requestNewPassword: AuthRequestNewPasswordProcessContract = {\n _authType: 'none',\n _opType: 'void',\n validation,\n operation\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport validator from 'validator'\nimport zod from 'zod'\nimport { Codes } from '../../../types/errors/index.js'\nimport { errorResponse, jsonResponse } from '../../utils.js'\nimport { AuthSignupProcessContract } from '../../../types/api/auth/signup/index.js'\n\nexport const validation: AuthSignupProcessContract['validation'] = async ({ body }) => {\n const validationSchema = zod.object({\n username: zod.string()\n .min(1)\n .refine(\n input => validator\n .isSlug(input.toLowerCase()),\n { message: 'Username must contain alphanumeric or non starting, trailing nor consecutive hyphens or underscores' }),\n email: zod\n .string()\n .email('Invalid email format'),\n password: zod\n .string()\n .min(1, 'Password must be at least one character long')\n })\n try {\n const validated = validationSchema.parse(body)\n return jsonResponse(200, {\n body: validated,\n params: {},\n query: {}\n })\n } catch (err) {\n const errStr = unknownToString(err)\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, errStr)\n }\n}\n", "import bcrypt from 'bcrypt'\nimport { createAndSendUserEmailValidationToken } from '../../../auth/index.js'\nimport { insertOne, findOne } from '../../../database/index.js'\nimport { OperationContext } from '../../../types/database/index.js'\nimport env from '../../../env/index.js'\nimport { Codes } from '../../../types/errors/index.js'\nimport { logInfo, logError } from '../../../logs/index.js'\nimport { Category as LogCategory } from '../../../types/logs/index.js'\nimport { BaseUserModel, GoogleUserModel, LocalUserModel } from '../../../schema/user/user/index.js'\nimport { UserRole, UserStatus, IBaseUser, IGoogleUser, ILocalUser } from '../../../types/schema/index.js'\nimport { errorResponse, jsonResponse } from '../../utils.js'\nimport { localUserToDTO } from '../../../transformers/user/index.js'\nimport { AuthSignupProcessContract } from '../../../types/api/auth/signup/index.js'\n\nconst silentOperation: AuthSignupProcessContract['operation'] = async ({ body }) => {\n const { username, email, password } = body\n const rootQueryContext: OperationContext = { initiatorId: env.ROOT_USER_ID }\n const foundUsername = await findOne<IBaseUser>(BaseUserModel, { username }, rootQueryContext)\n if (foundUsername.success) return errorResponse(400, Codes.USERNAME_ALREADY_TAKEN, username) \n const foundEmail = await findOne<IGoogleUser>(GoogleUserModel, { email }, rootQueryContext)\n if (foundEmail.success) return errorResponse(400, Codes.EMAIL_ADDRESS_ALREADY_TAKEN, email)\n const inserted = await insertOne<ILocalUser>(LocalUserModel, {\n username,\n role: UserRole.USER,\n status: UserStatus.ACTIVE,\n badges: [],\n email,\n _password: await bcrypt.hash(password, 10),\n verified: false\n }, rootQueryContext)\n if (!inserted.success) return errorResponse(500, Codes.DB_ERROR, inserted.error.details.dbError)\n await createAndSendUserEmailValidationToken(email, username)\n return jsonResponse(201, localUserToDTO(inserted.payload))\n}\n\nexport const operation: typeof silentOperation = async hooks => {\n const result = await silentOperation(hooks)\n if (result.type === 'json') logInfo(LogCategory.USER_SIGNUP, 'User created', { user: result.payload })\n else if (result.code === Codes.DB_ERROR) logError(LogCategory.USER_SIGNUP, 'User creation failed', {\n providedUsername: hooks.body.username,\n providedEmail: hooks.body.email,\n error: {\n code: result.code,\n message: result.message,\n details: result.details\n }\n })\n return result\n}\n", "import { validation } from './valiadtion.js'\nimport { operation } from './operation.js'\nimport { AuthSignupProcessContract } from '../../../types/api/auth/signup/index.js'\n\nexport const signup: AuthSignupProcessContract = {\n _authType: 'none',\n _opType: 'json',\n validation,\n operation\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport zod from 'zod'\nimport { Codes } from '../../../types/errors/index.js'\nimport { errorResponse, jsonResponse } from '../../utils.js'\nimport { AuthSubmitNewPasswordProcessContract } from '../../../types/api/auth/submit-new-password/index.js'\n\nexport const validation: AuthSubmitNewPasswordProcessContract['validation'] = async ({ body }) => {\n const validationSchema = zod.object({\n email: zod\n .string()\n .email('Invalid email format'),\n token: zod\n .string(),\n password: zod\n .string()\n .min(1, 'Password must be at least one character long')\n })\n try {\n const validated = validationSchema.parse(body)\n return jsonResponse(200, {\n body: validated,\n params: {},\n query: {}\n })\n } catch (err) {\n const errStr = unknownToString(err)\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, errStr)\n }\n}\n", "import bcrypt from 'bcrypt'\nimport { revokeAllUserAuthTokens } from '../../../auth/index.js'\nimport {\n findOne,\n updateOne,\n deleteMany\n} from '../../../database/index.js'\nimport env from '../../../env/index.js'\nimport { Codes } from '../../../types/errors/index.js'\nimport { LocalUserModel } from '../../../schema/user/user/index.js'\nimport { errorResponse, voidResponse } from '../../utils.js'\nimport { UserPasswordRenewalTokenModel } from '../../../schema/user/password-renewal-token/index.js'\nimport { ILocalUser, IUserPasswordRenewalToken } from '../../../types/schema/index.js'\nimport { logError, logInfo } from '../../../logs/index.js'\nimport { Category as LogCategory } from '../../../types/logs/index.js'\nimport { AuthSubmitNewPasswordProcessContract } from '../../../types/api/auth/submit-new-password/index.js'\n\nexport const silentOperation: AuthSubmitNewPasswordProcessContract['operation'] = async ({ body, accessTokenSigned, cookies }) => {\n const { token, email, password } = body\n const tokenLookup = await findOne<IUserPasswordRenewalToken>(\n UserPasswordRenewalTokenModel,\n { value: token, email: email, expiresOn: { $gte: Date.now() } },\n { initiatorId: env.ROOT_USER_ID }\n )\n if (!tokenLookup.success) return errorResponse(400, Codes.USER_PASSWORD_RENEWAL_TOKEN_DOES_NOT_EXIST, email, token)\n await deleteMany<IUserPasswordRenewalToken>(UserPasswordRenewalTokenModel, { email }, { initiatorId: env.ROOT_USER_ID })\n const foundUser = await findOne<ILocalUser>(\n LocalUserModel,\n { email },\n { initiatorId: env.ROOT_USER_ID }\n )\n if (!foundUser.success) return errorResponse(400, Codes.USER_EMAIL_DOES_NOT_EXIST, email)\n const { refreshToken: refreshTokenSigned } = cookies\n const additionalTokensToRevoke = []\n if (accessTokenSigned !== undefined) additionalTokensToRevoke.push(accessTokenSigned)\n if (typeof refreshTokenSigned === 'string') additionalTokensToRevoke.push(refreshTokenSigned)\n const revoked = await revokeAllUserAuthTokens(foundUser.payload._id, additionalTokensToRevoke)\n if (!revoked.success) return errorResponse(\n 500,\n Codes.USER_TOKENS_REVOCATION_FAILED,\n foundUser.payload._id.toString(),\n additionalTokensToRevoke\n )\n const updatedUser = await updateOne<ILocalUser>(\n LocalUserModel,\n { _id: foundUser.payload._id },\n { $set: { _password: await bcrypt.hash(password, 10) } },\n { initiatorId: env.ROOT_USER_ID }\n )\n if (!updatedUser.success) {\n if (updatedUser.error.code === Codes.DB_ERROR) return errorResponse(500, Codes.DB_ERROR, updatedUser.error.details.dbError)\n return errorResponse(500, Codes.USER_DOES_NOT_EXIST, foundUser.payload._id.toString())\n }\n return voidResponse()\n}\n\nexport const operation: typeof silentOperation = async hooks => {\n const result = await silentOperation(hooks)\n if (result.type === 'void') logInfo(LogCategory.USER_PASSWORD_RENEWAL, 'Password renewal successful', { email: hooks.body.email })\n else logError(LogCategory.USER_PASSWORD_RENEWAL, 'Password renewal failed', {\n email: hooks.body.email,\n error: {\n code: result.code,\n message: result.message,\n details: result.details\n }\n })\n return result\n}\n", "import { validation } from './validation.js'\nimport { operation } from './operation.js'\nimport { AuthSubmitNewPasswordProcessContract } from '../../../types/api/auth/submit-new-password/index.js'\n\nexport const submitNewPassword: AuthSubmitNewPasswordProcessContract = {\n _authType: 'none',\n _opType: 'void',\n validation,\n operation\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport zod from 'zod'\nimport { Codes } from '../../../types/errors/index.js'\nimport { errorResponse, jsonResponse } from '../../utils.js'\nimport { AuthVerifyEmailProcessContract } from '../../../types/api/auth/verify-email/index.js'\n\nexport const validation: AuthVerifyEmailProcessContract['validation'] = async ({ body }) => {\n const validationSchema = zod.object({\n email: zod\n .string()\n .email('Invalid email format'),\n token: zod\n .string()\n })\n try {\n const validated = validationSchema.parse(body)\n return jsonResponse(200, {\n body: validated,\n params: {},\n query: {}\n })\n } catch (err) {\n const errStr = unknownToString(err)\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, errStr)\n }\n}\n", "import {\n updateOne,\n deleteOne,\n} from '../../../database/index.js'\nimport env from '../../../env/index.js'\nimport { Codes } from '../../../types/errors/index.js'\nimport { LocalUserModel } from '../../../schema/user/user/index.js'\nimport { UserEmailValidationTokenModel } from '../../../schema/user/email-validation-token/index.js'\nimport { ILocalUser, IUserEmailValidationToken } from '../../../types/schema/index.js'\nimport { errorResponse, jsonResponse } from '../../utils.js'\nimport { logError, logInfo } from '../../../logs/index.js'\nimport { Category } from '../../../types/logs/index.js'\nimport { AuthVerifyEmailProcessContract } from '../../../types/api/auth/verify-email/index.js'\n\nexport const silentOperation: AuthVerifyEmailProcessContract['operation'] = async ({ body }) => {\n const { email, token } = body\n if (token === undefined) return errorResponse(400, Codes.USER_EMAIL_VERIFICATION_TOKEN_NOT_PROVIDED)\n const now = new Date()\n const rootQueryContext = { initiatorId: env.ROOT_USER_ID }\n const tokenDeletion = await deleteOne<IUserEmailValidationToken>(\n UserEmailValidationTokenModel,\n { email, value: token, expiresOn: { $gte: now } },\n rootQueryContext\n )\n if (!tokenDeletion.success) return errorResponse(400, Codes.USER_EMAIL_VERIFICATION_TOKEN_DOES_NOT_EXIST)\n const userUpdation = await updateOne<ILocalUser>(\n LocalUserModel,\n { email },\n { $set: { verified: true } },\n rootQueryContext\n )\n if (!userUpdation.success) {\n if (userUpdation.error.code === Codes.DB_ERROR) return errorResponse(500, Codes.DB_ERROR, userUpdation.error.details.dbError)\n return errorResponse(500, Codes.USER_EMAIL_DOES_NOT_EXIST, email)\n }\n const updatedUser = userUpdation.payload\n return jsonResponse(200, {\n _id: updatedUser._id.toString(),\n username: updatedUser.username,\n email: updatedUser.email,\n role: updatedUser.role,\n status: updatedUser.status,\n badges: updatedUser.badges,\n verified: updatedUser.verified\n })\n}\n\nexport const operation: typeof silentOperation = async hooks => {\n const result = await silentOperation(hooks)\n if (result.type === 'json') logInfo(Category.USER_EMAIL_VERIFICATION, 'Email verification successful', { email: hooks.body.email })\n else logError(Category.USER_EMAIL_VERIFICATION, 'Email verification failed', {\n email: hooks.body.email,\n error: {\n code: result.code,\n message: result.message,\n details: result.details\n }\n })\n return result\n}\n", "import { validation } from './validation.js'\nimport { operation } from './operation.js'\nimport { AuthVerifyEmailProcessContract } from '../../../types/api/auth/verify-email/index.js'\n\nexport const verifyEmail: AuthVerifyEmailProcessContract = {\n _authType: 'none',\n _opType: 'json',\n validation,\n operation\n}\n", "import { AuthWhoamiProcessContract } from '../../../types/api/auth/whoami/index.js'\nimport { jsonResponse } from '../../utils.js'\n\nexport const authentication: AuthWhoamiProcessContract['authentication'] = async ({\n accessTokenSigned,\n accessTokenPayload,\n user\n}) => jsonResponse(200, {\n accessTokenSigned,\n accessTokenPayload,\n user\n})\n", "import { Codes } from '../../../types/errors/index.js'\nimport { logError } from '../../../logs/index.js'\nimport { Category as LogCategory } from '../../../types/logs/index.js'\nimport { discriminateUser } from '../../../schema/user/user/index.js'\nimport { googleUserToDTO, localUserToDTO } from '../../../transformers/user/index.js'\nimport { errorResponse, jsonResponse } from '../../utils.js'\nimport { AuthWhoamiProcessContract } from '../../../types/api/auth/whoami/index.js'\n\nexport const silentOperation: AuthWhoamiProcessContract['operation'] = async ({ user, accessTokenPayload }) => {\n const discriminatedUser = discriminateUser(user)\n if (discriminatedUser === null) return errorResponse(500, Codes.USER_DOES_NOT_EXIST, accessTokenPayload.userId)\n if (discriminatedUser.authType === 'LocalUser') return jsonResponse(200, localUserToDTO(discriminatedUser))\n return jsonResponse(200, googleUserToDTO(discriminatedUser))\n}\n\nexport const operation: typeof silentOperation = async hooks => {\n const result = await silentOperation(hooks)\n if (result.type === 'error') logError(\n LogCategory.USER_LOOKUP,\n 'This user is not LocalUser nor GoogleUser, which should never happen', {\n userId: hooks.accessTokenPayload?.userId,\n error: {\n code: result.code,\n message: result.message,\n details: result.details\n }\n })\n return result\n}\n", "import { AuthWhoamiProcessContract } from '../../../types/api/auth/whoami/index.js'\nimport { authentication } from './authentication.js'\nimport { strongAuthNullValidation } from '../../../validation/index.js'\nimport { operation } from './operation.js'\n\nexport const whoami: AuthWhoamiProcessContract = {\n _authType: 'strong',\n _opType: 'json',\n authentication: authentication,\n validation: strongAuthNullValidation,\n operation\n}\n", "import { login } from './login/index.js'\nimport { logout } from './logout/index.js'\nimport { logoutEverywhere } from './logout-everywhere/index.js'\nimport { refreshToken } from './refresh-token/index.js'\nimport { requestEmailVerificationToken } from './request-email-verification-token/index.js'\nimport { requestNewPassword } from './request-new-password/index.js'\nimport { signup } from './signup/index.js'\nimport { submitNewPassword } from './submit-new-password/index.js'\nimport { verifyEmail } from './verify-email/index.js'\nimport { whoami } from './whoami/index.js'\n\nexport const auth = {\n login,\n logout,\n logoutEverywhere,\n refreshToken,\n requestEmailVerificationToken,\n requestNewPassword,\n signup,\n submitNewPassword,\n verifyEmail,\n whoami\n}\n", "import { Duration } from '@design-edito/tools/agnostic/time/duration/index.js'\nimport env from '../../../env/index.js'\nimport { CsrfGetTokenProcessContract } from '../../../types/api/csrf/get-token/index.js'\nimport { jsonResponse } from '../../utils.js'\nimport { tokens } from '../../../csrf/index.js'\n\nexport const operation: CsrfGetTokenProcessContract['operation'] = async ({ cookies, setCookie }) => {\n const cookie = cookies[env.CSRF_COOKIE_NAME]\n const secret: string = typeof cookie === 'string' ? cookie : tokens.secretSync()\n if (typeof cookie !== 'string') setCookie(env.CSRF_COOKIE_NAME, secret, {\n httpOnly: true,\n secure: env.ALLOW_HTTP === 'false',\n sameSite: 'none',\n maxAge: Duration.hours(2).toMilliseconds()\n })\n return jsonResponse(200, { token: tokens.create(secret) })\n}\n", "import { CsrfGetTokenProcessContract } from '../../../types/api/csrf/get-token/index.js'\nimport { noAuthNullValidation } from '../../../validation/index.js'\nimport { operation } from './operation.js'\n\nexport const getToken: CsrfGetTokenProcessContract = {\n _authType: 'none',\n _opType: 'json',\n validation: noAuthNullValidation,\n operation\n}\n", "import { getToken } from './get-token/index.js'\n\nexport const csrf = {\n getToken\n}\n", "import { mebibytes } from '@design-edito/tools/agnostic/misc/data-size/index.js'\nimport { ImageFormatProcessContract } from '../../../types/api/image/format/index.js'\nimport { authentication } from './authentication.js'\nimport { validation } from './validation.js'\nimport { operation } from './operation.js'\n\nexport const format: ImageFormatProcessContract = {\n _authType: 'strong',\n _opType: 'file',\n uploads: {\n fields: [{ name: 'image', maxCount: 1 }],\n limits: { fileSize: mebibytes(20).toBytes() }\n },\n authentication,\n validation,\n operation\n}\n", "import { allow } from '../../../auth/index.js'\nimport { ImageFormatProcessContract } from '../../../types/api/image/format/index.js'\nimport { UserStatus, UserBadge } from '../../../types/schema/index.js'\n\nexport const authentication: ImageFormatProcessContract['authentication'] = allow({\n verified: true,\n statuses: [UserStatus.ACTIVE],\n badges: [UserBadge.FORMAT_IMAGE]\n})\n", "import { Codes } from '../../../types/errors/index.js'\nimport { errorResponse, jsonResponse } from '../../utils.js'\nimport { ImageFormatProcessContract } from '../../../types/api/image/format/index.js'\nimport { isNonNullObject } from '@design-edito/tools/agnostic/objects/is-object/index.js'\nimport {\n isFormatAvifOptions,\n isFormatHeifOptions,\n isFormatJpgOptions,\n isFormatKeepOptions,\n isFormatPngOptions,\n isFormatTiffOptions,\n isFormatWebpOptions\n} from '@design-edito/tools/node/images/format/index.js'\n\nexport const validation: ImageFormatProcessContract['validation'] = async ({ body, files: { image } }) => {\n if (image === undefined || image.length === 0) return errorResponse(400, Codes.INVALID_REQUEST_FILES, 'Field named \\'image\\' in request files is required')\n if (image.length > 1) return errorResponse(400, Codes.INVALID_REQUEST_FILES, 'Cannot process multiple files at once')\n if (!isNonNullObject(body)) return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, 'Request body is required')\n if (!('format' in body) && isFormatKeepOptions(body)) return jsonResponse(200, { body, params: {}, query: {} })\n const format = (body as any).format\n if (typeof format !== 'string') return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, 'Invalid image format')\n if ((format === 'jpg' || format === 'jpeg') && isFormatJpgOptions(body)) return jsonResponse(200, { body: { ...body, format }, params: {}, query: {} })\n else if (format === 'png' && isFormatPngOptions(body)) return jsonResponse(200, { body: { ...body, format }, params: {}, query: {} })\n else if (format === 'webp' && isFormatWebpOptions(body)) return jsonResponse(200, { body: { ...body, format }, params: {}, query: {} })\n else if (format === 'avif' && isFormatAvifOptions(body)) return jsonResponse(200, { body: { ...body, format }, params: {}, query: {} })\n else if (format === 'tiff' && isFormatTiffOptions(body)) return jsonResponse(200, { body: { ...body, format }, params: {}, query: {} })\n else if (format === 'heif' && isFormatHeifOptions(body)) return jsonResponse(200, { body: { ...body, format }, params: {}, query: {} })\n return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, 'Invalid image format type')\n}\n", "import { createReadStream } from 'node:fs'\nimport { buffer as toBuffer } from 'node:stream/consumers'\nimport { format } from '@design-edito/tools/node/images/format/index.js'\nimport { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport { Codes } from '../../../types/errors/index.js'\nimport { logError } from '../../../logs/index.js'\nimport { Category } from '../../../types/logs/index.js'\nimport { errorResponse, fileResponse } from '../../utils.js'\nimport { ImageFormatProcessContract } from '../../../types/api/image/format/index.js'\nimport { fileTypeFromBuffer } from 'file-type'\n\nexport const silentOperation: ImageFormatProcessContract['operation'] = async ({ body, files }) => {\n const file = files.image?.[0]\n if (file === undefined) return errorResponse(400, Codes.INVALID_REQUEST_FILES, 'No file uploaded')\n try {\n if ('compressionLevel' in body && body.compressionLevel !== undefined) {\n body.compressionLevel = body.compressionLevel / 10\n }\n const fileStream = createReadStream(file.path)\n const formattedBufferAttempt = 'format' in body\n ? await format(await toBuffer(fileStream), body.format, body)\n : await format(await toBuffer(fileStream), body)\n if (!formattedBufferAttempt.success) return errorResponse(500, Codes.IMAGE_FORMAT_FAILED, formattedBufferAttempt.error)\n const { payload: formattedBuffer } = formattedBufferAttempt\n const { ext, mime } = await fileTypeFromBuffer(formattedBuffer) ?? {}\n if (ext === undefined || mime === undefined) return errorResponse(500, Codes.IMAGE_FORMAT_FAILED, 'Unable to determine output image file type')\n return fileResponse(\n 200,\n `${file.outBase}.${ext}`,\n formattedBuffer,\n mime,\n 'private, max-age=0, no-cache',\n formattedBuffer.byteLength\n )\n } catch (error) {\n return errorResponse(\n 500,\n Codes.IMAGE_FORMAT_FAILED,\n unknownToString(error)\n )\n }\n}\n\nexport const operation: typeof silentOperation = async hooks => {\n const { body, files } = hooks\n const result = await silentOperation(hooks)\n if (result.type === 'error'\n && result.code === Codes.IMAGE_FORMAT_FAILED) logError(\n Category.FILE_PROCESSING,\n 'Something went wrong while formatting an image',\n { body, files, error: result.details }\n )\n return result\n}\n", "import { mebibytes } from '@design-edito/tools/agnostic/misc/data-size/index.js'\nimport { ImageTransformProcessContract } from '../../../types/api/image/transform/index.js'\nimport { authentication } from './authentication.js'\nimport { validation } from './validation.js'\nimport { operation } from './operation.js'\n\nexport const transform: ImageTransformProcessContract = {\n _authType: 'strong',\n _opType: 'file',\n uploads: {\n fields: [{ name: 'image', maxCount: 1 }],\n limits: { fileSize: mebibytes(2).toBytes() }\n },\n authentication,\n validation,\n operation\n}\n", "import { allow } from '../../../auth/index.js'\nimport { ImageTransformProcessContract } from '../../../types/api/image/transform/index.js'\nimport { UserStatus, UserBadge } from '../../../types/schema/index.js'\n\nexport const authentication: ImageTransformProcessContract['authentication'] = allow({\n verified: true,\n statuses: [UserStatus.ACTIVE],\n badges: [UserBadge.FORMAT_IMAGE]\n})\n", "import { Codes } from '../../../types/errors/index.js'\nimport { errorResponse, jsonResponse } from '../../utils.js'\nimport { ImageTransformProcessContract } from '../../../types/api/image/transform/index.js'\nimport { isNonNullObject } from '@design-edito/tools/agnostic/objects/is-object/index.js'\nimport { isOperationDescriptor, OperationDescriptor } from '@design-edito/tools/node/images/transform/index.js'\nimport { Outcome } from '@design-edito/tools/agnostic/misc/outcome/index.js'\n\nexport const validation: ImageTransformProcessContract['validation'] = async ({ body, files: { image } }) => {\n if (image === undefined || image.length === 0) return errorResponse(400, Codes.INVALID_REQUEST_FILES, 'Field named \\'image\\' in request files is required')\n if (image.length > 1) return errorResponse(400, Codes.INVALID_REQUEST_FILES, 'Cannot process multiple files at once')\n if (!isNonNullObject(body)) return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, 'Request body is required')\n if (!('operations' in body)) return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, 'Field named \\'operations\\' in request body is required')\n const { operations } = body\n if (!Array.isArray(operations)) return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, 'Field named \\'operations\\' in request body must be an array')\n if (operations.length > 10) return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, 'Field named \\'operations\\' in request body must be an array of at most 10 operations')\n const validatedOperations = operations.map(isOperationDescriptor)\n const failedOperations = validatedOperations.filter(op => !op.success)\n if (failedOperations.length > 0) return errorResponse(400, Codes.INVALID_REQUEST_BODY, body, failedOperations.map(op => op.error).join(', '))\n const ops = validatedOperations.map(op => (op as Outcome.Success<OperationDescriptor>).payload)\n return jsonResponse(200, { body: { operations: ops }, params: {}, query: {} })\n}\n", "import { createReadStream } from 'node:fs'\nimport { buffer as toBuffer } from 'node:stream/consumers'\nimport { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport { transform } from '@design-edito/tools/node/images/transform/index.js'\nimport { Duration } from '@design-edito/tools/agnostic/time/duration/index.js'\nimport { fileTypeFromBuffer } from 'file-type'\nimport { Codes } from '../../../types/errors/index.js'\nimport { logError, logWarning } from '../../../logs/index.js'\nimport { Category } from '../../../types/logs/index.js'\nimport { errorResponse, fileResponse } from '../../utils.js'\nimport type { ImageTransformProcessContract } from '../../../types/api/image/transform/index.js'\n\nlet parallelTransformationsCount = 0\n\nexport const silentOperation: ImageTransformProcessContract['operation'] = async ({ body, files: { image } }) => {\n if (parallelTransformationsCount >= 4) return errorResponse(\n 429,\n Codes.TOO_MANY_REQUESTS,\n 'Too many concurrent requests on this route at the time, try again later.')\n const imageFile = image?.[0]\n if (imageFile === undefined) return errorResponse(400, Codes.INVALID_REQUEST_FILES, 'No file uploaded')\n parallelTransformationsCount++\n try {\n // The operations length is limited in ./validation.ts\n const { operations } = body\n const fileBuffer = await toBuffer(createReadStream(imageFile.path))\n const transformedSharpInstanceAttempt = await transform(fileBuffer, operations, {\n timeoutMs: Duration.seconds(10).toMs(),\n opTimeoutMs: Duration.seconds(5).toMs(),\n width: 4096,\n height: 4096\n })\n if (!transformedSharpInstanceAttempt.success) {\n logWarning(\n Category.FILE_PROCESSING,\n 'Could not transform the image',\n { error: transformedSharpInstanceAttempt.error }\n )\n return errorResponse(500, Codes.IMAGE_TRANSFORM_FAILED, 'Could not transform the image')\n }\n const transformedSharpInstance = transformedSharpInstanceAttempt.payload\n const formattedBuffer = await transformedSharpInstance.toBuffer()\n const { ext: outputExt, mime: outputMime } = await fileTypeFromBuffer(formattedBuffer) ?? {}\n if (outputExt === undefined || outputMime === undefined) return errorResponse(\n 500,\n Codes.UNKNOWN_ERROR,\n 'Failed to determine output file type'\n )\n const outputName = `${imageFile.outBase}.${new Date().toISOString()}.${outputExt}`\n return fileResponse(\n 200,\n outputName,\n formattedBuffer,\n outputMime,\n 'private, max-age=0, no-cache',\n formattedBuffer.byteLength\n )\n } catch (error) {\n return errorResponse(500, Codes.UNKNOWN_ERROR, unknownToString(error))\n } finally {\n parallelTransformationsCount--\n }\n}\n\nexport const operation: typeof silentOperation = async hooks => {\n const { body, files } = hooks\n const result = await silentOperation(hooks)\n if (result.type === 'error'\n && result.code === Codes.UNKNOWN_ERROR) logError(\n Category.FILE_PROCESSING,\n 'Something went wrong while transforming an image',\n { body, files, error: result.details }\n )\n return result\n}\n", "import { format } from './format/index.js'\nimport { transform } from './transform/index.js'\n\nexport const image = {\n format,\n transform\n}\n", "import { SystemKillProcessContract } from '../../../types/api/system/kill/index.js'\n\nexport const operation: SystemKillProcessContract['operation'] = async () => {\n process.exit(1)\n}\n", "import { allow } from '../../../auth/index.js'\nimport { SystemKillProcessContract } from '../../../types/api/system/kill/index.js'\nimport { UserBadge, UserRole, UserStatus } from '../../../types/schema/index.js'\nimport { strongAuthNullValidation } from '../../../validation/index.js'\nimport { operation } from './operation.js'\n\nexport const kill: SystemKillProcessContract = {\n _authType: 'strong',\n _opType: 'void',\n authentication: allow({\n verified: true,\n roles: [UserRole.ADMIN, UserRole.ROOT],\n statuses: [UserStatus.ACTIVE],\n badges: [UserBadge.CAN_SYSTEM_KILL],\n }),\n validation: strongAuthNullValidation,\n operation\n}\n", "import { SystemPingProcessContract } from '../../../types/api/system/ping/index.js'\nimport { jsonResponse } from '../../utils.js'\n\nexport const operation: SystemPingProcessContract['operation'] = async () => {\n return jsonResponse(200, { pong: true })\n}\n", "import { SystemPingProcessContract } from '../../../types/api/system/ping/index.js'\nimport { noAuthNullValidation } from '../../../validation/index.js'\nimport { operation } from './operation.js'\n\nexport const ping: SystemPingProcessContract = {\n _authType: 'none',\n _opType: 'json',\n validation: noAuthNullValidation,\n operation\n}\n", "import { send as sendMail } from '../../../email/index.js'\nimport { SystemSendMailProcessContract } from '../../../types/api/system/send-mail/index.js'\nimport { voidResponse } from '../../utils.js'\n\nexport const operation: SystemSendMailProcessContract['operation'] = async ({ query }) => {\n const { to, subject, text } = query\n await sendMail('noreply@localhost', 'noreply', to, 'user', subject, text)\n return voidResponse()\n}\n", "import { allow } from '../../../auth/index.js'\nimport { SystemSendMailProcessContract } from '../../../types/api/system/send-mail/index.js'\nimport { Codes } from '../../../types/errors/index.js'\nimport { UserBadge, UserRole, UserStatus } from '../../../types/schema/index.js'\nimport { errorResponse, jsonResponse } from '../../utils.js'\nimport { operation } from './operation.js'\n\nexport const sendMail: SystemSendMailProcessContract = {\n _authType: 'strong',\n _opType: 'void',\n authentication: allow({\n verified: true,\n badges: [UserBadge.CAN_SYSTEM_SEND_MAIL],\n roles: [UserRole.ADMIN, UserRole.ROOT],\n statuses: [UserStatus.ACTIVE]\n }),\n validation: async hooks => {\n const { query, params } = hooks\n const { to, subject, text } = query\n if (typeof to !== 'string' || to === '') return errorResponse(400, Codes.INVALID_REQUEST_QUERY, query, 'Invalid \"to\" query parameter')\n if (typeof subject !== 'string' || subject === '') return errorResponse(400, Codes.INVALID_REQUEST_QUERY, query, 'Invalid \"subject\" query parameter')\n if (typeof text !== 'string' || text === '') return errorResponse(400, Codes.INVALID_REQUEST_QUERY, query, 'Invalid \"text\" query parameter')\n const validated = { to, subject, text }\n return jsonResponse(200, {\n body: {},\n query: validated,\n params\n })\n },\n operation\n}\n", "import { Duration } from '@design-edito/tools/agnostic/time/duration/index.js'\nimport { throttle } from '@design-edito/tools/agnostic/optim/throttle-debounce/index.js'\nimport { ping as dbPing } from '../../../database/index.js'\nimport env from '../../../env/index.js'\n// [WIP] WARNING: should not import from init, this should come from a hook\nimport { aliveSince } from '../../../init/index.js'\nimport { SystemStatusCheckProcessContract } from '../../../types/api/system/status-check/index.js'\nimport { jsonResponse } from '../../utils.js'\nimport { ping as fsPing } from '../../../fs/index.js'\nimport { pingScanner } from '../../../upload/index.js'\n\nlet lastDbPing: number | null = null\nlet lastFsPing: number | null = null\nlet lastClamavPing: number | null = null\n\nconst dbPingThrottled = throttle(async() => {\n const result = await dbPing()\n lastDbPing = result?.success ? result.payload : null\n return lastDbPing\n}, Duration.seconds(10).toMs()).throttled\nconst fsPingThrottled = throttle(async() => {\n const result = await fsPing()\n lastFsPing = result?.success ? result.payload : null\n return lastFsPing\n}, Duration.seconds(10).toMs()).throttled\nconst clamavPingThrottled = throttle(async() => {\n const result = await pingScanner()\n lastClamavPing = result?.success ? result.payload : null\n return lastClamavPing\n}, Duration.seconds(10).toMs()).throttled\n\nexport const operation: SystemStatusCheckProcessContract['operation'] = async () => {\n const now = new Date()\n const uptimeSeconds = Math.floor((now.getTime() - aliveSince.getTime()) / 1000)\n const fsType = env.FS_STORAGE_TYPE\n dbPingThrottled()\n fsPingThrottled()\n clamavPingThrottled()\n const isHealthy = lastDbPing !== null\n && lastFsPing !== null\n && lastClamavPing !== null\n return jsonResponse(200, {\n isHealthy,\n builtOn: env.ESBUILD_BUILT_ON,\n aliveSince: aliveSince.toISOString(),\n uptimeSeconds,\n database: {\n connected: lastDbPing !== null,\n pingMs: Math.round((lastDbPing ?? Infinity) * 10) / 10\n },\n fs: {\n type: fsType,\n connected: lastFsPing !== null,\n pingMs: Math.round((lastFsPing ?? Infinity) * 10) / 10\n },\n clamav: {\n connected: lastClamavPing !== null,\n pingMs: Math.round((lastClamavPing ?? Infinity) * 10) / 10\n }\n })\n}\n", "import { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport { Duration } from '@design-edito/tools/agnostic/time/duration/index.js'\nimport { wait } from '@design-edito/tools/agnostic/time/wait/index.js'\nimport bcrypt from 'bcrypt'\nimport { Types as MongooseTypes } from 'mongoose'\nimport { stopAgenda, scheduleCronTask } from '../cron/index.js'\nimport * as Database from'../database/index.js'\nimport * as Email from '../email/index.js'\nimport env from '../env/index.js'\nimport { LocalUserModel } from '../schema/user/user/index.js'\nimport { UserAuthTokenModel } from '../schema/user/auth-token/index.js'\nimport { UserUploadQuotaModel } from '../schema/user/upload-quota/index.js'\nimport { UserEmailValidationTokenModel } from '../schema/user/email-validation-token/index.js'\nimport { UserPasswordRenewalTokenModel } from '../schema/user/password-renewal-token/index.js'\nimport { UserRevokedAuthTokenModel } from '../schema/user/revoked-auth-token/index.js'\nimport {\n ILocalUser,\n IUserAuthToken,\n IUserUploadQuota,\n IUserEmailValidationToken,\n IUserPasswordRenewalToken,\n IUserRevokedAuthToken,\n UserRole,\n UserStatus,\n UserBadge\n} from '../types/schema/index.js'\nimport {\n flush as tempDirFlush,\n updateCurrentByteSize as updateTempDirCurrentByteSize,\n cleanupOldFiles as cleanupOldTempFiles\n} from '../temp/index.js'\nimport {\n logError,\n logFatal,\n logInfo,\n logWarning\n} from '../logs/index.js'\nimport { Category as LogCategory } from '../types/logs/index.js'\nimport { Codes } from '../types/errors/index.js'\nimport { Shutdown } from '../types/init/index.js'\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * Boot stuff\n *\n * * * * * * * * * * * * * * * * * * * * */\n\nexport const aliveSince = new Date()\n\nexport async function notifyMainAdminUserServerStarted () {\n if (env.ALLOW_MAIN_ADMIN_USER_EMAIL_NOTIFICATIONS === 'false') return\n await Email.send(\n env.EMAILER_TYPE === 'gmail' ? env.EMAILER_GMAIL_EMAIL : env.EMAILER_MAILERSEND_EMAILER_EMAIL,\n env.EMAILER_TYPE === 'gmail' ? env.EMAILER_GMAIL_NAME : env.EMAILER_MAILERSEND_EMAILER_NAME,\n env.MAIN_ADMIN_USER_EMAIL,\n env.MAIN_ADMIN_USER_NAME,\n `LM Publisher API server started (${env.APP_LABEL})`,\n `Server started at ${aliveSince.toISOString()}\\n`\n )\n}\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * Cleanup stuff\n *\n * * * * * * * * * * * * * * * * * * * * */\n\nlet currentlyShuttingDown = false\nexport function isShuttingDown () {\n return currentlyShuttingDown\n}\n\nexport function captureTerminationSignals () {\n process.on('SIGINT', async () => {\n if (currentlyShuttingDown) return\n currentlyShuttingDown = true\n logFatal(LogCategory.SHUTDOWN, 'SIGINT received')\n await shutdown(0)\n })\n\n process.on('SIGTERM', async () => {\n if (currentlyShuttingDown) return\n currentlyShuttingDown = true\n logFatal(LogCategory.SHUTDOWN, 'SIGTERM received')\n await shutdown(0)\n })\n}\n\nconst shutdownList: (() => Promise<any>)[] = [\n stopAgenda,\n Database.disconnect,\n tempDirFlush\n]\n\nexport function subscribeShutdownTask (task: () => Promise<any>) {\n shutdownList.push(task)\n}\n\nexport async function gracefulShutdown () {\n await Promise.all(shutdownList.map(t => t()))\n}\n\nexport const shutdown: Shutdown = async code => {\n logInfo(LogCategory.SHUTDOWN, 'Running cleanup tasks...')\n await gracefulShutdown()\n logInfo(LogCategory.SHUTDOWN, 'Cleanup complete, bye.')\n await wait(Duration.seconds(5).toMs())\n process.exit(code)\n}\n\nexport async function scheduleCronTasks () {\n // [WIP] intervals goes to .env ?\n await scheduleCronTask('ENSURE_ROOT_USER', '5 minutes', ensureSingleRootUser, async () => await shutdown(1))\n await scheduleCronTask('ENSURE_MAIN_ADMIN_USER', '5 minutes', ensureSingleMainAdminUser, async () => await shutdown(1))\n await scheduleCronTask('CLEANUP_USER_EMAIL_VERIFICATION_TOKENS', '5 minutes', cleanupUserEmailVerificationTokens, async () => await shutdown(1))\n await scheduleCronTask('CLEANUP_USER_REVOKED_AUTH_TOKENS', '5 minutes', cleanupUserRevokedAuthTokens, async () => await shutdown(1))\n await scheduleCronTask('CLEANUP_USER_PASSWORD_RENEWAL_TOKENS', '5 minutes', cleanupUserPasswordRenewalTokens, async () => await shutdown(1))\n await scheduleCronTask('CLEANUP_USER_STALE_AUTH_TOKENS', '5 minutes', cleanupUserStaleAuthTokens, async () => await shutdown(1))\n await scheduleCronTask('RESET_USER_DAILY_UPLOAD_QUOTA', '0 0 * * *', resetUserDailyUploadQuota, async () => await shutdown(1))\n await scheduleCronTask('RESET_USER_MONTHLY_UPLOAD_QUOTA', '0 1 1 * *', resetUserMonthlyUploadQuota, async () => await shutdown(1))\n await scheduleCronTask('UPDATE_TEMP_DIR_SIZE', '30 seconds', updateTempDirCurrentByteSize, async () => await shutdown(1))\n await scheduleCronTask('CLEANUP_OLD_TEMP_FILES', '10 seconds', async () => await cleanupOldTempFiles(Duration.minutes(1).toMs()), async () => await shutdown(1))\n}\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * Cron tasks [WIP] should live in /cron ?\n *\n * * * * * * * * * * * * * * * * * * * * */\n\nexport async function ensureSingleRootUser () {\n logInfo(LogCategory.CRON, 'Ensuring ROOT user...')\n try {\n const rootUsersViaRoleLookup = await Database.findMany<ILocalUser>(\n LocalUserModel,\n { role: UserRole.ROOT },\n { initiatorId: env.ROOT_USER_ID },\n { limit: 2 }\n )\n const rootUsersViaRole = rootUsersViaRoleLookup.success ? rootUsersViaRoleLookup.payload.found : []\n const rootUsersViaIdLookup = await Database.findMany<ILocalUser>(\n LocalUserModel,\n { _id: env.ROOT_USER_ID },\n { initiatorId: env.ROOT_USER_ID },\n { limit: 2 }\n )\n const rootUsersViaId = rootUsersViaIdLookup.success ? rootUsersViaIdLookup.payload.found : []\n const rootUsersWithDuplicates = [...rootUsersViaRole, ...rootUsersViaId]\n const rootUsersIdsSet = new Set(rootUsersWithDuplicates.map(usr => usr._id.toString()))\n\n // No ROOT user found\n if (rootUsersIdsSet.size === 0) {\n const newRootUser = new LocalUserModel({\n _id: new MongooseTypes.ObjectId(env.ROOT_USER_ID),\n username: env.ROOT_USER_NAME,\n email: env.ROOT_USER_EMAIL,\n _password: await bcrypt.hash(env.ROOT_USER_PWD, 10),\n role: UserRole.ROOT,\n status: UserStatus.ACTIVE,\n badges: [],\n verified: true\n })\n const rootUserInserted = await Database.insertOne<ILocalUser>(\n LocalUserModel,\n newRootUser,\n { initiatorId: env.ROOT_USER_ID }\n )\n if (!rootUserInserted.success) {\n logFatal(\n LogCategory.CRON,\n 'Something went wrong while creating ROOT user. Shutting down',\n { error: rootUserInserted.error }\n )\n return await shutdown(1)\n }\n logInfo(LogCategory.CRON, 'ROOT user created')\n return\n }\n\n // Many ROOT users found\n if (rootUsersIdsSet.size > 1) {\n logFatal(LogCategory.CRON, 'Multiple ROOT users found, shutting down')\n return await shutdown(1)\n }\n\n // Single ROOT user found\n logInfo(LogCategory.CRON, 'ROOT user exists')\n\n } catch (err) {\n logFatal(\n LogCategory.CRON,\n 'An unknown error occured while initing the database',\n { error: unknownToString(err) }\n )\n return await shutdown(1)\n }\n}\n\nexport async function ensureSingleMainAdminUser () {\n logInfo(LogCategory.CRON, 'Ensuring MAIN ADMIN user...')\n try {\n const mainAdminUsersViaIdLookup = await Database.findMany<ILocalUser>(\n LocalUserModel,\n { _id: env.MAIN_ADMIN_USER_ID },\n { initiatorId: env.ROOT_USER_ID },\n { limit: 2 }\n )\n const mainAdminUsersViaId = mainAdminUsersViaIdLookup.success\n ? mainAdminUsersViaIdLookup.payload.found\n : []\n const [\n firstMainAdminUser,\n ...otherMainAdminUsers\n ] = mainAdminUsersViaId\n\n // No MAIN ADMIN user found\n if (firstMainAdminUser === undefined) {\n const newMainAdminUser = new LocalUserModel({\n _id: new MongooseTypes.ObjectId(env.MAIN_ADMIN_USER_ID),\n username: env.MAIN_ADMIN_USER_NAME,\n email: env.MAIN_ADMIN_USER_EMAIL,\n _password: await bcrypt.hash(env.MAIN_ADMIN_USER_PWD, 10),\n role: UserRole.ADMIN,\n status: UserStatus.ACTIVE,\n badges: [...Object.values(UserBadge)],\n verified: true\n })\n const mainAdminUserInserted = await Database.insertOne<ILocalUser>(\n LocalUserModel,\n newMainAdminUser,\n { initiatorId: env.ROOT_USER_ID }\n )\n if (!mainAdminUserInserted.success) {\n logFatal(\n LogCategory.CRON,\n 'Something went wrong while creating MAIN ADMIN user. Shutting down',\n { error: mainAdminUserInserted.error }\n )\n return await shutdown(1)\n }\n logInfo(LogCategory.CRON, 'MAIN ADMIN user created')\n return\n }\n\n // Many MAIN ADMIN users found\n if (otherMainAdminUsers.length > 0) {\n logFatal(LogCategory.CRON, 'Multiple MAIN ADMIN users found, shutting down')\n return await shutdown(1)\n }\n\n // Single MAIN ADMIN user found\n // Ensure MAIN ADMIN has all badges\n const mainAdminUser = firstMainAdminUser\n const mainAdminUserHasAllBadges = Object\n .values(UserBadge)\n .every(b => mainAdminUser.badges.includes(b))\n if (!mainAdminUserHasAllBadges) {\n logWarning(LogCategory.CRON, 'MAIN ADMIN user is missing badges, updating...')\n const updated = await Database.updateOne<ILocalUser>(\n LocalUserModel,\n { _id: firstMainAdminUser._id },\n { badges: [...Object.values(UserBadge)] },\n { initiatorId: env.ROOT_USER_ID }\n )\n if (updated.success) logInfo(LogCategory.CRON, 'MAIN ADMIN user badges updated')\n else {\n logError(LogCategory.CRON, 'Failed to update MAIN ADMIN user badges', { error: updated.error })\n }\n } else logInfo(LogCategory.CRON, 'MAIN ADMIN user has all badges')\n\n logInfo(LogCategory.CRON, 'MAIN ADMIN user exists')\n\n } catch (err) {\n logFatal(\n LogCategory.CRON,\n 'An unknown error occured while initing the database',\n { error: unknownToString(err) }\n )\n return await shutdown(1)\n }\n}\n\nexport async function cleanupUserEmailVerificationTokens () {\n const now = new Date()\n const deleted = await Database.deleteMany<IUserEmailValidationToken>(\n UserEmailValidationTokenModel,\n { expiresOn: { $lt: now } },\n { initiatorId: env.ROOT_USER_ID }\n )\n if (!deleted.success\n && deleted.error.code !== Codes.DB_NO_DOCUMENT_MATCHES_FILTER) {\n logError(\n LogCategory.CRON,\n 'Failed to cleanup users email verification tokens',\n { error: deleted.error }\n )\n return\n }\n logInfo(LogCategory.CRON, 'Cleaned up users email verification tokens')\n return\n}\n\nexport async function cleanupUserRevokedAuthTokens () {\n const now = Date.now()\n const refreshTokenLifetimeSeconds = env.REFRESH_TOKEN_EXPIRATION_SECONDS\n const refreshTokenLifetimeMs = Duration.seconds(refreshTokenLifetimeSeconds).toMilliseconds()\n const oldEnoughRevokedTokensThreshold = new Date(now - (refreshTokenLifetimeMs * 5))\n const deleted = await Database.deleteMany<IUserRevokedAuthToken>(\n UserRevokedAuthTokenModel,\n { revokedOn: { $lt: oldEnoughRevokedTokensThreshold } },\n { initiatorId: env.ROOT_USER_ID }\n )\n if (!deleted.success\n && deleted.error.code !== Codes.DB_NO_DOCUMENT_MATCHES_FILTER) {\n logError(\n LogCategory.CRON,\n 'Failed to cleanup users revoked auth tokens',\n { error: deleted.error }\n )\n return\n }\n logInfo(LogCategory.CRON, 'Cleaned up users revoked auth tokens')\n return\n}\n\nexport async function cleanupUserPasswordRenewalTokens () {\n const now = new Date()\n const deleted = await Database.deleteMany<IUserPasswordRenewalToken>(\n UserPasswordRenewalTokenModel,\n { expiresOn: { $lt: now } },\n { initiatorId: env.ROOT_USER_ID }\n )\n if (!deleted.success\n && deleted.error.code !== Codes.DB_NO_DOCUMENT_MATCHES_FILTER) {\n logError(\n LogCategory.CRON,\n 'Failed to cleanup users password renewal tokens',\n { error: deleted.error }\n )\n return\n }\n logInfo(LogCategory.CRON, 'Cleaned up users password renewal tokens')\n return\n}\n\nexport async function cleanupUserStaleAuthTokens () {\n const now = new Date()\n const deleted = await Database.deleteMany<IUserAuthToken>(\n UserAuthTokenModel,\n { expiresOn: { $lt: now } },\n { initiatorId: env.ROOT_USER_ID }\n )\n if (!deleted.success\n && deleted.error.code !== Codes.DB_NO_DOCUMENT_MATCHES_FILTER) {\n logError(\n LogCategory.CRON,\n 'Failed to cleanup users stale auth tokens',\n { error: deleted.error }\n )\n return\n }\n logInfo(LogCategory.CRON, 'Cleaned up users stale auth tokens')\n return\n}\n\nexport async function resetUserDailyUploadQuota () {\n const reseted = await Database.updateMany<IUserUploadQuota>(\n UserUploadQuotaModel,\n {},\n { dailyUploadsByteSize: 0 },\n { initiatorId: env.ROOT_USER_ID }\n )\n if (!reseted.success\n && reseted.error.code !== Codes.DB_NO_DOCUMENT_MATCHES_FILTER) {\n logError(\n LogCategory.CRON,\n 'Failed to reset users daily upload quota',\n { error: reseted.error }\n )\n return\n }\n logInfo(LogCategory.CRON, 'Reset users daily upload quota')\n return\n}\n\nexport async function resetUserMonthlyUploadQuota () {\n const reseted = await Database.updateMany<IUserUploadQuota>(UserUploadQuotaModel, {}, { monthlyUploadsByteSize: 0 }, { initiatorId: env.ROOT_USER_ID })\n if (!reseted.success\n && reseted.error.code !== Codes.DB_NO_DOCUMENT_MATCHES_FILTER) {\n logError(\n LogCategory.CRON,\n 'Failed to reset users monthly upload quota',\n { error: reseted.error }\n )\n return\n }\n logInfo(LogCategory.CRON, 'Reset users monthly upload quota')\n return\n}\n\n// [WIP] keep this migration tool for later\n// export async function migrateUserBadges () {\n// await LocalUserModel.updateMany<ILocalUser>(\n// { badges: { $exists: false } },\n// { $set: { badges: [] } }\n// )\n// }\n", "import { randomUUID } from 'node:crypto'\nimport { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport { Agenda } from 'agenda'\nimport * as Database from '../database/index.js'\nimport env from '../env/index.js'\nimport { logError, logFatal, logInfo } from '../logs/index.js'\nimport { Category as LogCategory } from '../types/logs/index.js'\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * Agenda setup\n *\n * * * * * * * * * * * * * * * * * * * * */\n\nlet agenda: Agenda | null = null\n\n// [WIP] should live in /init ?\nexport async function startAgenda (): Promise<void> {\n const jobId = randomUUID().split('-').at(0) ?? '-'\n const logDetails = { startupAttemptId: jobId }\n if (agenda !== null) return\n logInfo(LogCategory.INIT, 'Starting agenda...', logDetails)\n agenda = new Agenda()\n agenda.database(Database.connectionString, env.DB_RESERVED_AGENDA_JOBS_COLLECTION_NAME)\n agenda.processEvery('1 minute')\n await new Promise<void>((resolve, reject) => {\n agenda!.once('ready', () => {\n logInfo(LogCategory.INIT, 'Agenda ready', logDetails)\n resolve()\n })\n agenda!.once('error', (err) => {\n logFatal(LogCategory.INIT, 'Agenda error', {\n error: unknownToString(err),\n startupAttemptId: jobId\n })\n reject(err)\n })\n })\n await agenda.start()\n logInfo(LogCategory.INIT, 'Agenda started', logDetails)\n}\n\nexport function getAgenda () { return agenda }\nexport async function stopAgenda () { await agenda?.stop() }\n\nexport async function scheduleCronTask (\n name: string,\n interval: string,\n cronTask: () => void | Promise<void>,\n errHandler?: (err: unknown) => Promise<void> | void\n) {\n try {\n await startAgenda()\n agenda!.define(name, cronTask)\n await agenda!.every(interval, name)\n logInfo(LogCategory.INIT, 'Cron task scheduled', { name, interval })\n } catch (err) {\n logError(\n LogCategory.INIT,\n 'An unknown error occured while initing the cron tasks',\n { error: unknownToString(err) }\n )\n return await errHandler?.(err)\n }\n}\n", "import { Readable } from 'node:stream'\nimport { hrtime } from 'node:process'\nimport { Storage as GcsStorage, Bucket as GCSBucket } from '@google-cloud/storage'\nimport { S3Client, ListObjectsV2Command } from '@aws-sdk/client-s3'\nimport { Client as FtpsClient } from 'basic-ftp'\nimport SftpClient from 'ssh2-sftp-client'\nimport { Outcome } from '@design-edito/tools/agnostic/misc/outcome/index.js'\nimport { sanitizePath } from '@design-edito/tools/agnostic/sanitization/index.js'\nimport {\n isFtpClient,\n isGcsBucket,\n isS3ClientWithBucket,\n isSftpClient\n} from '@design-edito/tools/node/cloud-storage/clients/index.js'\nimport { unknownToString } from '@design-edito/tools/agnostic/errors/unknown-to-string/index.js'\nimport {\n logError,\n logInfo\n} from '../logs/index.js'\nimport { Category as LogCategory } from '../types/logs/index.js'\nimport env from '../env/index.js'\nimport {\n CopyDir,\n CopyDirErrCode,\n CopyFile,\n CopyFileErrCode,\n DownloadFile,\n DownloadFileErrCode,\n ExistsFile,\n ExistsFileErrCode,\n ListDir,\n ListDirErrCode,\n MoveDir,\n MoveDirErrCode,\n MoveFile,\n MoveFileErrCode,\n RemoveDir,\n RemoveDirErrCode,\n RemoveFile,\n RemoveFileErrCode,\n StatFile,\n StatFileErrCode,\n UploadFileErrCode,\n type Client,\n type GetClient,\n type UploadFile\n} from '../types/fs/index.js'\n\n// Upload file\nimport { upload as s3UploadFile } from '@design-edito/tools/node/@aws-s3/storage/file/upload/index.js'\nimport { upload as gcsUploadFile } from '@design-edito/tools/node/@google-cloud/storage/file/upload/index.js'\nimport { upload as ftpsUploadFile } from '@design-edito/tools/node/ftps/file/upload/index.js'\nimport { upload as sftpUploadFile } from '@design-edito/tools/node/sftp/file/upload/index.js'\n// Copy file\nimport { copy as s3CopyFile } from '@design-edito/tools/node/@aws-s3/storage/file/copy/index.js'\nimport { copy as gcsCopyFile } from '@design-edito/tools/node/@google-cloud/storage/file/copy/index.js'\nimport { copy as ftpsCopyFile } from '@design-edito/tools/node/ftps/file/copy/index.js'\nimport { copy as sftpCopyFile } from '@design-edito/tools/node/sftp/file/copy/index.js'\n// Move file\nimport { move as s3MoveFile } from '@design-edito/tools/node/@aws-s3/storage/file/move/index.js'\nimport { move as gcsMoveFile } from '@design-edito/tools/node/@google-cloud/storage/file/move/index.js'\nimport { move as ftpsMoveFile } from '@design-edito/tools/node/ftps/file/move/index.js'\nimport { move as sftpMoveFile } from '@design-edito/tools/node/sftp/file/move/index.js'\n// Download file\nimport { download as s3DownloadFile } from '@design-edito/tools/node/@aws-s3/storage/file/download/index.js'\nimport { download as gcsDownloadFile } from '@design-edito/tools/node/@google-cloud/storage/file/download/index.js'\nimport { download as ftpsDownloadFile } from '@design-edito/tools/node/ftps/file/download/index.js'\nimport { download as sftpDownloadFile } from '@design-edito/tools/node/sftp/file/download/index.js'\n// Exists file\nimport { exists as s3ExistsFile } from '@design-edito/tools/node/@aws-s3/storage/file/exists/index.js'\nimport { exists as gcsExistsFile } from '@design-edito/tools/node/@google-cloud/storage/file/exists/index.js'\nimport { exists as ftpsExistsFile } from '@design-edito/tools/node/ftps/file/exists/index.js'\nimport { exists as sftpExistsFile } from '@design-edito/tools/node/sftp/file/exists/index.js'\n// Stat file\nimport { stat as s3StatFile, Stat as S3Stat } from '@design-edito/tools/node/@aws-s3/storage/file/stat/index.js'\nimport { stat as gcsStatFile, Stat as GCSStat } from '@design-edito/tools/node/@google-cloud/storage/file/stat/index.js'\nimport { stat as ftpsStatFile, Stat as FtpsStat } from '@design-edito/tools/node/ftps/file/stat/index.js'\nimport { stat as sftpStatFile, Stat as SftpStat } from '@design-edito/tools/node/sftp/file/stat/index.js'\n// Remove file\nimport { remove as s3RemoveFile } from '@design-edito/tools/node/@aws-s3/storage/file/remove/index.js'\nimport { remove as gcsRemoveFile } from '@design-edito/tools/node/@google-cloud/storage/file/remove/index.js'\nimport { remove as ftpsRemoveFile } from '@design-edito/tools/node/ftps/file/remove/index.js'\nimport { remove as sftpRemoveFile } from '@design-edito/tools/node/sftp/file/remove/index.js'\n// Copy dir\nimport { copyDir as s3CopyDir } from '@design-edito/tools/node/@aws-s3/storage/directory/copy-dir/index.js'\nimport { copyDir as gcsCopyDir } from '@design-edito/tools/node/@google-cloud/storage/directory/copy-dir/index.js'\nimport { copyDir as ftpsCopyDir } from '@design-edito/tools/node/ftps/directory/copy-dir/index.js'\nimport { copyDir as sftpCopyDir } from '@design-edito/tools/node/sftp/directory/copy-dir/index.js'\n// Move dir\nimport { moveDir as s3MoveDir } from '@design-edito/tools/node/@aws-s3/storage/directory/move-dir/index.js'\nimport { moveDir as gcsMoveDir } from '@design-edito/tools/node/@google-cloud/storage/directory/move-dir/index.js'\nimport { moveDir as ftpsMoveDir } from '@design-edito/tools/node/ftps/directory/move-dir/index.js'\nimport { moveDir as sftpMoveDir } from '@design-edito/tools/node/sftp/directory/move-dir/index.js'\n// List dir\nimport { list as s3ListDir } from '@design-edito/tools/node/@aws-s3/storage/directory/list/index.js'\nimport { list as gcsListDir } from '@design-edito/tools/node/@google-cloud/storage/directory/list/index.js'\nimport { list as ftpsListDir } from '@design-edito/tools/node/ftps/directory/list/index.js'\nimport { list as sftpListDir } from '@design-edito/tools/node/sftp/directory/list/index.js'\n// Remove dir\nimport { removeDir as s3RemoveDir } from '@design-edito/tools/node/@aws-s3/storage/directory/remove-dir/index.js'\nimport { removeDir as gcsRemoveDir } from '@design-edito/tools/node/@google-cloud/storage/directory/remove-dir/index.js'\nimport { removeDir as ftpsRemoveDir } from '@design-edito/tools/node/ftps/directory/remove-dir/index.js'\nimport { removeDir as sftpRemoveDir } from '@design-edito/tools/node/sftp/directory/remove-dir/index.js'\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * Client\n * \n * * * * * * * * * * * * * * * * * * * * */\n\nlet _client: Client\n\nif (env.FS_STORAGE_TYPE === 'gcs') {\n const gcsBucket = new GcsStorage({\n projectId: env.FS_STORAGE_GCS_PROJECT_ID,\n credentials: {\n client_email: env.FS_STORAGE_GCS_CLIENT_EMAIL,\n private_key: env.FS_STORAGE_GCS_PRIVATE_KEY\n }\n }).bucket(env.FS_STORAGE_GCS_BUCKET_NAME)\n _client = gcsBucket\n} else if (env.FS_STORAGE_TYPE === 'aws') {\n const awsClient = {\n bucketName: env.FS_STORAGE_AWS_BUCKET_NAME,\n client: new S3Client({\n region: env.FS_STORAGE_AWS_REGION,\n credentials: {\n accessKeyId: env.FS_STORAGE_AWS_ACCESS_KEY_ID,\n secretAccessKey: env.FS_STORAGE_AWS_SECRET_ACCESS_KEY!\n }\n })\n }\n _client = awsClient\n} else if (env.FS_STORAGE_TYPE === 'ftps') {\n const ftpClient = new FtpsClient()\n _client = ftpClient\n} else {\n const sftpClient = new SftpClient()\n _client = sftpClient\n}\n\nexport const getClient: GetClient = async () => {\n if (isGcsBucket(_client)) return Outcome.makeSuccess(_client)\n if (isS3ClientWithBucket(_client)) return Outcome.makeSuccess(_client)\n if (isFtpClient(_client) && env.FS_STORAGE_TYPE === 'ftps') {\n try {\n await _client.send('NOOP')\n return Outcome.makeSuccess(_client)\n } catch {\n try {\n await _client.access({\n host: env.FS_STORAGE_FTP_HOST,\n port: Number(env.FS_STORAGE_FTP_PORT),\n user: env.FS_STORAGE_FTP_USER,\n password: env.FS_STORAGE_FTP_PASSWORD,\n secure: true\n })\n return Outcome.makeSuccess(_client)\n } catch (err) {\n return Outcome.makeFailure(unknownToString(err))\n }\n }\n }\n if (isSftpClient(_client) && env.FS_STORAGE_TYPE === 'sftp') {\n try {\n await _client.list('.')\n return Outcome.makeSuccess(_client)\n } catch (err) {\n try {\n await _client.connect({\n host: env.FS_STORAGE_FTP_HOST,\n port: Number(env.FS_STORAGE_FTP_PORT),\n username: env.FS_STORAGE_FTP_USER,\n password: env.FS_STORAGE_FTP_PASSWORD,\n // optionally privateKey: process.env.SFTP_PRIVATE_KEY,\n // and other ssh2 options\n })\n return Outcome.makeSuccess(_client)\n } catch (err) {\n return Outcome.makeFailure(unknownToString(err))\n }\n }\n }\n\n // [WIP] something is wrong here, should not happen\n return Outcome.makeFailure('Client is not available')\n // _client is SftpClient\n}\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * Ping\n * \n * * * * * * * * * * * * * * * * * * * * */\n\nexport async function ping(): Promise<Outcome.Either<number, string>> {\n const clientAccess = await getClient()\n if (!clientAccess.success) return Outcome.makeFailure(clientAccess.error)\n const client = clientAccess.payload\n const start = hrtime()\n try {\n if (isGcsBucket(client)) await client.getFiles({\n maxResults: 1\n })\n else if (isS3ClientWithBucket(client)) await client.client.send(new ListObjectsV2Command({\n Bucket: client.bucketName,\n MaxKeys: 1\n }))\n else if (isFtpClient(client)) {\n if (client.closed) return Outcome.makeFailure('ftps client is closed')\n await client.list('/')\n } else if (client instanceof SftpClient) await client.list('.')\n else return Outcome.makeFailure('Unknown client type')\n const diff = hrtime(start)\n const durationMs = (diff[0] * 1e3) + (diff[1] / 1e6)\n return Outcome.makeSuccess(durationMs)\n } catch (err) {\n return Outcome.makeFailure(unknownToString(err))\n }\n}\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * Upload file\n * \n * * * * * * * * * * * * * * * * * * * * */\n\nexport const uploadFileSilent: UploadFile = async (fileDescriptor, overwrite) => {\n const clientAccess = await getClient()\n if (!clientAccess.success) return Outcome.makeFailure({ code: UploadFileErrCode.CLIENT_NOT_AVAILABLE })\n const client = clientAccess.payload\n const { path, hash, byteSize, mimeType, description } = fileDescriptor\n if (path !== sanitizePath(path)) return Outcome.makeFailure({ code: UploadFileErrCode.PATH_NOT_AllLOWED })\n const scannedFile = Readable.from(fileDescriptor.scannedFile)\n let uploadAttempt: Outcome.Either<true, string>\n if (isGcsBucket(client)) {\n uploadAttempt = await gcsUploadFile(\n client,\n path,\n scannedFile, {\n overwrite,\n saveOptions: {\n contentType: mimeType,\n metadata: {\n description,\n byteSize,\n hash\n }\n }\n }\n )\n } else if (isS3ClientWithBucket(client)) {\n uploadAttempt = await s3UploadFile(\n client.client,\n client.bucketName,\n path,\n scannedFile, {\n overwrite,\n fileMetadata: {\n ContentType: mimeType,\n ContentLength: byteSize,\n Metadata: {\n description,\n hash\n }\n }\n }\n )\n } else if (isFtpClient(client)) {\n uploadAttempt = await ftpsUploadFile(\n client,\n path,\n scannedFile, {\n overwrite,\n ensureDir: true\n }\n )\n } else {\n uploadAttempt = await sftpUploadFile(\n client,\n path,\n scannedFile, {\n overwrite,\n ensureDir: true\n }\n )\n }\n if (uploadAttempt.success) return Outcome.makeSuccess(true)\n return Outcome.makeFailure({\n code: UploadFileErrCode.UPLOAD_FAILED,\n details: uploadAttempt.error\n })\n}\n\nexport const uploadFile: typeof uploadFileSilent = async function (fileDescriptor, overwrite) {\n const uploadResult = await uploadFileSilent(fileDescriptor, overwrite)\n const { byteSize, path } = fileDescriptor\n if (uploadResult.success) {\n logInfo(LogCategory.FS, 'File uploaded', { path, byteSize })\n return uploadResult\n }\n logError(LogCategory.FS, 'Failed to upload file', { path, byteSize, reason: uploadResult.error })\n return uploadResult\n}\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * Copy file\n * \n * * * * * * * * * * * * * * * * * * * * */\n\nexport const copyFileSilent: CopyFile = async (srcPath, destPath, overwrite) => {\n const clientAccess = await getClient()\n if (!clientAccess.success) return Outcome.makeFailure({ code: CopyFileErrCode.CLIENT_NOT_AVAILABLE })\n const client = clientAccess.payload\n if (destPath !== sanitizePath(destPath)) return Outcome.makeFailure({ code: CopyFileErrCode.DEST_PATH_NOT_AllLOWED })\n let copyAttempt: Outcome.Either<true, string>\n if (isGcsBucket(client)) { copyAttempt = await gcsCopyFile(client, srcPath, destPath, { overwrite }) }\n else if (isS3ClientWithBucket(client)) { copyAttempt = await s3CopyFile(client.client, client.bucketName, srcPath, destPath, { overwrite }) }\n else if (isFtpClient(client)) { copyAttempt = await ftpsCopyFile(client, srcPath, destPath, { overwrite, ensureDir: true }) }\n else { copyAttempt = await sftpCopyFile(client, srcPath, destPath, { overwrite, ensureDir: true }) }\n if (copyAttempt.success) return Outcome.makeSuccess(true)\n return Outcome.makeFailure({\n code: CopyFileErrCode.COPY_FAILED,\n details: copyAttempt.error\n })\n}\n\nexport const copyFile: typeof copyFileSilent = async function (srcPath, destPath, overwrite) {\n const copyResult = await copyFileSilent(srcPath, destPath, overwrite)\n if (copyResult.success) {\n logInfo(LogCategory.FS, 'File copied', { srcPath, destPath })\n return copyResult\n }\n logError(LogCategory.FS, 'Failed to copy file', { srcPath, destPath, reason: copyResult.error })\n return copyResult\n}\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * Move file\n * \n * * * * * * * * * * * * * * * * * * * * */\n\nexport const moveFileSilent: MoveFile = async (srcPath, destPath, overwrite) => {\n const clientAccess = await getClient()\n if (!clientAccess.success) return Outcome.makeFailure({ code: MoveFileErrCode.CLIENT_NOT_AVAILABLE })\n const client = clientAccess.payload\n if (destPath !== sanitizePath(destPath)) return Outcome.makeFailure({ code: MoveFileErrCode.DEST_PATH_NOT_AllLOWED })\n let moveAttempt: Outcome.Either<true, string>\n if (isGcsBucket(client)) { moveAttempt = await gcsMoveFile(client, srcPath, destPath, { overwrite }) }\n else if (isS3ClientWithBucket(client)) { moveAttempt = await s3MoveFile(client.client, client.bucketName, srcPath, destPath, { overwrite }) }\n else if (isFtpClient(client)) { moveAttempt = await ftpsMoveFile(client, srcPath, destPath, { overwrite, ensureDir: true }) }\n else { moveAttempt = await sftpMoveFile(client, srcPath, destPath, { overwrite, ensureDir: true }) }\n if (moveAttempt.success) return Outcome.makeSuccess(true)\n return Outcome.makeFailure({\n code: MoveFileErrCode.MOVE_FAILED,\n details: moveAttempt.error\n })\n}\n\nexport const moveFile: typeof moveFileSilent = async function (srcPath, destPath, overwrite) {\n const moveResult = await moveFileSilent(srcPath, destPath, overwrite)\n if (moveResult.success) {\n logInfo(LogCategory.FS, 'File moved', { srcPath, destPath })\n return moveResult\n }\n logError(LogCategory.FS, 'Failed to move file', { srcPath, destPath, reason: moveResult.error })\n return moveResult\n}\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * Download file\n * \n * * * * * * * * * * * * * * * * * * * * */\n\nexport const downloadFileSilent: DownloadFile = async (targetPath) => {\n const clientAccess = await getClient()\n if (!clientAccess.success) return Outcome.makeFailure({ code: DownloadFileErrCode.CLIENT_NOT_AVAILABLE })\n const client = clientAccess.payload\n if (targetPath !== sanitizePath(targetPath)) return Outcome.makeFailure({ code: DownloadFileErrCode.PATH_NOT_AllLOWED })\n let downloadAttempt: Outcome.Either<Readable, string>\n if (isGcsBucket(client)) { downloadAttempt = await gcsDownloadFile(client, targetPath) }\n else if (isS3ClientWithBucket(client)) { downloadAttempt = await s3DownloadFile(client.client, client.bucketName, targetPath) }\n else if (isFtpClient(client)) { downloadAttempt = await ftpsDownloadFile(client, targetPath) }\n else { downloadAttempt = await sftpDownloadFile(client, targetPath) }\n if (downloadAttempt.success) return Outcome.makeSuccess(true)\n return Outcome.makeFailure({\n code: DownloadFileErrCode.DOWNLOAD_FAILED,\n details: downloadAttempt.error\n })\n}\n\nexport const downloadFile: typeof downloadFileSilent = async function (targetPath) {\n const downloadResult = await downloadFileSilent(targetPath)\n if (downloadResult.success) {\n logInfo(LogCategory.FS, 'File download', { targetPath })\n return downloadResult\n }\n logError(LogCategory.FS, 'Failed to download file', { targetPath, reason: downloadResult.error })\n return downloadResult\n}\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * Exists file\n * \n * * * * * * * * * * * * * * * * * * * * */\n\nexport const existsFileSilent: ExistsFile = async (targetPath) => {\n const clientAccess = await getClient()\n if (!clientAccess.success) return Outcome.makeFailure({ code: ExistsFileErrCode.CLIENT_NOT_AVAILABLE })\n const client = clientAccess.payload\n if (targetPath !== sanitizePath(targetPath)) return Outcome.makeFailure({ code: ExistsFileErrCode.PATH_NOT_AllLOWED })\n let existsAttempt: Outcome.Either<boolean, string>\n if (isGcsBucket(client)) { existsAttempt = await gcsExistsFile(client, targetPath) }\n else if (isS3ClientWithBucket(client)) { existsAttempt = await s3ExistsFile(client.client, client.bucketName, targetPath) }\n else if (isFtpClient(client)) { existsAttempt = await ftpsExistsFile(client, targetPath) }\n else { existsAttempt = await sftpExistsFile(client, targetPath) }\n if (existsAttempt.success) return Outcome.makeSuccess(true)\n return Outcome.makeFailure({\n code: ExistsFileErrCode.EXISTS_FAILED,\n details: existsAttempt.error\n })\n}\n\nexport const existsFile: typeof existsFileSilent = async function (targetPath) {\n const existsResult = await existsFileSilent(targetPath)\n if (existsResult.success) {\n logInfo(LogCategory.FS, 'File exists', { targetPath })\n return existsResult\n }\n logError(LogCategory.FS, 'Failed to exists file', { targetPath, reason: existsResult.error })\n return existsResult\n}\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * Stat file\n * \n * * * * * * * * * * * * * * * * * * * * */\n\nexport const statFileSilent: StatFile = async (targetPath) => {\n const clientAccess = await getClient()\n if (!clientAccess.success) return Outcome.makeFailure({ code: StatFileErrCode.CLIENT_NOT_AVAILABLE })\n const client = clientAccess.payload\n if (targetPath !== sanitizePath(targetPath)) return Outcome.makeFailure({ code: StatFileErrCode.PATH_NOT_AllLOWED })\n let statAttempt: Outcome.Either<GCSStat | S3Stat | FtpsStat | SftpStat, string>\n if (isGcsBucket(client)) { statAttempt = await gcsStatFile(client, targetPath) }\n else if (isS3ClientWithBucket(client)) { statAttempt = await s3StatFile(client.client, client.bucketName, targetPath) }\n else if (isFtpClient(client)) { statAttempt = await ftpsStatFile(client, targetPath) }\n else { statAttempt = await sftpStatFile(client, targetPath) }\n if (statAttempt.success) return Outcome.makeSuccess(true)\n return Outcome.makeFailure({\n code: StatFileErrCode.STAT_FAILED,\n details: statAttempt.error\n })\n}\n\nexport const statFile: typeof statFileSilent = async function (targetPath) {\n const statResult = await statFileSilent(targetPath)\n if (statResult.success) {\n logInfo(LogCategory.FS, 'File stat', { targetPath })\n return statResult\n }\n logError(LogCategory.FS, 'Failed to stat file', { targetPath, reason: statResult.error })\n return statResult\n}\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * Remove file\n * \n * * * * * * * * * * * * * * * * * * * * */\n\nexport const removeFileSilent: RemoveFile = async (targetPath) => {\n const clientAccess = await getClient()\n if (!clientAccess.success) return Outcome.makeFailure({ code: RemoveFileErrCode.CLIENT_NOT_AVAILABLE })\n const client = clientAccess.payload\n if (targetPath !== sanitizePath(targetPath)) return Outcome.makeFailure({ code: RemoveFileErrCode.PATH_NOT_AllLOWED })\n let removeAttempt: Outcome.Either<true, string>\n if (isGcsBucket(client)) { removeAttempt = await gcsRemoveFile(client, targetPath) }\n else if (isS3ClientWithBucket(client)) { removeAttempt = await s3RemoveFile(client.client, client.bucketName, targetPath) }\n else if (isFtpClient(client)) { removeAttempt = await ftpsRemoveFile(client, targetPath) }\n else { removeAttempt = await sftpRemoveFile(client, targetPath) }\n if (removeAttempt.success) return Outcome.makeSuccess(true)\n return Outcome.makeFailure({\n code: RemoveFileErrCode.REMOVE_FAILED,\n details: removeAttempt.error\n })\n}\n\nexport const removeFile: typeof removeFileSilent = async function (targetPath) {\n const removeResult = await removeFileSilent(targetPath)\n if (removeResult.success) {\n logInfo(LogCategory.FS, 'File removed', { targetPath })\n return removeResult\n }\n logError(LogCategory.FS, 'Failed to remove file', { targetPath, reason: removeResult.error })\n return removeResult\n}\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * Copy dir\n * \n * * * * * * * * * * * * * * * * * * * * */\n\nexport const copyDirSilent: CopyDir = async (srcPath, destPath, overwrite) => {\n const clientAccess = await getClient()\n if (!clientAccess.success) return Outcome.makeFailure({ code: CopyDirErrCode.CLIENT_NOT_AVAILABLE })\n const client = clientAccess.payload\n if (destPath !== sanitizePath(destPath)) return Outcome.makeFailure({ code: CopyDirErrCode.DEST_PATH_NOT_AllLOWED })\n let copyAttempt: Outcome.Either<true, string>\n if (isGcsBucket(client)) { copyAttempt = await gcsCopyDir(client, srcPath, destPath, { overwrite }) }\n else if (isS3ClientWithBucket(client)) { copyAttempt = await s3CopyDir(client.client, client.bucketName, srcPath, destPath, { overwrite }) }\n else if (isFtpClient(client)) { copyAttempt = await ftpsCopyDir(client, srcPath, destPath, { overwrite, ensureDir: true }) }\n else { copyAttempt = await sftpCopyDir(client, srcPath, destPath, { overwrite, ensureDir: true }) }\n if (copyAttempt.success) return Outcome.makeSuccess(true)\n return Outcome.makeFailure({\n code: CopyDirErrCode.COPY_FAILED,\n details: copyAttempt.error\n })\n}\n\nexport const copyDir: typeof copyDirSilent = async function (srcPath, destPath, overwrite) {\n const copyResult = await copyDirSilent(srcPath, destPath, overwrite)\n if (copyResult.success) {\n logInfo(LogCategory.FS, 'Directory copied', { srcPath, destPath })\n return copyResult\n }\n logError(LogCategory.FS, 'Failed to copy directory', { srcPath, destPath, reason: copyResult.error })\n return copyResult\n}\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * Move dir\n * \n * * * * * * * * * * * * * * * * * * * * */\n\nexport const moveDirSilent: MoveDir = async (srcPath, destPath, overwrite) => {\n const clientAccess = await getClient()\n if (!clientAccess.success) return Outcome.makeFailure({ code: MoveDirErrCode.CLIENT_NOT_AVAILABLE })\n const client = clientAccess.payload\n if (destPath !== sanitizePath(destPath)) return Outcome.makeFailure({ code: MoveDirErrCode.DEST_PATH_NOT_AllLOWED })\n let moveAttempt: Outcome.Either<true, string>\n if (isGcsBucket(client)) { moveAttempt = await gcsMoveDir(client, srcPath, destPath, { overwrite }) }\n else if (isS3ClientWithBucket(client)) { moveAttempt = await s3MoveDir(client.client, client.bucketName, srcPath, destPath, { overwrite }) }\n else if (isFtpClient(client)) { moveAttempt = await ftpsMoveDir(client, srcPath, destPath, { overwrite, ensureDir: true }) }\n else { moveAttempt = await sftpMoveDir(client, srcPath, destPath, { overwrite, ensureDir: true }) }\n if (moveAttempt.success) return Outcome.makeSuccess(true)\n return Outcome.makeFailure({\n code: MoveDirErrCode.MOVE_FAILED,\n details: moveAttempt.error\n })\n}\n\nexport const moveDir: typeof moveDirSilent = async function (srcPath, destPath, overwrite) {\n const moveResult = await moveDirSilent(srcPath, destPath, overwrite)\n if (moveResult.success) {\n logInfo(LogCategory.FS, 'Directory moved', { srcPath, destPath })\n return moveResult\n }\n logError(LogCategory.FS, 'Failed to move directory', { srcPath, destPath, reason: moveResult.error })\n return moveResult\n}\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * List dir\n * \n * * * * * * * * * * * * * * * * * * * * */\n\nexport const listDirSilent: ListDir = async (targetPath) => {\n const clientAccess = await getClient()\n if (!clientAccess.success) return Outcome.makeFailure({ code: ListDirErrCode.CLIENT_NOT_AVAILABLE })\n const client = clientAccess.payload\n if (targetPath !== sanitizePath(targetPath)) return Outcome.makeFailure({ code: ListDirErrCode.PATH_NOT_AllLOWED })\n let listAttempt: Outcome.Either<string[], string>\n if (isGcsBucket(client)) { listAttempt = await gcsListDir(client, targetPath) }\n else if (isS3ClientWithBucket(client)) { listAttempt = await s3ListDir(client.client, client.bucketName, targetPath) }\n else if (isFtpClient(client)) { listAttempt = await ftpsListDir(client, targetPath) }\n else { listAttempt = await sftpListDir(client, targetPath) }\n if (listAttempt.success) return Outcome.makeSuccess(listAttempt.payload)\n return Outcome.makeFailure({\n code: ListDirErrCode.LIST_FAILED,\n details: listAttempt.error\n })\n}\n\nexport const listDir: typeof listDirSilent = async function (targetPath) {\n const listResult = await listDirSilent(targetPath)\n if (listResult.success) {\n logInfo(LogCategory.FS, 'Directory listed', { targetPath })\n return listResult\n }\n logError(LogCategory.FS, 'Failed to list directory', { targetPath, reason: listResult.error })\n return listResult\n}\n\n/* * * * * * * * * * * * * * * * * * * * *\n *\n * Remove dir\n * \n * * * * * * * * * * * * * * * * * * * * */\n\nexport const removeDirSilent: RemoveDir = async (targetPath) => {\n const clientAccess = await getClient()\n if (!clientAccess.success) return Outcome.makeFailure({ code: RemoveDirErrCode.CLIENT_NOT_AVAILABLE })\n const client = clientAccess.payload\n if (targetPath !== sanitizePath(targetPath)) return Outcome.makeFailure({ code: RemoveDirErrCode.PATH_NOT_AllLOWED })\n let removeAttempt: Outcome.Either<true, string>\n if (isGcsBucket(client)) { removeAttempt = await gcsRemoveDir(client, targetPath) }\n else if (isS3ClientWithBucket(client)) { removeAttempt = await s3RemoveDir(client.client, client.bucketName, targetPath) }\n else if (isFtpClient(client)) { removeAttempt = await ftpsRemoveDir(client, targetPath) }\n else { removeAttempt = await sftpRemoveDir(client, targetPath) }\n if (removeAttempt.success) return Outcome.makeSuccess(true)\n return Outcome.makeFailure({\n code: RemoveDirErrCode.REMOVE_FAILED,\n details: removeAttempt.error\n })\n}\n\nexport const removeDir: typeof removeDirSilent = async function (targetPath) {\n const removeResult = await removeDirSilent(targetPath)\n if (removeResult.success) {\n logInfo(LogCategory.FS, 'Directory removed', { targetPath })\n return removeResult\n }\n logError(LogCategory.FS, 'Failed to remove directory', { targetPath, reason: removeResult.error })\n return removeResult\n}\n", "import { SystemStatusCheckProcessContract } from '../../../types/api/system/status-check/index.js'\nimport { noAuthNullValidation } from '../../../validation/index.js'\nimport { operation } from './operation.js'\n\nexport const statusCheck: SystemStatusCheckProcessContract = {\n _authType: 'none',\n _opType: 'json',\n validation: noAuthNullValidation,\n operation\n}\n", "import { kill } from './kill/index.js'\nimport { ping } from './ping/index.js'\nimport { sendMail } from './send-mail/index.js'\nimport { statusCheck } from './status-check/index.js'\n\nexport const system = {\n kill,\n ping,\n sendMail,\n statusCheck\n}\n", "import { ENDPOINT, Contracts } from '../types/api/index.js'\nimport { admin } from './admin/index.js'\nimport { auth } from './auth/index.js'\nimport { csrf } from './csrf/index.js'\nimport { image } from './image/index.js'\nimport { system } from './system/index.js'\nimport { makeRouter } from './utils.js'\n\nexport const ROUTES: Contracts = {\n // CSRF\n [ENDPOINT.CSRF_GET_TOKEN]: csrf.getToken,\n\n // System\n [ENDPOINT.SYSTEM_KILL]: system.kill,\n [ENDPOINT.SYSTEM_PING]: system.ping,\n [ENDPOINT.SYSTEM_SEND_MAIL]: system.sendMail,\n [ENDPOINT.SYSTEM_STATUS_CHECK_GET]: system.statusCheck,\n [ENDPOINT.SYSTEM_STATUS_CHECK_POST]: system.statusCheck,\n\n // Auth\n [ENDPOINT.AUTH_LOGIN]: auth.login,\n [ENDPOINT.AUTH_LOGOUT]: auth.logout,\n [ENDPOINT.AUTH_LOGOUT_EVERYWHERE]: auth.logoutEverywhere,\n [ENDPOINT.AUTH_REFRESH_TOKEN]: auth.refreshToken,\n [ENDPOINT.AUTH_REQUEST_EMAIL_VERIFICATION_TOKEN]: auth.requestEmailVerificationToken,\n [ENDPOINT.AUTH_REQUEST_NEW_PASSWORD]: auth.requestNewPassword,\n [ENDPOINT.AUTH_SIGNUP]: auth.signup,\n [ENDPOINT.AUTH_SUBMIT_NEW_PASSWORD]: auth.submitNewPassword,\n [ENDPOINT.AUTH_VERIFY_EMAIL]: auth.verifyEmail,\n [ENDPOINT.AUTH_WHOAMI]: auth.whoami,\n [ENDPOINT.AUTH_WHOAMI_GET]: auth.whoami,\n\n // Admin\n [ENDPOINT.ADMIN_TEMP_FLUSH]: admin.temp.flush,\n [ENDPOINT.ADMIN_USERS_CREATE]: admin.users.create,\n [ENDPOINT.ADMIN_USERS_GET]: admin.users.get,\n [ENDPOINT.ADMIN_USERS_LIST]: admin.users.list,\n [ENDPOINT.ADMIN_USERS_UPDATE]: admin.users.update,\n [ENDPOINT.ADMIN_USERS_DELETE]: admin.users.delete,\n [ENDPOINT.ADMIN_USERS_REVOKE_AUTH_TOKENS]: admin.users.revokeAuthTokens,\n [ENDPOINT.ADMIN_USERS_REVOKE_EMAIL_VALIDATION_TOKENS]: admin.users.revokeEmailValidationTokens,\n [ENDPOINT.ADMIN_USERS_REVOKE_PASSWORD_RENEWAL_TOKENS]: admin.users.revokePasswordRenewalTokens,\n [ENDPOINT.ADMIN_USERS_GET_UPLOAD_QUOTA]: admin.users.getUploadQuota,\n [ENDPOINT.ADMIN_USERS_RESET_UPLOAD_QUOTA]: admin.users.resetUploadQuota,\n\n // Image\n [ENDPOINT.IMAGE_FORMAT]: image.format,\n [ENDPOINT.IMAGE_TRANSFORM]: image.transform\n}\n\nexport const router = makeRouter(ROUTES)\n", "import { Express, Router } from 'express'\nimport {\n ENDPOINT as PLUGIN_ENDPOINT,\n Contracts as PluginContracts,\n} from '../types/plugins/index.js'\nimport { Plugin } from '../types/plugins/internals.js'\nimport { makeRouter } from '../api/utils.js'\nimport { generatePlugin } from './utils.js'\nimport { scheduleCronTask } from '../cron/index.js'\n\nexport async function init (app: Express): Promise<Router> {\n // Plugins\n // const examplePlugin = await generatePlugin(examplePluginGenerator)\n const allPlugins: Plugin<PluginContracts>[] = []\n\n // Routes\n const ROUTES: PluginContracts = {}\n const router = makeRouter(ROUTES)\n app.use(router)\n\n // Tasks\n const TASKS = allPlugins.map(plugin => plugin.tasks).flat()\n TASKS.forEach(task => scheduleCronTask(\n task.name,\n task.interval,\n task.cronTask,\n task.errHandler\n ))\n\n return router\n}\n", "import { Request, Response, NextFunction } from 'express'\nimport env from '../env/index.js'\nimport { logInfo, logWarning } from '../logs/index.js'\nimport { Category as LogCategory } from '../types/logs/index.js'\nimport { errorResponse, sendServerErrorResponse } from '../api/utils.js'\nimport { Codes } from '../types/errors/index.js'\n\nexport function enforceHttpsMiddleware () {\n if (env.ALLOW_HTTP === 'true') logWarning(LogCategory.SSL, 'HTTP is allowed on this server')\n else logInfo(LogCategory.SSL, 'HTTPS is enforced on this server')\n return function (\n req: Request,\n res: Response,\n next: NextFunction\n ) {\n req.app.set('trust proxy', true)\n if (env.ALLOW_HTTP === 'true') next()\n else if (req.protocol === 'https') next()\n else {\n const { ips, method, path, protocol } = req\n logWarning(LogCategory.SSL, 'Forbidden incoming HTTP request', { protocol, method, path, ips })\n sendServerErrorResponse(res, errorResponse(403, Codes.HTTP_FORBIDDEN))\n }\n }\n}\n", "import cors from 'cors'\nimport env from '../env/index.js'\nimport { accessTokenHeader } from '../auth/index.js'\n\nexport const corsMiddleware = cors({\n origin: env.CORS_WHITELIST,\n credentials: true,\n allowedHeaders: ['Authorization', 'Content-Type', 'X-CSRF-Token'],\n exposedHeaders: [accessTokenHeader]\n})\n", "import http from 'node:http'\nimport debugModule from 'debug'\nimport { Express } from 'express'\nimport { shutdown } from '../init/index.js'\nimport { logFatal, logInfo } from '../logs/index.js'\nimport { Category as LogCategory } from '../types/logs/index.js'\nimport env from '../env/index.js'\n\ninterface NodeError extends Error {\n syscall?: string\n code?: string\n}\n\nexport function serve (app: Express) {\n const port = normalizePort(env.PORT)\n const debug = debugModule('lm-publisher:server')\n const server = http.createServer(app) // Https is assumed to be handled by the hosting service\n app.set('port', port)\n server.listen({ port: port, host: '0.0.0.0' })\n server.on('error', (error: NodeError) => {\n if (error.syscall !== 'listen') throw error\n var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port\n switch (error.code) {\n case 'EACCES':\n logFatal(LogCategory.WWW, `${bind} requires elevated privileges`)\n return shutdown(1)\n case 'EADDRINUSE':\n logFatal(LogCategory.WWW, `${bind} is already in use`)\n return shutdown(1)\n default:\n throw error\n }\n })\n server.on('listening', () => {\n var addr = server.address()\n var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + (addr?.port ?? '')\n debug('Listening on ' + bind)\n logInfo(LogCategory.WWW, 'Listening on ' + bind)\n })\n\n function normalizePort (val: string) {\n var port = parseInt(val, 10)\n if (isNaN(port)) return val\n if (port >= 0) return port\n return false\n }\n}\n"],
|
5
|
+
"mappings": ";AAAA,OAAOA,WAAU;AACjB,SAAS,qBAAqB;AAC9B,OAAO,kBAAkB;AACzB,OAAO,aAAa;AACpB,SAAS,YAAAC,iBAAgB;;;ACHzB,SAAS,wBAAwB;AACjC,SAAS,UAAAC,eAAc;AACvB,SAAS,YAAAC,iBAAgB;AACzB,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,SAAS,qBAAqB;AACvC,SAAS,cAA+C;AACxD,SAAS,0BAA0B;AACnC,SAAS,yBAAyB;AAClC,SAAS,0BAA0B;AACnC,SAAS,2BAA2B;AACpC,SAAS,mBAAAC,wBAAuB;AAChC,SAAS,aAAAC,kBAAiB;;;ACX1B,SAAS,kBAAkB;AAC3B,SAAS,WAAAC,gBAAe;AACxB,SAAS,uBAAuB;AAChC,SAAS,YAAAC,iBAAgB;AACzB,SAAS,mBAAAC,wBAAuB;AAEhC,OAAO,SAAS;AAChB,SAAS,SAASC,sBAAqB;;;ACRvC,SAAS,uBAAuB;AAChC,SAAS,WAAAC,gBAAe;AACxB;AAAA,EACE,WAAW;AAAA,EACX,eAAe;AAAA,EACf,cAAc;AAAA,OACT;;;ACNP,OAAO,YAAY;AACnB,SAAS,SAAS;AAGlB,OAAO,OAAO;AAGd,IAAM,YAAY,CAAC,KAAyB,eAAiC,OAAO,IACjF,MAAM,SAAS,EACf,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EACnB,OAAO,CAAC,MAAM,MAAM,EAAE;AAGzB,IAAM,aAAa,EAAE,OAAO;AAAA;AAAA,EAE1B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,2CAA2C,EAAE,KAAK,CAAC,QAAQ,OAAO,CAAC;AAAA;AAAA,EAGnE,YAAY,EAAE,KAAK,CAAC,QAAQ,OAAO,CAAC;AAAA,EACpC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACtB,gBAAgB,EAAE,OAAO,EAAE,UAAU,SAAO,UAAU,KAAK,GAAG,CAAC,EAAE,OAAO,SAAO,IAAI,SAAS,GAAG,EAAE,SAAS,kBAAkB,CAAC;AAAA;AAAA,EAG7H,aAAa,EAAE,KAAK,CAAC,WAAW,aAAa,CAAC;AAAA,EAC9C,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACzB,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,EAC7B,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,QAAQ,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACxB,yCAAyC,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA,EAGzD,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE;AAAA,EAC/B,gBAAgB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAChC,iBAAiB,EAAE,OAAO,EAAE,MAAM;AAAA,EAClC,eAAe,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAE/B,oBAAoB,EAAE,OAAO,EAAE,IAAI,EAAE;AAAA,EACrC,sBAAsB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACtC,uBAAuB,EAAE,OAAO,EAAE,MAAM;AAAA,EACxC,qBAAqB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA,EAGrC,8CAA8C,EAAE,OAAO,EAAE,UAAU,OAAK,SAAS,CAAC,CAAC,EAAE,OAAO,OAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,mBAAmB,CAAC;AAAA,EAC3I,8CAA8C,EAAE,OAAO,EAAE,UAAU,OAAK,SAAS,CAAC,CAAC,EAAE,OAAO,OAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,mBAAmB,CAAC;AAAA,EAE3I,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAE5B,iCAAiC,EAAE,OAAO,EAAE,UAAU,OAAK,WAAW,CAAC,CAAC,EAAE,OAAO,OAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,mBAAmB,CAAC;AAAA,EAChI,wCAAwC,EAAE,OAAO,EAAE,UAAU,OAAK,WAAW,CAAC,CAAC,EAAE,OAAO,OAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,mBAAmB,CAAC;AAAA,EACvI,kCAAkC,EAAE,OAAO,EAAE,UAAU,OAAK,WAAW,CAAC,CAAC,EAAE,OAAO,OAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,mBAAmB,CAAC;AAAA,EACjI,gCAAgC,EAAE,OAAO,EAAE,UAAU,OAAK,WAAW,CAAC,CAAC,EAAE,OAAO,OAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,mBAAmB,CAAC;AAAA,EAC/H,iCAAiC,EAAE,OAAO,EAAE,UAAU,OAAK,WAAW,CAAC,CAAC,EAAE,OAAO,OAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,mBAAmB,CAAC;AAAA,EAEhI,uCAAuC,EAAE,OAAO,EAAE,UAAU,OAAK,WAAW,CAAC,CAAC,EAAE,OAAO,OAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,mBAAmB,CAAC;AAAA,EACtI,8CAA8C,EAAE,OAAO,EAAE,UAAU,OAAK,WAAW,CAAC,CAAC,EAAE,OAAO,OAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,mBAAmB,CAAC;AAAA,EAC7I,wCAAwC,EAAE,OAAO,EAAE,UAAU,OAAK,WAAW,CAAC,CAAC,EAAE,OAAO,OAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,mBAAmB,CAAC;AAAA,EACvI,sCAAsC,EAAE,OAAO,EAAE,UAAU,OAAK,WAAW,CAAC,CAAC,EAAE,OAAO,OAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,mBAAmB,CAAC;AAAA,EACrI,uCAAuC,EAAE,OAAO,EAAE,UAAU,OAAK,WAAW,CAAC,CAAC,EAAE,OAAO,OAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,mBAAmB,CAAC;AAAA;AAAA,EAGtI,iBAAiB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACjC,6BAA6B,EAAE,OAAO,EAAE,UAAU,OAAK,WAAW,CAAC,CAAC,EAAE,OAAO,OAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,mBAAmB,CAAC;AAAA;AAAA,EAG5H,kBAAkB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAClC,mBAAmB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA;AAAA,EAGnC,mCAAmC,EAAE,OAAO,EAAE,UAAU,OAAK,SAAS,CAAC,CAAC,EAAE,OAAO,OAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,mBAAmB,CAAC;AAAA,EAChI,qCAAqC,EAAE,OAAO,EAAE,UAAU,OAAK,SAAS,CAAC,CAAC,EAAE,OAAO,OAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,mBAAmB,CAAC;AAAA,EAClI,mCAAmC,EAAE,OAAO,EAAE,UAAU,OAAK,SAAS,CAAC,CAAC,EAAE,OAAO,OAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,mBAAmB,CAAC;AAAA,EAChI,gCAAgC,EAAE,OAAO,EAAE,UAAU,OAAK,UAAU,GAAG,GAAG,CAAC,EAAE,OAAO,SAAO,IAAI,SAAS,GAAG,EAAE,SAAS,kBAAkB,CAAC;AAAA;AAAA,EAGzI,iBAAiB,EAAE,KAAK,CAAC,QAAQ,OAAO,CAAC;AAAA,EACzC,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,UAAU,OAAK,SAAS,CAAC,CAAC,EAAE,OAAO,OAAK,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,mBAAmB,CAAC,EAAE,SAAS;AAAA,EAC5H,kBAAkB,EAAE,KAAK,CAAC,QAAQ,KAAK,CAAC;AAAA;AAAA,EAGxC,kBAAkB,EAAE,OAAO;AAC7B,CAAC;AAGD,IAAM,gBAAgB,EAAE,mBAAmB,gBAAgB;AAAA,EACzD,EAAE,OAAO;AAAA,IACP,cAAc,EAAE,QAAQ,YAAY;AAAA,IACpC,4BAA4B,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IAC5C,kCAAkC,EAAE,OAAO,EAAE,MAAM;AAAA,IACnD,iCAAiC,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EACnD,CAAC;AAAA,EACD,EAAE,OAAO;AAAA,IACP,cAAc,EAAE,QAAQ,OAAO;AAAA,IAC/B,qBAAqB,EAAE,OAAO,EAAE,MAAM;AAAA,IACtC,oBAAoB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IACpC,wBAAwB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC1C,CAAC;AACH,CAAC;AAGD,IAAM,gBAAgB,EAAE,mBAAmB,mBAAmB;AAAA,EAC5D,EAAE,OAAO;AAAA,IACP,iBAAiB,EAAE,QAAQ,KAAK;AAAA,IAChC,4BAA4B,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IAC5C,2BAA2B,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IAC3C,6BAA6B,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IAC7C,4BAA4B,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,UAAU,OAAK,EAAE,QAAQ,SAAS,IAAI,CAAC;AAAA,EACvF,CAAC;AAAA,EACD,EAAE,OAAO;AAAA,IACP,iBAAiB,EAAE,QAAQ,KAAK;AAAA,IAChC,uBAAuB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IACvC,8BAA8B,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IAC9C,kCAAkC,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IAClD,4BAA4B,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC9C,CAAC;AAAA,EACD,EAAE,OAAO;AAAA,IACP,iBAAiB,EAAE,QAAQ,MAAM;AAAA,IACjC,qBAAqB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IACrC,qBAAqB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IACrC,qBAAqB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IACrC,yBAAyB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC3C,CAAC;AAAA,EACD,EAAE,OAAO;AAAA,IACP,iBAAiB,EAAE,QAAQ,MAAM;AAAA,IACjC,qBAAqB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IACrC,qBAAqB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IACrC,qBAAqB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,IACrC,yBAAyB,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC3C,CAAC;AACH,CAAC;AAED,IAAM,YAAY,WACf,IAAI,aAAa,EACjB,IAAI,aAAa;AACpB,IAAM,SAAS,UAAU,UAAU;AAAA,EACjC,GAAG,QAAQ;AAAA,EACX,kBAAkB;AAAA;AACpB,CAAC;AACD,IAAI,CAAC,OAAO,SAAS;AACnB,UAAQ,MAAM,+CAA0C,OAAO,MAAM,OAAO,CAAC;AAC7E,UAAQ,KAAK,CAAC;AAChB;AAEA,IAAM,MAAW,OAAO;AAExB,IAAO,cAAQ;;;ACpJf,SAAS,eAAe;;;ACEjB,IAAK,QAAL,kBAAKC,WAAL;AAEL,EAAAA,OAAA,oBAAiB;AAGjB,EAAAA,OAAA,mBAAgB;AAGhB,EAAAA,OAAA,cAAW;AACX,EAAAA,OAAA,mCAAgC;AAChC,EAAAA,OAAA,gCAA6B;AAG7B,EAAAA,OAAA,4BAAyB;AAGzB,EAAAA,OAAA,4BAAyB;AACzB,EAAAA,OAAA,yBAAsB;AACtB,EAAAA,OAAA,yBAAsB;AACtB,EAAAA,OAAA,+BAA4B;AAC5B,EAAAA,OAAA,4BAAyB;AACzB,EAAAA,OAAA,iCAA8B;AAC9B,EAAAA,OAAA,gDAA6C;AAC7C,EAAAA,OAAA,kDAA+C;AAC/C,EAAAA,OAAA,4CAAyC;AACzC,EAAAA,OAAA,iCAA8B;AAC9B,EAAAA,OAAA,yBAAsB;AACtB,EAAAA,OAAA,gDAA6C;AAC7C,EAAAA,OAAA,gCAA6B;AAC7B,EAAAA,OAAA,gCAA6B;AAC7B,EAAAA,OAAA,kCAA+B;AAC/B,EAAAA,OAAA,gCAA6B;AAC7B,EAAAA,OAAA,mCAAgC;AAChC,EAAAA,OAAA,yCAAsC;AACtC,EAAAA,OAAA,0CAAuC;AAGvC,EAAAA,OAAA,wBAAqB;AAGrB,EAAAA,OAAA,0BAAuB;AACvB,EAAAA,OAAA,2BAAwB;AACxB,EAAAA,OAAA,2BAAwB;AACxB,EAAAA,OAAA,2BAAwB;AACxB,EAAAA,OAAA,uBAAoB;AAGpB,EAAAA,OAAA,sCAAmC;AACnC,EAAAA,OAAA,wCAAqC;AACrC,EAAAA,OAAA,sCAAmC;AACnC,EAAAA,OAAA,gCAA6B;AAC7B,EAAAA,OAAA,mBAAgB;AAChB,EAAAA,OAAA,yCAAsC;AACtC,EAAAA,OAAA,oBAAiB;AACjB,EAAAA,OAAA,2BAAwB;AACxB,EAAAA,OAAA,uBAAoB;AAGpB,EAAAA,OAAA,oBAAiB;AACjB,EAAAA,OAAA,mBAAgB;AAChB,EAAAA,OAAA,gBAAa;AACb,EAAAA,OAAA,oBAAiB;AACjB,EAAAA,OAAA,sBAAmB;AACnB,EAAAA,OAAA,gCAA6B;AAG7B,EAAAA,OAAA,yBAAsB;AACtB,EAAAA,OAAA,4BAAyB;AAGzB,EAAAA,OAAA,eAAY;AAtEF,SAAAA;AAAA,GAAA;AAyEL,IAAM,WAAW;AAAA,EACtB,CAAC,qCAAoB,GAAG;AAAA,IACtB,SAAS;AAAA,IACT,cAAc,MAAM;AAAA,EACtB;AAAA,EAEA,CAAC,mCAAmB,GAAG;AAAA,IACrB,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,yBAAc,GAAG;AAAA,IAChB,SAAS;AAAA,IACT,eAAe,CAAC,aAAqB,EAAE,QAAQ;AAAA,EACjD;AAAA,EAEA,CAAC,mEAAmC,GAAG;AAAA,IACrC,SAAS;AAAA,IACT,cAAc,CACZC,iBACA,WACG;AACH,UAAI;AACF,cAAM,cAAc,KAAK,UAAU,MAAM;AACzC,eAAO;AAAA,UACL,YAAYA;AAAA,UACZ,QAAQ;AAAA,QACV;AAAA,MACF,SAAS,KAAK;AACZ,eAAO;AAAA,UACL,YAAYA;AAAA,UACZ,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,CAAC,6DAAgC,GAAG;AAAA,IAClC,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,qDAA4B,GAAG;AAAA,IAC9B,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,qDAA4B,GAAG;AAAA,IAC9B,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,+CAAyB,GAAG;AAAA,IAC3B,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,+CAAyB,GAAG;AAAA,IAC3B,SAAS;AAAA,IACT,cAAc,CAAC,YAAoB,EAAE,OAAO;AAAA,EAC9C;AAAA,EAEA,CAAC,2DAA+B,GAAG;AAAA,IACjC,SAAS;AAAA,IACT,cAAc,CAAC,WAAmB,EAAE,MAAM;AAAA,EAC5C;AAAA,EAEA,CAAC,qDAA4B,GAAG;AAAA,IAC9B,SAAS;AAAA,IACT,cAAc,CAAC,cAAsB,EAAE,SAAS;AAAA,EAClD;AAAA,EAEA,CAAC,+DAAiC,GAAG;AAAA,IACnC,SAAS;AAAA,IACT,cAAc,CAAC,WAAmB,EAAE,MAAM;AAAA,EAC5C;AAAA,EAEA,CAAC,6FAAgD,GAAG;AAAA,IAClD,SAAS;AAAA,IACT,cAAc,MAAM;AAAA,EACtB;AAAA,EAEA,CAAC,iGAAkD,GAAG;AAAA,IACpD,SAAS;AAAA,IACT,cAAc,MAAM;AAAA,EACtB;AAAA,EAEA,CAAC,qFAA4C,GAAG;AAAA,IAC9C,SAAS;AAAA,IACT,cAAc,CAAC,YAAoB;AAAA,EACrC;AAAA,EAEA,CAAC,+DAAiC,GAAG;AAAA,IACnC,SAAS;AAAA,IACT,cAAc,CAAC,WAAmB,EAAE,MAAM;AAAA,EAC5C;AAAA,EAEA,CAAC,+CAAyB,GAAG;AAAA,IAC3B,SAAS;AAAA,IACT,cAAc,MAAM;AAAA,EACtB;AAAA,EAEA,CAAC,6FAAgD,GAAG;AAAA,IAClD,SAAS;AAAA,IACT,cAAc,CAAC,OAAe,WAAmB,EAAE,OAAO,MAAM;AAAA,EAClE;AAAA,EAEA,CAAC,6DAAgC,GAAG;AAAA,IAClC,SAAS;AAAA,IACT,cAAc,MAAM;AAAA,EACtB;AAAA,EAEA,CAAC,6DAAgC,GAAG;AAAA,IAClC,SAAS;AAAA,IACT,cAAc,MAAM;AAAA,EACtB;AAAA,EAEA,CAAC,iEAAkC,GAAG;AAAA,IACpC,SAAS;AAAA,IACT,cAAc,MAAM;AAAA,EACtB;AAAA,EAEA,CAAC,6DAAgC,GAAG;AAAA,IAClC,SAAS;AAAA,IACT,cAAc,MAAM;AAAA,EACtB;AAAA,EAEA,CAAC,mEAAmC,GAAG;AAAA,IACrC,SAAS;AAAA,IACT,cAAc,CAAC,QAAgBC,aAAsB,EAAE,QAAQ,QAAAA,QAAO;AAAA,EACxE;AAAA,EAEA,CAAC,+EAAyC,GAAG;AAAA,IAC3C,SAAS;AAAA,IACT,cAAc,CAAC,QAAgB,WAAoB,EAAE,QAAQ,MAAM;AAAA,EACrE;AAAA,EAEA,CAAC,iFAA0C,GAAG;AAAA,IAC5C,SAAS;AAAA,IACT,cAAc,CAAC,QAAgB,WAAoB,EAAE,QAAQ,MAAM;AAAA,EACrE;AAAA,EAEA,CAAC,6CAAwB,GAAG;AAAA,IAC1B,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,iDAA0B,GAAG;AAAA,IAC5B,SAAS;AAAA,IACT,eAAe,CAAC,MAAW,WAAmB,EAAE,MAAM,MAAM;AAAA,EAC9D;AAAA,EAEA,CAAC,mDAA2B,GAAG;AAAA,IAC7B,SAAS;AAAA,IACT,eAAe,CAAC,OAAY,WAAmB,EAAE,OAAO,MAAM;AAAA,EAChE;AAAA,EAEA,CAAC,mDAA2B,GAAG;AAAA,IAC7B,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,mDAA2B,GAAG;AAAA,IAC7B,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,2CAAuB,GAAG;AAAA,IACzB,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,yEAAsC,GAAG;AAAA,IACxC,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,6EAAwC,GAAG;AAAA,IAC1C,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,yEAAsC,GAAG;AAAA,IACxC,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,6DAAgC,GAAG;AAAA,IAClC,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,mCAAmB,GAAG;AAAA,IACrB,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,+EAAyC,GAAG;AAAA,IAC3C,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,qCAAoB,GAAG;AAAA,IACtB,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,mDAA2B,GAAG;AAAA,IAC7B,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,2CAAuB,GAAG;AAAA,IACzB,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,qCAAoB,GAAG;AAAA,IACtB,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,mCAAmB,GAAG;AAAA,IACrB,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,6BAAgB,GAAG;AAAA,IAClB,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,qCAAoB,GAAG;AAAA,IACtB,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,yCAAsB,GAAG;AAAA,IACxB,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,6DAAgC,GAAG;AAAA,IAClC,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,+CAAyB,GAAG;AAAA,IAC3B,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,qDAA4B,GAAG;AAAA,IAC9B,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AAAA,EAEA,CAAC,2BAAe,GAAG;AAAA,IACjB,SAAS;AAAA,IACT,cAAc,CAAC,YAAqB;AAAA,EACtC;AACF;;;ADrUO,IAAM,YAAuB,CAClC,SACG,WACc;AACjB,QAAM,UAAU,SAAS,IAAI,EAAE;AAC/B,QAAM,eAAe,SAAS,IAAI,EAAE;AACpC,QAAM,UAAU,aAAa,GAAG,MAAe;AAC/C,SAAO,EAAE,MAAM,SAAS,QAAQ;AAClC;AAEO,IAAM,qBAAyC,CACpD,SACG,WACA,QAAQ,YAAY,UAAU,MAAM,GAAG,MAAM,CAAC;;;AExBnD,SAAS,cAAc;AACvB,OAAO,WAAW;AAaX,IAAM,MAAM,CAAC,OAAe,UAAoB,SAAiB,YAAyC;AAC/G,MAAI;AACJ,MAAI,8BAAuB,gBAAe,MAAM,KAAK,IAAI,SAAS,EAAE,MAAM,SAAS,EAAE,MAAM,YAAY,CAAC;AAAA,WAC/F,8BAAuB,gBAAe,MAAM,KAAK,IAAI,SAAS,EAAE,MAAM,YAAY,CAAC;AAAA,WACnF,4BAAsB,gBAAe,MAAM,KAAK,IAAI,SAAS,EAAE,MAAM,YAAY,CAAC;AAAA,WAClF,4BAAsB,gBAAe,MAAM,KAAK,IAAI,SAAS,EAAE,MAAM,YAAY,CAAC;AAAA,WAClF,4BAAsB,gBAAe,MAAM,KAAK,IAAI,SAAS,EAAE,MAAM,YAAY,CAAC;AAAA,MACtF,gBAAe,MAAM,KAAK,QAAQ,MAAM,YAAY,CAAC;AAC1D,QAAM,SAAS,KACP,oBAAI,KAAK,GAAE,YAAY,CAAC,IACxB,YAAY,KACX,QAAQ,KACT,OAAO,IACP,UAAU,KAAK,UAAU,OAAO,IAAI,EAAE;AAC9C,UAAQ,IAAI,MAAM;AACpB;AAEO,IAAM,WAAqB,CAAC,UAAU,SAAS,YAAkB,yBAAiB,UAAU,SAAS,OAAO;AAC5G,IAAM,WAAqB,CAAC,UAAU,SAAS,YAAkB,yBAAiB,UAAU,SAAS,OAAO;AAC5G,IAAM,aAAyB,CAAC,UAAU,SAAS,YAAkB,uBAAgB,UAAU,SAAS,OAAO;AAC/G,IAAM,UAAmB,CAAC,UAAU,SAAS,YAAkB,uBAAgB,UAAU,SAAS,OAAO;AACzG,IAAM,UAAmB,CAAC,UAAU,SAAS,YAAkB,uBAAgB,UAAU,SAAS,OAAO;AAGzG,IAAM,uBAAuB,CAAC,KAAc,KAAe,SAA6B;AAC7F,QAAM,UAAU,OAAO,OAAO;AAC9B,QAAM,cAAc,KAAK,IAAI;AAC7B,MAAI,GAAG,UAAU,MAAM;AAzCzB;AA0CI,UAAM,QAAQ,OAAO,OAAO;AAC5B,UAAM,aAAa,QAAQ;AAC3B,UAAM,aAAa,OAAO,aAAa,QAAU;AACjD,qCAA0B,GAAG,IAAI,MAAM,IAAI,IAAI,WAAW,IAAI;AAAA,MAC5D,YAAY,IAAI;AAAA,MAChB,IAAI,IAAI;AAAA,MACR,WAAW,IAAI,QAAQ,YAAY;AAAA,MACnC,UAAQ,SAAI,OAAO,aAAX,mBAAqB,WAAU;AAAA,MACvC;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACD,OAAK;AACP;;;AJ7BA,SAAS,YAAY;AACrB,SAAS,gBAAgB;AAQzB,eAAsB,OAAiD;AACrE,QAAM,OAAO,oBAAoB,CAAC;AAClC,MAAI,SAAS,UACR,KAAK,eAAe,KACpB,KAAK,OAAO,QAAW;AAC1B,4BAAyB,mCAAmC,EAAE,YAAY,6BAAM,WAAW,CAAC;AAC5F,WAAOC,SAAQ,YAAY,8BAA8B;AAAA,EAC3D;AACA,MAAI;AACF,UAAMC,SAAQ,QAAQ,OAAO,OAAO;AACpC,UAAM,KAAK,GAAG,MAAM,EAAE,KAAK;AAC3B,UAAM,MAAM,QAAQ,OAAO,OAAO;AAClC,UAAM,aAAa,OAAO,MAAMA,MAAK,IAAI;AACzC,WAAOD,SAAQ,YAAY,UAAU;AAAA,EACvC,SAAS,KAAK;AACZ,4BAAyB,uBAAuB,EAAE,OAAO,gBAAgB,GAAG,EAAE,CAAC;AAC/E,WAAOA,SAAQ,YAAY,gBAAgB,GAAG,CAAC;AAAA,EACjD;AACF;AAQA,IAAI,oBAAoB;AACxB,oBAAoB,GAAG,YAAI,WAAW;AACtC,qBAAqB,GAAG,YAAI,MAAM,IAAI,YAAI,MAAM,IAAI,YAAI,OAAO;AAC/D,IAAI,YAAI,YAAY,UAAa,YAAI,YAAY,IAAI;AAAE,uBAAqB,IAAI,YAAI,OAAO;AAAG;AAC9F,IAAI,YAAI,YAAY,UAAa,YAAI,YAAY,IAAI;AAAE,uBAAqB,IAAI,YAAI,OAAO;AAAG;AAC9F,IAAI,YAAI,WAAW,UAAa,YAAI,WAAW,IAAI;AAAE,uBAAqB,IAAI,YAAI,MAAM;AAAG;AAEpF,IAAM,mBAAmB;AAEhC,eAAsB,UAAW;AAC/B,MAAI;AACF,UAAM,gBAAgB,gBAAgB;AACtC,2BAAwB,oBAAoB;AAC5C,WAAOA,SAAQ,YAAY,IAAI;AAAA,EACjC,SAAS,KAAK;AACZ,UAAM,SAAS,gBAAgB,GAAG;AAClC,4BAAyB,gCAAgC,EAAE,OAAO,OAAO,CAAC;AAC1E,WAAOA,SAAQ,YAAY,MAAM;AAAA,EACnC;AACF;AAEA,eAAsB,mBACpB,UAAU,GACV,UAAU,SAAS,QAAQ,CAAC,EAAE,KAAK,GACnC;AACA,WAAS,IAAI,GAAG,IAAI,SAAS,KAAK;AAChC,UAAM,SAAS,MAAM,QAAQ;AAC7B,QAAI,OAAO,QAAS,QAAO;AAC3B,2BAAwB,aAAa,IAAI,CAAC,IAAI,OAAO,QAAQ,UAAU,GAAI,aAAa;AACxF,UAAM,KAAK,OAAO;AAAA,EACpB;AACA,SAAOA,SAAQ,YAAY,8BAA8B;AAC3D;AAEA,eAAsB,aAAa;AACjC,MAAI;AACF,UAAM,mBAAmB;AACzB,2BAAwB,uBAAuB;AAAA,EACjD,SAAS,KAAK;AACZ,4BAAyB,qCAAqC,EAAE,OAAO,gBAAgB,GAAG,EAAE,CAAC;AAAA,EAC/F;AACF;AAQO,IAAM,YAAuB,OAAO,OAAO,MAAM,YAAY;AAClE,MAAI;AACF,UAAM,MAAM,IAAI,MAAM,IAAI;AAC1B,QAAI,UAAU,EAAE,QAAQ;AACxB,UAAM,QAAQ,MAAM,IAAI,KAAK;AAC7B,WAAOA,SAAQ,YAAY,KAAK;AAAA,EAClC,SAAS,KAAK;AACZ,UAAM,SAAS,gBAAgB,GAAG;AAClC,4BAAyB,wBAAwB;AAAA,MAC/C,OAAO;AAAA,MACP,WAAW,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,IACF,CAAC;AACD,WAAO,8CAAmC,MAAM;AAAA,EAClD;AACF;AAEO,IAAM,aAAyB,OAAQ,OAAO,MAAM,YAAY;AACrE,MAAI;AACF,UAAM,OAAO,KAAK,IAAI,OAAK;AACzB,YAAM,MAAM,IAAI,MAAM,CAAC;AACvB,UAAI,UAAU,EAAE,QAAQ;AACxB,aAAO;AAAA,IACT,CAAC;AACD,UAAM,QAAQ,MAAM,MAAM,WAAW,IAAI;AACzC,WAAOA,SAAQ,YAAY;AAAA,MACzB,UAAU;AAAA,MACV,eAAe,MAAM;AAAA,IACvB,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,SAAS,gBAAgB,GAAG;AAClC,4BAAyB,yBAAyB;AAAA,MAChD,OAAO;AAAA,MACP,WAAW,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,IACF,CAAC;AACD,WAAO,8CAAmC,MAAM;AAAA,EAClD;AACF;AAEO,IAAM,UAAmB,OAAO,OAAO,QAAQ,YAAY;AAChE,MAAI;AACF,UAAM,QAAQ,MAAM,MACjB,QAAQ,MAAM,EACd,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,EACnC,KAAK;AACR,QAAI,UAAU,MAAM;AAClB,gCAA2B,wBAAwB;AAAA,QACjD,WAAW,MAAM;AAAA,QACjB;AAAA,QACA;AAAA,MACF,CAAC;AACD,aAAO,wFAAwD,MAAM,WAAW,MAAM;AAAA,IACxF;AACA,WAAOA,SAAQ,YAAY,KAAK;AAAA,EAClC,SAAS,KAAK;AACZ,4BAAyB,sBAAsB;AAAA,MAC7C,OAAO,gBAAgB,GAAG;AAAA,MAC1B,WAAW,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,IACF,CAAC;AACD,WAAO,8CAAmC,gBAAgB,GAAG,CAAC;AAAA,EAChE;AACF;AAEO,IAAM,WAAqB,OAAO,OAAO,QAAQ,SAAS,YAAY;AAC3E,MAAI;AACF,UAAM;AAAA,MACJ,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,OAAO,CAAC;AAAA,IACV,IAAI,WAAW,CAAC;AAChB,QAAI,SAAS,EAAG,QAAO,8CAAmC,8BAA8B;AACxF,QAAI,OAAO,EAAG,QAAO,8CAAmC,yCAAyC;AACjG,UAAM,CAAC,OAAO,KAAK,IAAI,MAAM,QAAQ,IAAI;AAAA,MACvC,MAAM,eAAe,MAAM;AAAA,MAC3B,MAAM,KAAK,MAAM,EACd,KAAK,IAAI,EACT,KAAK,IAAI,EACT,MAAM,KAAK,EACX,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,EACnC,KAAK;AAAA,IACV,CAAC;AACD,QAAI,MAAM,WAAW,GAAG;AACtB,gCAA2B,yBAAyB;AAAA,QAClD,WAAW,MAAM;AAAA,QACjB;AAAA,QACA;AAAA,MACF,CAAC;AACD,aAAO,wFAAwD,MAAM,WAAW,MAAM;AAAA,IACxF;AACA,UAAM,UAAU,OAAO;AACvB,UAAM,UAAU,QAAQ,OAAO,MAAM;AACrC,UAAM,WAAW,CAAC,UACd,OACA,YAAY;AACZ,YAAM,UAAU,KAAK,IAAI,OAAO,OAAO,CAAC;AACxC,YAAM,WAAW,YAAY,IAAI,OAAO;AACxC,aAAO,MAAM;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QAAS;AAAA,UACP,GAAG;AAAA,UACH,MAAM;AAAA,UACN,OAAO;AAAA,QACT;AAAA,MAAC;AAAA,IACL;AACF,UAAM,WAAW,CAAC,UACd,OACA,YAAY,MAAM;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MAAS;AAAA,QACP,GAAG;AAAA,QACH,MAAM,OAAO;AAAA,MACf;AAAA,IAAC;AACL,WAAOA,SAAQ,YAAY;AAAA,MACzB;AAAA,MACA,YAAY,MAAM;AAAA,MAClB,YAAY;AAAA,MACZ,MAAM;AAAA,MACN,MAAM;AAAA,IACR,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,4BAAyB,uBAAuB;AAAA,MAC9C,OAAO,gBAAgB,GAAG;AAAA,MAC1B,WAAW,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,IACF,CAAC;AACD,WAAO,8CAAmC,gBAAgB,GAAG,CAAC;AAAA,EAChE;AACF;AAEO,IAAM,YAAuB,OAAO,OAAO,QAAQE,SAAQ,YAAY;AAC5E,MAAI;AACF,UAAM,UAAU,MAAM,MACnB,iBAAiB,QAAQA,SAAQ,EAAE,KAAK,KAAK,CAAC,EAC9C,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,EACnC,KAAK;AACR,QAAI,YAAY,MAAM;AACpB,gCAA2B,0BAA0B;AAAA,QACnD,WAAW,MAAM;AAAA,QACjB;AAAA,QACA;AAAA,QACA,QAAAA;AAAA,MACF,CAAC;AACD,aAAO,wFAAwD,MAAM,WAAW,MAAM;AAAA,IACxF;AACA,WAAOF,SAAQ,YAAY,OAAO;AAAA,EACpC,SAAS,KAAK;AACZ,4BAAyB,wBAAwB;AAAA,MAC/C,OAAO,gBAAgB,GAAG;AAAA,MAC1B,WAAW,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA,QAAAE;AAAA,IACF,CAAC;AACD,WAAO,8CAAmC,gBAAgB,GAAG,CAAC;AAAA,EAChE;AACF;AAEO,IAAM,aAAyB,OAAO,OAAO,QAAQA,SAAQ,YAAY;AAC9E,MAAI;AACF,UAAM,UAAU,MAAM,MACnB,WAAW,QAAQA,OAAM,EACzB,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,EACnC,KAAK;AACR,QAAI,QAAQ,kBAAkB,GAAG;AAC/B,gCAA2B,2BAA2B;AAAA,QACpD,WAAW,MAAM;AAAA,QACjB;AAAA,QACA;AAAA,QACA,QAAAA;AAAA,MACF,CAAC;AACD,aAAO,wFAAwD,MAAM,WAAW,MAAM;AAAA,IACxF;AACA,WAAOF,SAAQ,YAAY;AAAA,MACzB,cAAc,QAAQ;AAAA,IACxB,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,4BAAyB,yBAAyB;AAAA,MAChD,OAAO,gBAAgB,GAAG;AAAA,MAC1B,WAAW,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA,QAAAE;AAAA,IACF,CAAC;AACD,WAAO,8CAAmC,gBAAgB,GAAG,CAAC;AAAA,EAChE;AACF;AAEO,IAAM,YAAuB,OAAO,OAAO,QAAQ,YAAY;AACpE,MAAI;AACF,UAAM,UAAU,MAAM,MACnB,iBAAiB,MAAM,EACvB,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,EACnC,KAAK;AACR,QAAI,YAAY,MAAM;AACpB,gCAA2B,0BAA0B;AAAA,QACnD,WAAW,MAAM;AAAA,QACjB;AAAA,QACA;AAAA,MACF,CAAC;AACD,aAAO,wFAAwD,MAAM,WAAW,MAAM;AAAA,IACxF;AACA,WAAOF,SAAQ,YAAY,OAAO;AAAA,EACpC,SAAS,KAAK;AACZ,4BAAyB,wBAAwB;AAAA,MAC/C,OAAO,gBAAgB,GAAG;AAAA,MAC1B,WAAW,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,IACF,CAAC;AACD,WAAO,8CAAmC,gBAAgB,GAAG,CAAC;AAAA,EAChE;AACF;AAEO,IAAM,aAAyB,OAAO,OAAO,QAAQ,YAAY;AACtE,MAAI;AACF,UAAM,UAAU,MAAM,MACnB,WAAW,MAAM,EACjB,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,EACnC,KAAK;AACR,QAAI,QAAQ,iBAAiB,GAAG;AAC9B,gCAA2B,2BAA2B;AAAA,QACpD,WAAW,MAAM;AAAA,QACjB;AAAA,QACA;AAAA,MACF,CAAC;AACD,aAAO,wFAAwD,MAAM,WAAW,MAAM;AAAA,IACxF;AACA,WAAOA,SAAQ,YAAY,EAAE,cAAc,QAAQ,aAAa,CAAC;AAAA,EACnE,SAAS,KAAK;AACZ,4BAAyB,yBAAyB;AAAA,MAChD,OAAO,gBAAgB,GAAG;AAAA,MAC1B,WAAW,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,IACF,CAAC;AACD,WAAO,8CAAmC,gBAAgB,GAAG,CAAC;AAAA,EAChE;AACF;;;AKnWA,SAAS,WAAAG,gBAAe;AACxB,SAAS,mBAAAC,wBAAuB;AAChC,SAAS,QAAQ,WAAW,aAAa,kBAAkB;AAE3D,OAAO,gBAAqC;AAM5C,eAAe,mBACb,QACA,MACA,UACA,IACA,QACA,SACA,UAC8C;AAC9C,QAAM,aAAa,IAAI,WAAW,EAAE,OAAO,CAAC;AAC5C,QAAM,SAAS,IAAI,OAAO,MAAM,QAAQ;AACxC,QAAM,YAAY,IAAI,UAAU,IAAI,MAAM;AAC1C,QAAM,cAAc,IAAI,YAAY,EACjC,QAAQ,MAAM,EACd,MAAM,CAAC,SAAS,CAAC,EACjB,WAAW,MAAM,EACjB,WAAW,OAAO,EAClB,QAAQ,QAAQ;AACnB,MAAI;AACF,UAAM,OAAO,MAAM,WAAW,MAAM,KAAK,WAAW;AACpD,WAAOC,SAAQ,YAAY,IAAI;AAAA,EACjC,SAAS,KAAK;AACZ,kCAA4B,wBAAwB;AAAA,MAClD;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAOC,iBAAgB,GAAG;AAAA,IAC5B,CAAC;AACD,WAAOD,SAAQ,YAAYC,iBAAgB,GAAG,CAAC;AAAA,EACjD;AACF;AAEA,eAAe,cACb,YACA,eACA,MACA,UACA,IACA,QACA,SACA,UACkD;AAClD,MAAI;AACF,UAAM,cAAc,WAAW,gBAAgB;AAAA,MAC7C,SAAS;AAAA,MACT,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,MAAM;AAAA,MACR;AAAA,IACF,CAAC;AAGD,QAAI;AACF,YAAM,YAAY,OAAO;AAAA,IAC3B,SAAS,WAAW;AAClB,oCAA4B,yCAAyC;AAAA,QACnE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAOA,iBAAgB,SAAS;AAAA,MAClC,CAAC;AACD,YAAM,WAAW,0CAA0CA,iBAAgB,SAAS,CAAC;AACrF,aAAOD,SAAQ,YAAY,QAAQ;AAAA,IACrC;AAEA,UAAM,OAAO,MAAM,YAAY,SAAS;AAAA,MACtC,MAAM,GAAG,QAAQ,KAAK,IAAI;AAAA,MAC1B,IAAI,GAAG,MAAM,KAAK,EAAE;AAAA,MACpB;AAAA,MACA,MAAM;AAAA,IACR,CAAC;AAID,QAAI,KAAK,YAAY,KAAK,SAAS,SAAS,GAAG;AAC7C,YAAM,WAAW,gCAAgC,KAAK,SAAS,KAAK,IAAI,CAAC;AACzE,oCAA4B,2BAA2B;AAAA,QACrD;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU,KAAK;AAAA,QACf,UAAU,KAAK;AAAA,MACjB,CAAC;AACD,aAAOA,SAAQ,YAAY,QAAQ;AAAA,IACrC;AAGA,QAAI,KAAK,WAAW,KAAK,QAAQ,SAAS,GAAG;AAC3C,oCAA4B,0CAA0C;AAAA,QACpE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS,KAAK;AAAA,QACd,UAAU,KAAK;AAAA,MACjB,CAAC;AAAA,IAGH;AAEA,WAAOA,SAAQ,YAAY,IAAI;AAAA,EACjC,SAAS,KAAK;AACZ,kCAA4B,mCAAmC;AAAA,MAC7D;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAOC,iBAAgB,GAAG;AAAA,IAC5B,CAAC;AACD,WAAOD,SAAQ,YAAYC,iBAAgB,GAAG,CAAC;AAAA,EACjD;AACF;AAEO,IAAM,OAAa,OACxB,MACA,UACA,IACA,QACA,SACA,aACG;AACH,MAAI,YAAI,iBAAiB,aAAc,QAAO;AAAA,IAC5C,YAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAAA,MACK,QAAO;AAAA,IACV,YAAI;AAAA,IACJ,YAAI;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AClKA;AAAA,EACE,UAAUC;AAAA,EACV,SAAS;AAAA,OAEJ;AACP,OAAO,eAAe;;;AC8Gf,IAAK,WAAL,kBAAKC,cAAL;AACL,EAAAA,UAAA,UAAO;AACP,EAAAA,UAAA,WAAQ;AACR,EAAAA,UAAA,UAAO;AAHG,SAAAA;AAAA,GAAA;AAML,IAAK,aAAL,kBAAKC,gBAAL;AACL,EAAAA,YAAA,YAAS;AACT,EAAAA,YAAA,eAAY;AACZ,EAAAA,YAAA,YAAS;AAHC,SAAAA;AAAA,GAAA;AAML,IAAK,YAAL,kBAAKC,eAAL;AAEL,EAAAA,WAAA,0BAAuB;AAGvB,EAAAA,WAAA,qBAAkB;AAGlB,EAAAA,WAAA,6BAA0B;AAC1B,EAAAA,WAAA,0BAAuB;AACvB,EAAAA,WAAA,6BAA0B;AAC1B,EAAAA,WAAA,4BAAyB;AAGzB,EAAAA,WAAA,gCAA6B;AAC7B,EAAAA,WAAA,6BAA0B;AAC1B,EAAAA,WAAA,gCAA6B;AAC7B,EAAAA,WAAA,+BAA4B;AAG5B,EAAAA,WAAA,yBAAsB;AAGtB,EAAAA,WAAA,kBAAe;AAGf,EAAAA,WAAA,yBAAsB;AACtB,EAAAA,WAAA,0BAAuB;AACvB,EAAAA,WAAA,4BAAyB;AACzB,EAAAA,WAAA,4BAAyB;AACzB,EAAAA,WAAA,4BAAyB;AACzB,EAAAA,WAAA,wCAAqC;AACrC,EAAAA,WAAA,oDAAiD;AACjD,EAAAA,WAAA,oDAAiD;AACjD,EAAAA,WAAA,sCAAmC;AACnC,EAAAA,WAAA,6CAA0C;AAG1C,EAAAA,WAAA,0BAAuB;AAtCb,SAAAA;AAAA,GAAA;;;AC/HZ,OAAO,UAAU;AACjB,SAAS,mBAAAC,wBAAuB;AAChC;AAAA,EACE,SAAS;AAAA,EACT,UAAU;AAAA,OAGL;AAKA,IAAM,oBAAwC,IAAI,eAA6B;AAAA,EACpF,cAAc,EAAE,MAAM,MAAM,UAAU,KAAK;AAAA,EAC3C,WAAW,EAAE,MAAM,eAAe,UAAU,UAAU,KAAK;AAAA,EAC3D,qBAAqB,EAAE,MAAM,QAAQ,UAAU,KAAK;AACtD,CAAC;AAGD,eAAsB,gBAAiB,UAA4B,mBAAkE;AACnI,QAAM,cAAc,SAAS,SAAS;AACtC,QAAM,cAAc,OAAO,QAAQ,WAAW,EAAE,OAAO,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,WAAW,GAAG,CAAC;AACtF,QAAM,iBAAiB,OAAO,YAAY,WAAW;AACrD,QAAM,cAAc,KAAK,UAAU,cAAc;AACjD,QAAM,aAAa,MAAM,IAAI,QAAgB,CAAC,SAAS,WAAW;AAChE,SAAK,KAAK,aAAa,CAAC,KAAKC,gBAAe;AAC1C,UAAI,QAAQ,KAAM,QAAO,OAAO,GAAG;AACnC,aAAO,QAAQA,WAAU;AAAA,IAC3B,CAAC;AAAA,EACH,CAAC;AACD,QAAM,SAAS,WAAW,SAAS,QAAQ;AAC3C,QAAM,cAA4B;AAAA,IAChC,cAAc,oBAAI,KAAK;AAAA,IACvB,WAAW;AAAA,IACX,qBAAqB;AAAA,EACvB;AACA,SAAO;AACT;AAEO,IAAM,qBAAyC,CAAmB,gBAAmC;AAC1G,QAAM,SAAS,YAAY,MAAM;AACjC,SAAO,IAAI,IAAI,eAAgC;AAAA,IAC7C,UAAU;AAAA,MACR,MAAM,CAAC,iBAAiB;AAAA,MACxB,UAAU;AAAA,MACV,SAAS,CAAC;AAAA,IACZ;AAAA,EACF,CAAC,CAAC;AACF,SAAO,IAAI,QAAQ,UAAU;AAC7B,SAAO,IAAI,cAAc,gBAAgB;AACzC,SAAO,IAAI,oBAAoB,YAAY;AAC3C,SAAO,IAAI,aAAa,YAAY;AACpC,SAAO,IAAI,cAAc,YAAY;AAErC,iBAAe,WAEb,MACA;AAzDJ;AA0DI,UAAM,WAAU,UAAK,YAAL,mBAAc;AAC9B,UAAM,eAAc,mCAAS,gBAAe;AAC5C,UAAM,oBAAoB,gBAAgB,OAAO,IAAI,cAAc,SAAS,WAAW,IAAI;AAC3F,QAAI,sBAAsB,KAAM,QAAO,KAAK,IAAI,MAAM,uDAAuD,CAAC;AAC9G,QAAI;AACF,YAAM,cAAc,MAAM,gBAAgB,MAAM,iBAAiB;AACjE,UAAI,KAAK,OAAO;AAAE,aAAK,WAAW,CAAC,WAAW;AAAA,MAAE,MAC3C,MAAK,SAAS,KAAK,WAAW;AACnC,WAAK;AAAA,IACP,SAAS,KAAK;AACZ,YAAM,SAASD,iBAAgB,GAAG;AAClC,WAAK,IAAI,MAAM,MAAM,CAAC;AAAA,IACxB;AAAA,EACF;AAEA,iBAAe,iBACb,MACA,MACA;AA5EJ;AA6EI,QAAI;AACF,iBAAW,OAAO,MAAM;AACtB,cAAM,WAAU,SAAI,YAAJ,mBAAa;AAC7B,cAAM,eAAc,mCAAS,gBAAe;AAC5C,cAAM,oBAAoB,gBAAgB,OAAO,IAAI,cAAc,SAAS,WAAW,IAAI;AAC3F,YAAI,sBAAsB,KAAM,QAAO,KAAK,IAAI,MAAM,6DAA6D,CAAC;AACpH,cAAM,cAAc,MAAM,gBAAgB,KAAK,iBAAiB;AAChE,YAAI,WAAW,CAAC,WAAW;AAAA,MAC7B;AACA,WAAK;AAAA,IACP,SAAS,KAAK;AACZ,YAAM,SAASA,iBAAgB,GAAG;AAClC,WAAK,IAAI,MAAM,MAAM,CAAC;AAAA,IACxB;AAAA,EACF;AAEA,iBAAe,aAEb,MACA;AAhGJ;AAiGI,UAAM,WAAU,UAAK,WAAW,EAAE,YAAlB,mBAA2B;AAC3C,UAAM,eAAc,mCAAS,gBAAe;AAC5C,UAAM,oBAAoB,gBAAgB,OAAO,IAAI,cAAc,SAAS,WAAW,IAAI;AAC3F,QAAI,sBAAsB,KAAM,QAAO,KAAK,IAAI,MAAM,yDAAyD,CAAC;AAChH,QAAI;AACF,YAAM,aAAa,KAAK,MAAM,QAAQ,KAAK,UAAU,CAAC,EAAE,KAAK;AAC7D,YAAM,MAAM,MAAM;AAClB,UAAI,QAAQ,KAAM,QAAO,KAAK,IAAI,MAAM,+BAA+B,CAAC;AACxE,YAAM,cAAc,MAAM,gBAAgB,KAAK,iBAAiB;AAChE,UAAI,SAAS,KAAK,WAAW;AAC7B,WAAK,IAAI,EAAE,UAAU,IAAI,SAAS,CAAC;AACnC,WAAK;AAAA,IACP,SAAS,KAAK;AACZ,YAAM,SAASA,iBAAgB,GAAG;AAClC,WAAK,IAAI,MAAM,MAAM,CAAC;AAAA,IACxB;AAAA,EACF;AACA,SAAO;AACT;;;ACnHA,SAAS,mBAAAE,wBAAuB;AAChC;AAAA,EACE,SAASC;AAAA,EACT,UAAUC;AAAA,OAGL;AAMA,IAAM,aAA0B,IAAIC,gBAAsB;AAAA,EAC/D,cAAc,EAAE,MAAM,MAAM,UAAU,KAAK;AAAA,EAC3C,WAAW,EAAE,MAAMA,gBAAe,UAAU,UAAU,KAAK;AAAA,EAC3D,kBAAkB,EAAE,MAAM,MAAM,UAAU,KAAK;AAAA,EAC/C,eAAe,EAAE,MAAMA,gBAAe,UAAU,UAAU,KAAK;AAAA,EAC/D,sBAAsB,EAAE,MAAM,QAAQ,UAAU,KAAK;AACvD,CAAC;AAGM,IAAM,kBAAmC,CAAoB,gBAAgE;AAClI,QAAM,SAAS,YAAY,MAAM;AACjC,SAAO,IAAI,IAAIA,gBAA6B;AAAA,IAC1C,OAAO;AAAA,MACL,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,QACP,cAAc,oBAAI,KAAK;AAAA,QACvB,WAAW,IAAIC,eAAc,SAAS,YAAI,YAAY;AAAA,QACtD,kBAAkB,oBAAI,KAAK;AAAA,QAC3B,eAAe,IAAIA,eAAc,SAAS,YAAI,YAAY;AAAA,QAC1D,sBAAsB;AAAA,MACxB;AAAA,IACF;AAAA,EACF,CAAC,CAAC;AAEF,SAAO,IAAI,QAAQ,UAAU;AAC7B,SAAO,IAAI,cAAc,gBAAgB;AACzC,SAAO,IAAI,oBAAoB,YAAY;AAC3C,SAAO,IAAI,aAAa,YAAY;AACpC,SAAO,IAAI,cAAc,YAAY;AAErC,SAAO;AAEP,WAAS,WAEP,MACA;AAhDJ;AAiDI,UAAM,WAAU,UAAK,YAAL,mBAAc;AAC9B,UAAM,eAAc,mCAAS,gBAAe;AAC5C,UAAM,oBAAoB,gBAAgB,OAAO,IAAIA,eAAc,SAAS,WAAW,IAAI;AAC3F,QAAI,sBAAsB,KAAM,QAAO,KAAK,IAAI,MAAM,uDAAuD,CAAC;AAC9G,QAAI,KAAK,OAAO;AACd,WAAK,MAAM,eAAe,oBAAI,KAAK;AACnC,WAAK,MAAM,YAAY;AAAA,IACzB;AACA,SAAK,MAAM,mBAAmB,oBAAI,KAAK;AACvC,SAAK,MAAM,gBAAgB;AAC3B,SAAK,MAAM,uBAAuB;AAClC,SAAK;AAAA,EACP;AAEA,WAAS,iBACP,MACA,MACA;AAlEJ;AAmEI,QAAI;AACF,iBAAW,OAAO,MAAM;AACtB,cAAM,WAAU,SAAI,YAAJ,mBAAa;AAC7B,cAAM,eAAc,mCAAS,gBAAe;AAC5C,cAAM,oBAAoB,gBAAgB,OAAO,IAAIA,eAAc,SAAS,WAAW,IAAI;AAC3F,YAAI,sBAAsB,KAAM,QAAO,KAAK,IAAI,MAAM,6DAA6D,CAAC;AACpH,YAAI,MAAM,eAAe,oBAAI,KAAK;AAClC,YAAI,MAAM,YAAY;AACtB,YAAI,MAAM,mBAAmB,oBAAI,KAAK;AACtC,YAAI,MAAM,gBAAgB;AAC1B,YAAI,MAAM,uBAAuB;AAAA,MACnC;AACA,WAAK;AAAA,IACP,SAAS,KAAK;AACZ,YAAM,SAASC,iBAAgB,GAAG;AAClC,WAAK,IAAI,MAAM,MAAM,CAAC;AAAA,IACxB;AAAA,EACF;AAEA,WAAS,aAEP,MACA;AAzFJ;AA0FI,UAAM,WAAU,UAAK,WAAW,EAAE,YAAlB,mBAA2B;AAC3C,UAAM,eAAc,mCAAS,gBAAe;AAC5C,UAAM,oBAAoB,gBAAgB,OAAO,IAAID,eAAc,SAAS,WAAW,IAAI;AAC3F,QAAI,sBAAsB,KAAM,QAAO,KAAK,IAAI,MAAM,6DAA6D,CAAC;AACpH,UAAM,YAAY,KAAK,UAAU;AACjC,QAAI,MAAM,QAAQ,SAAS,EAAG,QAAO,KAAK,IAAI,MAAM,6DAA6D,CAAC;AAClH,UAAME,UAA6C,aAAa,CAAC;AACjE,IAAAA,QAAO,OAAOA,QAAO,QAAQ,CAAC;AAC9B,IAAAA,QAAO,OAAOA,QAAO,QAAQ,CAAC;AAC9B,IAAAA,QAAO,KAAK,wBAAwB,IAAI,oBAAI,KAAK;AACjD,IAAAA,QAAO,KAAK,qBAAqB,IAAI;AACrC,IAAAA,QAAO,KAAK,4BAA4B,KAAMA,QAAO,KAAK,4BAA4B,KAAgB,KAAK;AAC3G,SAAK,UAAUA,OAAM;AACrB,SAAK;AAAA,EACP;AACF;;;ACzGA,SAAS,UAAUC,uBAAsB;AAIlC,IAAM,sBAA2C,CAAoB,gBAAoE;AAC9I,QAAM,SAAS,YAAY,MAAM;AACjC,SAAO,IAAI,IAAIA,gBAAiC;AAAA,IAC9C,WAAW;AAAA,MACT,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,EACF,CAAC,CAAC;AACF,SAAO;AACT;;;AJkBO,IAAM,iBAAqC;AAGlD,IAAM,iBAAiB,CAAC,UAAkB,UAAU,QAAQ,KAAK;AACjE,IAAM,oBAAoB,CAAC,UAAkB,UAAU,OAAO,MAAM,YAAY,CAAC;AACjF,IAAM,4BAA4B,CAAC,UAAkC,GAAG,MAAM,KAAK;AACnF,IAAM,+BAA+B,CAAC,UAAkC,GAAG,MAAM,KAAK;AAE/E,IAAM,qBAA0C,IAAIC,gBAA8B;AAAA,EACvF,UAAU,EAAE,MAAM,QAAQ,UAAU,MAAM,QAAQ,MAAM,UAAU;AAAA,IAChE,WAAW;AAAA,IACX,SAAS;AAAA,EACX,EAAC;AAAA,EACD,MAAM,EAAE,MAAM,QAAQ,MAAM,OAAO,OAAO,QAAQ,GAAG,UAAU,MAAM,2BAAuB;AAAA,EAC5F,QAAQ,EAAE,MAAM,QAAQ,MAAM,OAAO,OAAO,UAAU,GAAG,UAAU,MAAM,+BAA2B;AAAA,EACpG,QAAQ,EAAE,MAAM,CAAC,MAAM,GAAG,MAAM,OAAO,OAAO,SAAS,GAAG,UAAU,MAAM,SAAS,CAAC,EAAE;AACxF,GAAG,EAAE,kBAAkB,YAAY,KAAK,MAAM,CAAC;AAExC,IAAM,sBAA4C,IAAIA,gBAA+B;AAAA,EAC1F,OAAO,EAAE,MAAM,QAAQ,UAAU,MAAM,QAAQ,MAAM,UAAU;AAAA,IAC7D,WAAW;AAAA,IACX,SAAS;AAAA,EACX,EAAC;AAAA,EACD,UAAU,EAAE,MAAM,SAAS,UAAU,MAAM,SAAS,MAAM;AAC5D,CAAC;AAEM,IAAM,uBAA8C,IAAIA,gBAAgC;AAAA,EAC7F,UAAU,EAAE,MAAM,QAAQ,UAAU,MAAM,QAAQ,KAAK;AAAA,EACvD,UAAU;AAAA,IACR,MAAM;AAAA,IACN,UAAU;AAAA,IACV,SAAS;AAAA,IACT,WAAW;AAAA,IACX,UAAU;AAAA,MACR,WAAW,CAAC,MAAe,MAAM;AAAA,MACjC,SAAS;AAAA,IACX;AAAA,EACF;AACF,CAAC;AAEM,IAAM,iBAAkC,gBAAgB,mBAAmB,kBAAkB,CAAC;AAC9F,IAAM,kBAAoC,oBAAoB,gBAAgB,mBAAmB,mBAAmB,CAAC,CAAC;AACtH,IAAM,mBAAgD,gBAAgB,mBAAmB,oBAAoB,CAAC;AAG9G,IAAM,gBAAgC,cAAyB,gBAAgB,cAAc;AAC7F,IAAM,iBAAkC,cAAc,cAA0B,aAAa,eAAe;AAC5G,IAAM,kBAAkB,cAAc,cAA2B,cAAc,gBAAgB;AAG/F,IAAM,mBAAqC,CAAC,SAA8G;AAC/J,MAAI,EAAE,cAAc,MAAO,QAAO;AAClC,MAAI,KAAK,aAAa,aAAa;AACjC,QAAI,EAAE,WAAW,SAAS,OAAO,KAAK,UAAU,SAAU,QAAO;AACjE,QAAI,EAAE,eAAe,SAAS,OAAO,KAAK,cAAc,SAAU,QAAO;AACzE,QAAI,EAAE,cAAc,SAAS,OAAO,KAAK,aAAa,UAAW,QAAO;AACxE,WAAO;AAAA,EACT,WAAW,KAAK,aAAa,cAAc;AACzC,QAAI,EAAE,cAAc,SAAS,OAAO,KAAK,aAAa,SAAU,QAAO;AACvE,QAAI,EAAE,cAAc,SAAS,KAAK,aAAa,KAAM,QAAO;AAC5D,WAAO;AAAA,EACT,MACK,QAAO;AACd;;;AK9FA;AAAA,EACE,UAAUC;AAAA,EACV,SAASC;AAAA,OACJ;AAUA,IAAMC,kBAA8C;AAGpD,IAAM,sBAA4C,IAAIC,gBAA+B;AAAA,EAC1F,OAAO,EAAE,MAAM,QAAQ,UAAU,MAAM,QAAQ,KAAK;AAAA,EACpD,QAAQ,EAAE,MAAMA,gBAAe,UAAU,KAAU,gBAAgB,UAAU,KAAK;AAAA,EAClF,UAAU,EAAE,MAAM,MAAM,UAAU,KAAK;AACzC,CAAC;AAGM,IAAM,qBAA0CC;AAAA,EACrDF;AAAA,EACA;AACF;;;AC1BA;AAAA,EACE,UAAUG;AAAA,EACV,SAASC;AAAA,OACJ;AAUA,IAAMC,kBAAqD;AAG3D,IAAM,6BAA0D,IAAIC,gBAAsC;AAAA,EAC/G,OAAO,EAAE,MAAM,QAAQ,UAAU,KAAK;AAAA,EACtC,QAAQ,EAAE,MAAMA,gBAAe,UAAU,KAAU,gBAAgB,UAAU,KAAK;AAAA,EAClF,WAAW,EAAE,MAAM,MAAM,UAAU,KAAK;AAC1C,CAAC;AAGM,IAAM,4BAAwDC;AAAA,EACnEF;AAAA,EACA;AACF;;;AC1BA;AAAA,EACE,UAAUG;AAAA,EACV,SAASC;AAAA,OACJ;AASA,IAAMC,kBAAyD;AAG/D,IAAM,iCAAkE,IAAIF,gBAA0C;AAAA,EAC3H,OAAO,EAAE,MAAM,QAAQ,UAAU,MAAM,QAAQ,KAAK;AAAA,EACpD,OAAO,EAAE,MAAM,QAAQ,UAAU,KAAK;AAAA,EACtC,WAAW,EAAE,MAAM,MAAM,UAAU,KAAK;AAC1C,CAAC;AAGM,IAAM,gCAAgEC;AAAA,EAC3EC;AAAA,EACA;AACF;;;ACzBA;AAAA,EACE,UAAUC;AAAA,EACV,SAASC;AAAA,OACJ;AASA,IAAMC,kBAAyD;AAG/D,IAAM,iCAAkE,IAAIF,gBAA0C;AAAA,EAC3H,OAAO,EAAE,MAAM,QAAQ,UAAU,MAAM,QAAQ,KAAK;AAAA,EACpD,OAAO,EAAE,MAAM,QAAQ,UAAU,KAAK;AAAA,EACtC,WAAW,EAAE,MAAM,MAAM,UAAU,KAAK;AAC1C,CAAC;AAGM,IAAM,gCAAgEC;AAAA,EAC3EC;AAAA,EACA;AACF;;;AfeO,SAAS,eAAgB,SAAsC;AACpE,MAAI,CAAC,gBAAgB,OAAO,EAAG,QAAO;AACtC,MAAI,EAAE,YAAY,SAAU,QAAO;AACnC,MAAI,OAAO,QAAQ,WAAW,SAAU,QAAO;AAC/C,MAAI,EAAE,SAAS,SAAU,QAAO;AAChC,MAAI,OAAO,QAAQ,QAAQ,SAAU,QAAO;AAC5C,MAAI,EAAE,kBAAkB,SAAU,QAAO;AACzC,MAAI,OAAO,QAAQ,iBAAiB,SAAU,QAAO;AACrD,SAAO;AACT;AAEA,eAAsB,oBACpB,QACA,cACA;AACA,WAAS,OAAO,SAAS;AACzB,QAAM,YAAY,MAAM,QAAmB,eAAe,EAAE,KAAK,OAAO,GAAG,EAAE,aAAa,YAAI,aAAa,CAAC;AAC5G,MAAI,CAAC,UAAU,QAAS,QAAO;AAC/B,QAAM,WAAW,UAAU;AAC3B,QAAM,WAAW,SAAS;AAC1B,QAAM,oBAAoB,oCAA+B;AACzD,QAAM,UAAgC,EAAE,QAAQ,SAAS,mBAAmB,aAAa;AACzF,QAAM,UAA2B;AAAA,IAC/B,WAAW,oBACP,YAAI,wCACJ,YAAI;AAAA,EACV;AACA,MAAI;AACJ,MAAI;AACF,YAAQ,IAAI,KAAK,SAAS,YAAI,YAAY,OAAO;AAAA,EACnD,SAAS,KAAK;AACZ;AAAA;AAAA,MAEE;AAAA,MACA,EAAE,OAAOC,iBAAgB,GAAG,EAAE;AAAA,IAChC;AACA,WAAO;AAAA;AAAA,MAEL;AAAA,MACAA,iBAAgB,GAAG;AAAA,IACrB;AAAA,EACF;AACA,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,IAAoB;AAAA,MAClB,QAAQ,IAAIC,eAAc,SAAS,MAAM;AAAA,MACzC,OAAO;AAAA,MACP,UAAU,oBAAI,KAAK;AAAA,IACrB;AAAA,IACA,EAAE,aAAa,YAAI,aAAa;AAAA,EAClC;AACA,MAAI,CAAC,SAAS,QAAS,QAAO;AAC9B,SAAOC,SAAQ,YAAY,KAAK;AAClC;AAEA,eAAsB,qBACpB,QACA,cACA;AACA,WAAS,OAAO,SAAS;AACzB,QAAM,YAAY,MAAM,QAAmB,eAAe,EAAE,KAAK,OAAO,GAAG,EAAE,aAAa,YAAI,aAAa,CAAC;AAC5G,MAAI,CAAC,UAAU,QAAS,QAAO;AAC/B,QAAM,WAAW,UAAU;AAC3B,QAAM,WAAW,SAAS;AAC1B,QAAM,oBAAoB,oCAA+B;AACzD,QAAM,UAAgC,EAAE,QAAQ,SAAS,mBAAmB,aAAa;AACzF,QAAM,UAA2B;AAAA,IAC/B,WAAW,oBACP,YAAI,yCACJ,YAAI;AAAA,EACV;AACA,MAAI;AACJ,MAAI;AACF,YAAQ,IAAI,KAAK,SAAS,YAAI,YAAY,OAAO;AAAA,EACnD,SAAS,KAAK;AACZ;AAAA;AAAA,MAEE;AAAA,MACA,EAAE,OAAOF,iBAAgB,GAAG,EAAE;AAAA,IAChC;AACA,WAAO;AAAA;AAAA,MAEL;AAAA,MACAA,iBAAgB,GAAG;AAAA,IACrB;AAAA,EACF;AACA,QAAM,WAAW,MAAM;AAAA,IACrB;AAAA,IAAoB;AAAA,MAClB,QAAQ,IAAIC,eAAc,SAAS,MAAM;AAAA,MACzC,OAAO;AAAA,MACP,UAAU,oBAAI,KAAK;AAAA,IACrB;AAAA,IACA,EAAE,aAAa,YAAI,aAAa;AAAA,EAClC;AACA,MAAI,CAAC,SAAS,QAAS,QAAO;AAC9B,SAAOC,SAAQ,YAAY,KAAK;AAClC;AAEO,IAAM,oBAAoB;AAE1B,SAAS,uBACd,WACA,OACA;AACA,SAAO,UAAU,mBAAmB,UAAU,KAAK,EAAE;AACvD;AAEO,SAAS,wBACd,WACA,OACAC,QACA;AACA,QAAM,YAAYA,SACd,YAAI,yCACJ,YAAI;AACR,SAAO,UAAU,gBAAgB,OAAO;AAAA,IACtC,UAAU;AAAA,IACV,QAAQ,YAAI,eAAe;AAAA,IAC3B,UAAU;AAAA,IACV,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,YAAY,GAAI;AAAA,EACjD,CAAC;AACH;AAEA,eAAsB,iBACpB,QACAC,SACA;AACA,WAAS,OAAO,SAAS;AACzB,QAAM,WAAWA;AACjB,MAAI,SAAS,WAAW,EAAG,QAAOF,SAAQ,YAAY,IAAI;AAC1D,QAAM,kBAAkB,MAAM,WAA2B,oBAAoB,EAAE,QAAQ,OAAO,EAAE,KAAK,SAAS,EAAE,GAAG,EAAE,aAAa,YAAI,aAAa,CAAC;AACpJ,MAAI,CAAC,gBAAgB,SAAS;AAC5B,UAAM,EAAE,KAAK,IAAI,gBAAgB;AACjC,QAAI,8EAA8C;AAChD;AAAA;AAAA,QAEE;AAAA,QACA,EAAE,QAAQ,QAAAE,SAAQ,OAAO,gBAAgB,MAAM;AAAA,MACjD;AACA,aAAO;AAAA,IACT,OAAO;AACL;AAAA;AAAA,QAEE;AAAA,QACA,EAAE,QAAQ,QAAAA,SAAQ,OAAO,gBAAgB,MAAM;AAAA,MACjD;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACA,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,mBAAmB,MAAM,WAAkC,2BAA2B,SAAS,IAAI,YAAU;AAAA,IACjH,OAAO;AAAA,IACP,QAAQ,IAAIH,eAAc,SAAS,MAAM;AAAA,IACzC,WAAW;AAAA,EACb,EAAE,GAAG,EAAE,aAAa,YAAI,aAAa,CAAC;AACtC,MAAI,CAAC,iBAAiB,SAAS;AAC7B;AAAA;AAAA,MAEE;AAAA,MACA,EAAE,QAAQ,QAAAG,SAAQ,OAAO,iBAAiB,MAAM;AAAA,IAClD;AACA,WAAO;AAAA,EACT;AACA,MAAI,iBAAiB,QAAQ,kBAAkB,SAAS,QAAQ;AAC9D;AAAA;AAAA,MAEE;AAAA,MAA2G;AAAA,QACzG;AAAA,QACA,QAAAA;AAAA,QACA,cAAc,gBAAgB,QAAQ;AAAA,QACtC,UAAU,iBAAiB;AAAA,MAC7B;AAAA,IAAC;AACH,WAAO;AAAA;AAAA,MAEL;AAAA,IACF;AAAA,EACF;AACA,SAAOF,SAAQ,YAAY,IAAI;AACjC;AAEA,eAAsB,wBACpB,QACA,mBAA6B,CAAC,GAC9B;AACA,WAAS,OAAO,SAAS;AACzB,QAAM,uBAAuB,MAAM;AAAA,IACjC;AAAA,IACA,EAAE,OAAO;AAAA,IACT,EAAE,aAAa,YAAI,aAAa;AAAA,IAChC,EAAE,OAAO,KAAM,MAAM,EAAE,UAAU,GAAG,EAAE;AAAA,EACxC;AACA,MAAI,qBAAqB,WACpB,qBAAqB,QAAQ,MAAM,WAAW,EAAG,QAAOA,SAAQ,YAAY,IAAI;AACrF,MAAI,CAAC,qBAAqB,SAAS;AACjC,QAAI,qBAAqB,MAAM,6EAA8C,QAAOA,SAAQ,YAAY,IAAI;AAC5G;AAAA;AAAA,MAEE;AAAA,MACA,EAAE,QAAQ,OAAO,qBAAqB,MAAM;AAAA,IAC9C;AACA,WAAO;AAAA,EACT;AACA,QAAM,iBAAiB,qBAAqB,QAAQ;AACpD,QAAM,WAAW,eAAe,IAAI,WAAS,MAAM,KAAK;AACxD,SAAO,MAAM,iBAAiB,QAAQ,CAAC,GAAG,UAAU,GAAG,gBAAgB,CAAC;AAC1E;AAQA,eAAsB,uBACpB,KACA,KACA,MACA;AACA,QAAM,aAAa,IAAI,QAAQ;AAC/B,MAAI,eAAe,UAAa,CAAC,WAAW,WAAW,SAAS,EAAG,QAAO,KAAK;AAC/E,QAAM,QAAQ,WAAW,MAAM,GAAG,EAAE,CAAC;AACrC,MAAI,UAAU,OAAW,QAAO,KAAK;AACrC,MAAI;AACJ,MAAI;AACF,UAAM,WAAW,IAAI,OAAO,OAAO,YAAI,UAAU;AACjD,UAAM,YAAY,eAAe,QAAQ;AACzC,QAAI,CAAC,UAAW,OAAM,IAAI,MAAM,iCAAiC,KAAK,EAAE;AACxE,cAAU;AAAA,EACZ,SAAS,KAAK;AACZ;AAAA;AAAA,MAEE;AAAA,MACA,EAAE,OAAOF,iBAAgB,GAAG,EAAE;AAAA,IAChC;AACA,WAAO,KAAK;AAAA,EACd;AACA,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,QAAM,EAAE,QAAQ,SAAS,KAAK,aAAa,IAAI;AAC/C,QAAM,kBAAkB,UACpB,YAAI,+CACJ,YAAI;AACR,QAAM,6BAA6B,UAC/B,YAAI,uCACJ,YAAI;AACR,QAAM,yBAAyB,MAAM,MAAM;AAC3C,QAAM,sBAAsB,eAAe;AAC3C,QAAM,yBAAyB,0BAA0B;AACzD,MAAI,wBAAwB;AAC1B,UAAM,oBAAoB,MAAM;AAAA,MAC9B;AAAA,MACA,EAAE,OAAO,MAAM;AAAA,MACf,EAAE,aAAa,YAAI,aAAa;AAAA,IAClC;AACA,QAAI,kBAAkB,QAAS,QAAO,KAAK;AAC3C,UAAM,WAAW,MAAM,oBAAoB,QAAQ,eAAe,CAAC;AACnE,QAAI,CAAC,SAAS,QAAS,QAAO,KAAK;AACnC,QAAI;AACJ,QAAI;AACF,YAAM,WAAW,IAAI,OAAO,SAAS,SAAS,YAAI,UAAU;AAC5D,YAAM,YAAY,eAAe,QAAQ;AACzC,UAAI,CAAC,UAAW,OAAM,IAAI,MAAM,iCAAiC,SAAS,OAAO,EAAE;AACnF,wBAAkB;AAAA,IACpB,SAAS,KAAK;AACZ;AAAA;AAAA,QAEE;AAAA,QACA,EAAE,OAAOA,iBAAgB,GAAG,EAAE;AAAA,MAChC;AACA,aAAO,KAAK;AAAA,IACd;AACA,2BAAuB,IAAI,WAAW,SAAS,OAAO;AACtD,QAAI,OAAO,oBAAoB,SAAS;AACxC,QAAI,OAAO,qBAAqB;AAChC,WAAO,KAAK;AAAA,EACd,OAAO;AACL,QAAI,OAAO,oBAAoB;AAC/B,QAAI,OAAO,qBAAqB;AAChC,WAAO,KAAK;AAAA,EACd;AACF;AAQA,eAAsB,iBACpB,mBACA,oBAIC;AACD,MAAI,sBAAsB,OAAW,QAAO,0EAAiD,yBAAyB;AACtH,MAAI,uBAAuB,OAAW,QAAO,0EAAiD,yBAAyB;AACvH,QAAM,EAAE,IAAI,IAAI;AAChB,MAAI,QAAQ,OAAW,QAAO,0EAAiD,0BAA0B;AACzG,QAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,MAAI,OAAO,IAAK,QAAO,0EAAiD,0BAA0B;AAClG,MAAI,sBAAsB,OAAW,QAAO,0EAAiD,2BAA2B;AACxH,QAAM,oBAAoB,MAAM,QAA+B,2BAA2B,EAAE,OAAO,kBAAkB,GAAG,EAAE,aAAa,YAAI,aAAa,CAAC;AACzJ,MAAI,kBAAkB,QAAS,QAAO,0EAAiD,+BAA+B;AACtH,SAAOE,SAAQ,YAAY,EAAE,mBAAmB,mBAAmB,CAAC;AACtE;AAEA,eAAsB,UAAW,QAAgB;AAC/C,QAAM,aAAa,MAAM,QAAmB,eAAe,EAAE,KAAK,OAAO,GAAG,EAAE,aAAa,YAAI,aAAa,CAAC;AAC7G,MAAI,CAAC,WAAW,QAAS,QAAO,oEAA8C,qBAAqB;AACnG,QAAM,WAAW,WAAW;AAC5B,QAAM,oBAAoB,iBAAiB,QAAQ;AACnD,MAAI,sBAAsB,KAAM,QAAO,oEAA8C,qBAAqB;AAC1G,SAAOA,SAAQ,YAAY,iBAAiB;AAC9C;AAOO,IAAM,QAAiB,CAAC,UAAU,CAAC,MAAM,OAAO,UAAU;AAC/D,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AACJ,QAAM,EAAE,MAAM,mBAAmB,mBAAmB,IAAI;AAGxD,MACE,UAAU,UACP,aAAa,UACb,WAAW,UACX,aAAa,OAChB,QAAO,aAAa,KAAc;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACD,QAAM,oBAAoB,iBAAiB,IAAI;AAC/C,MAAI,sBAAsB,KAAM,QAAO,cAAc,sDAAgC,qBAAqB;AAG1G,QAAM,aAAa,UAAU;AAC7B,QAAM,UAAU,cAAc,MAAM,SAAS,kBAAkB,IAAI;AACnE,MAAI,cAAc,CAAC,QAAS,QAAO,cAAc,4DAAmC,mCAAmC;AAGvH,QAAM,eAAe,aAAa;AAClC,QAAM,YAAY,gBAAgB,SAAS,SAAS,kBAAkB,MAAM;AAC5E,MAAI,gBAAgB,CAAC,UAAW,QAAO,cAAc,sDAAgC,qCAAqC;AAG1H,QAAM,cAAc,WAAW;AAC/B,QAAM,WAAW,eAAe,kBAAkB,OAAO,KAAK,eAAa,OAAO,SAAS,SAAS,CAAC;AACrG,MAAI,eAAe,CAAC,SAAU,QAAO,cAAc,sDAAgC,oCAAoC;AAEvH,SAAO,aAAa,KAAc;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAQA,eAAsB,sCACpB,OACA,UACA;AACA,QAAM,uBAAuB,YAAI;AACjC,QAAM,kBAAkBG,UAAS,QAAQ,oBAAoB,EAAE,eAAe;AAC9E,QAAM,0BAA0B,KAAK,IAAI,IAAI;AAC7C,QAAM,iBAAiB,IAAI,KAAK,uBAAuB;AACvD,QAAM,aAAa,WAAW;AAC9B,QAAM,gBAA6D;AAAA,IACjE;AAAA,IACA,OAAO;AAAA,IACP,WAAW;AAAA,EACb;AACA,QAAM,gBAAgB,MAAM,UAAqC,+BAA+B,eAAe,EAAE,aAAa,YAAI,aAAa,CAAC;AAChJ,MAAI,CAAC,cAAc,SAAS;AAC1B,8EAA8C,sDAAsD;AAAA,MAClG;AAAA,MACA;AAAA,MACA,OAAO,cAAc;AAAA,IACvB,CAAC;AAAA,EACH;AACA,QAAM,YAAY,OAAO,QAAQ,kDACoB,UAAU,iCAC3B,YAAI,4CAA4C;AACpF,QAAM,cAAc,YAAI,iBAAiB,eAAe,YAAI,mCAAmC,YAAI;AACnG,QAAM,aAAa,YAAI,iBAAiB,eAAe,YAAI,kCAAkC;AAC7F,QAAM,OAAO,MAAY;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO;AACT;AAEA,eAAsB,sCAAuC,OAAe,UAAkB;AAC5F,QAAM,uBAAuB,YAAI;AACjC,QAAM,kBAAkBA,UAAS,QAAQ,oBAAoB,EAAE,eAAe;AAC9E,QAAM,0BAA0B,KAAK,IAAI,IAAI;AAC7C,QAAM,iBAAiB,IAAI,KAAK,uBAAuB;AACvD,QAAM,aAAa,WAAW;AAC9B,QAAM,gBAA6D;AAAA,IACjE;AAAA,IACA,OAAO;AAAA,IACP,WAAW;AAAA,EACb;AACA,QAAM,gBAAgB,MAAM,UAAqC,+BAA+B,eAAe,EAAE,aAAa,YAAI,aAAa,CAAC;AAChJ,MAAI,CAAC,cAAc,SAAS;AAC1B,kEAA4C,sDAAsD;AAAA,MAChG;AAAA,MACA;AAAA,MACA,OAAO,cAAc;AAAA,IACvB,CAAC;AAAA,EACH;AACA,QAAM,YAAY,OAAO,QAAQ,8CACgB,UAAU,iCACvB,YAAI,4CAA4C;AACpF,QAAM,cAAc,YAAI,iBAAiB,eAAe,YAAI,mCAAmC,YAAI;AACnG,QAAM,aAAa,YAAI,iBAAiB,eAAe,YAAI,kCAAkC;AAC7F,QAAM,OAAO,MAAY;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,SAAO;AACT;;;AgBjeA,OAAO,UAAU;AAEjB,SAAS,WAAAC,gBAAe;AAIjB,IAAM,SAAS,IAAI,KAAK;AAExB,IAAM,SAAS,CAAC,QAAuD;AAC5E,QAAM,iBAAiB,CAAC,OAAO,QAAQ,WAAW,OAAO;AACzD,MAAI,eAAe,SAAS,IAAI,MAAM,EAAG,QAAOC,SAAQ,YAAY,IAAI;AACxE,QAAM,SAAS,IAAI,QAAQ,YAAI,gBAAgB;AAC/C,QAAM,QAAQ,IAAI,QAAQ,YAAI,iBAAiB;AAC/C,MAAI,OAAO,WAAW,SAAU,QAAOA,SAAQ,+DAAgD;AAC/F,MAAI,OAAO,UAAU,SAAU,QAAOA,SAAQ,6DAA+C;AAC7F,QAAM,WAAW,OAAO,OAAO,QAAQ,KAAK;AAC5C,MAAI,CAAC,SAAU,QAAOA,SAAQ,yDAA6C;AAC3E,SAAOA,SAAQ,YAAY,IAAI;AACjC;;;AClBA,SAAS,kBAAkB;AAC3B,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,OAAO,UAAU,YAAAC,iBAAgB;AACjC,SAAS,WAAAC,gBAAe;AACxB,SAAS,iBAAiB;AAC1B,SAAS,mBAAAC,wBAAuB;AAChC,SAAS,SAASC,sBAAqB;AACvC,OAAO,YAAY;;;ACRnB;AAAA,EACE,UAAUC;AAAA,EACV,SAASC;AAAA,EACT,SAASC;AAAA,OACJ;AAUA,IAAMC,kBAAgD;AAGtD,IAAM,wBAAgD,IAAIC,gBAAiC;AAAA,EAChG,KAAK;AAAA,IACH,MAAMA,gBAAe,MAAM;AAAA,IAC3B,SAAS,MAAM,IAAIC,eAAc,SAAS;AAAA,EAC5C;AAAA,EACA,QAAQ;AAAA,IACN,MAAMD,gBAAe,MAAM;AAAA,IAC3B,KAAU;AAAA,IACV,UAAU;AAAA,IACV,QAAQ;AAAA,EACV;AAAA,EACA,sBAAsB,EAAE,MAAM,QAAQ,UAAU,MAAM,SAAS,EAAE;AAAA,EACjE,wBAAwB,EAAE,MAAM,QAAQ,UAAU,MAAM,SAAS,EAAE;AAAA,EACnE,sBAAsB,EAAE,MAAM,QAAQ,UAAU,MAAM,SAAS,EAAE;AACnE,CAAC;AAGM,IAAM,uBAA8CE;AAAA,EACzDH;AAAA,EACA;AACF;;;ACrCA,SAAS,cAAAI,mBAAkB;AAC3B,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,iBAAiB;AAC1B,SAAS,OAAO,cAAc;AAC9B,OAAO,oBAAoB;AAc3B,IAAM;AAAA,EACJ,MAAM;AAAA,EACN;AACF,IAAI,MAAM,OAAO,EAAE,QAAQ,YAAI,gBAAgB,CAAC;AAEzC,IAAM,cAA2B,MAAM;AAEvC,IAAM,eAA6B,CAAC,aAA8B;AACvE,QAAM,SAAS,KAAK,IAAI,EAAE,SAAS;AACnC,QAAM,SAAS,OAAO,SAAS,IAAI,GAAG;AACtC,QAAM,QAAQ,OAAO,MAAM,GAAG,CAAC;AAC/B,QAAM,QAAQ,OAAO,MAAM,GAAG,CAAC;AAC/B,QAAM,QAAQ,OAAO,MAAM,GAAG,EAAE;AAChC,QAAM,QAAQ,OAAO,MAAM,IAAI,EAAE;AACjC,QAAM,aAAaC,YAAW,EAC3B,QAAQ,MAAM,EAAE,EAChB,MAAM,SAAS,EACf,KAAK,GAAG;AACX,QAAM,aAAa,KAAK,KAAK,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,UAAU,EAAE;AAC5F,MAAI,aAAa,OAAW,QAAO;AACnC,SAAO,KAAK,KAAK,YAAY,QAAQ;AACvC;AAEO,IAAM,kBAAmC,OAAO,aAAqB;AAC1E,QAAM,gBAAgB,IAAI,KAAK,KAAK,IAAI,IAAI,QAAQ;AACpD,QAAM,mBAAmB,cAAc,QAAQ,EAAE,SAAS,EAAE,SAAS,IAAI,GAAG;AAC5E,QAAM,iBAAiB,iBAAiB,MAAM,GAAG,CAAC;AAClD,QAAM,iBAAiB,iBAAiB,MAAM,GAAG,CAAC;AAClD,QAAM,iBAAiB,iBAAiB,MAAM,GAAG,EAAE;AACnD,QAAM,iBAAiB,iBAAiB,MAAM,IAAI,EAAE;AACpD,MAAI;AACF,UAAM,gBAAgB;AACtB,UAAM,YAAY,MAAM,GAAG,SAAS,QAAQ,aAAa;AACzD,UAAM,QAAQ,IAAI,UAAU,IAAI,aAAW;AACzC,YAAM,gBAAgB,SAAS,OAAO;AACtC,YAAM,kBAAkB,SAAS,cAAc;AAC/C,YAAM,cAAc,KAAK,KAAK,mBAAmB,OAAO;AACxD,YAAM,eAAe,OAAO,MAAM,aAAa,KAC1C,GAAG,aAAa,GAAG,WAAW,KAC9B,gBAAgB;AACrB,UAAI,aAAc,QAAO,GAAG,SAAS,GAAG,aAAa,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IACvF,CAAC,CAAC;AAAA,EACJ,SAAS,KAAU;AACjB,SAAI,2BAAK,UAAS,SAAU;AAAA;AAAA,MAE1B;AAAA,MACA,EAAE,OAAO,IAAI;AAAA,IACf;AAAA,EACF;AACA,MAAI;AACF,UAAM,gBAAgB,KAAK,KAAK,mBAAmB,cAAc;AACjE,UAAM,YAAY,MAAM,GAAG,SAAS,QAAQ,aAAa;AACzD,UAAM,QAAQ,IAAI,UAAU,IAAI,aAAW;AACzC,YAAM,gBAAgB,SAAS,OAAO;AACtC,YAAM,kBAAkB,SAAS,cAAc;AAC/C,YAAM,cAAc,KAAK,KAAK,eAAe,OAAO;AACpD,YAAM,eAAe,OAAO,MAAM,aAAa,KAC1C,GAAG,aAAa,GAAG,WAAW,KAC9B,gBAAgB;AACrB,UAAI,aAAc,QAAO,GAAG,SAAS,GAAG,aAAa,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IACvF,CAAC,CAAC;AAAA,EACJ,SAAS,KAAU;AACjB,SAAI,2BAAK,UAAS,SAAU;AAAA;AAAA,MAE1B;AAAA,MACA,EAAE,OAAO,IAAI;AAAA,IACf;AAAA,EACF;AACA,MAAI;AACF,UAAM,gBAAgB,KAAK,KAAK,mBAAmB,gBAAgB,cAAc;AACjF,UAAM,YAAY,MAAM,GAAG,SAAS,QAAQ,aAAa;AACzD,UAAM,QAAQ,IAAI,UAAU,IAAI,aAAW;AACzC,YAAM,gBAAgB,SAAS,OAAO;AACtC,YAAM,kBAAkB,SAAS,cAAc;AAC/C,YAAM,cAAc,KAAK,KAAK,eAAe,OAAO;AACpD,YAAM,eAAe,OAAO,MAAM,aAAa,KAC1C,GAAG,aAAa,GAAG,WAAW,KAC9B,gBAAgB;AACrB,UAAI,aAAc,QAAO,GAAG,SAAS,GAAG,aAAa,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IACvF,CAAC,CAAC;AAAA,EACJ,SAAS,KAAU;AACjB,SAAI,2BAAK,UAAS,SAAU;AAAA;AAAA,MAE1B;AAAA,MACA,EAAE,OAAO,IAAI;AAAA,IACf;AAAA,EACF;AACA,MAAI;AACF,UAAM,gBAAgB,KAAK,KAAK,mBAAmB,gBAAgB,gBAAgB,cAAc;AACjG,UAAM,YAAY,MAAM,GAAG,SAAS,QAAQ,aAAa;AACzD,UAAM,QAAQ,IAAI,UAAU,IAAI,aAAW;AACzC,YAAM,gBAAgB,SAAS,OAAO;AACtC,YAAM,kBAAkB,SAAS,cAAc;AAC/C,YAAM,cAAc,KAAK,KAAK,eAAe,OAAO;AACpD,YAAM,eAAe,OAAO,MAAM,aAAa,KAC1C,GAAG,aAAa,GAAG,WAAW,KAC9B,gBAAgB;AACrB,UAAI,aAAc,QAAO,GAAG,SAAS,GAAG,aAAa,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IACvF,CAAC,CAAC;AACF,+BAA0B,sBAAsB;AAAA,EAClD,SAAS,KAAU;AACjB,SAAI,2BAAK,UAAS,SAAU;AAAA;AAAA,MAE1B;AAAA,MACA,EAAE,OAAO,IAAI;AAAA,IACf;AAAA,EACF;AACF;AAEA,eAAe,oBAAqB;AAClC,QAAM,sBAAsB,UAAU,cAAqB;AAC3D,QAAM,QAAQ,MAAM,oBAAoB,iBAAiB;AACzD,SAAO,SAAS;AAClB;AAEA,IAAI,kBAAkB;AAEf,IAAM,wBAA+C,YAAY;AACtE,MAAI;AACF,sBAAkB,MAAM,kBAAkB;AAC1C,+BAA0B,sCAAsC,EAAE,gBAAgB,CAAC;AAAA,EACrF,SAAS,KAAK;AACZ,gCAA2B,+CAA+C,EAAE,OAAO,IAAI,CAAC;AACxF,sBAAkB;AAAA,EACpB;AACF;AAIO,IAAM,0BAAmD,CAAC,UAAkB;AACjF,QAAM,cAAc,kBAAkB;AACtC,oBAAkB;AAClB,SAAO;AACT;AAEO,IAAM,QAAe,YAAY;AACtC,QAAM,QAAQ;AACd,QAAM,sBAAsB;AAC5B,6BAA0B,oBAAoB,EAAE,kBAAkB,CAAC;AACrE;;;AC9JA,SAAS,gBAAgB;AACzB,SAAS,UAAAC,eAAc;AACvB,SAAqB,kBAAkB;AACvC,SAAS,WAAAC,gBAAe;AACxB,SAAS,mBAAAC,wBAAuB;AAYzB,IAAM,kBAAN,MAAkD;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EAER,YACE,UACA,MACA,MACA;AACA,SAAK,UAAU,SAAS,SACpB,GAAG,QAAQ,MAAM,IAAI,IAAI,IAAI,KAC7B,GAAG,QAAQ,MAAM,IAAI;AACzB,mCAA4B,iCAAiC;AAAA,MAC3D;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,KAAK;AAAA,MACd,WAAW,YAAI;AAAA,IACjB,CAAC;AACD,QAAI,YAAI,qBAAqB,OAAO;AAClC,WAAK,OAAO,IAAI,WAAW;AAC3B,WAAK,SAAS;AACd,WAAK,WAAW;AAAA,IAClB,OAAO;AACL,WAAK,OAAO;AACZ,WAAK,SAAS;AAAA,IAChB;AAAA,EACF;AAAA,EAEA,MAAM,MAAO,KAAa,SAAsB;AAC9C,UAAM,UAAU,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,GAAG,EAAE;AAC1D;AAAA;AAAA,MAEE,6CAAwC,OAAO;AAAA,MAAQ;AAAA,QACvD;AAAA,QACA;AAAA,MACF;AAAA,IAAC;AACD,QAAI,KAAK,WAAW,MAAM;AACxB,YAAM,WAAW,MAAM,MAAM,KAAK,OAAO;AACzC;AAAA;AAAA,QAEE,mDAA8C,OAAO;AAAA,QAAK;AAAA,UACxD;AAAA,UACA;AAAA,QACJ;AAAA,MAAC;AACD,UAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU,EAAE;AACnF,aAAO,MAAM,SAAS,KAAK;AAAA,IAC7B,OAAO;AACL,YAAM,aAAa,MAAM,KAAK,OAAO,QAAQ,EAAE,GAAG,SAAS,IAAI,CAAC;AAChE;AAAA;AAAA,QAEE,mDAA8C,OAAO;AAAA,QAAK;AAAA,UACxD;AAAA,UACA,UAAU;AAAA,QACd;AAAA,MAAC;AACD,aAAO,WAAW;AAAA,IACpB;AAAA,EACF;AAAA,EAEA,MAAc,aAAc;AAC1B,UAAM,EAAE,QAAQ,MAAAC,MAAK,IAAI;AACzB,QAAI,WAAW,KAAM;AACrB,QAAIA,UAAS,KAAM;AACnB,SAAK,SAAS,MAAMA,MAAK,iBAAiB,KAAK,OAAO,KAAK;AAAA,EAC7D;AAAA,EAEA,MAAM,WACJ,QACA,UAAkB,KACuB;AACzC,WAAO,KAAK,gBAAgB,QAAQ,OAAO;AAAA,EAC7C;AAAA,EAEA,MAAM,WACJ,QACA,UAAkB,KACuB;AACzC,UAAM,SAAmB,CAAC;AAC1B,qBAAiB,SAAS,OAAQ,QAAO,KAAK,KAAK;AACnD,UAAM,SAAS,OAAO,OAAO,MAAM;AACnC,WAAO,KAAK,gBAAgB,QAAQ,OAAO;AAAA,EAC7C;AAAA,EAEA,MAAM,KACJ,MACA,UAAkB,KACI;AACtB,QAAI,gBAAgB,SAAU,QAAO,KAAK,WAAW,MAAM,OAAO;AAClE,WAAO,KAAK,WAAW,MAAM,OAAO;AAAA,EACtC;AAAA,EAEA,MAAc,gBACZ,QACA,SACsB;AACtB,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,OAAO;AAC9D,QAAI;AACF,YAAM,WAAW,yBAAyB,KAAK,OAAO,EAAE,SAAS,EAAE;AACnE,YAAM,OAAO;AACb,YAAM,WAAW;AACjB,UAAI,OAAO;AACX,cAAQ,KAAK,QAAQ,GAAG,IAAI;AAC5B,cAAQ,0DAA0D,QAAQ,IAAI,IAAI;AAClF,cAAQ,yCAAyC,IAAI;AACrD,cAAQ;AACR,YAAM,SAAS,OAAO,KAAK,MAAM,MAAM;AACvC,YAAM,SAAS,OAAO,KAAK,GAAG,IAAI,KAAK,QAAQ,KAAK,IAAI,IAAI,MAAM;AAClE,YAAM,WAAW,OAAO,OAAO,CAAC,QAAQ,QAAQ,MAAM,CAAC;AACvD,YAAM,WAAW,MAAM,KAAK,MAAM,GAAG,KAAK,OAAO,SAAS;AAAA,QACxD,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,QAAQ,WAAW;AAAA,QACnB,SAAS;AAAA,UACP,gBAAgB,iCAAiC,QAAQ;AAAA,QAC3D;AAAA,MACF,CAAC;AACD,mBAAa,SAAS;AACtB,YAAM,SAAS;AAMf,UAAI,OAAO,MAAO,QAAOC,SAAQ,YAAY,IAAI;AAAA,UAC5C,QAAOA,SAAQ,YAAY;AAAA,QAC9B;AAAA,QACA,SAAS,WAAW,OAAO,MAAM;AAAA,MACnC,CAAC;AAAA,IACH,SAAS,OAAO;AACd,mBAAa,SAAS;AACtB,UAAI,OAAO,UAAU,YAChB,UAAU,QACV,UAAU,SACV,MAAM,SAAS,aAAc,QAAOA,SAAQ,YAAY;AAAA,QAC3D;AAAA,QACA,SAAS;AAAA,MACX,CAAC;AACD,aAAOA,SAAQ,YAAY;AAAA,QACzB;AAAA,QACA,SAASC,iBAAgB,KAAK;AAAA,MAChC,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,KAAM,UAAkB,KAA+B;AAC3D,UAAMC,SAAQC,QAAO,OAAO;AAC5B,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,OAAO;AAC9D,QAAI;AACF,YAAM,WAAW,MAAM,KAAK,MAAM,GAAG,KAAK,OAAO,SAAS;AAAA,QACxD,QAAQ;AAAA,QACR,QAAQ,WAAW;AAAA,QACnB,SAAS;AAAA,UACP,gBAAgB;AAAA,QAClB;AAAA,MACF,CAAC;AACD,mBAAa,SAAS;AACtB,YAAM,SAAS;AAIf,UAAI,OAAO,WAAW,KAAM,QAAOH,SAAQ,YAAY,EAAE,sDAA2C,CAAC;AACrG,UAAI,OAAO,UAAU,YAAa,QAAOA,SAAQ,YAAY,EAAE,sDAA2C,CAAC;AAC3G,YAAM,MAAMG,QAAO,OAAO;AAC1B,YAAM,aAAa,OAAO,MAAMD,MAAK,IAAI;AACzC,aAAOF,SAAQ,YAAY,UAAU;AAAA,IACvC,SAAS,OAAO;AACd,mBAAa,SAAS;AACtB,aAAOA,SAAQ,YAAY,EAAE,sDAA2C,CAAC;AAAA,IAC3E;AAAA,EACF;AACF;;;AH7JO,IAAM,gBAAsC,OAAO,YAAY;AAAA,EACpE,aAAa,CAAC,MAAM,OAAO,OAAO,GAAG,MAAM,YAAmB,CAAC;AAAA,EAC/D,UAAU,CAAC,MAAM,MAAM,OAAO;AAC5B,UAAM,yBAAyB,wBAA+B,KAAK,IAAI;AACvE,QAAI,0BAA0B,UAAU,YAAI,2BAA2B,EAAE,QAAQ,EAAG,QAAO,GAAG,IAAI,MAAM,wBAAwB,GAAG,EAAE;AACrI,UAAM,WAAW,aAAiB,KAAK,YAAY;AACnD,UAAM,WAAWI,MAAK,KAAK,YAAmB,GAAG,QAAQ;AACzD,UAAM,UAAUA,MAAK,QAAQ,QAAQ;AACrC,IAAAC,IAAG,SAAS,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC,EAC3C,KAAK,MAAM,GAAG,MAAM,QAAQ,CAAC,EAC7B,MAAM,SAAO,GAAG,KAAK,EAAE,CAAC;AAAA,EAC7B;AACF,CAAC;AAGM,IAAM,UAAU,IAAI,gBAAgB,YAAI,iBAAiB,YAAI,aAAc,YAAI,WAAW;AAE1F,IAAM,WAAqB,OAAO,MAAM,UAAU,QAAS;AAChE,QAAM,aAAa,MAAM,QAAQ,KAAK,MAAM,OAAO;AACnD,MAAI,WAAW,QAAS,QAAOC,SAAQ,YAAY,IAAI;AACvD,kCAA6B,uBAAuB;AAAA,IAClD,OAAO,WAAW;AAAA,IAClB,MAAM,gBAAgB,SAAS,WAAW;AAAA,EAC5C,CAAC;AACD,SAAOA,SAAQ,YAAY;AAAA,IACzB;AAAA,IACA,SAAS,WAAW,MAAM;AAAA,EAC5B,CAAC;AACH;AAEO,IAAM,cAA2B,OAAO,UAAkB,QAAS;AACxE,QAAM,aAAa,MAAM,QAAQ,KAAK,OAAO;AAC7C,MAAI,WAAW,SAAS;AACtB,WAAOA,SAAQ,YAAY,WAAW,OAAO;AAAA,EAC/C;AACA,kCAA6B,sCAAsC,EAAE,OAAO,WAAW,MAAM,CAAC;AAC9F,SAAOA,SAAQ,YAAY;AAAA,IACzB;AAAA,IACA,SAAS,WAAW,MAAM;AAAA,EAC5B,CAAC;AACH;AAGO,IAAM,cAA2B,OAAO,SAAkD;AAC/F,QAAM,OAAO,WAAW,QAAQ;AAChC,QAAM,aAAa,IAAI,OAAO,UAAU;AAAA,IACtC,WAAW,CAAC,OAAO,MAAM,aAAa;AACpC,WAAK,OAAO,KAAK;AACjB,eAAS;AAAA,IACX;AAAA,EACF,CAAC;AACD,QAAM,cAAwB,OAAO,SAAS,IAAI,IAAIC,UAAS,KAAK,IAAI,IAAI;AAC5E,cAAY,KAAK,UAAU;AAC3B,SAAO,IAAI,QAAwC,aAAW;AAC5D,eAAW,GAAG,UAAU,MAAM,QAAQD,SAAQ,YAAY,KAAK,OAAO,KAAK,CAAC,CAAC,CAAC;AAC9E,eAAW,GAAG,SAAS,CAAC,QAAQ,QAAQA,SAAQ,YAAYE,iBAAgB,GAAG,CAAC,CAAC,CAAC;AAAA,EACpF,CAAC;AACH;AAGO,IAAM,yBAAiD,OAAO,QAAQ,cAAc,kBAAkB;AAC3G,QAAM,eAAe,MAAe,QAA0B,sBAAsB,EAAE,OAAO,GAAG,EAAE,aAAa,OAAO,CAAC;AACvH,MAAI,CAAC,aAAa,WACb,aAAa,MAAM,mCAAyB,QAAOF,SAAQ,qCAA0B;AAC1F,MAAI;AACJ,MAAI,CAAC,aAAa,SAAS;AACzB,UAAM,WAAW,MAAe,UAA4B,sBAAsB;AAAA,MAChF,QAAQ,IAAIG,eAAc,SAAS,MAAM;AAAA,MACzC,sBAAsB;AAAA,MACtB,wBAAwB;AAAA,MACxB,sBAAsB;AAAA,IACxB,GAAG,EAAE,aAAa,OAAO,CAAC;AAC1B,QAAI,CAAC,SAAS,QAAS,QAAOH,SAAQ,qCAA0B;AAChE,yBAAqB,SAAS;AAAA,EAChC,OAAO;AACL,yBAAqB,aAAa;AAAA,EACpC;AACA,QAAM,EAAE,sBAAsB,wBAAwB,qBAAqB,IAAI;AAC/E,QAAM,yBAAyB,uBAAuB;AACtD,QAAM,2BAA2B,yBAAyB;AAC1D,QAAM,yBAAyB,uBAAuB;AACtD,MAAI,yBAAyB,cAAc,MAAO,QAAOA,SAAQ,qFAAkD;AACnH,MAAI,2BAA2B,cAAc,QAAS,QAAOA,SAAQ,yFAAoD;AACzH,MAAI,yBAAyB,cAAc,MAAO,QAAOA,SAAQ,qFAAkD;AACnH,QAAM,kBAAkB,MAAe,UAA4B,sBAAsB,EAAE,OAAO,GAAG;AAAA,IACnG,MAAM;AAAA,MACJ,sBAAsB;AAAA,MACtB,wBAAwB;AAAA,MACxB,sBAAsB;AAAA,IACxB;AAAA,EACF,GAAG,EAAE,aAAa,OAAO,CAAC;AAC1B,MAAI,gBAAgB,QAAS,QAAOA,SAAQ,YAAY,gBAAgB,OAAO;AAC/E,SAAOA,SAAQ,YAAY,gBAAgB,MAAM,IAAI;AACvD;;;AlB3EO,IAAM,gBAAgB,CAC3B,YACA,SACG,YACwB;AAC3B,QAAM,UAAU,UAAU,MAAM,GAAG,OAAO;AAC1C,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,SAAS,QAAQ;AAAA,IACjB,SAAS,QAAQ;AAAA,EACnB;AACF;AAEO,IAAM,eAAe,OAA2B,EAAE,MAAM,OAAO;AAE/D,IAAM,eAAe,CAC1B,YACA,aAC2B;AAAA,EAC3B,MAAM;AAAA,EACN;AAAA,EACA;AACF;AAEO,IAAM,eAAe,CAC1B,YACA,SACA,MACA,OACA,MACA,UAC2B;AAAA,EAC3B,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,eAAe,CAC1B,YACA,UACA,SACA,aACA,cACA,wBACwB;AAAA,EACxB,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAQO,IAAM,+BAA+B,OAA+B;AAAA,EACzE,IAAI;AAAA,EACJ,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,eAAe;AAAA,EACf,aAAa;AACf;AAEO,IAAM,yBAAyB,CAAC,aAAyD;AAC9F,QAAM,EAAE,IAAI,QAAQ,WAAW,eAAe,YAAY,IAAI;AAC9D,QAAM,QAAQI,QAAO,OAAO;AAC5B,QAAM,YAAY,QAAQ;AAC1B,QAAM,YAAY,OAAO,YAAY,QAAU;AAC/C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,IAAM,wBAAwB,CACnC,KACA,KACA,SACG;AACH,QAAM,EAAE,GAAG,IAAI;AACf,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,EAAE,qBAAqB,EAAE,QAAQ,KAAK,EAAE,IAAI;AAClD,QAAM,EAAE,OAAO,IAAI;AACnB,MAAI,OAAO,WAAW;AAAA,IACpB,IAAI,MAAM;AAAA,IACV;AAAA,IACA,WAAWC,YAAW;AAAA,IACtB,eAAeD,QAAO,OAAO;AAAA,IAC7B,aAAa,KAAK,IAAI;AAAA,EACxB;AACA,OAAK;AACP;AAEO,IAAM,qBAAqB,CAAC,QAA0C;AAC3E,QAAM,WAAW,IAAI,OAAO;AAC5B,MAAI,aAAa,OAAW;AAAA;AAAA,IAE1B;AAAA,EACF;AACA,SAAO,YAAY,6BAA6B;AAClD;AAQO,IAAM,4BAA4B,CACvC,KACA,iBACG;AACH,MAAI,UAAU,iBAAiB,UAAU,EACtC,UAAU,2BAA2B,qBAAqB,EAC1D,UAAU,mBAAmB,aAAa,EAC1C,UAAU,6BAA6B,qCAAqC,EAC5E,UAAU,0BAA0B,SAAS,EAC7C,UAAU,gBAAgB,aAAa,SAAS,EAChD,UAAU,mBAAmB,GAAG,KAAK,IAAI,IAAI,aAAa,WAAW,IAAI,EACzE,UAAU,iBAAiB,KAAK,UAAU;AAAA,IACzC,QAAQ,aAAa;AAAA,IACrB,WAAW,aAAa;AAAA,IACxB,aAAa,aAAa;AAAA,EAC5B,CAAC,CAAC;AACN;AAEO,IAAM,0BAA0B,CAIrC,KACAE,mBACqC;AACrC,QAAM,WAAW,mBAAmB,GAAG;AACvC,QAAM,eAAe,uBAAuB,QAAQ;AACpD,4BAA0B,KAAK,YAAY;AAC3C,QAAM,eAAuC;AAAA,IAC3C,SAAS;AAAA,IACT,YAAYA,eAAc;AAAA,IAC1B,MAAM;AAAA,IACN,OAAO;AAAA,MACL,MAAMA,eAAc;AAAA,MACpB,SAASA,eAAc;AAAA,MACvB,SAASA,eAAc;AAAA,IACzB;AAAA,IACA,MAAM;AAAA,EACR;AACA,MAAI,OAAO,aAAa,UAAU,EAC/B,KAAK,0BAA0B,EAC/B,UAAU,uBAAuB,QAAQ,EACzC,KAAK,YAAY;AACpB,SAAO;AACT;AAEO,IAAM,yBAAyB,CACpC,QACmC;AACnC,QAAM,WAAW,mBAAmB,GAAG;AACvC,QAAM,eAAe,uBAAuB,QAAQ;AACpD,4BAA0B,KAAK,YAAY;AAC3C,MAAI,OAAO,GAAG,EACX,IAAI;AACP,SAAO;AACT;AAEO,IAAM,yBAAyB,CAIpC,KACAC,kBACoC;AACpC,QAAM,WAAW,mBAAmB,GAAG;AACvC,QAAM,eAAe,uBAAuB,QAAQ;AACpD,4BAA0B,KAAK,YAAY;AAC3C,QAAM,eAAsC;AAAA,IAC1C,SAAS;AAAA,IACT,GAAGA;AAAA,IACH,MAAM;AAAA,EACR;AACA,MAAI,OAAO,aAAa,UAAU,EAC/B,KAAK,iCAAiC,EACtC,UAAU,uBAAuB,QAAQ,EACzC,KAAK,YAAY;AACpB,SAAO;AACT;AAEO,IAAM,yBAAyB,CAIpC,KACAC,kBACoC;AACpC,QAAM,WAAW,mBAAmB,GAAG;AACvC,QAAM,eAAe,uBAAuB,QAAQ;AACpD,4BAA0B,KAAK,YAAY;AAC3C,QAAM,eAAsC;AAAA,IAC1C,SAAS;AAAA,IACT,GAAGA;AAAA,IACH,MAAM;AAAA,EACR;AACA,MAAI,OAAO,aAAa,UAAU,EAC/B,KAAK,iCAAiC,EACtC,UAAU,uBAAuB,QAAQ,EACzC,UAAU,iBAAiB,aAAa,KAAK,EAC7C,UAAU,UAAU,aAAa,IAAI,EACrC,UAAU,eAAe,aAAa,QAAQ,EAAE,EAChD,UAAU,eAAe,aAAa,QAAQ,EAAE,EAChD,KAAK,YAAY;AACpB,SAAO;AACT;AAEO,IAAM,yBAAyB,CACpC,KACAC,kBACuF;AACvF,QAAM,WAAW,mBAAmB,GAAG;AACvC,QAAM,eAAe,uBAAuB,QAAQ;AACpD,4BAA0B,KAAK,YAAY;AAC3C,MAAI,OAAOA,cAAa,UAAU,EAC/B,KAAKA,cAAa,WAAW,EAC7B,UAAU,uBAAuB,yBAAyBA,cAAa,QAAQ,uBAAuB,mBAAmBA,cAAa,QAAQ,CAAC,EAAE,EACjJ,UAAU,iBAAiBA,cAAa,YAAY,EACpD,UAAU,kBAAkBA,cAAa,kBAAkB;AAC9D,MAAIA,cAAa,mBAAmBC,WAAU;AAC5C,UAAM,eAAe;AACrB,IAAAD,cAAa,QAAQ,GAAG,SAAS,CAAC,QAAQ;AACxC,kEAA2C,cAAc,EAAE,IAAI,CAAC;AAChE,UAAI,CAAC,IAAI,aAAa;AACpB,gCAAwB,KAAK;AAAA,UAC3B;AAAA;AAAA,UAEA;AAAA,QACF,CAAC;AAAA,MACH,MAAO,KAAI,QAAQ;AAAA,IACrB,CAAC;AACD,IAAAA,cAAa,QAAQ,KAAK,GAAG;AAAA,EAC/B,MACK,KAAI,KAAKA,cAAa,OAAO;AAClC,SAAO;AACT;AAQO,IAAM,iBAAiB,OAC5B,KACA,KACA,QACA,QACA,QACA,kBAA2B,SACsD;AAGjF,QAAM,gBAAgB,MAAM,oBAAoB,KAAK,KAAK;AAAA,IACxD,SAAS;AAAA,IACT,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,YAAY;AAAA,EACd,CAAC;AACD,MAAI,CAAC,cAAc,SAAS;AAC1B,UAAM,EAAE,KAAK,IAAI,cAAc;AAC/B,QAAI,SAAS,kBAAmB,QAAO,cAAc,4CAA2B,sBAAsB,cAAc,MAAM,KAAK,EAAE;AACjI,WAAO,cAAc,0DAAkCE,iBAAgB,cAAc,KAAK,CAAC;AAAA,EAC7F;AACA,QAAM,EAAE,MAAM,IAAI;AAClB,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,sCAA+B,4DAA4D,EAAE,MAAM,CAAC;AACpG,QAAI,OAAO,UAAU;AACrB,WAAO,aAAa;AAAA,EACtB;AACA,MAAI,UAAU,QAAW;AACvB,QAAI,OAAO,UAAU,CAAC;AACtB,WAAO,aAAa;AAAA,EACtB;AAGA,QAAM,aAAa,OAAO,QAAQ,KAAK;AAIvC,MAAI,WAAW,WAAW,EAAG,QAAO,aAAa;AACjD,MAAI,WAAW,MAAM,CAAC,CAAC,GAAGC,MAAK,MAAMA,OAAM,WAAW,CAAC,EAAG,QAAO,aAAa;AAG9E,MAAI,iBAAiB;AACnB,UAAM,EAAE,OAAO,IAAI,IAAI,OAAO,sBAAsB,CAAC;AACrD,QAAI,WAAW,OAAW,QAAO,cAAc,4DAAmC,4CAA4C;AAC9H,UAAM,sBAAsB,OAAO,OAAO,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,SAAS,MAAM,KAAK,MAAM,CAAC;AAChG,QAAI,wBAAwB,EAAG,QAAO,cAAc,0DAAkC,2BAA2B;AACjH,UAAM,wBAAwB,MAAM,uBAAuB,QAAQ,qBAAqB;AAAA,MACtF,OAAOC,WAAU,YAAI,iCAAiC,EAAE,QAAQ;AAAA,MAChE,SAASA,WAAU,YAAI,mCAAmC,EAAE,QAAQ;AAAA,MACpE,OAAOA,WAAU,YAAI,iCAAiC,EAAE,QAAQ;AAAA,IAClE,CAAC;AACD,QAAI,CAAC,sBAAsB,QAAS,QAAO,cAAc,oEAAuC,sCAAsC;AAAA,EACxI;AAGA,QAAM,qBAAmE,CAAC;AAC1E,aAAW,CAAC,OAAOD,MAAK,KAAK,YAAY;AACvC,eAAW,WAAWA,QAAO;AAC3B,YAAM,OAAOA,OAAM,OAAO;AAC1B,YAAME,QAAO,KAAK;AAClB,YAAM,aAAa,MAAM,SAAS,iBAAiBA,KAAI,CAAC;AACxD,UAAI,CAAC,WAAW,SAAS;AACvB,YAAI,WAAW,MAAM,mCAAiC,QAAO,cAAc,0CAA0B,uBAAuB,OAAO,aAAa,KAAK,cAAc;AAAA,YAC9J,QAAO,cAAc,oEAAuC,0BAA0B;AAAA,MAC7F;AACA,YAAM,SAAS,KAAK;AACpB,YAAM,SAAS,KAAK;AACpB,YAAM,EAAE,MAAM,QAAQ,KAAK,SAAS,IAAI,cAAc,MAAM;AAC5D,YAAM,QAAQ,SAAS,QAAQ,OAAO,EAAE;AACxC,YAAM,kBAAkB,mBAAmB,MAAM,YAAY,CAAC;AAC9D,YAAM,EAAE,KAAK,aAAa,MAAM,aAAa,IAAI,MAAM,mBAAmB,iBAAiBA,KAAI,CAAC,KAAK,CAAC;AACtG,UAAI,gBAAgB,UAAa,gBAAgB,gBAAiB,QAAO,cAAc,0DAAkC,uBAAuB,OAAO,aAAa,KAAK,2BAA2B;AACpM,UAAI,iBAAiB,UAAa,iBAAiB,OAAQ,QAAO,cAAc,0DAAkC,uBAAuB,OAAO,aAAa,KAAK,2BAA2B;AAC7L,YAAM,SAAS,eAAe;AAC9B,YAAM,oBAAoB,YAAI;AAC9B,UAAI,CAAC,kBAAkB,SAAS,MAAM,EAAG,QAAO,cAAc,0DAAkC,IAAI,MAAM,wEAAwE,OAAO,aAAa,KAAK,GAAG;AAC9M,YAAM,UAAU;AAChB,YAAM,UAAU,WAAW,KAAK,SAAS,GAAG,MAAM,IAAI,MAAM;AAC5D,YAAM,UAAU,gBAAgB;AAChC,YAAM,cAAc,MAAM,YAAY,iBAAiBA,KAAI,CAAC;AAC5D,UAAI,CAAC,YAAY,QAAS,QAAO,cAAc,gDAA6B,uBAAuB,OAAO,aAAa,KAAK,iBAAiB;AAC7I,YAAM,OAAO,YAAY;AACzB,yBAAmB,KAAK,EAAE,OAAO,MAAM;AAAA,QACrC,WAAW,KAAK;AAAA,QAChB,MAAM,KAAK;AAAA,QACX,aAAa,KAAK;AAAA,QAClB,MAAAA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,EAAC,CAAC;AAAA,IACJ;AAAA,EACF;AACA,QAAM,iBAAiD,mBAAmB,OAAO,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM;AACzG,QAAI,CAAC,IAAI,KAAK,EAAG,KAAI,KAAK,IAAI,CAAC;AAC/B,QAAI,KAAK,EAAE,KAAK,IAAI;AACpB,WAAO;AAAA,EACT,GAAG,CAAC,CAAmC;AAEvC,MAAI,OAAO,UAAU;AACrB,SAAO,aAAa;AACtB;AAQO,SAAS,qBAA0F,UAAa;AACrH,SAAO,OAAO,KAAc,QAA+C;AACzE,UAAM,kBAAkB;AAAA,MACtB,MAAM;AAAA,QACJ,SAAS,YAAY,SACjB,KAAK,MAAM,IAAI,KAAK,KAAe,IACnC,IAAI;AAAA,MACV;AAAA,MACA,OAAO,kBAAkB,IAAI,KAAK;AAAA,MAClC,QAAQ,kBAAkB,IAAI,MAAM;AAAA,MACpC,OAAO,IAAI,OAAO,WAAW,CAAC;AAAA,MAC9B,SAAS,kBAAkB,IAAI,OAAO;AAAA,MACtC,SAAS,kBAAkB,IAAI,OAAO;AAAA,MACtC,aAAa,kBAAkB,IAAI,WAAW;AAAA,MAC9C,IAAI,IAAI,MAAM;AAAA,MACd,mBAAmB;AAAA,MACnB,oBAAoB;AAAA,MACpB,MAAM;AAAA,MACN,WAAW,IAAIC,YAA0C,IAAI,OAAO,GAAGA,OAAM;AAAA,MAC7E,WAAW,IAAIA,YAA6C,IAAI,UAAU,GAAGA,OAAM;AAAA,MACnF,YAAY;AAAA,MACZ,YAAY;AAAA,IACd;AACA,UAAM,EAAE,YAAAC,cAAY,WAAAC,YAAU,IAAI;AAClC,UAAM,mBAAmB,MAAMD,aAAW,eAAe;AACzD,QAAI,iBAAiB,SAAS,QAAS,QAAO;AAC9C,UAAM,EAAE,MAAM,QAAQ,MAAM,IAAK,iBAAiB;AAClD,UAAM,iBAAiB;AAAA,MACrB,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,kBAAkB,MAAMC,YAAU,cAAc;AACtD,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,4BAA6B,KAAgE;AACjH,QAAM,EAAE,mBAAmB,mBAAmB,IAAI,IAAI;AACtD,MAAI,sBAAsB,OAAW,QAAO,cAAc,4DAAmC,yBAAyB;AACtH,MAAI,uBAAuB,OAAW,QAAO,cAAc,4DAAmC,2BAA2B;AACzH,QAAM,gBAAgB,MAAM,iBAAiB,mBAAmB,kBAAkB;AAClF,MAAI,CAAC,cAAc,QAAS,QAAO,cAAc,4DAAmC,cAAc,MAAM,OAAO;AAC/G,SAAO,aAAa,KAAK,EAAE,mBAAmB,mBAAmB,CAAC;AACpE;AAEO,SAAS,uBAA8F,UAAa;AACzH,SAAO,OAAO,KAAc,QAA+C;AACzE,UAAM,uBAAuB,MAAM,4BAA4B,GAAG;AAClE,QAAI,qBAAqB,SAAS,QAAS,QAAO;AAClD,QAAI,EAAE,mBAAmB,mBAAmB,IAAI,qBAAqB;AACrE,UAAM,sBAAsB;AAAA,MAC1B,MAAM;AAAA,QACJ,SAAS,YAAY,SACjB,KAAK,MAAM,IAAI,KAAK,KAAe,IACnC,IAAI;AAAA,MACV;AAAA,MACA,OAAO,kBAAkB,IAAI,KAAK;AAAA,MAClC,QAAQ,kBAAkB,IAAI,MAAM;AAAA,MACpC,OAAO,IAAI,OAAO,WAAW,CAAC;AAAA,MAC9B,SAAS,kBAAkB,IAAI,OAAO;AAAA,MACtC,SAAS,kBAAkB,IAAI,OAAO;AAAA,MACtC,aAAa,kBAAkB,IAAI,WAAW;AAAA,MAC9C,IAAI,IAAI,MAAM;AAAA,MACd;AAAA,MACA,oBAAoB,kBAAkB,kBAAkB;AAAA,MACxD,MAAM;AAAA,MACN,WAAW,IAAIF,YAA0C,IAAI,OAAO,GAAGA,OAAM;AAAA,MAC7E,WAAW,IAAIA,YAA6C,IAAI,UAAU,GAAGA,OAAM;AAAA,MACnF,YAAY;AAAA,MACZ,YAAY;AAAA,IACd;AACA,UAAM,EAAE,gBAAAG,kBAAgB,YAAAF,cAAY,WAAAC,YAAU,IAAI;AAClD,UAAM,uBAAuB,MAAMC,iBAAe,mBAAmB;AACrE,QAAI,qBAAqB,SAAS,QAAS,QAAO;AAClD,wBAAoB,qBAAqB,QAAQ;AACjD,yBAAqB,qBAAqB,QAAQ;AAClD,UAAM,kBAAkB;AAAA,MACtB,GAAG;AAAA,MACH;AAAA,MACA;AAAA,IACF;AACA,UAAM,mBAAmB,MAAMF,aAAW,eAAe;AACzD,QAAI,iBAAiB,SAAS,QAAS,QAAO;AAC9C,UAAM,EAAE,MAAM,QAAQ,MAAM,IAAI,iBAAiB;AACjD,UAAM,iBAAiB;AAAA,MACrB,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,kBAAkB,MAAMC,YAAU,cAAc;AACtD,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,8BAA+B,KAAkE;AACrH,QAAM,EAAE,mBAAmB,mBAAmB,IAAI,IAAI;AACtD,MAAI,sBAAsB,OAAW,QAAO,cAAc,4DAAmC,yBAAyB;AACtH,MAAI,uBAAuB,OAAW,QAAO,cAAc,4DAAmC,2BAA2B;AACzH,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,oBAAoB,MAAM,QAAQ,IAAI;AAAA,IAC1C,iBAAiB,mBAAmB,kBAAkB;AAAA,IACtD,UAAU,MAAM;AAAA,EAClB,CAAU;AACV,QAAM,CAAC,cAAc,WAAW,IAAI;AACpC,MAAI,CAAC,aAAa,QAAS,QAAO,cAAc,4DAAmC,aAAa,MAAM,OAAO;AAC7G,MAAI,CAAC,YAAY,QAAS,QAAO,cAAc,sDAAgC,YAAY,MAAM,OAAO;AACxG,QAAM,OAAO,YAAY;AACzB,SAAO,aAAa,KAAK;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AACH;AAEO,SAAS,yBAAkG,UAAa;AAC7H,SAAO,OAAO,KAAc,QAA+C;AACzE,UAAM,uBAAuB,MAAM,8BAA8B,GAAG;AACpE,QAAI,qBAAqB,SAAS,QAAS,QAAO;AAClD,QAAI,EAAE,MAAM,mBAAmB,mBAAmB,IAAI,qBAAqB;AAC3E,UAAM,sBAAsB;AAAA,MAC1B,MAAM;AAAA,QACJ,SAAS,YAAY,SACjB,KAAK,MAAM,IAAI,KAAK,KAAe,IACnC,IAAI;AAAA,MACV;AAAA,MACA,QAAQ,kBAAkB,IAAI,MAAM;AAAA,MACpC,OAAO,kBAAkB,IAAI,KAAK;AAAA,MAClC,OAAO,IAAI,OAAO,WAAW,CAAC;AAAA,MAC9B,SAAS,kBAAkB,IAAI,OAAO;AAAA,MACtC,SAAS,kBAAkB,IAAI,OAAO;AAAA,MACtC,aAAa,kBAAkB,IAAI,WAAW;AAAA,MAC9C,IAAI,IAAI,MAAM;AAAA,MACd;AAAA,MACA,oBAAoB,kBAAkB,kBAAkB;AAAA,MACxD;AAAA,MACA,WAAW,IAAIF,YAA0C,IAAI,OAAO,GAAGA,OAAM;AAAA,MAC7E,WAAW,IAAIA,YAA6C,IAAI,UAAU,GAAGA,OAAM;AAAA,MACnF,YAAY;AAAA,MACZ,YAAY;AAAA,IACd;AACA,UAAM,EAAE,gBAAAG,kBAAgB,YAAAF,cAAY,WAAAC,YAAU,IAAI;AAClD,UAAM,uBAAuB,MAAMC,iBAAe,mBAAmB;AACrE,QAAI,qBAAqB,SAAS,QAAS,QAAO;AAClD,wBAAoB,qBAAqB,QAAQ;AACjD,yBAAqB,qBAAqB,QAAQ;AAClD,UAAM,kBAAkB;AAAA,MACtB,GAAG;AAAA,MACH;AAAA,MACA;AAAA,IACF;AACA,UAAM,mBAAmB,MAAMF,aAAW,eAAe;AACzD,QAAI,iBAAiB,SAAS,QAAS,QAAO;AAC9C,UAAM,EAAE,MAAM,QAAQ,MAAM,IAAI,iBAAiB;AACjD,UAAM,iBAAiB;AAAA,MACrB,GAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,kBAAkB,MAAMC,YAAU,cAAc;AACtD,WAAO;AAAA,EACT;AACF;AAEO,SAAS,WAAYE,SAAyF;AACnH,QAAM,gBAAgB,OAAO;AAC7B,SAAO,QAAQA,OAAM,EAAE,QAAQ,CAAC,CAAC,cAAc,SAAS,MAAM;AAC5D,mBAAe;AACf,UAAM,WAAW;AACjB,UAAM,SAAS,iBAAiB,YAAY;AAC5C,UAAML,QAAO,eAAe,YAAY;AACxC,UAAM,mBAAmB,OAAO,YAAY;AAC5C,QAAI,qBAAqB,SACpB,qBAAqB,UACrB,qBAAqB,SACrB,qBAAqB,SACxB,OAAM,IAAI,MAAM,0BAA0B,YAAY,EAAE;AAC1D,kBAAc,gBAAgB,EAAEA,OAAM,OAAO,KAAK,QAAQ;AApmB9D;AAqmBM,UAAI;AACF,cAAM;AAAA,UACJ;AAAA,UACA,qBAAqB;AAAA,UACrB;AAAA,QACF,IAAI;AACJ,YAAI,uBAAuB,SACtB,cAAc,UACd,qBAAqB,OAAO;AAC/B,gBAAM,wBAAwB,OAAgB,GAAG;AACjD,cAAI,CAAC,sBAAsB,SAAS;AAClC,kBAAMM,YAAW,cAAc,oDAA+B,sBAAsB,KAAK;AACzF,oCAAwB,KAAKA,SAAQ;AACrC;AAAA,UACF;AAAA,QACF;AACA,YAAI,YAAY,QAAW;AACzB,gBAAM,gBAAgB,MAAM;AAAA,YAC1B;AAAA,YACA;AAAA,YACA,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,QAAQ;AAAA,YACR,QAAQ;AAAA,UACV;AACA,cAAI,cAAc,SAAS,SAAS;AAClC,oCAAwB,KAAK,aAAa;AAC1C;AAAA,UACF;AAAA,QACF;AACA,YAAI;AACJ,YAAI,SAAS,cAAc,QAAQ;AAAE,qBAAW,MAAM,qBAAqB,QAAQ,EAAE,KAAK,GAAG;AAAA,QAAE,WACtF,SAAS,cAAc,QAAQ;AAAE,qBAAW,MAAM,uBAAuB,QAAQ,EAAE,KAAK,GAAG;AAAA,QAAE,WAC7F,SAAS,cAAc,UAAU;AAAE,qBAAW,MAAM,yBAAyB,QAAQ,EAAE,KAAK,GAAG;AAAA,QAAE,MACrG,OAAM,EAAE,SAAS,qBAAqB,SAAS;AACpD,YAAI,SAAS,SAAS,QAAS,yBAAwB,KAAK,QAAQ;AAAA,iBAC3D,SAAS,SAAS,OAAQ,wBAAuB,KAAK,QAAQ;AAAA,iBAC9D,SAAS,SAAS,OAAQ,wBAAuB,KAAK,QAAQ;AAAA,iBAC9D,SAAS,SAAS,OAAQ,wBAAuB,KAAK,QAAQ;AAAA,iBAC9D,SAAS,SAAS,OAAQ,wBAAuB,GAAG;AAAA,YACxD,OAAM,EAAE,SAAS,wDAAwD,SAAS;AAAA,MACzF,SAAS,KAAK;AACZ,4DAAuC,qCAAqC;AAAA,UAC1E;AAAA,UACA;AAAA,UACA,MAAAN;AAAA,UACA,SAAQ,SAAI,OAAO,uBAAX,mBAA+B;AAAA,UACvC,aAAa,IAAI;AAAA,UACjB,MAAM,IAAI;AAAA,UACV,QAAQ,IAAI;AAAA,UACZ,OAAO,IAAI;AAAA,UACX,OAAO,IAAI;AAAA,QACb,CAAC;AACD,gCAAwB,KAAK;AAAA,UAC3B;AAAA;AAAA,UAEA;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AACD,SAAO;AACT;AAQO,IAAM,mBAAmB,CAAC,aAAqB;AACpD,QAAM,SAAS,SAAS,MAAM,GAAG,SAAS,QAAQ,GAAG,CAAC;AACtD,SAAO;AACT;AAEO,IAAM,iBAAiB,CAAC,aAAqB;AAClD,QAAMA,QAAO,SAAS,MAAM,SAAS,QAAQ,GAAG,IAAI,CAAC;AACrD,SAAOA;AACT;AAEO,IAAM,uBAAuB,CAAC,GAAY,QAAkB;AACjE,0BAAwB,KAAK;AAAA,IAC3B;AAAA;AAAA,IAEA;AAAA,EACF,CAAC;AACH;AAEO,IAAM,qBAAqB,CAChC,KACA,MACA,KACA,UACG;AACH;AAAA;AAAA,IAEE;AAAA,IACA,EAAE,IAAI;AAAA,EACR;AACA,0BAAwB,KAAK;AAAA,IAC3B;AAAA;AAAA,IAEA;AAAA,EACF,CAAC;AACH;;;AsBtsBO,IAAM,uBAA6C,YAAY,aAAa,KAAK;AAAA,EACtF,MAAM,CAAC;AAAA,EACP,QAAQ,CAAC;AAAA,EACT,OAAO,CAAC;AACV,CAAC;AAEM,IAAM,yBAAiD,YAAY,aAAa,KAAK;AAAA,EAC1F,MAAM,CAAC;AAAA,EACP,QAAQ,CAAC;AAAA,EACT,OAAO,CAAC;AACV,CAAC;AAEM,IAAM,2BAAqD,YAAY,aAAa,KAAK;AAAA,EAC9F,MAAM,CAAC;AAAA,EACP,QAAQ,CAAC;AAAA,EACT,OAAO,CAAC;AACV,CAAC;;;ACnBM,IAAM,iBAAkE,MAAM;AAAA,EACnF,OAAO,oBAAe;AAAA,EACtB,UAAU,sBAAkB;AAAA,EAC5B,QAAQ,kDAA+B;AAAA,EACvC,UAAU;AACZ,CAAC;;;ACLM,IAAM,YAAwD,YAAY;AAC/E,QAAM,MAAM;AACZ,SAAO,aAAa;AACtB;;;ACFO,IAAMO,SAAuC;AAAA,EAClD,WAAW;AAAA,EACX,SAAS;AAAA,EACT;AAAA,EACA,YAAY;AAAA,EACZ;AACF;;;ACTO,IAAM,OAAO;AAAA,EAClB,OAAAC;AACF;;;ACAO,IAAMC,kBAAoE,MAAM;AAAA,EACrF,OAAO,oBAAe;AAAA,EACtB,UAAU,sBAAkB;AAAA,EAC5B,QAAQ,sDAAiC;AAAA,EACzC,UAAU;AACZ,CAAC;;;ACTD,OAAO,YAAY;;;ACMZ,IAAM,gBAA+B,UAAQ;AAClD,SAAO;AAAA,IACL,KAAK,KAAK,IAAI,SAAS;AAAA,IACvB,UAAU,KAAK;AAAA,IACf,MAAM,KAAK;AAAA,IACX,QAAQ,KAAK;AAAA,IACb,QAAQ,KAAK;AAAA,EACf;AACF;AAEO,IAAM,iBAAiC,UAAQ;AACpD,QAAM,OAAO,cAAc,IAAI;AAC/B,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAO,KAAK;AAAA,IACZ,UAAU,KAAK;AAAA,EACjB;AACF;AAEO,IAAM,kBAAmC,UAAQ;AACtD,QAAM,OAAO,cAAc,IAAI;AAC/B,SAAO;AAAA,IACL,GAAG;AAAA,IACH,UAAU,KAAK;AAAA,IACf,UAAU,KAAK;AAAA,EACjB;AACF;;;ADxBO,IAAM,kBAAgE,OAAO,EAAE,MAAM,oBAAoB,EAAE,OAAO,EAAE,MAAM;AAC/H,MAAI,cAAc,MAAM;AACtB,UAAMC,oBAAmB,MAAM,UAAuB,iBAAiB;AAAA,MACrE,UAAU,KAAK;AAAA,MACf,UAAU,KAAK;AAAA,MACf,MAAM,KAAK;AAAA,MACX,QAAQ,KAAK;AAAA,MACb,QAAQ,KAAK;AAAA,MACb,UAAU,KAAK;AAAA,IACjB,GAAG,EAAE,aAAa,OAAO,CAAC;AAC1B,QAAIA,kBAAiB,QAAS,QAAO,aAAa,KAAK,gBAAgBA,kBAAiB,OAAO,CAAC;AAChG,UAAM,EAAE,MAAAC,OAAM,SAAAC,SAAQ,IAAIF,kBAAiB;AAC3C,WAAO,cAAc,KAAKC,OAAMC,QAAO;AAAA,EACzC;AACA,QAAM,mBAAmB,MAAM,UAAsB,gBAAgB;AAAA,IACnE,UAAU,KAAK;AAAA,IACf,OAAO,KAAK;AAAA,IACZ,WAAW,MAAM,OAAO,KAAK,KAAK,UAAU,EAAE;AAAA,IAC9C,MAAM,KAAK;AAAA,IACX,QAAQ,KAAK;AAAA,IACb,QAAQ,KAAK;AAAA,IACb,UAAU,KAAK;AAAA,EACjB,GAAG,EAAE,aAAa,OAAO,CAAC;AAC1B,MAAI,iBAAiB,QAAS,QAAO,aAAa,KAAK,eAAe,iBAAiB,OAAO,CAAC;AAC/F,QAAM,EAAE,MAAM,QAAQ,IAAI,iBAAiB;AAC3C,SAAO,cAAc,KAAK,MAAM,OAAO;AACzC;AAEO,IAAMC,aAA0D,OAAM,UAAS;AACpF,QAAM,SAAS,MAAM,gBAAgB,KAAK;AAC1C,SAAO;AACT;;;AEvCA,SAAS,mBAAAC,wBAAuB;AAChC,OAAO,SAAS;AAMT,IAAM,aAA4D,OAAO,EAAE,KAAK,MAAM;AAC3F,QAAM,uBAAuB,IAAI,OAAO;AAAA,IACtC,UAAU,IAAI,OAAO,EAAE,IAAI,CAAC;AAAA,IAC5B,MAAM,IAAI,WAAW,QAAQ;AAAA,IAC7B,QAAQ,IAAI,WAAW,UAAU;AAAA,IACjC,QAAQ,IAAI,MAAM,IAAI,WAAW,SAAS,CAAC;AAAA,EAC7C,CAAC;AACD,QAAM,gCAAgC,IAAI,OAAO;AAAA,IAC/C,OAAO,IAAI,OAAO,EAAE,MAAM;AAAA,IAC1B,UAAU,IAAI,QAAQ;AAAA,IACtB,UAAU,IAAI,OAAO,EAAE,IAAI,CAAC;AAAA,EAC9B,CAAC;AACD,QAAM,2BAA2B,IAAI,OAAO;AAAA,IAC1C,UAAU,IAAI,OAAO,EAAE,IAAI,CAAC;AAAA,IAC5B,UAAU,IAAI,QAAQ,IAAI;AAAA,EAC5B,CAAC;AACD,QAAM,gBAAgB,IAAI,MAAM;AAAA,IAC9B,qBAAqB,MAAM,6BAA6B;AAAA,IACxD,qBAAqB,MAAM,wBAAwB;AAAA,EACrD,CAAC;AACD,MAAI;AACF,UAAM,YAAY,cAAc,MAAM,IAAI;AAC1C,WAAO,aAAa,KAAK;AAAA,MACvB,MAAM;AAAA,MACN,OAAO,CAAC;AAAA,MACR,QAAQ,CAAC;AAAA,IACX,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,SAASC,iBAAgB,GAAG;AAClC,WAAO,cAAc,wDAAiC,MAAM,MAAM;AAAA,EACpE;AACF;;;ACjCO,IAAM,SAA0C;AAAA,EACrD,WAAW;AAAA,EACX,SAAS;AAAA,EACT,gBAAAC;AAAA,EACA;AAAA,EACA,WAAAC;AACF;;;ACPO,IAAMC,kBAAoE,MAAM;AAAA,EACrF,OAAO,oBAAe;AAAA,EACtB,UAAU,sBAAkB;AAAA,EAC5B,QAAQ,sDAAiC;AAAA,EACzC,UAAU;AACZ,CAAC;;;ACDM,IAAMC,mBAAgE,OAAO,EAAE,MAAM,oBAAoB,EAAE,OAAO,EAAE,MAAM;AAC/H,QAAM,EAAE,IAAI,IAAI;AAChB,QAAM,UAAU,MAAM,UAAqB,eAAe,EAAE,IAAI,GAAG,EAAE,aAAa,OAAO,CAAC;AAC1F,MAAI,CAAC,QAAQ,SAAS;AACpB,UAAM,EAAE,MAAM,QAAQ,IAAI,QAAQ;AAClC,WAAO,cAAc,KAAK,MAAM,OAAO;AAAA,EACzC;AACA,QAAM,gBAAgB,iBAAiB,QAAQ,OAAO;AACtD,MAAI,kBAAkB,KAAM,QAAO,cAAc,0EAA0C,cAAc,WAAW,EAAE,IAAI,CAAC;AAC3H,MAAI,cAAc,aAAa,aAAc,QAAO,aAAa,KAAK,gBAAgB,aAAa,CAAC;AACpG,SAAO,aAAa,KAAK,eAAe,aAAa,CAAC;AACxD;AAEO,IAAMC,aAA0D,OAAM,UAAS;AACpF,QAAM,SAAS,MAAMD,iBAAgB,KAAK;AAC1C,SAAO;AACT;;;ACxBA,SAAS,mBAAAE,yBAAuB;AAChC,OAAOC,UAAS;AAKT,IAAMC,cAA4D,OAAO,EAAE,KAAK,MAAM;AAC3F,QAAM,gBAAgBC,KAAI,OAAO,EAAE,KAAKA,KAAI,OAAO,EAAE,CAAC;AACtD,MAAI;AACF,UAAM,YAAY,cAAc,MAAM,IAAI;AAC1C,WAAO,aAAa,KAAK;AAAA,MACvB,MAAM;AAAA,MACN,OAAO,CAAC;AAAA,MACR,QAAQ,CAAC;AAAA,IACX,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,SAASC,kBAAgB,GAAG;AAClC,WAAO,cAAc,wDAAiC,MAAM,MAAM;AAAA,EACpE;AACF;;;ACdO,IAAM,aAA8C;AAAA,EACzD,WAAW;AAAA,EACX,SAAS;AAAA,EACT,gBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AACF;;;ACPO,IAAMC,kBAAiE,MAAM;AAAA,EAClF,OAAO,oBAAe;AAAA,EACtB,UAAU,sBAAkB;AAAA,EAC5B,QAAQ,gDAA8B;AAAA,EACtC,UAAU;AACZ,CAAC;;;ACDM,IAAMC,mBAA6D,OAAO,EAAE,MAAM,oBAAoB,EAAE,OAAO,EAAE,MAAM;AAE5H,MAAI,SAAS,QAAQ,cAAc,MAAM;AACvC,UAAM,EAAE,KAAK,SAAS,IAAI;AAC1B,UAAM,SAAS,EAAE,KAAK,SAAS;AAC/B,UAAM,SAAS,MAAM,QAAmB,eAAe,QAAQ,EAAE,aAAa,OAAO,CAAC;AACtF,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,EAAE,KAAK,IAAI,OAAO;AACxB,UAAI,6EAA8C,QAAO,cAAc,KAAK,MAAM,cAAc,WAAW,MAAM;AACjH,aAAO,cAAc,KAAK,MAAM,kCAAkC;AAAA,IACpE;AACA,UAAM,gBAAgB,iBAAiB,OAAO,OAAO;AACrD,QAAI,kBAAkB,KAAM,QAAO,cAAc,0EAA0C,cAAc,WAAW,MAAM;AAC1H,QAAI,cAAc,aAAa,YAAa,QAAO,aAAa,KAAK,eAAe,aAAa,CAAC;AAClG,WAAO,aAAa,KAAK,gBAAgB,aAAa,CAAC;AAAA,EAGzD,WAAW,WAAW,MAAM;AAC1B,UAAM,SAAS,EAAE,OAAO,KAAK,MAAM;AACnC,UAAM,SAAS,MAAM,QAAoB,gBAAgB,QAAQ,EAAE,aAAa,OAAO,CAAC;AACxF,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,EAAE,KAAK,IAAI,OAAO;AACxB,UAAI,6EAA8C,QAAO,cAAc,KAAK,MAAM,eAAe,WAAW,MAAM;AAClH,aAAO,cAAc,KAAK,MAAM,kCAAkC;AAAA,IACpE;AACA,WAAO,aAAa,KAAK,eAAe,OAAO,OAAO,CAAC;AAAA,EAGzD,OAAO;AACL,UAAM,SAAS,EAAE,UAAU,KAAK,SAAS;AACzC,UAAM,SAAS,MAAM,QAAqB,iBAAiB,QAAQ,EAAE,aAAa,OAAO,CAAC;AAC1F,QAAI,CAAC,OAAO,SAAS;AACnB,YAAM,EAAE,KAAK,IAAI,OAAO;AACxB,UAAI,6EAA8C,QAAO,cAAc,KAAK,MAAM,gBAAgB,WAAW,MAAM;AACnH,aAAO,cAAc,KAAK,MAAM,kCAAkC;AAAA,IACpE;AACA,WAAO,aAAa,KAAK,gBAAgB,OAAO,OAAO,CAAC;AAAA,EAC1D;AACF;AAEO,IAAMC,aAAuD,OAAM,UAAS;AACjF,QAAM,SAAS,MAAMD,iBAAgB,KAAK;AAC1C,SAAO;AACT;;;ACnDA,SAAS,mBAAAE,yBAAuB;AAChC,OAAOC,UAAS;AAKT,IAAMC,cAAyD,OAAO,EAAE,KAAK,MAAM;AACxF,QAAM,gBAAgBC,KAAI,MAAM;AAAA,IAC9BA,KAAI,OAAO,EAAE,KAAKA,KAAI,OAAO,EAAE,CAAC;AAAA,IAChCA,KAAI,OAAO,EAAE,UAAUA,KAAI,OAAO,EAAE,CAAC;AAAA,IACrCA,KAAI,OAAO,EAAE,OAAOA,KAAI,OAAO,EAAE,CAAC;AAAA,IAClCA,KAAI,OAAO,EAAE,UAAUA,KAAI,OAAO,EAAE,CAAC;AAAA,EACvC,CAAC;AACD,MAAI;AACF,UAAM,YAAY,cAAc,MAAM,IAAI;AAC1C,WAAO,aAAa,KAAK;AAAA,MACvB,MAAM;AAAA,MACN,OAAO,CAAC;AAAA,MACR,QAAQ,CAAC;AAAA,IACX,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,SAASC,kBAAgB,GAAG;AAClC,WAAO,cAAc,wDAAiC,MAAM,MAAM;AAAA,EACpE;AACF;;;ACnBO,IAAM,MAAoC;AAAA,EAC/C,WAAW;AAAA,EACX,SAAS;AAAA,EACT,gBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AACF;;;ACPO,IAAMC,kBAA4E,MAAM;AAAA,EAC7F,OAAO,oBAAe;AAAA,EACtB,UAAU,sBAAkB;AAAA,EAC5B,QAAQ,0EAA2C;AAAA,EACnD,UAAU;AACZ,CAAC;;;ACPM,IAAM,uBAA6C,WAAS;AACjE,SAAO;AAAA,IACL,QAAQ,MAAM,OAAO,SAAS;AAAA,IAC9B,sBAAsB,MAAM;AAAA,IAC5B,wBAAwB,MAAM;AAAA,IAC9B,sBAAsB,MAAM;AAAA,EAC9B;AACF;;;ACFO,IAAMC,aAAkE,OAAO,EAAE,MAAM,oBAAoB,EAAE,QAAQ,YAAY,EAAE,MAAM;AAC9I,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA,EAAE,OAAO;AAAA,IACT,EAAE,aAAa,YAAY;AAAA,EAC7B;AACA,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,EAAE,MAAM,QAAQ,IAAI,OAAO;AACjC,WAAO,cAAc,KAAK,MAAM,OAAO;AAAA,EACzC;AACA,SAAO,aAAa,KAAK,qBAAqB,OAAO,OAAO,CAAC;AAC/D;;;ACnBA,SAAS,mBAAAC,yBAAuB;AAChC,OAAOC,UAAS;AAKT,IAAMC,cAAoE,OAAO,EAAE,KAAK,MAAM;AACnG,QAAM,gBAAgBC,KAAI,OAAO,EAAE,QAAQA,KAAI,OAAO,EAAE,CAAC;AACzD,MAAI;AACF,UAAM,YAAY,cAAc,MAAM,IAAI;AAC1C,WAAO,aAAa,KAAK;AAAA,MACvB,MAAM;AAAA,MACN,OAAO,CAAC;AAAA,MACR,QAAQ,CAAC;AAAA,IACX,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,SAASC,kBAAgB,GAAG;AAClC,WAAO,cAAc,wDAAiC,MAAM,MAAM;AAAA,EACpE;AACF;;;ACdO,IAAM,iBAA0D;AAAA,EACrE,WAAW;AAAA,EACX,SAAS;AAAA,EACT,gBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AACF;;;ACPO,IAAMC,kBAAkE,MAAM;AAAA,EACnF,OAAO,oBAAe;AAAA,EACtB,UAAU,sBAAkB;AAAA,EAC5B,QAAQ,kDAA+B;AAAA,EACvC,UAAU;AACZ,CAAC;;;ACTD,SAAS,WAAW;AAUpB,IAAM,QAAQ;AAEP,IAAMC,mBAA8D,OAAO,EAAE,MAAM,OAAO,oBAAoB,EAAE,OAAO,GAAG,YAAY,MAAM;AACjJ,QAAM,EAAE,MAAM,aAAa,IAAI,IAAI;AACnC,QAAM,aAAa,SAAS,UAAU;AACtC,QAAM,OAAO,OAAO,MAAM,UAAU,IAAI,IAAI;AAC5C,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAGJ,QAAM,iBAAiB,aAAa,SAAY,SAAY;AAC5D,QAAM,iBAAiB,qBAAqB,SAAY,SAAY,EAAE,QAAQ,kBAAkB,UAAU,IAAI;AAC9G,QAAM,aAAa,eAAe,SAAY,SAAY,EAAE,KAAK,WAAW;AAC5E,QAAM,eAAe,iBAAiB,SAAY,SAAY,EAAE,KAAK,aAAa;AAClF,QAAM,eAAe,iBAAiB,SAAY,SAAY,EAAE,MAAM,aAAa;AACnF,QAAM,cAAc,kBAAkB,SAAY,SAAY,EAAE,QAAQ,eAAe,UAAU,IAAI;AACrG,QAAM,iBAAiB,qBAAqB,SAAY,SAAY,EAAE,QAAQ,kBAAkB,UAAU,IAAI;AAC9G,QAAM,mBAAmB,0BAA0B,UAAa,2BAA2B;AAC3F,QAAM,qBAAqB,0BAA0B,SAAY,EAAE,MAAM,IAAI,KAAK,qBAAqB,EAAE,IAAI,CAAC;AAC9G,QAAM,sBAAsB,2BAA2B,SAAY,EAAE,MAAM,IAAI,KAAK,sBAAsB,EAAE,IAAI,CAAC;AACjH,QAAM,aAAa,mBAAmB;AAAA,IACpC,sBAAsB;AAAA,MACpB,GAAG;AAAA,MACH,GAAG;AAAA,IACL;AAAA,EACF,IAAI,CAAC;AAEL,QAAM,kBAAkB,IAAI,IAAI,aAAa,qBAAqB;AAClE,QAAM,kBAAkB,IAAI,IAAI,aAAa,qBAAqB;AAClE,kBAAgB,aAAa,IAAI,SAAS,OAAO,GAAG,SAAS,CAAC;AAC9D,kBAAgB,aAAa,IAAI,SAAS,OAAO,GAAG,SAAS,CAAC;AAC9D,QAAM,cAAc,GAAG,gBAAgB,QAAQ,GAAG,gBAAgB,MAAM;AACxE,QAAM,cAAc,GAAG,gBAAgB,QAAQ,GAAG,gBAAgB,MAAM;AAKxE,MAAI,kBAAkB,QAAW;AAC/B,QAAI,qBAAqB,OAAW,QAAO,cAAc,wDAAiC,MAAM,0CAA0C;AAC1I,UAAM,cAAc,MAAM,SAAqB,gBAAgB;AAAA,MAC7D,UAAU;AAAA,MACV,UAAU;AAAA,MACV,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,GAAG;AAAA,IACL,GAAG,EAAE,aAAa,OAAO,GAAG;AAAA,MAC1B,OAAO;AAAA,MACP,MAAM,OAAO;AAAA,IACf,CAAC;AACD,QAAI,CAAC,YAAY,SAAS;AACxB,YAAM,EAAE,MAAM,QAAQ,IAAI,YAAY;AACtC,UAAI,6EAA8C,QAAO,aAAa,KAAK,CAAC,GAAG,GAAG,GAAG,MAAM,IAAI;AAC/F,aAAO,cAAc,KAAK,MAAM,OAAO;AAAA,IACzC;AACA,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,YAAY;AAChB,UAAM,WAAW,MAAM,IAAI,cAAc;AACzC,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,OAAO,cAAc;AAAA,MAC9B,SAAS,OAAO,cAAc;AAAA,IAChC;AAAA,EAKF,WAAW,qBAAqB,QAAW;AACzC,QAAI,kBAAkB,OAAW,QAAO,cAAc,wDAAiC,MAAM,0CAA0C;AACvI,UAAM,cAAc,MAAM,SAAsB,iBAAiB;AAAA,MAC/D,UAAU;AAAA,MACV,UAAU;AAAA,MACV,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,GAAG;AAAA,IACL,GAAG,EAAE,aAAa,OAAO,GAAG;AAAA,MAC1B,OAAO;AAAA,MACP,MAAM,OAAO;AAAA,IACf,CAAC;AACD,QAAI,CAAC,YAAY,SAAS;AACxB,YAAM,EAAE,MAAM,QAAQ,IAAI,YAAY;AACtC,UAAI,6EAA8C,QAAO,aAAa,KAAK,CAAC,GAAG,GAAG,GAAG,MAAM,IAAI;AAC/F,aAAO,cAAc,KAAK,MAAM,OAAO;AAAA,IACzC;AACA,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,YAAY;AAChB,UAAM,WAAW,MAAM,IAAI,eAAe;AAC1C,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,OAAO,cAAc;AAAA,MAC9B,SAAS,OAAO,cAAc;AAAA,IAChC;AAAA,EAKF,OAAO;AACL,UAAM,cAAc,MAAM,SAAoB,eAAe;AAAA,MAC3D,UAAU;AAAA,MACV,UAAU;AAAA,MACV,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,GAAG;AAAA,IACL,GAAG,EAAE,aAAa,OAAO,GAAG;AAAA,MAC1B,OAAO;AAAA,MACP,MAAM,OAAO;AAAA,IACf,CAAC;AACD,QAAI,CAAC,YAAY,SAAS;AACxB,YAAM,EAAE,MAAM,QAAQ,IAAI,YAAY;AACtC,UAAI,6EAA8C,QAAO,aAAa,KAAK,CAAC,GAAG,GAAG,GAAG,MAAM,IAAI;AAC/F,aAAO,cAAc,KAAK,MAAM,OAAO;AAAA,IACzC;AACA,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,YAAY;AAChB,UAAM,WAAW,MAAM,IAAI,cAAY;AACrC,YAAM,gBAAgB,iBAAiB,QAAQ;AAC/C,UAAI,kBAAkB,KAAM,QAAO;AACnC,UAAI,cAAc,aAAa,YAAa,QAAO,eAAe,aAAa;AAC/E,aAAO,gBAAgB,aAAa;AAAA,IACtC,CAAC,EAAE,OAAO,CAAC,SAA+C,SAAS,IAAI;AACvE,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS,OAAO,cAAc;AAAA,MAC9B,SAAS,OAAO,cAAc;AAAA,IAChC;AAAA,EACF;AACF;AAEO,IAAMC,aAAoC,OAAM,UAAS;AAC9D,QAAM,SAAS,MAAMD,iBAAgB,KAAK;AAC1C,SAAO;AACT;;;AC/KA,SAAS,mBAAAE,yBAAuB;AAChC,OAAOC,UAAS;AAOT,IAAMC,cAA0D,OAAO,EAAE,MAAM,MAAM,MAAM;AAChG,QAAM,gBAAgBC,KAAI,OAAO;AAAA,IAC/B,UAAUA,KAAI,QAAQ,EAAE,SAAS;AAAA,IACjC,kBAAkBA,KAAI,OAAO,EAAE,SAAS;AAAA,IACxC,YAAYA,KAAI,MAAMA,KAAI,WAAW,QAAQ,CAAC,EAAE,SAAS;AAAA,IACzD,cAAcA,KAAI,MAAMA,KAAI,WAAW,UAAU,CAAC,EAAE,SAAS;AAAA,IAC7D,cAAcA,KAAI,MAAMA,KAAI,WAAW,SAAS,CAAC,EAAE,SAAS;AAAA,IAC5D,eAAeA,KAAI,OAAO,EAAE,SAAS;AAAA,IACrC,kBAAkBA,KAAI,OAAO,EAAE,SAAS;AAAA,IACxC,uBAAuBA,KAAI,OAAO,EAAE,SAAS;AAAA,IAC7C,wBAAwBA,KAAI,OAAO,EAAE,SAAS;AAAA,EAChD,CAAC;AACD,QAAM,iBAAiBA,KAAI,OAAO,EAAE,MAAMA,KAAI,OAAO,EAAE,SAAS,EAAE,CAAC;AACnE,MAAI;AACJ,MAAI;AACJ,MAAI;AAAE,oBAAgB,cAAc,MAAM,IAAI;AAAA,EAAE,SACzC,KAAK;AAAE,WAAO,cAAc,wDAAiC,MAAMC,kBAAgB,GAAG,CAAC;AAAA,EAAE;AAChG,MAAI;AAAE,qBAAiB,eAAe,MAAM,KAAK;AAAA,EAAE,SAC5C,KAAK;AAAE,WAAO,cAAc,0DAAkC,OAAOA,kBAAgB,GAAG,CAAC;AAAA,EAAE;AAClG,SAAO,aAAa,KAAK;AAAA,IACvB,MAAM;AAAA,IACN,QAAQ,CAAC;AAAA,IACT,OAAO;AAAA,EACT,CAAC;AACH;;;AC3BO,IAAM,OAAsC;AAAA,EACjD,WAAW;AAAA,EACX,SAAS;AAAA,EACT,gBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AACF;;;ACPO,IAAMC,kBAA8E,MAAM;AAAA,EAC/F,OAAO,oBAAe;AAAA,EACtB,UAAU,sBAAkB;AAAA,EAC5B,QAAQ,mFAAkD;AAAA,EAC1D,UAAU;AACZ,CAAC;;;ACFM,IAAMC,aAAoE,OAAO,EAAE,MAAM,oBAAoB,EAAE,QAAQ,YAAY,EAAE,MAAM;AAChJ,QAAM,kBAAkB,MAAM;AAAA,IAC5B;AAAA,IACA,EAAE,QAAQ,KAAK,OAAO;AAAA,IAAG;AAAA,MACvB,sBAAsB,KAAK,wBAAwB;AAAA,MACnD,wBAAwB,KAAK,0BAA0B;AAAA,MACvD,sBAAsB,KAAK,wBAAwB;AAAA,IACrD;AAAA,IAAG,EAAE,aAAa,YAAY;AAAA,EAChC;AACA,MAAI,CAAC,gBAAgB,SAAS;AAC5B,UAAM,EAAE,MAAM,QAAQ,IAAI,gBAAgB;AAC1C,WAAO,cAAc,KAAK,MAAM,OAAO;AAAA,EACzC;AACA,SAAO,aAAa,KAAK,qBAAqB,gBAAgB,OAAO,CAAC;AACxE;;;ACrBA,SAAS,mBAAAC,yBAAuB;AAChC,OAAOC,UAAS;AAKT,IAAMC,cAAsE,OAAO,EAAE,KAAK,MAAM;AACrG,QAAM,gBAAgBC,KAAI,OAAO;AAAA,IAC/B,QAAQA,KAAI,OAAO;AAAA,IACnB,sBAAsBA,KAAI,OAAO,EAAE,SAAS;AAAA,IAC5C,wBAAwBA,KAAI,OAAO,EAAE,SAAS;AAAA,IAC9C,sBAAsBA,KAAI,OAAO,EAAE,SAAS;AAAA,EAC9C,CAAC;AACD,MAAI;AACF,UAAM,YAAY,cAAc,MAAM,IAAI;AAC1C,WAAO,aAAa,KAAK;AAAA,MACvB,MAAM;AAAA,MACN,OAAO,CAAC;AAAA,MACR,QAAQ,CAAC;AAAA,IACX,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,SAASC,kBAAgB,GAAG;AAClC,WAAO,cAAc,wDAAiC,MAAM,MAAM;AAAA,EACpE;AACF;;;ACnBO,IAAM,mBAA8D;AAAA,EACzE,WAAW;AAAA,EACX,SAAS;AAAA,EACT,gBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AACF;;;ACPO,IAAMC,kBAA8E,MAAM;AAAA,EAC/F,OAAO,oBAAe;AAAA,EACtB,UAAU,sBAAkB;AAAA,EAC5B,QAAQ,8EAA6C;AAAA,EACrD,UAAU;AACZ,CAAC;;;ACDM,IAAMC,mBAA0E,OAAO,EAAE,MAAM,oBAAoB,EAAE,OAAO,EAAE,MAAM;AAGzI,QAAM,mBAAmB,MAAM,SAAyB,oBAAoB,EAAE,QAAQ,KAAK,OAAO,GAAG,EAAE,aAAa,OAAO,GAAG,EAAE,OAAO,IAAK,CAAC;AAC7I,MAAI,CAAC,iBAAiB,SAAS;AAC7B,UAAM,EAAE,MAAAC,OAAM,SAAAC,SAAQ,IAAI,iBAAiB;AAC3C,QAAID,8EAA8C,QAAO,aAAa;AACtE,WAAO,cAAc,KAAKA,OAAMC,QAAO;AAAA,EACzC;AACA,QAAM,EAAE,OAAO,WAAW,IAAI,iBAAiB;AAC/C,MAAI,WAAW,WAAW,EAAG,QAAO,aAAa;AAGjD,QAAM,kBAAkB,MAAM,WAA2B,oBAAoB,EAAE,QAAQ,KAAK,OAAO,GAAG,EAAE,aAAa,OAAO,CAAC;AAC7H,MAAI,CAAC,gBAAgB,SAAS;AAC5B,UAAM,EAAE,MAAAD,OAAM,SAAAC,SAAQ,IAAI,gBAAgB;AAC1C,WAAO,cAAc,KAAKD,OAAMC,QAAO;AAAA,EACzC;AAGA,QAAM,qBAAqB,WAAW,IAAI,CAAC,EAAE,OAAO,QAAAC,QAAO,OAAO,EAAE,OAAO,QAAAA,SAAQ,WAAW,oBAAI,KAAK,EAAE,EAAE;AAC3G,QAAM,qBAAqB,MAAM,WAAkC,2BAA2B,oBAAoB,EAAE,aAAa,OAAO,CAAC;AACzI,MAAI,mBAAmB,QAAS,QAAO,aAAa;AACpD,QAAM,EAAE,MAAM,QAAQ,IAAI,mBAAmB;AAC7C,SAAO,cAAc,KAAK,MAAM,OAAO;AACzC;AAEO,IAAMC,aAAoC,OAAM,UAAS;AAC9D,QAAM,SAAS,MAAMJ,iBAAgB,KAAK;AAC1C,SAAO;AACT;;;ACtCA,SAAS,mBAAAK,yBAAuB;AAChC,OAAOC,UAAS;AAKT,IAAMC,cAAsE,OAAO,EAAE,KAAK,MAAM;AACrG,QAAM,gBAAgBC,KAAI,OAAO,EAAE,QAAQA,KAAI,OAAO,EAAE,CAAC;AACzD,MAAI;AACF,UAAM,YAAY,cAAc,MAAM,IAAI;AAC1C,WAAO,aAAa,KAAK;AAAA,MACvB,MAAM;AAAA,MACN,OAAO,CAAC;AAAA,MACR,QAAQ,CAAC;AAAA,IACX,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,SAASC,kBAAgB,GAAG;AAClC,WAAO,cAAc,wDAAiC,MAAM,MAAM;AAAA,EACpE;AACF;;;ACdO,IAAM,mBAA8D;AAAA,EACzE,WAAW;AAAA,EACX,SAAS;AAAA,EACT,gBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AACF;;;ACPO,IAAMC,kBAAyF,MAAM;AAAA,EAC1G,OAAO,oBAAe;AAAA,EACtB,UAAU,sBAAkB;AAAA,EAC5B,QAAQ,sGAAyD;AAAA,EACjE,UAAU;AACZ,CAAC;;;ACHM,IAAMC,aAA+E,OAAO,EAAC,MAAM,oBAAoB,EAAE,OAAO,EAAC,MAAM;AAC5I,QAAM,kBAAkB,MAAM;AAAA,IAC5B;AAAA,IACA,EAAE,OAAO,KAAK,MAAM;AAAA,IACpB,EAAE,aAAa,OAAO;AAAA,EACxB;AACA,MAAI,CAAC,gBAAgB,SAAS;AAC5B,UAAM,EAAE,MAAM,QAAQ,IAAI,gBAAgB;AAC1C,WAAO,cAAc,KAAK,MAAM,OAAO;AAAA,EACzC;AACA,SAAO,aAAa;AACtB;;;ACjBA,SAAS,mBAAAC,yBAAuB;AAChC,OAAOC,UAAS;AAKT,IAAMC,cAAiF,OAAO,EAAE,KAAK,MAAM;AAChH,QAAM,gBAAgBC,KAAI,OAAO,EAAE,OAAOA,KAAI,OAAO,EAAE,CAAC;AACxD,MAAI;AACF,UAAM,YAAY,cAAc,MAAM,IAAI;AAC1C,WAAO,aAAa,KAAK;AAAA,MACvB,MAAM;AAAA,MACN,OAAO,CAAC;AAAA,MACR,QAAQ,CAAC;AAAA,IACX,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,SAASC,kBAAgB,GAAG;AAClC,WAAO,cAAc,wDAAiC,MAAM,MAAM;AAAA,EACpE;AACF;;;ACdO,IAAM,8BAAoF;AAAA,EAC/F,WAAW;AAAA,EACX,SAAS;AAAA,EACT,gBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AACF;;;ACPO,IAAMC,mBAAyF,MAAM;AAAA,EAC1G,OAAO,oBAAe;AAAA,EACtB,UAAU,sBAAkB;AAAA,EAC5B,QAAQ,sGAAyD;AAAA,EACjE,UAAU;AACZ,CAAC;;;ACHM,IAAMC,cAA+E,OAAO,EAAE,MAAM,oBAAoB,EAAE,OAAO,EAAE,MAAM;AAC9I,QAAM,kBAAkB,MAAM;AAAA,IAC5B;AAAA,IACA,EAAE,OAAO,KAAK,MAAM;AAAA,IACpB,EAAE,aAAa,OAAO;AAAA,EACxB;AACA,MAAI,gBAAgB,QAAS,QAAO,aAAa;AACjD,QAAM,EAAE,MAAM,QAAQ,IAAI,gBAAgB;AAC1C,SAAO,cAAc,KAAK,MAAM,OAAO;AACzC;;;ACfA,SAAS,mBAAAC,yBAAuB;AAChC,OAAOC,UAAS;AAKT,IAAMC,cAAiF,OAAO,EAAE,KAAK,MAAM;AAChH,QAAM,gBAAgBC,KAAI,OAAO,EAAE,OAAOA,KAAI,OAAO,EAAE,CAAC;AACxD,MAAI;AACF,UAAM,YAAY,cAAc,MAAM,IAAI;AAC1C,WAAO,aAAa,KAAK;AAAA,MACvB,MAAM;AAAA,MACN,OAAO,CAAC;AAAA,MACR,QAAQ,CAAC;AAAA,IACX,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,SAASC,kBAAgB,GAAG;AAClC,WAAO,cAAc,wDAAiC,MAAM,MAAM;AAAA,EACpE;AACF;;;ACdO,IAAM,8BAAoF;AAAA,EAC/F,WAAW;AAAA,EACX,SAAS;AAAA,EACT,gBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AACF;;;ACPO,IAAMC,mBAAoE,MAAM;AAAA,EACrF,OAAO,oBAAe;AAAA,EACtB,UAAU,sBAAkB;AAAA,EAC5B,QAAQ,sDAAiC;AAAA,EACzC,UAAU;AACZ,CAAC;;;ACTD,OAAOC,aAAY;AASZ,IAAMC,mBAAgE,OAAO,EAAE,MAAM,oBAAoB,EAAE,OAAO,EAAE,MAAM;AAC/H,MAAI,cAAc,MAAM;AACtB,QAAI,cAAc,KAAM,QAAO,cAAc,wDAAiC,MAAM,qDAAqD;AACzI,QAAI,WAAW,KAAM,QAAO,cAAc,wDAAiC,MAAM,mCAAmC;AACpH,QAAI,cAAc,KAAM,QAAO,cAAc,wDAAiC,MAAM,sCAAsC;AAC1H,UAAM,cAAc;AAAA,MAClB,UAAU,KAAK;AAAA,MACf,MAAM,KAAK;AAAA,MACX,QAAQ,KAAK;AAAA,MACb,UAAU,KAAK;AAAA,IACjB;AACA,QAAI,KAAK,cAAc,OAAW,CAAC,YAAoB,SAAS,KAAK;AACrE,QAAI,KAAK,cAAc,OAAW,CAAC,YAAoB,QAAQ,EAAE,QAAQ,EAAE,OAAO,KAAK,UAAU,EAAE;AACnG,QAAI,KAAK,iBAAiB,OAAW,CAAC,YAAoB,QAAQ,EAAE,QAAQ,EAAE,KAAK,KAAK,aAAa,EAAE;AACvG,UAAM,kBAAkB,MAAM,UAAuB,iBAAiB,EAAE,KAAK,KAAK,IAAI,GAAG,aAAa,EAAE,aAAa,OAAO,CAAC;AAC7H,QAAI,CAAC,gBAAgB,SAAS;AAC5B,YAAM,EAAE,MAAM,QAAQ,IAAI,gBAAgB;AAC1C,aAAO,cAAc,KAAK,MAAM,OAAO;AAAA,IACzC;AACA,WAAO,aAAa,KAAK,gBAAgB,gBAAgB,OAAO,CAAC;AAAA,EACnE,OAAO;AACL,UAAM,cAAc;AAAA,MAClB,UAAU,KAAK;AAAA,MACf,MAAM,KAAK;AAAA,MACX,QAAQ,KAAK;AAAA,MACb,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,MACf,WAAW,KAAK,aAAa,SACzB,MAAMC,QAAO,KAAK,KAAK,UAAU,EAAE,IACnC;AAAA,IACN;AACA,QAAI,KAAK,cAAc,OAAW,CAAC,YAAoB,SAAS,KAAK;AACrE,QAAI,KAAK,cAAc,OAAW,CAAC,YAAoB,QAAQ,EAAE,QAAQ,EAAE,OAAO,KAAK,UAAU,EAAE;AACnG,QAAI,KAAK,iBAAiB,OAAW,CAAC,YAAoB,QAAQ,EAAE,QAAQ,EAAE,KAAK,KAAK,aAAa,EAAE;AACvG,UAAM,kBAAkB,MAAM,UAAsB,gBAAgB,EAAE,KAAK,KAAK,IAAI,GAAG,aAAa,EAAE,aAAa,OAAO,CAAC;AAC3H,QAAI,CAAC,gBAAgB,SAAS;AAC5B,YAAM,EAAE,MAAM,QAAQ,IAAI,gBAAgB;AAC1C,aAAO,cAAc,KAAK,MAAM,OAAO;AAAA,IACzC;AACA,WAAO,aAAa,KAAK,eAAe,gBAAgB,OAAO,CAAC;AAAA,EAClE;AACF;AAEO,IAAMC,cAAoC,OAAM,UAAS;AAC9D,QAAM,SAAS,MAAMF,iBAAgB,KAAK;AAC1C,SAAO;AACT;;;ACvDA,SAAS,mBAAAG,yBAAuB;AAChC,OAAOC,WAAS;AAMT,IAAMC,eAA4D,OAAO,EAAE,KAAK,MAAM;AAC3F,QAAM,gBAAgBC,MAAI,OAAO;AAAA,IAC/B,KAAKA,MAAI,OAAO;AAAA,IAChB,UAAUA,MAAI,OAAO,EAAE,SAAS;AAAA,IAChC,MAAMA,MAAI,WAAW,QAAQ,EAAE,SAAS;AAAA,IACxC,QAAQA,MAAI,WAAW,UAAU,EAAE,SAAS;AAAA,IAC5C,WAAWA,MAAI,MAAMA,MAAI,WAAW,SAAS,CAAC,EAAE,SAAS;AAAA,IACzD,cAAcA,MAAI,MAAMA,MAAI,WAAW,SAAS,CAAC,EAAE,SAAS;AAAA,IAC5D,WAAWA,MAAI,MAAMA,MAAI,WAAW,SAAS,CAAC,EAAE,SAAS;AAAA,IACzD,UAAUA,MAAI,QAAQ,EAAE,SAAS;AAAA,IACjC,OAAOA,MAAI,OAAO,EAAE,MAAM,EAAE,SAAS;AAAA,IACrC,UAAUA,MAAI,OAAO,EAAE,SAAS;AAAA,IAChC,UAAUA,MAAI,OAAO,EAAE,SAAS;AAAA,EAClC,CAAC;AACD,MAAI;AACF,UAAM,YAAY,cAAc,MAAM,IAAI;AAC1C,WAAO,aAAa,KAAK;AAAA,MACvB,MAAM;AAAA,MACN,OAAO,CAAC;AAAA,MACR,QAAQ,CAAC;AAAA,IACX,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,SAASC,kBAAgB,GAAG;AAClC,WAAO,cAAc,wDAAiC,MAAM,MAAM;AAAA,EACpE;AACF;;;AC3BO,IAAM,SAA0C;AAAA,EACrD,WAAW;AAAA,EACX,SAAS;AAAA,EACT,gBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AACF;;;ACAO,IAAM,QAAQ;AAAA,EACnB;AAAA,EACA,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACnBO,IAAM,QAAQ;AAAA,EACnB;AAAA,EACA;AACF;;;ACNA,SAAS,mBAAAC,yBAAuB;AAChC,SAAS,mBAAAC,wBAAuB;AAChC,OAAOC,gBAAe;AACtB,OAAOC,WAAS;AAKT,IAAMC,eAAqD,OAAO,EAAE,MAAM,QAAQ,MAAM,MAAM;AACnG,MAAI,CAACC,iBAAgB,IAAI,EAAG,QAAO,cAAc,wDAAiC,MAAM,sBAAsB;AAC9G,MAAI,WAAW,MAAM;AACnB,UAAM,kBAAkBC,MAAI,OAAO;AAAA,MACjC,OAAOA,MACJ,OAAO,EACP,MAAM,sBAAsB;AAAA,MAC/B,UAAUA,MACP,OAAO,EACP,IAAI,GAAG,8CAA8C;AAAA,IAC1D,CAAC;AACD,QAAI;AACF,YAAM,qBAAqB,gBAAgB,MAAM,IAAI;AACrD,aAAO,aAAa,KAAK;AAAA,QACvB,MAAM;AAAA,QACN;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,YAAM,SAASC,kBAAgB,GAAG;AAClC,aAAO,cAAc,wDAAiC,MAAM,MAAM;AAAA,IACpE;AAAA,EACF,WAAW,cAAc,MAAM;AAC7B,UAAM,qBAAqBD,MAAI,OAAO;AAAA,MACpC,UAAUA,MAAI,OAAO,EAClB,IAAI,CAAC,EACL;AAAA,QACC,WAASE,WACN,OAAO,MAAM,YAAY,CAAC;AAAA,QAC3B,EAAE,SAAS,sGAAsG;AAAA,MACrH;AAAA,MACF,UAAUF,MACP,OAAO,EACP,IAAI,GAAG,8CAA8C;AAAA,IAC1D,CAAC;AACD,QAAI;AACF,YAAM,wBAAwB,mBAAmB,MAAM,IAAI;AAC3D,aAAO,aAAa,KAAK;AAAA,QACvB,MAAM;AAAA,QACN;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,YAAM,SAASC,kBAAgB,GAAG;AAClC,aAAO,cAAc,wDAAiC,MAAM,MAAM;AAAA,IACpE;AAAA,EACF,OAAO;AACL,WAAO,cAAc,wDAAiC,MAAM,oCAAoC;AAAA,EAClG;AACF;;;ACzDA,OAAOE,aAAY;AAqBZ,IAAMC,mBAAyD,OAAO,EAAE,MAAM,WAAW,UAAU,MAAM;AAC9G,QAAM,EAAE,SAAS,IAAI;AACrB,QAAM,QAAQ,WAAW,OAAO,EAAE,OAAO,KAAK,MAAM,IAAI,EAAE,UAAU,KAAK,SAAS;AAClF,QAAM,YAAY,MAAM,QAAoB,gBAAgB,OAAO,EAAE,aAAa,YAAI,aAAa,CAAC;AACpG,MAAI,CAAC,UAAU,SAAS;AACtB,UAAM,MAAM,UAAU;AACtB,QAAI,IAAI,mCAAyB,QAAO,cAAc,gCAAqB,IAAI,QAAQ,OAAO;AAC9F,WAAO,cAAc,oDAA8B;AAAA,EACrD;AACA,QAAM,iBAAiB,MAAMC,QAAO,QAAQ,UAAU,UAAU,QAAQ,SAAS;AACjF,MAAI,CAAC,eAAgB,QAAO,cAAc,oDAA8B;AACxE,QAAM,WAAW,UAAU;AAC3B,QAAM,cAAc,SAAS,gCAA2B,SAAS;AACjE,QAAM,SAAS,SAAS,IAAI,SAAS;AACrC,QAAM,cAAc,MAAM,oBAAoB,QAAQ,CAAC;AACvD,QAAMC,gBAAe,MAAM,qBAAqB,QAAQ,CAAC;AACzD,MAAI,CAAC,YAAY,QAAS,QAAO,cAAc,sFAAgD,iCAAiC;AAChI,MAAI,CAACA,cAAa,QAAS,QAAO,cAAc,wFAAiD,kCAAkC;AACnI,yBAAuB,WAAW,YAAY,OAAO;AACrD,0BAAwB,WAAWA,cAAa,SAAS,WAAW;AACpE,SAAO,aAAa,KAAK,eAAe,QAAQ,CAAC;AACnD;AAEO,IAAMC,cAAoC,OAAM,UAAS;AAC9D,QAAM,SAAS,MAAMH,iBAAgB,KAAK;AAC1C,QAAM,mBAAmB,cAAc,MAAM,OAAO,MAAM,KAAK,WAAW;AAC1E,QAAM,gBAAgB,WAAW,MAAM,OAAO,MAAM,KAAK,QAAQ;AACjE,QAAM;AAAA,IACJ;AAAA,IACA,qCAAqC;AAAA,IACrC,sCAAsC;AAAA,EACxC,IAAI;AACJ,MAAI,OAAO,SAAS,OAAQ,wCAAgC,kBAAkB,EAAE,MAAM,OAAO,QAAQ,CAAC;AAAA,WAC7F,OAAO,SAAS,SAAU,yCAAiC,YAAY;AAAA,IAC9E;AAAA,IACA;AAAA,IACA,OAAO;AAAA,MACL,MAAM,OAAO;AAAA,MACb,SAAS,OAAO;AAAA,MAChB,SAAS,OAAO;AAAA,IAClB;AAAA,EACF,CAAC;AAAA,WACQ,OAAO,SAAS,iBAAkB,yCAAiC,iCAAiC;AAAA,IAC3G;AAAA,IACA;AAAA,IACA,OAAO;AAAA,MACL,MAAM,OAAO;AAAA,MACb,SAAS,OAAO;AAAA,MAChB,SAAS,OAAO;AAAA,IAClB;AAAA,EACF,CAAC;AAAA,WACQ,OAAO,SAAS,kBAAmB,yCAAiC,kCAAkC;AAAA,IAC7G;AAAA,IACA;AAAA,IACA,OAAO;AAAA,MACL,MAAM,OAAO;AAAA,MACb,SAAS,OAAO;AAAA,MAChB,SAAS,OAAO;AAAA,IAClB;AAAA,EACF,CAAC;AACD,SAAO;AACT;;;AC9EO,IAAM,QAAkC;AAAA,EAC7C,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAYI;AAAA,EACZ,WAAWC;AACb;;;ACNO,IAAMC,mBAA8D,OAAO;AAAA,EAChF;AAAA,EACA;AACF,MAAM,aAAa,KAAK;AAAA,EACtB;AAAA,EACA;AACF,CAAC;;;ACTD,OAAOC,UAAS;AAST,IAAMC,mBAA0D,OAAO,EAAE,SAAS,kBAAkB,MAAM;AAC/G,QAAM,EAAE,cAAc,mBAAmB,IAAI;AAC7C,QAAM,qBAAqBC,KAAI,OAAO,mBAAmB,YAAI,UAAU;AACvE,MAAI,CAAC,eAAe,kBAAkB,EAAG,QAAO,cAAc,4DAAmC,yBAAyB;AAC1H,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,WAAqB,CAAC;AAC5B,MAAI,sBAAsB,OAAW,UAAS,KAAK,iBAAiB;AACpE,MAAI,uBAAuB,OAAW,UAAS,KAAK,kBAAkB;AACtE,QAAM,UAAU,MAAM,iBAAiB,QAAQ,QAAQ;AACvD,MAAI,CAAC,QAAQ,QAAS,QAAO,cAAc,0EAA0C,QAAQ,QAAQ;AACrG,SAAO,aAAa;AACtB;AAEO,IAAMC,cAAoC,OAAM,UAAS;AAC9D,QAAM,SAAS,MAAMF,iBAAgB,KAAK;AAC1C,QAAM,EAAE,mBAAmB,IAAI;AAC/B,QAAM,EAAE,OAAO,IAAI;AACnB,MAAI,OAAO,SAAS,OAAQ,0CAAiC,mBAAmB,EAAE,OAAO,CAAC;AAAA,WACjF,OAAO,6EAA8C,2CAAkC,2BAA2B;AAAA,IACzH;AAAA,IACA,aAAa,MAAM;AAAA,IACnB,cAAc,MAAM,QAAQ;AAAA,EAC9B,CAAC;AACD,SAAO;AACT;;;AC5BO,IAAM,SAAoC;AAAA,EAC/C,WAAW;AAAA,EACX,SAAS;AAAA,EACT,gBAAgBG;AAAA,EAChB,YAAY;AAAA,EACZ,WAAWC;AACb;;;ACRO,IAAMC,mBAAwE,OAAO;AAAA,EAC1F;AAAA,EACA;AACF,MAAM,aAAa,KAAK;AAAA,EACtB;AAAA,EACA;AACF,CAAC;;;ACFM,IAAMC,mBAAoE,OAAO;AAAA,EACtF;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,MAAI,sBAAsB,OAAW,QAAO,cAAc,4DAAmC,yBAAyB;AACtH,MAAI,uBAAuB,OAAW,QAAO,cAAc,4DAAmC,yBAAyB;AACvH,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,EAAE,cAAc,mBAAmB,IAAI;AAC7C,QAAM,WAAqB,CAAC;AAC5B,MAAI,OAAO,sBAAsB,SAAU,UAAS,KAAK,iBAAiB;AAC1E,MAAI,OAAO,uBAAuB,SAAU,UAAS,KAAK,kBAAkB;AAC5E,QAAM,UAAU,MAAM,wBAAwB,QAAQ,QAAQ;AAC9D,MAAI,CAAC,QAAQ,QAAS,QAAO,cAAc,0EAA0C,QAAQ,QAAQ;AACrG,SAAO,aAAa;AACtB;AAEO,IAAMC,cAAoC,OAAM,UAAS;AAC9D,QAAM,SAAS,MAAMD,iBAAgB,KAAK;AAC1C,QAAM,EAAE,mBAAmB,IAAI;AAC/B,QAAM,EAAE,OAAO,IAAI;AACnB,MAAI,OAAO,SAAS,OAAQ,0CAAiC,mBAAmB,EAAE,OAAO,CAAC;AAAA,WACjF,OAAO,6EAA8C,2CAAkC,2BAA2B;AAAA,IACzH;AAAA,IACA,aAAa,MAAM;AAAA,IACnB,cAAc,MAAM,QAAQ;AAAA,EAC9B,CAAC;AACD,SAAO;AACT;;;AC9BO,IAAM,mBAAwD;AAAA,EACnE,WAAW;AAAA,EACX,SAAS;AAAA,EACT,gBAAAE;AAAA,EACA,YAAY;AAAA,EACZ,WAAAC;AACF;;;ACXA,OAAOC,UAAS;AAmBT,IAAMC,oBAAgE,OAAO,EAAE,SAAS,WAAW,UAAU,MAAM;AACxH,QAAM,gBAAgB,QAAO,mCAAS,kBAAiB;AACvD,MAAI,CAAC,cAAe,QAAO,cAAc,kEAAqC;AAC9E,QAAM,oBAAoB,MAAM,QAA+B,2BAA2B,EAAE,OAAO,QAAQ,aAAa,GAAG,EAAE,aAAa,YAAI,aAAa,CAAC;AAC5J,MAAI,kBAAkB,QAAS,QAAO,cAAc,kEAAqC;AACzF,MAAI;AACF,UAAM,UAAUC,KAAI,OAAO,QAAQ,cAAc,YAAI,UAAU;AAC/D,QAAI,CAAC,eAAe,OAAO,EAAG,QAAO,cAAc,sEAAuC;AAC1F,UAAM,EAAE,QAAQ,KAAK,aAAa,IAAI;AACtC,UAAM,MAAM,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;AACxC,UAAM,kBAAkB,OAAO;AAC/B,QAAI,gBAAiB,QAAO,cAAc,kEAAqC;AAC/E,QAAI,gBAAgB,YAAI,gCAAiC,QAAO,cAAc,4DAAmC,iDAAiD;AAClK,UAAM,YAAY,MAAM,QAAmB,eAAe,EAAE,KAAK,OAAO,GAAG,EAAE,aAAa,YAAI,aAAa,CAAC;AAC5G,QAAI,CAAC,UAAU,QAAS,QAAO,cAAc,sDAAgC,MAAM;AACnF,UAAM,WAAW,UAAU;AAC3B,UAAM,cAAc,SAAS,gCAA2B,SAAS;AACjE,UAAM,iBAAiB,MAAM,oBAAoB,QAAQ,CAAC;AAC1D,UAAM,kBAAkB,MAAM,qBAAqB,QAAQ,eAAe,CAAC;AAC3E,QAAI,CAAC,eAAe,QAAS,QAAO,cAAc,sFAAgD,QAAQ,eAAe,MAAM,OAAO;AACtI,QAAI,CAAC,gBAAgB,QAAS,QAAO,cAAc,wFAAiD,QAAQ,gBAAgB,MAAM,OAAO;AACzI,2BAAuB,WAAW,eAAe,OAAO;AACxD,4BAAwB,WAAW,gBAAgB,SAAS,WAAW;AACvE,WAAO,aAAa;AAAA,EACtB,SAAS,KAAK;AACZ,WAAO,cAAc,4DAAmC,sBAAsB,GAAG,EAAE;AAAA,EACrF;AACF;AAEO,IAAMC,cAAoC,OAAM,UAAS;AAC9D,QAAM,SAAS,MAAMF,kBAAgB,KAAK;AAC1C,MAAI,OAAO,SAAS,QAAQ;AAC1B,QAAI;AACF,YAAM,UAAUC,KAAI,OAAO,MAAM,QAAQ,cAAc,YAAI,UAAU;AACrE,UAAI,CAAC,eAAe,OAAO,EAAG,OAAM;AACpC,YAAM,EAAE,QAAQ,KAAK,aAAa,IAAI;AACtC,+DAAyC,iCAAiC;AAAA,QACxE;AAAA,QACA;AAAA,QACA;AAAA,QACA,sBAAsB,MAAM,QAAQ;AAAA,MACtC,CAAC;AACD,aAAO;AAAA,IACT,QACM;AACJ,kEAA4C,yFAAyF;AACrI,aAAO;AAAA,IACT;AAAA,EACF;AACA,MACE,OAAO,8EACJ,OAAO,0EACP,OAAO,4DACP,OAAO,4FACP,OAAO,2FACV,2DAA0C,wCAAwC;AAAA,IAClF,OAAO;AAAA,MACL,MAAM,OAAO;AAAA,MACb,SAAS,OAAO;AAAA,MAChB,SAAS,OAAO;AAAA,IAClB;AAAA,EACF,CAAC;AACD,SAAO;AACT;;;AC9EO,IAAM,eAAgD;AAAA,EAC3D,WAAW;AAAA,EACX,SAAS;AAAA,EACT,oBAAoB;AAAA,EACpB,YAAY;AAAA,EACZ,WAAAE;AACF;;;ACVA,SAAS,mBAAAC,yBAAuB;AAChC,OAAOC,WAAS;AAKT,IAAMC,eAA6E,OAAO,EAAE,KAAK,MAAM;AAC5G,QAAM,mBAAmBC,MAAI,OAAO;AAAA,IAClC,OAAOA,MACJ,OAAO,EACP,MAAM,sBAAsB;AAAA,EAC/B,CAAC;AACH,MAAI;AACF,UAAM,YAAY,iBAAiB,MAAM,IAAI;AAC7C,WAAO,aAAa,KAAK;AAAA,MACvB,MAAM;AAAA,MACN,QAAQ,CAAC;AAAA,MACT,OAAO,CAAC;AAAA,IACV,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,SAASC,kBAAgB,GAAG;AAClC,WAAO,cAAc,wDAAiC,MAAM,MAAM;AAAA,EACpE;AACF;;;ACXO,IAAMC,oBAAiF,OAAO,EAAE,KAAK,MAAM;AAChH,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,aAAa,MAAM,QAAoB,gBAAgB,EAAE,MAAM,GAAG,EAAE,aAAa,YAAI,aAAa,CAAC;AACzG,MAAI,CAAC,WAAW,QAAS,QAAO,cAAc,kEAAsC,KAAK;AACzF,QAAM,WAAsC,+BAA+B,EAAE,MAAM,GAAG,EAAE,aAAa,YAAI,aAAa,CAAC;AACvH,QAAM,WAAW,WAAW;AAC5B,MAAI,SAAS,aAAa,KAAM,QAAO,cAAc,sEAAwC,KAAK;AAClG,QAAM,sCAAsC,OAAO,SAAS,QAAQ;AACpE,SAAO,aAAa;AACtB;AAEO,IAAMC,cAAoC,OAAM,UAAS;AAC9D,QAAM,SAAS,MAAMD,kBAAgB,KAAK;AAC1C,MAAI,OAAO,SAAS,OAAQ;AAAA;AAAA,IAE1B;AAAA,IACA,EAAE,OAAO,MAAM,KAAK,MAAM;AAAA,EAC5B;AACA,SAAO;AACT;;;AC3BO,IAAM,gCAAkF;AAAA,EAC7F,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAAE;AAAA,EACA,WAAAC;AACF;;;ACTA,SAAS,mBAAAC,yBAAuB;AAChC,OAAOC,WAAS;AAKT,IAAMC,eAAkE,OAAO,EAAE,KAAK,MAAM;AACjG,QAAM,mBAAmBC,MAAI,OAAO;AAAA,IAClC,OAAOA,MACJ,OAAO,EACP,MAAM,sBAAsB;AAAA,EACjC,CAAC;AACD,MAAI;AACF,UAAM,YAAY,iBAAiB,MAAM,IAAI;AAC7C,WAAO,aAAa,KAAK;AAAA,MACvB,MAAM;AAAA,MACN,QAAQ,CAAC;AAAA,MACT,OAAO,CAAC;AAAA,IACV,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,SAASC,kBAAgB,GAAG;AAClC,WAAO,cAAc,wDAAiC,MAAM,MAAM;AAAA,EACpE;AACF;;;ACRO,IAAMC,oBAAsE,OAAO,EAAE,KAAK,MAAM;AACrG,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,YAAY,MAAM,QAAoB,gBAAgB,EAAE,MAAM,GAAG,EAAE,aAAa,YAAI,aAAa,CAAC;AACxG,MAAI,CAAC,UAAU,QAAS,QAAO,cAAc,kEAAsC,KAAK;AACxF,QAAM,WAAsC,+BAA+B,EAAE,MAAM,GAAG,EAAE,aAAa,YAAI,aAAa,CAAC;AACvH,QAAM,sCAAsC,OAAO,UAAU,QAAQ,QAAQ;AAC7E,SAAO,aAAa;AACtB;AAEO,IAAMC,cAAoC,OAAM,UAAS;AAC9D,QAAM,SAAS,MAAMD,kBAAgB,KAAK;AAC1C,MAAI,OAAO,SAAS,OAAQ;AAAA;AAAA,IAE1B;AAAA,IACA,EAAE,OAAO,MAAM,KAAK,MAAM;AAAA,EAC5B;AAAA,MACK,+DAA4C,mCAAmC;AAAA,IAClF,OAAO,MAAM,KAAK;AAAA,IAClB,OAAO;AAAA,MACL,MAAM,OAAO;AAAA,MACb,SAAS,OAAO;AAAA,MAChB,SAAS,OAAO;AAAA,IAClB;AAAA,EACF,CAAC;AACD,SAAO;AACT;;;ACpCO,IAAM,qBAA4D;AAAA,EACvE,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAAE;AAAA,EACA,WAAAC;AACF;;;ACTA,SAAS,mBAAAC,yBAAuB;AAChC,OAAOC,gBAAe;AACtB,OAAOC,WAAS;AAKT,IAAMC,eAAsD,OAAO,EAAE,KAAK,MAAM;AACrF,QAAM,mBAAmBC,MAAI,OAAO;AAAA,IAClC,UAAUA,MAAI,OAAO,EAClB,IAAI,CAAC,EACL;AAAA,MACC,WAASC,WACN,OAAO,MAAM,YAAY,CAAC;AAAA,MAC7B,EAAE,SAAS,sGAAsG;AAAA,IAAC;AAAA,IACtH,OAAOD,MACJ,OAAO,EACP,MAAM,sBAAsB;AAAA,IAC/B,UAAUA,MACP,OAAO,EACP,IAAI,GAAG,8CAA8C;AAAA,EAC1D,CAAC;AACD,MAAI;AACF,UAAM,YAAY,iBAAiB,MAAM,IAAI;AAC7C,WAAO,aAAa,KAAK;AAAA,MACvB,MAAM;AAAA,MACN,QAAQ,CAAC;AAAA,MACT,OAAO,CAAC;AAAA,IACV,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,SAASE,kBAAgB,GAAG;AAClC,WAAO,cAAc,wDAAiC,MAAM,MAAM;AAAA,EACpE;AACF;;;ACjCA,OAAOC,aAAY;AAcnB,IAAMC,oBAA0D,OAAO,EAAE,KAAK,MAAM;AAClF,QAAM,EAAE,UAAU,OAAO,SAAS,IAAI;AACtC,QAAM,mBAAqC,EAAE,aAAa,YAAI,aAAa;AAC3E,QAAM,gBAAgB,MAAM,QAAmB,eAAe,EAAE,SAAS,GAAG,gBAAgB;AAC5F,MAAI,cAAc,QAAS,QAAO,cAAc,4DAAmC,QAAQ;AAC3F,QAAM,aAAa,MAAM,QAAqB,iBAAiB,EAAE,MAAM,GAAG,gBAAgB;AAC1F,MAAI,WAAW,QAAS,QAAO,cAAc,sEAAwC,KAAK;AAC1F,QAAM,WAAW,MAAM,UAAsB,gBAAgB;AAAA,IAC3D;AAAA,IACA;AAAA,IACA;AAAA,IACA,QAAQ,CAAC;AAAA,IACT;AAAA,IACA,WAAW,MAAMC,QAAO,KAAK,UAAU,EAAE;AAAA,IACzC,UAAU;AAAA,EACZ,GAAG,gBAAgB;AACnB,MAAI,CAAC,SAAS,QAAS,QAAO,cAAc,gCAAqB,SAAS,MAAM,QAAQ,OAAO;AAC/F,QAAM,sCAAsC,OAAO,QAAQ;AAC3D,SAAO,aAAa,KAAK,eAAe,SAAS,OAAO,CAAC;AAC3D;AAEO,IAAMC,cAAoC,OAAM,UAAS;AAC9D,QAAM,SAAS,MAAMF,kBAAgB,KAAK;AAC1C,MAAI,OAAO,SAAS,OAAQ,4CAAiC,gBAAgB,EAAE,MAAM,OAAO,QAAQ,CAAC;AAAA,WAC5F,OAAO,mCAAyB,6CAAkC,wBAAwB;AAAA,IACjG,kBAAkB,MAAM,KAAK;AAAA,IAC7B,eAAe,MAAM,KAAK;AAAA,IAC1B,OAAO;AAAA,MACL,MAAM,OAAO;AAAA,MACb,SAAS,OAAO;AAAA,MAChB,SAAS,OAAO;AAAA,IAClB;AAAA,EACF,CAAC;AACD,SAAO;AACT;;;AC5CO,IAAM,SAAoC;AAAA,EAC/C,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAAG;AAAA,EACA,WAAAC;AACF;;;ACTA,SAAS,mBAAAC,yBAAuB;AAChC,OAAOC,WAAS;AAKT,IAAMC,eAAiE,OAAO,EAAE,KAAK,MAAM;AAChG,QAAM,mBAAmBC,MAAI,OAAO;AAAA,IAClC,OAAOA,MACJ,OAAO,EACP,MAAM,sBAAsB;AAAA,IAC/B,OAAOA,MACJ,OAAO;AAAA,IACV,UAAUA,MACP,OAAO,EACP,IAAI,GAAG,8CAA8C;AAAA,EAC1D,CAAC;AACD,MAAI;AACF,UAAM,YAAY,iBAAiB,MAAM,IAAI;AAC7C,WAAO,aAAa,KAAK;AAAA,MACvB,MAAM;AAAA,MACN,QAAQ,CAAC;AAAA,MACT,OAAO,CAAC;AAAA,IACV,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,SAASC,kBAAgB,GAAG;AAClC,WAAO,cAAc,wDAAiC,MAAM,MAAM;AAAA,EACpE;AACF;;;AC5BA,OAAOC,aAAY;AAiBZ,IAAMC,oBAAqE,OAAO,EAAE,MAAM,mBAAmB,QAAQ,MAAM;AAChI,QAAM,EAAE,OAAO,OAAO,SAAS,IAAI;AACnC,QAAM,cAAc,MAAM;AAAA,IACxB;AAAA,IACA,EAAE,OAAO,OAAO,OAAc,WAAW,EAAE,MAAM,KAAK,IAAI,EAAE,EAAE;AAAA,IAC9D,EAAE,aAAa,YAAI,aAAa;AAAA,EAClC;AACA,MAAI,CAAC,YAAY,QAAS,QAAO,cAAc,oGAAuD,OAAO,KAAK;AAClH,QAAM,WAAsC,+BAA+B,EAAE,MAAM,GAAG,EAAE,aAAa,YAAI,aAAa,CAAC;AACvH,QAAM,YAAY,MAAM;AAAA,IACtB;AAAA,IACA,EAAE,MAAM;AAAA,IACR,EAAE,aAAa,YAAI,aAAa;AAAA,EAClC;AACA,MAAI,CAAC,UAAU,QAAS,QAAO,cAAc,kEAAsC,KAAK;AACxF,QAAM,EAAE,cAAc,mBAAmB,IAAI;AAC7C,QAAM,2BAA2B,CAAC;AAClC,MAAI,sBAAsB,OAAW,0BAAyB,KAAK,iBAAiB;AACpF,MAAI,OAAO,uBAAuB,SAAU,0BAAyB,KAAK,kBAAkB;AAC5F,QAAM,UAAU,MAAM,wBAAwB,UAAU,QAAQ,KAAK,wBAAwB;AAC7F,MAAI,CAAC,QAAQ,QAAS,QAAO;AAAA,IAC3B;AAAA;AAAA,IAEA,UAAU,QAAQ,IAAI,SAAS;AAAA,IAC/B;AAAA,EACF;AACA,QAAM,cAAc,MAAM;AAAA,IACxB;AAAA,IACA,EAAE,KAAK,UAAU,QAAQ,IAAI;AAAA,IAC7B,EAAE,MAAM,EAAE,WAAW,MAAMC,QAAO,KAAK,UAAU,EAAE,EAAE,EAAE;AAAA,IACvD,EAAE,aAAa,YAAI,aAAa;AAAA,EAClC;AACA,MAAI,CAAC,YAAY,SAAS;AACxB,QAAI,YAAY,MAAM,mCAAyB,QAAO,cAAc,gCAAqB,YAAY,MAAM,QAAQ,OAAO;AAC1H,WAAO,cAAc,sDAAgC,UAAU,QAAQ,IAAI,SAAS,CAAC;AAAA,EACvF;AACA,SAAO,aAAa;AACtB;AAEO,IAAMC,cAAoC,OAAM,UAAS;AAC9D,QAAM,SAAS,MAAMF,kBAAgB,KAAK;AAC1C,MAAI,OAAO,SAAS,OAAQ,8DAA2C,+BAA+B,EAAE,OAAO,MAAM,KAAK,MAAM,CAAC;AAAA,MAC5H,+DAA4C,2BAA2B;AAAA,IAC1E,OAAO,MAAM,KAAK;AAAA,IAClB,OAAO;AAAA,MACL,MAAM,OAAO;AAAA,MACb,SAAS,OAAO;AAAA,MAChB,SAAS,OAAO;AAAA,IAClB;AAAA,EACF,CAAC;AACD,SAAO;AACT;;;AChEO,IAAM,oBAA0D;AAAA,EACrE,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAAG;AAAA,EACA,WAAAC;AACF;;;ACTA,SAAS,mBAAAC,yBAAuB;AAChC,OAAOC,WAAS;AAKT,IAAMC,eAA2D,OAAO,EAAE,KAAK,MAAM;AAC1F,QAAM,mBAAmBC,MAAI,OAAO;AAAA,IAClC,OAAOA,MACJ,OAAO,EACP,MAAM,sBAAsB;AAAA,IAC/B,OAAOA,MACJ,OAAO;AAAA,EACZ,CAAC;AACD,MAAI;AACF,UAAM,YAAY,iBAAiB,MAAM,IAAI;AAC7C,WAAO,aAAa,KAAK;AAAA,MACvB,MAAM;AAAA,MACN,QAAQ,CAAC;AAAA,MACT,OAAO,CAAC;AAAA,IACV,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,UAAM,SAASC,kBAAgB,GAAG;AAClC,WAAO,cAAc,wDAAiC,MAAM,MAAM;AAAA,EACpE;AACF;;;ACXO,IAAMC,oBAA+D,OAAO,EAAE,KAAK,MAAM;AAC9F,QAAM,EAAE,OAAO,MAAM,IAAI;AACzB,MAAI,UAAU,OAAW,QAAO,cAAc,kGAAqD;AACnG,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,mBAAmB,EAAE,aAAa,YAAI,aAAa;AACzD,QAAM,gBAAgB,MAAM;AAAA,IAC1B;AAAA,IACA,EAAE,OAAO,OAAO,OAAO,WAAW,EAAE,MAAM,IAAI,EAAE;AAAA,IAChD;AAAA,EACF;AACA,MAAI,CAAC,cAAc,QAAS,QAAO,cAAc,sGAAuD;AACxG,QAAM,eAAe,MAAM;AAAA,IACzB;AAAA,IACA,EAAE,MAAM;AAAA,IACR,EAAE,MAAM,EAAE,UAAU,KAAK,EAAE;AAAA,IAC3B;AAAA,EACF;AACA,MAAI,CAAC,aAAa,SAAS;AACzB,QAAI,aAAa,MAAM,mCAAyB,QAAO,cAAc,gCAAqB,aAAa,MAAM,QAAQ,OAAO;AAC5H,WAAO,cAAc,kEAAsC,KAAK;AAAA,EAClE;AACA,QAAM,cAAc,aAAa;AACjC,SAAO,aAAa,KAAK;AAAA,IACvB,KAAK,YAAY,IAAI,SAAS;AAAA,IAC9B,UAAU,YAAY;AAAA,IACtB,OAAO,YAAY;AAAA,IACnB,MAAM,YAAY;AAAA,IAClB,QAAQ,YAAY;AAAA,IACpB,QAAQ,YAAY;AAAA,IACpB,UAAU,YAAY;AAAA,EACxB,CAAC;AACH;AAEO,IAAMC,cAAoC,OAAM,UAAS;AAC9D,QAAM,SAAS,MAAMD,kBAAgB,KAAK;AAC1C,MAAI,OAAO,SAAS,OAAQ,0EAA0C,iCAAiC,EAAE,OAAO,MAAM,KAAK,MAAM,CAAC;AAAA,MAC7H,2EAA2C,6BAA6B;AAAA,IAC3E,OAAO,MAAM,KAAK;AAAA,IAClB,OAAO;AAAA,MACL,MAAM,OAAO;AAAA,MACb,SAAS,OAAO;AAAA,MAChB,SAAS,OAAO;AAAA,IAClB;AAAA,EACF,CAAC;AACD,SAAO;AACT;;;ACvDO,IAAM,cAA8C;AAAA,EACzD,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAAE;AAAA,EACA,WAAAC;AACF;;;ACNO,IAAMC,mBAA8D,OAAO;AAAA,EAChF;AAAA,EACA;AAAA,EACA;AACF,MAAM,aAAa,KAAK;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AACF,CAAC;;;ACHM,IAAMC,oBAA0D,OAAO,EAAE,MAAM,mBAAmB,MAAM;AAC7G,QAAM,oBAAoB,iBAAiB,IAAI;AAC/C,MAAI,sBAAsB,KAAM,QAAO,cAAc,sDAAgC,mBAAmB,MAAM;AAC9G,MAAI,kBAAkB,aAAa,YAAa,QAAO,aAAa,KAAK,eAAe,iBAAiB,CAAC;AAC1G,SAAO,aAAa,KAAK,gBAAgB,iBAAiB,CAAC;AAC7D;AAEO,IAAMC,cAAoC,OAAM,UAAS;AAfhE;AAgBE,QAAM,SAAS,MAAMD,kBAAgB,KAAK;AAC1C,MAAI,OAAO,SAAS,QAAS;AAAA;AAAA,IAE3B;AAAA,IAAwE;AAAA,MACxE,SAAQ,WAAM,uBAAN,mBAA0B;AAAA,MAClC,OAAO;AAAA,QACL,MAAM,OAAO;AAAA,QACb,SAAS,OAAO;AAAA,QAChB,SAAS,OAAO;AAAA,MAClB;AAAA,IACF;AAAA,EAAC;AACD,SAAO;AACT;;;ACvBO,IAAM,SAAoC;AAAA,EAC/C,WAAW;AAAA,EACX,SAAS;AAAA,EACT,gBAAgBE;AAAA,EAChB,YAAY;AAAA,EACZ,WAAAC;AACF;;;ACAO,IAAM,OAAO;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;ACtBA,SAAS,YAAAC,iBAAgB;AAMlB,IAAMC,cAAsD,OAAO,EAAE,SAAS,UAAU,MAAM;AACnG,QAAM,SAAS,QAAQ,YAAI,gBAAgB;AAC3C,QAAM,SAAiB,OAAO,WAAW,WAAW,SAAS,OAAO,WAAW;AAC/E,MAAI,OAAO,WAAW,SAAU,WAAU,YAAI,kBAAkB,QAAQ;AAAA,IACtE,UAAU;AAAA,IACV,QAAQ,YAAI,eAAe;AAAA,IAC3B,UAAU;AAAA,IACV,QAAQC,UAAS,MAAM,CAAC,EAAE,eAAe;AAAA,EAC3C,CAAC;AACD,SAAO,aAAa,KAAK,EAAE,OAAO,OAAO,OAAO,MAAM,EAAE,CAAC;AAC3D;;;ACZO,IAAM,WAAwC;AAAA,EACnD,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,WAAAC;AACF;;;ACPO,IAAMC,QAAO;AAAA,EAClB;AACF;;;ACJA,SAAS,aAAAC,kBAAiB;;;ACInB,IAAMC,mBAA+D,MAAM;AAAA,EAChF,UAAU;AAAA,EACV,UAAU,sBAAkB;AAAA,EAC5B,QAAQ,kCAAuB;AACjC,CAAC;;;ACLD,SAAS,mBAAAC,wBAAuB;AAChC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEA,IAAMC,eAAuD,OAAO,EAAE,MAAM,OAAO,EAAE,OAAAC,OAAM,EAAE,MAAM;AACxG,MAAIA,WAAU,UAAaA,OAAM,WAAW,EAAG,QAAO,cAAc,0DAAkC,kDAAoD;AAC1J,MAAIA,OAAM,SAAS,EAAG,QAAO,cAAc,0DAAkC,uCAAuC;AACpH,MAAI,CAACF,iBAAgB,IAAI,EAAG,QAAO,cAAc,wDAAiC,MAAM,0BAA0B;AAClH,MAAI,EAAE,YAAY,SAAS,oBAAoB,IAAI,EAAG,QAAO,aAAa,KAAK,EAAE,MAAM,QAAQ,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC;AAC9G,QAAMG,UAAU,KAAa;AAC7B,MAAI,OAAOA,YAAW,SAAU,QAAO,cAAc,wDAAiC,MAAM,sBAAsB;AAClH,OAAKA,YAAW,SAASA,YAAW,WAAW,mBAAmB,IAAI,EAAG,QAAO,aAAa,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,QAAAA,QAAO,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC;AAAA,WAC7IA,YAAW,SAAS,mBAAmB,IAAI,EAAG,QAAO,aAAa,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,QAAAA,QAAO,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC;AAAA,WAC3HA,YAAW,UAAU,oBAAoB,IAAI,EAAG,QAAO,aAAa,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,QAAAA,QAAO,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC;AAAA,WAC7HA,YAAW,UAAU,oBAAoB,IAAI,EAAG,QAAO,aAAa,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,QAAAA,QAAO,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC;AAAA,WAC7HA,YAAW,UAAU,oBAAoB,IAAI,EAAG,QAAO,aAAa,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,QAAAA,QAAO,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC;AAAA,WAC7HA,YAAW,UAAU,oBAAoB,IAAI,EAAG,QAAO,aAAa,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,QAAAA,QAAO,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC;AACtI,SAAO,cAAc,wDAAiC,MAAM,2BAA2B;AACzF;;;AC5BA,SAAS,oBAAAC,yBAAwB;AACjC,SAAS,UAAU,gBAAgB;AACnC,SAAS,cAAc;AACvB,SAAS,mBAAAC,yBAAuB;AAMhC,SAAS,0BAA0B;AAE5B,IAAMC,oBAA2D,OAAO,EAAE,MAAM,MAAM,MAAM;AAXnG;AAYE,QAAM,QAAO,WAAM,UAAN,mBAAc;AAC3B,MAAI,SAAS,OAAW,QAAO,cAAc,0DAAkC,kBAAkB;AACjG,MAAI;AACF,QAAI,sBAAsB,QAAQ,KAAK,qBAAqB,QAAW;AACrE,WAAK,mBAAmB,KAAK,mBAAmB;AAAA,IAClD;AACA,UAAM,aAAaC,kBAAiB,KAAK,IAAI;AAC7C,UAAM,yBAAyB,YAAY,OACvC,MAAM,OAAO,MAAM,SAAS,UAAU,GAAG,KAAK,QAAQ,IAAI,IAC1D,MAAM,OAAO,MAAM,SAAS,UAAU,GAAG,IAAI;AACjD,QAAI,CAAC,uBAAuB,QAAS,QAAO,cAAc,sDAAgC,uBAAuB,KAAK;AACtH,UAAM,EAAE,SAAS,gBAAgB,IAAI;AACrC,UAAM,EAAE,KAAK,KAAK,IAAI,MAAM,mBAAmB,eAAe,KAAK,CAAC;AACpE,QAAI,QAAQ,UAAa,SAAS,OAAW,QAAO,cAAc,sDAAgC,4CAA4C;AAC9I,WAAO;AAAA,MACL;AAAA,MACA,GAAG,KAAK,OAAO,IAAI,GAAG;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,IAClB;AAAA,EACF,SAAS,OAAO;AACd,WAAO;AAAA,MACL;AAAA;AAAA,MAEAC,kBAAgB,KAAK;AAAA,IACvB;AAAA,EACF;AACF;AAEO,IAAMC,cAAoC,OAAM,UAAS;AAC9D,QAAM,EAAE,MAAM,MAAM,IAAI;AACxB,QAAM,SAAS,MAAMH,kBAAgB,KAAK;AAC1C,MAAI,OAAO,SAAS,WACf,OAAO,yDAAoC;AAAA;AAAA,IAE9C;AAAA,IACA,EAAE,MAAM,OAAO,OAAO,OAAO,QAAQ;AAAA,EACvC;AACA,SAAO;AACT;;;AH/CO,IAAMI,UAAqC;AAAA,EAChD,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,IACP,QAAQ,CAAC,EAAE,MAAM,SAAS,UAAU,EAAE,CAAC;AAAA,IACvC,QAAQ,EAAE,UAAUC,WAAU,EAAE,EAAE,QAAQ,EAAE;AAAA,EAC9C;AAAA,EACA,gBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AACF;;;AIhBA,SAAS,aAAAC,kBAAiB;;;ACInB,IAAMC,mBAAkE,MAAM;AAAA,EACnF,UAAU;AAAA,EACV,UAAU,sBAAkB;AAAA,EAC5B,QAAQ,kCAAuB;AACjC,CAAC;;;ACLD,SAAS,mBAAAC,wBAAuB;AAChC,SAAS,6BAAkD;AAGpD,IAAMC,eAA0D,OAAO,EAAE,MAAM,OAAO,EAAE,OAAAC,OAAM,EAAE,MAAM;AAC3G,MAAIA,WAAU,UAAaA,OAAM,WAAW,EAAG,QAAO,cAAc,0DAAkC,kDAAoD;AAC1J,MAAIA,OAAM,SAAS,EAAG,QAAO,cAAc,0DAAkC,uCAAuC;AACpH,MAAI,CAACF,iBAAgB,IAAI,EAAG,QAAO,cAAc,wDAAiC,MAAM,0BAA0B;AAClH,MAAI,EAAE,gBAAgB,MAAO,QAAO,cAAc,wDAAiC,MAAM,sDAAwD;AACjJ,QAAM,EAAE,WAAW,IAAI;AACvB,MAAI,CAAC,MAAM,QAAQ,UAAU,EAAG,QAAO,cAAc,wDAAiC,MAAM,2DAA6D;AACzJ,MAAI,WAAW,SAAS,GAAI,QAAO,cAAc,wDAAiC,MAAM,oFAAsF;AAC9K,QAAM,sBAAsB,WAAW,IAAI,qBAAqB;AAChE,QAAM,mBAAmB,oBAAoB,OAAO,QAAM,CAAC,GAAG,OAAO;AACrE,MAAI,iBAAiB,SAAS,EAAG,QAAO,cAAc,wDAAiC,MAAM,iBAAiB,IAAI,QAAM,GAAG,KAAK,EAAE,KAAK,IAAI,CAAC;AAC5I,QAAM,MAAM,oBAAoB,IAAI,QAAO,GAA4C,OAAO;AAC9F,SAAO,aAAa,KAAK,EAAE,MAAM,EAAE,YAAY,IAAI,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC;AAC/E;;;ACpBA,SAAS,oBAAAG,yBAAwB;AACjC,SAAS,UAAUC,iBAAgB;AACnC,SAAS,mBAAAC,yBAAuB;AAChC,SAAS,iBAAiB;AAC1B,SAAS,YAAAC,iBAAgB;AACzB,SAAS,sBAAAC,2BAA0B;AAOnC,IAAI,+BAA+B;AAE5B,IAAMC,oBAA8D,OAAO,EAAE,MAAM,OAAO,EAAE,OAAAC,OAAM,EAAE,MAAM;AAC/G,MAAI,gCAAgC,EAAG,QAAO;AAAA,IAC5C;AAAA;AAAA,IAEA;AAAA,EAA0E;AAC5E,QAAM,YAAYA,UAAA,gBAAAA,OAAQ;AAC1B,MAAI,cAAc,OAAW,QAAO,cAAc,0DAAkC,kBAAkB;AACtG;AACA,MAAI;AAEF,UAAM,EAAE,WAAW,IAAI;AACvB,UAAM,aAAa,MAAMC,UAASC,kBAAiB,UAAU,IAAI,CAAC;AAClE,UAAM,kCAAkC,MAAM,UAAU,YAAY,YAAY;AAAA,MAC9E,WAAWC,UAAS,QAAQ,EAAE,EAAE,KAAK;AAAA,MACrC,aAAaA,UAAS,QAAQ,CAAC,EAAE,KAAK;AAAA,MACtC,OAAO;AAAA,MACP,QAAQ;AAAA,IACV,CAAC;AACD,QAAI,CAAC,gCAAgC,SAAS;AAC5C;AAAA;AAAA,QAEE;AAAA,QACA,EAAE,OAAO,gCAAgC,MAAM;AAAA,MACjD;AACA,aAAO,cAAc,4DAAmC,+BAA+B;AAAA,IACzF;AACA,UAAM,2BAA2B,gCAAgC;AACjE,UAAM,kBAAkB,MAAM,yBAAyB,SAAS;AAChE,UAAM,EAAE,KAAK,WAAW,MAAM,WAAW,IAAI,MAAMC,oBAAmB,eAAe,KAAK,CAAC;AAC3F,QAAI,cAAc,UAAa,eAAe,OAAW,QAAO;AAAA,MAC9D;AAAA;AAAA,MAEA;AAAA,IACF;AACA,UAAM,aAAa,GAAG,UAAU,OAAO,KAAI,oBAAI,KAAK,GAAE,YAAY,CAAC,IAAI,SAAS;AAChF,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,IAClB;AAAA,EACF,SAAS,OAAO;AACd,WAAO,cAAc,0CAA0BC,kBAAgB,KAAK,CAAC;AAAA,EACvE,UAAE;AACA;AAAA,EACF;AACF;AAEO,IAAMC,cAAoC,OAAM,UAAS;AAC9D,QAAM,EAAE,MAAM,MAAM,IAAI;AACxB,QAAM,SAAS,MAAMP,kBAAgB,KAAK;AAC1C,MAAI,OAAO,SAAS,WACf,OAAO,6CAA8B;AAAA;AAAA,IAExC;AAAA,IACA,EAAE,MAAM,OAAO,OAAO,OAAO,QAAQ;AAAA,EACvC;AACA,SAAO;AACT;;;AHpEO,IAAMQ,aAA2C;AAAA,EACtD,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AAAA,IACP,QAAQ,CAAC,EAAE,MAAM,SAAS,UAAU,EAAE,CAAC;AAAA,IACvC,QAAQ,EAAE,UAAUC,WAAU,CAAC,EAAE,QAAQ,EAAE;AAAA,EAC7C;AAAA,EACA,gBAAAC;AAAA,EACA,YAAAC;AAAA,EACA,WAAAC;AACF;;;AIbO,IAAM,QAAQ;AAAA,EACnB,QAAAC;AAAA,EACA,WAAAC;AACF;;;ACJO,IAAMC,cAAoD,YAAY;AAC3E,UAAQ,KAAK,CAAC;AAChB;;;ACEO,IAAM,OAAkC;AAAA,EAC7C,WAAW;AAAA,EACX,SAAS;AAAA,EACT,gBAAgB,MAAM;AAAA,IACpB,UAAU;AAAA,IACV,OAAO,uCAA8B;AAAA,IACrC,UAAU,sBAAkB;AAAA,IAC5B,QAAQ,oCAA0B;AAAA,EACpC,CAAC;AAAA,EACD,YAAY;AAAA,EACZ,WAAAC;AACF;;;ACdO,IAAMC,cAAoD,YAAY;AAC3E,SAAO,aAAa,KAAK,EAAE,MAAM,KAAK,CAAC;AACzC;;;ACDO,IAAMC,QAAkC;AAAA,EAC7C,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,WAAAC;AACF;;;ACLO,IAAMC,cAAwD,OAAO,EAAE,MAAM,MAAM;AACxF,QAAM,EAAE,IAAI,SAAS,KAAK,IAAI;AAC9B,QAAM,KAAS,qBAAqB,WAAW,IAAI,QAAQ,SAAS,IAAI;AACxE,SAAO,aAAa;AACtB;;;ACDO,IAAM,WAA0C;AAAA,EACrD,WAAW;AAAA,EACX,SAAS;AAAA,EACT,gBAAgB,MAAM;AAAA,IACpB,UAAU;AAAA,IACV,QAAQ,8CAA+B;AAAA,IACvC,OAAO,uCAA8B;AAAA,IACrC,UAAU,sBAAkB;AAAA,EAC9B,CAAC;AAAA,EACD,YAAY,OAAM,UAAS;AACzB,UAAM,EAAE,OAAO,OAAO,IAAI;AAC1B,UAAM,EAAE,IAAI,SAAS,KAAK,IAAI;AAC9B,QAAI,OAAO,OAAO,YAAY,OAAO,GAAI,QAAO,cAAc,0DAAkC,OAAO,8BAA8B;AACrI,QAAI,OAAO,YAAY,YAAY,YAAY,GAAI,QAAO,cAAc,0DAAkC,OAAO,mCAAmC;AACpJ,QAAI,OAAO,SAAS,YAAY,SAAS,GAAI,QAAO,cAAc,0DAAkC,OAAO,gCAAgC;AAC3I,UAAM,YAAY,EAAE,IAAI,SAAS,KAAK;AACtC,WAAO,aAAa,KAAK;AAAA,MACvB,MAAM,CAAC;AAAA,MACP,OAAO;AAAA,MACP;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EACA,WAAAC;AACF;;;AC9BA,SAAS,YAAAC,iBAAgB;AACzB,SAAS,gBAAgB;;;ACDzB,SAAS,mBAAAC,yBAAuB;AAChC,SAAS,YAAAC,iBAAgB;AACzB,SAAS,QAAAC,aAAY;AACrB,OAAOC,aAAY;AACnB,SAAS,SAASC,sBAAqB;;;ACJvC,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,mBAAAC,yBAAuB;AAChC,SAAS,cAAc;AAYvB,IAAI,SAAwB;AAG5B,eAAsB,cAA8B;AAClD,QAAM,QAAQC,YAAW,EAAE,MAAM,GAAG,EAAE,GAAG,CAAC,KAAK;AAC/C,QAAM,aAAa,EAAE,kBAAkB,MAAM;AAC7C,MAAI,WAAW,KAAM;AACrB,6BAA0B,sBAAsB,UAAU;AAC1D,WAAS,IAAI,OAAO;AACpB,SAAO,SAAkB,kBAAkB,YAAI,uCAAuC;AACtF,SAAO,aAAa,UAAU;AAC9B,QAAM,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3C,WAAQ,KAAK,SAAS,MAAM;AAC1B,iCAA0B,gBAAgB,UAAU;AACpD,cAAQ;AAAA,IACV,CAAC;AACD,WAAQ,KAAK,SAAS,CAAC,QAAQ;AAC7B,kCAA2B,gBAAgB;AAAA,QACzC,OAAOC,kBAAgB,GAAG;AAAA,QAC1B,kBAAkB;AAAA,MACpB,CAAC;AACD,aAAO,GAAG;AAAA,IACZ,CAAC;AAAA,EACH,CAAC;AACD,QAAM,OAAO,MAAM;AACnB,6BAA0B,kBAAkB,UAAU;AACxD;AAGA,eAAsB,aAAc;AAAE,SAAM,iCAAQ;AAAO;AAE3D,eAAsB,iBACpB,MACA,UACA,UACA,YACA;AACA,MAAI;AACF,UAAM,YAAY;AAClB,WAAQ,OAAO,MAAM,QAAQ;AAC7B,UAAM,OAAQ,MAAM,UAAU,IAAI;AAClC,+BAA0B,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAAA,EACrE,SAAS,KAAK;AACZ;AAAA;AAAA,MAEE;AAAA,MACA,EAAE,OAAOC,kBAAgB,GAAG,EAAE;AAAA,IAChC;AACA,WAAO,OAAM,yCAAa;AAAA,EAC5B;AACF;;;ADjBO,IAAM,aAAa,oBAAI,KAAK;AAEnC,eAAsB,mCAAoC;AACxD,MAAI,YAAI,8CAA8C,QAAS;AAC/D,QAAY;AAAA,IACV,YAAI,iBAAiB,UAAU,YAAI,sBAAsB,YAAI;AAAA,IAC7D,YAAI,iBAAiB,UAAU,YAAI,qBAAqB,YAAI;AAAA,IAC5D,YAAI;AAAA,IACJ,YAAI;AAAA,IACJ,oCAAoC,YAAI,SAAS;AAAA,IACjD,qBAAqB,WAAW,YAAY,CAAC;AAAA;AAAA,EAC/C;AACF;AAQA,IAAI,wBAAwB;AAKrB,SAAS,4BAA6B;AAC3C,UAAQ,GAAG,UAAU,YAAY;AAC/B,QAAI,sBAAuB;AAC3B,4BAAwB;AACxB,wCAA+B,iBAAiB;AAChD,UAAM,SAAS,CAAC;AAAA,EAClB,CAAC;AAED,UAAQ,GAAG,WAAW,YAAY;AAChC,QAAI,sBAAuB;AAC3B,4BAAwB;AACxB,wCAA+B,kBAAkB;AACjD,UAAM,SAAS,CAAC;AAAA,EAClB,CAAC;AACH;AAEA,IAAM,eAAuC;AAAA,EAC3C;AAAA,EACS;AAAA,EACT;AACF;AAMA,eAAsB,mBAAoB;AACxC,QAAM,QAAQ,IAAI,aAAa,IAAI,OAAK,EAAE,CAAC,CAAC;AAC9C;AAEO,IAAM,WAAqB,OAAM,SAAQ;AAC9C,qCAA8B,0BAA0B;AACxD,QAAM,iBAAiB;AACvB,qCAA8B,wBAAwB;AACtD,QAAMC,MAAKC,UAAS,QAAQ,CAAC,EAAE,KAAK,CAAC;AACrC,UAAQ,KAAK,IAAI;AACnB;AAEA,eAAsB,oBAAqB;AAEzC,QAAM,iBAAiB,oBAAoB,aAAa,sBAAsB,YAAY,MAAM,SAAS,CAAC,CAAC;AAC3G,QAAM,iBAAiB,0BAA0B,aAAa,2BAA2B,YAAY,MAAM,SAAS,CAAC,CAAC;AACtH,QAAM,iBAAiB,0CAA0C,aAAa,oCAAoC,YAAY,MAAM,SAAS,CAAC,CAAC;AAC/I,QAAM,iBAAiB,oCAAoC,aAAa,8BAA8B,YAAY,MAAM,SAAS,CAAC,CAAC;AACnI,QAAM,iBAAiB,wCAAwC,aAAa,kCAAkC,YAAY,MAAM,SAAS,CAAC,CAAC;AAC3I,QAAM,iBAAiB,kCAAkC,aAAa,4BAA4B,YAAY,MAAM,SAAS,CAAC,CAAC;AAC/H,QAAM,iBAAiB,iCAAiC,aAAa,2BAA2B,YAAY,MAAM,SAAS,CAAC,CAAC;AAC7H,QAAM,iBAAiB,mCAAmC,aAAa,6BAA6B,YAAY,MAAM,SAAS,CAAC,CAAC;AACjI,QAAM,iBAAiB,wBAAwB,cAAc,uBAA8B,YAAY,MAAM,SAAS,CAAC,CAAC;AACxH,QAAM,iBAAiB,0BAA0B,cAAc,YAAY,MAAM,gBAAoBA,UAAS,QAAQ,CAAC,EAAE,KAAK,CAAC,GAAG,YAAY,MAAM,SAAS,CAAC,CAAC;AACjK;AAQA,eAAsB,uBAAwB;AAC5C,6BAA0B,uBAAuB;AACjD,MAAI;AACF,UAAM,yBAAyB,MAAe;AAAA,MAC5C;AAAA,MACA,EAAE,wBAAoB;AAAA,MACtB,EAAE,aAAa,YAAI,aAAa;AAAA,MAChC,EAAE,OAAO,EAAE;AAAA,IACb;AACA,UAAM,mBAAmB,uBAAuB,UAAU,uBAAuB,QAAQ,QAAQ,CAAC;AAClG,UAAM,uBAAuB,MAAe;AAAA,MAC1C;AAAA,MACA,EAAE,KAAK,YAAI,aAAa;AAAA,MACxB,EAAE,aAAa,YAAI,aAAa;AAAA,MAChC,EAAE,OAAO,EAAE;AAAA,IACb;AACA,UAAM,iBAAiB,qBAAqB,UAAU,qBAAqB,QAAQ,QAAQ,CAAC;AAC5F,UAAM,0BAA0B,CAAC,GAAG,kBAAkB,GAAG,cAAc;AACvE,UAAM,kBAAkB,IAAI,IAAI,wBAAwB,IAAI,SAAO,IAAI,IAAI,SAAS,CAAC,CAAC;AAGtF,QAAI,gBAAgB,SAAS,GAAG;AAC9B,YAAM,cAAc,IAAI,eAAe;AAAA,QACrC,KAAK,IAAIC,eAAc,SAAS,YAAI,YAAY;AAAA,QAChD,UAAU,YAAI;AAAA,QACd,OAAO,YAAI;AAAA,QACX,WAAW,MAAMC,QAAO,KAAK,YAAI,eAAe,EAAE;AAAA,QAClD;AAAA,QACA;AAAA,QACA,QAAQ,CAAC;AAAA,QACT,UAAU;AAAA,MACZ,CAAC;AACD,YAAM,mBAAmB,MAAe;AAAA,QACtC;AAAA,QACA;AAAA,QACA,EAAE,aAAa,YAAI,aAAa;AAAA,MAClC;AACA,UAAI,CAAC,iBAAiB,SAAS;AAC7B;AAAA;AAAA,UAEE;AAAA,UACA,EAAE,OAAO,iBAAiB,MAAM;AAAA,QAClC;AACA,eAAO,MAAM,SAAS,CAAC;AAAA,MACzB;AACA,iCAA0B,mBAAmB;AAC7C;AAAA,IACF;AAGA,QAAI,gBAAgB,OAAO,GAAG;AAC5B,kCAA2B,0CAA0C;AACrE,aAAO,MAAM,SAAS,CAAC;AAAA,IACzB;AAGA,+BAA0B,kBAAkB;AAAA,EAE9C,SAAS,KAAK;AACZ;AAAA;AAAA,MAEE;AAAA,MACA,EAAE,OAAOC,kBAAgB,GAAG,EAAE;AAAA,IAChC;AACA,WAAO,MAAM,SAAS,CAAC;AAAA,EACzB;AACF;AAEA,eAAsB,4BAA6B;AACjD,6BAA0B,6BAA6B;AACvD,MAAI;AACF,UAAM,4BAA4B,MAAe;AAAA,MAC/C;AAAA,MACA,EAAE,KAAK,YAAI,mBAAmB;AAAA,MAC9B,EAAE,aAAa,YAAI,aAAa;AAAA,MAChC,EAAE,OAAO,EAAE;AAAA,IACb;AACA,UAAM,sBAAsB,0BAA0B,UAClD,0BAA0B,QAAQ,QAClC,CAAC;AACL,UAAM;AAAA,MACJ;AAAA,MACA,GAAG;AAAA,IACL,IAAI;AAGJ,QAAI,uBAAuB,QAAW;AACpC,YAAM,mBAAmB,IAAI,eAAe;AAAA,QAC1C,KAAK,IAAIF,eAAc,SAAS,YAAI,kBAAkB;AAAA,QACtD,UAAU,YAAI;AAAA,QACd,OAAO,YAAI;AAAA,QACX,WAAW,MAAMC,QAAO,KAAK,YAAI,qBAAqB,EAAE;AAAA,QACxD;AAAA,QACA;AAAA,QACA,QAAQ,CAAC,GAAG,OAAO,OAAO,SAAS,CAAC;AAAA,QACpC,UAAU;AAAA,MACZ,CAAC;AACD,YAAM,wBAAwB,MAAe;AAAA,QAC3C;AAAA,QACA;AAAA,QACA,EAAE,aAAa,YAAI,aAAa;AAAA,MAClC;AACA,UAAI,CAAC,sBAAsB,SAAS;AAClC;AAAA;AAAA,UAEE;AAAA,UACA,EAAE,OAAO,sBAAsB,MAAM;AAAA,QACvC;AACA,eAAO,MAAM,SAAS,CAAC;AAAA,MACzB;AACA,iCAA0B,yBAAyB;AACnD;AAAA,IACF;AAGA,QAAI,oBAAoB,SAAS,GAAG;AAClC,kCAA2B,gDAAgD;AAC3E,aAAO,MAAM,SAAS,CAAC;AAAA,IACzB;AAIA,UAAM,gBAAgB;AACtB,UAAM,4BAA4B,OAC/B,OAAO,SAAS,EAChB,MAAM,OAAK,cAAc,OAAO,SAAS,CAAC,CAAC;AAC9C,QAAI,CAAC,2BAA2B;AAC9B,oCAA6B,gDAAgD;AAC7E,YAAM,UAAU,MAAe;AAAA,QAC7B;AAAA,QACA,EAAE,KAAK,mBAAmB,IAAI;AAAA,QAC9B,EAAE,QAAQ,CAAC,GAAG,OAAO,OAAO,SAAS,CAAC,EAAE;AAAA,QACxC,EAAE,aAAa,YAAI,aAAa;AAAA,MAClC;AACA,UAAI,QAAQ,QAAS,4BAA0B,gCAAgC;AAAA,WAC1E;AACH,oCAA2B,2CAA2C,EAAE,OAAO,QAAQ,MAAM,CAAC;AAAA,MAChG;AAAA,IACF,MAAO,4BAA0B,gCAAgC;AAEjE,+BAA0B,wBAAwB;AAAA,EAEpD,SAAS,KAAK;AACZ;AAAA;AAAA,MAEE;AAAA,MACA,EAAE,OAAOC,kBAAgB,GAAG,EAAE;AAAA,IAChC;AACA,WAAO,MAAM,SAAS,CAAC;AAAA,EACzB;AACF;AAEA,eAAsB,qCAAsC;AAC1D,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,UAAU,MAAe;AAAA,IAC7B;AAAA,IACA,EAAE,WAAW,EAAE,KAAK,IAAI,EAAE;AAAA,IAC1B,EAAE,aAAa,YAAI,aAAa;AAAA,EAClC;AACA,MAAI,CAAC,QAAQ,WACR,QAAQ,MAAM,8EAA8C;AAC/D;AAAA;AAAA,MAEE;AAAA,MACA,EAAE,OAAO,QAAQ,MAAM;AAAA,IACzB;AACA;AAAA,EACF;AACA,6BAA0B,4CAA4C;AACtE;AACF;AAEA,eAAsB,+BAAgC;AACpD,QAAM,MAAM,KAAK,IAAI;AACrB,QAAM,8BAA8B,YAAI;AACxC,QAAM,yBAAyBH,UAAS,QAAQ,2BAA2B,EAAE,eAAe;AAC5F,QAAM,kCAAkC,IAAI,KAAK,MAAO,yBAAyB,CAAE;AACnF,QAAM,UAAU,MAAe;AAAA,IAC7B;AAAA,IACA,EAAE,WAAW,EAAE,KAAK,gCAAgC,EAAE;AAAA,IACtD,EAAE,aAAa,YAAI,aAAa;AAAA,EAClC;AACA,MAAI,CAAC,QAAQ,WACR,QAAQ,MAAM,8EAA8C;AAC/D;AAAA;AAAA,MAEE;AAAA,MACA,EAAE,OAAO,QAAQ,MAAM;AAAA,IACzB;AACA;AAAA,EACF;AACA,6BAA0B,sCAAsC;AAChE;AACF;AAEA,eAAsB,mCAAoC;AACxD,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,UAAU,MAAe;AAAA,IAC7B;AAAA,IACA,EAAE,WAAW,EAAE,KAAK,IAAI,EAAE;AAAA,IAC1B,EAAE,aAAa,YAAI,aAAa;AAAA,EAClC;AACA,MAAI,CAAC,QAAQ,WACR,QAAQ,MAAM,8EAA8C;AAC/D;AAAA;AAAA,MAEE;AAAA,MACA,EAAE,OAAO,QAAQ,MAAM;AAAA,IACzB;AACA;AAAA,EACF;AACA,6BAA0B,0CAA0C;AACpE;AACF;AAEA,eAAsB,6BAA8B;AAClD,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,UAAU,MAAe;AAAA,IAC7B;AAAA,IACA,EAAE,WAAW,EAAE,KAAK,IAAI,EAAE;AAAA,IAC1B,EAAE,aAAa,YAAI,aAAa;AAAA,EAClC;AACA,MAAI,CAAC,QAAQ,WACR,QAAQ,MAAM,8EAA8C;AAC/D;AAAA;AAAA,MAEE;AAAA,MACA,EAAE,OAAO,QAAQ,MAAM;AAAA,IACzB;AACA;AAAA,EACF;AACA,6BAA0B,oCAAoC;AAC9D;AACF;AAEA,eAAsB,4BAA6B;AACjD,QAAM,UAAU,MAAe;AAAA,IAC7B;AAAA,IACA,CAAC;AAAA,IACD,EAAE,sBAAsB,EAAE;AAAA,IAC1B,EAAE,aAAa,YAAI,aAAa;AAAA,EAClC;AACA,MAAI,CAAC,QAAQ,WACR,QAAQ,MAAM,8EAA8C;AAC/D;AAAA;AAAA,MAEE;AAAA,MACA,EAAE,OAAO,QAAQ,MAAM;AAAA,IACzB;AACA;AAAA,EACF;AACA,6BAA0B,gCAAgC;AAC1D;AACF;AAEA,eAAsB,8BAA+B;AACnD,QAAM,UAAU,MAAe,WAA6B,sBAAsB,CAAC,GAAG,EAAE,wBAAwB,EAAE,GAAG,EAAE,aAAa,YAAI,aAAa,CAAC;AACtJ,MAAI,CAAC,QAAQ,WACR,QAAQ,MAAM,8EAA8C;AAC/D;AAAA;AAAA,MAEE;AAAA,MACA,EAAE,OAAO,QAAQ,MAAM;AAAA,IACzB;AACA;AAAA,EACF;AACA,6BAA0B,kCAAkC;AAC5D;AACF;;;AE7YA,SAAS,UAAAI,eAAc;AACvB,SAAS,WAAW,kBAAuC;AAC3D,SAAS,UAAU,4BAA4B;AAC/C,SAAS,UAAU,kBAAkB;AACrC,OAAO,gBAAgB;AACvB,SAAS,WAAAC,gBAAe;AACxB,SAAS,oBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,mBAAAC,yBAAuB;AAmChC,SAAS,UAAU,oBAAoB;AACvC,SAAS,UAAU,qBAAqB;AACxC,SAAS,UAAU,sBAAsB;AACzC,SAAS,UAAU,sBAAsB;AAEzC,SAAS,QAAQ,kBAAkB;AACnC,SAAS,QAAQ,mBAAmB;AACpC,SAAS,QAAQ,oBAAoB;AACrC,SAAS,QAAQ,oBAAoB;AAErC,SAAS,QAAQ,kBAAkB;AACnC,SAAS,QAAQ,mBAAmB;AACpC,SAAS,QAAQ,oBAAoB;AACrC,SAAS,QAAQ,oBAAoB;AAErC,SAAS,YAAY,sBAAsB;AAC3C,SAAS,YAAY,uBAAuB;AAC5C,SAAS,YAAY,wBAAwB;AAC7C,SAAS,YAAY,wBAAwB;AAE7C,SAAS,UAAU,oBAAoB;AACvC,SAAS,UAAU,qBAAqB;AACxC,SAAS,UAAU,sBAAsB;AACzC,SAAS,UAAU,sBAAsB;AAEzC,SAAS,QAAQ,kBAAkC;AACnD,SAAS,QAAQ,mBAAoC;AACrD,SAAS,QAAQ,oBAAsC;AACvD,SAAS,QAAQ,oBAAsC;AAEvD,SAAS,UAAU,oBAAoB;AACvC,SAAS,UAAU,qBAAqB;AACxC,SAAS,UAAU,sBAAsB;AACzC,SAAS,UAAU,sBAAsB;AAEzC,SAAS,WAAW,iBAAiB;AACrC,SAAS,WAAW,kBAAkB;AACtC,SAAS,WAAW,mBAAmB;AACvC,SAAS,WAAW,mBAAmB;AAEvC,SAAS,WAAW,iBAAiB;AACrC,SAAS,WAAW,kBAAkB;AACtC,SAAS,WAAW,mBAAmB;AACvC,SAAS,WAAW,mBAAmB;AAEvC,SAAS,QAAQ,iBAAiB;AAClC,SAAS,QAAQ,kBAAkB;AACnC,SAAS,QAAQ,mBAAmB;AACpC,SAAS,QAAQ,mBAAmB;AAEpC,SAAS,aAAa,mBAAmB;AACzC,SAAS,aAAa,oBAAoB;AAC1C,SAAS,aAAa,qBAAqB;AAC3C,SAAS,aAAa,qBAAqB;AAQ3C,IAAI;AAEJ,IAAI,YAAI,oBAAoB,OAAO;AACjC,QAAM,YAAY,IAAI,WAAW;AAAA,IAC/B,WAAW,YAAI;AAAA,IACf,aAAa;AAAA,MACX,cAAc,YAAI;AAAA,MAClB,aAAa,YAAI;AAAA,IACnB;AAAA,EACF,CAAC,EAAE,OAAO,YAAI,0BAA0B;AACxC,YAAU;AACZ,WAAW,YAAI,oBAAoB,OAAO;AACxC,QAAM,YAAY;AAAA,IAChB,YAAY,YAAI;AAAA,IAChB,QAAQ,IAAI,SAAS;AAAA,MACnB,QAAQ,YAAI;AAAA,MACZ,aAAa;AAAA,QACX,aAAa,YAAI;AAAA,QACjB,iBAAiB,YAAI;AAAA,MACvB;AAAA,IACF,CAAC;AAAA,EACH;AACA,YAAU;AACZ,WAAW,YAAI,oBAAoB,QAAQ;AACzC,QAAM,YAAY,IAAI,WAAW;AACjC,YAAU;AACZ,OAAO;AACL,QAAM,aAAa,IAAI,WAAW;AAClC,YAAU;AACZ;AAEO,IAAM,YAAuB,YAAY;AAC9C,MAAI,YAAY,OAAO,EAAG,QAAOC,SAAQ,YAAY,OAAO;AAC5D,MAAI,qBAAqB,OAAO,EAAG,QAAOA,SAAQ,YAAY,OAAO;AACrE,MAAI,YAAY,OAAO,KAAK,YAAI,oBAAoB,QAAQ;AAC1D,QAAI;AACF,YAAM,QAAQ,KAAK,MAAM;AACzB,aAAOA,SAAQ,YAAY,OAAO;AAAA,IACpC,QAAQ;AACN,UAAI;AACF,cAAM,QAAQ,OAAO;AAAA,UACnB,MAAM,YAAI;AAAA,UACV,MAAM,OAAO,YAAI,mBAAmB;AAAA,UACpC,MAAM,YAAI;AAAA,UACV,UAAU,YAAI;AAAA,UACd,QAAQ;AAAA,QACV,CAAC;AACD,eAAOA,SAAQ,YAAY,OAAO;AAAA,MACpC,SAAS,KAAK;AACZ,eAAOA,SAAQ,YAAYC,kBAAgB,GAAG,CAAC;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AACA,MAAI,aAAa,OAAO,KAAK,YAAI,oBAAoB,QAAQ;AAC3D,QAAI;AACF,YAAM,QAAQ,KAAK,GAAG;AACtB,aAAOD,SAAQ,YAAY,OAAO;AAAA,IACpC,SAAS,KAAK;AACZ,UAAI;AACF,cAAM,QAAQ,QAAQ;AAAA,UACpB,MAAM,YAAI;AAAA,UACV,MAAM,OAAO,YAAI,mBAAmB;AAAA,UACpC,UAAU,YAAI;AAAA,UACd,UAAU,YAAI;AAAA;AAAA;AAAA,QAGhB,CAAC;AACD,eAAOA,SAAQ,YAAY,OAAO;AAAA,MACpC,SAASE,MAAK;AACZ,eAAOF,SAAQ,YAAYC,kBAAgBC,IAAG,CAAC;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AAGA,SAAOF,SAAQ,YAAY,yBAAyB;AAEtD;AAQA,eAAsBG,QAAgD;AACpE,QAAM,eAAe,MAAM,UAAU;AACrC,MAAI,CAAC,aAAa,QAAS,QAAOH,SAAQ,YAAY,aAAa,KAAK;AACxE,QAAM,SAAS,aAAa;AAC5B,QAAMI,SAAQC,QAAO;AACrB,MAAI;AACF,QAAI,YAAY,MAAM,EAAG,OAAM,OAAO,SAAS;AAAA,MAC7C,YAAY;AAAA,IACd,CAAC;AAAA,aACQ,qBAAqB,MAAM,EAAG,OAAM,OAAO,OAAO,KAAK,IAAI,qBAAqB;AAAA,MACvF,QAAQ,OAAO;AAAA,MACf,SAAS;AAAA,IACX,CAAC,CAAC;AAAA,aACO,YAAY,MAAM,GAAG;AAC5B,UAAI,OAAO,OAAQ,QAAOL,SAAQ,YAAY,uBAAuB;AACrE,YAAM,OAAO,KAAK,GAAG;AAAA,IACvB,WAAW,kBAAkB,WAAY,OAAM,OAAO,KAAK,GAAG;AAAA,QACzD,QAAOA,SAAQ,YAAY,qBAAqB;AACrD,UAAM,OAAOK,QAAOD,MAAK;AACzB,UAAM,aAAc,KAAK,CAAC,IAAI,MAAQ,KAAK,CAAC,IAAI;AAChD,WAAOJ,SAAQ,YAAY,UAAU;AAAA,EACvC,SAAS,KAAK;AACZ,WAAOA,SAAQ,YAAYC,kBAAgB,GAAG,CAAC;AAAA,EACjD;AACF;;;AHhNA,IAAI,aAA4B;AAChC,IAAI,aAA4B;AAChC,IAAI,iBAAgC;AAEpC,IAAM,kBAAkB,SAAS,YAAW;AAC1C,QAAM,SAAS,MAAM,KAAO;AAC5B,gBAAa,iCAAQ,WAAU,OAAO,UAAU;AAChD,SAAO;AACT,GAAGK,UAAS,QAAQ,EAAE,EAAE,KAAK,CAAC,EAAE;AAChC,IAAM,kBAAkB,SAAS,YAAW;AAC1C,QAAM,SAAS,MAAMC,MAAO;AAC5B,gBAAa,iCAAQ,WAAU,OAAO,UAAU;AAChD,SAAO;AACT,GAAGD,UAAS,QAAQ,EAAE,EAAE,KAAK,CAAC,EAAE;AAChC,IAAM,sBAAsB,SAAS,YAAW;AAC9C,QAAM,SAAS,MAAM,YAAY;AACjC,oBAAiB,iCAAQ,WAAU,OAAO,UAAU;AACpD,SAAO;AACT,GAAGA,UAAS,QAAQ,EAAE,EAAE,KAAK,CAAC,EAAE;AAEzB,IAAME,cAA2D,YAAY;AAClF,QAAM,MAAM,oBAAI,KAAK;AACrB,QAAM,gBAAgB,KAAK,OAAO,IAAI,QAAQ,IAAI,WAAW,QAAQ,KAAK,GAAI;AAC9E,QAAM,SAAS,YAAI;AACnB,kBAAgB;AAChB,kBAAgB;AAChB,sBAAoB;AACpB,QAAM,YAAY,eAAe,QAC5B,eAAe,QACf,mBAAmB;AACxB,SAAO,aAAa,KAAK;AAAA,IACvB;AAAA,IACA,SAAS,YAAI;AAAA,IACb,YAAY,WAAW,YAAY;AAAA,IACnC;AAAA,IACA,UAAU;AAAA,MACR,WAAW,eAAe;AAAA,MAC1B,QAAQ,KAAK,OAAO,cAAc,YAAY,EAAE,IAAI;AAAA,IACtD;AAAA,IACA,IAAI;AAAA,MACF,MAAM;AAAA,MACN,WAAW,eAAe;AAAA,MAC1B,QAAQ,KAAK,OAAO,cAAc,YAAY,EAAE,IAAI;AAAA,IACtD;AAAA,IACA,QAAQ;AAAA,MACN,WAAW,mBAAmB;AAAA,MAC9B,QAAQ,KAAK,OAAO,kBAAkB,YAAY,EAAE,IAAI;AAAA,IAC1D;AAAA,EACF,CAAC;AACH;;;AIxDO,IAAM,cAAgD;AAAA,EAC3D,WAAW;AAAA,EACX,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,WAAAC;AACF;;;ACJO,IAAM,SAAS;AAAA,EACpB;AAAA,EACA,MAAAC;AAAA,EACA;AAAA,EACA;AACF;;;ACFO,IAAM,SAAoB;AAAA;AAAA,EAE/B,2CAAwB,GAAGC,MAAK;AAAA;AAAA,EAGhC,qCAAqB,GAAG,OAAO;AAAA,EAC/B,qCAAqB,GAAG,OAAO;AAAA,EAC/B,+CAA0B,GAAG,OAAO;AAAA,EACpC,yDAAiC,GAAG,OAAO;AAAA,EAC3C,2DAAkC,GAAG,OAAO;AAAA;AAAA,EAG5C,oCAAoB,GAAG,KAAK;AAAA,EAC5B,sCAAqB,GAAG,KAAK;AAAA,EAC7B,4DAAgC,GAAG,KAAK;AAAA,EACxC,oDAA4B,GAAG,KAAK;AAAA,EACpC,0FAA+C,GAAG,KAAK;AAAA,EACvD,kEAAmC,GAAG,KAAK;AAAA,EAC3C,sCAAqB,GAAG,KAAK;AAAA,EAC7B,gEAAkC,GAAG,KAAK;AAAA,EAC1C,kDAA2B,GAAG,KAAK;AAAA,EACnC,sCAAqB,GAAG,KAAK;AAAA,EAC7B,yCAAyB,GAAG,KAAK;AAAA;AAAA,EAGjC,gDAA0B,GAAG,MAAM,KAAK;AAAA,EACxC,oDAA4B,GAAG,MAAM,MAAM;AAAA,EAC3C,8CAAyB,GAAG,MAAM,MAAM;AAAA,EACxC,gDAA0B,GAAG,MAAM,MAAM;AAAA,EACzC,oDAA4B,GAAG,MAAM,MAAM;AAAA,EAC3C,oDAA4B,GAAG,MAAM,MAAM;AAAA,EAC3C,4EAAwC,GAAG,MAAM,MAAM;AAAA,EACvD,oGAAoD,GAAG,MAAM,MAAM;AAAA,EACnE,oGAAoD,GAAG,MAAM,MAAM;AAAA,EACnE,wEAAsC,GAAG,MAAM,MAAM;AAAA,EACrD,4EAAwC,GAAG,MAAM,MAAM;AAAA;AAAA,EAGvD,wCAAsB,GAAG,MAAM;AAAA,EAC/B,8CAAyB,GAAG,MAAM;AACpC;AAEO,IAAM,SAAS,WAAW,MAAM;;;ACxCvC,eAAsB,KAAM,KAA+B;AAGzD,QAAM,aAAwC,CAAC;AAG/C,QAAMC,UAA0B,CAAC;AACjC,QAAMC,UAAS,WAAWD,OAAM;AAChC,MAAI,IAAIC,OAAM;AAGd,QAAM,QAAQ,WAAW,IAAI,YAAU,OAAO,KAAK,EAAE,KAAK;AAC1D,QAAM,QAAQ,UAAQ;AAAA,IACpB,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EACP,CAAC;AAED,SAAOA;AACT;;;ACvBO,SAAS,yBAA0B;AACxC,MAAI,YAAI,eAAe,OAAQ,6BAA4B,gCAAgC;AAAA,MACtF,0BAAyB,kCAAkC;AAChE,SAAO,SACL,KACA,KACA,MACA;AACA,QAAI,IAAI,IAAI,eAAe,IAAI;AAC/B,QAAI,YAAI,eAAe,OAAQ,MAAK;AAAA,aAC3B,IAAI,aAAa,QAAS,MAAK;AAAA,SACnC;AACH,YAAM,EAAE,KAAK,QAAQ,MAAAC,OAAM,SAAS,IAAI;AACxC,kCAA4B,mCAAmC,EAAE,UAAU,QAAQ,MAAAA,OAAM,IAAI,CAAC;AAC9F,8BAAwB,KAAK,cAAc,0CAAyB,CAAC;AAAA,IACvE;AAAA,EACF;AACF;;;ACxBA,OAAO,UAAU;AAIV,IAAM,iBAAiB,KAAK;AAAA,EACjC,QAAQ,YAAI;AAAA,EACZ,aAAa;AAAA,EACb,gBAAgB,CAAC,iBAAiB,gBAAgB,cAAc;AAAA,EAChE,gBAAgB,CAAC,iBAAiB;AACpC,CAAC;;;ACTD,OAAO,UAAU;AACjB,OAAO,iBAAiB;AAYjB,SAAS,MAAO,KAAc;AACnC,QAAM,OAAO,cAAc,YAAI,IAAI;AACnC,QAAM,QAAQ,YAAY,qBAAqB;AAC/C,QAAM,SAAS,KAAK,aAAa,GAAG;AACpC,MAAI,IAAI,QAAQ,IAAI;AACpB,SAAO,OAAO,EAAE,MAAY,MAAM,UAAU,CAAC;AAC7C,SAAO,GAAG,SAAS,CAAC,UAAqB;AACvC,QAAI,MAAM,YAAY,SAAU,OAAM;AACtC,QAAI,OAAO,OAAO,SAAS,WAAW,UAAU,OAAO,UAAU;AACjE,YAAQ,MAAM,MAAM;AAAA,MAClB,KAAK;AACH,kCAA0B,GAAG,IAAI,+BAA+B;AAChE,eAAO,SAAS,CAAC;AAAA,MACnB,KAAK;AACH,kCAA0B,GAAG,IAAI,oBAAoB;AACrD,eAAO,SAAS,CAAC;AAAA,MACnB;AACE,cAAM;AAAA,IACV;AAAA,EACF,CAAC;AACD,SAAO,GAAG,aAAa,MAAM;AAC3B,QAAI,OAAO,OAAO,QAAQ;AAC1B,QAAI,OAAO,OAAO,SAAS,WAAW,UAAU,OAAO,YAAW,6BAAM,SAAQ;AAChF,UAAM,kBAAkB,IAAI;AAC5B,6BAAyB,kBAAkB,IAAI;AAAA,EACjD,CAAC;AAED,WAAS,cAAe,KAAa;AACnC,QAAIC,QAAO,SAAS,KAAK,EAAE;AAC3B,QAAI,MAAMA,KAAI,EAAG,QAAO;AACxB,QAAIA,SAAQ,EAAG,QAAOA;AACtB,WAAO;AAAA,EACT;AACF;;;AlI7BA,eAAsB,QAAS;AAC7B,6BAA0B,oBAAoB;AAG9C,EAAK,0BAA0B;AAG/B,QAAM,kBAAkB,MAAe,mBAAmB,GAAGC,UAAS,QAAQ,CAAC,EAAE,KAAK,CAAC;AACvF,MAAI,CAAC,gBAAgB,QAAS,CAAK,SAAS,CAAC;AAC7C,QAAW,kBAAkB;AAC7B,QAAW,qBAAqB;AAChC,QAAW,0BAA0B;AAGrC,QAAM,MAAM,QAAQ;AACpB,MAAI,IAAI,cAAc;AACtB,MAAI,IAAI,oBAAoB;AAC5B,MAAI,IAAI,QAAQ,KAAK,CAAC;AACtB,MAAI,IAAI,QAAQ,WAAW,EAAE,UAAU,MAAM,CAAC,CAAC;AAC/C,MAAI,IAAI,aAAa,CAAC;AAGtB,MAAI,IAAQ,uBAAuB,CAAC;AACpC,MAAI,IAAa,qBAAqB;AACtC,MAAI,IAAS,sBAAsB;AAGnC,MAAI,IAAQ,MAAM;AAGlB,QAAc,KAAK,GAAG;AAGtB,QAAM,OAAOC,MAAK,QAAQ,cAAc,YAAY,GAAG,CAAC;AACxD,QAAM,SAASA,MAAK,KAAK,MAAM,QAAQ;AACvC,MAAI,IAAI,QAAQ,OAAO,MAAM,CAAC;AAG9B,MAAI,IAAa,oBAAoB;AACrC,MAAI,IAAa,kBAAkB;AAEnC,QAAM,GAAG;AAGT,EAAK,iCAAiC;AACxC;",
|
6
|
+
"names": ["path", "Duration", "hrtime", "Readable", "randomUUID", "unknownToString", "mebibytes", "Outcome", "Duration", "unknownToString", "MongooseTypes", "Outcome", "Codes", "collectionName", "tokens", "Outcome", "start", "update", "Outcome", "unknownToString", "Outcome", "unknownToString", "MongooseSchema", "UserRole", "UserStatus", "UserBadge", "unknownToString", "compressed", "unknownToString", "MongooseTypes", "MongooseSchema", "MongooseSchema", "MongooseTypes", "unknownToString", "update", "MongooseSchema", "MongooseSchema", "MongooseSchema", "mongooseModel", "collectionName", "MongooseSchema", "mongooseModel", "MongooseSchema", "mongooseModel", "collectionName", "MongooseSchema", "mongooseModel", "MongooseSchema", "mongooseModel", "collectionName", "MongooseSchema", "mongooseModel", "collectionName", "unknownToString", "MongooseTypes", "Outcome", "admin", "tokens", "Duration", "Outcome", "Outcome", "fs", "path", "Readable", "Outcome", "unknownToString", "MongooseTypes", "MongooseSchema", "mongooseModel", "MongooseTypes", "collectionName", "MongooseSchema", "MongooseTypes", "mongooseModel", "randomUUID", "randomUUID", "hrtime", "Outcome", "unknownToString", "auth", "Outcome", "unknownToString", "start", "hrtime", "path", "fs", "Outcome", "Readable", "unknownToString", "MongooseTypes", "hrtime", "randomUUID", "errorResponse", "jsonResponse", "listResponse", "fileResponse", "Readable", "unknownToString", "files", "mebibytes", "path", "params", "validation", "operation", "authentication", "router", "response", "flush", "flush", "authentication", "insertionAttempt", "code", "message", "operation", "unknownToString", "unknownToString", "authentication", "operation", "authentication", "silentOperation", "operation", "unknownToString", "zod", "validation", "zod", "unknownToString", "authentication", "validation", "operation", "authentication", "silentOperation", "operation", "unknownToString", "zod", "validation", "zod", "unknownToString", "authentication", "validation", "operation", "authentication", "operation", "unknownToString", "zod", "validation", "zod", "unknownToString", "authentication", "validation", "operation", "authentication", "silentOperation", "operation", "unknownToString", "zod", "validation", "zod", "unknownToString", "authentication", "validation", "operation", "authentication", "operation", "unknownToString", "zod", "validation", "zod", "unknownToString", "authentication", "validation", "operation", "authentication", "silentOperation", "code", "message", "userId", "operation", "unknownToString", "zod", "validation", "zod", "unknownToString", "authentication", "validation", "operation", "authentication", "operation", "unknownToString", "zod", "validation", "zod", "unknownToString", "authentication", "validation", "operation", "authentication", "operation", "unknownToString", "zod", "validation", "zod", "unknownToString", "authentication", "validation", "operation", "authentication", "bcrypt", "silentOperation", "bcrypt", "operation", "unknownToString", "zod", "validation", "zod", "unknownToString", "authentication", "validation", "operation", "unknownToString", "isNonNullObject", "validator", "zod", "validation", "isNonNullObject", "zod", "unknownToString", "validator", "bcrypt", "silentOperation", "bcrypt", "refreshToken", "operation", "validation", "operation", "authentication", "jwt", "silentOperation", "jwt", "operation", "authentication", "operation", "authentication", "silentOperation", "operation", "authentication", "operation", "jwt", "silentOperation", "jwt", "operation", "operation", "unknownToString", "zod", "validation", "zod", "unknownToString", "silentOperation", "operation", "validation", "operation", "unknownToString", "zod", "validation", "zod", "unknownToString", "silentOperation", "operation", "validation", "operation", "unknownToString", "validator", "zod", "validation", "zod", "validator", "unknownToString", "bcrypt", "silentOperation", "bcrypt", "operation", "validation", "operation", "unknownToString", "zod", "validation", "zod", "unknownToString", "bcrypt", "silentOperation", "bcrypt", "operation", "validation", "operation", "unknownToString", "zod", "validation", "zod", "unknownToString", "silentOperation", "operation", "validation", "operation", "authentication", "silentOperation", "operation", "authentication", "operation", "Duration", "operation", "Duration", "operation", "csrf", "mebibytes", "authentication", "isNonNullObject", "validation", "image", "format", "createReadStream", "unknownToString", "silentOperation", "createReadStream", "unknownToString", "operation", "format", "mebibytes", "authentication", "validation", "operation", "mebibytes", "authentication", "isNonNullObject", "validation", "image", "createReadStream", "toBuffer", "unknownToString", "Duration", "fileTypeFromBuffer", "silentOperation", "image", "toBuffer", "createReadStream", "Duration", "fileTypeFromBuffer", "unknownToString", "operation", "transform", "mebibytes", "authentication", "validation", "operation", "format", "transform", "operation", "operation", "operation", "ping", "operation", "operation", "operation", "Duration", "unknownToString", "Duration", "wait", "bcrypt", "MongooseTypes", "randomUUID", "unknownToString", "randomUUID", "unknownToString", "unknownToString", "wait", "Duration", "MongooseTypes", "bcrypt", "unknownToString", "hrtime", "Outcome", "unknownToString", "Outcome", "unknownToString", "err", "ping", "start", "hrtime", "Duration", "ping", "operation", "operation", "ping", "csrf", "ROUTES", "router", "path", "port", "Duration", "path"]
|
7
|
+
}
|