olova 2.0.39 → 2.0.40

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/index.d.ts CHANGED
@@ -76,8 +76,9 @@ interface RouterProps {
76
76
  initialComponent?: React.ComponentType;
77
77
  initialParams?: Record<string, string>;
78
78
  onRouteChange?: (metadata: Metadata | undefined) => void;
79
+ children?: React.ReactNode;
79
80
  }
80
- declare function Router({ url, initialComponent, initialParams, onRouteChange }: RouterProps): react_jsx_runtime.JSX.Element | null;
81
+ declare function Router({ url, initialComponent, initialParams, onRouteChange, children }: RouterProps): react_jsx_runtime.JSX.Element | null;
81
82
  declare function Link({ href, children, ...props }: {
82
83
  href: string;
83
84
  children: ReactNode;
package/dist/router.js CHANGED
@@ -130,12 +130,13 @@ async function loadRoute(path) {
130
130
  console.warn(`[Router] No match for: ${path}`);
131
131
  return null;
132
132
  }
133
- function Router({ url, initialComponent, initialParams, onRouteChange }) {
133
+ function Router({ url, initialComponent, initialParams, onRouteChange, children }) {
134
134
  const [path, setPath] = useState(() => normalizePath(url || (typeof window !== "undefined" ? window.location.pathname : "/")));
135
135
  const [Component, setComponent] = useState(() => initialComponent || null);
136
136
  const [params, setParams] = useState(() => initialParams || {});
137
137
  const hasHydrated = React.useRef(false);
138
138
  const isInitialRender = React.useRef(true);
139
+ const [isLoading, setIsLoading] = useState(!initialComponent);
139
140
  useEffect(() => {
140
141
  if (typeof window === "undefined") return;
141
142
  const handleNavigation = () => {
@@ -155,10 +156,12 @@ function Router({ url, initialComponent, initialParams, onRouteChange }) {
155
156
  console.log(`[Router] Hydration skipped for: ${path}`);
156
157
  hasHydrated.current = true;
157
158
  isInitialRender.current = false;
159
+ setIsLoading(false);
158
160
  return;
159
161
  }
160
162
  let isCancelled = false;
161
163
  const load = async () => {
164
+ console.log(`[Router] Loading route: ${path}`);
162
165
  const result = await loadRoute(path);
163
166
  if (!isCancelled) {
164
167
  if (result) {
@@ -185,6 +188,8 @@ function Router({ url, initialComponent, initialParams, onRouteChange }) {
185
188
  }
186
189
  }
187
190
  isInitialRender.current = false;
191
+ setIsLoading(false);
192
+ hasHydrated.current = true;
188
193
  }
189
194
  };
190
195
  load();
@@ -192,15 +197,15 @@ function Router({ url, initialComponent, initialParams, onRouteChange }) {
192
197
  isCancelled = true;
193
198
  };
194
199
  }, [path, onRouteChange]);
200
+ if (isLoading && isInitialRender.current) {
201
+ return null;
202
+ }
195
203
  if (!Component) {
196
204
  if (initialComponent) {
197
205
  const InitComp = initialComponent;
198
206
  return /* @__PURE__ */ jsx(RouterContext.Provider, { value: { params, path }, children: /* @__PURE__ */ jsx(InitComp, { ...params }) });
199
207
  }
200
- if (!isInitialRender.current) {
201
- return /* @__PURE__ */ jsx("div", { children: "Loading..." });
202
- }
203
- return null;
208
+ return /* @__PURE__ */ jsx("div", { children: "Loading..." });
204
209
  }
205
210
  return /* @__PURE__ */ jsx(RouterContext.Provider, { value: { params, path }, children: /* @__PURE__ */ jsx(Component, { ...params }) });
206
211
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client/router.tsx"],"sourcesContent":["import React, { useState, useEffect, createContext, useContext, type ReactNode } from 'react';\n\n// @ts-ignore - Virtual module provided by Olova Vite plugin\nimport { routes } from 'virtual:olova-routes';\n\nconst RouterContext = createContext<{ params: Record<string, string>, path: string }>({ params: {}, path: '/' });\n\nexport function useParams() {\n return useContext(RouterContext).params;\n}\n\nexport function usePath() {\n return useContext(RouterContext).path;\n}\n\n/**\n * Returns the current pathname (without query string or hash)\n * Similar to Next.js usePathname hook\n */\nexport function usePathname(): string {\n const [pathname, setPathname] = useState(() => {\n if (typeof window === 'undefined') return '/';\n return window.location.pathname;\n });\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const handleNavigation = () => {\n setPathname(window.location.pathname);\n };\n\n window.addEventListener('popstate', handleNavigation);\n window.addEventListener('pushstate', handleNavigation);\n\n return () => {\n window.removeEventListener('popstate', handleNavigation);\n window.removeEventListener('pushstate', handleNavigation);\n };\n }, []);\n\n return pathname;\n}\n\n/**\n * A read-only interface for URLSearchParams\n * Similar to Next.js useSearchParams hook\n */\ninterface ReadonlyURLSearchParams {\n get(name: string): string | null;\n getAll(name: string): string[];\n has(name: string): boolean;\n keys(): IterableIterator<string>;\n values(): IterableIterator<string>;\n entries(): IterableIterator<[string, string]>;\n forEach(callback: (value: string, key: string, parent: URLSearchParams) => void): void;\n toString(): string;\n size: number;\n}\n\n/**\n * Returns the current URL search parameters\n * Similar to Next.js useSearchParams hook\n * \n * Example usage:\n * const searchParams = useSearchParams();\n * const query = searchParams.get('q'); // ?q=hello -> 'hello'\n * const tags = searchParams.getAll('tag'); // ?tag=a&tag=b -> ['a', 'b']\n */\nexport function useSearchParams(): ReadonlyURLSearchParams {\n const [searchParams, setSearchParams] = useState<URLSearchParams>(() => {\n if (typeof window === 'undefined') return new URLSearchParams();\n return new URLSearchParams(window.location.search);\n });\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const handleNavigation = () => {\n setSearchParams(new URLSearchParams(window.location.search));\n };\n\n window.addEventListener('popstate', handleNavigation);\n window.addEventListener('pushstate', handleNavigation);\n\n return () => {\n window.removeEventListener('popstate', handleNavigation);\n window.removeEventListener('pushstate', handleNavigation);\n };\n }, []);\n\n // Return a readonly interface that wraps URLSearchParams\n return {\n get: (name: string) => searchParams.get(name),\n getAll: (name: string) => searchParams.getAll(name),\n has: (name: string) => searchParams.has(name),\n keys: () => searchParams.keys(),\n values: () => searchParams.values(),\n entries: () => searchParams.entries(),\n forEach: (callback) => searchParams.forEach(callback),\n toString: () => searchParams.toString(),\n get size() { return Array.from(searchParams.keys()).length; }\n };\n}\n\n// Helper to normalize paths\nconst normalizePath = (path: string) => {\n let p = path.split('?')[0].split('#')[0];\n if (p.length > 1 && p.endsWith('/')) p = p.slice(0, -1);\n return p || '/';\n};\n\n// Route matching with param extraction\nexport function matchRoute(path: string) {\n const normalizedPath = normalizePath(path);\n const routeKeys = Object.keys(routes);\n \n for (const route of routeKeys) {\n // Handle exact match first\n if (route === normalizedPath) {\n return { loader: routes[route], params: {}, pattern: route };\n }\n \n // Convert :param and $param to regex group\n const regexPath = route\n .replace(/:[^\\/]+/g, '([^/]+)')\n .replace(/\\$[^\\/]+/g, '([^/]+)');\n \n const regex = new RegExp(`^${regexPath}$`);\n const match = normalizedPath.match(regex);\n \n if (match) {\n const params: Record<string, string> = {};\n const paramNames = (route.match(/[:$][^\\/]+/g) || []).map(s => s.slice(1));\n paramNames.forEach((name, i) => {\n params[name] = match[i + 1];\n });\n return { loader: routes[route], params, pattern: route };\n }\n }\n return null;\n}\n\n// Metadata type - like Next.js\nexport interface Metadata {\n title?: string;\n description?: string;\n keywords?: string | string[];\n openGraph?: {\n title?: string;\n description?: string;\n url?: string;\n siteName?: string;\n images?: { url: string; width?: number; height?: number; alt?: string }[];\n type?: string;\n };\n twitter?: {\n card?: 'summary' | 'summary_large_image' | 'app' | 'player';\n site?: string;\n creator?: string;\n title?: string;\n description?: string;\n images?: string[];\n };\n robots?: string;\n canonical?: string;\n jsonLd?: object | object[];\n}\n\n// Simple markdown to HTML converter (basic support)\nfunction parseMarkdown(md: string): string {\n return md\n // Headers\n .replace(/^### (.*$)/gim, '<h3>$1</h3>')\n .replace(/^## (.*$)/gim, '<h2>$1</h2>')\n .replace(/^# (.*$)/gim, '<h1>$1</h1>')\n // Bold and italic\n .replace(/\\*\\*\\*(.*?)\\*\\*\\*/g, '<strong><em>$1</em></strong>')\n .replace(/\\*\\*(.*?)\\*\\*/g, '<strong>$1</strong>')\n .replace(/\\*(.*?)\\*/g, '<em>$1</em>')\n // Code blocks\n .replace(/```([\\s\\S]*?)```/g, '<pre><code>$1</code></pre>')\n .replace(/`(.*?)`/g, '<code>$1</code>')\n // Links\n .replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<a href=\"$2\">$1</a>')\n // Line breaks and paragraphs\n .replace(/\\n\\n/g, '</p><p>')\n .replace(/\\n/g, '<br>')\n // Wrap in paragraph\n .replace(/^(.*)$/, '<p>$1</p>');\n}\n\n// React component for rendering HTML content\nfunction HtmlContent({ html }: { html: string }) {\n return React.createElement('div', { \n dangerouslySetInnerHTML: { __html: html },\n className: 'olova-html-content'\n });\n}\n\n// React component for rendering Markdown content\nfunction MarkdownContent({ markdown }: { markdown: string }) {\n const html = parseMarkdown(markdown);\n return React.createElement('article', { \n dangerouslySetInnerHTML: { __html: html },\n className: 'olova-markdown-content'\n });\n}\n\nexport async function loadRoute(path: string) {\n const match = matchRoute(path);\n if (match) {\n console.log(`[Router] Loading route: ${path} (pattern: ${match.pattern})`);\n const module = await match.loader();\n \n // Handle HTML files\n if (module.__isHtml) {\n return { \n module: {\n default: () => HtmlContent({ html: module.__rawHtml }),\n },\n params: match.params,\n metadata: undefined\n };\n }\n \n // Handle Markdown files\n if (module.__isMd) {\n return { \n module: {\n default: () => MarkdownContent({ markdown: module.default }),\n },\n params: match.params,\n metadata: undefined\n };\n }\n \n return { \n module,\n params: match.params,\n metadata: module.metadata as Metadata | undefined\n };\n }\n console.warn(`[Router] No match for: ${path}`);\n return null;\n}\n\ninterface RouterProps {\n url?: string;\n initialComponent?: React.ComponentType;\n initialParams?: Record<string, string>;\n onRouteChange?: (metadata: Metadata | undefined) => void;\n}\n\nexport function Router({ url, initialComponent, initialParams, onRouteChange }: RouterProps) {\n const [path, setPath] = useState(() => normalizePath(url || (typeof window !== 'undefined' ? window.location.pathname : '/')));\n // CRITICAL: Initialize with initialComponent to match SSG output - no Loading state during hydration\n const [Component, setComponent] = useState<React.ComponentType | null>(() => initialComponent || null);\n const [params, setParams] = useState<Record<string, string>>(() => initialParams || {});\n const hasHydrated = React.useRef(false);\n const isInitialRender = React.useRef(true);\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const handleNavigation = () => {\n const newPath = normalizePath(window.location.pathname);\n console.log(`[Router] Navigation event: ${newPath}`);\n setPath(newPath);\n };\n\n window.addEventListener('popstate', handleNavigation);\n window.addEventListener('pushstate', handleNavigation);\n\n return () => {\n window.removeEventListener('popstate', handleNavigation);\n window.removeEventListener('pushstate', handleNavigation);\n };\n }, []);\n\n useEffect(() => {\n // Skip loading on mount if we already have the initial component for the current path\n if (!hasHydrated.current && initialComponent && path === normalizePath(url || '')) {\n console.log(`[Router] Hydration skipped for: ${path}`);\n hasHydrated.current = true;\n isInitialRender.current = false;\n return;\n }\n\n let isCancelled = false;\n const load = async () => {\n const result = await loadRoute(path);\n if (!isCancelled) {\n if (result) {\n setComponent(() => result.module.default);\n setParams(result.params);\n // Call onRouteChange with new metadata for SEO updates\n if (onRouteChange) {\n onRouteChange(result.metadata);\n }\n } else {\n // Try to load custom 404 page\n const fallbackResult = await loadRoute('/404');\n if (fallbackResult) {\n console.log('[Router] Serving custom 404 page');\n setComponent(() => fallbackResult.module.default);\n setParams(fallbackResult.params);\n if (onRouteChange) {\n onRouteChange(fallbackResult.metadata);\n }\n } else {\n // Default 404 if no custom page exists\n setComponent(() => () => <div>404 Not Found</div>);\n setParams({});\n if (onRouteChange) {\n onRouteChange(undefined);\n }\n }\n }\n isInitialRender.current = false;\n }\n };\n\n load();\n return () => { isCancelled = true; };\n }, [path, onRouteChange]);\n\n // During initial render with initialComponent, use it directly to match SSG\n // Only show Loading... for subsequent client-side navigations when Component is null\n if (!Component) {\n // If we have initialComponent, use it (shouldn't happen but safety)\n if (initialComponent) {\n const InitComp = initialComponent;\n return (\n <RouterContext.Provider value={{ params, path }}>\n <InitComp {...params} />\n </RouterContext.Provider>\n );\n }\n // Only show loading for pure client-side navigation (not hydration)\n if (!isInitialRender.current) {\n return <div>Loading...</div>;\n }\n // During hydration if somehow no component, render nothing to avoid mismatch\n return null;\n }\n \n return (\n <RouterContext.Provider value={{ params, path }}>\n <Component {...params} />\n </RouterContext.Provider>\n );\n}\n\n// Link component - always uses SPA navigation (like Next.js)\n// Pre-rendered HTML is only for initial page load and SEO crawlers\nexport function Link({ href, children, ...props }: { href: string, children: ReactNode } & React.AnchorHTMLAttributes<HTMLAnchorElement>): React.ReactElement {\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n // Allow modifier keys for new tab, etc.\n if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;\n // Allow external links\n if (href.startsWith('http') || href.startsWith('//')) return;\n\n e.preventDefault();\n \n // Compare full URLs (including query strings) to allow search param changes\n const currentUrl = window.location.pathname + window.location.search;\n const targetUrl = href.startsWith('/') ? href : '/' + href;\n \n if (currentUrl === targetUrl) return;\n \n // SPA navigation - no page reload\n window.history.pushState({}, '', href);\n window.dispatchEvent(new Event('pushstate'));\n };\n\n return (\n <a href={href} onClick={handleClick} {...props}>\n {children}\n </a>\n );\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/client/router.tsx"],"sourcesContent":["import React, { useState, useEffect, createContext, useContext, type ReactNode } from 'react';\n\n// @ts-ignore - Virtual module provided by Olova Vite plugin\nimport { routes } from 'virtual:olova-routes';\n\nconst RouterContext = createContext<{ params: Record<string, string>, path: string }>({ params: {}, path: '/' });\n\nexport function useParams() {\n return useContext(RouterContext).params;\n}\n\nexport function usePath() {\n return useContext(RouterContext).path;\n}\n\n/**\n * Returns the current pathname (without query string or hash)\n * Similar to Next.js usePathname hook\n */\nexport function usePathname(): string {\n const [pathname, setPathname] = useState(() => {\n if (typeof window === 'undefined') return '/';\n return window.location.pathname;\n });\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const handleNavigation = () => {\n setPathname(window.location.pathname);\n };\n\n window.addEventListener('popstate', handleNavigation);\n window.addEventListener('pushstate', handleNavigation);\n\n return () => {\n window.removeEventListener('popstate', handleNavigation);\n window.removeEventListener('pushstate', handleNavigation);\n };\n }, []);\n\n return pathname;\n}\n\n/**\n * A read-only interface for URLSearchParams\n * Similar to Next.js useSearchParams hook\n */\ninterface ReadonlyURLSearchParams {\n get(name: string): string | null;\n getAll(name: string): string[];\n has(name: string): boolean;\n keys(): IterableIterator<string>;\n values(): IterableIterator<string>;\n entries(): IterableIterator<[string, string]>;\n forEach(callback: (value: string, key: string, parent: URLSearchParams) => void): void;\n toString(): string;\n size: number;\n}\n\n/**\n * Returns the current URL search parameters\n * Similar to Next.js useSearchParams hook\n * \n * Example usage:\n * const searchParams = useSearchParams();\n * const query = searchParams.get('q'); // ?q=hello -> 'hello'\n * const tags = searchParams.getAll('tag'); // ?tag=a&tag=b -> ['a', 'b']\n */\nexport function useSearchParams(): ReadonlyURLSearchParams {\n const [searchParams, setSearchParams] = useState<URLSearchParams>(() => {\n if (typeof window === 'undefined') return new URLSearchParams();\n return new URLSearchParams(window.location.search);\n });\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const handleNavigation = () => {\n setSearchParams(new URLSearchParams(window.location.search));\n };\n\n window.addEventListener('popstate', handleNavigation);\n window.addEventListener('pushstate', handleNavigation);\n\n return () => {\n window.removeEventListener('popstate', handleNavigation);\n window.removeEventListener('pushstate', handleNavigation);\n };\n }, []);\n\n // Return a readonly interface that wraps URLSearchParams\n return {\n get: (name: string) => searchParams.get(name),\n getAll: (name: string) => searchParams.getAll(name),\n has: (name: string) => searchParams.has(name),\n keys: () => searchParams.keys(),\n values: () => searchParams.values(),\n entries: () => searchParams.entries(),\n forEach: (callback) => searchParams.forEach(callback),\n toString: () => searchParams.toString(),\n get size() { return Array.from(searchParams.keys()).length; }\n };\n}\n\n// Helper to normalize paths\nconst normalizePath = (path: string) => {\n let p = path.split('?')[0].split('#')[0];\n if (p.length > 1 && p.endsWith('/')) p = p.slice(0, -1);\n return p || '/';\n};\n\n// Route matching with param extraction\nexport function matchRoute(path: string) {\n const normalizedPath = normalizePath(path);\n const routeKeys = Object.keys(routes);\n \n for (const route of routeKeys) {\n // Handle exact match first\n if (route === normalizedPath) {\n return { loader: routes[route], params: {}, pattern: route };\n }\n \n // Convert :param and $param to regex group\n const regexPath = route\n .replace(/:[^\\/]+/g, '([^/]+)')\n .replace(/\\$[^\\/]+/g, '([^/]+)');\n \n const regex = new RegExp(`^${regexPath}$`);\n const match = normalizedPath.match(regex);\n \n if (match) {\n const params: Record<string, string> = {};\n const paramNames = (route.match(/[:$][^\\/]+/g) || []).map(s => s.slice(1));\n paramNames.forEach((name, i) => {\n params[name] = match[i + 1];\n });\n return { loader: routes[route], params, pattern: route };\n }\n }\n return null;\n}\n\n// Metadata type - like Next.js\nexport interface Metadata {\n title?: string;\n description?: string;\n keywords?: string | string[];\n openGraph?: {\n title?: string;\n description?: string;\n url?: string;\n siteName?: string;\n images?: { url: string; width?: number; height?: number; alt?: string }[];\n type?: string;\n };\n twitter?: {\n card?: 'summary' | 'summary_large_image' | 'app' | 'player';\n site?: string;\n creator?: string;\n title?: string;\n description?: string;\n images?: string[];\n };\n robots?: string;\n canonical?: string;\n jsonLd?: object | object[];\n}\n\n// Simple markdown to HTML converter (basic support)\nfunction parseMarkdown(md: string): string {\n return md\n // Headers\n .replace(/^### (.*$)/gim, '<h3>$1</h3>')\n .replace(/^## (.*$)/gim, '<h2>$1</h2>')\n .replace(/^# (.*$)/gim, '<h1>$1</h1>')\n // Bold and italic\n .replace(/\\*\\*\\*(.*?)\\*\\*\\*/g, '<strong><em>$1</em></strong>')\n .replace(/\\*\\*(.*?)\\*\\*/g, '<strong>$1</strong>')\n .replace(/\\*(.*?)\\*/g, '<em>$1</em>')\n // Code blocks\n .replace(/```([\\s\\S]*?)```/g, '<pre><code>$1</code></pre>')\n .replace(/`(.*?)`/g, '<code>$1</code>')\n // Links\n .replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<a href=\"$2\">$1</a>')\n // Line breaks and paragraphs\n .replace(/\\n\\n/g, '</p><p>')\n .replace(/\\n/g, '<br>')\n // Wrap in paragraph\n .replace(/^(.*)$/, '<p>$1</p>');\n}\n\n// React component for rendering HTML content\nfunction HtmlContent({ html }: { html: string }) {\n return React.createElement('div', { \n dangerouslySetInnerHTML: { __html: html },\n className: 'olova-html-content'\n });\n}\n\n// React component for rendering Markdown content\nfunction MarkdownContent({ markdown }: { markdown: string }) {\n const html = parseMarkdown(markdown);\n return React.createElement('article', { \n dangerouslySetInnerHTML: { __html: html },\n className: 'olova-markdown-content'\n });\n}\n\nexport async function loadRoute(path: string) {\n const match = matchRoute(path);\n if (match) {\n console.log(`[Router] Loading route: ${path} (pattern: ${match.pattern})`);\n const module = await match.loader();\n \n // Handle HTML files\n if (module.__isHtml) {\n return { \n module: {\n default: () => HtmlContent({ html: module.__rawHtml }),\n },\n params: match.params,\n metadata: undefined\n };\n }\n \n // Handle Markdown files\n if (module.__isMd) {\n return { \n module: {\n default: () => MarkdownContent({ markdown: module.default }),\n },\n params: match.params,\n metadata: undefined\n };\n }\n \n return { \n module,\n params: match.params,\n metadata: module.metadata as Metadata | undefined\n };\n }\n console.warn(`[Router] No match for: ${path}`);\n return null;\n}\n\ninterface RouterProps {\n url?: string;\n initialComponent?: React.ComponentType;\n initialParams?: Record<string, string>;\n onRouteChange?: (metadata: Metadata | undefined) => void;\n children?: React.ReactNode;\n}\n\nexport function Router({ url, initialComponent, initialParams, onRouteChange, children }: RouterProps) {\n const [path, setPath] = useState(() => normalizePath(url || (typeof window !== 'undefined' ? window.location.pathname : '/')));\n // CRITICAL: Initialize with initialComponent to match SSG output - no Loading state during hydration\n const [Component, setComponent] = useState<React.ComponentType | null>(() => initialComponent || null);\n const [params, setParams] = useState<Record<string, string>>(() => initialParams || {});\n const hasHydrated = React.useRef(false);\n const isInitialRender = React.useRef(true);\n const [isLoading, setIsLoading] = useState(!initialComponent);\n\n useEffect(() => {\n if (typeof window === 'undefined') return;\n\n const handleNavigation = () => {\n const newPath = normalizePath(window.location.pathname);\n console.log(`[Router] Navigation event: ${newPath}`);\n setPath(newPath);\n };\n\n window.addEventListener('popstate', handleNavigation);\n window.addEventListener('pushstate', handleNavigation);\n\n return () => {\n window.removeEventListener('popstate', handleNavigation);\n window.removeEventListener('pushstate', handleNavigation);\n };\n }, []);\n\n useEffect(() => {\n // Skip loading on mount if we already have the initial component for the current path\n if (!hasHydrated.current && initialComponent && path === normalizePath(url || '')) {\n console.log(`[Router] Hydration skipped for: ${path}`);\n hasHydrated.current = true;\n isInitialRender.current = false;\n setIsLoading(false);\n return;\n }\n\n let isCancelled = false;\n const load = async () => {\n console.log(`[Router] Loading route: ${path}`);\n const result = await loadRoute(path);\n if (!isCancelled) {\n if (result) {\n setComponent(() => result.module.default);\n setParams(result.params);\n // Call onRouteChange with new metadata for SEO updates\n if (onRouteChange) {\n onRouteChange(result.metadata);\n }\n } else {\n // Try to load custom 404 page\n const fallbackResult = await loadRoute('/404');\n if (fallbackResult) {\n console.log('[Router] Serving custom 404 page');\n setComponent(() => fallbackResult.module.default);\n setParams(fallbackResult.params);\n if (onRouteChange) {\n onRouteChange(fallbackResult.metadata);\n }\n } else {\n // Default 404 if no custom page exists\n setComponent(() => () => <div>404 Not Found</div>);\n setParams({});\n if (onRouteChange) {\n onRouteChange(undefined);\n }\n }\n }\n isInitialRender.current = false;\n setIsLoading(false);\n hasHydrated.current = true;\n }\n };\n\n load();\n return () => { isCancelled = true; };\n }, [path, onRouteChange]);\n\n // During initial hydration when we don't have a component yet,\n // render null to let React hydrate the existing SSG content\n // Once component loads, React will properly update the DOM\n if (isLoading && isInitialRender.current) {\n // Return null during initial hydration - React will keep existing DOM\n return null;\n }\n\n if (!Component) {\n // If we have initialComponent, use it (shouldn't happen but safety)\n if (initialComponent) {\n const InitComp = initialComponent;\n return (\n <RouterContext.Provider value={{ params, path }}>\n <InitComp {...params} />\n </RouterContext.Provider>\n );\n }\n // Show loading for pure client-side navigation\n return <div>Loading...</div>;\n }\n \n return (\n <RouterContext.Provider value={{ params, path }}>\n <Component {...params} />\n </RouterContext.Provider>\n );\n}\n\n// Link component - always uses SPA navigation (like Next.js)\n// Pre-rendered HTML is only for initial page load and SEO crawlers\nexport function Link({ href, children, ...props }: { href: string, children: ReactNode } & React.AnchorHTMLAttributes<HTMLAnchorElement>): React.ReactElement {\n const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {\n // Allow modifier keys for new tab, etc.\n if (e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey) return;\n // Allow external links\n if (href.startsWith('http') || href.startsWith('//')) return;\n\n e.preventDefault();\n \n // Compare full URLs (including query strings) to allow search param changes\n const currentUrl = window.location.pathname + window.location.search;\n const targetUrl = href.startsWith('/') ? href : '/' + href;\n \n if (currentUrl === targetUrl) return;\n \n // SPA navigation - no page reload\n window.history.pushState({}, '', href);\n window.dispatchEvent(new Event('pushstate'));\n };\n\n return (\n <a href={href} onClick={handleClick} {...props}>\n {children}\n </a>\n );\n}"],"mappings":"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","names":[]}
package/dist/vite.js CHANGED
@@ -336,37 +336,29 @@ function generateSeoTags(metadata) {
336
336
  }
337
337
  }
338
338
 
339
- const path = window.location.pathname;
340
- loadRoute(path).then((result) => {
341
- const Component = result ? result.module.default : () => <div>404 Not Found</div>;
342
- // @ts-ignore
343
- const serverData = window.__OLOVA_DATA__ || window.$OLOVA?.$route || {};
344
- const params = serverData.params || (result ? result.params : {});
345
- const metadata = serverData.metadata || (result ? result.metadata : undefined);
346
-
347
- // Framework handles SEO automatically (like Next.js)
348
- generateSeoTags(metadata);
339
+ // Get SSG data from the server-rendered scripts
340
+ // @ts-ignore
341
+ const serverData = window.$OLOVA?.$route || {};
342
+ const path = serverData.path || window.location.pathname;
343
+ const params = serverData.params || {};
344
+ // @ts-ignore
345
+ const serverMeta = window.$OLOVA?.$meta || {};
349
346
 
350
- const app = (
351
- <React.StrictMode>
352
- <Layout>
353
- <Router url={path} initialComponent={Component} initialParams={params} onRouteChange={(newMetadata) => generateSeoTags(newMetadata)} />
354
- </Layout>
355
- </React.StrictMode>
356
- );
347
+ // Framework handles SEO automatically (like Next.js)
348
+ generateSeoTags(serverMeta);
357
349
 
358
- // Always hydrate using the document as root since we always have a shell from SSG
359
- console.log("[Olova] Hydrating document with component:", Component ? (Component.name || 'Anonymous') : "NULL");
360
-
361
- // Debug loaded route result
362
- if (result) {
363
- console.log("[Olova] Route module keys:", Object.keys(result.module));
364
- } else {
365
- console.warn("[Olova] Route result is null/undefined");
366
- }
350
+ // Hydrate immediately - Router handles component loading internally
351
+ // This ensures the initial render matches the SSG HTML exactly
352
+ const app = (
353
+ <React.StrictMode>
354
+ <Layout>
355
+ <Router url={path} initialParams={params} onRouteChange={(newMetadata) => generateSeoTags(newMetadata)} />
356
+ </Layout>
357
+ </React.StrictMode>
358
+ );
367
359
 
368
- hydrateRoot(document, app);
369
- });`;
360
+ console.log("[Olova] Hydrating document for path:", path);
361
+ hydrateRoot(document, app);`;
370
362
  const result = await transformWithEsbuild(code, "olova-client.tsx", {
371
363
  loader: "tsx",
372
364
  jsx: "automatic"
package/dist/vite.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/plugins/config.ts","../src/plugins/router.ts","../src/plugins/framework.ts","../src/plugins/virtual-html.ts","../src/plugins/hydration.ts","../src/plugins/ssg.ts","../src/plugins/utils.ts","../src/plugins/clean-url.ts","../src/plugins/auto-generate.ts","../src/plugins/error-overlay.ts","../src/plugins/index.ts","../src/plugins/terminal.ts"],"sourcesContent":["import { type Plugin } from 'vite';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\n\r\n// Terminal colors\r\nconst colors = {\r\n reset: '\\x1b[0m',\r\n bold: '\\x1b[1m',\r\n dim: '\\x1b[2m',\r\n cyan: '\\x1b[36m',\r\n green: '\\x1b[32m',\r\n white: '\\x1b[37m',\r\n};\r\n\r\n// =============================================================================\r\n// CONFIG PLUGIN - Creates .olova folder and configures Vite settings\r\n// =============================================================================\r\nexport function configPlugin(): Plugin {\r\n const olovaDir = path.resolve('.olova');\r\n \r\n return {\r\n name: 'olova-config',\r\n config(_config, { command }) {\r\n // Create .olova folder on startup\r\n if (!fs.existsSync(olovaDir)) {\r\n fs.mkdirSync(olovaDir, { recursive: true });\r\n }\r\n \r\n // Skip build config for SSG builds\r\n if (process.env.IS_SSG_BUILD) {\r\n return {\r\n appType: 'custom',\r\n cacheDir: './.olova/cache',\r\n };\r\n }\r\n \r\n // Show startup banner for dev mode\r\n if (command === 'serve') {\r\n console.log('');\r\n console.log(` ${colors.bold}${colors.cyan}🟢 Olova${colors.reset} ${colors.dim}v1.0.0${colors.reset}`);\r\n console.log('');\r\n }\r\n \r\n return {\r\n appType: 'custom',\r\n cacheDir: './.olova/cache',\r\n build: {\r\n outDir: './.olova/dist',\r\n sourcemap: false,\r\n chunkSizeWarningLimit: 500,\r\n rollupOptions: {\r\n onwarn(warning, warn) {\r\n // Suppress \"dynamic import will not move module\" warnings\r\n if (warning.code === 'PLUGIN_WARNING' && warning.message?.includes('dynamic import will not move')) {\r\n return;\r\n }\r\n // Suppress \"static\" directive warnings (Olova uses this for static routes)\r\n if (warning.message?.includes('Module level directives') && warning.message?.includes('static')) {\r\n return;\r\n }\r\n // Suppress sourcemap warnings for static directive\r\n if (warning.message?.includes('sourcemap') && warning.message?.includes(\"Can't resolve original location\")) {\r\n return;\r\n }\r\n warn(warning);\r\n },\r\n output: {\r\n chunkFileNames: 'pro_olova_static/chunks/[name]-[hash].js',\r\n entryFileNames: 'pro_olova_static/olova-[hash].js',\r\n assetFileNames: 'pro_olova_static/[name]-[hash][extname]',\r\n manualChunks(id) {\r\n if (id.includes('node_modules')) {\r\n if (id.includes('react-dom')) {\r\n return 'vendor-react-dom';\r\n }\r\n if (id.includes('react')) {\r\n return 'vendor-react';\r\n }\r\n // Keep olova separate so it properly depends on React\r\n if (id.includes('olova')) {\r\n return undefined; // Let Rollup handle it normally\r\n }\r\n return 'vendor';\r\n }\r\n },\r\n },\r\n },\r\n },\r\n preview: {\r\n port: 4173,\r\n strictPort: false,\r\n },\r\n // Exclude olova from dependency optimization so our virtual modules work\r\n optimizeDeps: {\r\n exclude: ['olova', 'olova/router'],\r\n },\r\n // Also configure SSR to handle these modules\r\n ssr: {\r\n noExternal: ['olova', /^virtual:/],\r\n },\r\n };\r\n },\r\n configureServer(server) {\r\n // Show ready message when server starts\r\n server.httpServer?.once('listening', () => {\r\n const address = server.httpServer?.address();\r\n const port = typeof address === 'object' && address ? address.port : 5173;\r\n \r\n setTimeout(() => {\r\n console.log(` ${colors.green}✓${colors.reset} Ready in ${colors.dim}${Math.round(performance.now())}ms${colors.reset}`);\r\n console.log('');\r\n console.log(` ${colors.dim}➜${colors.reset} ${colors.bold}Local:${colors.reset} ${colors.cyan}http://localhost:${port}/${colors.reset}`);\r\n console.log('');\r\n }, 100);\r\n });\r\n },\r\n };\r\n}\r\n","import { type Plugin, type ViteDevServer } from 'vite';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\n\r\n// =============================================================================\r\n// ROUTER PLUGIN - File-system based routing with HMR support\r\n// =============================================================================\r\nexport function routerPlugin(): Plugin {\r\n const virtualModuleId = 'virtual:olova-routes';\r\n const resolvedVirtualModuleId = '\\0' + virtualModuleId;\r\n let server: ViteDevServer | null = null;\r\n\r\n // Helper function to invalidate the virtual module and trigger HMR\r\n const invalidateRoutes = () => {\r\n if (server) {\r\n const mod = server.moduleGraph.getModuleById(resolvedVirtualModuleId);\r\n if (mod) {\r\n server.moduleGraph.invalidateModule(mod);\r\n // Send HMR update to refresh the routes\r\n server.ws.send({\r\n type: 'full-reload',\r\n path: '*'\r\n });\r\n }\r\n }\r\n };\r\n\r\n return {\r\n name: 'olova-router',\r\n enforce: 'pre',\r\n \r\n // Configure dev server to watch for file changes\r\n configureServer(devServer) {\r\n server = devServer;\r\n const srcDir = path.resolve(process.cwd(), 'src');\r\n \r\n // Watch the src directory for file changes\r\n const watcher = devServer.watcher;\r\n \r\n // Handle file additions\r\n watcher.on('add', (filePath: string) => {\r\n if (filePath.startsWith(srcDir) && /\\.(tsx|jsx|html|md)$/.test(filePath)) {\r\n console.log('\\x1b[36m[olova]\\x1b[0m New route detected:', path.relative(srcDir, filePath));\r\n invalidateRoutes();\r\n }\r\n });\r\n \r\n // Handle file deletions\r\n watcher.on('unlink', (filePath: string) => {\r\n if (filePath.startsWith(srcDir) && /\\.(tsx|jsx|html|md)$/.test(filePath)) {\r\n console.log('\\x1b[36m[olova]\\x1b[0m Route removed:', path.relative(srcDir, filePath));\r\n invalidateRoutes();\r\n }\r\n });\r\n \r\n // Handle directory additions (new route folders)\r\n watcher.on('addDir', (dirPath: string) => {\r\n if (dirPath.startsWith(srcDir) && dirPath !== srcDir) {\r\n console.log('\\x1b[36m[olova]\\x1b[0m New route folder detected:', path.relative(srcDir, dirPath));\r\n // Don't invalidate immediately - wait for files to be added\r\n }\r\n });\r\n \r\n // Handle directory deletions\r\n watcher.on('unlinkDir', (dirPath: string) => {\r\n if (dirPath.startsWith(srcDir) && dirPath !== srcDir) {\r\n console.log('\\x1b[36m[olova]\\x1b[0m Route folder removed:', path.relative(srcDir, dirPath));\r\n invalidateRoutes();\r\n }\r\n });\r\n },\r\n \r\n resolveId(id) {\r\n if (id === virtualModuleId) {\r\n return resolvedVirtualModuleId;\r\n }\r\n },\r\n \r\n // Mark the virtual module as having side effects for proper HMR\r\n handleHotUpdate({ file, server: devServer }) {\r\n const srcDir = path.resolve(process.cwd(), 'src');\r\n \r\n // If a route file's content changes (like adding \"static\" directive), refresh routes\r\n if (file.startsWith(srcDir) && /\\.(tsx|jsx)$/.test(file)) {\r\n const mod = devServer.moduleGraph.getModuleById(resolvedVirtualModuleId);\r\n if (mod) {\r\n devServer.moduleGraph.invalidateModule(mod);\r\n }\r\n }\r\n },\r\n \r\n load(id) {\r\n if (id === resolvedVirtualModuleId) {\r\n const srcDir = path.resolve(process.cwd(), 'src');\r\n \r\n // Helper to scan directory recursively\r\n // Supports Next.js-style conventions:\r\n // - (folder) = Route Group (ignored in URL, for organization only)\r\n // - [folder] = Dynamic Route (captures URL parameter)\r\n const getRoutes = (dir: string, baseRoute: string = '', baseImportPath: string = ''): string[] => {\r\n const entries = fs.readdirSync(dir, { withFileTypes: true });\r\n let routes: string[] = [];\r\n\r\n for (const entry of entries) {\r\n const entryName = entry.name;\r\n const fullPath = path.join(dir, entryName);\r\n \r\n if (entry.isDirectory()) {\r\n // Check if it's a route group (folder wrapped in parentheses)\r\n const isRouteGroup = /^\\(.+\\)$/.test(entryName);\r\n \r\n if (isRouteGroup) {\r\n // Route groups: folder is ignored in URL path but kept in import path\r\n // e.g., (auth) folder -> URL stays same, import includes (auth)\r\n routes = routes.concat(getRoutes(\r\n fullPath, \r\n baseRoute, // URL path stays the same (group is ignored)\r\n `${baseImportPath}/${entryName}` // Import path includes the folder\r\n ));\r\n } else {\r\n // Regular folder or dynamic route folder\r\n routes = routes.concat(getRoutes(\r\n fullPath, \r\n `${baseRoute}/${entryName}`,\r\n `${baseImportPath}/${entryName}`\r\n ));\r\n }\r\n } else {\r\n // Support multiple file types: .tsx, .jsx, .html, .md\r\n const ext = path.extname(entryName);\r\n const supportedExts = ['.tsx', '.jsx', '.html', '.md'];\r\n \r\n if (supportedExts.includes(ext)) {\r\n const nameNoExt = entryName.replace(/\\.(tsx|jsx|html|md)$/, '');\r\n if (nameNoExt === 'root') continue; \r\n \r\n let routePath = baseRoute;\r\n if (nameNoExt !== 'index' && nameNoExt !== 'App') {\r\n routePath = `${baseRoute}/${nameNoExt}`;\r\n }\r\n \r\n if (routePath === '') routePath = '/';\r\n \r\n // Convert $param to :param for dynamic routes (Olova convention)\r\n const normalizedRoutePath = routePath\r\n .replace(/\\$(.+?)(?=\\/|$)/g, ':$1');\r\n \r\n // Path relative to project root for import\r\n const importPath = `/src${baseImportPath}/${entryName}`;\r\n \r\n if (ext === '.html') {\r\n // HTML files: create a wrapper that fetches and renders the HTML\r\n routes.push(` \"${normalizedRoutePath}\": () => import(\"${importPath}?raw\").then(m => ({ default: () => { const div = document.createElement('div'); div.innerHTML = m.default; return div.innerHTML; }, __isHtml: true, __isStatic: true, __rawHtml: m.default })),`);\r\n } else if (ext === '.md') {\r\n // MD files: import as raw and render as markdown\r\n routes.push(` \"${normalizedRoutePath}\": () => import(\"${importPath}?raw\").then(m => ({ default: m.default, __isMd: true, __isStatic: true })),`);\r\n } else {\r\n // TSX/JSX files: check for \"static\" directive\r\n const fileContent = fs.readFileSync(fullPath, 'utf-8');\r\n const firstLine = fileContent.trim().split('\\n')[0].trim();\r\n const hasStaticDirective = firstLine === '\"static\"' || firstLine === \"'static'\";\r\n \r\n if (hasStaticDirective) {\r\n // Static route: add __isStatic flag\r\n routes.push(` \"${normalizedRoutePath}\": () => import(\"${importPath}\").then(m => Object.assign({}, m, { __isStatic: true })),`);\r\n } else {\r\n // Client-only route: standard import\r\n routes.push(` \"${normalizedRoutePath}\": () => import(\"${importPath}\"),`);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n return routes;\r\n };\r\n\r\n let routeLines: string[] = [];\r\n if (fs.existsSync(srcDir)) {\r\n routeLines = getRoutes(srcDir);\r\n }\r\n\r\n return `export const routes = {\r\n${routeLines.join('\\n')}\r\n};`;\r\n }\r\n },\r\n };\r\n}\r\n","import { type Plugin, transformWithEsbuild } from 'vite';\r\n\r\n// =============================================================================\r\n// FRAMEWORK PLUGIN - Virtual entry points for client and server\r\n// =============================================================================\r\nexport function frameworkPlugin(): Plugin {\r\n const virtualClientEntry = 'olova/client';\r\n const resolvedVirtualClientEntry = '\\0' + virtualClientEntry;\r\n const virtualServerEntry = 'olova/server';\r\n const resolvedVirtualServerEntry = '\\0' + virtualServerEntry;\r\n\r\n return {\r\n name: 'olova-framework',\r\n enforce: 'pre',\r\n resolveId(id: string) {\r\n if (id === virtualClientEntry || id === '/olova/client' || id === 'olova/client.tsx') return resolvedVirtualClientEntry;\r\n if (id === virtualServerEntry || id === '/olova/server' || id === 'olova/server.tsx') return resolvedVirtualServerEntry;\r\n },\r\n async load(id: string) {\r\n if (id === resolvedVirtualClientEntry) {\r\n const code = `\r\nimport React from 'react';\r\nimport { hydrateRoot, createRoot } from 'react-dom/client';\r\nimport Layout, { metadata as defaultMetadata } from '/src/root.tsx';\r\nimport { Router, loadRoute } from 'olova/router';\r\n\r\n// Helper to generate SEO meta tags\r\nfunction generateSeoTags(metadata) {\r\n const meta = { ...defaultMetadata, ...metadata };\r\n const tags = [];\r\n \r\n // Title\r\n if (meta.title) {\r\n document.title = meta.title;\r\n }\r\n \r\n // Description\r\n if (meta.description) {\r\n let tag = document.querySelector('meta[name=\"description\"]');\r\n if (!tag) {\r\n tag = document.createElement('meta');\r\n tag.setAttribute('name', 'description');\r\n document.head.appendChild(tag);\r\n }\r\n tag.setAttribute('content', meta.description);\r\n }\r\n \r\n // Keywords\r\n if (meta.keywords) {\r\n const content = Array.isArray(meta.keywords) ? meta.keywords.join(', ') : meta.keywords;\r\n let tag = document.querySelector('meta[name=\"keywords\"]');\r\n if (!tag) {\r\n tag = document.createElement('meta');\r\n tag.setAttribute('name', 'keywords');\r\n document.head.appendChild(tag);\r\n }\r\n tag.setAttribute('content', content);\r\n }\r\n \r\n // Open Graph\r\n if (meta.openGraph) {\r\n const og = meta.openGraph;\r\n const ogTags = [\r\n ['og:title', og.title || meta.title],\r\n ['og:description', og.description],\r\n ['og:url', og.url],\r\n ['og:site_name', og.siteName],\r\n ['og:type', og.type],\r\n ];\r\n ogTags.forEach(([prop, content]) => {\r\n if (content) {\r\n let tag = document.querySelector(\\`meta[property=\"\\${prop}\"]\\`);\r\n if (!tag) {\r\n tag = document.createElement('meta');\r\n tag.setAttribute('property', prop);\r\n document.head.appendChild(tag);\r\n }\r\n tag.setAttribute('content', content);\r\n }\r\n });\r\n }\r\n \r\n // Twitter Card\r\n if (meta.twitter) {\r\n const tw = meta.twitter;\r\n const twTags = [\r\n ['twitter:card', tw.card || 'summary'],\r\n ['twitter:site', tw.site],\r\n ['twitter:creator', tw.creator],\r\n ['twitter:title', tw.title || meta.title],\r\n ['twitter:description', tw.description],\r\n ];\r\n twTags.forEach(([name, content]) => {\r\n if (content) {\r\n let tag = document.querySelector(\\`meta[name=\"\\${name}\"]\\`);\r\n if (!tag) {\r\n tag = document.createElement('meta');\r\n tag.setAttribute('name', name);\r\n document.head.appendChild(tag);\r\n }\r\n tag.setAttribute('content', content);\r\n }\r\n });\r\n }\r\n}\r\n\r\nconst path = window.location.pathname;\r\nloadRoute(path).then((result) => {\r\n const Component = result ? result.module.default : () => <div>404 Not Found</div>;\r\n // @ts-ignore\r\n const serverData = window.__OLOVA_DATA__ || window.$OLOVA?.$route || {};\r\n const params = serverData.params || (result ? result.params : {});\r\n const metadata = serverData.metadata || (result ? result.metadata : undefined);\r\n\r\n // Framework handles SEO automatically (like Next.js)\r\n generateSeoTags(metadata);\r\n\r\n const app = (\r\n <React.StrictMode>\r\n <Layout>\r\n <Router url={path} initialComponent={Component} initialParams={params} onRouteChange={(newMetadata) => generateSeoTags(newMetadata)} />\r\n </Layout>\r\n </React.StrictMode>\r\n );\r\n\r\n // Always hydrate using the document as root since we always have a shell from SSG\r\n console.log(\"[Olova] Hydrating document with component:\", Component ? (Component.name || 'Anonymous') : \"NULL\");\r\n \r\n // Debug loaded route result\r\n if (result) {\r\n console.log(\"[Olova] Route module keys:\", Object.keys(result.module));\r\n } else {\r\n console.warn(\"[Olova] Route result is null/undefined\");\r\n }\r\n\r\n hydrateRoot(document, app);\r\n});`;\r\n const result = await transformWithEsbuild(code, 'olova-client.tsx', {\r\n loader: 'tsx',\r\n jsx: 'automatic',\r\n });\r\n return result.code;\r\n }\r\n if (id === resolvedVirtualServerEntry) {\r\n const code = `\r\nimport React from 'react';\r\nimport { renderToString } from 'react-dom/server';\r\nimport Layout, { metadata as defaultMetadata } from '/src/root.tsx';\r\nimport { routes } from 'virtual:olova-routes';\r\n\r\n// =============================================================================\r\n// INLINE ROUTER UTILITIES (to avoid external olova/router import)\r\n// =============================================================================\r\nconst normalizePath = (path) => {\r\n let p = path.split('?')[0].split('#')[0];\r\n if (p.length > 1 && p.endsWith('/')) p = p.slice(0, -1);\r\n return p || '/';\r\n};\r\n\r\nfunction matchRoute(path) {\r\n const normalizedPath = normalizePath(path);\r\n const routeKeys = Object.keys(routes);\r\n \r\n for (const route of routeKeys) {\r\n if (route === normalizedPath) {\r\n return { loader: routes[route], params: {}, pattern: route };\r\n }\r\n \r\n const regexPath = route\r\n .replace(/:[^\\\\/]+/g, '([^/]+)')\r\n .replace(/\\\\$[^\\\\/]+/g, '([^/]+)');\r\n \r\n const regex = new RegExp(\\`^\\${regexPath}$\\`);\r\n const match = normalizedPath.match(regex);\r\n \r\n if (match) {\r\n const params = {};\r\n const paramNames = (route.match(/[:\\\\$][^\\\\/]+/g) || []).map(s => s.slice(1));\r\n paramNames.forEach((name, i) => {\r\n params[name] = match[i + 1];\r\n });\r\n return { loader: routes[route], params, pattern: route };\r\n }\r\n }\r\n return null;\r\n}\r\n\r\nfunction parseMarkdown(md) {\r\n return md\r\n .replace(/^### (.*$)/gim, '<h3>$1</h3>')\r\n .replace(/^## (.*$)/gim, '<h2>$1</h2>')\r\n .replace(/^# (.*$)/gim, '<h1>$1</h1>')\r\n .replace(/\\\\*\\\\*\\\\*(.*?)\\\\*\\\\*\\\\*/g, '<strong><em>$1</em></strong>')\r\n .replace(/\\\\*\\\\*(.*?)\\\\*\\\\*/g, '<strong>$1</strong>')\r\n .replace(/\\\\*(.*?)\\\\*/g, '<em>$1</em>')\r\n .replace(/\\`\\`\\`([\\\\s\\\\S]*?)\\`\\`\\`/g, '<pre><code>$1</code></pre>')\r\n .replace(/\\`(.*?)\\`/g, '<code>$1</code>')\r\n .replace(/\\\\[([^\\\\]]+)\\\\]\\\\(([^)]+)\\\\)/g, '<a href=\"$2\">$1</a>')\r\n .replace(/\\\\n\\\\n/g, '</p><p>')\r\n .replace(/\\\\n/g, '<br>')\r\n .replace(/^(.*)$/, '<p>$1</p>');\r\n}\r\n\r\nfunction HtmlContent({ html }) {\r\n return React.createElement('div', { \r\n dangerouslySetInnerHTML: { __html: html },\r\n className: 'olova-html-content'\r\n });\r\n}\r\n\r\nfunction MarkdownContent({ markdown }) {\r\n const html = parseMarkdown(markdown);\r\n return React.createElement('article', { \r\n dangerouslySetInnerHTML: { __html: html },\r\n className: 'olova-markdown-content'\r\n });\r\n}\r\n\r\nasync function loadRoute(path) {\r\n const match = matchRoute(path);\r\n if (match) {\r\n const module = await match.loader();\r\n \r\n if (module.__isHtml) {\r\n return { \r\n module: {\r\n default: () => HtmlContent({ html: module.__rawHtml }),\r\n },\r\n params: match.params,\r\n metadata: undefined\r\n };\r\n }\r\n \r\n if (module.__isMd) {\r\n return { \r\n module: {\r\n default: () => MarkdownContent({ markdown: module.default }),\r\n },\r\n params: match.params,\r\n metadata: undefined\r\n };\r\n }\r\n \r\n return { \r\n module,\r\n params: match.params,\r\n metadata: module.metadata\r\n };\r\n }\r\n return null;\r\n}\r\n\r\nconst RouterContext = React.createContext({ params: {}, path: '/' });\r\n\r\nfunction Router({ url, initialComponent, initialParams }) {\r\n const Component = initialComponent || (() => <div>Loading...</div>);\r\n const params = initialParams || {};\r\n // Server-side: Just render the Component directly (no Context needed)\r\n // The Context.Provider wrapping happens on client for hooks to work\r\n return <Component {...params} />;\r\n}\r\n\r\n// =============================================================================\r\n// SEO HEAD GENERATION\r\n// =============================================================================\r\nfunction generateSeoHead(metadata) {\r\n const meta = { ...defaultMetadata, ...metadata };\r\n let head = '';\r\n \r\n if (meta.title) {\r\n head += \\`<title>\\${meta.title}</title>\\\\n\\`;\r\n }\r\n \r\n if (meta.description) {\r\n head += \\`<meta name=\"description\" content=\"\\${meta.description}\" />\\\\n\\`;\r\n }\r\n if (meta.keywords) {\r\n const content = Array.isArray(meta.keywords) ? meta.keywords.join(', ') : meta.keywords;\r\n head += \\`<meta name=\"keywords\" content=\"\\${content}\" />\\\\n\\`;\r\n }\r\n if (meta.robots) {\r\n head += \\`<meta name=\"robots\" content=\"\\${meta.robots}\" />\\\\n\\`;\r\n }\r\n if (meta.canonical) {\r\n head += \\`<link rel=\"canonical\" href=\"\\${meta.canonical}\" />\\\\n\\`;\r\n }\r\n \r\n if (meta.openGraph) {\r\n const og = meta.openGraph;\r\n head += \\`<meta property=\"og:title\" content=\"\\${og.title || meta.title}\" />\\\\n\\`;\r\n if (og.description) head += \\`<meta property=\"og:description\" content=\"\\${og.description}\" />\\\\n\\`;\r\n if (og.url) head += \\`<meta property=\"og:url\" content=\"\\${og.url}\" />\\\\n\\`;\r\n if (og.siteName) head += \\`<meta property=\"og:site_name\" content=\"\\${og.siteName}\" />\\\\n\\`;\r\n if (og.type) head += \\`<meta property=\"og:type\" content=\"\\${og.type}\" />\\\\n\\`;\r\n if (og.images) {\r\n og.images.forEach(img => {\r\n head += \\`<meta property=\"og:image\" content=\"\\${img.url}\" />\\\\n\\`;\r\n });\r\n }\r\n }\r\n \r\n if (meta.twitter) {\r\n const tw = meta.twitter;\r\n head += \\`<meta name=\"twitter:card\" content=\"\\${tw.card || 'summary'}\" />\\\\n\\`;\r\n if (tw.site) head += \\`<meta name=\"twitter:site\" content=\"\\${tw.site}\" />\\\\n\\`;\r\n if (tw.creator) head += \\`<meta name=\"twitter:creator\" content=\"\\${tw.creator}\" />\\\\n\\`;\r\n head += \\`<meta name=\"twitter:title\" content=\"\\${tw.title || meta.title}\" />\\\\n\\`;\r\n if (tw.description) head += \\`<meta name=\"twitter:description\" content=\"\\${tw.description}\" />\\\\n\\`;\r\n if (tw.images) {\r\n tw.images.forEach(img => {\r\n head += \\`<meta name=\"twitter:image\" content=\"\\${img}\" />\\\\n\\`;\r\n });\r\n }\r\n }\r\n \r\n return head;\r\n}\r\n\r\n// =============================================================================\r\n// SERVER RENDER FUNCTIONS\r\n// =============================================================================\r\nexport async function render(url) {\r\n const result = await loadRoute(url);\r\n const Component = result ? result.module.default : () => <div>404 Not Found</div>;\r\n const params = result ? result.params : {};\r\n const metadata = result ? result.metadata : undefined;\r\n \r\n const seoHead = generateSeoHead(metadata);\r\n \r\n let html = renderToString(\r\n <Layout>\r\n <Router url={url} initialComponent={Component} initialParams={params} />\r\n </Layout>\r\n );\r\n \r\n if (html.includes('</head>')) {\r\n html = html.replace('</head>', seoHead + '</head>');\r\n }\r\n \r\n return { html, hydrationData: { params, metadata } };\r\n}\r\n\r\nexport function renderShell() {\r\n const seoHead = generateSeoHead({});\r\n let html = renderToString(<Layout>{null}</Layout>);\r\n if (html.includes('</head>')) {\r\n html = html.replace('</head>', seoHead + '</head>');\r\n }\r\n return html;\r\n}\r\n\r\nexport function renderShellWithMetadata(metadata) {\r\n const seoHead = generateSeoHead(metadata);\r\n let html = renderToString(<Layout>{null}</Layout>);\r\n if (html.includes('</head>')) {\r\n html = html.replace('</head>', seoHead + '</head>');\r\n }\r\n return html;\r\n}\r\n\r\nexport { loadRoute };`;\r\n const result = await transformWithEsbuild(code, 'olova-server.tsx', {\r\n loader: 'tsx',\r\n jsx: 'automatic',\r\n });\r\n return result.code;\r\n }\r\n }\r\n }\r\n}\r\n","import { type Plugin, type ViteDevServer } from 'vite';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport { generateOlovaHydration, generateJsonLd } from './hydration';\r\n\r\n// =============================================================================\r\n// VIRTUAL HTML PLUGIN - Handles dev and build HTML generation\r\n// \r\n// Rendering modes:\r\n// - ALL PAGES: Layout shell (root.tsx) is always pre-rendered (like Next.js)\r\n// - \"static\" directive: Full page content is also pre-rendered\r\n// - .html/.md files: Always fully static\r\n// - Default (no directive): Shell is pre-rendered, page content renders on client\r\n// =============================================================================\r\nexport function virtualHtmlPlugin(): Plugin {\r\n let viteServer: ViteDevServer | null = null;\r\n \r\n // Check if a route file is marked as static\r\n const isStaticRoute = (routePath: string): { isStatic: boolean; fileType: 'tsx' | 'jsx' | 'html' | 'md' | null } => {\r\n const srcDir = path.resolve('src');\r\n let filePath = routePath === '/' ? '' : routePath.slice(1);\r\n \r\n // Check for HTML/MD files first - these are always static\r\n const htmlMdPaths = [\r\n path.join(srcDir, filePath, 'index.html'),\r\n path.join(srcDir, filePath, 'index.md'),\r\n path.join(srcDir, filePath + '.html'),\r\n path.join(srcDir, filePath + '.md'),\r\n ];\r\n \r\n for (const p of htmlMdPaths) {\r\n if (fs.existsSync(p)) {\r\n const ext = path.extname(p).slice(1) as 'html' | 'md';\r\n return { isStatic: true, fileType: ext };\r\n }\r\n }\r\n \r\n // Check for TSX/JSX files\r\n const tsxJsxPaths = [\r\n path.join(srcDir, filePath, 'index.tsx'),\r\n path.join(srcDir, filePath, 'index.jsx'),\r\n path.join(srcDir, filePath + '.tsx'),\r\n path.join(srcDir, filePath + '.jsx'),\r\n path.join(srcDir, 'App.tsx'),\r\n path.join(srcDir, 'App.jsx'),\r\n ];\r\n \r\n for (const p of tsxJsxPaths) {\r\n if (fs.existsSync(p)) {\r\n const content = fs.readFileSync(p, 'utf-8');\r\n const firstLine = content.trim().split('\\n')[0].trim();\r\n const isStatic = firstLine === '\"static\"' || firstLine === \"'static'\";\r\n const ext = path.extname(p).slice(1) as 'tsx' | 'jsx';\r\n return { isStatic, fileType: ext };\r\n }\r\n }\r\n \r\n return { isStatic: false, fileType: null };\r\n };\r\n \r\n // Extract metadata from a file\r\n const extractMetadata = (filePath: string): Record<string, unknown> => {\r\n try {\r\n if (!fs.existsSync(filePath)) return {};\r\n const content = fs.readFileSync(filePath, 'utf-8');\r\n \r\n const metadataMatch = content.match(/export\\s+const\\s+metadata\\s*=\\s*(\\{[\\s\\S]*?\\});/);\r\n if (metadataMatch) {\r\n try {\r\n let metaStr = metadataMatch[1]\r\n .replace(/'/g, '\"')\r\n .replace(/(\\w+):/g, '\"$1\":')\r\n .replace(/,\\s*}/g, '}')\r\n .replace(/,\\s*]/g, ']');\r\n return JSON.parse(metaStr);\r\n } catch {\r\n const titleMatch = content.match(/title:\\s*['\"]([^'\"]+)['\"]/);\r\n const descMatch = content.match(/description:\\s*['\"]([^'\"]+)['\"]/);\r\n return {\r\n title: titleMatch?.[1] || 'Olova App',\r\n description: descMatch?.[1] || '',\r\n };\r\n }\r\n }\r\n return {};\r\n } catch {\r\n return {};\r\n }\r\n };\r\n\r\n // Get metadata for a route\r\n const getRouteMetadata = (routePath: string): Record<string, unknown> => {\r\n const srcDir = path.resolve('src');\r\n let filePath = routePath === '/' ? '' : routePath.slice(1);\r\n \r\n const possiblePaths = [\r\n path.join(srcDir, filePath, 'index.tsx'),\r\n path.join(srcDir, filePath, 'index.jsx'),\r\n path.join(srcDir, filePath + '.tsx'),\r\n path.join(srcDir, filePath + '.jsx'),\r\n path.join(srcDir, 'App.tsx'),\r\n path.join(srcDir, 'App.jsx'),\r\n ];\r\n \r\n for (const p of possiblePaths) {\r\n if (fs.existsSync(p)) {\r\n return extractMetadata(p);\r\n }\r\n }\r\n \r\n const rootPath = path.join(srcDir, 'root.tsx');\r\n if (fs.existsSync(rootPath)) {\r\n return extractMetadata(rootPath);\r\n }\r\n \r\n return {};\r\n };\r\n\r\n // Build SEO head content\r\n const buildSeoHead = (routePath: string, metadata?: Record<string, unknown>): string => {\r\n const meta = metadata || getRouteMetadata(routePath);\r\n let headContent = '';\r\n \r\n if (meta.title) {\r\n headContent += `<title>${meta.title}</title>\\n`;\r\n } else {\r\n headContent += `<title>Olova App</title>\\n`;\r\n }\r\n \r\n if (meta.description) {\r\n headContent += `<meta name=\"description\" content=\"${meta.description}\" />\\n`;\r\n }\r\n \r\n if (meta.keywords) {\r\n const keywords = Array.isArray(meta.keywords) \r\n ? (meta.keywords as string[]).join(', ') \r\n : meta.keywords;\r\n headContent += `<meta name=\"keywords\" content=\"${keywords}\" />\\n`;\r\n }\r\n \r\n const jsonLdScript = generateJsonLd({ route: routePath, metadata: meta });\r\n headContent += jsonLdScript + '\\n';\r\n \r\n headContent += `<style id=\"olova-critical\">*{box-sizing:border-box}html{-webkit-text-size-adjust:100%;line-height:1.5}body{font-family:system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif}</style>\\n`;\r\n \r\n return headContent;\r\n };\r\n\r\n // Build hydration scripts\r\n const buildBodyScripts = (routePath: string, metadata?: Record<string, unknown>, isStatic?: boolean): string => {\r\n const meta = metadata || getRouteMetadata(routePath);\r\n const devBuildId = 'dev-' + Date.now().toString(36);\r\n return generateOlovaHydration({\r\n route: routePath,\r\n metadata: meta,\r\n chunks: [],\r\n isStatic: isStatic || false,\r\n }, devBuildId);\r\n };\r\n\r\n // Render shell (layout with children=null) - always runs\r\n const renderShell = async (): Promise<string> => {\r\n if (!viteServer) return '';\r\n\r\n try {\r\n const serverModule = await viteServer.ssrLoadModule('olova/server');\r\n if (serverModule?.renderShell) {\r\n return serverModule.renderShell() || '';\r\n }\r\n } catch (e: any) {\r\n // Silent fail - shell rendering is best-effort\r\n }\r\n return '';\r\n };\r\n\r\n // Render full page (for static pages)\r\n const renderFullPage = async (routePath: string): Promise<{ html: string; metadata: Record<string, unknown> }> => {\r\n if (!viteServer) return { html: '', metadata: {} };\r\n\r\n try {\r\n const serverModule = await viteServer.ssrLoadModule('olova/server');\r\n if (serverModule?.render) {\r\n const result = await serverModule.render(routePath);\r\n return {\r\n html: result.html || '',\r\n metadata: result.hydrationData?.metadata || {}\r\n };\r\n }\r\n } catch (e: any) {\r\n console.error('[Olova] Full page render error:', e.message);\r\n }\r\n return { html: '', metadata: {} };\r\n };\r\n\r\n // Inject content into HTML\r\n const injectIntoHtml = (html: string, seoHead: string, bodyScripts: string): string => {\r\n let result = html;\r\n \r\n // Inject SEO into head\r\n if (result.includes('</head>')) {\r\n result = result.replace('</head>', seoHead + '</head>');\r\n }\r\n \r\n // Inject scripts before </body>\r\n if (result.includes('</body>')) {\r\n result = result.replace('</body>', \r\n bodyScripts + \r\n '<script type=\"module\" src=\"/olova/client\"></script>\\n</body>'\r\n );\r\n } else {\r\n result += bodyScripts + '<script type=\"module\" src=\"/olova/client\"></script>';\r\n }\r\n \r\n return result;\r\n };\r\n\r\n return {\r\n name: 'olova-virtual-html',\r\n enforce: 'pre',\r\n \r\n resolveId(id: string) {\r\n if (id === 'index.html' || id === 'virtual:index.html' || id === '/index.html') {\r\n return 'virtual:olova-index.html';\r\n }\r\n },\r\n \r\n load(id: string) {\r\n if (id === 'virtual:olova-index.html') {\r\n return `<!DOCTYPE html>\r\n<html lang=\"en\">\r\n <head>\r\n <meta charset=\"UTF-8\" />\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\r\n </head>\r\n <body>\r\n <script type=\"module\" src=\"/olova/client\"></script>\r\n </body>\r\n</html>`;\r\n }\r\n },\r\n\r\n configureServer(server) {\r\n viteServer = server;\r\n \r\n return () => {\r\n server.middlewares.use(async (req, res, next) => {\r\n const url = req.url || '/';\r\n \r\n const accept = req.headers.accept || '';\r\n if (!accept.includes('text/html')) {\r\n return next();\r\n }\r\n \r\n if (url.startsWith('/@') || url.startsWith('/__') || url.startsWith('/node_modules')) {\r\n return next();\r\n }\r\n \r\n if (/\\.\\w+$/.test(url) && !url.endsWith('.html')) {\r\n return next();\r\n }\r\n \r\n const routePath = url.split('?')[0].replace(/\\/+$/, '') || '/';\r\n \r\n try {\r\n const { isStatic, fileType } = isStaticRoute(routePath);\r\n const routeMetadata = getRouteMetadata(routePath);\r\n \r\n let finalHtml: string;\r\n let metadata = { ...routeMetadata };\r\n \r\n if (isStatic) {\r\n // STATIC: Full page SSR\r\n const { html: fullHtml, metadata: ssrMetadata } = await renderFullPage(routePath);\r\n metadata = { ...routeMetadata, ...ssrMetadata };\r\n \r\n if (fullHtml) {\r\n const seoHead = buildSeoHead(routePath, metadata);\r\n const bodyScripts = buildBodyScripts(routePath, metadata, true);\r\n finalHtml = injectIntoHtml(fullHtml, seoHead, bodyScripts);\r\n } else {\r\n // Fallback: shell with metadata\r\n const shellHtml = await renderShell();\r\n const seoHead = buildSeoHead(routePath, metadata);\r\n const bodyScripts = buildBodyScripts(routePath, metadata, true);\r\n \r\n if (shellHtml) {\r\n finalHtml = injectIntoHtml(shellHtml, seoHead, bodyScripts);\r\n } else {\r\n finalHtml = `<!DOCTYPE html>\r\n<html lang=\"en\">\r\n <head>\r\n <meta charset=\"UTF-8\" />\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\r\n ${seoHead}\r\n </head>\r\n <body>\r\n ${bodyScripts}\r\n <script type=\"module\" src=\"/olova/client\"></script>\r\n </body>\r\n</html>`;\r\n }\r\n }\r\n } else {\r\n // CLIENT-SIDE: Render shell (layout) but not page content\r\n // This gives you the header/nav in view source, like Next.js\r\n const shellHtml = await renderShell();\r\n const seoHead = buildSeoHead(routePath, metadata);\r\n const bodyScripts = buildBodyScripts(routePath, metadata, false);\r\n \r\n if (shellHtml) {\r\n // Shell rendered - inject SEO and scripts\r\n finalHtml = injectIntoHtml(shellHtml, seoHead, bodyScripts);\r\n } else {\r\n // Shell failed - minimal HTML\r\n finalHtml = `<!DOCTYPE html>\r\n<html lang=\"en\">\r\n <head>\r\n <meta charset=\"UTF-8\" />\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\r\n ${seoHead}\r\n </head>\r\n <body>\r\n ${bodyScripts}\r\n <script type=\"module\" src=\"/olova/client\"></script>\r\n </body>\r\n</html>`;\r\n }\r\n }\r\n \r\n // Ensure DOCTYPE\r\n if (!finalHtml.trim().toLowerCase().startsWith('<!doctype')) {\r\n finalHtml = '<!DOCTYPE html>\\n' + finalHtml;\r\n }\r\n \r\n // Transform through Vite for HMR\r\n const transformedHtml = await server.transformIndexHtml(url, finalHtml);\r\n \r\n res.setHeader('Content-Type', 'text/html');\r\n res.statusCode = 200;\r\n res.end(transformedHtml);\r\n } catch (e: any) {\r\n console.error('[Olova] Error:', e);\r\n next(e);\r\n }\r\n });\r\n };\r\n }\r\n };\r\n}\r\n","// =============================================================================\r\n// OLOVA HYDRATION SYSTEM\r\n// Implements \"Flight\" format for efficient client hydration\r\n// \r\n\r\n\r\nexport interface OlovaHydrationData {\r\n route: string;\r\n metadata?: Record<string, unknown>;\r\n params?: Record<string, string>;\r\n chunks?: string[];\r\n isStatic?: boolean;\r\n}\r\n\r\n// Flight data types for streaming\r\ntype FlightDataType = \r\n | 'M' // Metadata\r\n | 'T' // Component Tree\r\n | 'R' // Route info\r\n | 'P' // Params\r\n | 'A' // Assets/Chunks\r\n | 'S' // State\r\n | 'D' // Structured Data (Schema.org/JSON-LD)\r\n | 'H' // Hints (prefetch, preload)\r\n | 'E'; // End marker\r\n\r\ninterface FlightChunk {\r\n type: FlightDataType;\r\n data: unknown;\r\n}\r\n\r\nexport function generateOlovaHydration(data: OlovaHydrationData, buildId: string): string {\r\n const meta = (data.metadata || {}) as Record<string, unknown>;\r\n const scripts: string[] = [];\r\n \r\n // Initialize the flight array (like Next.js's self.__next_f)\r\n scripts.push(`<script>self.__olova_f=self.__olova_f||[];function _oF(d){self.__olova_f.push(d)}</script>`);\r\n \r\n // ==========================================================================\r\n // CHUNK 0: Route Information (Critical for navigation)\r\n // ==========================================================================\r\n const routeChunk: FlightChunk = {\r\n type: 'R',\r\n data: {\r\n path: data.route,\r\n params: data.params || {},\r\n pattern: data.route === '/' ? '/' : data.route.replace(/\\/[^/]+$/, '/:slug'),\r\n isStatic: data.isStatic ?? true,\r\n buildId: buildId\r\n }\r\n };\r\n scripts.push(`<script>_oF([0,\"${routeChunk.type}\",${JSON.stringify(routeChunk.data)}])</script>`);\r\n \r\n // ==========================================================================\r\n // CHUNK 1: Metadata (SEO Critical - must be early)\r\n // ==========================================================================\r\n const metadataChunk: FlightChunk = {\r\n type: 'M',\r\n data: {\r\n title: meta.title || 'Olova App',\r\n description: meta.description || '',\r\n keywords: Array.isArray(meta.keywords) ? meta.keywords : [],\r\n robots: meta.robots || 'index, follow',\r\n canonical: meta.canonical || null,\r\n og: {\r\n type: 'website',\r\n locale: 'en_US',\r\n ...((meta.openGraph as object) || {})\r\n },\r\n twitter: {\r\n card: 'summary_large_image',\r\n ...((meta.twitter as object) || {})\r\n }\r\n }\r\n };\r\n scripts.push(`<script>_oF([1,\"${metadataChunk.type}\",${JSON.stringify(metadataChunk.data)}])</script>`);\r\n \r\n // ==========================================================================\r\n // CHUNK 2: Component Tree (For React reconciliation)\r\n // ==========================================================================\r\n const pageName = data.route === '/' \r\n ? 'HomePage' \r\n : data.route.slice(1).split('/').map(s => s.charAt(0).toUpperCase() + s.slice(1)).join('') + 'Page';\r\n \r\n const treeChunk: FlightChunk = {\r\n type: 'T',\r\n data: {\r\n layout: 'RootLayout',\r\n page: pageName,\r\n template: null,\r\n loading: null,\r\n error: null,\r\n notFound: null\r\n }\r\n };\r\n scripts.push(`<script>_oF([2,\"${treeChunk.type}\",${JSON.stringify(treeChunk.data)}])</script>`);\r\n \r\n // ==========================================================================\r\n // CHUNK 3: Structured Data (JSON-LD for SEO boost)\r\n // ==========================================================================\r\n const structuredData: FlightChunk = {\r\n type: 'D',\r\n data: [\r\n {\r\n '@context': 'https://schema.org',\r\n '@type': 'WebPage',\r\n name: meta.title || 'Olova App',\r\n description: meta.description || '',\r\n url: data.route\r\n },\r\n {\r\n '@context': 'https://schema.org',\r\n '@type': 'WebApplication',\r\n name: 'Olova',\r\n applicationCategory: 'WebApplication',\r\n operatingSystem: 'Any'\r\n }\r\n ]\r\n };\r\n scripts.push(`<script>_oF([3,\"${structuredData.type}\",${JSON.stringify(structuredData.data)}])</script>`);\r\n \r\n // ==========================================================================\r\n // CHUNK 4: Assets for prefetching (Performance optimization)\r\n // ==========================================================================\r\n const assetsChunk: FlightChunk = {\r\n type: 'A',\r\n data: {\r\n chunks: data.chunks || [],\r\n styles: [],\r\n // Prefetch hints for next likely navigations\r\n prefetch: (data.chunks || []).slice(0, 5)\r\n }\r\n };\r\n scripts.push(`<script>_oF([4,\"${assetsChunk.type}\",${JSON.stringify(assetsChunk.data)}])</script>`);\r\n \r\n // ==========================================================================\r\n // CHUNK 5: Resource Hints (Browser optimization)\r\n // ==========================================================================\r\n const hintsChunk: FlightChunk = {\r\n type: 'H',\r\n data: {\r\n dnsPrefetch: ['fonts.googleapis.com', 'fonts.gstatic.com'],\r\n preconnect: ['https://fonts.googleapis.com', 'https://fonts.gstatic.com'],\r\n modulePreload: (data.chunks || []).slice(0, 3)\r\n }\r\n };\r\n scripts.push(`<script>_oF([5,\"${hintsChunk.type}\",${JSON.stringify(hintsChunk.data)}])</script>`);\r\n \r\n // ==========================================================================\r\n // CHUNK 6: Hydration State (Final - marks ready)\r\n // ==========================================================================\r\n const stateChunk: FlightChunk = {\r\n type: 'S',\r\n data: {\r\n hydrated: false,\r\n streaming: false,\r\n ready: true,\r\n timestamp: Date.now(),\r\n version: '1.0.0',\r\n buildId: buildId\r\n }\r\n };\r\n scripts.push(`<script>_oF([6,\"${stateChunk.type}\",${JSON.stringify(stateChunk.data)}])</script>`);\r\n \r\n // ==========================================================================\r\n // END MARKER: Signals all chunks are delivered\r\n // ==========================================================================\r\n scripts.push(`<script>_oF([7,\"E\",null])</script>`);\r\n \r\n // ==========================================================================\r\n // GLOBAL $OLOVA OBJECT: Easy access to hydration data (backward compatible)\r\n // ==========================================================================\r\n const globalPayload = {\r\n $route: routeChunk.data,\r\n $meta: metadataChunk.data,\r\n $tree: treeChunk.data,\r\n $schema: structuredData.data,\r\n $assets: assetsChunk.data,\r\n $hints: hintsChunk.data,\r\n $state: stateChunk.data,\r\n $build: {\r\n id: buildId,\r\n version: '1.0.0',\r\n timestamp: Date.now(),\r\n env: 'production'\r\n }\r\n };\r\n scripts.push(`<script>$OLOVA=${JSON.stringify(globalPayload)}</script>`);\r\n \r\n return scripts.join('');\r\n}\r\n\r\n/**\r\n * Generate JSON-LD structured data script for SEO\r\n * This is injected into <head> for search engine crawlers\r\n */\r\nexport function generateJsonLd(data: OlovaHydrationData): string {\r\n const meta = (data.metadata || {}) as Record<string, unknown>;\r\n \r\n const jsonLd = {\r\n '@context': 'https://schema.org',\r\n '@graph': [\r\n {\r\n '@type': 'WebPage',\r\n '@id': data.route,\r\n name: meta.title || 'Olova App',\r\n description: meta.description || '',\r\n url: data.route,\r\n isPartOf: {\r\n '@type': 'WebSite',\r\n name: 'Olova App'\r\n }\r\n },\r\n {\r\n '@type': 'BreadcrumbList',\r\n itemListElement: data.route.split('/').filter(Boolean).map((segment, index, arr) => ({\r\n '@type': 'ListItem',\r\n position: index + 1,\r\n name: segment.charAt(0).toUpperCase() + segment.slice(1),\r\n item: '/' + arr.slice(0, index + 1).join('/')\r\n }))\r\n }\r\n ]\r\n };\r\n \r\n return `<script type=\"application/ld+json\">${JSON.stringify(jsonLd)}</script>`;\r\n}\r\n\r\n/**\r\n * Parse flight data from the page (client-side utility)\r\n * Use this to access hydration data in your components\r\n */\r\nexport function parseFlightData(): Record<string, unknown> | null {\r\n // Check if we're in a browser environment\r\n if (typeof globalThis === 'undefined' || typeof (globalThis as Record<string, unknown>).document === 'undefined') {\r\n return null;\r\n }\r\n \r\n const flightArray = ((globalThis as Record<string, unknown>).__olova_f) as unknown[] | undefined;\r\n if (!flightArray) return null;\r\n \r\n const result: Record<string, unknown> = {};\r\n const typeMap: Record<FlightDataType, string> = {\r\n 'M': '$meta',\r\n 'T': '$tree', \r\n 'R': '$route',\r\n 'P': '$params',\r\n 'A': '$assets',\r\n 'S': '$state',\r\n 'D': '$schema',\r\n 'H': '$hints',\r\n 'E': '$end'\r\n };\r\n \r\n for (const chunk of flightArray) {\r\n if (Array.isArray(chunk) && chunk.length >= 3) {\r\n const [_index, type, data] = chunk;\r\n const key = typeMap[type as FlightDataType];\r\n if (key && key !== '$end') {\r\n result[key] = data;\r\n }\r\n }\r\n }\r\n \r\n return result;\r\n}\r\n","import { type Plugin, build } from 'vite';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport { pathToFileURL } from 'url';\r\nimport { \r\n minifyHtml, \r\n generateBuildId, \r\n generateResourceHints, \r\n generateCriticalCSS, \r\n generatePerformanceMeta, \r\n generateServiceWorkerScript, \r\n generateServiceWorkerContent \r\n} from './utils';\r\nimport { generateOlovaHydration, generateJsonLd } from './hydration';\r\n\r\n// =============================================================================\r\n// TERMINAL STYLING - Next.js-inspired console output\r\n// =============================================================================\r\nconst colors = {\r\n reset: '\\x1b[0m',\r\n bold: '\\x1b[1m',\r\n dim: '\\x1b[2m',\r\n green: '\\x1b[32m',\r\n cyan: '\\x1b[36m',\r\n yellow: '\\x1b[33m',\r\n magenta: '\\x1b[35m',\r\n blue: '\\x1b[34m',\r\n red: '\\x1b[31m',\r\n white: '\\x1b[37m',\r\n gray: '\\x1b[90m',\r\n bgGreen: '\\x1b[42m',\r\n bgCyan: '\\x1b[46m',\r\n bgMagenta: '\\x1b[45m',\r\n};\r\n\r\nconst symbols = {\r\n success: '✓',\r\n arrow: '→',\r\n bullet: '○',\r\n filled: '●',\r\n lambda: 'λ',\r\n static: '○',\r\n ssr: '●',\r\n info: 'ℹ',\r\n};\r\n\r\n// Format milliseconds to human readable\r\nfunction formatTime(ms: number): string {\r\n if (ms < 1) return '<1ms';\r\n if (ms < 10) return `${ms.toFixed(1)}ms`;\r\n if (ms < 1000) return `${Math.round(ms)}ms`;\r\n if (ms < 60000) return `${(ms / 1000).toFixed(2)}s`;\r\n const mins = Math.floor(ms / 60000);\r\n const secs = Math.round((ms % 60000) / 1000);\r\n return `${mins}m ${secs}s`;\r\n}\r\n\r\n// Format bytes to human readable\r\nfunction formatBytes(bytes: number): string {\r\n if (bytes < 1024) return `${bytes} B`;\r\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} kB`;\r\n return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;\r\n}\r\n\r\n// Logger with Next.js-style formatting\r\nconst logger = {\r\n header: (text: string) => {\r\n console.log(`\\n${colors.bold}${colors.white}${text}${colors.reset}`);\r\n },\r\n \r\n info: (text: string) => {\r\n console.log(`${colors.cyan}${symbols.info}${colors.reset} ${text}`);\r\n },\r\n \r\n success: (text: string) => {\r\n console.log(`${colors.green}${symbols.success}${colors.reset} ${text}`);\r\n },\r\n \r\n route: (route: string, type: 'static' | 'ssr' | 'isr', size?: number, time?: number) => {\r\n const symbol = type === 'static' ? symbols.static : symbols.ssr;\r\n const color = type === 'static' ? colors.white : colors.magenta;\r\n const sizeStr = size ? ` ${colors.dim}${formatBytes(size)}${colors.reset}` : '';\r\n const timeStr = time ? ` ${colors.gray}(${formatTime(time)})${colors.reset}` : '';\r\n console.log(`${color}${symbol}${colors.reset} ${route}${sizeStr}${timeStr}`);\r\n },\r\n \r\n step: (step: string, time?: number) => {\r\n const timeStr = time ? ` ${colors.gray}${formatTime(time)}${colors.reset}` : '';\r\n console.log(` ${colors.dim}${symbols.arrow}${colors.reset} ${step}${timeStr}`);\r\n },\r\n \r\n buildComplete: (totalRoutes: number, staticRoutes: number, totalTime: number) => {\r\n console.log('');\r\n console.log(`${colors.bold}${colors.green}${symbols.success} Build completed!${colors.reset}`);\r\n console.log('');\r\n console.log(` ${colors.dim}Routes:${colors.reset} ${totalRoutes} total`);\r\n console.log(` ${colors.dim}Static:${colors.reset} ${staticRoutes} prerendered`);\r\n console.log(` ${colors.dim}Time:${colors.reset} ${formatTime(totalTime)}`);\r\n console.log('');\r\n },\r\n \r\n legend: () => {\r\n console.log(`${colors.dim}${symbols.static} Static${colors.reset} ${colors.dim}${symbols.ssr} SSR${colors.reset} ${colors.dim}λ ISR${colors.reset}`);\r\n },\r\n \r\n banner: (buildId: string) => {\r\n console.log('');\r\n console.log(`${colors.bold}${colors.cyan} 🟢 Olova${colors.reset} ${colors.dim}Static Export${colors.reset}`);\r\n console.log(`${colors.dim} Build ID: ${buildId}${colors.reset}`);\r\n console.log('');\r\n },\r\n \r\n error: (text: string) => {\r\n console.log(`${colors.red}✗${colors.reset} ${colors.red}${text}${colors.reset}`);\r\n },\r\n \r\n warn: (text: string) => {\r\n console.log(`${colors.yellow}⚠${colors.reset} ${colors.yellow}${text}${colors.reset}`);\r\n },\r\n};\r\n\r\n// =============================================================================\r\n// SSG PLUGIN - Static Site Generation\r\n// =============================================================================\r\nexport function ssgPlugin(): Plugin {\r\n return {\r\n name: 'olova-ssg',\r\n apply: 'build',\r\n config() {\r\n if (process.env.IS_SSG_BUILD) {\r\n return {};\r\n }\r\n return {\r\n build: {\r\n manifest: true,\r\n rollupOptions: {\r\n input: 'index.html'\r\n }\r\n }\r\n }\r\n },\r\n async closeBundle() {\r\n if (process.env.IS_SSG_BUILD) return;\r\n process.env.IS_SSG_BUILD = 'true';\r\n \r\n const totalStartTime = performance.now();\r\n const buildId = generateBuildId();\r\n \r\n // Show banner\r\n logger.banner(buildId);\r\n \r\n // =========================================================\r\n // STEP 1: Build Server Entry\r\n // =========================================================\r\n logger.header('Generating static pages...');\r\n const serverBuildStart = performance.now();\r\n \r\n try {\r\n await build({\r\n configFile: './vite.config.ts',\r\n build: {\r\n ssr: true,\r\n outDir: '.olova/server',\r\n rollupOptions: {\r\n input: 'olova/server',\r\n },\r\n emptyOutDir: true,\r\n reportCompressedSize: false,\r\n },\r\n // Ensure virtual modules are bundled, not left as external imports\r\n ssr: {\r\n noExternal: true,\r\n },\r\n logLevel: 'silent',\r\n });\r\n logger.step('Server bundle compiled', performance.now() - serverBuildStart);\r\n } catch (e) {\r\n logger.error('SSG Build Failed');\r\n console.error(e);\r\n process.env.IS_SSG_BUILD = '';\r\n return;\r\n } finally {\r\n process.env.IS_SSG_BUILD = '';\r\n }\r\n\r\n // =========================================================\r\n // STEP 2: Scan Routes\r\n // =========================================================\r\n const scanStart = performance.now();\r\n const allRoutes: { route: string, isStatic: boolean, filePath: string }[] = [];\r\n \r\n const scan = (dir: string, base: string = '') => {\r\n if (!fs.existsSync(dir)) return;\r\n const entries = fs.readdirSync(dir, { withFileTypes: true });\r\n for (const entry of entries) {\r\n const fullPath = path.join(dir, entry.name);\r\n if (entry.isDirectory()) {\r\n const isRouteGroup = /^\\(.+\\)$/.test(entry.name);\r\n if (isRouteGroup) {\r\n scan(fullPath, base);\r\n } else {\r\n scan(fullPath, `${base}/${entry.name}`);\r\n }\r\n } else {\r\n const ext = path.extname(entry.name);\r\n const supportedExts = ['.tsx', '.jsx', '.html', '.md'];\r\n \r\n if (supportedExts.includes(ext)) {\r\n const nameNoExt = entry.name.replace(/\\.(tsx|jsx|html|md)$/, '');\r\n if (nameNoExt === 'root') continue;\r\n let route = base;\r\n if (nameNoExt !== 'index' && nameNoExt !== 'App') {\r\n route = `${base}/${nameNoExt}`;\r\n }\r\n if (route === '') route = '/';\r\n if (route.includes('$')) continue;\r\n \r\n if (ext === '.html' || ext === '.md') {\r\n allRoutes.push({ route, isStatic: true, filePath: fullPath });\r\n } else {\r\n const fileContent = fs.readFileSync(fullPath, 'utf-8');\r\n const firstLine = fileContent.trim().split('\\n')[0].trim();\r\n const isStatic = firstLine === '\"static\"' || firstLine === \"'static'\";\r\n allRoutes.push({ route, isStatic, filePath: fullPath });\r\n }\r\n }\r\n }\r\n }\r\n };\r\n scan(path.resolve('src'));\r\n logger.step(`Found ${allRoutes.length} routes`, performance.now() - scanStart);\r\n\r\n // =========================================================\r\n // STEP 3: Load Server Entry\r\n // =========================================================\r\n const serverDir = path.resolve('.olova/server');\r\n let serverFile = fs.readdirSync(serverDir).find(f => \r\n (f === 'server.js' || f.includes('server-entry')) && f.endsWith('.js')\r\n );\r\n if (!serverFile) {\r\n logger.error('Could not find server build artifact');\r\n return;\r\n }\r\n const serverEntryPath = path.join(serverDir, serverFile);\r\n const { render, renderShell, renderShellWithMetadata, loadRoute } = await import(pathToFileURL(serverEntryPath).href);\r\n\r\n // =========================================================\r\n // STEP 4: Prepare Assets\r\n // =========================================================\r\n const assetsStart = performance.now();\r\n const distDir = path.resolve('.olova/dist');\r\n const clientHtmlPath = path.join(distDir, 'index.html');\r\n \r\n let shellHtml = renderShell();\r\n if (!shellHtml.startsWith('<!DOCTYPE html>')) {\r\n shellHtml = `<!DOCTYPE html>\\n${shellHtml}`;\r\n }\r\n \r\n let template = '';\r\n if (fs.existsSync(clientHtmlPath)) {\r\n template = fs.readFileSync(clientHtmlPath, 'utf-8');\r\n }\r\n\r\n // Read manifest to get CSS and JS entry files\r\n const manifestPath = path.join(distDir, '.vite', 'manifest.json');\r\n let cssLinks: string[] = [];\r\n let entryScript = ''; // The main entry point script tag\r\n if (fs.existsSync(manifestPath)) {\r\n try {\r\n const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));\r\n // Find entry point files (CSS and JS)\r\n for (const [key, value] of Object.entries(manifest)) {\r\n const entry = value as { isEntry?: boolean; css?: string[]; file?: string };\r\n \r\n // Extract CSS files from all entries\r\n if (entry.css && entry.css.length > 0) {\r\n for (const cssFile of entry.css) {\r\n const cssLink = `<link rel=\"stylesheet\" href=\"/${cssFile}\" />`;\r\n if (!cssLinks.includes(cssLink)) {\r\n cssLinks.push(cssLink);\r\n }\r\n }\r\n }\r\n \r\n // Extract the main entry JS file (this is critical for hydration!)\r\n if (entry.isEntry && entry.file) {\r\n entryScript = `<script type=\"module\" crossorigin src=\"/${entry.file}\"></script>`;\r\n logger.step(`Found entry script: ${entry.file}`);\r\n }\r\n }\r\n if (cssLinks.length > 0) {\r\n logger.step(`Found ${cssLinks.length} CSS file(s) from manifest`);\r\n }\r\n if (!entryScript) {\r\n // Fallback: look for any olova-*.js file in the static folder\r\n const staticDir = path.join(distDir, 'pro_olova_static');\r\n if (fs.existsSync(staticDir)) {\r\n const files = fs.readdirSync(staticDir);\r\n const entryFile = files.find(f => f.startsWith('olova-') && f.endsWith('.js'));\r\n if (entryFile) {\r\n entryScript = `<script type=\"module\" crossorigin src=\"/pro_olova_static/${entryFile}\"></script>`;\r\n logger.step(`Found entry script (fallback): ${entryFile}`);\r\n }\r\n }\r\n }\r\n } catch (e) {\r\n logger.warn('Could not parse manifest.json');\r\n }\r\n }\r\n\r\n const scripts = template.match(/<script[\\s\\S]*?>[\\s\\S]*?<\\/script>/gi) || [];\r\n const links = template.match(/<link[\\s\\S]*?>/gi) || [];\r\n \r\n const chunksDir = path.join(distDir, 'pro_olova_static', 'chunks');\r\n let preloadLinks: string[] = [];\r\n if (fs.existsSync(chunksDir)) {\r\n const chunks = fs.readdirSync(chunksDir).filter(f => f.endsWith('.js'));\r\n preloadLinks = chunks.map(chunk => \r\n `<link rel=\"modulepreload\" crossorigin href=\"/pro_olova_static/chunks/${chunk}\" />`\r\n );\r\n }\r\n \r\n const mainScriptMatch = template.match(/src=\"(\\/pro_olova_static\\/olova-[^\"]+\\.js)\"/);\r\n if (mainScriptMatch) {\r\n preloadLinks.unshift(`<link rel=\"modulepreload\" crossorigin href=\"${mainScriptMatch[1]}\" />`);\r\n }\r\n \r\n const chunkList: string[] = [];\r\n if (fs.existsSync(chunksDir)) {\r\n const chunks = fs.readdirSync(chunksDir).filter(f => f.endsWith('.js'));\r\n chunks.forEach(chunk => chunkList.push(`/pro_olova_static/chunks/${chunk}`));\r\n }\r\n \r\n // Performance optimizations\r\n const resourceHints = generateResourceHints();\r\n const criticalCSS = generateCriticalCSS();\r\n const performanceMeta = generatePerformanceMeta();\r\n const swScript = generateServiceWorkerScript();\r\n const performanceHead = [performanceMeta, resourceHints, criticalCSS].join('');\r\n \r\n // Service Worker\r\n const allAssetsForSW = [\r\n '/',\r\n '/index.html',\r\n ...chunkList,\r\n ...cssLinks.map(l => l.match(/href=\"([^\"]+)\"/)?.[1]).filter(Boolean) as string[],\r\n ...links.map(l => l.match(/href=\"([^\"]+)\"/)?.[1]).filter(Boolean) as string[],\r\n ...(entryScript.match(/src=\"([^\"]+)\"/) ? [entryScript.match(/src=\"([^\"]+)\"/)![1]] : [])\r\n ];\r\n const swContent = generateServiceWorkerContent(buildId, allAssetsForSW);\r\n fs.writeFileSync(path.join(distDir, 'sw.js'), swContent);\r\n \r\n // Include CSS links first for fast style loading, then validation scripts, then the entry script\r\n const assets = [performanceHead, ...cssLinks, ...links, ...preloadLinks, ...scripts, entryScript, swScript].join('\\n');\r\n logger.step(`Assets optimized (${cssLinks.length} styles, ${preloadLinks.length} preloads, SW ready)`, performance.now() - assetsStart);\r\n\r\n // =========================================================\r\n // STEP 5: Generate Routes\r\n // =========================================================\r\n console.log('');\r\n logger.header('Route');\r\n logger.legend();\r\n console.log('');\r\n \r\n let staticCount = 0;\r\n const routeResults: { route: string, type: 'static' | 'ssr', size: number, time: number }[] = [];\r\n \r\n for (const { route, isStatic } of allRoutes) {\r\n const routeStart = performance.now();\r\n let finalHtml = '';\r\n let isFullRender = false;\r\n \r\n // Always try to render full page first (unless explicitly opted out, which we don't support yet)\r\n // This ensures SSG content matches Client hydration for better UX and SEO\r\n try {\r\n const { html, hydrationData } = await render(route);\r\n if (html) {\r\n finalHtml = html;\r\n isFullRender = true;\r\n staticCount++;\r\n \r\n if (Object.keys(hydrationData.params || {}).length > 0) {\r\n const scriptTag = `<script>window.__OLOVA_DATA__ = ${JSON.stringify(hydrationData)};</script>`;\r\n if (finalHtml.includes('</body>')) {\r\n finalHtml = finalHtml.replace('</body>', `${scriptTag}\\n</body>`);\r\n } else {\r\n finalHtml += `\\n${scriptTag}`;\r\n }\r\n }\r\n\r\n const jsonLdScript = generateJsonLd({ route, metadata: hydrationData.metadata });\r\n \r\n if (finalHtml.includes('</head>')) {\r\n finalHtml = finalHtml.replace('</head>', `${jsonLdScript}${assets}\\n</head>`);\r\n } else {\r\n finalHtml = finalHtml.replace('</body>', `${assets}\\n</body>`);\r\n }\r\n if (!finalHtml.startsWith('<!DOCTYPE html>')) {\r\n finalHtml = `<!DOCTYPE html>\\n${finalHtml}`;\r\n }\r\n\r\n const flightScripts = generateOlovaHydration({\r\n route,\r\n metadata: hydrationData.metadata,\r\n params: hydrationData.params,\r\n chunks: chunkList,\r\n isStatic: true,\r\n }, buildId);\r\n if (finalHtml.includes('</body>')) {\r\n finalHtml = finalHtml.replace('</body>', `${flightScripts}</body>`);\r\n }\r\n\r\n finalHtml = minifyHtml(finalHtml);\r\n }\r\n } catch (e) {\r\n // Fallback to shell if render fails\r\n console.error(`[SSG] Render failed for ${route}:`, e);\r\n }\r\n\r\n // Fallback to Shell Rendering if full render failed\r\n if (!isFullRender) {\r\n let pageMetadata = {};\r\n try {\r\n const routeResult = await loadRoute(route);\r\n if (routeResult && routeResult.metadata) {\r\n pageMetadata = routeResult.metadata;\r\n }\r\n } catch (e) {\r\n // Continue with empty metadata\r\n }\r\n \r\n finalHtml = renderShellWithMetadata(pageMetadata);\r\n if (!finalHtml.startsWith('<!DOCTYPE html>')) {\r\n finalHtml = `<!DOCTYPE html>\\n${finalHtml}`;\r\n }\r\n \r\n const jsonLdScript = generateJsonLd({ route, metadata: pageMetadata });\r\n \r\n if (finalHtml.includes('</head>')) {\r\n finalHtml = finalHtml.replace('</head>', `${jsonLdScript}${assets}\\n</head>`);\r\n } else {\r\n finalHtml = finalHtml.replace('</body>', `${assets}\\n</body>`);\r\n }\r\n \r\n const flightScripts = generateOlovaHydration({\r\n route,\r\n metadata: pageMetadata,\r\n chunks: chunkList,\r\n isStatic: false,\r\n }, buildId);\r\n if (finalHtml.includes('</body>')) {\r\n finalHtml = finalHtml.replace('</body>', `${flightScripts}</body>`);\r\n }\r\n }\r\n\r\n const outPath = path.join(distDir, route === '/' ? 'index.html' : `${route}/index.html`);\r\n fs.mkdirSync(path.dirname(outPath), { recursive: true });\r\n fs.writeFileSync(outPath, finalHtml);\r\n \r\n const routeTime = performance.now() - routeStart;\r\n const routeSize = Buffer.byteLength(finalHtml, 'utf8');\r\n routeResults.push({ route, type: isStatic ? 'static' : 'ssr', size: routeSize, time: routeTime });\r\n \r\n logger.route(route, isStatic ? 'static' : 'ssr', routeSize, routeTime);\r\n }\r\n\r\n // =========================================================\r\n // STEP 6: Generate 404.html\r\n // =========================================================\r\n const fallbackPath = path.join(distDir, '404.html');\r\n if (fs.existsSync(clientHtmlPath)) {\r\n fs.copyFileSync(clientHtmlPath, fallbackPath);\r\n }\r\n\r\n // =========================================================\r\n // Final Summary\r\n // =========================================================\r\n const totalTime = performance.now() - totalStartTime;\r\n logger.buildComplete(allRoutes.length, staticCount, totalTime);\r\n \r\n // Output directory info\r\n console.log(`${colors.dim} Output:${colors.reset} .olova/dist`);\r\n console.log('');\r\n }\r\n };\r\n}\r\n","// Helper function to minify HTML (Next.js-style compact output)\r\nexport function minifyHtml(html: string): string {\r\n return html\r\n // Remove HTML comments (but keep conditional comments)\r\n .replace(/<!--(?!\\[if).*?-->/gs, '')\r\n // Collapse multiple whitespace to single space\r\n .replace(/\\s+/g, ' ')\r\n // Remove whitespace between tags\r\n .replace(/> </g, '><')\r\n // Remove whitespace around tags\r\n .replace(/\\s*(<[^>]+>)\\s*/g, '$1')\r\n // Trim\r\n .trim();\r\n}\r\n\r\n// Generate unique build ID for cache busting (like Next.js buildId)\r\nexport function generateBuildId(): string {\r\n return Math.random().toString(36).substring(2, 15) + Date.now().toString(36);\r\n}\r\n\r\nexport function generateResourceHints(): string {\r\n return `\r\n <link rel=\"dns-prefetch\" href=\"//fonts.googleapis.com\">\r\n <link rel=\"dns-prefetch\" href=\"//fonts.gstatic.com\">\r\n <link rel=\"dns-prefetch\" href=\"//cdn.jsdelivr.net\">\r\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" crossorigin>\r\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\r\n `.trim().replace(/\\n\\s+/g, '');\r\n}\r\n\r\n// Generate critical CSS for above-the-fold content (inline in head)\r\nexport function generateCriticalCSS(): string {\r\n return `<style id=\"olova-critical\">\r\n *{box-sizing:border-box;margin:0;padding:0}\r\n html{-webkit-text-size-adjust:100%;line-height:1.5}\r\n body{font-family:system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif}\r\n img,video{max-width:100%;height:auto}\r\n [hidden]{display:none!important}\r\n </style>`.replace(/\\n\\s*/g, '');\r\n}\r\n\r\n// Generate service worker registration script\r\nexport function generateServiceWorkerScript(): string {\r\n return `<script>if('serviceWorker'in navigator){window.addEventListener('load',()=>{navigator.serviceWorker.register('/sw.js').catch(()=>{})})}</script>`;\r\n}\r\n\r\n// Generate service worker file content for offline caching\r\nexport function generateServiceWorkerContent(buildId: string, assets: string[]): string {\r\n return `// Olova Service Worker v${buildId}\r\nconst CACHE_NAME = 'olova-cache-${buildId}';\r\nconst ASSETS = ${JSON.stringify(assets)};\r\n\r\nself.addEventListener('install', (e) => {\r\n e.waitUntil(caches.open(CACHE_NAME).then(cache => cache.addAll(ASSETS)));\r\n self.skipWaiting();\r\n});\r\n\r\nself.addEventListener('activate', (e) => {\r\n e.waitUntil(caches.keys().then(keys => Promise.all(\r\n keys.filter(k => k !== CACHE_NAME).map(k => caches.delete(k))\r\n )));\r\n});\r\n\r\nself.addEventListener('fetch', (e) => {\r\n e.respondWith(caches.match(e.request).then(r => r || fetch(e.request)));\r\n});\r\n`;\r\n}\r\n\r\n// Generate performance meta tags\r\nexport function generatePerformanceMeta(): string {\r\n return `<meta http-equiv=\"x-dns-prefetch-control\" content=\"on\"><meta name=\"color-scheme\" content=\"light dark\">`;\r\n}\r\n","import { type Plugin } from 'vite';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\n\r\n// =============================================================================\r\n// CLEAN URL PLUGIN - Handles clean URLs in preview mode\r\n// =============================================================================\r\nexport function cleanUrlPlugin(): Plugin {\r\n return {\r\n name: 'olova-clean-url',\r\n configurePreviewServer(server) {\r\n // Use middleware that runs BEFORE Vite's static serving\r\n server.middlewares.use((req, res, next) => {\r\n const urlPath = (req.url || '/').split('?')[0];\r\n const distDir = path.resolve('.olova/dist');\r\n \r\n // Handle root path\r\n if (urlPath === '/') {\r\n const indexPath = path.join(distDir, 'index.html');\r\n if (fs.existsSync(indexPath)) {\r\n const content = fs.readFileSync(indexPath, 'utf-8');\r\n res.setHeader('Content-Type', 'text/html');\r\n res.end(content);\r\n return;\r\n }\r\n }\r\n \r\n // Skip if it has a file extension (assets, scripts, etc.)\r\n if (urlPath.includes('.')) return next();\r\n \r\n // Check if /route/index.html exists (clean URLs)\r\n const indexPath = path.join(distDir, urlPath, 'index.html');\r\n if (fs.existsSync(indexPath)) {\r\n const content = fs.readFileSync(indexPath, 'utf-8');\r\n res.setHeader('Content-Type', 'text/html');\r\n res.end(content);\r\n return;\r\n }\r\n \r\n next();\r\n });\r\n }\r\n };\r\n}\r\n","import { type Plugin } from \"vite\";\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\n\r\n// =============================================================================\r\n// AUTO GENERATE PLUGIN - Auto-generates boilerplate code for new route files\r\n// =============================================================================\r\n\r\n/**\r\n * Converts a folder name to PascalCase for component naming\r\n */\r\nfunction toPascalCase(str: string): string {\r\n // Remove $ prefix for dynamic routes\r\n const cleanStr = str.replace(/^\\$/, \"\");\r\n\r\n return cleanStr\r\n .split(/[-_]/)\r\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\r\n .join(\"\");\r\n}\r\n\r\n/**\r\n * Generates the boilerplate code for a new route component\r\n */\r\nfunction generateBoilerplate(folderName: string, isDynamic: boolean): string {\r\n const componentName = toPascalCase(folderName);\r\n\r\n if (isDynamic) {\r\n // Dynamic route with useParams\r\n const paramName = folderName.replace(/^\\$/, \"\");\r\n return `import { useParams } from '../../route';\r\n\r\nexport default function ${componentName}() {\r\n const { ${paramName} } = useParams();\r\n return (\r\n <div>\r\n <h1>${componentName} Page</h1>\r\n <p>{${paramName}}</p>\r\n </div>\r\n );\r\n}\r\n`;\r\n }\r\n\r\n // Regular static route\r\n return `export default function ${componentName}() {\r\n return (\r\n <div>\r\n <h1>${componentName} Page</h1>\r\n <p>Welcome to ${componentName}</p>\r\n </div>\r\n );\r\n}\r\n`;\r\n}\r\n\r\nexport function autoGeneratePlugin(): Plugin {\r\n let srcDir: string;\r\n\r\n return {\r\n name: \"olova-auto-generate\",\r\n\r\n configResolved(config) {\r\n srcDir = path.resolve(config.root, \"src\");\r\n },\r\n\r\n configureServer(server) {\r\n console.log(\r\n \"\\x1b[36m[olova] Auto-generate plugin active - watching for new route files\\x1b[0m\"\r\n );\r\n\r\n // Watch for file creation events\r\n server.watcher.on(\"add\", (filePath: string) => {\r\n // Normalize path for Windows compatibility\r\n const normalizedPath = path.normalize(filePath);\r\n const normalizedSrcDir = path.normalize(srcDir);\r\n\r\n // Only process .tsx or .jsx files\r\n const ext = path.extname(normalizedPath);\r\n if (ext !== \".tsx\" && ext !== \".jsx\") {\r\n return;\r\n }\r\n\r\n // Check if file is inside src directory\r\n if (!normalizedPath.startsWith(normalizedSrcDir)) {\r\n return;\r\n }\r\n\r\n // Get the file name without extension\r\n const fileName = path.basename(normalizedPath, ext);\r\n\r\n // Only auto-generate for index files\r\n if (fileName !== \"index\") {\r\n return;\r\n }\r\n\r\n // Get the folder name\r\n const folderPath = path.dirname(normalizedPath);\r\n const folderName = path.basename(folderPath);\r\n\r\n // Skip root src folder and route groups (folders starting with parentheses)\r\n if (folderName === \"src\" || folderName.startsWith(\"(\")) {\r\n return;\r\n }\r\n\r\n // Check if file is empty or very small (just created)\r\n try {\r\n fs.statSync(normalizedPath);\r\n const content = fs.readFileSync(normalizedPath, \"utf-8\");\r\n\r\n // Only generate if file is empty or has minimal content\r\n if (content.trim().length > 10) {\r\n return;\r\n }\r\n } catch (err) {\r\n // File might not exist yet or other error, skip\r\n return;\r\n }\r\n\r\n // Check if it's a dynamic route (folder starts with $)\r\n const isDynamic = folderName.startsWith(\"$\");\r\n\r\n // Generate the boilerplate\r\n const boilerplate = generateBoilerplate(folderName, isDynamic);\r\n\r\n // Write the boilerplate to the file\r\n try {\r\n fs.writeFileSync(normalizedPath, boilerplate, \"utf-8\");\r\n console.log(\r\n `\\x1b[32m✓ [olova] Auto-generated: ${folderName}/index${ext}\\x1b[0m`\r\n );\r\n } catch (err) {\r\n console.error(\r\n `\\x1b[31m✗ [olova] Failed to write boilerplate:\\x1b[0m`,\r\n err\r\n );\r\n }\r\n });\r\n },\r\n };\r\n}\r\n","import { type Plugin, type ViteDevServer } from 'vite';\r\nimport path from 'path';\r\n\r\n// =============================================================================\r\n// PROACTIVE ERROR CHECKER - Validates all files on save like Next.js\r\n// This makes Vite's error overlay show instantly for ANY file with an error\r\n// =============================================================================\r\n\r\nexport function proactiveErrorPlugin(): Plugin {\r\n return {\r\n name: 'olova-proactive-error',\r\n enforce: 'post',\r\n\r\n configureServer(devServer: ViteDevServer) {\r\n const srcDir = path.resolve(process.cwd(), 'src');\r\n\r\n // Function to validate a file and send error to Vite's overlay\r\n const validateFile = async (filePath: string) => {\r\n if (!filePath.startsWith(srcDir)) return;\r\n if (!/\\.(tsx?|jsx?)$/.test(filePath)) return;\r\n\r\n const relativePath = path.relative(srcDir, filePath);\r\n console.log('\\x1b[36m[olova]\\x1b[0m Checking:', relativePath);\r\n\r\n try {\r\n // Convert file path to URL format for Vite\r\n const url = '/' + path.relative(process.cwd(), filePath).replace(/\\\\/g, '/');\r\n \r\n // Proactively transform the file\r\n await devServer.transformRequest(url);\r\n \r\n console.log('\\x1b[32m[olova]\\x1b[0m ✓', relativePath, 'OK');\r\n } catch (err: any) {\r\n console.log('\\x1b[31m[olova]\\x1b[0m ✗', relativePath);\r\n \r\n // Send error to Vite's error overlay via WebSocket\r\n // This is the official way Vite shows errors in the overlay\r\n devServer.ws.send({\r\n type: 'error',\r\n err: {\r\n message: err.message || String(err),\r\n stack: err.stack || '',\r\n id: err.id || filePath,\r\n frame: err.frame || '',\r\n plugin: err.plugin || 'olova',\r\n loc: err.loc || undefined,\r\n },\r\n });\r\n }\r\n };\r\n\r\n // Watch for file changes\r\n devServer.watcher.on('change', async (filePath: string) => {\r\n // Small delay to ensure file is fully written\r\n await new Promise(r => setTimeout(r, 50));\r\n await validateFile(filePath);\r\n });\r\n\r\n // Also check new files when they're added\r\n devServer.watcher.on('add', async (filePath: string) => {\r\n // Wait for file to be fully written\r\n await new Promise(r => setTimeout(r, 100));\r\n await validateFile(filePath);\r\n });\r\n },\r\n };\r\n}\r\n","// Import all plugins from separate files\r\nexport { configPlugin } from './config';\r\nexport { routerPlugin } from './router';\r\nexport { frameworkPlugin } from './framework';\r\nexport { virtualHtmlPlugin } from './virtual-html';\r\nexport { ssgPlugin } from './ssg';\r\nexport { cleanUrlPlugin } from './clean-url';\r\nexport { autoGeneratePlugin } from './auto-generate';\r\nexport { proactiveErrorPlugin } from './error-overlay';\r\n\r\n// Import all plugins for the combined array\r\nimport { configPlugin } from './config';\r\nimport { routerPlugin } from './router';\r\nimport { frameworkPlugin } from './framework';\r\nimport { virtualHtmlPlugin } from './virtual-html';\r\nimport { ssgPlugin } from './ssg';\r\nimport { cleanUrlPlugin } from './clean-url';\r\nimport { autoGeneratePlugin } from './auto-generate';\r\nimport { proactiveErrorPlugin } from './error-overlay';\r\n\r\n// =============================================================================\r\n// EXPORT ALL PLUGINS AS A SINGLE ARRAY\r\n// =============================================================================\r\n// Using 'any[]' return type to avoid Vite version conflicts between packages\r\n// This prevents TypeScript errors when consumer projects have different Vite versions\r\nexport function olovaPlugins(): any[] {\r\n return [\r\n configPlugin(), // Must be first - creates .olova folder and sets config\r\n routerPlugin(),\r\n frameworkPlugin(),\r\n virtualHtmlPlugin(),\r\n ssgPlugin(),\r\n cleanUrlPlugin(),\r\n autoGeneratePlugin(), // Auto-generates boilerplate for new route files\r\n proactiveErrorPlugin(), // Checks all files on save for instant error detection\r\n ];\r\n}\r\n","// =============================================================================\r\n// TERMINAL STYLING UTILITIES\r\n// Next.js-inspired console output for professional CLI experience\r\n// =============================================================================\r\n\r\n// ANSI color codes for terminal styling\r\nexport const colors = {\r\n // Reset\r\n reset: '\\x1b[0m',\r\n \r\n // Styles\r\n bold: '\\x1b[1m',\r\n dim: '\\x1b[2m',\r\n italic: '\\x1b[3m',\r\n underline: '\\x1b[4m',\r\n \r\n // Foreground colors\r\n black: '\\x1b[30m',\r\n red: '\\x1b[31m',\r\n green: '\\x1b[32m',\r\n yellow: '\\x1b[33m',\r\n blue: '\\x1b[34m',\r\n magenta: '\\x1b[35m',\r\n cyan: '\\x1b[36m',\r\n white: '\\x1b[37m',\r\n gray: '\\x1b[90m',\r\n \r\n // Background colors\r\n bgBlack: '\\x1b[40m',\r\n bgRed: '\\x1b[41m',\r\n bgGreen: '\\x1b[42m',\r\n bgYellow: '\\x1b[43m',\r\n bgBlue: '\\x1b[44m',\r\n bgMagenta: '\\x1b[45m',\r\n bgCyan: '\\x1b[46m',\r\n bgWhite: '\\x1b[47m',\r\n};\r\n\r\n// Symbols for terminal output\r\nexport const symbols = {\r\n success: '✓',\r\n error: '✗',\r\n warning: '⚠',\r\n info: 'ℹ',\r\n arrow: '→',\r\n arrowRight: '➜',\r\n bullet: '○',\r\n filled: '●',\r\n lambda: 'λ',\r\n triangle: '🟢',\r\n square: '■',\r\n diamond: '◆',\r\n star: '★',\r\n check: '✔',\r\n cross: '✖',\r\n pointer: '❯',\r\n};\r\n\r\n// Format time in human readable format\r\nexport function formatTime(ms: number): string {\r\n if (ms < 1) return '<1ms';\r\n if (ms < 10) return `${ms.toFixed(1)}ms`;\r\n if (ms < 1000) return `${Math.round(ms)}ms`;\r\n if (ms < 60000) return `${(ms / 1000).toFixed(2)}s`;\r\n const mins = Math.floor(ms / 60000);\r\n const secs = Math.round((ms % 60000) / 1000);\r\n return `${mins}m ${secs}s`;\r\n}\r\n\r\n// Format bytes in human readable format\r\nexport function formatBytes(bytes: number): string {\r\n if (bytes === 0) return '0 B';\r\n const k = 1024;\r\n const sizes = ['B', 'kB', 'MB', 'GB'];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;\r\n}\r\n\r\n// Logger utility with Next.js-style formatting\r\nexport const logger = {\r\n // Print banner\r\n banner: (name: string, version: string = '1.0.0') => {\r\n console.log('');\r\n console.log(` ${colors.bold}${colors.cyan}${symbols.triangle} ${name}${colors.reset} ${colors.dim}v${version}${colors.reset}`);\r\n console.log('');\r\n },\r\n \r\n // Print header\r\n header: (text: string) => {\r\n console.log(`\\n${colors.bold}${colors.white}${text}${colors.reset}`);\r\n },\r\n \r\n // Info message\r\n info: (text: string) => {\r\n console.log(`${colors.cyan}${symbols.info}${colors.reset} ${text}`);\r\n },\r\n \r\n // Success message\r\n success: (text: string, time?: number) => {\r\n const timeStr = time !== undefined ? ` ${colors.dim}${formatTime(time)}${colors.reset}` : '';\r\n console.log(`${colors.green}${symbols.success}${colors.reset} ${text}${timeStr}`);\r\n },\r\n \r\n // Error message\r\n error: (text: string) => {\r\n console.log(`${colors.red}${symbols.error}${colors.reset} ${colors.red}${text}${colors.reset}`);\r\n },\r\n \r\n // Warning message\r\n warn: (text: string) => {\r\n console.log(`${colors.yellow}${symbols.warning}${colors.reset} ${colors.yellow}${text}${colors.reset}`);\r\n },\r\n \r\n // Step in a process\r\n step: (text: string, time?: number) => {\r\n const timeStr = time !== undefined ? ` ${colors.gray}${formatTime(time)}${colors.reset}` : '';\r\n console.log(` ${colors.dim}${symbols.arrow}${colors.reset} ${text}${timeStr}`);\r\n },\r\n \r\n // Route log (for SSG)\r\n route: (route: string, type: 'static' | 'ssr' | 'isr', size?: number, time?: number) => {\r\n const symbol = type === 'static' ? symbols.bullet : type === 'ssr' ? symbols.filled : symbols.lambda;\r\n const color = type === 'static' ? colors.white : type === 'ssr' ? colors.magenta : colors.cyan;\r\n const sizeStr = size ? ` ${colors.dim}${formatBytes(size)}${colors.reset}` : '';\r\n const timeStr = time ? ` ${colors.gray}(${formatTime(time)})${colors.reset}` : '';\r\n console.log(`${color}${symbol}${colors.reset} ${route}${sizeStr}${timeStr}`);\r\n },\r\n \r\n // Indent text \r\n indent: (text: string, level: number = 1) => {\r\n console.log(`${' '.repeat(level)}${text}`);\r\n },\r\n \r\n // Empty line\r\n newline: () => console.log(''),\r\n \r\n // Dim text\r\n dim: (text: string) => `${colors.dim}${text}${colors.reset}`,\r\n \r\n // Bold text \r\n bold: (text: string) => `${colors.bold}${text}${colors.reset}`,\r\n \r\n // Colored text\r\n cyan: (text: string) => `${colors.cyan}${text}${colors.reset}`,\r\n green: (text: string) => `${colors.green}${text}${colors.reset}`,\r\n yellow: (text: string) => `${colors.yellow}${text}${colors.reset}`,\r\n red: (text: string) => `${colors.red}${text}${colors.reset}`,\r\n magenta: (text: string) => `${colors.magenta}${text}${colors.reset}`,\r\n};\r\n\r\n// Create a timer for measuring performance\r\nexport function createTimer() {\r\n const start = performance.now();\r\n return {\r\n elapsed: () => performance.now() - start,\r\n format: () => formatTime(performance.now() - start),\r\n };\r\n}\r\n"],"mappings":";AACA,OAAO,QAAQ;AACf,OAAO,UAAU;AAGjB,IAAM,SAAS;AAAA,EACX,OAAO;AAAA,EACP,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AACX;AAKO,SAAS,eAAuB;AACrC,QAAM,WAAW,KAAK,QAAQ,QAAQ;AAEtC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO,SAAS,EAAE,QAAQ,GAAG;AAE3B,UAAI,CAAC,GAAG,WAAW,QAAQ,GAAG;AAC5B,WAAG,UAAU,UAAU,EAAE,WAAW,KAAK,CAAC;AAAA,MAC5C;AAGA,UAAI,QAAQ,IAAI,cAAc;AAC5B,eAAO;AAAA,UACL,SAAS;AAAA,UACT,UAAU;AAAA,QACZ;AAAA,MACF;AAGA,UAAI,YAAY,SAAS;AACvB,gBAAQ,IAAI,EAAE;AACd,gBAAQ,IAAI,KAAK,OAAO,IAAI,GAAG,OAAO,IAAI,kBAAW,OAAO,KAAK,IAAI,OAAO,GAAG,SAAS,OAAO,KAAK,EAAE;AACtG,gBAAQ,IAAI,EAAE;AAAA,MAChB;AAEA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,OAAO;AAAA,UACL,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,uBAAuB;AAAA,UACvB,eAAe;AAAA,YACb,OAAO,SAAS,MAAM;AAEpB,kBAAI,QAAQ,SAAS,oBAAoB,QAAQ,SAAS,SAAS,8BAA8B,GAAG;AAClG;AAAA,cACF;AAEA,kBAAI,QAAQ,SAAS,SAAS,yBAAyB,KAAK,QAAQ,SAAS,SAAS,QAAQ,GAAG;AAC/F;AAAA,cACF;AAEA,kBAAI,QAAQ,SAAS,SAAS,WAAW,KAAK,QAAQ,SAAS,SAAS,iCAAiC,GAAG;AAC1G;AAAA,cACF;AACA,mBAAK,OAAO;AAAA,YACd;AAAA,YACA,QAAQ;AAAA,cACN,gBAAgB;AAAA,cAChB,gBAAgB;AAAA,cAChB,gBAAgB;AAAA,cAChB,aAAa,IAAI;AACf,oBAAI,GAAG,SAAS,cAAc,GAAG;AAC/B,sBAAI,GAAG,SAAS,WAAW,GAAG;AAC5B,2BAAO;AAAA,kBACT;AACA,sBAAI,GAAG,SAAS,OAAO,GAAG;AACxB,2BAAO;AAAA,kBACT;AAEA,sBAAI,GAAG,SAAS,OAAO,GAAG;AACxB,2BAAO;AAAA,kBACT;AACA,yBAAO;AAAA,gBACT;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,SAAS;AAAA,UACP,MAAM;AAAA,UACN,YAAY;AAAA,QACd;AAAA;AAAA,QAEA,cAAc;AAAA,UACZ,SAAS,CAAC,SAAS,cAAc;AAAA,QACnC;AAAA;AAAA,QAEA,KAAK;AAAA,UACH,YAAY,CAAC,SAAS,WAAW;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAAA,IACA,gBAAgB,QAAQ;AAEtB,aAAO,YAAY,KAAK,aAAa,MAAM;AACzC,cAAM,UAAU,OAAO,YAAY,QAAQ;AAC3C,cAAM,OAAO,OAAO,YAAY,YAAY,UAAU,QAAQ,OAAO;AAErE,mBAAW,MAAM;AACf,kBAAQ,IAAI,KAAK,OAAO,KAAK,SAAI,OAAO,KAAK,aAAa,OAAO,GAAG,GAAG,KAAK,MAAM,YAAY,IAAI,CAAC,CAAC,KAAK,OAAO,KAAK,EAAE;AACvH,kBAAQ,IAAI,EAAE;AACd,kBAAQ,IAAI,KAAK,OAAO,GAAG,SAAI,OAAO,KAAK,KAAK,OAAO,IAAI,SAAS,OAAO,KAAK,MAAM,OAAO,IAAI,oBAAoB,IAAI,IAAI,OAAO,KAAK,EAAE;AAC3I,kBAAQ,IAAI,EAAE;AAAA,QAChB,GAAG,GAAG;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;ACpHA,OAAOA,SAAQ;AACf,OAAOC,WAAU;AAKV,SAAS,eAAuB;AACrC,QAAM,kBAAkB;AACxB,QAAM,0BAA0B,OAAO;AACvC,MAAI,SAA+B;AAGnC,QAAM,mBAAmB,MAAM;AAC7B,QAAI,QAAQ;AACV,YAAM,MAAM,OAAO,YAAY,cAAc,uBAAuB;AACpE,UAAI,KAAK;AACP,eAAO,YAAY,iBAAiB,GAAG;AAEvC,eAAO,GAAG,KAAK;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,QACR,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA;AAAA,IAGT,gBAAgB,WAAW;AACzB,eAAS;AACT,YAAM,SAASA,MAAK,QAAQ,QAAQ,IAAI,GAAG,KAAK;AAGhD,YAAM,UAAU,UAAU;AAG1B,cAAQ,GAAG,OAAO,CAAC,aAAqB;AACtC,YAAI,SAAS,WAAW,MAAM,KAAK,uBAAuB,KAAK,QAAQ,GAAG;AACxE,kBAAQ,IAAI,8CAA8CA,MAAK,SAAS,QAAQ,QAAQ,CAAC;AACzF,2BAAiB;AAAA,QACnB;AAAA,MACF,CAAC;AAGD,cAAQ,GAAG,UAAU,CAAC,aAAqB;AACzC,YAAI,SAAS,WAAW,MAAM,KAAK,uBAAuB,KAAK,QAAQ,GAAG;AACxE,kBAAQ,IAAI,yCAAyCA,MAAK,SAAS,QAAQ,QAAQ,CAAC;AACpF,2BAAiB;AAAA,QACnB;AAAA,MACF,CAAC;AAGD,cAAQ,GAAG,UAAU,CAAC,YAAoB;AACxC,YAAI,QAAQ,WAAW,MAAM,KAAK,YAAY,QAAQ;AACpD,kBAAQ,IAAI,qDAAqDA,MAAK,SAAS,QAAQ,OAAO,CAAC;AAAA,QAEjG;AAAA,MACF,CAAC;AAGD,cAAQ,GAAG,aAAa,CAAC,YAAoB;AAC3C,YAAI,QAAQ,WAAW,MAAM,KAAK,YAAY,QAAQ;AACpD,kBAAQ,IAAI,gDAAgDA,MAAK,SAAS,QAAQ,OAAO,CAAC;AAC1F,2BAAiB;AAAA,QACnB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAEA,UAAU,IAAI;AACZ,UAAI,OAAO,iBAAiB;AAC1B,eAAO;AAAA,MACT;AAAA,IACF;AAAA;AAAA,IAGA,gBAAgB,EAAE,MAAM,QAAQ,UAAU,GAAG;AAC3C,YAAM,SAASA,MAAK,QAAQ,QAAQ,IAAI,GAAG,KAAK;AAGhD,UAAI,KAAK,WAAW,MAAM,KAAK,eAAe,KAAK,IAAI,GAAG;AACxD,cAAM,MAAM,UAAU,YAAY,cAAc,uBAAuB;AACvE,YAAI,KAAK;AACP,oBAAU,YAAY,iBAAiB,GAAG;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AAAA,IAEA,KAAK,IAAI;AACP,UAAI,OAAO,yBAAyB;AAClC,cAAM,SAASA,MAAK,QAAQ,QAAQ,IAAI,GAAG,KAAK;AAMhD,cAAM,YAAY,CAAC,KAAa,YAAoB,IAAI,iBAAyB,OAAiB;AAC9F,gBAAM,UAAUD,IAAG,YAAY,KAAK,EAAE,eAAe,KAAK,CAAC;AAC3D,cAAI,SAAmB,CAAC;AAExB,qBAAW,SAAS,SAAS;AACzB,kBAAM,YAAY,MAAM;AACxB,kBAAM,WAAWC,MAAK,KAAK,KAAK,SAAS;AAEzC,gBAAI,MAAM,YAAY,GAAG;AAErB,oBAAM,eAAe,WAAW,KAAK,SAAS;AAE9C,kBAAI,cAAc;AAGd,yBAAS,OAAO,OAAO;AAAA,kBACnB;AAAA,kBACA;AAAA;AAAA,kBACA,GAAG,cAAc,IAAI,SAAS;AAAA;AAAA,gBAClC,CAAC;AAAA,cACL,OAAO;AAEH,yBAAS,OAAO,OAAO;AAAA,kBACnB;AAAA,kBACA,GAAG,SAAS,IAAI,SAAS;AAAA,kBACzB,GAAG,cAAc,IAAI,SAAS;AAAA,gBAClC,CAAC;AAAA,cACL;AAAA,YACJ,OAAO;AAEH,oBAAM,MAAMA,MAAK,QAAQ,SAAS;AAClC,oBAAM,gBAAgB,CAAC,QAAQ,QAAQ,SAAS,KAAK;AAErD,kBAAI,cAAc,SAAS,GAAG,GAAG;AAC7B,sBAAM,YAAY,UAAU,QAAQ,wBAAwB,EAAE;AAC9D,oBAAI,cAAc,OAAQ;AAE1B,oBAAI,YAAY;AAChB,oBAAI,cAAc,WAAW,cAAc,OAAO;AAC9C,8BAAY,GAAG,SAAS,IAAI,SAAS;AAAA,gBACzC;AAEA,oBAAI,cAAc,GAAI,aAAY;AAGlC,sBAAM,sBAAsB,UACvB,QAAQ,oBAAoB,KAAK;AAGtC,sBAAM,aAAa,OAAO,cAAc,IAAI,SAAS;AAErD,oBAAI,QAAQ,SAAS;AAEjB,yBAAO,KAAK,MAAM,mBAAmB,oBAAoB,UAAU,iMAAiM;AAAA,gBACxQ,WAAW,QAAQ,OAAO;AAEtB,yBAAO,KAAK,MAAM,mBAAmB,oBAAoB,UAAU,6EAA6E;AAAA,gBACpJ,OAAO;AAEH,wBAAM,cAAcD,IAAG,aAAa,UAAU,OAAO;AACrD,wBAAM,YAAY,YAAY,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC,EAAE,KAAK;AACzD,wBAAM,qBAAqB,cAAc,cAAc,cAAc;AAErE,sBAAI,oBAAoB;AAEpB,2BAAO,KAAK,MAAM,mBAAmB,oBAAoB,UAAU,2DAA2D;AAAA,kBAClI,OAAO;AAEH,2BAAO,KAAK,MAAM,mBAAmB,oBAAoB,UAAU,KAAK;AAAA,kBAC5E;AAAA,gBACJ;AAAA,cACJ;AAAA,YACJ;AAAA,UACJ;AACA,iBAAO;AAAA,QACX;AAEA,YAAI,aAAuB,CAAC;AAC5B,YAAIA,IAAG,WAAW,MAAM,GAAG;AACvB,uBAAa,UAAU,MAAM;AAAA,QACjC;AAEA,eAAO;AAAA,EACb,WAAW,KAAK,IAAI,CAAC;AAAA;AAAA,MAEjB;AAAA,IACF;AAAA,EACF;AACF;;;AC3LA,SAAsB,4BAA4B;AAK3C,SAAS,kBAA0B;AACxC,QAAM,qBAAqB;AAC3B,QAAM,6BAA6B,OAAO;AAC1C,QAAM,qBAAqB;AAC3B,QAAM,6BAA6B,OAAO;AAE1C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU,IAAY;AACpB,UAAI,OAAO,sBAAsB,OAAO,mBAAmB,OAAO,mBAAoB,QAAO;AAC7F,UAAI,OAAO,sBAAsB,OAAO,mBAAmB,OAAO,mBAAoB,QAAO;AAAA,IAC/F;AAAA,IACA,MAAM,KAAK,IAAY;AACrB,UAAI,OAAO,4BAA4B;AACrC,cAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqHb,cAAM,SAAS,MAAM,qBAAqB,MAAM,oBAAoB;AAAA,UAChE,QAAQ;AAAA,UACR,KAAK;AAAA,QACT,CAAC;AACD,eAAO,OAAO;AAAA,MAChB;AACA,UAAI,OAAO,4BAA4B;AACrC,cAAM,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyNb,cAAM,SAAS,MAAM,qBAAqB,MAAM,oBAAoB;AAAA,UAChE,QAAQ;AAAA,UACR,KAAK;AAAA,QACT,CAAC;AACD,eAAO,OAAO;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACF;;;AChXA,OAAOE,SAAQ;AACf,OAAOC,WAAU;;;AC6BV,SAAS,uBAAuB,MAA0B,SAAyB;AACtF,QAAM,OAAQ,KAAK,YAAY,CAAC;AAChC,QAAM,UAAoB,CAAC;AAG3B,UAAQ,KAAK,4FAA4F;AAKzG,QAAM,aAA0B;AAAA,IAC5B,MAAM;AAAA,IACN,MAAM;AAAA,MACF,MAAM,KAAK;AAAA,MACX,QAAQ,KAAK,UAAU,CAAC;AAAA,MACxB,SAAS,KAAK,UAAU,MAAM,MAAM,KAAK,MAAM,QAAQ,YAAY,QAAQ;AAAA,MAC3E,UAAU,KAAK,YAAY;AAAA,MAC3B;AAAA,IACJ;AAAA,EACJ;AACA,UAAQ,KAAK,mBAAmB,WAAW,IAAI,KAAK,KAAK,UAAU,WAAW,IAAI,CAAC,aAAa;AAKhG,QAAM,gBAA6B;AAAA,IAC/B,MAAM;AAAA,IACN,MAAM;AAAA,MACF,OAAO,KAAK,SAAS;AAAA,MACrB,aAAa,KAAK,eAAe;AAAA,MACjC,UAAU,MAAM,QAAQ,KAAK,QAAQ,IAAI,KAAK,WAAW,CAAC;AAAA,MAC1D,QAAQ,KAAK,UAAU;AAAA,MACvB,WAAW,KAAK,aAAa;AAAA,MAC7B,IAAI;AAAA,QACA,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,GAAK,KAAK,aAAwB,CAAC;AAAA,MACvC;AAAA,MACA,SAAS;AAAA,QACL,MAAM;AAAA,QACN,GAAK,KAAK,WAAsB,CAAC;AAAA,MACrC;AAAA,IACJ;AAAA,EACJ;AACA,UAAQ,KAAK,mBAAmB,cAAc,IAAI,KAAK,KAAK,UAAU,cAAc,IAAI,CAAC,aAAa;AAKtG,QAAM,WAAW,KAAK,UAAU,MAC1B,aACA,KAAK,MAAM,MAAM,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,OAAK,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI;AAEjG,QAAM,YAAyB;AAAA,IAC3B,MAAM;AAAA,IACN,MAAM;AAAA,MACF,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,OAAO;AAAA,MACP,UAAU;AAAA,IACd;AAAA,EACJ;AACA,UAAQ,KAAK,mBAAmB,UAAU,IAAI,KAAK,KAAK,UAAU,UAAU,IAAI,CAAC,aAAa;AAK9F,QAAM,iBAA8B;AAAA,IAChC,MAAM;AAAA,IACN,MAAM;AAAA,MACF;AAAA,QACI,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,MAAM,KAAK,SAAS;AAAA,QACpB,aAAa,KAAK,eAAe;AAAA,QACjC,KAAK,KAAK;AAAA,MACd;AAAA,MACA;AAAA,QACI,YAAY;AAAA,QACZ,SAAS;AAAA,QACT,MAAM;AAAA,QACN,qBAAqB;AAAA,QACrB,iBAAiB;AAAA,MACrB;AAAA,IACJ;AAAA,EACJ;AACA,UAAQ,KAAK,mBAAmB,eAAe,IAAI,KAAK,KAAK,UAAU,eAAe,IAAI,CAAC,aAAa;AAKxG,QAAM,cAA2B;AAAA,IAC7B,MAAM;AAAA,IACN,MAAM;AAAA,MACF,QAAQ,KAAK,UAAU,CAAC;AAAA,MACxB,QAAQ,CAAC;AAAA;AAAA,MAET,WAAW,KAAK,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC;AAAA,IAC5C;AAAA,EACJ;AACA,UAAQ,KAAK,mBAAmB,YAAY,IAAI,KAAK,KAAK,UAAU,YAAY,IAAI,CAAC,aAAa;AAKlG,QAAM,aAA0B;AAAA,IAC5B,MAAM;AAAA,IACN,MAAM;AAAA,MACF,aAAa,CAAC,wBAAwB,mBAAmB;AAAA,MACzD,YAAY,CAAC,gCAAgC,2BAA2B;AAAA,MACxE,gBAAgB,KAAK,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC;AAAA,IACjD;AAAA,EACJ;AACA,UAAQ,KAAK,mBAAmB,WAAW,IAAI,KAAK,KAAK,UAAU,WAAW,IAAI,CAAC,aAAa;AAKhG,QAAM,aAA0B;AAAA,IAC5B,MAAM;AAAA,IACN,MAAM;AAAA,MACF,UAAU;AAAA,MACV,WAAW;AAAA,MACX,OAAO;AAAA,MACP,WAAW,KAAK,IAAI;AAAA,MACpB,SAAS;AAAA,MACT;AAAA,IACJ;AAAA,EACJ;AACA,UAAQ,KAAK,mBAAmB,WAAW,IAAI,KAAK,KAAK,UAAU,WAAW,IAAI,CAAC,aAAa;AAKhG,UAAQ,KAAK,oCAAoC;AAKjD,QAAM,gBAAgB;AAAA,IAClB,QAAQ,WAAW;AAAA,IACnB,OAAO,cAAc;AAAA,IACrB,OAAO,UAAU;AAAA,IACjB,SAAS,eAAe;AAAA,IACxB,SAAS,YAAY;AAAA,IACrB,QAAQ,WAAW;AAAA,IACnB,QAAQ,WAAW;AAAA,IACnB,QAAQ;AAAA,MACJ,IAAI;AAAA,MACJ,SAAS;AAAA,MACT,WAAW,KAAK,IAAI;AAAA,MACpB,KAAK;AAAA,IACT;AAAA,EACJ;AACA,UAAQ,KAAK,kBAAkB,KAAK,UAAU,aAAa,CAAC,WAAW;AAEvE,SAAO,QAAQ,KAAK,EAAE;AAC1B;AAMO,SAAS,eAAe,MAAkC;AAC7D,QAAM,OAAQ,KAAK,YAAY,CAAC;AAEhC,QAAM,SAAS;AAAA,IACX,YAAY;AAAA,IACZ,UAAU;AAAA,MACN;AAAA,QACI,SAAS;AAAA,QACT,OAAO,KAAK;AAAA,QACZ,MAAM,KAAK,SAAS;AAAA,QACpB,aAAa,KAAK,eAAe;AAAA,QACjC,KAAK,KAAK;AAAA,QACV,UAAU;AAAA,UACN,SAAS;AAAA,UACT,MAAM;AAAA,QACV;AAAA,MACJ;AAAA,MACA;AAAA,QACI,SAAS;AAAA,QACT,iBAAiB,KAAK,MAAM,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,IAAI,CAAC,SAAS,OAAO,SAAS;AAAA,UACjF,SAAS;AAAA,UACT,UAAU,QAAQ;AAAA,UAClB,MAAM,QAAQ,OAAO,CAAC,EAAE,YAAY,IAAI,QAAQ,MAAM,CAAC;AAAA,UACvD,MAAM,MAAM,IAAI,MAAM,GAAG,QAAQ,CAAC,EAAE,KAAK,GAAG;AAAA,QAChD,EAAE;AAAA,MACN;AAAA,IACJ;AAAA,EACJ;AAEA,SAAO,sCAAsC,KAAK,UAAU,MAAM,CAAC;AACvE;AAMO,SAAS,kBAAkD;AAE9D,MAAI,OAAO,eAAe,eAAe,OAAQ,WAAuC,aAAa,aAAa;AAC9G,WAAO;AAAA,EACX;AAEA,QAAM,cAAgB,WAAuC;AAC7D,MAAI,CAAC,YAAa,QAAO;AAEzB,QAAM,SAAkC,CAAC;AACzC,QAAM,UAA0C;AAAA,IAC5C,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,EACT;AAEA,aAAW,SAAS,aAAa;AAC7B,QAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,UAAU,GAAG;AAC3C,YAAM,CAAC,QAAQ,MAAM,IAAI,IAAI;AAC7B,YAAM,MAAM,QAAQ,IAAsB;AAC1C,UAAI,OAAO,QAAQ,QAAQ;AACvB,eAAO,GAAG,IAAI;AAAA,MAClB;AAAA,IACJ;AAAA,EACJ;AAEA,SAAO;AACX;;;AD3PO,SAAS,oBAA4B;AACxC,MAAI,aAAmC;AAGvC,QAAM,gBAAgB,CAAC,cAA6F;AAChH,UAAM,SAASC,MAAK,QAAQ,KAAK;AACjC,QAAI,WAAW,cAAc,MAAM,KAAK,UAAU,MAAM,CAAC;AAGzD,UAAM,cAAc;AAAA,MAChBA,MAAK,KAAK,QAAQ,UAAU,YAAY;AAAA,MACxCA,MAAK,KAAK,QAAQ,UAAU,UAAU;AAAA,MACtCA,MAAK,KAAK,QAAQ,WAAW,OAAO;AAAA,MACpCA,MAAK,KAAK,QAAQ,WAAW,KAAK;AAAA,IACtC;AAEA,eAAW,KAAK,aAAa;AACzB,UAAIC,IAAG,WAAW,CAAC,GAAG;AAClB,cAAM,MAAMD,MAAK,QAAQ,CAAC,EAAE,MAAM,CAAC;AACnC,eAAO,EAAE,UAAU,MAAM,UAAU,IAAI;AAAA,MAC3C;AAAA,IACJ;AAGA,UAAM,cAAc;AAAA,MAChBA,MAAK,KAAK,QAAQ,UAAU,WAAW;AAAA,MACvCA,MAAK,KAAK,QAAQ,UAAU,WAAW;AAAA,MACvCA,MAAK,KAAK,QAAQ,WAAW,MAAM;AAAA,MACnCA,MAAK,KAAK,QAAQ,WAAW,MAAM;AAAA,MACnCA,MAAK,KAAK,QAAQ,SAAS;AAAA,MAC3BA,MAAK,KAAK,QAAQ,SAAS;AAAA,IAC/B;AAEA,eAAW,KAAK,aAAa;AACzB,UAAIC,IAAG,WAAW,CAAC,GAAG;AAClB,cAAM,UAAUA,IAAG,aAAa,GAAG,OAAO;AAC1C,cAAM,YAAY,QAAQ,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC,EAAE,KAAK;AACrD,cAAM,WAAW,cAAc,cAAc,cAAc;AAC3D,cAAM,MAAMD,MAAK,QAAQ,CAAC,EAAE,MAAM,CAAC;AACnC,eAAO,EAAE,UAAU,UAAU,IAAI;AAAA,MACrC;AAAA,IACJ;AAEA,WAAO,EAAE,UAAU,OAAO,UAAU,KAAK;AAAA,EAC7C;AAGA,QAAM,kBAAkB,CAAC,aAA8C;AACnE,QAAI;AACA,UAAI,CAACC,IAAG,WAAW,QAAQ,EAAG,QAAO,CAAC;AACtC,YAAM,UAAUA,IAAG,aAAa,UAAU,OAAO;AAEjD,YAAM,gBAAgB,QAAQ,MAAM,iDAAiD;AACrF,UAAI,eAAe;AACf,YAAI;AACA,cAAI,UAAU,cAAc,CAAC,EACxB,QAAQ,MAAM,GAAG,EACjB,QAAQ,WAAW,OAAO,EAC1B,QAAQ,UAAU,GAAG,EACrB,QAAQ,UAAU,GAAG;AAC1B,iBAAO,KAAK,MAAM,OAAO;AAAA,QAC7B,QAAQ;AACJ,gBAAM,aAAa,QAAQ,MAAM,2BAA2B;AAC5D,gBAAM,YAAY,QAAQ,MAAM,iCAAiC;AACjE,iBAAO;AAAA,YACH,OAAO,aAAa,CAAC,KAAK;AAAA,YAC1B,aAAa,YAAY,CAAC,KAAK;AAAA,UACnC;AAAA,QACJ;AAAA,MACJ;AACA,aAAO,CAAC;AAAA,IACZ,QAAQ;AACJ,aAAO,CAAC;AAAA,IACZ;AAAA,EACJ;AAGA,QAAM,mBAAmB,CAAC,cAA+C;AACrE,UAAM,SAASD,MAAK,QAAQ,KAAK;AACjC,QAAI,WAAW,cAAc,MAAM,KAAK,UAAU,MAAM,CAAC;AAEzD,UAAM,gBAAgB;AAAA,MAClBA,MAAK,KAAK,QAAQ,UAAU,WAAW;AAAA,MACvCA,MAAK,KAAK,QAAQ,UAAU,WAAW;AAAA,MACvCA,MAAK,KAAK,QAAQ,WAAW,MAAM;AAAA,MACnCA,MAAK,KAAK,QAAQ,WAAW,MAAM;AAAA,MACnCA,MAAK,KAAK,QAAQ,SAAS;AAAA,MAC3BA,MAAK,KAAK,QAAQ,SAAS;AAAA,IAC/B;AAEA,eAAW,KAAK,eAAe;AAC3B,UAAIC,IAAG,WAAW,CAAC,GAAG;AAClB,eAAO,gBAAgB,CAAC;AAAA,MAC5B;AAAA,IACJ;AAEA,UAAM,WAAWD,MAAK,KAAK,QAAQ,UAAU;AAC7C,QAAIC,IAAG,WAAW,QAAQ,GAAG;AACzB,aAAO,gBAAgB,QAAQ;AAAA,IACnC;AAEA,WAAO,CAAC;AAAA,EACZ;AAGA,QAAM,eAAe,CAAC,WAAmB,aAA+C;AACpF,UAAM,OAAO,YAAY,iBAAiB,SAAS;AACnD,QAAI,cAAc;AAElB,QAAI,KAAK,OAAO;AACZ,qBAAe,UAAU,KAAK,KAAK;AAAA;AAAA,IACvC,OAAO;AACH,qBAAe;AAAA;AAAA,IACnB;AAEA,QAAI,KAAK,aAAa;AAClB,qBAAe,qCAAqC,KAAK,WAAW;AAAA;AAAA,IACxE;AAEA,QAAI,KAAK,UAAU;AACf,YAAM,WAAW,MAAM,QAAQ,KAAK,QAAQ,IACrC,KAAK,SAAsB,KAAK,IAAI,IACrC,KAAK;AACX,qBAAe,kCAAkC,QAAQ;AAAA;AAAA,IAC7D;AAEA,UAAM,eAAe,eAAe,EAAE,OAAO,WAAW,UAAU,KAAK,CAAC;AACxE,mBAAe,eAAe;AAE9B,mBAAe;AAAA;AAEf,WAAO;AAAA,EACX;AAGA,QAAM,mBAAmB,CAAC,WAAmB,UAAoC,aAA+B;AAC5G,UAAM,OAAO,YAAY,iBAAiB,SAAS;AACnD,UAAM,aAAa,SAAS,KAAK,IAAI,EAAE,SAAS,EAAE;AAClD,WAAO,uBAAuB;AAAA,MAC1B,OAAO;AAAA,MACP,UAAU;AAAA,MACV,QAAQ,CAAC;AAAA,MACT,UAAU,YAAY;AAAA,IAC1B,GAAG,UAAU;AAAA,EACjB;AAGA,QAAM,cAAc,YAA6B;AAC7C,QAAI,CAAC,WAAY,QAAO;AAExB,QAAI;AACA,YAAM,eAAe,MAAM,WAAW,cAAc,cAAc;AAClE,UAAI,cAAc,aAAa;AAC3B,eAAO,aAAa,YAAY,KAAK;AAAA,MACzC;AAAA,IACJ,SAAS,GAAQ;AAAA,IAEjB;AACA,WAAO;AAAA,EACX;AAGA,QAAM,iBAAiB,OAAO,cAAoF;AAC9G,QAAI,CAAC,WAAY,QAAO,EAAE,MAAM,IAAI,UAAU,CAAC,EAAE;AAEjD,QAAI;AACA,YAAM,eAAe,MAAM,WAAW,cAAc,cAAc;AAClE,UAAI,cAAc,QAAQ;AACtB,cAAM,SAAS,MAAM,aAAa,OAAO,SAAS;AAClD,eAAO;AAAA,UACH,MAAM,OAAO,QAAQ;AAAA,UACrB,UAAU,OAAO,eAAe,YAAY,CAAC;AAAA,QACjD;AAAA,MACJ;AAAA,IACJ,SAAS,GAAQ;AACb,cAAQ,MAAM,mCAAmC,EAAE,OAAO;AAAA,IAC9D;AACA,WAAO,EAAE,MAAM,IAAI,UAAU,CAAC,EAAE;AAAA,EACpC;AAGA,QAAM,iBAAiB,CAAC,MAAc,SAAiB,gBAAgC;AACnF,QAAI,SAAS;AAGb,QAAI,OAAO,SAAS,SAAS,GAAG;AAC5B,eAAS,OAAO,QAAQ,WAAW,UAAU,SAAS;AAAA,IAC1D;AAGA,QAAI,OAAO,SAAS,SAAS,GAAG;AAC5B,eAAS,OAAO;AAAA,QAAQ;AAAA,QACpB,cACA;AAAA,MACJ;AAAA,IACJ,OAAO;AACH,gBAAU,cAAc;AAAA,IAC5B;AAEA,WAAO;AAAA,EACX;AAEA,SAAO;AAAA,IACH,MAAM;AAAA,IACN,SAAS;AAAA,IAET,UAAU,IAAY;AAClB,UAAI,OAAO,gBAAgB,OAAO,wBAAwB,OAAO,eAAe;AAC5E,eAAO;AAAA,MACX;AAAA,IACJ;AAAA,IAEA,KAAK,IAAY;AACb,UAAI,OAAO,4BAA4B;AACnC,eAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAUX;AAAA,IACJ;AAAA,IAEA,gBAAgB,QAAQ;AACpB,mBAAa;AAEb,aAAO,MAAM;AACT,eAAO,YAAY,IAAI,OAAO,KAAK,KAAK,SAAS;AAC7C,gBAAM,MAAM,IAAI,OAAO;AAEvB,gBAAM,SAAS,IAAI,QAAQ,UAAU;AACrC,cAAI,CAAC,OAAO,SAAS,WAAW,GAAG;AAC/B,mBAAO,KAAK;AAAA,UAChB;AAEA,cAAI,IAAI,WAAW,IAAI,KAAK,IAAI,WAAW,KAAK,KAAK,IAAI,WAAW,eAAe,GAAG;AAClF,mBAAO,KAAK;AAAA,UAChB;AAEA,cAAI,SAAS,KAAK,GAAG,KAAK,CAAC,IAAI,SAAS,OAAO,GAAG;AAC9C,mBAAO,KAAK;AAAA,UAChB;AAEA,gBAAM,YAAY,IAAI,MAAM,GAAG,EAAE,CAAC,EAAE,QAAQ,QAAQ,EAAE,KAAK;AAE3D,cAAI;AACA,kBAAM,EAAE,UAAU,SAAS,IAAI,cAAc,SAAS;AACtD,kBAAM,gBAAgB,iBAAiB,SAAS;AAEhD,gBAAI;AACJ,gBAAI,WAAW,EAAE,GAAG,cAAc;AAElC,gBAAI,UAAU;AAEV,oBAAM,EAAE,MAAM,UAAU,UAAU,YAAY,IAAI,MAAM,eAAe,SAAS;AAChF,yBAAW,EAAE,GAAG,eAAe,GAAG,YAAY;AAE9C,kBAAI,UAAU;AACV,sBAAM,UAAU,aAAa,WAAW,QAAQ;AAChD,sBAAM,cAAc,iBAAiB,WAAW,UAAU,IAAI;AAC9D,4BAAY,eAAe,UAAU,SAAS,WAAW;AAAA,cAC7D,OAAO;AAEH,sBAAM,YAAY,MAAM,YAAY;AACpC,sBAAM,UAAU,aAAa,WAAW,QAAQ;AAChD,sBAAM,cAAc,iBAAiB,WAAW,UAAU,IAAI;AAE9D,oBAAI,WAAW;AACX,8BAAY,eAAe,WAAW,SAAS,WAAW;AAAA,gBAC9D,OAAO;AACH,8BAAY;AAAA;AAAA;AAAA;AAAA;AAAA,MAK1C,OAAO;AAAA;AAAA;AAAA,MAGP,WAAW;AAAA;AAAA;AAAA;AAAA,gBAIe;AAAA,cACJ;AAAA,YACJ,OAAO;AAGH,oBAAM,YAAY,MAAM,YAAY;AACpC,oBAAM,UAAU,aAAa,WAAW,QAAQ;AAChD,oBAAM,cAAc,iBAAiB,WAAW,UAAU,KAAK;AAE/D,kBAAI,WAAW;AAEX,4BAAY,eAAe,WAAW,SAAS,WAAW;AAAA,cAC9D,OAAO;AAEH,4BAAY;AAAA;AAAA;AAAA;AAAA;AAAA,MAKtC,OAAO;AAAA;AAAA;AAAA,MAGP,WAAW;AAAA;AAAA;AAAA;AAAA,cAIW;AAAA,YACJ;AAGA,gBAAI,CAAC,UAAU,KAAK,EAAE,YAAY,EAAE,WAAW,WAAW,GAAG;AACzD,0BAAY,sBAAsB;AAAA,YACtC;AAGA,kBAAM,kBAAkB,MAAM,OAAO,mBAAmB,KAAK,SAAS;AAEtE,gBAAI,UAAU,gBAAgB,WAAW;AACzC,gBAAI,aAAa;AACjB,gBAAI,IAAI,eAAe;AAAA,UAC3B,SAAS,GAAQ;AACb,oBAAQ,MAAM,kBAAkB,CAAC;AACjC,iBAAK,CAAC;AAAA,UACV;AAAA,QACJ,CAAC;AAAA,MACL;AAAA,IACJ;AAAA,EACJ;AACJ;;;AE5VA,SAAsB,aAAa;AACnC,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,qBAAqB;;;ACFvB,SAAS,WAAW,MAAsB;AAC7C,SAAO,KAEF,QAAQ,wBAAwB,EAAE,EAElC,QAAQ,QAAQ,GAAG,EAEnB,QAAQ,QAAQ,IAAI,EAEpB,QAAQ,oBAAoB,IAAI,EAEhC,KAAK;AACd;AAGO,SAAS,kBAA0B;AACtC,SAAO,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,GAAG,EAAE,IAAI,KAAK,IAAI,EAAE,SAAS,EAAE;AAC/E;AAEO,SAAS,wBAAgC;AAC5C,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAML,KAAK,EAAE,QAAQ,UAAU,EAAE;AACjC;AAGO,SAAS,sBAA8B;AAC1C,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAMG,QAAQ,UAAU,EAAE;AAClC;AAGO,SAAS,8BAAsC;AAClD,SAAO;AACX;AAGO,SAAS,6BAA6B,SAAiB,QAA0B;AACpF,SAAO,4BAA4B,OAAO;AAAA,kCACZ,OAAO;AAAA,iBACxB,KAAK,UAAU,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBvC;AAGO,SAAS,0BAAkC;AAC9C,SAAO;AACX;;;ADtDA,IAAMC,UAAS;AAAA,EACX,OAAO;AAAA,EACP,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AAAA,EACP,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,WAAW;AACf;AAEA,IAAM,UAAU;AAAA,EACZ,SAAS;AAAA,EACT,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,MAAM;AACV;AAGA,SAAS,WAAW,IAAoB;AACpC,MAAI,KAAK,EAAG,QAAO;AACnB,MAAI,KAAK,GAAI,QAAO,GAAG,GAAG,QAAQ,CAAC,CAAC;AACpC,MAAI,KAAK,IAAM,QAAO,GAAG,KAAK,MAAM,EAAE,CAAC;AACvC,MAAI,KAAK,IAAO,QAAO,IAAI,KAAK,KAAM,QAAQ,CAAC,CAAC;AAChD,QAAM,OAAO,KAAK,MAAM,KAAK,GAAK;AAClC,QAAM,OAAO,KAAK,MAAO,KAAK,MAAS,GAAI;AAC3C,SAAO,GAAG,IAAI,KAAK,IAAI;AAC3B;AAGA,SAAS,YAAY,OAAuB;AACxC,MAAI,QAAQ,KAAM,QAAO,GAAG,KAAK;AACjC,MAAI,QAAQ,OAAO,KAAM,QAAO,IAAI,QAAQ,MAAM,QAAQ,CAAC,CAAC;AAC5D,SAAO,IAAI,SAAS,OAAO,OAAO,QAAQ,CAAC,CAAC;AAChD;AAGA,IAAM,SAAS;AAAA,EACX,QAAQ,CAAC,SAAiB;AACtB,YAAQ,IAAI;AAAA,EAAKA,QAAO,IAAI,GAAGA,QAAO,KAAK,GAAG,IAAI,GAAGA,QAAO,KAAK,EAAE;AAAA,EACvE;AAAA,EAEA,MAAM,CAAC,SAAiB;AACpB,YAAQ,IAAI,GAAGA,QAAO,IAAI,GAAG,QAAQ,IAAI,GAAGA,QAAO,KAAK,IAAI,IAAI,EAAE;AAAA,EACtE;AAAA,EAEA,SAAS,CAAC,SAAiB;AACvB,YAAQ,IAAI,GAAGA,QAAO,KAAK,GAAG,QAAQ,OAAO,GAAGA,QAAO,KAAK,IAAI,IAAI,EAAE;AAAA,EAC1E;AAAA,EAEA,OAAO,CAAC,OAAe,MAAgC,MAAe,SAAkB;AACpF,UAAM,SAAS,SAAS,WAAW,QAAQ,SAAS,QAAQ;AAC5D,UAAM,QAAQ,SAAS,WAAWA,QAAO,QAAQA,QAAO;AACxD,UAAM,UAAU,OAAO,IAAIA,QAAO,GAAG,GAAG,YAAY,IAAI,CAAC,GAAGA,QAAO,KAAK,KAAK;AAC7E,UAAM,UAAU,OAAO,IAAIA,QAAO,IAAI,IAAI,WAAW,IAAI,CAAC,IAAIA,QAAO,KAAK,KAAK;AAC/E,YAAQ,IAAI,GAAG,KAAK,GAAG,MAAM,GAAGA,QAAO,KAAK,IAAI,KAAK,GAAG,OAAO,GAAG,OAAO,EAAE;AAAA,EAC/E;AAAA,EAEA,MAAM,CAAC,MAAc,SAAkB;AACnC,UAAM,UAAU,OAAO,IAAIA,QAAO,IAAI,GAAG,WAAW,IAAI,CAAC,GAAGA,QAAO,KAAK,KAAK;AAC7E,YAAQ,IAAI,KAAKA,QAAO,GAAG,GAAG,QAAQ,KAAK,GAAGA,QAAO,KAAK,IAAI,IAAI,GAAG,OAAO,EAAE;AAAA,EAClF;AAAA,EAEA,eAAe,CAAC,aAAqB,cAAsB,cAAsB;AAC7E,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,GAAGA,QAAO,IAAI,GAAGA,QAAO,KAAK,GAAG,QAAQ,OAAO,oBAAoBA,QAAO,KAAK,EAAE;AAC7F,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,KAAKA,QAAO,GAAG,UAAUA,QAAO,KAAK,KAAK,WAAW,QAAQ;AACzE,YAAQ,IAAI,KAAKA,QAAO,GAAG,UAAUA,QAAO,KAAK,KAAK,YAAY,cAAc;AAChF,YAAQ,IAAI,KAAKA,QAAO,GAAG,QAAQA,QAAO,KAAK,OAAO,WAAW,SAAS,CAAC,EAAE;AAC7E,YAAQ,IAAI,EAAE;AAAA,EAClB;AAAA,EAEA,QAAQ,MAAM;AACV,YAAQ,IAAI,GAAGA,QAAO,GAAG,GAAG,QAAQ,MAAM,UAAUA,QAAO,KAAK,KAAKA,QAAO,GAAG,GAAG,QAAQ,GAAG,OAAOA,QAAO,KAAK,KAAKA,QAAO,GAAG,aAAQA,QAAO,KAAK,EAAE;AAAA,EACzJ;AAAA,EAEA,QAAQ,CAAC,YAAoB;AACzB,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,GAAGA,QAAO,IAAI,GAAGA,QAAO,IAAI,qBAAcA,QAAO,KAAK,IAAIA,QAAO,GAAG,gBAAgBA,QAAO,KAAK,EAAE;AAC9G,YAAQ,IAAI,GAAGA,QAAO,GAAG,gBAAgB,OAAO,GAAGA,QAAO,KAAK,EAAE;AACjE,YAAQ,IAAI,EAAE;AAAA,EAClB;AAAA,EAEA,OAAO,CAAC,SAAiB;AACrB,YAAQ,IAAI,GAAGA,QAAO,GAAG,SAAIA,QAAO,KAAK,IAAIA,QAAO,GAAG,GAAG,IAAI,GAAGA,QAAO,KAAK,EAAE;AAAA,EACnF;AAAA,EAEA,MAAM,CAAC,SAAiB;AACpB,YAAQ,IAAI,GAAGA,QAAO,MAAM,SAAIA,QAAO,KAAK,IAAIA,QAAO,MAAM,GAAG,IAAI,GAAGA,QAAO,KAAK,EAAE;AAAA,EACzF;AACJ;AAKO,SAAS,YAAoB;AAChC,SAAO;AAAA,IACH,MAAM;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AACL,UAAI,QAAQ,IAAI,cAAc;AAC1B,eAAO,CAAC;AAAA,MACZ;AACA,aAAO;AAAA,QACH,OAAO;AAAA,UACH,UAAU;AAAA,UACV,eAAe;AAAA,YACX,OAAO;AAAA,UACX;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,IACA,MAAM,cAAc;AAChB,UAAI,QAAQ,IAAI,aAAc;AAC9B,cAAQ,IAAI,eAAe;AAE3B,YAAM,iBAAiB,YAAY,IAAI;AACvC,YAAM,UAAU,gBAAgB;AAGhC,aAAO,OAAO,OAAO;AAKrB,aAAO,OAAO,4BAA4B;AAC1C,YAAM,mBAAmB,YAAY,IAAI;AAEzC,UAAI;AACA,cAAM,MAAM;AAAA,UACR,YAAY;AAAA,UACZ,OAAO;AAAA,YACH,KAAK;AAAA,YACL,QAAQ;AAAA,YACR,eAAe;AAAA,cACX,OAAO;AAAA,YACX;AAAA,YACA,aAAa;AAAA,YACb,sBAAsB;AAAA,UAC1B;AAAA;AAAA,UAEA,KAAK;AAAA,YACD,YAAY;AAAA,UAChB;AAAA,UACA,UAAU;AAAA,QACd,CAAC;AACD,eAAO,KAAK,0BAA0B,YAAY,IAAI,IAAI,gBAAgB;AAAA,MAC9E,SAAS,GAAG;AACR,eAAO,MAAM,kBAAkB;AAC/B,gBAAQ,MAAM,CAAC;AACf,gBAAQ,IAAI,eAAe;AAC3B;AAAA,MACJ,UAAE;AACC,gBAAQ,IAAI,eAAe;AAAA,MAC9B;AAKA,YAAM,YAAY,YAAY,IAAI;AAClC,YAAM,YAAsE,CAAC;AAE7E,YAAM,OAAO,CAAC,KAAa,OAAe,OAAO;AAC7C,YAAI,CAACC,IAAG,WAAW,GAAG,EAAG;AACzB,cAAM,UAAUA,IAAG,YAAY,KAAK,EAAE,eAAe,KAAK,CAAC;AAC3D,mBAAW,SAAS,SAAS;AACzB,gBAAM,WAAWC,MAAK,KAAK,KAAK,MAAM,IAAI;AAC1C,cAAI,MAAM,YAAY,GAAG;AACrB,kBAAM,eAAe,WAAW,KAAK,MAAM,IAAI;AAC/C,gBAAI,cAAc;AACd,mBAAK,UAAU,IAAI;AAAA,YACvB,OAAO;AACH,mBAAK,UAAU,GAAG,IAAI,IAAI,MAAM,IAAI,EAAE;AAAA,YAC1C;AAAA,UACJ,OAAO;AACH,kBAAM,MAAMA,MAAK,QAAQ,MAAM,IAAI;AACnC,kBAAM,gBAAgB,CAAC,QAAQ,QAAQ,SAAS,KAAK;AAErD,gBAAI,cAAc,SAAS,GAAG,GAAG;AAC7B,oBAAM,YAAY,MAAM,KAAK,QAAQ,wBAAwB,EAAE;AAC/D,kBAAI,cAAc,OAAQ;AAC1B,kBAAI,QAAQ;AACZ,kBAAI,cAAc,WAAW,cAAc,OAAO;AAC9C,wBAAQ,GAAG,IAAI,IAAI,SAAS;AAAA,cAChC;AACA,kBAAI,UAAU,GAAI,SAAQ;AAC1B,kBAAI,MAAM,SAAS,GAAG,EAAG;AAEzB,kBAAI,QAAQ,WAAW,QAAQ,OAAO;AAClC,0BAAU,KAAK,EAAE,OAAO,UAAU,MAAM,UAAU,SAAS,CAAC;AAAA,cAChE,OAAO;AACH,sBAAM,cAAcD,IAAG,aAAa,UAAU,OAAO;AACrD,sBAAM,YAAY,YAAY,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC,EAAE,KAAK;AACzD,sBAAM,WAAW,cAAc,cAAc,cAAc;AAC3D,0BAAU,KAAK,EAAE,OAAO,UAAU,UAAU,SAAS,CAAC;AAAA,cAC1D;AAAA,YACJ;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AACA,WAAKC,MAAK,QAAQ,KAAK,CAAC;AACxB,aAAO,KAAK,SAAS,UAAU,MAAM,WAAW,YAAY,IAAI,IAAI,SAAS;AAK7E,YAAM,YAAYA,MAAK,QAAQ,eAAe;AAC9C,UAAI,aAAaD,IAAG,YAAY,SAAS,EAAE;AAAA,QAAK,QAC3C,MAAM,eAAe,EAAE,SAAS,cAAc,MAAM,EAAE,SAAS,KAAK;AAAA,MACzE;AACA,UAAI,CAAC,YAAY;AACb,eAAO,MAAM,sCAAsC;AACnD;AAAA,MACJ;AACA,YAAM,kBAAkBC,MAAK,KAAK,WAAW,UAAU;AACvD,YAAM,EAAE,QAAQ,aAAa,yBAAyB,UAAU,IAAI,MAAM,OAAO,cAAc,eAAe,EAAE;AAKhH,YAAM,cAAc,YAAY,IAAI;AACpC,YAAM,UAAUA,MAAK,QAAQ,aAAa;AAC1C,YAAM,iBAAiBA,MAAK,KAAK,SAAS,YAAY;AAEtD,UAAI,YAAY,YAAY;AAC5B,UAAI,CAAC,UAAU,WAAW,iBAAiB,GAAG;AAC1C,oBAAY;AAAA,EAAoB,SAAS;AAAA,MAC7C;AAEA,UAAI,WAAW;AACf,UAAID,IAAG,WAAW,cAAc,GAAG;AAC/B,mBAAWA,IAAG,aAAa,gBAAgB,OAAO;AAAA,MACtD;AAGA,YAAM,eAAeC,MAAK,KAAK,SAAS,SAAS,eAAe;AAChE,UAAI,WAAqB,CAAC;AAC1B,UAAI,cAAc;AAClB,UAAID,IAAG,WAAW,YAAY,GAAG;AAC7B,YAAI;AACA,gBAAM,WAAW,KAAK,MAAMA,IAAG,aAAa,cAAc,OAAO,CAAC;AAElE,qBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACjD,kBAAM,QAAQ;AAGd,gBAAI,MAAM,OAAO,MAAM,IAAI,SAAS,GAAG;AACnC,yBAAW,WAAW,MAAM,KAAK;AAC7B,sBAAM,UAAU,iCAAiC,OAAO;AACxD,oBAAI,CAAC,SAAS,SAAS,OAAO,GAAG;AAC7B,2BAAS,KAAK,OAAO;AAAA,gBACzB;AAAA,cACJ;AAAA,YACJ;AAGA,gBAAI,MAAM,WAAW,MAAM,MAAM;AAC7B,4BAAc,2CAA2C,MAAM,IAAI;AACnE,qBAAO,KAAK,uBAAuB,MAAM,IAAI,EAAE;AAAA,YACnD;AAAA,UACJ;AACA,cAAI,SAAS,SAAS,GAAG;AACrB,mBAAO,KAAK,SAAS,SAAS,MAAM,4BAA4B;AAAA,UACpE;AACA,cAAI,CAAC,aAAa;AAEd,kBAAM,YAAYC,MAAK,KAAK,SAAS,kBAAkB;AACvD,gBAAID,IAAG,WAAW,SAAS,GAAG;AAC1B,oBAAM,QAAQA,IAAG,YAAY,SAAS;AACtC,oBAAM,YAAY,MAAM,KAAK,OAAK,EAAE,WAAW,QAAQ,KAAK,EAAE,SAAS,KAAK,CAAC;AAC7E,kBAAI,WAAW;AACX,8BAAc,4DAA4D,SAAS;AACnF,uBAAO,KAAK,kCAAkC,SAAS,EAAE;AAAA,cAC7D;AAAA,YACJ;AAAA,UACJ;AAAA,QACJ,SAAS,GAAG;AACR,iBAAO,KAAK,+BAA+B;AAAA,QAC/C;AAAA,MACJ;AAEA,YAAM,UAAU,SAAS,MAAM,sCAAsC,KAAK,CAAC;AAC3E,YAAM,QAAQ,SAAS,MAAM,kBAAkB,KAAK,CAAC;AAErD,YAAM,YAAYC,MAAK,KAAK,SAAS,oBAAoB,QAAQ;AACjE,UAAI,eAAyB,CAAC;AAC9B,UAAID,IAAG,WAAW,SAAS,GAAG;AAC1B,cAAM,SAASA,IAAG,YAAY,SAAS,EAAE,OAAO,OAAK,EAAE,SAAS,KAAK,CAAC;AACtE,uBAAe,OAAO;AAAA,UAAI,WACtB,wEAAwE,KAAK;AAAA,QACjF;AAAA,MACJ;AAEA,YAAM,kBAAkB,SAAS,MAAM,6CAA6C;AACpF,UAAI,iBAAiB;AACjB,qBAAa,QAAQ,+CAA+C,gBAAgB,CAAC,CAAC,MAAM;AAAA,MAChG;AAEA,YAAM,YAAsB,CAAC;AAC7B,UAAIA,IAAG,WAAW,SAAS,GAAG;AAC1B,cAAM,SAASA,IAAG,YAAY,SAAS,EAAE,OAAO,OAAK,EAAE,SAAS,KAAK,CAAC;AACtE,eAAO,QAAQ,WAAS,UAAU,KAAK,4BAA4B,KAAK,EAAE,CAAC;AAAA,MAC/E;AAGA,YAAM,gBAAgB,sBAAsB;AAC5C,YAAM,cAAc,oBAAoB;AACxC,YAAM,kBAAkB,wBAAwB;AAChD,YAAM,WAAW,4BAA4B;AAC7C,YAAM,kBAAkB,CAAC,iBAAiB,eAAe,WAAW,EAAE,KAAK,EAAE;AAG7E,YAAM,iBAAiB;AAAA,QACnB;AAAA,QACA;AAAA,QACA,GAAG;AAAA,QACH,GAAG,SAAS,IAAI,OAAK,EAAE,MAAM,gBAAgB,IAAI,CAAC,CAAC,EAAE,OAAO,OAAO;AAAA,QACnE,GAAG,MAAM,IAAI,OAAK,EAAE,MAAM,gBAAgB,IAAI,CAAC,CAAC,EAAE,OAAO,OAAO;AAAA,QAChE,GAAI,YAAY,MAAM,eAAe,IAAI,CAAC,YAAY,MAAM,eAAe,EAAG,CAAC,CAAC,IAAI,CAAC;AAAA,MACzF;AACA,YAAM,YAAY,6BAA6B,SAAS,cAAc;AACtE,MAAAA,IAAG,cAAcC,MAAK,KAAK,SAAS,OAAO,GAAG,SAAS;AAGvD,YAAM,SAAS,CAAC,iBAAiB,GAAG,UAAU,GAAG,OAAO,GAAG,cAAc,GAAG,SAAS,aAAa,QAAQ,EAAE,KAAK,IAAI;AACrH,aAAO,KAAK,qBAAqB,SAAS,MAAM,YAAY,aAAa,MAAM,wBAAwB,YAAY,IAAI,IAAI,WAAW;AAKtI,cAAQ,IAAI,EAAE;AACd,aAAO,OAAO,OAAO;AACrB,aAAO,OAAO;AACd,cAAQ,IAAI,EAAE;AAEd,UAAI,cAAc;AAClB,YAAM,eAAwF,CAAC;AAE/F,iBAAW,EAAE,OAAO,SAAS,KAAK,WAAW;AACzC,cAAM,aAAa,YAAY,IAAI;AACnC,YAAI,YAAY;AAChB,YAAI,eAAe;AAInB,YAAI;AACA,gBAAM,EAAE,MAAM,cAAc,IAAI,MAAM,OAAO,KAAK;AAClD,cAAI,MAAM;AACN,wBAAY;AACZ,2BAAe;AACf;AAEA,gBAAI,OAAO,KAAK,cAAc,UAAU,CAAC,CAAC,EAAE,SAAS,GAAG;AACpD,oBAAM,YAAY,mCAAmC,KAAK,UAAU,aAAa,CAAC;AAClF,kBAAI,UAAU,SAAS,SAAS,GAAG;AAC/B,4BAAY,UAAU,QAAQ,WAAW,GAAG,SAAS;AAAA,QAAW;AAAA,cACpE,OAAO;AACH,6BAAa;AAAA,EAAK,SAAS;AAAA,cAC/B;AAAA,YACJ;AAEA,kBAAM,eAAe,eAAe,EAAE,OAAO,UAAU,cAAc,SAAS,CAAC;AAE/E,gBAAI,UAAU,SAAS,SAAS,GAAG;AAC/B,0BAAY,UAAU,QAAQ,WAAW,GAAG,YAAY,GAAG,MAAM;AAAA,QAAW;AAAA,YAChF,OAAO;AACH,0BAAY,UAAU,QAAQ,WAAW,GAAG,MAAM;AAAA,QAAW;AAAA,YACjE;AACA,gBAAI,CAAC,UAAU,WAAW,iBAAiB,GAAG;AAC1C,0BAAY;AAAA,EAAoB,SAAS;AAAA,YAC7C;AAEA,kBAAM,gBAAgB,uBAAuB;AAAA,cACzC;AAAA,cACA,UAAU,cAAc;AAAA,cACxB,QAAQ,cAAc;AAAA,cACtB,QAAQ;AAAA,cACR,UAAU;AAAA,YACd,GAAG,OAAO;AACV,gBAAI,UAAU,SAAS,SAAS,GAAG;AAC/B,0BAAY,UAAU,QAAQ,WAAW,GAAG,aAAa,SAAS;AAAA,YACtE;AAEA,wBAAY,WAAW,SAAS;AAAA,UACpC;AAAA,QACJ,SAAS,GAAG;AAER,kBAAQ,MAAM,2BAA2B,KAAK,KAAK,CAAC;AAAA,QACxD;AAGA,YAAI,CAAC,cAAc;AACf,cAAI,eAAe,CAAC;AACpB,cAAI;AACA,kBAAM,cAAc,MAAM,UAAU,KAAK;AACzC,gBAAI,eAAe,YAAY,UAAU;AACrC,6BAAe,YAAY;AAAA,YAC/B;AAAA,UACJ,SAAS,GAAG;AAAA,UAEZ;AAEA,sBAAY,wBAAwB,YAAY;AAChD,cAAI,CAAC,UAAU,WAAW,iBAAiB,GAAG;AAC1C,wBAAY;AAAA,EAAoB,SAAS;AAAA,UAC7C;AAEA,gBAAM,eAAe,eAAe,EAAE,OAAO,UAAU,aAAa,CAAC;AAErE,cAAI,UAAU,SAAS,SAAS,GAAG;AAC/B,wBAAY,UAAU,QAAQ,WAAW,GAAG,YAAY,GAAG,MAAM;AAAA,QAAW;AAAA,UAChF,OAAO;AACH,wBAAY,UAAU,QAAQ,WAAW,GAAG,MAAM;AAAA,QAAW;AAAA,UACjE;AAEA,gBAAM,gBAAgB,uBAAuB;AAAA,YACzC;AAAA,YACA,UAAU;AAAA,YACV,QAAQ;AAAA,YACR,UAAU;AAAA,UACd,GAAG,OAAO;AACV,cAAI,UAAU,SAAS,SAAS,GAAG;AAC/B,wBAAY,UAAU,QAAQ,WAAW,GAAG,aAAa,SAAS;AAAA,UACtE;AAAA,QACJ;AAEA,cAAM,UAAUA,MAAK,KAAK,SAAS,UAAU,MAAM,eAAe,GAAG,KAAK,aAAa;AACvF,QAAAD,IAAG,UAAUC,MAAK,QAAQ,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AACvD,QAAAD,IAAG,cAAc,SAAS,SAAS;AAEnC,cAAM,YAAY,YAAY,IAAI,IAAI;AACtC,cAAM,YAAY,OAAO,WAAW,WAAW,MAAM;AACrD,qBAAa,KAAK,EAAE,OAAO,MAAM,WAAW,WAAW,OAAO,MAAM,WAAW,MAAM,UAAU,CAAC;AAEhG,eAAO,MAAM,OAAO,WAAW,WAAW,OAAO,WAAW,SAAS;AAAA,MACzE;AAKA,YAAM,eAAeC,MAAK,KAAK,SAAS,UAAU;AAClD,UAAID,IAAG,WAAW,cAAc,GAAG;AAC/B,QAAAA,IAAG,aAAa,gBAAgB,YAAY;AAAA,MAChD;AAKA,YAAM,YAAY,YAAY,IAAI,IAAI;AACtC,aAAO,cAAc,UAAU,QAAQ,aAAa,SAAS;AAG7D,cAAQ,IAAI,GAAGD,QAAO,GAAG,YAAYA,QAAO,KAAK,eAAe;AAChE,cAAQ,IAAI,EAAE;AAAA,IAClB;AAAA,EACJ;AACJ;;;AEpeA,OAAOG,SAAQ;AACf,OAAOC,WAAU;AAKV,SAAS,iBAAyB;AACvC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,uBAAuB,QAAQ;AAE7B,aAAO,YAAY,IAAI,CAAC,KAAK,KAAK,SAAS;AACzC,cAAM,WAAW,IAAI,OAAO,KAAK,MAAM,GAAG,EAAE,CAAC;AAC7C,cAAM,UAAUA,MAAK,QAAQ,aAAa;AAG1C,YAAI,YAAY,KAAK;AACnB,gBAAMC,aAAYD,MAAK,KAAK,SAAS,YAAY;AACjD,cAAID,IAAG,WAAWE,UAAS,GAAG;AAC5B,kBAAM,UAAUF,IAAG,aAAaE,YAAW,OAAO;AAClD,gBAAI,UAAU,gBAAgB,WAAW;AACzC,gBAAI,IAAI,OAAO;AACf;AAAA,UACF;AAAA,QACF;AAGA,YAAI,QAAQ,SAAS,GAAG,EAAG,QAAO,KAAK;AAGvC,cAAM,YAAYD,MAAK,KAAK,SAAS,SAAS,YAAY;AAC1D,YAAID,IAAG,WAAW,SAAS,GAAG;AAC5B,gBAAM,UAAUA,IAAG,aAAa,WAAW,OAAO;AAClD,cAAI,UAAU,gBAAgB,WAAW;AACzC,cAAI,IAAI,OAAO;AACf;AAAA,QACF;AAEA,aAAK;AAAA,MACP,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;AC1CA,OAAOG,SAAQ;AACf,OAAOC,WAAU;AASjB,SAAS,aAAa,KAAqB;AAEzC,QAAM,WAAW,IAAI,QAAQ,OAAO,EAAE;AAEtC,SAAO,SACJ,MAAM,MAAM,EACZ,IAAI,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC,EAAE,YAAY,CAAC,EACxE,KAAK,EAAE;AACZ;AAKA,SAAS,oBAAoB,YAAoB,WAA4B;AAC3E,QAAM,gBAAgB,aAAa,UAAU;AAE7C,MAAI,WAAW;AAEb,UAAM,YAAY,WAAW,QAAQ,OAAO,EAAE;AAC9C,WAAO;AAAA;AAAA,0BAEe,aAAa;AAAA,cACzB,SAAS;AAAA;AAAA;AAAA,kBAGL,aAAa;AAAA,kBACb,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAKzB;AAGA,SAAO,2BAA2B,aAAa;AAAA;AAAA;AAAA,kBAG/B,aAAa;AAAA,4BACH,aAAa;AAAA;AAAA;AAAA;AAAA;AAKzC;AAEO,SAAS,qBAA6B;AAC3C,MAAI;AAEJ,SAAO;AAAA,IACL,MAAM;AAAA,IAEN,eAAe,QAAQ;AACrB,eAASA,MAAK,QAAQ,OAAO,MAAM,KAAK;AAAA,IAC1C;AAAA,IAEA,gBAAgB,QAAQ;AACtB,cAAQ;AAAA,QACN;AAAA,MACF;AAGA,aAAO,QAAQ,GAAG,OAAO,CAAC,aAAqB;AAE7C,cAAM,iBAAiBA,MAAK,UAAU,QAAQ;AAC9C,cAAM,mBAAmBA,MAAK,UAAU,MAAM;AAG9C,cAAM,MAAMA,MAAK,QAAQ,cAAc;AACvC,YAAI,QAAQ,UAAU,QAAQ,QAAQ;AACpC;AAAA,QACF;AAGA,YAAI,CAAC,eAAe,WAAW,gBAAgB,GAAG;AAChD;AAAA,QACF;AAGA,cAAM,WAAWA,MAAK,SAAS,gBAAgB,GAAG;AAGlD,YAAI,aAAa,SAAS;AACxB;AAAA,QACF;AAGA,cAAM,aAAaA,MAAK,QAAQ,cAAc;AAC9C,cAAM,aAAaA,MAAK,SAAS,UAAU;AAG3C,YAAI,eAAe,SAAS,WAAW,WAAW,GAAG,GAAG;AACtD;AAAA,QACF;AAGA,YAAI;AACF,UAAAD,IAAG,SAAS,cAAc;AAC1B,gBAAM,UAAUA,IAAG,aAAa,gBAAgB,OAAO;AAGvD,cAAI,QAAQ,KAAK,EAAE,SAAS,IAAI;AAC9B;AAAA,UACF;AAAA,QACF,SAAS,KAAK;AAEZ;AAAA,QACF;AAGA,cAAM,YAAY,WAAW,WAAW,GAAG;AAG3C,cAAM,cAAc,oBAAoB,YAAY,SAAS;AAG7D,YAAI;AACF,UAAAA,IAAG,cAAc,gBAAgB,aAAa,OAAO;AACrD,kBAAQ;AAAA,YACN,0CAAqC,UAAU,SAAS,GAAG;AAAA,UAC7D;AAAA,QACF,SAAS,KAAK;AACZ,kBAAQ;AAAA,YACN;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;AC3IA,OAAOE,WAAU;AAOV,SAAS,uBAA+B;AAC7C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IAET,gBAAgB,WAA0B;AACxC,YAAM,SAASA,MAAK,QAAQ,QAAQ,IAAI,GAAG,KAAK;AAGhD,YAAM,eAAe,OAAO,aAAqB;AAC/C,YAAI,CAAC,SAAS,WAAW,MAAM,EAAG;AAClC,YAAI,CAAC,iBAAiB,KAAK,QAAQ,EAAG;AAEtC,cAAM,eAAeA,MAAK,SAAS,QAAQ,QAAQ;AACnD,gBAAQ,IAAI,oCAAoC,YAAY;AAE5D,YAAI;AAEF,gBAAM,MAAM,MAAMA,MAAK,SAAS,QAAQ,IAAI,GAAG,QAAQ,EAAE,QAAQ,OAAO,GAAG;AAG3E,gBAAM,UAAU,iBAAiB,GAAG;AAEpC,kBAAQ,IAAI,iCAA4B,cAAc,IAAI;AAAA,QAC5D,SAAS,KAAU;AACjB,kBAAQ,IAAI,iCAA4B,YAAY;AAIpD,oBAAU,GAAG,KAAK;AAAA,YAChB,MAAM;AAAA,YACN,KAAK;AAAA,cACH,SAAS,IAAI,WAAW,OAAO,GAAG;AAAA,cAClC,OAAO,IAAI,SAAS;AAAA,cACpB,IAAI,IAAI,MAAM;AAAA,cACd,OAAO,IAAI,SAAS;AAAA,cACpB,QAAQ,IAAI,UAAU;AAAA,cACtB,KAAK,IAAI,OAAO;AAAA,YAClB;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAGA,gBAAU,QAAQ,GAAG,UAAU,OAAO,aAAqB;AAEzD,cAAM,IAAI,QAAQ,OAAK,WAAW,GAAG,EAAE,CAAC;AACxC,cAAM,aAAa,QAAQ;AAAA,MAC7B,CAAC;AAGD,gBAAU,QAAQ,GAAG,OAAO,OAAO,aAAqB;AAEtD,cAAM,IAAI,QAAQ,OAAK,WAAW,GAAG,GAAG,CAAC;AACzC,cAAM,aAAa,QAAQ;AAAA,MAC7B,CAAC;AAAA,IACH;AAAA,EACF;AACF;;;ACzCO,SAAS,eAAsB;AACpC,SAAO;AAAA,IACL,aAAa;AAAA;AAAA,IACb,aAAa;AAAA,IACb,gBAAgB;AAAA,IAChB,kBAAkB;AAAA,IAClB,UAAU;AAAA,IACV,eAAe;AAAA,IACf,mBAAmB;AAAA;AAAA,IACnB,qBAAqB;AAAA;AAAA,EACvB;AACF;;;AC9BO,IAAMC,UAAS;AAAA;AAAA,EAElB,OAAO;AAAA;AAAA,EAGP,MAAM;AAAA,EACN,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,WAAW;AAAA;AAAA,EAGX,OAAO;AAAA,EACP,KAAK;AAAA,EACL,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AAAA,EACN,OAAO;AAAA,EACP,MAAM;AAAA;AAAA,EAGN,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,SAAS;AACb;AAGO,IAAMC,WAAU;AAAA,EACnB,SAAS;AAAA,EACT,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM;AAAA,EACN,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,SAAS;AACb;AAGO,SAASC,YAAW,IAAoB;AAC3C,MAAI,KAAK,EAAG,QAAO;AACnB,MAAI,KAAK,GAAI,QAAO,GAAG,GAAG,QAAQ,CAAC,CAAC;AACpC,MAAI,KAAK,IAAM,QAAO,GAAG,KAAK,MAAM,EAAE,CAAC;AACvC,MAAI,KAAK,IAAO,QAAO,IAAI,KAAK,KAAM,QAAQ,CAAC,CAAC;AAChD,QAAM,OAAO,KAAK,MAAM,KAAK,GAAK;AAClC,QAAM,OAAO,KAAK,MAAO,KAAK,MAAS,GAAI;AAC3C,SAAO,GAAG,IAAI,KAAK,IAAI;AAC3B;AAGO,SAASC,aAAY,OAAuB;AAC/C,MAAI,UAAU,EAAG,QAAO;AACxB,QAAM,IAAI;AACV,QAAM,QAAQ,CAAC,KAAK,MAAM,MAAM,IAAI;AACpC,QAAM,IAAI,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,CAAC,CAAC;AAClD,SAAO,GAAG,YAAY,QAAQ,KAAK,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC;AACzE;AAGO,IAAMC,UAAS;AAAA;AAAA,EAElB,QAAQ,CAAC,MAAc,UAAkB,YAAY;AACjD,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,KAAKJ,QAAO,IAAI,GAAGA,QAAO,IAAI,GAAGC,SAAQ,QAAQ,IAAI,IAAI,GAAGD,QAAO,KAAK,IAAIA,QAAO,GAAG,IAAI,OAAO,GAAGA,QAAO,KAAK,EAAE;AAC9H,YAAQ,IAAI,EAAE;AAAA,EAClB;AAAA;AAAA,EAGA,QAAQ,CAAC,SAAiB;AACtB,YAAQ,IAAI;AAAA,EAAKA,QAAO,IAAI,GAAGA,QAAO,KAAK,GAAG,IAAI,GAAGA,QAAO,KAAK,EAAE;AAAA,EACvE;AAAA;AAAA,EAGA,MAAM,CAAC,SAAiB;AACpB,YAAQ,IAAI,GAAGA,QAAO,IAAI,GAAGC,SAAQ,IAAI,GAAGD,QAAO,KAAK,IAAI,IAAI,EAAE;AAAA,EACtE;AAAA;AAAA,EAGA,SAAS,CAAC,MAAc,SAAkB;AACtC,UAAM,UAAU,SAAS,SAAY,IAAIA,QAAO,GAAG,GAAGE,YAAW,IAAI,CAAC,GAAGF,QAAO,KAAK,KAAK;AAC1F,YAAQ,IAAI,GAAGA,QAAO,KAAK,GAAGC,SAAQ,OAAO,GAAGD,QAAO,KAAK,IAAI,IAAI,GAAG,OAAO,EAAE;AAAA,EACpF;AAAA;AAAA,EAGA,OAAO,CAAC,SAAiB;AACrB,YAAQ,IAAI,GAAGA,QAAO,GAAG,GAAGC,SAAQ,KAAK,GAAGD,QAAO,KAAK,IAAIA,QAAO,GAAG,GAAG,IAAI,GAAGA,QAAO,KAAK,EAAE;AAAA,EAClG;AAAA;AAAA,EAGA,MAAM,CAAC,SAAiB;AACpB,YAAQ,IAAI,GAAGA,QAAO,MAAM,GAAGC,SAAQ,OAAO,GAAGD,QAAO,KAAK,IAAIA,QAAO,MAAM,GAAG,IAAI,GAAGA,QAAO,KAAK,EAAE;AAAA,EAC1G;AAAA;AAAA,EAGA,MAAM,CAAC,MAAc,SAAkB;AACnC,UAAM,UAAU,SAAS,SAAY,IAAIA,QAAO,IAAI,GAAGE,YAAW,IAAI,CAAC,GAAGF,QAAO,KAAK,KAAK;AAC3F,YAAQ,IAAI,KAAKA,QAAO,GAAG,GAAGC,SAAQ,KAAK,GAAGD,QAAO,KAAK,IAAI,IAAI,GAAG,OAAO,EAAE;AAAA,EAClF;AAAA;AAAA,EAGA,OAAO,CAAC,OAAe,MAAgC,MAAe,SAAkB;AACpF,UAAM,SAAS,SAAS,WAAWC,SAAQ,SAAS,SAAS,QAAQA,SAAQ,SAASA,SAAQ;AAC9F,UAAM,QAAQ,SAAS,WAAWD,QAAO,QAAQ,SAAS,QAAQA,QAAO,UAAUA,QAAO;AAC1F,UAAM,UAAU,OAAO,IAAIA,QAAO,GAAG,GAAGG,aAAY,IAAI,CAAC,GAAGH,QAAO,KAAK,KAAK;AAC7E,UAAM,UAAU,OAAO,IAAIA,QAAO,IAAI,IAAIE,YAAW,IAAI,CAAC,IAAIF,QAAO,KAAK,KAAK;AAC/E,YAAQ,IAAI,GAAG,KAAK,GAAG,MAAM,GAAGA,QAAO,KAAK,IAAI,KAAK,GAAG,OAAO,GAAG,OAAO,EAAE;AAAA,EAC/E;AAAA;AAAA,EAGA,QAAQ,CAAC,MAAc,QAAgB,MAAM;AACzC,YAAQ,IAAI,GAAG,KAAK,OAAO,KAAK,CAAC,GAAG,IAAI,EAAE;AAAA,EAC9C;AAAA;AAAA,EAGA,SAAS,MAAM,QAAQ,IAAI,EAAE;AAAA;AAAA,EAG7B,KAAK,CAAC,SAAiB,GAAGA,QAAO,GAAG,GAAG,IAAI,GAAGA,QAAO,KAAK;AAAA;AAAA,EAG1D,MAAM,CAAC,SAAiB,GAAGA,QAAO,IAAI,GAAG,IAAI,GAAGA,QAAO,KAAK;AAAA;AAAA,EAG5D,MAAM,CAAC,SAAiB,GAAGA,QAAO,IAAI,GAAG,IAAI,GAAGA,QAAO,KAAK;AAAA,EAC5D,OAAO,CAAC,SAAiB,GAAGA,QAAO,KAAK,GAAG,IAAI,GAAGA,QAAO,KAAK;AAAA,EAC9D,QAAQ,CAAC,SAAiB,GAAGA,QAAO,MAAM,GAAG,IAAI,GAAGA,QAAO,KAAK;AAAA,EAChE,KAAK,CAAC,SAAiB,GAAGA,QAAO,GAAG,GAAG,IAAI,GAAGA,QAAO,KAAK;AAAA,EAC1D,SAAS,CAAC,SAAiB,GAAGA,QAAO,OAAO,GAAG,IAAI,GAAGA,QAAO,KAAK;AACtE;AAGO,SAAS,cAAc;AAC1B,QAAM,QAAQ,YAAY,IAAI;AAC9B,SAAO;AAAA,IACH,SAAS,MAAM,YAAY,IAAI,IAAI;AAAA,IACnC,QAAQ,MAAME,YAAW,YAAY,IAAI,IAAI,KAAK;AAAA,EACtD;AACJ;","names":["fs","path","fs","path","path","fs","fs","path","colors","fs","path","fs","path","indexPath","fs","path","path","colors","symbols","formatTime","formatBytes","logger"]}
1
+ {"version":3,"sources":["../src/plugins/config.ts","../src/plugins/router.ts","../src/plugins/framework.ts","../src/plugins/virtual-html.ts","../src/plugins/hydration.ts","../src/plugins/ssg.ts","../src/plugins/utils.ts","../src/plugins/clean-url.ts","../src/plugins/auto-generate.ts","../src/plugins/error-overlay.ts","../src/plugins/index.ts","../src/plugins/terminal.ts"],"sourcesContent":["import { type Plugin } from 'vite';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\n\r\n// Terminal colors\r\nconst colors = {\r\n reset: '\\x1b[0m',\r\n bold: '\\x1b[1m',\r\n dim: '\\x1b[2m',\r\n cyan: '\\x1b[36m',\r\n green: '\\x1b[32m',\r\n white: '\\x1b[37m',\r\n};\r\n\r\n// =============================================================================\r\n// CONFIG PLUGIN - Creates .olova folder and configures Vite settings\r\n// =============================================================================\r\nexport function configPlugin(): Plugin {\r\n const olovaDir = path.resolve('.olova');\r\n \r\n return {\r\n name: 'olova-config',\r\n config(_config, { command }) {\r\n // Create .olova folder on startup\r\n if (!fs.existsSync(olovaDir)) {\r\n fs.mkdirSync(olovaDir, { recursive: true });\r\n }\r\n \r\n // Skip build config for SSG builds\r\n if (process.env.IS_SSG_BUILD) {\r\n return {\r\n appType: 'custom',\r\n cacheDir: './.olova/cache',\r\n };\r\n }\r\n \r\n // Show startup banner for dev mode\r\n if (command === 'serve') {\r\n console.log('');\r\n console.log(` ${colors.bold}${colors.cyan}🟢 Olova${colors.reset} ${colors.dim}v1.0.0${colors.reset}`);\r\n console.log('');\r\n }\r\n \r\n return {\r\n appType: 'custom',\r\n cacheDir: './.olova/cache',\r\n build: {\r\n outDir: './.olova/dist',\r\n sourcemap: false,\r\n chunkSizeWarningLimit: 500,\r\n rollupOptions: {\r\n onwarn(warning, warn) {\r\n // Suppress \"dynamic import will not move module\" warnings\r\n if (warning.code === 'PLUGIN_WARNING' && warning.message?.includes('dynamic import will not move')) {\r\n return;\r\n }\r\n // Suppress \"static\" directive warnings (Olova uses this for static routes)\r\n if (warning.message?.includes('Module level directives') && warning.message?.includes('static')) {\r\n return;\r\n }\r\n // Suppress sourcemap warnings for static directive\r\n if (warning.message?.includes('sourcemap') && warning.message?.includes(\"Can't resolve original location\")) {\r\n return;\r\n }\r\n warn(warning);\r\n },\r\n output: {\r\n chunkFileNames: 'pro_olova_static/chunks/[name]-[hash].js',\r\n entryFileNames: 'pro_olova_static/olova-[hash].js',\r\n assetFileNames: 'pro_olova_static/[name]-[hash][extname]',\r\n manualChunks(id) {\r\n if (id.includes('node_modules')) {\r\n if (id.includes('react-dom')) {\r\n return 'vendor-react-dom';\r\n }\r\n if (id.includes('react')) {\r\n return 'vendor-react';\r\n }\r\n // Keep olova separate so it properly depends on React\r\n if (id.includes('olova')) {\r\n return undefined; // Let Rollup handle it normally\r\n }\r\n return 'vendor';\r\n }\r\n },\r\n },\r\n },\r\n },\r\n preview: {\r\n port: 4173,\r\n strictPort: false,\r\n },\r\n // Exclude olova from dependency optimization so our virtual modules work\r\n optimizeDeps: {\r\n exclude: ['olova', 'olova/router'],\r\n },\r\n // Also configure SSR to handle these modules\r\n ssr: {\r\n noExternal: ['olova', /^virtual:/],\r\n },\r\n };\r\n },\r\n configureServer(server) {\r\n // Show ready message when server starts\r\n server.httpServer?.once('listening', () => {\r\n const address = server.httpServer?.address();\r\n const port = typeof address === 'object' && address ? address.port : 5173;\r\n \r\n setTimeout(() => {\r\n console.log(` ${colors.green}✓${colors.reset} Ready in ${colors.dim}${Math.round(performance.now())}ms${colors.reset}`);\r\n console.log('');\r\n console.log(` ${colors.dim}➜${colors.reset} ${colors.bold}Local:${colors.reset} ${colors.cyan}http://localhost:${port}/${colors.reset}`);\r\n console.log('');\r\n }, 100);\r\n });\r\n },\r\n };\r\n}\r\n","import { type Plugin, type ViteDevServer } from 'vite';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\n\r\n// =============================================================================\r\n// ROUTER PLUGIN - File-system based routing with HMR support\r\n// =============================================================================\r\nexport function routerPlugin(): Plugin {\r\n const virtualModuleId = 'virtual:olova-routes';\r\n const resolvedVirtualModuleId = '\\0' + virtualModuleId;\r\n let server: ViteDevServer | null = null;\r\n\r\n // Helper function to invalidate the virtual module and trigger HMR\r\n const invalidateRoutes = () => {\r\n if (server) {\r\n const mod = server.moduleGraph.getModuleById(resolvedVirtualModuleId);\r\n if (mod) {\r\n server.moduleGraph.invalidateModule(mod);\r\n // Send HMR update to refresh the routes\r\n server.ws.send({\r\n type: 'full-reload',\r\n path: '*'\r\n });\r\n }\r\n }\r\n };\r\n\r\n return {\r\n name: 'olova-router',\r\n enforce: 'pre',\r\n \r\n // Configure dev server to watch for file changes\r\n configureServer(devServer) {\r\n server = devServer;\r\n const srcDir = path.resolve(process.cwd(), 'src');\r\n \r\n // Watch the src directory for file changes\r\n const watcher = devServer.watcher;\r\n \r\n // Handle file additions\r\n watcher.on('add', (filePath: string) => {\r\n if (filePath.startsWith(srcDir) && /\\.(tsx|jsx|html|md)$/.test(filePath)) {\r\n console.log('\\x1b[36m[olova]\\x1b[0m New route detected:', path.relative(srcDir, filePath));\r\n invalidateRoutes();\r\n }\r\n });\r\n \r\n // Handle file deletions\r\n watcher.on('unlink', (filePath: string) => {\r\n if (filePath.startsWith(srcDir) && /\\.(tsx|jsx|html|md)$/.test(filePath)) {\r\n console.log('\\x1b[36m[olova]\\x1b[0m Route removed:', path.relative(srcDir, filePath));\r\n invalidateRoutes();\r\n }\r\n });\r\n \r\n // Handle directory additions (new route folders)\r\n watcher.on('addDir', (dirPath: string) => {\r\n if (dirPath.startsWith(srcDir) && dirPath !== srcDir) {\r\n console.log('\\x1b[36m[olova]\\x1b[0m New route folder detected:', path.relative(srcDir, dirPath));\r\n // Don't invalidate immediately - wait for files to be added\r\n }\r\n });\r\n \r\n // Handle directory deletions\r\n watcher.on('unlinkDir', (dirPath: string) => {\r\n if (dirPath.startsWith(srcDir) && dirPath !== srcDir) {\r\n console.log('\\x1b[36m[olova]\\x1b[0m Route folder removed:', path.relative(srcDir, dirPath));\r\n invalidateRoutes();\r\n }\r\n });\r\n },\r\n \r\n resolveId(id) {\r\n if (id === virtualModuleId) {\r\n return resolvedVirtualModuleId;\r\n }\r\n },\r\n \r\n // Mark the virtual module as having side effects for proper HMR\r\n handleHotUpdate({ file, server: devServer }) {\r\n const srcDir = path.resolve(process.cwd(), 'src');\r\n \r\n // If a route file's content changes (like adding \"static\" directive), refresh routes\r\n if (file.startsWith(srcDir) && /\\.(tsx|jsx)$/.test(file)) {\r\n const mod = devServer.moduleGraph.getModuleById(resolvedVirtualModuleId);\r\n if (mod) {\r\n devServer.moduleGraph.invalidateModule(mod);\r\n }\r\n }\r\n },\r\n \r\n load(id) {\r\n if (id === resolvedVirtualModuleId) {\r\n const srcDir = path.resolve(process.cwd(), 'src');\r\n \r\n // Helper to scan directory recursively\r\n // Supports Next.js-style conventions:\r\n // - (folder) = Route Group (ignored in URL, for organization only)\r\n // - [folder] = Dynamic Route (captures URL parameter)\r\n const getRoutes = (dir: string, baseRoute: string = '', baseImportPath: string = ''): string[] => {\r\n const entries = fs.readdirSync(dir, { withFileTypes: true });\r\n let routes: string[] = [];\r\n\r\n for (const entry of entries) {\r\n const entryName = entry.name;\r\n const fullPath = path.join(dir, entryName);\r\n \r\n if (entry.isDirectory()) {\r\n // Check if it's a route group (folder wrapped in parentheses)\r\n const isRouteGroup = /^\\(.+\\)$/.test(entryName);\r\n \r\n if (isRouteGroup) {\r\n // Route groups: folder is ignored in URL path but kept in import path\r\n // e.g., (auth) folder -> URL stays same, import includes (auth)\r\n routes = routes.concat(getRoutes(\r\n fullPath, \r\n baseRoute, // URL path stays the same (group is ignored)\r\n `${baseImportPath}/${entryName}` // Import path includes the folder\r\n ));\r\n } else {\r\n // Regular folder or dynamic route folder\r\n routes = routes.concat(getRoutes(\r\n fullPath, \r\n `${baseRoute}/${entryName}`,\r\n `${baseImportPath}/${entryName}`\r\n ));\r\n }\r\n } else {\r\n // Support multiple file types: .tsx, .jsx, .html, .md\r\n const ext = path.extname(entryName);\r\n const supportedExts = ['.tsx', '.jsx', '.html', '.md'];\r\n \r\n if (supportedExts.includes(ext)) {\r\n const nameNoExt = entryName.replace(/\\.(tsx|jsx|html|md)$/, '');\r\n if (nameNoExt === 'root') continue; \r\n \r\n let routePath = baseRoute;\r\n if (nameNoExt !== 'index' && nameNoExt !== 'App') {\r\n routePath = `${baseRoute}/${nameNoExt}`;\r\n }\r\n \r\n if (routePath === '') routePath = '/';\r\n \r\n // Convert $param to :param for dynamic routes (Olova convention)\r\n const normalizedRoutePath = routePath\r\n .replace(/\\$(.+?)(?=\\/|$)/g, ':$1');\r\n \r\n // Path relative to project root for import\r\n const importPath = `/src${baseImportPath}/${entryName}`;\r\n \r\n if (ext === '.html') {\r\n // HTML files: create a wrapper that fetches and renders the HTML\r\n routes.push(` \"${normalizedRoutePath}\": () => import(\"${importPath}?raw\").then(m => ({ default: () => { const div = document.createElement('div'); div.innerHTML = m.default; return div.innerHTML; }, __isHtml: true, __isStatic: true, __rawHtml: m.default })),`);\r\n } else if (ext === '.md') {\r\n // MD files: import as raw and render as markdown\r\n routes.push(` \"${normalizedRoutePath}\": () => import(\"${importPath}?raw\").then(m => ({ default: m.default, __isMd: true, __isStatic: true })),`);\r\n } else {\r\n // TSX/JSX files: check for \"static\" directive\r\n const fileContent = fs.readFileSync(fullPath, 'utf-8');\r\n const firstLine = fileContent.trim().split('\\n')[0].trim();\r\n const hasStaticDirective = firstLine === '\"static\"' || firstLine === \"'static'\";\r\n \r\n if (hasStaticDirective) {\r\n // Static route: add __isStatic flag\r\n routes.push(` \"${normalizedRoutePath}\": () => import(\"${importPath}\").then(m => Object.assign({}, m, { __isStatic: true })),`);\r\n } else {\r\n // Client-only route: standard import\r\n routes.push(` \"${normalizedRoutePath}\": () => import(\"${importPath}\"),`);\r\n }\r\n }\r\n }\r\n }\r\n }\r\n return routes;\r\n };\r\n\r\n let routeLines: string[] = [];\r\n if (fs.existsSync(srcDir)) {\r\n routeLines = getRoutes(srcDir);\r\n }\r\n\r\n return `export const routes = {\r\n${routeLines.join('\\n')}\r\n};`;\r\n }\r\n },\r\n };\r\n}\r\n","import { type Plugin, transformWithEsbuild } from 'vite';\r\n\r\n// =============================================================================\r\n// FRAMEWORK PLUGIN - Virtual entry points for client and server\r\n// =============================================================================\r\nexport function frameworkPlugin(): Plugin {\r\n const virtualClientEntry = 'olova/client';\r\n const resolvedVirtualClientEntry = '\\0' + virtualClientEntry;\r\n const virtualServerEntry = 'olova/server';\r\n const resolvedVirtualServerEntry = '\\0' + virtualServerEntry;\r\n\r\n return {\r\n name: 'olova-framework',\r\n enforce: 'pre',\r\n resolveId(id: string) {\r\n if (id === virtualClientEntry || id === '/olova/client' || id === 'olova/client.tsx') return resolvedVirtualClientEntry;\r\n if (id === virtualServerEntry || id === '/olova/server' || id === 'olova/server.tsx') return resolvedVirtualServerEntry;\r\n },\r\n async load(id: string) {\r\n if (id === resolvedVirtualClientEntry) {\r\n const code = `\r\nimport React from 'react';\r\nimport { hydrateRoot, createRoot } from 'react-dom/client';\r\nimport Layout, { metadata as defaultMetadata } from '/src/root.tsx';\r\nimport { Router, loadRoute } from 'olova/router';\r\n\r\n// Helper to generate SEO meta tags\r\nfunction generateSeoTags(metadata) {\r\n const meta = { ...defaultMetadata, ...metadata };\r\n const tags = [];\r\n \r\n // Title\r\n if (meta.title) {\r\n document.title = meta.title;\r\n }\r\n \r\n // Description\r\n if (meta.description) {\r\n let tag = document.querySelector('meta[name=\"description\"]');\r\n if (!tag) {\r\n tag = document.createElement('meta');\r\n tag.setAttribute('name', 'description');\r\n document.head.appendChild(tag);\r\n }\r\n tag.setAttribute('content', meta.description);\r\n }\r\n \r\n // Keywords\r\n if (meta.keywords) {\r\n const content = Array.isArray(meta.keywords) ? meta.keywords.join(', ') : meta.keywords;\r\n let tag = document.querySelector('meta[name=\"keywords\"]');\r\n if (!tag) {\r\n tag = document.createElement('meta');\r\n tag.setAttribute('name', 'keywords');\r\n document.head.appendChild(tag);\r\n }\r\n tag.setAttribute('content', content);\r\n }\r\n \r\n // Open Graph\r\n if (meta.openGraph) {\r\n const og = meta.openGraph;\r\n const ogTags = [\r\n ['og:title', og.title || meta.title],\r\n ['og:description', og.description],\r\n ['og:url', og.url],\r\n ['og:site_name', og.siteName],\r\n ['og:type', og.type],\r\n ];\r\n ogTags.forEach(([prop, content]) => {\r\n if (content) {\r\n let tag = document.querySelector(\\`meta[property=\"\\${prop}\"]\\`);\r\n if (!tag) {\r\n tag = document.createElement('meta');\r\n tag.setAttribute('property', prop);\r\n document.head.appendChild(tag);\r\n }\r\n tag.setAttribute('content', content);\r\n }\r\n });\r\n }\r\n \r\n // Twitter Card\r\n if (meta.twitter) {\r\n const tw = meta.twitter;\r\n const twTags = [\r\n ['twitter:card', tw.card || 'summary'],\r\n ['twitter:site', tw.site],\r\n ['twitter:creator', tw.creator],\r\n ['twitter:title', tw.title || meta.title],\r\n ['twitter:description', tw.description],\r\n ];\r\n twTags.forEach(([name, content]) => {\r\n if (content) {\r\n let tag = document.querySelector(\\`meta[name=\"\\${name}\"]\\`);\r\n if (!tag) {\r\n tag = document.createElement('meta');\r\n tag.setAttribute('name', name);\r\n document.head.appendChild(tag);\r\n }\r\n tag.setAttribute('content', content);\r\n }\r\n });\r\n }\r\n}\r\n\r\n// Get SSG data from the server-rendered scripts\r\n// @ts-ignore\r\nconst serverData = window.$OLOVA?.$route || {};\r\nconst path = serverData.path || window.location.pathname;\r\nconst params = serverData.params || {};\r\n// @ts-ignore \r\nconst serverMeta = window.$OLOVA?.$meta || {};\r\n\r\n// Framework handles SEO automatically (like Next.js)\r\ngenerateSeoTags(serverMeta);\r\n\r\n// Hydrate immediately - Router handles component loading internally\r\n// This ensures the initial render matches the SSG HTML exactly\r\nconst app = (\r\n <React.StrictMode>\r\n <Layout>\r\n <Router url={path} initialParams={params} onRouteChange={(newMetadata) => generateSeoTags(newMetadata)} />\r\n </Layout>\r\n </React.StrictMode>\r\n);\r\n\r\nconsole.log(\"[Olova] Hydrating document for path:\", path);\r\nhydrateRoot(document, app);`;\r\n const result = await transformWithEsbuild(code, 'olova-client.tsx', {\r\n loader: 'tsx',\r\n jsx: 'automatic',\r\n });\r\n return result.code;\r\n }\r\n if (id === resolvedVirtualServerEntry) {\r\n const code = `\r\nimport React from 'react';\r\nimport { renderToString } from 'react-dom/server';\r\nimport Layout, { metadata as defaultMetadata } from '/src/root.tsx';\r\nimport { routes } from 'virtual:olova-routes';\r\n\r\n// =============================================================================\r\n// INLINE ROUTER UTILITIES (to avoid external olova/router import)\r\n// =============================================================================\r\nconst normalizePath = (path) => {\r\n let p = path.split('?')[0].split('#')[0];\r\n if (p.length > 1 && p.endsWith('/')) p = p.slice(0, -1);\r\n return p || '/';\r\n};\r\n\r\nfunction matchRoute(path) {\r\n const normalizedPath = normalizePath(path);\r\n const routeKeys = Object.keys(routes);\r\n \r\n for (const route of routeKeys) {\r\n if (route === normalizedPath) {\r\n return { loader: routes[route], params: {}, pattern: route };\r\n }\r\n \r\n const regexPath = route\r\n .replace(/:[^\\\\/]+/g, '([^/]+)')\r\n .replace(/\\\\$[^\\\\/]+/g, '([^/]+)');\r\n \r\n const regex = new RegExp(\\`^\\${regexPath}$\\`);\r\n const match = normalizedPath.match(regex);\r\n \r\n if (match) {\r\n const params = {};\r\n const paramNames = (route.match(/[:\\\\$][^\\\\/]+/g) || []).map(s => s.slice(1));\r\n paramNames.forEach((name, i) => {\r\n params[name] = match[i + 1];\r\n });\r\n return { loader: routes[route], params, pattern: route };\r\n }\r\n }\r\n return null;\r\n}\r\n\r\nfunction parseMarkdown(md) {\r\n return md\r\n .replace(/^### (.*$)/gim, '<h3>$1</h3>')\r\n .replace(/^## (.*$)/gim, '<h2>$1</h2>')\r\n .replace(/^# (.*$)/gim, '<h1>$1</h1>')\r\n .replace(/\\\\*\\\\*\\\\*(.*?)\\\\*\\\\*\\\\*/g, '<strong><em>$1</em></strong>')\r\n .replace(/\\\\*\\\\*(.*?)\\\\*\\\\*/g, '<strong>$1</strong>')\r\n .replace(/\\\\*(.*?)\\\\*/g, '<em>$1</em>')\r\n .replace(/\\`\\`\\`([\\\\s\\\\S]*?)\\`\\`\\`/g, '<pre><code>$1</code></pre>')\r\n .replace(/\\`(.*?)\\`/g, '<code>$1</code>')\r\n .replace(/\\\\[([^\\\\]]+)\\\\]\\\\(([^)]+)\\\\)/g, '<a href=\"$2\">$1</a>')\r\n .replace(/\\\\n\\\\n/g, '</p><p>')\r\n .replace(/\\\\n/g, '<br>')\r\n .replace(/^(.*)$/, '<p>$1</p>');\r\n}\r\n\r\nfunction HtmlContent({ html }) {\r\n return React.createElement('div', { \r\n dangerouslySetInnerHTML: { __html: html },\r\n className: 'olova-html-content'\r\n });\r\n}\r\n\r\nfunction MarkdownContent({ markdown }) {\r\n const html = parseMarkdown(markdown);\r\n return React.createElement('article', { \r\n dangerouslySetInnerHTML: { __html: html },\r\n className: 'olova-markdown-content'\r\n });\r\n}\r\n\r\nasync function loadRoute(path) {\r\n const match = matchRoute(path);\r\n if (match) {\r\n const module = await match.loader();\r\n \r\n if (module.__isHtml) {\r\n return { \r\n module: {\r\n default: () => HtmlContent({ html: module.__rawHtml }),\r\n },\r\n params: match.params,\r\n metadata: undefined\r\n };\r\n }\r\n \r\n if (module.__isMd) {\r\n return { \r\n module: {\r\n default: () => MarkdownContent({ markdown: module.default }),\r\n },\r\n params: match.params,\r\n metadata: undefined\r\n };\r\n }\r\n \r\n return { \r\n module,\r\n params: match.params,\r\n metadata: module.metadata\r\n };\r\n }\r\n return null;\r\n}\r\n\r\nconst RouterContext = React.createContext({ params: {}, path: '/' });\r\n\r\nfunction Router({ url, initialComponent, initialParams }) {\r\n const Component = initialComponent || (() => <div>Loading...</div>);\r\n const params = initialParams || {};\r\n // Server-side: Just render the Component directly (no Context needed)\r\n // The Context.Provider wrapping happens on client for hooks to work\r\n return <Component {...params} />;\r\n}\r\n\r\n// =============================================================================\r\n// SEO HEAD GENERATION\r\n// =============================================================================\r\nfunction generateSeoHead(metadata) {\r\n const meta = { ...defaultMetadata, ...metadata };\r\n let head = '';\r\n \r\n if (meta.title) {\r\n head += \\`<title>\\${meta.title}</title>\\\\n\\`;\r\n }\r\n \r\n if (meta.description) {\r\n head += \\`<meta name=\"description\" content=\"\\${meta.description}\" />\\\\n\\`;\r\n }\r\n if (meta.keywords) {\r\n const content = Array.isArray(meta.keywords) ? meta.keywords.join(', ') : meta.keywords;\r\n head += \\`<meta name=\"keywords\" content=\"\\${content}\" />\\\\n\\`;\r\n }\r\n if (meta.robots) {\r\n head += \\`<meta name=\"robots\" content=\"\\${meta.robots}\" />\\\\n\\`;\r\n }\r\n if (meta.canonical) {\r\n head += \\`<link rel=\"canonical\" href=\"\\${meta.canonical}\" />\\\\n\\`;\r\n }\r\n \r\n if (meta.openGraph) {\r\n const og = meta.openGraph;\r\n head += \\`<meta property=\"og:title\" content=\"\\${og.title || meta.title}\" />\\\\n\\`;\r\n if (og.description) head += \\`<meta property=\"og:description\" content=\"\\${og.description}\" />\\\\n\\`;\r\n if (og.url) head += \\`<meta property=\"og:url\" content=\"\\${og.url}\" />\\\\n\\`;\r\n if (og.siteName) head += \\`<meta property=\"og:site_name\" content=\"\\${og.siteName}\" />\\\\n\\`;\r\n if (og.type) head += \\`<meta property=\"og:type\" content=\"\\${og.type}\" />\\\\n\\`;\r\n if (og.images) {\r\n og.images.forEach(img => {\r\n head += \\`<meta property=\"og:image\" content=\"\\${img.url}\" />\\\\n\\`;\r\n });\r\n }\r\n }\r\n \r\n if (meta.twitter) {\r\n const tw = meta.twitter;\r\n head += \\`<meta name=\"twitter:card\" content=\"\\${tw.card || 'summary'}\" />\\\\n\\`;\r\n if (tw.site) head += \\`<meta name=\"twitter:site\" content=\"\\${tw.site}\" />\\\\n\\`;\r\n if (tw.creator) head += \\`<meta name=\"twitter:creator\" content=\"\\${tw.creator}\" />\\\\n\\`;\r\n head += \\`<meta name=\"twitter:title\" content=\"\\${tw.title || meta.title}\" />\\\\n\\`;\r\n if (tw.description) head += \\`<meta name=\"twitter:description\" content=\"\\${tw.description}\" />\\\\n\\`;\r\n if (tw.images) {\r\n tw.images.forEach(img => {\r\n head += \\`<meta name=\"twitter:image\" content=\"\\${img}\" />\\\\n\\`;\r\n });\r\n }\r\n }\r\n \r\n return head;\r\n}\r\n\r\n// =============================================================================\r\n// SERVER RENDER FUNCTIONS\r\n// =============================================================================\r\nexport async function render(url) {\r\n const result = await loadRoute(url);\r\n const Component = result ? result.module.default : () => <div>404 Not Found</div>;\r\n const params = result ? result.params : {};\r\n const metadata = result ? result.metadata : undefined;\r\n \r\n const seoHead = generateSeoHead(metadata);\r\n \r\n let html = renderToString(\r\n <Layout>\r\n <Router url={url} initialComponent={Component} initialParams={params} />\r\n </Layout>\r\n );\r\n \r\n if (html.includes('</head>')) {\r\n html = html.replace('</head>', seoHead + '</head>');\r\n }\r\n \r\n return { html, hydrationData: { params, metadata } };\r\n}\r\n\r\nexport function renderShell() {\r\n const seoHead = generateSeoHead({});\r\n let html = renderToString(<Layout>{null}</Layout>);\r\n if (html.includes('</head>')) {\r\n html = html.replace('</head>', seoHead + '</head>');\r\n }\r\n return html;\r\n}\r\n\r\nexport function renderShellWithMetadata(metadata) {\r\n const seoHead = generateSeoHead(metadata);\r\n let html = renderToString(<Layout>{null}</Layout>);\r\n if (html.includes('</head>')) {\r\n html = html.replace('</head>', seoHead + '</head>');\r\n }\r\n return html;\r\n}\r\n\r\nexport { loadRoute };`;\r\n const result = await transformWithEsbuild(code, 'olova-server.tsx', {\r\n loader: 'tsx',\r\n jsx: 'automatic',\r\n });\r\n return result.code;\r\n }\r\n }\r\n }\r\n}\r\n","import { type Plugin, type ViteDevServer } from 'vite';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport { generateOlovaHydration, generateJsonLd } from './hydration';\r\n\r\n// =============================================================================\r\n// VIRTUAL HTML PLUGIN - Handles dev and build HTML generation\r\n// \r\n// Rendering modes:\r\n// - ALL PAGES: Layout shell (root.tsx) is always pre-rendered (like Next.js)\r\n// - \"static\" directive: Full page content is also pre-rendered\r\n// - .html/.md files: Always fully static\r\n// - Default (no directive): Shell is pre-rendered, page content renders on client\r\n// =============================================================================\r\nexport function virtualHtmlPlugin(): Plugin {\r\n let viteServer: ViteDevServer | null = null;\r\n \r\n // Check if a route file is marked as static\r\n const isStaticRoute = (routePath: string): { isStatic: boolean; fileType: 'tsx' | 'jsx' | 'html' | 'md' | null } => {\r\n const srcDir = path.resolve('src');\r\n let filePath = routePath === '/' ? '' : routePath.slice(1);\r\n \r\n // Check for HTML/MD files first - these are always static\r\n const htmlMdPaths = [\r\n path.join(srcDir, filePath, 'index.html'),\r\n path.join(srcDir, filePath, 'index.md'),\r\n path.join(srcDir, filePath + '.html'),\r\n path.join(srcDir, filePath + '.md'),\r\n ];\r\n \r\n for (const p of htmlMdPaths) {\r\n if (fs.existsSync(p)) {\r\n const ext = path.extname(p).slice(1) as 'html' | 'md';\r\n return { isStatic: true, fileType: ext };\r\n }\r\n }\r\n \r\n // Check for TSX/JSX files\r\n const tsxJsxPaths = [\r\n path.join(srcDir, filePath, 'index.tsx'),\r\n path.join(srcDir, filePath, 'index.jsx'),\r\n path.join(srcDir, filePath + '.tsx'),\r\n path.join(srcDir, filePath + '.jsx'),\r\n path.join(srcDir, 'App.tsx'),\r\n path.join(srcDir, 'App.jsx'),\r\n ];\r\n \r\n for (const p of tsxJsxPaths) {\r\n if (fs.existsSync(p)) {\r\n const content = fs.readFileSync(p, 'utf-8');\r\n const firstLine = content.trim().split('\\n')[0].trim();\r\n const isStatic = firstLine === '\"static\"' || firstLine === \"'static'\";\r\n const ext = path.extname(p).slice(1) as 'tsx' | 'jsx';\r\n return { isStatic, fileType: ext };\r\n }\r\n }\r\n \r\n return { isStatic: false, fileType: null };\r\n };\r\n \r\n // Extract metadata from a file\r\n const extractMetadata = (filePath: string): Record<string, unknown> => {\r\n try {\r\n if (!fs.existsSync(filePath)) return {};\r\n const content = fs.readFileSync(filePath, 'utf-8');\r\n \r\n const metadataMatch = content.match(/export\\s+const\\s+metadata\\s*=\\s*(\\{[\\s\\S]*?\\});/);\r\n if (metadataMatch) {\r\n try {\r\n let metaStr = metadataMatch[1]\r\n .replace(/'/g, '\"')\r\n .replace(/(\\w+):/g, '\"$1\":')\r\n .replace(/,\\s*}/g, '}')\r\n .replace(/,\\s*]/g, ']');\r\n return JSON.parse(metaStr);\r\n } catch {\r\n const titleMatch = content.match(/title:\\s*['\"]([^'\"]+)['\"]/);\r\n const descMatch = content.match(/description:\\s*['\"]([^'\"]+)['\"]/);\r\n return {\r\n title: titleMatch?.[1] || 'Olova App',\r\n description: descMatch?.[1] || '',\r\n };\r\n }\r\n }\r\n return {};\r\n } catch {\r\n return {};\r\n }\r\n };\r\n\r\n // Get metadata for a route\r\n const getRouteMetadata = (routePath: string): Record<string, unknown> => {\r\n const srcDir = path.resolve('src');\r\n let filePath = routePath === '/' ? '' : routePath.slice(1);\r\n \r\n const possiblePaths = [\r\n path.join(srcDir, filePath, 'index.tsx'),\r\n path.join(srcDir, filePath, 'index.jsx'),\r\n path.join(srcDir, filePath + '.tsx'),\r\n path.join(srcDir, filePath + '.jsx'),\r\n path.join(srcDir, 'App.tsx'),\r\n path.join(srcDir, 'App.jsx'),\r\n ];\r\n \r\n for (const p of possiblePaths) {\r\n if (fs.existsSync(p)) {\r\n return extractMetadata(p);\r\n }\r\n }\r\n \r\n const rootPath = path.join(srcDir, 'root.tsx');\r\n if (fs.existsSync(rootPath)) {\r\n return extractMetadata(rootPath);\r\n }\r\n \r\n return {};\r\n };\r\n\r\n // Build SEO head content\r\n const buildSeoHead = (routePath: string, metadata?: Record<string, unknown>): string => {\r\n const meta = metadata || getRouteMetadata(routePath);\r\n let headContent = '';\r\n \r\n if (meta.title) {\r\n headContent += `<title>${meta.title}</title>\\n`;\r\n } else {\r\n headContent += `<title>Olova App</title>\\n`;\r\n }\r\n \r\n if (meta.description) {\r\n headContent += `<meta name=\"description\" content=\"${meta.description}\" />\\n`;\r\n }\r\n \r\n if (meta.keywords) {\r\n const keywords = Array.isArray(meta.keywords) \r\n ? (meta.keywords as string[]).join(', ') \r\n : meta.keywords;\r\n headContent += `<meta name=\"keywords\" content=\"${keywords}\" />\\n`;\r\n }\r\n \r\n const jsonLdScript = generateJsonLd({ route: routePath, metadata: meta });\r\n headContent += jsonLdScript + '\\n';\r\n \r\n headContent += `<style id=\"olova-critical\">*{box-sizing:border-box}html{-webkit-text-size-adjust:100%;line-height:1.5}body{font-family:system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif}</style>\\n`;\r\n \r\n return headContent;\r\n };\r\n\r\n // Build hydration scripts\r\n const buildBodyScripts = (routePath: string, metadata?: Record<string, unknown>, isStatic?: boolean): string => {\r\n const meta = metadata || getRouteMetadata(routePath);\r\n const devBuildId = 'dev-' + Date.now().toString(36);\r\n return generateOlovaHydration({\r\n route: routePath,\r\n metadata: meta,\r\n chunks: [],\r\n isStatic: isStatic || false,\r\n }, devBuildId);\r\n };\r\n\r\n // Render shell (layout with children=null) - always runs\r\n const renderShell = async (): Promise<string> => {\r\n if (!viteServer) return '';\r\n\r\n try {\r\n const serverModule = await viteServer.ssrLoadModule('olova/server');\r\n if (serverModule?.renderShell) {\r\n return serverModule.renderShell() || '';\r\n }\r\n } catch (e: any) {\r\n // Silent fail - shell rendering is best-effort\r\n }\r\n return '';\r\n };\r\n\r\n // Render full page (for static pages)\r\n const renderFullPage = async (routePath: string): Promise<{ html: string; metadata: Record<string, unknown> }> => {\r\n if (!viteServer) return { html: '', metadata: {} };\r\n\r\n try {\r\n const serverModule = await viteServer.ssrLoadModule('olova/server');\r\n if (serverModule?.render) {\r\n const result = await serverModule.render(routePath);\r\n return {\r\n html: result.html || '',\r\n metadata: result.hydrationData?.metadata || {}\r\n };\r\n }\r\n } catch (e: any) {\r\n console.error('[Olova] Full page render error:', e.message);\r\n }\r\n return { html: '', metadata: {} };\r\n };\r\n\r\n // Inject content into HTML\r\n const injectIntoHtml = (html: string, seoHead: string, bodyScripts: string): string => {\r\n let result = html;\r\n \r\n // Inject SEO into head\r\n if (result.includes('</head>')) {\r\n result = result.replace('</head>', seoHead + '</head>');\r\n }\r\n \r\n // Inject scripts before </body>\r\n if (result.includes('</body>')) {\r\n result = result.replace('</body>', \r\n bodyScripts + \r\n '<script type=\"module\" src=\"/olova/client\"></script>\\n</body>'\r\n );\r\n } else {\r\n result += bodyScripts + '<script type=\"module\" src=\"/olova/client\"></script>';\r\n }\r\n \r\n return result;\r\n };\r\n\r\n return {\r\n name: 'olova-virtual-html',\r\n enforce: 'pre',\r\n \r\n resolveId(id: string) {\r\n if (id === 'index.html' || id === 'virtual:index.html' || id === '/index.html') {\r\n return 'virtual:olova-index.html';\r\n }\r\n },\r\n \r\n load(id: string) {\r\n if (id === 'virtual:olova-index.html') {\r\n return `<!DOCTYPE html>\r\n<html lang=\"en\">\r\n <head>\r\n <meta charset=\"UTF-8\" />\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\r\n </head>\r\n <body>\r\n <script type=\"module\" src=\"/olova/client\"></script>\r\n </body>\r\n</html>`;\r\n }\r\n },\r\n\r\n configureServer(server) {\r\n viteServer = server;\r\n \r\n return () => {\r\n server.middlewares.use(async (req, res, next) => {\r\n const url = req.url || '/';\r\n \r\n const accept = req.headers.accept || '';\r\n if (!accept.includes('text/html')) {\r\n return next();\r\n }\r\n \r\n if (url.startsWith('/@') || url.startsWith('/__') || url.startsWith('/node_modules')) {\r\n return next();\r\n }\r\n \r\n if (/\\.\\w+$/.test(url) && !url.endsWith('.html')) {\r\n return next();\r\n }\r\n \r\n const routePath = url.split('?')[0].replace(/\\/+$/, '') || '/';\r\n \r\n try {\r\n const { isStatic, fileType } = isStaticRoute(routePath);\r\n const routeMetadata = getRouteMetadata(routePath);\r\n \r\n let finalHtml: string;\r\n let metadata = { ...routeMetadata };\r\n \r\n if (isStatic) {\r\n // STATIC: Full page SSR\r\n const { html: fullHtml, metadata: ssrMetadata } = await renderFullPage(routePath);\r\n metadata = { ...routeMetadata, ...ssrMetadata };\r\n \r\n if (fullHtml) {\r\n const seoHead = buildSeoHead(routePath, metadata);\r\n const bodyScripts = buildBodyScripts(routePath, metadata, true);\r\n finalHtml = injectIntoHtml(fullHtml, seoHead, bodyScripts);\r\n } else {\r\n // Fallback: shell with metadata\r\n const shellHtml = await renderShell();\r\n const seoHead = buildSeoHead(routePath, metadata);\r\n const bodyScripts = buildBodyScripts(routePath, metadata, true);\r\n \r\n if (shellHtml) {\r\n finalHtml = injectIntoHtml(shellHtml, seoHead, bodyScripts);\r\n } else {\r\n finalHtml = `<!DOCTYPE html>\r\n<html lang=\"en\">\r\n <head>\r\n <meta charset=\"UTF-8\" />\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\r\n ${seoHead}\r\n </head>\r\n <body>\r\n ${bodyScripts}\r\n <script type=\"module\" src=\"/olova/client\"></script>\r\n </body>\r\n</html>`;\r\n }\r\n }\r\n } else {\r\n // CLIENT-SIDE: Render shell (layout) but not page content\r\n // This gives you the header/nav in view source, like Next.js\r\n const shellHtml = await renderShell();\r\n const seoHead = buildSeoHead(routePath, metadata);\r\n const bodyScripts = buildBodyScripts(routePath, metadata, false);\r\n \r\n if (shellHtml) {\r\n // Shell rendered - inject SEO and scripts\r\n finalHtml = injectIntoHtml(shellHtml, seoHead, bodyScripts);\r\n } else {\r\n // Shell failed - minimal HTML\r\n finalHtml = `<!DOCTYPE html>\r\n<html lang=\"en\">\r\n <head>\r\n <meta charset=\"UTF-8\" />\r\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\r\n ${seoHead}\r\n </head>\r\n <body>\r\n ${bodyScripts}\r\n <script type=\"module\" src=\"/olova/client\"></script>\r\n </body>\r\n</html>`;\r\n }\r\n }\r\n \r\n // Ensure DOCTYPE\r\n if (!finalHtml.trim().toLowerCase().startsWith('<!doctype')) {\r\n finalHtml = '<!DOCTYPE html>\\n' + finalHtml;\r\n }\r\n \r\n // Transform through Vite for HMR\r\n const transformedHtml = await server.transformIndexHtml(url, finalHtml);\r\n \r\n res.setHeader('Content-Type', 'text/html');\r\n res.statusCode = 200;\r\n res.end(transformedHtml);\r\n } catch (e: any) {\r\n console.error('[Olova] Error:', e);\r\n next(e);\r\n }\r\n });\r\n };\r\n }\r\n };\r\n}\r\n","// =============================================================================\r\n// OLOVA HYDRATION SYSTEM\r\n// Implements \"Flight\" format for efficient client hydration\r\n// \r\n\r\n\r\nexport interface OlovaHydrationData {\r\n route: string;\r\n metadata?: Record<string, unknown>;\r\n params?: Record<string, string>;\r\n chunks?: string[];\r\n isStatic?: boolean;\r\n}\r\n\r\n// Flight data types for streaming\r\ntype FlightDataType = \r\n | 'M' // Metadata\r\n | 'T' // Component Tree\r\n | 'R' // Route info\r\n | 'P' // Params\r\n | 'A' // Assets/Chunks\r\n | 'S' // State\r\n | 'D' // Structured Data (Schema.org/JSON-LD)\r\n | 'H' // Hints (prefetch, preload)\r\n | 'E'; // End marker\r\n\r\ninterface FlightChunk {\r\n type: FlightDataType;\r\n data: unknown;\r\n}\r\n\r\nexport function generateOlovaHydration(data: OlovaHydrationData, buildId: string): string {\r\n const meta = (data.metadata || {}) as Record<string, unknown>;\r\n const scripts: string[] = [];\r\n \r\n // Initialize the flight array (like Next.js's self.__next_f)\r\n scripts.push(`<script>self.__olova_f=self.__olova_f||[];function _oF(d){self.__olova_f.push(d)}</script>`);\r\n \r\n // ==========================================================================\r\n // CHUNK 0: Route Information (Critical for navigation)\r\n // ==========================================================================\r\n const routeChunk: FlightChunk = {\r\n type: 'R',\r\n data: {\r\n path: data.route,\r\n params: data.params || {},\r\n pattern: data.route === '/' ? '/' : data.route.replace(/\\/[^/]+$/, '/:slug'),\r\n isStatic: data.isStatic ?? true,\r\n buildId: buildId\r\n }\r\n };\r\n scripts.push(`<script>_oF([0,\"${routeChunk.type}\",${JSON.stringify(routeChunk.data)}])</script>`);\r\n \r\n // ==========================================================================\r\n // CHUNK 1: Metadata (SEO Critical - must be early)\r\n // ==========================================================================\r\n const metadataChunk: FlightChunk = {\r\n type: 'M',\r\n data: {\r\n title: meta.title || 'Olova App',\r\n description: meta.description || '',\r\n keywords: Array.isArray(meta.keywords) ? meta.keywords : [],\r\n robots: meta.robots || 'index, follow',\r\n canonical: meta.canonical || null,\r\n og: {\r\n type: 'website',\r\n locale: 'en_US',\r\n ...((meta.openGraph as object) || {})\r\n },\r\n twitter: {\r\n card: 'summary_large_image',\r\n ...((meta.twitter as object) || {})\r\n }\r\n }\r\n };\r\n scripts.push(`<script>_oF([1,\"${metadataChunk.type}\",${JSON.stringify(metadataChunk.data)}])</script>`);\r\n \r\n // ==========================================================================\r\n // CHUNK 2: Component Tree (For React reconciliation)\r\n // ==========================================================================\r\n const pageName = data.route === '/' \r\n ? 'HomePage' \r\n : data.route.slice(1).split('/').map(s => s.charAt(0).toUpperCase() + s.slice(1)).join('') + 'Page';\r\n \r\n const treeChunk: FlightChunk = {\r\n type: 'T',\r\n data: {\r\n layout: 'RootLayout',\r\n page: pageName,\r\n template: null,\r\n loading: null,\r\n error: null,\r\n notFound: null\r\n }\r\n };\r\n scripts.push(`<script>_oF([2,\"${treeChunk.type}\",${JSON.stringify(treeChunk.data)}])</script>`);\r\n \r\n // ==========================================================================\r\n // CHUNK 3: Structured Data (JSON-LD for SEO boost)\r\n // ==========================================================================\r\n const structuredData: FlightChunk = {\r\n type: 'D',\r\n data: [\r\n {\r\n '@context': 'https://schema.org',\r\n '@type': 'WebPage',\r\n name: meta.title || 'Olova App',\r\n description: meta.description || '',\r\n url: data.route\r\n },\r\n {\r\n '@context': 'https://schema.org',\r\n '@type': 'WebApplication',\r\n name: 'Olova',\r\n applicationCategory: 'WebApplication',\r\n operatingSystem: 'Any'\r\n }\r\n ]\r\n };\r\n scripts.push(`<script>_oF([3,\"${structuredData.type}\",${JSON.stringify(structuredData.data)}])</script>`);\r\n \r\n // ==========================================================================\r\n // CHUNK 4: Assets for prefetching (Performance optimization)\r\n // ==========================================================================\r\n const assetsChunk: FlightChunk = {\r\n type: 'A',\r\n data: {\r\n chunks: data.chunks || [],\r\n styles: [],\r\n // Prefetch hints for next likely navigations\r\n prefetch: (data.chunks || []).slice(0, 5)\r\n }\r\n };\r\n scripts.push(`<script>_oF([4,\"${assetsChunk.type}\",${JSON.stringify(assetsChunk.data)}])</script>`);\r\n \r\n // ==========================================================================\r\n // CHUNK 5: Resource Hints (Browser optimization)\r\n // ==========================================================================\r\n const hintsChunk: FlightChunk = {\r\n type: 'H',\r\n data: {\r\n dnsPrefetch: ['fonts.googleapis.com', 'fonts.gstatic.com'],\r\n preconnect: ['https://fonts.googleapis.com', 'https://fonts.gstatic.com'],\r\n modulePreload: (data.chunks || []).slice(0, 3)\r\n }\r\n };\r\n scripts.push(`<script>_oF([5,\"${hintsChunk.type}\",${JSON.stringify(hintsChunk.data)}])</script>`);\r\n \r\n // ==========================================================================\r\n // CHUNK 6: Hydration State (Final - marks ready)\r\n // ==========================================================================\r\n const stateChunk: FlightChunk = {\r\n type: 'S',\r\n data: {\r\n hydrated: false,\r\n streaming: false,\r\n ready: true,\r\n timestamp: Date.now(),\r\n version: '1.0.0',\r\n buildId: buildId\r\n }\r\n };\r\n scripts.push(`<script>_oF([6,\"${stateChunk.type}\",${JSON.stringify(stateChunk.data)}])</script>`);\r\n \r\n // ==========================================================================\r\n // END MARKER: Signals all chunks are delivered\r\n // ==========================================================================\r\n scripts.push(`<script>_oF([7,\"E\",null])</script>`);\r\n \r\n // ==========================================================================\r\n // GLOBAL $OLOVA OBJECT: Easy access to hydration data (backward compatible)\r\n // ==========================================================================\r\n const globalPayload = {\r\n $route: routeChunk.data,\r\n $meta: metadataChunk.data,\r\n $tree: treeChunk.data,\r\n $schema: structuredData.data,\r\n $assets: assetsChunk.data,\r\n $hints: hintsChunk.data,\r\n $state: stateChunk.data,\r\n $build: {\r\n id: buildId,\r\n version: '1.0.0',\r\n timestamp: Date.now(),\r\n env: 'production'\r\n }\r\n };\r\n scripts.push(`<script>$OLOVA=${JSON.stringify(globalPayload)}</script>`);\r\n \r\n return scripts.join('');\r\n}\r\n\r\n/**\r\n * Generate JSON-LD structured data script for SEO\r\n * This is injected into <head> for search engine crawlers\r\n */\r\nexport function generateJsonLd(data: OlovaHydrationData): string {\r\n const meta = (data.metadata || {}) as Record<string, unknown>;\r\n \r\n const jsonLd = {\r\n '@context': 'https://schema.org',\r\n '@graph': [\r\n {\r\n '@type': 'WebPage',\r\n '@id': data.route,\r\n name: meta.title || 'Olova App',\r\n description: meta.description || '',\r\n url: data.route,\r\n isPartOf: {\r\n '@type': 'WebSite',\r\n name: 'Olova App'\r\n }\r\n },\r\n {\r\n '@type': 'BreadcrumbList',\r\n itemListElement: data.route.split('/').filter(Boolean).map((segment, index, arr) => ({\r\n '@type': 'ListItem',\r\n position: index + 1,\r\n name: segment.charAt(0).toUpperCase() + segment.slice(1),\r\n item: '/' + arr.slice(0, index + 1).join('/')\r\n }))\r\n }\r\n ]\r\n };\r\n \r\n return `<script type=\"application/ld+json\">${JSON.stringify(jsonLd)}</script>`;\r\n}\r\n\r\n/**\r\n * Parse flight data from the page (client-side utility)\r\n * Use this to access hydration data in your components\r\n */\r\nexport function parseFlightData(): Record<string, unknown> | null {\r\n // Check if we're in a browser environment\r\n if (typeof globalThis === 'undefined' || typeof (globalThis as Record<string, unknown>).document === 'undefined') {\r\n return null;\r\n }\r\n \r\n const flightArray = ((globalThis as Record<string, unknown>).__olova_f) as unknown[] | undefined;\r\n if (!flightArray) return null;\r\n \r\n const result: Record<string, unknown> = {};\r\n const typeMap: Record<FlightDataType, string> = {\r\n 'M': '$meta',\r\n 'T': '$tree', \r\n 'R': '$route',\r\n 'P': '$params',\r\n 'A': '$assets',\r\n 'S': '$state',\r\n 'D': '$schema',\r\n 'H': '$hints',\r\n 'E': '$end'\r\n };\r\n \r\n for (const chunk of flightArray) {\r\n if (Array.isArray(chunk) && chunk.length >= 3) {\r\n const [_index, type, data] = chunk;\r\n const key = typeMap[type as FlightDataType];\r\n if (key && key !== '$end') {\r\n result[key] = data;\r\n }\r\n }\r\n }\r\n \r\n return result;\r\n}\r\n","import { type Plugin, build } from 'vite';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\nimport { pathToFileURL } from 'url';\r\nimport { \r\n minifyHtml, \r\n generateBuildId, \r\n generateResourceHints, \r\n generateCriticalCSS, \r\n generatePerformanceMeta, \r\n generateServiceWorkerScript, \r\n generateServiceWorkerContent \r\n} from './utils';\r\nimport { generateOlovaHydration, generateJsonLd } from './hydration';\r\n\r\n// =============================================================================\r\n// TERMINAL STYLING - Next.js-inspired console output\r\n// =============================================================================\r\nconst colors = {\r\n reset: '\\x1b[0m',\r\n bold: '\\x1b[1m',\r\n dim: '\\x1b[2m',\r\n green: '\\x1b[32m',\r\n cyan: '\\x1b[36m',\r\n yellow: '\\x1b[33m',\r\n magenta: '\\x1b[35m',\r\n blue: '\\x1b[34m',\r\n red: '\\x1b[31m',\r\n white: '\\x1b[37m',\r\n gray: '\\x1b[90m',\r\n bgGreen: '\\x1b[42m',\r\n bgCyan: '\\x1b[46m',\r\n bgMagenta: '\\x1b[45m',\r\n};\r\n\r\nconst symbols = {\r\n success: '✓',\r\n arrow: '→',\r\n bullet: '○',\r\n filled: '●',\r\n lambda: 'λ',\r\n static: '○',\r\n ssr: '●',\r\n info: 'ℹ',\r\n};\r\n\r\n// Format milliseconds to human readable\r\nfunction formatTime(ms: number): string {\r\n if (ms < 1) return '<1ms';\r\n if (ms < 10) return `${ms.toFixed(1)}ms`;\r\n if (ms < 1000) return `${Math.round(ms)}ms`;\r\n if (ms < 60000) return `${(ms / 1000).toFixed(2)}s`;\r\n const mins = Math.floor(ms / 60000);\r\n const secs = Math.round((ms % 60000) / 1000);\r\n return `${mins}m ${secs}s`;\r\n}\r\n\r\n// Format bytes to human readable\r\nfunction formatBytes(bytes: number): string {\r\n if (bytes < 1024) return `${bytes} B`;\r\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} kB`;\r\n return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;\r\n}\r\n\r\n// Logger with Next.js-style formatting\r\nconst logger = {\r\n header: (text: string) => {\r\n console.log(`\\n${colors.bold}${colors.white}${text}${colors.reset}`);\r\n },\r\n \r\n info: (text: string) => {\r\n console.log(`${colors.cyan}${symbols.info}${colors.reset} ${text}`);\r\n },\r\n \r\n success: (text: string) => {\r\n console.log(`${colors.green}${symbols.success}${colors.reset} ${text}`);\r\n },\r\n \r\n route: (route: string, type: 'static' | 'ssr' | 'isr', size?: number, time?: number) => {\r\n const symbol = type === 'static' ? symbols.static : symbols.ssr;\r\n const color = type === 'static' ? colors.white : colors.magenta;\r\n const sizeStr = size ? ` ${colors.dim}${formatBytes(size)}${colors.reset}` : '';\r\n const timeStr = time ? ` ${colors.gray}(${formatTime(time)})${colors.reset}` : '';\r\n console.log(`${color}${symbol}${colors.reset} ${route}${sizeStr}${timeStr}`);\r\n },\r\n \r\n step: (step: string, time?: number) => {\r\n const timeStr = time ? ` ${colors.gray}${formatTime(time)}${colors.reset}` : '';\r\n console.log(` ${colors.dim}${symbols.arrow}${colors.reset} ${step}${timeStr}`);\r\n },\r\n \r\n buildComplete: (totalRoutes: number, staticRoutes: number, totalTime: number) => {\r\n console.log('');\r\n console.log(`${colors.bold}${colors.green}${symbols.success} Build completed!${colors.reset}`);\r\n console.log('');\r\n console.log(` ${colors.dim}Routes:${colors.reset} ${totalRoutes} total`);\r\n console.log(` ${colors.dim}Static:${colors.reset} ${staticRoutes} prerendered`);\r\n console.log(` ${colors.dim}Time:${colors.reset} ${formatTime(totalTime)}`);\r\n console.log('');\r\n },\r\n \r\n legend: () => {\r\n console.log(`${colors.dim}${symbols.static} Static${colors.reset} ${colors.dim}${symbols.ssr} SSR${colors.reset} ${colors.dim}λ ISR${colors.reset}`);\r\n },\r\n \r\n banner: (buildId: string) => {\r\n console.log('');\r\n console.log(`${colors.bold}${colors.cyan} 🟢 Olova${colors.reset} ${colors.dim}Static Export${colors.reset}`);\r\n console.log(`${colors.dim} Build ID: ${buildId}${colors.reset}`);\r\n console.log('');\r\n },\r\n \r\n error: (text: string) => {\r\n console.log(`${colors.red}✗${colors.reset} ${colors.red}${text}${colors.reset}`);\r\n },\r\n \r\n warn: (text: string) => {\r\n console.log(`${colors.yellow}⚠${colors.reset} ${colors.yellow}${text}${colors.reset}`);\r\n },\r\n};\r\n\r\n// =============================================================================\r\n// SSG PLUGIN - Static Site Generation\r\n// =============================================================================\r\nexport function ssgPlugin(): Plugin {\r\n return {\r\n name: 'olova-ssg',\r\n apply: 'build',\r\n config() {\r\n if (process.env.IS_SSG_BUILD) {\r\n return {};\r\n }\r\n return {\r\n build: {\r\n manifest: true,\r\n rollupOptions: {\r\n input: 'index.html'\r\n }\r\n }\r\n }\r\n },\r\n async closeBundle() {\r\n if (process.env.IS_SSG_BUILD) return;\r\n process.env.IS_SSG_BUILD = 'true';\r\n \r\n const totalStartTime = performance.now();\r\n const buildId = generateBuildId();\r\n \r\n // Show banner\r\n logger.banner(buildId);\r\n \r\n // =========================================================\r\n // STEP 1: Build Server Entry\r\n // =========================================================\r\n logger.header('Generating static pages...');\r\n const serverBuildStart = performance.now();\r\n \r\n try {\r\n await build({\r\n configFile: './vite.config.ts',\r\n build: {\r\n ssr: true,\r\n outDir: '.olova/server',\r\n rollupOptions: {\r\n input: 'olova/server',\r\n },\r\n emptyOutDir: true,\r\n reportCompressedSize: false,\r\n },\r\n // Ensure virtual modules are bundled, not left as external imports\r\n ssr: {\r\n noExternal: true,\r\n },\r\n logLevel: 'silent',\r\n });\r\n logger.step('Server bundle compiled', performance.now() - serverBuildStart);\r\n } catch (e) {\r\n logger.error('SSG Build Failed');\r\n console.error(e);\r\n process.env.IS_SSG_BUILD = '';\r\n return;\r\n } finally {\r\n process.env.IS_SSG_BUILD = '';\r\n }\r\n\r\n // =========================================================\r\n // STEP 2: Scan Routes\r\n // =========================================================\r\n const scanStart = performance.now();\r\n const allRoutes: { route: string, isStatic: boolean, filePath: string }[] = [];\r\n \r\n const scan = (dir: string, base: string = '') => {\r\n if (!fs.existsSync(dir)) return;\r\n const entries = fs.readdirSync(dir, { withFileTypes: true });\r\n for (const entry of entries) {\r\n const fullPath = path.join(dir, entry.name);\r\n if (entry.isDirectory()) {\r\n const isRouteGroup = /^\\(.+\\)$/.test(entry.name);\r\n if (isRouteGroup) {\r\n scan(fullPath, base);\r\n } else {\r\n scan(fullPath, `${base}/${entry.name}`);\r\n }\r\n } else {\r\n const ext = path.extname(entry.name);\r\n const supportedExts = ['.tsx', '.jsx', '.html', '.md'];\r\n \r\n if (supportedExts.includes(ext)) {\r\n const nameNoExt = entry.name.replace(/\\.(tsx|jsx|html|md)$/, '');\r\n if (nameNoExt === 'root') continue;\r\n let route = base;\r\n if (nameNoExt !== 'index' && nameNoExt !== 'App') {\r\n route = `${base}/${nameNoExt}`;\r\n }\r\n if (route === '') route = '/';\r\n if (route.includes('$')) continue;\r\n \r\n if (ext === '.html' || ext === '.md') {\r\n allRoutes.push({ route, isStatic: true, filePath: fullPath });\r\n } else {\r\n const fileContent = fs.readFileSync(fullPath, 'utf-8');\r\n const firstLine = fileContent.trim().split('\\n')[0].trim();\r\n const isStatic = firstLine === '\"static\"' || firstLine === \"'static'\";\r\n allRoutes.push({ route, isStatic, filePath: fullPath });\r\n }\r\n }\r\n }\r\n }\r\n };\r\n scan(path.resolve('src'));\r\n logger.step(`Found ${allRoutes.length} routes`, performance.now() - scanStart);\r\n\r\n // =========================================================\r\n // STEP 3: Load Server Entry\r\n // =========================================================\r\n const serverDir = path.resolve('.olova/server');\r\n let serverFile = fs.readdirSync(serverDir).find(f => \r\n (f === 'server.js' || f.includes('server-entry')) && f.endsWith('.js')\r\n );\r\n if (!serverFile) {\r\n logger.error('Could not find server build artifact');\r\n return;\r\n }\r\n const serverEntryPath = path.join(serverDir, serverFile);\r\n const { render, renderShell, renderShellWithMetadata, loadRoute } = await import(pathToFileURL(serverEntryPath).href);\r\n\r\n // =========================================================\r\n // STEP 4: Prepare Assets\r\n // =========================================================\r\n const assetsStart = performance.now();\r\n const distDir = path.resolve('.olova/dist');\r\n const clientHtmlPath = path.join(distDir, 'index.html');\r\n \r\n let shellHtml = renderShell();\r\n if (!shellHtml.startsWith('<!DOCTYPE html>')) {\r\n shellHtml = `<!DOCTYPE html>\\n${shellHtml}`;\r\n }\r\n \r\n let template = '';\r\n if (fs.existsSync(clientHtmlPath)) {\r\n template = fs.readFileSync(clientHtmlPath, 'utf-8');\r\n }\r\n\r\n // Read manifest to get CSS and JS entry files\r\n const manifestPath = path.join(distDir, '.vite', 'manifest.json');\r\n let cssLinks: string[] = [];\r\n let entryScript = ''; // The main entry point script tag\r\n if (fs.existsSync(manifestPath)) {\r\n try {\r\n const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf-8'));\r\n // Find entry point files (CSS and JS)\r\n for (const [key, value] of Object.entries(manifest)) {\r\n const entry = value as { isEntry?: boolean; css?: string[]; file?: string };\r\n \r\n // Extract CSS files from all entries\r\n if (entry.css && entry.css.length > 0) {\r\n for (const cssFile of entry.css) {\r\n const cssLink = `<link rel=\"stylesheet\" href=\"/${cssFile}\" />`;\r\n if (!cssLinks.includes(cssLink)) {\r\n cssLinks.push(cssLink);\r\n }\r\n }\r\n }\r\n \r\n // Extract the main entry JS file (this is critical for hydration!)\r\n if (entry.isEntry && entry.file) {\r\n entryScript = `<script type=\"module\" crossorigin src=\"/${entry.file}\"></script>`;\r\n logger.step(`Found entry script: ${entry.file}`);\r\n }\r\n }\r\n if (cssLinks.length > 0) {\r\n logger.step(`Found ${cssLinks.length} CSS file(s) from manifest`);\r\n }\r\n if (!entryScript) {\r\n // Fallback: look for any olova-*.js file in the static folder\r\n const staticDir = path.join(distDir, 'pro_olova_static');\r\n if (fs.existsSync(staticDir)) {\r\n const files = fs.readdirSync(staticDir);\r\n const entryFile = files.find(f => f.startsWith('olova-') && f.endsWith('.js'));\r\n if (entryFile) {\r\n entryScript = `<script type=\"module\" crossorigin src=\"/pro_olova_static/${entryFile}\"></script>`;\r\n logger.step(`Found entry script (fallback): ${entryFile}`);\r\n }\r\n }\r\n }\r\n } catch (e) {\r\n logger.warn('Could not parse manifest.json');\r\n }\r\n }\r\n\r\n const scripts = template.match(/<script[\\s\\S]*?>[\\s\\S]*?<\\/script>/gi) || [];\r\n const links = template.match(/<link[\\s\\S]*?>/gi) || [];\r\n \r\n const chunksDir = path.join(distDir, 'pro_olova_static', 'chunks');\r\n let preloadLinks: string[] = [];\r\n if (fs.existsSync(chunksDir)) {\r\n const chunks = fs.readdirSync(chunksDir).filter(f => f.endsWith('.js'));\r\n preloadLinks = chunks.map(chunk => \r\n `<link rel=\"modulepreload\" crossorigin href=\"/pro_olova_static/chunks/${chunk}\" />`\r\n );\r\n }\r\n \r\n const mainScriptMatch = template.match(/src=\"(\\/pro_olova_static\\/olova-[^\"]+\\.js)\"/);\r\n if (mainScriptMatch) {\r\n preloadLinks.unshift(`<link rel=\"modulepreload\" crossorigin href=\"${mainScriptMatch[1]}\" />`);\r\n }\r\n \r\n const chunkList: string[] = [];\r\n if (fs.existsSync(chunksDir)) {\r\n const chunks = fs.readdirSync(chunksDir).filter(f => f.endsWith('.js'));\r\n chunks.forEach(chunk => chunkList.push(`/pro_olova_static/chunks/${chunk}`));\r\n }\r\n \r\n // Performance optimizations\r\n const resourceHints = generateResourceHints();\r\n const criticalCSS = generateCriticalCSS();\r\n const performanceMeta = generatePerformanceMeta();\r\n const swScript = generateServiceWorkerScript();\r\n const performanceHead = [performanceMeta, resourceHints, criticalCSS].join('');\r\n \r\n // Service Worker\r\n const allAssetsForSW = [\r\n '/',\r\n '/index.html',\r\n ...chunkList,\r\n ...cssLinks.map(l => l.match(/href=\"([^\"]+)\"/)?.[1]).filter(Boolean) as string[],\r\n ...links.map(l => l.match(/href=\"([^\"]+)\"/)?.[1]).filter(Boolean) as string[],\r\n ...(entryScript.match(/src=\"([^\"]+)\"/) ? [entryScript.match(/src=\"([^\"]+)\"/)![1]] : [])\r\n ];\r\n const swContent = generateServiceWorkerContent(buildId, allAssetsForSW);\r\n fs.writeFileSync(path.join(distDir, 'sw.js'), swContent);\r\n \r\n // Include CSS links first for fast style loading, then validation scripts, then the entry script\r\n const assets = [performanceHead, ...cssLinks, ...links, ...preloadLinks, ...scripts, entryScript, swScript].join('\\n');\r\n logger.step(`Assets optimized (${cssLinks.length} styles, ${preloadLinks.length} preloads, SW ready)`, performance.now() - assetsStart);\r\n\r\n // =========================================================\r\n // STEP 5: Generate Routes\r\n // =========================================================\r\n console.log('');\r\n logger.header('Route');\r\n logger.legend();\r\n console.log('');\r\n \r\n let staticCount = 0;\r\n const routeResults: { route: string, type: 'static' | 'ssr', size: number, time: number }[] = [];\r\n \r\n for (const { route, isStatic } of allRoutes) {\r\n const routeStart = performance.now();\r\n let finalHtml = '';\r\n let isFullRender = false;\r\n \r\n // Always try to render full page first (unless explicitly opted out, which we don't support yet)\r\n // This ensures SSG content matches Client hydration for better UX and SEO\r\n try {\r\n const { html, hydrationData } = await render(route);\r\n if (html) {\r\n finalHtml = html;\r\n isFullRender = true;\r\n staticCount++;\r\n \r\n if (Object.keys(hydrationData.params || {}).length > 0) {\r\n const scriptTag = `<script>window.__OLOVA_DATA__ = ${JSON.stringify(hydrationData)};</script>`;\r\n if (finalHtml.includes('</body>')) {\r\n finalHtml = finalHtml.replace('</body>', `${scriptTag}\\n</body>`);\r\n } else {\r\n finalHtml += `\\n${scriptTag}`;\r\n }\r\n }\r\n\r\n const jsonLdScript = generateJsonLd({ route, metadata: hydrationData.metadata });\r\n \r\n if (finalHtml.includes('</head>')) {\r\n finalHtml = finalHtml.replace('</head>', `${jsonLdScript}${assets}\\n</head>`);\r\n } else {\r\n finalHtml = finalHtml.replace('</body>', `${assets}\\n</body>`);\r\n }\r\n if (!finalHtml.startsWith('<!DOCTYPE html>')) {\r\n finalHtml = `<!DOCTYPE html>\\n${finalHtml}`;\r\n }\r\n\r\n const flightScripts = generateOlovaHydration({\r\n route,\r\n metadata: hydrationData.metadata,\r\n params: hydrationData.params,\r\n chunks: chunkList,\r\n isStatic: true,\r\n }, buildId);\r\n if (finalHtml.includes('</body>')) {\r\n finalHtml = finalHtml.replace('</body>', `${flightScripts}</body>`);\r\n }\r\n\r\n finalHtml = minifyHtml(finalHtml);\r\n }\r\n } catch (e) {\r\n // Fallback to shell if render fails\r\n console.error(`[SSG] Render failed for ${route}:`, e);\r\n }\r\n\r\n // Fallback to Shell Rendering if full render failed\r\n if (!isFullRender) {\r\n let pageMetadata = {};\r\n try {\r\n const routeResult = await loadRoute(route);\r\n if (routeResult && routeResult.metadata) {\r\n pageMetadata = routeResult.metadata;\r\n }\r\n } catch (e) {\r\n // Continue with empty metadata\r\n }\r\n \r\n finalHtml = renderShellWithMetadata(pageMetadata);\r\n if (!finalHtml.startsWith('<!DOCTYPE html>')) {\r\n finalHtml = `<!DOCTYPE html>\\n${finalHtml}`;\r\n }\r\n \r\n const jsonLdScript = generateJsonLd({ route, metadata: pageMetadata });\r\n \r\n if (finalHtml.includes('</head>')) {\r\n finalHtml = finalHtml.replace('</head>', `${jsonLdScript}${assets}\\n</head>`);\r\n } else {\r\n finalHtml = finalHtml.replace('</body>', `${assets}\\n</body>`);\r\n }\r\n \r\n const flightScripts = generateOlovaHydration({\r\n route,\r\n metadata: pageMetadata,\r\n chunks: chunkList,\r\n isStatic: false,\r\n }, buildId);\r\n if (finalHtml.includes('</body>')) {\r\n finalHtml = finalHtml.replace('</body>', `${flightScripts}</body>`);\r\n }\r\n }\r\n\r\n const outPath = path.join(distDir, route === '/' ? 'index.html' : `${route}/index.html`);\r\n fs.mkdirSync(path.dirname(outPath), { recursive: true });\r\n fs.writeFileSync(outPath, finalHtml);\r\n \r\n const routeTime = performance.now() - routeStart;\r\n const routeSize = Buffer.byteLength(finalHtml, 'utf8');\r\n routeResults.push({ route, type: isStatic ? 'static' : 'ssr', size: routeSize, time: routeTime });\r\n \r\n logger.route(route, isStatic ? 'static' : 'ssr', routeSize, routeTime);\r\n }\r\n\r\n // =========================================================\r\n // STEP 6: Generate 404.html\r\n // =========================================================\r\n const fallbackPath = path.join(distDir, '404.html');\r\n if (fs.existsSync(clientHtmlPath)) {\r\n fs.copyFileSync(clientHtmlPath, fallbackPath);\r\n }\r\n\r\n // =========================================================\r\n // Final Summary\r\n // =========================================================\r\n const totalTime = performance.now() - totalStartTime;\r\n logger.buildComplete(allRoutes.length, staticCount, totalTime);\r\n \r\n // Output directory info\r\n console.log(`${colors.dim} Output:${colors.reset} .olova/dist`);\r\n console.log('');\r\n }\r\n };\r\n}\r\n","// Helper function to minify HTML (Next.js-style compact output)\r\nexport function minifyHtml(html: string): string {\r\n return html\r\n // Remove HTML comments (but keep conditional comments)\r\n .replace(/<!--(?!\\[if).*?-->/gs, '')\r\n // Collapse multiple whitespace to single space\r\n .replace(/\\s+/g, ' ')\r\n // Remove whitespace between tags\r\n .replace(/> </g, '><')\r\n // Remove whitespace around tags\r\n .replace(/\\s*(<[^>]+>)\\s*/g, '$1')\r\n // Trim\r\n .trim();\r\n}\r\n\r\n// Generate unique build ID for cache busting (like Next.js buildId)\r\nexport function generateBuildId(): string {\r\n return Math.random().toString(36).substring(2, 15) + Date.now().toString(36);\r\n}\r\n\r\nexport function generateResourceHints(): string {\r\n return `\r\n <link rel=\"dns-prefetch\" href=\"//fonts.googleapis.com\">\r\n <link rel=\"dns-prefetch\" href=\"//fonts.gstatic.com\">\r\n <link rel=\"dns-prefetch\" href=\"//cdn.jsdelivr.net\">\r\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\" crossorigin>\r\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\r\n `.trim().replace(/\\n\\s+/g, '');\r\n}\r\n\r\n// Generate critical CSS for above-the-fold content (inline in head)\r\nexport function generateCriticalCSS(): string {\r\n return `<style id=\"olova-critical\">\r\n *{box-sizing:border-box;margin:0;padding:0}\r\n html{-webkit-text-size-adjust:100%;line-height:1.5}\r\n body{font-family:system-ui,-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif}\r\n img,video{max-width:100%;height:auto}\r\n [hidden]{display:none!important}\r\n </style>`.replace(/\\n\\s*/g, '');\r\n}\r\n\r\n// Generate service worker registration script\r\nexport function generateServiceWorkerScript(): string {\r\n return `<script>if('serviceWorker'in navigator){window.addEventListener('load',()=>{navigator.serviceWorker.register('/sw.js').catch(()=>{})})}</script>`;\r\n}\r\n\r\n// Generate service worker file content for offline caching\r\nexport function generateServiceWorkerContent(buildId: string, assets: string[]): string {\r\n return `// Olova Service Worker v${buildId}\r\nconst CACHE_NAME = 'olova-cache-${buildId}';\r\nconst ASSETS = ${JSON.stringify(assets)};\r\n\r\nself.addEventListener('install', (e) => {\r\n e.waitUntil(caches.open(CACHE_NAME).then(cache => cache.addAll(ASSETS)));\r\n self.skipWaiting();\r\n});\r\n\r\nself.addEventListener('activate', (e) => {\r\n e.waitUntil(caches.keys().then(keys => Promise.all(\r\n keys.filter(k => k !== CACHE_NAME).map(k => caches.delete(k))\r\n )));\r\n});\r\n\r\nself.addEventListener('fetch', (e) => {\r\n e.respondWith(caches.match(e.request).then(r => r || fetch(e.request)));\r\n});\r\n`;\r\n}\r\n\r\n// Generate performance meta tags\r\nexport function generatePerformanceMeta(): string {\r\n return `<meta http-equiv=\"x-dns-prefetch-control\" content=\"on\"><meta name=\"color-scheme\" content=\"light dark\">`;\r\n}\r\n","import { type Plugin } from 'vite';\r\nimport fs from 'fs';\r\nimport path from 'path';\r\n\r\n// =============================================================================\r\n// CLEAN URL PLUGIN - Handles clean URLs in preview mode\r\n// =============================================================================\r\nexport function cleanUrlPlugin(): Plugin {\r\n return {\r\n name: 'olova-clean-url',\r\n configurePreviewServer(server) {\r\n // Use middleware that runs BEFORE Vite's static serving\r\n server.middlewares.use((req, res, next) => {\r\n const urlPath = (req.url || '/').split('?')[0];\r\n const distDir = path.resolve('.olova/dist');\r\n \r\n // Handle root path\r\n if (urlPath === '/') {\r\n const indexPath = path.join(distDir, 'index.html');\r\n if (fs.existsSync(indexPath)) {\r\n const content = fs.readFileSync(indexPath, 'utf-8');\r\n res.setHeader('Content-Type', 'text/html');\r\n res.end(content);\r\n return;\r\n }\r\n }\r\n \r\n // Skip if it has a file extension (assets, scripts, etc.)\r\n if (urlPath.includes('.')) return next();\r\n \r\n // Check if /route/index.html exists (clean URLs)\r\n const indexPath = path.join(distDir, urlPath, 'index.html');\r\n if (fs.existsSync(indexPath)) {\r\n const content = fs.readFileSync(indexPath, 'utf-8');\r\n res.setHeader('Content-Type', 'text/html');\r\n res.end(content);\r\n return;\r\n }\r\n \r\n next();\r\n });\r\n }\r\n };\r\n}\r\n","import { type Plugin } from \"vite\";\r\nimport fs from \"fs\";\r\nimport path from \"path\";\r\n\r\n// =============================================================================\r\n// AUTO GENERATE PLUGIN - Auto-generates boilerplate code for new route files\r\n// =============================================================================\r\n\r\n/**\r\n * Converts a folder name to PascalCase for component naming\r\n */\r\nfunction toPascalCase(str: string): string {\r\n // Remove $ prefix for dynamic routes\r\n const cleanStr = str.replace(/^\\$/, \"\");\r\n\r\n return cleanStr\r\n .split(/[-_]/)\r\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\r\n .join(\"\");\r\n}\r\n\r\n/**\r\n * Generates the boilerplate code for a new route component\r\n */\r\nfunction generateBoilerplate(folderName: string, isDynamic: boolean): string {\r\n const componentName = toPascalCase(folderName);\r\n\r\n if (isDynamic) {\r\n // Dynamic route with useParams\r\n const paramName = folderName.replace(/^\\$/, \"\");\r\n return `import { useParams } from '../../route';\r\n\r\nexport default function ${componentName}() {\r\n const { ${paramName} } = useParams();\r\n return (\r\n <div>\r\n <h1>${componentName} Page</h1>\r\n <p>{${paramName}}</p>\r\n </div>\r\n );\r\n}\r\n`;\r\n }\r\n\r\n // Regular static route\r\n return `export default function ${componentName}() {\r\n return (\r\n <div>\r\n <h1>${componentName} Page</h1>\r\n <p>Welcome to ${componentName}</p>\r\n </div>\r\n );\r\n}\r\n`;\r\n}\r\n\r\nexport function autoGeneratePlugin(): Plugin {\r\n let srcDir: string;\r\n\r\n return {\r\n name: \"olova-auto-generate\",\r\n\r\n configResolved(config) {\r\n srcDir = path.resolve(config.root, \"src\");\r\n },\r\n\r\n configureServer(server) {\r\n console.log(\r\n \"\\x1b[36m[olova] Auto-generate plugin active - watching for new route files\\x1b[0m\"\r\n );\r\n\r\n // Watch for file creation events\r\n server.watcher.on(\"add\", (filePath: string) => {\r\n // Normalize path for Windows compatibility\r\n const normalizedPath = path.normalize(filePath);\r\n const normalizedSrcDir = path.normalize(srcDir);\r\n\r\n // Only process .tsx or .jsx files\r\n const ext = path.extname(normalizedPath);\r\n if (ext !== \".tsx\" && ext !== \".jsx\") {\r\n return;\r\n }\r\n\r\n // Check if file is inside src directory\r\n if (!normalizedPath.startsWith(normalizedSrcDir)) {\r\n return;\r\n }\r\n\r\n // Get the file name without extension\r\n const fileName = path.basename(normalizedPath, ext);\r\n\r\n // Only auto-generate for index files\r\n if (fileName !== \"index\") {\r\n return;\r\n }\r\n\r\n // Get the folder name\r\n const folderPath = path.dirname(normalizedPath);\r\n const folderName = path.basename(folderPath);\r\n\r\n // Skip root src folder and route groups (folders starting with parentheses)\r\n if (folderName === \"src\" || folderName.startsWith(\"(\")) {\r\n return;\r\n }\r\n\r\n // Check if file is empty or very small (just created)\r\n try {\r\n fs.statSync(normalizedPath);\r\n const content = fs.readFileSync(normalizedPath, \"utf-8\");\r\n\r\n // Only generate if file is empty or has minimal content\r\n if (content.trim().length > 10) {\r\n return;\r\n }\r\n } catch (err) {\r\n // File might not exist yet or other error, skip\r\n return;\r\n }\r\n\r\n // Check if it's a dynamic route (folder starts with $)\r\n const isDynamic = folderName.startsWith(\"$\");\r\n\r\n // Generate the boilerplate\r\n const boilerplate = generateBoilerplate(folderName, isDynamic);\r\n\r\n // Write the boilerplate to the file\r\n try {\r\n fs.writeFileSync(normalizedPath, boilerplate, \"utf-8\");\r\n console.log(\r\n `\\x1b[32m✓ [olova] Auto-generated: ${folderName}/index${ext}\\x1b[0m`\r\n );\r\n } catch (err) {\r\n console.error(\r\n `\\x1b[31m✗ [olova] Failed to write boilerplate:\\x1b[0m`,\r\n err\r\n );\r\n }\r\n });\r\n },\r\n };\r\n}\r\n","import { type Plugin, type ViteDevServer } from 'vite';\r\nimport path from 'path';\r\n\r\n// =============================================================================\r\n// PROACTIVE ERROR CHECKER - Validates all files on save like Next.js\r\n// This makes Vite's error overlay show instantly for ANY file with an error\r\n// =============================================================================\r\n\r\nexport function proactiveErrorPlugin(): Plugin {\r\n return {\r\n name: 'olova-proactive-error',\r\n enforce: 'post',\r\n\r\n configureServer(devServer: ViteDevServer) {\r\n const srcDir = path.resolve(process.cwd(), 'src');\r\n\r\n // Function to validate a file and send error to Vite's overlay\r\n const validateFile = async (filePath: string) => {\r\n if (!filePath.startsWith(srcDir)) return;\r\n if (!/\\.(tsx?|jsx?)$/.test(filePath)) return;\r\n\r\n const relativePath = path.relative(srcDir, filePath);\r\n console.log('\\x1b[36m[olova]\\x1b[0m Checking:', relativePath);\r\n\r\n try {\r\n // Convert file path to URL format for Vite\r\n const url = '/' + path.relative(process.cwd(), filePath).replace(/\\\\/g, '/');\r\n \r\n // Proactively transform the file\r\n await devServer.transformRequest(url);\r\n \r\n console.log('\\x1b[32m[olova]\\x1b[0m ✓', relativePath, 'OK');\r\n } catch (err: any) {\r\n console.log('\\x1b[31m[olova]\\x1b[0m ✗', relativePath);\r\n \r\n // Send error to Vite's error overlay via WebSocket\r\n // This is the official way Vite shows errors in the overlay\r\n devServer.ws.send({\r\n type: 'error',\r\n err: {\r\n message: err.message || String(err),\r\n stack: err.stack || '',\r\n id: err.id || filePath,\r\n frame: err.frame || '',\r\n plugin: err.plugin || 'olova',\r\n loc: err.loc || undefined,\r\n },\r\n });\r\n }\r\n };\r\n\r\n // Watch for file changes\r\n devServer.watcher.on('change', async (filePath: string) => {\r\n // Small delay to ensure file is fully written\r\n await new Promise(r => setTimeout(r, 50));\r\n await validateFile(filePath);\r\n });\r\n\r\n // Also check new files when they're added\r\n devServer.watcher.on('add', async (filePath: string) => {\r\n // Wait for file to be fully written\r\n await new Promise(r => setTimeout(r, 100));\r\n await validateFile(filePath);\r\n });\r\n },\r\n };\r\n}\r\n","// Import all plugins from separate files\r\nexport { configPlugin } from './config';\r\nexport { routerPlugin } from './router';\r\nexport { frameworkPlugin } from './framework';\r\nexport { virtualHtmlPlugin } from './virtual-html';\r\nexport { ssgPlugin } from './ssg';\r\nexport { cleanUrlPlugin } from './clean-url';\r\nexport { autoGeneratePlugin } from './auto-generate';\r\nexport { proactiveErrorPlugin } from './error-overlay';\r\n\r\n// Import all plugins for the combined array\r\nimport { configPlugin } from './config';\r\nimport { routerPlugin } from './router';\r\nimport { frameworkPlugin } from './framework';\r\nimport { virtualHtmlPlugin } from './virtual-html';\r\nimport { ssgPlugin } from './ssg';\r\nimport { cleanUrlPlugin } from './clean-url';\r\nimport { autoGeneratePlugin } from './auto-generate';\r\nimport { proactiveErrorPlugin } from './error-overlay';\r\n\r\n// =============================================================================\r\n// EXPORT ALL PLUGINS AS A SINGLE ARRAY\r\n// =============================================================================\r\n// Using 'any[]' return type to avoid Vite version conflicts between packages\r\n// This prevents TypeScript errors when consumer projects have different Vite versions\r\nexport function olovaPlugins(): any[] {\r\n return [\r\n configPlugin(), // Must be first - creates .olova folder and sets config\r\n routerPlugin(),\r\n frameworkPlugin(),\r\n virtualHtmlPlugin(),\r\n ssgPlugin(),\r\n cleanUrlPlugin(),\r\n autoGeneratePlugin(), // Auto-generates boilerplate for new route files\r\n proactiveErrorPlugin(), // Checks all files on save for instant error detection\r\n ];\r\n}\r\n","// =============================================================================\r\n// TERMINAL STYLING UTILITIES\r\n// Next.js-inspired console output for professional CLI experience\r\n// =============================================================================\r\n\r\n// ANSI color codes for terminal styling\r\nexport const colors = {\r\n // Reset\r\n reset: '\\x1b[0m',\r\n \r\n // Styles\r\n bold: '\\x1b[1m',\r\n dim: '\\x1b[2m',\r\n italic: '\\x1b[3m',\r\n underline: '\\x1b[4m',\r\n \r\n // Foreground colors\r\n black: '\\x1b[30m',\r\n red: '\\x1b[31m',\r\n green: '\\x1b[32m',\r\n yellow: '\\x1b[33m',\r\n blue: '\\x1b[34m',\r\n magenta: '\\x1b[35m',\r\n cyan: '\\x1b[36m',\r\n white: '\\x1b[37m',\r\n gray: '\\x1b[90m',\r\n \r\n // Background colors\r\n bgBlack: '\\x1b[40m',\r\n bgRed: '\\x1b[41m',\r\n bgGreen: '\\x1b[42m',\r\n bgYellow: '\\x1b[43m',\r\n bgBlue: '\\x1b[44m',\r\n bgMagenta: '\\x1b[45m',\r\n bgCyan: '\\x1b[46m',\r\n bgWhite: '\\x1b[47m',\r\n};\r\n\r\n// Symbols for terminal output\r\nexport const symbols = {\r\n success: '✓',\r\n error: '✗',\r\n warning: '⚠',\r\n info: 'ℹ',\r\n arrow: '→',\r\n arrowRight: '➜',\r\n bullet: '○',\r\n filled: '●',\r\n lambda: 'λ',\r\n triangle: '🟢',\r\n square: '■',\r\n diamond: '◆',\r\n star: '★',\r\n check: '✔',\r\n cross: '✖',\r\n pointer: '❯',\r\n};\r\n\r\n// Format time in human readable format\r\nexport function formatTime(ms: number): string {\r\n if (ms < 1) return '<1ms';\r\n if (ms < 10) return `${ms.toFixed(1)}ms`;\r\n if (ms < 1000) return `${Math.round(ms)}ms`;\r\n if (ms < 60000) return `${(ms / 1000).toFixed(2)}s`;\r\n const mins = Math.floor(ms / 60000);\r\n const secs = Math.round((ms % 60000) / 1000);\r\n return `${mins}m ${secs}s`;\r\n}\r\n\r\n// Format bytes in human readable format\r\nexport function formatBytes(bytes: number): string {\r\n if (bytes === 0) return '0 B';\r\n const k = 1024;\r\n const sizes = ['B', 'kB', 'MB', 'GB'];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(1))} ${sizes[i]}`;\r\n}\r\n\r\n// Logger utility with Next.js-style formatting\r\nexport const logger = {\r\n // Print banner\r\n banner: (name: string, version: string = '1.0.0') => {\r\n console.log('');\r\n console.log(` ${colors.bold}${colors.cyan}${symbols.triangle} ${name}${colors.reset} ${colors.dim}v${version}${colors.reset}`);\r\n console.log('');\r\n },\r\n \r\n // Print header\r\n header: (text: string) => {\r\n console.log(`\\n${colors.bold}${colors.white}${text}${colors.reset}`);\r\n },\r\n \r\n // Info message\r\n info: (text: string) => {\r\n console.log(`${colors.cyan}${symbols.info}${colors.reset} ${text}`);\r\n },\r\n \r\n // Success message\r\n success: (text: string, time?: number) => {\r\n const timeStr = time !== undefined ? ` ${colors.dim}${formatTime(time)}${colors.reset}` : '';\r\n console.log(`${colors.green}${symbols.success}${colors.reset} ${text}${timeStr}`);\r\n },\r\n \r\n // Error message\r\n error: (text: string) => {\r\n console.log(`${colors.red}${symbols.error}${colors.reset} ${colors.red}${text}${colors.reset}`);\r\n },\r\n \r\n // Warning message\r\n warn: (text: string) => {\r\n console.log(`${colors.yellow}${symbols.warning}${colors.reset} ${colors.yellow}${text}${colors.reset}`);\r\n },\r\n \r\n // Step in a process\r\n step: (text: string, time?: number) => {\r\n const timeStr = time !== undefined ? ` ${colors.gray}${formatTime(time)}${colors.reset}` : '';\r\n console.log(` ${colors.dim}${symbols.arrow}${colors.reset} ${text}${timeStr}`);\r\n },\r\n \r\n // Route log (for SSG)\r\n route: (route: string, type: 'static' | 'ssr' | 'isr', size?: number, time?: number) => {\r\n const symbol = type === 'static' ? symbols.bullet : type === 'ssr' ? symbols.filled : symbols.lambda;\r\n const color = type === 'static' ? colors.white : type === 'ssr' ? colors.magenta : colors.cyan;\r\n const sizeStr = size ? ` ${colors.dim}${formatBytes(size)}${colors.reset}` : '';\r\n const timeStr = time ? ` ${colors.gray}(${formatTime(time)})${colors.reset}` : '';\r\n console.log(`${color}${symbol}${colors.reset} ${route}${sizeStr}${timeStr}`);\r\n },\r\n \r\n // Indent text \r\n indent: (text: string, level: number = 1) => {\r\n console.log(`${' '.repeat(level)}${text}`);\r\n },\r\n \r\n // Empty line\r\n newline: () => console.log(''),\r\n \r\n // Dim text\r\n dim: (text: string) => `${colors.dim}${text}${colors.reset}`,\r\n \r\n // Bold text \r\n bold: (text: string) => `${colors.bold}${text}${colors.reset}`,\r\n \r\n // Colored text\r\n cyan: (text: string) => `${colors.cyan}${text}${colors.reset}`,\r\n green: (text: string) => `${colors.green}${text}${colors.reset}`,\r\n yellow: (text: string) => `${colors.yellow}${text}${colors.reset}`,\r\n red: (text: string) => `${colors.red}${text}${colors.reset}`,\r\n magenta: (text: string) => `${colors.magenta}${text}${colors.reset}`,\r\n};\r\n\r\n// Create a timer for measuring performance\r\nexport function createTimer() {\r\n const start = performance.now();\r\n return {\r\n elapsed: () => performance.now() - start,\r\n format: () => formatTime(performance.now() - start),\r\n };\r\n}\r\n"],"mappings":"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","names":["fs","path","fs","path","path","fs","fs","path","colors","fs","path","fs","path","indexPath","fs","path","path","colors","symbols","formatTime","formatBytes","logger"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "olova",
3
- "version": "2.0.39",
3
+ "version": "2.0.40",
4
4
  "description": "framework built with Vite - file-system routing, SSG, and SEO",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",