@edvak99/voice-receptionist-widget 1.1.3 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-DT9UKvQO.mjs +307 -0
  2. package/fesm2022/edvak99-voice-receptionist-widget-activities-page.component-DT9UKvQO.mjs.map +1 -0
  3. package/fesm2022/{edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-Dn0GrZ6_.mjs → edvak99-voice-receptionist-widget-ai-receptionist-api.service-48cifVPF.mjs} +1275 -561
  4. package/fesm2022/edvak99-voice-receptionist-widget-ai-receptionist-api.service-48cifVPF.mjs.map +1 -0
  5. package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-C5inEHJw.mjs +278 -0
  6. package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-C5inEHJw.mjs.map +1 -0
  7. package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-sYhM20CE.mjs +418 -0
  8. package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-sYhM20CE.mjs.map +1 -0
  9. package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-DpwajEOE.mjs +194 -0
  10. package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-DpwajEOE.mjs.map +1 -0
  11. package/fesm2022/{edvak99-voice-receptionist-widget-call-recording-player.component-B8_qp7Fe.mjs → edvak99-voice-receptionist-widget-call-recording-player.component-CgkRcFOl.mjs} +3 -2
  12. package/fesm2022/{edvak99-voice-receptionist-widget-call-recording-player.component-B8_qp7Fe.mjs.map → edvak99-voice-receptionist-widget-call-recording-player.component-CgkRcFOl.mjs.map} +1 -1
  13. package/fesm2022/{edvak99-voice-receptionist-widget-call-review.service-Cj2XTeK4.mjs → edvak99-voice-receptionist-widget-call-review.service-CIMcjGKX.mjs} +2 -2
  14. package/fesm2022/{edvak99-voice-receptionist-widget-call-review.service-Cj2XTeK4.mjs.map → edvak99-voice-receptionist-widget-call-review.service-CIMcjGKX.mjs.map} +1 -1
  15. package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-Deh3jPgo.mjs +21 -0
  16. package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-Deh3jPgo.mjs.map +1 -0
  17. package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-CxbO0eDS.mjs +440 -0
  18. package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-CxbO0eDS.mjs.map +1 -0
  19. package/fesm2022/{edvak99-voice-receptionist-widget-eds-elapsed.pipe-BgLsnq6A.mjs → edvak99-voice-receptionist-widget-dashboard-socket.service-BX91r74O.mjs} +5 -21
  20. package/fesm2022/edvak99-voice-receptionist-widget-dashboard-socket.service-BX91r74O.mjs.map +1 -0
  21. package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-CWRiJGfv.mjs +38 -0
  22. package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-CWRiJGfv.mjs.map +1 -0
  23. package/fesm2022/edvak99-voice-receptionist-widget-eds-button.component-Bg5T5BN8.mjs +27 -0
  24. package/fesm2022/edvak99-voice-receptionist-widget-eds-button.component-Bg5T5BN8.mjs.map +1 -0
  25. package/fesm2022/edvak99-voice-receptionist-widget-eds-elapsed.pipe-BFCiJOT3.mjs +22 -0
  26. package/fesm2022/edvak99-voice-receptionist-widget-eds-elapsed.pipe-BFCiJOT3.mjs.map +1 -0
  27. package/fesm2022/{edvak99-voice-receptionist-widget-live-calls-list.service-0kGWO6sh.mjs → edvak99-voice-receptionist-widget-eds-pulse-dot.component-BPY6xN7C.mjs} +15 -5
  28. package/fesm2022/edvak99-voice-receptionist-widget-eds-pulse-dot.component-BPY6xN7C.mjs.map +1 -0
  29. package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-BsBQIS_f.mjs +203 -0
  30. package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-BsBQIS_f.mjs.map +1 -0
  31. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-CaSDMxpV.mjs +81 -0
  32. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-CaSDMxpV.mjs.map +1 -0
  33. package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-Cy3ND-c-.mjs +1070 -0
  34. package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-Cy3ND-c-.mjs.map +1 -0
  35. package/fesm2022/edvak99-voice-receptionist-widget-modal.component-COfi7biN.mjs +48 -0
  36. package/fesm2022/edvak99-voice-receptionist-widget-modal.component-COfi7biN.mjs.map +1 -0
  37. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-Bdh4QfFe.mjs +127 -0
  38. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-Bdh4QfFe.mjs.map +1 -0
  39. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-fHVzpiVk.mjs +268 -0
  40. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-fHVzpiVk.mjs.map +1 -0
  41. package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-Bok64X2q.mjs +968 -0
  42. package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-Bok64X2q.mjs.map +1 -0
  43. package/fesm2022/{edvak99-voice-receptionist-widget-tasks-page.component-DXxjMVUv.mjs → edvak99-voice-receptionist-widget-tasks-page.component-Bb9lPcYi.mjs} +56 -5
  44. package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-Bb9lPcYi.mjs.map +1 -0
  45. package/fesm2022/{edvak99-voice-receptionist-widget-wizard-page.component-C1Z6yC0q.mjs → edvak99-voice-receptionist-widget-wizard-page.component-BZVlWLWh.mjs} +4 -2
  46. package/fesm2022/{edvak99-voice-receptionist-widget-wizard-page.component-C1Z6yC0q.mjs.map → edvak99-voice-receptionist-widget-wizard-page.component-BZVlWLWh.mjs.map} +1 -1
  47. package/fesm2022/edvak99-voice-receptionist-widget.mjs +1 -1
  48. package/lib/components/call-conversation-panel/call-conversation-panel.component.d.ts +9 -6
  49. package/lib/components/call-tasks-panel/call-tasks-panel.component.d.ts +8 -8
  50. package/lib/components/knowledge-test-modal/knowledge-test-modal.component.d.ts +28 -0
  51. package/lib/components/live-transcript-panel/live-transcript-panel.component.d.ts +7 -4
  52. package/lib/components/outbound-dial-modal/outbound-dial-modal.component.d.ts +26 -0
  53. package/lib/layout/eds-module-nav.component.d.ts +0 -3
  54. package/lib/mocks/agent-activity.seed.d.ts +2 -0
  55. package/lib/models/agent-activity.types.d.ts +54 -0
  56. package/lib/models/ai-receptionist.types.d.ts +25 -0
  57. package/lib/models/api-dto.types.d.ts +18 -0
  58. package/lib/models/live-transcript.types.d.ts +2 -1
  59. package/lib/models/outbound-patient.types.d.ts +23 -0
  60. package/lib/models/outbound-purpose.types.d.ts +2 -0
  61. package/lib/models/staff-media.types.d.ts +36 -0
  62. package/lib/pages/activities-page/activities-page.component.d.ts +57 -0
  63. package/lib/pages/analytics-page/analytics-page.component.d.ts +38 -14
  64. package/lib/pages/call-history-detail-page/call-history-detail-page.component.d.ts +2 -3
  65. package/lib/pages/call-history-page/call-history-page.component.d.ts +9 -6
  66. package/lib/pages/dashboard-page/dashboard-page.component.d.ts +12 -8
  67. package/lib/pages/live-calls-page/live-calls-page.component.d.ts +14 -24
  68. package/lib/pages/live-monitor-page/live-monitor-page.component.d.ts +34 -1
  69. package/lib/pages/settings-page/settings-fields.config.d.ts +16 -0
  70. package/lib/pages/settings-page/settings-page.component.d.ts +48 -14
  71. package/lib/services/ai-receptionist-api.mock.d.ts +34 -0
  72. package/lib/services/ai-receptionist-api.service.d.ts +56 -1
  73. package/lib/services/live-transcript.service.d.ts +1 -0
  74. package/lib/services/staff-media.service.d.ts +52 -0
  75. package/lib/ui/eds-avatar.component.d.ts +5 -2
  76. package/lib/ui/eds-button.component.d.ts +1 -1
  77. package/lib/utils/call-history-display.util.d.ts +21 -0
  78. package/lib/utils/outbound-purpose.util.d.ts +19 -0
  79. package/lib/utils/transcript-timing.util.d.ts +1 -1
  80. package/lib/utils/welcome-message.util.d.ts +1 -1
  81. package/package.json +2 -1
  82. package/styles/eds.scss +95 -66
  83. package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-Dsujn5az.mjs +0 -113
  84. package/fesm2022/edvak99-voice-receptionist-widget-analytics-page.component-Dsujn5az.mjs.map +0 -1
  85. package/fesm2022/edvak99-voice-receptionist-widget-audit-page.component-xoLlHj8K.mjs +0 -67
  86. package/fesm2022/edvak99-voice-receptionist-widget-audit-page.component-xoLlHj8K.mjs.map +0 -1
  87. package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-2K9W77As.mjs +0 -316
  88. package/fesm2022/edvak99-voice-receptionist-widget-call-history-detail-page.component-2K9W77As.mjs.map +0 -1
  89. package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-B5AnEjoh.mjs +0 -174
  90. package/fesm2022/edvak99-voice-receptionist-widget-call-history-page.component-B5AnEjoh.mjs.map +0 -1
  91. package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-BgsBCKgZ.mjs +0 -70
  92. package/fesm2022/edvak99-voice-receptionist-widget-call-review.util-BgsBCKgZ.mjs.map +0 -1
  93. package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-BNdnbAVM.mjs +0 -248
  94. package/fesm2022/edvak99-voice-receptionist-widget-dashboard-page.component-BNdnbAVM.mjs.map +0 -1
  95. package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-CbphhP6o.mjs +0 -27
  96. package/fesm2022/edvak99-voice-receptionist-widget-eds-avatar.component-CbphhP6o.mjs.map +0 -1
  97. package/fesm2022/edvak99-voice-receptionist-widget-eds-elapsed.pipe-BgLsnq6A.mjs.map +0 -1
  98. package/fesm2022/edvak99-voice-receptionist-widget-edvak99-voice-receptionist-widget-Dn0GrZ6_.mjs.map +0 -1
  99. package/fesm2022/edvak99-voice-receptionist-widget-knowledge-hub.page-BngGx_Lc.mjs +0 -609
  100. package/fesm2022/edvak99-voice-receptionist-widget-knowledge-hub.page-BngGx_Lc.mjs.map +0 -1
  101. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-list.service-0kGWO6sh.mjs.map +0 -1
  102. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-DfLmK89M.mjs +0 -115
  103. package/fesm2022/edvak99-voice-receptionist-widget-live-calls-page.component-DfLmK89M.mjs.map +0 -1
  104. package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-DNpLFqBw.mjs +0 -574
  105. package/fesm2022/edvak99-voice-receptionist-widget-live-monitor-page.component-DNpLFqBw.mjs.map +0 -1
  106. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-BQECIuJu.mjs +0 -54
  107. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purpose.util-BQECIuJu.mjs.map +0 -1
  108. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-CYSZ832p.mjs +0 -265
  109. package/fesm2022/edvak99-voice-receptionist-widget-outbound-purposes-page.component-CYSZ832p.mjs.map +0 -1
  110. package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-B9nv6wtB.mjs +0 -509
  111. package/fesm2022/edvak99-voice-receptionist-widget-settings-page.component-B9nv6wtB.mjs.map +0 -1
  112. package/fesm2022/edvak99-voice-receptionist-widget-task.util-DdtI0CR3.mjs +0 -52
  113. package/fesm2022/edvak99-voice-receptionist-widget-task.util-DdtI0CR3.mjs.map +0 -1
  114. package/fesm2022/edvak99-voice-receptionist-widget-tasks-page.component-DXxjMVUv.mjs.map +0 -1
  115. package/lib/knowledge/components/faq-empty-state/faq-empty-state.component.d.ts +0 -22
  116. package/lib/knowledge/components/faq-form/faq-form.component.d.ts +0 -27
  117. package/lib/knowledge/components/faq-search-tester/faq-search-tester.component.d.ts +0 -17
  118. package/lib/knowledge/mocks/practice-faq.seed.d.ts +0 -2
  119. package/lib/knowledge/models/practice-faq.model.d.ts +0 -50
  120. package/lib/knowledge/pages/knowledge-hub.page.d.ts +0 -54
  121. package/lib/knowledge/services/practice-faq-api.mock.d.ts +0 -16
  122. package/lib/knowledge/services/practice-faq-api.service.d.ts +0 -26
  123. package/lib/knowledge/utils/faq.util.d.ts +0 -3
  124. package/lib/layout/eds-topbar.component.d.ts +0 -29
  125. package/lib/pages/audit-page/audit-page.component.d.ts +0 -21
  126. package/lib/ui/eds-waveform.component.d.ts +0 -8
@@ -1 +0,0 @@
1
- {"version":3,"file":"edvak99-voice-receptionist-widget-settings-page.component-B9nv6wtB.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/pages/settings-page/tts-voice-presets.ts","../../../projects/voice-receptionist-widget/src/lib/pages/settings-page/settings-fields.config.ts","../../../projects/voice-receptionist-widget/src/lib/pages/settings-page/settings-page.component.ts","../../../projects/voice-receptionist-widget/src/lib/pages/settings-page/settings-page.component.html"],"sourcesContent":["/** Curated ElevenLabs voices — keep in sync with backend `tts-voice-presets.ts`. */\n\nexport interface TtsVoicePreset {\n id: string;\n label: string;\n}\n\nexport const DEFAULT_TTS_VOICE_ID = '7EzWGsX10sAS4c9m9cPf';\n\nexport const TTS_VOICE_PRESETS: readonly TtsVoicePreset[] = [\n {\n id: '7EzWGsX10sAS4c9m9cPf',\n label: 'Jack John – Conversational and Upbeat',\n },\n {\n id: 'NUjosfEayZAdRcDmcHM8',\n label: 'Madison – Cool, Calm & Conversational',\n },\n {\n id: 'gE0owC0H9C8SzfDyIUtB',\n label: 'Ivanna – Sassy, Condescending and Clear',\n },\n {\n id: 'Uc7anshoV8mdBhDnEZEX',\n label: 'Cecily – Clear and Warm',\n },\n] as const;\n","import { AgentSettings } from '../../models/ai-receptionist.types';\nimport { TTS_VOICE_PRESETS } from './tts-voice-presets';\n\nexport type SettingsSection = Exclude<keyof AgentSettings, 'safety' | 'effectiveWelcomeMessage'>;\n\nexport interface SettingsFieldOption {\n value: string;\n label: string;\n}\n\nexport interface SettingsFieldMeta {\n key: string;\n label: string;\n description: string;\n type: 'text' | 'number' | 'boolean' | 'select';\n options?: SettingsFieldOption[];\n readOnly?: boolean;\n}\n\nexport interface SettingsSectionMeta {\n title: string;\n description: string;\n}\n\nexport const SETTINGS_SECTION_META: Record<SettingsSection, SettingsSectionMeta> = {\n general: {\n title: 'General',\n description: 'Practice identity and how the AI introduces itself on calls.',\n },\n phone: {\n title: 'Phone',\n description: 'Inbound routing, after-hours behavior, and ring timing.',\n },\n tasks: {\n title: 'Tasks & follow-ups',\n description: 'When the AI should create staff tasks after a call.',\n },\n scheduling: {\n title: 'Scheduling',\n description: 'Rules for booking and rescheduling appointments.',\n },\n refill: {\n title: 'Medication refills',\n description: 'Refill approval windows and staff review requirements.',\n },\n verify: {\n title: 'Patient verification',\n description: 'Identity checks before accessing chart or scheduling data.',\n },\n escalation: {\n title: 'Escalation',\n description: 'When to offer a human or transfer to reception.',\n },\n outbound: {\n title: 'Outbound calling',\n description: 'Outbound dialer defaults. Purpose templates are managed separately.',\n },\n transcripts: {\n title: 'Transcripts & recording',\n description: 'Retention and PHI handling for call transcripts.',\n },\n advanced: {\n title: 'Advanced',\n description: 'Model and debug options — read-only. Contact Edvak support to change.',\n },\n};\n\n/** Entire sections where every field is read-only (including unknown API fields). */\nexport const READ_ONLY_SECTIONS = new Set<SettingsSection>(['advanced', 'verify']);\n\n/** Settings tabs that stay visible but cannot be selected/edited. */\nexport const DISABLED_SETTINGS_TABS = new Set<SettingsSection>(['verify']);\n\n/** Individual fields locked for compliance, telephony, or core agent identity. */\nexport const READ_ONLY_FIELD_KEYS: ReadonlyArray<{ section: SettingsSection; key: string; reason: string }> = [\n { section: 'general', key: 'practiceName', reason: 'Core practice identity' },\n { section: 'general', key: 'agentName', reason: 'AI agent identity' },\n { section: 'general', key: 'timezone', reason: 'Practice timezone' },\n { section: 'general', key: 'language', reason: 'Default language' },\n { section: 'phone', key: 'mainNumber', reason: 'Inbound phone routing' },\n { section: 'outbound', key: 'callerId', reason: 'Outbound caller ID' },\n { section: 'transcripts', key: 'retainDays', reason: 'Recording retention policy' },\n { section: 'transcripts', key: 'redactPhi', reason: 'PHI redaction policy' },\n { section: 'advanced', key: 'modelVersion', reason: 'Voice AI model profile' },\n { section: 'advanced', key: 'debugMode', reason: 'Debug logging' },\n];\n\nconst READ_ONLY_LOOKUP = new Set(\n READ_ONLY_FIELD_KEYS.map(({ section, key }) => `${section}.${key}`),\n);\n\nexport function isFieldReadOnly(section: SettingsSection, key: string): boolean {\n if (READ_ONLY_SECTIONS.has(section)) return true;\n return READ_ONLY_LOOKUP.has(`${section}.${key}`);\n}\n\nexport function readOnlyFieldReason(section: SettingsSection, key: string): string | undefined {\n return READ_ONLY_FIELD_KEYS.find((f) => f.section === section && f.key === key)?.reason;\n}\n\nexport const SETTINGS_FIELDS: Record<SettingsSection, SettingsFieldMeta[]> = {\n general: [\n {\n key: 'practiceName',\n label: 'Practice name',\n description: 'Spoken on greetings and confirmations.',\n type: 'text',\n },\n {\n key: 'agentName',\n label: 'AI agent name',\n description: 'How the assistant introduces itself (e.g. “Ava”).',\n type: 'text',\n },\n {\n key: 'timezone',\n label: 'Timezone',\n description: 'Used for hours, scheduling, and call timestamps.',\n type: 'text',\n },\n {\n key: 'language',\n label: 'Default language',\n description: 'Primary language for the AI receptionist.',\n type: 'text',\n },\n {\n key: 'ttsVoiceId',\n label: 'Voice',\n description: 'Spoken voice used on phone calls for this practice.',\n type: 'select',\n options: TTS_VOICE_PRESETS.map((p) => ({ value: p.id, label: p.label })),\n },\n ],\n phone: [\n {\n key: 'mainNumber',\n label: 'Main phone number',\n description: 'Primary inbound number patients call.',\n type: 'text',\n },\n {\n key: 'afterHours',\n label: 'After-hours mode',\n description: 'Use after-hours greeting and routing outside business hours.',\n type: 'boolean',\n },\n {\n key: 'ringTimeout',\n label: 'Ring timeout (seconds)',\n description: 'How long to ring before the AI answers.',\n type: 'number',\n },\n ],\n tasks: [\n {\n key: 'autoCreate',\n label: 'Auto-create tasks',\n description: 'Create a staff task when the AI cannot fully resolve a request.',\n type: 'boolean',\n },\n {\n key: 'defaultAssignee',\n label: 'Default assignee',\n description: 'Team or role new tasks are routed to.',\n type: 'text',\n },\n ],\n scheduling: [\n {\n key: 'leadTimeHours',\n label: 'Minimum lead time (hours)',\n description: 'Earliest bookable slot from now.',\n type: 'number',\n },\n {\n key: 'allowSameDay',\n label: 'Allow same-day booking',\n description: 'Let patients book appointments later today.',\n type: 'boolean',\n },\n ],\n refill: [\n {\n key: 'autoApproveDays',\n label: 'Auto-approve within (days)',\n description: 'Refills due within this window may be auto-approved.',\n type: 'number',\n },\n {\n key: 'requireStaffReview',\n label: 'Require staff review',\n description: 'All refill requests need staff approval before sending to pharmacy.',\n type: 'boolean',\n },\n ],\n verify: [\n {\n key: 'requireDob',\n label: 'Require date of birth',\n description: 'Ask for DOB before lookup or scheduling.',\n type: 'boolean',\n },\n {\n key: 'requireName',\n label: 'Require full name',\n description: 'Ask for patient name during verification.',\n type: 'boolean',\n },\n {\n key: 'maxAttempts',\n label: 'Max verification attempts',\n description: 'After this many failures, offer transfer to staff.',\n type: 'number',\n },\n ],\n escalation: [\n {\n key: 'sentimentThreshold',\n label: 'Sentiment threshold',\n description: 'Escalate when caller sentiment reaches this level (e.g. frustrated).',\n type: 'text',\n },\n {\n key: 'urgentKeywords',\n label: 'Urgent keywords',\n description: 'Comma-separated phrases that trigger immediate escalation.',\n type: 'text',\n },\n ],\n outbound: [\n {\n key: 'enabled',\n label: 'Outbound calls enabled',\n description: 'Allow staff to place outbound calls from the dashboard.',\n type: 'boolean',\n },\n {\n key: 'callerId',\n label: 'Outbound caller ID',\n description: 'Number shown to patients on outbound calls.',\n type: 'text',\n },\n ],\n transcripts: [\n {\n key: 'retainDays',\n label: 'Retention (days)',\n description: 'How long transcripts and recordings are kept.',\n type: 'number',\n },\n {\n key: 'redactPhi',\n label: 'Redact PHI in transcripts',\n description: 'Mask sensitive identifiers in stored transcripts.',\n type: 'boolean',\n },\n ],\n advanced: [\n {\n key: 'modelVersion',\n label: 'Model version',\n description: 'Voice AI model profile (set by Edvak support).',\n type: 'text',\n },\n {\n key: 'debugMode',\n label: 'Debug mode',\n description: 'Verbose logging for troubleshooting — not for production.',\n type: 'boolean',\n },\n ],\n};\n\n/** Fallback label for API fields not listed in config. */\nexport function humanizeFieldKey(key: string): string {\n return key\n .replace(/([A-Z])/g, ' $1')\n .replace(/_/g, ' ')\n .trim()\n .replace(/^\\w/, (c) => c.toUpperCase());\n}\n\nexport function resolveFieldMeta(\n section: SettingsSection,\n key: string,\n value: string | boolean | number,\n): SettingsFieldMeta {\n const known = SETTINGS_FIELDS[section]?.find((f) => f.key === key);\n if (known) return known;\n return {\n key,\n label: humanizeFieldKey(key),\n description: '',\n type: typeof value === 'boolean' ? 'boolean' : typeof value === 'number' ? 'number' : 'text',\n };\n}\n","import { ChangeDetectionStrategy, Component, computed, inject, OnInit, signal } from '@angular/core';\n\nimport { FormsModule } from '@angular/forms';\n\nimport { RouterLink } from '@angular/router';\n\n\n\nimport { AgentSettings } from '../../models/ai-receptionist.types';\n\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\n\nimport { EdsBadgeComponent } from '../../ui/eds-badge.component';\n\nimport { EdsButtonComponent } from '../../ui/eds-button.component';\n\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\n\nimport { ToastService } from '../../shared/toast.service';\n\nimport {\n\n buildAutoWelcomeTemplate,\n\n resolveWelcomePreview,\n\n WELCOME_MESSAGE_MAX,\n\n} from '../../utils/welcome-message.util';\n\nimport {\n DISABLED_SETTINGS_TABS,\n isFieldReadOnly,\n READ_ONLY_SECTIONS,\n resolveFieldMeta,\n SETTINGS_FIELDS,\n SETTINGS_SECTION_META,\n SettingsFieldMeta,\n SettingsSection,\n} from './settings-fields.config';\n\n\n\ntype SettingsTab = keyof AgentSettings;\n\n\n\nconst GENERAL_IDENTITY_KEYS = new Set(['practiceName', 'agentName']);\n\nconst GENERAL_OTHER_KEYS = new Set(['timezone', 'language', 'ttsVoiceId']);\n\n\n\n@Component({\n selector: 'eds-settings-page',\n imports: [FormsModule, RouterLink, EdsBadgeComponent, EdsButtonComponent, EdsIconComponent],\n templateUrl: './settings-page.component.html',\n styleUrl: './settings-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\n\nexport class SettingsPageComponent implements OnInit {\n\n private readonly api = inject(AiReceptionistApiService);\n\n private readonly toast = inject(ToastService);\n\n private originalSettings: AgentSettings | null = null;\n\n protected readonly isFieldReadOnly = isFieldReadOnly;\n\n protected readonly readOnlySections = READ_ONLY_SECTIONS;\n\n protected readonly disabledTabs = DISABLED_SETTINGS_TABS;\n\n\n\n protected readonly settings = signal<AgentSettings | null>(null);\n\n protected readonly tab = signal<SettingsTab>('general');\n\n protected readonly loading = signal(true);\n\n protected readonly saving = signal(false);\n\n protected readonly saved = signal(false);\n\n\n\n protected readonly welcomeMax = WELCOME_MESSAGE_MAX;\n\n protected readonly previewingVoice = signal(false);\n\n private voicePreviewAudio: HTMLAudioElement | null = null;\n\n\n\n protected readonly tabs: { id: SettingsTab; label: string; icon: string }[] = [\n\n { id: 'general', label: 'General', icon: 'business' },\n\n { id: 'phone', label: 'Phone', icon: 'call' },\n\n { id: 'tasks', label: 'Tasks', icon: 'task_alt' },\n\n { id: 'scheduling', label: 'Scheduling', icon: 'calendar_month' },\n\n { id: 'refill', label: 'Refills', icon: 'medication' },\n\n { id: 'verify', label: 'Verification', icon: 'verified_user' },\n\n { id: 'escalation', label: 'Escalation', icon: 'warning' },\n\n { id: 'outbound', label: 'Outbound', icon: 'call_made' },\n\n { id: 'transcripts', label: 'Transcripts', icon: 'transcribe' },\n\n { id: 'advanced', label: 'Advanced', icon: 'tune' },\n\n { id: 'safety', label: 'Safety', icon: 'health_and_safety' },\n\n ];\n\n\n\n protected readonly sectionMeta = computed(() => {\n\n const id = this.tab();\n\n if (id === 'safety') {\n\n return { title: 'Safety checklist', description: '' };\n\n }\n\n return SETTINGS_SECTION_META[id as SettingsSection];\n\n });\n\n\n\n protected readonly fieldsForTab = computed((): SettingsFieldMeta[] => {\n\n const s = this.settings();\n\n const id = this.tab();\n\n if (!s || id === 'safety') return [];\n\n\n\n const section = s[id] as Record<string, string | boolean | number>;\n\n const configured = SETTINGS_FIELDS[id as SettingsSection] ?? [];\n\n const configuredKeys = new Set(configured.map((f) => f.key));\n\n\n\n const extras = Object.keys(section)\n\n .filter((key) => key !== 'welcomeMessage' && !configuredKeys.has(key))\n\n .map((key) => resolveFieldMeta(id as SettingsSection, key, section[key]));\n\n\n\n return [...configured, ...extras];\n\n });\n\n\n\n protected readonly generalIdentityFields = computed(() =>\n\n this.fieldsForTab().filter((f) => GENERAL_IDENTITY_KEYS.has(f.key)),\n\n );\n\n\n\n protected readonly generalOtherFields = computed(() =>\n\n this.fieldsForTab().filter((f) => GENERAL_OTHER_KEYS.has(f.key)),\n\n );\n\n\n\n protected readonly welcomeMessage = computed(() =>\n\n String(this.settings()?.general['welcomeMessage'] ?? ''),\n\n );\n\n\n\n protected readonly welcomePlaceholder = computed(() => {\n\n const s = this.settings();\n\n if (!s) return '';\n\n return buildAutoWelcomeTemplate(\n\n String(s.general['practiceName'] ?? ''),\n\n String(s.general['agentName'] ?? ''),\n\n );\n\n });\n\n\n\n protected readonly welcomePreview = computed(() => {\n\n const s = this.settings();\n\n if (!s) return '';\n\n return resolveWelcomePreview(\n\n String(s.general['welcomeMessage'] ?? ''),\n\n String(s.general['practiceName'] ?? ''),\n\n String(s.general['agentName'] ?? ''),\n\n );\n\n });\n\n\n\n protected readonly usingDefaultWelcome = computed(() => !this.welcomeMessage().trim());\n\n\n\n protected readonly showRecordingConsentHint = computed(() => {\n\n const t = this.settings()?.transcripts;\n\n if (!t) return false;\n\n const retain = Number(t['retainDays'] ?? 0);\n\n return retain > 0 || t['redactPhi'] === true;\n\n });\n\n\n\n ngOnInit(): void {\n\n this.api.getSettings().subscribe({\n\n next: ({ data }) => {\n\n this.originalSettings = structuredClone(data);\n\n this.settings.set(structuredClone(data));\n\n this.loading.set(false);\n\n },\n\n error: () => {\n\n this.loading.set(false);\n\n this.toast.show('Failed to load agent settings', 'error');\n\n },\n\n });\n\n }\n\n\n\n protected fieldIsReadOnly(section: SettingsTab, key: string): boolean {\n if (section === 'safety' || section === 'effectiveWelcomeMessage') return true;\n return isFieldReadOnly(section, key);\n }\n\n protected sectionIsReadOnly(section: SettingsTab): boolean {\n if (section === 'safety' || section === 'effectiveWelcomeMessage') return true;\n return READ_ONLY_SECTIONS.has(section);\n }\n\n protected isTabDisabled(id: SettingsTab): boolean {\n return id !== 'safety' && id !== 'effectiveWelcomeMessage' && DISABLED_SETTINGS_TABS.has(id);\n }\n\n protected setTab(id: SettingsTab): void {\n if (this.isTabDisabled(id)) return;\n this.tab.set(id);\n }\n\n\n\n protected updateField(section: SettingsTab, key: string, value: string | boolean | number): void {\n\n const current = this.settings();\n\n if (!current || section === 'safety' || isFieldReadOnly(section as SettingsSection, key)) return;\n\n const sectionData = { ...(current[section] as Record<string, string | boolean | number>) };\n\n sectionData[key] = value;\n\n this.settings.set({ ...current, [section]: sectionData });\n\n }\n\n\n\n protected updateWelcomeMessage(value: string): void {\n\n this.updateField('general', 'welcomeMessage', value.slice(0, WELCOME_MESSAGE_MAX));\n\n }\n\n\n\n protected resetWelcomeMessage(): void {\n\n this.updateField('general', 'welcomeMessage', '');\n\n }\n\n protected previewSelectedVoice(): void {\n const voiceId = String(this.fieldValue('general', 'ttsVoiceId') ?? '').trim();\n if (!voiceId || this.previewingVoice()) return;\n\n this.previewingVoice.set(true);\n this.api.previewVoice(voiceId).subscribe({\n next: (blob) => {\n this.previewingVoice.set(false);\n if (this.voicePreviewAudio) {\n this.voicePreviewAudio.pause();\n URL.revokeObjectURL(this.voicePreviewAudio.src);\n this.voicePreviewAudio = null;\n }\n const url = URL.createObjectURL(blob);\n const audio = new Audio(url);\n this.voicePreviewAudio = audio;\n audio.onended = () => {\n URL.revokeObjectURL(url);\n if (this.voicePreviewAudio === audio) this.voicePreviewAudio = null;\n };\n void audio.play().catch(() => {\n this.toast.show('Could not play voice preview in this browser.', 'error');\n URL.revokeObjectURL(url);\n });\n },\n error: () => {\n this.previewingVoice.set(false);\n this.toast.show('Could not generate voice preview. Try again.', 'error');\n },\n });\n }\n\n\n\n protected fieldValue(section: SettingsTab, key: string): string | boolean | number {\n\n const s = this.settings();\n\n if (!s || section === 'safety') return '';\n\n return (s[section] as Record<string, string | boolean | number>)[key];\n\n }\n\n\n\n protected save(): void {\n\n const s = this.settings();\n\n const orig = this.originalSettings;\n\n if (!s || !orig) return;\n\n\n\n const payload = structuredClone(s);\n\n const wm = String(payload.general['welcomeMessage'] ?? '').trim();\n\n payload.general['welcomeMessage'] = wm;\n\n this.restoreReadOnlyFields(payload, orig);\n\n\n\n this.saving.set(true);\n\n this.api.putSettings(payload).subscribe({\n\n next: ({ data }) => {\n\n this.originalSettings = structuredClone(data);\n\n this.settings.set(structuredClone(data));\n\n this.saving.set(false);\n\n this.saved.set(true);\n\n this.toast.show('Agent settings saved', 'success');\n\n setTimeout(() => this.saved.set(false), 2000);\n\n },\n\n error: () => {\n\n this.saving.set(false);\n\n this.toast.show('Failed to save agent settings', 'error');\n\n },\n\n });\n\n }\n\n private restoreReadOnlyFields(payload: AgentSettings, orig: AgentSettings): void {\n const editableSections: SettingsSection[] = [\n 'general',\n 'phone',\n 'tasks',\n 'scheduling',\n 'refill',\n 'verify',\n 'escalation',\n 'outbound',\n 'transcripts',\n 'advanced',\n ];\n\n for (const sectionKey of editableSections) {\n if (READ_ONLY_SECTIONS.has(sectionKey)) {\n payload[sectionKey] = structuredClone(orig[sectionKey]);\n continue;\n }\n\n const payloadSection = payload[sectionKey] as Record<string, string | boolean | number>;\n const origSection = orig[sectionKey] as Record<string, string | boolean | number>;\n for (const key of Object.keys(payloadSection)) {\n if (isFieldReadOnly(sectionKey, key)) {\n payloadSection[key] = origSection[key];\n }\n }\n }\n }\n\n}\n\n\n","<div class=\"eds-page settings-page\">\n <header class=\"settings-page__header\">\n <div>\n <h1 class=\"eds-h1\">Agent settings</h1>\n <p class=\"settings-page__subtitle\">Configure AI receptionist behavior and safety</p>\n </div>\n <div class=\"settings-page__save-row\">\n @if (saved()) {\n <span class=\"settings-page__saved\">Saved</span>\n }\n <eds-button variant=\"primary\" [disabled]=\"saving()\" (click)=\"save()\">\n <eds-icon name=\"save\" [size]=\"18\" />\n {{ saving() ? 'Saving…' : 'Save changes' }}\n </eds-button>\n </div>\n </header>\n\n @if (loading()) {\n <p class=\"settings-page__loading\">Loading settings…</p>\n } @else if (settings()) {\n <div class=\"settings-page__layout\">\n <nav class=\"eds-card settings-page__sidebar\" aria-label=\"Settings sections\">\n @for (t of tabs; track t.id) {\n <button\n type=\"button\"\n class=\"settings-page__nav-item\"\n [class.settings-page__nav-item--active]=\"tab() === t.id\"\n [class.settings-page__nav-item--disabled]=\"isTabDisabled(t.id)\"\n [disabled]=\"isTabDisabled(t.id)\"\n [attr.title]=\"isTabDisabled(t.id) ? 'This section is currently disabled' : null\"\n (click)=\"setTab(t.id)\"\n >\n <eds-icon [name]=\"t.icon\" [size]=\"18\" />\n {{ t.label }}\n @if (isTabDisabled(t.id)) {\n <span class=\"settings-page__nav-disabled-badge\">Disabled</span>\n }\n </button>\n }\n </nav>\n\n <article class=\"eds-card settings-page__panel\">\n @if (tab() === 'safety') {\n <header class=\"settings-page__panel-head\">\n <h2 class=\"settings-page__panel-title\">Safety checklist</h2>\n <p class=\"settings-page__panel-desc\">\n Read-only compliance status. Contact Edvak support to change safety configuration.\n </p>\n </header>\n <ul class=\"settings-page__safety\">\n @for (item of settings()!.safety; track item.id) {\n <li>\n <eds-icon\n [name]=\"item.status === 'ok' ? 'check_circle' : 'error'\"\n [size]=\"22\"\n />\n <span class=\"settings-page__safety-label\">{{ item.label }}</span>\n <eds-badge [tone]=\"item.status === 'ok' ? 'pos' : 'notice'\">\n {{ item.status === 'ok' ? 'Pass' : 'Needs attention' }}\n </eds-badge>\n </li>\n }\n </ul>\n } @else {\n <header class=\"settings-page__panel-head\">\n <h2 class=\"settings-page__panel-title\">{{ sectionMeta().title }}</h2>\n <p class=\"settings-page__panel-desc\">{{ sectionMeta().description }}</p>\n </header>\n\n @if (sectionIsReadOnly(tab())) {\n <p class=\"settings-page__readonly-banner\">\n <eds-icon name=\"lock\" [size]=\"18\" />\n These settings are managed by Edvak. Contact support to request changes.\n </p>\n }\n\n @if (tab() === 'general') {\n <a routerLink=\"../knowledge\" class=\"settings-page__quick-link\">\n <eds-icon name=\"menu_book\" [size]=\"22\" />\n <div>\n <span class=\"settings-page__quick-link-title\">Practice Knowledge Base</span>\n <span class=\"settings-page__quick-link-desc\">FAQ answers your AI uses on phone calls</span>\n </div>\n <eds-icon name=\"chevron_right\" [size]=\"20\" />\n </a>\n\n <div class=\"settings-page__fields settings-page__fields--general\">\n @for (field of generalIdentityFields(); track field.key) {\n <label\n class=\"settings-page__field\"\n [class.settings-page__field--readonly]=\"isFieldReadOnly('general', field.key)\"\n >\n <span class=\"settings-page__field-label\">\n {{ field.label }}\n @if (isFieldReadOnly('general', field.key)) {\n <span class=\"settings-page__readonly-badge\">Read-only</span>\n }\n </span>\n @if (field.description) {\n <span class=\"settings-page__field-desc\">{{ field.description }}</span>\n }\n <input\n type=\"text\"\n class=\"settings-page__input\"\n [class.settings-page__input--readonly]=\"isFieldReadOnly('general', field.key)\"\n [disabled]=\"isFieldReadOnly('general', field.key)\"\n [ngModel]=\"fieldValue('general', field.key)\"\n (ngModelChange)=\"updateField('general', field.key, $event)\"\n />\n </label>\n }\n\n <section class=\"settings-page__welcome\">\n <label class=\"settings-page__field settings-page__field--full\">\n <span class=\"settings-page__field-label\">Welcome message</span>\n <span class=\"settings-page__field-desc\">\n Spoken automatically when a caller connects. Leave blank to use the default template.\n </span>\n <textarea\n class=\"settings-page__textarea\"\n rows=\"4\"\n [maxlength]=\"welcomeMax\"\n [placeholder]=\"welcomePlaceholder()\"\n [ngModel]=\"welcomeMessage()\"\n (ngModelChange)=\"updateWelcomeMessage($event)\"\n ></textarea>\n <span class=\"settings-page__char-count\">\n {{ welcomeMessage().length }}/{{ welcomeMax }}\n </span>\n @if (showRecordingConsentHint()) {\n <p class=\"settings-page__recording-hint\">\n Call recording is enabled — consider mentioning that the call may be recorded or monitored.\n </p>\n }\n </label>\n\n <div class=\"settings-page__welcome-preview eds-card\">\n <div class=\"settings-page__welcome-preview-head\">\n <eds-icon name=\"record_voice_over\" [size]=\"20\" />\n <span class=\"settings-page__field-label\">Live preview</span>\n @if (usingDefaultWelcome()) {\n <eds-badge tone=\"gray\">Default template</eds-badge>\n }\n </div>\n <p class=\"settings-page__welcome-preview-text\">“{{ welcomePreview() }}”</p>\n </div>\n\n @if (!usingDefaultWelcome()) {\n <eds-button variant=\"secondary\" type=\"button\" (click)=\"resetWelcomeMessage()\">\n Reset to default\n </eds-button>\n }\n </section>\n\n @for (field of generalOtherFields(); track field.key) {\n <label\n class=\"settings-page__field\"\n [class.settings-page__field--readonly]=\"isFieldReadOnly('general', field.key)\"\n >\n <span class=\"settings-page__field-label\">\n {{ field.label }}\n @if (isFieldReadOnly('general', field.key)) {\n <span class=\"settings-page__readonly-badge\">Read-only</span>\n }\n </span>\n @if (field.description) {\n <span class=\"settings-page__field-desc\">{{ field.description }}</span>\n }\n @if (field.type === 'select' && field.options?.length) {\n <select\n class=\"settings-page__input settings-page__select\"\n [class.settings-page__input--readonly]=\"isFieldReadOnly('general', field.key)\"\n [disabled]=\"isFieldReadOnly('general', field.key)\"\n [ngModel]=\"fieldValue('general', field.key)\"\n (ngModelChange)=\"updateField('general', field.key, $event)\"\n >\n @for (opt of field.options; track opt.value) {\n <option [ngValue]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n @if (field.key === 'ttsVoiceId') {\n <div class=\"settings-page__voice-preview-row\">\n <eds-button\n variant=\"secondary\"\n type=\"button\"\n [disabled]=\"previewingVoice()\"\n (click)=\"previewSelectedVoice()\"\n >\n {{ previewingVoice() ? 'Generating…' : 'Preview voice' }}\n </eds-button>\n <span class=\"settings-page__field-desc\">\n Plays a short sample in the browser — save to use on phone calls.\n </span>\n </div>\n }\n } @else {\n <input\n type=\"text\"\n class=\"settings-page__input\"\n [class.settings-page__input--readonly]=\"isFieldReadOnly('general', field.key)\"\n [disabled]=\"isFieldReadOnly('general', field.key)\"\n [ngModel]=\"fieldValue('general', field.key)\"\n (ngModelChange)=\"updateField('general', field.key, $event)\"\n />\n }\n </label>\n }\n </div>\n } @else {\n @if (tab() === 'outbound') {\n <a [routerLink]=\"['../settings/outbound-purposes']\" class=\"settings-page__quick-link\">\n <eds-icon name=\"call_made\" [size]=\"22\" />\n <div>\n <span class=\"settings-page__quick-link-title\">Outbound Call Purposes</span>\n <span class=\"settings-page__quick-link-desc\">Templates, required fields, and opening scripts</span>\n </div>\n <eds-icon name=\"chevron_right\" [size]=\"20\" />\n </a>\n }\n\n <div class=\"settings-page__fields\">\n @for (field of fieldsForTab(); track field.key) {\n @if (field.type === 'boolean') {\n <label\n class=\"settings-page__toggle-row\"\n [class.settings-page__toggle-row--readonly]=\"fieldIsReadOnly(tab(), field.key)\"\n >\n <div class=\"settings-page__toggle-copy\">\n <span class=\"settings-page__field-label\">\n {{ field.label }}\n @if (fieldIsReadOnly(tab(), field.key)) {\n <span class=\"settings-page__readonly-badge\">Read-only</span>\n }\n </span>\n @if (field.description) {\n <span class=\"settings-page__field-desc\">{{ field.description }}</span>\n }\n </div>\n <input\n type=\"checkbox\"\n class=\"settings-page__checkbox\"\n [disabled]=\"fieldIsReadOnly(tab(), field.key)\"\n [ngModel]=\"fieldValue(tab(), field.key)\"\n (ngModelChange)=\"updateField(tab(), field.key, $event)\"\n />\n </label>\n } @else {\n <label\n class=\"settings-page__field\"\n [class.settings-page__field--readonly]=\"fieldIsReadOnly(tab(), field.key)\"\n >\n <span class=\"settings-page__field-label\">\n {{ field.label }}\n @if (fieldIsReadOnly(tab(), field.key)) {\n <span class=\"settings-page__readonly-badge\">Read-only</span>\n }\n </span>\n @if (field.description) {\n <span class=\"settings-page__field-desc\">{{ field.description }}</span>\n }\n @if (field.type === 'number') {\n <input\n type=\"number\"\n class=\"settings-page__input\"\n [class.settings-page__input--readonly]=\"fieldIsReadOnly(tab(), field.key)\"\n [disabled]=\"fieldIsReadOnly(tab(), field.key)\"\n [ngModel]=\"fieldValue(tab(), field.key)\"\n (ngModelChange)=\"updateField(tab(), field.key, +$event)\"\n />\n } @else if (field.type === 'select' && field.options?.length) {\n <select\n class=\"settings-page__input settings-page__select\"\n [class.settings-page__input--readonly]=\"fieldIsReadOnly(tab(), field.key)\"\n [disabled]=\"fieldIsReadOnly(tab(), field.key)\"\n [ngModel]=\"fieldValue(tab(), field.key)\"\n (ngModelChange)=\"updateField(tab(), field.key, $event)\"\n >\n @for (opt of field.options; track opt.value) {\n <option [ngValue]=\"opt.value\">{{ opt.label }}</option>\n }\n </select>\n } @else {\n <input\n type=\"text\"\n class=\"settings-page__input\"\n [class.settings-page__input--readonly]=\"fieldIsReadOnly(tab(), field.key)\"\n [disabled]=\"fieldIsReadOnly(tab(), field.key)\"\n [ngModel]=\"fieldValue(tab(), field.key)\"\n (ngModelChange)=\"updateField(tab(), field.key, $event)\"\n />\n }\n </label>\n }\n }\n </div>\n }\n }\n </article>\n </div>\n }\n</div>\n"],"names":[],"mappings":";;;;;;;AAAA;AAOO,MAAM,oBAAoB,GAAG,sBAAsB;AAEnD,MAAM,iBAAiB,GAA8B;AAC1D,IAAA;AACE,QAAA,EAAE,EAAE,sBAAsB;AAC1B,QAAA,KAAK,EAAE,uCAAuC;AAC/C,KAAA;AACD,IAAA;AACE,QAAA,EAAE,EAAE,sBAAsB;AAC1B,QAAA,KAAK,EAAE,uCAAuC;AAC/C,KAAA;AACD,IAAA;AACE,QAAA,EAAE,EAAE,sBAAsB;AAC1B,QAAA,KAAK,EAAE,yCAAyC;AACjD,KAAA;AACD,IAAA;AACE,QAAA,EAAE,EAAE,sBAAsB;AAC1B,QAAA,KAAK,EAAE,yBAAyB;AACjC,KAAA;CACO;;ACFH,MAAM,qBAAqB,GAAiD;AACjF,IAAA,OAAO,EAAE;AACP,QAAA,KAAK,EAAE,SAAS;AAChB,QAAA,WAAW,EAAE,8DAA8D;AAC5E,KAAA;AACD,IAAA,KAAK,EAAE;AACL,QAAA,KAAK,EAAE,OAAO;AACd,QAAA,WAAW,EAAE,yDAAyD;AACvE,KAAA;AACD,IAAA,KAAK,EAAE;AACL,QAAA,KAAK,EAAE,oBAAoB;AAC3B,QAAA,WAAW,EAAE,qDAAqD;AACnE,KAAA;AACD,IAAA,UAAU,EAAE;AACV,QAAA,KAAK,EAAE,YAAY;AACnB,QAAA,WAAW,EAAE,kDAAkD;AAChE,KAAA;AACD,IAAA,MAAM,EAAE;AACN,QAAA,KAAK,EAAE,oBAAoB;AAC3B,QAAA,WAAW,EAAE,wDAAwD;AACtE,KAAA;AACD,IAAA,MAAM,EAAE;AACN,QAAA,KAAK,EAAE,sBAAsB;AAC7B,QAAA,WAAW,EAAE,4DAA4D;AAC1E,KAAA;AACD,IAAA,UAAU,EAAE;AACV,QAAA,KAAK,EAAE,YAAY;AACnB,QAAA,WAAW,EAAE,iDAAiD;AAC/D,KAAA;AACD,IAAA,QAAQ,EAAE;AACR,QAAA,KAAK,EAAE,kBAAkB;AACzB,QAAA,WAAW,EAAE,qEAAqE;AACnF,KAAA;AACD,IAAA,WAAW,EAAE;AACX,QAAA,KAAK,EAAE,yBAAyB;AAChC,QAAA,WAAW,EAAE,kDAAkD;AAChE,KAAA;AACD,IAAA,QAAQ,EAAE;AACR,QAAA,KAAK,EAAE,UAAU;AACjB,QAAA,WAAW,EAAE,uEAAuE;AACrF,KAAA;CACF;AAED;AACO,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAkB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;AAElF;AACO,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAkB,CAAC,QAAQ,CAAC,CAAC;AAE1E;AACO,MAAM,oBAAoB,GAA6E;IAC5G,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,wBAAwB,EAAE;IAC7E,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,mBAAmB,EAAE;IACrE,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,mBAAmB,EAAE;IACpE,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,kBAAkB,EAAE;IACnE,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,uBAAuB,EAAE;IACxE,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,oBAAoB,EAAE;IACtE,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,4BAA4B,EAAE;IACnF,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,sBAAsB,EAAE;IAC5E,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,wBAAwB,EAAE;IAC9E,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE;CACnE;AAED,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAC9B,oBAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,CAAA,EAAG,OAAO,CAAA,CAAA,EAAI,GAAG,CAAA,CAAE,CAAC,CACpE;AAEK,SAAU,eAAe,CAAC,OAAwB,EAAE,GAAW,EAAA;AACnE,IAAA,IAAI,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC;AAAE,QAAA,OAAO,IAAI;IAChD,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAA,EAAG,OAAO,CAAA,CAAA,EAAI,GAAG,CAAA,CAAE,CAAC;AAClD;AAEM,SAAU,mBAAmB,CAAC,OAAwB,EAAE,GAAW,EAAA;IACvE,OAAO,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,KAAK,OAAO,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,MAAM;AACzF;AAEO,MAAM,eAAe,GAAiD;AAC3E,IAAA,OAAO,EAAE;AACP,QAAA;AACE,YAAA,GAAG,EAAE,cAAc;AACnB,YAAA,KAAK,EAAE,eAAe;AACtB,YAAA,WAAW,EAAE,wCAAwC;AACrD,YAAA,IAAI,EAAE,MAAM;AACb,SAAA;AACD,QAAA;AACE,YAAA,GAAG,EAAE,WAAW;AAChB,YAAA,KAAK,EAAE,eAAe;AACtB,YAAA,WAAW,EAAE,mDAAmD;AAChE,YAAA,IAAI,EAAE,MAAM;AACb,SAAA;AACD,QAAA;AACE,YAAA,GAAG,EAAE,UAAU;AACf,YAAA,KAAK,EAAE,UAAU;AACjB,YAAA,WAAW,EAAE,kDAAkD;AAC/D,YAAA,IAAI,EAAE,MAAM;AACb,SAAA;AACD,QAAA;AACE,YAAA,GAAG,EAAE,UAAU;AACf,YAAA,KAAK,EAAE,kBAAkB;AACzB,YAAA,WAAW,EAAE,2CAA2C;AACxD,YAAA,IAAI,EAAE,MAAM;AACb,SAAA;AACD,QAAA;AACE,YAAA,GAAG,EAAE,YAAY;AACjB,YAAA,KAAK,EAAE,OAAO;AACd,YAAA,WAAW,EAAE,qDAAqD;AAClE,YAAA,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;AACzE,SAAA;AACF,KAAA;AACD,IAAA,KAAK,EAAE;AACL,QAAA;AACE,YAAA,GAAG,EAAE,YAAY;AACjB,YAAA,KAAK,EAAE,mBAAmB;AAC1B,YAAA,WAAW,EAAE,uCAAuC;AACpD,YAAA,IAAI,EAAE,MAAM;AACb,SAAA;AACD,QAAA;AACE,YAAA,GAAG,EAAE,YAAY;AACjB,YAAA,KAAK,EAAE,kBAAkB;AACzB,YAAA,WAAW,EAAE,8DAA8D;AAC3E,YAAA,IAAI,EAAE,SAAS;AAChB,SAAA;AACD,QAAA;AACE,YAAA,GAAG,EAAE,aAAa;AAClB,YAAA,KAAK,EAAE,wBAAwB;AAC/B,YAAA,WAAW,EAAE,yCAAyC;AACtD,YAAA,IAAI,EAAE,QAAQ;AACf,SAAA;AACF,KAAA;AACD,IAAA,KAAK,EAAE;AACL,QAAA;AACE,YAAA,GAAG,EAAE,YAAY;AACjB,YAAA,KAAK,EAAE,mBAAmB;AAC1B,YAAA,WAAW,EAAE,iEAAiE;AAC9E,YAAA,IAAI,EAAE,SAAS;AAChB,SAAA;AACD,QAAA;AACE,YAAA,GAAG,EAAE,iBAAiB;AACtB,YAAA,KAAK,EAAE,kBAAkB;AACzB,YAAA,WAAW,EAAE,uCAAuC;AACpD,YAAA,IAAI,EAAE,MAAM;AACb,SAAA;AACF,KAAA;AACD,IAAA,UAAU,EAAE;AACV,QAAA;AACE,YAAA,GAAG,EAAE,eAAe;AACpB,YAAA,KAAK,EAAE,2BAA2B;AAClC,YAAA,WAAW,EAAE,kCAAkC;AAC/C,YAAA,IAAI,EAAE,QAAQ;AACf,SAAA;AACD,QAAA;AACE,YAAA,GAAG,EAAE,cAAc;AACnB,YAAA,KAAK,EAAE,wBAAwB;AAC/B,YAAA,WAAW,EAAE,6CAA6C;AAC1D,YAAA,IAAI,EAAE,SAAS;AAChB,SAAA;AACF,KAAA;AACD,IAAA,MAAM,EAAE;AACN,QAAA;AACE,YAAA,GAAG,EAAE,iBAAiB;AACtB,YAAA,KAAK,EAAE,4BAA4B;AACnC,YAAA,WAAW,EAAE,sDAAsD;AACnE,YAAA,IAAI,EAAE,QAAQ;AACf,SAAA;AACD,QAAA;AACE,YAAA,GAAG,EAAE,oBAAoB;AACzB,YAAA,KAAK,EAAE,sBAAsB;AAC7B,YAAA,WAAW,EAAE,qEAAqE;AAClF,YAAA,IAAI,EAAE,SAAS;AAChB,SAAA;AACF,KAAA;AACD,IAAA,MAAM,EAAE;AACN,QAAA;AACE,YAAA,GAAG,EAAE,YAAY;AACjB,YAAA,KAAK,EAAE,uBAAuB;AAC9B,YAAA,WAAW,EAAE,0CAA0C;AACvD,YAAA,IAAI,EAAE,SAAS;AAChB,SAAA;AACD,QAAA;AACE,YAAA,GAAG,EAAE,aAAa;AAClB,YAAA,KAAK,EAAE,mBAAmB;AAC1B,YAAA,WAAW,EAAE,2CAA2C;AACxD,YAAA,IAAI,EAAE,SAAS;AAChB,SAAA;AACD,QAAA;AACE,YAAA,GAAG,EAAE,aAAa;AAClB,YAAA,KAAK,EAAE,2BAA2B;AAClC,YAAA,WAAW,EAAE,oDAAoD;AACjE,YAAA,IAAI,EAAE,QAAQ;AACf,SAAA;AACF,KAAA;AACD,IAAA,UAAU,EAAE;AACV,QAAA;AACE,YAAA,GAAG,EAAE,oBAAoB;AACzB,YAAA,KAAK,EAAE,qBAAqB;AAC5B,YAAA,WAAW,EAAE,sEAAsE;AACnF,YAAA,IAAI,EAAE,MAAM;AACb,SAAA;AACD,QAAA;AACE,YAAA,GAAG,EAAE,gBAAgB;AACrB,YAAA,KAAK,EAAE,iBAAiB;AACxB,YAAA,WAAW,EAAE,4DAA4D;AACzE,YAAA,IAAI,EAAE,MAAM;AACb,SAAA;AACF,KAAA;AACD,IAAA,QAAQ,EAAE;AACR,QAAA;AACE,YAAA,GAAG,EAAE,SAAS;AACd,YAAA,KAAK,EAAE,wBAAwB;AAC/B,YAAA,WAAW,EAAE,yDAAyD;AACtE,YAAA,IAAI,EAAE,SAAS;AAChB,SAAA;AACD,QAAA;AACE,YAAA,GAAG,EAAE,UAAU;AACf,YAAA,KAAK,EAAE,oBAAoB;AAC3B,YAAA,WAAW,EAAE,6CAA6C;AAC1D,YAAA,IAAI,EAAE,MAAM;AACb,SAAA;AACF,KAAA;AACD,IAAA,WAAW,EAAE;AACX,QAAA;AACE,YAAA,GAAG,EAAE,YAAY;AACjB,YAAA,KAAK,EAAE,kBAAkB;AACzB,YAAA,WAAW,EAAE,+CAA+C;AAC5D,YAAA,IAAI,EAAE,QAAQ;AACf,SAAA;AACD,QAAA;AACE,YAAA,GAAG,EAAE,WAAW;AAChB,YAAA,KAAK,EAAE,2BAA2B;AAClC,YAAA,WAAW,EAAE,mDAAmD;AAChE,YAAA,IAAI,EAAE,SAAS;AAChB,SAAA;AACF,KAAA;AACD,IAAA,QAAQ,EAAE;AACR,QAAA;AACE,YAAA,GAAG,EAAE,cAAc;AACnB,YAAA,KAAK,EAAE,eAAe;AACtB,YAAA,WAAW,EAAE,gDAAgD;AAC7D,YAAA,IAAI,EAAE,MAAM;AACb,SAAA;AACD,QAAA;AACE,YAAA,GAAG,EAAE,WAAW;AAChB,YAAA,KAAK,EAAE,YAAY;AACnB,YAAA,WAAW,EAAE,2DAA2D;AACxE,YAAA,IAAI,EAAE,SAAS;AAChB,SAAA;AACF,KAAA;CACF;AAED;AACM,SAAU,gBAAgB,CAAC,GAAW,EAAA;AAC1C,IAAA,OAAO;AACJ,SAAA,OAAO,CAAC,UAAU,EAAE,KAAK;AACzB,SAAA,OAAO,CAAC,IAAI,EAAE,GAAG;AACjB,SAAA,IAAI;AACJ,SAAA,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;AAC3C;SAEgB,gBAAgB,CAC9B,OAAwB,EACxB,GAAW,EACX,KAAgC,EAAA;IAEhC,MAAM,KAAK,GAAG,eAAe,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC;AAClE,IAAA,IAAI,KAAK;AAAE,QAAA,OAAO,KAAK;IACvB,OAAO;QACL,GAAG;AACH,QAAA,KAAK,EAAE,gBAAgB,CAAC,GAAG,CAAC;AAC5B,QAAA,WAAW,EAAE,EAAE;QACf,IAAI,EAAE,OAAO,KAAK,KAAK,SAAS,GAAG,SAAS,GAAG,OAAO,KAAK,KAAK,QAAQ,GAAG,QAAQ,GAAG,MAAM;KAC7F;AACH;;ACzPA,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;AAEpE,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;MAY7D,qBAAqB,CAAA;AARlC,IAAA,WAAA,GAAA;AAUmB,QAAA,IAAA,CAAA,GAAG,GAAG,MAAM,CAAC,wBAAwB,CAAC;AAEtC,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAC,YAAY,CAAC;QAErC,IAAA,CAAA,gBAAgB,GAAyB,IAAI;QAElC,IAAA,CAAA,eAAe,GAAG,eAAe;QAEjC,IAAA,CAAA,gBAAgB,GAAG,kBAAkB;QAErC,IAAA,CAAA,YAAY,GAAG,sBAAsB;AAIrC,QAAA,IAAA,CAAA,QAAQ,GAAG,MAAM,CAAuB,IAAI,CAAC;AAE7C,QAAA,IAAA,CAAA,GAAG,GAAG,MAAM,CAAc,SAAS,CAAC;AAEpC,QAAA,IAAA,CAAA,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC;AAEtB,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;AAEtB,QAAA,IAAA,CAAA,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAIrB,IAAA,CAAA,UAAU,GAAG,mBAAmB;AAEhC,QAAA,IAAA,CAAA,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC;QAE1C,IAAA,CAAA,iBAAiB,GAA4B,IAAI;AAItC,QAAA,IAAA,CAAA,IAAI,GAAuD;YAE5E,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE;YAErD,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE;YAE7C,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE;YAEjD,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,gBAAgB,EAAE;YAEjE,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE;YAEtD,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,eAAe,EAAE;YAE9D,EAAE,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,SAAS,EAAE;YAE1D,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE;YAExD,EAAE,EAAE,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,EAAE;YAE/D,EAAE,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE;YAEnD,EAAE,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,mBAAmB,EAAE;SAE7D;AAIkB,QAAA,IAAA,CAAA,WAAW,GAAG,QAAQ,CAAC,MAAK;AAE7C,YAAA,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE;AAErB,YAAA,IAAI,EAAE,KAAK,QAAQ,EAAE;gBAEnB,OAAO,EAAE,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,EAAE,EAAE;YAEvD;AAEA,YAAA,OAAO,qBAAqB,CAAC,EAAqB,CAAC;AAErD,QAAA,CAAC,CAAC;AAIiB,QAAA,IAAA,CAAA,YAAY,GAAG,QAAQ,CAAC,MAA0B;AAEnE,YAAA,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE;AAEzB,YAAA,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE;AAErB,YAAA,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,QAAQ;AAAE,gBAAA,OAAO,EAAE;AAIpC,YAAA,MAAM,OAAO,GAAG,CAAC,CAAC,EAAE,CAA8C;YAElE,MAAM,UAAU,GAAG,eAAe,CAAC,EAAqB,CAAC,IAAI,EAAE;AAE/D,YAAA,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC;AAI5D,YAAA,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO;AAE/B,iBAAA,MAAM,CAAC,CAAC,GAAG,KAAK,GAAG,KAAK,gBAAgB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC;AAEpE,iBAAA,GAAG,CAAC,CAAC,GAAG,KAAK,gBAAgB,CAAC,EAAqB,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;AAI3E,YAAA,OAAO,CAAC,GAAG,UAAU,EAAE,GAAG,MAAM,CAAC;AAEnC,QAAA,CAAC,CAAC;AAIiB,QAAA,IAAA,CAAA,qBAAqB,GAAG,QAAQ,CAAC,MAElD,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAEpE;AAIkB,QAAA,IAAA,CAAA,kBAAkB,GAAG,QAAQ,CAAC,MAE/C,IAAI,CAAC,YAAY,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAEjE;QAIkB,IAAA,CAAA,cAAc,GAAG,QAAQ,CAAC,MAE3C,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAEzD;AAIkB,QAAA,IAAA,CAAA,kBAAkB,GAAG,QAAQ,CAAC,MAAK;AAEpD,YAAA,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE;AAEzB,YAAA,IAAI,CAAC,CAAC;AAAE,gBAAA,OAAO,EAAE;YAEjB,OAAO,wBAAwB,CAE7B,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,EAEvC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAErC;AAEH,QAAA,CAAC,CAAC;AAIiB,QAAA,IAAA,CAAA,cAAc,GAAG,QAAQ,CAAC,MAAK;AAEhD,YAAA,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE;AAEzB,YAAA,IAAI,CAAC,CAAC;AAAE,gBAAA,OAAO,EAAE;AAEjB,YAAA,OAAO,qBAAqB,CAE1B,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,EAEzC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,EAEvC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC,CAErC;AAEH,QAAA,CAAC,CAAC;AAIiB,QAAA,IAAA,CAAA,mBAAmB,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC,IAAI,EAAE,CAAC;AAInE,QAAA,IAAA,CAAA,wBAAwB,GAAG,QAAQ,CAAC,MAAK;YAE1D,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,EAAE,WAAW;AAEtC,YAAA,IAAI,CAAC,CAAC;AAAE,gBAAA,OAAO,KAAK;YAEpB,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;YAE3C,OAAO,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,KAAK,IAAI;AAE9C,QAAA,CAAC,CAAC;AAmNH,IAAA;IA/MC,QAAQ,GAAA;AAEN,QAAA,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC;AAE/B,YAAA,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,KAAI;AAEjB,gBAAA,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC,IAAI,CAAC;gBAE7C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;AAExC,gBAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;YAEzB,CAAC;YAED,KAAK,EAAE,MAAK;AAEV,gBAAA,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;gBAEvB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,+BAA+B,EAAE,OAAO,CAAC;YAE3D,CAAC;AAEF,SAAA,CAAC;IAEJ;IAIU,eAAe,CAAC,OAAoB,EAAE,GAAW,EAAA;AACzD,QAAA,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,yBAAyB;AAAE,YAAA,OAAO,IAAI;AAC9E,QAAA,OAAO,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC;IACtC;AAEU,IAAA,iBAAiB,CAAC,OAAoB,EAAA;AAC9C,QAAA,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,yBAAyB;AAAE,YAAA,OAAO,IAAI;AAC9E,QAAA,OAAO,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC;IACxC;AAEU,IAAA,aAAa,CAAC,EAAe,EAAA;AACrC,QAAA,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,KAAK,yBAAyB,IAAI,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC;IAC9F;AAEU,IAAA,MAAM,CAAC,EAAe,EAAA;AAC9B,QAAA,IAAI,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;YAAE;AAC5B,QAAA,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;IAClB;AAIU,IAAA,WAAW,CAAC,OAAoB,EAAE,GAAW,EAAE,KAAgC,EAAA;AAEvF,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE;AAE/B,QAAA,IAAI,CAAC,OAAO,IAAI,OAAO,KAAK,QAAQ,IAAI,eAAe,CAAC,OAA0B,EAAE,GAAG,CAAC;YAAE;QAE1F,MAAM,WAAW,GAAG,EAAE,GAAI,OAAO,CAAC,OAAO,CAA+C,EAAE;AAE1F,QAAA,WAAW,CAAC,GAAG,CAAC,GAAG,KAAK;AAExB,QAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,OAAO,EAAE,CAAC,OAAO,GAAG,WAAW,EAAE,CAAC;IAE3D;AAIU,IAAA,oBAAoB,CAAC,KAAa,EAAA;AAE1C,QAAA,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,gBAAgB,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC;IAEpF;IAIU,mBAAmB,GAAA;QAE3B,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,gBAAgB,EAAE,EAAE,CAAC;IAEnD;IAEU,oBAAoB,GAAA;AAC5B,QAAA,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;AAC7E,QAAA,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,eAAe,EAAE;YAAE;AAExC,QAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC;AACvC,YAAA,IAAI,EAAE,CAAC,IAAI,KAAI;AACb,gBAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC;AAC/B,gBAAA,IAAI,IAAI,CAAC,iBAAiB,EAAE;AAC1B,oBAAA,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE;oBAC9B,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC;AAC/C,oBAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI;gBAC/B;gBACA,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC;AACrC,gBAAA,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,GAAG,CAAC;AAC5B,gBAAA,IAAI,CAAC,iBAAiB,GAAG,KAAK;AAC9B,gBAAA,KAAK,CAAC,OAAO,GAAG,MAAK;AACnB,oBAAA,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC;AACxB,oBAAA,IAAI,IAAI,CAAC,iBAAiB,KAAK,KAAK;AAAE,wBAAA,IAAI,CAAC,iBAAiB,GAAG,IAAI;AACrE,gBAAA,CAAC;gBACD,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,MAAK;oBAC3B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,+CAA+C,EAAE,OAAO,CAAC;AACzE,oBAAA,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC;AAC1B,gBAAA,CAAC,CAAC;YACJ,CAAC;YACD,KAAK,EAAE,MAAK;AACV,gBAAA,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,KAAK,CAAC;gBAC/B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,8CAA8C,EAAE,OAAO,CAAC;YAC1E,CAAC;AACF,SAAA,CAAC;IACJ;IAIU,UAAU,CAAC,OAAoB,EAAE,GAAW,EAAA;AAEpD,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE;AAEzB,QAAA,IAAI,CAAC,CAAC,IAAI,OAAO,KAAK,QAAQ;AAAE,YAAA,OAAO,EAAE;AAEzC,QAAA,OAAQ,CAAC,CAAC,OAAO,CAA+C,CAAC,GAAG,CAAC;IAEvE;IAIU,IAAI,GAAA;AAEZ,QAAA,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE;AAEzB,QAAA,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB;AAElC,QAAA,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI;YAAE;AAIjB,QAAA,MAAM,OAAO,GAAG,eAAe,CAAC,CAAC,CAAC;AAElC,QAAA,MAAM,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;AAEjE,QAAA,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC,GAAG,EAAE;AAEtC,QAAA,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,IAAI,CAAC;AAIzC,QAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;QAErB,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC;AAEtC,YAAA,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,KAAI;AAEjB,gBAAA,IAAI,CAAC,gBAAgB,GAAG,eAAe,CAAC,IAAI,CAAC;gBAE7C,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;AAExC,gBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;AAEtB,gBAAA,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;gBAEpB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,sBAAsB,EAAE,SAAS,CAAC;AAElD,gBAAA,UAAU,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC;YAE/C,CAAC;YAED,KAAK,EAAE,MAAK;AAEV,gBAAA,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;gBAEtB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,+BAA+B,EAAE,OAAO,CAAC;YAE3D,CAAC;AAEF,SAAA,CAAC;IAEJ;IAEQ,qBAAqB,CAAC,OAAsB,EAAE,IAAmB,EAAA;AACvE,QAAA,MAAM,gBAAgB,GAAsB;YAC1C,SAAS;YACT,OAAO;YACP,OAAO;YACP,YAAY;YACZ,QAAQ;YACR,QAAQ;YACR,YAAY;YACZ,UAAU;YACV,aAAa;YACb,UAAU;SACX;AAED,QAAA,KAAK,MAAM,UAAU,IAAI,gBAAgB,EAAE;AACzC,YAAA,IAAI,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE;gBACtC,OAAO,CAAC,UAAU,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;gBACvD;YACF;AAEA,YAAA,MAAM,cAAc,GAAG,OAAO,CAAC,UAAU,CAA8C;AACvF,YAAA,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAA8C;YACjF,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,EAAE;AAC7C,gBAAA,IAAI,eAAe,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE;oBACpC,cAAc,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC;gBACxC;YACF;QACF;IACF;+GA7YW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;mGAArB,qBAAqB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC7DlC,yrcA6SA,EAAA,MAAA,EAAA,CAAA,62OAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EDtPc,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,cAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,uBAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,iGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,4BAAA,EAAA,QAAA,EAAA,uGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,0BAAA,EAAA,QAAA,EAAA,6GAAA,EAAA,MAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,4EAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,qDAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,SAAA,EAAA,gBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,QAAA,EAAA,CAAA,SAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,UAAU,EAAA,QAAA,EAAA,cAAA,EAAA,MAAA,EAAA,CAAA,QAAA,EAAA,aAAA,EAAA,UAAA,EAAA,qBAAA,EAAA,OAAA,EAAA,MAAA,EAAA,YAAA,EAAA,kBAAA,EAAA,oBAAA,EAAA,YAAA,EAAA,YAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,iBAAiB,EAAA,QAAA,EAAA,WAAA,EAAA,MAAA,EAAA,CAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,kBAAkB,EAAA,QAAA,EAAA,YAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,MAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAE,gBAAgB,EAAA,QAAA,EAAA,UAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,QAAA,CAAA,EAAA,CAAA,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;4FAMjF,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBARjC,SAAS;AACI,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,mBAAmB,EAAA,OAAA,EACpB,CAAC,WAAW,EAAE,UAAU,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,CAAC,EAAA,eAAA,EAG1E,uBAAuB,CAAC,MAAM,EAAA,QAAA,EAAA,yrcAAA,EAAA,MAAA,EAAA,CAAA,62OAAA,CAAA,EAAA;;;;;"}
@@ -1,52 +0,0 @@
1
- const TASK_TYPE_OPTIONS = [
2
- 'Refill request',
3
- 'Callback',
4
- 'Billing',
5
- 'Scheduling',
6
- 'Clinical',
7
- 'Other',
8
- ];
9
- function taskStatusLabel(status) {
10
- if (status === 'in_progress')
11
- return 'In progress';
12
- if (status === 'done')
13
- return 'Done';
14
- return 'Open';
15
- }
16
- function taskStatusTone(status) {
17
- const map = {
18
- open: 'brand',
19
- in_progress: 'notice',
20
- done: 'pos',
21
- };
22
- return map[status];
23
- }
24
- function taskPriorityTone(priority) {
25
- return priority === 'urgent' ? 'neg' : 'gray';
26
- }
27
- function taskPriorityLabel(priority) {
28
- return priority === 'urgent' ? 'Urgent' : 'Normal';
29
- }
30
- function taskSourceLabel(source) {
31
- if (source === 'voice')
32
- return 'Voice';
33
- if (source === 'sync')
34
- return 'Sync';
35
- return 'Manual';
36
- }
37
- function taskTypeTone(type) {
38
- const key = type.toLowerCase();
39
- if (key.includes('refill'))
40
- return 'violet';
41
- if (key.includes('callback'))
42
- return 'brand';
43
- if (key.includes('billing'))
44
- return 'notice';
45
- return 'gray';
46
- }
47
- function taskCallRoute(callId) {
48
- return callId.startsWith('LC') ? ['../live', callId] : ['../history', callId];
49
- }
50
-
51
- export { TASK_TYPE_OPTIONS as T, taskStatusTone as a, taskTypeTone as b, taskPriorityLabel as c, taskPriorityTone as d, taskSourceLabel as e, taskCallRoute as f, taskStatusLabel as t };
52
- //# sourceMappingURL=edvak99-voice-receptionist-widget-task.util-DdtI0CR3.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"edvak99-voice-receptionist-widget-task.util-DdtI0CR3.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/utils/task.util.ts"],"sourcesContent":["import { BadgeTone } from '../ui/eds-badge.component';\nimport { TaskPriority, TaskSource, TaskStatus } from '../models/ai-receptionist.types';\n\nexport const TASK_TYPE_OPTIONS = [\n 'Refill request',\n 'Callback',\n 'Billing',\n 'Scheduling',\n 'Clinical',\n 'Other',\n] as const;\n\nexport function taskStatusLabel(status: TaskStatus): string {\n if (status === 'in_progress') return 'In progress';\n if (status === 'done') return 'Done';\n return 'Open';\n}\n\nexport function taskStatusTone(status: TaskStatus): BadgeTone {\n const map: Record<TaskStatus, BadgeTone> = {\n open: 'brand',\n in_progress: 'notice',\n done: 'pos',\n };\n return map[status];\n}\n\nexport function taskPriorityTone(priority: TaskPriority): BadgeTone {\n return priority === 'urgent' ? 'neg' : 'gray';\n}\n\nexport function taskPriorityLabel(priority: TaskPriority): string {\n return priority === 'urgent' ? 'Urgent' : 'Normal';\n}\n\nexport function taskSourceLabel(source: TaskSource): string {\n if (source === 'voice') return 'Voice';\n if (source === 'sync') return 'Sync';\n return 'Manual';\n}\n\nexport function taskTypeTone(type: string): BadgeTone {\n const key = type.toLowerCase();\n if (key.includes('refill')) return 'violet';\n if (key.includes('callback')) return 'brand';\n if (key.includes('billing')) return 'notice';\n return 'gray';\n}\n\nexport function taskCallRoute(callId: string): string[] {\n return callId.startsWith('LC') ? ['../live', callId] : ['../history', callId];\n}\n"],"names":[],"mappings":"AAGO,MAAM,iBAAiB,GAAG;IAC/B,gBAAgB;IAChB,UAAU;IACV,SAAS;IACT,YAAY;IACZ,UAAU;IACV,OAAO;;AAGH,SAAU,eAAe,CAAC,MAAkB,EAAA;IAChD,IAAI,MAAM,KAAK,aAAa;AAAE,QAAA,OAAO,aAAa;IAClD,IAAI,MAAM,KAAK,MAAM;AAAE,QAAA,OAAO,MAAM;AACpC,IAAA,OAAO,MAAM;AACf;AAEM,SAAU,cAAc,CAAC,MAAkB,EAAA;AAC/C,IAAA,MAAM,GAAG,GAAkC;AACzC,QAAA,IAAI,EAAE,OAAO;AACb,QAAA,WAAW,EAAE,QAAQ;AACrB,QAAA,IAAI,EAAE,KAAK;KACZ;AACD,IAAA,OAAO,GAAG,CAAC,MAAM,CAAC;AACpB;AAEM,SAAU,gBAAgB,CAAC,QAAsB,EAAA;IACrD,OAAO,QAAQ,KAAK,QAAQ,GAAG,KAAK,GAAG,MAAM;AAC/C;AAEM,SAAU,iBAAiB,CAAC,QAAsB,EAAA;IACtD,OAAO,QAAQ,KAAK,QAAQ,GAAG,QAAQ,GAAG,QAAQ;AACpD;AAEM,SAAU,eAAe,CAAC,MAAkB,EAAA;IAChD,IAAI,MAAM,KAAK,OAAO;AAAE,QAAA,OAAO,OAAO;IACtC,IAAI,MAAM,KAAK,MAAM;AAAE,QAAA,OAAO,MAAM;AACpC,IAAA,OAAO,QAAQ;AACjB;AAEM,SAAU,YAAY,CAAC,IAAY,EAAA;AACvC,IAAA,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE;AAC9B,IAAA,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;AAAE,QAAA,OAAO,QAAQ;AAC3C,IAAA,IAAI,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC;AAAE,QAAA,OAAO,OAAO;AAC5C,IAAA,IAAI,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC;AAAE,QAAA,OAAO,QAAQ;AAC5C,IAAA,OAAO,MAAM;AACf;AAEM,SAAU,aAAa,CAAC,MAAc,EAAA;IAC1C,OAAO,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,MAAM,CAAC;AAC/E;;;;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"edvak99-voice-receptionist-widget-tasks-page.component-DXxjMVUv.mjs","sources":["../../../projects/voice-receptionist-widget/src/lib/shared/copy-button.component.ts","../../../projects/voice-receptionist-widget/src/lib/components/task-detail-drawer/task-detail-drawer.component.ts","../../../projects/voice-receptionist-widget/src/lib/components/task-detail-drawer/task-detail-drawer.component.html","../../../projects/voice-receptionist-widget/src/lib/pages/tasks-page/tasks-page.component.ts","../../../projects/voice-receptionist-widget/src/lib/pages/tasks-page/tasks-page.component.html"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n Input,\n inject,\n signal,\n} from '@angular/core';\n\nimport { ToastService } from './toast.service';\n\n@Component({\n selector: 'app-copy-btn',\n standalone: true,\n template: `\n @if (copyValue) {\n <button\n type=\"button\"\n class=\"copy-btn\"\n (click)=\"onCopy($event)\"\n [attr.aria-label]=\"ariaLabel\"\n [title]=\"copied() ? 'Copied' : 'Copy to clipboard'\"\n >\n @if (copied()) {\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2.2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n } @else {\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">\n <rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\" />\n <path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\" />\n </svg>\n }\n </button>\n }\n `,\n styleUrl: './copy-button.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class CopyButtonComponent {\n /** Raw value to copy (full ID / phone / etc.) */\n @Input() value: string | null | undefined = '';\n /** Accessible label, e.g. \"patient ID\" */\n @Input() label = 'value';\n\n private readonly toast = inject(ToastService);\n\n protected readonly copied = signal(false);\n\n protected get copyValue(): string {\n const v = this.value?.trim();\n return v && v !== '—' ? v : '';\n }\n\n protected get ariaLabel(): string {\n return this.copied() ? 'Copied' : `Copy ${this.label}`;\n }\n\n async onCopy(event: MouseEvent): Promise<void> {\n event.stopPropagation();\n const text = this.copyValue;\n if (!text) return;\n\n try {\n await navigator.clipboard.writeText(text);\n this.copied.set(true);\n setTimeout(() => this.copied.set(false), 1500);\n } catch {\n this.toast.show('Could not copy — clipboard unavailable', 'error', 2500);\n }\n }\n}\n","import { DatePipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n input,\n output,\n} from '@angular/core';\nimport { RouterLink } from '@angular/router';\n\nimport { TaskItem, TaskStatus } from '../../models/ai-receptionist.types';\nimport { CopyButtonComponent } from '../../shared/copy-button.component';\nimport { EdsBadgeComponent } from '../../ui/eds-badge.component';\nimport { EdsButtonComponent } from '../../ui/eds-button.component';\nimport { EdsIconComponent } from '../../ui/eds-icon.component';\nimport {\n taskCallRoute,\n taskPriorityLabel,\n taskPriorityTone,\n taskSourceLabel,\n taskStatusLabel,\n taskStatusTone,\n taskTypeTone,\n} from '../../utils/task.util';\n\n@Component({\n selector: 'eds-task-detail-drawer',\n imports: [\n DatePipe,\n RouterLink,\n CopyButtonComponent,\n EdsBadgeComponent,\n EdsButtonComponent,\n EdsIconComponent,\n ],\n templateUrl: './task-detail-drawer.component.html',\n styleUrl: './task-detail-drawer.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class TaskDetailDrawerComponent {\n readonly task = input.required<TaskItem>();\n\n readonly closed = output<void>();\n readonly statusChange = output<TaskStatus>();\n\n protected readonly taskStatusLabel = taskStatusLabel;\n protected readonly taskStatusTone = taskStatusTone;\n protected readonly taskPriorityLabel = taskPriorityLabel;\n protected readonly taskPriorityTone = taskPriorityTone;\n protected readonly taskSourceLabel = taskSourceLabel;\n protected readonly taskTypeTone = taskTypeTone;\n protected readonly taskCallRoute = taskCallRoute;\n\n protected close(): void {\n this.closed.emit();\n }\n\n protected markDone(): void {\n const t = this.task();\n this.statusChange.emit(t.status === 'done' ? 'open' : 'done');\n }\n\n protected onBackdropClick(event: MouseEvent): void {\n if (event.target === event.currentTarget) this.close();\n }\n}\n","<div class=\"task-drawer__backdrop\" (click)=\"onBackdropClick($event)\">\n <aside class=\"task-drawer\" role=\"dialog\" aria-modal=\"true\" [attr.aria-label]=\"task().title\">\n <header class=\"task-drawer__head\">\n <div>\n <eds-badge [tone]=\"taskTypeTone(task().type)\">{{ task().type }}</eds-badge>\n <h2 class=\"task-drawer__title\">{{ task().title }}</h2>\n </div>\n <button type=\"button\" class=\"task-drawer__close\" (click)=\"close()\" aria-label=\"Close\">\n <eds-icon name=\"close\" [size]=\"22\" />\n </button>\n </header>\n\n <div class=\"task-drawer__body\">\n <section class=\"task-drawer__section\">\n <h3 class=\"eds-label\">Description</h3>\n <p class=\"task-drawer__description\">{{ task().description || '—' }}</p>\n </section>\n\n <dl class=\"task-drawer__meta\">\n <div>\n <dt class=\"eds-label\">Patient</dt>\n <dd>{{ task().patient }}</dd>\n </div>\n <div>\n <dt class=\"eds-label\">Assignee</dt>\n <dd>{{ task().assignee }}</dd>\n </div>\n <div>\n <dt class=\"eds-label\">Status</dt>\n <dd><eds-badge [tone]=\"taskStatusTone(task().status)\">{{ taskStatusLabel(task().status) }}</eds-badge></dd>\n </div>\n <div>\n <dt class=\"eds-label\">Priority</dt>\n <dd><eds-badge [tone]=\"taskPriorityTone(task().priority)\">{{ taskPriorityLabel(task().priority) }}</eds-badge></dd>\n </div>\n <div>\n <dt class=\"eds-label\">Source</dt>\n <dd>{{ taskSourceLabel(task().source) }}</dd>\n </div>\n <div>\n <dt class=\"eds-label\">Created</dt>\n <dd>{{ task().created | date: 'medium' }}</dd>\n </div>\n <div>\n <dt class=\"eds-label\">Call</dt>\n <dd>\n @if (task().callId) {\n <a [routerLink]=\"taskCallRoute(task().callId!)\" class=\"task-drawer__link\">{{ task().callId }}</a>\n } @else {\n —\n }\n </dd>\n </div>\n </dl>\n\n @if (task().edvakTaskId || task().edvakStatus || task().medicationName || task().medicationId) {\n <section class=\"task-drawer__section task-drawer__section--edvak\">\n <h3 class=\"eds-label\">Edvak / refill details</h3>\n <dl class=\"task-drawer__meta\">\n @if (task().edvakTaskId) {\n <div>\n <dt class=\"eds-label\">Edvak task ID</dt>\n <dd class=\"task-drawer__copy-row\">\n <code>{{ task().edvakTaskId }}</code>\n <app-copy-btn [value]=\"task().edvakTaskId\" label=\"Edvak task ID\" />\n </dd>\n </div>\n }\n @if (task().edvakStatus) {\n <div>\n <dt class=\"eds-label\">Edvak status</dt>\n <dd><eds-badge tone=\"brand\">{{ task().edvakStatus }}</eds-badge></dd>\n </div>\n }\n @if (task().medicationName) {\n <div>\n <dt class=\"eds-label\">Medication</dt>\n <dd>{{ task().medicationName }}</dd>\n </div>\n }\n @if (task().medicationId) {\n <div>\n <dt class=\"eds-label\">Medication ID</dt>\n <dd class=\"task-drawer__copy-row\">\n <code>{{ task().medicationId }}</code>\n <app-copy-btn [value]=\"task().medicationId\" label=\"medication ID\" />\n </dd>\n </div>\n }\n </dl>\n </section>\n }\n </div>\n\n <footer class=\"task-drawer__foot\">\n <eds-button variant=\"secondary\" type=\"button\" (click)=\"markDone()\">\n {{ task().status === 'done' ? 'Reopen task' : 'Mark done' }}\n </eds-button>\n </footer>\n </aside>\n</div>\n","import { DatePipe } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n Component,\n computed,\n inject,\n OnInit,\n signal,\n} from '@angular/core';\nimport { ActivatedRoute, RouterLink } from '@angular/router';\n\nimport { TaskDetailDrawerComponent } from '../../components/task-detail-drawer/task-detail-drawer.component';\nimport {\n TaskFilters,\n TaskItem,\n TaskSource,\n TaskStatus,\n} from '../../models/ai-receptionist.types';\nimport { DEFAULT_PAGE_SIZE, totalPages as calcTotalPages } from '../../models/pagination';\nimport { AiReceptionistApiService } from '../../services/ai-receptionist-api.service';\nimport { EdsBadgeComponent } from '../../ui/eds-badge.component';\nimport { EdsButtonComponent } from '../../ui/eds-button.component';\nimport {\n TASK_TYPE_OPTIONS,\n taskCallRoute,\n taskPriorityTone,\n taskSourceLabel,\n taskStatusLabel,\n taskStatusTone,\n taskTypeTone,\n} from '../../utils/task.util';\n\n@Component({\n selector: 'eds-tasks-page',\n imports: [\n DatePipe,\n RouterLink,\n EdsBadgeComponent,\n EdsButtonComponent,\n TaskDetailDrawerComponent,\n ],\n templateUrl: './tasks-page.component.html',\n styleUrl: './tasks-page.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class TasksPageComponent implements OnInit {\n private readonly api = inject(AiReceptionistApiService);\n private readonly route = inject(ActivatedRoute);\n\n protected readonly pageSize = DEFAULT_PAGE_SIZE;\n protected readonly tasks = signal<TaskItem[]>([]);\n protected readonly total = signal(0);\n protected readonly page = signal(1);\n protected readonly loading = signal(true);\n protected readonly selectedTask = signal<TaskItem | null>(null);\n\n protected readonly statusFilter = signal<'' | TaskStatus>('');\n protected readonly typeFilter = signal('');\n protected readonly sourceFilter = signal<'' | TaskSource>('');\n protected readonly callIdFilter = signal('');\n\n protected readonly typeOptions = TASK_TYPE_OPTIONS;\n protected readonly taskStatusLabel = taskStatusLabel;\n protected readonly taskStatusTone = taskStatusTone;\n protected readonly taskPriorityTone = taskPriorityTone;\n protected readonly taskSourceLabel = taskSourceLabel;\n protected readonly taskTypeTone = taskTypeTone;\n protected readonly taskCallRoute = taskCallRoute;\n\n protected readonly hasActiveFilters = computed(\n () =>\n !!this.statusFilter() ||\n !!this.typeFilter() ||\n !!this.sourceFilter() ||\n !!this.callIdFilter(),\n );\n\n ngOnInit(): void {\n const callId = this.route.snapshot.queryParamMap.get('callId') ?? '';\n if (callId) this.callIdFilter.set(callId);\n this.load();\n }\n\n protected setStatusFilter(value: string): void {\n this.statusFilter.set(value as '' | TaskStatus);\n this.page.set(1);\n this.load();\n }\n\n protected setTypeFilter(value: string): void {\n this.typeFilter.set(value);\n this.page.set(1);\n this.load();\n }\n\n protected setSourceFilter(value: string): void {\n this.sourceFilter.set(value as '' | TaskSource);\n this.page.set(1);\n this.load();\n }\n\n protected setCallIdFilter(value: string): void {\n this.callIdFilter.set(value);\n this.page.set(1);\n this.load();\n }\n\n protected clearFilters(): void {\n this.statusFilter.set('');\n this.typeFilter.set('');\n this.sourceFilter.set('');\n this.callIdFilter.set('');\n this.page.set(1);\n this.load();\n }\n\n protected openTask(task: TaskItem): void {\n this.selectedTask.set(task);\n }\n\n protected closeDrawer(): void {\n this.selectedTask.set(null);\n }\n\n protected onStatusChange(status: TaskStatus): void {\n const task = this.selectedTask();\n if (!task) return;\n this.api.patchTask(task.id, status).subscribe(({ data }) => {\n if (data) {\n this.selectedTask.set(data);\n this.tasks.update((rows) => rows.map((r) => (r.id === data.id ? data : r)));\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 private load(): void {\n this.loading.set(true);\n const filters: TaskFilters = {\n page: this.page(),\n limit: DEFAULT_PAGE_SIZE,\n };\n if (this.statusFilter()) filters.status = this.statusFilter() as TaskStatus;\n if (this.typeFilter()) filters.type = this.typeFilter();\n if (this.sourceFilter()) filters.source = this.sourceFilter() as TaskSource;\n if (this.callIdFilter().trim()) filters.callId = this.callIdFilter().trim();\n\n this.api.getTasks(filters).subscribe({\n next: ({ items, total, page }) => {\n this.tasks.set(items);\n this.total.set(total);\n this.page.set(page);\n this.loading.set(false);\n },\n error: () => this.loading.set(false),\n });\n }\n}\n","<div class=\"eds-page tasks-page\">\n <header class=\"tasks-page__header\">\n <div>\n <h1 class=\"eds-h1\">Tasks & follow-ups</h1>\n <p class=\"eds-body-sm\">Action items from calls — all types, not just refills</p>\n </div>\n </header>\n\n <section class=\"list-section\">\n <div class=\"list-toolbar\">\n <div class=\"filter-group\">\n <label for=\"task-status\">Status</label>\n <select\n id=\"task-status\"\n class=\"filter-input\"\n [value]=\"statusFilter()\"\n (change)=\"setStatusFilter($any($event.target).value)\"\n >\n <option value=\"\">All</option>\n <option value=\"open\">Open</option>\n <option value=\"in_progress\">In progress</option>\n <option value=\"done\">Done</option>\n </select>\n </div>\n <div class=\"filter-group\">\n <label for=\"task-type\">Type</label>\n <select\n id=\"task-type\"\n class=\"filter-input\"\n [value]=\"typeFilter()\"\n (change)=\"setTypeFilter($any($event.target).value)\"\n >\n <option value=\"\">All types</option>\n @for (t of typeOptions; track t) {\n <option [value]=\"t\">{{ t }}</option>\n }\n </select>\n </div>\n <div class=\"filter-group\">\n <label for=\"task-source\">Source</label>\n <select\n id=\"task-source\"\n class=\"filter-input\"\n [value]=\"sourceFilter()\"\n (change)=\"setSourceFilter($any($event.target).value)\"\n >\n <option value=\"\">All sources</option>\n <option value=\"voice\">Voice</option>\n <option value=\"sync\">Sync</option>\n <option value=\"manual\">Manual</option>\n </select>\n </div>\n <div class=\"filter-group\">\n <label for=\"task-call\">Call ID</label>\n <input\n id=\"task-call\"\n type=\"text\"\n class=\"filter-input\"\n [value]=\"callIdFilter()\"\n placeholder=\"Filter by call\"\n (change)=\"setCallIdFilter($any($event.target).value)\"\n />\n </div>\n @if (hasActiveFilters()) {\n <button type=\"button\" class=\"link-btn\" (click)=\"clearFilters()\">Clear filters</button>\n }\n </div>\n\n @if (loading()) {\n <p class=\"eds-body-sm tasks-page__loading\">Loading tasks…</p>\n } @else {\n <div class=\"table-wrap\">\n <table class=\"data-table\">\n <thead>\n <tr>\n <th>Created</th>\n <th>Title</th>\n <th>Type</th>\n <th>Patient</th>\n <th>Priority</th>\n <th>Status</th>\n <th>Source</th>\n <th>Call</th>\n </tr>\n </thead>\n <tbody>\n @for (task of tasks(); track task.id) {\n <tr class=\"tasks-page__row\" (click)=\"openTask(task)\">\n <td class=\"cell-muted\">{{ task.created | date: 'MM/dd/yy, h:mm a' }}</td>\n <td class=\"tasks-page__title-cell\">{{ task.title }}</td>\n <td><eds-badge [tone]=\"taskTypeTone(task.type)\">{{ task.type }}</eds-badge></td>\n <td>{{ task.patient }}</td>\n <td>\n <eds-badge [tone]=\"taskPriorityTone(task.priority)\">\n {{ task.priority === 'urgent' ? 'Urgent' : 'Normal' }}\n </eds-badge>\n </td>\n <td><eds-badge [tone]=\"taskStatusTone(task.status)\">{{ taskStatusLabel(task.status) }}</eds-badge></td>\n <td class=\"cell-muted\">{{ taskSourceLabel(task.source) }}</td>\n <td (click)=\"$event.stopPropagation()\">\n @if (task.callId) {\n <a [routerLink]=\"taskCallRoute(task.callId)\" class=\"link-btn\">{{ task.callId }}</a>\n } @else {\n <span class=\"cell-muted\">—</span>\n }\n </td>\n </tr>\n } @empty {\n <tr>\n <td colspan=\"8\" class=\"empty-state\">No tasks match these filters.</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n\n <footer class=\"pagination\">\n <span>Page {{ page() }} of {{ totalPages() }} · {{ total() }} total</span>\n <div class=\"pagination-btns\">\n <eds-button variant=\"secondary\" [disabled]=\"page() <= 1\" (click)=\"prevPage()\">Previous</eds-button>\n <eds-button variant=\"secondary\" [disabled]=\"page() >= totalPages()\" (click)=\"nextPage()\">Next</eds-button>\n </div>\n </footer>\n </section>\n</div>\n\n@if (selectedTask(); as task) {\n <eds-task-detail-drawer\n [task]=\"task\"\n (closed)=\"closeDrawer()\"\n (statusChange)=\"onStatusChange($event)\"\n />\n}"],"names":["calcTotalPages"],"mappings":"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"}
@@ -1,22 +0,0 @@
1
- import { EventEmitter } from '@angular/core';
2
- import { FAQ_STARTER_TEMPLATES } from '../../models/practice-faq.model';
3
- import * as i0 from "@angular/core";
4
- export declare class FaqEmptyStateComponent {
5
- protected readonly starters: {
6
- label: string;
7
- question: string;
8
- answer: string;
9
- category: string;
10
- }[];
11
- readonly add: EventEmitter<void>;
12
- readonly useTemplate: EventEmitter<{
13
- label: string;
14
- question: string;
15
- answer: string;
16
- category: string;
17
- }>;
18
- protected onAdd(): void;
19
- protected onTemplate(t: (typeof FAQ_STARTER_TEMPLATES)[number]): void;
20
- static ɵfac: i0.ɵɵFactoryDeclaration<FaqEmptyStateComponent, never>;
21
- static ɵcmp: i0.ɵɵComponentDeclaration<FaqEmptyStateComponent, "eds-faq-empty-state", never, {}, { "add": "add"; "useTemplate": "useTemplate"; }, never, never, true, never>;
22
- }
@@ -1,27 +0,0 @@
1
- import { EventEmitter, OnChanges } from '@angular/core';
2
- import { CreatePracticeFaqRequest, PracticeFaq, UpdatePracticeFaqRequest } from '../../models/practice-faq.model';
3
- import * as i0 from "@angular/core";
4
- export declare class FaqFormComponent implements OnChanges {
5
- open: boolean;
6
- faq: PracticeFaq | null;
7
- initialQuestion: string;
8
- initialAnswer: string;
9
- initialCategory: string;
10
- readonly closed: EventEmitter<void>;
11
- readonly saved: EventEmitter<CreatePracticeFaqRequest | UpdatePracticeFaqRequest>;
12
- protected readonly categories: readonly ["hours", "location", "parking", "insurance", "services", "policies", "general"];
13
- protected readonly saving: import("@angular/core").WritableSignal<boolean>;
14
- protected readonly error: import("@angular/core").WritableSignal<string | null>;
15
- protected question: string;
16
- protected answer: string;
17
- protected category: string;
18
- protected sortOrder: number;
19
- protected isActive: boolean;
20
- protected get isEdit(): boolean;
21
- ngOnChanges(): void;
22
- protected close(): void;
23
- protected submit(): void;
24
- private resetForm;
25
- static ɵfac: i0.ɵɵFactoryDeclaration<FaqFormComponent, never>;
26
- static ɵcmp: i0.ɵɵComponentDeclaration<FaqFormComponent, "eds-faq-form", never, { "open": { "alias": "open"; "required": false; }; "faq": { "alias": "faq"; "required": false; }; "initialQuestion": { "alias": "initialQuestion"; "required": false; }; "initialAnswer": { "alias": "initialAnswer"; "required": false; }; "initialCategory": { "alias": "initialCategory"; "required": false; }; }, { "closed": "closed"; "saved": "saved"; }, never, never, true, never>;
27
- }
@@ -1,17 +0,0 @@
1
- import { PracticeFaqSearchItem } from '../../models/practice-faq.model';
2
- import { categoryBadgeClass, scorePercent } from '../../utils/faq.util';
3
- import * as i0 from "@angular/core";
4
- export declare class FaqSearchTesterComponent {
5
- private readonly api;
6
- protected query: string;
7
- protected readonly loading: import("@angular/core").WritableSignal<boolean>;
8
- protected readonly searched: import("@angular/core").WritableSignal<boolean>;
9
- protected readonly found: import("@angular/core").WritableSignal<boolean>;
10
- protected readonly results: import("@angular/core").WritableSignal<PracticeFaqSearchItem[]>;
11
- protected readonly error: import("@angular/core").WritableSignal<string | null>;
12
- protected categoryClass: typeof categoryBadgeClass;
13
- protected scorePercent: typeof scorePercent;
14
- protected search(): void;
15
- static ɵfac: i0.ɵɵFactoryDeclaration<FaqSearchTesterComponent, never>;
16
- static ɵcmp: i0.ɵɵComponentDeclaration<FaqSearchTesterComponent, "eds-faq-search-tester", never, {}, {}, never, never, true, never>;
17
- }
@@ -1,2 +0,0 @@
1
- import { PracticeFaq } from '../models/practice-faq.model';
2
- export declare const SEED_PRACTICE_FAQS: PracticeFaq[];
@@ -1,50 +0,0 @@
1
- export interface PracticeFaq {
2
- faqId: string;
3
- question: string;
4
- answer: string;
5
- category: string | null;
6
- sortOrder: number;
7
- isActive: boolean;
8
- hasEmbedding: boolean;
9
- createdAt: string;
10
- updatedAt: string;
11
- }
12
- export interface CreatePracticeFaqRequest {
13
- question: string;
14
- answer: string;
15
- category?: string;
16
- sortOrder?: number;
17
- isActive?: boolean;
18
- }
19
- export interface UpdatePracticeFaqRequest {
20
- question?: string;
21
- answer?: string;
22
- category?: string | null;
23
- sortOrder?: number;
24
- isActive?: boolean;
25
- }
26
- export interface PracticeFaqSearchResult {
27
- found: boolean;
28
- items: PracticeFaqSearchItem[];
29
- }
30
- export interface PracticeFaqSearchItem {
31
- faqId: string;
32
- question: string;
33
- answer: string;
34
- category: string | null;
35
- score: number;
36
- }
37
- export interface PracticeFaqListResponse {
38
- items: PracticeFaq[];
39
- total?: number;
40
- page?: number;
41
- limit?: number;
42
- }
43
- export type FaqActiveFilter = 'all' | 'active' | 'inactive';
44
- export declare const FAQ_CATEGORY_PRESETS: readonly ["hours", "location", "parking", "insurance", "services", "policies", "general"];
45
- export declare const FAQ_STARTER_TEMPLATES: Array<{
46
- label: string;
47
- question: string;
48
- answer: string;
49
- category: string;
50
- }>;
@@ -1,54 +0,0 @@
1
- import { OnInit } from '@angular/core';
2
- import { CreatePracticeFaqRequest, FaqActiveFilter, PracticeFaq, UpdatePracticeFaqRequest } from '../models/practice-faq.model';
3
- import { categoryBadgeClass, truncateText } from '../utils/faq.util';
4
- import * as i0 from "@angular/core";
5
- export declare class KnowledgeHubPageComponent implements OnInit {
6
- private readonly api;
7
- private readonly toast;
8
- protected readonly pageSize = 50;
9
- protected readonly pageFaqs: import("@angular/core").WritableSignal<PracticeFaq[]>;
10
- protected readonly total: import("@angular/core").WritableSignal<number>;
11
- protected readonly page: import("@angular/core").WritableSignal<number>;
12
- protected readonly loading: import("@angular/core").WritableSignal<boolean>;
13
- protected readonly error: import("@angular/core").WritableSignal<string | null>;
14
- protected readonly activeFilter: import("@angular/core").WritableSignal<FaqActiveFilter>;
15
- protected readonly categoryFilter: import("@angular/core").WritableSignal<string>;
16
- protected readonly listSearch: import("@angular/core").WritableSignal<string>;
17
- protected readonly formOpen: import("@angular/core").WritableSignal<boolean>;
18
- protected readonly editing: import("@angular/core").WritableSignal<PracticeFaq | null>;
19
- protected readonly formSeed: import("@angular/core").WritableSignal<{
20
- question: string;
21
- answer: string;
22
- category: string;
23
- }>;
24
- protected readonly categories: readonly ["hours", "location", "parking", "insurance", "services", "policies", "general"];
25
- protected readonly activeTabs: {
26
- id: FaqActiveFilter;
27
- label: string;
28
- }[];
29
- /** Client filters still applied on the current page (category / local search / inactive). */
30
- protected readonly faqs: import("@angular/core").Signal<PracticeFaq[]>;
31
- protected categoryClass: typeof categoryBadgeClass;
32
- protected truncate: typeof truncateText;
33
- ngOnInit(): void;
34
- protected load(): void;
35
- protected setActiveFilter(id: FaqActiveFilter): void;
36
- protected toggleCategory(cat: string): void;
37
- protected isCategorySelected(cat: string): boolean;
38
- protected totalPages(): number;
39
- protected prevPage(): void;
40
- protected nextPage(): void;
41
- protected openCreate(): void;
42
- protected openEdit(faq: PracticeFaq): void;
43
- protected closeForm(): void;
44
- protected onStarterTemplate(t: {
45
- question: string;
46
- answer: string;
47
- category: string;
48
- }): void;
49
- protected onSave(payload: CreatePracticeFaqRequest | UpdatePracticeFaqRequest): void;
50
- protected toggleActive(faq: PracticeFaq, active: boolean): void;
51
- protected deleteFaq(faq: PracticeFaq): void;
52
- static ɵfac: i0.ɵɵFactoryDeclaration<KnowledgeHubPageComponent, never>;
53
- static ɵcmp: i0.ɵɵComponentDeclaration<KnowledgeHubPageComponent, "eds-knowledge-hub-page", never, {}, {}, never, never, true, never>;
54
- }
@@ -1,16 +0,0 @@
1
- import { Observable } from 'rxjs';
2
- import { CreatePracticeFaqRequest, PracticeFaq, PracticeFaqSearchResult, UpdatePracticeFaqRequest } from '../models/practice-faq.model';
3
- import * as i0 from "@angular/core";
4
- export declare class PracticeFaqApiMockService {
5
- private readonly faqs;
6
- list(activeOnly?: boolean): Observable<PracticeFaq[]>;
7
- get(faqId: string): Observable<PracticeFaq | null>;
8
- create(body: CreatePracticeFaqRequest): Observable<PracticeFaq>;
9
- update(faqId: string, body: UpdatePracticeFaqRequest): Observable<PracticeFaq>;
10
- delete(faqId: string): Observable<{
11
- success: boolean;
12
- }>;
13
- search(q: string, limit?: number): Observable<PracticeFaqSearchResult>;
14
- static ɵfac: i0.ɵɵFactoryDeclaration<PracticeFaqApiMockService, never>;
15
- static ɵprov: i0.ɵɵInjectableDeclaration<PracticeFaqApiMockService>;
16
- }
@@ -1,26 +0,0 @@
1
- import { Observable } from 'rxjs';
2
- import { type PaginatedResult } from '../../models/pagination';
3
- import { CreatePracticeFaqRequest, PracticeFaq, PracticeFaqSearchResult, UpdatePracticeFaqRequest } from '../models/practice-faq.model';
4
- import * as i0 from "@angular/core";
5
- export declare class PracticeFaqApiService {
6
- private readonly http;
7
- private readonly mock;
8
- private readonly config;
9
- private readonly paths;
10
- private readonly base;
11
- private get useMock();
12
- list(opts?: {
13
- activeOnly?: boolean;
14
- page?: number;
15
- limit?: number;
16
- }): Observable<PaginatedResult<PracticeFaq>>;
17
- get(faqId: string): Observable<PracticeFaq | null>;
18
- create(body: CreatePracticeFaqRequest): Observable<PracticeFaq>;
19
- update(faqId: string, body: UpdatePracticeFaqRequest): Observable<PracticeFaq>;
20
- delete(faqId: string): Observable<{
21
- success: boolean;
22
- }>;
23
- search(q: string, limit?: number): Observable<PracticeFaqSearchResult>;
24
- static ɵfac: i0.ɵɵFactoryDeclaration<PracticeFaqApiService, never>;
25
- static ɵprov: i0.ɵɵInjectableDeclaration<PracticeFaqApiService>;
26
- }
@@ -1,3 +0,0 @@
1
- export declare function categoryBadgeClass(category: string | null): string;
2
- export declare function truncateText(text: string, max?: number): string;
3
- export declare function scorePercent(score: number): number;
@@ -1,29 +0,0 @@
1
- import { AgentOnlineService } from '../services/agent-online.service';
2
- import * as i0 from "@angular/core";
3
- export declare class EdsTopbarComponent {
4
- private readonly router;
5
- private readonly sessionAdapter;
6
- private readonly toast;
7
- protected readonly agentOnline: AgentOnlineService;
8
- protected readonly pageTitle: import("@angular/core").WritableSignal<string>;
9
- protected readonly confirmOffOpen: import("@angular/core").WritableSignal<boolean>;
10
- protected readonly online: import("@angular/core").Signal<import("../services/agent-online.service").AgentOnlineKnownState>;
11
- protected readonly loading: import("@angular/core").Signal<boolean>;
12
- protected readonly toggling: import("@angular/core").Signal<boolean>;
13
- protected readonly statusError: import("@angular/core").Signal<string | null>;
14
- protected readonly userEmail: import("@angular/core").Signal<string | null>;
15
- protected readonly showUser: import("@angular/core").Signal<boolean>;
16
- protected readonly showLogout: import("@angular/core").Signal<boolean>;
17
- protected readonly userInitials: import("@angular/core").Signal<string>;
18
- protected readonly statusLabel: import("@angular/core").Signal<"Checking status…" | "Status unknown" | "AI receptionist is answering calls" | "AI is offline — calls go to front desk">;
19
- protected readonly switchDisabled: import("@angular/core").Signal<boolean>;
20
- constructor();
21
- protected onToggleClick(): void;
22
- protected cancelConfirmOff(): void;
23
- protected confirmTurnOff(): void;
24
- private applyOnline;
25
- protected logout(): void;
26
- private updateTitle;
27
- static ɵfac: i0.ɵɵFactoryDeclaration<EdsTopbarComponent, never>;
28
- static ɵcmp: i0.ɵɵComponentDeclaration<EdsTopbarComponent, "eds-topbar", never, {}, {}, never, never, true, never>;
29
- }
@@ -1,21 +0,0 @@
1
- import { OnInit } from '@angular/core';
2
- import { AuditEvent } from '../../models/ai-receptionist.types';
3
- import * as i0 from "@angular/core";
4
- export declare class AuditPageComponent implements OnInit {
5
- private readonly api;
6
- protected readonly pageSize = 50;
7
- protected readonly events: import("@angular/core").WritableSignal<AuditEvent[]>;
8
- protected readonly total: import("@angular/core").WritableSignal<number>;
9
- protected readonly page: import("@angular/core").WritableSignal<number>;
10
- protected readonly search: import("@angular/core").WritableSignal<string>;
11
- protected readonly actor: import("@angular/core").WritableSignal<string>;
12
- protected readonly loading: import("@angular/core").WritableSignal<boolean>;
13
- ngOnInit(): void;
14
- protected load(): void;
15
- protected searchSubmit(): void;
16
- protected totalPages(): number;
17
- protected prevPage(): void;
18
- protected nextPage(): void;
19
- static ɵfac: i0.ɵɵFactoryDeclaration<AuditPageComponent, never>;
20
- static ɵcmp: i0.ɵɵComponentDeclaration<AuditPageComponent, "eds-audit-page", never, {}, {}, never, never, true, never>;
21
- }
@@ -1,8 +0,0 @@
1
- import * as i0 from "@angular/core";
2
- export declare class EdsWaveformComponent {
3
- readonly active: import("@angular/core").InputSignal<boolean>;
4
- readonly tone: import("@angular/core").InputSignal<"brand" | "violet">;
5
- protected readonly bars: number[];
6
- static ɵfac: i0.ɵɵFactoryDeclaration<EdsWaveformComponent, never>;
7
- static ɵcmp: i0.ɵɵComponentDeclaration<EdsWaveformComponent, "eds-waveform", never, { "active": { "alias": "active"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
8
- }