var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var VisualizeResourceComponent_1;
/**
 * @fileoverview Knowledge Hub "Visualize" Resource (host surface)
 *
 * Phase 5 host surface that replaces the standalone "Clusters" tab. It hosts two
 * visualization modes behind an internal segmented control:
 *   - "Clusters"  — the existing cluster scatter visualization (embedded child).
 *   - "Tag Cloud" — a weighted tag cloud driven by TagCloudEngine.
 *
 * Both modes feed ONE shared record-drilldown panel:
 *   - cluster point selection  → a single record opened/listed.
 *   - tag-cloud word selection → the records carrying that tag (via RunView).
 *
 * The host owns the resource lifecycle (NotifyLoadComplete), agent context
 * (ActiveVisualizationMode), and all navigation — the embedded children emit
 * open-record intents up to here.
 */
import { Component, ChangeDetectorRef, inject, ViewChild } from '@angular/core';
import { Subject } from 'rxjs';
import { CompositeKey, RunView } from '@memberjunction/core';
import { UserInfoEngine } from '@memberjunction/core-entities';
import { RegisterClass } from '@memberjunction/global';
import { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';
import { buildVisualizeAgentContext, resolveDrilldownRecord, capVisualizeList, VISUALIZATION_MODES, } from './visualize-agent-context';
import { validateEnumParam, validateStringParam } from '../../../shared/agent-tool-validation';
import * as i0 from "@angular/core";
import * as i1 from "@memberjunction/ng-ui-components";
import * as i2 from "../clusters/cluster-visualization-resource.component";
import * as i3 from "./tag-cloud/tag-cloud.component";
import * as i4 from "./record-drilldown/record-drilldown.component";
const _c0 = ["tagCloud"];
function VisualizeResourceComponent_For_5_Template(rf, ctx) { if (rf & 1) {
    const _r1 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "button", 11);
    i0.ɵɵlistener("click", function VisualizeResourceComponent_For_5_Template_button_click_0_listener() { const mode_r2 = i0.ɵɵrestoreView(_r1).$implicit; const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.SelectMode(mode_r2.ID)); });
    i0.ɵɵelement(1, "i");
    i0.ɵɵelementStart(2, "span");
    i0.ɵɵtext(3);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const mode_r2 = ctx.$implicit;
    const ctx_r2 = i0.ɵɵnextContext();
    i0.ɵɵclassProp("active", ctx_r2.IsActiveMode(mode_r2.ID));
    i0.ɵɵattribute("aria-selected", ctx_r2.IsActiveMode(mode_r2.ID));
    i0.ɵɵadvance();
    i0.ɵɵclassMap(mode_r2.Icon);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(mode_r2.Label);
} }
function VisualizeResourceComponent_Conditional_9_Template(rf, ctx) { if (rf & 1) {
    const _r4 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "app-cluster-visualization-resource", 12);
    i0.ɵɵlistener("OpenRecordRequested", function VisualizeResourceComponent_Conditional_9_Template_app_cluster_visualization_resource_OpenRecordRequested_0_listener($event) { i0.ɵɵrestoreView(_r4); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnClusterOpenRecord($event)); });
    i0.ɵɵelementEnd();
} if (rf & 2) {
    i0.ɵɵproperty("Embedded", true);
} }
function VisualizeResourceComponent_Conditional_10_Template(rf, ctx) { if (rf & 1) {
    const _r5 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "app-kh-tag-cloud", 13, 0);
    i0.ɵɵlistener("TagSelected", function VisualizeResourceComponent_Conditional_10_Template_app_kh_tag_cloud_TagSelected_0_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r2 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r2.OnTagSelected($event)); });
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r2 = i0.ɵɵnextContext();
    i0.ɵɵproperty("Provider", ctx_r2.Provider);
} }
let VisualizeResourceComponent = class VisualizeResourceComponent extends BaseResourceComponent {
    static { VisualizeResourceComponent_1 = this; }
    tagCloud;
    cdr = inject(ChangeDetectorRef);
    navigationService = inject(NavigationService);
    destroy$ = new Subject();
    // ================================================================
    // Resource overrides
    // ================================================================
    async GetResourceDisplayName(_data) {
        return 'Visualize';
    }
    async GetResourceIconClass(_data) {
        return 'fa-solid fa-circle-nodes';
    }
    // ================================================================
    // Mode switch
    // ================================================================
    Modes = [
        { ID: 'clusters', Label: 'Clusters', Icon: 'fa-solid fa-circle-nodes' },
        { ID: 'tagcloud', Label: 'Tag Cloud', Icon: 'fa-solid fa-cloud' },
    ];
    ActiveMode = 'clusters';
    // ================================================================
    // Shared drilldown state
    // ================================================================
    DrilldownVisible = false;
    DrilldownTitle = '';
    DrilldownSubtitle = '';
    DrilldownIcon = 'fa-solid fa-list';
    DrilldownLoading = false;
    DrilldownRecords = [];
    // ================================================================
    // Preferences
    // ================================================================
    /** Current preference key for the active mode. */
    static PREFS_KEY = 'KH_Visualize_Mode';
    /** Legacy key (pre-rename) — read for back-compat only. */
    static LEGACY_PREFS_KEY = 'KH_Clusters_ActiveTab';
    // ================================================================
    // Lifecycle
    // ================================================================
    async ngAfterViewInit() {
        await UserInfoEngine.Instance.Config(false);
        this.loadModePreference();
        this.emitAgentContext();
        this.registerAgentTools();
        // loadModePreference() may flip ActiveMode AFTER the view's first CD pass
        // (it runs post-`await`), which swaps the `@if (IsActiveMode('clusters'))`
        // branch and the embedded child's count bindings mid-cycle — surfacing an
        // NG0100. Flush once here so the mode is settled before the next checked render.
        this.cdr.detectChanges();
        this.NotifyLoadComplete();
    }
    ngOnDestroy() {
        super.ngOnDestroy();
        this.destroy$.next();
        this.destroy$.complete();
    }
    // ================================================================
    // Mode switching
    // ================================================================
    SelectMode(mode) {
        if (this.ActiveMode === mode) {
            return;
        }
        this.ActiveMode = mode;
        this.CloseDrilldown();
        this.persistModePreference();
        this.emitAgentContext();
        this.cdr.detectChanges();
    }
    IsActiveMode(mode) {
        return this.ActiveMode === mode;
    }
    TrackByMode(_index, mode) {
        return mode.ID;
    }
    // ================================================================
    // Drilldown — shared by both modes
    // ================================================================
    /** Cluster mode: open the underlying entity record directly. */
    OnClusterOpenRecord(request) {
        this.openEntityRecord(request.EntityName, request.RecordID);
    }
    /** Tag-cloud mode: list the records carrying the clicked tag in the drilldown. */
    async OnTagSelected(selection) {
        this.DrilldownVisible = true;
        this.DrilldownLoading = true;
        this.DrilldownIcon = 'fa-solid fa-tag';
        this.DrilldownTitle = selection.Tag;
        this.DrilldownSubtitle = `${selection.Count} tagged ${selection.Count === 1 ? 'record' : 'records'}`;
        this.DrilldownRecords = [];
        this.cdr.detectChanges();
        this.emitAgentContext();
        try {
            this.DrilldownRecords = await this.loadRecordsForTag(selection.Tag, selection.Scope);
        }
        catch (error) {
            console.error('[Visualize] Error loading tag records:', error);
            this.DrilldownRecords = [];
        }
        finally {
            this.DrilldownLoading = false;
            this.emitAgentContext();
            this.cdr.detectChanges();
        }
    }
    /** Drilldown open-record intent (from the shared panel). */
    OnDrilldownOpenRecord(request) {
        this.openEntityRecord(request.EntityName, request.RecordID);
    }
    CloseDrilldown() {
        this.DrilldownVisible = false;
        this.DrilldownRecords = [];
        this.DrilldownLoading = false;
        this.emitAgentContext();
        this.cdr.detectChanges();
    }
    // ================================================================
    // Private helpers
    // ================================================================
    /**
     * Load the content-item records carrying a given tag, scoped to the same
     * content-source / content-type the cloud was built with. Each returned row
     * is a `MJ: Content Items` record the user can open.
     */
    async loadRecordsForTag(tag, scope) {
        const rv = RunView.FromMetadataProvider(this.ProviderToUse);
        const user = this.ProviderToUse.CurrentUser;
        // 1) Tag rows for this tag text → ItemID + Weight.
        const safeTag = tag.replace(/'/g, "''");
        const tagResult = await rv.RunView({
            EntityName: 'MJ: Content Item Tags',
            ExtraFilter: `Tag = '${safeTag}'`,
            Fields: ['ItemID', 'Item', 'Weight'],
            MaxRows: 200,
            ResultType: 'simple',
        }, user);
        if (!tagResult.Success || tagResult.Results.length === 0) {
            return [];
        }
        // De-dupe by ItemID, keep the highest weight seen.
        const byItem = new Map();
        for (const row of tagResult.Results) {
            const existing = byItem.get(row.ItemID);
            if (!existing || row.Weight > existing.weight) {
                byItem.set(row.ItemID, { item: row.Item, weight: row.Weight });
            }
        }
        const itemIDs = Array.from(byItem.keys());
        // 2) Resolve content-item details, narrowed by scope when present.
        const itemFilter = this.buildItemFilter(itemIDs, scope);
        const itemResult = await rv.RunView({
            EntityName: 'MJ: Content Items',
            ExtraFilter: itemFilter,
            Fields: ['ID', 'Name', 'ContentSource', 'ContentType'],
            MaxRows: 200,
            ResultType: 'simple',
        }, user);
        if (!itemResult.Success) {
            return [];
        }
        return itemResult.Results.map(item => {
            const tagged = byItem.get(item.ID);
            const subtitleParts = [item.ContentType, item.ContentSource].filter(p => !!p);
            return {
                EntityName: 'MJ: Content Items',
                RecordID: item.ID,
                Title: item.Name || tagged?.item || 'Untitled',
                Subtitle: subtitleParts.join(' · '),
                Weight: tagged?.weight,
            };
        }).sort((a, b) => (b.Weight ?? 0) - (a.Weight ?? 0));
    }
    /** Build the `MJ: Content Items` filter: ID IN (...) plus optional scope. */
    buildItemFilter(itemIDs, scope) {
        const fragments = [];
        if (itemIDs.length > 0) {
            const quoted = itemIDs.map(id => `'${id.replace(/'/g, "''")}'`).join(', ');
            fragments.push(`ID IN (${quoted})`);
        }
        if (scope.ContentSourceIDs && scope.ContentSourceIDs.length > 0) {
            const quoted = scope.ContentSourceIDs.map(id => `'${id.replace(/'/g, "''")}'`).join(', ');
            fragments.push(`ContentSourceID IN (${quoted})`);
        }
        if (scope.ContentTypeIDs && scope.ContentTypeIDs.length > 0) {
            const quoted = scope.ContentTypeIDs.map(id => `'${id.replace(/'/g, "''")}'`).join(', ');
            fragments.push(`ContentTypeID IN (${quoted})`);
        }
        return fragments.join(' AND ');
    }
    /** Open an entity record via NavigationService (single navigation path). */
    openEntityRecord(entityName, recordID) {
        if (!entityName || !recordID) {
            return;
        }
        const md = this.ProviderToUse;
        const entityInfo = md.EntityByName(entityName);
        const pkey = new CompositeKey();
        if (entityInfo) {
            pkey.LoadFromURLSegment(entityInfo, recordID);
        }
        else {
            pkey.KeyValuePairs = [{ FieldName: 'ID', Value: recordID }];
        }
        this.navigationService.OpenEntityRecord(entityName, pkey);
    }
    // ================================================================
    // Agent context + tools
    // ================================================================
    /**
     * Publish the host's state to the AI agent. Re-emitted whenever the mode
     * switches or the shared drilldown opens/loads/closes — so the streamed
     * context tracks what's on screen. Deepened to Data-Explorer depth: the
     * available modes plus the shared drilldown panel (open/loading state, what
     * it's showing, and the records it currently lists by id+title).
     */
    emitAgentContext() {
        this.navigationService.SetAgentContext(this, buildVisualizeAgentContext({
            ActiveMode: this.ActiveMode,
            AvailableModes: [...VISUALIZATION_MODES],
            DrilldownVisible: this.DrilldownVisible,
            DrilldownLoading: this.DrilldownLoading,
            DrilldownTitle: this.DrilldownTitle,
            DrilldownSubtitle: this.DrilldownSubtitle,
            DrilldownRecords: this.buildDrilldownSummaries(),
        }));
    }
    /** Map the loaded drilldown rows to bounded id+title+subtitle summaries for the agent. */
    buildDrilldownSummaries() {
        return this.DrilldownRecords.map(r => ({
            RecordID: r.RecordID,
            Title: r.Title,
            Subtitle: r.Subtitle ?? '',
        }));
    }
    /**
     * 🚨 SAFETY BOUNDARY (Knowledge Hub · Visualize host)
     * ------------------------------------------------------------------
     * The agent may SWITCH the visualization mode, OPEN a record currently
     * listed in the shared drilldown (by id or title), and CLOSE the
     * drilldown. All are read-only navigations / view-state changes.
     *
     * Nothing here mutates, deletes, or re-tags content. The embedded
     * Clusters child registers its OWN deep tools when it is the standalone
     * surface; here it is Embedded, so cluster recompute is reached through
     * the child's UI, not duplicated on the host. Tolerant handlers: every
     * Handler returns { Success, Data?, ErrorMessage? } and never throws;
     * drilldown references resolve id→title→contains.
     */
    registerAgentTools() {
        this.navigationService.SetAgentClientTools(this, [
            {
                Name: 'SwitchVisualizationMode',
                Description: 'Switch the Visualize surface mode (clusters or tagcloud)',
                ParameterSchema: {
                    type: 'object',
                    properties: { mode: { type: 'string', enum: [...VISUALIZATION_MODES] } },
                    required: ['mode'],
                },
                Handler: async (params) => {
                    const check = validateEnumParam(params['mode'], VISUALIZATION_MODES, 'mode');
                    if (!check.ok) {
                        return check.result;
                    }
                    this.SelectMode(check.value);
                    return { Success: true, Data: { ActiveMode: this.ActiveMode } };
                },
            },
            {
                Name: 'OpenDrilldownRecord',
                Description: 'Open one of the records currently listed in the shared drilldown panel, by record id or title. Only available while the drilldown is open.',
                ParameterSchema: {
                    type: 'object',
                    properties: { reference: { type: 'string', description: 'The record id or its on-screen title.' } },
                    required: ['reference'],
                },
                Handler: async (params) => {
                    const check = validateStringParam(params['reference'], 'reference');
                    if (!check.ok) {
                        return check.result;
                    }
                    if (!this.DrilldownVisible || this.DrilldownRecords.length === 0) {
                        return { Success: false, ErrorMessage: 'The drilldown panel is empty — select a tag or cluster point first.' };
                    }
                    const candidates = this.DrilldownRecords.map(r => ({ RecordID: r.RecordID, Title: r.Title }));
                    const match = resolveDrilldownRecord(check.value, candidates);
                    if (!match) {
                        const titles = capVisualizeList(candidates.map(c => c.Title));
                        return { Success: false, ErrorMessage: `No drilldown record matches "${check.value}". Listed records include: ${titles.join(', ')}.` };
                    }
                    const full = this.DrilldownRecords.find(r => r.RecordID === match.RecordID);
                    if (full) {
                        this.openEntityRecord(full.EntityName, full.RecordID);
                    }
                    return { Success: true, Data: { Title: match.Title } };
                },
            },
            {
                Name: 'CloseDrilldown',
                Description: 'Close the shared drilldown panel.',
                ParameterSchema: { type: 'object', properties: {} },
                Handler: async () => {
                    this.CloseDrilldown();
                    return { Success: true };
                },
            },
            {
                Name: 'ListDrilldownRecords',
                Description: 'List the records currently shown in the shared drilldown panel (bounded).',
                ParameterSchema: { type: 'object', properties: {} },
                Handler: async () => {
                    return {
                        Success: true,
                        Data: {
                            DrilldownVisible: this.DrilldownVisible,
                            DrilldownTitle: this.DrilldownTitle || null,
                            Records: capVisualizeList(this.buildDrilldownSummaries()),
                            TotalCount: this.DrilldownRecords.length,
                        },
                    };
                },
            },
        ]);
    }
    // ================================================================
    // Preferences (with legacy back-compat)
    // ================================================================
    persistModePreference() {
        UserInfoEngine.Instance.SetSettingDebounced(VisualizeResourceComponent_1.PREFS_KEY, this.ActiveMode);
    }
    loadModePreference() {
        // Prefer the new key; fall back to the legacy "Clusters" tab key.
        const raw = UserInfoEngine.Instance.GetSetting(VisualizeResourceComponent_1.PREFS_KEY)
            ?? UserInfoEngine.Instance.GetSetting(VisualizeResourceComponent_1.LEGACY_PREFS_KEY);
        if (raw === 'clusters' || raw === 'tagcloud') {
            this.ActiveMode = raw;
        }
    }
    static ɵfac = /*@__PURE__*/ (() => { let ɵVisualizeResourceComponent_BaseFactory; return function VisualizeResourceComponent_Factory(__ngFactoryType__) { return (ɵVisualizeResourceComponent_BaseFactory || (ɵVisualizeResourceComponent_BaseFactory = i0.ɵɵgetInheritedFactory(VisualizeResourceComponent)))(__ngFactoryType__ || VisualizeResourceComponent); }; })();
    static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: VisualizeResourceComponent, selectors: [["app-visualize-resource"]], viewQuery: function VisualizeResourceComponent_Query(rf, ctx) { if (rf & 1) {
            i0.ɵɵviewQuery(_c0, 5);
        } if (rf & 2) {
            let _t;
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.tagCloud = _t.first);
        } }, standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 12, vars: 9, consts: [["tagCloud", ""], ["Title", "Visualize", "Icon", "fa-solid fa-circle-nodes", "Subtitle", "Explore your knowledge base as clusters or a tag cloud"], ["toolbar", ""], ["role", "tablist", 1, "mode-switch"], ["type", "button", "role", "tab", 1, "mode-switch-btn", 3, "active"], [3, "Flex", "Padding"], [1, "visualize-container"], [1, "visualize-main"], [3, "Embedded"], [3, "Provider"], [3, "Closed", "OpenRecord", "Visible", "IsLoading", "Title", "Subtitle", "Icon", "Records"], ["type", "button", "role", "tab", 1, "mode-switch-btn", 3, "click"], [3, "OpenRecordRequested", "Embedded"], [3, "TagSelected", "Provider"]], template: function VisualizeResourceComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵelementStart(0, "mj-page-layout")(1, "mj-page-header", 1)(2, "div", 2)(3, "div", 3);
            i0.ɵɵrepeaterCreate(4, VisualizeResourceComponent_For_5_Template, 4, 6, "button", 4, ctx.TrackByMode, true);
            i0.ɵɵelementEnd()()();
            i0.ɵɵelementStart(6, "mj-page-body", 5)(7, "div", 6)(8, "div", 7);
            i0.ɵɵconditionalCreate(9, VisualizeResourceComponent_Conditional_9_Template, 1, 1, "app-cluster-visualization-resource", 8)(10, VisualizeResourceComponent_Conditional_10_Template, 2, 1, "app-kh-tag-cloud", 9);
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(11, "app-kh-record-drilldown", 10);
            i0.ɵɵlistener("Closed", function VisualizeResourceComponent_Template_app_kh_record_drilldown_Closed_11_listener() { return ctx.CloseDrilldown(); })("OpenRecord", function VisualizeResourceComponent_Template_app_kh_record_drilldown_OpenRecord_11_listener($event) { return ctx.OnDrilldownOpenRecord($event); });
            i0.ɵɵelementEnd()()()();
        } if (rf & 2) {
            i0.ɵɵadvance(4);
            i0.ɵɵrepeater(ctx.Modes);
            i0.ɵɵadvance(2);
            i0.ɵɵproperty("Flex", true)("Padding", false);
            i0.ɵɵadvance(3);
            i0.ɵɵconditional(ctx.IsActiveMode("clusters") ? 9 : 10);
            i0.ɵɵadvance(2);
            i0.ɵɵproperty("Visible", ctx.DrilldownVisible)("IsLoading", ctx.DrilldownLoading)("Title", ctx.DrilldownTitle)("Subtitle", ctx.DrilldownSubtitle)("Icon", ctx.DrilldownIcon)("Records", ctx.DrilldownRecords);
        } }, dependencies: [i1.MJPageHeaderComponent, i1.MJPageLayoutComponent, i1.MJPageBodyComponent, i2.ClusterVisualizationResourceComponent, i3.TagCloudComponent, i4.RecordDrilldownComponent], styles: ["[_nghost-%COMP%] {\n  display: block;\n  height: 100%;\n}\n\n\n\n.mode-switch[_ngcontent-%COMP%] {\n  display: inline-flex;\n  gap: 2px;\n  padding: 3px;\n  background: var(--mj-bg-surface-sunken);\n  border: 1px solid var(--mj-border-default);\n  border-radius: 8px;\n}\n\n.mode-switch-btn[_ngcontent-%COMP%] {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n  padding: 6px 14px;\n  border: none;\n  background: transparent;\n  color: var(--mj-text-secondary);\n  font-size: 13px;\n  font-weight: 600;\n  border-radius: 6px;\n  cursor: pointer;\n  transition: background 0.15s ease, color 0.15s ease;\n}\n\n.mode-switch-btn[_ngcontent-%COMP%]:hover {\n  color: var(--mj-text-primary);\n  background: var(--mj-bg-surface-hover);\n}\n\n.mode-switch-btn.active[_ngcontent-%COMP%] {\n  background: var(--mj-bg-surface);\n  color: var(--mj-brand-primary);\n  box-shadow: 0 1px 2px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n}\n\n\n\n.visualize-container[_ngcontent-%COMP%] {\n  display: flex;\n  height: 100%;\n  min-height: 0;\n  width: 100%;\n}\n\n.visualize-main[_ngcontent-%COMP%] {\n  flex: 1;\n  min-width: 0;\n  min-height: 0;\n  display: flex;\n  flex-direction: column;\n}\n\n.visualize-main[_ngcontent-%COMP%]    > app-cluster-visualization-resource[_ngcontent-%COMP%], \n.visualize-main[_ngcontent-%COMP%]    > app-kh-tag-cloud[_ngcontent-%COMP%] {\n  flex: 1;\n  min-height: 0;\n  display: block;\n}"] });
};
VisualizeResourceComponent = VisualizeResourceComponent_1 = __decorate([
    RegisterClass(BaseResourceComponent, 'VisualizationResource')
], VisualizeResourceComponent);
export { VisualizeResourceComponent };
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(VisualizeResourceComponent, [{
        type: Component,
        args: [{ standalone: false, selector: 'app-visualize-resource', template: "<mj-page-layout>\n  <mj-page-header\n    Title=\"Visualize\"\n    Icon=\"fa-solid fa-circle-nodes\"\n    Subtitle=\"Explore your knowledge base as clusters or a tag cloud\">\n    <div toolbar>\n      <div class=\"mode-switch\" role=\"tablist\">\n        @for (mode of Modes; track TrackByMode($index, mode)) {\n          <button\n            type=\"button\"\n            class=\"mode-switch-btn\"\n            role=\"tab\"\n            [class.active]=\"IsActiveMode(mode.ID)\"\n            [attr.aria-selected]=\"IsActiveMode(mode.ID)\"\n            (click)=\"SelectMode(mode.ID)\">\n            <i [class]=\"mode.Icon\"></i>\n            <span>{{ mode.Label }}</span>\n          </button>\n        }\n      </div>\n    </div>\n  </mj-page-header>\n\n  <mj-page-body [Flex]=\"true\" [Padding]=\"false\">\n    <div class=\"visualize-container\">\n      <div class=\"visualize-main\">\n        @if (IsActiveMode('clusters')) {\n          <app-cluster-visualization-resource\n            [Embedded]=\"true\"\n            (OpenRecordRequested)=\"OnClusterOpenRecord($event)\">\n          </app-cluster-visualization-resource>\n        } @else {\n          <app-kh-tag-cloud\n            #tagCloud\n            [Provider]=\"Provider\"\n            (TagSelected)=\"OnTagSelected($event)\">\n          </app-kh-tag-cloud>\n        }\n      </div>\n\n      <app-kh-record-drilldown\n        [Visible]=\"DrilldownVisible\"\n        [IsLoading]=\"DrilldownLoading\"\n        [Title]=\"DrilldownTitle\"\n        [Subtitle]=\"DrilldownSubtitle\"\n        [Icon]=\"DrilldownIcon\"\n        [Records]=\"DrilldownRecords\"\n        (Closed)=\"CloseDrilldown()\"\n        (OpenRecord)=\"OnDrilldownOpenRecord($event)\">\n      </app-kh-record-drilldown>\n    </div>\n  </mj-page-body>\n</mj-page-layout>\n", styles: [":host {\n  display: block;\n  height: 100%;\n}\n\n/* Segmented mode switch in the header toolbar */\n.mode-switch {\n  display: inline-flex;\n  gap: 2px;\n  padding: 3px;\n  background: var(--mj-bg-surface-sunken);\n  border: 1px solid var(--mj-border-default);\n  border-radius: 8px;\n}\n\n.mode-switch-btn {\n  display: inline-flex;\n  align-items: center;\n  gap: 6px;\n  padding: 6px 14px;\n  border: none;\n  background: transparent;\n  color: var(--mj-text-secondary);\n  font-size: 13px;\n  font-weight: 600;\n  border-radius: 6px;\n  cursor: pointer;\n  transition: background 0.15s ease, color 0.15s ease;\n}\n\n.mode-switch-btn:hover {\n  color: var(--mj-text-primary);\n  background: var(--mj-bg-surface-hover);\n}\n\n.mode-switch-btn.active {\n  background: var(--mj-bg-surface);\n  color: var(--mj-brand-primary);\n  box-shadow: 0 1px 2px color-mix(in srgb, var(--mj-text-primary) 12%, transparent);\n}\n\n/* Body layout: main visualization + drilldown side panel */\n.visualize-container {\n  display: flex;\n  height: 100%;\n  min-height: 0;\n  width: 100%;\n}\n\n.visualize-main {\n  flex: 1;\n  min-width: 0;\n  min-height: 0;\n  display: flex;\n  flex-direction: column;\n}\n\n.visualize-main > app-cluster-visualization-resource,\n.visualize-main > app-kh-tag-cloud {\n  flex: 1;\n  min-height: 0;\n  display: block;\n}\n"] }]
    }], null, { tagCloud: [{
            type: ViewChild,
            args: ['tagCloud']
        }] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(VisualizeResourceComponent, { className: "VisualizeResourceComponent", filePath: "src/KnowledgeHub/components/visualize/visualize-resource.component.ts", lineNumber: 53 }); })();
/** Tree-shaking prevention */
export function LoadVisualizeResource() {
    // Prevents tree-shaking of the component
}
//# sourceMappingURL=visualize-resource.component.js.map