@inherits LayoutComponentBase
@implements IAsyncDisposable
@inject IJSRuntime JS
@inject NavigationManager Nav
@inject Lumeo.Services.ThemeService ThemeService
@inject Lumeo.Services.KeyboardShortcutService Shortcuts
@inject Lumeo.Services.ConsentService Consent

<div class="min-h-screen bg-background">
    <!-- Floating Navbar (outside animation wrapper — CSS transforms break fixed positioning) -->
    <div class="fixed top-3 inset-x-0 z-50 px-4 flex justify-center pointer-events-none">
        <header class="pointer-events-auto flex h-14 w-full max-w-[1400px] items-center gap-4 rounded-[var(--radius-xl)] border border-border/50 bg-background/85 backdrop-blur-md shadow-md px-4">
            <!-- Hamburger (mobile only) -->
            <Button Variant="Button.ButtonVariant.Ghost" Size="Button.ButtonSize.Icon"
                    Class="lg:hidden mr-1"
                    OnClick="@(() => _mobileNavOpen = !_mobileNavOpen)">
                <DynamicIcon Name="@(_mobileNavOpen ? "X" : "Menu")" Class="h-4 w-4" />
            </Button>

            <!-- Logo -->
            <Lumeo.Link Href="" Class="flex items-center space-x-2 font-bold text-lg text-foreground no-underline shrink-0">
                <svg width="28" height="28" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
                    <circle cx="16" cy="16" r="9" fill="none" stroke="currentColor" stroke-width="2" opacity="0.55"/>
                    <circle cx="16" cy="16" r="3" fill="currentColor"/>
                </svg>
                <Lumeo.Text As="span">Lumeo</Lumeo.Text>
            </Lumeo.Link>

            <!-- Nav links (desktop) -->
            <nav class="hidden md:flex items-center space-x-1 text-sm font-medium ml-2">
                <a href="docs/introduction" class="@NavLinkClass("docs")">Docs</a>
                <a href="components" class="@NavLinkClass("catalog")">Components</a>
                <a href="patterns" class="@NavLinkClass("patterns")">Patterns</a>
                <a href="blocks" class="@NavLinkClass("blocks")">Blocks</a>
            </nav>

            <!-- Spacer -->
            <div class="flex-1"></div>

            <!-- Search (icon on mobile, full bar on desktop) -->
            <Button Variant="Button.ButtonVariant.Ghost"
                    Class="h-auto items-center gap-2 rounded-md px-2 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground transition-colors sm:border sm:border-border sm:bg-muted/50 sm:px-3 sm:w-52"
                    data-search-trigger="true"
                    OnClick="OpenSearch">
                <DynamicIcon Name="Search" Class="h-4 w-4 sm:h-3.5 sm:w-3.5 shrink-0" />
                <Lumeo.Text As="span" Class="hidden sm:block flex-1 text-left">Search docs...</Lumeo.Text>
                <kbd class="hidden sm:inline-flex pointer-events-none rounded border bg-background px-1.5 py-0.5 text-[10px] font-medium text-muted-foreground">⌘K</kbd>
            </Button>

            <!-- Right actions -->
            <Flex Class="items-center gap-1">
                @if (ShowDocsLayout)
                {
                    <Button Variant="Button.ButtonVariant.Ghost" Size="Button.ButtonSize.Icon"
                            OnClick="@(() => { _customizerOpen = !_customizerOpen; })"
                            title="Toggle customizer (Ctrl+B)"
                            aria-label="Toggle customizer">
                        <DynamicIcon Name="SlidersHorizontal" Class="h-4 w-4" />
                    </Button>
                }
                <Button Variant="Button.ButtonVariant.Ghost" Size="Button.ButtonSize.Icon" OnClick="ToggleDarkMode"
                        title="Toggle dark mode (Ctrl+D)"
                        aria-label="@(_darkMode ? "Switch to light mode" : "Switch to dark mode")">
                    @if (_darkMode)
                    {
                        <DynamicIcon Name="Sun" Class="h-4 w-4" />
                    }
                    else
                    {
                        <DynamicIcon Name="Moon" Class="h-4 w-4" />
                    }
                </Button>
                <Lumeo.Link Href="https://github.com/Brain2k-0005/Lumeo" Class="inline-flex items-center justify-center h-9 w-9 rounded-md text-muted-foreground hover:text-foreground hover:bg-accent transition-colors no-underline"
                            aria-label="Lumeo on GitHub" title="Lumeo on GitHub">
                    <svg viewBox="0 0 24 24" class="h-4 w-4" fill="currentColor" aria-hidden="true">
                        <path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z"/>
                    </svg>
                </Lumeo.Link>
            </Flex>
        </header>
    </div>

    <!-- Main Content — animation wrapper here so transform doesn't break fixed nav -->
    <div class="pt-[76px] lumeo-app-enter">
    @if (ShowDocsLayout)
    {
        <Flex>
            @switch (SidebarSection)
            {
                case "blocks":
                    <BlocksSidebar />
                    break;
                case "docs":
                    <DocsSidebar />
                    break;
                case "components":
                    <ComponentDetailSidebar />
                    break;
                case "patterns":
                    <PatternsSidebar />
                    break;
                default:
                    break; // "none" — catalog and home get full-width, no sidebar
            }
            <main class="flex-1 min-w-0">
                <div class="container mx-auto px-4 sm:px-6 py-8 @(SidebarSection is "blocks" or "none" ? "" : "max-w-5xl")">
                    @Body
                </div>
            </main>
            @if (SidebarSection != "blocks" && SidebarSection != "none")
            {
                <OnThisPage />
            }
            <div class="hidden lg:block">
                <CustomizerSidebar IsOpen="@_customizerOpen" IsOpenChanged="@(v => { _customizerOpen = v; StateHasChanged(); })" />
            </div>
        </Flex>
    }
    else
    {
        <main class="flex-1 min-w-0">
            @Body
        </main>
    }
    </div>
</div>

<OverlayProvider />
<ToastProvider Position="ToastViewport.ToastPosition.BottomRight" />

@* ---------- Consent banner + conditional analytics ----------
   The banner persists the user's choice in localStorage and surfaces it via
   ConsentService.HasConsent("analytics"). Only when that's granted do we
   inject the Cloudflare Web Analytics beacon — so the site is fully cookie-
   free and zero-telemetry until the user opts in. *@
<ConsentBanner @ref="_consentBanner" PrivacyPolicyUrl="/privacy" />

@if (Consent.HasConsent("analytics") && !string.IsNullOrEmpty(CloudflareAnalyticsToken))
{
    <script defer src="https://static.cloudflareinsights.com/beacon.min.js"
            data-cf-beacon='@($"{{\"token\": \"{CloudflareAnalyticsToken}\"}}")'></script>
}

<!-- Search Command Palette -->
@if (_searchOpen)
{
    <div class="fixed inset-0 z-[100] flex items-start justify-center pt-[15vh]" data-testid="search-palette" role="dialog" aria-label="Search palette" @onkeydown="HandleSearchKeyDown">
        @* backdrop-blur was removed — re-rasterizing the blur on every hover
           repaint made item hover feel laggy on content-heavy pages. A simple
           opaque-ish background is much cheaper and visually equivalent. *@
        <div class="absolute inset-0 bg-background/85" @onclick="CloseSearch"></div>
        @* isolate + will-change promote the palette to its own compositor layer,
           so hover repaints don't invalidate anything behind the backdrop. *@
        <div class="relative w-full max-w-[480px] mx-4 rounded-[var(--radius-xl)] bg-card shadow-2xl border border-border/40 overflow-hidden isolate will-change-transform" @onclick:stopPropagation>

            @* Search input row *@
            <div class="flex items-center gap-3 px-4 border-b border-border/30">
                <DynamicIcon Name="Search" Class="h-4 w-4 text-muted-foreground/60 shrink-0" />
                <input class="flex-1 bg-transparent py-4 text-sm outline-none placeholder:text-muted-foreground/50 text-foreground"
                       placeholder="Search components, patterns..."
                       value="@_query"
                       @oninput="OnQueryChanged"
                       @ref="_searchInput"
                       autofocus />
                @if (_query.Length > 0)
                {
                    <button class="inline-flex items-center justify-center h-6 w-6 rounded text-muted-foreground/60 hover:text-foreground hover:bg-accent transition-colors"
                            @onclick='() => { _query = string.Empty; _hits = []; }'>
                        <DynamicIcon Name="X" Class="h-3.5 w-3.5" />
                    </button>
                }
            </div>

            @* Results list *@
            <div class="max-h-[360px] overflow-y-auto">
                @if (_query.Length > 0 && _hits.Count == 0)
                {
                    <div class="py-12 text-center">
                        <Lumeo.Text Size="sm" Color="muted">No results for "<Lumeo.Text As="span" Class="text-foreground">@_query</Lumeo.Text>"</Lumeo.Text>
                    </div>
                }
                else if (_query.Length == 0)
                {
                    @* Curated empty state — popular components *@
                    <div class="py-1.5">
                        <Lumeo.Text Size="xs" Color="muted" Class="px-4 py-1 block">Popular components</Lumeo.Text>
                        @foreach (var (label, slug) in _popularComponents)
                        {
                            <a class="w-full flex items-center gap-3 px-4 py-2.5 text-sm hover:bg-accent/50 transition-colors text-left group no-underline"
                               href="@($"components/{slug}")"
                               @onclick="CloseSearch">
                                <DynamicIcon Name="Component" Class="h-3.5 w-3.5 text-muted-foreground/50 shrink-0" />
                                <span class="flex-1 text-foreground/90">@label</span>
                                <span class="text-[11px] text-muted-foreground/40 group-hover:text-muted-foreground/60 transition-colors">Component</span>
                            </a>
                        }
                    </div>
                }
                else
                {
                    <div class="py-1.5">
                        @foreach (var hit in _hits)
                        {
                            <button class="w-full flex items-center gap-3 px-4 py-2.5 text-sm hover:bg-accent/50 transition-colors text-left group"
                                    data-testid="@($"search-palette-result-{SlugFromUrl(hit.Url)}")"
                                    @onclick="() => NavigateToHit(hit)">
                                <DynamicIcon Name="@GetSearchIcon(hit.Category)" Class="h-3.5 w-3.5 text-muted-foreground/50 shrink-0" />
                                <span class="flex-1 text-foreground/90">@hit.Title</span>
                                <span class="text-[11px] text-muted-foreground/40 group-hover:text-muted-foreground/60 transition-colors">@hit.Category</span>
                            </button>
                        }
                    </div>
                }
            </div>

            @* Footer *@
            <div class="border-t border-border/30 px-4 py-2 flex items-center gap-4 text-[11px] text-muted-foreground/50">
                <span class="flex items-center gap-1.5"><kbd class="rounded border border-border/40 bg-muted/50 px-1 py-0.5 text-[10px]">↵</kbd> select</span>
                <span class="flex items-center gap-1.5"><kbd class="rounded border border-border/40 bg-muted/50 px-1 py-0.5 text-[10px]">Esc</kbd> close</span>
                <span class="flex items-center gap-1.5 ml-auto"><kbd class="rounded border border-border/40 bg-muted/50 px-1 py-0.5 text-[10px]">Ctrl+D</kbd> dark mode</span>
                <span class="flex items-center gap-1.5"><kbd class="rounded border border-border/40 bg-muted/50 px-1 py-0.5 text-[10px]">Ctrl+B</kbd> sidebar</span>
                <span class="flex items-center gap-1.5"><kbd class="rounded border border-border/40 bg-muted/50 px-1 py-0.5 text-[10px]">Ctrl+/</kbd> shortcuts</span>
            </div>
        </div>
    </div>
}

<!-- Mobile Nav Overlay -->
@if (_mobileNavOpen)
{
    <div class="fixed inset-0 z-[80] lg:hidden" @onclick="@(() => _mobileNavOpen = false)">
        <div class="absolute inset-0 bg-background/80 backdrop-blur-sm"></div>
        <div class="absolute left-0 top-0 bottom-0 w-72 bg-card border-r border-border/50 shadow-2xl overflow-y-auto flex flex-col"
             @onclick:stopPropagation>
            <div class="flex items-center justify-between px-4 pt-4 pb-3 border-b border-border/40 shrink-0">
                <Lumeo.Text Class="font-semibold text-sm text-foreground">Navigation</Lumeo.Text>
                <Button Variant="Button.ButtonVariant.Ghost" Size="Button.ButtonSize.Icon" Class="h-7 w-7"
                        OnClick="@(() => _mobileNavOpen = false)">
                    <DynamicIcon Name="X" Class="h-4 w-4" />
                </Button>
            </div>
            <nav class="px-3 py-2 border-b border-border/30 flex gap-1 shrink-0">
                <a href="docs/introduction" class="@NavLinkClass("docs")">Docs</a>
                <a href="components" class="@NavLinkClass("catalog")">Components</a>
                <a href="patterns" class="@NavLinkClass("patterns")">Patterns</a>
                <a href="blocks" class="@NavLinkClass("blocks")">Blocks</a>
            </nav>
            @if (ShowDocsLayout)
            {
                <div class="flex-1 overflow-y-auto">
                    @switch (SidebarSection)
                    {
                        case "blocks":
                            <BlocksSidebar IsMobile="true" />
                            break;
                        case "docs":
                            <DocsSidebar IsMobile="true" />
                            break;
                        case "components":
                            <NavMenu Section="components" IsMobile="true" />
                            break;
                        case "patterns":
                            <PatternsSidebar IsMobile="true" />
                            break;
                        default:
                            break;
                    }
                </div>
            }
        </div>
    </div>
}

<!-- Mobile Customizer Overlay -->
@if (_customizerOpen && ShowDocsLayout)
{
    <div class="fixed inset-0 z-[90] lg:hidden" @onclick="@(() => _customizerOpen = false)">
        <div class="absolute inset-0 bg-background/80 backdrop-blur-sm"></div>
        <div class="absolute right-0 top-0 bottom-0 w-72 bg-card border-l border-border/50 shadow-2xl flex flex-col"
             @onclick:stopPropagation>
            <div class="flex items-center justify-between px-4 pt-4 pb-3 border-b border-border/40 shrink-0">
                <Lumeo.Text Class="font-semibold text-sm text-foreground">Customizer</Lumeo.Text>
                <Button Variant="Button.ButtonVariant.Ghost" Size="Button.ButtonSize.Icon" Class="h-7 w-7"
                        OnClick="@(() => _customizerOpen = false)">
                    <DynamicIcon Name="X" Class="h-4 w-4" />
                </Button>
            </div>
            <CustomizerSidebar IsOpen="true" IsMobile="true" IsOpenChanged="@(v => { _customizerOpen = v; StateHasChanged(); })" />
        </div>
    </div>
}

@code {
    // Cloudflare Web Analytics beacon token. When non-empty AND the user has
    // consented to the "analytics" category, MainLayout injects the beacon
    // script. Leave empty to ship without analytics at all.
    private const string CloudflareAnalyticsToken = "21fac6cd604348129ae8f1b345d46ba5";

    // Popular components shown in the Cmd+K empty state
    private static readonly (string Label, string Slug)[] _popularComponents =
    [
        ("Button",  "button"),
        ("Input",   "input"),
        ("Card",    "card"),
        ("Dialog",  "dialog"),
        ("Select",  "select"),
        ("Toast",   "toast"),
    ];

    private readonly List<IAsyncDisposable> _kbdShortcuts = new();
    private ConsentBanner? _consentBanner;
    private bool _darkMode;
    private bool _customizerOpen = false;
    private bool _mobileNavOpen;
    private bool _searchOpen;
    private string _query = string.Empty;
    private List<SearchHit> _hits = [];
    private CancellationTokenSource? _searchCts;
    private ElementReference _searchInput;

    /// <summary>Called from footer "Cookie preferences" link to re-open the dialog.</summary>
    public void OpenConsentPreferences() => _consentBanner?.ShowPreferences();

    private string CurrentPath => Nav.ToBaseRelativePath(Nav.Uri).TrimEnd('/').ToLowerInvariant();

    /// <summary>
    /// Returns the sidebar section to display based on the current route:
    /// "none"       — home (/) and bare catalog (/components)
    /// "docs"       — /docs/* routes
    /// "components" — /components/{slug} (specific component detail)
    /// "patterns"   — /patterns/*
    /// "blocks"     — /blocks/*
    /// Anything else defaults to "docs" (safe fallback for /themes etc.)
    /// </summary>
    private string SidebarSection
    {
        get
        {
            var p = CurrentPath;
            if (p == "") return "none";
            if (p.Equals("components", StringComparison.OrdinalIgnoreCase)) return "none"; // bare catalog → full width
            if (p.StartsWith("components/", StringComparison.OrdinalIgnoreCase)) return "components";
            if (p.StartsWith("docs", StringComparison.OrdinalIgnoreCase)) return "docs";
            if (p.StartsWith("patterns", StringComparison.OrdinalIgnoreCase)) return "patterns";
            if (p.StartsWith("blocks", StringComparison.OrdinalIgnoreCase)) return "blocks";
            return "docs"; // /themes and other misc pages default to docs sidebar
        }
    }

    private bool ShowDocsLayout
    {
        get
        {
            // Landing gets full-width layout (no docs sidebar)
            if (CurrentPath == "") return false;
            return true;
        }
    }

    private string NavLinkClass(string segment)
    {
        bool isActive;
        switch (segment)
        {
            case "catalog":
                // /components (catalog) AND /components/{slug} (component detail) both
                // belong to the Components section — keep top-nav highlight here while
                // browsing any component page.
                isActive = CurrentPath.Equals("components", StringComparison.OrdinalIgnoreCase)
                        || CurrentPath.StartsWith("components/", StringComparison.OrdinalIgnoreCase);
                break;
            case "docs":
                // Only /docs/* — guides, services, etc.
                isActive = CurrentPath.StartsWith("docs", StringComparison.OrdinalIgnoreCase);
                break;
            case "patterns":
                isActive = CurrentPath.StartsWith("patterns", StringComparison.OrdinalIgnoreCase);
                break;
            case "blocks":
                isActive = CurrentPath.StartsWith("blocks", StringComparison.OrdinalIgnoreCase);
                break;
            default:
                isActive = CurrentPath.StartsWith(segment, StringComparison.OrdinalIgnoreCase);
                break;
        }
        return isActive
            ? "rounded-md px-3 py-1.5 text-foreground bg-accent transition-colors no-underline"
            : "rounded-md px-3 py-1.5 text-muted-foreground hover:text-foreground hover:bg-accent transition-colors no-underline";
    }

    private record SearchHit(string Id, string Title, string Summary, string Category, string Type, string Url);

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            try
            {
                Nav.LocationChanged += OnLocationChanged;
                await ThemeService.InitializeAsync();
                _darkMode = ThemeService.IsDark;
                ThemeService.OnThemeChanged += OnThemeServiceChanged;
                StateHasChanged();

                await JS.InvokeVoidAsync("lumeo.setupSearch");

                // Signal to the prerender crawler (Puppeteer) that the app has
                // rendered the first route. No-op at runtime for real users.
                await JS.InvokeVoidAsync("lumeo.signalBlazorReady");

                _kbdShortcuts.Add(await Shortcuts.RegisterAsync("ctrl+b", () =>
                {
                    _customizerOpen = !_customizerOpen;
                    InvokeAsync(StateHasChanged);
                    return Task.CompletedTask;
                }));
                _kbdShortcuts.Add(await Shortcuts.RegisterAsync("ctrl+d", async () =>
                {
                    await ToggleDarkMode();
                    await InvokeAsync(StateHasChanged);
                }));
                _kbdShortcuts.Add(await Shortcuts.RegisterAsync("ctrl+/", () =>
                {
                    Nav.NavigateTo("docs/services/keyboard-shortcuts");
                    return Task.CompletedTask;
                }));
            }
            catch (Exception ex)
            {
                Console.WriteLine($"[Lumeo] Init error: {ex.Message}");
            }
        }
    }

    private async Task OpenSearch()
    {
        _searchOpen = true;
        _query = string.Empty;
        _hits = [];
        StateHasChanged();
        await Task.Delay(50);
        try { await _searchInput.FocusAsync(); } catch (Exception) { /* search input may not be rendered yet */ }
    }

    private void CloseSearch()
    {
        _searchOpen = false;
        _query = string.Empty;
        _hits = [];
        _searchCts?.Cancel();
    }

    private void HandleSearchKeyDown(KeyboardEventArgs e)
    {
        if (e.Key == "Escape") CloseSearch();
    }

    private async Task OnQueryChanged(ChangeEventArgs e)
    {
        _query = e.Value?.ToString() ?? string.Empty;
        _searchCts?.Cancel();
        _searchCts = new CancellationTokenSource();
        var token = _searchCts.Token;
        if (string.IsNullOrWhiteSpace(_query))
        {
            _hits = [];
            return;
        }
        try
        {
            // 50 ms is enough to coalesce fast typists without making the
            // first keystroke feel laggy. Local search itself is sub-2 ms.
            await Task.Delay(50, token);
            var hits = await JS.InvokeAsync<SearchHit[]>("lumeoAlgolia.search", token, _query);
            _hits = hits.ToList();
            StateHasChanged();
        }
        catch (TaskCanceledException) { /* superseded by newer query */ }
        catch (JSDisconnectedException) { /* user navigated away mid-await */ }
        catch (JSException ex)
        {
            Console.WriteLine($"[Lumeo] Search error: {ex.Message}");
        }
    }

    private void NavigateToHit(SearchHit hit)
    {
        CloseSearch();
        Nav.NavigateTo(hit.Url);
    }

    /// <summary>
    /// Derives a slug suitable for a stable test-id from a search hit URL.
    /// Strips path separators and any leading/trailing slashes so the result
    /// is safe to embed in <c>data-testid="search-palette-result-{slug}"</c>.
    /// </summary>
    private static string SlugFromUrl(string url)
    {
        if (string.IsNullOrWhiteSpace(url)) return "unknown";
        var trimmed = url.Trim('/').ToLowerInvariant();
        // Take the last path segment (e.g. "components/badge" -> "badge")
        var lastSlash = trimmed.LastIndexOf('/');
        var slug = lastSlash >= 0 ? trimmed[(lastSlash + 1)..] : trimmed;
        // Strip query string if any
        var q = slug.IndexOf('?');
        if (q >= 0) slug = slug[..q];
        return string.IsNullOrEmpty(slug) ? "unknown" : slug;
    }

    private static string GetSearchIcon(string category) => category switch
    {
        "Blocks" => "LayoutGrid",
        "Charts" => "TrendingUp",
        "Services" => "Wrench",
        "Customization" => "Palette",
        "Components" => "Component",
        "Getting Started" => "BookOpen",
        "Patterns" => "Puzzle",
        "Guides" => "FileText",
        _ => "Box"
    };

    private void OnThemeServiceChanged()
    {
        _darkMode = ThemeService.IsDark;
        InvokeAsync(StateHasChanged);
    }

    private void OnLocationChanged(object? sender, Microsoft.AspNetCore.Components.Routing.LocationChangedEventArgs e)
    {
        _mobileNavOpen = false;
        InvokeAsync(StateHasChanged);
    }

    public async ValueTask DisposeAsync()
    {
        Nav.LocationChanged -= OnLocationChanged;
        ThemeService.OnThemeChanged -= OnThemeServiceChanged;
        _searchCts?.Cancel();
        _searchCts?.Dispose();
        foreach (var s in _kbdShortcuts) await s.DisposeAsync();
    }

    private async Task ToggleDarkMode()
    {
        await ThemeService.ToggleModeAsync();
        _darkMode = ThemeService.IsDark;
    }
}
