@africanies/angular-web-sdk 0.1.11 → 0.1.13

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 (228) hide show
  1. package/.nx/cache/{13466509747676776487 → 13293303228070520113}/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs +66 -1
  2. package/.nx/cache/13293303228070520113/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs.map +1 -0
  3. package/.nx/cache/{13466509747676776487 → 13293303228070520113}/dist/libs/africanies-core/types/africanies-africanies-core.d.ts +6 -1
  4. package/.nx/cache/{6673686859704879504 → 13387631073062967069}/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs +31 -13
  5. package/.nx/cache/13387631073062967069/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs.map +1 -0
  6. package/.nx/cache/{6673686859704879504 → 13387631073062967069}/dist/libs/africanies-theme/tailwind-preset.cjs +85 -17
  7. package/.nx/cache/{6673686859704879504 → 13387631073062967069}/dist/libs/africanies-theme/types/africanies-africanies-theme.d.ts +7 -3
  8. package/.nx/cache/16704640000606796352/dist/libs/africanies-storage/README.md +31 -0
  9. package/.nx/cache/16704640000606796352/dist/libs/africanies-storage/fesm2022/africanies-africanies-storage.mjs +249 -0
  10. package/.nx/cache/16704640000606796352/dist/libs/africanies-storage/fesm2022/africanies-africanies-storage.mjs.map +1 -0
  11. package/.nx/cache/16704640000606796352/dist/libs/africanies-storage/package.json +26 -0
  12. package/.nx/cache/16704640000606796352/dist/libs/africanies-storage/types/africanies-africanies-storage.d.ts +210 -0
  13. package/.nx/cache/{14876618240301288353 → 2427575433215940812}/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs +2998 -1122
  14. package/.nx/cache/2427575433215940812/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs.map +1 -0
  15. package/.nx/cache/{14995846848874973576 → 2427575433215940812}/dist/libs/africanies-ui/types/africanies-africanies-ui.d.ts +450 -140
  16. package/.nx/cache/{6664915487114632770 → 7730350229628359718}/dist/libs/africanies-icons/assets/icons.sprite.svg +7 -0
  17. package/.nx/cache/{6664915487114632770 → 7730350229628359718}/dist/libs/africanies-icons/fesm2022/africanies-africanies-icons.mjs +7 -0
  18. package/.nx/cache/7730350229628359718/dist/libs/africanies-icons/fesm2022/africanies-africanies-icons.mjs.map +1 -0
  19. package/.nx/cache/{6664915487114632770 → 7730350229628359718}/dist/libs/africanies-icons/types/africanies-africanies-icons.d.ts +2 -2
  20. package/.nx/cache/{14995846848874973576 → 7821397806208783174}/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs +2572 -962
  21. package/.nx/cache/7821397806208783174/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs.map +1 -0
  22. package/.nx/cache/{14876618240301288353 → 7821397806208783174}/dist/libs/africanies-ui/types/africanies-africanies-ui.d.ts +460 -147
  23. package/.nx/cache/run.json +35 -35
  24. package/.nx/cache/terminalOutputs/10603154579345867998 +397 -0
  25. package/.nx/cache/terminalOutputs/12354163057083828162 +80 -0
  26. package/.nx/cache/terminalOutputs/{9040451482998546630 → 13293303228070520113} +1 -1
  27. package/.nx/cache/terminalOutputs/{6673686859704879504 → 13387631073062967069} +1 -1
  28. package/.nx/cache/terminalOutputs/{14061940909886036014 → 14876351543379349919} +46 -43
  29. package/.nx/cache/terminalOutputs/15336883221450327589 +21 -0
  30. package/.nx/cache/terminalOutputs/16208231681037145050 +87 -0
  31. package/.nx/cache/terminalOutputs/{13466509747676776487 → 16704640000606796352} +6 -6
  32. package/.nx/cache/terminalOutputs/1811006905937373707 +74 -0
  33. package/.nx/cache/terminalOutputs/2005781115771702035 +8 -0
  34. package/.nx/cache/terminalOutputs/2360743690449633551 +21 -0
  35. package/.nx/cache/terminalOutputs/{14876618240301288353 → 2427575433215940812} +2 -2
  36. package/.nx/cache/terminalOutputs/2981230413857865352 +8 -0
  37. package/.nx/cache/terminalOutputs/3243550283886864639 +8 -0
  38. package/.nx/cache/terminalOutputs/3380188914363501109 +231 -0
  39. package/.nx/cache/terminalOutputs/3699068646900552690 +8 -0
  40. package/.nx/cache/terminalOutputs/5175669339257931410 +8 -0
  41. package/.nx/cache/terminalOutputs/6040230831125637867 +8 -0
  42. package/.nx/cache/terminalOutputs/7730350229628359718 +21 -0
  43. package/.nx/cache/terminalOutputs/{14995846848874973576 → 7821397806208783174} +2 -2
  44. package/.nx/cache/terminalOutputs/8098730470212963224 +87 -0
  45. package/.nx/cache/terminalOutputs/8928690901537686687 +21 -0
  46. package/.nx/workspace-data/0091ABA9-5C90-580D-953C-8C94E763ADB5-v3.db +0 -0
  47. package/.nx/workspace-data/0091ABA9-5C90-580D-953C-8C94E763ADB5-v3.db-shm +0 -0
  48. package/.nx/workspace-data/0091ABA9-5C90-580D-953C-8C94E763ADB5-v3.db-wal +0 -0
  49. package/.nx/workspace-data/d/daemon.log +4176 -0
  50. package/.nx/workspace-data/d/server-process.json +2 -2
  51. package/.nx/workspace-data/file-map.json +2995 -2989
  52. package/.nx/workspace-data/nx_files.nxt +0 -0
  53. package/.nx/workspace-data/project-graph.json +2 -2
  54. package/apps/playground/src/app/pages/forms-page.ts +70 -14
  55. package/apps/playground/src/app/snippets/forms.snippets.ts +41 -6
  56. package/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs +60 -0
  57. package/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs.map +1 -1
  58. package/dist/libs/africanies-icons/fesm2022/africanies-africanies-icons.mjs +6 -0
  59. package/dist/libs/africanies-icons/fesm2022/africanies-africanies-icons.mjs.map +1 -1
  60. package/dist/libs/africanies-storage/fesm2022/africanies-africanies-storage.mjs +6 -0
  61. package/dist/libs/africanies-storage/fesm2022/africanies-africanies-storage.mjs.map +1 -1
  62. package/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs +6 -0
  63. package/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs.map +1 -1
  64. package/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs +1323 -85
  65. package/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs.map +1 -1
  66. package/dist/libs/africanies-ui/types/africanies-africanies-ui.d.ts +201 -15
  67. package/libs/africanies-core/src/lib/auth/auth-token.service.ts +3 -0
  68. package/libs/africanies-core/src/lib/auth/auth.service.ts +3 -0
  69. package/libs/africanies-core/src/lib/country/country.service.ts +3 -0
  70. package/libs/africanies-core/src/lib/currency/currency.service.ts +3 -0
  71. package/libs/africanies-core/src/lib/document/document.service.ts +3 -0
  72. package/libs/africanies-core/src/lib/file/file.service.ts +3 -0
  73. package/libs/africanies-core/src/lib/filters/filter-options.resolver.ts +3 -0
  74. package/libs/africanies-core/src/lib/http/api-client.ts +3 -0
  75. package/libs/africanies-core/src/lib/mode/mode-config.service.ts +3 -0
  76. package/libs/africanies-core/src/lib/notification/notification.service.ts +3 -0
  77. package/libs/africanies-core/src/lib/overlay/route-overlay.service.ts +3 -0
  78. package/libs/africanies-core/src/lib/payment-method/payment-method.service.ts +3 -0
  79. package/libs/africanies-core/src/lib/plan/plan.service.ts +3 -0
  80. package/libs/africanies-core/src/lib/product/product.service.ts +3 -0
  81. package/libs/africanies-core/src/lib/service/service.service.ts +3 -0
  82. package/libs/africanies-core/src/lib/shipment-method/shipment-method.service.ts +3 -0
  83. package/libs/africanies-core/src/lib/shipping/shipping-mode.service.ts +3 -0
  84. package/libs/africanies-core/src/lib/user/user.service.ts +3 -0
  85. package/libs/africanies-core/src/lib/warehouse/warehouse.service.ts +3 -0
  86. package/libs/africanies-core/src/lib/zone/zone.service.ts +3 -0
  87. package/libs/africanies-icons/src/lib/africanies-icon.component.ts +3 -0
  88. package/libs/africanies-icons/src/lib/icon-registry.service.ts +3 -0
  89. package/libs/africanies-storage/src/lib/local-storage.service.ts +3 -0
  90. package/libs/africanies-storage/src/lib/session-storage.service.ts +3 -0
  91. package/libs/africanies-theme/src/lib/mode-color.service.ts +3 -0
  92. package/libs/africanies-theme/src/lib/theme.service.ts +3 -0
  93. package/libs/africanies-ui/src/index.ts +18 -0
  94. package/libs/africanies-ui/src/lib/accordion/accordion.component.ts +3 -0
  95. package/libs/africanies-ui/src/lib/action-menu/action-menu-trigger.directive.ts +3 -0
  96. package/libs/africanies-ui/src/lib/action-menu/action-menu.component.ts +3 -0
  97. package/libs/africanies-ui/src/lib/alert/alert.component.ts +3 -0
  98. package/libs/africanies-ui/src/lib/avatar/avatar-menu.component.ts +3 -0
  99. package/libs/africanies-ui/src/lib/avatar/avatar.component.ts +3 -0
  100. package/libs/africanies-ui/src/lib/brand/brand-logo.component.ts +3 -0
  101. package/libs/africanies-ui/src/lib/button/button.component.ts +3 -0
  102. package/libs/africanies-ui/src/lib/carrier/carrier-logo.component.ts +3 -0
  103. package/libs/africanies-ui/src/lib/chip/chip.component.ts +3 -0
  104. package/libs/africanies-ui/src/lib/content-stack/content-stack.component.ts +3 -0
  105. package/libs/africanies-ui/src/lib/copy-button/copy-button.component.ts +3 -0
  106. package/libs/africanies-ui/src/lib/feedback/async-state.component.ts +3 -0
  107. package/libs/africanies-ui/src/lib/feedback/empty-state.component.ts +3 -0
  108. package/libs/africanies-ui/src/lib/feedback/error-indicator.component.ts +3 -0
  109. package/libs/africanies-ui/src/lib/feedback/error-state.component.ts +3 -0
  110. package/libs/africanies-ui/src/lib/feedback/loading-state.component.ts +3 -0
  111. package/libs/africanies-ui/src/lib/filters/filter-drawer.panel.ts +3 -0
  112. package/libs/africanies-ui/src/lib/filters/filter-drawer.service.ts +3 -0
  113. package/libs/africanies-ui/src/lib/filters/filter-query.service.ts +3 -0
  114. package/libs/africanies-ui/src/lib/forms/address-input/address-input.component.ts +3 -0
  115. package/libs/africanies-ui/src/lib/forms/address-input/google-places.service.ts +3 -0
  116. package/libs/africanies-ui/src/lib/forms/checkbox/checkbox.component.ts +3 -0
  117. package/libs/africanies-ui/src/lib/forms/date-picker/date-picker.component.ts +3 -0
  118. package/libs/africanies-ui/src/lib/forms/file-upload/camera-capture.dialog.ts +3 -0
  119. package/libs/africanies-ui/src/lib/forms/file-upload/file-preview.dialog.ts +3 -0
  120. package/libs/africanies-ui/src/lib/forms/file-upload/file-upload.component.ts +3 -0
  121. package/libs/africanies-ui/src/lib/forms/index.ts +20 -0
  122. package/libs/africanies-ui/src/lib/forms/number-input/number-input.component.ts +3 -0
  123. package/libs/africanies-ui/src/lib/forms/otp-input/otp-input.component.ts +3 -0
  124. package/libs/africanies-ui/src/lib/forms/phone-input/index.ts +21 -0
  125. package/libs/africanies-ui/src/lib/forms/phone-input/phone-codes.ts +264 -0
  126. package/libs/africanies-ui/src/lib/forms/phone-input/phone-input.component.ts +480 -0
  127. package/libs/africanies-ui/src/lib/forms/phone-input/phone-input.types.ts +35 -0
  128. package/libs/africanies-ui/src/lib/forms/phone-input/phone-input.utils.spec.ts +81 -0
  129. package/libs/africanies-ui/src/lib/forms/phone-input/phone-input.utils.ts +275 -0
  130. package/libs/africanies-ui/src/lib/forms/radio/radio.component.ts +3 -0
  131. package/libs/africanies-ui/src/lib/forms/search-combobox/search-combobox.component.ts +3 -0
  132. package/libs/africanies-ui/src/lib/forms/select/select.component.ts +3 -0
  133. package/libs/africanies-ui/src/lib/forms/text-input/text-input.component.ts +3 -0
  134. package/libs/africanies-ui/src/lib/forms/textarea/textarea.component.ts +3 -0
  135. package/libs/africanies-ui/src/lib/forms/toggle/toggle.component.ts +3 -0
  136. package/libs/africanies-ui/src/lib/image/image.component.ts +3 -0
  137. package/libs/africanies-ui/src/lib/info-popover/info-popover-content.directive.ts +3 -0
  138. package/libs/africanies-ui/src/lib/info-popover/info-popover-trigger.directive.ts +3 -0
  139. package/libs/africanies-ui/src/lib/info-popover/info-popover.component.ts +3 -0
  140. package/libs/africanies-ui/src/lib/layout/app-shell-content-header.component.ts +3 -0
  141. package/libs/africanies-ui/src/lib/layout/app-shell-header-slot.directive.ts +3 -0
  142. package/libs/africanies-ui/src/lib/layout/app-shell-header.component.ts +9 -0
  143. package/libs/africanies-ui/src/lib/layout/app-shell.component.ts +3 -0
  144. package/libs/africanies-ui/src/lib/layout/header-weather.spec.ts +62 -94
  145. package/libs/africanies-ui/src/lib/layout/header-weather.ts +54 -61
  146. package/libs/africanies-ui/src/lib/layout/page-header.component.ts +3 -0
  147. package/libs/africanies-ui/src/lib/modules/africanies-actions.module.ts +3 -0
  148. package/libs/africanies-ui/src/lib/modules/africanies-feedback.module.ts +3 -0
  149. package/libs/africanies-ui/src/lib/modules/africanies-forms.module.ts +5 -0
  150. package/libs/africanies-ui/src/lib/modules/africanies-info-popover.module.ts +3 -0
  151. package/libs/africanies-ui/src/lib/modules/africanies-navigation.module.ts +3 -0
  152. package/libs/africanies-ui/src/lib/modules/africanies-stepper.module.ts +3 -0
  153. package/libs/africanies-ui/src/lib/modules/africanies-table.module.ts +3 -0
  154. package/libs/africanies-ui/src/lib/modules/africanies-tooltip.module.ts +3 -0
  155. package/libs/africanies-ui/src/lib/navigation/breadcrumb/breadcrumb.component.ts +3 -0
  156. package/libs/africanies-ui/src/lib/navigation/segment/segment.component.ts +5 -1
  157. package/libs/africanies-ui/src/lib/navigation/shipping-mode-switch/shipping-mode-switch.component.ts +3 -0
  158. package/libs/africanies-ui/src/lib/navigation/side-nav/africanies-side-nav.component.ts +3 -0
  159. package/libs/africanies-ui/src/lib/navigation/tabs/tab-def.directive.ts +3 -0
  160. package/libs/africanies-ui/src/lib/navigation/tabs/tabs.component.ts +3 -0
  161. package/libs/africanies-ui/src/lib/notifications/notification-drawer.panel.ts +3 -0
  162. package/libs/africanies-ui/src/lib/notifications/notification-drawer.service.ts +3 -0
  163. package/libs/africanies-ui/src/lib/overlay/confirm-dialog.component.ts +3 -0
  164. package/libs/africanies-ui/src/lib/overlay/confirm.service.ts +3 -0
  165. package/libs/africanies-ui/src/lib/overlay/drawer.service.ts +3 -0
  166. package/libs/africanies-ui/src/lib/overlay/modal.service.ts +3 -0
  167. package/libs/africanies-ui/src/lib/overlay/overlay-frame.component.ts +9 -0
  168. package/libs/africanies-ui/src/lib/pagination/pagination.component.ts +3 -0
  169. package/libs/africanies-ui/src/lib/stepper/step-def.directive.ts +3 -0
  170. package/libs/africanies-ui/src/lib/stepper/stepper.component.ts +3 -0
  171. package/libs/africanies-ui/src/lib/table/cell-def.directive.ts +3 -0
  172. package/libs/africanies-ui/src/lib/table/header-cell-def.directive.ts +3 -0
  173. package/libs/africanies-ui/src/lib/table/row-detail-def.directive.ts +3 -0
  174. package/libs/africanies-ui/src/lib/table/table.component.ts +3 -0
  175. package/libs/africanies-ui/src/lib/toast/toast-host.component.ts +4 -1
  176. package/libs/africanies-ui/src/lib/toast/toast-item.component.ts +3 -0
  177. package/libs/africanies-ui/src/lib/toast/toast.service.ts +3 -0
  178. package/libs/africanies-ui/src/lib/tooltip/tooltip-trigger.directive.ts +3 -0
  179. package/libs/africanies-ui/src/lib/tooltip/tooltip.component.ts +3 -0
  180. package/package.json +1 -1
  181. package/.nx/cache/13466509747676776487/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs.map +0 -1
  182. package/.nx/cache/14416694322692463866/dist/libs/africanies-models/README.md +0 -60
  183. package/.nx/cache/14416694322692463866/dist/libs/africanies-models/fesm2022/africanies-africanies-models.mjs +0 -599
  184. package/.nx/cache/14416694322692463866/dist/libs/africanies-models/fesm2022/africanies-africanies-models.mjs.map +0 -1
  185. package/.nx/cache/14416694322692463866/dist/libs/africanies-models/package.json +0 -23
  186. package/.nx/cache/14416694322692463866/dist/libs/africanies-models/types/africanies-africanies-models.d.ts +0 -1452
  187. package/.nx/cache/14876618240301288353/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs.map +0 -1
  188. package/.nx/cache/14995846848874973576/dist/libs/africanies-ui/fesm2022/africanies-africanies-ui.mjs.map +0 -1
  189. package/.nx/cache/17626862048742598274/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs +0 -221
  190. package/.nx/cache/17626862048742598274/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs.map +0 -1
  191. package/.nx/cache/17626862048742598274/dist/libs/africanies-theme/tailwind-preset.cjs +0 -253
  192. package/.nx/cache/17626862048742598274/dist/libs/africanies-theme/types/africanies-africanies-theme.d.ts +0 -166
  193. package/.nx/cache/6664915487114632770/dist/libs/africanies-icons/fesm2022/africanies-africanies-icons.mjs.map +0 -1
  194. package/.nx/cache/6673686859704879504/dist/libs/africanies-theme/README.md +0 -46
  195. package/.nx/cache/6673686859704879504/dist/libs/africanies-theme/fesm2022/africanies-africanies-theme.mjs.map +0 -1
  196. package/.nx/cache/6673686859704879504/dist/libs/africanies-theme/package.json +0 -35
  197. package/.nx/cache/9040451482998546630/dist/libs/africanies-core/README.md +0 -85
  198. package/.nx/cache/9040451482998546630/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs +0 -4511
  199. package/.nx/cache/9040451482998546630/dist/libs/africanies-core/fesm2022/africanies-africanies-core.mjs.map +0 -1
  200. package/.nx/cache/9040451482998546630/dist/libs/africanies-core/package.json +0 -31
  201. package/.nx/cache/9040451482998546630/dist/libs/africanies-core/types/africanies-africanies-core.d.ts +0 -2741
  202. package/.nx/cache/terminalOutputs/13555699813138069787 +0 -6
  203. package/.nx/cache/terminalOutputs/14416694322692463866 +0 -108
  204. package/.nx/cache/terminalOutputs/1446890025183346611 +0 -32
  205. package/.nx/cache/terminalOutputs/17394769338046050914 +0 -8
  206. package/.nx/cache/terminalOutputs/17626862048742598274 +0 -21
  207. package/.nx/cache/terminalOutputs/6337357866566791975 +0 -6
  208. package/.nx/cache/terminalOutputs/6664915487114632770 +0 -44
  209. package/.nx/cache/terminalOutputs/783228502946611950 +0 -19
  210. package/.nx/cache/terminalOutputs/7978448102466861029 +0 -32
  211. /package/.nx/cache/{13466509747676776487 → 13293303228070520113}/dist/libs/africanies-core/README.md +0 -0
  212. /package/.nx/cache/{13466509747676776487 → 13293303228070520113}/dist/libs/africanies-core/package.json +0 -0
  213. /package/.nx/cache/{17626862048742598274 → 13387631073062967069}/dist/libs/africanies-theme/README.md +0 -0
  214. /package/.nx/cache/{17626862048742598274 → 13387631073062967069}/dist/libs/africanies-theme/package.json +0 -0
  215. /package/.nx/cache/{14876618240301288353 → 2427575433215940812}/dist/libs/africanies-ui/README.md +0 -0
  216. /package/.nx/cache/{14876618240301288353 → 2427575433215940812}/dist/libs/africanies-ui/assets/brand/africanies-logo-mini.png +0 -0
  217. /package/.nx/cache/{14876618240301288353 → 2427575433215940812}/dist/libs/africanies-ui/assets/brand/africanies-logo.png +0 -0
  218. /package/.nx/cache/{14876618240301288353 → 2427575433215940812}/dist/libs/africanies-ui/assets/brand/africanies-logo.svg +0 -0
  219. /package/.nx/cache/{14876618240301288353 → 2427575433215940812}/dist/libs/africanies-ui/assets/carriers/dhl.svg +0 -0
  220. /package/.nx/cache/{14876618240301288353 → 2427575433215940812}/dist/libs/africanies-ui/package.json +0 -0
  221. /package/.nx/cache/{6664915487114632770 → 7730350229628359718}/dist/libs/africanies-icons/README.md +0 -0
  222. /package/.nx/cache/{6664915487114632770 → 7730350229628359718}/dist/libs/africanies-icons/package.json +0 -0
  223. /package/.nx/cache/{14995846848874973576 → 7821397806208783174}/dist/libs/africanies-ui/README.md +0 -0
  224. /package/.nx/cache/{14995846848874973576 → 7821397806208783174}/dist/libs/africanies-ui/assets/brand/africanies-logo-mini.png +0 -0
  225. /package/.nx/cache/{14995846848874973576 → 7821397806208783174}/dist/libs/africanies-ui/assets/brand/africanies-logo.png +0 -0
  226. /package/.nx/cache/{14995846848874973576 → 7821397806208783174}/dist/libs/africanies-ui/assets/brand/africanies-logo.svg +0 -0
  227. /package/.nx/cache/{14995846848874973576 → 7821397806208783174}/dist/libs/africanies-ui/assets/carriers/dhl.svg +0 -0
  228. /package/.nx/cache/{14995846848874973576 → 7821397806208783174}/dist/libs/africanies-ui/package.json +0 -0
@@ -1,8 +1,8 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, input, booleanAttribute, computed, ChangeDetectionStrategy, Component, output, signal, Injector, DestroyRef, Injectable, numberAttribute, Directive, viewChild, contentChild, model, makeEnvironmentProviders, provideAppInitializer, forwardRef, InjectionToken, effect, afterNextRender, viewChildren, TemplateRef, contentChildren, untracked, runInInjectionContext, afterRenderEffect, NgModule } from '@angular/core';
2
+ import { inject, input, booleanAttribute, computed, ChangeDetectionStrategy, Component, output, signal, Injector, DestroyRef, Injectable, numberAttribute, Directive, viewChild, contentChild, model, makeEnvironmentProviders, provideAppInitializer, forwardRef, InjectionToken, effect, afterNextRender, viewChildren, untracked, TemplateRef, contentChildren, runInInjectionContext, afterRenderEffect, NgModule } from '@angular/core';
3
3
  import { AfricaniesIconComponent } from '@africanies/africanies-icons';
4
4
  import { ModeColorService, ThemeService } from '@africanies/africanies-theme';
5
- import { copyToClipboard, AFRICANIES_HTTP_TOAST, FilterOptionsResolver, MODAL_SERVICE, DRAWER_SERVICE, ShippingModeService, resolveNotificationLinkForMode } from '@africanies/africanies-core';
5
+ import { copyToClipboard, AFRICANIES_HTTP_TOAST, FilterOptionsResolver, MODAL_SERVICE, DRAWER_SERVICE, countryFlagUrl, ShippingModeService, resolveNotificationLinkForMode } from '@africanies/africanies-core';
6
6
  import { Overlay, CdkOverlayOrigin, CdkConnectedOverlay } from '@angular/cdk/overlay';
7
7
  import { ComponentPortal } from '@angular/cdk/portal';
8
8
  import { Router, ActivatedRoute, RouterLink, NavigationEnd } from '@angular/router';
@@ -46,6 +46,9 @@ import { NgTemplateOutlet, NgClass, DatePipe } from '@angular/common';
46
46
  * </button>
47
47
  * ```
48
48
  */
49
+ /**
50
+ * Theme-token button used across AFRICANIES surfaces.
51
+ */
49
52
  class ButtonComponent {
50
53
  modeColor = inject(ModeColorService);
51
54
  /**
@@ -239,6 +242,9 @@ function toastFingerprint(variant, title, message) {
239
242
  * Single toast card — dense, token-based, with optional countdown rail.
240
243
  * Stacked identical toasts can expand; close peels the outermost copy.
241
244
  */
245
+ /**
246
+ * Single toast card — dense, token-based, with optional countdown rail. Stacked identical toasts can expand; close peels the outermost copy.
247
+ */
242
248
  class ToastItemComponent {
243
249
  /** Stack entry to render. */
244
250
  item = input.required(/* @ts-ignore */
@@ -667,6 +673,9 @@ function railFill(variant) {
667
673
  * Caps to the viewport and scrolls when the stack (or an expanded group)
668
674
  * would otherwise run off-screen.
669
675
  */
676
+ /**
677
+ * Fixed stack host attached once by {@link ToastService.ensureHost}. Caps to the viewport and scrolls when the stack (or an expanded group) would otherwise run off-screen.
678
+ */
670
679
  class ToastHostComponent {
671
680
  toastService = inject(ToastService);
672
681
  toasts = this.toastService.items;
@@ -684,7 +693,7 @@ class ToastHostComponent {
684
693
  <div class="flex w-full flex-col gap-2">
685
694
  @if (toastService.showHostActions()) {
686
695
  <div
687
- class="sticky top-0 z-10 flex flex-wrap justify-end gap-2 bg-white/80 pb-1 backdrop-blur-sm dark:bg-ink-surface/80"
696
+ class="sticky top-0 z-10 flex flex-wrap justify-end gap-2 bg-transparent pb-1 backdrop-blur-sm dark:bg-transparent"
688
697
  >
689
698
  @if (toastService.hasStacks()) {
690
699
  @if (toastService.allStacksExpanded()) {
@@ -753,7 +762,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
753
762
  <div class="flex w-full flex-col gap-2">
754
763
  @if (toastService.showHostActions()) {
755
764
  <div
756
- class="sticky top-0 z-10 flex flex-wrap justify-end gap-2 bg-white/80 pb-1 backdrop-blur-sm dark:bg-ink-surface/80"
765
+ class="sticky top-0 z-10 flex flex-wrap justify-end gap-2 bg-transparent pb-1 backdrop-blur-sm dark:bg-transparent"
757
766
  >
758
767
  @if (toastService.hasStacks()) {
759
768
  @if (toastService.allStacksExpanded()) {
@@ -827,6 +836,9 @@ const TOAST_OVERLAY_Z_INDEX = '1100';
827
836
  *
828
837
  * Prefer {@link provideAfricaniesToasts} at bootstrap so the host overlay mounts once.
829
838
  */
839
+ /**
840
+ * Imperative toast stack for AFRICANIES apps.
841
+ */
830
842
  class ToastService {
831
843
  overlay = inject(Overlay);
832
844
  injector = inject(Injector);
@@ -1161,6 +1173,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
1161
1173
  * <africanies-copy [value]="ref" ariaLabel="Copy reference" [announce]="true" />
1162
1174
  * ```
1163
1175
  */
1176
+ /**
1177
+ * Icon button that copies {@link value} to the clipboard.
1178
+ */
1164
1179
  class CopyButtonComponent {
1165
1180
  toastService = inject(ToastService, { optional: true });
1166
1181
  /** Plain text written to the clipboard. */
@@ -1396,6 +1411,9 @@ function navigateNavItem(router, item, keepScroll = true) {
1396
1411
  * </africanies-action-menu>
1397
1412
  * ```
1398
1413
  */
1414
+ /**
1415
+ * Marks projected content as the custom trigger for {@link ActionMenuComponent}.
1416
+ */
1399
1417
  class ActionMenuTriggerDirective {
1400
1418
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: ActionMenuTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1401
1419
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: ActionMenuTriggerDirective, isStandalone: true, selector: "[africaniesActionMenuTrigger]", ngImport: i0 });
@@ -1475,6 +1493,9 @@ const MENU_PANEL_POSITIONS = [
1475
1493
  * }
1476
1494
  * ```
1477
1495
  */
1496
+ /**
1497
+ * Compact overflow menu for row and toolbar actions.
1498
+ */
1478
1499
  class ActionMenuComponent {
1479
1500
  router = inject(Router);
1480
1501
  panelPositions = MENU_PANEL_POSITIONS;
@@ -1902,6 +1923,9 @@ let nextMenuId = 0;
1902
1923
  * />
1903
1924
  * ```
1904
1925
  */
1926
+ /**
1927
+ * Blocking empty state when a fetch succeeded but produced no rows / value.
1928
+ */
1905
1929
  class EmptyStateComponent {
1906
1930
  /**
1907
1931
  * Empty-copy. Defaults to a generic phrase; override for filter-specific help.
@@ -2001,6 +2025,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
2001
2025
  * </div>
2002
2026
  * ```
2003
2027
  */
2028
+ /**
2029
+ * Compact error pill for non-blocking failures while stale data stays visible — distinct from {@link ErrorStateComponent} (full-section blocking).
2030
+ */
2004
2031
  class ErrorIndicatorComponent {
2005
2032
  /**
2006
2033
  * Error copy. When empty, the indicator is not shown.
@@ -2146,6 +2173,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
2146
2173
  * />
2147
2174
  * ```
2148
2175
  */
2176
+ /**
2177
+ * Blocking error state for failed async fetches (not field validation).
2178
+ */
2149
2179
  class ErrorStateComponent {
2150
2180
  /**
2151
2181
  * Human-readable failure reason. Required so the alert is never an empty
@@ -2233,6 +2263,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
2233
2263
  * <africanies-loading-state mode="inline" message="Refreshing…" />
2234
2264
  * ```
2235
2265
  */
2266
+ /**
2267
+ * Blocking / inline loading indicator for async surfaces.
2268
+ */
2236
2269
  class LoadingStateComponent {
2237
2270
  modeColor = inject(ModeColorService);
2238
2271
  /**
@@ -2344,6 +2377,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
2344
2377
  * </africanies-async-state>
2345
2378
  * ```
2346
2379
  */
2380
+ /**
2381
+ * Async query wrapper that maps {@link AsyncQueryStateModel} into loading / error / empty / success with non-blocking badges for background activity.
2382
+ */
2347
2383
  class AsyncStateComponent {
2348
2384
  /**
2349
2385
  * Snapshot from the app's query layer (e.g. mapped `injectQuery()` signals).
@@ -2560,6 +2596,9 @@ function isEmptyData(data) {
2560
2596
  * </africanies-accordion>
2561
2597
  * ```
2562
2598
  */
2599
+ /**
2600
+ * Bordered expandable panel with animated fold — the pattern used on Manifest detail and Make Payment review.
2601
+ */
2563
2602
  class AccordionComponent {
2564
2603
  /** Plain-text header. Prefer projected `[africaniesAccordionTitle]` for rich titles. */
2565
2604
  title = input('', /* @ts-ignore */
@@ -2690,6 +2729,9 @@ const DEFAULT_ICONS = {
2690
2729
  * }
2691
2730
  * ```
2692
2731
  */
2732
+ /**
2733
+ * Inline page/section banner — distinct from {@link ErrorStateComponent} (full-section async failure + Retry).
2734
+ */
2693
2735
  class AlertComponent {
2694
2736
  /** Semantic tone. Defaults to `info`. */
2695
2737
  variant = input('info', /* @ts-ignore */
@@ -2871,6 +2913,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
2871
2913
  * <africanies-chip variant="warning" [removable]="true" (removed)="clear()">Pending</africanies-chip>
2872
2914
  * ```
2873
2915
  */
2916
+ /**
2917
+ * Compact status / category label.
2918
+ */
2874
2919
  class ChipComponent {
2875
2920
  /** Semantic tone. Defaults to `neutral`. Ignored when {@link color} is set. */
2876
2921
  variant = input('neutral', /* @ts-ignore */
@@ -3026,6 +3071,9 @@ function normalizeCarrierLogoSlug(value) {
3026
3071
  * <africanies-carrier-logo [carrier]="item.delivery_vendor" />
3027
3072
  * ```
3028
3073
  */
3074
+ /**
3075
+ * Inline carrier marks for delivery vendor cells.
3076
+ */
3029
3077
  class CarrierLogoComponent {
3030
3078
  /** Raw carrier slug or label from the API. */
3031
3079
  carrier = input('', /* @ts-ignore */
@@ -3178,6 +3226,9 @@ function deliveryVendorSelected(storedValue, baseOptions = deliveryVendorSelectO
3178
3226
  * />
3179
3227
  * ```
3180
3228
  */
3229
+ /**
3230
+ * Compact stacked text for table cells and detail panels.
3231
+ */
3181
3232
  class ContentStackComponent {
3182
3233
  /** Primary line — usually a person or entity name. */
3183
3234
  title = input('', /* @ts-ignore */
@@ -3290,6 +3341,9 @@ function provideAfricaniesToasts() {
3290
3341
  * </africanies-tooltip>
3291
3342
  * ```
3292
3343
  */
3344
+ /**
3345
+ * Marks projected content as the custom trigger for {@link TooltipComponent}.
3346
+ */
3293
3347
  class TooltipTriggerDirective {
3294
3348
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: TooltipTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3295
3349
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: TooltipTriggerDirective, isStandalone: true, selector: "[africaniesTooltipTrigger]", ngImport: i0 });
@@ -3389,6 +3443,9 @@ const PLACEMENT_POSITIONS$1 = {
3389
3443
  * </africanies-tooltip>
3390
3444
  * ```
3391
3445
  */
3446
+ /**
3447
+ * Contextual help tip — default info icon or a custom projected trigger.
3448
+ */
3392
3449
  class TooltipComponent {
3393
3450
  tooltipId = `africanies-tooltip-${++nextTooltipId}`;
3394
3451
  customTrigger = contentChild(TooltipTriggerDirective, /* @ts-ignore */
@@ -3666,6 +3723,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
3666
3723
  * </africanies-info-popover>
3667
3724
  * ```
3668
3725
  */
3726
+ /**
3727
+ * Marks projected content as the custom trigger for {@link InfoPopoverComponent}.
3728
+ */
3669
3729
  class InfoPopoverTriggerDirective {
3670
3730
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: InfoPopoverTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
3671
3731
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: InfoPopoverTriggerDirective, isStandalone: true, selector: "[africaniesInfoPopoverTrigger]", ngImport: i0 });
@@ -3771,6 +3831,9 @@ const PLACEMENT_POSITIONS = {
3771
3831
  * </africanies-info-popover>
3772
3832
  * ```
3773
3833
  */
3834
+ /**
3835
+ * Hover / focus / click info panel with a white card, optional title, and fully projected body content (any child component or markup).
3836
+ */
3774
3837
  class InfoPopoverComponent {
3775
3838
  panelId = `africanies-info-popover-${++nextInfoPopoverId}`;
3776
3839
  customTrigger = contentChild(InfoPopoverTriggerDirective, /* @ts-ignore */
@@ -4086,6 +4149,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
4086
4149
  * </africanies-info-popover>
4087
4150
  * ```
4088
4151
  */
4152
+ /**
4153
+ * Marks projected content as the panel body for {@link InfoPopoverComponent}.
4154
+ */
4089
4155
  class InfoPopoverContentDirective {
4090
4156
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: InfoPopoverContentDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
4091
4157
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: InfoPopoverContentDirective, isStandalone: true, selector: "[africaniesInfoPopoverContent]", ngImport: i0 });
@@ -4186,6 +4252,9 @@ let nextDatePickerId = 0;
4186
4252
  * </africanies-date-picker>
4187
4253
  * ```
4188
4254
  */
4255
+ /**
4256
+ * Date field wrapping native `input[type=date]`, following shared AFRICANIES form field pattern.
4257
+ */
4189
4258
  class DatePickerComponent {
4190
4259
  theme = inject(ThemeService, { optional: true });
4191
4260
  controlId = `africanies-date-picker-${++nextDatePickerId}`;
@@ -4632,6 +4701,9 @@ function attachOverlayContent(overlay, parentInjector, component, overlayConfig,
4632
4701
  * });
4633
4702
  * ```
4634
4703
  */
4704
+ /**
4705
+ * Opens centered modal dialogs via Angular CDK Overlay.
4706
+ */
4635
4707
  class ModalService {
4636
4708
  overlay = inject(Overlay);
4637
4709
  injector = inject(Injector);
@@ -4817,6 +4889,9 @@ const SELECT_PANEL_POSITIONS = [
4817
4889
  * ]);
4818
4890
  * ```
4819
4891
  */
4892
+ /**
4893
+ * Option select following the shared AFRICANIES form field pattern.
4894
+ */
4820
4895
  class SelectComponent {
4821
4896
  modal = inject(ModalService, { optional: true });
4822
4897
  modeColor = inject(ModeColorService);
@@ -6133,6 +6208,9 @@ let nextTextInputId = 0;
6133
6208
  * </africanies-text-input>
6134
6209
  * ```
6135
6210
  */
6211
+ /**
6212
+ * Single-line text field — **reference** form control for `@africanies/africanies-ui`.
6213
+ */
6136
6214
  class TextInputComponent {
6137
6215
  /** Stable ids so label / aria-describedby stay paired across re-renders. */
6138
6216
  controlId = `africanies-text-input-${++nextTextInputId}`;
@@ -6341,6 +6419,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
6341
6419
  * No-ops when Angular Router is not in the injector (unit tests without
6342
6420
  * `provideRouter`).
6343
6421
  */
6422
+ /**
6423
+ * Bidirectional list-query sync with the browser URL.
6424
+ */
6344
6425
  class FilterQueryService {
6345
6426
  route = inject(ActivatedRoute, { optional: true });
6346
6427
  router = inject(Router, { optional: true });
@@ -6475,6 +6556,9 @@ function paramMapToRecord(map) {
6475
6556
  * {@link FilterDrawerResult}. Successful Apply also writes the query bag to
6476
6557
  * the browser URL via {@link FilterQueryService} (page resets to 1).
6477
6558
  */
6559
+ /**
6560
+ * Schema-driven filter drawer body.
6561
+ */
6478
6562
  class FilterDrawerPanel {
6479
6563
  data = inject(OVERLAY_DATA);
6480
6564
  ref = inject((AfricaniesOverlayRef));
@@ -7455,6 +7539,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
7455
7539
  * drawer.open(FiltersPanel, { data: { facet: 'status' } });
7456
7540
  * ```
7457
7541
  */
7542
+ /**
7543
+ * Opens edge-anchored drawer panels via Angular CDK Overlay.
7544
+ */
7458
7545
  class DrawerService {
7459
7546
  overlay = inject(Overlay);
7460
7547
  injector = inject(Injector);
@@ -7554,6 +7641,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
7554
7641
  * });
7555
7642
  * ```
7556
7643
  */
7644
+ /**
7645
+ * Opens the schema-driven {@link FilterDrawerPanel} via {@link DrawerService}.
7646
+ */
7557
7647
  class FilterDrawerService {
7558
7648
  drawer = inject(DrawerService);
7559
7649
  filterQuery = inject(FilterQueryService);
@@ -7590,6 +7680,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
7590
7680
  * primary button shows {@link ButtonComponent} loading until the work
7591
7681
  * settles. Errors leave the dialog open.
7592
7682
  */
7683
+ /**
7684
+ * Built-in confirm dialog hosted by {@link ConfirmService} / {@link ModalService}.
7685
+ */
7593
7686
  class ConfirmDialogComponent {
7594
7687
  /** Stable ids so aria-labelledby / aria-describedby stay unique per instance. */
7595
7688
  titleId = `africanies-confirm-title-${cryptoRandom()}`;
@@ -7890,6 +7983,9 @@ function cryptoRandom() {
7890
7983
  * });
7891
7984
  * ```
7892
7985
  */
7986
+ /**
7987
+ * One-line confirm flow built on {@link ModalService}.
7988
+ */
7893
7989
  class ConfirmService {
7894
7990
  modal = inject(ModalService);
7895
7991
  /**
@@ -7937,6 +8033,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
7937
8033
  * </africanies-overlay-frame>
7938
8034
  * ```
7939
8035
  */
8036
+ /**
8037
+ * Marks projected chrome as the non-scrolling overlay header (title + close).
8038
+ */
7940
8039
  class OverlayHeaderDirective {
7941
8040
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: OverlayHeaderDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
7942
8041
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: OverlayHeaderDirective, isStandalone: true, selector: "[africaniesOverlayHeader]", ngImport: i0 });
@@ -7962,6 +8061,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
7962
8061
  * </africanies-overlay-frame>
7963
8062
  * ```
7964
8063
  */
8064
+ /**
8065
+ * Marks projected chrome as the non-scrolling overlay footer (actions).
8066
+ */
7965
8067
  class OverlayFooterDirective {
7966
8068
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: OverlayFooterDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
7967
8069
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: OverlayFooterDirective, isStandalone: true, selector: "[africaniesOverlayFooter]", ngImport: i0 });
@@ -8004,6 +8106,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
8004
8106
  * export class EditModal {}
8005
8107
  * ```
8006
8108
  */
8109
+ /**
8110
+ * Header / scroll body / footer shell for {@link ModalService} and {@link DrawerService} panels.
8111
+ */
8007
8112
  class OverlayFrameComponent {
8008
8113
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: OverlayFrameComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
8009
8114
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "22.0.8", type: OverlayFrameComponent, isStandalone: true, selector: "africanies-overlay-frame", host: { classAttribute: "flex min-h-0 w-full flex-1 flex-col overflow-hidden" }, ngImport: i0, template: `
@@ -8113,6 +8218,9 @@ const PLACE_DETAILS_FIELD_MASK = 'id,displayName,formattedAddress,addressCompone
8113
8218
  * No Maps JavaScript widget, AutocompleteService, or PlacesService.
8114
8219
  * Register {@link provideGooglePlaces} with a key that has Places API (New).
8115
8220
  */
8221
+ /**
8222
+ * Places API (New) over REST — same contract as the working React autocomplete (`POST …/places:autocomplete`, `GET …/places/{id}`).
8223
+ */
8116
8224
  class GooglePlacesService {
8117
8225
  config = inject(GOOGLE_PLACES_CONFIG, { optional: true });
8118
8226
  /**
@@ -8312,6 +8420,9 @@ const ADDRESS_PANEL_POSITIONS = [
8312
8420
  * </africanies-address-input>
8313
8421
  * ```
8314
8422
  */
8423
+ /**
8424
+ * Google Places address field with suggestion dropdown.
8425
+ */
8315
8426
  class AddressInputComponent {
8316
8427
  places = inject(GooglePlacesService);
8317
8428
  destroyRef = inject(DestroyRef);
@@ -8898,6 +9009,9 @@ let nextCheckboxId = 0;
8898
9009
  * />
8899
9010
  * ```
8900
9011
  */
9012
+ /**
9013
+ * Boolean checkbox following the shared AFRICANIES form field pattern.
9014
+ */
8901
9015
  class CheckboxComponent {
8902
9016
  modeColor = inject(ModeColorService);
8903
9017
  controlId = `africanies-checkbox-${++nextCheckboxId}`;
@@ -9208,6 +9322,9 @@ function fileExtensionLabel(fileName) {
9208
9322
  * Prefer opening via {@link ModalService} so the stream is owned by this
9209
9323
  * dialog and torn down on close / destroy.
9210
9324
  */
9325
+ /**
9326
+ * Live webcam capture dialog for {@link FileUploadComponent}.
9327
+ */
9211
9328
  class CameraCaptureDialogComponent {
9212
9329
  destroyRef = inject(DestroyRef);
9213
9330
  ref = inject((AfricaniesOverlayRef));
@@ -9514,6 +9631,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
9514
9631
  * Object URLs created here are revoked on destroy; the list’s image
9515
9632
  * `previewUrl` is left alone.
9516
9633
  */
9634
+ /**
9635
+ * Large-file preview modal for {@link FileUploadComponent}.
9636
+ */
9517
9637
  class FilePreviewDialogComponent {
9518
9638
  data = inject(OVERLAY_DATA);
9519
9639
  ref = inject((AfricaniesOverlayRef));
@@ -9713,6 +9833,9 @@ let nextFileUploadId = 0;
9713
9833
  * />
9714
9834
  * ```
9715
9835
  */
9836
+ /**
9837
+ * File / camera / drag-and-drop picker following the shared AFRICANIES form field pattern.
9838
+ */
9716
9839
  class FileUploadComponent {
9717
9840
  destroyRef = inject(DestroyRef);
9718
9841
  /** Optional so the control still works when overlays are not registered. */
@@ -10781,6 +10904,9 @@ function formatWhileTyping(raw) {
10781
10904
  * amount = signal<number | null>(1250); // UI shows "1,250"
10782
10905
  * ```
10783
10906
  */
10907
+ /**
10908
+ * Numeric field following the shared AFRICANIES form field pattern.
10909
+ */
10784
10910
  class NumberInputComponent {
10785
10911
  controlId = `africanies-number-input-${++nextNumberInputId}`;
10786
10912
  hintId = `${this.controlId}-hint`;
@@ -11064,6 +11190,9 @@ let nextOtpId = 0;
11064
11190
  * />
11065
11191
  * ```
11066
11192
  */
11193
+ /**
11194
+ * One-time-passcode field — discrete digit cells, single string model.
11195
+ */
11067
11196
  class OtpInputComponent {
11068
11197
  destroyRef = inject(DestroyRef);
11069
11198
  cellInputs = viewChildren('cellInput', /* @ts-ignore */
@@ -11487,58 +11616,1052 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
11487
11616
  `, styles: [".africanies-otp-cell-masked{-webkit-text-security:disc;text-security:disc}\n"] }]
11488
11617
  }], ctorParameters: () => [], propDecorators: { cellInputs: [{ type: i0.ViewChildren, args: ['cellInput', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], length: [{ type: i0.Input, args: [{ isSignal: true, alias: "length", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], showResend: [{ type: i0.Input, args: [{ isSignal: true, alias: "showResend", required: false }] }], resendPrompt: [{ type: i0.Input, args: [{ isSignal: true, alias: "resendPrompt", required: false }] }], resendLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "resendLabel", required: false }] }], resendCooldown: [{ type: i0.Input, args: [{ isSignal: true, alias: "resendCooldown", required: false }] }], completed: [{ type: i0.Output, args: ["completed"] }], resend: [{ type: i0.Output, args: ["resend"] }] } });
11489
11618
 
11490
- let nextRadioId = 0;
11491
11619
  /**
11492
- * Radio group following the shared AFRICANIES form field pattern.
11620
+ * ISO 3166-1 alpha-2 dial code (with `+`).
11493
11621
  *
11494
- * **Prefix/suffix slots are omitted** radios are mutually exclusive options
11495
- * with labels; affix projection does not apply.
11622
+ * Shared with classic import-export phone fields; used when
11623
+ * `libphonenumber-js` is not bundled as a peer.
11624
+ */
11625
+ const PHONE_DIAL_CODES = {
11626
+ AF: '+93',
11627
+ AX: '+358',
11628
+ AL: '+355',
11629
+ DZ: '+213',
11630
+ AS: '+1',
11631
+ AD: '+376',
11632
+ AO: '+244',
11633
+ AI: '+1',
11634
+ AQ: '+672',
11635
+ AG: '+1',
11636
+ AR: '+54',
11637
+ AM: '+374',
11638
+ AW: '+297',
11639
+ AU: '+61',
11640
+ AT: '+43',
11641
+ AZ: '+994',
11642
+ BS: '+1',
11643
+ BH: '+973',
11644
+ BD: '+880',
11645
+ BB: '+1',
11646
+ BY: '+375',
11647
+ BE: '+32',
11648
+ BZ: '+501',
11649
+ BJ: '+229',
11650
+ BM: '+1',
11651
+ BT: '+975',
11652
+ BO: '+591',
11653
+ BQ: '+599',
11654
+ BA: '+387',
11655
+ BW: '+267',
11656
+ BV: '+55',
11657
+ BR: '+55',
11658
+ IO: '+246',
11659
+ BN: '+673',
11660
+ BG: '+359',
11661
+ BF: '+226',
11662
+ BI: '+257',
11663
+ KH: '+855',
11664
+ CM: '+237',
11665
+ CA: '+1',
11666
+ CV: '+238',
11667
+ KY: '+1',
11668
+ CF: '+236',
11669
+ TD: '+235',
11670
+ CL: '+56',
11671
+ CN: '+86',
11672
+ CX: '+61',
11673
+ CC: '+61',
11674
+ CO: '+57',
11675
+ KM: '+269',
11676
+ CG: '+242',
11677
+ CK: '+682',
11678
+ CR: '+506',
11679
+ HR: '+385',
11680
+ CU: '+53',
11681
+ CW: '+599',
11682
+ CY: '+357',
11683
+ CZ: '+420',
11684
+ DK: '+45',
11685
+ DJ: '+253',
11686
+ DM: '+1',
11687
+ DO: '+1',
11688
+ CD: '+243',
11689
+ EC: '+593',
11690
+ EG: '+20',
11691
+ SV: '+503',
11692
+ GQ: '+240',
11693
+ ER: '+291',
11694
+ EE: '+370',
11695
+ ET: '+251',
11696
+ FK: '+500',
11697
+ FO: '+298',
11698
+ FJ: '+679',
11699
+ FI: '+358',
11700
+ FR: '+33',
11701
+ GF: '+594',
11702
+ PF: '+689',
11703
+ TF: '+262',
11704
+ GA: '+241',
11705
+ GM: '+220',
11706
+ GE: '+995',
11707
+ DE: '+49',
11708
+ GH: '+233',
11709
+ GI: '+350',
11710
+ GR: '+30',
11711
+ GL: '+299',
11712
+ GD: '+1',
11713
+ GP: '+590',
11714
+ GU: '+1',
11715
+ GT: '+502',
11716
+ GG: '+44',
11717
+ GN: '+224',
11718
+ GW: '+245',
11719
+ GY: '+592',
11720
+ HT: '+509',
11721
+ HM: '+672',
11722
+ HN: '+504',
11723
+ HK: '+852',
11724
+ HU: '+36',
11725
+ IS: '+354',
11726
+ IN: '+91',
11727
+ ID: '+62',
11728
+ IR: '+98',
11729
+ IQ: '+964',
11730
+ IE: '+353',
11731
+ IM: '+44',
11732
+ IL: '+972',
11733
+ IT: '+39',
11734
+ CI: '+225',
11735
+ JM: '+1',
11736
+ JP: '+81',
11737
+ JE: '+44',
11738
+ JO: '+962',
11739
+ KZ: '+7',
11740
+ KE: '+254',
11741
+ KI: '+686',
11742
+ XK: '+383',
11743
+ KW: '+965',
11744
+ KG: '+996',
11745
+ LA: '+856',
11746
+ LV: '+371',
11747
+ LB: '+961',
11748
+ LS: '+266',
11749
+ LR: '+231',
11750
+ LY: '+218',
11751
+ LI: '+423',
11752
+ LT: '+370',
11753
+ LU: '+352',
11754
+ MO: '+853',
11755
+ MK: '+389',
11756
+ MG: '+261',
11757
+ MW: '+265',
11758
+ MY: '+60',
11759
+ MV: '+960',
11760
+ ML: '+223',
11761
+ MT: '+356',
11762
+ MH: '+692',
11763
+ MQ: '+596',
11764
+ MR: '+222',
11765
+ MU: '+230',
11766
+ YT: '+262',
11767
+ MX: '+52',
11768
+ FM: '+691',
11769
+ MD: '+373',
11770
+ MC: '+377',
11771
+ MN: '+976',
11772
+ ME: '+382',
11773
+ MS: '+1',
11774
+ MA: '+212',
11775
+ MZ: '+258',
11776
+ MM: '+95',
11777
+ NA: '+264',
11778
+ NR: '+674',
11779
+ NP: '+977',
11780
+ NL: '+31',
11781
+ AN: '+599',
11782
+ NC: '+687',
11783
+ NZ: '+64',
11784
+ NI: '+505',
11785
+ NE: '+227',
11786
+ NG: '+234',
11787
+ NU: '+683',
11788
+ NF: '+672',
11789
+ MP: '+1',
11790
+ KP: '+850',
11791
+ NO: '+47',
11792
+ OM: '+968',
11793
+ PK: '+92',
11794
+ PW: '+680',
11795
+ PS: '+970',
11796
+ PA: '+507',
11797
+ PG: '+675',
11798
+ PY: '+595',
11799
+ PE: '+51',
11800
+ PH: '+63',
11801
+ PN: '+64',
11802
+ PL: '+48',
11803
+ PT: '+351',
11804
+ PR: '+1',
11805
+ QA: '+974',
11806
+ RO: '+40',
11807
+ RU: '+7',
11808
+ RW: '+250',
11809
+ RE: '+262',
11810
+ BL: '+590',
11811
+ MF: '+590',
11812
+ SH: '+290',
11813
+ KN: '+1',
11814
+ LC: '+1',
11815
+ PM: '+508',
11816
+ VC: '+1',
11817
+ WS: '+685',
11818
+ SM: '+378',
11819
+ ST: '+239',
11820
+ SA: '+966',
11821
+ SN: '+221',
11822
+ RS: '+381',
11823
+ SC: '+248',
11824
+ SL: '+232',
11825
+ SG: '+65',
11826
+ SX: '+1',
11827
+ SK: '+421',
11828
+ SI: '+386',
11829
+ SB: '+677',
11830
+ SO: '+252',
11831
+ ZA: '+27',
11832
+ GS: '+500',
11833
+ KR: '+82',
11834
+ SS: '+211',
11835
+ ES: '+34',
11836
+ LK: '+94',
11837
+ SD: '+249',
11838
+ SR: '+597',
11839
+ SJ: '+47',
11840
+ SZ: '+268',
11841
+ SE: '+46',
11842
+ CH: '+41',
11843
+ SY: '+963',
11844
+ TW: '+886',
11845
+ TJ: '+992',
11846
+ TZ: '+255',
11847
+ TH: '+66',
11848
+ TL: '+670',
11849
+ TG: '+228',
11850
+ TK: '+690',
11851
+ TO: '+676',
11852
+ TT: '+1',
11853
+ TN: '+216',
11854
+ TR: '+90',
11855
+ TM: '+993',
11856
+ TC: '+1',
11857
+ TV: '+688',
11858
+ UG: '+256',
11859
+ UA: '+380',
11860
+ AE: '+971',
11861
+ GB: '+44',
11862
+ US: '+1',
11863
+ UY: '+598',
11864
+ UZ: '+998',
11865
+ VU: '+678',
11866
+ VA: '+379',
11867
+ VE: '+58',
11868
+ VN: '+84',
11869
+ VG: '+1',
11870
+ VI: '+1',
11871
+ WF: '+681',
11872
+ EH: '+212',
11873
+ YE: '+967',
11874
+ ZM: '+260',
11875
+ ZW: '+263',
11876
+ };
11877
+ /** Max national digit count (ITU E.164 national significant number). */
11878
+ const PHONE_MAX_NATIONAL_DIGITS = 15;
11879
+ /** Minimum national digits before we treat a draft as a complete number. */
11880
+ const PHONE_MIN_NATIONAL_DIGITS = 4;
11881
+
11882
+ const regionNames = typeof Intl !== 'undefined' && 'DisplayNames' in Intl
11883
+ ? new Intl.DisplayNames(['en'], { type: 'region' })
11884
+ : null;
11885
+ /** Digits only from a phone draft. */
11886
+ function phoneDigitsOnly(value) {
11887
+ return (value ?? '').replace(/\D/g, '');
11888
+ }
11889
+ /** Normalize ISO2 to uppercase two letters, or `''`. */
11890
+ function normalizePhoneIso2(iso2) {
11891
+ const code = (iso2 ?? '').trim().toUpperCase();
11892
+ return /^[A-Z]{2}$/.test(code) ? code : '';
11893
+ }
11894
+ /** Dial code for an ISO2 (with `+`), or `''` when unknown. */
11895
+ function dialCodeForIso2(iso2) {
11896
+ const code = normalizePhoneIso2(iso2);
11897
+ return code ? (PHONE_DIAL_CODES[code] ?? '') : '';
11898
+ }
11899
+ /** English country name from ISO2 (falls back to the code). */
11900
+ function phoneCountryName(iso2) {
11901
+ const code = normalizePhoneIso2(iso2);
11902
+ if (!code) {
11903
+ return '';
11904
+ }
11905
+ try {
11906
+ return regionNames?.of(code) ?? code;
11907
+ }
11908
+ catch {
11909
+ return code;
11910
+ }
11911
+ }
11912
+ /** All dial-code countries for the picker (sorted by name). */
11913
+ function phoneCountryOptions() {
11914
+ return Object.keys(PHONE_DIAL_CODES)
11915
+ .map((iso2) => {
11916
+ const dialCode = PHONE_DIAL_CODES[iso2];
11917
+ return {
11918
+ iso2,
11919
+ dialCode,
11920
+ name: phoneCountryName(iso2),
11921
+ flagUrl: countryFlagUrl(iso2, { width: 40 }),
11922
+ };
11923
+ })
11924
+ .sort((a, b) => a.name.localeCompare(b.name));
11925
+ }
11926
+ /**
11927
+ * Filter dial-code countries by name, ISO2, or dial digits.
11928
+ * Digit matching is skipped when the query has no digits — otherwise
11929
+ * `''.includes('')` would keep every country for letter-only searches.
11930
+ */
11931
+ function filterPhoneCountries(countries, query) {
11932
+ const q = query.trim().toLowerCase();
11933
+ if (!q) {
11934
+ return [...countries];
11935
+ }
11936
+ const qDigits = phoneDigitsOnly(q);
11937
+ return countries.filter((row) => {
11938
+ if (row.name.toLowerCase().includes(q) ||
11939
+ row.iso2.toLowerCase().includes(q) ||
11940
+ row.dialCode.toLowerCase().includes(q)) {
11941
+ return true;
11942
+ }
11943
+ return qDigits.length > 0
11944
+ ? phoneDigitsOnly(row.dialCode).includes(qDigits)
11945
+ : false;
11946
+ });
11947
+ }
11948
+ /**
11949
+ * Match an E.164 / international string to the longest known dial code.
11950
+ * Prefers `hintIso2` when several countries share the same dial code (e.g. `+1`).
11951
+ */
11952
+ function matchDialCode(e164OrInternational, hintIso2) {
11953
+ const digits = phoneDigitsOnly(e164OrInternational);
11954
+ if (!digits) {
11955
+ return null;
11956
+ }
11957
+ const hint = normalizePhoneIso2(hintIso2);
11958
+ if (hint) {
11959
+ const hintDial = PHONE_DIAL_CODES[hint];
11960
+ if (hintDial) {
11961
+ const hintDigits = phoneDigitsOnly(hintDial);
11962
+ if (digits.startsWith(hintDigits)) {
11963
+ return {
11964
+ iso2: hint,
11965
+ dialCode: hintDial,
11966
+ nationalDigits: digits.slice(hintDigits.length),
11967
+ };
11968
+ }
11969
+ }
11970
+ }
11971
+ let best = null;
11972
+ for (const [iso2, dialCode] of Object.entries(PHONE_DIAL_CODES)) {
11973
+ const dialDigits = phoneDigitsOnly(dialCode);
11974
+ if (!digits.startsWith(dialDigits)) {
11975
+ continue;
11976
+ }
11977
+ const nationalDigits = digits.slice(dialDigits.length);
11978
+ if (!best ||
11979
+ dialDigits.length > phoneDigitsOnly(best.dialCode).length) {
11980
+ best = { iso2, dialCode, nationalDigits };
11981
+ }
11982
+ }
11983
+ return best;
11984
+ }
11985
+ /**
11986
+ * Strip a leading dial code from a stored phone (classic `removeDialCode`).
11987
+ * Returns national digits for prefilling the input.
11988
+ */
11989
+ function removeDialCode(phone, hintIso2) {
11990
+ const raw = (phone ?? '').trim();
11991
+ if (!raw) {
11992
+ return '';
11993
+ }
11994
+ const matched = matchDialCode(raw, hintIso2);
11995
+ if (matched) {
11996
+ return matched.nationalDigits;
11997
+ }
11998
+ return phoneDigitsOnly(raw);
11999
+ }
12000
+ /** Group national digits for readable display (… + last 4). */
12001
+ function formatNationalDigits(digits) {
12002
+ const clean = phoneDigitsOnly(digits).slice(0, PHONE_MAX_NATIONAL_DIGITS);
12003
+ if (!clean) {
12004
+ return '';
12005
+ }
12006
+ if (clean.length <= 4) {
12007
+ return clean;
12008
+ }
12009
+ const end = clean.slice(-4);
12010
+ const head = clean.slice(0, -4).replace(/(\d{3})(?=\d)/g, '$1 ').trim();
12011
+ return `${head} ${end}`.trim();
12012
+ }
12013
+ /**
12014
+ * Build the structured value (or `null` when empty).
12015
+ */
12016
+ function buildPhoneNumberValue(iso2, nationalDraft) {
12017
+ const countryCode = normalizePhoneIso2(iso2);
12018
+ const dialCode = dialCodeForIso2(countryCode);
12019
+ if (!countryCode || !dialCode) {
12020
+ return null;
12021
+ }
12022
+ const nationalDigits = phoneDigitsOnly(nationalDraft).slice(0, PHONE_MAX_NATIONAL_DIGITS);
12023
+ if (!nationalDigits) {
12024
+ return null;
12025
+ }
12026
+ const number = formatNationalDigits(nationalDigits);
12027
+ const e164Number = `${dialCode}${nationalDigits}`;
12028
+ const internationalNumber = `${dialCode} ${number}`.trim();
12029
+ // Trunk-prefix `0` for national display when digits omit it (classic ngx shape).
12030
+ const nationalNumber = nationalDigits.startsWith('0')
12031
+ ? number
12032
+ : `0${number}`;
12033
+ return {
12034
+ number,
12035
+ internationalNumber,
12036
+ nationalNumber,
12037
+ e164Number,
12038
+ countryCode,
12039
+ dialCode,
12040
+ };
12041
+ }
12042
+ /**
12043
+ * Canonical outbound phone string — prefer E.164 from a structured value.
12044
+ */
12045
+ function phoneToE164(phone) {
12046
+ if (phone == null) {
12047
+ return '';
12048
+ }
12049
+ if (typeof phone === 'string') {
12050
+ const digits = phoneDigitsOnly(phone);
12051
+ if (!digits) {
12052
+ return '';
12053
+ }
12054
+ return phone.trim().startsWith('+') ? `+${digits}` : phone.trim();
12055
+ }
12056
+ return phone.e164Number?.trim() || '';
12057
+ }
12058
+ /**
12059
+ * Soft validity: has dial code + enough national digits (not full libphonenumber).
12060
+ */
12061
+ function isPhoneNumberComplete(phone) {
12062
+ if (!phone?.e164Number) {
12063
+ return false;
12064
+ }
12065
+ const national = phoneDigitsOnly(phone.number);
12066
+ return (national.length >= PHONE_MIN_NATIONAL_DIGITS &&
12067
+ national.length <= PHONE_MAX_NATIONAL_DIGITS);
12068
+ }
12069
+ /**
12070
+ * Split an incoming control value (E.164 string or structured) into UI state.
12071
+ */
12072
+ function parsePhoneControlValue(value, fallbackIso2) {
12073
+ const fallback = normalizePhoneIso2(fallbackIso2) || 'US';
12074
+ if (value == null || value === '') {
12075
+ return { iso2: fallback, nationalDigits: '' };
12076
+ }
12077
+ if (typeof value === 'object') {
12078
+ const iso2 = normalizePhoneIso2(value.countryCode) || fallback;
12079
+ const national = phoneDigitsOnly(value.number) ||
12080
+ phoneDigitsOnly(value.nationalNumber) ||
12081
+ removeDialCode(value.e164Number, iso2);
12082
+ return { iso2, nationalDigits: national };
12083
+ }
12084
+ const matched = matchDialCode(value, fallback);
12085
+ if (matched) {
12086
+ return {
12087
+ iso2: matched.iso2,
12088
+ nationalDigits: matched.nationalDigits,
12089
+ };
12090
+ }
12091
+ return {
12092
+ iso2: fallback,
12093
+ nationalDigits: phoneDigitsOnly(value),
12094
+ };
12095
+ }
12096
+
12097
+ let nextPhoneInputId = 0;
12098
+ const PANEL_POSITIONS$1 = [
12099
+ {
12100
+ originX: 'start',
12101
+ originY: 'bottom',
12102
+ overlayX: 'start',
12103
+ overlayY: 'top',
12104
+ offsetY: 4,
12105
+ },
12106
+ {
12107
+ originX: 'start',
12108
+ originY: 'top',
12109
+ overlayX: 'start',
12110
+ overlayY: 'bottom',
12111
+ offsetY: -4,
12112
+ },
12113
+ ];
12114
+ /**
12115
+ * International phone field — flag + dial code + national number.
11496
12116
  *
11497
- * Selected ring and center disc follow {@link ModeColorService}
11498
- * (SFN green / STN orange).
12117
+ * Visual / behavioral cousin of classic `africanies-phone-field`
12118
+ * (`ngx-intl-tel-input`), rebuilt for Angular 22 + AFRICANIES form chrome
12119
+ * (no ngx peer-dep).
11499
12120
  *
11500
- * @typeParam T - Option value type.
12121
+ * **Value contract**
12122
+ * - `[(value)]` / CVA → **E.164 string** (e.g. `+2348012345678`) so admin
12123
+ * mappers stay `phone: string`.
12124
+ * - `phoneValue` model mirrors the structured classic object when you need
12125
+ * `countryCode` / `dialCode` in the parent.
11501
12126
  *
11502
12127
  * @example
11503
12128
  * ```html
11504
- * <africanies-radio
11505
- * label="Shipment mode"
11506
- * [options]="modeOptions"
11507
- * [(value)]="mode"
12129
+ * <africanies-phone-input
12130
+ * label="Phone"
12131
+ * [countryIso2]="countryIso"
12132
+ * [lockCountry]="true"
12133
+ * [error]="phoneError()"
12134
+ * [(value)]="phone"
11508
12135
  * />
11509
12136
  * ```
11510
12137
  */
11511
- class RadioComponent {
11512
- modeColor = inject(ModeColorService);
11513
- groupName = `africanies-radio-${++nextRadioId}`;
11514
- hintId = `${this.groupName}-hint`;
11515
- errorId = `${this.groupName}-error`;
12138
+ /**
12139
+ * International phone field — flag + dial code + national number.
12140
+ */
12141
+ class PhoneInputComponent {
12142
+ controlId = `africanies-phone-input-${++nextPhoneInputId}`;
12143
+ hintId = `${this.controlId}-hint`;
12144
+ errorId = `${this.controlId}-error`;
11516
12145
  labelClass = FORM_LABEL_CLASS;
11517
12146
  hintClass = FORM_HINT_CLASS;
11518
12147
  errorClass = FORM_ERROR_CLASS;
11519
- /** Group legend / label. */
12148
+ panelPositions = PANEL_POSITIONS$1;
12149
+ allCountries = phoneCountryOptions();
12150
+ injector = inject(Injector);
12151
+ countrySearch = viewChild('countrySearch', /* @ts-ignore */
12152
+ ...(ngDevMode ? [{ debugName: "countrySearch" }] : /* istanbul ignore next */ []));
12153
+ /** Visible field label. */
11520
12154
  label = input('', /* @ts-ignore */
11521
12155
  ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
11522
- /** Helper copy. Hidden while {@link error} is set. */
12156
+ /** Helper under the field (hidden while {@link error} is set). */
11523
12157
  hint = input(undefined, /* @ts-ignore */
11524
12158
  ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
11525
- /** Field-level validation message. Distinct from `ErrorStateComponent`. */
12159
+ /** Field-level validation message. */
11526
12160
  error = input(null, /* @ts-ignore */
11527
12161
  ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
11528
- /** Options rendered as radios. */
11529
- options = input([], /* @ts-ignore */
11530
- ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
11531
- /** Selected option value (`[(value)]` + CVA). */
11532
- value = model(null, /* @ts-ignore */
12162
+ /** National-number placeholder. */
12163
+ placeholder = input('Phone number', /* @ts-ignore */
12164
+ ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
12165
+ /**
12166
+ * Selected country ISO2. Parents set this from address/user country.
12167
+ * Two-way so picking a country updates the parent.
12168
+ */
12169
+ countryIso2 = model('US', /* @ts-ignore */
12170
+ ...(ngDevMode ? [{ debugName: "countryIso2" }] : /* istanbul ignore next */ []));
12171
+ /**
12172
+ * When true, the flag/dial segment is not clickable (classic `resetISO`).
12173
+ * Use for locked sender-country phones; set `false` for free country pick.
12174
+ */
12175
+ lockCountry = input(false, { ...(ngDevMode ? { debugName: "lockCountry" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
12176
+ /**
12177
+ * E.164 string for `[(value)]` / reactive forms.
12178
+ * Empty string when cleared.
12179
+ */
12180
+ value = model('', /* @ts-ignore */
11533
12181
  ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
11534
- /** Host disable flag (in addition to CVA). */
12182
+ /**
12183
+ * Structured phone object (classic `PhoneNumberFormat` shape).
12184
+ * `null` when the national field is empty.
12185
+ */
12186
+ phoneValue = model(null, /* @ts-ignore */
12187
+ ...(ngDevMode ? [{ debugName: "phoneValue" }] : /* istanbul ignore next */ []));
11535
12188
  disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {}), alias: 'disabled',
11536
12189
  transform: booleanAttribute });
11537
12190
  cvaDisabled = signal(false, /* @ts-ignore */
11538
12191
  ...(ngDevMode ? [{ debugName: "cvaDisabled" }] : /* istanbul ignore next */ []));
11539
12192
  disabled = computed(() => this.disabledInput() || this.cvaDisabled(), /* @ts-ignore */
11540
12193
  ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
11541
- describedBy = computed(() => {
12194
+ countryOpen = signal(false, /* @ts-ignore */
12195
+ ...(ngDevMode ? [{ debugName: "countryOpen" }] : /* istanbul ignore next */ []));
12196
+ countryQuery = signal('', /* @ts-ignore */
12197
+ ...(ngDevMode ? [{ debugName: "countryQuery" }] : /* istanbul ignore next */ []));
12198
+ /** Digits currently typed in the national field. */
12199
+ nationalDigits = signal('', /* @ts-ignore */
12200
+ ...(ngDevMode ? [{ debugName: "nationalDigits" }] : /* istanbul ignore next */ []));
12201
+ dialCode = computed(() => dialCodeForIso2(this.countryIso2()) || '+1', /* @ts-ignore */
12202
+ ...(ngDevMode ? [{ debugName: "dialCode" }] : /* istanbul ignore next */ []));
12203
+ flagUrl = computed(() => {
12204
+ const iso = normalizePhoneIso2(this.countryIso2());
12205
+ return iso ? countryFlagUrl(iso, { width: 40 }) : '';
12206
+ }, /* @ts-ignore */
12207
+ ...(ngDevMode ? [{ debugName: "flagUrl" }] : /* istanbul ignore next */ []));
12208
+ nationalDisplay = computed(() => this.nationalDigits(), /* @ts-ignore */
12209
+ ...(ngDevMode ? [{ debugName: "nationalDisplay" }] : /* istanbul ignore next */ []));
12210
+ filteredCountries = computed(() => filterPhoneCountries(this.allCountries, this.countryQuery()), /* @ts-ignore */
12211
+ ...(ngDevMode ? [{ debugName: "filteredCountries" }] : /* istanbul ignore next */ []));
12212
+ shellClass = computed(() => {
12213
+ let classes = FORM_FIELD_CLASS;
12214
+ if (this.error()) {
12215
+ classes += ` ${FORM_FIELD_ERROR_CLASS}`;
12216
+ }
12217
+ if (this.disabled()) {
12218
+ classes += ` ${FORM_DISABLED_CLASS}`;
12219
+ }
12220
+ return classes;
12221
+ }, /* @ts-ignore */
12222
+ ...(ngDevMode ? [{ debugName: "shellClass" }] : /* istanbul ignore next */ []));
12223
+ describedBy = computed(() => {
12224
+ if (this.error()) {
12225
+ return this.errorId;
12226
+ }
12227
+ if (this.hint()) {
12228
+ return this.hintId;
12229
+ }
12230
+ return null;
12231
+ }, /* @ts-ignore */
12232
+ ...(ngDevMode ? [{ debugName: "describedBy" }] : /* istanbul ignore next */ []));
12233
+ onChange = () => undefined;
12234
+ onTouched = () => undefined;
12235
+ /** True while applying an external `value` so emit does not loop. */
12236
+ syncingFromExternal = false;
12237
+ constructor() {
12238
+ // Template `[(value)]` / `[value]` updates the model but does not call CVA
12239
+ // `writeValue`. Sync national digits whenever the external value or the
12240
+ // parent-bound country changes (edit prepopulate + locked country forms).
12241
+ effect(() => {
12242
+ const external = this.value();
12243
+ const iso = this.countryIso2();
12244
+ const locked = this.lockCountry();
12245
+ untracked(() => this.applyExternalValue(external, iso, locked));
12246
+ });
12247
+ }
12248
+ maxLengthAttr() {
12249
+ return PHONE_MAX_NATIONAL_DIGITS;
12250
+ }
12251
+ writeValue(value) {
12252
+ this.applyExternalValue(value, this.countryIso2(), this.lockCountry());
12253
+ const e164 = this.phoneValue()?.e164Number ??
12254
+ (typeof value === 'string' ? value.trim() : '');
12255
+ this.syncingFromExternal = true;
12256
+ this.value.set(e164);
12257
+ this.syncingFromExternal = false;
12258
+ }
12259
+ registerOnChange(fn) {
12260
+ this.onChange = fn;
12261
+ }
12262
+ registerOnTouched(fn) {
12263
+ this.onTouched = fn;
12264
+ }
12265
+ setDisabledState(isDisabled) {
12266
+ this.cvaDisabled.set(isDisabled);
12267
+ }
12268
+ toggleCountryPicker(event) {
12269
+ event.preventDefault();
12270
+ event.stopPropagation();
12271
+ if (this.disabled() || this.lockCountry()) {
12272
+ return;
12273
+ }
12274
+ this.countryOpen.update((open) => !open);
12275
+ if (this.countryOpen()) {
12276
+ this.countryQuery.set('');
12277
+ // Overlay attaches on the next render; focus search so typing filters.
12278
+ afterNextRender(() => this.countrySearch()?.nativeElement.focus(), { injector: this.injector });
12279
+ }
12280
+ }
12281
+ closeCountryPicker() {
12282
+ this.countryOpen.set(false);
12283
+ }
12284
+ onCountryQuery(event) {
12285
+ this.countryQuery.set(event.target.value);
12286
+ }
12287
+ selectCountry(row) {
12288
+ this.countryIso2.set(row.iso2);
12289
+ this.closeCountryPicker();
12290
+ this.emitFromState();
12291
+ }
12292
+ onNationalInput(event) {
12293
+ const raw = event.target.value;
12294
+ const digits = phoneDigitsOnly(raw).slice(0, PHONE_MAX_NATIONAL_DIGITS);
12295
+ this.nationalDigits.set(digits);
12296
+ this.emitFromState();
12297
+ }
12298
+ onBlur() {
12299
+ this.onTouched();
12300
+ }
12301
+ applyExternalValue(value, preferredIso2, lockCountry) {
12302
+ const preferred = normalizePhoneIso2(preferredIso2) || 'US';
12303
+ const parsed = parsePhoneControlValue(value, preferred);
12304
+ // Locked forms keep the parent country; still strip that dial code from
12305
+ // stored E.164 / international strings so the national field prefills.
12306
+ const iso2 = lockCountry ? preferred : parsed.iso2;
12307
+ const nationalDigits = lockCountry
12308
+ ? nationalDigitsForLockedCountry(value, preferred)
12309
+ : parsed.nationalDigits;
12310
+ if (iso2 === normalizePhoneIso2(this.countryIso2()) &&
12311
+ nationalDigits === this.nationalDigits()) {
12312
+ return;
12313
+ }
12314
+ this.syncingFromExternal = true;
12315
+ if (!lockCountry) {
12316
+ this.countryIso2.set(iso2);
12317
+ }
12318
+ this.nationalDigits.set(nationalDigits);
12319
+ this.phoneValue.set(buildPhoneNumberValue(iso2, nationalDigits));
12320
+ this.syncingFromExternal = false;
12321
+ }
12322
+ emitFromState() {
12323
+ if (this.syncingFromExternal) {
12324
+ return;
12325
+ }
12326
+ const structured = buildPhoneNumberValue(this.countryIso2(), this.nationalDigits());
12327
+ const e164 = structured ? phoneToE164(structured) : '';
12328
+ this.phoneValue.set(structured);
12329
+ this.value.set(e164);
12330
+ this.onChange(e164);
12331
+ }
12332
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PhoneInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
12333
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: PhoneInputComponent, isStandalone: true, selector: "africanies-phone-input", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, error: { classPropertyName: "error", publicName: "error", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, countryIso2: { classPropertyName: "countryIso2", publicName: "countryIso2", isSignal: true, isRequired: false, transformFunction: null }, lockCountry: { classPropertyName: "lockCountry", publicName: "lockCountry", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, phoneValue: { classPropertyName: "phoneValue", publicName: "phoneValue", isSignal: true, isRequired: false, transformFunction: null }, disabledInput: { classPropertyName: "disabledInput", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { countryIso2: "countryIso2Change", value: "valueChange", phoneValue: "phoneValueChange" }, host: { classAttribute: "relative block" }, providers: [
12334
+ {
12335
+ provide: NG_VALUE_ACCESSOR,
12336
+ useExisting: forwardRef(() => PhoneInputComponent),
12337
+ multi: true,
12338
+ },
12339
+ ], viewQueries: [{ propertyName: "countrySearch", first: true, predicate: ["countrySearch"], descendants: true, isSignal: true }], ngImport: i0, template: `
12340
+ <label [attr.for]="controlId" [class]="labelClass">{{ label() }}</label>
12341
+
12342
+ <div [class]="shellClass()">
12343
+ <button
12344
+ cdkOverlayOrigin
12345
+ #dialOrigin="cdkOverlayOrigin"
12346
+ type="button"
12347
+ class="inline-flex h-full shrink-0 items-center gap-1.5 border-0 border-r border-control bg-transparent px-2.5 text-body-sm text-ink dark:border-white/25 dark:text-white disabled:cursor-not-allowed"
12348
+ [class.pointer-events-none]="lockCountry()"
12349
+ [attr.aria-expanded]="countryOpen()"
12350
+ [attr.aria-haspopup]="'listbox'"
12351
+ [attr.aria-label]="'Country dial code'"
12352
+ [disabled]="disabled() || lockCountry()"
12353
+ (click)="toggleCountryPicker($event)"
12354
+ >
12355
+ @if (flagUrl(); as src) {
12356
+ <img
12357
+ [src]="src"
12358
+ alt=""
12359
+ class="h-4 w-5 rounded-sm object-cover"
12360
+ loading="lazy"
12361
+ aria-hidden="true"
12362
+ />
12363
+ }
12364
+ <span class="tabular-nums">{{ dialCode() }}</span>
12365
+ @if (!lockCountry()) {
12366
+ <africanies-icon name="chevron-down" [size]="14" class="shrink-0 opacity-70" />
12367
+ }
12368
+ </button>
12369
+
12370
+ <input
12371
+ [id]="controlId"
12372
+ type="tel"
12373
+ inputmode="tel"
12374
+ autocomplete="tel-national"
12375
+ class="min-h-0 h-full min-w-0 flex-1 border-0 bg-transparent px-3 py-0 text-body text-ink outline-none placeholder:text-neutral-500 disabled:cursor-not-allowed dark:text-white"
12376
+ [value]="nationalDisplay()"
12377
+ [disabled]="disabled()"
12378
+ [attr.placeholder]="placeholder() || null"
12379
+ [attr.maxlength]="maxLengthAttr()"
12380
+ [attr.aria-invalid]="error() ? true : null"
12381
+ [attr.aria-describedby]="describedBy()"
12382
+ (input)="onNationalInput($event)"
12383
+ (blur)="onBlur()"
12384
+ />
12385
+ </div>
12386
+
12387
+ @if (error(); as err) {
12388
+ <p [id]="errorId" [class]="errorClass" role="alert">{{ err }}</p>
12389
+ } @else if (hint(); as h) {
12390
+ <p [id]="hintId" [class]="hintClass">{{ h }}</p>
12391
+ }
12392
+
12393
+ <ng-template
12394
+ cdkConnectedOverlay
12395
+ [cdkConnectedOverlayOrigin]="dialOrigin"
12396
+ [cdkConnectedOverlayOpen]="countryOpen()"
12397
+ [cdkConnectedOverlayPositions]="panelPositions"
12398
+ [cdkConnectedOverlayWidth]="320"
12399
+ [cdkConnectedOverlayPush]="true"
12400
+ [cdkConnectedOverlayHasBackdrop]="true"
12401
+ cdkConnectedOverlayBackdropClass="cdk-overlay-transparent-backdrop"
12402
+ (backdropClick)="closeCountryPicker()"
12403
+ (overlayOutsideClick)="closeCountryPicker()"
12404
+ >
12405
+ <div
12406
+ class="flex w-full flex-col overflow-hidden rounded-md border border-border bg-white shadow-lg dark:border-white/15 dark:bg-ink-950"
12407
+ role="listbox"
12408
+ [attr.aria-label]="'Select country'"
12409
+ >
12410
+ <div class="border-b border-border p-2 dark:border-white/15">
12411
+ <input
12412
+ #countrySearch
12413
+ type="search"
12414
+ class="h-9 w-full rounded-control border border-control bg-transparent px-3 text-body-sm text-ink outline-none placeholder:text-neutral-500 focus:ring-2 focus:ring-inset focus:ring-focus dark:border-white/25 dark:text-white"
12415
+ placeholder="Search country or code"
12416
+ [value]="countryQuery()"
12417
+ (input)="onCountryQuery($event)"
12418
+ (keydown)="$event.stopPropagation()"
12419
+ />
12420
+ </div>
12421
+ <ul class="africanies-overlay-scroll m-0 max-h-56 list-none overflow-auto p-1">
12422
+ @for (row of filteredCountries(); track row.iso2) {
12423
+ <li>
12424
+ <button
12425
+ type="button"
12426
+ class="flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-2 text-left text-body-sm text-ink hover:bg-neutral-100 dark:text-white dark:hover:bg-white/10"
12427
+ [class.bg-neutral-100]="row.iso2 === countryIso2()"
12428
+ [class.dark:bg-white/10]="row.iso2 === countryIso2()"
12429
+ role="option"
12430
+ [attr.aria-selected]="row.iso2 === countryIso2()"
12431
+ (click)="selectCountry(row)"
12432
+ >
12433
+ <img
12434
+ [src]="row.flagUrl"
12435
+ alt=""
12436
+ class="h-4 w-5 shrink-0 rounded-sm object-cover"
12437
+ loading="lazy"
12438
+ aria-hidden="true"
12439
+ />
12440
+ <span class="min-w-0 flex-1 truncate">{{ row.name }}</span>
12441
+ <span class="shrink-0 tabular-nums text-neutral-600 dark:text-neutral-400">
12442
+ {{ row.dialCode }}
12443
+ </span>
12444
+ </button>
12445
+ </li>
12446
+ } @empty {
12447
+ <li class="px-3 py-4 text-center text-caption text-neutral-600 dark:text-neutral-400">
12448
+ No countries match.
12449
+ </li>
12450
+ }
12451
+ </ul>
12452
+ </div>
12453
+ </ng-template>
12454
+ `, isInline: true, dependencies: [{ kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }, { kind: "directive", type: CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "directive", type: CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation", "cdkConnectedOverlayUsePopover", "cdkConnectedOverlayMatchWidth", "cdkConnectedOverlay"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
12455
+ }
12456
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: PhoneInputComponent, decorators: [{
12457
+ type: Component,
12458
+ args: [{
12459
+ selector: 'africanies-phone-input',
12460
+ standalone: true,
12461
+ changeDetection: ChangeDetectionStrategy.OnPush,
12462
+ imports: [AfricaniesIconComponent, CdkOverlayOrigin, CdkConnectedOverlay],
12463
+ providers: [
12464
+ {
12465
+ provide: NG_VALUE_ACCESSOR,
12466
+ useExisting: forwardRef(() => PhoneInputComponent),
12467
+ multi: true,
12468
+ },
12469
+ ],
12470
+ host: {
12471
+ class: 'relative block',
12472
+ },
12473
+ template: `
12474
+ <label [attr.for]="controlId" [class]="labelClass">{{ label() }}</label>
12475
+
12476
+ <div [class]="shellClass()">
12477
+ <button
12478
+ cdkOverlayOrigin
12479
+ #dialOrigin="cdkOverlayOrigin"
12480
+ type="button"
12481
+ class="inline-flex h-full shrink-0 items-center gap-1.5 border-0 border-r border-control bg-transparent px-2.5 text-body-sm text-ink dark:border-white/25 dark:text-white disabled:cursor-not-allowed"
12482
+ [class.pointer-events-none]="lockCountry()"
12483
+ [attr.aria-expanded]="countryOpen()"
12484
+ [attr.aria-haspopup]="'listbox'"
12485
+ [attr.aria-label]="'Country dial code'"
12486
+ [disabled]="disabled() || lockCountry()"
12487
+ (click)="toggleCountryPicker($event)"
12488
+ >
12489
+ @if (flagUrl(); as src) {
12490
+ <img
12491
+ [src]="src"
12492
+ alt=""
12493
+ class="h-4 w-5 rounded-sm object-cover"
12494
+ loading="lazy"
12495
+ aria-hidden="true"
12496
+ />
12497
+ }
12498
+ <span class="tabular-nums">{{ dialCode() }}</span>
12499
+ @if (!lockCountry()) {
12500
+ <africanies-icon name="chevron-down" [size]="14" class="shrink-0 opacity-70" />
12501
+ }
12502
+ </button>
12503
+
12504
+ <input
12505
+ [id]="controlId"
12506
+ type="tel"
12507
+ inputmode="tel"
12508
+ autocomplete="tel-national"
12509
+ class="min-h-0 h-full min-w-0 flex-1 border-0 bg-transparent px-3 py-0 text-body text-ink outline-none placeholder:text-neutral-500 disabled:cursor-not-allowed dark:text-white"
12510
+ [value]="nationalDisplay()"
12511
+ [disabled]="disabled()"
12512
+ [attr.placeholder]="placeholder() || null"
12513
+ [attr.maxlength]="maxLengthAttr()"
12514
+ [attr.aria-invalid]="error() ? true : null"
12515
+ [attr.aria-describedby]="describedBy()"
12516
+ (input)="onNationalInput($event)"
12517
+ (blur)="onBlur()"
12518
+ />
12519
+ </div>
12520
+
12521
+ @if (error(); as err) {
12522
+ <p [id]="errorId" [class]="errorClass" role="alert">{{ err }}</p>
12523
+ } @else if (hint(); as h) {
12524
+ <p [id]="hintId" [class]="hintClass">{{ h }}</p>
12525
+ }
12526
+
12527
+ <ng-template
12528
+ cdkConnectedOverlay
12529
+ [cdkConnectedOverlayOrigin]="dialOrigin"
12530
+ [cdkConnectedOverlayOpen]="countryOpen()"
12531
+ [cdkConnectedOverlayPositions]="panelPositions"
12532
+ [cdkConnectedOverlayWidth]="320"
12533
+ [cdkConnectedOverlayPush]="true"
12534
+ [cdkConnectedOverlayHasBackdrop]="true"
12535
+ cdkConnectedOverlayBackdropClass="cdk-overlay-transparent-backdrop"
12536
+ (backdropClick)="closeCountryPicker()"
12537
+ (overlayOutsideClick)="closeCountryPicker()"
12538
+ >
12539
+ <div
12540
+ class="flex w-full flex-col overflow-hidden rounded-md border border-border bg-white shadow-lg dark:border-white/15 dark:bg-ink-950"
12541
+ role="listbox"
12542
+ [attr.aria-label]="'Select country'"
12543
+ >
12544
+ <div class="border-b border-border p-2 dark:border-white/15">
12545
+ <input
12546
+ #countrySearch
12547
+ type="search"
12548
+ class="h-9 w-full rounded-control border border-control bg-transparent px-3 text-body-sm text-ink outline-none placeholder:text-neutral-500 focus:ring-2 focus:ring-inset focus:ring-focus dark:border-white/25 dark:text-white"
12549
+ placeholder="Search country or code"
12550
+ [value]="countryQuery()"
12551
+ (input)="onCountryQuery($event)"
12552
+ (keydown)="$event.stopPropagation()"
12553
+ />
12554
+ </div>
12555
+ <ul class="africanies-overlay-scroll m-0 max-h-56 list-none overflow-auto p-1">
12556
+ @for (row of filteredCountries(); track row.iso2) {
12557
+ <li>
12558
+ <button
12559
+ type="button"
12560
+ class="flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-2 text-left text-body-sm text-ink hover:bg-neutral-100 dark:text-white dark:hover:bg-white/10"
12561
+ [class.bg-neutral-100]="row.iso2 === countryIso2()"
12562
+ [class.dark:bg-white/10]="row.iso2 === countryIso2()"
12563
+ role="option"
12564
+ [attr.aria-selected]="row.iso2 === countryIso2()"
12565
+ (click)="selectCountry(row)"
12566
+ >
12567
+ <img
12568
+ [src]="row.flagUrl"
12569
+ alt=""
12570
+ class="h-4 w-5 shrink-0 rounded-sm object-cover"
12571
+ loading="lazy"
12572
+ aria-hidden="true"
12573
+ />
12574
+ <span class="min-w-0 flex-1 truncate">{{ row.name }}</span>
12575
+ <span class="shrink-0 tabular-nums text-neutral-600 dark:text-neutral-400">
12576
+ {{ row.dialCode }}
12577
+ </span>
12578
+ </button>
12579
+ </li>
12580
+ } @empty {
12581
+ <li class="px-3 py-4 text-center text-caption text-neutral-600 dark:text-neutral-400">
12582
+ No countries match.
12583
+ </li>
12584
+ }
12585
+ </ul>
12586
+ </div>
12587
+ </ng-template>
12588
+ `,
12589
+ }]
12590
+ }], ctorParameters: () => [], propDecorators: { countrySearch: [{ type: i0.ViewChild, args: ['countrySearch', { isSignal: true }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], error: [{ type: i0.Input, args: [{ isSignal: true, alias: "error", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], countryIso2: [{ type: i0.Input, args: [{ isSignal: true, alias: "countryIso2", required: false }] }, { type: i0.Output, args: ["countryIso2Change"] }], lockCountry: [{ type: i0.Input, args: [{ isSignal: true, alias: "lockCountry", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], phoneValue: [{ type: i0.Input, args: [{ isSignal: true, alias: "phoneValue", required: false }] }, { type: i0.Output, args: ["phoneValueChange"] }], disabledInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
12591
+ /** National digits when the dial-code country is fixed by the parent. */
12592
+ function nationalDigitsForLockedCountry(value, iso2) {
12593
+ if (value == null || value === '') {
12594
+ return '';
12595
+ }
12596
+ if (typeof value === 'object') {
12597
+ return (phoneDigitsOnly(value.number) ||
12598
+ phoneDigitsOnly(value.nationalNumber) ||
12599
+ removeDialCode(value.e164Number, iso2));
12600
+ }
12601
+ const stripped = removeDialCode(value, iso2);
12602
+ // removeDialCode returns full digits when no dial matched — still fine as national.
12603
+ return stripped;
12604
+ }
12605
+
12606
+ /**
12607
+ * Phone input form control exports.
12608
+ */
12609
+
12610
+ let nextRadioId = 0;
12611
+ /**
12612
+ * Radio group following the shared AFRICANIES form field pattern.
12613
+ *
12614
+ * **Prefix/suffix slots are omitted** — radios are mutually exclusive options
12615
+ * with labels; affix projection does not apply.
12616
+ *
12617
+ * Selected ring and center disc follow {@link ModeColorService}
12618
+ * (SFN green / STN orange).
12619
+ *
12620
+ * @typeParam T - Option value type.
12621
+ *
12622
+ * @example
12623
+ * ```html
12624
+ * <africanies-radio
12625
+ * label="Shipment mode"
12626
+ * [options]="modeOptions"
12627
+ * [(value)]="mode"
12628
+ * />
12629
+ * ```
12630
+ */
12631
+ /**
12632
+ * Radio group following the shared AFRICANIES form field pattern.
12633
+ */
12634
+ class RadioComponent {
12635
+ modeColor = inject(ModeColorService);
12636
+ groupName = `africanies-radio-${++nextRadioId}`;
12637
+ hintId = `${this.groupName}-hint`;
12638
+ errorId = `${this.groupName}-error`;
12639
+ labelClass = FORM_LABEL_CLASS;
12640
+ hintClass = FORM_HINT_CLASS;
12641
+ errorClass = FORM_ERROR_CLASS;
12642
+ /** Group legend / label. */
12643
+ label = input('', /* @ts-ignore */
12644
+ ...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
12645
+ /** Helper copy. Hidden while {@link error} is set. */
12646
+ hint = input(undefined, /* @ts-ignore */
12647
+ ...(ngDevMode ? [{ debugName: "hint" }] : /* istanbul ignore next */ []));
12648
+ /** Field-level validation message. Distinct from `ErrorStateComponent`. */
12649
+ error = input(null, /* @ts-ignore */
12650
+ ...(ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []));
12651
+ /** Options rendered as radios. */
12652
+ options = input([], /* @ts-ignore */
12653
+ ...(ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []));
12654
+ /** Selected option value (`[(value)]` + CVA). */
12655
+ value = model(null, /* @ts-ignore */
12656
+ ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
12657
+ /** Host disable flag (in addition to CVA). */
12658
+ disabledInput = input(false, { ...(ngDevMode ? { debugName: "disabledInput" } : /* istanbul ignore next */ {}), alias: 'disabled',
12659
+ transform: booleanAttribute });
12660
+ cvaDisabled = signal(false, /* @ts-ignore */
12661
+ ...(ngDevMode ? [{ debugName: "cvaDisabled" }] : /* istanbul ignore next */ []));
12662
+ disabled = computed(() => this.disabledInput() || this.cvaDisabled(), /* @ts-ignore */
12663
+ ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
12664
+ describedBy = computed(() => {
11542
12665
  if (this.error()) {
11543
12666
  return this.errorId;
11544
12667
  }
@@ -11753,6 +12876,9 @@ const PANEL_POSITIONS = [
11753
12876
  * />
11754
12877
  * ```
11755
12878
  */
12879
+ /**
12880
+ * Generic type-as-you-search combobox with a debounced async lookup and overlay result list.
12881
+ */
11756
12882
  class SearchComboboxComponent {
11757
12883
  destroyRef = inject(DestroyRef);
11758
12884
  controlId = `africanies-search-combobox-${++nextSearchComboboxId}`;
@@ -12382,6 +13508,9 @@ let nextTextareaId = 0;
12382
13508
  * />
12383
13509
  * ```
12384
13510
  */
13511
+ /**
13512
+ * Multi-line text field following the shared form-control pattern (`shared AFRICANIES form field pattern`). Supports prefix/suffix slots, field-level `error`, and {@link ControlValueAccessor}.
13513
+ */
12385
13514
  class TextareaComponent {
12386
13515
  controlId = `africanies-textarea-${++nextTextareaId}`;
12387
13516
  hintId = `${this.controlId}-hint`;
@@ -12577,6 +13706,9 @@ let nextToggleId = 0;
12577
13706
  * />
12578
13707
  * ```
12579
13708
  */
13709
+ /**
13710
+ * Boolean switch following the shared AFRICANIES form field pattern.
13711
+ */
12580
13712
  class ToggleComponent {
12581
13713
  modeColor = inject(ModeColorService);
12582
13714
  controlId = `africanies-toggle-${++nextToggleId}`;
@@ -12824,6 +13956,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
12824
13956
  * <africanies-breadcrumb [items]="staticCrumbs" />
12825
13957
  * ```
12826
13958
  */
13959
+ /**
13960
+ * Breadcrumb trail for hierarchical navigation.
13961
+ */
12827
13962
  class BreadcrumbComponent {
12828
13963
  modeColor = inject(ModeColorService);
12829
13964
  /** Ordered crumbs; the last entry is the current page. */
@@ -13334,6 +14469,9 @@ const DEFAULT_LINK_ACTIVE$2 = {
13334
14469
  * ]" />
13335
14470
  * ```
13336
14471
  */
14472
+ /**
14473
+ * Compact segmented control for view modes and filters.
14474
+ */
13337
14475
  class SegmentComponent {
13338
14476
  router = inject(Router);
13339
14477
  modeColor = inject(ModeColorService);
@@ -13527,7 +14665,7 @@ class SegmentComponent {
13527
14665
  }
13528
14666
  }
13529
14667
  </div>
13530
- `, isInline: true, styles: [":host .africanies-segment-thumb{width:calc((100% - .5rem)/2)}\n"], dependencies: [{ kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
14668
+ `, isInline: true, styles: [":host .africanies-segment-thumb{width:calc((100% - .75rem)/2)}\n"], dependencies: [{ kind: "component", type: AfricaniesIconComponent, selector: "africanies-icon", inputs: ["name", "size"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
13531
14669
  }
13532
14670
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: SegmentComponent, decorators: [{
13533
14671
  type: Component,
@@ -13589,7 +14727,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
13589
14727
  }
13590
14728
  }
13591
14729
  </div>
13592
- `, styles: [":host .africanies-segment-thumb{width:calc((100% - .5rem)/2)}\n"] }]
14730
+ `, styles: [":host .africanies-segment-thumb{width:calc((100% - .75rem)/2)}\n"] }]
13593
14731
  }], ctorParameters: () => [], propDecorators: { items: [{ type: i0.Input, args: [{ isSignal: true, alias: "items", required: true }] }], activeId: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeId", required: false }] }, { type: i0.Output, args: ["activeIdChange"] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], linkActiveOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "linkActiveOptions", required: false }] }], keepScroll: [{ type: i0.Input, args: [{ isSignal: true, alias: "keepScroll", required: false }] }] } });
13594
14732
 
13595
14733
  const PANEL_OPEN_STORAGE_KEY = 'africanies-shipping-mode-panel-open';
@@ -13643,6 +14781,9 @@ const SHIPPING_MODE_GLYPH = `M88.42,68.75a48.8,48.8,0,0,1-4.74,11.1h9.89a7.67,7.
13643
14781
  * </africanies-side-nav>
13644
14782
  * ```
13645
14783
  */
14784
+ /**
14785
+ * Two-up shipping mode switcher for app-shell side navs.
14786
+ */
13646
14787
  class ShippingModeSwitchComponent {
13647
14788
  shipping = inject(ShippingModeService);
13648
14789
  /**
@@ -14038,6 +15179,9 @@ const AFRICANIES_BRAND_LOGO_MINI_URL = new InjectionToken('AFRICANIES_BRAND_LOGO
14038
15179
  * Override with a custom `logoSrc` on {@link SideNavComponent} when the host
14039
15180
  * ships its own mark.
14040
15181
  */
15182
+ /**
15183
+ * Default AFRICANIES wordmark — inlined so it works without copying static assets.
15184
+ */
14041
15185
  class BrandLogoComponent {
14042
15186
  size = input('md', /* @ts-ignore */
14043
15187
  ...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
@@ -14171,6 +15315,9 @@ const DEFAULT_LINK_ACTIVE$1 = {
14171
15315
  * />
14172
15316
  * ```
14173
15317
  */
15318
+ /**
15319
+ * App shell side navigation with icons, nested items, and a collapsible rail.
15320
+ */
14174
15321
  class SideNavComponent {
14175
15322
  modeColor = inject(ModeColorService);
14176
15323
  defaultLogoUrl = inject(AFRICANIES_BRAND_LOGO_URL);
@@ -14490,6 +15637,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
14490
15637
  * </ng-template>
14491
15638
  * ```
14492
15639
  */
15640
+ /**
15641
+ * Registers projected tab panel content against a tab id for {@link TabsComponent} (local / non-router mode).
15642
+ */
14493
15643
  class TabDefDirective {
14494
15644
  /** Template projected as the active tab panel. */
14495
15645
  template = inject((TemplateRef));
@@ -14543,6 +15693,9 @@ const DEFAULT_LINK_ACTIVE = {
14543
15693
  * <router-outlet />
14544
15694
  * ```
14545
15695
  */
15696
+ /**
15697
+ * Tab list for page / section navigation.
15698
+ */
14546
15699
  class TabsComponent {
14547
15700
  router = inject(Router);
14548
15701
  modeColor = inject(ModeColorService);
@@ -14892,6 +16045,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
14892
16045
  * </africanies-page-header>
14893
16046
  * ```
14894
16047
  */
16048
+ /**
16049
+ * Page title + subtitle for product screens.
16050
+ */
14895
16051
  class PageHeaderComponent {
14896
16052
  /** Page heading. Omit when the shell already rendered a title. */
14897
16053
  title = input('', /* @ts-ignore */
@@ -14967,6 +16123,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
14967
16123
  * Content chrome above the app-shell body: Back, breadcrumbs, then the page
14968
16124
  * title and optional subtitle.
14969
16125
  */
16126
+ /**
16127
+ * Content chrome above the app-shell body: Back, breadcrumbs, then the page title and optional subtitle.
16128
+ */
14970
16129
  class AppShellContentHeaderComponent {
14971
16130
  router = inject(Router);
14972
16131
  breadcrumbs = input([], /* @ts-ignore */
@@ -15090,6 +16249,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
15090
16249
  * <africanies-avatar name="Ops Team" />
15091
16250
  * ```
15092
16251
  */
16252
+ /**
16253
+ * Circular avatar with image or initials fallback.
16254
+ */
15093
16255
  class AvatarComponent {
15094
16256
  /** Display name — used for initials when no image loads. */
15095
16257
  name = input('', /* @ts-ignore */
@@ -15196,6 +16358,9 @@ function initialsFromName(name) {
15196
16358
  * />
15197
16359
  * ```
15198
16360
  */
16361
+ /**
16362
+ * Avatar trigger with an attached overflow menu — profile / account actions.
16363
+ */
15199
16364
  class AvatarMenuComponent {
15200
16365
  name = input.required(/* @ts-ignore */
15201
16366
  ...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
@@ -15292,6 +16457,9 @@ const MARK_ALL_CONFIRM_MS = 4000;
15292
16457
  *
15293
16458
  * Opened via {@link NotificationDrawerService}.
15294
16459
  */
16460
+ /**
16461
+ * Right-edge drawer listing in-app notifications.
16462
+ */
15295
16463
  class NotificationDrawerPanel {
15296
16464
  ref = inject(AfricaniesOverlayRef);
15297
16465
  data = inject(OVERLAY_DATA);
@@ -16098,6 +17266,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
16098
17266
  *
16099
17267
  * Requires {@link provideAfricaniesUiOverlays} at bootstrap.
16100
17268
  */
17269
+ /**
17270
+ * Opens {@link NotificationDrawerPanel} via {@link DrawerService}.
17271
+ */
16101
17272
  class NotificationDrawerService {
16102
17273
  drawer = inject(DrawerService);
16103
17274
  /**
@@ -16381,13 +17552,14 @@ function hashString(value) {
16381
17552
  }
16382
17553
 
16383
17554
  /** Bump when cache shape or city resolution strategy changes. */
16384
- const CACHE_KEY = 'africanies-header-weather-v7';
16385
- const FETCH_MS = 4_000;
16386
- const BROWSER_GEO_MS = 3_500;
16387
- /** IP fallback — city string is used only when reverse-geocode is empty. */
17555
+ const CACHE_KEY = 'africanies-header-weather-v8';
17556
+ const FETCH_MS = 8_000;
17557
+ /** After Allow, wait for a GPS/Wi-Fi fix. A short timeout loses the prompt and falls through to IP. */
17558
+ const DEVICE_GEO_MS = 15_000;
17559
+ const DEVICE_GEO_PROMPT_MS = 25_000;
17560
+ /** IP city is the office egress (often Lagos) and must not label the device. */
16388
17561
  const GEO_URL = 'https://get.geojs.io/v1/ip/geo.json';
16389
- /** Client reverse-geocode so the label matches the forecast coordinates. */
16390
- const REVERSE_GEO_URL = 'https://api.bigdatacloud.net/data/reverse-geocode-client';
17562
+ const REVERSE_GEO_URL = 'https://geocoding-api.open-meteo.com/v1/reverse';
16391
17563
  const WEATHER_LABELS = {
16392
17564
  clear: 'Clear',
16393
17565
  cloudy: 'Cloudy',
@@ -16457,15 +17629,16 @@ function headerWeatherIcon(kind, hour) {
16457
17629
  return 'cloud-o';
16458
17630
  }
16459
17631
  /**
16460
- * City-level forecast via browser / IP geolocation + Open-Meteo (no API key).
17632
+ * City-level forecast. The label is the device location only.
16461
17633
  *
16462
- * Coordinates prefer the browser Geolocation API (accurate for travellers;
16463
- * may prompt once). Otherwise IP geo is used. The city label is reverse-
16464
- * geocoded from those coordinates, with the IP city as a fallback.
17634
+ * The Geolocation API (GPS / nearby Wi-Fi) is reverse-geocoded. IP lookup is
17635
+ * not used for the city a shared office egress makes every colleague "Lagos".
17636
+ * If the device fix is refused, weather still loads from IP coordinates with
17637
+ * no city.
16465
17638
  *
16466
17639
  * Fails closed: missing browser APIs, timeouts, and HTTP errors all return
16467
- * `null` so the greeting can stay time-of-day only. Cached per local hour
16468
- * in `sessionStorage`.
17640
+ * `null` so the greeting can stay time-of-day only. A snapshot with a city
17641
+ * is cached per local hour in `sessionStorage`.
16469
17642
  *
16470
17643
  * @param fetchFn - Injected `fetch` for tests.
16471
17644
  * @returns Forecast snapshot, or `null` when lookup fails.
@@ -16481,7 +17654,8 @@ async function loadHeaderWeather(fetchFn) {
16481
17654
  return cached;
16482
17655
  }
16483
17656
  try {
16484
- const coords = await resolveCoordinates(run);
17657
+ const device = await tryDeviceCoordinates();
17658
+ const coords = device ?? (await ipCoordinates(run));
16485
17659
  if (!coords) {
16486
17660
  return null;
16487
17661
  }
@@ -16498,10 +17672,13 @@ async function loadHeaderWeather(fetchFn) {
16498
17672
  return null;
16499
17673
  }
16500
17674
  const temperatureC = asNumber(forecast?.current?.temperature_2m) ?? undefined;
16501
- const city = (await reverseGeocodeCity(run, coords.latitude, coords.longitude)) ??
16502
- coords.fallbackCity;
17675
+ const city = device
17676
+ ? await reverseGeocodeCity(run, device.latitude, device.longitude)
17677
+ : undefined;
16503
17678
  const weather = { kind, temperatureC, city };
16504
- writeCache({ hour, kind, temperatureC, city });
17679
+ if (city) {
17680
+ writeCache({ hour, kind, temperatureC, city });
17681
+ }
16505
17682
  return weather;
16506
17683
  }
16507
17684
  catch {
@@ -16548,41 +17725,27 @@ function writeCache(value) {
16548
17725
  // Private mode / quota — greeting still works without cache.
16549
17726
  }
16550
17727
  }
16551
- /**
16552
- * Prefer device coordinates when available (may prompt once); otherwise fall
16553
- * back to IP geo. IP is always fetched in parallel so its city can backfill
16554
- * the label when reverse-geocode is empty (browser geo has no city string).
16555
- */
16556
- async function resolveCoordinates(fetchFn) {
16557
- const [browser, ipGeo] = await Promise.all([
16558
- tryBrowserGeolocation(),
16559
- fetchIpGeo(fetchFn),
16560
- ]);
16561
- const ipCity = asCity(ipGeo?.city);
16562
- if (browser) {
16563
- return { ...browser, fallbackCity: ipCity };
16564
- }
16565
- const latitude = asNumber(ipGeo?.latitude);
16566
- const longitude = asNumber(ipGeo?.longitude);
17728
+ async function ipCoordinates(fetchFn) {
17729
+ const payload = (await fetchJson(fetchFn, GEO_URL));
17730
+ const latitude = asNumber(payload?.latitude);
17731
+ const longitude = asNumber(payload?.longitude);
16567
17732
  if (latitude === null || longitude === null) {
16568
17733
  return null;
16569
17734
  }
16570
- return {
16571
- latitude,
16572
- longitude,
16573
- fallbackCity: ipCity,
16574
- };
16575
- }
16576
- async function fetchIpGeo(fetchFn) {
16577
- return (await fetchJson(fetchFn, GEO_URL));
17735
+ return { latitude, longitude };
16578
17736
  }
16579
- async function tryBrowserGeolocation() {
17737
+ async function tryDeviceCoordinates() {
16580
17738
  if (typeof navigator === 'undefined' ||
16581
17739
  typeof navigator.geolocation?.getCurrentPosition !== 'function') {
16582
17740
  return null;
16583
17741
  }
17742
+ const permission = await geolocationPermission();
17743
+ if (permission === 'denied') {
17744
+ return null;
17745
+ }
17746
+ const timeout = permission === 'granted' ? DEVICE_GEO_MS : DEVICE_GEO_PROMPT_MS;
16584
17747
  return await new Promise((resolve) => {
16585
- const timer = setTimeout(() => resolve(null), BROWSER_GEO_MS);
17748
+ const timer = setTimeout(() => resolve(null), timeout);
16586
17749
  navigator.geolocation.getCurrentPosition((position) => {
16587
17750
  clearTimeout(timer);
16588
17751
  resolve({
@@ -16593,20 +17756,28 @@ async function tryBrowserGeolocation() {
16593
17756
  clearTimeout(timer);
16594
17757
  resolve(null);
16595
17758
  }, {
16596
- enableHighAccuracy: false,
16597
- maximumAge: 600_000,
16598
- timeout: BROWSER_GEO_MS,
17759
+ enableHighAccuracy: true,
17760
+ maximumAge: 0,
17761
+ timeout,
16599
17762
  });
16600
17763
  });
16601
17764
  }
17765
+ async function geolocationPermission() {
17766
+ try {
17767
+ const status = await navigator.permissions?.query({ name: 'geolocation' });
17768
+ return status?.state ?? 'unknown';
17769
+ }
17770
+ catch {
17771
+ return 'unknown';
17772
+ }
17773
+ }
16602
17774
  async function reverseGeocodeCity(fetchFn, latitude, longitude) {
16603
17775
  const url = `${REVERSE_GEO_URL}?latitude=${encodeURIComponent(String(latitude))}` +
16604
17776
  `&longitude=${encodeURIComponent(String(longitude))}` +
16605
- `&localityLanguage=en`;
17777
+ `&language=en&count=1`;
16606
17778
  const payload = (await fetchJson(fetchFn, url));
16607
- return (asCity(payload?.city) ??
16608
- asCity(payload?.locality) ??
16609
- asCity(payload?.principalSubdivision));
17779
+ const place = payload?.results?.[0];
17780
+ return asCity(place?.name) ?? asCity(place?.admin1);
16610
17781
  }
16611
17782
  function asNumber(value) {
16612
17783
  if (typeof value === 'number' && Number.isFinite(value)) {
@@ -16646,6 +17817,9 @@ async function fetchJson(fetchFn, url) {
16646
17817
  }
16647
17818
  }
16648
17819
 
17820
+ /**
17821
+ * Marks projected content as extra leading chrome in {@link AppShellHeaderComponent}.
17822
+ */
16649
17823
  /**
16650
17824
  * Marks projected content as extra leading chrome in {@link AppShellHeaderComponent}.
16651
17825
  */
@@ -16663,6 +17837,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
16663
17837
  /**
16664
17838
  * Marks projected content as extra trailing chrome in {@link AppShellHeaderComponent}.
16665
17839
  */
17840
+ /**
17841
+ * Marks projected content as extra trailing chrome in {@link AppShellHeaderComponent}.
17842
+ */
16666
17843
  class AppShellHeaderEndDirective {
16667
17844
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AppShellHeaderEndDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
16668
17845
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: AppShellHeaderEndDirective, isStandalone: true, selector: "[africaniesAppShellHeaderEnd]", ngImport: i0 });
@@ -16691,6 +17868,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
16691
17868
  * />
16692
17869
  * ```
16693
17870
  */
17871
+ /**
17872
+ * Product header bar for {@link AppShellComponent}: a short time-of-day kicker plus the given name, local weather, live clock, notification inbox drawer, and avatar menu. Breadcrumbs and Back belong in the content column via {@link AppShellContentHeaderComponent}.
17873
+ */
16694
17874
  class AppShellHeaderComponent {
16695
17875
  notificationsDrawer = inject(NotificationDrawerService);
16696
17876
  destroyRef = inject(DestroyRef);
@@ -17125,6 +18305,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
17125
18305
  *
17126
18306
  * When present, the built-in {@link AppShellHeaderComponent} is skipped.
17127
18307
  */
18308
+ /**
18309
+ * Marks projected content as the custom header for {@link AppShellComponent}.
18310
+ */
17128
18311
  class AppShellHeaderSlotDirective {
17129
18312
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AppShellHeaderSlotDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
17130
18313
  static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.0.8", type: AppShellHeaderSlotDirective, isStandalone: true, selector: "[africaniesAppShellHeader]", ngImport: i0 });
@@ -17166,6 +18349,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
17166
18349
  * </africanies-app-shell>
17167
18350
  * ```
17168
18351
  */
18352
+ /**
18353
+ * Application chrome scaffold: side nav + sticky header + constrained content.
18354
+ */
17169
18355
  class AppShellComponent {
17170
18356
  modeColor = inject(ModeColorService);
17171
18357
  logoMiniUrl = inject(AFRICANIES_BRAND_LOGO_MINI_URL);
@@ -17364,6 +18550,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
17364
18550
  * />
17365
18551
  * ```
17366
18552
  */
18553
+ /**
18554
+ * Image with a shaped loading frame and fallback while the asset fetches or if it fails to render.
18555
+ */
17367
18556
  class ImageComponent {
17368
18557
  imgRef = viewChild('img', /* @ts-ignore */
17369
18558
  ...(ngDevMode ? [{ debugName: "imgRef" }] : /* istanbul ignore next */ []));
@@ -17562,6 +18751,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
17562
18751
  * </ng-template>
17563
18752
  * ```
17564
18753
  */
18754
+ /**
18755
+ * Registers a projected cell template against a column key for {@link TableComponent}.
18756
+ */
17565
18757
  class CellDefDirective {
17566
18758
  /** Template projected into matching column body cells. */
17567
18759
  template = inject((TemplateRef));
@@ -17595,6 +18787,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
17595
18787
  * </ng-template>
17596
18788
  * ```
17597
18789
  */
18790
+ /**
18791
+ * Registers a projected header cell template against a column key for {@link TableComponent}.
18792
+ */
17598
18793
  class HeaderCellDefDirective {
17599
18794
  /** Template projected into the matching column header cell. */
17600
18795
  template = inject(TemplateRef);
@@ -17627,6 +18822,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
17627
18822
  * </ng-template>
17628
18823
  * ```
17629
18824
  */
18825
+ /**
18826
+ * Registers a label / value pair inside an expanded table row.
18827
+ */
17630
18828
  class RowDetailDefDirective {
17631
18829
  /** Template rendered as the detail value. */
17632
18830
  template = inject((TemplateRef));
@@ -17701,6 +18899,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
17701
18899
  *
17702
18900
  * Page controls for server-style lists (bind to {@link PaginationMetaModel}).
17703
18901
  */
18902
+ /**
18903
+ * Page-size select, numbered pager, and prev/next — driven by {@link PaginationMetaModel} from the API envelope.
18904
+ */
17704
18905
  class PaginationComponent {
17705
18906
  filterQuery = inject(FilterQueryService);
17706
18907
  modeColor = inject(ModeColorService);
@@ -18097,6 +19298,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
18097
19298
  * to the top of that scrollport. Mobile keeps horizontal-only overflow so
18098
19299
  * page scroll is unchanged.
18099
19300
  */
19301
+ /**
19302
+ * Presentational data table with template-based cells.
19303
+ */
18100
19304
  class TableComponent {
18101
19305
  destroyRef = inject(DestroyRef);
18102
19306
  shipping = inject(ShippingModeService);
@@ -19333,6 +20537,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
19333
20537
  * </ng-template>
19334
20538
  * ```
19335
20539
  */
20540
+ /**
20541
+ * Registers projected step body content against a step key for {@link StepperComponent}.
20542
+ */
19336
20543
  class StepDefDirective {
19337
20544
  /** Template projected as the active step body. */
19338
20545
  template = inject((TemplateRef));
@@ -19369,6 +20576,9 @@ function prefersReducedMotion() {
19369
20576
  * When `animateSteps` is true (default), the step body fades/slides via the
19370
20577
  * Web Animations API (skipped when the user prefers reduced motion).
19371
20578
  */
20579
+ /**
20580
+ * Multi-step wizard for form flows (e.g. shipment creation).
20581
+ */
19372
20582
  class StepperComponent {
19373
20583
  modeColor = inject(ModeColorService);
19374
20584
  steps = input.required(/* @ts-ignore */
@@ -19657,6 +20867,9 @@ const ACTIONS = [
19657
20867
  * export class ToolbarModule {}
19658
20868
  * ```
19659
20869
  */
20870
+ /**
20871
+ * Button, copy-to-clipboard control, overflow action menu, and avatar menu.
20872
+ */
19660
20873
  class AfricaniesActionsModule {
19661
20874
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesActionsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
19662
20875
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesActionsModule, imports: [ButtonComponent,
@@ -19706,6 +20919,9 @@ const FEEDBACK = [
19706
20919
  * export class ListPageModule {}
19707
20920
  * ```
19708
20921
  */
20922
+ /**
20923
+ * Async feedback states, accordion panels, inline alert, and status chips.
20924
+ */
19709
20925
  class AfricaniesFeedbackModule {
19710
20926
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesFeedbackModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
19711
20927
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesFeedbackModule, imports: [AccordionComponent,
@@ -19745,6 +20961,7 @@ const FORM_CONTROLS = [
19745
20961
  DatePickerComponent,
19746
20962
  FileUploadComponent,
19747
20963
  OtpInputComponent,
20964
+ PhoneInputComponent,
19748
20965
  ];
19749
20966
  /**
19750
20967
  * All form controls in one import for apps that prefer NgModules.
@@ -19759,6 +20976,9 @@ const FORM_CONTROLS = [
19759
20976
  * export class ShipmentFormsModule {}
19760
20977
  * ```
19761
20978
  */
20979
+ /**
20980
+ * All form controls in one import for apps that prefer NgModules.
20981
+ */
19762
20982
  class AfricaniesFormsModule {
19763
20983
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesFormsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
19764
20984
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesFormsModule, imports: [TextInputComponent,
@@ -19771,7 +20991,8 @@ class AfricaniesFormsModule {
19771
20991
  ToggleComponent,
19772
20992
  DatePickerComponent,
19773
20993
  FileUploadComponent,
19774
- OtpInputComponent], exports: [TextInputComponent,
20994
+ OtpInputComponent,
20995
+ PhoneInputComponent], exports: [TextInputComponent,
19775
20996
  TextareaComponent,
19776
20997
  NumberInputComponent,
19777
20998
  SelectComponent,
@@ -19781,12 +21002,14 @@ class AfricaniesFormsModule {
19781
21002
  ToggleComponent,
19782
21003
  DatePickerComponent,
19783
21004
  FileUploadComponent,
19784
- OtpInputComponent] });
21005
+ OtpInputComponent,
21006
+ PhoneInputComponent] });
19785
21007
  static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesFormsModule, imports: [SelectComponent,
19786
21008
  CheckboxComponent,
19787
21009
  ToggleComponent,
19788
21010
  FileUploadComponent,
19789
- OtpInputComponent] });
21011
+ OtpInputComponent,
21012
+ PhoneInputComponent] });
19790
21013
  }
19791
21014
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesFormsModule, decorators: [{
19792
21015
  type: NgModule,
@@ -19804,6 +21027,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
19804
21027
  * imports: [InfoPopoverComponent, InfoPopoverContentDirective, InfoPopoverTriggerDirective],
19805
21028
  * ```
19806
21029
  */
21030
+ /**
21031
+ * NgModule facade for {@link InfoPopoverComponent} and its trigger/content markers.
21032
+ */
19807
21033
  class AfricaniesInfoPopoverModule {
19808
21034
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesInfoPopoverModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
19809
21035
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesInfoPopoverModule, imports: [InfoPopoverComponent,
@@ -19857,6 +21083,9 @@ const NAV = [
19857
21083
  * export class ShellModule {}
19858
21084
  * ```
19859
21085
  */
21086
+ /**
21087
+ * App shell, breadcrumb, tabs (+ `africaniesTabDef`), segment, side nav, shipping mode switch, brand logo, avatar menu, and shell header chrome.
21088
+ */
19860
21089
  class AfricaniesNavigationModule {
19861
21090
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesNavigationModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
19862
21091
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesNavigationModule, imports: [AppShellComponent,
@@ -19915,6 +21144,9 @@ const STEPPER = [StepperComponent, StepDefDirective];
19915
21144
  * export class WizardModule {}
19916
21145
  * ```
19917
21146
  */
21147
+ /**
21148
+ * Stepper (+ `africaniesStepDef`).
21149
+ */
19918
21150
  class AfricaniesStepperModule {
19919
21151
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesStepperModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
19920
21152
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesStepperModule, imports: [StepperComponent, StepDefDirective], exports: [StepperComponent, StepDefDirective] });
@@ -19945,6 +21177,9 @@ const DATA = [
19945
21177
  * export class ShipmentsListModule {}
19946
21178
  * ```
19947
21179
  */
21180
+ /**
21181
+ * Table (+ `africaniesCellDef`) and pagination.
21182
+ */
19948
21183
  class AfricaniesTableModule {
19949
21184
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesTableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
19950
21185
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesTableModule, imports: [TableComponent,
@@ -19977,6 +21212,9 @@ const TOOLTIP = [TooltipComponent, TooltipTriggerDirective];
19977
21212
  * export class FormHintsModule {}
19978
21213
  * ```
19979
21214
  */
21215
+ /**
21216
+ * Tooltip (+ `africaniesTooltipTrigger`).
21217
+ */
19980
21218
  class AfricaniesTooltipModule {
19981
21219
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesTooltipModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
19982
21220
  static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "22.0.8", ngImport: i0, type: AfricaniesTooltipModule, imports: [TooltipComponent, TooltipTriggerDirective], exports: [TooltipComponent, TooltipTriggerDirective] });
@@ -20009,5 +21247,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
20009
21247
  * Generated bundle index. Do not edit.
20010
21248
  */
20011
21249
 
20012
- export { AFRICANIES_BRAND_LOGO_MINI_URL, AFRICANIES_BRAND_LOGO_URL, AccordionComponent, ActionMenuComponent, ActionMenuTriggerDirective, AddressInputComponent, AfricaniesActionsModule, AfricaniesFeedbackModule, AfricaniesFormsModule, AfricaniesInfoPopoverModule, AfricaniesNavigationModule, AfricaniesOverlayRef, AfricaniesStepperModule, AfricaniesTableModule, AfricaniesTooltipModule, AlertComponent, AppShellComponent, AppShellContentHeaderComponent, AppShellHeaderComponent, AppShellHeaderEndDirective, AppShellHeaderSlotDirective, AppShellHeaderStartDirective, AsyncStateComponent, AvatarComponent, AvatarMenuComponent, BrandLogoComponent, BreadcrumbComponent, ButtonComponent, CarrierLogoComponent, CellDefDirective, CheckboxComponent, ChipComponent, ConfirmDialogComponent, ConfirmService, ContentStackComponent, CopyButtonComponent, DatePickerComponent, DrawerService, EmptyStateComponent, ErrorIndicatorComponent, ErrorStateComponent, FileUploadComponent, FilterDrawerPanel, FilterDrawerService, FilterQueryService, GOOGLE_PLACES_CONFIG, GooglePlacesService, HeaderCellDefDirective, ImageComponent, InfoPopoverComponent, InfoPopoverContentDirective, InfoPopoverTriggerDirective, LoadingStateComponent, MODAL_SIZE_PANEL_CLASS, ModalService, NotificationDrawerPanel, NotificationDrawerService, NumberInputComponent, OVERLAY_DATA, OtpInputComponent, OverlayFooterDirective, OverlayFrameComponent, OverlayHeaderDirective, PageHeaderComponent, PaginationComponent, RadioComponent, RowDetailDefDirective, SearchComboboxComponent, SegmentComponent, SelectComponent, ShippingModeSwitchComponent, SideNavComponent, StepDefDirective, StepperComponent, TOAST_DURATION_MS, TOAST_ICONS, TabDefDirective, TableComponent, TabsComponent, TextInputComponent, TextareaComponent, ToastService, ToggleComponent, TooltipComponent, TooltipTriggerDirective, acceptLabels, buildBreadcrumbsFromSideNav, deliveryVendorOptionsForStoredValue, deliveryVendorSelectOptions, deliveryVendorSelected, fileExtensionLabel, fileMatchesAccept, headerGreetingFirstName, headerGreetingPeriod, isCatalogRootRoute, isNavItemActive, isNestedChildRoute, navItemUrlTree, normalizeCarrierLogoSlug, normalizeNavPath, pickHeaderGreeting, provideAfricaniesToasts, provideAfricaniesUiOverlays, provideGooglePlaces, resolveCatalogRootLink, resolveContentBackTarget, resolveHeaderBackTarget, resolveParentPathFromRootSnapshot, toastFingerprint };
21250
+ export { AFRICANIES_BRAND_LOGO_MINI_URL, AFRICANIES_BRAND_LOGO_URL, AccordionComponent, ActionMenuComponent, ActionMenuTriggerDirective, AddressInputComponent, AfricaniesActionsModule, AfricaniesFeedbackModule, AfricaniesFormsModule, AfricaniesInfoPopoverModule, AfricaniesNavigationModule, AfricaniesOverlayRef, AfricaniesStepperModule, AfricaniesTableModule, AfricaniesTooltipModule, AlertComponent, AppShellComponent, AppShellContentHeaderComponent, AppShellHeaderComponent, AppShellHeaderEndDirective, AppShellHeaderSlotDirective, AppShellHeaderStartDirective, AsyncStateComponent, AvatarComponent, AvatarMenuComponent, BrandLogoComponent, BreadcrumbComponent, ButtonComponent, CarrierLogoComponent, CellDefDirective, CheckboxComponent, ChipComponent, ConfirmDialogComponent, ConfirmService, ContentStackComponent, CopyButtonComponent, DatePickerComponent, DrawerService, EmptyStateComponent, ErrorIndicatorComponent, ErrorStateComponent, FileUploadComponent, FilterDrawerPanel, FilterDrawerService, FilterQueryService, GOOGLE_PLACES_CONFIG, GooglePlacesService, HeaderCellDefDirective, ImageComponent, InfoPopoverComponent, InfoPopoverContentDirective, InfoPopoverTriggerDirective, LoadingStateComponent, MODAL_SIZE_PANEL_CLASS, ModalService, NotificationDrawerPanel, NotificationDrawerService, NumberInputComponent, OVERLAY_DATA, OtpInputComponent, OverlayFooterDirective, OverlayFrameComponent, OverlayHeaderDirective, PHONE_DIAL_CODES, PHONE_MAX_NATIONAL_DIGITS, PHONE_MIN_NATIONAL_DIGITS, PageHeaderComponent, PaginationComponent, PhoneInputComponent, RadioComponent, RowDetailDefDirective, SearchComboboxComponent, SegmentComponent, SelectComponent, ShippingModeSwitchComponent, SideNavComponent, StepDefDirective, StepperComponent, TOAST_DURATION_MS, TOAST_ICONS, TabDefDirective, TableComponent, TabsComponent, TextInputComponent, TextareaComponent, ToastService, ToggleComponent, TooltipComponent, TooltipTriggerDirective, acceptLabels, buildBreadcrumbsFromSideNav, buildPhoneNumberValue, deliveryVendorOptionsForStoredValue, deliveryVendorSelectOptions, deliveryVendorSelected, dialCodeForIso2, fileExtensionLabel, fileMatchesAccept, formatNationalDigits, headerGreetingFirstName, headerGreetingPeriod, isCatalogRootRoute, isNavItemActive, isNestedChildRoute, isPhoneNumberComplete, matchDialCode, navItemUrlTree, normalizeCarrierLogoSlug, normalizeNavPath, normalizePhoneIso2, parsePhoneControlValue, phoneCountryName, phoneCountryOptions, phoneDigitsOnly, phoneToE164, pickHeaderGreeting, provideAfricaniesToasts, provideAfricaniesUiOverlays, provideGooglePlaces, removeDialCode, resolveCatalogRootLink, resolveContentBackTarget, resolveHeaderBackTarget, resolveParentPathFromRootSnapshot, toastFingerprint };
20013
21251
  //# sourceMappingURL=africanies-africanies-ui.mjs.map