@memberjunction/ng-shared 6.1.0-edge.0 → 6.1.0-edge.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"home-pin.service.d.ts","sourceRoot":"","sources":["../../src/lib/home-pin.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAGvC,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;;AAKxF;;;;;GAKG;AACH,qBACa,iBAAiB;IAC5B,+FAA+F;IAC/F,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,4BAA4B,CAAQ;IAE5D;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAQ;IAEnD,mDAAmD;IACnD,SAAgB,KAAK,uCAAgD;IAErE,OAAO,CAAC,MAAM,CAAS;IAMvB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB/B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IASjC;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO;IAkBvC;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM9B;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAQzD;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,iBAAiB,EAAE,GAAG,IAAI;IAS5C;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;IAIxE;;OAEG;IACH,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,iBAAiB,GAAG,SAAS;IAQ7F;;OAEG;IACH,gBAAgB,IAAI,iBAAiB,EAAE;IAIvC;;OAEG;IACH,SAAS,IAAI,MAAM,EAAE;IAcrB;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,EAAE;IAUtD;;;;;OAKG;IACG,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IA4BzE;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAgCnB,OAAO,CAAC,eAAe;IA+CvB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,UAAU;yCAvSP,iBAAiB;6CAAjB,iBAAiB;CAmT7B"}
1
+ {"version":3,"file":"home-pin.service.d.ts","sourceRoot":"","sources":["../../src/lib/home-pin.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,MAAM,CAAC;AAGvC,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;;AAKxF;;;;;GAKG;AACH,qBACa,iBAAiB;IAC5B,+FAA+F;IAC/F,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,4BAA4B,CAAQ;IAE5D;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAQ;IAEnD,mDAAmD;IACnD,SAAgB,KAAK,uCAAgD;IAErE,OAAO,CAAC,MAAM,CAAS;IAMvB;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAgB/B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IASjC;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO;IAkBvC;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAM9B;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAQzD;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,iBAAiB,EAAE,GAAG,IAAI;IAS5C;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO;IAIxE;;OAEG;IACH,OAAO,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,iBAAiB,GAAG,SAAS;IAQ7F;;OAEG;IACH,gBAAgB,IAAI,iBAAiB,EAAE;IAIvC;;OAEG;IACH,SAAS,IAAI,MAAM,EAAE;IAcrB;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,EAAE;IAUtD;;;;;OAKG;IACG,gBAAgB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IA4BzE;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAgCnB,OAAO,CAAC,eAAe;IA6CvB,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,UAAU;yCArSP,iBAAiB;6CAAjB,iBAAiB;CAiT7B"}
@@ -228,8 +228,6 @@ export class HomeAppPinService {
228
228
  return pin.Configuration['viewId'] === config['viewId'];
229
229
  case 'Queries':
230
230
  return pin.Configuration['queryId'] === config['queryId'];
231
- case 'Reports':
232
- return pin.Configuration['reportId'] === config['reportId'];
233
231
  case 'Records':
234
232
  return pin.Configuration['Entity'] === config['Entity']
235
233
  && pin.Configuration['recordId'] === config['recordId'];
@@ -1 +1 @@
1
- {"version":3,"file":"home-pin.service.js","sourceRoot":"","sources":["../../src/lib/home-pin.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { toJpeg } from 'html-to-image';\nimport { HomeAppPinnedItem, HomeAppPinInput, HomeAppPinUpdate } from './home-pin.types';\n\n/** UserSettings key for persisting pins */\nconst PINS_SETTING_KEY = 'HomeApp.PinnedItems';\n\n/**\n * Service for managing pinned items on the Home dashboard.\n *\n * All pin state is stored as a JSON blob in UserSettings via UserInfoEngine.\n * Uses debounced saving to avoid excessive DB writes during edit mode operations.\n */\n@Injectable({ providedIn: 'root' })\nexport class HomeAppPinService {\n /** Max time to wait for a thumbnail capture before giving up and pinning without a preview. */\n private static readonly THUMBNAIL_CAPTURE_TIMEOUT_MS = 4000;\n\n /**\n * Max DOM node count we'll attempt to rasterize. Above this, html-to-image's synchronous\n * clone/inline step blocks the main thread long enough to freeze the UI, so we skip the\n * (decorative) preview instead. Tuned to comfortably allow typical dashboards/forms while\n * excluding heavy grid/map views like the Data Explorer.\n */\n private static readonly THUMBNAIL_MAX_NODES = 3000;\n\n /** Observable of current pins (for reactive UI) */\n public readonly Pins$ = new BehaviorSubject<HomeAppPinnedItem[]>([]);\n\n private loaded = false;\n\n // =============================================\n // LOADING\n // =============================================\n\n /**\n * Load pins from UserSettings. Safe to call multiple times (loads only once).\n */\n async LoadPins(): Promise<void> {\n if (this.loaded) return;\n\n const raw = UserInfoEngine.Instance.GetSetting(PINS_SETTING_KEY);\n if (raw) {\n try {\n const pins = JSON.parse(raw) as HomeAppPinnedItem[];\n this.Pins$.next(this.sortPins(pins));\n } catch (err) {\n console.warn('HomeAppPinService: Failed to parse saved pins, starting fresh', err);\n this.Pins$.next([]);\n }\n }\n this.loaded = true;\n }\n\n /**\n * Force reload from UserSettings (e.g. after external changes)\n */\n async ReloadPins(): Promise<void> {\n this.loaded = false;\n await this.LoadPins();\n }\n\n // =============================================\n // CRUD OPERATIONS\n // =============================================\n\n /**\n * Add a new pin. Returns false if a duplicate already exists.\n */\n AddPin(input: HomeAppPinInput): boolean {\n if (this.IsPinned(input.ResourceType, input.Configuration)) {\n return false;\n }\n\n const pins = [...this.Pins$.value];\n const newPin: HomeAppPinnedItem = {\n ...input,\n Id: this.generateId(),\n Sequence: pins.length,\n PinnedAt: new Date().toISOString()\n };\n\n pins.push(newPin);\n this.updateAndSave(pins);\n return true;\n }\n\n /**\n * Remove a pin by ID\n */\n RemovePin(pinId: string): void {\n const pins = this.Pins$.value.filter(p => p.Id !== pinId);\n this.resequence(pins);\n this.updateAndSave(pins);\n }\n\n /**\n * Update pin properties (name, description, icon, group, thumbnail)\n */\n UpdatePin(pinId: string, updates: HomeAppPinUpdate): void {\n const pins = this.Pins$.value.map(p => {\n if (p.Id !== pinId) return p;\n return { ...p, ...updates };\n });\n this.updateAndSave(pins);\n }\n\n /**\n * Reorder pins. Accepts full reordered array with updated Sequence values.\n */\n ReorderPins(pins: HomeAppPinnedItem[]): void {\n this.resequence(pins);\n this.updateAndSave(pins);\n }\n\n // =============================================\n // DUPLICATE DETECTION\n // =============================================\n\n /**\n * Check if a resource is already pinned\n */\n IsPinned(resourceType: string, config: Record<string, unknown>): boolean {\n return this.Pins$.value.some(pin => this.matchesResource(pin, resourceType, config));\n }\n\n /**\n * Find the pin for a given resource, if it exists\n */\n FindPin(resourceType: string, config: Record<string, unknown>): HomeAppPinnedItem | undefined {\n return this.Pins$.value.find(pin => this.matchesResource(pin, resourceType, config));\n }\n\n // =============================================\n // HELPERS\n // =============================================\n\n /**\n * Get ungrouped pins (Group is null/undefined/empty)\n */\n GetUngroupedPins(): HomeAppPinnedItem[] {\n return this.Pins$.value.filter(p => !p.Group);\n }\n\n /**\n * Get unique group names in display order (ordered by lowest Sequence in group)\n */\n GetGroups(): string[] {\n const groupMinSeq = new Map<string, number>();\n for (const pin of this.Pins$.value) {\n if (!pin.Group) continue;\n const current = groupMinSeq.get(pin.Group);\n if (current === undefined || pin.Sequence < current) {\n groupMinSeq.set(pin.Group, pin.Sequence);\n }\n }\n return [...groupMinSeq.entries()]\n .sort((a, b) => a[1] - b[1])\n .map(([name]) => name);\n }\n\n /**\n * Get pins in a specific group\n */\n GetPinsInGroup(groupName: string): HomeAppPinnedItem[] {\n return this.Pins$.value\n .filter(p => p.Group === groupName)\n .sort((a, b) => a.Sequence - b.Sequence);\n }\n\n // =============================================\n // THUMBNAIL CAPTURE\n // =============================================\n\n /**\n * Capture a thumbnail of a DOM element using html-to-image.\n * Uses SVG foreignObject so the browser's own CSS engine handles\n * modern features like color-mix() that html2canvas can't parse.\n * Returns a base64 JPEG data URL (~5-15KB) or undefined on failure.\n */\n async CaptureThumbnail(element: HTMLElement): Promise<string | undefined> {\n try {\n if (element.clientWidth === 0 || element.clientHeight === 0) {\n return undefined;\n }\n // Bail on very large DOM trees. html-to-image clones and inlines the ENTIRE subtree\n // SYNCHRONOUSLY before it ever yields, so a heavy view (e.g. the Data Explorer's grid\n // + map) blocks the main thread for seconds — long enough to freeze the UI, and the\n // timeout below (setTimeout-based) can't even fire while the thread is blocked. A\n // thumbnail is best-effort decoration, so skip rather than jank the app.\n const nodeCount = element.getElementsByTagName('*').length;\n if (nodeCount > HomeAppPinService.THUMBNAIL_MAX_NODES) {\n return undefined;\n }\n // Race against a timeout as a secondary guard for the async portion: toJpeg() can also\n // hang on content with cross-origin resources it must re-fetch (e.g. Leaflet map tiles),\n // where the inlining/canvas step never resolves. Don't cacheBust — re-fetching every\n // image is what tends to stall, and a slightly cached preview is fine.\n const capture = toJpeg(element, {\n quality: 0.6,\n pixelRatio: 0.2,\n });\n return await this.withTimeout(capture, HomeAppPinService.THUMBNAIL_CAPTURE_TIMEOUT_MS);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Resolve to `undefined` if the given promise hasn't settled within `ms`.\n * Note: this does not cancel the underlying work (toJpeg is not cancelable),\n * it just stops the pin flow from waiting on it.\n */\n private withTimeout(promise: Promise<string>, ms: number): Promise<string | undefined> {\n return new Promise<string | undefined>((resolve) => {\n let settled = false;\n const timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n resolve(undefined);\n }\n }, ms);\n promise.then(\n (value) => {\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n resolve(value);\n }\n },\n () => {\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n resolve(undefined);\n }\n }\n );\n });\n }\n\n // =============================================\n // PRIVATE\n // =============================================\n\n private matchesResource(pin: HomeAppPinnedItem, resourceType: string, config: Record<string, unknown>): boolean {\n if (pin.ResourceType !== resourceType) return false;\n switch (resourceType) {\n case 'Dashboards':\n return pin.Configuration['dashboardId'] === config['dashboardId'];\n case 'User Views':\n return pin.Configuration['viewId'] === config['viewId'];\n case 'Queries':\n return pin.Configuration['queryId'] === config['queryId'];\n case 'Reports':\n return pin.Configuration['reportId'] === config['reportId'];\n case 'Records':\n return pin.Configuration['Entity'] === config['Entity']\n && pin.Configuration['recordId'] === config['recordId'];\n case 'Custom': {\n // Match by app name + nav item name + route — never use appId or driverClass\n // Include route to differentiate same nav item with different URL paths\n const sameApp = pin.Configuration['appName'] === config['appName'];\n const sameNav = pin.Configuration['navItemName'] === config['navItemName'];\n const pinRoute = pin.Configuration['route'] as string || '';\n const configRoute = config['route'] as string || '';\n const sameRoute = pinRoute === configRoute;\n // Also compare queryParams if present\n const pinQP = JSON.stringify(pin.Configuration['queryParams'] || {});\n const configQP = JSON.stringify(config['queryParams'] || {});\n const sameQP = pinQP === configQP;\n return sameApp && sameNav && sameRoute && sameQP;\n }\n case 'Actions': {\n // A pinned Action is unique per (actionId + preset-params + runtime-params + title).\n // Two pins targeting the same action with different preset configs are allowed —\n // e.g. \"Weekly Report — Sales\" vs. \"Weekly Report — Ops\" both pin \"Run Report\".\n if (pin.Configuration['actionId'] !== config['actionId']) return false;\n const pinPreset = JSON.stringify(pin.Configuration['presetParams'] ?? {});\n const configPreset = JSON.stringify(config['presetParams'] ?? {});\n const pinRuntime = JSON.stringify(pin.Configuration['runtimeParamNames'] ?? []);\n const configRuntime = JSON.stringify(config['runtimeParamNames'] ?? []);\n const samePreset = pinPreset === configPreset;\n const sameRuntime = pinRuntime === configRuntime;\n const sameTitle = pin.DisplayName === (config['displayName'] ?? pin.DisplayName);\n return samePreset && sameRuntime && sameTitle;\n }\n default:\n return false;\n }\n }\n\n private updateAndSave(pins: HomeAppPinnedItem[]): void {\n const sorted = this.sortPins(pins);\n this.Pins$.next(sorted);\n UserInfoEngine.Instance.SetSettingDebounced(\n PINS_SETTING_KEY,\n JSON.stringify(sorted)\n );\n }\n\n private sortPins(pins: HomeAppPinnedItem[]): HomeAppPinnedItem[] {\n return [...pins].sort((a, b) => a.Sequence - b.Sequence);\n }\n\n private resequence(pins: HomeAppPinnedItem[]): void {\n pins.forEach((pin, i) => { pin.Sequence = i; });\n }\n\n private generateId(): string {\n // Crypto.randomUUID is available in modern browsers\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Fallback for older browsers\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n}\n"]}
1
+ {"version":3,"file":"home-pin.service.js","sourceRoot":"","sources":["../../src/lib/home-pin.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs';\nimport { UserInfoEngine } from '@memberjunction/core-entities';\nimport { toJpeg } from 'html-to-image';\nimport { HomeAppPinnedItem, HomeAppPinInput, HomeAppPinUpdate } from './home-pin.types';\n\n/** UserSettings key for persisting pins */\nconst PINS_SETTING_KEY = 'HomeApp.PinnedItems';\n\n/**\n * Service for managing pinned items on the Home dashboard.\n *\n * All pin state is stored as a JSON blob in UserSettings via UserInfoEngine.\n * Uses debounced saving to avoid excessive DB writes during edit mode operations.\n */\n@Injectable({ providedIn: 'root' })\nexport class HomeAppPinService {\n /** Max time to wait for a thumbnail capture before giving up and pinning without a preview. */\n private static readonly THUMBNAIL_CAPTURE_TIMEOUT_MS = 4000;\n\n /**\n * Max DOM node count we'll attempt to rasterize. Above this, html-to-image's synchronous\n * clone/inline step blocks the main thread long enough to freeze the UI, so we skip the\n * (decorative) preview instead. Tuned to comfortably allow typical dashboards/forms while\n * excluding heavy grid/map views like the Data Explorer.\n */\n private static readonly THUMBNAIL_MAX_NODES = 3000;\n\n /** Observable of current pins (for reactive UI) */\n public readonly Pins$ = new BehaviorSubject<HomeAppPinnedItem[]>([]);\n\n private loaded = false;\n\n // =============================================\n // LOADING\n // =============================================\n\n /**\n * Load pins from UserSettings. Safe to call multiple times (loads only once).\n */\n async LoadPins(): Promise<void> {\n if (this.loaded) return;\n\n const raw = UserInfoEngine.Instance.GetSetting(PINS_SETTING_KEY);\n if (raw) {\n try {\n const pins = JSON.parse(raw) as HomeAppPinnedItem[];\n this.Pins$.next(this.sortPins(pins));\n } catch (err) {\n console.warn('HomeAppPinService: Failed to parse saved pins, starting fresh', err);\n this.Pins$.next([]);\n }\n }\n this.loaded = true;\n }\n\n /**\n * Force reload from UserSettings (e.g. after external changes)\n */\n async ReloadPins(): Promise<void> {\n this.loaded = false;\n await this.LoadPins();\n }\n\n // =============================================\n // CRUD OPERATIONS\n // =============================================\n\n /**\n * Add a new pin. Returns false if a duplicate already exists.\n */\n AddPin(input: HomeAppPinInput): boolean {\n if (this.IsPinned(input.ResourceType, input.Configuration)) {\n return false;\n }\n\n const pins = [...this.Pins$.value];\n const newPin: HomeAppPinnedItem = {\n ...input,\n Id: this.generateId(),\n Sequence: pins.length,\n PinnedAt: new Date().toISOString()\n };\n\n pins.push(newPin);\n this.updateAndSave(pins);\n return true;\n }\n\n /**\n * Remove a pin by ID\n */\n RemovePin(pinId: string): void {\n const pins = this.Pins$.value.filter(p => p.Id !== pinId);\n this.resequence(pins);\n this.updateAndSave(pins);\n }\n\n /**\n * Update pin properties (name, description, icon, group, thumbnail)\n */\n UpdatePin(pinId: string, updates: HomeAppPinUpdate): void {\n const pins = this.Pins$.value.map(p => {\n if (p.Id !== pinId) return p;\n return { ...p, ...updates };\n });\n this.updateAndSave(pins);\n }\n\n /**\n * Reorder pins. Accepts full reordered array with updated Sequence values.\n */\n ReorderPins(pins: HomeAppPinnedItem[]): void {\n this.resequence(pins);\n this.updateAndSave(pins);\n }\n\n // =============================================\n // DUPLICATE DETECTION\n // =============================================\n\n /**\n * Check if a resource is already pinned\n */\n IsPinned(resourceType: string, config: Record<string, unknown>): boolean {\n return this.Pins$.value.some(pin => this.matchesResource(pin, resourceType, config));\n }\n\n /**\n * Find the pin for a given resource, if it exists\n */\n FindPin(resourceType: string, config: Record<string, unknown>): HomeAppPinnedItem | undefined {\n return this.Pins$.value.find(pin => this.matchesResource(pin, resourceType, config));\n }\n\n // =============================================\n // HELPERS\n // =============================================\n\n /**\n * Get ungrouped pins (Group is null/undefined/empty)\n */\n GetUngroupedPins(): HomeAppPinnedItem[] {\n return this.Pins$.value.filter(p => !p.Group);\n }\n\n /**\n * Get unique group names in display order (ordered by lowest Sequence in group)\n */\n GetGroups(): string[] {\n const groupMinSeq = new Map<string, number>();\n for (const pin of this.Pins$.value) {\n if (!pin.Group) continue;\n const current = groupMinSeq.get(pin.Group);\n if (current === undefined || pin.Sequence < current) {\n groupMinSeq.set(pin.Group, pin.Sequence);\n }\n }\n return [...groupMinSeq.entries()]\n .sort((a, b) => a[1] - b[1])\n .map(([name]) => name);\n }\n\n /**\n * Get pins in a specific group\n */\n GetPinsInGroup(groupName: string): HomeAppPinnedItem[] {\n return this.Pins$.value\n .filter(p => p.Group === groupName)\n .sort((a, b) => a.Sequence - b.Sequence);\n }\n\n // =============================================\n // THUMBNAIL CAPTURE\n // =============================================\n\n /**\n * Capture a thumbnail of a DOM element using html-to-image.\n * Uses SVG foreignObject so the browser's own CSS engine handles\n * modern features like color-mix() that html2canvas can't parse.\n * Returns a base64 JPEG data URL (~5-15KB) or undefined on failure.\n */\n async CaptureThumbnail(element: HTMLElement): Promise<string | undefined> {\n try {\n if (element.clientWidth === 0 || element.clientHeight === 0) {\n return undefined;\n }\n // Bail on very large DOM trees. html-to-image clones and inlines the ENTIRE subtree\n // SYNCHRONOUSLY before it ever yields, so a heavy view (e.g. the Data Explorer's grid\n // + map) blocks the main thread for seconds — long enough to freeze the UI, and the\n // timeout below (setTimeout-based) can't even fire while the thread is blocked. A\n // thumbnail is best-effort decoration, so skip rather than jank the app.\n const nodeCount = element.getElementsByTagName('*').length;\n if (nodeCount > HomeAppPinService.THUMBNAIL_MAX_NODES) {\n return undefined;\n }\n // Race against a timeout as a secondary guard for the async portion: toJpeg() can also\n // hang on content with cross-origin resources it must re-fetch (e.g. Leaflet map tiles),\n // where the inlining/canvas step never resolves. Don't cacheBust — re-fetching every\n // image is what tends to stall, and a slightly cached preview is fine.\n const capture = toJpeg(element, {\n quality: 0.6,\n pixelRatio: 0.2,\n });\n return await this.withTimeout(capture, HomeAppPinService.THUMBNAIL_CAPTURE_TIMEOUT_MS);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Resolve to `undefined` if the given promise hasn't settled within `ms`.\n * Note: this does not cancel the underlying work (toJpeg is not cancelable),\n * it just stops the pin flow from waiting on it.\n */\n private withTimeout(promise: Promise<string>, ms: number): Promise<string | undefined> {\n return new Promise<string | undefined>((resolve) => {\n let settled = false;\n const timer = setTimeout(() => {\n if (!settled) {\n settled = true;\n resolve(undefined);\n }\n }, ms);\n promise.then(\n (value) => {\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n resolve(value);\n }\n },\n () => {\n if (!settled) {\n settled = true;\n clearTimeout(timer);\n resolve(undefined);\n }\n }\n );\n });\n }\n\n // =============================================\n // PRIVATE\n // =============================================\n\n private matchesResource(pin: HomeAppPinnedItem, resourceType: string, config: Record<string, unknown>): boolean {\n if (pin.ResourceType !== resourceType) return false;\n switch (resourceType) {\n case 'Dashboards':\n return pin.Configuration['dashboardId'] === config['dashboardId'];\n case 'User Views':\n return pin.Configuration['viewId'] === config['viewId'];\n case 'Queries':\n return pin.Configuration['queryId'] === config['queryId'];\n case 'Records':\n return pin.Configuration['Entity'] === config['Entity']\n && pin.Configuration['recordId'] === config['recordId'];\n case 'Custom': {\n // Match by app name + nav item name + route — never use appId or driverClass\n // Include route to differentiate same nav item with different URL paths\n const sameApp = pin.Configuration['appName'] === config['appName'];\n const sameNav = pin.Configuration['navItemName'] === config['navItemName'];\n const pinRoute = pin.Configuration['route'] as string || '';\n const configRoute = config['route'] as string || '';\n const sameRoute = pinRoute === configRoute;\n // Also compare queryParams if present\n const pinQP = JSON.stringify(pin.Configuration['queryParams'] || {});\n const configQP = JSON.stringify(config['queryParams'] || {});\n const sameQP = pinQP === configQP;\n return sameApp && sameNav && sameRoute && sameQP;\n }\n case 'Actions': {\n // A pinned Action is unique per (actionId + preset-params + runtime-params + title).\n // Two pins targeting the same action with different preset configs are allowed —\n // e.g. \"Weekly Report — Sales\" vs. \"Weekly Report — Ops\" both pin \"Run Report\".\n if (pin.Configuration['actionId'] !== config['actionId']) return false;\n const pinPreset = JSON.stringify(pin.Configuration['presetParams'] ?? {});\n const configPreset = JSON.stringify(config['presetParams'] ?? {});\n const pinRuntime = JSON.stringify(pin.Configuration['runtimeParamNames'] ?? []);\n const configRuntime = JSON.stringify(config['runtimeParamNames'] ?? []);\n const samePreset = pinPreset === configPreset;\n const sameRuntime = pinRuntime === configRuntime;\n const sameTitle = pin.DisplayName === (config['displayName'] ?? pin.DisplayName);\n return samePreset && sameRuntime && sameTitle;\n }\n default:\n return false;\n }\n }\n\n private updateAndSave(pins: HomeAppPinnedItem[]): void {\n const sorted = this.sortPins(pins);\n this.Pins$.next(sorted);\n UserInfoEngine.Instance.SetSettingDebounced(\n PINS_SETTING_KEY,\n JSON.stringify(sorted)\n );\n }\n\n private sortPins(pins: HomeAppPinnedItem[]): HomeAppPinnedItem[] {\n return [...pins].sort((a, b) => a.Sequence - b.Sequence);\n }\n\n private resequence(pins: HomeAppPinnedItem[]): void {\n pins.forEach((pin, i) => { pin.Sequence = i; });\n }\n\n private generateId(): string {\n // Crypto.randomUUID is available in modern browsers\n if (typeof crypto !== 'undefined' && crypto.randomUUID) {\n return crypto.randomUUID();\n }\n // Fallback for older browsers\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {\n const r = (Math.random() * 16) | 0;\n const v = c === 'x' ? r : (r & 0x3) | 0x8;\n return v.toString(16);\n });\n }\n}\n"]}
@@ -307,11 +307,6 @@ export declare class NavigationService implements OnDestroy {
307
307
  * Uses Home app if available, otherwise falls back to active app or system app
308
308
  */
309
309
  OpenDashboard(dashboardId: string, dashboardName: string, options?: NavigationOptions): string;
310
- /**
311
- * Open a report
312
- * Uses Home app if available, otherwise falls back to active app or system app
313
- */
314
- OpenReport(reportId: string, reportName: string, options?: NavigationOptions): string;
315
310
  /**
316
311
  * Open an artifact
317
312
  * Artifacts are versioned content containers (reports, dashboards, UI components, etc.)
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.service.d.ts","sourceRoot":"","sources":["../../src/lib/navigation.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,SAAS,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAA8B,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACrI,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAuE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC/H,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAa,eAAe,EAAE,OAAO,EAAgB,UAAU,EAAE,MAAM,MAAM,CAAC;AACrF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAGvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;;AAElE;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B;;;;;OAKG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IAC/B,sDAAsD;IACtD,MAAM,EAAE,qBAAqB,CAAC;IAC9B,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,yEAAyE;IACzE,gBAAgB,CAAC,EAAE,KAAK,CAAC;QACrB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACzC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;KAClE,CAAC,CAAC;CACN;AAED,MAAM,WAAW,wBAAwB;IACrC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;GAIG;AACH,eAAO,MAAM,aAAa,eAAe,CAAC;AAO1C;;;GAGG;AACH,qBAGa,iBAAkB,YAAW,SAAS;IAc/C,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,UAAU;IAdpB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,aAAa,CAAsB;IAE3C,OAAO,CAAC,kBAAkB,CAAwC;IAClE,yFAAyF;IAClF,kBAAkB,oCAA0C;IAEnE,6EAA6E;IAC7E,OAAO,CAAC,UAAU,CAAwC;IAC1D,4BAA4B;IAC5B,OAAO,CAAC,aAAa,CAAuB;gBAGlC,gBAAgB,EAAE,qBAAqB,EACvC,UAAU,EAAE,kBAAkB;IAKxC;;;;OAIG;IACH,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAED;;;;;;OAMG;IACH,OAAO,CAAC,uBAAuB;IAmC/B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAmB1B;;;OAGG;IACI,iBAAiB,IAAI,IAAI;IAShC;;;;OAIG;IACH,SAAgB,oBAAoB,8BAAqC;IAEzE,kGAAkG;IAClG,OAAO,CAAC,iBAAiB,CAA2D;IAEpF;;;;;;;;OAQG;IACH,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAAyF;IAEtI;;;;;;;;;;;;;;;;;;;OAmBG;IACH,SAAgB,mBAAmB,6CAAwD;IAE3F;;;;;;OAMG;IACI,yBAAyB,CAAC,QAAQ,EAAE,kBAAkB,GAAG,IAAI,GAAG,IAAI;IAI3E;;;;;;;;;;OAUG;IACI,eAAe,CAAC,MAAM,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI7F;;;;;;;;;OASG;IACI,mBAAmB,CAAC,MAAM,EAAE,qBAAqB,EAAE,KAAK,EAAE,KAAK,CAAC;QACrE,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACzC,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;KAChE,CAAC,GAAG,IAAI;IAKT;;;;;;OAMG;IACI,wBAAwB,CAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI;IASpE;;;;;;OAMG;IACI,sBAAsB,CAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI;IAMlE;;;OAGG;IACI,cAAc,CAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI;IAI1D,WAAW,IAAI,IAAI;IAInB;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAcpC;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAUzB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,kCAAkC;IAI1C;;OAEG;IACH,OAAO,CAAC,cAAc;IAwBtB;;OAEG;IACI,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,MAAM;IAkD1G;;;;;;;;;;OAUG;IACI,gBAAgB,CACrB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,YAAY,EACxB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,MAAM;IAiET;;;;;;;;OAQG;IACH,OAAO,CAAC,sBAAsB;IAS9B,+EAA+E;IAC/E,OAAO,CAAC,iBAAiB;IAUzB;;;;;;OAMG;IACH,OAAO,CAAC,oBAAoB;IAe5B;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAoB5B;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAmD5B;;;;;;OAMG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAwBnD;;;;;;;;OAQG;IACU,oBAAoB,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAwF7E;;;OAGG;IACI,QAAQ,CACb,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,MAAM;IA2BT;;;OAGG;IACI,aAAa,CAClB,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,MAAM;IA2BT;;;OAGG;IACI,UAAU,CACf,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,MAAM;IA2BT;;;;OAIG;IACI,YAAY,CACjB,UAAU,EAAE,MAAM,EAClB,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,MAAM;IA2BT;;;;OAIG;IACI,eAAe,CACpB,UAAU,EAAE,MAAM,EAClB,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,MAAM;IA8BT;;;OAGG;IACI,SAAS,CACd,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,MAAM;IA2BT;;;;;OAKG;IACI,mBAAmB,CACxB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,iBAAiB,GAC1B,MAAM;IA+CT;;;;;;;OAOG;IACI,UAAU,CACf,KAAK,EAAE,MAAM,EACb,aAAa,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,EAC9D,OAAO,CAAC,EAAE,iBAAiB,GAC1B,MAAM;IAoCT;;;;;;;;;;;OAWG;IACU,iBAAiB,CAC5B,WAAW,EAAE,MAAM,EACnB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,KAAK,CAAC,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,iBAAiB,GAC1B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAgCzB;;;;;;;;;;;OAWG;IACG,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IA0FlH;;;;;;;;;;;;;;;;OAgBG;IACH,0BAA0B,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,GAAG,IAAI;IAU5E;;;;;OAKG;IACH,oBAAoB,CAClB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,EAC1C,KAAK,CAAC,EAAE,wBAAwB,GAC/B,OAAO;IA0BV;;;;OAIG;IACH,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,UAAQ,GAAG,IAAI;IAI5F;;;;;;;;;;;;;OAaG;IACI,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAU/E,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,yBAAyB;IA0BjC;;;OAGG;IACH,OAAO,CAAC,qBAAqB;yCA7yClB,iBAAiB;6CAAjB,iBAAiB;CA+0C7B"}
1
+ {"version":3,"file":"navigation.service.d.ts","sourceRoot":"","sources":["../../src/lib/navigation.service.ts"],"names":[],"mappings":"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"}
@@ -730,34 +730,6 @@ export class NavigationService {
730
730
  return this.workspaceManager.OpenTab(request, appColor);
731
731
  }
732
732
  }
733
- /**
734
- * Open a report
735
- * Uses Home app if available, otherwise falls back to active app or system app
736
- */
737
- OpenReport(reportId, reportName, options) {
738
- const appId = this.getDefaultApplicationId();
739
- const appColor = this.getDefaultAppColor();
740
- let forceNew = this.shouldForceNewTab(options);
741
- const request = {
742
- ApplicationId: appId,
743
- Title: reportName,
744
- Configuration: {
745
- resourceType: 'Reports',
746
- reportId,
747
- recordId: reportId // Also needed in Configuration for tab-container.component to populate ResourceRecordID
748
- },
749
- ResourceRecordId: reportId,
750
- IsPinned: options?.pinTab || false
751
- };
752
- // Handle transition from single-resource mode
753
- forceNew = this.handleSingleResourceModeTransition(forceNew, request);
754
- if (forceNew) {
755
- return this.workspaceManager.OpenTabForced(request, appColor);
756
- }
757
- else {
758
- return this.workspaceManager.OpenTab(request, appColor);
759
- }
760
- }
761
733
  /**
762
734
  * Open an artifact
763
735
  * Artifacts are versioned content containers (reports, dashboards, UI components, etc.)
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.service.js","sourceRoot":"","sources":["../../src/lib/navigation.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,eAAe,CAAC;AAGtD,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,yBAAyB,EAAuB,MAAM,qBAAqB,CAAC;AAC/H,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,OAAO,EAA4B,MAAM,MAAM,CAAC;AAErF,OAAO,EAAE,GAAG,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;;;AA+CpD;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,YAAY,CAAC;AAE1C;;GAEG;AACH,MAAM,iBAAiB,GAAG,SAAS,CAAC,CAAC,2BAA2B;AAEhE;;;GAGG;AAIH,MAAM,OAAO,iBAAiB;IAclB;IACA;IAdF,eAAe,GAAG,KAAK,CAAC;IACxB,aAAa,GAAmB,EAAE,CAAC;IAEnC,kBAAkB,GAAG,IAAI,OAAO,EAAyB,CAAC;IAClE,yFAAyF;IAClF,kBAAkB,GAAG,IAAI,CAAC,kBAAkB,CAAC,YAAY,EAAE,CAAC;IAEnE,6EAA6E;IACrE,UAAU,GAA8B,SAAS,CAAC;IAC1D,4BAA4B;IACpB,aAAa,GAAkB,IAAI,CAAC;IAE5C,YACU,gBAAuC,EACvC,UAA8B;QAD9B,qBAAgB,GAAhB,gBAAgB,CAAuB;QACvC,eAAU,GAAV,UAAU,CAAoB;QAEtC,IAAI,CAAC,4BAA4B,EAAE,CAAC;IACtC,CAAC;IAED;;;;OAIG;IACH,IAAI,gBAAgB;QAClB,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED;;;;;;OAMG;IACK,uBAAuB;QAC7B,oBAAoB;QACpB,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAClC,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;gBAC7B,OAAO,IAAI,CAAC,UAAU,CAAC;YACzB,CAAC;YACD,uCAAuC;YACvC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC;YACjD,IAAI,SAAS,EAAE,CAAC;gBACd,OAAO,SAAS,CAAC,EAAE,CAAC;YACtB,CAAC;YACD,OAAO,aAAa,CAAC;QACvB,CAAC;QAED,iCAAiC;QACjC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACrD,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;YACxC,OAAO,OAAO,CAAC,EAAE,CAAC;QACpB,CAAC;QAED,oCAAoC;QACpC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QAEvB,oCAAoC;QACpC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC;QACjD,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,SAAS,CAAC,EAAE,CAAC;QACtB,CAAC;QAED,8BAA8B;QAC9B,OAAO,aAAa,CAAC;IACvB,CAAC;IAED;;;OAGG;IACK,kBAAkB;QACxB,4BAA4B;QAC5B,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAE/B,oCAAoC;QACpC,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC,aAAa,CAAC;QAC5B,CAAC;QAED,mBAAmB;QACnB,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC;QACjD,IAAI,SAAS,EAAE,CAAC;YACd,OAAO,SAAS,CAAC,QAAQ,EAAE,CAAC;QAC9B,CAAC;QAED,6BAA6B;QAC7B,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IAED;;;OAGG;IACI,iBAAiB;QACtB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED,+CAA+C;IAC/C,+BAA+B;IAC/B,+CAA+C;IAE/C;;;;OAIG;IACa,oBAAoB,GAAG,IAAI,OAAO,EAAsB,CAAC;IAEzE,kGAAkG;IAC1F,iBAAiB,GAAwD,EAAE,CAAC;IAEpF;;;;;;;;OAQG;IACc,4BAA4B,GAAG,IAAI,GAAG,EAA8E,CAAC;IAEtI;;;;;;;;;;;;;;;;;;;OAmBG;IACa,mBAAmB,GAAG,IAAI,eAAe,CAA4B,IAAI,CAAC,CAAC;IAE3F;;;;;;OAMG;IACI,yBAAyB,CAAC,QAAmC;QAClE,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAED;;;;;;;;;;OAUG;IACI,eAAe,CAAC,MAA6B,EAAE,OAAgC;QACpF,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED;;;;;;;;;OASG;IACI,mBAAmB,CAAC,MAA6B,EAAE,KAKxD;QACA,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAC/B,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED;;;;;;OAMG;IACI,wBAAwB,CAAC,MAA6B;QAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,4BAA4B,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC5D,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;QAC/B,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED;;;;;;OAMG;IACI,sBAAsB,CAAC,MAA6B;QACzD,IAAI,CAAC,4BAA4B,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACtE,IAAI,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3E,CAAC;IAED;;;OAGG;IACI,cAAc,CAAC,MAA6B;QACjD,IAAI,CAAC,4BAA4B,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACnD,CAAC;IAED,WAAW;QACT,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;IACvD,CAAC;IAED;;OAEG;IACK,4BAA4B;QAClC,iFAAiF;QACjF,iCAAiC;QACjC,iFAAiF;QACjF,sFAAsF;QACtF,2EAA2E;QAC3E,iCAAiC;QACjC,IAAI,CAAC,aAAa,CAAC,IAAI,CACrB,SAAS,CAAa,QAAQ,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE;YAChF,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,QAAQ,CAAC;QACxC,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,cAAc;QACpB,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,OAA2B;QACnD,6CAA6C;QAC7C,IAAI,OAAO,EAAE,WAAW,KAAK,SAAS,EAAE,CAAC;YACvC,OAAO,OAAO,CAAC,WAAW,CAAC;QAC7B,CAAC;QAED,4CAA4C;QAC5C,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC;IAC/B,CAAC;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACK,kCAAkC,CAAC,QAAiB,EAAE,WAAuB;QACnF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,GAAQ,EAAE,OAAmB;QAClD,uCAAuC;QACvC,IAAI,GAAG,CAAC,aAAa,KAAK,OAAO,CAAC,aAAa,EAAE,CAAC;YAChD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,6DAA6D;QAC7D,IAAI,OAAO,CAAC,aAAa,EAAE,YAAY,EAAE,CAAC;YACxC,MAAM,eAAe,GAAG,OAAO,CAAC,gBAAgB,IAAI,EAAE,CAAC;YACvD,MAAM,WAAW,GAAG,GAAG,CAAC,gBAAgB,IAAI,EAAE,CAAC;YAC/C,OAAO,GAAG,CAAC,aAAa,EAAE,YAAY,KAAK,OAAO,CAAC,aAAa,CAAC,YAAY;gBACtE,WAAW,KAAK,eAAe,CAAC;QACzC,CAAC;QAED,qDAAqD;QACrD,IAAI,OAAO,CAAC,aAAa,EAAE,OAAO,IAAI,OAAO,CAAC,aAAa,EAAE,WAAW,EAAE,CAAC;YACzE,OAAO,GAAG,CAAC,aAAa,EAAE,OAAO,KAAK,OAAO,CAAC,aAAa,CAAC,OAAO;gBAC5D,GAAG,CAAC,aAAa,EAAE,WAAW,KAAK,OAAO,CAAC,aAAa,CAAC,WAAW,CAAC;QAC9E,CAAC;QAED,+BAA+B;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACI,WAAW,CAAC,KAAa,EAAE,OAAgB,EAAE,QAAgB,EAAE,OAA2B;QAC/F,IAAI,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAE/C,+BAA+B;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC;QAEhC,wFAAwF;QACxF,qFAAqF;QACrF,gFAAgF;QAChF,wDAAwD;QACxD,MAAM,SAAS,GAAI,OAA0B,CAAC,SAAS,KAAK,IAAI,CAAC;QAEjE,MAAM,OAAO,GAAe;YAC1B,aAAa,EAAE,KAAK;YACpB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,gBAAgB,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE,EAAG,sDAAsD;YACjG,aAAa,EAAE;gBACb,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,YAAY,EAAE,OAAO,CAAC,YAAY;gBAClC,WAAW,EAAE,OAAO,CAAC,WAAW,EAAG,oDAAoD;gBACvF,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,OAAO,EAAE,OAAO,EAAG,kCAAkC;gBACrD,KAAK,EAAE,KAAK;gBACZ,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,EAAG,gCAAgC;gBACvF,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;aACjC;YACD,QAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;SACnC,CAAC;QAEF,8CAA8C;QAC9C,QAAQ,GAAG,IAAI,CAAC,kCAAkC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEtE,IAAI,KAAa,CAAC;QAClB,IAAI,QAAQ,EAAE,CAAC;YACb,0BAA0B;YAC1B,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACjE,CAAC;aAAM,CAAC;YACN,yDAAyD;YACzD,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC3D,CAAC;QAED,mEAAmE;QACnE,IAAI,OAAO,EAAE,WAAW,EAAE,CAAC;YACzB,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;QACzD,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;;;;OAUG;IACI,gBAAgB,CACrB,UAAkB,EAClB,UAAwB,EACxB,OAA2B;QAE3B,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;QAErC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC;QACjD,MAAM,KAAK,GAAG,QAAQ,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC;QACpF,MAAM,QAAQ,GAAG,QAAQ,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAE1F,MAAM,QAAQ,GAAG,UAAU,CAAC,YAAY,EAAE,CAAC;QAE3C,sEAAsE;QACtE,kDAAkD;QAClD,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC9D,IAAI,QAAQ,EAAE,CAAC;gBACb,iEAAiE;gBACjE,gEAAgE;gBAChE,mEAAmE;gBACnE,8DAA8D;gBAC9D,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;gBAChD,iEAAiE;gBACjE,oEAAoE;gBACpE,kEAAkE;gBAClE,4DAA4D;gBAC5D,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBAChD,IAAI,CAAC,sBAAsB,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;gBACzC,OAAO,QAAQ,CAAC,EAAE,CAAC;YACrB,CAAC;QACH,CAAC;QAED,IAAI,QAAQ,GAAG,QAAQ,IAAI,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAE3D,MAAM,OAAO,GAAe;YAC1B,aAAa,EAAE,KAAK;YACpB,KAAK,EAAE,GAAG,UAAU,MAAM,QAAQ,EAAE;YACpC,aAAa,EAAE;gBACb,YAAY,EAAE,qBAAqB;gBACnC,MAAM,EAAE,UAAU,EAAG,wEAAwE;gBAC7F,QAAQ,EAAE,QAAQ,EAAG,wFAAwF;gBAC7G,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC;aACtC;YACD,gBAAgB,EAAE,QAAQ;YAC1B,QAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;YAClC,gEAAgE;YAChE,sEAAsE;YACtE,iCAAiC;YACjC,gBAAgB,EAAE,QAAQ;SAC3B,CAAC;QAEF,8CAA8C;QAC9C,QAAQ,GAAG,IAAI,CAAC,kCAAkC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEtE,IAAI,KAAa,CAAC;QAClB,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACjE,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC3D,CAAC;QAED,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;;OAQG;IACK,sBAAsB,CAAC,KAAa;QAC1C,UAAU,CAAC,GAAG,EAAE;YACd,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAC;YACxD,IAAI,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,IAAI,MAAM,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;gBAC3E,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC,EAAE,CAAC,CAAC,CAAC;IACR,CAAC;IAED,+EAA+E;IACvE,iBAAiB,CAAC,UAAkB,EAAE,QAAgB;QAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAC;QACxD,MAAM,KAAK,GAAG,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAClC,CAAC,CAAC,gBAAgB,KAAK,QAAQ;YAC/B,CAAC,CAAC,aAAa,EAAE,CAAC,cAAc,CAAC,KAAK,qBAAqB;YAC3D,CAAC,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,KAAK,UAAU,CAC3C,CAAC;QACF,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IACzC,CAAC;IAED;;;;;;OAMG;IACK,oBAAoB,CAAC,KAAa,EAAE,OAA2B;QACrE,IAAI,CAAC,gBAAgB,CAAC,sBAAsB,CAAC,KAAK,EAAE;YAClD,WAAW,EAAE,SAAS;YACtB,aAAa,EAAE,SAAS;YACxB,cAAc,EAAE,SAAS;YACzB,iBAAiB,EAAE,SAAS;YAC5B,WAAW,EAAE,SAAS;YACtB,WAAW,EAAE,SAAS;YACtB,iBAAiB,EAAE,SAAS;YAC5B,kBAAkB,EAAE,SAAS;YAC7B,cAAc,EAAE,SAAS;YACzB,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC;SACtC,CAAC,CAAC;IACL,CAAC;IAED;;;;;OAKG;IACK,oBAAoB,CAAC,OAA2B;QACtD,IAAI,OAAO,EAAE,YAAY,KAAK,MAAM,EAAE,CAAC;YACrC,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,IAAI,OAAO,EAAE,YAAY,EAAE,CAAC;YAC1B,MAAM,GAAG,GAAG,OAAO,CAAC,YAAY,CAAC;YACjC,MAAM,OAAO,GAA4B,EAAE,CAAC;YAC5C,IAAI,GAAG,CAAC,WAAW;gBAAE,OAAO,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC;YAC9D,IAAI,GAAG,CAAC,aAAa;gBAAE,OAAO,CAAC,eAAe,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC;YACpE,IAAI,GAAG,CAAC,cAAc;gBAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,GAAG,CAAC,cAAc,CAAC;YACvE,IAAI,GAAG,CAAC,WAAW;gBAAE,OAAO,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC;YAC9D,IAAI,GAAG,CAAC,WAAW;gBAAE,OAAO,CAAC,aAAa,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC;YAC9D,IAAI,GAAG,CAAC,iBAAiB,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3E,OAAO,CAAC,mBAAmB,CAAC,GAAG,GAAG,CAAC,iBAAiB,CAAC;YACvD,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,IAAI,CAAC,oBAAoB,EAAE,CAAC;IACrC,CAAC;IAED;;;;;OAKG;IACK,oBAAoB;QAC1B,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC;QACjD,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,OAAO,GAA4B;YACvC,WAAW,EAAE,SAAS,CAAC,EAAE;YACzB,aAAa,EAAE,SAAS,CAAC,IAAI;SAC9B,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAC;QACxD,MAAM,SAAS,GAAG,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,WAAW,CAAC,CAAC;QACtE,IAAI,CAAC,SAAS,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,aAAa,EAAE,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;YACzF,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,IAAI,yBAAyB,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,CAAC;YACvD,qEAAqE;YACrE,oEAAoE;YACpE,kEAAkE;YAClE,MAAM,YAAY,GAAG,SAAS,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,CAAC;YACzD,MAAM,cAAc,GAAG,SAAS,CAAC,gBAAgB,IAAI,SAAS,CAAC,aAAa,EAAE,CAAC,UAAU,CAAC,CAAC;YAC3F,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,OAAO,cAAc,KAAK,QAAQ,IAAI,cAAc,EAAE,CAAC;gBAC7F,OAAO,CAAC,aAAa,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC;gBACtC,OAAO,CAAC,aAAa,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC;gBACzC,OAAO,CAAC,oBAAoB,CAAC,GAAG,YAAY,CAAC;gBAC7C,OAAO,CAAC,gBAAgB,CAAC,GAAG,cAAc,CAAC;YAC7C,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC;QACD,OAAO,CAAC,gBAAgB,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC;QAC5C,oEAAoE;QACpE,uEAAuE;QACvE,6DAA6D;QAC7D,MAAM,WAAW,GAAG,SAAS,CAAC,aAAa,EAAE,CAAC,aAAa,CAAC,CAAC;QAC7D,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9D,OAAO,CAAC,mBAAmB,CAAC,GAAG,WAAW,CAAC;QAC7C,CAAC;QACD,qEAAqE;QACrE,qEAAqE;QACrE,qBAAqB;QACrB,OAAO,CAAC,aAAa,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC;QACtC,sEAAsE;QACtE,sEAAsE;QACtE,qEAAqE;QACrE,+BAA+B;QAC/B,MAAM,WAAW,GAAG,SAAS,CAAC,aAAa,EAAE,CAAC,aAAa,CAAC,CAAC;QAC7D,IAAI,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1F,OAAO,CAAC,mBAAmB,CAAC,GAAG,EAAE,GAAI,WAAsC,EAAE,CAAC;QAChF,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,eAAe,CAAC,KAAa;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;QAC5E,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO;QACT,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC;QACzC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;QAC5D,MAAM,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,cAAc,EAAE,CAAC;QACrD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO;QACT,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChD,MAAM,OAAO,GAAG,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,CAA2B,CAAC;QACtF,MAAM,KAAK,GAAkC,EAAE,CAAC;QAChD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACvC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,CAAC,wBAAwB,CAAC,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC;IAED;;;;;;;;OAQG;IACI,KAAK,CAAC,oBAAoB,CAAC,MAA2B;QAC3D,yEAAyE;QACzE,yEAAyE;QACzE,qEAAqE;QACrE,uEAAuE;QACvE,oCAAoC;QACpC,IAAI,MAAM,CAAC,kBAAkB,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;YACvD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAC;YACxD,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YACvG,MAAM,WAAW,GAAG,CAAC,CAAC,SAAS;gBAC7B,yBAAyB,CAAC,SAAS,CAAC,aAAa,CAAC;gBAClD,SAAS,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,KAAK,MAAM,CAAC,kBAAkB;gBACjE,SAAS,CAAC,gBAAgB,KAAK,MAAM,CAAC,cAAc,CAAC;YACvD,IAAI,SAAS,IAAI,WAAW,EAAE,CAAC;gBAC7B,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;gBACjD,OAAO;YACT,CAAC;YACD,MAAM,SAAS,GAAG,IAAI,YAAY,EAAE,CAAC;YACrC,SAAS,CAAC,wBAAwB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;YAC1D,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,kBAAkB,EAAE,SAAS,CAAC,CAAC;YAC5D,OAAO;QACT,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YACxB,OAAO;QACT,CAAC;QACD,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;YACvB,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAC;YACxD,MAAM,SAAS,GAAG,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,WAAW,CAAC,CAAC;YACtE,gEAAgE;YAChE,oEAAoE;YACpE,qEAAqE;YACrE,oEAAoE;YACpE,+DAA+D;YAC/D,mEAAmE;YACnE,mEAAmE;YACnE,oEAAoE;YACpE,MAAM,cAAc,GAAG,SAAS,EAAE,aAAa,EAAE,CAAC,aAAa,CAAC,CAAC;YACjE,MAAM,QAAQ,GAAG,MAAM,CAAC,iBAAiB,IAAI,OAAO,cAAc,KAAK,QAAQ;gBAC7E,CAAC,CAAC,cAAc,KAAK,MAAM,CAAC,iBAAiB;gBAC7C,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,IAAI,SAAS,EAAE,KAAK,KAAK,MAAM,CAAC,cAAc,CAAC,CAAC;YAC3E,MAAM,eAAe,GAAG,CAAC,CAAC,SAAS;gBACjC,CAAC,CAAC,MAAM,CAAC,WAAW,IAAI,UAAU,CAAC,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;gBAChF,QAAQ,CAAC;YACX,IAAI,SAAS,IAAI,eAAe,EAAE,CAAC;gBACjC,qEAAqE;gBACrE,oEAAoE;gBACpE,4DAA4D;gBAC5D,oEAAoE;gBACpE,+DAA+D;gBAC/D,mEAAmE;gBACnE,MAAM,aAAa,GAAG,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,CAA2B,CAAC;gBACjG,MAAM,OAAO,GAAkC,EAAE,CAAC;gBAClD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;oBAC7C,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;gBACtB,CAAC;gBACD,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;gBACvD,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACpC,IAAI,CAAC,qBAAqB,CAAC,SAAS,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;gBACpD,CAAC;gBACD,mEAAmE;gBACnE,kEAAkE;gBAClE,iEAAiE;gBACjE,qDAAqD;gBACrD,IAAI,MAAM,CAAC,iBAAiB,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACjF,IAAI,CAAC,wBAAwB,CAAC,SAAS,CAAC,EAAE,EAAE,MAAM,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;gBAC9E,CAAC;gBACD,iEAAiE;gBACjE,gEAAgE;gBAChE,+DAA+D;gBAC/D,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;gBAC5D,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;gBACjD,OAAO;YACT,CAAC;QACH,CAAC;QACD,wEAAwE;QACxE,wEAAwE;QACxE,4DAA4D;QAC5D,MAAM,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,iBAAiB,IAAI,MAAM,CAAC,cAAc,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC;QACxH,uEAAuE;QACvE,iCAAiC;QACjC,IAAI,MAAM,CAAC,iBAAiB,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjF,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,cAAc,EAAE,CAAC;YAC3D,IAAI,WAAW,EAAE,CAAC;gBAChB,IAAI,CAAC,wBAAwB,CAAC,WAAW,EAAE,MAAM,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAC;YAC7E,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;OAGG;IACI,QAAQ,CACb,MAAc,EACd,QAAgB,EAChB,OAA2B;QAE3B,MAAM,KAAK,GAAG,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC3C,IAAI,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAE/C,MAAM,OAAO,GAAe;YAC1B,aAAa,EAAE,KAAK;YACpB,KAAK,EAAE,QAAQ;YACf,aAAa,EAAE;gBACb,YAAY,EAAE,gBAAgB;gBAC9B,MAAM;gBACN,QAAQ,EAAE,MAAM,CAAE,wFAAwF;aAC3G;YACD,gBAAgB,EAAE,MAAM;YACxB,QAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;SACnC,CAAC;QAEF,8CAA8C;QAC9C,QAAQ,GAAG,IAAI,CAAC,kCAAkC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEtE,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAChE,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED;;;OAGG;IACI,aAAa,CAClB,WAAmB,EACnB,aAAqB,EACrB,OAA2B;QAE3B,MAAM,KAAK,GAAG,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC3C,IAAI,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAE/C,MAAM,OAAO,GAAe;YAC1B,aAAa,EAAE,KAAK;YACpB,KAAK,EAAE,aAAa;YACpB,aAAa,EAAE;gBACb,YAAY,EAAE,YAAY;gBAC1B,WAAW;gBACX,QAAQ,EAAE,WAAW,CAAE,wFAAwF;aAChH;YACD,gBAAgB,EAAE,WAAW;YAC7B,QAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;SACnC,CAAC;QAEF,8CAA8C;QAC9C,QAAQ,GAAG,IAAI,CAAC,kCAAkC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEtE,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAChE,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED;;;OAGG;IACI,UAAU,CACf,QAAgB,EAChB,UAAkB,EAClB,OAA2B;QAE3B,MAAM,KAAK,GAAG,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC3C,IAAI,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAE/C,MAAM,OAAO,GAAe;YAC1B,aAAa,EAAE,KAAK;YACpB,KAAK,EAAE,UAAU;YACjB,aAAa,EAAE;gBACb,YAAY,EAAE,SAAS;gBACvB,QAAQ;gBACR,QAAQ,EAAE,QAAQ,CAAE,wFAAwF;aAC7G;YACD,gBAAgB,EAAE,QAAQ;YAC1B,QAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;SACnC,CAAC;QAEF,8CAA8C;QAC9C,QAAQ,GAAG,IAAI,CAAC,kCAAkC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEtE,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAChE,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,YAAY,CACjB,UAAkB,EAClB,YAAqB,EACrB,OAA2B;QAE3B,MAAM,KAAK,GAAG,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC3C,IAAI,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAE/C,MAAM,OAAO,GAAe;YAC1B,aAAa,EAAE,KAAK;YACpB,KAAK,EAAE,YAAY,IAAI,cAAc,UAAU,EAAE;YACjD,aAAa,EAAE;gBACb,YAAY,EAAE,WAAW;gBACzB,UAAU;gBACV,QAAQ,EAAE,UAAU,CAAE,wFAAwF;aAC/G;YACD,gBAAgB,EAAE,UAAU;YAC5B,QAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;SACnC,CAAC;QAEF,8CAA8C;QAC9C,QAAQ,GAAG,IAAI,CAAC,kCAAkC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEtE,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAChE,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,eAAe,CACpB,UAAkB,EAClB,WAAoB,EACpB,OAA2B;QAE3B,MAAM,KAAK,GAAG,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC3C,IAAI,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAE/C,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;QACtD,MAAM,OAAO,GAAe;YAC1B,aAAa,EAAE,KAAK;YACpB,KAAK,EAAE,GAAG,UAAU,GAAG,YAAY,EAAE;YACrC,aAAa,EAAE;gBACb,YAAY,EAAE,gBAAgB;gBAC9B,MAAM,EAAE,UAAU;gBAClB,WAAW,EAAE,WAAW;gBACxB,SAAS,EAAE,IAAI;gBACf,QAAQ,EAAE,SAAS,CAAE,mCAAmC;aACzD;YACD,gBAAgB,EAAE,SAAS;YAC3B,QAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;SACnC,CAAC;QAEF,8CAA8C;QAC9C,QAAQ,GAAG,IAAI,CAAC,kCAAkC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEtE,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAChE,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED;;;OAGG;IACI,SAAS,CACd,OAAe,EACf,SAAiB,EACjB,OAA2B;QAE3B,MAAM,KAAK,GAAG,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC3C,IAAI,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAE/C,MAAM,OAAO,GAAe;YAC1B,aAAa,EAAE,KAAK;YACpB,KAAK,EAAE,SAAS;YAChB,aAAa,EAAE;gBACb,YAAY,EAAE,SAAS;gBACvB,OAAO;gBACP,QAAQ,EAAE,OAAO,CAAE,wFAAwF;aAC5G;YACD,gBAAgB,EAAE,OAAO;YACzB,QAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;SACnC,CAAC;QAEF,8CAA8C;QAC9C,QAAQ,GAAG,IAAI,CAAC,kCAAkC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEtE,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAChE,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACI,mBAAmB,CACxB,UAAkB,EAClB,OAA2B;QAE3B,kEAAkE;QAClE,uEAAuE;QACvE,sEAAsE;QACtE,6DAA6D;QAC7D,oEAAoE;QACpE,6CAA6C;QAC7C,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,CAAC;QACjD,MAAM,KAAK,GAAG,QAAQ,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,uBAAuB,EAAE,CAAC;QACpF,MAAM,QAAQ,GAAG,QAAQ,IAAI,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAE1F,IAAI,QAAQ,GAAG,QAAQ,IAAI,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAE3D,MAAM,OAAO,GAAe;YAC1B,aAAa,EAAE,KAAK;YACpB,KAAK,EAAE,OAAO,UAAU,EAAE;YAC1B,aAAa,EAAE;gBACb,YAAY,EAAE,qBAAqB;gBACnC,MAAM,EAAE,UAAU,EAAG,wEAAwE;gBAC7F,QAAQ,EAAE,EAAE,EAAS,sCAAsC;gBAC3D,KAAK,EAAE,IAAI,EAAU,wCAAwC;gBAC7D,eAAe,EAAE,OAAO,EAAE,eAAe,EAAG,0CAA0C;gBACtF,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC;aACtC;YACD,gBAAgB,EAAE,EAAE,EAAG,wBAAwB;YAC/C,QAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;YAClC,gBAAgB,EAAE,QAAQ;SAC3B,CAAC;QAEF,8CAA8C;QAC9C,QAAQ,GAAG,IAAI,CAAC,kCAAkC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEtE,IAAI,KAAa,CAAC;QAClB,IAAI,QAAQ,EAAE,CAAC;YACb,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACjE,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC3D,CAAC;QAED,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;OAOG;IACI,UAAU,CACf,KAAa,EACb,aAA8D,EAC9D,OAA2B;QAE3B,MAAM,KAAK,GAAG,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC7C,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC3C,IAAI,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAE/C,MAAM,MAAM,GAA4B;YACtC,YAAY,EAAE,gBAAgB;YAC9B,KAAK,EAAE,KAAK;YACZ,WAAW,EAAE,KAAK;YAClB,QAAQ,EAAE,UAAU,KAAK,EAAE;SAC5B,CAAC;QACF,IAAI,aAAa,EAAE,YAAY,IAAI,IAAI,EAAE,CAAC;YACxC,MAAM,CAAC,cAAc,CAAC,GAAG,aAAa,CAAC,YAAY,CAAC;QACtD,CAAC;QACD,IAAI,aAAa,EAAE,QAAQ,IAAI,aAAa,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjE,MAAM,CAAC,UAAU,CAAC,GAAG,aAAa,CAAC,QAAQ,CAAC;QAC9C,CAAC;QAED,MAAM,OAAO,GAAe;YAC1B,aAAa,EAAE,KAAK;YACpB,KAAK,EAAE,WAAW,KAAK,EAAE;YACzB,aAAa,EAAE,MAAM;YACrB,gBAAgB,EAAE,UAAU,KAAK,EAAE;YACnC,QAAQ,EAAE,KAAK;SAChB,CAAC;QAEF,8CAA8C;QAC9C,QAAQ,GAAG,IAAI,CAAC,kCAAkC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAEtE,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAChE,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IAED;;;;;;;;;;;OAWG;IACI,KAAK,CAAC,iBAAiB,CAC5B,WAAmB,EACnB,aAAuC,EACvC,KAAc,EACd,OAA2B;QAE3B,2CAA2C;QAC3C,MAAM,WAAW,GAAG,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,YAAY,EAAE,EAAE,EAAE,CAAC;QAChE,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;QACpD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,IAAI,CAAC;QACd,CAAC;QAED,4BAA4B;QAC5B,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,WAAW,CAAC,CAAC;QAClE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACd,CAAC;QAED,yDAAyD;QACzD,MAAM,aAAa,GAAY;YAC7B,GAAG,OAAO;YACV,aAAa,EAAE;gBACb,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;gBAChC,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC;aACzB;SACF,CAAC;QAEF,2BAA2B;QAC3B,OAAO,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,aAAa,EAAE,GAAG,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC;IAC/E,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,WAAW,CAAC,KAAa,EAAE,WAAoB,EAAE,WAA2C;QAChG,MAAM,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;QAE1C,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;QAC5E,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO;QACT,CAAC;QAED,wEAAwE;QACxE,sEAAsE;QACtE,sEAAsE;QACtE,uEAAuE;QACvE,sEAAsE;QACtE,gEAAgE;QAChE,sEAAsE;QACtE,mEAAmE;QACnE,kCAAkC;QAClC,MAAM,OAAO,GAAG,iBAAiB,EAAE;YACjC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;YAClG,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAE5C,sCAAsC;QACtC,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,KAAK,WAAW,CAAC,CAAC;YAClE,IAAI,OAAO,EAAE,CAAC;gBACZ,mEAAmE;gBACnE,kEAAkE;gBAClE,mEAAmE;gBACnE,mEAAmE;gBACnE,+DAA+D;gBAC/D,iEAAiE;gBACjE,0BAA0B;gBAC1B,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;oBACrC,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,EAAE,CAAC,aAAa,CAAC,CAAC;oBAClD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACpD,OAAO,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC;oBAClC,CAAC;oBACD,OAAO,GAAG,CAAC,KAAK,KAAK,OAAO,CAAC,KAAK;wBAChC,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBACxE,CAAC,CAAC,CAAC;gBAEH,IAAI,WAAW,EAAE,CAAC;oBAChB,yBAAyB;oBACzB,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;gBACrD,CAAC;qBAAM,CAAC;oBACN,iCAAiC;oBACjC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACnD,CAAC;gBACD,mFAAmF;gBACnF,iFAAiF;gBACjF,IAAI,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACvD,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,cAAc,EAAE,CAAC;oBAC3D,IAAI,WAAW,EAAE,CAAC;wBAChB,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;oBACvD,CAAC;gBACH,CAAC;gBACD,OAAO;YACT,CAAC;YACD,uDAAuD;QACzD,CAAC;QAED,6DAA6D;QAC7D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,qBAAqB;YACrB,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,gBAAgB,EAAE,CAAC;YAChD,IAAI,UAAU,EAAE,CAAC;gBACf,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;aAAM,CAAC;YACN,mEAAmE;YACnE,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,CAAC;YACxD,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,EAAE,WAAW,CAAC,CAAC;YACrE,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,kDAAkD;gBAClD,IAAI,CAAC,gBAAgB,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;QAED,4EAA4E;QAC5E,+EAA+E;QAC/E,oFAAoF;QACpF,IAAI,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvD,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,cAAc,EAAE,CAAC;YAC3D,IAAI,WAAW,EAAE,CAAC;gBAChB,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,0BAA0B,CAAC,WAA0C;QACnE,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,cAAc,EAAE,CAAC;QAC3D,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,OAAO,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;YAC5E,OAAO;QACT,CAAC;QAED,IAAI,CAAC,qBAAqB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACvD,CAAC;IAED;;;;;OAKG;IACH,oBAAoB,CAClB,KAAa,EACb,WAA0C,EAC1C,KAAgC;QAEhC,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,2FAA2F,EAAE,KAAK,CAAC,CAAC;YAClH,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,yBAAyB,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC;YACzD,OAAO,CAAC,KAAK,CAAC,kGAAkG,EAAE;gBAChH,KAAK;gBACL,KAAK;gBACL,OAAO,EAAE;oBACP,YAAY,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC,cAAc,CAAC;oBACjD,WAAW,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC,yBAAyB,CAAC,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC,aAAa,CAAC;oBACjG,QAAQ,EAAE,GAAG,CAAC,gBAAgB,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC,UAAU,CAAC;oBACjE,WAAW,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC,aAAa,CAAC;oBAC/C,MAAM,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,aAAa,EAAE,CAAC,QAAQ,CAAC;iBACvE;aACF,CAAC,CAAC;YACH,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,CAAC,qBAAqB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QAC/C,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;OAIG;IACH,wBAAwB,CAAC,KAAa,EAAE,MAA8B,EAAE,KAAK,GAAG,KAAK;QACnF,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED;;;;;;;;;;;;;OAaG;IACI,qBAAqB,CAAC,KAAa;QACxC,OAAO,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,IAAI,CAC7C,GAAG,CAAC,MAAM,CAAC,EAAE;YACX,MAAM,GAAG,GAAG,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,CAAC;YACpD,OAAO,CAAC,GAAG,EAAE,aAAa,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,CAA2B,CAAC;QAC/E,CAAC,CAAC,EACF,oBAAoB,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAC9D,CAAC;IACJ,CAAC;IAEO,kBAAkB,CAAC,CAAyB,EAAE,CAAyB;QAC7E,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;YAClC,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/C,CAAC;IAEO,yBAAyB,CAAC,GAA2E,EAAE,KAA+B;QAC5I,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,CAAC,QAAmC,EAAE,MAAe,EAAE,SAAS,GAAG,KAAK,EAAW,EAAE;YACnG,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBAChD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;YACtC,MAAM,UAAU,GAAG,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACxD,OAAO,SAAS;gBACd,CAAC,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,UAAU,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE;gBACvE,CAAC,CAAC,YAAY,KAAK,UAAU,CAAC;QAClC,CAAC,CAAC;QAEF,MAAM,kBAAkB,GAAG,CAAC,MAAM,CAAC,yBAAyB,CAAC,IAAI,MAAM,CAAC,aAAa,CAAC,CAAuB,CAAC;QAC9G,MAAM,eAAe,GAAG,GAAG,CAAC,gBAAgB,IAAK,MAAM,CAAC,UAAU,CAAwB,IAAI,EAAE,CAAC;QACjG,MAAM,aAAa,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAuB,CAAC;QAEnF,oFAAoF;QACpF,qFAAqF;QACrF,OAAO,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,MAAM,CAAC,cAAc,CAAC,EAAE,IAAI,CAAC;YAC9D,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,kBAAkB,CAAC;YAC9C,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,eAAe,CAAC;YACxC,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;YACjD,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC;IAED;;;OAGG;IACK,qBAAqB,CAAC,KAAa,EAAE,WAA0C;QACrF,MAAM,GAAG,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChD,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,IAAI,CAAC,yDAAyD,EAAE,KAAK,CAAC,CAAC;YAC/E,OAAO;QACT,CAAC;QAED,kDAAkD;QAClD,MAAM,mBAAmB,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,CAAkC,CAAC;QAExG,8BAA8B;QAC9B,MAAM,iBAAiB,GAA2B,EAAE,CAAC;QAErD,+CAA+C;QAC/C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,mBAAmB,CAAC,EAAE,CAAC;YAC/D,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACnB,iBAAiB,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACjC,CAAC;QACH,CAAC;QAED,uCAAuC;QACvC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;YACvD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACnB,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC;YAChC,CAAC;iBAAM,CAAC;gBACN,iBAAiB,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACjC,CAAC;QACH,CAAC;QAED,+BAA+B;QAC/B,IAAI,CAAC,gBAAgB,CAAC,sBAAsB,CAAC,KAAK,EAAE;YAClD,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS;SACvF,CAAC,CAAC;IACL,CAAC;2GA90CU,iBAAiB;gEAAjB,iBAAiB,WAAjB,iBAAiB,mBAFhB,MAAM;;iFAEP,iBAAiB;cAH7B,UAAU;eAAC;gBACV,UAAU,EAAE,MAAM;aACnB","sourcesContent":["import { Injectable, OnDestroy } from '@angular/core';\nimport { WorkspaceStateManager, NavItem, DynamicNavItem, TabRequest, ApplicationManager } from '@memberjunction/ng-base-application';\nimport { NavigationOptions } from './navigation.interfaces';\nimport { IsRecordTabsStyle, RECORDS_RESOURCE_TYPE, IsRecordsTabConfiguration, RecordSourceContext } from './record-open-style';\nimport { CompositeKey } from '@memberjunction/core';\nimport { fromEvent, BehaviorSubject, Subject, Subscription, Observable } from 'rxjs';\nimport type { AppContextSnapshot } from '@memberjunction/ai-core-plus';\nimport { map, distinctUntilChanged } from 'rxjs/operators';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent } from './base-resource-component';\n\n/**\n * Event emitted when query params change on a tab (e.g., from browser back/forward).\n * Includes the tab ID so that only the component in the affected tab reacts,\n * preventing cross-tab leakage in multi-tab scenarios.\n */\nexport interface QueryParamChangeEvent {\n TabId: string;\n Params: Record<string, string>;\n /**\n * Bypass the receiving component's duplicate-delivery guard. Set by\n * explicit restore navigations (e.g. the origin crumb): the component's\n * state may have DRIFTED from the last-delivered params, in which case a\n * restore to those same params would otherwise be dropped as a duplicate.\n */\n Force?: boolean;\n}\n\n/**\n * Event emitted when a resource component reports its agent context or tools.\n * The shell (which owns the ComponentCacheManager) subscribes to these events\n * and updates the cache + active AppContextSnapshot accordingly.\n */\nexport interface AgentContextUpdate {\n /** The component instance that reported the update */\n Caller: BaseResourceComponent;\n /** Dashboard-specific context for the agent (undefined = no change) */\n AgentContext?: Record<string, unknown>;\n /** Client tools available from this dashboard (undefined = no change) */\n AgentClientTools?: Array<{\n Name: string;\n Description: string;\n ParameterSchema: Record<string, unknown>;\n Handler: (params: Record<string, unknown>) => Promise<unknown>;\n }>;\n}\n\nexport interface TabQueryParamUpdateGuard {\n resourceType?: string | null;\n driverClass?: string | null;\n recordId?: string | null;\n navItemName?: string | null;\n entity?: string | null;\n}\n\n/**\n * System application ID for non-app-specific resources (fallback only)\n * Uses double underscore prefix to indicate system-level resource\n * @deprecated Prefer using NavigationService.getDefaultApplicationId() instead\n */\nexport const SYSTEM_APP_ID = '__explorer';\n\n/**\n * Neutral color for fallback when no app is available\n */\nconst NEUTRAL_APP_COLOR = '#9E9E9E'; // Material Design Gray 500\n\n/**\n * Centralized navigation service that handles all navigation operations\n * with automatic shift-key detection for power user workflows\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class NavigationService implements OnDestroy {\n private shiftKeyPressed = false;\n private subscriptions: Subscription[] = [];\n\n private queryParamChanged$ = new Subject<QueryParamChangeEvent>();\n /** Observable that emits when query params change on a tab (back/forward navigation). */\n public QueryParamChanged$ = this.queryParamChanged$.asObservable();\n\n /** Cached Home app ID (null means not found, undefined means not checked) */\n private _homeAppId: string | null | undefined = undefined;\n /** Cached Home app color */\n private _homeAppColor: string | null = null;\n\n constructor(\n private workspaceManager: WorkspaceStateManager,\n private appManager: ApplicationManager\n ) {\n this.setupGlobalShiftKeyDetection();\n }\n\n /**\n * Get the neutral color used for system-wide resources (entities, views, dashboards)\n * Returns a light neutral gray\n * @deprecated Use getDefaultAppColor() for better UX with Home app integration\n */\n get ExplorerAppColor(): string {\n return NEUTRAL_APP_COLOR;\n }\n\n /**\n * Gets the default application ID for orphan resources.\n * Priority: Home app > Active app > SYSTEM_APP_ID\n *\n * This ensures orphan resources (entity records, dashboards, views opened directly)\n * are grouped under the Home app instead of being orphaned in the tab system.\n */\n private getDefaultApplicationId(): string {\n // Check cache first\n if (this._homeAppId !== undefined) {\n if (this._homeAppId !== null) {\n return this._homeAppId;\n }\n // Home app not found, check active app\n const activeApp = this.appManager.GetActiveApp();\n if (activeApp) {\n return activeApp.ID;\n }\n return SYSTEM_APP_ID;\n }\n\n // First time - look for Home app\n const homeApp = this.appManager.GetAppByName('Home');\n if (homeApp) {\n this._homeAppId = homeApp.ID;\n this._homeAppColor = homeApp.GetColor();\n return homeApp.ID;\n }\n\n // Cache that Home app doesn't exist\n this._homeAppId = null;\n\n // Fall back to currently active app\n const activeApp = this.appManager.GetActiveApp();\n if (activeApp) {\n return activeApp.ID;\n }\n\n // Last resort - system app ID\n return SYSTEM_APP_ID;\n }\n\n /**\n * Gets the default app color for orphan resources.\n * Returns Home app color if available, otherwise neutral gray.\n */\n private getDefaultAppColor(): string {\n // Ensure cache is populated\n this.getDefaultApplicationId();\n\n // If Home app exists, use its color\n if (this._homeAppColor) {\n return this._homeAppColor;\n }\n\n // Check active app\n const activeApp = this.appManager.GetActiveApp();\n if (activeApp) {\n return activeApp.GetColor();\n }\n\n // Fall back to neutral color\n return NEUTRAL_APP_COLOR;\n }\n\n /**\n * Clears the cached Home app info.\n * Call this if apps are reloaded or user logs out.\n */\n public clearHomeAppCache(): void {\n this._homeAppId = undefined;\n this._homeAppColor = null;\n }\n\n // ════════════════════════════════════════════\n // Agent Context & Client Tools\n // ════════════════════════════════════════════\n\n /**\n * Observable stream of agent context updates from resource components.\n * The shell subscribes to this to update the ComponentCacheManager and\n * push changes to the chat overlay's AppContextSnapshot.DashboardContext.\n */\n public readonly AgentContextUpdated$ = new Subject<AgentContextUpdate>();\n\n /** The client tools currently surfaced to the agent (the most recent SetAgentClientTools set). */\n private currentAgentTools: NonNullable<AgentContextUpdate['AgentClientTools']> = [];\n\n /**\n * Tools captured for each cached resource component at the moment it was DETACHED, keyed by that\n * component (the one the cache manager tracks). Replayed on reattach. Captured at detach time (vs.\n * keyed by the registering component) so it works even when a resource WRAPPER component is what's\n * cached/reattached while an INNER child component is what actually called SetAgentClientTools\n * (e.g. Data Explorer's resource wrapper hosting its dashboard) — keying by the registerer would\n * miss on reattach. This keeps the agent's live tool set a function of the CURRENTLY attached\n * surface, fixing the staleness where a previous app's tools lingered after navigation.\n */\n private readonly agentToolsByDetachedResource = new Map<BaseResourceComponent, NonNullable<AgentContextUpdate['AgentClientTools']>>();\n\n /**\n * Latest `AppContextSnapshot` published by the Explorer app shell.\n *\n * Why: any embedded `<mj-conversation-chat-area>` instance outside the\n * floating chat overlay (Form Builder cockpit, future domain dashboards\n * that pop their own AI pane) needs to feed the SAME context the overlay\n * does so the agent sees what app + view + dashboard state the user is\n * looking at. Without this, the agent only sees the embedder's narrow\n * `AdditionalContext` slice and treats the user as if they have no app\n * context at all — which is the bug we just fixed.\n *\n * `MJExplorerAppComponent` is the canonical publisher (it owns the\n * snapshot construction); consumers SUBSCRIBE and bind the value to\n * their chat-area's `[appContext]`. Non-Explorer apps (custom MJ apps\n * that don't include explorer-app at all) build their own snapshot via\n * `BuildAppContextSnapshot()` in `@memberjunction/ai-core-plus`.\n *\n * Initial value is `null`; the publisher emits the first real snapshot\n * after the active app + nav state resolve on bootstrap.\n */\n public readonly AppContextSnapshot$ = new BehaviorSubject<AppContextSnapshot | null>(null);\n\n /**\n * Push a fresh AppContextSnapshot. Called by MJExplorerAppComponent\n * after each (a) app/tab change, (b) `handleAgentContextUpdate`\n * merging in `AdditionalContext` from a dashboard. Idempotent — no\n * de-duplication; embedders should treat the stream as \"the latest\n * value is canonical.\"\n */\n public PublishAppContextSnapshot(snapshot: AppContextSnapshot | null): void {\n this.AppContextSnapshot$.next(snapshot);\n }\n\n /**\n * Report the current agent-visible state from a resource component.\n * Call this whenever the dashboard's internal state changes (tab switch,\n * filter change, pipeline status change, drill-down, etc.).\n *\n * @param caller - Pass `this` from the calling component. Used to match\n * against the ComponentCacheManager to identify which cached component\n * this update belongs to.\n * @param context - Key-value pairs representing dashboard state the agent\n * should know about. Each dashboard defines its own shape.\n */\n public SetAgentContext(caller: BaseResourceComponent, context: Record<string, unknown>): void {\n this.AgentContextUpdated$.next({ Caller: caller, AgentContext: context });\n }\n\n /**\n * Register the client tools available from a resource component.\n * Call this on component init and whenever the available tools change.\n * Tools are automatically unregistered when the component becomes inactive\n * (tab switch) and re-registered when it becomes active again.\n *\n * @param caller - Pass `this` from the calling component.\n * @param tools - Array of tool definitions with Name, Description,\n * ParameterSchema (JSON Schema), and Handler function.\n */\n public SetAgentClientTools(caller: BaseResourceComponent, tools: Array<{\n Name: string;\n Description: string;\n ParameterSchema: Record<string, unknown>;\n Handler: (params: Record<string, unknown>) => Promise<unknown>;\n }>): void {\n this.currentAgentTools = tools;\n this.AgentContextUpdated$.next({ Caller: caller, AgentClientTools: tools });\n }\n\n /**\n * Re-publish a cached resource component's tools when its tab is re-focused. Cached components keep\n * their Angular instance but do NOT re-run `ngAfterViewInit`, so they never re-register on reattach\n * — the shell calls this so the just-reactivated surface's tools become the agent's active set\n * again. Replays the set captured for this component at its last detach; no-op (lets a fresh\n * component register itself) when none was captured (e.g. a component's very first attach).\n */\n public NotifyResourceReattached(caller: BaseResourceComponent): void {\n const tools = this.agentToolsByDetachedResource.get(caller);\n if (tools === undefined) {\n return;\n }\n this.currentAgentTools = tools;\n this.AgentContextUpdated$.next({ Caller: caller, AgentClientTools: tools });\n }\n\n /**\n * Capture + clear the active client tools when a resource component's tab is detached (navigated\n * away from), so the previous surface's tools aren't offered to the agent on the next surface. We\n * snapshot whatever tools are CURRENTLY active and key them by the detaching component, so\n * {@link NotifyResourceReattached} can replay them — robust to a wrapper component being the one\n * cached/reattached while an inner child actually registered the tools (e.g. Data Explorer).\n */\n public NotifyResourceDetached(caller: BaseResourceComponent): void {\n this.agentToolsByDetachedResource.set(caller, this.currentAgentTools);\n this.currentAgentTools = [];\n this.AgentContextUpdated$.next({ Caller: caller, AgentClientTools: [] });\n }\n\n /**\n * Drop a destroyed component's captured tools (e.g. on LRU eviction), so the map doesn't retain\n * references to dead component instances.\n */\n public ForgetResource(caller: BaseResourceComponent): void {\n this.agentToolsByDetachedResource.delete(caller);\n }\n\n ngOnDestroy(): void {\n this.subscriptions.forEach(sub => sub.unsubscribe());\n }\n\n /**\n * Set up global keyboard event listeners to track shift key state\n */\n private setupGlobalShiftKeyDetection(): void {\n // Track shift key via mousedown events (capture phase) instead of keydown/keyup.\n // This is more reliable because:\n // 1. MouseEvent.shiftKey always reflects the actual modifier state at click time\n // 2. No risk of \"stuck\" state from missed keyup events (focus loss, tab switch, etc.)\n // 3. Navigation is always triggered by a click, so the shift state is read\n // at exactly the right moment\n this.subscriptions.push(\n fromEvent<MouseEvent>(document, 'mousedown', { capture: true }).subscribe(event => {\n this.shiftKeyPressed = event.shiftKey;\n })\n );\n }\n\n /**\n * Get current shift key state\n */\n private isShiftPressed(): boolean {\n return this.shiftKeyPressed;\n }\n\n /**\n * Determine if a new tab should be forced based on options and shift key state\n */\n private shouldForceNewTab(options?: NavigationOptions): boolean {\n // If forceNewTab is explicitly set, use that\n if (options?.forceNewTab !== undefined) {\n return options.forceNewTab;\n }\n\n // Otherwise, use global shift key detection\n return this.isShiftPressed();\n }\n\n /**\n * Returns whether the caller should use OpenTabForced (force-new path) or\n * OpenTab (replace-temp path).\n *\n * Rule: only honor an explicit force-new request — from the user via\n * shift+click, or from the caller via `options.forceNewTab`. We deliberately\n * do NOT apply heuristics that auto-switch the workspace out of\n * single-resource mode on cross-resource navigation. A previous version of\n * this method tried to do that (\"force new if single-resource + different\n * resource\") and it caused a regression: every plain hyperlink click on a\n * record opened a new tab and dropped the user into multi-tab mode, even\n * though they didn't ask for it. That violated the principle that mode\n * transitions are user-driven (shift) or explicitly requested (options).\n *\n * If a particular caller really needs the parent context preserved when\n * creating/navigating to a child resource (e.g. \"+New\" on a related-entity\n * grid inside an open record), the caller should pass `forceNewTab: true`\n * in `NavigationOptions`. That keeps intent explicit at the call site\n * instead of buried in a global heuristic.\n */\n private handleSingleResourceModeTransition(forceNew: boolean, _newRequest: TabRequest): boolean {\n return forceNew;\n }\n\n /**\n * Check if a tab request matches an existing tab's resource\n */\n private isSameResource(tab: any, request: TabRequest): boolean {\n // Different apps = different resources\n if (tab.applicationId !== request.ApplicationId) {\n return false;\n }\n\n // For resource-based tabs, compare resourceType and recordId\n if (request.Configuration?.resourceType) {\n const requestRecordId = request.ResourceRecordId || '';\n const tabRecordId = tab.resourceRecordId || '';\n return tab.configuration?.resourceType === request.Configuration.resourceType &&\n tabRecordId === requestRecordId;\n }\n\n // For app nav items, compare appName and navItemName\n if (request.Configuration?.appName && request.Configuration?.navItemName) {\n return tab.configuration?.appName === request.Configuration.appName &&\n tab.configuration?.navItemName === request.Configuration.navItemName;\n }\n\n // Fallback to basic comparison\n return false;\n }\n\n /**\n * Open a navigation item within an app\n */\n public OpenNavItem(appId: string, navItem: NavItem, appColor: string, options?: NavigationOptions): string {\n let forceNew = this.shouldForceNewTab(options);\n\n // Get the app to find its name\n const app = this.appManager.GetAppById(appId);\n const appName = app?.Name || '';\n\n // Dynamic nav items (e.g. orphan entity records) carry their original tab Configuration\n // and should NOT get navItemName stamped on them — that would cause buildResourceUrl\n // to produce a nav-item-style URL like /app/home/<label> instead of the correct\n // resource-type URL like /app/home/record/Entity/ID|...\n const isDynamic = (navItem as DynamicNavItem).isDynamic === true;\n\n const request: TabRequest = {\n ApplicationId: appId,\n Title: navItem.Label,\n ResourceRecordId: navItem.RecordID || '', // Also store at top level for consistent tab matching\n Configuration: {\n route: navItem.Route,\n resourceType: navItem.ResourceType,\n driverClass: navItem.DriverClass, // Pass through DriverClass for Custom resource type\n recordId: navItem.RecordID,\n appName: appName, // Store app name for URL building\n appId: appId,\n ...(isDynamic ? {} : { navItemName: navItem.Label }), // Only set for static nav items\n ...(navItem.Configuration || {})\n },\n IsPinned: options?.pinTab || false\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n let tabId: string;\n if (forceNew) {\n // Always create a new tab\n tabId = this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n // Use existing OpenTab logic (may replace temporary tab)\n tabId = this.workspaceManager.OpenTab(request, appColor);\n }\n\n // Apply query params to the newly opened/activated tab if provided\n if (options?.queryParams) {\n this.applyQueryParamsToTab(tabId, options.queryParams);\n }\n\n return tabId;\n }\n\n /**\n * Open an entity record view. Behavior forks on the deployment's\n * record-open style (see record-open-style.ts):\n * - 'records' (default): the record ALWAYS opens as its own tab, assigned\n * to the app the user is standing in (no Home reassignment, no nav flip).\n * Re-opening a record that's already open focuses its existing tab,\n * browser-style. The shell's Records pill + strip are the visible UI.\n * - 'classic': the original Home-first assignment and tab semantics.\n * Both styles capture the source-app trail into the tab configuration for\n * context UI and diagnostics.\n */\n public OpenEntityRecord(\n entityName: string,\n recordPkey: CompositeKey,\n options?: NavigationOptions\n ): string {\n const tabsMode = IsRecordTabsStyle();\n\n const activeApp = this.appManager.GetActiveApp();\n const appId = tabsMode && activeApp ? activeApp.ID : this.getDefaultApplicationId();\n const appColor = tabsMode && activeApp ? activeApp.GetColor() : this.getDefaultAppColor();\n\n const recordId = recordPkey.ToURLSegment();\n\n // Browser-style dedup: if this exact record is already open in a tab,\n // focus that tab instead of opening a second copy\n if (tabsMode) {\n const existing = this.findOpenRecordTab(entityName, recordId);\n if (existing) {\n // RE-CAPTURE the origin: re-opening means \"I came from somewhere\n // NEW\" — the crumb must point at where the user is standing for\n // THIS open, not wherever they were when the tab was first created\n // (possibly days ago, possibly under an older origin schema).\n this.refreshSourceContext(existing.id, options);\n // The activation assert applies to RE-opens too — the same-click\n // stale-stomp that motivated it for fresh opens is equally possible\n // here, and without it the symptom is maddening: opening a record\n // works the FIRST time and silently fails every time after.\n this.workspaceManager.SetActiveTab(existing.id);\n this.assertRecordActivation(existing.id);\n return existing.id;\n }\n }\n\n let forceNew = tabsMode || this.shouldForceNewTab(options);\n\n const request: TabRequest = {\n ApplicationId: appId,\n Title: `${entityName} - ${recordId}`,\n Configuration: {\n resourceType: RECORDS_RESOURCE_TYPE,\n Entity: entityName, // Must use 'Entity' (capital E) - expected by record-resource.component\n recordId: recordId, // Also needed in Configuration for tab-container.component to populate ResourceRecordID\n ...this.resolveSourceContext(options)\n },\n ResourceRecordId: recordId,\n IsPinned: options?.pinTab || false,\n // Records style: opening a record must not pin the nav tab (see\n // TabRequest.PreservePinState) — a pinned nav tab forces the main tab\n // bar visible on every nav page.\n PreservePinState: tabsMode\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n let tabId: string;\n if (forceNew) {\n tabId = this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n tabId = this.workspaceManager.OpenTab(request, appColor);\n }\n\n if (tabsMode) {\n this.assertRecordActivation(tabId);\n }\n\n return tabId;\n }\n\n /**\n * Opening a record means the record WINS the activation race — assert it\n * after the synchronous open flow settles. Surfaces that both emit a\n * record-open AND run their own internal navigation in the same click\n * (e.g. a grid row's select handler updating query params from a config\n * snapshot captured before the open) can otherwise stomp the activation\n * with stale state, leaving the tab open but never shown. Skipped when the\n * tab was closed in the meantime.\n */\n private assertRecordActivation(tabId: string): void {\n setTimeout(() => {\n const config = this.workspaceManager.GetConfiguration();\n if (config?.tabs.some(t => t.id === tabId) && config.activeTabId !== tabId) {\n this.workspaceManager.SetActiveTab(tabId);\n }\n }, 0);\n }\n\n /** Find an already-open tab showing this exact record (records-style dedup) */\n private findOpenRecordTab(entityName: string, recordId: string): { id: string } | null {\n const config = this.workspaceManager.GetConfiguration();\n const match = config?.tabs.find(t =>\n t.resourceRecordId === recordId &&\n t.configuration?.['resourceType'] === RECORDS_RESOURCE_TYPE &&\n t.configuration?.['Entity'] === entityName\n );\n return match ? { id: match.id } : null;\n }\n\n /**\n * Overwrite a record tab's origin with a freshly-resolved one (the dedup\n * re-open path). All source keys are explicitly cleared first — a shallow\n * config merge would otherwise let fields from the OLD origin shape leak\n * through (e.g. a parent-record origin's sourceRecordEntity surviving a\n * re-open from a nav page, or pre-schema captures keeping stale labels).\n */\n private refreshSourceContext(tabId: string, options?: NavigationOptions): void {\n this.workspaceManager.UpdateTabConfiguration(tabId, {\n sourceAppId: undefined,\n sourceAppName: undefined,\n sourceNavLabel: undefined,\n sourceNavItemName: undefined,\n sourceTabId: undefined,\n sourceLabel: undefined,\n sourceQueryParams: undefined,\n sourceRecordEntity: undefined,\n sourceRecordId: undefined,\n ...this.resolveSourceContext(options)\n });\n }\n\n /**\n * Resolve the source context to stamp into a record tab's configuration.\n * Callers that are workspace tabs omit options.recordSource and get the\n * active app/tab snapshot; overlay surfaces pass their own context;\n * 'none' means no origin (no crumb).\n */\n private resolveSourceContext(options?: NavigationOptions): Record<string, unknown> {\n if (options?.recordSource === 'none') {\n return {};\n }\n if (options?.recordSource) {\n const src = options.recordSource;\n const context: Record<string, unknown> = {};\n if (src.sourceAppId) context['sourceAppId'] = src.sourceAppId;\n if (src.sourceAppName) context['sourceAppName'] = src.sourceAppName;\n if (src.sourceNavLabel) context['sourceNavLabel'] = src.sourceNavLabel;\n if (src.sourceTabId) context['sourceTabId'] = src.sourceTabId;\n if (src.sourceLabel) context['sourceLabel'] = src.sourceLabel;\n if (src.sourceQueryParams && Object.keys(src.sourceQueryParams).length > 0) {\n context['sourceQueryParams'] = src.sourceQueryParams;\n }\n return context;\n }\n return this.captureSourceContext();\n }\n\n /**\n * Snapshot of where the user was when the record was\n * opened — the source app and (when the active tab belongs to that app and\n * isn't itself a record) the nav page they were on. Rendered by the\n * breadcrumb strip as \"App › Page › Record\".\n */\n private captureSourceContext(): Record<string, unknown> {\n const activeApp = this.appManager.GetActiveApp();\n if (!activeApp) {\n return {};\n }\n const context: Record<string, unknown> = {\n sourceAppId: activeApp.ID,\n sourceAppName: activeApp.Name\n };\n const config = this.workspaceManager.GetConfiguration();\n const activeTab = config?.tabs.find(t => t.id === config.activeTabId);\n if (!activeTab || !UUIDsEqual(activeTab.applicationId, activeApp.ID) || !activeTab.title) {\n return context;\n }\n if (IsRecordsTabConfiguration(activeTab.configuration)) {\n // Opened from INSIDE another record → the crumb points at the PARENT\n // record (Matt's record→record design call). Identity, not just the\n // tab id, so the return survives tab closure (re-open via dedup).\n const parentEntity = activeTab.configuration?.['Entity'];\n const parentRecordId = activeTab.resourceRecordId || activeTab.configuration?.['recordId'];\n if (typeof parentEntity === 'string' && typeof parentRecordId === 'string' && parentRecordId) {\n context['sourceTabId'] = activeTab.id;\n context['sourceLabel'] = activeTab.title;\n context['sourceRecordEntity'] = parentEntity;\n context['sourceRecordId'] = parentRecordId;\n }\n return context;\n }\n context['sourceNavLabel'] = activeTab.title;\n // Canonical nav identity alongside the display title: titles mutate\n // (Data Explorer renames its tab to the drilled entity), so the return\n // path verifies/resolves by navItemName and shows the label.\n const navItemName = activeTab.configuration?.['navItemName'];\n if (typeof navItemName === 'string' && navItemName.length > 0) {\n context['sourceNavItemName'] = navItemName;\n }\n // The exact tab, not just its label — the origin crumb's return path\n // prefers reactivating this tab (state intact) over re-resolving the\n // nav item by label.\n context['sourceTabId'] = activeTab.id;\n // Snapshot the tab's query params too: dashboards keep their DRILL-IN\n // state there (e.g. Data Explorer's entity section), and it can drift\n // or be stomped between open and return. The crumb restores the page\n // AS IT WAS, not just the tab.\n const queryParams = activeTab.configuration?.['queryParams'];\n if (queryParams && typeof queryParams === 'object' && Object.keys(queryParams).length > 0) {\n context['sourceQueryParams'] = { ...(queryParams as Record<string, string>) };\n }\n return context;\n }\n\n /**\n * Switch to an app's LANDING page — its default nav item in its BASE\n * state (drifted section params cleared, reset force-delivered so the\n * dashboard actually returns to its landing even if its state diverged).\n * The origin crumb's APP segment uses this: classic breadcrumb semantics,\n * each level goes to that level's home.\n */\n async SwitchToAppHome(appId: string): Promise<void> {\n const app = this.appManager.GetAllApps().find(a => UUIDsEqual(a.ID, appId));\n if (!app) {\n return;\n }\n const navItems = await app.GetNavItems();\n const home = navItems.find(i => i.isDefault) ?? navItems[0];\n await this.SwitchToApp(appId, home?.Label);\n const tabId = this.workspaceManager.GetActiveTabId();\n if (!tabId) {\n return;\n }\n const tab = this.workspaceManager.GetTab(tabId);\n const current = (tab?.configuration?.['queryParams'] || {}) as Record<string, string>;\n const clear: Record<string, string | null> = {};\n for (const key of Object.keys(current)) {\n clear[key] = null;\n }\n if (Object.keys(clear).length > 0) {\n this.applyQueryParamsToTab(tabId, clear);\n }\n this.NotifyQueryParamsChanged(tabId, {}, true);\n }\n\n /**\n * Take the user back to where they were when a record was opened (the\n * origin crumb's click path). Fidelity ladder:\n * 1. The exact source tab, if it's still open — reactivate it with all its\n * state (query params, scroll, cached component) intact.\n * 2. Otherwise re-resolve by app + nav label via SwitchToApp, which reuses\n * a matching open tab or opens the nav item fresh.\n * No-ops when the context has no sourceAppId (capture was best-effort).\n */\n public async ReturnToRecordSource(origin: RecordSourceContext): Promise<void> {\n // Parent-RECORD origin (opened from inside another record): activate the\n // parent's tab while it still shows that record, else RE-OPEN the parent\n // — OpenEntityRecord's dedup makes the re-open land on (or recreate)\n // exactly that record. No app flip either way: record tabs live in the\n // records region regardless of app.\n if (origin.sourceRecordEntity && origin.sourceRecordId) {\n const config = this.workspaceManager.GetConfiguration();\n const sourceTab = origin.sourceTabId ? config?.tabs.find(t => t.id === origin.sourceTabId) : undefined;\n const stillParent = !!sourceTab &&\n IsRecordsTabConfiguration(sourceTab.configuration) &&\n sourceTab.configuration?.['Entity'] === origin.sourceRecordEntity &&\n sourceTab.resourceRecordId === origin.sourceRecordId;\n if (sourceTab && stillParent) {\n this.workspaceManager.SetActiveTab(sourceTab.id);\n return;\n }\n const parentKey = new CompositeKey();\n parentKey.SimpleLoadFromURLSegment(origin.sourceRecordId);\n this.OpenEntityRecord(origin.sourceRecordEntity, parentKey);\n return;\n }\n if (!origin.sourceAppId) {\n return;\n }\n if (origin.sourceTabId) {\n const config = this.workspaceManager.GetConfiguration();\n const sourceTab = config?.tabs.find(t => t.id === origin.sourceTabId);\n // Tab ids are NOT stable identities for nav pages: the temp-tab\n // replacement model (WorkspaceStateManager.OpenTab) reuses the same\n // tab id when the user navigates elsewhere — the captured id can now\n // hold a DIFFERENT page in a DIFFERENT app. Trust it only while the\n // tab still shows the captured page; otherwise fall through to\n // re-resolving by app + nav item below. Prefer navItemName for the\n // page check — TITLES MUTATE (Data Explorer renames its tab to the\n // drilled entity), and a mutated title must not disqualify the tab.\n const tabNavItemName = sourceTab?.configuration?.['navItemName'];\n const samePage = origin.sourceNavItemName && typeof tabNavItemName === 'string'\n ? tabNavItemName === origin.sourceNavItemName\n : (!origin.sourceNavLabel || sourceTab?.title === origin.sourceNavLabel);\n const stillSourcePage = !!sourceTab &&\n (!origin.sourceAppId || UUIDsEqual(sourceTab.applicationId, origin.sourceAppId)) &&\n samePage;\n if (sourceTab && stillSourcePage) {\n // Restore the tab's query params to the capture-time snapshot BEFORE\n // activating, so a cached resource component reattaches against the\n // right config (see SwitchToApp's queryParams doc). REPLACE\n // semantics: null out params the tab has gained since capture, then\n // lay the snapshot over — \"back\" means the page as it was, and\n // drill-in state (e.g. Data Explorer's entity section) lives here.\n const currentParams = (sourceTab.configuration?.['queryParams'] || {}) as Record<string, string>;\n const restore: Record<string, string | null> = {};\n for (const key of Object.keys(currentParams)) {\n restore[key] = null;\n }\n Object.assign(restore, origin.sourceQueryParams ?? {});\n if (Object.keys(restore).length > 0) {\n this.applyQueryParamsToTab(sourceTab.id, restore);\n }\n // FORCE delivery: the component's state may have drifted while its\n // last-delivered params already equal the snapshot — the reactive\n // path would drop the restore as a duplicate (crumb lands on the\n // dashboard's home instead of the captured section).\n if (origin.sourceQueryParams && Object.keys(origin.sourceQueryParams).length > 0) {\n this.NotifyQueryParamsChanged(sourceTab.id, origin.sourceQueryParams, true);\n }\n // Set the app context first so the shell's nav renders the right\n // app the moment the tab activates (activation alone would also\n // flip it, but explicit sequencing avoids a visible two-step).\n await this.appManager.SetActiveApp(sourceTab.applicationId);\n this.workspaceManager.SetActiveTab(sourceTab.id);\n return;\n }\n }\n // Re-resolve by the CANONICAL nav-item name when we have it — the label\n // is a display title that may have mutated into something SwitchToApp's\n // nav-item lookup can't match (e.g. a drilled entity name).\n await this.SwitchToApp(origin.sourceAppId, origin.sourceNavItemName ?? origin.sourceNavLabel, origin.sourceQueryParams);\n // Same drift-proofing as the exact-tab path: force the delivery so the\n // restore can't be deduped away.\n if (origin.sourceQueryParams && Object.keys(origin.sourceQueryParams).length > 0) {\n const targetTabId = this.workspaceManager.GetActiveTabId();\n if (targetTabId) {\n this.NotifyQueryParamsChanged(targetTabId, origin.sourceQueryParams, true);\n }\n }\n }\n\n /**\n * Open a view\n * Uses Home app if available, otherwise falls back to active app or system app\n */\n public OpenView(\n viewId: string,\n viewName: string,\n options?: NavigationOptions\n ): string {\n const appId = this.getDefaultApplicationId();\n const appColor = this.getDefaultAppColor();\n let forceNew = this.shouldForceNewTab(options);\n\n const request: TabRequest = {\n ApplicationId: appId,\n Title: viewName,\n Configuration: {\n resourceType: 'MJ: User Views',\n viewId,\n recordId: viewId // Also needed in Configuration for tab-container.component to populate ResourceRecordID\n },\n ResourceRecordId: viewId,\n IsPinned: options?.pinTab || false\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n if (forceNew) {\n return this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n return this.workspaceManager.OpenTab(request, appColor);\n }\n }\n\n /**\n * Open a dashboard\n * Uses Home app if available, otherwise falls back to active app or system app\n */\n public OpenDashboard(\n dashboardId: string,\n dashboardName: string,\n options?: NavigationOptions\n ): string {\n const appId = this.getDefaultApplicationId();\n const appColor = this.getDefaultAppColor();\n let forceNew = this.shouldForceNewTab(options);\n\n const request: TabRequest = {\n ApplicationId: appId,\n Title: dashboardName,\n Configuration: {\n resourceType: 'Dashboards',\n dashboardId,\n recordId: dashboardId // Also needed in Configuration for tab-container.component to populate ResourceRecordID\n },\n ResourceRecordId: dashboardId,\n IsPinned: options?.pinTab || false\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n if (forceNew) {\n return this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n return this.workspaceManager.OpenTab(request, appColor);\n }\n }\n\n /**\n * Open a report\n * Uses Home app if available, otherwise falls back to active app or system app\n */\n public OpenReport(\n reportId: string,\n reportName: string,\n options?: NavigationOptions\n ): string {\n const appId = this.getDefaultApplicationId();\n const appColor = this.getDefaultAppColor();\n let forceNew = this.shouldForceNewTab(options);\n\n const request: TabRequest = {\n ApplicationId: appId,\n Title: reportName,\n Configuration: {\n resourceType: 'Reports',\n reportId,\n recordId: reportId // Also needed in Configuration for tab-container.component to populate ResourceRecordID\n },\n ResourceRecordId: reportId,\n IsPinned: options?.pinTab || false\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n if (forceNew) {\n return this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n return this.workspaceManager.OpenTab(request, appColor);\n }\n }\n\n /**\n * Open an artifact\n * Artifacts are versioned content containers (reports, dashboards, UI components, etc.)\n * Uses Home app if available, otherwise falls back to active app or system app\n */\n public OpenArtifact(\n artifactId: string,\n artifactName?: string,\n options?: NavigationOptions\n ): string {\n const appId = this.getDefaultApplicationId();\n const appColor = this.getDefaultAppColor();\n let forceNew = this.shouldForceNewTab(options);\n\n const request: TabRequest = {\n ApplicationId: appId,\n Title: artifactName || `Artifact - ${artifactId}`,\n Configuration: {\n resourceType: 'Artifacts',\n artifactId,\n recordId: artifactId // Also needed in Configuration for tab-container.component to populate ResourceRecordID\n },\n ResourceRecordId: artifactId,\n IsPinned: options?.pinTab || false\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n if (forceNew) {\n return this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n return this.workspaceManager.OpenTab(request, appColor);\n }\n }\n\n /**\n * Open a dynamic view\n * Dynamic views are entity-based views with custom filters, not saved views\n * Uses Home app if available, otherwise falls back to active app or system app\n */\n public OpenDynamicView(\n entityName: string,\n extraFilter?: string,\n options?: NavigationOptions\n ): string {\n const appId = this.getDefaultApplicationId();\n const appColor = this.getDefaultAppColor();\n let forceNew = this.shouldForceNewTab(options);\n\n const filterSuffix = extraFilter ? ' (Filtered)' : '';\n const request: TabRequest = {\n ApplicationId: appId,\n Title: `${entityName}${filterSuffix}`,\n Configuration: {\n resourceType: 'MJ: User Views',\n Entity: entityName,\n ExtraFilter: extraFilter,\n isDynamic: true,\n recordId: 'dynamic' // Special marker for dynamic views\n },\n ResourceRecordId: 'dynamic',\n IsPinned: options?.pinTab || false\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n if (forceNew) {\n return this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n return this.workspaceManager.OpenTab(request, appColor);\n }\n }\n\n /**\n * Open a query\n * Uses Home app if available, otherwise falls back to active app or system app\n */\n public OpenQuery(\n queryId: string,\n queryName: string,\n options?: NavigationOptions\n ): string {\n const appId = this.getDefaultApplicationId();\n const appColor = this.getDefaultAppColor();\n let forceNew = this.shouldForceNewTab(options);\n\n const request: TabRequest = {\n ApplicationId: appId,\n Title: queryName,\n Configuration: {\n resourceType: 'Queries',\n queryId,\n recordId: queryId // Also needed in Configuration for tab-container.component to populate ResourceRecordID\n },\n ResourceRecordId: queryId,\n IsPinned: options?.pinTab || false\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n if (forceNew) {\n return this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n return this.workspaceManager.OpenTab(request, appColor);\n }\n }\n\n /**\n * Open a new entity record creation form\n * Uses Home app if available, otherwise falls back to active app or system app\n * @param entityName The name of the entity to create a new record for\n * @param options Navigation options including optional newRecordValues for pre-populating fields\n */\n public OpenNewEntityRecord(\n entityName: string,\n options?: NavigationOptions\n ): string {\n // Records style: new-record tabs are RECORD tabs and get the same\n // treatment as OpenEntityRecord — assigned to the ACTIVE app, always a\n // new tab, nav pins preserved, origin captured. Without the forceNew,\n // the non-forced OpenTab consumed the user's nav page as the\n // replaceable temp tab and CONVERTED it into a records-region tab —\n // silently destroying the page they were on.\n const tabsMode = IsRecordTabsStyle();\n const activeApp = this.appManager.GetActiveApp();\n const appId = tabsMode && activeApp ? activeApp.ID : this.getDefaultApplicationId();\n const appColor = tabsMode && activeApp ? activeApp.GetColor() : this.getDefaultAppColor();\n\n let forceNew = tabsMode || this.shouldForceNewTab(options);\n\n const request: TabRequest = {\n ApplicationId: appId,\n Title: `New ${entityName}`,\n Configuration: {\n resourceType: RECORDS_RESOURCE_TYPE,\n Entity: entityName, // Must use 'Entity' (capital E) - expected by record-resource.component\n recordId: '', // Empty recordId indicates new record\n isNew: true, // Flag to indicate this is a new record\n NewRecordValues: options?.newRecordValues, // Pass through initial values if provided\n ...this.resolveSourceContext(options)\n },\n ResourceRecordId: '', // Empty for new records\n IsPinned: options?.pinTab || false,\n PreservePinState: tabsMode\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n let tabId: string;\n if (forceNew) {\n tabId = this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n tabId = this.workspaceManager.OpenTab(request, appColor);\n }\n\n if (tabsMode) {\n this.assertRecordActivation(tabId);\n }\n\n return tabId;\n }\n\n /**\n * Open a universal search results tab for the given query.\n * This is the primary way to open search results from anywhere in the application.\n *\n * @param query The search query text\n * @param searchOptions Optional search-specific options (e.g., minRelevance, scopeIDs)\n * @param options Navigation options\n */\n public OpenSearch(\n query: string,\n searchOptions?: { minRelevance?: number; scopeIDs?: string[] },\n options?: NavigationOptions\n ): string {\n const appId = this.getDefaultApplicationId();\n const appColor = this.getDefaultAppColor();\n let forceNew = this.shouldForceNewTab(options);\n\n const config: Record<string, unknown> = {\n resourceType: 'Search Results',\n Query: query,\n SearchInput: query,\n recordId: `search-${query}`\n };\n if (searchOptions?.minRelevance != null) {\n config['MinRelevance'] = searchOptions.minRelevance;\n }\n if (searchOptions?.scopeIDs && searchOptions.scopeIDs.length > 0) {\n config['ScopeIDs'] = searchOptions.scopeIDs;\n }\n\n const request: TabRequest = {\n ApplicationId: appId,\n Title: `Search: ${query}`,\n Configuration: config,\n ResourceRecordId: `search-${query}`,\n IsPinned: false\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n if (forceNew) {\n return this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n return this.workspaceManager.OpenTab(request, appColor);\n }\n }\n\n /**\n * Navigate to a nav item by name within the current or specified application.\n * Allows passing additional configuration parameters to merge with the nav item's config.\n * This is useful for cross-resource navigation where a component needs to navigate\n * to another nav item with specific parameters (e.g., navigate to Conversations with a specific conversationId).\n *\n * @param navItemName The label/name of the nav item to navigate to\n * @param configuration Additional configuration to merge (e.g., conversationId, artifactId)\n * @param appId Optional app ID (defaults to current active app)\n * @param options Navigation options\n * @returns The tab ID if successful, null if nav item not found\n */\n public async OpenNavItemByName(\n navItemName: string,\n configuration?: Record<string, unknown>,\n appId?: string,\n options?: NavigationOptions\n ): Promise<string | null> {\n // Get app (use provided or current active)\n const targetAppId = appId || this.appManager.GetActiveApp()?.ID;\n if (!targetAppId) {\n return null;\n }\n\n const app = this.appManager.GetAppById(targetAppId);\n if (!app) {\n return null;\n }\n\n // Find the nav item by name\n const navItems = await app.GetNavItems();\n const navItem = navItems.find(item => item.Label === navItemName);\n if (!navItem) {\n return null;\n }\n\n // Create a merged nav item with additional configuration\n const mergedNavItem: NavItem = {\n ...navItem,\n Configuration: {\n ...(navItem.Configuration || {}),\n ...(configuration || {})\n }\n };\n\n // Use existing OpenNavItem\n return this.OpenNavItem(targetAppId, mergedNavItem, app.GetColor(), options);\n }\n\n /**\n * Switch to an application by ID.\n * This sets the app as active and either opens a specific nav item or creates a default tab.\n * If the requested nav item already has an open tab, switches to that tab instead of creating a new one.\n * @param appId The application ID to switch to\n * @param navItemName Optional name of a nav item to open within the app. If provided, opens that nav item.\n * @param queryParams Optional query params to apply to the target tab. Applied SYNCHRONOUSLY once the\n * target tab is active — critical when navigating (e.g. from a Home pin) to an\n * app whose resource component is cached: the params must be in the tab config\n * BEFORE the tab-container reattaches the cached component, otherwise the cache\n * restores its own (stale) saved params and the navigation intent is lost.\n */\n async SwitchToApp(appId: string, navItemName?: string, queryParams?: Record<string, string | null>): Promise<void> {\n await this.appManager.SetActiveApp(appId);\n\n const app = this.appManager.GetAllApps().find(a => UUIDsEqual(a.ID, appId));\n if (!app) {\n return;\n }\n\n // Records style: record tabs are ASSIGNED to apps but live in their own\n // region — switching to an app must surface its NAV pages, so records\n // don't count here. Without this filter, the active record tab (which\n // belongs to the target app) satisfied the \"already on this app's tab\"\n // check and the whole switch silently no-oped — the dead origin-crumb\n // click when the crumb only knew the app. Records DOCKED to the\n // workspace are excluded too (identity check, not region membership):\n // switch-to-app must land on a page, never a record. Classic style\n // keeps records as ordinary tabs.\n const appTabs = IsRecordTabsStyle()\n ? this.workspaceManager.GetAppTabs(appId).filter(t => !IsRecordsTabConfiguration(t.configuration))\n : this.workspaceManager.GetAppTabs(appId);\n\n // If a specific nav item is requested\n if (navItemName) {\n const navItems = await app.GetNavItems();\n const navItem = navItems.find(item => item.Label === navItemName);\n if (navItem) {\n // Check if there's already a tab for this nav item. Identity check\n // uses configuration.navItemName when the tab carries it — TITLES\n // LIE: same-driver nav switches reuse the live tab and can leave a\n // stale title behind (e.g. Data Explorer's tab titled \"Data\" while\n // its content and navItemName say \"Dashboards\"). Matching that\n // chimera by title activated the WRONG page instead of reopening\n // the requested nav item.\n const existingTab = appTabs.find(tab => {\n const tabNav = tab.configuration?.['navItemName'];\n if (typeof tabNav === 'string' && tabNav.length > 0) {\n return tabNav === navItem.Label;\n }\n return tab.title === navItem.Label ||\n (tab.configuration?.['route'] === navItem.Route && !!navItem.Route);\n });\n\n if (existingTab) {\n // Switch to existing tab\n this.workspaceManager.SetActiveTab(existingTab.id);\n } else {\n // Open new tab for this nav item\n this.OpenNavItem(appId, navItem, app.GetColor());\n }\n // Apply the requested query params to whichever tab is now active — synchronously,\n // so they're present before the (possibly cached) resource component reattaches.\n if (queryParams && Object.keys(queryParams).length > 0) {\n const targetTabId = this.workspaceManager.GetActiveTabId();\n if (targetTabId) {\n this.applyQueryParamsToTab(targetTabId, queryParams);\n }\n }\n return;\n }\n // Nav item not found, fall through to default behavior\n }\n\n // No specific nav item requested - check if app has any tabs\n if (appTabs.length === 0) {\n // Create default tab\n const tabRequest = await app.CreateDefaultTab();\n if (tabRequest) {\n this.workspaceManager.OpenTab(tabRequest, app.GetColor());\n }\n } else {\n // App has tabs - switch to the first one (or active one if exists)\n const config = this.workspaceManager.GetConfiguration();\n const activeAppTab = appTabs.find(t => t.id === config?.activeTabId);\n if (!activeAppTab) {\n // No active tab for this app, switch to first tab\n this.workspaceManager.SetActiveTab(appTabs[0].id);\n }\n }\n\n // Apply requested query params on the DEFAULT path too (previously only the\n // navItemName branch did) — e.g. the omnibar's '@agent' → Chat pre-addressing.\n // Synchronous, so params are present before a cached resource component reattaches.\n if (queryParams && Object.keys(queryParams).length > 0) {\n const targetTabId = this.workspaceManager.GetActiveTabId();\n if (targetTabId) {\n this.applyQueryParamsToTab(targetTabId, queryParams);\n }\n }\n }\n\n /**\n * Update the query params for the currently active tab.\n * This updates the tab's configuration and triggers a URL sync via the shell's\n * workspace configuration subscription.\n *\n * Use this instead of directly calling router.navigate() to ensure proper\n * URL management that respects app-scoped routes.\n *\n * @param queryParams Object containing query param key-value pairs.\n * Use null values to remove a query param.\n * @example\n * // Add or update query params\n * navigationService.UpdateActiveTabQueryParams({ category: 'abc123', dashboard: 'xyz789' });\n *\n * // Remove a query param\n * navigationService.UpdateActiveTabQueryParams({ category: null });\n */\n UpdateActiveTabQueryParams(queryParams: Record<string, string | null>): void {\n const activeTabId = this.workspaceManager.GetActiveTabId();\n if (!activeTabId) {\n console.warn('NavigationService.UpdateActiveTabQueryParams: No active tab');\n return;\n }\n\n this.applyQueryParamsToTab(activeTabId, queryParams);\n }\n\n /**\n * Update query params for a specific tab, optionally only if the tab still hosts\n * the expected resource identity. This matters in single-resource mode where a\n * tab ID can be reused for a different resource while the previous component is\n * detached but still alive in the cache.\n */\n UpdateTabQueryParams(\n tabId: string,\n queryParams: Record<string, string | null>,\n guard?: TabQueryParamUpdateGuard\n ): boolean {\n const tab = this.workspaceManager.GetTab(tabId);\n if (!tab) {\n console.debug('NavigationService.UpdateTabQueryParams: Tab not found; ignoring stale query-param update:', tabId);\n return false;\n }\n\n if (guard && !this.tabMatchesQueryParamGuard(tab, guard)) {\n console.debug('NavigationService.UpdateTabQueryParams: Tab identity changed; ignoring stale query-param update:', {\n tabId,\n guard,\n current: {\n resourceType: tab.configuration?.['resourceType'],\n driverClass: tab.configuration?.['resourceTypeDriverClass'] || tab.configuration?.['driverClass'],\n recordId: tab.resourceRecordId || tab.configuration?.['recordId'],\n navItemName: tab.configuration?.['navItemName'],\n entity: tab.configuration?.['Entity'] || tab.configuration?.['entity']\n }\n });\n return false;\n }\n\n this.applyQueryParamsToTab(tabId, queryParams);\n return true;\n }\n\n /**\n * Notify subscribers that query params changed on a specific tab.\n * Called by the shell when back/forward navigation changes query params on the active tab.\n * The notification includes the tab ID so only the component in that tab reacts.\n */\n NotifyQueryParamsChanged(tabId: string, params: Record<string, string>, force = false): void {\n this.queryParamChanged$.next({ TabId: tabId, Params: params, Force: force });\n }\n\n /**\n * Reactively observe the query params for a specific tab.\n *\n * Backed by the workspace BehaviorSubject, so a subscriber receives the current\n * params *immediately* on subscribe AND every subsequent change — including the\n * deep-link params that the ResourceResolver merges into the tab configuration on\n * a cold/direct URL load.\n *\n * This is the race-free counterpart to {@link NotifyQueryParamsChanged} (a plain\n * Subject that drops events fired before a component has subscribed). A resource\n * component that mounts from workspace restoration can subscribe here and still\n * pick up its initial deep-link state regardless of whether the params landed in\n * the tab config before or after it mounted.\n */\n public ObserveTabQueryParams(tabId: string): Observable<Record<string, string>> {\n return this.workspaceManager.Configuration.pipe(\n map(config => {\n const tab = config?.tabs?.find(t => t.id === tabId);\n return (tab?.configuration?.['queryParams'] || {}) as Record<string, string>;\n }),\n distinctUntilChanged((a, b) => this.shallowParamsEqual(a, b))\n );\n }\n\n private shallowParamsEqual(a: Record<string, string>, b: Record<string, string>): boolean {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) {\n return false;\n }\n return keysA.every(key => a[key] === b[key]);\n }\n\n private tabMatchesQueryParamGuard(tab: { resourceRecordId?: string; configuration?: Record<string, unknown> }, guard: TabQueryParamUpdateGuard): boolean {\n const config = tab.configuration || {};\n const matches = (expected: string | null | undefined, actual: unknown, normalize = false): boolean => {\n if (expected === undefined || expected === null) {\n return true;\n }\n const expectedText = String(expected);\n const actualText = actual == null ? '' : String(actual);\n return normalize\n ? expectedText.trim().toLowerCase() === actualText.trim().toLowerCase()\n : expectedText === actualText;\n };\n\n const currentDriverClass = (config['resourceTypeDriverClass'] || config['driverClass']) as string | undefined;\n const currentRecordId = tab.resourceRecordId || (config['recordId'] as string | undefined) || '';\n const currentEntity = (config['Entity'] || config['entity']) as string | undefined;\n\n // Resource type and entity names can vary by casing/metadata spelling; class names,\n // record IDs, and nav labels are canonical tab identity fields and stay exact-match.\n return matches(guard.resourceType, config['resourceType'], true) &&\n matches(guard.driverClass, currentDriverClass) &&\n matches(guard.recordId, currentRecordId) &&\n matches(guard.navItemName, config['navItemName']) &&\n matches(guard.entity, currentEntity, true);\n }\n\n /**\n * Apply query params to a specific tab by ID.\n * Merges with any existing query params on the tab. Use null values to remove params.\n */\n private applyQueryParamsToTab(tabId: string, queryParams: Record<string, string | null>): void {\n const tab = this.workspaceManager.GetTab(tabId);\n if (!tab) {\n console.warn('NavigationService.applyQueryParamsToTab: Tab not found:', tabId);\n return;\n }\n\n // Get existing queryParams from tab configuration\n const existingQueryParams = (tab.configuration?.['queryParams'] || {}) as Record<string, string | null>;\n\n // Merge with new query params\n const mergedQueryParams: Record<string, string> = {};\n\n // Start with existing params (excluding nulls)\n for (const [key, value] of Object.entries(existingQueryParams)) {\n if (value !== null) {\n mergedQueryParams[key] = value;\n }\n }\n\n // Apply new params (null means remove)\n for (const [key, value] of Object.entries(queryParams)) {\n if (value === null) {\n delete mergedQueryParams[key];\n } else {\n mergedQueryParams[key] = value;\n }\n }\n\n // Update the tab configuration\n this.workspaceManager.UpdateTabConfiguration(tabId, {\n queryParams: Object.keys(mergedQueryParams).length > 0 ? mergedQueryParams : undefined\n });\n }\n}\n"]}
1
+ {"version":3,"file":"navigation.service.js","sourceRoot":"","sources":["../../src/lib/navigation.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable, OnDestroy } from '@angular/core';\nimport { WorkspaceStateManager, NavItem, DynamicNavItem, TabRequest, ApplicationManager } from '@memberjunction/ng-base-application';\nimport { NavigationOptions } from './navigation.interfaces';\nimport { IsRecordTabsStyle, RECORDS_RESOURCE_TYPE, IsRecordsTabConfiguration, RecordSourceContext } from './record-open-style';\nimport { CompositeKey } from '@memberjunction/core';\nimport { fromEvent, BehaviorSubject, Subject, Subscription, Observable } from 'rxjs';\nimport type { AppContextSnapshot } from '@memberjunction/ai-core-plus';\nimport { map, distinctUntilChanged } from 'rxjs/operators';\nimport { UUIDsEqual } from '@memberjunction/global';\nimport { BaseResourceComponent } from './base-resource-component';\n\n/**\n * Event emitted when query params change on a tab (e.g., from browser back/forward).\n * Includes the tab ID so that only the component in the affected tab reacts,\n * preventing cross-tab leakage in multi-tab scenarios.\n */\nexport interface QueryParamChangeEvent {\n TabId: string;\n Params: Record<string, string>;\n /**\n * Bypass the receiving component's duplicate-delivery guard. Set by\n * explicit restore navigations (e.g. the origin crumb): the component's\n * state may have DRIFTED from the last-delivered params, in which case a\n * restore to those same params would otherwise be dropped as a duplicate.\n */\n Force?: boolean;\n}\n\n/**\n * Event emitted when a resource component reports its agent context or tools.\n * The shell (which owns the ComponentCacheManager) subscribes to these events\n * and updates the cache + active AppContextSnapshot accordingly.\n */\nexport interface AgentContextUpdate {\n /** The component instance that reported the update */\n Caller: BaseResourceComponent;\n /** Dashboard-specific context for the agent (undefined = no change) */\n AgentContext?: Record<string, unknown>;\n /** Client tools available from this dashboard (undefined = no change) */\n AgentClientTools?: Array<{\n Name: string;\n Description: string;\n ParameterSchema: Record<string, unknown>;\n Handler: (params: Record<string, unknown>) => Promise<unknown>;\n }>;\n}\n\nexport interface TabQueryParamUpdateGuard {\n resourceType?: string | null;\n driverClass?: string | null;\n recordId?: string | null;\n navItemName?: string | null;\n entity?: string | null;\n}\n\n/**\n * System application ID for non-app-specific resources (fallback only)\n * Uses double underscore prefix to indicate system-level resource\n * @deprecated Prefer using NavigationService.getDefaultApplicationId() instead\n */\nexport const SYSTEM_APP_ID = '__explorer';\n\n/**\n * Neutral color for fallback when no app is available\n */\nconst NEUTRAL_APP_COLOR = '#9E9E9E'; // Material Design Gray 500\n\n/**\n * Centralized navigation service that handles all navigation operations\n * with automatic shift-key detection for power user workflows\n */\n@Injectable({\n providedIn: 'root'\n})\nexport class NavigationService implements OnDestroy {\n private shiftKeyPressed = false;\n private subscriptions: Subscription[] = [];\n\n private queryParamChanged$ = new Subject<QueryParamChangeEvent>();\n /** Observable that emits when query params change on a tab (back/forward navigation). */\n public QueryParamChanged$ = this.queryParamChanged$.asObservable();\n\n /** Cached Home app ID (null means not found, undefined means not checked) */\n private _homeAppId: string | null | undefined = undefined;\n /** Cached Home app color */\n private _homeAppColor: string | null = null;\n\n constructor(\n private workspaceManager: WorkspaceStateManager,\n private appManager: ApplicationManager\n ) {\n this.setupGlobalShiftKeyDetection();\n }\n\n /**\n * Get the neutral color used for system-wide resources (entities, views, dashboards)\n * Returns a light neutral gray\n * @deprecated Use getDefaultAppColor() for better UX with Home app integration\n */\n get ExplorerAppColor(): string {\n return NEUTRAL_APP_COLOR;\n }\n\n /**\n * Gets the default application ID for orphan resources.\n * Priority: Home app > Active app > SYSTEM_APP_ID\n *\n * This ensures orphan resources (entity records, dashboards, views opened directly)\n * are grouped under the Home app instead of being orphaned in the tab system.\n */\n private getDefaultApplicationId(): string {\n // Check cache first\n if (this._homeAppId !== undefined) {\n if (this._homeAppId !== null) {\n return this._homeAppId;\n }\n // Home app not found, check active app\n const activeApp = this.appManager.GetActiveApp();\n if (activeApp) {\n return activeApp.ID;\n }\n return SYSTEM_APP_ID;\n }\n\n // First time - look for Home app\n const homeApp = this.appManager.GetAppByName('Home');\n if (homeApp) {\n this._homeAppId = homeApp.ID;\n this._homeAppColor = homeApp.GetColor();\n return homeApp.ID;\n }\n\n // Cache that Home app doesn't exist\n this._homeAppId = null;\n\n // Fall back to currently active app\n const activeApp = this.appManager.GetActiveApp();\n if (activeApp) {\n return activeApp.ID;\n }\n\n // Last resort - system app ID\n return SYSTEM_APP_ID;\n }\n\n /**\n * Gets the default app color for orphan resources.\n * Returns Home app color if available, otherwise neutral gray.\n */\n private getDefaultAppColor(): string {\n // Ensure cache is populated\n this.getDefaultApplicationId();\n\n // If Home app exists, use its color\n if (this._homeAppColor) {\n return this._homeAppColor;\n }\n\n // Check active app\n const activeApp = this.appManager.GetActiveApp();\n if (activeApp) {\n return activeApp.GetColor();\n }\n\n // Fall back to neutral color\n return NEUTRAL_APP_COLOR;\n }\n\n /**\n * Clears the cached Home app info.\n * Call this if apps are reloaded or user logs out.\n */\n public clearHomeAppCache(): void {\n this._homeAppId = undefined;\n this._homeAppColor = null;\n }\n\n // ════════════════════════════════════════════\n // Agent Context & Client Tools\n // ════════════════════════════════════════════\n\n /**\n * Observable stream of agent context updates from resource components.\n * The shell subscribes to this to update the ComponentCacheManager and\n * push changes to the chat overlay's AppContextSnapshot.DashboardContext.\n */\n public readonly AgentContextUpdated$ = new Subject<AgentContextUpdate>();\n\n /** The client tools currently surfaced to the agent (the most recent SetAgentClientTools set). */\n private currentAgentTools: NonNullable<AgentContextUpdate['AgentClientTools']> = [];\n\n /**\n * Tools captured for each cached resource component at the moment it was DETACHED, keyed by that\n * component (the one the cache manager tracks). Replayed on reattach. Captured at detach time (vs.\n * keyed by the registering component) so it works even when a resource WRAPPER component is what's\n * cached/reattached while an INNER child component is what actually called SetAgentClientTools\n * (e.g. Data Explorer's resource wrapper hosting its dashboard) — keying by the registerer would\n * miss on reattach. This keeps the agent's live tool set a function of the CURRENTLY attached\n * surface, fixing the staleness where a previous app's tools lingered after navigation.\n */\n private readonly agentToolsByDetachedResource = new Map<BaseResourceComponent, NonNullable<AgentContextUpdate['AgentClientTools']>>();\n\n /**\n * Latest `AppContextSnapshot` published by the Explorer app shell.\n *\n * Why: any embedded `<mj-conversation-chat-area>` instance outside the\n * floating chat overlay (Form Builder cockpit, future domain dashboards\n * that pop their own AI pane) needs to feed the SAME context the overlay\n * does so the agent sees what app + view + dashboard state the user is\n * looking at. Without this, the agent only sees the embedder's narrow\n * `AdditionalContext` slice and treats the user as if they have no app\n * context at all — which is the bug we just fixed.\n *\n * `MJExplorerAppComponent` is the canonical publisher (it owns the\n * snapshot construction); consumers SUBSCRIBE and bind the value to\n * their chat-area's `[appContext]`. Non-Explorer apps (custom MJ apps\n * that don't include explorer-app at all) build their own snapshot via\n * `BuildAppContextSnapshot()` in `@memberjunction/ai-core-plus`.\n *\n * Initial value is `null`; the publisher emits the first real snapshot\n * after the active app + nav state resolve on bootstrap.\n */\n public readonly AppContextSnapshot$ = new BehaviorSubject<AppContextSnapshot | null>(null);\n\n /**\n * Push a fresh AppContextSnapshot. Called by MJExplorerAppComponent\n * after each (a) app/tab change, (b) `handleAgentContextUpdate`\n * merging in `AdditionalContext` from a dashboard. Idempotent — no\n * de-duplication; embedders should treat the stream as \"the latest\n * value is canonical.\"\n */\n public PublishAppContextSnapshot(snapshot: AppContextSnapshot | null): void {\n this.AppContextSnapshot$.next(snapshot);\n }\n\n /**\n * Report the current agent-visible state from a resource component.\n * Call this whenever the dashboard's internal state changes (tab switch,\n * filter change, pipeline status change, drill-down, etc.).\n *\n * @param caller - Pass `this` from the calling component. Used to match\n * against the ComponentCacheManager to identify which cached component\n * this update belongs to.\n * @param context - Key-value pairs representing dashboard state the agent\n * should know about. Each dashboard defines its own shape.\n */\n public SetAgentContext(caller: BaseResourceComponent, context: Record<string, unknown>): void {\n this.AgentContextUpdated$.next({ Caller: caller, AgentContext: context });\n }\n\n /**\n * Register the client tools available from a resource component.\n * Call this on component init and whenever the available tools change.\n * Tools are automatically unregistered when the component becomes inactive\n * (tab switch) and re-registered when it becomes active again.\n *\n * @param caller - Pass `this` from the calling component.\n * @param tools - Array of tool definitions with Name, Description,\n * ParameterSchema (JSON Schema), and Handler function.\n */\n public SetAgentClientTools(caller: BaseResourceComponent, tools: Array<{\n Name: string;\n Description: string;\n ParameterSchema: Record<string, unknown>;\n Handler: (params: Record<string, unknown>) => Promise<unknown>;\n }>): void {\n this.currentAgentTools = tools;\n this.AgentContextUpdated$.next({ Caller: caller, AgentClientTools: tools });\n }\n\n /**\n * Re-publish a cached resource component's tools when its tab is re-focused. Cached components keep\n * their Angular instance but do NOT re-run `ngAfterViewInit`, so they never re-register on reattach\n * — the shell calls this so the just-reactivated surface's tools become the agent's active set\n * again. Replays the set captured for this component at its last detach; no-op (lets a fresh\n * component register itself) when none was captured (e.g. a component's very first attach).\n */\n public NotifyResourceReattached(caller: BaseResourceComponent): void {\n const tools = this.agentToolsByDetachedResource.get(caller);\n if (tools === undefined) {\n return;\n }\n this.currentAgentTools = tools;\n this.AgentContextUpdated$.next({ Caller: caller, AgentClientTools: tools });\n }\n\n /**\n * Capture + clear the active client tools when a resource component's tab is detached (navigated\n * away from), so the previous surface's tools aren't offered to the agent on the next surface. We\n * snapshot whatever tools are CURRENTLY active and key them by the detaching component, so\n * {@link NotifyResourceReattached} can replay them — robust to a wrapper component being the one\n * cached/reattached while an inner child actually registered the tools (e.g. Data Explorer).\n */\n public NotifyResourceDetached(caller: BaseResourceComponent): void {\n this.agentToolsByDetachedResource.set(caller, this.currentAgentTools);\n this.currentAgentTools = [];\n this.AgentContextUpdated$.next({ Caller: caller, AgentClientTools: [] });\n }\n\n /**\n * Drop a destroyed component's captured tools (e.g. on LRU eviction), so the map doesn't retain\n * references to dead component instances.\n */\n public ForgetResource(caller: BaseResourceComponent): void {\n this.agentToolsByDetachedResource.delete(caller);\n }\n\n ngOnDestroy(): void {\n this.subscriptions.forEach(sub => sub.unsubscribe());\n }\n\n /**\n * Set up global keyboard event listeners to track shift key state\n */\n private setupGlobalShiftKeyDetection(): void {\n // Track shift key via mousedown events (capture phase) instead of keydown/keyup.\n // This is more reliable because:\n // 1. MouseEvent.shiftKey always reflects the actual modifier state at click time\n // 2. No risk of \"stuck\" state from missed keyup events (focus loss, tab switch, etc.)\n // 3. Navigation is always triggered by a click, so the shift state is read\n // at exactly the right moment\n this.subscriptions.push(\n fromEvent<MouseEvent>(document, 'mousedown', { capture: true }).subscribe(event => {\n this.shiftKeyPressed = event.shiftKey;\n })\n );\n }\n\n /**\n * Get current shift key state\n */\n private isShiftPressed(): boolean {\n return this.shiftKeyPressed;\n }\n\n /**\n * Determine if a new tab should be forced based on options and shift key state\n */\n private shouldForceNewTab(options?: NavigationOptions): boolean {\n // If forceNewTab is explicitly set, use that\n if (options?.forceNewTab !== undefined) {\n return options.forceNewTab;\n }\n\n // Otherwise, use global shift key detection\n return this.isShiftPressed();\n }\n\n /**\n * Returns whether the caller should use OpenTabForced (force-new path) or\n * OpenTab (replace-temp path).\n *\n * Rule: only honor an explicit force-new request — from the user via\n * shift+click, or from the caller via `options.forceNewTab`. We deliberately\n * do NOT apply heuristics that auto-switch the workspace out of\n * single-resource mode on cross-resource navigation. A previous version of\n * this method tried to do that (\"force new if single-resource + different\n * resource\") and it caused a regression: every plain hyperlink click on a\n * record opened a new tab and dropped the user into multi-tab mode, even\n * though they didn't ask for it. That violated the principle that mode\n * transitions are user-driven (shift) or explicitly requested (options).\n *\n * If a particular caller really needs the parent context preserved when\n * creating/navigating to a child resource (e.g. \"+New\" on a related-entity\n * grid inside an open record), the caller should pass `forceNewTab: true`\n * in `NavigationOptions`. That keeps intent explicit at the call site\n * instead of buried in a global heuristic.\n */\n private handleSingleResourceModeTransition(forceNew: boolean, _newRequest: TabRequest): boolean {\n return forceNew;\n }\n\n /**\n * Check if a tab request matches an existing tab's resource\n */\n private isSameResource(tab: any, request: TabRequest): boolean {\n // Different apps = different resources\n if (tab.applicationId !== request.ApplicationId) {\n return false;\n }\n\n // For resource-based tabs, compare resourceType and recordId\n if (request.Configuration?.resourceType) {\n const requestRecordId = request.ResourceRecordId || '';\n const tabRecordId = tab.resourceRecordId || '';\n return tab.configuration?.resourceType === request.Configuration.resourceType &&\n tabRecordId === requestRecordId;\n }\n\n // For app nav items, compare appName and navItemName\n if (request.Configuration?.appName && request.Configuration?.navItemName) {\n return tab.configuration?.appName === request.Configuration.appName &&\n tab.configuration?.navItemName === request.Configuration.navItemName;\n }\n\n // Fallback to basic comparison\n return false;\n }\n\n /**\n * Open a navigation item within an app\n */\n public OpenNavItem(appId: string, navItem: NavItem, appColor: string, options?: NavigationOptions): string {\n let forceNew = this.shouldForceNewTab(options);\n\n // Get the app to find its name\n const app = this.appManager.GetAppById(appId);\n const appName = app?.Name || '';\n\n // Dynamic nav items (e.g. orphan entity records) carry their original tab Configuration\n // and should NOT get navItemName stamped on them — that would cause buildResourceUrl\n // to produce a nav-item-style URL like /app/home/<label> instead of the correct\n // resource-type URL like /app/home/record/Entity/ID|...\n const isDynamic = (navItem as DynamicNavItem).isDynamic === true;\n\n const request: TabRequest = {\n ApplicationId: appId,\n Title: navItem.Label,\n ResourceRecordId: navItem.RecordID || '', // Also store at top level for consistent tab matching\n Configuration: {\n route: navItem.Route,\n resourceType: navItem.ResourceType,\n driverClass: navItem.DriverClass, // Pass through DriverClass for Custom resource type\n recordId: navItem.RecordID,\n appName: appName, // Store app name for URL building\n appId: appId,\n ...(isDynamic ? {} : { navItemName: navItem.Label }), // Only set for static nav items\n ...(navItem.Configuration || {})\n },\n IsPinned: options?.pinTab || false\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n let tabId: string;\n if (forceNew) {\n // Always create a new tab\n tabId = this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n // Use existing OpenTab logic (may replace temporary tab)\n tabId = this.workspaceManager.OpenTab(request, appColor);\n }\n\n // Apply query params to the newly opened/activated tab if provided\n if (options?.queryParams) {\n this.applyQueryParamsToTab(tabId, options.queryParams);\n }\n\n return tabId;\n }\n\n /**\n * Open an entity record view. Behavior forks on the deployment's\n * record-open style (see record-open-style.ts):\n * - 'records' (default): the record ALWAYS opens as its own tab, assigned\n * to the app the user is standing in (no Home reassignment, no nav flip).\n * Re-opening a record that's already open focuses its existing tab,\n * browser-style. The shell's Records pill + strip are the visible UI.\n * - 'classic': the original Home-first assignment and tab semantics.\n * Both styles capture the source-app trail into the tab configuration for\n * context UI and diagnostics.\n */\n public OpenEntityRecord(\n entityName: string,\n recordPkey: CompositeKey,\n options?: NavigationOptions\n ): string {\n const tabsMode = IsRecordTabsStyle();\n\n const activeApp = this.appManager.GetActiveApp();\n const appId = tabsMode && activeApp ? activeApp.ID : this.getDefaultApplicationId();\n const appColor = tabsMode && activeApp ? activeApp.GetColor() : this.getDefaultAppColor();\n\n const recordId = recordPkey.ToURLSegment();\n\n // Browser-style dedup: if this exact record is already open in a tab,\n // focus that tab instead of opening a second copy\n if (tabsMode) {\n const existing = this.findOpenRecordTab(entityName, recordId);\n if (existing) {\n // RE-CAPTURE the origin: re-opening means \"I came from somewhere\n // NEW\" — the crumb must point at where the user is standing for\n // THIS open, not wherever they were when the tab was first created\n // (possibly days ago, possibly under an older origin schema).\n this.refreshSourceContext(existing.id, options);\n // The activation assert applies to RE-opens too — the same-click\n // stale-stomp that motivated it for fresh opens is equally possible\n // here, and without it the symptom is maddening: opening a record\n // works the FIRST time and silently fails every time after.\n this.workspaceManager.SetActiveTab(existing.id);\n this.assertRecordActivation(existing.id);\n return existing.id;\n }\n }\n\n let forceNew = tabsMode || this.shouldForceNewTab(options);\n\n const request: TabRequest = {\n ApplicationId: appId,\n Title: `${entityName} - ${recordId}`,\n Configuration: {\n resourceType: RECORDS_RESOURCE_TYPE,\n Entity: entityName, // Must use 'Entity' (capital E) - expected by record-resource.component\n recordId: recordId, // Also needed in Configuration for tab-container.component to populate ResourceRecordID\n ...this.resolveSourceContext(options)\n },\n ResourceRecordId: recordId,\n IsPinned: options?.pinTab || false,\n // Records style: opening a record must not pin the nav tab (see\n // TabRequest.PreservePinState) — a pinned nav tab forces the main tab\n // bar visible on every nav page.\n PreservePinState: tabsMode\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n let tabId: string;\n if (forceNew) {\n tabId = this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n tabId = this.workspaceManager.OpenTab(request, appColor);\n }\n\n if (tabsMode) {\n this.assertRecordActivation(tabId);\n }\n\n return tabId;\n }\n\n /**\n * Opening a record means the record WINS the activation race — assert it\n * after the synchronous open flow settles. Surfaces that both emit a\n * record-open AND run their own internal navigation in the same click\n * (e.g. a grid row's select handler updating query params from a config\n * snapshot captured before the open) can otherwise stomp the activation\n * with stale state, leaving the tab open but never shown. Skipped when the\n * tab was closed in the meantime.\n */\n private assertRecordActivation(tabId: string): void {\n setTimeout(() => {\n const config = this.workspaceManager.GetConfiguration();\n if (config?.tabs.some(t => t.id === tabId) && config.activeTabId !== tabId) {\n this.workspaceManager.SetActiveTab(tabId);\n }\n }, 0);\n }\n\n /** Find an already-open tab showing this exact record (records-style dedup) */\n private findOpenRecordTab(entityName: string, recordId: string): { id: string } | null {\n const config = this.workspaceManager.GetConfiguration();\n const match = config?.tabs.find(t =>\n t.resourceRecordId === recordId &&\n t.configuration?.['resourceType'] === RECORDS_RESOURCE_TYPE &&\n t.configuration?.['Entity'] === entityName\n );\n return match ? { id: match.id } : null;\n }\n\n /**\n * Overwrite a record tab's origin with a freshly-resolved one (the dedup\n * re-open path). All source keys are explicitly cleared first — a shallow\n * config merge would otherwise let fields from the OLD origin shape leak\n * through (e.g. a parent-record origin's sourceRecordEntity surviving a\n * re-open from a nav page, or pre-schema captures keeping stale labels).\n */\n private refreshSourceContext(tabId: string, options?: NavigationOptions): void {\n this.workspaceManager.UpdateTabConfiguration(tabId, {\n sourceAppId: undefined,\n sourceAppName: undefined,\n sourceNavLabel: undefined,\n sourceNavItemName: undefined,\n sourceTabId: undefined,\n sourceLabel: undefined,\n sourceQueryParams: undefined,\n sourceRecordEntity: undefined,\n sourceRecordId: undefined,\n ...this.resolveSourceContext(options)\n });\n }\n\n /**\n * Resolve the source context to stamp into a record tab's configuration.\n * Callers that are workspace tabs omit options.recordSource and get the\n * active app/tab snapshot; overlay surfaces pass their own context;\n * 'none' means no origin (no crumb).\n */\n private resolveSourceContext(options?: NavigationOptions): Record<string, unknown> {\n if (options?.recordSource === 'none') {\n return {};\n }\n if (options?.recordSource) {\n const src = options.recordSource;\n const context: Record<string, unknown> = {};\n if (src.sourceAppId) context['sourceAppId'] = src.sourceAppId;\n if (src.sourceAppName) context['sourceAppName'] = src.sourceAppName;\n if (src.sourceNavLabel) context['sourceNavLabel'] = src.sourceNavLabel;\n if (src.sourceTabId) context['sourceTabId'] = src.sourceTabId;\n if (src.sourceLabel) context['sourceLabel'] = src.sourceLabel;\n if (src.sourceQueryParams && Object.keys(src.sourceQueryParams).length > 0) {\n context['sourceQueryParams'] = src.sourceQueryParams;\n }\n return context;\n }\n return this.captureSourceContext();\n }\n\n /**\n * Snapshot of where the user was when the record was\n * opened — the source app and (when the active tab belongs to that app and\n * isn't itself a record) the nav page they were on. Rendered by the\n * breadcrumb strip as \"App › Page › Record\".\n */\n private captureSourceContext(): Record<string, unknown> {\n const activeApp = this.appManager.GetActiveApp();\n if (!activeApp) {\n return {};\n }\n const context: Record<string, unknown> = {\n sourceAppId: activeApp.ID,\n sourceAppName: activeApp.Name\n };\n const config = this.workspaceManager.GetConfiguration();\n const activeTab = config?.tabs.find(t => t.id === config.activeTabId);\n if (!activeTab || !UUIDsEqual(activeTab.applicationId, activeApp.ID) || !activeTab.title) {\n return context;\n }\n if (IsRecordsTabConfiguration(activeTab.configuration)) {\n // Opened from INSIDE another record → the crumb points at the PARENT\n // record (Matt's record→record design call). Identity, not just the\n // tab id, so the return survives tab closure (re-open via dedup).\n const parentEntity = activeTab.configuration?.['Entity'];\n const parentRecordId = activeTab.resourceRecordId || activeTab.configuration?.['recordId'];\n if (typeof parentEntity === 'string' && typeof parentRecordId === 'string' && parentRecordId) {\n context['sourceTabId'] = activeTab.id;\n context['sourceLabel'] = activeTab.title;\n context['sourceRecordEntity'] = parentEntity;\n context['sourceRecordId'] = parentRecordId;\n }\n return context;\n }\n context['sourceNavLabel'] = activeTab.title;\n // Canonical nav identity alongside the display title: titles mutate\n // (Data Explorer renames its tab to the drilled entity), so the return\n // path verifies/resolves by navItemName and shows the label.\n const navItemName = activeTab.configuration?.['navItemName'];\n if (typeof navItemName === 'string' && navItemName.length > 0) {\n context['sourceNavItemName'] = navItemName;\n }\n // The exact tab, not just its label — the origin crumb's return path\n // prefers reactivating this tab (state intact) over re-resolving the\n // nav item by label.\n context['sourceTabId'] = activeTab.id;\n // Snapshot the tab's query params too: dashboards keep their DRILL-IN\n // state there (e.g. Data Explorer's entity section), and it can drift\n // or be stomped between open and return. The crumb restores the page\n // AS IT WAS, not just the tab.\n const queryParams = activeTab.configuration?.['queryParams'];\n if (queryParams && typeof queryParams === 'object' && Object.keys(queryParams).length > 0) {\n context['sourceQueryParams'] = { ...(queryParams as Record<string, string>) };\n }\n return context;\n }\n\n /**\n * Switch to an app's LANDING page — its default nav item in its BASE\n * state (drifted section params cleared, reset force-delivered so the\n * dashboard actually returns to its landing even if its state diverged).\n * The origin crumb's APP segment uses this: classic breadcrumb semantics,\n * each level goes to that level's home.\n */\n async SwitchToAppHome(appId: string): Promise<void> {\n const app = this.appManager.GetAllApps().find(a => UUIDsEqual(a.ID, appId));\n if (!app) {\n return;\n }\n const navItems = await app.GetNavItems();\n const home = navItems.find(i => i.isDefault) ?? navItems[0];\n await this.SwitchToApp(appId, home?.Label);\n const tabId = this.workspaceManager.GetActiveTabId();\n if (!tabId) {\n return;\n }\n const tab = this.workspaceManager.GetTab(tabId);\n const current = (tab?.configuration?.['queryParams'] || {}) as Record<string, string>;\n const clear: Record<string, string | null> = {};\n for (const key of Object.keys(current)) {\n clear[key] = null;\n }\n if (Object.keys(clear).length > 0) {\n this.applyQueryParamsToTab(tabId, clear);\n }\n this.NotifyQueryParamsChanged(tabId, {}, true);\n }\n\n /**\n * Take the user back to where they were when a record was opened (the\n * origin crumb's click path). Fidelity ladder:\n * 1. The exact source tab, if it's still open — reactivate it with all its\n * state (query params, scroll, cached component) intact.\n * 2. Otherwise re-resolve by app + nav label via SwitchToApp, which reuses\n * a matching open tab or opens the nav item fresh.\n * No-ops when the context has no sourceAppId (capture was best-effort).\n */\n public async ReturnToRecordSource(origin: RecordSourceContext): Promise<void> {\n // Parent-RECORD origin (opened from inside another record): activate the\n // parent's tab while it still shows that record, else RE-OPEN the parent\n // — OpenEntityRecord's dedup makes the re-open land on (or recreate)\n // exactly that record. No app flip either way: record tabs live in the\n // records region regardless of app.\n if (origin.sourceRecordEntity && origin.sourceRecordId) {\n const config = this.workspaceManager.GetConfiguration();\n const sourceTab = origin.sourceTabId ? config?.tabs.find(t => t.id === origin.sourceTabId) : undefined;\n const stillParent = !!sourceTab &&\n IsRecordsTabConfiguration(sourceTab.configuration) &&\n sourceTab.configuration?.['Entity'] === origin.sourceRecordEntity &&\n sourceTab.resourceRecordId === origin.sourceRecordId;\n if (sourceTab && stillParent) {\n this.workspaceManager.SetActiveTab(sourceTab.id);\n return;\n }\n const parentKey = new CompositeKey();\n parentKey.SimpleLoadFromURLSegment(origin.sourceRecordId);\n this.OpenEntityRecord(origin.sourceRecordEntity, parentKey);\n return;\n }\n if (!origin.sourceAppId) {\n return;\n }\n if (origin.sourceTabId) {\n const config = this.workspaceManager.GetConfiguration();\n const sourceTab = config?.tabs.find(t => t.id === origin.sourceTabId);\n // Tab ids are NOT stable identities for nav pages: the temp-tab\n // replacement model (WorkspaceStateManager.OpenTab) reuses the same\n // tab id when the user navigates elsewhere — the captured id can now\n // hold a DIFFERENT page in a DIFFERENT app. Trust it only while the\n // tab still shows the captured page; otherwise fall through to\n // re-resolving by app + nav item below. Prefer navItemName for the\n // page check — TITLES MUTATE (Data Explorer renames its tab to the\n // drilled entity), and a mutated title must not disqualify the tab.\n const tabNavItemName = sourceTab?.configuration?.['navItemName'];\n const samePage = origin.sourceNavItemName && typeof tabNavItemName === 'string'\n ? tabNavItemName === origin.sourceNavItemName\n : (!origin.sourceNavLabel || sourceTab?.title === origin.sourceNavLabel);\n const stillSourcePage = !!sourceTab &&\n (!origin.sourceAppId || UUIDsEqual(sourceTab.applicationId, origin.sourceAppId)) &&\n samePage;\n if (sourceTab && stillSourcePage) {\n // Restore the tab's query params to the capture-time snapshot BEFORE\n // activating, so a cached resource component reattaches against the\n // right config (see SwitchToApp's queryParams doc). REPLACE\n // semantics: null out params the tab has gained since capture, then\n // lay the snapshot over — \"back\" means the page as it was, and\n // drill-in state (e.g. Data Explorer's entity section) lives here.\n const currentParams = (sourceTab.configuration?.['queryParams'] || {}) as Record<string, string>;\n const restore: Record<string, string | null> = {};\n for (const key of Object.keys(currentParams)) {\n restore[key] = null;\n }\n Object.assign(restore, origin.sourceQueryParams ?? {});\n if (Object.keys(restore).length > 0) {\n this.applyQueryParamsToTab(sourceTab.id, restore);\n }\n // FORCE delivery: the component's state may have drifted while its\n // last-delivered params already equal the snapshot — the reactive\n // path would drop the restore as a duplicate (crumb lands on the\n // dashboard's home instead of the captured section).\n if (origin.sourceQueryParams && Object.keys(origin.sourceQueryParams).length > 0) {\n this.NotifyQueryParamsChanged(sourceTab.id, origin.sourceQueryParams, true);\n }\n // Set the app context first so the shell's nav renders the right\n // app the moment the tab activates (activation alone would also\n // flip it, but explicit sequencing avoids a visible two-step).\n await this.appManager.SetActiveApp(sourceTab.applicationId);\n this.workspaceManager.SetActiveTab(sourceTab.id);\n return;\n }\n }\n // Re-resolve by the CANONICAL nav-item name when we have it — the label\n // is a display title that may have mutated into something SwitchToApp's\n // nav-item lookup can't match (e.g. a drilled entity name).\n await this.SwitchToApp(origin.sourceAppId, origin.sourceNavItemName ?? origin.sourceNavLabel, origin.sourceQueryParams);\n // Same drift-proofing as the exact-tab path: force the delivery so the\n // restore can't be deduped away.\n if (origin.sourceQueryParams && Object.keys(origin.sourceQueryParams).length > 0) {\n const targetTabId = this.workspaceManager.GetActiveTabId();\n if (targetTabId) {\n this.NotifyQueryParamsChanged(targetTabId, origin.sourceQueryParams, true);\n }\n }\n }\n\n /**\n * Open a view\n * Uses Home app if available, otherwise falls back to active app or system app\n */\n public OpenView(\n viewId: string,\n viewName: string,\n options?: NavigationOptions\n ): string {\n const appId = this.getDefaultApplicationId();\n const appColor = this.getDefaultAppColor();\n let forceNew = this.shouldForceNewTab(options);\n\n const request: TabRequest = {\n ApplicationId: appId,\n Title: viewName,\n Configuration: {\n resourceType: 'MJ: User Views',\n viewId,\n recordId: viewId // Also needed in Configuration for tab-container.component to populate ResourceRecordID\n },\n ResourceRecordId: viewId,\n IsPinned: options?.pinTab || false\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n if (forceNew) {\n return this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n return this.workspaceManager.OpenTab(request, appColor);\n }\n }\n\n /**\n * Open a dashboard\n * Uses Home app if available, otherwise falls back to active app or system app\n */\n public OpenDashboard(\n dashboardId: string,\n dashboardName: string,\n options?: NavigationOptions\n ): string {\n const appId = this.getDefaultApplicationId();\n const appColor = this.getDefaultAppColor();\n let forceNew = this.shouldForceNewTab(options);\n\n const request: TabRequest = {\n ApplicationId: appId,\n Title: dashboardName,\n Configuration: {\n resourceType: 'Dashboards',\n dashboardId,\n recordId: dashboardId // Also needed in Configuration for tab-container.component to populate ResourceRecordID\n },\n ResourceRecordId: dashboardId,\n IsPinned: options?.pinTab || false\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n if (forceNew) {\n return this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n return this.workspaceManager.OpenTab(request, appColor);\n }\n }\n\n /**\n * Open an artifact\n * Artifacts are versioned content containers (reports, dashboards, UI components, etc.)\n * Uses Home app if available, otherwise falls back to active app or system app\n */\n public OpenArtifact(\n artifactId: string,\n artifactName?: string,\n options?: NavigationOptions\n ): string {\n const appId = this.getDefaultApplicationId();\n const appColor = this.getDefaultAppColor();\n let forceNew = this.shouldForceNewTab(options);\n\n const request: TabRequest = {\n ApplicationId: appId,\n Title: artifactName || `Artifact - ${artifactId}`,\n Configuration: {\n resourceType: 'Artifacts',\n artifactId,\n recordId: artifactId // Also needed in Configuration for tab-container.component to populate ResourceRecordID\n },\n ResourceRecordId: artifactId,\n IsPinned: options?.pinTab || false\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n if (forceNew) {\n return this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n return this.workspaceManager.OpenTab(request, appColor);\n }\n }\n\n /**\n * Open a dynamic view\n * Dynamic views are entity-based views with custom filters, not saved views\n * Uses Home app if available, otherwise falls back to active app or system app\n */\n public OpenDynamicView(\n entityName: string,\n extraFilter?: string,\n options?: NavigationOptions\n ): string {\n const appId = this.getDefaultApplicationId();\n const appColor = this.getDefaultAppColor();\n let forceNew = this.shouldForceNewTab(options);\n\n const filterSuffix = extraFilter ? ' (Filtered)' : '';\n const request: TabRequest = {\n ApplicationId: appId,\n Title: `${entityName}${filterSuffix}`,\n Configuration: {\n resourceType: 'MJ: User Views',\n Entity: entityName,\n ExtraFilter: extraFilter,\n isDynamic: true,\n recordId: 'dynamic' // Special marker for dynamic views\n },\n ResourceRecordId: 'dynamic',\n IsPinned: options?.pinTab || false\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n if (forceNew) {\n return this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n return this.workspaceManager.OpenTab(request, appColor);\n }\n }\n\n /**\n * Open a query\n * Uses Home app if available, otherwise falls back to active app or system app\n */\n public OpenQuery(\n queryId: string,\n queryName: string,\n options?: NavigationOptions\n ): string {\n const appId = this.getDefaultApplicationId();\n const appColor = this.getDefaultAppColor();\n let forceNew = this.shouldForceNewTab(options);\n\n const request: TabRequest = {\n ApplicationId: appId,\n Title: queryName,\n Configuration: {\n resourceType: 'Queries',\n queryId,\n recordId: queryId // Also needed in Configuration for tab-container.component to populate ResourceRecordID\n },\n ResourceRecordId: queryId,\n IsPinned: options?.pinTab || false\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n if (forceNew) {\n return this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n return this.workspaceManager.OpenTab(request, appColor);\n }\n }\n\n /**\n * Open a new entity record creation form\n * Uses Home app if available, otherwise falls back to active app or system app\n * @param entityName The name of the entity to create a new record for\n * @param options Navigation options including optional newRecordValues for pre-populating fields\n */\n public OpenNewEntityRecord(\n entityName: string,\n options?: NavigationOptions\n ): string {\n // Records style: new-record tabs are RECORD tabs and get the same\n // treatment as OpenEntityRecord — assigned to the ACTIVE app, always a\n // new tab, nav pins preserved, origin captured. Without the forceNew,\n // the non-forced OpenTab consumed the user's nav page as the\n // replaceable temp tab and CONVERTED it into a records-region tab —\n // silently destroying the page they were on.\n const tabsMode = IsRecordTabsStyle();\n const activeApp = this.appManager.GetActiveApp();\n const appId = tabsMode && activeApp ? activeApp.ID : this.getDefaultApplicationId();\n const appColor = tabsMode && activeApp ? activeApp.GetColor() : this.getDefaultAppColor();\n\n let forceNew = tabsMode || this.shouldForceNewTab(options);\n\n const request: TabRequest = {\n ApplicationId: appId,\n Title: `New ${entityName}`,\n Configuration: {\n resourceType: RECORDS_RESOURCE_TYPE,\n Entity: entityName, // Must use 'Entity' (capital E) - expected by record-resource.component\n recordId: '', // Empty recordId indicates new record\n isNew: true, // Flag to indicate this is a new record\n NewRecordValues: options?.newRecordValues, // Pass through initial values if provided\n ...this.resolveSourceContext(options)\n },\n ResourceRecordId: '', // Empty for new records\n IsPinned: options?.pinTab || false,\n PreservePinState: tabsMode\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n let tabId: string;\n if (forceNew) {\n tabId = this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n tabId = this.workspaceManager.OpenTab(request, appColor);\n }\n\n if (tabsMode) {\n this.assertRecordActivation(tabId);\n }\n\n return tabId;\n }\n\n /**\n * Open a universal search results tab for the given query.\n * This is the primary way to open search results from anywhere in the application.\n *\n * @param query The search query text\n * @param searchOptions Optional search-specific options (e.g., minRelevance, scopeIDs)\n * @param options Navigation options\n */\n public OpenSearch(\n query: string,\n searchOptions?: { minRelevance?: number; scopeIDs?: string[] },\n options?: NavigationOptions\n ): string {\n const appId = this.getDefaultApplicationId();\n const appColor = this.getDefaultAppColor();\n let forceNew = this.shouldForceNewTab(options);\n\n const config: Record<string, unknown> = {\n resourceType: 'Search Results',\n Query: query,\n SearchInput: query,\n recordId: `search-${query}`\n };\n if (searchOptions?.minRelevance != null) {\n config['MinRelevance'] = searchOptions.minRelevance;\n }\n if (searchOptions?.scopeIDs && searchOptions.scopeIDs.length > 0) {\n config['ScopeIDs'] = searchOptions.scopeIDs;\n }\n\n const request: TabRequest = {\n ApplicationId: appId,\n Title: `Search: ${query}`,\n Configuration: config,\n ResourceRecordId: `search-${query}`,\n IsPinned: false\n };\n\n // Handle transition from single-resource mode\n forceNew = this.handleSingleResourceModeTransition(forceNew, request);\n\n if (forceNew) {\n return this.workspaceManager.OpenTabForced(request, appColor);\n } else {\n return this.workspaceManager.OpenTab(request, appColor);\n }\n }\n\n /**\n * Navigate to a nav item by name within the current or specified application.\n * Allows passing additional configuration parameters to merge with the nav item's config.\n * This is useful for cross-resource navigation where a component needs to navigate\n * to another nav item with specific parameters (e.g., navigate to Conversations with a specific conversationId).\n *\n * @param navItemName The label/name of the nav item to navigate to\n * @param configuration Additional configuration to merge (e.g., conversationId, artifactId)\n * @param appId Optional app ID (defaults to current active app)\n * @param options Navigation options\n * @returns The tab ID if successful, null if nav item not found\n */\n public async OpenNavItemByName(\n navItemName: string,\n configuration?: Record<string, unknown>,\n appId?: string,\n options?: NavigationOptions\n ): Promise<string | null> {\n // Get app (use provided or current active)\n const targetAppId = appId || this.appManager.GetActiveApp()?.ID;\n if (!targetAppId) {\n return null;\n }\n\n const app = this.appManager.GetAppById(targetAppId);\n if (!app) {\n return null;\n }\n\n // Find the nav item by name\n const navItems = await app.GetNavItems();\n const navItem = navItems.find(item => item.Label === navItemName);\n if (!navItem) {\n return null;\n }\n\n // Create a merged nav item with additional configuration\n const mergedNavItem: NavItem = {\n ...navItem,\n Configuration: {\n ...(navItem.Configuration || {}),\n ...(configuration || {})\n }\n };\n\n // Use existing OpenNavItem\n return this.OpenNavItem(targetAppId, mergedNavItem, app.GetColor(), options);\n }\n\n /**\n * Switch to an application by ID.\n * This sets the app as active and either opens a specific nav item or creates a default tab.\n * If the requested nav item already has an open tab, switches to that tab instead of creating a new one.\n * @param appId The application ID to switch to\n * @param navItemName Optional name of a nav item to open within the app. If provided, opens that nav item.\n * @param queryParams Optional query params to apply to the target tab. Applied SYNCHRONOUSLY once the\n * target tab is active — critical when navigating (e.g. from a Home pin) to an\n * app whose resource component is cached: the params must be in the tab config\n * BEFORE the tab-container reattaches the cached component, otherwise the cache\n * restores its own (stale) saved params and the navigation intent is lost.\n */\n async SwitchToApp(appId: string, navItemName?: string, queryParams?: Record<string, string | null>): Promise<void> {\n await this.appManager.SetActiveApp(appId);\n\n const app = this.appManager.GetAllApps().find(a => UUIDsEqual(a.ID, appId));\n if (!app) {\n return;\n }\n\n // Records style: record tabs are ASSIGNED to apps but live in their own\n // region — switching to an app must surface its NAV pages, so records\n // don't count here. Without this filter, the active record tab (which\n // belongs to the target app) satisfied the \"already on this app's tab\"\n // check and the whole switch silently no-oped — the dead origin-crumb\n // click when the crumb only knew the app. Records DOCKED to the\n // workspace are excluded too (identity check, not region membership):\n // switch-to-app must land on a page, never a record. Classic style\n // keeps records as ordinary tabs.\n const appTabs = IsRecordTabsStyle()\n ? this.workspaceManager.GetAppTabs(appId).filter(t => !IsRecordsTabConfiguration(t.configuration))\n : this.workspaceManager.GetAppTabs(appId);\n\n // If a specific nav item is requested\n if (navItemName) {\n const navItems = await app.GetNavItems();\n const navItem = navItems.find(item => item.Label === navItemName);\n if (navItem) {\n // Check if there's already a tab for this nav item. Identity check\n // uses configuration.navItemName when the tab carries it — TITLES\n // LIE: same-driver nav switches reuse the live tab and can leave a\n // stale title behind (e.g. Data Explorer's tab titled \"Data\" while\n // its content and navItemName say \"Dashboards\"). Matching that\n // chimera by title activated the WRONG page instead of reopening\n // the requested nav item.\n const existingTab = appTabs.find(tab => {\n const tabNav = tab.configuration?.['navItemName'];\n if (typeof tabNav === 'string' && tabNav.length > 0) {\n return tabNav === navItem.Label;\n }\n return tab.title === navItem.Label ||\n (tab.configuration?.['route'] === navItem.Route && !!navItem.Route);\n });\n\n if (existingTab) {\n // Switch to existing tab\n this.workspaceManager.SetActiveTab(existingTab.id);\n } else {\n // Open new tab for this nav item\n this.OpenNavItem(appId, navItem, app.GetColor());\n }\n // Apply the requested query params to whichever tab is now active — synchronously,\n // so they're present before the (possibly cached) resource component reattaches.\n if (queryParams && Object.keys(queryParams).length > 0) {\n const targetTabId = this.workspaceManager.GetActiveTabId();\n if (targetTabId) {\n this.applyQueryParamsToTab(targetTabId, queryParams);\n }\n }\n return;\n }\n // Nav item not found, fall through to default behavior\n }\n\n // No specific nav item requested - check if app has any tabs\n if (appTabs.length === 0) {\n // Create default tab\n const tabRequest = await app.CreateDefaultTab();\n if (tabRequest) {\n this.workspaceManager.OpenTab(tabRequest, app.GetColor());\n }\n } else {\n // App has tabs - switch to the first one (or active one if exists)\n const config = this.workspaceManager.GetConfiguration();\n const activeAppTab = appTabs.find(t => t.id === config?.activeTabId);\n if (!activeAppTab) {\n // No active tab for this app, switch to first tab\n this.workspaceManager.SetActiveTab(appTabs[0].id);\n }\n }\n\n // Apply requested query params on the DEFAULT path too (previously only the\n // navItemName branch did) — e.g. the omnibar's '@agent' → Chat pre-addressing.\n // Synchronous, so params are present before a cached resource component reattaches.\n if (queryParams && Object.keys(queryParams).length > 0) {\n const targetTabId = this.workspaceManager.GetActiveTabId();\n if (targetTabId) {\n this.applyQueryParamsToTab(targetTabId, queryParams);\n }\n }\n }\n\n /**\n * Update the query params for the currently active tab.\n * This updates the tab's configuration and triggers a URL sync via the shell's\n * workspace configuration subscription.\n *\n * Use this instead of directly calling router.navigate() to ensure proper\n * URL management that respects app-scoped routes.\n *\n * @param queryParams Object containing query param key-value pairs.\n * Use null values to remove a query param.\n * @example\n * // Add or update query params\n * navigationService.UpdateActiveTabQueryParams({ category: 'abc123', dashboard: 'xyz789' });\n *\n * // Remove a query param\n * navigationService.UpdateActiveTabQueryParams({ category: null });\n */\n UpdateActiveTabQueryParams(queryParams: Record<string, string | null>): void {\n const activeTabId = this.workspaceManager.GetActiveTabId();\n if (!activeTabId) {\n console.warn('NavigationService.UpdateActiveTabQueryParams: No active tab');\n return;\n }\n\n this.applyQueryParamsToTab(activeTabId, queryParams);\n }\n\n /**\n * Update query params for a specific tab, optionally only if the tab still hosts\n * the expected resource identity. This matters in single-resource mode where a\n * tab ID can be reused for a different resource while the previous component is\n * detached but still alive in the cache.\n */\n UpdateTabQueryParams(\n tabId: string,\n queryParams: Record<string, string | null>,\n guard?: TabQueryParamUpdateGuard\n ): boolean {\n const tab = this.workspaceManager.GetTab(tabId);\n if (!tab) {\n console.debug('NavigationService.UpdateTabQueryParams: Tab not found; ignoring stale query-param update:', tabId);\n return false;\n }\n\n if (guard && !this.tabMatchesQueryParamGuard(tab, guard)) {\n console.debug('NavigationService.UpdateTabQueryParams: Tab identity changed; ignoring stale query-param update:', {\n tabId,\n guard,\n current: {\n resourceType: tab.configuration?.['resourceType'],\n driverClass: tab.configuration?.['resourceTypeDriverClass'] || tab.configuration?.['driverClass'],\n recordId: tab.resourceRecordId || tab.configuration?.['recordId'],\n navItemName: tab.configuration?.['navItemName'],\n entity: tab.configuration?.['Entity'] || tab.configuration?.['entity']\n }\n });\n return false;\n }\n\n this.applyQueryParamsToTab(tabId, queryParams);\n return true;\n }\n\n /**\n * Notify subscribers that query params changed on a specific tab.\n * Called by the shell when back/forward navigation changes query params on the active tab.\n * The notification includes the tab ID so only the component in that tab reacts.\n */\n NotifyQueryParamsChanged(tabId: string, params: Record<string, string>, force = false): void {\n this.queryParamChanged$.next({ TabId: tabId, Params: params, Force: force });\n }\n\n /**\n * Reactively observe the query params for a specific tab.\n *\n * Backed by the workspace BehaviorSubject, so a subscriber receives the current\n * params *immediately* on subscribe AND every subsequent change — including the\n * deep-link params that the ResourceResolver merges into the tab configuration on\n * a cold/direct URL load.\n *\n * This is the race-free counterpart to {@link NotifyQueryParamsChanged} (a plain\n * Subject that drops events fired before a component has subscribed). A resource\n * component that mounts from workspace restoration can subscribe here and still\n * pick up its initial deep-link state regardless of whether the params landed in\n * the tab config before or after it mounted.\n */\n public ObserveTabQueryParams(tabId: string): Observable<Record<string, string>> {\n return this.workspaceManager.Configuration.pipe(\n map(config => {\n const tab = config?.tabs?.find(t => t.id === tabId);\n return (tab?.configuration?.['queryParams'] || {}) as Record<string, string>;\n }),\n distinctUntilChanged((a, b) => this.shallowParamsEqual(a, b))\n );\n }\n\n private shallowParamsEqual(a: Record<string, string>, b: Record<string, string>): boolean {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) {\n return false;\n }\n return keysA.every(key => a[key] === b[key]);\n }\n\n private tabMatchesQueryParamGuard(tab: { resourceRecordId?: string; configuration?: Record<string, unknown> }, guard: TabQueryParamUpdateGuard): boolean {\n const config = tab.configuration || {};\n const matches = (expected: string | null | undefined, actual: unknown, normalize = false): boolean => {\n if (expected === undefined || expected === null) {\n return true;\n }\n const expectedText = String(expected);\n const actualText = actual == null ? '' : String(actual);\n return normalize\n ? expectedText.trim().toLowerCase() === actualText.trim().toLowerCase()\n : expectedText === actualText;\n };\n\n const currentDriverClass = (config['resourceTypeDriverClass'] || config['driverClass']) as string | undefined;\n const currentRecordId = tab.resourceRecordId || (config['recordId'] as string | undefined) || '';\n const currentEntity = (config['Entity'] || config['entity']) as string | undefined;\n\n // Resource type and entity names can vary by casing/metadata spelling; class names,\n // record IDs, and nav labels are canonical tab identity fields and stay exact-match.\n return matches(guard.resourceType, config['resourceType'], true) &&\n matches(guard.driverClass, currentDriverClass) &&\n matches(guard.recordId, currentRecordId) &&\n matches(guard.navItemName, config['navItemName']) &&\n matches(guard.entity, currentEntity, true);\n }\n\n /**\n * Apply query params to a specific tab by ID.\n * Merges with any existing query params on the tab. Use null values to remove params.\n */\n private applyQueryParamsToTab(tabId: string, queryParams: Record<string, string | null>): void {\n const tab = this.workspaceManager.GetTab(tabId);\n if (!tab) {\n console.warn('NavigationService.applyQueryParamsToTab: Tab not found:', tabId);\n return;\n }\n\n // Get existing queryParams from tab configuration\n const existingQueryParams = (tab.configuration?.['queryParams'] || {}) as Record<string, string | null>;\n\n // Merge with new query params\n const mergedQueryParams: Record<string, string> = {};\n\n // Start with existing params (excluding nulls)\n for (const [key, value] of Object.entries(existingQueryParams)) {\n if (value !== null) {\n mergedQueryParams[key] = value;\n }\n }\n\n // Apply new params (null means remove)\n for (const [key, value] of Object.entries(queryParams)) {\n if (value === null) {\n delete mergedQueryParams[key];\n } else {\n mergedQueryParams[key] = value;\n }\n }\n\n // Update the tab configuration\n this.workspaceManager.UpdateTabConfiguration(tabId, {\n queryParams: Object.keys(mergedQueryParams).length > 0 ? mergedQueryParams : undefined\n });\n }\n}\n"]}
@@ -48,7 +48,6 @@ export declare class SharedService {
48
48
  get ViewResourceType(): MJResourceTypeEntity;
49
49
  get RecordResourceType(): MJResourceTypeEntity;
50
50
  get DashboardResourceType(): MJResourceTypeEntity;
51
- get ReportResourceType(): MJResourceTypeEntity;
52
51
  get SearchResultsResourceType(): MJResourceTypeEntity;
53
52
  get ListResourceType(): MJResourceTypeEntity;
54
53
  ResourceTypeByID(id: string): MJResourceTypeEntity | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"shared.service.d.ts","sourceRoot":"","sources":["../../src/lib/shared.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shared.service.d.ts","sourceRoot":"","sources":["../../src/lib/shared.service.ts"],"names":[],"mappings":"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"}
@@ -126,9 +126,6 @@ export class SharedService {
126
126
  get DashboardResourceType() {
127
127
  return SharedService._resourceTypes.find(rt => rt.Name.trim().toLowerCase() === 'dashboards');
128
128
  }
129
- get ReportResourceType() {
130
- return SharedService._resourceTypes.find(rt => rt.Name.trim().toLowerCase() === 'reports');
131
- }
132
129
  get SearchResultsResourceType() {
133
130
  return SharedService._resourceTypes.find(rt => rt.Name.trim().toLowerCase() === 'search results');
134
131
  }
@@ -267,7 +264,6 @@ export class SharedService {
267
264
  { routeSegment: 'record', name: 'records' },
268
265
  { routeSegment: 'view', name: 'user views' },
269
266
  { routeSegment: 'search', name: 'search results' },
270
- { routeSegment: 'report', name: 'reports' },
271
267
  { routeSegment: 'query', name: 'queries' },
272
268
  { routeSegment: 'dashboard', name: 'dashboards' },
273
269
  { routeSegment: 'list', name: 'lists' },
@@ -1 +1 @@
1
- {"version":3,"file":"shared.service.js","sourceRoot":"","sources":["../../src/lib/shared.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { ElementRef, Injectable, Injector } from '@angular/core';\nimport { CompositeKey, IMetadataProvider, LocalCacheManager, LogError, Metadata, StartupManager } from '@memberjunction/core';\nimport { ArtifactMetadataEngine, DashboardEngine, ResourcePermissionEngine, MJResourceTypeEntity, MJUserNotificationEntity, ViewColumnInfo } from '@memberjunction/core-entities';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport { EntityCommunicationsEngineBase } from \"@memberjunction/entity-communications-base\";\nimport { MJEventType, MJGlobal, ConvertMarkdownStringToHtmlList, InvokeManualResize, UUIDsEqual, GetGlobalObjectStore } from '@memberjunction/global';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\nimport { Subject, Observable, BehaviorSubject, firstValueFrom } from 'rxjs';\nimport { first, tap } from 'rxjs/operators';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { IsDescendantElement } from '@memberjunction/ng-shared-generic';\nimport { RecordNavigationAdapter } from '@memberjunction/ng-base-types';\nimport { NavigationService } from './navigation.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class SharedService {\n private static readonly _globalStoreKey = '___SINGLETON__SharedService';\n private static _loaded: boolean = false;\n private static _resourceTypes: MJResourceTypeEntity[] = [];\n private static isLoading$ = new BehaviorSubject<boolean>(false);\n private tabChange = new Subject();\n tabChange$ = this.tabChange.asObservable();\n private _navigationService: NavigationService | null = null;\n\n constructor(\n private mjNotificationsService: MJNotificationService,\n private injector: Injector\n ) {\n const g = GetGlobalObjectStore()!;\n if (g[SharedService._globalStoreKey]) {\n return g[SharedService._globalStoreKey] as SharedService;\n }\n g[SharedService._globalStoreKey] = this;\n\n // Supply record navigation to Generic widgets that need it but must not import Explorer.\n // The widget calls RecordNavigationAdapter.OpenEntityRecord(...); this is what makes that\n // resolve to an Explorer tab. Registered here because SharedService is constructed once per\n // app and is already the Explorer-side owner of OpenEntityRecord.\n // See guides/UI_LAYERING_GUIDE.md §3 and the adapter's own docs.\n RecordNavigationAdapter.Register({\n OpenEntityRecord: (entityName, recordKey) => this.OpenEntityRecord(entityName, recordKey),\n });\n\n MJGlobal.Instance.GetEventListener(true).subscribe(async (event) => {\n switch (event.event) {\n case MJEventType.LoggedIn:\n if (SharedService._loaded === false) {\n // Pre-warm non-critical engines IMMEDIATELY on LoggedIn, before\n // StartupManager.Startup() completes. These engines only need\n // Metadata.Provider (set during setupGraphQLClient's provider.Config()).\n // Firing them here allows their RunViews calls to be coalesced with\n // the startup engines' calls into fewer mega-batched GraphQL requests.\n SharedService.preWarmEngines();\n\n // Handle app startup — joins the same Startup() promise that\n // setupGraphQLClient kicked off.\n await StartupManager.Instance.Startup();\n\n await SharedService.RefreshData(false);\n }\n break;\n }\n }); \n }\n\n public static get Instance(): SharedService {\n return GetGlobalObjectStore()![SharedService._globalStoreKey] as SharedService;\n }\n\n /**\n * Optional explicit metadata provider. Set via `setProvider()` from a caller\n * with provider context (e.g. the shell). Falls back to `Metadata.Provider`\n * when not set.\n */\n private _provider: IMetadataProvider | null = null;\n\n public set Provider(value: IMetadataProvider | null) {\n this._provider = value;\n }\n\n public get Provider(): IMetadataProvider {\n return this._provider ?? Metadata.Provider;\n }\n\n /**\n * Pre-warms commonly used engines in the background after login.\n * This reduces perceived latency when users navigate to features like\n * Conversations, Dashboards, or Artifacts. Fire-and-forget pattern -\n * errors are logged but don't block the UI.\n */\n private static preWarmEngines(): void {\n // AIEngineBase is the slowest - loads agents, models, prompts, etc.\n // Critical for Conversations feature\n AIEngineBase.Instance.Config(false).catch(err =>\n LogError(`Failed to pre-warm AIEngineBase: ${err}`)\n );\n\n // ArtifactMetadataEngine.Config() loads only the artifact-type registry —\n // a small, fixed set. Artifacts and versions (whose Content can be huge) are\n // fetched on demand per-artifact, so this pre-warm stays cheap and bounded.\n // Used by Conversations and the Artifact viewer.\n ArtifactMetadataEngine.Instance.Config(false).catch(err =>\n LogError(`Failed to pre-warm ArtifactMetadataEngine: ${err}`)\n );\n\n // DashboardEngine loads dashboard metadata\n // Used when viewing dashboards\n DashboardEngine.Instance.Config(false).catch(err =>\n LogError(`Failed to pre-warm DashboardEngine: ${err}`)\n );\n\n EntityCommunicationsEngineBase.Instance.Config(false).catch(err =>\n LogError(`Failed to pre-warm DashboardEngine: ${err}`)\n );\n }\n\n /**\n * Get the NavigationService singleton instance\n * Lazy-loaded to avoid circular dependency issues\n */\n private get navigationService(): NavigationService {\n if (!this._navigationService) {\n this._navigationService = this.injector.get(NavigationService);\n }\n return this._navigationService;\n }\n\n /**\n * Get the neutral color used for system-wide resources\n */\n public get ExplorerAppColor(): string {\n return this.navigationService.ExplorerAppColor;\n }\n\n /**\n * Returns the current session ID, which is automatically created when the service is instantiated.\n */\n public get SessionId(): string {\n return (<GraphQLDataProvider>this.Provider).sessionId;\n }\n\n public get ResourceTypes(): MJResourceTypeEntity[] {\n return SharedService._resourceTypes;\n }\n public get ViewResourceType(): MJResourceTypeEntity {\n return SharedService._resourceTypes.find(rt => rt.Name.trim().toLowerCase() === 'user views')!;\n }\n public get RecordResourceType(): MJResourceTypeEntity {\n return SharedService._resourceTypes.find(rt => rt.Name.trim().toLowerCase() === 'records')!;\n }\n public get DashboardResourceType(): MJResourceTypeEntity {\n return SharedService._resourceTypes.find(rt => rt.Name.trim().toLowerCase() === 'dashboards')!;\n }\n public get ReportResourceType(): MJResourceTypeEntity {\n return SharedService._resourceTypes.find(rt => rt.Name.trim().toLowerCase() === 'reports')!;\n }\n public get SearchResultsResourceType(): MJResourceTypeEntity {\n return SharedService._resourceTypes.find(rt => rt.Name.trim().toLowerCase() === 'search results')!;\n }\n public get ListResourceType(): MJResourceTypeEntity {\n return SharedService._resourceTypes.find(rt => rt.Name.trim().toLowerCase() === 'lists')!;\n }\n public ResourceTypeByID(id: string): MJResourceTypeEntity | undefined {\n return SharedService._resourceTypes.find(rt => UUIDsEqual(rt.ID, id));\n }\n public ResourceTypeByName(name: string): MJResourceTypeEntity | undefined {\n return SharedService._resourceTypes.find(rt => rt.Name.trim().toLowerCase() === name.trim().toLowerCase());\n }\n\n /**\n * Refreshes the data for the service. If OnlyIfNeeded is true, then the data is only refreshed if it hasn't been loaded yet.\n */\n public static async RefreshData(OnlyIfNeeded: boolean = false) {\n if (OnlyIfNeeded && SharedService._loaded) {\n return;\n }\n\n const canProceed$ = SharedService.isLoading$.pipe(\n first(isLoading => !isLoading),\n tap(() => SharedService.isLoading$.next(true))\n );\n\n await firstValueFrom(canProceed$);\n\n try {\n // After waiting for the current loading operation to complete, check again\n // if _loaded is true and OnlyIfNeeded is true, return early\n if (OnlyIfNeeded && SharedService._loaded) {\n return;\n }\n\n await SharedService.handleDataLoading();\n\n // Mark as loaded\n SharedService._loaded = true;\n } finally {\n // Ensure we always reset the loading flag\n SharedService.isLoading$.next(false);\n }\n }\n\n private static async handleDataLoading() {\n // make sure startup is done\n await StartupManager.Instance.Startup();\n\n this._resourceTypes = ResourcePermissionEngine.Instance.ResourceTypes;\n\n // Note: RefreshUserNotifications() removed here because MJNotificationService\n // already handles it via its own MJEventType.LoggedIn subscription. Calling it\n // from both places caused a duplicate User Notifications GraphQL request on login.\n } \n\n FormatColumnValue(col: ViewColumnInfo, value: any, maxLength: number = 0, trailingChars: string = \"...\") {\n if (value === null || value === undefined)\n return value;\n\n try {\n const retVal = col.EntityField.FormatValue(value, 0);\n if (maxLength > 0 && retVal && retVal.length > maxLength)\n return retVal.substring(0, maxLength) + trailingChars;\n else\n return retVal;\n }\n catch (e) {\n LogError(e);\n return value;\n }\n }\n\n public ConvertMarkdownStringToHtmlList(listType: HtmlListType, text: string): string {\n return ConvertMarkdownStringToHtmlList(listType, text) ?? text;\n }\n\n \n public InvokeManualResize(delay: number = 50) {\n return InvokeManualResize(delay, this);\n }\n\n public PushStatusUpdates(): Observable<string> {\n const gp: GraphQLDataProvider = <GraphQLDataProvider>this.Provider;\n return gp.PushStatusUpdates();\n }\n\n private _currentUserImage: string | Blob = '/assets/user.png';\n public get CurrentUserImage(): string | Blob {\n return this._currentUserImage;\n }\n public set CurrentUserImage(value: string | Blob) {\n this._currentUserImage = value;\n }\n\n /**\n * @deprecated Use MJNotificationService.UserNotifications instead\n */\n public static get UserNotifications(): MJUserNotificationEntity[] {\n return MJNotificationService.UserNotifications;\n }\n /**\n * @deprecated Use MJNotificationService.UnreadUserNotifications instead\n */\n public static get UnreadUserNotifications(): MJUserNotificationEntity[] {\n return MJNotificationService.UnreadUserNotifications;\n }\n /**\n * @deprecated Use MJNotificationService.UnreadUserNotificationCount instead\n */\n public static get UnreadUserNotificationCount(): number {\n return MJNotificationService.UnreadUserNotificationCount;\n }\n\n /**\n * Utility method that returns true if child is a descendant of parent, false otherwise. \n */\n /**\n * @deprecated Use `IsDescendantElement` from `@memberjunction/ng-shared-generic`. This is a pure\n * DOM predicate with no Explorer coupling; keeping it here forced widgets that wanted it to\n * depend on Explorer. Delegates so existing callers are unaffected.\n */\n public static IsDescendant(parent: ElementRef, child: ElementRef) {\n return IsDescendantElement(parent, child);\n }\n\n\n /**\n * Creates a notification in the database and refreshes the UI. Returns the notification object.\n * @param title \n * @param message \n * @param resourceTypeId \n * @param resourceRecordId \n * @param resourceConfiguration Any object, it is converted to a string by JSON.stringify and stored in the database\n * @returns \n * @deprecated Use MJNotificationService.CreateNotification instead\n */\n public async CreateNotification(title: string, message: string, resourceTypeId: string | null, resourceRecordId: string | null, resourceConfiguration: any | null, displayToUser : boolean = true): Promise<MJUserNotificationEntity> {\n return this.mjNotificationsService.CreateNotification(title, message, resourceTypeId, resourceRecordId, resourceConfiguration, displayToUser);\n }\n\n /**\n * @deprecated Use MJNotificationService.RefreshUserNotifications instead\n */\n public static async RefreshUserNotifications() {\n MJNotificationService.RefreshUserNotifications();\n }\n\n /**\n * Creates a message that is not saved to the User Notifications table, but is displayed to the user.\n * @param message - text to display\n * @param style - display styling\n * @param hideAfter - option to auto hide after the specified delay in milliseconds\n * @deprecated Use MJNotificationService.CreateSimpleNotification instead\n */\n public CreateSimpleNotification(message: string, style: \"none\" | \"success\" | \"error\" | \"warning\" | \"info\" = \"success\", hideAfter?: number) {\n return this.mjNotificationsService.CreateSimpleNotification(message, style, hideAfter);\n }\n\n\n\n private _resourceTypeMap = [\n { routeSegment: 'record', name: 'records' },\n { routeSegment: 'view', name: 'user views' },\n { routeSegment: 'search', name: 'search results' },\n { routeSegment: 'report', name: 'reports' },\n { routeSegment: 'query', name: 'queries' },\n { routeSegment: 'dashboard', name: 'dashboards' },\n { routeSegment: 'list', name: 'lists' },\n \n ]\n /**\n * Maps a Resource Type record Name column to the corresponding route segment\n * @param resourceTypeName \n * @returns \n */\n public mapResourceTypeNameToRouteSegment(resourceTypeName: string) {\n const item = this._resourceTypeMap.find(rt => rt.name.trim().toLowerCase() === resourceTypeName.trim().toLowerCase());\n if (item)\n return item.routeSegment;\n else\n return null \n }\n\n /**\n * Maps a route segment to the corresponding Resource Type record Name column\n * @param resourceRouteSegment \n * @returns \n */\n public mapResourceTypeRouteSegmentToName(resourceRouteSegment: string) {\n const item = this._resourceTypeMap.find(rt => rt.routeSegment.trim().toLowerCase() === resourceRouteSegment.trim().toLowerCase());\n if (item)\n return item.name;\n else\n return null \n }\n\n /**\n * Opens an entity record in a new or existing tab\n * Uses the modern NavigationService for tab-based navigation\n */\n public OpenEntityRecord(entityName: string, recordPkey: CompositeKey) {\n try {\n console.log('SharedService.OpenEntityRecord called:', entityName, recordPkey.ToURLSegment());\n // Use NavigationService to open in new tab-based UX\n this.navigationService.OpenEntityRecord(entityName, recordPkey);\n }\n catch (e) {\n console.error('Error in OpenEntityRecord:', e);\n LogError(e);\n }\n }\n}\n\nexport const HtmlListType = {\n Unordered: 'Unordered',\n Ordered: 'Ordered',\n} as const;\n\nexport type HtmlListType = typeof HtmlListType[keyof typeof HtmlListType];\n\n\nexport const EventCodes = {\n ViewClicked: \"ViewClicked\",\n EntityRecordClicked: \"EntityRecordClicked\",\n AddDashboard: \"AddDashboard\",\n AddReport: \"AddReport\",\n AddQuery: \"AddQuery\",\n ViewCreated: \"ViewCreated\",\n ViewUpdated: \"ViewUpdated\",\n RunSearch: \"RunSearch\",\n ViewNotifications: \"ViewNotifications\",\n PushStatusUpdates: \"PushStatusUpdates\",\n UserNotificationsUpdated: \"UserNotificationsUpdated\",\n CloseCurrentTab: \"CloseCurrentTab\",\n ListCreated: \"ListCreated\",\n ListClicked: 'ListClicked',\n AvatarUpdated: 'AvatarUpdated'\n} as const;\n\nexport type EventCodes = typeof EventCodes[keyof typeof EventCodes];"]}
1
+ {"version":3,"file":"shared.service.js","sourceRoot":"","sources":["../../src/lib/shared.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { ElementRef, Injectable, Injector } from '@angular/core';\nimport { CompositeKey, IMetadataProvider, LocalCacheManager, LogError, Metadata, StartupManager } from '@memberjunction/core';\nimport { ArtifactMetadataEngine, DashboardEngine, ResourcePermissionEngine, MJResourceTypeEntity, MJUserNotificationEntity, ViewColumnInfo } from '@memberjunction/core-entities';\nimport { AIEngineBase } from '@memberjunction/ai-engine-base';\nimport { EntityCommunicationsEngineBase } from \"@memberjunction/entity-communications-base\";\nimport { MJEventType, MJGlobal, ConvertMarkdownStringToHtmlList, InvokeManualResize, UUIDsEqual, GetGlobalObjectStore } from '@memberjunction/global';\nimport { GraphQLDataProvider } from '@memberjunction/graphql-dataprovider';\nimport { Subject, Observable, BehaviorSubject, firstValueFrom } from 'rxjs';\nimport { first, tap } from 'rxjs/operators';\nimport { MJNotificationService } from '@memberjunction/ng-notifications';\nimport { IsDescendantElement } from '@memberjunction/ng-shared-generic';\nimport { RecordNavigationAdapter } from '@memberjunction/ng-base-types';\nimport { NavigationService } from './navigation.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class SharedService {\n private static readonly _globalStoreKey = '___SINGLETON__SharedService';\n private static _loaded: boolean = false;\n private static _resourceTypes: MJResourceTypeEntity[] = [];\n private static isLoading$ = new BehaviorSubject<boolean>(false);\n private tabChange = new Subject();\n tabChange$ = this.tabChange.asObservable();\n private _navigationService: NavigationService | null = null;\n\n constructor(\n private mjNotificationsService: MJNotificationService,\n private injector: Injector\n ) {\n const g = GetGlobalObjectStore()!;\n if (g[SharedService._globalStoreKey]) {\n return g[SharedService._globalStoreKey] as SharedService;\n }\n g[SharedService._globalStoreKey] = this;\n\n // Supply record navigation to Generic widgets that need it but must not import Explorer.\n // The widget calls RecordNavigationAdapter.OpenEntityRecord(...); this is what makes that\n // resolve to an Explorer tab. Registered here because SharedService is constructed once per\n // app and is already the Explorer-side owner of OpenEntityRecord.\n // See guides/UI_LAYERING_GUIDE.md §3 and the adapter's own docs.\n RecordNavigationAdapter.Register({\n OpenEntityRecord: (entityName, recordKey) => this.OpenEntityRecord(entityName, recordKey),\n });\n\n MJGlobal.Instance.GetEventListener(true).subscribe(async (event) => {\n switch (event.event) {\n case MJEventType.LoggedIn:\n if (SharedService._loaded === false) {\n // Pre-warm non-critical engines IMMEDIATELY on LoggedIn, before\n // StartupManager.Startup() completes. These engines only need\n // Metadata.Provider (set during setupGraphQLClient's provider.Config()).\n // Firing them here allows their RunViews calls to be coalesced with\n // the startup engines' calls into fewer mega-batched GraphQL requests.\n SharedService.preWarmEngines();\n\n // Handle app startup — joins the same Startup() promise that\n // setupGraphQLClient kicked off.\n await StartupManager.Instance.Startup();\n\n await SharedService.RefreshData(false);\n }\n break;\n }\n }); \n }\n\n public static get Instance(): SharedService {\n return GetGlobalObjectStore()![SharedService._globalStoreKey] as SharedService;\n }\n\n /**\n * Optional explicit metadata provider. Set via `setProvider()` from a caller\n * with provider context (e.g. the shell). Falls back to `Metadata.Provider`\n * when not set.\n */\n private _provider: IMetadataProvider | null = null;\n\n public set Provider(value: IMetadataProvider | null) {\n this._provider = value;\n }\n\n public get Provider(): IMetadataProvider {\n return this._provider ?? Metadata.Provider;\n }\n\n /**\n * Pre-warms commonly used engines in the background after login.\n * This reduces perceived latency when users navigate to features like\n * Conversations, Dashboards, or Artifacts. Fire-and-forget pattern -\n * errors are logged but don't block the UI.\n */\n private static preWarmEngines(): void {\n // AIEngineBase is the slowest - loads agents, models, prompts, etc.\n // Critical for Conversations feature\n AIEngineBase.Instance.Config(false).catch(err =>\n LogError(`Failed to pre-warm AIEngineBase: ${err}`)\n );\n\n // ArtifactMetadataEngine.Config() loads only the artifact-type registry —\n // a small, fixed set. Artifacts and versions (whose Content can be huge) are\n // fetched on demand per-artifact, so this pre-warm stays cheap and bounded.\n // Used by Conversations and the Artifact viewer.\n ArtifactMetadataEngine.Instance.Config(false).catch(err =>\n LogError(`Failed to pre-warm ArtifactMetadataEngine: ${err}`)\n );\n\n // DashboardEngine loads dashboard metadata\n // Used when viewing dashboards\n DashboardEngine.Instance.Config(false).catch(err =>\n LogError(`Failed to pre-warm DashboardEngine: ${err}`)\n );\n\n EntityCommunicationsEngineBase.Instance.Config(false).catch(err =>\n LogError(`Failed to pre-warm DashboardEngine: ${err}`)\n );\n }\n\n /**\n * Get the NavigationService singleton instance\n * Lazy-loaded to avoid circular dependency issues\n */\n private get navigationService(): NavigationService {\n if (!this._navigationService) {\n this._navigationService = this.injector.get(NavigationService);\n }\n return this._navigationService;\n }\n\n /**\n * Get the neutral color used for system-wide resources\n */\n public get ExplorerAppColor(): string {\n return this.navigationService.ExplorerAppColor;\n }\n\n /**\n * Returns the current session ID, which is automatically created when the service is instantiated.\n */\n public get SessionId(): string {\n return (<GraphQLDataProvider>this.Provider).sessionId;\n }\n\n public get ResourceTypes(): MJResourceTypeEntity[] {\n return SharedService._resourceTypes;\n }\n public get ViewResourceType(): MJResourceTypeEntity {\n return SharedService._resourceTypes.find(rt => rt.Name.trim().toLowerCase() === 'user views')!;\n }\n public get RecordResourceType(): MJResourceTypeEntity {\n return SharedService._resourceTypes.find(rt => rt.Name.trim().toLowerCase() === 'records')!;\n }\n public get DashboardResourceType(): MJResourceTypeEntity {\n return SharedService._resourceTypes.find(rt => rt.Name.trim().toLowerCase() === 'dashboards')!;\n }\n public get SearchResultsResourceType(): MJResourceTypeEntity {\n return SharedService._resourceTypes.find(rt => rt.Name.trim().toLowerCase() === 'search results')!;\n }\n public get ListResourceType(): MJResourceTypeEntity {\n return SharedService._resourceTypes.find(rt => rt.Name.trim().toLowerCase() === 'lists')!;\n }\n public ResourceTypeByID(id: string): MJResourceTypeEntity | undefined {\n return SharedService._resourceTypes.find(rt => UUIDsEqual(rt.ID, id));\n }\n public ResourceTypeByName(name: string): MJResourceTypeEntity | undefined {\n return SharedService._resourceTypes.find(rt => rt.Name.trim().toLowerCase() === name.trim().toLowerCase());\n }\n\n /**\n * Refreshes the data for the service. If OnlyIfNeeded is true, then the data is only refreshed if it hasn't been loaded yet.\n */\n public static async RefreshData(OnlyIfNeeded: boolean = false) {\n if (OnlyIfNeeded && SharedService._loaded) {\n return;\n }\n\n const canProceed$ = SharedService.isLoading$.pipe(\n first(isLoading => !isLoading),\n tap(() => SharedService.isLoading$.next(true))\n );\n\n await firstValueFrom(canProceed$);\n\n try {\n // After waiting for the current loading operation to complete, check again\n // if _loaded is true and OnlyIfNeeded is true, return early\n if (OnlyIfNeeded && SharedService._loaded) {\n return;\n }\n\n await SharedService.handleDataLoading();\n\n // Mark as loaded\n SharedService._loaded = true;\n } finally {\n // Ensure we always reset the loading flag\n SharedService.isLoading$.next(false);\n }\n }\n\n private static async handleDataLoading() {\n // make sure startup is done\n await StartupManager.Instance.Startup();\n\n this._resourceTypes = ResourcePermissionEngine.Instance.ResourceTypes;\n\n // Note: RefreshUserNotifications() removed here because MJNotificationService\n // already handles it via its own MJEventType.LoggedIn subscription. Calling it\n // from both places caused a duplicate User Notifications GraphQL request on login.\n } \n\n FormatColumnValue(col: ViewColumnInfo, value: any, maxLength: number = 0, trailingChars: string = \"...\") {\n if (value === null || value === undefined)\n return value;\n\n try {\n const retVal = col.EntityField.FormatValue(value, 0);\n if (maxLength > 0 && retVal && retVal.length > maxLength)\n return retVal.substring(0, maxLength) + trailingChars;\n else\n return retVal;\n }\n catch (e) {\n LogError(e);\n return value;\n }\n }\n\n public ConvertMarkdownStringToHtmlList(listType: HtmlListType, text: string): string {\n return ConvertMarkdownStringToHtmlList(listType, text) ?? text;\n }\n\n \n public InvokeManualResize(delay: number = 50) {\n return InvokeManualResize(delay, this);\n }\n\n public PushStatusUpdates(): Observable<string> {\n const gp: GraphQLDataProvider = <GraphQLDataProvider>this.Provider;\n return gp.PushStatusUpdates();\n }\n\n private _currentUserImage: string | Blob = '/assets/user.png';\n public get CurrentUserImage(): string | Blob {\n return this._currentUserImage;\n }\n public set CurrentUserImage(value: string | Blob) {\n this._currentUserImage = value;\n }\n\n /**\n * @deprecated Use MJNotificationService.UserNotifications instead\n */\n public static get UserNotifications(): MJUserNotificationEntity[] {\n return MJNotificationService.UserNotifications;\n }\n /**\n * @deprecated Use MJNotificationService.UnreadUserNotifications instead\n */\n public static get UnreadUserNotifications(): MJUserNotificationEntity[] {\n return MJNotificationService.UnreadUserNotifications;\n }\n /**\n * @deprecated Use MJNotificationService.UnreadUserNotificationCount instead\n */\n public static get UnreadUserNotificationCount(): number {\n return MJNotificationService.UnreadUserNotificationCount;\n }\n\n /**\n * Utility method that returns true if child is a descendant of parent, false otherwise. \n */\n /**\n * @deprecated Use `IsDescendantElement` from `@memberjunction/ng-shared-generic`. This is a pure\n * DOM predicate with no Explorer coupling; keeping it here forced widgets that wanted it to\n * depend on Explorer. Delegates so existing callers are unaffected.\n */\n public static IsDescendant(parent: ElementRef, child: ElementRef) {\n return IsDescendantElement(parent, child);\n }\n\n\n /**\n * Creates a notification in the database and refreshes the UI. Returns the notification object.\n * @param title \n * @param message \n * @param resourceTypeId \n * @param resourceRecordId \n * @param resourceConfiguration Any object, it is converted to a string by JSON.stringify and stored in the database\n * @returns \n * @deprecated Use MJNotificationService.CreateNotification instead\n */\n public async CreateNotification(title: string, message: string, resourceTypeId: string | null, resourceRecordId: string | null, resourceConfiguration: any | null, displayToUser : boolean = true): Promise<MJUserNotificationEntity> {\n return this.mjNotificationsService.CreateNotification(title, message, resourceTypeId, resourceRecordId, resourceConfiguration, displayToUser);\n }\n\n /**\n * @deprecated Use MJNotificationService.RefreshUserNotifications instead\n */\n public static async RefreshUserNotifications() {\n MJNotificationService.RefreshUserNotifications();\n }\n\n /**\n * Creates a message that is not saved to the User Notifications table, but is displayed to the user.\n * @param message - text to display\n * @param style - display styling\n * @param hideAfter - option to auto hide after the specified delay in milliseconds\n * @deprecated Use MJNotificationService.CreateSimpleNotification instead\n */\n public CreateSimpleNotification(message: string, style: \"none\" | \"success\" | \"error\" | \"warning\" | \"info\" = \"success\", hideAfter?: number) {\n return this.mjNotificationsService.CreateSimpleNotification(message, style, hideAfter);\n }\n\n\n\n private _resourceTypeMap = [\n { routeSegment: 'record', name: 'records' },\n { routeSegment: 'view', name: 'user views' },\n { routeSegment: 'search', name: 'search results' },\n { routeSegment: 'query', name: 'queries' },\n { routeSegment: 'dashboard', name: 'dashboards' },\n { routeSegment: 'list', name: 'lists' },\n \n ]\n /**\n * Maps a Resource Type record Name column to the corresponding route segment\n * @param resourceTypeName \n * @returns \n */\n public mapResourceTypeNameToRouteSegment(resourceTypeName: string) {\n const item = this._resourceTypeMap.find(rt => rt.name.trim().toLowerCase() === resourceTypeName.trim().toLowerCase());\n if (item)\n return item.routeSegment;\n else\n return null \n }\n\n /**\n * Maps a route segment to the corresponding Resource Type record Name column\n * @param resourceRouteSegment \n * @returns \n */\n public mapResourceTypeRouteSegmentToName(resourceRouteSegment: string) {\n const item = this._resourceTypeMap.find(rt => rt.routeSegment.trim().toLowerCase() === resourceRouteSegment.trim().toLowerCase());\n if (item)\n return item.name;\n else\n return null \n }\n\n /**\n * Opens an entity record in a new or existing tab\n * Uses the modern NavigationService for tab-based navigation\n */\n public OpenEntityRecord(entityName: string, recordPkey: CompositeKey) {\n try {\n console.log('SharedService.OpenEntityRecord called:', entityName, recordPkey.ToURLSegment());\n // Use NavigationService to open in new tab-based UX\n this.navigationService.OpenEntityRecord(entityName, recordPkey);\n }\n catch (e) {\n console.error('Error in OpenEntityRecord:', e);\n LogError(e);\n }\n }\n}\n\nexport const HtmlListType = {\n Unordered: 'Unordered',\n Ordered: 'Ordered',\n} as const;\n\nexport type HtmlListType = typeof HtmlListType[keyof typeof HtmlListType];\n\n\nexport const EventCodes = {\n ViewClicked: \"ViewClicked\",\n EntityRecordClicked: \"EntityRecordClicked\",\n AddDashboard: \"AddDashboard\",\n AddReport: \"AddReport\",\n AddQuery: \"AddQuery\",\n ViewCreated: \"ViewCreated\",\n ViewUpdated: \"ViewUpdated\",\n RunSearch: \"RunSearch\",\n ViewNotifications: \"ViewNotifications\",\n PushStatusUpdates: \"PushStatusUpdates\",\n UserNotificationsUpdated: \"UserNotificationsUpdated\",\n CloseCurrentTab: \"CloseCurrentTab\",\n ListCreated: \"ListCreated\",\n ListClicked: 'ListClicked',\n AvatarUpdated: 'AvatarUpdated'\n} as const;\n\nexport type EventCodes = typeof EventCodes[keyof typeof EventCodes];"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ng-shared",
3
- "version": "6.1.0-edge.0",
3
+ "version": "6.1.0-edge.2",
4
4
  "description": "MemberJunction: MJ Explorer Angular Shared Package - utility functions and other reusable elements used across other MJ Angular packages within the MJ Explorer App - do not use outside of MJ Explorer.",
5
5
  "main": "./dist/public-api.js",
6
6
  "typings": "./dist/public-api.d.ts",
@@ -18,24 +18,24 @@
18
18
  "@angular/compiler-cli": "21.1.3"
19
19
  },
20
20
  "peerDependencies": {
21
- "@angular/common": "21.1.3",
22
- "@angular/core": "21.1.3",
23
- "@angular/router": "21.1.3",
21
+ "@angular/common": "^21.1.3",
22
+ "@angular/core": "^21.1.3",
23
+ "@angular/router": "^21.1.3",
24
24
  "rxjs": "^7.8.2"
25
25
  },
26
26
  "dependencies": {
27
27
  "@angular/platform-browser": "21.1.3",
28
- "@memberjunction/ai-core-plus": "6.1.0-edge.0",
29
- "@memberjunction/ai-engine-base": "6.1.0-edge.0",
30
- "@memberjunction/core": "6.1.0-edge.0",
31
- "@memberjunction/core-entities": "6.1.0-edge.0",
32
- "@memberjunction/entity-communications-base": "6.1.0-edge.0",
33
- "@memberjunction/global": "6.1.0-edge.0",
34
- "@memberjunction/graphql-dataprovider": "6.1.0-edge.0",
35
- "@memberjunction/ng-base-application": "6.1.0-edge.0",
36
- "@memberjunction/ng-base-types": "6.1.0-edge.0",
37
- "@memberjunction/ng-notifications": "6.1.0-edge.0",
38
- "@memberjunction/ng-shared-generic": "6.1.0-edge.0",
28
+ "@memberjunction/ai-core-plus": "6.1.0-edge.2",
29
+ "@memberjunction/ai-engine-base": "6.1.0-edge.2",
30
+ "@memberjunction/core": "6.1.0-edge.2",
31
+ "@memberjunction/core-entities": "6.1.0-edge.2",
32
+ "@memberjunction/entity-communications-base": "6.1.0-edge.2",
33
+ "@memberjunction/global": "6.1.0-edge.2",
34
+ "@memberjunction/graphql-dataprovider": "6.1.0-edge.2",
35
+ "@memberjunction/ng-base-application": "6.1.0-edge.2",
36
+ "@memberjunction/ng-base-types": "6.1.0-edge.2",
37
+ "@memberjunction/ng-notifications": "6.1.0-edge.2",
38
+ "@memberjunction/ng-shared-generic": "6.1.0-edge.2",
39
39
  "html-to-image": "^1.11.11",
40
40
  "tslib": "^2.8.1"
41
41
  },