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;
};
/**
 * @fileoverview Knowledge Hub — Feature Pipelines dashboard tab.
 *
 * Full-page resource component listing the **Feature Pipelines** (Predictive
 * Studio SP6 / `plans/predictive-studio.md` §5.4). A Feature Pipeline has no
 * dedicated entity: it IS an `MJ: Record Processes` row categorized into the
 * seeded "Feature Pipeline" category (Infer / Action / Agent + a write-back
 * `OutputMapping`). This surface makes them first-class + discoverable +
 * monitorable inside Knowledge Hub:
 *
 *   - lists the feature-pipeline Record Processes (from {@link FeaturePipelineEngine}),
 *   - shows each one's target entity, written attribute, and last-run / freshness,
 *   - offers **Run** (invokes the existing `PredictiveStudio.RunFeaturePipeline`
 *     Remote Operation via the provider's `RouteOperation` seam — the same
 *     hardened Record Set Processing run path), and
 *   - an **authoring** entry that opens the reusable `mj-record-process-editor`
 *     (from `@memberjunction/ng-record-process-studio`) in a dialog — we do NOT
 *     rebuild the authoring surface.
 *
 * Registered as `BaseResourceComponent` driver `FeaturePipelinesResource`; wired
 * into the Knowledge Hub application's nav via metadata (`DriverClass`).
 */
import { Component, ChangeDetectorRef, inject, } from '@angular/core';
import { Subject, takeUntil } from 'rxjs';
import { RegisterClass } from '@memberjunction/global';
import { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';
import { MJNotificationService } from '@memberjunction/ng-notifications';
import { FeaturePipelineEngine, } from './feature-pipeline.engine';
import { buildFeaturePipelinesAgentContext, resolvePipeline, buildPipelineNotFoundError, } from './feature-pipelines-agent-context';
import { validateStringParam } from '../../../shared/agent-tool-validation';
import * as i0 from "@angular/core";
import * as i1 from "@memberjunction/ng-shared-generic";
import * as i2 from "@memberjunction/ng-ui-components";
import * as i3 from "@memberjunction/ng-record-process-studio";
const _forTrack0 = ($index, $item) => $item.ID;
function FeaturePipelinesResourceComponent_Conditional_3_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-stat-badge", 2);
} if (rf & 2) {
    const ctx_r0 = i0.ɵɵnextContext();
    i0.ɵɵproperty("Count", ctx_r0.FailedCount);
} }
function FeaturePipelinesResourceComponent_Conditional_4_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-stat-badge", 3);
} if (rf & 2) {
    const ctx_r0 = i0.ɵɵnextContext();
    i0.ɵɵproperty("Count", ctx_r0.FilteredPipelines.length)("Total", ctx_r0.AllPipelines.length);
} }
function FeaturePipelinesResourceComponent_Conditional_13_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 11);
    i0.ɵɵelement(1, "mj-loading", 16);
    i0.ɵɵelementEnd();
} }
function FeaturePipelinesResourceComponent_Conditional_14_Template(rf, ctx) { if (rf & 1) {
    const _r2 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "mj-empty-state", 17);
    i0.ɵɵlistener("Action", function FeaturePipelinesResourceComponent_Conditional_14_Template_mj_empty_state_Action_0_listener() { i0.ɵɵrestoreView(_r2); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnNewPipeline()); });
    i0.ɵɵelementEnd();
} }
function FeaturePipelinesResourceComponent_Conditional_15_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "mj-empty-state", 13);
} }
function FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_10_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "p", 26);
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const pipeline_r4 = i0.ɵɵnextContext().$implicit;
    i0.ɵɵproperty("title", pipeline_r4.Description);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(pipeline_r4.Description);
} }
function FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_30_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "span", 34);
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const pipeline_r4 = i0.ɵɵnextContext().$implicit;
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate2("\u00B7 ", pipeline_r4.LastRunSuccess, "/", pipeline_r4.LastRunProcessed, " written");
} }
function FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_33_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "i", 39);
    i0.ɵɵtext(1, " Running\u2026 ");
} }
function FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_34_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "i", 40);
    i0.ɵɵtext(1, " Run ");
} }
function FeaturePipelinesResourceComponent_Conditional_16_For_2_Template(rf, ctx) { if (rf & 1) {
    const _r3 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "div", 19)(1, "div", 20);
    i0.ɵɵelement(2, "i", 21);
    i0.ɵɵelementStart(3, "div", 22)(4, "h3", 23);
    i0.ɵɵtext(5);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(6, "span", 24);
    i0.ɵɵtext(7);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(8, "span", 25);
    i0.ɵɵtext(9);
    i0.ɵɵelementEnd()();
    i0.ɵɵconditionalCreate(10, FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_10_Template, 2, 2, "p", 26);
    i0.ɵɵelementStart(11, "div", 27)(12, "div", 28)(13, "span", 29);
    i0.ɵɵelement(14, "i", 30);
    i0.ɵɵtext(15, " Target");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(16, "span", 31);
    i0.ɵɵtext(17);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(18, "div", 28)(19, "span", 29);
    i0.ɵɵelement(20, "i", 32);
    i0.ɵɵtext(21, " Writes");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(22, "span", 31);
    i0.ɵɵtext(23);
    i0.ɵɵelementEnd()();
    i0.ɵɵelementStart(24, "div", 28)(25, "span", 29);
    i0.ɵɵelement(26, "i", 33);
    i0.ɵɵtext(27, " Last run");
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(28, "span", 31);
    i0.ɵɵtext(29);
    i0.ɵɵconditionalCreate(30, FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_30_Template, 2, 2, "span", 34);
    i0.ɵɵelementEnd()()();
    i0.ɵɵelementStart(31, "div", 35)(32, "button", 36);
    i0.ɵɵlistener("click", function FeaturePipelinesResourceComponent_Conditional_16_For_2_Template_button_click_32_listener() { const pipeline_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnRunPipeline(pipeline_r4)); });
    i0.ɵɵconditionalCreate(33, FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_33_Template, 2, 0)(34, FeaturePipelinesResourceComponent_Conditional_16_For_2_Conditional_34_Template, 2, 0);
    i0.ɵɵelementEnd();
    i0.ɵɵelementStart(35, "button", 37);
    i0.ɵɵlistener("click", function FeaturePipelinesResourceComponent_Conditional_16_For_2_Template_button_click_35_listener() { const pipeline_r4 = i0.ɵɵrestoreView(_r3).$implicit; const ctx_r0 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r0.OnEditPipeline(pipeline_r4)); });
    i0.ɵɵelement(36, "i", 38);
    i0.ɵɵtext(37, " Edit ");
    i0.ɵɵelementEnd()()();
} if (rf & 2) {
    const pipeline_r4 = ctx.$implicit;
    const ctx_r0 = i0.ɵɵnextContext(2);
    i0.ɵɵclassProp("fp-card--disabled", pipeline_r4.Status !== "Active");
    i0.ɵɵadvance(2);
    i0.ɵɵclassMap(ctx_r0.WorkTypeIcon(pipeline_r4.WorkType));
    i0.ɵɵadvance(2);
    i0.ɵɵproperty("title", pipeline_r4.Name);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(pipeline_r4.Name);
    i0.ɵɵadvance(2);
    i0.ɵɵtextInterpolate(pipeline_r4.WorkType);
    i0.ɵɵadvance();
    i0.ɵɵclassMap(ctx_r0.RunStatusClass(pipeline_r4.LastRunStatus));
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate1(" ", ctx_r0.RunStatusLabel(pipeline_r4.LastRunStatus), " ");
    i0.ɵɵadvance();
    i0.ɵɵconditional(pipeline_r4.Description ? 10 : -1);
    i0.ɵɵadvance(7);
    i0.ɵɵtextInterpolate(pipeline_r4.TargetEntity);
    i0.ɵɵadvance(6);
    i0.ɵɵtextInterpolate(pipeline_r4.OutputAttribute || "\u2014");
    i0.ɵɵadvance(6);
    i0.ɵɵtextInterpolate1(" ", ctx_r0.TimeAgo(pipeline_r4.LastRunAt), " ");
    i0.ɵɵadvance();
    i0.ɵɵconditional(pipeline_r4.LastRunProcessed != null ? 30 : -1);
    i0.ɵɵadvance(2);
    i0.ɵɵproperty("disabled", !pipeline_r4.OnDemandEnabled || pipeline_r4.Status !== "Active" || ctx_r0.IsRunning(pipeline_r4.ID));
    i0.ɵɵadvance();
    i0.ɵɵconditional(ctx_r0.IsRunning(pipeline_r4.ID) ? 33 : 34);
} }
function FeaturePipelinesResourceComponent_Conditional_16_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 14);
    i0.ɵɵrepeaterCreate(1, FeaturePipelinesResourceComponent_Conditional_16_For_2_Template, 38, 17, "div", 18, _forTrack0);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r0 = i0.ɵɵnextContext();
    i0.ɵɵadvance();
    i0.ɵɵrepeater(ctx_r0.FilteredPipelines);
} }
function FeaturePipelinesResourceComponent_Conditional_17_Template(rf, ctx) { if (rf & 1) {
    const _r5 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "mj-dialog", 41);
    i0.ɵɵlistener("Close", function FeaturePipelinesResourceComponent_Conditional_17_Template_mj_dialog_Close_0_listener() { i0.ɵɵrestoreView(_r5); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnEditorCancelled()); });
    i0.ɵɵelementStart(1, "mj-record-process-editor", 42);
    i0.ɵɵlistener("Saved", function FeaturePipelinesResourceComponent_Conditional_17_Template_mj_record_process_editor_Saved_1_listener($event) { i0.ɵɵrestoreView(_r5); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnEditorSaved($event)); })("Cancelled", function FeaturePipelinesResourceComponent_Conditional_17_Template_mj_record_process_editor_Cancelled_1_listener() { i0.ɵɵrestoreView(_r5); const ctx_r0 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r0.OnEditorCancelled()); });
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const ctx_r0 = i0.ɵɵnextContext();
    i0.ɵɵproperty("Visible", ctx_r0.ShowEditor)("Width", 900);
    i0.ɵɵadvance();
    i0.ɵɵproperty("RecordProcessID", ctx_r0.EditingPipelineID);
} }
/** Stable operation key of the Run Feature Pipeline Remote Operation. */
const RUN_FEATURE_PIPELINE_OP = 'PredictiveStudio.RunFeaturePipeline';
let FeaturePipelinesResourceComponent = class FeaturePipelinesResourceComponent extends BaseResourceComponent {
    cdr = inject(ChangeDetectorRef);
    navigationService = inject(NavigationService);
    destroy$ = new Subject();
    // ================================================================
    // Resource overrides
    // ================================================================
    async GetResourceDisplayName(_data) {
        return 'Feature Pipelines';
    }
    async GetResourceIconClass(_data) {
        return 'fa-solid fa-diagram-project';
    }
    // ================================================================
    // State
    // ================================================================
    /** True while the engine is loading its caches. */
    IsLoading = true;
    /** All feature-pipeline summaries (unfiltered). */
    AllPipelines = [];
    /** Pipelines after the search filter is applied (what the cards render). */
    FilteredPipelines = [];
    /** Free-text search over name / target entity / output attribute. */
    SearchQuery = '';
    /** Ids of pipelines with a Run currently in flight (disables their Run button). */
    RunningIDs = new Set();
    /** Authoring dialog state. */
    ShowEditor = false;
    /** Record Process id being authored, or null for a new draft. */
    EditingPipelineID = null;
    // ================================================================
    // Computed
    // ================================================================
    /** Count of pipelines whose underlying Record Process is Active. */
    get ActiveCount() {
        return this.AllPipelines.filter((p) => p.Status === 'Active').length;
    }
    /** Count of pipelines that have never run. */
    get NeverRunCount() {
        return this.AllPipelines.filter((p) => p.LastRunStatus === 'Never').length;
    }
    /** Count of pipelines whose most recent run failed. */
    get FailedCount() {
        return this.AllPipelines.filter((p) => p.LastRunStatus === 'Failed').length;
    }
    // ================================================================
    // Lifecycle
    // ================================================================
    async ngAfterViewInit() {
        await this.loadData();
        this.subscribeToEngine();
        this.emitAgentContext();
        this.registerAgentTools();
        this.NotifyLoadComplete();
    }
    ngOnDestroy() {
        super.ngOnDestroy();
        this.destroy$.next();
        this.destroy$.complete();
    }
    // ================================================================
    // Public Methods — Toolbar
    // ================================================================
    /** Reload the engine caches from the server. */
    async Refresh() {
        await this.loadData(true);
    }
    /** Apply the search filter (called on every keystroke). */
    OnSearchChanged() {
        this.applyFilter();
        this.emitAgentContext();
        this.cdr.detectChanges();
    }
    /** Open the authoring editor for a brand-new feature pipeline draft. */
    OnNewPipeline() {
        this.EditingPipelineID = null;
        this.ShowEditor = true;
        this.cdr.detectChanges();
    }
    // ================================================================
    // Public Methods — Card Actions
    // ================================================================
    /** Open the authoring editor for an existing feature pipeline. */
    OnEditPipeline(pipeline) {
        this.EditingPipelineID = pipeline.ID;
        this.ShowEditor = true;
        this.cdr.detectChanges();
    }
    /**
     * Run a feature pipeline on demand by invoking the
     * `PredictiveStudio.RunFeaturePipeline` Remote Operation through the active
     * provider. The op delegates to the Record Set Processing substrate — the same
     * batching/resume/audit path the rest of the platform uses.
     */
    async OnRunPipeline(pipeline) {
        if (this.RunningIDs.has(pipeline.ID))
            return;
        this.RunningIDs.add(pipeline.ID);
        this.cdr.detectChanges();
        try {
            const input = { featurePipelineID: pipeline.ID };
            // RouteOperation lives on IRemoteOperationProvider, which every concrete
            // provider (the browser's GraphQLDataProvider here) implements via ProviderBase.
            // The narrowing cast is the documented "power-tool seam" entry point.
            const opProvider = this.ProviderToUse;
            const result = await opProvider.RouteOperation(RUN_FEATURE_PIPELINE_OP, input, { provider: this.ProviderToUse });
            this.notifyRunResult(pipeline, result);
        }
        catch (error) {
            MJNotificationService.Instance.CreateSimpleNotification(`Failed to run "${pipeline.Name}": ${error instanceof Error ? error.message : String(error)}`, 'error', 5000);
        }
        finally {
            this.RunningIDs.delete(pipeline.ID);
            // Refresh so the card reflects the new run / freshness.
            await this.loadData(true);
        }
    }
    /** Whether a given pipeline currently has a Run in flight. */
    IsRunning(pipelineID) {
        return this.RunningIDs.has(pipelineID);
    }
    // ================================================================
    // Public Methods — Authoring Dialog
    // ================================================================
    /** Called when the editor saves — refresh and close. */
    async OnEditorSaved(_record) {
        this.ShowEditor = false;
        this.EditingPipelineID = null;
        await this.loadData(true);
    }
    /** Called when the editor is cancelled — just close. */
    OnEditorCancelled() {
        this.ShowEditor = false;
        this.EditingPipelineID = null;
        this.cdr.detectChanges();
    }
    // ================================================================
    // Public Methods — Display Helpers
    // ================================================================
    /** Font Awesome icon for a pipeline's work type. */
    WorkTypeIcon(workType) {
        switch (workType) {
            case 'Infer':
                return 'fa-solid fa-wand-magic-sparkles';
            case 'Agent':
                return 'fa-solid fa-robot';
            case 'Action':
                return 'fa-solid fa-bolt';
            case 'FieldRules':
                return 'fa-solid fa-list-check';
            case 'ML Model':
                return 'fa-solid fa-brain';
            default:
                // Keeps the function total against future CodeGen-added work types.
                return 'fa-solid fa-gear';
        }
    }
    /** CSS modifier class for a run-status pill. */
    RunStatusClass(status) {
        return `status--${status.toLowerCase()}`;
    }
    /** Human-readable label for a run status. */
    RunStatusLabel(status) {
        return status === 'Never' ? 'Never run' : status;
    }
    /** Relative "x ago" string for the last-run timestamp. */
    TimeAgo(date) {
        if (!date)
            return 'Never';
        const diffMs = Date.now() - new Date(date).getTime();
        const minutes = Math.floor(diffMs / 60000);
        const hours = Math.floor(minutes / 60);
        const days = Math.floor(hours / 24);
        if (days > 0)
            return `${days}d ago`;
        if (hours > 0)
            return `${hours}h ago`;
        if (minutes > 0)
            return `${minutes}m ago`;
        return 'Just now';
    }
    // ================================================================
    // Private Methods
    // ================================================================
    /** The engine instance scoped to the active provider (multi-provider safe). */
    get engine() {
        return (FeaturePipelineEngine.GetProviderInstance(this.ProviderToUse, FeaturePipelineEngine));
    }
    async loadData(forceRefresh = false) {
        this.IsLoading = true;
        this.cdr.detectChanges();
        try {
            const p = this.ProviderToUse;
            await this.engine.Config(forceRefresh, p.CurrentUser, p);
            this.AllPipelines = this.engine.GetSummaries();
            this.applyFilter();
        }
        catch (error) {
            console.error('[FeaturePipelinesResource] Error loading data:', error);
            this.AllPipelines = [];
            this.FilteredPipelines = [];
        }
        finally {
            this.IsLoading = false;
            this.cdr.detectChanges();
        }
    }
    /**
     * Re-derive the summaries whenever the engine's cached Record Processes or
     * Process Runs change (save / delete / remote-invalidate elsewhere) — reactivity
     * for free from the BaseEngine streams.
     */
    subscribeToEngine() {
        this.engine.Pipelines$.pipe(takeUntil(this.destroy$)).subscribe(() => {
            this.AllPipelines = this.engine.GetSummaries();
            this.applyFilter();
            this.emitAgentContext();
            this.cdr.detectChanges();
        });
    }
    applyFilter() {
        const q = this.SearchQuery.trim().toLowerCase();
        if (!q) {
            this.FilteredPipelines = this.AllPipelines;
            return;
        }
        this.FilteredPipelines = this.AllPipelines.filter((p) => p.Name.toLowerCase().includes(q) ||
            p.TargetEntity.toLowerCase().includes(q) ||
            (p.OutputAttribute ?? '').toLowerCase().includes(q));
    }
    notifyRunResult(pipeline, result) {
        if (result.Success && result.Output) {
            const out = result.Output;
            MJNotificationService.Instance.CreateSimpleNotification(`"${pipeline.Name}" finished: ${out.written} written, ${out.processed} processed, ${out.error} error(s).`, out.error > 0 ? 'warning' : 'success', 5000);
        }
        else {
            MJNotificationService.Instance.CreateSimpleNotification(`"${pipeline.Name}" did not complete: ${result.ErrorMessage ?? 'unknown error'}`, 'error', 5000);
        }
    }
    // ---- Agent context + client tools (required for every dashboard) ----
    //
    // 🔒 SAFETY BOUNDARY (Feature Pipelines surface)
    // ----------------------------------------------
    // EXPOSED to the agent: idempotent refresh, read-only search/filter, selection,
    // opening a pipeline's authoring editor (UI — no auto-save), and the existing
    // on-demand RUN (RunFeaturePipeline). Running a feature pipeline is intentionally
    // exposed: it is an idempotent, hardened Record-Set-Processing pass that derives
    // and writes feature values back via the pipeline's own OutputMapping — the same
    // run path the platform uses everywhere, with no agent-supplied parameters.
    //
    // NEVER EXPOSED: there is no agent tool that saves/deletes a pipeline definition
    // or its OutputMapping (authoring is a deliberate UI action via the editor
    // dialog). The agent may *open* the editor, never commit it.
    emitAgentContext() {
        this.navigationService.SetAgentContext(this, buildFeaturePipelinesAgentContext({
            AllPipelines: this.AllPipelines,
            FilteredPipelines: this.FilteredPipelines,
            SearchQuery: this.SearchQuery,
            RunningIDs: this.RunningIDs,
            IsLoading: this.IsLoading,
        }));
    }
    /** Resolve a pipeline reference (id/name/contains) or return a tolerant failure. */
    resolvePipelineOrFail(raw) {
        const v = validateStringParam(raw, 'pipeline');
        if (!v.ok)
            return { ok: false, result: v.result };
        const match = resolvePipeline(v.value, this.AllPipelines);
        if (!match) {
            return {
                ok: false,
                result: {
                    Success: false,
                    ErrorMessage: buildPipelineNotFoundError(v.value, this.AllPipelines.map((p) => p.Name)),
                },
            };
        }
        return { ok: true, pipeline: match };
    }
    registerAgentTools() {
        this.navigationService.SetAgentClientTools(this, [
            {
                Name: 'RunFeaturePipeline',
                Description: 'Run a Feature Pipeline on demand by its id or name. Derives + persists feature values back to the target entity via the pipeline OutputMapping (idempotent Record-Set-Processing pass; no agent-supplied parameters).',
                ParameterSchema: {
                    type: 'object',
                    properties: { pipeline: { type: 'string', description: 'The feature pipeline id or name' } },
                    required: ['pipeline'],
                },
                Handler: async (params) => {
                    const r = this.resolvePipelineOrFail(params['pipeline'] ?? params['name']);
                    if (!r.ok)
                        return r.result;
                    if (!r.pipeline.OnDemandEnabled) {
                        return { Success: false, ErrorMessage: `"${r.pipeline.Name}" is not enabled for on-demand runs.` };
                    }
                    await this.OnRunPipeline(r.pipeline);
                    return { Success: true, Data: { Pipeline: r.pipeline.Name } };
                },
            },
            {
                Name: 'SearchFeaturePipelines',
                Description: 'Filter the feature pipeline list by a search term (name / target entity / attribute). Pass empty to clear. Read-only.',
                ParameterSchema: {
                    type: 'object',
                    properties: { query: { type: 'string' } },
                    required: ['query'],
                },
                Handler: async (params) => {
                    const v = validateStringParam(params['query'], 'query');
                    if (!v.ok)
                        return v.result;
                    this.SearchQuery = v.value;
                    this.OnSearchChanged();
                    return { Success: true, Data: { FilteredCount: this.FilteredPipelines.length } };
                },
            },
            {
                Name: 'RefreshFeaturePipelines',
                Description: 'Reload the feature pipelines and their latest run/freshness from the server. Idempotent.',
                ParameterSchema: { type: 'object', properties: {} },
                Handler: async () => {
                    await this.Refresh();
                    this.emitAgentContext();
                    return { Success: true, Data: { PipelineCount: this.AllPipelines.length } };
                },
            },
            {
                Name: 'OpenFeaturePipelineEditor',
                Description: 'Open the authoring editor for a feature pipeline by id or name (UI dialog — does NOT auto-save). Use to inspect or edit a pipeline definition.',
                ParameterSchema: {
                    type: 'object',
                    properties: { pipeline: { type: 'string', description: 'The feature pipeline id or name' } },
                    required: ['pipeline'],
                },
                Handler: async (params) => {
                    const r = this.resolvePipelineOrFail(params['pipeline'] ?? params['name']);
                    if (!r.ok)
                        return r.result;
                    this.OnEditPipeline(r.pipeline);
                    return { Success: true, Data: { Pipeline: r.pipeline.Name } };
                },
            },
        ]);
    }
    static ɵfac = /*@__PURE__*/ (() => { let ɵFeaturePipelinesResourceComponent_BaseFactory; return function FeaturePipelinesResourceComponent_Factory(__ngFactoryType__) { return (ɵFeaturePipelinesResourceComponent_BaseFactory || (ɵFeaturePipelinesResourceComponent_BaseFactory = i0.ɵɵgetInheritedFactory(FeaturePipelinesResourceComponent)))(__ngFactoryType__ || FeaturePipelinesResourceComponent); }; })();
    static ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: FeaturePipelinesResourceComponent, selectors: [["app-feature-pipelines-resource"]], standalone: false, features: [i0.ɵɵInheritDefinitionFeature], decls: 18, vars: 6, consts: [["Title", "Feature Pipelines", "Icon", "fa-solid fa-diagram-project", "Subtitle", "Derive feature attributes from your data and persist them back to entities"], ["meta", ""], ["Label", "last run failed", "Variant", "error", 3, "Count"], ["Label", "pipelines", 3, "Count", "Total"], ["actions", ""], [3, "Clicked", "Loading"], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click"], [1, "fa-solid", "fa-plus"], ["toolbar", ""], ["Placeholder", "Search by name, entity, or attribute\u2026", 3, "ValueChange", "Value"], [3, "Flex"], [1, "fp-loading"], ["Icon", "fa-solid fa-diagram-project", "Title", "No feature pipelines yet", "Message", "A Feature Pipeline derives an attribute per record (e.g. an LLM summary or score) and writes it back to your data \u2014 reusable analytics, independent of any model.", "ActionText", "New Pipeline", "ActionIcon", "fa-solid fa-plus"], ["Variant", "no-results", "Icon", "fa-solid fa-magnifying-glass", "Title", "No matching pipelines", "Message", "No feature pipelines match your search."], [1, "fp-grid"], ["Title", "Feature Pipeline", 3, "Visible", "Width"], ["text", "Loading feature pipelines\u2026", "size", "medium"], ["Icon", "fa-solid fa-diagram-project", "Title", "No feature pipelines yet", "Message", "A Feature Pipeline derives an attribute per record (e.g. an LLM summary or score) and writes it back to your data \u2014 reusable analytics, independent of any model.", "ActionText", "New Pipeline", "ActionIcon", "fa-solid fa-plus", 3, "Action"], [1, "fp-card", 3, "fp-card--disabled"], [1, "fp-card"], [1, "fp-card__head"], [1, "fp-card__icon"], [1, "fp-card__title"], [3, "title"], [1, "fp-card__worktype"], [1, "fp-status"], [1, "fp-card__desc", 3, "title"], [1, "fp-card__meta"], [1, "fp-meta-row"], [1, "fp-meta-row__k"], [1, "fa-solid", "fa-table"], [1, "fp-meta-row__v"], [1, "fa-solid", "fa-pen-to-square"], [1, "fa-solid", "fa-clock-rotate-left"], [1, "fp-meta-row__sub"], [1, "fp-card__actions"], ["mjButton", "", "variant", "primary", "size", "sm", 3, "click", "disabled"], ["mjButton", "", "variant", "secondary", "size", "sm", 3, "click"], [1, "fa-solid", "fa-sliders"], [1, "fa-solid", "fa-spinner", "fa-spin"], [1, "fa-solid", "fa-play"], ["Title", "Feature Pipeline", 3, "Close", "Visible", "Width"], [3, "Saved", "Cancelled", "RecordProcessID"]], template: function FeaturePipelinesResourceComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵelementStart(0, "mj-page-layout")(1, "mj-page-header", 0)(2, "div", 1);
            i0.ɵɵconditionalCreate(3, FeaturePipelinesResourceComponent_Conditional_3_Template, 1, 1, "mj-stat-badge", 2)(4, FeaturePipelinesResourceComponent_Conditional_4_Template, 1, 2, "mj-stat-badge", 3);
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(5, "div", 4)(6, "mj-refresh-button", 5);
            i0.ɵɵlistener("Clicked", function FeaturePipelinesResourceComponent_Template_mj_refresh_button_Clicked_6_listener() { return ctx.Refresh(); });
            i0.ɵɵelementEnd();
            i0.ɵɵelementStart(7, "button", 6);
            i0.ɵɵlistener("click", function FeaturePipelinesResourceComponent_Template_button_click_7_listener() { return ctx.OnNewPipeline(); });
            i0.ɵɵelement(8, "i", 7);
            i0.ɵɵtext(9, " New Pipeline ");
            i0.ɵɵelementEnd()();
            i0.ɵɵelementStart(10, "div", 8)(11, "mj-page-search", 9);
            i0.ɵɵlistener("ValueChange", function FeaturePipelinesResourceComponent_Template_mj_page_search_ValueChange_11_listener($event) { ctx.SearchQuery = $event; return ctx.OnSearchChanged(); });
            i0.ɵɵelementEnd()()();
            i0.ɵɵelementStart(12, "mj-page-body", 10);
            i0.ɵɵconditionalCreate(13, FeaturePipelinesResourceComponent_Conditional_13_Template, 2, 0, "div", 11)(14, FeaturePipelinesResourceComponent_Conditional_14_Template, 1, 0, "mj-empty-state", 12)(15, FeaturePipelinesResourceComponent_Conditional_15_Template, 1, 0, "mj-empty-state", 13)(16, FeaturePipelinesResourceComponent_Conditional_16_Template, 3, 0, "div", 14);
            i0.ɵɵelementEnd()();
            i0.ɵɵconditionalCreate(17, FeaturePipelinesResourceComponent_Conditional_17_Template, 2, 3, "mj-dialog", 15);
        } if (rf & 2) {
            i0.ɵɵadvance(3);
            i0.ɵɵconditional(ctx.FailedCount > 0 ? 3 : 4);
            i0.ɵɵadvance(3);
            i0.ɵɵproperty("Loading", ctx.IsLoading);
            i0.ɵɵadvance(5);
            i0.ɵɵproperty("Value", ctx.SearchQuery);
            i0.ɵɵadvance();
            i0.ɵɵproperty("Flex", true);
            i0.ɵɵadvance();
            i0.ɵɵconditional(ctx.IsLoading ? 13 : ctx.AllPipelines.length === 0 ? 14 : ctx.FilteredPipelines.length === 0 ? 15 : 16);
            i0.ɵɵadvance(4);
            i0.ɵɵconditional(ctx.ShowEditor ? 17 : -1);
        } }, dependencies: [i1.LoadingComponent, i2.MJButtonDirective, i2.MJPageHeaderComponent, i2.MJPageLayoutComponent, i2.MJPageBodyComponent, i2.MJPageSearchComponent, i2.MJStatBadgeComponent, i2.MJRefreshButtonComponent, i2.MJDialogComponent, i2.MJEmptyStateComponent, i3.RecordProcessEditorComponent], styles: ["\n\n\n\n\n\n.fp-loading[_ngcontent-%COMP%] {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  min-height: 240px;\n  width: 100%;\n}\n\n.fp-grid[_ngcontent-%COMP%] {\n  display: grid;\n  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));\n  gap: 16px;\n  padding: 4px;\n  align-content: start;\n}\n\n.fp-card[_ngcontent-%COMP%] {\n  display: flex;\n  flex-direction: column;\n  gap: 12px;\n  padding: 16px;\n  border: 1px solid var(--mj-border-default);\n  border-radius: var(--mj-radius-lg, 10px);\n  background: var(--mj-bg-surface-card);\n  transition: border-color 0.15s ease, box-shadow 0.15s ease;\n\n  &:hover {\n    border-color: var(--mj-border-strong);\n    box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n  }\n\n  &--disabled {\n    opacity: 0.65;\n  }\n}\n\n.fp-card__head[_ngcontent-%COMP%] {\n  display: flex;\n  align-items: flex-start;\n  gap: 12px;\n}\n\n.fp-card__icon[_ngcontent-%COMP%] {\n  flex: 0 0 auto;\n  width: 36px;\n  height: 36px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--mj-radius-md, 8px);\n  background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n  color: var(--mj-brand-primary);\n  font-size: 16px;\n}\n\n.fp-card__title[_ngcontent-%COMP%] {\n  flex: 1 1 auto;\n  min-width: 0;\n\n  h3 {\n    margin: 0;\n    font-size: 15px;\n    font-weight: 600;\n    color: var(--mj-text-primary);\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n}\n\n.fp-card__worktype[_ngcontent-%COMP%] {\n  font-size: 11px;\n  font-weight: 600;\n  text-transform: uppercase;\n  letter-spacing: 0.04em;\n  color: var(--mj-text-muted);\n}\n\n.fp-card__desc[_ngcontent-%COMP%] {\n  margin: 0;\n  font-size: 13px;\n  line-height: 1.4;\n  color: var(--mj-text-secondary);\n  display: -webkit-box;\n  -webkit-line-clamp: 2;\n  line-clamp: 2;\n  -webkit-box-orient: vertical;\n  overflow: hidden;\n}\n\n.fp-card__meta[_ngcontent-%COMP%] {\n  display: flex;\n  flex-direction: column;\n  gap: 6px;\n  padding: 10px 0;\n  border-top: 1px solid var(--mj-border-subtle);\n  border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.fp-meta-row[_ngcontent-%COMP%] {\n  display: flex;\n  align-items: baseline;\n  justify-content: space-between;\n  gap: 12px;\n  font-size: 13px;\n\n  &__k {\n    flex: 0 0 auto;\n    color: var(--mj-text-muted);\n\n    i {\n      width: 14px;\n      margin-right: 4px;\n    }\n  }\n\n  &__v {\n    flex: 1 1 auto;\n    text-align: right;\n    color: var(--mj-text-primary);\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n\n  &__sub {\n    color: var(--mj-text-muted);\n    font-size: 12px;\n  }\n}\n\n.fp-card__actions[_ngcontent-%COMP%] {\n  display: flex;\n  gap: 8px;\n  margin-top: auto;\n}\n\n\n\n.fp-status[_ngcontent-%COMP%] {\n  flex: 0 0 auto;\n  align-self: flex-start;\n  padding: 2px 10px;\n  border-radius: var(--mj-radius-full, 999px);\n  font-size: 11px;\n  font-weight: 600;\n  white-space: nowrap;\n\n  &.status--never {\n    background: var(--mj-bg-surface-sunken);\n    color: var(--mj-text-muted);\n  }\n\n  &.status--running {\n    background: var(--mj-status-info-bg);\n    color: var(--mj-status-info-text);\n  }\n\n  &.status--completed {\n    background: var(--mj-status-success-bg);\n    color: var(--mj-status-success-text);\n  }\n\n  &.status--failed {\n    background: var(--mj-status-error-bg);\n    color: var(--mj-status-error-text);\n  }\n\n  &.status--cancelled {\n    background: var(--mj-status-warning-bg);\n    color: var(--mj-status-warning-text);\n  }\n}"] });
};
FeaturePipelinesResourceComponent = __decorate([
    RegisterClass(BaseResourceComponent, 'FeaturePipelinesResource')
], FeaturePipelinesResourceComponent);
export { FeaturePipelinesResourceComponent };
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(FeaturePipelinesResourceComponent, [{
        type: Component,
        args: [{ standalone: false, selector: 'app-feature-pipelines-resource', template: "<mj-page-layout>\n  <mj-page-header\n    Title=\"Feature Pipelines\"\n    Icon=\"fa-solid fa-diagram-project\"\n    Subtitle=\"Derive feature attributes from your data and persist them back to entities\">\n    <div meta>\n      @if (FailedCount > 0) {\n        <mj-stat-badge [Count]=\"FailedCount\" Label=\"last run failed\" Variant=\"error\"></mj-stat-badge>\n      } @else {\n        <mj-stat-badge\n          [Count]=\"FilteredPipelines.length\"\n          [Total]=\"AllPipelines.length\"\n          Label=\"pipelines\">\n        </mj-stat-badge>\n      }\n    </div>\n    <div actions>\n      <mj-refresh-button [Loading]=\"IsLoading\" (Clicked)=\"Refresh()\"></mj-refresh-button>\n      <button mjButton variant=\"primary\" size=\"sm\" (click)=\"OnNewPipeline()\">\n        <i class=\"fa-solid fa-plus\"></i> New Pipeline\n      </button>\n    </div>\n    <div toolbar>\n      <mj-page-search\n        [Value]=\"SearchQuery\"\n        Placeholder=\"Search by name, entity, or attribute\u2026\"\n        (ValueChange)=\"SearchQuery = $event; OnSearchChanged()\">\n      </mj-page-search>\n    </div>\n  </mj-page-header>\n\n  <mj-page-body [Flex]=\"true\">\n    @if (IsLoading) {\n      <div class=\"fp-loading\">\n        <mj-loading text=\"Loading feature pipelines\u2026\" size=\"medium\"></mj-loading>\n      </div>\n    } @else if (AllPipelines.length === 0) {\n      <mj-empty-state\n        Icon=\"fa-solid fa-diagram-project\"\n        Title=\"No feature pipelines yet\"\n        Message=\"A Feature Pipeline derives an attribute per record (e.g. an LLM summary or score) and writes it back to your data \u2014 reusable analytics, independent of any model.\"\n        ActionText=\"New Pipeline\"\n        ActionIcon=\"fa-solid fa-plus\"\n        (Action)=\"OnNewPipeline()\">\n      </mj-empty-state>\n    } @else if (FilteredPipelines.length === 0) {\n      <mj-empty-state\n        Variant=\"no-results\"\n        Icon=\"fa-solid fa-magnifying-glass\"\n        Title=\"No matching pipelines\"\n        Message=\"No feature pipelines match your search.\">\n      </mj-empty-state>\n    } @else {\n      <div class=\"fp-grid\">\n        @for (pipeline of FilteredPipelines; track pipeline.ID) {\n          <div class=\"fp-card\" [class.fp-card--disabled]=\"pipeline.Status !== 'Active'\">\n            <div class=\"fp-card__head\">\n              <i class=\"fp-card__icon\" [class]=\"WorkTypeIcon(pipeline.WorkType)\"></i>\n              <div class=\"fp-card__title\">\n                <h3 [title]=\"pipeline.Name\">{{ pipeline.Name }}</h3>\n                <span class=\"fp-card__worktype\">{{ pipeline.WorkType }}</span>\n              </div>\n              <span class=\"fp-status\" [class]=\"RunStatusClass(pipeline.LastRunStatus)\">\n                {{ RunStatusLabel(pipeline.LastRunStatus) }}\n              </span>\n            </div>\n\n            @if (pipeline.Description) {\n              <p class=\"fp-card__desc\" [title]=\"pipeline.Description\">{{ pipeline.Description }}</p>\n            }\n\n            <div class=\"fp-card__meta\">\n              <div class=\"fp-meta-row\">\n                <span class=\"fp-meta-row__k\"><i class=\"fa-solid fa-table\"></i> Target</span>\n                <span class=\"fp-meta-row__v\">{{ pipeline.TargetEntity }}</span>\n              </div>\n              <div class=\"fp-meta-row\">\n                <span class=\"fp-meta-row__k\"><i class=\"fa-solid fa-pen-to-square\"></i> Writes</span>\n                <span class=\"fp-meta-row__v\">{{ pipeline.OutputAttribute || '\u2014' }}</span>\n              </div>\n              <div class=\"fp-meta-row\">\n                <span class=\"fp-meta-row__k\"><i class=\"fa-solid fa-clock-rotate-left\"></i> Last run</span>\n                <span class=\"fp-meta-row__v\">\n                  {{ TimeAgo(pipeline.LastRunAt) }}\n                  @if (pipeline.LastRunProcessed != null) {\n                    <span class=\"fp-meta-row__sub\">\u00B7 {{ pipeline.LastRunSuccess }}/{{ pipeline.LastRunProcessed }} written</span>\n                  }\n                </span>\n              </div>\n            </div>\n\n            <div class=\"fp-card__actions\">\n              <button\n                mjButton\n                variant=\"primary\"\n                size=\"sm\"\n                [disabled]=\"!pipeline.OnDemandEnabled || pipeline.Status !== 'Active' || IsRunning(pipeline.ID)\"\n                (click)=\"OnRunPipeline(pipeline)\">\n                @if (IsRunning(pipeline.ID)) {\n                  <i class=\"fa-solid fa-spinner fa-spin\"></i> Running\u2026\n                } @else {\n                  <i class=\"fa-solid fa-play\"></i> Run\n                }\n              </button>\n              <button mjButton variant=\"secondary\" size=\"sm\" (click)=\"OnEditPipeline(pipeline)\">\n                <i class=\"fa-solid fa-sliders\"></i> Edit\n              </button>\n            </div>\n          </div>\n        }\n      </div>\n    }\n  </mj-page-body>\n</mj-page-layout>\n\n@if (ShowEditor) {\n  <mj-dialog [Visible]=\"ShowEditor\" Title=\"Feature Pipeline\" [Width]=\"900\" (Close)=\"OnEditorCancelled()\">\n    <mj-record-process-editor\n      [RecordProcessID]=\"EditingPipelineID\"\n      (Saved)=\"OnEditorSaved($event)\"\n      (Cancelled)=\"OnEditorCancelled()\">\n    </mj-record-process-editor>\n  </mj-dialog>\n}\n", styles: ["/**\n * Feature Pipelines (Knowledge Hub) \u2014 card-grid layout.\n * All colors use semantic design tokens (dark-mode + white-label safe).\n */\n\n.fp-loading {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  min-height: 240px;\n  width: 100%;\n}\n\n.fp-grid {\n  display: grid;\n  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));\n  gap: 16px;\n  padding: 4px;\n  align-content: start;\n}\n\n.fp-card {\n  display: flex;\n  flex-direction: column;\n  gap: 12px;\n  padding: 16px;\n  border: 1px solid var(--mj-border-default);\n  border-radius: var(--mj-radius-lg, 10px);\n  background: var(--mj-bg-surface-card);\n  transition: border-color 0.15s ease, box-shadow 0.15s ease;\n\n  &:hover {\n    border-color: var(--mj-border-strong);\n    box-shadow: 0 2px 8px color-mix(in srgb, var(--mj-brand-primary) 8%, transparent);\n  }\n\n  &--disabled {\n    opacity: 0.65;\n  }\n}\n\n.fp-card__head {\n  display: flex;\n  align-items: flex-start;\n  gap: 12px;\n}\n\n.fp-card__icon {\n  flex: 0 0 auto;\n  width: 36px;\n  height: 36px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  border-radius: var(--mj-radius-md, 8px);\n  background: color-mix(in srgb, var(--mj-brand-primary) 12%, var(--mj-bg-surface));\n  color: var(--mj-brand-primary);\n  font-size: 16px;\n}\n\n.fp-card__title {\n  flex: 1 1 auto;\n  min-width: 0;\n\n  h3 {\n    margin: 0;\n    font-size: 15px;\n    font-weight: 600;\n    color: var(--mj-text-primary);\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n}\n\n.fp-card__worktype {\n  font-size: 11px;\n  font-weight: 600;\n  text-transform: uppercase;\n  letter-spacing: 0.04em;\n  color: var(--mj-text-muted);\n}\n\n.fp-card__desc {\n  margin: 0;\n  font-size: 13px;\n  line-height: 1.4;\n  color: var(--mj-text-secondary);\n  display: -webkit-box;\n  -webkit-line-clamp: 2;\n  line-clamp: 2;\n  -webkit-box-orient: vertical;\n  overflow: hidden;\n}\n\n.fp-card__meta {\n  display: flex;\n  flex-direction: column;\n  gap: 6px;\n  padding: 10px 0;\n  border-top: 1px solid var(--mj-border-subtle);\n  border-bottom: 1px solid var(--mj-border-subtle);\n}\n\n.fp-meta-row {\n  display: flex;\n  align-items: baseline;\n  justify-content: space-between;\n  gap: 12px;\n  font-size: 13px;\n\n  &__k {\n    flex: 0 0 auto;\n    color: var(--mj-text-muted);\n\n    i {\n      width: 14px;\n      margin-right: 4px;\n    }\n  }\n\n  &__v {\n    flex: 1 1 auto;\n    text-align: right;\n    color: var(--mj-text-primary);\n    overflow: hidden;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n\n  &__sub {\n    color: var(--mj-text-muted);\n    font-size: 12px;\n  }\n}\n\n.fp-card__actions {\n  display: flex;\n  gap: 8px;\n  margin-top: auto;\n}\n\n/* Run-status pill \u2014 semantic status tokens */\n.fp-status {\n  flex: 0 0 auto;\n  align-self: flex-start;\n  padding: 2px 10px;\n  border-radius: var(--mj-radius-full, 999px);\n  font-size: 11px;\n  font-weight: 600;\n  white-space: nowrap;\n\n  &.status--never {\n    background: var(--mj-bg-surface-sunken);\n    color: var(--mj-text-muted);\n  }\n\n  &.status--running {\n    background: var(--mj-status-info-bg);\n    color: var(--mj-status-info-text);\n  }\n\n  &.status--completed {\n    background: var(--mj-status-success-bg);\n    color: var(--mj-status-success-text);\n  }\n\n  &.status--failed {\n    background: var(--mj-status-error-bg);\n    color: var(--mj-status-error-text);\n  }\n\n  &.status--cancelled {\n    background: var(--mj-status-warning-bg);\n    color: var(--mj-status-warning-text);\n  }\n}\n"] }]
    }], null, null); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(FeaturePipelinesResourceComponent, { className: "FeaturePipelinesResourceComponent", filePath: "src/KnowledgeHub/components/feature-pipelines/feature-pipelines-resource.component.ts", lineNumber: 65 }); })();
/** Tree-shaking prevention — keeps the component in the bundle. */
export function LoadFeaturePipelinesResource() {
    // Prevents tree-shaking of the component.
}
//# sourceMappingURL=feature-pipelines-resource.component.js.map