@djangocfg/nextjs 2.1.64 → 2.1.66
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/index.mjs +1 -1
- package/dist/config/index.mjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/sitemap/route.ts","../src/sitemap/generator.ts","../src/health/route.ts","../src/og-image/route.tsx","../src/og-image/components/DefaultTemplate.tsx","../src/og-image/utils/fonts.ts","../src/og-image/utils/url.ts","../src/og-image/utils/metadata.ts","../src/navigation/utils.ts","../src/pwa/plugin.ts","../src/config/constants.ts","../src/config/packages/checker.ts","../src/config/utils/env.ts","../src/config/packages/definitions.ts","../src/config/plugins/compression.ts","../src/config/plugins/devStartup.ts","../src/ai/constants.ts","../src/config/packages/installer.ts","../src/config/packages/updater.ts","../src/config/utils/version.ts","../src/config/utils/deepMerge.ts","../src/config/createNextConfig.ts","../src/ai/client.ts"],"sourcesContent":["{\n \"name\": \"@djangocfg/nextjs\",\n \"version\": \"2.1.64\",\n \"description\": \"Next.js server utilities: sitemap, health, OG images, contact forms, navigation, config\",\n \"keywords\": [\n \"nextjs\",\n \"sitemap\",\n \"health\",\n \"og-image\",\n \"navigation\",\n \"config\",\n \"react\",\n \"typescript\"\n ],\n \"author\": {\n \"name\": \"DjangoCFG\",\n \"url\": \"https://djangocfg.com\"\n },\n \"homepage\": \"https://djangocfg.com\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/markolofsen/django-cfg.git\",\n \"directory\": \"packages/nextjs\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/markolofsen/django-cfg/issues\"\n },\n \"license\": \"MIT\",\n \"main\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.mts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.mts\",\n \"import\": \"./dist/index.mjs\",\n \"default\": \"./dist/index.mjs\"\n },\n \"./sitemap\": {\n \"types\": \"./dist/sitemap/index.d.mts\",\n \"import\": \"./dist/sitemap/index.mjs\",\n \"default\": \"./dist/sitemap/index.mjs\"\n },\n \"./health\": {\n \"types\": \"./dist/health/index.d.mts\",\n \"import\": \"./dist/health/index.mjs\",\n \"default\": \"./dist/health/index.mjs\"\n },\n \"./og-image\": {\n \"types\": \"./dist/og-image/index.d.mts\",\n \"import\": \"./dist/og-image/index.mjs\",\n \"default\": \"./dist/og-image/index.mjs\"\n },\n \"./og-image/utils\": {\n \"types\": \"./dist/og-image/utils/index.d.mts\",\n \"import\": \"./dist/og-image/utils/index.mjs\",\n \"default\": \"./dist/og-image/utils/index.mjs\"\n },\n \"./og-image/components\": {\n \"types\": \"./dist/og-image/components/index.d.mts\",\n \"import\": \"./dist/og-image/components/index.mjs\",\n \"default\": \"./dist/og-image/components/index.mjs\"\n },\n \"./navigation\": {\n \"types\": \"./dist/navigation/index.d.mts\",\n \"import\": \"./dist/navigation/index.mjs\",\n \"default\": \"./dist/navigation/index.mjs\"\n },\n \"./config\": {\n \"types\": \"./dist/config/index.d.mts\",\n \"import\": \"./dist/config/index.mjs\",\n \"default\": \"./dist/config/index.mjs\"\n },\n \"./ai\": {\n \"types\": \"./dist/ai/index.d.mts\",\n \"import\": \"./dist/ai/index.mjs\",\n \"default\": \"./dist/ai/index.mjs\"\n },\n \"./pwa\": {\n \"types\": \"./dist/pwa/index.d.mts\",\n \"import\": \"./dist/pwa/index.mjs\",\n \"default\": \"./dist/pwa/index.mjs\"\n },\n \"./pwa/worker\": {\n \"types\": \"./dist/pwa/worker/index.d.mts\",\n \"import\": \"./dist/pwa/worker/index.mjs\",\n \"default\": \"./dist/pwa/worker/index.mjs\"\n },\n \"./worker\": {\n \"types\": \"./dist/pwa/worker/index.d.mts\",\n \"import\": \"./dist/pwa/worker/index.mjs\",\n \"default\": \"./dist/pwa/worker/index.mjs\"\n },\n \"./pwa/server\": {\n \"types\": \"./dist/pwa/server/index.d.mts\",\n \"import\": \"./dist/pwa/server/index.mjs\",\n \"default\": \"./dist/pwa/server/index.mjs\"\n },\n \"./pwa/server/routes\": {\n \"types\": \"./dist/pwa/server/routes.d.mts\",\n \"import\": \"./dist/pwa/server/routes.mjs\",\n \"default\": \"./dist/pwa/server/routes.mjs\"\n }\n },\n \"files\": [\n \"dist\",\n \"src\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"bin\": {\n \"djangocfg-docs\": \"./dist/ai/cli.mjs\",\n \"djangocfg-pwa\": \"./dist/pwa/cli.mjs\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"clean\": \"rm -rf dist\",\n \"lint\": \"eslint .\",\n \"check\": \"tsc --noEmit\",\n \"ai-docs\": \"tsx src/ai/cli.ts\",\n \"pwa\": \"tsx src/pwa/cli.ts\"\n },\n \"peerDependencies\": {\n \"next\": \"^16.0.10\"\n },\n \"dependencies\": {\n \"@serwist/next\": \"^9.2.3\",\n \"@serwist/sw\": \"^9.2.3\",\n \"chalk\": \"^5.3.0\",\n \"conf\": \"^15.0.2\",\n \"consola\": \"^3.4.2\",\n \"semver\": \"^7.7.3\",\n \"serwist\": \"^9.2.3\",\n \"web-push\": \"^3.6.7\"\n },\n \"devDependencies\": {\n \"@djangocfg/imgai\": \"workspace:*\",\n \"@djangocfg/layouts\": \"workspace:*\",\n \"@djangocfg/typescript-config\": \"workspace:*\",\n \"@types/node\": \"^24.7.2\",\n \"@types/react\": \"19.2.2\",\n \"@types/react-dom\": \"19.2.1\",\n \"@types/semver\": \"^7.7.1\",\n \"@types/web-push\": \"^3.6.4\",\n \"@types/webpack\": \"^5.28.5\",\n \"@vercel/og\": \"^0.8.5\",\n \"eslint\": \"^9.37.0\",\n \"lucide-react\": \"^0.545.0\",\n \"tsup\": \"^8.0.1\",\n \"tsx\": \"^4.19.2\",\n \"typescript\": \"^5.9.3\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}","/**\n * Sitemap Route Handler for Next.js App Router\n *\n * Usage:\n * ```tsx\n * // app/sitemap.ts\n * import { createSitemapHandler } from '@djangocfg/nextjs/sitemap';\n *\n * export default createSitemapHandler({\n * siteUrl: 'https://example.com',\n * staticPages: [\n * { loc: '/', changefreq: 'daily', priority: 1.0 },\n * { loc: '/about', changefreq: 'monthly', priority: 0.8 },\n * ],\n * dynamicPages: async () => {\n * // Fetch dynamic pages from API\n * const posts = await fetchPosts();\n * return posts.map(post => ({\n * loc: `/posts/${post.slug}`,\n * lastmod: post.updatedAt,\n * changefreq: 'weekly',\n * priority: 0.7,\n * }));\n * },\n * });\n * ```\n */\n\nimport { NextResponse } from 'next/server';\n\nimport { generateSitemapXml, normalizeUrl } from './generator';\n\nimport type { SitemapGeneratorOptions } from './types';\nimport type { SitemapUrl } from '../types';\n\nexport function createSitemapHandler(options: SitemapGeneratorOptions) {\n const {\n siteUrl,\n staticPages = [],\n dynamicPages = [],\n cacheControl = 'public, s-maxage=86400, stale-while-revalidate',\n } = options;\n\n return async function GET() {\n const urls: SitemapUrl[] = [...staticPages];\n\n // Add dynamic pages\n if (dynamicPages) {\n if (typeof dynamicPages === 'function') {\n const dynamicUrls = await dynamicPages();\n urls.push(...dynamicUrls);\n } else {\n urls.push(...dynamicPages);\n }\n }\n\n // Normalize all URLs\n const normalizedUrls = urls.map((url) => ({\n ...url,\n loc: normalizeUrl(url.loc, siteUrl),\n }));\n\n // Generate XML\n const sitemap = generateSitemapXml(normalizedUrls);\n\n // Return response\n return new NextResponse(sitemap, {\n status: 200,\n headers: {\n 'Content-Type': 'application/xml',\n 'Cache-Control': cacheControl,\n },\n });\n };\n}\n\n","/**\n * Sitemap Generator\n *\n * Generates XML sitemap from configuration\n */\n\nimport type { SitemapUrl } from '../types';\n\n/**\n * Generate XML sitemap string from URLs\n */\nexport function generateSitemapXml(urls: SitemapUrl[]): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xsi:schemaLocation=\"http://www.sitemaps.org/schemas/sitemap/0.9\n http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd\">\n${urls\n .map(\n ({ loc, lastmod, changefreq, priority }) => ` <url>\n <loc>${escapeXml(loc)}</loc>\n ${lastmod ? `<lastmod>${formatDate(lastmod)}</lastmod>` : ''}\n ${changefreq ? `<changefreq>${changefreq}</changefreq>` : ''}\n ${priority !== undefined ? `<priority>${priority.toFixed(1)}</priority>` : ''}\n </url>`\n )\n .join('\\n')}\n</urlset>`;\n}\n\n/**\n * Format date for sitemap (ISO 8601)\n */\nfunction formatDate(date: string | Date): string {\n if (typeof date === 'string') {\n return date;\n }\n return date.toISOString().split('T')[0];\n}\n\n/**\n * Escape XML special characters\n */\nfunction escapeXml(unsafe: string): string {\n return unsafe\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n/**\n * Normalize URL (ensure absolute)\n */\nexport function normalizeUrl(url: string, siteUrl: string): string {\n if (url.startsWith('http://') || url.startsWith('https://')) {\n return url;\n }\n const baseUrl = siteUrl.endsWith('/') ? siteUrl.slice(0, -1) : siteUrl;\n const path = url.startsWith('/') ? url : `/${url}`;\n return `${baseUrl}${path}`;\n}\n\n","/**\n * Health Route Handler for Next.js App Router\n *\n * Usage:\n * ```tsx\n * // app/api/health/route.ts\n * import { createHealthHandler } from '@djangocfg/nextjs/health';\n *\n * export const GET = createHealthHandler({\n * version: process.env.NEXT_PUBLIC_APP_VERSION || '1.0.0',\n * checks: [\n * {\n * name: 'database',\n * check: async () => {\n * // Check database connection\n * return await checkDatabase();\n * },\n * },\n * ],\n * });\n * ```\n */\n\nimport { NextResponse } from 'next/server';\n\nimport type { HealthConfig, HealthResponse } from './types';\n\nexport function createHealthHandler(config: HealthConfig = {}) {\n const { version, checks = [], customData = {} } = config;\n\n return async function GET() {\n const startTime = Date.now();\n let status: 'ok' | 'error' = 'ok';\n const checkResults: Record<string, boolean> = {};\n\n // Run health checks\n if (checks.length > 0) {\n for (const check of checks) {\n try {\n const result = await check.check();\n checkResults[check.name] = result;\n if (!result) {\n status = 'error';\n }\n } catch (error) {\n checkResults[check.name] = false;\n status = 'error';\n }\n }\n }\n\n const response: HealthResponse = {\n status,\n timestamp: new Date().toISOString(),\n uptime: process.uptime(),\n ...(version && { version }),\n ...(Object.keys(checkResults).length > 0 && { checks: checkResults }),\n ...customData,\n };\n\n const statusCode = status === 'ok' ? 200 : 503;\n\n return NextResponse.json(response, { status: statusCode });\n };\n}\n\n","/**\n * OG Image Route Handler\n *\n * Factory function to create OG Image route handler for Next.js App Router\n *\n * Usage:\n * ```tsx\n * // app/api/og/route.tsx\n * import { createOgImageHandler } from '@djangocfg/nextjs/og-image';\n * import { MyTemplate } from './templates';\n *\n * export const { GET, runtime } = createOgImageHandler({\n * template: MyTemplate,\n * defaultProps: {\n * siteName: 'My Site',\n * },\n * fonts: [{ family: 'Manrope', weight: 700 }],\n * });\n * ```\n */\n\nimport { ImageResponse } from 'next/og';\nimport { NextRequest } from 'next/server';\n\nimport { DefaultTemplate } from './components/DefaultTemplate';\nimport { loadGoogleFonts } from './utils';\nimport { parseOgImageData } from './utils/url';\n\nimport type { ReactElement } from 'react';\nimport type { OgImageTemplateProps } from './types';\n\nexport interface OgImageHandlerConfig {\n /** Custom template component (optional, defaults to DefaultTemplate) */\n template?: (props: OgImageTemplateProps) => ReactElement;\n /** Default props to merge with query params */\n defaultProps?: Partial<OgImageTemplateProps>;\n /** Google Fonts to load */\n fonts?: Array<{ family: string; weight: 400 | 500 | 600 | 700 | 800 | 900 }>;\n /** Image size */\n size?: { width: number; height: number };\n /** Enable debug mode */\n debug?: boolean;\n}\n\n/**\n * Factory function to create OG Image route handler\n * \n * @example\n * ```tsx\n * // app/api/og/route.tsx\n * import { createOgImageHandler } from '@djangocfg/nextjs/og-image';\n * import { MyTemplate } from '@/components/MyTemplate';\n * \n * export const { GET, runtime } = createOgImageHandler({\n * template: MyTemplate,\n * defaultProps: { siteName: 'My Site' },\n * fonts: [{ family: 'Inter', weight: 700 }],\n * });\n * ```\n */\nexport function createOgImageHandler(config: OgImageHandlerConfig) {\n const {\n template: Template = DefaultTemplate,\n defaultProps = {},\n fonts: fontConfig = [],\n size = { width: 1200, height: 630 },\n debug = false,\n } = config;\n\n async function GET(req: NextRequest) {\n let searchParams: URLSearchParams = new URLSearchParams();\n \n // Try to get searchParams from multiple sources\n if (req.nextUrl?.searchParams && req.nextUrl.searchParams.size > 0) {\n searchParams = req.nextUrl.searchParams;\n } else if (req.nextUrl?.search && req.nextUrl.search.length > 1) {\n searchParams = new URLSearchParams(req.nextUrl.search);\n } else {\n try {\n const url = new URL(req.url);\n if (url.searchParams.size > 0) {\n searchParams = url.searchParams;\n }\n } catch (error) {\n // Ignore\n }\n \n if (searchParams.size === 0 && req.url) {\n const queryIndex = req.url.indexOf('?');\n if (queryIndex !== -1) {\n const queryString = req.url.substring(queryIndex + 1);\n searchParams = new URLSearchParams(queryString);\n }\n }\n \n if (searchParams.size === 0) {\n const customParams = req.headers.get('x-og-search-params');\n if (customParams) {\n searchParams = new URLSearchParams(customParams);\n }\n }\n }\n\n // Initialize with defaults\n let title = defaultProps.title || 'Untitled';\n let subtitle = defaultProps.subtitle || '';\n let description = defaultProps.description || subtitle;\n\n // Support base64 data parameter (priority: base64 > query params > defaults)\n // All template props can be encoded in base64, including styling params\n const dataParam = searchParams.get('data');\n let decodedParams: Record<string, any> = {};\n \n if (dataParam) {\n try {\n const paramsObj: Record<string, string> = { data: dataParam };\n for (const [key, value] of searchParams.entries()) {\n if (key !== 'data') {\n paramsObj[key] = value;\n }\n }\n decodedParams = parseOgImageData(paramsObj);\n \n // Base64 data takes precedence - apply all decoded values\n if (decodedParams.title && typeof decodedParams.title === 'string' && decodedParams.title.trim() !== '') {\n title = decodedParams.title.trim();\n }\n if (decodedParams.subtitle && typeof decodedParams.subtitle === 'string' && decodedParams.subtitle.trim() !== '') {\n subtitle = decodedParams.subtitle.trim();\n }\n if (decodedParams.description && typeof decodedParams.description === 'string' && decodedParams.description.trim() !== '') {\n description = decodedParams.description.trim();\n }\n } catch (error) {\n // Silently fall back to defaults\n }\n }\n\n // Fallback to query params if not set from base64\n if (!title || title === 'Untitled') {\n const titleParam = searchParams.get('title');\n if (titleParam) {\n title = titleParam;\n }\n }\n if (!subtitle) {\n const subtitleParam = searchParams.get('subtitle');\n if (subtitleParam) {\n subtitle = subtitleParam;\n }\n }\n if (!description || description === subtitle) {\n const descParam = searchParams.get('description');\n if (descParam) {\n description = descParam;\n }\n }\n\n // Load fonts if configured\n let fonts: any[] = [];\n if (fontConfig.length > 0) {\n fonts = await loadGoogleFonts(fontConfig);\n }\n\n // Helper function to parse numeric/boolean values from decoded params\n const parseValue = (value: any, type: 'number' | 'boolean' | 'string' = 'string'): any => {\n if (value === undefined || value === null || value === '') {\n return undefined;\n }\n if (type === 'number') {\n const num = Number(value);\n return isNaN(num) ? undefined : num;\n }\n if (type === 'boolean') {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') {\n return value.toLowerCase() === 'true' || value === '1';\n }\n return Boolean(value);\n }\n return String(value);\n };\n\n // Merge props: decoded params from URL override defaultProps\n const templateProps: OgImageTemplateProps = {\n ...defaultProps,\n // Content\n title,\n subtitle,\n description,\n // Override with decoded params if present\n siteName: decodedParams.siteName || defaultProps.siteName,\n logo: decodedParams.logo || defaultProps.logo,\n // Background\n backgroundType: (decodedParams.backgroundType as 'gradient' | 'solid') || defaultProps.backgroundType,\n gradientStart: decodedParams.gradientStart || defaultProps.gradientStart,\n gradientEnd: decodedParams.gradientEnd || defaultProps.gradientEnd,\n backgroundColor: decodedParams.backgroundColor || defaultProps.backgroundColor,\n // Typography - Title\n titleSize: parseValue(decodedParams.titleSize, 'number') ?? defaultProps.titleSize,\n titleWeight: parseValue(decodedParams.titleWeight, 'number') ?? defaultProps.titleWeight,\n titleColor: decodedParams.titleColor || defaultProps.titleColor,\n // Typography - Description\n descriptionSize: parseValue(decodedParams.descriptionSize, 'number') ?? defaultProps.descriptionSize,\n descriptionColor: decodedParams.descriptionColor || defaultProps.descriptionColor,\n // Typography - Site Name\n siteNameSize: parseValue(decodedParams.siteNameSize, 'number') ?? defaultProps.siteNameSize,\n siteNameColor: decodedParams.siteNameColor || defaultProps.siteNameColor,\n // Layout\n padding: parseValue(decodedParams.padding, 'number') ?? defaultProps.padding,\n logoSize: parseValue(decodedParams.logoSize, 'number') ?? defaultProps.logoSize,\n // Visibility flags\n showLogo: parseValue(decodedParams.showLogo, 'boolean') ?? defaultProps.showLogo,\n showSiteName: parseValue(decodedParams.showSiteName, 'boolean') ?? defaultProps.showSiteName,\n };\n\n\n return new ImageResponse(\n <Template {...templateProps} />,\n {\n width: size.width,\n height: size.height,\n fonts,\n debug: debug || process.env.NODE_ENV === 'development',\n }\n );\n }\n\n return {\n GET,\n runtime: 'edge' as const,\n };\n}\n\n/**\n * Create OG Image route handler for dynamic route with path parameter\n * \n * This is a convenience wrapper for Next.js dynamic routes like `/api/og/[data]/route.tsx`.\n * It extracts the `data` parameter from the path and passes it to the handler as a query parameter.\n * Also handles static export mode automatically.\n * \n * @example\n * ```tsx\n * // app/api/og/[data]/route.tsx\n * import { createOgImageDynamicRoute } from '@djangocfg/nextjs/og-image';\n * import { OgImageTemplate } from '@/components/OgImageTemplate';\n * \n * export const runtime = 'nodejs';\n * export const dynamic = 'force-static';\n * export const revalidate = false;\n * \n * const handler = createOgImageDynamicRoute({\n * template: OgImageTemplate,\n * defaultProps: {\n * siteName: 'My App',\n * logo: '/logo.svg',\n * },\n * });\n * \n * export async function GET(\n * request: NextRequest,\n * { params }: { params: { data: string } }\n ) {\n * return handler(request, params);\n * }\n * ```\n */\nexport function createOgImageDynamicRoute(config: OgImageHandlerConfig) {\n const handler = createOgImageHandler(config);\n const isStaticBuild = typeof process !== 'undefined' && process.env.NEXT_PUBLIC_STATIC_BUILD === 'true';\n\n async function GET(\n request: NextRequest,\n context: { params: Promise<{ data: string }> }\n ) {\n // In static export mode, return a simple error response\n if (isStaticBuild) {\n return new Response('OG Image generation is not available in static export mode', {\n status: 404,\n headers: { 'Content-Type': 'text/plain' },\n });\n }\n\n // Await params (Next.js 15+ uses Promise)\n const params = await context.params;\n \n // Extract data from path parameter\n const dataParam = params.data;\n \n // Create a request with the data parameter as a query param for the handler\n const url = new URL(request.url);\n url.searchParams.set('data', dataParam);\n \n const modifiedRequest = new NextRequest(url.toString(), {\n method: request.method,\n headers: request.headers,\n });\n\n return handler.GET(modifiedRequest);\n }\n\n // For static export, provide generateStaticParams that returns empty array\n // This allows the route to be excluded from static build\n async function generateStaticParams(): Promise<Array<{ data: string }>> {\n return [];\n }\n\n return {\n GET,\n generateStaticParams,\n };\n}\n","/**\n * Default OG Image Template\n *\n * A modern, gradient-based template for OG images\n */\n\nimport type { ReactElement } from 'react';\nimport type { OgImageTemplateProps } from '../types';\n\n/**\n * Default OG Image Template Component\n *\n * Features:\n * - Modern gradient background\n * - Responsive text sizing\n * - Optional logo and site name\n * - Clean typography\n * - Full customization support\n *\n * @param props - Template props with title, description, siteName, logo and optional customization\n */\nexport function DefaultTemplate({\n title,\n description,\n siteName,\n logo,\n // Visibility flags\n showLogo = true,\n showSiteName = true,\n // Background customization\n backgroundType = 'gradient',\n gradientStart = '#667eea',\n gradientEnd = '#764ba2',\n backgroundColor = '#ffffff',\n // Typography - Title\n titleSize,\n titleWeight = 800,\n titleColor = 'white',\n // Typography - Description\n descriptionSize = 32,\n descriptionColor = 'rgba(255, 255, 255, 0.85)',\n // Typography - Site Name\n siteNameSize = 28,\n siteNameColor = 'rgba(255, 255, 255, 0.95)',\n // Layout\n padding = 80,\n logoSize = 48,\n // Dev mode\n devMode = false,\n}: OgImageTemplateProps): ReactElement {\n // Calculate title size if not provided (responsive based on title length)\n const calculatedTitleSize = titleSize || (title.length > 60 ? 56 : 72);\n \n // Determine background style\n const backgroundStyle =\n backgroundType === 'gradient'\n ? `linear-gradient(135deg, ${gradientStart} 0%, ${gradientEnd} 100%)`\n : backgroundColor;\n\n // Grid overlay for dev mode\n const gridOverlay = devMode ? (\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundImage: `\n linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px),\n linear-gradient(90deg, rgba(0, 0, 0, 0.1) 1px, transparent 1px)\n `,\n backgroundSize: '20px 20px',\n pointerEvents: 'none',\n zIndex: 10,\n }}\n />\n ) : null;\n\n return (\n <div\n style={{\n height: '100%',\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n background: backgroundStyle,\n padding: `${padding}px`,\n fontFamily: 'system-ui, -apple-system, sans-serif',\n position: 'relative',\n }}\n >\n {gridOverlay}\n \n {/* Header with logo and site name */}\n {((showLogo && logo) || (showSiteName && siteName)) && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '16px',\n }}\n >\n {showLogo && logo && (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={logo}\n alt=\"Logo\"\n width={logoSize}\n height={logoSize}\n style={{\n borderRadius: '8px',\n }}\n />\n )}\n {showSiteName && siteName && (\n <div\n style={{\n fontSize: siteNameSize,\n fontWeight: 600,\n color: siteNameColor,\n letterSpacing: '-0.02em',\n }}\n >\n {siteName}\n </div>\n )}\n </div>\n )}\n\n {/* Main content */}\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '24px',\n flex: 1,\n justifyContent: 'center',\n }}\n >\n {/* Title */}\n <div\n style={{\n fontSize: calculatedTitleSize,\n fontWeight: titleWeight,\n color: titleColor,\n lineHeight: 1.1,\n letterSpacing: '-0.03em',\n textShadow: backgroundType === 'gradient' ? '0 2px 20px rgba(0, 0, 0, 0.2)' : 'none',\n maxWidth: '100%',\n wordWrap: 'break-word',\n }}\n >\n {title}\n </div>\n\n {/* Description */}\n {description && (\n <div\n style={{\n fontSize: descriptionSize,\n fontWeight: 400,\n color: descriptionColor,\n lineHeight: 1.5,\n letterSpacing: '-0.01em',\n maxWidth: '90%',\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n }}\n >\n {description}\n </div>\n )}\n </div>\n\n {/* Footer decoration */}\n <div\n style={{\n display: 'flex',\n width: '100%',\n height: '4px',\n background: backgroundType === 'gradient' \n ? `linear-gradient(90deg, ${gradientStart} 0%, ${gradientEnd} 100%)`\n : gradientStart,\n borderRadius: '2px',\n }}\n />\n </div>\n );\n}\n\n/**\n * Simple light template variant\n * \n * Light background variant with dark text\n */\nexport function LightTemplate({\n title,\n description,\n siteName,\n logo,\n // Visibility flags\n showLogo = true,\n showSiteName = true,\n // Background customization (defaults to light theme)\n backgroundType = 'solid',\n gradientStart = '#667eea',\n gradientEnd = '#764ba2',\n backgroundColor = '#ffffff',\n // Typography - Title\n titleSize,\n titleWeight = 800,\n titleColor = '#111',\n // Typography - Description\n descriptionSize = 32,\n descriptionColor = '#666',\n // Typography - Site Name\n siteNameSize = 28,\n siteNameColor = '#111',\n // Layout\n padding = 80,\n logoSize = 48,\n // Dev mode\n devMode = false,\n}: OgImageTemplateProps): ReactElement {\n // Calculate title size if not provided (responsive based on title length)\n const calculatedTitleSize = titleSize || (title.length > 60 ? 56 : 72);\n \n // Determine background style\n const backgroundStyle =\n backgroundType === 'gradient'\n ? `linear-gradient(135deg, ${gradientStart} 0%, ${gradientEnd} 100%)`\n : backgroundColor;\n\n // Grid overlay for dev mode\n const gridOverlay = devMode ? (\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundImage: `\n linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px),\n linear-gradient(90deg, rgba(0, 0, 0, 0.1) 1px, transparent 1px)\n `,\n backgroundSize: '20px 20px',\n pointerEvents: 'none',\n zIndex: 10,\n }}\n />\n ) : null;\n\n return (\n <div\n style={{\n height: '100%',\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n background: backgroundStyle,\n padding: `${padding}px`,\n fontFamily: 'system-ui, -apple-system, sans-serif',\n position: 'relative',\n }}\n >\n {gridOverlay}\n \n {/* Header with logo and site name */}\n {((showLogo && logo) || (showSiteName && siteName)) && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '16px',\n }}\n >\n {showLogo && logo && (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={logo}\n alt=\"Logo\"\n width={logoSize}\n height={logoSize}\n style={{\n borderRadius: '8px',\n }}\n />\n )}\n {showSiteName && siteName && (\n <div\n style={{\n fontSize: siteNameSize,\n fontWeight: 600,\n color: siteNameColor,\n letterSpacing: '-0.02em',\n }}\n >\n {siteName}\n </div>\n )}\n </div>\n )}\n\n {/* Main content */}\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '24px',\n flex: 1,\n justifyContent: 'center',\n }}\n >\n {/* Title */}\n <div\n style={{\n fontSize: calculatedTitleSize,\n fontWeight: titleWeight,\n color: titleColor,\n lineHeight: 1.1,\n letterSpacing: '-0.03em',\n maxWidth: '100%',\n wordWrap: 'break-word',\n }}\n >\n {title}\n </div>\n\n {/* Description */}\n {description && (\n <div\n style={{\n fontSize: descriptionSize,\n fontWeight: 400,\n color: descriptionColor,\n lineHeight: 1.5,\n letterSpacing: '-0.01em',\n maxWidth: '90%',\n }}\n >\n {description}\n </div>\n )}\n </div>\n\n {/* Footer decoration */}\n <div\n style={{\n display: 'flex',\n width: '100%',\n height: '4px',\n background: backgroundType === 'gradient' \n ? `linear-gradient(90deg, ${gradientStart} 0%, ${gradientEnd} 100%)`\n : gradientStart,\n borderRadius: '2px',\n }}\n />\n </div>\n );\n}\n\n","/**\n * Font Utilities for OG Image Generation\n *\n * Provides dynamic font loading from Google Fonts without requiring files in public/\n * Based on Vercel's official @vercel/og documentation\n */\n\nexport interface FontConfig {\n name: string;\n weight?: 400 | 500 | 600 | 700 | 800 | 900;\n style?: 'normal' | 'italic';\n data: ArrayBuffer;\n}\n\n/**\n * Load a Google Font dynamically\n *\n * @param font - Font family name (e.g., \"Inter\", \"Roboto\", \"Manrope\")\n * @param text - Text to optimize font for (optional, reduces file size)\n * @param weight - Font weight (default: 700)\n * @returns ArrayBuffer of font data\n *\n * @example\n * const fontData = await loadGoogleFont('Manrope', 'Hello World', 700);\n */\nexport async function loadGoogleFont(\n font: string,\n text?: string,\n weight: number = 700\n): Promise<ArrayBuffer> {\n // Construct Google Fonts API URL\n let url = `https://fonts.googleapis.com/css2?family=${font}:wght@${weight}`;\n\n // Add text parameter to optimize font subset (reduces size)\n if (text) {\n url += `&text=${encodeURIComponent(text)}`;\n }\n\n try {\n // Fetch CSS containing font URL\n const css = await fetch(url, {\n headers: {\n // Required to get TTF format instead of WOFF2\n 'User-Agent':\n 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1',\n },\n }).then((res) => res.text());\n\n // Extract font URL from CSS\n const resource = css.match(/src: url\\((.+)\\) format\\('(opentype|truetype)'\\)/);\n\n if (!resource || !resource[1]) {\n throw new Error(`Failed to parse font URL from CSS for font: ${font}`);\n }\n\n // Fetch actual font file\n const response = await fetch(resource[1]);\n\n if (response.status !== 200) {\n throw new Error(`Failed to fetch font data: HTTP ${response.status}`);\n }\n\n return await response.arrayBuffer();\n } catch (error) {\n console.error(`Error loading Google Font \"${font}\":`, error);\n throw new Error(`Failed to load font \"${font}\": ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Load multiple Google Fonts\n *\n * @param fonts - Array of font configurations to load\n * @returns Array of FontConfig objects ready for ImageResponse\n *\n * @example\n * const fonts = await loadGoogleFonts([\n * { family: 'Manrope', weight: 700 },\n * { family: 'Inter', weight: 400 }\n * ]);\n */\nexport async function loadGoogleFonts(\n fonts: Array<{\n family: string;\n weight?: 400 | 500 | 600 | 700 | 800 | 900;\n style?: 'normal' | 'italic';\n text?: string;\n }>\n): Promise<FontConfig[]> {\n const fontConfigs = await Promise.all(\n fonts.map(async ({ family, weight = 700, style = 'normal', text }) => {\n const data = await loadGoogleFont(family, text, weight);\n return {\n name: family,\n weight,\n style,\n data,\n };\n })\n );\n\n return fontConfigs;\n}\n\n/**\n * Create a font loader with caching\n *\n * Useful for reusing font data across multiple OG image requests\n *\n * @example\n * const fontLoader = createFontLoader();\n * const font = await fontLoader.load('Manrope', 700);\n */\nexport function createFontLoader() {\n const cache = new Map<string, Promise<ArrayBuffer>>();\n\n return {\n /**\n * Load a font with caching\n */\n async load(\n family: string,\n weight: number = 700,\n text?: string\n ): Promise<ArrayBuffer> {\n const cacheKey = `${family}-${weight}-${text || 'all'}`;\n\n if (!cache.has(cacheKey)) {\n cache.set(cacheKey, loadGoogleFont(family, text, weight));\n }\n\n return cache.get(cacheKey)!;\n },\n\n /**\n * Clear the cache\n */\n clear() {\n cache.clear();\n },\n\n /**\n * Get cache size\n */\n size() {\n return cache.size;\n },\n };\n}\n\n","/**\n * URL Generation Helpers for OG Images\n *\n * Utilities to generate OG image URLs with proper query parameters\n */\n\n/** Default OG Image API base URL */\nconst DEFAULT_OG_IMAGE_BASE_URL = 'https://djangocfg.com/api/og';\n\n/**\n * Encode string to base64 with Unicode support\n * Works in both browser and Node.js environments\n */\nfunction encodeBase64(str: string): string {\n // Node.js environment\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(str, 'utf-8').toString('base64');\n }\n // Browser environment - handle Unicode via UTF-8 encoding\n return btoa(unescape(encodeURIComponent(str)));\n}\n\n/**\n * Decode base64 string with Unicode support\n * Works in both browser, Node.js, and Edge Runtime environments\n */\nfunction decodeBase64(str: string): string {\n // Node.js environment\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(str, 'base64').toString('utf-8');\n }\n // Edge Runtime / Browser environment - handle Unicode via UTF-8 decoding\n // atob is available in Edge Runtime\n try {\n const binaryString = atob(str);\n // Convert binary string to UTF-8\n return decodeURIComponent(\n binaryString\n .split('')\n .map((c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))\n .join('')\n );\n } catch (error) {\n // Fallback to simpler method if above fails\n return decodeURIComponent(escape(atob(str)));\n }\n}\n\n/**\n * OG Image URL parameters\n * All parameters can be encoded in URL via base64\n */\nexport interface OgImageUrlParams {\n /** Page title */\n title: string;\n /** Page description (optional) */\n description?: string;\n /** Site name (optional) */\n siteName?: string;\n /** Logo URL (optional) */\n logo?: string;\n /** Background type: 'gradient' or 'solid' */\n backgroundType?: 'gradient' | 'solid';\n /** Gradient start color (hex) */\n gradientStart?: string;\n /** Gradient end color (hex) */\n gradientEnd?: string;\n /** Background color (for solid type) */\n backgroundColor?: string;\n /** Title font size (px) */\n titleSize?: number;\n /** Title font weight */\n titleWeight?: number;\n /** Title text color */\n titleColor?: string;\n /** Description font size (px) */\n descriptionSize?: number;\n /** Description text color */\n descriptionColor?: string;\n /** Site name font size (px) */\n siteNameSize?: number;\n /** Site name text color */\n siteNameColor?: string;\n /** Padding (px) */\n padding?: number;\n /** Logo size (px) */\n logoSize?: number;\n /** Show logo flag */\n showLogo?: boolean;\n /** Show site name flag */\n showSiteName?: boolean;\n /** Additional custom parameters */\n [key: string]: string | number | boolean | undefined;\n}\n\n/**\n * Options for generating OG image URL\n */\nexport interface GenerateOgImageUrlOptions {\n /**\n * Base URL of the OG image API route\n * @default 'https://djangocfg.com/api/og'\n */\n baseUrl?: string;\n /**\n * If true, encode params as base64 for safer URLs\n * @default true\n */\n useBase64?: boolean;\n}\n\n/**\n * Generate OG image URL with query parameters or base64 encoding\n *\n * @param params - URL parameters for the OG image\n * @param options - Generation options (baseUrl, useBase64)\n * @returns Complete OG image URL with encoded parameters\n *\n * @example\n * ```typescript\n * // Using default baseUrl (https://djangocfg.com/api/og)\n * const url = generateOgImageUrl({\n * title: 'My Page Title',\n * description: 'Page description here',\n * });\n *\n * // With custom baseUrl\n * const url = generateOgImageUrl(\n * { title: 'My Page' },\n * { baseUrl: '/api/og' }\n * );\n * ```\n */\nexport function generateOgImageUrl(\n params: OgImageUrlParams,\n options: GenerateOgImageUrlOptions = {}\n): string {\n const {\n baseUrl = DEFAULT_OG_IMAGE_BASE_URL,\n useBase64 = true\n } = options;\n\n if (useBase64) {\n // Clean params - remove undefined/null/empty values\n const cleanParams: Record<string, string | number | boolean> = {};\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null && value !== '') {\n cleanParams[key] = value;\n }\n });\n\n // Encode as base64 (Unicode-safe)\n const jsonString = JSON.stringify(cleanParams);\n const base64Data = encodeBase64(jsonString);\n\n // CRITICAL: Use path parameter instead of query parameter\n // Next.js strips query params in internal requests for metadata generation\n // Using /api/og/[data] instead of /api/og?data=... preserves the data\n // IMPORTANT: Add trailing slash to avoid 308 redirects which cause timeouts in crawlers\n return `${baseUrl}/${base64Data}/`;\n } else {\n // Legacy query params mode\n const searchParams = new URLSearchParams();\n\n // Add all defined parameters\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null && value !== '') {\n searchParams.append(key, String(value));\n }\n });\n\n const query = searchParams.toString();\n return query ? `${baseUrl}?${query}` : baseUrl;\n }\n}\n\n/**\n * Get absolute OG image URL from relative path\n *\n * Useful for generating absolute URLs required by Open Graph meta tags\n *\n * @param relativePath - Relative OG image path (e.g., '/api/og?title=Hello')\n * @param siteUrl - Base site URL (e.g., 'https://example.com')\n * @returns Absolute URL\n *\n * @example\n * ```typescript\n * const absolute = getAbsoluteOgImageUrl(\n * '/api/og?title=Hello',\n * 'https://example.com'\n * );\n * // Result: https://example.com/api/og?title=Hello\n * ```\n */\nexport function getAbsoluteOgImageUrl(\n relativePath: string,\n siteUrl: string\n): string {\n // If path is already an absolute URL, return as-is\n if (relativePath.startsWith('http://') || relativePath.startsWith('https://')) {\n return relativePath;\n }\n\n // Remove trailing slash from site URL\n const cleanSiteUrl = siteUrl.replace(/\\/$/, '');\n\n // Ensure relative path starts with /\n const cleanPath = relativePath.startsWith('/')\n ? relativePath\n : `/${relativePath}`;\n\n return `${cleanSiteUrl}${cleanPath}`;\n}\n\n/**\n * Create OG image URL builder with preset configuration\n *\n * Useful when you want to reuse the same base URL and default parameters\n *\n * @param defaults - Default parameters to merge with each URL generation\n * @param options - Default options (baseUrl, useBase64)\n * @returns URL builder function\n *\n * @example\n * ```typescript\n * const buildOgUrl = createOgImageUrlBuilder(\n * { siteName: 'My Site', logo: '/logo.png' },\n * { baseUrl: '/api/og' }\n * );\n *\n * const url1 = buildOgUrl({ title: 'Page 1' });\n * const url2 = buildOgUrl({ title: 'Page 2', description: 'Custom desc' });\n * ```\n */\nexport function createOgImageUrlBuilder(\n defaults: Partial<OgImageUrlParams> = {},\n options: GenerateOgImageUrlOptions = {}\n) {\n return (params: OgImageUrlParams): string => {\n return generateOgImageUrl(\n { ...defaults, ...params },\n options\n );\n };\n}\n\n/**\n * Parse OG image URL parameters from a URL string (legacy query params)\n *\n * @param url - Full or relative URL with query parameters\n * @returns Parsed parameters object\n *\n * @example\n * ```typescript\n * const params = parseOgImageUrl('/api/og?title=Hello&description=World');\n * // Result: { title: 'Hello', description: 'World' }\n * ```\n */\nexport function parseOgImageUrl(url: string): Record<string, string> {\n try {\n const urlObj = new URL(url, 'http://dummy.com');\n const params: Record<string, string> = {};\n\n urlObj.searchParams.forEach((value, key) => {\n params[key] = value;\n });\n\n return params;\n } catch {\n return {};\n }\n}\n\n/**\n * Parse OG image data from base64-encoded query parameter\n *\n * Use this in your API route to decode the `data` parameter\n * Supports both base64 (new) and legacy query params format\n *\n * @param searchParams - URL search params or request object\n * @returns Parsed OG image parameters\n *\n * @example\n * ```typescript\n * // In Next.js API route (pages/api/og.ts)\n * export default function handler(req) {\n * const params = parseOgImageData(req.query);\n * // { title: 'Hello', description: 'World' }\n * }\n *\n * // In Next.js App Router (app/api/og/route.ts)\n * export async function GET(request: Request) {\n * const { searchParams } = new URL(request.url);\n * const params = parseOgImageData(Object.fromEntries(searchParams));\n * // { title: 'Hello', description: 'World' }\n * }\n * ```\n */\nexport function parseOgImageData(\n searchParams: Record<string, string | string[] | undefined> | URLSearchParams\n): Record<string, string> {\n try {\n // Handle URLSearchParams\n let params: Record<string, string | undefined>;\n\n if (searchParams instanceof URLSearchParams) {\n // Convert URLSearchParams to object\n params = {};\n for (const [key, value] of searchParams.entries()) {\n params[key] = value;\n }\n } else {\n params = searchParams as Record<string, string | undefined>;\n }\n\n // Debug logging\n if (process.env.NODE_ENV === 'development') {\n console.log('[parseOgImageData] Input params keys:', Object.keys(params));\n console.log('[parseOgImageData] Input params:', params);\n }\n\n // Check for base64-encoded data parameter\n const dataParam = params.data;\n if (dataParam && typeof dataParam === 'string' && dataParam.trim() !== '') {\n if (process.env.NODE_ENV === 'development') {\n console.log('[parseOgImageData] Found data param, length:', dataParam.length);\n }\n\n try {\n const decoded = decodeBase64(dataParam);\n if (process.env.NODE_ENV === 'development') {\n console.log('[parseOgImageData] Decoded string:', decoded.substring(0, 100));\n }\n\n const parsed = JSON.parse(decoded);\n if (process.env.NODE_ENV === 'development') {\n console.log('[parseOgImageData] Parsed JSON:', parsed);\n }\n\n // Ensure all values are strings\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(parsed)) {\n if (value !== undefined && value !== null) {\n result[key] = String(value);\n }\n }\n\n if (process.env.NODE_ENV === 'development') {\n console.log('[parseOgImageData] Result:', result);\n }\n\n return result;\n } catch (decodeError) {\n console.error('[parseOgImageData] Error decoding/parsing data param:', decodeError);\n if (decodeError instanceof Error) {\n console.error('[parseOgImageData] Error message:', decodeError.message);\n }\n // Fall through to legacy query params\n }\n } else {\n if (process.env.NODE_ENV === 'development') {\n console.log('[parseOgImageData] No data param found or empty');\n }\n }\n\n // Fallback to legacy query params format\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(params)) {\n if (key !== 'data' && value !== undefined && value !== null) {\n result[key] = Array.isArray(value) ? value[0] : String(value);\n }\n }\n\n if (process.env.NODE_ENV === 'development') {\n console.log('[parseOgImageData] Fallback result:', result);\n }\n\n return result;\n } catch (error) {\n console.error('[parseOgImageData] Unexpected error:', error);\n return {};\n }\n}\n\n// Export base64 utilities for advanced use cases\nexport { encodeBase64, decodeBase64 };\n","/**\n * Metadata Utilities for OG Images\n *\n * Helpers to automatically add og:image to Next.js metadata\n */\n\nimport type { Metadata } from 'next';\nimport { generateOgImageUrl, getAbsoluteOgImageUrl, OgImageUrlParams} from './url';\n\n/**\n * Options for generating OG image metadata\n */\nexport interface AppMetadataOptions {\n /** Base URL of the OG image API route (e.g., '/api/og') */\n ogImageBaseUrl?: string;\n /** Site URL for absolute URLs (e.g., 'https://example.com') */\n siteUrl?: string;\n /** Default parameters to merge with page-specific params */\n defaultParams?: Partial<OgImageUrlParams>;\n /** Whether to use base64 encoding (default: true) */\n useBase64?: boolean;\n /** Favicon URL (e.g., '/favicon.png') - automatically added to metadata.icons */\n favicon?: string;\n /** Apple touch icon URL (e.g., '/apple-icon.png') - automatically added to metadata.icons */\n appleIcon?: string;\n}\n\n/**\n * Extract title from metadata\n */\nfunction extractTitle(metadata: Metadata): string {\n if (typeof metadata.title === 'string') {\n return metadata.title;\n }\n if (metadata.title) {\n if ('default' in metadata.title) {\n return metadata.title.default;\n }\n if ('absolute' in metadata.title) {\n return metadata.title.absolute;\n }\n }\n return '';\n}\n\n/**\n * Extract description from metadata\n */\nfunction extractDescription(metadata: Metadata): string {\n if (typeof metadata.description === 'string') {\n return metadata.description;\n }\n return '';\n}\n\n/**\n * Generate Next.js metadata with OG image\n *\n * Automatically adds og:image, twitter:image, and other OG meta tags\n * Automatically extracts title and description from metadata if not provided\n *\n * @param metadata - Base metadata object\n * @param ogImageParams - Optional parameters for OG image generation (if not provided, extracted from metadata)\n * @param options - Configuration options\n * @returns Enhanced metadata with OG image\n *\n * @example\n * ```typescript\n * // In page.tsx or layout.tsx\n * import { generateAppMetadata } from '@djangocfg/nextjs/og-image';\n * import { settings } from '@/core/settings';\n *\n * export const metadata = generateAppMetadata(\n * {\n * title: 'My Page',\n * description: 'Page description',\n * },\n * undefined, // Will auto-extract from metadata\n * {\n * ogImageBaseUrl: '/api/og',\n * siteUrl: settings.app.siteUrl,\n * favicon: settings.app.icons.favicon,\n * appleIcon: settings.app.icons.logo192,\n * defaultParams: {\n * siteName: settings.app.name,\n * logo: settings.app.icons.logoVector,\n * },\n * }\n * );\n * ```\n */\n/**\n * Get site URL automatically from environment\n * Priority: NEXT_PUBLIC_SITE_URL > VERCEL_URL > fallback\n */\nfunction getSiteUrl(): string {\n // Try NEXT_PUBLIC_SITE_URL first (most reliable)\n if (typeof process !== 'undefined' && process.env.NEXT_PUBLIC_SITE_URL) {\n return process.env.NEXT_PUBLIC_SITE_URL;\n }\n \n // Development fallback\n return '';\n}\n\nexport function generateAppMetadata(\n metadata: Metadata,\n ogImageParams?: Partial<OgImageUrlParams>,\n options: AppMetadataOptions = {}\n): Metadata {\n const {\n ogImageBaseUrl = 'https://djangocfg.com/api/og',\n siteUrl: providedSiteUrl,\n defaultParams = {},\n useBase64 = true,\n favicon,\n appleIcon,\n } = options;\n\n // Automatically determine siteUrl if not provided or is undefined\n const siteUrl = providedSiteUrl && providedSiteUrl !== 'undefined' \n ? providedSiteUrl \n : getSiteUrl();\n\n // Auto-extract title and description from metadata if not provided\n const extractedTitle = extractTitle(metadata);\n const extractedDescription = extractDescription(metadata);\n\n // Merge with provided params (provided params take precedence)\n const finalOgImageParams: OgImageUrlParams = {\n ...defaultParams,\n title: ogImageParams?.title || extractedTitle || defaultParams.title || '',\n description: ogImageParams?.description || extractedDescription || defaultParams.description || '',\n ...ogImageParams,\n };\n\n // Get alt text for image (title or siteName as fallback)\n const imageAlt = finalOgImageParams.title || finalOgImageParams.siteName;\n\n // Generate relative OG image URL\n const relativeOgImageUrl = generateOgImageUrl(\n finalOgImageParams,\n { baseUrl: ogImageBaseUrl, useBase64 }\n );\n\n // CRITICAL: Use absolute URL to ensure query params are preserved\n // Next.js might strip query params from relative URLs in some cases\n // Absolute URLs ensure the full URL with params is used\n const ogImageUrl = siteUrl\n ? getAbsoluteOgImageUrl(relativeOgImageUrl, siteUrl)\n : relativeOgImageUrl;\n\n // Normalize existing images to arrays\n const existingOgImages = metadata.openGraph?.images\n ? Array.isArray(metadata.openGraph.images)\n ? metadata.openGraph.images\n : [metadata.openGraph.images]\n : [];\n\n const existingTwitterImages = metadata.twitter?.images\n ? Array.isArray(metadata.twitter.images)\n ? metadata.twitter.images\n : [metadata.twitter.images]\n : [];\n\n // Build final metadata object\n const finalMetadata: Metadata = {\n ...metadata,\n openGraph: {\n ...metadata.openGraph,\n images: [\n ...existingOgImages,\n {\n url: ogImageUrl,\n width: 1200,\n height: 630,\n alt: imageAlt,\n },\n ],\n },\n twitter: {\n ...metadata.twitter,\n card: 'summary_large_image',\n images: [\n ...existingTwitterImages,\n {\n url: ogImageUrl,\n alt: imageAlt,\n },\n ],\n },\n };\n\n // Automatically add metadataBase if siteUrl is an absolute URL\n // metadataBase requires absolute URL - skip if siteUrl is relative path (like /cfg/admin)\n // Only add if not already set in input metadata\n if (!finalMetadata.metadataBase && siteUrl) {\n // Check if siteUrl is an absolute URL (starts with http:// or https://)\n if (siteUrl.startsWith('http://') || siteUrl.startsWith('https://')) {\n try {\n finalMetadata.metadataBase = new URL(siteUrl);\n } catch (e) {\n // If URL construction fails, skip metadataBase\n // This shouldn't happen if we check for http/https, but just in case\n }\n }\n }\n\n // Add favicon and apple icon if provided\n if (favicon || appleIcon) {\n // metadata.icons can be string, array, or object - only spread if it's an object\n const existingIcons = metadata.icons && typeof metadata.icons === 'object' && !Array.isArray(metadata.icons)\n ? metadata.icons\n : {};\n finalMetadata.icons = {\n ...existingIcons,\n ...(favicon && { icon: favicon }),\n ...(appleIcon && { apple: appleIcon }),\n };\n }\n\n return finalMetadata;\n}\n\n/**\n * Create OG image metadata generator with preset configuration\n *\n * Useful when you want to reuse the same configuration across multiple pages\n *\n * @param options - Configuration options\n * @returns Metadata generator function\n *\n * @example\n * ```typescript\n * // In a shared file (e.g., lib/metadata.ts)\n * import { createAppMetadataGenerator } from '@djangocfg/nextjs/og-image';\n * import { settings } from '@/core/settings';\n *\n * export const generateMetadata = createAppMetadataGenerator({\n * ogImageBaseUrl: '/api/og',\n * siteUrl: settings.app.siteUrl,\n * favicon: settings.app.icons.favicon,\n * appleIcon: settings.app.icons.logo192,\n * defaultParams: {\n * siteName: settings.app.name,\n * logo: settings.app.icons.logoVector,\n * },\n * });\n *\n * // In page.tsx\n * import { generateMetadata } from '@/lib/metadata';\n *\n * export const metadata = generateMetadata({\n * title: 'My Page',\n * description: 'Description',\n * });\n * ```\n */\nexport function createAppMetadataGenerator(\n options: AppMetadataOptions\n) {\n return (\n metadata: Metadata,\n ogImageParams?: Partial<OgImageUrlParams>\n ): Metadata => {\n return generateAppMetadata(metadata, ogImageParams, options);\n };\n}\n\n","/**\n * Navigation Utilities\n *\n * Common utilities for route definitions and navigation\n */\n\nimport type { RouteDefinition, RouteMetadata, MenuItem } from './types';\n\n// ─────────────────────────────────────────────────────────────────────────\n// Route Definition Helper\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Define a route with metadata\n *\n * IMPORTANT: Next.js automatically handles basePath for <Link> components when\n * basePath is set in next.config.ts. We should NOT add basePath manually here,\n * as it would cause double-prefixing in static builds.\n *\n * @param path - Route path (e.g., '/dashboard', '/admin/users')\n * @param metadata - Route metadata (label, icon, etc.)\n */\nexport function defineRoute(\n path: string,\n metadata: RouteMetadata,\n): RouteDefinition {\n // Always return path as-is. Next.js will handle basePath automatically\n // for <Link> components when basePath is set in next.config.ts\n return {\n path,\n metadata,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Route Guards\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Get redirect path for unauthenticated users\n */\nexport function getUnauthenticatedRedirect(\n path: string,\n authPath: string = '/auth',\n): string | null {\n if (path.startsWith('/private') || path.startsWith('/admin')) {\n // Return path as-is. Next.js will handle basePath automatically for router.push()\n // when basePath is set in next.config.ts\n return authPath;\n }\n return null;\n}\n\n/**\n * Get redirect path to auth page\n */\nexport function redirectToAuth(\n authPath: string = '/auth',\n): string {\n // Return path as-is. Next.js will handle basePath automatically for router.push()\n // when basePath is set in next.config.ts\n return authPath;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Route Lookup\n// ─────────────────────────────────────────────────────────────────────────\n\nexport function findRoute(\n routes: RouteDefinition[],\n path: string\n): RouteDefinition | undefined {\n return routes.find((r) => r.path === path);\n}\n\nexport function findRouteByPattern(\n routes: RouteDefinition[],\n path: string\n): RouteDefinition | undefined {\n const exact = findRoute(routes, path);\n if (exact) return exact;\n\n const segments = path.split('/').filter(Boolean);\n for (let i = segments.length; i > 0; i--) {\n const parentPath = '/' + segments.slice(0, i).join('/');\n const parent = findRoute(routes, parentPath);\n if (parent) return parent;\n }\n\n return undefined;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Page Title\n// ─────────────────────────────────────────────────────────────────────────\n\nexport function getPageTitle(\n routes: RouteDefinition[],\n path: string,\n fallback = 'Dashboard'\n): string {\n const route = findRouteByPattern(routes, path);\n return route?.metadata.label || fallback;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Active Route\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Check if a route is active\n *\n * @param current - Current pathname\n * @param target - Target route path to check\n * @param allRoutes - Optional array of all routes to prevent parent paths from being active when child paths are active\n * @returns true if the route is active\n */\nexport function isActive(\n current: string,\n target: string,\n allRoutes?: RouteDefinition[]\n): boolean {\n const matches =\n current === target || (target !== '/' && current.startsWith(target + '/'));\n\n // If allRoutes is provided, check for more specific paths\n if (matches && allRoutes) {\n return !allRoutes.some(\n (otherRoute) =>\n otherRoute.path !== target &&\n otherRoute.path.startsWith(target + '/') &&\n (current === otherRoute.path ||\n current.startsWith(otherRoute.path + '/'))\n );\n }\n\n return matches;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Menu Generation Helper\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Filter and convert routes to menu items\n */\nexport function routesToMenuItems(\n routes: RouteDefinition[],\n groupName: string\n): MenuItem[] {\n return routes\n .filter(\n (r) =>\n r.metadata.group === groupName &&\n r.metadata.icon &&\n (r.metadata.show === undefined || r.metadata.show === true)\n )\n .sort((a, b) => (a.metadata.order || 0) - (b.metadata.order || 0))\n .map((r) => ({\n path: r.path,\n label: r.metadata.label,\n icon: r.metadata.icon!,\n }));\n}\n\n","/**\n * PWA (Progressive Web App) Plugin\n *\n * Configures Serwist for service worker and offline support\n * Modern PWA solution for Next.js 15+ with App Router\n *\n * @see https://serwist.pages.dev/\n */\n\nimport type { NextConfig } from 'next';\nimport { consola } from 'consola';\n\nexport interface PWAPluginOptions {\n /**\n * Destination directory for service worker files\n * @default 'public'\n * @deprecated Use swDest instead\n */\n dest?: string;\n\n /**\n * Path to service worker source file (relative to project root)\n * @default 'app/sw.ts'\n */\n swSrc?: string;\n\n /**\n * Destination for compiled service worker\n * @default 'public/sw.js'\n */\n swDest?: string;\n\n /**\n * Disable PWA completely\n * @default false in production, true in development\n * @example disable: process.env.NODE_ENV === 'development'\n */\n disable?: boolean;\n\n /**\n * Cache on navigation - cache pages when navigating\n * @default true\n */\n cacheOnNavigation?: boolean;\n\n /**\n * Reload app when device goes back online\n * @default true\n */\n reloadOnOnline?: boolean;\n\n /**\n * Additional Serwist options\n * @see https://serwist.pages.dev/docs/next/configuring\n */\n serwistOptions?: Record<string, any>;\n}\n\n/**\n * Add PWA configuration to Next.js config using Serwist\n *\n * @example Basic usage\n * ```ts\n * import { createBaseNextConfig, withPWA } from '@djangocfg/nextjs/config';\n *\n * const nextConfig = createBaseNextConfig({...});\n *\n * export default withPWA(nextConfig, {\n * swSrc: 'app/sw.ts',\n * disable: process.env.NODE_ENV === 'development',\n * });\n * ```\n *\n * @example Integrated with createBaseNextConfig\n * ```ts\n * import { createBaseNextConfig } from '@djangocfg/nextjs/config';\n *\n * const config = createBaseNextConfig({\n * pwa: {\n * swSrc: 'app/sw.ts',\n * disable: false,\n * },\n * });\n *\n * export default config;\n * ```\n */\nexport function withPWA(\n nextConfig: NextConfig,\n options: PWAPluginOptions = {}\n): NextConfig {\n const isDev = process.env.NODE_ENV === 'development';\n const isStaticBuild = process.env.NEXT_PUBLIC_STATIC_BUILD === 'true';\n\n // Determine if PWA should be disabled:\n // - Explicitly disabled via options\n // - In development mode (default)\n // - Static build (output: 'export' doesn't support service workers)\n const shouldDisable = options.disable !== undefined\n ? options.disable\n : (isDev || isStaticBuild);\n\n const defaultOptions: PWAPluginOptions = {\n swSrc: 'app/sw.ts',\n swDest: 'public/sw.js',\n disable: shouldDisable,\n cacheOnNavigation: true,\n reloadOnOnline: true,\n ...options,\n };\n\n try {\n // Suppress Turbopack warning - it only applies to dev mode, not production builds\n // The warning is misleading when running `next build` with Turbopack\n // See: https://github.com/serwist/serwist/issues/54\n if (!process.env.SERWIST_SUPPRESS_TURBOPACK_WARNING) {\n process.env.SERWIST_SUPPRESS_TURBOPACK_WARNING = '1';\n }\n\n const withSerwistInit = require('@serwist/next').default;\n\n const withSerwist = withSerwistInit({\n swSrc: defaultOptions.swSrc,\n swDest: defaultOptions.swDest,\n disable: defaultOptions.disable,\n cacheOnNavigation: defaultOptions.cacheOnNavigation,\n reloadOnOnline: defaultOptions.reloadOnOnline,\n ...defaultOptions.serwistOptions,\n });\n\n return withSerwist(nextConfig);\n } catch (error) {\n consola.error('Failed to configure Serwist:', error);\n return nextConfig;\n }\n}\n\n/**\n * Get service worker template content\n *\n * Returns ready-to-use service worker code for app/sw.ts\n *\n * @example\n * ```ts\n * import { getServiceWorkerTemplate } from '@djangocfg/nextjs/config';\n *\n * // Copy this to your app/sw.ts file\n * console.log(getServiceWorkerTemplate());\n * ```\n */\nexport function getServiceWorkerTemplate(): string {\n return `/**\n * Service Worker (Serwist)\n *\n * Modern PWA service worker using Serwist\n */\n\nimport { defaultCache } from '@serwist/next/worker';\nimport { Serwist } from 'serwist';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ndeclare const self: any;\n\nconst serwist = new Serwist({\n // Precache entries injected by Serwist build plugin\n precacheEntries: self.__SW_MANIFEST,\n\n // Skip waiting - activate new SW immediately\n skipWaiting: true,\n\n // Take control of all clients immediately\n clientsClaim: true,\n\n // Enable navigation preload for faster loads\n navigationPreload: true,\n\n // Use default Next.js runtime caching strategies\n runtimeCaching: defaultCache,\n\n // Fallback pages for offline\n fallbacks: {\n entries: [\n {\n url: '/_offline',\n matcher({ request }) {\n return request.destination === 'document';\n },\n },\n ],\n },\n});\n\nserwist.addEventListeners();\n`;\n}\n\n// Backward compatibility exports (deprecated)\nexport const defaultRuntimeCaching = [];\nexport function createApiCacheRule() {\n consola.warn('createApiCacheRule is deprecated with Serwist. Use defaultCache from @serwist/next/worker');\n return {};\n}\nexport function createStaticAssetRule() {\n consola.warn('createStaticAssetRule is deprecated with Serwist. Use defaultCache from @serwist/next/worker');\n return {};\n}\nexport function createCdnCacheRule() {\n consola.warn('createCdnCacheRule is deprecated with Serwist. Use defaultCache from @serwist/next/worker');\n return {};\n}\n","/**\n * Shared Constants for DjangoCFG Next.js Configuration\n */\n\n// Package name for version checks\nexport const PACKAGE_NAME = '@djangocfg/nextjs';\n\n// Version cache TTL (1 hour)\nexport const VERSION_CACHE_TTL_MS = 60 * 60 * 1000;\n\n// ASCII Art Banner for Django CFG\nexport const DJANGO_CFG_BANNER = `\n██████╗ ██╗ █████╗ ███╗ ██╗ ██████╗ ██████╗ ██████╗███████╗ ██████╗\n██╔══██╗ ██║██╔══██╗████╗ ██║██╔════╝ ██╔═══██╗ ██╔════╝██╔════╝██╔════╝\n██║ ██║ ██║███████║██╔██╗ ██║██║ ███╗██║ ██║ ██║ █████╗ ██║ ███╗\n██║ ██║██ ██║██╔══██║██║╚██╗██║██║ ██║██║ ██║ ██║ ██╔══╝ ██║ ██║\n██████╔╝╚█████╔╝██║ ██║██║ ╚████║╚██████╔╝╚██████╔╝ ╚██████╗██║ ╚██████╔╝\n╚═════╝ ╚════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═════╝ ╚═════╝╚═╝ ╚═════╝\n`;\n\n// All @djangocfg packages that can be updated together\nexport const DJANGOCFG_PACKAGES = [\n '@djangocfg/ui-core',\n '@djangocfg/ui-nextjs',\n '@djangocfg/layouts',\n '@djangocfg/nextjs',\n '@djangocfg/api',\n '@djangocfg/centrifugo',\n '@djangocfg/eslint-config',\n '@djangocfg/typescript-config',\n] as const;\n\n// Default packages to transpile\nexport const DEFAULT_TRANSPILE_PACKAGES = [\n '@djangocfg/ui-core',\n '@djangocfg/ui-nextjs',\n '@djangocfg/layouts',\n '@djangocfg/api',\n '@djangocfg/centrifugo',\n] as const;\n\n// Default packages to optimize imports\nexport const DEFAULT_OPTIMIZE_PACKAGES = [\n '@djangocfg/ui-core',\n '@djangocfg/ui-nextjs',\n '@djangocfg/layouts',\n 'lucide-react',\n 'recharts',\n] as const;\n","/**\n * Package Checker\n *\n * Checks which optional packages are missing and need to be installed.\n */\n\nimport { createRequire } from 'module';\nimport { join } from 'path';\n\nimport { isDev, isStaticBuild } from '../utils/env';\nimport { getPackagesForContext, OPTIONAL_PACKAGES } from './definitions';\n\nimport type { PackageDefinition } from './definitions';\nexport interface MissingPackage extends PackageDefinition {\n /** Why is this package needed? */\n reason: string;\n}\n\n/**\n * Check if a package is installed in the consumer's project\n * Uses process.cwd() to check from the consumer's context, not the library's\n */\nexport function isPackageInstalled(packageName: string): boolean {\n try {\n // Create require from consumer's cwd to check their node_modules\n const consumerRequire = createRequire(join(process.cwd(), 'package.json'));\n consumerRequire.resolve(packageName);\n return true;\n } catch {\n // Fallback: try regular require (for packages hoisted to root)\n try {\n require.resolve(packageName);\n return true;\n } catch {\n return false;\n }\n }\n}\n\n/**\n * Get all missing packages for current context\n */\nexport function getMissingPackages(): MissingPackage[] {\n const neededPackages = getPackagesForContext({ isStaticBuild, isDev });\n const missing: MissingPackage[] = [];\n\n for (const pkg of neededPackages) {\n if (!isPackageInstalled(pkg.name)) {\n missing.push({\n ...pkg,\n reason: getReasonText(pkg),\n });\n }\n }\n\n return missing;\n}\n\n/**\n * Check specific packages\n */\nexport function checkPackages(packageNames: string[]): MissingPackage[] {\n const missing: MissingPackage[] = [];\n\n for (const name of packageNames) {\n if (!isPackageInstalled(name)) {\n const definition = OPTIONAL_PACKAGES.find(p => p.name === name);\n missing.push({\n name,\n description: definition?.description || 'Optional package',\n condition: definition?.condition || 'always',\n devDependency: definition?.devDependency ?? true,\n reason: definition ? getReasonText(definition) : 'Requested by configuration',\n });\n }\n }\n\n return missing;\n}\n\n/**\n * Get human-readable reason for package requirement\n */\nfunction getReasonText(pkg: PackageDefinition): string {\n switch (pkg.condition) {\n case 'static-build':\n return 'Required for static build (NEXT_PUBLIC_STATIC_BUILD=true)';\n case 'dev':\n return 'Required for development mode';\n case 'always':\n return 'Required for all builds';\n default:\n return 'Optional feature';\n }\n}\n","/**\n * Environment Variable Utilities\n */\n\nexport const isStaticBuild = process.env.NEXT_PUBLIC_STATIC_BUILD === 'true';\nexport const isDev = process.env.NODE_ENV === 'development';\nexport const isProduction = process.env.NODE_ENV === 'production';\nexport const isCI = process.env.CI === 'true';\n\n/**\n * Get base path for static builds\n */\nexport function getBasePath(isDefaultCfgAdmin?: boolean): string {\n if (!isStaticBuild) return '';\n return isDefaultCfgAdmin ? '/cfg/admin' : '/cfg/nextjs-admin';\n}\n\n/**\n * Get API URL (empty for static builds)\n */\nexport function getApiUrl(): string {\n return isStaticBuild ? '' : (process.env.NEXT_PUBLIC_API_URL || '');\n}\n\n/**\n * Get Site URL (empty for static builds)\n */\nexport function getSiteUrl(): string {\n return isStaticBuild ? '' : (process.env.NEXT_PUBLIC_SITE_URL || '');\n}\n","/**\n * Package Definitions\n *\n * Defines optional packages that can be auto-installed when needed.\n */\n\nexport interface PackageDefinition {\n /** npm package name */\n name: string;\n /** Human-readable description */\n description: string;\n /** When is this package needed? */\n condition: 'static-build' | 'dev' | 'always';\n /** Is this a dev dependency? */\n devDependency: boolean;\n /** Feature flag that enables this package */\n featureFlag?: string;\n}\n\n/**\n * Optional packages that can be auto-installed\n */\nexport const OPTIONAL_PACKAGES: PackageDefinition[] = [\n {\n name: 'compression-webpack-plugin',\n description: 'Gzip and Brotli compression for static builds',\n condition: 'static-build',\n devDependency: true,\n },\n {\n name: '@next/bundle-analyzer',\n description: 'Bundle analyzer for analyzing build output',\n condition: 'dev',\n devDependency: true,\n featureFlag: 'ANALYZE',\n },\n];\n\n/**\n * Required peer dependencies (should already be installed)\n */\nexport const PEER_DEPENDENCIES = [\n 'next',\n 'react',\n 'react-dom',\n] as const;\n\n/**\n * Get packages needed for current build context\n */\nexport function getPackagesForContext(options: {\n isStaticBuild: boolean;\n isDev: boolean;\n}): PackageDefinition[] {\n return OPTIONAL_PACKAGES.filter(pkg => {\n switch (pkg.condition) {\n case 'static-build':\n return options.isStaticBuild;\n case 'dev':\n return options.isDev;\n case 'always':\n return true;\n default:\n return false;\n }\n });\n}\n","/**\n * Compression Plugin Setup\n *\n * Adds Gzip and Brotli compression for static builds.\n */\n\nimport type { Configuration as WebpackConfig } from 'webpack';\nimport { isPackageInstalled } from '../packages/checker';\n\nexport interface CompressionPluginOptions {\n /** Enable gzip compression */\n gzip?: boolean;\n /** Enable brotli compression */\n brotli?: boolean;\n /** Minimum file size to compress (default: 8192) */\n threshold?: number;\n /** Minimum compression ratio (default: 0.8) */\n minRatio?: number;\n /** Brotli compression level (default: 8) */\n brotliLevel?: number;\n}\n\nconst DEFAULT_OPTIONS: Required<CompressionPluginOptions> = {\n gzip: true,\n brotli: true,\n threshold: 8192,\n minRatio: 0.8,\n brotliLevel: 8,\n};\n\n/**\n * Add compression plugins to webpack config\n *\n * Returns true if plugins were added, false if compression-webpack-plugin is not installed\n */\nexport function addCompressionPlugins(\n config: WebpackConfig,\n options: CompressionPluginOptions = {}\n): boolean {\n // Check if compression-webpack-plugin is installed\n if (!isPackageInstalled('compression-webpack-plugin')) {\n return false;\n }\n\n const opts = { ...DEFAULT_OPTIONS, ...options };\n\n try {\n // Dynamic import to avoid bundling if not installed\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const CompressionPlugin = require('compression-webpack-plugin');\n\n if (!config.plugins) {\n config.plugins = [];\n }\n\n // Gzip compression\n if (opts.gzip) {\n config.plugins.push(\n new CompressionPlugin({\n filename: '[path][base].gz',\n algorithm: 'gzip',\n test: /\\.(js|css|html|svg|json)$/,\n threshold: opts.threshold,\n minRatio: opts.minRatio,\n })\n );\n }\n\n // Brotli compression\n if (opts.brotli) {\n config.plugins.push(\n new CompressionPlugin({\n filename: '[path][base].br',\n algorithm: 'brotliCompress',\n test: /\\.(js|css|html|svg|json)$/,\n threshold: opts.threshold,\n minRatio: opts.minRatio,\n compressionOptions: {\n level: opts.brotliLevel,\n },\n })\n );\n }\n\n return true;\n } catch (error) {\n // compression-webpack-plugin failed to load\n return false;\n }\n}\n\n/**\n * Check if compression is available\n */\nexport function isCompressionAvailable(): boolean {\n return isPackageInstalled('compression-webpack-plugin');\n}\n","/**\n * Dev Startup Webpack Plugin\n *\n * Handles banner display, version checking, and package updates.\n */\n\nimport type { Compiler } from 'webpack';\nimport chalk from 'chalk';\n\nimport { AI_DOCS_HINT } from '../../ai/constants';\nimport { DJANGO_CFG_BANNER } from '../constants';\nimport { checkAndInstallPackages } from '../packages/installer';\nimport { checkAndUpdatePackages } from '../packages/updater';\nimport { getCurrentVersion } from '../utils/version';\n\n// Track if startup tasks were already run (persists across HMR)\nlet startupDone = false;\n\nexport interface DevStartupPluginOptions {\n /** Check for missing optional packages (default: true) */\n checkPackages?: boolean;\n /** Auto-install missing packages without prompting */\n autoInstall?: boolean;\n /** Check for @djangocfg/* package updates (default: true) */\n checkUpdates?: boolean;\n /** Auto-update packages without prompting */\n autoUpdate?: boolean;\n /** Force check workspace:* packages (for testing in monorepo) */\n forceCheckWorkspace?: boolean;\n}\n\n/**\n * Webpack plugin for dev startup tasks\n */\nexport class DevStartupPlugin {\n private options: DevStartupPluginOptions;\n\n constructor(options: DevStartupPluginOptions = {}) {\n this.options = options;\n }\n\n apply(compiler: Compiler): void {\n // Use tapPromise for proper async handling\n compiler.hooks.done.tapPromise('DevStartupPlugin', async () => {\n // Run startup tasks only once\n if (!startupDone) {\n startupDone = true;\n await this.runStartupTasks();\n }\n });\n }\n\n private async runStartupTasks(): Promise<void> {\n // 1. Print banner\n console.log('\\n' + chalk.yellowBright.bold(DJANGO_CFG_BANNER));\n\n // 2. Print current version\n const version = getCurrentVersion();\n if (version) {\n console.log(chalk.dim(` 📦 @djangocfg/nextjs v${version}`));\n }\n\n // 3. Check PWA setup\n this.checkPWASetup();\n\n // 4. Print AI docs hint\n console.log(chalk.magenta(` ${AI_DOCS_HINT}\\n`));\n\n // 5. Check for package updates\n if (this.options.checkUpdates !== false) {\n try {\n await checkAndUpdatePackages({\n autoUpdate: this.options.autoUpdate,\n forceCheckWorkspace: this.options.forceCheckWorkspace,\n force: true, // Force check ignoring cooldown\n });\n } catch (err) {\n console.log(chalk.red(' Update check failed:'), err);\n }\n }\n\n // 6. Check for missing optional packages\n if (this.options.checkPackages !== false) {\n await checkAndInstallPackages({\n autoInstall: this.options.autoInstall,\n });\n }\n }\n\n private checkPWASetup(): void {\n const fs = require('fs');\n const path = require('path');\n\n const cwd = process.cwd();\n const swPath = path.join(cwd, 'app', 'sw.ts');\n const manifestPath = path.join(cwd, 'app', 'manifest.ts');\n\n const hasSW = fs.existsSync(swPath);\n const hasManifest = fs.existsSync(manifestPath);\n\n if (hasSW || hasManifest) {\n console.log(chalk.cyan(' 📱 PWA Configuration:'));\n\n if (hasSW) {\n console.log(chalk.green(' ✓ Service Worker: app/sw.ts'));\n } else {\n console.log(chalk.yellow(' ⚠ Service Worker: not found'));\n }\n\n if (hasManifest) {\n console.log(chalk.green(' ✓ Manifest: app/manifest.ts'));\n } else {\n console.log(chalk.yellow(' ⚠ Manifest: not found'));\n }\n\n console.log(chalk.dim(' → Check: DevTools → Application → Service Workers'));\n console.log(chalk.dim(' → Test push: import from @djangocfg/nextjs/pwa'));\n }\n }\n}\n\n/**\n * Reset plugin state (useful for tests)\n */\nexport function resetDevStartupState(): void {\n startupDone = false;\n}\n","/**\n * AI Documentation Constants\n */\n\n// MCP Server URLs\nexport const MCP_BASE_URL = 'https://mcp.djangocfg.com';\nexport const MCP_SERVER_URL = `${MCP_BASE_URL}/mcp`;\nexport const MCP_API_URL = `${MCP_BASE_URL}/api/search`;\n\n// API Endpoints\nexport const API_SEARCH_ENDPOINT = '/api/search';\nexport const API_INFO_ENDPOINT = '/api/info';\nexport const DEFAULT_TIMEOUT = 10000; // ms\n\n// AI Hint for console output\nexport const AI_DOCS_HINT = `🤖 AI Docs: ${MCP_SERVER_URL} | pnpm ai-docs search \"query\"`;\n\n// Full AI Hint description\nexport const AI_HINT = `\nDjangoCFG Documentation is available via MCP server.\n\nTo get help with DjangoCFG configuration:\n1. Use the MCP server: ${MCP_SERVER_URL}\n2. Or search directly: ${MCP_API_URL}?q=YOUR_QUERY&limit=5\n\nExample queries:\n- \"How to configure PostgreSQL database?\"\n- \"What is DatabaseConfig?\"\n- \"How to setup Redis cache?\"\n- \"Email configuration with SMTP\"\n`;\n","/**\n * Package Installer\n *\n * Provides auto-installation functionality with user confirmation and progress indication.\n */\n\nimport chalk from 'chalk';\nimport { execSync, spawn } from 'child_process';\nimport Conf from 'conf';\nimport consola from 'consola';\nimport { createInterface } from 'readline';\n\nimport { isCI } from '../utils/env';\nimport { getMissingPackages } from './checker';\n\nimport type { MissingPackage } from './checker';\n// Installer preferences cache\nconst installerCache = new Conf<{\n autoInstall?: boolean;\n skipPackages?: string[];\n lastPrompt?: number;\n}>({\n projectName: 'djangocfg-nextjs-installer',\n projectVersion: '1.0.0',\n});\n\n// Don't prompt more than once per hour\nconst PROMPT_COOLDOWN_MS = 60 * 60 * 1000;\n\n// Spinner frames for progress\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\nexport interface InstallOptions {\n /** Auto-install without prompting */\n autoInstall?: boolean;\n /** Skip specific packages */\n skipPackages?: string[];\n /** Force prompt even if recently prompted */\n force?: boolean;\n}\n\nexport interface InstallProgress {\n current: number;\n total: number;\n package: string;\n status: 'pending' | 'installing' | 'done' | 'error';\n}\n\n/**\n * Detect package manager\n */\nexport function detectPackageManager(): 'pnpm' | 'yarn' | 'npm' {\n try {\n // Check for lockfiles\n const fs = require('fs');\n const path = require('path');\n const cwd = process.cwd();\n\n if (fs.existsSync(path.join(cwd, 'pnpm-lock.yaml'))) return 'pnpm';\n if (fs.existsSync(path.join(cwd, 'yarn.lock'))) return 'yarn';\n if (fs.existsSync(path.join(cwd, 'package-lock.json'))) return 'npm';\n\n // Check for global package manager\n try {\n execSync('pnpm --version', { stdio: 'ignore' });\n return 'pnpm';\n } catch {\n try {\n execSync('yarn --version', { stdio: 'ignore' });\n return 'yarn';\n } catch {\n return 'npm';\n }\n }\n } catch {\n return 'npm';\n }\n}\n\n/**\n * Build install command for a single package\n */\nexport function buildSingleInstallCommand(\n packageName: string,\n isDev: boolean,\n pm: 'pnpm' | 'yarn' | 'npm'\n): string {\n const devFlag = isDev ? '-D ' : '';\n switch (pm) {\n case 'pnpm':\n return `pnpm add ${devFlag}${packageName}`;\n case 'yarn':\n return `yarn add ${devFlag}${packageName}`;\n case 'npm':\n return `npm install ${devFlag}${packageName}`;\n }\n}\n\n/**\n * Build install command for multiple packages (for display)\n */\nexport function buildInstallCommand(packages: MissingPackage[], pm: 'pnpm' | 'yarn' | 'npm'): string {\n const devPackages = packages.filter(p => p.devDependency).map(p => p.name);\n const prodPackages = packages.filter(p => !p.devDependency).map(p => p.name);\n\n const commands: string[] = [];\n\n if (devPackages.length > 0) {\n switch (pm) {\n case 'pnpm':\n commands.push(`pnpm add -D ${devPackages.join(' ')}`);\n break;\n case 'yarn':\n commands.push(`yarn add -D ${devPackages.join(' ')}`);\n break;\n case 'npm':\n commands.push(`npm install -D ${devPackages.join(' ')}`);\n break;\n }\n }\n\n if (prodPackages.length > 0) {\n switch (pm) {\n case 'pnpm':\n commands.push(`pnpm add ${prodPackages.join(' ')}`);\n break;\n case 'yarn':\n commands.push(`yarn add ${prodPackages.join(' ')}`);\n break;\n case 'npm':\n commands.push(`npm install ${prodPackages.join(' ')}`);\n break;\n }\n }\n\n return commands.join(' && ');\n}\n\n/**\n * Ask user for confirmation via readline\n */\nasync function askConfirmation(question: string): Promise<boolean> {\n // Skip prompt in CI or non-TTY environments\n if (isCI || !process.stdin.isTTY) {\n return false;\n }\n\n return new Promise((resolve) => {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n rl.question(question, (answer) => {\n rl.close();\n const normalized = answer.toLowerCase().trim();\n resolve(normalized === '' || normalized === 'y' || normalized === 'yes');\n });\n });\n}\n\n/**\n * Create a simple spinner\n */\nfunction createSpinner(text: string) {\n let frameIndex = 0;\n let interval: NodeJS.Timeout | null = null;\n let currentText = text;\n\n const render = () => {\n const frame = SPINNER_FRAMES[frameIndex];\n process.stdout.write(`\\r${chalk.cyan(frame)} ${currentText}`);\n frameIndex = (frameIndex + 1) % SPINNER_FRAMES.length;\n };\n\n return {\n start() {\n if (process.stdout.isTTY) {\n interval = setInterval(render, 80);\n render();\n } else {\n console.log(` ${currentText}`);\n }\n return this;\n },\n text(newText: string) {\n currentText = newText;\n if (!process.stdout.isTTY) {\n console.log(` ${newText}`);\n }\n return this;\n },\n succeed(text?: string) {\n if (interval) clearInterval(interval);\n if (process.stdout.isTTY) {\n process.stdout.write(`\\r${chalk.green('✓')} ${text || currentText}\\n`);\n } else {\n console.log(` ${chalk.green('✓')} ${text || currentText}`);\n }\n return this;\n },\n fail(text?: string) {\n if (interval) clearInterval(interval);\n if (process.stdout.isTTY) {\n process.stdout.write(`\\r${chalk.red('✗')} ${text || currentText}\\n`);\n } else {\n console.log(` ${chalk.red('✗')} ${text || currentText}`);\n }\n return this;\n },\n stop() {\n if (interval) clearInterval(interval);\n if (process.stdout.isTTY) {\n process.stdout.write('\\r\\x1b[K'); // Clear line\n }\n return this;\n },\n };\n}\n\n/**\n * Install a single package with progress\n */\nasync function installSinglePackage(\n pkg: MissingPackage,\n pm: 'pnpm' | 'yarn' | 'npm',\n index: number,\n total: number\n): Promise<boolean> {\n const command = buildSingleInstallCommand(pkg.name, pkg.devDependency, pm);\n const progress = `[${index + 1}/${total}]`;\n const spinner = createSpinner(`${chalk.dim(progress)} Installing ${chalk.cyan(pkg.name)}...`);\n\n spinner.start();\n\n return new Promise((resolve) => {\n const [cmd, ...args] = command.split(' ');\n const proc = spawn(cmd, args, {\n shell: true,\n cwd: process.cwd(),\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n let stderr = '';\n\n proc.stderr?.on('data', (data) => {\n stderr += data.toString();\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n spinner.succeed(`${chalk.dim(progress)} ${chalk.cyan(pkg.name)} ${chalk.green('installed')}`);\n resolve(true);\n } else {\n spinner.fail(`${chalk.dim(progress)} ${chalk.cyan(pkg.name)} ${chalk.red('failed')}`);\n if (stderr) {\n console.log(chalk.dim(` ${stderr.split('\\n')[0]}`));\n }\n resolve(false);\n }\n });\n\n proc.on('error', () => {\n spinner.fail(`${chalk.dim(progress)} ${chalk.cyan(pkg.name)} ${chalk.red('failed')}`);\n resolve(false);\n });\n });\n}\n\n/**\n * Install packages with progress indication\n */\nexport async function installPackagesWithProgress(packages: MissingPackage[]): Promise<boolean> {\n if (packages.length === 0) return true;\n\n const pm = detectPackageManager();\n const total = packages.length;\n\n console.log('');\n console.log(chalk.bold(` Installing ${total} package${total > 1 ? 's' : ''}...`));\n console.log('');\n\n let successCount = 0;\n let failedPackages: string[] = [];\n\n for (let i = 0; i < packages.length; i++) {\n const success = await installSinglePackage(packages[i], pm, i, total);\n if (success) {\n successCount++;\n } else {\n failedPackages.push(packages[i].name);\n }\n }\n\n console.log('');\n\n if (failedPackages.length === 0) {\n consola.success(`All ${total} packages installed successfully!`);\n return true;\n } else if (successCount > 0) {\n consola.warn(`${successCount}/${total} packages installed. Failed: ${failedPackages.join(', ')}`);\n return false;\n } else {\n consola.error(`Failed to install packages: ${failedPackages.join(', ')}`);\n return false;\n }\n}\n\n/**\n * Install packages (simple version without per-package progress)\n */\nexport async function installPackages(packages: MissingPackage[]): Promise<boolean> {\n // Use progress version for multiple packages in TTY\n if (packages.length > 1 && process.stdout.isTTY) {\n return installPackagesWithProgress(packages);\n }\n\n // Simple installation for single package or non-TTY\n if (packages.length === 0) return true;\n\n const pm = detectPackageManager();\n const command = buildInstallCommand(packages, pm);\n\n consola.info(`Installing: ${chalk.cyan(packages.map(p => p.name).join(', '))}`);\n\n const spinner = createSpinner('Installing packages...');\n spinner.start();\n\n return new Promise((resolve) => {\n const proc = spawn(command, {\n shell: true,\n cwd: process.cwd(),\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n spinner.succeed('Packages installed successfully!');\n resolve(true);\n } else {\n spinner.fail('Failed to install packages');\n resolve(false);\n }\n });\n\n proc.on('error', () => {\n spinner.fail('Installation failed');\n resolve(false);\n });\n });\n}\n\n/**\n * Check and prompt for missing packages\n *\n * Returns true if all packages are available (either already installed or just installed)\n */\nexport async function checkAndInstallPackages(options: InstallOptions = {}): Promise<boolean> {\n const missing = getMissingPackages();\n\n // Filter out skipped packages\n const skipList = options.skipPackages || installerCache.get('skipPackages') || [];\n const toInstall = missing.filter(p => !skipList.includes(p.name));\n\n if (toInstall.length === 0) {\n return true;\n }\n\n // Check cooldown (don't prompt too often)\n const lastPrompt = installerCache.get('lastPrompt') || 0;\n if (!options.force && (Date.now() - lastPrompt) < PROMPT_COOLDOWN_MS) {\n // Show info but don't prompt\n printMissingPackagesInfo(toInstall);\n return false;\n }\n\n // Auto-install if configured\n if (options.autoInstall || installerCache.get('autoInstall')) {\n return installPackages(toInstall);\n }\n\n // Show missing packages\n console.log('');\n consola.box('📦 Missing Optional Packages');\n console.log('');\n\n for (const pkg of toInstall) {\n console.log(` ${chalk.yellow('•')} ${chalk.bold(pkg.name)}`);\n console.log(` ${chalk.dim(pkg.description)}`);\n console.log(` ${chalk.dim(pkg.reason)}`);\n console.log('');\n }\n\n // Build install command for display\n const pm = detectPackageManager();\n const command = buildInstallCommand(toInstall, pm);\n\n console.log(` ${chalk.cyan('Command:')} ${command}`);\n console.log('');\n\n // Ask for confirmation\n installerCache.set('lastPrompt', Date.now());\n\n const shouldInstall = await askConfirmation(\n `${chalk.green('?')} Install these packages now? ${chalk.dim('[Y/n]')} `\n );\n\n if (shouldInstall) {\n const success = await installPackages(toInstall);\n\n // Ask if user wants to enable auto-install for future\n if (success) {\n const enableAuto = await askConfirmation(\n `${chalk.green('?')} Enable auto-install for future? ${chalk.dim('[y/N]')} `\n );\n if (enableAuto) {\n installerCache.set('autoInstall', true);\n consola.info('Auto-install enabled. Run with --no-auto-install to disable.');\n }\n }\n\n return success;\n }\n\n // User declined, ask if they want to skip these packages permanently\n const skipPermanently = await askConfirmation(\n `${chalk.green('?')} Skip these packages in future prompts? ${chalk.dim('[y/N]')} `\n );\n\n if (skipPermanently) {\n const currentSkip = installerCache.get('skipPackages') || [];\n installerCache.set('skipPackages', [...currentSkip, ...toInstall.map(p => p.name)]);\n consola.info('Packages added to skip list.');\n }\n\n return false;\n}\n\n/**\n * Print info about missing packages without prompting\n */\nfunction printMissingPackagesInfo(packages: MissingPackage[]): void {\n if (packages.length === 0) return;\n\n const pm = detectPackageManager();\n const command = buildInstallCommand(packages, pm);\n\n consola.warn(`Missing optional packages: ${packages.map(p => p.name).join(', ')}`);\n consola.info(`Install with: ${chalk.cyan(command)}`);\n}\n\n/**\n * Reset installer preferences\n */\nexport function resetInstallerPreferences(): void {\n installerCache.clear();\n consola.success('Installer preferences reset');\n}\n","/**\n * Package Updater\n *\n * Checks for outdated @djangocfg/* packages and offers to update them.\n */\n\nimport chalk from 'chalk';\nimport { spawn } from 'child_process';\nimport Conf from 'conf';\nimport consola from 'consola';\nimport { createRequire } from 'module';\nimport { join } from 'path';\nimport { createInterface } from 'readline';\nimport semver from 'semver';\n\nimport { DJANGOCFG_PACKAGES, PACKAGE_NAME } from '../constants';\nimport { isCI } from '../utils/env';\nimport { detectPackageManager } from './installer';\n\n// Updater preferences cache\nconst updaterCache = new Conf<{\n autoUpdate?: boolean;\n lastCheck?: number;\n skippedVersions?: Record<string, string>;\n}>({\n projectName: 'djangocfg-nextjs-updater',\n projectVersion: '1.0.0',\n});\n\n// Check for updates once per hour\nconst UPDATE_CHECK_COOLDOWN_MS = 60 * 60 * 1000;\n\n// Spinner frames\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\nexport interface PackageVersion {\n name: string;\n current: string | null;\n latest: string | null;\n hasUpdate: boolean;\n}\n\nexport interface UpdateOptions {\n /** Auto-update without prompting */\n autoUpdate?: boolean;\n /** Force check even if recently checked (ignores cooldown) */\n force?: boolean;\n /** Force check even for workspace:* packages (for testing) */\n forceCheckWorkspace?: boolean;\n}\n\n/**\n * Check if package is a workspace dependency\n */\nfunction isWorkspacePackage(packageName: string): boolean {\n try {\n const fs = require('fs');\n const pkgJsonPath = join(process.cwd(), 'package.json');\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n\n const deps = { ...pkgJson.dependencies, ...pkgJson.devDependencies };\n const version = deps[packageName];\n\n return version?.startsWith('workspace:') || false;\n } catch {\n return false;\n }\n}\n\n/**\n * Get installed version of a package from consumer's project\n * Uses multiple fallback strategies for monorepo compatibility\n */\nexport function getInstalledVersion(packageName: string): string | null {\n const fs = require('fs');\n const cwd = process.cwd();\n\n // Strategy 1: Direct read from node_modules (works with symlinks)\n try {\n const directPath = join(cwd, 'node_modules', packageName, 'package.json');\n if (fs.existsSync(directPath)) {\n const pkg = JSON.parse(fs.readFileSync(directPath, 'utf-8'));\n return pkg.version || null;\n }\n } catch {\n // Continue to next strategy\n }\n\n // Strategy 2: Use createRequire from cwd\n try {\n const consumerRequire = createRequire(join(cwd, 'package.json'));\n const pkgPath = consumerRequire.resolve(`${packageName}/package.json`);\n const pkg = require(pkgPath);\n return pkg.version || null;\n } catch {\n // Continue to next strategy\n }\n\n // Strategy 3: Try global require\n try {\n const pkgPath = require.resolve(`${packageName}/package.json`);\n const pkg = require(pkgPath);\n return pkg.version || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check if we should skip update checking for this package\n * (e.g., workspace packages shouldn't be checked against npm)\n */\nexport function shouldCheckUpdates(packageName: string): boolean {\n return !isWorkspacePackage(packageName);\n}\n\n/**\n * Fetch latest version from npm registry\n */\nasync function fetchLatestVersion(packageName: string): Promise<string | null> {\n try {\n const https = await import('https');\n return new Promise((resolve) => {\n const req = https.get(\n `https://registry.npmjs.org/${packageName}/latest`,\n { timeout: 5000 },\n (res: any) => {\n let data = '';\n res.on('data', (chunk: string) => { data += chunk; });\n res.on('end', () => {\n try {\n const json = JSON.parse(data);\n resolve(json.version || null);\n } catch {\n resolve(null);\n }\n });\n }\n );\n req.on('error', () => resolve(null));\n req.on('timeout', () => { req.destroy(); resolve(null); });\n });\n } catch {\n return null;\n }\n}\n\n/**\n * Check all @djangocfg packages for updates\n * All packages are aligned to the version of @djangocfg/nextjs (master package)\n * Skips workspace:* packages unless forceCheckWorkspace is true\n */\nexport async function checkForUpdates(options: { forceCheckWorkspace?: boolean } = {}): Promise<PackageVersion[]> {\n const results: PackageVersion[] = [];\n\n // First, get the latest version of master package (@djangocfg/nextjs)\n // All other packages should align to this version\n const masterLatest = await fetchLatestVersion(PACKAGE_NAME);\n if (!masterLatest) {\n // Can't determine target version, skip update check\n return results;\n }\n\n // Check packages against master version\n const checks = DJANGOCFG_PACKAGES.map(async (name) => {\n // Skip workspace packages unless force mode\n const isWorkspace = !shouldCheckUpdates(name);\n if (!options.forceCheckWorkspace && isWorkspace) {\n return null;\n }\n\n const current = getInstalledVersion(name);\n if (!current) {\n return null;\n }\n\n // All packages should update to master package version\n const hasUpdate = !!(masterLatest && current && semver.gt(masterLatest, current));\n\n return { name, current, latest: masterLatest, hasUpdate };\n });\n\n const checkResults = await Promise.all(checks);\n\n for (const result of checkResults) {\n if (result) {\n results.push(result);\n }\n }\n\n return results;\n}\n\n/**\n * Get packages that need updating\n */\nexport async function getOutdatedPackages(options: { forceCheckWorkspace?: boolean } = {}): Promise<PackageVersion[]> {\n const all = await checkForUpdates(options);\n const skipped = updaterCache.get('skippedVersions') || {};\n\n return all.filter(pkg => {\n if (!pkg.hasUpdate) return false;\n // Skip if user chose to skip this specific version\n if (skipped[pkg.name] === pkg.latest) return false;\n return true;\n });\n}\n\n/**\n * Create a simple spinner\n */\nfunction createSpinner(text: string) {\n let frameIndex = 0;\n let interval: NodeJS.Timeout | null = null;\n let currentText = text;\n\n const render = () => {\n const frame = SPINNER_FRAMES[frameIndex];\n process.stdout.write(`\\r${chalk.cyan(frame)} ${currentText}`);\n frameIndex = (frameIndex + 1) % SPINNER_FRAMES.length;\n };\n\n return {\n start() {\n if (process.stdout.isTTY) {\n interval = setInterval(render, 80);\n render();\n } else {\n console.log(` ${currentText}`);\n }\n return this;\n },\n text(newText: string) {\n currentText = newText;\n return this;\n },\n succeed(text?: string) {\n if (interval) clearInterval(interval);\n if (process.stdout.isTTY) {\n process.stdout.write(`\\r${chalk.green('✓')} ${text || currentText}\\n`);\n } else {\n console.log(` ${chalk.green('✓')} ${text || currentText}`);\n }\n return this;\n },\n fail(text?: string) {\n if (interval) clearInterval(interval);\n if (process.stdout.isTTY) {\n process.stdout.write(`\\r${chalk.red('✗')} ${text || currentText}\\n`);\n } else {\n console.log(` ${chalk.red('✗')} ${text || currentText}`);\n }\n return this;\n },\n stop() {\n if (interval) clearInterval(interval);\n if (process.stdout.isTTY) {\n process.stdout.write('\\r\\x1b[K');\n }\n return this;\n },\n };\n}\n\n/**\n * Ask user for confirmation\n */\nasync function askConfirmation(question: string): Promise<boolean> {\n if (isCI || !process.stdin.isTTY) {\n return false;\n }\n\n return new Promise((resolve) => {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n rl.question(question, (answer) => {\n rl.close();\n const normalized = answer.toLowerCase().trim();\n resolve(normalized === '' || normalized === 'y' || normalized === 'yes');\n });\n });\n}\n\n/**\n * Update a single package with progress\n */\nasync function updateSinglePackage(\n pkg: PackageVersion,\n pm: 'pnpm' | 'yarn' | 'npm',\n index: number,\n total: number\n): Promise<boolean> {\n const progress = `[${index + 1}/${total}]`;\n const versionInfo = `${chalk.red(pkg.current)} → ${chalk.green(pkg.latest)}`;\n const spinner = createSpinner(\n `${chalk.dim(progress)} Updating ${chalk.cyan(pkg.name)} ${versionInfo}`\n );\n\n spinner.start();\n\n // Always install with @latest to keep package.json consistent\n const command = pm === 'pnpm'\n ? `pnpm add ${pkg.name}@latest`\n : pm === 'yarn'\n ? `yarn add ${pkg.name}@latest`\n : `npm install ${pkg.name}@latest`;\n\n return new Promise((resolve) => {\n const proc = spawn(command, {\n shell: true,\n cwd: process.cwd(),\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n spinner.succeed(\n `${chalk.dim(progress)} ${chalk.cyan(pkg.name)} ${chalk.green(pkg.latest!)}`\n );\n resolve(true);\n } else {\n spinner.fail(\n `${chalk.dim(progress)} ${chalk.cyan(pkg.name)} ${chalk.red('failed')}`\n );\n resolve(false);\n }\n });\n\n proc.on('error', () => {\n spinner.fail(`${chalk.dim(progress)} ${chalk.cyan(pkg.name)} ${chalk.red('failed')}`);\n resolve(false);\n });\n });\n}\n\n/**\n * Update packages with progress\n */\nexport async function updatePackagesWithProgress(packages: PackageVersion[]): Promise<boolean> {\n if (packages.length === 0) return true;\n\n const pm = detectPackageManager();\n const total = packages.length;\n\n console.log('');\n console.log(chalk.bold(` Updating ${total} package${total > 1 ? 's' : ''}...`));\n console.log('');\n\n let successCount = 0;\n const failedPackages: string[] = [];\n\n for (let i = 0; i < packages.length; i++) {\n const success = await updateSinglePackage(packages[i], pm, i, total);\n if (success) {\n successCount++;\n } else {\n failedPackages.push(packages[i].name);\n }\n }\n\n console.log('');\n\n if (failedPackages.length === 0) {\n consola.success(`All ${total} packages updated successfully!`);\n return true;\n } else if (successCount > 0) {\n consola.warn(`${successCount}/${total} packages updated. Failed: ${failedPackages.join(', ')}`);\n return false;\n } else {\n consola.error(`Failed to update packages: ${failedPackages.join(', ')}`);\n return false;\n }\n}\n\n/**\n * Check and prompt for package updates\n */\nexport async function checkAndUpdatePackages(options: UpdateOptions = {}): Promise<boolean> {\n // Check cooldown\n const lastCheck = updaterCache.get('lastCheck') || 0;\n if (!options.force && (Date.now() - lastCheck) < UPDATE_CHECK_COOLDOWN_MS) {\n return true;\n }\n\n updaterCache.set('lastCheck', Date.now());\n\n // Check for updates\n const spinner = createSpinner('Checking for updates...');\n spinner.start();\n\n const outdated = await getOutdatedPackages({\n forceCheckWorkspace: options.forceCheckWorkspace,\n });\n\n spinner.stop();\n\n console.log(chalk.dim(` Found ${outdated.length} outdated package(s)`));\n\n if (outdated.length === 0) {\n console.log(chalk.green(' ✓ All packages are up to date'));\n return true;\n }\n\n // Auto-update if configured\n if (options.autoUpdate || updaterCache.get('autoUpdate')) {\n return updatePackagesWithProgress(outdated);\n }\n\n // Show outdated packages\n console.log('');\n consola.box('📦 Updates Available');\n console.log('');\n\n for (const pkg of outdated) {\n console.log(\n ` ${chalk.yellow('•')} ${chalk.bold(pkg.name)} ` +\n `${chalk.red(pkg.current)} → ${chalk.green(pkg.latest)}`\n );\n }\n console.log('');\n\n // Ask for confirmation\n const shouldUpdate = await askConfirmation(\n `${chalk.green('?')} Update these packages now? ${chalk.dim('[Y/n]')} `\n );\n\n if (shouldUpdate) {\n const success = await updatePackagesWithProgress(outdated);\n\n if (success) {\n const enableAuto = await askConfirmation(\n `${chalk.green('?')} Enable auto-update for future? ${chalk.dim('[y/N]')} `\n );\n if (enableAuto) {\n updaterCache.set('autoUpdate', true);\n consola.info('Auto-update enabled.');\n }\n }\n\n return success;\n }\n\n // User declined, ask if they want to skip these versions\n const skipVersions = await askConfirmation(\n `${chalk.green('?')} Skip these versions in future? ${chalk.dim('[y/N]')} `\n );\n\n if (skipVersions) {\n const skipped = updaterCache.get('skippedVersions') || {};\n for (const pkg of outdated) {\n if (pkg.latest) {\n skipped[pkg.name] = pkg.latest;\n }\n }\n updaterCache.set('skippedVersions', skipped);\n consola.info('Versions skipped. Will prompt again for newer versions.');\n }\n\n return false;\n}\n\n/**\n * Reset updater preferences\n */\nexport function resetUpdaterPreferences(): void {\n updaterCache.clear();\n consola.success('Updater preferences reset');\n}\n","/**\n * Version Checking Utilities\n */\n\nimport chalk from 'chalk';\nimport Conf from 'conf';\nimport consola from 'consola';\nimport semver from 'semver';\n\nimport { DJANGOCFG_PACKAGES, PACKAGE_NAME, VERSION_CACHE_TTL_MS } from '../constants';\n\n// Version cache using conf (stores in ~/.config/djangocfg-nextjs/)\nconst versionCache = new Conf<{\n latestVersion?: string;\n lastCheck?: number;\n}>({\n projectName: 'djangocfg-nextjs',\n projectVersion: '1.0.0',\n});\n\n/**\n * Get current package version from package.json\n */\nexport function getCurrentVersion(): string | null {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const packageJson = require('../../../package.json');\n return packageJson.version || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Fetch latest version from npm registry (with 1 hour caching via conf)\n */\nexport async function fetchLatestVersion(): Promise<string | null> {\n // Check cache first\n const lastCheck = versionCache.get('lastCheck') || 0;\n const cachedVersion = versionCache.get('latestVersion');\n\n if (cachedVersion && (Date.now() - lastCheck) < VERSION_CACHE_TTL_MS) {\n return cachedVersion;\n }\n\n // Fetch from npm registry\n try {\n const https = await import('https');\n return new Promise((resolve) => {\n const req = https.get(\n `https://registry.npmjs.org/${PACKAGE_NAME}/latest`,\n { timeout: 5000 },\n (res: any) => {\n let data = '';\n res.on('data', (chunk: string) => { data += chunk; });\n res.on('end', () => {\n try {\n const json = JSON.parse(data);\n const version = json.version || null;\n if (version) {\n versionCache.set('latestVersion', version);\n versionCache.set('lastCheck', Date.now());\n }\n resolve(version);\n } catch {\n resolve(cachedVersion || null);\n }\n });\n }\n );\n req.on('error', () => resolve(cachedVersion || null));\n req.on('timeout', () => { req.destroy(); resolve(cachedVersion || null); });\n });\n } catch {\n return cachedVersion || null;\n }\n}\n\n/**\n * Check if update is available\n */\nexport async function checkForUpdate(): Promise<{\n hasUpdate: boolean;\n currentVersion: string | null;\n latestVersion: string | null;\n}> {\n const currentVersion = getCurrentVersion();\n if (!currentVersion) {\n return { hasUpdate: false, currentVersion: null, latestVersion: null };\n }\n\n const latestVersion = await fetchLatestVersion();\n const hasUpdate = !!(latestVersion && semver.gt(latestVersion, currentVersion));\n\n return { hasUpdate, currentVersion, latestVersion };\n}\n\n/**\n * Get update command for all djangocfg packages\n */\nexport function getUpdateCommand(): string {\n return `pnpm add ${DJANGOCFG_PACKAGES.map(p => `${p}@latest`).join(' ')}`;\n}\n\n/**\n * Print version info and update notification\n */\nexport async function printVersionInfo(): Promise<void> {\n const { hasUpdate, currentVersion, latestVersion } = await checkForUpdate();\n\n if (!currentVersion) return;\n\n // Print current version\n consola.box(`📦 @djangocfg/nextjs v${currentVersion}`);\n\n // Show update notification if available\n if (hasUpdate && latestVersion) {\n consola.warn(`Update Available! ${chalk.red(currentVersion)} → ${chalk.green(latestVersion)}`);\n consola.info(`Run: ${chalk.cyan(getUpdateCommand())}`);\n console.log('');\n }\n}\n","/**\n * Deep Merge Utility\n *\n * Recursively merges objects, replacing arrays instead of merging them.\n */\n\nexport function deepMerge<T extends Record<string, any>>(target: T, source: Partial<T>): T {\n const output = { ...target };\n\n for (const key in source) {\n if (source[key] === undefined) continue;\n\n // Arrays: replace (don't merge arrays)\n if (Array.isArray(source[key])) {\n output[key] = source[key] as any;\n }\n // Objects: deep merge\n else if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {\n const targetValue = output[key];\n if (targetValue && typeof targetValue === 'object' && !Array.isArray(targetValue)) {\n output[key] = deepMerge(targetValue, source[key] as any);\n } else {\n output[key] = source[key] as any;\n }\n }\n // Primitives: replace\n else {\n output[key] = source[key] as any;\n }\n }\n\n return output;\n}\n","/**\n * Base Next.js Configuration Factory\n *\n * Universal, reusable Next.js config for all DjangoCFG projects\n * Provides standard settings that can be extended per project\n *\n * @example\n * ```typescript\n * // In your project's next.config.ts\n * import { createBaseNextConfig } from '@djangocfg/nextjs/config';\n * import bundleAnalyzer from '@next/bundle-analyzer';\n *\n * const withBundleAnalyzer = bundleAnalyzer({\n * enabled: process.env.ANALYZE === 'true',\n * });\n *\n * export default withBundleAnalyzer(createBaseNextConfig({\n * // Your project-specific overrides\n * transpilePackages: ['my-custom-package'],\n * }));\n * ```\n */\n\nimport type { NextConfig } from 'next';\nimport type { Configuration as WebpackConfig } from 'webpack';\n\nimport { type PWAPluginOptions, withPWA } from '../pwa/plugin';\nimport { DEFAULT_OPTIMIZE_PACKAGES, DEFAULT_TRANSPILE_PACKAGES } from './constants';\nimport { addCompressionPlugins } from './plugins/compression';\nimport { DevStartupPlugin } from './plugins/devStartup';\nimport { deepMerge } from './utils/deepMerge';\nimport { getApiUrl, getBasePath, getSiteUrl, isDev, isStaticBuild } from './utils/env';\n\n// ─────────────────────────────────────────────────────────────────────────\n// Configuration Options\n// ─────────────────────────────────────────────────────────────────────────\n\nexport interface BaseNextConfigOptions {\n /** Static build path (used when NEXT_PUBLIC_STATIC_BUILD=true) */\n isDefaultCfgAdmin?: boolean;\n /** Additional transpile packages (merged with defaults) */\n transpilePackages?: string[];\n /** Additional optimize package imports (merged with defaults) */\n optimizePackageImports?: string[];\n /** Check for @djangocfg/* package updates on startup (default: true) */\n checkUpdates?: boolean;\n /** Auto-update outdated packages without prompting (default: false) */\n autoUpdate?: boolean;\n /** Force check workspace:* packages for updates (for testing in monorepo) */\n forceCheckWorkspace?: boolean;\n /** Check for missing optional packages on startup (default: true) */\n checkPackages?: boolean;\n /** Auto-install missing packages without prompting (default: false) */\n autoInstall?: boolean;\n /**\n * Allow embedding this app in iframe from specified origins\n * Set to ['*'] to allow all origins, or specify domains like ['https://djangocfg.com']\n */\n allowIframeFrom?: string[];\n /**\n * PWA configuration options\n * Set to false to disable PWA, or provide custom options\n * @default { enabled: true (in production), disable: true (in development) }\n */\n pwa?: PWAPluginOptions | false;\n /** Turbopack configuration (Next.js 16+ default bundler) */\n turbopack?: NextConfig['turbopack'];\n /** Custom webpack configuration function (called after base webpack logic) */\n webpack?: (\n config: WebpackConfig,\n options: { isServer: boolean; dev: boolean; [key: string]: any }\n ) => WebpackConfig | void;\n /** Custom experimental options (merged with defaults) */\n experimental?: NextConfig['experimental'];\n /** Custom env variables (merged with defaults) */\n env?: Record<string, string | undefined>;\n /** Additional redirects (merged with base URL normalization redirects) */\n redirects?: NextConfig['redirects'];\n /** Additional headers (merged with base CORS/security headers) */\n headers?: NextConfig['headers'];\n /** Additional rewrites */\n rewrites?: NextConfig['rewrites'];\n /** Override any Next.js config option */\n [key: string]: any;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Base Configuration Factory\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Create base Next.js configuration with standard DjangoCFG settings\n *\n * @param options - Custom configuration options to merge with base config\n * @returns Next.js configuration function\n */\nexport function createBaseNextConfig(\n options: BaseNextConfigOptions = {}\n): NextConfig {\n\n const basePath = getBasePath(options.isDefaultCfgAdmin);\n const apiUrl = getApiUrl();\n const siteUrl = getSiteUrl();\n\n // Base configuration\n const baseConfig: NextConfig = {\n reactStrictMode: true,\n trailingSlash: true,\n\n // Static export configuration\n ...(isStaticBuild && {\n output: 'export' as const,\n distDir: 'out',\n basePath: basePath,\n // Fix for Next.js 15.5.4: prevent 500.html generation issue\n generateBuildId: async () => {\n return 'static-build';\n },\n }),\n\n // Standalone output for Docker (only in production, not dev)\n ...(!isStaticBuild && !isDev && {\n output: 'standalone' as const,\n }),\n\n // Environment variables\n env: {\n NEXT_PUBLIC_BASE_PATH: basePath,\n NEXT_PUBLIC_API_URL: apiUrl,\n NEXT_PUBLIC_SITE_URL: siteUrl,\n // Disable Next.js telemetry (Next.js 15+ uses env var instead of config option)\n NEXT_TELEMETRY_DISABLED: '1',\n ...options.env,\n },\n\n // Images configuration\n images: {\n unoptimized: true,\n },\n\n // CORS headers for static files and iframe embedding\n async headers() {\n const headers: { source: string; headers: { key: string; value: string }[] }[] = [\n {\n source: '/static/:path*',\n headers: [\n { key: 'Access-Control-Allow-Origin', value: '*' },\n { key: 'Access-Control-Allow-Methods', value: 'GET, OPTIONS' },\n { key: 'Access-Control-Allow-Headers', value: 'Origin, Content-Type, Accept' },\n ],\n },\n ];\n\n // Add iframe embedding headers if allowIframeFrom is specified\n if (options.allowIframeFrom && options.allowIframeFrom.length > 0) {\n const frameAncestors = options.allowIframeFrom.includes('*')\n ? '*'\n : `'self' ${options.allowIframeFrom.join(' ')}`;\n\n headers.push({\n source: '/:path*',\n headers: [\n // Content-Security-Policy frame-ancestors directive\n { key: 'Content-Security-Policy', value: `frame-ancestors ${frameAncestors}` },\n // X-Frame-Options for older browsers (ALLOW-FROM is deprecated, use CSP instead)\n // Only set SAMEORIGIN if allowing all, otherwise browsers will use CSP\n ...(options.allowIframeFrom.includes('*')\n ? []\n : [{ key: 'X-Frame-Options', value: 'SAMEORIGIN' }]\n ),\n ],\n });\n }\n\n // Merge with user-provided headers\n const userHeaders = options.headers ? await options.headers() : [];\n return [...headers, ...userHeaders];\n },\n\n // Rewrites (user-provided only)\n ...(options.rewrites && {\n rewrites: options.rewrites,\n }),\n\n // Redirects for URL normalization\n // Fixes \"Failed to construct 'URL': Invalid URL\" error with double slashes\n async redirects() {\n const baseRedirects = [\n // Normalize double slashes in URL path (e.g., /foo//bar -> /foo/bar)\n {\n source: '/:path*(//)/:rest*',\n destination: '/:path*/:rest*',\n permanent: true,\n },\n // Handle root double slash (e.g., // -> /)\n {\n source: '//',\n destination: '/',\n permanent: true,\n },\n ];\n\n // Merge with user-provided redirects\n const userRedirects = options.redirects ? await options.redirects() : [];\n return [...baseRedirects, ...userRedirects];\n },\n\n // Transpile packages (merge with user-provided)\n transpilePackages: [\n ...DEFAULT_TRANSPILE_PACKAGES,\n ...(options.transpilePackages || []),\n ],\n\n // Turbopack configuration (Next.js 16+ default bundler)\n // Always set turbopack config to silence Next.js 16 warning about webpack config\n turbopack: options.turbopack || {},\n\n // Experimental features\n experimental: {\n // Optimize package imports (only in production)\n ...(!isDev && {\n optimizePackageImports: [\n ...DEFAULT_OPTIMIZE_PACKAGES,\n ...(options.optimizePackageImports || []),\n ],\n }),\n // Dev mode optimizations\n ...(isDev && {\n optimizeCss: false,\n }),\n // User experimental options applied last (can override base settings)\n ...options.experimental,\n },\n\n // Webpack configuration\n webpack: (config: WebpackConfig, webpackOptions: { isServer: boolean; dev: boolean; [key: string]: any }) => {\n const { isServer, dev } = webpackOptions;\n\n // Add dev startup plugin (client-side only in dev)\n if (dev && !isServer) {\n if (!config.plugins) {\n config.plugins = [];\n }\n config.plugins.push(\n new DevStartupPlugin({\n checkUpdates: options.checkUpdates,\n autoUpdate: options.autoUpdate,\n forceCheckWorkspace: options.forceCheckWorkspace,\n checkPackages: options.checkPackages,\n autoInstall: options.autoInstall,\n })\n );\n }\n\n // Dev mode optimizations\n if (dev) {\n config.optimization = {\n ...config.optimization,\n removeAvailableModules: false,\n removeEmptyChunks: false,\n splitChunks: false, // Disable code splitting in dev for faster compilation\n };\n }\n\n // Filesystem cache (dev and production)\n config.cache = {\n type: 'filesystem',\n buildDependencies: {},\n };\n\n // Compression plugins (only for static build in production, client-side)\n if (!isServer && isStaticBuild && !dev) {\n addCompressionPlugins(config);\n }\n\n // Call user's webpack function if provided\n if (options.webpack) {\n return options.webpack(config, webpackOptions);\n }\n\n return config;\n },\n };\n\n // Deep merge user options with base config\n let finalConfig = deepMerge(baseConfig, options);\n\n // Cleanup: Remove custom options that are not part of NextConfig\n delete (finalConfig as any).optimizePackageImports;\n delete (finalConfig as any).isDefaultCfgAdmin;\n delete (finalConfig as any).checkUpdates;\n delete (finalConfig as any).autoUpdate;\n delete (finalConfig as any).forceCheckWorkspace;\n delete (finalConfig as any).checkPackages;\n delete (finalConfig as any).autoInstall;\n delete (finalConfig as any).allowIframeFrom;\n delete (finalConfig as any).openBrowser;\n // Note: turbopack is a valid NextConfig option, don't delete it\n\n // Apply PWA wrapper only if explicitly configured (opt-in)\n // PWA requires sw.ts file in the app, so apps must explicitly enable it\n if (options.pwa) {\n finalConfig = withPWA(finalConfig, options.pwa);\n }\n delete (finalConfig as any).pwa;\n\n return finalConfig;\n}\n","/**\n * DjangoCFG Documentation Client\n *\n * HTTP client for accessing DjangoCFG documentation via MCP server API.\n */\n\nimport { API_INFO_ENDPOINT, API_SEARCH_ENDPOINT, DEFAULT_TIMEOUT, MCP_BASE_URL } from './constants';\n\nimport type { SearchResult, SearchOptions, McpConfig, ApiSearchResponse } from './types';\n\n/**\n * Client for DjangoCFG Documentation API.\n */\nexport class DjangoCfgDocsClient {\n private baseUrl: string;\n private timeout: number;\n\n constructor(baseUrl: string = MCP_BASE_URL, timeout: number = DEFAULT_TIMEOUT) {\n this.baseUrl = baseUrl.replace(/\\/$/, '');\n this.timeout = timeout;\n }\n\n private async makeRequest<T>(endpoint: string, params?: Record<string, string | number>): Promise<T> {\n let url = `${this.baseUrl}${endpoint}`;\n\n if (params) {\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n searchParams.set(key, String(value));\n }\n url = `${url}?${searchParams.toString()}`;\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n 'User-Agent': 'DjangoCFG-AI-Client/1.0',\n },\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP Error ${response.status}: ${response.statusText}`);\n }\n\n return await response.json();\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Search documentation.\n */\n async search(query: string, options: SearchOptions = {}): Promise<SearchResult[]> {\n const { limit = 5, category } = options;\n\n const params: Record<string, string | number> = { q: query, limit };\n if (category) {\n params.category = category;\n }\n\n const data = await this.makeRequest<ApiSearchResponse>(API_SEARCH_ENDPOINT, params);\n\n const results = data.results || (Array.isArray(data) ? data : []);\n\n return results.map((item) => ({\n title: item.title || '',\n content: item.content || item.snippet || '',\n url: item.url || '',\n score: item.score || 0,\n category: item.category || '',\n }));\n }\n\n /**\n * Get detailed info about a specific topic.\n */\n async getInfo(topic: string): Promise<Record<string, unknown>> {\n return this.makeRequest(API_INFO_ENDPOINT, { topic });\n }\n\n /**\n * Get MCP server configuration for AI assistants.\n */\n getMcpConfig(): McpConfig {\n return {\n mcpServers: {\n 'djangocfg-docs': {\n url: `${this.baseUrl}/mcp`,\n },\n },\n };\n }\n}\n\n// Default client instance\nlet defaultClient: DjangoCfgDocsClient | null = null;\n\nfunction getClient(): DjangoCfgDocsClient {\n if (!defaultClient) {\n defaultClient = new DjangoCfgDocsClient();\n }\n return defaultClient;\n}\n\n/**\n * Search DjangoCFG documentation.\n *\n * @example\n * ```ts\n * const results = await search('database configuration');\n * results.forEach(r => console.log(r.title, r.url));\n * ```\n */\nexport async function search(query: string, options: SearchOptions = {}): Promise<SearchResult[]> {\n return getClient().search(query, options);\n}\n\n/**\n * Get documentation as formatted text.\n *\n * @example\n * ```ts\n * const docs = await getDocs('How to configure PostgreSQL?');\n * console.log(docs);\n * ```\n */\nexport async function getDocs(query: string, limit: number = 3): Promise<string> {\n const results = await search(query, { limit });\n\n if (results.length === 0) {\n return `No documentation found for: ${query}`;\n }\n\n const output: string[] = [];\n\n results.forEach((r, i) => {\n output.push(`## ${i + 1}. ${r.title}`);\n output.push(r.content);\n if (r.url) {\n output.push(`📖 Read more: ${r.url}`);\n }\n output.push('');\n });\n\n return output.join('\\n');\n}\n\n/**\n * Get detailed info about a topic.\n */\nexport async function getInfo(topic: string): Promise<Record<string, unknown>> {\n return getClient().getInfo(topic);\n}\n\n/**\n * Get MCP server configuration.\n */\nexport function getMcpConfig(): McpConfig {\n return getClient().getMcpConfig();\n}\n"],"mappings":"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","names":["NextResponse","result","jsx","isStaticBuild","isDev","isStaticBuild","getSiteUrl","chalk","consola","isDev","text","consola","chalk","spawn","Conf","consola","createRequire","join","createInterface","Conf","SPINNER_FRAMES","join","createRequire","createSpinner","chalk","text","askConfirmation","createInterface","spawn","consola","chalk","Conf","consola","semver","Conf","fetchLatestVersion","semver","consola","chalk","chalk","getSiteUrl"]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/sitemap/route.ts","../src/sitemap/generator.ts","../src/health/route.ts","../src/og-image/route.tsx","../src/og-image/components/DefaultTemplate.tsx","../src/og-image/utils/fonts.ts","../src/og-image/utils/url.ts","../src/og-image/utils/metadata.ts","../src/navigation/utils.ts","../src/pwa/plugin.ts","../src/config/constants.ts","../src/config/packages/checker.ts","../src/config/utils/env.ts","../src/config/packages/definitions.ts","../src/config/plugins/compression.ts","../src/config/plugins/devStartup.ts","../src/ai/constants.ts","../src/config/packages/installer.ts","../src/config/packages/updater.ts","../src/config/utils/version.ts","../src/config/utils/deepMerge.ts","../src/config/createNextConfig.ts","../src/ai/client.ts"],"sourcesContent":["{\n \"name\": \"@djangocfg/nextjs\",\n \"version\": \"2.1.66\",\n \"description\": \"Next.js server utilities: sitemap, health, OG images, contact forms, navigation, config\",\n \"keywords\": [\n \"nextjs\",\n \"sitemap\",\n \"health\",\n \"og-image\",\n \"navigation\",\n \"config\",\n \"react\",\n \"typescript\"\n ],\n \"author\": {\n \"name\": \"DjangoCFG\",\n \"url\": \"https://djangocfg.com\"\n },\n \"homepage\": \"https://djangocfg.com\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/markolofsen/django-cfg.git\",\n \"directory\": \"packages/nextjs\"\n },\n \"bugs\": {\n \"url\": \"https://github.com/markolofsen/django-cfg/issues\"\n },\n \"license\": \"MIT\",\n \"main\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.mts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.mts\",\n \"import\": \"./dist/index.mjs\",\n \"default\": \"./dist/index.mjs\"\n },\n \"./sitemap\": {\n \"types\": \"./dist/sitemap/index.d.mts\",\n \"import\": \"./dist/sitemap/index.mjs\",\n \"default\": \"./dist/sitemap/index.mjs\"\n },\n \"./health\": {\n \"types\": \"./dist/health/index.d.mts\",\n \"import\": \"./dist/health/index.mjs\",\n \"default\": \"./dist/health/index.mjs\"\n },\n \"./og-image\": {\n \"types\": \"./dist/og-image/index.d.mts\",\n \"import\": \"./dist/og-image/index.mjs\",\n \"default\": \"./dist/og-image/index.mjs\"\n },\n \"./og-image/utils\": {\n \"types\": \"./dist/og-image/utils/index.d.mts\",\n \"import\": \"./dist/og-image/utils/index.mjs\",\n \"default\": \"./dist/og-image/utils/index.mjs\"\n },\n \"./og-image/components\": {\n \"types\": \"./dist/og-image/components/index.d.mts\",\n \"import\": \"./dist/og-image/components/index.mjs\",\n \"default\": \"./dist/og-image/components/index.mjs\"\n },\n \"./navigation\": {\n \"types\": \"./dist/navigation/index.d.mts\",\n \"import\": \"./dist/navigation/index.mjs\",\n \"default\": \"./dist/navigation/index.mjs\"\n },\n \"./config\": {\n \"types\": \"./dist/config/index.d.mts\",\n \"import\": \"./dist/config/index.mjs\",\n \"default\": \"./dist/config/index.mjs\"\n },\n \"./ai\": {\n \"types\": \"./dist/ai/index.d.mts\",\n \"import\": \"./dist/ai/index.mjs\",\n \"default\": \"./dist/ai/index.mjs\"\n },\n \"./pwa\": {\n \"types\": \"./dist/pwa/index.d.mts\",\n \"import\": \"./dist/pwa/index.mjs\",\n \"default\": \"./dist/pwa/index.mjs\"\n },\n \"./pwa/worker\": {\n \"types\": \"./dist/pwa/worker/index.d.mts\",\n \"import\": \"./dist/pwa/worker/index.mjs\",\n \"default\": \"./dist/pwa/worker/index.mjs\"\n },\n \"./worker\": {\n \"types\": \"./dist/pwa/worker/index.d.mts\",\n \"import\": \"./dist/pwa/worker/index.mjs\",\n \"default\": \"./dist/pwa/worker/index.mjs\"\n },\n \"./pwa/server\": {\n \"types\": \"./dist/pwa/server/index.d.mts\",\n \"import\": \"./dist/pwa/server/index.mjs\",\n \"default\": \"./dist/pwa/server/index.mjs\"\n },\n \"./pwa/server/routes\": {\n \"types\": \"./dist/pwa/server/routes.d.mts\",\n \"import\": \"./dist/pwa/server/routes.mjs\",\n \"default\": \"./dist/pwa/server/routes.mjs\"\n }\n },\n \"files\": [\n \"dist\",\n \"src\",\n \"README.md\",\n \"LICENSE\"\n ],\n \"bin\": {\n \"djangocfg-docs\": \"./dist/ai/cli.mjs\",\n \"djangocfg-pwa\": \"./dist/pwa/cli.mjs\"\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"clean\": \"rm -rf dist\",\n \"lint\": \"eslint .\",\n \"check\": \"tsc --noEmit\",\n \"ai-docs\": \"tsx src/ai/cli.ts\",\n \"pwa\": \"tsx src/pwa/cli.ts\"\n },\n \"peerDependencies\": {\n \"next\": \"^16.0.10\"\n },\n \"dependencies\": {\n \"@serwist/next\": \"^9.2.3\",\n \"@serwist/sw\": \"^9.2.3\",\n \"chalk\": \"^5.3.0\",\n \"conf\": \"^15.0.2\",\n \"consola\": \"^3.4.2\",\n \"semver\": \"^7.7.3\",\n \"serwist\": \"^9.2.3\",\n \"web-push\": \"^3.6.7\"\n },\n \"devDependencies\": {\n \"@djangocfg/imgai\": \"workspace:*\",\n \"@djangocfg/layouts\": \"workspace:*\",\n \"@djangocfg/typescript-config\": \"workspace:*\",\n \"@types/node\": \"^24.7.2\",\n \"@types/react\": \"19.2.2\",\n \"@types/react-dom\": \"19.2.1\",\n \"@types/semver\": \"^7.7.1\",\n \"@types/web-push\": \"^3.6.4\",\n \"@types/webpack\": \"^5.28.5\",\n \"@vercel/og\": \"^0.8.5\",\n \"eslint\": \"^9.37.0\",\n \"lucide-react\": \"^0.545.0\",\n \"tsup\": \"^8.0.1\",\n \"tsx\": \"^4.19.2\",\n \"typescript\": \"^5.9.3\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n }\n}","/**\n * Sitemap Route Handler for Next.js App Router\n *\n * Usage:\n * ```tsx\n * // app/sitemap.ts\n * import { createSitemapHandler } from '@djangocfg/nextjs/sitemap';\n *\n * export default createSitemapHandler({\n * siteUrl: 'https://example.com',\n * staticPages: [\n * { loc: '/', changefreq: 'daily', priority: 1.0 },\n * { loc: '/about', changefreq: 'monthly', priority: 0.8 },\n * ],\n * dynamicPages: async () => {\n * // Fetch dynamic pages from API\n * const posts = await fetchPosts();\n * return posts.map(post => ({\n * loc: `/posts/${post.slug}`,\n * lastmod: post.updatedAt,\n * changefreq: 'weekly',\n * priority: 0.7,\n * }));\n * },\n * });\n * ```\n */\n\nimport { NextResponse } from 'next/server';\n\nimport { generateSitemapXml, normalizeUrl } from './generator';\n\nimport type { SitemapGeneratorOptions } from './types';\nimport type { SitemapUrl } from '../types';\n\nexport function createSitemapHandler(options: SitemapGeneratorOptions) {\n const {\n siteUrl,\n staticPages = [],\n dynamicPages = [],\n cacheControl = 'public, s-maxage=86400, stale-while-revalidate',\n } = options;\n\n return async function GET() {\n const urls: SitemapUrl[] = [...staticPages];\n\n // Add dynamic pages\n if (dynamicPages) {\n if (typeof dynamicPages === 'function') {\n const dynamicUrls = await dynamicPages();\n urls.push(...dynamicUrls);\n } else {\n urls.push(...dynamicPages);\n }\n }\n\n // Normalize all URLs\n const normalizedUrls = urls.map((url) => ({\n ...url,\n loc: normalizeUrl(url.loc, siteUrl),\n }));\n\n // Generate XML\n const sitemap = generateSitemapXml(normalizedUrls);\n\n // Return response\n return new NextResponse(sitemap, {\n status: 200,\n headers: {\n 'Content-Type': 'application/xml',\n 'Cache-Control': cacheControl,\n },\n });\n };\n}\n\n","/**\n * Sitemap Generator\n *\n * Generates XML sitemap from configuration\n */\n\nimport type { SitemapUrl } from '../types';\n\n/**\n * Generate XML sitemap string from URLs\n */\nexport function generateSitemapXml(urls: SitemapUrl[]): string {\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n xsi:schemaLocation=\"http://www.sitemaps.org/schemas/sitemap/0.9\n http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd\">\n${urls\n .map(\n ({ loc, lastmod, changefreq, priority }) => ` <url>\n <loc>${escapeXml(loc)}</loc>\n ${lastmod ? `<lastmod>${formatDate(lastmod)}</lastmod>` : ''}\n ${changefreq ? `<changefreq>${changefreq}</changefreq>` : ''}\n ${priority !== undefined ? `<priority>${priority.toFixed(1)}</priority>` : ''}\n </url>`\n )\n .join('\\n')}\n</urlset>`;\n}\n\n/**\n * Format date for sitemap (ISO 8601)\n */\nfunction formatDate(date: string | Date): string {\n if (typeof date === 'string') {\n return date;\n }\n return date.toISOString().split('T')[0];\n}\n\n/**\n * Escape XML special characters\n */\nfunction escapeXml(unsafe: string): string {\n return unsafe\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n/**\n * Normalize URL (ensure absolute)\n */\nexport function normalizeUrl(url: string, siteUrl: string): string {\n if (url.startsWith('http://') || url.startsWith('https://')) {\n return url;\n }\n const baseUrl = siteUrl.endsWith('/') ? siteUrl.slice(0, -1) : siteUrl;\n const path = url.startsWith('/') ? url : `/${url}`;\n return `${baseUrl}${path}`;\n}\n\n","/**\n * Health Route Handler for Next.js App Router\n *\n * Usage:\n * ```tsx\n * // app/api/health/route.ts\n * import { createHealthHandler } from '@djangocfg/nextjs/health';\n *\n * export const GET = createHealthHandler({\n * version: process.env.NEXT_PUBLIC_APP_VERSION || '1.0.0',\n * checks: [\n * {\n * name: 'database',\n * check: async () => {\n * // Check database connection\n * return await checkDatabase();\n * },\n * },\n * ],\n * });\n * ```\n */\n\nimport { NextResponse } from 'next/server';\n\nimport type { HealthConfig, HealthResponse } from './types';\n\nexport function createHealthHandler(config: HealthConfig = {}) {\n const { version, checks = [], customData = {} } = config;\n\n return async function GET() {\n const startTime = Date.now();\n let status: 'ok' | 'error' = 'ok';\n const checkResults: Record<string, boolean> = {};\n\n // Run health checks\n if (checks.length > 0) {\n for (const check of checks) {\n try {\n const result = await check.check();\n checkResults[check.name] = result;\n if (!result) {\n status = 'error';\n }\n } catch (error) {\n checkResults[check.name] = false;\n status = 'error';\n }\n }\n }\n\n const response: HealthResponse = {\n status,\n timestamp: new Date().toISOString(),\n uptime: process.uptime(),\n ...(version && { version }),\n ...(Object.keys(checkResults).length > 0 && { checks: checkResults }),\n ...customData,\n };\n\n const statusCode = status === 'ok' ? 200 : 503;\n\n return NextResponse.json(response, { status: statusCode });\n };\n}\n\n","/**\n * OG Image Route Handler\n *\n * Factory function to create OG Image route handler for Next.js App Router\n *\n * Usage:\n * ```tsx\n * // app/api/og/route.tsx\n * import { createOgImageHandler } from '@djangocfg/nextjs/og-image';\n * import { MyTemplate } from './templates';\n *\n * export const { GET, runtime } = createOgImageHandler({\n * template: MyTemplate,\n * defaultProps: {\n * siteName: 'My Site',\n * },\n * fonts: [{ family: 'Manrope', weight: 700 }],\n * });\n * ```\n */\n\nimport { ImageResponse } from 'next/og';\nimport { NextRequest } from 'next/server';\n\nimport { DefaultTemplate } from './components/DefaultTemplate';\nimport { loadGoogleFonts } from './utils';\nimport { parseOgImageData } from './utils/url';\n\nimport type { ReactElement } from 'react';\nimport type { OgImageTemplateProps } from './types';\n\nexport interface OgImageHandlerConfig {\n /** Custom template component (optional, defaults to DefaultTemplate) */\n template?: (props: OgImageTemplateProps) => ReactElement;\n /** Default props to merge with query params */\n defaultProps?: Partial<OgImageTemplateProps>;\n /** Google Fonts to load */\n fonts?: Array<{ family: string; weight: 400 | 500 | 600 | 700 | 800 | 900 }>;\n /** Image size */\n size?: { width: number; height: number };\n /** Enable debug mode */\n debug?: boolean;\n}\n\n/**\n * Factory function to create OG Image route handler\n * \n * @example\n * ```tsx\n * // app/api/og/route.tsx\n * import { createOgImageHandler } from '@djangocfg/nextjs/og-image';\n * import { MyTemplate } from '@/components/MyTemplate';\n * \n * export const { GET, runtime } = createOgImageHandler({\n * template: MyTemplate,\n * defaultProps: { siteName: 'My Site' },\n * fonts: [{ family: 'Inter', weight: 700 }],\n * });\n * ```\n */\nexport function createOgImageHandler(config: OgImageHandlerConfig) {\n const {\n template: Template = DefaultTemplate,\n defaultProps = {},\n fonts: fontConfig = [],\n size = { width: 1200, height: 630 },\n debug = false,\n } = config;\n\n async function GET(req: NextRequest) {\n let searchParams: URLSearchParams = new URLSearchParams();\n \n // Try to get searchParams from multiple sources\n if (req.nextUrl?.searchParams && req.nextUrl.searchParams.size > 0) {\n searchParams = req.nextUrl.searchParams;\n } else if (req.nextUrl?.search && req.nextUrl.search.length > 1) {\n searchParams = new URLSearchParams(req.nextUrl.search);\n } else {\n try {\n const url = new URL(req.url);\n if (url.searchParams.size > 0) {\n searchParams = url.searchParams;\n }\n } catch (error) {\n // Ignore\n }\n \n if (searchParams.size === 0 && req.url) {\n const queryIndex = req.url.indexOf('?');\n if (queryIndex !== -1) {\n const queryString = req.url.substring(queryIndex + 1);\n searchParams = new URLSearchParams(queryString);\n }\n }\n \n if (searchParams.size === 0) {\n const customParams = req.headers.get('x-og-search-params');\n if (customParams) {\n searchParams = new URLSearchParams(customParams);\n }\n }\n }\n\n // Initialize with defaults\n let title = defaultProps.title || 'Untitled';\n let subtitle = defaultProps.subtitle || '';\n let description = defaultProps.description || subtitle;\n\n // Support base64 data parameter (priority: base64 > query params > defaults)\n // All template props can be encoded in base64, including styling params\n const dataParam = searchParams.get('data');\n let decodedParams: Record<string, any> = {};\n \n if (dataParam) {\n try {\n const paramsObj: Record<string, string> = { data: dataParam };\n for (const [key, value] of searchParams.entries()) {\n if (key !== 'data') {\n paramsObj[key] = value;\n }\n }\n decodedParams = parseOgImageData(paramsObj);\n \n // Base64 data takes precedence - apply all decoded values\n if (decodedParams.title && typeof decodedParams.title === 'string' && decodedParams.title.trim() !== '') {\n title = decodedParams.title.trim();\n }\n if (decodedParams.subtitle && typeof decodedParams.subtitle === 'string' && decodedParams.subtitle.trim() !== '') {\n subtitle = decodedParams.subtitle.trim();\n }\n if (decodedParams.description && typeof decodedParams.description === 'string' && decodedParams.description.trim() !== '') {\n description = decodedParams.description.trim();\n }\n } catch (error) {\n // Silently fall back to defaults\n }\n }\n\n // Fallback to query params if not set from base64\n if (!title || title === 'Untitled') {\n const titleParam = searchParams.get('title');\n if (titleParam) {\n title = titleParam;\n }\n }\n if (!subtitle) {\n const subtitleParam = searchParams.get('subtitle');\n if (subtitleParam) {\n subtitle = subtitleParam;\n }\n }\n if (!description || description === subtitle) {\n const descParam = searchParams.get('description');\n if (descParam) {\n description = descParam;\n }\n }\n\n // Load fonts if configured\n let fonts: any[] = [];\n if (fontConfig.length > 0) {\n fonts = await loadGoogleFonts(fontConfig);\n }\n\n // Helper function to parse numeric/boolean values from decoded params\n const parseValue = (value: any, type: 'number' | 'boolean' | 'string' = 'string'): any => {\n if (value === undefined || value === null || value === '') {\n return undefined;\n }\n if (type === 'number') {\n const num = Number(value);\n return isNaN(num) ? undefined : num;\n }\n if (type === 'boolean') {\n if (typeof value === 'boolean') return value;\n if (typeof value === 'string') {\n return value.toLowerCase() === 'true' || value === '1';\n }\n return Boolean(value);\n }\n return String(value);\n };\n\n // Merge props: decoded params from URL override defaultProps\n const templateProps: OgImageTemplateProps = {\n ...defaultProps,\n // Content\n title,\n subtitle,\n description,\n // Override with decoded params if present\n siteName: decodedParams.siteName || defaultProps.siteName,\n logo: decodedParams.logo || defaultProps.logo,\n // Background\n backgroundType: (decodedParams.backgroundType as 'gradient' | 'solid') || defaultProps.backgroundType,\n gradientStart: decodedParams.gradientStart || defaultProps.gradientStart,\n gradientEnd: decodedParams.gradientEnd || defaultProps.gradientEnd,\n backgroundColor: decodedParams.backgroundColor || defaultProps.backgroundColor,\n // Typography - Title\n titleSize: parseValue(decodedParams.titleSize, 'number') ?? defaultProps.titleSize,\n titleWeight: parseValue(decodedParams.titleWeight, 'number') ?? defaultProps.titleWeight,\n titleColor: decodedParams.titleColor || defaultProps.titleColor,\n // Typography - Description\n descriptionSize: parseValue(decodedParams.descriptionSize, 'number') ?? defaultProps.descriptionSize,\n descriptionColor: decodedParams.descriptionColor || defaultProps.descriptionColor,\n // Typography - Site Name\n siteNameSize: parseValue(decodedParams.siteNameSize, 'number') ?? defaultProps.siteNameSize,\n siteNameColor: decodedParams.siteNameColor || defaultProps.siteNameColor,\n // Layout\n padding: parseValue(decodedParams.padding, 'number') ?? defaultProps.padding,\n logoSize: parseValue(decodedParams.logoSize, 'number') ?? defaultProps.logoSize,\n // Visibility flags\n showLogo: parseValue(decodedParams.showLogo, 'boolean') ?? defaultProps.showLogo,\n showSiteName: parseValue(decodedParams.showSiteName, 'boolean') ?? defaultProps.showSiteName,\n };\n\n\n return new ImageResponse(\n <Template {...templateProps} />,\n {\n width: size.width,\n height: size.height,\n fonts,\n debug: debug || process.env.NODE_ENV === 'development',\n }\n );\n }\n\n return {\n GET,\n runtime: 'edge' as const,\n };\n}\n\n/**\n * Create OG Image route handler for dynamic route with path parameter\n * \n * This is a convenience wrapper for Next.js dynamic routes like `/api/og/[data]/route.tsx`.\n * It extracts the `data` parameter from the path and passes it to the handler as a query parameter.\n * Also handles static export mode automatically.\n * \n * @example\n * ```tsx\n * // app/api/og/[data]/route.tsx\n * import { createOgImageDynamicRoute } from '@djangocfg/nextjs/og-image';\n * import { OgImageTemplate } from '@/components/OgImageTemplate';\n * \n * export const runtime = 'nodejs';\n * export const dynamic = 'force-static';\n * export const revalidate = false;\n * \n * const handler = createOgImageDynamicRoute({\n * template: OgImageTemplate,\n * defaultProps: {\n * siteName: 'My App',\n * logo: '/logo.svg',\n * },\n * });\n * \n * export async function GET(\n * request: NextRequest,\n * { params }: { params: { data: string } }\n ) {\n * return handler(request, params);\n * }\n * ```\n */\nexport function createOgImageDynamicRoute(config: OgImageHandlerConfig) {\n const handler = createOgImageHandler(config);\n const isStaticBuild = typeof process !== 'undefined' && process.env.NEXT_PUBLIC_STATIC_BUILD === 'true';\n\n async function GET(\n request: NextRequest,\n context: { params: Promise<{ data: string }> }\n ) {\n // In static export mode, return a simple error response\n if (isStaticBuild) {\n return new Response('OG Image generation is not available in static export mode', {\n status: 404,\n headers: { 'Content-Type': 'text/plain' },\n });\n }\n\n // Await params (Next.js 15+ uses Promise)\n const params = await context.params;\n \n // Extract data from path parameter\n const dataParam = params.data;\n \n // Create a request with the data parameter as a query param for the handler\n const url = new URL(request.url);\n url.searchParams.set('data', dataParam);\n \n const modifiedRequest = new NextRequest(url.toString(), {\n method: request.method,\n headers: request.headers,\n });\n\n return handler.GET(modifiedRequest);\n }\n\n // For static export, provide generateStaticParams that returns empty array\n // This allows the route to be excluded from static build\n async function generateStaticParams(): Promise<Array<{ data: string }>> {\n return [];\n }\n\n return {\n GET,\n generateStaticParams,\n };\n}\n","/**\n * Default OG Image Template\n *\n * A modern, gradient-based template for OG images\n */\n\nimport type { ReactElement } from 'react';\nimport type { OgImageTemplateProps } from '../types';\n\n/**\n * Default OG Image Template Component\n *\n * Features:\n * - Modern gradient background\n * - Responsive text sizing\n * - Optional logo and site name\n * - Clean typography\n * - Full customization support\n *\n * @param props - Template props with title, description, siteName, logo and optional customization\n */\nexport function DefaultTemplate({\n title,\n description,\n siteName,\n logo,\n // Visibility flags\n showLogo = true,\n showSiteName = true,\n // Background customization\n backgroundType = 'gradient',\n gradientStart = '#667eea',\n gradientEnd = '#764ba2',\n backgroundColor = '#ffffff',\n // Typography - Title\n titleSize,\n titleWeight = 800,\n titleColor = 'white',\n // Typography - Description\n descriptionSize = 32,\n descriptionColor = 'rgba(255, 255, 255, 0.85)',\n // Typography - Site Name\n siteNameSize = 28,\n siteNameColor = 'rgba(255, 255, 255, 0.95)',\n // Layout\n padding = 80,\n logoSize = 48,\n // Dev mode\n devMode = false,\n}: OgImageTemplateProps): ReactElement {\n // Calculate title size if not provided (responsive based on title length)\n const calculatedTitleSize = titleSize || (title.length > 60 ? 56 : 72);\n \n // Determine background style\n const backgroundStyle =\n backgroundType === 'gradient'\n ? `linear-gradient(135deg, ${gradientStart} 0%, ${gradientEnd} 100%)`\n : backgroundColor;\n\n // Grid overlay for dev mode\n const gridOverlay = devMode ? (\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundImage: `\n linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px),\n linear-gradient(90deg, rgba(0, 0, 0, 0.1) 1px, transparent 1px)\n `,\n backgroundSize: '20px 20px',\n pointerEvents: 'none',\n zIndex: 10,\n }}\n />\n ) : null;\n\n return (\n <div\n style={{\n height: '100%',\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n background: backgroundStyle,\n padding: `${padding}px`,\n fontFamily: 'system-ui, -apple-system, sans-serif',\n position: 'relative',\n }}\n >\n {gridOverlay}\n \n {/* Header with logo and site name */}\n {((showLogo && logo) || (showSiteName && siteName)) && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '16px',\n }}\n >\n {showLogo && logo && (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={logo}\n alt=\"Logo\"\n width={logoSize}\n height={logoSize}\n style={{\n borderRadius: '8px',\n }}\n />\n )}\n {showSiteName && siteName && (\n <div\n style={{\n fontSize: siteNameSize,\n fontWeight: 600,\n color: siteNameColor,\n letterSpacing: '-0.02em',\n }}\n >\n {siteName}\n </div>\n )}\n </div>\n )}\n\n {/* Main content */}\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '24px',\n flex: 1,\n justifyContent: 'center',\n }}\n >\n {/* Title */}\n <div\n style={{\n fontSize: calculatedTitleSize,\n fontWeight: titleWeight,\n color: titleColor,\n lineHeight: 1.1,\n letterSpacing: '-0.03em',\n textShadow: backgroundType === 'gradient' ? '0 2px 20px rgba(0, 0, 0, 0.2)' : 'none',\n maxWidth: '100%',\n wordWrap: 'break-word',\n }}\n >\n {title}\n </div>\n\n {/* Description */}\n {description && (\n <div\n style={{\n fontSize: descriptionSize,\n fontWeight: 400,\n color: descriptionColor,\n lineHeight: 1.5,\n letterSpacing: '-0.01em',\n maxWidth: '90%',\n display: '-webkit-box',\n WebkitLineClamp: 2,\n WebkitBoxOrient: 'vertical',\n overflow: 'hidden',\n }}\n >\n {description}\n </div>\n )}\n </div>\n\n {/* Footer decoration */}\n <div\n style={{\n display: 'flex',\n width: '100%',\n height: '4px',\n background: backgroundType === 'gradient' \n ? `linear-gradient(90deg, ${gradientStart} 0%, ${gradientEnd} 100%)`\n : gradientStart,\n borderRadius: '2px',\n }}\n />\n </div>\n );\n}\n\n/**\n * Simple light template variant\n * \n * Light background variant with dark text\n */\nexport function LightTemplate({\n title,\n description,\n siteName,\n logo,\n // Visibility flags\n showLogo = true,\n showSiteName = true,\n // Background customization (defaults to light theme)\n backgroundType = 'solid',\n gradientStart = '#667eea',\n gradientEnd = '#764ba2',\n backgroundColor = '#ffffff',\n // Typography - Title\n titleSize,\n titleWeight = 800,\n titleColor = '#111',\n // Typography - Description\n descriptionSize = 32,\n descriptionColor = '#666',\n // Typography - Site Name\n siteNameSize = 28,\n siteNameColor = '#111',\n // Layout\n padding = 80,\n logoSize = 48,\n // Dev mode\n devMode = false,\n}: OgImageTemplateProps): ReactElement {\n // Calculate title size if not provided (responsive based on title length)\n const calculatedTitleSize = titleSize || (title.length > 60 ? 56 : 72);\n \n // Determine background style\n const backgroundStyle =\n backgroundType === 'gradient'\n ? `linear-gradient(135deg, ${gradientStart} 0%, ${gradientEnd} 100%)`\n : backgroundColor;\n\n // Grid overlay for dev mode\n const gridOverlay = devMode ? (\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n right: 0,\n bottom: 0,\n backgroundImage: `\n linear-gradient(rgba(0, 0, 0, 0.1) 1px, transparent 1px),\n linear-gradient(90deg, rgba(0, 0, 0, 0.1) 1px, transparent 1px)\n `,\n backgroundSize: '20px 20px',\n pointerEvents: 'none',\n zIndex: 10,\n }}\n />\n ) : null;\n\n return (\n <div\n style={{\n height: '100%',\n width: '100%',\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n justifyContent: 'space-between',\n background: backgroundStyle,\n padding: `${padding}px`,\n fontFamily: 'system-ui, -apple-system, sans-serif',\n position: 'relative',\n }}\n >\n {gridOverlay}\n \n {/* Header with logo and site name */}\n {((showLogo && logo) || (showSiteName && siteName)) && (\n <div\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: '16px',\n }}\n >\n {showLogo && logo && (\n // eslint-disable-next-line @next/next/no-img-element\n <img\n src={logo}\n alt=\"Logo\"\n width={logoSize}\n height={logoSize}\n style={{\n borderRadius: '8px',\n }}\n />\n )}\n {showSiteName && siteName && (\n <div\n style={{\n fontSize: siteNameSize,\n fontWeight: 600,\n color: siteNameColor,\n letterSpacing: '-0.02em',\n }}\n >\n {siteName}\n </div>\n )}\n </div>\n )}\n\n {/* Main content */}\n <div\n style={{\n display: 'flex',\n flexDirection: 'column',\n gap: '24px',\n flex: 1,\n justifyContent: 'center',\n }}\n >\n {/* Title */}\n <div\n style={{\n fontSize: calculatedTitleSize,\n fontWeight: titleWeight,\n color: titleColor,\n lineHeight: 1.1,\n letterSpacing: '-0.03em',\n maxWidth: '100%',\n wordWrap: 'break-word',\n }}\n >\n {title}\n </div>\n\n {/* Description */}\n {description && (\n <div\n style={{\n fontSize: descriptionSize,\n fontWeight: 400,\n color: descriptionColor,\n lineHeight: 1.5,\n letterSpacing: '-0.01em',\n maxWidth: '90%',\n }}\n >\n {description}\n </div>\n )}\n </div>\n\n {/* Footer decoration */}\n <div\n style={{\n display: 'flex',\n width: '100%',\n height: '4px',\n background: backgroundType === 'gradient' \n ? `linear-gradient(90deg, ${gradientStart} 0%, ${gradientEnd} 100%)`\n : gradientStart,\n borderRadius: '2px',\n }}\n />\n </div>\n );\n}\n\n","/**\n * Font Utilities for OG Image Generation\n *\n * Provides dynamic font loading from Google Fonts without requiring files in public/\n * Based on Vercel's official @vercel/og documentation\n */\n\nexport interface FontConfig {\n name: string;\n weight?: 400 | 500 | 600 | 700 | 800 | 900;\n style?: 'normal' | 'italic';\n data: ArrayBuffer;\n}\n\n/**\n * Load a Google Font dynamically\n *\n * @param font - Font family name (e.g., \"Inter\", \"Roboto\", \"Manrope\")\n * @param text - Text to optimize font for (optional, reduces file size)\n * @param weight - Font weight (default: 700)\n * @returns ArrayBuffer of font data\n *\n * @example\n * const fontData = await loadGoogleFont('Manrope', 'Hello World', 700);\n */\nexport async function loadGoogleFont(\n font: string,\n text?: string,\n weight: number = 700\n): Promise<ArrayBuffer> {\n // Construct Google Fonts API URL\n let url = `https://fonts.googleapis.com/css2?family=${font}:wght@${weight}`;\n\n // Add text parameter to optimize font subset (reduces size)\n if (text) {\n url += `&text=${encodeURIComponent(text)}`;\n }\n\n try {\n // Fetch CSS containing font URL\n const css = await fetch(url, {\n headers: {\n // Required to get TTF format instead of WOFF2\n 'User-Agent':\n 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; de-at) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1',\n },\n }).then((res) => res.text());\n\n // Extract font URL from CSS\n const resource = css.match(/src: url\\((.+)\\) format\\('(opentype|truetype)'\\)/);\n\n if (!resource || !resource[1]) {\n throw new Error(`Failed to parse font URL from CSS for font: ${font}`);\n }\n\n // Fetch actual font file\n const response = await fetch(resource[1]);\n\n if (response.status !== 200) {\n throw new Error(`Failed to fetch font data: HTTP ${response.status}`);\n }\n\n return await response.arrayBuffer();\n } catch (error) {\n console.error(`Error loading Google Font \"${font}\":`, error);\n throw new Error(`Failed to load font \"${font}\": ${error instanceof Error ? error.message : 'Unknown error'}`);\n }\n}\n\n/**\n * Load multiple Google Fonts\n *\n * @param fonts - Array of font configurations to load\n * @returns Array of FontConfig objects ready for ImageResponse\n *\n * @example\n * const fonts = await loadGoogleFonts([\n * { family: 'Manrope', weight: 700 },\n * { family: 'Inter', weight: 400 }\n * ]);\n */\nexport async function loadGoogleFonts(\n fonts: Array<{\n family: string;\n weight?: 400 | 500 | 600 | 700 | 800 | 900;\n style?: 'normal' | 'italic';\n text?: string;\n }>\n): Promise<FontConfig[]> {\n const fontConfigs = await Promise.all(\n fonts.map(async ({ family, weight = 700, style = 'normal', text }) => {\n const data = await loadGoogleFont(family, text, weight);\n return {\n name: family,\n weight,\n style,\n data,\n };\n })\n );\n\n return fontConfigs;\n}\n\n/**\n * Create a font loader with caching\n *\n * Useful for reusing font data across multiple OG image requests\n *\n * @example\n * const fontLoader = createFontLoader();\n * const font = await fontLoader.load('Manrope', 700);\n */\nexport function createFontLoader() {\n const cache = new Map<string, Promise<ArrayBuffer>>();\n\n return {\n /**\n * Load a font with caching\n */\n async load(\n family: string,\n weight: number = 700,\n text?: string\n ): Promise<ArrayBuffer> {\n const cacheKey = `${family}-${weight}-${text || 'all'}`;\n\n if (!cache.has(cacheKey)) {\n cache.set(cacheKey, loadGoogleFont(family, text, weight));\n }\n\n return cache.get(cacheKey)!;\n },\n\n /**\n * Clear the cache\n */\n clear() {\n cache.clear();\n },\n\n /**\n * Get cache size\n */\n size() {\n return cache.size;\n },\n };\n}\n\n","/**\n * URL Generation Helpers for OG Images\n *\n * Utilities to generate OG image URLs with proper query parameters\n */\n\n/** Default OG Image API base URL */\nconst DEFAULT_OG_IMAGE_BASE_URL = 'https://djangocfg.com/api/og';\n\n/**\n * Encode string to base64 with Unicode support\n * Works in both browser and Node.js environments\n */\nfunction encodeBase64(str: string): string {\n // Node.js environment\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(str, 'utf-8').toString('base64');\n }\n // Browser environment - handle Unicode via UTF-8 encoding\n return btoa(unescape(encodeURIComponent(str)));\n}\n\n/**\n * Decode base64 string with Unicode support\n * Works in both browser, Node.js, and Edge Runtime environments\n */\nfunction decodeBase64(str: string): string {\n // Node.js environment\n if (typeof Buffer !== 'undefined') {\n return Buffer.from(str, 'base64').toString('utf-8');\n }\n // Edge Runtime / Browser environment - handle Unicode via UTF-8 decoding\n // atob is available in Edge Runtime\n try {\n const binaryString = atob(str);\n // Convert binary string to UTF-8\n return decodeURIComponent(\n binaryString\n .split('')\n .map((c) => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))\n .join('')\n );\n } catch (error) {\n // Fallback to simpler method if above fails\n return decodeURIComponent(escape(atob(str)));\n }\n}\n\n/**\n * OG Image URL parameters\n * All parameters can be encoded in URL via base64\n */\nexport interface OgImageUrlParams {\n /** Page title */\n title: string;\n /** Page description (optional) */\n description?: string;\n /** Site name (optional) */\n siteName?: string;\n /** Logo URL (optional) */\n logo?: string;\n /** Background type: 'gradient' or 'solid' */\n backgroundType?: 'gradient' | 'solid';\n /** Gradient start color (hex) */\n gradientStart?: string;\n /** Gradient end color (hex) */\n gradientEnd?: string;\n /** Background color (for solid type) */\n backgroundColor?: string;\n /** Title font size (px) */\n titleSize?: number;\n /** Title font weight */\n titleWeight?: number;\n /** Title text color */\n titleColor?: string;\n /** Description font size (px) */\n descriptionSize?: number;\n /** Description text color */\n descriptionColor?: string;\n /** Site name font size (px) */\n siteNameSize?: number;\n /** Site name text color */\n siteNameColor?: string;\n /** Padding (px) */\n padding?: number;\n /** Logo size (px) */\n logoSize?: number;\n /** Show logo flag */\n showLogo?: boolean;\n /** Show site name flag */\n showSiteName?: boolean;\n /** Additional custom parameters */\n [key: string]: string | number | boolean | undefined;\n}\n\n/**\n * Options for generating OG image URL\n */\nexport interface GenerateOgImageUrlOptions {\n /**\n * Base URL of the OG image API route\n * @default 'https://djangocfg.com/api/og'\n */\n baseUrl?: string;\n /**\n * If true, encode params as base64 for safer URLs\n * @default true\n */\n useBase64?: boolean;\n}\n\n/**\n * Generate OG image URL with query parameters or base64 encoding\n *\n * @param params - URL parameters for the OG image\n * @param options - Generation options (baseUrl, useBase64)\n * @returns Complete OG image URL with encoded parameters\n *\n * @example\n * ```typescript\n * // Using default baseUrl (https://djangocfg.com/api/og)\n * const url = generateOgImageUrl({\n * title: 'My Page Title',\n * description: 'Page description here',\n * });\n *\n * // With custom baseUrl\n * const url = generateOgImageUrl(\n * { title: 'My Page' },\n * { baseUrl: '/api/og' }\n * );\n * ```\n */\nexport function generateOgImageUrl(\n params: OgImageUrlParams,\n options: GenerateOgImageUrlOptions = {}\n): string {\n const {\n baseUrl = DEFAULT_OG_IMAGE_BASE_URL,\n useBase64 = true\n } = options;\n\n if (useBase64) {\n // Clean params - remove undefined/null/empty values\n const cleanParams: Record<string, string | number | boolean> = {};\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null && value !== '') {\n cleanParams[key] = value;\n }\n });\n\n // Encode as base64 (Unicode-safe)\n const jsonString = JSON.stringify(cleanParams);\n const base64Data = encodeBase64(jsonString);\n\n // CRITICAL: Use path parameter instead of query parameter\n // Next.js strips query params in internal requests for metadata generation\n // Using /api/og/[data] instead of /api/og?data=... preserves the data\n // IMPORTANT: Add trailing slash to avoid 308 redirects which cause timeouts in crawlers\n return `${baseUrl}/${base64Data}/`;\n } else {\n // Legacy query params mode\n const searchParams = new URLSearchParams();\n\n // Add all defined parameters\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null && value !== '') {\n searchParams.append(key, String(value));\n }\n });\n\n const query = searchParams.toString();\n return query ? `${baseUrl}?${query}` : baseUrl;\n }\n}\n\n/**\n * Get absolute OG image URL from relative path\n *\n * Useful for generating absolute URLs required by Open Graph meta tags\n *\n * @param relativePath - Relative OG image path (e.g., '/api/og?title=Hello')\n * @param siteUrl - Base site URL (e.g., 'https://example.com')\n * @returns Absolute URL\n *\n * @example\n * ```typescript\n * const absolute = getAbsoluteOgImageUrl(\n * '/api/og?title=Hello',\n * 'https://example.com'\n * );\n * // Result: https://example.com/api/og?title=Hello\n * ```\n */\nexport function getAbsoluteOgImageUrl(\n relativePath: string,\n siteUrl: string\n): string {\n // If path is already an absolute URL, return as-is\n if (relativePath.startsWith('http://') || relativePath.startsWith('https://')) {\n return relativePath;\n }\n\n // Remove trailing slash from site URL\n const cleanSiteUrl = siteUrl.replace(/\\/$/, '');\n\n // Ensure relative path starts with /\n const cleanPath = relativePath.startsWith('/')\n ? relativePath\n : `/${relativePath}`;\n\n return `${cleanSiteUrl}${cleanPath}`;\n}\n\n/**\n * Create OG image URL builder with preset configuration\n *\n * Useful when you want to reuse the same base URL and default parameters\n *\n * @param defaults - Default parameters to merge with each URL generation\n * @param options - Default options (baseUrl, useBase64)\n * @returns URL builder function\n *\n * @example\n * ```typescript\n * const buildOgUrl = createOgImageUrlBuilder(\n * { siteName: 'My Site', logo: '/logo.png' },\n * { baseUrl: '/api/og' }\n * );\n *\n * const url1 = buildOgUrl({ title: 'Page 1' });\n * const url2 = buildOgUrl({ title: 'Page 2', description: 'Custom desc' });\n * ```\n */\nexport function createOgImageUrlBuilder(\n defaults: Partial<OgImageUrlParams> = {},\n options: GenerateOgImageUrlOptions = {}\n) {\n return (params: OgImageUrlParams): string => {\n return generateOgImageUrl(\n { ...defaults, ...params },\n options\n );\n };\n}\n\n/**\n * Parse OG image URL parameters from a URL string (legacy query params)\n *\n * @param url - Full or relative URL with query parameters\n * @returns Parsed parameters object\n *\n * @example\n * ```typescript\n * const params = parseOgImageUrl('/api/og?title=Hello&description=World');\n * // Result: { title: 'Hello', description: 'World' }\n * ```\n */\nexport function parseOgImageUrl(url: string): Record<string, string> {\n try {\n const urlObj = new URL(url, 'http://dummy.com');\n const params: Record<string, string> = {};\n\n urlObj.searchParams.forEach((value, key) => {\n params[key] = value;\n });\n\n return params;\n } catch {\n return {};\n }\n}\n\n/**\n * Parse OG image data from base64-encoded query parameter\n *\n * Use this in your API route to decode the `data` parameter\n * Supports both base64 (new) and legacy query params format\n *\n * @param searchParams - URL search params or request object\n * @returns Parsed OG image parameters\n *\n * @example\n * ```typescript\n * // In Next.js API route (pages/api/og.ts)\n * export default function handler(req) {\n * const params = parseOgImageData(req.query);\n * // { title: 'Hello', description: 'World' }\n * }\n *\n * // In Next.js App Router (app/api/og/route.ts)\n * export async function GET(request: Request) {\n * const { searchParams } = new URL(request.url);\n * const params = parseOgImageData(Object.fromEntries(searchParams));\n * // { title: 'Hello', description: 'World' }\n * }\n * ```\n */\nexport function parseOgImageData(\n searchParams: Record<string, string | string[] | undefined> | URLSearchParams\n): Record<string, string> {\n try {\n // Handle URLSearchParams\n let params: Record<string, string | undefined>;\n\n if (searchParams instanceof URLSearchParams) {\n // Convert URLSearchParams to object\n params = {};\n for (const [key, value] of searchParams.entries()) {\n params[key] = value;\n }\n } else {\n params = searchParams as Record<string, string | undefined>;\n }\n\n // Debug logging\n if (process.env.NODE_ENV === 'development') {\n console.log('[parseOgImageData] Input params keys:', Object.keys(params));\n console.log('[parseOgImageData] Input params:', params);\n }\n\n // Check for base64-encoded data parameter\n const dataParam = params.data;\n if (dataParam && typeof dataParam === 'string' && dataParam.trim() !== '') {\n if (process.env.NODE_ENV === 'development') {\n console.log('[parseOgImageData] Found data param, length:', dataParam.length);\n }\n\n try {\n const decoded = decodeBase64(dataParam);\n if (process.env.NODE_ENV === 'development') {\n console.log('[parseOgImageData] Decoded string:', decoded.substring(0, 100));\n }\n\n const parsed = JSON.parse(decoded);\n if (process.env.NODE_ENV === 'development') {\n console.log('[parseOgImageData] Parsed JSON:', parsed);\n }\n\n // Ensure all values are strings\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(parsed)) {\n if (value !== undefined && value !== null) {\n result[key] = String(value);\n }\n }\n\n if (process.env.NODE_ENV === 'development') {\n console.log('[parseOgImageData] Result:', result);\n }\n\n return result;\n } catch (decodeError) {\n console.error('[parseOgImageData] Error decoding/parsing data param:', decodeError);\n if (decodeError instanceof Error) {\n console.error('[parseOgImageData] Error message:', decodeError.message);\n }\n // Fall through to legacy query params\n }\n } else {\n if (process.env.NODE_ENV === 'development') {\n console.log('[parseOgImageData] No data param found or empty');\n }\n }\n\n // Fallback to legacy query params format\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(params)) {\n if (key !== 'data' && value !== undefined && value !== null) {\n result[key] = Array.isArray(value) ? value[0] : String(value);\n }\n }\n\n if (process.env.NODE_ENV === 'development') {\n console.log('[parseOgImageData] Fallback result:', result);\n }\n\n return result;\n } catch (error) {\n console.error('[parseOgImageData] Unexpected error:', error);\n return {};\n }\n}\n\n// Export base64 utilities for advanced use cases\nexport { encodeBase64, decodeBase64 };\n","/**\n * Metadata Utilities for OG Images\n *\n * Helpers to automatically add og:image to Next.js metadata\n */\n\nimport type { Metadata } from 'next';\nimport { generateOgImageUrl, getAbsoluteOgImageUrl, OgImageUrlParams} from './url';\n\n/**\n * Options for generating OG image metadata\n */\nexport interface AppMetadataOptions {\n /** Base URL of the OG image API route (e.g., '/api/og') */\n ogImageBaseUrl?: string;\n /** Site URL for absolute URLs (e.g., 'https://example.com') */\n siteUrl?: string;\n /** Default parameters to merge with page-specific params */\n defaultParams?: Partial<OgImageUrlParams>;\n /** Whether to use base64 encoding (default: true) */\n useBase64?: boolean;\n /** Favicon URL (e.g., '/favicon.png') - automatically added to metadata.icons */\n favicon?: string;\n /** Apple touch icon URL (e.g., '/apple-icon.png') - automatically added to metadata.icons */\n appleIcon?: string;\n}\n\n/**\n * Extract title from metadata\n */\nfunction extractTitle(metadata: Metadata): string {\n if (typeof metadata.title === 'string') {\n return metadata.title;\n }\n if (metadata.title) {\n if ('default' in metadata.title) {\n return metadata.title.default;\n }\n if ('absolute' in metadata.title) {\n return metadata.title.absolute;\n }\n }\n return '';\n}\n\n/**\n * Extract description from metadata\n */\nfunction extractDescription(metadata: Metadata): string {\n if (typeof metadata.description === 'string') {\n return metadata.description;\n }\n return '';\n}\n\n/**\n * Generate Next.js metadata with OG image\n *\n * Automatically adds og:image, twitter:image, and other OG meta tags\n * Automatically extracts title and description from metadata if not provided\n *\n * @param metadata - Base metadata object\n * @param ogImageParams - Optional parameters for OG image generation (if not provided, extracted from metadata)\n * @param options - Configuration options\n * @returns Enhanced metadata with OG image\n *\n * @example\n * ```typescript\n * // In page.tsx or layout.tsx\n * import { generateAppMetadata } from '@djangocfg/nextjs/og-image';\n * import { settings } from '@/core/settings';\n *\n * export const metadata = generateAppMetadata(\n * {\n * title: 'My Page',\n * description: 'Page description',\n * },\n * undefined, // Will auto-extract from metadata\n * {\n * ogImageBaseUrl: '/api/og',\n * siteUrl: settings.app.siteUrl,\n * favicon: settings.app.icons.favicon,\n * appleIcon: settings.app.icons.logo192,\n * defaultParams: {\n * siteName: settings.app.name,\n * logo: settings.app.icons.logoVector,\n * },\n * }\n * );\n * ```\n */\n/**\n * Get site URL automatically from environment\n * Priority: NEXT_PUBLIC_SITE_URL > VERCEL_URL > fallback\n */\nfunction getSiteUrl(): string {\n // Try NEXT_PUBLIC_SITE_URL first (most reliable)\n if (typeof process !== 'undefined' && process.env.NEXT_PUBLIC_SITE_URL) {\n return process.env.NEXT_PUBLIC_SITE_URL;\n }\n \n // Development fallback\n return '';\n}\n\nexport function generateAppMetadata(\n metadata: Metadata,\n ogImageParams?: Partial<OgImageUrlParams>,\n options: AppMetadataOptions = {}\n): Metadata {\n const {\n ogImageBaseUrl = 'https://djangocfg.com/api/og',\n siteUrl: providedSiteUrl,\n defaultParams = {},\n useBase64 = true,\n favicon,\n appleIcon,\n } = options;\n\n // Automatically determine siteUrl if not provided or is undefined\n const siteUrl = providedSiteUrl && providedSiteUrl !== 'undefined' \n ? providedSiteUrl \n : getSiteUrl();\n\n // Auto-extract title and description from metadata if not provided\n const extractedTitle = extractTitle(metadata);\n const extractedDescription = extractDescription(metadata);\n\n // Merge with provided params (provided params take precedence)\n const finalOgImageParams: OgImageUrlParams = {\n ...defaultParams,\n title: ogImageParams?.title || extractedTitle || defaultParams.title || '',\n description: ogImageParams?.description || extractedDescription || defaultParams.description || '',\n ...ogImageParams,\n };\n\n // Get alt text for image (title or siteName as fallback)\n const imageAlt = finalOgImageParams.title || finalOgImageParams.siteName;\n\n // Generate relative OG image URL\n const relativeOgImageUrl = generateOgImageUrl(\n finalOgImageParams,\n { baseUrl: ogImageBaseUrl, useBase64 }\n );\n\n // CRITICAL: Use absolute URL to ensure query params are preserved\n // Next.js might strip query params from relative URLs in some cases\n // Absolute URLs ensure the full URL with params is used\n const ogImageUrl = siteUrl\n ? getAbsoluteOgImageUrl(relativeOgImageUrl, siteUrl)\n : relativeOgImageUrl;\n\n // Normalize existing images to arrays\n const existingOgImages = metadata.openGraph?.images\n ? Array.isArray(metadata.openGraph.images)\n ? metadata.openGraph.images\n : [metadata.openGraph.images]\n : [];\n\n const existingTwitterImages = metadata.twitter?.images\n ? Array.isArray(metadata.twitter.images)\n ? metadata.twitter.images\n : [metadata.twitter.images]\n : [];\n\n // Build final metadata object\n const finalMetadata: Metadata = {\n ...metadata,\n openGraph: {\n ...metadata.openGraph,\n images: [\n ...existingOgImages,\n {\n url: ogImageUrl,\n width: 1200,\n height: 630,\n alt: imageAlt,\n },\n ],\n },\n twitter: {\n ...metadata.twitter,\n card: 'summary_large_image',\n images: [\n ...existingTwitterImages,\n {\n url: ogImageUrl,\n alt: imageAlt,\n },\n ],\n },\n };\n\n // Automatically add metadataBase if siteUrl is an absolute URL\n // metadataBase requires absolute URL - skip if siteUrl is relative path (like /cfg/admin)\n // Only add if not already set in input metadata\n if (!finalMetadata.metadataBase && siteUrl) {\n // Check if siteUrl is an absolute URL (starts with http:// or https://)\n if (siteUrl.startsWith('http://') || siteUrl.startsWith('https://')) {\n try {\n finalMetadata.metadataBase = new URL(siteUrl);\n } catch (e) {\n // If URL construction fails, skip metadataBase\n // This shouldn't happen if we check for http/https, but just in case\n }\n }\n }\n\n // Add favicon and apple icon if provided\n if (favicon || appleIcon) {\n // metadata.icons can be string, array, or object - only spread if it's an object\n const existingIcons = metadata.icons && typeof metadata.icons === 'object' && !Array.isArray(metadata.icons)\n ? metadata.icons\n : {};\n finalMetadata.icons = {\n ...existingIcons,\n ...(favicon && { icon: favicon }),\n ...(appleIcon && { apple: appleIcon }),\n };\n }\n\n return finalMetadata;\n}\n\n/**\n * Create OG image metadata generator with preset configuration\n *\n * Useful when you want to reuse the same configuration across multiple pages\n *\n * @param options - Configuration options\n * @returns Metadata generator function\n *\n * @example\n * ```typescript\n * // In a shared file (e.g., lib/metadata.ts)\n * import { createAppMetadataGenerator } from '@djangocfg/nextjs/og-image';\n * import { settings } from '@/core/settings';\n *\n * export const generateMetadata = createAppMetadataGenerator({\n * ogImageBaseUrl: '/api/og',\n * siteUrl: settings.app.siteUrl,\n * favicon: settings.app.icons.favicon,\n * appleIcon: settings.app.icons.logo192,\n * defaultParams: {\n * siteName: settings.app.name,\n * logo: settings.app.icons.logoVector,\n * },\n * });\n *\n * // In page.tsx\n * import { generateMetadata } from '@/lib/metadata';\n *\n * export const metadata = generateMetadata({\n * title: 'My Page',\n * description: 'Description',\n * });\n * ```\n */\nexport function createAppMetadataGenerator(\n options: AppMetadataOptions\n) {\n return (\n metadata: Metadata,\n ogImageParams?: Partial<OgImageUrlParams>\n ): Metadata => {\n return generateAppMetadata(metadata, ogImageParams, options);\n };\n}\n\n","/**\n * Navigation Utilities\n *\n * Common utilities for route definitions and navigation\n */\n\nimport type { RouteDefinition, RouteMetadata, MenuItem } from './types';\n\n// ─────────────────────────────────────────────────────────────────────────\n// Route Definition Helper\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Define a route with metadata\n *\n * IMPORTANT: Next.js automatically handles basePath for <Link> components when\n * basePath is set in next.config.ts. We should NOT add basePath manually here,\n * as it would cause double-prefixing in static builds.\n *\n * @param path - Route path (e.g., '/dashboard', '/admin/users')\n * @param metadata - Route metadata (label, icon, etc.)\n */\nexport function defineRoute(\n path: string,\n metadata: RouteMetadata,\n): RouteDefinition {\n // Always return path as-is. Next.js will handle basePath automatically\n // for <Link> components when basePath is set in next.config.ts\n return {\n path,\n metadata,\n };\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Route Guards\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Get redirect path for unauthenticated users\n */\nexport function getUnauthenticatedRedirect(\n path: string,\n authPath: string = '/auth',\n): string | null {\n if (path.startsWith('/private') || path.startsWith('/admin')) {\n // Return path as-is. Next.js will handle basePath automatically for router.push()\n // when basePath is set in next.config.ts\n return authPath;\n }\n return null;\n}\n\n/**\n * Get redirect path to auth page\n */\nexport function redirectToAuth(\n authPath: string = '/auth',\n): string {\n // Return path as-is. Next.js will handle basePath automatically for router.push()\n // when basePath is set in next.config.ts\n return authPath;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Route Lookup\n// ─────────────────────────────────────────────────────────────────────────\n\nexport function findRoute(\n routes: RouteDefinition[],\n path: string\n): RouteDefinition | undefined {\n return routes.find((r) => r.path === path);\n}\n\nexport function findRouteByPattern(\n routes: RouteDefinition[],\n path: string\n): RouteDefinition | undefined {\n const exact = findRoute(routes, path);\n if (exact) return exact;\n\n const segments = path.split('/').filter(Boolean);\n for (let i = segments.length; i > 0; i--) {\n const parentPath = '/' + segments.slice(0, i).join('/');\n const parent = findRoute(routes, parentPath);\n if (parent) return parent;\n }\n\n return undefined;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Page Title\n// ─────────────────────────────────────────────────────────────────────────\n\nexport function getPageTitle(\n routes: RouteDefinition[],\n path: string,\n fallback = 'Dashboard'\n): string {\n const route = findRouteByPattern(routes, path);\n return route?.metadata.label || fallback;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Active Route\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Check if a route is active\n *\n * @param current - Current pathname\n * @param target - Target route path to check\n * @param allRoutes - Optional array of all routes to prevent parent paths from being active when child paths are active\n * @returns true if the route is active\n */\nexport function isActive(\n current: string,\n target: string,\n allRoutes?: RouteDefinition[]\n): boolean {\n const matches =\n current === target || (target !== '/' && current.startsWith(target + '/'));\n\n // If allRoutes is provided, check for more specific paths\n if (matches && allRoutes) {\n return !allRoutes.some(\n (otherRoute) =>\n otherRoute.path !== target &&\n otherRoute.path.startsWith(target + '/') &&\n (current === otherRoute.path ||\n current.startsWith(otherRoute.path + '/'))\n );\n }\n\n return matches;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Menu Generation Helper\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Filter and convert routes to menu items\n */\nexport function routesToMenuItems(\n routes: RouteDefinition[],\n groupName: string\n): MenuItem[] {\n return routes\n .filter(\n (r) =>\n r.metadata.group === groupName &&\n r.metadata.icon &&\n (r.metadata.show === undefined || r.metadata.show === true)\n )\n .sort((a, b) => (a.metadata.order || 0) - (b.metadata.order || 0))\n .map((r) => ({\n path: r.path,\n label: r.metadata.label,\n icon: r.metadata.icon!,\n }));\n}\n\n","/**\n * PWA (Progressive Web App) Plugin\n *\n * Configures Serwist for service worker and offline support\n * Modern PWA solution for Next.js 15+ with App Router\n *\n * @see https://serwist.pages.dev/\n */\n\nimport type { NextConfig } from 'next';\nimport { consola } from 'consola';\n\nexport interface PWAPluginOptions {\n /**\n * Destination directory for service worker files\n * @default 'public'\n * @deprecated Use swDest instead\n */\n dest?: string;\n\n /**\n * Path to service worker source file (relative to project root)\n * @default 'app/sw.ts'\n */\n swSrc?: string;\n\n /**\n * Destination for compiled service worker\n * @default 'public/sw.js'\n */\n swDest?: string;\n\n /**\n * Disable PWA completely\n * @default false in production, true in development\n * @example disable: process.env.NODE_ENV === 'development'\n */\n disable?: boolean;\n\n /**\n * Cache on navigation - cache pages when navigating\n * @default true\n */\n cacheOnNavigation?: boolean;\n\n /**\n * Reload app when device goes back online\n * @default true\n */\n reloadOnOnline?: boolean;\n\n /**\n * Additional Serwist options\n * @see https://serwist.pages.dev/docs/next/configuring\n */\n serwistOptions?: Record<string, any>;\n}\n\n/**\n * Add PWA configuration to Next.js config using Serwist\n *\n * @example Basic usage\n * ```ts\n * import { createBaseNextConfig, withPWA } from '@djangocfg/nextjs/config';\n *\n * const nextConfig = createBaseNextConfig({...});\n *\n * export default withPWA(nextConfig, {\n * swSrc: 'app/sw.ts',\n * disable: process.env.NODE_ENV === 'development',\n * });\n * ```\n *\n * @example Integrated with createBaseNextConfig\n * ```ts\n * import { createBaseNextConfig } from '@djangocfg/nextjs/config';\n *\n * const config = createBaseNextConfig({\n * pwa: {\n * swSrc: 'app/sw.ts',\n * disable: false,\n * },\n * });\n *\n * export default config;\n * ```\n */\nexport function withPWA(\n nextConfig: NextConfig,\n options: PWAPluginOptions = {}\n): NextConfig {\n const isDev = process.env.NODE_ENV === 'development';\n const isStaticBuild = process.env.NEXT_PUBLIC_STATIC_BUILD === 'true';\n\n // Determine if PWA should be disabled:\n // - Explicitly disabled via options\n // - In development mode (default)\n // - Static build (output: 'export' doesn't support service workers)\n const shouldDisable = options.disable !== undefined\n ? options.disable\n : (isDev || isStaticBuild);\n\n const defaultOptions: PWAPluginOptions = {\n swSrc: 'app/sw.ts',\n swDest: 'public/sw.js',\n disable: shouldDisable,\n cacheOnNavigation: true,\n reloadOnOnline: true,\n ...options,\n };\n\n try {\n // Suppress Turbopack warning - it only applies to dev mode, not production builds\n // The warning is misleading when running `next build` with Turbopack\n // See: https://github.com/serwist/serwist/issues/54\n if (!process.env.SERWIST_SUPPRESS_TURBOPACK_WARNING) {\n process.env.SERWIST_SUPPRESS_TURBOPACK_WARNING = '1';\n }\n\n const withSerwistInit = require('@serwist/next').default;\n\n const withSerwist = withSerwistInit({\n swSrc: defaultOptions.swSrc,\n swDest: defaultOptions.swDest,\n disable: defaultOptions.disable,\n cacheOnNavigation: defaultOptions.cacheOnNavigation,\n reloadOnOnline: defaultOptions.reloadOnOnline,\n ...defaultOptions.serwistOptions,\n });\n\n return withSerwist(nextConfig);\n } catch (error) {\n consola.error('Failed to configure Serwist:', error);\n return nextConfig;\n }\n}\n\n/**\n * Get service worker template content\n *\n * Returns ready-to-use service worker code for app/sw.ts\n *\n * @example\n * ```ts\n * import { getServiceWorkerTemplate } from '@djangocfg/nextjs/config';\n *\n * // Copy this to your app/sw.ts file\n * console.log(getServiceWorkerTemplate());\n * ```\n */\nexport function getServiceWorkerTemplate(): string {\n return `/**\n * Service Worker (Serwist)\n *\n * Modern PWA service worker using Serwist\n */\n\nimport { defaultCache } from '@serwist/next/worker';\nimport { Serwist } from 'serwist';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ndeclare const self: any;\n\nconst serwist = new Serwist({\n // Precache entries injected by Serwist build plugin\n precacheEntries: self.__SW_MANIFEST,\n\n // Skip waiting - activate new SW immediately\n skipWaiting: true,\n\n // Take control of all clients immediately\n clientsClaim: true,\n\n // Enable navigation preload for faster loads\n navigationPreload: true,\n\n // Use default Next.js runtime caching strategies\n runtimeCaching: defaultCache,\n\n // Fallback pages for offline\n fallbacks: {\n entries: [\n {\n url: '/_offline',\n matcher({ request }) {\n return request.destination === 'document';\n },\n },\n ],\n },\n});\n\nserwist.addEventListeners();\n`;\n}\n\n// Backward compatibility exports (deprecated)\nexport const defaultRuntimeCaching = [];\nexport function createApiCacheRule() {\n consola.warn('createApiCacheRule is deprecated with Serwist. Use defaultCache from @serwist/next/worker');\n return {};\n}\nexport function createStaticAssetRule() {\n consola.warn('createStaticAssetRule is deprecated with Serwist. Use defaultCache from @serwist/next/worker');\n return {};\n}\nexport function createCdnCacheRule() {\n consola.warn('createCdnCacheRule is deprecated with Serwist. Use defaultCache from @serwist/next/worker');\n return {};\n}\n","/**\n * Shared Constants for DjangoCFG Next.js Configuration\n */\n\n// Package name for version checks\nexport const PACKAGE_NAME = '@djangocfg/nextjs';\n\n// Version cache TTL (1 hour)\nexport const VERSION_CACHE_TTL_MS = 60 * 60 * 1000;\n\n// ASCII Art Banner for Django CFG\nexport const DJANGO_CFG_BANNER = `\n██████╗ ██╗ █████╗ ███╗ ██╗ ██████╗ ██████╗ ██████╗███████╗ ██████╗\n██╔══██╗ ██║██╔══██╗████╗ ██║██╔════╝ ██╔═══██╗ ██╔════╝██╔════╝██╔════╝\n██║ ██║ ██║███████║██╔██╗ ██║██║ ███╗██║ ██║ ██║ █████╗ ██║ ███╗\n██║ ██║██ ██║██╔══██║██║╚██╗██║██║ ██║██║ ██║ ██║ ██╔══╝ ██║ ██║\n██████╔╝╚█████╔╝██║ ██║██║ ╚████║╚██████╔╝╚██████╔╝ ╚██████╗██║ ╚██████╔╝\n╚═════╝ ╚════╝ ╚═╝ ╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═════╝ ╚═════╝╚═╝ ╚═════╝\n`;\n\n// All @djangocfg packages that can be updated together\nexport const DJANGOCFG_PACKAGES = [\n '@djangocfg/ui-core',\n '@djangocfg/ui-nextjs',\n '@djangocfg/layouts',\n '@djangocfg/nextjs',\n '@djangocfg/api',\n '@djangocfg/centrifugo',\n '@djangocfg/eslint-config',\n '@djangocfg/typescript-config',\n] as const;\n\n// Default packages to transpile\nexport const DEFAULT_TRANSPILE_PACKAGES = [\n '@djangocfg/ui-core',\n '@djangocfg/ui-nextjs',\n '@djangocfg/layouts',\n '@djangocfg/api',\n '@djangocfg/centrifugo',\n] as const;\n\n// Default packages to optimize imports\nexport const DEFAULT_OPTIMIZE_PACKAGES = [\n '@djangocfg/ui-core',\n '@djangocfg/ui-nextjs',\n '@djangocfg/layouts',\n 'lucide-react',\n 'recharts',\n] as const;\n","/**\n * Package Checker\n *\n * Checks which optional packages are missing and need to be installed.\n */\n\nimport { createRequire } from 'module';\nimport { join } from 'path';\n\nimport { isDev, isStaticBuild } from '../utils/env';\nimport { getPackagesForContext, OPTIONAL_PACKAGES } from './definitions';\n\nimport type { PackageDefinition } from './definitions';\nexport interface MissingPackage extends PackageDefinition {\n /** Why is this package needed? */\n reason: string;\n}\n\n/**\n * Check if a package is installed in the consumer's project\n * Uses process.cwd() to check from the consumer's context, not the library's\n */\nexport function isPackageInstalled(packageName: string): boolean {\n try {\n // Create require from consumer's cwd to check their node_modules\n const consumerRequire = createRequire(join(process.cwd(), 'package.json'));\n consumerRequire.resolve(packageName);\n return true;\n } catch {\n // Fallback: try regular require (for packages hoisted to root)\n try {\n require.resolve(packageName);\n return true;\n } catch {\n return false;\n }\n }\n}\n\n/**\n * Get all missing packages for current context\n */\nexport function getMissingPackages(): MissingPackage[] {\n const neededPackages = getPackagesForContext({ isStaticBuild, isDev });\n const missing: MissingPackage[] = [];\n\n for (const pkg of neededPackages) {\n if (!isPackageInstalled(pkg.name)) {\n missing.push({\n ...pkg,\n reason: getReasonText(pkg),\n });\n }\n }\n\n return missing;\n}\n\n/**\n * Check specific packages\n */\nexport function checkPackages(packageNames: string[]): MissingPackage[] {\n const missing: MissingPackage[] = [];\n\n for (const name of packageNames) {\n if (!isPackageInstalled(name)) {\n const definition = OPTIONAL_PACKAGES.find(p => p.name === name);\n missing.push({\n name,\n description: definition?.description || 'Optional package',\n condition: definition?.condition || 'always',\n devDependency: definition?.devDependency ?? true,\n reason: definition ? getReasonText(definition) : 'Requested by configuration',\n });\n }\n }\n\n return missing;\n}\n\n/**\n * Get human-readable reason for package requirement\n */\nfunction getReasonText(pkg: PackageDefinition): string {\n switch (pkg.condition) {\n case 'static-build':\n return 'Required for static build (NEXT_PUBLIC_STATIC_BUILD=true)';\n case 'dev':\n return 'Required for development mode';\n case 'always':\n return 'Required for all builds';\n default:\n return 'Optional feature';\n }\n}\n","/**\n * Environment Variable Utilities\n */\n\nexport const isStaticBuild = process.env.NEXT_PUBLIC_STATIC_BUILD === 'true';\nexport const isDev = process.env.NODE_ENV === 'development';\nexport const isProduction = process.env.NODE_ENV === 'production';\nexport const isCI = process.env.CI === 'true';\n\n/**\n * Get base path for static builds\n */\nexport function getBasePath(isDefaultCfgAdmin?: boolean): string {\n if (!isStaticBuild) return '';\n return isDefaultCfgAdmin ? '/cfg/admin' : '/cfg/nextjs-admin';\n}\n\n/**\n * Get API URL (empty for static builds)\n */\nexport function getApiUrl(): string {\n return isStaticBuild ? '' : (process.env.NEXT_PUBLIC_API_URL || '');\n}\n\n/**\n * Get Site URL (empty for static builds)\n */\nexport function getSiteUrl(): string {\n return isStaticBuild ? '' : (process.env.NEXT_PUBLIC_SITE_URL || '');\n}\n","/**\n * Package Definitions\n *\n * Defines optional packages that can be auto-installed when needed.\n */\n\nexport interface PackageDefinition {\n /** npm package name */\n name: string;\n /** Human-readable description */\n description: string;\n /** When is this package needed? */\n condition: 'static-build' | 'dev' | 'always';\n /** Is this a dev dependency? */\n devDependency: boolean;\n /** Feature flag that enables this package */\n featureFlag?: string;\n}\n\n/**\n * Optional packages that can be auto-installed\n */\nexport const OPTIONAL_PACKAGES: PackageDefinition[] = [\n {\n name: 'compression-webpack-plugin',\n description: 'Gzip and Brotli compression for static builds',\n condition: 'static-build',\n devDependency: true,\n },\n {\n name: '@next/bundle-analyzer',\n description: 'Bundle analyzer for analyzing build output',\n condition: 'dev',\n devDependency: true,\n featureFlag: 'ANALYZE',\n },\n];\n\n/**\n * Required peer dependencies (should already be installed)\n */\nexport const PEER_DEPENDENCIES = [\n 'next',\n 'react',\n 'react-dom',\n] as const;\n\n/**\n * Get packages needed for current build context\n */\nexport function getPackagesForContext(options: {\n isStaticBuild: boolean;\n isDev: boolean;\n}): PackageDefinition[] {\n return OPTIONAL_PACKAGES.filter(pkg => {\n switch (pkg.condition) {\n case 'static-build':\n return options.isStaticBuild;\n case 'dev':\n return options.isDev;\n case 'always':\n return true;\n default:\n return false;\n }\n });\n}\n","/**\n * Compression Plugin Setup\n *\n * Adds Gzip and Brotli compression for static builds.\n */\n\nimport type { Configuration as WebpackConfig } from 'webpack';\nimport { isPackageInstalled } from '../packages/checker';\n\nexport interface CompressionPluginOptions {\n /** Enable gzip compression */\n gzip?: boolean;\n /** Enable brotli compression */\n brotli?: boolean;\n /** Minimum file size to compress (default: 8192) */\n threshold?: number;\n /** Minimum compression ratio (default: 0.8) */\n minRatio?: number;\n /** Brotli compression level (default: 8) */\n brotliLevel?: number;\n}\n\nconst DEFAULT_OPTIONS: Required<CompressionPluginOptions> = {\n gzip: true,\n brotli: true,\n threshold: 8192,\n minRatio: 0.8,\n brotliLevel: 8,\n};\n\n/**\n * Add compression plugins to webpack config\n *\n * Returns true if plugins were added, false if compression-webpack-plugin is not installed\n */\nexport function addCompressionPlugins(\n config: WebpackConfig,\n options: CompressionPluginOptions = {}\n): boolean {\n // Check if compression-webpack-plugin is installed\n if (!isPackageInstalled('compression-webpack-plugin')) {\n return false;\n }\n\n const opts = { ...DEFAULT_OPTIONS, ...options };\n\n try {\n // Dynamic import to avoid bundling if not installed\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const CompressionPlugin = require('compression-webpack-plugin');\n\n if (!config.plugins) {\n config.plugins = [];\n }\n\n // Gzip compression\n if (opts.gzip) {\n config.plugins.push(\n new CompressionPlugin({\n filename: '[path][base].gz',\n algorithm: 'gzip',\n test: /\\.(js|css|html|svg|json)$/,\n threshold: opts.threshold,\n minRatio: opts.minRatio,\n })\n );\n }\n\n // Brotli compression\n if (opts.brotli) {\n config.plugins.push(\n new CompressionPlugin({\n filename: '[path][base].br',\n algorithm: 'brotliCompress',\n test: /\\.(js|css|html|svg|json)$/,\n threshold: opts.threshold,\n minRatio: opts.minRatio,\n compressionOptions: {\n level: opts.brotliLevel,\n },\n })\n );\n }\n\n return true;\n } catch (error) {\n // compression-webpack-plugin failed to load\n return false;\n }\n}\n\n/**\n * Check if compression is available\n */\nexport function isCompressionAvailable(): boolean {\n return isPackageInstalled('compression-webpack-plugin');\n}\n","/**\n * Dev Startup Webpack Plugin\n *\n * Handles banner display, version checking, and package updates.\n */\n\nimport type { Compiler } from 'webpack';\nimport chalk from 'chalk';\n\nimport { AI_DOCS_HINT } from '../../ai/constants';\nimport { DJANGO_CFG_BANNER } from '../constants';\nimport { checkAndInstallPackages } from '../packages/installer';\nimport { checkAndUpdatePackages } from '../packages/updater';\nimport { getCurrentVersion } from '../utils/version';\n\n// Track if startup tasks were already run (persists across HMR)\nlet startupDone = false;\n\nexport interface DevStartupPluginOptions {\n /** Check for missing optional packages (default: true) */\n checkPackages?: boolean;\n /** Auto-install missing packages without prompting */\n autoInstall?: boolean;\n /** Check for @djangocfg/* package updates (default: true) */\n checkUpdates?: boolean;\n /** Auto-update packages without prompting */\n autoUpdate?: boolean;\n /** Force check workspace:* packages (for testing in monorepo) */\n forceCheckWorkspace?: boolean;\n}\n\n/**\n * Webpack plugin for dev startup tasks\n */\nexport class DevStartupPlugin {\n private options: DevStartupPluginOptions;\n\n constructor(options: DevStartupPluginOptions = {}) {\n this.options = options;\n }\n\n apply(compiler: Compiler): void {\n // Use tapPromise for proper async handling\n compiler.hooks.done.tapPromise('DevStartupPlugin', async () => {\n // Run startup tasks only once\n if (!startupDone) {\n startupDone = true;\n await this.runStartupTasks();\n }\n });\n }\n\n private async runStartupTasks(): Promise<void> {\n // 1. Print banner\n console.log('\\n' + chalk.yellowBright.bold(DJANGO_CFG_BANNER));\n\n // 2. Print current version\n const version = getCurrentVersion();\n if (version) {\n console.log(chalk.dim(` 📦 @djangocfg/nextjs v${version}`));\n }\n\n // 3. Check PWA setup\n this.checkPWASetup();\n\n // 4. Print AI docs hint\n console.log(chalk.magenta(` ${AI_DOCS_HINT}\\n`));\n\n // 5. Check for package updates\n if (this.options.checkUpdates !== false) {\n try {\n await checkAndUpdatePackages({\n autoUpdate: this.options.autoUpdate,\n forceCheckWorkspace: this.options.forceCheckWorkspace,\n force: true, // Force check ignoring cooldown\n });\n } catch (err) {\n console.log(chalk.red(' Update check failed:'), err);\n }\n }\n\n // 6. Check for missing optional packages\n if (this.options.checkPackages !== false) {\n await checkAndInstallPackages({\n autoInstall: this.options.autoInstall,\n });\n }\n }\n\n private checkPWASetup(): void {\n const fs = require('fs');\n const path = require('path');\n\n const cwd = process.cwd();\n const swPath = path.join(cwd, 'app', 'sw.ts');\n const manifestPath = path.join(cwd, 'app', 'manifest.ts');\n\n const hasSW = fs.existsSync(swPath);\n const hasManifest = fs.existsSync(manifestPath);\n\n if (hasSW || hasManifest) {\n console.log(chalk.cyan(' 📱 PWA Configuration:'));\n\n if (hasSW) {\n console.log(chalk.green(' ✓ Service Worker: app/sw.ts'));\n } else {\n console.log(chalk.yellow(' ⚠ Service Worker: not found'));\n }\n\n if (hasManifest) {\n console.log(chalk.green(' ✓ Manifest: app/manifest.ts'));\n } else {\n console.log(chalk.yellow(' ⚠ Manifest: not found'));\n }\n\n console.log(chalk.dim(' → Check: DevTools → Application → Service Workers'));\n console.log(chalk.dim(' → Test push: import from @djangocfg/nextjs/pwa'));\n }\n }\n}\n\n/**\n * Reset plugin state (useful for tests)\n */\nexport function resetDevStartupState(): void {\n startupDone = false;\n}\n","/**\n * AI Documentation Constants\n */\n\n// MCP Server URLs\nexport const MCP_BASE_URL = 'https://mcp.djangocfg.com';\nexport const MCP_SERVER_URL = `${MCP_BASE_URL}/mcp`;\nexport const MCP_API_URL = `${MCP_BASE_URL}/api/search`;\n\n// API Endpoints\nexport const API_SEARCH_ENDPOINT = '/api/search';\nexport const API_INFO_ENDPOINT = '/api/info';\nexport const DEFAULT_TIMEOUT = 10000; // ms\n\n// AI Hint for console output\nexport const AI_DOCS_HINT = `🤖 AI Docs: ${MCP_SERVER_URL} | pnpm ai-docs search \"query\"`;\n\n// Full AI Hint description\nexport const AI_HINT = `\nDjangoCFG Documentation is available via MCP server.\n\nTo get help with DjangoCFG configuration:\n1. Use the MCP server: ${MCP_SERVER_URL}\n2. Or search directly: ${MCP_API_URL}?q=YOUR_QUERY&limit=5\n\nExample queries:\n- \"How to configure PostgreSQL database?\"\n- \"What is DatabaseConfig?\"\n- \"How to setup Redis cache?\"\n- \"Email configuration with SMTP\"\n`;\n","/**\n * Package Installer\n *\n * Provides auto-installation functionality with user confirmation and progress indication.\n */\n\nimport chalk from 'chalk';\nimport { execSync, spawn } from 'child_process';\nimport Conf from 'conf';\nimport consola from 'consola';\nimport { createInterface } from 'readline';\n\nimport { isCI } from '../utils/env';\nimport { getMissingPackages } from './checker';\n\nimport type { MissingPackage } from './checker';\n// Installer preferences cache\nconst installerCache = new Conf<{\n autoInstall?: boolean;\n skipPackages?: string[];\n lastPrompt?: number;\n}>({\n projectName: 'djangocfg-nextjs-installer',\n projectVersion: '1.0.0',\n});\n\n// Don't prompt more than once per hour\nconst PROMPT_COOLDOWN_MS = 60 * 60 * 1000;\n\n// Spinner frames for progress\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\nexport interface InstallOptions {\n /** Auto-install without prompting */\n autoInstall?: boolean;\n /** Skip specific packages */\n skipPackages?: string[];\n /** Force prompt even if recently prompted */\n force?: boolean;\n}\n\nexport interface InstallProgress {\n current: number;\n total: number;\n package: string;\n status: 'pending' | 'installing' | 'done' | 'error';\n}\n\n/**\n * Detect package manager\n */\nexport function detectPackageManager(): 'pnpm' | 'yarn' | 'npm' {\n try {\n // Check for lockfiles\n const fs = require('fs');\n const path = require('path');\n const cwd = process.cwd();\n\n if (fs.existsSync(path.join(cwd, 'pnpm-lock.yaml'))) return 'pnpm';\n if (fs.existsSync(path.join(cwd, 'yarn.lock'))) return 'yarn';\n if (fs.existsSync(path.join(cwd, 'package-lock.json'))) return 'npm';\n\n // Check for global package manager\n try {\n execSync('pnpm --version', { stdio: 'ignore' });\n return 'pnpm';\n } catch {\n try {\n execSync('yarn --version', { stdio: 'ignore' });\n return 'yarn';\n } catch {\n return 'npm';\n }\n }\n } catch {\n return 'npm';\n }\n}\n\n/**\n * Build install command for a single package\n */\nexport function buildSingleInstallCommand(\n packageName: string,\n isDev: boolean,\n pm: 'pnpm' | 'yarn' | 'npm'\n): string {\n const devFlag = isDev ? '-D ' : '';\n switch (pm) {\n case 'pnpm':\n return `pnpm add ${devFlag}${packageName}`;\n case 'yarn':\n return `yarn add ${devFlag}${packageName}`;\n case 'npm':\n return `npm install ${devFlag}${packageName}`;\n }\n}\n\n/**\n * Build install command for multiple packages (for display)\n */\nexport function buildInstallCommand(packages: MissingPackage[], pm: 'pnpm' | 'yarn' | 'npm'): string {\n const devPackages = packages.filter(p => p.devDependency).map(p => p.name);\n const prodPackages = packages.filter(p => !p.devDependency).map(p => p.name);\n\n const commands: string[] = [];\n\n if (devPackages.length > 0) {\n switch (pm) {\n case 'pnpm':\n commands.push(`pnpm add -D ${devPackages.join(' ')}`);\n break;\n case 'yarn':\n commands.push(`yarn add -D ${devPackages.join(' ')}`);\n break;\n case 'npm':\n commands.push(`npm install -D ${devPackages.join(' ')}`);\n break;\n }\n }\n\n if (prodPackages.length > 0) {\n switch (pm) {\n case 'pnpm':\n commands.push(`pnpm add ${prodPackages.join(' ')}`);\n break;\n case 'yarn':\n commands.push(`yarn add ${prodPackages.join(' ')}`);\n break;\n case 'npm':\n commands.push(`npm install ${prodPackages.join(' ')}`);\n break;\n }\n }\n\n return commands.join(' && ');\n}\n\n/**\n * Ask user for confirmation via readline\n */\nasync function askConfirmation(question: string): Promise<boolean> {\n // Skip prompt in CI or non-TTY environments\n if (isCI || !process.stdin.isTTY) {\n return false;\n }\n\n return new Promise((resolve) => {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n rl.question(question, (answer) => {\n rl.close();\n const normalized = answer.toLowerCase().trim();\n resolve(normalized === '' || normalized === 'y' || normalized === 'yes');\n });\n });\n}\n\n/**\n * Create a simple spinner\n */\nfunction createSpinner(text: string) {\n let frameIndex = 0;\n let interval: NodeJS.Timeout | null = null;\n let currentText = text;\n\n const render = () => {\n const frame = SPINNER_FRAMES[frameIndex];\n process.stdout.write(`\\r${chalk.cyan(frame)} ${currentText}`);\n frameIndex = (frameIndex + 1) % SPINNER_FRAMES.length;\n };\n\n return {\n start() {\n if (process.stdout.isTTY) {\n interval = setInterval(render, 80);\n render();\n } else {\n console.log(` ${currentText}`);\n }\n return this;\n },\n text(newText: string) {\n currentText = newText;\n if (!process.stdout.isTTY) {\n console.log(` ${newText}`);\n }\n return this;\n },\n succeed(text?: string) {\n if (interval) clearInterval(interval);\n if (process.stdout.isTTY) {\n process.stdout.write(`\\r${chalk.green('✓')} ${text || currentText}\\n`);\n } else {\n console.log(` ${chalk.green('✓')} ${text || currentText}`);\n }\n return this;\n },\n fail(text?: string) {\n if (interval) clearInterval(interval);\n if (process.stdout.isTTY) {\n process.stdout.write(`\\r${chalk.red('✗')} ${text || currentText}\\n`);\n } else {\n console.log(` ${chalk.red('✗')} ${text || currentText}`);\n }\n return this;\n },\n stop() {\n if (interval) clearInterval(interval);\n if (process.stdout.isTTY) {\n process.stdout.write('\\r\\x1b[K'); // Clear line\n }\n return this;\n },\n };\n}\n\n/**\n * Install a single package with progress\n */\nasync function installSinglePackage(\n pkg: MissingPackage,\n pm: 'pnpm' | 'yarn' | 'npm',\n index: number,\n total: number\n): Promise<boolean> {\n const command = buildSingleInstallCommand(pkg.name, pkg.devDependency, pm);\n const progress = `[${index + 1}/${total}]`;\n const spinner = createSpinner(`${chalk.dim(progress)} Installing ${chalk.cyan(pkg.name)}...`);\n\n spinner.start();\n\n return new Promise((resolve) => {\n const [cmd, ...args] = command.split(' ');\n const proc = spawn(cmd, args, {\n shell: true,\n cwd: process.cwd(),\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n let stderr = '';\n\n proc.stderr?.on('data', (data) => {\n stderr += data.toString();\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n spinner.succeed(`${chalk.dim(progress)} ${chalk.cyan(pkg.name)} ${chalk.green('installed')}`);\n resolve(true);\n } else {\n spinner.fail(`${chalk.dim(progress)} ${chalk.cyan(pkg.name)} ${chalk.red('failed')}`);\n if (stderr) {\n console.log(chalk.dim(` ${stderr.split('\\n')[0]}`));\n }\n resolve(false);\n }\n });\n\n proc.on('error', () => {\n spinner.fail(`${chalk.dim(progress)} ${chalk.cyan(pkg.name)} ${chalk.red('failed')}`);\n resolve(false);\n });\n });\n}\n\n/**\n * Install packages with progress indication\n */\nexport async function installPackagesWithProgress(packages: MissingPackage[]): Promise<boolean> {\n if (packages.length === 0) return true;\n\n const pm = detectPackageManager();\n const total = packages.length;\n\n console.log('');\n console.log(chalk.bold(` Installing ${total} package${total > 1 ? 's' : ''}...`));\n console.log('');\n\n let successCount = 0;\n let failedPackages: string[] = [];\n\n for (let i = 0; i < packages.length; i++) {\n const success = await installSinglePackage(packages[i], pm, i, total);\n if (success) {\n successCount++;\n } else {\n failedPackages.push(packages[i].name);\n }\n }\n\n console.log('');\n\n if (failedPackages.length === 0) {\n consola.success(`All ${total} packages installed successfully!`);\n return true;\n } else if (successCount > 0) {\n consola.warn(`${successCount}/${total} packages installed. Failed: ${failedPackages.join(', ')}`);\n return false;\n } else {\n consola.error(`Failed to install packages: ${failedPackages.join(', ')}`);\n return false;\n }\n}\n\n/**\n * Install packages (simple version without per-package progress)\n */\nexport async function installPackages(packages: MissingPackage[]): Promise<boolean> {\n // Use progress version for multiple packages in TTY\n if (packages.length > 1 && process.stdout.isTTY) {\n return installPackagesWithProgress(packages);\n }\n\n // Simple installation for single package or non-TTY\n if (packages.length === 0) return true;\n\n const pm = detectPackageManager();\n const command = buildInstallCommand(packages, pm);\n\n consola.info(`Installing: ${chalk.cyan(packages.map(p => p.name).join(', '))}`);\n\n const spinner = createSpinner('Installing packages...');\n spinner.start();\n\n return new Promise((resolve) => {\n const proc = spawn(command, {\n shell: true,\n cwd: process.cwd(),\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n spinner.succeed('Packages installed successfully!');\n resolve(true);\n } else {\n spinner.fail('Failed to install packages');\n resolve(false);\n }\n });\n\n proc.on('error', () => {\n spinner.fail('Installation failed');\n resolve(false);\n });\n });\n}\n\n/**\n * Check and prompt for missing packages\n *\n * Returns true if all packages are available (either already installed or just installed)\n */\nexport async function checkAndInstallPackages(options: InstallOptions = {}): Promise<boolean> {\n const missing = getMissingPackages();\n\n // Filter out skipped packages\n const skipList = options.skipPackages || installerCache.get('skipPackages') || [];\n const toInstall = missing.filter(p => !skipList.includes(p.name));\n\n if (toInstall.length === 0) {\n return true;\n }\n\n // Check cooldown (don't prompt too often)\n const lastPrompt = installerCache.get('lastPrompt') || 0;\n if (!options.force && (Date.now() - lastPrompt) < PROMPT_COOLDOWN_MS) {\n // Show info but don't prompt\n printMissingPackagesInfo(toInstall);\n return false;\n }\n\n // Auto-install if configured\n if (options.autoInstall || installerCache.get('autoInstall')) {\n return installPackages(toInstall);\n }\n\n // Show missing packages\n console.log('');\n consola.box('📦 Missing Optional Packages');\n console.log('');\n\n for (const pkg of toInstall) {\n console.log(` ${chalk.yellow('•')} ${chalk.bold(pkg.name)}`);\n console.log(` ${chalk.dim(pkg.description)}`);\n console.log(` ${chalk.dim(pkg.reason)}`);\n console.log('');\n }\n\n // Build install command for display\n const pm = detectPackageManager();\n const command = buildInstallCommand(toInstall, pm);\n\n console.log(` ${chalk.cyan('Command:')} ${command}`);\n console.log('');\n\n // Ask for confirmation\n installerCache.set('lastPrompt', Date.now());\n\n const shouldInstall = await askConfirmation(\n `${chalk.green('?')} Install these packages now? ${chalk.dim('[Y/n]')} `\n );\n\n if (shouldInstall) {\n const success = await installPackages(toInstall);\n\n // Ask if user wants to enable auto-install for future\n if (success) {\n const enableAuto = await askConfirmation(\n `${chalk.green('?')} Enable auto-install for future? ${chalk.dim('[y/N]')} `\n );\n if (enableAuto) {\n installerCache.set('autoInstall', true);\n consola.info('Auto-install enabled. Run with --no-auto-install to disable.');\n }\n }\n\n return success;\n }\n\n // User declined, ask if they want to skip these packages permanently\n const skipPermanently = await askConfirmation(\n `${chalk.green('?')} Skip these packages in future prompts? ${chalk.dim('[y/N]')} `\n );\n\n if (skipPermanently) {\n const currentSkip = installerCache.get('skipPackages') || [];\n installerCache.set('skipPackages', [...currentSkip, ...toInstall.map(p => p.name)]);\n consola.info('Packages added to skip list.');\n }\n\n return false;\n}\n\n/**\n * Print info about missing packages without prompting\n */\nfunction printMissingPackagesInfo(packages: MissingPackage[]): void {\n if (packages.length === 0) return;\n\n const pm = detectPackageManager();\n const command = buildInstallCommand(packages, pm);\n\n consola.warn(`Missing optional packages: ${packages.map(p => p.name).join(', ')}`);\n consola.info(`Install with: ${chalk.cyan(command)}`);\n}\n\n/**\n * Reset installer preferences\n */\nexport function resetInstallerPreferences(): void {\n installerCache.clear();\n consola.success('Installer preferences reset');\n}\n","/**\n * Package Updater\n *\n * Checks for outdated @djangocfg/* packages and offers to update them.\n */\n\nimport chalk from 'chalk';\nimport { spawn } from 'child_process';\nimport Conf from 'conf';\nimport consola from 'consola';\nimport { createRequire } from 'module';\nimport { join } from 'path';\nimport { createInterface } from 'readline';\nimport semver from 'semver';\n\nimport { DJANGOCFG_PACKAGES, PACKAGE_NAME } from '../constants';\nimport { isCI } from '../utils/env';\nimport { detectPackageManager } from './installer';\n\n// Updater preferences cache\nconst updaterCache = new Conf<{\n autoUpdate?: boolean;\n lastCheck?: number;\n skippedVersions?: Record<string, string>;\n}>({\n projectName: 'djangocfg-nextjs-updater',\n projectVersion: '1.0.0',\n});\n\n// Check for updates once per hour\nconst UPDATE_CHECK_COOLDOWN_MS = 60 * 60 * 1000;\n\n// Spinner frames\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\n\nexport interface PackageVersion {\n name: string;\n current: string | null;\n latest: string | null;\n hasUpdate: boolean;\n}\n\nexport interface UpdateOptions {\n /** Auto-update without prompting */\n autoUpdate?: boolean;\n /** Force check even if recently checked (ignores cooldown) */\n force?: boolean;\n /** Force check even for workspace:* packages (for testing) */\n forceCheckWorkspace?: boolean;\n}\n\n/**\n * Check if package is a workspace dependency\n */\nfunction isWorkspacePackage(packageName: string): boolean {\n try {\n const fs = require('fs');\n const pkgJsonPath = join(process.cwd(), 'package.json');\n const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));\n\n const deps = { ...pkgJson.dependencies, ...pkgJson.devDependencies };\n const version = deps[packageName];\n\n return version?.startsWith('workspace:') || false;\n } catch {\n return false;\n }\n}\n\n/**\n * Get installed version of a package from consumer's project\n * Uses multiple fallback strategies for monorepo compatibility\n */\nexport function getInstalledVersion(packageName: string): string | null {\n const fs = require('fs');\n const cwd = process.cwd();\n\n // Strategy 1: Direct read from node_modules (works with symlinks)\n try {\n const directPath = join(cwd, 'node_modules', packageName, 'package.json');\n if (fs.existsSync(directPath)) {\n const pkg = JSON.parse(fs.readFileSync(directPath, 'utf-8'));\n return pkg.version || null;\n }\n } catch {\n // Continue to next strategy\n }\n\n // Strategy 2: Use createRequire from cwd\n try {\n const consumerRequire = createRequire(join(cwd, 'package.json'));\n const pkgPath = consumerRequire.resolve(`${packageName}/package.json`);\n const pkg = require(pkgPath);\n return pkg.version || null;\n } catch {\n // Continue to next strategy\n }\n\n // Strategy 3: Try global require\n try {\n const pkgPath = require.resolve(`${packageName}/package.json`);\n const pkg = require(pkgPath);\n return pkg.version || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Check if we should skip update checking for this package\n * (e.g., workspace packages shouldn't be checked against npm)\n */\nexport function shouldCheckUpdates(packageName: string): boolean {\n return !isWorkspacePackage(packageName);\n}\n\n/**\n * Fetch latest version from npm registry\n */\nasync function fetchLatestVersion(packageName: string): Promise<string | null> {\n try {\n const https = await import('https');\n return new Promise((resolve) => {\n const req = https.get(\n `https://registry.npmjs.org/${packageName}/latest`,\n { timeout: 5000 },\n (res: any) => {\n let data = '';\n res.on('data', (chunk: string) => { data += chunk; });\n res.on('end', () => {\n try {\n const json = JSON.parse(data);\n resolve(json.version || null);\n } catch {\n resolve(null);\n }\n });\n }\n );\n req.on('error', () => resolve(null));\n req.on('timeout', () => { req.destroy(); resolve(null); });\n });\n } catch {\n return null;\n }\n}\n\n/**\n * Check all @djangocfg packages for updates\n * All packages are aligned to the version of @djangocfg/nextjs (master package)\n * Skips workspace:* packages unless forceCheckWorkspace is true\n */\nexport async function checkForUpdates(options: { forceCheckWorkspace?: boolean } = {}): Promise<PackageVersion[]> {\n const results: PackageVersion[] = [];\n\n // First, get the latest version of master package (@djangocfg/nextjs)\n // All other packages should align to this version\n const masterLatest = await fetchLatestVersion(PACKAGE_NAME);\n if (!masterLatest) {\n // Can't determine target version, skip update check\n return results;\n }\n\n // Check packages against master version\n const checks = DJANGOCFG_PACKAGES.map(async (name) => {\n // Skip workspace packages unless force mode\n const isWorkspace = !shouldCheckUpdates(name);\n if (!options.forceCheckWorkspace && isWorkspace) {\n return null;\n }\n\n const current = getInstalledVersion(name);\n if (!current) {\n return null;\n }\n\n // All packages should update to master package version\n const hasUpdate = !!(masterLatest && current && semver.gt(masterLatest, current));\n\n return { name, current, latest: masterLatest, hasUpdate };\n });\n\n const checkResults = await Promise.all(checks);\n\n for (const result of checkResults) {\n if (result) {\n results.push(result);\n }\n }\n\n return results;\n}\n\n/**\n * Get packages that need updating\n */\nexport async function getOutdatedPackages(options: { forceCheckWorkspace?: boolean } = {}): Promise<PackageVersion[]> {\n const all = await checkForUpdates(options);\n const skipped = updaterCache.get('skippedVersions') || {};\n\n return all.filter(pkg => {\n if (!pkg.hasUpdate) return false;\n // Skip if user chose to skip this specific version\n if (skipped[pkg.name] === pkg.latest) return false;\n return true;\n });\n}\n\n/**\n * Create a simple spinner\n */\nfunction createSpinner(text: string) {\n let frameIndex = 0;\n let interval: NodeJS.Timeout | null = null;\n let currentText = text;\n\n const render = () => {\n const frame = SPINNER_FRAMES[frameIndex];\n process.stdout.write(`\\r${chalk.cyan(frame)} ${currentText}`);\n frameIndex = (frameIndex + 1) % SPINNER_FRAMES.length;\n };\n\n return {\n start() {\n if (process.stdout.isTTY) {\n interval = setInterval(render, 80);\n render();\n } else {\n console.log(` ${currentText}`);\n }\n return this;\n },\n text(newText: string) {\n currentText = newText;\n return this;\n },\n succeed(text?: string) {\n if (interval) clearInterval(interval);\n if (process.stdout.isTTY) {\n process.stdout.write(`\\r${chalk.green('✓')} ${text || currentText}\\n`);\n } else {\n console.log(` ${chalk.green('✓')} ${text || currentText}`);\n }\n return this;\n },\n fail(text?: string) {\n if (interval) clearInterval(interval);\n if (process.stdout.isTTY) {\n process.stdout.write(`\\r${chalk.red('✗')} ${text || currentText}\\n`);\n } else {\n console.log(` ${chalk.red('✗')} ${text || currentText}`);\n }\n return this;\n },\n stop() {\n if (interval) clearInterval(interval);\n if (process.stdout.isTTY) {\n process.stdout.write('\\r\\x1b[K');\n }\n return this;\n },\n };\n}\n\n/**\n * Ask user for confirmation\n */\nasync function askConfirmation(question: string): Promise<boolean> {\n if (isCI || !process.stdin.isTTY) {\n return false;\n }\n\n return new Promise((resolve) => {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n rl.question(question, (answer) => {\n rl.close();\n const normalized = answer.toLowerCase().trim();\n resolve(normalized === '' || normalized === 'y' || normalized === 'yes');\n });\n });\n}\n\n/**\n * Update a single package with progress\n */\nasync function updateSinglePackage(\n pkg: PackageVersion,\n pm: 'pnpm' | 'yarn' | 'npm',\n index: number,\n total: number\n): Promise<boolean> {\n const progress = `[${index + 1}/${total}]`;\n const versionInfo = `${chalk.red(pkg.current)} → ${chalk.green(pkg.latest)}`;\n const spinner = createSpinner(\n `${chalk.dim(progress)} Updating ${chalk.cyan(pkg.name)} ${versionInfo}`\n );\n\n spinner.start();\n\n // Always install with @latest to keep package.json consistent\n const command = pm === 'pnpm'\n ? `pnpm add ${pkg.name}@latest`\n : pm === 'yarn'\n ? `yarn add ${pkg.name}@latest`\n : `npm install ${pkg.name}@latest`;\n\n return new Promise((resolve) => {\n const proc = spawn(command, {\n shell: true,\n cwd: process.cwd(),\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n\n proc.on('close', (code) => {\n if (code === 0) {\n spinner.succeed(\n `${chalk.dim(progress)} ${chalk.cyan(pkg.name)} ${chalk.green(pkg.latest!)}`\n );\n resolve(true);\n } else {\n spinner.fail(\n `${chalk.dim(progress)} ${chalk.cyan(pkg.name)} ${chalk.red('failed')}`\n );\n resolve(false);\n }\n });\n\n proc.on('error', () => {\n spinner.fail(`${chalk.dim(progress)} ${chalk.cyan(pkg.name)} ${chalk.red('failed')}`);\n resolve(false);\n });\n });\n}\n\n/**\n * Update packages with progress\n */\nexport async function updatePackagesWithProgress(packages: PackageVersion[]): Promise<boolean> {\n if (packages.length === 0) return true;\n\n const pm = detectPackageManager();\n const total = packages.length;\n\n console.log('');\n console.log(chalk.bold(` Updating ${total} package${total > 1 ? 's' : ''}...`));\n console.log('');\n\n let successCount = 0;\n const failedPackages: string[] = [];\n\n for (let i = 0; i < packages.length; i++) {\n const success = await updateSinglePackage(packages[i], pm, i, total);\n if (success) {\n successCount++;\n } else {\n failedPackages.push(packages[i].name);\n }\n }\n\n console.log('');\n\n if (failedPackages.length === 0) {\n consola.success(`All ${total} packages updated successfully!`);\n return true;\n } else if (successCount > 0) {\n consola.warn(`${successCount}/${total} packages updated. Failed: ${failedPackages.join(', ')}`);\n return false;\n } else {\n consola.error(`Failed to update packages: ${failedPackages.join(', ')}`);\n return false;\n }\n}\n\n/**\n * Check and prompt for package updates\n */\nexport async function checkAndUpdatePackages(options: UpdateOptions = {}): Promise<boolean> {\n // Check cooldown\n const lastCheck = updaterCache.get('lastCheck') || 0;\n if (!options.force && (Date.now() - lastCheck) < UPDATE_CHECK_COOLDOWN_MS) {\n return true;\n }\n\n updaterCache.set('lastCheck', Date.now());\n\n // Check for updates\n const spinner = createSpinner('Checking for updates...');\n spinner.start();\n\n const outdated = await getOutdatedPackages({\n forceCheckWorkspace: options.forceCheckWorkspace,\n });\n\n spinner.stop();\n\n console.log(chalk.dim(` Found ${outdated.length} outdated package(s)`));\n\n if (outdated.length === 0) {\n console.log(chalk.green(' ✓ All packages are up to date'));\n return true;\n }\n\n // Auto-update if configured\n if (options.autoUpdate || updaterCache.get('autoUpdate')) {\n return updatePackagesWithProgress(outdated);\n }\n\n // Show outdated packages\n console.log('');\n consola.box('📦 Updates Available');\n console.log('');\n\n for (const pkg of outdated) {\n console.log(\n ` ${chalk.yellow('•')} ${chalk.bold(pkg.name)} ` +\n `${chalk.red(pkg.current)} → ${chalk.green(pkg.latest)}`\n );\n }\n console.log('');\n\n // Ask for confirmation\n const shouldUpdate = await askConfirmation(\n `${chalk.green('?')} Update these packages now? ${chalk.dim('[Y/n]')} `\n );\n\n if (shouldUpdate) {\n const success = await updatePackagesWithProgress(outdated);\n\n if (success) {\n const enableAuto = await askConfirmation(\n `${chalk.green('?')} Enable auto-update for future? ${chalk.dim('[y/N]')} `\n );\n if (enableAuto) {\n updaterCache.set('autoUpdate', true);\n consola.info('Auto-update enabled.');\n }\n }\n\n return success;\n }\n\n // User declined, ask if they want to skip these versions\n const skipVersions = await askConfirmation(\n `${chalk.green('?')} Skip these versions in future? ${chalk.dim('[y/N]')} `\n );\n\n if (skipVersions) {\n const skipped = updaterCache.get('skippedVersions') || {};\n for (const pkg of outdated) {\n if (pkg.latest) {\n skipped[pkg.name] = pkg.latest;\n }\n }\n updaterCache.set('skippedVersions', skipped);\n consola.info('Versions skipped. Will prompt again for newer versions.');\n }\n\n return false;\n}\n\n/**\n * Reset updater preferences\n */\nexport function resetUpdaterPreferences(): void {\n updaterCache.clear();\n consola.success('Updater preferences reset');\n}\n","/**\n * Version Checking Utilities\n */\n\nimport chalk from 'chalk';\nimport Conf from 'conf';\nimport consola from 'consola';\nimport semver from 'semver';\n\nimport { DJANGOCFG_PACKAGES, PACKAGE_NAME, VERSION_CACHE_TTL_MS } from '../constants';\n\n// Version cache using conf (stores in ~/.config/djangocfg-nextjs/)\nconst versionCache = new Conf<{\n latestVersion?: string;\n lastCheck?: number;\n}>({\n projectName: 'djangocfg-nextjs',\n projectVersion: '1.0.0',\n});\n\n/**\n * Get current package version from package.json\n */\nexport function getCurrentVersion(): string | null {\n try {\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const packageJson = require('../../../package.json');\n return packageJson.version || null;\n } catch {\n return null;\n }\n}\n\n/**\n * Fetch latest version from npm registry (with 1 hour caching via conf)\n */\nexport async function fetchLatestVersion(): Promise<string | null> {\n // Check cache first\n const lastCheck = versionCache.get('lastCheck') || 0;\n const cachedVersion = versionCache.get('latestVersion');\n\n if (cachedVersion && (Date.now() - lastCheck) < VERSION_CACHE_TTL_MS) {\n return cachedVersion;\n }\n\n // Fetch from npm registry\n try {\n const https = await import('https');\n return new Promise((resolve) => {\n const req = https.get(\n `https://registry.npmjs.org/${PACKAGE_NAME}/latest`,\n { timeout: 5000 },\n (res: any) => {\n let data = '';\n res.on('data', (chunk: string) => { data += chunk; });\n res.on('end', () => {\n try {\n const json = JSON.parse(data);\n const version = json.version || null;\n if (version) {\n versionCache.set('latestVersion', version);\n versionCache.set('lastCheck', Date.now());\n }\n resolve(version);\n } catch {\n resolve(cachedVersion || null);\n }\n });\n }\n );\n req.on('error', () => resolve(cachedVersion || null));\n req.on('timeout', () => { req.destroy(); resolve(cachedVersion || null); });\n });\n } catch {\n return cachedVersion || null;\n }\n}\n\n/**\n * Check if update is available\n */\nexport async function checkForUpdate(): Promise<{\n hasUpdate: boolean;\n currentVersion: string | null;\n latestVersion: string | null;\n}> {\n const currentVersion = getCurrentVersion();\n if (!currentVersion) {\n return { hasUpdate: false, currentVersion: null, latestVersion: null };\n }\n\n const latestVersion = await fetchLatestVersion();\n const hasUpdate = !!(latestVersion && semver.gt(latestVersion, currentVersion));\n\n return { hasUpdate, currentVersion, latestVersion };\n}\n\n/**\n * Get update command for all djangocfg packages\n */\nexport function getUpdateCommand(): string {\n return `pnpm add ${DJANGOCFG_PACKAGES.map(p => `${p}@latest`).join(' ')}`;\n}\n\n/**\n * Print version info and update notification\n */\nexport async function printVersionInfo(): Promise<void> {\n const { hasUpdate, currentVersion, latestVersion } = await checkForUpdate();\n\n if (!currentVersion) return;\n\n // Print current version\n consola.box(`📦 @djangocfg/nextjs v${currentVersion}`);\n\n // Show update notification if available\n if (hasUpdate && latestVersion) {\n consola.warn(`Update Available! ${chalk.red(currentVersion)} → ${chalk.green(latestVersion)}`);\n consola.info(`Run: ${chalk.cyan(getUpdateCommand())}`);\n console.log('');\n }\n}\n","/**\n * Deep Merge Utility\n *\n * Recursively merges objects, replacing arrays instead of merging them.\n */\n\nexport function deepMerge<T extends Record<string, any>>(target: T, source: Partial<T>): T {\n const output = { ...target };\n\n for (const key in source) {\n if (source[key] === undefined) continue;\n\n // Arrays: replace (don't merge arrays)\n if (Array.isArray(source[key])) {\n output[key] = source[key] as any;\n }\n // Objects: deep merge\n else if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) {\n const targetValue = output[key];\n if (targetValue && typeof targetValue === 'object' && !Array.isArray(targetValue)) {\n output[key] = deepMerge(targetValue, source[key] as any);\n } else {\n output[key] = source[key] as any;\n }\n }\n // Primitives: replace\n else {\n output[key] = source[key] as any;\n }\n }\n\n return output;\n}\n","/**\n * Base Next.js Configuration Factory\n *\n * Universal, reusable Next.js config for all DjangoCFG projects\n * Provides standard settings that can be extended per project\n *\n * @example\n * ```typescript\n * // In your project's next.config.ts\n * import { createBaseNextConfig } from '@djangocfg/nextjs/config';\n * import bundleAnalyzer from '@next/bundle-analyzer';\n *\n * const withBundleAnalyzer = bundleAnalyzer({\n * enabled: process.env.ANALYZE === 'true',\n * });\n *\n * export default withBundleAnalyzer(createBaseNextConfig({\n * // Your project-specific overrides\n * transpilePackages: ['my-custom-package'],\n * }));\n * ```\n */\n\nimport type { NextConfig } from 'next';\nimport type { Configuration as WebpackConfig } from 'webpack';\n\nimport { type PWAPluginOptions, withPWA } from '../pwa/plugin';\nimport { DEFAULT_OPTIMIZE_PACKAGES, DEFAULT_TRANSPILE_PACKAGES } from './constants';\nimport { addCompressionPlugins } from './plugins/compression';\nimport { DevStartupPlugin } from './plugins/devStartup';\nimport { deepMerge } from './utils/deepMerge';\nimport { getApiUrl, getBasePath, getSiteUrl, isDev, isStaticBuild } from './utils/env';\n\n// ─────────────────────────────────────────────────────────────────────────\n// Configuration Options\n// ─────────────────────────────────────────────────────────────────────────\n\nexport interface BaseNextConfigOptions {\n /** Static build path (used when NEXT_PUBLIC_STATIC_BUILD=true) */\n isDefaultCfgAdmin?: boolean;\n /** Additional transpile packages (merged with defaults) */\n transpilePackages?: string[];\n /** Additional optimize package imports (merged with defaults) */\n optimizePackageImports?: string[];\n /** Check for @djangocfg/* package updates on startup (default: true) */\n checkUpdates?: boolean;\n /** Auto-update outdated packages without prompting (default: false) */\n autoUpdate?: boolean;\n /** Force check workspace:* packages for updates (for testing in monorepo) */\n forceCheckWorkspace?: boolean;\n /** Check for missing optional packages on startup (default: true) */\n checkPackages?: boolean;\n /** Auto-install missing packages without prompting (default: false) */\n autoInstall?: boolean;\n /**\n * Allow embedding this app in iframe from specified origins\n * Set to ['*'] to allow all origins, or specify domains like ['https://djangocfg.com']\n */\n allowIframeFrom?: string[];\n /**\n * PWA configuration options\n * Set to false to disable PWA, or provide custom options\n * @default { enabled: true (in production), disable: true (in development) }\n */\n pwa?: PWAPluginOptions | false;\n /** Turbopack configuration (Next.js 16+ default bundler) */\n turbopack?: NextConfig['turbopack'];\n /** Custom webpack configuration function (called after base webpack logic) */\n webpack?: (\n config: WebpackConfig,\n options: { isServer: boolean; dev: boolean; [key: string]: any }\n ) => WebpackConfig | void;\n /** Custom experimental options (merged with defaults) */\n experimental?: NextConfig['experimental'];\n /** Custom env variables (merged with defaults) */\n env?: Record<string, string | undefined>;\n /** Additional redirects (merged with base URL normalization redirects) */\n redirects?: NextConfig['redirects'];\n /** Additional headers (merged with base CORS/security headers) */\n headers?: NextConfig['headers'];\n /** Additional rewrites */\n rewrites?: NextConfig['rewrites'];\n /** Override any Next.js config option */\n [key: string]: any;\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Base Configuration Factory\n// ─────────────────────────────────────────────────────────────────────────\n\n/**\n * Create base Next.js configuration with standard DjangoCFG settings\n *\n * @param options - Custom configuration options to merge with base config\n * @returns Next.js configuration function\n */\nexport function createBaseNextConfig(\n options: BaseNextConfigOptions = {}\n): NextConfig {\n\n const basePath = getBasePath(options.isDefaultCfgAdmin);\n const apiUrl = getApiUrl();\n const siteUrl = getSiteUrl();\n\n // Base configuration\n const baseConfig: NextConfig = {\n reactStrictMode: true,\n trailingSlash: true,\n\n // Static export configuration\n ...(isStaticBuild && {\n output: 'export' as const,\n distDir: 'out',\n basePath: basePath,\n // Fix for Next.js 15.5.4: prevent 500.html generation issue\n generateBuildId: async () => {\n return 'static-build';\n },\n }),\n\n // Standalone output for Docker (only in production, not dev)\n ...(!isStaticBuild && !isDev && {\n output: 'standalone' as const,\n }),\n\n // Environment variables\n env: {\n NEXT_PUBLIC_BASE_PATH: basePath,\n NEXT_PUBLIC_API_URL: apiUrl,\n NEXT_PUBLIC_SITE_URL: siteUrl,\n // Disable Next.js telemetry (Next.js 15+ uses env var instead of config option)\n NEXT_TELEMETRY_DISABLED: '1',\n ...options.env,\n },\n\n // Images configuration\n images: {\n unoptimized: true,\n },\n\n // CORS headers for static files and iframe embedding\n async headers() {\n const headers: { source: string; headers: { key: string; value: string }[] }[] = [\n {\n source: '/static/:path*',\n headers: [\n { key: 'Access-Control-Allow-Origin', value: '*' },\n { key: 'Access-Control-Allow-Methods', value: 'GET, OPTIONS' },\n { key: 'Access-Control-Allow-Headers', value: 'Origin, Content-Type, Accept' },\n ],\n },\n ];\n\n // Add iframe embedding headers if allowIframeFrom is specified\n if (options.allowIframeFrom && options.allowIframeFrom.length > 0) {\n const frameAncestors = options.allowIframeFrom.includes('*')\n ? '*'\n : `'self' ${options.allowIframeFrom.join(' ')}`;\n\n headers.push({\n source: '/:path*',\n headers: [\n // Content-Security-Policy frame-ancestors directive\n { key: 'Content-Security-Policy', value: `frame-ancestors ${frameAncestors}` },\n // X-Frame-Options for older browsers (ALLOW-FROM is deprecated, use CSP instead)\n // Only set SAMEORIGIN if allowing all, otherwise browsers will use CSP\n ...(options.allowIframeFrom.includes('*')\n ? []\n : [{ key: 'X-Frame-Options', value: 'SAMEORIGIN' }]\n ),\n ],\n });\n }\n\n // Merge with user-provided headers\n const userHeaders = options.headers ? await options.headers() : [];\n return [...headers, ...userHeaders];\n },\n\n // Rewrites (user-provided only)\n ...(options.rewrites && {\n rewrites: options.rewrites,\n }),\n\n // Redirects for URL normalization\n // Fixes \"Failed to construct 'URL': Invalid URL\" error with double slashes\n async redirects() {\n const baseRedirects = [\n // Normalize double slashes in URL path (e.g., /foo//bar -> /foo/bar)\n {\n source: '/:path*(//)/:rest*',\n destination: '/:path*/:rest*',\n permanent: true,\n },\n // Handle root double slash (e.g., // -> /)\n {\n source: '//',\n destination: '/',\n permanent: true,\n },\n ];\n\n // Merge with user-provided redirects\n const userRedirects = options.redirects ? await options.redirects() : [];\n return [...baseRedirects, ...userRedirects];\n },\n\n // Transpile packages (merge with user-provided)\n transpilePackages: [\n ...DEFAULT_TRANSPILE_PACKAGES,\n ...(options.transpilePackages || []),\n ],\n\n // Turbopack configuration (Next.js 16+ default bundler)\n // Always set turbopack config to silence Next.js 16 warning about webpack config\n turbopack: options.turbopack || {},\n\n // Experimental features\n experimental: {\n // Optimize package imports (only in production)\n ...(!isDev && {\n optimizePackageImports: [\n ...DEFAULT_OPTIMIZE_PACKAGES,\n ...(options.optimizePackageImports || []),\n ],\n }),\n // Dev mode optimizations\n ...(isDev && {\n optimizeCss: false,\n }),\n // User experimental options applied last (can override base settings)\n ...options.experimental,\n },\n\n // Webpack configuration\n webpack: (config: WebpackConfig, webpackOptions: { isServer: boolean; dev: boolean; [key: string]: any }) => {\n const { isServer, dev } = webpackOptions;\n\n // Add dev startup plugin (client-side only in dev)\n if (dev && !isServer) {\n if (!config.plugins) {\n config.plugins = [];\n }\n config.plugins.push(\n new DevStartupPlugin({\n checkUpdates: options.checkUpdates,\n autoUpdate: options.autoUpdate,\n forceCheckWorkspace: options.forceCheckWorkspace,\n checkPackages: options.checkPackages,\n autoInstall: options.autoInstall,\n })\n );\n }\n\n // Dev mode optimizations\n if (dev) {\n config.optimization = {\n ...config.optimization,\n removeAvailableModules: false,\n removeEmptyChunks: false,\n splitChunks: false, // Disable code splitting in dev for faster compilation\n };\n }\n\n // Filesystem cache (dev and production)\n config.cache = {\n type: 'filesystem',\n buildDependencies: {},\n };\n\n // Compression plugins (only for static build in production, client-side)\n if (!isServer && isStaticBuild && !dev) {\n addCompressionPlugins(config);\n }\n\n // Call user's webpack function if provided\n if (options.webpack) {\n return options.webpack(config, webpackOptions);\n }\n\n return config;\n },\n };\n\n // Deep merge user options with base config\n let finalConfig = deepMerge(baseConfig, options);\n\n // Cleanup: Remove custom options that are not part of NextConfig\n delete (finalConfig as any).optimizePackageImports;\n delete (finalConfig as any).isDefaultCfgAdmin;\n delete (finalConfig as any).checkUpdates;\n delete (finalConfig as any).autoUpdate;\n delete (finalConfig as any).forceCheckWorkspace;\n delete (finalConfig as any).checkPackages;\n delete (finalConfig as any).autoInstall;\n delete (finalConfig as any).allowIframeFrom;\n delete (finalConfig as any).openBrowser;\n // Note: turbopack is a valid NextConfig option, don't delete it\n\n // Apply PWA wrapper only if explicitly configured (opt-in)\n // PWA requires sw.ts file in the app, so apps must explicitly enable it\n if (options.pwa) {\n finalConfig = withPWA(finalConfig, options.pwa);\n }\n delete (finalConfig as any).pwa;\n\n return finalConfig;\n}\n","/**\n * DjangoCFG Documentation Client\n *\n * HTTP client for accessing DjangoCFG documentation via MCP server API.\n */\n\nimport { API_INFO_ENDPOINT, API_SEARCH_ENDPOINT, DEFAULT_TIMEOUT, MCP_BASE_URL } from './constants';\n\nimport type { SearchResult, SearchOptions, McpConfig, ApiSearchResponse } from './types';\n\n/**\n * Client for DjangoCFG Documentation API.\n */\nexport class DjangoCfgDocsClient {\n private baseUrl: string;\n private timeout: number;\n\n constructor(baseUrl: string = MCP_BASE_URL, timeout: number = DEFAULT_TIMEOUT) {\n this.baseUrl = baseUrl.replace(/\\/$/, '');\n this.timeout = timeout;\n }\n\n private async makeRequest<T>(endpoint: string, params?: Record<string, string | number>): Promise<T> {\n let url = `${this.baseUrl}${endpoint}`;\n\n if (params) {\n const searchParams = new URLSearchParams();\n for (const [key, value] of Object.entries(params)) {\n searchParams.set(key, String(value));\n }\n url = `${url}?${searchParams.toString()}`;\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n 'User-Agent': 'DjangoCFG-AI-Client/1.0',\n },\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP Error ${response.status}: ${response.statusText}`);\n }\n\n return await response.json();\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * Search documentation.\n */\n async search(query: string, options: SearchOptions = {}): Promise<SearchResult[]> {\n const { limit = 5, category } = options;\n\n const params: Record<string, string | number> = { q: query, limit };\n if (category) {\n params.category = category;\n }\n\n const data = await this.makeRequest<ApiSearchResponse>(API_SEARCH_ENDPOINT, params);\n\n const results = data.results || (Array.isArray(data) ? data : []);\n\n return results.map((item) => ({\n title: item.title || '',\n content: item.content || item.snippet || '',\n url: item.url || '',\n score: item.score || 0,\n category: item.category || '',\n }));\n }\n\n /**\n * Get detailed info about a specific topic.\n */\n async getInfo(topic: string): Promise<Record<string, unknown>> {\n return this.makeRequest(API_INFO_ENDPOINT, { topic });\n }\n\n /**\n * Get MCP server configuration for AI assistants.\n */\n getMcpConfig(): McpConfig {\n return {\n mcpServers: {\n 'djangocfg-docs': {\n url: `${this.baseUrl}/mcp`,\n },\n },\n };\n }\n}\n\n// Default client instance\nlet defaultClient: DjangoCfgDocsClient | null = null;\n\nfunction getClient(): DjangoCfgDocsClient {\n if (!defaultClient) {\n defaultClient = new DjangoCfgDocsClient();\n }\n return defaultClient;\n}\n\n/**\n * Search DjangoCFG documentation.\n *\n * @example\n * ```ts\n * const results = await search('database configuration');\n * results.forEach(r => console.log(r.title, r.url));\n * ```\n */\nexport async function search(query: string, options: SearchOptions = {}): Promise<SearchResult[]> {\n return getClient().search(query, options);\n}\n\n/**\n * Get documentation as formatted text.\n *\n * @example\n * ```ts\n * const docs = await getDocs('How to configure PostgreSQL?');\n * console.log(docs);\n * ```\n */\nexport async function getDocs(query: string, limit: number = 3): Promise<string> {\n const results = await search(query, { limit });\n\n if (results.length === 0) {\n return `No documentation found for: ${query}`;\n }\n\n const output: string[] = [];\n\n results.forEach((r, i) => {\n output.push(`## ${i + 1}. ${r.title}`);\n output.push(r.content);\n if (r.url) {\n output.push(`📖 Read more: ${r.url}`);\n }\n output.push('');\n });\n\n return output.join('\\n');\n}\n\n/**\n * Get detailed info about a topic.\n */\nexport async function getInfo(topic: string): Promise<Record<string, unknown>> {\n return getClient().getInfo(topic);\n}\n\n/**\n * Get MCP server configuration.\n */\nexport function getMcpConfig(): McpConfig {\n return getClient().getMcpConfig();\n}\n"],"mappings":";;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA,MACE,MAAQ;AAAA,MACR,SAAW;AAAA,MACX,aAAe;AAAA,MACf,UAAY;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,QAAU;AAAA,QACR,MAAQ;AAAA,QACR,KAAO;AAAA,MACT;AAAA,MACA,UAAY;AAAA,MACZ,YAAc;AAAA,QACZ,MAAQ;AAAA,QACR,KAAO;AAAA,QACP,WAAa;AAAA,MACf;AAAA,MACA,MAAQ;AAAA,QACN,KAAO;AAAA,MACT;AAAA,MACA,SAAW;AAAA,MACX,MAAQ;AAAA,MACR,OAAS;AAAA,MACT,SAAW;AAAA,QACT,KAAK;AAAA,UACH,OAAS;AAAA,UACT,QAAU;AAAA,UACV,SAAW;AAAA,QACb;AAAA,QACA,aAAa;AAAA,UACX,OAAS;AAAA,UACT,QAAU;AAAA,UACV,SAAW;AAAA,QACb;AAAA,QACA,YAAY;AAAA,UACV,OAAS;AAAA,UACT,QAAU;AAAA,UACV,SAAW;AAAA,QACb;AAAA,QACA,cAAc;AAAA,UACZ,OAAS;AAAA,UACT,QAAU;AAAA,UACV,SAAW;AAAA,QACb;AAAA,QACA,oBAAoB;AAAA,UAClB,OAAS;AAAA,UACT,QAAU;AAAA,UACV,SAAW;AAAA,QACb;AAAA,QACA,yBAAyB;AAAA,UACvB,OAAS;AAAA,UACT,QAAU;AAAA,UACV,SAAW;AAAA,QACb;AAAA,QACA,gBAAgB;AAAA,UACd,OAAS;AAAA,UACT,QAAU;AAAA,UACV,SAAW;AAAA,QACb;AAAA,QACA,YAAY;AAAA,UACV,OAAS;AAAA,UACT,QAAU;AAAA,UACV,SAAW;AAAA,QACb;AAAA,QACA,QAAQ;AAAA,UACN,OAAS;AAAA,UACT,QAAU;AAAA,UACV,SAAW;AAAA,QACb;AAAA,QACA,SAAS;AAAA,UACP,OAAS;AAAA,UACT,QAAU;AAAA,UACV,SAAW;AAAA,QACb;AAAA,QACA,gBAAgB;AAAA,UACd,OAAS;AAAA,UACT,QAAU;AAAA,UACV,SAAW;AAAA,QACb;AAAA,QACA,YAAY;AAAA,UACV,OAAS;AAAA,UACT,QAAU;AAAA,UACV,SAAW;AAAA,QACb;AAAA,QACA,gBAAgB;AAAA,UACd,OAAS;AAAA,UACT,QAAU;AAAA,UACV,SAAW;AAAA,QACb;AAAA,QACA,uBAAuB;AAAA,UACrB,OAAS;AAAA,UACT,QAAU;AAAA,UACV,SAAW;AAAA,QACb;AAAA,MACF;AAAA,MACA,OAAS;AAAA,QACP;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,KAAO;AAAA,QACL,kBAAkB;AAAA,QAClB,iBAAiB;AAAA,MACnB;AAAA,MACA,SAAW;AAAA,QACT,OAAS;AAAA,QACT,KAAO;AAAA,QACP,OAAS;AAAA,QACT,MAAQ;AAAA,QACR,OAAS;AAAA,QACT,WAAW;AAAA,QACX,KAAO;AAAA,MACT;AAAA,MACA,kBAAoB;AAAA,QAClB,MAAQ;AAAA,MACV;AAAA,MACA,cAAgB;AAAA,QACd,iBAAiB;AAAA,QACjB,eAAe;AAAA,QACf,OAAS;AAAA,QACT,MAAQ;AAAA,QACR,SAAW;AAAA,QACX,QAAU;AAAA,QACV,SAAW;AAAA,QACX,YAAY;AAAA,MACd;AAAA,MACA,iBAAmB;AAAA,QACjB,oBAAoB;AAAA,QACpB,sBAAsB;AAAA,QACtB,gCAAgC;AAAA,QAChC,eAAe;AAAA,QACf,gBAAgB;AAAA,QAChB,oBAAoB;AAAA,QACpB,iBAAiB;AAAA,QACjB,mBAAmB;AAAA,QACnB,kBAAkB;AAAA,QAClB,cAAc;AAAA,QACd,QAAU;AAAA,QACV,gBAAgB;AAAA,QAChB,MAAQ;AAAA,QACR,KAAO;AAAA,QACP,YAAc;AAAA,MAChB;AAAA,MACA,eAAiB;AAAA,QACf,QAAU;AAAA,MACZ;AAAA,IACF;AAAA;AAAA;;;AC9HA,SAAS,oBAAoB;;;ACjBtB,SAAS,mBAAmB,MAA4B;AAC7D,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA,EAKP,KACC;AAAA,IACC,CAAC,EAAE,KAAK,SAAS,YAAY,SAAS,MAAM;AAAA,WACrC,UAAU,GAAG,CAAC;AAAA,MACnB,UAAU,YAAY,WAAW,OAAO,CAAC,eAAe,EAAE;AAAA,MAC1D,aAAa,eAAe,UAAU,kBAAkB,EAAE;AAAA,MAC1D,aAAa,SAAY,aAAa,SAAS,QAAQ,CAAC,CAAC,gBAAgB,EAAE;AAAA;AAAA,EAE/E,EACC,KAAK,IAAI,CAAC;AAAA;AAEb;AAKA,SAAS,WAAW,MAA6B;AAC/C,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO;AAAA,EACT;AACA,SAAO,KAAK,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AACxC;AAKA,SAAS,UAAU,QAAwB;AACzC,SAAO,OACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ,EACtB,QAAQ,MAAM,QAAQ;AAC3B;AAKO,SAAS,aAAa,KAAa,SAAyB;AACjE,MAAI,IAAI,WAAW,SAAS,KAAK,IAAI,WAAW,UAAU,GAAG;AAC3D,WAAO;AAAA,EACT;AACA,QAAM,UAAU,QAAQ,SAAS,GAAG,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI;AAC/D,QAAM,OAAO,IAAI,WAAW,GAAG,IAAI,MAAM,IAAI,GAAG;AAChD,SAAO,GAAG,OAAO,GAAG,IAAI;AAC1B;;;AD3BO,SAAS,qBAAqB,SAAkC;AACrE,QAAM;AAAA,IACJ;AAAA,IACA,cAAc,CAAC;AAAA,IACf,eAAe,CAAC;AAAA,IAChB,eAAe;AAAA,EACjB,IAAI;AAEJ,SAAO,eAAe,MAAM;AAC1B,UAAM,OAAqB,CAAC,GAAG,WAAW;AAG1C,QAAI,cAAc;AAChB,UAAI,OAAO,iBAAiB,YAAY;AACtC,cAAM,cAAc,MAAM,aAAa;AACvC,aAAK,KAAK,GAAG,WAAW;AAAA,MAC1B,OAAO;AACL,aAAK,KAAK,GAAG,YAAY;AAAA,MAC3B;AAAA,IACF;AAGA,UAAM,iBAAiB,KAAK,IAAI,CAAC,SAAS;AAAA,MACxC,GAAG;AAAA,MACH,KAAK,aAAa,IAAI,KAAK,OAAO;AAAA,IACpC,EAAE;AAGF,UAAM,UAAU,mBAAmB,cAAc;AAGjD,WAAO,IAAI,aAAa,SAAS;AAAA,MAC/B,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,iBAAiB;AAAA,MACnB;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AEnDA,SAAS,gBAAAA,qBAAoB;AAItB,SAAS,oBAAoB,SAAuB,CAAC,GAAG;AAC7D,QAAM,EAAE,SAAS,SAAS,CAAC,GAAG,aAAa,CAAC,EAAE,IAAI;AAElD,SAAO,eAAe,MAAM;AAC1B,UAAM,YAAY,KAAK,IAAI;AAC3B,QAAI,SAAyB;AAC7B,UAAM,eAAwC,CAAC;AAG/C,QAAI,OAAO,SAAS,GAAG;AACrB,iBAAW,SAAS,QAAQ;AAC1B,YAAI;AACF,gBAAM,SAAS,MAAM,MAAM,MAAM;AACjC,uBAAa,MAAM,IAAI,IAAI;AAC3B,cAAI,CAAC,QAAQ;AACX,qBAAS;AAAA,UACX;AAAA,QACF,SAAS,OAAO;AACd,uBAAa,MAAM,IAAI,IAAI;AAC3B,mBAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAEA,UAAM,WAA2B;AAAA,MAC/B;AAAA,MACA,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,QAAQ,QAAQ,OAAO;AAAA,MACvB,GAAI,WAAW,EAAE,QAAQ;AAAA,MACzB,GAAI,OAAO,KAAK,YAAY,EAAE,SAAS,KAAK,EAAE,QAAQ,aAAa;AAAA,MACnE,GAAG;AAAA,IACL;AAEA,UAAM,aAAa,WAAW,OAAO,MAAM;AAE3C,WAAOA,cAAa,KAAK,UAAU,EAAE,QAAQ,WAAW,CAAC;AAAA,EAC3D;AACF;;;AC3CA,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;;;ACuCxB,cAqCI,YArCJ;AAxCG,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA,WAAW;AAAA,EACX,eAAe;AAAA;AAAA,EAEf,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,kBAAkB;AAAA;AAAA,EAElB;AAAA,EACA,cAAc;AAAA,EACd,aAAa;AAAA;AAAA,EAEb,kBAAkB;AAAA,EAClB,mBAAmB;AAAA;AAAA,EAEnB,eAAe;AAAA,EACf,gBAAgB;AAAA;AAAA,EAEhB,UAAU;AAAA,EACV,WAAW;AAAA;AAAA,EAEX,UAAU;AACZ,GAAuC;AAErC,QAAM,sBAAsB,cAAc,MAAM,SAAS,KAAK,KAAK;AAGnE,QAAM,kBACJ,mBAAmB,aACf,2BAA2B,aAAa,QAAQ,WAAW,WAC3D;AAGN,QAAM,cAAc,UAClB;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,UAAU;AAAA,QACV,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,iBAAiB;AAAA;AAAA;AAAA;AAAA,QAIjB,gBAAgB;AAAA,QAChB,eAAe;AAAA,QACf,QAAQ;AAAA,MACV;AAAA;AAAA,EACF,IACE;AAEJ,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,SAAS;AAAA,QACT,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,YAAY;AAAA,QACZ,SAAS,GAAG,OAAO;AAAA,QACnB,YAAY;AAAA,QACZ,UAAU;AAAA,MACZ;AAAA,MAEC;AAAA;AAAA,SAGE,YAAY,QAAU,gBAAgB,aACvC;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,KAAK;AAAA,YACP;AAAA,YAEC;AAAA,0BAAY;AAAA,cAEX;AAAA,gBAAC;AAAA;AAAA,kBACC,KAAK;AAAA,kBACL,KAAI;AAAA,kBACJ,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,OAAO;AAAA,oBACL,cAAc;AAAA,kBAChB;AAAA;AAAA,cACF;AAAA,cAED,gBAAgB,YACf;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,UAAU;AAAA,oBACV,YAAY;AAAA,oBACZ,OAAO;AAAA,oBACP,eAAe;AAAA,kBACjB;AAAA,kBAEC;AAAA;AAAA,cACH;AAAA;AAAA;AAAA,QAEJ;AAAA,QAIF;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,eAAe;AAAA,cACf,KAAK;AAAA,cACL,MAAM;AAAA,cACN,gBAAgB;AAAA,YAClB;AAAA,YAGA;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,UAAU;AAAA,oBACV,YAAY;AAAA,oBACZ,OAAO;AAAA,oBACP,YAAY;AAAA,oBACZ,eAAe;AAAA,oBACf,YAAY,mBAAmB,aAAa,kCAAkC;AAAA,oBAC9E,UAAU;AAAA,oBACV,UAAU;AAAA,kBACZ;AAAA,kBAEC;AAAA;AAAA,cACH;AAAA,cAGC,eACC;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,UAAU;AAAA,oBACV,YAAY;AAAA,oBACZ,OAAO;AAAA,oBACP,YAAY;AAAA,oBACZ,eAAe;AAAA,oBACf,UAAU;AAAA,oBACV,SAAS;AAAA,oBACT,iBAAiB;AAAA,oBACjB,iBAAiB;AAAA,oBACjB,UAAU;AAAA,kBACZ;AAAA,kBAEC;AAAA;AAAA,cACH;AAAA;AAAA;AAAA,QAEJ;AAAA,QAGA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,YAAY,mBAAmB,aAC3B,0BAA0B,aAAa,QAAQ,WAAW,WAC1D;AAAA,cACJ,cAAc;AAAA,YAChB;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;AAOO,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA,WAAW;AAAA,EACX,eAAe;AAAA;AAAA,EAEf,iBAAiB;AAAA,EACjB,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,kBAAkB;AAAA;AAAA,EAElB;AAAA,EACA,cAAc;AAAA,EACd,aAAa;AAAA;AAAA,EAEb,kBAAkB;AAAA,EAClB,mBAAmB;AAAA;AAAA,EAEnB,eAAe;AAAA,EACf,gBAAgB;AAAA;AAAA,EAEhB,UAAU;AAAA,EACV,WAAW;AAAA;AAAA,EAEX,UAAU;AACZ,GAAuC;AAErC,QAAM,sBAAsB,cAAc,MAAM,SAAS,KAAK,KAAK;AAGnE,QAAM,kBACJ,mBAAmB,aACf,2BAA2B,aAAa,QAAQ,WAAW,WAC3D;AAGN,QAAM,cAAc,UAClB;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,UAAU;AAAA,QACV,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,iBAAiB;AAAA;AAAA;AAAA;AAAA,QAIjB,gBAAgB;AAAA,QAChB,eAAe;AAAA,QACf,QAAQ;AAAA,MACV;AAAA;AAAA,EACF,IACE;AAEJ,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,SAAS;AAAA,QACT,eAAe;AAAA,QACf,YAAY;AAAA,QACZ,gBAAgB;AAAA,QAChB,YAAY;AAAA,QACZ,SAAS,GAAG,OAAO;AAAA,QACnB,YAAY;AAAA,QACZ,UAAU;AAAA,MACZ;AAAA,MAEC;AAAA;AAAA,SAGE,YAAY,QAAU,gBAAgB,aACvC;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,KAAK;AAAA,YACP;AAAA,YAEC;AAAA,0BAAY;AAAA,cAEX;AAAA,gBAAC;AAAA;AAAA,kBACC,KAAK;AAAA,kBACL,KAAI;AAAA,kBACJ,OAAO;AAAA,kBACP,QAAQ;AAAA,kBACR,OAAO;AAAA,oBACL,cAAc;AAAA,kBAChB;AAAA;AAAA,cACF;AAAA,cAED,gBAAgB,YACf;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,UAAU;AAAA,oBACV,YAAY;AAAA,oBACZ,OAAO;AAAA,oBACP,eAAe;AAAA,kBACjB;AAAA,kBAEC;AAAA;AAAA,cACH;AAAA;AAAA;AAAA,QAEJ;AAAA,QAIF;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,eAAe;AAAA,cACf,KAAK;AAAA,cACL,MAAM;AAAA,cACN,gBAAgB;AAAA,YAClB;AAAA,YAGA;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,UAAU;AAAA,oBACV,YAAY;AAAA,oBACZ,OAAO;AAAA,oBACP,YAAY;AAAA,oBACZ,eAAe;AAAA,oBACf,UAAU;AAAA,oBACV,UAAU;AAAA,kBACZ;AAAA,kBAEC;AAAA;AAAA,cACH;AAAA,cAGC,eACC;AAAA,gBAAC;AAAA;AAAA,kBACC,OAAO;AAAA,oBACL,UAAU;AAAA,oBACV,YAAY;AAAA,oBACZ,OAAO;AAAA,oBACP,YAAY;AAAA,oBACZ,eAAe;AAAA,oBACf,UAAU;AAAA,kBACZ;AAAA,kBAEC;AAAA;AAAA,cACH;AAAA;AAAA;AAAA,QAEJ;AAAA,QAGA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,cACL,SAAS;AAAA,cACT,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,YAAY,mBAAmB,aAC3B,0BAA0B,aAAa,QAAQ,WAAW,WAC1D;AAAA,cACJ,cAAc;AAAA,YAChB;AAAA;AAAA,QACF;AAAA;AAAA;AAAA,EACF;AAEJ;;;ACtVA,eAAsB,eACpB,MACA,MACA,SAAiB,KACK;AAEtB,MAAI,MAAM,4CAA4C,IAAI,SAAS,MAAM;AAGzE,MAAI,MAAM;AACR,WAAO,SAAS,mBAAmB,IAAI,CAAC;AAAA,EAC1C;AAEA,MAAI;AAEF,UAAM,MAAM,MAAM,MAAM,KAAK;AAAA,MAC3B,SAAS;AAAA;AAAA,QAEP,cACE;AAAA,MACJ;AAAA,IACF,CAAC,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC;AAG3B,UAAM,WAAW,IAAI,MAAM,kDAAkD;AAE7E,QAAI,CAAC,YAAY,CAAC,SAAS,CAAC,GAAG;AAC7B,YAAM,IAAI,MAAM,+CAA+C,IAAI,EAAE;AAAA,IACvE;AAGA,UAAM,WAAW,MAAM,MAAM,SAAS,CAAC,CAAC;AAExC,QAAI,SAAS,WAAW,KAAK;AAC3B,YAAM,IAAI,MAAM,mCAAmC,SAAS,MAAM,EAAE;AAAA,IACtE;AAEA,WAAO,MAAM,SAAS,YAAY;AAAA,EACpC,SAAS,OAAO;AACd,YAAQ,MAAM,8BAA8B,IAAI,MAAM,KAAK;AAC3D,UAAM,IAAI,MAAM,wBAAwB,IAAI,MAAM,iBAAiB,QAAQ,MAAM,UAAU,eAAe,EAAE;AAAA,EAC9G;AACF;AAcA,eAAsB,gBACpB,OAMuB;AACvB,QAAM,cAAc,MAAM,QAAQ;AAAA,IAChC,MAAM,IAAI,OAAO,EAAE,QAAQ,SAAS,KAAK,QAAQ,UAAU,KAAK,MAAM;AACpE,YAAM,OAAO,MAAM,eAAe,QAAQ,MAAM,MAAM;AACtD,aAAO;AAAA,QACL,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAWO,SAAS,mBAAmB;AACjC,QAAM,QAAQ,oBAAI,IAAkC;AAEpD,SAAO;AAAA;AAAA;AAAA;AAAA,IAIL,MAAM,KACJ,QACA,SAAiB,KACjB,MACsB;AACtB,YAAM,WAAW,GAAG,MAAM,IAAI,MAAM,IAAI,QAAQ,KAAK;AAErD,UAAI,CAAC,MAAM,IAAI,QAAQ,GAAG;AACxB,cAAM,IAAI,UAAU,eAAe,QAAQ,MAAM,MAAM,CAAC;AAAA,MAC1D;AAEA,aAAO,MAAM,IAAI,QAAQ;AAAA,IAC3B;AAAA;AAAA;AAAA;AAAA,IAKA,QAAQ;AACN,YAAM,MAAM;AAAA,IACd;AAAA;AAAA;AAAA;AAAA,IAKA,OAAO;AACL,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AACF;;;AC7IA,IAAM,4BAA4B;AAMlC,SAAS,aAAa,KAAqB;AAEzC,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,OAAO,KAAK,KAAK,OAAO,EAAE,SAAS,QAAQ;AAAA,EACpD;AAEA,SAAO,KAAK,SAAS,mBAAmB,GAAG,CAAC,CAAC;AAC/C;AAMA,SAAS,aAAa,KAAqB;AAEzC,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,OAAO,KAAK,KAAK,QAAQ,EAAE,SAAS,OAAO;AAAA,EACpD;AAGA,MAAI;AACF,UAAM,eAAe,KAAK,GAAG;AAE7B,WAAO;AAAA,MACL,aACG,MAAM,EAAE,EACR,IAAI,CAAC,MAAM,OAAO,OAAO,EAAE,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,MAAM,EAAE,CAAC,EAChE,KAAK,EAAE;AAAA,IACZ;AAAA,EACF,SAAS,OAAO;AAEd,WAAO,mBAAmB,OAAO,KAAK,GAAG,CAAC,CAAC;AAAA,EAC7C;AACF;AAuFO,SAAS,mBACd,QACA,UAAqC,CAAC,GAC9B;AACR,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,YAAY;AAAA,EACd,IAAI;AAEJ,MAAI,WAAW;AAEb,UAAM,cAAyD,CAAC;AAChE,WAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAC/C,UAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,IAAI;AACzD,oBAAY,GAAG,IAAI;AAAA,MACrB;AAAA,IACF,CAAC;AAGD,UAAM,aAAa,KAAK,UAAU,WAAW;AAC7C,UAAM,aAAa,aAAa,UAAU;AAM1C,WAAO,GAAG,OAAO,IAAI,UAAU;AAAA,EACjC,OAAO;AAEL,UAAM,eAAe,IAAI,gBAAgB;AAGzC,WAAO,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,KAAK,KAAK,MAAM;AAC/C,UAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,IAAI;AACzD,qBAAa,OAAO,KAAK,OAAO,KAAK,CAAC;AAAA,MACxC;AAAA,IACF,CAAC;AAED,UAAM,QAAQ,aAAa,SAAS;AACpC,WAAO,QAAQ,GAAG,OAAO,IAAI,KAAK,KAAK;AAAA,EACzC;AACF;AAoBO,SAAS,sBACd,cACA,SACQ;AAER,MAAI,aAAa,WAAW,SAAS,KAAK,aAAa,WAAW,UAAU,GAAG;AAC7E,WAAO;AAAA,EACT;AAGA,QAAM,eAAe,QAAQ,QAAQ,OAAO,EAAE;AAG9C,QAAM,YAAY,aAAa,WAAW,GAAG,IACzC,eACA,IAAI,YAAY;AAEpB,SAAO,GAAG,YAAY,GAAG,SAAS;AACpC;AAsBO,SAAS,wBACd,WAAsC,CAAC,GACvC,UAAqC,CAAC,GACtC;AACA,SAAO,CAAC,WAAqC;AAC3C,WAAO;AAAA,MACL,EAAE,GAAG,UAAU,GAAG,OAAO;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AACF;AAcO,SAAS,gBAAgB,KAAqC;AACnE,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,KAAK,kBAAkB;AAC9C,UAAM,SAAiC,CAAC;AAExC,WAAO,aAAa,QAAQ,CAAC,OAAO,QAAQ;AAC1C,aAAO,GAAG,IAAI;AAAA,IAChB,CAAC;AAED,WAAO;AAAA,EACT,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AA2BO,SAAS,iBACd,cACwB;AACxB,MAAI;AAEF,QAAI;AAEJ,QAAI,wBAAwB,iBAAiB;AAE3C,eAAS,CAAC;AACV,iBAAW,CAAC,KAAK,KAAK,KAAK,aAAa,QAAQ,GAAG;AACjD,eAAO,GAAG,IAAI;AAAA,MAChB;AAAA,IACF,OAAO;AACL,eAAS;AAAA,IACX;AAGA,QAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,cAAQ,IAAI,yCAAyC,OAAO,KAAK,MAAM,CAAC;AACxE,cAAQ,IAAI,oCAAoC,MAAM;AAAA,IACxD;AAGA,UAAM,YAAY,OAAO;AACzB,QAAI,aAAa,OAAO,cAAc,YAAY,UAAU,KAAK,MAAM,IAAI;AACzE,UAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,gBAAQ,IAAI,gDAAgD,UAAU,MAAM;AAAA,MAC9E;AAEA,UAAI;AACF,cAAM,UAAU,aAAa,SAAS;AACtC,YAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,kBAAQ,IAAI,sCAAsC,QAAQ,UAAU,GAAG,GAAG,CAAC;AAAA,QAC7E;AAEA,cAAM,SAAS,KAAK,MAAM,OAAO;AACjC,YAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,kBAAQ,IAAI,mCAAmC,MAAM;AAAA,QACvD;AAGA,cAAMC,UAAiC,CAAC;AACxC,mBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,cAAI,UAAU,UAAa,UAAU,MAAM;AACzC,YAAAA,QAAO,GAAG,IAAI,OAAO,KAAK;AAAA,UAC5B;AAAA,QACF;AAEA,YAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,kBAAQ,IAAI,8BAA8BA,OAAM;AAAA,QAClD;AAEA,eAAOA;AAAA,MACT,SAAS,aAAa;AACpB,gBAAQ,MAAM,yDAAyD,WAAW;AAClF,YAAI,uBAAuB,OAAO;AAChC,kBAAQ,MAAM,qCAAqC,YAAY,OAAO;AAAA,QACxE;AAAA,MAEF;AAAA,IACF,OAAO;AACL,UAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,gBAAQ,IAAI,iDAAiD;AAAA,MAC/D;AAAA,IACF;AAGA,UAAM,SAAiC,CAAC;AACxC,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,UAAI,QAAQ,UAAU,UAAU,UAAa,UAAU,MAAM;AAC3D,eAAO,GAAG,IAAI,MAAM,QAAQ,KAAK,IAAI,MAAM,CAAC,IAAI,OAAO,KAAK;AAAA,MAC9D;AAAA,IACF;AAEA,QAAI,QAAQ,IAAI,aAAa,eAAe;AAC1C,cAAQ,IAAI,uCAAuC,MAAM;AAAA,IAC3D;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AACd,YAAQ,MAAM,wCAAwC,KAAK;AAC3D,WAAO,CAAC;AAAA,EACV;AACF;;;AChWA,SAAS,aAAa,UAA4B;AAChD,MAAI,OAAO,SAAS,UAAU,UAAU;AACtC,WAAO,SAAS;AAAA,EAClB;AACA,MAAI,SAAS,OAAO;AAClB,QAAI,aAAa,SAAS,OAAO;AAC/B,aAAO,SAAS,MAAM;AAAA,IACxB;AACA,QAAI,cAAc,SAAS,OAAO;AAChC,aAAO,SAAS,MAAM;AAAA,IACxB;AAAA,EACF;AACA,SAAO;AACT;AAKA,SAAS,mBAAmB,UAA4B;AACtD,MAAI,OAAO,SAAS,gBAAgB,UAAU;AAC5C,WAAO,SAAS;AAAA,EAClB;AACA,SAAO;AACT;AA0CA,SAAS,aAAqB;AAE5B,MAAI,OAAO,YAAY,eAAe,QAAQ,IAAI,sBAAsB;AACtE,WAAO,QAAQ,IAAI;AAAA,EACrB;AAGA,SAAO;AACT;AAEO,SAAS,oBACd,UACA,eACA,UAA8B,CAAC,GACrB;AACV,QAAM;AAAA,IACJ,iBAAiB;AAAA,IACjB,SAAS;AAAA,IACT,gBAAgB,CAAC;AAAA,IACjB,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,EACF,IAAI;AAGJ,QAAM,UAAU,mBAAmB,oBAAoB,cACnD,kBACA,WAAW;AAGf,QAAM,iBAAiB,aAAa,QAAQ;AAC5C,QAAM,uBAAuB,mBAAmB,QAAQ;AAGxD,QAAM,qBAAuC;AAAA,IAC3C,GAAG;AAAA,IACH,OAAO,eAAe,SAAS,kBAAkB,cAAc,SAAS;AAAA,IACxE,aAAa,eAAe,eAAe,wBAAwB,cAAc,eAAe;AAAA,IAChG,GAAG;AAAA,EACL;AAGA,QAAM,WAAW,mBAAmB,SAAS,mBAAmB;AAGhE,QAAM,qBAAqB;AAAA,IACzB;AAAA,IACA,EAAE,SAAS,gBAAgB,UAAU;AAAA,EACvC;AAKA,QAAM,aAAa,UACf,sBAAsB,oBAAoB,OAAO,IACjD;AAGJ,QAAM,mBAAmB,SAAS,WAAW,SACzC,MAAM,QAAQ,SAAS,UAAU,MAAM,IACrC,SAAS,UAAU,SACnB,CAAC,SAAS,UAAU,MAAM,IAC5B,CAAC;AAEL,QAAM,wBAAwB,SAAS,SAAS,SAC5C,MAAM,QAAQ,SAAS,QAAQ,MAAM,IACnC,SAAS,QAAQ,SACjB,CAAC,SAAS,QAAQ,MAAM,IAC1B,CAAC;AAGL,QAAM,gBAA0B;AAAA,IAC9B,GAAG;AAAA,IACH,WAAW;AAAA,MACT,GAAG,SAAS;AAAA,MACZ,QAAQ;AAAA,QACN,GAAG;AAAA,QACH;AAAA,UACE,KAAK;AAAA,UACL,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,KAAK;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,GAAG,SAAS;AAAA,MACZ,MAAM;AAAA,MACN,QAAQ;AAAA,QACN,GAAG;AAAA,QACH;AAAA,UACE,KAAK;AAAA,UACL,KAAK;AAAA,QACP;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAKA,MAAI,CAAC,cAAc,gBAAgB,SAAS;AAE1C,QAAI,QAAQ,WAAW,SAAS,KAAK,QAAQ,WAAW,UAAU,GAAG;AACnE,UAAI;AACF,sBAAc,eAAe,IAAI,IAAI,OAAO;AAAA,MAC9C,SAAS,GAAG;AAAA,MAGZ;AAAA,IACF;AAAA,EACF;AAGA,MAAI,WAAW,WAAW;AAExB,UAAM,gBAAgB,SAAS,SAAS,OAAO,SAAS,UAAU,YAAY,CAAC,MAAM,QAAQ,SAAS,KAAK,IACvG,SAAS,QACT,CAAC;AACL,kBAAc,QAAQ;AAAA,MACpB,GAAG;AAAA,MACH,GAAI,WAAW,EAAE,MAAM,QAAQ;AAAA,MAC/B,GAAI,aAAa,EAAE,OAAO,UAAU;AAAA,IACtC;AAAA,EACF;AAEA,SAAO;AACT;AAoCO,SAAS,2BACd,SACA;AACA,SAAO,CACL,UACA,kBACa;AACb,WAAO,oBAAoB,UAAU,eAAe,OAAO;AAAA,EAC7D;AACF;;;AJjDM,gBAAAC,YAAA;AA9JC,SAAS,qBAAqB,QAA8B;AACjE,QAAM;AAAA,IACJ,UAAU,WAAW;AAAA,IACrB,eAAe,CAAC;AAAA,IAChB,OAAO,aAAa,CAAC;AAAA,IACrB,OAAO,EAAE,OAAO,MAAM,QAAQ,IAAI;AAAA,IAClC,QAAQ;AAAA,EACV,IAAI;AAEJ,iBAAe,IAAI,KAAkB;AACnC,QAAI,eAAgC,IAAI,gBAAgB;AAGxD,QAAI,IAAI,SAAS,gBAAgB,IAAI,QAAQ,aAAa,OAAO,GAAG;AAClE,qBAAe,IAAI,QAAQ;AAAA,IAC7B,WAAW,IAAI,SAAS,UAAU,IAAI,QAAQ,OAAO,SAAS,GAAG;AAC/D,qBAAe,IAAI,gBAAgB,IAAI,QAAQ,MAAM;AAAA,IACvD,OAAO;AACL,UAAI;AACF,cAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,YAAI,IAAI,aAAa,OAAO,GAAG;AAC7B,yBAAe,IAAI;AAAA,QACrB;AAAA,MACF,SAAS,OAAO;AAAA,MAEhB;AAEA,UAAI,aAAa,SAAS,KAAK,IAAI,KAAK;AACtC,cAAM,aAAa,IAAI,IAAI,QAAQ,GAAG;AACtC,YAAI,eAAe,IAAI;AACrB,gBAAM,cAAc,IAAI,IAAI,UAAU,aAAa,CAAC;AACpD,yBAAe,IAAI,gBAAgB,WAAW;AAAA,QAChD;AAAA,MACF;AAEA,UAAI,aAAa,SAAS,GAAG;AAC3B,cAAM,eAAe,IAAI,QAAQ,IAAI,oBAAoB;AACzD,YAAI,cAAc;AAChB,yBAAe,IAAI,gBAAgB,YAAY;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAGA,QAAI,QAAQ,aAAa,SAAS;AAClC,QAAI,WAAW,aAAa,YAAY;AACxC,QAAI,cAAc,aAAa,eAAe;AAI9C,UAAM,YAAY,aAAa,IAAI,MAAM;AACzC,QAAI,gBAAqC,CAAC;AAE1C,QAAI,WAAW;AACb,UAAI;AACF,cAAM,YAAoC,EAAE,MAAM,UAAU;AAC5D,mBAAW,CAAC,KAAK,KAAK,KAAK,aAAa,QAAQ,GAAG;AACjD,cAAI,QAAQ,QAAQ;AAClB,sBAAU,GAAG,IAAI;AAAA,UACnB;AAAA,QACF;AACA,wBAAgB,iBAAiB,SAAS;AAG1C,YAAI,cAAc,SAAS,OAAO,cAAc,UAAU,YAAY,cAAc,MAAM,KAAK,MAAM,IAAI;AACvG,kBAAQ,cAAc,MAAM,KAAK;AAAA,QACnC;AACA,YAAI,cAAc,YAAY,OAAO,cAAc,aAAa,YAAY,cAAc,SAAS,KAAK,MAAM,IAAI;AAChH,qBAAW,cAAc,SAAS,KAAK;AAAA,QACzC;AACA,YAAI,cAAc,eAAe,OAAO,cAAc,gBAAgB,YAAY,cAAc,YAAY,KAAK,MAAM,IAAI;AACzH,wBAAc,cAAc,YAAY,KAAK;AAAA,QAC/C;AAAA,MACF,SAAS,OAAO;AAAA,MAEhB;AAAA,IACF;AAGA,QAAI,CAAC,SAAS,UAAU,YAAY;AAClC,YAAM,aAAa,aAAa,IAAI,OAAO;AAC3C,UAAI,YAAY;AACd,gBAAQ;AAAA,MACV;AAAA,IACF;AACA,QAAI,CAAC,UAAU;AACb,YAAM,gBAAgB,aAAa,IAAI,UAAU;AACjD,UAAI,eAAe;AACjB,mBAAW;AAAA,MACb;AAAA,IACF;AACA,QAAI,CAAC,eAAe,gBAAgB,UAAU;AAC5C,YAAM,YAAY,aAAa,IAAI,aAAa;AAChD,UAAI,WAAW;AACb,sBAAc;AAAA,MAChB;AAAA,IACF;AAGA,QAAI,QAAe,CAAC;AACpB,QAAI,WAAW,SAAS,GAAG;AACzB,cAAQ,MAAM,gBAAgB,UAAU;AAAA,IAC1C;AAGA,UAAM,aAAa,CAAC,OAAY,OAAwC,aAAkB;AACxF,UAAI,UAAU,UAAa,UAAU,QAAQ,UAAU,IAAI;AACzD,eAAO;AAAA,MACT;AACA,UAAI,SAAS,UAAU;AACrB,cAAM,MAAM,OAAO,KAAK;AACxB,eAAO,MAAM,GAAG,IAAI,SAAY;AAAA,MAClC;AACA,UAAI,SAAS,WAAW;AACtB,YAAI,OAAO,UAAU,UAAW,QAAO;AACvC,YAAI,OAAO,UAAU,UAAU;AAC7B,iBAAO,MAAM,YAAY,MAAM,UAAU,UAAU;AAAA,QACrD;AACA,eAAO,QAAQ,KAAK;AAAA,MACtB;AACA,aAAO,OAAO,KAAK;AAAA,IACrB;AAGA,UAAM,gBAAsC;AAAA,MAC1C,GAAG;AAAA;AAAA,MAEH;AAAA,MACA;AAAA,MACA;AAAA;AAAA,MAEA,UAAU,cAAc,YAAY,aAAa;AAAA,MACjD,MAAM,cAAc,QAAQ,aAAa;AAAA;AAAA,MAEzC,gBAAiB,cAAc,kBAA2C,aAAa;AAAA,MACvF,eAAe,cAAc,iBAAiB,aAAa;AAAA,MAC3D,aAAa,cAAc,eAAe,aAAa;AAAA,MACvD,iBAAiB,cAAc,mBAAmB,aAAa;AAAA;AAAA,MAE/D,WAAW,WAAW,cAAc,WAAW,QAAQ,KAAK,aAAa;AAAA,MACzE,aAAa,WAAW,cAAc,aAAa,QAAQ,KAAK,aAAa;AAAA,MAC7E,YAAY,cAAc,cAAc,aAAa;AAAA;AAAA,MAErD,iBAAiB,WAAW,cAAc,iBAAiB,QAAQ,KAAK,aAAa;AAAA,MACrF,kBAAkB,cAAc,oBAAoB,aAAa;AAAA;AAAA,MAEjE,cAAc,WAAW,cAAc,cAAc,QAAQ,KAAK,aAAa;AAAA,MAC/E,eAAe,cAAc,iBAAiB,aAAa;AAAA;AAAA,MAE3D,SAAS,WAAW,cAAc,SAAS,QAAQ,KAAK,aAAa;AAAA,MACrE,UAAU,WAAW,cAAc,UAAU,QAAQ,KAAK,aAAa;AAAA;AAAA,MAEvE,UAAU,WAAW,cAAc,UAAU,SAAS,KAAK,aAAa;AAAA,MACxE,cAAc,WAAW,cAAc,cAAc,SAAS,KAAK,aAAa;AAAA,IAClF;AAGA,WAAO,IAAI;AAAA,MACT,gBAAAA,KAAC,YAAU,GAAG,eAAe;AAAA,MAC7B;AAAA,QACE,OAAO,KAAK;AAAA,QACZ,QAAQ,KAAK;AAAA,QACb;AAAA,QACA,OAAO,SAAS,QAAQ,IAAI,aAAa;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,SAAS;AAAA,EACX;AACF;AAmCO,SAAS,0BAA0B,QAA8B;AACtE,QAAM,UAAU,qBAAqB,MAAM;AAC3C,QAAMC,iBAAgB,OAAO,YAAY,eAAe,QAAQ,IAAI,6BAA6B;AAEjG,iBAAe,IACb,SACA,SACA;AAEA,QAAIA,gBAAe;AACjB,aAAO,IAAI,SAAS,8DAA8D;AAAA,QAChF,QAAQ;AAAA,QACR,SAAS,EAAE,gBAAgB,aAAa;AAAA,MAC1C,CAAC;AAAA,IACH;AAGA,UAAM,SAAS,MAAM,QAAQ;AAG7B,UAAM,YAAY,OAAO;AAGzB,UAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,QAAI,aAAa,IAAI,QAAQ,SAAS;AAEtC,UAAM,kBAAkB,IAAI,YAAY,IAAI,SAAS,GAAG;AAAA,MACtD,QAAQ,QAAQ;AAAA,MAChB,SAAS,QAAQ;AAAA,IACnB,CAAC;AAED,WAAO,QAAQ,IAAI,eAAe;AAAA,EACpC;AAIA,iBAAe,uBAAyD;AACtE,WAAO,CAAC;AAAA,EACV;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;;;AKjSO,SAAS,YACd,MACA,UACiB;AAGjB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AASO,SAAS,2BACd,MACA,WAAmB,SACJ;AACf,MAAI,KAAK,WAAW,UAAU,KAAK,KAAK,WAAW,QAAQ,GAAG;AAG5D,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAKO,SAAS,eACd,WAAmB,SACX;AAGR,SAAO;AACT;AAMO,SAAS,UACd,QACA,MAC6B;AAC7B,SAAO,OAAO,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAC3C;AAEO,SAAS,mBACd,QACA,MAC6B;AAC7B,QAAM,QAAQ,UAAU,QAAQ,IAAI;AACpC,MAAI,MAAO,QAAO;AAElB,QAAM,WAAW,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AAC/C,WAAS,IAAI,SAAS,QAAQ,IAAI,GAAG,KAAK;AACxC,UAAM,aAAa,MAAM,SAAS,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG;AACtD,UAAM,SAAS,UAAU,QAAQ,UAAU;AAC3C,QAAI,OAAQ,QAAO;AAAA,EACrB;AAEA,SAAO;AACT;AAMO,SAAS,aACd,QACA,MACA,WAAW,aACH;AACR,QAAM,QAAQ,mBAAmB,QAAQ,IAAI;AAC7C,SAAO,OAAO,SAAS,SAAS;AAClC;AAcO,SAAS,SACd,SACA,QACA,WACS;AACT,QAAM,UACJ,YAAY,UAAW,WAAW,OAAO,QAAQ,WAAW,SAAS,GAAG;AAG1E,MAAI,WAAW,WAAW;AACxB,WAAO,CAAC,UAAU;AAAA,MAChB,CAAC,eACC,WAAW,SAAS,UACpB,WAAW,KAAK,WAAW,SAAS,GAAG,MACtC,YAAY,WAAW,QACtB,QAAQ,WAAW,WAAW,OAAO,GAAG;AAAA,IAC9C;AAAA,EACF;AAEA,SAAO;AACT;AASO,SAAS,kBACd,QACA,WACY;AACZ,SAAO,OACJ;AAAA,IACC,CAAC,MACC,EAAE,SAAS,UAAU,aACrB,EAAE,SAAS,SACV,EAAE,SAAS,SAAS,UAAa,EAAE,SAAS,SAAS;AAAA,EAC1D,EACC,KAAK,CAAC,GAAG,OAAO,EAAE,SAAS,SAAS,MAAM,EAAE,SAAS,SAAS,EAAE,EAChE,IAAI,CAAC,OAAO;AAAA,IACX,MAAM,EAAE;AAAA,IACR,OAAO,EAAE,SAAS;AAAA,IAClB,MAAM,EAAE,SAAS;AAAA,EACnB,EAAE;AACN;;;ACzJA,SAAS,eAAe;AA6EjB,SAAS,QACd,YACA,UAA4B,CAAC,GACjB;AACZ,QAAMC,SAAQ,QAAQ,IAAI,aAAa;AACvC,QAAMC,iBAAgB,QAAQ,IAAI,6BAA6B;AAM/D,QAAM,gBAAgB,QAAQ,YAAY,SACtC,QAAQ,UACPD,UAASC;AAEd,QAAM,iBAAmC;AAAA,IACvC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,GAAG;AAAA,EACL;AAEA,MAAI;AAIF,QAAI,CAAC,QAAQ,IAAI,oCAAoC;AACnD,cAAQ,IAAI,qCAAqC;AAAA,IACnD;AAEA,UAAM,kBAAkB,UAAQ,eAAe,EAAE;AAEjD,UAAM,cAAc,gBAAgB;AAAA,MAClC,OAAO,eAAe;AAAA,MACtB,QAAQ,eAAe;AAAA,MACvB,SAAS,eAAe;AAAA,MACxB,mBAAmB,eAAe;AAAA,MAClC,gBAAgB,eAAe;AAAA,MAC/B,GAAG,eAAe;AAAA,IACpB,CAAC;AAED,WAAO,YAAY,UAAU;AAAA,EAC/B,SAAS,OAAO;AACd,YAAQ,MAAM,gCAAgC,KAAK;AACnD,WAAO;AAAA,EACT;AACF;;;AClIO,IAAM,eAAe;AAGrB,IAAM,uBAAuB,KAAK,KAAK;AAGvC,IAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAU1B,IAAM,qBAAqB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,6BAA6B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,4BAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;;;AC1CA,SAAS,qBAAqB;AAC9B,SAAS,YAAY;;;ACHd,IAAM,gBAAgB,QAAQ,IAAI,6BAA6B;AAC/D,IAAM,QAAQ,QAAQ,IAAI,aAAa;AACvC,IAAM,eAAe,QAAQ,IAAI,aAAa;AAC9C,IAAM,OAAO,QAAQ,IAAI,OAAO;AAKhC,SAAS,YAAY,mBAAqC;AAC/D,MAAI,CAAC,cAAe,QAAO;AAC3B,SAAO,oBAAoB,eAAe;AAC5C;AAKO,SAAS,YAAoB;AAClC,SAAO,gBAAgB,KAAM,QAAQ,IAAI,uBAAuB;AAClE;AAKO,SAASC,cAAqB;AACnC,SAAO,gBAAgB,KAAM,QAAQ,IAAI,wBAAwB;AACnE;;;ACPO,IAAM,oBAAyC;AAAA,EACpD;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,WAAW;AAAA,IACX,eAAe;AAAA,EACjB;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,aAAa;AAAA,IACb,WAAW;AAAA,IACX,eAAe;AAAA,IACf,aAAa;AAAA,EACf;AACF;AAKO,IAAM,oBAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AACF;AAKO,SAAS,sBAAsB,SAGd;AACtB,SAAO,kBAAkB,OAAO,SAAO;AACrC,YAAQ,IAAI,WAAW;AAAA,MACrB,KAAK;AACH,eAAO,QAAQ;AAAA,MACjB,KAAK;AACH,eAAO,QAAQ;AAAA,MACjB,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IACX;AAAA,EACF,CAAC;AACH;;;AF5CO,SAAS,mBAAmB,aAA8B;AAC/D,MAAI;AAEF,UAAM,kBAAkB,cAAc,KAAK,QAAQ,IAAI,GAAG,cAAc,CAAC;AACzE,oBAAgB,QAAQ,WAAW;AACnC,WAAO;AAAA,EACT,QAAQ;AAEN,QAAI;AACF,gBAAQ,QAAQ,WAAW;AAC3B,aAAO;AAAA,IACT,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAKO,SAAS,qBAAuC;AACrD,QAAM,iBAAiB,sBAAsB,EAAE,eAAe,MAAM,CAAC;AACrE,QAAM,UAA4B,CAAC;AAEnC,aAAW,OAAO,gBAAgB;AAChC,QAAI,CAAC,mBAAmB,IAAI,IAAI,GAAG;AACjC,cAAQ,KAAK;AAAA,QACX,GAAG;AAAA,QACH,QAAQ,cAAc,GAAG;AAAA,MAC3B,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAKO,SAAS,cAAc,cAA0C;AACtE,QAAM,UAA4B,CAAC;AAEnC,aAAW,QAAQ,cAAc;AAC/B,QAAI,CAAC,mBAAmB,IAAI,GAAG;AAC7B,YAAM,aAAa,kBAAkB,KAAK,OAAK,EAAE,SAAS,IAAI;AAC9D,cAAQ,KAAK;AAAA,QACX;AAAA,QACA,aAAa,YAAY,eAAe;AAAA,QACxC,WAAW,YAAY,aAAa;AAAA,QACpC,eAAe,YAAY,iBAAiB;AAAA,QAC5C,QAAQ,aAAa,cAAc,UAAU,IAAI;AAAA,MACnD,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAKA,SAAS,cAAc,KAAgC;AACrD,UAAQ,IAAI,WAAW;AAAA,IACrB,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;;;AGxEA,IAAM,kBAAsD;AAAA,EAC1D,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,UAAU;AAAA,EACV,aAAa;AACf;AAOO,SAAS,sBACd,QACA,UAAoC,CAAC,GAC5B;AAET,MAAI,CAAC,mBAAmB,4BAA4B,GAAG;AACrD,WAAO;AAAA,EACT;AAEA,QAAM,OAAO,EAAE,GAAG,iBAAiB,GAAG,QAAQ;AAE9C,MAAI;AAGF,UAAM,oBAAoB,UAAQ,4BAA4B;AAE9D,QAAI,CAAC,OAAO,SAAS;AACnB,aAAO,UAAU,CAAC;AAAA,IACpB;AAGA,QAAI,KAAK,MAAM;AACb,aAAO,QAAQ;AAAA,QACb,IAAI,kBAAkB;AAAA,UACpB,UAAU;AAAA,UACV,WAAW;AAAA,UACX,MAAM;AAAA,UACN,WAAW,KAAK;AAAA,UAChB,UAAU,KAAK;AAAA,QACjB,CAAC;AAAA,MACH;AAAA,IACF;AAGA,QAAI,KAAK,QAAQ;AACf,aAAO,QAAQ;AAAA,QACb,IAAI,kBAAkB;AAAA,UACpB,UAAU;AAAA,UACV,WAAW;AAAA,UACX,MAAM;AAAA,UACN,WAAW,KAAK;AAAA,UAChB,UAAU,KAAK;AAAA,UACf,oBAAoB;AAAA,YAClB,OAAO,KAAK;AAAA,UACd;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IACF;AAEA,WAAO;AAAA,EACT,SAAS,OAAO;AAEd,WAAO;AAAA,EACT;AACF;AAKO,SAAS,yBAAkC;AAChD,SAAO,mBAAmB,4BAA4B;AACxD;;;ACzFA,OAAOC,YAAW;;;ACFX,IAAM,eAAe;AACrB,IAAM,iBAAiB,GAAG,YAAY;AACtC,IAAM,cAAc,GAAG,YAAY;AAGnC,IAAM,sBAAsB;AAC5B,IAAM,oBAAoB;AAC1B,IAAM,kBAAkB;AAGxB,IAAM,eAAe,sBAAe,cAAc;AAGlD,IAAM,UAAU;AAAA;AAAA;AAAA;AAAA,yBAIE,cAAc;AAAA,yBACd,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACjBpC,OAAO,WAAW;AAClB,SAAS,UAAU,aAAa;AAChC,OAAO,UAAU;AACjB,OAAOC,cAAa;AACpB,SAAS,uBAAuB;AAOhC,IAAM,iBAAiB,IAAI,KAIxB;AAAA,EACD,aAAa;AAAA,EACb,gBAAgB;AAClB,CAAC;AAGD,IAAM,qBAAqB,KAAK,KAAK;AAGrC,IAAM,iBAAiB,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG;AAqBjE,SAAS,uBAAgD;AAC9D,MAAI;AAEF,UAAM,KAAK,UAAQ,IAAI;AACvB,UAAM,OAAO,UAAQ,MAAM;AAC3B,UAAM,MAAM,QAAQ,IAAI;AAExB,QAAI,GAAG,WAAW,KAAK,KAAK,KAAK,gBAAgB,CAAC,EAAG,QAAO;AAC5D,QAAI,GAAG,WAAW,KAAK,KAAK,KAAK,WAAW,CAAC,EAAG,QAAO;AACvD,QAAI,GAAG,WAAW,KAAK,KAAK,KAAK,mBAAmB,CAAC,EAAG,QAAO;AAG/D,QAAI;AACF,eAAS,kBAAkB,EAAE,OAAO,SAAS,CAAC;AAC9C,aAAO;AAAA,IACT,QAAQ;AACN,UAAI;AACF,iBAAS,kBAAkB,EAAE,OAAO,SAAS,CAAC;AAC9C,eAAO;AAAA,MACT,QAAQ;AACN,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAAS,0BACd,aACAC,QACA,IACQ;AACR,QAAM,UAAUA,SAAQ,QAAQ;AAChC,UAAQ,IAAI;AAAA,IACV,KAAK;AACH,aAAO,YAAY,OAAO,GAAG,WAAW;AAAA,IAC1C,KAAK;AACH,aAAO,YAAY,OAAO,GAAG,WAAW;AAAA,IAC1C,KAAK;AACH,aAAO,eAAe,OAAO,GAAG,WAAW;AAAA,EAC/C;AACF;AAKO,SAAS,oBAAoB,UAA4B,IAAqC;AACnG,QAAM,cAAc,SAAS,OAAO,OAAK,EAAE,aAAa,EAAE,IAAI,OAAK,EAAE,IAAI;AACzE,QAAM,eAAe,SAAS,OAAO,OAAK,CAAC,EAAE,aAAa,EAAE,IAAI,OAAK,EAAE,IAAI;AAE3E,QAAM,WAAqB,CAAC;AAE5B,MAAI,YAAY,SAAS,GAAG;AAC1B,YAAQ,IAAI;AAAA,MACV,KAAK;AACH,iBAAS,KAAK,eAAe,YAAY,KAAK,GAAG,CAAC,EAAE;AACpD;AAAA,MACF,KAAK;AACH,iBAAS,KAAK,eAAe,YAAY,KAAK,GAAG,CAAC,EAAE;AACpD;AAAA,MACF,KAAK;AACH,iBAAS,KAAK,kBAAkB,YAAY,KAAK,GAAG,CAAC,EAAE;AACvD;AAAA,IACJ;AAAA,EACF;AAEA,MAAI,aAAa,SAAS,GAAG;AAC3B,YAAQ,IAAI;AAAA,MACV,KAAK;AACH,iBAAS,KAAK,YAAY,aAAa,KAAK,GAAG,CAAC,EAAE;AAClD;AAAA,MACF,KAAK;AACH,iBAAS,KAAK,YAAY,aAAa,KAAK,GAAG,CAAC,EAAE;AAClD;AAAA,MACF,KAAK;AACH,iBAAS,KAAK,eAAe,aAAa,KAAK,GAAG,CAAC,EAAE;AACrD;AAAA,IACJ;AAAA,EACF;AAEA,SAAO,SAAS,KAAK,MAAM;AAC7B;AAKA,eAAe,gBAAgB,UAAoC;AAEjE,MAAI,QAAQ,CAAC,QAAQ,MAAM,OAAO;AAChC,WAAO;AAAA,EACT;AAEA,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,KAAK,gBAAgB;AAAA,MACzB,OAAO,QAAQ;AAAA,MACf,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAED,OAAG,SAAS,UAAU,CAAC,WAAW;AAChC,SAAG,MAAM;AACT,YAAM,aAAa,OAAO,YAAY,EAAE,KAAK;AAC7C,cAAQ,eAAe,MAAM,eAAe,OAAO,eAAe,KAAK;AAAA,IACzE,CAAC;AAAA,EACH,CAAC;AACH;AAKA,SAAS,cAAc,MAAc;AACnC,MAAI,aAAa;AACjB,MAAI,WAAkC;AACtC,MAAI,cAAc;AAElB,QAAM,SAAS,MAAM;AACnB,UAAM,QAAQ,eAAe,UAAU;AACvC,YAAQ,OAAO,MAAM,KAAK,MAAM,KAAK,KAAK,CAAC,IAAI,WAAW,EAAE;AAC5D,kBAAc,aAAa,KAAK,eAAe;AAAA,EACjD;AAEA,SAAO;AAAA,IACL,QAAQ;AACN,UAAI,QAAQ,OAAO,OAAO;AACxB,mBAAW,YAAY,QAAQ,EAAE;AACjC,eAAO;AAAA,MACT,OAAO;AACL,gBAAQ,IAAI,KAAK,WAAW,EAAE;AAAA,MAChC;AACA,aAAO;AAAA,IACT;AAAA,IACA,KAAK,SAAiB;AACpB,oBAAc;AACd,UAAI,CAAC,QAAQ,OAAO,OAAO;AACzB,gBAAQ,IAAI,KAAK,OAAO,EAAE;AAAA,MAC5B;AACA,aAAO;AAAA,IACT;AAAA,IACA,QAAQC,OAAe;AACrB,UAAI,SAAU,eAAc,QAAQ;AACpC,UAAI,QAAQ,OAAO,OAAO;AACxB,gBAAQ,OAAO,MAAM,KAAK,MAAM,MAAM,QAAG,CAAC,IAAIA,SAAQ,WAAW;AAAA,CAAI;AAAA,MACvE,OAAO;AACL,gBAAQ,IAAI,KAAK,MAAM,MAAM,QAAG,CAAC,IAAIA,SAAQ,WAAW,EAAE;AAAA,MAC5D;AACA,aAAO;AAAA,IACT;AAAA,IACA,KAAKA,OAAe;AAClB,UAAI,SAAU,eAAc,QAAQ;AACpC,UAAI,QAAQ,OAAO,OAAO;AACxB,gBAAQ,OAAO,MAAM,KAAK,MAAM,IAAI,QAAG,CAAC,IAAIA,SAAQ,WAAW;AAAA,CAAI;AAAA,MACrE,OAAO;AACL,gBAAQ,IAAI,KAAK,MAAM,IAAI,QAAG,CAAC,IAAIA,SAAQ,WAAW,EAAE;AAAA,MAC1D;AACA,aAAO;AAAA,IACT;AAAA,IACA,OAAO;AACL,UAAI,SAAU,eAAc,QAAQ;AACpC,UAAI,QAAQ,OAAO,OAAO;AACxB,gBAAQ,OAAO,MAAM,UAAU;AAAA,MACjC;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAKA,eAAe,qBACb,KACA,IACA,OACA,OACkB;AAClB,QAAM,UAAU,0BAA0B,IAAI,MAAM,IAAI,eAAe,EAAE;AACzE,QAAM,WAAW,IAAI,QAAQ,CAAC,IAAI,KAAK;AACvC,QAAM,UAAU,cAAc,GAAG,MAAM,IAAI,QAAQ,CAAC,eAAe,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK;AAE5F,UAAQ,MAAM;AAEd,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,CAAC,KAAK,GAAG,IAAI,IAAI,QAAQ,MAAM,GAAG;AACxC,UAAM,OAAO,MAAM,KAAK,MAAM;AAAA,MAC5B,OAAO;AAAA,MACP,KAAK,QAAQ,IAAI;AAAA,MACjB,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,IAClC,CAAC;AAED,QAAI,SAAS;AAEb,SAAK,QAAQ,GAAG,QAAQ,CAAC,SAAS;AAChC,gBAAU,KAAK,SAAS;AAAA,IAC1B,CAAC;AAED,SAAK,GAAG,SAAS,CAAC,SAAS;AACzB,UAAI,SAAS,GAAG;AACd,gBAAQ,QAAQ,GAAG,MAAM,IAAI,QAAQ,CAAC,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,IAAI,MAAM,MAAM,WAAW,CAAC,EAAE;AAC5F,gBAAQ,IAAI;AAAA,MACd,OAAO;AACL,gBAAQ,KAAK,GAAG,MAAM,IAAI,QAAQ,CAAC,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,IAAI,MAAM,IAAI,QAAQ,CAAC,EAAE;AACpF,YAAI,QAAQ;AACV,kBAAQ,IAAI,MAAM,IAAI,OAAO,OAAO,MAAM,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;AAAA,QACvD;AACA,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF,CAAC;AAED,SAAK,GAAG,SAAS,MAAM;AACrB,cAAQ,KAAK,GAAG,MAAM,IAAI,QAAQ,CAAC,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,IAAI,MAAM,IAAI,QAAQ,CAAC,EAAE;AACpF,cAAQ,KAAK;AAAA,IACf,CAAC;AAAA,EACH,CAAC;AACH;AAKA,eAAsB,4BAA4B,UAA8C;AAC9F,MAAI,SAAS,WAAW,EAAG,QAAO;AAElC,QAAM,KAAK,qBAAqB;AAChC,QAAM,QAAQ,SAAS;AAEvB,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,MAAM,KAAK,gBAAgB,KAAK,WAAW,QAAQ,IAAI,MAAM,EAAE,KAAK,CAAC;AACjF,UAAQ,IAAI,EAAE;AAEd,MAAI,eAAe;AACnB,MAAI,iBAA2B,CAAC;AAEhC,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAM,UAAU,MAAM,qBAAqB,SAAS,CAAC,GAAG,IAAI,GAAG,KAAK;AACpE,QAAI,SAAS;AACX;AAAA,IACF,OAAO;AACL,qBAAe,KAAK,SAAS,CAAC,EAAE,IAAI;AAAA,IACtC;AAAA,EACF;AAEA,UAAQ,IAAI,EAAE;AAEd,MAAI,eAAe,WAAW,GAAG;AAC/B,IAAAC,SAAQ,QAAQ,OAAO,KAAK,mCAAmC;AAC/D,WAAO;AAAA,EACT,WAAW,eAAe,GAAG;AAC3B,IAAAA,SAAQ,KAAK,GAAG,YAAY,IAAI,KAAK,gCAAgC,eAAe,KAAK,IAAI,CAAC,EAAE;AAChG,WAAO;AAAA,EACT,OAAO;AACL,IAAAA,SAAQ,MAAM,+BAA+B,eAAe,KAAK,IAAI,CAAC,EAAE;AACxE,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,gBAAgB,UAA8C;AAElF,MAAI,SAAS,SAAS,KAAK,QAAQ,OAAO,OAAO;AAC/C,WAAO,4BAA4B,QAAQ;AAAA,EAC7C;AAGA,MAAI,SAAS,WAAW,EAAG,QAAO;AAElC,QAAM,KAAK,qBAAqB;AAChC,QAAM,UAAU,oBAAoB,UAAU,EAAE;AAEhD,EAAAA,SAAQ,KAAK,eAAe,MAAM,KAAK,SAAS,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,CAAC,EAAE;AAE9E,QAAM,UAAU,cAAc,wBAAwB;AACtD,UAAQ,MAAM;AAEd,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,OAAO,MAAM,SAAS;AAAA,MAC1B,OAAO;AAAA,MACP,KAAK,QAAQ,IAAI;AAAA,MACjB,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,IAClC,CAAC;AAED,SAAK,GAAG,SAAS,CAAC,SAAS;AACzB,UAAI,SAAS,GAAG;AACd,gBAAQ,QAAQ,kCAAkC;AAClD,gBAAQ,IAAI;AAAA,MACd,OAAO;AACL,gBAAQ,KAAK,4BAA4B;AACzC,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF,CAAC;AAED,SAAK,GAAG,SAAS,MAAM;AACrB,cAAQ,KAAK,qBAAqB;AAClC,cAAQ,KAAK;AAAA,IACf,CAAC;AAAA,EACH,CAAC;AACH;AAOA,eAAsB,wBAAwB,UAA0B,CAAC,GAAqB;AAC5F,QAAM,UAAU,mBAAmB;AAGnC,QAAM,WAAW,QAAQ,gBAAgB,eAAe,IAAI,cAAc,KAAK,CAAC;AAChF,QAAM,YAAY,QAAQ,OAAO,OAAK,CAAC,SAAS,SAAS,EAAE,IAAI,CAAC;AAEhE,MAAI,UAAU,WAAW,GAAG;AAC1B,WAAO;AAAA,EACT;AAGA,QAAM,aAAa,eAAe,IAAI,YAAY,KAAK;AACvD,MAAI,CAAC,QAAQ,SAAU,KAAK,IAAI,IAAI,aAAc,oBAAoB;AAEpE,6BAAyB,SAAS;AAClC,WAAO;AAAA,EACT;AAGA,MAAI,QAAQ,eAAe,eAAe,IAAI,aAAa,GAAG;AAC5D,WAAO,gBAAgB,SAAS;AAAA,EAClC;AAGA,UAAQ,IAAI,EAAE;AACd,EAAAA,SAAQ,IAAI,qCAA8B;AAC1C,UAAQ,IAAI,EAAE;AAEd,aAAW,OAAO,WAAW;AAC3B,YAAQ,IAAI,KAAK,MAAM,OAAO,QAAG,CAAC,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,EAAE;AAC5D,YAAQ,IAAI,OAAO,MAAM,IAAI,IAAI,WAAW,CAAC,EAAE;AAC/C,YAAQ,IAAI,OAAO,MAAM,IAAI,IAAI,MAAM,CAAC,EAAE;AAC1C,YAAQ,IAAI,EAAE;AAAA,EAChB;AAGA,QAAM,KAAK,qBAAqB;AAChC,QAAM,UAAU,oBAAoB,WAAW,EAAE;AAEjD,UAAQ,IAAI,KAAK,MAAM,KAAK,UAAU,CAAC,IAAI,OAAO,EAAE;AACpD,UAAQ,IAAI,EAAE;AAGd,iBAAe,IAAI,cAAc,KAAK,IAAI,CAAC;AAE3C,QAAM,gBAAgB,MAAM;AAAA,IAC1B,GAAG,MAAM,MAAM,GAAG,CAAC,gCAAgC,MAAM,IAAI,OAAO,CAAC;AAAA,EACvE;AAEA,MAAI,eAAe;AACjB,UAAM,UAAU,MAAM,gBAAgB,SAAS;AAG/C,QAAI,SAAS;AACX,YAAM,aAAa,MAAM;AAAA,QACvB,GAAG,MAAM,MAAM,GAAG,CAAC,oCAAoC,MAAM,IAAI,OAAO,CAAC;AAAA,MAC3E;AACA,UAAI,YAAY;AACd,uBAAe,IAAI,eAAe,IAAI;AACtC,QAAAA,SAAQ,KAAK,8DAA8D;AAAA,MAC7E;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAGA,QAAM,kBAAkB,MAAM;AAAA,IAC5B,GAAG,MAAM,MAAM,GAAG,CAAC,2CAA2C,MAAM,IAAI,OAAO,CAAC;AAAA,EAClF;AAEA,MAAI,iBAAiB;AACnB,UAAM,cAAc,eAAe,IAAI,cAAc,KAAK,CAAC;AAC3D,mBAAe,IAAI,gBAAgB,CAAC,GAAG,aAAa,GAAG,UAAU,IAAI,OAAK,EAAE,IAAI,CAAC,CAAC;AAClF,IAAAA,SAAQ,KAAK,8BAA8B;AAAA,EAC7C;AAEA,SAAO;AACT;AAKA,SAAS,yBAAyB,UAAkC;AAClE,MAAI,SAAS,WAAW,EAAG;AAE3B,QAAM,KAAK,qBAAqB;AAChC,QAAM,UAAU,oBAAoB,UAAU,EAAE;AAEhD,EAAAA,SAAQ,KAAK,8BAA8B,SAAS,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE;AACjF,EAAAA,SAAQ,KAAK,iBAAiB,MAAM,KAAK,OAAO,CAAC,EAAE;AACrD;AAKO,SAAS,4BAAkC;AAChD,iBAAe,MAAM;AACrB,EAAAA,SAAQ,QAAQ,6BAA6B;AAC/C;;;ACncA,OAAOC,YAAW;AAClB,SAAS,SAAAC,cAAa;AACtB,OAAOC,WAAU;AACjB,OAAOC,cAAa;AACpB,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,QAAAC,aAAY;AACrB,SAAS,mBAAAC,wBAAuB;AAChC,OAAO,YAAY;AAOnB,IAAM,eAAe,IAAIC,MAItB;AAAA,EACD,aAAa;AAAA,EACb,gBAAgB;AAClB,CAAC;AAGD,IAAM,2BAA2B,KAAK,KAAK;AAG3C,IAAMC,kBAAiB,CAAC,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,UAAK,QAAG;AAqBxE,SAAS,mBAAmB,aAA8B;AACxD,MAAI;AACF,UAAM,KAAK,UAAQ,IAAI;AACvB,UAAM,cAAcC,MAAK,QAAQ,IAAI,GAAG,cAAc;AACtD,UAAM,UAAU,KAAK,MAAM,GAAG,aAAa,aAAa,OAAO,CAAC;AAEhE,UAAM,OAAO,EAAE,GAAG,QAAQ,cAAc,GAAG,QAAQ,gBAAgB;AACnE,UAAM,UAAU,KAAK,WAAW;AAEhC,WAAO,SAAS,WAAW,YAAY,KAAK;AAAA,EAC9C,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMO,SAAS,oBAAoB,aAAoC;AACtE,QAAM,KAAK,UAAQ,IAAI;AACvB,QAAM,MAAM,QAAQ,IAAI;AAGxB,MAAI;AACF,UAAM,aAAaA,MAAK,KAAK,gBAAgB,aAAa,cAAc;AACxE,QAAI,GAAG,WAAW,UAAU,GAAG;AAC7B,YAAM,MAAM,KAAK,MAAM,GAAG,aAAa,YAAY,OAAO,CAAC;AAC3D,aAAO,IAAI,WAAW;AAAA,IACxB;AAAA,EACF,QAAQ;AAAA,EAER;AAGA,MAAI;AACF,UAAM,kBAAkBC,eAAcD,MAAK,KAAK,cAAc,CAAC;AAC/D,UAAM,UAAU,gBAAgB,QAAQ,GAAG,WAAW,eAAe;AACrE,UAAM,MAAM,UAAQ,OAAO;AAC3B,WAAO,IAAI,WAAW;AAAA,EACxB,QAAQ;AAAA,EAER;AAGA,MAAI;AACF,UAAM,UAAU,UAAQ,QAAQ,GAAG,WAAW,eAAe;AAC7D,UAAM,MAAM,UAAQ,OAAO;AAC3B,WAAO,IAAI,WAAW;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAMO,SAAS,mBAAmB,aAA8B;AAC/D,SAAO,CAAC,mBAAmB,WAAW;AACxC;AAKA,eAAe,mBAAmB,aAA6C;AAC7E,MAAI;AACF,UAAM,QAAQ,MAAM,OAAO,OAAO;AAClC,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,MAAM,MAAM;AAAA,QAChB,8BAA8B,WAAW;AAAA,QACzC,EAAE,SAAS,IAAK;AAAA,QAChB,CAAC,QAAa;AACZ,cAAI,OAAO;AACX,cAAI,GAAG,QAAQ,CAAC,UAAkB;AAAE,oBAAQ;AAAA,UAAO,CAAC;AACpD,cAAI,GAAG,OAAO,MAAM;AAClB,gBAAI;AACF,oBAAM,OAAO,KAAK,MAAM,IAAI;AAC5B,sBAAQ,KAAK,WAAW,IAAI;AAAA,YAC9B,QAAQ;AACN,sBAAQ,IAAI;AAAA,YACd;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AACA,UAAI,GAAG,SAAS,MAAM,QAAQ,IAAI,CAAC;AACnC,UAAI,GAAG,WAAW,MAAM;AAAE,YAAI,QAAQ;AAAG,gBAAQ,IAAI;AAAA,MAAG,CAAC;AAAA,IAC3D,CAAC;AAAA,EACH,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAOA,eAAsB,gBAAgB,UAA6C,CAAC,GAA8B;AAChH,QAAM,UAA4B,CAAC;AAInC,QAAM,eAAe,MAAM,mBAAmB,YAAY;AAC1D,MAAI,CAAC,cAAc;AAEjB,WAAO;AAAA,EACT;AAGA,QAAM,SAAS,mBAAmB,IAAI,OAAO,SAAS;AAEpD,UAAM,cAAc,CAAC,mBAAmB,IAAI;AAC5C,QAAI,CAAC,QAAQ,uBAAuB,aAAa;AAC/C,aAAO;AAAA,IACT;AAEA,UAAM,UAAU,oBAAoB,IAAI;AACxC,QAAI,CAAC,SAAS;AACZ,aAAO;AAAA,IACT;AAGA,UAAM,YAAY,CAAC,EAAE,gBAAgB,WAAW,OAAO,GAAG,cAAc,OAAO;AAE/E,WAAO,EAAE,MAAM,SAAS,QAAQ,cAAc,UAAU;AAAA,EAC1D,CAAC;AAED,QAAM,eAAe,MAAM,QAAQ,IAAI,MAAM;AAE7C,aAAW,UAAU,cAAc;AACjC,QAAI,QAAQ;AACV,cAAQ,KAAK,MAAM;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AACT;AAKA,eAAsB,oBAAoB,UAA6C,CAAC,GAA8B;AACpH,QAAM,MAAM,MAAM,gBAAgB,OAAO;AACzC,QAAM,UAAU,aAAa,IAAI,iBAAiB,KAAK,CAAC;AAExD,SAAO,IAAI,OAAO,SAAO;AACvB,QAAI,CAAC,IAAI,UAAW,QAAO;AAE3B,QAAI,QAAQ,IAAI,IAAI,MAAM,IAAI,OAAQ,QAAO;AAC7C,WAAO;AAAA,EACT,CAAC;AACH;AAKA,SAASE,eAAc,MAAc;AACnC,MAAI,aAAa;AACjB,MAAI,WAAkC;AACtC,MAAI,cAAc;AAElB,QAAM,SAAS,MAAM;AACnB,UAAM,QAAQH,gBAAe,UAAU;AACvC,YAAQ,OAAO,MAAM,KAAKI,OAAM,KAAK,KAAK,CAAC,IAAI,WAAW,EAAE;AAC5D,kBAAc,aAAa,KAAKJ,gBAAe;AAAA,EACjD;AAEA,SAAO;AAAA,IACL,QAAQ;AACN,UAAI,QAAQ,OAAO,OAAO;AACxB,mBAAW,YAAY,QAAQ,EAAE;AACjC,eAAO;AAAA,MACT,OAAO;AACL,gBAAQ,IAAI,KAAK,WAAW,EAAE;AAAA,MAChC;AACA,aAAO;AAAA,IACT;AAAA,IACA,KAAK,SAAiB;AACpB,oBAAc;AACd,aAAO;AAAA,IACT;AAAA,IACA,QAAQK,OAAe;AACrB,UAAI,SAAU,eAAc,QAAQ;AACpC,UAAI,QAAQ,OAAO,OAAO;AACxB,gBAAQ,OAAO,MAAM,KAAKD,OAAM,MAAM,QAAG,CAAC,IAAIC,SAAQ,WAAW;AAAA,CAAI;AAAA,MACvE,OAAO;AACL,gBAAQ,IAAI,KAAKD,OAAM,MAAM,QAAG,CAAC,IAAIC,SAAQ,WAAW,EAAE;AAAA,MAC5D;AACA,aAAO;AAAA,IACT;AAAA,IACA,KAAKA,OAAe;AAClB,UAAI,SAAU,eAAc,QAAQ;AACpC,UAAI,QAAQ,OAAO,OAAO;AACxB,gBAAQ,OAAO,MAAM,KAAKD,OAAM,IAAI,QAAG,CAAC,IAAIC,SAAQ,WAAW;AAAA,CAAI;AAAA,MACrE,OAAO;AACL,gBAAQ,IAAI,KAAKD,OAAM,IAAI,QAAG,CAAC,IAAIC,SAAQ,WAAW,EAAE;AAAA,MAC1D;AACA,aAAO;AAAA,IACT;AAAA,IACA,OAAO;AACL,UAAI,SAAU,eAAc,QAAQ;AACpC,UAAI,QAAQ,OAAO,OAAO;AACxB,gBAAQ,OAAO,MAAM,UAAU;AAAA,MACjC;AACA,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAKA,eAAeC,iBAAgB,UAAoC;AACjE,MAAI,QAAQ,CAAC,QAAQ,MAAM,OAAO;AAChC,WAAO;AAAA,EACT;AAEA,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,KAAKC,iBAAgB;AAAA,MACzB,OAAO,QAAQ;AAAA,MACf,QAAQ,QAAQ;AAAA,IAClB,CAAC;AAED,OAAG,SAAS,UAAU,CAAC,WAAW;AAChC,SAAG,MAAM;AACT,YAAM,aAAa,OAAO,YAAY,EAAE,KAAK;AAC7C,cAAQ,eAAe,MAAM,eAAe,OAAO,eAAe,KAAK;AAAA,IACzE,CAAC;AAAA,EACH,CAAC;AACH;AAKA,eAAe,oBACb,KACA,IACA,OACA,OACkB;AAClB,QAAM,WAAW,IAAI,QAAQ,CAAC,IAAI,KAAK;AACvC,QAAM,cAAc,GAAGH,OAAM,IAAI,IAAI,OAAO,CAAC,WAAMA,OAAM,MAAM,IAAI,MAAM,CAAC;AAC1E,QAAM,UAAUD;AAAA,IACd,GAAGC,OAAM,IAAI,QAAQ,CAAC,aAAaA,OAAM,KAAK,IAAI,IAAI,CAAC,IAAI,WAAW;AAAA,EACxE;AAEA,UAAQ,MAAM;AAGd,QAAM,UAAU,OAAO,SACnB,YAAY,IAAI,IAAI,YACpB,OAAO,SACP,YAAY,IAAI,IAAI,YACpB,eAAe,IAAI,IAAI;AAE3B,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,UAAM,OAAOI,OAAM,SAAS;AAAA,MAC1B,OAAO;AAAA,MACP,KAAK,QAAQ,IAAI;AAAA,MACjB,OAAO,CAAC,UAAU,QAAQ,MAAM;AAAA,IAClC,CAAC;AAED,SAAK,GAAG,SAAS,CAAC,SAAS;AACzB,UAAI,SAAS,GAAG;AACd,gBAAQ;AAAA,UACN,GAAGJ,OAAM,IAAI,QAAQ,CAAC,IAAIA,OAAM,KAAK,IAAI,IAAI,CAAC,IAAIA,OAAM,MAAM,IAAI,MAAO,CAAC;AAAA,QAC5E;AACA,gBAAQ,IAAI;AAAA,MACd,OAAO;AACL,gBAAQ;AAAA,UACN,GAAGA,OAAM,IAAI,QAAQ,CAAC,IAAIA,OAAM,KAAK,IAAI,IAAI,CAAC,IAAIA,OAAM,IAAI,QAAQ,CAAC;AAAA,QACvE;AACA,gBAAQ,KAAK;AAAA,MACf;AAAA,IACF,CAAC;AAED,SAAK,GAAG,SAAS,MAAM;AACrB,cAAQ,KAAK,GAAGA,OAAM,IAAI,QAAQ,CAAC,IAAIA,OAAM,KAAK,IAAI,IAAI,CAAC,IAAIA,OAAM,IAAI,QAAQ,CAAC,EAAE;AACpF,cAAQ,KAAK;AAAA,IACf,CAAC;AAAA,EACH,CAAC;AACH;AAKA,eAAsB,2BAA2B,UAA8C;AAC7F,MAAI,SAAS,WAAW,EAAG,QAAO;AAElC,QAAM,KAAK,qBAAqB;AAChC,QAAM,QAAQ,SAAS;AAEvB,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAIA,OAAM,KAAK,cAAc,KAAK,WAAW,QAAQ,IAAI,MAAM,EAAE,KAAK,CAAC;AAC/E,UAAQ,IAAI,EAAE;AAEd,MAAI,eAAe;AACnB,QAAM,iBAA2B,CAAC;AAElC,WAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,UAAM,UAAU,MAAM,oBAAoB,SAAS,CAAC,GAAG,IAAI,GAAG,KAAK;AACnE,QAAI,SAAS;AACX;AAAA,IACF,OAAO;AACL,qBAAe,KAAK,SAAS,CAAC,EAAE,IAAI;AAAA,IACtC;AAAA,EACF;AAEA,UAAQ,IAAI,EAAE;AAEd,MAAI,eAAe,WAAW,GAAG;AAC/B,IAAAK,SAAQ,QAAQ,OAAO,KAAK,iCAAiC;AAC7D,WAAO;AAAA,EACT,WAAW,eAAe,GAAG;AAC3B,IAAAA,SAAQ,KAAK,GAAG,YAAY,IAAI,KAAK,8BAA8B,eAAe,KAAK,IAAI,CAAC,EAAE;AAC9F,WAAO;AAAA,EACT,OAAO;AACL,IAAAA,SAAQ,MAAM,8BAA8B,eAAe,KAAK,IAAI,CAAC,EAAE;AACvE,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,uBAAuB,UAAyB,CAAC,GAAqB;AAE1F,QAAM,YAAY,aAAa,IAAI,WAAW,KAAK;AACnD,MAAI,CAAC,QAAQ,SAAU,KAAK,IAAI,IAAI,YAAa,0BAA0B;AACzE,WAAO;AAAA,EACT;AAEA,eAAa,IAAI,aAAa,KAAK,IAAI,CAAC;AAGxC,QAAM,UAAUN,eAAc,yBAAyB;AACvD,UAAQ,MAAM;AAEd,QAAM,WAAW,MAAM,oBAAoB;AAAA,IACzC,qBAAqB,QAAQ;AAAA,EAC/B,CAAC;AAED,UAAQ,KAAK;AAEb,UAAQ,IAAIC,OAAM,IAAI,WAAW,SAAS,MAAM,sBAAsB,CAAC;AAEvE,MAAI,SAAS,WAAW,GAAG;AACzB,YAAQ,IAAIA,OAAM,MAAM,sCAAiC,CAAC;AAC1D,WAAO;AAAA,EACT;AAGA,MAAI,QAAQ,cAAc,aAAa,IAAI,YAAY,GAAG;AACxD,WAAO,2BAA2B,QAAQ;AAAA,EAC5C;AAGA,UAAQ,IAAI,EAAE;AACd,EAAAK,SAAQ,IAAI,6BAAsB;AAClC,UAAQ,IAAI,EAAE;AAEd,aAAW,OAAO,UAAU;AAC1B,YAAQ;AAAA,MACN,KAAKL,OAAM,OAAO,QAAG,CAAC,IAAIA,OAAM,KAAK,IAAI,IAAI,CAAC,KAC3CA,OAAM,IAAI,IAAI,OAAO,CAAC,WAAMA,OAAM,MAAM,IAAI,MAAM,CAAC;AAAA,IACxD;AAAA,EACF;AACA,UAAQ,IAAI,EAAE;AAGd,QAAM,eAAe,MAAME;AAAA,IACzB,GAAGF,OAAM,MAAM,GAAG,CAAC,+BAA+BA,OAAM,IAAI,OAAO,CAAC;AAAA,EACtE;AAEA,MAAI,cAAc;AAChB,UAAM,UAAU,MAAM,2BAA2B,QAAQ;AAEzD,QAAI,SAAS;AACX,YAAM,aAAa,MAAME;AAAA,QACvB,GAAGF,OAAM,MAAM,GAAG,CAAC,mCAAmCA,OAAM,IAAI,OAAO,CAAC;AAAA,MAC1E;AACA,UAAI,YAAY;AACd,qBAAa,IAAI,cAAc,IAAI;AACnC,QAAAK,SAAQ,KAAK,sBAAsB;AAAA,MACrC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAGA,QAAM,eAAe,MAAMH;AAAA,IACzB,GAAGF,OAAM,MAAM,GAAG,CAAC,mCAAmCA,OAAM,IAAI,OAAO,CAAC;AAAA,EAC1E;AAEA,MAAI,cAAc;AAChB,UAAM,UAAU,aAAa,IAAI,iBAAiB,KAAK,CAAC;AACxD,eAAW,OAAO,UAAU;AAC1B,UAAI,IAAI,QAAQ;AACd,gBAAQ,IAAI,IAAI,IAAI,IAAI;AAAA,MAC1B;AAAA,IACF;AACA,iBAAa,IAAI,mBAAmB,OAAO;AAC3C,IAAAK,SAAQ,KAAK,yDAAyD;AAAA,EACxE;AAEA,SAAO;AACT;AAKO,SAAS,0BAAgC;AAC9C,eAAa,MAAM;AACnB,EAAAA,SAAQ,QAAQ,2BAA2B;AAC7C;;;ACldA,OAAOC,YAAW;AAClB,OAAOC,WAAU;AACjB,OAAOC,cAAa;AACpB,OAAOC,aAAY;AAKnB,IAAM,eAAe,IAAIC,MAGtB;AAAA,EACD,aAAa;AAAA,EACb,gBAAgB;AAClB,CAAC;AAKM,SAAS,oBAAmC;AACjD,MAAI;AAEF,UAAM,cAAc;AACpB,WAAO,YAAY,WAAW;AAAA,EAChC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAsBC,sBAA6C;AAEjE,QAAM,YAAY,aAAa,IAAI,WAAW,KAAK;AACnD,QAAM,gBAAgB,aAAa,IAAI,eAAe;AAEtD,MAAI,iBAAkB,KAAK,IAAI,IAAI,YAAa,sBAAsB;AACpE,WAAO;AAAA,EACT;AAGA,MAAI;AACF,UAAM,QAAQ,MAAM,OAAO,OAAO;AAClC,WAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,YAAM,MAAM,MAAM;AAAA,QAChB,8BAA8B,YAAY;AAAA,QAC1C,EAAE,SAAS,IAAK;AAAA,QAChB,CAAC,QAAa;AACZ,cAAI,OAAO;AACX,cAAI,GAAG,QAAQ,CAAC,UAAkB;AAAE,oBAAQ;AAAA,UAAO,CAAC;AACpD,cAAI,GAAG,OAAO,MAAM;AAClB,gBAAI;AACF,oBAAM,OAAO,KAAK,MAAM,IAAI;AAC5B,oBAAM,UAAU,KAAK,WAAW;AAChC,kBAAI,SAAS;AACX,6BAAa,IAAI,iBAAiB,OAAO;AACzC,6BAAa,IAAI,aAAa,KAAK,IAAI,CAAC;AAAA,cAC1C;AACA,sBAAQ,OAAO;AAAA,YACjB,QAAQ;AACN,sBAAQ,iBAAiB,IAAI;AAAA,YAC/B;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AACA,UAAI,GAAG,SAAS,MAAM,QAAQ,iBAAiB,IAAI,CAAC;AACpD,UAAI,GAAG,WAAW,MAAM;AAAE,YAAI,QAAQ;AAAG,gBAAQ,iBAAiB,IAAI;AAAA,MAAG,CAAC;AAAA,IAC5E,CAAC;AAAA,EACH,QAAQ;AACN,WAAO,iBAAiB;AAAA,EAC1B;AACF;AAKA,eAAsB,iBAInB;AACD,QAAM,iBAAiB,kBAAkB;AACzC,MAAI,CAAC,gBAAgB;AACnB,WAAO,EAAE,WAAW,OAAO,gBAAgB,MAAM,eAAe,KAAK;AAAA,EACvE;AAEA,QAAM,gBAAgB,MAAMA,oBAAmB;AAC/C,QAAM,YAAY,CAAC,EAAE,iBAAiBC,QAAO,GAAG,eAAe,cAAc;AAE7E,SAAO,EAAE,WAAW,gBAAgB,cAAc;AACpD;AAKO,SAAS,mBAA2B;AACzC,SAAO,YAAY,mBAAmB,IAAI,OAAK,GAAG,CAAC,SAAS,EAAE,KAAK,GAAG,CAAC;AACzE;AAKA,eAAsB,mBAAkC;AACtD,QAAM,EAAE,WAAW,gBAAgB,cAAc,IAAI,MAAM,eAAe;AAE1E,MAAI,CAAC,eAAgB;AAGrB,EAAAC,SAAQ,IAAI,gCAAyB,cAAc,EAAE;AAGrD,MAAI,aAAa,eAAe;AAC9B,IAAAA,SAAQ,KAAK,qBAAqBC,OAAM,IAAI,cAAc,CAAC,WAAMA,OAAM,MAAM,aAAa,CAAC,EAAE;AAC7F,IAAAD,SAAQ,KAAK,QAAQC,OAAM,KAAK,iBAAiB,CAAC,CAAC,EAAE;AACrD,YAAQ,IAAI,EAAE;AAAA,EAChB;AACF;;;AJzGA,IAAI,cAAc;AAkBX,IAAM,mBAAN,MAAuB;AAAA,EAG5B,YAAY,UAAmC,CAAC,GAAG;AACjD,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAM,UAA0B;AAE9B,aAAS,MAAM,KAAK,WAAW,oBAAoB,YAAY;AAE7D,UAAI,CAAC,aAAa;AAChB,sBAAc;AACd,cAAM,KAAK,gBAAgB;AAAA,MAC7B;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,kBAAiC;AAE7C,YAAQ,IAAI,OAAOC,OAAM,aAAa,KAAK,iBAAiB,CAAC;AAG7D,UAAM,UAAU,kBAAkB;AAClC,QAAI,SAAS;AACX,cAAQ,IAAIA,OAAM,IAAI,kCAA2B,OAAO,EAAE,CAAC;AAAA,IAC7D;AAGA,SAAK,cAAc;AAGnB,YAAQ,IAAIA,OAAM,QAAQ,KAAK,YAAY;AAAA,CAAI,CAAC;AAGhD,QAAI,KAAK,QAAQ,iBAAiB,OAAO;AACvC,UAAI;AACF,cAAM,uBAAuB;AAAA,UAC3B,YAAY,KAAK,QAAQ;AAAA,UACzB,qBAAqB,KAAK,QAAQ;AAAA,UAClC,OAAO;AAAA;AAAA,QACT,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,gBAAQ,IAAIA,OAAM,IAAI,wBAAwB,GAAG,GAAG;AAAA,MACtD;AAAA,IACF;AAGA,QAAI,KAAK,QAAQ,kBAAkB,OAAO;AACxC,YAAM,wBAAwB;AAAA,QAC5B,aAAa,KAAK,QAAQ;AAAA,MAC5B,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEQ,gBAAsB;AAC5B,UAAM,KAAK,UAAQ,IAAI;AACvB,UAAM,OAAO,UAAQ,MAAM;AAE3B,UAAM,MAAM,QAAQ,IAAI;AACxB,UAAM,SAAS,KAAK,KAAK,KAAK,OAAO,OAAO;AAC5C,UAAM,eAAe,KAAK,KAAK,KAAK,OAAO,aAAa;AAExD,UAAM,QAAQ,GAAG,WAAW,MAAM;AAClC,UAAM,cAAc,GAAG,WAAW,YAAY;AAE9C,QAAI,SAAS,aAAa;AACxB,cAAQ,IAAIA,OAAM,KAAK,gCAAyB,CAAC;AAEjD,UAAI,OAAO;AACT,gBAAQ,IAAIA,OAAM,MAAM,uCAAkC,CAAC;AAAA,MAC7D,OAAO;AACL,gBAAQ,IAAIA,OAAM,OAAO,uCAAkC,CAAC;AAAA,MAC9D;AAEA,UAAI,aAAa;AACf,gBAAQ,IAAIA,OAAM,MAAM,uCAAkC,CAAC;AAAA,MAC7D,OAAO;AACL,gBAAQ,IAAIA,OAAM,OAAO,iCAA4B,CAAC;AAAA,MACxD;AAEA,cAAQ,IAAIA,OAAM,IAAI,uEAAwD,CAAC;AAC/E,cAAQ,IAAIA,OAAM,IAAI,0DAAqD,CAAC;AAAA,IAC9E;AAAA,EACF;AACF;AAKO,SAAS,uBAA6B;AAC3C,gBAAc;AAChB;;;AKxHO,SAAS,UAAyC,QAAW,QAAuB;AACzF,QAAM,SAAS,EAAE,GAAG,OAAO;AAE3B,aAAW,OAAO,QAAQ;AACxB,QAAI,OAAO,GAAG,MAAM,OAAW;AAG/B,QAAI,MAAM,QAAQ,OAAO,GAAG,CAAC,GAAG;AAC9B,aAAO,GAAG,IAAI,OAAO,GAAG;AAAA,IAC1B,WAES,OAAO,GAAG,KAAK,OAAO,OAAO,GAAG,MAAM,YAAY,CAAC,MAAM,QAAQ,OAAO,GAAG,CAAC,GAAG;AACtF,YAAM,cAAc,OAAO,GAAG;AAC9B,UAAI,eAAe,OAAO,gBAAgB,YAAY,CAAC,MAAM,QAAQ,WAAW,GAAG;AACjF,eAAO,GAAG,IAAI,UAAU,aAAa,OAAO,GAAG,CAAQ;AAAA,MACzD,OAAO;AACL,eAAO,GAAG,IAAI,OAAO,GAAG;AAAA,MAC1B;AAAA,IACF,OAEK;AACH,aAAO,GAAG,IAAI,OAAO,GAAG;AAAA,IAC1B;AAAA,EACF;AAEA,SAAO;AACT;;;ACgEO,SAAS,qBACd,UAAiC,CAAC,GACtB;AAEZ,QAAM,WAAW,YAAY,QAAQ,iBAAiB;AACtD,QAAM,SAAS,UAAU;AACzB,QAAM,UAAUC,YAAW;AAG3B,QAAM,aAAyB;AAAA,IAC7B,iBAAiB;AAAA,IACjB,eAAe;AAAA;AAAA,IAGf,GAAI,iBAAiB;AAAA,MACnB,QAAQ;AAAA,MACR,SAAS;AAAA,MACT;AAAA;AAAA,MAEA,iBAAiB,YAAY;AAC3B,eAAO;AAAA,MACT;AAAA,IACF;AAAA;AAAA,IAGA,GAAI,CAAC,iBAAiB,CAAC,SAAS;AAAA,MAC9B,QAAQ;AAAA,IACV;AAAA;AAAA,IAGA,KAAK;AAAA,MACH,uBAAuB;AAAA,MACvB,qBAAqB;AAAA,MACrB,sBAAsB;AAAA;AAAA,MAEtB,yBAAyB;AAAA,MACzB,GAAG,QAAQ;AAAA,IACb;AAAA;AAAA,IAGA,QAAQ;AAAA,MACN,aAAa;AAAA,IACf;AAAA;AAAA,IAGA,MAAM,UAAU;AACd,YAAM,UAA2E;AAAA,QAC/E;AAAA,UACE,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,EAAE,KAAK,+BAA+B,OAAO,IAAI;AAAA,YACjD,EAAE,KAAK,gCAAgC,OAAO,eAAe;AAAA,YAC7D,EAAE,KAAK,gCAAgC,OAAO,+BAA+B;AAAA,UAC/E;AAAA,QACF;AAAA,MACF;AAGA,UAAI,QAAQ,mBAAmB,QAAQ,gBAAgB,SAAS,GAAG;AACjE,cAAM,iBAAiB,QAAQ,gBAAgB,SAAS,GAAG,IACvD,MACA,UAAU,QAAQ,gBAAgB,KAAK,GAAG,CAAC;AAE/C,gBAAQ,KAAK;AAAA,UACX,QAAQ;AAAA,UACR,SAAS;AAAA;AAAA,YAEP,EAAE,KAAK,2BAA2B,OAAO,mBAAmB,cAAc,GAAG;AAAA;AAAA;AAAA,YAG7E,GAAI,QAAQ,gBAAgB,SAAS,GAAG,IACpC,CAAC,IACD,CAAC,EAAE,KAAK,mBAAmB,OAAO,aAAa,CAAC;AAAA,UAEtD;AAAA,QACF,CAAC;AAAA,MACH;AAGA,YAAM,cAAc,QAAQ,UAAU,MAAM,QAAQ,QAAQ,IAAI,CAAC;AACjE,aAAO,CAAC,GAAG,SAAS,GAAG,WAAW;AAAA,IACpC;AAAA;AAAA,IAGA,GAAI,QAAQ,YAAY;AAAA,MACtB,UAAU,QAAQ;AAAA,IACpB;AAAA;AAAA;AAAA,IAIA,MAAM,YAAY;AAChB,YAAM,gBAAgB;AAAA;AAAA,QAEpB;AAAA,UACE,QAAQ;AAAA,UACR,aAAa;AAAA,UACb,WAAW;AAAA,QACb;AAAA;AAAA,QAEA;AAAA,UACE,QAAQ;AAAA,UACR,aAAa;AAAA,UACb,WAAW;AAAA,QACb;AAAA,MACF;AAGA,YAAM,gBAAgB,QAAQ,YAAY,MAAM,QAAQ,UAAU,IAAI,CAAC;AACvE,aAAO,CAAC,GAAG,eAAe,GAAG,aAAa;AAAA,IAC5C;AAAA;AAAA,IAGA,mBAAmB;AAAA,MACjB,GAAG;AAAA,MACH,GAAI,QAAQ,qBAAqB,CAAC;AAAA,IACpC;AAAA;AAAA;AAAA,IAIA,WAAW,QAAQ,aAAa,CAAC;AAAA;AAAA,IAGjC,cAAc;AAAA;AAAA,MAEZ,GAAI,CAAC,SAAS;AAAA,QACZ,wBAAwB;AAAA,UACtB,GAAG;AAAA,UACH,GAAI,QAAQ,0BAA0B,CAAC;AAAA,QACzC;AAAA,MACF;AAAA;AAAA,MAEA,GAAI,SAAS;AAAA,QACX,aAAa;AAAA,MACf;AAAA;AAAA,MAEA,GAAG,QAAQ;AAAA,IACb;AAAA;AAAA,IAGA,SAAS,CAAC,QAAuB,mBAA4E;AAC3G,YAAM,EAAE,UAAU,IAAI,IAAI;AAG1B,UAAI,OAAO,CAAC,UAAU;AACpB,YAAI,CAAC,OAAO,SAAS;AACnB,iBAAO,UAAU,CAAC;AAAA,QACpB;AACA,eAAO,QAAQ;AAAA,UACb,IAAI,iBAAiB;AAAA,YACnB,cAAc,QAAQ;AAAA,YACtB,YAAY,QAAQ;AAAA,YACpB,qBAAqB,QAAQ;AAAA,YAC7B,eAAe,QAAQ;AAAA,YACvB,aAAa,QAAQ;AAAA,UACvB,CAAC;AAAA,QACH;AAAA,MACF;AAGA,UAAI,KAAK;AACP,eAAO,eAAe;AAAA,UACpB,GAAG,OAAO;AAAA,UACV,wBAAwB;AAAA,UACxB,mBAAmB;AAAA,UACnB,aAAa;AAAA;AAAA,QACf;AAAA,MACF;AAGA,aAAO,QAAQ;AAAA,QACb,MAAM;AAAA,QACN,mBAAmB,CAAC;AAAA,MACtB;AAGA,UAAI,CAAC,YAAY,iBAAiB,CAAC,KAAK;AACtC,8BAAsB,MAAM;AAAA,MAC9B;AAGA,UAAI,QAAQ,SAAS;AACnB,eAAO,QAAQ,QAAQ,QAAQ,cAAc;AAAA,MAC/C;AAEA,aAAO;AAAA,IACT;AAAA,EACF;AAGA,MAAI,cAAc,UAAU,YAAY,OAAO;AAG/C,SAAQ,YAAoB;AAC5B,SAAQ,YAAoB;AAC5B,SAAQ,YAAoB;AAC5B,SAAQ,YAAoB;AAC5B,SAAQ,YAAoB;AAC5B,SAAQ,YAAoB;AAC5B,SAAQ,YAAoB;AAC5B,SAAQ,YAAoB;AAC5B,SAAQ,YAAoB;AAK5B,MAAI,QAAQ,KAAK;AACf,kBAAc,QAAQ,aAAa,QAAQ,GAAG;AAAA,EAChD;AACA,SAAQ,YAAoB;AAE5B,SAAO;AACT;;;ACtSO,IAAM,sBAAN,MAA0B;AAAA,EAI/B,YAAY,UAAkB,cAAc,UAAkB,iBAAiB;AAC7E,SAAK,UAAU,QAAQ,QAAQ,OAAO,EAAE;AACxC,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,MAAc,YAAe,UAAkB,QAAsD;AACnG,QAAI,MAAM,GAAG,KAAK,OAAO,GAAG,QAAQ;AAEpC,QAAI,QAAQ;AACV,YAAM,eAAe,IAAI,gBAAgB;AACzC,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,qBAAa,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,MACrC;AACA,YAAM,GAAG,GAAG,IAAI,aAAa,SAAS,CAAC;AAAA,IACzC;AAEA,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,KAAK,OAAO;AAEnE,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,KAAK;AAAA,QAChC,QAAQ;AAAA,QACR,SAAS;AAAA,UACP,QAAQ;AAAA,UACR,cAAc;AAAA,QAChB;AAAA,QACA,QAAQ,WAAW;AAAA,MACrB,CAAC;AAED,UAAI,CAAC,SAAS,IAAI;AAChB,cAAM,IAAI,MAAM,cAAc,SAAS,MAAM,KAAK,SAAS,UAAU,EAAE;AAAA,MACzE;AAEA,aAAO,MAAM,SAAS,KAAK;AAAA,IAC7B,UAAE;AACA,mBAAa,SAAS;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,OAAO,OAAe,UAAyB,CAAC,GAA4B;AAChF,UAAM,EAAE,QAAQ,GAAG,SAAS,IAAI;AAEhC,UAAM,SAA0C,EAAE,GAAG,OAAO,MAAM;AAClE,QAAI,UAAU;AACZ,aAAO,WAAW;AAAA,IACpB;AAEA,UAAM,OAAO,MAAM,KAAK,YAA+B,qBAAqB,MAAM;AAElF,UAAM,UAAU,KAAK,YAAY,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC;AAE/D,WAAO,QAAQ,IAAI,CAAC,UAAU;AAAA,MAC5B,OAAO,KAAK,SAAS;AAAA,MACrB,SAAS,KAAK,WAAW,KAAK,WAAW;AAAA,MACzC,KAAK,KAAK,OAAO;AAAA,MACjB,OAAO,KAAK,SAAS;AAAA,MACrB,UAAU,KAAK,YAAY;AAAA,IAC7B,EAAE;AAAA,EACJ;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,QAAQ,OAAiD;AAC7D,WAAO,KAAK,YAAY,mBAAmB,EAAE,MAAM,CAAC;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA,EAKA,eAA0B;AACxB,WAAO;AAAA,MACL,YAAY;AAAA,QACV,kBAAkB;AAAA,UAChB,KAAK,GAAG,KAAK,OAAO;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAGA,IAAI,gBAA4C;AAEhD,SAAS,YAAiC;AACxC,MAAI,CAAC,eAAe;AAClB,oBAAgB,IAAI,oBAAoB;AAAA,EAC1C;AACA,SAAO;AACT;AAWA,eAAsB,OAAO,OAAe,UAAyB,CAAC,GAA4B;AAChG,SAAO,UAAU,EAAE,OAAO,OAAO,OAAO;AAC1C;AAWA,eAAsB,QAAQ,OAAe,QAAgB,GAAoB;AAC/E,QAAM,UAAU,MAAM,OAAO,OAAO,EAAE,MAAM,CAAC;AAE7C,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO,+BAA+B,KAAK;AAAA,EAC7C;AAEA,QAAM,SAAmB,CAAC;AAE1B,UAAQ,QAAQ,CAAC,GAAG,MAAM;AACxB,WAAO,KAAK,MAAM,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE;AACrC,WAAO,KAAK,EAAE,OAAO;AACrB,QAAI,EAAE,KAAK;AACT,aAAO,KAAK,wBAAiB,EAAE,GAAG,EAAE;AAAA,IACtC;AACA,WAAO,KAAK,EAAE;AAAA,EAChB,CAAC;AAED,SAAO,OAAO,KAAK,IAAI;AACzB;AAKA,eAAsB,QAAQ,OAAiD;AAC7E,SAAO,UAAU,EAAE,QAAQ,KAAK;AAClC;AAKO,SAAS,eAA0B;AACxC,SAAO,UAAU,EAAE,aAAa;AAClC;","names":["NextResponse","result","jsx","isStaticBuild","isDev","isStaticBuild","getSiteUrl","chalk","consola","isDev","text","consola","chalk","spawn","Conf","consola","createRequire","join","createInterface","Conf","SPINNER_FRAMES","join","createRequire","createSpinner","chalk","text","askConfirmation","createInterface","spawn","consola","chalk","Conf","consola","semver","Conf","fetchLatestVersion","semver","consola","chalk","chalk","getSiteUrl"]}
|