@alfadocs/ui-kit-debug 1.50.1 → 1.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (513) hide show
  1. package/dist/_chunks/{actions-cell-renderer-DMittsR3.js → actions-cell-renderer-DBI33cMp.js} +4 -4
  2. package/dist/_chunks/{actions-cell-renderer-DMittsR3.js.map → actions-cell-renderer-DBI33cMp.js.map} +1 -1
  3. package/dist/_chunks/{agenda-tray-BhZASyJm.js → agenda-tray-CGhEEnFE.js} +3 -3
  4. package/dist/_chunks/{agenda-tray-BhZASyJm.js.map → agenda-tray-CGhEEnFE.js.map} +1 -1
  5. package/dist/_chunks/{ai-credits-notice-C-kz_RrY.js → ai-credits-notice-C9K_ley1.js} +3 -3
  6. package/dist/_chunks/{ai-credits-notice-C-kz_RrY.js.map → ai-credits-notice-C9K_ley1.js.map} +1 -1
  7. package/dist/_chunks/{ai-permission-notice-BRZeS3mT.js → ai-permission-notice-DMG1o4Qa.js} +2 -2
  8. package/dist/_chunks/{ai-permission-notice-BRZeS3mT.js.map → ai-permission-notice-DMG1o4Qa.js.map} +1 -1
  9. package/dist/_chunks/{ai-prompt-input-CxvnXsAs.js → ai-prompt-input-ucwO-z8g.js} +2 -2
  10. package/dist/_chunks/{ai-prompt-input-CxvnXsAs.js.map → ai-prompt-input-ucwO-z8g.js.map} +1 -1
  11. package/dist/_chunks/{alia-sidebar-Dx-oeOV2.js → alia-sidebar-K3gaNH94.js} +7 -7
  12. package/dist/_chunks/{alia-sidebar-Dx-oeOV2.js.map → alia-sidebar-K3gaNH94.js.map} +1 -1
  13. package/dist/_chunks/{anamnesis-card-D8Si-2GV.js → anamnesis-card-CPjry4ur.js} +2 -2
  14. package/dist/_chunks/{anamnesis-card-D8Si-2GV.js.map → anamnesis-card-CPjry4ur.js.map} +1 -1
  15. package/dist/_chunks/{anamnesis-summary-rows-CZirLRuv.js → anamnesis-summary-rows-D9LZZHLw.js} +9 -9
  16. package/dist/_chunks/{anamnesis-summary-rows-CZirLRuv.js.map → anamnesis-summary-rows-D9LZZHLw.js.map} +1 -1
  17. package/dist/_chunks/{appointment-card-BgLpE6T5.js → appointment-card-DETaIfBb.js} +2 -2
  18. package/dist/_chunks/{appointment-card-BgLpE6T5.js.map → appointment-card-DETaIfBb.js.map} +1 -1
  19. package/dist/_chunks/{appointment-peek-Dk11UOVW.js → appointment-peek-B79v56Zc.js} +4 -4
  20. package/dist/_chunks/{appointment-peek-Dk11UOVW.js.map → appointment-peek-B79v56Zc.js.map} +1 -1
  21. package/dist/_chunks/{appointment-timeline-wQ-PdkFV.js → appointment-timeline-tyJJPgVU.js} +5 -5
  22. package/dist/_chunks/{appointment-timeline-wQ-PdkFV.js.map → appointment-timeline-tyJJPgVU.js.map} +1 -1
  23. package/dist/_chunks/{appointment-tray-D7Gt6m8x.js → appointment-tray-Dq4zto_L.js} +4 -4
  24. package/dist/_chunks/{appointment-tray-D7Gt6m8x.js.map → appointment-tray-Dq4zto_L.js.map} +1 -1
  25. package/dist/_chunks/{audio-recorder-DZBtAvLH.js → audio-recorder-Ddlp5rVg.js} +3 -3
  26. package/dist/_chunks/{audio-recorder-DZBtAvLH.js.map → audio-recorder-Ddlp5rVg.js.map} +1 -1
  27. package/dist/_chunks/{balance-badge-cell-klaxFNL_.js → balance-badge-cell-BCEsdEOe.js} +4 -4
  28. package/dist/_chunks/{balance-badge-cell-klaxFNL_.js.map → balance-badge-cell-BCEsdEOe.js.map} +1 -1
  29. package/dist/_chunks/{bishop-score-BMLRvXYF.js → bishop-score-1NAiZh0K.js} +2 -2
  30. package/dist/_chunks/{bishop-score-BMLRvXYF.js.map → bishop-score-1NAiZh0K.js.map} +1 -1
  31. package/dist/_chunks/{bmi-calculator-DUhRyyrA.js → bmi-calculator-ZzzPZhhI.js} +2 -2
  32. package/dist/_chunks/{bmi-calculator-DUhRyyrA.js.map → bmi-calculator-ZzzPZhhI.js.map} +1 -1
  33. package/dist/_chunks/{booking-Cdzd8kyY.js → booking-DmyX24Ls.js} +5 -5
  34. package/dist/_chunks/{booking-Cdzd8kyY.js.map → booking-DmyX24Ls.js.map} +1 -1
  35. package/dist/_chunks/{button-18oBsI3n.js → button-CYPx2xFq.js} +38 -36
  36. package/dist/_chunks/button-CYPx2xFq.js.map +1 -0
  37. package/dist/_chunks/{button-group-BSDqso_C.js → button-group-t9RrsCS6.js} +3 -3
  38. package/dist/_chunks/{button-group-BSDqso_C.js.map → button-group-t9RrsCS6.js.map} +1 -1
  39. package/dist/_chunks/{calendar-E6Yu4lzC.js → calendar-aqzmITxw.js} +542 -510
  40. package/dist/_chunks/calendar-aqzmITxw.js.map +1 -0
  41. package/dist/_chunks/calendar-workspace-BqoPkCUp.js +10597 -0
  42. package/dist/_chunks/calendar-workspace-BqoPkCUp.js.map +1 -0
  43. package/dist/_chunks/{care-plan-card-ciBaaguw.js → care-plan-card-amX33mMF.js} +2 -2
  44. package/dist/_chunks/{care-plan-card-ciBaaguw.js.map → care-plan-card-amX33mMF.js.map} +1 -1
  45. package/dist/_chunks/{care-plan-entry-card-D7A0whiZ.js → care-plan-entry-card-DNkEucjN.js} +2 -2
  46. package/dist/_chunks/{care-plan-entry-card-D7A0whiZ.js.map → care-plan-entry-card-DNkEucjN.js.map} +1 -1
  47. package/dist/_chunks/{care-plan-header-DKV1gLqv.js → care-plan-header-CJi853Rf.js} +2 -2
  48. package/dist/_chunks/{care-plan-header-DKV1gLqv.js.map → care-plan-header-CJi853Rf.js.map} +1 -1
  49. package/dist/_chunks/{carousel.agent-DqDGR2yH.js → carousel.agent-2EhJsAtl.js} +2 -2
  50. package/dist/_chunks/{carousel.agent-DqDGR2yH.js.map → carousel.agent-2EhJsAtl.js.map} +1 -1
  51. package/dist/_chunks/{chart-VjuXDXOZ.js → chart-B2HnwMP5.js} +3 -3
  52. package/dist/_chunks/{chart-VjuXDXOZ.js.map → chart-B2HnwMP5.js.map} +1 -1
  53. package/dist/_chunks/{chat-input-BVho_SqP.js → chat-input-CHUsUFOD.js} +2 -2
  54. package/dist/_chunks/{chat-input-BVho_SqP.js.map → chat-input-CHUsUFOD.js.map} +1 -1
  55. package/dist/_chunks/{chat-message-B4ihjNy3.js → chat-message-DTcRGhNo.js} +3 -3
  56. package/dist/_chunks/{chat-message-B4ihjNy3.js.map → chat-message-DTcRGhNo.js.map} +1 -1
  57. package/dist/_chunks/{code-block-C_eNHWaa.js → code-block-BrwcZNPq.js} +2 -2
  58. package/dist/_chunks/{code-block-C_eNHWaa.js.map → code-block-BrwcZNPq.js.map} +1 -1
  59. package/dist/_chunks/{connection-status-Cfux3TvH.js → connection-status-DMheLE65.js} +3 -3
  60. package/dist/_chunks/{connection-status-Cfux3TvH.js.map → connection-status-DMheLE65.js.map} +1 -1
  61. package/dist/_chunks/{contact-profile-card-Dj4NgBL-.js → contact-profile-card-zQLGGFKG.js} +2 -2
  62. package/dist/_chunks/{contact-profile-card-Dj4NgBL-.js.map → contact-profile-card-zQLGGFKG.js.map} +1 -1
  63. package/dist/_chunks/{control-room-rail-DAO0qfOI.js → control-room-rail-5iuM3jcm.js} +3 -3
  64. package/dist/_chunks/{control-room-rail-DAO0qfOI.js.map → control-room-rail-5iuM3jcm.js.map} +1 -1
  65. package/dist/_chunks/{copy-field-Cm4y5Bff.js → copy-field-C-KvrgOG.js} +2 -2
  66. package/dist/_chunks/{copy-field-Cm4y5Bff.js.map → copy-field-C-KvrgOG.js.map} +1 -1
  67. package/dist/_chunks/{cycle-calculator-B9lBRNiZ.js → cycle-calculator-DQMCeEzn.js} +2 -2
  68. package/dist/_chunks/{cycle-calculator-B9lBRNiZ.js.map → cycle-calculator-DQMCeEzn.js.map} +1 -1
  69. package/dist/_chunks/{dashboard-grid-uX7x1ePj.js → dashboard-grid-H7uph3HO.js} +2 -2
  70. package/dist/_chunks/{dashboard-grid-uX7x1ePj.js.map → dashboard-grid-H7uph3HO.js.map} +1 -1
  71. package/dist/_chunks/{data-table-CrI3_bjH.js → data-table-C4yPR89K.js} +7 -7
  72. package/dist/_chunks/{data-table-CrI3_bjH.js.map → data-table-C4yPR89K.js.map} +1 -1
  73. package/dist/_chunks/{data-table-tabs-CzYYKp2_.js → data-table-tabs-Dd_O1nPY.js} +3 -3
  74. package/dist/_chunks/{data-table-tabs-CzYYKp2_.js.map → data-table-tabs-Dd_O1nPY.js.map} +1 -1
  75. package/dist/_chunks/{description-list-1A2DEbE6.js → description-list-DOPu69Jg.js} +2 -2
  76. package/dist/_chunks/{description-list-1A2DEbE6.js.map → description-list-DOPu69Jg.js.map} +1 -1
  77. package/dist/_chunks/{document-preview-Od2Hz4z5.js → document-preview-Dzh1YAz8.js} +3 -3
  78. package/dist/_chunks/{document-preview-Od2Hz4z5.js.map → document-preview-Dzh1YAz8.js.map} +1 -1
  79. package/dist/_chunks/{document-scanner-p0aGlzCy.js → document-scanner-BSVwMR4V.js} +2 -2
  80. package/dist/_chunks/{document-scanner-p0aGlzCy.js.map → document-scanner-BSVwMR4V.js.map} +1 -1
  81. package/dist/_chunks/dropdown-menu-DIzxr_lp.js +594 -0
  82. package/dist/_chunks/dropdown-menu-DIzxr_lp.js.map +1 -0
  83. package/dist/_chunks/{due-date-calculator-BVqJaxzd.js → due-date-calculator-DUjw4w5O.js} +2 -2
  84. package/dist/_chunks/{due-date-calculator-BVqJaxzd.js.map → due-date-calculator-DUjw4w5O.js.map} +1 -1
  85. package/dist/_chunks/{editable-currency-cell-renderer-D_G2Ap61.js → editable-currency-cell-renderer-Cch3RIJL.js} +3 -3
  86. package/dist/_chunks/{editable-currency-cell-renderer-D_G2Ap61.js.map → editable-currency-cell-renderer-Cch3RIJL.js.map} +1 -1
  87. package/dist/_chunks/{editable-description-B4NVdjvd.js → editable-description-CRQib91p.js} +3 -3
  88. package/dist/_chunks/{editable-description-B4NVdjvd.js.map → editable-description-CRQib91p.js.map} +1 -1
  89. package/dist/_chunks/{editor-overlay-BDiBvQmL.js → editor-overlay-DsA7vR5C.js} +2 -2
  90. package/dist/_chunks/{editor-overlay-BDiBvQmL.js.map → editor-overlay-DsA7vR5C.js.map} +1 -1
  91. package/dist/_chunks/{empty-state-DTBZ1ENT.js → empty-state-Ck1wVWdN.js} +2 -2
  92. package/dist/_chunks/{empty-state-DTBZ1ENT.js.map → empty-state-Ck1wVWdN.js.map} +1 -1
  93. package/dist/_chunks/{entity-summary-CFJfBdVP.js → entity-summary-Cvs21xPr.js} +3 -3
  94. package/dist/_chunks/{entity-summary-CFJfBdVP.js.map → entity-summary-Cvs21xPr.js.map} +1 -1
  95. package/dist/_chunks/{error-boundary-BxTqEXqj.js → error-boundary-C_HAzVLO.js} +2 -2
  96. package/dist/_chunks/{error-boundary-BxTqEXqj.js.map → error-boundary-C_HAzVLO.js.map} +1 -1
  97. package/dist/_chunks/{face-scheme-fku-RShg.js → face-scheme-DVZZTuXT.js} +5 -5
  98. package/dist/_chunks/{face-scheme-fku-RShg.js.map → face-scheme-DVZZTuXT.js.map} +1 -1
  99. package/dist/_chunks/{fetal-weight-B69yOS9W.js → fetal-weight-B-lO-948.js} +2 -2
  100. package/dist/_chunks/{fetal-weight-B69yOS9W.js.map → fetal-weight-B-lO-948.js.map} +1 -1
  101. package/dist/_chunks/{field-array-lIXrFWS0.js → field-array-B3IDOct8.js} +3 -3
  102. package/dist/_chunks/{field-array-lIXrFWS0.js.map → field-array-B3IDOct8.js.map} +1 -1
  103. package/dist/_chunks/{file-manager-C6QQPQV5.js → file-manager-COUb-w8j.js} +7 -7
  104. package/dist/_chunks/{file-manager-C6QQPQV5.js.map → file-manager-COUb-w8j.js.map} +1 -1
  105. package/dist/_chunks/{finished-terminal-B2oqXO0Y.js → finished-terminal-BrAWwfOw.js} +2 -2
  106. package/dist/_chunks/{finished-terminal-B2oqXO0Y.js.map → finished-terminal-BrAWwfOw.js.map} +1 -1
  107. package/dist/_chunks/{fiscal-code-input-BEF8eKIG.js → fiscal-code-input-CwUwhUZy.js} +2 -2
  108. package/dist/_chunks/{fiscal-code-input-BEF8eKIG.js.map → fiscal-code-input-CwUwhUZy.js.map} +1 -1
  109. package/dist/_chunks/floating-action-button-pojvb9gG.js.map +1 -1
  110. package/dist/_chunks/{freemium-paywall-B6JITu4l.js → freemium-paywall-DiPJrL18.js} +2 -2
  111. package/dist/_chunks/{freemium-paywall-B6JITu4l.js.map → freemium-paywall-DiPJrL18.js.map} +1 -1
  112. package/dist/_chunks/{gestational-age-calculator-DsGN6_HS.js → gestational-age-calculator-BVPtrWKf.js} +2 -2
  113. package/dist/_chunks/{gestational-age-calculator-DsGN6_HS.js.map → gestational-age-calculator-BVPtrWKf.js.map} +1 -1
  114. package/dist/_chunks/{hcg-doubling-D2SH-e7t.js → hcg-doubling-CPktiA3H.js} +2 -2
  115. package/dist/_chunks/{hcg-doubling-D2SH-e7t.js.map → hcg-doubling-CPktiA3H.js.map} +1 -1
  116. package/dist/_chunks/{header-CCjp5GvE.js → header-C8NbLgVq.js} +2 -2
  117. package/dist/_chunks/{header-CCjp5GvE.js.map → header-C8NbLgVq.js.map} +1 -1
  118. package/dist/_chunks/header-settings-D0M3WNTS.js +305 -0
  119. package/dist/_chunks/header-settings-D0M3WNTS.js.map +1 -0
  120. package/dist/_chunks/{help-me-write-templates-DQtT1qs_.js → help-me-write-templates-CYAKuXZ3.js} +5 -5
  121. package/dist/_chunks/{help-me-write-templates-DQtT1qs_.js.map → help-me-write-templates-CYAKuXZ3.js.map} +1 -1
  122. package/dist/_chunks/{hover-card-BplP5SzQ.js → hover-card-BM0vNmq4.js} +2 -2
  123. package/dist/_chunks/{hover-card-BplP5SzQ.js.map → hover-card-BM0vNmq4.js.map} +1 -1
  124. package/dist/_chunks/{icon-button-CY7GU_Se.js → icon-button-JAXAkqWC.js} +2 -2
  125. package/dist/_chunks/icon-button-JAXAkqWC.js.map +1 -0
  126. package/dist/_chunks/{icon-button-group-B_426QN_.js → icon-button-group-ud2BLmxe.js} +3 -3
  127. package/dist/_chunks/{icon-button-group-B_426QN_.js.map → icon-button-group-ud2BLmxe.js.map} +1 -1
  128. package/dist/_chunks/{icon-picker-ZLebyB0U.js → icon-picker-B1PwkUHy.js} +3 -3
  129. package/dist/_chunks/{icon-picker-ZLebyB0U.js.map → icon-picker-B1PwkUHy.js.map} +1 -1
  130. package/dist/_chunks/{image-cropper-_HiNN79d.js → image-cropper-DM6hpXUw.js} +2 -2
  131. package/dist/_chunks/{image-cropper-_HiNN79d.js.map → image-cropper-DM6hpXUw.js.map} +1 -1
  132. package/dist/_chunks/{info-tip-laBxZhKu.js → info-tip-CywkQ1NX.js} +2 -2
  133. package/dist/_chunks/{info-tip-laBxZhKu.js.map → info-tip-CywkQ1NX.js.map} +1 -1
  134. package/dist/_chunks/{insert-result-CSuPQyKL.js → insert-result-Fu9AHxR6.js} +2 -2
  135. package/dist/_chunks/{insert-result-CSuPQyKL.js.map → insert-result-Fu9AHxR6.js.map} +1 -1
  136. package/dist/_chunks/{key-value-pair-Dcdl3Gni.js → key-value-pair-BL1J3_Km.js} +2 -2
  137. package/dist/_chunks/{key-value-pair-Dcdl3Gni.js.map → key-value-pair-BL1J3_Km.js.map} +1 -1
  138. package/dist/_chunks/{kit-extensions-BTJSnM_H.js → kit-extensions-B9Qn6VIc.js} +6 -6
  139. package/dist/_chunks/{kit-extensions-BTJSnM_H.js.map → kit-extensions-B9Qn6VIc.js.map} +1 -1
  140. package/dist/_chunks/{link-cell-renderer-CkNbUsBM.js → link-cell-renderer-BcW3F1j9.js} +2 -2
  141. package/dist/_chunks/{link-cell-renderer-CkNbUsBM.js.map → link-cell-renderer-BcW3F1j9.js.map} +1 -1
  142. package/dist/_chunks/{locale-picker-DGkQmhV9.js → locale-picker-Z42P8T-i.js} +218 -213
  143. package/dist/_chunks/locale-picker-Z42P8T-i.js.map +1 -0
  144. package/dist/_chunks/{map-view-Bb7ClKSF.js → map-view-DxYPJjM9.js} +2 -2
  145. package/dist/_chunks/{map-view-Bb7ClKSF.js.map → map-view-DxYPJjM9.js.map} +1 -1
  146. package/dist/_chunks/{marketplace-app-shell-1uKqs4gD.js → marketplace-app-shell-rTTvWRrE.js} +6 -6
  147. package/dist/_chunks/{marketplace-app-shell-1uKqs4gD.js.map → marketplace-app-shell-rTTvWRrE.js.map} +1 -1
  148. package/dist/_chunks/{message-card-C2zsvyj0.js → message-card-CUBPPn4Z.js} +3 -3
  149. package/dist/_chunks/{message-card-C2zsvyj0.js.map → message-card-CUBPPn4Z.js.map} +1 -1
  150. package/dist/_chunks/{message-tray-CMlmxdH2.js → message-tray-uy3DAIbn.js} +4 -4
  151. package/dist/_chunks/{message-tray-CMlmxdH2.js.map → message-tray-uy3DAIbn.js.map} +1 -1
  152. package/dist/_chunks/{muscle-scheme-Co0NIgbU.js → muscle-scheme-CH-vQ7Ch.js} +2 -2
  153. package/dist/_chunks/{muscle-scheme-Co0NIgbU.js.map → muscle-scheme-CH-vQ7Ch.js.map} +1 -1
  154. package/dist/_chunks/{notes-panel-xxpFt-I1.js → notes-panel-Dka4Z2M7.js} +4 -4
  155. package/dist/_chunks/{notes-panel-xxpFt-I1.js.map → notes-panel-Dka4Z2M7.js.map} +1 -1
  156. package/dist/_chunks/{notification-card-DDzBCi8l.js → notification-card-Hy8w3UWx.js} +3 -3
  157. package/dist/_chunks/{notification-card-DDzBCi8l.js.map → notification-card-Hy8w3UWx.js.map} +1 -1
  158. package/dist/_chunks/{notification-tray-PnH2PBlZ.js → notification-tray-VuV3XXB8.js} +4 -4
  159. package/dist/_chunks/{notification-tray-PnH2PBlZ.js.map → notification-tray-VuV3XXB8.js.map} +1 -1
  160. package/dist/_chunks/{optical-prescription-DUufWXfZ.js → optical-prescription-C2n6d0HO.js} +2 -2
  161. package/dist/_chunks/{optical-prescription-DUufWXfZ.js.map → optical-prescription-C2n6d0HO.js.map} +1 -1
  162. package/dist/_chunks/{panel-subview-CzHutkA8.js → panel-subview-DAY-ToM3.js} +2 -2
  163. package/dist/_chunks/{panel-subview-CzHutkA8.js.map → panel-subview-DAY-ToM3.js.map} +1 -1
  164. package/dist/_chunks/{patient-details-tTlvrJSU.js → patient-details-D9sAM3qh.js} +3 -3
  165. package/dist/_chunks/{patient-details-tTlvrJSU.js.map → patient-details-D9sAM3qh.js.map} +1 -1
  166. package/dist/_chunks/{patient-field-row-DElFbpKc.js → patient-field-row-CT04C_lZ.js} +277 -257
  167. package/dist/_chunks/patient-field-row-CT04C_lZ.js.map +1 -0
  168. package/dist/_chunks/{patient-search-DgXdGkhK.js → patient-search-DkIukAMQ.js} +3 -3
  169. package/dist/_chunks/{patient-search-DgXdGkhK.js.map → patient-search-DkIukAMQ.js.map} +1 -1
  170. package/dist/_chunks/{patient-summary-card-DQ__6DR-.js → patient-summary-card-DI0BH-Fe.js} +5 -5
  171. package/dist/_chunks/{patient-summary-card-DQ__6DR-.js.map → patient-summary-card-DI0BH-Fe.js.map} +1 -1
  172. package/dist/_chunks/{payment-automation-upsell-ugi4np1l.js → payment-automation-upsell-vQBIyUky.js} +2 -2
  173. package/dist/_chunks/{payment-automation-upsell-ugi4np1l.js.map → payment-automation-upsell-vQBIyUky.js.map} +1 -1
  174. package/dist/_chunks/{payment-request-card-DMJB57Tv.js → payment-request-card-BSaJzhxz.js} +3 -3
  175. package/dist/_chunks/{payment-request-card-DMJB57Tv.js.map → payment-request-card-BSaJzhxz.js.map} +1 -1
  176. package/dist/_chunks/{periodontal-chart-DbGzKDj7.js → periodontal-chart-BcTcOc79.js} +2 -2
  177. package/dist/_chunks/{periodontal-chart-DbGzKDj7.js.map → periodontal-chart-BcTcOc79.js.map} +1 -1
  178. package/dist/_chunks/{periodontal-chart-card-DvHyP47v.js → periodontal-chart-card-NS_nToBf.js} +2 -2
  179. package/dist/_chunks/{periodontal-chart-card-DvHyP47v.js.map → periodontal-chart-card-NS_nToBf.js.map} +1 -1
  180. package/dist/_chunks/{popover-Dvb40vPH.js → popover-SASSeAdY.js} +2 -2
  181. package/dist/_chunks/{popover-Dvb40vPH.js.map → popover-SASSeAdY.js.map} +1 -1
  182. package/dist/_chunks/{practice-results-EKRiqWtQ.js → practice-results-C3ifcObw.js} +6 -6
  183. package/dist/_chunks/{practice-results-EKRiqWtQ.js.map → practice-results-C3ifcObw.js.map} +1 -1
  184. package/dist/_chunks/{pregnancy-dating-lfjjZVZH.js → pregnancy-dating-CpJ3iYvD.js} +2 -2
  185. package/dist/_chunks/{pregnancy-dating-lfjjZVZH.js.map → pregnancy-dating-CpJ3iYvD.js.map} +1 -1
  186. package/dist/_chunks/{pregnancy-weight-gain-WpNt-S0q.js → pregnancy-weight-gain-kDOhA2vZ.js} +2 -2
  187. package/dist/_chunks/{pregnancy-weight-gain-WpNt-S0q.js.map → pregnancy-weight-gain-kDOhA2vZ.js.map} +1 -1
  188. package/dist/_chunks/{privacy-lock-D6gq0GDg.js → privacy-lock-CEyvNpC8.js} +3 -3
  189. package/dist/_chunks/{privacy-lock-D6gq0GDg.js.map → privacy-lock-CEyvNpC8.js.map} +1 -1
  190. package/dist/_chunks/{privacy-mask-BC5lw2zB.js → privacy-mask-TzMlEu3Q.js} +2 -2
  191. package/dist/_chunks/{privacy-mask-BC5lw2zB.js.map → privacy-mask-TzMlEu3Q.js.map} +1 -1
  192. package/dist/_chunks/{product-hub-panel-CKeSCSeE.js → product-hub-panel-b70i9Hi1.js} +3 -3
  193. package/dist/_chunks/{product-hub-panel-CKeSCSeE.js.map → product-hub-panel-b70i9Hi1.js.map} +1 -1
  194. package/dist/_chunks/{public-header.agent-B9wDmUeB.js → public-header.agent-D0ApOrmx.js} +3 -3
  195. package/dist/_chunks/{public-header.agent-B9wDmUeB.js.map → public-header.agent-D0ApOrmx.js.map} +1 -1
  196. package/dist/_chunks/{radiograph-panel.agent-TmyIvTOa.js → radiograph-panel.agent-jhwaIW8U.js} +4 -4
  197. package/dist/_chunks/{radiograph-panel.agent-TmyIvTOa.js.map → radiograph-panel.agent-jhwaIW8U.js.map} +1 -1
  198. package/dist/_chunks/resource-chip-DQeCJzJf.js +143 -0
  199. package/dist/_chunks/resource-chip-DQeCJzJf.js.map +1 -0
  200. package/dist/_chunks/{reviews-panel-BdwFp_0c.js → reviews-panel-B5QC4FIp.js} +4 -4
  201. package/dist/_chunks/{reviews-panel-BdwFp_0c.js.map → reviews-panel-B5QC4FIp.js.map} +1 -1
  202. package/dist/_chunks/{rich-text-editor-y6ML0KeV.js → rich-text-editor-DoBXdwmx.js} +930 -943
  203. package/dist/_chunks/rich-text-editor-DoBXdwmx.js.map +1 -0
  204. package/dist/_chunks/{session-countdown-ACJyTXH2.js → session-countdown-26XB5u38.js} +2 -2
  205. package/dist/_chunks/{session-countdown-ACJyTXH2.js.map → session-countdown-26XB5u38.js.map} +1 -1
  206. package/dist/_chunks/{sheet-D0Lh0KR2.js → sheet-CwhNzxbr.js} +2 -2
  207. package/dist/_chunks/{sheet-D0Lh0KR2.js.map → sheet-CwhNzxbr.js.map} +1 -1
  208. package/dist/_chunks/{sign-in-with-alfadocs-button-CDyJAIzW.js → sign-in-with-alfadocs-button-jxbze77L.js} +2 -2
  209. package/dist/_chunks/{sign-in-with-alfadocs-button-CDyJAIzW.js.map → sign-in-with-alfadocs-button-jxbze77L.js.map} +1 -1
  210. package/dist/_chunks/{signature-request-BUGeG8oD.js → signature-request-BorHf3CY.js} +4 -4
  211. package/dist/_chunks/{signature-request-BUGeG8oD.js.map → signature-request-BorHf3CY.js.map} +1 -1
  212. package/dist/_chunks/{slot-grid-4fWH3Euk.js → slot-grid-xgf2UKLS.js} +4 -4
  213. package/dist/_chunks/{slot-grid-4fWH3Euk.js.map → slot-grid-xgf2UKLS.js.map} +1 -1
  214. package/dist/_chunks/social-sign-in-button-dlpPI5l7.js.map +1 -1
  215. package/dist/_chunks/{streaming-text-eRiizArc.js → streaming-text-Cos2fVTw.js} +2 -2
  216. package/dist/_chunks/{streaming-text-eRiizArc.js.map → streaming-text-Cos2fVTw.js.map} +1 -1
  217. package/dist/_chunks/{tab-bar-BHFf6knq.js → tab-bar-BrkMUW0c.js} +2 -2
  218. package/dist/_chunks/{tab-bar-BHFf6knq.js.map → tab-bar-BrkMUW0c.js.map} +1 -1
  219. package/dist/_chunks/tabs-tK22Mz7r.js +413 -0
  220. package/dist/_chunks/tabs-tK22Mz7r.js.map +1 -0
  221. package/dist/_chunks/{task-card-jaOhnj_q.js → task-card-CLpHmqEY.js} +2 -2
  222. package/dist/_chunks/{task-card-jaOhnj_q.js.map → task-card-CLpHmqEY.js.map} +1 -1
  223. package/dist/_chunks/{task-editor-DlvTwAfv.js → task-editor-B4UGsU7l.js} +6 -6
  224. package/dist/_chunks/{task-editor-DlvTwAfv.js.map → task-editor-B4UGsU7l.js.map} +1 -1
  225. package/dist/_chunks/{task-tray-HHyxi9ga.js → task-tray-dsmYgjVb.js} +4 -4
  226. package/dist/_chunks/{task-tray-HHyxi9ga.js.map → task-tray-dsmYgjVb.js.map} +1 -1
  227. package/dist/_chunks/{tasks-panel-DbSjq_mz.js → tasks-panel-CwwVw491.js} +6 -6
  228. package/dist/_chunks/{tasks-panel-DbSjq_mz.js.map → tasks-panel-CwwVw491.js.map} +1 -1
  229. package/dist/_chunks/{theme-toggle-LUBxlNDm.js → theme-toggle-jyoyhbJL.js} +4 -4
  230. package/dist/_chunks/{theme-toggle-LUBxlNDm.js.map → theme-toggle-jyoyhbJL.js.map} +1 -1
  231. package/dist/_chunks/{toast-CT8hjr9r.js → toast-FijDyPnv.js} +2 -2
  232. package/dist/_chunks/{toast-CT8hjr9r.js.map → toast-FijDyPnv.js.map} +1 -1
  233. package/dist/_chunks/{token-insert-menu-klwbxVKh.js → token-insert-menu-Cjf99IdN.js} +3 -3
  234. package/dist/_chunks/{token-insert-menu-klwbxVKh.js.map → token-insert-menu-Cjf99IdN.js.map} +1 -1
  235. package/dist/_chunks/{tool-rail-DEeX4PdN.js → tool-rail-DphMl1hX.js} +2 -2
  236. package/dist/_chunks/{tool-rail-DEeX4PdN.js.map → tool-rail-DphMl1hX.js.map} +1 -1
  237. package/dist/_chunks/{tooth-scheme-BkjhkI8g.js → tooth-scheme-BaCJnyg9.js} +663 -718
  238. package/dist/_chunks/tooth-scheme-BaCJnyg9.js.map +1 -0
  239. package/dist/_chunks/{unit-converter-Dp_KDxE6.js → unit-converter-CGpOgarU.js} +2 -2
  240. package/dist/_chunks/{unit-converter-Dp_KDxE6.js.map → unit-converter-CGpOgarU.js.map} +1 -1
  241. package/dist/_chunks/{use-appointment-details-read-5-hV-2xA.js → use-appointment-details-read-uEnJLVfA.js} +14 -14
  242. package/dist/_chunks/{use-appointment-details-read-5-hV-2xA.js.map → use-appointment-details-read-uEnJLVfA.js.map} +1 -1
  243. package/dist/_chunks/wallet-pay-button--dnR6NfJ.js.map +1 -1
  244. package/dist/_chunks/{warning-stack-CEgYkI1z.js → warning-stack-7Hffm7K1.js} +3 -3
  245. package/dist/_chunks/{warning-stack-CEgYkI1z.js.map → warning-stack-7Hffm7K1.js.map} +1 -1
  246. package/dist/_chunks/{workflow-map-qGkQTNvS.js → workflow-map-Jfe9L9Wt.js} +6 -6
  247. package/dist/_chunks/{workflow-map-qGkQTNvS.js.map → workflow-map-Jfe9L9Wt.js.map} +1 -1
  248. package/dist/_chunks/{workflow-status-ClHfz4Kr.js → workflow-status-jHfsIDzi.js} +2 -2
  249. package/dist/_chunks/{workflow-status-ClHfz4Kr.js.map → workflow-status-jHfsIDzi.js.map} +1 -1
  250. package/dist/agent-catalog.json +103 -38
  251. package/dist/agent-i18n/en.json +7 -4
  252. package/dist/components/_shared/entity-card/entity-card.d.ts +1 -1
  253. package/dist/components/_shared/field-visibility-cog.d.ts.map +1 -1
  254. package/dist/components/agenda-tray/index.js +1 -1
  255. package/dist/components/ai-credits-notice/index.js +1 -1
  256. package/dist/components/ai-permission-notice/index.js +1 -1
  257. package/dist/components/ai-prompt-input/index.js +1 -1
  258. package/dist/components/anamnesis-card/index.js +1 -1
  259. package/dist/components/anamnesis-summary-card/anamnesis-summary-card.d.ts +1 -1
  260. package/dist/components/appointment-card/index.js +2 -2
  261. package/dist/components/appointment-details-panel/index.js +1 -1
  262. package/dist/components/appointment-peek/index.js +1 -1
  263. package/dist/components/appointment-timeline/index.js +1 -1
  264. package/dist/components/audio-recorder/index.js +1 -1
  265. package/dist/components/bishop-score/index.js +1 -1
  266. package/dist/components/bmi-calculator/index.js +1 -1
  267. package/dist/components/booking/index.js +1 -1
  268. package/dist/components/button/button.d.ts +11 -0
  269. package/dist/components/button/button.d.ts.map +1 -1
  270. package/dist/components/button/icon-button.d.ts +4 -0
  271. package/dist/components/button/icon-button.d.ts.map +1 -1
  272. package/dist/components/button/index.js +2 -2
  273. package/dist/components/button-group/index.js +1 -1
  274. package/dist/components/calendar/calendar.d.ts +5 -3
  275. package/dist/components/calendar/calendar.d.ts.map +1 -1
  276. package/dist/components/calendar/index.js +1 -1
  277. package/dist/components/care-plan-card/index.js +1 -1
  278. package/dist/components/care-plan-entry-card/index.js +1 -1
  279. package/dist/components/care-plan-header/index.js +1 -1
  280. package/dist/components/carousel/index.js +1 -1
  281. package/dist/components/chart/chart.d.ts +1 -1
  282. package/dist/components/chart/index.js +1 -1
  283. package/dist/components/chat-input/index.js +1 -1
  284. package/dist/components/chat-message/index.js +1 -1
  285. package/dist/components/connection-status/index.js +1 -1
  286. package/dist/components/contact-profile-card/index.js +1 -1
  287. package/dist/components/control-room-rail/index.js +1 -1
  288. package/dist/components/copy-field/index.js +1 -1
  289. package/dist/components/cycle-calculator/index.js +1 -1
  290. package/dist/components/dashboard-grid/index.js +1 -1
  291. package/dist/components/data-table/index.js +4 -4
  292. package/dist/components/data-table-tabs/index.js +1 -1
  293. package/dist/components/description-list/index.js +1 -1
  294. package/dist/components/document-preview/index.js +1 -1
  295. package/dist/components/document-scanner/index.js +1 -1
  296. package/dist/components/dropdown-menu/dropdown-menu.agent.d.ts.map +1 -1
  297. package/dist/components/dropdown-menu/dropdown-menu.d.ts +52 -2
  298. package/dist/components/dropdown-menu/dropdown-menu.d.ts.map +1 -1
  299. package/dist/components/dropdown-menu/index.d.ts +1 -1
  300. package/dist/components/dropdown-menu/index.d.ts.map +1 -1
  301. package/dist/components/dropdown-menu/index.js +1 -1
  302. package/dist/components/due-date-calculator/index.js +1 -1
  303. package/dist/components/editable-description/index.js +1 -1
  304. package/dist/components/editor-overlay/index.js +1 -1
  305. package/dist/components/empty-state/index.js +1 -1
  306. package/dist/components/entity-summary/index.js +1 -1
  307. package/dist/components/error-boundary/index.js +1 -1
  308. package/dist/components/face-scheme/index.js +1 -1
  309. package/dist/components/fetal-weight/index.js +1 -1
  310. package/dist/components/field-array/index.js +1 -1
  311. package/dist/components/file-manager/index.js +1 -1
  312. package/dist/components/finished-terminal/index.js +1 -1
  313. package/dist/components/fiscal-code-input/index.js +1 -1
  314. package/dist/components/floating-action-button/floating-action-button.d.ts.map +1 -1
  315. package/dist/components/freemium-paywall/index.js +1 -1
  316. package/dist/components/gestational-age-calculator/index.js +1 -1
  317. package/dist/components/hcg-doubling/index.js +1 -1
  318. package/dist/components/header/index.js +1 -1
  319. package/dist/components/header-settings/header-settings.d.ts +3 -3
  320. package/dist/components/header-settings/header-settings.d.ts.map +1 -1
  321. package/dist/components/header-settings/index.js +1 -1
  322. package/dist/components/hover-card/index.js +1 -1
  323. package/dist/components/icon-button/index.js +1 -1
  324. package/dist/components/icon-button-group/index.js +1 -1
  325. package/dist/components/icon-picker/index.js +1 -1
  326. package/dist/components/image-cropper/index.js +1 -1
  327. package/dist/components/info-tip/index.js +1 -1
  328. package/dist/components/key-value-pair/index.js +1 -1
  329. package/dist/components/locale-picker/index.js +1 -1
  330. package/dist/components/locale-picker/locale-picker.d.ts +7 -0
  331. package/dist/components/locale-picker/locale-picker.d.ts.map +1 -1
  332. package/dist/components/map-view/index.js +1 -1
  333. package/dist/components/message-card/index.js +1 -1
  334. package/dist/components/message-tray/index.js +1 -1
  335. package/dist/components/muscle-scheme/index.js +1 -1
  336. package/dist/components/notes-panel/index.js +1 -1
  337. package/dist/components/notification-card/index.js +1 -1
  338. package/dist/components/notification-tray/index.js +1 -1
  339. package/dist/components/operator-hero/operator-hero.d.ts +1 -1
  340. package/dist/components/optical-prescription/index.js +1 -1
  341. package/dist/components/panel-subview/index.js +1 -1
  342. package/dist/components/patient-details/index.js +1 -1
  343. package/dist/components/patient-details/patient-details.d.ts +1 -1
  344. package/dist/components/patient-search/index.js +1 -1
  345. package/dist/components/patient-summary-card/index.js +1 -1
  346. package/dist/components/patient-summary-card/patient-summary-card.d.ts +1 -1
  347. package/dist/components/patient-table/index.js +1 -1
  348. package/dist/components/payment-card/index.js +1 -1
  349. package/dist/components/periodontal-chart/index.js +1 -1
  350. package/dist/components/periodontal-chart-card/index.js +1 -1
  351. package/dist/components/popover/index.js +1 -1
  352. package/dist/components/practice-results/index.js +1 -1
  353. package/dist/components/pregnancy-dating/index.js +1 -1
  354. package/dist/components/pregnancy-weight-gain/index.js +1 -1
  355. package/dist/components/privacy-lock/index.js +1 -1
  356. package/dist/components/product-hub-tray/index.js +1 -1
  357. package/dist/components/public-header/index.js +1 -1
  358. package/dist/components/radiograph-panel/index.js +1 -1
  359. package/dist/components/resource-chip/index.d.ts +1 -1
  360. package/dist/components/resource-chip/index.d.ts.map +1 -1
  361. package/dist/components/resource-chip/index.js +3 -2
  362. package/dist/components/resource-chip/resource-chip.d.ts +20 -0
  363. package/dist/components/resource-chip/resource-chip.d.ts.map +1 -1
  364. package/dist/components/reviews-panel/index.js +1 -1
  365. package/dist/components/rich-text-editor/editor-toolbar.d.ts.map +1 -1
  366. package/dist/components/rich-text-editor/index.js +2 -2
  367. package/dist/components/session-countdown/index.js +1 -1
  368. package/dist/components/sheet/index.js +1 -1
  369. package/dist/components/sign-in-with-alfadocs-button/index.js +1 -1
  370. package/dist/components/skeleton-scheme/index.js +1 -1
  371. package/dist/components/slot-grid/index.js +1 -1
  372. package/dist/components/social-sign-in-button/social-sign-in-button.d.ts.map +1 -1
  373. package/dist/components/streaming-text/index.js +1 -1
  374. package/dist/components/tab-bar/index.js +1 -1
  375. package/dist/components/tabs/index.js +1 -1
  376. package/dist/components/tabs/tabs.d.ts.map +1 -1
  377. package/dist/components/task-card/index.js +1 -1
  378. package/dist/components/task-editor/index.js +1 -1
  379. package/dist/components/task-tray/index.js +1 -1
  380. package/dist/components/tasks-panel/index.js +1 -1
  381. package/dist/components/theme-toggle/index.js +1 -1
  382. package/dist/components/toast/index.js +1 -1
  383. package/dist/components/token-insert-menu/index.js +1 -1
  384. package/dist/components/tool-rail/index.js +1 -1
  385. package/dist/components/tooth-scheme/index.js +1 -1
  386. package/dist/components/tooth-scheme/tooth-scheme.d.ts +2 -2
  387. package/dist/components/tooth-scheme/tooth-scheme.d.ts.map +1 -1
  388. package/dist/components/unit-converter/index.js +1 -1
  389. package/dist/components/wallet-pay-button/wallet-pay-button.d.ts.map +1 -1
  390. package/dist/components/warning-stack/index.js +1 -1
  391. package/dist/components/workflow/index.js +1 -1
  392. package/dist/components/workflow/workflow-card.d.ts +1 -1
  393. package/dist/components/workflow-status/index.js +1 -1
  394. package/dist/i18n/locales/ar.d.ts +5 -0
  395. package/dist/i18n/locales/ar.d.ts.map +1 -1
  396. package/dist/i18n/locales/ar.js +5 -0
  397. package/dist/i18n/locales/ar.js.map +1 -1
  398. package/dist/i18n/locales/de.d.ts +5 -0
  399. package/dist/i18n/locales/de.d.ts.map +1 -1
  400. package/dist/i18n/locales/de.js +5 -0
  401. package/dist/i18n/locales/de.js.map +1 -1
  402. package/dist/i18n/locales/el.d.ts +5 -0
  403. package/dist/i18n/locales/el.d.ts.map +1 -1
  404. package/dist/i18n/locales/el.js +5 -0
  405. package/dist/i18n/locales/el.js.map +1 -1
  406. package/dist/i18n/locales/en.d.ts +5 -0
  407. package/dist/i18n/locales/en.d.ts.map +1 -1
  408. package/dist/i18n/locales/en.js +5 -0
  409. package/dist/i18n/locales/en.js.map +1 -1
  410. package/dist/i18n/locales/es.d.ts +5 -0
  411. package/dist/i18n/locales/es.d.ts.map +1 -1
  412. package/dist/i18n/locales/es.js +5 -0
  413. package/dist/i18n/locales/es.js.map +1 -1
  414. package/dist/i18n/locales/fr.d.ts +5 -0
  415. package/dist/i18n/locales/fr.d.ts.map +1 -1
  416. package/dist/i18n/locales/fr.js +5 -0
  417. package/dist/i18n/locales/fr.js.map +1 -1
  418. package/dist/i18n/locales/hi.d.ts +5 -0
  419. package/dist/i18n/locales/hi.d.ts.map +1 -1
  420. package/dist/i18n/locales/hi.js +5 -0
  421. package/dist/i18n/locales/hi.js.map +1 -1
  422. package/dist/i18n/locales/it.d.ts +5 -0
  423. package/dist/i18n/locales/it.d.ts.map +1 -1
  424. package/dist/i18n/locales/it.js +5 -0
  425. package/dist/i18n/locales/it.js.map +1 -1
  426. package/dist/i18n/locales/ja.d.ts +5 -0
  427. package/dist/i18n/locales/ja.d.ts.map +1 -1
  428. package/dist/i18n/locales/ja.js +5 -0
  429. package/dist/i18n/locales/ja.js.map +1 -1
  430. package/dist/i18n/locales/nl.d.ts +5 -0
  431. package/dist/i18n/locales/nl.d.ts.map +1 -1
  432. package/dist/i18n/locales/nl.js +5 -0
  433. package/dist/i18n/locales/nl.js.map +1 -1
  434. package/dist/i18n/locales/pl.d.ts +5 -0
  435. package/dist/i18n/locales/pl.d.ts.map +1 -1
  436. package/dist/i18n/locales/pl.js +5 -0
  437. package/dist/i18n/locales/pl.js.map +1 -1
  438. package/dist/i18n/locales/pt.d.ts +5 -0
  439. package/dist/i18n/locales/pt.d.ts.map +1 -1
  440. package/dist/i18n/locales/pt.js +5 -0
  441. package/dist/i18n/locales/pt.js.map +1 -1
  442. package/dist/i18n/locales/ro.d.ts +5 -0
  443. package/dist/i18n/locales/ro.d.ts.map +1 -1
  444. package/dist/i18n/locales/ro.js +5 -0
  445. package/dist/i18n/locales/ro.js.map +1 -1
  446. package/dist/i18n/locales/ru.d.ts +5 -0
  447. package/dist/i18n/locales/ru.d.ts.map +1 -1
  448. package/dist/i18n/locales/ru.js +5 -0
  449. package/dist/i18n/locales/ru.js.map +1 -1
  450. package/dist/i18n/locales/sq.d.ts +5 -0
  451. package/dist/i18n/locales/sq.d.ts.map +1 -1
  452. package/dist/i18n/locales/sq.js +5 -0
  453. package/dist/i18n/locales/sq.js.map +1 -1
  454. package/dist/i18n/locales/sv.d.ts +5 -0
  455. package/dist/i18n/locales/sv.d.ts.map +1 -1
  456. package/dist/i18n/locales/sv.js +5 -0
  457. package/dist/i18n/locales/sv.js.map +1 -1
  458. package/dist/i18n/locales/tr.d.ts +5 -0
  459. package/dist/i18n/locales/tr.d.ts.map +1 -1
  460. package/dist/i18n/locales/tr.js +5 -0
  461. package/dist/i18n/locales/tr.js.map +1 -1
  462. package/dist/i18n/locales/zh.d.ts +5 -0
  463. package/dist/i18n/locales/zh.d.ts.map +1 -1
  464. package/dist/i18n/locales/zh.js +5 -0
  465. package/dist/i18n/locales/zh.js.map +1 -1
  466. package/dist/index.js +477 -476
  467. package/dist/locales/ar.json +5 -0
  468. package/dist/locales/de.json +5 -0
  469. package/dist/locales/el.json +5 -0
  470. package/dist/locales/en.json +5 -0
  471. package/dist/locales/es.json +5 -0
  472. package/dist/locales/fr.json +5 -0
  473. package/dist/locales/hi.json +5 -0
  474. package/dist/locales/it.json +5 -0
  475. package/dist/locales/ja.json +5 -0
  476. package/dist/locales/nl.json +5 -0
  477. package/dist/locales/pl.json +5 -0
  478. package/dist/locales/pt.json +5 -0
  479. package/dist/locales/ro.json +5 -0
  480. package/dist/locales/ru.json +5 -0
  481. package/dist/locales/sq.json +5 -0
  482. package/dist/locales/sv.json +5 -0
  483. package/dist/locales/tr.json +5 -0
  484. package/dist/locales/zh.json +5 -0
  485. package/dist/patterns/alia-assistant/index.js +1 -1
  486. package/dist/patterns/anamnesis/index.js +1 -1
  487. package/dist/patterns/calendar/calendar.sheets.d.ts.map +1 -1
  488. package/dist/patterns/calendar/calendar.surface.d.ts +4 -1
  489. package/dist/patterns/calendar/calendar.surface.d.ts.map +1 -1
  490. package/dist/patterns/calendar/index.js +1 -1
  491. package/dist/patterns/help-me-write-templates/index.js +1 -1
  492. package/dist/patterns/marketplace-app-shell/index.js +1 -1
  493. package/dist/patterns/payment-automation-upsell/index.js +1 -1
  494. package/dist/patterns/signature-request/index.js +1 -1
  495. package/dist/tokens.css +2 -1
  496. package/package.json +1 -1
  497. package/dist/_chunks/button-18oBsI3n.js.map +0 -1
  498. package/dist/_chunks/calendar-E6Yu4lzC.js.map +0 -1
  499. package/dist/_chunks/calendar-workspace-DjbGFjg1.js +0 -10584
  500. package/dist/_chunks/calendar-workspace-DjbGFjg1.js.map +0 -1
  501. package/dist/_chunks/dropdown-menu-C8PaW3lR.js +0 -369
  502. package/dist/_chunks/dropdown-menu-C8PaW3lR.js.map +0 -1
  503. package/dist/_chunks/header-settings-ZXa6hXuu.js +0 -335
  504. package/dist/_chunks/header-settings-ZXa6hXuu.js.map +0 -1
  505. package/dist/_chunks/icon-button-CY7GU_Se.js.map +0 -1
  506. package/dist/_chunks/locale-picker-DGkQmhV9.js.map +0 -1
  507. package/dist/_chunks/patient-field-row-DElFbpKc.js.map +0 -1
  508. package/dist/_chunks/resource-chip-DYTG0IQQ.js +0 -83
  509. package/dist/_chunks/resource-chip-DYTG0IQQ.js.map +0 -1
  510. package/dist/_chunks/rich-text-editor-y6ML0KeV.js.map +0 -1
  511. package/dist/_chunks/tabs-CFsuMQ5H.js +0 -409
  512. package/dist/_chunks/tabs-CFsuMQ5H.js.map +0 -1
  513. package/dist/_chunks/tooth-scheme-BkjhkI8g.js.map +0 -1
@@ -0,0 +1,143 @@
1
+ import { jsxs as N, jsx as n } from "react/jsx-runtime";
2
+ import { forwardRef as k, useRef as A, useState as R, useLayoutEffect as C } from "react";
3
+ import { c as O } from "./index-D2ZczOXr.js";
4
+ import { T as _ } from "./tooltip-Cp-PLePW.js";
5
+ import { A as T } from "./armchair-BaLDW6Hz.js";
6
+ const H = O(
7
+ [
8
+ "ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]",
9
+ "ds:max-w-full",
10
+ // No pill: the label sits on the page ink, so it is legible in all
11
+ // four themes without knowing the resource colour.
12
+ "ds:text-[color:var(--foreground)]",
13
+ "type-eyebrow ds:[--type-eyebrow-size:var(--font-size-2xs)]"
14
+ ].join(" "),
15
+ {
16
+ variants: {
17
+ orientation: {
18
+ // Disc above, name beneath — the stack spends the header's
19
+ // block axis, which is the one a resource column has to spare.
20
+ horizontal: "ds:flex-col",
21
+ // column-REVERSE: the label writes bottom-to-top (the kit's
22
+ // rotated-label direction), so the glyph circle must sit at the
23
+ // BLOCK-END — the start of the reading flow — while keeping
24
+ // circle-first DOM order in both orientations.
25
+ vertical: "ds:flex-col-reverse"
26
+ }
27
+ },
28
+ defaultVariants: { orientation: "horizontal" }
29
+ }
30
+ );
31
+ function U(i, { locale: a, letters: c = 1 } = {}) {
32
+ const r = i.trim().split(/\s+/).map((e) => e.replace(/[^\p{L}\p{M}\p{Nd}]/gu, "")).filter(Boolean), s = (e, p) => {
33
+ const d = Array.from(e);
34
+ return (d[0] ?? "").toLocaleUpperCase(a) + d.slice(1, p).join("");
35
+ };
36
+ if (r.length === 0) return "";
37
+ if (r.length === 1) {
38
+ const [e] = r;
39
+ return new RegExp("\\p{Nd}", "u").test(e) ? e : s(e, Math.max(3, c));
40
+ }
41
+ return r.map((e) => new RegExp("^\\p{Nd}", "u").test(e) ? e : s(e, c)).join("");
42
+ }
43
+ const M = k(
44
+ ({ label: i, color: a, icon: c, orientation: r, shortLabel: s, className: e, style: p, ...d }, j) => {
45
+ const u = r === "vertical", l = s !== void 0 && s.trim() !== "" && s !== i, h = A(null), [o, v] = R(!1), [g, x] = R(!1);
46
+ !o && g && x(!1), C(() => {
47
+ var z;
48
+ const t = h.current;
49
+ if (!l || !t) {
50
+ v(!1);
51
+ return;
52
+ }
53
+ const f = () => {
54
+ v(
55
+ u ? t.scrollHeight > t.clientHeight : t.scrollWidth > t.clientWidth
56
+ );
57
+ };
58
+ f();
59
+ let m = !0;
60
+ if ((z = document.fonts) == null || z.ready.then(() => {
61
+ m && f();
62
+ }), typeof ResizeObserver > "u")
63
+ return () => {
64
+ m = !1;
65
+ };
66
+ const y = new ResizeObserver(f);
67
+ return y.observe(t), () => {
68
+ m = !1, y.disconnect();
69
+ };
70
+ }, [l, u, i, s]);
71
+ const w = a ? { "--resource-chip-color": a } : void 0, b = /* @__PURE__ */ N(
72
+ "span",
73
+ {
74
+ ref: j,
75
+ ...d,
76
+ "data-component": "resource-chip",
77
+ "data-orientation": r ?? "horizontal",
78
+ "data-abbreviated": o ? "" : void 0,
79
+ className: H({ orientation: r, className: e }),
80
+ style: p,
81
+ children: [
82
+ /* @__PURE__ */ n(
83
+ "span",
84
+ {
85
+ className: [
86
+ "ds:flex ds:size-6 ds:shrink-0 ds:items-center ds:justify-center",
87
+ /* Hairline ring, NOT 1.5px: the Lucide glyph is a 24-unit
88
+ icon at stroke-width 2 drawn at 14px, so its strokes land
89
+ at ~1.17px — a 1.5px ring is visibly HEAVIER than the
90
+ glyph it encloses, and a fractional width on a full-radius
91
+ circle antialiases unevenly around the curve. 1px sits
92
+ just under the glyph weight and matches the kit's other
93
+ indicator disc. */
94
+ "ds:rounded-full ds:border ds:[&_svg]:size-3.5",
95
+ // Seeded default; the inline setter wins when a colour is given.
96
+ "ds:[--resource-chip-color:var(--muted-foreground)]",
97
+ "ds:[--resource-chip-ink:color-mix(in_srgb,var(--resource-chip-color)_70%,var(--foreground))]",
98
+ "ds:[background-color:color-mix(in_srgb,var(--resource-chip-color)_16%,transparent)]",
99
+ "ds:[border-color:var(--resource-chip-ink)]",
100
+ "ds:[color:var(--resource-chip-ink)]"
101
+ ].join(" "),
102
+ style: w,
103
+ "aria-hidden": "true",
104
+ children: c ?? /* @__PURE__ */ n(T, {})
105
+ }
106
+ ),
107
+ /* @__PURE__ */ N(
108
+ "span",
109
+ {
110
+ className: u ? "ds:grid ds:text-start ds:[writing-mode:vertical-rl] ds:rotate-180 ds:[max-inline-size:6.5rem]" : "ds:grid ds:text-center ds:[max-inline-size:100%]",
111
+ children: [
112
+ /* @__PURE__ */ n(
113
+ "span",
114
+ {
115
+ ref: h,
116
+ className: `ds:truncate ds:[grid-area:1/1] ${o ? "ds:opacity-0" : ""}`,
117
+ children: i
118
+ }
119
+ ),
120
+ l && o && /* @__PURE__ */ n("span", { "aria-hidden": "true", className: "ds:truncate ds:[grid-area:1/1]", children: s })
121
+ ]
122
+ }
123
+ )
124
+ ]
125
+ }
126
+ );
127
+ return l ? /* @__PURE__ */ n(
128
+ _,
129
+ {
130
+ label: i,
131
+ open: o && g,
132
+ onOpenChange: (t) => x(t && o),
133
+ children: b
134
+ }
135
+ ) : b;
136
+ }
137
+ );
138
+ M.displayName = "ResourceChip";
139
+ export {
140
+ M as R,
141
+ U as a
142
+ };
143
+ //# sourceMappingURL=resource-chip-DQeCJzJf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-chip-DQeCJzJf.js","sources":["../../src/components/resource-chip/resource-chip.tsx"],"sourcesContent":["/* ------------------------------------------------------------------ */\n/* ResourceChip — the one chip for a PLACE resource (a chair, a room, */\n/* a device) so the display is identical everywhere it appears: */\n/* calendar column headers, pickers, legends. */\n/* */\n/* SHAPE: a colour disc holding a place glyph, with the name beneath. */\n/* People get the SAME disc through Avatar — initials or a photo — so */\n/* the two resource axes share one shape and still say different */\n/* things: a face is a person, an armchair is a place. That is why */\n/* the disc carries a GLYPH and never a short code; a circle with */\n/* characters in it reads as a person, and a code beside the name it */\n/* abbreviates only says the same thing twice. */\n/* */\n/* There is deliberately NO pill. A neutral pill per column turned a */\n/* colour-coded header into a row of greys, and the surface it added */\n/* competed with the appointment cards below it. The colour lives in */\n/* the disc — never behind the label — so label contrast never depends */\n/* on a caller-supplied hex. */\n/* */\n/* COLOUR MODEL: the disc is a light WASH of the resource colour, and */\n/* the ring and glyph are the colour at strength. The strong halves */\n/* are mixed 70% toward `--foreground` rather than used raw, because */\n/* raw picker hexes do NOT clear the 3:1 graphics minimum (WCAG */\n/* 1.4.11) against their own wash: Peacock lands at 2.70:1 on light */\n/* and Grape at 1.88:1 on dark. Mixing toward the foreground token is */\n/* theme-adaptive by construction — it darkens on light and lightens */\n/* on dark — and takes every palette entry to ≥ 3.2:1 in all four */\n/* themes while keeping the hue plainly recognisable. The wash is */\n/* mixed with `transparent`, not a surface token, so it composites */\n/* correctly over whatever the host paints behind the header. */\n/* */\n/* `orientation` names how the LABEL is written, not how the chip */\n/* stacks: both variants stack block-wise, and `vertical` additionally */\n/* writes the label bottom-to-top for narrow calendar columns, which */\n/* puts the disc at the block-END — the start of that reading flow. */\n/* */\n/* SHORT LABEL: with `shortLabel`, the chip swaps to it only while the */\n/* full name does not fit. The short name joins the full one in a */\n/* single grid cell, and the full one never leaves layout (it goes */\n/* transparent, not hidden), so the chip keeps asking for the full */\n/* width and swaps back when the column grows. The full name stays the */\n/* accessible name and shows on hover. */\n/* ------------------------------------------------------------------ */\n\nimport {\n forwardRef,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type HTMLAttributes,\n type ReactNode,\n} from 'react';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { Armchair } from 'lucide-react';\nimport { Tooltip } from '../tooltip';\n\nconst resourceChipVariants = cva(\n [\n 'ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]',\n 'ds:max-w-full',\n // No pill: the label sits on the page ink, so it is legible in all\n // four themes without knowing the resource colour.\n 'ds:text-[color:var(--foreground)]',\n 'type-eyebrow ds:[--type-eyebrow-size:var(--font-size-2xs)]',\n ].join(' '),\n {\n variants: {\n orientation: {\n // Disc above, name beneath — the stack spends the header's\n // block axis, which is the one a resource column has to spare.\n horizontal: 'ds:flex-col',\n // column-REVERSE: the label writes bottom-to-top (the kit's\n // rotated-label direction), so the glyph circle must sit at the\n // BLOCK-END — the start of the reading flow — while keeping\n // circle-first DOM order in both orientations.\n vertical: 'ds:flex-col-reverse',\n },\n },\n defaultVariants: { orientation: 'horizontal' },\n },\n);\n\nexport interface ResourceChipProps\n extends\n Omit<HTMLAttributes<HTMLSpanElement>, 'color'>,\n VariantProps<typeof resourceChipVariants> {\n /** Visible resource name. */\n label: string;\n /**\n * Resource colour (any CSS colour string) — drives the whole disc via\n * one CSS custom property: a light wash for the fill, and the colour\n * mixed toward `--foreground` for the ring and glyph. Omitted → the\n * muted token, so the disc degrades to a neutral.\n */\n color?: string;\n /**\n * Glyph inside the colour disc. Defaults to the kit's treatment-chair\n * glyph (`Armchair`); pass another Lucide element for rooms/devices.\n * Keep it a GLYPH — a short code here would read as a person's\n * initials, which is the Avatar's job.\n */\n icon?: ReactNode;\n /**\n * Shorter name shown instead of `label` while `label` does not fit,\n * for example a chair's short code. `label` stays the accessible name\n * and shows in a tooltip while the short one is on screen. Use\n * `abbreviateResourceLabel(label)` when the data has no short code.\n */\n shortLabel?: string;\n}\n\n/**\n * A short form of a resource name for a crowded header: the first letter\n * of each word, with numbers kept whole (\"Poltrona 12\" → \"P12\", \"Sala\n * igiene 2\" → \"SI2\"). A single word without a number keeps its first\n * three letters, since one letter rarely tells two rooms apart. Pass the\n * UI `locale` so capitals follow its rules (Turkish i → İ), and more\n * `letters` per word to tell apart two names that abbreviate alike\n * (\"Poltrona igiene 1\" → \"PoIg1\" at 2).\n */\nexport function abbreviateResourceLabel(\n label: string,\n { locale, letters = 1 }: { locale?: string; letters?: number } = {},\n): string {\n // Only letters, their marks and digits count: \"(Chair)\" reads as\n // \"Chair\", and a word of symbols alone (\"·\", \"&\") drops out. Any\n // script's digits are a number (Arabic ١٢, Devanagari १२).\n const words = label\n .trim()\n .split(/\\s+/)\n .map((word) => word.replace(/[^\\p{L}\\p{M}\\p{Nd}]/gu, ''))\n .filter(Boolean);\n const start = (word: string, count: number) => {\n const chars = Array.from(word);\n return (\n (chars[0] ?? '').toLocaleUpperCase(locale) +\n chars.slice(1, count).join('')\n );\n };\n if (words.length === 0) return '';\n if (words.length === 1) {\n const [word] = words as [string];\n return /\\p{Nd}/u.test(word) ? word : start(word, Math.max(3, letters));\n }\n return words\n .map((word) => (/^\\p{Nd}/u.test(word) ? word : start(word, letters)))\n .join('');\n}\n\nexport const ResourceChip = forwardRef<HTMLSpanElement, ResourceChipProps>(\n (\n { label, color, icon, orientation, shortLabel, className, style, ...rest },\n ref,\n ) => {\n const vertical = orientation === 'vertical';\n const canAbbreviate =\n shortLabel !== undefined &&\n shortLabel.trim() !== '' &&\n shortLabel !== label;\n const fullRef = useRef<HTMLSpanElement>(null);\n const [abbreviated, setAbbreviated] = useState(false);\n const [tipOpen, setTipOpen] = useState(false);\n // A hover while the name fits must not leave the tooltip armed to pop\n // up on its own once the name stops fitting.\n if (!abbreviated && tipOpen) setTipOpen(false);\n\n /* The full name is always laid out, so its own box tracks the room\n the chip is given: overflowing it means the name does not fit. */\n useLayoutEffect(() => {\n const el = fullRef.current;\n if (!canAbbreviate || !el) {\n setAbbreviated(false);\n return;\n }\n const measure = () => {\n setAbbreviated(\n vertical\n ? el.scrollHeight > el.clientHeight\n : el.scrollWidth > el.clientWidth,\n );\n };\n measure();\n let live = true;\n // A late web font changes the text length without resizing a\n // capped box, so measure once more when fonts settle.\n void document.fonts?.ready.then(() => {\n if (live) measure();\n });\n if (typeof ResizeObserver === 'undefined') {\n return () => {\n live = false;\n };\n }\n const observer = new ResizeObserver(measure);\n observer.observe(el);\n return () => {\n live = false;\n observer.disconnect();\n };\n }, [canAbbreviate, vertical, label, shortLabel]);\n\n /* Runtime caller-supplied colour flows through ONE inline CSS\n custom-property setter (23-constraints §Runtime-computed\n dimensions); every consuming declaration — wash, ring, glyph —\n lives in the className as Tailwind arbitrary values and derives\n from it. The class below seeds a muted default that this inline\n value overrides when a colour is supplied. */\n const dotStyle: CSSProperties | undefined = color\n ? ({ '--resource-chip-color': color } as CSSProperties)\n : undefined;\n const chip = (\n <span\n ref={ref}\n {...rest}\n data-component=\"resource-chip\"\n data-orientation={orientation ?? 'horizontal'}\n data-abbreviated={abbreviated ? '' : undefined}\n className={resourceChipVariants({ orientation, className })}\n // eslint-disable-next-line react/forbid-dom-props -- consumer-forwarded style; the runtime colour itself flows through a CSS custom property (23-constraints §inline-style exception)\n style={style}\n >\n <span\n className={[\n 'ds:flex ds:size-6 ds:shrink-0 ds:items-center ds:justify-center',\n /* Hairline ring, NOT 1.5px: the Lucide glyph is a 24-unit\n icon at stroke-width 2 drawn at 14px, so its strokes land\n at ~1.17px — a 1.5px ring is visibly HEAVIER than the\n glyph it encloses, and a fractional width on a full-radius\n circle antialiases unevenly around the curve. 1px sits\n just under the glyph weight and matches the kit's other\n indicator disc. */\n 'ds:rounded-full ds:border ds:[&_svg]:size-3.5',\n // Seeded default; the inline setter wins when a colour is given.\n 'ds:[--resource-chip-color:var(--muted-foreground)]',\n 'ds:[--resource-chip-ink:color-mix(in_srgb,var(--resource-chip-color)_70%,var(--foreground))]',\n 'ds:[background-color:color-mix(in_srgb,var(--resource-chip-color)_16%,transparent)]',\n 'ds:[border-color:var(--resource-chip-ink)]',\n 'ds:[color:var(--resource-chip-ink)]',\n ].join(' ')}\n // eslint-disable-next-line react/forbid-dom-props -- caller-supplied resource colour injected via CSS variables\n style={dotStyle}\n aria-hidden=\"true\"\n >\n {icon ?? <Armchair />}\n </span>\n <span\n className={\n vertical\n ? 'ds:grid ds:text-start ds:[writing-mode:vertical-rl] ds:rotate-180 ds:[max-inline-size:6.5rem]'\n : 'ds:grid ds:text-center ds:[max-inline-size:100%]'\n }\n >\n <span\n ref={fullRef}\n className={`ds:truncate ds:[grid-area:1/1] ${abbreviated ? 'ds:opacity-0' : ''}`}\n >\n {label}\n </span>\n {canAbbreviate && abbreviated && (\n <span aria-hidden=\"true\" className=\"ds:truncate ds:[grid-area:1/1]\">\n {shortLabel}\n </span>\n )}\n </span>\n </span>\n );\n\n if (!canAbbreviate) return chip;\n return (\n <Tooltip\n label={label}\n open={abbreviated && tipOpen}\n onOpenChange={(next) => setTipOpen(next && abbreviated)}\n >\n {chip}\n </Tooltip>\n );\n },\n);\nResourceChip.displayName = 'ResourceChip';\n"],"names":["resourceChipVariants","cva","abbreviateResourceLabel","label","locale","letters","words","word","start","count","chars","ResourceChip","forwardRef","color","icon","orientation","shortLabel","className","style","rest","ref","vertical","canAbbreviate","fullRef","useRef","abbreviated","setAbbreviated","useState","tipOpen","setTipOpen","useLayoutEffect","el","measure","live","_a","observer","dotStyle","chip","jsxs","jsx","Armchair","Tooltip","next"],"mappings":";;;;;AAyDA,MAAMA,IAAuBC;AAAA,EAC3B;AAAA,IACE;AAAA,IACA;AAAA;AAAA;AAAA,IAGA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AAAA,EACV;AAAA,IACE,UAAU;AAAA,MACR,aAAa;AAAA;AAAA;AAAA,QAGX,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA,QAKZ,UAAU;AAAA,MAAA;AAAA,IACZ;AAAA,IAEF,iBAAiB,EAAE,aAAa,aAAA;AAAA,EAAa;AAEjD;AAwCO,SAASC,EACdC,GACA,EAAE,QAAAC,GAAQ,SAAAC,IAAU,EAAA,IAA6C,IACzD;AAIR,QAAMC,IAAQH,EACX,KAAA,EACA,MAAM,KAAK,EACX,IAAI,CAACI,MAASA,EAAK,QAAQ,yBAAyB,EAAE,CAAC,EACvD,OAAO,OAAO,GACXC,IAAQ,CAACD,GAAcE,MAAkB;AAC7C,UAAMC,IAAQ,MAAM,KAAKH,CAAI;AAC7B,YACGG,EAAM,CAAC,KAAK,IAAI,kBAAkBN,CAAM,IACzCM,EAAM,MAAM,GAAGD,CAAK,EAAE,KAAK,EAAE;AAAA,EAEjC;AACA,MAAIH,EAAM,WAAW,EAAG,QAAO;AAC/B,MAAIA,EAAM,WAAW,GAAG;AACtB,UAAM,CAACC,CAAI,IAAID;AACf,WAAO,yBAAA,EAAU,KAAKC,CAAI,IAAIA,IAAOC,EAAMD,GAAM,KAAK,IAAI,GAAGF,CAAO,CAAC;AAAA,EACvE;AACA,SAAOC,EACJ,IAAI,CAACC,MAAU,WAAA,YAAA,KAAW,KAAKA,CAAI,IAAIA,IAAOC,EAAMD,GAAMF,CAAO,CAAE,EACnE,KAAK,EAAE;AACZ;AAEO,MAAMM,IAAeC;AAAA,EAC1B,CACE,EAAE,OAAAT,GAAO,OAAAU,GAAO,MAAAC,GAAM,aAAAC,GAAa,YAAAC,GAAY,WAAAC,GAAW,OAAAC,GAAO,GAAGC,EAAA,GACpEC,MACG;AACH,UAAMC,IAAWN,MAAgB,YAC3BO,IACJN,MAAe,UACfA,EAAW,WAAW,MACtBA,MAAeb,GACXoB,IAAUC,EAAwB,IAAI,GACtC,CAACC,GAAaC,CAAc,IAAIC,EAAS,EAAK,GAC9C,CAACC,GAASC,CAAU,IAAIF,EAAS,EAAK;AAG5C,IAAI,CAACF,KAAeG,KAASC,EAAW,EAAK,GAI7CC,EAAgB,MAAM;;AACpB,YAAMC,IAAKR,EAAQ;AACnB,UAAI,CAACD,KAAiB,CAACS,GAAI;AACzB,QAAAL,EAAe,EAAK;AACpB;AAAA,MACF;AACA,YAAMM,IAAU,MAAM;AACpB,QAAAN;AAAA,UACEL,IACIU,EAAG,eAAeA,EAAG,eACrBA,EAAG,cAAcA,EAAG;AAAA,QAAA;AAAA,MAE5B;AACA,MAAAC,EAAA;AACA,UAAIC,IAAO;AAMX,WAHKC,IAAA,SAAS,UAAT,QAAAA,EAAgB,MAAM,KAAK,MAAM;AACpC,QAAID,KAAMD,EAAA;AAAA,MACZ,IACI,OAAO,iBAAmB;AAC5B,eAAO,MAAM;AACX,UAAAC,IAAO;AAAA,QACT;AAEF,YAAME,IAAW,IAAI,eAAeH,CAAO;AAC3C,aAAAG,EAAS,QAAQJ,CAAE,GACZ,MAAM;AACX,QAAAE,IAAO,IACPE,EAAS,WAAA;AAAA,MACX;AAAA,IACF,GAAG,CAACb,GAAeD,GAAUlB,GAAOa,CAAU,CAAC;AAQ/C,UAAMoB,IAAsCvB,IACvC,EAAE,yBAAyBA,MAC5B,QACEwB,IACJ,gBAAAC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAAlB;AAAA,QACC,GAAGD;AAAA,QACJ,kBAAe;AAAA,QACf,oBAAkBJ,KAAe;AAAA,QACjC,oBAAkBU,IAAc,KAAK;AAAA,QACrC,WAAWzB,EAAqB,EAAE,aAAAe,GAAa,WAAAE,GAAW;AAAA,QAE1D,OAAAC;AAAA,QAEA,UAAA;AAAA,UAAA,gBAAAqB;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAW;AAAA,gBACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAQA;AAAA;AAAA,gBAEA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cAAA,EACA,KAAK,GAAG;AAAA,cAEV,OAAOH;AAAA,cACP,eAAY;AAAA,cAEX,UAAAtB,uBAAS0B,GAAA,CAAA,CAAS;AAAA,YAAA;AAAA,UAAA;AAAA,UAErB,gBAAAF;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WACEjB,IACI,kGACA;AAAA,cAGN,UAAA;AAAA,gBAAA,gBAAAkB;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,KAAKhB;AAAA,oBACL,WAAW,kCAAkCE,IAAc,iBAAiB,EAAE;AAAA,oBAE7E,UAAAtB;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAEFmB,KAAiBG,KAChB,gBAAAc,EAAC,QAAA,EAAK,eAAY,QAAO,WAAU,kCAChC,UAAAvB,EAAA,CACH;AAAA,cAAA;AAAA,YAAA;AAAA,UAAA;AAAA,QAEJ;AAAA,MAAA;AAAA,IAAA;AAIJ,WAAKM,IAEH,gBAAAiB;AAAA,MAACE;AAAA,MAAA;AAAA,QACC,OAAAtC;AAAA,QACA,MAAMsB,KAAeG;AAAA,QACrB,cAAc,CAACc,MAASb,EAAWa,KAAQjB,CAAW;AAAA,QAErD,UAAAY;AAAA,MAAA;AAAA,IAAA,IAPsBA;AAAA,EAU7B;AACF;AACA1B,EAAa,cAAc;"}
@@ -6,10 +6,10 @@ import { u as X } from "./registry-DvAUVLHh.js";
6
6
  import { R as k } from "./rating-BYbUowdK.js";
7
7
  import { C as A } from "./card-DPmk26CL.js";
8
8
  import { C as Y, b as Z, a as ee } from "./collapsible-CTjxzGuF.js";
9
- import { D as l } from "./description-list-1A2DEbE6.js";
10
- import { E as te } from "./empty-state-DTBZ1ENT.js";
9
+ import { D as l } from "./description-list-DOPu69Jg.js";
10
+ import { E as te } from "./empty-state-Ck1wVWdN.js";
11
11
  import { S as T } from "./skeleton-B1KTdJ4N.js";
12
- import { B as se } from "./button-18oBsI3n.js";
12
+ import { B as se } from "./button-CYPx2xFq.js";
13
13
  import { P as re } from "./panel-header-D_mTdhUp.js";
14
14
  import { S as ae } from "./star-Bf9L2Uot.js";
15
15
  import { C as ne } from "./chevron-down-DWE7GSq9.js";
@@ -556,4 +556,4 @@ export {
556
556
  me as R,
557
557
  ie as r
558
558
  };
559
- //# sourceMappingURL=reviews-panel-BdwFp_0c.js.map
559
+ //# sourceMappingURL=reviews-panel-B5QC4FIp.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reviews-panel-BdwFp_0c.js","sources":["../../src/components/reviews-panel/reviews-panel.agent.ts","../../src/components/reviews-panel/reviews-panel.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — ReviewsPanel. */\n/* */\n/* Replaces the legacy patient-reviews Carousel with a single panel that */\n/* surfaces an aggregate score, a star-bucket filter, and a vertical list */\n/* of compact review cards. The adapter exposes the active filter and the */\n/* visible review count so a host agent can drive the panel and observe */\n/* what the user actually sees after the filter is applied. The reviews */\n/* themselves remain owned by the consumer — they never flow through the */\n/* adapter (PHI: pseudonyms + free-text comments stay on the page). */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { ReviewFilter, ReviewsPanelHandle } from './reviews-panel';\n\nexport const reviewsPanelAgent: AgentAdapter<ReviewsPanelHandle> = {\n id: 'reviews-panel',\n capabilities: ['filter'],\n state: {\n filter: {\n type: 'string',\n descriptionKey: 'ui.agent.reviewsPanel.state.filter',\n description:\n 'Active star-bucket filter — `\"all\"` or an integer 1..5. Reads the controlled `filter` prop.',\n read: (handle) => handle.getFilter(),\n },\n visibleCount: {\n type: 'number',\n descriptionKey: 'ui.agent.reviewsPanel.state.visibleCount',\n description:\n 'Number of reviews currently rendered after the filter is applied.',\n read: (handle) => handle.getVisibleCount(),\n },\n },\n actions: {\n set_filter: {\n // Pure ephemeral narrowing of the visible list — no data loss.\n safety: 'read',\n argsType: '{ filter: \"all\" | 1 | 2 | 3 | 4 | 5 }',\n argsSchema: {\n type: 'object',\n properties: {\n filter: {\n description: 'Star bucket to show, or \"all\" to clear the filter.',\n oneOf: [\n { type: 'string', enum: ['all'] },\n { type: 'integer', enum: [1, 2, 3, 4, 5] },\n ],\n },\n },\n required: ['filter'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.reviewsPanel.actions.setFilter',\n description:\n 'Narrow the visible review list to a star bucket, or `\"all\"` to clear the filter.',\n examples: [\n { args: { filter: 5 }, note: 'Show only 5-star reviews.' },\n { args: { filter: 'all' }, note: 'Clear the star filter.' },\n ],\n invoke: (handle, args: { filter: ReviewFilter }) => {\n handle.setFilter(args.filter);\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'reviews-panel',\n description: 'Marks the ReviewsPanel root region.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n },\n};\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type KeyboardEvent,\n type ReactNode,\n} from 'react';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ChevronDown, Star } from 'lucide-react';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { reviewsPanelAgent } from './reviews-panel.agent';\nimport { Rating } from '../rating/rating';\nimport { Card } from '../card/card';\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '../collapsible/collapsible';\nimport { DescriptionList } from '../description-list/description-list';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { Skeleton } from '../skeleton/skeleton';\nimport { Button } from '../button/button';\nimport { PanelHeader } from '../panel-header';\n\n/* -------------------------------------------------------------------- */\n/* ReviewsPanel */\n/* */\n/* Replaces the legacy patient-reviews Carousel with a two-column panel */\n/* — a star-bucket filter sidebar + a vertical list of compact review */\n/* cards — that surfaces the aggregate score, the volume, and (via a */\n/* per-card Collapsible) the rich per-axis breakdown alfaDocs already */\n/* collects but the carousel buried. */\n/* -------------------------------------------------------------------- */\n\n/* -------------------------------------------------------------------- */\n/* Public types */\n/* -------------------------------------------------------------------- */\n\nexport interface ReviewItem {\n id: string;\n /** When the review was authored (ISO 8601). */\n authoredAt: string;\n /** Anonymised author display (\"Marco T.\", \"Anna_M\"). Falls back to a localised \"Anonymous\". */\n pseudonym?: string;\n /** 0..max — drives the visible star summary on the compact card. */\n overallScore: number;\n /** Short free-text comment shown on the compact card. */\n comment?: string;\n /** Practice reply (revealed in the expanded panel only). */\n reply?: string;\n /** Optional per-axis breakdown — when present, the card grows an\n * \"Expand\" affordance that reveals these in a DescriptionList. */\n breakdown?: {\n appointmentScore?: number;\n communicationScore?: number;\n staffScore?: number;\n overallScore?: number;\n };\n /** Optional categorical follow-ups, surfaced inside the breakdown. */\n futureVisit?: 'yes' | 'no' | 'unsure';\n recommendation?: 'yes' | 'no' | 'unsure';\n}\n\nexport interface ReviewsAggregate {\n /** Total review count across all star buckets (may exceed the loaded set when paginated). */\n count: number;\n /** Average score across the full population (drives the header `Rating`). */\n averageScore: number;\n /**\n * Optional histogram — per-bucket count keyed by integer star value 1..5.\n * When omitted, the panel derives buckets from the loaded `reviews` array\n * (best-effort: paginated consumers SHOULD provide this explicitly).\n */\n histogram?: Record<1 | 2 | 3 | 4 | 5, number>;\n}\n\nexport type ReviewFilter = 'all' | 1 | 2 | 3 | 4 | 5;\n\nexport interface ReviewsPanelHandle {\n getFilter: () => ReviewFilter;\n setFilter: (next: ReviewFilter) => void;\n /** Total visible after filter is applied. */\n getVisibleCount: () => number;\n}\n\nexport interface ReviewsPanelProps extends Omit<\n ComponentPropsWithoutRef<'section'>,\n 'aria-label' | 'children'\n> {\n reviews: ReviewItem[];\n aggregate: ReviewsAggregate;\n\n /**\n * Active star filter. Controlled — consumer owns it for shareability via\n * URL query strings. Omit for uncontrolled (panel-managed) filtering.\n */\n filter?: ReviewFilter;\n onFilterChange?: (next: ReviewFilter) => void;\n\n /**\n * Optional intro callout shown above the list (e.g. \"Riepilogo delle\n * opinioni — i pazienti raccontano…\"). Render-prop slot so the consumer\n * can drop in `<Alert>` / `<Callout>` / plain `<p>`.\n */\n introSlot?: ReactNode;\n\n /** Optional header right-end action (e.g. a \"Leave a review\" button). */\n headerActionSlot?: ReactNode;\n\n /** Override the default region aria-label. */\n 'aria-label'?: string;\n\n /** Agent-readiness id. */\n id?: string;\n\n className?: string;\n\n /**\n * Hide the filter sidebar — useful when the panel mounts under ~640px\n * width or inside a narrow column. Defaults to false.\n */\n hideFilter?: boolean;\n\n /**\n * @default 'flat'\n * `'elevated'` wraps the panel in the equivalent of `Card variant=\"elevated\"`\n * — same tokens (`--card`, `--card-border`, `--shadow-card`,\n * `--radius-lg`), same padding. Use to drop the consumer-side\n * `<Card><Card.Body>` wrap.\n */\n surface?: 'flat' | 'elevated';\n\n /** Render skeletons for the header and the list. */\n loading?: boolean;\n}\n\n/* -------------------------------------------------------------------- */\n/* Constants & helpers */\n/* -------------------------------------------------------------------- */\n\nconst FILTER_VALUES: readonly ReviewFilter[] = ['all', 5, 4, 3, 2, 1] as const;\n\nfunction bucketOf(score: number): 1 | 2 | 3 | 4 | 5 {\n const n = Math.min(5, Math.max(1, Math.floor(score)));\n return n as 1 | 2 | 3 | 4 | 5;\n}\n\nfunction deriveHistogram(\n reviews: ReviewItem[],\n): Record<1 | 2 | 3 | 4 | 5, number> {\n const out: Record<1 | 2 | 3 | 4 | 5, number> = {\n 1: 0,\n 2: 0,\n 3: 0,\n 4: 0,\n 5: 0,\n };\n for (const r of reviews) out[bucketOf(r.overallScore)] += 1;\n return out;\n}\n\n/* -------------------------------------------------------------------- */\n/* FilterBar — hand-rolled radiogroup with roving tabindex */\n/* */\n/* Lives in the shared `PanelHeader` filters row, so it lays out */\n/* HORIZONTALLY (a wrapping bar of star-bucket chips) rather than the */\n/* legacy vertical sidebar column. Still the WAI-ARIA RadioGroup pattern */\n/* — each chip is a full click target with a non-text leading glyph (the */\n/* star ramp) and a trailing count. NOT Radix `RadioGroup` because we */\n/* need that glyph-plus-count chip shape. */\n/* */\n/* Activation is automatic — Arrow keys move BOTH focus and selection, */\n/* so a keyboard user feels the same responsiveness as a mouse user. */\n/* That's the right call here because filter activation is cheap (re- */\n/* renders the visible list); contrast with the booking ServiceGrid */\n/* where activation cascades through downstream selection state. */\n/* -------------------------------------------------------------------- */\n\nconst filterRowVariants = cva(\n [\n 'ds:relative ds:inline-flex ds:items-center ds:justify-center',\n 'ds:gap-[var(--spacing-xs)]',\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:pt-[var(--spacing-2xs)] ds:pb-[var(--spacing-2xs)]',\n 'ds:text-start',\n 'ds:transition-[background-color,color]',\n 'ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n 'ds:cursor-pointer',\n ].join(' '),\n {\n variants: {\n state: {\n idle: 'ds:hover:bg-[var(--muted)]/30 ds:text-[var(--foreground)]',\n selected: [\n 'ds:bg-[var(--primary)]',\n 'ds:text-[var(--primary-foreground)]',\n 'ds:font-[var(--font-weight-semibold)]',\n ].join(' '),\n },\n },\n defaultVariants: { state: 'idle' },\n },\n);\n\ninterface FilterBarProps {\n filter: ReviewFilter;\n histogram: Record<1 | 2 | 3 | 4 | 5, number>;\n totalCount: number;\n onChange: (next: ReviewFilter) => void;\n}\n\nfunction FilterBar({\n filter,\n histogram,\n totalCount,\n onChange,\n}: FilterBarProps) {\n const { t } = useTranslation();\n const labelId = useId();\n\n // Roving tabindex tracks where keyboard focus is. We use AUTOMATIC\n // activation: arrow keys move focus AND fire onChange (see the rationale\n // above the component). To keep the visible aria-checked row and the\n // tab-stop aligned when the parent changes `filter` externally (e.g.\n // from a `?filter=4` URL parameter on page load), sync focusIndex to\n // the current filter via the effect below — without it, the tab stop\n // could land on `All` while the highlight shows `4`.\n const [focusIndex, setFocusIndex] = useState<number>(() =>\n Math.max(0, FILTER_VALUES.indexOf(filter)),\n );\n useEffect(() => {\n const i = FILTER_VALUES.indexOf(filter);\n if (i >= 0) setFocusIndex(i);\n }, [filter]);\n\n const rowRefs = useRef<Map<number, HTMLButtonElement>>(new Map());\n const focusAt = useCallback((index: number) => {\n rowRefs.current.get(index)?.focus();\n }, []);\n\n const total = FILTER_VALUES.length;\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>, index: number) => {\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowRight': {\n event.preventDefault();\n const next = (index + 1) % total;\n setFocusIndex(next);\n focusAt(next);\n onChange(FILTER_VALUES[next]);\n break;\n }\n case 'ArrowUp':\n case 'ArrowLeft': {\n event.preventDefault();\n const prev = (index - 1 + total) % total;\n setFocusIndex(prev);\n focusAt(prev);\n onChange(FILTER_VALUES[prev]);\n break;\n }\n case 'Home': {\n event.preventDefault();\n setFocusIndex(0);\n focusAt(0);\n onChange(FILTER_VALUES[0]);\n break;\n }\n case 'End': {\n event.preventDefault();\n const last = total - 1;\n setFocusIndex(last);\n focusAt(last);\n onChange(FILTER_VALUES[last]);\n break;\n }\n case 'Enter':\n case ' ': {\n event.preventDefault();\n onChange(FILTER_VALUES[index]);\n break;\n }\n default:\n break;\n }\n },\n [total, focusAt, onChange],\n );\n\n return (\n <>\n <h3\n id={labelId}\n className=\"type-label ds:font-[var(--font-weight-semibold)] ds:text-[var(--foreground)] ds:m-0\"\n >\n {t('reviewsPanel.filterTitle')}\n </h3>\n <div\n role=\"radiogroup\"\n aria-labelledby={labelId}\n className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-2xs)]\"\n >\n {FILTER_VALUES.map((val, index) => {\n const isAll = val === 'all';\n const stars = isAll ? 0 : (val as 1 | 2 | 3 | 4 | 5);\n const count = isAll\n ? totalCount\n : histogram[stars as 1 | 2 | 3 | 4 | 5];\n const isSelected = val === filter;\n const isFocused = focusIndex === index;\n const ariaLabel = isAll\n ? t('reviewsPanel.filter.allLabel', { count })\n : t('reviewsPanel.filter.starsLabel', { stars, count });\n\n return (\n <button\n key={String(val)}\n ref={(node) => {\n if (node) rowRefs.current.set(index, node);\n else rowRefs.current.delete(index);\n }}\n type=\"button\"\n role=\"radio\"\n aria-checked={isSelected}\n aria-label={ariaLabel}\n tabIndex={isFocused ? 0 : -1}\n onClick={() => {\n setFocusIndex(index);\n onChange(val);\n }}\n onFocus={() => setFocusIndex(index)}\n onKeyDown={(e) => handleKeyDown(e, index)}\n data-filter-bucket={String(val)}\n className={filterRowVariants({\n state: isSelected ? 'selected' : 'idle',\n })}\n >\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\"\n >\n {isAll ? (\n <span className=\"type-label\">\n {t('reviewsPanel.filter.allShort')}\n </span>\n ) : (\n <Rating value={stars} size=\"sm\" decorative />\n )}\n </span>\n <span\n aria-hidden=\"true\"\n className={[\n 'type-meta',\n // Idle row: count is dimmed (--muted-foreground over\n // --background ≈ 4.5:1, AA passes). Selected row\n // paints violet bg + white text on the BUTTON, but\n // the count's own explicit color override would\n // otherwise win the cascade and leave dark navy-grey\n // text on the violet pill (~3:1, AA-fail). Match the\n // row's foreground when selected; slight opacity\n // keeps the count secondary to the label.\n isSelected\n ? 'ds:text-[color:var(--primary-foreground)]'\n : 'ds:text-[var(--muted-foreground)]',\n ].join(' ')}\n >\n {count}\n </span>\n </button>\n );\n })}\n </div>\n </>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* ReviewCard — compact card with optional Collapsible breakdown */\n/* -------------------------------------------------------------------- */\n\ninterface ReviewCardProps {\n review: ReviewItem;\n locale: string;\n}\n\nfunction ReviewCard({ review, locale }: ReviewCardProps) {\n const { t } = useTranslation();\n const triggerId = useId();\n const contentId = useId();\n const [open, setOpen] = useState(false);\n\n const breakdownHasValues = Boolean(\n review.breakdown && Object.values(review.breakdown).some((v) => v != null),\n );\n const hasDetails =\n Boolean(review.reply) ||\n breakdownHasValues ||\n Boolean(review.futureVisit) ||\n Boolean(review.recommendation);\n\n const formattedDate = useMemo(() => {\n if (!review.authoredAt) return '';\n try {\n const parsed = new Date(review.authoredAt);\n if (Number.isNaN(parsed.getTime())) return review.authoredAt;\n return new Intl.DateTimeFormat(locale, { dateStyle: 'medium' }).format(\n parsed,\n );\n } catch {\n return review.authoredAt;\n }\n }, [review.authoredAt, locale]);\n\n const pseudonym = review.pseudonym ?? t('reviewsPanel.anonymous');\n\n // Compose the full Card body. The Collapsible wraps the footer + the\n // hidden content so both share the same Radix Root and the Trigger's\n // `data-state` reaches the Content automatically (used for the height\n // animation). The Footer + Content are direct Card children so the\n // Card root's flex-col places them in order.\n const footerAndDetails = (\n <Collapsible\n open={hasDetails ? open : false}\n onOpenChange={hasDetails ? setOpen : undefined}\n >\n <Card.Footer>\n <span className=\"type-meta ds:text-[var(--muted-foreground)]\">\n {formattedDate}\n </span>\n {hasDetails ? (\n <CollapsibleTrigger asChild>\n <button\n id={triggerId}\n type=\"button\"\n data-review-trigger\n className=\"ds:ms-auto ds:inline-flex ds:items-center ds:gap-[var(--spacing-2xs)] ds:rounded-[var(--radius-sm)] ds:ps-[var(--spacing-2xs)] ds:pe-[var(--spacing-2xs)] ds:pt-[var(--spacing-2xs)] ds:pb-[var(--spacing-2xs)] ds:bg-transparent ds:border-0 ds:text-[length:var(--font-size-sm)] ds:text-[var(--primary)] ds:hover:underline ds:cursor-pointer ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-[var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)] ds:forced-colors:focus-visible:outline-[CanvasText]\"\n >\n {open\n ? t('reviewsPanel.card.collapse')\n : t('reviewsPanel.card.expand')}\n <ChevronDown\n aria-hidden=\"true\"\n className={[\n 'ds:size-4 ds:transition-transform ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n open ? 'ds:rotate-180' : '',\n ]\n .filter(Boolean)\n .join(' ')}\n />\n </button>\n </CollapsibleTrigger>\n ) : null}\n </Card.Footer>\n {hasDetails ? (\n <CollapsibleContent id={contentId} aria-labelledby={triggerId}>\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:pb-[var(--spacing-md)]\">\n {breakdownHasValues ||\n review.futureVisit ||\n review.recommendation ? (\n <DescriptionList layout=\"inline\" density=\"compact\">\n {review.breakdown?.appointmentScore != null ? (\n <DescriptionList.Row>\n <DescriptionList.Term>\n {t('reviewsPanel.breakdown.appointment')}\n </DescriptionList.Term>\n <DescriptionList.Detail>\n <Rating\n value={review.breakdown.appointmentScore}\n size=\"sm\"\n />\n </DescriptionList.Detail>\n </DescriptionList.Row>\n ) : null}\n {review.breakdown?.communicationScore != null ? (\n <DescriptionList.Row>\n <DescriptionList.Term>\n {t('reviewsPanel.breakdown.communication')}\n </DescriptionList.Term>\n <DescriptionList.Detail>\n <Rating\n value={review.breakdown.communicationScore}\n size=\"sm\"\n />\n </DescriptionList.Detail>\n </DescriptionList.Row>\n ) : null}\n {review.breakdown?.staffScore != null ? (\n <DescriptionList.Row>\n <DescriptionList.Term>\n {t('reviewsPanel.breakdown.staff')}\n </DescriptionList.Term>\n <DescriptionList.Detail>\n <Rating value={review.breakdown.staffScore} size=\"sm\" />\n </DescriptionList.Detail>\n </DescriptionList.Row>\n ) : null}\n {review.breakdown?.overallScore != null ? (\n <DescriptionList.Row>\n <DescriptionList.Term>\n {t('reviewsPanel.breakdown.overall')}\n </DescriptionList.Term>\n <DescriptionList.Detail>\n <Rating value={review.breakdown.overallScore} size=\"sm\" />\n </DescriptionList.Detail>\n </DescriptionList.Row>\n ) : null}\n {review.futureVisit ? (\n <DescriptionList.Row>\n <DescriptionList.Term>\n {t('reviewsPanel.breakdown.futureVisit')}\n </DescriptionList.Term>\n <DescriptionList.Detail>\n {t(`reviewsPanel.answer.${review.futureVisit}`)}\n </DescriptionList.Detail>\n </DescriptionList.Row>\n ) : null}\n {review.recommendation ? (\n <DescriptionList.Row>\n <DescriptionList.Term>\n {t('reviewsPanel.breakdown.recommendation')}\n </DescriptionList.Term>\n <DescriptionList.Detail>\n {t(`reviewsPanel.answer.${review.recommendation}`)}\n </DescriptionList.Detail>\n </DescriptionList.Row>\n ) : null}\n </DescriptionList>\n ) : null}\n {review.reply ? (\n <div className=\"ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)]/40 ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:pt-[var(--spacing-sm)] ds:pb-[var(--spacing-sm)]\">\n <p className=\"type-label ds:m-0 ds:mb-[var(--spacing-2xs)] ds:text-[var(--muted-foreground)] ds:font-[var(--font-weight-semibold)]\">\n {t('reviewsPanel.replyTitle')}\n </p>\n <p className=\"type-body-sm ds:m-0 ds:text-[var(--foreground)] ds:[white-space:pre-line]\">\n {review.reply}\n </p>\n </div>\n ) : null}\n </div>\n </CollapsibleContent>\n ) : null}\n </Collapsible>\n );\n\n return (\n <Card variant=\"default\" className=\"ds:shadow-[var(--shadow-sm)]\">\n <Card.Header>\n <div className=\"ds:flex ds:items-start ds:justify-between ds:gap-[var(--spacing-sm)]\">\n <h4 className=\"type-title-item ds:m-0 ds:text-[var(--foreground)]\">\n {pseudonym}\n </h4>\n <Rating value={review.overallScore} size=\"sm\" />\n </div>\n </Card.Header>\n {review.comment ? (\n <Card.Body>\n <p className=\"type-body ds:m-0 ds:text-[var(--foreground)] ds:line-clamp-2\">\n {review.comment}\n </p>\n </Card.Body>\n ) : null}\n {footerAndDetails}\n </Card>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* PanelSkeleton — loading state */\n/* -------------------------------------------------------------------- */\n\nfunction PanelSkeleton({ hideFilter }: { hideFilter: boolean }) {\n // The parent <section> already carries `aria-busy=\"true\"`, which is the\n // canonical SR signal for \"this region is loading\". Don't add `role=status`\n // + `aria-live=polite` here too — pairing both would double-announce on\n // mount. Skeleton itself is `aria-hidden`.\n return (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n <div className=\"ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)]\">\n <Skeleton variant=\"text\" width=\"40%\" />\n <Skeleton variant=\"text\" width=\"20%\" />\n </div>\n {!hideFilter ? (\n <div className=\"ds:flex ds:flex-wrap ds:gap-[var(--spacing-xs)]\">\n {Array.from({ length: 6 }, (_, i) => (\n <Skeleton\n key={`rp-fs-${i}`}\n variant=\"rounded\"\n width=\"4rem\"\n height=\"2.5rem\"\n />\n ))}\n </div>\n ) : null}\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {Array.from({ length: 3 }, (_, i) => (\n <Skeleton key={`rp-rs-${i}`} variant=\"rounded\" height=\"6rem\" />\n ))}\n </div>\n </div>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* Root variants */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva(\n // No root padding: the shared `PanelHeader` owns the header's edge\n // padding (px/pt/pb) and the body wrapper below owns the content\n // padding, so the header divider can span flush to the panel edge.\n 'ds:flex ds:w-full ds:flex-col ds:text-[var(--foreground)]',\n {\n variants: {\n // `surface=\"elevated\"` matches `Card variant=\"elevated\"` — same\n // chrome tokens — so consumers can drop their own Card wraps\n // without producing a double-card look. Padding is supplied by the\n // header + body, not the root, so the header divider reaches the\n // card edge. Default `'flat'` adds no chrome.\n surface: {\n flat: '',\n elevated: [\n 'ds:overflow-hidden',\n 'ds:rounded-[var(--radius-lg)]',\n 'ds:bg-[var(--card)] ds:text-[var(--card-foreground)]',\n 'ds:border ds:border-[color:var(--card-border)]',\n 'ds:shadow-[var(--shadow-card)]',\n ].join(' '),\n },\n },\n defaultVariants: { surface: 'flat' },\n },\n);\n\n/* -------------------------------------------------------------------- */\n/* ReviewsPanel */\n/* -------------------------------------------------------------------- */\n\nexport const ReviewsPanel = forwardRef<HTMLElement, ReviewsPanelProps>(\n (\n {\n reviews,\n aggregate,\n filter: filterProp,\n onFilterChange,\n introSlot,\n headerActionSlot,\n 'aria-label': ariaLabel,\n id,\n className,\n hideFilter = false,\n surface = 'flat',\n loading = false,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation();\n const locale = i18n.language ?? 'en';\n\n // Controlled / uncontrolled filter handling. When `filterProp` is\n // undefined the panel manages the filter internally — the consumer can\n // mount the panel and never wire `filter` / `onFilterChange` for the\n // common case where the URL doesn't carry the filter state. When the\n // prop IS provided, the consumer owns the truth.\n const [internalFilter, setInternalFilter] = useState<ReviewFilter>('all');\n const filter = filterProp ?? internalFilter;\n\n const handleFilterChange = useCallback(\n (next: ReviewFilter) => {\n if (filterProp === undefined) setInternalFilter(next);\n onFilterChange?.(next);\n },\n [filterProp, onFilterChange],\n );\n\n // Prefer the consumer-provided histogram; fall back to deriving from the\n // loaded reviews. Pagination consumers SHOULD pass an explicit histogram\n // so the per-bucket counts reflect server-side totals rather than only\n // what's loaded on this page.\n const histogram = useMemo(\n () => aggregate.histogram ?? deriveHistogram(reviews),\n [aggregate.histogram, reviews],\n );\n\n const visibleReviews = useMemo(() => {\n if (filter === 'all') return reviews;\n return reviews.filter((r) => bucketOf(r.overallScore) === filter);\n }, [reviews, filter]);\n\n /* Agent registration — exposes filter + visible count via refs so the\n imperative handle returns the latest values without re-creating the\n handle on every render. */\n const latestFilterRef = useRef(filter);\n latestFilterRef.current = filter;\n const latestVisibleCountRef = useRef(visibleReviews.length);\n latestVisibleCountRef.current = visibleReviews.length;\n\n const agentHandle = useMemo<ReviewsPanelHandle>(\n () => ({\n getFilter: () => latestFilterRef.current,\n setFilter: (next) => handleFilterChange(next),\n getVisibleCount: () => latestVisibleCountRef.current,\n }),\n [handleFilterChange],\n );\n\n const rootRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => rootRef.current as HTMLElement, []);\n useAgentRegistration(reviewsPanelAgent, agentHandle, id);\n\n const resolvedAriaLabel = ariaLabel ?? t('reviewsPanel.regionLabel');\n const dataFilter = String(filter);\n\n /* ---------------------------- Loading ---------------------------- */\n if (loading) {\n return (\n <section\n ref={rootRef as React.Ref<HTMLElement>}\n aria-label={resolvedAriaLabel}\n aria-busy=\"true\"\n id={id}\n data-component=\"reviews-panel\"\n data-component-id={id}\n data-filter={dataFilter}\n data-state=\"loading\"\n className={rootVariants({ surface, className })}\n {...rest}\n >\n <div className=\"ds:p-[var(--spacing-md)]\">\n <PanelSkeleton hideFilter={hideFilter} />\n </div>\n </section>\n );\n }\n\n /* ----------------------- Zero-total empty ------------------------ */\n // No header, no filter — just the EmptyState. The region landmark is\n // still emitted so an agent can locate the empty panel by its\n // data-component marker.\n if (aggregate.count === 0 && reviews.length === 0) {\n return (\n <section\n ref={rootRef as React.Ref<HTMLElement>}\n aria-label={resolvedAriaLabel}\n id={id}\n data-component=\"reviews-panel\"\n data-component-id={id}\n data-filter={dataFilter}\n data-state=\"empty\"\n className={rootVariants({ surface, className })}\n {...rest}\n >\n <div className=\"ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"no-results\"\n title={t('reviewsPanel.empty.title')}\n description={t('reviewsPanel.empty.description')}\n />\n </div>\n </section>\n );\n }\n\n const showFilter = !hideFilter;\n\n return (\n <section\n ref={rootRef as React.Ref<HTMLElement>}\n aria-label={resolvedAriaLabel}\n id={id}\n data-component=\"reviews-panel\"\n data-component-id={id}\n data-filter={dataFilter}\n className={rootVariants({ surface, className })}\n {...rest}\n >\n {/* Shared rail header — the panel root is a region landmark with an\n accessible name, so this nested <header> is a generic element\n (not a banner) and stays within the region. The rail injects the\n favourite / close actions via PanelHeaderActionsProvider; the\n panel's own aggregate Rating + headerActionSlot lead the cluster. */}\n <PanelHeader\n title={t('reviewsPanel.title')}\n icon={<Star aria-hidden=\"true\" />}\n titleScale=\"section\"\n sticky\n actions={\n <>\n {headerActionSlot}\n <Rating\n value={aggregate.averageScore}\n reviews={{ count: aggregate.count }}\n size=\"md\"\n />\n </>\n }\n filters={\n showFilter ? (\n <FilterBar\n filter={filter}\n histogram={histogram}\n totalCount={aggregate.count}\n onChange={handleFilterChange}\n />\n ) : undefined\n }\n />\n\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)] ds:min-w-0 ds:p-[var(--spacing-md)]\">\n {introSlot\n ? // Render the slot raw — the consumer's introSlot owns\n // its own visual chrome (Alert, Infotip, plain <p>, …).\n // 0.31.x wrapped the slot in a `bg-info/8` tinted box,\n // but when the consumer passed an Alert with its own\n // tinted surface the visual stack rendered TWO concentric\n // tinted boxes (\"double effect\"). The wrapper added no\n // semantic value either (no role, no aria), so dropping\n // it is purely visual.\n introSlot\n : null}\n\n {visibleReviews.length === 0 ? (\n // `role=\"status\"` already implies `aria-live=\"polite\"` —\n // declaring both would queue two announcements when the\n // filter changes (the radio's aria-checked flip + this\n // container's text). Keeping `role` only.\n <div\n role=\"status\"\n data-state=\"no-match\"\n className=\"ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-sm)] ds:rounded-[var(--radius-md)] ds:border ds:border-dashed ds:border-[var(--border)] ds:p-[var(--spacing-lg)] ds:text-center\"\n >\n <p className=\"type-body ds:m-0 ds:text-[var(--muted-foreground)]\">\n {filter === 'all'\n ? t('reviewsPanel.empty.title')\n : t('reviewsPanel.empty.filterDescription', {\n stars: filter,\n })}\n </p>\n {filter !== 'all' ? (\n <Button\n intent=\"secondary\"\n size=\"sm\"\n onClick={() => handleFilterChange('all')}\n >\n {t('reviewsPanel.empty.resetFilter')}\n </Button>\n ) : null}\n </div>\n ) : (\n <ol\n aria-label={t('reviewsPanel.listLabel')}\n className=\"ds:list-none ds:m-0 ds:p-0 ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\"\n >\n {visibleReviews.map((review) => (\n <li key={review.id} data-review-id={review.id}>\n <ReviewCard review={review} locale={locale} />\n </li>\n ))}\n </ol>\n )}\n </div>\n </section>\n );\n },\n);\n\nReviewsPanel.displayName = 'ReviewsPanel';\n"],"names":["reviewsPanelAgent","handle","args","FILTER_VALUES","bucketOf","score","deriveHistogram","reviews","out","r","filterRowVariants","cva","FilterBar","filter","histogram","totalCount","onChange","t","useTranslation","labelId","useId","focusIndex","setFocusIndex","useState","useEffect","i","rowRefs","useRef","focusAt","useCallback","index","_a","total","handleKeyDown","event","next","prev","last","jsxs","Fragment","jsx","val","isAll","stars","count","isSelected","isFocused","ariaLabel","node","e","Rating","ReviewCard","review","locale","triggerId","contentId","open","setOpen","breakdownHasValues","hasDetails","formattedDate","useMemo","parsed","pseudonym","footerAndDetails","Collapsible","Card","CollapsibleTrigger","ChevronDown","CollapsibleContent","DescriptionList","_b","_c","_d","PanelSkeleton","hideFilter","Skeleton","_","rootVariants","ReviewsPanel","forwardRef","aggregate","filterProp","onFilterChange","introSlot","headerActionSlot","id","className","surface","loading","rest","ref","i18n","internalFilter","setInternalFilter","handleFilterChange","visibleReviews","latestFilterRef","latestVisibleCountRef","agentHandle","rootRef","useImperativeHandle","useAgentRegistration","resolvedAriaLabel","dataFilter","EmptyState","showFilter","PanelHeader","Star","Button"],"mappings":"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"}
1
+ {"version":3,"file":"reviews-panel-B5QC4FIp.js","sources":["../../src/components/reviews-panel/reviews-panel.agent.ts","../../src/components/reviews-panel/reviews-panel.tsx"],"sourcesContent":["/* -------------------------------------------------------------------- */\n/* Agent adapter — ReviewsPanel. */\n/* */\n/* Replaces the legacy patient-reviews Carousel with a single panel that */\n/* surfaces an aggregate score, a star-bucket filter, and a vertical list */\n/* of compact review cards. The adapter exposes the active filter and the */\n/* visible review count so a host agent can drive the panel and observe */\n/* what the user actually sees after the filter is applied. The reviews */\n/* themselves remain owned by the consumer — they never flow through the */\n/* adapter (PHI: pseudonyms + free-text comments stay on the page). */\n/* -------------------------------------------------------------------- */\n\nimport type { AgentAdapter } from '../../agent/types';\nimport type { ReviewFilter, ReviewsPanelHandle } from './reviews-panel';\n\nexport const reviewsPanelAgent: AgentAdapter<ReviewsPanelHandle> = {\n id: 'reviews-panel',\n capabilities: ['filter'],\n state: {\n filter: {\n type: 'string',\n descriptionKey: 'ui.agent.reviewsPanel.state.filter',\n description:\n 'Active star-bucket filter — `\"all\"` or an integer 1..5. Reads the controlled `filter` prop.',\n read: (handle) => handle.getFilter(),\n },\n visibleCount: {\n type: 'number',\n descriptionKey: 'ui.agent.reviewsPanel.state.visibleCount',\n description:\n 'Number of reviews currently rendered after the filter is applied.',\n read: (handle) => handle.getVisibleCount(),\n },\n },\n actions: {\n set_filter: {\n // Pure ephemeral narrowing of the visible list — no data loss.\n safety: 'read',\n argsType: '{ filter: \"all\" | 1 | 2 | 3 | 4 | 5 }',\n argsSchema: {\n type: 'object',\n properties: {\n filter: {\n description: 'Star bucket to show, or \"all\" to clear the filter.',\n oneOf: [\n { type: 'string', enum: ['all'] },\n { type: 'integer', enum: [1, 2, 3, 4, 5] },\n ],\n },\n },\n required: ['filter'],\n },\n idempotent: true,\n descriptionKey: 'ui.agent.reviewsPanel.actions.setFilter',\n description:\n 'Narrow the visible review list to a star bucket, or `\"all\"` to clear the filter.',\n examples: [\n { args: { filter: 5 }, note: 'Show only 5-star reviews.' },\n { args: { filter: 'all' }, note: 'Clear the star filter.' },\n ],\n invoke: (handle, args: { filter: ReviewFilter }) => {\n handle.setFilter(args.filter);\n },\n },\n },\n domHooks: {\n root: {\n attr: 'data-component',\n value: 'reviews-panel',\n description: 'Marks the ReviewsPanel root region.',\n },\n instanceId: {\n attr: 'data-component-id',\n sourceProp: 'id',\n description: 'Sourced from the id prop.',\n },\n },\n};\n","import {\n forwardRef,\n useCallback,\n useEffect,\n useId,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n type ComponentPropsWithoutRef,\n type KeyboardEvent,\n type ReactNode,\n} from 'react';\nimport { cva } from 'class-variance-authority';\nimport { useTranslation } from 'react-i18next';\nimport { ChevronDown, Star } from 'lucide-react';\nimport { useAgentRegistration } from '../../agent/registry';\nimport { reviewsPanelAgent } from './reviews-panel.agent';\nimport { Rating } from '../rating/rating';\nimport { Card } from '../card/card';\nimport {\n Collapsible,\n CollapsibleContent,\n CollapsibleTrigger,\n} from '../collapsible/collapsible';\nimport { DescriptionList } from '../description-list/description-list';\nimport { EmptyState } from '../empty-state/empty-state';\nimport { Skeleton } from '../skeleton/skeleton';\nimport { Button } from '../button/button';\nimport { PanelHeader } from '../panel-header';\n\n/* -------------------------------------------------------------------- */\n/* ReviewsPanel */\n/* */\n/* Replaces the legacy patient-reviews Carousel with a two-column panel */\n/* — a star-bucket filter sidebar + a vertical list of compact review */\n/* cards — that surfaces the aggregate score, the volume, and (via a */\n/* per-card Collapsible) the rich per-axis breakdown alfaDocs already */\n/* collects but the carousel buried. */\n/* -------------------------------------------------------------------- */\n\n/* -------------------------------------------------------------------- */\n/* Public types */\n/* -------------------------------------------------------------------- */\n\nexport interface ReviewItem {\n id: string;\n /** When the review was authored (ISO 8601). */\n authoredAt: string;\n /** Anonymised author display (\"Marco T.\", \"Anna_M\"). Falls back to a localised \"Anonymous\". */\n pseudonym?: string;\n /** 0..max — drives the visible star summary on the compact card. */\n overallScore: number;\n /** Short free-text comment shown on the compact card. */\n comment?: string;\n /** Practice reply (revealed in the expanded panel only). */\n reply?: string;\n /** Optional per-axis breakdown — when present, the card grows an\n * \"Expand\" affordance that reveals these in a DescriptionList. */\n breakdown?: {\n appointmentScore?: number;\n communicationScore?: number;\n staffScore?: number;\n overallScore?: number;\n };\n /** Optional categorical follow-ups, surfaced inside the breakdown. */\n futureVisit?: 'yes' | 'no' | 'unsure';\n recommendation?: 'yes' | 'no' | 'unsure';\n}\n\nexport interface ReviewsAggregate {\n /** Total review count across all star buckets (may exceed the loaded set when paginated). */\n count: number;\n /** Average score across the full population (drives the header `Rating`). */\n averageScore: number;\n /**\n * Optional histogram — per-bucket count keyed by integer star value 1..5.\n * When omitted, the panel derives buckets from the loaded `reviews` array\n * (best-effort: paginated consumers SHOULD provide this explicitly).\n */\n histogram?: Record<1 | 2 | 3 | 4 | 5, number>;\n}\n\nexport type ReviewFilter = 'all' | 1 | 2 | 3 | 4 | 5;\n\nexport interface ReviewsPanelHandle {\n getFilter: () => ReviewFilter;\n setFilter: (next: ReviewFilter) => void;\n /** Total visible after filter is applied. */\n getVisibleCount: () => number;\n}\n\nexport interface ReviewsPanelProps extends Omit<\n ComponentPropsWithoutRef<'section'>,\n 'aria-label' | 'children'\n> {\n reviews: ReviewItem[];\n aggregate: ReviewsAggregate;\n\n /**\n * Active star filter. Controlled — consumer owns it for shareability via\n * URL query strings. Omit for uncontrolled (panel-managed) filtering.\n */\n filter?: ReviewFilter;\n onFilterChange?: (next: ReviewFilter) => void;\n\n /**\n * Optional intro callout shown above the list (e.g. \"Riepilogo delle\n * opinioni — i pazienti raccontano…\"). Render-prop slot so the consumer\n * can drop in `<Alert>` / `<Callout>` / plain `<p>`.\n */\n introSlot?: ReactNode;\n\n /** Optional header right-end action (e.g. a \"Leave a review\" button). */\n headerActionSlot?: ReactNode;\n\n /** Override the default region aria-label. */\n 'aria-label'?: string;\n\n /** Agent-readiness id. */\n id?: string;\n\n className?: string;\n\n /**\n * Hide the filter sidebar — useful when the panel mounts under ~640px\n * width or inside a narrow column. Defaults to false.\n */\n hideFilter?: boolean;\n\n /**\n * @default 'flat'\n * `'elevated'` wraps the panel in the equivalent of `Card variant=\"elevated\"`\n * — same tokens (`--card`, `--card-border`, `--shadow-card`,\n * `--radius-lg`), same padding. Use to drop the consumer-side\n * `<Card><Card.Body>` wrap.\n */\n surface?: 'flat' | 'elevated';\n\n /** Render skeletons for the header and the list. */\n loading?: boolean;\n}\n\n/* -------------------------------------------------------------------- */\n/* Constants & helpers */\n/* -------------------------------------------------------------------- */\n\nconst FILTER_VALUES: readonly ReviewFilter[] = ['all', 5, 4, 3, 2, 1] as const;\n\nfunction bucketOf(score: number): 1 | 2 | 3 | 4 | 5 {\n const n = Math.min(5, Math.max(1, Math.floor(score)));\n return n as 1 | 2 | 3 | 4 | 5;\n}\n\nfunction deriveHistogram(\n reviews: ReviewItem[],\n): Record<1 | 2 | 3 | 4 | 5, number> {\n const out: Record<1 | 2 | 3 | 4 | 5, number> = {\n 1: 0,\n 2: 0,\n 3: 0,\n 4: 0,\n 5: 0,\n };\n for (const r of reviews) out[bucketOf(r.overallScore)] += 1;\n return out;\n}\n\n/* -------------------------------------------------------------------- */\n/* FilterBar — hand-rolled radiogroup with roving tabindex */\n/* */\n/* Lives in the shared `PanelHeader` filters row, so it lays out */\n/* HORIZONTALLY (a wrapping bar of star-bucket chips) rather than the */\n/* legacy vertical sidebar column. Still the WAI-ARIA RadioGroup pattern */\n/* — each chip is a full click target with a non-text leading glyph (the */\n/* star ramp) and a trailing count. NOT Radix `RadioGroup` because we */\n/* need that glyph-plus-count chip shape. */\n/* */\n/* Activation is automatic — Arrow keys move BOTH focus and selection, */\n/* so a keyboard user feels the same responsiveness as a mouse user. */\n/* That's the right call here because filter activation is cheap (re- */\n/* renders the visible list); contrast with the booking ServiceGrid */\n/* where activation cascades through downstream selection state. */\n/* -------------------------------------------------------------------- */\n\nconst filterRowVariants = cva(\n [\n 'ds:relative ds:inline-flex ds:items-center ds:justify-center',\n 'ds:gap-[var(--spacing-xs)]',\n 'ds:min-h-[var(--min-target-size)]',\n 'ds:rounded-[var(--radius-md)]',\n 'ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)]',\n 'ds:pt-[var(--spacing-2xs)] ds:pb-[var(--spacing-2xs)]',\n 'ds:text-start',\n 'ds:transition-[background-color,color]',\n 'ds:duration-[var(--animation-duration)]',\n 'ds:motion-reduce:transition-none',\n 'ds:focus-visible:outline-[length:var(--focus-ring-width)]',\n 'ds:focus-visible:outline-solid',\n 'ds:focus-visible:outline-[var(--ring)]',\n 'ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)]',\n 'ds:forced-colors:focus-visible:outline-[CanvasText]',\n 'ds:cursor-pointer',\n ].join(' '),\n {\n variants: {\n state: {\n idle: 'ds:hover:bg-[var(--muted)]/30 ds:text-[var(--foreground)]',\n selected: [\n 'ds:bg-[var(--primary)]',\n 'ds:text-[var(--primary-foreground)]',\n 'ds:font-[var(--font-weight-semibold)]',\n ].join(' '),\n },\n },\n defaultVariants: { state: 'idle' },\n },\n);\n\ninterface FilterBarProps {\n filter: ReviewFilter;\n histogram: Record<1 | 2 | 3 | 4 | 5, number>;\n totalCount: number;\n onChange: (next: ReviewFilter) => void;\n}\n\nfunction FilterBar({\n filter,\n histogram,\n totalCount,\n onChange,\n}: FilterBarProps) {\n const { t } = useTranslation();\n const labelId = useId();\n\n // Roving tabindex tracks where keyboard focus is. We use AUTOMATIC\n // activation: arrow keys move focus AND fire onChange (see the rationale\n // above the component). To keep the visible aria-checked row and the\n // tab-stop aligned when the parent changes `filter` externally (e.g.\n // from a `?filter=4` URL parameter on page load), sync focusIndex to\n // the current filter via the effect below — without it, the tab stop\n // could land on `All` while the highlight shows `4`.\n const [focusIndex, setFocusIndex] = useState<number>(() =>\n Math.max(0, FILTER_VALUES.indexOf(filter)),\n );\n useEffect(() => {\n const i = FILTER_VALUES.indexOf(filter);\n if (i >= 0) setFocusIndex(i);\n }, [filter]);\n\n const rowRefs = useRef<Map<number, HTMLButtonElement>>(new Map());\n const focusAt = useCallback((index: number) => {\n rowRefs.current.get(index)?.focus();\n }, []);\n\n const total = FILTER_VALUES.length;\n const handleKeyDown = useCallback(\n (event: KeyboardEvent<HTMLButtonElement>, index: number) => {\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowRight': {\n event.preventDefault();\n const next = (index + 1) % total;\n setFocusIndex(next);\n focusAt(next);\n onChange(FILTER_VALUES[next]);\n break;\n }\n case 'ArrowUp':\n case 'ArrowLeft': {\n event.preventDefault();\n const prev = (index - 1 + total) % total;\n setFocusIndex(prev);\n focusAt(prev);\n onChange(FILTER_VALUES[prev]);\n break;\n }\n case 'Home': {\n event.preventDefault();\n setFocusIndex(0);\n focusAt(0);\n onChange(FILTER_VALUES[0]);\n break;\n }\n case 'End': {\n event.preventDefault();\n const last = total - 1;\n setFocusIndex(last);\n focusAt(last);\n onChange(FILTER_VALUES[last]);\n break;\n }\n case 'Enter':\n case ' ': {\n event.preventDefault();\n onChange(FILTER_VALUES[index]);\n break;\n }\n default:\n break;\n }\n },\n [total, focusAt, onChange],\n );\n\n return (\n <>\n <h3\n id={labelId}\n className=\"type-label ds:font-[var(--font-weight-semibold)] ds:text-[var(--foreground)] ds:m-0\"\n >\n {t('reviewsPanel.filterTitle')}\n </h3>\n <div\n role=\"radiogroup\"\n aria-labelledby={labelId}\n className=\"ds:flex ds:flex-wrap ds:items-center ds:gap-[var(--spacing-2xs)]\"\n >\n {FILTER_VALUES.map((val, index) => {\n const isAll = val === 'all';\n const stars = isAll ? 0 : (val as 1 | 2 | 3 | 4 | 5);\n const count = isAll\n ? totalCount\n : histogram[stars as 1 | 2 | 3 | 4 | 5];\n const isSelected = val === filter;\n const isFocused = focusIndex === index;\n const ariaLabel = isAll\n ? t('reviewsPanel.filter.allLabel', { count })\n : t('reviewsPanel.filter.starsLabel', { stars, count });\n\n return (\n <button\n key={String(val)}\n ref={(node) => {\n if (node) rowRefs.current.set(index, node);\n else rowRefs.current.delete(index);\n }}\n type=\"button\"\n role=\"radio\"\n aria-checked={isSelected}\n aria-label={ariaLabel}\n tabIndex={isFocused ? 0 : -1}\n onClick={() => {\n setFocusIndex(index);\n onChange(val);\n }}\n onFocus={() => setFocusIndex(index)}\n onKeyDown={(e) => handleKeyDown(e, index)}\n data-filter-bucket={String(val)}\n className={filterRowVariants({\n state: isSelected ? 'selected' : 'idle',\n })}\n >\n <span\n aria-hidden=\"true\"\n className=\"ds:inline-flex ds:items-center ds:gap-[var(--spacing-xs)]\"\n >\n {isAll ? (\n <span className=\"type-label\">\n {t('reviewsPanel.filter.allShort')}\n </span>\n ) : (\n <Rating value={stars} size=\"sm\" decorative />\n )}\n </span>\n <span\n aria-hidden=\"true\"\n className={[\n 'type-meta',\n // Idle row: count is dimmed (--muted-foreground over\n // --background ≈ 4.5:1, AA passes). Selected row\n // paints violet bg + white text on the BUTTON, but\n // the count's own explicit color override would\n // otherwise win the cascade and leave dark navy-grey\n // text on the violet pill (~3:1, AA-fail). Match the\n // row's foreground when selected; slight opacity\n // keeps the count secondary to the label.\n isSelected\n ? 'ds:text-[color:var(--primary-foreground)]'\n : 'ds:text-[var(--muted-foreground)]',\n ].join(' ')}\n >\n {count}\n </span>\n </button>\n );\n })}\n </div>\n </>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* ReviewCard — compact card with optional Collapsible breakdown */\n/* -------------------------------------------------------------------- */\n\ninterface ReviewCardProps {\n review: ReviewItem;\n locale: string;\n}\n\nfunction ReviewCard({ review, locale }: ReviewCardProps) {\n const { t } = useTranslation();\n const triggerId = useId();\n const contentId = useId();\n const [open, setOpen] = useState(false);\n\n const breakdownHasValues = Boolean(\n review.breakdown && Object.values(review.breakdown).some((v) => v != null),\n );\n const hasDetails =\n Boolean(review.reply) ||\n breakdownHasValues ||\n Boolean(review.futureVisit) ||\n Boolean(review.recommendation);\n\n const formattedDate = useMemo(() => {\n if (!review.authoredAt) return '';\n try {\n const parsed = new Date(review.authoredAt);\n if (Number.isNaN(parsed.getTime())) return review.authoredAt;\n return new Intl.DateTimeFormat(locale, { dateStyle: 'medium' }).format(\n parsed,\n );\n } catch {\n return review.authoredAt;\n }\n }, [review.authoredAt, locale]);\n\n const pseudonym = review.pseudonym ?? t('reviewsPanel.anonymous');\n\n // Compose the full Card body. The Collapsible wraps the footer + the\n // hidden content so both share the same Radix Root and the Trigger's\n // `data-state` reaches the Content automatically (used for the height\n // animation). The Footer + Content are direct Card children so the\n // Card root's flex-col places them in order.\n const footerAndDetails = (\n <Collapsible\n open={hasDetails ? open : false}\n onOpenChange={hasDetails ? setOpen : undefined}\n >\n <Card.Footer>\n <span className=\"type-meta ds:text-[var(--muted-foreground)]\">\n {formattedDate}\n </span>\n {hasDetails ? (\n <CollapsibleTrigger asChild>\n <button\n id={triggerId}\n type=\"button\"\n data-review-trigger\n className=\"ds:ms-auto ds:inline-flex ds:items-center ds:gap-[var(--spacing-2xs)] ds:rounded-[var(--radius-sm)] ds:ps-[var(--spacing-2xs)] ds:pe-[var(--spacing-2xs)] ds:pt-[var(--spacing-2xs)] ds:pb-[var(--spacing-2xs)] ds:bg-transparent ds:border-0 ds:text-[length:var(--font-size-sm)] ds:text-[var(--primary)] ds:hover:underline ds:cursor-pointer ds:focus-visible:outline-[length:var(--focus-ring-width)] ds:focus-visible:outline-solid ds:focus-visible:outline-[var(--ring)] ds:focus-visible:outline-offset-[length:var(--focus-ring-offset)] ds:forced-colors:focus-visible:outline-[CanvasText]\"\n >\n {open\n ? t('reviewsPanel.card.collapse')\n : t('reviewsPanel.card.expand')}\n <ChevronDown\n aria-hidden=\"true\"\n className={[\n 'ds:size-4 ds:transition-transform ds:duration-[var(--animation-duration)] ds:motion-reduce:transition-none',\n open ? 'ds:rotate-180' : '',\n ]\n .filter(Boolean)\n .join(' ')}\n />\n </button>\n </CollapsibleTrigger>\n ) : null}\n </Card.Footer>\n {hasDetails ? (\n <CollapsibleContent id={contentId} aria-labelledby={triggerId}>\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)] ds:ps-[var(--spacing-md)] ds:pe-[var(--spacing-md)] ds:pb-[var(--spacing-md)]\">\n {breakdownHasValues ||\n review.futureVisit ||\n review.recommendation ? (\n <DescriptionList layout=\"inline\" density=\"compact\">\n {review.breakdown?.appointmentScore != null ? (\n <DescriptionList.Row>\n <DescriptionList.Term>\n {t('reviewsPanel.breakdown.appointment')}\n </DescriptionList.Term>\n <DescriptionList.Detail>\n <Rating\n value={review.breakdown.appointmentScore}\n size=\"sm\"\n />\n </DescriptionList.Detail>\n </DescriptionList.Row>\n ) : null}\n {review.breakdown?.communicationScore != null ? (\n <DescriptionList.Row>\n <DescriptionList.Term>\n {t('reviewsPanel.breakdown.communication')}\n </DescriptionList.Term>\n <DescriptionList.Detail>\n <Rating\n value={review.breakdown.communicationScore}\n size=\"sm\"\n />\n </DescriptionList.Detail>\n </DescriptionList.Row>\n ) : null}\n {review.breakdown?.staffScore != null ? (\n <DescriptionList.Row>\n <DescriptionList.Term>\n {t('reviewsPanel.breakdown.staff')}\n </DescriptionList.Term>\n <DescriptionList.Detail>\n <Rating value={review.breakdown.staffScore} size=\"sm\" />\n </DescriptionList.Detail>\n </DescriptionList.Row>\n ) : null}\n {review.breakdown?.overallScore != null ? (\n <DescriptionList.Row>\n <DescriptionList.Term>\n {t('reviewsPanel.breakdown.overall')}\n </DescriptionList.Term>\n <DescriptionList.Detail>\n <Rating value={review.breakdown.overallScore} size=\"sm\" />\n </DescriptionList.Detail>\n </DescriptionList.Row>\n ) : null}\n {review.futureVisit ? (\n <DescriptionList.Row>\n <DescriptionList.Term>\n {t('reviewsPanel.breakdown.futureVisit')}\n </DescriptionList.Term>\n <DescriptionList.Detail>\n {t(`reviewsPanel.answer.${review.futureVisit}`)}\n </DescriptionList.Detail>\n </DescriptionList.Row>\n ) : null}\n {review.recommendation ? (\n <DescriptionList.Row>\n <DescriptionList.Term>\n {t('reviewsPanel.breakdown.recommendation')}\n </DescriptionList.Term>\n <DescriptionList.Detail>\n {t(`reviewsPanel.answer.${review.recommendation}`)}\n </DescriptionList.Detail>\n </DescriptionList.Row>\n ) : null}\n </DescriptionList>\n ) : null}\n {review.reply ? (\n <div className=\"ds:rounded-[var(--radius-sm)] ds:bg-[var(--muted)]/40 ds:ps-[var(--spacing-sm)] ds:pe-[var(--spacing-sm)] ds:pt-[var(--spacing-sm)] ds:pb-[var(--spacing-sm)]\">\n <p className=\"type-label ds:m-0 ds:mb-[var(--spacing-2xs)] ds:text-[var(--muted-foreground)] ds:font-[var(--font-weight-semibold)]\">\n {t('reviewsPanel.replyTitle')}\n </p>\n <p className=\"type-body-sm ds:m-0 ds:text-[var(--foreground)] ds:[white-space:pre-line]\">\n {review.reply}\n </p>\n </div>\n ) : null}\n </div>\n </CollapsibleContent>\n ) : null}\n </Collapsible>\n );\n\n return (\n <Card variant=\"default\" className=\"ds:shadow-[var(--shadow-sm)]\">\n <Card.Header>\n <div className=\"ds:flex ds:items-start ds:justify-between ds:gap-[var(--spacing-sm)]\">\n <h4 className=\"type-title-item ds:m-0 ds:text-[var(--foreground)]\">\n {pseudonym}\n </h4>\n <Rating value={review.overallScore} size=\"sm\" />\n </div>\n </Card.Header>\n {review.comment ? (\n <Card.Body>\n <p className=\"type-body ds:m-0 ds:text-[var(--foreground)] ds:line-clamp-2\">\n {review.comment}\n </p>\n </Card.Body>\n ) : null}\n {footerAndDetails}\n </Card>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* PanelSkeleton — loading state */\n/* -------------------------------------------------------------------- */\n\nfunction PanelSkeleton({ hideFilter }: { hideFilter: boolean }) {\n // The parent <section> already carries `aria-busy=\"true\"`, which is the\n // canonical SR signal for \"this region is loading\". Don't add `role=status`\n // + `aria-live=polite` here too — pairing both would double-announce on\n // mount. Skeleton itself is `aria-hidden`.\n return (\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)]\">\n <div className=\"ds:flex ds:items-center ds:justify-between ds:gap-[var(--spacing-sm)]\">\n <Skeleton variant=\"text\" width=\"40%\" />\n <Skeleton variant=\"text\" width=\"20%\" />\n </div>\n {!hideFilter ? (\n <div className=\"ds:flex ds:flex-wrap ds:gap-[var(--spacing-xs)]\">\n {Array.from({ length: 6 }, (_, i) => (\n <Skeleton\n key={`rp-fs-${i}`}\n variant=\"rounded\"\n width=\"4rem\"\n height=\"2.5rem\"\n />\n ))}\n </div>\n ) : null}\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\">\n {Array.from({ length: 3 }, (_, i) => (\n <Skeleton key={`rp-rs-${i}`} variant=\"rounded\" height=\"6rem\" />\n ))}\n </div>\n </div>\n );\n}\n\n/* -------------------------------------------------------------------- */\n/* Root variants */\n/* -------------------------------------------------------------------- */\n\nconst rootVariants = cva(\n // No root padding: the shared `PanelHeader` owns the header's edge\n // padding (px/pt/pb) and the body wrapper below owns the content\n // padding, so the header divider can span flush to the panel edge.\n 'ds:flex ds:w-full ds:flex-col ds:text-[var(--foreground)]',\n {\n variants: {\n // `surface=\"elevated\"` matches `Card variant=\"elevated\"` — same\n // chrome tokens — so consumers can drop their own Card wraps\n // without producing a double-card look. Padding is supplied by the\n // header + body, not the root, so the header divider reaches the\n // card edge. Default `'flat'` adds no chrome.\n surface: {\n flat: '',\n elevated: [\n 'ds:overflow-hidden',\n 'ds:rounded-[var(--radius-lg)]',\n 'ds:bg-[var(--card)] ds:text-[var(--card-foreground)]',\n 'ds:border ds:border-[color:var(--card-border)]',\n 'ds:shadow-[var(--shadow-card)]',\n ].join(' '),\n },\n },\n defaultVariants: { surface: 'flat' },\n },\n);\n\n/* -------------------------------------------------------------------- */\n/* ReviewsPanel */\n/* -------------------------------------------------------------------- */\n\nexport const ReviewsPanel = forwardRef<HTMLElement, ReviewsPanelProps>(\n (\n {\n reviews,\n aggregate,\n filter: filterProp,\n onFilterChange,\n introSlot,\n headerActionSlot,\n 'aria-label': ariaLabel,\n id,\n className,\n hideFilter = false,\n surface = 'flat',\n loading = false,\n ...rest\n },\n ref,\n ) => {\n const { t, i18n } = useTranslation();\n const locale = i18n.language ?? 'en';\n\n // Controlled / uncontrolled filter handling. When `filterProp` is\n // undefined the panel manages the filter internally — the consumer can\n // mount the panel and never wire `filter` / `onFilterChange` for the\n // common case where the URL doesn't carry the filter state. When the\n // prop IS provided, the consumer owns the truth.\n const [internalFilter, setInternalFilter] = useState<ReviewFilter>('all');\n const filter = filterProp ?? internalFilter;\n\n const handleFilterChange = useCallback(\n (next: ReviewFilter) => {\n if (filterProp === undefined) setInternalFilter(next);\n onFilterChange?.(next);\n },\n [filterProp, onFilterChange],\n );\n\n // Prefer the consumer-provided histogram; fall back to deriving from the\n // loaded reviews. Pagination consumers SHOULD pass an explicit histogram\n // so the per-bucket counts reflect server-side totals rather than only\n // what's loaded on this page.\n const histogram = useMemo(\n () => aggregate.histogram ?? deriveHistogram(reviews),\n [aggregate.histogram, reviews],\n );\n\n const visibleReviews = useMemo(() => {\n if (filter === 'all') return reviews;\n return reviews.filter((r) => bucketOf(r.overallScore) === filter);\n }, [reviews, filter]);\n\n /* Agent registration — exposes filter + visible count via refs so the\n imperative handle returns the latest values without re-creating the\n handle on every render. */\n const latestFilterRef = useRef(filter);\n latestFilterRef.current = filter;\n const latestVisibleCountRef = useRef(visibleReviews.length);\n latestVisibleCountRef.current = visibleReviews.length;\n\n const agentHandle = useMemo<ReviewsPanelHandle>(\n () => ({\n getFilter: () => latestFilterRef.current,\n setFilter: (next) => handleFilterChange(next),\n getVisibleCount: () => latestVisibleCountRef.current,\n }),\n [handleFilterChange],\n );\n\n const rootRef = useRef<HTMLElement>(null);\n useImperativeHandle(ref, () => rootRef.current as HTMLElement, []);\n useAgentRegistration(reviewsPanelAgent, agentHandle, id);\n\n const resolvedAriaLabel = ariaLabel ?? t('reviewsPanel.regionLabel');\n const dataFilter = String(filter);\n\n /* ---------------------------- Loading ---------------------------- */\n if (loading) {\n return (\n <section\n ref={rootRef as React.Ref<HTMLElement>}\n aria-label={resolvedAriaLabel}\n aria-busy=\"true\"\n id={id}\n data-component=\"reviews-panel\"\n data-component-id={id}\n data-filter={dataFilter}\n data-state=\"loading\"\n className={rootVariants({ surface, className })}\n {...rest}\n >\n <div className=\"ds:p-[var(--spacing-md)]\">\n <PanelSkeleton hideFilter={hideFilter} />\n </div>\n </section>\n );\n }\n\n /* ----------------------- Zero-total empty ------------------------ */\n // No header, no filter — just the EmptyState. The region landmark is\n // still emitted so an agent can locate the empty panel by its\n // data-component marker.\n if (aggregate.count === 0 && reviews.length === 0) {\n return (\n <section\n ref={rootRef as React.Ref<HTMLElement>}\n aria-label={resolvedAriaLabel}\n id={id}\n data-component=\"reviews-panel\"\n data-component-id={id}\n data-filter={dataFilter}\n data-state=\"empty\"\n className={rootVariants({ surface, className })}\n {...rest}\n >\n <div className=\"ds:p-[var(--spacing-md)]\">\n <EmptyState\n variant=\"no-results\"\n title={t('reviewsPanel.empty.title')}\n description={t('reviewsPanel.empty.description')}\n />\n </div>\n </section>\n );\n }\n\n const showFilter = !hideFilter;\n\n return (\n <section\n ref={rootRef as React.Ref<HTMLElement>}\n aria-label={resolvedAriaLabel}\n id={id}\n data-component=\"reviews-panel\"\n data-component-id={id}\n data-filter={dataFilter}\n className={rootVariants({ surface, className })}\n {...rest}\n >\n {/* Shared rail header — the panel root is a region landmark with an\n accessible name, so this nested <header> is a generic element\n (not a banner) and stays within the region. The rail injects the\n favourite / close actions via PanelHeaderActionsProvider; the\n panel's own aggregate Rating + headerActionSlot lead the cluster. */}\n <PanelHeader\n title={t('reviewsPanel.title')}\n icon={<Star aria-hidden=\"true\" />}\n titleScale=\"section\"\n sticky\n actions={\n <>\n {headerActionSlot}\n <Rating\n value={aggregate.averageScore}\n reviews={{ count: aggregate.count }}\n size=\"md\"\n />\n </>\n }\n filters={\n showFilter ? (\n <FilterBar\n filter={filter}\n histogram={histogram}\n totalCount={aggregate.count}\n onChange={handleFilterChange}\n />\n ) : undefined\n }\n />\n\n <div className=\"ds:flex ds:flex-col ds:gap-[var(--spacing-md)] ds:min-w-0 ds:p-[var(--spacing-md)]\">\n {introSlot\n ? // Render the slot raw — the consumer's introSlot owns\n // its own visual chrome (Alert, Infotip, plain <p>, …).\n // 0.31.x wrapped the slot in a `bg-info/8` tinted box,\n // but when the consumer passed an Alert with its own\n // tinted surface the visual stack rendered TWO concentric\n // tinted boxes (\"double effect\"). The wrapper added no\n // semantic value either (no role, no aria), so dropping\n // it is purely visual.\n introSlot\n : null}\n\n {visibleReviews.length === 0 ? (\n // `role=\"status\"` already implies `aria-live=\"polite\"` —\n // declaring both would queue two announcements when the\n // filter changes (the radio's aria-checked flip + this\n // container's text). Keeping `role` only.\n <div\n role=\"status\"\n data-state=\"no-match\"\n className=\"ds:flex ds:flex-col ds:items-center ds:gap-[var(--spacing-sm)] ds:rounded-[var(--radius-md)] ds:border ds:border-dashed ds:border-[var(--border)] ds:p-[var(--spacing-lg)] ds:text-center\"\n >\n <p className=\"type-body ds:m-0 ds:text-[var(--muted-foreground)]\">\n {filter === 'all'\n ? t('reviewsPanel.empty.title')\n : t('reviewsPanel.empty.filterDescription', {\n stars: filter,\n })}\n </p>\n {filter !== 'all' ? (\n <Button\n intent=\"secondary\"\n size=\"sm\"\n onClick={() => handleFilterChange('all')}\n >\n {t('reviewsPanel.empty.resetFilter')}\n </Button>\n ) : null}\n </div>\n ) : (\n <ol\n aria-label={t('reviewsPanel.listLabel')}\n className=\"ds:list-none ds:m-0 ds:p-0 ds:flex ds:flex-col ds:gap-[var(--spacing-sm)]\"\n >\n {visibleReviews.map((review) => (\n <li key={review.id} data-review-id={review.id}>\n <ReviewCard review={review} locale={locale} />\n </li>\n ))}\n </ol>\n )}\n </div>\n </section>\n );\n },\n);\n\nReviewsPanel.displayName = 'ReviewsPanel';\n"],"names":["reviewsPanelAgent","handle","args","FILTER_VALUES","bucketOf","score","deriveHistogram","reviews","out","r","filterRowVariants","cva","FilterBar","filter","histogram","totalCount","onChange","t","useTranslation","labelId","useId","focusIndex","setFocusIndex","useState","useEffect","i","rowRefs","useRef","focusAt","useCallback","index","_a","total","handleKeyDown","event","next","prev","last","jsxs","Fragment","jsx","val","isAll","stars","count","isSelected","isFocused","ariaLabel","node","e","Rating","ReviewCard","review","locale","triggerId","contentId","open","setOpen","breakdownHasValues","hasDetails","formattedDate","useMemo","parsed","pseudonym","footerAndDetails","Collapsible","Card","CollapsibleTrigger","ChevronDown","CollapsibleContent","DescriptionList","_b","_c","_d","PanelSkeleton","hideFilter","Skeleton","_","rootVariants","ReviewsPanel","forwardRef","aggregate","filterProp","onFilterChange","introSlot","headerActionSlot","id","className","surface","loading","rest","ref","i18n","internalFilter","setInternalFilter","handleFilterChange","visibleReviews","latestFilterRef","latestVisibleCountRef","agentHandle","rootRef","useImperativeHandle","useAgentRegistration","resolvedAriaLabel","dataFilter","EmptyState","showFilter","PanelHeader","Star","Button"],"mappings":";;;;;;;;;;;;;;;AAeO,MAAMA,KAAsD;AAAA,EACjE,IAAI;AAAA,EACJ,cAAc,CAAC,QAAQ;AAAA,EACvB,OAAO;AAAA,IACL,QAAQ;AAAA,MACN,MAAM;AAAA,MACN,gBAAgB;AAAA,MAChB,aACE;AAAA,MACF,MAAM,CAACC,MAAWA,EAAO,UAAA;AAAA,IAAU;AAAA,IAErC,cAAc;AAAA,MACZ,MAAM;AAAA,MACN,gBAAgB;AAAA,MAChB,aACE;AAAA,MACF,MAAM,CAACA,MAAWA,EAAO,gBAAA;AAAA,IAAgB;AAAA,EAC3C;AAAA,EAEF,SAAS;AAAA,IACP,YAAY;AAAA;AAAA,MAEV,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,YAAY;AAAA,QACV,MAAM;AAAA,QACN,YAAY;AAAA,UACV,QAAQ;AAAA,YACN,aAAa;AAAA,YACb,OAAO;AAAA,cACL,EAAE,MAAM,UAAU,MAAM,CAAC,KAAK,EAAA;AAAA,cAC9B,EAAE,MAAM,WAAW,MAAM,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC,EAAA;AAAA,YAAE;AAAA,UAC3C;AAAA,QACF;AAAA,QAEF,UAAU,CAAC,QAAQ;AAAA,MAAA;AAAA,MAErB,YAAY;AAAA,MACZ,gBAAgB;AAAA,MAChB,aACE;AAAA,MACF,UAAU;AAAA,QACR,EAAE,MAAM,EAAE,QAAQ,EAAA,GAAK,MAAM,4BAAA;AAAA,QAC7B,EAAE,MAAM,EAAE,QAAQ,MAAA,GAAS,MAAM,yBAAA;AAAA,MAAyB;AAAA,MAE5D,QAAQ,CAACA,GAAQC,MAAmC;AAClD,QAAAD,EAAO,UAAUC,EAAK,MAAM;AAAA,MAC9B;AAAA,IAAA;AAAA,EACF;AAAA,EAEF,UAAU;AAAA,IACR,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,IAAA;AAAA,IAEf,YAAY;AAAA,MACV,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,aAAa;AAAA,IAAA;AAAA,EACf;AAEJ,GCsEMC,IAAyC,CAAC,OAAO,GAAG,GAAG,GAAG,GAAG,CAAC;AAEpE,SAASC,EAASC,GAAkC;AAElD,SADU,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,KAAK,MAAMA,CAAK,CAAC,CAAC;AAEtD;AAEA,SAASC,GACPC,GACmC;AACnC,QAAMC,IAAyC;AAAA,IAC7C,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EAAA;AAEL,aAAWC,KAAKF,EAAS,CAAAC,EAAIJ,EAASK,EAAE,YAAY,CAAC,KAAK;AAC1D,SAAOD;AACT;AAmBA,MAAME,KAAoBC;AAAA,EACxB;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,EACA,KAAK,GAAG;AAAA,EACV;AAAA,IACE,UAAU;AAAA,MACR,OAAO;AAAA,QACL,MAAM;AAAA,QACN,UAAU;AAAA,UACR;AAAA,UACA;AAAA,UACA;AAAA,QAAA,EACA,KAAK,GAAG;AAAA,MAAA;AAAA,IACZ;AAAA,IAEF,iBAAiB,EAAE,OAAO,OAAA;AAAA,EAAO;AAErC;AASA,SAASC,GAAU;AAAA,EACjB,QAAAC;AAAA,EACA,WAAAC;AAAA,EACA,YAAAC;AAAA,EACA,UAAAC;AACF,GAAmB;AACjB,QAAM,EAAE,GAAAC,EAAA,IAAMC,EAAA,GACRC,IAAUC,EAAA,GASV,CAACC,GAAYC,CAAa,IAAIC;AAAA,IAAiB,MACnD,KAAK,IAAI,GAAGpB,EAAc,QAAQU,CAAM,CAAC;AAAA,EAAA;AAE3C,EAAAW,EAAU,MAAM;AACd,UAAMC,IAAItB,EAAc,QAAQU,CAAM;AACtC,IAAIY,KAAK,KAAGH,EAAcG,CAAC;AAAA,EAC7B,GAAG,CAACZ,CAAM,CAAC;AAEX,QAAMa,IAAUC,EAAuC,oBAAI,KAAK,GAC1DC,IAAUC,EAAY,CAACC,MAAkB;;AAC7C,KAAAC,IAAAL,EAAQ,QAAQ,IAAII,CAAK,MAAzB,QAAAC,EAA4B;AAAA,EAC9B,GAAG,CAAA,CAAE,GAECC,IAAQ7B,EAAc,QACtB8B,IAAgBJ;AAAA,IACpB,CAACK,GAAyCJ,MAAkB;AAC1D,cAAQI,EAAM,KAAA;AAAA,QACZ,KAAK;AAAA,QACL,KAAK,cAAc;AACjB,UAAAA,EAAM,eAAA;AACN,gBAAMC,KAAQL,IAAQ,KAAKE;AAC3B,UAAAV,EAAca,CAAI,GAClBP,EAAQO,CAAI,GACZnB,EAASb,EAAcgC,CAAI,CAAC;AAC5B;AAAA,QACF;AAAA,QACA,KAAK;AAAA,QACL,KAAK,aAAa;AAChB,UAAAD,EAAM,eAAA;AACN,gBAAME,KAAQN,IAAQ,IAAIE,KAASA;AACnC,UAAAV,EAAcc,CAAI,GAClBR,EAAQQ,CAAI,GACZpB,EAASb,EAAciC,CAAI,CAAC;AAC5B;AAAA,QACF;AAAA,QACA,KAAK,QAAQ;AACX,UAAAF,EAAM,eAAA,GACNZ,EAAc,CAAC,GACfM,EAAQ,CAAC,GACTZ,EAASb,EAAc,CAAC,CAAC;AACzB;AAAA,QACF;AAAA,QACA,KAAK,OAAO;AACV,UAAA+B,EAAM,eAAA;AACN,gBAAMG,IAAOL,IAAQ;AACrB,UAAAV,EAAce,CAAI,GAClBT,EAAQS,CAAI,GACZrB,EAASb,EAAckC,CAAI,CAAC;AAC5B;AAAA,QACF;AAAA,QACA,KAAK;AAAA,QACL,KAAK,KAAK;AACR,UAAAH,EAAM,eAAA,GACNlB,EAASb,EAAc2B,CAAK,CAAC;AAC7B;AAAA,QACF;AAAA,MAEE;AAAA,IAEN;AAAA,IACA,CAACE,GAAOJ,GAASZ,CAAQ;AAAA,EAAA;AAG3B,SACE,gBAAAsB,EAAAC,GAAA,EACE,UAAA;AAAA,IAAA,gBAAAC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,IAAIrB;AAAA,QACJ,WAAU;AAAA,QAET,YAAE,0BAA0B;AAAA,MAAA;AAAA,IAAA;AAAA,IAE/B,gBAAAqB;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,mBAAiBrB;AAAA,QACjB,WAAU;AAAA,QAET,UAAAhB,EAAc,IAAI,CAACsC,GAAKX,MAAU;AACjC,gBAAMY,IAAQD,MAAQ,OAChBE,IAAQD,IAAQ,IAAKD,GACrBG,IAAQF,IACV3B,IACAD,EAAU6B,CAA0B,GAClCE,IAAaJ,MAAQ5B,GACrBiC,IAAYzB,MAAeS,GAC3BiB,IAAYL,IACdzB,EAAE,gCAAgC,EAAE,OAAA2B,GAAO,IAC3C3B,EAAE,kCAAkC,EAAE,OAAA0B,GAAO,OAAAC,GAAO;AAExD,iBACE,gBAAAN;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC,KAAK,CAACU,MAAS;AACb,gBAAIA,IAAMtB,EAAQ,QAAQ,IAAII,GAAOkB,CAAI,IACpCtB,EAAQ,QAAQ,OAAOI,CAAK;AAAA,cACnC;AAAA,cACA,MAAK;AAAA,cACL,MAAK;AAAA,cACL,gBAAce;AAAA,cACd,cAAYE;AAAA,cACZ,UAAUD,IAAY,IAAI;AAAA,cAC1B,SAAS,MAAM;AACb,gBAAAxB,EAAcQ,CAAK,GACnBd,EAASyB,CAAG;AAAA,cACd;AAAA,cACA,SAAS,MAAMnB,EAAcQ,CAAK;AAAA,cAClC,WAAW,CAACmB,MAAMhB,EAAcgB,GAAGnB,CAAK;AAAA,cACxC,sBAAoB,OAAOW,CAAG;AAAA,cAC9B,WAAW/B,GAAkB;AAAA,gBAC3B,OAAOmC,IAAa,aAAa;AAAA,cAAA,CAClC;AAAA,cAED,UAAA;AAAA,gBAAA,gBAAAL;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,eAAY;AAAA,oBACZ,WAAU;AAAA,oBAET,cACC,gBAAAA,EAAC,QAAA,EAAK,WAAU,cACb,YAAE,8BAA8B,EAAA,CACnC,IAEA,gBAAAA,EAACU,KAAO,OAAOP,GAAO,MAAK,MAAK,YAAU,GAAA,CAAC;AAAA,kBAAA;AAAA,gBAAA;AAAA,gBAG/C,gBAAAH;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,eAAY;AAAA,oBACZ,WAAW;AAAA,sBACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBASAK,IACI,8CACA;AAAA,oBAAA,EACJ,KAAK,GAAG;AAAA,oBAET,UAAAD;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACH;AAAA,YAAA;AAAA,YAnDK,OAAOH,CAAG;AAAA,UAAA;AAAA,QAsDrB,CAAC;AAAA,MAAA;AAAA,IAAA;AAAA,EACH,GACF;AAEJ;AAWA,SAASU,GAAW,EAAE,QAAAC,GAAQ,QAAAC,KAA2B;;AACvD,QAAM,EAAE,GAAApC,EAAA,IAAMC,EAAA,GACRoC,IAAYlC,EAAA,GACZmC,IAAYnC,EAAA,GACZ,CAACoC,GAAMC,CAAO,IAAIlC,EAAS,EAAK,GAEhCmC,IAAqB,GACzBN,EAAO,aAAa,OAAO,OAAOA,EAAO,SAAS,EAAE,KAAK,CAAC,MAAM,KAAK,IAAI,IAErEO,IACJ,EAAQP,EAAO,SACfM,KACA,EAAQN,EAAO,eACf,EAAQA,EAAO,gBAEXQ,IAAgBC,EAAQ,MAAM;AAClC,QAAI,CAACT,EAAO,WAAY,QAAO;AAC/B,QAAI;AACF,YAAMU,IAAS,IAAI,KAAKV,EAAO,UAAU;AACzC,aAAI,OAAO,MAAMU,EAAO,SAAS,IAAUV,EAAO,aAC3C,IAAI,KAAK,eAAeC,GAAQ,EAAE,WAAW,SAAA,CAAU,EAAE;AAAA,QAC9DS;AAAA,MAAA;AAAA,IAEJ,QAAQ;AACN,aAAOV,EAAO;AAAA,IAChB;AAAA,EACF,GAAG,CAACA,EAAO,YAAYC,CAAM,CAAC,GAExBU,IAAYX,EAAO,aAAanC,EAAE,wBAAwB,GAO1D+C,IACJ,gBAAA1B;AAAA,IAAC2B;AAAA,IAAA;AAAA,MACC,MAAMN,IAAaH,IAAO;AAAA,MAC1B,cAAcG,IAAaF,IAAU;AAAA,MAErC,UAAA;AAAA,QAAA,gBAAAnB,EAAC4B,EAAK,QAAL,EACC,UAAA;AAAA,UAAA,gBAAA1B,EAAC,QAAA,EAAK,WAAU,+CACb,UAAAoB,GACH;AAAA,UACCD,IACC,gBAAAnB,EAAC2B,GAAA,EAAmB,SAAO,IACzB,UAAA,gBAAA7B;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,IAAIgB;AAAA,cACJ,MAAK;AAAA,cACL,uBAAmB;AAAA,cACnB,WAAU;AAAA,cAET,UAAA;AAAA,gBACGrC,EADHuC,IACK,+BACA,0BAD4B;AAAA,gBAElC,gBAAAhB;AAAA,kBAAC4B;AAAA,kBAAA;AAAA,oBACC,eAAY;AAAA,oBACZ,WAAW;AAAA,sBACT;AAAA,sBACAZ,IAAO,kBAAkB;AAAA,oBAAA,EAExB,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACb;AAAA,YAAA;AAAA,UAAA,GAEJ,IACE;AAAA,QAAA,GACN;AAAA,QACCG,IACC,gBAAAnB,EAAC6B,IAAA,EAAmB,IAAId,GAAW,mBAAiBD,GAClD,UAAA,gBAAAhB,EAAC,OAAA,EAAI,WAAU,gIACZ,UAAA;AAAA,UAAAoB,KACDN,EAAO,eACPA,EAAO,mCACJkB,GAAA,EAAgB,QAAO,UAAS,SAAQ,WACtC,UAAA;AAAA,cAAAvC,IAAAqB,EAAO,cAAP,gBAAArB,EAAkB,qBAAoB,OACrC,gBAAAO,EAACgC,EAAgB,KAAhB,EACC,UAAA;AAAA,cAAA,gBAAA9B,EAAC8B,EAAgB,MAAhB,EACE,UAAArD,EAAE,oCAAoC,GACzC;AAAA,cACA,gBAAAuB,EAAC8B,EAAgB,QAAhB,EACC,UAAA,gBAAA9B;AAAA,gBAACU;AAAA,gBAAA;AAAA,kBACC,OAAOE,EAAO,UAAU;AAAA,kBACxB,MAAK;AAAA,gBAAA;AAAA,cAAA,EACP,CACF;AAAA,YAAA,EAAA,CACF,IACE;AAAA,cACHmB,IAAAnB,EAAO,cAAP,gBAAAmB,EAAkB,uBAAsB,OACvC,gBAAAjC,EAACgC,EAAgB,KAAhB,EACC,UAAA;AAAA,cAAA,gBAAA9B,EAAC8B,EAAgB,MAAhB,EACE,UAAArD,EAAE,sCAAsC,GAC3C;AAAA,cACA,gBAAAuB,EAAC8B,EAAgB,QAAhB,EACC,UAAA,gBAAA9B;AAAA,gBAACU;AAAA,gBAAA;AAAA,kBACC,OAAOE,EAAO,UAAU;AAAA,kBACxB,MAAK;AAAA,gBAAA;AAAA,cAAA,EACP,CACF;AAAA,YAAA,EAAA,CACF,IACE;AAAA,cACHoB,IAAApB,EAAO,cAAP,gBAAAoB,EAAkB,eAAc,OAC/B,gBAAAlC,EAACgC,EAAgB,KAAhB,EACC,UAAA;AAAA,cAAA,gBAAA9B,EAAC8B,EAAgB,MAAhB,EACE,UAAArD,EAAE,8BAA8B,GACnC;AAAA,cACA,gBAAAuB,EAAC8B,EAAgB,QAAhB,EACC,UAAA,gBAAA9B,EAACU,GAAA,EAAO,OAAOE,EAAO,UAAU,YAAY,MAAK,KAAA,CAAK,EAAA,CACxD;AAAA,YAAA,EAAA,CACF,IACE;AAAA,cACHqB,IAAArB,EAAO,cAAP,gBAAAqB,EAAkB,iBAAgB,OACjC,gBAAAnC,EAACgC,EAAgB,KAAhB,EACC,UAAA;AAAA,cAAA,gBAAA9B,EAAC8B,EAAgB,MAAhB,EACE,UAAArD,EAAE,gCAAgC,GACrC;AAAA,cACA,gBAAAuB,EAAC8B,EAAgB,QAAhB,EACC,UAAA,gBAAA9B,EAACU,GAAA,EAAO,OAAOE,EAAO,UAAU,cAAc,MAAK,KAAA,CAAK,EAAA,CAC1D;AAAA,YAAA,EAAA,CACF,IACE;AAAA,YACHA,EAAO,cACN,gBAAAd,EAACgC,EAAgB,KAAhB,EACC,UAAA;AAAA,cAAA,gBAAA9B,EAAC8B,EAAgB,MAAhB,EACE,UAAArD,EAAE,oCAAoC,GACzC;AAAA,cACA,gBAAAuB,EAAC8B,EAAgB,QAAhB,EACE,YAAE,uBAAuBlB,EAAO,WAAW,EAAE,EAAA,CAChD;AAAA,YAAA,EAAA,CACF,IACE;AAAA,YACHA,EAAO,iBACN,gBAAAd,EAACgC,EAAgB,KAAhB,EACC,UAAA;AAAA,cAAA,gBAAA9B,EAAC8B,EAAgB,MAAhB,EACE,UAAArD,EAAE,uCAAuC,GAC5C;AAAA,cACA,gBAAAuB,EAAC8B,EAAgB,QAAhB,EACE,YAAE,uBAAuBlB,EAAO,cAAc,EAAE,EAAA,CACnD;AAAA,YAAA,EAAA,CACF,IACE;AAAA,UAAA,EAAA,CACN,IACE;AAAA,UACHA,EAAO,QACN,gBAAAd,EAAC,OAAA,EAAI,WAAU,iKACb,UAAA;AAAA,YAAA,gBAAAE,EAAC,KAAA,EAAE,WAAU,wHACV,UAAAvB,EAAE,yBAAyB,GAC9B;AAAA,YACA,gBAAAuB,EAAC,KAAA,EAAE,WAAU,6EACV,YAAO,MAAA,CACV;AAAA,UAAA,EAAA,CACF,IACE;AAAA,QAAA,EAAA,CACN,GACF,IACE;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIR,SACE,gBAAAF,EAAC4B,GAAA,EAAK,SAAQ,WAAU,WAAU,gCAChC,UAAA;AAAA,IAAA,gBAAA1B,EAAC0B,EAAK,QAAL,EACC,UAAA,gBAAA5B,EAAC,OAAA,EAAI,WAAU,wEACb,UAAA;AAAA,MAAA,gBAAAE,EAAC,MAAA,EAAG,WAAU,sDACX,UAAAuB,GACH;AAAA,wBACCb,GAAA,EAAO,OAAOE,EAAO,cAAc,MAAK,KAAA,CAAK;AAAA,IAAA,EAAA,CAChD,EAAA,CACF;AAAA,IACCA,EAAO,UACN,gBAAAZ,EAAC0B,EAAK,MAAL,EACC,UAAA,gBAAA1B,EAAC,KAAA,EAAE,WAAU,gEACV,UAAAY,EAAO,QAAA,CACV,GACF,IACE;AAAA,IACHY;AAAA,EAAA,GACH;AAEJ;AAMA,SAASU,GAAc,EAAE,YAAAC,KAAuC;AAK9D,SACE,gBAAArC,EAAC,OAAA,EAAI,WAAU,kDACb,UAAA;AAAA,IAAA,gBAAAA,EAAC,OAAA,EAAI,WAAU,yEACb,UAAA;AAAA,MAAA,gBAAAE,EAACoC,GAAA,EAAS,SAAQ,QAAO,OAAM,OAAM;AAAA,MACrC,gBAAApC,EAACoC,GAAA,EAAS,SAAQ,QAAO,OAAM,MAAA,CAAM;AAAA,IAAA,GACvC;AAAA,IACED,IAWE,OAVF,gBAAAnC,EAAC,OAAA,EAAI,WAAU,mDACZ,UAAA,MAAM,KAAK,EAAE,QAAQ,EAAA,GAAK,CAACqC,GAAGpD,MAC7B,gBAAAe;AAAA,MAACoC;AAAA,MAAA;AAAA,QAEC,SAAQ;AAAA,QACR,OAAM;AAAA,QACN,QAAO;AAAA,MAAA;AAAA,MAHF,SAASnD,CAAC;AAAA,IAAA,CAKlB,GACH;AAAA,IAEF,gBAAAe,EAAC,SAAI,WAAU,kDACZ,gBAAM,KAAK,EAAE,QAAQ,EAAA,GAAK,CAACqC,GAAGpD,MAC7B,gBAAAe,EAACoC,GAAA,EAA4B,SAAQ,WAAU,QAAO,UAAvC,SAASnD,CAAC,EAAoC,CAC9D,EAAA,CACH;AAAA,EAAA,GACF;AAEJ;AAMA,MAAMqD,IAAenE;AAAA;AAAA;AAAA;AAAA,EAInB;AAAA,EACA;AAAA,IACE,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAMR,SAAS;AAAA,QACP,MAAM;AAAA,QACN,UAAU;AAAA,UACR;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QAAA,EACA,KAAK,GAAG;AAAA,MAAA;AAAA,IACZ;AAAA,IAEF,iBAAiB,EAAE,SAAS,OAAA;AAAA,EAAO;AAEvC,GAMaoE,KAAeC;AAAA,EAC1B,CACE;AAAA,IACE,SAAAzE;AAAA,IACA,WAAA0E;AAAA,IACA,QAAQC;AAAA,IACR,gBAAAC;AAAA,IACA,WAAAC;AAAA,IACA,kBAAAC;AAAA,IACA,cAActC;AAAA,IACd,IAAAuC;AAAA,IACA,WAAAC;AAAA,IACA,YAAAZ,IAAa;AAAA,IACb,SAAAa,IAAU;AAAA,IACV,SAAAC,IAAU;AAAA,IACV,GAAGC;AAAA,EAAA,GAELC,MACG;AACH,UAAM,EAAE,GAAA1E,GAAG,MAAA2E,EAAA,IAAS1E,EAAA,GACdmC,IAASuC,EAAK,YAAY,MAO1B,CAACC,GAAgBC,CAAiB,IAAIvE,EAAuB,KAAK,GAClEV,IAASqE,KAAcW,GAEvBE,IAAqBlE;AAAA,MACzB,CAACM,MAAuB;AACtB,QAAI+C,MAAe,UAAWY,EAAkB3D,CAAI,GACpDgD,KAAA,QAAAA,EAAiBhD;AAAA,MACnB;AAAA,MACA,CAAC+C,GAAYC,CAAc;AAAA,IAAA,GAOvBrE,IAAY+C;AAAA,MAChB,MAAMoB,EAAU,aAAa3E,GAAgBC,CAAO;AAAA,MACpD,CAAC0E,EAAU,WAAW1E,CAAO;AAAA,IAAA,GAGzByF,IAAiBnC,EAAQ,MACzBhD,MAAW,QAAcN,IACtBA,EAAQ,OAAO,CAACE,MAAML,EAASK,EAAE,YAAY,MAAMI,CAAM,GAC/D,CAACN,GAASM,CAAM,CAAC,GAKdoF,IAAkBtE,EAAOd,CAAM;AACrC,IAAAoF,EAAgB,UAAUpF;AAC1B,UAAMqF,IAAwBvE,EAAOqE,EAAe,MAAM;AAC1D,IAAAE,EAAsB,UAAUF,EAAe;AAE/C,UAAMG,IAActC;AAAA,MAClB,OAAO;AAAA,QACL,WAAW,MAAMoC,EAAgB;AAAA,QACjC,WAAW,CAAC9D,MAAS4D,EAAmB5D,CAAI;AAAA,QAC5C,iBAAiB,MAAM+D,EAAsB;AAAA,MAAA;AAAA,MAE/C,CAACH,CAAkB;AAAA,IAAA,GAGfK,IAAUzE,EAAoB,IAAI;AACxC,IAAA0E,EAAoBV,GAAK,MAAMS,EAAQ,SAAwB,CAAA,CAAE,GACjEE,EAAqBtG,IAAmBmG,GAAab,CAAE;AAEvD,UAAMiB,IAAoBxD,KAAa9B,EAAE,0BAA0B,GAC7DuF,IAAa,OAAO3F,CAAM;AAGhC,QAAI4E;AACF,aACE,gBAAAjD;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAK4D;AAAA,UACL,cAAYG;AAAA,UACZ,aAAU;AAAA,UACV,IAAAjB;AAAA,UACA,kBAAe;AAAA,UACf,qBAAmBA;AAAA,UACnB,eAAakB;AAAA,UACb,cAAW;AAAA,UACX,WAAW1B,EAAa,EAAE,SAAAU,GAAS,WAAAD,GAAW;AAAA,UAC7C,GAAGG;AAAA,UAEJ,4BAAC,OAAA,EAAI,WAAU,4BACb,UAAA,gBAAAlD,EAACkC,IAAA,EAAc,YAAAC,GAAwB,EAAA,CACzC;AAAA,QAAA;AAAA,MAAA;AASN,QAAIM,EAAU,UAAU,KAAK1E,EAAQ,WAAW;AAC9C,aACE,gBAAAiC;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,KAAK4D;AAAA,UACL,cAAYG;AAAA,UACZ,IAAAjB;AAAA,UACA,kBAAe;AAAA,UACf,qBAAmBA;AAAA,UACnB,eAAakB;AAAA,UACb,cAAW;AAAA,UACX,WAAW1B,EAAa,EAAE,SAAAU,GAAS,WAAAD,GAAW;AAAA,UAC7C,GAAGG;AAAA,UAEJ,UAAA,gBAAAlD,EAAC,OAAA,EAAI,WAAU,4BACb,UAAA,gBAAAA;AAAA,YAACiE;AAAA,YAAA;AAAA,cACC,SAAQ;AAAA,cACR,OAAOxF,EAAE,0BAA0B;AAAA,cACnC,aAAaA,EAAE,gCAAgC;AAAA,YAAA;AAAA,UAAA,EACjD,CACF;AAAA,QAAA;AAAA,MAAA;AAKN,UAAMyF,IAAa,CAAC/B;AAEpB,WACE,gBAAArC;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,KAAK8D;AAAA,QACL,cAAYG;AAAA,QACZ,IAAAjB;AAAA,QACA,kBAAe;AAAA,QACf,qBAAmBA;AAAA,QACnB,eAAakB;AAAA,QACb,WAAW1B,EAAa,EAAE,SAAAU,GAAS,WAAAD,GAAW;AAAA,QAC7C,GAAGG;AAAA,QAOJ,UAAA;AAAA,UAAA,gBAAAlD;AAAA,YAACmE;AAAA,YAAA;AAAA,cACC,OAAO1F,EAAE,oBAAoB;AAAA,cAC7B,MAAM,gBAAAuB,EAACoE,IAAA,EAAK,eAAY,OAAA,CAAO;AAAA,cAC/B,YAAW;AAAA,cACX,QAAM;AAAA,cACN,SACE,gBAAAtE,EAAAC,GAAA,EACG,UAAA;AAAA,gBAAA8C;AAAA,gBACD,gBAAA7C;AAAA,kBAACU;AAAA,kBAAA;AAAA,oBACC,OAAO+B,EAAU;AAAA,oBACjB,SAAS,EAAE,OAAOA,EAAU,MAAA;AAAA,oBAC5B,MAAK;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACP,GACF;AAAA,cAEF,SACEyB,IACE,gBAAAlE;AAAA,gBAAC5B;AAAA,gBAAA;AAAA,kBACC,QAAAC;AAAA,kBACA,WAAAC;AAAA,kBACA,YAAYmE,EAAU;AAAA,kBACtB,UAAUc;AAAA,gBAAA;AAAA,cAAA,IAEV;AAAA,YAAA;AAAA,UAAA;AAAA,UAIR,gBAAAzD,EAAC,OAAA,EAAI,WAAU,sFACZ,UAAA;AAAA,YAAA8C,KAUG;AAAA,YAEHY,EAAe,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,cAKzB,gBAAA1D;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAK;AAAA,kBACL,cAAW;AAAA,kBACX,WAAU;AAAA,kBAEV,UAAA;AAAA,oBAAA,gBAAAE,EAAC,KAAA,EAAE,WAAU,sDACV,UAAA3B,MAAW,QACRI,EAAE,0BAA0B,IAC5BA,EAAE,wCAAwC;AAAA,sBACxC,OAAOJ;AAAA,oBAAA,CACR,GACP;AAAA,oBACCA,MAAW,QACV,gBAAA2B;AAAA,sBAACqE;AAAA,sBAAA;AAAA,wBACC,QAAO;AAAA,wBACP,MAAK;AAAA,wBACL,SAAS,MAAMd,EAAmB,KAAK;AAAA,wBAEtC,YAAE,gCAAgC;AAAA,sBAAA;AAAA,oBAAA,IAEnC;AAAA,kBAAA;AAAA,gBAAA;AAAA,cAAA;AAAA,gBAGN,gBAAAvD;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,cAAYvB,EAAE,wBAAwB;AAAA,gBACtC,WAAU;AAAA,gBAET,YAAe,IAAI,CAACmC,MACnB,gBAAAZ,EAAC,QAAmB,kBAAgBY,EAAO,IACzC,UAAA,gBAAAZ,EAACW,MAAW,QAAAC,GAAgB,QAAAC,GAAgB,EAAA,GADrCD,EAAO,EAEhB,CACD;AAAA,cAAA;AAAA,YAAA;AAAA,UACH,EAAA,CAEJ;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AACF;AAEA2B,GAAa,cAAc;"}