@edvak99/voice-receptionist-widget 1.1.21 → 1.1.22
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.
- package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-dcDXT2KG.mjs +533 -0
- package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-dcDXT2KG.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-analytics-page.component-CmImX5FN.mjs → edvak99-voice-receptionist-widget-analytics-page.component-B25yZJZz.mjs} +2 -2
- package/fesm2022/{edvak99-voice-receptionist-widget-analytics-page.component-CmImX5FN.mjs.map → edvak99-voice-receptionist-widget-analytics-page.component-B25yZJZz.mjs.map} +1 -1
- package/fesm2022/edvak99-voice-receptionist-widget-audit-page.component-Df-dtgR3.mjs +96 -0
- package/fesm2022/edvak99-voice-receptionist-widget-audit-page.component-Df-dtgR3.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-call-history-detail-page.component-BT4clUO-.mjs → edvak99-voice-receptionist-widget-call-history-detail-page.component-BJGzgVxG.mjs} +21 -10
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-BJGzgVxG.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-CcwwO5SO.mjs +254 -0
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-CcwwO5SO.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-call-recording-player.component-4fL-zUWy.mjs → edvak99-voice-receptionist-widget-call-recording-player.component-BepxNLNQ.mjs} +2 -2
- package/fesm2022/{edvak99-voice-receptionist-widget-call-recording-player.component-4fL-zUWy.mjs.map → edvak99-voice-receptionist-widget-call-recording-player.component-BepxNLNQ.mjs.map} +1 -1
- package/fesm2022/{edvak99-voice-receptionist-widget-call-review.service-BhbCmB1S.mjs → edvak99-voice-receptionist-widget-call-review.service-nFqc30t3.mjs} +2 -2
- package/fesm2022/{edvak99-voice-receptionist-widget-call-review.service-BhbCmB1S.mjs.map → edvak99-voice-receptionist-widget-call-review.service-nFqc30t3.mjs.map} +1 -1
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-CMgOu0aw.mjs +311 -0
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-CMgOu0aw.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-DDS7VdnD.mjs → edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-CJ1L6QeE.mjs} +54 -25
- package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-CJ1L6QeE.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-live-calls-page.component-4LtgT4lS.mjs → edvak99-voice-receptionist-widget-live-calls-page.component-MnBMu8iA.mjs} +4 -4
- package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-MnBMu8iA.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-live-monitor-page.component-B1lKfw-j.mjs → edvak99-voice-receptionist-widget-live-monitor-page.component-BzvMkbC4.mjs} +10 -7
- package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-BzvMkbC4.mjs.map +1 -0
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-Aws6TaaE.mjs +273 -0
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-Aws6TaaE.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-task-detail-drawer.component-aDTKTV79.mjs → edvak99-voice-receptionist-widget-task-detail-drawer.component-DVWdArqj.mjs} +14 -6
- package/fesm2022/edvak99-voice-receptionist-widget-task-detail-drawer.component-DVWdArqj.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-tasks-page.component-Dj1nWx6V.mjs → edvak99-voice-receptionist-widget-tasks-page.component-CBDmGLol.mjs} +11 -7
- package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-CBDmGLol.mjs.map +1 -0
- package/fesm2022/{edvak99-voice-receptionist-widget-wizard-page.component-CQttbEzW.mjs → edvak99-voice-receptionist-widget-wizard-page.component-C-hdBQIV.mjs} +2 -2
- package/fesm2022/{edvak99-voice-receptionist-widget-wizard-page.component-CQttbEzW.mjs.map → edvak99-voice-receptionist-widget-wizard-page.component-C-hdBQIV.mjs.map} +1 -1
- package/fesm2022/edvak99-voice-receptionist-widget.mjs +1 -1
- package/lib/components/call-tasks-panel/call-tasks-panel.component.d.ts +3 -0
- package/lib/components/patient-profile-drawer/patient-profile-drawer.component.d.ts +3 -0
- package/lib/components/task-detail-drawer/task-detail-drawer.component.d.ts +3 -0
- package/lib/pages/activities-page/activities-page.component.d.ts +5 -2
- package/lib/pages/audit-page/audit-page.component.d.ts +3 -0
- package/lib/pages/call-history-detail-page/call-history-detail-page.component.d.ts +2 -0
- package/lib/pages/call-history-page/call-history-page.component.d.ts +1 -0
- package/lib/pages/dashboard-page/dashboard-page.component.d.ts +4 -0
- package/lib/pages/live-monitor-page/live-monitor-page.component.d.ts +2 -0
- package/lib/pages/outbound-purposes-page/outbound-purposes-page.component.d.ts +3 -0
- package/lib/pages/settings-page/settings-page.component.d.ts +1 -0
- package/lib/pages/tasks-page/tasks-page.component.d.ts +2 -0
- package/lib/services/ai-receptionist-api.service.d.ts +1 -0
- package/package.json +1 -1
- package/src/assets/css/_tables.scss +12 -0
- package/styles/embed.scss +27 -0
- package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-CpXa1J9-.mjs +0 -510
- package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-CpXa1J9-.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-audit-page.component-DTAB2WTX.mjs +0 -78
- package/fesm2022/edvak99-voice-receptionist-widget-audit-page.component-DTAB2WTX.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-BT4clUO-.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-BACON4uq.mjs +0 -247
- package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-BACON4uq.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-CxNYLBbg.mjs +0 -291
- package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-CxNYLBbg.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-DDS7VdnD.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-4LtgT4lS.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-B1lKfw-j.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-BkIHblSu.mjs +0 -269
- package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-BkIHblSu.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-task-detail-drawer.component-aDTKTV79.mjs.map +0 -1
- package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-Dj1nWx6V.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edvak99-voice-receptionist-widget-activities-page.component-dcDXT2KG.mjs","sources":["../../../src/lib/components/patient-profile-drawer/patient-profile-drawer.component.ts","../../../src/lib/components/patient-profile-drawer/patient-profile-drawer.component.html","../../../src/lib/pages/activities-page/activities-page.component.ts","../../../src/lib/pages/activities-page/activities-page.component.html"],"sourcesContent":["import { DatePipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n CUSTOM_ELEMENTS_SCHEMA,\n inject,\n input,\n output,\n} from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\n\nimport { AgentActivity } from '../../models/agent-activity.types';\nimport { EdAvatarComponent } from '../../ui/ed-avatar.component';\nimport { EdIconButtonComponent } from '../../ui/ed-icon-button.component';\nimport { IconComponent } from '../../ui/ed-icon.component';\nimport { ViewportPortalDirective } from '../../shared/viewport-portal.directive';\n\n@Component({\n selector: 'eds-patient-profile-drawer',\n imports: [\n DatePipe,\n EdAvatarComponent,\n EdIconButtonComponent,\n IconComponent,\n ViewportPortalDirective,\n ],\n templateUrl: './patient-profile-drawer.component.html',\n styleUrl: './patient-profile-drawer.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\n})\nexport class PatientProfileDrawerComponent {\n private readonly router = inject(Router);\n private readonly route = inject(ActivatedRoute);\n\n readonly patient = input.required<AgentActivity>();\n\n readonly closed = output<void>();\n\n protected close(): void {\n this.closed.emit();\n }\n\n protected openCallHistory(): void {\n const callId = this.patient().callId;\n if (!callId) return;\n this.close();\n void this.router.navigate(['../history', callId], { relativeTo: this.route });\n }\n\n protected onBackdropClick(event: MouseEvent): void {\n if (event.target === event.currentTarget) this.close();\n }\n\n protected display(value: string | null | undefined): string {\n const s = String(value ?? '').trim();\n return s || '—';\n }\n\n protected insuranceLabel(): string {\n const p = this.patient();\n if (p.hasInsurance === true) {\n return p.insuranceName ? `Insured — ${p.insuranceName}` : 'Insured';\n }\n if (p.hasInsurance === false) return 'No insurance on file';\n return p.insuranceName || 'Not verified';\n }\n\n protected insuranceTone(): 'covered' | 'none' | 'unknown' {\n const p = this.patient();\n if (p.hasInsurance === true) return 'covered';\n if (p.hasInsurance === false) return 'none';\n return 'unknown';\n }\n}\n","<div\n edsViewportPortal\n class=\"eds-drawer-backdrop fixed left-0 top-0 z-[100100] flex h-[100vh] w-[100vw] justify-end\"\n (click)=\"onBackdropClick($event)\"\n role=\"presentation\"\n>\n <ed-drawer\n size=\"base\"\n class=\"slide-in-rtl ed-main-sidepanel h-full bg-[#f7f8fa]\"\n role=\"dialog\"\n aria-modal=\"true\"\n [attr.aria-label]=\"display(patient().patientName)\"\n >\n <ed-drawer-header class=\"border-b border-zinc-200 bg-white px-4 py-3 shadow-none\">\n <h6 class=\"m-0 text-base font-semibold text-zinc-900\">Patient profile</h6>\n <ed-icon-button\n name=\"close\"\n label=\"Close\"\n size=\"sm\"\n ghost\n (click$)=\"close()\"\n />\n </ed-drawer-header>\n\n <ed-drawer-body class=\"flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto\">\n <section class=\"rounded-xl border border-zinc-200 bg-white p-4\">\n <div class=\"flex items-start gap-3\">\n <ed-avatar\n shape=\"box\"\n size=\"base\"\n [initials]=\"patient().patientInitials || '?'\"\n tone=\"brand\"\n />\n <div class=\"min-w-0 flex-1\">\n <h4>\n {{ display(patient().patientName) }}\n </h4>\n @if (patient().patientDob || patient().patientAge != null || patient().patientGender) {\n <p class=\"mt-1 mb-0 text-sm text-zinc-500\">\n @if (patient().patientDob) {\n DOB: {{ patient().patientDob | date: 'MM/dd/yyyy' }}\n }\n @if (patient().patientAge != null) {\n · {{ patient().patientAge }}Y\n }\n @if (patient().patientGender) {\n · {{ patient().patientGender }}\n }\n </p>\n }\n </div>\n </div>\n </section>\n\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">MRN</span>\n <span class=\"text-sm text-zinc-600\">{{ display(patient().patientMrn) }}</span>\n </div>\n </section>\n\n @if (patient().patientId) {\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">Patient ID</span>\n <span class=\"font-mono text-sm text-zinc-600\">{{ patient().patientId }}</span>\n </div>\n </section>\n }\n\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">Insurance</span>\n <span\n class=\"vr-insurance-badge inline-flex items-center rounded-full border px-2.5 py-1 text-xs font-medium\"\n [attr.data-state]=\"insuranceTone()\"\n >\n {{ insuranceLabel() }}\n </span>\n </div>\n </section>\n\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">Registered</span>\n <span class=\"text-sm text-zinc-600\">\n @if (patient().occurredAt) {\n {{ patient().occurredAt | date: 'MMM d, y, h:mm a' }}\n } @else {\n —\n }\n </span>\n </div>\n </section>\n\n @if (patient().detail) {\n <section class=\"rounded-xl border border-zinc-200 bg-white p-4\">\n <h3 class=\"m-0 text-sm font-semibold text-zinc-800\">Details</h3>\n <p class=\"mt-2 mb-0 whitespace-pre-wrap text-sm leading-relaxed text-zinc-600\">\n {{ patient().detail }}\n </p>\n </section>\n }\n\n @if (patient().callId) {\n <section class=\"rounded-xl border border-zinc-200 bg-white px-4 py-3\">\n <div class=\"flex items-center justify-between gap-3\">\n <span class=\"text-sm font-medium text-zinc-800\">Call</span>\n <button\n type=\"button\"\n class=\"eds-plain-nav text-sm font-medium text-dark\"\n (click)=\"openCallHistory()\"\n >\n View call\n </button>\n </div>\n </section>\n }\n </ed-drawer-body>\n </ed-drawer>\n</div>\n","import { ChangeDetectionStrategy, Component, CUSTOM_ELEMENTS_SCHEMA, OnDestroy, OnInit, inject, signal } from '@angular/core';\nimport { ActivatedRoute, Router } from '@angular/router';\n\nimport { PatientProfileDrawerComponent } from '../../components/patient-profile-drawer/patient-profile-drawer.component';\nimport { TaskDetailDrawerComponent } from '../../components/task-detail-drawer/task-detail-drawer.component';\nimport {\n ActivitiesTab,\n AgentActivity,\n initialsFromName,\n} from '../../models/agent-activity.types';\nimport { TaskItem, TaskStatus } from '../../models/ai-receptionist.types';\nimport { DEFAULT_PAGE_SIZE, totalPages as calcTotalPages } from '../../models/pagination';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { ageFromDob } from '../../utils/call-history-display.util';\nimport { EdButtonComponent } from '../../ui/ed-button.component';\nimport { EdSkeletonComponent } from '../../ui/ed-skeleton.component';\n\nimport { SmartTooltipDirective } from '../../shared/smart-tooltip.directive';\nimport { TABLE_SKELETON_ROWS } from '../../shared/table-skeleton.constants';\nimport { EdAvatarComponent } from '../../ui/ed-avatar.component';\nimport { IconComponent } from '../../ui/ed-icon.component';\nimport { EdsSearchFieldComponent } from '../../ui/eds-search-field.component';\n\ntype TabId = ActivitiesTab;\n\nconst TABS: { id: TabId; label: string }[] = [\n { id: 'task_created', label: 'Tasks' },\n { id: 'appointment_booked', label: 'Appointments' },\n { id: 'patient_created', label: 'Registrations' },\n];\n\nconst AVATAR_TONES = ['green', 'amber', 'brand', 'violet', 'rose'] as const;\n\n@Component({\n selector: 'eds-activities-page',\n imports: [\n EdAvatarComponent,\n IconComponent,\n EdButtonComponent,\n EdsSearchFieldComponent,\n SmartTooltipDirective,\n EdSkeletonComponent,\n TaskDetailDrawerComponent,\n PatientProfileDrawerComponent,\n ],\n templateUrl: './activities-page.component.html',\n styleUrl: './activities-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\n host: { class: 'block h-full min-h-0' },\n})\nexport class ActivitiesPageComponent implements OnInit, OnDestroy {\n private readonly api = inject(AiReceptionistApiService);\n private readonly route = inject(ActivatedRoute);\n private readonly router = inject(Router);\n\n protected readonly tabs = TABS;\n protected readonly pageSize = DEFAULT_PAGE_SIZE;\n protected readonly items = signal<AgentActivity[]>([]);\n protected readonly total = signal(0);\n protected readonly page = signal(1);\n protected readonly activeTab = signal<TabId>('task_created');\n protected readonly callIdFilter = signal<string | null>(null);\n protected readonly search = signal('');\n protected readonly loading = signal(true);\n protected readonly loadError = signal<string | null>(null);\n protected readonly skeletonRows = TABLE_SKELETON_ROWS;\n protected readonly selectedTask = signal<TaskItem | null>(null);\n protected readonly selectedPatient = signal<AgentActivity | null>(null);\n private searchTimer: ReturnType<typeof setTimeout> | null = null;\n\n ngOnInit(): void {\n const callId = this.route.snapshot.queryParamMap.get('callId')?.trim() || null;\n if (callId) this.callIdFilter.set(callId);\n\n const tabParam = (this.route.snapshot.queryParamMap.get('tab') || '').trim().toLowerCase();\n const tabFromQuery = this.tabFromQuery(tabParam);\n if (tabFromQuery) {\n this.activeTab.set(tabFromQuery);\n } else {\n this.activeTab.set('task_created');\n void this.router.navigate([], {\n relativeTo: this.route,\n queryParams: { tab: 'tasks' },\n queryParamsHandling: 'merge',\n replaceUrl: true,\n });\n }\n\n this.load();\n }\n\n protected setTab(tab: TabId): void {\n if (this.activeTab() === tab) return;\n this.activeTab.set(tab);\n this.page.set(1);\n void this.router.navigate([], {\n relativeTo: this.route,\n queryParams: { tab: this.tabQueryValue(tab) },\n queryParamsHandling: 'merge',\n replaceUrl: true,\n });\n this.load();\n }\n\n private tabFromQuery(raw: string): TabId | null {\n switch (raw) {\n case 'tasks':\n case 'task':\n case 'task_created':\n return 'task_created';\n case 'appointments':\n case 'appointment':\n case 'appointment_booked':\n return 'appointment_booked';\n case 'registrations':\n case 'registration':\n case 'patient_created':\n return 'patient_created';\n default:\n return null;\n }\n }\n\n private tabQueryValue(tab: TabId): string {\n switch (tab) {\n case 'task_created':\n return 'tasks';\n case 'patient_created':\n return 'registrations';\n default:\n return 'appointments';\n }\n }\n\n protected clearCallFilter(): void {\n this.callIdFilter.set(null);\n this.page.set(1);\n this.load();\n }\n\n ngOnDestroy(): void {\n if (this.searchTimer) clearTimeout(this.searchTimer);\n }\n\n protected onSearchInput(value: string): void {\n this.search.set(value);\n if (this.searchTimer) clearTimeout(this.searchTimer);\n this.searchTimer = setTimeout(() => {\n this.page.set(1);\n this.load();\n }, value.trim() ? 300 : 0);\n }\n\n protected applySearch(): void {\n if (this.searchTimer) clearTimeout(this.searchTimer);\n this.page.set(1);\n this.load();\n }\n\n protected load(): void {\n this.loading.set(true);\n this.loadError.set(null);\n const tab = this.activeTab();\n this.api\n .getActivities({\n page: this.page(),\n limit: DEFAULT_PAGE_SIZE,\n types: tab,\n callId: this.callIdFilter() || undefined,\n search: this.search().trim() || undefined,\n })\n .subscribe({\n next: ({ items, total, page }) => {\n this.items.set(items);\n this.total.set(total);\n this.page.set(page);\n this.loading.set(false);\n },\n error: () => {\n this.loading.set(false);\n this.items.set([]);\n this.total.set(0);\n this.loadError.set(\n 'Activities feed is unavailable. Confirm GET /api/ai-receptionist/activities is deployed.',\n );\n },\n });\n }\n\n protected totalPages(): number {\n return calcTotalPages(this.total(), DEFAULT_PAGE_SIZE);\n }\n\n protected prevPage(): void {\n if (this.page() <= 1) return;\n this.page.update((p) => p - 1);\n this.load();\n }\n\n protected nextPage(): void {\n if (this.page() >= this.totalPages()) return;\n this.page.update((p) => p + 1);\n this.load();\n }\n\n protected historyLink(callId: string | null | undefined): string[] | null {\n return callId ? ['../history', callId] : null;\n }\n\n protected openCallHistory(callId: string | null | undefined, ev?: Event): void {\n if (!callId) return;\n if (ev && (ev.target as HTMLElement).closest('a,button')) return;\n void this.router.navigate(['../history', callId], { relativeTo: this.route });\n }\n\n protected openTask(item: AgentActivity): void {\n this.selectedPatient.set(null);\n this.selectedTask.set(this.activityToTask(item));\n }\n\n protected openPatient(item: AgentActivity): void {\n this.selectedTask.set(null);\n this.selectedPatient.set(item);\n }\n\n protected closeTaskDrawer(): void {\n this.selectedTask.set(null);\n }\n\n protected closePatientDrawer(): void {\n this.selectedPatient.set(null);\n }\n\n protected onTaskStatusChange(status: TaskStatus): void {\n const task = this.selectedTask();\n if (!task) return;\n this.api.patchTask(task.id, status).subscribe({\n next: ({ data }) => {\n if (data) {\n this.selectedTask.set(data);\n } else {\n this.selectedTask.set({ ...task, status });\n }\n },\n error: () => {\n // Optimistic local update if patch fails (activity-sourced ids may not exist).\n this.selectedTask.set({ ...task, status });\n },\n });\n }\n\n private activityToTask(item: AgentActivity): TaskItem {\n const priority =\n item.priority === 'urgent' || item.priority === 'high' ? 'urgent' : 'normal';\n const created = this.parseDate(item.occurredAt)?.getTime() ?? Date.now();\n return {\n id: item.taskId || item.id,\n created,\n title: this.taskTitle(item),\n type: 'task',\n description: item.detail || '',\n patient: item.patientName || 'Unknown caller',\n priority,\n status: 'open',\n source: 'voice',\n assignee: 'AI Receptionist',\n callId: item.callId || undefined,\n };\n }\n\n protected displayMrn(item: AgentActivity): string {\n return item.patientMrn?.trim() || '—';\n }\n\n protected providerSpecialtyLabel(item: AgentActivity): string | null {\n const s = item.providerSpecialty?.trim();\n if (!s) return null;\n // Hide stray numeric IDs that sometimes land in specialty.\n if (/^\\d+(\\.\\d+)?$/.test(s)) return null;\n return s;\n }\n\n /** Day-anchored stamp — a bare clock time gave no idea which day a row belonged to. */\n protected timestampLabel(item: AgentActivity): string {\n const start = this.parseDate(item.startAt || item.occurredAt);\n if (!start) return '—';\n const stamp = `${this.formatDay(start)}, ${this.formatClock(start)}`;\n const end = this.parseDate(item.endAt);\n if (end && end.getTime() > start.getTime()) {\n return `${stamp} – ${this.formatClock(end)}`;\n }\n return stamp;\n }\n\n protected durationLabel(item: AgentActivity): string | null {\n const mins = item.durationMinutes;\n if (mins == null || mins <= 0) {\n if (item.startAt && item.endAt) {\n const ms = Date.parse(item.endAt) - Date.parse(item.startAt);\n if (Number.isFinite(ms) && ms > 0) {\n return `${Math.round(ms / 60000)} MIN`;\n }\n }\n return null;\n }\n return `${mins} MIN`;\n }\n\n protected appointmentTimeRange(item: AgentActivity): string {\n const start = this.parseDate(item.startAt || item.occurredAt);\n if (!start) return '—';\n const end = this.parseDate(item.endAt);\n if (end && end.getTime() > start.getTime()) {\n return `${this.formatClock(start)} - ${this.formatClock(end)}`;\n }\n return this.formatClock(start);\n }\n\n protected appointmentDayLabel(item: AgentActivity): string {\n const start = this.parseDate(item.startAt || item.occurredAt);\n return start ? this.formatDay(start) : '—';\n }\n\n protected dueLabel(item: AgentActivity): string {\n const d = this.parseDate(item.occurredAt || item.startAt);\n if (!d) return '—';\n return d.toLocaleDateString('en-US', {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n });\n }\n\n protected categoryLabel(item: AgentActivity): string {\n if (item.visitType) return item.visitType;\n switch (item.type) {\n case 'appointment_booked':\n return 'Appointment';\n case 'patient_created':\n return 'Registration';\n case 'task_created':\n return item.title && !/^task created$/i.test(item.title) ? item.title : 'Task';\n default:\n return item.title || 'Activity';\n }\n }\n\n protected patientMeta(item: AgentActivity): string | null {\n const parts: string[] = [];\n const dob = item.patientDob;\n const age = item.patientAge ?? (dob ? ageFromDob(dob) : null);\n if (dob && age != null) parts.push(`DOB: ${this.formatDob(dob)} · ${age}Y`);\n else if (dob) parts.push(`DOB: ${this.formatDob(dob)}`);\n else if (age != null) parts.push(`${age}Y`);\n if (item.patientGender) parts.push(item.patientGender);\n return parts.length ? parts.join(' | ') : null;\n }\n\n protected patientInitials(item: AgentActivity): string {\n return item.patientInitials || initialsFromName(item.patientName) || '?';\n }\n\n protected providerInitials(item: AgentActivity): string {\n return item.providerInitials || initialsFromName(item.providerName) || '?';\n }\n\n protected avatarTone(key: string | null | undefined, salt: number): string {\n const raw = `${key || 'x'}:${salt}`;\n let hash = 0;\n for (let i = 0; i < raw.length; i++) hash = (hash + raw.charCodeAt(i) * (i + 1)) % 997;\n return AVATAR_TONES[hash % AVATAR_TONES.length];\n }\n\n protected insuranceState(item: AgentActivity): 'covered' | 'none' | 'unknown' {\n if (item.hasInsurance === true) return 'covered';\n if (item.hasInsurance === false) return 'none';\n return 'unknown';\n }\n\n protected insuranceIcon(item: AgentActivity): string {\n switch (this.insuranceState(item)) {\n case 'covered':\n return 'verified_user';\n case 'none':\n return 'gpp_bad';\n default:\n return 'gpp_maybe';\n }\n }\n\n protected insuranceLabel(item: AgentActivity): string {\n switch (this.insuranceState(item)) {\n case 'covered':\n return 'Insured';\n case 'none':\n return 'No insurance';\n default:\n return 'Unverified';\n }\n }\n\n protected insuranceTitle(item: AgentActivity): string {\n switch (this.insuranceState(item)) {\n case 'covered':\n return item.insuranceName ? `Insured — ${item.insuranceName}` : 'Insured';\n case 'none':\n return 'No insurance on file';\n default:\n return 'Insurance not verified';\n }\n }\n\n protected isTaskRow(item: AgentActivity): boolean {\n return item.type === 'task_created';\n }\n\n protected taskTitle(item: AgentActivity): string {\n const title = (item.title || '').trim();\n if (title && !/^task created$/i.test(title)) return title;\n return item.visitType || 'Task';\n }\n\n /** Subtitle under the task title; omitted when it duplicates the title. */\n protected taskDetail(item: AgentActivity): string | null {\n const detail = (item.detail || '').trim();\n if (!detail) return null;\n const title = this.taskTitle(item).trim().toLowerCase();\n if (detail.toLowerCase() === title) return null;\n if (/^task created$/i.test(detail)) return null;\n return detail;\n }\n\n protected priorityLabel(item: AgentActivity): string {\n switch (item.priority) {\n case 'urgent':\n return 'Urgent';\n case 'high':\n return 'High';\n case 'low':\n return 'Low';\n case 'medium':\n case 'normal':\n default:\n return 'Medium';\n }\n }\n\n protected priorityTone(item: AgentActivity): string {\n switch (item.priority) {\n case 'urgent':\n return 'urgent';\n case 'high':\n return 'high';\n case 'low':\n return 'low';\n default:\n return 'medium';\n }\n }\n\n protected isRegistrationTab(): boolean {\n return this.activeTab() === 'patient_created';\n }\n\n protected emptyLabel(): string {\n if (this.callIdFilter()) return 'No activities found for this call.';\n switch (this.activeTab()) {\n case 'task_created':\n return 'No tasks created by the AI yet.';\n case 'patient_created':\n return 'No patient registrations yet.';\n default:\n return 'No appointments booked by the AI yet.';\n }\n }\n\n private parseDate(iso: string | null | undefined): Date | null {\n if (!iso) return null;\n const d = new Date(iso);\n return Number.isNaN(d.getTime()) ? null : d;\n }\n\n private formatDay(d: Date): string {\n const midnight = (x: Date) => new Date(x.getFullYear(), x.getMonth(), x.getDate()).getTime();\n const now = new Date();\n const days = Math.round((midnight(d) - midnight(now)) / 86_400_000);\n if (days === 0) return 'Today';\n if (days === 1) return 'Tomorrow';\n if (days === -1) return 'Yesterday';\n return d.toLocaleDateString(\n undefined,\n d.getFullYear() === now.getFullYear()\n ? { weekday: 'short', month: 'short', day: 'numeric' }\n : { month: 'short', day: 'numeric', year: 'numeric' },\n );\n }\n\n private formatClock(d: Date): string {\n return d.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });\n }\n\n private formatDob(iso: string): string {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(iso.trim());\n if (m) return `${m[2]}-${m[3]}-${m[1]}`;\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return iso;\n const mm = String(d.getMonth() + 1).padStart(2, '0');\n const dd = String(d.getDate()).padStart(2, '0');\n return `${mm}-${dd}-${d.getFullYear()}`;\n }\n}\n","<div class=\"activities-page flex h-full min-h-0 min-w-0 max-w-full flex-col overflow-hidden bg-lighter p-base\">\n <div class=\"mb-sm flex shrink-0 flex-col gap-sm\">\n <header class=\"relative z-10 flex items-start justify-between gap-base bg-lighter\">\n <div class=\"grid gap-2xs\">\n <h4>Activities</h4>\n <p class=\"fs-sm text-light\">All activities done by the AI at one place</p>\n </div>\n <div class=\"flex shrink-0 items-center gap-base\">\n <div class=\"relative w-60\">\n <eds-search-field\n inputClass=\"form-input w-full pr-10\"\n placeholder=\"Search here\"\n ariaLabel=\"Search activities\"\n [value]=\"search()\"\n (valueChange)=\"onSearchInput($event)\"\n (enter)=\"applySearch()\" />\n <span class=\"pointer-events-none absolute inset-y-0 right-3 inline-flex items-center text-lighter\">\n <ed-icon name=\"search\" [size]=\"20\" color=\"currentColor\" />\n </span>\n </div>\n </div>\n </header>\n\n @if (callIdFilter(); as callId) {\n <div class=\"flex flex-wrap items-center justify-between gap-sm rounded-lg bg-primary-50 px-base py-sm fs-sm text-body\"\n role=\"status\">\n <span>Showing activities for call <strong class=\"text-dark\">{{ callId }}</strong></span>\n <button\n type=\"button\"\n class=\"cursor-pointer border-none bg-transparent px-0 py-2xs fs-sm text-primary hover:underline\"\n (click)=\"clearCallFilter()\">\n Clear filter\n </button>\n </div>\n }\n\n <nav class=\"flex flex-wrap gap-xs bg-white rounded-md px-xs py-xs\" aria-label=\"Activity type\">\n @for (tab of tabs; track tab.id) {\n <button\n type=\"button\"\n [class]=\"\n activeTab() === tab.id\n ? 'cursor-pointer rounded-full border-none bg-primary-50 px-base py-xs text-primary transition-colors'\n : 'cursor-pointer rounded-full border-none bg-transparent px-base py-xs text-light transition-colors hover:bg-white hover:text-dark'\"\n (click)=\"setTab(tab.id)\">\n {{ tab.label }}\n </button>\n }\n </nav>\n </div>\n\n @if (loadError()) {\n <p class=\"fs-sm text-danger\" role=\"alert\">{{ loadError() }}</p>\n } @else {\n <div class=\"flex min-h-0 min-w-0 max-w-full flex-1 flex-col overflow-hidden rounded-md bg-white\">\n <div class=\"eds-table-scroll min-h-0 min-w-0 flex-1\">\n @if (activeTab() === 'task_created') {\n <table class=\"table-default eds-sticky-table eds-centered-table min-w-5xl w-full\" aria-label=\"Tasks\">\n <thead>\n <tr>\n <th class=\"bg-light\">Priority</th>\n <th class=\"bg-light\">Task</th>\n <th class=\"bg-light\">Assigned by</th>\n <th class=\"bg-light\">Patient / Caller</th>\n <th class=\"bg-light\">Created date</th>\n </tr>\n </thead>\n @if (loading()) {\n <tbody aria-busy=\"true\">\n @for (_ of skeletonRows; track _) {\n <tr>\n <td>\n <div class=\"flex items-center gap-xs py-2xs\">\n <ed-skeleton class=\"h-2.5 w-2.5 !rounded-sm\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-14\"></ed-skeleton>\n </div>\n </td>\n <td>\n <div class=\"grid gap-2xs py-2xs\">\n <ed-skeleton class=\"h-3 w-44\"></ed-skeleton>\n <ed-skeleton class=\"h-5 w-24 !rounded-full\"></ed-skeleton>\n </div>\n </td>\n <td>\n <div class=\"flex items-center gap-xs py-2xs\">\n <ed-skeleton class=\"h-8 w-8 !rounded-full\"></ed-skeleton>\n <div class=\"grid gap-2xs\">\n <ed-skeleton class=\"h-3 w-24\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-16\"></ed-skeleton>\n </div>\n </div>\n </td>\n <td>\n <div class=\"flex items-center gap-xs py-2xs\">\n <ed-skeleton class=\"h-8 w-8 !rounded-md\"></ed-skeleton>\n <div class=\"grid gap-2xs\">\n <ed-skeleton class=\"h-3 w-28\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-36\"></ed-skeleton>\n </div>\n </div>\n </td>\n <td><ed-skeleton class=\"h-3 w-24\"></ed-skeleton></td>\n </tr>\n }\n </tbody>\n } @else {\n <tbody>\n @for (item of items(); track item.id; let i = $index) {\n <tr\n class=\"hover-parent relative cursor-pointer\"\n role=\"button\"\n [attr.tabindex]=\"i === 0 ? 0 : -1\"\n [attr.aria-label]=\"'View task: ' + taskTitle(item)\"\n (click)=\"openTask(item)\"\n (keyup.enter)=\"openTask(item)\"\n >\n <td>\n <div\n class=\"inline-flex items-center gap-xs text-dark\"\n [attr.data-tone]=\"priorityTone(item)\"\n >\n <span\n class=\"activities-page__priority-mark h-2.5 w-2.5 shrink-0 rotate-45 rounded-sm\"\n aria-hidden=\"true\"\n ></span>\n <span class=\"fs-sm capitalize\">{{ priorityLabel(item) }}</span>\n </div>\n </td>\n <td>\n <div class=\"grid min-w-0 gap-2xs\">\n <span\n class=\"inline-block min-w-0 max-w-72 truncate fs-sm font-semibold text-dark\"\n [smartTooltip]=\"taskTitle(item)\"\n [tooltipOnlyWhenTruncated]=\"true\"\n >{{ taskTitle(item) }}</span>\n <span\n class=\"inline-block min-w-0 max-w-72\"\n [smartTooltip]=\"categoryLabel(item)\"\n [tooltipOnlyWhenTruncated]=\"true\"\n >\n <ed-badge-2 variant=\"light\" pill uppercase class=\"max-w-full\">\n <span class=\"block truncate text-dark\">{{ categoryLabel(item) }}</span>\n </ed-badge-2>\n </span>\n </div>\n </td>\n <td>\n <div class=\"flex min-w-0 items-center gap-xs\">\n <ed-avatar shape=\"circle\" size=\"base\" initials=\"AI\" tone=\"brand\" />\n <div class=\"grid min-w-0 gap-2xs\">\n <span class=\"fs-sm font-semibold text-dark\">AI Receptionist</span>\n <span class=\"fs-xs text-light\">Voice agent</span>\n </div>\n </div>\n </td>\n <td>\n <div class=\"flex min-w-0 items-center gap-xs\">\n <ed-avatar\n shape=\"box\"\n size=\"base\"\n [initials]=\"patientInitials(item)\"\n [tone]=\"avatarTone(item.patientId || item.patientName || item.id, i)\"\n />\n <div class=\"grid min-w-0 gap-2xs\">\n <span\n class=\"inline-block min-w-0 max-w-56 truncate fs-sm font-semibold text-dark\"\n [smartTooltip]=\"item.patientName || 'Unknown caller'\"\n [tooltipOnlyWhenTruncated]=\"true\"\n >{{ item.patientName || 'Unknown caller' }}</span>\n @if (patientMeta(item); as meta) {\n <span\n class=\"inline-block min-w-0 max-w-64 truncate fs-xs text-light\"\n [smartTooltip]=\"meta\"\n [tooltipOnlyWhenTruncated]=\"true\"\n >{{ meta }}</span>\n }\n </div>\n </div>\n </td>\n <td class=\"whitespace-nowrap fs-sm text-light\">{{ dueLabel(item) }}</td>\n </tr>\n } @empty {\n <tr class=\"empty-row\">\n <td colspan=\"5\" class=\"py-lg text-center fs-sm text-light\">{{ emptyLabel() }}</td>\n </tr>\n }\n </tbody>\n }\n </table>\n } @else if (activeTab() === 'appointment_booked') {\n <table class=\"table-default eds-sticky-table eds-centered-table min-w-5xl w-full\" aria-label=\"Appointments\">\n <thead>\n <tr>\n <th class=\"bg-light\">Date</th>\n <th class=\"bg-light\">Patient</th>\n <th class=\"bg-light\">Provider</th>\n <th class=\"bg-light text-right\">Insurance</th>\n </tr>\n </thead>\n @if (loading()) {\n <tbody aria-busy=\"true\">\n @for (_ of skeletonRows; track _) {\n <tr>\n <td>\n <div class=\"grid gap-2xs py-2xs\">\n <ed-skeleton class=\"h-3 w-40\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-28\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-20\"></ed-skeleton>\n </div>\n </td>\n <td>\n <div class=\"flex items-center gap-xs py-2xs\">\n <ed-skeleton class=\"h-8 w-8 !rounded-md\"></ed-skeleton>\n <div class=\"grid gap-2xs\">\n <ed-skeleton class=\"h-3 w-28\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-36\"></ed-skeleton>\n </div>\n </div>\n </td>\n <td>\n <div class=\"flex items-center gap-xs py-2xs\">\n <ed-skeleton class=\"h-8 w-8 !rounded-full\"></ed-skeleton>\n <div class=\"grid gap-2xs\">\n <ed-skeleton class=\"h-3 w-24\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-20\"></ed-skeleton>\n </div>\n </div>\n </td>\n <td class=\"text-right\">\n <div class=\"flex items-center justify-end\">\n <ed-skeleton class=\"h-8 w-8 !rounded-full\"></ed-skeleton>\n </div>\n </td>\n </tr>\n }\n </tbody>\n } @else {\n <tbody>\n @for (item of items(); track item.id; let i = $index) {\n <tr\n class=\"hover-parent relative\"\n [class.cursor-pointer]=\"!!item.callId\"\n [attr.role]=\"item.callId ? 'button' : null\"\n [attr.tabindex]=\"item.callId ? (i === 0 ? 0 : -1) : null\"\n [attr.aria-label]=\"item.callId ? 'Open call history' : null\"\n (click)=\"openCallHistory(item.callId, $event)\"\n (keyup.enter)=\"openCallHistory(item.callId)\"\n >\n <td>\n <div class=\"grid min-w-0 gap-2xs\">\n <div class=\"flex flex-wrap items-center gap-2xs\">\n <span class=\"whitespace-nowrap fs-sm font-semibold text-dark\">{{ appointmentTimeRange(item) }}</span>\n @if (durationLabel(item); as duration) {\n <span class=\"inline-flex h-5 items-center rounded bg-light px-2xs fs-xs font-medium text-dark\">\n {{ duration }}\n </span>\n }\n </div>\n <span class=\"fs-sm text-light\">{{ categoryLabel(item) }}</span>\n <span class=\"fs-xs text-light\">{{ appointmentDayLabel(item) }}</span>\n </div>\n </td>\n <td>\n <div class=\"flex min-w-0 items-center gap-xs\">\n <ed-avatar\n shape=\"box\"\n size=\"base\"\n [initials]=\"patientInitials(item)\"\n [tone]=\"avatarTone(item.patientId || item.patientName || item.id, i)\"\n />\n <div class=\"grid min-w-0 gap-2xs\">\n <span\n class=\"inline-block min-w-0 max-w-56 truncate fs-sm font-semibold text-dark\"\n [smartTooltip]=\"item.patientName || 'Unknown patient'\"\n [tooltipOnlyWhenTruncated]=\"true\"\n >{{ item.patientName || 'Unknown patient' }}</span>\n @if (patientMeta(item); as meta) {\n <span\n class=\"inline-block min-w-0 max-w-64 truncate fs-xs text-light\"\n [smartTooltip]=\"meta\"\n [tooltipOnlyWhenTruncated]=\"true\"\n >{{ meta }}</span>\n }\n </div>\n </div>\n </td>\n <td>\n @if (item.providerName) {\n <div class=\"flex min-w-0 items-center gap-xs\">\n <ed-avatar\n shape=\"circle\"\n size=\"base\"\n [initials]=\"providerInitials(item)\"\n [tone]=\"avatarTone(item.providerId || item.providerName, i + 3)\"\n />\n <div class=\"grid min-w-0 gap-2xs\">\n <span\n class=\"inline-block min-w-0 max-w-56 truncate fs-sm font-semibold text-dark\"\n [smartTooltip]=\"item.providerName\"\n [tooltipOnlyWhenTruncated]=\"true\"\n >{{ item.providerName }}</span>\n @if (providerSpecialtyLabel(item); as specialty) {\n <span\n class=\"inline-block min-w-0 max-w-64 truncate fs-xs text-light\"\n [smartTooltip]=\"specialty\"\n [tooltipOnlyWhenTruncated]=\"true\"\n >{{ specialty }}</span>\n }\n </div>\n </div>\n } @else {\n <span class=\"fs-xs text-light\">No provider assigned</span>\n }\n </td>\n <td>\n <div class=\"flex items-center justify-end\">\n <span\n class=\"activities-page__insurance inline-flex h-8 w-8 items-center justify-center rounded-full border border-transparent\"\n [attr.data-state]=\"insuranceState(item)\"\n [title]=\"insuranceTitle(item)\"\n [attr.aria-label]=\"insuranceLabel(item)\"\n >\n <ed-icon [name]=\"insuranceIcon(item)\" [size]=\"18\" />\n </span>\n </div>\n </td>\n </tr>\n } @empty {\n <tr class=\"empty-row\">\n <td colspan=\"4\" class=\"py-lg text-center fs-sm text-light\">{{ emptyLabel() }}</td>\n </tr>\n }\n </tbody>\n }\n </table>\n } @else {\n <table class=\"table-default eds-sticky-table eds-centered-table min-w-5xl w-full\" aria-label=\"Registrations\">\n <thead>\n <tr>\n <th class=\"bg-light\">Date</th>\n <th class=\"bg-light\">Name</th>\n <th class=\"bg-light\">MRN</th>\n <th class=\"bg-light\">Payer</th>\n <th class=\"bg-light text-right\">Insurance</th>\n </tr>\n </thead>\n @if (loading()) {\n <tbody aria-busy=\"true\">\n @for (_ of skeletonRows; track _) {\n <tr>\n <td>\n <div class=\"grid gap-2xs py-2xs\">\n <ed-skeleton class=\"h-3 w-28\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-20\"></ed-skeleton>\n </div>\n </td>\n <td>\n <div class=\"flex items-center gap-xs py-2xs\">\n <ed-skeleton class=\"h-8 w-8 !rounded-md\"></ed-skeleton>\n <div class=\"grid gap-2xs\">\n <ed-skeleton class=\"h-3 w-28\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-36\"></ed-skeleton>\n </div>\n </div>\n </td>\n <td><ed-skeleton class=\"h-3 w-16\"></ed-skeleton></td>\n <td><ed-skeleton class=\"h-3 w-24\"></ed-skeleton></td>\n <td class=\"text-right\">\n <div class=\"flex items-center justify-end\">\n <ed-skeleton class=\"h-8 w-8 !rounded-full\"></ed-skeleton>\n </div>\n </td>\n </tr>\n }\n </tbody>\n } @else {\n <tbody>\n @for (item of items(); track item.id; let i = $index) {\n <tr\n class=\"hover-parent relative cursor-pointer\"\n role=\"button\"\n [attr.tabindex]=\"i === 0 ? 0 : -1\"\n [attr.aria-label]=\"'View patient: ' + (item.patientName || 'Unknown patient')\"\n (click)=\"openPatient(item)\"\n (keyup.enter)=\"openPatient(item)\"\n >\n <td>\n <div class=\"grid min-w-0 gap-2xs\">\n <span class=\"whitespace-nowrap fs-sm font-semibold text-dark\">{{ timestampLabel(item) }}</span>\n <span class=\"fs-sm text-light\">{{ categoryLabel(item) }}</span>\n </div>\n </td>\n <td>\n <div class=\"flex min-w-0 items-center gap-xs\">\n <ed-avatar\n shape=\"box\"\n size=\"base\"\n [initials]=\"patientInitials(item)\"\n [tone]=\"avatarTone(item.patientId || item.patientName || item.id, i)\"\n />\n <div class=\"grid min-w-0 gap-2xs\">\n <span\n class=\"inline-block min-w-0 max-w-56 truncate fs-sm font-semibold text-dark\"\n [smartTooltip]=\"item.patientName || 'Unknown patient'\"\n [tooltipOnlyWhenTruncated]=\"true\"\n >{{ item.patientName || 'Unknown patient' }}</span>\n @if (patientMeta(item); as meta) {\n <span\n class=\"inline-block min-w-0 max-w-64 truncate fs-xs text-light\"\n [smartTooltip]=\"meta\"\n [tooltipOnlyWhenTruncated]=\"true\"\n >{{ meta }}</span>\n }\n </div>\n </div>\n </td>\n <td class=\"fs-sm text-body\">{{ displayMrn(item) }}</td>\n <td>\n @if (insuranceState(item) === 'covered') {\n <span class=\"fs-sm text-dark\">{{ item.insuranceName || 'Insured' }}</span>\n } @else {\n <span class=\"fs-sm text-dark\">Add Insurance</span>\n }\n </td>\n <td>\n <div class=\"flex items-center justify-end\">\n <span\n class=\"activities-page__insurance inline-flex h-8 w-8 items-center justify-center rounded-full border border-transparent\"\n [attr.data-state]=\"insuranceState(item)\"\n [title]=\"insuranceTitle(item)\"\n [attr.aria-label]=\"insuranceLabel(item)\"\n >\n <ed-icon [name]=\"insuranceIcon(item)\" [size]=\"18\" />\n </span>\n </div>\n </td>\n </tr>\n } @empty {\n <tr class=\"empty-row\">\n <td colspan=\"5\" class=\"py-lg text-center fs-sm text-light\">{{ emptyLabel() }}</td>\n </tr>\n }\n </tbody>\n }\n </table>\n }\n </div>\n\n @if (!loading() && total() > pageSize) {\n <footer class=\"mt-sm flex shrink-0 flex-wrap items-center justify-between gap-sm border-t border-light pt-sm\">\n <span class=\"fs-sm text-light\">\n Page {{ page() }} of {{ totalPages() }} · {{ total() }} total\n </span>\n <div class=\"flex gap-xs\">\n <ed-button\n variant=\"secondary\"\n outline\n size=\"sm\"\n [disabled]=\"page() <= 1\"\n (click$)=\"prevPage()\"\n >\n Previous\n </ed-button>\n <ed-button\n variant=\"secondary\"\n outline\n size=\"sm\"\n [disabled]=\"page() >= totalPages()\"\n (click$)=\"nextPage()\"\n >\n Next\n </ed-button>\n </div>\n </footer>\n }\n </div>\n }\n</div>\n\n@if (selectedTask(); as task) {\n <eds-task-detail-drawer\n [task]=\"task\"\n (closed)=\"closeTaskDrawer()\"\n (statusChange)=\"onTaskStatusChange($event)\"\n />\n}\n\n@if (selectedPatient(); as patient) {\n <eds-patient-profile-drawer\n [patient]=\"patient\"\n (closed)=\"closePatientDrawer()\"\n />\n}\n"],"names":["calcTotalPages"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { inject, signal, computed, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
|
-
import { A as AiReceptionistApiService, T as ToastService,
|
|
3
|
+
import { A as AiReceptionistApiService, T as ToastService, t as triggerBlobDownload, I as IconComponent, f as EdButtonComponent, p as EdIconButtonComponent, g as EdSkeletonComponent } from './edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-CJ1L6QeE.mjs';
|
|
4
4
|
|
|
5
5
|
/** Figma pastel palette for horizontal reason bars */
|
|
6
6
|
const REASON_COLORS = ['#DAB2FF', '#A3B3FF', '#FFA1AD', '#74D4FF', 'rgba(255,32,86,0.2)', '#BBF451', '#FFD230'];
|
|
@@ -432,4 +432,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
|
|
|
432
432
|
}] });
|
|
433
433
|
|
|
434
434
|
export { AnalyticsPageComponent };
|
|
435
|
-
//# sourceMappingURL=edvak99-voice-receptionist-widget-analytics-page.component-
|
|
435
|
+
//# sourceMappingURL=edvak99-voice-receptionist-widget-analytics-page.component-B25yZJZz.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edvak99-voice-receptionist-widget-analytics-page.component-CmImX5FN.mjs","sources":["../../../src/lib/pages/analytics-page/analytics-page.component.ts","../../../src/lib/pages/analytics-page/analytics-page.component.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, inject, OnInit, signal } from '@angular/core';\n\nimport {\n AnalyticsData,\n AnalyticsKpiCard,\n AnalyticsQuery,\n AnalyticsVolumePoint,\n} from '../../models/ai-receptionist.types';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { ToastService } from '../../shared/toast.service';\nimport { triggerBlobDownload } from '../../utils/csv-download.util';\nimport { EdButtonComponent } from '../../ui/ed-button.component';\nimport { EdSkeletonComponent } from '../../ui/ed-skeleton.component';\n\nimport { IconComponent } from '../../ui/ed-icon.component';\nimport { EdIconButtonComponent } from '../../ui/ed-icon-button.component';\n\n/** Figma pastel palette for horizontal reason bars */\nconst REASON_COLORS = ['#DAB2FF', '#A3B3FF', '#FFA1AD', '#74D4FF', 'rgba(255,32,86,0.2)', '#BBF451', '#FFD230'];\n/** Figma pastel palette for transfer / stuck bars */\nconst STUCK_COLORS = ['#DAB2FF', '#A3B3FF', '#74D4FF', '#FFD230'];\n\nconst OUTCOME_TEXT_COLORS = ['#8200DB', '#2162F0', '#DB0C15'];\nconst OUTCOME_FALLBACK_COLORS = ['#DAB2FF', '#A3B3FF', '#FFA1AD'];\n\ninterface DistributionSegVm {\n label: string;\n value: number;\n color: string;\n textColor: string;\n width: number;\n tooltip: string;\n callsText: string;\n}\n\ninterface SecondaryKpiVm {\n label: string;\n value: string;\n sub?: string;\n delta?: string;\n tone: string;\n trendIcon: string;\n}\n\ninterface HbarRowVm {\n label: string;\n value: number;\n widthPct: number;\n color: string;\n tooltip: string;\n delayMs: number;\n}\n\ninterface PeakRowVm {\n hour: number;\n label: string;\n heightPct: number;\n tooltip: string;\n showLabel: boolean;\n delayMs: number;\n}\n\ninterface VolumePointVm {\n trackKey: string;\n tooltip: string;\n}\n\n@Component({\n selector: 'eds-analytics-page',\n imports: [IconComponent, EdButtonComponent, EdIconButtonComponent, EdSkeletonComponent],\n templateUrl: './analytics-page.component.html',\n styleUrl: './analytics-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { class: 'block h-full min-h-0' },\n})\nexport class AnalyticsPageComponent implements OnInit {\n private readonly api = inject(AiReceptionistApiService);\n private readonly toast = inject(ToastService);\n\n protected readonly data = signal<AnalyticsData | null>(null);\n protected readonly range = signal('30d');\n protected readonly startDate = signal('');\n protected readonly endDate = signal('');\n protected readonly loading = signal(true);\n protected readonly exporting = signal(false);\n protected readonly kpiSkeletonRows = [0, 1, 2, 3] as const;\n protected readonly legendSkeletonRows = [0, 1, 2] as const;\n protected readonly chartRowSkeletonRows = [0, 1, 2, 3, 4] as const;\n protected readonly peakSkeletonRows = [\n 'h-16',\n 'h-24',\n 'h-20',\n 'h-32',\n 'h-28',\n 'h-36',\n 'h-24',\n 'h-40',\n 'h-28',\n 'h-20',\n 'h-16',\n 'h-12',\n ] as const;\n protected readonly chartsReady = signal(false);\n protected readonly hoveredVolume = signal<number | null>(null);\n protected readonly filtersOpen = signal(false);\n\n protected readonly ranges = [\n { id: '7d', label: '7 days' },\n { id: '30d', label: '30 days' },\n { id: '90d', label: '90 days' },\n ] as const;\n\n protected readonly impactKpi = computed(() =>\n this.findKpi(/(impact|hours|front-desk|time saved)/i),\n );\n protected readonly resolutionKpi = computed(() =>\n this.findKpi(/(autonomous|resolution)/i),\n );\n\n protected readonly impactSubPrimary = computed(() => {\n const sub = this.impactKpi()?.sub || 'of front-desk time handled by the AI';\n const tilde = sub.indexOf('~');\n if (tilde === -1) return sub;\n return sub.slice(0, tilde).trim();\n });\n\n protected readonly impactSubSecondary = computed(() => {\n const sub = this.impactKpi()?.sub || '';\n const tilde = sub.indexOf('~');\n if (tilde === -1) return null;\n return sub.slice(tilde).trim();\n });\n\n protected readonly resolutionTrend = computed(() => {\n const kpi = this.resolutionKpi();\n if (!kpi?.delta) return null;\n const tone = this.deltaTone(kpi);\n return {\n delta: kpi.delta.replace(/^[+\\s]+/, ''),\n tone,\n icon: tone === 'pos' ? 'growth_chart_trend_up' : 'growth_chart_trend_down',\n };\n });\n\n protected readonly secondaryKpis = computed((): SecondaryKpiVm[] => {\n const cards = this.data()?.kpiCards ?? [];\n const preferred = [\n /appointment/i,\n /task/i,\n /patient|registr/i,\n /calls?\\s*handled|total\\s*calls|^calls$/i,\n ];\n const picked: AnalyticsKpiCard[] = [];\n for (const re of preferred) {\n const hit = cards.find((c) => re.test(c.label) && !picked.includes(c));\n if (hit) picked.push(hit);\n }\n const list =\n picked.length >= 4\n ? picked.slice(0, 4)\n : [\n ...picked,\n ...cards.filter(\n (c) =>\n !picked.includes(c) &&\n !/(impact|hours|front-desk|autonomous|resolution)/i.test(c.label),\n ),\n ].slice(0, 4);\n\n return list.map((kpi) => {\n const tone = this.deltaTone(kpi);\n return {\n label: kpi.label,\n value: kpi.value,\n sub: kpi.sub,\n delta: kpi.delta ? kpi.delta.replace(/^[+\\s]+/, '') : undefined,\n tone,\n trendIcon: tone === 'pos' ? 'growth_chart_trend_up' : 'growth_chart_trend_down',\n };\n });\n });\n\n protected readonly distribution = computed((): DistributionSegVm[] => {\n const outcomes = this.data()?.outcomes ?? [];\n const total = outcomes.reduce((s, o) => s + o.value, 0) || 1;\n return outcomes.map((o, i) => {\n const width = (o.value / total) * 100;\n const calls = this.estimatedCalls(o.value);\n return {\n ...o,\n color: o.color || OUTCOME_FALLBACK_COLORS[i % OUTCOME_FALLBACK_COLORS.length],\n textColor: OUTCOME_TEXT_COLORS[i % OUTCOME_TEXT_COLORS.length],\n pct: Math.round(width),\n width,\n tooltip: `${o.label}: ${o.value}% (${calls.toLocaleString()} calls)`,\n callsText: `${calls.toLocaleString()} calls`,\n };\n });\n });\n\n protected readonly totalCallsLabel = computed(() => {\n const handled = this.findKpi(/calls?\\s*handled|total\\s*calls|^calls$/i);\n if (handled?.value) return handled.value.includes('Call') ? handled.value : `${handled.value} Calls`;\n const n = this.data()?.kpis.totalCalls;\n return n ? `${n.toLocaleString()} Calls` : 'Calls';\n });\n\n protected readonly directionSub = computed(() => {\n const handled = this.findKpi(/calls?\\s*handled|total\\s*calls|^calls$/i);\n if (handled?.sub && /inbound|outbound/i.test(handled.sub)) return handled.sub;\n return null;\n });\n\n protected readonly volumePoints = computed(() => this.data()?.volume.points ?? []);\n\n protected readonly volumeTotalPath = computed(() => this.buildVolumePath('total'));\n protected readonly volumeInboundPath = computed(() => this.buildVolumePath('inbound'));\n protected readonly volumeOutboundPath = computed(() => this.buildVolumePath('outbound'));\n protected readonly volumeAreaPath = computed(() => {\n const line = this.volumeTotalPath();\n if (!line) return '';\n return `${line} L100,100 L0,100 Z`;\n });\n\n protected readonly volumePointVms = computed((): VolumePointVm[] =>\n this.volumePoints().map((point) => ({\n trackKey: point.date || point.label,\n tooltip: this.volumeTooltip(point),\n })),\n );\n\n protected readonly reasonRows = computed((): HbarRowVm[] => {\n const items = this.data()?.reasons ?? [];\n const max = Math.max(...items.map((i) => i.value), 1);\n return items.map((item, i) => ({\n label: item.label,\n value: item.value,\n widthPct: (item.value / max) * 100,\n color: REASON_COLORS[i % REASON_COLORS.length],\n tooltip: `${item.label}: ${item.value}%`,\n delayMs: i * 40,\n }));\n });\n\n protected readonly transferRows = computed((): HbarRowVm[] => {\n const items = this.data()?.transfers ?? [];\n const max = Math.max(...items.map((i) => i.value), 1);\n return items.map((item, i) => ({\n label: item.label,\n value: item.value,\n widthPct: (item.value / max) * 100,\n color: STUCK_COLORS[i % STUCK_COLORS.length],\n tooltip: `${item.label}: ${item.value}%`,\n delayMs: i * 40,\n }));\n });\n\n protected readonly peakRows = computed((): PeakRowVm[] => {\n const points = this.data()?.peakHours.points ?? [];\n const max = Math.max(...points.map((p) => p.count), 1);\n return points.map((point, i) => ({\n hour: point.hour,\n label: point.label,\n heightPct: point.count <= 0 ? 0 : (point.count / max) * 100,\n tooltip: `${point.label}: ${point.count} call${point.count === 1 ? '' : 's'}`,\n showLabel: this.showPeakAxisLabel(i, points.length),\n delayMs: i * 18,\n }));\n });\n\n /** Human date span for the selected analytics window (month + year included). */\n protected readonly periodLabel = computed(() => {\n const customStart = this.parseIsoDate(this.startDate());\n const customEnd = this.parseIsoDate(this.endDate());\n if (customStart && customEnd) return this.formatPeriodRange(customStart, customEnd);\n\n const vol = this.data()?.volume;\n const start =\n this.parseIsoDate(vol?.startDate) ?? this.parseIsoDate(vol?.points?.[0]?.date) ?? null;\n const end =\n this.parseIsoDate(vol?.endDate) ??\n this.parseIsoDate(vol?.points?.[vol.points.length - 1]?.date) ??\n null;\n if (start && end) return this.formatPeriodRange(start, end);\n\n const days = this.range() === '7d' ? 7 : this.range() === '90d' ? 90 : 30;\n const endD = new Date();\n const startD = new Date();\n startD.setDate(endD.getDate() - (days - 1));\n return this.formatPeriodRange(startD, endD);\n });\n\n protected readonly volumeAxisLabels = computed(() => {\n const points = this.volumePoints();\n return points.map((p, i) => this.volumeAxisLabel(p, i, points.length));\n });\n\n ngOnInit(): void {\n this.applyPresetDates(this.range());\n this.load();\n }\n\n protected toggleFilters(event?: Event): void {\n event?.stopPropagation();\n this.filtersOpen.update((open) => !open);\n }\n\n protected closeFilters(): void {\n this.filtersOpen.set(false);\n }\n\n protected onFiltersDocClick(event: MouseEvent): void {\n const target = event.target as HTMLElement | null;\n if (!target?.closest('[data-analytics-filters]')) {\n this.filtersOpen.set(false);\n }\n }\n\n protected setRange(id: string): void {\n this.range.set(id);\n this.applyPresetDates(id);\n }\n\n protected onStartDate(value: string): void {\n this.startDate.set(value);\n this.range.set('custom');\n }\n\n protected onEndDate(value: string): void {\n this.endDate.set(value);\n this.range.set('custom');\n }\n\n protected applyFilters(): void {\n this.load();\n }\n\n protected resetFilters(): void {\n this.range.set('30d');\n this.applyPresetDates('30d');\n this.load();\n }\n\n protected exportCsv(): void {\n if (this.exporting()) return;\n this.exporting.set(true);\n this.api.exportAnalyticsCsv(this.activeFilters()).subscribe({\n next: ({ blob, filename }) => {\n triggerBlobDownload(blob, filename);\n this.exporting.set(false);\n this.toast.show('Export downloaded', 'success');\n },\n error: (err: { message?: string }) => {\n this.exporting.set(false);\n this.toast.show(err.message ?? 'Failed to export CSV', 'error');\n },\n });\n }\n\n protected onVolumeEnter(index: number): void {\n this.hoveredVolume.set(index);\n }\n\n protected onVolumeLeave(): void {\n this.hoveredVolume.set(null);\n }\n\n private buildVolumePath(series: 'total' | 'inbound' | 'outbound'): string {\n const points = this.volumePoints();\n if (!points.length) return '';\n const max = Math.max(\n ...points.map((p) => Math.max(p.count, p.inbound ?? 0, p.outbound ?? 0)),\n 1,\n );\n const w = 100;\n const h = 100;\n const step = points.length === 1 ? 0 : w / (points.length - 1);\n return points\n .map((p, i) => {\n const yVal =\n series === 'inbound'\n ? (p.inbound ?? Math.round(p.count * 0.8))\n : series === 'outbound'\n ? (p.outbound ?? Math.round(p.count * 0.2))\n : p.count;\n const x = i * step;\n const y = h - (yVal / max) * h;\n return `${i === 0 ? 'M' : 'L'}${x.toFixed(2)},${y.toFixed(2)}`;\n })\n .join(' ');\n }\n\n private volumeTooltip(point: AnalyticsVolumePoint): string {\n const inbound = point.inbound ?? Math.round(point.count * 0.8);\n const outbound = point.outbound ?? Math.max(0, point.count - inbound);\n const headline = this.volumePointHeadline(point);\n return `${headline}\\nTotal ${point.count} · In ${inbound} · Out ${outbound}`;\n }\n\n private showPeakAxisLabel(index: number, total: number): boolean {\n if (total <= 12) return true;\n const hour = this.data()?.peakHours.points[index]?.hour;\n if (hour != null && [9, 12, 15, 18, 21].includes(hour)) return true;\n const step = total <= 24 ? 3 : 4;\n return index % step === 0 || index === total - 1;\n }\n\n private volumeAxisLabel(point: AnalyticsVolumePoint, index: number, total: number): string {\n if (/week/i.test(point.day) || /week/i.test(point.label)) {\n const week = point.day || point.label;\n const month = point.date ? this.formatMonthYear(point.date) : '';\n return month ? `${week} · ${month}` : week;\n }\n if (point.date) {\n if (total <= 7) return this.formatChartDate(point.date);\n const step = total <= 14 ? 2 : total <= 31 ? 5 : 7;\n if (index % step !== 0 && index !== total - 1) return '';\n return this.formatChartDate(point.date);\n }\n return point.day || point.label;\n }\n\n private deltaTone(kpi: AnalyticsKpiCard | null | undefined): string {\n if (!kpi?.delta) return 'neutral';\n if (kpi.tone === 'pos' || kpi.tone === 'warn' || kpi.tone === 'neg') return kpi.tone;\n if (/^\\+/.test(kpi.delta.trim())) return 'pos';\n if (/^-|−/.test(kpi.delta.trim())) return 'warn';\n return 'neutral';\n }\n\n private formatChartDate(date: string): string {\n const iso = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(date.trim());\n if (iso) return `${iso[2]}/${iso[3]}`;\n return date;\n }\n\n private estimatedCalls(pct: number): number {\n const total = this.data()?.kpis.totalCalls ?? 0;\n if (!total) return Math.round(pct);\n return Math.round((total * pct) / 100);\n }\n\n private volumePointHeadline(point: AnalyticsVolumePoint): string {\n const raw = (point.label || point.day || '').trim();\n if (/week/i.test(raw) && point.date) {\n return `${raw} · ${this.formatMonthYear(point.date)}`;\n }\n if (point.date) return this.formatFullChartDate(point.date);\n return raw || 'Period';\n }\n\n private formatMonthYear(date: string): string {\n const d = this.parseIsoDate(date);\n if (!d) return '';\n return d.toLocaleDateString(undefined, { month: 'short', year: 'numeric' });\n }\n\n private formatFullChartDate(date: string): string {\n const d = this.parseIsoDate(date);\n if (!d) return this.formatChartDate(date);\n return d.toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n });\n }\n\n private formatPeriodRange(start: Date, end: Date): string {\n const sameYear = start.getFullYear() === end.getFullYear();\n const sameMonth = sameYear && start.getMonth() === end.getMonth();\n if (sameMonth) {\n return `${start.toLocaleDateString(undefined, { month: 'short', day: 'numeric' })} – ${end.getDate()}, ${end.getFullYear()}`;\n }\n if (sameYear) {\n return `${start.toLocaleDateString(undefined, { month: 'short', day: 'numeric' })} – ${end.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' })}`;\n }\n return `${start.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' })} – ${end.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' })}`;\n }\n\n private parseIsoDate(value: string | null | undefined): Date | null {\n if (!value?.trim()) return null;\n const iso = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(value.trim());\n if (iso) {\n const d = new Date(Number(iso[1]), Number(iso[2]) - 1, Number(iso[3]));\n return Number.isNaN(d.getTime()) ? null : d;\n }\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n }\n\n private findKpi(re: RegExp): AnalyticsKpiCard | null {\n return this.data()?.kpiCards.find((c) => re.test(c.label)) ?? null;\n }\n\n private activeFilters(): AnalyticsQuery {\n return {\n range: this.range(),\n startDate: this.startDate() || undefined,\n endDate: this.endDate() || undefined,\n };\n }\n\n private applyPresetDates(id: string): void {\n const days = id === '7d' ? 7 : id === '90d' ? 90 : 30;\n const end = new Date();\n const start = new Date();\n start.setDate(end.getDate() - (days - 1));\n this.startDate.set(this.toIsoDate(start));\n this.endDate.set(this.toIsoDate(end));\n }\n\n private toIsoDate(d: Date): string {\n const y = d.getFullYear();\n const m = String(d.getMonth() + 1).padStart(2, '0');\n const day = String(d.getDate()).padStart(2, '0');\n return `${y}-${m}-${day}`;\n }\n\n private load(): void {\n this.loading.set(true);\n this.chartsReady.set(false);\n this.hoveredVolume.set(null);\n this.api.getAnalytics(this.activeFilters()).subscribe(({ data }) => {\n this.data.set(data);\n this.loading.set(false);\n // Next frame so CSS enter animations run after paint.\n requestAnimationFrame(() => this.chartsReady.set(true));\n });\n }\n}\n","<div class=\"flex h-full min-h-0 flex-col overflow-hidden bg-lighter p-base analytics-page\">\n <header class=\"mb-md flex shrink-0 items-start justify-between gap-base\">\n <div class=\"flex flex-col gap-2xs\">\n <h4>Analytics</h4>\n <p class=\"fs-sm text-light\">Call volume, outcomes, and agent performance</p>\n </div>\n <div class=\"flex shrink-0 items-center gap-base\">\n <ed-button\n variant=\"default\"\n outline\n size=\"sm\"\n [disabled]=\"exporting()\"\n (click$)=\"exportCsv()\"\n >\n <ed-icon slot=\"prefix\" name=\"download\" [size]=\"16\" />\n Export\n </ed-button>\n <div\n class=\"relative\"\n data-analytics-filters\n (document:click)=\"onFiltersDocClick($event)\"\n >\n <ed-icon-button\n name=\"filter_alt\"\n label=\"Filters\"\n size=\"md\"\n outline\n allowBubble\n [pressed]=\"filtersOpen()\"\n toggle\n (click$)=\"toggleFilters($event)\"\n />\n @if (filtersOpen()) {\n <div\n class=\"absolute right-0 top-[calc(100%+4px)] z-20 w-[22rem] rounded-md border border-light bg-white shadow-md\"\n role=\"dialog\"\n aria-label=\"Analytics Filter\"\n (click)=\"$event.stopPropagation()\"\n >\n <header class=\"flex items-center justify-between border-b border-light px-base py-sm\">\n <h5 class=\"m-0\">Analytics Filter</h5>\n <ed-icon-button\n name=\"close\"\n size=\"sm\"\n label=\"Close filters\"\n (click$)=\"closeFilters()\"\n />\n </header>\n <section class=\"grid gap-base p-base\">\n <div class=\"grid gap-2xs\">\n <span class=\"fs-xs font-semibold uppercase tracking-wide text-light\">Range</span>\n <div class=\"analytics-page__range-row\" role=\"group\" aria-label=\"Preset range\">\n @for (r of ranges; track r.id) {\n <button\n type=\"button\"\n class=\"analytics-page__range-btn\"\n [class.analytics-page__range-btn--active]=\"range() === r.id\"\n (click)=\"setRange(r.id)\"\n >\n {{ r.label }}\n </button>\n }\n </div>\n </div>\n <div class=\"grid grid-cols-2 gap-sm\">\n <div class=\"grid gap-2xs\">\n <label class=\"fs-sm font-semibold text-light\" for=\"analytics-start-date\">From</label>\n <input\n id=\"analytics-start-date\"\n class=\"form-input is-sm w-full\"\n type=\"date\"\n [value]=\"startDate()\"\n [max]=\"endDate() || undefined\"\n (input)=\"onStartDate($any($event.target).value)\"\n />\n </div>\n <div class=\"grid gap-2xs\">\n <label class=\"fs-sm font-semibold text-light\" for=\"analytics-end-date\">To</label>\n <input\n id=\"analytics-end-date\"\n class=\"form-input is-sm w-full\"\n type=\"date\"\n [value]=\"endDate()\"\n [min]=\"startDate() || undefined\"\n (input)=\"onEndDate($any($event.target).value)\"\n />\n </div>\n </div>\n </section>\n <footer class=\"flex flex-row-reverse flex-wrap items-center gap-sm border-t border-light px-base py-sm\">\n <ed-button\n variant=\"primary\"\n fill\n size=\"sm\"\n (click$)=\"applyFilters(); closeFilters()\"\n >\n Apply\n </ed-button>\n <ed-button\n variant=\"secondary\"\n outline\n size=\"sm\"\n (click$)=\"resetFilters()\"\n >\n Reset\n </ed-button>\n </footer>\n </div>\n }\n </div>\n </div>\n </header>\n\n <div class=\"flex min-h-0 flex-1 flex-col gap-md overflow-y-auto\">\n @if (loading()) {\n <div class=\"flex flex-col gap-base\" aria-busy=\"true\" aria-live=\"polite\">\n <section class=\"flex flex-col gap-base lg:flex-row\" aria-label=\"Key outcomes\">\n <article class=\"flex min-h-36 shrink-0 flex-col gap-sm rounded-md border border-light bg-white p-base lg:w-72\">\n <ed-skeleton class=\"h-3 w-40\"></ed-skeleton>\n <ed-skeleton class=\"h-7 w-28\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-48\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-36\"></ed-skeleton>\n </article>\n <article class=\"flex min-w-0 flex-1 flex-col gap-base overflow-hidden rounded-lg border border-light bg-white p-base lg:flex-row lg:items-center\">\n <div class=\"flex w-full shrink-0 flex-col gap-sm lg:w-52\">\n <ed-skeleton class=\"h-3 w-36\"></ed-skeleton>\n <ed-skeleton class=\"h-7 w-20\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-40\"></ed-skeleton>\n </div>\n <div class=\"flex min-w-0 flex-1 flex-col gap-sm\">\n <div class=\"flex items-center justify-between gap-sm\">\n <ed-skeleton class=\"h-3 w-28\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-24\"></ed-skeleton>\n </div>\n <ed-skeleton class=\"h-8 w-full !rounded-md\"></ed-skeleton>\n <div class=\"flex flex-wrap gap-md\">\n @for (_ of legendSkeletonRows; track _) {\n <div class=\"inline-flex items-center gap-xs\">\n <ed-skeleton class=\"h-4 w-4 !rounded-sm\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-20\"></ed-skeleton>\n </div>\n }\n </div>\n </div>\n </article>\n </section>\n\n <section class=\"grid grid-cols-1 gap-base sm:grid-cols-2 xl:grid-cols-4\" aria-label=\"Activity KPIs\">\n @for (_ of kpiSkeletonRows; track _) {\n <article class=\"flex flex-col gap-2xs rounded-md border border-light bg-white p-base\">\n <ed-skeleton class=\"h-3 w-28\"></ed-skeleton>\n <ed-skeleton class=\"h-6 w-14\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-24\"></ed-skeleton>\n </article>\n }\n </section>\n\n <div class=\"grid grid-cols-1 gap-base md:grid-cols-2\">\n <article class=\"flex flex-col gap-base overflow-hidden rounded-lg border border-light bg-white p-base\">\n <div class=\"flex flex-wrap items-center justify-between gap-base\">\n <h3>Call Volume</h3>\n <div class=\"flex flex-wrap gap-md\">\n @for (_ of legendSkeletonRows; track _) {\n <ed-skeleton class=\"h-3 w-20\"></ed-skeleton>\n }\n </div>\n </div>\n <ed-skeleton class=\"h-60 w-full !rounded-md\"></ed-skeleton>\n </article>\n <article class=\"flex flex-col gap-base overflow-hidden rounded-lg border border-light bg-white p-base\">\n <h3>Top Call Reasons</h3>\n <div class=\"flex flex-col gap-md\">\n @for (_ of chartRowSkeletonRows; track _) {\n <div class=\"grid grid-cols-[minmax(110px,140px)_1fr_42px] items-center gap-sm\">\n <ed-skeleton class=\"h-3 w-20 justify-self-end\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-full !rounded-r-xl\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-8 justify-self-end\"></ed-skeleton>\n </div>\n }\n </div>\n </article>\n <article class=\"flex flex-col gap-base overflow-hidden rounded-lg border border-light bg-white p-base\">\n <h3>Reasons AI got stuck</h3>\n <div class=\"flex flex-col gap-md\">\n @for (_ of chartRowSkeletonRows; track _) {\n <div class=\"grid grid-cols-[minmax(110px,140px)_1fr_42px] items-center gap-sm\">\n <ed-skeleton class=\"h-3 w-20 justify-self-end\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-full !rounded-r-xl\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-8 justify-self-end\"></ed-skeleton>\n </div>\n }\n </div>\n </article>\n <article class=\"flex flex-col gap-base overflow-hidden rounded-lg border border-light bg-white p-base\">\n <h3>Peak Hours</h3>\n <div class=\"flex h-40 items-end gap-xs\">\n @for (heightClass of peakSkeletonRows; track $index) {\n <ed-skeleton [class]=\"'min-w-0 flex-1 !rounded-t-full ' + heightClass\"></ed-skeleton>\n }\n </div>\n </article>\n </div>\n </div>\n } @else {\n @if (data(); as d) {\n <div class=\"analytics-page__body flex flex-col gap-base\" [class.analytics-page__body--ready]=\"chartsReady()\">\n <section class=\"flex flex-col gap-base lg:flex-row\" aria-label=\"Key outcomes\">\n <article\n class=\"analytics-page__impact flex min-h-36 shrink-0 flex-col gap-sm rounded-md p-base text-white lg:w-72\"\n >\n <div class=\"flex items-center gap-2xs\">\n <ed-icon name=\"lightning\" [size]=\"12\" color=\"currentColor\" />\n <span class=\"fs-xs font-semibold uppercase tracking-wide opacity-90\">\n {{ impactKpi()?.label || 'Estimated Impact This Month' }}\n </span>\n </div>\n <strong class=\"fs-lg font-semibold leading-tight\">\n {{ impactKpi()?.value || '—' }}\n </strong>\n <div class=\"flex flex-col gap-2xs opacity-90\">\n <p class=\"m-0 fs-sm\">{{ impactSubPrimary() }}</p>\n @if (impactSubSecondary(); as secondary) {\n <p class=\"m-0 fs-xs opacity-90\">{{ secondary }}</p>\n }\n </div>\n </article>\n\n <article\n class=\"analytics-page__card flex min-w-0 flex-1 flex-col gap-base overflow-hidden rounded-lg bg-white p-base lg:flex-row lg:items-center\"\n >\n <div class=\"flex w-full shrink-0 flex-col gap-sm lg:w-52\">\n <span class=\"fs-xs font-semibold uppercase tracking-wide text-light\">\n {{ resolutionKpi()?.label || 'AI Autonomous Resolution' }}\n </span>\n <strong class=\"fs-lg font-semibold text-dark\">\n {{ resolutionKpi()?.value || '—' }}\n </strong>\n <div class=\"flex flex-wrap items-center gap-xs\">\n <span class=\"fs-sm text-body\">\n {{ resolutionKpi()?.sub || 'without staff intervention' }}\n </span>\n @if (resolutionTrend(); as trend) {\n <span class=\"analytics-page__divider\" aria-hidden=\"true\"></span>\n <span\n class=\"analytics-page__trend inline-flex items-center gap-2xs\"\n [attr.data-tone]=\"trend.tone\"\n >\n <ed-icon [name]=\"trend.icon\" [size]=\"12\" color=\"currentColor\" />\n {{ trend.delta }}\n </span>\n }\n </div>\n </div>\n\n <div class=\"analytics-page__v-divider hidden lg:block\" aria-hidden=\"true\"></div>\n\n <div class=\"analytics-page__distribution flex min-w-0 flex-1 flex-col gap-sm\">\n <div class=\"flex flex-wrap items-center justify-between gap-sm\">\n <strong class=\"fs-sm font-semibold text-body\">{{ totalCallsLabel() }}</strong>\n @if (directionSub(); as dir) {\n <span class=\"fs-sm text-body\">{{ dir }}</span>\n }\n </div>\n <div\n class=\"analytics-page__stack flex h-8 gap-2xs overflow-hidden rounded-md\"\n role=\"img\"\n aria-label=\"Call distribution\"\n >\n @for (seg of distribution(); track seg.label) {\n <span\n class=\"analytics-page__stack-seg relative flex min-w-0 items-center justify-center\"\n [style.flex-grow]=\"seg.width\"\n [style.background]=\"seg.color\"\n [attr.aria-label]=\"seg.tooltip\"\n >\n @if (seg.width >= 8) {\n <span\n class=\"analytics-page__stack-pct fs-xs font-semibold uppercase tracking-wide\"\n [style.color]=\"seg.textColor\"\n >\n {{ seg.value }}%\n </span>\n }\n <span class=\"analytics-page__tooltip\">{{ seg.tooltip }}</span>\n </span>\n }\n </div>\n <ul class=\"m-0 flex list-none flex-wrap gap-x-md gap-y-xs p-0\">\n @for (seg of distribution(); track seg.label) {\n <li class=\"inline-flex items-center gap-xs\">\n <span\n class=\"h-4 w-4 shrink-0 rounded-sm\"\n [style.background]=\"seg.color\"\n ></span>\n <span class=\"inline-flex items-center gap-2xs\">\n <strong class=\"fs-sm font-semibold text-body\">{{ seg.label }}</strong>\n <span class=\"fs-xs text-light\">{{ seg.callsText }}</span>\n </span>\n </li>\n }\n </ul>\n </div>\n </article>\n </section>\n\n <section\n class=\"grid grid-cols-1 gap-base sm:grid-cols-2 xl:grid-cols-4\"\n aria-label=\"Activity KPIs\"\n >\n @for (kpi of secondaryKpis(); track kpi.label) {\n <article class=\"analytics-page__card flex flex-col gap-2xs rounded-md bg-white p-base\">\n <span class=\"fs-xs font-semibold uppercase tracking-wide text-light\">{{ kpi.label }}</span>\n <strong class=\"font-semibold text-dark\">{{ kpi.value }}</strong>\n <div class=\"flex flex-wrap items-center gap-xs\">\n @if (kpi.sub) {\n <span class=\"fs-sm text-body\">{{ kpi.sub }}</span>\n }\n @if (kpi.delta) {\n <span class=\"analytics-page__divider\" aria-hidden=\"true\"></span>\n <span\n class=\"analytics-page__trend inline-flex items-center gap-2xs\"\n [attr.data-tone]=\"kpi.tone\"\n >\n <ed-icon [name]=\"kpi.trendIcon\" [size]=\"12\" color=\"currentColor\" />\n {{ kpi.delta }}\n </span>\n }\n </div>\n </article>\n }\n </section>\n\n <div class=\"grid grid-cols-1 gap-base md:grid-cols-2\">\n <article class=\"flex flex-col gap-md overflow-hidden rounded-lg bg-white p-base analytics-page__chart\">\n <div class=\"flex flex-wrap items-center justify-between gap-base\">\n <h3>Call Volume</h3>\n <ul class=\"m-0 flex list-none flex-wrap items-center justify-end gap-md p-0\">\n <li class=\"inline-flex items-center gap-2xs\">\n <span class=\"analytics-page__dot analytics-page__dot--total h-2 w-2 rounded-full\"></span>\n <span class=\"fs-sm font-semibold text-body\">Total Calls</span>\n </li>\n <li class=\"inline-flex items-center gap-2xs\">\n <span class=\"analytics-page__dot analytics-page__dot--in h-2 w-2 rounded-full\"></span>\n <span class=\"fs-sm font-semibold text-body\">Inbound Calls</span>\n </li>\n <li class=\"inline-flex items-center gap-2xs\">\n <span class=\"analytics-page__dot analytics-page__dot--out h-2 w-2 rounded-full\"></span>\n <span class=\"fs-sm font-semibold text-body\">Outbound Calls</span>\n </li>\n </ul>\n </div>\n <div class=\"analytics-page__line-chart relative h-60\">\n <svg viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\" aria-hidden=\"true\">\n <path class=\"analytics-page__area\" [attr.d]=\"volumeAreaPath()\" />\n <path\n class=\"analytics-page__line analytics-page__line--total\"\n [attr.d]=\"volumeTotalPath()\"\n fill=\"none\"\n />\n <path\n class=\"analytics-page__line analytics-page__line--in\"\n [attr.d]=\"volumeInboundPath()\"\n fill=\"none\"\n />\n <path\n class=\"analytics-page__line analytics-page__line--out\"\n [attr.d]=\"volumeOutboundPath()\"\n fill=\"none\"\n />\n </svg>\n <div\n class=\"analytics-page__volume-hit flex\"\n role=\"list\"\n aria-label=\"Call volume by period\"\n (mouseleave)=\"onVolumeLeave()\"\n >\n @for (point of volumePointVms(); track point.trackKey; let i = $index) {\n <button\n type=\"button\"\n class=\"analytics-page__volume-col relative min-w-0 flex-1 cursor-default border-none bg-transparent p-0\"\n role=\"listitem\"\n [class.analytics-page__volume-col--active]=\"hoveredVolume() === i\"\n [attr.aria-label]=\"point.tooltip\"\n (mouseenter)=\"onVolumeEnter(i)\"\n (focus)=\"onVolumeEnter(i)\"\n (blur)=\"onVolumeLeave()\"\n >\n <span class=\"analytics-page__tooltip analytics-page__tooltip--multiline\">\n {{ point.tooltip }}\n </span>\n </button>\n }\n </div>\n <div class=\"mt-xs flex justify-between gap-2xs\">\n @for (label of volumeAxisLabels(); track $index) {\n <span class=\"flex-1 text-center fs-xs font-semibold uppercase tracking-wide text-light\">\n {{ label }}\n </span>\n }\n </div>\n </div>\n </article>\n\n <article class=\"flex flex-col gap-base overflow-hidden rounded-lg bg-white p-base analytics-page__chart\">\n <h3>Top Call Reasons</h3>\n <div class=\"flex flex-col gap-md\">\n @for (item of reasonRows(); track item.label) {\n <div\n class=\"analytics-page__hbar-row grid items-center gap-sm\"\n [attr.aria-label]=\"item.tooltip\"\n >\n <span class=\"fs-xs font-semibold uppercase tracking-wide text-light text-right\">\n {{ item.label }}\n </span>\n <div class=\"analytics-page__hbar-track relative h-3 overflow-hidden rounded-r-xl\">\n <span\n class=\"analytics-page__hbar-fill block h-full min-w-1 rounded-r-xl\"\n [style.width.%]=\"item.widthPct\"\n [style.background]=\"item.color\"\n [style.animation-delay.ms]=\"item.delayMs\"\n ></span>\n <span class=\"analytics-page__tooltip\">{{ item.tooltip }}</span>\n </div>\n <span class=\"fs-xs font-semibold uppercase tracking-wide text-dark text-right\">\n {{ item.value }}%\n </span>\n </div>\n }\n </div>\n </article>\n\n <article class=\"flex flex-col gap-base overflow-hidden rounded-lg bg-white p-base analytics-page__chart\">\n <h3>Reasons AI got stuck</h3>\n <div class=\"flex flex-col gap-md\">\n @for (item of transferRows(); track item.label) {\n <div\n class=\"analytics-page__hbar-row grid items-center gap-sm\"\n [attr.aria-label]=\"item.tooltip\"\n >\n <span class=\"fs-xs font-semibold uppercase tracking-wide text-light text-right\">\n {{ item.label }}\n </span>\n <div class=\"analytics-page__hbar-track relative h-3 overflow-hidden rounded-r-xl\">\n <span\n class=\"analytics-page__hbar-fill block h-full min-w-1 rounded-r-xl\"\n [style.width.%]=\"item.widthPct\"\n [style.background]=\"item.color\"\n [style.animation-delay.ms]=\"item.delayMs\"\n ></span>\n <span class=\"analytics-page__tooltip\">{{ item.tooltip }}</span>\n </div>\n <span class=\"fs-xs font-semibold uppercase tracking-wide text-dark text-right\">\n {{ item.value }}%\n </span>\n </div>\n }\n </div>\n </article>\n\n <article class=\"flex flex-col gap-md overflow-hidden rounded-lg bg-white p-base analytics-page__chart\">\n <h3>Peak Hours</h3>\n <div class=\"flex flex-col gap-xs\">\n <div class=\"flex h-40 items-end gap-xs\" role=\"list\" aria-label=\"Call volume by hour\">\n @for (point of peakRows(); track point.hour) {\n <div\n class=\"analytics-page__peak-col flex h-full min-w-0 flex-1 flex-col\"\n role=\"listitem\"\n [attr.aria-label]=\"point.tooltip\"\n >\n <div class=\"analytics-page__peak-wrap relative flex min-h-0 flex-1 items-end justify-center\">\n <div\n class=\"analytics-page__peak-bar w-3 min-h-0.5 rounded-t-full\"\n [style.height.%]=\"point.heightPct\"\n [style.animation-delay.ms]=\"point.delayMs\"\n ></div>\n <span class=\"analytics-page__tooltip\">{{ point.tooltip }}</span>\n </div>\n </div>\n }\n </div>\n <div class=\"flex gap-xs\">\n @for (point of peakRows(); track point.hour) {\n <span class=\"min-h-3.5 flex-1 text-center fs-xs font-semibold uppercase tracking-wide text-light\">\n @if (point.showLabel) {\n {{ point.label }}\n }\n </span>\n }\n </div>\n </div>\n </article>\n </div>\n </div>\n }\n }\n </div>\n</div>\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"edvak99-voice-receptionist-widget-analytics-page.component-B25yZJZz.mjs","sources":["../../../src/lib/pages/analytics-page/analytics-page.component.ts","../../../src/lib/pages/analytics-page/analytics-page.component.html"],"sourcesContent":["import { ChangeDetectionStrategy, Component, computed, inject, OnInit, signal } from '@angular/core';\n\nimport {\n AnalyticsData,\n AnalyticsKpiCard,\n AnalyticsQuery,\n AnalyticsVolumePoint,\n} from '../../models/ai-receptionist.types';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { ToastService } from '../../shared/toast.service';\nimport { triggerBlobDownload } from '../../utils/csv-download.util';\nimport { EdButtonComponent } from '../../ui/ed-button.component';\nimport { EdSkeletonComponent } from '../../ui/ed-skeleton.component';\n\nimport { IconComponent } from '../../ui/ed-icon.component';\nimport { EdIconButtonComponent } from '../../ui/ed-icon-button.component';\n\n/** Figma pastel palette for horizontal reason bars */\nconst REASON_COLORS = ['#DAB2FF', '#A3B3FF', '#FFA1AD', '#74D4FF', 'rgba(255,32,86,0.2)', '#BBF451', '#FFD230'];\n/** Figma pastel palette for transfer / stuck bars */\nconst STUCK_COLORS = ['#DAB2FF', '#A3B3FF', '#74D4FF', '#FFD230'];\n\nconst OUTCOME_TEXT_COLORS = ['#8200DB', '#2162F0', '#DB0C15'];\nconst OUTCOME_FALLBACK_COLORS = ['#DAB2FF', '#A3B3FF', '#FFA1AD'];\n\ninterface DistributionSegVm {\n label: string;\n value: number;\n color: string;\n textColor: string;\n width: number;\n tooltip: string;\n callsText: string;\n}\n\ninterface SecondaryKpiVm {\n label: string;\n value: string;\n sub?: string;\n delta?: string;\n tone: string;\n trendIcon: string;\n}\n\ninterface HbarRowVm {\n label: string;\n value: number;\n widthPct: number;\n color: string;\n tooltip: string;\n delayMs: number;\n}\n\ninterface PeakRowVm {\n hour: number;\n label: string;\n heightPct: number;\n tooltip: string;\n showLabel: boolean;\n delayMs: number;\n}\n\ninterface VolumePointVm {\n trackKey: string;\n tooltip: string;\n}\n\n@Component({\n selector: 'eds-analytics-page',\n imports: [IconComponent, EdButtonComponent, EdIconButtonComponent, EdSkeletonComponent],\n templateUrl: './analytics-page.component.html',\n styleUrl: './analytics-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: { class: 'block h-full min-h-0' },\n})\nexport class AnalyticsPageComponent implements OnInit {\n private readonly api = inject(AiReceptionistApiService);\n private readonly toast = inject(ToastService);\n\n protected readonly data = signal<AnalyticsData | null>(null);\n protected readonly range = signal('30d');\n protected readonly startDate = signal('');\n protected readonly endDate = signal('');\n protected readonly loading = signal(true);\n protected readonly exporting = signal(false);\n protected readonly kpiSkeletonRows = [0, 1, 2, 3] as const;\n protected readonly legendSkeletonRows = [0, 1, 2] as const;\n protected readonly chartRowSkeletonRows = [0, 1, 2, 3, 4] as const;\n protected readonly peakSkeletonRows = [\n 'h-16',\n 'h-24',\n 'h-20',\n 'h-32',\n 'h-28',\n 'h-36',\n 'h-24',\n 'h-40',\n 'h-28',\n 'h-20',\n 'h-16',\n 'h-12',\n ] as const;\n protected readonly chartsReady = signal(false);\n protected readonly hoveredVolume = signal<number | null>(null);\n protected readonly filtersOpen = signal(false);\n\n protected readonly ranges = [\n { id: '7d', label: '7 days' },\n { id: '30d', label: '30 days' },\n { id: '90d', label: '90 days' },\n ] as const;\n\n protected readonly impactKpi = computed(() =>\n this.findKpi(/(impact|hours|front-desk|time saved)/i),\n );\n protected readonly resolutionKpi = computed(() =>\n this.findKpi(/(autonomous|resolution)/i),\n );\n\n protected readonly impactSubPrimary = computed(() => {\n const sub = this.impactKpi()?.sub || 'of front-desk time handled by the AI';\n const tilde = sub.indexOf('~');\n if (tilde === -1) return sub;\n return sub.slice(0, tilde).trim();\n });\n\n protected readonly impactSubSecondary = computed(() => {\n const sub = this.impactKpi()?.sub || '';\n const tilde = sub.indexOf('~');\n if (tilde === -1) return null;\n return sub.slice(tilde).trim();\n });\n\n protected readonly resolutionTrend = computed(() => {\n const kpi = this.resolutionKpi();\n if (!kpi?.delta) return null;\n const tone = this.deltaTone(kpi);\n return {\n delta: kpi.delta.replace(/^[+\\s]+/, ''),\n tone,\n icon: tone === 'pos' ? 'growth_chart_trend_up' : 'growth_chart_trend_down',\n };\n });\n\n protected readonly secondaryKpis = computed((): SecondaryKpiVm[] => {\n const cards = this.data()?.kpiCards ?? [];\n const preferred = [\n /appointment/i,\n /task/i,\n /patient|registr/i,\n /calls?\\s*handled|total\\s*calls|^calls$/i,\n ];\n const picked: AnalyticsKpiCard[] = [];\n for (const re of preferred) {\n const hit = cards.find((c) => re.test(c.label) && !picked.includes(c));\n if (hit) picked.push(hit);\n }\n const list =\n picked.length >= 4\n ? picked.slice(0, 4)\n : [\n ...picked,\n ...cards.filter(\n (c) =>\n !picked.includes(c) &&\n !/(impact|hours|front-desk|autonomous|resolution)/i.test(c.label),\n ),\n ].slice(0, 4);\n\n return list.map((kpi) => {\n const tone = this.deltaTone(kpi);\n return {\n label: kpi.label,\n value: kpi.value,\n sub: kpi.sub,\n delta: kpi.delta ? kpi.delta.replace(/^[+\\s]+/, '') : undefined,\n tone,\n trendIcon: tone === 'pos' ? 'growth_chart_trend_up' : 'growth_chart_trend_down',\n };\n });\n });\n\n protected readonly distribution = computed((): DistributionSegVm[] => {\n const outcomes = this.data()?.outcomes ?? [];\n const total = outcomes.reduce((s, o) => s + o.value, 0) || 1;\n return outcomes.map((o, i) => {\n const width = (o.value / total) * 100;\n const calls = this.estimatedCalls(o.value);\n return {\n ...o,\n color: o.color || OUTCOME_FALLBACK_COLORS[i % OUTCOME_FALLBACK_COLORS.length],\n textColor: OUTCOME_TEXT_COLORS[i % OUTCOME_TEXT_COLORS.length],\n pct: Math.round(width),\n width,\n tooltip: `${o.label}: ${o.value}% (${calls.toLocaleString()} calls)`,\n callsText: `${calls.toLocaleString()} calls`,\n };\n });\n });\n\n protected readonly totalCallsLabel = computed(() => {\n const handled = this.findKpi(/calls?\\s*handled|total\\s*calls|^calls$/i);\n if (handled?.value) return handled.value.includes('Call') ? handled.value : `${handled.value} Calls`;\n const n = this.data()?.kpis.totalCalls;\n return n ? `${n.toLocaleString()} Calls` : 'Calls';\n });\n\n protected readonly directionSub = computed(() => {\n const handled = this.findKpi(/calls?\\s*handled|total\\s*calls|^calls$/i);\n if (handled?.sub && /inbound|outbound/i.test(handled.sub)) return handled.sub;\n return null;\n });\n\n protected readonly volumePoints = computed(() => this.data()?.volume.points ?? []);\n\n protected readonly volumeTotalPath = computed(() => this.buildVolumePath('total'));\n protected readonly volumeInboundPath = computed(() => this.buildVolumePath('inbound'));\n protected readonly volumeOutboundPath = computed(() => this.buildVolumePath('outbound'));\n protected readonly volumeAreaPath = computed(() => {\n const line = this.volumeTotalPath();\n if (!line) return '';\n return `${line} L100,100 L0,100 Z`;\n });\n\n protected readonly volumePointVms = computed((): VolumePointVm[] =>\n this.volumePoints().map((point) => ({\n trackKey: point.date || point.label,\n tooltip: this.volumeTooltip(point),\n })),\n );\n\n protected readonly reasonRows = computed((): HbarRowVm[] => {\n const items = this.data()?.reasons ?? [];\n const max = Math.max(...items.map((i) => i.value), 1);\n return items.map((item, i) => ({\n label: item.label,\n value: item.value,\n widthPct: (item.value / max) * 100,\n color: REASON_COLORS[i % REASON_COLORS.length],\n tooltip: `${item.label}: ${item.value}%`,\n delayMs: i * 40,\n }));\n });\n\n protected readonly transferRows = computed((): HbarRowVm[] => {\n const items = this.data()?.transfers ?? [];\n const max = Math.max(...items.map((i) => i.value), 1);\n return items.map((item, i) => ({\n label: item.label,\n value: item.value,\n widthPct: (item.value / max) * 100,\n color: STUCK_COLORS[i % STUCK_COLORS.length],\n tooltip: `${item.label}: ${item.value}%`,\n delayMs: i * 40,\n }));\n });\n\n protected readonly peakRows = computed((): PeakRowVm[] => {\n const points = this.data()?.peakHours.points ?? [];\n const max = Math.max(...points.map((p) => p.count), 1);\n return points.map((point, i) => ({\n hour: point.hour,\n label: point.label,\n heightPct: point.count <= 0 ? 0 : (point.count / max) * 100,\n tooltip: `${point.label}: ${point.count} call${point.count === 1 ? '' : 's'}`,\n showLabel: this.showPeakAxisLabel(i, points.length),\n delayMs: i * 18,\n }));\n });\n\n /** Human date span for the selected analytics window (month + year included). */\n protected readonly periodLabel = computed(() => {\n const customStart = this.parseIsoDate(this.startDate());\n const customEnd = this.parseIsoDate(this.endDate());\n if (customStart && customEnd) return this.formatPeriodRange(customStart, customEnd);\n\n const vol = this.data()?.volume;\n const start =\n this.parseIsoDate(vol?.startDate) ?? this.parseIsoDate(vol?.points?.[0]?.date) ?? null;\n const end =\n this.parseIsoDate(vol?.endDate) ??\n this.parseIsoDate(vol?.points?.[vol.points.length - 1]?.date) ??\n null;\n if (start && end) return this.formatPeriodRange(start, end);\n\n const days = this.range() === '7d' ? 7 : this.range() === '90d' ? 90 : 30;\n const endD = new Date();\n const startD = new Date();\n startD.setDate(endD.getDate() - (days - 1));\n return this.formatPeriodRange(startD, endD);\n });\n\n protected readonly volumeAxisLabels = computed(() => {\n const points = this.volumePoints();\n return points.map((p, i) => this.volumeAxisLabel(p, i, points.length));\n });\n\n ngOnInit(): void {\n this.applyPresetDates(this.range());\n this.load();\n }\n\n protected toggleFilters(event?: Event): void {\n event?.stopPropagation();\n this.filtersOpen.update((open) => !open);\n }\n\n protected closeFilters(): void {\n this.filtersOpen.set(false);\n }\n\n protected onFiltersDocClick(event: MouseEvent): void {\n const target = event.target as HTMLElement | null;\n if (!target?.closest('[data-analytics-filters]')) {\n this.filtersOpen.set(false);\n }\n }\n\n protected setRange(id: string): void {\n this.range.set(id);\n this.applyPresetDates(id);\n }\n\n protected onStartDate(value: string): void {\n this.startDate.set(value);\n this.range.set('custom');\n }\n\n protected onEndDate(value: string): void {\n this.endDate.set(value);\n this.range.set('custom');\n }\n\n protected applyFilters(): void {\n this.load();\n }\n\n protected resetFilters(): void {\n this.range.set('30d');\n this.applyPresetDates('30d');\n this.load();\n }\n\n protected exportCsv(): void {\n if (this.exporting()) return;\n this.exporting.set(true);\n this.api.exportAnalyticsCsv(this.activeFilters()).subscribe({\n next: ({ blob, filename }) => {\n triggerBlobDownload(blob, filename);\n this.exporting.set(false);\n this.toast.show('Export downloaded', 'success');\n },\n error: (err: { message?: string }) => {\n this.exporting.set(false);\n this.toast.show(err.message ?? 'Failed to export CSV', 'error');\n },\n });\n }\n\n protected onVolumeEnter(index: number): void {\n this.hoveredVolume.set(index);\n }\n\n protected onVolumeLeave(): void {\n this.hoveredVolume.set(null);\n }\n\n private buildVolumePath(series: 'total' | 'inbound' | 'outbound'): string {\n const points = this.volumePoints();\n if (!points.length) return '';\n const max = Math.max(\n ...points.map((p) => Math.max(p.count, p.inbound ?? 0, p.outbound ?? 0)),\n 1,\n );\n const w = 100;\n const h = 100;\n const step = points.length === 1 ? 0 : w / (points.length - 1);\n return points\n .map((p, i) => {\n const yVal =\n series === 'inbound'\n ? (p.inbound ?? Math.round(p.count * 0.8))\n : series === 'outbound'\n ? (p.outbound ?? Math.round(p.count * 0.2))\n : p.count;\n const x = i * step;\n const y = h - (yVal / max) * h;\n return `${i === 0 ? 'M' : 'L'}${x.toFixed(2)},${y.toFixed(2)}`;\n })\n .join(' ');\n }\n\n private volumeTooltip(point: AnalyticsVolumePoint): string {\n const inbound = point.inbound ?? Math.round(point.count * 0.8);\n const outbound = point.outbound ?? Math.max(0, point.count - inbound);\n const headline = this.volumePointHeadline(point);\n return `${headline}\\nTotal ${point.count} · In ${inbound} · Out ${outbound}`;\n }\n\n private showPeakAxisLabel(index: number, total: number): boolean {\n if (total <= 12) return true;\n const hour = this.data()?.peakHours.points[index]?.hour;\n if (hour != null && [9, 12, 15, 18, 21].includes(hour)) return true;\n const step = total <= 24 ? 3 : 4;\n return index % step === 0 || index === total - 1;\n }\n\n private volumeAxisLabel(point: AnalyticsVolumePoint, index: number, total: number): string {\n if (/week/i.test(point.day) || /week/i.test(point.label)) {\n const week = point.day || point.label;\n const month = point.date ? this.formatMonthYear(point.date) : '';\n return month ? `${week} · ${month}` : week;\n }\n if (point.date) {\n if (total <= 7) return this.formatChartDate(point.date);\n const step = total <= 14 ? 2 : total <= 31 ? 5 : 7;\n if (index % step !== 0 && index !== total - 1) return '';\n return this.formatChartDate(point.date);\n }\n return point.day || point.label;\n }\n\n private deltaTone(kpi: AnalyticsKpiCard | null | undefined): string {\n if (!kpi?.delta) return 'neutral';\n if (kpi.tone === 'pos' || kpi.tone === 'warn' || kpi.tone === 'neg') return kpi.tone;\n if (/^\\+/.test(kpi.delta.trim())) return 'pos';\n if (/^-|−/.test(kpi.delta.trim())) return 'warn';\n return 'neutral';\n }\n\n private formatChartDate(date: string): string {\n const iso = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(date.trim());\n if (iso) return `${iso[2]}/${iso[3]}`;\n return date;\n }\n\n private estimatedCalls(pct: number): number {\n const total = this.data()?.kpis.totalCalls ?? 0;\n if (!total) return Math.round(pct);\n return Math.round((total * pct) / 100);\n }\n\n private volumePointHeadline(point: AnalyticsVolumePoint): string {\n const raw = (point.label || point.day || '').trim();\n if (/week/i.test(raw) && point.date) {\n return `${raw} · ${this.formatMonthYear(point.date)}`;\n }\n if (point.date) return this.formatFullChartDate(point.date);\n return raw || 'Period';\n }\n\n private formatMonthYear(date: string): string {\n const d = this.parseIsoDate(date);\n if (!d) return '';\n return d.toLocaleDateString(undefined, { month: 'short', year: 'numeric' });\n }\n\n private formatFullChartDate(date: string): string {\n const d = this.parseIsoDate(date);\n if (!d) return this.formatChartDate(date);\n return d.toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n });\n }\n\n private formatPeriodRange(start: Date, end: Date): string {\n const sameYear = start.getFullYear() === end.getFullYear();\n const sameMonth = sameYear && start.getMonth() === end.getMonth();\n if (sameMonth) {\n return `${start.toLocaleDateString(undefined, { month: 'short', day: 'numeric' })} – ${end.getDate()}, ${end.getFullYear()}`;\n }\n if (sameYear) {\n return `${start.toLocaleDateString(undefined, { month: 'short', day: 'numeric' })} – ${end.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' })}`;\n }\n return `${start.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' })} – ${end.toLocaleDateString(undefined, { month: 'short', day: 'numeric', year: 'numeric' })}`;\n }\n\n private parseIsoDate(value: string | null | undefined): Date | null {\n if (!value?.trim()) return null;\n const iso = /^(\\d{4})-(\\d{2})-(\\d{2})/.exec(value.trim());\n if (iso) {\n const d = new Date(Number(iso[1]), Number(iso[2]) - 1, Number(iso[3]));\n return Number.isNaN(d.getTime()) ? null : d;\n }\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? null : d;\n }\n\n private findKpi(re: RegExp): AnalyticsKpiCard | null {\n return this.data()?.kpiCards.find((c) => re.test(c.label)) ?? null;\n }\n\n private activeFilters(): AnalyticsQuery {\n return {\n range: this.range(),\n startDate: this.startDate() || undefined,\n endDate: this.endDate() || undefined,\n };\n }\n\n private applyPresetDates(id: string): void {\n const days = id === '7d' ? 7 : id === '90d' ? 90 : 30;\n const end = new Date();\n const start = new Date();\n start.setDate(end.getDate() - (days - 1));\n this.startDate.set(this.toIsoDate(start));\n this.endDate.set(this.toIsoDate(end));\n }\n\n private toIsoDate(d: Date): string {\n const y = d.getFullYear();\n const m = String(d.getMonth() + 1).padStart(2, '0');\n const day = String(d.getDate()).padStart(2, '0');\n return `${y}-${m}-${day}`;\n }\n\n private load(): void {\n this.loading.set(true);\n this.chartsReady.set(false);\n this.hoveredVolume.set(null);\n this.api.getAnalytics(this.activeFilters()).subscribe(({ data }) => {\n this.data.set(data);\n this.loading.set(false);\n // Next frame so CSS enter animations run after paint.\n requestAnimationFrame(() => this.chartsReady.set(true));\n });\n }\n}\n","<div class=\"flex h-full min-h-0 flex-col overflow-hidden bg-lighter p-base analytics-page\">\n <header class=\"mb-md flex shrink-0 items-start justify-between gap-base\">\n <div class=\"flex flex-col gap-2xs\">\n <h4>Analytics</h4>\n <p class=\"fs-sm text-light\">Call volume, outcomes, and agent performance</p>\n </div>\n <div class=\"flex shrink-0 items-center gap-base\">\n <ed-button\n variant=\"default\"\n outline\n size=\"sm\"\n [disabled]=\"exporting()\"\n (click$)=\"exportCsv()\"\n >\n <ed-icon slot=\"prefix\" name=\"download\" [size]=\"16\" />\n Export\n </ed-button>\n <div\n class=\"relative\"\n data-analytics-filters\n (document:click)=\"onFiltersDocClick($event)\"\n >\n <ed-icon-button\n name=\"filter_alt\"\n label=\"Filters\"\n size=\"md\"\n outline\n allowBubble\n [pressed]=\"filtersOpen()\"\n toggle\n (click$)=\"toggleFilters($event)\"\n />\n @if (filtersOpen()) {\n <div\n class=\"absolute right-0 top-[calc(100%+4px)] z-20 w-[22rem] rounded-md border border-light bg-white shadow-md\"\n role=\"dialog\"\n aria-label=\"Analytics Filter\"\n (click)=\"$event.stopPropagation()\"\n >\n <header class=\"flex items-center justify-between border-b border-light px-base py-sm\">\n <h5 class=\"m-0\">Analytics Filter</h5>\n <ed-icon-button\n name=\"close\"\n size=\"sm\"\n label=\"Close filters\"\n (click$)=\"closeFilters()\"\n />\n </header>\n <section class=\"grid gap-base p-base\">\n <div class=\"grid gap-2xs\">\n <span class=\"fs-xs font-semibold uppercase tracking-wide text-light\">Range</span>\n <div class=\"analytics-page__range-row\" role=\"group\" aria-label=\"Preset range\">\n @for (r of ranges; track r.id) {\n <button\n type=\"button\"\n class=\"analytics-page__range-btn\"\n [class.analytics-page__range-btn--active]=\"range() === r.id\"\n (click)=\"setRange(r.id)\"\n >\n {{ r.label }}\n </button>\n }\n </div>\n </div>\n <div class=\"grid grid-cols-2 gap-sm\">\n <div class=\"grid gap-2xs\">\n <label class=\"fs-sm font-semibold text-light\" for=\"analytics-start-date\">From</label>\n <input\n id=\"analytics-start-date\"\n class=\"form-input is-sm w-full\"\n type=\"date\"\n [value]=\"startDate()\"\n [max]=\"endDate() || undefined\"\n (input)=\"onStartDate($any($event.target).value)\"\n />\n </div>\n <div class=\"grid gap-2xs\">\n <label class=\"fs-sm font-semibold text-light\" for=\"analytics-end-date\">To</label>\n <input\n id=\"analytics-end-date\"\n class=\"form-input is-sm w-full\"\n type=\"date\"\n [value]=\"endDate()\"\n [min]=\"startDate() || undefined\"\n (input)=\"onEndDate($any($event.target).value)\"\n />\n </div>\n </div>\n </section>\n <footer class=\"flex flex-row-reverse flex-wrap items-center gap-sm border-t border-light px-base py-sm\">\n <ed-button\n variant=\"primary\"\n fill\n size=\"sm\"\n (click$)=\"applyFilters(); closeFilters()\"\n >\n Apply\n </ed-button>\n <ed-button\n variant=\"secondary\"\n outline\n size=\"sm\"\n (click$)=\"resetFilters()\"\n >\n Reset\n </ed-button>\n </footer>\n </div>\n }\n </div>\n </div>\n </header>\n\n <div class=\"flex min-h-0 flex-1 flex-col gap-md overflow-y-auto\">\n @if (loading()) {\n <div class=\"flex flex-col gap-base\" aria-busy=\"true\" aria-live=\"polite\">\n <section class=\"flex flex-col gap-base lg:flex-row\" aria-label=\"Key outcomes\">\n <article class=\"flex min-h-36 shrink-0 flex-col gap-sm rounded-md border border-light bg-white p-base lg:w-72\">\n <ed-skeleton class=\"h-3 w-40\"></ed-skeleton>\n <ed-skeleton class=\"h-7 w-28\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-48\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-36\"></ed-skeleton>\n </article>\n <article class=\"flex min-w-0 flex-1 flex-col gap-base overflow-hidden rounded-lg border border-light bg-white p-base lg:flex-row lg:items-center\">\n <div class=\"flex w-full shrink-0 flex-col gap-sm lg:w-52\">\n <ed-skeleton class=\"h-3 w-36\"></ed-skeleton>\n <ed-skeleton class=\"h-7 w-20\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-40\"></ed-skeleton>\n </div>\n <div class=\"flex min-w-0 flex-1 flex-col gap-sm\">\n <div class=\"flex items-center justify-between gap-sm\">\n <ed-skeleton class=\"h-3 w-28\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-24\"></ed-skeleton>\n </div>\n <ed-skeleton class=\"h-8 w-full !rounded-md\"></ed-skeleton>\n <div class=\"flex flex-wrap gap-md\">\n @for (_ of legendSkeletonRows; track _) {\n <div class=\"inline-flex items-center gap-xs\">\n <ed-skeleton class=\"h-4 w-4 !rounded-sm\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-20\"></ed-skeleton>\n </div>\n }\n </div>\n </div>\n </article>\n </section>\n\n <section class=\"grid grid-cols-1 gap-base sm:grid-cols-2 xl:grid-cols-4\" aria-label=\"Activity KPIs\">\n @for (_ of kpiSkeletonRows; track _) {\n <article class=\"flex flex-col gap-2xs rounded-md border border-light bg-white p-base\">\n <ed-skeleton class=\"h-3 w-28\"></ed-skeleton>\n <ed-skeleton class=\"h-6 w-14\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-24\"></ed-skeleton>\n </article>\n }\n </section>\n\n <div class=\"grid grid-cols-1 gap-base md:grid-cols-2\">\n <article class=\"flex flex-col gap-base overflow-hidden rounded-lg border border-light bg-white p-base\">\n <div class=\"flex flex-wrap items-center justify-between gap-base\">\n <h3>Call Volume</h3>\n <div class=\"flex flex-wrap gap-md\">\n @for (_ of legendSkeletonRows; track _) {\n <ed-skeleton class=\"h-3 w-20\"></ed-skeleton>\n }\n </div>\n </div>\n <ed-skeleton class=\"h-60 w-full !rounded-md\"></ed-skeleton>\n </article>\n <article class=\"flex flex-col gap-base overflow-hidden rounded-lg border border-light bg-white p-base\">\n <h3>Top Call Reasons</h3>\n <div class=\"flex flex-col gap-md\">\n @for (_ of chartRowSkeletonRows; track _) {\n <div class=\"grid grid-cols-[minmax(110px,140px)_1fr_42px] items-center gap-sm\">\n <ed-skeleton class=\"h-3 w-20 justify-self-end\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-full !rounded-r-xl\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-8 justify-self-end\"></ed-skeleton>\n </div>\n }\n </div>\n </article>\n <article class=\"flex flex-col gap-base overflow-hidden rounded-lg border border-light bg-white p-base\">\n <h3>Reasons AI got stuck</h3>\n <div class=\"flex flex-col gap-md\">\n @for (_ of chartRowSkeletonRows; track _) {\n <div class=\"grid grid-cols-[minmax(110px,140px)_1fr_42px] items-center gap-sm\">\n <ed-skeleton class=\"h-3 w-20 justify-self-end\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-full !rounded-r-xl\"></ed-skeleton>\n <ed-skeleton class=\"h-3 w-8 justify-self-end\"></ed-skeleton>\n </div>\n }\n </div>\n </article>\n <article class=\"flex flex-col gap-base overflow-hidden rounded-lg border border-light bg-white p-base\">\n <h3>Peak Hours</h3>\n <div class=\"flex h-40 items-end gap-xs\">\n @for (heightClass of peakSkeletonRows; track $index) {\n <ed-skeleton [class]=\"'min-w-0 flex-1 !rounded-t-full ' + heightClass\"></ed-skeleton>\n }\n </div>\n </article>\n </div>\n </div>\n } @else {\n @if (data(); as d) {\n <div class=\"analytics-page__body flex flex-col gap-base\" [class.analytics-page__body--ready]=\"chartsReady()\">\n <section class=\"flex flex-col gap-base lg:flex-row\" aria-label=\"Key outcomes\">\n <article\n class=\"analytics-page__impact flex min-h-36 shrink-0 flex-col gap-sm rounded-md p-base text-white lg:w-72\"\n >\n <div class=\"flex items-center gap-2xs\">\n <ed-icon name=\"lightning\" [size]=\"12\" color=\"currentColor\" />\n <span class=\"fs-xs font-semibold uppercase tracking-wide opacity-90\">\n {{ impactKpi()?.label || 'Estimated Impact This Month' }}\n </span>\n </div>\n <strong class=\"fs-lg font-semibold leading-tight\">\n {{ impactKpi()?.value || '—' }}\n </strong>\n <div class=\"flex flex-col gap-2xs opacity-90\">\n <p class=\"m-0 fs-sm\">{{ impactSubPrimary() }}</p>\n @if (impactSubSecondary(); as secondary) {\n <p class=\"m-0 fs-xs opacity-90\">{{ secondary }}</p>\n }\n </div>\n </article>\n\n <article\n class=\"analytics-page__card flex min-w-0 flex-1 flex-col gap-base overflow-hidden rounded-lg bg-white p-base lg:flex-row lg:items-center\"\n >\n <div class=\"flex w-full shrink-0 flex-col gap-sm lg:w-52\">\n <span class=\"fs-xs font-semibold uppercase tracking-wide text-light\">\n {{ resolutionKpi()?.label || 'AI Autonomous Resolution' }}\n </span>\n <strong class=\"fs-lg font-semibold text-dark\">\n {{ resolutionKpi()?.value || '—' }}\n </strong>\n <div class=\"flex flex-wrap items-center gap-xs\">\n <span class=\"fs-sm text-body\">\n {{ resolutionKpi()?.sub || 'without staff intervention' }}\n </span>\n @if (resolutionTrend(); as trend) {\n <span class=\"analytics-page__divider\" aria-hidden=\"true\"></span>\n <span\n class=\"analytics-page__trend inline-flex items-center gap-2xs\"\n [attr.data-tone]=\"trend.tone\"\n >\n <ed-icon [name]=\"trend.icon\" [size]=\"12\" color=\"currentColor\" />\n {{ trend.delta }}\n </span>\n }\n </div>\n </div>\n\n <div class=\"analytics-page__v-divider hidden lg:block\" aria-hidden=\"true\"></div>\n\n <div class=\"analytics-page__distribution flex min-w-0 flex-1 flex-col gap-sm\">\n <div class=\"flex flex-wrap items-center justify-between gap-sm\">\n <strong class=\"fs-sm font-semibold text-body\">{{ totalCallsLabel() }}</strong>\n @if (directionSub(); as dir) {\n <span class=\"fs-sm text-body\">{{ dir }}</span>\n }\n </div>\n <div\n class=\"analytics-page__stack flex h-8 gap-2xs overflow-hidden rounded-md\"\n role=\"img\"\n aria-label=\"Call distribution\"\n >\n @for (seg of distribution(); track seg.label) {\n <span\n class=\"analytics-page__stack-seg relative flex min-w-0 items-center justify-center\"\n [style.flex-grow]=\"seg.width\"\n [style.background]=\"seg.color\"\n [attr.aria-label]=\"seg.tooltip\"\n >\n @if (seg.width >= 8) {\n <span\n class=\"analytics-page__stack-pct fs-xs font-semibold uppercase tracking-wide\"\n [style.color]=\"seg.textColor\"\n >\n {{ seg.value }}%\n </span>\n }\n <span class=\"analytics-page__tooltip\">{{ seg.tooltip }}</span>\n </span>\n }\n </div>\n <ul class=\"m-0 flex list-none flex-wrap gap-x-md gap-y-xs p-0\">\n @for (seg of distribution(); track seg.label) {\n <li class=\"inline-flex items-center gap-xs\">\n <span\n class=\"h-4 w-4 shrink-0 rounded-sm\"\n [style.background]=\"seg.color\"\n ></span>\n <span class=\"inline-flex items-center gap-2xs\">\n <strong class=\"fs-sm font-semibold text-body\">{{ seg.label }}</strong>\n <span class=\"fs-xs text-light\">{{ seg.callsText }}</span>\n </span>\n </li>\n }\n </ul>\n </div>\n </article>\n </section>\n\n <section\n class=\"grid grid-cols-1 gap-base sm:grid-cols-2 xl:grid-cols-4\"\n aria-label=\"Activity KPIs\"\n >\n @for (kpi of secondaryKpis(); track kpi.label) {\n <article class=\"analytics-page__card flex flex-col gap-2xs rounded-md bg-white p-base\">\n <span class=\"fs-xs font-semibold uppercase tracking-wide text-light\">{{ kpi.label }}</span>\n <strong class=\"font-semibold text-dark\">{{ kpi.value }}</strong>\n <div class=\"flex flex-wrap items-center gap-xs\">\n @if (kpi.sub) {\n <span class=\"fs-sm text-body\">{{ kpi.sub }}</span>\n }\n @if (kpi.delta) {\n <span class=\"analytics-page__divider\" aria-hidden=\"true\"></span>\n <span\n class=\"analytics-page__trend inline-flex items-center gap-2xs\"\n [attr.data-tone]=\"kpi.tone\"\n >\n <ed-icon [name]=\"kpi.trendIcon\" [size]=\"12\" color=\"currentColor\" />\n {{ kpi.delta }}\n </span>\n }\n </div>\n </article>\n }\n </section>\n\n <div class=\"grid grid-cols-1 gap-base md:grid-cols-2\">\n <article class=\"flex flex-col gap-md overflow-hidden rounded-lg bg-white p-base analytics-page__chart\">\n <div class=\"flex flex-wrap items-center justify-between gap-base\">\n <h3>Call Volume</h3>\n <ul class=\"m-0 flex list-none flex-wrap items-center justify-end gap-md p-0\">\n <li class=\"inline-flex items-center gap-2xs\">\n <span class=\"analytics-page__dot analytics-page__dot--total h-2 w-2 rounded-full\"></span>\n <span class=\"fs-sm font-semibold text-body\">Total Calls</span>\n </li>\n <li class=\"inline-flex items-center gap-2xs\">\n <span class=\"analytics-page__dot analytics-page__dot--in h-2 w-2 rounded-full\"></span>\n <span class=\"fs-sm font-semibold text-body\">Inbound Calls</span>\n </li>\n <li class=\"inline-flex items-center gap-2xs\">\n <span class=\"analytics-page__dot analytics-page__dot--out h-2 w-2 rounded-full\"></span>\n <span class=\"fs-sm font-semibold text-body\">Outbound Calls</span>\n </li>\n </ul>\n </div>\n <div class=\"analytics-page__line-chart relative h-60\">\n <svg viewBox=\"0 0 100 100\" preserveAspectRatio=\"none\" aria-hidden=\"true\">\n <path class=\"analytics-page__area\" [attr.d]=\"volumeAreaPath()\" />\n <path\n class=\"analytics-page__line analytics-page__line--total\"\n [attr.d]=\"volumeTotalPath()\"\n fill=\"none\"\n />\n <path\n class=\"analytics-page__line analytics-page__line--in\"\n [attr.d]=\"volumeInboundPath()\"\n fill=\"none\"\n />\n <path\n class=\"analytics-page__line analytics-page__line--out\"\n [attr.d]=\"volumeOutboundPath()\"\n fill=\"none\"\n />\n </svg>\n <div\n class=\"analytics-page__volume-hit flex\"\n role=\"list\"\n aria-label=\"Call volume by period\"\n (mouseleave)=\"onVolumeLeave()\"\n >\n @for (point of volumePointVms(); track point.trackKey; let i = $index) {\n <button\n type=\"button\"\n class=\"analytics-page__volume-col relative min-w-0 flex-1 cursor-default border-none bg-transparent p-0\"\n role=\"listitem\"\n [class.analytics-page__volume-col--active]=\"hoveredVolume() === i\"\n [attr.aria-label]=\"point.tooltip\"\n (mouseenter)=\"onVolumeEnter(i)\"\n (focus)=\"onVolumeEnter(i)\"\n (blur)=\"onVolumeLeave()\"\n >\n <span class=\"analytics-page__tooltip analytics-page__tooltip--multiline\">\n {{ point.tooltip }}\n </span>\n </button>\n }\n </div>\n <div class=\"mt-xs flex justify-between gap-2xs\">\n @for (label of volumeAxisLabels(); track $index) {\n <span class=\"flex-1 text-center fs-xs font-semibold uppercase tracking-wide text-light\">\n {{ label }}\n </span>\n }\n </div>\n </div>\n </article>\n\n <article class=\"flex flex-col gap-base overflow-hidden rounded-lg bg-white p-base analytics-page__chart\">\n <h3>Top Call Reasons</h3>\n <div class=\"flex flex-col gap-md\">\n @for (item of reasonRows(); track item.label) {\n <div\n class=\"analytics-page__hbar-row grid items-center gap-sm\"\n [attr.aria-label]=\"item.tooltip\"\n >\n <span class=\"fs-xs font-semibold uppercase tracking-wide text-light text-right\">\n {{ item.label }}\n </span>\n <div class=\"analytics-page__hbar-track relative h-3 overflow-hidden rounded-r-xl\">\n <span\n class=\"analytics-page__hbar-fill block h-full min-w-1 rounded-r-xl\"\n [style.width.%]=\"item.widthPct\"\n [style.background]=\"item.color\"\n [style.animation-delay.ms]=\"item.delayMs\"\n ></span>\n <span class=\"analytics-page__tooltip\">{{ item.tooltip }}</span>\n </div>\n <span class=\"fs-xs font-semibold uppercase tracking-wide text-dark text-right\">\n {{ item.value }}%\n </span>\n </div>\n }\n </div>\n </article>\n\n <article class=\"flex flex-col gap-base overflow-hidden rounded-lg bg-white p-base analytics-page__chart\">\n <h3>Reasons AI got stuck</h3>\n <div class=\"flex flex-col gap-md\">\n @for (item of transferRows(); track item.label) {\n <div\n class=\"analytics-page__hbar-row grid items-center gap-sm\"\n [attr.aria-label]=\"item.tooltip\"\n >\n <span class=\"fs-xs font-semibold uppercase tracking-wide text-light text-right\">\n {{ item.label }}\n </span>\n <div class=\"analytics-page__hbar-track relative h-3 overflow-hidden rounded-r-xl\">\n <span\n class=\"analytics-page__hbar-fill block h-full min-w-1 rounded-r-xl\"\n [style.width.%]=\"item.widthPct\"\n [style.background]=\"item.color\"\n [style.animation-delay.ms]=\"item.delayMs\"\n ></span>\n <span class=\"analytics-page__tooltip\">{{ item.tooltip }}</span>\n </div>\n <span class=\"fs-xs font-semibold uppercase tracking-wide text-dark text-right\">\n {{ item.value }}%\n </span>\n </div>\n }\n </div>\n </article>\n\n <article class=\"flex flex-col gap-md overflow-hidden rounded-lg bg-white p-base analytics-page__chart\">\n <h3>Peak Hours</h3>\n <div class=\"flex flex-col gap-xs\">\n <div class=\"flex h-40 items-end gap-xs\" role=\"list\" aria-label=\"Call volume by hour\">\n @for (point of peakRows(); track point.hour) {\n <div\n class=\"analytics-page__peak-col flex h-full min-w-0 flex-1 flex-col\"\n role=\"listitem\"\n [attr.aria-label]=\"point.tooltip\"\n >\n <div class=\"analytics-page__peak-wrap relative flex min-h-0 flex-1 items-end justify-center\">\n <div\n class=\"analytics-page__peak-bar w-3 min-h-0.5 rounded-t-full\"\n [style.height.%]=\"point.heightPct\"\n [style.animation-delay.ms]=\"point.delayMs\"\n ></div>\n <span class=\"analytics-page__tooltip\">{{ point.tooltip }}</span>\n </div>\n </div>\n }\n </div>\n <div class=\"flex gap-xs\">\n @for (point of peakRows(); track point.hour) {\n <span class=\"min-h-3.5 flex-1 text-center fs-xs font-semibold uppercase tracking-wide text-light\">\n @if (point.showLabel) {\n {{ point.label }}\n }\n </span>\n }\n </div>\n </div>\n </article>\n </div>\n </div>\n }\n }\n </div>\n</div>\n"],"names":[],"mappings":";;;;AAiBA;AACA,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,qBAAqB,EAAE,SAAS,EAAE,SAAS,CAAC;AAC/G;AACA,MAAM,YAAY,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC;AAEjE,MAAM,mBAAmB,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC;AAC7D,MAAM,uBAAuB,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC;MAoDpD,sBAAsB,CAAA;AARnC,IAAA,WAAA,GAAA;AASmB,QAAA,IAAA,CAAA,GAAG,GAAG,MAAM,CAAC,wBAAwB,CAAC;AACtC,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC;AAE1B,QAAA,IAAA,CAAA,IAAI,GAAG,MAAM,CAAuB,IAAI,CAAC;AACzC,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;AACrB,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,EAAE,CAAC;AACtB,QAAA,IAAA,CAAA,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC;AACpB,QAAA,IAAA,CAAA,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC;AACtB,QAAA,IAAA,CAAA,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC;QACzB,IAAA,CAAA,eAAe,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAU;QACvC,IAAA,CAAA,kBAAkB,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAU;AACvC,QAAA,IAAA,CAAA,oBAAoB,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAU;AAC/C,QAAA,IAAA,CAAA,gBAAgB,GAAG;YACpC,MAAM;YACN,MAAM;YACN,MAAM;YACN,MAAM;YACN,MAAM;YACN,MAAM;YACN,MAAM;YACN,MAAM;YACN,MAAM;YACN,MAAM;YACN,MAAM;YACN,MAAM;SACE;AACS,QAAA,IAAA,CAAA,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC;AAC3B,QAAA,IAAA,CAAA,aAAa,GAAG,MAAM,CAAgB,IAAI,CAAC;AAC3C,QAAA,IAAA,CAAA,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC;AAE3B,QAAA,IAAA,CAAA,MAAM,GAAG;AAC1B,YAAA,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE;AAC7B,YAAA,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE;AAC/B,YAAA,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE;SACvB;AAES,QAAA,IAAA,CAAA,SAAS,GAAG,QAAQ,CAAC,MACtC,IAAI,CAAC,OAAO,CAAC,uCAAuC,CAAC,CACtD;AACkB,QAAA,IAAA,CAAA,aAAa,GAAG,QAAQ,CAAC,MAC1C,IAAI,CAAC,OAAO,CAAC,0BAA0B,CAAC,CACzC;AAEkB,QAAA,IAAA,CAAA,gBAAgB,GAAG,QAAQ,CAAC,MAAK;YAClD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,IAAI,sCAAsC;YAC3E,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC;YAC9B,IAAI,KAAK,KAAK,CAAC,CAAC;AAAE,gBAAA,OAAO,GAAG;YAC5B,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE;AACnC,QAAA,CAAC,CAAC;AAEiB,QAAA,IAAA,CAAA,kBAAkB,GAAG,QAAQ,CAAC,MAAK;YACpD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,EAAE,GAAG,IAAI,EAAE;YACvC,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC;YAC9B,IAAI,KAAK,KAAK,CAAC,CAAC;AAAE,gBAAA,OAAO,IAAI;YAC7B,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE;AAChC,QAAA,CAAC,CAAC;AAEiB,QAAA,IAAA,CAAA,eAAe,GAAG,QAAQ,CAAC,MAAK;AACjD,YAAA,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,EAAE;YAChC,IAAI,CAAC,GAAG,EAAE,KAAK;AAAE,gBAAA,OAAO,IAAI;YAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;YAChC,OAAO;gBACL,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC;gBACvC,IAAI;gBACJ,IAAI,EAAE,IAAI,KAAK,KAAK,GAAG,uBAAuB,GAAG,yBAAyB;aAC3E;AACH,QAAA,CAAC,CAAC;AAEiB,QAAA,IAAA,CAAA,aAAa,GAAG,QAAQ,CAAC,MAAuB;YACjE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,IAAI,EAAE;AACzC,YAAA,MAAM,SAAS,GAAG;gBAChB,cAAc;gBACd,OAAO;gBACP,kBAAkB;gBAClB,yCAAyC;aAC1C;YACD,MAAM,MAAM,GAAuB,EAAE;AACrC,YAAA,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE;AAC1B,gBAAA,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACtE,gBAAA,IAAI,GAAG;AAAE,oBAAA,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;YAC3B;AACA,YAAA,MAAM,IAAI,GACR,MAAM,CAAC,MAAM,IAAI;kBACb,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;AACnB,kBAAE;AACE,oBAAA,GAAG,MAAM;AACT,oBAAA,GAAG,KAAK,CAAC,MAAM,CACb,CAAC,CAAC,KACA,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;wBACnB,CAAC,kDAAkD,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CACpE;AACF,iBAAA,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;AAEnB,YAAA,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,KAAI;gBACtB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC;gBAChC,OAAO;oBACL,KAAK,EAAE,GAAG,CAAC,KAAK;oBAChB,KAAK,EAAE,GAAG,CAAC,KAAK;oBAChB,GAAG,EAAE,GAAG,CAAC,GAAG;oBACZ,KAAK,EAAE,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,GAAG,SAAS;oBAC/D,IAAI;oBACJ,SAAS,EAAE,IAAI,KAAK,KAAK,GAAG,uBAAuB,GAAG,yBAAyB;iBAChF;AACH,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;AAEiB,QAAA,IAAA,CAAA,YAAY,GAAG,QAAQ,CAAC,MAA0B;YACnE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,IAAI,EAAE;YAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC;YAC5D,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAI;gBAC3B,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,IAAI,GAAG;gBACrC,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC;gBAC1C,OAAO;AACL,oBAAA,GAAG,CAAC;AACJ,oBAAA,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,uBAAuB,CAAC,CAAC,GAAG,uBAAuB,CAAC,MAAM,CAAC;oBAC7E,SAAS,EAAE,mBAAmB,CAAC,CAAC,GAAG,mBAAmB,CAAC,MAAM,CAAC;AAC9D,oBAAA,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;oBACtB,KAAK;AACL,oBAAA,OAAO,EAAE,CAAA,EAAG,CAAC,CAAC,KAAK,CAAA,EAAA,EAAK,CAAC,CAAC,KAAK,CAAA,GAAA,EAAM,KAAK,CAAC,cAAc,EAAE,CAAA,OAAA,CAAS;AACpE,oBAAA,SAAS,EAAE,CAAA,EAAG,KAAK,CAAC,cAAc,EAAE,CAAA,MAAA,CAAQ;iBAC7C;AACH,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,CAAC;AAEiB,QAAA,IAAA,CAAA,eAAe,GAAG,QAAQ,CAAC,MAAK;YACjD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,yCAAyC,CAAC;YACvE,IAAI,OAAO,EAAE,KAAK;gBAAE,OAAO,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,GAAG,GAAG,OAAO,CAAC,KAAK,CAAA,MAAA,CAAQ;YACpG,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,UAAU;AACtC,YAAA,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC,cAAc,EAAE,CAAA,MAAA,CAAQ,GAAG,OAAO;AACpD,QAAA,CAAC,CAAC;AAEiB,QAAA,IAAA,CAAA,YAAY,GAAG,QAAQ,CAAC,MAAK;YAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,yCAAyC,CAAC;YACvE,IAAI,OAAO,EAAE,GAAG,IAAI,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;gBAAE,OAAO,OAAO,CAAC,GAAG;AAC7E,YAAA,OAAO,IAAI;AACb,QAAA,CAAC,CAAC;AAEiB,QAAA,IAAA,CAAA,YAAY,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;AAE/D,QAAA,IAAA,CAAA,eAAe,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;AAC/D,QAAA,IAAA,CAAA,iBAAiB,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;AACnE,QAAA,IAAA,CAAA,kBAAkB,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;AACrE,QAAA,IAAA,CAAA,cAAc,GAAG,QAAQ,CAAC,MAAK;AAChD,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,EAAE;AACnC,YAAA,IAAI,CAAC,IAAI;AAAE,gBAAA,OAAO,EAAE;YACpB,OAAO,CAAA,EAAG,IAAI,CAAA,kBAAA,CAAoB;AACpC,QAAA,CAAC,CAAC;AAEiB,QAAA,IAAA,CAAA,cAAc,GAAG,QAAQ,CAAC,MAC3C,IAAI,CAAC,YAAY,EAAE,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM;AAClC,YAAA,QAAQ,EAAE,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,KAAK;AACnC,YAAA,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC;SACnC,CAAC,CAAC,CACJ;AAEkB,QAAA,IAAA,CAAA,UAAU,GAAG,QAAQ,CAAC,MAAkB;YACzD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,OAAO,IAAI,EAAE;YACxC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACrD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM;gBAC7B,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,IAAI,GAAG;gBAClC,KAAK,EAAE,aAAa,CAAC,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC;gBAC9C,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA,EAAA,EAAK,IAAI,CAAC,KAAK,CAAA,CAAA,CAAG;gBACxC,OAAO,EAAE,CAAC,GAAG,EAAE;AAChB,aAAA,CAAC,CAAC;AACL,QAAA,CAAC,CAAC;AAEiB,QAAA,IAAA,CAAA,YAAY,GAAG,QAAQ,CAAC,MAAkB;YAC3D,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,IAAI,EAAE;YAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACrD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM;gBAC7B,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,QAAQ,EAAE,CAAC,IAAI,CAAC,KAAK,GAAG,GAAG,IAAI,GAAG;gBAClC,KAAK,EAAE,YAAY,CAAC,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC;gBAC5C,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAA,EAAA,EAAK,IAAI,CAAC,KAAK,CAAA,CAAA,CAAG;gBACxC,OAAO,EAAE,CAAC,GAAG,EAAE;AAChB,aAAA,CAAC,CAAC;AACL,QAAA,CAAC,CAAC;AAEiB,QAAA,IAAA,CAAA,QAAQ,GAAG,QAAQ,CAAC,MAAkB;AACvD,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,CAAC,MAAM,IAAI,EAAE;YAClD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACtD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM;gBAC/B,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,SAAS,EAAE,KAAK,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,IAAI,GAAG;gBAC3D,OAAO,EAAE,GAAG,KAAK,CAAC,KAAK,CAAA,EAAA,EAAK,KAAK,CAAC,KAAK,CAAA,KAAA,EAAQ,KAAK,CAAC,KAAK,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,CAAA,CAAE;gBAC7E,SAAS,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC;gBACnD,OAAO,EAAE,CAAC,GAAG,EAAE;AAChB,aAAA,CAAC,CAAC;AACL,QAAA,CAAC,CAAC;;AAGiB,QAAA,IAAA,CAAA,WAAW,GAAG,QAAQ,CAAC,MAAK;YAC7C,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YACvD,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YACnD,IAAI,WAAW,IAAI,SAAS;gBAAE,OAAO,IAAI,CAAC,iBAAiB,CAAC,WAAW,EAAE,SAAS,CAAC;YAEnF,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,MAAM;YAC/B,MAAM,KAAK,GACT,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,IAAI;YACxF,MAAM,GAAG,GACP,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC;AAC/B,gBAAA,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC;AAC7D,gBAAA,IAAI;YACN,IAAI,KAAK,IAAI,GAAG;gBAAE,OAAO,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC;AAE3D,YAAA,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,KAAK,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,KAAK,KAAK,GAAG,EAAE,GAAG,EAAE;AACzE,YAAA,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE;AACvB,YAAA,MAAM,MAAM,GAAG,IAAI,IAAI,EAAE;AACzB,YAAA,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC;YAC3C,OAAO,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC;AAC7C,QAAA,CAAC,CAAC;AAEiB,QAAA,IAAA,CAAA,gBAAgB,GAAG,QAAQ,CAAC,MAAK;AAClD,YAAA,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE;YAClC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,IAAI,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;AACxE,QAAA,CAAC,CAAC;AA0OH,IAAA;IAxOC,QAAQ,GAAA;QACN,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QACnC,IAAI,CAAC,IAAI,EAAE;IACb;AAEU,IAAA,aAAa,CAAC,KAAa,EAAA;QACnC,KAAK,EAAE,eAAe,EAAE;AACxB,QAAA,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC;IAC1C;IAEU,YAAY,GAAA;AACpB,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC;IAC7B;AAEU,IAAA,iBAAiB,CAAC,KAAiB,EAAA;AAC3C,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAA4B;QACjD,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,0BAA0B,CAAC,EAAE;AAChD,YAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC;QAC7B;IACF;AAEU,IAAA,QAAQ,CAAC,EAAU,EAAA;AAC3B,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;AAClB,QAAA,IAAI,CAAC,gBAAgB,CAAC,EAAE,CAAC;IAC3B;AAEU,IAAA,WAAW,CAAC,KAAa,EAAA;AACjC,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;AACzB,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC1B;AAEU,IAAA,SAAS,CAAC,KAAa,EAAA;AAC/B,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;AACvB,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;IAC1B;IAEU,YAAY,GAAA;QACpB,IAAI,CAAC,IAAI,EAAE;IACb;IAEU,YAAY,GAAA;AACpB,QAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;AACrB,QAAA,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC;QAC5B,IAAI,CAAC,IAAI,EAAE;IACb;IAEU,SAAS,GAAA;QACjB,IAAI,IAAI,CAAC,SAAS,EAAE;YAAE;AACtB,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC;AACxB,QAAA,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,SAAS,CAAC;YAC1D,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAI;AAC3B,gBAAA,mBAAmB,CAAC,IAAI,EAAE,QAAQ,CAAC;AACnC,gBAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;gBACzB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,EAAE,SAAS,CAAC;YACjD,CAAC;AACD,YAAA,KAAK,EAAE,CAAC,GAAyB,KAAI;AACnC,gBAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC;AACzB,gBAAA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,sBAAsB,EAAE,OAAO,CAAC;YACjE,CAAC;AACF,SAAA,CAAC;IACJ;AAEU,IAAA,aAAa,CAAC,KAAa,EAAA;AACnC,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC;IAC/B;IAEU,aAAa,GAAA;AACrB,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;IAC9B;AAEQ,IAAA,eAAe,CAAC,MAAwC,EAAA;AAC9D,QAAA,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE;QAClC,IAAI,CAAC,MAAM,CAAC,MAAM;AAAE,YAAA,OAAO,EAAE;AAC7B,QAAA,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAClB,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,EACxE,CAAC,CACF;QACD,MAAM,CAAC,GAAG,GAAG;QACb,MAAM,CAAC,GAAG,GAAG;QACb,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;AAC9D,QAAA,OAAO;AACJ,aAAA,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAI;AACZ,YAAA,MAAM,IAAI,GACR,MAAM,KAAK;AACT,mBAAG,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC;kBACvC,MAAM,KAAK;AACX,uBAAG,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC;AAC1C,sBAAE,CAAC,CAAC,KAAK;AACf,YAAA,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI;YAClB,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,IAAI,CAAC;YAC9B,OAAO,CAAA,EAAG,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,GAAG,CAAA,EAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA,CAAA,EAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA,CAAE;AAChE,QAAA,CAAC;aACA,IAAI,CAAC,GAAG,CAAC;IACd;AAEQ,IAAA,aAAa,CAAC,KAA2B,EAAA;AAC/C,QAAA,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC;AAC9D,QAAA,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC;QACrE,MAAM,QAAQ,GAAG,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC;QAChD,OAAO,CAAA,EAAG,QAAQ,CAAA,QAAA,EAAW,KAAK,CAAC,KAAK,CAAA,MAAA,EAAS,OAAO,CAAA,OAAA,EAAU,QAAQ,CAAA,CAAE;IAC9E;IAEQ,iBAAiB,CAAC,KAAa,EAAE,KAAa,EAAA;QACpD,IAAI,KAAK,IAAI,EAAE;AAAE,YAAA,OAAO,IAAI;AAC5B,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI;AACvD,QAAA,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;AAAE,YAAA,OAAO,IAAI;AACnE,QAAA,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC;QAChC,OAAO,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,KAAK,GAAG,CAAC;IAClD;AAEQ,IAAA,eAAe,CAAC,KAA2B,EAAE,KAAa,EAAE,KAAa,EAAA;AAC/E,QAAA,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;YACxD,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,KAAK;YACrC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE;AAChE,YAAA,OAAO,KAAK,GAAG,CAAA,EAAG,IAAI,CAAA,GAAA,EAAM,KAAK,CAAA,CAAE,GAAG,IAAI;QAC5C;AACA,QAAA,IAAI,KAAK,CAAC,IAAI,EAAE;YACd,IAAI,KAAK,IAAI,CAAC;gBAAE,OAAO,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC;YACvD,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE,GAAG,CAAC,GAAG,KAAK,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC;YAClD,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,KAAK,GAAG,CAAC;AAAE,gBAAA,OAAO,EAAE;YACxD,OAAO,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC;QACzC;AACA,QAAA,OAAO,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,KAAK;IACjC;AAEQ,IAAA,SAAS,CAAC,GAAwC,EAAA;QACxD,IAAI,CAAC,GAAG,EAAE,KAAK;AAAE,YAAA,OAAO,SAAS;AACjC,QAAA,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK;YAAE,OAAO,GAAG,CAAC,IAAI;QACpF,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AAAE,YAAA,OAAO,KAAK;QAC9C,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AAAE,YAAA,OAAO,MAAM;AAChD,QAAA,OAAO,SAAS;IAClB;AAEQ,IAAA,eAAe,CAAC,IAAY,EAAA;QAClC,MAAM,GAAG,GAAG,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;AACxD,QAAA,IAAI,GAAG;YAAE,OAAO,CAAA,EAAG,GAAG,CAAC,CAAC,CAAC,CAAA,CAAA,EAAI,GAAG,CAAC,CAAC,CAAC,CAAA,CAAE;AACrC,QAAA,OAAO,IAAI;IACb;AAEQ,IAAA,cAAc,CAAC,GAAW,EAAA;AAChC,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,UAAU,IAAI,CAAC;AAC/C,QAAA,IAAI,CAAC,KAAK;AAAE,YAAA,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;AAClC,QAAA,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,GAAG,IAAI,GAAG,CAAC;IACxC;AAEQ,IAAA,mBAAmB,CAAC,KAA2B,EAAA;AACrD,QAAA,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE;QACnD,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,EAAE;AACnC,YAAA,OAAO,CAAA,EAAG,GAAG,CAAA,GAAA,EAAM,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA,CAAE;QACvD;QACA,IAAI,KAAK,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC;QAC3D,OAAO,GAAG,IAAI,QAAQ;IACxB;AAEQ,IAAA,eAAe,CAAC,IAAY,EAAA;QAClC,MAAM,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;AACjC,QAAA,IAAI,CAAC,CAAC;AAAE,YAAA,OAAO,EAAE;AACjB,QAAA,OAAO,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAC7E;AAEQ,IAAA,mBAAmB,CAAC,IAAY,EAAA;QACtC,MAAM,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;AACjC,QAAA,IAAI,CAAC,CAAC;AAAE,YAAA,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;AACzC,QAAA,OAAO,CAAC,CAAC,kBAAkB,CAAC,SAAS,EAAE;AACrC,YAAA,KAAK,EAAE,OAAO;AACd,YAAA,GAAG,EAAE,SAAS;AACd,YAAA,IAAI,EAAE,SAAS;AAChB,SAAA,CAAC;IACJ;IAEQ,iBAAiB,CAAC,KAAW,EAAE,GAAS,EAAA;QAC9C,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,EAAE,KAAK,GAAG,CAAC,WAAW,EAAE;AAC1D,QAAA,MAAM,SAAS,GAAG,QAAQ,IAAI,KAAK,CAAC,QAAQ,EAAE,KAAK,GAAG,CAAC,QAAQ,EAAE;QACjE,IAAI,SAAS,EAAE;AACb,YAAA,OAAO,CAAA,EAAG,KAAK,CAAC,kBAAkB,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAA,GAAA,EAAM,GAAG,CAAC,OAAO,EAAE,CAAA,EAAA,EAAK,GAAG,CAAC,WAAW,EAAE,CAAA,CAAE;QAC9H;QACA,IAAI,QAAQ,EAAE;AACZ,YAAA,OAAO,GAAG,KAAK,CAAC,kBAAkB,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAA,GAAA,EAAM,GAAG,CAAC,kBAAkB,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE;QACjL;AACA,QAAA,OAAO,GAAG,KAAK,CAAC,kBAAkB,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,MAAM,GAAG,CAAC,kBAAkB,CAAC,SAAS,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,EAAE;IAClM;AAEQ,IAAA,YAAY,CAAC,KAAgC,EAAA;AACnD,QAAA,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE;AAAE,YAAA,OAAO,IAAI;QAC/B,MAAM,GAAG,GAAG,0BAA0B,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QACzD,IAAI,GAAG,EAAE;AACP,YAAA,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACtE,YAAA,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC;QAC7C;AACA,QAAA,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC;AACzB,QAAA,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC;IAC7C;AAEQ,IAAA,OAAO,CAAC,EAAU,EAAA;QACxB,OAAO,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI;IACpE;IAEQ,aAAa,GAAA;QACnB,OAAO;AACL,YAAA,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE;AACnB,YAAA,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,SAAS;AACxC,YAAA,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,SAAS;SACrC;IACH;AAEQ,IAAA,gBAAgB,CAAC,EAAU,EAAA;QACjC,MAAM,IAAI,GAAG,EAAE,KAAK,IAAI,GAAG,CAAC,GAAG,EAAE,KAAK,KAAK,GAAG,EAAE,GAAG,EAAE;AACrD,QAAA,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE;AACtB,QAAA,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE;AACxB,QAAA,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC;AACzC,QAAA,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AACzC,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACvC;AAEQ,IAAA,SAAS,CAAC,CAAO,EAAA;AACvB,QAAA,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;AACzB,QAAA,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;AACnD,QAAA,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;AAChD,QAAA,OAAO,GAAG,CAAC,CAAA,CAAA,EAAI,CAAC,CAAA,CAAA,EAAI,GAAG,EAAE;IAC3B;IAEQ,IAAI,GAAA;AACV,QAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;AACtB,QAAA,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC;AAC3B,QAAA,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;AAC5B,QAAA,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,KAAI;AACjE,YAAA,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;AACnB,YAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;;AAEvB,YAAA,qBAAqB,CAAC,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AACzD,QAAA,CAAC,CAAC;IACJ;+GArcW,sBAAsB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;mGAAtB,sBAAsB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,IAAA,EAAA,EAAA,cAAA,EAAA,sBAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC3EnC,iiuBAifA,EAAA,MAAA,EAAA,CAAA,4pKAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,ED5aY,aAAa,sLAAE,iBAAiB,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,MAAA,EAAA,UAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,MAAA,EAAA,SAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,MAAA,EAAA,MAAA,EAAA,YAAA,EAAA,KAAA,EAAA,QAAA,EAAA,UAAA,EAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,qBAAqB,EAAA,QAAA,EAAA,gBAAA,EAAA,MAAA,EAAA,CAAA,OAAA,EAAA,MAAA,EAAA,MAAA,EAAA,SAAA,EAAA,aAAA,EAAA,OAAA,EAAA,SAAA,EAAA,OAAA,EAAA,QAAA,EAAA,OAAA,EAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,QAAA,EAAA,SAAA,EAAA,IAAA,EAAA,OAAA,EAAA,UAAA,EAAA,OAAA,EAAA,WAAA,EAAA,UAAA,CAAA,EAAA,OAAA,EAAA,CAAA,OAAA,EAAA,OAAA,EAAA,MAAA,EAAA,QAAA,EAAA,QAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,mBAAmB,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,OAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAM3E,sBAAsB,EAAA,UAAA,EAAA,CAAA;kBARlC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,oBAAoB,WACrB,CAAC,aAAa,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,mBAAmB,CAAC,EAAA,eAAA,EAGtE,uBAAuB,CAAC,MAAM,EAAA,IAAA,EACzC,EAAE,KAAK,EAAE,sBAAsB,EAAE,EAAA,QAAA,EAAA,iiuBAAA,EAAA,MAAA,EAAA,CAAA,4pKAAA,CAAA,EAAA;;;;;"}
|