├── .npmrc ├── src ├── index.ts ├── main.ts ├── lib │ ├── index.ts │ ├── diagnostic.ts │ ├── rule.ts │ ├── parser.ts │ ├── output.ts │ ├── traversal.ts │ └── linter.ts ├── rules │ ├── s21-structural-no-goto.ts │ ├── s21-structural-indentation-limit.ts │ ├── s21-structural-function-line-limit.ts │ ├── index.ts │ ├── s21-structural-no-multiple-returns.ts │ ├── s21-structural-no-global-variables.ts │ └── s21-structural-no-multiple-loop-exits.ts └── cli │ └── index.ts ├── languages ├── tree-sitter-c.wasm └── tree-sitter-cpp.wasm ├── typings └── languages.d.ts ├── .editorconfig ├── tsconfig.json ├── tsup.config.ts ├── readme.md ├── biome.json ├── package.json ├── .gitignore └── pnpm-lock.yaml /.npmrc: -------------------------------------------------------------------------------- 1 | preid=dev 2 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./lib" 2 | export * from "./rules" 3 | -------------------------------------------------------------------------------- /languages/tree-sitter-c.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s21toolkit/s21lint/HEAD/languages/tree-sitter-c.wasm -------------------------------------------------------------------------------- /languages/tree-sitter-cpp.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/s21toolkit/s21lint/HEAD/languages/tree-sitter-cpp.wasm -------------------------------------------------------------------------------- /typings/languages.d.ts: -------------------------------------------------------------------------------- 1 | declare module "*.wasm" { 2 | const source: Uint8Array 3 | 4 | export default source 5 | } 6 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { s21lintCommand } from "@/cli" 4 | import { binary, run } from "cmd-ts" 5 | 6 | run(binary(s21lintCommand), process.argv) 7 | -------------------------------------------------------------------------------- /src/lib/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./diagnostic" 2 | export * from "./linter" 3 | export * from "./output" 4 | export * from "./parser" 5 | export * from "./rule" 6 | export * from "./traversal" 7 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | [*] 2 | charset = utf-8 3 | end_of_line = lf 4 | 5 | insert_final_newline = true 6 | trim_trailing_whitespace = true 7 | 8 | indent_style = tab 9 | tab_width = 3 10 | 11 | [*.{yml,yaml}] 12 | indent_style = space 13 | indent_size = 2 14 | 15 | [*.{md}] 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /src/lib/diagnostic.ts: -------------------------------------------------------------------------------- 1 | import type Parser from "web-tree-sitter" 2 | import type { Rule } from "./rule" 3 | 4 | export namespace Diagnostic { 5 | export type Severity = "warning" | "error" 6 | } 7 | 8 | export type Diagnostic = { 9 | reporter: Rule 10 | 11 | severity: Diagnostic.Severity 12 | 13 | node: Parser.SyntaxNode 14 | 15 | message: string 16 | } 17 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "@tsconfig/node20/tsconfig.json", 4 | "@tsconfig/strictest/tsconfig.json" 5 | ], 6 | "compilerOptions": { 7 | "module": "ESNext", 8 | "moduleResolution": "Bundler", 9 | "noEmit": true, 10 | "declaration": false, 11 | 12 | "baseUrl": ".", 13 | "paths": { 14 | "@/*": ["./src/*"], 15 | "@languages/*": ["./languages/*"] 16 | } 17 | }, 18 | "exclude": ["build"] 19 | } 20 | -------------------------------------------------------------------------------- /src/rules/s21-structural-no-goto.ts: -------------------------------------------------------------------------------- 1 | import { defineRule } from "@/lib" 2 | 3 | export const s21StructuralNoGoto = defineRule({ 4 | name: "s21-structural-no-goto", 5 | 6 | check(ctx) { 7 | const gotoStatements = ctx.language 8 | .query("(goto_statement) @goto") 9 | .captures(ctx.node) 10 | 11 | for (const gotoStatement of gotoStatements) { 12 | ctx.error(gotoStatement.node, "goto statement is forbidden") 13 | } 14 | }, 15 | }) 16 | -------------------------------------------------------------------------------- /tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { type Options, defineConfig } from "tsup" 2 | 3 | const baseConfig = { 4 | clean: true, 5 | bundle: true, 6 | outDir: "build", 7 | loader: { 8 | ".wasm": "binary", 9 | }, 10 | } satisfies Options 11 | 12 | export default defineConfig([ 13 | { 14 | ...baseConfig, 15 | entry: ["src/main.ts"], 16 | format: "esm", 17 | target: "node20", 18 | }, 19 | { 20 | ...baseConfig, 21 | entry: ["src/index.ts"], 22 | format: ["esm", "cjs"], 23 | dts: true, 24 | }, 25 | ]) 26 | -------------------------------------------------------------------------------- /src/lib/rule.ts: -------------------------------------------------------------------------------- 1 | import type Parser from "web-tree-sitter" 2 | 3 | export type FilterContext = { 4 | node: Parser.SyntaxNode 5 | tree: Parser.Tree 6 | language: Parser.Language 7 | } 8 | 9 | export type CheckContext = FilterContext & { 10 | warn: (node: Parser.SyntaxNode, message: string) => void 11 | error: (node: Parser.SyntaxNode, message: string) => void 12 | } 13 | 14 | export type Rule = { 15 | name: string 16 | 17 | filter?: (context: FilterContext) => boolean 18 | 19 | check: (context: CheckContext) => void 20 | } 21 | 22 | export function defineRule(rule: Rule): Rule { 23 | return rule 24 | } 25 | -------------------------------------------------------------------------------- /src/rules/s21-structural-indentation-limit.ts: -------------------------------------------------------------------------------- 1 | import { defineRule, traverse } from "@/lib" 2 | 3 | const INDENTATION_LIMIT = 4 4 | 5 | export const s21StructuralIndentationLimit = defineRule({ 6 | name: "s21-structural-indentation-limit", 7 | 8 | check(ctx) { 9 | let currentIndentation = 0 10 | 11 | traverse(ctx.tree, { 12 | compound_statement: { 13 | enter(node) { 14 | currentIndentation++ 15 | 16 | if (currentIndentation > INDENTATION_LIMIT) { 17 | ctx.error( 18 | node, 19 | `code blocks must not exceed ${INDENTATION_LIMIT} indentation levels`, 20 | ) 21 | } 22 | }, 23 | leave() { 24 | currentIndentation-- 25 | }, 26 | }, 27 | }) 28 | }, 29 | }) 30 | -------------------------------------------------------------------------------- /src/rules/s21-structural-function-line-limit.ts: -------------------------------------------------------------------------------- 1 | import { defineRule } from "@/lib" 2 | 3 | const FUNCTION_BODY_LINE_LIMIT = 50 4 | 5 | export const s21StructuralFunctionLineLimit = defineRule({ 6 | name: "s21-structural-function-line-limit", 7 | 8 | check(ctx) { 9 | const functionBodies = ctx.language 10 | .query("(function_definition body: _ @body)") 11 | .captures(ctx.node) 12 | 13 | for (const functionBody of functionBodies) { 14 | const { startPosition, endPosition } = functionBody.node 15 | 16 | const lineCount = endPosition.row - startPosition.row 17 | if (lineCount > FUNCTION_BODY_LINE_LIMIT) { 18 | ctx.error( 19 | functionBody.node, 20 | `function body must not exceed ${FUNCTION_BODY_LINE_LIMIT} lines`, 21 | ) 22 | } 23 | } 24 | }, 25 | }) 26 | -------------------------------------------------------------------------------- /src/lib/parser.ts: -------------------------------------------------------------------------------- 1 | import c from "@languages/tree-sitter-c.wasm" 2 | import cpp from "@languages/tree-sitter-cpp.wasm" 3 | import Parser from "web-tree-sitter" 4 | 5 | async function loadLanguages() { 6 | const languages = { 7 | c: await Parser.Language.load(c), 8 | cpp: await Parser.Language.load(cpp), 9 | } 10 | 11 | return languages 12 | } 13 | 14 | export type Language = keyof Awaited> 15 | 16 | let languages: Awaited> | undefined 17 | 18 | export async function createParser(language: Language) { 19 | await Parser.init() 20 | 21 | const parser = new Parser() 22 | 23 | if (!languages) { 24 | languages = await loadLanguages() 25 | } 26 | 27 | parser.setLanguage(languages[language]) 28 | 29 | return parser 30 | } 31 | -------------------------------------------------------------------------------- /src/lib/output.ts: -------------------------------------------------------------------------------- 1 | import chalk from "chalk" 2 | import { stripIndent } from "common-tags" 3 | import type { Diagnostic } from "./diagnostic" 4 | 5 | export function printDiagnostic( 6 | filename: string, 7 | source: string, 8 | diagnostic: Diagnostic, 9 | ) { 10 | const { node, message, severity, reporter } = diagnostic 11 | 12 | const { row, column } = node.startPosition 13 | 14 | const line = source.split("\n")[row] 15 | 16 | const lineNumberPrefix = `${row + 1}: ` 17 | 18 | const columnPointerOffset = " ".repeat(column + lineNumberPrefix.length) 19 | 20 | const messageColor = severity === "error" ? chalk.red : chalk.yellow 21 | 22 | const severityTag = messageColor(`[${severity}]`) 23 | const location = chalk.blue(`${filename}:${row + 1}:${column + 1}`) 24 | 25 | console.log(stripIndent` 26 | ${severityTag} ${location} (${reporter.name}) 27 | ${lineNumberPrefix}${chalk.gray(line)} 28 | ${columnPointerOffset}${messageColor(`^--- ${message}`)} 29 | `) 30 | } 31 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # s21lint 2 | 3 | Программа для статической проверки C/C++ кода на соответствие требованиям к проектам школы 21. 4 | 5 | Это консольная утилита, вместо неё можно использовать [расширение на VSCode](https://github.com/s21toolkit/s21lint-vscode). 6 | 7 | ## Установка 8 | 9 | ```sh 10 | npm install --global @s21toolkit/lint 11 | ``` 12 | 13 | ## Использование 14 | 15 | ```sh 16 | s21lint program.c 17 | s21lint foo.c bar.c 18 | s21lint *.c 19 | s21lint "**.c" 20 | s21lint "src/**.c" "include/**.h" 21 | ``` 22 | 23 | ## Поддерживаемые правила 24 | 25 | - Структурное программирование 26 | - `s21-structural-function-line-limit` 27 | - Лимит количества строк в функции (50) 28 | - `s21-structural-indentation-limit` 29 | - Лимит отступа для блоков (4) 30 | - `s21-structural-no-global-variables` 31 | - Запрет использования глобальных переменных 32 | - `s21-structural-no-goto` 33 | - Запрет использования goto 34 | - `s21-structural-no-multiple-loop-exits` 35 | - Запрет нескольких выходов (break/return) в одном цикле 36 | - `s21-structural-no-multiple-returns` 37 | - Предупреждение о нескольких возвратах из функции 38 | -------------------------------------------------------------------------------- /biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "node_modules/@biomejs/biome/configuration_schema.json", 3 | "organizeImports": { 4 | "enabled": true 5 | }, 6 | "files": { 7 | "ignore": ["build", "package.json", "pnpm-lock.yaml"] 8 | }, 9 | "linter": { 10 | "enabled": true, 11 | "rules": { 12 | "recommended": true, 13 | "suspicious": { 14 | "noImplicitAnyLet": "off" 15 | } 16 | } 17 | }, 18 | "formatter": { 19 | "enabled": true, 20 | "indentStyle": "tab", 21 | "indentWidth": 3, 22 | "lineEnding": "lf" 23 | }, 24 | "javascript": { 25 | "parser": { 26 | "unsafeParameterDecoratorsEnabled": true 27 | }, 28 | "formatter": { 29 | "enabled": true, 30 | "arrowParentheses": "always", 31 | "bracketSameLine": true, 32 | "bracketSpacing": true, 33 | "jsxQuoteStyle": "double", 34 | "quoteStyle": "double", 35 | "lineWidth": 80, 36 | "quoteProperties": "preserve", 37 | "trailingComma": "all", 38 | "semicolons": "asNeeded" 39 | } 40 | }, 41 | "json": { 42 | "parser": { 43 | "allowComments": true, 44 | "allowTrailingCommas": true 45 | }, 46 | "formatter": { 47 | "enabled": true 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/rules/index.ts: -------------------------------------------------------------------------------- 1 | import type { Rule } from "@/lib" 2 | import { s21StructuralFunctionLineLimit } from "./s21-structural-function-line-limit" 3 | import { s21StructuralIndentationLimit } from "./s21-structural-indentation-limit" 4 | import { s21StructuralNoGlobalVariables } from "./s21-structural-no-global-variables" 5 | import { s21StructuralNoGoto } from "./s21-structural-no-goto" 6 | import { s21StructuralNoMultipleLoopExits } from "./s21-structural-no-multiple-loop-exits" 7 | import { s21StructuralNoMultipleReturns } from "./s21-structural-no-multiple-returns" 8 | 9 | export const rules = [ 10 | s21StructuralNoGoto, 11 | s21StructuralFunctionLineLimit, 12 | s21StructuralIndentationLimit, 13 | s21StructuralNoGlobalVariables, 14 | s21StructuralNoMultipleReturns, 15 | s21StructuralNoMultipleLoopExits, 16 | ] satisfies Rule[] 17 | 18 | export * from "./s21-structural-function-line-limit" 19 | export * from "./s21-structural-indentation-limit" 20 | export * from "./s21-structural-no-global-variables" 21 | export * from "./s21-structural-no-goto" 22 | export * from "./s21-structural-no-multiple-loop-exits" 23 | export * from "./s21-structural-no-multiple-returns" 24 | -------------------------------------------------------------------------------- /src/rules/s21-structural-no-multiple-returns.ts: -------------------------------------------------------------------------------- 1 | import { defineRule, traverse } from "@/lib" 2 | import type { SyntaxNode } from "web-tree-sitter" 3 | 4 | export const s21StructuralNoMultipleReturns = defineRule({ 5 | name: "s21-structural-no-multiple-returns", 6 | 7 | check(ctx) { 8 | const returnStatements: SyntaxNode[][] = [] 9 | 10 | const functionVisitor = { 11 | enter() { 12 | returnStatements.push([]) 13 | }, 14 | leave() { 15 | const top = returnStatements.pop() 16 | 17 | if (!top || top.length <= 1) { 18 | return 19 | } 20 | 21 | // Emit warnings since we can't be sure that all return statements are used correctly 22 | for (const node of top) { 23 | ctx.warn( 24 | node, 25 | "multiple return statements are only allowed for argument validation", 26 | ) 27 | } 28 | }, 29 | } 30 | 31 | traverse(ctx.tree, { 32 | function_definition: functionVisitor, 33 | lambda_expression: functionVisitor, 34 | return_statement(node) { 35 | const top = returnStatements.at(-1) 36 | 37 | if (!top) { 38 | return 39 | } 40 | 41 | top.push(node) 42 | }, 43 | }) 44 | }, 45 | }) 46 | -------------------------------------------------------------------------------- /src/rules/s21-structural-no-global-variables.ts: -------------------------------------------------------------------------------- 1 | import { defineRule } from "@/lib" 2 | import { oneLine } from "common-tags" 3 | 4 | const GLOBAL_VARIABLE_DECLARATION_QUERY = oneLine` 5 | [ 6 | (translation_unit 7 | (declaration 8 | (type_qualifier)* @type_qualifier 9 | (type_qualifier)* @type_qualifier 10 | (type_qualifier)* @type_qualifier 11 | (type_qualifier)* @type_qualifier 12 | declarator: [(init_declarator) (identifier)] 13 | ) @declaration 14 | (#not-eq? @type_qualifier "const") 15 | ) 16 | (namespace_definition 17 | body: (_ 18 | (declaration 19 | (type_qualifier)* @type_qualifier 20 | (type_qualifier)* @type_qualifier 21 | (type_qualifier)* @type_qualifier 22 | (type_qualifier)* @type_qualifier 23 | declarator: [(init_declarator) (identifier)] 24 | ) @declaration 25 | (#not-eq? @type_qualifier "const") 26 | ) 27 | ) 28 | ] 29 | ` 30 | 31 | export const s21StructuralNoGlobalVariables = defineRule({ 32 | name: "s21-structural-no-global-variables", 33 | 34 | check(ctx) { 35 | const globalVariableDeclarations = ctx.language 36 | .query(GLOBAL_VARIABLE_DECLARATION_QUERY) 37 | .captures(ctx.node) 38 | 39 | for (const globalVariableDeclaration of globalVariableDeclarations) { 40 | ctx.error( 41 | globalVariableDeclaration.node, 42 | "global variables are forbidden", 43 | ) 44 | } 45 | }, 46 | }) 47 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@s21toolkit/lint", 3 | "description": "C/C++ linter for school 21 project", 4 | "version": "1.1.2", 5 | "private": false, 6 | "type": "module", 7 | "exports": { 8 | "default": "./build/index.js", 9 | "require": "./build/index.cjs", 10 | "types": "./build/index.d.ts" 11 | }, 12 | "bin": { 13 | "s21lint": "./build/main.js" 14 | }, 15 | "files": [ 16 | "build/*", 17 | "README.md" 18 | ], 19 | "scripts": { 20 | "build:compile": "tsup", 21 | "build": "pnpm lint && pnpm build:compile", 22 | "lint": "tsc && bun biome check .", 23 | "lint:fix": "bun biome check --apply .", 24 | "compile-grammar": "pnpm tree-sitter build-wasm --", 25 | "compile-grammar:c": "pnpm compile-grammar node_modules/tree-sitter-c", 26 | "compile-grammar:cpp": "pnpm compile-grammar node_modules/tree-sitter-cpp", 27 | "compile-grammars": "pnpm compile-grammar:c", 28 | "prepublishOnly": "pnpm build", 29 | "postversion": "git push & git push --tags", 30 | "release": "npm version -m 'chore(release): %s' --" 31 | }, 32 | "devDependencies": { 33 | "@biomejs/biome": "^1.6.4", 34 | "@tsconfig/node20": "^20.1.4", 35 | "@tsconfig/strictest": "^2.0.5", 36 | "@types/common-tags": "^1.8.4", 37 | "@types/node": "^20.12.7", 38 | "tree-sitter-c": "^0.20.8", 39 | "tree-sitter-cli": "^0.21.0", 40 | "tree-sitter-cpp": "^0.20.5", 41 | "tsup": "^8.0.2" 42 | }, 43 | "peerDependencies": { 44 | "typescript": "^5.3.3" 45 | }, 46 | "dependencies": { 47 | "chalk": "^5.3.0", 48 | "cmd-ts": "^0.13.0", 49 | "common-tags": "^1.8.2", 50 | "fast-glob": "^3.3.2", 51 | "web-tree-sitter": "^0.21.0" 52 | }, 53 | "volta": { 54 | "node": "20.12.2" 55 | }, 56 | "publishConfig": { 57 | "registry": "https://registry.npmjs.org" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/lib/traversal.ts: -------------------------------------------------------------------------------- 1 | import type Parser from "web-tree-sitter" 2 | 3 | export namespace Visitor { 4 | export type NodeVisitor = ( 5 | node: Parser.SyntaxNode, 6 | path: Parser.SyntaxNode[], 7 | ) => void 8 | 9 | export type EnterLeaveVisitor = { 10 | enter?: NodeVisitor 11 | leave?: NodeVisitor 12 | } 13 | } 14 | 15 | export type Visitor = Record< 16 | string, 17 | Visitor.NodeVisitor | Visitor.EnterLeaveVisitor 18 | > 19 | 20 | type TraversalRecord = { 21 | node: Parser.SyntaxNode 22 | enter: boolean 23 | path: Parser.SyntaxNode[] 24 | } 25 | 26 | function visit(record: TraversalRecord, visitor: Visitor) { 27 | const visitHandler = visitor[record.node.type] 28 | 29 | if (!visitHandler) { 30 | return 31 | } 32 | 33 | const node = record.node 34 | const path = [...record.path, record.node] 35 | 36 | if (typeof visitHandler === "function") { 37 | if (record.enter) { 38 | visitHandler(node, path) 39 | } 40 | } else { 41 | if (record.enter) { 42 | visitHandler.enter?.(node, path) 43 | } else { 44 | visitHandler.leave?.(node, path) 45 | } 46 | } 47 | } 48 | 49 | export function traverse(tree: Parser.Tree, visitor: Visitor) { 50 | const traversalStack: TraversalRecord[] = [ 51 | { 52 | node: tree.walk().currentNode(), 53 | enter: true, 54 | path: [], 55 | }, 56 | ] 57 | 58 | while (traversalStack.length > 0) { 59 | // biome-ignore lint/style/noNonNullAssertion: 60 | const record = traversalStack.pop()! 61 | 62 | visit(record, visitor) 63 | 64 | if (record.enter) { 65 | traversalStack.push({ 66 | node: record.node, 67 | enter: false, 68 | path: record.path, 69 | }) 70 | 71 | for (const node of record.node.children) { 72 | traversalStack.push({ 73 | node, 74 | enter: true, 75 | path: [...record.path, record.node], 76 | }) 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/rules/s21-structural-no-multiple-loop-exits.ts: -------------------------------------------------------------------------------- 1 | import { defineRule, traverse } from "@/lib" 2 | import type { SyntaxNode } from "web-tree-sitter" 3 | 4 | export const s21StructuralNoMultipleLoopExits = defineRule({ 5 | name: "s21-structural-no-multiple-loop-exits", 6 | 7 | // TODO: Treat condition + exit statement as 2 exit statements (e.g. while (condition) { break; }) 8 | check(ctx) { 9 | const exitStatements: SyntaxNode[][] = [] 10 | 11 | function pushExitStatement(node: SyntaxNode) { 12 | const top = exitStatements.at(-1) 13 | 14 | if (!top) { 15 | return 16 | } 17 | 18 | top.push(node) 19 | } 20 | 21 | function popExitStatements() { 22 | const top = exitStatements.pop() ?? [] 23 | 24 | if (top.length <= 1) { 25 | return 26 | } 27 | 28 | for (const node of top) { 29 | ctx.error(node, "multiple loop exit statements are forbidden") 30 | } 31 | } 32 | 33 | traverse(ctx.tree, { 34 | for_statement: { 35 | enter() { 36 | exitStatements.push([]) 37 | }, 38 | leave() { 39 | popExitStatements() 40 | }, 41 | }, 42 | while_statement: { 43 | enter() { 44 | exitStatements.push([]) 45 | }, 46 | leave() { 47 | popExitStatements() 48 | }, 49 | }, 50 | do_statement: { 51 | enter() { 52 | exitStatements.push([]) 53 | }, 54 | leave() { 55 | popExitStatements() 56 | }, 57 | }, 58 | // Ignore breaks out of switch statements 59 | switch_statement: { 60 | enter() { 61 | exitStatements.push([]) 62 | }, 63 | leave() { 64 | exitStatements.pop() 65 | }, 66 | }, 67 | // Ignore returns from lambdas 68 | lambda_expression: { 69 | enter() { 70 | exitStatements.push([]) 71 | }, 72 | leave() { 73 | exitStatements.pop() 74 | }, 75 | }, 76 | break_statement(node) { 77 | pushExitStatement(node) 78 | }, 79 | return_statement(node) { 80 | pushExitStatement(node) 81 | }, 82 | }) 83 | }, 84 | }) 85 | -------------------------------------------------------------------------------- /src/cli/index.ts: -------------------------------------------------------------------------------- 1 | import { readFile } from "node:fs/promises" 2 | import { Linter, createParser, printDiagnostic } from "@/lib" 3 | import { rules } from "@/rules" 4 | import chalk from "chalk" 5 | import { command, rest } from "cmd-ts" 6 | import { oneLine } from "common-tags" 7 | import fg from "fast-glob" 8 | 9 | export const s21lintCommand = command({ 10 | name: "s21lint", 11 | description: "C/C++ linter for school 21 projects", 12 | args: { 13 | pathsOrPatterns: rest({ 14 | displayName: "files", 15 | description: "Files to check", 16 | }), 17 | }, 18 | async handler(argv) { 19 | const { pathsOrPatterns } = argv 20 | 21 | if (pathsOrPatterns.length === 0) { 22 | process.exitCode = 1 23 | 24 | console.log("No input files") 25 | 26 | return 27 | } 28 | 29 | const resolvedPaths = (await fg(pathsOrPatterns)).filter((file) => 30 | /\.(c|cc|cpp|cxx|h|hh|hxx|hpp)$/.test(file), 31 | ) 32 | 33 | if (resolvedPaths.length === 0) { 34 | process.exitCode = 1 35 | 36 | console.log("No resolved input files") 37 | 38 | return 39 | } 40 | 41 | const parser = await createParser("cpp") 42 | 43 | const linter = new Linter({ rules }) 44 | 45 | for (const path of resolvedPaths) { 46 | const content = await readFile(path, "utf8") 47 | 48 | const program = parser.parse(content) 49 | 50 | linter.checkProgram(program, path) 51 | 52 | for (const diagnostic of linter.getFileDiagnostics(path)) { 53 | printDiagnostic(path, content, diagnostic) 54 | } 55 | } 56 | if (!linter.hasDiagnostics()) { 57 | console.log(`No errors found in ${resolvedPaths.length} files`) 58 | 59 | return 60 | } 61 | 62 | if (linter.hasErrors()) { 63 | process.exitCode = 1 64 | } 65 | 66 | const stats = linter.getStats() 67 | 68 | const erroneousFileCount = new Set([ 69 | ...linter.diagnostics.errors.keys(), 70 | ...linter.diagnostics.warnings.keys(), 71 | ]).size 72 | 73 | console.log(oneLine` 74 | Found 75 | ${chalk.red(`${stats.errors} errors`)} 76 | and ${chalk.yellow(`${stats.warnings} warnings`)} 77 | in ${erroneousFileCount}/${resolvedPaths.length} files 78 | `) 79 | }, 80 | }) 81 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore 2 | 3 | # Logs 4 | 5 | logs 6 | _.log 7 | npm-debug.log_ 8 | yarn-debug.log* 9 | yarn-error.log* 10 | lerna-debug.log* 11 | .pnpm-debug.log* 12 | 13 | # Caches 14 | 15 | .cache 16 | 17 | # Diagnostic reports (https://nodejs.org/api/report.html) 18 | 19 | report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json 20 | 21 | # Runtime data 22 | 23 | pids 24 | _.pid 25 | _.seed 26 | *.pid.lock 27 | 28 | # Directory for instrumented libs generated by jscoverage/JSCover 29 | 30 | lib-cov 31 | 32 | # Coverage directory used by tools like istanbul 33 | 34 | coverage 35 | *.lcov 36 | 37 | # nyc test coverage 38 | 39 | .nyc_output 40 | 41 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 42 | 43 | .grunt 44 | 45 | # Bower dependency directory (https://bower.io/) 46 | 47 | bower_components 48 | 49 | # node-waf configuration 50 | 51 | .lock-wscript 52 | 53 | # Compiled binary addons (https://nodejs.org/api/addons.html) 54 | 55 | build/Release 56 | 57 | # Dependency directories 58 | 59 | node_modules/ 60 | jspm_packages/ 61 | 62 | # Snowpack dependency directory (https://snowpack.dev/) 63 | 64 | web_modules/ 65 | 66 | # TypeScript cache 67 | 68 | *.tsbuildinfo 69 | 70 | # Optional npm cache directory 71 | 72 | .npm 73 | 74 | # Optional eslint cache 75 | 76 | .eslintcache 77 | 78 | # Optional stylelint cache 79 | 80 | .stylelintcache 81 | 82 | # Microbundle cache 83 | 84 | .rpt2_cache/ 85 | .rts2_cache_cjs/ 86 | .rts2_cache_es/ 87 | .rts2_cache_umd/ 88 | 89 | # Optional REPL history 90 | 91 | .node_repl_history 92 | 93 | # Output of 'npm pack' 94 | 95 | *.tgz 96 | 97 | # Yarn Integrity file 98 | 99 | .yarn-integrity 100 | 101 | # dotenv environment variable files 102 | 103 | .env 104 | .env.development.local 105 | .env.test.local 106 | .env.production.local 107 | .env.local 108 | 109 | # parcel-bundler cache (https://parceljs.org/) 110 | 111 | .parcel-cache 112 | 113 | # Next.js build output 114 | 115 | .next 116 | out 117 | 118 | # Nuxt.js build / generate output 119 | 120 | .nuxt 121 | dist 122 | 123 | # Gatsby files 124 | 125 | # Comment in the public line in if your project uses Gatsby and not Next.js 126 | 127 | # https://nextjs.org/blog/next-9-1#public-directory-support 128 | 129 | # public 130 | 131 | # vuepress build output 132 | 133 | .vuepress/dist 134 | 135 | # vuepress v2.x temp and cache directory 136 | 137 | .temp 138 | 139 | # Docusaurus cache and generated files 140 | 141 | .docusaurus 142 | 143 | # Serverless directories 144 | 145 | .serverless/ 146 | 147 | # FuseBox cache 148 | 149 | .fusebox/ 150 | 151 | # DynamoDB Local files 152 | 153 | .dynamodb/ 154 | 155 | # TernJS port file 156 | 157 | .tern-port 158 | 159 | # Stores VSCode versions used for testing VSCode extensions 160 | 161 | .vscode-test 162 | 163 | # yarn v2 164 | 165 | .yarn/cache 166 | .yarn/unplugged 167 | .yarn/build-state.yml 168 | .yarn/install-state.gz 169 | .pnp.* 170 | 171 | # IntelliJ based IDEs 172 | .idea 173 | 174 | # Finder (MacOS) folder config 175 | .DS_Store 176 | 177 | # VSCode workspace configuration 178 | .vscode/ 179 | 180 | # Build artifacts 181 | build/ 182 | -------------------------------------------------------------------------------- /src/lib/linter.ts: -------------------------------------------------------------------------------- 1 | import type Parser from "web-tree-sitter" 2 | import type { Diagnostic } from "./diagnostic" 3 | import type { Rule } from "./rule" 4 | 5 | export class Linter { 6 | readonly #errors = new Map() 7 | readonly #warnings = new Map() 8 | 9 | constructor( 10 | readonly configuration: { 11 | rules: Rule[] 12 | }, 13 | ) {} 14 | 15 | emitDiagnostic(filename: string, diagnostic: Diagnostic) { 16 | const collection = 17 | diagnostic.severity === "error" ? this.#errors : this.#warnings 18 | 19 | if (!collection.has(filename)) { 20 | collection.set(filename, [diagnostic]) 21 | } else { 22 | // biome-ignore lint/style/noNonNullAssertion: 23 | collection.get(filename)!.push(diagnostic) 24 | } 25 | } 26 | 27 | checkProgram(program: Parser.Tree, filename = "default") { 28 | this.clearFileDiagnostics(filename) 29 | 30 | const context = { 31 | node: program.rootNode, 32 | tree: program, 33 | language: program.getLanguage(), 34 | } 35 | 36 | for (const rule of this.configuration.rules) { 37 | const shouldCheck = rule.filter?.(context) 38 | 39 | if (shouldCheck === false) { 40 | continue 41 | } 42 | 43 | rule.check({ 44 | ...context, 45 | warn: (node, message) => 46 | this.emitDiagnostic(filename, { 47 | node, 48 | message, 49 | reporter: rule, 50 | severity: "warning", 51 | }), 52 | error: (node, message) => 53 | this.emitDiagnostic(filename, { 54 | node, 55 | message, 56 | reporter: rule, 57 | severity: "error", 58 | }), 59 | }) 60 | } 61 | } 62 | 63 | getFileDiagnostics(filename: string) { 64 | const warnings = this.diagnostics.warnings.get(filename) ?? [] 65 | const errors = this.diagnostics.errors.get(filename) ?? [] 66 | 67 | return { 68 | warnings, 69 | errors, 70 | *[Symbol.iterator]() { 71 | yield* this.warnings 72 | yield* this.errors 73 | }, 74 | } 75 | } 76 | 77 | get diagnostics() { 78 | return { 79 | warnings: this.#warnings, 80 | errors: this.#errors, 81 | *[Symbol.iterator]() { 82 | yield* this.warnings 83 | yield* this.errors 84 | }, 85 | } 86 | } 87 | 88 | hasErrors(filename?: string) { 89 | if (!filename) { 90 | return this.diagnostics.errors.size > 0 91 | } 92 | 93 | return this.diagnostics.errors.has(filename) 94 | } 95 | 96 | hasWarnings(filename?: string) { 97 | if (!filename) { 98 | return this.diagnostics.warnings.size > 0 99 | } 100 | 101 | return this.diagnostics.warnings.has(filename) 102 | } 103 | 104 | hasDiagnostics(filename?: string) { 105 | return this.hasErrors(filename) || this.hasWarnings(filename) 106 | } 107 | 108 | getStats(filename?: string) { 109 | const errors = [] 110 | const warnings = [] 111 | 112 | if (!filename) { 113 | for (const diagnostic of this.diagnostics.errors.values()) { 114 | errors.push(...diagnostic) 115 | } 116 | 117 | for (const diagnostic of this.diagnostics.warnings.values()) { 118 | warnings.push(...diagnostic) 119 | } 120 | } else { 121 | const errorDiagnostics = this.diagnostics.errors.get(filename) ?? [] 122 | const warningDiagnostics = 123 | this.diagnostics.warnings.get(filename) ?? [] 124 | 125 | errors.push(...errorDiagnostics) 126 | warnings.push(...warningDiagnostics) 127 | } 128 | 129 | return { 130 | errors: errors.length, 131 | warnings: warnings.length, 132 | total: errors.length + warnings.length, 133 | } 134 | } 135 | 136 | clearDiagnostics() { 137 | this.#errors.clear() 138 | this.#warnings.clear() 139 | } 140 | 141 | clearFileDiagnostics(filename: string) { 142 | this.#errors.delete(filename) 143 | this.#warnings.delete(filename) 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: '6.0' 2 | 3 | settings: 4 | autoInstallPeers: true 5 | excludeLinksFromLockfile: false 6 | 7 | dependencies: 8 | chalk: 9 | specifier: ^5.3.0 10 | version: 5.3.0 11 | cmd-ts: 12 | specifier: ^0.13.0 13 | version: 0.13.0 14 | common-tags: 15 | specifier: ^1.8.2 16 | version: 1.8.2 17 | fast-glob: 18 | specifier: ^3.3.2 19 | version: 3.3.2 20 | typescript: 21 | specifier: ^5.3.3 22 | version: 5.4.5 23 | web-tree-sitter: 24 | specifier: ^0.21.0 25 | version: 0.21.0 26 | 27 | devDependencies: 28 | '@biomejs/biome': 29 | specifier: ^1.6.4 30 | version: 1.6.4 31 | '@tsconfig/node20': 32 | specifier: ^20.1.4 33 | version: 20.1.4 34 | '@tsconfig/strictest': 35 | specifier: ^2.0.5 36 | version: 2.0.5 37 | '@types/common-tags': 38 | specifier: ^1.8.4 39 | version: 1.8.4 40 | '@types/node': 41 | specifier: ^20.12.7 42 | version: 20.12.7 43 | tree-sitter-c: 44 | specifier: ^0.20.8 45 | version: 0.20.8 46 | tree-sitter-cli: 47 | specifier: ^0.21.0 48 | version: 0.21.0 49 | tree-sitter-cpp: 50 | specifier: ^0.20.5 51 | version: 0.20.5 52 | tsup: 53 | specifier: ^8.0.2 54 | version: 8.0.2 55 | 56 | packages: 57 | 58 | /@biomejs/biome@1.6.4: 59 | resolution: {integrity: sha512-3groVd2oWsLC0ZU+XXgHSNbq31lUcOCBkCcA7sAQGBopHcmL+jmmdoWlY3S61zIh+f2mqQTQte1g6PZKb3JJjA==} 60 | engines: {node: '>=14.21.3'} 61 | hasBin: true 62 | requiresBuild: true 63 | optionalDependencies: 64 | '@biomejs/cli-darwin-arm64': 1.6.4 65 | '@biomejs/cli-darwin-x64': 1.6.4 66 | '@biomejs/cli-linux-arm64': 1.6.4 67 | '@biomejs/cli-linux-arm64-musl': 1.6.4 68 | '@biomejs/cli-linux-x64': 1.6.4 69 | '@biomejs/cli-linux-x64-musl': 1.6.4 70 | '@biomejs/cli-win32-arm64': 1.6.4 71 | '@biomejs/cli-win32-x64': 1.6.4 72 | dev: true 73 | 74 | /@biomejs/cli-darwin-arm64@1.6.4: 75 | resolution: {integrity: sha512-2WZef8byI9NRzGajGj5RTrroW9BxtfbP9etigW1QGAtwu/6+cLkdPOWRAs7uFtaxBNiKFYA8j/BxV5zeAo5QOQ==} 76 | engines: {node: '>=14.21.3'} 77 | cpu: [arm64] 78 | os: [darwin] 79 | requiresBuild: true 80 | dev: true 81 | optional: true 82 | 83 | /@biomejs/cli-darwin-x64@1.6.4: 84 | resolution: {integrity: sha512-uo1zgM7jvzcoDpF6dbGizejDLCqNpUIRkCj/oEK0PB0NUw8re/cn1EnxuOLZqDpn+8G75COLQTOx8UQIBBN/Kg==} 85 | engines: {node: '>=14.21.3'} 86 | cpu: [x64] 87 | os: [darwin] 88 | requiresBuild: true 89 | dev: true 90 | optional: true 91 | 92 | /@biomejs/cli-linux-arm64-musl@1.6.4: 93 | resolution: {integrity: sha512-Hp8Jwt6rjj0wCcYAEN6/cfwrrPLLlGOXZ56Lei4Pt4jy39+UuPeAVFPeclrrCfxyL1wQ2xPrhd/saTHSL6DoJg==} 94 | engines: {node: '>=14.21.3'} 95 | cpu: [arm64] 96 | os: [linux] 97 | requiresBuild: true 98 | dev: true 99 | optional: true 100 | 101 | /@biomejs/cli-linux-arm64@1.6.4: 102 | resolution: {integrity: sha512-wAOieaMNIpLrxGc2/xNvM//CIZg7ueWy3V5A4T7gDZ3OL/Go27EKE59a+vMKsBCYmTt7jFl4yHz0TUkUbodA/w==} 103 | engines: {node: '>=14.21.3'} 104 | cpu: [arm64] 105 | os: [linux] 106 | requiresBuild: true 107 | dev: true 108 | optional: true 109 | 110 | /@biomejs/cli-linux-x64-musl@1.6.4: 111 | resolution: {integrity: sha512-wqi0hr8KAx5kBO0B+m5u8QqiYFFBJOSJVSuRqTeGWW+GYLVUtXNidykNqf1JsW6jJDpbkSp2xHKE/bTlVaG2Kg==} 112 | engines: {node: '>=14.21.3'} 113 | cpu: [x64] 114 | os: [linux] 115 | requiresBuild: true 116 | dev: true 117 | optional: true 118 | 119 | /@biomejs/cli-linux-x64@1.6.4: 120 | resolution: {integrity: sha512-qTWhuIw+/ePvOkjE9Zxf5OqSCYxtAvcTJtVmZT8YQnmY2I62JKNV2m7tf6O5ViKZUOP0mOQ6NgqHKcHH1eT8jw==} 121 | engines: {node: '>=14.21.3'} 122 | cpu: [x64] 123 | os: [linux] 124 | requiresBuild: true 125 | dev: true 126 | optional: true 127 | 128 | /@biomejs/cli-win32-arm64@1.6.4: 129 | resolution: {integrity: sha512-Wp3FiEeF6v6C5qMfLkHwf4YsoNHr/n0efvoC8jCKO/kX05OXaVExj+1uVQ1eGT7Pvx0XVm/TLprRO0vq/V6UzA==} 130 | engines: {node: '>=14.21.3'} 131 | cpu: [arm64] 132 | os: [win32] 133 | requiresBuild: true 134 | dev: true 135 | optional: true 136 | 137 | /@biomejs/cli-win32-x64@1.6.4: 138 | resolution: {integrity: sha512-mz183Di5hTSGP7KjNWEhivcP1wnHLGmOxEROvoFsIxMYtDhzJDad4k5gI/1JbmA0xe4n52vsgqo09tBhrMT/Zg==} 139 | engines: {node: '>=14.21.3'} 140 | cpu: [x64] 141 | os: [win32] 142 | requiresBuild: true 143 | dev: true 144 | optional: true 145 | 146 | /@esbuild/aix-ppc64@0.19.12: 147 | resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} 148 | engines: {node: '>=12'} 149 | cpu: [ppc64] 150 | os: [aix] 151 | requiresBuild: true 152 | dev: true 153 | optional: true 154 | 155 | /@esbuild/android-arm64@0.19.12: 156 | resolution: {integrity: sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==} 157 | engines: {node: '>=12'} 158 | cpu: [arm64] 159 | os: [android] 160 | requiresBuild: true 161 | dev: true 162 | optional: true 163 | 164 | /@esbuild/android-arm@0.19.12: 165 | resolution: {integrity: sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==} 166 | engines: {node: '>=12'} 167 | cpu: [arm] 168 | os: [android] 169 | requiresBuild: true 170 | dev: true 171 | optional: true 172 | 173 | /@esbuild/android-x64@0.19.12: 174 | resolution: {integrity: sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==} 175 | engines: {node: '>=12'} 176 | cpu: [x64] 177 | os: [android] 178 | requiresBuild: true 179 | dev: true 180 | optional: true 181 | 182 | /@esbuild/darwin-arm64@0.19.12: 183 | resolution: {integrity: sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==} 184 | engines: {node: '>=12'} 185 | cpu: [arm64] 186 | os: [darwin] 187 | requiresBuild: true 188 | dev: true 189 | optional: true 190 | 191 | /@esbuild/darwin-x64@0.19.12: 192 | resolution: {integrity: sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==} 193 | engines: {node: '>=12'} 194 | cpu: [x64] 195 | os: [darwin] 196 | requiresBuild: true 197 | dev: true 198 | optional: true 199 | 200 | /@esbuild/freebsd-arm64@0.19.12: 201 | resolution: {integrity: sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==} 202 | engines: {node: '>=12'} 203 | cpu: [arm64] 204 | os: [freebsd] 205 | requiresBuild: true 206 | dev: true 207 | optional: true 208 | 209 | /@esbuild/freebsd-x64@0.19.12: 210 | resolution: {integrity: sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==} 211 | engines: {node: '>=12'} 212 | cpu: [x64] 213 | os: [freebsd] 214 | requiresBuild: true 215 | dev: true 216 | optional: true 217 | 218 | /@esbuild/linux-arm64@0.19.12: 219 | resolution: {integrity: sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==} 220 | engines: {node: '>=12'} 221 | cpu: [arm64] 222 | os: [linux] 223 | requiresBuild: true 224 | dev: true 225 | optional: true 226 | 227 | /@esbuild/linux-arm@0.19.12: 228 | resolution: {integrity: sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==} 229 | engines: {node: '>=12'} 230 | cpu: [arm] 231 | os: [linux] 232 | requiresBuild: true 233 | dev: true 234 | optional: true 235 | 236 | /@esbuild/linux-ia32@0.19.12: 237 | resolution: {integrity: sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==} 238 | engines: {node: '>=12'} 239 | cpu: [ia32] 240 | os: [linux] 241 | requiresBuild: true 242 | dev: true 243 | optional: true 244 | 245 | /@esbuild/linux-loong64@0.19.12: 246 | resolution: {integrity: sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==} 247 | engines: {node: '>=12'} 248 | cpu: [loong64] 249 | os: [linux] 250 | requiresBuild: true 251 | dev: true 252 | optional: true 253 | 254 | /@esbuild/linux-mips64el@0.19.12: 255 | resolution: {integrity: sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==} 256 | engines: {node: '>=12'} 257 | cpu: [mips64el] 258 | os: [linux] 259 | requiresBuild: true 260 | dev: true 261 | optional: true 262 | 263 | /@esbuild/linux-ppc64@0.19.12: 264 | resolution: {integrity: sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==} 265 | engines: {node: '>=12'} 266 | cpu: [ppc64] 267 | os: [linux] 268 | requiresBuild: true 269 | dev: true 270 | optional: true 271 | 272 | /@esbuild/linux-riscv64@0.19.12: 273 | resolution: {integrity: sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==} 274 | engines: {node: '>=12'} 275 | cpu: [riscv64] 276 | os: [linux] 277 | requiresBuild: true 278 | dev: true 279 | optional: true 280 | 281 | /@esbuild/linux-s390x@0.19.12: 282 | resolution: {integrity: sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==} 283 | engines: {node: '>=12'} 284 | cpu: [s390x] 285 | os: [linux] 286 | requiresBuild: true 287 | dev: true 288 | optional: true 289 | 290 | /@esbuild/linux-x64@0.19.12: 291 | resolution: {integrity: sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==} 292 | engines: {node: '>=12'} 293 | cpu: [x64] 294 | os: [linux] 295 | requiresBuild: true 296 | dev: true 297 | optional: true 298 | 299 | /@esbuild/netbsd-x64@0.19.12: 300 | resolution: {integrity: sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==} 301 | engines: {node: '>=12'} 302 | cpu: [x64] 303 | os: [netbsd] 304 | requiresBuild: true 305 | dev: true 306 | optional: true 307 | 308 | /@esbuild/openbsd-x64@0.19.12: 309 | resolution: {integrity: sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==} 310 | engines: {node: '>=12'} 311 | cpu: [x64] 312 | os: [openbsd] 313 | requiresBuild: true 314 | dev: true 315 | optional: true 316 | 317 | /@esbuild/sunos-x64@0.19.12: 318 | resolution: {integrity: sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==} 319 | engines: {node: '>=12'} 320 | cpu: [x64] 321 | os: [sunos] 322 | requiresBuild: true 323 | dev: true 324 | optional: true 325 | 326 | /@esbuild/win32-arm64@0.19.12: 327 | resolution: {integrity: sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==} 328 | engines: {node: '>=12'} 329 | cpu: [arm64] 330 | os: [win32] 331 | requiresBuild: true 332 | dev: true 333 | optional: true 334 | 335 | /@esbuild/win32-ia32@0.19.12: 336 | resolution: {integrity: sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==} 337 | engines: {node: '>=12'} 338 | cpu: [ia32] 339 | os: [win32] 340 | requiresBuild: true 341 | dev: true 342 | optional: true 343 | 344 | /@esbuild/win32-x64@0.19.12: 345 | resolution: {integrity: sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==} 346 | engines: {node: '>=12'} 347 | cpu: [x64] 348 | os: [win32] 349 | requiresBuild: true 350 | dev: true 351 | optional: true 352 | 353 | /@isaacs/cliui@8.0.2: 354 | resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} 355 | engines: {node: '>=12'} 356 | dependencies: 357 | string-width: 5.1.2 358 | string-width-cjs: /string-width@4.2.3 359 | strip-ansi: 7.1.0 360 | strip-ansi-cjs: /strip-ansi@6.0.1 361 | wrap-ansi: 8.1.0 362 | wrap-ansi-cjs: /wrap-ansi@7.0.0 363 | dev: true 364 | 365 | /@jridgewell/gen-mapping@0.3.5: 366 | resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} 367 | engines: {node: '>=6.0.0'} 368 | dependencies: 369 | '@jridgewell/set-array': 1.2.1 370 | '@jridgewell/sourcemap-codec': 1.4.15 371 | '@jridgewell/trace-mapping': 0.3.25 372 | dev: true 373 | 374 | /@jridgewell/resolve-uri@3.1.2: 375 | resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} 376 | engines: {node: '>=6.0.0'} 377 | dev: true 378 | 379 | /@jridgewell/set-array@1.2.1: 380 | resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} 381 | engines: {node: '>=6.0.0'} 382 | dev: true 383 | 384 | /@jridgewell/sourcemap-codec@1.4.15: 385 | resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} 386 | dev: true 387 | 388 | /@jridgewell/trace-mapping@0.3.25: 389 | resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} 390 | dependencies: 391 | '@jridgewell/resolve-uri': 3.1.2 392 | '@jridgewell/sourcemap-codec': 1.4.15 393 | dev: true 394 | 395 | /@nodelib/fs.scandir@2.1.5: 396 | resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} 397 | engines: {node: '>= 8'} 398 | dependencies: 399 | '@nodelib/fs.stat': 2.0.5 400 | run-parallel: 1.2.0 401 | 402 | /@nodelib/fs.stat@2.0.5: 403 | resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} 404 | engines: {node: '>= 8'} 405 | 406 | /@nodelib/fs.walk@1.2.8: 407 | resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} 408 | engines: {node: '>= 8'} 409 | dependencies: 410 | '@nodelib/fs.scandir': 2.1.5 411 | fastq: 1.17.1 412 | 413 | /@pkgjs/parseargs@0.11.0: 414 | resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} 415 | engines: {node: '>=14'} 416 | requiresBuild: true 417 | dev: true 418 | optional: true 419 | 420 | /@rollup/rollup-android-arm-eabi@4.14.2: 421 | resolution: {integrity: sha512-ahxSgCkAEk+P/AVO0vYr7DxOD3CwAQrT0Go9BJyGQ9Ef0QxVOfjDZMiF4Y2s3mLyPrjonchIMH/tbWHucJMykQ==} 422 | cpu: [arm] 423 | os: [android] 424 | requiresBuild: true 425 | dev: true 426 | optional: true 427 | 428 | /@rollup/rollup-android-arm64@4.14.2: 429 | resolution: {integrity: sha512-lAarIdxZWbFSHFSDao9+I/F5jDaKyCqAPMq5HqnfpBw8dKDiCaaqM0lq5h1pQTLeIqueeay4PieGR5jGZMWprw==} 430 | cpu: [arm64] 431 | os: [android] 432 | requiresBuild: true 433 | dev: true 434 | optional: true 435 | 436 | /@rollup/rollup-darwin-arm64@4.14.2: 437 | resolution: {integrity: sha512-SWsr8zEUk82KSqquIMgZEg2GE5mCSfr9sE/thDROkX6pb3QQWPp8Vw8zOq2GyxZ2t0XoSIUlvHDkrf5Gmf7x3Q==} 438 | cpu: [arm64] 439 | os: [darwin] 440 | requiresBuild: true 441 | dev: true 442 | optional: true 443 | 444 | /@rollup/rollup-darwin-x64@4.14.2: 445 | resolution: {integrity: sha512-o/HAIrQq0jIxJAhgtIvV5FWviYK4WB0WwV91SLUnsliw1lSAoLsmgEEgRWzDguAFeUEUUoIWXiJrPqU7vGiVkA==} 446 | cpu: [x64] 447 | os: [darwin] 448 | requiresBuild: true 449 | dev: true 450 | optional: true 451 | 452 | /@rollup/rollup-linux-arm-gnueabihf@4.14.2: 453 | resolution: {integrity: sha512-nwlJ65UY9eGq91cBi6VyDfArUJSKOYt5dJQBq8xyLhvS23qO+4Nr/RreibFHjP6t+5ap2ohZrUJcHv5zk5ju/g==} 454 | cpu: [arm] 455 | os: [linux] 456 | requiresBuild: true 457 | dev: true 458 | optional: true 459 | 460 | /@rollup/rollup-linux-arm64-gnu@4.14.2: 461 | resolution: {integrity: sha512-Pg5TxxO2IVlMj79+c/9G0LREC9SY3HM+pfAwX7zj5/cAuwrbfj2Wv9JbMHIdPCfQpYsI4g9mE+2Bw/3aeSs2rQ==} 462 | cpu: [arm64] 463 | os: [linux] 464 | requiresBuild: true 465 | dev: true 466 | optional: true 467 | 468 | /@rollup/rollup-linux-arm64-musl@4.14.2: 469 | resolution: {integrity: sha512-cAOTjGNm84gc6tS02D1EXtG7tDRsVSDTBVXOLbj31DkwfZwgTPYZ6aafSU7rD/4R2a34JOwlF9fQayuTSkoclA==} 470 | cpu: [arm64] 471 | os: [linux] 472 | requiresBuild: true 473 | dev: true 474 | optional: true 475 | 476 | /@rollup/rollup-linux-powerpc64le-gnu@4.14.2: 477 | resolution: {integrity: sha512-4RyT6v1kXb7C0fn6zV33rvaX05P0zHoNzaXI/5oFHklfKm602j+N4mn2YvoezQViRLPnxP8M1NaY4s/5kXO5cw==} 478 | cpu: [ppc64] 479 | os: [linux] 480 | requiresBuild: true 481 | dev: true 482 | optional: true 483 | 484 | /@rollup/rollup-linux-riscv64-gnu@4.14.2: 485 | resolution: {integrity: sha512-KNUH6jC/vRGAKSorySTyc/yRYlCwN/5pnMjXylfBniwtJx5O7X17KG/0efj8XM3TZU7raYRXJFFReOzNmL1n1w==} 486 | cpu: [riscv64] 487 | os: [linux] 488 | requiresBuild: true 489 | dev: true 490 | optional: true 491 | 492 | /@rollup/rollup-linux-s390x-gnu@4.14.2: 493 | resolution: {integrity: sha512-xPV4y73IBEXToNPa3h5lbgXOi/v0NcvKxU0xejiFw6DtIYQqOTMhZ2DN18/HrrP0PmiL3rGtRG9gz1QE8vFKXQ==} 494 | cpu: [s390x] 495 | os: [linux] 496 | requiresBuild: true 497 | dev: true 498 | optional: true 499 | 500 | /@rollup/rollup-linux-x64-gnu@4.14.2: 501 | resolution: {integrity: sha512-QBhtr07iFGmF9egrPOWyO5wciwgtzKkYPNLVCFZTmr4TWmY0oY2Dm/bmhHjKRwZoGiaKdNcKhFtUMBKvlchH+Q==} 502 | cpu: [x64] 503 | os: [linux] 504 | requiresBuild: true 505 | dev: true 506 | optional: true 507 | 508 | /@rollup/rollup-linux-x64-musl@4.14.2: 509 | resolution: {integrity: sha512-8zfsQRQGH23O6qazZSFY5jP5gt4cFvRuKTpuBsC1ZnSWxV8ZKQpPqOZIUtdfMOugCcBvFGRa1pDC/tkf19EgBw==} 510 | cpu: [x64] 511 | os: [linux] 512 | requiresBuild: true 513 | dev: true 514 | optional: true 515 | 516 | /@rollup/rollup-win32-arm64-msvc@4.14.2: 517 | resolution: {integrity: sha512-H4s8UjgkPnlChl6JF5empNvFHp77Jx+Wfy2EtmYPe9G22XV+PMuCinZVHurNe8ggtwoaohxARJZbaH/3xjB/FA==} 518 | cpu: [arm64] 519 | os: [win32] 520 | requiresBuild: true 521 | dev: true 522 | optional: true 523 | 524 | /@rollup/rollup-win32-ia32-msvc@4.14.2: 525 | resolution: {integrity: sha512-djqpAjm/i8erWYF0K6UY4kRO3X5+T4TypIqw60Q8MTqSBaQNpNXDhxdjpZ3ikgb+wn99svA7jxcXpiyg9MUsdw==} 526 | cpu: [ia32] 527 | os: [win32] 528 | requiresBuild: true 529 | dev: true 530 | optional: true 531 | 532 | /@rollup/rollup-win32-x64-msvc@4.14.2: 533 | resolution: {integrity: sha512-teAqzLT0yTYZa8ZP7zhFKEx4cotS8Tkk5XiqNMJhD4CpaWB1BHARE4Qy+RzwnXvSAYv+Q3jAqCVBS+PS+Yee8Q==} 534 | cpu: [x64] 535 | os: [win32] 536 | requiresBuild: true 537 | dev: true 538 | optional: true 539 | 540 | /@tsconfig/node20@20.1.4: 541 | resolution: {integrity: sha512-sqgsT69YFeLWf5NtJ4Xq/xAF8p4ZQHlmGW74Nu2tD4+g5fAsposc4ZfaaPixVu4y01BEiDCWLRDCvDM5JOsRxg==} 542 | dev: true 543 | 544 | /@tsconfig/strictest@2.0.5: 545 | resolution: {integrity: sha512-ec4tjL2Rr0pkZ5hww65c+EEPYwxOi4Ryv+0MtjeaSQRJyq322Q27eOQiFbuNgw2hpL4hB1/W/HBGk3VKS43osg==} 546 | dev: true 547 | 548 | /@types/common-tags@1.8.4: 549 | resolution: {integrity: sha512-S+1hLDJPjWNDhcGxsxEbepzaxWqURP/o+3cP4aa2w7yBXgdcmKGQtZzP8JbyfOd0m+33nh+8+kvxYE2UJtBDkg==} 550 | dev: true 551 | 552 | /@types/estree@1.0.5: 553 | resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} 554 | dev: true 555 | 556 | /@types/node@20.12.7: 557 | resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==} 558 | dependencies: 559 | undici-types: 5.26.5 560 | dev: true 561 | 562 | /ansi-regex@5.0.1: 563 | resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} 564 | engines: {node: '>=8'} 565 | 566 | /ansi-regex@6.0.1: 567 | resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} 568 | engines: {node: '>=12'} 569 | dev: true 570 | 571 | /ansi-styles@4.3.0: 572 | resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} 573 | engines: {node: '>=8'} 574 | dependencies: 575 | color-convert: 2.0.1 576 | 577 | /ansi-styles@6.2.1: 578 | resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} 579 | engines: {node: '>=12'} 580 | dev: true 581 | 582 | /any-promise@1.3.0: 583 | resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} 584 | dev: true 585 | 586 | /anymatch@3.1.3: 587 | resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} 588 | engines: {node: '>= 8'} 589 | dependencies: 590 | normalize-path: 3.0.0 591 | picomatch: 2.3.1 592 | dev: true 593 | 594 | /array-union@2.1.0: 595 | resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} 596 | engines: {node: '>=8'} 597 | dev: true 598 | 599 | /balanced-match@1.0.2: 600 | resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} 601 | dev: true 602 | 603 | /binary-extensions@2.3.0: 604 | resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} 605 | engines: {node: '>=8'} 606 | dev: true 607 | 608 | /brace-expansion@2.0.1: 609 | resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} 610 | dependencies: 611 | balanced-match: 1.0.2 612 | dev: true 613 | 614 | /braces@3.0.2: 615 | resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} 616 | engines: {node: '>=8'} 617 | dependencies: 618 | fill-range: 7.0.1 619 | 620 | /bundle-require@4.0.2(esbuild@0.19.12): 621 | resolution: {integrity: sha512-jwzPOChofl67PSTW2SGubV9HBQAhhR2i6nskiOThauo9dzwDUgOWQScFVaJkjEfYX+UXiD+LEx8EblQMc2wIag==} 622 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 623 | peerDependencies: 624 | esbuild: '>=0.17' 625 | dependencies: 626 | esbuild: 0.19.12 627 | load-tsconfig: 0.2.5 628 | dev: true 629 | 630 | /cac@6.7.14: 631 | resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} 632 | engines: {node: '>=8'} 633 | dev: true 634 | 635 | /chalk@4.1.2: 636 | resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} 637 | engines: {node: '>=10'} 638 | dependencies: 639 | ansi-styles: 4.3.0 640 | supports-color: 7.2.0 641 | dev: false 642 | 643 | /chalk@5.3.0: 644 | resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} 645 | engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} 646 | dev: false 647 | 648 | /chokidar@3.6.0: 649 | resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} 650 | engines: {node: '>= 8.10.0'} 651 | dependencies: 652 | anymatch: 3.1.3 653 | braces: 3.0.2 654 | glob-parent: 5.1.2 655 | is-binary-path: 2.1.0 656 | is-glob: 4.0.3 657 | normalize-path: 3.0.0 658 | readdirp: 3.6.0 659 | optionalDependencies: 660 | fsevents: 2.3.3 661 | dev: true 662 | 663 | /cmd-ts@0.13.0: 664 | resolution: {integrity: sha512-nsnxf6wNIM/JAS7T/x/1JmbEsjH0a8tezXqqpaL0O6+eV0/aDEnRxwjxpu0VzDdRcaC1ixGSbRlUuf/IU59I4g==} 665 | dependencies: 666 | chalk: 4.1.2 667 | debug: 4.3.4 668 | didyoumean: 1.2.2 669 | strip-ansi: 6.0.1 670 | transitivePeerDependencies: 671 | - supports-color 672 | dev: false 673 | 674 | /color-convert@2.0.1: 675 | resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} 676 | engines: {node: '>=7.0.0'} 677 | dependencies: 678 | color-name: 1.1.4 679 | 680 | /color-name@1.1.4: 681 | resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} 682 | 683 | /commander@4.1.1: 684 | resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} 685 | engines: {node: '>= 6'} 686 | dev: true 687 | 688 | /common-tags@1.8.2: 689 | resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} 690 | engines: {node: '>=4.0.0'} 691 | dev: false 692 | 693 | /cross-spawn@7.0.3: 694 | resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} 695 | engines: {node: '>= 8'} 696 | dependencies: 697 | path-key: 3.1.1 698 | shebang-command: 2.0.0 699 | which: 2.0.2 700 | dev: true 701 | 702 | /debug@4.3.4: 703 | resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} 704 | engines: {node: '>=6.0'} 705 | peerDependencies: 706 | supports-color: '*' 707 | peerDependenciesMeta: 708 | supports-color: 709 | optional: true 710 | dependencies: 711 | ms: 2.1.2 712 | 713 | /didyoumean@1.2.2: 714 | resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} 715 | dev: false 716 | 717 | /dir-glob@3.0.1: 718 | resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} 719 | engines: {node: '>=8'} 720 | dependencies: 721 | path-type: 4.0.0 722 | dev: true 723 | 724 | /eastasianwidth@0.2.0: 725 | resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} 726 | dev: true 727 | 728 | /emoji-regex@8.0.0: 729 | resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} 730 | dev: true 731 | 732 | /emoji-regex@9.2.2: 733 | resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} 734 | dev: true 735 | 736 | /esbuild@0.19.12: 737 | resolution: {integrity: sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==} 738 | engines: {node: '>=12'} 739 | hasBin: true 740 | requiresBuild: true 741 | optionalDependencies: 742 | '@esbuild/aix-ppc64': 0.19.12 743 | '@esbuild/android-arm': 0.19.12 744 | '@esbuild/android-arm64': 0.19.12 745 | '@esbuild/android-x64': 0.19.12 746 | '@esbuild/darwin-arm64': 0.19.12 747 | '@esbuild/darwin-x64': 0.19.12 748 | '@esbuild/freebsd-arm64': 0.19.12 749 | '@esbuild/freebsd-x64': 0.19.12 750 | '@esbuild/linux-arm': 0.19.12 751 | '@esbuild/linux-arm64': 0.19.12 752 | '@esbuild/linux-ia32': 0.19.12 753 | '@esbuild/linux-loong64': 0.19.12 754 | '@esbuild/linux-mips64el': 0.19.12 755 | '@esbuild/linux-ppc64': 0.19.12 756 | '@esbuild/linux-riscv64': 0.19.12 757 | '@esbuild/linux-s390x': 0.19.12 758 | '@esbuild/linux-x64': 0.19.12 759 | '@esbuild/netbsd-x64': 0.19.12 760 | '@esbuild/openbsd-x64': 0.19.12 761 | '@esbuild/sunos-x64': 0.19.12 762 | '@esbuild/win32-arm64': 0.19.12 763 | '@esbuild/win32-ia32': 0.19.12 764 | '@esbuild/win32-x64': 0.19.12 765 | dev: true 766 | 767 | /execa@5.1.1: 768 | resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} 769 | engines: {node: '>=10'} 770 | dependencies: 771 | cross-spawn: 7.0.3 772 | get-stream: 6.0.1 773 | human-signals: 2.1.0 774 | is-stream: 2.0.1 775 | merge-stream: 2.0.0 776 | npm-run-path: 4.0.1 777 | onetime: 5.1.2 778 | signal-exit: 3.0.7 779 | strip-final-newline: 2.0.0 780 | dev: true 781 | 782 | /fast-glob@3.3.2: 783 | resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} 784 | engines: {node: '>=8.6.0'} 785 | dependencies: 786 | '@nodelib/fs.stat': 2.0.5 787 | '@nodelib/fs.walk': 1.2.8 788 | glob-parent: 5.1.2 789 | merge2: 1.4.1 790 | micromatch: 4.0.5 791 | 792 | /fastq@1.17.1: 793 | resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} 794 | dependencies: 795 | reusify: 1.0.4 796 | 797 | /fill-range@7.0.1: 798 | resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} 799 | engines: {node: '>=8'} 800 | dependencies: 801 | to-regex-range: 5.0.1 802 | 803 | /foreground-child@3.1.1: 804 | resolution: {integrity: sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==} 805 | engines: {node: '>=14'} 806 | dependencies: 807 | cross-spawn: 7.0.3 808 | signal-exit: 4.1.0 809 | dev: true 810 | 811 | /fsevents@2.3.3: 812 | resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} 813 | engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} 814 | os: [darwin] 815 | requiresBuild: true 816 | dev: true 817 | optional: true 818 | 819 | /get-stream@6.0.1: 820 | resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} 821 | engines: {node: '>=10'} 822 | dev: true 823 | 824 | /glob-parent@5.1.2: 825 | resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} 826 | engines: {node: '>= 6'} 827 | dependencies: 828 | is-glob: 4.0.3 829 | 830 | /glob@10.3.12: 831 | resolution: {integrity: sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==} 832 | engines: {node: '>=16 || 14 >=14.17'} 833 | hasBin: true 834 | dependencies: 835 | foreground-child: 3.1.1 836 | jackspeak: 2.3.6 837 | minimatch: 9.0.4 838 | minipass: 7.0.4 839 | path-scurry: 1.10.2 840 | dev: true 841 | 842 | /globby@11.1.0: 843 | resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} 844 | engines: {node: '>=10'} 845 | dependencies: 846 | array-union: 2.1.0 847 | dir-glob: 3.0.1 848 | fast-glob: 3.3.2 849 | ignore: 5.3.1 850 | merge2: 1.4.1 851 | slash: 3.0.0 852 | dev: true 853 | 854 | /has-flag@4.0.0: 855 | resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} 856 | engines: {node: '>=8'} 857 | dev: false 858 | 859 | /human-signals@2.1.0: 860 | resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} 861 | engines: {node: '>=10.17.0'} 862 | dev: true 863 | 864 | /ignore@5.3.1: 865 | resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==} 866 | engines: {node: '>= 4'} 867 | dev: true 868 | 869 | /is-binary-path@2.1.0: 870 | resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} 871 | engines: {node: '>=8'} 872 | dependencies: 873 | binary-extensions: 2.3.0 874 | dev: true 875 | 876 | /is-extglob@2.1.1: 877 | resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} 878 | engines: {node: '>=0.10.0'} 879 | 880 | /is-fullwidth-code-point@3.0.0: 881 | resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} 882 | engines: {node: '>=8'} 883 | dev: true 884 | 885 | /is-glob@4.0.3: 886 | resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} 887 | engines: {node: '>=0.10.0'} 888 | dependencies: 889 | is-extglob: 2.1.1 890 | 891 | /is-number@7.0.0: 892 | resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} 893 | engines: {node: '>=0.12.0'} 894 | 895 | /is-stream@2.0.1: 896 | resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} 897 | engines: {node: '>=8'} 898 | dev: true 899 | 900 | /isexe@2.0.0: 901 | resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} 902 | dev: true 903 | 904 | /jackspeak@2.3.6: 905 | resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==} 906 | engines: {node: '>=14'} 907 | dependencies: 908 | '@isaacs/cliui': 8.0.2 909 | optionalDependencies: 910 | '@pkgjs/parseargs': 0.11.0 911 | dev: true 912 | 913 | /joycon@3.1.1: 914 | resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} 915 | engines: {node: '>=10'} 916 | dev: true 917 | 918 | /lilconfig@3.1.1: 919 | resolution: {integrity: sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==} 920 | engines: {node: '>=14'} 921 | dev: true 922 | 923 | /lines-and-columns@1.2.4: 924 | resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} 925 | dev: true 926 | 927 | /load-tsconfig@0.2.5: 928 | resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} 929 | engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} 930 | dev: true 931 | 932 | /lodash.sortby@4.7.0: 933 | resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} 934 | dev: true 935 | 936 | /lru-cache@10.2.0: 937 | resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} 938 | engines: {node: 14 || >=16.14} 939 | dev: true 940 | 941 | /merge-stream@2.0.0: 942 | resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} 943 | dev: true 944 | 945 | /merge2@1.4.1: 946 | resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} 947 | engines: {node: '>= 8'} 948 | 949 | /micromatch@4.0.5: 950 | resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} 951 | engines: {node: '>=8.6'} 952 | dependencies: 953 | braces: 3.0.2 954 | picomatch: 2.3.1 955 | 956 | /mimic-fn@2.1.0: 957 | resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} 958 | engines: {node: '>=6'} 959 | dev: true 960 | 961 | /minimatch@9.0.4: 962 | resolution: {integrity: sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==} 963 | engines: {node: '>=16 || 14 >=14.17'} 964 | dependencies: 965 | brace-expansion: 2.0.1 966 | dev: true 967 | 968 | /minipass@7.0.4: 969 | resolution: {integrity: sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==} 970 | engines: {node: '>=16 || 14 >=14.17'} 971 | dev: true 972 | 973 | /ms@2.1.2: 974 | resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} 975 | 976 | /mz@2.7.0: 977 | resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} 978 | dependencies: 979 | any-promise: 1.3.0 980 | object-assign: 4.1.1 981 | thenify-all: 1.6.0 982 | dev: true 983 | 984 | /nan@2.19.0: 985 | resolution: {integrity: sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw==} 986 | dev: true 987 | 988 | /normalize-path@3.0.0: 989 | resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} 990 | engines: {node: '>=0.10.0'} 991 | dev: true 992 | 993 | /npm-run-path@4.0.1: 994 | resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} 995 | engines: {node: '>=8'} 996 | dependencies: 997 | path-key: 3.1.1 998 | dev: true 999 | 1000 | /object-assign@4.1.1: 1001 | resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} 1002 | engines: {node: '>=0.10.0'} 1003 | dev: true 1004 | 1005 | /onetime@5.1.2: 1006 | resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} 1007 | engines: {node: '>=6'} 1008 | dependencies: 1009 | mimic-fn: 2.1.0 1010 | dev: true 1011 | 1012 | /path-key@3.1.1: 1013 | resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} 1014 | engines: {node: '>=8'} 1015 | dev: true 1016 | 1017 | /path-scurry@1.10.2: 1018 | resolution: {integrity: sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==} 1019 | engines: {node: '>=16 || 14 >=14.17'} 1020 | dependencies: 1021 | lru-cache: 10.2.0 1022 | minipass: 7.0.4 1023 | dev: true 1024 | 1025 | /path-type@4.0.0: 1026 | resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} 1027 | engines: {node: '>=8'} 1028 | dev: true 1029 | 1030 | /picomatch@2.3.1: 1031 | resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} 1032 | engines: {node: '>=8.6'} 1033 | 1034 | /pirates@4.0.6: 1035 | resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==} 1036 | engines: {node: '>= 6'} 1037 | dev: true 1038 | 1039 | /postcss-load-config@4.0.2: 1040 | resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==} 1041 | engines: {node: '>= 14'} 1042 | peerDependencies: 1043 | postcss: '>=8.0.9' 1044 | ts-node: '>=9.0.0' 1045 | peerDependenciesMeta: 1046 | postcss: 1047 | optional: true 1048 | ts-node: 1049 | optional: true 1050 | dependencies: 1051 | lilconfig: 3.1.1 1052 | yaml: 2.4.1 1053 | dev: true 1054 | 1055 | /punycode@2.3.1: 1056 | resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} 1057 | engines: {node: '>=6'} 1058 | dev: true 1059 | 1060 | /queue-microtask@1.2.3: 1061 | resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} 1062 | 1063 | /readdirp@3.6.0: 1064 | resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} 1065 | engines: {node: '>=8.10.0'} 1066 | dependencies: 1067 | picomatch: 2.3.1 1068 | dev: true 1069 | 1070 | /resolve-from@5.0.0: 1071 | resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} 1072 | engines: {node: '>=8'} 1073 | dev: true 1074 | 1075 | /reusify@1.0.4: 1076 | resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} 1077 | engines: {iojs: '>=1.0.0', node: '>=0.10.0'} 1078 | 1079 | /rollup@4.14.2: 1080 | resolution: {integrity: sha512-WkeoTWvuBoFjFAhsEOHKRoZ3r9GfTyhh7Vff1zwebEFLEFjT1lG3784xEgKiTa7E+e70vsC81roVL2MP4tgEEQ==} 1081 | engines: {node: '>=18.0.0', npm: '>=8.0.0'} 1082 | hasBin: true 1083 | dependencies: 1084 | '@types/estree': 1.0.5 1085 | optionalDependencies: 1086 | '@rollup/rollup-android-arm-eabi': 4.14.2 1087 | '@rollup/rollup-android-arm64': 4.14.2 1088 | '@rollup/rollup-darwin-arm64': 4.14.2 1089 | '@rollup/rollup-darwin-x64': 4.14.2 1090 | '@rollup/rollup-linux-arm-gnueabihf': 4.14.2 1091 | '@rollup/rollup-linux-arm64-gnu': 4.14.2 1092 | '@rollup/rollup-linux-arm64-musl': 4.14.2 1093 | '@rollup/rollup-linux-powerpc64le-gnu': 4.14.2 1094 | '@rollup/rollup-linux-riscv64-gnu': 4.14.2 1095 | '@rollup/rollup-linux-s390x-gnu': 4.14.2 1096 | '@rollup/rollup-linux-x64-gnu': 4.14.2 1097 | '@rollup/rollup-linux-x64-musl': 4.14.2 1098 | '@rollup/rollup-win32-arm64-msvc': 4.14.2 1099 | '@rollup/rollup-win32-ia32-msvc': 4.14.2 1100 | '@rollup/rollup-win32-x64-msvc': 4.14.2 1101 | fsevents: 2.3.3 1102 | dev: true 1103 | 1104 | /run-parallel@1.2.0: 1105 | resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} 1106 | dependencies: 1107 | queue-microtask: 1.2.3 1108 | 1109 | /shebang-command@2.0.0: 1110 | resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} 1111 | engines: {node: '>=8'} 1112 | dependencies: 1113 | shebang-regex: 3.0.0 1114 | dev: true 1115 | 1116 | /shebang-regex@3.0.0: 1117 | resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} 1118 | engines: {node: '>=8'} 1119 | dev: true 1120 | 1121 | /signal-exit@3.0.7: 1122 | resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} 1123 | dev: true 1124 | 1125 | /signal-exit@4.1.0: 1126 | resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} 1127 | engines: {node: '>=14'} 1128 | dev: true 1129 | 1130 | /slash@3.0.0: 1131 | resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} 1132 | engines: {node: '>=8'} 1133 | dev: true 1134 | 1135 | /source-map@0.8.0-beta.0: 1136 | resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} 1137 | engines: {node: '>= 8'} 1138 | dependencies: 1139 | whatwg-url: 7.1.0 1140 | dev: true 1141 | 1142 | /string-width@4.2.3: 1143 | resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} 1144 | engines: {node: '>=8'} 1145 | dependencies: 1146 | emoji-regex: 8.0.0 1147 | is-fullwidth-code-point: 3.0.0 1148 | strip-ansi: 6.0.1 1149 | dev: true 1150 | 1151 | /string-width@5.1.2: 1152 | resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} 1153 | engines: {node: '>=12'} 1154 | dependencies: 1155 | eastasianwidth: 0.2.0 1156 | emoji-regex: 9.2.2 1157 | strip-ansi: 7.1.0 1158 | dev: true 1159 | 1160 | /strip-ansi@6.0.1: 1161 | resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} 1162 | engines: {node: '>=8'} 1163 | dependencies: 1164 | ansi-regex: 5.0.1 1165 | 1166 | /strip-ansi@7.1.0: 1167 | resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} 1168 | engines: {node: '>=12'} 1169 | dependencies: 1170 | ansi-regex: 6.0.1 1171 | dev: true 1172 | 1173 | /strip-final-newline@2.0.0: 1174 | resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} 1175 | engines: {node: '>=6'} 1176 | dev: true 1177 | 1178 | /sucrase@3.35.0: 1179 | resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==} 1180 | engines: {node: '>=16 || 14 >=14.17'} 1181 | hasBin: true 1182 | dependencies: 1183 | '@jridgewell/gen-mapping': 0.3.5 1184 | commander: 4.1.1 1185 | glob: 10.3.12 1186 | lines-and-columns: 1.2.4 1187 | mz: 2.7.0 1188 | pirates: 4.0.6 1189 | ts-interface-checker: 0.1.13 1190 | dev: true 1191 | 1192 | /supports-color@7.2.0: 1193 | resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} 1194 | engines: {node: '>=8'} 1195 | dependencies: 1196 | has-flag: 4.0.0 1197 | dev: false 1198 | 1199 | /thenify-all@1.6.0: 1200 | resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} 1201 | engines: {node: '>=0.8'} 1202 | dependencies: 1203 | thenify: 3.3.1 1204 | dev: true 1205 | 1206 | /thenify@3.3.1: 1207 | resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} 1208 | dependencies: 1209 | any-promise: 1.3.0 1210 | dev: true 1211 | 1212 | /to-regex-range@5.0.1: 1213 | resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} 1214 | engines: {node: '>=8.0'} 1215 | dependencies: 1216 | is-number: 7.0.0 1217 | 1218 | /tr46@1.0.1: 1219 | resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} 1220 | dependencies: 1221 | punycode: 2.3.1 1222 | dev: true 1223 | 1224 | /tree-kill@1.2.2: 1225 | resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} 1226 | hasBin: true 1227 | dev: true 1228 | 1229 | /tree-sitter-c@0.20.8: 1230 | resolution: {integrity: sha512-1393KNfnj67sCpoUjvTa2w1zU1h/3WvZ3Oz/kQzpMQhOjJURTbHAiMguKbBHhveGcoiPWc19bObfybTOWxVorA==} 1231 | requiresBuild: true 1232 | dependencies: 1233 | nan: 2.19.0 1234 | dev: true 1235 | 1236 | /tree-sitter-cli@0.21.0: 1237 | resolution: {integrity: sha512-wA7wT5724fNQW82XDH6zT6ZcYonjrAKLCHHuhLsPcAKULrhp3rNuMvlgBdB5FUBvmjHNhtTZF/qpHenMoRJPBw==} 1238 | hasBin: true 1239 | requiresBuild: true 1240 | dev: true 1241 | 1242 | /tree-sitter-cpp@0.20.5: 1243 | resolution: {integrity: sha512-x/q7iveXtvQaWUcCeuL6gVtBeC6vo8CoiTNGFWhgiaNlNeI9dun0+qJWhpjfOfEYnRRYnkvvnjDmn6/oBjFsjQ==} 1244 | requiresBuild: true 1245 | dependencies: 1246 | nan: 2.19.0 1247 | dev: true 1248 | 1249 | /ts-interface-checker@0.1.13: 1250 | resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} 1251 | dev: true 1252 | 1253 | /tsup@8.0.2: 1254 | resolution: {integrity: sha512-NY8xtQXdH7hDUAZwcQdY/Vzlw9johQsaqf7iwZ6g1DOUlFYQ5/AtVAjTvihhEyeRlGo4dLRVHtrRaL35M1daqQ==} 1255 | engines: {node: '>=18'} 1256 | hasBin: true 1257 | peerDependencies: 1258 | '@microsoft/api-extractor': ^7.36.0 1259 | '@swc/core': ^1 1260 | postcss: ^8.4.12 1261 | typescript: '>=4.5.0' 1262 | peerDependenciesMeta: 1263 | '@microsoft/api-extractor': 1264 | optional: true 1265 | '@swc/core': 1266 | optional: true 1267 | postcss: 1268 | optional: true 1269 | typescript: 1270 | optional: true 1271 | dependencies: 1272 | bundle-require: 4.0.2(esbuild@0.19.12) 1273 | cac: 6.7.14 1274 | chokidar: 3.6.0 1275 | debug: 4.3.4 1276 | esbuild: 0.19.12 1277 | execa: 5.1.1 1278 | globby: 11.1.0 1279 | joycon: 3.1.1 1280 | postcss-load-config: 4.0.2 1281 | resolve-from: 5.0.0 1282 | rollup: 4.14.2 1283 | source-map: 0.8.0-beta.0 1284 | sucrase: 3.35.0 1285 | tree-kill: 1.2.2 1286 | transitivePeerDependencies: 1287 | - supports-color 1288 | - ts-node 1289 | dev: true 1290 | 1291 | /typescript@5.4.5: 1292 | resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} 1293 | engines: {node: '>=14.17'} 1294 | hasBin: true 1295 | dev: false 1296 | 1297 | /undici-types@5.26.5: 1298 | resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} 1299 | dev: true 1300 | 1301 | /web-tree-sitter@0.21.0: 1302 | resolution: {integrity: sha512-iJ+QJ6ikN9D9cG7Kh6q3KtAstYFUQbYZ8OjuPEJYWfj2kLrmp5I3C2n6WjE1Y3jvj7nJbkcrJytJGWUEhCxn+g==} 1303 | dev: false 1304 | 1305 | /webidl-conversions@4.0.2: 1306 | resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} 1307 | dev: true 1308 | 1309 | /whatwg-url@7.1.0: 1310 | resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} 1311 | dependencies: 1312 | lodash.sortby: 4.7.0 1313 | tr46: 1.0.1 1314 | webidl-conversions: 4.0.2 1315 | dev: true 1316 | 1317 | /which@2.0.2: 1318 | resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} 1319 | engines: {node: '>= 8'} 1320 | hasBin: true 1321 | dependencies: 1322 | isexe: 2.0.0 1323 | dev: true 1324 | 1325 | /wrap-ansi@7.0.0: 1326 | resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} 1327 | engines: {node: '>=10'} 1328 | dependencies: 1329 | ansi-styles: 4.3.0 1330 | string-width: 4.2.3 1331 | strip-ansi: 6.0.1 1332 | dev: true 1333 | 1334 | /wrap-ansi@8.1.0: 1335 | resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} 1336 | engines: {node: '>=12'} 1337 | dependencies: 1338 | ansi-styles: 6.2.1 1339 | string-width: 5.1.2 1340 | strip-ansi: 7.1.0 1341 | dev: true 1342 | 1343 | /yaml@2.4.1: 1344 | resolution: {integrity: sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==} 1345 | engines: {node: '>= 14'} 1346 | hasBin: true 1347 | dev: true 1348 | --------------------------------------------------------------------------------