@workos/oagen 0.6.0 → 0.8.0

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.
Files changed (53) hide show
  1. package/dist/cli/index.mjs +1339 -451
  2. package/dist/cli/index.mjs.map +1 -1
  3. package/dist/compat/index.d.mts +144 -57
  4. package/dist/compat/index.d.mts.map +1 -1
  5. package/dist/compat/index.mjs +365 -35
  6. package/dist/compat/index.mjs.map +1 -1
  7. package/dist/{diff-CltJMcwG.mjs → diff-BaH9qa8k.mjs} +100 -23
  8. package/dist/diff-BaH9qa8k.mjs.map +1 -0
  9. package/dist/differ-CTl98yoS.d.mts +116 -0
  10. package/dist/differ-CTl98yoS.d.mts.map +1 -0
  11. package/dist/index.d.mts +4 -2
  12. package/dist/index.d.mts.map +1 -1
  13. package/dist/index.mjs +177 -4
  14. package/dist/index.mjs.map +1 -1
  15. package/dist/{differ-CG5ZErKl.mjs → overlay-TYxHOCow.mjs} +1112 -553
  16. package/dist/overlay-TYxHOCow.mjs.map +1 -0
  17. package/dist/scripts/smoke/baseline.mjs +176 -3
  18. package/dist/scripts/smoke/baseline.mjs.map +1 -1
  19. package/dist/smoke.d.mts +43 -0
  20. package/dist/smoke.d.mts.map +1 -1
  21. package/dist/smoke.mjs +176 -3
  22. package/dist/smoke.mjs.map +1 -1
  23. package/dist/tree-sitter-C53w_0WE.mjs.map +1 -1
  24. package/dist/{types-C7g5sLuX.d.mts → types-mTtkgy_h.d.mts} +213 -2
  25. package/dist/types-mTtkgy_h.d.mts.map +1 -0
  26. package/dist/verify/index.d.mts +4 -3
  27. package/dist/verify/index.d.mts.map +1 -1
  28. package/dist/verify/index.mjs +12 -10
  29. package/dist/verify/index.mjs.map +1 -1
  30. package/docs/architecture/emitter-contract.md +2 -2
  31. package/docs/architecture/extractor-contract.md +6 -5
  32. package/docs/architecture/pipeline.md +4 -3
  33. package/docs/architecture/workflows.md +5 -3
  34. package/docs/cli.md +148 -6
  35. package/docs/contributor/public-api.md +1 -1
  36. package/docs/core/compatibility-ir.md +200 -0
  37. package/docs/core/compatibility-policy.md +170 -0
  38. package/docs/core/compatibility.md +83 -0
  39. package/docs/core/index.md +5 -0
  40. package/docs/core/manifest-schema.md +76 -0
  41. package/docs/core/quickstart.md +9 -2
  42. package/docs/core/verify-compat.md +235 -0
  43. package/package.json +1 -1
  44. package/skills/generate-emitter/SKILL.md +12 -7
  45. package/skills/generate-emitter/references/project-scaffold.md +27 -6
  46. package/skills/generate-extractor/SKILL.md +14 -8
  47. package/skills/generate-sdk/SKILL.md +2 -2
  48. package/skills/generate-smoke-test/SKILL.md +9 -5
  49. package/skills/review-operations/SKILL.md +2 -2
  50. package/skills/verify-compat/SKILL.md +1 -1
  51. package/dist/diff-CltJMcwG.mjs.map +0 -1
  52. package/dist/differ-CG5ZErKl.mjs.map +0 -1
  53. package/dist/types-C7g5sLuX.d.mts.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/ir/sdk-behavior.ts","../src/parser/refs.ts","../src/parser/inline-models.ts","../src/parser/schemas.ts","../src/parser/pagination.ts","../src/parser/responses.ts","../src/parser/operations.ts","../src/parser/normalize-inline-models.ts","../src/parser/collect-inline-enums.ts","../src/parser/normalize-model-refs.ts","../src/parser/parse.ts","../src/engine/operation-plan.ts"],"sourcesContent":["/**\n * SDK Behavior IR — language-agnostic runtime policies for generated SDKs.\n *\n * These types capture the \"what\" of SDK behavior (retry, telemetry, errors, etc.)\n * while emitters provide the \"how\" (language-specific mechanism).\n *\n * Emitters access these via `ctx.spec.sdk` — always populated, never undefined.\n */\n\n// ── Retry ──────────────────────────────────────────────────────────\n\n/** Retry policy — when and how to retry failed requests. */\nexport interface RetryPolicy {\n /** HTTP status codes that trigger a retry. */\n retryableStatusCodes: number[];\n /** Maximum number of retry attempts (0 = no retries). */\n maxRetries: number;\n /** Whether to retry on connection errors (DNS failure, TCP reset). */\n retryOnConnectionError: boolean;\n /** Whether to retry on timeout errors. */\n retryOnTimeout: boolean;\n /** Backoff strategy between retries. */\n backoff: BackoffStrategy;\n}\n\n/** Exponential backoff configuration.\n *\n * Formula: `delay = min(initialDelay * multiplier^attempt, maxDelay)`\n * With jitter: `delay += delay * jitterFactor * random(0, 1)`\n */\nexport interface BackoffStrategy {\n /** Initial delay in seconds before the first retry. */\n initialDelay: number;\n /** Multiplier applied to the delay on each subsequent retry. */\n multiplier: number;\n /** Maximum delay in seconds (cap). */\n maxDelay: number;\n /** Jitter factor (0..1). 0.5 means up to 50% random jitter added. */\n jitterFactor: number;\n}\n\n// ── Errors ─────────────────────────────────────────────────────────\n\n/** Error mapping — status codes to named exception kinds. */\nexport interface ErrorPolicy {\n /** Map from HTTP status code to a logical error kind name (e.g. 400 → 'BadRequest').\n * Emitters append language-specific suffixes (e.g. 'BadRequestException'). */\n statusCodeMap: Record<number, string>;\n /** Catch-all error kind for 5xx status codes not in the map. */\n serverErrorKind: string;\n /** Catch-all error kind for unrecognized status codes. */\n clientErrorKind: string;\n /** URL template for error documentation. Use {code} as placeholder for the API error code.\n * Example: 'https://workos.com/docs/errors/{code}' */\n errorDocUrlTemplate?: string;\n}\n\n// ── Telemetry ──────────────────────────────────────────────────────\n\n/** Telemetry — what request metrics to track and send. */\nexport interface TelemetryPolicy {\n /** Whether telemetry is enabled by default. Users can opt out via constructor param. */\n enabledByDefault: boolean;\n /** Header name for client telemetry data (previous request's ID + latency). */\n headerName: string;\n /** Response header name for the request ID. */\n requestIdHeader: string;\n}\n\n// ── Pagination ─────────────────────────────────────────────────────\n\n/** Pagination behavior defaults. */\nexport interface PaginationPolicy {\n /** Delay in milliseconds between pages during auto-pagination. 0 = no delay. */\n autoPageDelayMs: number;\n}\n\n// ── Idempotency ────────────────────────────────────────────────────\n\n/** Idempotency auto-generation rules. */\nexport interface IdempotencyPolicy {\n /** Header name for the idempotency key. */\n headerName: string;\n /** Whether to auto-generate a UUID v4 idempotency key for POST requests when retries > 0. */\n autoGenerateForPost: boolean;\n}\n\n// ── Logging ────────────────────────────────────────────────────────\n\n/** Logging contract — what to log at which level. */\nexport interface LoggingPolicy {\n /** Whether structured logging hooks are generated. */\n enabled: boolean;\n /** Log events that the generated client emits. */\n events: LogEvent[];\n}\n\n/** A discrete loggable event in the request lifecycle. */\nexport type LogEvent =\n | 'request.start'\n | 'request.success'\n | 'request.retry'\n | 'request.rate_limited'\n | 'request.error'\n | 'request.connection_error';\n\n// ── User-Agent ─────────────────────────────────────────────────────\n\n/** User-Agent construction rules. */\nexport interface UserAgentPolicy {\n /** Template for the SDK identifier string.\n * Placeholders: {name} = spec name, {lang} = emitter language, {version} = SDK version.\n * Each emitter interpolates with its own language string and casing conventions.\n * Example: '{name} {lang}/{version}' → 'WorkOS PHP/4.32.0' */\n sdkIdentifierTemplate: string;\n /** Whether to append the runtime/language version (e.g. PHP 8.2, Python 3.12). */\n includeRuntimeVersion: boolean;\n /** Whether to allow app info enrichment via setAppInfo(name, version, url). */\n allowAppInfo: boolean;\n /** AI agent environment variable detection entries. */\n aiAgentEnvVars: AiAgentEnvVar[];\n}\n\n/** Maps an environment variable to an AI agent slug for User-Agent enrichment. */\nexport interface AiAgentEnvVar {\n /** Environment variable to check (e.g. 'CLAUDE_CODE'). */\n envVar: string;\n /** Agent name to append to User-Agent (e.g. 'ClaudeCode'). */\n agentName: string;\n}\n\n// ── Request Guards ─────────────────────────────────────────────────\n\n/** Guards that validate request params before sending. */\nexport interface RequestGuardPolicy {\n /** Keys that should be in RequestOptions, not in params.\n * If detected in the body or query params, the SDK throws an error. */\n optionKeys: string[];\n}\n\n// ── Timeouts ───────────────────────────────────────────────────────\n\n/** Timeout configuration. */\nexport interface TimeoutPolicy {\n /** Default HTTP request timeout in seconds. */\n defaultTimeoutSeconds: number;\n /** Environment variable name to override the timeout (e.g. 'WORKOS_REQUEST_TIMEOUT'). */\n timeoutEnvVar?: string;\n}\n\n// ── Root ───────────────────────────────────────────────────────────\n\n/** Language-agnostic runtime policies for generated SDKs.\n * Attached to `ApiSpec.sdk` and consumed by emitters via `ctx.spec.sdk`. */\nexport interface SdkBehavior {\n retry: RetryPolicy;\n errors: ErrorPolicy;\n telemetry: TelemetryPolicy;\n pagination: PaginationPolicy;\n idempotency: IdempotencyPolicy;\n logging: LoggingPolicy;\n userAgent: UserAgentPolicy;\n requestGuard: RequestGuardPolicy;\n timeout: TimeoutPolicy;\n}\n\n// ── Defaults ───────────────────────────────────────────────────────\n\n/**\n * Canonical SDK behavior defaults. These match the PHP emitter's current\n * implementation (the most complete). Per-language overrides can be applied\n * via `mergeSdkBehavior()` in each SDK's `oagen.config.ts`.\n *\n * - Retry: exponential backoff with jitter, retries on 429/5xx\n * - Errors: standard HTTP status → exception kind mapping\n * - Telemetry: enabled by default, tracks request ID + latency\n * - Pagination: no inter-page delay (Node overrides to 350ms)\n * - Idempotency: auto-generate UUID v4 for retryable POSTs\n * - Logging: all lifecycle events enabled\n * - User-Agent: SDK identifier + runtime version + app info + AI agent detection\n * - Request guards: detect misplaced RequestOptions keys in params\n * - Timeout: 60s default (Python overrides to 30s)\n */\nexport function defaultSdkBehavior(): SdkBehavior {\n return {\n retry: {\n retryableStatusCodes: [429, 500, 502, 503, 504],\n maxRetries: 3,\n retryOnConnectionError: true,\n retryOnTimeout: true,\n backoff: {\n initialDelay: 1.0,\n multiplier: 2.0,\n maxDelay: 30.0,\n jitterFactor: 0.5,\n },\n },\n errors: {\n statusCodeMap: {\n 400: 'BadRequest',\n 401: 'Authentication',\n 403: 'Authorization',\n 404: 'NotFound',\n 409: 'Conflict',\n 422: 'UnprocessableEntity',\n 429: 'RateLimitExceeded',\n },\n serverErrorKind: 'Server',\n clientErrorKind: 'Api',\n errorDocUrlTemplate: 'https://workos.com/docs/errors/{code}',\n },\n telemetry: {\n enabledByDefault: true,\n headerName: 'X-WorkOS-Client-Telemetry',\n requestIdHeader: 'X-Request-ID',\n },\n pagination: {\n autoPageDelayMs: 0,\n },\n idempotency: {\n headerName: 'Idempotency-Key',\n autoGenerateForPost: true,\n },\n logging: {\n enabled: true,\n events: [\n 'request.start',\n 'request.success',\n 'request.retry',\n 'request.rate_limited',\n 'request.error',\n 'request.connection_error',\n ],\n },\n userAgent: {\n sdkIdentifierTemplate: '{name} {lang}/{version}',\n includeRuntimeVersion: true,\n allowAppInfo: true,\n aiAgentEnvVars: [\n { envVar: 'CLAUDE_CODE', agentName: 'ClaudeCode' },\n { envVar: 'CURSOR_AGENT', agentName: 'Cursor' },\n { envVar: 'CLINE_ACTIVE', agentName: 'Cline' },\n { envVar: 'WINDSURF_ACTIVE', agentName: 'Windsurf' },\n { envVar: 'COPILOT_AGENT', agentName: 'Copilot' },\n ],\n },\n requestGuard: {\n optionKeys: [\n 'api_key',\n 'apiKey',\n 'idempotency_key',\n 'idempotencyKey',\n 'extra_headers',\n 'extraHeaders',\n 'max_retries',\n 'maxRetries',\n 'base_url',\n 'baseUrl',\n ],\n },\n timeout: {\n defaultTimeoutSeconds: 60,\n },\n };\n}\n\n// ── Merge ──────────────────────────────────────────────────────────\n\n/** Recursive partial type for deep overrides. */\nexport type DeepPartial<T> = {\n [K in keyof T]?: T[K] extends (infer U)[]\n ? U[] // Arrays replace entirely (don't concat)\n : T[K] extends object\n ? DeepPartial<T[K]>\n : T[K];\n};\n\n/**\n * Deep-merge partial overrides into the canonical defaults.\n * Arrays replace entirely (so `retryableStatusCodes: [429]` replaces the full list,\n * rather than appending). Object properties are merged recursively.\n */\nexport function mergeSdkBehavior(overrides: DeepPartial<SdkBehavior>): SdkBehavior {\n return deepMerge(\n defaultSdkBehavior() as unknown as Record<string, unknown>,\n overrides as unknown as Record<string, unknown>,\n ) as unknown as SdkBehavior;\n}\n\n/**\n * Self-contained deep merge (no external imports — ir/ is layer 0).\n * Arrays and primitives from `source` replace those in `target`.\n * Objects are merged recursively.\n */\nfunction deepMerge(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = { ...target };\n for (const key of Object.keys(source)) {\n const sourceVal = source[key];\n const targetVal = target[key];\n if (sourceVal === undefined) continue;\n if (\n sourceVal !== null &&\n typeof sourceVal === 'object' &&\n !Array.isArray(sourceVal) &&\n targetVal !== null &&\n typeof targetVal === 'object' &&\n !Array.isArray(targetVal)\n ) {\n result[key] = deepMerge(targetVal as Record<string, unknown>, sourceVal as Record<string, unknown>);\n } else {\n result[key] = sourceVal;\n }\n }\n return result;\n}\n","import { readFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { makeDocumentFromString, bundleDocument, createConfig, BaseResolver, Oas3_1Types } from '@redocly/openapi-core';\nimport { SpecParseError } from '../errors.js';\n\nexport interface BundledSpec {\n parsed: Record<string, unknown>;\n specPath: string;\n}\n\nexport async function loadAndBundleSpec(specPath: string): Promise<BundledSpec> {\n const absolutePath = resolve(specPath);\n const content = await readFile(absolutePath, 'utf-8');\n const document = makeDocumentFromString(content, pathToFileURL(absolutePath).href);\n\n const config = await createConfig({});\n const resolver = new BaseResolver();\n\n const result = await bundleDocument({\n document,\n config,\n types: Oas3_1Types,\n externalRefResolver: resolver,\n dereference: false,\n });\n\n if (result.problems.some((p) => p.severity === 'error')) {\n const errors = result.problems\n .filter((p) => p.severity === 'error')\n .map((p) => p.message)\n .join('\\n');\n throw new SpecParseError(\n `Failed to parse spec: ${errors}`,\n `Check the OpenAPI spec at \"${absolutePath}\" for syntax errors. Run a linter such as \\`npx @redocly/cli lint ${specPath}\\` to identify issues.`,\n );\n }\n\n return {\n parsed: result.bundle.parsed as Record<string, unknown>,\n specPath: absolutePath,\n };\n}\n","import type { Model, Field } from '../ir/types.js';\nimport { toPascalCase, cleanSchemaName, stripListItemMarkers, singularize } from '../utils/naming.js';\nimport type { SchemaObject } from './schemas.js';\nimport { buildFieldFromSchema } from './schemas.js';\n\n/**\n * Qualify an inline model name with the parent schema name.\n * If `parentName` is provided and the field name doesn't already start with\n * the parent, the result is `${parentName}${PascalField}` with the trailing\n * word singularized (e.g., Connection + Domains → ConnectionDomain).\n */\nexport function qualifyInlineModelName(baseName: string, parentName?: string): string {\n if (!parentName) return baseName;\n // Strip ListItem/ByExternalId markers from parent name so inline model names\n // are clean and match the names produced by qualifyNestedName() in responses.ts.\n // e.g., ConnectionListItem + Domains → Connection + Domain = ConnectionDomain\n const cleanParent = stripListItemMarkers(parentName);\n if (baseName.startsWith(cleanParent)) return baseName;\n // Singularize the trailing PascalCase word of the combined name.\n // Split baseName into leading words + trailing word, singularize trailing.\n const trailingMatch = baseName.match(/^(.*?)([A-Z][a-z]*)$/);\n if (trailingMatch) {\n const [, prefix, trailingWord] = trailingMatch;\n const singular = singularize(trailingWord);\n return `${cleanParent}${prefix}${singular}`;\n }\n return `${cleanParent}${baseName}`;\n}\n\n/**\n * Walk all component schemas and extract inline Model definitions for fields\n * that are objects with properties (or arrays of such objects).\n * These correspond to the ModelRef entries created by schemaToTypeRef.\n */\nexport function extractInlineModelsFromSchemas(schemas: Record<string, SchemaObject> | undefined): Model[] {\n if (!schemas) return [];\n\n const inlineModels: Model[] = [];\n\n for (const [schemaName, schema] of Object.entries(schemas)) {\n const parentName = cleanSchemaName(toPascalCase(schemaName));\n extractInlineModelsFromProperties(schema, inlineModels, parentName);\n }\n\n return inlineModels;\n}\n\nfunction extractInlineModelsFromProperties(schema: SchemaObject, results: Model[], parentName?: string): void {\n const properties = schema.properties ?? {};\n const allOfSchemas = schema.allOf ?? [];\n\n for (const sub of allOfSchemas) {\n if (sub.properties) {\n extractInlineModelsFromProperties(sub, results, parentName);\n }\n }\n\n for (const [fieldName, fieldSchema] of Object.entries(properties)) {\n if (!fieldSchema) continue;\n // Direct inline object with properties (with or without explicit type: 'object')\n if (fieldSchema.properties && (fieldSchema.type === 'object' || !fieldSchema.type)) {\n const baseName = toPascalCase(fieldName);\n const modelName = qualifyInlineModelName(baseName, parentName);\n results.push(buildInlineModel(modelName, fieldSchema));\n extractInlineModelsFromProperties(fieldSchema, results, modelName);\n }\n\n // Array of inline objects\n if (fieldSchema.type === 'array' && fieldSchema.items) {\n const items = fieldSchema.items;\n if (items.properties && (items.type === 'object' || !items.type)) {\n const baseName = toPascalCase(fieldName);\n const modelName = qualifyInlineModelName(baseName, parentName);\n results.push(buildInlineModel(modelName, items));\n extractInlineModelsFromProperties(items, results, modelName);\n }\n }\n\n // oneOf containing objects — extract the first non-null variant as a model\n // This handles: totp: { oneOf: [{ type: object, properties: {...} }, { type: 'null' }] }\n if (fieldSchema.oneOf) {\n const objectVariant = fieldSchema.oneOf.find((v) => v.properties && (v.type === 'object' || !v.type));\n if (objectVariant) {\n const baseName = toPascalCase(fieldName);\n const modelName = qualifyInlineModelName(baseName, parentName);\n const existingNames = new Set(results.map((r) => r.name));\n if (!existingNames.has(modelName)) {\n results.push(buildInlineModel(modelName, objectVariant));\n extractInlineModelsFromProperties(objectVariant, results, modelName);\n }\n }\n }\n }\n}\n\nfunction buildInlineModel(name: string, schema: SchemaObject): Model {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n\n for (const [fieldName, fieldSchema] of Object.entries(schema.properties ?? {})) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet));\n }\n\n return { name, description: schema.description, fields };\n}\n","import type { Model, Enum, EnumValue, Field, TypeRef } from '../ir/types.js';\nimport { walkTypeRef } from '../ir/types.js';\nimport { toPascalCase, toUpperSnakeCase, cleanSchemaName, singularize, stripListItemMarkers } from '../utils/naming.js';\n\n/**\n * Module-level transform set during extractSchemas(). Used by schemaToTypeRef()\n * to apply the same name transform to $ref model/enum references.\n */\nlet activeSchemaNameTransform: ((name: string) => string) | null = null;\n\n/** Apply cleanSchemaName + the active transform (if any) to a raw schema name. */\nfunction resolveSchemaName(rawName: string): string {\n let name = cleanSchemaName(toPascalCase(rawName));\n if (activeSchemaNameTransform) name = activeSchemaNameTransform(name);\n return name;\n}\n\nexport interface SchemaExtractionOptions {\n schemaNameTransform?: (name: string) => string;\n}\n\nexport interface SchemaObject {\n type?: string | string[];\n format?: string;\n description?: string;\n properties?: Record<string, SchemaObject | undefined>;\n required?: string[];\n items?: SchemaObject;\n enum?: (string | number)[];\n allOf?: SchemaObject[];\n oneOf?: SchemaObject[];\n anyOf?: SchemaObject[];\n discriminator?: { propertyName: string; mapping?: Record<string, string> };\n readOnly?: boolean;\n writeOnly?: boolean;\n nullable?: boolean;\n $ref?: string;\n additionalProperties?: boolean | SchemaObject;\n const?: unknown;\n patternProperties?: Record<string, SchemaObject>;\n deprecated?: boolean;\n default?: unknown;\n example?: unknown;\n [key: string]: unknown;\n}\n\nexport interface ExtractedSchemas {\n models: Model[];\n enums: Enum[];\n}\n\nexport function extractSchemas(\n schemas: Record<string, SchemaObject> | undefined,\n options?: SchemaExtractionOptions,\n): ExtractedSchemas {\n const enums: Enum[] = [];\n\n if (!schemas) return { models: [], enums };\n\n // Build collision-safe transform if provided\n if (options?.schemaNameTransform) {\n const transform = options.schemaNameTransform;\n const rawNames = Object.keys(schemas);\n const cleanedNames = rawNames.map((n) => cleanSchemaName(toPascalCase(n)));\n const transformedToOriginals = new Map<string, string[]>();\n for (const cleaned of cleanedNames) {\n const transformed = transform(cleaned);\n if (!transformedToOriginals.has(transformed)) transformedToOriginals.set(transformed, []);\n transformedToOriginals.get(transformed)!.push(cleaned);\n }\n const unsafeToTransform = new Set<string>();\n for (const [, originals] of transformedToOriginals) {\n if (originals.length > 1) {\n for (const n of originals) unsafeToTransform.add(n);\n }\n }\n activeSchemaNameTransform = (name: string) => (unsafeToTransform.has(name) ? name : transform(name));\n } else {\n activeSchemaNameTransform = null;\n }\n\n const modelsByCleanName = new Map<string, Model>();\n\n for (const [name, schema] of Object.entries(schemas)) {\n const pascalName = resolveSchemaName(name);\n\n if (schema.enum) {\n enums.push(extractEnum(pascalName, schema));\n } else {\n const model = extractModel(pascalName, schema, schemas);\n const existing = modelsByCleanName.get(pascalName);\n if (existing) {\n // Keep the model with more fields when names collide after cleaning\n if (model.fields.length > existing.fields.length) {\n modelsByCleanName.set(pascalName, model);\n }\n } else {\n modelsByCleanName.set(pascalName, model);\n }\n\n for (const inlineModel of extractDiscriminatedAllOfVariantModels(schema, pascalName)) {\n const existingInline = modelsByCleanName.get(inlineModel.name);\n if (existingInline) {\n if (inlineModel.fields.length > existingInline.fields.length) {\n modelsByCleanName.set(inlineModel.name, inlineModel);\n }\n } else {\n modelsByCleanName.set(inlineModel.name, inlineModel);\n }\n }\n }\n }\n\n const models = [...modelsByCleanName.values()];\n\n // Collect inline models from nested object/oneOf properties\n // that schemaToTypeRef created model refs for but weren't extracted\n const modelNames = new Set(models.map((m) => m.name));\n const inlineQueue: Model[] = [...models];\n while (inlineQueue.length > 0) {\n const model = inlineQueue.pop()!;\n for (const field of model.fields) {\n collectNestedInlineModels(field.type, field.name, model.name, schemas ?? {}, models, modelNames, inlineQueue);\n }\n }\n\n // Collect inline enums from model fields\n for (const model of models) {\n collectInlineEnums(model.fields, enums);\n }\n\n // NOTE: activeSchemaNameTransform is intentionally NOT cleared here.\n // extractOperations() calls schemaToTypeRef() for $ref resolution and\n // needs the same transform active. parseSpec() calls clearSchemaNameTransform()\n // after all extraction is complete.\n return { models, enums };\n}\n\n/** Clear the module-level schemaNameTransform. Called by parseSpec() after all extraction phases. */\nexport function clearSchemaNameTransform(): void {\n activeSchemaNameTransform = null;\n}\n\n/**\n * Walk a single TypeRef and extract inline enum refs as top-level enum definitions.\n * Shared by both schemas.ts (field-level) and parse.ts (model-level) collection passes.\n */\nexport function collectInlineEnumFromRef(ref: TypeRef, enums: Enum[], seen: Set<string>): void {\n walkTypeRef(ref, {\n enum: (r) => {\n if (r.values && !seen.has(r.name)) {\n seen.add(r.name);\n enums.push({\n name: r.name,\n values: r.values.map((v) => ({\n name: toUpperSnakeCase(String(v)),\n value: v,\n description: undefined,\n })),\n });\n }\n },\n });\n}\n\n/**\n * Walk model fields and extract inline enum refs as top-level enum definitions.\n * This ensures type alias files are generated for inline enums.\n */\nfunction collectInlineEnums(fields: Field[], enums: Enum[]): void {\n const seen = new Set(enums.map((e) => e.name));\n for (const field of fields) {\n collectInlineEnumFromRef(field.type, enums, seen);\n }\n}\n\n/**\n * Walk a TypeRef tree and extract inline models for any model refs that point\n * to schemas with inline object properties (not in components/schemas).\n * This handles nested objects like `totp: { oneOf: [{ type: object, properties: {...} }] }`\n * that schemaToTypeRef turns into model refs but aren't extracted from components.\n */\nfunction collectNestedInlineModels(\n ref: TypeRef,\n fieldName: string,\n parentModelName: string,\n schemas: Record<string, SchemaObject>,\n models: Model[],\n modelNames: Set<string>,\n queue: Model[],\n): void {\n walkTypeRef(ref, {\n model: (modelRef) => {\n if (modelNames.has(modelRef.name)) return; // already extracted\n // Check if this model name corresponds to a component schema\n // by checking all possible original names that would map to this PascalCase name\n const isComponent = Object.keys(schemas).some((k) => resolveSchemaName(k) === modelRef.name);\n if (isComponent) return; // will be extracted from components\n\n // This is a reference to a nested inline model that wasn't extracted.\n // Look up the field schema in the parent model's component schema to extract it.\n const parentSchema = findSchemaByName(parentModelName, schemas);\n if (!parentSchema) return;\n\n const fieldSchema = findNestedFieldSchema(fieldName, parentSchema, schemas);\n if (!fieldSchema) return;\n\n // Extract inline models from the field schema\n const extracted = extractNestedSchema(modelRef.name, fieldSchema);\n for (const m of extracted) {\n if (!modelNames.has(m.name)) {\n models.push(m);\n modelNames.add(m.name);\n queue.push(m); // re-scan for deeper nesting\n }\n }\n },\n });\n}\n\n/** Find a component schema by PascalCase name. */\nfunction findSchemaByName(pascalName: string, schemas: Record<string, SchemaObject>): SchemaObject | null {\n for (const [k, v] of Object.entries(schemas)) {\n if (resolveSchemaName(k) === pascalName) return v;\n }\n return null;\n}\n\n/** Walk into a schema to find a field's sub-schema, resolving allOf. */\nfunction findNestedFieldSchema(\n fieldName: string,\n parentSchema: SchemaObject,\n schemas: Record<string, SchemaObject>,\n): SchemaObject | null {\n if (parentSchema.properties?.[fieldName]) {\n return parentSchema.properties[fieldName]!;\n }\n if (parentSchema.allOf) {\n for (const sub of parentSchema.allOf) {\n let resolved = sub;\n if (sub.$ref) {\n const segments = sub.$ref.split('/');\n const refName = segments[segments.length - 1];\n if (refName && schemas[refName]) resolved = schemas[refName];\n }\n if (resolved.properties?.[fieldName]) {\n return resolved.properties[fieldName]!;\n }\n }\n }\n return null;\n}\n\n/** Extract a model (and nested models) from an inline field schema. */\nfunction extractNestedSchema(name: string, schema: SchemaObject): Model[] {\n // Handle oneOf: extract each object variant as its own model\n if (schema.oneOf) {\n const models: Model[] = [];\n for (const variant of schema.oneOf) {\n if (variant.$ref) continue;\n if (variant.properties && (variant.type === 'object' || !variant.type)) {\n const requiredSet = new Set(variant.required ?? []);\n const fields: Field[] = [];\n for (const [fn, fs] of Object.entries(variant.properties)) {\n if (!fs) continue;\n fields.push(buildFieldFromSchema(fn, fs, name, requiredSet));\n }\n // Use the name for the first variant, suffix for subsequent\n const variantName = models.length === 0 ? name : `${name}${models.length + 1}`;\n models.push({ name: variantName, description: variant.description, fields });\n }\n }\n return models;\n }\n\n // Handle direct object\n if (schema.properties && (schema.type === 'object' || !schema.type)) {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n for (const [fn, fs] of Object.entries(schema.properties)) {\n if (!fs) continue;\n fields.push(buildFieldFromSchema(fn, fs, name, requiredSet));\n }\n return [{ name, description: schema.description, fields }];\n }\n\n // Handle array with inline items\n if (schema.type === 'array' && schema.items?.properties) {\n const requiredSet = new Set(schema.items.required ?? []);\n const fields: Field[] = [];\n for (const [fn, fs] of Object.entries(schema.items.properties)) {\n if (!fs) continue;\n fields.push(buildFieldFromSchema(fn, fs, name, requiredSet));\n }\n return [{ name, description: schema.items.description, fields }];\n }\n\n return [];\n}\n\n/** Build a single Field from a schema property entry. Shared across all extraction sites. */\nexport function buildFieldFromSchema(\n fieldName: string,\n fieldSchema: SchemaObject,\n contextName: string,\n requiredSet: Set<string>,\n): Field {\n return {\n name: fieldName,\n type: schemaToTypeRef(fieldSchema, fieldName, contextName),\n required: requiredSet.has(fieldName),\n description: fieldSchema.description,\n readOnly: fieldSchema.readOnly || undefined,\n writeOnly: fieldSchema.writeOnly || undefined,\n deprecated: fieldSchema.deprecated || undefined,\n default: fieldSchema.default,\n example: fieldSchema.example,\n };\n}\n\n/**\n * If every non-null oneOf/anyOf variant is a string-valued const, return the\n * list of those const values so the union can collapse into a single enum.\n * Returns null when any variant isn't a pure string-const (model ref,\n * number const, nullable, etc.).\n */\nfunction collectLiteralStringConsts(variants: SchemaObject[]): string[] | null {\n if (variants.length === 0) return null;\n const values: string[] = [];\n for (const v of variants) {\n // A single-element enum is semantically identical to const.\n if (typeof v.const === 'string') {\n values.push(v.const);\n continue;\n }\n if (Array.isArray(v.enum) && v.enum.length === 1 && typeof v.enum[0] === 'string') {\n values.push(v.enum[0]);\n continue;\n }\n return null;\n }\n return values;\n}\n\n/** Build an EnumRef the same way the regular enum path does for naming. */\nfunction buildSyntheticEnumRef(\n values: string[],\n contextName: string | undefined,\n parentModelName: string | undefined,\n): TypeRef {\n const baseName = toPascalCase(contextName ?? 'UnknownEnum');\n const cleanParent = parentModelName ? stripListItemMarkers(parentModelName) : undefined;\n const qualifiedName = cleanParent && !baseName.startsWith(cleanParent) ? `${cleanParent}${baseName}` : baseName;\n return { kind: 'enum', name: qualifiedName, values };\n}\n\n/**\n * Detect an implicit discriminator on an oneOf where every variant is an\n * object schema that pins the same property to a const value. Returns\n * { property, mapping } so the IR can represent the union as discriminated\n * without needing an explicit `discriminator:` key in the spec.\n *\n * Both shapes are supported:\n * { properties: { event: { const: \"x\" } }, required: [\"event\"] }\n * { properties: { event: { type: \"string\", enum: [\"x\"] } } }\n *\n * Returns null when any variant doesn't fit the pattern or when variants\n * disagree on which property carries the discriminator.\n */\nfunction detectConstPropertyDiscriminator(\n variants: SchemaObject[],\n): { property: string; mapping: Record<string, string> } | null {\n if (variants.length < 2) return null;\n\n // Find properties whose const value is present on every variant.\n let candidateProperty: string | null = null;\n const candidates = Object.keys(variants[0]?.properties ?? {});\n for (const propName of candidates) {\n if (variants.every((v) => getConstPropertyValue(v, propName) !== null)) {\n candidateProperty = propName;\n break;\n }\n }\n\n if (!candidateProperty) return null;\n\n const mapping: Record<string, string> = {};\n for (const v of variants) {\n const value = getConstPropertyValue(v, candidateProperty);\n if (value === null) return null;\n // Require a $ref or title so we have a concrete model name to map to.\n const variantName = resolveVariantModelName(v);\n if (!variantName) return null;\n mapping[value] = variantName;\n }\n\n return { property: candidateProperty, mapping };\n}\n\nfunction getConstPropertyValue(schema: SchemaObject, property: string): string | null {\n const prop = schema.properties?.[property];\n if (!prop) return null;\n if (typeof prop.const === 'string') return prop.const;\n if (Array.isArray(prop.enum) && prop.enum.length === 1 && typeof prop.enum[0] === 'string') {\n return prop.enum[0];\n }\n return null;\n}\n\nfunction resolveVariantModelName(schema: SchemaObject): string | null {\n if (schema.$ref) {\n return resolveSchemaName(schema.$ref.replace(/^#\\/components\\/schemas\\//, ''));\n }\n const title = typeof schema['title'] === 'string' ? (schema['title'] as string) : null;\n if (title) return resolveSchemaName(title);\n return null;\n}\n\nfunction extractEnum(name: string, schema: SchemaObject): Enum {\n const values: EnumValue[] = (schema.enum ?? []).map((v) => ({\n name: toUpperSnakeCase(String(v)),\n value: typeof v === 'number' ? v : String(v),\n description: undefined,\n }));\n\n return { name, values };\n}\nfunction extractModel(name: string, schema: SchemaObject, schemas?: Record<string, SchemaObject>): Model {\n if (schema.allOf) {\n return extractAllOfModel(name, schema, schemas);\n }\n\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n\n for (const [fieldName, fieldSchema] of Object.entries(schema.properties ?? {})) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet));\n }\n\n // When additionalProperties is an object schema alongside properties,\n // surface it as a catch-all map field so emitters can generate Map<string, T>.\n if (schema.additionalProperties && typeof schema.additionalProperties === 'object' && schema.properties) {\n const apKeys = Object.keys(schema.additionalProperties);\n if (apKeys.length > 0) {\n const valueType = schemaToTypeRef(schema.additionalProperties as SchemaObject, 'additionalProperties', name);\n fields.push({\n name: 'additionalProperties',\n type: { kind: 'map', valueType },\n required: false,\n description: 'Additional properties not captured by named fields',\n });\n }\n }\n\n return { name, description: schema.description, fields };\n}\n\nfunction extractAllOfModel(name: string, schema: SchemaObject, schemas?: Record<string, SchemaObject>): Model {\n const fields: Field[] = [];\n const requiredSet = new Set<string>();\n\n for (const subSchema of schema.allOf ?? []) {\n // Resolve $ref sub-schemas by looking up the referenced component schema\n let resolved = subSchema;\n if (subSchema.$ref && schemas) {\n const segments = subSchema.$ref.split('/');\n const refName = segments[segments.length - 1];\n if (refName && schemas[refName]) {\n resolved = schemas[refName];\n }\n }\n\n // If the resolved schema is itself an allOf, recursively extract its fields\n if (resolved.allOf) {\n const nested = extractAllOfModel(name, resolved, schemas);\n for (const f of nested.fields) {\n fields.push({ ...f, required: false }); // will be re-set below\n if (f.required) requiredSet.add(f.name);\n }\n } else {\n if (resolved.required) {\n for (const r of resolved.required) requiredSet.add(r);\n }\n if (resolved.properties) {\n // Use an empty requiredSet — required flags are set in the final pass below\n const emptyRequired = new Set<string>();\n for (const [fieldName, fieldSchema] of Object.entries(resolved.properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, emptyRequired));\n }\n }\n }\n }\n\n // Also collect required from the outer schema\n if (schema.required) {\n for (const r of schema.required) requiredSet.add(r);\n }\n\n // Set required flags\n for (const f of fields) {\n f.required = requiredSet.has(f.name);\n }\n\n return { name, description: schema.description, fields };\n}\n\nfunction extractDiscriminatedAllOfVariantModels(schema: SchemaObject, fallbackName: string): Model[] {\n const models: Model[] = [];\n const seenNames = new Set<string>();\n\n for (const subSchema of schema.allOf ?? []) {\n for (const variant of subSchema.oneOf ?? []) {\n if (!variant.properties || (variant.type !== undefined && variant.type !== 'object')) continue;\n\n const variantName = deriveDiscriminatedVariantName(variant, fallbackName);\n for (const model of extractInlineModelDeep(variantName, variant)) {\n if (seenNames.has(model.name)) continue;\n seenNames.add(model.name);\n models.push(model);\n }\n }\n }\n\n return models;\n}\n\nfunction deriveDiscriminatedVariantName(schema: SchemaObject, fallbackName: string): string {\n if (!schema.properties) return fallbackName;\n\n const preferred = ['event', 'type', 'object'];\n for (const name of preferred) {\n const field = schema.properties[name];\n if (!field) continue;\n if (typeof field.const === 'string') {\n return toPascalCase(field.const);\n }\n if (field.enum && field.enum.length === 1 && typeof field.enum[0] === 'string') {\n return toPascalCase(field.enum[0]);\n }\n }\n\n for (const field of Object.values(schema.properties)) {\n if (!field) continue;\n if (typeof field.const === 'string') {\n return toPascalCase(field.const);\n }\n if (field.enum && field.enum.length === 1 && typeof field.enum[0] === 'string') {\n return toPascalCase(field.enum[0]);\n }\n }\n\n return fallbackName;\n}\n\nfunction extractInlineModelDeep(name: string, schema: SchemaObject): Model[] {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n const properties = schema.properties ?? {};\n const nestedModels: Model[] = [];\n\n for (const [fieldName, fieldSchema] of Object.entries(properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet));\n\n if (fieldSchema.type === 'object' && fieldSchema.properties) {\n nestedModels.push(...extractInlineModelDeep(qualifyNestedInlineName(name, fieldName), fieldSchema));\n }\n\n if (fieldSchema.type === 'array' && fieldSchema.items?.properties) {\n nestedModels.push(...extractInlineModelDeep(qualifyNestedInlineName(name, fieldName), fieldSchema.items));\n }\n\n if (fieldSchema.allOf) {\n const mergedProperties: Record<string, SchemaObject | undefined> = {};\n const mergedRequired: string[] = [];\n for (const sub of fieldSchema.allOf) {\n if (sub.properties) Object.assign(mergedProperties, sub.properties);\n if (sub.required) mergedRequired.push(...sub.required);\n }\n if (Object.keys(mergedProperties).length > 0) {\n nestedModels.push(\n ...extractInlineModelDeep(qualifyNestedInlineName(name, fieldName), {\n type: 'object',\n properties: mergedProperties,\n required: mergedRequired,\n }),\n );\n }\n }\n\n if (fieldSchema.oneOf) {\n const objectVariant = fieldSchema.oneOf.find((v) => v.properties && (v.type === 'object' || !v.type));\n if (objectVariant) {\n nestedModels.push(...extractInlineModelDeep(qualifyNestedInlineName(name, fieldName), objectVariant));\n }\n }\n }\n\n return [{ name, description: schema.description, fields }, ...nestedModels];\n}\n\nfunction qualifyNestedInlineName(parentName: string, fieldName: string): string {\n const pascalField = toPascalCase(fieldName);\n if (pascalField.startsWith(parentName)) return pascalField;\n\n const cleanParent = stripListItemMarkers(parentName);\n const qualified = `${cleanParent}${pascalField}`;\n const match = qualified.match(/^(.+?)([A-Z][a-z]+s?)$/);\n if (match && match[2]) {\n return match[1] + singularize(match[2]);\n }\n return qualified;\n}\n\nexport function schemaToTypeRef(schema: SchemaObject, contextName?: string, parentModelName?: string): TypeRef {\n // Handle $ref → ModelRef\n if (schema.$ref) {\n const segments = schema.$ref.split('/');\n const rawName = segments[segments.length - 1];\n return { kind: 'model', name: resolveSchemaName(rawName) };\n }\n\n // Handle OAS 3.1 nullable type arrays: type: [string, null]\n if (Array.isArray(schema.type)) {\n const nonNullTypes = schema.type.filter((t: string) => t !== 'null');\n // type: ['null'] — only null, no real type\n if (nonNullTypes.length === 0) {\n return { kind: 'nullable', inner: { kind: 'primitive', type: 'unknown' } };\n }\n if (schema.type.includes('null') && nonNullTypes.length === 1) {\n return {\n kind: 'nullable',\n inner: schemaToTypeRef({ ...schema, type: nonNullTypes[0], nullable: false }, contextName),\n };\n }\n // Multiple non-null types → union\n if (nonNullTypes.length > 1) {\n const variants = nonNullTypes.map((t: string) => schemaToTypeRef({ ...schema, type: t }, contextName));\n const ref: TypeRef = { kind: 'union', variants };\n if (schema.type.includes('null')) {\n return { kind: 'nullable', inner: ref };\n }\n return ref;\n }\n }\n\n // Handle OAS 3.0 nullable flag\n if (schema.nullable && schema.type) {\n return {\n kind: 'nullable',\n inner: schemaToTypeRef({ ...schema, nullable: false }, contextName),\n };\n }\n\n // Handle allOf — merge properties from all sub-schemas.\n // This handles patterns like: allOf: [{ type: object, properties: {...} }, { oneOf: [...] }]\n // which are valid OAS 3.1 but weren't handled for field-level schemas.\n if (schema.allOf) {\n // If allOf contains a $ref, prefer the ref (it's a named type)\n const refItem = schema.allOf.find((s: SchemaObject) => s.$ref);\n if (refItem) {\n // If allOf has $ref AND siblings with properties, return a merged model ref\n // to avoid losing the augmentation properties\n const hasAugmentation = schema.allOf.some((s: SchemaObject) => !s.$ref && (s.properties || s.type === 'object'));\n if (hasAugmentation) {\n const baseName = toPascalCase(contextName ?? 'UnknownModel');\n return { kind: 'model', name: qualifyInlineModelName(baseName, parentModelName) };\n }\n return schemaToTypeRef(refItem, contextName, parentModelName);\n }\n // If allOf has a single item, unwrap it\n if (schema.allOf.length === 1) {\n return schemaToTypeRef(schema.allOf[0], contextName, parentModelName);\n }\n // If allOf items all have properties, treat as a merged model\n const hasProperties = schema.allOf.some((s: SchemaObject) => s.properties);\n if (hasProperties) {\n const baseName = toPascalCase(contextName ?? 'UnknownModel');\n return {\n kind: 'model',\n name: qualifyInlineModelName(baseName, parentModelName),\n };\n }\n // Fall through to other checks\n }\n\n // Handle oneOf / anyOf → Union or Nullable\n // Valid OAS 3.1: properties can have { oneOf: [{ type: object }, { type: 'null' }] }\n // without a wrapping `type` field.\n if (schema.oneOf || schema.anyOf) {\n const compositionKind: 'oneOf' | 'anyOf' = schema.oneOf ? 'oneOf' : 'anyOf';\n const rawVariants: SchemaObject[] = schema.oneOf ?? schema.anyOf ?? [];\n\n // Check for nullable pattern: oneOf: [realType, { type: 'null' }]\n const nullVariant = rawVariants.find(\n (v: SchemaObject) => v.type === 'null' || (Array.isArray(v.type) && v.type.length === 1 && v.type[0] === 'null'),\n );\n const nonNullVariants = rawVariants.filter((v) => v !== nullVariant);\n\n if (nullVariant && nonNullVariants.length === 1) {\n // Nullable single type — unwrap as nullable\n return {\n kind: 'nullable',\n inner: schemaToTypeRef(nonNullVariants[0], contextName, parentModelName),\n };\n }\n\n // Collapse an oneOf/anyOf whose non-null variants are all string-const\n // schemas into a single enum. This turns patterns like\n // provider: { oneOf: [{ const: \"AppleOAuth\" }, { const: \"GitHubOAuth\" }, ...] }\n // into a proper enum type with one member per variant instead of a\n // structurally-opaque union of literal refs.\n const literalStrings = collectLiteralStringConsts(nonNullVariants);\n if (literalStrings !== null && literalStrings.length >= 2) {\n const enumRef = buildSyntheticEnumRef(literalStrings, contextName, parentModelName);\n return nullVariant ? { kind: 'nullable', inner: enumRef } : enumRef;\n }\n\n // Synthesize a discriminator when all non-null variants are objects that\n // share a property whose schema carries a `const` value. Covers the\n // EventSchema-style pattern where each oneOf variant pins `event:\n // const: \"...\"` instead of the spec using an explicit `discriminator:`.\n const syntheticDiscriminator =\n !schema.discriminator && compositionKind === 'oneOf' ? detectConstPropertyDiscriminator(nonNullVariants) : null;\n\n // General union\n const variants = rawVariants\n .filter((v: SchemaObject) => v.type !== 'null')\n .map((v: SchemaObject) => schemaToTypeRef(v, contextName, parentModelName));\n const hasNull = !!nullVariant;\n const union: TypeRef = {\n kind: 'union',\n variants,\n compositionKind,\n ...(schema.discriminator\n ? {\n discriminator: {\n property: schema.discriminator.propertyName,\n mapping: Object.fromEntries(\n Object.entries(schema.discriminator.mapping ?? {}).map(([k, v]) => [\n k,\n v.replace(/^#\\/components\\/schemas\\//, ''),\n ]),\n ),\n },\n }\n : syntheticDiscriminator\n ? { discriminator: syntheticDiscriminator }\n : {}),\n };\n return hasNull ? { kind: 'nullable', inner: union } : union;\n }\n\n // Handle const → LiteralType (supports string, number, boolean)\n if (schema.const !== undefined) {\n if (typeof schema.const === 'string' || typeof schema.const === 'number' || typeof schema.const === 'boolean') {\n return { kind: 'literal', value: schema.const };\n }\n // null const → nullable unknown\n if (schema.const === null) {\n return { kind: 'nullable', inner: { kind: 'primitive', type: 'unknown' } };\n }\n // const of object/array → map or array with unknown values\n if (typeof schema.const === 'object') {\n if (Array.isArray(schema.const)) {\n return { kind: 'array', items: { kind: 'primitive', type: 'unknown' } };\n }\n return { kind: 'map', valueType: { kind: 'primitive', type: 'unknown' } };\n }\n }\n if (schema.enum && schema.enum.length === 1) {\n const v = schema.enum[0];\n return { kind: 'literal', value: typeof v === 'number' ? v : String(v) };\n }\n\n // Handle enum\n if (schema.enum) {\n const baseName = toPascalCase(contextName ?? 'UnknownEnum');\n // Strip ListItem/ByExternalId markers from parent name so enum names are clean:\n // e.g., DirectoryListItem + State → Directory + State = DirectoryState\n const cleanParent = parentModelName ? stripListItemMarkers(parentModelName) : undefined;\n // Avoid redundant prefix: Connection + ConnectionType → ConnectionType\n const qualifiedName = cleanParent && !baseName.startsWith(cleanParent) ? `${cleanParent}${baseName}` : baseName;\n return {\n kind: 'enum',\n name: qualifiedName,\n values: schema.enum.map((v) => (typeof v === 'number' ? v : String(v))),\n };\n }\n\n // Handle array — pass parentModelName through to qualify inline items\n if (schema.type === 'array' && schema.items) {\n return {\n kind: 'array',\n items: schemaToTypeRef(schema.items, contextName, parentModelName),\n };\n }\n // Handle array without explicit type but with items (valid OAS 3.1)\n if (!schema.type && schema.items) {\n return {\n kind: 'array',\n items: schemaToTypeRef(schema.items, contextName, parentModelName),\n };\n }\n\n // Handle object → ModelRef (if it has properties, it's a named model reference)\n // When additionalProperties is also present, we still return a ModelRef so the\n // named properties are preserved. The extractModel path will pick up the extra\n // properties as a catch-all map field named `additionalProperties`.\n if (schema.type === 'object' && schema.properties) {\n const baseName = toPascalCase(contextName ?? 'UnknownModel');\n return {\n kind: 'model',\n name: qualifyInlineModelName(baseName, parentModelName),\n };\n }\n\n // Handle freeform object with additionalProperties or patternProperties → Map<string, T>\n if (schema.type === 'object' && !schema.properties) {\n let valueType: TypeRef = { kind: 'primitive', type: 'unknown' };\n if (schema.additionalProperties && typeof schema.additionalProperties === 'object') {\n // Empty additionalProperties ({}) means \"any value\" — keep as unknown\n const apKeys = Object.keys(schema.additionalProperties);\n if (apKeys.length > 0) {\n valueType = schemaToTypeRef(schema.additionalProperties as SchemaObject, contextName);\n }\n } else if (schema.patternProperties) {\n // patternProperties: { \"pattern\": schema } → use the first pattern's schema as value type\n const patterns = Object.values(schema.patternProperties);\n if (patterns.length > 0) {\n valueType = schemaToTypeRef(patterns[0], contextName);\n }\n }\n return {\n kind: 'map',\n valueType,\n };\n }\n\n // Handle primitives\n const primitiveMap: Record<string, 'string' | 'integer' | 'number' | 'boolean'> = {\n string: 'string',\n integer: 'integer',\n number: 'number',\n boolean: 'boolean',\n };\n\n const typeStr = Array.isArray(schema.type) ? schema.type[0] : schema.type;\n if (typeStr && primitiveMap[typeStr]) {\n return {\n kind: 'primitive',\n type: primitiveMap[typeStr],\n ...(schema.format ? { format: schema.format } : {}),\n };\n }\n\n // Handle schemas with no type — if it has properties, treat as model\n if (!schema.type && schema.properties) {\n const baseName = toPascalCase(contextName ?? 'UnknownModel');\n return {\n kind: 'model',\n name: qualifyInlineModelName(baseName, parentModelName),\n };\n }\n\n // Empty schema {} → unknown\n if (\n !schema.type &&\n !schema.$ref &&\n !schema.oneOf &&\n !schema.anyOf &&\n !schema.allOf &&\n !schema.enum &&\n !schema.properties &&\n !schema.items\n ) {\n return { kind: 'primitive', type: 'unknown' };\n }\n\n // Fallback: treat unknown schemas as unknown\n if (contextName) {\n console.warn(`[oagen] Warning: Unknown schema shape treated as unknown (context: ${contextName})`);\n }\n return { kind: 'primitive', type: 'unknown' };\n}\n\nimport { qualifyInlineModelName } from './inline-models.js';\n\nexport { qualifyInlineModelName, extractInlineModelsFromSchemas } from './inline-models.js';\n","import type { TypeRef, Parameter, PaginationMeta } from '../ir/types.js';\n\nconst CURSOR_PARAMS = ['cursor', 'after', 'before', 'starting_after', 'ending_before', 'page_token', 'next_token'];\n\nconst OFFSET_PARAMS = ['offset', 'page', 'page_number', 'skip'];\nconst LIMIT_PARAMS = ['limit', 'page_size', 'per_page', 'size', 'count'];\n\n/**\n * Detect if an operation uses pagination and return structured metadata\n * for auto-paging iterator generation.\n *\n * Supports two strategies:\n * 1. **Cursor-based**: query params include a cursor-like parameter\n * 2. **Offset-based**: query params include both an offset-like and limit-like parameter\n *\n * Returns null if no pagination pattern is detected.\n */\nexport function detectPagination(\n response: TypeRef,\n queryParams: Parameter[],\n dataPath?: string,\n): PaginationMeta | null {\n // Try cursor-based first (preferred)\n const cursorParam = queryParams.find((p) => CURSOR_PARAMS.includes(p.name));\n\n if (cursorParam) {\n const itemType: TypeRef = response.kind === 'array' ? response.items : response;\n return {\n strategy: 'cursor',\n param: cursorParam.name,\n dataPath: dataPath,\n itemType,\n };\n }\n\n // Try offset-based pagination\n const offsetParam = queryParams.find((p) => OFFSET_PARAMS.includes(p.name));\n const limitParam = queryParams.find((p) => LIMIT_PARAMS.includes(p.name));\n\n if (offsetParam && limitParam) {\n const itemType: TypeRef = response.kind === 'array' ? response.items : response;\n return {\n strategy: 'offset',\n param: offsetParam.name,\n limitParam: limitParam.name,\n dataPath: dataPath,\n itemType,\n };\n }\n\n return null;\n}\n","import type { TypeRef, Model, Field } from '../ir/types.js';\nimport { toPascalCase, singularize, stripListItemMarkers } from '../utils/naming.js';\nimport type { SchemaObject } from './schemas.js';\nimport { schemaToTypeRef, buildFieldFromSchema } from './schemas.js';\n\nexport interface ResponseExtractionResult {\n /** The TypeRef to use as the operation's response type */\n response: TypeRef;\n /** Any inline models discovered during extraction (to merge into ir.models) */\n inlineModels: Model[];\n /** Whether this response indicates a paginated list */\n isPaginated: boolean;\n /** Path to the data array within the response envelope (e.g., 'data') */\n dataPath?: string;\n /** TypeRef of individual items in a paginated list */\n itemType?: TypeRef;\n}\n\nexport function classifyAndExtractResponse(schema: SchemaObject, contextName: string): ResponseExtractionResult {\n // 1. If schema is a $ref, resolve to model name (Phase 1)\n if (schema.$ref) {\n return { response: schemaToTypeRef(schema, contextName), inlineModels: [], isPaginated: false };\n }\n\n // 2. Check for list envelope (structural detection: array prop + non-array companion)\n const envelope = detectListEnvelope(schema);\n if (envelope.isEnvelope) {\n return extractListResponse(schema, contextName, envelope.dataPath!);\n }\n\n // 3. Check for single-resource wrapper ({ resource_name: { object: \"...\", ... } })\n if (isSingleResourceWrapper(schema)) {\n return extractWrappedResource(schema, contextName);\n }\n\n // 4. Direct resource or plain inline object\n return extractDirectResource(schema, contextName);\n}\n\ninterface ListEnvelopeResult {\n isEnvelope: boolean;\n dataPath: string | null;\n}\n\nconst KNOWN_DATA_PATHS = new Set(['data', 'items', 'results', 'records', 'entries', 'values', 'nodes', 'edges']);\n\nconst PAGINATION_METADATA_PATTERNS = [\n 'meta',\n 'metadata',\n 'pagination',\n 'cursor',\n 'has_more',\n 'page_info',\n 'total',\n 'next_page',\n 'previous_page',\n 'offset',\n];\n\nfunction detectListEnvelope(schema: SchemaObject): ListEnvelopeResult {\n // Collect all property sources (allOf sub-schemas or flat schema)\n const propSources: Record<string, SchemaObject | undefined>[] = [];\n if (schema.allOf) {\n for (const sub of schema.allOf) {\n if (sub.properties) propSources.push(sub.properties);\n }\n }\n if (schema.properties) {\n propSources.push(schema.properties);\n }\n\n if (propSources.length === 0) return { isEnvelope: false, dataPath: null };\n\n // Merge all properties into a single view\n const mergedProps: Record<string, SchemaObject | undefined> = {};\n for (const source of propSources) {\n Object.assign(mergedProps, source);\n }\n\n // Find array-typed properties and non-array companion properties\n const arrayProps: string[] = [];\n const nonArrayKeys: string[] = [];\n\n for (const [key, propSchema] of Object.entries(mergedProps)) {\n if (!propSchema) continue;\n if (propSchema.type === 'array') {\n arrayProps.push(key);\n } else {\n nonArrayKeys.push(key);\n }\n }\n\n // List envelope heuristic: exactly one array property + at least one non-array companion\n // that looks like pagination metadata. A `data` array alone (e.g. with only an\n // `object` discriminant companion) is NOT sufficient — the companion must indicate\n // actual pagination (cursor, metadata, total, etc.).\n if (arrayProps.length === 1 && nonArrayKeys.length >= 1) {\n const arrayPropName = arrayProps[0];\n\n const hasPaginationCompanion = nonArrayKeys.some((key) =>\n PAGINATION_METADATA_PATTERNS.some((pattern) => key.toLowerCase().includes(pattern)),\n );\n\n if (KNOWN_DATA_PATHS.has(arrayPropName) && hasPaginationCompanion) {\n return { isEnvelope: true, dataPath: arrayPropName };\n }\n\n // Non-standard array property name — still treat as envelope if pagination companion exists\n if (hasPaginationCompanion) {\n return { isEnvelope: true, dataPath: arrayPropName };\n }\n }\n\n return { isEnvelope: false, dataPath: null };\n}\n\nfunction extractListResponse(schema: SchemaObject, contextName: string, dataPath: string): ResponseExtractionResult {\n let itemTypeRef: TypeRef = { kind: 'primitive', type: 'string' };\n const inlineModels: Model[] = [];\n\n // Collect all property sources (allOf sub-schemas or flat schema)\n const propSources: Record<string, SchemaObject | undefined>[] = [];\n if (schema.allOf) {\n for (const sub of schema.allOf) {\n if (sub.properties) propSources.push(sub.properties);\n }\n }\n if (schema.properties) {\n propSources.push(schema.properties);\n }\n\n for (const props of propSources) {\n const dataProp = props[dataPath];\n if (!dataProp) continue;\n\n if (dataProp.type === 'array' && dataProp.items) {\n const items = dataProp.items;\n if (items.$ref) {\n itemTypeRef = schemaToTypeRef(items, contextName);\n } else if (items.type === 'object' && items.properties) {\n const itemName = contextName.replace(/Response$/, '') + 'Item';\n itemTypeRef = { kind: 'model', name: itemName };\n inlineModels.push(...extractInlineModel(itemName, items));\n }\n }\n }\n\n return {\n response: { kind: 'array', items: itemTypeRef },\n inlineModels,\n isPaginated: true,\n dataPath,\n itemType: itemTypeRef,\n };\n}\n\nfunction hasDiscriminantConstField(schema: SchemaObject): { property: string; value: string } | null {\n if (!schema.properties) return null;\n\n // Prefer well-known discriminant properties for backward compatibility\n const preferred = ['object', 'type'];\n for (const name of preferred) {\n const field = schema.properties[name];\n if (!field) continue;\n if (field.const !== undefined && typeof field.const === 'string') {\n return { property: name, value: field.const };\n }\n if (field.enum && field.enum.length === 1 && typeof field.enum[0] === 'string') {\n return { property: name, value: field.enum[0] };\n }\n }\n\n // Fall back to any property with a const or single-value enum\n for (const [name, field] of Object.entries(schema.properties)) {\n if (!field) continue;\n if (field.const !== undefined && typeof field.const === 'string') {\n return { property: name, value: field.const };\n }\n if (field.enum && field.enum.length === 1 && typeof field.enum[0] === 'string') {\n return { property: name, value: field.enum[0] };\n }\n }\n\n return null;\n}\n\nfunction isSingleResourceWrapper(schema: SchemaObject): boolean {\n if (schema.type !== 'object') return false;\n if (!schema.properties) return false;\n\n // Find the wrapper property: use required[0] if available, or the single property key\n let wrapperKey: string | undefined;\n if (schema.required && schema.required.length === 1) {\n wrapperKey = schema.required[0];\n } else {\n const propKeys = Object.keys(schema.properties);\n if (propKeys.length === 1) {\n wrapperKey = propKeys[0];\n }\n }\n if (!wrapperKey) return false;\n\n const propSchema = schema.properties[wrapperKey];\n if (!propSchema) return false;\n\n // Direct object with a discriminant const field\n if (propSchema.type === 'object' && hasDiscriminantConstField(propSchema) !== null) return true;\n\n // oneOf with object + null (nullable resource)\n if (propSchema.oneOf) {\n return propSchema.oneOf.some((v) => v.type === 'object' && hasDiscriminantConstField(v) !== null);\n }\n\n return false;\n}\n\nfunction extractWrappedResource(schema: SchemaObject, contextName: string): ResponseExtractionResult {\n const props = schema.properties!;\n const wrapperKey = schema.required && schema.required.length === 1 ? schema.required[0] : Object.keys(props)[0];\n const propSchema = props[wrapperKey]!;\n const inlineModels: Model[] = [];\n\n // Derive model name from the object const value or wrapper property name\n const resourceName = contextName.replace(/Response$/, '');\n\n if (propSchema.oneOf) {\n const objectVariant = propSchema.oneOf.find((v) => v.type === 'object' && hasDiscriminantConstField(v) !== null);\n\n if (objectVariant) {\n const modelName = deriveModelName(objectVariant, resourceName);\n inlineModels.push(...extractInlineModel(modelName, objectVariant));\n\n const hasNullVariant = propSchema.oneOf.some(\n (v) => v.type === 'null' || (Array.isArray(v.type) && v.type.includes('null')),\n );\n\n const modelRef: TypeRef = { kind: 'model', name: modelName };\n return {\n response: hasNullVariant ? { kind: 'nullable', inner: modelRef } : modelRef,\n inlineModels,\n isPaginated: false,\n };\n }\n }\n\n // Direct object\n const modelName = deriveModelName(propSchema, resourceName);\n inlineModels.push(...extractInlineModel(modelName, propSchema));\n\n return {\n response: { kind: 'model', name: modelName },\n inlineModels,\n isPaginated: false,\n };\n}\n\nfunction extractDirectResource(schema: SchemaObject, contextName: string): ResponseExtractionResult {\n const inlineModels: Model[] = [];\n\n // Direct object with properties (with or without explicit type: 'object')\n if (schema.properties && (schema.type === 'object' || !schema.type)) {\n const modelName = deriveModelName(schema, contextName);\n inlineModels.push(...extractInlineModel(modelName, schema));\n return {\n response: { kind: 'model', name: modelName },\n inlineModels,\n isPaginated: false,\n };\n }\n\n // allOf with properties — merge into a single model\n if (schema.allOf) {\n const mergedProperties: Record<string, SchemaObject | undefined> = {};\n const mergedRequired: string[] = [];\n for (const sub of schema.allOf) {\n if (sub.properties) {\n Object.assign(mergedProperties, sub.properties);\n }\n if (sub.required) {\n mergedRequired.push(...sub.required);\n }\n }\n if (Object.keys(mergedProperties).length > 0) {\n const merged: SchemaObject = { type: 'object', properties: mergedProperties, required: mergedRequired };\n const modelName = deriveModelName(merged, contextName);\n inlineModels.push(...extractInlineModel(modelName, merged));\n return {\n response: { kind: 'model', name: modelName },\n inlineModels,\n isPaginated: false,\n };\n }\n }\n\n // oneOf — delegate to schemaToTypeRef (returns union) but also extract inline models\n // from object variants so the model refs resolve\n if (schema.oneOf) {\n for (const variant of schema.oneOf) {\n if (variant.properties && (variant.type === 'object' || !variant.type)) {\n const modelName = deriveModelName(variant, contextName);\n const existingNames = new Set(inlineModels.map((m) => m.name));\n if (!existingNames.has(modelName)) {\n inlineModels.push(...extractInlineModel(modelName, variant));\n }\n }\n }\n }\n\n // Array with inline object items — extract the item model\n if (schema.type === 'array' && schema.items) {\n const items = schema.items;\n if (items.$ref) {\n return {\n response: { kind: 'array', items: schemaToTypeRef(items, contextName) },\n inlineModels,\n isPaginated: false,\n };\n }\n if (items.properties && (items.type === 'object' || !items.type)) {\n const itemName = contextName.replace(/Response$/, '') + 'Item';\n inlineModels.push(...extractInlineModel(itemName, items));\n return {\n response: { kind: 'array', items: { kind: 'model', name: itemName } },\n inlineModels,\n isPaginated: false,\n };\n }\n }\n\n // Non-object schema (primitive, union, etc.) — delegate to schemaToTypeRef\n return {\n response: schemaToTypeRef(schema, contextName),\n inlineModels,\n isPaginated: false,\n };\n}\n\nfunction deriveModelName(schema: SchemaObject, fallback: string): string {\n if (!schema.properties) return toPascalCase(fallback);\n\n // Prefer well-known discriminant properties for backward compatibility\n const preferred = ['object', 'type'];\n for (const name of preferred) {\n const field = schema.properties[name];\n if (field && field.const && typeof field.const === 'string') {\n return toPascalCase(field.const);\n }\n }\n\n // Fall back to any property with a const string value\n for (const [, field] of Object.entries(schema.properties)) {\n if (field && field.const && typeof field.const === 'string') {\n return toPascalCase(field.const);\n }\n }\n\n return toPascalCase(fallback);\n}\n\n/**\n * Qualify a nested inline model name with its parent to avoid generic names.\n * e.g., parent=\"Connection\" + field=\"domains\" → \"ConnectionDomain\" (singularized)\n * Only qualifies when the field name alone would be too generic.\n */\nfunction qualifyNestedName(parentName: string, fieldName: string): string {\n const pascalField = toPascalCase(fieldName);\n // If the field name already starts with the parent name, don't double-prefix\n if (pascalField.startsWith(parentName)) return pascalField;\n // Qualify with parent and singularize:\n // Connection + Domains → ConnectionDomains → singularize lead word → ConnectionDomain\n const cleanParent = stripListItemMarkers(parentName);\n const qualified = `${cleanParent}${pascalField}`;\n // Singularize the trailing word: ConnectionDomains → ConnectionDomain\n const match = qualified.match(/^(.+?)([A-Z][a-z]+s?)$/);\n if (match && match[2]) {\n const trailing = singularize(match[2]);\n return match[1] + trailing;\n }\n return qualified;\n}\n\nfunction extractInlineModel(name: string, schema: SchemaObject): Model[] {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n const properties = schema.properties ?? {};\n const nestedModels: Model[] = [];\n\n for (const [fieldName, fieldSchema] of Object.entries(properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet));\n\n // Recursively extract nested inline objects — qualify with parent name\n // to avoid generic names like \"Domains\" when multiple parents have a \"domains\" field\n if (fieldSchema.type === 'object' && fieldSchema.properties) {\n const nestedName = qualifyNestedName(name, fieldName);\n nestedModels.push(...extractInlineModel(nestedName, fieldSchema));\n }\n if (fieldSchema.type === 'array' && fieldSchema.items) {\n const items = fieldSchema.items;\n if (items.type === 'object' && items.properties) {\n const nestedName = qualifyNestedName(name, fieldName);\n nestedModels.push(...extractInlineModel(nestedName, items));\n }\n }\n // Handle allOf with inline object properties — merge into a single nested model\n if (fieldSchema.allOf) {\n const mergedProperties: Record<string, SchemaObject | undefined> = {};\n const mergedRequired: string[] = [];\n for (const sub of fieldSchema.allOf) {\n if (sub.properties) Object.assign(mergedProperties, sub.properties);\n if (sub.required) mergedRequired.push(...sub.required);\n }\n if (Object.keys(mergedProperties).length > 0) {\n const nestedName = qualifyNestedName(name, fieldName);\n const merged: SchemaObject = { type: 'object', properties: mergedProperties, required: mergedRequired };\n const existingNames = new Set(nestedModels.map((m) => m.name));\n if (!existingNames.has(nestedName)) {\n nestedModels.push(...extractInlineModel(nestedName, merged));\n }\n }\n }\n // Handle oneOf containing inline objects — extract the first non-null object variant\n if (fieldSchema.oneOf) {\n const objectVariant = fieldSchema.oneOf.find((v) => v.properties && (v.type === 'object' || !v.type));\n if (objectVariant) {\n const nestedName = qualifyNestedName(name, fieldName);\n const existingNames = new Set(nestedModels.map((m) => m.name));\n if (!existingNames.has(nestedName)) {\n nestedModels.push(...extractInlineModel(nestedName, objectVariant));\n }\n }\n }\n }\n\n return [{ name, description: schema.description, fields }, ...nestedModels];\n}\n","import type {\n Service,\n Operation,\n HttpMethod,\n Parameter,\n TypeRef,\n ErrorResponse,\n SuccessResponse,\n SecurityRequirement,\n Model,\n Field,\n PaginationMeta,\n} from '../ir/types.js';\nimport { toPascalCase, toCamelCase, cleanSchemaName } from '../utils/naming.js';\nimport type { SchemaObject } from './schemas.js';\nimport { schemaToTypeRef, buildFieldFromSchema } from './schemas.js';\nimport { detectPagination } from './pagination.js';\nimport { classifyAndExtractResponse } from './responses.js';\n\ninterface PathItem {\n get?: OperationObject;\n post?: OperationObject;\n put?: OperationObject;\n patch?: OperationObject;\n delete?: OperationObject;\n head?: OperationObject;\n options?: OperationObject;\n trace?: OperationObject;\n parameters?: ParameterObject[];\n}\n\ninterface OperationObject {\n operationId?: string;\n summary?: string;\n description?: string;\n tags?: string[];\n parameters?: ParameterObject[];\n requestBody?: RequestBodyObject;\n responses?: Record<string, ResponseObject>;\n deprecated?: boolean;\n 'x-oagen-async'?: boolean;\n security?: Array<Record<string, string[]>>;\n}\n\ninterface ParameterObject {\n name: string;\n in: 'path' | 'query' | 'header' | 'cookie';\n required?: boolean;\n description?: string;\n schema?: SchemaObject;\n deprecated?: boolean;\n example?: unknown;\n style?: string;\n explode?: boolean;\n}\n\ninterface RequestBodyObject {\n required?: boolean;\n content?: Record<string, { schema?: SchemaObject }>;\n}\n\ninterface ResponseObject {\n description?: string;\n content?: Record<string, { schema?: SchemaObject }>;\n}\n\nconst HTTP_METHODS: HttpMethod[] = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'];\n\nexport interface OperationExtractionResult {\n services: Service[];\n inlineModels: Model[];\n}\n\nexport function extractOperations(\n paths: Record<string, PathItem> | undefined,\n operationIdTransform?: (id: string) => string,\n): OperationExtractionResult {\n if (!paths) return { services: [], inlineModels: [] };\n\n const serviceMap = new Map<string, Operation[]>();\n const inlineModels: Model[] = [];\n\n for (const [path, pathItem] of Object.entries(paths)) {\n const pathLevelParams = pathItem.parameters ?? [];\n\n for (const method of HTTP_METHODS) {\n const op = pathItem[method];\n if (!op) continue;\n\n const serviceName = inferServiceName(path, op.tags?.[0]);\n\n const { operation, inlineModels: opModels } = buildOperation(\n method,\n path,\n op,\n pathLevelParams,\n operationIdTransform,\n serviceName,\n );\n inlineModels.push(...opModels);\n const ops = serviceMap.get(serviceName) ?? [];\n ops.push(operation);\n serviceMap.set(serviceName, ops);\n }\n }\n\n // Split services when a single tag groups operations from multiple path prefixes.\n // Example: /organizations and /organization_domains both tagged \"organizations\"\n // should become separate services based on their first path segment.\n for (const [serviceName, operations] of serviceMap) {\n const pathGroups = new Map<string, Operation[]>();\n for (const op of operations) {\n const firstSeg = op.path.split('/').filter(Boolean)[0] ?? '';\n const groupKey = firstSeg.startsWith('{') ? serviceName : toPascalCase(firstSeg);\n const group = pathGroups.get(groupKey) ?? [];\n group.push(op);\n pathGroups.set(groupKey, group);\n }\n // Only split if there are multiple distinct path-prefix groups AND\n // at least one group name differs from the current service name\n if (pathGroups.size > 1) {\n const needsSplit = [...pathGroups.keys()].some((k) => k !== serviceName);\n if (needsSplit) {\n serviceMap.delete(serviceName);\n for (const [groupName, groupOps] of pathGroups) {\n const existing = serviceMap.get(groupName) ?? [];\n existing.push(...groupOps);\n serviceMap.set(groupName, existing);\n }\n }\n }\n }\n\n // Disambiguate operation names within each service.\n // Multiple operations can get the same name (e.g., several \"list\" endpoints\n // in UserManagement for users, invitations, auth factors, etc.).\n for (const [, operations] of serviceMap) {\n disambiguateOperationNames(operations);\n }\n\n const services = Array.from(serviceMap.entries()).map(([name, operations]) => ({\n name,\n operations,\n }));\n\n return { services, inlineModels };\n}\n\nfunction inferServiceName(path: string, tag?: string): string {\n // Prefer OpenAPI tag when available — tags represent the logical grouping\n // (e.g., \"multi-factor-auth\" for /auth/factors/* endpoints).\n if (tag) {\n return toPascalCase(tag);\n }\n // Fallback: extract first meaningful path segment: /widgets/{id}/sub → \"Widgets\"\n const segments = path.split('/').filter(Boolean);\n const first = segments[0] ?? 'Default';\n // Skip path params\n if (first.startsWith('{')) return 'Default';\n return toPascalCase(first);\n}\n\nfunction inferOperationName(\n method: HttpMethod,\n path: string,\n operationId?: string,\n operationIdTransform?: (id: string) => string,\n): string {\n if (operationId) {\n if (operationIdTransform) {\n return operationIdTransform(operationId);\n }\n return toCamelCase(operationId);\n }\n\n // Fallback when no operationId is available — use method + path to build\n // a descriptive name like \"listUsers\", \"getOrganization\", \"deleteAuthFactor\"\n const verb = inferVerb(method, path);\n const resource = inferResourceFromPath(path);\n return resource ? toCamelCase(`${verb}_${resource}`) : verb;\n}\n\n/**\n * Infer the CRUD verb from HTTP method and path shape.\n */\nfunction inferVerb(method: HttpMethod, path: string): string {\n const segments = path.split('/').filter(Boolean);\n const hasTrailingParam = segments.length > 0 && segments[segments.length - 1].startsWith('{');\n\n switch (method) {\n case 'get':\n return hasTrailingParam ? 'get' : 'list';\n case 'post':\n return 'create';\n case 'put':\n case 'patch':\n return 'update';\n case 'delete':\n return 'delete';\n case 'head':\n return 'check';\n case 'options':\n return 'options';\n case 'trace':\n return 'trace';\n default:\n return method;\n }\n}\n\n/**\n * Extract a resource noun from the path for operation naming.\n * Uses the last non-param segment (the resource being operated on).\n *\n * Examples:\n * /user_management/users → \"Users\"\n * /user_management/users/{id} → \"User\" (singular for item operations)\n * /user_management/users/{id}/auth_factors → \"AuthFactors\"\n * /organizations/{id}/api_keys → \"ApiKeys\"\n * /sso/authorize → \"Authorize\" (action endpoint)\n */\nfunction inferResourceFromPath(path: string): string | null {\n const segments = path.split('/').filter(Boolean);\n if (segments.length <= 1) return null;\n\n // Find the last meaningful (non-param) segment\n let resourceSegment: string | null = null;\n for (let i = segments.length - 1; i >= 0; i--) {\n if (!segments[i].startsWith('{')) {\n resourceSegment = segments[i];\n break;\n }\n }\n\n if (!resourceSegment) return null;\n // Skip the service name (first segment) — it would be redundant\n if (resourceSegment === segments[0]) return null;\n\n return toPascalCase(resourceSegment);\n}\n\n/**\n * Detect and resolve name collisions within a service's operations.\n *\n * When multiple operations share the same name (e.g., several \"list\" from\n * different sub-resources), disambiguate by appending the resource noun\n * from the path. Only renames operations on DIFFERENT paths — same-name\n * operations on the same path (e.g., PUT + PATCH both \"update\") are left as-is\n * since they represent the same logical resource.\n */\nfunction disambiguateOperationNames(operations: Operation[]): void {\n // Group by name\n const byName = new Map<string, Operation[]>();\n for (const op of operations) {\n const group = byName.get(op.name) ?? [];\n group.push(op);\n byName.set(op.name, group);\n }\n\n for (const [name, group] of byName) {\n if (group.length <= 1) continue;\n\n // Check if these are genuinely different resources (different paths)\n // vs the same resource with different methods (PUT + PATCH)\n const uniquePaths = new Set(group.map((op) => op.path));\n if (uniquePaths.size <= 1) continue; // same path, different methods — no disambiguation needed\n\n for (const op of group) {\n const resource = inferResourceFromPath(op.path);\n if (resource) {\n const newName = toCamelCase(`${name}_${resource}`);\n (op as { name: string }).name = newName;\n }\n }\n\n // If disambiguation still left collisions (same sub-resource),\n // use the full distinguishing path segment chain\n const renamed = new Map<string, Operation[]>();\n for (const op of group) {\n const rGroup = renamed.get(op.name) ?? [];\n rGroup.push(op);\n renamed.set(op.name, rGroup);\n }\n for (const [, rGroup] of renamed) {\n if (rGroup.length <= 1) continue;\n // Still colliding — different paths map to same resource name.\n // Use deeper path context to disambiguate.\n for (const op of rGroup) {\n const deeper = inferDeeperContext(op.path);\n if (deeper) {\n (op as { name: string }).name = toCamelCase(`${op.name}_${deeper}`);\n }\n }\n }\n }\n}\n\n/**\n * Extract a deeper disambiguation context from the path when the last\n * segment isn't unique enough. Uses the second-to-last non-param segment.\n *\n * /users/{id}/auth_factors → already captured as \"AuthFactors\"\n * /users/external_id/{external_id} → \"ExternalId\" (special path, not a sub-resource)\n */\nfunction inferDeeperContext(path: string): string | null {\n const segments = path.split('/').filter(Boolean);\n const nonParams = segments.filter((s) => !s.startsWith('{'));\n // Skip first (service) and last (already used) — use the middle ones\n if (nonParams.length >= 3) {\n return toPascalCase(nonParams.slice(1, -1).join('_'));\n }\n return null;\n}\n\nfunction buildOperation(\n method: HttpMethod,\n path: string,\n op: OperationObject,\n pathLevelParams: ParameterObject[],\n operationIdTransform?: (id: string) => string,\n serviceName?: string,\n): { operation: Operation; inlineModels: Model[] } {\n const allParams = [...pathLevelParams, ...(op.parameters ?? [])];\n\n const hasIdempotencyHeader = allParams.some((p) => p.in === 'header' && p.name.toLowerCase() === 'idempotency-key');\n\n // Use the service name as context so inline parameter enums get qualified\n // names. e.g., service \"SSO\" + param \"provider\" → \"SSOProvider\".\n const opContext = serviceName;\n const pathParams = extractParams(allParams, 'path', opContext);\n const queryParams = extractParams(allParams, 'query', opContext);\n const headerParams = extractParams(allParams, 'header', opContext).filter(\n (p) => p.name.toLowerCase() !== 'idempotency-key',\n );\n const cookieParams = extractParams(allParams, 'cookie', opContext);\n\n const reqBodyModels: Model[] = [];\n const { body: requestBody, encoding: requestBodyEncoding } = extractRequestBody(op.requestBody, op, reqBodyModels);\n const {\n response,\n successResponses,\n errors,\n inlineModels,\n isPaginated,\n dataPath: responseDataPath,\n itemType: responseItemType,\n } = extractResponses(op.responses, op, path, method);\n inlineModels.push(...reqBodyModels);\n\n // Build structured pagination metadata from response classification and query param detection\n const paginationFromParams = detectPagination(response, queryParams, responseDataPath);\n let pagination: PaginationMeta | undefined;\n if (isPaginated) {\n const itemType = responseItemType ?? (response.kind === 'array' ? response.items : response);\n pagination = {\n strategy: paginationFromParams?.strategy ?? 'cursor',\n param: paginationFromParams?.param ?? 'after',\n limitParam: paginationFromParams?.limitParam,\n dataPath: responseDataPath ?? paginationFromParams?.dataPath,\n itemType,\n };\n } else if (paginationFromParams) {\n pagination = paginationFromParams;\n }\n\n // Extract per-operation security overrides\n const security = extractOperationSecurity(op.security);\n\n return {\n operation: {\n name: inferOperationName(method, path, op.operationId, operationIdTransform),\n description: buildDescription(op.summary, op.description),\n httpMethod: method,\n path,\n pathParams,\n queryParams,\n headerParams,\n cookieParams: cookieParams.length > 0 ? cookieParams : undefined,\n requestBody,\n requestBodyEncoding,\n response,\n successResponses,\n errors,\n pagination,\n injectIdempotencyKey: hasIdempotencyHeader,\n deprecated: op.deprecated || undefined,\n async: op['x-oagen-async'],\n security,\n },\n inlineModels,\n };\n}\n\n/**\n * Extract per-operation security requirements from an OpenAPI security directive.\n * Returns undefined when the operation uses the spec-level default security.\n *\n * OpenAPI security format: `security: [{ schemeName: [scope1, scope2] }]`\n */\nfunction extractOperationSecurity(\n security: Array<Record<string, string[]>> | undefined,\n): SecurityRequirement[] | undefined {\n if (!security || security.length === 0) return undefined;\n\n const requirements: SecurityRequirement[] = [];\n for (const entry of security) {\n for (const [schemeName, scopes] of Object.entries(entry)) {\n requirements.push({ schemeName, scopes: scopes ?? [] });\n }\n }\n return requirements.length > 0 ? requirements : undefined;\n}\n\nfunction buildDescription(summary: string | undefined, description: string | undefined): string | undefined {\n if (summary && description && summary !== description) {\n return `${summary}\\n\\n${description}`;\n }\n return description ?? summary;\n}\n\nfunction extractParams(\n params: ParameterObject[],\n location: 'path' | 'query' | 'header' | 'cookie',\n operationContext?: string,\n): Parameter[] {\n return params\n .filter((p) => p.in === location)\n .map((p) => ({\n name: p.name,\n type: p.schema\n ? schemaToTypeRef(p.schema, p.name, operationContext ? toPascalCase(operationContext) : undefined)\n : ({ kind: 'primitive', type: 'string' } as TypeRef),\n required: p.required ?? false,\n description: p.description,\n deprecated: p.deprecated || p.schema?.deprecated || undefined,\n default: p.schema?.default,\n example: p.example ?? p.schema?.example,\n style: p.style as Parameter['style'],\n explode: p.explode,\n }));\n}\n\nfunction extractRequestBody(\n body: RequestBodyObject | undefined,\n op: OperationObject | undefined,\n inlineModels: Model[],\n): { body?: TypeRef; encoding?: 'json' | 'form-data' | 'form-urlencoded' | 'binary' | 'text' } {\n if (!body?.content) return {};\n\n // Detect encoding and find schema from content type in priority order\n let encoding: 'json' | 'form-data' | 'form-urlencoded' | 'binary' | 'text' = 'json';\n let schema: SchemaObject | undefined;\n\n if (body.content['application/json']?.schema) {\n encoding = 'json';\n schema = body.content['application/json']!.schema;\n } else if (body.content['multipart/form-data']?.schema) {\n encoding = 'form-data';\n schema = body.content['multipart/form-data']!.schema;\n } else if (body.content['application/x-www-form-urlencoded']?.schema) {\n encoding = 'form-urlencoded';\n schema = body.content['application/x-www-form-urlencoded']!.schema;\n } else if (body.content['application/octet-stream']) {\n encoding = 'binary';\n schema = body.content['application/octet-stream']!.schema;\n } else if (body.content['text/plain']) {\n encoding = 'text';\n schema = body.content['text/plain']!.schema;\n }\n\n if (!schema) {\n // For binary/text, a schema is optional — produce a primitive TypeRef\n if (encoding === 'binary') {\n return { body: { kind: 'primitive', type: 'string', format: 'binary' }, encoding };\n }\n if (encoding === 'text') {\n return { body: { kind: 'primitive', type: 'string' }, encoding };\n }\n return {};\n }\n\n const rawName = op?.operationId ? toPascalCase(op.operationId) + 'Request' : 'RequestBody';\n const contextName = cleanSchemaName(rawName);\n\n // If the request body is an inline object with properties, extract it as a model\n if (schema.properties && (schema.type === 'object' || !schema.type)) {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n for (const [fieldName, fieldSchema] of Object.entries(schema.properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, contextName, requiredSet));\n }\n inlineModels.push({ name: contextName, description: undefined, fields });\n return { body: { kind: 'model', name: contextName }, encoding };\n }\n\n // If the request body is a oneOf, extract each variant as an inline model\n // and build a union type pointing to them by name.\n if (schema.oneOf) {\n const variants: TypeRef[] = [];\n\n for (const variant of schema.oneOf) {\n if (variant.$ref) {\n const ref = schemaToTypeRef(variant, contextName);\n variants.push(ref);\n } else if (variant.type === 'null') {\n // skip null variant in union, handle separately\n } else if (variant.properties && (variant.type === 'object' || !variant.type)) {\n const variantName = deriveOneOfVariantName(variant, contextName, inlineModels);\n const requiredSet = new Set(variant.required ?? []);\n const fields: Field[] = [];\n for (const [fieldName, fieldSchema] of Object.entries(variant.properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, variantName, requiredSet));\n }\n inlineModels.push({ name: variantName, description: variant.description, fields });\n variants.push({ kind: 'model', name: variantName });\n } else {\n variants.push(schemaToTypeRef(variant, contextName));\n }\n }\n\n const hasNull = schema.oneOf.some(\n (v: SchemaObject) => v.type === 'null' || (Array.isArray(v.type) && v.type.includes('null')),\n );\n const union: TypeRef = {\n kind: 'union',\n variants,\n ...(schema.discriminator\n ? {\n discriminator: { property: schema.discriminator.propertyName, mapping: schema.discriminator.mapping ?? {} },\n }\n : {}),\n };\n const body = hasNull ? ({ kind: 'nullable', inner: union } as TypeRef) : union;\n return { body, encoding };\n }\n\n return { body: schemaToTypeRef(schema, contextName), encoding };\n}\n\n/** Derive a unique variant name for a oneOf inline model. */\nfunction deriveOneOfVariantName(variant: SchemaObject, baseName: string, existingModels: Model[]): string {\n // Try to use a distinguishing property (e.g., \"grant_type\" field's const/enum value)\n if (variant.properties) {\n for (const [, propSchema] of Object.entries(variant.properties)) {\n if (propSchema?.const && typeof propSchema.const === 'string') {\n return toPascalCase(propSchema.const) + baseName.replace(/Request$/, '') + 'Request';\n }\n }\n }\n // Fallback: append a numeric suffix\n const existingNames = new Set(existingModels.map((m) => m.name));\n let name = baseName;\n let suffix = 2;\n while (existingNames.has(name)) {\n name = `${baseName}${suffix}`;\n suffix++;\n }\n return name;\n}\n\nfunction deriveResponseName(op: OperationObject | undefined, path: string, method: HttpMethod): string {\n if (op?.operationId) {\n return cleanSchemaName(toPascalCase(op.operationId) + 'Response');\n }\n const segments = path.split('/').filter(Boolean);\n const resource = segments[0] ?? 'Unknown';\n return toPascalCase(resource) + toPascalCase(method) + 'Response';\n}\n\nfunction extractResponses(\n responses?: Record<string, ResponseObject>,\n op?: OperationObject,\n path?: string,\n method?: HttpMethod,\n): {\n response: TypeRef;\n successResponses?: SuccessResponse[];\n errors: ErrorResponse[];\n inlineModels: Model[];\n isPaginated: boolean;\n dataPath?: string;\n itemType?: TypeRef;\n} {\n const errors: ErrorResponse[] = [];\n let response: TypeRef = { kind: 'primitive', type: 'string' };\n let inlineModels: Model[] = [];\n let isPaginated = false;\n let dataPath: string | undefined;\n let itemType: TypeRef | undefined;\n\n if (!responses) return { response, errors, inlineModels, isPaginated };\n\n const allSuccessResponses: SuccessResponse[] = [];\n\n for (const [statusCode, resp] of Object.entries(responses)) {\n const code = parseInt(statusCode, 10);\n\n if (code >= 200 && code < 300) {\n let extractedType: TypeRef = { kind: 'primitive', type: 'unknown' };\n const jsonContent = resp.content?.['application/json'];\n if (jsonContent?.schema) {\n const contextName = deriveResponseName(op, path ?? '/', method ?? 'get');\n const result = classifyAndExtractResponse(jsonContent.schema, contextName);\n extractedType = result.response;\n // Keep track of inline models and pagination from the latest 2xx with a schema\n inlineModels = result.inlineModels;\n isPaginated = result.isPaginated;\n dataPath = result.dataPath;\n itemType = result.itemType;\n } else if (resp.content) {\n // Handle non-JSON response content types (text/plain, binary, XML, etc.)\n if (resp.content['application/octet-stream'] || resp.content['application/pdf']) {\n extractedType = { kind: 'primitive', type: 'string', format: 'binary' };\n } else if (\n resp.content['text/plain'] ||\n resp.content['text/html'] ||\n resp.content['text/xml'] ||\n resp.content['application/xml']\n ) {\n extractedType = { kind: 'primitive', type: 'string' };\n } else {\n // Try the first available content type's schema\n const firstKey = Object.keys(resp.content)[0];\n if (firstKey) {\n const firstContent = resp.content[firstKey];\n if (firstContent?.schema) {\n extractedType = schemaToTypeRef(\n firstContent.schema,\n deriveResponseName(op, path ?? '/', method ?? 'get'),\n );\n }\n }\n }\n }\n allSuccessResponses.push({ statusCode: code, type: extractedType });\n } else if (code >= 300 && code < 400) {\n // 3xx redirects — include so emitter can detect redirect endpoints\n allSuccessResponses.push({ statusCode: code, type: { kind: 'primitive', type: 'unknown' } });\n } else if (code >= 400) {\n const jsonContent = resp.content?.['application/json'];\n const type = jsonContent?.schema ? schemaToTypeRef(jsonContent.schema, `Error${code}`) : undefined;\n errors.push({ statusCode: code, type });\n }\n }\n\n // Primary response = lowest 2xx with a body schema, falling back to first 2xx\n if (allSuccessResponses.length > 0) {\n const sorted = [...allSuccessResponses].sort((a, b) => a.statusCode - b.statusCode);\n const primary =\n sorted.find((r) => r.type.kind !== 'primitive' || (r.type as { type: string }).type !== 'unknown') ?? sorted[0];\n response = primary.type;\n }\n\n const successResponses = allSuccessResponses.length > 1 ? allSuccessResponses : undefined;\n\n return { response, successResponses, errors, inlineModels, isPaginated, dataPath, itemType };\n}\n","import type { Model, Service, TypeRef } from '../ir/types.js';\nimport { walkTypeRef } from '../ir/types.js';\n\nfunction keepLargestByName(models: Model[]): Model[] {\n const byName = new Map<string, Model>();\n for (const model of models) {\n const existing = byName.get(model.name);\n if (!existing || model.fields.length > existing.fields.length) {\n byName.set(model.name, model);\n }\n }\n return [...byName.values()];\n}\n\nfunction rewriteModelRef(ref: TypeRef, oldName: string, newName: string): void {\n walkTypeRef(ref, {\n model: (r) => {\n if (r.name === oldName) (r as { name: string }).name = newName;\n },\n });\n}\n\nfunction rewriteModelRefs(models: Model[], services: Service[], oldName: string, newName: string): void {\n for (const model of models) {\n for (const field of model.fields) {\n rewriteModelRef(field.type, oldName, newName);\n }\n }\n for (const service of services) {\n for (const op of service.operations) {\n rewriteModelRef(op.response, oldName, newName);\n if (op.requestBody) {\n rewriteModelRef(op.requestBody, oldName, newName);\n }\n }\n }\n}\n\nexport function mergeInlineResponseModels(schemaModels: Model[], inlineModels: Model[]): Model[] {\n const mergedSchemaModels = [...schemaModels];\n const schemaModelNames = new Set(mergedSchemaModels.map((m) => m.name));\n const schemaModelsByName = new Map(mergedSchemaModels.map((m) => [m.name, m]));\n\n const deduplicatedInlineModels = inlineModels.filter((model) => {\n if (!schemaModelNames.has(model.name)) return true;\n\n const existing = schemaModelsByName.get(model.name)!;\n const existingFieldNames = new Set(existing.fields.map((f) => f.name));\n const inlineFieldNames = new Set(model.fields.map((f) => f.name));\n const hasDifference =\n model.fields.some((f) => !existingFieldNames.has(f.name)) ||\n existing.fields.some((f) => !inlineFieldNames.has(f.name));\n\n if (hasDifference && model.fields.length > existing.fields.length) {\n const idx = mergedSchemaModels.indexOf(existing);\n if (idx !== -1) mergedSchemaModels[idx] = model;\n schemaModelsByName.set(model.name, model);\n console.warn(\n `[oagen] Warning: Inline model \"${model.name}\" has more fields than component schema (${model.fields.length} vs ${existing.fields.length}) — using inline response model`,\n );\n } else if (hasDifference) {\n console.warn(\n `[oagen] Warning: Inline model \"${model.name}\" has different fields than component schema — using component schema`,\n );\n }\n\n return false;\n });\n\n return [...mergedSchemaModels, ...keepLargestByName(deduplicatedInlineModels)];\n}\n\nexport function mergeFieldInlineModels(existingModels: Model[], fieldInlineModels: Model[]): Model[] {\n const modelNames = new Set(existingModels.map((m) => m.name));\n const modelsByName = new Map(existingModels.map((m) => [m.name, m]));\n\n const deduplicatedFieldModels = fieldInlineModels.filter((model) => {\n if (!modelNames.has(model.name)) return true;\n\n const existing = modelsByName.get(model.name)!;\n const existingFieldNames = new Set(existing.fields.map((f) => f.name));\n const inlineFieldNames = new Set(model.fields.map((f) => f.name));\n const hasDifference =\n model.fields.some((f) => !existingFieldNames.has(f.name)) ||\n existing.fields.some((f) => !inlineFieldNames.has(f.name));\n\n if (hasDifference) {\n console.warn(\n `[oagen] Warning: Inline model \"${model.name}\" has different fields than component schema — using component schema`,\n );\n }\n\n return false;\n });\n\n return [...existingModels, ...keepLargestByName(deduplicatedFieldModels)];\n}\n\nfunction hasModelConstDiscriminant(model: Model): boolean {\n return model.fields.some(\n (f) => (f.name === 'object' || f.name === 'type') && f.type.kind === 'literal' && typeof f.type.value === 'string',\n );\n}\n\nfunction isModelReferencedByOthers(name: string, models: Model[], excludeNames: Set<string>): boolean {\n for (const model of models) {\n if (excludeNames.has(model.name)) continue;\n for (const field of model.fields) {\n let found = false;\n walkTypeRef(field.type, {\n model: (r) => {\n if (r.name === name) found = true;\n },\n });\n if (found) return true;\n }\n }\n return false;\n}\n\nexport function collapseJsonSuffixModels(models: Model[], services: Service[]): Model[] {\n const normalizedModels = [...models];\n const byName = new Map(normalizedModels.map((m) => [m.name, m]));\n\n // Pass 1: collect merge candidates\n const mergeCandidates: Array<{ jsonModel: Model; baseModel: Model }> = [];\n for (const model of normalizedModels) {\n if (!model.name.endsWith('Json')) continue;\n\n const baseName = model.name.slice(0, -4);\n const baseModel = byName.get(baseName);\n if (!baseModel || model.fields.length <= baseModel.fields.length) continue;\n\n const isSuperset = baseModel.fields.every((f) => model.fields.some((mf) => mf.name === f.name));\n if (!isSuperset) continue;\n\n // Guard: both models have a const discriminant — they are distinct entities\n if (hasModelConstDiscriminant(model) && hasModelConstDiscriminant(baseModel)) continue;\n\n // Guard: a third model explicitly references the Json-suffix model\n if (isModelReferencedByOthers(model.name, normalizedModels, new Set([model.name, baseName]))) continue;\n\n mergeCandidates.push({ jsonModel: model, baseModel });\n }\n\n // Pass 2: apply merges\n const toRemove = new Set<string>();\n for (const { jsonModel, baseModel } of mergeCandidates) {\n baseModel.fields = jsonModel.fields;\n toRemove.add(jsonModel.name);\n rewriteModelRefs(normalizedModels, services, jsonModel.name, baseModel.name);\n console.warn(\n `[oagen] Merged \"${jsonModel.name}\" into \"${baseModel.name}\" (${jsonModel.fields.length} fields, superset)`,\n );\n }\n\n return normalizedModels.filter((m) => !toRemove.has(m.name));\n}\n","import type { Enum, Model, Service } from '../ir/types.js';\nimport { collectInlineEnumFromRef } from './schemas.js';\n\nexport function collectInlineEnumsFromModels(models: Model[], enums: Enum[]): void {\n const enumNames = new Set(enums.map((e) => e.name));\n for (const model of models) {\n for (const field of model.fields) {\n collectInlineEnumFromRef(field.type, enums, enumNames);\n }\n }\n}\n\n/**\n * Collect inline enum definitions from operation parameters (query, path, header)\n * and promote them to top-level enums so emitters can generate typed enum files.\n */\nexport function collectInlineEnumsFromOperations(services: Service[], enums: Enum[]): void {\n const enumNames = new Set(enums.map((e) => e.name));\n for (const service of services) {\n for (const op of service.operations) {\n for (const param of [...op.pathParams, ...op.queryParams, ...op.headerParams, ...(op.cookieParams ?? [])]) {\n collectInlineEnumFromRef(param.type, enums, enumNames);\n }\n }\n }\n}\n","import type { ApiSpec, TypeRef } from '../ir/types.js';\nimport { walkTypeRef } from '../ir/types.js';\n\nexport function validateModelRefs(spec: ApiSpec): void {\n const knownNames = new Set<string>();\n for (const m of spec.models) knownNames.add(m.name);\n for (const e of spec.enums) knownNames.add(e.name);\n\n function walkRef(ref: TypeRef, context: string): void {\n walkTypeRef(ref, {\n model: (r) => {\n if (!knownNames.has(r.name)) {\n console.warn(`[oagen] Warning: Unresolved model reference \"${r.name}\" (context: ${context})`);\n }\n },\n });\n }\n\n for (const model of spec.models) {\n for (const field of model.fields) {\n walkRef(field.type, `${model.name}.${field.name}`);\n }\n }\n\n for (const service of spec.services) {\n for (const op of service.operations) {\n for (const p of [...op.pathParams, ...op.queryParams, ...op.headerParams]) {\n walkRef(p.type, `${service.name}.${op.name}.${p.name}`);\n }\n if (op.requestBody) walkRef(op.requestBody, `${service.name}.${op.name}.requestBody`);\n walkRef(op.response, `${service.name}.${op.name}.response`);\n }\n }\n}\n","import type { ApiSpec, AuthScheme, ServerEntry } from '../ir/types.js';\nimport { defaultSdkBehavior } from '../ir/sdk-behavior.js';\nimport { SpecParseError } from '../errors.js';\nimport { loadAndBundleSpec } from './refs.js';\nimport { extractSchemas, extractInlineModelsFromSchemas, clearSchemaNameTransform } from './schemas.js';\nimport { extractOperations } from './operations.js';\nimport {\n mergeInlineResponseModels,\n collapseJsonSuffixModels,\n mergeFieldInlineModels,\n} from './normalize-inline-models.js';\nimport { collectInlineEnumsFromModels, collectInlineEnumsFromOperations } from './collect-inline-enums.js';\nimport { validateModelRefs } from './normalize-model-refs.js';\n\nexport interface ParseOptions {\n operationIdTransform?: (id: string) => string;\n schemaNameTransform?: (name: string) => string;\n}\n\nexport async function parseSpec(specPath: string, options?: ParseOptions): Promise<ApiSpec> {\n const { parsed } = await loadAndBundleSpec(specPath);\n\n const spec = parsed as {\n openapi?: string;\n info?: { title?: string; version?: string; description?: string };\n servers?: Array<{ url?: string; description?: string }>;\n paths?: Record<string, unknown>;\n components?: {\n schemas?: Record<string, unknown>;\n securitySchemes?: Record<\n string,\n { type: string; scheme?: string; in?: string; name?: string; flows?: Record<string, unknown> }\n >;\n };\n };\n\n // Validate OpenAPI version\n const version = spec.openapi ?? '';\n if (!version.startsWith('3.')) {\n throw new SpecParseError(\n `Unsupported OpenAPI version: ${version}. oagen requires OpenAPI 3.x`,\n `Update the spec to OpenAPI 3.0 or 3.1. If you are using Swagger 2.x, convert it first with \\`npx swagger2openapi ${specPath}\\`.`,\n );\n }\n\n const { models, enums } = extractSchemas(\n spec.components?.schemas as Record<string, Record<string, unknown>> | undefined,\n { schemaNameTransform: options?.schemaNameTransform },\n );\n\n const { services, inlineModels } = extractOperations(\n spec.paths as Record<string, Record<string, unknown>> | undefined,\n options?.operationIdTransform,\n );\n\n // schemaNameTransform is kept active through extractOperations so that\n // $ref-based TypeRefs in operations resolve to the same transformed names.\n // Now that all extraction is done, clear it.\n clearSchemaNameTransform();\n\n const responseNormalizedModels = mergeInlineResponseModels(models, inlineModels);\n\n // Extract inline models from model field definitions (objects/arrays with properties)\n const fieldInlineModels = extractInlineModelsFromSchemas(\n spec.components?.schemas as Record<string, Record<string, unknown>> | undefined,\n );\n const fieldMergedModels = mergeFieldInlineModels(responseNormalizedModels, fieldInlineModels);\n const finalModels = collapseJsonSuffixModels(fieldMergedModels, services);\n collectInlineEnumsFromModels(finalModels, enums);\n collectInlineEnumsFromOperations(services, enums);\n\n const auth = extractAuthSchemes(spec.components?.securitySchemes);\n\n const serverEntries: ServerEntry[] = (spec.servers ?? [])\n .map((s) => ({ url: s.url ?? '', description: s.description }))\n .filter((s) => s.url);\n\n const result: ApiSpec = {\n name: spec.info?.title ?? 'Unknown API',\n version: spec.info?.version ?? '0.0.0',\n description: spec.info?.description,\n baseUrl: serverEntries[0]?.url ?? '',\n servers: serverEntries.length > 0 ? serverEntries : undefined,\n services,\n models: finalModels,\n enums,\n auth,\n sdk: defaultSdkBehavior(),\n };\n\n validateModelRefs(result);\n\n return result;\n}\n/** Extract authentication schemes from OpenAPI securitySchemes. */\nfunction extractAuthSchemes(\n securitySchemes?: Record<\n string,\n { type: string; scheme?: string; in?: string; name?: string; flows?: Record<string, unknown> }\n >,\n): AuthScheme[] | undefined {\n if (!securitySchemes) return undefined;\n const schemes: AuthScheme[] = [];\n for (const [, scheme] of Object.entries(securitySchemes)) {\n if (scheme.type === 'http' && scheme.scheme === 'bearer') {\n schemes.push({ kind: 'bearer' });\n } else if (scheme.type === 'apiKey' && scheme.in && scheme.name) {\n schemes.push({ kind: 'apiKey', in: scheme.in as 'header' | 'query' | 'cookie', name: scheme.name });\n } else if (scheme.type === 'oauth2' && scheme.flows) {\n schemes.push({ kind: 'oauth2', flows: scheme.flows });\n }\n }\n return schemes.length > 0 ? schemes : undefined;\n}\n","import type { Operation, TypeRef } from '../ir/types.js';\nimport { assertNever } from '../ir/types.js';\n\nexport interface OperationPlan {\n operation: Operation;\n isDelete: boolean;\n hasBody: boolean;\n isIdempotentPost: boolean;\n pathParamsInOptions: boolean;\n isPaginated: boolean;\n responseModelName: string | null;\n /** For paginated operations, the model name of individual list items\n * (unwrapped from the list wrapper). Null for non-paginated. */\n paginatedItemModelName: string | null;\n isModelResponse: boolean;\n /** True when the response is an unpaginated `type: array` of models.\n * Emitters should use this to return `Model[]` (or the language's list\n * equivalent) and map the deserializer over each element. */\n isArrayResponse: boolean;\n hasQueryParams: boolean;\n isAsync: boolean;\n}\n\nexport function planOperation(op: Operation): OperationPlan {\n const isDelete = op.httpMethod === 'delete';\n const hasBody = !!op.requestBody;\n const isIdempotentPost = op.injectIdempotencyKey && op.httpMethod === 'post';\n const hasQueryParams = op.queryParams.length > 0;\n const pathParamsInOptions = op.pathParams.length > 1 || (op.pathParams.length > 0 && (hasBody || hasQueryParams));\n const isPaginated = op.pagination !== undefined;\n const responseModelName = resolveResponseModelName(op);\n const paginatedItemModelName =\n isPaginated && op.pagination?.itemType.kind === 'model' ? op.pagination.itemType.name : null;\n const isModelResponse = responseModelName !== null;\n // Unpaginated `type: array` of models — needs `Model[]` return + elementwise\n // deserialization. Paginated operations use the pagination wrapper instead.\n const isArrayResponse = !isPaginated && op.response.kind === 'array' && op.response.items.kind === 'model';\n const isAsync = op.async ?? true;\n\n return {\n operation: op,\n isDelete,\n hasBody,\n isIdempotentPost,\n pathParamsInOptions,\n isPaginated,\n responseModelName,\n paginatedItemModelName,\n isModelResponse,\n isArrayResponse,\n hasQueryParams,\n isAsync,\n };\n}\n\nexport function resolveResponseModelName(op: Operation): string | null {\n if (op.httpMethod === 'delete') return null;\n return extractModelName(op.response);\n}\n\nfunction extractModelName(ref: TypeRef): string | null {\n switch (ref.kind) {\n case 'model':\n return ref.name;\n case 'array':\n return ref.items.kind === 'model' ? ref.items.name : null;\n case 'nullable':\n return extractModelName(ref.inner);\n case 'union': {\n const firstModel = ref.variants.find((v) => v.kind === 'model');\n return firstModel && firstModel.kind === 'model' ? firstModel.name : null;\n }\n case 'map':\n case 'enum':\n case 'primitive':\n case 'literal':\n return null;\n default:\n return assertNever(ref);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/ir/sdk-behavior.ts","../src/parser/refs.ts","../src/parser/inline-models.ts","../src/parser/schemas.ts","../src/parser/pagination.ts","../src/parser/responses.ts","../src/parser/operations.ts","../src/parser/normalize-inline-models.ts","../src/parser/collect-inline-enums.ts","../src/parser/normalize-model-refs.ts","../src/parser/parse.ts","../src/engine/operation-plan.ts"],"sourcesContent":["/**\n * SDK Behavior IR — language-agnostic runtime policies for generated SDKs.\n *\n * These types capture the \"what\" of SDK behavior (retry, telemetry, errors, etc.)\n * while emitters provide the \"how\" (language-specific mechanism).\n *\n * Emitters access these via `ctx.spec.sdk` — always populated, never undefined.\n */\n\n// ── Retry ──────────────────────────────────────────────────────────\n\n/** Retry policy — when and how to retry failed requests. */\nexport interface RetryPolicy {\n /** HTTP status codes that trigger a retry. */\n retryableStatusCodes: number[];\n /** Maximum number of retry attempts (0 = no retries). */\n maxRetries: number;\n /** Whether to retry on connection errors (DNS failure, TCP reset). */\n retryOnConnectionError: boolean;\n /** Whether to retry on timeout errors. */\n retryOnTimeout: boolean;\n /** Backoff strategy between retries. */\n backoff: BackoffStrategy;\n}\n\n/** Exponential backoff configuration.\n *\n * Formula: `delay = min(initialDelay * multiplier^attempt, maxDelay)`\n * With jitter: `delay += delay * jitterFactor * random(0, 1)`\n */\nexport interface BackoffStrategy {\n /** Initial delay in seconds before the first retry. */\n initialDelay: number;\n /** Multiplier applied to the delay on each subsequent retry. */\n multiplier: number;\n /** Maximum delay in seconds (cap). */\n maxDelay: number;\n /** Jitter factor (0..1). 0.5 means up to 50% random jitter added. */\n jitterFactor: number;\n}\n\n// ── Errors ─────────────────────────────────────────────────────────\n\n/** Error mapping — status codes to named exception kinds. */\nexport interface ErrorPolicy {\n /** Map from HTTP status code to a logical error kind name (e.g. 400 → 'BadRequest').\n * Emitters append language-specific suffixes (e.g. 'BadRequestException'). */\n statusCodeMap: Record<number, string>;\n /** Catch-all error kind for 5xx status codes not in the map. */\n serverErrorKind: string;\n /** Catch-all error kind for unrecognized status codes. */\n clientErrorKind: string;\n /** URL template for error documentation. Use {code} as placeholder for the API error code.\n * Example: 'https://workos.com/docs/errors/{code}' */\n errorDocUrlTemplate?: string;\n}\n\n// ── Telemetry ──────────────────────────────────────────────────────\n\n/** Telemetry — what request metrics to track and send. */\nexport interface TelemetryPolicy {\n /** Whether telemetry is enabled by default. Users can opt out via constructor param. */\n enabledByDefault: boolean;\n /** Header name for client telemetry data (previous request's ID + latency). */\n headerName: string;\n /** Response header name for the request ID. */\n requestIdHeader: string;\n}\n\n// ── Pagination ─────────────────────────────────────────────────────\n\n/** Pagination behavior defaults. */\nexport interface PaginationPolicy {\n /** Delay in milliseconds between pages during auto-pagination. 0 = no delay. */\n autoPageDelayMs: number;\n}\n\n// ── Idempotency ────────────────────────────────────────────────────\n\n/** Idempotency auto-generation rules. */\nexport interface IdempotencyPolicy {\n /** Header name for the idempotency key. */\n headerName: string;\n /** Whether to auto-generate a UUID v4 idempotency key for POST requests when retries > 0. */\n autoGenerateForPost: boolean;\n}\n\n// ── Logging ────────────────────────────────────────────────────────\n\n/** Logging contract — what to log at which level. */\nexport interface LoggingPolicy {\n /** Whether structured logging hooks are generated. */\n enabled: boolean;\n /** Log events that the generated client emits. */\n events: LogEvent[];\n}\n\n/** A discrete loggable event in the request lifecycle. */\nexport type LogEvent =\n | 'request.start'\n | 'request.success'\n | 'request.retry'\n | 'request.rate_limited'\n | 'request.error'\n | 'request.connection_error';\n\n// ── User-Agent ─────────────────────────────────────────────────────\n\n/** User-Agent construction rules. */\nexport interface UserAgentPolicy {\n /** Template for the SDK identifier string.\n * Placeholders: {name} = spec name, {lang} = emitter language, {version} = SDK version.\n * Each emitter interpolates with its own language string and casing conventions.\n * Example: '{name} {lang}/{version}' → 'WorkOS PHP/4.32.0' */\n sdkIdentifierTemplate: string;\n /** Whether to append the runtime/language version (e.g. PHP 8.2, Python 3.12). */\n includeRuntimeVersion: boolean;\n /** Whether to allow app info enrichment via setAppInfo(name, version, url). */\n allowAppInfo: boolean;\n /** AI agent environment variable detection entries. */\n aiAgentEnvVars: AiAgentEnvVar[];\n}\n\n/** Maps an environment variable to an AI agent slug for User-Agent enrichment. */\nexport interface AiAgentEnvVar {\n /** Environment variable to check (e.g. 'CLAUDE_CODE'). */\n envVar: string;\n /** Agent name to append to User-Agent (e.g. 'ClaudeCode'). */\n agentName: string;\n}\n\n// ── Request Guards ─────────────────────────────────────────────────\n\n/** Guards that validate request params before sending. */\nexport interface RequestGuardPolicy {\n /** Keys that should be in RequestOptions, not in params.\n * If detected in the body or query params, the SDK throws an error. */\n optionKeys: string[];\n}\n\n// ── Timeouts ───────────────────────────────────────────────────────\n\n/** Timeout configuration. */\nexport interface TimeoutPolicy {\n /** Default HTTP request timeout in seconds. */\n defaultTimeoutSeconds: number;\n /** Environment variable name to override the timeout (e.g. 'WORKOS_REQUEST_TIMEOUT'). */\n timeoutEnvVar?: string;\n}\n\n// ── Root ───────────────────────────────────────────────────────────\n\n/** Language-agnostic runtime policies for generated SDKs.\n * Attached to `ApiSpec.sdk` and consumed by emitters via `ctx.spec.sdk`. */\nexport interface SdkBehavior {\n retry: RetryPolicy;\n errors: ErrorPolicy;\n telemetry: TelemetryPolicy;\n pagination: PaginationPolicy;\n idempotency: IdempotencyPolicy;\n logging: LoggingPolicy;\n userAgent: UserAgentPolicy;\n requestGuard: RequestGuardPolicy;\n timeout: TimeoutPolicy;\n}\n\n// ── Defaults ───────────────────────────────────────────────────────\n\n/**\n * Canonical SDK behavior defaults. These match the PHP emitter's current\n * implementation (the most complete). Per-language overrides can be applied\n * via `mergeSdkBehavior()` in each SDK's `oagen.config.ts`.\n *\n * - Retry: exponential backoff with jitter, retries on 429/5xx\n * - Errors: standard HTTP status → exception kind mapping\n * - Telemetry: enabled by default, tracks request ID + latency\n * - Pagination: no inter-page delay (Node overrides to 350ms)\n * - Idempotency: auto-generate UUID v4 for retryable POSTs\n * - Logging: all lifecycle events enabled\n * - User-Agent: SDK identifier + runtime version + app info + AI agent detection\n * - Request guards: detect misplaced RequestOptions keys in params\n * - Timeout: 60s default (Python overrides to 30s)\n */\nexport function defaultSdkBehavior(): SdkBehavior {\n return {\n retry: {\n retryableStatusCodes: [429, 500, 502, 503, 504],\n maxRetries: 3,\n retryOnConnectionError: true,\n retryOnTimeout: true,\n backoff: {\n initialDelay: 1.0,\n multiplier: 2.0,\n maxDelay: 30.0,\n jitterFactor: 0.5,\n },\n },\n errors: {\n statusCodeMap: {\n 400: 'BadRequest',\n 401: 'Authentication',\n 403: 'Authorization',\n 404: 'NotFound',\n 409: 'Conflict',\n 422: 'UnprocessableEntity',\n 429: 'RateLimitExceeded',\n },\n serverErrorKind: 'Server',\n clientErrorKind: 'Api',\n errorDocUrlTemplate: 'https://workos.com/docs/errors/{code}',\n },\n telemetry: {\n enabledByDefault: true,\n headerName: 'X-WorkOS-Client-Telemetry',\n requestIdHeader: 'X-Request-ID',\n },\n pagination: {\n autoPageDelayMs: 0,\n },\n idempotency: {\n headerName: 'Idempotency-Key',\n autoGenerateForPost: true,\n },\n logging: {\n enabled: true,\n events: [\n 'request.start',\n 'request.success',\n 'request.retry',\n 'request.rate_limited',\n 'request.error',\n 'request.connection_error',\n ],\n },\n userAgent: {\n sdkIdentifierTemplate: '{name} {lang}/{version}',\n includeRuntimeVersion: true,\n allowAppInfo: true,\n aiAgentEnvVars: [\n { envVar: 'CLAUDE_CODE', agentName: 'ClaudeCode' },\n { envVar: 'CURSOR_AGENT', agentName: 'Cursor' },\n { envVar: 'CLINE_ACTIVE', agentName: 'Cline' },\n { envVar: 'WINDSURF_ACTIVE', agentName: 'Windsurf' },\n { envVar: 'COPILOT_AGENT', agentName: 'Copilot' },\n ],\n },\n requestGuard: {\n optionKeys: [\n 'api_key',\n 'apiKey',\n 'idempotency_key',\n 'idempotencyKey',\n 'extra_headers',\n 'extraHeaders',\n 'max_retries',\n 'maxRetries',\n 'base_url',\n 'baseUrl',\n ],\n },\n timeout: {\n defaultTimeoutSeconds: 60,\n },\n };\n}\n\n// ── Merge ──────────────────────────────────────────────────────────\n\n/** Recursive partial type for deep overrides. */\nexport type DeepPartial<T> = {\n [K in keyof T]?: T[K] extends (infer U)[]\n ? U[] // Arrays replace entirely (don't concat)\n : T[K] extends object\n ? DeepPartial<T[K]>\n : T[K];\n};\n\n/**\n * Deep-merge partial overrides into the canonical defaults.\n * Arrays replace entirely (so `retryableStatusCodes: [429]` replaces the full list,\n * rather than appending). Object properties are merged recursively.\n */\nexport function mergeSdkBehavior(overrides: DeepPartial<SdkBehavior>): SdkBehavior {\n return deepMerge(\n defaultSdkBehavior() as unknown as Record<string, unknown>,\n overrides as unknown as Record<string, unknown>,\n ) as unknown as SdkBehavior;\n}\n\n/**\n * Self-contained deep merge (no external imports — ir/ is layer 0).\n * Arrays and primitives from `source` replace those in `target`.\n * Objects are merged recursively.\n */\nfunction deepMerge(target: Record<string, unknown>, source: Record<string, unknown>): Record<string, unknown> {\n const result: Record<string, unknown> = { ...target };\n for (const key of Object.keys(source)) {\n const sourceVal = source[key];\n const targetVal = target[key];\n if (sourceVal === undefined) continue;\n if (\n sourceVal !== null &&\n typeof sourceVal === 'object' &&\n !Array.isArray(sourceVal) &&\n targetVal !== null &&\n typeof targetVal === 'object' &&\n !Array.isArray(targetVal)\n ) {\n result[key] = deepMerge(targetVal as Record<string, unknown>, sourceVal as Record<string, unknown>);\n } else {\n result[key] = sourceVal;\n }\n }\n return result;\n}\n","import { readFile } from 'node:fs/promises';\nimport { resolve } from 'node:path';\nimport { pathToFileURL } from 'node:url';\nimport { makeDocumentFromString, bundleDocument, createConfig, BaseResolver, Oas3_1Types } from '@redocly/openapi-core';\nimport { SpecParseError } from '../errors.js';\n\nexport interface BundledSpec {\n parsed: Record<string, unknown>;\n specPath: string;\n}\n\nexport async function loadAndBundleSpec(specPath: string): Promise<BundledSpec> {\n const absolutePath = resolve(specPath);\n const content = await readFile(absolutePath, 'utf-8');\n const document = makeDocumentFromString(content, pathToFileURL(absolutePath).href);\n\n const config = await createConfig({});\n const resolver = new BaseResolver();\n\n const result = await bundleDocument({\n document,\n config,\n types: Oas3_1Types,\n externalRefResolver: resolver,\n dereference: false,\n });\n\n if (result.problems.some((p) => p.severity === 'error')) {\n const errors = result.problems\n .filter((p) => p.severity === 'error')\n .map((p) => p.message)\n .join('\\n');\n throw new SpecParseError(\n `Failed to parse spec: ${errors}`,\n `Check the OpenAPI spec at \"${absolutePath}\" for syntax errors. Run a linter such as \\`npx @redocly/cli lint ${specPath}\\` to identify issues.`,\n );\n }\n\n return {\n parsed: result.bundle.parsed as Record<string, unknown>,\n specPath: absolutePath,\n };\n}\n","import type { Model, Field } from '../ir/types.js';\nimport { toPascalCase, cleanSchemaName, stripListItemMarkers, singularize } from '../utils/naming.js';\nimport type { SchemaObject } from './schemas.js';\nimport { buildFieldFromSchema } from './schemas.js';\n\n/**\n * Qualify an inline model name with the parent schema name.\n * If `parentName` is provided and the field name doesn't already start with\n * the parent, the result is `${parentName}${PascalField}` with the trailing\n * word singularized (e.g., Connection + Domains → ConnectionDomain).\n */\nexport function qualifyInlineModelName(baseName: string, parentName?: string): string {\n if (!parentName) return baseName;\n // Strip ListItem/ByExternalId markers from parent name so inline model names\n // are clean and match the names produced by qualifyNestedName() in responses.ts.\n // e.g., ConnectionListItem + Domains → Connection + Domain = ConnectionDomain\n const cleanParent = stripListItemMarkers(parentName);\n if (baseName.startsWith(cleanParent)) return baseName;\n // Singularize the trailing PascalCase word of the combined name.\n // Split baseName into leading words + trailing word, singularize trailing.\n const trailingMatch = baseName.match(/^(.*?)([A-Z][a-z]*)$/);\n if (trailingMatch) {\n const [, prefix, trailingWord] = trailingMatch;\n const singular = singularize(trailingWord);\n return `${cleanParent}${prefix}${singular}`;\n }\n return `${cleanParent}${baseName}`;\n}\n\n/**\n * Walk all component schemas and extract inline Model definitions for fields\n * that are objects with properties (or arrays of such objects).\n * These correspond to the ModelRef entries created by schemaToTypeRef.\n */\nexport function extractInlineModelsFromSchemas(schemas: Record<string, SchemaObject> | undefined): Model[] {\n if (!schemas) return [];\n\n const inlineModels: Model[] = [];\n\n for (const [schemaName, schema] of Object.entries(schemas)) {\n const parentName = cleanSchemaName(toPascalCase(schemaName));\n extractInlineModelsFromProperties(schema, inlineModels, parentName);\n }\n\n return inlineModels;\n}\n\nfunction extractInlineModelsFromProperties(schema: SchemaObject, results: Model[], parentName?: string): void {\n const properties = schema.properties ?? {};\n const allOfSchemas = schema.allOf ?? [];\n\n for (const sub of allOfSchemas) {\n if (sub.properties) {\n extractInlineModelsFromProperties(sub, results, parentName);\n }\n }\n\n for (const [fieldName, fieldSchema] of Object.entries(properties)) {\n if (!fieldSchema) continue;\n // Direct inline object with properties (with or without explicit type: 'object')\n if (fieldSchema.properties && (fieldSchema.type === 'object' || !fieldSchema.type)) {\n const baseName = toPascalCase(fieldName);\n const modelName = qualifyInlineModelName(baseName, parentName);\n results.push(buildInlineModel(modelName, fieldSchema));\n extractInlineModelsFromProperties(fieldSchema, results, modelName);\n }\n\n // Array of inline objects\n if (fieldSchema.type === 'array' && fieldSchema.items) {\n const items = fieldSchema.items;\n if (items.properties && (items.type === 'object' || !items.type)) {\n const baseName = toPascalCase(fieldName);\n const modelName = qualifyInlineModelName(baseName, parentName);\n results.push(buildInlineModel(modelName, items));\n extractInlineModelsFromProperties(items, results, modelName);\n }\n }\n\n // oneOf containing objects — extract the first non-null variant as a model\n // This handles: totp: { oneOf: [{ type: object, properties: {...} }, { type: 'null' }] }\n if (fieldSchema.oneOf) {\n const objectVariant = fieldSchema.oneOf.find((v) => v.properties && (v.type === 'object' || !v.type));\n if (objectVariant) {\n const baseName = toPascalCase(fieldName);\n const modelName = qualifyInlineModelName(baseName, parentName);\n const existingNames = new Set(results.map((r) => r.name));\n if (!existingNames.has(modelName)) {\n results.push(buildInlineModel(modelName, objectVariant));\n extractInlineModelsFromProperties(objectVariant, results, modelName);\n }\n }\n }\n }\n}\n\nfunction buildInlineModel(name: string, schema: SchemaObject): Model {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n\n for (const [fieldName, fieldSchema] of Object.entries(schema.properties ?? {})) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet));\n }\n\n return { name, description: schema.description, fields };\n}\n","import type { Model, Enum, EnumValue, Field, TypeRef } from '../ir/types.js';\nimport { walkTypeRef } from '../ir/types.js';\nimport { toPascalCase, toUpperSnakeCase, cleanSchemaName, singularize, stripListItemMarkers } from '../utils/naming.js';\n\n/**\n * Module-level transform set during extractSchemas(). Used by schemaToTypeRef()\n * to apply the same name transform to $ref model/enum references.\n */\nlet activeSchemaNameTransform: ((name: string) => string) | null = null;\n\n/** Apply cleanSchemaName + the active transform (if any) to a raw schema name. */\nfunction resolveSchemaName(rawName: string): string {\n let name = cleanSchemaName(toPascalCase(rawName));\n if (activeSchemaNameTransform) name = activeSchemaNameTransform(name);\n return name;\n}\n\nexport interface SchemaExtractionOptions {\n schemaNameTransform?: (name: string) => string;\n}\n\nexport interface SchemaObject {\n type?: string | string[];\n format?: string;\n description?: string;\n properties?: Record<string, SchemaObject | undefined>;\n required?: string[];\n items?: SchemaObject;\n enum?: (string | number)[];\n allOf?: SchemaObject[];\n oneOf?: SchemaObject[];\n anyOf?: SchemaObject[];\n discriminator?: { propertyName: string; mapping?: Record<string, string> };\n readOnly?: boolean;\n writeOnly?: boolean;\n nullable?: boolean;\n $ref?: string;\n additionalProperties?: boolean | SchemaObject;\n const?: unknown;\n patternProperties?: Record<string, SchemaObject>;\n deprecated?: boolean;\n default?: unknown;\n example?: unknown;\n [key: string]: unknown;\n}\n\nexport interface ExtractedSchemas {\n models: Model[];\n enums: Enum[];\n}\n\nexport function extractSchemas(\n schemas: Record<string, SchemaObject> | undefined,\n options?: SchemaExtractionOptions,\n): ExtractedSchemas {\n const enums: Enum[] = [];\n\n if (!schemas) return { models: [], enums };\n\n // Build collision-safe transform if provided\n if (options?.schemaNameTransform) {\n const transform = options.schemaNameTransform;\n const rawNames = Object.keys(schemas);\n const cleanedNames = rawNames.map((n) => cleanSchemaName(toPascalCase(n)));\n const transformedToOriginals = new Map<string, string[]>();\n for (const cleaned of cleanedNames) {\n const transformed = transform(cleaned);\n if (!transformedToOriginals.has(transformed)) transformedToOriginals.set(transformed, []);\n transformedToOriginals.get(transformed)!.push(cleaned);\n }\n const unsafeToTransform = new Set<string>();\n for (const [, originals] of transformedToOriginals) {\n if (originals.length > 1) {\n for (const n of originals) unsafeToTransform.add(n);\n }\n }\n activeSchemaNameTransform = (name: string) => (unsafeToTransform.has(name) ? name : transform(name));\n } else {\n activeSchemaNameTransform = null;\n }\n\n const modelsByCleanName = new Map<string, Model>();\n\n for (const [name, schema] of Object.entries(schemas)) {\n const pascalName = resolveSchemaName(name);\n\n if (schema.enum) {\n enums.push(extractEnum(pascalName, schema));\n } else {\n const model = extractModel(pascalName, schema, schemas);\n const existing = modelsByCleanName.get(pascalName);\n if (existing) {\n // Keep the model with more fields when names collide after cleaning\n if (model.fields.length > existing.fields.length) {\n modelsByCleanName.set(pascalName, model);\n }\n } else {\n modelsByCleanName.set(pascalName, model);\n }\n\n for (const inlineModel of extractDiscriminatedAllOfVariantModels(schema, pascalName)) {\n const existingInline = modelsByCleanName.get(inlineModel.name);\n if (existingInline) {\n if (inlineModel.fields.length > existingInline.fields.length) {\n modelsByCleanName.set(inlineModel.name, inlineModel);\n }\n } else {\n modelsByCleanName.set(inlineModel.name, inlineModel);\n }\n }\n }\n }\n\n const models = [...modelsByCleanName.values()];\n\n // Collect inline models from nested object/oneOf properties\n // that schemaToTypeRef created model refs for but weren't extracted\n const modelNames = new Set(models.map((m) => m.name));\n const inlineQueue: Model[] = [...models];\n while (inlineQueue.length > 0) {\n const model = inlineQueue.pop()!;\n for (const field of model.fields) {\n collectNestedInlineModels(field.type, field.name, model.name, schemas ?? {}, models, modelNames, inlineQueue);\n }\n }\n\n // Collect inline enums from model fields\n for (const model of models) {\n collectInlineEnums(model.fields, enums);\n }\n\n // NOTE: activeSchemaNameTransform is intentionally NOT cleared here.\n // extractOperations() calls schemaToTypeRef() for $ref resolution and\n // needs the same transform active. parseSpec() calls clearSchemaNameTransform()\n // after all extraction is complete.\n return { models, enums };\n}\n\n/** Clear the module-level schemaNameTransform. Called by parseSpec() after all extraction phases. */\nexport function clearSchemaNameTransform(): void {\n activeSchemaNameTransform = null;\n}\n\n/**\n * Walk a single TypeRef and extract inline enum refs as top-level enum definitions.\n * Shared by both schemas.ts (field-level) and parse.ts (model-level) collection passes.\n */\nexport function collectInlineEnumFromRef(ref: TypeRef, enums: Enum[], seen: Set<string>): void {\n walkTypeRef(ref, {\n enum: (r) => {\n if (r.values && !seen.has(r.name)) {\n seen.add(r.name);\n enums.push({\n name: r.name,\n values: r.values.map((v) => ({\n name: toUpperSnakeCase(String(v)),\n value: v,\n description: undefined,\n })),\n });\n }\n },\n });\n}\n\n/**\n * Walk model fields and extract inline enum refs as top-level enum definitions.\n * This ensures type alias files are generated for inline enums.\n */\nfunction collectInlineEnums(fields: Field[], enums: Enum[]): void {\n const seen = new Set(enums.map((e) => e.name));\n for (const field of fields) {\n collectInlineEnumFromRef(field.type, enums, seen);\n }\n}\n\n/**\n * Walk a TypeRef tree and extract inline models for any model refs that point\n * to schemas with inline object properties (not in components/schemas).\n * This handles nested objects like `totp: { oneOf: [{ type: object, properties: {...} }] }`\n * that schemaToTypeRef turns into model refs but aren't extracted from components.\n */\nfunction collectNestedInlineModels(\n ref: TypeRef,\n fieldName: string,\n parentModelName: string,\n schemas: Record<string, SchemaObject>,\n models: Model[],\n modelNames: Set<string>,\n queue: Model[],\n): void {\n walkTypeRef(ref, {\n model: (modelRef) => {\n if (modelNames.has(modelRef.name)) return; // already extracted\n // Check if this model name corresponds to a component schema\n // by checking all possible original names that would map to this PascalCase name\n const isComponent = Object.keys(schemas).some((k) => resolveSchemaName(k) === modelRef.name);\n if (isComponent) return; // will be extracted from components\n\n // This is a reference to a nested inline model that wasn't extracted.\n // Look up the field schema in the parent model's component schema to extract it.\n const parentSchema = findSchemaByName(parentModelName, schemas);\n if (!parentSchema) return;\n\n const fieldSchema = findNestedFieldSchema(fieldName, parentSchema, schemas);\n if (!fieldSchema) return;\n\n // Extract inline models from the field schema\n const extracted = extractNestedSchema(modelRef.name, fieldSchema);\n for (const m of extracted) {\n if (!modelNames.has(m.name)) {\n models.push(m);\n modelNames.add(m.name);\n queue.push(m); // re-scan for deeper nesting\n }\n }\n },\n });\n}\n\n/** Find a component schema by PascalCase name. */\nfunction findSchemaByName(pascalName: string, schemas: Record<string, SchemaObject>): SchemaObject | null {\n for (const [k, v] of Object.entries(schemas)) {\n if (resolveSchemaName(k) === pascalName) return v;\n }\n return null;\n}\n\n/** Walk into a schema to find a field's sub-schema, resolving allOf and oneOf/anyOf. */\nfunction findNestedFieldSchema(\n fieldName: string,\n parentSchema: SchemaObject,\n schemas: Record<string, SchemaObject>,\n): SchemaObject | null {\n if (parentSchema.properties?.[fieldName]) {\n return parentSchema.properties[fieldName]!;\n }\n if (parentSchema.allOf) {\n for (const sub of parentSchema.allOf) {\n let resolved = sub;\n if (sub.$ref) {\n const segments = sub.$ref.split('/');\n const refName = segments[segments.length - 1];\n if (refName && schemas[refName]) resolved = schemas[refName];\n }\n if (resolved.properties?.[fieldName]) {\n return resolved.properties[fieldName]!;\n }\n }\n }\n // Also check inside oneOf/anyOf variants (pure oneOf schemas flatten variant\n // properties into the model, so the field may live inside a variant).\n for (const variant of [...(parentSchema.oneOf ?? []), ...(parentSchema.anyOf ?? [])]) {\n let resolved = variant;\n if (variant.$ref) {\n const segments = variant.$ref.split('/');\n const refName = segments[segments.length - 1];\n if (refName && schemas[refName]) resolved = schemas[refName];\n }\n if (resolved.properties?.[fieldName]) {\n return resolved.properties[fieldName]!;\n }\n }\n return null;\n}\n\n/** Extract a model (and nested models) from an inline field schema. */\nfunction extractNestedSchema(name: string, schema: SchemaObject): Model[] {\n // Handle oneOf: extract each object variant as its own model\n if (schema.oneOf) {\n const models: Model[] = [];\n for (const variant of schema.oneOf) {\n if (variant.$ref) continue;\n if (variant.properties && (variant.type === 'object' || !variant.type)) {\n const requiredSet = new Set(variant.required ?? []);\n const fields: Field[] = [];\n for (const [fn, fs] of Object.entries(variant.properties)) {\n if (!fs) continue;\n fields.push(buildFieldFromSchema(fn, fs, name, requiredSet));\n }\n // Use the name for the first variant, suffix for subsequent\n const variantName = models.length === 0 ? name : `${name}${models.length + 1}`;\n models.push({ name: variantName, description: variant.description, fields });\n }\n }\n return models;\n }\n\n // Handle direct object\n if (schema.properties && (schema.type === 'object' || !schema.type)) {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n for (const [fn, fs] of Object.entries(schema.properties)) {\n if (!fs) continue;\n fields.push(buildFieldFromSchema(fn, fs, name, requiredSet));\n }\n return [{ name, description: schema.description, fields }];\n }\n\n // Handle array with inline items\n if (schema.type === 'array' && schema.items?.properties) {\n const requiredSet = new Set(schema.items.required ?? []);\n const fields: Field[] = [];\n for (const [fn, fs] of Object.entries(schema.items.properties)) {\n if (!fs) continue;\n fields.push(buildFieldFromSchema(fn, fs, name, requiredSet));\n }\n return [{ name, description: schema.items.description, fields }];\n }\n\n return [];\n}\n\n/** Build a single Field from a schema property entry. Shared across all extraction sites. */\nexport function buildFieldFromSchema(\n fieldName: string,\n fieldSchema: SchemaObject,\n contextName: string,\n requiredSet: Set<string>,\n): Field {\n return {\n name: fieldName,\n type: schemaToTypeRef(fieldSchema, fieldName, contextName),\n required: requiredSet.has(fieldName),\n description: fieldSchema.description,\n readOnly: fieldSchema.readOnly || undefined,\n writeOnly: fieldSchema.writeOnly || undefined,\n deprecated: fieldSchema.deprecated || undefined,\n default: fieldSchema.default,\n example: fieldSchema.example,\n };\n}\n\n/**\n * If every non-null oneOf/anyOf variant is a string-valued const, return the\n * list of those const values so the union can collapse into a single enum.\n * Returns null when any variant isn't a pure string-const (model ref,\n * number const, nullable, etc.).\n */\nfunction collectLiteralStringConsts(variants: SchemaObject[]): string[] | null {\n if (variants.length === 0) return null;\n const values: string[] = [];\n for (const v of variants) {\n // A single-element enum is semantically identical to const.\n if (typeof v.const === 'string') {\n values.push(v.const);\n continue;\n }\n if (Array.isArray(v.enum) && v.enum.length === 1 && typeof v.enum[0] === 'string') {\n values.push(v.enum[0]);\n continue;\n }\n return null;\n }\n return values;\n}\n\n/** Build an EnumRef the same way the regular enum path does for naming. */\nfunction buildSyntheticEnumRef(\n values: string[],\n contextName: string | undefined,\n parentModelName: string | undefined,\n): TypeRef {\n const baseName = toPascalCase(contextName ?? 'UnknownEnum');\n const cleanParent = parentModelName ? stripListItemMarkers(parentModelName) : undefined;\n const qualifiedName = cleanParent && !baseName.startsWith(cleanParent) ? `${cleanParent}${baseName}` : baseName;\n return { kind: 'enum', name: qualifiedName, values };\n}\n\n/**\n * Detect an implicit discriminator on an oneOf where every variant is an\n * object schema that pins the same property to a const value. Returns\n * { property, mapping } so the IR can represent the union as discriminated\n * without needing an explicit `discriminator:` key in the spec.\n *\n * Both shapes are supported:\n * { properties: { event: { const: \"x\" } }, required: [\"event\"] }\n * { properties: { event: { type: \"string\", enum: [\"x\"] } } }\n *\n * Returns null when any variant doesn't fit the pattern or when variants\n * disagree on which property carries the discriminator.\n */\nfunction detectConstPropertyDiscriminator(\n variants: SchemaObject[],\n): { property: string; mapping: Record<string, string> } | null {\n if (variants.length < 2) return null;\n\n // Find properties whose const value is present on every variant.\n let candidateProperty: string | null = null;\n const candidates = Object.keys(variants[0]?.properties ?? {});\n for (const propName of candidates) {\n if (variants.every((v) => getConstPropertyValue(v, propName) !== null)) {\n candidateProperty = propName;\n break;\n }\n }\n\n if (!candidateProperty) return null;\n\n const mapping: Record<string, string> = {};\n for (const v of variants) {\n const value = getConstPropertyValue(v, candidateProperty);\n if (value === null) return null;\n // Require a $ref or title so we have a concrete model name to map to.\n const variantName = resolveVariantModelName(v);\n if (!variantName) return null;\n mapping[value] = variantName;\n }\n\n return { property: candidateProperty, mapping };\n}\n\nfunction getConstPropertyValue(schema: SchemaObject, property: string): string | null {\n const prop = schema.properties?.[property];\n if (!prop) return null;\n if (typeof prop.const === 'string') return prop.const;\n if (Array.isArray(prop.enum) && prop.enum.length === 1 && typeof prop.enum[0] === 'string') {\n return prop.enum[0];\n }\n return null;\n}\n\nfunction resolveVariantModelName(schema: SchemaObject): string | null {\n if (schema.$ref) {\n return resolveSchemaName(schema.$ref.replace(/^#\\/components\\/schemas\\//, ''));\n }\n const title = typeof schema['title'] === 'string' ? (schema['title'] as string) : null;\n if (title) return resolveSchemaName(title);\n return null;\n}\n\nfunction extractEnum(name: string, schema: SchemaObject): Enum {\n const values: EnumValue[] = (schema.enum ?? []).map((v) => ({\n name: toUpperSnakeCase(String(v)),\n value: typeof v === 'number' ? v : String(v),\n description: undefined,\n }));\n\n return { name, values };\n}\nfunction extractModel(name: string, schema: SchemaObject, schemas?: Record<string, SchemaObject>): Model {\n if (schema.allOf) {\n return extractAllOfModel(name, schema, schemas);\n }\n\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n\n for (const [fieldName, fieldSchema] of Object.entries(schema.properties ?? {})) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet));\n }\n\n // Pure oneOf/anyOf schemas (no allOf, no properties): merge variant fields\n // as optional. This handles schemas like UpdateOrganizationMembership which\n // is a oneOf with mutually exclusive field groups (role_slug vs role_slugs).\n if (fields.length === 0 && (schema.oneOf || schema.anyOf)) {\n const variants = schema.oneOf ?? schema.anyOf ?? [];\n const emptyRequired = new Set<string>();\n const seenFieldNames = new Set<string>();\n for (const variant of variants) {\n if (!variant.properties) continue;\n for (const [fieldName, fieldSchema] of Object.entries(variant.properties)) {\n if (!fieldSchema || seenFieldNames.has(fieldName)) continue;\n seenFieldNames.add(fieldName);\n fields.push(buildFieldFromSchema(fieldName, fieldSchema as SchemaObject, name, emptyRequired));\n }\n }\n }\n\n // When additionalProperties is an object schema alongside properties,\n // surface it as a catch-all map field so emitters can generate Map<string, T>.\n if (schema.additionalProperties && typeof schema.additionalProperties === 'object' && schema.properties) {\n const apKeys = Object.keys(schema.additionalProperties);\n if (apKeys.length > 0) {\n const valueType = schemaToTypeRef(schema.additionalProperties as SchemaObject, 'additionalProperties', name);\n fields.push({\n name: 'additionalProperties',\n type: { kind: 'map', valueType },\n required: false,\n description: 'Additional properties not captured by named fields',\n });\n }\n }\n\n return { name, description: schema.description, fields };\n}\n\nfunction extractAllOfModel(name: string, schema: SchemaObject, schemas?: Record<string, SchemaObject>): Model {\n const fields: Field[] = [];\n const requiredSet = new Set<string>();\n let resultDiscriminator: { property: string; mapping: Record<string, string> } | undefined;\n\n for (const subSchema of schema.allOf ?? []) {\n // Resolve $ref sub-schemas by looking up the referenced component schema\n let resolved = subSchema;\n if (subSchema.$ref && schemas) {\n const segments = subSchema.$ref.split('/');\n const refName = segments[segments.length - 1];\n if (refName && schemas[refName]) {\n resolved = schemas[refName];\n }\n }\n\n // If the resolved schema is itself an allOf, recursively extract its fields\n if (resolved.allOf) {\n const nested = extractAllOfModel(name, resolved, schemas);\n for (const f of nested.fields) {\n fields.push({ ...f, required: false }); // will be re-set below\n if (f.required) requiredSet.add(f.name);\n }\n } else if (resolved.oneOf || resolved.anyOf) {\n const variants = resolved.oneOf ?? resolved.anyOf ?? [];\n // Detect discriminated union: every variant pins the same property to a\n // distinct const value (e.g. EventSchema where each variant has event: const).\n // When detected, store the discriminator instead of flattening variant fields —\n // the base allOf schema already captures the common fields.\n const discriminatorInfo = detectAllOfVariantDiscriminator(variants, name);\n if (discriminatorInfo) {\n resultDiscriminator = discriminatorInfo;\n } else {\n // Flatten oneOf/anyOf variant fields into the parent model as optional\n // fields. This handles the common allOf + oneOf pattern where the spec\n // uses mutually exclusive variant groups (e.g. password vs password_hash).\n const emptyRequired = new Set<string>();\n const seenFieldNames = new Set(fields.map((f) => f.name));\n for (const variant of variants) {\n if (!variant.properties) continue;\n for (const [fieldName, fieldSchema] of Object.entries(variant.properties)) {\n if (!fieldSchema || seenFieldNames.has(fieldName)) continue;\n seenFieldNames.add(fieldName);\n fields.push(buildFieldFromSchema(fieldName, fieldSchema as SchemaObject, name, emptyRequired));\n }\n }\n // Do NOT add variant-level required to the requiredSet — these fields\n // are optional at the parent level because they come from mutually\n // exclusive branches.\n }\n } else {\n if (resolved.required) {\n for (const r of resolved.required) requiredSet.add(r);\n }\n if (resolved.properties) {\n // Use an empty requiredSet — required flags are set in the final pass below\n const emptyRequired = new Set<string>();\n for (const [fieldName, fieldSchema] of Object.entries(resolved.properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, emptyRequired));\n }\n }\n }\n }\n\n // Also collect required from the outer schema\n if (schema.required) {\n for (const r of schema.required) requiredSet.add(r);\n }\n\n // Set required flags\n for (const f of fields) {\n f.required = requiredSet.has(f.name);\n }\n\n return {\n name,\n description: schema.description,\n fields,\n ...(resultDiscriminator ? { discriminator: resultDiscriminator } : {}),\n };\n}\n\n/**\n * Detect an implicit discriminator on an allOf+oneOf where every variant is an\n * object that pins the same property to a distinct const value. Unlike\n * detectConstPropertyDiscriminator (which requires $ref or title for variant\n * model names), this version derives model names from the const value itself\n * using deriveDiscriminatedVariantName — matching how extractDiscriminatedAllOfVariantModels\n * names those models.\n *\n * Returns null when no discriminator can be reliably detected.\n */\nfunction detectAllOfVariantDiscriminator(\n variants: SchemaObject[],\n fallbackName: string,\n): { property: string; mapping: Record<string, string> } | null {\n if (variants.length < 2) return null;\n\n // Find a property whose const value is present on every variant\n const candidates = Object.keys(variants[0]?.properties ?? {});\n let candidateProperty: string | null = null;\n for (const propName of candidates) {\n if (variants.every((v) => getConstPropertyValue(v, propName) !== null)) {\n candidateProperty = propName;\n break;\n }\n }\n if (!candidateProperty) return null;\n\n const mapping: Record<string, string> = {};\n const seenModelNames = new Set<string>();\n for (const v of variants) {\n const value = getConstPropertyValue(v, candidateProperty);\n if (value === null) return null;\n const modelName = deriveDiscriminatedVariantName(v, fallbackName);\n // If two variants map to the same model name, the discriminator is ambiguous\n if (seenModelNames.has(modelName)) return null;\n seenModelNames.add(modelName);\n mapping[value] = modelName;\n }\n\n return { property: candidateProperty, mapping };\n}\n\nfunction extractDiscriminatedAllOfVariantModels(schema: SchemaObject, fallbackName: string): Model[] {\n const models: Model[] = [];\n const seenNames = new Set<string>();\n\n for (const subSchema of schema.allOf ?? []) {\n for (const variant of subSchema.oneOf ?? []) {\n if (!variant.properties || (variant.type !== undefined && variant.type !== 'object')) continue;\n\n const variantName = deriveDiscriminatedVariantName(variant, fallbackName);\n for (const model of extractInlineModelDeep(variantName, variant)) {\n if (seenNames.has(model.name)) continue;\n seenNames.add(model.name);\n models.push(model);\n }\n }\n }\n\n return models;\n}\n\nfunction deriveDiscriminatedVariantName(schema: SchemaObject, fallbackName: string): string {\n if (!schema.properties) return fallbackName;\n\n const preferred = ['event', 'type', 'object'];\n for (const name of preferred) {\n const field = schema.properties[name];\n if (!field) continue;\n if (typeof field.const === 'string') {\n return toPascalCase(field.const);\n }\n if (field.enum && field.enum.length === 1 && typeof field.enum[0] === 'string') {\n return toPascalCase(field.enum[0]);\n }\n }\n\n for (const field of Object.values(schema.properties)) {\n if (!field) continue;\n if (typeof field.const === 'string') {\n return toPascalCase(field.const);\n }\n if (field.enum && field.enum.length === 1 && typeof field.enum[0] === 'string') {\n return toPascalCase(field.enum[0]);\n }\n }\n\n return fallbackName;\n}\n\nfunction extractInlineModelDeep(name: string, schema: SchemaObject): Model[] {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n const properties = schema.properties ?? {};\n const nestedModels: Model[] = [];\n\n for (const [fieldName, fieldSchema] of Object.entries(properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet));\n\n if (fieldSchema.type === 'object' && fieldSchema.properties) {\n nestedModels.push(...extractInlineModelDeep(qualifyNestedInlineName(name, fieldName), fieldSchema));\n }\n\n if (fieldSchema.type === 'array' && fieldSchema.items?.properties) {\n nestedModels.push(...extractInlineModelDeep(qualifyNestedInlineName(name, fieldName), fieldSchema.items));\n }\n\n if (fieldSchema.allOf) {\n const mergedProperties: Record<string, SchemaObject | undefined> = {};\n const mergedRequired: string[] = [];\n for (const sub of fieldSchema.allOf) {\n if (sub.properties) Object.assign(mergedProperties, sub.properties);\n if (sub.required) mergedRequired.push(...sub.required);\n }\n if (Object.keys(mergedProperties).length > 0) {\n nestedModels.push(\n ...extractInlineModelDeep(qualifyNestedInlineName(name, fieldName), {\n type: 'object',\n properties: mergedProperties,\n required: mergedRequired,\n }),\n );\n }\n }\n\n if (fieldSchema.oneOf) {\n const objectVariant = fieldSchema.oneOf.find((v) => v.properties && (v.type === 'object' || !v.type));\n if (objectVariant) {\n nestedModels.push(...extractInlineModelDeep(qualifyNestedInlineName(name, fieldName), objectVariant));\n }\n }\n }\n\n return [{ name, description: schema.description, fields }, ...nestedModels];\n}\n\nfunction qualifyNestedInlineName(parentName: string, fieldName: string): string {\n const pascalField = toPascalCase(fieldName);\n if (pascalField.startsWith(parentName)) return pascalField;\n\n const cleanParent = stripListItemMarkers(parentName);\n const qualified = `${cleanParent}${pascalField}`;\n const match = qualified.match(/^(.+?)([A-Z][a-z]+s?)$/);\n if (match && match[2]) {\n return match[1] + singularize(match[2]);\n }\n return qualified;\n}\n\nexport function schemaToTypeRef(schema: SchemaObject, contextName?: string, parentModelName?: string): TypeRef {\n // Handle $ref → ModelRef\n if (schema.$ref) {\n const segments = schema.$ref.split('/');\n const rawName = segments[segments.length - 1];\n return { kind: 'model', name: resolveSchemaName(rawName) };\n }\n\n // Handle OAS 3.1 nullable type arrays: type: [string, null]\n if (Array.isArray(schema.type)) {\n const nonNullTypes = schema.type.filter((t: string) => t !== 'null');\n // type: ['null'] — only null, no real type\n if (nonNullTypes.length === 0) {\n return { kind: 'nullable', inner: { kind: 'primitive', type: 'unknown' } };\n }\n if (schema.type.includes('null') && nonNullTypes.length === 1) {\n return {\n kind: 'nullable',\n inner: schemaToTypeRef({ ...schema, type: nonNullTypes[0], nullable: false }, contextName),\n };\n }\n // Multiple non-null types → union\n if (nonNullTypes.length > 1) {\n const variants = nonNullTypes.map((t: string) => schemaToTypeRef({ ...schema, type: t }, contextName));\n const ref: TypeRef = { kind: 'union', variants };\n if (schema.type.includes('null')) {\n return { kind: 'nullable', inner: ref };\n }\n return ref;\n }\n }\n\n // Handle OAS 3.0 nullable flag\n if (schema.nullable && schema.type) {\n return {\n kind: 'nullable',\n inner: schemaToTypeRef({ ...schema, nullable: false }, contextName),\n };\n }\n\n // Handle allOf — merge properties from all sub-schemas.\n // This handles patterns like: allOf: [{ type: object, properties: {...} }, { oneOf: [...] }]\n // which are valid OAS 3.1 but weren't handled for field-level schemas.\n if (schema.allOf) {\n // If allOf contains a $ref, prefer the ref (it's a named type)\n const refItem = schema.allOf.find((s: SchemaObject) => s.$ref);\n if (refItem) {\n // If allOf has $ref AND siblings with properties, return a merged model ref\n // to avoid losing the augmentation properties\n const hasAugmentation = schema.allOf.some((s: SchemaObject) => !s.$ref && (s.properties || s.type === 'object'));\n if (hasAugmentation) {\n const baseName = toPascalCase(contextName ?? 'UnknownModel');\n return { kind: 'model', name: qualifyInlineModelName(baseName, parentModelName) };\n }\n return schemaToTypeRef(refItem, contextName, parentModelName);\n }\n // If allOf has a single item, unwrap it\n if (schema.allOf.length === 1) {\n return schemaToTypeRef(schema.allOf[0], contextName, parentModelName);\n }\n // If allOf items all have properties, treat as a merged model\n const hasProperties = schema.allOf.some((s: SchemaObject) => s.properties);\n if (hasProperties) {\n const baseName = toPascalCase(contextName ?? 'UnknownModel');\n return {\n kind: 'model',\n name: qualifyInlineModelName(baseName, parentModelName),\n };\n }\n // Fall through to other checks\n }\n\n // Handle oneOf / anyOf → Union or Nullable\n // Valid OAS 3.1: properties can have { oneOf: [{ type: object }, { type: 'null' }] }\n // without a wrapping `type` field.\n if (schema.oneOf || schema.anyOf) {\n const compositionKind: 'oneOf' | 'anyOf' = schema.oneOf ? 'oneOf' : 'anyOf';\n const rawVariants: SchemaObject[] = schema.oneOf ?? schema.anyOf ?? [];\n\n // Check for nullable pattern: oneOf: [realType, { type: 'null' }]\n const nullVariant = rawVariants.find(\n (v: SchemaObject) => v.type === 'null' || (Array.isArray(v.type) && v.type.length === 1 && v.type[0] === 'null'),\n );\n const nonNullVariants = rawVariants.filter((v) => v !== nullVariant);\n\n if (nullVariant && nonNullVariants.length === 1) {\n // Nullable single type — unwrap as nullable\n return {\n kind: 'nullable',\n inner: schemaToTypeRef(nonNullVariants[0], contextName, parentModelName),\n };\n }\n\n // Collapse an oneOf/anyOf whose non-null variants are all string-const\n // schemas into a single enum. This turns patterns like\n // provider: { oneOf: [{ const: \"AppleOAuth\" }, { const: \"GitHubOAuth\" }, ...] }\n // into a proper enum type with one member per variant instead of a\n // structurally-opaque union of literal refs.\n const literalStrings = collectLiteralStringConsts(nonNullVariants);\n if (literalStrings !== null && literalStrings.length >= 2) {\n const enumRef = buildSyntheticEnumRef(literalStrings, contextName, parentModelName);\n return nullVariant ? { kind: 'nullable', inner: enumRef } : enumRef;\n }\n\n // Synthesize a discriminator when all non-null variants are objects that\n // share a property whose schema carries a `const` value. Covers the\n // EventSchema-style pattern where each oneOf variant pins `event:\n // const: \"...\"` instead of the spec using an explicit `discriminator:`.\n const syntheticDiscriminator =\n !schema.discriminator && compositionKind === 'oneOf' ? detectConstPropertyDiscriminator(nonNullVariants) : null;\n\n // General union\n const variants = rawVariants\n .filter((v: SchemaObject) => v.type !== 'null')\n .map((v: SchemaObject) => schemaToTypeRef(v, contextName, parentModelName));\n const hasNull = !!nullVariant;\n const union: TypeRef = {\n kind: 'union',\n variants,\n compositionKind,\n ...(schema.discriminator\n ? {\n discriminator: {\n property: schema.discriminator.propertyName,\n mapping: Object.fromEntries(\n Object.entries(schema.discriminator.mapping ?? {}).map(([k, v]) => [\n k,\n v.replace(/^#\\/components\\/schemas\\//, ''),\n ]),\n ),\n },\n }\n : syntheticDiscriminator\n ? { discriminator: syntheticDiscriminator }\n : {}),\n };\n return hasNull ? { kind: 'nullable', inner: union } : union;\n }\n\n // Handle const → LiteralType (supports string, number, boolean)\n if (schema.const !== undefined) {\n if (typeof schema.const === 'string' || typeof schema.const === 'number' || typeof schema.const === 'boolean') {\n return { kind: 'literal', value: schema.const };\n }\n // null const → nullable unknown\n if (schema.const === null) {\n return { kind: 'nullable', inner: { kind: 'primitive', type: 'unknown' } };\n }\n // const of object/array → map or array with unknown values\n if (typeof schema.const === 'object') {\n if (Array.isArray(schema.const)) {\n return { kind: 'array', items: { kind: 'primitive', type: 'unknown' } };\n }\n return { kind: 'map', valueType: { kind: 'primitive', type: 'unknown' } };\n }\n }\n if (schema.enum && schema.enum.length === 1) {\n const v = schema.enum[0];\n return { kind: 'literal', value: typeof v === 'number' ? v : String(v) };\n }\n\n // Handle enum\n if (schema.enum) {\n const baseName = toPascalCase(contextName ?? 'UnknownEnum');\n // Strip ListItem/ByExternalId markers from parent name so enum names are clean:\n // e.g., DirectoryListItem + State → Directory + State = DirectoryState\n const cleanParent = parentModelName ? stripListItemMarkers(parentModelName) : undefined;\n // Avoid redundant prefix: Connection + ConnectionType → ConnectionType\n const qualifiedName = cleanParent && !baseName.startsWith(cleanParent) ? `${cleanParent}${baseName}` : baseName;\n return {\n kind: 'enum',\n name: qualifiedName,\n values: schema.enum.map((v) => (typeof v === 'number' ? v : String(v))),\n };\n }\n\n // Handle array — pass parentModelName through to qualify inline items\n if (schema.type === 'array' && schema.items) {\n return {\n kind: 'array',\n items: schemaToTypeRef(schema.items, contextName, parentModelName),\n };\n }\n // Handle array without explicit type but with items (valid OAS 3.1)\n if (!schema.type && schema.items) {\n return {\n kind: 'array',\n items: schemaToTypeRef(schema.items, contextName, parentModelName),\n };\n }\n\n // Handle object → ModelRef (if it has properties, it's a named model reference)\n // When additionalProperties is also present, we still return a ModelRef so the\n // named properties are preserved. The extractModel path will pick up the extra\n // properties as a catch-all map field named `additionalProperties`.\n if (schema.type === 'object' && schema.properties) {\n const baseName = toPascalCase(contextName ?? 'UnknownModel');\n return {\n kind: 'model',\n name: qualifyInlineModelName(baseName, parentModelName),\n };\n }\n\n // Handle freeform object with additionalProperties or patternProperties → Map<string, T>\n if (schema.type === 'object' && !schema.properties) {\n let valueType: TypeRef = { kind: 'primitive', type: 'unknown' };\n if (schema.additionalProperties && typeof schema.additionalProperties === 'object') {\n // Empty additionalProperties ({}) means \"any value\" — keep as unknown\n const apKeys = Object.keys(schema.additionalProperties);\n if (apKeys.length > 0) {\n valueType = schemaToTypeRef(schema.additionalProperties as SchemaObject, contextName);\n }\n } else if (schema.patternProperties) {\n // patternProperties: { \"pattern\": schema } → use the first pattern's schema as value type\n const patterns = Object.values(schema.patternProperties);\n if (patterns.length > 0) {\n valueType = schemaToTypeRef(patterns[0], contextName);\n }\n }\n return {\n kind: 'map',\n valueType,\n };\n }\n\n // Handle primitives\n const primitiveMap: Record<string, 'string' | 'integer' | 'number' | 'boolean'> = {\n string: 'string',\n integer: 'integer',\n number: 'number',\n boolean: 'boolean',\n };\n\n const typeStr = Array.isArray(schema.type) ? schema.type[0] : schema.type;\n if (typeStr && primitiveMap[typeStr]) {\n return {\n kind: 'primitive',\n type: primitiveMap[typeStr],\n ...(schema.format ? { format: schema.format } : {}),\n };\n }\n\n // Handle schemas with no type — if it has properties, treat as model\n if (!schema.type && schema.properties) {\n const baseName = toPascalCase(contextName ?? 'UnknownModel');\n return {\n kind: 'model',\n name: qualifyInlineModelName(baseName, parentModelName),\n };\n }\n\n // Empty schema {} → unknown\n if (\n !schema.type &&\n !schema.$ref &&\n !schema.oneOf &&\n !schema.anyOf &&\n !schema.allOf &&\n !schema.enum &&\n !schema.properties &&\n !schema.items\n ) {\n return { kind: 'primitive', type: 'unknown' };\n }\n\n // Fallback: treat unknown schemas as unknown\n if (contextName) {\n console.warn(`[oagen] Warning: Unknown schema shape treated as unknown (context: ${contextName})`);\n }\n return { kind: 'primitive', type: 'unknown' };\n}\n\nimport { qualifyInlineModelName } from './inline-models.js';\n\nexport { qualifyInlineModelName, extractInlineModelsFromSchemas } from './inline-models.js';\n","import type { TypeRef, Parameter, PaginationMeta } from '../ir/types.js';\n\nconst CURSOR_PARAMS = ['cursor', 'after', 'before', 'starting_after', 'ending_before', 'page_token', 'next_token'];\n\nconst OFFSET_PARAMS = ['offset', 'page', 'page_number', 'skip'];\nconst LIMIT_PARAMS = ['limit', 'page_size', 'per_page', 'size', 'count'];\n\n/**\n * Detect if an operation uses pagination and return structured metadata\n * for auto-paging iterator generation.\n *\n * Supports two strategies:\n * 1. **Cursor-based**: query params include a cursor-like parameter\n * 2. **Offset-based**: query params include both an offset-like and limit-like parameter\n *\n * Returns null if no pagination pattern is detected.\n */\nexport function detectPagination(\n response: TypeRef,\n queryParams: Parameter[],\n dataPath?: string,\n): PaginationMeta | null {\n // Try cursor-based first (preferred)\n const cursorParam = queryParams.find((p) => CURSOR_PARAMS.includes(p.name));\n\n if (cursorParam) {\n const itemType: TypeRef = response.kind === 'array' ? response.items : response;\n return {\n strategy: 'cursor',\n param: cursorParam.name,\n dataPath: dataPath,\n itemType,\n };\n }\n\n // Try offset-based pagination\n const offsetParam = queryParams.find((p) => OFFSET_PARAMS.includes(p.name));\n const limitParam = queryParams.find((p) => LIMIT_PARAMS.includes(p.name));\n\n if (offsetParam && limitParam) {\n const itemType: TypeRef = response.kind === 'array' ? response.items : response;\n return {\n strategy: 'offset',\n param: offsetParam.name,\n limitParam: limitParam.name,\n dataPath: dataPath,\n itemType,\n };\n }\n\n return null;\n}\n","import type { TypeRef, Model, Field } from '../ir/types.js';\nimport { toPascalCase, singularize, stripListItemMarkers } from '../utils/naming.js';\nimport type { SchemaObject } from './schemas.js';\nimport { schemaToTypeRef, buildFieldFromSchema } from './schemas.js';\n\nexport interface ResponseExtractionResult {\n /** The TypeRef to use as the operation's response type */\n response: TypeRef;\n /** Any inline models discovered during extraction (to merge into ir.models) */\n inlineModels: Model[];\n /** Whether this response indicates a paginated list */\n isPaginated: boolean;\n /** Path to the data array within the response envelope (e.g., 'data') */\n dataPath?: string;\n /** TypeRef of individual items in a paginated list */\n itemType?: TypeRef;\n}\n\nexport function classifyAndExtractResponse(schema: SchemaObject, contextName: string): ResponseExtractionResult {\n // 1. If schema is a $ref, resolve to model name (Phase 1)\n if (schema.$ref) {\n return { response: schemaToTypeRef(schema, contextName), inlineModels: [], isPaginated: false };\n }\n\n // 2. Check for list envelope (structural detection: array prop + non-array companion)\n const envelope = detectListEnvelope(schema);\n if (envelope.isEnvelope) {\n return extractListResponse(schema, contextName, envelope.dataPath!);\n }\n\n // 3. Check for single-resource wrapper ({ resource_name: { object: \"...\", ... } })\n if (isSingleResourceWrapper(schema)) {\n return extractWrappedResource(schema, contextName);\n }\n\n // 4. Direct resource or plain inline object\n return extractDirectResource(schema, contextName);\n}\n\ninterface ListEnvelopeResult {\n isEnvelope: boolean;\n dataPath: string | null;\n}\n\nconst KNOWN_DATA_PATHS = new Set(['data', 'items', 'results', 'records', 'entries', 'values', 'nodes', 'edges']);\n\nconst PAGINATION_METADATA_PATTERNS = [\n 'meta',\n 'metadata',\n 'pagination',\n 'cursor',\n 'has_more',\n 'page_info',\n 'total',\n 'next_page',\n 'previous_page',\n 'offset',\n];\n\nfunction detectListEnvelope(schema: SchemaObject): ListEnvelopeResult {\n // Collect all property sources (allOf sub-schemas or flat schema)\n const propSources: Record<string, SchemaObject | undefined>[] = [];\n if (schema.allOf) {\n for (const sub of schema.allOf) {\n if (sub.properties) propSources.push(sub.properties);\n }\n }\n if (schema.properties) {\n propSources.push(schema.properties);\n }\n\n if (propSources.length === 0) return { isEnvelope: false, dataPath: null };\n\n // Merge all properties into a single view\n const mergedProps: Record<string, SchemaObject | undefined> = {};\n for (const source of propSources) {\n Object.assign(mergedProps, source);\n }\n\n // Find array-typed properties and non-array companion properties\n const arrayProps: string[] = [];\n const nonArrayKeys: string[] = [];\n\n for (const [key, propSchema] of Object.entries(mergedProps)) {\n if (!propSchema) continue;\n if (propSchema.type === 'array') {\n arrayProps.push(key);\n } else {\n nonArrayKeys.push(key);\n }\n }\n\n // List envelope heuristic: exactly one array property + at least one non-array companion\n // that looks like pagination metadata. A `data` array alone (e.g. with only an\n // `object` discriminant companion) is NOT sufficient — the companion must indicate\n // actual pagination (cursor, metadata, total, etc.).\n if (arrayProps.length === 1 && nonArrayKeys.length >= 1) {\n const arrayPropName = arrayProps[0];\n\n const hasPaginationCompanion = nonArrayKeys.some((key) =>\n PAGINATION_METADATA_PATTERNS.some((pattern) => key.toLowerCase().includes(pattern)),\n );\n\n if (KNOWN_DATA_PATHS.has(arrayPropName) && hasPaginationCompanion) {\n return { isEnvelope: true, dataPath: arrayPropName };\n }\n\n // Non-standard array property name — still treat as envelope if pagination companion exists\n if (hasPaginationCompanion) {\n return { isEnvelope: true, dataPath: arrayPropName };\n }\n }\n\n return { isEnvelope: false, dataPath: null };\n}\n\nfunction extractListResponse(schema: SchemaObject, contextName: string, dataPath: string): ResponseExtractionResult {\n let itemTypeRef: TypeRef = { kind: 'primitive', type: 'string' };\n const inlineModels: Model[] = [];\n\n // Collect all property sources (allOf sub-schemas or flat schema)\n const propSources: Record<string, SchemaObject | undefined>[] = [];\n if (schema.allOf) {\n for (const sub of schema.allOf) {\n if (sub.properties) propSources.push(sub.properties);\n }\n }\n if (schema.properties) {\n propSources.push(schema.properties);\n }\n\n for (const props of propSources) {\n const dataProp = props[dataPath];\n if (!dataProp) continue;\n\n if (dataProp.type === 'array' && dataProp.items) {\n const items = dataProp.items;\n if (items.$ref) {\n itemTypeRef = schemaToTypeRef(items, contextName);\n } else if (items.type === 'object' && items.properties) {\n const itemName = contextName.replace(/Response$/, '') + 'Item';\n itemTypeRef = { kind: 'model', name: itemName };\n inlineModels.push(...extractInlineModel(itemName, items));\n }\n }\n }\n\n return {\n response: { kind: 'array', items: itemTypeRef },\n inlineModels,\n isPaginated: true,\n dataPath,\n itemType: itemTypeRef,\n };\n}\n\nfunction hasDiscriminantConstField(schema: SchemaObject): { property: string; value: string } | null {\n if (!schema.properties) return null;\n\n // Prefer well-known discriminant properties for backward compatibility\n const preferred = ['object', 'type'];\n for (const name of preferred) {\n const field = schema.properties[name];\n if (!field) continue;\n if (field.const !== undefined && typeof field.const === 'string') {\n return { property: name, value: field.const };\n }\n if (field.enum && field.enum.length === 1 && typeof field.enum[0] === 'string') {\n return { property: name, value: field.enum[0] };\n }\n }\n\n // Fall back to any property with a const or single-value enum\n for (const [name, field] of Object.entries(schema.properties)) {\n if (!field) continue;\n if (field.const !== undefined && typeof field.const === 'string') {\n return { property: name, value: field.const };\n }\n if (field.enum && field.enum.length === 1 && typeof field.enum[0] === 'string') {\n return { property: name, value: field.enum[0] };\n }\n }\n\n return null;\n}\n\nfunction isSingleResourceWrapper(schema: SchemaObject): boolean {\n if (schema.type !== 'object') return false;\n if (!schema.properties) return false;\n\n // Find the wrapper property: use required[0] if available, or the single property key\n let wrapperKey: string | undefined;\n if (schema.required && schema.required.length === 1) {\n wrapperKey = schema.required[0];\n } else {\n const propKeys = Object.keys(schema.properties);\n if (propKeys.length === 1) {\n wrapperKey = propKeys[0];\n }\n }\n if (!wrapperKey) return false;\n\n const propSchema = schema.properties[wrapperKey];\n if (!propSchema) return false;\n\n // Direct object with a discriminant const field\n if (propSchema.type === 'object' && hasDiscriminantConstField(propSchema) !== null) return true;\n\n // oneOf with object + null (nullable resource)\n if (propSchema.oneOf) {\n return propSchema.oneOf.some((v) => v.type === 'object' && hasDiscriminantConstField(v) !== null);\n }\n\n return false;\n}\n\nfunction extractWrappedResource(schema: SchemaObject, contextName: string): ResponseExtractionResult {\n const props = schema.properties!;\n const wrapperKey = schema.required && schema.required.length === 1 ? schema.required[0] : Object.keys(props)[0];\n const propSchema = props[wrapperKey]!;\n const inlineModels: Model[] = [];\n\n // Derive model name from the object const value or wrapper property name\n const resourceName = contextName.replace(/Response$/, '');\n\n if (propSchema.oneOf) {\n const objectVariant = propSchema.oneOf.find((v) => v.type === 'object' && hasDiscriminantConstField(v) !== null);\n\n if (objectVariant) {\n const modelName = deriveModelName(objectVariant, resourceName);\n inlineModels.push(...extractInlineModel(modelName, objectVariant));\n\n const hasNullVariant = propSchema.oneOf.some(\n (v) => v.type === 'null' || (Array.isArray(v.type) && v.type.includes('null')),\n );\n\n const modelRef: TypeRef = { kind: 'model', name: modelName };\n return {\n response: hasNullVariant ? { kind: 'nullable', inner: modelRef } : modelRef,\n inlineModels,\n isPaginated: false,\n };\n }\n }\n\n // Direct object\n const modelName = deriveModelName(propSchema, resourceName);\n inlineModels.push(...extractInlineModel(modelName, propSchema));\n\n return {\n response: { kind: 'model', name: modelName },\n inlineModels,\n isPaginated: false,\n };\n}\n\nfunction extractDirectResource(schema: SchemaObject, contextName: string): ResponseExtractionResult {\n const inlineModels: Model[] = [];\n\n // Direct object with properties (with or without explicit type: 'object')\n if (schema.properties && (schema.type === 'object' || !schema.type)) {\n const modelName = deriveModelName(schema, contextName);\n inlineModels.push(...extractInlineModel(modelName, schema));\n return {\n response: { kind: 'model', name: modelName },\n inlineModels,\n isPaginated: false,\n };\n }\n\n // allOf with properties — merge into a single model\n if (schema.allOf) {\n const mergedProperties: Record<string, SchemaObject | undefined> = {};\n const mergedRequired: string[] = [];\n for (const sub of schema.allOf) {\n if (sub.properties) {\n Object.assign(mergedProperties, sub.properties);\n }\n if (sub.required) {\n mergedRequired.push(...sub.required);\n }\n }\n if (Object.keys(mergedProperties).length > 0) {\n const merged: SchemaObject = { type: 'object', properties: mergedProperties, required: mergedRequired };\n const modelName = deriveModelName(merged, contextName);\n inlineModels.push(...extractInlineModel(modelName, merged));\n return {\n response: { kind: 'model', name: modelName },\n inlineModels,\n isPaginated: false,\n };\n }\n }\n\n // oneOf — delegate to schemaToTypeRef (returns union) but also extract inline models\n // from object variants so the model refs resolve\n if (schema.oneOf) {\n for (const variant of schema.oneOf) {\n if (variant.properties && (variant.type === 'object' || !variant.type)) {\n const modelName = deriveModelName(variant, contextName);\n const existingNames = new Set(inlineModels.map((m) => m.name));\n if (!existingNames.has(modelName)) {\n inlineModels.push(...extractInlineModel(modelName, variant));\n }\n }\n }\n }\n\n // Array with inline object items — extract the item model\n if (schema.type === 'array' && schema.items) {\n const items = schema.items;\n if (items.$ref) {\n return {\n response: { kind: 'array', items: schemaToTypeRef(items, contextName) },\n inlineModels,\n isPaginated: false,\n };\n }\n if (items.properties && (items.type === 'object' || !items.type)) {\n const itemName = contextName.replace(/Response$/, '') + 'Item';\n inlineModels.push(...extractInlineModel(itemName, items));\n return {\n response: { kind: 'array', items: { kind: 'model', name: itemName } },\n inlineModels,\n isPaginated: false,\n };\n }\n }\n\n // Non-object schema (primitive, union, etc.) — delegate to schemaToTypeRef\n return {\n response: schemaToTypeRef(schema, contextName),\n inlineModels,\n isPaginated: false,\n };\n}\n\nfunction deriveModelName(schema: SchemaObject, fallback: string): string {\n if (!schema.properties) return toPascalCase(fallback);\n\n // Prefer well-known discriminant properties for backward compatibility\n const preferred = ['object', 'type'];\n for (const name of preferred) {\n const field = schema.properties[name];\n if (field && field.const && typeof field.const === 'string') {\n return toPascalCase(field.const);\n }\n }\n\n // Fall back to any property with a const string value\n for (const [, field] of Object.entries(schema.properties)) {\n if (field && field.const && typeof field.const === 'string') {\n return toPascalCase(field.const);\n }\n }\n\n return toPascalCase(fallback);\n}\n\n/**\n * Qualify a nested inline model name with its parent to avoid generic names.\n * e.g., parent=\"Connection\" + field=\"domains\" → \"ConnectionDomain\" (singularized)\n * Only qualifies when the field name alone would be too generic.\n */\nfunction qualifyNestedName(parentName: string, fieldName: string): string {\n const pascalField = toPascalCase(fieldName);\n // If the field name already starts with the parent name, don't double-prefix\n if (pascalField.startsWith(parentName)) return pascalField;\n // Qualify with parent and singularize:\n // Connection + Domains → ConnectionDomains → singularize lead word → ConnectionDomain\n const cleanParent = stripListItemMarkers(parentName);\n const qualified = `${cleanParent}${pascalField}`;\n // Singularize the trailing word: ConnectionDomains → ConnectionDomain\n const match = qualified.match(/^(.+?)([A-Z][a-z]+s?)$/);\n if (match && match[2]) {\n const trailing = singularize(match[2]);\n return match[1] + trailing;\n }\n return qualified;\n}\n\nfunction extractInlineModel(name: string, schema: SchemaObject): Model[] {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n const properties = schema.properties ?? {};\n const nestedModels: Model[] = [];\n\n for (const [fieldName, fieldSchema] of Object.entries(properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, name, requiredSet));\n\n // Recursively extract nested inline objects — qualify with parent name\n // to avoid generic names like \"Domains\" when multiple parents have a \"domains\" field\n if (fieldSchema.type === 'object' && fieldSchema.properties) {\n const nestedName = qualifyNestedName(name, fieldName);\n nestedModels.push(...extractInlineModel(nestedName, fieldSchema));\n }\n if (fieldSchema.type === 'array' && fieldSchema.items) {\n const items = fieldSchema.items;\n if (items.type === 'object' && items.properties) {\n const nestedName = qualifyNestedName(name, fieldName);\n nestedModels.push(...extractInlineModel(nestedName, items));\n }\n }\n // Handle allOf with inline object properties — merge into a single nested model\n if (fieldSchema.allOf) {\n const mergedProperties: Record<string, SchemaObject | undefined> = {};\n const mergedRequired: string[] = [];\n for (const sub of fieldSchema.allOf) {\n if (sub.properties) Object.assign(mergedProperties, sub.properties);\n if (sub.required) mergedRequired.push(...sub.required);\n }\n if (Object.keys(mergedProperties).length > 0) {\n const nestedName = qualifyNestedName(name, fieldName);\n const merged: SchemaObject = { type: 'object', properties: mergedProperties, required: mergedRequired };\n const existingNames = new Set(nestedModels.map((m) => m.name));\n if (!existingNames.has(nestedName)) {\n nestedModels.push(...extractInlineModel(nestedName, merged));\n }\n }\n }\n // Handle oneOf containing inline objects — extract the first non-null object variant\n if (fieldSchema.oneOf) {\n const objectVariant = fieldSchema.oneOf.find((v) => v.properties && (v.type === 'object' || !v.type));\n if (objectVariant) {\n const nestedName = qualifyNestedName(name, fieldName);\n const existingNames = new Set(nestedModels.map((m) => m.name));\n if (!existingNames.has(nestedName)) {\n nestedModels.push(...extractInlineModel(nestedName, objectVariant));\n }\n }\n }\n }\n\n return [{ name, description: schema.description, fields }, ...nestedModels];\n}\n","import type {\n Service,\n Operation,\n HttpMethod,\n Parameter,\n ParameterGroup,\n TypeRef,\n ErrorResponse,\n SuccessResponse,\n SecurityRequirement,\n Model,\n Field,\n PaginationMeta,\n} from '../ir/types.js';\nimport { toPascalCase, toCamelCase, cleanSchemaName } from '../utils/naming.js';\nimport type { SchemaObject } from './schemas.js';\nimport { schemaToTypeRef, buildFieldFromSchema } from './schemas.js';\nimport { detectPagination } from './pagination.js';\nimport { classifyAndExtractResponse } from './responses.js';\n\ninterface PathItem {\n get?: OperationObject;\n post?: OperationObject;\n put?: OperationObject;\n patch?: OperationObject;\n delete?: OperationObject;\n head?: OperationObject;\n options?: OperationObject;\n trace?: OperationObject;\n parameters?: ParameterObject[];\n}\n\ninterface ParameterGroupExtension {\n optional: boolean;\n variants: Record<string, string[]>;\n}\n\ninterface OperationObject {\n operationId?: string;\n summary?: string;\n description?: string;\n tags?: string[];\n parameters?: ParameterObject[];\n requestBody?: RequestBodyObject;\n responses?: Record<string, ResponseObject>;\n deprecated?: boolean;\n 'x-oagen-async'?: boolean;\n security?: Array<Record<string, string[]>>;\n 'x-mutually-exclusive-parameter-groups'?: Record<string, ParameterGroupExtension>;\n 'x-mutually-exclusive-body-groups'?: Record<string, ParameterGroupExtension>;\n}\n\ninterface ParameterObject {\n name: string;\n in: 'path' | 'query' | 'header' | 'cookie';\n required?: boolean;\n description?: string;\n schema?: SchemaObject;\n deprecated?: boolean;\n example?: unknown;\n style?: string;\n explode?: boolean;\n}\n\ninterface RequestBodyObject {\n required?: boolean;\n content?: Record<string, { schema?: SchemaObject }>;\n}\n\ninterface ResponseObject {\n description?: string;\n content?: Record<string, { schema?: SchemaObject }>;\n}\n\nconst HTTP_METHODS: HttpMethod[] = ['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace'];\n\nexport interface OperationExtractionResult {\n services: Service[];\n inlineModels: Model[];\n}\n\nexport function extractOperations(\n paths: Record<string, PathItem> | undefined,\n operationIdTransform?: (id: string) => string,\n): OperationExtractionResult {\n if (!paths) return { services: [], inlineModels: [] };\n\n const serviceMap = new Map<string, Operation[]>();\n const inlineModels: Model[] = [];\n\n for (const [path, pathItem] of Object.entries(paths)) {\n const pathLevelParams = pathItem.parameters ?? [];\n\n for (const method of HTTP_METHODS) {\n const op = pathItem[method];\n if (!op) continue;\n\n const serviceName = inferServiceName(path, op.tags?.[0]);\n\n const { operation, inlineModels: opModels } = buildOperation(\n method,\n path,\n op,\n pathLevelParams,\n operationIdTransform,\n serviceName,\n );\n inlineModels.push(...opModels);\n const ops = serviceMap.get(serviceName) ?? [];\n ops.push(operation);\n serviceMap.set(serviceName, ops);\n }\n }\n\n // Split services when a single tag groups operations from multiple path prefixes.\n // Example: /organizations and /organization_domains both tagged \"organizations\"\n // should become separate services based on their first path segment.\n for (const [serviceName, operations] of serviceMap) {\n const pathGroups = new Map<string, Operation[]>();\n for (const op of operations) {\n const firstSeg = op.path.split('/').filter(Boolean)[0] ?? '';\n const groupKey = firstSeg.startsWith('{') ? serviceName : toPascalCase(firstSeg);\n const group = pathGroups.get(groupKey) ?? [];\n group.push(op);\n pathGroups.set(groupKey, group);\n }\n // Only split if there are multiple distinct path-prefix groups AND\n // at least one group name differs from the current service name\n if (pathGroups.size > 1) {\n const needsSplit = [...pathGroups.keys()].some((k) => k !== serviceName);\n if (needsSplit) {\n serviceMap.delete(serviceName);\n for (const [groupName, groupOps] of pathGroups) {\n const existing = serviceMap.get(groupName) ?? [];\n existing.push(...groupOps);\n serviceMap.set(groupName, existing);\n }\n }\n }\n }\n\n // Disambiguate operation names within each service.\n // Multiple operations can get the same name (e.g., several \"list\" endpoints\n // in UserManagement for users, invitations, auth factors, etc.).\n for (const [, operations] of serviceMap) {\n disambiguateOperationNames(operations);\n }\n\n const services = Array.from(serviceMap.entries()).map(([name, operations]) => ({\n name,\n operations,\n }));\n\n return { services, inlineModels };\n}\n\nfunction inferServiceName(path: string, tag?: string): string {\n // Prefer OpenAPI tag when available — tags represent the logical grouping\n // (e.g., \"multi-factor-auth\" for /auth/factors/* endpoints).\n if (tag) {\n return toPascalCase(tag);\n }\n // Fallback: extract first meaningful path segment: /widgets/{id}/sub → \"Widgets\"\n const segments = path.split('/').filter(Boolean);\n const first = segments[0] ?? 'Default';\n // Skip path params\n if (first.startsWith('{')) return 'Default';\n return toPascalCase(first);\n}\n\nfunction inferOperationName(\n method: HttpMethod,\n path: string,\n operationId?: string,\n operationIdTransform?: (id: string) => string,\n): string {\n if (operationId) {\n if (operationIdTransform) {\n return operationIdTransform(operationId);\n }\n return toCamelCase(operationId);\n }\n\n // Fallback when no operationId is available — use method + path to build\n // a descriptive name like \"listUsers\", \"getOrganization\", \"deleteAuthFactor\"\n const verb = inferVerb(method, path);\n const resource = inferResourceFromPath(path);\n return resource ? toCamelCase(`${verb}_${resource}`) : verb;\n}\n\n/**\n * Infer the CRUD verb from HTTP method and path shape.\n */\nfunction inferVerb(method: HttpMethod, path: string): string {\n const segments = path.split('/').filter(Boolean);\n const hasTrailingParam = segments.length > 0 && segments[segments.length - 1].startsWith('{');\n\n switch (method) {\n case 'get':\n return hasTrailingParam ? 'get' : 'list';\n case 'post':\n return 'create';\n case 'put':\n case 'patch':\n return 'update';\n case 'delete':\n return 'delete';\n case 'head':\n return 'check';\n case 'options':\n return 'options';\n case 'trace':\n return 'trace';\n default:\n return method;\n }\n}\n\n/**\n * Extract a resource noun from the path for operation naming.\n * Uses the last non-param segment (the resource being operated on).\n *\n * Examples:\n * /user_management/users → \"Users\"\n * /user_management/users/{id} → \"User\" (singular for item operations)\n * /user_management/users/{id}/auth_factors → \"AuthFactors\"\n * /organizations/{id}/api_keys → \"ApiKeys\"\n * /sso/authorize → \"Authorize\" (action endpoint)\n */\nfunction inferResourceFromPath(path: string): string | null {\n const segments = path.split('/').filter(Boolean);\n if (segments.length <= 1) return null;\n\n // Find the last meaningful (non-param) segment\n let resourceSegment: string | null = null;\n for (let i = segments.length - 1; i >= 0; i--) {\n if (!segments[i].startsWith('{')) {\n resourceSegment = segments[i];\n break;\n }\n }\n\n if (!resourceSegment) return null;\n // Skip the service name (first segment) — it would be redundant\n if (resourceSegment === segments[0]) return null;\n\n return toPascalCase(resourceSegment);\n}\n\n/**\n * Detect and resolve name collisions within a service's operations.\n *\n * When multiple operations share the same name (e.g., several \"list\" from\n * different sub-resources), disambiguate by appending the resource noun\n * from the path. Only renames operations on DIFFERENT paths — same-name\n * operations on the same path (e.g., PUT + PATCH both \"update\") are left as-is\n * since they represent the same logical resource.\n */\nfunction disambiguateOperationNames(operations: Operation[]): void {\n // Group by name\n const byName = new Map<string, Operation[]>();\n for (const op of operations) {\n const group = byName.get(op.name) ?? [];\n group.push(op);\n byName.set(op.name, group);\n }\n\n for (const [name, group] of byName) {\n if (group.length <= 1) continue;\n\n // Check if these are genuinely different resources (different paths)\n // vs the same resource with different methods (PUT + PATCH)\n const uniquePaths = new Set(group.map((op) => op.path));\n if (uniquePaths.size <= 1) continue; // same path, different methods — no disambiguation needed\n\n for (const op of group) {\n const resource = inferResourceFromPath(op.path);\n if (resource) {\n const newName = toCamelCase(`${name}_${resource}`);\n (op as { name: string }).name = newName;\n }\n }\n\n // If disambiguation still left collisions (same sub-resource),\n // use the full distinguishing path segment chain\n const renamed = new Map<string, Operation[]>();\n for (const op of group) {\n const rGroup = renamed.get(op.name) ?? [];\n rGroup.push(op);\n renamed.set(op.name, rGroup);\n }\n for (const [, rGroup] of renamed) {\n if (rGroup.length <= 1) continue;\n // Still colliding — different paths map to same resource name.\n // Use deeper path context to disambiguate.\n for (const op of rGroup) {\n const deeper = inferDeeperContext(op.path);\n if (deeper) {\n (op as { name: string }).name = toCamelCase(`${op.name}_${deeper}`);\n }\n }\n }\n }\n}\n\n/**\n * Extract a deeper disambiguation context from the path when the last\n * segment isn't unique enough. Uses the second-to-last non-param segment.\n *\n * /users/{id}/auth_factors → already captured as \"AuthFactors\"\n * /users/external_id/{external_id} → \"ExternalId\" (special path, not a sub-resource)\n */\nfunction inferDeeperContext(path: string): string | null {\n const segments = path.split('/').filter(Boolean);\n const nonParams = segments.filter((s) => !s.startsWith('{'));\n // Skip first (service) and last (already used) — use the middle ones\n if (nonParams.length >= 3) {\n return toPascalCase(nonParams.slice(1, -1).join('_'));\n }\n return null;\n}\n\n/**\n * Extract mutually-exclusive parameter groups from the `x-mutually-exclusive-parameter-groups`\n * operation extension. Cross-references grouped parameter names against the already-extracted\n * IR parameter arrays so emitters get object-identity references.\n */\nfunction extractParameterGroups(\n op: OperationObject,\n allIRParams: Parameter[],\n operationContext: string,\n): ParameterGroup[] | undefined {\n const raw = op['x-mutually-exclusive-parameter-groups'];\n if (!raw || typeof raw !== 'object') return undefined;\n\n const paramByName = new Map<string, Parameter>();\n for (const p of allIRParams) {\n paramByName.set(p.name, p);\n }\n\n const groups: ParameterGroup[] = [];\n\n for (const [groupName, groupDef] of Object.entries(raw)) {\n if (!groupDef || typeof groupDef !== 'object') {\n throw new Error(\n `Malformed x-mutually-exclusive-parameter-groups.${groupName} in ${operationContext}: expected an object with \"optional\" and \"variants\".`,\n );\n }\n\n if (typeof groupDef.optional !== 'boolean') {\n throw new Error(\n `Malformed x-mutually-exclusive-parameter-groups.${groupName}.optional in ${operationContext}: expected a boolean.`,\n );\n }\n\n if (!groupDef.variants || typeof groupDef.variants !== 'object') {\n throw new Error(\n `Malformed x-mutually-exclusive-parameter-groups.${groupName}.variants in ${operationContext}: expected an object mapping variant names to parameter name arrays.`,\n );\n }\n\n if (Object.keys(groupDef.variants).length === 0) {\n throw new Error(\n `Malformed x-mutually-exclusive-parameter-groups.${groupName} in ${operationContext}: group has zero variants.`,\n );\n }\n\n const variants = Object.entries(groupDef.variants).map(([variantName, paramNames]) => {\n if (!Array.isArray(paramNames) || paramNames.length === 0) {\n throw new Error(\n `Malformed x-mutually-exclusive-parameter-groups.${groupName}.variants.${variantName} in ${operationContext}: expected a non-empty array of parameter names.`,\n );\n }\n const parameters: Parameter[] = paramNames.map((pName) => {\n const irParam = paramByName.get(pName);\n if (!irParam) {\n throw new Error(\n `x-mutually-exclusive-parameter-groups.${groupName}.variants.${variantName} references parameter \"${pName}\" which does not exist in the operation's parameters[] (${operationContext}).`,\n );\n }\n return irParam;\n });\n return { name: variantName, parameters };\n });\n\n groups.push({\n name: groupName,\n optional: groupDef.optional,\n variants,\n });\n }\n\n return groups.length > 0 ? groups : undefined;\n}\n\n/**\n * Extract mutually-exclusive body parameter groups from the\n * `x-mutually-exclusive-body-groups` operation extension. Unlike query\n * parameter groups (whose parameters live in operation.queryParams), body\n * group parameters are synthetic — built from the oneOf variant schemas in\n * the request body. Emitters use the group's presence to generate sum-type\n * interfaces and custom JSON marshalling instead of flat optional fields.\n */\nfunction extractBodyParameterGroups(op: OperationObject, operationContext: string): ParameterGroup[] | undefined {\n const raw = op['x-mutually-exclusive-body-groups'];\n if (!raw || typeof raw !== 'object') return undefined;\n\n // Collect the body schema's oneOf variant fields so we can resolve types.\n // The body schema has been structurally rewritten to allOf: [base, { oneOf: [...] }]\n // by the spec generator; the variant properties live inside oneOf branches.\n const bodySchema = op.requestBody?.content?.['application/json']?.schema;\n const variantFieldSchemas = new Map<string, SchemaObject>();\n\n if (bodySchema) {\n // Walk allOf → oneOf → variant.properties to find all variant fields\n for (const sub of bodySchema.allOf ?? []) {\n for (const variant of sub.oneOf ?? []) {\n if (variant.properties) {\n for (const [name, fieldSchema] of Object.entries(variant.properties)) {\n if (fieldSchema) variantFieldSchemas.set(name, fieldSchema);\n }\n }\n }\n }\n // Also check top-level oneOf (for inline schemas that aren't wrapped in allOf)\n for (const variant of bodySchema.oneOf ?? []) {\n if (variant.properties) {\n for (const [name, fieldSchema] of Object.entries(variant.properties)) {\n if (fieldSchema) variantFieldSchemas.set(name, fieldSchema);\n }\n }\n }\n }\n\n const groups: ParameterGroup[] = [];\n\n for (const [groupName, groupDef] of Object.entries(raw)) {\n if (!groupDef || typeof groupDef !== 'object') continue;\n if (typeof groupDef.optional !== 'boolean') continue;\n if (!groupDef.variants || typeof groupDef.variants !== 'object') continue;\n if (Object.keys(groupDef.variants).length === 0) continue;\n\n const variants = Object.entries(groupDef.variants).map(([variantName, paramNames]) => {\n if (!Array.isArray(paramNames) || paramNames.length === 0) {\n throw new Error(\n `Malformed x-mutually-exclusive-body-groups.${groupName}.variants.${variantName} in ${operationContext}: expected a non-empty array of parameter names.`,\n );\n }\n const parameters: Parameter[] = paramNames.map((pName) => {\n const fieldSchema = variantFieldSchemas.get(pName);\n const fieldType: TypeRef = fieldSchema\n ? schemaToTypeRef(fieldSchema, toPascalCase(pName))\n : { kind: 'primitive', type: 'string' };\n return {\n name: pName,\n type: fieldType,\n required: false, // group variant fields are always optional at the struct level\n description: fieldSchema?.description,\n };\n });\n return { name: variantName, parameters };\n });\n\n groups.push({\n name: groupName,\n optional: groupDef.optional,\n variants,\n });\n }\n\n return groups.length > 0 ? groups : undefined;\n}\n\nfunction buildOperation(\n method: HttpMethod,\n path: string,\n op: OperationObject,\n pathLevelParams: ParameterObject[],\n operationIdTransform?: (id: string) => string,\n serviceName?: string,\n): { operation: Operation; inlineModels: Model[] } {\n const allParams = [...pathLevelParams, ...(op.parameters ?? [])];\n\n const hasIdempotencyHeader = allParams.some((p) => p.in === 'header' && p.name.toLowerCase() === 'idempotency-key');\n\n // Use the service name as context so inline parameter enums get qualified\n // names. e.g., service \"SSO\" + param \"provider\" → \"SSOProvider\".\n const opContext = serviceName;\n const pathParams = extractParams(allParams, 'path', opContext);\n const queryParams = extractParams(allParams, 'query', opContext);\n const headerParams = extractParams(allParams, 'header', opContext).filter(\n (p) => p.name.toLowerCase() !== 'idempotency-key',\n );\n const cookieParams = extractParams(allParams, 'cookie', opContext);\n\n const reqBodyModels: Model[] = [];\n const { body: requestBody, encoding: requestBodyEncoding } = extractRequestBody(op.requestBody, op, reqBodyModels);\n const {\n response,\n successResponses,\n errors,\n inlineModels,\n isPaginated,\n dataPath: responseDataPath,\n itemType: responseItemType,\n } = extractResponses(op.responses, op, path, method);\n inlineModels.push(...reqBodyModels);\n\n // Build structured pagination metadata from response classification and query param detection\n const paginationFromParams = detectPagination(response, queryParams, responseDataPath);\n let pagination: PaginationMeta | undefined;\n if (isPaginated) {\n const itemType = responseItemType ?? (response.kind === 'array' ? response.items : response);\n pagination = {\n strategy: paginationFromParams?.strategy ?? 'cursor',\n param: paginationFromParams?.param ?? 'after',\n limitParam: paginationFromParams?.limitParam,\n dataPath: responseDataPath ?? paginationFromParams?.dataPath,\n itemType,\n };\n } else if (paginationFromParams) {\n pagination = paginationFromParams;\n }\n\n // Extract per-operation security overrides\n const security = extractOperationSecurity(op.security);\n\n // Extract mutually-exclusive parameter groups (query/path/header/cookie)\n const allIRParams = [...pathParams, ...queryParams, ...headerParams, ...cookieParams];\n const opLabel = op.operationId ?? `${method.toUpperCase()} ${path}`;\n const queryParamGroups = extractParameterGroups(op, allIRParams, opLabel);\n\n // Extract mutually-exclusive body parameter groups\n const bodyParamGroups = extractBodyParameterGroups(op, opLabel);\n\n // Merge both sources into a single parameterGroups array\n const parameterGroups =\n queryParamGroups || bodyParamGroups ? [...(queryParamGroups ?? []), ...(bodyParamGroups ?? [])] : undefined;\n\n return {\n operation: {\n name: inferOperationName(method, path, op.operationId, operationIdTransform),\n description: buildDescription(op.summary, op.description),\n httpMethod: method,\n path,\n pathParams,\n queryParams,\n headerParams,\n cookieParams: cookieParams.length > 0 ? cookieParams : undefined,\n requestBody,\n requestBodyEncoding,\n response,\n successResponses,\n errors,\n pagination,\n injectIdempotencyKey: hasIdempotencyHeader,\n deprecated: op.deprecated || undefined,\n async: op['x-oagen-async'],\n security,\n parameterGroups,\n },\n inlineModels,\n };\n}\n\n/**\n * Extract per-operation security requirements from an OpenAPI security directive.\n * Returns undefined when the operation uses the spec-level default security.\n *\n * OpenAPI security format: `security: [{ schemeName: [scope1, scope2] }]`\n */\nfunction extractOperationSecurity(\n security: Array<Record<string, string[]>> | undefined,\n): SecurityRequirement[] | undefined {\n if (!security || security.length === 0) return undefined;\n\n const requirements: SecurityRequirement[] = [];\n for (const entry of security) {\n for (const [schemeName, scopes] of Object.entries(entry)) {\n requirements.push({ schemeName, scopes: scopes ?? [] });\n }\n }\n return requirements.length > 0 ? requirements : undefined;\n}\n\nfunction buildDescription(summary: string | undefined, description: string | undefined): string | undefined {\n if (summary && description && summary !== description) {\n return `${summary}\\n\\n${description}`;\n }\n return description ?? summary;\n}\n\nfunction extractParams(\n params: ParameterObject[],\n location: 'path' | 'query' | 'header' | 'cookie',\n operationContext?: string,\n): Parameter[] {\n return params\n .filter((p) => p.in === location)\n .map((p) => ({\n name: p.name,\n type: p.schema\n ? schemaToTypeRef(p.schema, p.name, operationContext ? toPascalCase(operationContext) : undefined)\n : ({ kind: 'primitive', type: 'string' } as TypeRef),\n required: p.required ?? false,\n description: p.description,\n deprecated: p.deprecated || p.schema?.deprecated || undefined,\n default: p.schema?.default,\n example: p.example ?? p.schema?.example,\n style: p.style as Parameter['style'],\n explode: p.explode,\n }));\n}\n\nfunction extractRequestBody(\n body: RequestBodyObject | undefined,\n op: OperationObject | undefined,\n inlineModels: Model[],\n): { body?: TypeRef; encoding?: 'json' | 'form-data' | 'form-urlencoded' | 'binary' | 'text' } {\n if (!body?.content) return {};\n\n // Detect encoding and find schema from content type in priority order\n let encoding: 'json' | 'form-data' | 'form-urlencoded' | 'binary' | 'text' = 'json';\n let schema: SchemaObject | undefined;\n\n if (body.content['application/json']?.schema) {\n encoding = 'json';\n schema = body.content['application/json']!.schema;\n } else if (body.content['multipart/form-data']?.schema) {\n encoding = 'form-data';\n schema = body.content['multipart/form-data']!.schema;\n } else if (body.content['application/x-www-form-urlencoded']?.schema) {\n encoding = 'form-urlencoded';\n schema = body.content['application/x-www-form-urlencoded']!.schema;\n } else if (body.content['application/octet-stream']) {\n encoding = 'binary';\n schema = body.content['application/octet-stream']!.schema;\n } else if (body.content['text/plain']) {\n encoding = 'text';\n schema = body.content['text/plain']!.schema;\n }\n\n if (!schema) {\n // For binary/text, a schema is optional — produce a primitive TypeRef\n if (encoding === 'binary') {\n return { body: { kind: 'primitive', type: 'string', format: 'binary' }, encoding };\n }\n if (encoding === 'text') {\n return { body: { kind: 'primitive', type: 'string' }, encoding };\n }\n return {};\n }\n\n const rawName = op?.operationId ? toPascalCase(op.operationId) + 'Request' : 'RequestBody';\n const contextName = cleanSchemaName(rawName);\n\n // If the request body is an inline object with properties, extract it as a model\n if (schema.properties && (schema.type === 'object' || !schema.type)) {\n const requiredSet = new Set(schema.required ?? []);\n const fields: Field[] = [];\n for (const [fieldName, fieldSchema] of Object.entries(schema.properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, contextName, requiredSet));\n }\n inlineModels.push({ name: contextName, description: undefined, fields });\n return { body: { kind: 'model', name: contextName }, encoding };\n }\n\n // If the request body is a oneOf, extract each variant as an inline model\n // and build a union type pointing to them by name.\n if (schema.oneOf) {\n const variants: TypeRef[] = [];\n\n for (const variant of schema.oneOf) {\n if (variant.$ref) {\n const ref = schemaToTypeRef(variant, contextName);\n variants.push(ref);\n } else if (variant.type === 'null') {\n // skip null variant in union, handle separately\n } else if (variant.properties && (variant.type === 'object' || !variant.type)) {\n const variantName = deriveOneOfVariantName(variant, contextName, inlineModels);\n const requiredSet = new Set(variant.required ?? []);\n const fields: Field[] = [];\n for (const [fieldName, fieldSchema] of Object.entries(variant.properties)) {\n if (!fieldSchema) continue;\n fields.push(buildFieldFromSchema(fieldName, fieldSchema, variantName, requiredSet));\n }\n inlineModels.push({ name: variantName, description: variant.description, fields });\n variants.push({ kind: 'model', name: variantName });\n } else {\n variants.push(schemaToTypeRef(variant, contextName));\n }\n }\n\n const hasNull = schema.oneOf.some(\n (v: SchemaObject) => v.type === 'null' || (Array.isArray(v.type) && v.type.includes('null')),\n );\n const union: TypeRef = {\n kind: 'union',\n variants,\n ...(schema.discriminator\n ? {\n discriminator: { property: schema.discriminator.propertyName, mapping: schema.discriminator.mapping ?? {} },\n }\n : {}),\n };\n const body = hasNull ? ({ kind: 'nullable', inner: union } as TypeRef) : union;\n return { body, encoding };\n }\n\n return { body: schemaToTypeRef(schema, contextName), encoding };\n}\n\n/** Derive a unique variant name for a oneOf inline model. */\nfunction deriveOneOfVariantName(variant: SchemaObject, baseName: string, existingModels: Model[]): string {\n // Try to use a distinguishing property (e.g., \"grant_type\" field's const/enum value)\n if (variant.properties) {\n for (const [, propSchema] of Object.entries(variant.properties)) {\n if (propSchema?.const && typeof propSchema.const === 'string') {\n return toPascalCase(propSchema.const) + baseName.replace(/Request$/, '') + 'Request';\n }\n }\n }\n // Fallback: append a numeric suffix\n const existingNames = new Set(existingModels.map((m) => m.name));\n let name = baseName;\n let suffix = 2;\n while (existingNames.has(name)) {\n name = `${baseName}${suffix}`;\n suffix++;\n }\n return name;\n}\n\nfunction deriveResponseName(op: OperationObject | undefined, path: string, method: HttpMethod): string {\n if (op?.operationId) {\n return cleanSchemaName(toPascalCase(op.operationId) + 'Response');\n }\n const segments = path.split('/').filter(Boolean);\n const resource = segments[0] ?? 'Unknown';\n return toPascalCase(resource) + toPascalCase(method) + 'Response';\n}\n\nfunction extractResponses(\n responses?: Record<string, ResponseObject>,\n op?: OperationObject,\n path?: string,\n method?: HttpMethod,\n): {\n response: TypeRef;\n successResponses?: SuccessResponse[];\n errors: ErrorResponse[];\n inlineModels: Model[];\n isPaginated: boolean;\n dataPath?: string;\n itemType?: TypeRef;\n} {\n const errors: ErrorResponse[] = [];\n let response: TypeRef = { kind: 'primitive', type: 'string' };\n let inlineModels: Model[] = [];\n let isPaginated = false;\n let dataPath: string | undefined;\n let itemType: TypeRef | undefined;\n\n if (!responses) return { response, errors, inlineModels, isPaginated };\n\n const allSuccessResponses: SuccessResponse[] = [];\n\n for (const [statusCode, resp] of Object.entries(responses)) {\n const code = parseInt(statusCode, 10);\n\n if (code >= 200 && code < 300) {\n let extractedType: TypeRef = { kind: 'primitive', type: 'unknown' };\n const jsonContent = resp.content?.['application/json'];\n if (jsonContent?.schema) {\n const contextName = deriveResponseName(op, path ?? '/', method ?? 'get');\n const result = classifyAndExtractResponse(jsonContent.schema, contextName);\n extractedType = result.response;\n // Keep track of inline models and pagination from the latest 2xx with a schema\n inlineModels = result.inlineModels;\n isPaginated = result.isPaginated;\n dataPath = result.dataPath;\n itemType = result.itemType;\n } else if (resp.content) {\n // Handle non-JSON response content types (text/plain, binary, XML, etc.)\n if (resp.content['application/octet-stream'] || resp.content['application/pdf']) {\n extractedType = { kind: 'primitive', type: 'string', format: 'binary' };\n } else if (\n resp.content['text/plain'] ||\n resp.content['text/html'] ||\n resp.content['text/xml'] ||\n resp.content['application/xml']\n ) {\n extractedType = { kind: 'primitive', type: 'string' };\n } else {\n // Try the first available content type's schema\n const firstKey = Object.keys(resp.content)[0];\n if (firstKey) {\n const firstContent = resp.content[firstKey];\n if (firstContent?.schema) {\n extractedType = schemaToTypeRef(\n firstContent.schema,\n deriveResponseName(op, path ?? '/', method ?? 'get'),\n );\n }\n }\n }\n }\n allSuccessResponses.push({ statusCode: code, type: extractedType });\n } else if (code >= 300 && code < 400) {\n // 3xx redirects — include so emitter can detect redirect endpoints\n allSuccessResponses.push({ statusCode: code, type: { kind: 'primitive', type: 'unknown' } });\n } else if (code >= 400) {\n const jsonContent = resp.content?.['application/json'];\n const type = jsonContent?.schema ? schemaToTypeRef(jsonContent.schema, `Error${code}`) : undefined;\n errors.push({ statusCode: code, type });\n }\n }\n\n // Primary response = lowest 2xx with a body schema, falling back to first 2xx\n if (allSuccessResponses.length > 0) {\n const sorted = [...allSuccessResponses].sort((a, b) => a.statusCode - b.statusCode);\n const primary =\n sorted.find((r) => r.type.kind !== 'primitive' || (r.type as { type: string }).type !== 'unknown') ?? sorted[0];\n response = primary.type;\n }\n\n const successResponses = allSuccessResponses.length > 1 ? allSuccessResponses : undefined;\n\n return { response, successResponses, errors, inlineModels, isPaginated, dataPath, itemType };\n}\n","import type { Model, Service, TypeRef } from '../ir/types.js';\nimport { walkTypeRef } from '../ir/types.js';\n\nfunction keepLargestByName(models: Model[]): Model[] {\n const byName = new Map<string, Model>();\n for (const model of models) {\n const existing = byName.get(model.name);\n if (!existing || model.fields.length > existing.fields.length) {\n byName.set(model.name, model);\n }\n }\n return [...byName.values()];\n}\n\nfunction rewriteModelRef(ref: TypeRef, oldName: string, newName: string): void {\n walkTypeRef(ref, {\n model: (r) => {\n if (r.name === oldName) (r as { name: string }).name = newName;\n },\n });\n}\n\nfunction rewriteModelRefs(models: Model[], services: Service[], oldName: string, newName: string): void {\n for (const model of models) {\n for (const field of model.fields) {\n rewriteModelRef(field.type, oldName, newName);\n }\n }\n for (const service of services) {\n for (const op of service.operations) {\n rewriteModelRef(op.response, oldName, newName);\n if (op.requestBody) {\n rewriteModelRef(op.requestBody, oldName, newName);\n }\n }\n }\n}\n\nexport function mergeInlineResponseModels(schemaModels: Model[], inlineModels: Model[]): Model[] {\n const mergedSchemaModels = [...schemaModels];\n const schemaModelNames = new Set(mergedSchemaModels.map((m) => m.name));\n const schemaModelsByName = new Map(mergedSchemaModels.map((m) => [m.name, m]));\n\n const deduplicatedInlineModels = inlineModels.filter((model) => {\n if (!schemaModelNames.has(model.name)) return true;\n\n const existing = schemaModelsByName.get(model.name)!;\n const existingFieldNames = new Set(existing.fields.map((f) => f.name));\n const inlineFieldNames = new Set(model.fields.map((f) => f.name));\n const hasDifference =\n model.fields.some((f) => !existingFieldNames.has(f.name)) ||\n existing.fields.some((f) => !inlineFieldNames.has(f.name));\n\n if (hasDifference && model.fields.length > existing.fields.length) {\n const idx = mergedSchemaModels.indexOf(existing);\n if (idx !== -1) mergedSchemaModels[idx] = model;\n schemaModelsByName.set(model.name, model);\n console.warn(\n `[oagen] Warning: Inline model \"${model.name}\" has more fields than component schema (${model.fields.length} vs ${existing.fields.length}) — using inline response model`,\n );\n } else if (hasDifference) {\n console.warn(\n `[oagen] Warning: Inline model \"${model.name}\" has different fields than component schema — using component schema`,\n );\n }\n\n return false;\n });\n\n return [...mergedSchemaModels, ...keepLargestByName(deduplicatedInlineModels)];\n}\n\nexport function mergeFieldInlineModels(existingModels: Model[], fieldInlineModels: Model[]): Model[] {\n const modelNames = new Set(existingModels.map((m) => m.name));\n const modelsByName = new Map(existingModels.map((m) => [m.name, m]));\n\n const deduplicatedFieldModels = fieldInlineModels.filter((model) => {\n if (!modelNames.has(model.name)) return true;\n\n const existing = modelsByName.get(model.name)!;\n const existingFieldNames = new Set(existing.fields.map((f) => f.name));\n const inlineFieldNames = new Set(model.fields.map((f) => f.name));\n const hasDifference =\n model.fields.some((f) => !existingFieldNames.has(f.name)) ||\n existing.fields.some((f) => !inlineFieldNames.has(f.name));\n\n if (hasDifference) {\n console.warn(\n `[oagen] Warning: Inline model \"${model.name}\" has different fields than component schema — using component schema`,\n );\n }\n\n return false;\n });\n\n return [...existingModels, ...keepLargestByName(deduplicatedFieldModels)];\n}\n\nfunction hasModelConstDiscriminant(model: Model): boolean {\n return model.fields.some(\n (f) => (f.name === 'object' || f.name === 'type') && f.type.kind === 'literal' && typeof f.type.value === 'string',\n );\n}\n\nfunction isModelReferencedByOthers(name: string, models: Model[], excludeNames: Set<string>): boolean {\n for (const model of models) {\n if (excludeNames.has(model.name)) continue;\n for (const field of model.fields) {\n let found = false;\n walkTypeRef(field.type, {\n model: (r) => {\n if (r.name === name) found = true;\n },\n });\n if (found) return true;\n }\n }\n return false;\n}\n\nexport function collapseJsonSuffixModels(models: Model[], services: Service[]): Model[] {\n const normalizedModels = [...models];\n const byName = new Map(normalizedModels.map((m) => [m.name, m]));\n\n // Pass 1: collect merge candidates\n const mergeCandidates: Array<{ jsonModel: Model; baseModel: Model }> = [];\n for (const model of normalizedModels) {\n if (!model.name.endsWith('Json')) continue;\n\n const baseName = model.name.slice(0, -4);\n const baseModel = byName.get(baseName);\n if (!baseModel || model.fields.length <= baseModel.fields.length) continue;\n\n const isSuperset = baseModel.fields.every((f) => model.fields.some((mf) => mf.name === f.name));\n if (!isSuperset) continue;\n\n // Guard: both models have a const discriminant — they are distinct entities\n if (hasModelConstDiscriminant(model) && hasModelConstDiscriminant(baseModel)) continue;\n\n // Guard: a third model explicitly references the Json-suffix model\n if (isModelReferencedByOthers(model.name, normalizedModels, new Set([model.name, baseName]))) continue;\n\n mergeCandidates.push({ jsonModel: model, baseModel });\n }\n\n // Pass 2: apply merges\n const toRemove = new Set<string>();\n for (const { jsonModel, baseModel } of mergeCandidates) {\n baseModel.fields = jsonModel.fields;\n toRemove.add(jsonModel.name);\n rewriteModelRefs(normalizedModels, services, jsonModel.name, baseModel.name);\n console.warn(\n `[oagen] Merged \"${jsonModel.name}\" into \"${baseModel.name}\" (${jsonModel.fields.length} fields, superset)`,\n );\n }\n\n return normalizedModels.filter((m) => !toRemove.has(m.name));\n}\n","import type { Enum, Model, Service } from '../ir/types.js';\nimport { collectInlineEnumFromRef } from './schemas.js';\n\nexport function collectInlineEnumsFromModels(models: Model[], enums: Enum[]): void {\n const enumNames = new Set(enums.map((e) => e.name));\n for (const model of models) {\n for (const field of model.fields) {\n collectInlineEnumFromRef(field.type, enums, enumNames);\n }\n }\n}\n\n/**\n * Collect inline enum definitions from operation parameters (query, path, header)\n * and promote them to top-level enums so emitters can generate typed enum files.\n */\nexport function collectInlineEnumsFromOperations(services: Service[], enums: Enum[]): void {\n const enumNames = new Set(enums.map((e) => e.name));\n for (const service of services) {\n for (const op of service.operations) {\n for (const param of [...op.pathParams, ...op.queryParams, ...op.headerParams, ...(op.cookieParams ?? [])]) {\n collectInlineEnumFromRef(param.type, enums, enumNames);\n }\n }\n }\n}\n","import type { ApiSpec, TypeRef } from '../ir/types.js';\nimport { walkTypeRef } from '../ir/types.js';\n\nexport function validateModelRefs(spec: ApiSpec): void {\n const knownNames = new Set<string>();\n for (const m of spec.models) knownNames.add(m.name);\n for (const e of spec.enums) knownNames.add(e.name);\n\n function walkRef(ref: TypeRef, context: string): void {\n walkTypeRef(ref, {\n model: (r) => {\n if (!knownNames.has(r.name)) {\n console.warn(`[oagen] Warning: Unresolved model reference \"${r.name}\" (context: ${context})`);\n }\n },\n });\n }\n\n for (const model of spec.models) {\n for (const field of model.fields) {\n walkRef(field.type, `${model.name}.${field.name}`);\n }\n }\n\n for (const service of spec.services) {\n for (const op of service.operations) {\n for (const p of [...op.pathParams, ...op.queryParams, ...op.headerParams]) {\n walkRef(p.type, `${service.name}.${op.name}.${p.name}`);\n }\n if (op.requestBody) walkRef(op.requestBody, `${service.name}.${op.name}.requestBody`);\n walkRef(op.response, `${service.name}.${op.name}.response`);\n }\n }\n}\n","import type { ApiSpec, AuthScheme, ServerEntry } from '../ir/types.js';\nimport { defaultSdkBehavior } from '../ir/sdk-behavior.js';\nimport { SpecParseError } from '../errors.js';\nimport { loadAndBundleSpec } from './refs.js';\nimport { extractSchemas, extractInlineModelsFromSchemas, clearSchemaNameTransform } from './schemas.js';\nimport { extractOperations } from './operations.js';\nimport {\n mergeInlineResponseModels,\n collapseJsonSuffixModels,\n mergeFieldInlineModels,\n} from './normalize-inline-models.js';\nimport { collectInlineEnumsFromModels, collectInlineEnumsFromOperations } from './collect-inline-enums.js';\nimport { validateModelRefs } from './normalize-model-refs.js';\n\nexport interface ParseOptions {\n operationIdTransform?: (id: string) => string;\n schemaNameTransform?: (name: string) => string;\n}\n\nexport async function parseSpec(specPath: string, options?: ParseOptions): Promise<ApiSpec> {\n const { parsed } = await loadAndBundleSpec(specPath);\n\n const spec = parsed as {\n openapi?: string;\n info?: { title?: string; version?: string; description?: string };\n servers?: Array<{ url?: string; description?: string }>;\n paths?: Record<string, unknown>;\n components?: {\n schemas?: Record<string, unknown>;\n securitySchemes?: Record<\n string,\n { type: string; scheme?: string; in?: string; name?: string; flows?: Record<string, unknown> }\n >;\n };\n };\n\n // Validate OpenAPI version\n const version = spec.openapi ?? '';\n if (!version.startsWith('3.')) {\n throw new SpecParseError(\n `Unsupported OpenAPI version: ${version}. oagen requires OpenAPI 3.x`,\n `Update the spec to OpenAPI 3.0 or 3.1. If you are using Swagger 2.x, convert it first with \\`npx swagger2openapi ${specPath}\\`.`,\n );\n }\n\n const { models, enums } = extractSchemas(\n spec.components?.schemas as Record<string, Record<string, unknown>> | undefined,\n { schemaNameTransform: options?.schemaNameTransform },\n );\n\n const { services, inlineModels } = extractOperations(\n spec.paths as Record<string, Record<string, unknown>> | undefined,\n options?.operationIdTransform,\n );\n\n // schemaNameTransform is kept active through extractOperations so that\n // $ref-based TypeRefs in operations resolve to the same transformed names.\n // Now that all extraction is done, clear it.\n clearSchemaNameTransform();\n\n const responseNormalizedModels = mergeInlineResponseModels(models, inlineModels);\n\n // Extract inline models from model field definitions (objects/arrays with properties)\n const fieldInlineModels = extractInlineModelsFromSchemas(\n spec.components?.schemas as Record<string, Record<string, unknown>> | undefined,\n );\n const fieldMergedModels = mergeFieldInlineModels(responseNormalizedModels, fieldInlineModels);\n const finalModels = collapseJsonSuffixModels(fieldMergedModels, services);\n collectInlineEnumsFromModels(finalModels, enums);\n collectInlineEnumsFromOperations(services, enums);\n\n const auth = extractAuthSchemes(spec.components?.securitySchemes);\n\n const serverEntries: ServerEntry[] = (spec.servers ?? [])\n .map((s) => ({ url: s.url ?? '', description: s.description }))\n .filter((s) => s.url);\n\n const result: ApiSpec = {\n name: spec.info?.title ?? 'Unknown API',\n version: spec.info?.version ?? '0.0.0',\n description: spec.info?.description,\n baseUrl: serverEntries[0]?.url ?? '',\n servers: serverEntries.length > 0 ? serverEntries : undefined,\n services,\n models: finalModels,\n enums,\n auth,\n sdk: defaultSdkBehavior(),\n };\n\n validateModelRefs(result);\n\n return result;\n}\n/** Extract authentication schemes from OpenAPI securitySchemes. */\nfunction extractAuthSchemes(\n securitySchemes?: Record<\n string,\n { type: string; scheme?: string; in?: string; name?: string; flows?: Record<string, unknown> }\n >,\n): AuthScheme[] | undefined {\n if (!securitySchemes) return undefined;\n const schemes: AuthScheme[] = [];\n for (const [, scheme] of Object.entries(securitySchemes)) {\n if (scheme.type === 'http' && scheme.scheme === 'bearer') {\n schemes.push({ kind: 'bearer' });\n } else if (scheme.type === 'apiKey' && scheme.in && scheme.name) {\n schemes.push({ kind: 'apiKey', in: scheme.in as 'header' | 'query' | 'cookie', name: scheme.name });\n } else if (scheme.type === 'oauth2' && scheme.flows) {\n schemes.push({ kind: 'oauth2', flows: scheme.flows });\n }\n }\n return schemes.length > 0 ? schemes : undefined;\n}\n","import type { Operation, TypeRef } from '../ir/types.js';\nimport { assertNever } from '../ir/types.js';\n\nexport interface OperationPlan {\n operation: Operation;\n isDelete: boolean;\n hasBody: boolean;\n isIdempotentPost: boolean;\n pathParamsInOptions: boolean;\n isPaginated: boolean;\n responseModelName: string | null;\n /** For paginated operations, the model name of individual list items\n * (unwrapped from the list wrapper). Null for non-paginated. */\n paginatedItemModelName: string | null;\n isModelResponse: boolean;\n /** True when the response is an unpaginated `type: array` of models.\n * Emitters should use this to return `Model[]` (or the language's list\n * equivalent) and map the deserializer over each element. */\n isArrayResponse: boolean;\n hasQueryParams: boolean;\n isAsync: boolean;\n}\n\nexport function planOperation(op: Operation): OperationPlan {\n const isDelete = op.httpMethod === 'delete';\n const hasBody = !!op.requestBody;\n const isIdempotentPost = op.injectIdempotencyKey && op.httpMethod === 'post';\n const hasQueryParams = op.queryParams.length > 0;\n const pathParamsInOptions = op.pathParams.length > 1 || (op.pathParams.length > 0 && (hasBody || hasQueryParams));\n const isPaginated = op.pagination !== undefined;\n const responseModelName = resolveResponseModelName(op);\n const paginatedItemModelName =\n isPaginated && op.pagination?.itemType.kind === 'model' ? op.pagination.itemType.name : null;\n const isModelResponse = responseModelName !== null;\n // Unpaginated `type: array` of models — needs `Model[]` return + elementwise\n // deserialization. Paginated operations use the pagination wrapper instead.\n const isArrayResponse = !isPaginated && op.response.kind === 'array' && op.response.items.kind === 'model';\n const isAsync = op.async ?? true;\n\n return {\n operation: op,\n isDelete,\n hasBody,\n isIdempotentPost,\n pathParamsInOptions,\n isPaginated,\n responseModelName,\n paginatedItemModelName,\n isModelResponse,\n isArrayResponse,\n hasQueryParams,\n isAsync,\n };\n}\n\nexport function resolveResponseModelName(op: Operation): string | null {\n if (op.httpMethod === 'delete') return null;\n return extractModelName(op.response);\n}\n\nfunction extractModelName(ref: TypeRef): string | null {\n switch (ref.kind) {\n case 'model':\n return ref.name;\n case 'array':\n return ref.items.kind === 'model' ? ref.items.name : null;\n case 'nullable':\n return extractModelName(ref.inner);\n case 'union': {\n const firstModel = ref.variants.find((v) => v.kind === 'model');\n return firstModel && firstModel.kind === 'model' ? firstModel.name : null;\n }\n case 'map':\n case 'enum':\n case 'primitive':\n case 'literal':\n return null;\n default:\n return assertNever(ref);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAuLA,SAAgB,qBAAkC;AAChD,QAAO;EACL,OAAO;GACL,sBAAsB;IAAC;IAAK;IAAK;IAAK;IAAK;IAAI;GAC/C,YAAY;GACZ,wBAAwB;GACxB,gBAAgB;GAChB,SAAS;IACP,cAAc;IACd,YAAY;IACZ,UAAU;IACV,cAAc;IACf;GACF;EACD,QAAQ;GACN,eAAe;IACb,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACN;GACD,iBAAiB;GACjB,iBAAiB;GACjB,qBAAqB;GACtB;EACD,WAAW;GACT,kBAAkB;GAClB,YAAY;GACZ,iBAAiB;GAClB;EACD,YAAY,EACV,iBAAiB,GAClB;EACD,aAAa;GACX,YAAY;GACZ,qBAAqB;GACtB;EACD,SAAS;GACP,SAAS;GACT,QAAQ;IACN;IACA;IACA;IACA;IACA;IACA;IACD;GACF;EACD,WAAW;GACT,uBAAuB;GACvB,uBAAuB;GACvB,cAAc;GACd,gBAAgB;IACd;KAAE,QAAQ;KAAe,WAAW;KAAc;IAClD;KAAE,QAAQ;KAAgB,WAAW;KAAU;IAC/C;KAAE,QAAQ;KAAgB,WAAW;KAAS;IAC9C;KAAE,QAAQ;KAAmB,WAAW;KAAY;IACpD;KAAE,QAAQ;KAAiB,WAAW;KAAW;IAClD;GACF;EACD,cAAc,EACZ,YAAY;GACV;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,EACF;EACD,SAAS,EACP,uBAAuB,IACxB;EACF;;;;;;;AAmBH,SAAgB,iBAAiB,WAAkD;AACjF,QAAO,UACL,oBAAoB,EACpB,UACD;;;;;;;AAQH,SAAS,UAAU,QAAiC,QAA0D;CAC5G,MAAM,SAAkC,EAAE,GAAG,QAAQ;AACrD,MAAK,MAAM,OAAO,OAAO,KAAK,OAAO,EAAE;EACrC,MAAM,YAAY,OAAO;EACzB,MAAM,YAAY,OAAO;AACzB,MAAI,cAAc,KAAA,EAAW;AAC7B,MACE,cAAc,QACd,OAAO,cAAc,YACrB,CAAC,MAAM,QAAQ,UAAU,IACzB,cAAc,QACd,OAAO,cAAc,YACrB,CAAC,MAAM,QAAQ,UAAU,CAEzB,QAAO,OAAO,UAAU,WAAsC,UAAqC;MAEnG,QAAO,OAAO;;AAGlB,QAAO;;;;AC9ST,eAAsB,kBAAkB,UAAwC;CAC9E,MAAM,eAAe,QAAQ,SAAS;CAOtC,MAAM,SAAS,MAAM,eAAe;EAClC,UANe,uBADD,MAAM,SAAS,cAAc,QAAQ,EACJ,cAAc,aAAa,CAAC,KAAK;EAOhF,QALa,MAAM,aAAa,EAAE,CAAC;EAMnC,OAAO;EACP,qBANe,IAAI,cAAc;EAOjC,aAAa;EACd,CAAC;AAEF,KAAI,OAAO,SAAS,MAAM,MAAM,EAAE,aAAa,QAAQ,CAKrD,OAAM,IAAI,eACR,yBALa,OAAO,SACnB,QAAQ,MAAM,EAAE,aAAa,QAAQ,CACrC,KAAK,MAAM,EAAE,QAAQ,CACrB,KAAK,KAAK,IAGX,8BAA8B,aAAa,oEAAoE,SAAS,wBACzH;AAGH,QAAO;EACL,QAAQ,OAAO,OAAO;EACtB,UAAU;EACX;;;;;;;;;;AC9BH,SAAgB,uBAAuB,UAAkB,YAA6B;AACpF,KAAI,CAAC,WAAY,QAAO;CAIxB,MAAM,cAAc,qBAAqB,WAAW;AACpD,KAAI,SAAS,WAAW,YAAY,CAAE,QAAO;CAG7C,MAAM,gBAAgB,SAAS,MAAM,uBAAuB;AAC5D,KAAI,eAAe;EACjB,MAAM,GAAG,QAAQ,gBAAgB;AAEjC,SAAO,GAAG,cAAc,SADP,YAAY,aAAa;;AAG5C,QAAO,GAAG,cAAc;;;;;;;AAQ1B,SAAgB,+BAA+B,SAA4D;AACzG,KAAI,CAAC,QAAS,QAAO,EAAE;CAEvB,MAAM,eAAwB,EAAE;AAEhC,MAAK,MAAM,CAAC,YAAY,WAAW,OAAO,QAAQ,QAAQ,CAExD,mCAAkC,QAAQ,cADvB,gBAAgB,aAAa,WAAW,CAAC,CACO;AAGrE,QAAO;;AAGT,SAAS,kCAAkC,QAAsB,SAAkB,YAA2B;CAC5G,MAAM,aAAa,OAAO,cAAc,EAAE;CAC1C,MAAM,eAAe,OAAO,SAAS,EAAE;AAEvC,MAAK,MAAM,OAAO,aAChB,KAAI,IAAI,WACN,mCAAkC,KAAK,SAAS,WAAW;AAI/D,MAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,WAAW,EAAE;AACjE,MAAI,CAAC,YAAa;AAElB,MAAI,YAAY,eAAe,YAAY,SAAS,YAAY,CAAC,YAAY,OAAO;GAElF,MAAM,YAAY,uBADD,aAAa,UAAU,EACW,WAAW;AAC9D,WAAQ,KAAK,iBAAiB,WAAW,YAAY,CAAC;AACtD,qCAAkC,aAAa,SAAS,UAAU;;AAIpE,MAAI,YAAY,SAAS,WAAW,YAAY,OAAO;GACrD,MAAM,QAAQ,YAAY;AAC1B,OAAI,MAAM,eAAe,MAAM,SAAS,YAAY,CAAC,MAAM,OAAO;IAEhE,MAAM,YAAY,uBADD,aAAa,UAAU,EACW,WAAW;AAC9D,YAAQ,KAAK,iBAAiB,WAAW,MAAM,CAAC;AAChD,sCAAkC,OAAO,SAAS,UAAU;;;AAMhE,MAAI,YAAY,OAAO;GACrB,MAAM,gBAAgB,YAAY,MAAM,MAAM,MAAM,EAAE,eAAe,EAAE,SAAS,YAAY,CAAC,EAAE,MAAM;AACrG,OAAI,eAAe;IAEjB,MAAM,YAAY,uBADD,aAAa,UAAU,EACW,WAAW;AAE9D,QAAI,CADkB,IAAI,IAAI,QAAQ,KAAK,MAAM,EAAE,KAAK,CAAC,CACtC,IAAI,UAAU,EAAE;AACjC,aAAQ,KAAK,iBAAiB,WAAW,cAAc,CAAC;AACxD,uCAAkC,eAAe,SAAS,UAAU;;;;;;AAO9E,SAAS,iBAAiB,MAAc,QAA6B;CACnE,MAAM,cAAc,IAAI,IAAI,OAAO,YAAY,EAAE,CAAC;CAClD,MAAM,SAAkB,EAAE;AAE1B,MAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,OAAO,cAAc,EAAE,CAAC,EAAE;AAC9E,MAAI,CAAC,YAAa;AAClB,SAAO,KAAK,qBAAqB,WAAW,aAAa,MAAM,YAAY,CAAC;;AAG9E,QAAO;EAAE;EAAM,aAAa,OAAO;EAAa;EAAQ;;;;;;;;AChG1D,IAAI,4BAA+D;;AAGnE,SAAS,kBAAkB,SAAyB;CAClD,IAAI,OAAO,gBAAgB,aAAa,QAAQ,CAAC;AACjD,KAAI,0BAA2B,QAAO,0BAA0B,KAAK;AACrE,QAAO;;AAqCT,SAAgB,eACd,SACA,SACkB;CAClB,MAAM,QAAgB,EAAE;AAExB,KAAI,CAAC,QAAS,QAAO;EAAE,QAAQ,EAAE;EAAE;EAAO;AAG1C,KAAI,SAAS,qBAAqB;EAChC,MAAM,YAAY,QAAQ;EAE1B,MAAM,eADW,OAAO,KAAK,QAAQ,CACP,KAAK,MAAM,gBAAgB,aAAa,EAAE,CAAC,CAAC;EAC1E,MAAM,yCAAyB,IAAI,KAAuB;AAC1D,OAAK,MAAM,WAAW,cAAc;GAClC,MAAM,cAAc,UAAU,QAAQ;AACtC,OAAI,CAAC,uBAAuB,IAAI,YAAY,CAAE,wBAAuB,IAAI,aAAa,EAAE,CAAC;AACzF,0BAAuB,IAAI,YAAY,CAAE,KAAK,QAAQ;;EAExD,MAAM,oCAAoB,IAAI,KAAa;AAC3C,OAAK,MAAM,GAAG,cAAc,uBAC1B,KAAI,UAAU,SAAS,EACrB,MAAK,MAAM,KAAK,UAAW,mBAAkB,IAAI,EAAE;AAGvD,+BAA6B,SAAkB,kBAAkB,IAAI,KAAK,GAAG,OAAO,UAAU,KAAK;OAEnG,6BAA4B;CAG9B,MAAM,oCAAoB,IAAI,KAAoB;AAElD,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,QAAQ,EAAE;EACpD,MAAM,aAAa,kBAAkB,KAAK;AAE1C,MAAI,OAAO,KACT,OAAM,KAAK,YAAY,YAAY,OAAO,CAAC;OACtC;GACL,MAAM,QAAQ,aAAa,YAAY,QAAQ,QAAQ;GACvD,MAAM,WAAW,kBAAkB,IAAI,WAAW;AAClD,OAAI;QAEE,MAAM,OAAO,SAAS,SAAS,OAAO,OACxC,mBAAkB,IAAI,YAAY,MAAM;SAG1C,mBAAkB,IAAI,YAAY,MAAM;AAG1C,QAAK,MAAM,eAAe,uCAAuC,QAAQ,WAAW,EAAE;IACpF,MAAM,iBAAiB,kBAAkB,IAAI,YAAY,KAAK;AAC9D,QAAI;SACE,YAAY,OAAO,SAAS,eAAe,OAAO,OACpD,mBAAkB,IAAI,YAAY,MAAM,YAAY;UAGtD,mBAAkB,IAAI,YAAY,MAAM,YAAY;;;;CAM5D,MAAM,SAAS,CAAC,GAAG,kBAAkB,QAAQ,CAAC;CAI9C,MAAM,aAAa,IAAI,IAAI,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC;CACrD,MAAM,cAAuB,CAAC,GAAG,OAAO;AACxC,QAAO,YAAY,SAAS,GAAG;EAC7B,MAAM,QAAQ,YAAY,KAAK;AAC/B,OAAK,MAAM,SAAS,MAAM,OACxB,2BAA0B,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,WAAW,EAAE,EAAE,QAAQ,YAAY,YAAY;;AAKjH,MAAK,MAAM,SAAS,OAClB,oBAAmB,MAAM,QAAQ,MAAM;AAOzC,QAAO;EAAE;EAAQ;EAAO;;;AAI1B,SAAgB,2BAAiC;AAC/C,6BAA4B;;;;;;AAO9B,SAAgB,yBAAyB,KAAc,OAAe,MAAyB;AAC7F,aAAY,KAAK,EACf,OAAO,MAAM;AACX,MAAI,EAAE,UAAU,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE;AACjC,QAAK,IAAI,EAAE,KAAK;AAChB,SAAM,KAAK;IACT,MAAM,EAAE;IACR,QAAQ,EAAE,OAAO,KAAK,OAAO;KAC3B,MAAM,iBAAiB,OAAO,EAAE,CAAC;KACjC,OAAO;KACP,aAAa,KAAA;KACd,EAAE;IACJ,CAAC;;IAGP,CAAC;;;;;;AAOJ,SAAS,mBAAmB,QAAiB,OAAqB;CAChE,MAAM,OAAO,IAAI,IAAI,MAAM,KAAK,MAAM,EAAE,KAAK,CAAC;AAC9C,MAAK,MAAM,SAAS,OAClB,0BAAyB,MAAM,MAAM,OAAO,KAAK;;;;;;;;AAUrD,SAAS,0BACP,KACA,WACA,iBACA,SACA,QACA,YACA,OACM;AACN,aAAY,KAAK,EACf,QAAQ,aAAa;AACnB,MAAI,WAAW,IAAI,SAAS,KAAK,CAAE;AAInC,MADoB,OAAO,KAAK,QAAQ,CAAC,MAAM,MAAM,kBAAkB,EAAE,KAAK,SAAS,KAAK,CAC3E;EAIjB,MAAM,eAAe,iBAAiB,iBAAiB,QAAQ;AAC/D,MAAI,CAAC,aAAc;EAEnB,MAAM,cAAc,sBAAsB,WAAW,cAAc,QAAQ;AAC3E,MAAI,CAAC,YAAa;EAGlB,MAAM,YAAY,oBAAoB,SAAS,MAAM,YAAY;AACjE,OAAK,MAAM,KAAK,UACd,KAAI,CAAC,WAAW,IAAI,EAAE,KAAK,EAAE;AAC3B,UAAO,KAAK,EAAE;AACd,cAAW,IAAI,EAAE,KAAK;AACtB,SAAM,KAAK,EAAE;;IAIpB,CAAC;;;AAIJ,SAAS,iBAAiB,YAAoB,SAA4D;AACxG,MAAK,MAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,QAAQ,CAC1C,KAAI,kBAAkB,EAAE,KAAK,WAAY,QAAO;AAElD,QAAO;;;AAIT,SAAS,sBACP,WACA,cACA,SACqB;AACrB,KAAI,aAAa,aAAa,WAC5B,QAAO,aAAa,WAAW;AAEjC,KAAI,aAAa,MACf,MAAK,MAAM,OAAO,aAAa,OAAO;EACpC,IAAI,WAAW;AACf,MAAI,IAAI,MAAM;GACZ,MAAM,WAAW,IAAI,KAAK,MAAM,IAAI;GACpC,MAAM,UAAU,SAAS,SAAS,SAAS;AAC3C,OAAI,WAAW,QAAQ,SAAU,YAAW,QAAQ;;AAEtD,MAAI,SAAS,aAAa,WACxB,QAAO,SAAS,WAAW;;AAMjC,MAAK,MAAM,WAAW,CAAC,GAAI,aAAa,SAAS,EAAE,EAAG,GAAI,aAAa,SAAS,EAAE,CAAE,EAAE;EACpF,IAAI,WAAW;AACf,MAAI,QAAQ,MAAM;GAChB,MAAM,WAAW,QAAQ,KAAK,MAAM,IAAI;GACxC,MAAM,UAAU,SAAS,SAAS,SAAS;AAC3C,OAAI,WAAW,QAAQ,SAAU,YAAW,QAAQ;;AAEtD,MAAI,SAAS,aAAa,WACxB,QAAO,SAAS,WAAW;;AAG/B,QAAO;;;AAIT,SAAS,oBAAoB,MAAc,QAA+B;AAExE,KAAI,OAAO,OAAO;EAChB,MAAM,SAAkB,EAAE;AAC1B,OAAK,MAAM,WAAW,OAAO,OAAO;AAClC,OAAI,QAAQ,KAAM;AAClB,OAAI,QAAQ,eAAe,QAAQ,SAAS,YAAY,CAAC,QAAQ,OAAO;IACtE,MAAM,cAAc,IAAI,IAAI,QAAQ,YAAY,EAAE,CAAC;IACnD,MAAM,SAAkB,EAAE;AAC1B,SAAK,MAAM,CAAC,IAAI,OAAO,OAAO,QAAQ,QAAQ,WAAW,EAAE;AACzD,SAAI,CAAC,GAAI;AACT,YAAO,KAAK,qBAAqB,IAAI,IAAI,MAAM,YAAY,CAAC;;IAG9D,MAAM,cAAc,OAAO,WAAW,IAAI,OAAO,GAAG,OAAO,OAAO,SAAS;AAC3E,WAAO,KAAK;KAAE,MAAM;KAAa,aAAa,QAAQ;KAAa;KAAQ,CAAC;;;AAGhF,SAAO;;AAIT,KAAI,OAAO,eAAe,OAAO,SAAS,YAAY,CAAC,OAAO,OAAO;EACnE,MAAM,cAAc,IAAI,IAAI,OAAO,YAAY,EAAE,CAAC;EAClD,MAAM,SAAkB,EAAE;AAC1B,OAAK,MAAM,CAAC,IAAI,OAAO,OAAO,QAAQ,OAAO,WAAW,EAAE;AACxD,OAAI,CAAC,GAAI;AACT,UAAO,KAAK,qBAAqB,IAAI,IAAI,MAAM,YAAY,CAAC;;AAE9D,SAAO,CAAC;GAAE;GAAM,aAAa,OAAO;GAAa;GAAQ,CAAC;;AAI5D,KAAI,OAAO,SAAS,WAAW,OAAO,OAAO,YAAY;EACvD,MAAM,cAAc,IAAI,IAAI,OAAO,MAAM,YAAY,EAAE,CAAC;EACxD,MAAM,SAAkB,EAAE;AAC1B,OAAK,MAAM,CAAC,IAAI,OAAO,OAAO,QAAQ,OAAO,MAAM,WAAW,EAAE;AAC9D,OAAI,CAAC,GAAI;AACT,UAAO,KAAK,qBAAqB,IAAI,IAAI,MAAM,YAAY,CAAC;;AAE9D,SAAO,CAAC;GAAE;GAAM,aAAa,OAAO,MAAM;GAAa;GAAQ,CAAC;;AAGlE,QAAO,EAAE;;;AAIX,SAAgB,qBACd,WACA,aACA,aACA,aACO;AACP,QAAO;EACL,MAAM;EACN,MAAM,gBAAgB,aAAa,WAAW,YAAY;EAC1D,UAAU,YAAY,IAAI,UAAU;EACpC,aAAa,YAAY;EACzB,UAAU,YAAY,YAAY,KAAA;EAClC,WAAW,YAAY,aAAa,KAAA;EACpC,YAAY,YAAY,cAAc,KAAA;EACtC,SAAS,YAAY;EACrB,SAAS,YAAY;EACtB;;;;;;;;AASH,SAAS,2BAA2B,UAA2C;AAC7E,KAAI,SAAS,WAAW,EAAG,QAAO;CAClC,MAAM,SAAmB,EAAE;AAC3B,MAAK,MAAM,KAAK,UAAU;AAExB,MAAI,OAAO,EAAE,UAAU,UAAU;AAC/B,UAAO,KAAK,EAAE,MAAM;AACpB;;AAEF,MAAI,MAAM,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,WAAW,KAAK,OAAO,EAAE,KAAK,OAAO,UAAU;AACjF,UAAO,KAAK,EAAE,KAAK,GAAG;AACtB;;AAEF,SAAO;;AAET,QAAO;;;AAIT,SAAS,sBACP,QACA,aACA,iBACS;CACT,MAAM,WAAW,aAAa,eAAe,cAAc;CAC3D,MAAM,cAAc,kBAAkB,qBAAqB,gBAAgB,GAAG,KAAA;AAE9E,QAAO;EAAE,MAAM;EAAQ,MADD,eAAe,CAAC,SAAS,WAAW,YAAY,GAAG,GAAG,cAAc,aAAa;EAC3D;EAAQ;;;;;;;;;;;;;;;AAgBtD,SAAS,iCACP,UAC8D;AAC9D,KAAI,SAAS,SAAS,EAAG,QAAO;CAGhC,IAAI,oBAAmC;CACvC,MAAM,aAAa,OAAO,KAAK,SAAS,IAAI,cAAc,EAAE,CAAC;AAC7D,MAAK,MAAM,YAAY,WACrB,KAAI,SAAS,OAAO,MAAM,sBAAsB,GAAG,SAAS,KAAK,KAAK,EAAE;AACtE,sBAAoB;AACpB;;AAIJ,KAAI,CAAC,kBAAmB,QAAO;CAE/B,MAAM,UAAkC,EAAE;AAC1C,MAAK,MAAM,KAAK,UAAU;EACxB,MAAM,QAAQ,sBAAsB,GAAG,kBAAkB;AACzD,MAAI,UAAU,KAAM,QAAO;EAE3B,MAAM,cAAc,wBAAwB,EAAE;AAC9C,MAAI,CAAC,YAAa,QAAO;AACzB,UAAQ,SAAS;;AAGnB,QAAO;EAAE,UAAU;EAAmB;EAAS;;AAGjD,SAAS,sBAAsB,QAAsB,UAAiC;CACpF,MAAM,OAAO,OAAO,aAAa;AACjC,KAAI,CAAC,KAAM,QAAO;AAClB,KAAI,OAAO,KAAK,UAAU,SAAU,QAAO,KAAK;AAChD,KAAI,MAAM,QAAQ,KAAK,KAAK,IAAI,KAAK,KAAK,WAAW,KAAK,OAAO,KAAK,KAAK,OAAO,SAChF,QAAO,KAAK,KAAK;AAEnB,QAAO;;AAGT,SAAS,wBAAwB,QAAqC;AACpE,KAAI,OAAO,KACT,QAAO,kBAAkB,OAAO,KAAK,QAAQ,6BAA6B,GAAG,CAAC;CAEhF,MAAM,QAAQ,OAAO,OAAO,aAAa,WAAY,OAAO,WAAsB;AAClF,KAAI,MAAO,QAAO,kBAAkB,MAAM;AAC1C,QAAO;;AAGT,SAAS,YAAY,MAAc,QAA4B;AAO7D,QAAO;EAAE;EAAM,SANc,OAAO,QAAQ,EAAE,EAAE,KAAK,OAAO;GAC1D,MAAM,iBAAiB,OAAO,EAAE,CAAC;GACjC,OAAO,OAAO,MAAM,WAAW,IAAI,OAAO,EAAE;GAC5C,aAAa,KAAA;GACd,EAAE;EAEoB;;AAEzB,SAAS,aAAa,MAAc,QAAsB,SAA+C;AACvG,KAAI,OAAO,MACT,QAAO,kBAAkB,MAAM,QAAQ,QAAQ;CAGjD,MAAM,cAAc,IAAI,IAAI,OAAO,YAAY,EAAE,CAAC;CAClD,MAAM,SAAkB,EAAE;AAE1B,MAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,OAAO,cAAc,EAAE,CAAC,EAAE;AAC9E,MAAI,CAAC,YAAa;AAClB,SAAO,KAAK,qBAAqB,WAAW,aAAa,MAAM,YAAY,CAAC;;AAM9E,KAAI,OAAO,WAAW,MAAM,OAAO,SAAS,OAAO,QAAQ;EACzD,MAAM,WAAW,OAAO,SAAS,OAAO,SAAS,EAAE;EACnD,MAAM,gCAAgB,IAAI,KAAa;EACvC,MAAM,iCAAiB,IAAI,KAAa;AACxC,OAAK,MAAM,WAAW,UAAU;AAC9B,OAAI,CAAC,QAAQ,WAAY;AACzB,QAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,QAAQ,WAAW,EAAE;AACzE,QAAI,CAAC,eAAe,eAAe,IAAI,UAAU,CAAE;AACnD,mBAAe,IAAI,UAAU;AAC7B,WAAO,KAAK,qBAAqB,WAAW,aAA6B,MAAM,cAAc,CAAC;;;;AAOpG,KAAI,OAAO,wBAAwB,OAAO,OAAO,yBAAyB,YAAY,OAAO;MAC5E,OAAO,KAAK,OAAO,qBAAqB,CAC5C,SAAS,GAAG;GACrB,MAAM,YAAY,gBAAgB,OAAO,sBAAsC,wBAAwB,KAAK;AAC5G,UAAO,KAAK;IACV,MAAM;IACN,MAAM;KAAE,MAAM;KAAO;KAAW;IAChC,UAAU;IACV,aAAa;IACd,CAAC;;;AAIN,QAAO;EAAE;EAAM,aAAa,OAAO;EAAa;EAAQ;;AAG1D,SAAS,kBAAkB,MAAc,QAAsB,SAA+C;CAC5G,MAAM,SAAkB,EAAE;CAC1B,MAAM,8BAAc,IAAI,KAAa;CACrC,IAAI;AAEJ,MAAK,MAAM,aAAa,OAAO,SAAS,EAAE,EAAE;EAE1C,IAAI,WAAW;AACf,MAAI,UAAU,QAAQ,SAAS;GAC7B,MAAM,WAAW,UAAU,KAAK,MAAM,IAAI;GAC1C,MAAM,UAAU,SAAS,SAAS,SAAS;AAC3C,OAAI,WAAW,QAAQ,SACrB,YAAW,QAAQ;;AAKvB,MAAI,SAAS,OAAO;GAClB,MAAM,SAAS,kBAAkB,MAAM,UAAU,QAAQ;AACzD,QAAK,MAAM,KAAK,OAAO,QAAQ;AAC7B,WAAO,KAAK;KAAE,GAAG;KAAG,UAAU;KAAO,CAAC;AACtC,QAAI,EAAE,SAAU,aAAY,IAAI,EAAE,KAAK;;aAEhC,SAAS,SAAS,SAAS,OAAO;GAC3C,MAAM,WAAW,SAAS,SAAS,SAAS,SAAS,EAAE;GAKvD,MAAM,oBAAoB,gCAAgC,UAAU,KAAK;AACzE,OAAI,kBACF,uBAAsB;QACjB;IAIL,MAAM,gCAAgB,IAAI,KAAa;IACvC,MAAM,iBAAiB,IAAI,IAAI,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC;AACzD,SAAK,MAAM,WAAW,UAAU;AAC9B,SAAI,CAAC,QAAQ,WAAY;AACzB,UAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,QAAQ,WAAW,EAAE;AACzE,UAAI,CAAC,eAAe,eAAe,IAAI,UAAU,CAAE;AACnD,qBAAe,IAAI,UAAU;AAC7B,aAAO,KAAK,qBAAqB,WAAW,aAA6B,MAAM,cAAc,CAAC;;;;SAO/F;AACL,OAAI,SAAS,SACX,MAAK,MAAM,KAAK,SAAS,SAAU,aAAY,IAAI,EAAE;AAEvD,OAAI,SAAS,YAAY;IAEvB,MAAM,gCAAgB,IAAI,KAAa;AACvC,SAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,SAAS,WAAW,EAAE;AAC1E,SAAI,CAAC,YAAa;AAClB,YAAO,KAAK,qBAAqB,WAAW,aAAa,MAAM,cAAc,CAAC;;;;;AAOtF,KAAI,OAAO,SACT,MAAK,MAAM,KAAK,OAAO,SAAU,aAAY,IAAI,EAAE;AAIrD,MAAK,MAAM,KAAK,OACd,GAAE,WAAW,YAAY,IAAI,EAAE,KAAK;AAGtC,QAAO;EACL;EACA,aAAa,OAAO;EACpB;EACA,GAAI,sBAAsB,EAAE,eAAe,qBAAqB,GAAG,EAAE;EACtE;;;;;;;;;;;;AAaH,SAAS,gCACP,UACA,cAC8D;AAC9D,KAAI,SAAS,SAAS,EAAG,QAAO;CAGhC,MAAM,aAAa,OAAO,KAAK,SAAS,IAAI,cAAc,EAAE,CAAC;CAC7D,IAAI,oBAAmC;AACvC,MAAK,MAAM,YAAY,WACrB,KAAI,SAAS,OAAO,MAAM,sBAAsB,GAAG,SAAS,KAAK,KAAK,EAAE;AACtE,sBAAoB;AACpB;;AAGJ,KAAI,CAAC,kBAAmB,QAAO;CAE/B,MAAM,UAAkC,EAAE;CAC1C,MAAM,iCAAiB,IAAI,KAAa;AACxC,MAAK,MAAM,KAAK,UAAU;EACxB,MAAM,QAAQ,sBAAsB,GAAG,kBAAkB;AACzD,MAAI,UAAU,KAAM,QAAO;EAC3B,MAAM,YAAY,+BAA+B,GAAG,aAAa;AAEjE,MAAI,eAAe,IAAI,UAAU,CAAE,QAAO;AAC1C,iBAAe,IAAI,UAAU;AAC7B,UAAQ,SAAS;;AAGnB,QAAO;EAAE,UAAU;EAAmB;EAAS;;AAGjD,SAAS,uCAAuC,QAAsB,cAA+B;CACnG,MAAM,SAAkB,EAAE;CAC1B,MAAM,4BAAY,IAAI,KAAa;AAEnC,MAAK,MAAM,aAAa,OAAO,SAAS,EAAE,CACxC,MAAK,MAAM,WAAW,UAAU,SAAS,EAAE,EAAE;AAC3C,MAAI,CAAC,QAAQ,cAAe,QAAQ,SAAS,KAAA,KAAa,QAAQ,SAAS,SAAW;EAEtF,MAAM,cAAc,+BAA+B,SAAS,aAAa;AACzE,OAAK,MAAM,SAAS,uBAAuB,aAAa,QAAQ,EAAE;AAChE,OAAI,UAAU,IAAI,MAAM,KAAK,CAAE;AAC/B,aAAU,IAAI,MAAM,KAAK;AACzB,UAAO,KAAK,MAAM;;;AAKxB,QAAO;;AAGT,SAAS,+BAA+B,QAAsB,cAA8B;AAC1F,KAAI,CAAC,OAAO,WAAY,QAAO;AAG/B,MAAK,MAAM,QADO;EAAC;EAAS;EAAQ;EAAS,EACf;EAC5B,MAAM,QAAQ,OAAO,WAAW;AAChC,MAAI,CAAC,MAAO;AACZ,MAAI,OAAO,MAAM,UAAU,SACzB,QAAO,aAAa,MAAM,MAAM;AAElC,MAAI,MAAM,QAAQ,MAAM,KAAK,WAAW,KAAK,OAAO,MAAM,KAAK,OAAO,SACpE,QAAO,aAAa,MAAM,KAAK,GAAG;;AAItC,MAAK,MAAM,SAAS,OAAO,OAAO,OAAO,WAAW,EAAE;AACpD,MAAI,CAAC,MAAO;AACZ,MAAI,OAAO,MAAM,UAAU,SACzB,QAAO,aAAa,MAAM,MAAM;AAElC,MAAI,MAAM,QAAQ,MAAM,KAAK,WAAW,KAAK,OAAO,MAAM,KAAK,OAAO,SACpE,QAAO,aAAa,MAAM,KAAK,GAAG;;AAItC,QAAO;;AAGT,SAAS,uBAAuB,MAAc,QAA+B;CAC3E,MAAM,cAAc,IAAI,IAAI,OAAO,YAAY,EAAE,CAAC;CAClD,MAAM,SAAkB,EAAE;CAC1B,MAAM,aAAa,OAAO,cAAc,EAAE;CAC1C,MAAM,eAAwB,EAAE;AAEhC,MAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,WAAW,EAAE;AACjE,MAAI,CAAC,YAAa;AAClB,SAAO,KAAK,qBAAqB,WAAW,aAAa,MAAM,YAAY,CAAC;AAE5E,MAAI,YAAY,SAAS,YAAY,YAAY,WAC/C,cAAa,KAAK,GAAG,uBAAuB,wBAAwB,MAAM,UAAU,EAAE,YAAY,CAAC;AAGrG,MAAI,YAAY,SAAS,WAAW,YAAY,OAAO,WACrD,cAAa,KAAK,GAAG,uBAAuB,wBAAwB,MAAM,UAAU,EAAE,YAAY,MAAM,CAAC;AAG3G,MAAI,YAAY,OAAO;GACrB,MAAM,mBAA6D,EAAE;GACrE,MAAM,iBAA2B,EAAE;AACnC,QAAK,MAAM,OAAO,YAAY,OAAO;AACnC,QAAI,IAAI,WAAY,QAAO,OAAO,kBAAkB,IAAI,WAAW;AACnE,QAAI,IAAI,SAAU,gBAAe,KAAK,GAAG,IAAI,SAAS;;AAExD,OAAI,OAAO,KAAK,iBAAiB,CAAC,SAAS,EACzC,cAAa,KACX,GAAG,uBAAuB,wBAAwB,MAAM,UAAU,EAAE;IAClE,MAAM;IACN,YAAY;IACZ,UAAU;IACX,CAAC,CACH;;AAIL,MAAI,YAAY,OAAO;GACrB,MAAM,gBAAgB,YAAY,MAAM,MAAM,MAAM,EAAE,eAAe,EAAE,SAAS,YAAY,CAAC,EAAE,MAAM;AACrG,OAAI,cACF,cAAa,KAAK,GAAG,uBAAuB,wBAAwB,MAAM,UAAU,EAAE,cAAc,CAAC;;;AAK3G,QAAO,CAAC;EAAE;EAAM,aAAa,OAAO;EAAa;EAAQ,EAAE,GAAG,aAAa;;AAG7E,SAAS,wBAAwB,YAAoB,WAA2B;CAC9E,MAAM,cAAc,aAAa,UAAU;AAC3C,KAAI,YAAY,WAAW,WAAW,CAAE,QAAO;CAG/C,MAAM,YAAY,GADE,qBAAqB,WAAW,GACjB;CACnC,MAAM,QAAQ,UAAU,MAAM,yBAAyB;AACvD,KAAI,SAAS,MAAM,GACjB,QAAO,MAAM,KAAK,YAAY,MAAM,GAAG;AAEzC,QAAO;;AAGT,SAAgB,gBAAgB,QAAsB,aAAsB,iBAAmC;AAE7G,KAAI,OAAO,MAAM;EACf,MAAM,WAAW,OAAO,KAAK,MAAM,IAAI;EACvC,MAAM,UAAU,SAAS,SAAS,SAAS;AAC3C,SAAO;GAAE,MAAM;GAAS,MAAM,kBAAkB,QAAQ;GAAE;;AAI5D,KAAI,MAAM,QAAQ,OAAO,KAAK,EAAE;EAC9B,MAAM,eAAe,OAAO,KAAK,QAAQ,MAAc,MAAM,OAAO;AAEpE,MAAI,aAAa,WAAW,EAC1B,QAAO;GAAE,MAAM;GAAY,OAAO;IAAE,MAAM;IAAa,MAAM;IAAW;GAAE;AAE5E,MAAI,OAAO,KAAK,SAAS,OAAO,IAAI,aAAa,WAAW,EAC1D,QAAO;GACL,MAAM;GACN,OAAO,gBAAgB;IAAE,GAAG;IAAQ,MAAM,aAAa;IAAI,UAAU;IAAO,EAAE,YAAY;GAC3F;AAGH,MAAI,aAAa,SAAS,GAAG;GAE3B,MAAM,MAAe;IAAE,MAAM;IAAS,UADrB,aAAa,KAAK,MAAc,gBAAgB;KAAE,GAAG;KAAQ,MAAM;KAAG,EAAE,YAAY,CAAC;IACtD;AAChD,OAAI,OAAO,KAAK,SAAS,OAAO,CAC9B,QAAO;IAAE,MAAM;IAAY,OAAO;IAAK;AAEzC,UAAO;;;AAKX,KAAI,OAAO,YAAY,OAAO,KAC5B,QAAO;EACL,MAAM;EACN,OAAO,gBAAgB;GAAE,GAAG;GAAQ,UAAU;GAAO,EAAE,YAAY;EACpE;AAMH,KAAI,OAAO,OAAO;EAEhB,MAAM,UAAU,OAAO,MAAM,MAAM,MAAoB,EAAE,KAAK;AAC9D,MAAI,SAAS;AAIX,OADwB,OAAO,MAAM,MAAM,MAAoB,CAAC,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,UAAU,CAG9G,QAAO;IAAE,MAAM;IAAS,MAAM,uBADb,aAAa,eAAe,eAAe,EACG,gBAAgB;IAAE;AAEnF,UAAO,gBAAgB,SAAS,aAAa,gBAAgB;;AAG/D,MAAI,OAAO,MAAM,WAAW,EAC1B,QAAO,gBAAgB,OAAO,MAAM,IAAI,aAAa,gBAAgB;AAIvE,MADsB,OAAO,MAAM,MAAM,MAAoB,EAAE,WAAW,CAGxE,QAAO;GACL,MAAM;GACN,MAAM,uBAHS,aAAa,eAAe,eAAe,EAGnB,gBAAgB;GACxD;;AAQL,KAAI,OAAO,SAAS,OAAO,OAAO;EAChC,MAAM,kBAAqC,OAAO,QAAQ,UAAU;EACpE,MAAM,cAA8B,OAAO,SAAS,OAAO,SAAS,EAAE;EAGtE,MAAM,cAAc,YAAY,MAC7B,MAAoB,EAAE,SAAS,UAAW,MAAM,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,WAAW,KAAK,EAAE,KAAK,OAAO,OAC1G;EACD,MAAM,kBAAkB,YAAY,QAAQ,MAAM,MAAM,YAAY;AAEpE,MAAI,eAAe,gBAAgB,WAAW,EAE5C,QAAO;GACL,MAAM;GACN,OAAO,gBAAgB,gBAAgB,IAAI,aAAa,gBAAgB;GACzE;EAQH,MAAM,iBAAiB,2BAA2B,gBAAgB;AAClE,MAAI,mBAAmB,QAAQ,eAAe,UAAU,GAAG;GACzD,MAAM,UAAU,sBAAsB,gBAAgB,aAAa,gBAAgB;AACnF,UAAO,cAAc;IAAE,MAAM;IAAY,OAAO;IAAS,GAAG;;EAO9D,MAAM,yBACJ,CAAC,OAAO,iBAAiB,oBAAoB,UAAU,iCAAiC,gBAAgB,GAAG;EAG7G,MAAM,WAAW,YACd,QAAQ,MAAoB,EAAE,SAAS,OAAO,CAC9C,KAAK,MAAoB,gBAAgB,GAAG,aAAa,gBAAgB,CAAC;EAC7E,MAAM,UAAU,CAAC,CAAC;EAClB,MAAM,QAAiB;GACrB,MAAM;GACN;GACA;GACA,GAAI,OAAO,gBACP,EACE,eAAe;IACb,UAAU,OAAO,cAAc;IAC/B,SAAS,OAAO,YACd,OAAO,QAAQ,OAAO,cAAc,WAAW,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,OAAO,CACjE,GACA,EAAE,QAAQ,6BAA6B,GAAG,CAC3C,CAAC,CACH;IACF,EACF,GACD,yBACE,EAAE,eAAe,wBAAwB,GACzC,EAAE;GACT;AACD,SAAO,UAAU;GAAE,MAAM;GAAY,OAAO;GAAO,GAAG;;AAIxD,KAAI,OAAO,UAAU,KAAA,GAAW;AAC9B,MAAI,OAAO,OAAO,UAAU,YAAY,OAAO,OAAO,UAAU,YAAY,OAAO,OAAO,UAAU,UAClG,QAAO;GAAE,MAAM;GAAW,OAAO,OAAO;GAAO;AAGjD,MAAI,OAAO,UAAU,KACnB,QAAO;GAAE,MAAM;GAAY,OAAO;IAAE,MAAM;IAAa,MAAM;IAAW;GAAE;AAG5E,MAAI,OAAO,OAAO,UAAU,UAAU;AACpC,OAAI,MAAM,QAAQ,OAAO,MAAM,CAC7B,QAAO;IAAE,MAAM;IAAS,OAAO;KAAE,MAAM;KAAa,MAAM;KAAW;IAAE;AAEzE,UAAO;IAAE,MAAM;IAAO,WAAW;KAAE,MAAM;KAAa,MAAM;KAAW;IAAE;;;AAG7E,KAAI,OAAO,QAAQ,OAAO,KAAK,WAAW,GAAG;EAC3C,MAAM,IAAI,OAAO,KAAK;AACtB,SAAO;GAAE,MAAM;GAAW,OAAO,OAAO,MAAM,WAAW,IAAI,OAAO,EAAE;GAAE;;AAI1E,KAAI,OAAO,MAAM;EACf,MAAM,WAAW,aAAa,eAAe,cAAc;EAG3D,MAAM,cAAc,kBAAkB,qBAAqB,gBAAgB,GAAG,KAAA;AAG9E,SAAO;GACL,MAAM;GACN,MAHoB,eAAe,CAAC,SAAS,WAAW,YAAY,GAAG,GAAG,cAAc,aAAa;GAIrG,QAAQ,OAAO,KAAK,KAAK,MAAO,OAAO,MAAM,WAAW,IAAI,OAAO,EAAE,CAAE;GACxE;;AAIH,KAAI,OAAO,SAAS,WAAW,OAAO,MACpC,QAAO;EACL,MAAM;EACN,OAAO,gBAAgB,OAAO,OAAO,aAAa,gBAAgB;EACnE;AAGH,KAAI,CAAC,OAAO,QAAQ,OAAO,MACzB,QAAO;EACL,MAAM;EACN,OAAO,gBAAgB,OAAO,OAAO,aAAa,gBAAgB;EACnE;AAOH,KAAI,OAAO,SAAS,YAAY,OAAO,WAErC,QAAO;EACL,MAAM;EACN,MAAM,uBAHS,aAAa,eAAe,eAAe,EAGnB,gBAAgB;EACxD;AAIH,KAAI,OAAO,SAAS,YAAY,CAAC,OAAO,YAAY;EAClD,IAAI,YAAqB;GAAE,MAAM;GAAa,MAAM;GAAW;AAC/D,MAAI,OAAO,wBAAwB,OAAO,OAAO,yBAAyB;OAEzD,OAAO,KAAK,OAAO,qBAAqB,CAC5C,SAAS,EAClB,aAAY,gBAAgB,OAAO,sBAAsC,YAAY;aAE9E,OAAO,mBAAmB;GAEnC,MAAM,WAAW,OAAO,OAAO,OAAO,kBAAkB;AACxD,OAAI,SAAS,SAAS,EACpB,aAAY,gBAAgB,SAAS,IAAI,YAAY;;AAGzD,SAAO;GACL,MAAM;GACN;GACD;;CAIH,MAAM,eAA4E;EAChF,QAAQ;EACR,SAAS;EACT,QAAQ;EACR,SAAS;EACV;CAED,MAAM,UAAU,MAAM,QAAQ,OAAO,KAAK,GAAG,OAAO,KAAK,KAAK,OAAO;AACrE,KAAI,WAAW,aAAa,SAC1B,QAAO;EACL,MAAM;EACN,MAAM,aAAa;EACnB,GAAI,OAAO,SAAS,EAAE,QAAQ,OAAO,QAAQ,GAAG,EAAE;EACnD;AAIH,KAAI,CAAC,OAAO,QAAQ,OAAO,WAEzB,QAAO;EACL,MAAM;EACN,MAAM,uBAHS,aAAa,eAAe,eAAe,EAGnB,gBAAgB;EACxD;AAIH,KACE,CAAC,OAAO,QACR,CAAC,OAAO,QACR,CAAC,OAAO,SACR,CAAC,OAAO,SACR,CAAC,OAAO,SACR,CAAC,OAAO,QACR,CAAC,OAAO,cACR,CAAC,OAAO,MAER,QAAO;EAAE,MAAM;EAAa,MAAM;EAAW;AAI/C,KAAI,YACF,SAAQ,KAAK,sEAAsE,YAAY,GAAG;AAEpG,QAAO;EAAE,MAAM;EAAa,MAAM;EAAW;;;;AC59B/C,MAAM,gBAAgB;CAAC;CAAU;CAAS;CAAU;CAAkB;CAAiB;CAAc;CAAa;AAElH,MAAM,gBAAgB;CAAC;CAAU;CAAQ;CAAe;CAAO;AAC/D,MAAM,eAAe;CAAC;CAAS;CAAa;CAAY;CAAQ;CAAQ;;;;;;;;;;;AAYxE,SAAgB,iBACd,UACA,aACA,UACuB;CAEvB,MAAM,cAAc,YAAY,MAAM,MAAM,cAAc,SAAS,EAAE,KAAK,CAAC;AAE3E,KAAI,aAAa;EACf,MAAM,WAAoB,SAAS,SAAS,UAAU,SAAS,QAAQ;AACvE,SAAO;GACL,UAAU;GACV,OAAO,YAAY;GACT;GACV;GACD;;CAIH,MAAM,cAAc,YAAY,MAAM,MAAM,cAAc,SAAS,EAAE,KAAK,CAAC;CAC3E,MAAM,aAAa,YAAY,MAAM,MAAM,aAAa,SAAS,EAAE,KAAK,CAAC;AAEzE,KAAI,eAAe,YAAY;EAC7B,MAAM,WAAoB,SAAS,SAAS,UAAU,SAAS,QAAQ;AACvE,SAAO;GACL,UAAU;GACV,OAAO,YAAY;GACnB,YAAY,WAAW;GACb;GACV;GACD;;AAGH,QAAO;;;;AChCT,SAAgB,2BAA2B,QAAsB,aAA+C;AAE9G,KAAI,OAAO,KACT,QAAO;EAAE,UAAU,gBAAgB,QAAQ,YAAY;EAAE,cAAc,EAAE;EAAE,aAAa;EAAO;CAIjG,MAAM,WAAW,mBAAmB,OAAO;AAC3C,KAAI,SAAS,WACX,QAAO,oBAAoB,QAAQ,aAAa,SAAS,SAAU;AAIrE,KAAI,wBAAwB,OAAO,CACjC,QAAO,uBAAuB,QAAQ,YAAY;AAIpD,QAAO,sBAAsB,QAAQ,YAAY;;AAQnD,MAAM,mBAAmB,IAAI,IAAI;CAAC;CAAQ;CAAS;CAAW;CAAW;CAAW;CAAU;CAAS;CAAQ,CAAC;AAEhH,MAAM,+BAA+B;CACnC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAS,mBAAmB,QAA0C;CAEpE,MAAM,cAA0D,EAAE;AAClE,KAAI,OAAO;OACJ,MAAM,OAAO,OAAO,MACvB,KAAI,IAAI,WAAY,aAAY,KAAK,IAAI,WAAW;;AAGxD,KAAI,OAAO,WACT,aAAY,KAAK,OAAO,WAAW;AAGrC,KAAI,YAAY,WAAW,EAAG,QAAO;EAAE,YAAY;EAAO,UAAU;EAAM;CAG1E,MAAM,cAAwD,EAAE;AAChE,MAAK,MAAM,UAAU,YACnB,QAAO,OAAO,aAAa,OAAO;CAIpC,MAAM,aAAuB,EAAE;CAC/B,MAAM,eAAyB,EAAE;AAEjC,MAAK,MAAM,CAAC,KAAK,eAAe,OAAO,QAAQ,YAAY,EAAE;AAC3D,MAAI,CAAC,WAAY;AACjB,MAAI,WAAW,SAAS,QACtB,YAAW,KAAK,IAAI;MAEpB,cAAa,KAAK,IAAI;;AAQ1B,KAAI,WAAW,WAAW,KAAK,aAAa,UAAU,GAAG;EACvD,MAAM,gBAAgB,WAAW;EAEjC,MAAM,yBAAyB,aAAa,MAAM,QAChD,6BAA6B,MAAM,YAAY,IAAI,aAAa,CAAC,SAAS,QAAQ,CAAC,CACpF;AAED,MAAI,iBAAiB,IAAI,cAAc,IAAI,uBACzC,QAAO;GAAE,YAAY;GAAM,UAAU;GAAe;AAItD,MAAI,uBACF,QAAO;GAAE,YAAY;GAAM,UAAU;GAAe;;AAIxD,QAAO;EAAE,YAAY;EAAO,UAAU;EAAM;;AAG9C,SAAS,oBAAoB,QAAsB,aAAqB,UAA4C;CAClH,IAAI,cAAuB;EAAE,MAAM;EAAa,MAAM;EAAU;CAChE,MAAM,eAAwB,EAAE;CAGhC,MAAM,cAA0D,EAAE;AAClE,KAAI,OAAO;OACJ,MAAM,OAAO,OAAO,MACvB,KAAI,IAAI,WAAY,aAAY,KAAK,IAAI,WAAW;;AAGxD,KAAI,OAAO,WACT,aAAY,KAAK,OAAO,WAAW;AAGrC,MAAK,MAAM,SAAS,aAAa;EAC/B,MAAM,WAAW,MAAM;AACvB,MAAI,CAAC,SAAU;AAEf,MAAI,SAAS,SAAS,WAAW,SAAS,OAAO;GAC/C,MAAM,QAAQ,SAAS;AACvB,OAAI,MAAM,KACR,eAAc,gBAAgB,OAAO,YAAY;YACxC,MAAM,SAAS,YAAY,MAAM,YAAY;IACtD,MAAM,WAAW,YAAY,QAAQ,aAAa,GAAG,GAAG;AACxD,kBAAc;KAAE,MAAM;KAAS,MAAM;KAAU;AAC/C,iBAAa,KAAK,GAAG,mBAAmB,UAAU,MAAM,CAAC;;;;AAK/D,QAAO;EACL,UAAU;GAAE,MAAM;GAAS,OAAO;GAAa;EAC/C;EACA,aAAa;EACb;EACA,UAAU;EACX;;AAGH,SAAS,0BAA0B,QAAkE;AACnG,KAAI,CAAC,OAAO,WAAY,QAAO;AAI/B,MAAK,MAAM,QADO,CAAC,UAAU,OAAO,EACN;EAC5B,MAAM,QAAQ,OAAO,WAAW;AAChC,MAAI,CAAC,MAAO;AACZ,MAAI,MAAM,UAAU,KAAA,KAAa,OAAO,MAAM,UAAU,SACtD,QAAO;GAAE,UAAU;GAAM,OAAO,MAAM;GAAO;AAE/C,MAAI,MAAM,QAAQ,MAAM,KAAK,WAAW,KAAK,OAAO,MAAM,KAAK,OAAO,SACpE,QAAO;GAAE,UAAU;GAAM,OAAO,MAAM,KAAK;GAAI;;AAKnD,MAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,OAAO,WAAW,EAAE;AAC7D,MAAI,CAAC,MAAO;AACZ,MAAI,MAAM,UAAU,KAAA,KAAa,OAAO,MAAM,UAAU,SACtD,QAAO;GAAE,UAAU;GAAM,OAAO,MAAM;GAAO;AAE/C,MAAI,MAAM,QAAQ,MAAM,KAAK,WAAW,KAAK,OAAO,MAAM,KAAK,OAAO,SACpE,QAAO;GAAE,UAAU;GAAM,OAAO,MAAM,KAAK;GAAI;;AAInD,QAAO;;AAGT,SAAS,wBAAwB,QAA+B;AAC9D,KAAI,OAAO,SAAS,SAAU,QAAO;AACrC,KAAI,CAAC,OAAO,WAAY,QAAO;CAG/B,IAAI;AACJ,KAAI,OAAO,YAAY,OAAO,SAAS,WAAW,EAChD,cAAa,OAAO,SAAS;MACxB;EACL,MAAM,WAAW,OAAO,KAAK,OAAO,WAAW;AAC/C,MAAI,SAAS,WAAW,EACtB,cAAa,SAAS;;AAG1B,KAAI,CAAC,WAAY,QAAO;CAExB,MAAM,aAAa,OAAO,WAAW;AACrC,KAAI,CAAC,WAAY,QAAO;AAGxB,KAAI,WAAW,SAAS,YAAY,0BAA0B,WAAW,KAAK,KAAM,QAAO;AAG3F,KAAI,WAAW,MACb,QAAO,WAAW,MAAM,MAAM,MAAM,EAAE,SAAS,YAAY,0BAA0B,EAAE,KAAK,KAAK;AAGnG,QAAO;;AAGT,SAAS,uBAAuB,QAAsB,aAA+C;CACnG,MAAM,QAAQ,OAAO;CAErB,MAAM,aAAa,MADA,OAAO,YAAY,OAAO,SAAS,WAAW,IAAI,OAAO,SAAS,KAAK,OAAO,KAAK,MAAM,CAAC;CAE7G,MAAM,eAAwB,EAAE;CAGhC,MAAM,eAAe,YAAY,QAAQ,aAAa,GAAG;AAEzD,KAAI,WAAW,OAAO;EACpB,MAAM,gBAAgB,WAAW,MAAM,MAAM,MAAM,EAAE,SAAS,YAAY,0BAA0B,EAAE,KAAK,KAAK;AAEhH,MAAI,eAAe;GACjB,MAAM,YAAY,gBAAgB,eAAe,aAAa;AAC9D,gBAAa,KAAK,GAAG,mBAAmB,WAAW,cAAc,CAAC;GAElE,MAAM,iBAAiB,WAAW,MAAM,MACrC,MAAM,EAAE,SAAS,UAAW,MAAM,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,SAAS,OAAO,CAC9E;GAED,MAAM,WAAoB;IAAE,MAAM;IAAS,MAAM;IAAW;AAC5D,UAAO;IACL,UAAU,iBAAiB;KAAE,MAAM;KAAY,OAAO;KAAU,GAAG;IACnE;IACA,aAAa;IACd;;;CAKL,MAAM,YAAY,gBAAgB,YAAY,aAAa;AAC3D,cAAa,KAAK,GAAG,mBAAmB,WAAW,WAAW,CAAC;AAE/D,QAAO;EACL,UAAU;GAAE,MAAM;GAAS,MAAM;GAAW;EAC5C;EACA,aAAa;EACd;;AAGH,SAAS,sBAAsB,QAAsB,aAA+C;CAClG,MAAM,eAAwB,EAAE;AAGhC,KAAI,OAAO,eAAe,OAAO,SAAS,YAAY,CAAC,OAAO,OAAO;EACnE,MAAM,YAAY,gBAAgB,QAAQ,YAAY;AACtD,eAAa,KAAK,GAAG,mBAAmB,WAAW,OAAO,CAAC;AAC3D,SAAO;GACL,UAAU;IAAE,MAAM;IAAS,MAAM;IAAW;GAC5C;GACA,aAAa;GACd;;AAIH,KAAI,OAAO,OAAO;EAChB,MAAM,mBAA6D,EAAE;EACrE,MAAM,iBAA2B,EAAE;AACnC,OAAK,MAAM,OAAO,OAAO,OAAO;AAC9B,OAAI,IAAI,WACN,QAAO,OAAO,kBAAkB,IAAI,WAAW;AAEjD,OAAI,IAAI,SACN,gBAAe,KAAK,GAAG,IAAI,SAAS;;AAGxC,MAAI,OAAO,KAAK,iBAAiB,CAAC,SAAS,GAAG;GAC5C,MAAM,SAAuB;IAAE,MAAM;IAAU,YAAY;IAAkB,UAAU;IAAgB;GACvG,MAAM,YAAY,gBAAgB,QAAQ,YAAY;AACtD,gBAAa,KAAK,GAAG,mBAAmB,WAAW,OAAO,CAAC;AAC3D,UAAO;IACL,UAAU;KAAE,MAAM;KAAS,MAAM;KAAW;IAC5C;IACA,aAAa;IACd;;;AAML,KAAI,OAAO;OACJ,MAAM,WAAW,OAAO,MAC3B,KAAI,QAAQ,eAAe,QAAQ,SAAS,YAAY,CAAC,QAAQ,OAAO;GACtE,MAAM,YAAY,gBAAgB,SAAS,YAAY;AAEvD,OAAI,CADkB,IAAI,IAAI,aAAa,KAAK,MAAM,EAAE,KAAK,CAAC,CAC3C,IAAI,UAAU,CAC/B,cAAa,KAAK,GAAG,mBAAmB,WAAW,QAAQ,CAAC;;;AAOpE,KAAI,OAAO,SAAS,WAAW,OAAO,OAAO;EAC3C,MAAM,QAAQ,OAAO;AACrB,MAAI,MAAM,KACR,QAAO;GACL,UAAU;IAAE,MAAM;IAAS,OAAO,gBAAgB,OAAO,YAAY;IAAE;GACvE;GACA,aAAa;GACd;AAEH,MAAI,MAAM,eAAe,MAAM,SAAS,YAAY,CAAC,MAAM,OAAO;GAChE,MAAM,WAAW,YAAY,QAAQ,aAAa,GAAG,GAAG;AACxD,gBAAa,KAAK,GAAG,mBAAmB,UAAU,MAAM,CAAC;AACzD,UAAO;IACL,UAAU;KAAE,MAAM;KAAS,OAAO;MAAE,MAAM;MAAS,MAAM;MAAU;KAAE;IACrE;IACA,aAAa;IACd;;;AAKL,QAAO;EACL,UAAU,gBAAgB,QAAQ,YAAY;EAC9C;EACA,aAAa;EACd;;AAGH,SAAS,gBAAgB,QAAsB,UAA0B;AACvE,KAAI,CAAC,OAAO,WAAY,QAAO,aAAa,SAAS;AAIrD,MAAK,MAAM,QADO,CAAC,UAAU,OAAO,EACN;EAC5B,MAAM,QAAQ,OAAO,WAAW;AAChC,MAAI,SAAS,MAAM,SAAS,OAAO,MAAM,UAAU,SACjD,QAAO,aAAa,MAAM,MAAM;;AAKpC,MAAK,MAAM,GAAG,UAAU,OAAO,QAAQ,OAAO,WAAW,CACvD,KAAI,SAAS,MAAM,SAAS,OAAO,MAAM,UAAU,SACjD,QAAO,aAAa,MAAM,MAAM;AAIpC,QAAO,aAAa,SAAS;;;;;;;AAQ/B,SAAS,kBAAkB,YAAoB,WAA2B;CACxE,MAAM,cAAc,aAAa,UAAU;AAE3C,KAAI,YAAY,WAAW,WAAW,CAAE,QAAO;CAI/C,MAAM,YAAY,GADE,qBAAqB,WAAW,GACjB;CAEnC,MAAM,QAAQ,UAAU,MAAM,yBAAyB;AACvD,KAAI,SAAS,MAAM,IAAI;EACrB,MAAM,WAAW,YAAY,MAAM,GAAG;AACtC,SAAO,MAAM,KAAK;;AAEpB,QAAO;;AAGT,SAAS,mBAAmB,MAAc,QAA+B;CACvE,MAAM,cAAc,IAAI,IAAI,OAAO,YAAY,EAAE,CAAC;CAClD,MAAM,SAAkB,EAAE;CAC1B,MAAM,aAAa,OAAO,cAAc,EAAE;CAC1C,MAAM,eAAwB,EAAE;AAEhC,MAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,WAAW,EAAE;AACjE,MAAI,CAAC,YAAa;AAClB,SAAO,KAAK,qBAAqB,WAAW,aAAa,MAAM,YAAY,CAAC;AAI5E,MAAI,YAAY,SAAS,YAAY,YAAY,YAAY;GAC3D,MAAM,aAAa,kBAAkB,MAAM,UAAU;AACrD,gBAAa,KAAK,GAAG,mBAAmB,YAAY,YAAY,CAAC;;AAEnE,MAAI,YAAY,SAAS,WAAW,YAAY,OAAO;GACrD,MAAM,QAAQ,YAAY;AAC1B,OAAI,MAAM,SAAS,YAAY,MAAM,YAAY;IAC/C,MAAM,aAAa,kBAAkB,MAAM,UAAU;AACrD,iBAAa,KAAK,GAAG,mBAAmB,YAAY,MAAM,CAAC;;;AAI/D,MAAI,YAAY,OAAO;GACrB,MAAM,mBAA6D,EAAE;GACrE,MAAM,iBAA2B,EAAE;AACnC,QAAK,MAAM,OAAO,YAAY,OAAO;AACnC,QAAI,IAAI,WAAY,QAAO,OAAO,kBAAkB,IAAI,WAAW;AACnE,QAAI,IAAI,SAAU,gBAAe,KAAK,GAAG,IAAI,SAAS;;AAExD,OAAI,OAAO,KAAK,iBAAiB,CAAC,SAAS,GAAG;IAC5C,MAAM,aAAa,kBAAkB,MAAM,UAAU;IACrD,MAAM,SAAuB;KAAE,MAAM;KAAU,YAAY;KAAkB,UAAU;KAAgB;AAEvG,QAAI,CADkB,IAAI,IAAI,aAAa,KAAK,MAAM,EAAE,KAAK,CAAC,CAC3C,IAAI,WAAW,CAChC,cAAa,KAAK,GAAG,mBAAmB,YAAY,OAAO,CAAC;;;AAKlE,MAAI,YAAY,OAAO;GACrB,MAAM,gBAAgB,YAAY,MAAM,MAAM,MAAM,EAAE,eAAe,EAAE,SAAS,YAAY,CAAC,EAAE,MAAM;AACrG,OAAI,eAAe;IACjB,MAAM,aAAa,kBAAkB,MAAM,UAAU;AAErD,QAAI,CADkB,IAAI,IAAI,aAAa,KAAK,MAAM,EAAE,KAAK,CAAC,CAC3C,IAAI,WAAW,CAChC,cAAa,KAAK,GAAG,mBAAmB,YAAY,cAAc,CAAC;;;;AAM3E,QAAO,CAAC;EAAE;EAAM,aAAa,OAAO;EAAa;EAAQ,EAAE,GAAG,aAAa;;;;ACxW7E,MAAM,eAA6B;CAAC;CAAO;CAAQ;CAAO;CAAS;CAAU;CAAQ;CAAW;CAAQ;AAOxG,SAAgB,kBACd,OACA,sBAC2B;AAC3B,KAAI,CAAC,MAAO,QAAO;EAAE,UAAU,EAAE;EAAE,cAAc,EAAE;EAAE;CAErD,MAAM,6BAAa,IAAI,KAA0B;CACjD,MAAM,eAAwB,EAAE;AAEhC,MAAK,MAAM,CAAC,MAAM,aAAa,OAAO,QAAQ,MAAM,EAAE;EACpD,MAAM,kBAAkB,SAAS,cAAc,EAAE;AAEjD,OAAK,MAAM,UAAU,cAAc;GACjC,MAAM,KAAK,SAAS;AACpB,OAAI,CAAC,GAAI;GAET,MAAM,cAAc,iBAAiB,MAAM,GAAG,OAAO,GAAG;GAExD,MAAM,EAAE,WAAW,cAAc,aAAa,eAC5C,QACA,MACA,IACA,iBACA,sBACA,YACD;AACD,gBAAa,KAAK,GAAG,SAAS;GAC9B,MAAM,MAAM,WAAW,IAAI,YAAY,IAAI,EAAE;AAC7C,OAAI,KAAK,UAAU;AACnB,cAAW,IAAI,aAAa,IAAI;;;AAOpC,MAAK,MAAM,CAAC,aAAa,eAAe,YAAY;EAClD,MAAM,6BAAa,IAAI,KAA0B;AACjD,OAAK,MAAM,MAAM,YAAY;GAC3B,MAAM,WAAW,GAAG,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ,CAAC,MAAM;GAC1D,MAAM,WAAW,SAAS,WAAW,IAAI,GAAG,cAAc,aAAa,SAAS;GAChF,MAAM,QAAQ,WAAW,IAAI,SAAS,IAAI,EAAE;AAC5C,SAAM,KAAK,GAAG;AACd,cAAW,IAAI,UAAU,MAAM;;AAIjC,MAAI,WAAW,OAAO;OACD,CAAC,GAAG,WAAW,MAAM,CAAC,CAAC,MAAM,MAAM,MAAM,YAAY,EACxD;AACd,eAAW,OAAO,YAAY;AAC9B,SAAK,MAAM,CAAC,WAAW,aAAa,YAAY;KAC9C,MAAM,WAAW,WAAW,IAAI,UAAU,IAAI,EAAE;AAChD,cAAS,KAAK,GAAG,SAAS;AAC1B,gBAAW,IAAI,WAAW,SAAS;;;;;AAS3C,MAAK,MAAM,GAAG,eAAe,WAC3B,4BAA2B,WAAW;AAQxC,QAAO;EAAE,UALQ,MAAM,KAAK,WAAW,SAAS,CAAC,CAAC,KAAK,CAAC,MAAM,iBAAiB;GAC7E;GACA;GACD,EAAE;EAEgB;EAAc;;AAGnC,SAAS,iBAAiB,MAAc,KAAsB;AAG5D,KAAI,IACF,QAAO,aAAa,IAAI;CAI1B,MAAM,QADW,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ,CACzB,MAAM;AAE7B,KAAI,MAAM,WAAW,IAAI,CAAE,QAAO;AAClC,QAAO,aAAa,MAAM;;AAG5B,SAAS,mBACP,QACA,MACA,aACA,sBACQ;AACR,KAAI,aAAa;AACf,MAAI,qBACF,QAAO,qBAAqB,YAAY;AAE1C,SAAO,YAAY,YAAY;;CAKjC,MAAM,OAAO,UAAU,QAAQ,KAAK;CACpC,MAAM,WAAW,sBAAsB,KAAK;AAC5C,QAAO,WAAW,YAAY,GAAG,KAAK,GAAG,WAAW,GAAG;;;;;AAMzD,SAAS,UAAU,QAAoB,MAAsB;CAC3D,MAAM,WAAW,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ;CAChD,MAAM,mBAAmB,SAAS,SAAS,KAAK,SAAS,SAAS,SAAS,GAAG,WAAW,IAAI;AAE7F,SAAQ,QAAR;EACE,KAAK,MACH,QAAO,mBAAmB,QAAQ;EACpC,KAAK,OACH,QAAO;EACT,KAAK;EACL,KAAK,QACH,QAAO;EACT,KAAK,SACH,QAAO;EACT,KAAK,OACH,QAAO;EACT,KAAK,UACH,QAAO;EACT,KAAK,QACH,QAAO;EACT,QACE,QAAO;;;;;;;;;;;;;;AAeb,SAAS,sBAAsB,MAA6B;CAC1D,MAAM,WAAW,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ;AAChD,KAAI,SAAS,UAAU,EAAG,QAAO;CAGjC,IAAI,kBAAiC;AACrC,MAAK,IAAI,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,IACxC,KAAI,CAAC,SAAS,GAAG,WAAW,IAAI,EAAE;AAChC,oBAAkB,SAAS;AAC3B;;AAIJ,KAAI,CAAC,gBAAiB,QAAO;AAE7B,KAAI,oBAAoB,SAAS,GAAI,QAAO;AAE5C,QAAO,aAAa,gBAAgB;;;;;;;;;;;AAYtC,SAAS,2BAA2B,YAA+B;CAEjE,MAAM,yBAAS,IAAI,KAA0B;AAC7C,MAAK,MAAM,MAAM,YAAY;EAC3B,MAAM,QAAQ,OAAO,IAAI,GAAG,KAAK,IAAI,EAAE;AACvC,QAAM,KAAK,GAAG;AACd,SAAO,IAAI,GAAG,MAAM,MAAM;;AAG5B,MAAK,MAAM,CAAC,MAAM,UAAU,QAAQ;AAClC,MAAI,MAAM,UAAU,EAAG;AAKvB,MADoB,IAAI,IAAI,MAAM,KAAK,OAAO,GAAG,KAAK,CAAC,CACvC,QAAQ,EAAG;AAE3B,OAAK,MAAM,MAAM,OAAO;GACtB,MAAM,WAAW,sBAAsB,GAAG,KAAK;AAC/C,OAAI,SAED,IAAwB,OADT,YAAY,GAAG,KAAK,GAAG,WAAW;;EAOtD,MAAM,0BAAU,IAAI,KAA0B;AAC9C,OAAK,MAAM,MAAM,OAAO;GACtB,MAAM,SAAS,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE;AACzC,UAAO,KAAK,GAAG;AACf,WAAQ,IAAI,GAAG,MAAM,OAAO;;AAE9B,OAAK,MAAM,GAAG,WAAW,SAAS;AAChC,OAAI,OAAO,UAAU,EAAG;AAGxB,QAAK,MAAM,MAAM,QAAQ;IACvB,MAAM,SAAS,mBAAmB,GAAG,KAAK;AAC1C,QAAI,OACD,IAAwB,OAAO,YAAY,GAAG,GAAG,KAAK,GAAG,SAAS;;;;;;;;;;;;AAc7E,SAAS,mBAAmB,MAA6B;CAEvD,MAAM,YADW,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ,CACrB,QAAQ,MAAM,CAAC,EAAE,WAAW,IAAI,CAAC;AAE5D,KAAI,UAAU,UAAU,EACtB,QAAO,aAAa,UAAU,MAAM,GAAG,GAAG,CAAC,KAAK,IAAI,CAAC;AAEvD,QAAO;;;;;;;AAQT,SAAS,uBACP,IACA,aACA,kBAC8B;CAC9B,MAAM,MAAM,GAAG;AACf,KAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO,KAAA;CAE5C,MAAM,8BAAc,IAAI,KAAwB;AAChD,MAAK,MAAM,KAAK,YACd,aAAY,IAAI,EAAE,MAAM,EAAE;CAG5B,MAAM,SAA2B,EAAE;AAEnC,MAAK,MAAM,CAAC,WAAW,aAAa,OAAO,QAAQ,IAAI,EAAE;AACvD,MAAI,CAAC,YAAY,OAAO,aAAa,SACnC,OAAM,IAAI,MACR,mDAAmD,UAAU,MAAM,iBAAiB,sDACrF;AAGH,MAAI,OAAO,SAAS,aAAa,UAC/B,OAAM,IAAI,MACR,mDAAmD,UAAU,eAAe,iBAAiB,uBAC9F;AAGH,MAAI,CAAC,SAAS,YAAY,OAAO,SAAS,aAAa,SACrD,OAAM,IAAI,MACR,mDAAmD,UAAU,eAAe,iBAAiB,sEAC9F;AAGH,MAAI,OAAO,KAAK,SAAS,SAAS,CAAC,WAAW,EAC5C,OAAM,IAAI,MACR,mDAAmD,UAAU,MAAM,iBAAiB,4BACrF;EAGH,MAAM,WAAW,OAAO,QAAQ,SAAS,SAAS,CAAC,KAAK,CAAC,aAAa,gBAAgB;AACpF,OAAI,CAAC,MAAM,QAAQ,WAAW,IAAI,WAAW,WAAW,EACtD,OAAM,IAAI,MACR,mDAAmD,UAAU,YAAY,YAAY,MAAM,iBAAiB,kDAC7G;AAWH,UAAO;IAAE,MAAM;IAAa,YATI,WAAW,KAAK,UAAU;KACxD,MAAM,UAAU,YAAY,IAAI,MAAM;AACtC,SAAI,CAAC,QACH,OAAM,IAAI,MACR,yCAAyC,UAAU,YAAY,YAAY,yBAAyB,MAAM,0DAA0D,iBAAiB,IACtL;AAEH,YAAO;MACP;IACsC;IACxC;AAEF,SAAO,KAAK;GACV,MAAM;GACN,UAAU,SAAS;GACnB;GACD,CAAC;;AAGJ,QAAO,OAAO,SAAS,IAAI,SAAS,KAAA;;;;;;;;;;AAWtC,SAAS,2BAA2B,IAAqB,kBAAwD;CAC/G,MAAM,MAAM,GAAG;AACf,KAAI,CAAC,OAAO,OAAO,QAAQ,SAAU,QAAO,KAAA;CAK5C,MAAM,aAAa,GAAG,aAAa,UAAU,qBAAqB;CAClE,MAAM,sCAAsB,IAAI,KAA2B;AAE3D,KAAI,YAAY;AAEd,OAAK,MAAM,OAAO,WAAW,SAAS,EAAE,CACtC,MAAK,MAAM,WAAW,IAAI,SAAS,EAAE,CACnC,KAAI,QAAQ;QACL,MAAM,CAAC,MAAM,gBAAgB,OAAO,QAAQ,QAAQ,WAAW,CAClE,KAAI,YAAa,qBAAoB,IAAI,MAAM,YAAY;;AAMnE,OAAK,MAAM,WAAW,WAAW,SAAS,EAAE,CAC1C,KAAI,QAAQ;QACL,MAAM,CAAC,MAAM,gBAAgB,OAAO,QAAQ,QAAQ,WAAW,CAClE,KAAI,YAAa,qBAAoB,IAAI,MAAM,YAAY;;;CAMnE,MAAM,SAA2B,EAAE;AAEnC,MAAK,MAAM,CAAC,WAAW,aAAa,OAAO,QAAQ,IAAI,EAAE;AACvD,MAAI,CAAC,YAAY,OAAO,aAAa,SAAU;AAC/C,MAAI,OAAO,SAAS,aAAa,UAAW;AAC5C,MAAI,CAAC,SAAS,YAAY,OAAO,SAAS,aAAa,SAAU;AACjE,MAAI,OAAO,KAAK,SAAS,SAAS,CAAC,WAAW,EAAG;EAEjD,MAAM,WAAW,OAAO,QAAQ,SAAS,SAAS,CAAC,KAAK,CAAC,aAAa,gBAAgB;AACpF,OAAI,CAAC,MAAM,QAAQ,WAAW,IAAI,WAAW,WAAW,EACtD,OAAM,IAAI,MACR,8CAA8C,UAAU,YAAY,YAAY,MAAM,iBAAiB,kDACxG;AAcH,UAAO;IAAE,MAAM;IAAa,YAZI,WAAW,KAAK,UAAU;KACxD,MAAM,cAAc,oBAAoB,IAAI,MAAM;AAIlD,YAAO;MACL,MAAM;MACN,MALyB,cACvB,gBAAgB,aAAa,aAAa,MAAM,CAAC,GACjD;OAAE,MAAM;OAAa,MAAM;OAAU;MAIvC,UAAU;MACV,aAAa,aAAa;MAC3B;MACD;IACsC;IACxC;AAEF,SAAO,KAAK;GACV,MAAM;GACN,UAAU,SAAS;GACnB;GACD,CAAC;;AAGJ,QAAO,OAAO,SAAS,IAAI,SAAS,KAAA;;AAGtC,SAAS,eACP,QACA,MACA,IACA,iBACA,sBACA,aACiD;CACjD,MAAM,YAAY,CAAC,GAAG,iBAAiB,GAAI,GAAG,cAAc,EAAE,CAAE;CAEhE,MAAM,uBAAuB,UAAU,MAAM,MAAM,EAAE,OAAO,YAAY,EAAE,KAAK,aAAa,KAAK,kBAAkB;CAInH,MAAM,YAAY;CAClB,MAAM,aAAa,cAAc,WAAW,QAAQ,UAAU;CAC9D,MAAM,cAAc,cAAc,WAAW,SAAS,UAAU;CAChE,MAAM,eAAe,cAAc,WAAW,UAAU,UAAU,CAAC,QAChE,MAAM,EAAE,KAAK,aAAa,KAAK,kBACjC;CACD,MAAM,eAAe,cAAc,WAAW,UAAU,UAAU;CAElE,MAAM,gBAAyB,EAAE;CACjC,MAAM,EAAE,MAAM,aAAa,UAAU,wBAAwB,mBAAmB,GAAG,aAAa,IAAI,cAAc;CAClH,MAAM,EACJ,UACA,kBACA,QACA,cACA,aACA,UAAU,kBACV,UAAU,qBACR,iBAAiB,GAAG,WAAW,IAAI,MAAM,OAAO;AACpD,cAAa,KAAK,GAAG,cAAc;CAGnC,MAAM,uBAAuB,iBAAiB,UAAU,aAAa,iBAAiB;CACtF,IAAI;AACJ,KAAI,aAAa;EACf,MAAM,WAAW,qBAAqB,SAAS,SAAS,UAAU,SAAS,QAAQ;AACnF,eAAa;GACX,UAAU,sBAAsB,YAAY;GAC5C,OAAO,sBAAsB,SAAS;GACtC,YAAY,sBAAsB;GAClC,UAAU,oBAAoB,sBAAsB;GACpD;GACD;YACQ,qBACT,cAAa;CAIf,MAAM,WAAW,yBAAyB,GAAG,SAAS;CAGtD,MAAM,cAAc;EAAC,GAAG;EAAY,GAAG;EAAa,GAAG;EAAc,GAAG;EAAa;CACrF,MAAM,UAAU,GAAG,eAAe,GAAG,OAAO,aAAa,CAAC,GAAG;CAC7D,MAAM,mBAAmB,uBAAuB,IAAI,aAAa,QAAQ;CAGzE,MAAM,kBAAkB,2BAA2B,IAAI,QAAQ;CAG/D,MAAM,kBACJ,oBAAoB,kBAAkB,CAAC,GAAI,oBAAoB,EAAE,EAAG,GAAI,mBAAmB,EAAE,CAAE,GAAG,KAAA;AAEpG,QAAO;EACL,WAAW;GACT,MAAM,mBAAmB,QAAQ,MAAM,GAAG,aAAa,qBAAqB;GAC5E,aAAa,iBAAiB,GAAG,SAAS,GAAG,YAAY;GACzD,YAAY;GACZ;GACA;GACA;GACA;GACA,cAAc,aAAa,SAAS,IAAI,eAAe,KAAA;GACvD;GACA;GACA;GACA;GACA;GACA;GACA,sBAAsB;GACtB,YAAY,GAAG,cAAc,KAAA;GAC7B,OAAO,GAAG;GACV;GACA;GACD;EACD;EACD;;;;;;;;AASH,SAAS,yBACP,UACmC;AACnC,KAAI,CAAC,YAAY,SAAS,WAAW,EAAG,QAAO,KAAA;CAE/C,MAAM,eAAsC,EAAE;AAC9C,MAAK,MAAM,SAAS,SAClB,MAAK,MAAM,CAAC,YAAY,WAAW,OAAO,QAAQ,MAAM,CACtD,cAAa,KAAK;EAAE;EAAY,QAAQ,UAAU,EAAE;EAAE,CAAC;AAG3D,QAAO,aAAa,SAAS,IAAI,eAAe,KAAA;;AAGlD,SAAS,iBAAiB,SAA6B,aAAqD;AAC1G,KAAI,WAAW,eAAe,YAAY,YACxC,QAAO,GAAG,QAAQ,MAAM;AAE1B,QAAO,eAAe;;AAGxB,SAAS,cACP,QACA,UACA,kBACa;AACb,QAAO,OACJ,QAAQ,MAAM,EAAE,OAAO,SAAS,CAChC,KAAK,OAAO;EACX,MAAM,EAAE;EACR,MAAM,EAAE,SACJ,gBAAgB,EAAE,QAAQ,EAAE,MAAM,mBAAmB,aAAa,iBAAiB,GAAG,KAAA,EAAU,GAC/F;GAAE,MAAM;GAAa,MAAM;GAAU;EAC1C,UAAU,EAAE,YAAY;EACxB,aAAa,EAAE;EACf,YAAY,EAAE,cAAc,EAAE,QAAQ,cAAc,KAAA;EACpD,SAAS,EAAE,QAAQ;EACnB,SAAS,EAAE,WAAW,EAAE,QAAQ;EAChC,OAAO,EAAE;EACT,SAAS,EAAE;EACZ,EAAE;;AAGP,SAAS,mBACP,MACA,IACA,cAC6F;AAC7F,KAAI,CAAC,MAAM,QAAS,QAAO,EAAE;CAG7B,IAAI,WAAyE;CAC7E,IAAI;AAEJ,KAAI,KAAK,QAAQ,qBAAqB,QAAQ;AAC5C,aAAW;AACX,WAAS,KAAK,QAAQ,oBAAqB;YAClC,KAAK,QAAQ,wBAAwB,QAAQ;AACtD,aAAW;AACX,WAAS,KAAK,QAAQ,uBAAwB;YACrC,KAAK,QAAQ,sCAAsC,QAAQ;AACpE,aAAW;AACX,WAAS,KAAK,QAAQ,qCAAsC;YACnD,KAAK,QAAQ,6BAA6B;AACnD,aAAW;AACX,WAAS,KAAK,QAAQ,4BAA6B;YAC1C,KAAK,QAAQ,eAAe;AACrC,aAAW;AACX,WAAS,KAAK,QAAQ,cAAe;;AAGvC,KAAI,CAAC,QAAQ;AAEX,MAAI,aAAa,SACf,QAAO;GAAE,MAAM;IAAE,MAAM;IAAa,MAAM;IAAU,QAAQ;IAAU;GAAE;GAAU;AAEpF,MAAI,aAAa,OACf,QAAO;GAAE,MAAM;IAAE,MAAM;IAAa,MAAM;IAAU;GAAE;GAAU;AAElE,SAAO,EAAE;;CAIX,MAAM,cAAc,gBADJ,IAAI,cAAc,aAAa,GAAG,YAAY,GAAG,YAAY,cACjC;AAG5C,KAAI,OAAO,eAAe,OAAO,SAAS,YAAY,CAAC,OAAO,OAAO;EACnE,MAAM,cAAc,IAAI,IAAI,OAAO,YAAY,EAAE,CAAC;EAClD,MAAM,SAAkB,EAAE;AAC1B,OAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,OAAO,WAAW,EAAE;AACxE,OAAI,CAAC,YAAa;AAClB,UAAO,KAAK,qBAAqB,WAAW,aAAa,aAAa,YAAY,CAAC;;AAErF,eAAa,KAAK;GAAE,MAAM;GAAa,aAAa,KAAA;GAAW;GAAQ,CAAC;AACxE,SAAO;GAAE,MAAM;IAAE,MAAM;IAAS,MAAM;IAAa;GAAE;GAAU;;AAKjE,KAAI,OAAO,OAAO;EAChB,MAAM,WAAsB,EAAE;AAE9B,OAAK,MAAM,WAAW,OAAO,MAC3B,KAAI,QAAQ,MAAM;GAChB,MAAM,MAAM,gBAAgB,SAAS,YAAY;AACjD,YAAS,KAAK,IAAI;aACT,QAAQ,SAAS,QAAQ,YAEzB,QAAQ,eAAe,QAAQ,SAAS,YAAY,CAAC,QAAQ,OAAO;GAC7E,MAAM,cAAc,uBAAuB,SAAS,aAAa,aAAa;GAC9E,MAAM,cAAc,IAAI,IAAI,QAAQ,YAAY,EAAE,CAAC;GACnD,MAAM,SAAkB,EAAE;AAC1B,QAAK,MAAM,CAAC,WAAW,gBAAgB,OAAO,QAAQ,QAAQ,WAAW,EAAE;AACzE,QAAI,CAAC,YAAa;AAClB,WAAO,KAAK,qBAAqB,WAAW,aAAa,aAAa,YAAY,CAAC;;AAErF,gBAAa,KAAK;IAAE,MAAM;IAAa,aAAa,QAAQ;IAAa;IAAQ,CAAC;AAClF,YAAS,KAAK;IAAE,MAAM;IAAS,MAAM;IAAa,CAAC;QAEnD,UAAS,KAAK,gBAAgB,SAAS,YAAY,CAAC;EAIxD,MAAM,UAAU,OAAO,MAAM,MAC1B,MAAoB,EAAE,SAAS,UAAW,MAAM,QAAQ,EAAE,KAAK,IAAI,EAAE,KAAK,SAAS,OAAO,CAC5F;EACD,MAAM,QAAiB;GACrB,MAAM;GACN;GACA,GAAI,OAAO,gBACP,EACE,eAAe;IAAE,UAAU,OAAO,cAAc;IAAc,SAAS,OAAO,cAAc,WAAW,EAAE;IAAE,EAC5G,GACD,EAAE;GACP;AAED,SAAO;GAAE,MADI,UAAW;IAAE,MAAM;IAAY,OAAO;IAAO,GAAe;GAC1D;GAAU;;AAG3B,QAAO;EAAE,MAAM,gBAAgB,QAAQ,YAAY;EAAE;EAAU;;;AAIjE,SAAS,uBAAuB,SAAuB,UAAkB,gBAAiC;AAExG,KAAI,QAAQ;OACL,MAAM,GAAG,eAAe,OAAO,QAAQ,QAAQ,WAAW,CAC7D,KAAI,YAAY,SAAS,OAAO,WAAW,UAAU,SACnD,QAAO,aAAa,WAAW,MAAM,GAAG,SAAS,QAAQ,YAAY,GAAG,GAAG;;CAKjF,MAAM,gBAAgB,IAAI,IAAI,eAAe,KAAK,MAAM,EAAE,KAAK,CAAC;CAChE,IAAI,OAAO;CACX,IAAI,SAAS;AACb,QAAO,cAAc,IAAI,KAAK,EAAE;AAC9B,SAAO,GAAG,WAAW;AACrB;;AAEF,QAAO;;AAGT,SAAS,mBAAmB,IAAiC,MAAc,QAA4B;AACrG,KAAI,IAAI,YACN,QAAO,gBAAgB,aAAa,GAAG,YAAY,GAAG,WAAW;AAInE,QAAO,aAFU,KAAK,MAAM,IAAI,CAAC,OAAO,QAAQ,CACtB,MAAM,UACH,GAAG,aAAa,OAAO,GAAG;;AAGzD,SAAS,iBACP,WACA,IACA,MACA,QASA;CACA,MAAM,SAA0B,EAAE;CAClC,IAAI,WAAoB;EAAE,MAAM;EAAa,MAAM;EAAU;CAC7D,IAAI,eAAwB,EAAE;CAC9B,IAAI,cAAc;CAClB,IAAI;CACJ,IAAI;AAEJ,KAAI,CAAC,UAAW,QAAO;EAAE;EAAU;EAAQ;EAAc;EAAa;CAEtE,MAAM,sBAAyC,EAAE;AAEjD,MAAK,MAAM,CAAC,YAAY,SAAS,OAAO,QAAQ,UAAU,EAAE;EAC1D,MAAM,OAAO,SAAS,YAAY,GAAG;AAErC,MAAI,QAAQ,OAAO,OAAO,KAAK;GAC7B,IAAI,gBAAyB;IAAE,MAAM;IAAa,MAAM;IAAW;GACnE,MAAM,cAAc,KAAK,UAAU;AACnC,OAAI,aAAa,QAAQ;IACvB,MAAM,cAAc,mBAAmB,IAAI,QAAQ,KAAK,UAAU,MAAM;IACxE,MAAM,SAAS,2BAA2B,YAAY,QAAQ,YAAY;AAC1E,oBAAgB,OAAO;AAEvB,mBAAe,OAAO;AACtB,kBAAc,OAAO;AACrB,eAAW,OAAO;AAClB,eAAW,OAAO;cACT,KAAK,QAEd,KAAI,KAAK,QAAQ,+BAA+B,KAAK,QAAQ,mBAC3D,iBAAgB;IAAE,MAAM;IAAa,MAAM;IAAU,QAAQ;IAAU;YAEvE,KAAK,QAAQ,iBACb,KAAK,QAAQ,gBACb,KAAK,QAAQ,eACb,KAAK,QAAQ,mBAEb,iBAAgB;IAAE,MAAM;IAAa,MAAM;IAAU;QAChD;IAEL,MAAM,WAAW,OAAO,KAAK,KAAK,QAAQ,CAAC;AAC3C,QAAI,UAAU;KACZ,MAAM,eAAe,KAAK,QAAQ;AAClC,SAAI,cAAc,OAChB,iBAAgB,gBACd,aAAa,QACb,mBAAmB,IAAI,QAAQ,KAAK,UAAU,MAAM,CACrD;;;AAKT,uBAAoB,KAAK;IAAE,YAAY;IAAM,MAAM;IAAe,CAAC;aAC1D,QAAQ,OAAO,OAAO,IAE/B,qBAAoB,KAAK;GAAE,YAAY;GAAM,MAAM;IAAE,MAAM;IAAa,MAAM;IAAW;GAAE,CAAC;WACnF,QAAQ,KAAK;GACtB,MAAM,cAAc,KAAK,UAAU;GACnC,MAAM,OAAO,aAAa,SAAS,gBAAgB,YAAY,QAAQ,QAAQ,OAAO,GAAG,KAAA;AACzF,UAAO,KAAK;IAAE,YAAY;IAAM;IAAM,CAAC;;;AAK3C,KAAI,oBAAoB,SAAS,GAAG;EAClC,MAAM,SAAS,CAAC,GAAG,oBAAoB,CAAC,MAAM,GAAG,MAAM,EAAE,aAAa,EAAE,WAAW;AAGnF,cADE,OAAO,MAAM,MAAM,EAAE,KAAK,SAAS,eAAgB,EAAE,KAA0B,SAAS,UAAU,IAAI,OAAO,IAC5F;;CAGrB,MAAM,mBAAmB,oBAAoB,SAAS,IAAI,sBAAsB,KAAA;AAEhF,QAAO;EAAE;EAAU;EAAkB;EAAQ;EAAc;EAAa;EAAU;EAAU;;;;AC1zB9F,SAAS,kBAAkB,QAA0B;CACnD,MAAM,yBAAS,IAAI,KAAoB;AACvC,MAAK,MAAM,SAAS,QAAQ;EAC1B,MAAM,WAAW,OAAO,IAAI,MAAM,KAAK;AACvC,MAAI,CAAC,YAAY,MAAM,OAAO,SAAS,SAAS,OAAO,OACrD,QAAO,IAAI,MAAM,MAAM,MAAM;;AAGjC,QAAO,CAAC,GAAG,OAAO,QAAQ,CAAC;;AAG7B,SAAS,gBAAgB,KAAc,SAAiB,SAAuB;AAC7E,aAAY,KAAK,EACf,QAAQ,MAAM;AACZ,MAAI,EAAE,SAAS,QAAU,GAAuB,OAAO;IAE1D,CAAC;;AAGJ,SAAS,iBAAiB,QAAiB,UAAqB,SAAiB,SAAuB;AACtG,MAAK,MAAM,SAAS,OAClB,MAAK,MAAM,SAAS,MAAM,OACxB,iBAAgB,MAAM,MAAM,SAAS,QAAQ;AAGjD,MAAK,MAAM,WAAW,SACpB,MAAK,MAAM,MAAM,QAAQ,YAAY;AACnC,kBAAgB,GAAG,UAAU,SAAS,QAAQ;AAC9C,MAAI,GAAG,YACL,iBAAgB,GAAG,aAAa,SAAS,QAAQ;;;AAMzD,SAAgB,0BAA0B,cAAuB,cAAgC;CAC/F,MAAM,qBAAqB,CAAC,GAAG,aAAa;CAC5C,MAAM,mBAAmB,IAAI,IAAI,mBAAmB,KAAK,MAAM,EAAE,KAAK,CAAC;CACvE,MAAM,qBAAqB,IAAI,IAAI,mBAAmB,KAAK,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;CAE9E,MAAM,2BAA2B,aAAa,QAAQ,UAAU;AAC9D,MAAI,CAAC,iBAAiB,IAAI,MAAM,KAAK,CAAE,QAAO;EAE9C,MAAM,WAAW,mBAAmB,IAAI,MAAM,KAAK;EACnD,MAAM,qBAAqB,IAAI,IAAI,SAAS,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC;EACtE,MAAM,mBAAmB,IAAI,IAAI,MAAM,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC;EACjE,MAAM,gBACJ,MAAM,OAAO,MAAM,MAAM,CAAC,mBAAmB,IAAI,EAAE,KAAK,CAAC,IACzD,SAAS,OAAO,MAAM,MAAM,CAAC,iBAAiB,IAAI,EAAE,KAAK,CAAC;AAE5D,MAAI,iBAAiB,MAAM,OAAO,SAAS,SAAS,OAAO,QAAQ;GACjE,MAAM,MAAM,mBAAmB,QAAQ,SAAS;AAChD,OAAI,QAAQ,GAAI,oBAAmB,OAAO;AAC1C,sBAAmB,IAAI,MAAM,MAAM,MAAM;AACzC,WAAQ,KACN,kCAAkC,MAAM,KAAK,2CAA2C,MAAM,OAAO,OAAO,MAAM,SAAS,OAAO,OAAO,iCAC1I;aACQ,cACT,SAAQ,KACN,kCAAkC,MAAM,KAAK,uEAC9C;AAGH,SAAO;GACP;AAEF,QAAO,CAAC,GAAG,oBAAoB,GAAG,kBAAkB,yBAAyB,CAAC;;AAGhF,SAAgB,uBAAuB,gBAAyB,mBAAqC;CACnG,MAAM,aAAa,IAAI,IAAI,eAAe,KAAK,MAAM,EAAE,KAAK,CAAC;CAC7D,MAAM,eAAe,IAAI,IAAI,eAAe,KAAK,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;CAEpE,MAAM,0BAA0B,kBAAkB,QAAQ,UAAU;AAClE,MAAI,CAAC,WAAW,IAAI,MAAM,KAAK,CAAE,QAAO;EAExC,MAAM,WAAW,aAAa,IAAI,MAAM,KAAK;EAC7C,MAAM,qBAAqB,IAAI,IAAI,SAAS,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC;EACtE,MAAM,mBAAmB,IAAI,IAAI,MAAM,OAAO,KAAK,MAAM,EAAE,KAAK,CAAC;AAKjE,MAHE,MAAM,OAAO,MAAM,MAAM,CAAC,mBAAmB,IAAI,EAAE,KAAK,CAAC,IACzD,SAAS,OAAO,MAAM,MAAM,CAAC,iBAAiB,IAAI,EAAE,KAAK,CAAC,CAG1D,SAAQ,KACN,kCAAkC,MAAM,KAAK,uEAC9C;AAGH,SAAO;GACP;AAEF,QAAO,CAAC,GAAG,gBAAgB,GAAG,kBAAkB,wBAAwB,CAAC;;AAG3E,SAAS,0BAA0B,OAAuB;AACxD,QAAO,MAAM,OAAO,MACjB,OAAO,EAAE,SAAS,YAAY,EAAE,SAAS,WAAW,EAAE,KAAK,SAAS,aAAa,OAAO,EAAE,KAAK,UAAU,SAC3G;;AAGH,SAAS,0BAA0B,MAAc,QAAiB,cAAoC;AACpG,MAAK,MAAM,SAAS,QAAQ;AAC1B,MAAI,aAAa,IAAI,MAAM,KAAK,CAAE;AAClC,OAAK,MAAM,SAAS,MAAM,QAAQ;GAChC,IAAI,QAAQ;AACZ,eAAY,MAAM,MAAM,EACtB,QAAQ,MAAM;AACZ,QAAI,EAAE,SAAS,KAAM,SAAQ;MAEhC,CAAC;AACF,OAAI,MAAO,QAAO;;;AAGtB,QAAO;;AAGT,SAAgB,yBAAyB,QAAiB,UAA8B;CACtF,MAAM,mBAAmB,CAAC,GAAG,OAAO;CACpC,MAAM,SAAS,IAAI,IAAI,iBAAiB,KAAK,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;CAGhE,MAAM,kBAAiE,EAAE;AACzE,MAAK,MAAM,SAAS,kBAAkB;AACpC,MAAI,CAAC,MAAM,KAAK,SAAS,OAAO,CAAE;EAElC,MAAM,WAAW,MAAM,KAAK,MAAM,GAAG,GAAG;EACxC,MAAM,YAAY,OAAO,IAAI,SAAS;AACtC,MAAI,CAAC,aAAa,MAAM,OAAO,UAAU,UAAU,OAAO,OAAQ;AAGlE,MAAI,CADe,UAAU,OAAO,OAAO,MAAM,MAAM,OAAO,MAAM,OAAO,GAAG,SAAS,EAAE,KAAK,CAAC,CAC9E;AAGjB,MAAI,0BAA0B,MAAM,IAAI,0BAA0B,UAAU,CAAE;AAG9E,MAAI,0BAA0B,MAAM,MAAM,kBAAkB,IAAI,IAAI,CAAC,MAAM,MAAM,SAAS,CAAC,CAAC,CAAE;AAE9F,kBAAgB,KAAK;GAAE,WAAW;GAAO;GAAW,CAAC;;CAIvD,MAAM,2BAAW,IAAI,KAAa;AAClC,MAAK,MAAM,EAAE,WAAW,eAAe,iBAAiB;AACtD,YAAU,SAAS,UAAU;AAC7B,WAAS,IAAI,UAAU,KAAK;AAC5B,mBAAiB,kBAAkB,UAAU,UAAU,MAAM,UAAU,KAAK;AAC5E,UAAQ,KACN,mBAAmB,UAAU,KAAK,UAAU,UAAU,KAAK,KAAK,UAAU,OAAO,OAAO,oBACzF;;AAGH,QAAO,iBAAiB,QAAQ,MAAM,CAAC,SAAS,IAAI,EAAE,KAAK,CAAC;;;;ACzJ9D,SAAgB,6BAA6B,QAAiB,OAAqB;CACjF,MAAM,YAAY,IAAI,IAAI,MAAM,KAAK,MAAM,EAAE,KAAK,CAAC;AACnD,MAAK,MAAM,SAAS,OAClB,MAAK,MAAM,SAAS,MAAM,OACxB,0BAAyB,MAAM,MAAM,OAAO,UAAU;;;;;;AAS5D,SAAgB,iCAAiC,UAAqB,OAAqB;CACzF,MAAM,YAAY,IAAI,IAAI,MAAM,KAAK,MAAM,EAAE,KAAK,CAAC;AACnD,MAAK,MAAM,WAAW,SACpB,MAAK,MAAM,MAAM,QAAQ,WACvB,MAAK,MAAM,SAAS;EAAC,GAAG,GAAG;EAAY,GAAG,GAAG;EAAa,GAAG,GAAG;EAAc,GAAI,GAAG,gBAAgB,EAAE;EAAE,CACvG,0BAAyB,MAAM,MAAM,OAAO,UAAU;;;;AClB9D,SAAgB,kBAAkB,MAAqB;CACrD,MAAM,6BAAa,IAAI,KAAa;AACpC,MAAK,MAAM,KAAK,KAAK,OAAQ,YAAW,IAAI,EAAE,KAAK;AACnD,MAAK,MAAM,KAAK,KAAK,MAAO,YAAW,IAAI,EAAE,KAAK;CAElD,SAAS,QAAQ,KAAc,SAAuB;AACpD,cAAY,KAAK,EACf,QAAQ,MAAM;AACZ,OAAI,CAAC,WAAW,IAAI,EAAE,KAAK,CACzB,SAAQ,KAAK,gDAAgD,EAAE,KAAK,cAAc,QAAQ,GAAG;KAGlG,CAAC;;AAGJ,MAAK,MAAM,SAAS,KAAK,OACvB,MAAK,MAAM,SAAS,MAAM,OACxB,SAAQ,MAAM,MAAM,GAAG,MAAM,KAAK,GAAG,MAAM,OAAO;AAItD,MAAK,MAAM,WAAW,KAAK,SACzB,MAAK,MAAM,MAAM,QAAQ,YAAY;AACnC,OAAK,MAAM,KAAK;GAAC,GAAG,GAAG;GAAY,GAAG,GAAG;GAAa,GAAG,GAAG;GAAa,CACvE,SAAQ,EAAE,MAAM,GAAG,QAAQ,KAAK,GAAG,GAAG,KAAK,GAAG,EAAE,OAAO;AAEzD,MAAI,GAAG,YAAa,SAAQ,GAAG,aAAa,GAAG,QAAQ,KAAK,GAAG,GAAG,KAAK,cAAc;AACrF,UAAQ,GAAG,UAAU,GAAG,QAAQ,KAAK,GAAG,GAAG,KAAK,WAAW;;;;;ACXjE,eAAsB,UAAU,UAAkB,SAA0C;CAC1F,MAAM,EAAE,WAAW,MAAM,kBAAkB,SAAS;CAEpD,MAAM,OAAO;CAeb,MAAM,UAAU,KAAK,WAAW;AAChC,KAAI,CAAC,QAAQ,WAAW,KAAK,CAC3B,OAAM,IAAI,eACR,gCAAgC,QAAQ,+BACxC,oHAAoH,SAAS,KAC9H;CAGH,MAAM,EAAE,QAAQ,UAAU,eACxB,KAAK,YAAY,SACjB,EAAE,qBAAqB,SAAS,qBAAqB,CACtD;CAED,MAAM,EAAE,UAAU,iBAAiB,kBACjC,KAAK,OACL,SAAS,qBACV;AAKD,2BAA0B;CAS1B,MAAM,cAAc,yBADM,uBANO,0BAA0B,QAAQ,aAAa,EAGtD,+BACxB,KAAK,YAAY,QAClB,CAC4F,EAC7B,SAAS;AACzE,8BAA6B,aAAa,MAAM;AAChD,kCAAiC,UAAU,MAAM;CAEjD,MAAM,OAAO,mBAAmB,KAAK,YAAY,gBAAgB;CAEjE,MAAM,iBAAgC,KAAK,WAAW,EAAE,EACrD,KAAK,OAAO;EAAE,KAAK,EAAE,OAAO;EAAI,aAAa,EAAE;EAAa,EAAE,CAC9D,QAAQ,MAAM,EAAE,IAAI;CAEvB,MAAM,SAAkB;EACtB,MAAM,KAAK,MAAM,SAAS;EAC1B,SAAS,KAAK,MAAM,WAAW;EAC/B,aAAa,KAAK,MAAM;EACxB,SAAS,cAAc,IAAI,OAAO;EAClC,SAAS,cAAc,SAAS,IAAI,gBAAgB,KAAA;EACpD;EACA,QAAQ;EACR;EACA;EACA,KAAK,oBAAoB;EAC1B;AAED,mBAAkB,OAAO;AAEzB,QAAO;;;AAGT,SAAS,mBACP,iBAI0B;AAC1B,KAAI,CAAC,gBAAiB,QAAO,KAAA;CAC7B,MAAM,UAAwB,EAAE;AAChC,MAAK,MAAM,GAAG,WAAW,OAAO,QAAQ,gBAAgB,CACtD,KAAI,OAAO,SAAS,UAAU,OAAO,WAAW,SAC9C,SAAQ,KAAK,EAAE,MAAM,UAAU,CAAC;UACvB,OAAO,SAAS,YAAY,OAAO,MAAM,OAAO,KACzD,SAAQ,KAAK;EAAE,MAAM;EAAU,IAAI,OAAO;EAAqC,MAAM,OAAO;EAAM,CAAC;UAC1F,OAAO,SAAS,YAAY,OAAO,MAC5C,SAAQ,KAAK;EAAE,MAAM;EAAU,OAAO,OAAO;EAAO,CAAC;AAGzD,QAAO,QAAQ,SAAS,IAAI,UAAU,KAAA;;;;ACzFxC,SAAgB,cAAc,IAA8B;CAC1D,MAAM,WAAW,GAAG,eAAe;CACnC,MAAM,UAAU,CAAC,CAAC,GAAG;CACrB,MAAM,mBAAmB,GAAG,wBAAwB,GAAG,eAAe;CACtE,MAAM,iBAAiB,GAAG,YAAY,SAAS;CAC/C,MAAM,sBAAsB,GAAG,WAAW,SAAS,KAAM,GAAG,WAAW,SAAS,MAAM,WAAW;CACjG,MAAM,cAAc,GAAG,eAAe,KAAA;CACtC,MAAM,oBAAoB,yBAAyB,GAAG;AAStD,QAAO;EACL,WAAW;EACX;EACA;EACA;EACA;EACA;EACA;EACA,wBAfA,eAAe,GAAG,YAAY,SAAS,SAAS,UAAU,GAAG,WAAW,SAAS,OAAO;EAgBxF,iBAfsB,sBAAsB;EAgB5C,iBAbsB,CAAC,eAAe,GAAG,SAAS,SAAS,WAAW,GAAG,SAAS,MAAM,SAAS;EAcjG;EACA,SAdc,GAAG,SAAS;EAe3B;;AAGH,SAAgB,yBAAyB,IAA8B;AACrE,KAAI,GAAG,eAAe,SAAU,QAAO;AACvC,QAAO,iBAAiB,GAAG,SAAS;;AAGtC,SAAS,iBAAiB,KAA6B;AACrD,SAAQ,IAAI,MAAZ;EACE,KAAK,QACH,QAAO,IAAI;EACb,KAAK,QACH,QAAO,IAAI,MAAM,SAAS,UAAU,IAAI,MAAM,OAAO;EACvD,KAAK,WACH,QAAO,iBAAiB,IAAI,MAAM;EACpC,KAAK,SAAS;GACZ,MAAM,aAAa,IAAI,SAAS,MAAM,MAAM,EAAE,SAAS,QAAQ;AAC/D,UAAO,cAAc,WAAW,SAAS,UAAU,WAAW,OAAO;;EAEvE,KAAK;EACL,KAAK;EACL,KAAK;EACL,KAAK,UACH,QAAO;EACT,QACE,QAAO,YAAY,IAAI"}