@alien_intelligence/eslint-plugin-nitpicker 0.7.6 → 0.7.7
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 +37 -22
- package/dist/index.js +14 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/constants.ts","../src/lib/utils/rules.ts","../src/lib/rule.ts","../src/lib/utils/messages.ts","../src/lib/utils/migrations.ts","../src/rules/adonisjs/migrationTableOrder.ts","../src/lib/utils/controllers.ts","../src/lib/utils/words.ts","../src/lib/utils/comments.ts","../src/lib/utils/jsdocs.ts","../src/rules/adonisjs/requireControllerJSDoc.ts","../src/rules/adonisjs/requireMigrationJSDoc.ts","../src/lib/utils/regex.ts","../src/rules/adonisjs/requireValidatedRequest.ts","../src/rules/base/catchErrorName.ts","../src/rules/base/maxJSDocDescriptionLength.ts","../src/lib/utils/aliases.ts","../src/rules/base/noAliasVariables.ts","../src/lib/data/britishToAmerican.ts","../src/lib/utils/dictionaries.ts","../src/rules/base/noBritishEnglish.ts","../src/lib/utils/decorations.ts","../src/rules/base/noDecorativeCommentSeparators.ts","../src/lib/utils/locations.ts","../src/rules/base/noEmDash.ts","../src/rules/base/noEmojis.ts","../src/rules/base/noJSDocBlankBeforeTags.ts","../src/lib/utils/functions.ts","../src/rules/base/noJSDocReturnsOnVoid.ts","../src/rules/base/noLineCommentBackticks.ts","../src/rules/base/noLineCommentPeriod.ts","../src/rules/base/noPropertyAccessAlias.ts","../src/rules/base/noPropertyDestructuring.ts","../src/rules/base/noRelativeImports.ts","../src/rules/base/noSingleLineJSDoc.ts","../src/rules/base/requireCapitalizedComments.ts","../src/lib/utils/react.ts","../src/rules/base/requireCompleteJSDoc.ts","../src/lib/utils/frameworks.ts","../src/rules/base/requireFrameworkConfig.ts","../src/rules/base/requireFunctionJSDoc.ts","../src/lib/utils/objects.ts","../src/rules/base/requireMultilineObject.ts","../src/rules/react/maxClassNameLength.ts","../src/rules/react/noJSXComments.ts","../src/rules/react/requireContextHookDestructure.ts","../src/rules/react/requireDerivedUseMemo.ts","../src/rules/react/requireHookObjectReturn.ts","../src/rules/react/requireMemoCallbackJSDoc.ts","../src/rules/index.ts","../src/configs/helpers.ts","../src/configs/presets/all.ts","../src/configs/rulesets/base.ts","../src/configs/presets/recommended.ts","../src/configs/rulesets/adonisjs.ts","../src/configs/rulesets/react.ts","../src/configs/index.ts","../package.json","../src/index.ts"],"names":["CONSTANTS","constants_default","createRule","ESLintUtils","NitpickerRule","context","options","nitpick","problem","why","fix","isMigrationClass","node","getCreateTableBuilder","callback","getTableStatementCategory","statement","builderName","root","rootBuilderCall","expression","current","firstArgument","literal","MigrationTableOrder","builder","maxRank","category","rank","migrationTableOrder_default","isControllerClass","extractWords","text","words","match","matchCase","source","replacement","isWordChar","char","isDirectiveComment","comment","firstCommentContentChar","base","offset","line","markerLength","findProsePeriods","periods","quote","index","rest","endsWithAbbreviation","findBacktickSpans","spans","closing","lowercase","abbreviation","before","isJSDocComment","jsDocAnchor","declaration","earliest","found","decorator","getLeadingJSDoc","sourceCode","commentsBefore","closest","getJSDocParamNames","names","name","hasJSDocReturnsTag","tag","getJSDocLineTag","hasLeadingJSDoc","isBlankJSDocLine","isJSDocTagLine","getJSDocDescription","parts","content","findJSDocReturnsRange","tagLine","to","RequireControllerJSDoc","requireControllerJSDoc_default","RequireMigrationJSDoc","requireMigrationJSDoc_default","globToRegExp","glob","normalized","pattern","matchesGlob","filename","patterns","path","RequireValidatedRequest","allowIn","isRequest","requireValidatedRequest_default","CatchErrorName","catchErrorName_default","DEFAULT_MAX","MaxJSDocDescriptionLength","max","length","maxJSDocDescriptionLength_default","propertyAccessPath","properties","isPropertyAccessAlias","isReassigned","scope","variable","ASTUtils","declarations","definition","reference","isPathWritten","written","target","isAllShorthand","property","NoAliasVariables","noAliasVariables_default","BRITISH_TO_AMERICAN","buildDictionary","extra","ignore","dictionary","key","value","NoBritishEnglish","word","american","cased","from","fixer","noBritishEnglish_default","isDecorativeCommentLine","NoDecorativeCommentSeparators","lines","reportedLine","noDecorativeCommentSeparators_default","TOKEN_TYPES","allowedRanges","allow","locations","ranges","tokenTypes","location","type","token","isInAnyRange","start","end","NoEmDash","noEmDash_default","NoEmojis","noEmojis_default","NoJSDocBlankBeforeTags","runEnd","nextLine","noJSDocBlankBeforeTags_default","getDocumentableNode","fn","isTopLevel","parameterDocs","docs","collect","param","enclosingFunction","isDynamicImportThunk","getFunctionName","someReturn","visitorKeys","predicate","children","child","childNode","functionReturnsValue","argument","isVoidReturnType","annotation","isVoidFunction","NoJSDocReturnsOnVoid","check","anchor","jsdoc","range","noJSDocReturnsOnVoid_default","NoLineCommentBackticks","span","noLineCommentBackticks_default","NoLineCommentPeriod","period","loc","noLineCommentPeriod_default","NoPropertyAccessAlias","candidates","recordWrite","candidate","noPropertyAccessAlias_default","NoPropertyDestructuring","noPropertyDestructuring_default","NoRelativeImports","noRelativeImports_default","NoSingleLineJSDoc","indent","expanded","noSingleLineJSDoc_default","RequireCapitalizedComments","isContinuation","previous","requireCapitalizedComments_default","isReactComponentName","isHookName","isContextHookName","isFunctionValue","isJsxExpression","functionReturnsJsx","isComponentOrHook","hasNonHookCall","isDerivedValue","RequireCompleteJSDoc","documented","plainNames","doc","entry","requireCompleteJSDoc_default","FRAMEWORK_LABELS","importSources","sources","detectFrameworks","detected","RequireFrameworkConfig","ignored","enabled","framework","requireFrameworkConfig_default","RequireFunctionJSDoc","reportNode","documentable","requireFunctionJSDoc_default","expandObjectLiteral","baseIndent","propertyIndent","RequireMultilineObject","maxKeys","hasComments","requireMultilineObject_default","MaxClassNameLength","maxClassNameLength_default","NoJSXComments","noJSXComments_default","RequireContextHookDestructure","requireContextHookDestructure_default","RequireDerivedUseMemo","requireDerivedUseMemo_default","RequireHookObjectReturn","returnsFunction","declarator","report","requireHookObjectReturn_default","RequireMemoCallbackJSDoc","requireMemoCallbackJSDoc_default","ruleInstances","rules","rule","categoryRules","allRules","all","plugin","recommended","ROUTE_FILE_GLOBS","adonisjs","react","buildConfigs","version","index_default"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The global set of constants shared across the plugin, grouped by domain.\n */\nconst CONSTANTS = {\n /**\n * The short name the plugin is registered under inside an ESLint config,\n * e.g. `nitpicker/no-em-dash`.\n */\n PLUGIN_NAME: \"nitpicker\",\n\n /**\n * The base URL of the plugin's repository.\n */\n REPO_URL: \"https://github.com/Alien-Intelligence/eslint-plugin-nitpicker\",\n\n /**\n * The em dash character (U+2014), e.g. \"—\".\n */\n EM_DASH: \"—\",\n\n /**\n * Matches a single emoji as one unit: flag pairs, skin-tone and\n * variation-selector modifiers, and ZWJ sequences. Text-default pictographs\n * like © match only when emoji-styled with a variation selector.\n */\n EMOJI: /\\p{Regional_Indicator}\\p{Regional_Indicator}|\\p{Emoji_Presentation}(?:\\uFE0F|\\p{Emoji_Modifier})?(?:\\u200D\\p{Emoji_Presentation}(?:\\uFE0F|\\p{Emoji_Modifier})?)*|\\p{Extended_Pictographic}\\uFE0F/gu,\n\n /**\n * Constants for scanning comments.\n */\n COMMENTS: {\n /**\n * Box-drawing and block-element characters, which are always decorative\n * when found inside a comment.\n */\n BOX_DRAWING: /[─-▟]/,\n\n /**\n * A comment line made entirely of three or more repeated separator\n * characters, e.g. `======` or `------`.\n */\n PURE_SEPARATOR: /^[-=~*#_+]{3,}$/,\n\n /**\n * A short label fenced by separator runs inside a comment, e.g `-- Section --`.\n */\n WRAPPED_LABEL: /^[-=~*#_+]{2,}\\s.*\\s[-=~*#_+]{2,}$/,\n\n /**\n * A tooling directive comment (eslint, ts-, biome-ignore, etc.) rather\n * than prose, matched against the comment text.\n */\n DIRECTIVE:\n /^\\s*(?:eslint\\b|eslint-|globals?\\b|exported\\b|jshint\\b|jslint\\b|istanbul\\b|[cv]8\\b|ts-|prettier-ignore|biome-ignore|webpack\\b|noinspection\\b|@)/,\n\n /**\n * Quote characters that fence a verbatim span inside a comment, whose\n * dots belong to the quoted text rather than the surrounding prose. The\n * apostrophe is absent, as it appears unpaired in words like \"don't\".\n */\n QUOTES: new Set(['\"', \"`\"]),\n\n /**\n * Abbreviations whose trailing dot is part of the word itself, so it must\n * survive even though it looks like the end of a sentence.\n */\n ABBREVIATIONS: [\"e.g.\", \"i.e.\", \"etc.\", \"vs.\", \"cf.\", \"al.\", \"approx.\", \"resp.\"],\n },\n\n /**\n * Constants for inspecting JSDoc structure.\n */\n JSDOC: {\n /**\n * Matches a JSDoc block-tag line, capturing the tag name so callers can\n * find any tag (`param`, `returns`, `throws`, etc.).\n */\n TAG: /^\\s*\\*?\\s*@(\\w+)/,\n\n /**\n * Matches an `@param` line and captures the documented name, tolerating a\n * leading `{Type}` and an optional `[name]` or `[name=default]` form. A\n * dotted member such as `input.id` captures its root, `input`.\n */\n PARAM_TAG: /^\\s*\\*?\\s*@param\\s+(?:\\{[^}]*\\}\\s*)?\\[?([\\w$]+)/,\n },\n\n /**\n * Constants for splitting and inspecting words.\n */\n WORDS: {\n /**\n * Matches a single \"word\" character, i.e. anything that can appear inside\n * an identifier or a number (letters, digits, underscore and dollar).\n */\n WORD_CHAR: /[\\p{L}\\p{N}_$]/u,\n\n /**\n * Matches a single sub-word: an all-caps acronym, a capitalized word, or a\n * lowercase run, so `getUserName` splits into \"get\", \"User\" and \"Name\"\n */\n SUB_WORD: /[A-Z]+(?![a-z])|[A-Z][a-z]+|[a-z]+/g,\n },\n\n /**\n * Constants for object literals.\n */\n OBJECTS: {\n /**\n * The default maximum number of properties an object literal may keep on\n * a single line before it must be broken across multiple lines.\n */\n MAX_INLINE_KEYS: 2,\n\n /**\n * The default number of spaces per indentation level used when expanding\n * an object literal across multiple lines.\n */\n INDENT_WIDTH: 4,\n },\n\n /**\n * Constants for inspecting functions.\n */\n FUNCTIONS: {\n /**\n * The AST node types that introduce a new function scope.\n */\n NODE_TYPES: new Set([\"FunctionDeclaration\", \"FunctionExpression\", \"ArrowFunctionExpression\"]),\n },\n\n /**\n * Constants for detecting framework usage.\n */\n FRAMEWORKS: {\n /**\n * AdonisJS subpath import roots (`#models/...`, `#controllers/...`, etc.).\n */\n ADONIS_SUBPATH:\n /^#(models|controllers|services|middleware|validators|policies|config|start|database|providers|lib)\\b/,\n\n /**\n * React source files by extension.\n */\n REACT_FILE: /\\.[jt]sx$/,\n },\n\n /**\n * Constants for React semantics.\n */\n REACT: {\n /**\n * A React hook name: `use` followed by a capitalized word, e.g.\n * `useState` or `useMenuActions`.\n */\n HOOK: /^use[A-Z]/,\n\n /**\n * A context-consumer hook name, i.e. a `use…Context` wrapper such as\n * `useTreeViewContext` (the bare `useContext` is excluded).\n */\n CONTEXT_HOOK: /^use[A-Z]\\w*Context$/,\n\n /**\n * The memoization hooks whose result is worth documenting with a JSDoc.\n */\n MEMO_HOOKS: new Set([\"useMemo\", \"useCallback\"]),\n },\n\n /**\n * Constants for AdonisJS request handling.\n */\n REQUEST: {\n /**\n * The raw request accessors that read request data directly, bypassing\n * the Vine validator contract.\n */\n RAW_ACCESSORS: new Set([\"input\", \"body\", \"qs\", \"all\", \"only\", \"except\"]),\n },\n\n /**\n * Constants for AdonisJS migrations.\n */\n MIGRATIONS: {\n /**\n * Table-builder methods that declare an index or a constraint.\n */\n INDEX_METHODS: new Set([\"index\", \"unique\", \"primary\", \"foreign\"]),\n\n /**\n * Table-builder methods that declare a timestamp column.\n */\n TIMESTAMP_METHODS: new Set([\"timestamp\", \"dateTime\", \"datetime\"]),\n\n /**\n * Audit timestamp column names that form a migration's dedicated\n * timestamps group.\n */\n AUDIT_TIMESTAMPS: new Set([\"created_at\", \"updated_at\", \"deleted_at\"]),\n\n /**\n * The order table statements must be grouped in: columns first, then\n * timestamps, then indexes and constraints.\n */\n CATEGORY_ORDER: [\"column\", \"timestamp\", \"index\"],\n },\n} as const\n\nexport default CONSTANTS\n","import { ESLintUtils } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\n\n/**\n * The category a rule belongs to, which decides the shared config it ships in.\n */\nexport type RuleCategory = \"base\" | \"adonisjs\" | \"react\"\n\n/**\n * Extra metadata attached to every Nitpicker rule under `meta.docs`.\n */\nexport type NitpickerRuleDocs = {\n /**\n * A short, human-readable description of what the rule enforces.\n */\n description: string\n\n /**\n * Whether the rule is part of the `recommended` shared config.\n */\n recommended?: boolean\n\n /**\n * The category the rule belongs to, defaults to `base` when omitted.\n */\n category?: RuleCategory\n}\n\n/**\n * The shared rule factory for the whole plugin.\n */\nexport const createRule = ESLintUtils.RuleCreator<NitpickerRuleDocs>(\n () => `${CONSTANTS.REPO_URL}/blob/main/README.md#rules`,\n)\n","import { ESLintUtils, type TSESLint } from \"@typescript-eslint/utils\"\nimport { createRule, type NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\n/**\n * The base class every Nitpicker rule extends, so a rule only declares its name,\n * metadata, options, and visitor logic. Call {@link toRuleModule} to turn an\n * instance into the plain object ESLint expects.\n */\nexport abstract class NitpickerRule<MessageIds extends string = string, Options extends readonly unknown[] = []> {\n /**\n * The kebab-case name of the rule, without the plugin prefix\n * (e.g. `no-em-dash`).\n */\n abstract readonly name: string\n\n /**\n * The ESLint metadata describing the rule (type, docs, schema, messages).\n */\n abstract readonly meta: ESLintUtils.NamedCreateRuleMeta<MessageIds, NitpickerRuleDocs, Options>\n\n /**\n * The options applied when the rule is enabled without an explicit config.\n */\n abstract readonly defaultOptions: Options\n\n /**\n * The visitor factory ESLint calls for every linted file.\n * @param context The rule context for the current file.\n * @param options The user options merged with {@link defaultOptions}.\n * @returns The AST visitor listeners.\n */\n abstract create(\n context: Readonly<TSESLint.RuleContext<MessageIds, Options>>,\n options: Readonly<Options>,\n ): TSESLint.RuleListener\n\n /**\n * Builds the ESLint-compatible rule module from this instance.\n * @returns The plain rule module object consumed by ESLint.\n */\n toRuleModule(): TSESLint.RuleModule<MessageIds, Options, NitpickerRuleDocs> {\n return createRule<Options, MessageIds>({\n name: this.name,\n meta: this.meta,\n defaultOptions: this.defaultOptions,\n create: (context, options) => this.create(context, options),\n })\n }\n}\n","/**\n * The building blocks of a Nitpicker message.\n */\nexport type Nitpick = {\n /**\n * What is wrong, stated plainly, may contain ESLint `{{placeholders}}`.\n */\n problem: string\n\n /**\n * Why it is worth fixing, so the reader understands the intent.\n */\n why: string\n\n /**\n * A concrete, actionable instruction describing how to fix it.\n */\n fix: string\n}\n\n/**\n * Composes a {@link Nitpick} into one message string for a rule's\n * `meta.messages` entry, leaving any ESLint `{{placeholders}}` intact.\n * @param nitpick The problem/why/fix triplet to format.\n * @returns The formatted, multi-line message.\n */\nexport function nitpick({ problem, why, fix }: Nitpick): string {\n return `${problem}\\n - why: ${why}\\n - fix: ${fix}`\n}\n","import type { TSESTree } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\n\n/**\n * A category a `createTable` builder statement falls into, used to keep a\n * migration's columns, timestamps, and indexes grouped in that order.\n */\nexport type TableCategory = \"column\" | \"timestamp\" | \"index\"\n\n/**\n * Checks whether a class is an AdonisJS migration, i.e. a default-exported class\n * that extends `BaseSchema`.\n * @param node The class declaration to inspect.\n * @returns True if the class is a migration.\n */\nexport function isMigrationClass(node: TSESTree.ClassDeclaration): boolean {\n return (\n node.parent.type === \"ExportDefaultDeclaration\" &&\n node.superClass?.type === \"Identifier\" &&\n node.superClass.name === \"BaseSchema\"\n )\n}\n\n/**\n * Resolves the `this.schema.createTable(name, builder => { ... })` builder body\n * from a call expression, if the call is one.\n * @param node The call expression to inspect.\n * @returns The builder statements and parameter name, or `null`.\n */\nexport function getCreateTableBuilder(node: TSESTree.CallExpression): {\n body: TSESTree.Statement[]\n builderName: string\n} | null {\n if (node.callee.type !== \"MemberExpression\" || node.callee.property.type !== \"Identifier\") return null\n if (node.callee.property.name !== \"createTable\") return null\n\n // Require a schema receiver so only Lucid migration calls match\n if (node.callee.object.type !== \"MemberExpression\" || node.callee.object.property.type !== \"Identifier\") return null\n if (node.callee.object.property.name !== \"schema\") return null\n\n const callback = node.arguments.at(-1)\n if (callback?.type !== \"ArrowFunctionExpression\" && callback?.type !== \"FunctionExpression\") return null\n if (callback.body.type !== \"BlockStatement\" || callback.params[0]?.type !== \"Identifier\") return null\n\n return { body: callback.body.body, builderName: callback.params[0].name }\n}\n\n/**\n * Resolves the category of a single `createTable` builder statement.\n * @param statement The statement to categorize.\n * @param builderName The name of the table builder parameter.\n * @returns The category, or `null` when the statement is not ordered: either it\n * is not a builder call, or it is a domain timestamp such as `expires_at`, which\n * reads fine among the columns or beside the audit timestamps.\n */\nexport function getTableStatementCategory(statement: TSESTree.Statement, builderName: string): TableCategory | null {\n if (statement.type !== \"ExpressionStatement\") return null\n\n const root = rootBuilderCall(statement.expression, builderName)\n if (root === null) return null\n\n if (CONSTANTS.MIGRATIONS.INDEX_METHODS.has(root.method)) return \"index\"\n if (root.method === \"timestamps\") return \"timestamp\"\n\n if (CONSTANTS.MIGRATIONS.TIMESTAMP_METHODS.has(root.method)) {\n if (root.firstArgument !== undefined && CONSTANTS.MIGRATIONS.AUDIT_TIMESTAMPS.has(root.firstArgument)) {\n return \"timestamp\"\n }\n\n // A domain timestamp carries meaning of its own rather than tracking a\n // row's lifecycle, so it is not forced into either group\n return null\n }\n\n return \"column\"\n}\n\n/**\n * Walks a chained builder expression down to the first call on the builder, e.g.\n * `table.integer(\"x\").notNullable()` resolves to `integer` with argument `\"x\"`.\n * @param expression The (possibly chained) expression to walk.\n * @param builderName The name of the table builder parameter.\n * @returns The base method and its first string argument, or `null`.\n */\nfunction rootBuilderCall(\n expression: TSESTree.Expression,\n builderName: string,\n): { method: string; firstArgument: string | undefined } | null {\n let current: TSESTree.Node = expression\n\n while (current.type === \"CallExpression\" && current.callee.type === \"MemberExpression\") {\n if (current.callee.object.type === \"Identifier\" && current.callee.object.name === builderName) {\n if (current.callee.property.type !== \"Identifier\") return null\n\n const firstArgument = current.arguments[0]\n const literal =\n firstArgument?.type === \"Literal\" && typeof firstArgument.value === \"string\"\n ? firstArgument.value\n : undefined\n\n return { method: current.callee.property.name, firstArgument: literal }\n }\n\n current = current.callee.object\n }\n\n return null\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { getCreateTableBuilder, getTableStatementCategory } from \"@/lib/utils/migrations\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"outOfOrder\"\n\n/**\n * Enforces that a migration's `createTable` statements stay grouped in order:\n * columns, then audit timestamps, then indexes and constraints, this keeps every\n * migration structured the same way without needing section-label comments.\n */\nclass MigrationTableOrder extends NitpickerRule<MessageIds, Options> {\n readonly name = \"migration-table-order\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Group migration table statements as columns, then timestamps, then indexes and constraints.\",\n recommended: true,\n category: \"adonisjs\",\n },\n schema: [],\n messages: {\n outOfOrder: nitpick({\n problem: \"This {{category}} is out of order in the table definition.\",\n why: \"A migration reads consistently when columns come first, then timestamps, then indexes and constraints, each grouped together\",\n fix: \"Move it into its group so the order stays columns, timestamps, then indexes and constraints\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n CallExpression(node) {\n const builder = getCreateTableBuilder(node)\n if (builder === null) return\n\n let maxRank = 0\n\n for (const statement of builder.body) {\n const category = getTableStatementCategory(statement, builder.builderName)\n if (category === null) continue\n\n const rank = CONSTANTS.MIGRATIONS.CATEGORY_ORDER.indexOf(category)\n if (rank < maxRank) {\n context.report({\n node: statement,\n messageId: \"outOfOrder\",\n data: { category },\n })\n }\n\n maxRank = Math.max(maxRank, rank)\n }\n },\n }\n }\n}\n\nexport default new MigrationTableOrder()\n","import type { TSESTree } from \"@typescript-eslint/utils\"\n\n/**\n * Checks whether a class is an AdonisJS controller, i.e. a default-exported\n * class whose name ends with `Controller`.\n * @param node The class declaration to inspect.\n * @returns True if the class is a controller.\n */\nexport function isControllerClass(node: TSESTree.ClassDeclaration): boolean {\n return node.parent.type === \"ExportDefaultDeclaration\" && node.id?.name.endsWith(\"Controller\") === true\n}\n","import CONSTANTS from \"@/lib/constants\"\n\n/**\n * A sub-word found in a piece of text, with its start offset.\n */\nexport type Word = {\n /**\n * The sub-word, in its original casing.\n */\n text: string\n\n /**\n * The offset of the sub-word within the source text.\n */\n index: number\n}\n\n/**\n * Splits a piece of text into its sub-words, handling camelCase, PascalCase,\n * snake_case, and plain prose.\n * @param text The text to split.\n * @returns The sub-words found, each with its offset in the text.\n */\nexport function extractWords(text: string): Word[] {\n const words: Word[] = []\n\n for (const match of text.matchAll(CONSTANTS.WORDS.SUB_WORD)) {\n if (match.index !== undefined) {\n words.push({ text: match[0], index: match.index })\n }\n }\n\n return words\n}\n\n/**\n * Rewrites a replacement word to match the casing of the word it replaces, so a\n * capitalized source yields a capitalized result and an all-caps source an\n * all-caps one.\n * @param source The original word whose casing should be mirrored.\n * @param replacement The lowercase replacement word.\n * @returns The replacement, cased like the source.\n */\nexport function matchCase(source: string, replacement: string): string {\n if (source === source.toUpperCase()) {\n return replacement.toUpperCase()\n }\n\n if (source.charAt(0) === source.charAt(0).toUpperCase()) {\n return replacement.charAt(0).toUpperCase() + replacement.slice(1)\n }\n\n return replacement\n}\n\n/**\n * Checks whether a character is a \"word\" character, i.e. something that can\n * appear inside an identifier or a number (letters, digits, underscore, dollar).\n * @param char The single character to test, or `undefined` (e.g. past the end\n * of a string).\n * @returns True if the character is a word character, false otherwise.\n */\nexport function isWordChar(char: string | undefined): boolean {\n return char !== undefined && CONSTANTS.WORDS.WORD_CHAR.test(char)\n}\n","import type { TSESTree } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { isWordChar } from \"@/lib/utils/words\"\n\n/**\n * The first prose character of a comment, with its absolute source index.\n */\ntype CommentContent = { index: number; char: string }\n\n/**\n * A period inside a comment that punctuates prose rather than belonging to a\n * code token, with its absolute source index.\n */\nexport type ProsePeriod = {\n /**\n * The absolute source index of the period character.\n */\n index: number\n\n /**\n * Whether the period closes the comment, i.e. only whitespace follows it, so\n * removing it cannot run two sentences together.\n */\n terminal: boolean\n}\n\n/**\n * A backtick-fenced span inside a comment, with the absolute source indices of\n * its two backticks and the text they wrap.\n */\nexport type BacktickSpan = {\n /**\n * The absolute source index of the opening backtick.\n */\n start: number\n\n /**\n * The absolute source index of the closing backtick.\n */\n end: number\n\n /**\n * The text between the two backticks.\n */\n text: string\n}\n\n/**\n * Checks whether a comment is a tooling directive (eslint, `ts-`, biome-ignore,\n * etc.) rather than prose, which should not be treated as an English sentence.\n * @param comment The comment to test.\n * @returns True if the comment is a directive.\n */\nexport function isDirectiveComment(comment: TSESTree.Comment): boolean {\n return CONSTANTS.COMMENTS.DIRECTIVE.test(comment.value)\n}\n\n/**\n * Finds the first prose character of a comment, skipping the `//` or `/*`\n * delimiters and, for a block comment, the per-line ` * ` markers, so callers\n * can inspect where the comment's text actually begins.\n * @param comment The comment to inspect.\n * @returns The first content character and its source index, or `null` if the\n * comment has no textual content.\n */\nexport function firstCommentContentChar(comment: TSESTree.Comment): CommentContent | null {\n // Skip past the opening \"//\" or \"/*\" delimiter\n const base = comment.range[0] + 2\n\n if (comment.type === \"Line\") {\n const match = comment.value.match(/\\S/u)\n if (match?.index === undefined) return null\n\n return {\n index: base + match.index,\n char: match[0],\n }\n }\n\n let offset = 0\n for (const line of comment.value.split(\"\\n\")) {\n // Strip leading whitespace and a single \" * \" marker; whatever remains is\n // the line's content, so a marker-only line is skipped\n const markerLength = (line.match(/^\\s*\\*?\\s*/u)?.[0] ?? \"\").length\n const char = line.slice(markerLength).charAt(0)\n\n if (char !== \"\") {\n return {\n index: base + offset + markerLength,\n char,\n }\n }\n\n offset += line.length + 1\n }\n\n return null\n}\n\n/**\n * Finds the periods inside a `//` comment that punctuate prose, skipping the ones\n * that belong to a code token (`foo.bar`, `subagent.*`), sit inside a quoted\n * span, form an ellipsis, or close an abbreviation such as `e.g.`.\n * @param comment The line comment to scan.\n * @returns The prose periods found, in source order.\n */\nexport function findProsePeriods(comment: TSESTree.Comment): ProsePeriod[] {\n const periods: ProsePeriod[] = []\n\n // The comment value starts right after the leading \"//\"\n const base = comment.range[0] + 2\n let quote: string | null = null\n\n for (let index = 0; index < comment.value.length; index++) {\n const char = comment.value.charAt(index)\n\n // Inside a quoted span everything is verbatim until it closes\n if (quote !== null) {\n if (char === quote) quote = null\n continue\n }\n\n // Only open a span when it actually closes, so an unpaired quote does not\n // swallow the rest of the comment\n if (CONSTANTS.COMMENTS.QUOTES.has(char) && comment.value.includes(char, index + 1)) {\n quote = char\n continue\n }\n\n if (char !== \".\") continue\n\n // A run of consecutive dots is an ellipsis, leave it alone\n if (comment.value.charAt(index + 1) === \".\") {\n while (comment.value.charAt(index + 1) === \".\") index++\n continue\n }\n\n const rest = comment.value.slice(index + 1)\n\n // A dot is prose punctuation only when whitespace or the end of the\n // comment follows it, anything else makes it part of a token\n if (rest !== \"\" && !/^\\s/u.test(rest)) continue\n\n if (endsWithAbbreviation(comment.value.slice(0, index + 1))) continue\n\n periods.push({\n index: base + index,\n terminal: rest.trim() === \"\",\n })\n }\n\n return periods\n}\n\n/**\n * Finds the backtick-fenced spans inside a comment, skipping runs of backticks\n * (a code fence), an unpaired backtick, and any span already holding a double\n * quote, none of which survive being rewritten as a quoted span.\n * @param comment The comment to scan.\n * @returns The spans found, in source order.\n */\nexport function findBacktickSpans(comment: TSESTree.Comment): BacktickSpan[] {\n const spans: BacktickSpan[] = []\n\n // The comment value starts right after the leading \"//\"\n const base = comment.range[0] + 2\n\n for (let index = 0; index < comment.value.length; index++) {\n if (comment.value.charAt(index) !== \"`\") continue\n\n // A run of backticks fences a code block, which quotes cannot stand in for\n if (comment.value.charAt(index + 1) === \"`\") {\n while (comment.value.charAt(index + 1) === \"`\") index++\n continue\n }\n\n const closing = comment.value.indexOf(\"`\", index + 1)\n if (closing === -1) break\n\n const text = comment.value.slice(index + 1, closing)\n\n // Rewriting a span that already holds a double quote would nest quotes\n if (!text.includes('\"')) {\n spans.push({\n start: base + index,\n end: base + closing,\n text,\n })\n }\n\n index = closing\n }\n\n return spans\n}\n\n/**\n * Checks whether a piece of comment text ends with an abbreviation whose\n * trailing dot is part of the word, e.g. `e.g.` or `etc.`.\n * @param text The comment text up to and including the dot.\n * @returns True if the dot closes an abbreviation.\n */\nfunction endsWithAbbreviation(text: string): boolean {\n const lowercase = text.toLowerCase()\n\n return CONSTANTS.COMMENTS.ABBREVIATIONS.some(abbreviation => {\n if (!lowercase.endsWith(abbreviation)) return false\n\n // Require a boundary before the abbreviation so \"foo.al\" is not one\n const before = lowercase.charAt(lowercase.length - abbreviation.length - 1)\n return before === \"\" || !isWordChar(before)\n })\n}\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { isDirectiveComment } from \"@/lib/utils/comments\"\n\n/**\n * Checks whether a comment is a JSDoc comment, i.e. a block comment that opens\n * with `/**`.\n * @param comment The comment to test.\n * @returns True if the comment is a JSDoc block comment.\n */\nexport function isJSDocComment(comment: TSESTree.Comment): boolean {\n return comment.type === \"Block\" && comment.value.startsWith(\"*\")\n}\n\n/**\n * Resolves the node a JSDoc comment sits above, which for a decorated\n * declaration is its earliest decorator, since decorators are written between the\n * JSDoc and the declaration they belong to.\n * @param node The node to anchor the JSDoc lookup on.\n * @returns The node whose leading comments hold the JSDoc.\n */\nexport function jsDocAnchor(node: TSESTree.Node): TSESTree.Node {\n const declaration =\n (node.type === \"ExportDefaultDeclaration\" || node.type === \"ExportNamedDeclaration\") &&\n node.declaration !== null\n ? node.declaration\n : node\n\n const decorators = \"decorators\" in declaration ? declaration.decorators : undefined\n\n // Only a decorator written before the declaration shifts the anchor, the\n // \"export default @dec class\" form leaves the JSDoc above the export\n const earliest = decorators?.reduce<TSESTree.Decorator | undefined>(\n (found, decorator) => (found === undefined || decorator.range[0] < found.range[0] ? decorator : found),\n undefined,\n )\n\n return earliest !== undefined && earliest.range[0] < node.range[0] ? earliest : node\n}\n\n/**\n * Resolves the JSDoc comment documenting a node, if it has one.\n * @param sourceCode The source code of the linted file.\n * @param node The node to inspect the leading comments of.\n * @returns The JSDoc comment, or `null` when the node is undocumented.\n */\nexport function getLeadingJSDoc(\n sourceCode: Readonly<TSESLint.SourceCode>,\n node: TSESTree.Node,\n): TSESTree.Comment | null {\n const commentsBefore = sourceCode.getCommentsBefore(jsDocAnchor(node))\n\n // Skip trailing ignore directives (biome-ignore, eslint-*, @ts-*) that can\n // sit between the JSDoc and the node, so the JSDoc above them still counts\n let index = commentsBefore.length - 1\n while (index >= 0) {\n const comment = commentsBefore[index]\n if (comment === undefined || !isDirectiveComment(comment)) break\n index--\n }\n\n const closest = commentsBefore[index]\n return closest !== undefined && isJSDocComment(closest) ? closest : null\n}\n\n/**\n * Collects the parameter names a JSDoc documents, keyed on the root name so a\n * dotted member tag such as `@param input.id` counts as documenting `input`.\n * @param comment The JSDoc comment to read.\n * @returns The documented parameter names.\n */\nexport function getJSDocParamNames(comment: TSESTree.Comment): Set<string> {\n const names = new Set<string>()\n\n for (const line of comment.value.split(\"\\n\")) {\n const name = line.match(CONSTANTS.JSDOC.PARAM_TAG)?.[1]\n if (name !== undefined) names.add(name)\n }\n\n return names\n}\n\n/**\n * Checks whether a JSDoc carries a `@returns` (or `@return`) tag.\n * @param comment The JSDoc comment to read.\n * @returns True if the JSDoc documents a return value.\n */\nexport function hasJSDocReturnsTag(comment: TSESTree.Comment): boolean {\n return comment.value.split(\"\\n\").some(line => {\n const tag = getJSDocLineTag(line)\n return tag === \"returns\" || tag === \"return\"\n })\n}\n\n/**\n * Checks whether a node is immediately preceded by a JSDoc comment.\n * @param sourceCode The source code of the linted file.\n * @param node The node to inspect the leading comments of.\n * @returns True if the comment right before the node is a JSDoc comment.\n */\nexport function hasLeadingJSDoc(sourceCode: Readonly<TSESLint.SourceCode>, node: TSESTree.Node): boolean {\n return getLeadingJSDoc(sourceCode, node) !== null\n}\n\n/**\n * Checks whether a physical JSDoc line is blank, i.e. just a ` * ` with no\n * content after it.\n * @param line The physical source line to test.\n * @returns True if the line is an empty JSDoc line.\n */\nexport function isBlankJSDocLine(line: string): boolean {\n return /^\\s*\\*\\s*$/.test(line)\n}\n\n/**\n * Resolves the block-tag name a JSDoc line starts with, e.g. `param` or\n * `returns`, or `null` if the line is not a tag line.\n * @param line The physical source line to inspect.\n * @returns The tag name without its `@`, or `null`.\n */\nexport function getJSDocLineTag(line: string): string | null {\n const match = line.match(CONSTANTS.JSDOC.TAG)\n return match?.[1] ?? null\n}\n\n/**\n * Checks whether a physical JSDoc line holds a block tag, i.e. a ` * ` followed\n * by an `@tag` such as `@param` or `@returns`.\n * @param line The physical source line to test.\n * @returns True if the line starts a JSDoc tag.\n */\nexport function isJSDocTagLine(line: string): boolean {\n return getJSDocLineTag(line) !== null\n}\n\n/**\n * Extracts the description prose of a JSDoc comment, i.e. everything before the\n * first block tag, with the ` * ` markers stripped and wrapped lines joined into\n * a single space-separated string.\n * @param comment The JSDoc comment to read.\n * @returns The description as one collapsed prose string.\n */\nexport function getJSDocDescription(comment: TSESTree.Comment): string {\n const parts: string[] = []\n\n for (const line of comment.value.split(\"\\n\")) {\n const content = line.replace(/^\\s*\\*? ?/, \"\").trimEnd()\n if (content.startsWith(\"@\")) break\n\n parts.push(content)\n }\n\n return parts.join(\" \").replace(/\\s+/g, \" \").trim()\n}\n\n/**\n * Finds the source-line range of a JSDoc comment's `@returns` (or `@return`)\n * block, spanning the tag line down to the line before the next tag or the\n * closing `*/`.\n * @param sourceCode The source code of the linted file.\n * @param comment The JSDoc comment to inspect.\n * @returns The inclusive `from`/`to` source lines, or `null` if there is none.\n */\nexport function findJSDocReturnsRange(\n sourceCode: Readonly<TSESLint.SourceCode>,\n comment: TSESTree.Comment,\n): { from: number; to: number } | null {\n let tagLine = -1\n for (let line = comment.loc.start.line + 1; line < comment.loc.end.line; line++) {\n const tag = getJSDocLineTag(sourceCode.lines[line - 1] ?? \"\")\n if (tag === \"returns\" || tag === \"return\") {\n tagLine = line\n break\n }\n }\n\n if (tagLine === -1) return null\n\n let to = comment.loc.end.line - 1\n for (let line = tagLine + 1; line < comment.loc.end.line; line++) {\n if (isJSDocTagLine(sourceCode.lines[line - 1] ?? \"\")) {\n to = line - 1\n break\n }\n }\n\n return {\n from: tagLine,\n to,\n }\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { isControllerClass } from \"@/lib/utils/controllers\"\nimport { hasLeadingJSDoc } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"missingJSDoc\"\n\n/**\n * Requires a JSDoc comment above an AdonisJS controller (a default-exported\n * class whose name ends with `Controller`) so the responsibility it serves is\n * documented at a glance, before diving into its handler methods.\n */\nclass RequireControllerJSDoc extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-controller-jsdoc\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require a JSDoc comment describing an AdonisJS controller.\",\n recommended: true,\n category: \"adonisjs\",\n },\n schema: [],\n messages: {\n missingJSDoc: nitpick({\n problem: \"This controller has no JSDoc describing what it does.\",\n why: \"A controller's responsibility should be readable at a glance, before diving into its handler methods\",\n fix: \"Add a `/** ... */` JSDoc above the controller class summarizing what it handles\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n ClassDeclaration(node) {\n if (!isControllerClass(node)) return\n if (hasLeadingJSDoc(context.sourceCode, node.parent)) return\n\n context.report({ node: node.id ?? node, messageId: \"missingJSDoc\" })\n },\n }\n }\n}\n\nexport default new RequireControllerJSDoc()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { hasLeadingJSDoc } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { isMigrationClass } from \"@/lib/utils/migrations\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"missingJSDoc\"\n\n/**\n * Requires a JSDoc comment above an AdonisJS migration (a default-exported class\n * extending `BaseSchema`) so its intent is documented, the timestamped filename\n * alone does not convey what the migration changes.\n */\nclass RequireMigrationJSDoc extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-migration-jsdoc\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require a JSDoc comment describing an AdonisJS migration.\",\n recommended: true,\n category: \"adonisjs\",\n },\n schema: [],\n messages: {\n missingJSDoc: nitpick({\n problem: \"This migration has no JSDoc describing what it does.\",\n why: \"A migration's intent should be readable at a glance, the timestamped filename does not convey the schema change\",\n fix: \"Add a `/** ... */` JSDoc above the migration class summarizing the change\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n ClassDeclaration(node) {\n if (!isMigrationClass(node)) return\n if (hasLeadingJSDoc(context.sourceCode, node.parent)) return\n\n context.report({ node: node.id ?? node, messageId: \"missingJSDoc\" })\n },\n }\n }\n}\n\nexport default new RequireMigrationJSDoc()\n","/**\n * Converts a glob pattern into an anchored regular expression, supporting `*`\n * (any run within a path segment) and `**` (any run across segments).\n * @param glob The glob pattern to convert.\n * @returns The equivalent regular expression.\n */\nfunction globToRegExp(glob: string): RegExp {\n const normalized = glob.replace(/\\\\/g, \"/\")\n let pattern = \"^\"\n\n for (let index = 0; index < normalized.length; index++) {\n const char = normalized[index]\n if (char === undefined) break\n\n if (char === \"*\") {\n if (normalized[index + 1] === \"*\") {\n pattern += \".*\"\n index++\n\n // If the \"**\" is followed by a \"/\", skip it so that \"**/\" and \"**\" are equivalent\n if (normalized[index + 1] === \"/\") index++\n } else {\n pattern += \"[^/]*\"\n }\n } else if (\"\\\\^$.|?+()[]{}\".includes(char)) {\n pattern += `\\\\${char}`\n } else {\n pattern += char\n }\n }\n\n return new RegExp(`${pattern}$`)\n}\n\n/**\n * Checks whether a file path matches any of the given glob patterns, comparing\n * with forward slashes so it works the same on every platform.\n * @param filename The file path to test.\n * @param patterns The glob patterns to match against.\n * @returns True if the path matches at least one pattern.\n */\nexport function matchesGlob(filename: string, patterns: string[]): boolean {\n const path = filename.replace(/\\\\/g, \"/\")\n\n return patterns.some(pattern => globToRegExp(pattern).test(path))\n}\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { matchesGlob } from \"@/lib/utils/regex\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ allowIn: string[] }]\ntype MessageIds = \"rawRead\"\n\n/**\n * Flags a raw `request.input()`, `request.body()`, `request.qs()`, etc. read, so\n * request data goes through `request.validateUsing(validator)` instead, the\n * `allowIn` option lists globs (e.g. passthrough proxy controllers) that are\n * exempt.\n */\nclass RequireValidatedRequest extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-validated-request\"\n\n readonly defaultOptions: Options = [{ allowIn: [] }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require request data to be read through a Vine validator, not raw request accessors.\",\n recommended: true,\n category: \"adonisjs\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n allowIn: {\n type: \"array\",\n items: { type: \"string\" },\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n rawRead: nitpick({\n problem: \"`request.{{method}}()` reads request data directly.\",\n why: \"Request data must pass through a Vine validator so it is typed and checked, a raw accessor bypasses that contract\",\n fix: \"Read it through `request.validateUsing(someValidator)` instead\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const allowIn = options[0]?.allowIn ?? []\n if (allowIn.length > 0 && matchesGlob(context.filename, allowIn)) {\n return {}\n }\n\n // Whether an expression refers to the HttpContext \"request\", whether bound\n // directly or reached through \"ctx.request\" / \"this.ctx.request\"\n const isRequest = (node: TSESTree.Node): boolean => {\n if (node.type === \"Identifier\") return node.name === \"request\"\n return (\n node.type === \"MemberExpression\" &&\n node.property.type === \"Identifier\" &&\n node.property.name === \"request\"\n )\n }\n\n return {\n CallExpression(node) {\n if (node.callee.type !== \"MemberExpression\" || node.callee.property.type !== \"Identifier\") return\n if (!CONSTANTS.REQUEST.RAW_ACCESSORS.has(node.callee.property.name) || !isRequest(node.callee.object))\n return\n\n context.report({\n node: node.callee.property,\n messageId: \"rawRead\",\n data: {\n method: node.callee.property.name,\n },\n })\n },\n }\n }\n}\n\nexport default new RequireValidatedRequest()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"rename\"\n\n/**\n * Flags a `catch` clause that binds its error under any name other than `error`\n * (an underscore-prefixed name such as `_error` is allowed for a deliberately\n * unused binding), so error handling reads the same everywhere.\n */\nclass CatchErrorName extends NitpickerRule<MessageIds, Options> {\n readonly name = \"catch-error-name\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require a `catch` clause to bind its error as `error`.\",\n recommended: true,\n category: \"base\",\n },\n schema: [],\n messages: {\n rename: nitpick({\n problem: \"This `catch` binds the error as `{{name}}`.\",\n why: \"Every catch binds the error as `error` so error handling reads the same across the codebase\",\n fix: \"Rename the binding to `error`, or `_error` if it is intentionally unused\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n CatchClause(node) {\n // A bare catch with no binding, or a destructured binding, is left alone\n if (node.param?.type !== \"Identifier\") return\n if (node.param.name === \"error\" || node.param.name.startsWith(\"_\")) return\n\n context.report({\n node: node.param,\n messageId: \"rename\",\n data: { name: node.param.name },\n })\n },\n }\n }\n}\n\nexport default new CatchErrorName()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { getJSDocDescription, isJSDocComment } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ max: number }]\ntype MessageIds = \"tooLong\"\n\nconst DEFAULT_MAX = 250\n\n/**\n * Flags JSDoc comments whose description (the prose before the first tag) is\n * longer than the configured character limit, catching the oversized,\n * essay-like blocks AI models tend to produce.\n */\nclass MaxJSDocDescriptionLength extends NitpickerRule<MessageIds, Options> {\n readonly name = \"max-jsdoc-description-length\"\n\n readonly defaultOptions: Options = [{ max: DEFAULT_MAX }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Enforce a maximum character length for a JSDoc description.\",\n recommended: true,\n category: \"base\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n max: { type: \"integer\", minimum: 1 },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n tooLong: nitpick({\n problem: \"This JSDoc description is {{length}} characters, over the {{max}}-character limit.\",\n why: \"A JSDoc description should summarize what something is, an oversized one usually restates the code or explains how it is used, which does not belong here\",\n fix: 'Trim it to a concise summary of what it does, and remove any note about how or where it is used (e.g \"used by X to ...\", \"called from Y\"), which is an anti-pattern',\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const max = options[0]?.max ?? DEFAULT_MAX\n\n return {\n Program() {\n for (const comment of context.sourceCode.getAllComments()) {\n if (!isJSDocComment(comment)) continue\n\n const length = getJSDocDescription(comment).length\n if (length <= max) continue\n\n context.report({\n loc: comment.loc,\n messageId: \"tooLong\",\n data: { length, max },\n })\n }\n },\n }\n }\n}\n\nexport default new MaxJSDocDescriptionLength()\n","import { ASTUtils, type TSESLint, type TSESTree } from \"@typescript-eslint/utils\"\n\n/**\n * Builds the dotted path of a pure property access chain, i.e. one made only of\n * non-computed member accesses (with any `?.` or `!`) bottoming out at an\n * identifier or `this`, such as `auth.user!` or `menu.node.path`.\n * @param node The expression to inspect.\n * @returns The dotted path, e.g. `auth.user`, or `null` if the expression is not\n * a plain property access.\n */\nexport function propertyAccessPath(node: TSESTree.Expression): string | null {\n const properties: string[] = []\n let expression: TSESTree.Node = node\n\n while (true) {\n if (expression.type === \"ChainExpression\" || expression.type === \"TSNonNullExpression\") {\n expression = expression.expression\n continue\n }\n\n if (expression.type === \"MemberExpression\") {\n if (expression.computed) return null\n if (expression.property.type !== \"Identifier\") return null\n\n properties.unshift(expression.property.name)\n expression = expression.object\n continue\n }\n\n break\n }\n\n if (properties.length === 0) return null\n if (expression.type === \"ThisExpression\") return [\"this\", ...properties].join(\".\")\n if (expression.type === \"Identifier\") return [expression.name, ...properties].join(\".\")\n\n return null\n}\n\n/**\n * Checks whether an expression is nothing but a non-computed property access\n * chain (with any `?.` or `!`) bottoming out at an identifier or `this`, such as\n * `auth.user!` or `menu.node.path`.\n * @param node The expression to inspect.\n * @returns True if the expression is a plain property access.\n */\nexport function isPropertyAccessAlias(node: TSESTree.Expression): boolean {\n return propertyAccessPath(node) !== null\n}\n\n/**\n * Checks whether a binding is written to after its declaration, which makes an\n * alias of it a snapshot of the value at that point rather than a rename.\n * @param scope The scope the alias is declared in.\n * @param name The name of the source binding.\n * @returns True if the binding is reassigned somewhere.\n */\nexport function isReassigned(scope: TSESLint.Scope.Scope, name: string): boolean {\n const variable = ASTUtils.findVariable(scope, name)\n\n // An unresolved name is a global or an ambient declaration, so it is stable\n if (variable === null) return false\n\n const declarations = new Set<TSESTree.Node>(variable.defs.map(definition => definition.name))\n\n return variable.references.some(reference => reference.isWrite() && !declarations.has(reference.identifier))\n}\n\n/**\n * Checks whether a property path, or a prefix of it, is written to, which makes\n * an alias of that path a snapshot rather than a rename.\n * @param written The property paths written to in the file.\n * @param path The property path the alias reads.\n * @returns True if the path or one of its prefixes is written to.\n */\nexport function isPathWritten(written: ReadonlySet<string>, path: string): boolean {\n for (const target of written) {\n if (path === target || path.startsWith(`${target}.`)) return true\n }\n\n return false\n}\n\n/**\n * Checks whether an object pattern is nothing but plain shorthand properties,\n * i.e. `{ a, b }` with no rename, default, computed key, or rest element, which\n * makes it a pure alias of the object it destructures.\n * @param pattern The object pattern to inspect.\n * @returns True if every property is a pure shorthand grab.\n */\nexport function isAllShorthand(pattern: TSESTree.ObjectPattern): boolean {\n if (pattern.properties.length === 0) return false\n\n return pattern.properties.every(\n property =>\n property.type === \"Property\" &&\n property.shorthand &&\n !property.computed &&\n property.value.type === \"Identifier\",\n )\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { isReassigned } from \"@/lib/utils/aliases\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"alias\"\n\n/**\n * Flags a `const` whose entire value is another variable, such as\n * `const accessTokens = rawAccessTokens`, since it just renames the source. `let`,\n * exported bindings, annotated declarations, and snapshots of a reassigned source\n * are exempt.\n */\nclass NoAliasVariables extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-alias-variables\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Disallow a `const` whose whole value is another variable, use the source directly.\",\n recommended: true,\n category: \"base\",\n },\n schema: [],\n messages: {\n alias: nitpick({\n problem: \"`{{name}}` only aliases `{{source}}`.\",\n why: \"A variable that just renames another hides the original and adds a name to track for no gain\",\n fix: \"Remove it and use `{{source}}` directly, or rename `{{source}}` itself if the new name is better\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n VariableDeclarator(node) {\n if (node.parent.type !== \"VariableDeclaration\" || node.parent.kind !== \"const\") return\n\n // Exported bindings cannot be inlined away, so they are exempt\n if (node.parent.parent.type === \"ExportNamedDeclaration\") return\n\n if (node.id.type !== \"Identifier\" || node.init?.type !== \"Identifier\") return\n\n // A type annotation is a reason of its own to keep the binding, as\n // inlining it would drop the narrowing it applies\n if (node.id.typeAnnotation !== undefined) return\n\n // A reassigned source makes this a snapshot of its value here, not\n // a rename, so inlining it would change what the code does\n if (isReassigned(context.sourceCode.getScope(node), node.init.name)) return\n\n context.report({\n node,\n messageId: \"alias\",\n data: {\n name: node.id.name,\n source: node.init.name,\n },\n })\n },\n }\n }\n}\n\nexport default new NoAliasVariables()\n","/**\n * British English spellings mapped to their American equivalents, keyed in\n * lowercase. Extend it per project via the `no-british-english` rule's `extra`\n * option.\n */\nexport const BRITISH_TO_AMERICAN: Record<string, string> = {\n // \"-our\" to \"-or\"\n colour: \"color\",\n colours: \"colors\",\n coloured: \"colored\",\n colouring: \"coloring\",\n behaviour: \"behavior\",\n behaviours: \"behaviors\",\n favour: \"favor\",\n favours: \"favors\",\n favoured: \"favored\",\n favouring: \"favoring\",\n favourable: \"favorable\",\n favourite: \"favorite\",\n favourites: \"favorites\",\n flavour: \"flavor\",\n flavours: \"flavors\",\n honour: \"honor\",\n honours: \"honors\",\n honoured: \"honored\",\n honouring: \"honoring\",\n labour: \"labor\",\n labours: \"labors\",\n laboured: \"labored\",\n labouring: \"laboring\",\n neighbour: \"neighbor\",\n neighbours: \"neighbors\",\n humour: \"humor\",\n humours: \"humors\",\n rumour: \"rumor\",\n rumours: \"rumors\",\n harbour: \"harbor\",\n harbours: \"harbors\",\n endeavour: \"endeavor\",\n endeavours: \"endeavors\",\n endeavoured: \"endeavored\",\n endeavouring: \"endeavoring\",\n\n // \"-ise\" to \"-ize\" and their inflections\n normalise: \"normalize\",\n normalised: \"normalized\",\n normalising: \"normalizing\",\n normalisation: \"normalization\",\n initialise: \"initialize\",\n initialises: \"initializes\",\n initialised: \"initialized\",\n initialising: \"initializing\",\n initialisation: \"initialization\",\n serialise: \"serialize\",\n serialised: \"serialized\",\n serialising: \"serializing\",\n serialisation: \"serialization\",\n organise: \"organize\",\n organises: \"organizes\",\n organised: \"organized\",\n organising: \"organizing\",\n organisation: \"organization\",\n optimise: \"optimize\",\n optimised: \"optimized\",\n optimising: \"optimizing\",\n optimisation: \"optimization\",\n customise: \"customize\",\n customised: \"customized\",\n customising: \"customizing\",\n sanitise: \"sanitize\",\n sanitised: \"sanitized\",\n sanitising: \"sanitizing\",\n synchronise: \"synchronize\",\n synchronised: \"synchronized\",\n synchronising: \"synchronizing\",\n synchronisation: \"synchronization\",\n authorise: \"authorize\",\n authorised: \"authorized\",\n authorising: \"authorizing\",\n authorisation: \"authorization\",\n finalise: \"finalize\",\n finalised: \"finalized\",\n finalising: \"finalizing\",\n capitalise: \"capitalize\",\n capitalised: \"capitalized\",\n capitalising: \"capitalizing\",\n categorise: \"categorize\",\n categorises: \"categorizes\",\n categorised: \"categorized\",\n categorising: \"categorizing\",\n categorisation: \"categorization\",\n utilise: \"utilize\",\n utilises: \"utilizes\",\n utilised: \"utilized\",\n utilising: \"utilizing\",\n utilisation: \"utilization\",\n realise: \"realize\",\n realises: \"realizes\",\n realised: \"realized\",\n realising: \"realizing\",\n realisation: \"realization\",\n recognise: \"recognize\",\n recognises: \"recognizes\",\n recognised: \"recognized\",\n recognising: \"recognizing\",\n summarise: \"summarize\",\n summarises: \"summarizes\",\n summarised: \"summarized\",\n summarising: \"summarizing\",\n specialise: \"specialize\",\n specialises: \"specializes\",\n specialised: \"specialized\",\n specialising: \"specializing\",\n specialisation: \"specialization\",\n minimise: \"minimize\",\n minimises: \"minimizes\",\n minimised: \"minimized\",\n minimising: \"minimizing\",\n minimisation: \"minimization\",\n maximise: \"maximize\",\n maximises: \"maximizes\",\n maximised: \"maximized\",\n maximising: \"maximizing\",\n maximisation: \"maximization\",\n prioritise: \"prioritize\",\n prioritises: \"prioritizes\",\n prioritised: \"prioritized\",\n prioritising: \"prioritizing\",\n prioritisation: \"prioritization\",\n standardise: \"standardize\",\n standardises: \"standardizes\",\n standardised: \"standardized\",\n standardising: \"standardizing\",\n standardisation: \"standardization\",\n harmonise: \"harmonize\",\n harmonises: \"harmonizes\",\n harmonised: \"harmonized\",\n harmonising: \"harmonizing\",\n harmonisation: \"harmonization\",\n centralise: \"centralize\",\n centralises: \"centralizes\",\n centralised: \"centralized\",\n centralising: \"centralizing\",\n centralisation: \"centralization\",\n decentralise: \"decentralize\",\n decentralises: \"decentralizes\",\n decentralised: \"decentralized\",\n decentralising: \"decentralizing\",\n decentralisation: \"decentralization\",\n emphasise: \"emphasize\",\n emphasises: \"emphasizes\",\n emphasised: \"emphasized\",\n emphasising: \"emphasizing\",\n visualise: \"visualize\",\n visualises: \"visualizes\",\n visualised: \"visualized\",\n visualising: \"visualizing\",\n visualisation: \"visualization\",\n\n // \"-yse\" to \"-yze\"\n analyse: \"analyze\",\n analyses: \"analyzes\",\n analysed: \"analyzed\",\n analysing: \"analyzing\",\n paralyse: \"paralyze\",\n paralyses: \"paralyzes\",\n paralysed: \"paralyzed\",\n paralysing: \"paralyzing\",\n\n // \"-re\" to \"-er\"\n centre: \"center\",\n centred: \"centered\",\n centres: \"centers\",\n fibre: \"fiber\",\n fibres: \"fibers\",\n metre: \"meter\",\n metres: \"meters\",\n litre: \"liter\",\n litres: \"liters\",\n theatre: \"theater\",\n theatres: \"theaters\",\n calibre: \"caliber\",\n spectre: \"specter\",\n spectres: \"specters\",\n\n // \"-ce\" to \"-se\"\n licence: \"license\",\n defence: \"defense\",\n offence: \"offense\",\n pretence: \"pretense\",\n practise: \"practice\",\n\n // Doubled \"l\" in inflections\n cancelled: \"canceled\",\n cancelling: \"canceling\",\n labelled: \"labeled\",\n labelling: \"labeling\",\n modelled: \"modeled\",\n modelling: \"modeling\",\n travelled: \"traveled\",\n travelling: \"traveling\",\n signalled: \"signaled\",\n signalling: \"signaling\",\n fuelled: \"fueled\",\n fuelling: \"fueling\",\n marvellous: \"marvelous\",\n counsellor: \"counselor\",\n\n // Single \"l\" that doubles in American English\n fulfil: \"fulfill\",\n fulfils: \"fulfills\",\n fulfilment: \"fulfillment\",\n enrol: \"enroll\",\n enrols: \"enrolls\",\n enrolment: \"enrollment\",\n instalment: \"installment\",\n skilful: \"skillful\",\n wilful: \"willful\",\n\n // \"-ogue\" to \"-og\"\n dialogue: \"dialog\",\n dialogues: \"dialogs\",\n catalogue: \"catalog\",\n catalogues: \"catalogs\",\n analogue: \"analog\",\n analogues: \"analogs\",\n\n // Miscellaneous\n grey: \"gray\",\n artefact: \"artifact\",\n artefacts: \"artifacts\",\n sceptic: \"skeptic\",\n sceptical: \"skeptical\",\n programme: \"program\",\n programmes: \"programs\",\n enquiry: \"inquiry\",\n enquiries: \"inquiries\",\n aluminium: \"aluminum\",\n tyre: \"tire\",\n tyres: \"tires\",\n}\n","/**\n * Merges a base lookup with extra entries and removes ignored keys, keying everything in lowercase\n * for case-insensitive lookups. Used to let a rule's built-in table be extended or narrowed\n * through its options.\n * @param base The built-in lookup.\n * @param extra Additional entries to add or override.\n * @param ignore Keys to remove from the result.\n * @returns The merged, lowercase-keyed lookup.\n */\nexport function buildDictionary(\n base: Record<string, string>,\n extra: Record<string, string>,\n ignore: string[],\n): Record<string, string> {\n /**\n * A null-prototype object so lookups like `dictionary[\"constructor\"]` return\n * undefined instead of Object.prototype.constructor, which would otherwise\n * treat identifiers such as `BrowserWindowConstructorOptions` as matches.\n */\n const dictionary: Record<string, string> = Object.create(null)\n\n for (const [key, value] of Object.entries(base)) {\n dictionary[key.toLowerCase()] = value\n }\n\n for (const [key, value] of Object.entries(extra)) {\n dictionary[key.toLowerCase()] = value\n }\n\n for (const key of ignore) {\n delete dictionary[key.toLowerCase()]\n }\n\n return dictionary\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { BRITISH_TO_AMERICAN } from \"@/lib/data/britishToAmerican\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { buildDictionary } from \"@/lib/utils/dictionaries\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\nimport { extractWords, matchCase } from \"@/lib/utils/words\"\n\ntype Options = [{ extra: Record<string, string>; ignore: string[] }]\ntype MessageIds = \"british\"\n\n/**\n * Flags British English spellings in identifiers and comments, reporting the\n * American equivalent. The built-in dictionary can be extended per project with\n * the `extra` option, or narrowed with `ignore`.\n */\nclass NoBritishEnglish extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-british-english\"\n\n readonly defaultOptions: Options = [{ extra: {}, ignore: [] }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Disallow British English spellings in identifiers and comments.\",\n recommended: true,\n category: \"base\",\n },\n fixable: \"code\",\n schema: [\n {\n type: \"object\",\n properties: {\n extra: {\n type: \"object\",\n additionalProperties: { type: \"string\" },\n },\n ignore: {\n type: \"array\",\n items: { type: \"string\" },\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n british: nitpick({\n problem: \"British spelling `{{british}}`, this codebase uses American English.\",\n why: \"One spelling convention keeps identifiers and docs consistent and searchable\",\n fix: \"Use `{{american}}` instead\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const dictionary = buildDictionary(BRITISH_TO_AMERICAN, options[0]?.extra ?? {}, options[0]?.ignore ?? [])\n\n return {\n Identifier(node) {\n // Skip a member's property name (an external read), it cannot be\n // renamed from here\n if (node.parent.type === \"MemberExpression\" && node.parent.property === node && !node.parent.computed) {\n return\n }\n\n for (const word of extractWords(node.name)) {\n const american = dictionary[word.text.toLowerCase()]\n if (american === undefined) continue\n\n context.report({\n node,\n messageId: \"british\",\n data: { british: word.text, american: matchCase(word.text, american) },\n })\n }\n },\n Program() {\n for (const comment of context.sourceCode.getAllComments()) {\n for (const word of extractWords(comment.value)) {\n const american = dictionary[word.text.toLowerCase()]\n if (american === undefined) continue\n\n const cased = matchCase(word.text, american)\n\n // The comment value starts right after the \"//\" or \"/*\"\n const from = comment.range[0] + 2 + word.index\n const to = from + word.text.length\n\n context.report({\n loc: {\n start: context.sourceCode.getLocFromIndex(from),\n end: context.sourceCode.getLocFromIndex(to),\n },\n messageId: \"british\",\n data: { british: word.text, american: cased },\n fix: fixer => fixer.replaceTextRange([from, to], cased),\n })\n }\n }\n },\n }\n }\n}\n\nexport default new NoBritishEnglish()\n","import CONSTANTS from \"@/lib/constants\"\n\n/**\n * Checks whether a single comment line is a decorative separator, i.e. a banner,\n * a box-drawing rule, or a label fenced by repeated separator characters.\n * @param line The raw comment line, still carrying any leading ` * ` marker.\n * @returns True if the line is decorative.\n */\nexport function isDecorativeCommentLine(line: string): boolean {\n const content = line.replace(/^\\s*\\*?\\s*/, \"\").trimEnd()\n if (content.length === 0) return false\n\n return (\n CONSTANTS.COMMENTS.BOX_DRAWING.test(content) ||\n CONSTANTS.COMMENTS.PURE_SEPARATOR.test(content) ||\n CONSTANTS.COMMENTS.WRAPPED_LABEL.test(content)\n )\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { isDecorativeCommentLine } from \"@/lib/utils/decorations\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { matchesGlob } from \"@/lib/utils/regex\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ allowIn: string[] }]\ntype MessageIds = \"decorative\"\n\n/**\n * Flags decorative separators inside comments: banner rules (`// ======`),\n * box-drawing lines, and labels fenced by repeated dashes (`// -- Section --`),\n * the `allowIn` option lists globs where they are tolerated.\n */\nclass NoDecorativeCommentSeparators extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-decorative-comment-separators\"\n\n readonly defaultOptions: Options = [{ allowIn: [] }]\n\n readonly meta = {\n type: \"layout\",\n docs: {\n description: \"Disallow decorative separators (banners, box-drawing, repeated dashes) inside comments.\",\n recommended: true,\n category: \"base\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n allowIn: {\n type: \"array\",\n items: { type: \"string\" },\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n decorative: nitpick({\n problem: \"This comment uses a decorative separator.\",\n why: \"Repeated separator characters and box-drawing lines are visual noise that add nothing over a plain label\",\n fix: \"Remove the separator, a one-line label or a blank line already divides sections clearly\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const allowIn = options[0]?.allowIn ?? []\n if (allowIn.length > 0 && matchesGlob(context.filename, allowIn)) {\n return {}\n }\n\n return {\n Program() {\n for (const comment of context.sourceCode.getAllComments()) {\n const lines = comment.value.split(\"\\n\")\n\n for (let index = 0; index < lines.length; index++) {\n const line = lines[index]\n if (line === undefined || !isDecorativeCommentLine(line)) continue\n\n const reportedLine = comment.loc.start.line + index\n const source = context.sourceCode.lines[reportedLine - 1] ?? \"\"\n\n context.report({\n loc: {\n start: { line: reportedLine, column: 0 },\n end: { line: reportedLine, column: source.length },\n },\n messageId: \"decorative\",\n })\n }\n }\n },\n }\n }\n}\n\nexport default new NoDecorativeCommentSeparators()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\n\n/**\n * A place a flagged character may be tolerated, so user-facing copy, prompt\n * text, and glyphs can keep it while code and comments stay clean.\n */\nexport type SourceLocation = \"strings\" | \"templates\" | \"jsx\" | \"comments\"\n\n/**\n * The token type each location maps to, `comments` aside, as comments are not\n * tokens.\n */\nconst TOKEN_TYPES: Partial<Record<SourceLocation, string>> = {\n strings: \"String\",\n templates: \"Template\",\n jsx: \"JSXText\",\n}\n\n/**\n * Collects the source ranges covered by the given locations (string, template,\n * and JSX tokens, plus comments), so a raw-text scan can skip characters that\n * sit in copy the caller has chosen to allow.\n * @param sourceCode The source code of the linted file.\n * @param allow The locations to exempt.\n * @returns The exempt `[start, end]` ranges, empty when nothing is allowed.\n */\nexport function allowedRanges(\n sourceCode: Readonly<TSESLint.SourceCode>,\n allow: Iterable<SourceLocation>,\n): [number, number][] {\n const locations = new Set(allow)\n const ranges: [number, number][] = []\n if (locations.size === 0) return ranges\n\n const tokenTypes = new Set([...locations].map(location => TOKEN_TYPES[location]).filter(type => type !== undefined))\n\n for (const token of sourceCode.ast.tokens ?? []) {\n if (tokenTypes.has(token.type)) ranges.push(token.range)\n }\n\n if (locations.has(\"comments\")) {\n for (const comment of sourceCode.getAllComments()) {\n ranges.push(comment.range)\n }\n }\n\n return ranges\n}\n\n/**\n * Checks whether an index falls inside any of the given ranges.\n * @param index The source index to test.\n * @param ranges The `[start, end]` ranges to check against.\n * @returns True if the index sits within a range.\n */\nexport function isInAnyRange(index: number, ranges: [number, number][]): boolean {\n return ranges.some(([start, end]) => index >= start && index < end)\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { allowedRanges, isInAnyRange, type SourceLocation } from \"@/lib/utils/locations\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ allow?: SourceLocation[] }]\ntype MessageIds = \"emDash\"\n\n/**\n * Flags every em dash (—) character found anywhere in the source, except in the\n * locations the `allow` option exempts.\n */\nclass NoEmDash extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-em-dash\"\n\n readonly defaultOptions: Options = [{ allow: [] }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Disallow the em dash (—) character anywhere in the source.\",\n recommended: true,\n },\n schema: [\n {\n type: \"object\",\n properties: {\n allow: {\n type: \"array\",\n items: {\n type: \"string\",\n enum: [\"strings\", \"templates\", \"jsx\", \"comments\"],\n },\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n emDash: nitpick({\n problem: \"Found an em dash (—) character.\",\n why: \"Em dashes are typically introduced by AI-generated or auto-formatted text and are discouraged here.\",\n fix: \"Replace the em dash with a hyphen (-), a comma (,), or reword the sentence to avoid it, or allow it here with the rule's `allow` option if it is deliberate user-facing copy.\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n return {\n Program() {\n const text = context.sourceCode.getText()\n const ranges = allowedRanges(context.sourceCode, options[0]?.allow ?? [])\n\n // Scan the raw source so every em dash is caught, whether it appears\n // in code, strings, or comments\n for (let index = 0; index < text.length; index++) {\n if (text[index] !== CONSTANTS.EM_DASH) continue\n if (isInAnyRange(index, ranges)) continue\n\n context.report({\n loc: {\n start: context.sourceCode.getLocFromIndex(index),\n end: context.sourceCode.getLocFromIndex(index + 1),\n },\n messageId: \"emDash\",\n })\n }\n },\n }\n }\n}\n\nexport default new NoEmDash()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { allowedRanges, isInAnyRange, type SourceLocation } from \"@/lib/utils/locations\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ allow?: SourceLocation[] }]\ntype MessageIds = \"emoji\"\n\n/**\n * Flags every emoji in the source, except where the `allow` option exempts it.\n * Report-only, never auto-removing a glyph, since an emoji can carry meaning that\n * a silent deletion would lose.\n */\nclass NoEmojis extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-emojis\"\n\n readonly defaultOptions: Options = [{ allow: [] }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Disallow emoji characters anywhere in the source.\",\n recommended: true,\n category: \"base\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n allow: {\n type: \"array\",\n items: {\n type: \"string\",\n enum: [\"strings\", \"templates\", \"jsx\", \"comments\"],\n },\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n emoji: nitpick({\n problem: \"Found an emoji ({{emoji}}).\",\n why: \"Emojis are usually introduced by AI-generated text and add noise to code, comments, and identifiers\",\n fix: \"Remove the emoji, or allow it here with the rule's `allow` option if it is deliberate user-facing copy\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n return {\n Program() {\n const text = context.sourceCode.getText()\n const ranges = allowedRanges(context.sourceCode, options[0]?.allow ?? [])\n\n // Scan the raw source so every emoji is caught, whether it appears\n // in code, strings, or comments\n for (const match of text.matchAll(CONSTANTS.EMOJI)) {\n if (isInAnyRange(match.index, ranges)) continue\n\n context.report({\n loc: {\n start: context.sourceCode.getLocFromIndex(match.index),\n end: context.sourceCode.getLocFromIndex(match.index + match[0].length),\n },\n messageId: \"emoji\",\n data: { emoji: match[0] },\n })\n }\n },\n }\n }\n}\n\nexport default new NoEmojis()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { isBlankJSDocLine, isJSDocComment, isJSDocTagLine } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"blankBeforeTag\"\n\n/**\n * Flags blank lines that sit between a JSDoc description and its tags (or\n * between tags) and removes them so the tags follow on directly.\n */\nclass NoJSDocBlankBeforeTags extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-jsdoc-blank-before-tags\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"layout\",\n fixable: \"code\",\n docs: {\n description: \"Disallow blank lines before JSDoc tags such as `@param` or `@returns`.\",\n recommended: true,\n },\n schema: [],\n messages: {\n blankBeforeTag: nitpick({\n problem: \"There is a blank line before a JSDoc tag.\",\n why: \"Tags should follow the description directly; an empty line there is noise that inflates the comment.\",\n fix: \"Remove the blank line so the tag follows on directly.\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n Program() {\n for (const comment of context.sourceCode.getAllComments()) {\n if (!isJSDocComment(comment)) continue\n\n if (comment.loc.start.line === comment.loc.end.line) continue\n\n for (let line = comment.loc.start.line; line <= comment.loc.end.line; line++) {\n const text = context.sourceCode.lines[line - 1]\n if (text === undefined || !isBlankJSDocLine(text)) continue\n\n // Grow the run of consecutive blank lines\n let runEnd = line\n while (\n runEnd < comment.loc.end.line &&\n isBlankJSDocLine(context.sourceCode.lines[runEnd] ?? \"\")\n ) {\n runEnd++\n }\n\n // Only a blank run immediately before a tag is a problem\n const nextLine = context.sourceCode.lines[runEnd]\n if (nextLine !== undefined && isJSDocTagLine(nextLine)) {\n const from = context.sourceCode.getIndexFromLoc({ line, column: 0 })\n const to = context.sourceCode.getIndexFromLoc({ line: runEnd + 1, column: 0 })\n\n context.report({\n loc: {\n start: { line, column: 0 },\n end: { line: runEnd, column: text.length },\n },\n messageId: \"blankBeforeTag\",\n fix: fixer => fixer.removeRange([from, to]),\n })\n }\n\n line = runEnd\n }\n }\n },\n }\n }\n}\n\nexport default new NoJSDocBlankBeforeTags()\n","import type { TSESTree } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\n\n/**\n * Any node that introduces a callable function.\n */\nexport type FunctionNode = TSESTree.FunctionDeclaration | TSESTree.FunctionExpression | TSESTree.ArrowFunctionExpression\n\n/**\n * A lookup of AST node type to the property keys that hold its child nodes.\n */\nexport type VisitorKeys = Record<string, readonly string[] | undefined>\n\n/**\n * Predicate applied to a `return` statement's argument (which is `null` for a\n * bare `return`).\n */\ntype ReturnPredicate = (argument: TSESTree.Expression | null) => boolean\n\n/**\n * Resolves the node whose leading comments would document a function, walking\n * out through a variable declaration and/or an export statement (so\n * `export const foo = () => {}` resolves to the `export` node).\n * @param fn The function node to resolve from.\n * @returns The node a JSDoc comment would sit above.\n */\nexport function getDocumentableNode(fn: FunctionNode): TSESTree.Node {\n let node: TSESTree.Node = fn\n\n // An object or class member is documented above the member, not the function\n if (node.parent.type === \"Property\" || node.parent.type === \"MethodDefinition\") {\n return node.parent\n }\n\n if (node.parent.type === \"VariableDeclarator\" && node.parent.parent.type === \"VariableDeclaration\") {\n node = node.parent.parent\n }\n\n if (node.parent.type === \"ExportNamedDeclaration\" || node.parent.type === \"ExportDefaultDeclaration\") {\n node = node.parent\n }\n\n return node\n}\n\n/**\n * Checks whether a node sits directly at the top level of the module.\n * @param node The node to test.\n * @returns True if the node's parent is the program root.\n */\nexport function isTopLevel(node: TSESTree.Node): boolean {\n return node.parent?.type === \"Program\"\n}\n\n/**\n * A named thing a JSDoc `@param` can refer to.\n */\nexport type NamedParameter = { name: string; node: TSESTree.Node }\n\n/**\n * How a parameter expects to be documented: a plain name, or a destructured\n * object, which may be documented either property by property or under a single\n * name standing for the whole object.\n */\nexport type ParameterDoc =\n | { kind: \"name\"; name: string; node: TSESTree.Node }\n | { kind: \"object\"; names: NamedParameter[]; node: TSESTree.Node }\n\n/**\n * Describes how each parameter of a function expects to be documented. An array\n * pattern is skipped as too ambiguous to require.\n * @param fn The function node to read the signature of.\n * @returns One entry per documentable parameter.\n */\nexport function parameterDocs(fn: FunctionNode): ParameterDoc[] {\n const docs: ParameterDoc[] = []\n\n const collect = (param: TSESTree.Node): void => {\n switch (param.type) {\n case \"Identifier\":\n docs.push({\n kind: \"name\",\n name: param.name,\n node: param,\n })\n return\n case \"AssignmentPattern\":\n collect(param.left)\n return\n case \"RestElement\":\n collect(param.argument)\n return\n case \"TSParameterProperty\":\n collect(param.parameter)\n return\n case \"ObjectPattern\": {\n const names: NamedParameter[] = []\n for (const property of param.properties) {\n if (property.type === \"RestElement\") {\n if (property.argument.type === \"Identifier\") {\n names.push({ name: property.argument.name, node: property.argument })\n }\n } else if (property.key.type === \"Identifier\") {\n names.push({ name: property.key.name, node: property.key })\n }\n }\n\n if (names.length > 0) {\n docs.push({\n kind: \"object\",\n names,\n node: param,\n })\n }\n return\n }\n default:\n return\n }\n }\n\n for (const param of fn.params) collect(param)\n\n return docs\n}\n\n/**\n * Resolves the nearest function a node sits inside, walking out through its\n * parents.\n * @param node The node to search from.\n * @returns The enclosing function, or `null` if the node is at module scope.\n */\nexport function enclosingFunction(node: TSESTree.Node): FunctionNode | null {\n // \"node.parent\" is typed undefined but is null at the Program root, so guard\n // with a truthy check to stop the walk on either\n let current: TSESTree.Node | undefined = node.parent\n\n while (current) {\n if (CONSTANTS.FUNCTIONS.NODE_TYPES.has(current.type)) {\n return current as FunctionNode\n }\n\n current = current.parent\n }\n\n return null\n}\n\n/**\n * Checks whether a function is a bare dynamic-import thunk, i.e.\n * `() => import(\"...\")`, the lazy-loading pattern used for AdonisJS route\n * controllers and for code splitting.\n * @param fn The function node to inspect.\n * @returns True if the function only lazily imports a module.\n */\nexport function isDynamicImportThunk(fn: FunctionNode): boolean {\n return fn.type === \"ArrowFunctionExpression\" && fn.params.length === 0 && fn.body.type === \"ImportExpression\"\n}\n\n/**\n * Resolves the declared name of a function, whether it comes from the function\n * itself or the variable it is assigned to.\n * @param fn The function node to name.\n * @returns The function name, or `undefined` if it is anonymous.\n */\nexport function getFunctionName(fn: FunctionNode): string | undefined {\n if ((fn.type === \"FunctionDeclaration\" || fn.type === \"FunctionExpression\") && fn.id) {\n return fn.id.name\n }\n\n if (fn.parent.type === \"VariableDeclarator\" && fn.parent.id.type === \"Identifier\") {\n return fn.parent.id.name\n }\n\n return undefined\n}\n\n/**\n * Checks whether any `return` in a subtree satisfies a predicate, without\n * crossing into nested functions (whose returns belong to them, not us).\n * @param node The AST node to search from.\n * @param visitorKeys The AST visitor keys, used to walk the subtree.\n * @param predicate The test applied to each `return` argument.\n * @returns True if a matching `return` is found.\n */\nexport function someReturn(node: TSESTree.Node, visitorKeys: VisitorKeys, predicate: ReturnPredicate): boolean {\n if (node.type === \"ReturnStatement\") {\n return predicate(node.argument)\n }\n\n for (const key of visitorKeys[node.type] ?? []) {\n const value = (node as unknown as Record<string, unknown>)[key]\n const children = Array.isArray(value) ? value : [value]\n\n for (const child of children) {\n const childNode = child as TSESTree.Node | null | undefined\n if (!childNode || typeof childNode.type !== \"string\") continue\n if (CONSTANTS.FUNCTIONS.NODE_TYPES.has(childNode.type)) continue\n if (someReturn(childNode, visitorKeys, predicate)) return true\n }\n }\n\n return false\n}\n\n/**\n * Checks whether a function returns a value, i.e. an arrow with an expression\n * body or a body with a non-empty `return`.\n * @param fn The function node to inspect.\n * @param visitorKeys The AST visitor keys, used to walk the function body.\n * @returns True if the function returns a value.\n */\nexport function functionReturnsValue(fn: FunctionNode, visitorKeys: VisitorKeys): boolean {\n if (fn.type === \"ArrowFunctionExpression\" && fn.body.type !== \"BlockStatement\") {\n return true\n }\n\n return someReturn(fn.body, visitorKeys, argument => argument !== null)\n}\n\n/**\n * Checks whether a return-type annotation is `void` or `Promise<void>`.\n * @param annotation The return-type annotation to inspect.\n * @returns True if the annotation is a void type.\n */\nexport function isVoidReturnType(annotation: TSESTree.TSTypeAnnotation): boolean {\n if (annotation.typeAnnotation.type === \"TSVoidKeyword\") return true\n\n if (\n annotation.typeAnnotation.type === \"TSTypeReference\" &&\n annotation.typeAnnotation.typeName.type === \"Identifier\" &&\n annotation.typeAnnotation.typeName.name === \"Promise\"\n ) {\n return (\n annotation.typeAnnotation.typeArguments?.params.length === 1 &&\n annotation.typeAnnotation.typeArguments?.params[0]?.type === \"TSVoidKeyword\"\n )\n }\n\n return false\n}\n\n/**\n * Checks whether a function returns nothing, judged by its return-type\n * annotation when present, otherwise by its body.\n * @param fn The function node to inspect.\n * @param visitorKeys The AST visitor keys, used to walk the function body.\n * @returns True if the function is void.\n */\nexport function isVoidFunction(fn: FunctionNode, visitorKeys: VisitorKeys): boolean {\n if (fn.returnType) {\n return isVoidReturnType(fn.returnType)\n }\n\n return !functionReturnsValue(fn, visitorKeys)\n}\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { type FunctionNode, getDocumentableNode, isVoidFunction } from \"@/lib/utils/functions\"\nimport { findJSDocReturnsRange, isJSDocComment } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"voidReturns\"\n\n/**\n * Flags a `@returns` tag on a function that returns nothing (a void return type,\n * or a body with no `return` or only a bare `return`), and removes it, since it\n * documents a value that never exists.\n */\nclass NoJSDocReturnsOnVoid extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-jsdoc-returns-on-void\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n fixable: \"code\",\n docs: {\n description: \"Disallow a JSDoc `@returns` tag on a function that returns nothing.\",\n recommended: true,\n category: \"base\",\n },\n schema: [],\n messages: {\n voidReturns: nitpick({\n problem: \"This function returns nothing, but its JSDoc has a `@returns` tag.\",\n why: \"A `@returns` on a void function documents a value that never exists and drifts from the code\",\n fix: \"Remove the `@returns` tag\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n const check = (fn: FunctionNode, anchor: TSESTree.Node): void => {\n const jsdoc = context.sourceCode.getCommentsBefore(anchor).at(-1)\n if (jsdoc === undefined || !isJSDocComment(jsdoc)) return\n\n const range = findJSDocReturnsRange(context.sourceCode, jsdoc)\n if (range === null) return\n if (!isVoidFunction(fn, context.sourceCode.visitorKeys)) return\n\n const from = context.sourceCode.getIndexFromLoc({ line: range.from, column: 0 })\n const to = context.sourceCode.getIndexFromLoc({ line: range.to + 1, column: 0 })\n\n context.report({\n loc: {\n start: { line: range.from, column: 0 },\n end: { line: range.to, column: (context.sourceCode.lines[range.to - 1] ?? \"\").length },\n },\n messageId: \"voidReturns\",\n fix: fixer => fixer.removeRange([from, to]),\n })\n }\n\n return {\n FunctionDeclaration(node) {\n check(node, getDocumentableNode(node))\n },\n VariableDeclarator(node) {\n if (node.init?.type === \"ArrowFunctionExpression\" || node.init?.type === \"FunctionExpression\") {\n check(node.init, getDocumentableNode(node.init))\n }\n },\n MethodDefinition(node) {\n if (node.value.type === \"FunctionExpression\") {\n check(node.value, node)\n }\n },\n }\n }\n}\n\nexport default new NoJSDocReturnsOnVoid()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { findBacktickSpans, isDirectiveComment } from \"@/lib/utils/comments\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"backticks\"\n\n/**\n * Flags a backtick-fenced code reference inside a `//` line comment and rewrites\n * it with double quotes, since backticks only render as code in a JSDoc block.\n * Code fences, unpaired backticks, and directives are left alone.\n */\nclass NoLineCommentBackticks extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-line-comment-backticks\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n fixable: \"code\",\n docs: {\n description: \"Disallow backticks in `//` line comments, use double quotes for code references.\",\n recommended: true,\n category: \"base\",\n },\n schema: [],\n messages: {\n backticks: nitpick({\n problem: \"This line comment wraps `{{text}}` in backticks.\",\n why: \"Backticks only render as code inside a JSDoc block, in a `//` comment they stay literal characters, so double quotes read better\",\n fix: 'Wrap it in double quotes instead: \"{{text}}\"',\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n Program() {\n for (const comment of context.sourceCode.getAllComments()) {\n // A JSDoc block is where backticks do render, so only \"//\"\n // comments are rewritten, and never a tooling directive\n if (comment.type !== \"Line\" || isDirectiveComment(comment)) continue\n\n for (const span of findBacktickSpans(comment)) {\n context.report({\n loc: {\n start: context.sourceCode.getLocFromIndex(span.start),\n end: context.sourceCode.getLocFromIndex(span.end + 1),\n },\n messageId: \"backticks\",\n data: { text: span.text },\n fix: fixer => [\n fixer.replaceTextRange([span.start, span.start + 1], '\"'),\n fixer.replaceTextRange([span.end, span.end + 1], '\"'),\n ],\n })\n }\n }\n },\n }\n }\n}\n\nexport default new NoLineCommentBackticks()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { findProsePeriods } from \"@/lib/utils/comments\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"period\" | \"sentence\"\n\n/**\n * Flags periods used as prose punctuation inside `//` line comments. Dots that\n * are part of a token (`foo.bar`, `1.5`, `.env`, `subagent.*`), dots inside a\n * quoted span, ellipses, and abbreviations like `e.g.` are left alone.\n */\nclass NoLineCommentPeriod extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-line-comment-period\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"layout\",\n fixable: \"code\",\n docs: {\n description: \"Disallow prose periods in `//` line comments (code-reference dots and ellipses are allowed).\",\n recommended: true,\n },\n schema: [],\n messages: {\n period: nitpick({\n problem: \"This line comment ends with a period.\",\n why: \"Line comments should be short, clear fragments, not full sentences, so a closing period is just noise, dots inside code references like `foo.bar` are allowed.\",\n fix: \"Remove the period and keep the comment terse.\",\n }),\n sentence: nitpick({\n problem: \"This line comment runs two sentences together with a period.\",\n why: \"Line comments should be short, clear fragments, dropping the period on its own would leave a run-on, so the sentences belong on separate lines\",\n fix: \"Split it into one `//` line per fragment, or reword it as a single fragment (reported, not auto-fixed, so wrapped prose is never mangled)\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n Program() {\n for (const comment of context.sourceCode.getAllComments()) {\n if (comment.type !== \"Line\") continue\n\n for (const period of findProsePeriods(comment)) {\n const loc = {\n start: context.sourceCode.getLocFromIndex(period.index),\n end: context.sourceCode.getLocFromIndex(period.index + 1),\n }\n\n // A period that closes the comment can simply go, nothing\n // follows it to run together\n if (period.terminal) {\n context.report({\n loc,\n messageId: \"period\",\n fix: fixer => fixer.removeRange([period.index, period.index + 1]),\n })\n\n continue\n }\n\n // Mid-comment, the period separates two fragments, and\n // splitting it onto a new line mangles wrapped prose, so this\n // case is reported for a human or agent to reword, not fixed\n context.report({ loc, messageId: \"sentence\" })\n }\n }\n },\n }\n }\n}\n\nexport default new NoLineCommentPeriod()\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { isPathWritten, isReassigned, propertyAccessPath } from \"@/lib/utils/aliases\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"propertyAccessAlias\"\n\n/**\n * A `const` that reads like a property alias, held back until the whole file has\n * been walked so writes to the same property can exempt it.\n */\ntype Candidate = {\n /**\n * The declarator to report.\n */\n node: TSESTree.VariableDeclarator\n\n /**\n * The name the property is aliased under.\n */\n name: string\n\n /**\n * The dotted path the alias reads, e.g. `auth.user`.\n */\n path: string\n\n /**\n * The source text of the aliased expression.\n */\n expression: string\n}\n\n/**\n * Flags a `const` whose entire value is a single property access, such as\n * `const user = auth.user!`, since it just renames a property. `let`, exported\n * bindings, annotated declarations, and snapshots of a value written to later are\n * exempt.\n */\nclass NoPropertyAccessAlias extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-property-access-alias\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description:\n \"Disallow a `const` whose whole value is a single property access, inline the expression instead.\",\n recommended: true,\n category: \"base\",\n },\n schema: [],\n messages: {\n propertyAccessAlias: nitpick({\n problem: \"`{{name}}` only aliases the property access `{{expression}}`.\",\n why: \"A variable that just renames a property hides where the value comes from when scanning the code\",\n fix: \"Remove it and use `{{expression}}` inline, or use `let` if it is reassigned later\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n const candidates: Candidate[] = []\n const written = new Set<string>()\n\n // Track the properties the file writes to, so an alias taken before one of\n // those writes is understood as a snapshot\n const recordWrite = (target: TSESTree.Node): void => {\n if (target.type !== \"MemberExpression\") return\n\n const path = propertyAccessPath(target)\n if (path !== null) written.add(path)\n }\n\n return {\n AssignmentExpression(node) {\n recordWrite(node.left)\n },\n\n UpdateExpression(node) {\n recordWrite(node.argument)\n },\n\n VariableDeclarator(node) {\n if (node.parent.type !== \"VariableDeclaration\" || node.parent.kind !== \"const\") return\n\n // Exported bindings cannot be inlined away, so they are exempt\n if (node.parent.parent.type === \"ExportNamedDeclaration\") return\n\n if (node.id.type !== \"Identifier\" || node.init === null) return\n\n // A type annotation is a reason of its own to keep the binding, as\n // inlining it would drop the narrowing it applies\n if (node.id.typeAnnotation !== undefined) return\n\n const path = propertyAccessPath(node.init)\n if (path === null) return\n\n // A reassigned root object makes this a snapshot of what it held\n // here, so inlining it would change what the code does\n const root = path.slice(0, path.indexOf(\".\"))\n if (root !== \"this\" && isReassigned(context.sourceCode.getScope(node), root)) return\n\n candidates.push({\n node,\n name: node.id.name,\n path,\n expression: context.sourceCode.getText(node.init),\n })\n },\n\n \"Program:exit\"() {\n for (const candidate of candidates) {\n if (isPathWritten(written, candidate.path)) continue\n\n context.report({\n node: candidate.node,\n messageId: \"propertyAccessAlias\",\n data: {\n name: candidate.name,\n expression: candidate.expression,\n },\n })\n }\n },\n }\n }\n}\n\nexport default new NoPropertyAccessAlias()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { isAllShorthand, isPropertyAccessAlias } from \"@/lib/utils/aliases\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"destructure\"\n\n/**\n * Flags shorthand object destructuring off a plain object reference\n * (`const { a } = object`), which just aliases `object.a`. Destructuring a call\n * or hook result, renames, defaults, and rest elements are left alone.\n */\nclass NoPropertyDestructuring extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-property-destructuring\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Disallow shorthand destructuring off a plain object reference, access the property directly.\",\n recommended: true,\n category: \"base\",\n },\n schema: [],\n messages: {\n destructure: nitpick({\n problem: \"Destructuring from `{{source}}` here just aliases its properties.\",\n why: \"Reading `{{source}}.x` at the use site keeps the origin visible, destructuring a plain object hides where a value comes from (destructuring a call or hook result is fine)\",\n fix: \"Access the properties on `{{source}}` directly instead of destructuring\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n VariableDeclarator(node) {\n if (node.parent.type !== \"VariableDeclaration\" || node.parent.kind !== \"const\") return\n if (node.parent.parent.type === \"ExportNamedDeclaration\") return\n if (node.id.type !== \"ObjectPattern\" || node.init === null) return\n\n // Only a plain object reference is an alias, a call, await, or new\n // result is a computed value worth destructuring\n if (node.init.type !== \"Identifier\" && !isPropertyAccessAlias(node.init)) return\n\n // Only pure shorthand grabs (\"{ a }\") are aliases, renames,\n // defaults, and rest elements are deliberate\n if (!isAllShorthand(node.id)) return\n\n context.report({\n node,\n messageId: \"destructure\",\n data: { source: context.sourceCode.getText(node.init) },\n })\n },\n }\n }\n}\n\nexport default new NoPropertyDestructuring()\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { matchesGlob } from \"@/lib/utils/regex\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ allowIn: string[] }]\ntype MessageIds = \"relative\"\n\n/**\n * Flags a relative import or re-export specifier (`./` or `../`), so every\n * intra-package module is reached through its path alias instead. The `allowIn`\n * option lists globs (e.g. entrypoints) where relative paths are tolerated.\n */\nclass NoRelativeImports extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-relative-imports\"\n\n readonly defaultOptions: Options = [{ allowIn: [] }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Disallow relative import and re-export specifiers, use the package path alias.\",\n recommended: true,\n category: \"base\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n allowIn: {\n type: \"array\",\n items: { type: \"string\" },\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n relative: nitpick({\n problem: \"This import uses a relative path (`{{path}}`).\",\n why: \"A relative path breaks when a file moves and hides which package a module belongs to, the path alias is stable and explicit\",\n fix: \"Import through the package alias (`#...` or `@frontend/...`) instead of a relative path\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const allowIn = options[0]?.allowIn ?? []\n if (allowIn.length > 0 && matchesGlob(context.filename, allowIn)) {\n return {}\n }\n\n const check = (source: TSESTree.StringLiteral | null | undefined): void => {\n if (source === null || source === undefined) return\n if (!source.value.startsWith(\"./\") && !source.value.startsWith(\"../\")) return\n\n context.report({\n node: source,\n messageId: \"relative\",\n data: { path: source.value },\n })\n }\n\n return {\n ImportDeclaration(node) {\n check(node.source)\n },\n ExportNamedDeclaration(node) {\n check(node.source)\n },\n ExportAllDeclaration(node) {\n check(node.source)\n },\n ImportExpression(node) {\n if (node.source.type === \"Literal\" && typeof node.source.value === \"string\") {\n check(node.source as TSESTree.StringLiteral)\n }\n },\n }\n }\n}\n\nexport default new NoRelativeImports()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { isJSDocComment } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"singleLine\"\n\n/**\n * Flags JSDoc comments (`/**`) that are written on a single line and expands\n * them into the multi-line form:\n * ```\n * /** blabla */ -> /**\n * * blabla\n * */\n * ```\n */\nclass NoSingleLineJSDoc extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-single-line-jsdoc\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"layout\",\n fixable: \"code\",\n docs: {\n description: \"Require JSDoc comments to span multiple lines rather than sit on a single line.\",\n recommended: true,\n },\n schema: [],\n messages: {\n singleLine: nitpick({\n problem: \"This JSDoc comment is written on a single line.\",\n why: \"Multi-line JSDoc is easier to read, diff, and extend with additional tags, and is the house style.\",\n fix: \"Put the opening `/**`, the ` * ` content, and the closing `*/` each on their own line.\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n Program() {\n for (const comment of context.sourceCode.getAllComments()) {\n // Only JSDoc comments (\"/**\") that fit on one line\n if (!isJSDocComment(comment)) continue\n if (comment.loc.start.line !== comment.loc.end.line) continue\n\n // Strip the leading \"*\" left over from \"/**\" and normalize\n const content = comment.value.replace(/^\\*/, \"\").trim()\n\n // An empty JSDoc (\"/** */\") has nothing to expand onto its\n // own line, so it is left alone\n if (content.length === 0) continue\n\n context.report({\n loc: comment.loc,\n messageId: \"singleLine\",\n fix(fixer) {\n const indent = \" \".repeat(comment.loc.start.column)\n const expanded = `/**\\n${indent} * ${content}\\n${indent} */`\n return fixer.replaceTextRange(comment.range, expanded)\n },\n })\n }\n },\n }\n }\n}\n\nexport default new NoSingleLineJSDoc()\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { firstCommentContentChar, isDirectiveComment } from \"@/lib/utils/comments\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"capitalize\"\n\n/**\n * Flags a comment whose first prose letter is lowercase and capitalizes it, so\n * comments read as sentences. Continuation lines of a wrapped `//` comment,\n * tooling directives, and comments that open with code, a symbol, or a URL are\n * left alone.\n */\nclass RequireCapitalizedComments extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-capitalized-comments\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n fixable: \"code\",\n docs: {\n description: \"Require a comment to start with an uppercase letter.\",\n recommended: true,\n category: \"base\",\n },\n schema: [],\n messages: {\n capitalize: nitpick({\n problem: \"This comment starts with a lowercase letter.\",\n why: \"A comment reads as a sentence, and a sentence starts with a capital letter\",\n fix: \"Capitalize the first letter of the comment\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n // Whether a \"//\" comment continues a wrapped one, i.e the previous\n // physical line is itself a line comment\n const isContinuation = (comment: TSESTree.Comment): boolean => {\n if (comment.type !== \"Line\") return false\n\n const previous = context.sourceCode.lines[comment.loc.start.line - 2]\n return previous !== undefined && /^\\s*\\/\\//.test(previous)\n }\n\n return {\n Program() {\n for (const comment of context.sourceCode.getAllComments()) {\n if (isDirectiveComment(comment) || isContinuation(comment)) continue\n\n const content = firstCommentContentChar(comment)\n if (content === null || !/\\p{Ll}/u.test(content.char)) continue\n\n // Leave a comment that opens with a URL alone, capitalizing it\n // would break the link\n if (/^(?:https?:\\/\\/|www\\.)/u.test(context.sourceCode.getText().slice(content.index))) continue\n\n context.report({\n loc: {\n start: context.sourceCode.getLocFromIndex(content.index),\n end: context.sourceCode.getLocFromIndex(content.index + content.char.length),\n },\n messageId: \"capitalize\",\n fix: fixer =>\n fixer.replaceTextRange(\n [content.index, content.index + content.char.length],\n content.char.toUpperCase(),\n ),\n })\n }\n },\n }\n }\n}\n\nexport default new RequireCapitalizedComments()\n","import type { TSESTree } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { type FunctionNode, getFunctionName, someReturn, type VisitorKeys } from \"@/lib/utils/functions\"\n\n/**\n * Checks whether a name follows the `PascalCase` convention React uses to\n * distinguish component functions from plain functions and DOM tags.\n * @param name The function name to test.\n * @returns True if the name starts with an uppercase letter.\n */\nexport function isReactComponentName(name: string): boolean {\n return /^[A-Z]/.test(name)\n}\n\n/**\n * Checks whether a name is a React hook, i.e. `use` followed by a capitalized\n * word such as `useState` or `useMenuActions`.\n * @param name The function name to test.\n * @returns True if the name is a hook name.\n */\nexport function isHookName(name: string): boolean {\n return CONSTANTS.REACT.HOOK.test(name)\n}\n\n/**\n * Checks whether a name is a context-consumer hook, i.e. a `use…Context` wrapper\n * such as `useTreeViewContext` (the bare `useContext` is excluded).\n * @param name The function name to test.\n * @returns True if the name is a context-hook name.\n */\nexport function isContextHookName(name: string): boolean {\n return CONSTANTS.REACT.CONTEXT_HOOK.test(name)\n}\n\n/**\n * Checks whether an expression is, on its face, a function value: a function or\n * arrow expression, or a `useCallback` call (which always yields a function).\n * @param node The expression to inspect, if any.\n * @returns True if the expression evaluates to a function.\n */\nexport function isFunctionValue(node: TSESTree.Expression | null | undefined): boolean {\n if (!node) return false\n if (node.type === \"ArrowFunctionExpression\" || node.type === \"FunctionExpression\") return true\n\n return node.type === \"CallExpression\" && node.callee.type === \"Identifier\" && node.callee.name === \"useCallback\"\n}\n\n/**\n * Checks whether an expression evaluates to JSX, following the branches a\n * component commonly returns through (ternaries, `&&`, comma sequences).\n * @param node The expression to inspect, if any.\n * @returns True if the expression can produce a JSX element or fragment.\n */\nexport function isJsxExpression(node: TSESTree.Expression | null | undefined): boolean {\n if (!node) return false\n\n switch (node.type) {\n case \"JSXElement\":\n case \"JSXFragment\":\n return true\n case \"ConditionalExpression\":\n return isJsxExpression(node.consequent) || isJsxExpression(node.alternate)\n case \"LogicalExpression\":\n return isJsxExpression(node.left) || isJsxExpression(node.right)\n case \"SequenceExpression\":\n return isJsxExpression(node.expressions.at(-1))\n default:\n return false\n }\n}\n\n/**\n * Checks whether a function returns JSX, i.e. whether it looks like it renders\n * a React element.\n * @param fn The function node to inspect.\n * @param visitorKeys The AST visitor keys, used to walk the function body.\n * @returns True if the function returns JSX.\n */\nexport function functionReturnsJsx(fn: FunctionNode, visitorKeys: VisitorKeys): boolean {\n // An arrow with an expression body returns that expression directly\n if (fn.type === \"ArrowFunctionExpression\" && fn.body.type !== \"BlockStatement\") {\n return isJsxExpression(fn.body)\n }\n\n return someReturn(fn.body, visitorKeys, isJsxExpression)\n}\n\n/**\n * Checks whether a function is a React component or a custom hook, the scopes\n * where `useMemo` is available and where local derivations should be memoized.\n * @param fn The function node to inspect.\n * @param visitorKeys The AST visitor keys, used to walk the function body.\n * @returns True if the function is a component or a hook.\n */\nexport function isComponentOrHook(fn: FunctionNode, visitorKeys: VisitorKeys): boolean {\n const name = getFunctionName(fn)\n if (name === undefined) return false\n\n return isHookName(name) || (isReactComponentName(name) && functionReturnsJsx(fn, visitorKeys))\n}\n\n/**\n * Checks whether an expression contains a non-hook call, without descending into\n * nested functions, so a value built by a helper or method call is caught but a\n * callback's inner calls are not.\n * @param node The AST node to search from.\n * @param visitorKeys The AST visitor keys, used to walk the subtree.\n * @returns True if a non-hook call is found.\n */\nfunction hasNonHookCall(node: TSESTree.Node, visitorKeys: VisitorKeys): boolean {\n if (node.type === \"CallExpression\") {\n return !(node.callee.type === \"Identifier\" && isHookName(node.callee.name))\n }\n\n for (const key of visitorKeys[node.type] ?? []) {\n const value = (node as unknown as Record<string, unknown>)[key]\n const children = Array.isArray(value) ? value : [value]\n\n for (const child of children) {\n const childNode = child as TSESTree.Node | null | undefined\n if (!childNode || typeof childNode.type !== \"string\") continue\n if (CONSTANTS.FUNCTIONS.NODE_TYPES.has(childNode.type)) continue\n if (hasNonHookCall(childNode, visitorKeys)) return true\n }\n }\n\n return false\n}\n\n/**\n * Checks whether an expression is a derived value that belongs in a `useMemo`,\n * i.e. it computes something through a non-hook call. A function value (a\n * callback) and a bare hook result are not derived values.\n * @param node The expression to inspect.\n * @param visitorKeys The AST visitor keys, used to walk the expression.\n * @returns True if the expression is a derived value.\n */\nexport function isDerivedValue(node: TSESTree.Expression, visitorKeys: VisitorKeys): boolean {\n if (node.type === \"ArrowFunctionExpression\" || node.type === \"FunctionExpression\") return false\n\n return hasNonHookCall(node, visitorKeys)\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { type FunctionNode, getDocumentableNode, isVoidFunction, parameterDocs } from \"@/lib/utils/functions\"\nimport { getJSDocParamNames, getLeadingJSDoc, hasJSDocReturnsTag } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { functionReturnsJsx } from \"@/lib/utils/react\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"missingParam\" | \"missingReturns\"\n\n/**\n * Checks a function that already carries a JSDoc: every parameter must have an\n * `@param`, and a function returning a value must have a `@returns`. A void or\n * `Promise<void>` function needs no `@returns`, a component returning JSX is\n * exempt from it too.\n */\nclass RequireCompleteJSDoc extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-complete-jsdoc\"\n readonly defaultOptions: Options = []\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require a function's JSDoc to document every parameter and its return value.\",\n recommended: true,\n category: \"base\",\n },\n schema: [],\n messages: {\n missingParam: nitpick({\n problem: \"The JSDoc does not document the parameter `{{name}}`.\",\n why: \"A JSDoc that skips a parameter drifts from the signature and stops describing what the function takes\",\n fix: \"Add an `@param {{name}} ...` line describing what it is\",\n }),\n missingReturns: nitpick({\n problem: \"The JSDoc has no `@returns`, but this function returns a value.\",\n why: \"A documented function should say what it hands back, a missing `@returns` leaves the caller guessing\",\n fix: \"Add a `@returns ...` line describing the value (a void or `Promise<void>` function needs none)\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n /**\n * Creates the rule listener.\n * @param context The rule context.\n * @returns The rule listener.\n */\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n const check = (fn: FunctionNode): void => {\n const jsdoc = getLeadingJSDoc(context.sourceCode, getDocumentableNode(fn))\n if (jsdoc === null) return\n\n const documented = getJSDocParamNames(jsdoc)\n const docs = parameterDocs(fn)\n const plainNames = new Set(docs.filter(doc => doc.kind === \"name\").map(doc => doc.name))\n\n for (const doc of docs) {\n if (doc.kind === \"name\") {\n if (!documented.has(doc.name)) {\n context.report({\n node: doc.node,\n messageId: \"missingParam\",\n data: { name: doc.name },\n })\n }\n\n continue\n }\n\n if (doc.names.every(entry => documented.has(entry.name))) continue\n\n // A destructured object may instead be documented under one name\n // standing for the whole object, e.g. \"@param options\"\n const properties = new Set(doc.names.map(entry => entry.name))\n const documentedAsWhole = [...documented].some(name => !properties.has(name) && !plainNames.has(name))\n if (documentedAsWhole) continue\n\n for (const entry of doc.names) {\n if (documented.has(entry.name)) continue\n\n context.report({\n node: entry.node,\n messageId: \"missingParam\",\n data: { name: entry.name },\n })\n }\n }\n\n if (hasJSDocReturnsTag(jsdoc)) return\n if (isVoidFunction(fn, context.sourceCode.visitorKeys)) return\n\n // A component's render result is obvious, so it needs no \"@returns\"\n if (functionReturnsJsx(fn, context.sourceCode.visitorKeys)) return\n\n context.report({ node: jsdoc, messageId: \"missingReturns\" })\n }\n\n return {\n FunctionDeclaration(node) {\n check(node)\n },\n FunctionExpression(node) {\n check(node)\n },\n ArrowFunctionExpression(node) {\n check(node)\n },\n }\n }\n}\n\nexport default new RequireCompleteJSDoc()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\n\n/**\n * A framework Nitpicker ships a dedicated rule category and shared config for.\n */\nexport type Framework = \"adonisjs\" | \"react\"\n\n/**\n * The human-readable label for each framework, used in messages.\n */\nexport const FRAMEWORK_LABELS: Record<Framework, string> = {\n adonisjs: \"AdonisJS\",\n react: \"React\",\n}\n\n/**\n * Collects the module specifiers imported by a source file.\n * @param sourceCode The source code of the linted file.\n * @returns The list of imported module specifiers.\n */\nfunction importSources(sourceCode: Readonly<TSESLint.SourceCode>): string[] {\n const sources: string[] = []\n\n for (const statement of sourceCode.ast.body) {\n if (statement.type === \"ImportDeclaration\") {\n sources.push(String(statement.source.value))\n }\n }\n\n return sources\n}\n\n/**\n * Detects which supported frameworks a file appears to use, based on its imports\n * and file name.\n * @param sourceCode The source code of the linted file.\n * @param filename The path of the linted file.\n * @returns The set of frameworks detected in the file.\n */\nexport function detectFrameworks(sourceCode: Readonly<TSESLint.SourceCode>, filename: string): Set<Framework> {\n const detected = new Set<Framework>()\n const sources = importSources(sourceCode)\n\n if (sources.some(source => source.startsWith(\"@adonisjs/\") || CONSTANTS.FRAMEWORKS.ADONIS_SUBPATH.test(source))) {\n detected.add(\"adonisjs\")\n }\n\n const importsReact = sources.some(\n source => source === \"react\" || source.startsWith(\"react/\") || source === \"react-dom\",\n )\n if (importsReact || CONSTANTS.FRAMEWORKS.REACT_FILE.test(filename)) {\n detected.add(\"react\")\n }\n\n return detected\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { detectFrameworks, FRAMEWORK_LABELS, type Framework } from \"@/lib/utils/frameworks\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ ignore: Framework[] }]\ntype MessageIds = \"missingConfig\"\n\n/**\n * Warns when a file uses a framework (AdonisJS, React) whose Nitpicker config is\n * not enabled. Enabling the matching config (which sets a settings flag) or\n * turning off this rule silences it.\n */\nclass RequireFrameworkConfig extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-framework-config\"\n\n readonly defaultOptions: Options = [{ ignore: [] }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Warn when a file uses a framework whose Nitpicker config is not enabled.\",\n recommended: true,\n category: \"base\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n ignore: {\n type: \"array\",\n items: {\n type: \"string\",\n enum: [\"adonisjs\", \"react\"],\n },\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n missingConfig: nitpick({\n problem: \"This file uses {{framework}} but the Nitpicker {{framework}} rules are not enabled.\",\n why: \"Framework rules only run when you opt into the matching config, so files like this one go unchecked\",\n fix: \"Add `nitpicker.configs.{{config}}` (scoped to these files) to your ESLint config, or turn off `nitpicker/require-framework-config`\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const ignored = new Set(options[0]?.ignore ?? [])\n\n // Each framework config stamps \"settings.nitpicker<framework> = true\"\n const enabled = (context.settings[CONSTANTS.PLUGIN_NAME] ?? {}) as Partial<Record<Framework, boolean>>\n\n return {\n Program(node) {\n const detected = detectFrameworks(context.sourceCode, context.filename)\n\n for (const framework of detected) {\n if (ignored.has(framework) || enabled[framework]) continue\n\n context.report({\n node,\n messageId: \"missingConfig\",\n data: { framework: FRAMEWORK_LABELS[framework], config: framework },\n })\n }\n },\n }\n }\n}\n\nexport default new RequireFrameworkConfig()\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport {\n type FunctionNode,\n getDocumentableNode,\n getFunctionName,\n isDynamicImportThunk,\n isTopLevel,\n} from \"@/lib/utils/functions\"\nimport { hasLeadingJSDoc } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { functionReturnsJsx, isReactComponentName } from \"@/lib/utils/react\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"missingJSDoc\"\n\n/**\n * Requires a JSDoc comment on top-level functions, with React component\n * functions (`PascalCase` name returning JSX) being the sole exception.\n */\nclass RequireFunctionJSDoc extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-function-jsdoc\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require a JSDoc comment on top-level functions, except React component functions.\",\n recommended: true,\n },\n schema: [],\n messages: {\n missingJSDoc: nitpick({\n problem: \"The function `{{name}}` has no JSDoc comment.\",\n why: \"Top-level functions must document their purpose, parameters, and return value, React component functions are the only exception.\",\n fix: \"Add a `/** ... */` JSDoc block immediately above the function describing what it does.\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n const check = (fn: FunctionNode, reportNode: TSESTree.Node): void => {\n const name = getFunctionName(fn)\n // Anonymous functions (e.g \"export default () => {}\") are skipped\n if (name === undefined) return\n\n const documentable = getDocumentableNode(fn)\n if (!isTopLevel(documentable)) return\n\n // Lazy dynamic-import thunks (`() => import(\"...\")`) carry no logic worth documenting\n if (isDynamicImportThunk(fn)) return\n\n // React component functions are exempt from the JSDoc requirement\n if (isReactComponentName(name) && functionReturnsJsx(fn, context.sourceCode.visitorKeys)) return\n\n if (hasLeadingJSDoc(context.sourceCode, documentable)) return\n\n context.report({\n node: reportNode,\n messageId: \"missingJSDoc\",\n data: { name },\n })\n }\n\n return {\n FunctionDeclaration(node) {\n check(node, node.id ?? node)\n },\n VariableDeclarator(node) {\n if (!node.init) return\n if (node.init.type !== \"ArrowFunctionExpression\" && node.init.type !== \"FunctionExpression\") return\n\n check(node.init, node.id)\n },\n }\n }\n}\n\nexport default new RequireFunctionJSDoc()\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\n\n/**\n * Rebuilds an object literal across multiple lines, indenting each property one\n * level past the line the object opens on and closing the brace back at that\n * level, so the result matches the surrounding indentation.\n * @param sourceCode The source code of the linted file.\n * @param node The object expression to expand.\n * @param indent The number of spaces in one indentation level.\n * @returns The multiline object literal source text.\n */\nexport function expandObjectLiteral(\n sourceCode: Readonly<TSESLint.SourceCode>,\n node: TSESTree.ObjectExpression,\n indent: number,\n): string {\n const openingLine = sourceCode.lines[node.loc.start.line - 1] ?? \"\"\n const baseIndent = openingLine.match(/^\\s*/)?.[0] ?? \"\"\n const propertyIndent = baseIndent + \" \".repeat(indent)\n\n const body = node.properties.map(property => `${propertyIndent}${sourceCode.getText(property)}`).join(\",\\n\")\n\n return `{\\n${body},\\n${baseIndent}}`\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { expandObjectLiteral } from \"@/lib/utils/objects\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ maxKeys: number; indent: number }]\ntype MessageIds = \"shouldWrap\"\n\n/**\n * Flags an object literal that packs more than `maxKeys` properties onto a\n * single line, and expands it to one property per line, since a wide inline\n * object is harder to scan, diff, and edit than a stacked one.\n */\nclass RequireMultilineObject extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-multiline-object\"\n readonly defaultOptions: Options = [\n {\n maxKeys: CONSTANTS.OBJECTS.MAX_INLINE_KEYS,\n indent: CONSTANTS.OBJECTS.INDENT_WIDTH,\n },\n ]\n\n readonly meta = {\n type: \"suggestion\",\n fixable: \"code\",\n docs: {\n description: \"Require an object literal with more than a few properties to span multiple lines.\",\n recommended: true,\n category: \"base\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n maxKeys: { type: \"integer\", minimum: 1 },\n indent: { type: \"integer\", minimum: 1 },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n shouldWrap: nitpick({\n problem: \"This object literal has {{count}} properties packed onto a single line.\",\n why: \"An object with more than {{max}} properties is easier to scan, diff, and edit when each property sits on its own line\",\n fix: \"Break it across multiple lines, one property per line with a trailing comma\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const maxKeys = options[0]?.maxKeys ?? CONSTANTS.OBJECTS.MAX_INLINE_KEYS\n const indent = options[0]?.indent ?? CONSTANTS.OBJECTS.INDENT_WIDTH\n\n return {\n ObjectExpression(node) {\n if (node.properties.length <= maxKeys) return\n if (node.loc.start.line !== node.loc.end.line) return\n\n // The fix rebuilds the object from its properties alone, so a\n // comment between them would be dropped, only auto-fix a clean one\n const hasComments = context.sourceCode.getCommentsInside(node).length > 0\n\n context.report({\n node,\n messageId: \"shouldWrap\",\n data: { count: node.properties.length, max: maxKeys },\n fix: hasComments\n ? null\n : fixer => fixer.replaceText(node, expandObjectLiteral(context.sourceCode, node, indent)),\n })\n },\n }\n }\n}\n\nexport default new RequireMultilineObject()\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ max: number }]\ntype MessageIds = \"tooLong\"\n\nconst DEFAULT_MAX = 120\n\n/**\n * Flags a class string in a `className` longer than the configured limit, so a\n * wall of Tailwind utilities gets broken into shorter pieces. A long string\n * inside a `cn(...)` call is caught too, since `cn` does not break it up.\n */\nclass MaxClassNameLength extends NitpickerRule<MessageIds, Options> {\n readonly name = \"max-classname-length\"\n\n readonly defaultOptions: Options = [{ max: DEFAULT_MAX }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Enforce a maximum length for a `className` class string.\",\n recommended: true,\n category: \"react\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n max: { type: \"integer\", minimum: 1 },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n tooLong: nitpick({\n problem: \"This `className` string is {{length}} characters, over the {{max}}-character limit.\",\n why: \"A long wall of Tailwind classes is hard to scan and diff, and it overflows the line\",\n fix: \"Break the classes across multiple lines, grouping related ones into separate `cn()` arguments\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const max = options[0]?.max ?? DEFAULT_MAX\n\n // Collect the class strings inside a className value: string literals and\n // non-interpolated templates, including those nested in a cn(...) call,\n // without descending into a nested function\n const collect = (\n node: TSESTree.Node | null | undefined,\n found: { node: TSESTree.Node; text: string }[],\n ): void => {\n if (!node) return\n\n if (node.type === \"Literal\") {\n if (typeof node.value === \"string\") found.push({ node, text: node.value })\n return\n }\n\n if (node.type === \"TemplateLiteral\") {\n if (node.expressions.length === 0) found.push({ node, text: node.quasis[0]?.value.cooked ?? \"\" })\n return\n }\n\n for (const key of context.sourceCode.visitorKeys[node.type] ?? []) {\n const value = (node as unknown as Record<string, unknown>)[key]\n const children = Array.isArray(value) ? value : [value]\n\n for (const child of children) {\n const childNode = child as TSESTree.Node | null | undefined\n if (!childNode || typeof childNode.type !== \"string\") continue\n if (CONSTANTS.FUNCTIONS.NODE_TYPES.has(childNode.type)) continue\n collect(childNode, found)\n }\n }\n }\n\n return {\n JSXAttribute(node) {\n if (node.name.type !== \"JSXIdentifier\" || node.name.name !== \"className\" || node.value === null) return\n\n const found: { node: TSESTree.Node; text: string }[] = []\n collect(node.value, found)\n\n for (const { node: literal, text } of found) {\n if (text.length <= max) continue\n\n context.report({\n node: literal,\n messageId: \"tooLong\",\n data: { length: text.length, max },\n })\n }\n },\n }\n }\n}\n\nexport default new MaxClassNameLength()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"jsxComment\"\n\n/**\n * Flags an inline comment placed inside JSX (a `{ }` container holding only a\n * comment), which usually labels a section that should be its own named\n * component rather than a prose marker.\n */\nclass NoJSXComments extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-jsx-comments\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Disallow inline `{/* ... */}` comments inside JSX.\",\n recommended: true,\n category: \"react\",\n },\n schema: [],\n messages: {\n jsxComment: nitpick({\n problem: \"This JSX holds an inline `{/* ... */}` comment.\",\n why: \"A comment labeling a JSX section is a sign it should be its own named component, JSX should read as structure, not carry prose markers\",\n fix: \"Extract the section into a named sub-component whose name says what the comment said, or drop the comment\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n JSXExpressionContainer(node) {\n // Only a comment-only JSX container parses its inner expression as\n // empty, an ordinary value container never does\n if (node.expression.type !== \"JSXEmptyExpression\") return\n if (context.sourceCode.getCommentsInside(node).length === 0) return\n\n context.report({ node, messageId: \"jsxComment\" })\n },\n }\n }\n}\n\nexport default new NoJSXComments()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { isContextHookName } from \"@/lib/utils/react\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"destructure\"\n\n/**\n * Flags a context-consumer hook (`use…Context`) whose result is bound whole to a\n * variable instead of being destructured, since destructuring names exactly what\n * the caller uses and reads better than repeated `context.member` access.\n */\nclass RequireContextHookDestructure extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-context-hook-destructure\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require the result of a context-consumer hook to be destructured.\",\n recommended: true,\n category: \"react\",\n },\n schema: [],\n messages: {\n destructure: nitpick({\n problem: \"`{{hook}}` is bound whole instead of destructured.\",\n why: \"Destructuring at the call site names exactly what the caller uses and reads better than repeated `{{name}}.member` access\",\n fix: \"Destructure the members in use, e.g. `const { a, b } = {{hook}}()`\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n VariableDeclarator(node) {\n if (node.id.type !== \"Identifier\" || node.init?.type !== \"CallExpression\") return\n if (node.init.callee.type !== \"Identifier\" || !isContextHookName(node.init.callee.name)) return\n\n context.report({\n node,\n messageId: \"destructure\",\n data: { hook: node.init.callee.name, name: node.id.name },\n })\n },\n }\n }\n}\n\nexport default new RequireContextHookDestructure()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { enclosingFunction } from \"@/lib/utils/functions\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { isComponentOrHook, isDerivedValue } from \"@/lib/utils/react\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"useMemo\"\n\n/**\n * Flags a `const` in a component or hook whose value is derived through a\n * non-hook call (`list.find(...)`, `format(x)`), which recomputes on every\n * render, and asks for it to move into a `useMemo`.\n */\nclass RequireDerivedUseMemo extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-derived-usememo\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require a derived value in a component or hook to be memoized with useMemo.\",\n recommended: true,\n category: \"react\",\n },\n schema: [],\n messages: {\n useMemo: nitpick({\n problem: \"This derived value is computed inline on every render.\",\n why: \"A value derived through a call is recomputed each render and has nowhere to document itself, a useMemo makes it stable and gives it a JSDoc home\",\n fix: \"Wrap it in `useMemo(() => ..., [deps])` with a JSDoc describing the value, even for a one-liner\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n VariableDeclarator(node) {\n if (node.parent.type !== \"VariableDeclaration\" || node.parent.kind !== \"const\") return\n if (node.id.type !== \"Identifier\" || node.init === null) return\n\n // Only a direct local of a component or hook can move into a useMemo\n const fn = enclosingFunction(node)\n if (fn === null || !isComponentOrHook(fn, context.sourceCode.visitorKeys)) return\n\n if (!isDerivedValue(node.init, context.sourceCode.visitorKeys)) return\n\n context.report({ node, messageId: \"useMemo\" })\n },\n }\n }\n}\n\nexport default new RequireDerivedUseMemo()\n","import { ASTUtils, type TSESLint, type TSESTree } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { type FunctionNode, getFunctionName, someReturn } from \"@/lib/utils/functions\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { isFunctionValue, isHookName } from \"@/lib/utils/react\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"wrapInObject\"\n\n/**\n * Flags a custom hook that returns a bare function (directly or through a local\n * `useCallback`), and wraps it in an object, so the hook can grow new members\n * later without breaking every call site.\n */\nclass RequireHookObjectReturn extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-hook-object-return\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n fixable: \"code\",\n docs: {\n description: \"Require a custom hook to return an object rather than a bare function.\",\n recommended: true,\n category: \"react\",\n },\n schema: [],\n messages: {\n wrapInObject: nitpick({\n problem: \"This hook returns a bare function instead of an object.\",\n why: \"Returning an object lets the hook expose new members later without changing every call site, a bare function locks its shape\",\n fix: \"Return the function inside an object, e.g. `return { handleThing }`\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n // Whether a returned expression is a function, resolving a returned\n // identifier through its local declaration such as a \"useCallback\" const\n const returnsFunction = (argument: TSESTree.Expression): boolean => {\n if (isFunctionValue(argument)) return true\n if (argument.type !== \"Identifier\") return false\n\n const variable = ASTUtils.findVariable(context.sourceCode.getScope(argument), argument.name)\n const declarator = variable?.defs.at(-1)?.node\n return declarator?.type === \"VariableDeclarator\" && isFunctionValue(declarator.init)\n }\n\n const report = (argument: TSESTree.Expression): void => {\n context.report({\n node: argument,\n messageId: \"wrapInObject\",\n fix:\n argument.type === \"Identifier\"\n ? fixer => fixer.replaceText(argument, `{ ${argument.name} }`)\n : undefined,\n })\n }\n\n const check = (fn: FunctionNode): void => {\n const name = getFunctionName(fn)\n if (name === undefined || !isHookName(name)) return\n\n // An arrow with an expression body returns that expression directly\n if (fn.type === \"ArrowFunctionExpression\" && fn.body.type !== \"BlockStatement\") {\n if (returnsFunction(fn.body)) report(fn.body)\n return\n }\n\n someReturn(fn.body, context.sourceCode.visitorKeys, argument => {\n if (argument !== null && returnsFunction(argument)) report(argument)\n return false\n })\n }\n\n return {\n FunctionDeclaration(node) {\n check(node)\n },\n FunctionExpression(node) {\n check(node)\n },\n ArrowFunctionExpression(node) {\n check(node)\n },\n }\n }\n}\n\nexport default new RequireHookObjectReturn()\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { getJSDocLineTag, hasLeadingJSDoc } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"missingJSDoc\" | \"missingParam\"\n\n/**\n * Requires a JSDoc above a `useMemo` or `useCallback` so a memoized value or\n * handler documents its purpose. A `useCallback` must also carry an `@param` per\n * parameter, since it is a function.\n */\nclass RequireMemoCallbackJSDoc extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-memo-callback-jsdoc\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require a JSDoc on a useMemo or useCallback (with an `@param` per useCallback parameter).\",\n recommended: true,\n category: \"react\",\n },\n schema: [],\n messages: {\n missingJSDoc: nitpick({\n problem: \"This `{{hook}}` has no JSDoc.\",\n why: \"A memoized value or handler should document what it is, so its purpose is clear without reading the factory\",\n fix: \"Add a `/** ... */` JSDoc above the `const`\",\n }),\n missingParam: nitpick({\n problem: \"This `useCallback`'s JSDoc documents fewer parameters than the callback takes.\",\n why: \"A callback is a function, so each parameter it takes should be documented like any other\",\n fix: \"Add an `@param` line for each parameter of the callback\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n VariableDeclarator(node) {\n if (node.init?.type !== \"CallExpression\" || node.init.callee.type !== \"Identifier\") return\n if (!CONSTANTS.REACT.MEMO_HOOKS.has(node.init.callee.name)) return\n\n // The JSDoc sits above the whole declaration, or its export\n let target: TSESTree.Node = node.parent\n if (target.parent?.type === \"ExportNamedDeclaration\") target = target.parent\n\n if (!hasLeadingJSDoc(context.sourceCode, target)) {\n context.report({\n node: node.id,\n messageId: \"missingJSDoc\",\n data: { hook: node.init.callee.name },\n })\n return\n }\n\n if (node.init.callee.name !== \"useCallback\") return\n\n const callback = node.init.arguments[0]\n if (callback?.type !== \"ArrowFunctionExpression\" && callback?.type !== \"FunctionExpression\") return\n if (callback.params.length === 0) return\n\n const comment = context.sourceCode.getCommentsBefore(target).at(-1)\n const documented = (comment?.value.split(\"\\n\") ?? []).filter(\n line => getJSDocLineTag(line) === \"param\",\n ).length\n\n if (documented < callback.params.length) {\n context.report({ node: node.id, messageId: \"missingParam\" })\n }\n },\n }\n }\n}\n\nexport default new RequireMemoCallbackJSDoc()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\nimport migrationTableOrder from \"@/rules/adonisjs/migrationTableOrder\"\nimport requireControllerJSDoc from \"@/rules/adonisjs/requireControllerJSDoc\"\nimport requireMigrationJSDoc from \"@/rules/adonisjs/requireMigrationJSDoc\"\nimport requireValidatedRequest from \"@/rules/adonisjs/requireValidatedRequest\"\nimport catchErrorName from \"@/rules/base/catchErrorName\"\nimport maxJSDocDescriptionLength from \"@/rules/base/maxJSDocDescriptionLength\"\nimport noAliasVariables from \"@/rules/base/noAliasVariables\"\nimport noBritishEnglish from \"@/rules/base/noBritishEnglish\"\nimport noDecorativeCommentSeparators from \"@/rules/base/noDecorativeCommentSeparators\"\nimport noEmDash from \"@/rules/base/noEmDash\"\nimport noEmojis from \"@/rules/base/noEmojis\"\nimport noJSDocBlankBeforeTags from \"@/rules/base/noJSDocBlankBeforeTags\"\nimport noJSDocReturnsOnVoid from \"@/rules/base/noJSDocReturnsOnVoid\"\nimport noLineCommentBackticks from \"@/rules/base/noLineCommentBackticks\"\nimport noLineCommentPeriod from \"@/rules/base/noLineCommentPeriod\"\nimport noPropertyAccessAlias from \"@/rules/base/noPropertyAccessAlias\"\nimport noPropertyDestructuring from \"@/rules/base/noPropertyDestructuring\"\nimport noRelativeImports from \"@/rules/base/noRelativeImports\"\nimport noSingleLineJSDoc from \"@/rules/base/noSingleLineJSDoc\"\nimport requireCapitalizedComments from \"@/rules/base/requireCapitalizedComments\"\nimport requireCompleteJSDoc from \"@/rules/base/requireCompleteJSDoc\"\nimport requireFrameworkConfig from \"@/rules/base/requireFrameworkConfig\"\nimport requireFunctionJSDoc from \"@/rules/base/requireFunctionJSDoc\"\nimport requireMultilineObject from \"@/rules/base/requireMultilineObject\"\nimport maxClassNameLength from \"@/rules/react/maxClassNameLength\"\nimport noJSXComments from \"@/rules/react/noJSXComments\"\nimport requireContextHookDestructure from \"@/rules/react/requireContextHookDestructure\"\nimport requireDerivedUseMemo from \"@/rules/react/requireDerivedUseMemo\"\nimport requireHookObjectReturn from \"@/rules/react/requireHookObjectReturn\"\nimport requireMemoCallbackJSDoc from \"@/rules/react/requireMemoCallbackJSDoc\"\n\n/**\n * Every rule instance registered by the plugin.\n */\nconst ruleInstances = [\n migrationTableOrder,\n requireControllerJSDoc,\n requireMigrationJSDoc,\n requireValidatedRequest,\n catchErrorName,\n maxJSDocDescriptionLength,\n noAliasVariables,\n noBritishEnglish,\n noDecorativeCommentSeparators,\n noEmDash,\n noEmojis,\n noJSDocBlankBeforeTags,\n noJSDocReturnsOnVoid,\n noLineCommentBackticks,\n noLineCommentPeriod,\n noPropertyAccessAlias,\n noPropertyDestructuring,\n noRelativeImports,\n noSingleLineJSDoc,\n requireCapitalizedComments,\n requireCompleteJSDoc,\n requireFrameworkConfig,\n requireFunctionJSDoc,\n requireMultilineObject,\n maxClassNameLength,\n noJSXComments,\n requireContextHookDestructure,\n requireDerivedUseMemo,\n requireHookObjectReturn,\n requireMemoCallbackJSDoc,\n]\n\n/**\n * The plugin's rules, keyed by name, as the plain modules ESLint consumes.\n */\nexport const rules = Object.fromEntries(ruleInstances.map(rule => [rule.name, rule.toRuleModule()])) as Record<\n string,\n TSESLint.RuleModule<string, readonly unknown[], NitpickerRuleDocs>\n>\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport type { RuleCategory } from \"@/lib/utils/rules\"\nimport { rules } from \"@/rules\"\n\n/**\n * Builds the rules record for a single category, each enabled as a warning,\n * rules with no explicit category are treated as `base`.\n * @param category The category to collect rules for.\n * @returns The flat-config rules record for that category.\n */\nexport function categoryRules(category: RuleCategory): TSESLint.FlatConfig.Rules {\n const enabled: TSESLint.FlatConfig.Rules = {}\n\n for (const [name, rule] of Object.entries(rules)) {\n if ((rule.meta.docs?.category ?? \"base\") === category) {\n enabled[`${CONSTANTS.PLUGIN_NAME}/${name}`] = \"warn\"\n }\n }\n\n return enabled\n}\n\n/**\n * Builds a rules record enabling every rule the plugin ships, as a warning.\n * @returns The flat-config rules record for all rules.\n */\nexport function allRules(): TSESLint.FlatConfig.Rules {\n const enabled: TSESLint.FlatConfig.Rules = {}\n\n for (const name of Object.keys(rules)) {\n enabled[`${CONSTANTS.PLUGIN_NAME}/${name}`] = \"warn\"\n }\n\n return enabled\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { allRules } from \"@/configs/helpers\"\nimport CONSTANTS from \"@/lib/constants\"\n\n/**\n * Builds the `all` flat config: every rule the plugin ships, each enabled as a\n * warning, this is the maximally-pedantic Nitpicker experience. Both framework\n * settings flags are set, since enabling everything already opts into them.\n * @param plugin The plugin instance to register the rules against.\n * @returns The flat config object.\n */\nexport function all(plugin: TSESLint.FlatConfig.Plugin): TSESLint.FlatConfig.Config {\n return {\n name: `${CONSTANTS.PLUGIN_NAME}/all`,\n plugins: { [CONSTANTS.PLUGIN_NAME]: plugin },\n settings: { [CONSTANTS.PLUGIN_NAME]: { adonisjs: true, react: true } },\n rules: allRules(),\n }\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { categoryRules } from \"@/configs/helpers\"\nimport CONSTANTS from \"@/lib/constants\"\n\n/**\n * Builds the `base` flat config: the universal rules that apply to every file\n * regardless of framework.\n * @param plugin The plugin instance to register the rules against.\n * @returns The flat config object.\n */\nexport function base(plugin: TSESLint.FlatConfig.Plugin): TSESLint.FlatConfig.Config {\n return {\n name: `${CONSTANTS.PLUGIN_NAME}/base`,\n plugins: { [CONSTANTS.PLUGIN_NAME]: plugin },\n rules: categoryRules(\"base\"),\n }\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { base } from \"@/configs/rulesets/base\"\nimport CONSTANTS from \"@/lib/constants\"\n\n/**\n * Builds the `recommended` flat config: the sensible default for any project,\n * which is the universal `base` ruleset.\n * @param plugin The plugin instance to register the rules against.\n * @returns The flat config object.\n */\nexport function recommended(plugin: TSESLint.FlatConfig.Plugin): TSESLint.FlatConfig.Config {\n return {\n ...base(plugin),\n name: `${CONSTANTS.PLUGIN_NAME}/recommended`,\n }\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { categoryRules } from \"@/configs/helpers\"\nimport CONSTANTS from \"@/lib/constants\"\n\n// AdonisJS route files where banner separators are the clearest way to group routes\nconst ROUTE_FILE_GLOBS = [\"**/start/routes.ts\", \"**/start/routes/**/*.ts\"]\n\n/**\n * Builds the `adonisjs` flat config: AdonisJS-specific rules, plus a settings\n * flag so `require-framework-config` knows AdonisJS is opted into for these files.\n * It also permits decorative banners in route files, where they aid readability.\n * @param plugin The plugin instance to register the rules against.\n * @returns The flat config object.\n */\nexport function adonisjs(plugin: TSESLint.FlatConfig.Plugin): TSESLint.FlatConfig.Config {\n return {\n name: `${CONSTANTS.PLUGIN_NAME}/adonisjs`,\n plugins: { [CONSTANTS.PLUGIN_NAME]: plugin },\n settings: { [CONSTANTS.PLUGIN_NAME]: { adonisjs: true } },\n rules: {\n ...categoryRules(\"adonisjs\"),\n [`${CONSTANTS.PLUGIN_NAME}/no-decorative-comment-separators`]: [\"warn\", { allowIn: ROUTE_FILE_GLOBS }],\n },\n }\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { categoryRules } from \"@/configs/helpers\"\nimport CONSTANTS from \"@/lib/constants\"\n\n/**\n * Builds the `react` flat config: React-specific rules, plus a settings flag so\n * `require-framework-config` knows React is opted into for these files.\n * @param plugin The plugin instance to register the rules against.\n * @returns The flat config object.\n */\nexport function react(plugin: TSESLint.FlatConfig.Plugin): TSESLint.FlatConfig.Config {\n return {\n name: `${CONSTANTS.PLUGIN_NAME}/react`,\n plugins: { [CONSTANTS.PLUGIN_NAME]: plugin },\n settings: { [CONSTANTS.PLUGIN_NAME]: { react: true } },\n rules: categoryRules(\"react\"),\n }\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { all } from \"@/configs/presets/all\"\nimport { recommended } from \"@/configs/presets/recommended\"\nimport { adonisjs } from \"@/configs/rulesets/adonisjs\"\nimport { base } from \"@/configs/rulesets/base\"\nimport { react } from \"@/configs/rulesets/react\"\n\n/**\n * Builds all shared configs bundled with the plugin.\n *\n * Note: Configs are built from a factory rather than declared statically\n * because each one needs a reference to the plugin instance it belongs to.\n * @param plugin The plugin instance to register the rules against.\n * @returns A record of config name to flat config object.\n */\nexport function buildConfigs(plugin: TSESLint.FlatConfig.Plugin): Record<string, TSESLint.FlatConfig.Config> {\n return {\n base: base(plugin),\n recommended: recommended(plugin),\n adonisjs: adonisjs(plugin),\n react: react(plugin),\n all: all(plugin),\n }\n}\n","{\n \"name\": \"@alien_intelligence/eslint-plugin-nitpicker\",\n \"productName\": \"Nitpicker\",\n \"version\": \"0.7.6\",\n \"description\": \"A hyper-pedantic ESLint plugin that flags every stylistic and semantic nit, with AI-friendly fix context.\",\n \"author\": \"Alien <contact@alien.club> (https://www.alien.club/)\",\n \"license\": \"MIT\",\n \"private\": false,\n \"packageManager\": \"npm@11.4.2\",\n \"type\": \"module\",\n \"keywords\": [\n \"alien\",\n \"eslint\",\n \"eslintplugin\",\n \"eslint-plugin\",\n \"nitpicker\",\n \"linting\",\n \"code-style\",\n \"ai\"\n ],\n \"homepage\": \"https://github.com/Alien-Intelligence/eslint-plugin-nitpicker\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/Alien-Intelligence/eslint-plugin-nitpicker.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/Alien-Intelligence/eslint-plugin-nitpicker/issues\"\n },\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org/\",\n \"access\": \"public\",\n \"tag\": \"latest\"\n },\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n }\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"lint\": \"biome check\",\n \"lint:fix\": \"biome check --fix && biome format --write\",\n \"lint:nitpicker\": \"eslint \\\"src/**/*.ts\\\" \\\"tests/**/*.ts\\\"\",\n \"typecheck\": \"tsc --noEmit\",\n \"pretest\": \"node -e \\\"require('node:fs').rmSync('node_modules/.vite', { recursive: true, force: true })\\\"\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\"\n },\n \"peerDependencies\": {\n \"eslint\": \">=9.0.0\"\n },\n \"dependencies\": {\n \"@typescript-eslint/utils\": \"^8.18.0\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^2.5.2\",\n \"@types/node\": \"^24.12.2\",\n \"@typescript-eslint/parser\": \"^8.64.0\",\n \"eslint\": \"^9.17.0\",\n \"tsup\": \"^8.5.1\",\n \"typescript\": \"^5.8.3\",\n \"vitest\": \"^4.1.5\"\n }\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { buildConfigs } from \"@/configs\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { rules } from \"@/rules\"\n\n// Import the version from package.json to include in the plugin metadata\nimport { version } from \"../package.json\"\n\n/**\n * Main declaration of the `@alien_intelligence/eslint-plugin-nitpicker` plugin.\n */\nconst plugin: TSESLint.FlatConfig.Plugin = {\n meta: {\n name: `eslint-plugin-${CONSTANTS.PLUGIN_NAME}`,\n version,\n },\n rules,\n configs: {},\n}\n\n// Configs reference the plugin, so they are attached after it is created\nplugin.configs = buildConfigs(plugin)\n\nexport default plugin\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/lib/constants.ts","../src/lib/utils/rules.ts","../src/lib/rule.ts","../src/lib/utils/messages.ts","../src/lib/utils/migrations.ts","../src/rules/adonisjs/migrationTableOrder.ts","../src/lib/utils/controllers.ts","../src/lib/utils/words.ts","../src/lib/utils/comments.ts","../src/lib/utils/jsdocs.ts","../src/rules/adonisjs/requireControllerJSDoc.ts","../src/rules/adonisjs/requireMigrationJSDoc.ts","../src/lib/utils/regex.ts","../src/rules/adonisjs/requireValidatedRequest.ts","../src/rules/base/catchErrorName.ts","../src/rules/base/maxJSDocDescriptionLength.ts","../src/rules/base/maxLineCommentLength.ts","../src/lib/utils/aliases.ts","../src/rules/base/noAliasVariables.ts","../src/lib/data/britishToAmerican.ts","../src/lib/utils/dictionaries.ts","../src/rules/base/noBritishEnglish.ts","../src/lib/utils/decorations.ts","../src/rules/base/noDecorativeCommentSeparators.ts","../src/lib/utils/locations.ts","../src/rules/base/noEmDash.ts","../src/rules/base/noEmojis.ts","../src/rules/base/noJSDocBlankBeforeTags.ts","../src/lib/utils/functions.ts","../src/rules/base/noJSDocReturnsOnVoid.ts","../src/rules/base/noLineCommentBackticks.ts","../src/rules/base/noLineCommentPeriod.ts","../src/rules/base/noPropertyAccessAlias.ts","../src/rules/base/noPropertyDestructuring.ts","../src/rules/base/noRelativeImports.ts","../src/rules/base/noSingleLineJSDoc.ts","../src/rules/base/requireCapitalizedComments.ts","../src/lib/utils/react.ts","../src/rules/base/requireCompleteJSDoc.ts","../src/lib/utils/frameworks.ts","../src/rules/base/requireFrameworkConfig.ts","../src/rules/base/requireFunctionJSDoc.ts","../src/rules/base/requireJSDocDelimiterLines.ts","../src/lib/utils/objects.ts","../src/rules/base/requireMultilineObject.ts","../src/rules/react/maxClassNameLength.ts","../src/rules/react/noJSXComments.ts","../src/rules/react/requireContextHookDestructure.ts","../src/rules/react/requireDerivedUseMemo.ts","../src/rules/react/requireHookObjectReturn.ts","../src/rules/react/requireMemoCallbackJSDoc.ts","../src/rules/index.ts","../src/configs/helpers.ts","../src/configs/presets/all.ts","../src/configs/rulesets/base.ts","../src/configs/presets/recommended.ts","../src/configs/rulesets/adonisjs.ts","../src/configs/rulesets/react.ts","../src/configs/index.ts","../package.json","../src/index.ts"],"names":["CONSTANTS","constants_default","createRule","ESLintUtils","NitpickerRule","context","options","nitpick","problem","why","fix","isMigrationClass","node","getCreateTableBuilder","callback","getTableStatementCategory","statement","builderName","root","rootBuilderCall","expression","current","firstArgument","literal","MigrationTableOrder","builder","maxRank","category","rank","migrationTableOrder_default","isControllerClass","extractWords","text","words","match","matchCase","source","replacement","isWordChar","char","isDirectiveComment","comment","firstCommentContentChar","base","offset","line","markerLength","findProsePeriods","periods","quote","index","rest","endsWithAbbreviation","findBacktickSpans","spans","closing","lowercase","abbreviation","before","isJSDocComment","jsDocAnchor","declaration","earliest","found","decorator","getLeadingJSDoc","sourceCode","commentsBefore","closest","getJSDocParamNames","names","name","hasJSDocReturnsTag","tag","getJSDocLineTag","hasLeadingJSDoc","isBlankJSDocLine","isJSDocTagLine","getJSDocDescription","parts","content","findJSDocReturnsRange","tagLine","to","RequireControllerJSDoc","requireControllerJSDoc_default","RequireMigrationJSDoc","requireMigrationJSDoc_default","globToRegExp","glob","normalized","pattern","matchesGlob","filename","patterns","path","RequireValidatedRequest","allowIn","isRequest","requireValidatedRequest_default","CatchErrorName","catchErrorName_default","MaxJSDocDescriptionLength","max","length","maxJSDocDescriptionLength_default","MaxLineCommentLength","proseOf","run","report","first","last","previous","isConsecutive","maxLineCommentLength_default","propertyAccessPath","properties","isPropertyAccessAlias","isReassigned","scope","variable","ASTUtils","declarations","definition","reference","isPathWritten","written","target","isAllShorthand","property","NoAliasVariables","noAliasVariables_default","BRITISH_TO_AMERICAN","buildDictionary","extra","ignore","dictionary","key","value","NoBritishEnglish","word","american","cased","from","fixer","noBritishEnglish_default","isDecorativeCommentLine","NoDecorativeCommentSeparators","lines","reportedLine","noDecorativeCommentSeparators_default","TOKEN_TYPES","allowedRanges","allow","locations","ranges","tokenTypes","location","type","token","isInAnyRange","start","end","NoEmDash","noEmDash_default","NoEmojis","noEmojis_default","NoJSDocBlankBeforeTags","runEnd","nextLine","noJSDocBlankBeforeTags_default","getDocumentableNode","fn","isTopLevel","parameterDocs","docs","collect","param","enclosingFunction","isDynamicImportThunk","getFunctionName","someReturn","visitorKeys","predicate","children","child","childNode","functionReturnsValue","argument","isVoidReturnType","annotation","isVoidFunction","NoJSDocReturnsOnVoid","check","anchor","jsdoc","range","noJSDocReturnsOnVoid_default","NoLineCommentBackticks","span","noLineCommentBackticks_default","NoLineCommentPeriod","period","loc","noLineCommentPeriod_default","NoPropertyAccessAlias","candidates","recordWrite","candidate","noPropertyAccessAlias_default","NoPropertyDestructuring","noPropertyDestructuring_default","NoRelativeImports","noRelativeImports_default","NoSingleLineJSDoc","indent","expanded","noSingleLineJSDoc_default","RequireCapitalizedComments","isContinuation","requireCapitalizedComments_default","isReactComponentName","isHookName","isContextHookName","isFunctionValue","isJsxExpression","functionReturnsJsx","isComponentOrHook","hasNonHookCall","isDerivedValue","RequireCompleteJSDoc","documented","plainNames","doc","entry","requireCompleteJSDoc_default","FRAMEWORK_LABELS","importSources","sources","detectFrameworks","detected","RequireFrameworkConfig","ignored","enabled","framework","requireFrameworkConfig_default","RequireFunctionJSDoc","include","documentable","checkDeclared","memberName","requireFunctionJSDoc_default","RequireJSDocDelimiterLines","segments","opening","spacer","requireJSDocDelimiterLines_default","expandObjectLiteral","baseIndent","propertyIndent","RequireMultilineObject","maxKeys","hasComments","requireMultilineObject_default","MaxClassNameLength","maxClassNameLength_default","NoJSXComments","noJSXComments_default","RequireContextHookDestructure","requireContextHookDestructure_default","RequireDerivedUseMemo","requireDerivedUseMemo_default","RequireHookObjectReturn","returnsFunction","declarator","requireHookObjectReturn_default","RequireMemoCallbackJSDoc","requireMemoCallbackJSDoc_default","ruleInstances","rules","rule","categoryRules","allRules","all","plugin","recommended","ROUTE_FILE_GLOBS","adonisjs","react","buildConfigs","version","index_default"],"mappings":"4DAGA,IAAMA,EAAAA,CAAY,CAKd,WAAA,CAAa,WAAA,CAKb,SAAU,+DAAA,CAKV,OAAA,CAAS,QAAA,CAOT,KAAA,CAAO,IAAA,MAAA,CAAC,6MAAA,CAAiM,IAAE,CAAA,CAK3M,QAAA,CAAU,CAKN,WAAA,CAAa,OAAA,CAMb,cAAA,CAAgB,kBAKhB,aAAA,CAAe,oCAAA,CAMf,SAAA,CACI,iJAAA,CAOJ,MAAA,CAAQ,IAAI,IAAI,CAAC,GAAA,CAAK,GAAG,CAAC,CAAA,CAM1B,aAAA,CAAe,CAAC,MAAA,CAAQ,MAAA,CAAQ,MAAA,CAAQ,KAAA,CAAO,KAAA,CAAO,KAAA,CAAO,UAAW,OAAO,CAAA,CAM/E,cAAA,CAAgB,GACpB,CAAA,CAKA,KAAA,CAAO,CAKH,GAAA,CAAK,kBAAA,CAOL,SAAA,CAAW,iDAAA,CAKX,sBAAA,CAAwB,GAC5B,EAKA,KAAA,CAAO,CAKH,UAAW,iBAAA,CAMX,QAAA,CAAU,qCACd,CAAA,CAKA,OAAA,CAAS,CAKL,eAAA,CAAiB,CAAA,CAMjB,YAAA,CAAc,CAClB,CAAA,CAKA,SAAA,CAAW,CAIP,UAAA,CAAY,IAAI,GAAA,CAAI,CAAC,qBAAA,CAAuB,oBAAA,CAAsB,yBAAyB,CAAC,CAChG,CAAA,CAKA,WAAY,CAIR,cAAA,CACI,sGAAA,CAKJ,UAAA,CAAY,WAChB,CAAA,CAKA,MAAO,CAKH,IAAA,CAAM,WAAA,CAMN,YAAA,CAAc,sBAAA,CAKd,UAAA,CAAY,IAAI,GAAA,CAAI,CAAC,SAAA,CAAW,aAAa,CAAC,CAAA,CAK9C,qBAAsB,GAC1B,CAAA,CAKA,OAAA,CAAS,CAKL,aAAA,CAAe,IAAI,IAAI,CAAC,OAAA,CAAS,OAAQ,IAAA,CAAM,KAAA,CAAO,OAAQ,QAAQ,CAAC,CAC3E,CAAA,CAKA,UAAA,CAAY,CAIR,cAAe,IAAI,GAAA,CAAI,CAAC,OAAA,CAAS,QAAA,CAAU,SAAA,CAAW,SAAS,CAAC,CAAA,CAKhE,iBAAA,CAAmB,IAAI,GAAA,CAAI,CAAC,YAAa,UAAA,CAAY,UAAU,CAAC,CAAA,CAMhE,gBAAA,CAAkB,IAAI,IAAI,CAAC,YAAA,CAAc,YAAA,CAAc,YAAY,CAAC,CAAA,CAMpE,eAAgB,CAAC,QAAA,CAAU,WAAA,CAAa,OAAO,CACnD,CACJ,EAEOC,CAAAA,CAAQD,EAAAA,CCjMR,IAAME,EAAAA,CAAaC,WAAAA,CAAY,WAAA,CAClC,IAAM,CAAA,EAAGF,CAAAA,CAAU,QAAQ,CAAA,0BAAA,CAC/B,CAAA,CCzBO,IAAeG,CAAAA,CAAf,KAA0G,CAgC7G,cAA4E,CACxE,OAAOF,EAAAA,CAAgC,CACnC,IAAA,CAAM,IAAA,CAAK,KACX,IAAA,CAAM,IAAA,CAAK,IAAA,CACX,cAAA,CAAgB,IAAA,CAAK,cAAA,CACrB,OAAQ,CAACG,CAAAA,CAASC,CAAAA,GAAY,IAAA,CAAK,MAAA,CAAOD,CAAAA,CAASC,CAAO,CAC9D,CAAC,CACL,CACJ,CAAA,CCtBO,SAASC,EAAQ,CAAE,OAAA,CAAAC,CAAAA,CAAS,GAAA,CAAAC,CAAAA,CAAK,GAAA,CAAAC,CAAI,CAAA,CAAoB,CAC5D,OAAO,CAAA,EAAGF,CAAO;AAAA,SAAA,EAAcC,CAAG;AAAA,SAAA,EAAcC,CAAG,CAAA,CACvD,CCbO,SAASC,EAAAA,CAAiBC,CAAAA,CAA0C,CACvE,OACIA,CAAAA,CAAK,MAAA,CAAO,IAAA,GAAS,0BAAA,EACrBA,CAAAA,CAAK,UAAA,EAAY,IAAA,GAAS,YAAA,EAC1BA,CAAAA,CAAK,UAAA,CAAW,IAAA,GAAS,YAEjC,CAQO,SAASC,EAAAA,CAAsBD,CAAAA,CAG7B,CAML,GALIA,CAAAA,CAAK,MAAA,CAAO,IAAA,GAAS,oBAAsBA,CAAAA,CAAK,MAAA,CAAO,QAAA,CAAS,IAAA,GAAS,YAAA,EACzEA,CAAAA,CAAK,MAAA,CAAO,QAAA,CAAS,IAAA,GAAS,aAAA,EAG9BA,CAAAA,CAAK,MAAA,CAAO,MAAA,CAAO,IAAA,GAAS,kBAAA,EAAsBA,CAAAA,CAAK,MAAA,CAAO,MAAA,CAAO,QAAA,CAAS,IAAA,GAAS,YAAA,EACvFA,CAAAA,CAAK,MAAA,CAAO,MAAA,CAAO,QAAA,CAAS,IAAA,GAAS,QAAA,CAAU,OAAO,IAAA,CAE1D,IAAME,EAAWF,CAAAA,CAAK,SAAA,CAAU,EAAA,CAAG,EAAE,CAAA,CAErC,OADIE,CAAAA,EAAU,IAAA,GAAS,yBAAA,EAA6BA,CAAAA,EAAU,IAAA,GAAS,oBAAA,EACnEA,CAAAA,CAAS,IAAA,CAAK,IAAA,GAAS,gBAAA,EAAoBA,CAAAA,CAAS,MAAA,CAAO,CAAC,CAAA,EAAG,IAAA,GAAS,YAAA,CAAqB,IAAA,CAE1F,CAAE,IAAA,CAAMA,CAAAA,CAAS,IAAA,CAAK,IAAA,CAAM,WAAA,CAAaA,CAAAA,CAAS,MAAA,CAAO,CAAC,CAAA,CAAE,IAAK,CAC5E,CAUO,SAASC,EAAAA,CAA0BC,CAAAA,CAA+BC,CAAAA,CAA2C,CAChH,GAAID,CAAAA,CAAU,IAAA,GAAS,qBAAA,CAAuB,OAAO,IAAA,CAErD,IAAME,CAAAA,CAAOC,EAAAA,CAAgBH,CAAAA,CAAU,UAAA,CAAYC,CAAW,CAAA,CAC9D,OAAIC,CAAAA,GAAS,IAAA,CAAa,IAAA,CAEtBjB,CAAAA,CAAU,UAAA,CAAW,aAAA,CAAc,GAAA,CAAIiB,EAAK,MAAM,CAAA,CAAU,OAAA,CAC5DA,CAAAA,CAAK,MAAA,GAAW,YAAA,CAAqB,WAAA,CAErCjB,CAAAA,CAAU,UAAA,CAAW,iBAAA,CAAkB,GAAA,CAAIiB,CAAAA,CAAK,MAAM,CAAA,CAClDA,CAAAA,CAAK,aAAA,GAAkB,MAAA,EAAajB,CAAAA,CAAU,UAAA,CAAW,gBAAA,CAAiB,GAAA,CAAIiB,CAAAA,CAAK,aAAa,CAAA,CACzF,WAAA,CAKJ,IAAA,CAGJ,QACX,CASA,SAASC,EAAAA,CACLC,CAAAA,CACAH,CAAAA,CAC4D,CAC5D,IAAII,CAAAA,CAAyBD,CAAAA,CAE7B,KAAOC,CAAAA,CAAQ,IAAA,GAAS,gBAAA,EAAoBA,CAAAA,CAAQ,MAAA,CAAO,IAAA,GAAS,kBAAA,EAAoB,CACpF,GAAIA,CAAAA,CAAQ,MAAA,CAAO,MAAA,CAAO,IAAA,GAAS,YAAA,EAAgBA,CAAAA,CAAQ,MAAA,CAAO,MAAA,CAAO,IAAA,GAASJ,CAAAA,CAAa,CAC3F,GAAII,CAAAA,CAAQ,MAAA,CAAO,QAAA,CAAS,IAAA,GAAS,aAAc,OAAO,IAAA,CAE1D,IAAMC,CAAAA,CAAgBD,CAAAA,CAAQ,SAAA,CAAU,CAAC,CAAA,CACnCE,CAAAA,CACFD,CAAAA,EAAe,IAAA,GAAS,SAAA,EAAa,OAAOA,CAAAA,CAAc,KAAA,EAAU,QAAA,CAC9DA,CAAAA,CAAc,KAAA,CACd,MAAA,CAEV,OAAO,CAAE,MAAA,CAAQD,CAAAA,CAAQ,MAAA,CAAO,QAAA,CAAS,IAAA,CAAM,aAAA,CAAeE,CAAQ,CAC1E,CAEAF,CAAAA,CAAUA,CAAAA,CAAQ,MAAA,CAAO,OAC7B,CAEA,OAAO,IACX,CC5FA,IAAMG,CAAAA,CAAN,cAAkCpB,CAAmC,CACxD,IAAA,CAAO,uBAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,IAAA,CAAM,CACF,WAAA,CAAa,6FAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,UACd,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,UAAA,CAAYG,CAAAA,CAAQ,CAChB,OAAA,CAAS,4DAAA,CACT,GAAA,CAAK,8HAAA,CACL,GAAA,CAAK,6FACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAAqF,CACxF,OAAO,CACH,cAAA,CAAeO,CAAAA,CAAM,CACjB,IAAMa,CAAAA,CAAUZ,EAAAA,CAAsBD,CAAI,CAAA,CAC1C,GAAIa,CAAAA,GAAY,IAAA,CAAM,OAEtB,IAAIC,CAAAA,CAAU,CAAA,CAEd,IAAA,IAAWV,CAAAA,IAAaS,CAAAA,CAAQ,IAAA,CAAM,CAClC,IAAME,CAAAA,CAAWZ,EAAAA,CAA0BC,CAAAA,CAAWS,CAAAA,CAAQ,WAAW,CAAA,CACzE,GAAIE,CAAAA,GAAa,IAAA,CAAM,SAEvB,IAAMC,CAAAA,CAAO3B,CAAAA,CAAU,UAAA,CAAW,cAAA,CAAe,OAAA,CAAQ0B,CAAQ,CAAA,CAC7DC,CAAAA,CAAOF,CAAAA,EACPrB,EAAQ,MAAA,CAAO,CACX,IAAA,CAAMW,CAAAA,CACN,SAAA,CAAW,YAAA,CACX,IAAA,CAAM,CAAE,QAAA,CAAAW,CAAS,CACrB,CAAC,CAAA,CAGLD,CAAAA,CAAU,IAAA,CAAK,GAAA,CAAIA,CAAAA,CAASE,CAAI,EACpC,CACJ,CACJ,CACJ,CACJ,CAAA,CAEOC,EAAAA,CAAQ,IAAIL,CAAAA,CCzDZ,SAASM,EAAAA,CAAkBlB,CAAAA,CAA0C,CACxE,OAAOA,CAAAA,CAAK,MAAA,CAAO,IAAA,GAAS,0BAAA,EAA8BA,CAAAA,CAAK,EAAA,EAAI,IAAA,CAAK,QAAA,CAAS,YAAY,CAAA,GAAM,IACvG,CCaO,SAASmB,CAAAA,CAAaC,CAAAA,CAAsB,CAC/C,IAAMC,CAAAA,CAAgB,EAAC,CAEvB,IAAA,IAAWC,CAAAA,IAASF,CAAAA,CAAK,QAAA,CAAS/B,CAAAA,CAAU,KAAA,CAAM,QAAQ,CAAA,CAClDiC,CAAAA,CAAM,KAAA,GAAU,QAChBD,CAAAA,CAAM,IAAA,CAAK,CAAE,IAAA,CAAMC,CAAAA,CAAM,CAAC,CAAA,CAAG,KAAA,CAAOA,CAAAA,CAAM,KAAM,CAAC,CAAA,CAIzD,OAAOD,CACX,CAUO,SAASE,CAAAA,CAAUC,CAAAA,CAAgBC,CAAAA,CAA6B,CACnE,OAAID,CAAAA,GAAWA,CAAAA,CAAO,WAAA,EAAY,CACvBC,CAAAA,CAAY,WAAA,EAAY,CAG/BD,CAAAA,CAAO,MAAA,CAAO,CAAC,CAAA,GAAMA,CAAAA,CAAO,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAY,CAC3CC,CAAAA,CAAY,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAY,CAAIA,CAAAA,CAAY,KAAA,CAAM,CAAC,CAAA,CAG7DA,CACX,CASO,SAASC,EAAAA,CAAWC,CAAAA,CAAmC,CAC1D,OAAOA,CAAAA,GAAS,MAAA,EAAatC,CAAAA,CAAU,KAAA,CAAM,SAAA,CAAU,IAAA,CAAKsC,CAAI,CACpE,CCXO,SAASC,CAAAA,CAAmBC,CAAAA,CAAoC,CACnE,OAAOxC,CAAAA,CAAU,QAAA,CAAS,SAAA,CAAU,IAAA,CAAKwC,CAAAA,CAAQ,KAAK,CAC1D,CAUO,SAASC,EAAAA,CAAwBD,CAAAA,CAAkD,CAEtF,IAAME,CAAAA,CAAOF,CAAAA,CAAQ,KAAA,CAAM,CAAC,CAAA,CAAI,CAAA,CAEhC,GAAIA,CAAAA,CAAQ,IAAA,GAAS,MAAA,CAAQ,CACzB,IAAMP,CAAAA,CAAQO,CAAAA,CAAQ,KAAA,CAAM,KAAA,CAAM,KAAK,CAAA,CACvC,OAAIP,CAAAA,EAAO,KAAA,GAAU,MAAA,CAAkB,IAAA,CAEhC,CACH,KAAA,CAAOS,CAAAA,CAAOT,CAAAA,CAAM,KAAA,CACpB,IAAA,CAAMA,CAAAA,CAAM,CAAC,CACjB,CACJ,CAEA,IAAIU,CAAAA,CAAS,CAAA,CACb,IAAA,IAAWC,CAAAA,IAAQJ,CAAAA,CAAQ,KAAA,CAAM,KAAA,CAAM;AAAA,CAAI,CAAA,CAAG,CAG1C,IAAMK,CAAAA,CAAAA,CAAgBD,EAAK,KAAA,CAAM,aAAa,CAAA,GAAI,CAAC,CAAA,EAAK,EAAA,EAAI,OACtDN,CAAAA,CAAOM,CAAAA,CAAK,KAAA,CAAMC,CAAY,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,CAE9C,GAAIP,CAAAA,GAAS,EAAA,CACT,OAAO,CACH,MAAOI,CAAAA,CAAOC,CAAAA,CAASE,CAAAA,CACvB,IAAA,CAAAP,CACJ,CAAA,CAGJK,GAAUC,CAAAA,CAAK,MAAA,CAAS,EAC5B,CAEA,OAAO,IACX,CASO,SAASE,EAAAA,CAAiBN,CAAAA,CAA0C,CACvE,IAAMO,CAAAA,CAAyB,EAAC,CAG1BL,CAAAA,CAAOF,CAAAA,CAAQ,KAAA,CAAM,CAAC,CAAA,CAAI,EAC5BQ,CAAAA,CAAuB,IAAA,CAE3B,QAASC,CAAAA,CAAQ,CAAA,CAAGA,EAAQT,CAAAA,CAAQ,KAAA,CAAM,MAAA,CAAQS,CAAAA,EAAAA,CAAS,CACvD,IAAMX,EAAOE,CAAAA,CAAQ,KAAA,CAAM,MAAA,CAAOS,CAAK,CAAA,CAGvC,GAAID,IAAU,IAAA,CAAM,CACZV,CAAAA,GAASU,CAAAA,GAAOA,CAAAA,CAAQ,IAAA,CAAA,CAC5B,QACJ,CAIA,GAAIhD,CAAAA,CAAU,QAAA,CAAS,MAAA,CAAO,GAAA,CAAIsC,CAAI,CAAA,EAAKE,CAAAA,CAAQ,KAAA,CAAM,QAAA,CAASF,CAAAA,CAAMW,CAAAA,CAAQ,CAAC,CAAA,CAAG,CAChFD,CAAAA,CAAQV,CAAAA,CACR,QACJ,CAEA,GAAIA,CAAAA,GAAS,GAAA,CAAK,SAGlB,GAAIE,CAAAA,CAAQ,KAAA,CAAM,OAAOS,CAAAA,CAAQ,CAAC,IAAM,GAAA,CAAK,CACzC,KAAOT,CAAAA,CAAQ,KAAA,CAAM,MAAA,CAAOS,CAAAA,CAAQ,CAAC,CAAA,GAAM,KAAKA,CAAAA,EAAAA,CAChD,QACJ,CAEA,IAAMC,CAAAA,CAAOV,CAAAA,CAAQ,MAAM,KAAA,CAAMS,CAAAA,CAAQ,CAAC,CAAA,CAItCC,CAAAA,GAAS,EAAA,EAAM,CAAC,MAAA,CAAO,IAAA,CAAKA,CAAI,CAAA,EAEhCC,EAAAA,CAAqBX,CAAAA,CAAQ,MAAM,KAAA,CAAM,CAAA,CAAGS,CAAAA,CAAQ,CAAC,CAAC,CAAA,EAE1DF,EAAQ,IAAA,CAAK,CACT,KAAA,CAAOL,CAAAA,CAAOO,CAAAA,CACd,QAAA,CAAUC,EAAK,IAAA,EAAK,GAAM,EAC9B,CAAC,EACL,CAEA,OAAOH,CACX,CASO,SAASK,EAAAA,CAAkBZ,CAAAA,CAA2C,CACzE,IAAMa,CAAAA,CAAwB,EAAC,CAGzBX,CAAAA,CAAOF,CAAAA,CAAQ,KAAA,CAAM,CAAC,CAAA,CAAI,CAAA,CAEhC,IAAA,IAASS,CAAAA,CAAQ,CAAA,CAAGA,CAAAA,CAAQT,EAAQ,KAAA,CAAM,MAAA,CAAQS,CAAAA,EAAAA,CAAS,CACvD,GAAIT,CAAAA,CAAQ,MAAM,MAAA,CAAOS,CAAK,CAAA,GAAM,GAAA,CAAK,SAGzC,GAAIT,EAAQ,KAAA,CAAM,MAAA,CAAOS,CAAAA,CAAQ,CAAC,CAAA,GAAM,GAAA,CAAK,CACzC,KAAOT,CAAAA,CAAQ,KAAA,CAAM,MAAA,CAAOS,CAAAA,CAAQ,CAAC,IAAM,GAAA,EAAKA,CAAAA,EAAAA,CAChD,QACJ,CAEA,IAAMK,CAAAA,CAAUd,EAAQ,KAAA,CAAM,OAAA,CAAQ,IAAKS,CAAAA,CAAQ,CAAC,EACpD,GAAIK,CAAAA,GAAY,EAAA,CAAI,MAEpB,IAAMvB,CAAAA,CAAOS,EAAQ,KAAA,CAAM,KAAA,CAAMS,CAAAA,CAAQ,CAAA,CAAGK,CAAO,CAAA,CAG9CvB,EAAK,QAAA,CAAS,GAAG,CAAA,EAClBsB,CAAAA,CAAM,IAAA,CAAK,CACP,MAAOX,CAAAA,CAAOO,CAAAA,CACd,GAAA,CAAKP,CAAAA,CAAOY,CAAAA,CACZ,IAAA,CAAAvB,CACJ,CAAC,CAAA,CAGLkB,CAAAA,CAAQK,EACZ,CAEA,OAAOD,CACX,CAQA,SAASF,EAAAA,CAAqBpB,CAAAA,CAAuB,CACjD,IAAMwB,EAAYxB,CAAAA,CAAK,WAAA,EAAY,CAEnC,OAAO/B,CAAAA,CAAU,QAAA,CAAS,cAAc,IAAA,CAAKwD,CAAAA,EAAgB,CACzD,GAAI,CAACD,EAAU,QAAA,CAASC,CAAY,CAAA,CAAG,OAAO,MAAA,CAG9C,IAAMC,EAASF,CAAAA,CAAU,MAAA,CAAOA,CAAAA,CAAU,MAAA,CAASC,CAAAA,CAAa,MAAA,CAAS,CAAC,CAAA,CAC1E,OAAOC,CAAAA,GAAW,EAAA,EAAM,CAACpB,EAAAA,CAAWoB,CAAM,CAC9C,CAAC,CACL,CC1MO,SAASC,CAAAA,CAAelB,EAAoC,CAC/D,OAAOA,CAAAA,CAAQ,IAAA,GAAS,OAAA,EAAWA,CAAAA,CAAQ,MAAM,UAAA,CAAW,GAAG,CACnE,CASO,SAASmB,EAAAA,CAAYhD,EAAoC,CAC5D,IAAMiD,CAAAA,CAAAA,CACDjD,CAAAA,CAAK,IAAA,GAAS,0BAAA,EAA8BA,EAAK,IAAA,GAAS,wBAAA,GAC3DA,EAAK,WAAA,GAAgB,IAAA,CACfA,EAAK,WAAA,CACLA,CAAAA,CAMJkD,CAAAA,CAAAA,CAJa,YAAA,GAAgBD,CAAAA,CAAcA,CAAAA,CAAY,WAAa,MAAA,GAI7C,MAAA,CACzB,CAACE,CAAAA,CAAOC,CAAAA,GAAeD,CAAAA,GAAU,QAAaC,CAAAA,CAAU,KAAA,CAAM,CAAC,CAAA,CAAID,CAAAA,CAAM,KAAA,CAAM,CAAC,CAAA,CAAIC,CAAAA,CAAYD,CAAAA,CAChG,MACJ,CAAA,CAEA,OAAOD,IAAa,MAAA,EAAaA,CAAAA,CAAS,KAAA,CAAM,CAAC,CAAA,CAAIlD,CAAAA,CAAK,MAAM,CAAC,CAAA,CAAIkD,CAAAA,CAAWlD,CACpF,CAQO,SAASqD,EACZC,CAAAA,CACAtD,CAAAA,CACuB,CACvB,IAAMuD,CAAAA,CAAiBD,CAAAA,CAAW,kBAAkBN,EAAAA,CAAYhD,CAAI,CAAC,CAAA,CAIjEsC,CAAAA,CAAQiB,CAAAA,CAAe,OAAS,CAAA,CACpC,KAAOjB,CAAAA,EAAS,CAAA,EAAG,CACf,IAAMT,EAAU0B,CAAAA,CAAejB,CAAK,CAAA,CACpC,GAAIT,CAAAA,GAAY,MAAA,EAAa,CAACD,CAAAA,CAAmBC,CAAO,CAAA,CAAG,MAC3DS,CAAAA,GACJ,CAEA,IAAMkB,CAAAA,CAAUD,CAAAA,CAAejB,CAAK,CAAA,CACpC,OAAOkB,CAAAA,GAAY,QAAaT,CAAAA,CAAeS,CAAO,CAAA,CAAIA,CAAAA,CAAU,IACxE,CAQO,SAASC,EAAAA,CAAmB5B,CAAAA,CAAwC,CACvE,IAAM6B,CAAAA,CAAQ,IAAI,IAElB,IAAA,IAAWzB,CAAAA,IAAQJ,CAAAA,CAAQ,KAAA,CAAM,KAAA,CAAM;AAAA,CAAI,CAAA,CAAG,CAC1C,IAAM8B,CAAAA,CAAO1B,CAAAA,CAAK,KAAA,CAAM5C,CAAAA,CAAU,KAAA,CAAM,SAAS,CAAA,GAAI,CAAC,CAAA,CAClDsE,CAAAA,GAAS,MAAA,EAAWD,CAAAA,CAAM,GAAA,CAAIC,CAAI,EAC1C,CAEA,OAAOD,CACX,CAOO,SAASE,EAAAA,CAAmB/B,CAAAA,CAAoC,CACnE,OAAOA,CAAAA,CAAQ,MAAM,KAAA,CAAM;AAAA,CAAI,EAAE,IAAA,CAAKI,CAAAA,EAAQ,CAC1C,IAAM4B,EAAMC,CAAAA,CAAgB7B,CAAI,CAAA,CAChC,OAAO4B,IAAQ,SAAA,EAAaA,CAAAA,GAAQ,QACxC,CAAC,CACL,CAQO,SAASE,CAAAA,CAAgBT,CAAAA,CAA2CtD,EAA8B,CACrG,OAAOqD,CAAAA,CAAgBC,CAAAA,CAAYtD,CAAI,CAAA,GAAM,IACjD,CAQO,SAASgE,EAAiB/B,CAAAA,CAAuB,CACpD,OAAO,YAAA,CAAa,KAAKA,CAAI,CACjC,CAQO,SAAS6B,EAAgB7B,CAAAA,CAA6B,CAEzD,OADcA,CAAAA,CAAK,MAAM5C,CAAAA,CAAU,KAAA,CAAM,GAAG,CAAA,GAC7B,CAAC,CAAA,EAAK,IACzB,CAQO,SAAS4E,EAAehC,CAAAA,CAAuB,CAClD,OAAO6B,CAAAA,CAAgB7B,CAAI,CAAA,GAAM,IACrC,CASO,SAASiC,GAAoBrC,CAAAA,CAAmC,CACnE,IAAMsC,CAAAA,CAAkB,EAAC,CAEzB,IAAA,IAAWlC,CAAAA,IAAQJ,CAAAA,CAAQ,MAAM,KAAA,CAAM;AAAA,CAAI,CAAA,CAAG,CAC1C,IAAMuC,CAAAA,CAAUnC,CAAAA,CAAK,OAAA,CAAQ,WAAA,CAAa,EAAE,CAAA,CAAE,OAAA,EAAQ,CACtD,GAAImC,CAAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,CAAG,MAE7BD,CAAAA,CAAM,IAAA,CAAKC,CAAO,EACtB,CAEA,OAAOD,CAAAA,CAAM,IAAA,CAAK,GAAG,CAAA,CAAE,OAAA,CAAQ,OAAQ,GAAG,CAAA,CAAE,IAAA,EAChD,CAUO,SAASE,EAAAA,CACZf,CAAAA,CACAzB,CAAAA,CACmC,CACnC,IAAIyC,CAAAA,CAAU,EAAA,CACd,IAAA,IAASrC,CAAAA,CAAOJ,CAAAA,CAAQ,IAAI,KAAA,CAAM,IAAA,CAAO,CAAA,CAAGI,CAAAA,CAAOJ,CAAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,IAAA,CAAMI,CAAAA,EAAAA,CAAQ,CAC7E,IAAM4B,CAAAA,CAAMC,CAAAA,CAAgBR,CAAAA,CAAW,KAAA,CAAMrB,CAAAA,CAAO,CAAC,CAAA,EAAK,EAAE,CAAA,CAC5D,GAAI4B,CAAAA,GAAQ,SAAA,EAAaA,CAAAA,GAAQ,QAAA,CAAU,CACvCS,CAAAA,CAAUrC,CAAAA,CACV,KACJ,CACJ,CAEA,GAAIqC,CAAAA,GAAY,GAAI,OAAO,IAAA,CAE3B,IAAIC,CAAAA,CAAK1C,CAAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,IAAA,CAAO,CAAA,CAChC,IAAA,IAASI,CAAAA,CAAOqC,CAAAA,CAAU,CAAA,CAAGrC,CAAAA,CAAOJ,CAAAA,CAAQ,GAAA,CAAI,IAAI,IAAA,CAAMI,CAAAA,EAAAA,CACtD,GAAIgC,CAAAA,CAAeX,CAAAA,CAAW,KAAA,CAAMrB,CAAAA,CAAO,CAAC,CAAA,EAAK,EAAE,CAAA,CAAG,CAClDsC,CAAAA,CAAKtC,CAAAA,CAAO,CAAA,CACZ,KACJ,CAGJ,OAAO,CACH,IAAA,CAAMqC,CAAAA,CACN,EAAA,CAAAC,CACJ,CACJ,CC/KA,IAAMC,CAAAA,CAAN,cAAqChF,CAAmC,CAC3D,IAAA,CAAO,0BAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,IAAA,CAAM,CACF,WAAA,CAAa,4DAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,UACd,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,YAAA,CAAcG,CAAAA,CAAQ,CAClB,OAAA,CAAS,uDAAA,CACT,GAAA,CAAK,sGAAA,CACL,GAAA,CAAK,iFACT,CAAC,CACL,CACJ,CAAA,CAEA,OAAOF,CAAAA,CAAqF,CACxF,OAAO,CACH,gBAAA,CAAiBO,CAAAA,CAAM,CACdkB,EAAAA,CAAkBlB,CAAI,CAAA,GACvB+D,CAAAA,CAAgBtE,CAAAA,CAAQ,UAAA,CAAYO,CAAAA,CAAK,MAAM,CAAA,EAEnDP,EAAQ,MAAA,CAAO,CAAE,IAAA,CAAMO,CAAAA,CAAK,EAAA,EAAMA,CAAAA,CAAM,SAAA,CAAW,cAAe,CAAC,CAAA,EACvE,CACJ,CACJ,CACJ,CAAA,CAEOyE,EAAAA,CAAQ,IAAID,EClCnB,IAAME,CAAAA,CAAN,cAAoClF,CAAmC,CAC1D,IAAA,CAAO,yBAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,IAAA,CAAM,CACF,YAAa,2DAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,UACd,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,YAAA,CAAcG,CAAAA,CAAQ,CAClB,OAAA,CAAS,sDAAA,CACT,IAAK,iHAAA,CACL,GAAA,CAAK,2EACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAAqF,CACxF,OAAO,CACH,gBAAA,CAAiBO,CAAAA,CAAM,CACdD,EAAAA,CAAiBC,CAAI,CAAA,GACtB+D,CAAAA,CAAgBtE,CAAAA,CAAQ,UAAA,CAAYO,CAAAA,CAAK,MAAM,CAAA,EAEnDP,CAAAA,CAAQ,MAAA,CAAO,CAAE,IAAA,CAAMO,CAAAA,CAAK,EAAA,EAAMA,CAAAA,CAAM,SAAA,CAAW,cAAe,CAAC,CAAA,EACvE,CACJ,CACJ,CACJ,CAAA,CAEO2E,EAAAA,CAAQ,IAAID,CAAAA,CC3CnB,SAASE,EAAAA,CAAaC,CAAAA,CAAsB,CACxC,IAAMC,CAAAA,CAAaD,CAAAA,CAAK,OAAA,CAAQ,KAAA,CAAO,GAAG,CAAA,CACtCE,CAAAA,CAAU,GAAA,CAEd,IAAA,IAASzC,CAAAA,CAAQ,CAAA,CAAGA,CAAAA,CAAQwC,CAAAA,CAAW,MAAA,CAAQxC,CAAAA,EAAAA,CAAS,CACpD,IAAMX,CAAAA,CAAOmD,CAAAA,CAAWxC,CAAK,CAAA,CAC7B,GAAIX,CAAAA,GAAS,MAAA,CAAW,MAEpBA,CAAAA,GAAS,GAAA,CACLmD,CAAAA,CAAWxC,CAAAA,CAAQ,CAAC,CAAA,GAAM,GAAA,EAC1ByC,CAAAA,EAAW,IAAA,CACXzC,CAAAA,EAAAA,CAGIwC,CAAAA,CAAWxC,EAAQ,CAAC,CAAA,GAAM,GAAA,EAAKA,CAAAA,EAAAA,EAEnCyC,CAAAA,EAAW,OAAA,CAER,gBAAA,CAAiB,QAAA,CAASpD,CAAI,CAAA,CACrCoD,CAAAA,EAAW,CAAA,EAAA,EAAKpD,CAAI,CAAA,CAAA,CAEpBoD,CAAAA,EAAWpD,EAEnB,CAEA,OAAO,IAAI,MAAA,CAAO,CAAA,EAAGoD,CAAO,CAAA,CAAA,CAAG,CACnC,CASO,SAASC,CAAAA,CAAYC,CAAAA,CAAkBC,CAAAA,CAA6B,CACvE,IAAMC,CAAAA,CAAOF,CAAAA,CAAS,QAAQ,KAAA,CAAO,GAAG,CAAA,CAExC,OAAOC,CAAAA,CAAS,IAAA,CAAKH,CAAAA,EAAWH,EAAAA,CAAaG,CAAO,CAAA,CAAE,IAAA,CAAKI,CAAI,CAAC,CACpE,CC7BA,IAAMC,EAAN,cAAsC5F,CAAmC,CAC5D,IAAA,CAAO,2BAAA,CAEP,cAAA,CAA0B,CAAC,CAAE,OAAA,CAAS,EAAG,CAAC,CAAA,CAE1C,IAAA,CAAO,CACZ,IAAA,CAAM,aACN,IAAA,CAAM,CACF,WAAA,CAAa,sFAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,UACd,CAAA,CACA,MAAA,CAAQ,CACJ,CACI,IAAA,CAAM,QAAA,CACN,UAAA,CAAY,CACR,QAAS,CACL,IAAA,CAAM,OAAA,CACN,KAAA,CAAO,CAAE,IAAA,CAAM,QAAS,CAC5B,CACJ,CAAA,CACA,oBAAA,CAAsB,KAC1B,CACJ,CAAA,CACA,QAAA,CAAU,CACN,OAAA,CAASG,CAAAA,CAAQ,CACb,OAAA,CAAS,qDAAA,CACT,GAAA,CAAK,mHAAA,CACL,GAAA,CAAK,gEACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAA8DC,CAAAA,CAAyC,CAC1G,IAAM2F,CAAAA,CAAU3F,CAAAA,CAAQ,CAAC,CAAA,EAAG,OAAA,EAAW,EAAC,CACxC,GAAI2F,CAAAA,CAAQ,MAAA,CAAS,CAAA,EAAKL,CAAAA,CAAYvF,CAAAA,CAAQ,QAAA,CAAU4F,CAAO,EAC3D,OAAO,EAAC,CASZ,IAAMC,CAAAA,CAAatF,CAAAA,EACXA,CAAAA,CAAK,IAAA,GAAS,YAAA,CAAqBA,CAAAA,CAAK,IAAA,GAAS,SAAA,CAEjDA,CAAAA,CAAK,IAAA,GAAS,kBAAA,EACdA,CAAAA,CAAK,SAAS,IAAA,GAAS,YAAA,EACvBA,CAAAA,CAAK,QAAA,CAAS,IAAA,GAAS,SAAA,CAI/B,OAAO,CACH,cAAA,CAAeA,CAAAA,CAAM,CACbA,CAAAA,CAAK,MAAA,CAAO,IAAA,GAAS,kBAAA,EAAsBA,CAAAA,CAAK,OAAO,QAAA,CAAS,IAAA,GAAS,YAAA,EACzE,CAACX,CAAAA,CAAU,OAAA,CAAQ,aAAA,CAAc,GAAA,CAAIW,CAAAA,CAAK,MAAA,CAAO,QAAA,CAAS,IAAI,CAAA,EAAK,CAACsF,CAAAA,CAAUtF,CAAAA,CAAK,OAAO,MAAM,CAAA,EAGpGP,CAAAA,CAAQ,MAAA,CAAO,CACX,IAAA,CAAMO,CAAAA,CAAK,MAAA,CAAO,QAAA,CAClB,SAAA,CAAW,SAAA,CACX,IAAA,CAAM,CACF,MAAA,CAAQA,CAAAA,CAAK,MAAA,CAAO,SAAS,IACjC,CACJ,CAAC,EACL,CACJ,CACJ,CACJ,CAAA,CAEOuF,EAAAA,CAAQ,IAAIH,CAAAA,CC3EnB,IAAMI,CAAAA,CAAN,cAA6BhG,CAAmC,CACnD,KAAO,kBAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,IAAA,CAAM,CACF,WAAA,CAAa,wDAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,MACd,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,MAAA,CAAQG,CAAAA,CAAQ,CACZ,OAAA,CAAS,6CAAA,CACT,GAAA,CAAK,6FAAA,CACL,GAAA,CAAK,0EACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAAqF,CACxF,OAAO,CACH,WAAA,CAAYO,CAAAA,CAAM,CAEVA,CAAAA,CAAK,KAAA,EAAO,IAAA,GAAS,YAAA,GACrBA,CAAAA,CAAK,KAAA,CAAM,OAAS,OAAA,EAAWA,CAAAA,CAAK,KAAA,CAAM,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,EAEjEP,CAAAA,CAAQ,MAAA,CAAO,CACX,IAAA,CAAMO,CAAAA,CAAK,KAAA,CACX,SAAA,CAAW,QAAA,CACX,IAAA,CAAM,CAAE,IAAA,CAAMA,CAAAA,CAAK,KAAA,CAAM,IAAK,CAClC,CAAC,CAAA,EACL,CACJ,CACJ,CACJ,CAAA,CAEOyF,EAAAA,CAAQ,IAAID,CAAAA,CCrCnB,IAAME,CAAAA,CAAN,cAAwClG,CAAmC,CAC9D,IAAA,CAAO,8BAAA,CAEP,cAAA,CAA0B,CAAC,CAAE,GAAA,CAAKH,CAAAA,CAAU,KAAA,CAAM,sBAAuB,CAAC,CAAA,CAE1E,IAAA,CAAO,CACZ,IAAA,CAAM,aACN,IAAA,CAAM,CACF,WAAA,CAAa,6DAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,MACd,CAAA,CACA,MAAA,CAAQ,CACJ,CACI,IAAA,CAAM,QAAA,CACN,UAAA,CAAY,CACR,IAAK,CAAE,IAAA,CAAM,SAAA,CAAW,OAAA,CAAS,CAAE,CACvC,CAAA,CACA,oBAAA,CAAsB,KAC1B,CACJ,CAAA,CACA,QAAA,CAAU,CACN,OAAA,CAASM,CAAAA,CAAQ,CACb,QAAS,oFAAA,CACT,GAAA,CAAK,2JAAA,CACL,GAAA,CAAK,qKACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAA8DC,CAAAA,CAAyC,CAC1G,IAAMiG,CAAAA,CAAMjG,CAAAA,CAAQ,CAAC,CAAA,EAAG,GAAA,EAAOL,CAAAA,CAAU,KAAA,CAAM,sBAAA,CAE/C,OAAO,CACH,OAAA,EAAU,CACN,IAAA,IAAWwC,CAAAA,IAAWpC,CAAAA,CAAQ,UAAA,CAAW,cAAA,EAAe,CAAG,CACvD,GAAI,CAACsD,CAAAA,CAAelB,CAAO,CAAA,CAAG,SAE9B,IAAM+D,CAAAA,CAAS1B,EAAAA,CAAoBrC,CAAO,CAAA,CAAE,MAAA,CACxC+D,CAAAA,EAAUD,CAAAA,EAEdlG,CAAAA,CAAQ,MAAA,CAAO,CACX,GAAA,CAAKoC,CAAAA,CAAQ,GAAA,CACb,SAAA,CAAW,SAAA,CACX,IAAA,CAAM,CAAE,MAAA,CAAA+D,CAAAA,CAAQ,GAAA,CAAAD,CAAI,CACxB,CAAC,EACL,CACJ,CACJ,CACJ,CACJ,CAAA,CAEOE,EAAAA,CAAQ,IAAIH,CAAAA,CCpDnB,IAAMI,CAAAA,CAAN,cAAmCtG,CAAmC,CACzD,IAAA,CAAO,yBAAA,CAEP,cAAA,CAA0B,CAAC,CAAE,GAAA,CAAKH,EAAU,QAAA,CAAS,cAAe,CAAC,CAAA,CAErE,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,IAAA,CAAM,CACF,WAAA,CAAa,6EAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,MACd,EACA,MAAA,CAAQ,CACJ,CACI,IAAA,CAAM,QAAA,CACN,UAAA,CAAY,CACR,GAAA,CAAK,CAAE,IAAA,CAAM,SAAA,CAAW,OAAA,CAAS,CAAE,CACvC,CAAA,CACA,oBAAA,CAAsB,KAC1B,CACJ,CAAA,CACA,QAAA,CAAU,CACN,OAAA,CAASM,CAAAA,CAAQ,CACb,OAAA,CAAS,uFAAA,CACT,GAAA,CAAK,mHAAA,CACL,GAAA,CAAK,yGACT,CAAC,CACL,CACJ,EAEA,MAAA,CAAOF,CAAAA,CAA8DC,CAAAA,CAAyC,CAC1G,IAAMiG,CAAAA,CAAMjG,CAAAA,CAAQ,CAAC,CAAA,EAAG,GAAA,EAAOL,CAAAA,CAAU,QAAA,CAAS,cAAA,CAO5C0G,CAAAA,CAAWC,CAAAA,EACbA,CAAAA,CACK,GAAA,CAAInE,CAAAA,EAAWA,CAAAA,CAAQ,KAAA,CAAM,IAAA,EAAM,CAAA,CACnC,MAAA,CAAOT,CAAAA,EAAQA,CAAAA,GAAS,EAAE,CAAA,CAC1B,IAAA,CAAK,GAAG,CAAA,CAMX6E,CAAAA,CAAUD,GAAkC,CAC9C,GAAIA,CAAAA,CAAI,MAAA,GAAW,CAAA,CAAG,OAEtB,IAAMJ,CAAAA,CAASG,CAAAA,CAAQC,CAAG,CAAA,CAAE,MAAA,CAC5B,GAAIJ,CAAAA,EAAUD,CAAAA,CAAK,OAEnB,IAAMO,CAAAA,CAAQF,CAAAA,CAAI,CAAC,CAAA,CACbG,CAAAA,CAAOH,CAAAA,CAAI,EAAA,CAAG,EAAE,CAAA,CAClBE,CAAAA,GAAU,MAAA,EAAaC,CAAAA,GAAS,MAAA,EAEpC1G,CAAAA,CAAQ,MAAA,CAAO,CACX,IAAK,CAAE,KAAA,CAAOyG,CAAAA,CAAM,GAAA,CAAI,KAAA,CAAO,GAAA,CAAKC,CAAAA,CAAK,GAAA,CAAI,GAAI,CAAA,CACjD,SAAA,CAAW,SAAA,CACX,IAAA,CAAM,CAAE,MAAA,CAAAP,CAAAA,CAAQ,IAAAD,CAAI,CACxB,CAAC,EACL,CAAA,CAEA,OAAO,CACH,OAAA,EAAU,CACN,IAAIK,CAAAA,CAA0B,EAAC,CAE/B,IAAA,IAAWnE,CAAAA,IAAWpC,CAAAA,CAAQ,WAAW,cAAA,EAAe,CAAG,CACvD,IAAM2G,CAAAA,CAAWJ,CAAAA,CAAI,EAAA,CAAG,EAAE,CAAA,CACpBK,CAAAA,CACFD,CAAAA,GAAa,MAAA,EAAavE,CAAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,IAAA,GAASuE,EAAS,GAAA,CAAI,KAAA,CAAM,IAAA,CAAO,CAAA,CAEnF,GAAIvE,CAAAA,CAAQ,IAAA,GAAS,MAAA,EAAUD,CAAAA,CAAmBC,CAAO,CAAA,EAAK,CAACwE,CAAAA,CAAe,CAC1EJ,CAAAA,CAAOD,CAAG,EACVA,CAAAA,CAAMnE,CAAAA,CAAQ,IAAA,GAAS,MAAA,EAAU,CAACD,CAAAA,CAAmBC,CAAO,CAAA,CAAI,CAACA,CAAO,CAAA,CAAI,EAAC,CAC7E,QACJ,CAEAmE,CAAAA,CAAI,KAAKnE,CAAO,EACpB,CAEAoE,CAAAA,CAAOD,CAAG,EACd,CACJ,CACJ,CACJ,CAAA,CAEOM,EAAAA,CAAQ,IAAIR,CAAAA,CC9FZ,SAASS,CAAAA,CAAmBvG,CAAAA,CAA0C,CACzE,IAAMwG,CAAAA,CAAuB,EAAC,CAC1BhG,CAAAA,CAA4BR,CAAAA,CAEhC,OAAa,CACT,GAAIQ,CAAAA,CAAW,IAAA,GAAS,iBAAA,EAAqBA,EAAW,IAAA,GAAS,qBAAA,CAAuB,CACpFA,CAAAA,CAAaA,CAAAA,CAAW,UAAA,CACxB,QACJ,CAEA,GAAIA,CAAAA,CAAW,IAAA,GAAS,kBAAA,CAAoB,CAExC,GADIA,CAAAA,CAAW,QAAA,EACXA,EAAW,QAAA,CAAS,IAAA,GAAS,YAAA,CAAc,OAAO,IAAA,CAEtDgG,CAAAA,CAAW,OAAA,CAAQhG,CAAAA,CAAW,QAAA,CAAS,IAAI,CAAA,CAC3CA,CAAAA,CAAaA,CAAAA,CAAW,MAAA,CACxB,QACJ,CAEA,KACJ,CAEA,OAAIgG,CAAAA,CAAW,MAAA,GAAW,CAAA,CAAU,IAAA,CAChChG,CAAAA,CAAW,IAAA,GAAS,gBAAA,CAAyB,CAAC,MAAA,CAAQ,GAAGgG,CAAU,CAAA,CAAE,IAAA,CAAK,GAAG,EAC7EhG,CAAAA,CAAW,IAAA,GAAS,YAAA,CAAqB,CAACA,CAAAA,CAAW,IAAA,CAAM,GAAGgG,CAAU,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA,CAE/E,IACX,CASO,SAASC,EAAAA,CAAsBzG,EAAoC,CACtE,OAAOuG,CAAAA,CAAmBvG,CAAI,CAAA,GAAM,IACxC,CASO,SAAS0G,CAAAA,CAAaC,CAAAA,CAA6BhD,CAAAA,CAAuB,CAC7E,IAAMiD,CAAAA,CAAWC,QAAAA,CAAS,YAAA,CAAaF,EAAOhD,CAAI,CAAA,CAGlD,GAAIiD,CAAAA,GAAa,IAAA,CAAM,OAAO,MAAA,CAE9B,IAAME,CAAAA,CAAe,IAAI,GAAA,CAAmBF,CAAAA,CAAS,IAAA,CAAK,GAAA,CAAIG,CAAAA,EAAcA,CAAAA,CAAW,IAAI,CAAC,CAAA,CAE5F,OAAOH,CAAAA,CAAS,UAAA,CAAW,IAAA,CAAKI,CAAAA,EAAaA,CAAAA,CAAU,OAAA,EAAQ,EAAK,CAACF,CAAAA,CAAa,GAAA,CAAIE,CAAAA,CAAU,UAAU,CAAC,CAC/G,CASO,SAASC,EAAAA,CAAcC,CAAAA,CAA8B/B,CAAAA,CAAuB,CAC/E,IAAA,IAAWgC,CAAAA,IAAUD,CAAAA,CACjB,GAAI/B,CAAAA,GAASgC,CAAAA,EAAUhC,CAAAA,CAAK,UAAA,CAAW,CAAA,EAAGgC,CAAM,CAAA,CAAA,CAAG,CAAA,CAAG,OAAO,KAAA,CAGjE,OAAO,MACX,CASO,SAASC,EAAAA,CAAerC,CAAAA,CAA0C,CACrE,OAAIA,CAAAA,CAAQ,UAAA,CAAW,MAAA,GAAW,CAAA,CAAU,MAErCA,CAAAA,CAAQ,UAAA,CAAW,KAAA,CACtBsC,CAAAA,EACIA,CAAAA,CAAS,IAAA,GAAS,UAAA,EAClBA,CAAAA,CAAS,SAAA,EACT,CAACA,CAAAA,CAAS,QAAA,EACVA,CAAAA,CAAS,KAAA,CAAM,IAAA,GAAS,YAChC,CACJ,CCrFA,IAAMC,CAAAA,CAAN,cAA+B9H,CAAmC,CACrD,IAAA,CAAO,oBAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,IAAA,CAAM,CACF,WAAA,CAAa,oFAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,MACd,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,KAAA,CAAOG,CAAAA,CAAQ,CACX,OAAA,CAAS,wCACT,GAAA,CAAK,8FAAA,CACL,GAAA,CAAK,kGACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAAqF,CACxF,OAAO,CACH,kBAAA,CAAmBO,CAAAA,CAAM,CACjBA,EAAK,MAAA,CAAO,IAAA,GAAS,qBAAA,EAAyBA,CAAAA,CAAK,MAAA,CAAO,IAAA,GAAS,OAAA,EAGnEA,CAAAA,CAAK,MAAA,CAAO,MAAA,CAAO,IAAA,GAAS,wBAAA,GAE5BA,CAAAA,CAAK,EAAA,CAAG,IAAA,GAAS,YAAA,EAAgBA,CAAAA,CAAK,IAAA,EAAM,IAAA,GAAS,YAAA,EAIrDA,CAAAA,CAAK,EAAA,CAAG,cAAA,GAAmB,MAAA,GAI3B0G,CAAAA,CAAajH,CAAAA,CAAQ,UAAA,CAAW,QAAA,CAASO,CAAI,CAAA,CAAGA,CAAAA,CAAK,IAAA,CAAK,IAAI,CAAA,EAElEP,CAAAA,CAAQ,MAAA,CAAO,CACX,IAAA,CAAAO,CAAAA,CACA,SAAA,CAAW,OAAA,CACX,IAAA,CAAM,CACF,IAAA,CAAMA,CAAAA,CAAK,EAAA,CAAG,IAAA,CACd,MAAA,CAAQA,CAAAA,CAAK,KAAK,IACtB,CACJ,CAAC,CAAA,CAAA,EACL,CACJ,CACJ,CACJ,CAAA,CAEOuH,EAAAA,CAAQ,IAAID,CAAAA,CC/DZ,IAAME,EAAAA,CAA8C,CAEvD,MAAA,CAAQ,OAAA,CACR,QAAS,QAAA,CACT,QAAA,CAAU,SAAA,CACV,SAAA,CAAW,UAAA,CACX,SAAA,CAAW,UAAA,CACX,UAAA,CAAY,WAAA,CACZ,MAAA,CAAQ,OAAA,CACR,OAAA,CAAS,QAAA,CACT,QAAA,CAAU,SAAA,CACV,SAAA,CAAW,WACX,UAAA,CAAY,WAAA,CACZ,SAAA,CAAW,UAAA,CACX,UAAA,CAAY,WAAA,CACZ,OAAA,CAAS,QAAA,CACT,QAAA,CAAU,SAAA,CACV,MAAA,CAAQ,OAAA,CACR,OAAA,CAAS,QAAA,CACT,QAAA,CAAU,SAAA,CACV,UAAW,UAAA,CACX,MAAA,CAAQ,OAAA,CACR,OAAA,CAAS,QAAA,CACT,QAAA,CAAU,SAAA,CACV,SAAA,CAAW,UAAA,CACX,SAAA,CAAW,UAAA,CACX,UAAA,CAAY,WAAA,CACZ,MAAA,CAAQ,OAAA,CACR,OAAA,CAAS,SACT,MAAA,CAAQ,OAAA,CACR,OAAA,CAAS,QAAA,CACT,OAAA,CAAS,QAAA,CACT,QAAA,CAAU,SAAA,CACV,SAAA,CAAW,UAAA,CACX,UAAA,CAAY,WAAA,CACZ,WAAA,CAAa,YAAA,CACb,YAAA,CAAc,aAAA,CAGd,UAAW,WAAA,CACX,UAAA,CAAY,YAAA,CACZ,WAAA,CAAa,aAAA,CACb,aAAA,CAAe,eAAA,CACf,UAAA,CAAY,YAAA,CACZ,WAAA,CAAa,aAAA,CACb,WAAA,CAAa,aAAA,CACb,YAAA,CAAc,cAAA,CACd,cAAA,CAAgB,gBAAA,CAChB,SAAA,CAAW,WAAA,CACX,UAAA,CAAY,YAAA,CACZ,WAAA,CAAa,aAAA,CACb,aAAA,CAAe,eAAA,CACf,QAAA,CAAU,UAAA,CACV,SAAA,CAAW,WAAA,CACX,SAAA,CAAW,WAAA,CACX,UAAA,CAAY,aACZ,YAAA,CAAc,cAAA,CACd,QAAA,CAAU,UAAA,CACV,SAAA,CAAW,WAAA,CACX,UAAA,CAAY,YAAA,CACZ,YAAA,CAAc,cAAA,CACd,SAAA,CAAW,WAAA,CACX,UAAA,CAAY,YAAA,CACZ,WAAA,CAAa,aAAA,CACb,SAAU,UAAA,CACV,SAAA,CAAW,WAAA,CACX,UAAA,CAAY,YAAA,CACZ,WAAA,CAAa,aAAA,CACb,YAAA,CAAc,cAAA,CACd,aAAA,CAAe,eAAA,CACf,eAAA,CAAiB,iBAAA,CACjB,SAAA,CAAW,WAAA,CACX,UAAA,CAAY,aACZ,WAAA,CAAa,aAAA,CACb,aAAA,CAAe,eAAA,CACf,QAAA,CAAU,UAAA,CACV,SAAA,CAAW,WAAA,CACX,UAAA,CAAY,YAAA,CACZ,UAAA,CAAY,YAAA,CACZ,WAAA,CAAa,aAAA,CACb,YAAA,CAAc,cAAA,CACd,WAAY,YAAA,CACZ,WAAA,CAAa,aAAA,CACb,WAAA,CAAa,aAAA,CACb,YAAA,CAAc,cAAA,CACd,cAAA,CAAgB,gBAAA,CAChB,OAAA,CAAS,SAAA,CACT,QAAA,CAAU,UAAA,CACV,QAAA,CAAU,UAAA,CACV,SAAA,CAAW,YACX,WAAA,CAAa,aAAA,CACb,OAAA,CAAS,SAAA,CACT,QAAA,CAAU,UAAA,CACV,QAAA,CAAU,UAAA,CACV,SAAA,CAAW,WAAA,CACX,WAAA,CAAa,aAAA,CACb,SAAA,CAAW,WAAA,CACX,UAAA,CAAY,YAAA,CACZ,WAAY,YAAA,CACZ,WAAA,CAAa,aAAA,CACb,SAAA,CAAW,WAAA,CACX,UAAA,CAAY,YAAA,CACZ,UAAA,CAAY,YAAA,CACZ,WAAA,CAAa,aAAA,CACb,UAAA,CAAY,YAAA,CACZ,WAAA,CAAa,aAAA,CACb,WAAA,CAAa,cACb,YAAA,CAAc,cAAA,CACd,cAAA,CAAgB,gBAAA,CAChB,QAAA,CAAU,UAAA,CACV,SAAA,CAAW,WAAA,CACX,SAAA,CAAW,WAAA,CACX,UAAA,CAAY,YAAA,CACZ,YAAA,CAAc,cAAA,CACd,QAAA,CAAU,UAAA,CACV,UAAW,WAAA,CACX,SAAA,CAAW,WAAA,CACX,UAAA,CAAY,YAAA,CACZ,YAAA,CAAc,cAAA,CACd,UAAA,CAAY,YAAA,CACZ,WAAA,CAAa,aAAA,CACb,WAAA,CAAa,aAAA,CACb,YAAA,CAAc,cAAA,CACd,cAAA,CAAgB,iBAChB,WAAA,CAAa,aAAA,CACb,YAAA,CAAc,cAAA,CACd,YAAA,CAAc,cAAA,CACd,aAAA,CAAe,eAAA,CACf,eAAA,CAAiB,iBAAA,CACjB,SAAA,CAAW,WAAA,CACX,UAAA,CAAY,YAAA,CACZ,UAAA,CAAY,YAAA,CACZ,YAAa,aAAA,CACb,aAAA,CAAe,eAAA,CACf,UAAA,CAAY,YAAA,CACZ,WAAA,CAAa,aAAA,CACb,WAAA,CAAa,aAAA,CACb,YAAA,CAAc,cAAA,CACd,cAAA,CAAgB,gBAAA,CAChB,YAAA,CAAc,cAAA,CACd,aAAA,CAAe,gBACf,aAAA,CAAe,eAAA,CACf,cAAA,CAAgB,gBAAA,CAChB,gBAAA,CAAkB,kBAAA,CAClB,SAAA,CAAW,WAAA,CACX,UAAA,CAAY,YAAA,CACZ,UAAA,CAAY,YAAA,CACZ,WAAA,CAAa,aAAA,CACb,SAAA,CAAW,WAAA,CACX,WAAY,YAAA,CACZ,UAAA,CAAY,YAAA,CACZ,WAAA,CAAa,aAAA,CACb,aAAA,CAAe,eAAA,CAGf,OAAA,CAAS,SAAA,CACT,QAAA,CAAU,UAAA,CACV,QAAA,CAAU,UAAA,CACV,SAAA,CAAW,WAAA,CACX,QAAA,CAAU,WACV,SAAA,CAAW,WAAA,CACX,SAAA,CAAW,WAAA,CACX,UAAA,CAAY,YAAA,CAGZ,MAAA,CAAQ,QAAA,CACR,OAAA,CAAS,UAAA,CACT,OAAA,CAAS,SAAA,CACT,KAAA,CAAO,OAAA,CACP,MAAA,CAAQ,QAAA,CACR,MAAO,OAAA,CACP,MAAA,CAAQ,QAAA,CACR,KAAA,CAAO,OAAA,CACP,MAAA,CAAQ,QAAA,CACR,OAAA,CAAS,SAAA,CACT,QAAA,CAAU,UAAA,CACV,OAAA,CAAS,SAAA,CACT,OAAA,CAAS,SAAA,CACT,QAAA,CAAU,WAGV,OAAA,CAAS,SAAA,CACT,OAAA,CAAS,SAAA,CACT,OAAA,CAAS,SAAA,CACT,QAAA,CAAU,UAAA,CACV,QAAA,CAAU,UAAA,CAGV,SAAA,CAAW,UAAA,CACX,UAAA,CAAY,WAAA,CACZ,QAAA,CAAU,SAAA,CACV,SAAA,CAAW,UAAA,CACX,QAAA,CAAU,SAAA,CACV,SAAA,CAAW,UAAA,CACX,SAAA,CAAW,UAAA,CACX,UAAA,CAAY,WAAA,CACZ,SAAA,CAAW,UAAA,CACX,UAAA,CAAY,WAAA,CACZ,OAAA,CAAS,QAAA,CACT,SAAU,SAAA,CACV,UAAA,CAAY,WAAA,CACZ,UAAA,CAAY,WAAA,CAGZ,MAAA,CAAQ,SAAA,CACR,OAAA,CAAS,UAAA,CACT,UAAA,CAAY,aAAA,CACZ,KAAA,CAAO,QAAA,CACP,MAAA,CAAQ,SAAA,CACR,SAAA,CAAW,aACX,UAAA,CAAY,aAAA,CACZ,OAAA,CAAS,UAAA,CACT,MAAA,CAAQ,SAAA,CAGR,QAAA,CAAU,QAAA,CACV,SAAA,CAAW,SAAA,CACX,SAAA,CAAW,SAAA,CACX,UAAA,CAAY,UAAA,CACZ,QAAA,CAAU,QAAA,CACV,UAAW,SAAA,CAGX,IAAA,CAAM,MAAA,CACN,QAAA,CAAU,UAAA,CACV,SAAA,CAAW,WAAA,CACX,OAAA,CAAS,SAAA,CACT,SAAA,CAAW,WAAA,CACX,SAAA,CAAW,SAAA,CACX,UAAA,CAAY,UAAA,CACZ,OAAA,CAAS,UACT,SAAA,CAAW,WAAA,CACX,SAAA,CAAW,UAAA,CACX,IAAA,CAAM,MAAA,CACN,KAAA,CAAO,OACX,CAAA,CCvOO,SAASC,EAAAA,CACZ1F,CAAAA,CACA2F,CAAAA,CACAC,CAAAA,CACsB,CAMtB,IAAMC,EAAqC,MAAA,CAAO,MAAA,CAAO,IAAI,CAAA,CAE7D,IAAA,GAAW,CAACC,CAAAA,CAAKC,CAAK,CAAA,GAAK,MAAA,CAAO,OAAA,CAAQ/F,CAAI,CAAA,CAC1C6F,CAAAA,CAAWC,CAAAA,CAAI,WAAA,EAAa,CAAA,CAAIC,CAAAA,CAGpC,IAAA,GAAW,CAACD,CAAAA,CAAKC,CAAK,CAAA,GAAK,MAAA,CAAO,OAAA,CAAQJ,CAAK,CAAA,CAC3CE,CAAAA,CAAWC,CAAAA,CAAI,WAAA,EAAa,CAAA,CAAIC,EAGpC,IAAA,IAAWD,CAAAA,IAAOF,CAAAA,CACd,OAAOC,CAAAA,CAAWC,CAAAA,CAAI,WAAA,EAAa,CAAA,CAGvC,OAAOD,CACX,CClBA,IAAMG,CAAAA,CAAN,cAA+BvI,CAAmC,CACrD,IAAA,CAAO,oBAAA,CAEP,cAAA,CAA0B,CAAC,CAAE,KAAA,CAAO,EAAC,CAAG,MAAA,CAAQ,EAAG,CAAC,CAAA,CAEpD,IAAA,CAAO,CACZ,KAAM,YAAA,CACN,IAAA,CAAM,CACF,WAAA,CAAa,iEAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,MACd,CAAA,CACA,OAAA,CAAS,MAAA,CACT,MAAA,CAAQ,CACJ,CACI,IAAA,CAAM,SACN,UAAA,CAAY,CACR,KAAA,CAAO,CACH,IAAA,CAAM,QAAA,CACN,oBAAA,CAAsB,CAAE,IAAA,CAAM,QAAS,CAC3C,CAAA,CACA,MAAA,CAAQ,CACJ,IAAA,CAAM,OAAA,CACN,MAAO,CAAE,IAAA,CAAM,QAAS,CAC5B,CACJ,CAAA,CACA,oBAAA,CAAsB,KAC1B,CACJ,CAAA,CACA,QAAA,CAAU,CACN,OAAA,CAASG,CAAAA,CAAQ,CACb,OAAA,CAAS,uEACT,GAAA,CAAK,8EAAA,CACL,GAAA,CAAK,4BACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAA8DC,CAAAA,CAAyC,CAC1G,IAAMkI,CAAAA,CAAaH,EAAAA,CAAgBD,EAAAA,CAAqB9H,EAAQ,CAAC,CAAA,EAAG,KAAA,EAAS,EAAC,CAAGA,CAAAA,CAAQ,CAAC,CAAA,EAAG,MAAA,EAAU,EAAE,CAAA,CAEzG,OAAO,CACH,UAAA,CAAWM,CAAAA,CAAM,CAGb,GAAI,EAAAA,CAAAA,CAAK,MAAA,CAAO,IAAA,GAAS,kBAAA,EAAsBA,CAAAA,CAAK,MAAA,CAAO,QAAA,GAAaA,CAAAA,EAAQ,CAACA,CAAAA,CAAK,MAAA,CAAO,QAAA,CAAA,CAI7F,IAAA,IAAWgI,CAAAA,IAAQ7G,EAAanB,CAAAA,CAAK,IAAI,CAAA,CAAG,CACxC,IAAMiI,CAAAA,CAAWL,CAAAA,CAAWI,CAAAA,CAAK,IAAA,CAAK,WAAA,EAAa,CAAA,CAC/CC,CAAAA,GAAa,MAAA,EAEjBxI,CAAAA,CAAQ,MAAA,CAAO,CACX,IAAA,CAAAO,CAAAA,CACA,SAAA,CAAW,SAAA,CACX,IAAA,CAAM,CAAE,OAAA,CAASgI,CAAAA,CAAK,IAAA,CAAM,QAAA,CAAUzG,CAAAA,CAAUyG,CAAAA,CAAK,IAAA,CAAMC,CAAQ,CAAE,CACzE,CAAC,EACL,CACJ,CAAA,CACA,OAAA,EAAU,CACN,IAAA,IAAWpG,CAAAA,IAAWpC,CAAAA,CAAQ,UAAA,CAAW,cAAA,EAAe,CACpD,IAAA,IAAWuI,CAAAA,IAAQ7G,CAAAA,CAAaU,CAAAA,CAAQ,KAAK,CAAA,CAAG,CAC5C,IAAMoG,CAAAA,CAAWL,CAAAA,CAAWI,CAAAA,CAAK,IAAA,CAAK,WAAA,EAAa,CAAA,CACnD,GAAIC,CAAAA,GAAa,MAAA,CAAW,SAE5B,IAAMC,CAAAA,CAAQ3G,EAAUyG,CAAAA,CAAK,IAAA,CAAMC,CAAQ,CAAA,CAGrCE,CAAAA,CAAOtG,CAAAA,CAAQ,KAAA,CAAM,CAAC,CAAA,CAAI,CAAA,CAAImG,CAAAA,CAAK,KAAA,CACnCzD,CAAAA,CAAK4D,CAAAA,CAAOH,CAAAA,CAAK,IAAA,CAAK,OAE5BvI,CAAAA,CAAQ,MAAA,CAAO,CACX,GAAA,CAAK,CACD,KAAA,CAAOA,CAAAA,CAAQ,UAAA,CAAW,eAAA,CAAgB0I,CAAI,CAAA,CAC9C,GAAA,CAAK1I,CAAAA,CAAQ,UAAA,CAAW,eAAA,CAAgB8E,CAAE,CAC9C,CAAA,CACA,SAAA,CAAW,SAAA,CACX,IAAA,CAAM,CAAE,OAAA,CAASyD,CAAAA,CAAK,IAAA,CAAM,QAAA,CAAUE,CAAM,CAAA,CAC5C,GAAA,CAAKE,CAAAA,EAASA,CAAAA,CAAM,gBAAA,CAAiB,CAACD,EAAM5D,CAAE,CAAA,CAAG2D,CAAK,CAC1D,CAAC,EACL,CAER,CACJ,CACJ,CACJ,CAAA,CAEOG,EAAAA,CAAQ,IAAIN,CAAAA,CChGZ,SAASO,EAAAA,CAAwBrG,EAAuB,CAC3D,IAAMmC,CAAAA,CAAUnC,CAAAA,CAAK,OAAA,CAAQ,YAAA,CAAc,EAAE,CAAA,CAAE,OAAA,EAAQ,CACvD,OAAImC,CAAAA,CAAQ,MAAA,GAAW,CAAA,CAAU,KAAA,CAG7B/E,CAAAA,CAAU,SAAS,WAAA,CAAY,IAAA,CAAK+E,CAAO,CAAA,EAC3C/E,CAAAA,CAAU,QAAA,CAAS,cAAA,CAAe,IAAA,CAAK+E,CAAO,CAAA,EAC9C/E,CAAAA,CAAU,QAAA,CAAS,aAAA,CAAc,IAAA,CAAK+E,CAAO,CAErD,CCFA,IAAMmE,CAAAA,CAAN,cAA4C/I,CAAmC,CAClE,IAAA,CAAO,kCAAA,CAEP,cAAA,CAA0B,CAAC,CAAE,OAAA,CAAS,EAAG,CAAC,CAAA,CAE1C,IAAA,CAAO,CACZ,IAAA,CAAM,QAAA,CACN,IAAA,CAAM,CACF,WAAA,CAAa,yFAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,MACd,CAAA,CACA,MAAA,CAAQ,CACJ,CACI,IAAA,CAAM,QAAA,CACN,WAAY,CACR,OAAA,CAAS,CACL,IAAA,CAAM,OAAA,CACN,KAAA,CAAO,CAAE,IAAA,CAAM,QAAS,CAC5B,CACJ,CAAA,CACA,oBAAA,CAAsB,KAC1B,CACJ,CAAA,CACA,SAAU,CACN,UAAA,CAAYG,CAAAA,CAAQ,CAChB,OAAA,CAAS,2CAAA,CACT,GAAA,CAAK,0GAAA,CACL,GAAA,CAAK,yFACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAA8DC,EAAyC,CAC1G,IAAM2F,CAAAA,CAAU3F,CAAAA,CAAQ,CAAC,CAAA,EAAG,OAAA,EAAW,EAAC,CACxC,OAAI2F,CAAAA,CAAQ,MAAA,CAAS,CAAA,EAAKL,CAAAA,CAAYvF,CAAAA,CAAQ,QAAA,CAAU4F,CAAO,CAAA,CACpD,EAAC,CAGL,CACH,OAAA,EAAU,CACN,IAAA,IAAWxD,CAAAA,IAAWpC,CAAAA,CAAQ,UAAA,CAAW,cAAA,EAAe,CAAG,CACvD,IAAM+I,CAAAA,CAAQ3G,CAAAA,CAAQ,MAAM,KAAA,CAAM;AAAA,CAAI,CAAA,CAEtC,IAAA,IAASS,CAAAA,CAAQ,CAAA,CAAGA,CAAAA,CAAQkG,CAAAA,CAAM,MAAA,CAAQlG,CAAAA,EAAAA,CAAS,CAC/C,IAAML,CAAAA,CAAOuG,CAAAA,CAAMlG,CAAK,CAAA,CACxB,GAAIL,CAAAA,GAAS,MAAA,EAAa,CAACqG,EAAAA,CAAwBrG,CAAI,CAAA,CAAG,SAE1D,IAAMwG,CAAAA,CAAe5G,CAAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,IAAA,CAAOS,EACxCd,CAAAA,CAAS/B,CAAAA,CAAQ,UAAA,CAAW,KAAA,CAAMgJ,CAAAA,CAAe,CAAC,CAAA,EAAK,EAAA,CAE7DhJ,CAAAA,CAAQ,MAAA,CAAO,CACX,GAAA,CAAK,CACD,KAAA,CAAO,CAAE,IAAA,CAAMgJ,EAAc,MAAA,CAAQ,CAAE,CAAA,CACvC,GAAA,CAAK,CAAE,IAAA,CAAMA,CAAAA,CAAc,MAAA,CAAQjH,CAAAA,CAAO,MAAO,CACrD,CAAA,CACA,SAAA,CAAW,YACf,CAAC,EACL,CACJ,CACJ,CACJ,CACJ,CACJ,CAAA,CAEOkH,EAAAA,CAAQ,IAAIH,CAAAA,CCpEnB,IAAMI,EAAAA,CAAuD,CACzD,OAAA,CAAS,QAAA,CACT,SAAA,CAAW,UAAA,CACX,GAAA,CAAK,SACT,CAAA,CAUO,SAASC,CAAAA,CACZtF,CAAAA,CACAuF,CAAAA,CACkB,CAClB,IAAMC,CAAAA,CAAY,IAAI,GAAA,CAAID,CAAK,CAAA,CACzBE,CAAAA,CAA6B,EAAC,CACpC,GAAID,CAAAA,CAAU,IAAA,GAAS,CAAA,CAAG,OAAOC,CAAAA,CAEjC,IAAMC,CAAAA,CAAa,IAAI,GAAA,CAAI,CAAC,GAAGF,CAAS,CAAA,CAAE,GAAA,CAAIG,CAAAA,EAAYN,EAAAA,CAAYM,CAAQ,CAAC,CAAA,CAAE,MAAA,CAAOC,CAAAA,EAAQA,CAAAA,GAAS,MAAS,CAAC,CAAA,CAEnH,IAAA,IAAWC,CAAAA,IAAS7F,CAAAA,CAAW,GAAA,CAAI,MAAA,EAAU,EAAC,CACtC0F,CAAAA,CAAW,IAAIG,CAAAA,CAAM,IAAI,CAAA,EAAGJ,CAAAA,CAAO,IAAA,CAAKI,CAAAA,CAAM,KAAK,CAAA,CAG3D,GAAIL,CAAAA,CAAU,GAAA,CAAI,UAAU,CAAA,CACxB,IAAA,IAAWjH,CAAAA,IAAWyB,CAAAA,CAAW,cAAA,EAAe,CAC5CyF,CAAAA,CAAO,IAAA,CAAKlH,CAAAA,CAAQ,KAAK,CAAA,CAIjC,OAAOkH,CACX,CAQO,SAASK,CAAAA,CAAa9G,CAAAA,CAAeyG,CAAAA,CAAqC,CAC7E,OAAOA,EAAO,IAAA,CAAK,CAAC,CAACM,CAAAA,CAAOC,CAAG,CAAA,GAAMhH,CAAAA,EAAS+G,CAAAA,EAAS/G,CAAAA,CAAQgH,CAAG,CACtE,CC3CA,IAAMC,CAAAA,CAAN,cAAuB/J,CAAmC,CAC7C,IAAA,CAAO,YAAA,CAEP,cAAA,CAA0B,CAAC,CAAE,KAAA,CAAO,EAAG,CAAC,CAAA,CAExC,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,IAAA,CAAM,CACF,YAAa,iEAAA,CACb,WAAA,CAAa,IACjB,CAAA,CACA,MAAA,CAAQ,CACJ,CACI,IAAA,CAAM,QAAA,CACN,UAAA,CAAY,CACR,KAAA,CAAO,CACH,IAAA,CAAM,OAAA,CACN,KAAA,CAAO,CACH,IAAA,CAAM,QAAA,CACN,IAAA,CAAM,CAAC,SAAA,CAAW,WAAA,CAAa,KAAA,CAAO,UAAU,CACpD,CACJ,CACJ,CAAA,CACA,oBAAA,CAAsB,KAC1B,CACJ,EACA,QAAA,CAAU,CACN,MAAA,CAAQG,CAAAA,CAAQ,CACZ,OAAA,CAAS,sCAAA,CACT,GAAA,CAAK,qGAAA,CACL,GAAA,CAAK,+KACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,EAA8DC,CAAAA,CAAyC,CAC1G,OAAO,CACH,OAAA,EAAU,CACN,IAAM0B,CAAAA,CAAO3B,CAAAA,CAAQ,UAAA,CAAW,OAAA,EAAQ,CAClCsJ,CAAAA,CAASH,CAAAA,CAAcnJ,CAAAA,CAAQ,UAAA,CAAYC,EAAQ,CAAC,CAAA,EAAG,KAAA,EAAS,EAAE,CAAA,CAIxE,IAAA,IAAS4C,CAAAA,CAAQ,CAAA,CAAGA,CAAAA,CAAQlB,CAAAA,CAAK,MAAA,CAAQkB,CAAAA,EAAAA,CACjClB,CAAAA,CAAKkB,CAAK,CAAA,GAAMjD,CAAAA,CAAU,OAAA,GAC1B+J,CAAAA,CAAa9G,CAAAA,CAAOyG,CAAM,CAAA,EAE9BtJ,CAAAA,CAAQ,MAAA,CAAO,CACX,GAAA,CAAK,CACD,KAAA,CAAOA,CAAAA,CAAQ,UAAA,CAAW,eAAA,CAAgB6C,CAAK,EAC/C,GAAA,CAAK7C,CAAAA,CAAQ,UAAA,CAAW,eAAA,CAAgB6C,CAAAA,CAAQ,CAAC,CACrD,CAAA,CACA,SAAA,CAAW,QACf,CAAC,CAAA,EAET,CACJ,CACJ,CACJ,CAAA,CAEOkH,GAAQ,IAAID,CAAAA,CC3DnB,IAAME,CAAAA,CAAN,cAAuBjK,CAAmC,CAC7C,IAAA,CAAO,WAAA,CAEP,cAAA,CAA0B,CAAC,CAAE,KAAA,CAAO,EAAG,CAAC,EAExC,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,IAAA,CAAM,CACF,WAAA,CAAa,mDAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,MACd,CAAA,CACA,MAAA,CAAQ,CACJ,CACI,IAAA,CAAM,QAAA,CACN,UAAA,CAAY,CACR,KAAA,CAAO,CACH,IAAA,CAAM,OAAA,CACN,KAAA,CAAO,CACH,IAAA,CAAM,QAAA,CACN,IAAA,CAAM,CAAC,SAAA,CAAW,WAAA,CAAa,MAAO,UAAU,CACpD,CACJ,CACJ,CAAA,CACA,oBAAA,CAAsB,KAC1B,CACJ,CAAA,CACA,QAAA,CAAU,CACN,KAAA,CAAOG,CAAAA,CAAQ,CACX,OAAA,CAAS,6BAAA,CACT,IAAK,qGAAA,CACL,GAAA,CAAK,wGACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAA8DC,CAAAA,CAAyC,CAC1G,OAAO,CACH,OAAA,EAAU,CACN,IAAM0B,EAAO3B,CAAAA,CAAQ,UAAA,CAAW,OAAA,EAAQ,CAClCsJ,CAAAA,CAASH,CAAAA,CAAcnJ,CAAAA,CAAQ,UAAA,CAAYC,CAAAA,CAAQ,CAAC,CAAA,EAAG,KAAA,EAAS,EAAE,CAAA,CAIxE,IAAA,IAAW4B,CAAAA,IAASF,CAAAA,CAAK,QAAA,CAAS/B,CAAAA,CAAU,KAAK,CAAA,CACzC+J,CAAAA,CAAa9H,CAAAA,CAAM,KAAA,CAAOyH,CAAM,CAAA,EAEpCtJ,CAAAA,CAAQ,MAAA,CAAO,CACX,GAAA,CAAK,CACD,MAAOA,CAAAA,CAAQ,UAAA,CAAW,eAAA,CAAgB6B,CAAAA,CAAM,KAAK,CAAA,CACrD,GAAA,CAAK7B,CAAAA,CAAQ,UAAA,CAAW,eAAA,CAAgB6B,CAAAA,CAAM,KAAA,CAAQA,CAAAA,CAAM,CAAC,CAAA,CAAE,MAAM,CACzE,CAAA,CACA,SAAA,CAAW,OAAA,CACX,IAAA,CAAM,CAAE,KAAA,CAAOA,CAAAA,CAAM,CAAC,CAAE,CAC5B,CAAC,EAET,CACJ,CACJ,CACJ,CAAA,CAEOoI,GAAQ,IAAID,CAAAA,CC/DnB,IAAME,CAAAA,CAAN,cAAqCnK,CAAmC,CAC3D,IAAA,CAAO,4BAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,QAAA,CACN,OAAA,CAAS,MAAA,CACT,IAAA,CAAM,CACF,WAAA,CAAa,wEAAA,CACb,WAAA,CAAa,IACjB,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,cAAA,CAAgBG,CAAAA,CAAQ,CACpB,OAAA,CAAS,2CAAA,CACT,GAAA,CAAK,sGAAA,CACL,GAAA,CAAK,uDACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAAqF,CACxF,OAAO,CACH,OAAA,EAAU,CACN,IAAA,IAAWoC,CAAAA,IAAWpC,CAAAA,CAAQ,UAAA,CAAW,cAAA,EAAe,CACpD,GAAKsD,CAAAA,CAAelB,CAAO,CAAA,EAEvBA,CAAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,IAAA,GAASA,CAAAA,CAAQ,GAAA,CAAI,IAAI,IAAA,CAE/C,IAAA,IAASI,CAAAA,CAAOJ,CAAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,IAAA,CAAMI,CAAAA,EAAQJ,CAAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,IAAA,CAAMI,CAAAA,EAAAA,CAAQ,CAC1E,IAAMb,CAAAA,CAAO3B,CAAAA,CAAQ,UAAA,CAAW,KAAA,CAAMwC,CAAAA,CAAO,CAAC,CAAA,CAC9C,GAAIb,CAAAA,GAAS,MAAA,EAAa,CAAC4C,CAAAA,CAAiB5C,CAAI,CAAA,CAAG,SAGnD,IAAIwI,CAAAA,CAAS3H,EACb,KACI2H,CAAAA,CAAS/H,CAAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,IAAA,EACzBmC,CAAAA,CAAiBvE,CAAAA,CAAQ,UAAA,CAAW,KAAA,CAAMmK,CAAM,CAAA,EAAK,EAAE,CAAA,EAEvDA,CAAAA,EAAAA,CAIJ,IAAMC,EAAWpK,CAAAA,CAAQ,UAAA,CAAW,KAAA,CAAMmK,CAAM,CAAA,CAChD,GAAIC,CAAAA,GAAa,MAAA,EAAa5F,CAAAA,CAAe4F,CAAQ,CAAA,CAAG,CACpD,IAAM1B,CAAAA,CAAO1I,CAAAA,CAAQ,UAAA,CAAW,gBAAgB,CAAE,IAAA,CAAAwC,CAAAA,CAAM,MAAA,CAAQ,CAAE,CAAC,CAAA,CAC7DsC,CAAAA,CAAK9E,CAAAA,CAAQ,UAAA,CAAW,eAAA,CAAgB,CAAE,IAAA,CAAMmK,CAAAA,CAAS,CAAA,CAAG,MAAA,CAAQ,CAAE,CAAC,CAAA,CAE7EnK,CAAAA,CAAQ,MAAA,CAAO,CACX,GAAA,CAAK,CACD,KAAA,CAAO,CAAE,IAAA,CAAAwC,CAAAA,CAAM,MAAA,CAAQ,CAAE,CAAA,CACzB,GAAA,CAAK,CAAE,IAAA,CAAM2H,CAAAA,CAAQ,MAAA,CAAQxI,CAAAA,CAAK,MAAO,CAC7C,CAAA,CACA,SAAA,CAAW,gBAAA,CACX,GAAA,CAAKgH,CAAAA,EAASA,CAAAA,CAAM,WAAA,CAAY,CAACD,CAAAA,CAAM5D,CAAE,CAAC,CAC9C,CAAC,EACL,CAEAtC,CAAAA,CAAO2H,EACX,CAER,CACJ,CACJ,CACJ,CAAA,CAEOE,EAAAA,CAAQ,IAAIH,CAAAA,CCtDZ,SAASI,CAAAA,CAAoBC,EAAiC,CACjE,IAAIhK,CAAAA,CAAsBgK,CAAAA,CAG1B,OAAIhK,CAAAA,CAAK,MAAA,CAAO,IAAA,GAAS,UAAA,EAAcA,CAAAA,CAAK,MAAA,CAAO,IAAA,GAAS,kBAAA,CACjDA,CAAAA,CAAK,MAAA,EAGZA,CAAAA,CAAK,MAAA,CAAO,IAAA,GAAS,oBAAA,EAAwBA,CAAAA,CAAK,MAAA,CAAO,MAAA,CAAO,IAAA,GAAS,qBAAA,GACzEA,CAAAA,CAAOA,CAAAA,CAAK,MAAA,CAAO,MAAA,CAAA,CAAA,CAGnBA,CAAAA,CAAK,MAAA,CAAO,IAAA,GAAS,wBAAA,EAA4BA,EAAK,MAAA,CAAO,IAAA,GAAS,0BAAA,IACtEA,CAAAA,CAAOA,CAAAA,CAAK,MAAA,CAAA,CAGTA,CAAAA,CACX,CAOO,SAASiK,EAAAA,CAAWjK,CAAAA,CAA8B,CACrD,OAAOA,CAAAA,CAAK,MAAA,EAAQ,IAAA,GAAS,SACjC,CAsBO,SAASkK,EAAAA,CAAcF,CAAAA,CAAkC,CAC5D,IAAMG,CAAAA,CAAuB,EAAC,CAOxBC,CAAAA,CAAWC,CAAAA,EAA+B,CAC5C,OAAQA,CAAAA,CAAM,IAAA,EACV,KAAK,YAAA,CACDF,CAAAA,CAAK,IAAA,CAAK,CACN,IAAA,CAAM,MAAA,CACN,IAAA,CAAME,CAAAA,CAAM,IAAA,CACZ,IAAA,CAAMA,CACV,CAAC,CAAA,CACD,OACJ,KAAK,mBAAA,CACDD,CAAAA,CAAQC,CAAAA,CAAM,IAAI,CAAA,CAClB,OACJ,KAAK,aAAA,CACDD,CAAAA,CAAQC,CAAAA,CAAM,QAAQ,CAAA,CACtB,OACJ,KAAK,qBAAA,CACDD,CAAAA,CAAQC,CAAAA,CAAM,SAAS,CAAA,CACvB,OACJ,KAAK,eAAA,CAAiB,CAClB,IAAM3G,CAAAA,CAA0B,EAAC,CACjC,IAAA,IAAW2D,CAAAA,IAAYgD,CAAAA,CAAM,UAAA,CACrBhD,CAAAA,CAAS,IAAA,GAAS,aAAA,CACdA,EAAS,QAAA,CAAS,IAAA,GAAS,YAAA,EAC3B3D,CAAAA,CAAM,IAAA,CAAK,CAAE,IAAA,CAAM2D,CAAAA,CAAS,QAAA,CAAS,IAAA,CAAM,IAAA,CAAMA,CAAAA,CAAS,QAAS,CAAC,CAAA,CAEjEA,CAAAA,CAAS,IAAI,IAAA,GAAS,YAAA,EAC7B3D,CAAAA,CAAM,IAAA,CAAK,CAAE,IAAA,CAAM2D,CAAAA,CAAS,GAAA,CAAI,IAAA,CAAM,IAAA,CAAMA,CAAAA,CAAS,GAAI,CAAC,CAAA,CAI9D3D,CAAAA,CAAM,MAAA,CAAS,CAAA,EACfyG,CAAAA,CAAK,IAAA,CAAK,CACN,IAAA,CAAM,QAAA,CACN,KAAA,CAAAzG,CAAAA,CACA,IAAA,CAAM2G,CACV,CAAC,CAAA,CAEL,MACJ,CACA,QACI,MACR,CACJ,CAAA,CAEA,IAAA,IAAWA,CAAAA,IAASL,CAAAA,CAAG,MAAA,CAAQI,CAAAA,CAAQC,CAAK,CAAA,CAE5C,OAAOF,CACX,CAQO,SAASG,EAAAA,CAAkBtK,CAAAA,CAA0C,CAGxE,IAAIS,EAAqCT,CAAAA,CAAK,MAAA,CAE9C,KAAOS,CAAAA,EAAS,CACZ,GAAIpB,CAAAA,CAAU,SAAA,CAAU,UAAA,CAAW,GAAA,CAAIoB,CAAAA,CAAQ,IAAI,CAAA,CAC/C,OAAOA,CAAAA,CAGXA,CAAAA,CAAUA,EAAQ,OACtB,CAEA,OAAO,IACX,CASO,SAAS8J,EAAAA,CAAqBP,CAAAA,CAA2B,CAC5D,OAAOA,CAAAA,CAAG,IAAA,GAAS,yBAAA,EAA6BA,CAAAA,CAAG,MAAA,CAAO,MAAA,GAAW,CAAA,EAAKA,CAAAA,CAAG,IAAA,CAAK,IAAA,GAAS,kBAC/F,CAQO,SAASQ,CAAAA,CAAgBR,CAAAA,CAAsC,CAClE,GAAA,CAAKA,CAAAA,CAAG,IAAA,GAAS,qBAAA,EAAyBA,CAAAA,CAAG,IAAA,GAAS,uBAAyBA,CAAAA,CAAG,EAAA,CAC9E,OAAOA,CAAAA,CAAG,EAAA,CAAG,IAAA,CAGjB,GAAIA,CAAAA,CAAG,MAAA,CAAO,IAAA,GAAS,oBAAA,EAAwBA,CAAAA,CAAG,MAAA,CAAO,EAAA,CAAG,IAAA,GAAS,YAAA,CACjE,OAAOA,CAAAA,CAAG,MAAA,CAAO,EAAA,CAAG,IAI5B,CAUO,SAASS,CAAAA,CAAWzK,CAAAA,CAAqB0K,CAAAA,CAA0BC,CAAAA,CAAqC,CAC3G,GAAI3K,CAAAA,CAAK,IAAA,GAAS,iBAAA,CACd,OAAO2K,EAAU3K,CAAAA,CAAK,QAAQ,CAAA,CAGlC,IAAA,IAAW6H,CAAAA,IAAO6C,CAAAA,CAAY1K,CAAAA,CAAK,IAAI,CAAA,EAAK,EAAC,CAAG,CAC5C,IAAM8H,CAAAA,CAAS9H,CAAAA,CAA4C6H,CAAG,CAAA,CACxD+C,CAAAA,CAAW,KAAA,CAAM,OAAA,CAAQ9C,CAAK,CAAA,CAAIA,CAAAA,CAAQ,CAACA,CAAK,CAAA,CAEtD,IAAA,IAAW+C,CAAAA,IAASD,CAAAA,CAAU,CAC1B,IAAME,CAAAA,CAAYD,EAClB,GAAI,EAAA,CAACC,CAAAA,EAAa,OAAOA,CAAAA,CAAU,IAAA,EAAS,QAAA,CAAA,EACxC,CAAAzL,CAAAA,CAAU,SAAA,CAAU,UAAA,CAAW,GAAA,CAAIyL,CAAAA,CAAU,IAAI,CAAA,EACjDL,CAAAA,CAAWK,EAAWJ,CAAAA,CAAaC,CAAS,CAAA,CAAG,OAAO,KAC9D,CACJ,CAEA,OAAO,MACX,CASO,SAASI,EAAAA,CAAqBf,CAAAA,CAAkBU,CAAAA,CAAmC,CACtF,OAAIV,EAAG,IAAA,GAAS,yBAAA,EAA6BA,CAAAA,CAAG,IAAA,CAAK,IAAA,GAAS,gBAAA,CACnD,IAAA,CAGJS,CAAAA,CAAWT,CAAAA,CAAG,IAAA,CAAMU,CAAAA,CAAaM,CAAAA,EAAYA,CAAAA,GAAa,IAAI,CACzE,CAOO,SAASC,EAAAA,CAAiBC,CAAAA,CAAgD,CAC7E,OAAIA,CAAAA,CAAW,cAAA,CAAe,IAAA,GAAS,eAAA,CAAwB,IAAA,CAG3DA,CAAAA,CAAW,cAAA,CAAe,IAAA,GAAS,iBAAA,EACnCA,CAAAA,CAAW,cAAA,CAAe,QAAA,CAAS,OAAS,YAAA,EAC5CA,CAAAA,CAAW,cAAA,CAAe,QAAA,CAAS,IAAA,GAAS,SAAA,CAGxCA,CAAAA,CAAW,cAAA,CAAe,aAAA,EAAe,MAAA,CAAO,MAAA,GAAW,CAAA,EAC3DA,CAAAA,CAAW,cAAA,CAAe,aAAA,EAAe,MAAA,CAAO,CAAC,CAAA,EAAG,IAAA,GAAS,eAAA,CAI9D,KACX,CASO,SAASC,CAAAA,CAAenB,CAAAA,CAAkBU,CAAAA,CAAmC,CAChF,OAAIV,CAAAA,CAAG,UAAA,CACIiB,EAAAA,CAAiBjB,CAAAA,CAAG,UAAU,EAGlC,CAACe,EAAAA,CAAqBf,CAAAA,CAAIU,CAAW,CAChD,CCrPA,IAAMU,EAAAA,CAAN,cAAmC5L,CAAmC,CACzD,IAAA,CAAO,0BAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,OAAA,CAAS,MAAA,CACT,IAAA,CAAM,CACF,WAAA,CAAa,qEAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,MACd,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,WAAA,CAAaG,CAAAA,CAAQ,CACjB,OAAA,CAAS,oEAAA,CACT,GAAA,CAAK,8FAAA,CACL,GAAA,CAAK,2BACT,CAAC,CACL,CACJ,CAAA,CAEA,OAAOF,CAAAA,CAAqF,CAMxF,IAAM4L,CAAAA,CAAQ,CAACrB,CAAAA,CAAkBsB,CAAAA,GAAgC,CAC7D,IAAMC,CAAAA,CAAQ9L,CAAAA,CAAQ,UAAA,CAAW,iBAAA,CAAkB6L,CAAM,CAAA,CAAE,EAAA,CAAG,EAAE,CAAA,CAChE,GAAIC,CAAAA,GAAU,MAAA,EAAa,CAACxI,CAAAA,CAAewI,CAAK,CAAA,CAAG,OAEnD,IAAMC,CAAAA,CAAQnH,EAAAA,CAAsB5E,CAAAA,CAAQ,UAAA,CAAY8L,CAAK,CAAA,CAE7D,GADIC,CAAAA,GAAU,IAAA,EACV,CAACL,CAAAA,CAAenB,CAAAA,CAAIvK,CAAAA,CAAQ,UAAA,CAAW,WAAW,CAAA,CAAG,OAEzD,IAAM0I,CAAAA,CAAO1I,CAAAA,CAAQ,UAAA,CAAW,eAAA,CAAgB,CAAE,IAAA,CAAM+L,CAAAA,CAAM,IAAA,CAAM,MAAA,CAAQ,CAAE,CAAC,CAAA,CACzEjH,CAAAA,CAAK9E,CAAAA,CAAQ,UAAA,CAAW,eAAA,CAAgB,CAAE,IAAA,CAAM+L,CAAAA,CAAM,EAAA,CAAK,CAAA,CAAG,OAAQ,CAAE,CAAC,CAAA,CAE/E/L,CAAAA,CAAQ,MAAA,CAAO,CACX,GAAA,CAAK,CACD,KAAA,CAAO,CAAE,IAAA,CAAM+L,CAAAA,CAAM,IAAA,CAAM,MAAA,CAAQ,CAAE,CAAA,CACrC,IAAK,CAAE,IAAA,CAAMA,CAAAA,CAAM,EAAA,CAAI,MAAA,CAAA,CAAS/L,CAAAA,CAAQ,UAAA,CAAW,KAAA,CAAM+L,CAAAA,CAAM,EAAA,CAAK,CAAC,CAAA,EAAK,EAAA,EAAI,MAAO,CACzF,CAAA,CACA,SAAA,CAAW,aAAA,CACX,GAAA,CAAKpD,CAAAA,EAASA,CAAAA,CAAM,WAAA,CAAY,CAACD,CAAAA,CAAM5D,CAAE,CAAC,CAC9C,CAAC,EACL,CAAA,CAEA,OAAO,CACH,oBAAoBvE,CAAAA,CAAM,CACtBqL,CAAAA,CAAMrL,CAAAA,CAAM+J,CAAAA,CAAoB/J,CAAI,CAAC,EACzC,CAAA,CACA,kBAAA,CAAmBA,CAAAA,CAAM,CAAA,CACjBA,CAAAA,CAAK,IAAA,EAAM,IAAA,GAAS,yBAAA,EAA6BA,EAAK,IAAA,EAAM,IAAA,GAAS,oBAAA,GACrEqL,CAAAA,CAAMrL,CAAAA,CAAK,IAAA,CAAM+J,CAAAA,CAAoB/J,CAAAA,CAAK,IAAI,CAAC,EAEvD,CAAA,CACA,gBAAA,CAAiBA,CAAAA,CAAM,CACfA,CAAAA,CAAK,MAAM,IAAA,GAAS,oBAAA,EACpBqL,CAAAA,CAAMrL,CAAAA,CAAK,KAAA,CAAOA,CAAI,EAE9B,CACJ,CACJ,CACJ,CAAA,CAEOyL,EAAAA,CAAQ,IAAIL,EAAAA,CCrEnB,IAAMM,EAAAA,CAAN,cAAqClM,CAAmC,CAC3D,IAAA,CAAO,2BAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,OAAA,CAAS,MAAA,CACT,IAAA,CAAM,CACF,YAAa,kFAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,MACd,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,SAAA,CAAWG,CAAAA,CAAQ,CACf,OAAA,CAAS,kDAAA,CACT,IAAK,kIAAA,CACL,GAAA,CAAK,8CACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAAqF,CACxF,OAAO,CACH,OAAA,EAAU,CACN,IAAA,IAAWoC,CAAAA,IAAWpC,EAAQ,UAAA,CAAW,cAAA,EAAe,CAGpD,GAAI,EAAAoC,CAAAA,CAAQ,IAAA,GAAS,MAAA,EAAUD,CAAAA,CAAmBC,CAAO,CAAA,CAAA,CAEzD,IAAA,IAAW8J,CAAAA,IAAQlJ,EAAAA,CAAkBZ,CAAO,CAAA,CACxCpC,CAAAA,CAAQ,MAAA,CAAO,CACX,GAAA,CAAK,CACD,KAAA,CAAOA,CAAAA,CAAQ,UAAA,CAAW,eAAA,CAAgBkM,CAAAA,CAAK,KAAK,CAAA,CACpD,GAAA,CAAKlM,CAAAA,CAAQ,UAAA,CAAW,eAAA,CAAgBkM,EAAK,GAAA,CAAM,CAAC,CACxD,CAAA,CACA,SAAA,CAAW,WAAA,CACX,IAAA,CAAM,CAAE,IAAA,CAAMA,CAAAA,CAAK,IAAK,CAAA,CACxB,GAAA,CAAKvD,CAAAA,EAAS,CACVA,CAAAA,CAAM,iBAAiB,CAACuD,CAAAA,CAAK,KAAA,CAAOA,CAAAA,CAAK,KAAA,CAAQ,CAAC,CAAA,CAAG,GAAG,CAAA,CACxDvD,CAAAA,CAAM,gBAAA,CAAiB,CAACuD,CAAAA,CAAK,GAAA,CAAKA,CAAAA,CAAK,GAAA,CAAM,CAAC,CAAA,CAAG,GAAG,CACxD,CACJ,CAAC,EAGb,CACJ,CACJ,CACJ,CAAA,CAEOC,EAAAA,CAAQ,IAAIF,EAAAA,CCnDnB,IAAMG,EAAAA,CAAN,cAAkCrM,CAAmC,CACxD,IAAA,CAAO,wBAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,QAAA,CACN,OAAA,CAAS,MAAA,CACT,IAAA,CAAM,CACF,WAAA,CAAa,+FACb,WAAA,CAAa,IACjB,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,MAAA,CAAQG,CAAAA,CAAQ,CACZ,OAAA,CAAS,uCAAA,CACT,GAAA,CAAK,gKAAA,CACL,GAAA,CAAK,+CACT,CAAC,CAAA,CACD,QAAA,CAAUA,CAAAA,CAAQ,CACd,OAAA,CAAS,8DAAA,CACT,GAAA,CAAK,gJAAA,CACL,GAAA,CAAK,2IACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,EAAqF,CACxF,OAAO,CACH,OAAA,EAAU,CACN,IAAA,IAAWoC,CAAAA,IAAWpC,CAAAA,CAAQ,UAAA,CAAW,cAAA,EAAe,CACpD,GAAIoC,CAAAA,CAAQ,IAAA,GAAS,MAAA,CAErB,IAAA,IAAWiK,CAAAA,IAAU3J,EAAAA,CAAiBN,CAAO,CAAA,CAAG,CAC5C,IAAMkK,CAAAA,CAAM,CACR,KAAA,CAAOtM,CAAAA,CAAQ,UAAA,CAAW,eAAA,CAAgBqM,CAAAA,CAAO,KAAK,CAAA,CACtD,GAAA,CAAKrM,EAAQ,UAAA,CAAW,eAAA,CAAgBqM,CAAAA,CAAO,KAAA,CAAQ,CAAC,CAC5D,CAAA,CAIA,GAAIA,CAAAA,CAAO,QAAA,CAAU,CACjBrM,CAAAA,CAAQ,MAAA,CAAO,CACX,GAAA,CAAAsM,CAAAA,CACA,UAAW,QAAA,CACX,GAAA,CAAK3D,CAAAA,EAASA,CAAAA,CAAM,WAAA,CAAY,CAAC0D,CAAAA,CAAO,KAAA,CAAOA,CAAAA,CAAO,KAAA,CAAQ,CAAC,CAAC,CACpE,CAAC,CAAA,CAED,QACJ,CAKArM,CAAAA,CAAQ,MAAA,CAAO,CAAE,GAAA,CAAAsM,CAAAA,CAAK,SAAA,CAAW,UAAW,CAAC,EACjD,CAER,CACJ,CACJ,CACJ,CAAA,CAEOC,EAAAA,CAAQ,IAAIH,EAAAA,CCnCnB,IAAMI,EAAAA,CAAN,cAAoCzM,CAAmC,CAC1D,IAAA,CAAO,0BAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,IAAA,CAAM,CACF,WAAA,CACI,kGAAA,CACJ,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,MACd,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,mBAAA,CAAqBG,CAAAA,CAAQ,CACzB,OAAA,CAAS,gEACT,GAAA,CAAK,iGAAA,CACL,GAAA,CAAK,mFACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAAqF,CACxF,IAAMyM,CAAAA,CAA0B,EAAC,CAC3BhF,CAAAA,CAAU,IAAI,GAAA,CAOdiF,CAAAA,CAAehF,CAAAA,EAAgC,CACjD,GAAIA,CAAAA,CAAO,IAAA,GAAS,kBAAA,CAAoB,OAExC,IAAMhC,CAAAA,CAAOoB,CAAAA,CAAmBY,CAAM,CAAA,CAClChC,CAAAA,GAAS,IAAA,EAAM+B,CAAAA,CAAQ,GAAA,CAAI/B,CAAI,EACvC,CAAA,CAEA,OAAO,CACH,oBAAA,CAAqBnF,CAAAA,CAAM,CACvBmM,CAAAA,CAAYnM,CAAAA,CAAK,IAAI,EACzB,CAAA,CAEA,gBAAA,CAAiBA,EAAM,CACnBmM,CAAAA,CAAYnM,CAAAA,CAAK,QAAQ,EAC7B,CAAA,CAEA,kBAAA,CAAmBA,CAAAA,CAAM,CAUrB,GATIA,CAAAA,CAAK,MAAA,CAAO,IAAA,GAAS,qBAAA,EAAyBA,CAAAA,CAAK,MAAA,CAAO,OAAS,OAAA,EAGnEA,CAAAA,CAAK,MAAA,CAAO,MAAA,CAAO,IAAA,GAAS,wBAAA,EAE5BA,CAAAA,CAAK,EAAA,CAAG,IAAA,GAAS,YAAA,EAAgBA,CAAAA,CAAK,IAAA,GAAS,IAAA,EAI/CA,CAAAA,CAAK,EAAA,CAAG,cAAA,GAAmB,OAAW,OAE1C,IAAMmF,CAAAA,CAAOoB,CAAAA,CAAmBvG,CAAAA,CAAK,IAAI,CAAA,CACzC,GAAImF,CAAAA,GAAS,IAAA,CAAM,OAInB,IAAM7E,CAAAA,CAAO6E,CAAAA,CAAK,KAAA,CAAM,CAAA,CAAGA,CAAAA,CAAK,OAAA,CAAQ,GAAG,CAAC,CAAA,CACxC7E,CAAAA,GAAS,MAAA,EAAUoG,CAAAA,CAAajH,CAAAA,CAAQ,UAAA,CAAW,QAAA,CAASO,CAAI,CAAA,CAAGM,CAAI,CAAA,EAE3E4L,CAAAA,CAAW,KAAK,CACZ,IAAA,CAAAlM,CAAAA,CACA,IAAA,CAAMA,CAAAA,CAAK,EAAA,CAAG,IAAA,CACd,IAAA,CAAAmF,CAAAA,CACA,UAAA,CAAY1F,CAAAA,CAAQ,UAAA,CAAW,OAAA,CAAQO,CAAAA,CAAK,IAAI,CACpD,CAAC,EACL,CAAA,CAEA,cAAA,EAAiB,CACb,IAAA,IAAWoM,CAAAA,IAAaF,CAAAA,CAChBjF,EAAAA,CAAcC,CAAAA,CAASkF,CAAAA,CAAU,IAAI,CAAA,EAEzC3M,CAAAA,CAAQ,MAAA,CAAO,CACX,IAAA,CAAM2M,EAAU,IAAA,CAChB,SAAA,CAAW,qBAAA,CACX,IAAA,CAAM,CACF,IAAA,CAAMA,CAAAA,CAAU,IAAA,CAChB,UAAA,CAAYA,CAAAA,CAAU,UAC1B,CACJ,CAAC,EAET,CACJ,CACJ,CACJ,CAAA,CAEOC,EAAAA,CAAQ,IAAIJ,EAAAA,CCzHnB,IAAMK,EAAAA,CAAN,cAAsC9M,CAAmC,CAC5D,IAAA,CAAO,2BAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,IAAA,CAAM,CACF,WAAA,CAAa,8FAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,MACd,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,YAAaG,CAAAA,CAAQ,CACjB,OAAA,CAAS,mEAAA,CACT,GAAA,CAAK,4KAAA,CACL,GAAA,CAAK,yEACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAAqF,CACxF,OAAO,CACH,kBAAA,CAAmBO,CAAAA,CAAM,CACjBA,CAAAA,CAAK,MAAA,CAAO,IAAA,GAAS,qBAAA,EAAyBA,CAAAA,CAAK,MAAA,CAAO,IAAA,GAAS,OAAA,EACnEA,CAAAA,CAAK,MAAA,CAAO,MAAA,CAAO,IAAA,GAAS,wBAAA,GAC5BA,CAAAA,CAAK,EAAA,CAAG,IAAA,GAAS,eAAA,EAAmBA,CAAAA,CAAK,IAAA,GAAS,IAAA,EAIlDA,CAAAA,CAAK,IAAA,CAAK,IAAA,GAAS,YAAA,EAAgB,CAACyG,EAAAA,CAAsBzG,CAAAA,CAAK,IAAI,CAAA,EAIlEoH,GAAepH,CAAAA,CAAK,EAAE,CAAA,EAE3BP,CAAAA,CAAQ,MAAA,CAAO,CACX,IAAA,CAAAO,CAAAA,CACA,SAAA,CAAW,aAAA,CACX,IAAA,CAAM,CAAE,MAAA,CAAQP,CAAAA,CAAQ,UAAA,CAAW,OAAA,CAAQO,EAAK,IAAI,CAAE,CAC1D,CAAC,CAAA,EACL,CACJ,CACJ,CACJ,CAAA,CAEOuM,EAAAA,CAAQ,IAAID,EAAAA,CC/CnB,IAAME,EAAAA,CAAN,cAAgChN,CAAmC,CACtD,IAAA,CAAO,qBAAA,CAEP,cAAA,CAA0B,CAAC,CAAE,OAAA,CAAS,EAAG,CAAC,CAAA,CAE1C,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,IAAA,CAAM,CACF,WAAA,CAAa,gFAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,MACd,CAAA,CACA,MAAA,CAAQ,CACJ,CACI,IAAA,CAAM,QAAA,CACN,UAAA,CAAY,CACR,OAAA,CAAS,CACL,KAAM,OAAA,CACN,KAAA,CAAO,CAAE,IAAA,CAAM,QAAS,CAC5B,CACJ,CAAA,CACA,oBAAA,CAAsB,KAC1B,CACJ,CAAA,CACA,QAAA,CAAU,CACN,QAAA,CAAUG,CAAAA,CAAQ,CACd,OAAA,CAAS,gDAAA,CACT,GAAA,CAAK,6HAAA,CACL,GAAA,CAAK,yFACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAA8DC,CAAAA,CAAyC,CAC1G,IAAM2F,CAAAA,CAAU3F,EAAQ,CAAC,CAAA,EAAG,OAAA,EAAW,EAAC,CACxC,GAAI2F,CAAAA,CAAQ,MAAA,CAAS,CAAA,EAAKL,CAAAA,CAAYvF,CAAAA,CAAQ,QAAA,CAAU4F,CAAO,CAAA,CAC3D,OAAO,EAAC,CAOZ,IAAMgG,CAAAA,CAAS7J,CAAAA,EAA4D,CACnEA,CAAAA,EAAW,IAAA,GACX,CAACA,CAAAA,CAAO,KAAA,CAAM,UAAA,CAAW,IAAI,CAAA,EAAK,CAACA,CAAAA,CAAO,KAAA,CAAM,WAAW,KAAK,CAAA,EAEpE/B,CAAAA,CAAQ,MAAA,CAAO,CACX,IAAA,CAAM+B,CAAAA,CACN,SAAA,CAAW,UAAA,CACX,IAAA,CAAM,CAAE,IAAA,CAAMA,CAAAA,CAAO,KAAM,CAC/B,CAAC,GACL,CAAA,CAEA,OAAO,CACH,iBAAA,CAAkBxB,CAAAA,CAAM,CACpBqL,CAAAA,CAAMrL,CAAAA,CAAK,MAAM,EACrB,CAAA,CACA,sBAAA,CAAuBA,CAAAA,CAAM,CACzBqL,CAAAA,CAAMrL,CAAAA,CAAK,MAAM,EACrB,CAAA,CACA,oBAAA,CAAqBA,CAAAA,CAAM,CACvBqL,CAAAA,CAAMrL,CAAAA,CAAK,MAAM,EACrB,CAAA,CACA,gBAAA,CAAiBA,CAAAA,CAAM,CACfA,CAAAA,CAAK,MAAA,CAAO,IAAA,GAAS,SAAA,EAAa,OAAOA,CAAAA,CAAK,MAAA,CAAO,KAAA,EAAU,QAAA,EAC/DqL,CAAAA,CAAMrL,CAAAA,CAAK,MAAgC,EAEnD,CACJ,CACJ,CACJ,CAAA,CAEOyM,EAAAA,CAAQ,IAAID,GCrEnB,IAAME,EAAAA,CAAN,cAAgClN,CAAmC,CACtD,IAAA,CAAO,sBAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,QAAA,CACN,OAAA,CAAS,MAAA,CACT,KAAM,CACF,WAAA,CAAa,iFAAA,CACb,WAAA,CAAa,IACjB,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,UAAA,CAAYG,CAAAA,CAAQ,CAChB,OAAA,CAAS,iDAAA,CACT,IAAK,oGAAA,CACL,GAAA,CAAK,wFACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAAqF,CACxF,OAAO,CACH,OAAA,EAAU,CACN,IAAA,IAAWoC,CAAAA,IAAWpC,EAAQ,UAAA,CAAW,cAAA,EAAe,CAAG,CAGvD,GADI,CAACsD,CAAAA,CAAelB,CAAO,CAAA,EACvBA,CAAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,IAAA,GAASA,CAAAA,CAAQ,GAAA,CAAI,GAAA,CAAI,KAAM,SAGrD,IAAMuC,CAAAA,CAAUvC,CAAAA,CAAQ,KAAA,CAAM,OAAA,CAAQ,KAAA,CAAO,EAAE,CAAA,CAAE,IAAA,EAAK,CAIlDuC,CAAAA,CAAQ,MAAA,GAAW,CAAA,EAEvB3E,CAAAA,CAAQ,MAAA,CAAO,CACX,GAAA,CAAKoC,CAAAA,CAAQ,GAAA,CACb,SAAA,CAAW,YAAA,CACX,GAAA,CAAIuG,CAAAA,CAAO,CACP,IAAMuE,CAAAA,CAAS,GAAA,CAAI,MAAA,CAAO9K,CAAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,MAAM,EAC5C+K,CAAAA,CAAW,CAAA;AAAA,EAAQD,CAAM,MAAMvI,CAAO;AAAA,EAAKuI,CAAM,CAAA,GAAA,CAAA,CACvD,OAAOvE,CAAAA,CAAM,gBAAA,CAAiBvG,EAAQ,KAAA,CAAO+K,CAAQ,CACzD,CACJ,CAAC,EACL,CACJ,CACJ,CACJ,CACJ,CAAA,CAEOC,EAAAA,CAAQ,IAAIH,EAAAA,CCvDnB,IAAMI,EAAAA,CAAN,cAAyCtN,CAAmC,CAC/D,KAAO,8BAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,KAAO,CACZ,IAAA,CAAM,aACN,OAAA,CAAS,MAAA,CACT,KAAM,CACF,WAAA,CAAa,sDAAA,CACb,WAAA,CAAa,KACb,QAAA,CAAU,MACd,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,UAAA,CAAYG,EAAQ,CAChB,OAAA,CAAS,+CACT,GAAA,CAAK,4EAAA,CACL,IAAK,4CACT,CAAC,CACL,CACJ,EAEA,MAAA,CAAOF,CAAAA,CAAqF,CAOxF,IAAMsN,EAAkBlL,CAAAA,EAAuC,CAC3D,GAAIA,CAAAA,CAAQ,OAAS,MAAA,CAAQ,OAAO,OAEpC,IAAMuE,CAAAA,CAAW3G,EAAQ,UAAA,CAAW,KAAA,CAAMoC,CAAAA,CAAQ,GAAA,CAAI,MAAM,IAAA,CAAO,CAAC,CAAA,CACpE,OAAOuE,IAAa,MAAA,EAAa,UAAA,CAAW,IAAA,CAAKA,CAAQ,CAC7D,CAAA,CAEA,OAAO,CACH,OAAA,EAAU,CACN,QAAWvE,CAAAA,IAAWpC,CAAAA,CAAQ,UAAA,CAAW,cAAA,GAAkB,CACvD,GAAImC,CAAAA,CAAmBC,CAAO,GAAKkL,CAAAA,CAAelL,CAAO,CAAA,CAAG,SAE5D,IAAMuC,CAAAA,CAAUtC,EAAAA,CAAwBD,CAAO,CAAA,CAC3CuC,CAAAA,GAAY,MAAQ,CAAC,IAAA,MAAA,CAAC,SAAA,CAAO,GAAC,EAAC,IAAA,CAAKA,CAAAA,CAAQ,IAAI,CAAA,EAIhD,0BAA0B,IAAA,CAAK3E,CAAAA,CAAQ,UAAA,CAAW,OAAA,GAAU,KAAA,CAAM2E,CAAAA,CAAQ,KAAK,CAAC,CAAA,EAEpF3E,EAAQ,MAAA,CAAO,CACX,GAAA,CAAK,CACD,MAAOA,CAAAA,CAAQ,UAAA,CAAW,eAAA,CAAgB2E,CAAAA,CAAQ,KAAK,CAAA,CACvD,GAAA,CAAK3E,CAAAA,CAAQ,UAAA,CAAW,gBAAgB2E,CAAAA,CAAQ,KAAA,CAAQA,EAAQ,IAAA,CAAK,MAAM,CAC/E,CAAA,CACA,SAAA,CAAW,YAAA,CACX,GAAA,CAAKgE,GACDA,CAAAA,CAAM,gBAAA,CACF,CAAChE,CAAAA,CAAQ,MAAOA,CAAAA,CAAQ,KAAA,CAAQA,CAAAA,CAAQ,IAAA,CAAK,MAAM,CAAA,CACnDA,CAAAA,CAAQ,KAAK,WAAA,EACjB,CACR,CAAC,EACL,CACJ,CACJ,CACJ,CACJ,CAAA,CAEO4I,EAAAA,CAAQ,IAAIF,GCxEZ,SAASG,EAAAA,CAAqBtJ,CAAAA,CAAuB,CACxD,OAAO,QAAA,CAAS,IAAA,CAAKA,CAAI,CAC7B,CAQO,SAASuJ,CAAAA,CAAWvJ,CAAAA,CAAuB,CAC9C,OAAOtE,EAAU,KAAA,CAAM,IAAA,CAAK,IAAA,CAAKsE,CAAI,CACzC,CAQO,SAASwJ,EAAAA,CAAkBxJ,CAAAA,CAAuB,CACrD,OAAOtE,CAAAA,CAAU,MAAM,YAAA,CAAa,IAAA,CAAKsE,CAAI,CACjD,CAQO,SAASyJ,EAAAA,CAAgBpN,EAAuD,CACnF,OAAKA,CAAAA,CACDA,CAAAA,CAAK,OAAS,yBAAA,EAA6BA,CAAAA,CAAK,IAAA,GAAS,oBAAA,CAA6B,KAEnFA,CAAAA,CAAK,IAAA,GAAS,kBAAoBA,CAAAA,CAAK,MAAA,CAAO,OAAS,YAAA,EAAgBA,CAAAA,CAAK,MAAA,CAAO,IAAA,GAAS,cAHjF,KAItB,CAQO,SAASqN,CAAAA,CAAgBrN,EAAuD,CACnF,GAAI,CAACA,CAAAA,CAAM,OAAO,MAAA,CAElB,OAAQA,EAAK,IAAA,EACT,KAAK,YAAA,CACL,KAAK,aAAA,CACD,OAAO,MACX,KAAK,uBAAA,CACD,OAAOqN,CAAAA,CAAgBrN,EAAK,UAAU,CAAA,EAAKqN,CAAAA,CAAgBrN,CAAAA,CAAK,SAAS,CAAA,CAC7E,KAAK,oBACD,OAAOqN,CAAAA,CAAgBrN,EAAK,IAAI,CAAA,EAAKqN,CAAAA,CAAgBrN,CAAAA,CAAK,KAAK,CAAA,CACnE,KAAK,oBAAA,CACD,OAAOqN,EAAgBrN,CAAAA,CAAK,WAAA,CAAY,EAAA,CAAG,EAAE,CAAC,CAAA,CAClD,QACI,OAAO,MACf,CACJ,CASO,SAASsN,CAAAA,CAAmBtD,CAAAA,CAAkBU,CAAAA,CAAmC,CAEpF,OAAIV,CAAAA,CAAG,IAAA,GAAS,yBAAA,EAA6BA,EAAG,IAAA,CAAK,IAAA,GAAS,gBAAA,CACnDqD,CAAAA,CAAgBrD,EAAG,IAAI,CAAA,CAG3BS,EAAWT,CAAAA,CAAG,IAAA,CAAMU,EAAa2C,CAAe,CAC3D,CASO,SAASE,GAAkBvD,CAAAA,CAAkBU,CAAAA,CAAmC,CACnF,IAAM/G,EAAO6G,CAAAA,CAAgBR,CAAE,CAAA,CAC/B,OAAIrG,IAAS,MAAA,CAAkB,KAAA,CAExBuJ,CAAAA,CAAWvJ,CAAI,GAAMsJ,EAAAA,CAAqBtJ,CAAI,CAAA,EAAK2J,CAAAA,CAAmBtD,EAAIU,CAAW,CAChG,CAUA,SAAS8C,GAAexN,CAAAA,CAAqB0K,CAAAA,CAAmC,CAC5E,GAAI1K,EAAK,IAAA,GAAS,gBAAA,CACd,OAAO,EAAEA,CAAAA,CAAK,OAAO,IAAA,GAAS,YAAA,EAAgBkN,CAAAA,CAAWlN,CAAAA,CAAK,OAAO,IAAI,CAAA,CAAA,CAG7E,IAAA,IAAW6H,CAAAA,IAAO6C,EAAY1K,CAAAA,CAAK,IAAI,CAAA,EAAK,GAAI,CAC5C,IAAM8H,EAAS9H,CAAAA,CAA4C6H,CAAG,EACxD+C,CAAAA,CAAW,KAAA,CAAM,OAAA,CAAQ9C,CAAK,EAAIA,CAAAA,CAAQ,CAACA,CAAK,CAAA,CAEtD,QAAW+C,CAAAA,IAASD,CAAAA,CAAU,CAC1B,IAAME,EAAYD,CAAAA,CAClB,GAAI,GAACC,CAAAA,EAAa,OAAOA,EAAU,IAAA,EAAS,QAAA,CAAA,EACxC,CAAAzL,CAAAA,CAAU,UAAU,UAAA,CAAW,GAAA,CAAIyL,CAAAA,CAAU,IAAI,GACjD0C,EAAAA,CAAe1C,CAAAA,CAAWJ,CAAW,CAAA,CAAG,OAAO,KACvD,CACJ,CAEA,OAAO,MACX,CAUO,SAAS+C,EAAAA,CAAezN,CAAAA,CAA2B0K,CAAAA,CAAmC,CACzF,OAAI1K,CAAAA,CAAK,IAAA,GAAS,yBAAA,EAA6BA,EAAK,IAAA,GAAS,oBAAA,CAA6B,KAAA,CAEnFwN,EAAAA,CAAexN,EAAM0K,CAAW,CAC3C,CC5HA,IAAMgD,EAAAA,CAAN,cAAmClO,CAAmC,CACzD,IAAA,CAAO,wBAAA,CACP,eAA0B,EAAC,CAC3B,IAAA,CAAO,CACZ,KAAM,YAAA,CACN,IAAA,CAAM,CACF,WAAA,CAAa,+EACb,WAAA,CAAa,IAAA,CACb,SAAU,MACd,CAAA,CACA,OAAQ,EAAC,CACT,QAAA,CAAU,CACN,aAAcG,CAAAA,CAAQ,CAClB,OAAA,CAAS,uDAAA,CACT,IAAK,uGAAA,CACL,GAAA,CAAK,yDACT,CAAC,EACD,cAAA,CAAgBA,CAAAA,CAAQ,CACpB,OAAA,CAAS,iEAAA,CACT,IAAK,sGAAA,CACL,GAAA,CAAK,gGACT,CAAC,CACL,CACJ,CAAA,CAOA,MAAA,CAAOF,CAAAA,CAAqF,CAKxF,IAAM4L,CAAAA,CAASrB,CAAAA,EAA2B,CACtC,IAAMuB,CAAAA,CAAQlI,CAAAA,CAAgB5D,EAAQ,UAAA,CAAYsK,CAAAA,CAAoBC,CAAE,CAAC,CAAA,CACzE,GAAIuB,CAAAA,GAAU,KAAM,OAEpB,IAAMoC,CAAAA,CAAalK,EAAAA,CAAmB8H,CAAK,CAAA,CACrCpB,CAAAA,CAAOD,EAAAA,CAAcF,CAAE,EACvB4D,CAAAA,CAAa,IAAI,IAAIzD,CAAAA,CAAK,MAAA,CAAO0D,GAAOA,CAAAA,CAAI,IAAA,GAAS,MAAM,CAAA,CAAE,IAAIA,CAAAA,EAAOA,CAAAA,CAAI,IAAI,CAAC,EAEvF,IAAA,IAAWA,CAAAA,IAAO1D,CAAAA,CAAM,CACpB,GAAI0D,CAAAA,CAAI,IAAA,GAAS,OAAQ,CAChBF,CAAAA,CAAW,IAAIE,CAAAA,CAAI,IAAI,CAAA,EACxBpO,CAAAA,CAAQ,OAAO,CACX,IAAA,CAAMoO,CAAAA,CAAI,IAAA,CACV,UAAW,cAAA,CACX,IAAA,CAAM,CAAE,IAAA,CAAMA,EAAI,IAAK,CAC3B,CAAC,CAAA,CAGL,QACJ,CAEA,GAAIA,CAAAA,CAAI,KAAA,CAAM,KAAA,CAAMC,GAASH,CAAAA,CAAW,GAAA,CAAIG,CAAAA,CAAM,IAAI,CAAC,CAAA,CAAG,SAI1D,IAAMtH,CAAAA,CAAa,IAAI,GAAA,CAAIqH,CAAAA,CAAI,MAAM,GAAA,CAAIC,CAAAA,EAASA,EAAM,IAAI,CAAC,CAAA,CAE7D,GAD0B,EAAC,GAAGH,CAAU,CAAA,CAAE,IAAA,CAAKhK,GAAQ,CAAC6C,CAAAA,CAAW,GAAA,CAAI7C,CAAI,GAAK,CAACiK,CAAAA,CAAW,IAAIjK,CAAI,CAAC,EAGrG,IAAA,IAAWmK,CAAAA,IAASD,CAAAA,CAAI,KAAA,CAChBF,EAAW,GAAA,CAAIG,CAAAA,CAAM,IAAI,CAAA,EAE7BrO,EAAQ,MAAA,CAAO,CACX,IAAA,CAAMqO,CAAAA,CAAM,KACZ,SAAA,CAAW,cAAA,CACX,KAAM,CAAE,IAAA,CAAMA,EAAM,IAAK,CAC7B,CAAC,EAET,CAEIlK,EAAAA,CAAmB2H,CAAK,CAAA,EACxBJ,CAAAA,CAAenB,EAAIvK,CAAAA,CAAQ,UAAA,CAAW,WAAW,CAAA,EAGjD6N,EAAmBtD,CAAAA,CAAIvK,CAAAA,CAAQ,WAAW,WAAW,CAAA,EAEzDA,EAAQ,MAAA,CAAO,CAAE,IAAA,CAAM8L,CAAAA,CAAO,UAAW,gBAAiB,CAAC,EAC/D,CAAA,CAEA,OAAO,CACH,mBAAA,CAAoBvL,CAAAA,CAAM,CACtBqL,EAAMrL,CAAI,EACd,CAAA,CACA,kBAAA,CAAmBA,EAAM,CACrBqL,CAAAA,CAAMrL,CAAI,EACd,EACA,uBAAA,CAAwBA,CAAAA,CAAM,CAC1BqL,CAAAA,CAAMrL,CAAI,EACd,CACJ,CACJ,CACJ,EAEO+N,EAAAA,CAAQ,IAAIL,GCxGZ,IAAMM,EAAAA,CAA8C,CACvD,QAAA,CAAU,UAAA,CACV,KAAA,CAAO,OACX,EAOA,SAASC,EAAAA,CAAc3K,CAAAA,CAAqD,CACxE,IAAM4K,CAAAA,CAAoB,EAAC,CAE3B,IAAA,IAAW9N,KAAakD,CAAAA,CAAW,GAAA,CAAI,KAC/BlD,CAAAA,CAAU,IAAA,GAAS,qBACnB8N,CAAAA,CAAQ,IAAA,CAAK,MAAA,CAAO9N,CAAAA,CAAU,OAAO,KAAK,CAAC,CAAA,CAInD,OAAO8N,CACX,CASO,SAASC,EAAAA,CAAiB7K,CAAAA,CAA2C2B,EAAkC,CAC1G,IAAMmJ,EAAW,IAAI,GAAA,CACfF,EAAUD,EAAAA,CAAc3K,CAAU,CAAA,CAExC,OAAI4K,EAAQ,IAAA,CAAK1M,CAAAA,EAAUA,CAAAA,CAAO,UAAA,CAAW,YAAY,CAAA,EAAKnC,CAAAA,CAAU,UAAA,CAAW,cAAA,CAAe,KAAKmC,CAAM,CAAC,GAC1G4M,CAAAA,CAAS,GAAA,CAAI,UAAU,CAAA,CAAA,CAGNF,CAAAA,CAAQ,IAAA,CACzB1M,CAAAA,EAAUA,IAAW,OAAA,EAAWA,CAAAA,CAAO,UAAA,CAAW,QAAQ,GAAKA,CAAAA,GAAW,WAC9E,CAAA,EACoBnC,CAAAA,CAAU,WAAW,UAAA,CAAW,IAAA,CAAK4F,CAAQ,CAAA,GAC7DmJ,CAAAA,CAAS,IAAI,OAAO,CAAA,CAGjBA,CACX,CCzCA,IAAMC,EAAAA,CAAN,cAAqC7O,CAAmC,CAC3D,KAAO,0BAAA,CAEP,cAAA,CAA0B,CAAC,CAAE,OAAQ,EAAG,CAAC,CAAA,CAEzC,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,IAAA,CAAM,CACF,YAAa,0EAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,MACd,CAAA,CACA,MAAA,CAAQ,CACJ,CACI,KAAM,QAAA,CACN,UAAA,CAAY,CACR,MAAA,CAAQ,CACJ,KAAM,OAAA,CACN,KAAA,CAAO,CACH,IAAA,CAAM,SACN,IAAA,CAAM,CAAC,UAAA,CAAY,OAAO,CAC9B,CACJ,CACJ,CAAA,CACA,oBAAA,CAAsB,KAC1B,CACJ,CAAA,CACA,SAAU,CACN,aAAA,CAAeG,EAAQ,CACnB,OAAA,CAAS,qFAAA,CACT,GAAA,CAAK,sGACL,GAAA,CAAK,oIACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAA8DC,CAAAA,CAAyC,CAC1G,IAAM4O,CAAAA,CAAU,IAAI,GAAA,CAAI5O,CAAAA,CAAQ,CAAC,CAAA,EAAG,MAAA,EAAU,EAAE,EAG1C6O,CAAAA,CAAW9O,CAAAA,CAAQ,QAAA,CAASJ,CAAAA,CAAU,WAAW,CAAA,EAAK,EAAC,CAE7D,OAAO,CACH,OAAA,CAAQW,CAAAA,CAAM,CACV,IAAMoO,CAAAA,CAAWD,GAAiB1O,CAAAA,CAAQ,UAAA,CAAYA,CAAAA,CAAQ,QAAQ,EAEtE,IAAA,IAAW+O,CAAAA,IAAaJ,CAAAA,CAChBE,CAAAA,CAAQ,IAAIE,CAAS,CAAA,EAAKD,CAAAA,CAAQC,CAAS,GAE/C/O,CAAAA,CAAQ,MAAA,CAAO,CACX,IAAA,CAAAO,CAAAA,CACA,UAAW,eAAA,CACX,IAAA,CAAM,CAAE,SAAA,CAAWgO,GAAiBQ,CAAS,CAAA,CAAG,MAAA,CAAQA,CAAU,CACtE,CAAC,EAET,CACJ,CACJ,CACJ,CAAA,CAEOC,EAAAA,CAAQ,IAAIJ,EAAAA,CC/CnB,IAAMK,GAAN,cAAmClP,CAAmC,CACzD,IAAA,CAAO,yBAEP,cAAA,CAA0B,CAAC,CAAE,OAAA,CAAS,CAAC,eAAA,CAAiB,QAAQ,CAAA,CAAG,MAAA,CAAQ,EAAG,CAAC,EAE/E,IAAA,CAAO,CACZ,KAAM,YAAA,CACN,IAAA,CAAM,CACF,WAAA,CAAa,0EACb,WAAA,CAAa,IACjB,CAAA,CACA,MAAA,CAAQ,CACJ,CACI,IAAA,CAAM,QAAA,CACN,UAAA,CAAY,CACR,OAAA,CAAS,CACL,KAAM,OAAA,CACN,KAAA,CAAO,CACH,IAAA,CAAM,QAAA,CACN,IAAA,CAAM,CAAC,gBAAiB,gBAAA,CAAkB,QAAQ,CACtD,CACJ,EACA,MAAA,CAAQ,CACJ,IAAA,CAAM,OAAA,CACN,MAAO,CAAE,IAAA,CAAM,QAAS,CAC5B,CACJ,EACA,oBAAA,CAAsB,KAC1B,CACJ,CAAA,CACA,SAAU,CACN,YAAA,CAAcG,CAAAA,CAAQ,CAClB,QAAS,+CAAA,CACT,GAAA,CAAK,sHAAA,CACL,GAAA,CAAK,6EACT,CAAC,CACL,CACJ,CAAA,CAEA,OAAOF,CAAAA,CAA8DC,CAAAA,CAAyC,CAC1G,IAAMiP,EAAU,IAAI,GAAA,CAAajP,CAAAA,CAAQ,CAAC,GAAG,OAAA,EAAW,CAAC,eAAA,CAAiB,QAAQ,CAAC,CAAA,CAI7EiI,CAAAA,CAAS,IAAI,GAAA,CAAIjI,CAAAA,CAAQ,CAAC,CAAA,EAAG,MAAA,EAAU,EAAE,EASzCuG,CAAAA,CAAS,CAAC+D,CAAAA,CAAkB4E,CAAAA,CAA6BjL,EAAc3D,CAAAA,GAA8B,CACnG2H,CAAAA,CAAO,GAAA,CAAIhE,CAAI,CAAA,EAGf4G,EAAAA,CAAqBP,CAAE,CAAA,EAGvBiD,EAAAA,CAAqBtJ,CAAI,CAAA,EAAK2J,CAAAA,CAAmBtD,CAAAA,CAAIvK,CAAAA,CAAQ,WAAW,WAAW,CAAA,EAEnFsE,CAAAA,CAAgBtE,CAAAA,CAAQ,WAAYmP,CAAY,CAAA,EAEpDnP,CAAAA,CAAQ,MAAA,CAAO,CACX,IAAA,CAAAO,CAAAA,CACA,UAAW,cAAA,CACX,IAAA,CAAM,CAAE,IAAA,CAAA2D,CAAK,CACjB,CAAC,EACL,CAAA,CAQMkL,CAAAA,CAAgB,CAAC7E,CAAAA,CAAkBhK,IAA8B,CACnE,IAAM2D,CAAAA,CAAO6G,CAAAA,CAAgBR,CAAE,CAAA,CAC/B,GAAIrG,IAAS,MAAA,CAAW,OAExB,IAAMiL,CAAAA,CAAe7E,CAAAA,CAAoBC,CAAE,CAAA,CAGvC4E,EAAa,IAAA,GAAS,kBAAA,EAAsBA,CAAAA,CAAa,IAAA,GAAS,YAElE,CAAC3E,EAAAA,CAAW2E,CAAY,CAAA,EAAK,CAACD,CAAAA,CAAQ,GAAA,CAAI,QAAQ,CAAA,EAEtD1I,CAAAA,CAAO+D,EAAI4E,CAAAA,CAAcjL,CAAAA,CAAM3D,CAAI,EACvC,EAOM8O,CAAAA,CAAcjH,CAAAA,EAA2C,CAC3D,GAAIA,EAAI,IAAA,GAAS,YAAA,CAAc,OAAOA,CAAAA,CAAI,KAC1C,GAAIA,CAAAA,CAAI,OAAS,SAAA,EAAa,OAAOA,EAAI,KAAA,EAAU,QAAA,CAAU,OAAOA,CAAAA,CAAI,KAG5E,CAAA,CAEA,OAAO,CACH,mBAAA,CAAoB7H,EAAM,CACtB6O,CAAAA,CAAc7O,CAAAA,CAAMA,CAAAA,CAAK,IAAMA,CAAI,EACvC,EACA,kBAAA,CAAmBA,CAAAA,CAAM,CAChBA,CAAAA,CAAK,IAAA,GACNA,CAAAA,CAAK,IAAA,CAAK,OAAS,yBAAA,EAA6BA,CAAAA,CAAK,IAAA,CAAK,IAAA,GAAS,sBAEvE6O,CAAAA,CAAc7O,CAAAA,CAAK,IAAA,CAAMA,CAAAA,CAAK,EAAE,CAAA,EACpC,CAAA,CACA,iBAAiBA,CAAAA,CAAM,CAEnB,GADI,CAAC2O,CAAAA,CAAQ,GAAA,CAAI,eAAe,GAAK3O,CAAAA,CAAK,QAAA,EACtCA,CAAAA,CAAK,KAAA,CAAM,OAAS,oBAAA,CAAsB,OAE9C,IAAM2D,CAAAA,CAAOmL,EAAW9O,CAAAA,CAAK,GAAG,EAC5B2D,CAAAA,GAAS,MAAA,EAEbsC,EAAOjG,CAAAA,CAAK,KAAA,CAAOA,CAAAA,CAAM2D,CAAAA,CAAM3D,EAAK,GAAG,EAC3C,CAAA,CACA,QAAA,CAASA,EAAM,CAEX,GADI,CAAC2O,CAAAA,CAAQ,IAAI,gBAAgB,CAAA,EAAK3O,EAAK,QAAA,EACvCA,CAAAA,CAAK,MAAM,IAAA,GAAS,yBAAA,EAA6BA,CAAAA,CAAK,KAAA,CAAM,OAAS,oBAAA,CAAsB,OAE/F,IAAM2D,CAAAA,CAAOmL,EAAW9O,CAAAA,CAAK,GAAG,CAAA,CAC5B2D,CAAAA,GAAS,QAEbsC,CAAAA,CAAOjG,CAAAA,CAAK,MAAOA,CAAAA,CAAM2D,CAAAA,CAAM3D,EAAK,GAAG,EAC3C,CACJ,CACJ,CACJ,CAAA,CAEO+O,EAAAA,CAAQ,IAAIL,EAAAA,CCrJnB,IAAMM,EAAAA,CAAN,cAAyCxP,CAAmC,CAC/D,KAAO,+BAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,QAAA,CACN,OAAA,CAAS,YAAA,CACT,KAAM,CACF,WAAA,CAAa,6EAAA,CACb,WAAA,CAAa,KACb,QAAA,CAAU,MACd,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,WAAA,CAAaG,CAAAA,CAAQ,CACjB,OAAA,CAAS,uEAAA,CACT,GAAA,CAAK,qFAAA,CACL,IAAK,oEACT,CAAC,CAAA,CACD,WAAA,CAAaA,EAAQ,CACjB,OAAA,CAAS,qEAAA,CACT,GAAA,CAAK,uFACL,GAAA,CAAK,6DACT,CAAC,CACL,CACJ,EAEA,MAAA,CAAOF,CAAAA,CAAqF,CAKxF,IAAM4L,EAASxJ,CAAAA,EAAoC,CAE/C,GAAIA,CAAAA,CAAQ,IAAI,KAAA,CAAM,IAAA,GAASA,CAAAA,CAAQ,GAAA,CAAI,IAAI,IAAA,CAAM,OAErD,IAAMoN,CAAAA,CAAWpN,CAAAA,CAAQ,MAAM,KAAA,CAAM;AAAA,CAAI,CAAA,CACnC8K,CAAAA,CAAS,GAAA,CAAI,MAAA,CAAO9K,CAAAA,CAAQ,GAAA,CAAI,KAAA,CAAM,MAAM,CAAA,CAG5CqN,CAAAA,CAAAA,CAAWD,CAAAA,CAAS,CAAC,GAAK,EAAA,EAAI,OAAA,CAAQ,KAAA,CAAO,EAAE,CAAA,CACrD,GAAIC,CAAAA,CAAQ,IAAA,EAAK,GAAM,EAAA,CAAI,CACvB,IAAM7F,CAAAA,CAAQxH,CAAAA,CAAQ,KAAA,CAAM,CAAC,EAAI,CAAA,CAC3BsN,CAAAA,CAASD,CAAAA,CAAQ,UAAA,CAAW,GAAG,CAAA,CAAI,EAAA,CAAK,GAAA,CAE9CzP,CAAAA,CAAQ,MAAA,CAAO,CACX,GAAA,CAAK,CACD,KAAA,CAAOoC,CAAAA,CAAQ,GAAA,CAAI,MACnB,GAAA,CAAKpC,CAAAA,CAAQ,UAAA,CAAW,eAAA,CAAgB4J,CAAAA,CAAQ6F,CAAAA,CAAQ,MAAM,CAClE,EACA,SAAA,CAAW,aAAA,CACX,GAAA,CAAK9G,CAAAA,EAASA,CAAAA,CAAM,qBAAA,CAAsB,CAACiB,CAAAA,CAAOA,CAAK,CAAA,CAAG;AAAA,EAAKsD,CAAM,CAAA,EAAA,EAAKwC,CAAM,CAAA,CAAE,CACtF,CAAC,EACL,CAGA,GAAA,CADiBF,CAAAA,CAAS,EAAA,CAAG,EAAE,GAAK,EAAA,EAAI,OAAA,CAAQ,SAAA,CAAW,EAAE,CAAA,CACjD,IAAA,EAAK,GAAM,EAAA,CAAI,CACvB,IAAM3F,CAAAA,CAAMzH,CAAAA,CAAQ,KAAA,CAAM,CAAC,EAAI,CAAA,CAE/BpC,CAAAA,CAAQ,MAAA,CAAO,CACX,GAAA,CAAK,CACD,MAAOA,CAAAA,CAAQ,UAAA,CAAW,eAAA,CAAgB6J,CAAG,CAAA,CAC7C,GAAA,CAAKzH,EAAQ,GAAA,CAAI,GACrB,CAAA,CACA,SAAA,CAAW,aAAA,CACX,GAAA,CAAKuG,CAAAA,EAASA,CAAAA,CAAM,qBAAA,CAAsB,CAACkB,CAAAA,CAAKA,CAAG,CAAA,CAAG;AAAA,EAAKqD,CAAM,CAAA,CAAA,CAAG,CACxE,CAAC,EACL,CACJ,CAAA,CAEA,OAAO,CACH,OAAA,EAAU,CACN,IAAA,IAAW9K,CAAAA,IAAWpC,CAAAA,CAAQ,UAAA,CAAW,cAAA,EAAe,CAChDsD,CAAAA,CAAelB,CAAO,CAAA,EAAGwJ,CAAAA,CAAMxJ,CAAO,EAElD,CACJ,CACJ,CACJ,CAAA,CAEOuN,EAAAA,CAAQ,IAAIJ,EAAAA,CCpFZ,SAASK,EAAAA,CACZ/L,CAAAA,CACAtD,CAAAA,CACA2M,CAAAA,CACM,CAEN,IAAM2C,CAAAA,CAAAA,CADchM,CAAAA,CAAW,KAAA,CAAMtD,CAAAA,CAAK,GAAA,CAAI,KAAA,CAAM,IAAA,CAAO,CAAC,CAAA,EAAK,EAAA,EAClC,KAAA,CAAM,MAAM,CAAA,GAAI,CAAC,CAAA,EAAK,EAAA,CAC/CuP,CAAAA,CAAiBD,CAAAA,CAAa,GAAA,CAAI,MAAA,CAAO3C,CAAM,CAAA,CAIrD,OAAO,CAAA;AAAA,EAFM3M,CAAAA,CAAK,UAAA,CAAW,GAAA,CAAIqH,CAAAA,EAAY,CAAA,EAAGkI,CAAc,CAAA,EAAGjM,CAAAA,CAAW,OAAA,CAAQ+D,CAAQ,CAAC,CAAA,CAAE,EAAE,IAAA,CAAK,CAAA;AAAA,CAAK,CAE1F,CAAA;AAAA,EAAMiI,CAAU,CAAA,CAAA,CACrC,CCRA,IAAME,EAAAA,CAAN,cAAqChQ,CAAmC,CAC3D,IAAA,CAAO,0BAAA,CACP,cAAA,CAA0B,CAC/B,CACI,OAAA,CAASH,CAAAA,CAAU,OAAA,CAAQ,eAAA,CAC3B,MAAA,CAAQA,CAAAA,CAAU,OAAA,CAAQ,YAC9B,CACJ,CAAA,CAES,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,OAAA,CAAS,MAAA,CACT,IAAA,CAAM,CACF,WAAA,CAAa,mFAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,MACd,CAAA,CACA,MAAA,CAAQ,CACJ,CACI,IAAA,CAAM,QAAA,CACN,UAAA,CAAY,CACR,OAAA,CAAS,CAAE,IAAA,CAAM,SAAA,CAAW,OAAA,CAAS,CAAE,CAAA,CACvC,MAAA,CAAQ,CAAE,IAAA,CAAM,SAAA,CAAW,OAAA,CAAS,CAAE,CAC1C,CAAA,CACA,qBAAsB,KAC1B,CACJ,CAAA,CACA,QAAA,CAAU,CACN,UAAA,CAAYM,CAAAA,CAAQ,CAChB,OAAA,CAAS,yEAAA,CACT,GAAA,CAAK,uHAAA,CACL,GAAA,CAAK,6EACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAA8DC,CAAAA,CAAyC,CAC1G,IAAM+P,CAAAA,CAAU/P,CAAAA,CAAQ,CAAC,CAAA,EAAG,OAAA,EAAWL,CAAAA,CAAU,OAAA,CAAQ,eAAA,CACnDsN,CAAAA,CAASjN,CAAAA,CAAQ,CAAC,CAAA,EAAG,MAAA,EAAUL,CAAAA,CAAU,OAAA,CAAQ,YAAA,CAEvD,OAAO,CACH,gBAAA,CAAiBW,CAAAA,CAAM,CAEnB,GADIA,CAAAA,CAAK,UAAA,CAAW,MAAA,EAAUyP,CAAAA,EAC1BzP,CAAAA,CAAK,GAAA,CAAI,KAAA,CAAM,IAAA,GAASA,CAAAA,CAAK,GAAA,CAAI,GAAA,CAAI,IAAA,CAAM,OAI/C,IAAM0P,CAAAA,CAAcjQ,CAAAA,CAAQ,UAAA,CAAW,iBAAA,CAAkBO,CAAI,EAAE,MAAA,CAAS,CAAA,CAExEP,CAAAA,CAAQ,MAAA,CAAO,CACX,IAAA,CAAAO,CAAAA,CACA,SAAA,CAAW,YAAA,CACX,IAAA,CAAM,CAAE,KAAA,CAAOA,CAAAA,CAAK,UAAA,CAAW,MAAA,CAAQ,GAAA,CAAKyP,CAAQ,CAAA,CACpD,GAAA,CAAKC,CAAAA,CACC,IAAA,CACAtH,CAAAA,EAASA,CAAAA,CAAM,WAAA,CAAYpI,CAAAA,CAAMqP,EAAAA,CAAoB5P,CAAAA,CAAQ,UAAA,CAAYO,CAAAA,CAAM2M,CAAM,CAAC,CAChG,CAAC,EACL,CACJ,CACJ,CACJ,CAAA,CAEOgD,EAAAA,CAAQ,IAAIH,EAAAA,CC/DnB,IAAMI,EAAAA,CAAN,cAAiCpQ,CAAmC,CACvD,IAAA,CAAO,sBAAA,CAEP,cAAA,CAA0B,CAAC,CAAE,GAAA,CAAKH,CAAAA,CAAU,KAAA,CAAM,oBAAqB,CAAC,CAAA,CAExE,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,IAAA,CAAM,CACF,WAAA,CAAa,2DACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,OACd,CAAA,CACA,MAAA,CAAQ,CACJ,CACI,IAAA,CAAM,QAAA,CACN,UAAA,CAAY,CACR,GAAA,CAAK,CAAE,IAAA,CAAM,SAAA,CAAW,OAAA,CAAS,CAAE,CACvC,CAAA,CACA,oBAAA,CAAsB,KAC1B,CACJ,CAAA,CACA,QAAA,CAAU,CACN,OAAA,CAASM,CAAAA,CAAQ,CACb,OAAA,CAAS,qFAAA,CACT,GAAA,CAAK,sFACL,GAAA,CAAK,+FACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAA8DC,CAAAA,CAAyC,CAC1G,IAAMiG,CAAAA,CAAMjG,CAAAA,CAAQ,CAAC,CAAA,EAAG,GAAA,EAAOL,CAAAA,CAAU,KAAA,CAAM,oBAAA,CAQzC+K,CAAAA,CAAU,CACZpK,CAAAA,CACAmD,CAAAA,GACO,CACP,GAAKnD,CAAAA,CAEL,CAAA,GAAIA,CAAAA,CAAK,IAAA,GAAS,SAAA,CAAW,CACrB,OAAOA,EAAK,KAAA,EAAU,QAAA,EAAUmD,CAAAA,CAAM,IAAA,CAAK,CAAE,IAAA,CAAAnD,CAAAA,CAAM,IAAA,CAAMA,CAAAA,CAAK,KAAM,CAAC,CAAA,CACzE,MACJ,CAEA,GAAIA,CAAAA,CAAK,IAAA,GAAS,iBAAA,CAAmB,CAC7BA,CAAAA,CAAK,WAAA,CAAY,MAAA,GAAW,CAAA,EAAGmD,CAAAA,CAAM,IAAA,CAAK,CAAE,IAAA,CAAAnD,CAAAA,CAAM,IAAA,CAAMA,CAAAA,CAAK,MAAA,CAAO,CAAC,CAAA,EAAG,KAAA,CAAM,MAAA,EAAU,EAAG,CAAC,CAAA,CAChG,MACJ,CAEA,IAAA,IAAW6H,CAAAA,IAAOpI,CAAAA,CAAQ,UAAA,CAAW,WAAA,CAAYO,CAAAA,CAAK,IAAI,CAAA,EAAK,EAAC,CAAG,CAC/D,IAAM8H,CAAAA,CAAS9H,CAAAA,CAA4C6H,CAAG,CAAA,CACxD+C,CAAAA,CAAW,KAAA,CAAM,OAAA,CAAQ9C,CAAK,CAAA,CAAIA,CAAAA,CAAQ,CAACA,CAAK,EAEtD,IAAA,IAAW+C,CAAAA,IAASD,CAAAA,CAAU,CAC1B,IAAME,CAAAA,CAAYD,CAAAA,CACd,CAACC,CAAAA,EAAa,OAAOA,CAAAA,CAAU,IAAA,EAAS,QAAA,EACxCzL,CAAAA,CAAU,SAAA,CAAU,UAAA,CAAW,GAAA,CAAIyL,CAAAA,CAAU,IAAI,CAAA,EACrDV,CAAAA,CAAQU,CAAAA,CAAW3H,CAAK,EAC5B,CACJ,CAAA,CACJ,CAAA,CAEA,OAAO,CACH,YAAA,CAAanD,CAAAA,CAAM,CACf,GAAIA,CAAAA,CAAK,IAAA,CAAK,IAAA,GAAS,eAAA,EAAmBA,CAAAA,CAAK,IAAA,CAAK,IAAA,GAAS,WAAA,EAAeA,CAAAA,CAAK,KAAA,GAAU,IAAA,CAAM,OAEjG,IAAMmD,CAAAA,CAAiD,EAAC,CACxDiH,CAAAA,CAAQpK,CAAAA,CAAK,KAAA,CAAOmD,CAAK,CAAA,CAEzB,IAAA,GAAW,CAAE,IAAA,CAAMxC,CAAAA,CAAS,IAAA,CAAAS,CAAK,CAAA,GAAK+B,CAAAA,CAC9B/B,CAAAA,CAAK,MAAA,EAAUuE,CAAAA,EAEnBlG,EAAQ,MAAA,CAAO,CACX,IAAA,CAAMkB,CAAAA,CACN,SAAA,CAAW,SAAA,CACX,IAAA,CAAM,CAAE,MAAA,CAAQS,CAAAA,CAAK,MAAA,CAAQ,GAAA,CAAAuE,CAAI,CACrC,CAAC,EAET,CACJ,CACJ,CACJ,CAAA,CAEOkK,EAAAA,CAAQ,IAAID,EAAAA,CC1FnB,IAAME,EAAAA,CAAN,cAA4BtQ,CAAmC,CAClD,IAAA,CAAO,iBAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,IAAA,CAAM,CACF,WAAA,CAAa,oDAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,OACd,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,UAAA,CAAYG,CAAAA,CAAQ,CAChB,OAAA,CAAS,iDAAA,CACT,GAAA,CAAK,wIAAA,CACL,GAAA,CAAK,2GACT,CAAC,CACL,CACJ,CAAA,CAEA,OAAOF,CAAAA,CAAqF,CACxF,OAAO,CACH,sBAAA,CAAuBO,CAAAA,CAAM,CAGrBA,CAAAA,CAAK,UAAA,CAAW,IAAA,GAAS,oBAAA,EACzBP,CAAAA,CAAQ,UAAA,CAAW,iBAAA,CAAkBO,CAAI,CAAA,CAAE,MAAA,GAAW,CAAA,EAE1DP,CAAAA,CAAQ,MAAA,CAAO,CAAE,IAAA,CAAAO,CAAAA,CAAM,SAAA,CAAW,YAAa,CAAC,EACpD,CACJ,CACJ,CACJ,CAAA,CAEO+P,EAAAA,CAAQ,IAAID,EAAAA,CCnCnB,IAAME,EAAAA,CAAN,cAA4CxQ,CAAmC,CAClE,IAAA,CAAO,kCAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,IAAA,CAAM,CACF,WAAA,CAAa,mEAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,OACd,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,WAAA,CAAaG,CAAAA,CAAQ,CACjB,QAAS,oDAAA,CACT,GAAA,CAAK,2HAAA,CACL,GAAA,CAAK,oEACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAAqF,CACxF,OAAO,CACH,kBAAA,CAAmBO,CAAAA,CAAM,CACjBA,CAAAA,CAAK,EAAA,CAAG,IAAA,GAAS,YAAA,EAAgBA,CAAAA,CAAK,IAAA,EAAM,IAAA,GAAS,gBAAA,EACrDA,CAAAA,CAAK,IAAA,CAAK,MAAA,CAAO,IAAA,GAAS,YAAA,EAAgB,CAACmN,EAAAA,CAAkBnN,CAAAA,CAAK,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA,EAEtFP,CAAAA,CAAQ,MAAA,CAAO,CACX,IAAA,CAAAO,CAAAA,CACA,SAAA,CAAW,aAAA,CACX,IAAA,CAAM,CAAE,IAAA,CAAMA,CAAAA,CAAK,IAAA,CAAK,MAAA,CAAO,IAAA,CAAM,IAAA,CAAMA,CAAAA,CAAK,EAAA,CAAG,IAAK,CAC5D,CAAC,EACL,CACJ,CACJ,CACJ,CAAA,CAEOiQ,EAAAA,CAAQ,IAAID,GCrCnB,IAAME,EAAAA,CAAN,cAAoC1Q,CAAmC,CAC1D,IAAA,CAAO,yBAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,IAAA,CAAM,CACF,WAAA,CAAa,6EAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,OACd,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,OAAA,CAASG,CAAAA,CAAQ,CACb,OAAA,CAAS,yDACT,GAAA,CAAK,kJAAA,CACL,GAAA,CAAK,iGACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAAqF,CACxF,OAAO,CACH,kBAAA,CAAmBO,CAAAA,CAAM,CAErB,GADIA,CAAAA,CAAK,MAAA,CAAO,IAAA,GAAS,qBAAA,EAAyBA,CAAAA,CAAK,MAAA,CAAO,IAAA,GAAS,OAAA,EACnEA,CAAAA,CAAK,EAAA,CAAG,IAAA,GAAS,YAAA,EAAgBA,CAAAA,CAAK,IAAA,GAAS,IAAA,CAAM,OAGzD,IAAMgK,CAAAA,CAAKM,EAAAA,CAAkBtK,CAAI,CAAA,CAC7BgK,CAAAA,GAAO,IAAA,EAAQ,CAACuD,EAAAA,CAAkBvD,CAAAA,CAAIvK,CAAAA,CAAQ,UAAA,CAAW,WAAW,CAAA,EAEnEgO,EAAAA,CAAezN,CAAAA,CAAK,IAAA,CAAMP,CAAAA,CAAQ,UAAA,CAAW,WAAW,CAAA,EAE7DA,CAAAA,CAAQ,MAAA,CAAO,CAAE,IAAA,CAAAO,CAAAA,CAAM,SAAA,CAAW,SAAU,CAAC,EACjD,CACJ,CACJ,CACJ,CAAA,CAEOmQ,EAAAA,CAAQ,IAAID,EAAAA,CCxCnB,IAAME,EAAAA,CAAN,cAAsC5Q,CAAmC,CAC5D,IAAA,CAAO,4BAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,OAAA,CAAS,MAAA,CACT,IAAA,CAAM,CACF,WAAA,CAAa,wEAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,OACd,CAAA,CACA,MAAA,CAAQ,EAAC,CACT,QAAA,CAAU,CACN,YAAA,CAAcG,CAAAA,CAAQ,CAClB,OAAA,CAAS,yDAAA,CACT,GAAA,CAAK,8HAAA,CACL,GAAA,CAAK,qEACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAAqF,CAOxF,IAAM4Q,CAAAA,CAAmBrF,CAAAA,EAA2C,CAChE,GAAIoC,EAAAA,CAAgBpC,CAAQ,CAAA,CAAG,OAAO,KAAA,CACtC,GAAIA,CAAAA,CAAS,IAAA,GAAS,YAAA,CAAc,OAAO,MAAA,CAG3C,IAAMsF,CAAAA,CADWzJ,QAAAA,CAAS,YAAA,CAAapH,CAAAA,CAAQ,UAAA,CAAW,QAAA,CAASuL,CAAQ,CAAA,CAAGA,CAAAA,CAAS,IAAI,CAAA,EAC9D,IAAA,CAAK,EAAA,CAAG,EAAE,CAAA,EAAG,IAAA,CAC1C,OAAOsF,CAAAA,EAAY,IAAA,GAAS,oBAAA,EAAwBlD,EAAAA,CAAgBkD,CAAAA,CAAW,IAAI,CACvF,CAAA,CAMMrK,CAAAA,CAAU+E,GAAwC,CACpDvL,CAAAA,CAAQ,MAAA,CAAO,CACX,IAAA,CAAMuL,CAAAA,CACN,SAAA,CAAW,cAAA,CACX,GAAA,CACIA,CAAAA,CAAS,IAAA,GAAS,YAAA,CACZ5C,CAAAA,EAASA,CAAAA,CAAM,WAAA,CAAY4C,CAAAA,CAAU,CAAA,EAAA,EAAKA,CAAAA,CAAS,IAAI,CAAA,EAAA,CAAI,CAAA,CAC3D,MACd,CAAC,EACL,CAAA,CAMMK,CAAAA,CAASrB,CAAAA,EAA2B,CACtC,IAAMrG,CAAAA,CAAO6G,CAAAA,CAAgBR,CAAE,CAAA,CAC/B,GAAI,EAAArG,CAAAA,GAAS,MAAA,EAAa,CAACuJ,CAAAA,CAAWvJ,CAAI,CAAA,CAAA,CAG1C,CAAA,GAAIqG,CAAAA,CAAG,IAAA,GAAS,yBAAA,EAA6BA,CAAAA,CAAG,IAAA,CAAK,IAAA,GAAS,gBAAA,CAAkB,CACxEqG,CAAAA,CAAgBrG,CAAAA,CAAG,IAAI,CAAA,EAAG/D,CAAAA,CAAO+D,CAAAA,CAAG,IAAI,CAAA,CAC5C,MACJ,CAEAS,CAAAA,CAAWT,CAAAA,CAAG,IAAA,CAAMvK,CAAAA,CAAQ,WAAW,WAAA,CAAauL,CAAAA,GAC5CA,CAAAA,GAAa,IAAA,EAAQqF,CAAAA,CAAgBrF,CAAQ,CAAA,EAAG/E,CAAAA,CAAO+E,CAAQ,CAAA,CAC5D,KAAA,CACV,EAAA,CACL,CAAA,CAEA,OAAO,CACH,mBAAA,CAAoBhL,CAAAA,CAAM,CACtBqL,CAAAA,CAAMrL,CAAI,EACd,CAAA,CACA,kBAAA,CAAmBA,CAAAA,CAAM,CACrBqL,CAAAA,CAAMrL,CAAI,EACd,CAAA,CACA,uBAAA,CAAwBA,CAAAA,CAAM,CAC1BqL,EAAMrL,CAAI,EACd,CACJ,CACJ,CACJ,CAAA,CAEOuQ,EAAAA,CAAQ,IAAIH,EAAAA,CCxFnB,IAAMI,EAAAA,CAAN,cAAuChR,CAAmC,CAC7D,IAAA,CAAO,6BAAA,CAEP,cAAA,CAA0B,EAAC,CAE3B,IAAA,CAAO,CACZ,IAAA,CAAM,YAAA,CACN,IAAA,CAAM,CACF,WAAA,CAAa,2FAAA,CACb,WAAA,CAAa,IAAA,CACb,QAAA,CAAU,OACd,CAAA,CACA,OAAQ,EAAC,CACT,QAAA,CAAU,CACN,YAAA,CAAcG,CAAAA,CAAQ,CAClB,OAAA,CAAS,+BAAA,CACT,GAAA,CAAK,6GAAA,CACL,GAAA,CAAK,4CACT,CAAC,CAAA,CACD,YAAA,CAAcA,CAAAA,CAAQ,CAClB,OAAA,CAAS,gFAAA,CACT,GAAA,CAAK,0FAAA,CACL,GAAA,CAAK,yDACT,CAAC,CACL,CACJ,CAAA,CAEA,MAAA,CAAOF,CAAAA,CAAqF,CACxF,OAAO,CACH,kBAAA,CAAmBO,CAAAA,CAAM,CAErB,GADIA,CAAAA,CAAK,IAAA,EAAM,IAAA,GAAS,gBAAA,EAAoBA,CAAAA,CAAK,IAAA,CAAK,MAAA,CAAO,IAAA,GAAS,YAAA,EAClE,CAACX,CAAAA,CAAU,KAAA,CAAM,UAAA,CAAW,GAAA,CAAIW,CAAAA,CAAK,IAAA,CAAK,MAAA,CAAO,IAAI,CAAA,CAAG,OAG5D,IAAImH,CAAAA,CAAwBnH,CAAAA,CAAK,MAAA,CAGjC,GAFImH,CAAAA,CAAO,MAAA,EAAQ,OAAS,wBAAA,GAA0BA,CAAAA,CAASA,CAAAA,CAAO,MAAA,CAAA,CAElE,CAACpD,CAAAA,CAAgBtE,CAAAA,CAAQ,UAAA,CAAY0H,CAAM,CAAA,CAAG,CAC9C1H,CAAAA,CAAQ,MAAA,CAAO,CACX,IAAA,CAAMO,CAAAA,CAAK,EAAA,CACX,SAAA,CAAW,cAAA,CACX,IAAA,CAAM,CAAE,IAAA,CAAMA,CAAAA,CAAK,IAAA,CAAK,MAAA,CAAO,IAAK,CACxC,CAAC,CAAA,CACD,MACJ,CAEA,GAAIA,EAAK,IAAA,CAAK,MAAA,CAAO,IAAA,GAAS,aAAA,CAAe,OAE7C,IAAME,CAAAA,CAAWF,CAAAA,CAAK,IAAA,CAAK,SAAA,CAAU,CAAC,CAAA,CAEtC,GADIE,CAAAA,EAAU,IAAA,GAAS,yBAAA,EAA6BA,CAAAA,EAAU,IAAA,GAAS,oBAAA,EACnEA,CAAAA,CAAS,MAAA,CAAO,MAAA,GAAW,CAAA,CAAG,OAAA,CAElBT,CAAAA,CAAQ,UAAA,CAAW,iBAAA,CAAkB0H,CAAM,CAAA,CAAE,EAAA,CAAG,EAAE,CAAA,EACrC,MAAM,KAAA,CAAM;AAAA,CAAI,GAAK,EAAC,EAAG,OAClDlF,CAAAA,EAAQ6B,CAAAA,CAAgB7B,CAAI,CAAA,GAAM,OACtC,EAAE,MAAA,CAEe/B,CAAAA,CAAS,OAAO,MAAA,EAC7BT,CAAAA,CAAQ,OAAO,CAAE,IAAA,CAAMO,EAAK,EAAA,CAAI,SAAA,CAAW,cAAe,CAAC,EAEnE,CACJ,CACJ,CACJ,CAAA,CAEOyQ,EAAAA,CAAQ,IAAID,EAAAA,CCzCnB,IAAME,GAAgB,CAClBzP,EAAAA,CACAwD,GACAE,EAAAA,CACAY,EAAAA,CACAE,GACAI,EAAAA,CACAS,EAAAA,CACAiB,GACAc,EAAAA,CACAK,EAAAA,CACAc,EAAAA,CACAE,EAAAA,CACAI,GACA2B,EAAAA,CACAG,EAAAA,CACAI,GACAK,EAAAA,CACAE,EAAAA,CACAE,GACAI,EAAAA,CACAG,EAAAA,CACAe,GACAU,EAAAA,CACAW,EAAAA,CACAL,GACAY,EAAAA,CACAE,EAAAA,CACAE,GACAE,EAAAA,CACAE,EAAAA,CACAI,GACAE,EACJ,CAAA,CAKaE,EAAQ,MAAA,CAAO,WAAA,CAAYD,GAAc,GAAA,CAAIE,CAAAA,EAAQ,CAACA,CAAAA,CAAK,IAAA,CAAMA,EAAK,YAAA,EAAc,CAAC,CAAC,CAAA,CClE5F,SAASC,CAAAA,CAAc9P,CAAAA,CAAmD,CAC7E,IAAMwN,CAAAA,CAAqC,EAAC,CAE5C,IAAA,GAAW,CAAC5K,CAAAA,CAAMiN,CAAI,CAAA,GAAK,MAAA,CAAO,QAAQD,CAAK,CAAA,CAAA,CACtCC,EAAK,IAAA,CAAK,IAAA,EAAM,UAAY,MAAA,IAAY7P,CAAAA,GACzCwN,EAAQ,CAAA,EAAGlP,CAAAA,CAAU,WAAW,CAAA,CAAA,EAAIsE,CAAI,EAAE,CAAA,CAAI,MAAA,CAAA,CAItD,OAAO4K,CACX,CAMO,SAASuC,EAAAA,EAAsC,CAClD,IAAMvC,CAAAA,CAAqC,GAE3C,IAAA,IAAW5K,CAAAA,IAAQ,OAAO,IAAA,CAAKgN,CAAK,EAChCpC,CAAAA,CAAQ,CAAA,EAAGlP,EAAU,WAAW,CAAA,CAAA,EAAIsE,CAAI,CAAA,CAAE,CAAA,CAAI,MAAA,CAGlD,OAAO4K,CACX,CCxBO,SAASwC,GAAIC,CAAAA,CAAgE,CAChF,OAAO,CACH,IAAA,CAAM,GAAG3R,CAAAA,CAAU,WAAW,OAC9B,OAAA,CAAS,CAAE,CAACA,CAAAA,CAAU,WAAW,EAAG2R,CAAO,CAAA,CAC3C,SAAU,CAAE,CAAC3R,EAAU,WAAW,EAAG,CAAE,QAAA,CAAU,IAAA,CAAM,MAAO,IAAK,CAAE,EACrE,KAAA,CAAOyR,EAAAA,EACX,CACJ,CCRO,SAAS/O,CAAAA,CAAKiP,CAAAA,CAAgE,CACjF,OAAO,CACH,IAAA,CAAM,CAAA,EAAG3R,EAAU,WAAW,CAAA,KAAA,CAAA,CAC9B,QAAS,CAAE,CAACA,EAAU,WAAW,EAAG2R,CAAO,CAAA,CAC3C,KAAA,CAAOH,EAAc,MAAM,CAC/B,CACJ,CCNO,SAASI,GAAYD,CAAAA,CAAgE,CACxF,OAAO,CACH,GAAGjP,EAAKiP,CAAM,CAAA,CACd,KAAM,CAAA,EAAG3R,CAAAA,CAAU,WAAW,CAAA,YAAA,CAClC,CACJ,CCVA,IAAM6R,EAAAA,CAAmB,CAAC,oBAAA,CAAsB,yBAAyB,EASlE,SAASC,EAAAA,CAASH,EAAgE,CACrF,OAAO,CACH,IAAA,CAAM,GAAG3R,CAAAA,CAAU,WAAW,YAC9B,OAAA,CAAS,CAAE,CAACA,CAAAA,CAAU,WAAW,EAAG2R,CAAO,CAAA,CAC3C,SAAU,CAAE,CAAC3R,EAAU,WAAW,EAAG,CAAE,QAAA,CAAU,IAAK,CAAE,CAAA,CACxD,KAAA,CAAO,CACH,GAAGwR,CAAAA,CAAc,UAAU,CAAA,CAC3B,CAAC,GAAGxR,CAAAA,CAAU,WAAW,mCAAmC,EAAG,CAAC,OAAQ,CAAE,OAAA,CAAS6R,EAAiB,CAAC,CACzG,CACJ,CACJ,CCdO,SAASE,EAAAA,CAAMJ,EAAgE,CAClF,OAAO,CACH,IAAA,CAAM,CAAA,EAAG3R,EAAU,WAAW,CAAA,MAAA,CAAA,CAC9B,QAAS,CAAE,CAACA,EAAU,WAAW,EAAG2R,CAAO,CAAA,CAC3C,QAAA,CAAU,CAAE,CAAC3R,CAAAA,CAAU,WAAW,EAAG,CAAE,MAAO,IAAK,CAAE,EACrD,KAAA,CAAOwR,CAAAA,CAAc,OAAO,CAChC,CACJ,CCFO,SAASQ,EAAAA,CAAaL,EAAgF,CACzG,OAAO,CACH,IAAA,CAAMjP,CAAAA,CAAKiP,CAAM,CAAA,CACjB,WAAA,CAAaC,EAAAA,CAAYD,CAAM,EAC/B,QAAA,CAAUG,EAAAA,CAASH,CAAM,CAAA,CACzB,KAAA,CAAOI,GAAMJ,CAAM,CAAA,CACnB,IAAKD,EAAAA,CAAIC,CAAM,CACnB,CACJ,CCpBE,IAAAM,EAAAA,CAAW,OAAA,CCQb,IAAMN,EAAAA,CAAqC,CACvC,KAAM,CACF,IAAA,CAAM,iBAAiB3R,CAAAA,CAAU,WAAW,GAC5C,OAAA,CAAAiS,EACJ,EACA,KAAA,CAAAX,CAAAA,CACA,QAAS,EACb,EAGAK,EAAAA,CAAO,OAAA,CAAUK,GAAaL,EAAM,CAAA,KAE7BO,EAAAA,CAAQP","file":"index.js","sourcesContent":["/**\n * The global set of constants shared across the plugin, grouped by domain.\n */\nconst CONSTANTS = {\n /**\n * The short name the plugin is registered under inside an ESLint config,\n * e.g. `nitpicker/no-em-dash`.\n */\n PLUGIN_NAME: \"nitpicker\",\n\n /**\n * The base URL of the plugin's repository.\n */\n REPO_URL: \"https://github.com/Alien-Intelligence/eslint-plugin-nitpicker\",\n\n /**\n * The em dash character (U+2014), e.g. \"—\".\n */\n EM_DASH: \"—\",\n\n /**\n * Matches a single emoji as one unit: flag pairs, skin-tone and\n * variation-selector modifiers, and ZWJ sequences. Text-default pictographs\n * like © match only when emoji-styled with a variation selector.\n */\n EMOJI: /\\p{Regional_Indicator}\\p{Regional_Indicator}|\\p{Emoji_Presentation}(?:\\uFE0F|\\p{Emoji_Modifier})?(?:\\u200D\\p{Emoji_Presentation}(?:\\uFE0F|\\p{Emoji_Modifier})?)*|\\p{Extended_Pictographic}\\uFE0F/gu,\n\n /**\n * Constants for scanning comments.\n */\n COMMENTS: {\n /**\n * Box-drawing and block-element characters, which are always decorative\n * when found inside a comment.\n */\n BOX_DRAWING: /[─-▟]/,\n\n /**\n * A comment line made entirely of three or more repeated separator\n * characters, e.g. `======` or `------`.\n */\n PURE_SEPARATOR: /^[-=~*#_+]{3,}$/,\n\n /**\n * A short label fenced by separator runs inside a comment, e.g `-- Section --`.\n */\n WRAPPED_LABEL: /^[-=~*#_+]{2,}\\s.*\\s[-=~*#_+]{2,}$/,\n\n /**\n * A tooling directive comment (eslint, ts-, biome-ignore, etc.) rather\n * than prose, matched against the comment text.\n */\n DIRECTIVE:\n /^\\s*(?:eslint\\b|eslint-|globals?\\b|exported\\b|jshint\\b|jslint\\b|istanbul\\b|[cv]8\\b|ts-|prettier-ignore|biome-ignore|webpack\\b|noinspection\\b|@)/,\n\n /**\n * Quote characters that fence a verbatim span inside a comment, whose\n * dots belong to the quoted text rather than the surrounding prose. The\n * apostrophe is absent, as it appears unpaired in words like \"don't\".\n */\n QUOTES: new Set(['\"', \"`\"]),\n\n /**\n * Abbreviations whose trailing dot is part of the word itself, so it must\n * survive even though it looks like the end of a sentence.\n */\n ABBREVIATIONS: [\"e.g.\", \"i.e.\", \"etc.\", \"vs.\", \"cf.\", \"al.\", \"approx.\", \"resp.\"],\n\n /**\n * The default maximum prose length of a run of consecutive line comments,\n * tighter than a JSDoc description since a stacked wall reads worse.\n */\n MAX_RUN_LENGTH: 200,\n },\n\n /**\n * Constants for inspecting JSDoc structure.\n */\n JSDOC: {\n /**\n * Matches a JSDoc block-tag line, capturing the tag name so callers can\n * find any tag (`param`, `returns`, `throws`, etc.).\n */\n TAG: /^\\s*\\*?\\s*@(\\w+)/,\n\n /**\n * Matches an `@param` line and captures the documented name, tolerating a\n * leading `{Type}` and an optional `[name]` or `[name=default]` form. A\n * dotted member such as `input.id` captures its root, `input`.\n */\n PARAM_TAG: /^\\s*\\*?\\s*@param\\s+(?:\\{[^}]*\\}\\s*)?\\[?([\\w$]+)/,\n\n /**\n * The default maximum character length of a JSDoc description.\n */\n MAX_DESCRIPTION_LENGTH: 250,\n },\n\n /**\n * Constants for splitting and inspecting words.\n */\n WORDS: {\n /**\n * Matches a single \"word\" character, i.e. anything that can appear inside\n * an identifier or a number (letters, digits, underscore and dollar).\n */\n WORD_CHAR: /[\\p{L}\\p{N}_$]/u,\n\n /**\n * Matches a single sub-word: an all-caps acronym, a capitalized word, or a\n * lowercase run, so `getUserName` splits into \"get\", \"User\" and \"Name\"\n */\n SUB_WORD: /[A-Z]+(?![a-z])|[A-Z][a-z]+|[a-z]+/g,\n },\n\n /**\n * Constants for object literals.\n */\n OBJECTS: {\n /**\n * The default maximum number of properties an object literal may keep on\n * a single line before it must be broken across multiple lines.\n */\n MAX_INLINE_KEYS: 2,\n\n /**\n * The default number of spaces per indentation level used when expanding\n * an object literal across multiple lines.\n */\n INDENT_WIDTH: 4,\n },\n\n /**\n * Constants for inspecting functions.\n */\n FUNCTIONS: {\n /**\n * The AST node types that introduce a new function scope.\n */\n NODE_TYPES: new Set([\"FunctionDeclaration\", \"FunctionExpression\", \"ArrowFunctionExpression\"]),\n },\n\n /**\n * Constants for detecting framework usage.\n */\n FRAMEWORKS: {\n /**\n * AdonisJS subpath import roots (`#models/...`, `#controllers/...`, etc.).\n */\n ADONIS_SUBPATH:\n /^#(models|controllers|services|middleware|validators|policies|config|start|database|providers|lib)\\b/,\n\n /**\n * React source files by extension.\n */\n REACT_FILE: /\\.[jt]sx$/,\n },\n\n /**\n * Constants for React semantics.\n */\n REACT: {\n /**\n * A React hook name: `use` followed by a capitalized word, e.g.\n * `useState` or `useMenuActions`.\n */\n HOOK: /^use[A-Z]/,\n\n /**\n * A context-consumer hook name, i.e. a `use…Context` wrapper such as\n * `useTreeViewContext` (the bare `useContext` is excluded).\n */\n CONTEXT_HOOK: /^use[A-Z]\\w*Context$/,\n\n /**\n * The memoization hooks whose result is worth documenting with a JSDoc.\n */\n MEMO_HOOKS: new Set([\"useMemo\", \"useCallback\"]),\n\n /**\n * The default maximum length of a `className` class string.\n */\n MAX_CLASSNAME_LENGTH: 120,\n },\n\n /**\n * Constants for AdonisJS request handling.\n */\n REQUEST: {\n /**\n * The raw request accessors that read request data directly, bypassing\n * the Vine validator contract.\n */\n RAW_ACCESSORS: new Set([\"input\", \"body\", \"qs\", \"all\", \"only\", \"except\"]),\n },\n\n /**\n * Constants for AdonisJS migrations.\n */\n MIGRATIONS: {\n /**\n * Table-builder methods that declare an index or a constraint.\n */\n INDEX_METHODS: new Set([\"index\", \"unique\", \"primary\", \"foreign\"]),\n\n /**\n * Table-builder methods that declare a timestamp column.\n */\n TIMESTAMP_METHODS: new Set([\"timestamp\", \"dateTime\", \"datetime\"]),\n\n /**\n * Audit timestamp column names that form a migration's dedicated\n * timestamps group.\n */\n AUDIT_TIMESTAMPS: new Set([\"created_at\", \"updated_at\", \"deleted_at\"]),\n\n /**\n * The order table statements must be grouped in: columns first, then\n * timestamps, then indexes and constraints.\n */\n CATEGORY_ORDER: [\"column\", \"timestamp\", \"index\"],\n },\n} as const\n\nexport default CONSTANTS\n","import { ESLintUtils } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\n\n/**\n * The category a rule belongs to, which decides the shared config it ships in.\n */\nexport type RuleCategory = \"base\" | \"adonisjs\" | \"react\"\n\n/**\n * Extra metadata attached to every Nitpicker rule under `meta.docs`.\n */\nexport type NitpickerRuleDocs = {\n /**\n * A short, human-readable description of what the rule enforces.\n */\n description: string\n\n /**\n * Whether the rule is part of the `recommended` shared config.\n */\n recommended?: boolean\n\n /**\n * The category the rule belongs to, defaults to `base` when omitted.\n */\n category?: RuleCategory\n}\n\n/**\n * The shared rule factory for the whole plugin.\n */\nexport const createRule = ESLintUtils.RuleCreator<NitpickerRuleDocs>(\n () => `${CONSTANTS.REPO_URL}/blob/main/README.md#rules`,\n)\n","import { ESLintUtils, type TSESLint } from \"@typescript-eslint/utils\"\nimport { createRule, type NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\n/**\n * The base class every Nitpicker rule extends, so a rule only declares its name,\n * metadata, options, and visitor logic. Call {@link toRuleModule} to turn an\n * instance into the plain object ESLint expects.\n */\nexport abstract class NitpickerRule<MessageIds extends string = string, Options extends readonly unknown[] = []> {\n /**\n * The kebab-case name of the rule, without the plugin prefix\n * (e.g. `no-em-dash`).\n */\n abstract readonly name: string\n\n /**\n * The ESLint metadata describing the rule (type, docs, schema, messages).\n */\n abstract readonly meta: ESLintUtils.NamedCreateRuleMeta<MessageIds, NitpickerRuleDocs, Options>\n\n /**\n * The options applied when the rule is enabled without an explicit config.\n */\n abstract readonly defaultOptions: Options\n\n /**\n * The visitor factory ESLint calls for every linted file.\n * @param context The rule context for the current file.\n * @param options The user options merged with {@link defaultOptions}.\n * @returns The AST visitor listeners.\n */\n abstract create(\n context: Readonly<TSESLint.RuleContext<MessageIds, Options>>,\n options: Readonly<Options>,\n ): TSESLint.RuleListener\n\n /**\n * Builds the ESLint-compatible rule module from this instance.\n * @returns The plain rule module object consumed by ESLint.\n */\n toRuleModule(): TSESLint.RuleModule<MessageIds, Options, NitpickerRuleDocs> {\n return createRule<Options, MessageIds>({\n name: this.name,\n meta: this.meta,\n defaultOptions: this.defaultOptions,\n create: (context, options) => this.create(context, options),\n })\n }\n}\n","/**\n * The building blocks of a Nitpicker message.\n */\nexport type Nitpick = {\n /**\n * What is wrong, stated plainly, may contain ESLint `{{placeholders}}`.\n */\n problem: string\n\n /**\n * Why it is worth fixing, so the reader understands the intent.\n */\n why: string\n\n /**\n * A concrete, actionable instruction describing how to fix it.\n */\n fix: string\n}\n\n/**\n * Composes a {@link Nitpick} into one message string for a rule's\n * `meta.messages` entry, leaving any ESLint `{{placeholders}}` intact.\n * @param nitpick The problem/why/fix triplet to format.\n * @returns The formatted, multi-line message.\n */\nexport function nitpick({ problem, why, fix }: Nitpick): string {\n return `${problem}\\n - why: ${why}\\n - fix: ${fix}`\n}\n","import type { TSESTree } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\n\n/**\n * A category a `createTable` builder statement falls into, used to keep a\n * migration's columns, timestamps, and indexes grouped in that order.\n */\nexport type TableCategory = \"column\" | \"timestamp\" | \"index\"\n\n/**\n * Checks whether a class is an AdonisJS migration, i.e. a default-exported class\n * that extends `BaseSchema`.\n * @param node The class declaration to inspect.\n * @returns True if the class is a migration.\n */\nexport function isMigrationClass(node: TSESTree.ClassDeclaration): boolean {\n return (\n node.parent.type === \"ExportDefaultDeclaration\" &&\n node.superClass?.type === \"Identifier\" &&\n node.superClass.name === \"BaseSchema\"\n )\n}\n\n/**\n * Resolves the `this.schema.createTable(name, builder => { ... })` builder body\n * from a call expression, if the call is one.\n * @param node The call expression to inspect.\n * @returns The builder statements and parameter name, or `null`.\n */\nexport function getCreateTableBuilder(node: TSESTree.CallExpression): {\n body: TSESTree.Statement[]\n builderName: string\n} | null {\n if (node.callee.type !== \"MemberExpression\" || node.callee.property.type !== \"Identifier\") return null\n if (node.callee.property.name !== \"createTable\") return null\n\n // Require a schema receiver so only Lucid migration calls match\n if (node.callee.object.type !== \"MemberExpression\" || node.callee.object.property.type !== \"Identifier\") return null\n if (node.callee.object.property.name !== \"schema\") return null\n\n const callback = node.arguments.at(-1)\n if (callback?.type !== \"ArrowFunctionExpression\" && callback?.type !== \"FunctionExpression\") return null\n if (callback.body.type !== \"BlockStatement\" || callback.params[0]?.type !== \"Identifier\") return null\n\n return { body: callback.body.body, builderName: callback.params[0].name }\n}\n\n/**\n * Resolves the category of a single `createTable` builder statement.\n * @param statement The statement to categorize.\n * @param builderName The name of the table builder parameter.\n * @returns The category, or `null` when the statement is not ordered: either it\n * is not a builder call, or it is a domain timestamp such as `expires_at`, which\n * reads fine among the columns or beside the audit timestamps.\n */\nexport function getTableStatementCategory(statement: TSESTree.Statement, builderName: string): TableCategory | null {\n if (statement.type !== \"ExpressionStatement\") return null\n\n const root = rootBuilderCall(statement.expression, builderName)\n if (root === null) return null\n\n if (CONSTANTS.MIGRATIONS.INDEX_METHODS.has(root.method)) return \"index\"\n if (root.method === \"timestamps\") return \"timestamp\"\n\n if (CONSTANTS.MIGRATIONS.TIMESTAMP_METHODS.has(root.method)) {\n if (root.firstArgument !== undefined && CONSTANTS.MIGRATIONS.AUDIT_TIMESTAMPS.has(root.firstArgument)) {\n return \"timestamp\"\n }\n\n // A domain timestamp carries meaning of its own rather than tracking a\n // row's lifecycle, so it is not forced into either group\n return null\n }\n\n return \"column\"\n}\n\n/**\n * Walks a chained builder expression down to the first call on the builder, e.g.\n * `table.integer(\"x\").notNullable()` resolves to `integer` with argument `\"x\"`.\n * @param expression The (possibly chained) expression to walk.\n * @param builderName The name of the table builder parameter.\n * @returns The base method and its first string argument, or `null`.\n */\nfunction rootBuilderCall(\n expression: TSESTree.Expression,\n builderName: string,\n): { method: string; firstArgument: string | undefined } | null {\n let current: TSESTree.Node = expression\n\n while (current.type === \"CallExpression\" && current.callee.type === \"MemberExpression\") {\n if (current.callee.object.type === \"Identifier\" && current.callee.object.name === builderName) {\n if (current.callee.property.type !== \"Identifier\") return null\n\n const firstArgument = current.arguments[0]\n const literal =\n firstArgument?.type === \"Literal\" && typeof firstArgument.value === \"string\"\n ? firstArgument.value\n : undefined\n\n return { method: current.callee.property.name, firstArgument: literal }\n }\n\n current = current.callee.object\n }\n\n return null\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { getCreateTableBuilder, getTableStatementCategory } from \"@/lib/utils/migrations\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"outOfOrder\"\n\n/**\n * Enforces that a migration's `createTable` statements stay grouped in order:\n * columns, then audit timestamps, then indexes and constraints, this keeps every\n * migration structured the same way without needing section-label comments.\n */\nclass MigrationTableOrder extends NitpickerRule<MessageIds, Options> {\n readonly name = \"migration-table-order\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Group migration table statements as columns, then timestamps, then indexes and constraints.\",\n recommended: true,\n category: \"adonisjs\",\n },\n schema: [],\n messages: {\n outOfOrder: nitpick({\n problem: \"This {{category}} is out of order in the table definition.\",\n why: \"A migration reads consistently when columns come first, then timestamps, then indexes and constraints, each grouped together\",\n fix: \"Move it into its group so the order stays columns, timestamps, then indexes and constraints\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n CallExpression(node) {\n const builder = getCreateTableBuilder(node)\n if (builder === null) return\n\n let maxRank = 0\n\n for (const statement of builder.body) {\n const category = getTableStatementCategory(statement, builder.builderName)\n if (category === null) continue\n\n const rank = CONSTANTS.MIGRATIONS.CATEGORY_ORDER.indexOf(category)\n if (rank < maxRank) {\n context.report({\n node: statement,\n messageId: \"outOfOrder\",\n data: { category },\n })\n }\n\n maxRank = Math.max(maxRank, rank)\n }\n },\n }\n }\n}\n\nexport default new MigrationTableOrder()\n","import type { TSESTree } from \"@typescript-eslint/utils\"\n\n/**\n * Checks whether a class is an AdonisJS controller, i.e. a default-exported\n * class whose name ends with `Controller`.\n * @param node The class declaration to inspect.\n * @returns True if the class is a controller.\n */\nexport function isControllerClass(node: TSESTree.ClassDeclaration): boolean {\n return node.parent.type === \"ExportDefaultDeclaration\" && node.id?.name.endsWith(\"Controller\") === true\n}\n","import CONSTANTS from \"@/lib/constants\"\n\n/**\n * A sub-word found in a piece of text, with its start offset.\n */\nexport type Word = {\n /**\n * The sub-word, in its original casing.\n */\n text: string\n\n /**\n * The offset of the sub-word within the source text.\n */\n index: number\n}\n\n/**\n * Splits a piece of text into its sub-words, handling camelCase, PascalCase,\n * snake_case, and plain prose.\n * @param text The text to split.\n * @returns The sub-words found, each with its offset in the text.\n */\nexport function extractWords(text: string): Word[] {\n const words: Word[] = []\n\n for (const match of text.matchAll(CONSTANTS.WORDS.SUB_WORD)) {\n if (match.index !== undefined) {\n words.push({ text: match[0], index: match.index })\n }\n }\n\n return words\n}\n\n/**\n * Rewrites a replacement word to match the casing of the word it replaces, so a\n * capitalized source yields a capitalized result and an all-caps source an\n * all-caps one.\n * @param source The original word whose casing should be mirrored.\n * @param replacement The lowercase replacement word.\n * @returns The replacement, cased like the source.\n */\nexport function matchCase(source: string, replacement: string): string {\n if (source === source.toUpperCase()) {\n return replacement.toUpperCase()\n }\n\n if (source.charAt(0) === source.charAt(0).toUpperCase()) {\n return replacement.charAt(0).toUpperCase() + replacement.slice(1)\n }\n\n return replacement\n}\n\n/**\n * Checks whether a character is a \"word\" character, i.e. something that can\n * appear inside an identifier or a number (letters, digits, underscore, dollar).\n * @param char The single character to test, or `undefined` (e.g. past the end\n * of a string).\n * @returns True if the character is a word character, false otherwise.\n */\nexport function isWordChar(char: string | undefined): boolean {\n return char !== undefined && CONSTANTS.WORDS.WORD_CHAR.test(char)\n}\n","import type { TSESTree } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { isWordChar } from \"@/lib/utils/words\"\n\n/**\n * The first prose character of a comment, with its absolute source index.\n */\ntype CommentContent = { index: number; char: string }\n\n/**\n * A period inside a comment that punctuates prose rather than belonging to a\n * code token, with its absolute source index.\n */\nexport type ProsePeriod = {\n /**\n * The absolute source index of the period character.\n */\n index: number\n\n /**\n * Whether the period closes the comment, i.e. only whitespace follows it, so\n * removing it cannot run two sentences together.\n */\n terminal: boolean\n}\n\n/**\n * A backtick-fenced span inside a comment, with the absolute source indices of\n * its two backticks and the text they wrap.\n */\nexport type BacktickSpan = {\n /**\n * The absolute source index of the opening backtick.\n */\n start: number\n\n /**\n * The absolute source index of the closing backtick.\n */\n end: number\n\n /**\n * The text between the two backticks.\n */\n text: string\n}\n\n/**\n * Checks whether a comment is a tooling directive (eslint, `ts-`, biome-ignore,\n * etc.) rather than prose, which should not be treated as an English sentence.\n * @param comment The comment to test.\n * @returns True if the comment is a directive.\n */\nexport function isDirectiveComment(comment: TSESTree.Comment): boolean {\n return CONSTANTS.COMMENTS.DIRECTIVE.test(comment.value)\n}\n\n/**\n * Finds the first prose character of a comment, skipping the `//` or `/*`\n * delimiters and, for a block comment, the per-line ` * ` markers, so callers\n * can inspect where the comment's text actually begins.\n * @param comment The comment to inspect.\n * @returns The first content character and its source index, or `null` if the\n * comment has no textual content.\n */\nexport function firstCommentContentChar(comment: TSESTree.Comment): CommentContent | null {\n // Skip past the opening \"//\" or \"/*\" delimiter\n const base = comment.range[0] + 2\n\n if (comment.type === \"Line\") {\n const match = comment.value.match(/\\S/u)\n if (match?.index === undefined) return null\n\n return {\n index: base + match.index,\n char: match[0],\n }\n }\n\n let offset = 0\n for (const line of comment.value.split(\"\\n\")) {\n // Strip leading whitespace and a single \" * \" marker; whatever remains is\n // the line's content, so a marker-only line is skipped\n const markerLength = (line.match(/^\\s*\\*?\\s*/u)?.[0] ?? \"\").length\n const char = line.slice(markerLength).charAt(0)\n\n if (char !== \"\") {\n return {\n index: base + offset + markerLength,\n char,\n }\n }\n\n offset += line.length + 1\n }\n\n return null\n}\n\n/**\n * Finds the periods inside a `//` comment that punctuate prose, skipping the ones\n * that belong to a code token (`foo.bar`, `subagent.*`), sit inside a quoted\n * span, form an ellipsis, or close an abbreviation such as `e.g.`.\n * @param comment The line comment to scan.\n * @returns The prose periods found, in source order.\n */\nexport function findProsePeriods(comment: TSESTree.Comment): ProsePeriod[] {\n const periods: ProsePeriod[] = []\n\n // The comment value starts right after the leading \"//\"\n const base = comment.range[0] + 2\n let quote: string | null = null\n\n for (let index = 0; index < comment.value.length; index++) {\n const char = comment.value.charAt(index)\n\n // Inside a quoted span everything is verbatim until it closes\n if (quote !== null) {\n if (char === quote) quote = null\n continue\n }\n\n // Only open a span when it actually closes, so an unpaired quote does not\n // swallow the rest of the comment\n if (CONSTANTS.COMMENTS.QUOTES.has(char) && comment.value.includes(char, index + 1)) {\n quote = char\n continue\n }\n\n if (char !== \".\") continue\n\n // A run of consecutive dots is an ellipsis, leave it alone\n if (comment.value.charAt(index + 1) === \".\") {\n while (comment.value.charAt(index + 1) === \".\") index++\n continue\n }\n\n const rest = comment.value.slice(index + 1)\n\n // A dot is prose punctuation only when whitespace or the end of the\n // comment follows it, anything else makes it part of a token\n if (rest !== \"\" && !/^\\s/u.test(rest)) continue\n\n if (endsWithAbbreviation(comment.value.slice(0, index + 1))) continue\n\n periods.push({\n index: base + index,\n terminal: rest.trim() === \"\",\n })\n }\n\n return periods\n}\n\n/**\n * Finds the backtick-fenced spans inside a comment, skipping runs of backticks\n * (a code fence), an unpaired backtick, and any span already holding a double\n * quote, none of which survive being rewritten as a quoted span.\n * @param comment The comment to scan.\n * @returns The spans found, in source order.\n */\nexport function findBacktickSpans(comment: TSESTree.Comment): BacktickSpan[] {\n const spans: BacktickSpan[] = []\n\n // The comment value starts right after the leading \"//\"\n const base = comment.range[0] + 2\n\n for (let index = 0; index < comment.value.length; index++) {\n if (comment.value.charAt(index) !== \"`\") continue\n\n // A run of backticks fences a code block, which quotes cannot stand in for\n if (comment.value.charAt(index + 1) === \"`\") {\n while (comment.value.charAt(index + 1) === \"`\") index++\n continue\n }\n\n const closing = comment.value.indexOf(\"`\", index + 1)\n if (closing === -1) break\n\n const text = comment.value.slice(index + 1, closing)\n\n // Rewriting a span that already holds a double quote would nest quotes\n if (!text.includes('\"')) {\n spans.push({\n start: base + index,\n end: base + closing,\n text,\n })\n }\n\n index = closing\n }\n\n return spans\n}\n\n/**\n * Checks whether a piece of comment text ends with an abbreviation whose\n * trailing dot is part of the word, e.g. `e.g.` or `etc.`.\n * @param text The comment text up to and including the dot.\n * @returns True if the dot closes an abbreviation.\n */\nfunction endsWithAbbreviation(text: string): boolean {\n const lowercase = text.toLowerCase()\n\n return CONSTANTS.COMMENTS.ABBREVIATIONS.some(abbreviation => {\n if (!lowercase.endsWith(abbreviation)) return false\n\n // Require a boundary before the abbreviation so \"foo.al\" is not one\n const before = lowercase.charAt(lowercase.length - abbreviation.length - 1)\n return before === \"\" || !isWordChar(before)\n })\n}\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { isDirectiveComment } from \"@/lib/utils/comments\"\n\n/**\n * Checks whether a comment is a JSDoc comment, i.e. a block comment that opens\n * with `/**`.\n * @param comment The comment to test.\n * @returns True if the comment is a JSDoc block comment.\n */\nexport function isJSDocComment(comment: TSESTree.Comment): boolean {\n return comment.type === \"Block\" && comment.value.startsWith(\"*\")\n}\n\n/**\n * Resolves the node a JSDoc comment sits above, which for a decorated\n * declaration is its earliest decorator, since decorators are written between the\n * JSDoc and the declaration they belong to.\n * @param node The node to anchor the JSDoc lookup on.\n * @returns The node whose leading comments hold the JSDoc.\n */\nexport function jsDocAnchor(node: TSESTree.Node): TSESTree.Node {\n const declaration =\n (node.type === \"ExportDefaultDeclaration\" || node.type === \"ExportNamedDeclaration\") &&\n node.declaration !== null\n ? node.declaration\n : node\n\n const decorators = \"decorators\" in declaration ? declaration.decorators : undefined\n\n // Only a decorator written before the declaration shifts the anchor, the\n // \"export default @dec class\" form leaves the JSDoc above the export\n const earliest = decorators?.reduce<TSESTree.Decorator | undefined>(\n (found, decorator) => (found === undefined || decorator.range[0] < found.range[0] ? decorator : found),\n undefined,\n )\n\n return earliest !== undefined && earliest.range[0] < node.range[0] ? earliest : node\n}\n\n/**\n * Resolves the JSDoc comment documenting a node, if it has one.\n * @param sourceCode The source code of the linted file.\n * @param node The node to inspect the leading comments of.\n * @returns The JSDoc comment, or `null` when the node is undocumented.\n */\nexport function getLeadingJSDoc(\n sourceCode: Readonly<TSESLint.SourceCode>,\n node: TSESTree.Node,\n): TSESTree.Comment | null {\n const commentsBefore = sourceCode.getCommentsBefore(jsDocAnchor(node))\n\n // Skip trailing ignore directives (biome-ignore, eslint-*, @ts-*) that can\n // sit between the JSDoc and the node, so the JSDoc above them still counts\n let index = commentsBefore.length - 1\n while (index >= 0) {\n const comment = commentsBefore[index]\n if (comment === undefined || !isDirectiveComment(comment)) break\n index--\n }\n\n const closest = commentsBefore[index]\n return closest !== undefined && isJSDocComment(closest) ? closest : null\n}\n\n/**\n * Collects the parameter names a JSDoc documents, keyed on the root name so a\n * dotted member tag such as `@param input.id` counts as documenting `input`.\n * @param comment The JSDoc comment to read.\n * @returns The documented parameter names.\n */\nexport function getJSDocParamNames(comment: TSESTree.Comment): Set<string> {\n const names = new Set<string>()\n\n for (const line of comment.value.split(\"\\n\")) {\n const name = line.match(CONSTANTS.JSDOC.PARAM_TAG)?.[1]\n if (name !== undefined) names.add(name)\n }\n\n return names\n}\n\n/**\n * Checks whether a JSDoc carries a `@returns` (or `@return`) tag.\n * @param comment The JSDoc comment to read.\n * @returns True if the JSDoc documents a return value.\n */\nexport function hasJSDocReturnsTag(comment: TSESTree.Comment): boolean {\n return comment.value.split(\"\\n\").some(line => {\n const tag = getJSDocLineTag(line)\n return tag === \"returns\" || tag === \"return\"\n })\n}\n\n/**\n * Checks whether a node is immediately preceded by a JSDoc comment.\n * @param sourceCode The source code of the linted file.\n * @param node The node to inspect the leading comments of.\n * @returns True if the comment right before the node is a JSDoc comment.\n */\nexport function hasLeadingJSDoc(sourceCode: Readonly<TSESLint.SourceCode>, node: TSESTree.Node): boolean {\n return getLeadingJSDoc(sourceCode, node) !== null\n}\n\n/**\n * Checks whether a physical JSDoc line is blank, i.e. just a ` * ` with no\n * content after it.\n * @param line The physical source line to test.\n * @returns True if the line is an empty JSDoc line.\n */\nexport function isBlankJSDocLine(line: string): boolean {\n return /^\\s*\\*\\s*$/.test(line)\n}\n\n/**\n * Resolves the block-tag name a JSDoc line starts with, e.g. `param` or\n * `returns`, or `null` if the line is not a tag line.\n * @param line The physical source line to inspect.\n * @returns The tag name without its `@`, or `null`.\n */\nexport function getJSDocLineTag(line: string): string | null {\n const match = line.match(CONSTANTS.JSDOC.TAG)\n return match?.[1] ?? null\n}\n\n/**\n * Checks whether a physical JSDoc line holds a block tag, i.e. a ` * ` followed\n * by an `@tag` such as `@param` or `@returns`.\n * @param line The physical source line to test.\n * @returns True if the line starts a JSDoc tag.\n */\nexport function isJSDocTagLine(line: string): boolean {\n return getJSDocLineTag(line) !== null\n}\n\n/**\n * Extracts the description prose of a JSDoc comment, i.e. everything before the\n * first block tag, with the ` * ` markers stripped and wrapped lines joined into\n * a single space-separated string.\n * @param comment The JSDoc comment to read.\n * @returns The description as one collapsed prose string.\n */\nexport function getJSDocDescription(comment: TSESTree.Comment): string {\n const parts: string[] = []\n\n for (const line of comment.value.split(\"\\n\")) {\n const content = line.replace(/^\\s*\\*? ?/, \"\").trimEnd()\n if (content.startsWith(\"@\")) break\n\n parts.push(content)\n }\n\n return parts.join(\" \").replace(/\\s+/g, \" \").trim()\n}\n\n/**\n * Finds the source-line range of a JSDoc comment's `@returns` (or `@return`)\n * block, spanning the tag line down to the line before the next tag or the\n * closing `*/`.\n * @param sourceCode The source code of the linted file.\n * @param comment The JSDoc comment to inspect.\n * @returns The inclusive `from`/`to` source lines, or `null` if there is none.\n */\nexport function findJSDocReturnsRange(\n sourceCode: Readonly<TSESLint.SourceCode>,\n comment: TSESTree.Comment,\n): { from: number; to: number } | null {\n let tagLine = -1\n for (let line = comment.loc.start.line + 1; line < comment.loc.end.line; line++) {\n const tag = getJSDocLineTag(sourceCode.lines[line - 1] ?? \"\")\n if (tag === \"returns\" || tag === \"return\") {\n tagLine = line\n break\n }\n }\n\n if (tagLine === -1) return null\n\n let to = comment.loc.end.line - 1\n for (let line = tagLine + 1; line < comment.loc.end.line; line++) {\n if (isJSDocTagLine(sourceCode.lines[line - 1] ?? \"\")) {\n to = line - 1\n break\n }\n }\n\n return {\n from: tagLine,\n to,\n }\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { isControllerClass } from \"@/lib/utils/controllers\"\nimport { hasLeadingJSDoc } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"missingJSDoc\"\n\n/**\n * Requires a JSDoc comment above an AdonisJS controller (a default-exported\n * class whose name ends with `Controller`) so the responsibility it serves is\n * documented at a glance, before diving into its handler methods.\n */\nclass RequireControllerJSDoc extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-controller-jsdoc\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require a JSDoc comment describing an AdonisJS controller.\",\n recommended: true,\n category: \"adonisjs\",\n },\n schema: [],\n messages: {\n missingJSDoc: nitpick({\n problem: \"This controller has no JSDoc describing what it does.\",\n why: \"A controller's responsibility should be readable at a glance, before diving into its handler methods\",\n fix: \"Add a `/** ... */` JSDoc above the controller class summarizing what it handles\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n ClassDeclaration(node) {\n if (!isControllerClass(node)) return\n if (hasLeadingJSDoc(context.sourceCode, node.parent)) return\n\n context.report({ node: node.id ?? node, messageId: \"missingJSDoc\" })\n },\n }\n }\n}\n\nexport default new RequireControllerJSDoc()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { hasLeadingJSDoc } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { isMigrationClass } from \"@/lib/utils/migrations\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"missingJSDoc\"\n\n/**\n * Requires a JSDoc comment above an AdonisJS migration (a default-exported class\n * extending `BaseSchema`) so its intent is documented, the timestamped filename\n * alone does not convey what the migration changes.\n */\nclass RequireMigrationJSDoc extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-migration-jsdoc\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require a JSDoc comment describing an AdonisJS migration.\",\n recommended: true,\n category: \"adonisjs\",\n },\n schema: [],\n messages: {\n missingJSDoc: nitpick({\n problem: \"This migration has no JSDoc describing what it does.\",\n why: \"A migration's intent should be readable at a glance, the timestamped filename does not convey the schema change\",\n fix: \"Add a `/** ... */` JSDoc above the migration class summarizing the change\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n ClassDeclaration(node) {\n if (!isMigrationClass(node)) return\n if (hasLeadingJSDoc(context.sourceCode, node.parent)) return\n\n context.report({ node: node.id ?? node, messageId: \"missingJSDoc\" })\n },\n }\n }\n}\n\nexport default new RequireMigrationJSDoc()\n","/**\n * Converts a glob pattern into an anchored regular expression, supporting `*`\n * (any run within a path segment) and `**` (any run across segments).\n * @param glob The glob pattern to convert.\n * @returns The equivalent regular expression.\n */\nfunction globToRegExp(glob: string): RegExp {\n const normalized = glob.replace(/\\\\/g, \"/\")\n let pattern = \"^\"\n\n for (let index = 0; index < normalized.length; index++) {\n const char = normalized[index]\n if (char === undefined) break\n\n if (char === \"*\") {\n if (normalized[index + 1] === \"*\") {\n pattern += \".*\"\n index++\n\n // If the \"**\" is followed by a \"/\", skip it so that \"**/\" and \"**\" are equivalent\n if (normalized[index + 1] === \"/\") index++\n } else {\n pattern += \"[^/]*\"\n }\n } else if (\"\\\\^$.|?+()[]{}\".includes(char)) {\n pattern += `\\\\${char}`\n } else {\n pattern += char\n }\n }\n\n return new RegExp(`${pattern}$`)\n}\n\n/**\n * Checks whether a file path matches any of the given glob patterns, comparing\n * with forward slashes so it works the same on every platform.\n * @param filename The file path to test.\n * @param patterns The glob patterns to match against.\n * @returns True if the path matches at least one pattern.\n */\nexport function matchesGlob(filename: string, patterns: string[]): boolean {\n const path = filename.replace(/\\\\/g, \"/\")\n\n return patterns.some(pattern => globToRegExp(pattern).test(path))\n}\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { matchesGlob } from \"@/lib/utils/regex\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ allowIn: string[] }]\ntype MessageIds = \"rawRead\"\n\n/**\n * Flags a raw `request.input()`, `request.body()`, `request.qs()`, etc. read, so\n * request data goes through `request.validateUsing(validator)` instead, the\n * `allowIn` option lists globs (e.g. passthrough proxy controllers) that are\n * exempt.\n */\nclass RequireValidatedRequest extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-validated-request\"\n\n readonly defaultOptions: Options = [{ allowIn: [] }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require request data to be read through a Vine validator, not raw request accessors.\",\n recommended: true,\n category: \"adonisjs\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n allowIn: {\n type: \"array\",\n items: { type: \"string\" },\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n rawRead: nitpick({\n problem: \"`request.{{method}}()` reads request data directly.\",\n why: \"Request data must pass through a Vine validator so it is typed and checked, a raw accessor bypasses that contract\",\n fix: \"Read it through `request.validateUsing(someValidator)` instead\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const allowIn = options[0]?.allowIn ?? []\n if (allowIn.length > 0 && matchesGlob(context.filename, allowIn)) {\n return {}\n }\n\n /**\n * Checks whether an expression refers to the HttpContext request, whether\n * bound directly or reached through `ctx.request`.\n * @param node The expression to inspect.\n * @returns True if the expression is the request.\n */\n const isRequest = (node: TSESTree.Node): boolean => {\n if (node.type === \"Identifier\") return node.name === \"request\"\n return (\n node.type === \"MemberExpression\" &&\n node.property.type === \"Identifier\" &&\n node.property.name === \"request\"\n )\n }\n\n return {\n CallExpression(node) {\n if (node.callee.type !== \"MemberExpression\" || node.callee.property.type !== \"Identifier\") return\n if (!CONSTANTS.REQUEST.RAW_ACCESSORS.has(node.callee.property.name) || !isRequest(node.callee.object))\n return\n\n context.report({\n node: node.callee.property,\n messageId: \"rawRead\",\n data: {\n method: node.callee.property.name,\n },\n })\n },\n }\n }\n}\n\nexport default new RequireValidatedRequest()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"rename\"\n\n/**\n * Flags a `catch` clause that binds its error under any name other than `error`\n * (an underscore-prefixed name such as `_error` is allowed for a deliberately\n * unused binding), so error handling reads the same everywhere.\n */\nclass CatchErrorName extends NitpickerRule<MessageIds, Options> {\n readonly name = \"catch-error-name\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require a `catch` clause to bind its error as `error`.\",\n recommended: true,\n category: \"base\",\n },\n schema: [],\n messages: {\n rename: nitpick({\n problem: \"This `catch` binds the error as `{{name}}`.\",\n why: \"Every catch binds the error as `error` so error handling reads the same across the codebase\",\n fix: \"Rename the binding to `error`, or `_error` if it is intentionally unused\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n CatchClause(node) {\n // A bare catch with no binding, or a destructured binding, is left alone\n if (node.param?.type !== \"Identifier\") return\n if (node.param.name === \"error\" || node.param.name.startsWith(\"_\")) return\n\n context.report({\n node: node.param,\n messageId: \"rename\",\n data: { name: node.param.name },\n })\n },\n }\n }\n}\n\nexport default new CatchErrorName()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { getJSDocDescription, isJSDocComment } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ max: number }]\ntype MessageIds = \"tooLong\"\n\n/**\n * Flags JSDoc comments whose description (the prose before the first tag) is\n * longer than the configured character limit, catching the oversized,\n * essay-like blocks AI models tend to produce.\n */\nclass MaxJSDocDescriptionLength extends NitpickerRule<MessageIds, Options> {\n readonly name = \"max-jsdoc-description-length\"\n\n readonly defaultOptions: Options = [{ max: CONSTANTS.JSDOC.MAX_DESCRIPTION_LENGTH }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Enforce a maximum character length for a JSDoc description.\",\n recommended: true,\n category: \"base\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n max: { type: \"integer\", minimum: 1 },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n tooLong: nitpick({\n problem: \"This JSDoc description is {{length}} characters, over the {{max}}-character limit.\",\n why: \"A JSDoc description should summarize what something is, an oversized one usually restates the code or explains how it is used, which does not belong here\",\n fix: 'Trim it to a concise summary of what it does, and remove any note about how or where it is used (e.g \"used by X to ...\", \"called from Y\"), which is an anti-pattern',\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const max = options[0]?.max ?? CONSTANTS.JSDOC.MAX_DESCRIPTION_LENGTH\n\n return {\n Program() {\n for (const comment of context.sourceCode.getAllComments()) {\n if (!isJSDocComment(comment)) continue\n\n const length = getJSDocDescription(comment).length\n if (length <= max) continue\n\n context.report({\n loc: comment.loc,\n messageId: \"tooLong\",\n data: { length, max },\n })\n }\n },\n }\n }\n}\n\nexport default new MaxJSDocDescriptionLength()\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { isDirectiveComment } from \"@/lib/utils/comments\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ max: number }]\ntype MessageIds = \"tooLong\"\n\n/**\n * Flags a run of stacked `//` comments whose prose runs past the configured\n * limit, applying the same cap to a wall of line comments that\n * `max-jsdoc-description-length` applies to a JSDoc description.\n */\nclass MaxLineCommentLength extends NitpickerRule<MessageIds, Options> {\n readonly name = \"max-line-comment-length\"\n\n readonly defaultOptions: Options = [{ max: CONSTANTS.COMMENTS.MAX_RUN_LENGTH }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Enforce a maximum prose length for a run of consecutive `//` line comments.\",\n recommended: true,\n category: \"base\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n max: { type: \"integer\", minimum: 1 },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n tooLong: nitpick({\n problem: \"This run of line comments is {{length}} characters, over the {{max}}-character limit.\",\n why: \"A wall of stacked `//` lines is a paragraph in disguise, it buries the point and is hard to read next to the code\",\n fix: \"Cut it to the essential why, or move the long explanation into a JSDoc on the declaration it belongs to\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const max = options[0]?.max ?? CONSTANTS.COMMENTS.MAX_RUN_LENGTH\n\n /**\n * Joins the prose a run carries, with each marker and its padding stripped.\n * @param run The consecutive line comments to read.\n * @returns The joined prose.\n */\n const proseOf = (run: TSESTree.Comment[]): string =>\n run\n .map(comment => comment.value.trim())\n .filter(text => text !== \"\")\n .join(\" \")\n\n /**\n * Reports a run whose prose runs past the limit.\n * @param run The consecutive line comments to measure.\n */\n const report = (run: TSESTree.Comment[]): void => {\n if (run.length === 0) return\n\n const length = proseOf(run).length\n if (length <= max) return\n\n const first = run[0]\n const last = run.at(-1)\n if (first === undefined || last === undefined) return\n\n context.report({\n loc: { start: first.loc.start, end: last.loc.end },\n messageId: \"tooLong\",\n data: { length, max },\n })\n }\n\n return {\n Program() {\n let run: TSESTree.Comment[] = []\n\n for (const comment of context.sourceCode.getAllComments()) {\n const previous = run.at(-1)\n const isConsecutive =\n previous !== undefined && comment.loc.start.line === previous.loc.start.line + 1\n\n if (comment.type !== \"Line\" || isDirectiveComment(comment) || !isConsecutive) {\n report(run)\n run = comment.type === \"Line\" && !isDirectiveComment(comment) ? [comment] : []\n continue\n }\n\n run.push(comment)\n }\n\n report(run)\n },\n }\n }\n}\n\nexport default new MaxLineCommentLength()\n","import { ASTUtils, type TSESLint, type TSESTree } from \"@typescript-eslint/utils\"\n\n/**\n * Builds the dotted path of a pure property access chain, i.e. one made only of\n * non-computed member accesses (with any `?.` or `!`) bottoming out at an\n * identifier or `this`, such as `auth.user!` or `menu.node.path`.\n * @param node The expression to inspect.\n * @returns The dotted path, e.g. `auth.user`, or `null` if the expression is not\n * a plain property access.\n */\nexport function propertyAccessPath(node: TSESTree.Expression): string | null {\n const properties: string[] = []\n let expression: TSESTree.Node = node\n\n while (true) {\n if (expression.type === \"ChainExpression\" || expression.type === \"TSNonNullExpression\") {\n expression = expression.expression\n continue\n }\n\n if (expression.type === \"MemberExpression\") {\n if (expression.computed) return null\n if (expression.property.type !== \"Identifier\") return null\n\n properties.unshift(expression.property.name)\n expression = expression.object\n continue\n }\n\n break\n }\n\n if (properties.length === 0) return null\n if (expression.type === \"ThisExpression\") return [\"this\", ...properties].join(\".\")\n if (expression.type === \"Identifier\") return [expression.name, ...properties].join(\".\")\n\n return null\n}\n\n/**\n * Checks whether an expression is nothing but a non-computed property access\n * chain (with any `?.` or `!`) bottoming out at an identifier or `this`, such as\n * `auth.user!` or `menu.node.path`.\n * @param node The expression to inspect.\n * @returns True if the expression is a plain property access.\n */\nexport function isPropertyAccessAlias(node: TSESTree.Expression): boolean {\n return propertyAccessPath(node) !== null\n}\n\n/**\n * Checks whether a binding is written to after its declaration, which makes an\n * alias of it a snapshot of the value at that point rather than a rename.\n * @param scope The scope the alias is declared in.\n * @param name The name of the source binding.\n * @returns True if the binding is reassigned somewhere.\n */\nexport function isReassigned(scope: TSESLint.Scope.Scope, name: string): boolean {\n const variable = ASTUtils.findVariable(scope, name)\n\n // An unresolved name is a global or an ambient declaration, so it is stable\n if (variable === null) return false\n\n const declarations = new Set<TSESTree.Node>(variable.defs.map(definition => definition.name))\n\n return variable.references.some(reference => reference.isWrite() && !declarations.has(reference.identifier))\n}\n\n/**\n * Checks whether a property path, or a prefix of it, is written to, which makes\n * an alias of that path a snapshot rather than a rename.\n * @param written The property paths written to in the file.\n * @param path The property path the alias reads.\n * @returns True if the path or one of its prefixes is written to.\n */\nexport function isPathWritten(written: ReadonlySet<string>, path: string): boolean {\n for (const target of written) {\n if (path === target || path.startsWith(`${target}.`)) return true\n }\n\n return false\n}\n\n/**\n * Checks whether an object pattern is nothing but plain shorthand properties,\n * i.e. `{ a, b }` with no rename, default, computed key, or rest element, which\n * makes it a pure alias of the object it destructures.\n * @param pattern The object pattern to inspect.\n * @returns True if every property is a pure shorthand grab.\n */\nexport function isAllShorthand(pattern: TSESTree.ObjectPattern): boolean {\n if (pattern.properties.length === 0) return false\n\n return pattern.properties.every(\n property =>\n property.type === \"Property\" &&\n property.shorthand &&\n !property.computed &&\n property.value.type === \"Identifier\",\n )\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { isReassigned } from \"@/lib/utils/aliases\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"alias\"\n\n/**\n * Flags a `const` whose entire value is another variable, such as\n * `const accessTokens = rawAccessTokens`, since it just renames the source. `let`,\n * exported bindings, annotated declarations, and snapshots of a reassigned source\n * are exempt.\n */\nclass NoAliasVariables extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-alias-variables\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Disallow a `const` whose whole value is another variable, use the source directly.\",\n recommended: true,\n category: \"base\",\n },\n schema: [],\n messages: {\n alias: nitpick({\n problem: \"`{{name}}` only aliases `{{source}}`.\",\n why: \"A variable that just renames another hides the original and adds a name to track for no gain\",\n fix: \"Remove it and use `{{source}}` directly, or rename `{{source}}` itself if the new name is better\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n VariableDeclarator(node) {\n if (node.parent.type !== \"VariableDeclaration\" || node.parent.kind !== \"const\") return\n\n // Exported bindings cannot be inlined away, so they are exempt\n if (node.parent.parent.type === \"ExportNamedDeclaration\") return\n\n if (node.id.type !== \"Identifier\" || node.init?.type !== \"Identifier\") return\n\n // A type annotation is a reason of its own to keep the binding, as\n // inlining it would drop the narrowing it applies\n if (node.id.typeAnnotation !== undefined) return\n\n // A reassigned source makes this a snapshot of its value here, not\n // a rename, so inlining it would change what the code does\n if (isReassigned(context.sourceCode.getScope(node), node.init.name)) return\n\n context.report({\n node,\n messageId: \"alias\",\n data: {\n name: node.id.name,\n source: node.init.name,\n },\n })\n },\n }\n }\n}\n\nexport default new NoAliasVariables()\n","/**\n * British English spellings mapped to their American equivalents, keyed in\n * lowercase. Extend it per project via the `no-british-english` rule's `extra`\n * option.\n */\nexport const BRITISH_TO_AMERICAN: Record<string, string> = {\n // \"-our\" to \"-or\"\n colour: \"color\",\n colours: \"colors\",\n coloured: \"colored\",\n colouring: \"coloring\",\n behaviour: \"behavior\",\n behaviours: \"behaviors\",\n favour: \"favor\",\n favours: \"favors\",\n favoured: \"favored\",\n favouring: \"favoring\",\n favourable: \"favorable\",\n favourite: \"favorite\",\n favourites: \"favorites\",\n flavour: \"flavor\",\n flavours: \"flavors\",\n honour: \"honor\",\n honours: \"honors\",\n honoured: \"honored\",\n honouring: \"honoring\",\n labour: \"labor\",\n labours: \"labors\",\n laboured: \"labored\",\n labouring: \"laboring\",\n neighbour: \"neighbor\",\n neighbours: \"neighbors\",\n humour: \"humor\",\n humours: \"humors\",\n rumour: \"rumor\",\n rumours: \"rumors\",\n harbour: \"harbor\",\n harbours: \"harbors\",\n endeavour: \"endeavor\",\n endeavours: \"endeavors\",\n endeavoured: \"endeavored\",\n endeavouring: \"endeavoring\",\n\n // \"-ise\" to \"-ize\" and their inflections\n normalise: \"normalize\",\n normalised: \"normalized\",\n normalising: \"normalizing\",\n normalisation: \"normalization\",\n initialise: \"initialize\",\n initialises: \"initializes\",\n initialised: \"initialized\",\n initialising: \"initializing\",\n initialisation: \"initialization\",\n serialise: \"serialize\",\n serialised: \"serialized\",\n serialising: \"serializing\",\n serialisation: \"serialization\",\n organise: \"organize\",\n organises: \"organizes\",\n organised: \"organized\",\n organising: \"organizing\",\n organisation: \"organization\",\n optimise: \"optimize\",\n optimised: \"optimized\",\n optimising: \"optimizing\",\n optimisation: \"optimization\",\n customise: \"customize\",\n customised: \"customized\",\n customising: \"customizing\",\n sanitise: \"sanitize\",\n sanitised: \"sanitized\",\n sanitising: \"sanitizing\",\n synchronise: \"synchronize\",\n synchronised: \"synchronized\",\n synchronising: \"synchronizing\",\n synchronisation: \"synchronization\",\n authorise: \"authorize\",\n authorised: \"authorized\",\n authorising: \"authorizing\",\n authorisation: \"authorization\",\n finalise: \"finalize\",\n finalised: \"finalized\",\n finalising: \"finalizing\",\n capitalise: \"capitalize\",\n capitalised: \"capitalized\",\n capitalising: \"capitalizing\",\n categorise: \"categorize\",\n categorises: \"categorizes\",\n categorised: \"categorized\",\n categorising: \"categorizing\",\n categorisation: \"categorization\",\n utilise: \"utilize\",\n utilises: \"utilizes\",\n utilised: \"utilized\",\n utilising: \"utilizing\",\n utilisation: \"utilization\",\n realise: \"realize\",\n realises: \"realizes\",\n realised: \"realized\",\n realising: \"realizing\",\n realisation: \"realization\",\n recognise: \"recognize\",\n recognises: \"recognizes\",\n recognised: \"recognized\",\n recognising: \"recognizing\",\n summarise: \"summarize\",\n summarises: \"summarizes\",\n summarised: \"summarized\",\n summarising: \"summarizing\",\n specialise: \"specialize\",\n specialises: \"specializes\",\n specialised: \"specialized\",\n specialising: \"specializing\",\n specialisation: \"specialization\",\n minimise: \"minimize\",\n minimises: \"minimizes\",\n minimised: \"minimized\",\n minimising: \"minimizing\",\n minimisation: \"minimization\",\n maximise: \"maximize\",\n maximises: \"maximizes\",\n maximised: \"maximized\",\n maximising: \"maximizing\",\n maximisation: \"maximization\",\n prioritise: \"prioritize\",\n prioritises: \"prioritizes\",\n prioritised: \"prioritized\",\n prioritising: \"prioritizing\",\n prioritisation: \"prioritization\",\n standardise: \"standardize\",\n standardises: \"standardizes\",\n standardised: \"standardized\",\n standardising: \"standardizing\",\n standardisation: \"standardization\",\n harmonise: \"harmonize\",\n harmonises: \"harmonizes\",\n harmonised: \"harmonized\",\n harmonising: \"harmonizing\",\n harmonisation: \"harmonization\",\n centralise: \"centralize\",\n centralises: \"centralizes\",\n centralised: \"centralized\",\n centralising: \"centralizing\",\n centralisation: \"centralization\",\n decentralise: \"decentralize\",\n decentralises: \"decentralizes\",\n decentralised: \"decentralized\",\n decentralising: \"decentralizing\",\n decentralisation: \"decentralization\",\n emphasise: \"emphasize\",\n emphasises: \"emphasizes\",\n emphasised: \"emphasized\",\n emphasising: \"emphasizing\",\n visualise: \"visualize\",\n visualises: \"visualizes\",\n visualised: \"visualized\",\n visualising: \"visualizing\",\n visualisation: \"visualization\",\n\n // \"-yse\" to \"-yze\"\n analyse: \"analyze\",\n analyses: \"analyzes\",\n analysed: \"analyzed\",\n analysing: \"analyzing\",\n paralyse: \"paralyze\",\n paralyses: \"paralyzes\",\n paralysed: \"paralyzed\",\n paralysing: \"paralyzing\",\n\n // \"-re\" to \"-er\"\n centre: \"center\",\n centred: \"centered\",\n centres: \"centers\",\n fibre: \"fiber\",\n fibres: \"fibers\",\n metre: \"meter\",\n metres: \"meters\",\n litre: \"liter\",\n litres: \"liters\",\n theatre: \"theater\",\n theatres: \"theaters\",\n calibre: \"caliber\",\n spectre: \"specter\",\n spectres: \"specters\",\n\n // \"-ce\" to \"-se\"\n licence: \"license\",\n defence: \"defense\",\n offence: \"offense\",\n pretence: \"pretense\",\n practise: \"practice\",\n\n // Doubled \"l\" in inflections\n cancelled: \"canceled\",\n cancelling: \"canceling\",\n labelled: \"labeled\",\n labelling: \"labeling\",\n modelled: \"modeled\",\n modelling: \"modeling\",\n travelled: \"traveled\",\n travelling: \"traveling\",\n signalled: \"signaled\",\n signalling: \"signaling\",\n fuelled: \"fueled\",\n fuelling: \"fueling\",\n marvellous: \"marvelous\",\n counsellor: \"counselor\",\n\n // Single \"l\" that doubles in American English\n fulfil: \"fulfill\",\n fulfils: \"fulfills\",\n fulfilment: \"fulfillment\",\n enrol: \"enroll\",\n enrols: \"enrolls\",\n enrolment: \"enrollment\",\n instalment: \"installment\",\n skilful: \"skillful\",\n wilful: \"willful\",\n\n // \"-ogue\" to \"-og\"\n dialogue: \"dialog\",\n dialogues: \"dialogs\",\n catalogue: \"catalog\",\n catalogues: \"catalogs\",\n analogue: \"analog\",\n analogues: \"analogs\",\n\n // Miscellaneous\n grey: \"gray\",\n artefact: \"artifact\",\n artefacts: \"artifacts\",\n sceptic: \"skeptic\",\n sceptical: \"skeptical\",\n programme: \"program\",\n programmes: \"programs\",\n enquiry: \"inquiry\",\n enquiries: \"inquiries\",\n aluminium: \"aluminum\",\n tyre: \"tire\",\n tyres: \"tires\",\n}\n","/**\n * Merges a base lookup with extra entries and removes ignored keys, keying everything in lowercase\n * for case-insensitive lookups. Used to let a rule's built-in table be extended or narrowed\n * through its options.\n * @param base The built-in lookup.\n * @param extra Additional entries to add or override.\n * @param ignore Keys to remove from the result.\n * @returns The merged, lowercase-keyed lookup.\n */\nexport function buildDictionary(\n base: Record<string, string>,\n extra: Record<string, string>,\n ignore: string[],\n): Record<string, string> {\n /**\n * A null-prototype object so lookups like `dictionary[\"constructor\"]` return\n * undefined instead of Object.prototype.constructor, which would otherwise\n * treat identifiers such as `BrowserWindowConstructorOptions` as matches.\n */\n const dictionary: Record<string, string> = Object.create(null)\n\n for (const [key, value] of Object.entries(base)) {\n dictionary[key.toLowerCase()] = value\n }\n\n for (const [key, value] of Object.entries(extra)) {\n dictionary[key.toLowerCase()] = value\n }\n\n for (const key of ignore) {\n delete dictionary[key.toLowerCase()]\n }\n\n return dictionary\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { BRITISH_TO_AMERICAN } from \"@/lib/data/britishToAmerican\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { buildDictionary } from \"@/lib/utils/dictionaries\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\nimport { extractWords, matchCase } from \"@/lib/utils/words\"\n\ntype Options = [{ extra: Record<string, string>; ignore: string[] }]\ntype MessageIds = \"british\"\n\n/**\n * Flags British English spellings in identifiers and comments, reporting the\n * American equivalent. The built-in dictionary can be extended per project with\n * the `extra` option, or narrowed with `ignore`.\n */\nclass NoBritishEnglish extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-british-english\"\n\n readonly defaultOptions: Options = [{ extra: {}, ignore: [] }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Disallow British English spellings in identifiers and comments.\",\n recommended: true,\n category: \"base\",\n },\n fixable: \"code\",\n schema: [\n {\n type: \"object\",\n properties: {\n extra: {\n type: \"object\",\n additionalProperties: { type: \"string\" },\n },\n ignore: {\n type: \"array\",\n items: { type: \"string\" },\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n british: nitpick({\n problem: \"British spelling `{{british}}`, this codebase uses American English.\",\n why: \"One spelling convention keeps identifiers and docs consistent and searchable\",\n fix: \"Use `{{american}}` instead\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const dictionary = buildDictionary(BRITISH_TO_AMERICAN, options[0]?.extra ?? {}, options[0]?.ignore ?? [])\n\n return {\n Identifier(node) {\n // Skip a member's property name (an external read), it cannot be\n // renamed from here\n if (node.parent.type === \"MemberExpression\" && node.parent.property === node && !node.parent.computed) {\n return\n }\n\n for (const word of extractWords(node.name)) {\n const american = dictionary[word.text.toLowerCase()]\n if (american === undefined) continue\n\n context.report({\n node,\n messageId: \"british\",\n data: { british: word.text, american: matchCase(word.text, american) },\n })\n }\n },\n Program() {\n for (const comment of context.sourceCode.getAllComments()) {\n for (const word of extractWords(comment.value)) {\n const american = dictionary[word.text.toLowerCase()]\n if (american === undefined) continue\n\n const cased = matchCase(word.text, american)\n\n // The comment value starts right after the \"//\" or \"/*\"\n const from = comment.range[0] + 2 + word.index\n const to = from + word.text.length\n\n context.report({\n loc: {\n start: context.sourceCode.getLocFromIndex(from),\n end: context.sourceCode.getLocFromIndex(to),\n },\n messageId: \"british\",\n data: { british: word.text, american: cased },\n fix: fixer => fixer.replaceTextRange([from, to], cased),\n })\n }\n }\n },\n }\n }\n}\n\nexport default new NoBritishEnglish()\n","import CONSTANTS from \"@/lib/constants\"\n\n/**\n * Checks whether a single comment line is a decorative separator, i.e. a banner,\n * a box-drawing rule, or a label fenced by repeated separator characters.\n * @param line The raw comment line, still carrying any leading ` * ` marker.\n * @returns True if the line is decorative.\n */\nexport function isDecorativeCommentLine(line: string): boolean {\n const content = line.replace(/^\\s*\\*?\\s*/, \"\").trimEnd()\n if (content.length === 0) return false\n\n return (\n CONSTANTS.COMMENTS.BOX_DRAWING.test(content) ||\n CONSTANTS.COMMENTS.PURE_SEPARATOR.test(content) ||\n CONSTANTS.COMMENTS.WRAPPED_LABEL.test(content)\n )\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { isDecorativeCommentLine } from \"@/lib/utils/decorations\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { matchesGlob } from \"@/lib/utils/regex\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ allowIn: string[] }]\ntype MessageIds = \"decorative\"\n\n/**\n * Flags decorative separators inside comments: banner rules (`// ======`),\n * box-drawing lines, and labels fenced by repeated dashes (`// -- Section --`),\n * the `allowIn` option lists globs where they are tolerated.\n */\nclass NoDecorativeCommentSeparators extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-decorative-comment-separators\"\n\n readonly defaultOptions: Options = [{ allowIn: [] }]\n\n readonly meta = {\n type: \"layout\",\n docs: {\n description: \"Disallow decorative separators (banners, box-drawing, repeated dashes) inside comments.\",\n recommended: true,\n category: \"base\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n allowIn: {\n type: \"array\",\n items: { type: \"string\" },\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n decorative: nitpick({\n problem: \"This comment uses a decorative separator.\",\n why: \"Repeated separator characters and box-drawing lines are visual noise that add nothing over a plain label\",\n fix: \"Remove the separator, a one-line label or a blank line already divides sections clearly\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const allowIn = options[0]?.allowIn ?? []\n if (allowIn.length > 0 && matchesGlob(context.filename, allowIn)) {\n return {}\n }\n\n return {\n Program() {\n for (const comment of context.sourceCode.getAllComments()) {\n const lines = comment.value.split(\"\\n\")\n\n for (let index = 0; index < lines.length; index++) {\n const line = lines[index]\n if (line === undefined || !isDecorativeCommentLine(line)) continue\n\n const reportedLine = comment.loc.start.line + index\n const source = context.sourceCode.lines[reportedLine - 1] ?? \"\"\n\n context.report({\n loc: {\n start: { line: reportedLine, column: 0 },\n end: { line: reportedLine, column: source.length },\n },\n messageId: \"decorative\",\n })\n }\n }\n },\n }\n }\n}\n\nexport default new NoDecorativeCommentSeparators()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\n\n/**\n * A place a flagged character may be tolerated, so user-facing copy, prompt\n * text, and glyphs can keep it while code and comments stay clean.\n */\nexport type SourceLocation = \"strings\" | \"templates\" | \"jsx\" | \"comments\"\n\n/**\n * The token type each location maps to, `comments` aside, as comments are not\n * tokens.\n */\nconst TOKEN_TYPES: Partial<Record<SourceLocation, string>> = {\n strings: \"String\",\n templates: \"Template\",\n jsx: \"JSXText\",\n}\n\n/**\n * Collects the source ranges covered by the given locations (string, template,\n * and JSX tokens, plus comments), so a raw-text scan can skip characters that\n * sit in copy the caller has chosen to allow.\n * @param sourceCode The source code of the linted file.\n * @param allow The locations to exempt.\n * @returns The exempt `[start, end]` ranges, empty when nothing is allowed.\n */\nexport function allowedRanges(\n sourceCode: Readonly<TSESLint.SourceCode>,\n allow: Iterable<SourceLocation>,\n): [number, number][] {\n const locations = new Set(allow)\n const ranges: [number, number][] = []\n if (locations.size === 0) return ranges\n\n const tokenTypes = new Set([...locations].map(location => TOKEN_TYPES[location]).filter(type => type !== undefined))\n\n for (const token of sourceCode.ast.tokens ?? []) {\n if (tokenTypes.has(token.type)) ranges.push(token.range)\n }\n\n if (locations.has(\"comments\")) {\n for (const comment of sourceCode.getAllComments()) {\n ranges.push(comment.range)\n }\n }\n\n return ranges\n}\n\n/**\n * Checks whether an index falls inside any of the given ranges.\n * @param index The source index to test.\n * @param ranges The `[start, end]` ranges to check against.\n * @returns True if the index sits within a range.\n */\nexport function isInAnyRange(index: number, ranges: [number, number][]): boolean {\n return ranges.some(([start, end]) => index >= start && index < end)\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { allowedRanges, isInAnyRange, type SourceLocation } from \"@/lib/utils/locations\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ allow?: SourceLocation[] }]\ntype MessageIds = \"emDash\"\n\n/**\n * Flags every em dash (—) character found anywhere in the source, except in the\n * locations the `allow` option exempts.\n */\nclass NoEmDash extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-em-dash\"\n\n readonly defaultOptions: Options = [{ allow: [] }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Disallow the em dash (—) character anywhere in the source.\",\n recommended: true,\n },\n schema: [\n {\n type: \"object\",\n properties: {\n allow: {\n type: \"array\",\n items: {\n type: \"string\",\n enum: [\"strings\", \"templates\", \"jsx\", \"comments\"],\n },\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n emDash: nitpick({\n problem: \"Found an em dash (—) character.\",\n why: \"Em dashes are typically introduced by AI-generated or auto-formatted text and are discouraged here.\",\n fix: \"Replace the em dash with a hyphen (-), a comma (,), or reword the sentence to avoid it, or allow it here with the rule's `allow` option if it is deliberate user-facing copy.\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n return {\n Program() {\n const text = context.sourceCode.getText()\n const ranges = allowedRanges(context.sourceCode, options[0]?.allow ?? [])\n\n // Scan the raw source so every em dash is caught, whether it appears\n // in code, strings, or comments\n for (let index = 0; index < text.length; index++) {\n if (text[index] !== CONSTANTS.EM_DASH) continue\n if (isInAnyRange(index, ranges)) continue\n\n context.report({\n loc: {\n start: context.sourceCode.getLocFromIndex(index),\n end: context.sourceCode.getLocFromIndex(index + 1),\n },\n messageId: \"emDash\",\n })\n }\n },\n }\n }\n}\n\nexport default new NoEmDash()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { allowedRanges, isInAnyRange, type SourceLocation } from \"@/lib/utils/locations\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ allow?: SourceLocation[] }]\ntype MessageIds = \"emoji\"\n\n/**\n * Flags every emoji in the source, except where the `allow` option exempts it.\n * Report-only, never auto-removing a glyph, since an emoji can carry meaning that\n * a silent deletion would lose.\n */\nclass NoEmojis extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-emojis\"\n\n readonly defaultOptions: Options = [{ allow: [] }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Disallow emoji characters anywhere in the source.\",\n recommended: true,\n category: \"base\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n allow: {\n type: \"array\",\n items: {\n type: \"string\",\n enum: [\"strings\", \"templates\", \"jsx\", \"comments\"],\n },\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n emoji: nitpick({\n problem: \"Found an emoji ({{emoji}}).\",\n why: \"Emojis are usually introduced by AI-generated text and add noise to code, comments, and identifiers\",\n fix: \"Remove the emoji, or allow it here with the rule's `allow` option if it is deliberate user-facing copy\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n return {\n Program() {\n const text = context.sourceCode.getText()\n const ranges = allowedRanges(context.sourceCode, options[0]?.allow ?? [])\n\n // Scan the raw source so every emoji is caught, whether it appears\n // in code, strings, or comments\n for (const match of text.matchAll(CONSTANTS.EMOJI)) {\n if (isInAnyRange(match.index, ranges)) continue\n\n context.report({\n loc: {\n start: context.sourceCode.getLocFromIndex(match.index),\n end: context.sourceCode.getLocFromIndex(match.index + match[0].length),\n },\n messageId: \"emoji\",\n data: { emoji: match[0] },\n })\n }\n },\n }\n }\n}\n\nexport default new NoEmojis()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { isBlankJSDocLine, isJSDocComment, isJSDocTagLine } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"blankBeforeTag\"\n\n/**\n * Flags blank lines that sit between a JSDoc description and its tags (or\n * between tags) and removes them so the tags follow on directly.\n */\nclass NoJSDocBlankBeforeTags extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-jsdoc-blank-before-tags\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"layout\",\n fixable: \"code\",\n docs: {\n description: \"Disallow blank lines before JSDoc tags such as `@param` or `@returns`.\",\n recommended: true,\n },\n schema: [],\n messages: {\n blankBeforeTag: nitpick({\n problem: \"There is a blank line before a JSDoc tag.\",\n why: \"Tags should follow the description directly; an empty line there is noise that inflates the comment.\",\n fix: \"Remove the blank line so the tag follows on directly.\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n Program() {\n for (const comment of context.sourceCode.getAllComments()) {\n if (!isJSDocComment(comment)) continue\n\n if (comment.loc.start.line === comment.loc.end.line) continue\n\n for (let line = comment.loc.start.line; line <= comment.loc.end.line; line++) {\n const text = context.sourceCode.lines[line - 1]\n if (text === undefined || !isBlankJSDocLine(text)) continue\n\n // Grow the run of consecutive blank lines\n let runEnd = line\n while (\n runEnd < comment.loc.end.line &&\n isBlankJSDocLine(context.sourceCode.lines[runEnd] ?? \"\")\n ) {\n runEnd++\n }\n\n // Only a blank run immediately before a tag is a problem\n const nextLine = context.sourceCode.lines[runEnd]\n if (nextLine !== undefined && isJSDocTagLine(nextLine)) {\n const from = context.sourceCode.getIndexFromLoc({ line, column: 0 })\n const to = context.sourceCode.getIndexFromLoc({ line: runEnd + 1, column: 0 })\n\n context.report({\n loc: {\n start: { line, column: 0 },\n end: { line: runEnd, column: text.length },\n },\n messageId: \"blankBeforeTag\",\n fix: fixer => fixer.removeRange([from, to]),\n })\n }\n\n line = runEnd\n }\n }\n },\n }\n }\n}\n\nexport default new NoJSDocBlankBeforeTags()\n","import type { TSESTree } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\n\n/**\n * Any node that introduces a callable function.\n */\nexport type FunctionNode = TSESTree.FunctionDeclaration | TSESTree.FunctionExpression | TSESTree.ArrowFunctionExpression\n\n/**\n * A lookup of AST node type to the property keys that hold its child nodes.\n */\nexport type VisitorKeys = Record<string, readonly string[] | undefined>\n\n/**\n * Predicate applied to a `return` statement's argument (which is `null` for a\n * bare `return`).\n */\ntype ReturnPredicate = (argument: TSESTree.Expression | null) => boolean\n\n/**\n * Resolves the node whose leading comments would document a function, walking\n * out through a variable declaration and/or an export statement (so\n * `export const foo = () => {}` resolves to the `export` node).\n * @param fn The function node to resolve from.\n * @returns The node a JSDoc comment would sit above.\n */\nexport function getDocumentableNode(fn: FunctionNode): TSESTree.Node {\n let node: TSESTree.Node = fn\n\n // An object or class member is documented above the member, not the function\n if (node.parent.type === \"Property\" || node.parent.type === \"MethodDefinition\") {\n return node.parent\n }\n\n if (node.parent.type === \"VariableDeclarator\" && node.parent.parent.type === \"VariableDeclaration\") {\n node = node.parent.parent\n }\n\n if (node.parent.type === \"ExportNamedDeclaration\" || node.parent.type === \"ExportDefaultDeclaration\") {\n node = node.parent\n }\n\n return node\n}\n\n/**\n * Checks whether a node sits directly at the top level of the module.\n * @param node The node to test.\n * @returns True if the node's parent is the program root.\n */\nexport function isTopLevel(node: TSESTree.Node): boolean {\n return node.parent?.type === \"Program\"\n}\n\n/**\n * A named thing a JSDoc `@param` can refer to.\n */\nexport type NamedParameter = { name: string; node: TSESTree.Node }\n\n/**\n * How a parameter expects to be documented: a plain name, or a destructured\n * object, which may be documented either property by property or under a single\n * name standing for the whole object.\n */\nexport type ParameterDoc =\n | { kind: \"name\"; name: string; node: TSESTree.Node }\n | { kind: \"object\"; names: NamedParameter[]; node: TSESTree.Node }\n\n/**\n * Describes how each parameter of a function expects to be documented. An array\n * pattern is skipped as too ambiguous to require.\n * @param fn The function node to read the signature of.\n * @returns One entry per documentable parameter.\n */\nexport function parameterDocs(fn: FunctionNode): ParameterDoc[] {\n const docs: ParameterDoc[] = []\n\n /**\n * Adds the names a single parameter contributes, recursing through the\n * wrappers a parameter can carry.\n * @param param The parameter node to read.\n */\n const collect = (param: TSESTree.Node): void => {\n switch (param.type) {\n case \"Identifier\":\n docs.push({\n kind: \"name\",\n name: param.name,\n node: param,\n })\n return\n case \"AssignmentPattern\":\n collect(param.left)\n return\n case \"RestElement\":\n collect(param.argument)\n return\n case \"TSParameterProperty\":\n collect(param.parameter)\n return\n case \"ObjectPattern\": {\n const names: NamedParameter[] = []\n for (const property of param.properties) {\n if (property.type === \"RestElement\") {\n if (property.argument.type === \"Identifier\") {\n names.push({ name: property.argument.name, node: property.argument })\n }\n } else if (property.key.type === \"Identifier\") {\n names.push({ name: property.key.name, node: property.key })\n }\n }\n\n if (names.length > 0) {\n docs.push({\n kind: \"object\",\n names,\n node: param,\n })\n }\n return\n }\n default:\n return\n }\n }\n\n for (const param of fn.params) collect(param)\n\n return docs\n}\n\n/**\n * Resolves the nearest function a node sits inside, walking out through its\n * parents.\n * @param node The node to search from.\n * @returns The enclosing function, or `null` if the node is at module scope.\n */\nexport function enclosingFunction(node: TSESTree.Node): FunctionNode | null {\n // \"node.parent\" is typed undefined but is null at the Program root, so guard\n // with a truthy check to stop the walk on either\n let current: TSESTree.Node | undefined = node.parent\n\n while (current) {\n if (CONSTANTS.FUNCTIONS.NODE_TYPES.has(current.type)) {\n return current as FunctionNode\n }\n\n current = current.parent\n }\n\n return null\n}\n\n/**\n * Checks whether a function is a bare dynamic-import thunk, i.e.\n * `() => import(\"...\")`, the lazy-loading pattern used for AdonisJS route\n * controllers and for code splitting.\n * @param fn The function node to inspect.\n * @returns True if the function only lazily imports a module.\n */\nexport function isDynamicImportThunk(fn: FunctionNode): boolean {\n return fn.type === \"ArrowFunctionExpression\" && fn.params.length === 0 && fn.body.type === \"ImportExpression\"\n}\n\n/**\n * Resolves the declared name of a function, whether it comes from the function\n * itself or the variable it is assigned to.\n * @param fn The function node to name.\n * @returns The function name, or `undefined` if it is anonymous.\n */\nexport function getFunctionName(fn: FunctionNode): string | undefined {\n if ((fn.type === \"FunctionDeclaration\" || fn.type === \"FunctionExpression\") && fn.id) {\n return fn.id.name\n }\n\n if (fn.parent.type === \"VariableDeclarator\" && fn.parent.id.type === \"Identifier\") {\n return fn.parent.id.name\n }\n\n return undefined\n}\n\n/**\n * Checks whether any `return` in a subtree satisfies a predicate, without\n * crossing into nested functions (whose returns belong to them, not us).\n * @param node The AST node to search from.\n * @param visitorKeys The AST visitor keys, used to walk the subtree.\n * @param predicate The test applied to each `return` argument.\n * @returns True if a matching `return` is found.\n */\nexport function someReturn(node: TSESTree.Node, visitorKeys: VisitorKeys, predicate: ReturnPredicate): boolean {\n if (node.type === \"ReturnStatement\") {\n return predicate(node.argument)\n }\n\n for (const key of visitorKeys[node.type] ?? []) {\n const value = (node as unknown as Record<string, unknown>)[key]\n const children = Array.isArray(value) ? value : [value]\n\n for (const child of children) {\n const childNode = child as TSESTree.Node | null | undefined\n if (!childNode || typeof childNode.type !== \"string\") continue\n if (CONSTANTS.FUNCTIONS.NODE_TYPES.has(childNode.type)) continue\n if (someReturn(childNode, visitorKeys, predicate)) return true\n }\n }\n\n return false\n}\n\n/**\n * Checks whether a function returns a value, i.e. an arrow with an expression\n * body or a body with a non-empty `return`.\n * @param fn The function node to inspect.\n * @param visitorKeys The AST visitor keys, used to walk the function body.\n * @returns True if the function returns a value.\n */\nexport function functionReturnsValue(fn: FunctionNode, visitorKeys: VisitorKeys): boolean {\n if (fn.type === \"ArrowFunctionExpression\" && fn.body.type !== \"BlockStatement\") {\n return true\n }\n\n return someReturn(fn.body, visitorKeys, argument => argument !== null)\n}\n\n/**\n * Checks whether a return-type annotation is `void` or `Promise<void>`.\n * @param annotation The return-type annotation to inspect.\n * @returns True if the annotation is a void type.\n */\nexport function isVoidReturnType(annotation: TSESTree.TSTypeAnnotation): boolean {\n if (annotation.typeAnnotation.type === \"TSVoidKeyword\") return true\n\n if (\n annotation.typeAnnotation.type === \"TSTypeReference\" &&\n annotation.typeAnnotation.typeName.type === \"Identifier\" &&\n annotation.typeAnnotation.typeName.name === \"Promise\"\n ) {\n return (\n annotation.typeAnnotation.typeArguments?.params.length === 1 &&\n annotation.typeAnnotation.typeArguments?.params[0]?.type === \"TSVoidKeyword\"\n )\n }\n\n return false\n}\n\n/**\n * Checks whether a function returns nothing, judged by its return-type\n * annotation when present, otherwise by its body.\n * @param fn The function node to inspect.\n * @param visitorKeys The AST visitor keys, used to walk the function body.\n * @returns True if the function is void.\n */\nexport function isVoidFunction(fn: FunctionNode, visitorKeys: VisitorKeys): boolean {\n if (fn.returnType) {\n return isVoidReturnType(fn.returnType)\n }\n\n return !functionReturnsValue(fn, visitorKeys)\n}\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { type FunctionNode, getDocumentableNode, isVoidFunction } from \"@/lib/utils/functions\"\nimport { findJSDocReturnsRange, isJSDocComment } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"voidReturns\"\n\n/**\n * Flags a `@returns` tag on a function that returns nothing (a void return type,\n * or a body with no `return` or only a bare `return`), and removes it, since it\n * documents a value that never exists.\n */\nclass NoJSDocReturnsOnVoid extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-jsdoc-returns-on-void\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n fixable: \"code\",\n docs: {\n description: \"Disallow a JSDoc `@returns` tag on a function that returns nothing.\",\n recommended: true,\n category: \"base\",\n },\n schema: [],\n messages: {\n voidReturns: nitpick({\n problem: \"This function returns nothing, but its JSDoc has a `@returns` tag.\",\n why: \"A `@returns` on a void function documents a value that never exists and drifts from the code\",\n fix: \"Remove the `@returns` tag\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n /**\n * Reports a void function whose JSDoc still carries a returns tag.\n * @param fn The function to inspect.\n * @param anchor The node the JSDoc sits above.\n */\n const check = (fn: FunctionNode, anchor: TSESTree.Node): void => {\n const jsdoc = context.sourceCode.getCommentsBefore(anchor).at(-1)\n if (jsdoc === undefined || !isJSDocComment(jsdoc)) return\n\n const range = findJSDocReturnsRange(context.sourceCode, jsdoc)\n if (range === null) return\n if (!isVoidFunction(fn, context.sourceCode.visitorKeys)) return\n\n const from = context.sourceCode.getIndexFromLoc({ line: range.from, column: 0 })\n const to = context.sourceCode.getIndexFromLoc({ line: range.to + 1, column: 0 })\n\n context.report({\n loc: {\n start: { line: range.from, column: 0 },\n end: { line: range.to, column: (context.sourceCode.lines[range.to - 1] ?? \"\").length },\n },\n messageId: \"voidReturns\",\n fix: fixer => fixer.removeRange([from, to]),\n })\n }\n\n return {\n FunctionDeclaration(node) {\n check(node, getDocumentableNode(node))\n },\n VariableDeclarator(node) {\n if (node.init?.type === \"ArrowFunctionExpression\" || node.init?.type === \"FunctionExpression\") {\n check(node.init, getDocumentableNode(node.init))\n }\n },\n MethodDefinition(node) {\n if (node.value.type === \"FunctionExpression\") {\n check(node.value, node)\n }\n },\n }\n }\n}\n\nexport default new NoJSDocReturnsOnVoid()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { findBacktickSpans, isDirectiveComment } from \"@/lib/utils/comments\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"backticks\"\n\n/**\n * Flags a backtick-fenced code reference inside a `//` line comment and rewrites\n * it with double quotes, since backticks only render as code in a JSDoc block.\n * Code fences, unpaired backticks, and directives are left alone.\n */\nclass NoLineCommentBackticks extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-line-comment-backticks\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n fixable: \"code\",\n docs: {\n description: \"Disallow backticks in `//` line comments, use double quotes for code references.\",\n recommended: true,\n category: \"base\",\n },\n schema: [],\n messages: {\n backticks: nitpick({\n problem: \"This line comment wraps `{{text}}` in backticks.\",\n why: \"Backticks only render as code inside a JSDoc block, in a `//` comment they stay literal characters, so double quotes read better\",\n fix: 'Wrap it in double quotes instead: \"{{text}}\"',\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n Program() {\n for (const comment of context.sourceCode.getAllComments()) {\n // A JSDoc block is where backticks do render, so only \"//\"\n // comments are rewritten, and never a tooling directive\n if (comment.type !== \"Line\" || isDirectiveComment(comment)) continue\n\n for (const span of findBacktickSpans(comment)) {\n context.report({\n loc: {\n start: context.sourceCode.getLocFromIndex(span.start),\n end: context.sourceCode.getLocFromIndex(span.end + 1),\n },\n messageId: \"backticks\",\n data: { text: span.text },\n fix: fixer => [\n fixer.replaceTextRange([span.start, span.start + 1], '\"'),\n fixer.replaceTextRange([span.end, span.end + 1], '\"'),\n ],\n })\n }\n }\n },\n }\n }\n}\n\nexport default new NoLineCommentBackticks()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { findProsePeriods } from \"@/lib/utils/comments\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"period\" | \"sentence\"\n\n/**\n * Flags periods used as prose punctuation inside `//` line comments. Dots that\n * are part of a token (`foo.bar`, `1.5`, `.env`, `subagent.*`), dots inside a\n * quoted span, ellipses, and abbreviations like `e.g.` are left alone.\n */\nclass NoLineCommentPeriod extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-line-comment-period\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"layout\",\n fixable: \"code\",\n docs: {\n description: \"Disallow prose periods in `//` line comments (code-reference dots and ellipses are allowed).\",\n recommended: true,\n },\n schema: [],\n messages: {\n period: nitpick({\n problem: \"This line comment ends with a period.\",\n why: \"Line comments should be short, clear fragments, not full sentences, so a closing period is just noise, dots inside code references like `foo.bar` are allowed.\",\n fix: \"Remove the period and keep the comment terse.\",\n }),\n sentence: nitpick({\n problem: \"This line comment runs two sentences together with a period.\",\n why: \"Line comments should be short, clear fragments, dropping the period on its own would leave a run-on, so the sentences belong on separate lines\",\n fix: \"Split it into one `//` line per fragment, or reword it as a single fragment (reported, not auto-fixed, so wrapped prose is never mangled)\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n Program() {\n for (const comment of context.sourceCode.getAllComments()) {\n if (comment.type !== \"Line\") continue\n\n for (const period of findProsePeriods(comment)) {\n const loc = {\n start: context.sourceCode.getLocFromIndex(period.index),\n end: context.sourceCode.getLocFromIndex(period.index + 1),\n }\n\n // A period that closes the comment can simply go, nothing\n // follows it to run together\n if (period.terminal) {\n context.report({\n loc,\n messageId: \"period\",\n fix: fixer => fixer.removeRange([period.index, period.index + 1]),\n })\n\n continue\n }\n\n // Mid-comment, the period separates two fragments, and\n // splitting it onto a new line mangles wrapped prose, so this\n // case is reported for a human or agent to reword, not fixed\n context.report({ loc, messageId: \"sentence\" })\n }\n }\n },\n }\n }\n}\n\nexport default new NoLineCommentPeriod()\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { isPathWritten, isReassigned, propertyAccessPath } from \"@/lib/utils/aliases\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"propertyAccessAlias\"\n\n/**\n * A `const` that reads like a property alias, held back until the whole file has\n * been walked so writes to the same property can exempt it.\n */\ntype Candidate = {\n /**\n * The declarator to report.\n */\n node: TSESTree.VariableDeclarator\n\n /**\n * The name the property is aliased under.\n */\n name: string\n\n /**\n * The dotted path the alias reads, e.g. `auth.user`.\n */\n path: string\n\n /**\n * The source text of the aliased expression.\n */\n expression: string\n}\n\n/**\n * Flags a `const` whose entire value is a single property access, such as\n * `const user = auth.user!`, since it just renames a property. `let`, exported\n * bindings, annotated declarations, and snapshots of a value written to later are\n * exempt.\n */\nclass NoPropertyAccessAlias extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-property-access-alias\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description:\n \"Disallow a `const` whose whole value is a single property access, inline the expression instead.\",\n recommended: true,\n category: \"base\",\n },\n schema: [],\n messages: {\n propertyAccessAlias: nitpick({\n problem: \"`{{name}}` only aliases the property access `{{expression}}`.\",\n why: \"A variable that just renames a property hides where the value comes from when scanning the code\",\n fix: \"Remove it and use `{{expression}}` inline, or use `let` if it is reassigned later\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n const candidates: Candidate[] = []\n const written = new Set<string>()\n\n /**\n * Tracks a property the file writes to, so an alias taken before one of\n * those writes is understood as a snapshot.\n * @param target The assignment target to record.\n */\n const recordWrite = (target: TSESTree.Node): void => {\n if (target.type !== \"MemberExpression\") return\n\n const path = propertyAccessPath(target)\n if (path !== null) written.add(path)\n }\n\n return {\n AssignmentExpression(node) {\n recordWrite(node.left)\n },\n\n UpdateExpression(node) {\n recordWrite(node.argument)\n },\n\n VariableDeclarator(node) {\n if (node.parent.type !== \"VariableDeclaration\" || node.parent.kind !== \"const\") return\n\n // Exported bindings cannot be inlined away, so they are exempt\n if (node.parent.parent.type === \"ExportNamedDeclaration\") return\n\n if (node.id.type !== \"Identifier\" || node.init === null) return\n\n // A type annotation is a reason of its own to keep the binding, as\n // inlining it would drop the narrowing it applies\n if (node.id.typeAnnotation !== undefined) return\n\n const path = propertyAccessPath(node.init)\n if (path === null) return\n\n // A reassigned root object makes this a snapshot of what it held\n // here, so inlining it would change what the code does\n const root = path.slice(0, path.indexOf(\".\"))\n if (root !== \"this\" && isReassigned(context.sourceCode.getScope(node), root)) return\n\n candidates.push({\n node,\n name: node.id.name,\n path,\n expression: context.sourceCode.getText(node.init),\n })\n },\n\n \"Program:exit\"() {\n for (const candidate of candidates) {\n if (isPathWritten(written, candidate.path)) continue\n\n context.report({\n node: candidate.node,\n messageId: \"propertyAccessAlias\",\n data: {\n name: candidate.name,\n expression: candidate.expression,\n },\n })\n }\n },\n }\n }\n}\n\nexport default new NoPropertyAccessAlias()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { isAllShorthand, isPropertyAccessAlias } from \"@/lib/utils/aliases\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"destructure\"\n\n/**\n * Flags shorthand object destructuring off a plain object reference\n * (`const { a } = object`), which just aliases `object.a`. Destructuring a call\n * or hook result, renames, defaults, and rest elements are left alone.\n */\nclass NoPropertyDestructuring extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-property-destructuring\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Disallow shorthand destructuring off a plain object reference, access the property directly.\",\n recommended: true,\n category: \"base\",\n },\n schema: [],\n messages: {\n destructure: nitpick({\n problem: \"Destructuring from `{{source}}` here just aliases its properties.\",\n why: \"Reading `{{source}}.x` at the use site keeps the origin visible, destructuring a plain object hides where a value comes from (destructuring a call or hook result is fine)\",\n fix: \"Access the properties on `{{source}}` directly instead of destructuring\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n VariableDeclarator(node) {\n if (node.parent.type !== \"VariableDeclaration\" || node.parent.kind !== \"const\") return\n if (node.parent.parent.type === \"ExportNamedDeclaration\") return\n if (node.id.type !== \"ObjectPattern\" || node.init === null) return\n\n // Only a plain object reference is an alias, a call, await, or new\n // result is a computed value worth destructuring\n if (node.init.type !== \"Identifier\" && !isPropertyAccessAlias(node.init)) return\n\n // Only pure shorthand grabs (\"{ a }\") are aliases, renames,\n // defaults, and rest elements are deliberate\n if (!isAllShorthand(node.id)) return\n\n context.report({\n node,\n messageId: \"destructure\",\n data: { source: context.sourceCode.getText(node.init) },\n })\n },\n }\n }\n}\n\nexport default new NoPropertyDestructuring()\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { matchesGlob } from \"@/lib/utils/regex\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ allowIn: string[] }]\ntype MessageIds = \"relative\"\n\n/**\n * Flags a relative import or re-export specifier (`./` or `../`), so every\n * intra-package module is reached through its path alias instead. The `allowIn`\n * option lists globs (e.g. entrypoints) where relative paths are tolerated.\n */\nclass NoRelativeImports extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-relative-imports\"\n\n readonly defaultOptions: Options = [{ allowIn: [] }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Disallow relative import and re-export specifiers, use the package path alias.\",\n recommended: true,\n category: \"base\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n allowIn: {\n type: \"array\",\n items: { type: \"string\" },\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n relative: nitpick({\n problem: \"This import uses a relative path (`{{path}}`).\",\n why: \"A relative path breaks when a file moves and hides which package a module belongs to, the path alias is stable and explicit\",\n fix: \"Import through the package alias (`#...` or `@frontend/...`) instead of a relative path\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const allowIn = options[0]?.allowIn ?? []\n if (allowIn.length > 0 && matchesGlob(context.filename, allowIn)) {\n return {}\n }\n\n /**\n * Reports a module specifier written as a relative path.\n * @param source The module specifier to inspect, if any.\n */\n const check = (source: TSESTree.StringLiteral | null | undefined): void => {\n if (source === null || source === undefined) return\n if (!source.value.startsWith(\"./\") && !source.value.startsWith(\"../\")) return\n\n context.report({\n node: source,\n messageId: \"relative\",\n data: { path: source.value },\n })\n }\n\n return {\n ImportDeclaration(node) {\n check(node.source)\n },\n ExportNamedDeclaration(node) {\n check(node.source)\n },\n ExportAllDeclaration(node) {\n check(node.source)\n },\n ImportExpression(node) {\n if (node.source.type === \"Literal\" && typeof node.source.value === \"string\") {\n check(node.source as TSESTree.StringLiteral)\n }\n },\n }\n }\n}\n\nexport default new NoRelativeImports()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { isJSDocComment } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"singleLine\"\n\n/**\n * Flags JSDoc comments (`/**`) that are written on a single line and expands\n * them into the multi-line form:\n * ```\n * /** blabla */ -> /**\n * * blabla\n * */\n * ```\n */\nclass NoSingleLineJSDoc extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-single-line-jsdoc\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"layout\",\n fixable: \"code\",\n docs: {\n description: \"Require JSDoc comments to span multiple lines rather than sit on a single line.\",\n recommended: true,\n },\n schema: [],\n messages: {\n singleLine: nitpick({\n problem: \"This JSDoc comment is written on a single line.\",\n why: \"Multi-line JSDoc is easier to read, diff, and extend with additional tags, and is the house style.\",\n fix: \"Put the opening `/**`, the ` * ` content, and the closing `*/` each on their own line.\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n Program() {\n for (const comment of context.sourceCode.getAllComments()) {\n // Only JSDoc comments (\"/**\") that fit on one line\n if (!isJSDocComment(comment)) continue\n if (comment.loc.start.line !== comment.loc.end.line) continue\n\n // Strip the leading \"*\" left over from \"/**\" and normalize\n const content = comment.value.replace(/^\\*/, \"\").trim()\n\n // An empty JSDoc (\"/** */\") has nothing to expand onto its\n // own line, so it is left alone\n if (content.length === 0) continue\n\n context.report({\n loc: comment.loc,\n messageId: \"singleLine\",\n fix(fixer) {\n const indent = \" \".repeat(comment.loc.start.column)\n const expanded = `/**\\n${indent} * ${content}\\n${indent} */`\n return fixer.replaceTextRange(comment.range, expanded)\n },\n })\n }\n },\n }\n }\n}\n\nexport default new NoSingleLineJSDoc()\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { firstCommentContentChar, isDirectiveComment } from \"@/lib/utils/comments\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"capitalize\"\n\n/**\n * Flags a comment whose first prose letter is lowercase and capitalizes it, so\n * comments read as sentences. Continuation lines of a wrapped `//` comment,\n * tooling directives, and comments that open with code, a symbol, or a URL are\n * left alone.\n */\nclass RequireCapitalizedComments extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-capitalized-comments\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n fixable: \"code\",\n docs: {\n description: \"Require a comment to start with an uppercase letter.\",\n recommended: true,\n category: \"base\",\n },\n schema: [],\n messages: {\n capitalize: nitpick({\n problem: \"This comment starts with a lowercase letter.\",\n why: \"A comment reads as a sentence, and a sentence starts with a capital letter\",\n fix: \"Capitalize the first letter of the comment\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n /**\n * Checks whether a line comment continues a wrapped one, i.e the previous\n * physical line is itself a line comment.\n * @param comment The comment to test.\n * @returns True if the comment is a continuation line.\n */\n const isContinuation = (comment: TSESTree.Comment): boolean => {\n if (comment.type !== \"Line\") return false\n\n const previous = context.sourceCode.lines[comment.loc.start.line - 2]\n return previous !== undefined && /^\\s*\\/\\//.test(previous)\n }\n\n return {\n Program() {\n for (const comment of context.sourceCode.getAllComments()) {\n if (isDirectiveComment(comment) || isContinuation(comment)) continue\n\n const content = firstCommentContentChar(comment)\n if (content === null || !/\\p{Ll}/u.test(content.char)) continue\n\n // Leave a comment that opens with a URL alone, capitalizing it\n // would break the link\n if (/^(?:https?:\\/\\/|www\\.)/u.test(context.sourceCode.getText().slice(content.index))) continue\n\n context.report({\n loc: {\n start: context.sourceCode.getLocFromIndex(content.index),\n end: context.sourceCode.getLocFromIndex(content.index + content.char.length),\n },\n messageId: \"capitalize\",\n fix: fixer =>\n fixer.replaceTextRange(\n [content.index, content.index + content.char.length],\n content.char.toUpperCase(),\n ),\n })\n }\n },\n }\n }\n}\n\nexport default new RequireCapitalizedComments()\n","import type { TSESTree } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { type FunctionNode, getFunctionName, someReturn, type VisitorKeys } from \"@/lib/utils/functions\"\n\n/**\n * Checks whether a name follows the `PascalCase` convention React uses to\n * distinguish component functions from plain functions and DOM tags.\n * @param name The function name to test.\n * @returns True if the name starts with an uppercase letter.\n */\nexport function isReactComponentName(name: string): boolean {\n return /^[A-Z]/.test(name)\n}\n\n/**\n * Checks whether a name is a React hook, i.e. `use` followed by a capitalized\n * word such as `useState` or `useMenuActions`.\n * @param name The function name to test.\n * @returns True if the name is a hook name.\n */\nexport function isHookName(name: string): boolean {\n return CONSTANTS.REACT.HOOK.test(name)\n}\n\n/**\n * Checks whether a name is a context-consumer hook, i.e. a `use…Context` wrapper\n * such as `useTreeViewContext` (the bare `useContext` is excluded).\n * @param name The function name to test.\n * @returns True if the name is a context-hook name.\n */\nexport function isContextHookName(name: string): boolean {\n return CONSTANTS.REACT.CONTEXT_HOOK.test(name)\n}\n\n/**\n * Checks whether an expression is, on its face, a function value: a function or\n * arrow expression, or a `useCallback` call (which always yields a function).\n * @param node The expression to inspect, if any.\n * @returns True if the expression evaluates to a function.\n */\nexport function isFunctionValue(node: TSESTree.Expression | null | undefined): boolean {\n if (!node) return false\n if (node.type === \"ArrowFunctionExpression\" || node.type === \"FunctionExpression\") return true\n\n return node.type === \"CallExpression\" && node.callee.type === \"Identifier\" && node.callee.name === \"useCallback\"\n}\n\n/**\n * Checks whether an expression evaluates to JSX, following the branches a\n * component commonly returns through (ternaries, `&&`, comma sequences).\n * @param node The expression to inspect, if any.\n * @returns True if the expression can produce a JSX element or fragment.\n */\nexport function isJsxExpression(node: TSESTree.Expression | null | undefined): boolean {\n if (!node) return false\n\n switch (node.type) {\n case \"JSXElement\":\n case \"JSXFragment\":\n return true\n case \"ConditionalExpression\":\n return isJsxExpression(node.consequent) || isJsxExpression(node.alternate)\n case \"LogicalExpression\":\n return isJsxExpression(node.left) || isJsxExpression(node.right)\n case \"SequenceExpression\":\n return isJsxExpression(node.expressions.at(-1))\n default:\n return false\n }\n}\n\n/**\n * Checks whether a function returns JSX, i.e. whether it looks like it renders\n * a React element.\n * @param fn The function node to inspect.\n * @param visitorKeys The AST visitor keys, used to walk the function body.\n * @returns True if the function returns JSX.\n */\nexport function functionReturnsJsx(fn: FunctionNode, visitorKeys: VisitorKeys): boolean {\n // An arrow with an expression body returns that expression directly\n if (fn.type === \"ArrowFunctionExpression\" && fn.body.type !== \"BlockStatement\") {\n return isJsxExpression(fn.body)\n }\n\n return someReturn(fn.body, visitorKeys, isJsxExpression)\n}\n\n/**\n * Checks whether a function is a React component or a custom hook, the scopes\n * where `useMemo` is available and where local derivations should be memoized.\n * @param fn The function node to inspect.\n * @param visitorKeys The AST visitor keys, used to walk the function body.\n * @returns True if the function is a component or a hook.\n */\nexport function isComponentOrHook(fn: FunctionNode, visitorKeys: VisitorKeys): boolean {\n const name = getFunctionName(fn)\n if (name === undefined) return false\n\n return isHookName(name) || (isReactComponentName(name) && functionReturnsJsx(fn, visitorKeys))\n}\n\n/**\n * Checks whether an expression contains a non-hook call, without descending into\n * nested functions, so a value built by a helper or method call is caught but a\n * callback's inner calls are not.\n * @param node The AST node to search from.\n * @param visitorKeys The AST visitor keys, used to walk the subtree.\n * @returns True if a non-hook call is found.\n */\nfunction hasNonHookCall(node: TSESTree.Node, visitorKeys: VisitorKeys): boolean {\n if (node.type === \"CallExpression\") {\n return !(node.callee.type === \"Identifier\" && isHookName(node.callee.name))\n }\n\n for (const key of visitorKeys[node.type] ?? []) {\n const value = (node as unknown as Record<string, unknown>)[key]\n const children = Array.isArray(value) ? value : [value]\n\n for (const child of children) {\n const childNode = child as TSESTree.Node | null | undefined\n if (!childNode || typeof childNode.type !== \"string\") continue\n if (CONSTANTS.FUNCTIONS.NODE_TYPES.has(childNode.type)) continue\n if (hasNonHookCall(childNode, visitorKeys)) return true\n }\n }\n\n return false\n}\n\n/**\n * Checks whether an expression is a derived value that belongs in a `useMemo`,\n * i.e. it computes something through a non-hook call. A function value (a\n * callback) and a bare hook result are not derived values.\n * @param node The expression to inspect.\n * @param visitorKeys The AST visitor keys, used to walk the expression.\n * @returns True if the expression is a derived value.\n */\nexport function isDerivedValue(node: TSESTree.Expression, visitorKeys: VisitorKeys): boolean {\n if (node.type === \"ArrowFunctionExpression\" || node.type === \"FunctionExpression\") return false\n\n return hasNonHookCall(node, visitorKeys)\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { type FunctionNode, getDocumentableNode, isVoidFunction, parameterDocs } from \"@/lib/utils/functions\"\nimport { getJSDocParamNames, getLeadingJSDoc, hasJSDocReturnsTag } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { functionReturnsJsx } from \"@/lib/utils/react\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"missingParam\" | \"missingReturns\"\n\n/**\n * Checks a function that already carries a JSDoc: every parameter must have an\n * `@param`, and a function returning a value must have a `@returns`. A void or\n * `Promise<void>` function needs no `@returns`, a component returning JSX is\n * exempt from it too.\n */\nclass RequireCompleteJSDoc extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-complete-jsdoc\"\n readonly defaultOptions: Options = []\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require a function's JSDoc to document every parameter and its return value.\",\n recommended: true,\n category: \"base\",\n },\n schema: [],\n messages: {\n missingParam: nitpick({\n problem: \"The JSDoc does not document the parameter `{{name}}`.\",\n why: \"A JSDoc that skips a parameter drifts from the signature and stops describing what the function takes\",\n fix: \"Add an `@param {{name}} ...` line describing what it is\",\n }),\n missingReturns: nitpick({\n problem: \"The JSDoc has no `@returns`, but this function returns a value.\",\n why: \"A documented function should say what it hands back, a missing `@returns` leaves the caller guessing\",\n fix: \"Add a `@returns ...` line describing the value (a void or `Promise<void>` function needs none)\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n /**\n * Creates the rule listener.\n * @param context The rule context.\n * @returns The rule listener.\n */\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n /**\n * Checks a documented function's tags against its signature.\n * @param fn The function to inspect.\n */\n const check = (fn: FunctionNode): void => {\n const jsdoc = getLeadingJSDoc(context.sourceCode, getDocumentableNode(fn))\n if (jsdoc === null) return\n\n const documented = getJSDocParamNames(jsdoc)\n const docs = parameterDocs(fn)\n const plainNames = new Set(docs.filter(doc => doc.kind === \"name\").map(doc => doc.name))\n\n for (const doc of docs) {\n if (doc.kind === \"name\") {\n if (!documented.has(doc.name)) {\n context.report({\n node: doc.node,\n messageId: \"missingParam\",\n data: { name: doc.name },\n })\n }\n\n continue\n }\n\n if (doc.names.every(entry => documented.has(entry.name))) continue\n\n // A destructured object may instead be documented under one name\n // standing for the whole object, e.g. \"@param options\"\n const properties = new Set(doc.names.map(entry => entry.name))\n const documentedAsWhole = [...documented].some(name => !properties.has(name) && !plainNames.has(name))\n if (documentedAsWhole) continue\n\n for (const entry of doc.names) {\n if (documented.has(entry.name)) continue\n\n context.report({\n node: entry.node,\n messageId: \"missingParam\",\n data: { name: entry.name },\n })\n }\n }\n\n if (hasJSDocReturnsTag(jsdoc)) return\n if (isVoidFunction(fn, context.sourceCode.visitorKeys)) return\n\n // A component's render result is obvious, so it needs no \"@returns\"\n if (functionReturnsJsx(fn, context.sourceCode.visitorKeys)) return\n\n context.report({ node: jsdoc, messageId: \"missingReturns\" })\n }\n\n return {\n FunctionDeclaration(node) {\n check(node)\n },\n FunctionExpression(node) {\n check(node)\n },\n ArrowFunctionExpression(node) {\n check(node)\n },\n }\n }\n}\n\nexport default new RequireCompleteJSDoc()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\n\n/**\n * A framework Nitpicker ships a dedicated rule category and shared config for.\n */\nexport type Framework = \"adonisjs\" | \"react\"\n\n/**\n * The human-readable label for each framework, used in messages.\n */\nexport const FRAMEWORK_LABELS: Record<Framework, string> = {\n adonisjs: \"AdonisJS\",\n react: \"React\",\n}\n\n/**\n * Collects the module specifiers imported by a source file.\n * @param sourceCode The source code of the linted file.\n * @returns The list of imported module specifiers.\n */\nfunction importSources(sourceCode: Readonly<TSESLint.SourceCode>): string[] {\n const sources: string[] = []\n\n for (const statement of sourceCode.ast.body) {\n if (statement.type === \"ImportDeclaration\") {\n sources.push(String(statement.source.value))\n }\n }\n\n return sources\n}\n\n/**\n * Detects which supported frameworks a file appears to use, based on its imports\n * and file name.\n * @param sourceCode The source code of the linted file.\n * @param filename The path of the linted file.\n * @returns The set of frameworks detected in the file.\n */\nexport function detectFrameworks(sourceCode: Readonly<TSESLint.SourceCode>, filename: string): Set<Framework> {\n const detected = new Set<Framework>()\n const sources = importSources(sourceCode)\n\n if (sources.some(source => source.startsWith(\"@adonisjs/\") || CONSTANTS.FRAMEWORKS.ADONIS_SUBPATH.test(source))) {\n detected.add(\"adonisjs\")\n }\n\n const importsReact = sources.some(\n source => source === \"react\" || source.startsWith(\"react/\") || source === \"react-dom\",\n )\n if (importsReact || CONSTANTS.FRAMEWORKS.REACT_FILE.test(filename)) {\n detected.add(\"react\")\n }\n\n return detected\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { detectFrameworks, FRAMEWORK_LABELS, type Framework } from \"@/lib/utils/frameworks\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ ignore: Framework[] }]\ntype MessageIds = \"missingConfig\"\n\n/**\n * Warns when a file uses a framework (AdonisJS, React) whose Nitpicker config is\n * not enabled. Enabling the matching config (which sets a settings flag) or\n * turning off this rule silences it.\n */\nclass RequireFrameworkConfig extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-framework-config\"\n\n readonly defaultOptions: Options = [{ ignore: [] }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Warn when a file uses a framework whose Nitpicker config is not enabled.\",\n recommended: true,\n category: \"base\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n ignore: {\n type: \"array\",\n items: {\n type: \"string\",\n enum: [\"adonisjs\", \"react\"],\n },\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n missingConfig: nitpick({\n problem: \"This file uses {{framework}} but the Nitpicker {{framework}} rules are not enabled.\",\n why: \"Framework rules only run when you opt into the matching config, so files like this one go unchecked\",\n fix: \"Add `nitpicker.configs.{{config}}` (scoped to these files) to your ESLint config, or turn off `nitpicker/require-framework-config`\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const ignored = new Set(options[0]?.ignore ?? [])\n\n // Each framework config stamps \"settings.nitpicker<framework> = true\"\n const enabled = (context.settings[CONSTANTS.PLUGIN_NAME] ?? {}) as Partial<Record<Framework, boolean>>\n\n return {\n Program(node) {\n const detected = detectFrameworks(context.sourceCode, context.filename)\n\n for (const framework of detected) {\n if (ignored.has(framework) || enabled[framework]) continue\n\n context.report({\n node,\n messageId: \"missingConfig\",\n data: { framework: FRAMEWORK_LABELS[framework], config: framework },\n })\n }\n },\n }\n }\n}\n\nexport default new RequireFrameworkConfig()\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport {\n type FunctionNode,\n getDocumentableNode,\n getFunctionName,\n isDynamicImportThunk,\n isTopLevel,\n} from \"@/lib/utils/functions\"\nimport { hasLeadingJSDoc } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { functionReturnsJsx, isReactComponentName } from \"@/lib/utils/react\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\n/**\n * The function kinds that can be required to carry a JSDoc on top of the\n * top-level functions the rule always checks.\n */\ntype Include = \"class-methods\" | \"object-methods\" | \"nested\"\n\ntype Options = [{ include: Include[]; ignore: string[] }]\ntype MessageIds = \"missingJSDoc\"\n\n/**\n * Requires a JSDoc comment on top-level functions, plus whichever of class\n * methods, object-literal methods, and nested named functions the `include`\n * option asks for. React component functions are exempt.\n */\nclass RequireFunctionJSDoc extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-function-jsdoc\"\n\n readonly defaultOptions: Options = [{ include: [\"class-methods\", \"nested\"], ignore: [] }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require a JSDoc comment on functions, except React component functions.\",\n recommended: true,\n },\n schema: [\n {\n type: \"object\",\n properties: {\n include: {\n type: \"array\",\n items: {\n type: \"string\",\n enum: [\"class-methods\", \"object-methods\", \"nested\"],\n },\n },\n ignore: {\n type: \"array\",\n items: { type: \"string\" },\n },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n missingJSDoc: nitpick({\n problem: \"The function `{{name}}` has no JSDoc comment.\",\n why: \"A function must document its purpose, parameters, and return value, React component functions are the only exception\",\n fix: \"Add a `/** ... */` JSDoc block immediately above it describing what it does\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const include = new Set<Include>(options[0]?.include ?? [\"class-methods\", \"nested\"])\n\n // Names exempt from the requirement, for an inherited or framework member\n // whose purpose is fixed by the interface it implements\n const ignore = new Set(options[0]?.ignore ?? [])\n\n /**\n * Reports a function that carries no JSDoc, once the exemptions are applied.\n * @param fn The function to inspect.\n * @param documentable The node whose leading comments hold the JSDoc.\n * @param name The function's written name.\n * @param node The node to report on.\n */\n const report = (fn: FunctionNode, documentable: TSESTree.Node, name: string, node: TSESTree.Node): void => {\n if (ignore.has(name)) return\n\n // Lazy dynamic-import thunks carry no logic worth documenting\n if (isDynamicImportThunk(fn)) return\n\n // React component functions are exempt from the JSDoc requirement\n if (isReactComponentName(name) && functionReturnsJsx(fn, context.sourceCode.visitorKeys)) return\n\n if (hasLeadingJSDoc(context.sourceCode, documentable)) return\n\n context.report({\n node,\n messageId: \"missingJSDoc\",\n data: { name },\n })\n }\n\n /**\n * Checks a plain function or arrow const, at module scope always and deeper\n * only when nested functions are opted into.\n * @param fn The function to inspect.\n * @param node The node to report on.\n */\n const checkDeclared = (fn: FunctionNode, node: TSESTree.Node): void => {\n const name = getFunctionName(fn)\n if (name === undefined) return\n\n const documentable = getDocumentableNode(fn)\n\n // A member is handled by its own listener, not as a declaration\n if (documentable.type === \"MethodDefinition\" || documentable.type === \"Property\") return\n\n if (!isTopLevel(documentable) && !include.has(\"nested\")) return\n\n report(fn, documentable, name, node)\n }\n\n /**\n * Resolves the written name of a class or object member.\n * @param key The member key to read.\n * @returns The name, or `undefined` for a key this rule cannot read.\n */\n const memberName = (key: TSESTree.Node): string | undefined => {\n if (key.type === \"Identifier\") return key.name\n if (key.type === \"Literal\" && typeof key.value === \"string\") return key.value\n\n return undefined\n }\n\n return {\n FunctionDeclaration(node) {\n checkDeclared(node, node.id ?? node)\n },\n VariableDeclarator(node) {\n if (!node.init) return\n if (node.init.type !== \"ArrowFunctionExpression\" && node.init.type !== \"FunctionExpression\") return\n\n checkDeclared(node.init, node.id)\n },\n MethodDefinition(node) {\n if (!include.has(\"class-methods\") || node.computed) return\n if (node.value.type !== \"FunctionExpression\") return\n\n const name = memberName(node.key)\n if (name === undefined) return\n\n report(node.value, node, name, node.key)\n },\n Property(node) {\n if (!include.has(\"object-methods\") || node.computed) return\n if (node.value.type !== \"ArrowFunctionExpression\" && node.value.type !== \"FunctionExpression\") return\n\n const name = memberName(node.key)\n if (name === undefined) return\n\n report(node.value, node, name, node.key)\n },\n }\n }\n}\n\nexport default new RequireFunctionJSDoc()\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { isJSDocComment } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"openingLine\" | \"closingLine\"\n\n/**\n * Flags a multi-line JSDoc that shares its opening or closing delimiter line with\n * prose, so every block reads as an aligned column of ` * ` lines between a bare\n * opener and a bare closer.\n */\nclass RequireJSDocDelimiterLines extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-jsdoc-delimiter-lines\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"layout\",\n fixable: \"whitespace\",\n docs: {\n description: \"Require a JSDoc's opening and closing delimiters to sit on their own lines.\",\n recommended: true,\n category: \"base\",\n },\n schema: [],\n messages: {\n openingLine: nitpick({\n problem: \"This JSDoc starts its text on the same line as the opening delimiter.\",\n why: \"A block that opens mid-line breaks the aligned column of markers and reads unevenly\",\n fix: \"Move the text to the next line so the opening delimiter sits alone\",\n }),\n closingLine: nitpick({\n problem: \"This JSDoc ends its text on the same line as the closing delimiter.\",\n why: \"A block that closes mid-line breaks the aligned column of markers and reads unevenly\",\n fix: \"Move the closing delimiter onto its own line below the text\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n /**\n * Reports a JSDoc whose delimiters share a line with prose.\n * @param comment The JSDoc comment to inspect.\n */\n const check = (comment: TSESTree.Comment): void => {\n // A single-line JSDoc is \"no-single-line-jsdoc\"'s business, not this rule's\n if (comment.loc.start.line === comment.loc.end.line) return\n\n const segments = comment.value.split(\"\\n\")\n const indent = \" \".repeat(comment.loc.start.column)\n\n // \"comment.value\" keeps the \"*\" of the opener, so anything after it is text\n const opening = (segments[0] ?? \"\").replace(/^\\*/, \"\")\n if (opening.trim() !== \"\") {\n const start = comment.range[0] + 3\n const spacer = opening.startsWith(\" \") ? \"\" : \" \"\n\n context.report({\n loc: {\n start: comment.loc.start,\n end: context.sourceCode.getLocFromIndex(start + opening.length),\n },\n messageId: \"openingLine\",\n fix: fixer => fixer.insertTextBeforeRange([start, start], `\\n${indent} *${spacer}`),\n })\n }\n\n const closing = (segments.at(-1) ?? \"\").replace(/^\\s*\\*?/, \"\")\n if (closing.trim() !== \"\") {\n const end = comment.range[1] - 2\n\n context.report({\n loc: {\n start: context.sourceCode.getLocFromIndex(end),\n end: comment.loc.end,\n },\n messageId: \"closingLine\",\n fix: fixer => fixer.insertTextBeforeRange([end, end], `\\n${indent} `),\n })\n }\n }\n\n return {\n Program() {\n for (const comment of context.sourceCode.getAllComments()) {\n if (isJSDocComment(comment)) check(comment)\n }\n },\n }\n }\n}\n\nexport default new RequireJSDocDelimiterLines()\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\n\n/**\n * Rebuilds an object literal across multiple lines, indenting each property one\n * level past the line the object opens on and closing the brace back at that\n * level, so the result matches the surrounding indentation.\n * @param sourceCode The source code of the linted file.\n * @param node The object expression to expand.\n * @param indent The number of spaces in one indentation level.\n * @returns The multiline object literal source text.\n */\nexport function expandObjectLiteral(\n sourceCode: Readonly<TSESLint.SourceCode>,\n node: TSESTree.ObjectExpression,\n indent: number,\n): string {\n const openingLine = sourceCode.lines[node.loc.start.line - 1] ?? \"\"\n const baseIndent = openingLine.match(/^\\s*/)?.[0] ?? \"\"\n const propertyIndent = baseIndent + \" \".repeat(indent)\n\n const body = node.properties.map(property => `${propertyIndent}${sourceCode.getText(property)}`).join(\",\\n\")\n\n return `{\\n${body},\\n${baseIndent}}`\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { expandObjectLiteral } from \"@/lib/utils/objects\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ maxKeys: number; indent: number }]\ntype MessageIds = \"shouldWrap\"\n\n/**\n * Flags an object literal that packs more than `maxKeys` properties onto a\n * single line, and expands it to one property per line, since a wide inline\n * object is harder to scan, diff, and edit than a stacked one.\n */\nclass RequireMultilineObject extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-multiline-object\"\n readonly defaultOptions: Options = [\n {\n maxKeys: CONSTANTS.OBJECTS.MAX_INLINE_KEYS,\n indent: CONSTANTS.OBJECTS.INDENT_WIDTH,\n },\n ]\n\n readonly meta = {\n type: \"suggestion\",\n fixable: \"code\",\n docs: {\n description: \"Require an object literal with more than a few properties to span multiple lines.\",\n recommended: true,\n category: \"base\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n maxKeys: { type: \"integer\", minimum: 1 },\n indent: { type: \"integer\", minimum: 1 },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n shouldWrap: nitpick({\n problem: \"This object literal has {{count}} properties packed onto a single line.\",\n why: \"An object with more than {{max}} properties is easier to scan, diff, and edit when each property sits on its own line\",\n fix: \"Break it across multiple lines, one property per line with a trailing comma\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const maxKeys = options[0]?.maxKeys ?? CONSTANTS.OBJECTS.MAX_INLINE_KEYS\n const indent = options[0]?.indent ?? CONSTANTS.OBJECTS.INDENT_WIDTH\n\n return {\n ObjectExpression(node) {\n if (node.properties.length <= maxKeys) return\n if (node.loc.start.line !== node.loc.end.line) return\n\n // The fix rebuilds the object from its properties alone, so a\n // comment between them would be dropped, only auto-fix a clean one\n const hasComments = context.sourceCode.getCommentsInside(node).length > 0\n\n context.report({\n node,\n messageId: \"shouldWrap\",\n data: { count: node.properties.length, max: maxKeys },\n fix: hasComments\n ? null\n : fixer => fixer.replaceText(node, expandObjectLiteral(context.sourceCode, node, indent)),\n })\n },\n }\n }\n}\n\nexport default new RequireMultilineObject()\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = [{ max: number }]\ntype MessageIds = \"tooLong\"\n\n/**\n * Flags a class string in a `className` longer than the configured limit, so a\n * wall of Tailwind utilities gets broken into shorter pieces. A long string\n * inside a `cn(...)` call is caught too, since `cn` does not break it up.\n */\nclass MaxClassNameLength extends NitpickerRule<MessageIds, Options> {\n readonly name = \"max-classname-length\"\n\n readonly defaultOptions: Options = [{ max: CONSTANTS.REACT.MAX_CLASSNAME_LENGTH }]\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Enforce a maximum length for a `className` class string.\",\n recommended: true,\n category: \"react\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n max: { type: \"integer\", minimum: 1 },\n },\n additionalProperties: false,\n },\n ],\n messages: {\n tooLong: nitpick({\n problem: \"This `className` string is {{length}} characters, over the {{max}}-character limit.\",\n why: \"A long wall of Tailwind classes is hard to scan and diff, and it overflows the line\",\n fix: \"Break the classes across multiple lines, grouping related ones into separate `cn()` arguments\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>, options: Options): TSESLint.RuleListener {\n const max = options[0]?.max ?? CONSTANTS.REACT.MAX_CLASSNAME_LENGTH\n\n /**\n * Collects the class strings inside a className value, including those\n * nested in a `cn(...)` call, without descending into a nested function.\n * @param node The node to search from.\n * @param found The collected strings, appended in place.\n */\n const collect = (\n node: TSESTree.Node | null | undefined,\n found: { node: TSESTree.Node; text: string }[],\n ): void => {\n if (!node) return\n\n if (node.type === \"Literal\") {\n if (typeof node.value === \"string\") found.push({ node, text: node.value })\n return\n }\n\n if (node.type === \"TemplateLiteral\") {\n if (node.expressions.length === 0) found.push({ node, text: node.quasis[0]?.value.cooked ?? \"\" })\n return\n }\n\n for (const key of context.sourceCode.visitorKeys[node.type] ?? []) {\n const value = (node as unknown as Record<string, unknown>)[key]\n const children = Array.isArray(value) ? value : [value]\n\n for (const child of children) {\n const childNode = child as TSESTree.Node | null | undefined\n if (!childNode || typeof childNode.type !== \"string\") continue\n if (CONSTANTS.FUNCTIONS.NODE_TYPES.has(childNode.type)) continue\n collect(childNode, found)\n }\n }\n }\n\n return {\n JSXAttribute(node) {\n if (node.name.type !== \"JSXIdentifier\" || node.name.name !== \"className\" || node.value === null) return\n\n const found: { node: TSESTree.Node; text: string }[] = []\n collect(node.value, found)\n\n for (const { node: literal, text } of found) {\n if (text.length <= max) continue\n\n context.report({\n node: literal,\n messageId: \"tooLong\",\n data: { length: text.length, max },\n })\n }\n },\n }\n }\n}\n\nexport default new MaxClassNameLength()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"jsxComment\"\n\n/**\n * Flags an inline comment placed inside JSX (a `{ }` container holding only a\n * comment), which usually labels a section that should be its own named\n * component rather than a prose marker.\n */\nclass NoJSXComments extends NitpickerRule<MessageIds, Options> {\n readonly name = \"no-jsx-comments\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Disallow inline `{/* ... */}` comments inside JSX.\",\n recommended: true,\n category: \"react\",\n },\n schema: [],\n messages: {\n jsxComment: nitpick({\n problem: \"This JSX holds an inline `{/* ... */}` comment.\",\n why: \"A comment labeling a JSX section is a sign it should be its own named component, JSX should read as structure, not carry prose markers\",\n fix: \"Extract the section into a named sub-component whose name says what the comment said, or drop the comment\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n JSXExpressionContainer(node) {\n // Only a comment-only JSX container parses its inner expression as\n // empty, an ordinary value container never does\n if (node.expression.type !== \"JSXEmptyExpression\") return\n if (context.sourceCode.getCommentsInside(node).length === 0) return\n\n context.report({ node, messageId: \"jsxComment\" })\n },\n }\n }\n}\n\nexport default new NoJSXComments()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { isContextHookName } from \"@/lib/utils/react\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"destructure\"\n\n/**\n * Flags a context-consumer hook (`use…Context`) whose result is bound whole to a\n * variable instead of being destructured, since destructuring names exactly what\n * the caller uses and reads better than repeated `context.member` access.\n */\nclass RequireContextHookDestructure extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-context-hook-destructure\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require the result of a context-consumer hook to be destructured.\",\n recommended: true,\n category: \"react\",\n },\n schema: [],\n messages: {\n destructure: nitpick({\n problem: \"`{{hook}}` is bound whole instead of destructured.\",\n why: \"Destructuring at the call site names exactly what the caller uses and reads better than repeated `{{name}}.member` access\",\n fix: \"Destructure the members in use, e.g. `const { a, b } = {{hook}}()`\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n VariableDeclarator(node) {\n if (node.id.type !== \"Identifier\" || node.init?.type !== \"CallExpression\") return\n if (node.init.callee.type !== \"Identifier\" || !isContextHookName(node.init.callee.name)) return\n\n context.report({\n node,\n messageId: \"destructure\",\n data: { hook: node.init.callee.name, name: node.id.name },\n })\n },\n }\n }\n}\n\nexport default new RequireContextHookDestructure()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { enclosingFunction } from \"@/lib/utils/functions\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { isComponentOrHook, isDerivedValue } from \"@/lib/utils/react\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"useMemo\"\n\n/**\n * Flags a `const` in a component or hook whose value is derived through a\n * non-hook call (`list.find(...)`, `format(x)`), which recomputes on every\n * render, and asks for it to move into a `useMemo`.\n */\nclass RequireDerivedUseMemo extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-derived-usememo\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require a derived value in a component or hook to be memoized with useMemo.\",\n recommended: true,\n category: \"react\",\n },\n schema: [],\n messages: {\n useMemo: nitpick({\n problem: \"This derived value is computed inline on every render.\",\n why: \"A value derived through a call is recomputed each render and has nowhere to document itself, a useMemo makes it stable and gives it a JSDoc home\",\n fix: \"Wrap it in `useMemo(() => ..., [deps])` with a JSDoc describing the value, even for a one-liner\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n VariableDeclarator(node) {\n if (node.parent.type !== \"VariableDeclaration\" || node.parent.kind !== \"const\") return\n if (node.id.type !== \"Identifier\" || node.init === null) return\n\n // Only a direct local of a component or hook can move into a useMemo\n const fn = enclosingFunction(node)\n if (fn === null || !isComponentOrHook(fn, context.sourceCode.visitorKeys)) return\n\n if (!isDerivedValue(node.init, context.sourceCode.visitorKeys)) return\n\n context.report({ node, messageId: \"useMemo\" })\n },\n }\n }\n}\n\nexport default new RequireDerivedUseMemo()\n","import { ASTUtils, type TSESLint, type TSESTree } from \"@typescript-eslint/utils\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { type FunctionNode, getFunctionName, someReturn } from \"@/lib/utils/functions\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport { isFunctionValue, isHookName } from \"@/lib/utils/react\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"wrapInObject\"\n\n/**\n * Flags a custom hook that returns a bare function (directly or through a local\n * `useCallback`), and wraps it in an object, so the hook can grow new members\n * later without breaking every call site.\n */\nclass RequireHookObjectReturn extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-hook-object-return\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n fixable: \"code\",\n docs: {\n description: \"Require a custom hook to return an object rather than a bare function.\",\n recommended: true,\n category: \"react\",\n },\n schema: [],\n messages: {\n wrapInObject: nitpick({\n problem: \"This hook returns a bare function instead of an object.\",\n why: \"Returning an object lets the hook expose new members later without changing every call site, a bare function locks its shape\",\n fix: \"Return the function inside an object, e.g. `return { handleThing }`\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n /**\n * Checks whether a returned expression is a function, resolving an identifier\n * through its local declaration such as a `useCallback` const.\n * @param argument The returned expression.\n * @returns True if the expression is a function.\n */\n const returnsFunction = (argument: TSESTree.Expression): boolean => {\n if (isFunctionValue(argument)) return true\n if (argument.type !== \"Identifier\") return false\n\n const variable = ASTUtils.findVariable(context.sourceCode.getScope(argument), argument.name)\n const declarator = variable?.defs.at(-1)?.node\n return declarator?.type === \"VariableDeclarator\" && isFunctionValue(declarator.init)\n }\n\n /**\n * Reports a hook that hands back a bare function.\n * @param argument The returned expression to report on.\n */\n const report = (argument: TSESTree.Expression): void => {\n context.report({\n node: argument,\n messageId: \"wrapInObject\",\n fix:\n argument.type === \"Identifier\"\n ? fixer => fixer.replaceText(argument, `{ ${argument.name} }`)\n : undefined,\n })\n }\n\n /**\n * Checks a hook's returns for a bare function.\n * @param fn The function to inspect.\n */\n const check = (fn: FunctionNode): void => {\n const name = getFunctionName(fn)\n if (name === undefined || !isHookName(name)) return\n\n // An arrow with an expression body returns that expression directly\n if (fn.type === \"ArrowFunctionExpression\" && fn.body.type !== \"BlockStatement\") {\n if (returnsFunction(fn.body)) report(fn.body)\n return\n }\n\n someReturn(fn.body, context.sourceCode.visitorKeys, argument => {\n if (argument !== null && returnsFunction(argument)) report(argument)\n return false\n })\n }\n\n return {\n FunctionDeclaration(node) {\n check(node)\n },\n FunctionExpression(node) {\n check(node)\n },\n ArrowFunctionExpression(node) {\n check(node)\n },\n }\n }\n}\n\nexport default new RequireHookObjectReturn()\n","import type { TSESLint, TSESTree } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { NitpickerRule } from \"@/lib/rule\"\nimport { getJSDocLineTag, hasLeadingJSDoc } from \"@/lib/utils/jsdocs\"\nimport { nitpick } from \"@/lib/utils/messages\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\ntype Options = []\ntype MessageIds = \"missingJSDoc\" | \"missingParam\"\n\n/**\n * Requires a JSDoc above a `useMemo` or `useCallback` so a memoized value or\n * handler documents its purpose. A `useCallback` must also carry an `@param` per\n * parameter, since it is a function.\n */\nclass RequireMemoCallbackJSDoc extends NitpickerRule<MessageIds, Options> {\n readonly name = \"require-memo-callback-jsdoc\"\n\n readonly defaultOptions: Options = []\n\n readonly meta = {\n type: \"suggestion\",\n docs: {\n description: \"Require a JSDoc on a useMemo or useCallback (with an `@param` per useCallback parameter).\",\n recommended: true,\n category: \"react\",\n },\n schema: [],\n messages: {\n missingJSDoc: nitpick({\n problem: \"This `{{hook}}` has no JSDoc.\",\n why: \"A memoized value or handler should document what it is, so its purpose is clear without reading the factory\",\n fix: \"Add a `/** ... */` JSDoc above the `const`\",\n }),\n missingParam: nitpick({\n problem: \"This `useCallback`'s JSDoc documents fewer parameters than the callback takes.\",\n why: \"A callback is a function, so each parameter it takes should be documented like any other\",\n fix: \"Add an `@param` line for each parameter of the callback\",\n }),\n },\n } satisfies TSESLint.RuleMetaData<MessageIds, NitpickerRuleDocs, Options>\n\n create(context: Readonly<TSESLint.RuleContext<MessageIds, Options>>): TSESLint.RuleListener {\n return {\n VariableDeclarator(node) {\n if (node.init?.type !== \"CallExpression\" || node.init.callee.type !== \"Identifier\") return\n if (!CONSTANTS.REACT.MEMO_HOOKS.has(node.init.callee.name)) return\n\n // The JSDoc sits above the whole declaration, or its export\n let target: TSESTree.Node = node.parent\n if (target.parent?.type === \"ExportNamedDeclaration\") target = target.parent\n\n if (!hasLeadingJSDoc(context.sourceCode, target)) {\n context.report({\n node: node.id,\n messageId: \"missingJSDoc\",\n data: { hook: node.init.callee.name },\n })\n return\n }\n\n if (node.init.callee.name !== \"useCallback\") return\n\n const callback = node.init.arguments[0]\n if (callback?.type !== \"ArrowFunctionExpression\" && callback?.type !== \"FunctionExpression\") return\n if (callback.params.length === 0) return\n\n const comment = context.sourceCode.getCommentsBefore(target).at(-1)\n const documented = (comment?.value.split(\"\\n\") ?? []).filter(\n line => getJSDocLineTag(line) === \"param\",\n ).length\n\n if (documented < callback.params.length) {\n context.report({ node: node.id, messageId: \"missingParam\" })\n }\n },\n }\n }\n}\n\nexport default new RequireMemoCallbackJSDoc()\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport type { NitpickerRuleDocs } from \"@/lib/utils/rules\"\n\nimport migrationTableOrder from \"@/rules/adonisjs/migrationTableOrder\"\nimport requireControllerJSDoc from \"@/rules/adonisjs/requireControllerJSDoc\"\nimport requireMigrationJSDoc from \"@/rules/adonisjs/requireMigrationJSDoc\"\nimport requireValidatedRequest from \"@/rules/adonisjs/requireValidatedRequest\"\nimport catchErrorName from \"@/rules/base/catchErrorName\"\nimport maxJSDocDescriptionLength from \"@/rules/base/maxJSDocDescriptionLength\"\nimport maxLineCommentLength from \"@/rules/base/maxLineCommentLength\"\nimport noAliasVariables from \"@/rules/base/noAliasVariables\"\nimport noBritishEnglish from \"@/rules/base/noBritishEnglish\"\nimport noDecorativeCommentSeparators from \"@/rules/base/noDecorativeCommentSeparators\"\nimport noEmDash from \"@/rules/base/noEmDash\"\nimport noEmojis from \"@/rules/base/noEmojis\"\nimport noJSDocBlankBeforeTags from \"@/rules/base/noJSDocBlankBeforeTags\"\nimport noJSDocReturnsOnVoid from \"@/rules/base/noJSDocReturnsOnVoid\"\nimport noLineCommentBackticks from \"@/rules/base/noLineCommentBackticks\"\nimport noLineCommentPeriod from \"@/rules/base/noLineCommentPeriod\"\nimport noPropertyAccessAlias from \"@/rules/base/noPropertyAccessAlias\"\nimport noPropertyDestructuring from \"@/rules/base/noPropertyDestructuring\"\nimport noRelativeImports from \"@/rules/base/noRelativeImports\"\nimport noSingleLineJSDoc from \"@/rules/base/noSingleLineJSDoc\"\nimport requireCapitalizedComments from \"@/rules/base/requireCapitalizedComments\"\nimport requireCompleteJSDoc from \"@/rules/base/requireCompleteJSDoc\"\nimport requireFrameworkConfig from \"@/rules/base/requireFrameworkConfig\"\nimport requireFunctionJSDoc from \"@/rules/base/requireFunctionJSDoc\"\nimport requireJSDocDelimiterLines from \"@/rules/base/requireJSDocDelimiterLines\"\nimport requireMultilineObject from \"@/rules/base/requireMultilineObject\"\nimport maxClassNameLength from \"@/rules/react/maxClassNameLength\"\nimport noJSXComments from \"@/rules/react/noJSXComments\"\nimport requireContextHookDestructure from \"@/rules/react/requireContextHookDestructure\"\nimport requireDerivedUseMemo from \"@/rules/react/requireDerivedUseMemo\"\nimport requireHookObjectReturn from \"@/rules/react/requireHookObjectReturn\"\nimport requireMemoCallbackJSDoc from \"@/rules/react/requireMemoCallbackJSDoc\"\n\n/**\n * Every rule instance registered by the plugin.\n */\nconst ruleInstances = [\n migrationTableOrder,\n requireControllerJSDoc,\n requireMigrationJSDoc,\n requireValidatedRequest,\n catchErrorName,\n maxJSDocDescriptionLength,\n maxLineCommentLength,\n noAliasVariables,\n noBritishEnglish,\n noDecorativeCommentSeparators,\n noEmDash,\n noEmojis,\n noJSDocBlankBeforeTags,\n noJSDocReturnsOnVoid,\n noLineCommentBackticks,\n noLineCommentPeriod,\n noPropertyAccessAlias,\n noPropertyDestructuring,\n noRelativeImports,\n noSingleLineJSDoc,\n requireCapitalizedComments,\n requireCompleteJSDoc,\n requireFrameworkConfig,\n requireJSDocDelimiterLines,\n requireFunctionJSDoc,\n requireMultilineObject,\n maxClassNameLength,\n noJSXComments,\n requireContextHookDestructure,\n requireDerivedUseMemo,\n requireHookObjectReturn,\n requireMemoCallbackJSDoc,\n]\n\n/**\n * The plugin's rules, keyed by name, as the plain modules ESLint consumes.\n */\nexport const rules = Object.fromEntries(ruleInstances.map(rule => [rule.name, rule.toRuleModule()])) as Record<\n string,\n TSESLint.RuleModule<string, readonly unknown[], NitpickerRuleDocs>\n>\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport CONSTANTS from \"@/lib/constants\"\nimport type { RuleCategory } from \"@/lib/utils/rules\"\nimport { rules } from \"@/rules\"\n\n/**\n * Builds the rules record for a single category, each enabled as a warning,\n * rules with no explicit category are treated as `base`.\n * @param category The category to collect rules for.\n * @returns The flat-config rules record for that category.\n */\nexport function categoryRules(category: RuleCategory): TSESLint.FlatConfig.Rules {\n const enabled: TSESLint.FlatConfig.Rules = {}\n\n for (const [name, rule] of Object.entries(rules)) {\n if ((rule.meta.docs?.category ?? \"base\") === category) {\n enabled[`${CONSTANTS.PLUGIN_NAME}/${name}`] = \"warn\"\n }\n }\n\n return enabled\n}\n\n/**\n * Builds a rules record enabling every rule the plugin ships, as a warning.\n * @returns The flat-config rules record for all rules.\n */\nexport function allRules(): TSESLint.FlatConfig.Rules {\n const enabled: TSESLint.FlatConfig.Rules = {}\n\n for (const name of Object.keys(rules)) {\n enabled[`${CONSTANTS.PLUGIN_NAME}/${name}`] = \"warn\"\n }\n\n return enabled\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { allRules } from \"@/configs/helpers\"\nimport CONSTANTS from \"@/lib/constants\"\n\n/**\n * Builds the `all` flat config: every rule the plugin ships, each enabled as a\n * warning, this is the maximally-pedantic Nitpicker experience. Both framework\n * settings flags are set, since enabling everything already opts into them.\n * @param plugin The plugin instance to register the rules against.\n * @returns The flat config object.\n */\nexport function all(plugin: TSESLint.FlatConfig.Plugin): TSESLint.FlatConfig.Config {\n return {\n name: `${CONSTANTS.PLUGIN_NAME}/all`,\n plugins: { [CONSTANTS.PLUGIN_NAME]: plugin },\n settings: { [CONSTANTS.PLUGIN_NAME]: { adonisjs: true, react: true } },\n rules: allRules(),\n }\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { categoryRules } from \"@/configs/helpers\"\nimport CONSTANTS from \"@/lib/constants\"\n\n/**\n * Builds the `base` flat config: the universal rules that apply to every file\n * regardless of framework.\n * @param plugin The plugin instance to register the rules against.\n * @returns The flat config object.\n */\nexport function base(plugin: TSESLint.FlatConfig.Plugin): TSESLint.FlatConfig.Config {\n return {\n name: `${CONSTANTS.PLUGIN_NAME}/base`,\n plugins: { [CONSTANTS.PLUGIN_NAME]: plugin },\n rules: categoryRules(\"base\"),\n }\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { base } from \"@/configs/rulesets/base\"\nimport CONSTANTS from \"@/lib/constants\"\n\n/**\n * Builds the `recommended` flat config: the sensible default for any project,\n * which is the universal `base` ruleset.\n * @param plugin The plugin instance to register the rules against.\n * @returns The flat config object.\n */\nexport function recommended(plugin: TSESLint.FlatConfig.Plugin): TSESLint.FlatConfig.Config {\n return {\n ...base(plugin),\n name: `${CONSTANTS.PLUGIN_NAME}/recommended`,\n }\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { categoryRules } from \"@/configs/helpers\"\nimport CONSTANTS from \"@/lib/constants\"\n\n// AdonisJS route files where banner separators are the clearest way to group routes\nconst ROUTE_FILE_GLOBS = [\"**/start/routes.ts\", \"**/start/routes/**/*.ts\"]\n\n/**\n * Builds the `adonisjs` flat config: AdonisJS-specific rules, plus a settings\n * flag so `require-framework-config` knows AdonisJS is opted into for these files.\n * It also permits decorative banners in route files, where they aid readability.\n * @param plugin The plugin instance to register the rules against.\n * @returns The flat config object.\n */\nexport function adonisjs(plugin: TSESLint.FlatConfig.Plugin): TSESLint.FlatConfig.Config {\n return {\n name: `${CONSTANTS.PLUGIN_NAME}/adonisjs`,\n plugins: { [CONSTANTS.PLUGIN_NAME]: plugin },\n settings: { [CONSTANTS.PLUGIN_NAME]: { adonisjs: true } },\n rules: {\n ...categoryRules(\"adonisjs\"),\n [`${CONSTANTS.PLUGIN_NAME}/no-decorative-comment-separators`]: [\"warn\", { allowIn: ROUTE_FILE_GLOBS }],\n },\n }\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { categoryRules } from \"@/configs/helpers\"\nimport CONSTANTS from \"@/lib/constants\"\n\n/**\n * Builds the `react` flat config: React-specific rules, plus a settings flag so\n * `require-framework-config` knows React is opted into for these files.\n * @param plugin The plugin instance to register the rules against.\n * @returns The flat config object.\n */\nexport function react(plugin: TSESLint.FlatConfig.Plugin): TSESLint.FlatConfig.Config {\n return {\n name: `${CONSTANTS.PLUGIN_NAME}/react`,\n plugins: { [CONSTANTS.PLUGIN_NAME]: plugin },\n settings: { [CONSTANTS.PLUGIN_NAME]: { react: true } },\n rules: categoryRules(\"react\"),\n }\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { all } from \"@/configs/presets/all\"\nimport { recommended } from \"@/configs/presets/recommended\"\nimport { adonisjs } from \"@/configs/rulesets/adonisjs\"\nimport { base } from \"@/configs/rulesets/base\"\nimport { react } from \"@/configs/rulesets/react\"\n\n/**\n * Builds all shared configs bundled with the plugin.\n *\n * Note: Configs are built from a factory rather than declared statically\n * because each one needs a reference to the plugin instance it belongs to.\n * @param plugin The plugin instance to register the rules against.\n * @returns A record of config name to flat config object.\n */\nexport function buildConfigs(plugin: TSESLint.FlatConfig.Plugin): Record<string, TSESLint.FlatConfig.Config> {\n return {\n base: base(plugin),\n recommended: recommended(plugin),\n adonisjs: adonisjs(plugin),\n react: react(plugin),\n all: all(plugin),\n }\n}\n","{\n \"name\": \"@alien_intelligence/eslint-plugin-nitpicker\",\n \"productName\": \"Nitpicker\",\n \"version\": \"0.7.7\",\n \"description\": \"A hyper-pedantic ESLint plugin that flags every stylistic and semantic nit, with AI-friendly fix context.\",\n \"author\": \"Alien <contact@alien.club> (https://www.alien.club/)\",\n \"license\": \"MIT\",\n \"private\": false,\n \"packageManager\": \"npm@11.4.2\",\n \"type\": \"module\",\n \"keywords\": [\n \"alien\",\n \"eslint\",\n \"eslintplugin\",\n \"eslint-plugin\",\n \"nitpicker\",\n \"linting\",\n \"code-style\",\n \"ai\"\n ],\n \"homepage\": \"https://github.com/Alien-Intelligence/eslint-plugin-nitpicker\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/Alien-Intelligence/eslint-plugin-nitpicker.git\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/Alien-Intelligence/eslint-plugin-nitpicker/issues\"\n },\n \"publishConfig\": {\n \"registry\": \"https://registry.npmjs.org/\",\n \"access\": \"public\",\n \"tag\": \"latest\"\n },\n \"engines\": {\n \"node\": \">=20.0.0\"\n },\n \"files\": [\n \"dist\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n }\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"lint\": \"biome check\",\n \"lint:fix\": \"biome check --fix && biome format --write\",\n \"lint:nitpicker\": \"eslint \\\"src/**/*.ts\\\" \\\"tests/**/*.ts\\\"\",\n \"typecheck\": \"tsc --noEmit\",\n \"pretest\": \"node -e \\\"require('node:fs').rmSync('node_modules/.vite', { recursive: true, force: true })\\\"\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\"\n },\n \"peerDependencies\": {\n \"eslint\": \">=9.0.0\"\n },\n \"dependencies\": {\n \"@typescript-eslint/utils\": \"^8.18.0\"\n },\n \"devDependencies\": {\n \"@biomejs/biome\": \"^2.5.2\",\n \"@types/node\": \"^24.12.2\",\n \"@typescript-eslint/parser\": \"^8.64.0\",\n \"eslint\": \"^9.17.0\",\n \"tsup\": \"^8.5.1\",\n \"typescript\": \"^5.8.3\",\n \"vitest\": \"^4.1.5\"\n }\n}\n","import type { TSESLint } from \"@typescript-eslint/utils\"\nimport { buildConfigs } from \"@/configs\"\nimport CONSTANTS from \"@/lib/constants\"\nimport { rules } from \"@/rules\"\n\n// Import the version from package.json to include in the plugin metadata\nimport { version } from \"../package.json\"\n\n/**\n * Main declaration of the `@alien_intelligence/eslint-plugin-nitpicker` plugin.\n */\nconst plugin: TSESLint.FlatConfig.Plugin = {\n meta: {\n name: `eslint-plugin-${CONSTANTS.PLUGIN_NAME}`,\n version,\n },\n rules,\n configs: {},\n}\n\n// Configs reference the plugin, so they are attached after it is created\nplugin.configs = buildConfigs(plugin)\n\nexport default plugin\n"]}
|