@memberjunction/ng-explorer-core 5.43.0 → 5.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/generated/lazy-feature-config.d.ts +1 -1
  2. package/dist/generated/lazy-feature-config.d.ts.map +1 -1
  3. package/dist/generated/lazy-feature-config.js +15 -3
  4. package/dist/generated/lazy-feature-config.js.map +1 -1
  5. package/dist/lib/about/about-dialog.component.d.ts +0 -1
  6. package/dist/lib/about/about-dialog.component.d.ts.map +1 -1
  7. package/dist/lib/about/about-dialog.component.js +217 -218
  8. package/dist/lib/about/about-dialog.component.js.map +1 -1
  9. package/dist/lib/command-palette/command-palette.component.js +8 -14
  10. package/dist/lib/command-palette/command-palette.component.js.map +1 -1
  11. package/dist/lib/conversation-feedback/conversation-feedback.js +66 -73
  12. package/dist/lib/conversation-feedback/conversation-feedback.js.map +1 -1
  13. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js +35 -45
  14. package/dist/lib/dashboard-preferences-dialog/dashboard-preferences-dialog.component.js.map +1 -1
  15. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts +6 -4
  16. package/dist/lib/resource-wrappers/chat-conversations-resource.component.d.ts.map +1 -1
  17. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js +33 -17
  18. package/dist/lib/resource-wrappers/chat-conversations-resource.component.js.map +1 -1
  19. package/dist/lib/resource-wrappers/dashboard-resource.component.d.ts.map +1 -1
  20. package/dist/lib/resource-wrappers/dashboard-resource.component.js +9 -8
  21. package/dist/lib/resource-wrappers/dashboard-resource.component.js.map +1 -1
  22. package/dist/lib/resource-wrappers/search-results-resource.component.d.ts.map +1 -1
  23. package/dist/lib/resource-wrappers/search-results-resource.component.js +35 -43
  24. package/dist/lib/resource-wrappers/search-results-resource.component.js.map +1 -1
  25. package/dist/lib/shell/components/header/app-switcher.component.d.ts +6 -1
  26. package/dist/lib/shell/components/header/app-switcher.component.d.ts.map +1 -1
  27. package/dist/lib/shell/components/header/app-switcher.component.js +6 -3
  28. package/dist/lib/shell/components/header/app-switcher.component.js.map +1 -1
  29. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts +10 -2
  30. package/dist/lib/shell/components/tabs/component-cache-manager.d.ts.map +1 -1
  31. package/dist/lib/shell/components/tabs/component-cache-manager.js +19 -1
  32. package/dist/lib/shell/components/tabs/component-cache-manager.js.map +1 -1
  33. package/dist/lib/shell/components/tabs/tab-container.component.d.ts +1 -0
  34. package/dist/lib/shell/components/tabs/tab-container.component.d.ts.map +1 -1
  35. package/dist/lib/shell/components/tabs/tab-container.component.js +3 -2
  36. package/dist/lib/shell/components/tabs/tab-container.component.js.map +1 -1
  37. package/dist/lib/shell/shell.module.d.ts +1 -1
  38. package/dist/lib/shell/shell.module.d.ts.map +1 -1
  39. package/dist/lib/shell/shell.module.js +4 -1
  40. package/dist/lib/shell/shell.module.js.map +1 -1
  41. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js +5 -7
  42. package/dist/lib/single-dashboard/Components/add-item/add-item.component.js.map +1 -1
  43. package/dist/lib/single-dashboard/single-dashboard.component.js +17 -27
  44. package/dist/lib/single-dashboard/single-dashboard.component.js.map +1 -1
  45. package/dist/lib/single-list-detail/single-list-detail.component.d.ts +6 -2
  46. package/dist/lib/single-list-detail/single-list-detail.component.d.ts.map +1 -1
  47. package/dist/lib/single-list-detail/single-list-detail.component.js +48 -57
  48. package/dist/lib/single-list-detail/single-list-detail.component.js.map +1 -1
  49. package/dist/lib/single-search-result/single-search-result.component.js +17 -22
  50. package/dist/lib/single-search-result/single-search-result.component.js.map +1 -1
  51. package/dist/lib/user-notifications/user-notifications.component.d.ts +65 -9
  52. package/dist/lib/user-notifications/user-notifications.component.d.ts.map +1 -1
  53. package/dist/lib/user-notifications/user-notifications.component.js +441 -261
  54. package/dist/lib/user-notifications/user-notifications.component.js.map +1 -1
  55. package/dist/module.d.ts +33 -32
  56. package/dist/module.d.ts.map +1 -1
  57. package/dist/module.js +18 -7
  58. package/dist/module.js.map +1 -1
  59. package/package.json +49 -47
  60. package/dist/lib/__tests__/explorer-core.test.d.ts +0 -2
  61. package/dist/lib/__tests__/explorer-core.test.d.ts.map +0 -1
  62. package/dist/lib/__tests__/explorer-core.test.js +0 -229
  63. package/dist/lib/__tests__/explorer-core.test.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"search-results-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/search-results-resource.component.ts"],"names":[],"mappings":"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","sourcesContent":["import { Component, ChangeDetectorRef, inject } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { CompositeKey, Metadata, RunView } from '@memberjunction/core';\nimport { ResourceData } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { FileOpenService } from '@memberjunction/ng-file-storage';\nimport {\n SearchService,\n SearchResultItem,\n SearchFilter,\n SearchFilterChangeEvent,\n SearchRequest,\n SearchResponse,\n SearchResultSelectedEvent,\n StreamingProviderStatus,\n} from '@memberjunction/ng-search';\nimport { WordCloudItem, WordCloudItemEvent } from '@memberjunction/ng-word-cloud';\n\n@RegisterClass(BaseResourceComponent, 'SearchResultsResource')\n@Component({\n standalone: false,\n selector: 'mj-search-results-resource',\n template: `\n <div class=\"search-results-page\">\n <!-- Streaming status strip — visible while streamScopedSearch is in flight -->\n @if (EnableStreaming && (IsSearching || StreamingProviders.length > 0)) {\n <div class=\"streaming-status-strip\" aria-live=\"polite\">\n @for (p of StreamingProviders; track p.Name) {\n <span class=\"streaming-chip\"\n [class.streaming-chip-error]=\"p.State === 'Error'\"\n [class.streaming-chip-completed]=\"p.State === 'Completed'\">\n @if (p.State === 'Completed') {\n <i class=\"fa-solid fa-check\"></i>\n } @else {\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n }\n <span class=\"streaming-chip-name\">{{ p.Name }}</span>\n @if (p.State === 'Completed') {\n <span class=\"streaming-chip-count\">{{ p.Count }}</span>\n <span class=\"streaming-chip-time\">{{ p.ElapsedMs }}ms</span>\n } @else if (p.ErrorMessage) {\n <span class=\"streaming-chip-time\">{{ p.ErrorMessage }}</span>\n }\n </span>\n }\n @if (IsSearching) {\n <span class=\"streaming-chip streaming-chip-pending\">\n <i class=\"fa-solid fa-circle-notch fa-spin\"></i>\n <span>Streaming…</span>\n </span>\n }\n </div>\n }\n\n <!-- Header bar (always visible when we have server results) -->\n @if (HasSearched && ServerResultCount > 0) {\n <div class=\"search-header\">\n <div class=\"search-header-left\">\n @if (!ShowFilterPanel) {\n <button class=\"sr-icon-btn\" title=\"Show filters\" (click)=\"ToggleFilterPanel()\">\n <i class=\"fa-solid fa-filter\"></i>\n </button>\n }\n <span class=\"search-meta\">\n {{ FilteredResults.length }} of {{ ServerResultCount }} result{{ ServerResultCount !== 1 ? 's' : '' }}\n for \"{{ CurrentQuery }}\" in {{ ElapsedMs }}ms\n </span>\n </div>\n <div class=\"search-header-right\">\n <!-- Search within results -->\n <div class=\"sr-refine-wrapper\">\n <i class=\"fa-solid fa-filter-list sr-refine-icon\"></i>\n <input class=\"mj-input sr-refine-input\"\n placeholder=\"Filter within results...\"\n [value]=\"ClientFilterText\"\n (input)=\"OnClientFilterTextChange($any($event.target).value)\" />\n @if (ClientFilterText) {\n <button class=\"sr-refine-clear\" (click)=\"OnClientFilterTextChange('')\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n }\n </div>\n <!-- Sort -->\n <select class=\"mj-input sr-sort-select\" [value]=\"SortField\" (change)=\"OnSortChange($any($event.target).value)\">\n <option value=\"score\">Sort: Relevance</option>\n <option value=\"title\">Sort: Name</option>\n <option value=\"entity\">Sort: Entity</option>\n </select>\n <!-- View mode toggle -->\n <div class=\"sr-view-toggle\">\n <button class=\"sr-icon-btn\"\n [class.sr-view-active]=\"ViewMode === 'list'\"\n title=\"List view\"\n (click)=\"SetViewMode('list')\">\n <i class=\"fa-solid fa-list\"></i>\n </button>\n <button class=\"sr-icon-btn\"\n [class.sr-view-active]=\"ViewMode === 'cloud'\"\n title=\"Tag cloud view\"\n (click)=\"SetViewMode('cloud')\">\n <i class=\"fa-solid fa-cloud\"></i>\n </button>\n </div>\n <!-- Refresh -->\n <button class=\"sr-icon-btn\" title=\"Refresh search\" (click)=\"OnRefresh()\" [disabled]=\"IsSearching\">\n <i class=\"fa-solid fa-arrows-rotate\" [class.fa-spin]=\"IsSearching\"></i>\n </button>\n </div>\n </div>\n }\n\n <!-- Initial loading (first search) -->\n @if (IsSearching && ServerResultCount === 0) {\n <div class=\"search-loading\">\n <mj-loading text=\"Searching...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- No server results -->\n @if (!IsSearching && ServerResultCount === 0 && HasSearched) {\n <div class=\"search-no-results\">\n <i class=\"fa-solid fa-magnifying-glass-minus\"></i>\n <h3>No results found</h3>\n <p>Try different keywords or broaden your search.</p>\n </div>\n }\n <!-- Results body (visible when server returned results) -->\n @if (ServerResultCount > 0) {\n <div class=\"search-results-body-wrapper\">\n <!-- Semi-opaque loading overlay for re-queries (slider lowered, etc.) -->\n @if (IsSearching) {\n <div class=\"search-requery-overlay\">\n <mj-loading text=\"Updating results...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n @if (ViewMode === 'cloud') {\n <div class=\"search-cloud-wrapper\">\n @if (IsLoadingCloud) {\n <mj-loading text=\"Loading tag cloud...\" size=\"medium\"></mj-loading>\n } @else {\n <mj-word-cloud\n [Items]=\"CloudItems\"\n [MaxItems]=\"80\"\n ColorMode=\"weight-gradient\"\n [Interactive]=\"true\"\n (ItemClick)=\"OnCloudItemClick($event)\">\n </mj-word-cloud>\n }\n </div>\n } @else {\n <div class=\"search-body\">\n @if (ShowFilterPanel) {\n <mj-search-filter\n [Filters]=\"Filters\"\n [ActiveFilters]=\"ActiveFilters\"\n [ShowRelevanceSlider]=\"true\"\n [MinScorePercent]=\"MinScorePercent\"\n [ServerMinScorePercent]=\"serverMinScorePercent\"\n (FilterChanged)=\"OnFilterChanged($event)\"\n (FiltersCleared)=\"OnFiltersCleared()\"\n (CloseRequested)=\"ToggleFilterPanel()\"\n (MinScoreChanged)=\"OnMinScoreChanged($any($event))\">\n </mj-search-filter>\n }\n @if (FilteredResults.length > 0) {\n <mj-search-results\n [FlatResults]=\"FilteredResults\"\n [HighlightText]=\"ClientFilterText\"\n [ShowScores]=\"true\"\n [ShowTags]=\"true\"\n [ShowSummary]=\"false\"\n [PageSize]=\"20\"\n (ResultSelected)=\"OnResultSelected($event)\"\n (OpenRecordRequested)=\"OnOpenRecord($event)\">\n </mj-search-results>\n } @else {\n <div class=\"search-no-results-inline\">\n <i class=\"fa-solid fa-filter-circle-xmark\"></i>\n <p>No results match current filters. Try lowering the minimum relevance.</p>\n </div>\n }\n </div>\n }\n </div>\n }\n </div>\n `,\n styles: [`\n .search-results-page {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n overflow: hidden;\n }\n .search-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 8px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n }\n .search-header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .search-header-right {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .search-meta {\n color: var(--mj-text-muted);\n font-size: 13px;\n white-space: nowrap;\n }\n .sr-icon-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s;\n font-size: 13px;\n flex-shrink: 0;\n }\n .sr-icon-btn:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n .sr-icon-btn:disabled { opacity: 0.4; cursor: default; }\n .sr-refine-wrapper {\n position: relative;\n display: flex;\n align-items: center;\n }\n .sr-refine-icon {\n position: absolute;\n left: 8px;\n color: var(--mj-text-muted);\n font-size: 12px;\n pointer-events: none;\n }\n .sr-refine-input {\n padding: 5px 28px 5px 26px;\n font-size: 12px;\n width: 180px;\n border-radius: 6px;\n }\n .sr-refine-clear {\n position: absolute;\n right: 6px;\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 11px;\n padding: 2px;\n }\n .sr-refine-clear:hover { color: var(--mj-text-primary); }\n .sr-sort-select {\n padding: 5px 24px 5px 8px;\n font-size: 12px;\n border-radius: 6px;\n min-width: 130px;\n }\n .search-loading {\n display: flex;\n justify-content: center;\n padding: 60px 0;\n }\n .search-body {\n flex: 1;\n display: flex;\n gap: 16px;\n padding: 16px 24px;\n overflow: hidden;\n }\n .search-body mj-search-filter {\n flex-shrink: 0;\n width: 240px;\n overflow-y: auto;\n }\n .search-body mj-search-results {\n flex: 1;\n min-width: 0;\n overflow-y: auto;\n }\n .search-no-results {\n text-align: center;\n padding: 60px 20px;\n color: var(--mj-text-muted);\n }\n .search-no-results i {\n font-size: 48px;\n margin-bottom: 16px;\n opacity: 0.4;\n }\n .search-no-results h3 {\n font-size: 18px;\n color: var(--mj-text-primary);\n margin: 0 0 8px;\n }\n .search-no-results p {\n font-size: 14px;\n margin: 0;\n }\n .search-results-body-wrapper {\n position: relative;\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n .search-requery-overlay {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-page) 75%, transparent);\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .search-no-results-inline {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 8px;\n color: var(--mj-text-muted);\n padding: 40px 20px;\n }\n .search-no-results-inline i {\n font-size: 32px;\n opacity: 0.4;\n }\n .search-no-results-inline p {\n font-size: 13px;\n margin: 0;\n }\n .sr-view-toggle {\n display: flex;\n gap: 2px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n padding: 2px;\n background: var(--mj-bg-surface-sunken);\n }\n .sr-view-toggle .sr-icon-btn {\n border: none;\n border-radius: 4px;\n width: 28px;\n height: 26px;\n font-size: 12px;\n background: transparent;\n }\n .sr-view-toggle .sr-icon-btn.sr-view-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) 10%, transparent);\n }\n .search-cloud-wrapper {\n flex: 1;\n padding: 24px;\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .search-cloud-wrapper mj-word-cloud {\n width: 100%;\n height: 100%;\n max-height: 600px;\n }\n .streaming-status-strip {\n display: flex;\n flex-wrap: wrap;\n gap: 0.4rem;\n padding: 0.5rem 1rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n }\n .streaming-chip {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.2rem 0.55rem;\n border-radius: 9999px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.74rem;\n }\n .streaming-chip-pending {\n color: var(--mj-text-muted);\n }\n .streaming-chip-completed {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n border-color: var(--mj-status-success-border);\n color: var(--mj-status-success-text);\n }\n .streaming-chip-error {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: var(--mj-status-error-border);\n color: var(--mj-status-error-text);\n }\n .streaming-chip-name { font-weight: 500; }\n .streaming-chip-count { opacity: 0.7; }\n .streaming-chip-time { opacity: 0.6; font-size: 0.7rem; }\n `]\n})\nexport class SearchResultsResource extends BaseResourceComponent {\n private cdr = inject(ChangeDetectorRef);\n private searchService = inject(SearchService);\n private fileOpenService = inject(FileOpenService);\n\n CurrentQuery = '';\n IsSearching = false;\n HasSearched = false;\n TotalCount = 0;\n ElapsedMs = 0;\n Filters: SearchFilter[] = [];\n ActiveFilters: Record<string, string[]> = {};\n FilteredResults: SearchResultItem[] = [];\n MinScorePercent = 30;\n /** The MinScore that was sent to the server on the last search. If the user\n * slides below this, we need to re-query the server to get more results. */\n serverMinScorePercent = 30;\n /** How many results the server returned (before client-side filtering) */\n ServerResultCount = 0;\n ShowFilterPanel = true;\n SortField: 'score' | 'title' | 'entity' = 'score';\n ClientFilterText = '';\n ViewMode: 'list' | 'cloud' = 'list';\n CloudItems: WordCloudItem[] = [];\n IsLoadingCloud = false;\n\n /** All results from the last search (before client-side filtering) */\n private allResults: SearchResultItem[] = [];\n\n /** Selected scope IDs from the search bar (empty = unscoped/global). */\n private ScopeIDs: string[] = [];\n\n /**\n * Phase 2C streaming opt-in. Off by default to preserve Phase 1 request-response UX.\n * Enable per-resource via `Data.Configuration.EnableStreaming` or per-tab via the\n * `?stream=1` query param (mostly for engineering verification before flipping the\n * default).\n */\n EnableStreaming = false;\n\n /** Per-provider stream status displayed above results while a stream is in flight. */\n StreamingProviders: StreamingProviderStatus[] = [];\n\n /** Active stream subscription so we can cancel on a new search or destroy. */\n private currentStream: Subscription | null = null;\n\n private dataLoaded = false;\n\n // Override Data setter to trigger search when tab container provides the data\n // (ngOnInit fires before Data is set, so we can't rely on it)\n override set Data(value: ResourceData) {\n super.Data = value;\n if (!this.dataLoaded) {\n this.dataLoaded = true;\n this.loadFromData();\n }\n }\n override get Data(): ResourceData {\n return super.Data;\n }\n\n private async loadFromData(): Promise<void> {\n this.registerAgentTools();\n\n // Load filter panel preference\n try {\n const { UserInfoEngine } = require('@memberjunction/core-entities');\n const pref = UserInfoEngine.Instance.GetSetting('search.showFilterPanel');\n if (pref === 'false') this.ShowFilterPanel = false;\n } catch { /* ignore */ }\n\n const config = this.Data?.Configuration;\n if (config?.Query) {\n this.CurrentQuery = config.Query as string;\n } else if (config?.SearchInput) {\n this.CurrentQuery = config.SearchInput as string;\n }\n\n // Apply min relevance from the search bar dropdown if provided\n if (config?.MinRelevance != null) {\n const mr = Number(config.MinRelevance);\n if (!isNaN(mr) && mr >= 0 && mr <= 100) {\n this.MinScorePercent = mr;\n }\n }\n\n // Carry scope selection from the search bar through into the initial query.\n if (Array.isArray(config?.ScopeIDs)) {\n this.ScopeIDs = (config.ScopeIDs as unknown[]).filter((x): x is string => typeof x === 'string');\n }\n\n // Streaming opt-in: resource config wins; URL query param `?stream=1` is the\n // engineering-verification override (cleared once the default flips). Read the\n // URL directly because the resource's tab config doesn't always mirror URL params\n // into `Configuration.queryParams` at the moment loadFromData() runs.\n if (config?.EnableStreaming === true) {\n this.EnableStreaming = true;\n }\n try {\n const streamParam = new URL(window.location.href).searchParams.get('stream');\n if (streamParam === '1' || streamParam === 'true') {\n this.EnableStreaming = true;\n }\n } catch { /* ignore — server-side render or odd URL */ }\n\n // Sync min relevance to URL query param\n this.navigationService.UpdateActiveTabQueryParams({ minRelevance: String(this.MinScorePercent) });\n\n if (this.CurrentQuery) {\n await this.ExecuteSearch(this.CurrentQuery);\n }\n\n this.NotifyLoadComplete();\n }\n\n override ngOnDestroy(): void {\n this.currentStream?.unsubscribe();\n this.currentStream = null;\n super.ngOnDestroy();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n const query = (data.Configuration?.Query ?? data.Configuration?.SearchInput ?? 'Search') as string;\n return `Search: ${query}`;\n }\n\n async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-magnifying-glass';\n }\n\n async OnRefineSearch(query: string): Promise<void> {\n const trimmed = query?.trim();\n if (trimmed && trimmed.length >= 2) {\n this.CurrentQuery = trimmed;\n this.ActiveFilters = {};\n await this.ExecuteSearch(trimmed);\n }\n }\n\n OnFilterChanged(event: SearchFilterChangeEvent): void {\n this.ActiveFilters = {\n ...this.ActiveFilters,\n [event.Category]: event.SelectedValues\n };\n this.applyClientFilters();\n }\n\n OnFiltersCleared(): void {\n this.ActiveFilters = {};\n this.MinScorePercent = 30;\n this.navigationService.UpdateActiveTabQueryParams({ minRelevance: '30' });\n this.applyClientFilters();\n }\n\n OnMinScoreChanged(percent: number): void {\n this.MinScorePercent = percent;\n this.navigationService.UpdateActiveTabQueryParams({ minRelevance: String(percent) });\n if (percent < this.serverMinScorePercent && this.CurrentQuery) {\n // User lowered below what server filtered — need to re-query with lower threshold\n this.ExecuteSearch(this.CurrentQuery);\n } else {\n // User raised or stayed at/above server threshold — client-side filter is sufficient\n this.applyClientFilters();\n }\n }\n\n /**\n * React to ?minRelevance= changes that arrive after initial load — e.g. a Home pin or\n * deep link to a specific relevance threshold, or browser back/forward — when this tab\n * is re-focused rather than freshly loaded (so loadFromData() does not run again).\n */\n protected override OnQueryParamsChanged(params: Record<string, string>, _source: 'popstate' | 'deeplink'): void {\n const minRelevance = params['minRelevance'];\n if (minRelevance == null) return;\n const mr = Number(minRelevance);\n if (isNaN(mr) || mr < 0 || mr > 100 || mr === this.MinScorePercent) return;\n\n this.MinScorePercent = mr;\n if (mr < this.serverMinScorePercent && this.CurrentQuery) {\n // Below what the server filtered — re-query with the lower threshold.\n void this.ExecuteSearch(this.CurrentQuery);\n } else {\n this.applyClientFilters();\n }\n }\n\n OnResultSelected(event: SearchResultSelectedEvent): void {\n this.navigateToResult(event.Result);\n }\n\n OnOpenRecord(result: SearchResultItem): void {\n this.navigateToResult(result);\n }\n\n async OnRefresh(): Promise<void> {\n if (this.CurrentQuery) {\n this.ActiveFilters = {};\n this.MinScorePercent = 30;\n this.ClientFilterText = '';\n await this.ExecuteSearch(this.CurrentQuery);\n }\n }\n\n ToggleFilterPanel(): void {\n this.ShowFilterPanel = !this.ShowFilterPanel;\n // Persist preference\n try {\n const { UserInfoEngine } = require('@memberjunction/core-entities');\n UserInfoEngine.Instance.SetSettingDebounced(\n 'search.showFilterPanel',\n this.ShowFilterPanel ? 'true' : 'false'\n );\n } catch { /* ignore if UserInfoEngine not available */ }\n this.cdr.detectChanges();\n }\n\n OnSortChange(field: string): void {\n this.SortField = field as 'score' | 'title' | 'entity';\n this.applyClientFilters();\n }\n\n OnClientFilterTextChange(text: string): void {\n this.ClientFilterText = text;\n this.applyClientFilters();\n }\n\n SetViewMode(mode: 'list' | 'cloud'): void {\n this.ViewMode = mode;\n if (mode === 'cloud') {\n this.buildCloudItems();\n }\n this.emitAgentContext();\n this.cdr.detectChanges();\n }\n\n OnCloudItemClick(_event: WordCloudItemEvent): void {\n // No-op for now — tag filtering in the filter panel is not yet implemented.\n // Future: clicking a tag could filter results to only those with that tag.\n }\n\n /**\n * Navigate to a search result based on its ResultType discriminator.\n * - entity-record: opens the MJ entity record viewer\n * - storage-file: opens the file via pre-authenticated URL in new tab\n * - content-item: opens the MJ entity record viewer (content items are entity records)\n */\n private navigateToResult(result: SearchResultItem): void {\n if (result.ResultType === 'storage-file') {\n // Try preview first (opens in provider's web viewer), fall back to download\n if (!this.fileOpenService.OpenPreviewFromSearchResult(result.RawMetadata)) {\n this.fileOpenService.OpenFileFromSearchResult(result.RawMetadata);\n }\n return;\n }\n\n if (!result.EntityName || !result.RecordID) return;\n\n // entity-record, content-item, or unset — navigate to entity record\n const pkey = new CompositeKey([{ FieldName: 'ID', Value: result.RecordID }]);\n this.navigationService.OpenEntityRecord(result.EntityName, pkey);\n }\n\n private async ExecuteSearch(query: string): Promise<void> {\n this.IsSearching = true;\n this.HasSearched = false;\n this.cdr.detectChanges();\n\n this.serverMinScorePercent = this.MinScorePercent;\n const request: SearchRequest = {\n Query: query,\n MaxResults: 50,\n ActiveFilters: {},\n IncludeSources: ['vector', 'fulltext', 'entity', 'storage'],\n MinScore: this.MinScorePercent / 100\n };\n if (this.ScopeIDs.length > 0) {\n request.ScopeIDs = [...this.ScopeIDs];\n }\n\n if (this.EnableStreaming) {\n this.executeStreamingSearch(query, request);\n return;\n }\n\n const response: SearchResponse = await this.searchService.ExecuteSearch(request);\n\n this.allResults = [...response.Results].sort((a, b) => b.Score - a.Score);\n this.ServerResultCount = this.allResults.length;\n this.TotalCount = response.TotalCount;\n this.ElapsedMs = response.ElapsedMs;\n this.Filters = response.Filters;\n this.FilteredResults = [...this.allResults];\n\n this.IsSearching = false;\n this.HasSearched = true;\n this.emitAgentContext();\n this.cdr.detectChanges();\n }\n\n /**\n * Phase 2C streaming variant. Subscribes to `streamScopedSearch` and progressively\n * populates the result list as each provider reports back. The 'final' event carries\n * the canonical fused/reranked list, which replaces any partials the user already saw.\n *\n * Cancellation: a new query starts by tearing down the in-flight stream so events\n * from a stale search do not bleed into the current view.\n */\n private executeStreamingSearch(query: string, request: SearchRequest): void {\n // Cancel any prior stream so events from a stale query don't leak in.\n this.currentStream?.unsubscribe();\n this.currentStream = null;\n\n // Reset visible streaming state.\n this.StreamingProviders = [];\n this.allResults = [];\n this.FilteredResults = [];\n this.ServerResultCount = 0;\n this.TotalCount = 0;\n this.ElapsedMs = 0;\n this.cdr.detectChanges();\n\n this.currentStream = this.searchService.StreamSearch(request).subscribe({\n next: (event) => {\n if (event.Phase === 'provider' && event.ProviderName) {\n const count = event.Results?.length ?? 0;\n this.StreamingProviders = [\n ...this.StreamingProviders,\n {\n Name: event.ProviderName,\n Count: count,\n ElapsedMs: event.ElapsedMs ?? 0,\n State: 'Completed',\n },\n ];\n if (event.Results && event.Results.length > 0) {\n this.allResults = [...this.allResults, ...event.Results].sort((a, b) => b.Score - a.Score);\n this.ServerResultCount = this.allResults.length;\n this.applyClientFilters();\n }\n } else if (event.Phase === 'final' && event.Results) {\n this.allResults = [...event.Results].sort((a, b) => b.Score - a.Score);\n this.ServerResultCount = this.allResults.length;\n this.TotalCount = event.Results.length;\n this.ElapsedMs = event.ElapsedMs ?? this.ElapsedMs;\n this.Filters = this.searchService.BuildFilters(this.allResults);\n this.applyClientFilters();\n this.HasSearched = true;\n }\n this.cdr.detectChanges();\n },\n error: (err: Error) => {\n this.StreamingProviders = [\n ...this.StreamingProviders,\n { Name: 'stream', Count: 0, ElapsedMs: 0, State: 'Error', ErrorMessage: err.message },\n ];\n this.IsSearching = false;\n this.HasSearched = true;\n this.cdr.detectChanges();\n },\n complete: () => {\n this.IsSearching = false;\n this.HasSearched = true;\n this.emitAgentContext();\n this.cdr.detectChanges();\n },\n });\n }\n\n /**\n * Apply active filter selections to the full result set.\n */\n private applyClientFilters(): void {\n let results = this.allResults;\n\n // Apply min score filter FIRST (this determines what's \"available\")\n if (this.MinScorePercent > 0) {\n const minScore = this.MinScorePercent / 100;\n results = results.filter(r => r.Score >= minScore);\n }\n\n // Rebuild filters from score-filtered results so counts are accurate\n this.Filters = this.searchService.BuildFilters(results);\n this.TotalCount = results.length;\n\n // Apply facet filters\n if (this.hasActiveFilters()) {\n results = results.filter(r => this.matchesActiveFilters(r));\n }\n\n // Apply client text filter (search within results)\n if (this.ClientFilterText.trim()) {\n const term = this.ClientFilterText.trim().toLowerCase();\n results = results.filter(r =>\n (r.Title?.toLowerCase().includes(term)) ||\n (r.Snippet?.toLowerCase().includes(term)) ||\n (r.EntityName?.toLowerCase().includes(term)) ||\n (r.RecordName?.toLowerCase().includes(term)) ||\n (r.Tags?.some(t => t.toLowerCase().includes(term)))\n );\n }\n\n // Sort\n switch (this.SortField) {\n case 'title':\n results = [...results].sort((a, b) => (a.Title || '').localeCompare(b.Title || ''));\n break;\n case 'entity':\n results = [...results].sort((a, b) => a.EntityName.localeCompare(b.EntityName) || b.Score - a.Score);\n break;\n case 'score':\n default:\n results = [...results].sort((a, b) => b.Score - a.Score);\n break;\n }\n\n this.FilteredResults = results;\n this.emitAgentContext();\n this.cdr.detectChanges();\n }\n\n private hasActiveFilters(): boolean {\n return Object.values(this.ActiveFilters).some(v => v.length > 0);\n }\n\n private matchesActiveFilters(result: SearchResultItem): boolean {\n const entityFilter = this.ActiveFilters['Entity'];\n if (entityFilter?.length) {\n const matchesEntity = entityFilter.includes(result.EntityName);\n const matchesFiles = entityFilter.includes('__storage-files__') && result.ResultType === 'storage-file';\n if (!matchesEntity && !matchesFiles) return false;\n }\n\n const sourceFilter = this.ActiveFilters['Source'];\n if (sourceFilter?.length && !sourceFilter.includes(result.SourceType)) {\n return false;\n }\n\n const tagFilter = this.ActiveFilters['Tags'];\n if (tagFilter?.length && !tagFilter.some(t => result.Tags.includes(t))) {\n return false;\n }\n\n const fileTypeFilter = this.ActiveFilters['File Type'];\n if (fileTypeFilter?.length) {\n if (result.ResultType !== 'storage-file') return false;\n const ext = result.Title?.split('.').pop()?.toUpperCase() ?? '';\n if (!fileTypeFilter.includes(ext)) return false;\n }\n\n return true;\n }\n\n /**\n * Build WordCloudItem[] from search results by extracting entity names and tags,\n * weighted by their frequency across all results.\n */\n /**\n * Build word cloud items from MJ: Tagged Items linked to the search results.\n * Queries the TaggedItem entity for all records in the result set, aggregates\n * tag names by count and weight, and builds WordCloudItem[] for the cloud.\n */\n private async buildCloudItems(): Promise<void> {\n this.IsLoadingCloud = true;\n this.cdr.detectChanges();\n\n try {\n // Group results by entity to build efficient queries\n const byEntity = new Map<string, string[]>();\n for (const result of this.allResults) {\n const md = this.ProviderToUse;\n const entity = md.Entities.find(e => e.Name === result.EntityName);\n if (!entity) continue;\n const list = byEntity.get(entity.ID) || [];\n list.push(result.RecordID);\n byEntity.set(entity.ID, list);\n }\n\n // Query Tagged Items for all record IDs across all entities\n const tagAggregates = new Map<string, { count: number; totalWeight: number }>();\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n\n for (const [entityID, recordIDs] of byEntity) {\n if (recordIDs.length === 0) continue;\n\n // Build IN clause (batch in groups of 50 to avoid huge queries)\n for (let i = 0; i < recordIDs.length; i += 50) {\n const batch = recordIDs.slice(i, i + 50);\n const inClause = batch.map(id => `'${id.replace(/'/g, \"''\")}'`).join(',');\n\n const result = await rv.RunView<{ Tag: string; Weight: number }>({\n EntityName: 'MJ: Tagged Items',\n ExtraFilter: `EntityID = '${entityID}' AND RecordID IN (${inClause})`,\n Fields: ['Tag', 'Weight'],\n ResultType: 'simple'\n });\n\n if (result.Success && result.Results) {\n for (const row of result.Results) {\n const tagName = row.Tag;\n if (!tagName) continue;\n const existing = tagAggregates.get(tagName) || { count: 0, totalWeight: 0 };\n existing.count++;\n existing.totalWeight += (row.Weight ?? 1);\n tagAggregates.set(tagName, existing);\n }\n }\n }\n }\n\n // Build cloud items from aggregated tags\n if (tagAggregates.size === 0) {\n this.CloudItems = [{ Text: 'No tags found', Weight: 1, Category: 'empty' }];\n } else {\n const maxWeight = Math.max(...Array.from(tagAggregates.values()).map(v => v.totalWeight), 1);\n this.CloudItems = Array.from(tagAggregates.entries())\n .sort((a, b) => b[1].totalWeight - a[1].totalWeight)\n .map(([tagName, agg]) => ({\n Text: tagName,\n Weight: agg.totalWeight / maxWeight,\n Category: 'tag',\n Metadata: { type: 'tag', count: agg.count, totalWeight: agg.totalWeight }\n }));\n }\n } catch (err) {\n this.CloudItems = [{ Text: 'Error loading tags', Weight: 1, Category: 'error' }];\n }\n\n this.IsLoadingCloud = false;\n this.cdr.detectChanges();\n }\n\n /** Report current search state to the AI agent */\n private emitAgentContext(): void {\n this.navigationService.SetAgentContext(this, {\n CurrentQuery: this.CurrentQuery || null,\n ResultCount: this.TotalCount,\n FilteredCount: this.FilteredResults.length,\n ElapsedMs: this.ElapsedMs,\n HasSearched: this.HasSearched,\n ShowFilterPanel: this.ShowFilterPanel,\n ViewMode: this.ViewMode,\n SortField: this.SortField,\n MinScorePercent: this.MinScorePercent,\n ClientFilterText: this.ClientFilterText,\n ActiveFilterCount: Object.values(this.ActiveFilters).filter(v => v.length > 0).length,\n TopResults: this.FilteredResults.slice(0, 50).map(r => ({\n Title: r.Title || r.RecordName,\n EntityName: r.EntityName,\n RecordID: r.RecordID,\n Score: Math.round(r.Score * 100),\n SourceType: r.SourceType,\n Snippet: r.Snippet?.substring(0, 100)\n })),\n });\n }\n\n /** Register client tools the agent can invoke on the search results */\n private registerAgentTools(): void {\n this.navigationService.SetAgentClientTools(this, [\n {\n Name: 'RunSearch',\n Description: 'Execute a search query and display results',\n ParameterSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'The search query text' }\n },\n required: ['query']\n },\n Handler: async (params: Record<string, unknown>) => {\n const query = String(params['query'] ?? '');\n this.CurrentQuery = query;\n await this.ExecuteSearch(query);\n return { Success: true, Data: { ResultCount: this.TotalCount, ElapsedMs: this.ElapsedMs } };\n }\n },\n {\n Name: 'SortResults',\n Description: 'Change the sort order of search results',\n ParameterSchema: {\n type: 'object',\n properties: {\n field: { type: 'string', enum: ['score', 'title', 'entity'], description: 'Sort field' }\n },\n required: ['field']\n },\n Handler: async (params: Record<string, unknown>) => {\n this.OnSortChange(String(params['field']));\n return { Success: true, Data: { SortField: this.SortField } };\n }\n },\n {\n Name: 'FilterWithinResults',\n Description: 'Filter the current results by a keyword (client-side text filter)',\n ParameterSchema: {\n type: 'object',\n properties: {\n text: { type: 'string', description: 'Filter text (empty string to clear)' }\n },\n required: ['text']\n },\n Handler: async (params: Record<string, unknown>) => {\n this.OnClientFilterTextChange(String(params['text'] ?? ''));\n return { Success: true, Data: { FilteredCount: this.FilteredResults.length } };\n }\n },\n {\n Name: 'SetViewMode',\n Description: 'Switch between list view and tag cloud visualization',\n ParameterSchema: {\n type: 'object',\n properties: {\n mode: { type: 'string', enum: ['list', 'cloud'], description: 'View mode' }\n },\n required: ['mode']\n },\n Handler: async (params: Record<string, unknown>) => {\n this.SetViewMode((params['mode'] as 'list' | 'cloud') ?? 'list');\n return { Success: true, Data: { ViewMode: this.ViewMode } };\n }\n },\n {\n Name: 'ToggleFilterPanel',\n Description: 'Show or hide the filter panel on the left',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => {\n this.ToggleFilterPanel();\n return { Success: true, Data: { ShowFilterPanel: this.ShowFilterPanel } };\n }\n },\n {\n Name: 'SetMinRelevance',\n Description: 'Set the minimum relevance score filter (0-100 percent)',\n ParameterSchema: {\n type: 'object',\n properties: {\n percent: { type: 'number', description: 'Minimum relevance percentage (0-100)' }\n },\n required: ['percent']\n },\n Handler: async (params: Record<string, unknown>) => {\n this.OnMinScoreChanged(Number(params['percent'] ?? 0));\n return { Success: true, Data: { MinScorePercent: this.MinScorePercent, FilteredCount: this.FilteredResults.length } };\n }\n },\n {\n Name: 'RefreshSearch',\n Description: 'Re-execute the current search query',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => {\n await this.OnRefresh();\n return { Success: true, Data: { ResultCount: this.TotalCount, ElapsedMs: this.ElapsedMs } };\n }\n }\n ]);\n }\n}\n\nexport function LoadSearchResultsResource() {\n // Tree-shaking prevention\n}\n"]}
1
+ {"version":3,"file":"search-results-resource.component.js","sourceRoot":"","sources":["../../../src/lib/resource-wrappers/search-results-resource.component.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAErE,OAAO,EAAE,qBAAqB,EAAqB,MAAM,2BAA2B,CAAC;AACrF,OAAO,EAAE,YAAY,EAAY,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEvE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,EACH,aAAa,GAQhB,MAAM,2BAA2B,CAAC;;;;;;;;;IAiBH,uBAAiC;;;IAEjC,wBAAgD;;;IAIhD,gCAAmC;IAAA,YAAa;IAAA,iBAAO;IACvD,gCAAkC;IAAA,YAAmB;IAAA,iBAAO;;;IADzB,cAAa;IAAb,gCAAa;IACd,eAAmB;IAAnB,+CAAmB;;;IAErD,gCAAkC;IAAA,YAAoB;IAAA,iBAAO;;;IAA3B,cAAoB;IAApB,uCAAoB;;;IAb9D,+BAEiE;IAG3D,AAFF,yGAA+B,oFAEtB;IAGT,gCAAkC;IAAA,YAAY;IAAA,iBAAO;IAInD,AAHF,iGAA+B,uFAGF;IAGjC,iBAAO;;;IAbD,AADA,8DAAkD,wDACQ;IAC5D,cAIC;IAJD,oDAIC;IACiC,eAAY;IAAZ,+BAAY;IAC9C,cAKC;IALD,6EAKC;;;IAIL,+BAAoD;IAChD,wBAAgD;IAChD,4BAAM;IAAA,+BAAU;IACpB,AADoB,iBAAO,EACpB;;;IAvBf,8BAAuD;IACnD,uGAiBC;IACD,sGAAmB;IAMvB,iBAAM;;;IAxBF,cAiBC;IAjBD,wCAiBC;IACD,eAKC;IALD,6CAKC;;;;IASO,kCAA+E;IAA9B,wMAAS,0BAAmB,KAAC;IAC1E,wBAAkC;IACtC,iBAAS;;;;IAgBL,kCAAuE;IAAvC,wMAAS,gCAAyB,EAAE,CAAC,KAAC;IAClE,wBAAiC;IACrC,iBAAS;;;;IAtBrB,AADJ,8BAA2B,cACS;IAC5B,yGAAwB;IAKxB,gCAA0B;IACtB,YAEJ;IACJ,AADI,iBAAO,EACL;IAGF,AAFJ,+BAAiC,cAEE;IAC3B,wBAAsD;IACtD,iCAGuE;IAAhE,8LAAS,oDAAmD,KAAC;IAHpE,iBAGuE;IACvE,yGAAwB;IAK5B,iBAAM;IAEN,mCAA+G;IAAnD,kMAAU,wCAAuC,KAAC;IAC1G,mCAAsB;IAAA,gCAAe;IAAA,iBAAS;IAC9C,mCAAsB;IAAA,2BAAU;IAAA,iBAAS;IACzC,mCAAuB;IAAA,6BAAY;IACvC,AADuC,iBAAS,EACvC;IAGL,AADJ,gCAA4B,kBAIc;IAA9B,0LAAS,mBAAY,MAAM,CAAC,KAAC;IACjC,yBAAgC;IACpC,iBAAS;IACT,mCAGuC;IAA/B,0LAAS,mBAAY,OAAO,CAAC,KAAC;IAClC,yBAAiC;IAEzC,AADI,iBAAS,EACP;IAEN,mCAAkG;IAA/C,0LAAS,kBAAW,KAAC;IACpE,yBAAuE;IAGnF,AADI,AADI,iBAAS,EACP,EACJ;;;IAlDE,eAIC;IAJD,kDAIC;IAEG,eAEJ;IAFI,oNAEJ;IAQW,eAA0B;IAA1B,+CAA0B;IAEjC,cAIC;IAJD,kDAIC;IAGmC,cAAmB;IAAnB,wCAAmB;IAQ/C,eAA4C;IAA5C,4DAA4C;IAM5C,eAA6C;IAA7C,6DAA6C;IAOgB,eAAwB;IAAxB,6CAAwB;IACxD,cAA6B;IAA7B,6CAA6B;;;IAQ9E,8BAA4B;IACxB,iCAA2D;IAC/D,iBAAM;;;IAKN,oCAK+D;;;IAOvD,+BAAoC;IAChC,iCAAkE;IACtE,iBAAM;;;IAME,iCAAmE;;;;IAEnE,yCAK2C;IAAvC,2OAAa,+BAAwB,KAAC;IAC1C,iBAAgB;;;IAFZ,AAFA,AADA,yCAAoB,gBACL,qBAEK;;;IARhC,+BAAkC;IAG5B,AAFF,2HAAsB,wGAEb;IASb,iBAAM;;;IAXF,cAUC;IAVD,+CAUC;;;;IAKG,4CASwD;IAApD,AADA,AADA,AADA,sPAAiB,8BAAuB,KAAC,qOACvB,yBAAkB,KAAC,qOACnB,0BAAmB,KAAC,6OACnB,gCAA+B,KAAC;IACvD,iBAAmB;;;IALf,AADA,AADA,AADA,AADA,wCAAmB,uCACY,6BACH,2CACO,uDACY;;;;IAQnD,6CAQiD;IAA7C,AADA,yPAAkB,+BAAwB,KAAC,sPACpB,2BAAoB,KAAC;IAChD,iBAAoB;;;IAHhB,AADA,AADA,AADA,AADA,AADA,oDAA+B,0CACG,oBACf,kBACF,sBACI,gBACN;;;IAKnB,qCAIoF;;;IA9B5F,+BAAyB;IACrB,iIAAuB;IAwBrB,AAXF,kIAAkC,yGAWzB;IAOb,iBAAM;;;IA/BF,cAYC;IAZD,iDAYC;IACD,cAiBC;IAjBD,2DAiBC;;;IAtDb,8BAAyC;IAErC,sGAAmB;IAoBjB,AAdF,sGAA4B,gFAcnB;IAmCb,iBAAM;;;IAvDF,cAIC;IAJD,6CAIC;IAED,cAgDC;IAhDD,qDAgDC;;AAyMd,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,qBAAqB;IACpD,GAAG,GAAG,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAChC,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC;IACtC,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC;IAElD,YAAY,GAAG,EAAE,CAAC;IAClB,WAAW,GAAG,KAAK,CAAC;IACpB,WAAW,GAAG,KAAK,CAAC;IACpB,UAAU,GAAG,CAAC,CAAC;IACf,SAAS,GAAG,CAAC,CAAC;IACd,OAAO,GAAmB,EAAE,CAAC;IAC7B,aAAa,GAA6B,EAAE,CAAC;IAC7C,eAAe,GAAuB,EAAE,CAAC;IACzC,eAAe,GAAG,EAAE,CAAC;IACrB;iFAC6E;IAC7E,qBAAqB,GAAG,EAAE,CAAC;IAC3B,0EAA0E;IAC1E,iBAAiB,GAAG,CAAC,CAAC;IACtB,eAAe,GAAG,IAAI,CAAC;IACvB,SAAS,GAAiC,OAAO,CAAC;IAClD,gBAAgB,GAAG,EAAE,CAAC;IACtB,QAAQ,GAAqB,MAAM,CAAC;IACpC,UAAU,GAAoB,EAAE,CAAC;IACjC,cAAc,GAAG,KAAK,CAAC;IAEvB,sEAAsE;IAC9D,UAAU,GAAuB,EAAE,CAAC;IAE5C,wEAAwE;IAChE,QAAQ,GAAa,EAAE,CAAC;IAEhC;;;;;OAKG;IACH,eAAe,GAAG,KAAK,CAAC;IAExB,sFAAsF;IACtF,kBAAkB,GAA8B,EAAE,CAAC;IAEnD,8EAA8E;IACtE,aAAa,GAAwB,IAAI,CAAC;IAE1C,UAAU,GAAG,KAAK,CAAC;IAE3B,8EAA8E;IAC9E,8DAA8D;IAC9D,IAAa,IAAI,CAAC,KAAmB;QACjC,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACnB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,IAAI,CAAC,YAAY,EAAE,CAAC;QACxB,CAAC;IACL,CAAC;IACD,IAAa,IAAI;QACb,OAAO,KAAK,CAAC,IAAI,CAAC;IACtB,CAAC;IAEO,KAAK,CAAC,YAAY;QACtB,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAE1B,+BAA+B;QAC/B,IAAI,CAAC;YACD,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,+BAA+B,CAAC,CAAC;YACpE,MAAM,IAAI,GAAG,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,wBAAwB,CAAC,CAAC;YAC1E,IAAI,IAAI,KAAK,OAAO;gBAAE,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QACvD,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAExB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,aAAa,CAAC;QACxC,IAAI,MAAM,EAAE,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,KAAe,CAAC;QAC/C,CAAC;aAAM,IAAI,MAAM,EAAE,WAAW,EAAE,CAAC;YAC7B,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,WAAqB,CAAC;QACrD,CAAC;QAED,+DAA+D;QAC/D,IAAI,MAAM,EAAE,YAAY,IAAI,IAAI,EAAE,CAAC;YAC/B,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YACvC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC;gBACrC,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;YAC9B,CAAC;QACL,CAAC;QAED,4EAA4E;QAC5E,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,QAAQ,GAAI,MAAM,CAAC,QAAsB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC;QACrG,CAAC;QAED,6EAA6E;QAC7E,+EAA+E;QAC/E,kFAAkF;QAClF,sEAAsE;QACtE,IAAI,MAAM,EAAE,eAAe,KAAK,IAAI,EAAE,CAAC;YACnC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAChC,CAAC;QACD,IAAI,CAAC;YACD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC7E,IAAI,WAAW,KAAK,GAAG,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;gBAChD,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;YAChC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC,CAAC,4CAA4C,CAAC,CAAC;QAExD,wCAAwC;QACxC,IAAI,CAAC,iBAAiB,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;QAEvE,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAChD,CAAC;QAED,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC9B,CAAC;IAEQ,WAAW;QAChB,IAAI,CAAC,aAAa,EAAE,WAAW,EAAE,CAAC;QAClC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,KAAK,CAAC,WAAW,EAAE,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,IAAkB;QAC3C,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,IAAI,IAAI,CAAC,aAAa,EAAE,WAAW,IAAI,QAAQ,CAAW,CAAC;QACnG,OAAO,WAAW,KAAK,EAAE,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,oBAAoB,CAAC,KAAmB;QAC1C,OAAO,8BAA8B,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,KAAa;QAC9B,MAAM,OAAO,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC;QAC9B,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC;YAC5B,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;YACxB,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;IACL,CAAC;IAED,eAAe,CAAC,KAA8B;QAC1C,IAAI,CAAC,aAAa,GAAG;YACjB,GAAG,IAAI,CAAC,aAAa;YACrB,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,cAAc;SACzC,CAAC;QACF,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC9B,CAAC;IAED,gBAAgB;QACZ,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;QACxB,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,iBAAiB,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC9B,CAAC;IAED,iBAAiB,CAAC,OAAe;QAC7B,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC;QAC/B,IAAI,CAAC,iBAAiB,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC1D,IAAI,OAAO,GAAG,IAAI,CAAC,qBAAqB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5D,kFAAkF;YAClF,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC1C,CAAC;aAAM,CAAC;YACJ,qFAAqF;YACrF,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9B,CAAC;IACL,CAAC;IAED;;;;OAIG;IACgB,oBAAoB,CAAC,MAA8B,EAAE,OAAgC;QACpG,MAAM,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC,CAAC;QAC5C,IAAI,YAAY,IAAI,IAAI;YAAE,OAAO;QACjC,MAAM,EAAE,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC;QAChC,IAAI,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI,EAAE,KAAK,IAAI,CAAC,eAAe;YAAE,OAAO;QAE3E,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,IAAI,EAAE,GAAG,IAAI,CAAC,qBAAqB,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACvD,sEAAsE;YACtE,KAAK,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC9B,CAAC;IACL,CAAC;IAED,gBAAgB,CAAC,KAAgC;QAC7C,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACxC,CAAC;IAED,YAAY,CAAC,MAAwB;QACjC,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,SAAS;QACX,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACpB,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC;YACxB,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;YAC1B,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;YAC3B,MAAM,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAChD,CAAC;IACL,CAAC;IAED,iBAAiB;QACb,IAAI,CAAC,eAAe,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC;QAC7C,qBAAqB;QACrB,IAAI,CAAC;YACD,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,+BAA+B,CAAC,CAAC;YACpE,cAAc,CAAC,QAAQ,CAAC,mBAAmB,CACvC,wBAAwB,EACxB,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAC1C,CAAC;QACN,CAAC;QAAC,MAAM,CAAC,CAAC,4CAA4C,CAAC,CAAC;QACxD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,YAAY,CAAC,KAAa;QACtB,IAAI,CAAC,SAAS,GAAG,KAAqC,CAAC;QACvD,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC9B,CAAC;IAED,wBAAwB,CAAC,IAAY;QACjC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC7B,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC9B,CAAC;IAED,WAAW,CAAC,IAAsB;QAC9B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACnB,IAAI,CAAC,eAAe,EAAE,CAAC;QAC3B,CAAC;QACD,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,gBAAgB,CAAC,MAA0B;QACvC,4EAA4E;QAC5E,2EAA2E;IAC/E,CAAC;IAED;;;;;OAKG;IACK,gBAAgB,CAAC,MAAwB;QAC7C,IAAI,MAAM,CAAC,UAAU,KAAK,cAAc,EAAE,CAAC;YACvC,4EAA4E;YAC5E,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,2BAA2B,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;gBACxE,IAAI,CAAC,eAAe,CAAC,wBAAwB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;YACtE,CAAC;YACD,OAAO;QACX,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,CAAC,MAAM,CAAC,QAAQ;YAAE,OAAO;QAEnD,oEAAoE;QACpE,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC7E,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IACrE,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,KAAa;QACrC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC,eAAe,CAAC;QAClD,MAAM,OAAO,GAAkB;YAC3B,KAAK,EAAE,KAAK;YACZ,UAAU,EAAE,EAAE;YACd,aAAa,EAAE,EAAE;YACjB,cAAc,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,CAAC;YAC3D,QAAQ,EAAE,IAAI,CAAC,eAAe,GAAG,GAAG;SACvC,CAAC;QACF,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,QAAQ,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC;QAED,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,IAAI,CAAC,sBAAsB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAC5C,OAAO;QACX,CAAC;QAED,MAAM,QAAQ,GAAmB,MAAM,IAAI,CAAC,aAAa,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAEjF,IAAI,CAAC,UAAU,GAAG,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;QAC1E,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAChD,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC;QACtC,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC;QACpC,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;QAChC,IAAI,CAAC,eAAe,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC;QAE5C,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED;;;;;;;OAOG;IACK,sBAAsB,CAAC,KAAa,EAAE,OAAsB;QAChE,sEAAsE;QACtE,IAAI,CAAC,aAAa,EAAE,WAAW,EAAE,CAAC;QAClC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAE1B,iCAAiC;QACjC,IAAI,CAAC,kBAAkB,GAAG,EAAE,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC;QACrB,IAAI,CAAC,eAAe,GAAG,EAAE,CAAC;QAC1B,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;QACpB,IAAI,CAAC,SAAS,GAAG,CAAC,CAAC;QACnB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC;YACpE,IAAI,EAAE,CAAC,KAAK,EAAE,EAAE;gBACZ,IAAI,KAAK,CAAC,KAAK,KAAK,UAAU,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;oBACnD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC,CAAC;oBACzC,IAAI,CAAC,kBAAkB,GAAG;wBACtB,GAAG,IAAI,CAAC,kBAAkB;wBAC1B;4BACI,IAAI,EAAE,KAAK,CAAC,YAAY;4BACxB,KAAK,EAAE,KAAK;4BACZ,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,CAAC;4BAC/B,KAAK,EAAE,WAAW;yBACrB;qBACJ,CAAC;oBACF,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC5C,IAAI,CAAC,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,UAAU,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;wBAC3F,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;wBAChD,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBAC9B,CAAC;gBACL,CAAC;qBAAM,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;oBAClD,IAAI,CAAC,UAAU,GAAG,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;oBACvE,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;oBAChD,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;oBACvC,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC;oBACnD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBAChE,IAAI,CAAC,kBAAkB,EAAE,CAAC;oBAC1B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;gBAC5B,CAAC;gBACD,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YAC7B,CAAC;YACD,KAAK,EAAE,CAAC,GAAU,EAAE,EAAE;gBAClB,IAAI,CAAC,kBAAkB,GAAG;oBACtB,GAAG,IAAI,CAAC,kBAAkB;oBAC1B,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,GAAG,CAAC,OAAO,EAAE;iBACxF,CAAC;gBACF,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;gBACzB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;gBACxB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YAC7B,CAAC;YACD,QAAQ,EAAE,GAAG,EAAE;gBACX,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;gBACzB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;gBACxB,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACxB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;YAC7B,CAAC;SACJ,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACK,kBAAkB;QACtB,IAAI,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC;QAE9B,oEAAoE;QACpE,IAAI,IAAI,CAAC,eAAe,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,GAAG,GAAG,CAAC;YAC5C,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,QAAQ,CAAC,CAAC;QACvD,CAAC;QAED,qEAAqE;QACrE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QACxD,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;QAEjC,sBAAsB;QACtB,IAAI,IAAI,CAAC,gBAAgB,EAAE,EAAE,CAAC;YAC1B,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC;QAChE,CAAC;QAED,mDAAmD;QACnD,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACxD,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CACzB,CAAC,CAAC,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACvC,CAAC,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACzC,CAAC,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC5C,CAAC,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC5C,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CACtD,CAAC;QACN,CAAC;QAED,OAAO;QACP,QAAQ,IAAI,CAAC,SAAS,EAAE,CAAC;YACrB,KAAK,OAAO;gBACR,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;gBACpF,MAAM;YACV,KAAK,QAAQ;gBACT,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;gBACrG,MAAM;YACV,KAAK,OAAO,CAAC;YACb;gBACI,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;gBACzD,MAAM;QACd,CAAC;QAED,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC;QAC/B,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAEO,gBAAgB;QACpB,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACrE,CAAC;IAEO,oBAAoB,CAAC,MAAwB;QACjD,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAClD,IAAI,YAAY,EAAE,MAAM,EAAE,CAAC;YACvB,MAAM,aAAa,GAAG,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAC/D,MAAM,YAAY,GAAG,YAAY,CAAC,QAAQ,CAAC,mBAAmB,CAAC,IAAI,MAAM,CAAC,UAAU,KAAK,cAAc,CAAC;YACxG,IAAI,CAAC,aAAa,IAAI,CAAC,YAAY;gBAAE,OAAO,KAAK,CAAC;QACtD,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAClD,IAAI,YAAY,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YACpE,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC7C,IAAI,SAAS,EAAE,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACrE,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,MAAM,cAAc,GAAG,IAAI,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;QACvD,IAAI,cAAc,EAAE,MAAM,EAAE,CAAC;YACzB,IAAI,MAAM,CAAC,UAAU,KAAK,cAAc;gBAAE,OAAO,KAAK,CAAC;YACvD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;YAChE,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;QACpD,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAED;;;OAGG;IACH;;;;OAIG;IACK,KAAK,CAAC,eAAe;QACzB,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QAEzB,IAAI,CAAC;YACD,qDAAqD;YACrD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAoB,CAAC;YAC7C,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACnC,MAAM,EAAE,GAAG,IAAI,CAAC,aAAa,CAAC;gBAC9B,MAAM,MAAM,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,UAAU,CAAC,CAAC;gBACnE,IAAI,CAAC,MAAM;oBAAE,SAAS;gBACtB,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;gBAC3C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC3B,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;YAClC,CAAC;YAED,4DAA4D;YAC5D,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkD,CAAC;YAChF,MAAM,EAAE,GAAG,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YAE5D,KAAK,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,IAAI,QAAQ,EAAE,CAAC;gBAC3C,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;oBAAE,SAAS;gBAErC,gEAAgE;gBAChE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;oBAC5C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;oBACzC,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAE1E,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,OAAO,CAAkC;wBAC7D,UAAU,EAAE,kBAAkB;wBAC9B,WAAW,EAAE,eAAe,QAAQ,sBAAsB,QAAQ,GAAG;wBACrE,MAAM,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC;wBACzB,UAAU,EAAE,QAAQ;qBACvB,CAAC,CAAC;oBAEH,IAAI,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;wBACnC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;4BAC/B,MAAM,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC;4BACxB,IAAI,CAAC,OAAO;gCAAE,SAAS;4BACvB,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;4BAC5E,QAAQ,CAAC,KAAK,EAAE,CAAC;4BACjB,QAAQ,CAAC,WAAW,IAAI,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;4BAC1C,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;wBACzC,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;YAED,yCAAyC;YACzC,IAAI,aAAa,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBAC3B,IAAI,CAAC,UAAU,GAAG,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;YAChF,CAAC;iBAAM,CAAC;gBACJ,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC7F,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC;qBAChD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;qBACnD,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;oBACtB,IAAI,EAAE,OAAO;oBACb,MAAM,EAAE,GAAG,CAAC,WAAW,GAAG,SAAS;oBACnC,QAAQ,EAAE,KAAK;oBACf,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,CAAC,WAAW,EAAE;iBAC5E,CAAC,CAAC,CAAC;YACZ,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,IAAI,CAAC,UAAU,GAAG,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QACrF,CAAC;QAED,IAAI,CAAC,cAAc,GAAG,KAAK,CAAC;QAC5B,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,kDAAkD;IAC1C,gBAAgB;QACpB,IAAI,CAAC,iBAAiB,CAAC,eAAe,CAAC,IAAI,EAAE;YACzC,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,IAAI;YACvC,WAAW,EAAE,IAAI,CAAC,UAAU;YAC5B,aAAa,EAAE,IAAI,CAAC,eAAe,CAAC,MAAM;YAC1C,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,iBAAiB,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM;YACrF,UAAU,EAAE,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACpD,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,UAAU;gBAC9B,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC;gBAChC,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC;aACxC,CAAC,CAAC;SACN,CAAC,CAAC;IACP,CAAC;IAED,uEAAuE;IAC/D,kBAAkB;QACtB,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,CAAC,IAAI,EAAE;YAC7C;gBACI,IAAI,EAAE,WAAW;gBACjB,WAAW,EAAE,4CAA4C;gBACzD,eAAe,EAAE;oBACb,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACR,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uBAAuB,EAAE;qBAClE;oBACD,QAAQ,EAAE,CAAC,OAAO,CAAC;iBACtB;gBACD,OAAO,EAAE,KAAK,EAAE,MAA+B,EAAE,EAAE;oBAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;oBAC5C,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;oBAC1B,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;oBAChC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;gBAChG,CAAC;aACJ;YACD;gBACI,IAAI,EAAE,aAAa;gBACnB,WAAW,EAAE,yCAAyC;gBACtD,eAAe,EAAE;oBACb,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACR,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE;qBAC3F;oBACD,QAAQ,EAAE,CAAC,OAAO,CAAC;iBACtB;gBACD,OAAO,EAAE,KAAK,EAAE,MAA+B,EAAE,EAAE;oBAC/C,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;oBAC3C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;gBAClE,CAAC;aACJ;YACD;gBACI,IAAI,EAAE,qBAAqB;gBAC3B,WAAW,EAAE,mEAAmE;gBAChF,eAAe,EAAE;oBACb,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACR,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE;qBAC/E;oBACD,QAAQ,EAAE,CAAC,MAAM,CAAC;iBACrB;gBACD,OAAO,EAAE,KAAK,EAAE,MAA+B,EAAE,EAAE;oBAC/C,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;oBAC5D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,EAAE,CAAC;gBACnF,CAAC;aACJ;YACD;gBACI,IAAI,EAAE,aAAa;gBACnB,WAAW,EAAE,sDAAsD;gBACnE,eAAe,EAAE;oBACb,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACR,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,EAAE,WAAW,EAAE;qBAC9E;oBACD,QAAQ,EAAE,CAAC,MAAM,CAAC;iBACrB;gBACD,OAAO,EAAE,KAAK,EAAE,MAA+B,EAAE,EAAE;oBAC/C,IAAI,CAAC,WAAW,CAAE,MAAM,CAAC,MAAM,CAAsB,IAAI,MAAM,CAAC,CAAC;oBACjE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;gBAChE,CAAC;aACJ;YACD;gBACI,IAAI,EAAE,mBAAmB;gBACzB,WAAW,EAAE,2CAA2C;gBACxD,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;gBACnD,OAAO,EAAE,KAAK,IAAI,EAAE;oBAChB,IAAI,CAAC,iBAAiB,EAAE,CAAC;oBACzB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;gBAC9E,CAAC;aACJ;YACD;gBACI,IAAI,EAAE,iBAAiB;gBACvB,WAAW,EAAE,wDAAwD;gBACrE,eAAe,EAAE;oBACb,IAAI,EAAE,QAAQ;oBACd,UAAU,EAAE;wBACR,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sCAAsC,EAAE;qBACnF;oBACD,QAAQ,EAAE,CAAC,SAAS,CAAC;iBACxB;gBACD,OAAO,EAAE,KAAK,EAAE,MAA+B,EAAE,EAAE;oBAC/C,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBACvD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,eAAe,EAAE,IAAI,CAAC,eAAe,EAAE,aAAa,EAAE,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC1H,CAAC;aACJ;YACD;gBACI,IAAI,EAAE,eAAe;gBACrB,WAAW,EAAE,qCAAqC;gBAClD,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;gBACnD,OAAO,EAAE,KAAK,IAAI,EAAE;oBAChB,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;oBACvB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;gBAChG,CAAC;aACJ;SACJ,CAAC,CAAC;IACP,CAAC;iQA/oBQ,qBAAqB,yBAArB,qBAAqB;6DAArB,qBAAqB;YA3W1B,8BAAiC;YAE7B,uFAAyE;YA8BzE,yFAA4C;YAyD5C,uFAA8C;YAO9C,kGAA8D;YAS9D,uFAA6B;YA4DjC,iBAAM;;YAnKF,cA2BC;YA3BD,wGA2BC;YAGD,cAsDC;YAtDD,uEAsDC;YAGD,cAIC;YAJD,yEAIC;YAGD,cAOC;YAPD,6FAOC;YAED,cA2DC;YA3DD,oDA2DC;;;AAuMA,qBAAqB;IAhXjC,aAAa,CAAC,qBAAqB,EAAE,uBAAuB,CAAC;GAgXjD,qBAAqB,CAgpBjC;;iFAhpBY,qBAAqB;cA/WjC,SAAS;6BACM,KAAK,YACP,4BAA4B,YAC5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAuKT;;kFAqMQ,qBAAqB;AAkpBlC,MAAM,UAAU,yBAAyB;IACrC,0BAA0B;AAC9B,CAAC","sourcesContent":["import { Component, ChangeDetectorRef, inject } from '@angular/core';\nimport { Subscription } from 'rxjs';\nimport { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';\nimport { CompositeKey, Metadata, RunView } from '@memberjunction/core';\nimport { ResourceData } from '@memberjunction/core-entities';\nimport { RegisterClass } from '@memberjunction/global';\nimport { FileOpenService } from '@memberjunction/ng-file-storage';\nimport {\n SearchService,\n SearchResultItem,\n SearchFilter,\n SearchFilterChangeEvent,\n SearchRequest,\n SearchResponse,\n SearchResultSelectedEvent,\n StreamingProviderStatus,\n} from '@memberjunction/ng-search';\nimport { WordCloudItem, WordCloudItemEvent } from '@memberjunction/ng-word-cloud';\n\n@RegisterClass(BaseResourceComponent, 'SearchResultsResource')\n@Component({\n standalone: false,\n selector: 'mj-search-results-resource',\n template: `\n <div class=\"search-results-page\">\n <!-- Streaming status strip — visible while streamScopedSearch is in flight -->\n @if (EnableStreaming && (IsSearching || StreamingProviders.length > 0)) {\n <div class=\"streaming-status-strip\" aria-live=\"polite\">\n @for (p of StreamingProviders; track p.Name) {\n <span class=\"streaming-chip\"\n [class.streaming-chip-error]=\"p.State === 'Error'\"\n [class.streaming-chip-completed]=\"p.State === 'Completed'\">\n @if (p.State === 'Completed') {\n <i class=\"fa-solid fa-check\"></i>\n } @else {\n <i class=\"fa-solid fa-triangle-exclamation\"></i>\n }\n <span class=\"streaming-chip-name\">{{ p.Name }}</span>\n @if (p.State === 'Completed') {\n <span class=\"streaming-chip-count\">{{ p.Count }}</span>\n <span class=\"streaming-chip-time\">{{ p.ElapsedMs }}ms</span>\n } @else if (p.ErrorMessage) {\n <span class=\"streaming-chip-time\">{{ p.ErrorMessage }}</span>\n }\n </span>\n }\n @if (IsSearching) {\n <span class=\"streaming-chip streaming-chip-pending\">\n <i class=\"fa-solid fa-circle-notch fa-spin\"></i>\n <span>Streaming…</span>\n </span>\n }\n </div>\n }\n\n <!-- Header bar (always visible when we have server results) -->\n @if (HasSearched && ServerResultCount > 0) {\n <div class=\"search-header\">\n <div class=\"search-header-left\">\n @if (!ShowFilterPanel) {\n <button class=\"sr-icon-btn\" title=\"Show filters\" (click)=\"ToggleFilterPanel()\">\n <i class=\"fa-solid fa-filter\"></i>\n </button>\n }\n <span class=\"search-meta\">\n {{ FilteredResults.length }} of {{ ServerResultCount }} result{{ ServerResultCount !== 1 ? 's' : '' }}\n for \"{{ CurrentQuery }}\" in {{ ElapsedMs }}ms\n </span>\n </div>\n <div class=\"search-header-right\">\n <!-- Search within results -->\n <div class=\"sr-refine-wrapper\">\n <i class=\"fa-solid fa-filter-list sr-refine-icon\"></i>\n <input class=\"mj-input sr-refine-input\"\n placeholder=\"Filter within results...\"\n [value]=\"ClientFilterText\"\n (input)=\"OnClientFilterTextChange($any($event.target).value)\" />\n @if (ClientFilterText) {\n <button class=\"sr-refine-clear\" (click)=\"OnClientFilterTextChange('')\">\n <i class=\"fa-solid fa-xmark\"></i>\n </button>\n }\n </div>\n <!-- Sort -->\n <select class=\"mj-input sr-sort-select\" [value]=\"SortField\" (change)=\"OnSortChange($any($event.target).value)\">\n <option value=\"score\">Sort: Relevance</option>\n <option value=\"title\">Sort: Name</option>\n <option value=\"entity\">Sort: Entity</option>\n </select>\n <!-- View mode toggle -->\n <div class=\"sr-view-toggle\">\n <button class=\"sr-icon-btn\"\n [class.sr-view-active]=\"ViewMode === 'list'\"\n title=\"List view\"\n (click)=\"SetViewMode('list')\">\n <i class=\"fa-solid fa-list\"></i>\n </button>\n <button class=\"sr-icon-btn\"\n [class.sr-view-active]=\"ViewMode === 'cloud'\"\n title=\"Tag cloud view\"\n (click)=\"SetViewMode('cloud')\">\n <i class=\"fa-solid fa-cloud\"></i>\n </button>\n </div>\n <!-- Refresh -->\n <button class=\"sr-icon-btn\" title=\"Refresh search\" (click)=\"OnRefresh()\" [disabled]=\"IsSearching\">\n <i class=\"fa-solid fa-arrows-rotate\" [class.fa-spin]=\"IsSearching\"></i>\n </button>\n </div>\n </div>\n }\n\n <!-- Initial loading (first search) -->\n @if (IsSearching && ServerResultCount === 0) {\n <div class=\"search-loading\">\n <mj-loading text=\"Searching...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n <!-- No server results -->\n @if (!IsSearching && ServerResultCount === 0 && HasSearched) {\n <mj-empty-state\n class=\"search-no-results\"\n Variant=\"no-results\"\n Icon=\"fa-solid fa-magnifying-glass-minus\"\n Title=\"No results found\"\n Message=\"Try different keywords or broaden your search.\" />\n }\n <!-- Results body (visible when server returned results) -->\n @if (ServerResultCount > 0) {\n <div class=\"search-results-body-wrapper\">\n <!-- Semi-opaque loading overlay for re-queries (slider lowered, etc.) -->\n @if (IsSearching) {\n <div class=\"search-requery-overlay\">\n <mj-loading text=\"Updating results...\" size=\"medium\"></mj-loading>\n </div>\n }\n\n @if (ViewMode === 'cloud') {\n <div class=\"search-cloud-wrapper\">\n @if (IsLoadingCloud) {\n <mj-loading text=\"Loading tag cloud...\" size=\"medium\"></mj-loading>\n } @else {\n <mj-word-cloud\n [Items]=\"CloudItems\"\n [MaxItems]=\"80\"\n ColorMode=\"weight-gradient\"\n [Interactive]=\"true\"\n (ItemClick)=\"OnCloudItemClick($event)\">\n </mj-word-cloud>\n }\n </div>\n } @else {\n <div class=\"search-body\">\n @if (ShowFilterPanel) {\n <mj-search-filter\n [Filters]=\"Filters\"\n [ActiveFilters]=\"ActiveFilters\"\n [ShowRelevanceSlider]=\"true\"\n [MinScorePercent]=\"MinScorePercent\"\n [ServerMinScorePercent]=\"serverMinScorePercent\"\n (FilterChanged)=\"OnFilterChanged($event)\"\n (FiltersCleared)=\"OnFiltersCleared()\"\n (CloseRequested)=\"ToggleFilterPanel()\"\n (MinScoreChanged)=\"OnMinScoreChanged($any($event))\">\n </mj-search-filter>\n }\n @if (FilteredResults.length > 0) {\n <mj-search-results\n [FlatResults]=\"FilteredResults\"\n [HighlightText]=\"ClientFilterText\"\n [ShowScores]=\"true\"\n [ShowTags]=\"true\"\n [ShowSummary]=\"false\"\n [PageSize]=\"20\"\n (ResultSelected)=\"OnResultSelected($event)\"\n (OpenRecordRequested)=\"OnOpenRecord($event)\">\n </mj-search-results>\n } @else {\n <mj-empty-state\n class=\"search-no-results-inline\"\n Variant=\"no-results\"\n Icon=\"fa-solid fa-filter-circle-xmark\"\n Title=\"No results match current filters. Try lowering the minimum relevance.\" />\n }\n </div>\n }\n </div>\n }\n </div>\n `,\n styles: [`\n .search-results-page {\n height: 100%;\n display: flex;\n flex-direction: column;\n background: var(--mj-bg-page);\n overflow: hidden;\n }\n .search-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 8px 24px;\n border-bottom: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n flex-shrink: 0;\n }\n .search-header-left {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .search-header-right {\n display: flex;\n align-items: center;\n gap: 8px;\n }\n .search-meta {\n color: var(--mj-text-muted);\n font-size: 13px;\n white-space: nowrap;\n }\n .sr-icon-btn {\n width: 32px;\n height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n cursor: pointer;\n transition: all 0.15s;\n font-size: 13px;\n flex-shrink: 0;\n }\n .sr-icon-btn:hover { background: var(--mj-bg-surface-hover); color: var(--mj-text-primary); }\n .sr-icon-btn:disabled { opacity: 0.4; cursor: default; }\n .sr-refine-wrapper {\n position: relative;\n display: flex;\n align-items: center;\n }\n .sr-refine-icon {\n position: absolute;\n left: 8px;\n color: var(--mj-text-muted);\n font-size: 12px;\n pointer-events: none;\n }\n .sr-refine-input {\n padding: 5px 28px 5px 26px;\n font-size: 12px;\n width: 180px;\n border-radius: 6px;\n }\n .sr-refine-clear {\n position: absolute;\n right: 6px;\n background: none;\n border: none;\n color: var(--mj-text-muted);\n cursor: pointer;\n font-size: 11px;\n padding: 2px;\n }\n .sr-refine-clear:hover { color: var(--mj-text-primary); }\n .sr-sort-select {\n padding: 5px 24px 5px 8px;\n font-size: 12px;\n border-radius: 6px;\n min-width: 130px;\n }\n .search-loading {\n display: flex;\n justify-content: center;\n padding: 60px 0;\n }\n .search-body {\n flex: 1;\n display: flex;\n gap: 16px;\n padding: 16px 24px;\n overflow: hidden;\n }\n .search-body mj-search-filter {\n flex-shrink: 0;\n width: 240px;\n overflow-y: auto;\n }\n .search-body mj-search-results {\n flex: 1;\n min-width: 0;\n overflow-y: auto;\n }\n .search-results-body-wrapper {\n position: relative;\n flex: 1;\n display: flex;\n flex-direction: column;\n overflow: hidden;\n }\n .search-requery-overlay {\n position: absolute;\n inset: 0;\n background: color-mix(in srgb, var(--mj-bg-page) 75%, transparent);\n z-index: 10;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .search-no-results-inline {\n flex: 1;\n }\n .sr-view-toggle {\n display: flex;\n gap: 2px;\n border: 1px solid var(--mj-border-default);\n border-radius: 6px;\n padding: 2px;\n background: var(--mj-bg-surface-sunken);\n }\n .sr-view-toggle .sr-icon-btn {\n border: none;\n border-radius: 4px;\n width: 28px;\n height: 26px;\n font-size: 12px;\n background: transparent;\n }\n .sr-view-toggle .sr-icon-btn.sr-view-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) 10%, transparent);\n }\n .search-cloud-wrapper {\n flex: 1;\n padding: 24px;\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .search-cloud-wrapper mj-word-cloud {\n width: 100%;\n height: 100%;\n max-height: 600px;\n }\n .streaming-status-strip {\n display: flex;\n flex-wrap: wrap;\n gap: 0.4rem;\n padding: 0.5rem 1rem;\n border-bottom: 1px solid var(--mj-border-subtle);\n }\n .streaming-chip {\n display: inline-flex;\n align-items: center;\n gap: 0.35rem;\n padding: 0.2rem 0.55rem;\n border-radius: 9999px;\n border: 1px solid var(--mj-border-default);\n background: var(--mj-bg-surface);\n color: var(--mj-text-secondary);\n font-size: 0.74rem;\n }\n .streaming-chip-pending {\n color: var(--mj-text-muted);\n }\n .streaming-chip-completed {\n background: color-mix(in srgb, var(--mj-status-success) 10%, var(--mj-bg-surface));\n border-color: var(--mj-status-success-border);\n color: var(--mj-status-success-text);\n }\n .streaming-chip-error {\n background: color-mix(in srgb, var(--mj-status-error) 10%, var(--mj-bg-surface));\n border-color: var(--mj-status-error-border);\n color: var(--mj-status-error-text);\n }\n .streaming-chip-name { font-weight: 500; }\n .streaming-chip-count { opacity: 0.7; }\n .streaming-chip-time { opacity: 0.6; font-size: 0.7rem; }\n `]\n})\nexport class SearchResultsResource extends BaseResourceComponent {\n private cdr = inject(ChangeDetectorRef);\n private searchService = inject(SearchService);\n private fileOpenService = inject(FileOpenService);\n\n CurrentQuery = '';\n IsSearching = false;\n HasSearched = false;\n TotalCount = 0;\n ElapsedMs = 0;\n Filters: SearchFilter[] = [];\n ActiveFilters: Record<string, string[]> = {};\n FilteredResults: SearchResultItem[] = [];\n MinScorePercent = 30;\n /** The MinScore that was sent to the server on the last search. If the user\n * slides below this, we need to re-query the server to get more results. */\n serverMinScorePercent = 30;\n /** How many results the server returned (before client-side filtering) */\n ServerResultCount = 0;\n ShowFilterPanel = true;\n SortField: 'score' | 'title' | 'entity' = 'score';\n ClientFilterText = '';\n ViewMode: 'list' | 'cloud' = 'list';\n CloudItems: WordCloudItem[] = [];\n IsLoadingCloud = false;\n\n /** All results from the last search (before client-side filtering) */\n private allResults: SearchResultItem[] = [];\n\n /** Selected scope IDs from the search bar (empty = unscoped/global). */\n private ScopeIDs: string[] = [];\n\n /**\n * Phase 2C streaming opt-in. Off by default to preserve Phase 1 request-response UX.\n * Enable per-resource via `Data.Configuration.EnableStreaming` or per-tab via the\n * `?stream=1` query param (mostly for engineering verification before flipping the\n * default).\n */\n EnableStreaming = false;\n\n /** Per-provider stream status displayed above results while a stream is in flight. */\n StreamingProviders: StreamingProviderStatus[] = [];\n\n /** Active stream subscription so we can cancel on a new search or destroy. */\n private currentStream: Subscription | null = null;\n\n private dataLoaded = false;\n\n // Override Data setter to trigger search when tab container provides the data\n // (ngOnInit fires before Data is set, so we can't rely on it)\n override set Data(value: ResourceData) {\n super.Data = value;\n if (!this.dataLoaded) {\n this.dataLoaded = true;\n this.loadFromData();\n }\n }\n override get Data(): ResourceData {\n return super.Data;\n }\n\n private async loadFromData(): Promise<void> {\n this.registerAgentTools();\n\n // Load filter panel preference\n try {\n const { UserInfoEngine } = require('@memberjunction/core-entities');\n const pref = UserInfoEngine.Instance.GetSetting('search.showFilterPanel');\n if (pref === 'false') this.ShowFilterPanel = false;\n } catch { /* ignore */ }\n\n const config = this.Data?.Configuration;\n if (config?.Query) {\n this.CurrentQuery = config.Query as string;\n } else if (config?.SearchInput) {\n this.CurrentQuery = config.SearchInput as string;\n }\n\n // Apply min relevance from the search bar dropdown if provided\n if (config?.MinRelevance != null) {\n const mr = Number(config.MinRelevance);\n if (!isNaN(mr) && mr >= 0 && mr <= 100) {\n this.MinScorePercent = mr;\n }\n }\n\n // Carry scope selection from the search bar through into the initial query.\n if (Array.isArray(config?.ScopeIDs)) {\n this.ScopeIDs = (config.ScopeIDs as unknown[]).filter((x): x is string => typeof x === 'string');\n }\n\n // Streaming opt-in: resource config wins; URL query param `?stream=1` is the\n // engineering-verification override (cleared once the default flips). Read the\n // URL directly because the resource's tab config doesn't always mirror URL params\n // into `Configuration.queryParams` at the moment loadFromData() runs.\n if (config?.EnableStreaming === true) {\n this.EnableStreaming = true;\n }\n try {\n const streamParam = new URL(window.location.href).searchParams.get('stream');\n if (streamParam === '1' || streamParam === 'true') {\n this.EnableStreaming = true;\n }\n } catch { /* ignore — server-side render or odd URL */ }\n\n // Sync min relevance to URL query param\n this.UpdateQueryParams({ minRelevance: String(this.MinScorePercent) });\n\n if (this.CurrentQuery) {\n await this.ExecuteSearch(this.CurrentQuery);\n }\n\n this.NotifyLoadComplete();\n }\n\n override ngOnDestroy(): void {\n this.currentStream?.unsubscribe();\n this.currentStream = null;\n super.ngOnDestroy();\n }\n\n async GetResourceDisplayName(data: ResourceData): Promise<string> {\n const query = (data.Configuration?.Query ?? data.Configuration?.SearchInput ?? 'Search') as string;\n return `Search: ${query}`;\n }\n\n async GetResourceIconClass(_data: ResourceData): Promise<string> {\n return 'fa-solid fa-magnifying-glass';\n }\n\n async OnRefineSearch(query: string): Promise<void> {\n const trimmed = query?.trim();\n if (trimmed && trimmed.length >= 2) {\n this.CurrentQuery = trimmed;\n this.ActiveFilters = {};\n await this.ExecuteSearch(trimmed);\n }\n }\n\n OnFilterChanged(event: SearchFilterChangeEvent): void {\n this.ActiveFilters = {\n ...this.ActiveFilters,\n [event.Category]: event.SelectedValues\n };\n this.applyClientFilters();\n }\n\n OnFiltersCleared(): void {\n this.ActiveFilters = {};\n this.MinScorePercent = 30;\n this.UpdateQueryParams({ minRelevance: '30' });\n this.applyClientFilters();\n }\n\n OnMinScoreChanged(percent: number): void {\n this.MinScorePercent = percent;\n this.UpdateQueryParams({ minRelevance: String(percent) });\n if (percent < this.serverMinScorePercent && this.CurrentQuery) {\n // User lowered below what server filtered — need to re-query with lower threshold\n this.ExecuteSearch(this.CurrentQuery);\n } else {\n // User raised or stayed at/above server threshold — client-side filter is sufficient\n this.applyClientFilters();\n }\n }\n\n /**\n * React to ?minRelevance= changes that arrive after initial load — e.g. a Home pin or\n * deep link to a specific relevance threshold, or browser back/forward — when this tab\n * is re-focused rather than freshly loaded (so loadFromData() does not run again).\n */\n protected override OnQueryParamsChanged(params: Record<string, string>, _source: 'popstate' | 'deeplink'): void {\n const minRelevance = params['minRelevance'];\n if (minRelevance == null) return;\n const mr = Number(minRelevance);\n if (isNaN(mr) || mr < 0 || mr > 100 || mr === this.MinScorePercent) return;\n\n this.MinScorePercent = mr;\n if (mr < this.serverMinScorePercent && this.CurrentQuery) {\n // Below what the server filtered — re-query with the lower threshold.\n void this.ExecuteSearch(this.CurrentQuery);\n } else {\n this.applyClientFilters();\n }\n }\n\n OnResultSelected(event: SearchResultSelectedEvent): void {\n this.navigateToResult(event.Result);\n }\n\n OnOpenRecord(result: SearchResultItem): void {\n this.navigateToResult(result);\n }\n\n async OnRefresh(): Promise<void> {\n if (this.CurrentQuery) {\n this.ActiveFilters = {};\n this.MinScorePercent = 30;\n this.ClientFilterText = '';\n await this.ExecuteSearch(this.CurrentQuery);\n }\n }\n\n ToggleFilterPanel(): void {\n this.ShowFilterPanel = !this.ShowFilterPanel;\n // Persist preference\n try {\n const { UserInfoEngine } = require('@memberjunction/core-entities');\n UserInfoEngine.Instance.SetSettingDebounced(\n 'search.showFilterPanel',\n this.ShowFilterPanel ? 'true' : 'false'\n );\n } catch { /* ignore if UserInfoEngine not available */ }\n this.cdr.detectChanges();\n }\n\n OnSortChange(field: string): void {\n this.SortField = field as 'score' | 'title' | 'entity';\n this.applyClientFilters();\n }\n\n OnClientFilterTextChange(text: string): void {\n this.ClientFilterText = text;\n this.applyClientFilters();\n }\n\n SetViewMode(mode: 'list' | 'cloud'): void {\n this.ViewMode = mode;\n if (mode === 'cloud') {\n this.buildCloudItems();\n }\n this.emitAgentContext();\n this.cdr.detectChanges();\n }\n\n OnCloudItemClick(_event: WordCloudItemEvent): void {\n // No-op for now — tag filtering in the filter panel is not yet implemented.\n // Future: clicking a tag could filter results to only those with that tag.\n }\n\n /**\n * Navigate to a search result based on its ResultType discriminator.\n * - entity-record: opens the MJ entity record viewer\n * - storage-file: opens the file via pre-authenticated URL in new tab\n * - content-item: opens the MJ entity record viewer (content items are entity records)\n */\n private navigateToResult(result: SearchResultItem): void {\n if (result.ResultType === 'storage-file') {\n // Try preview first (opens in provider's web viewer), fall back to download\n if (!this.fileOpenService.OpenPreviewFromSearchResult(result.RawMetadata)) {\n this.fileOpenService.OpenFileFromSearchResult(result.RawMetadata);\n }\n return;\n }\n\n if (!result.EntityName || !result.RecordID) return;\n\n // entity-record, content-item, or unset — navigate to entity record\n const pkey = new CompositeKey([{ FieldName: 'ID', Value: result.RecordID }]);\n this.navigationService.OpenEntityRecord(result.EntityName, pkey);\n }\n\n private async ExecuteSearch(query: string): Promise<void> {\n this.IsSearching = true;\n this.HasSearched = false;\n this.cdr.detectChanges();\n\n this.serverMinScorePercent = this.MinScorePercent;\n const request: SearchRequest = {\n Query: query,\n MaxResults: 50,\n ActiveFilters: {},\n IncludeSources: ['vector', 'fulltext', 'entity', 'storage'],\n MinScore: this.MinScorePercent / 100\n };\n if (this.ScopeIDs.length > 0) {\n request.ScopeIDs = [...this.ScopeIDs];\n }\n\n if (this.EnableStreaming) {\n this.executeStreamingSearch(query, request);\n return;\n }\n\n const response: SearchResponse = await this.searchService.ExecuteSearch(request);\n\n this.allResults = [...response.Results].sort((a, b) => b.Score - a.Score);\n this.ServerResultCount = this.allResults.length;\n this.TotalCount = response.TotalCount;\n this.ElapsedMs = response.ElapsedMs;\n this.Filters = response.Filters;\n this.FilteredResults = [...this.allResults];\n\n this.IsSearching = false;\n this.HasSearched = true;\n this.emitAgentContext();\n this.cdr.detectChanges();\n }\n\n /**\n * Phase 2C streaming variant. Subscribes to `streamScopedSearch` and progressively\n * populates the result list as each provider reports back. The 'final' event carries\n * the canonical fused/reranked list, which replaces any partials the user already saw.\n *\n * Cancellation: a new query starts by tearing down the in-flight stream so events\n * from a stale search do not bleed into the current view.\n */\n private executeStreamingSearch(query: string, request: SearchRequest): void {\n // Cancel any prior stream so events from a stale query don't leak in.\n this.currentStream?.unsubscribe();\n this.currentStream = null;\n\n // Reset visible streaming state.\n this.StreamingProviders = [];\n this.allResults = [];\n this.FilteredResults = [];\n this.ServerResultCount = 0;\n this.TotalCount = 0;\n this.ElapsedMs = 0;\n this.cdr.detectChanges();\n\n this.currentStream = this.searchService.StreamSearch(request).subscribe({\n next: (event) => {\n if (event.Phase === 'provider' && event.ProviderName) {\n const count = event.Results?.length ?? 0;\n this.StreamingProviders = [\n ...this.StreamingProviders,\n {\n Name: event.ProviderName,\n Count: count,\n ElapsedMs: event.ElapsedMs ?? 0,\n State: 'Completed',\n },\n ];\n if (event.Results && event.Results.length > 0) {\n this.allResults = [...this.allResults, ...event.Results].sort((a, b) => b.Score - a.Score);\n this.ServerResultCount = this.allResults.length;\n this.applyClientFilters();\n }\n } else if (event.Phase === 'final' && event.Results) {\n this.allResults = [...event.Results].sort((a, b) => b.Score - a.Score);\n this.ServerResultCount = this.allResults.length;\n this.TotalCount = event.Results.length;\n this.ElapsedMs = event.ElapsedMs ?? this.ElapsedMs;\n this.Filters = this.searchService.BuildFilters(this.allResults);\n this.applyClientFilters();\n this.HasSearched = true;\n }\n this.cdr.detectChanges();\n },\n error: (err: Error) => {\n this.StreamingProviders = [\n ...this.StreamingProviders,\n { Name: 'stream', Count: 0, ElapsedMs: 0, State: 'Error', ErrorMessage: err.message },\n ];\n this.IsSearching = false;\n this.HasSearched = true;\n this.cdr.detectChanges();\n },\n complete: () => {\n this.IsSearching = false;\n this.HasSearched = true;\n this.emitAgentContext();\n this.cdr.detectChanges();\n },\n });\n }\n\n /**\n * Apply active filter selections to the full result set.\n */\n private applyClientFilters(): void {\n let results = this.allResults;\n\n // Apply min score filter FIRST (this determines what's \"available\")\n if (this.MinScorePercent > 0) {\n const minScore = this.MinScorePercent / 100;\n results = results.filter(r => r.Score >= minScore);\n }\n\n // Rebuild filters from score-filtered results so counts are accurate\n this.Filters = this.searchService.BuildFilters(results);\n this.TotalCount = results.length;\n\n // Apply facet filters\n if (this.hasActiveFilters()) {\n results = results.filter(r => this.matchesActiveFilters(r));\n }\n\n // Apply client text filter (search within results)\n if (this.ClientFilterText.trim()) {\n const term = this.ClientFilterText.trim().toLowerCase();\n results = results.filter(r =>\n (r.Title?.toLowerCase().includes(term)) ||\n (r.Snippet?.toLowerCase().includes(term)) ||\n (r.EntityName?.toLowerCase().includes(term)) ||\n (r.RecordName?.toLowerCase().includes(term)) ||\n (r.Tags?.some(t => t.toLowerCase().includes(term)))\n );\n }\n\n // Sort\n switch (this.SortField) {\n case 'title':\n results = [...results].sort((a, b) => (a.Title || '').localeCompare(b.Title || ''));\n break;\n case 'entity':\n results = [...results].sort((a, b) => a.EntityName.localeCompare(b.EntityName) || b.Score - a.Score);\n break;\n case 'score':\n default:\n results = [...results].sort((a, b) => b.Score - a.Score);\n break;\n }\n\n this.FilteredResults = results;\n this.emitAgentContext();\n this.cdr.detectChanges();\n }\n\n private hasActiveFilters(): boolean {\n return Object.values(this.ActiveFilters).some(v => v.length > 0);\n }\n\n private matchesActiveFilters(result: SearchResultItem): boolean {\n const entityFilter = this.ActiveFilters['Entity'];\n if (entityFilter?.length) {\n const matchesEntity = entityFilter.includes(result.EntityName);\n const matchesFiles = entityFilter.includes('__storage-files__') && result.ResultType === 'storage-file';\n if (!matchesEntity && !matchesFiles) return false;\n }\n\n const sourceFilter = this.ActiveFilters['Source'];\n if (sourceFilter?.length && !sourceFilter.includes(result.SourceType)) {\n return false;\n }\n\n const tagFilter = this.ActiveFilters['Tags'];\n if (tagFilter?.length && !tagFilter.some(t => result.Tags.includes(t))) {\n return false;\n }\n\n const fileTypeFilter = this.ActiveFilters['File Type'];\n if (fileTypeFilter?.length) {\n if (result.ResultType !== 'storage-file') return false;\n const ext = result.Title?.split('.').pop()?.toUpperCase() ?? '';\n if (!fileTypeFilter.includes(ext)) return false;\n }\n\n return true;\n }\n\n /**\n * Build WordCloudItem[] from search results by extracting entity names and tags,\n * weighted by their frequency across all results.\n */\n /**\n * Build word cloud items from MJ: Tagged Items linked to the search results.\n * Queries the TaggedItem entity for all records in the result set, aggregates\n * tag names by count and weight, and builds WordCloudItem[] for the cloud.\n */\n private async buildCloudItems(): Promise<void> {\n this.IsLoadingCloud = true;\n this.cdr.detectChanges();\n\n try {\n // Group results by entity to build efficient queries\n const byEntity = new Map<string, string[]>();\n for (const result of this.allResults) {\n const md = this.ProviderToUse;\n const entity = md.Entities.find(e => e.Name === result.EntityName);\n if (!entity) continue;\n const list = byEntity.get(entity.ID) || [];\n list.push(result.RecordID);\n byEntity.set(entity.ID, list);\n }\n\n // Query Tagged Items for all record IDs across all entities\n const tagAggregates = new Map<string, { count: number; totalWeight: number }>();\n const rv = RunView.FromMetadataProvider(this.ProviderToUse);\n\n for (const [entityID, recordIDs] of byEntity) {\n if (recordIDs.length === 0) continue;\n\n // Build IN clause (batch in groups of 50 to avoid huge queries)\n for (let i = 0; i < recordIDs.length; i += 50) {\n const batch = recordIDs.slice(i, i + 50);\n const inClause = batch.map(id => `'${id.replace(/'/g, \"''\")}'`).join(',');\n\n const result = await rv.RunView<{ Tag: string; Weight: number }>({\n EntityName: 'MJ: Tagged Items',\n ExtraFilter: `EntityID = '${entityID}' AND RecordID IN (${inClause})`,\n Fields: ['Tag', 'Weight'],\n ResultType: 'simple'\n });\n\n if (result.Success && result.Results) {\n for (const row of result.Results) {\n const tagName = row.Tag;\n if (!tagName) continue;\n const existing = tagAggregates.get(tagName) || { count: 0, totalWeight: 0 };\n existing.count++;\n existing.totalWeight += (row.Weight ?? 1);\n tagAggregates.set(tagName, existing);\n }\n }\n }\n }\n\n // Build cloud items from aggregated tags\n if (tagAggregates.size === 0) {\n this.CloudItems = [{ Text: 'No tags found', Weight: 1, Category: 'empty' }];\n } else {\n const maxWeight = Math.max(...Array.from(tagAggregates.values()).map(v => v.totalWeight), 1);\n this.CloudItems = Array.from(tagAggregates.entries())\n .sort((a, b) => b[1].totalWeight - a[1].totalWeight)\n .map(([tagName, agg]) => ({\n Text: tagName,\n Weight: agg.totalWeight / maxWeight,\n Category: 'tag',\n Metadata: { type: 'tag', count: agg.count, totalWeight: agg.totalWeight }\n }));\n }\n } catch (err) {\n this.CloudItems = [{ Text: 'Error loading tags', Weight: 1, Category: 'error' }];\n }\n\n this.IsLoadingCloud = false;\n this.cdr.detectChanges();\n }\n\n /** Report current search state to the AI agent */\n private emitAgentContext(): void {\n this.navigationService.SetAgentContext(this, {\n CurrentQuery: this.CurrentQuery || null,\n ResultCount: this.TotalCount,\n FilteredCount: this.FilteredResults.length,\n ElapsedMs: this.ElapsedMs,\n HasSearched: this.HasSearched,\n ShowFilterPanel: this.ShowFilterPanel,\n ViewMode: this.ViewMode,\n SortField: this.SortField,\n MinScorePercent: this.MinScorePercent,\n ClientFilterText: this.ClientFilterText,\n ActiveFilterCount: Object.values(this.ActiveFilters).filter(v => v.length > 0).length,\n TopResults: this.FilteredResults.slice(0, 50).map(r => ({\n Title: r.Title || r.RecordName,\n EntityName: r.EntityName,\n RecordID: r.RecordID,\n Score: Math.round(r.Score * 100),\n SourceType: r.SourceType,\n Snippet: r.Snippet?.substring(0, 100)\n })),\n });\n }\n\n /** Register client tools the agent can invoke on the search results */\n private registerAgentTools(): void {\n this.navigationService.SetAgentClientTools(this, [\n {\n Name: 'RunSearch',\n Description: 'Execute a search query and display results',\n ParameterSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'The search query text' }\n },\n required: ['query']\n },\n Handler: async (params: Record<string, unknown>) => {\n const query = String(params['query'] ?? '');\n this.CurrentQuery = query;\n await this.ExecuteSearch(query);\n return { Success: true, Data: { ResultCount: this.TotalCount, ElapsedMs: this.ElapsedMs } };\n }\n },\n {\n Name: 'SortResults',\n Description: 'Change the sort order of search results',\n ParameterSchema: {\n type: 'object',\n properties: {\n field: { type: 'string', enum: ['score', 'title', 'entity'], description: 'Sort field' }\n },\n required: ['field']\n },\n Handler: async (params: Record<string, unknown>) => {\n this.OnSortChange(String(params['field']));\n return { Success: true, Data: { SortField: this.SortField } };\n }\n },\n {\n Name: 'FilterWithinResults',\n Description: 'Filter the current results by a keyword (client-side text filter)',\n ParameterSchema: {\n type: 'object',\n properties: {\n text: { type: 'string', description: 'Filter text (empty string to clear)' }\n },\n required: ['text']\n },\n Handler: async (params: Record<string, unknown>) => {\n this.OnClientFilterTextChange(String(params['text'] ?? ''));\n return { Success: true, Data: { FilteredCount: this.FilteredResults.length } };\n }\n },\n {\n Name: 'SetViewMode',\n Description: 'Switch between list view and tag cloud visualization',\n ParameterSchema: {\n type: 'object',\n properties: {\n mode: { type: 'string', enum: ['list', 'cloud'], description: 'View mode' }\n },\n required: ['mode']\n },\n Handler: async (params: Record<string, unknown>) => {\n this.SetViewMode((params['mode'] as 'list' | 'cloud') ?? 'list');\n return { Success: true, Data: { ViewMode: this.ViewMode } };\n }\n },\n {\n Name: 'ToggleFilterPanel',\n Description: 'Show or hide the filter panel on the left',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => {\n this.ToggleFilterPanel();\n return { Success: true, Data: { ShowFilterPanel: this.ShowFilterPanel } };\n }\n },\n {\n Name: 'SetMinRelevance',\n Description: 'Set the minimum relevance score filter (0-100 percent)',\n ParameterSchema: {\n type: 'object',\n properties: {\n percent: { type: 'number', description: 'Minimum relevance percentage (0-100)' }\n },\n required: ['percent']\n },\n Handler: async (params: Record<string, unknown>) => {\n this.OnMinScoreChanged(Number(params['percent'] ?? 0));\n return { Success: true, Data: { MinScorePercent: this.MinScorePercent, FilteredCount: this.FilteredResults.length } };\n }\n },\n {\n Name: 'RefreshSearch',\n Description: 'Re-execute the current search query',\n ParameterSchema: { type: 'object', properties: {} },\n Handler: async () => {\n await this.OnRefresh();\n return { Success: true, Data: { ResultCount: this.TotalCount, ElapsedMs: this.ElapsedMs } };\n }\n }\n ]);\n }\n}\n\nexport function LoadSearchResultsResource() {\n // Tree-shaking prevention\n}\n"]}
@@ -48,7 +48,12 @@ export declare class AppSwitcherComponent {
48
48
  */
49
49
  openConfigDialog(): void;
50
50
  /**
51
- * Handle when config is saved - reload the app list
51
+ * Handle when config is saved close the dialog.
52
+ * The app list refreshes reactively: each UserApplication save fires a BaseEntity
53
+ * event, UserInfoEngine's debounced refresh (short DebounceTime on the
54
+ * 'MJ: User Applications' config) emits DataChange$, and
55
+ * ApplicationManager.syncFromEngine() pushes the new list to applications$,
56
+ * which the `apps` getter reads. No explicit reload needed here.
52
57
  */
53
58
  onConfigSaved(): void;
54
59
  static ɵfac: i0.ɵɵFactoryDeclaration<AppSwitcherComponent, never>;
@@ -1 +1 @@
1
- {"version":3,"file":"app-switcher.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/header/app-switcher.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAA2B,MAAM,eAAe,CAAC;AAChG,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAC1F,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;;AAG9E;;;GAGG;AACH,qBAMa,oBAAoB;IAYnB,OAAO,CAAC,UAAU;IAXrB,SAAS,EAAE,eAAe,GAAG,IAAI,CAAQ;IACzC,kBAAkB,UAAS;IACpC,qEAAqE;IAC5D,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IAClC,WAAW,uBAA8B;IAErB,eAAe,EAAG,sBAAsB,CAAC;IAEvE,YAAY,UAAS;IACrB,gBAAgB,UAAS;gBAEL,UAAU,EAAE,kBAAkB;IAElD;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;;OAGG;IACH,IAAI,IAAI,IAAI,eAAe,EAAE,CAE5B;IAED;;OAEG;IACH,cAAc,IAAI,IAAI;IAItB;;;OAGG;IACH,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAOrC,8EAA8E;IAC9E,WAAW,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO;IAI1C,+EAA+E;IAC/E,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO;IAI3C;;OAEG;IAEH,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAOvC;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAWxB;;OAEG;IACH,aAAa,IAAI,IAAI;yCArFV,oBAAoB;2CAApB,oBAAoB;CA0FhC"}
1
+ {"version":3,"file":"app-switcher.component.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/header/app-switcher.component.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,YAAY,EAA2B,MAAM,eAAe,CAAC;AAChG,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAC1F,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;;AAG9E;;;GAGG;AACH,qBAMa,oBAAoB;IAYnB,OAAO,CAAC,UAAU;IAXrB,SAAS,EAAE,eAAe,GAAG,IAAI,CAAQ;IACzC,kBAAkB,UAAS;IACpC,qEAAqE;IAC5D,YAAY,EAAE,MAAM,GAAG,IAAI,CAAQ;IAClC,WAAW,uBAA8B;IAErB,eAAe,EAAG,sBAAsB,CAAC;IAEvE,YAAY,UAAS;IACrB,gBAAgB,UAAS;gBAEL,UAAU,EAAE,kBAAkB;IAElD;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;;OAGG;IACH,IAAI,IAAI,IAAI,eAAe,EAAE,CAE5B;IAED;;OAEG;IACH,cAAc,IAAI,IAAI;IAItB;;;OAGG;IACH,SAAS,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI;IAOrC,8EAA8E;IAC9E,WAAW,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO;IAI1C,+EAA+E;IAC/E,YAAY,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO;IAI3C;;OAEG;IAEH,cAAc,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAOvC;;OAEG;IACH,gBAAgB,IAAI,IAAI;IAWxB;;;;;;;OAOG;IACH,aAAa,IAAI,IAAI;yCA1FV,oBAAoB;2CAApB,oBAAoB;CA6FhC"}
@@ -141,11 +141,14 @@ export class AppSwitcherComponent {
141
141
  }, 0);
142
142
  }
143
143
  /**
144
- * Handle when config is saved - reload the app list
144
+ * Handle when config is saved close the dialog.
145
+ * The app list refreshes reactively: each UserApplication save fires a BaseEntity
146
+ * event, UserInfoEngine's debounced refresh (short DebounceTime on the
147
+ * 'MJ: User Applications' config) emits DataChange$, and
148
+ * ApplicationManager.syncFromEngine() pushes the new list to applications$,
149
+ * which the `apps` getter reads. No explicit reload needed here.
145
150
  */
146
151
  onConfigSaved() {
147
- // The ApplicationManager will be refreshed by the dialog
148
- // Force a re-render by triggering change detection
149
152
  this.showConfigDialog = false;
150
153
  }
151
154
  static ɵfac = function AppSwitcherComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || AppSwitcherComponent)(i0.ɵɵdirectiveInject(i1.ApplicationManager)); };
@@ -1 +1 @@
1
- {"version":3,"file":"app-switcher.component.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/header/app-switcher.component.ts","../../../../../src/lib/shell/components/header/app-switcher.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, HostListener, ViewChild } from '@angular/core';\nimport { ApplicationManager, BaseApplication } from '@memberjunction/ng-base-application';\nimport { UserAppConfigComponent } from '@memberjunction/ng-explorer-settings';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n/**\n * App switcher dropdown in the header.\n * Displays current app and allows switching between apps.\n */\n@Component({\n standalone: false,\n selector: 'mj-app-switcher',\n templateUrl: './app-switcher.component.html',\n styleUrls: ['./app-switcher.component.css']\n})\nexport class AppSwitcherComponent {\n @Input() activeApp: BaseApplication | null = null;\n @Input() isViewingSystemTab = false;\n /** ID of the app currently being loaded (shows loading indicator) */\n @Input() loadingAppId: string | null = null;\n @Output() appSelected = new EventEmitter<string>();\n\n @ViewChild('appConfigDialog') appConfigDialog!: UserAppConfigComponent;\n\n showDropdown = false;\n showConfigDialog = false;\n\n constructor(private appManager: ApplicationManager) {}\n\n /**\n * Check if the app switcher should show loading state\n */\n get isLoading(): boolean {\n return this.loadingAppId !== null;\n }\n\n /**\n * Get applications that should appear in the app switcher dropdown\n * (NavigationStyle = 'App Switcher' or 'Both')\n */\n get apps(): BaseApplication[] {\n return this.appManager.GetAppSwitcherApps();\n }\n\n /**\n * Toggle dropdown visibility\n */\n toggleDropdown(): void {\n this.showDropdown = !this.showDropdown;\n }\n\n /**\n * Select an application\n * When viewing a system tab, always emit to allow returning to the app\n */\n selectApp(app: BaseApplication): void {\n this.showDropdown = false;\n if (!UUIDsEqual(app.ID, this.activeApp?.ID) || this.isViewingSystemTab) {\n this.appSelected.emit(app.ID);\n }\n }\n\n /** Case-insensitive UUID check whether an app is the currently active app. */\n IsActiveApp(app: BaseApplication): boolean {\n return UUIDsEqual(app.ID, this.activeApp?.ID);\n }\n\n /** Case-insensitive UUID check whether an app is the one currently loading. */\n IsLoadingApp(app: BaseApplication): boolean {\n return UUIDsEqual(app.ID, this.loadingAppId);\n }\n\n /**\n * Close dropdown when clicking outside\n */\n @HostListener('document:click', ['$event'])\n onClickOutside(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n if (!target.closest('.app-switcher-container') && this.showDropdown) {\n this.showDropdown = false;\n }\n }\n\n /**\n * Open the app configuration dialog\n */\n openConfigDialog(): void {\n this.showDropdown = false;\n this.showConfigDialog = true;\n // Use setTimeout to ensure ViewChild is available\n setTimeout(() => {\n if (this.appConfigDialog) {\n this.appConfigDialog.Open();\n }\n }, 0);\n }\n\n /**\n * Handle when config is saved - reload the app list\n */\n onConfigSaved(): void {\n // The ApplicationManager will be refreshed by the dialog\n // Force a re-render by triggering change detection\n this.showConfigDialog = false;\n }\n}\n","<div class=\"app-switcher-container\" [class.loading]=\"isLoading\">\n <div class=\"app-switcher-button\"\n mjClickable=\"Switch application\"\n testId=\"app-switcher-trigger\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"showDropdown\"\n (click)=\"toggleDropdown()\">\n <!-- Show spinner when loading, otherwise show app icon -->\n @if (isLoading) {\n <i class=\"app-icon loading-spinner fa-solid fa-spinner fa-spin\"></i>\n }\n @if (!isLoading) {\n <i class=\"app-icon\" [class]=\"activeApp?.Icon || 'fa-solid fa-cube'\"\n [style.color]=\"activeApp?.GetColor()\"\n [style.--active-color]=\"activeApp?.GetColor()\"></i>\n }\n <i class=\"dropdown-arrow fa-solid fa-chevron-down\"></i>\n </div>\n\n @if (showDropdown) {\n <div class=\"app-switcher-dropdown\">\n <div class=\"app-switcher-list\">\n @for (app of apps; track app) {\n <div\n class=\"app-switcher-item\"\n [mjClickable]=\"app.Name\"\n [testId]=\"'app-switcher-item-' + app.Name\"\n [attr.aria-current]=\"IsActiveApp(app) ? 'true' : null\"\n [class.active]=\"IsActiveApp(app)\"\n [class.loading]=\"IsLoadingApp(app)\"\n [style.--item-color]=\"app.GetColor()\"\n (click)=\"selectApp(app)\">\n @if (IsLoadingApp(app)) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n }\n @if (!IsLoadingApp(app)) {\n <i [class]=\"app.Icon || 'fa-solid fa-cube'\"></i>\n }\n <span>{{ app.Name }}</span>\n </div>\n }\n </div>\n <!-- Divider + Configure pinned at bottom -->\n <div class=\"app-switcher-divider\"></div>\n <div class=\"app-switcher-item configure-item\" mjClickable=\"Configure applications\" testId=\"app-switcher-configure\" (click)=\"openConfigDialog()\">\n <i class=\"fa-solid fa-gear\"></i>\n <span>Configure...</span>\n </div>\n </div>\n }\n</div>\n\n<!-- App Configuration Dialog -->\n<mj-user-app-config\n #appConfigDialog\n [(ShowDialog)]=\"showConfigDialog\"\n (ConfigSaved)=\"onConfigSaved()\">\n</mj-user-app-config>\n"]}
1
+ {"version":3,"file":"app-switcher.component.js","sourceRoot":"","sources":["../../../../../src/lib/shell/components/header/app-switcher.component.ts","../../../../../src/lib/shell/components/header/app-switcher.component.html"],"names":[],"mappings":"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","sourcesContent":["import { Component, Input, Output, EventEmitter, HostListener, ViewChild } from '@angular/core';\nimport { ApplicationManager, BaseApplication } from '@memberjunction/ng-base-application';\nimport { UserAppConfigComponent } from '@memberjunction/ng-explorer-settings';\nimport { UUIDsEqual } from '@memberjunction/global';\n\n/**\n * App switcher dropdown in the header.\n * Displays current app and allows switching between apps.\n */\n@Component({\n standalone: false,\n selector: 'mj-app-switcher',\n templateUrl: './app-switcher.component.html',\n styleUrls: ['./app-switcher.component.css']\n})\nexport class AppSwitcherComponent {\n @Input() activeApp: BaseApplication | null = null;\n @Input() isViewingSystemTab = false;\n /** ID of the app currently being loaded (shows loading indicator) */\n @Input() loadingAppId: string | null = null;\n @Output() appSelected = new EventEmitter<string>();\n\n @ViewChild('appConfigDialog') appConfigDialog!: UserAppConfigComponent;\n\n showDropdown = false;\n showConfigDialog = false;\n\n constructor(private appManager: ApplicationManager) {}\n\n /**\n * Check if the app switcher should show loading state\n */\n get isLoading(): boolean {\n return this.loadingAppId !== null;\n }\n\n /**\n * Get applications that should appear in the app switcher dropdown\n * (NavigationStyle = 'App Switcher' or 'Both')\n */\n get apps(): BaseApplication[] {\n return this.appManager.GetAppSwitcherApps();\n }\n\n /**\n * Toggle dropdown visibility\n */\n toggleDropdown(): void {\n this.showDropdown = !this.showDropdown;\n }\n\n /**\n * Select an application\n * When viewing a system tab, always emit to allow returning to the app\n */\n selectApp(app: BaseApplication): void {\n this.showDropdown = false;\n if (!UUIDsEqual(app.ID, this.activeApp?.ID) || this.isViewingSystemTab) {\n this.appSelected.emit(app.ID);\n }\n }\n\n /** Case-insensitive UUID check whether an app is the currently active app. */\n IsActiveApp(app: BaseApplication): boolean {\n return UUIDsEqual(app.ID, this.activeApp?.ID);\n }\n\n /** Case-insensitive UUID check whether an app is the one currently loading. */\n IsLoadingApp(app: BaseApplication): boolean {\n return UUIDsEqual(app.ID, this.loadingAppId);\n }\n\n /**\n * Close dropdown when clicking outside\n */\n @HostListener('document:click', ['$event'])\n onClickOutside(event: MouseEvent): void {\n const target = event.target as HTMLElement;\n if (!target.closest('.app-switcher-container') && this.showDropdown) {\n this.showDropdown = false;\n }\n }\n\n /**\n * Open the app configuration dialog\n */\n openConfigDialog(): void {\n this.showDropdown = false;\n this.showConfigDialog = true;\n // Use setTimeout to ensure ViewChild is available\n setTimeout(() => {\n if (this.appConfigDialog) {\n this.appConfigDialog.Open();\n }\n }, 0);\n }\n\n /**\n * Handle when config is saved close the dialog.\n * The app list refreshes reactively: each UserApplication save fires a BaseEntity\n * event, UserInfoEngine's debounced refresh (short DebounceTime on the\n * 'MJ: User Applications' config) emits DataChange$, and\n * ApplicationManager.syncFromEngine() pushes the new list to applications$,\n * which the `apps` getter reads. No explicit reload needed here.\n */\n onConfigSaved(): void {\n this.showConfigDialog = false;\n }\n}\n","<div class=\"app-switcher-container\" [class.loading]=\"isLoading\">\n <div class=\"app-switcher-button\"\n mjClickable=\"Switch application\"\n testId=\"app-switcher-trigger\"\n [attr.aria-haspopup]=\"true\"\n [attr.aria-expanded]=\"showDropdown\"\n (click)=\"toggleDropdown()\">\n <!-- Show spinner when loading, otherwise show app icon -->\n @if (isLoading) {\n <i class=\"app-icon loading-spinner fa-solid fa-spinner fa-spin\"></i>\n }\n @if (!isLoading) {\n <i class=\"app-icon\" [class]=\"activeApp?.Icon || 'fa-solid fa-cube'\"\n [style.color]=\"activeApp?.GetColor()\"\n [style.--active-color]=\"activeApp?.GetColor()\"></i>\n }\n <i class=\"dropdown-arrow fa-solid fa-chevron-down\"></i>\n </div>\n\n @if (showDropdown) {\n <div class=\"app-switcher-dropdown\">\n <div class=\"app-switcher-list\">\n @for (app of apps; track app) {\n <div\n class=\"app-switcher-item\"\n [mjClickable]=\"app.Name\"\n [testId]=\"'app-switcher-item-' + app.Name\"\n [attr.aria-current]=\"IsActiveApp(app) ? 'true' : null\"\n [class.active]=\"IsActiveApp(app)\"\n [class.loading]=\"IsLoadingApp(app)\"\n [style.--item-color]=\"app.GetColor()\"\n (click)=\"selectApp(app)\">\n @if (IsLoadingApp(app)) {\n <i class=\"fa-solid fa-spinner fa-spin\"></i>\n }\n @if (!IsLoadingApp(app)) {\n <i [class]=\"app.Icon || 'fa-solid fa-cube'\"></i>\n }\n <span>{{ app.Name }}</span>\n </div>\n }\n </div>\n <!-- Divider + Configure pinned at bottom -->\n <div class=\"app-switcher-divider\"></div>\n <div class=\"app-switcher-item configure-item\" mjClickable=\"Configure applications\" testId=\"app-switcher-configure\" (click)=\"openConfigDialog()\">\n <i class=\"fa-solid fa-gear\"></i>\n <span>Configure...</span>\n </div>\n </div>\n }\n</div>\n\n<!-- App Configuration Dialog -->\n<mj-user-app-config\n #appConfigDialog\n [(ShowDialog)]=\"showConfigDialog\"\n (ConfigSaved)=\"onConfigSaved()\">\n</mj-user-app-config>\n"]}
@@ -1,5 +1,5 @@
1
1
  import { ComponentRef, ApplicationRef } from '@angular/core';
2
- import { BaseResourceComponent } from '@memberjunction/ng-shared';
2
+ import { BaseResourceComponent, NavigationService } from '@memberjunction/ng-shared';
3
3
  import { ResourceData } from '@memberjunction/core-entities';
4
4
  /**
5
5
  * Metadata about a cached component
@@ -44,6 +44,7 @@ export interface CachedComponentInfo {
44
44
  */
45
45
  export declare class ComponentCacheManager {
46
46
  private appRef;
47
+ private navigationService?;
47
48
  private cache;
48
49
  /**
49
50
  * Maximum number of detached (not currently visible) components to keep
@@ -51,7 +52,14 @@ export declare class ComponentCacheManager {
51
52
  * evicted. Set to 0 to disable eviction (legacy behavior). Default: 20.
52
53
  */
53
54
  static MaxDetachedComponents: number;
54
- constructor(appRef: ApplicationRef);
55
+ /**
56
+ * @param navigationService Optional — when provided, the cache manager keeps the AI agent's live
57
+ * client-tool set in sync with the attached surface: it replays a reattached component's tools
58
+ * ({@link NavigationService.NotifyResourceReattached}) and clears them on detach
59
+ * ({@link NavigationService.NotifyResourceDetached}), since cached components don't re-run
60
+ * `ngAfterViewInit`. Centralizing it here covers BOTH single-resource and Golden Layout paths.
61
+ */
62
+ constructor(appRef: ApplicationRef, navigationService?: NavigationService | undefined);
55
63
  /**
56
64
  * Generate a unique cache key from resource identity.
57
65
  * This is the ONE canonical key format used by ALL cache operations.
@@ -1 +1 @@
1
- {"version":3,"file":"component-cache-manager.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/component-cache-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"component-cache-manager.d.ts","sourceRoot":"","sources":["../../../../../src/lib/shell/components/tabs/component-cache-manager.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,7 @@
17
17
  */
18
18
  export class ComponentCacheManager {
19
19
  appRef;
20
+ navigationService;
20
21
  cache = new Map();
21
22
  /**
22
23
  * Maximum number of detached (not currently visible) components to keep
@@ -24,8 +25,16 @@ export class ComponentCacheManager {
24
25
  * evicted. Set to 0 to disable eviction (legacy behavior). Default: 20.
25
26
  */
26
27
  static MaxDetachedComponents = 20;
27
- constructor(appRef) {
28
+ /**
29
+ * @param navigationService Optional — when provided, the cache manager keeps the AI agent's live
30
+ * client-tool set in sync with the attached surface: it replays a reattached component's tools
31
+ * ({@link NavigationService.NotifyResourceReattached}) and clears them on detach
32
+ * ({@link NavigationService.NotifyResourceDetached}), since cached components don't re-run
33
+ * `ngAfterViewInit`. Centralizing it here covers BOTH single-resource and Golden Layout paths.
34
+ */
35
+ constructor(appRef, navigationService) {
28
36
  this.appRef = appRef;
37
+ this.navigationService = navigationService;
29
38
  }
30
39
  /**
31
40
  * Generate a unique cache key from resource identity.
@@ -105,6 +114,9 @@ export class ComponentCacheManager {
105
114
  info.isAttached = true;
106
115
  info.attachedToTabId = tabId;
107
116
  info.lastUsed = new Date();
117
+ // Replay this surface's agent client tools to the AI agent on reattach (cached components keep
118
+ // their instance but never re-run ngAfterViewInit, so they don't re-register on their own).
119
+ this.navigationService?.NotifyResourceReattached(info.componentRef.instance);
108
120
  }
109
121
  }
110
122
  /**
@@ -121,6 +133,9 @@ export class ComponentCacheManager {
121
133
  info.isAttached = false;
122
134
  info.attachedToTabId = null;
123
135
  info.lastUsed = new Date();
136
+ // Clear this surface's agent client tools on detach so the previous app's tools aren't offered to
137
+ // the AI agent on the next surface. NotifyResourceReattached replays them if the user returns.
138
+ this.navigationService?.NotifyResourceDetached(info.componentRef.instance);
124
139
  this.EvictIfNeeded();
125
140
  return info;
126
141
  }
@@ -183,6 +198,8 @@ export class ComponentCacheManager {
183
198
  .sort((a, b) => a[1].lastUsed.getTime() - b[1].lastUsed.getTime());
184
199
  while (detached.length > ComponentCacheManager.MaxDetachedComponents) {
185
200
  const [key, info] = detached.shift();
201
+ // Drop the destroyed component's cached agent tools so the registry doesn't retain a dead ref.
202
+ this.navigationService?.ForgetResource(info.componentRef.instance);
186
203
  this.appRef.detachView(info.componentRef.hostView);
187
204
  info.componentRef.destroy();
188
205
  this.cache.delete(key);
@@ -205,6 +222,7 @@ export class ComponentCacheManager {
205
222
  const info = this.cache.get(key);
206
223
  if (!info)
207
224
  return;
225
+ this.navigationService?.ForgetResource(info.componentRef.instance);
208
226
  this.appRef.detachView(info.componentRef.hostView);
209
227
  info.componentRef.destroy();
210
228
  this.cache.delete(key);