@stackcraftmx/calcita 0.23.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (359) hide show
  1. package/README.md +111 -22
  2. package/cli/projectFiles.js +5 -3
  3. package/cli/templates/project/README.md.tpl +28 -0
  4. package/cli/templates/project/public/manifest.webmanifest.tpl +6 -6
  5. package/cli/templates/project/src/app/AppProviders.jsx.tpl +9 -4
  6. package/cli/templates/project/src/app/appRouter.jsx.tpl +4 -2
  7. package/cli/templates/project/src/app/appSettings.js.tpl +14 -0
  8. package/cli/templates/project/src/core/AppLogo.jsx.tpl +3 -1
  9. package/cli/templates/project/src/core/index.js.tpl +1 -0
  10. package/cli/templates/project/src/core/publicPaths.js.tpl +24 -0
  11. package/cli/templates/project/vite.config.js.tpl +27 -1
  12. package/dist/DataTable/AuditTrailTable.js +5 -3
  13. package/dist/DataTable/AuditTrailTable.js.map +1 -1
  14. package/dist/DataTable/ColumnFilters/MultiSelectColumnFilter.js +2 -1
  15. package/dist/DataTable/ColumnFilters/MultiSelectColumnFilter.js.map +1 -1
  16. package/dist/DataTable/EmptyState.js +2 -2
  17. package/dist/DataTable/EmptyState.js.map +1 -1
  18. package/dist/DataTable/FilterChips.js +2 -2
  19. package/dist/DataTable/FilterChips.js.map +1 -1
  20. package/dist/DataTable/GoToPage.js +4 -3
  21. package/dist/DataTable/GoToPage.js.map +1 -1
  22. package/dist/DataTable/ServerTable.js +153 -83
  23. package/dist/DataTable/ServerTable.js.map +1 -1
  24. package/dist/DataTable/rowSelection.js +61 -0
  25. package/dist/DataTable/rowSelection.js.map +1 -0
  26. package/dist/access/PermissionMatrix.js +3 -2
  27. package/dist/access/PermissionMatrix.js.map +1 -1
  28. package/dist/account/AccountSecuritySection.js +2 -2
  29. package/dist/account/AccountSecuritySection.js.map +1 -1
  30. package/dist/account/ForgotPasswordScreen.js +5 -4
  31. package/dist/account/ForgotPasswordScreen.js.map +1 -1
  32. package/dist/account/ProfileScreen.js +39 -13
  33. package/dist/account/ProfileScreen.js.map +1 -1
  34. package/dist/account/ResetPasswordScreen.js +3 -2
  35. package/dist/account/ResetPasswordScreen.js.map +1 -1
  36. package/dist/account/SignInScreen.js +7 -6
  37. package/dist/account/SignInScreen.js.map +1 -1
  38. package/dist/account/accountConnector.js.map +1 -1
  39. package/dist/account/restAccountConnector.js +2 -1
  40. package/dist/account/restAccountConnector.js.map +1 -1
  41. package/dist/adapters/reactRouterRoutes.js +7 -6
  42. package/dist/adapters/reactRouterRoutes.js.map +1 -1
  43. package/dist/api/createApiClient.js +35 -5
  44. package/dist/api/createApiClient.js.map +1 -1
  45. package/dist/appShell/AppLayout.js +27 -7
  46. package/dist/appShell/AppLayout.js.map +1 -1
  47. package/dist/appShell/AppearanceSettings.js +29 -6
  48. package/dist/appShell/AppearanceSettings.js.map +1 -1
  49. package/dist/appShell/AuthLayout.js +2 -0
  50. package/dist/appShell/AuthLayout.js.map +1 -1
  51. package/dist/appShell/BarActionButton.js +3 -3
  52. package/dist/appShell/BarActionButton.js.map +1 -1
  53. package/dist/appShell/BarActions.js +19 -8
  54. package/dist/appShell/BarActions.js.map +1 -1
  55. package/dist/appShell/BarCapsule.js +19 -4
  56. package/dist/appShell/BarCapsule.js.map +1 -1
  57. package/dist/appShell/BarSearch.js +92 -0
  58. package/dist/appShell/BarSearch.js.map +1 -0
  59. package/dist/appShell/MobileTabBar.js +3 -1
  60. package/dist/appShell/MobileTabBar.js.map +1 -1
  61. package/dist/appShell/shellSizes.js +2 -0
  62. package/dist/appShell/shellSizes.js.map +1 -1
  63. package/dist/auth/PasswordChecklist.js +2 -2
  64. package/dist/auth/PasswordChecklist.js.map +1 -1
  65. package/dist/calendar/EventCalendar.js +16 -5
  66. package/dist/calendar/EventCalendar.js.map +1 -1
  67. package/dist/calendar/EventDetails.js +74 -0
  68. package/dist/calendar/EventDetails.js.map +1 -0
  69. package/dist/calendar/calendarEvents.js +31 -0
  70. package/dist/calendar/calendarEvents.js.map +1 -0
  71. package/dist/calendar.js +8 -1
  72. package/dist/calendar.js.map +1 -1
  73. package/dist/charts.js +10 -1
  74. package/dist/charts.js.map +1 -1
  75. package/dist/datePickers/DateInput.js +3 -2
  76. package/dist/datePickers/DateInput.js.map +1 -1
  77. package/dist/downloads/DownloadManager.js +14 -20
  78. package/dist/downloads/DownloadManager.js.map +1 -1
  79. package/dist/downloads/downloadQueue.js +4 -2
  80. package/dist/downloads/downloadQueue.js.map +1 -1
  81. package/dist/downloads/downloadsMachine.js +4 -1
  82. package/dist/downloads/downloadsMachine.js.map +1 -1
  83. package/dist/downloads/fileTypes.js +22 -0
  84. package/dist/downloads/fileTypes.js.map +1 -0
  85. package/dist/feedback/ConfirmDialog.js +3 -2
  86. package/dist/feedback/ConfirmDialog.js.map +1 -1
  87. package/dist/feedback/ModalWaiting.js +2 -2
  88. package/dist/feedback/ModalWaiting.js.map +1 -1
  89. package/dist/feedback/NewBuildNotice.js +2 -2
  90. package/dist/feedback/NewBuildNotice.js.map +1 -1
  91. package/dist/filepond/FileDropzone.js +5 -3
  92. package/dist/filepond/FileDropzone.js.map +1 -1
  93. package/dist/formatting.js +171 -143
  94. package/dist/formatting.js.map +1 -1
  95. package/dist/forms/FormWizard.js +18 -45
  96. package/dist/forms/FormWizard.js.map +1 -1
  97. package/dist/forms/auth/ChangePasswordForm.js +5 -4
  98. package/dist/forms/auth/ChangePasswordForm.js.map +1 -1
  99. package/dist/forms/auth/ForgotPasswordForm.js +2 -2
  100. package/dist/forms/auth/ForgotPasswordForm.js.map +1 -1
  101. package/dist/forms/auth/SignInForm.js +2 -2
  102. package/dist/forms/auth/SignInForm.js.map +1 -1
  103. package/dist/forms/security/SecondStepForm.js +2 -2
  104. package/dist/forms/security/SecondStepForm.js.map +1 -1
  105. package/dist/forms/security/TwoStepVerificationCard.js +8 -6
  106. package/dist/forms/security/TwoStepVerificationCard.js.map +1 -1
  107. package/dist/hookForm/FormWizard.js +59 -0
  108. package/dist/hookForm/FormWizard.js.map +1 -0
  109. package/dist/inbox/InboxLayout.js +44 -8
  110. package/dist/inbox/InboxLayout.js.map +1 -1
  111. package/dist/inbox/MessageList.js +71 -21
  112. package/dist/inbox/MessageList.js.map +1 -1
  113. package/dist/inbox/MessageView.js +80 -29
  114. package/dist/inbox/MessageView.js.map +1 -1
  115. package/dist/inbox/inboxDates.js +4 -3
  116. package/dist/inbox/inboxDates.js.map +1 -1
  117. package/dist/index.js +157 -133
  118. package/dist/index.js.map +1 -1
  119. package/dist/inputs/CatalogInput.js +8 -4
  120. package/dist/inputs/CatalogInput.js.map +1 -1
  121. package/dist/inputs/ColorInput.js +3 -2
  122. package/dist/inputs/ColorInput.js.map +1 -1
  123. package/dist/inputs/FormSection.js +3 -3
  124. package/dist/inputs/FormSection.js.map +1 -1
  125. package/dist/inputs/NumberInput.js +3 -2
  126. package/dist/inputs/NumberInput.js.map +1 -1
  127. package/dist/inputs/SelectInput.js +29 -11
  128. package/dist/inputs/SelectInput.js.map +1 -1
  129. package/dist/inputs/TextInput.js +6 -2
  130. package/dist/inputs/TextInput.js.map +1 -1
  131. package/dist/inputs/WizardLayout.js +54 -0
  132. package/dist/inputs/WizardLayout.js.map +1 -0
  133. package/dist/kanban/KanbanBoard.js +239 -14
  134. package/dist/kanban/KanbanBoard.js.map +1 -1
  135. package/dist/kanban/kanbanCards.js +19 -0
  136. package/dist/kanban/kanbanCards.js.map +1 -0
  137. package/dist/kanban.js +7 -1
  138. package/dist/kanban.js.map +1 -1
  139. package/dist/locales/en.js +74 -1
  140. package/dist/locales/en.js.map +1 -1
  141. package/dist/locales/es.js +74 -1
  142. package/dist/locales/es.js.map +1 -1
  143. package/dist/maps/MapView.js +28 -8
  144. package/dist/maps/MapView.js.map +1 -1
  145. package/dist/observability/usePublishedBuildWatch.js +4 -3
  146. package/dist/observability/usePublishedBuildWatch.js.map +1 -1
  147. package/dist/pwa/InstallAppSetting.js +6 -5
  148. package/dist/pwa/InstallAppSetting.js.map +1 -1
  149. package/dist/pwa/InstallInstructionsDialog.js +2 -2
  150. package/dist/pwa/InstallInstructionsDialog.js.map +1 -1
  151. package/dist/pwa/InstallPromptBanner.js +15 -9
  152. package/dist/pwa/InstallPromptBanner.js.map +1 -1
  153. package/dist/pwa/useInstallPrompt.js +2 -1
  154. package/dist/pwa/useInstallPrompt.js.map +1 -1
  155. package/dist/react-hook-form.js +6 -4
  156. package/dist/react-hook-form.js.map +1 -1
  157. package/dist/security/ActivityLog.js +4 -3
  158. package/dist/security/ActivityLog.js.map +1 -1
  159. package/dist/security/RecoveryCodesDialog.js +4 -3
  160. package/dist/security/RecoveryCodesDialog.js.map +1 -1
  161. package/dist/security/SessionsCard.js +8 -6
  162. package/dist/security/SessionsCard.js.map +1 -1
  163. package/dist/table.js +2 -0
  164. package/dist/table.js.map +1 -1
  165. package/dist/theme/components/MuiDialog.js +13 -0
  166. package/dist/theme/components/MuiDialog.js.map +1 -0
  167. package/dist/theme/createToolkitTheme.js.map +1 -1
  168. package/dist/theme/toolkitComponents.js +2 -0
  169. package/dist/theme/toolkitComponents.js.map +1 -1
  170. package/dist/toolkit/ComponentTexts.js +13 -0
  171. package/dist/toolkit/ComponentTexts.js.map +1 -0
  172. package/dist/toolkit/ToolkitProvider.js +36 -28
  173. package/dist/toolkit/ToolkitProvider.js.map +1 -1
  174. package/dist/toolkit/browserNavigation.js +19 -20
  175. package/dist/toolkit/browserNavigation.js.map +1 -1
  176. package/dist/toolkit/componentTextsContext.js +15 -0
  177. package/dist/toolkit/componentTextsContext.js.map +1 -0
  178. package/dist/toolkit/hashNavigation.js +40 -0
  179. package/dist/toolkit/hashNavigation.js.map +1 -0
  180. package/dist/toolkit/navigationPaths.js +49 -0
  181. package/dist/toolkit/navigationPaths.js.map +1 -0
  182. package/dist/toolkit/toolkitSettings.js +24 -4
  183. package/dist/toolkit/toolkitSettings.js.map +1 -1
  184. package/dist/toolkit/useFormatters.js +12 -0
  185. package/dist/toolkit/useFormatters.js.map +1 -0
  186. package/dist/toolkit/useToolkitTranslation.js +11 -7
  187. package/dist/toolkit/useToolkitTranslation.js.map +1 -1
  188. package/dist/types/DataTable/AuditTrailTable.d.ts +3 -1
  189. package/dist/types/DataTable/EmptyState.d.ts +7 -2
  190. package/dist/types/DataTable/FilterChips.d.ts +3 -1
  191. package/dist/types/DataTable/GoToPage.d.ts +7 -2
  192. package/dist/types/DataTable/SelectionBar.d.ts +32 -0
  193. package/dist/types/DataTable/ServerTable.d.ts +64 -3
  194. package/dist/types/DataTable/index.d.ts +1 -1
  195. package/dist/types/DataTable/rowSelection.d.ts +113 -0
  196. package/dist/types/access/PermissionMatrix.d.ts +3 -1
  197. package/dist/types/account/AccountSecuritySection.d.ts +3 -1
  198. package/dist/types/account/ForgotPasswordScreen.d.ts +3 -1
  199. package/dist/types/account/ProfileScreen.d.ts +31 -1
  200. package/dist/types/account/ResetPasswordScreen.d.ts +3 -1
  201. package/dist/types/account/SignInScreen.d.ts +3 -1
  202. package/dist/types/account/accountConnector.d.ts +7 -2
  203. package/dist/types/adapters/reactRouterRoutes.d.ts +14 -2
  204. package/dist/types/api/createApiClient.d.ts +29 -1
  205. package/dist/types/appShell/AppLayout.d.ts +11 -1
  206. package/dist/types/appShell/AppearanceSettings.d.ts +8 -1
  207. package/dist/types/appShell/BarActionButton.d.ts +2 -2
  208. package/dist/types/appShell/BarActions.d.ts +6 -1
  209. package/dist/types/appShell/BarCapsule.d.ts +8 -0
  210. package/dist/types/appShell/BarSearch.d.ts +24 -0
  211. package/dist/types/appShell/MobileTabBar.d.ts +4 -1
  212. package/dist/types/appShell/shellSizes.d.ts +1 -0
  213. package/dist/types/auth/PasswordChecklist.d.ts +3 -1
  214. package/dist/types/calendar/EventCalendar.d.ts +18 -1
  215. package/dist/types/calendar/EventDetails.d.ts +36 -0
  216. package/dist/types/calendar/calendarEvents.d.ts +27 -0
  217. package/dist/types/calendar.d.ts +2 -0
  218. package/dist/types/charts.d.ts +4 -0
  219. package/dist/types/datePickers/DateInput.d.ts +3 -1
  220. package/dist/types/downloads/DownloadManager.d.ts +7 -1
  221. package/dist/types/downloads/downloadQueue.d.ts +8 -3
  222. package/dist/types/downloads/fileTypes.d.ts +39 -0
  223. package/dist/types/downloads/index.d.ts +1 -0
  224. package/dist/types/feedback/ConfirmDialog.d.ts +3 -1
  225. package/dist/types/feedback/ModalWaiting.d.ts +7 -2
  226. package/dist/types/feedback/NewBuildNotice.d.ts +3 -1
  227. package/dist/types/filepond/FileDropzone.d.ts +3 -1
  228. package/dist/types/formatting.d.ts +45 -90
  229. package/dist/types/forms/FormWizard.d.ts +3 -1
  230. package/dist/types/forms/auth/ChangePasswordForm.d.ts +3 -1
  231. package/dist/types/forms/auth/ForgotPasswordForm.d.ts +3 -1
  232. package/dist/types/forms/auth/SignInForm.d.ts +3 -1
  233. package/dist/types/forms/security/SecondStepForm.d.ts +3 -1
  234. package/dist/types/forms/security/TwoStepVerificationCard.d.ts +3 -1
  235. package/dist/types/hookForm/FormWizard.d.ts +22 -0
  236. package/dist/types/inbox/InboxLayout.d.ts +14 -2
  237. package/dist/types/inbox/MessageList.d.ts +30 -5
  238. package/dist/types/inbox/MessageView.d.ts +35 -3
  239. package/dist/types/inbox/inboxDates.d.ts +6 -1
  240. package/dist/types/index.d.ts +12 -5
  241. package/dist/types/inputs/CatalogInput.d.ts +9 -5
  242. package/dist/types/inputs/ColorInput.d.ts +3 -1
  243. package/dist/types/inputs/FormSection.d.ts +2 -2
  244. package/dist/types/inputs/NumberInput.d.ts +3 -1
  245. package/dist/types/inputs/SelectInput.d.ts +9 -5
  246. package/dist/types/inputs/TextInput.d.ts +3 -1
  247. package/dist/types/inputs/WizardLayout.d.ts +34 -0
  248. package/dist/types/kanban/KanbanBoard.d.ts +61 -6
  249. package/dist/types/kanban/kanbanCards.d.ts +22 -0
  250. package/dist/types/kanban.d.ts +1 -0
  251. package/dist/types/locales/en.d.ts +77 -0
  252. package/dist/types/locales/es.d.ts +77 -0
  253. package/dist/types/maps/MapView.d.ts +12 -3
  254. package/dist/types/observability/usePublishedBuildWatch.d.ts +3 -1
  255. package/dist/types/pwa/InstallAppSetting.d.ts +7 -1
  256. package/dist/types/pwa/InstallInstructionsDialog.d.ts +3 -1
  257. package/dist/types/pwa/InstallPromptBanner.d.ts +10 -1
  258. package/dist/types/pwa/useInstallPrompt.d.ts +3 -2
  259. package/dist/types/react-hook-form.d.ts +1 -0
  260. package/dist/types/security/ActivityLog.d.ts +3 -1
  261. package/dist/types/security/RecoveryCodesDialog.d.ts +6 -1
  262. package/dist/types/security/SessionsCard.d.ts +3 -1
  263. package/dist/types/table.d.ts +3 -1
  264. package/dist/types/theme/components/MuiDialog.d.ts +9 -0
  265. package/dist/types/toolkit/ComponentTexts.d.ts +11 -0
  266. package/dist/types/toolkit/ToolkitProvider.d.ts +18 -2
  267. package/dist/types/toolkit/browserNavigation.d.ts +23 -28
  268. package/dist/types/toolkit/componentTextsContext.d.ts +20 -0
  269. package/dist/types/toolkit/hashNavigation.d.ts +12 -0
  270. package/dist/types/toolkit/navigationPaths.d.ts +43 -0
  271. package/dist/types/toolkit/toolkitSettings.d.ts +49 -4
  272. package/dist/types/toolkit/useFormatters.d.ts +6 -0
  273. package/dist/types/toolkit/useToolkitTranslation.d.ts +2 -1
  274. package/dist/types/ui/actions/ActionsMenu.d.ts +20 -0
  275. package/dist/types/ui/actions/CopyButton.d.ts +3 -1
  276. package/dist/types/ui/actions/DownloadMenu.d.ts +8 -3
  277. package/dist/types/ui/actions/SecretField.d.ts +5 -1
  278. package/dist/types/ui/actions/SelectionActions.d.ts +39 -0
  279. package/dist/types/ui/filters/DateRangeFilter.d.ts +3 -1
  280. package/dist/types/ui/filters/QuickFilters.d.ts +3 -1
  281. package/dist/types/ui/index.d.ts +1 -1
  282. package/dist/types/ui/labels/tagOf.d.ts +13 -0
  283. package/dist/types/ui/layout/CollapsibleSection.d.ts +4 -1
  284. package/dist/types/ui/layout/ContentDialog.d.ts +3 -1
  285. package/dist/types/ui/layout/ErrorPage.d.ts +14 -1
  286. package/dist/types/ui/layout/FullPageLoader.d.ts +7 -1
  287. package/dist/types/ui/layout/PageHeading.d.ts +3 -1
  288. package/dist/types/ui/metrics/BarList.d.ts +7 -1
  289. package/dist/types/ui/metrics/CalendarHeatmap.d.ts +7 -1
  290. package/dist/types/ui/metrics/ChartTooltip.d.ts +9 -3
  291. package/dist/types/ui/metrics/ColumnChart.d.ts +23 -11
  292. package/dist/types/ui/metrics/LineChart.d.ts +41 -0
  293. package/dist/types/ui/metrics/MetricCard.d.ts +9 -1
  294. package/dist/types/ui/metrics/TableToggle.d.ts +9 -2
  295. package/dist/types/ui/metrics/chartParts.d.ts +112 -0
  296. package/dist/types/ui/navigation/BackButton.d.ts +3 -1
  297. package/dist/types/ui/navigation/ColorSchemeToggle.d.ts +8 -2
  298. package/dist/types/ui/navigation/FontSizeToggle.d.ts +7 -2
  299. package/dist/types/ui/navigation/LanguageToggle.d.ts +8 -3
  300. package/dist/types/ui/navigation/PageBreadcrumbs.d.ts +5 -2
  301. package/dist/types/ui/timeline/GroupedTimeline.d.ts +4 -1
  302. package/dist/types/upload/FileDropzone.d.ts +3 -1
  303. package/dist/ui/actions/ActionsMenu.js +51 -0
  304. package/dist/ui/actions/ActionsMenu.js.map +1 -0
  305. package/dist/ui/actions/CopyButton.js +2 -2
  306. package/dist/ui/actions/CopyButton.js.map +1 -1
  307. package/dist/ui/actions/DownloadMenu.js +11 -12
  308. package/dist/ui/actions/DownloadMenu.js.map +1 -1
  309. package/dist/ui/actions/SecretField.js +8 -4
  310. package/dist/ui/actions/SecretField.js.map +1 -1
  311. package/dist/ui/actions/SelectionActions.js +142 -0
  312. package/dist/ui/actions/SelectionActions.js.map +1 -0
  313. package/dist/ui/filters/DateRangeFilter.js +4 -3
  314. package/dist/ui/filters/DateRangeFilter.js.map +1 -1
  315. package/dist/ui/filters/QuickFilters.js +2 -2
  316. package/dist/ui/filters/QuickFilters.js.map +1 -1
  317. package/dist/ui/labels/tagOf.js +7 -0
  318. package/dist/ui/labels/tagOf.js.map +1 -0
  319. package/dist/ui/layout/CollapsibleSection.js +6 -2
  320. package/dist/ui/layout/CollapsibleSection.js.map +1 -1
  321. package/dist/ui/layout/ContentDialog.js +2 -2
  322. package/dist/ui/layout/ContentDialog.js.map +1 -1
  323. package/dist/ui/layout/ErrorPage.js +21 -7
  324. package/dist/ui/layout/ErrorPage.js.map +1 -1
  325. package/dist/ui/layout/FullPageLoader.js +2 -2
  326. package/dist/ui/layout/FullPageLoader.js.map +1 -1
  327. package/dist/ui/layout/PageHeading.js +2 -2
  328. package/dist/ui/layout/PageHeading.js.map +1 -1
  329. package/dist/ui/metrics/BarList.js +18 -13
  330. package/dist/ui/metrics/BarList.js.map +1 -1
  331. package/dist/ui/metrics/CalendarHeatmap.js +11 -6
  332. package/dist/ui/metrics/CalendarHeatmap.js.map +1 -1
  333. package/dist/ui/metrics/ChartTooltip.js +1 -1
  334. package/dist/ui/metrics/ChartTooltip.js.map +1 -1
  335. package/dist/ui/metrics/ColumnChart.js +59 -63
  336. package/dist/ui/metrics/ColumnChart.js.map +1 -1
  337. package/dist/ui/metrics/LineChart.js +117 -0
  338. package/dist/ui/metrics/LineChart.js.map +1 -0
  339. package/dist/ui/metrics/MetricCard.js +41 -8
  340. package/dist/ui/metrics/MetricCard.js.map +1 -1
  341. package/dist/ui/metrics/TableToggle.js +4 -2
  342. package/dist/ui/metrics/TableToggle.js.map +1 -1
  343. package/dist/ui/metrics/chartParts.js +93 -0
  344. package/dist/ui/metrics/chartParts.js.map +1 -0
  345. package/dist/ui/navigation/BackButton.js +2 -2
  346. package/dist/ui/navigation/BackButton.js.map +1 -1
  347. package/dist/ui/navigation/ColorSchemeToggle.js +6 -3
  348. package/dist/ui/navigation/ColorSchemeToggle.js.map +1 -1
  349. package/dist/ui/navigation/FontSizeToggle.js +3 -2
  350. package/dist/ui/navigation/FontSizeToggle.js.map +1 -1
  351. package/dist/ui/navigation/LanguageToggle.js +40 -19
  352. package/dist/ui/navigation/LanguageToggle.js.map +1 -1
  353. package/dist/ui/navigation/PageBreadcrumbs.js +2 -2
  354. package/dist/ui/navigation/PageBreadcrumbs.js.map +1 -1
  355. package/dist/ui/timeline/GroupedTimeline.js +10 -8
  356. package/dist/ui/timeline/GroupedTimeline.js.map +1 -1
  357. package/dist/upload/FileDropzone.js +5 -3
  358. package/dist/upload/FileDropzone.js.map +1 -1
  359. package/package.json +14 -6
@@ -1 +1 @@
1
- {"version":3,"file":"es.js","sources":["../../src/locales/es.js"],"sourcesContent":["// Textos del paquete en español (el idioma por omisión). Cada proyecto puede cambiar cualquiera con `texts` o `translate`\n// de ToolkitProvider, con la misma forma: namespace, llaves anidadas, {{variable}} y plurales _one / _other.\nexport default Object.freeze({\n \"table\": {\n \"search\": {\n \"placeholder\": \"Buscar dentro de estos resultados…\"\n },\n \"count\": {\n \"records_one\": \"{{total}} registro\",\n \"records_other\": \"{{total}} registros\",\n \"capped\": \"más de {{total}} registros\",\n \"cappedTag\": \"total aproximado\",\n \"cappedTooltip\": \"Hay al menos estos registros y puede haber más: agregue un filtro para verlos todos.\"\n },\n \"empty\": {\n \"default\": \"Sin registros\",\n \"filtered\": \"Ningún registro cumple con los filtros aplicados.\",\n \"clearFilters\": \"Quitar los filtros\"\n },\n \"chips\": {\n \"applied_one\": \"{{count}} filtro aplicado\",\n \"applied_other\": \"{{count}} filtros aplicados\",\n \"clearAll\": \"Limpiar todo\"\n },\n \"columnFilter\": {\n \"tooltip\": \"Filtrar (se aplica a todos los registros, no solo a esta página)\",\n \"activeTooltip_one\": \"{{count}} filtro en esta columna\",\n \"activeTooltip_other\": \"{{count}} filtros en esta columna\",\n \"clear\": \"Limpiar esta columna\",\n \"contains\": \"Contiene\"\n },\n \"options\": {\n \"searchPlaceholder\": \"Buscar opción…\",\n \"empty\": \"Sin valores en este resultado\",\n \"noMatch\": \"Ninguna opción coincide con “{{text}}”\"\n },\n \"sort\": {\n \"tooltip\": \"Ordenar por esta columna\",\n \"ascending\": \"orden ascendente\",\n \"descending\": \"orden descendente\",\n \"clear\": \"Quitar el orden\"\n },\n \"goToPage\": {\n \"page\": \"Página\",\n \"of_one\": \"de {{total}}\",\n \"of_other\": \"de {{total}}\",\n \"ariaLabel\": \"Ir a la página\"\n },\n \"quickFilters\": {\n \"all\": \"Todos\",\n \"countAriaLabel\": \"{{count}} registros\"\n },\n \"detail\": {\n \"tooltip\": \"Ver detalle\",\n \"ariaLabel\": \"Ver el detalle de este registro\"\n },\n \"error\": {\n \"generic\": \"No pudimos consultar la tabla.\"\n },\n \"dateRange\": {\n \"label\": \"Personalizado\",\n \"title\": \"Rango de fechas\",\n \"from\": \"Desde\",\n \"to\": \"Hasta\",\n \"fromHelp\": \"Desde el inicio de ese día\",\n \"toHelp\": \"Hasta el final de ese día\",\n \"invalid\": \"«Hasta» no puede ser antes de «Desde»\",\n \"summary\": \"{{from}} – {{to}}\",\n \"today\": \"hoy\",\n \"clear\": \"Quitar\",\n \"apply\": \"Aplicar\"\n },\n \"audit\": {\n \"columns\": {\n \"occurredAt\": \"Fecha y hora\",\n \"event\": \"Qué pasó\",\n \"result\": \"Resultado\",\n \"actor\": \"Quién\"\n },\n \"systemActor\": \"Proceso automático\",\n \"eventFilterCaption\": \"Filtrar por evento\",\n \"count_one\": \"{{count}} evento\",\n \"count_other\": \"{{count}} eventos\",\n \"empty\": \"Todavía no hay eventos registrados.\"\n }\n },\n \"common\": {\n \"actions\": {\n \"cancel\": \"Cancelar\",\n \"confirm\": \"Confirmar\",\n \"retry\": \"Intentar de nuevo\",\n \"download\": \"Descargar\",\n \"close\": \"Cerrar\",\n \"back\": \"Regresar\",\n \"reload\": \"Recargar la página\"\n },\n \"status\": {\n \"loading\": \"Cargando…\",\n \"noData\": \"Sin datos\"\n },\n \"form\": {\n \"showPassword\": \"Mostrar contraseña\",\n \"hidePassword\": \"Ocultar contraseña\",\n \"clear\": \"Borrar el texto\",\n \"selectPlaceholder\": \"Elija una opción\",\n \"copy\": \"Copiar\",\n \"copied\": \"Copiado\",\n \"noOptions\": \"Ninguna opción coincide\",\n \"loadingOptions\": \"Cargando opciones…\",\n \"pickColor\": \"Elegir el color\",\n \"colorContrast\": \"Contraste sobre blanco: {{ratio}}:1\",\n \"colorLowContrast\": \"Con ese color el texto casi no se leería sobre blanco. {{suggestion}} es el mismo tono, más oscuro.\",\n \"colorUseSuggestion\": \"Usar {{color}}\"\n },\n \"wizard\": {\n \"next\": \"Siguiente\",\n \"back\": \"Anterior\",\n \"skip\": \"Omitir este paso\",\n \"optional\": \"Opcional\",\n \"skipped\": \"Omitido\",\n \"stepOf\": \"Paso {{current}} de {{total}}\"\n },\n \"language\": {\n \"switchTo\": {\n \"es\": \"Cambiar a español\",\n \"en\": \"Cambiar a inglés\"\n }\n },\n \"colorScheme\": {\n \"label\": \"Claro u oscuro\",\n \"switchTo\": {\n \"light\": \"Cambiar a modo claro\",\n \"dark\": \"Cambiar a modo oscuro\"\n }\n },\n \"toast\": {\n \"done\": \"Listo\",\n \"error\": \"Ocurrió un error\",\n \"warning\": \"Atención\",\n \"info\": \"Aviso\",\n \"working\": \"Procesando…\"\n },\n \"waiting\": {\n \"title\": \"Un momento\",\n \"text\": \"Estamos procesando su solicitud. No cierre esta ventana.\"\n },\n \"newBuild\": {\n \"message\": \"Hay una versión nueva del sistema. Recargue la página para usarla.\",\n \"short\": \"Versión nueva disponible\",\n \"reload\": \"Recargar\"\n },\n \"install\": {\n \"banner\": \"Instale esta aplicación en su equipo para abrirla más rápido\",\n \"action\": \"Instalar\",\n \"howTo\": \"Cómo instalar\",\n \"dismiss\": \"Ahora no\",\n \"gotIt\": \"Entendido\",\n \"menuLabel\": \"Instalar la app\",\n \"iosModern\": {\n \"title\": \"Instalar en su iPhone o iPad\",\n \"step1\": \"Toque ⋯ (los tres puntos) junto a la barra de direcciones.\",\n \"step2\": \"Toque «Compartir».\",\n \"step3\": \"Toque «Agregar a inicio».\",\n \"step4\": \"Deje activado «Abrir como app web» y toque «Agregar».\"\n },\n \"iosClassic\": {\n \"title\": \"Instalar en su iPhone\",\n \"step1\": \"Toque el botón Compartir (el cuadro con una flecha hacia arriba).\",\n \"step2\": \"Toque «Agregar a inicio».\",\n \"step3\": \"Toque «Agregar».\"\n },\n \"androidFirefox\": {\n \"title\": \"Instalar en Firefox\",\n \"step1\": \"Toque el menú ⋮.\",\n \"step2\": \"Toque «Instalar» o «Agregar a pantalla de inicio».\",\n \"step3\": \"Confirme.\"\n }\n },\n \"upload\": {\n \"hint\": \"Arrastre aquí su archivo\",\n \"hintMultiple\": \"Arrastre aquí sus archivos\",\n \"choose\": \"Elegir archivo\",\n \"chooseMultiple\": \"Elegir archivos\",\n \"remove\": \"Quitar {{name}}\",\n \"invalidTitle\": \"Archivo no permitido\",\n \"invalidType\": \"«{{name}}» no es de un tipo permitido. Se aceptan: {{accept}}.\",\n \"tooLarge\": \"«{{name}}» pesa más de {{max}}.\",\n \"tooLargeShort\": \"Pesa más de lo permitido\",\n \"totalTooLargeShort\": \"Entre todos pesan más de lo permitido\",\n \"tooManyFiles_one\": \"Se puede subir {{count}} archivo como máximo.\",\n \"tooManyFiles_other\": \"Se pueden subir {{count}} archivos como máximo.\",\n \"maxSizeHint\": \"Hasta {{max}} por archivo\",\n \"maxTotalSizeHint\": \"Hasta {{max}} entre todos\",\n \"maxFilesHint_one\": \"Hasta {{count}} archivo\",\n \"maxFilesHint_other\": \"Hasta {{count}} archivos\",\n \"summary_one\": \"{{count}} archivo · {{total}}\",\n \"summary_other\": \"{{count}} archivos · {{total}}\",\n \"summaryOf_one\": \"{{count}} archivo · {{total}} de {{max}}\",\n \"summaryOf_other\": \"{{count}} archivos · {{total}} de {{max}}\",\n \"pond\": {\n \"loading\": \"Cargando\",\n \"loadError\": \"No se pudo cargar\",\n \"waitingForSize\": \"Calculando el peso\",\n \"sizeNotAvailable\": \"Peso no disponible\",\n \"invalidField\": \"Hay archivos que no son válidos\",\n \"processing\": \"Subiendo\",\n \"processingComplete\": \"Subido\",\n \"processingAborted\": \"Subida cancelada\",\n \"processingError\": \"No se pudo subir\",\n \"revertError\": \"No se pudo deshacer\",\n \"removeError\": \"No se pudo quitar\",\n \"tapToCancel\": \"toque para cancelar\",\n \"tapToRetry\": \"toque para reintentar\",\n \"tapToUndo\": \"toque para deshacer\",\n \"remove\": \"Quitar\",\n \"abortLoad\": \"Cancelar\",\n \"retryLoad\": \"Reintentar\",\n \"abortProcessing\": \"Cancelar\",\n \"undoProcessing\": \"Deshacer\",\n \"retryProcessing\": \"Reintentar\",\n \"processItem\": \"Subir\"\n }\n },\n \"download\": {\n \"formats\": {\n \"pdf\": {\n \"label\": \"PDF\",\n \"hint\": \"Para leer, imprimir o archivar\"\n },\n \"xlsx\": {\n \"label\": \"Excel\",\n \"hint\": \"Para filtrar y cruzar con otros datos\"\n },\n \"csv\": {\n \"label\": \"CSV\",\n \"hint\": \"Texto plano, para importar a otro sistema\"\n }\n }\n },\n \"downloads\": {\n \"title\": \"Descargas\",\n \"summaryDownloading_one\": \"Descargando {{count}} archivo…\",\n \"summaryDownloading_other\": \"Descargando {{count}} archivos…\",\n \"summaryCompleted_one\": \"{{count}} descarga lista\",\n \"summaryCompleted_other\": \"{{count}} descargas listas\",\n \"summaryFailed_one\": \"{{count}} descarga no se pudo completar\",\n \"summaryFailed_other\": \"{{count}} descargas no se pudieron completar\",\n \"collapse\": \"Minimizar\",\n \"expand\": \"Ver descargas\",\n \"close\": \"Cerrar\",\n \"cancel\": \"Cancelar descarga\",\n \"cancelOf\": \"Cancelar la descarga de {{name}}\",\n \"completedOf\": \"{{name}} descargado\",\n \"failedOf\": \"No se pudo descargar {{name}}\",\n \"canceledOf\": \"Se canceló la descarga de {{name}}\",\n \"preparing\": \"Preparando el archivo…\",\n \"progressOf\": \"{{loaded}} de {{total}}\",\n \"progressLoaded\": \"{{loaded}} descargados\",\n \"failed\": \"No se pudo descargar\",\n \"canceled\": \"Cancelada\"\n },\n \"charts\": {\n \"viewAsTable\": \"Ver como tabla\",\n \"viewAsChart\": \"Ver como gráfica\",\n \"less\": \"Menos\",\n \"more\": \"Más\",\n \"day\": \"Día\"\n }\n },\n \"layout\": {\n \"skipToContent\": \"Saltar al contenido\",\n \"barActions\": {\n \"more\": \"Más acciones\"\n },\n \"drawer\": {\n \"open\": \"Abrir el menú\",\n \"ariaLabel\": \"Menú principal\",\n \"expand\": \"Abrir el menú lateral\",\n \"collapse\": \"Encoger el menú lateral\",\n \"more\": \"Más\",\n \"showTabs\": \"Ver las pestañas\",\n \"editTabs\": \"Editar la barra\",\n \"editTabsHint\": \"Elija hasta {{count}} pantallas para la barra de abajo; las demás quedan en «Más».\",\n \"tabInBar\": \"{{label}} en la barra\",\n \"resetTabs\": \"Como venía\",\n \"doneEditing\": \"Listo\",\n \"scrollDown\": \"Ver más del menú\",\n \"scrollUp\": \"Ver lo de arriba del menú\"\n },\n \"account\": {\n \"open\": \"Abrir el menú de su cuenta\",\n \"myProfile\": \"Mi perfil\"\n },\n \"settings\": {\n \"open\": \"Ajustes\",\n \"language\": \"Idioma\",\n \"colorScheme\": \"Claro u oscuro\",\n \"light\": \"Claro\",\n \"dark\": \"Oscuro\",\n \"system\": \"Automático\"\n },\n \"fontSize\": {\n \"label\": \"Tamaño de letra\",\n \"normal\": \"Normal\",\n \"large\": \"Grande\",\n \"xLarge\": \"Muy grande\"\n },\n \"languageName\": {\n \"es\": \"Español\",\n \"en\": \"English\"\n },\n \"breadcrumbs\": \"Dónde está\",\n \"signOut\": \"Salir\",\n \"navigating\": \"Cargando la pantalla\"\n },\n \"auth\": {\n \"signIn\": {\n \"title\": \"Iniciar sesión\",\n \"subtitle\": \"Entre con su correo y su contraseña.\",\n \"email\": \"Correo electrónico\",\n \"password\": \"Contraseña\",\n \"remember\": \"Mantener la sesión abierta en este equipo\",\n \"submit\": \"Entrar\",\n \"forgot\": \"¿Olvidó su contraseña?\"\n },\n \"forgotPassword\": {\n \"title\": \"Recuperar su contraseña\",\n \"subtitle\": \"Escriba el correo con el que entra y le enviaremos un enlace para elegir una contraseña nueva.\",\n \"email\": \"Correo electrónico\",\n \"submit\": \"Enviar el enlace\",\n \"sentTitle\": \"Revise su correo\",\n \"sent\": \"Si {{email}} tiene una cuenta, le llegará un enlace en unos minutos. Si no lo ve, revise el correo no deseado.\",\n \"backToSignIn\": \"Regresar a iniciar sesión\"\n },\n \"changePassword\": {\n \"title\": \"Cambiar contraseña\",\n \"current\": \"Contraseña actual\",\n \"next\": \"Contraseña nueva\",\n \"confirm\": \"Repita la contraseña nueva\",\n \"submit\": \"Cambiar contraseña\",\n \"mismatch\": \"Las dos contraseñas nuevas no son iguales.\",\n \"sameAsCurrent\": \"La contraseña nueva debe ser distinta de la actual.\",\n \"notAccepted\": \"La contraseña nueva no cumple con lo que se pide abajo.\",\n \"done\": \"Su contraseña cambió. La próxima vez entre con la nueva.\"\n },\n \"passwordRules\": {\n \"title\": \"La contraseña nueva debe tener\",\n \"minLength\": \"Al menos {{count}} caracteres\",\n \"lowercase\": \"Una letra minúscula\",\n \"uppercase\": \"Una letra mayúscula\",\n \"number\": \"Un número\",\n \"symbol\": \"Un símbolo, por ejemplo ! ? # -\",\n \"met\": \"ya cumple\",\n \"missing\": \"falta\"\n }\n },\n \"access\": {\n \"permissions\": {\n \"countOf\": \"{{count}} de {{total}}\",\n \"allOf\": \"Todos los permisos de {{group}}\"\n }\n },\n \"metricCard\": {\n \"trend\": {\n \"up\": \"Subió\",\n \"down\": \"Bajó\",\n \"flat\": \"Sin cambio\"\n }\n },\n \"errorPage\": {\n \"goHome\": \"Ir al inicio\",\n \"retry\": \"Intentar de nuevo\",\n \"reload\": \"Recargar\",\n \"newVersion\": {\n \"title\": \"Hay una versión nueva\",\n \"text\": \"Se publicó una actualización mientras tenía la página abierta. Recargue para seguir donde estaba.\"\n },\n \"notFound\": {\n \"title\": \"Esta página no existe\",\n \"text\": \"La dirección no corresponde a ninguna pantalla. Puede que el enlace esté incompleto o que la página ya no exista.\"\n },\n \"forbidden\": {\n \"title\": \"No tiene permiso para ver esta pantalla\",\n \"text\": \"Su usuario no tiene acceso a esta información. Si considera que es un error, comuníquese con el administrador.\"\n },\n \"serverError\": {\n \"title\": \"Algo falló de nuestro lado\",\n \"text\": \"No pudimos mostrar esta pantalla. Inténtelo de nuevo en un momento; si el problema continúa, comuníquese con soporte.\"\n }\n },\n \"problems\": {\n \"offline\": {\n \"title\": \"Sin conexión\",\n \"detail\": \"No pudimos comunicarnos con el servidor. Revise su conexión e inténtelo de nuevo.\"\n },\n \"unauthenticated\": {\n \"title\": \"Necesita iniciar sesión\",\n \"detail\": \"Su sesión no es válida o ya terminó. Inicie sesión de nuevo para continuar.\"\n },\n \"forbidden\": {\n \"title\": \"No tiene permiso para realizar esta acción\",\n \"detail\": \"Su usuario no tiene acceso a esta información u operación. Si considera que es un error, comuníquese con el administrador.\"\n },\n \"notFound\": {\n \"title\": \"No encontramos lo que busca\",\n \"detail\": \"La dirección o el registro que solicitó no existe o ya no está disponible.\"\n },\n \"conflict\": {\n \"title\": \"No se puede realizar en este momento\",\n \"detail\": \"El registro cambió o no está en el estado que se necesita. Actualice la pantalla e inténtelo de nuevo.\"\n },\n \"payloadTooLarge\": {\n \"title\": \"Lo que envió es demasiado grande\",\n \"detail\": \"El archivo o los datos superan el tamaño máximo permitido.\"\n },\n \"csrfTokenMismatch\": {\n \"title\": \"La página necesita actualizarse\",\n \"detail\": \"Pasó demasiado tiempo o la página quedó desactualizada. Recárguela e inténtelo de nuevo.\"\n },\n \"validation\": {\n \"title\": \"Los datos enviados no son válidos\",\n \"detail\": \"Revise los campos marcados e inténtelo de nuevo.\"\n },\n \"tooManyRequests\": {\n \"title\": \"Demasiados intentos seguidos\",\n \"detail\": \"Hizo muchas solicitudes en poco tiempo. Espere un momento e inténtelo de nuevo.\"\n },\n \"serverError\": {\n \"title\": \"No pudimos completar su solicitud\",\n \"detail\": \"Ocurrió un problema en el servidor. Inténtelo en un momento; si el problema continúa, comuníquese con soporte.\"\n },\n \"serviceUnavailable\": {\n \"title\": \"El servicio no está disponible\",\n \"detail\": \"El servidor no está respondiendo en este momento. Inténtelo más tarde.\"\n },\n \"generic\": {\n \"title\": \"No pudimos completar su solicitud\",\n \"detail\": \"Ocurrió un problema con su solicitud. Si continúa, comuníquese con soporte.\"\n },\n \"gone\": {\n \"title\": \"Esto ya no está disponible\",\n \"detail\": \"El enlace o el registro venció o ya se usó.\"\n }\n },\n \"validation\": {\n \"default\": \"El valor no es válido.\",\n \"required\": \"Este campo es obligatorio.\",\n \"notType\": \"El valor no tiene el formato esperado.\",\n \"oneOf\": \"Elija una de las opciones.\",\n \"notOneOf\": \"Ese valor no está permitido.\",\n \"email\": \"Escriba un correo válido, por ejemplo nombre@empresa.com.\",\n \"url\": \"Escriba una dirección web válida.\",\n \"uuid\": \"El identificador no es válido.\",\n \"stringLength_one\": \"Escriba exactamente {{count}} carácter.\",\n \"stringLength_other\": \"Escriba exactamente {{count}} caracteres.\",\n \"stringMin_one\": \"Escriba al menos {{count}} carácter.\",\n \"stringMin_other\": \"Escriba al menos {{count}} caracteres.\",\n \"stringMax_one\": \"Escriba como máximo {{count}} carácter.\",\n \"stringMax_other\": \"Escriba como máximo {{count}} caracteres.\",\n \"matches\": \"El formato no es válido.\",\n \"trim\": \"Quite los espacios al inicio y al final.\",\n \"lowercase\": \"Escríbalo en minúsculas.\",\n \"uppercase\": \"Escríbalo en mayúsculas.\",\n \"numberMin\": \"No puede ser menor que {{min}}.\",\n \"numberMax\": \"No puede ser mayor que {{max}}.\",\n \"lessThan\": \"Debe ser menor que {{less}}.\",\n \"moreThan\": \"Debe ser mayor que {{more}}.\",\n \"positive\": \"Debe ser un número positivo.\",\n \"negative\": \"Debe ser un número negativo.\",\n \"integer\": \"Debe ser un número entero.\",\n \"dateMin\": \"La fecha no puede ser anterior a {{min}}.\",\n \"dateMax\": \"La fecha no puede ser posterior a {{max}}.\",\n \"arrayMin_one\": \"Elija al menos {{count}} opción.\",\n \"arrayMin_other\": \"Elija al menos {{count}} opciones.\",\n \"arrayMax_one\": \"Elija como máximo {{count}} opción.\",\n \"arrayMax_other\": \"Elija como máximo {{count}} opciones.\",\n \"arrayLength_one\": \"Elija exactamente {{count}} opción.\",\n \"arrayLength_other\": \"Elija exactamente {{count}} opciones.\"\n },\n \"dictionaries\": {\n \"unknown\": {\n \"label\": \"Sin estatus\",\n \"tooltip\": \"\"\n }\n },\n \"security\": {\n \"passkeys\": {\n \"cancelled\": \"No se usó ninguna llave de acceso. Puede intentarlo de nuevo.\",\n \"alreadyRegistered\": \"Esa llave de acceso ya está registrada en su cuenta.\",\n \"wrongDomain\": \"Las llaves de acceso solo funcionan en la dirección oficial del sistema.\",\n \"failed\": \"El navegador no pudo usar la llave de acceso.\",\n \"unsupported\": \"Este navegador no admite llaves de acceso.\"\n },\n \"twoStep\": {\n \"title\": \"Verificación en dos pasos\",\n \"description\": \"Además de su contraseña, un segundo paso al entrar. Si alguien obtiene su contraseña, no podrá entrar sin él.\",\n \"active\": \"Activa\",\n \"activeSince\": \"Desde {{date}}\",\n \"inactive\": \"Sin activar\",\n \"inactiveTooltip\": \"Su cuenta solo está protegida por la contraseña.\",\n \"passkeysTitle\": \"Llaves de acceso\",\n \"add\": \"Agregar\",\n \"passkeysEmpty\": \"La forma más segura: entra con la huella, el rostro o el PIN de su equipo.\",\n \"passkeyUsed\": \"Usada por última vez {{date}}\",\n \"passkeyCreated\": \"Creada {{date}}\",\n \"removePasskey\": \"Quitar {{name}}\",\n \"removePasskeyTooltip\": \"Quitar esta llave\",\n \"appTitle\": \"App autenticadora\",\n \"appActiveSince\": \"Activa desde {{date}}\",\n \"appDescription\": \"Un código de 6 dígitos que cambia cada 30 segundos.\",\n \"activate\": \"Activar\",\n \"deactivate\": \"Desactivar\",\n \"codesTitle\": \"Códigos de recuperación\",\n \"codesRemaining_one\": \"Le queda {{count}} código sin usar.\",\n \"codesRemaining_other\": \"Le quedan {{count}} códigos sin usar.\",\n \"codesNone\": \"Ya no le quedan códigos: genere otros.\",\n \"regenerate\": \"Generar nuevos\",\n \"passwordLabel\": \"Su contraseña actual\",\n \"passwordRequired\": \"Escriba su contraseña.\",\n \"disableTitle\": \"¿Desactivar la app autenticadora?\",\n \"disableText\": \"Si no tiene una llave de acceso, su cuenta quedará protegida solo por la contraseña y sus códigos de recuperación dejarán de servir.\",\n \"removeTitle\": \"¿Quitar «{{name}}»?\",\n \"removeText\": \"Ya no podrá entrar con esta llave. Bórrela también de su equipo o de su gestor de contraseñas.\",\n \"remove\": \"Quitar\",\n \"regenerateTitle\": \"¿Generar códigos nuevos?\",\n \"regenerateText\": \"Los códigos que tenga ahora dejarán de servir.\",\n \"generate\": \"Generar\",\n \"passkeyDialogTitle\": \"Agregar una llave de acceso\",\n \"passkeyDialogText\": \"Una llave de acceso usa la huella, el rostro o el PIN de este equipo o de su teléfono. No se puede robar con una página falsa y le permite entrar sin escribir su contraseña.\",\n \"passkeyName\": \"Nombre para reconocerla (opcional)\",\n \"passkeyNamePlaceholder\": \"Por ejemplo: MacBook del trabajo\",\n \"createPasskey\": \"Crear llave\",\n \"totpDialogTitle\": \"Activar la app autenticadora\",\n \"totpStep1\": \"1. Abra su app (Google Authenticator, Microsoft Authenticator, 1Password…) y escanee este código.\",\n \"totpQrAlt\": \"Código QR para la app autenticadora\",\n \"totpCantScan\": \"¿No puede escanear? Escriba esta clave en su app:\",\n \"totpStep2\": \"2. Escriba el código de 6 dígitos que muestra la app.\",\n \"codeLabel\": \"Código\",\n \"codeRequired\": \"Escriba el código de 6 dígitos.\",\n \"codeFormat\": \"Son 6 dígitos, como aparecen en su app.\",\n \"passkeyAdded\": \"Llave de acceso agregada\",\n \"passkeyRemoved\": \"Llave de acceso quitada\",\n \"appActivated\": \"App autenticadora activada\",\n \"appDeactivated\": \"App autenticadora desactivada\"\n },\n \"recoveryCodes\": {\n \"title\": \"Guarde sus códigos de recuperación\",\n \"warning\": \"Es la única vez que los verá. Con uno de ellos podrá entrar si pierde su teléfono o su llave de acceso; cada uno sirve una sola vez.\",\n \"copyAll\": \"Copiar todos\",\n \"download\": \"Descargar .txt\",\n \"saved\": \"Ya los guardé en un lugar seguro\",\n \"done\": \"Listo\",\n \"fileTitle\": \"{{appName}} · códigos de recuperación\",\n \"fileAccount\": \"Cuenta: {{account}}\",\n \"fileGenerated\": \"Generados: {{date}}\",\n \"fileHowTo\": \"Cada código sirve UNA sola vez para entrar si no tiene su teléfono o su llave de acceso.\",\n \"fileKeepSafe\": \"Guárdelos en un lugar seguro (un gestor de contraseñas o impresos bajo llave).\",\n \"fileName\": \"codigos-recuperacion-{{date}}.txt\"\n },\n \"secondStep\": {\n \"intro\": \"Su cuenta tiene verificación en dos pasos. Confirme que es usted para terminar de entrar.\",\n \"usePasskey\": \"Usar mi llave de acceso\",\n \"or\": \"o\",\n \"appCodeLabel\": \"Código de su app autenticadora\",\n \"appCodeHelp\": \"Ábrala (Google Authenticator, Microsoft Authenticator, 1Password…) y escriba los 6 dígitos.\",\n \"recoveryCodeLabel\": \"Código de recuperación\",\n \"recoveryCodeHelp\": \"Uno de los códigos que guardó al activar la verificación. Cada uno sirve una sola vez.\",\n \"recoveryCodeRequired\": \"Escriba uno de sus códigos de recuperación.\",\n \"recoveryCodeFormat\": \"Tienen la forma ABCDE-FGHJK.\",\n \"confirm\": \"Confirmar\",\n \"useRecovery\": \"No tengo mi teléfono: usar un código de recuperación\",\n \"useApp\": \"Usar el código de mi app autenticadora\",\n \"otherAccount\": \"Entrar con otra cuenta\",\n \"remainingAttempts_one\": \"Le queda {{count}} intento.\",\n \"remainingAttempts_other\": \"Le quedan {{count}} intentos.\"\n },\n \"sessions\": {\n \"title\": \"Mis sesiones\",\n \"description\": \"Dónde tiene la cuenta abierta. Si no reconoce un equipo, cierre la sesión en los demás y cambie su contraseña.\",\n \"current\": \"Este equipo\",\n \"device\": \"{{browser}} en {{platform}}\",\n \"otherBrowser\": \"Otro navegador\",\n \"otherPlatform\": \"otro sistema\",\n \"since\": \"Desde {{date}}\",\n \"network\": \"red {{network}}\",\n \"onlyThis\": \"Solo tiene la sesión abierta en este equipo.\",\n \"closeOthers\": \"Cerrar la sesión en los demás equipos\",\n \"confirmTitle\": \"¿Cerrar la sesión en los demás equipos?\",\n \"confirmText_one\": \"Se cerrará en {{count}} equipo. Este sigue dentro, y en el otro tendrá que volver a entrar con su contraseña.\",\n \"confirmText_other\": \"Se cerrará en {{count}} equipos. Este sigue dentro, y en los demás tendrá que volver a entrar con su contraseña.\",\n \"confirm\": \"Cerrar las demás\",\n \"closed_one\": \"Se cerró la sesión en {{count}} equipo\",\n \"closed_other\": \"Se cerró la sesión en {{count}} equipos\",\n \"noneClosed\": \"No había sesiones abiertas en otros equipos\"\n },\n \"activity\": {\n \"title\": \"Actividad de la cuenta\",\n \"description\": \"Lo último que pasó con su cuenta. Si ve algo que no fue usted, cambie su contraseña y cierre la sesión en los demás equipos.\",\n \"empty\": \"Todavía no hay actividad.\",\n \"from\": \"{{device}} · red {{network}}\",\n \"kinds\": {\n \"signedIn\": \"Entró\",\n \"signInFailed\": \"Intento de entrar con contraseña equivocada\",\n \"signedOut\": \"Salió\",\n \"passwordChanged\": \"Cambió su contraseña\",\n \"twoStepEnabled\": \"Activó la verificación en dos pasos\",\n \"twoStepDisabled\": \"Desactivó la verificación en dos pasos\",\n \"passkeyAdded\": \"Agregó una llave de acceso\",\n \"passkeyRemoved\": \"Quitó una llave de acceso\",\n \"recoveryCodesGenerated\": \"Generó códigos de recuperación nuevos\",\n \"recoveryCodeUsed\": \"Entró con un código de recuperación\",\n \"sessionsClosed\": \"Cerró la sesión en los demás equipos\"\n }\n }\n },\n \"calendar\": {\n \"previous\": \"Anterior\",\n \"next\": \"Siguiente\",\n \"today\": \"Hoy\",\n \"view\": \"Vista del calendario\",\n \"views\": {\n \"month\": \"Mes\",\n \"week\": \"Semana\",\n \"day\": \"Día\",\n \"list\": \"Lista\"\n }\n },\n \"kanban\": {\n \"instructions\": \"Para mover una tarjeta con el teclado: espacio para levantarla, flechas para moverla y espacio para soltarla. Escape la deja donde estaba.\",\n \"lifted\": \"Levantó «{{title}}», en {{column}}, posición {{position}}.\",\n \"moving\": \"Va a {{column}}, posición {{position}}.\",\n \"dropped\": \"Soltó «{{title}}» en {{column}}, posición {{position}}.\",\n \"cancelled\": \"«{{title}}» se quedó donde estaba.\",\n \"overLimit\": \"Pasó el tope de {{limit}} tarjetas.\",\n \"empty\": \"Sin tarjetas. Arrastre una aquí.\"\n },\n \"inbox\": {\n \"listLabel\": \"Mensajes\",\n \"folders\": \"Carpetas\",\n \"empty\": \"No hay mensajes aquí.\",\n \"noMessageSelected\": \"Elija un mensaje para leerlo.\",\n \"star\": \"Destacar\",\n \"unstar\": \"Quitar de destacados\",\n \"unread\": \"Sin leer\",\n \"attachments\": \"Archivos adjuntos\",\n \"to\": \"Para: {{to}}\",\n \"back\": \"Regresar\",\n \"unreadCount_one\": \"{{count}} sin leer\",\n \"unreadCount_other\": \"{{count}} sin leer\"\n },\n \"account\": {\n \"reset\": {\n \"title\": \"Elegir una contraseña nueva\",\n \"subtitle\": \"Llegó aquí desde el enlace del correo. Elija la contraseña con la que va a entrar.\",\n \"done\": \"Ya puede entrar con su contraseña nueva.\",\n \"goToSignIn\": \"Ir a iniciar sesión\",\n \"missingToken\": \"Este enlace no sirve: le falta su clave. Pida uno nuevo desde «¿Olvidó su contraseña?».\",\n \"askAgain\": \"Pedir otro enlace\"\n },\n \"profile\": {\n \"tabs\": {\n \"label\": \"Partes de su perfil\",\n \"data\": \"Sus datos\",\n \"security\": \"Seguridad\",\n \"preferences\": \"Preferencias\"\n },\n \"data\": {\n \"title\": \"Sus datos\",\n \"text\": \"Así le ven las demás personas en la app.\",\n \"name\": \"Nombre\",\n \"email\": \"Correo\",\n \"emailHelp\": \"Es el correo con el que entra; para cambiarlo, pídalo a quien administra la app.\",\n \"phone\": \"Teléfono (opcional)\",\n \"phoneInvalid\": \"Escriba solo dígitos (de 7 a 15), con + al inicio si es de otro país.\",\n \"save\": \"Guardar\",\n \"saved\": \"Se guardaron sus datos.\"\n },\n \"password\": {\n \"title\": \"Contraseña\",\n \"text\": \"Use una contraseña que no use en otros sitios. Al cambiarla, la próxima vez entra con la nueva.\"\n },\n \"preferences\": {\n \"title\": \"Apariencia\",\n \"text\": \"Cómo se ve la app para usted: el tamaño de letra, el idioma y claro u oscuro se recuerdan en este navegador.\"\n }\n },\n \"demo\": {\n \"totpCode\": \"Usar el código de ejemplo\",\n \"totpCodeHelp\": \"Solo en la demostración: llena el código que enseñaría su app ahorita, por si no la tiene a la mano.\",\n \"passkeyNote\": \"En la demostración la llave se guarda de verdad en su llavero (iCloud, Google o su gestor de contraseñas), pero esta página la olvida al recargar. Cuando termine de probar, bórrela también de su llavero.\",\n \"securityNote\": \"Servidor de demostración: la verificación funciona con su teléfono de verdad (escanee el QR o cree una llave con su huella), pero vive en la memoria de la pestaña: al recargar se apaga. Salga y vuelva a entrar para ver el segundo paso.\",\n \"server\": {\n \"wrongCredentialsTitle\": \"No pudo entrar\",\n \"wrongCredentials\": \"En la demostración se entra con {{email}} y cualquier contraseña.\",\n \"noSessionTitle\": \"Su sesión terminó\",\n \"noSession\": \"Vuelva a entrar.\",\n \"validationTitle\": \"Revise los datos\",\n \"validationDetail\": \"Hay campos por corregir.\",\n \"passwordRequired\": \"Escriba su contraseña para confirmar.\",\n \"nameRequired\": \"Escriba su nombre.\",\n \"wrongCodeTitle\": \"El código no coincide\",\n \"wrongCode\": \"Revise que sea el código que enseña su app ahorita.\",\n \"expiredTitle\": \"Se acabó el tiempo\",\n \"expired\": \"Pasaron más de 5 minutos: vuelva a escribir su contraseña.\",\n \"lockedTitle\": \"Demasiados intentos\",\n \"locked\": \"Por seguridad hay que empezar de nuevo: vuelva a escribir su contraseña.\",\n \"defaultPasskeyName\": \"Llave {{number}}\",\n \"profileSaved\": \"Se guardaron sus datos.\"\n }\n }\n }\n});\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"es.js","sources":["../../src/locales/es.js"],"sourcesContent":["// Textos del paquete en español (el idioma por omisión). Cada proyecto puede cambiar cualquiera con `texts` o `translate`\n// de ToolkitProvider, con la misma forma: namespace, llaves anidadas, {{variable}} y plurales _one / _other.\nexport default Object.freeze({\n \"table\": {\n \"search\": {\n \"placeholder\": \"Buscar dentro de estos resultados…\"\n },\n \"count\": {\n \"records_one\": \"{{total}} registro\",\n \"records_other\": \"{{total}} registros\",\n \"capped\": \"más de {{total}} registros\",\n \"cappedTag\": \"total aproximado\",\n \"cappedTooltip\": \"Hay al menos estos registros y puede haber más: agregue un filtro para verlos todos.\"\n },\n \"empty\": {\n \"default\": \"Sin registros\",\n \"filtered\": \"Ningún registro cumple con los filtros aplicados.\",\n \"clearFilters\": \"Quitar los filtros\"\n },\n \"chips\": {\n \"applied_one\": \"{{count}} filtro aplicado\",\n \"applied_other\": \"{{count}} filtros aplicados\",\n \"clearAll\": \"Limpiar todo\"\n },\n \"columnFilter\": {\n \"tooltip\": \"Filtrar (se aplica a todos los registros, no solo a esta página)\",\n \"activeTooltip_one\": \"{{count}} filtro en esta columna\",\n \"activeTooltip_other\": \"{{count}} filtros en esta columna\",\n \"clear\": \"Limpiar esta columna\",\n \"contains\": \"Contiene\"\n },\n \"options\": {\n \"searchPlaceholder\": \"Buscar opción…\",\n \"empty\": \"Sin valores en este resultado\",\n \"noMatch\": \"Ninguna opción coincide con “{{text}}”\"\n },\n \"sort\": {\n \"tooltip\": \"Ordenar por esta columna\",\n \"ascending\": \"orden ascendente\",\n \"descending\": \"orden descendente\",\n \"clear\": \"Quitar el orden\"\n },\n \"selection\": {\n \"count_one\": \"{{total}} elegido\",\n \"count_other\": \"{{total}} elegidos\",\n \"allMatching\": \"Los {{total}} que coinciden están elegidos\",\n \"allMatchingCapped\": \"Todos los que coinciden están elegidos\",\n \"pageSelected_one\": \"Se eligió el único renglón de esta página.\",\n \"pageSelected_other\": \"Se eligieron los {{count}} de esta página.\",\n \"selectAllMatching\": \"Elegir los {{total}} que coinciden\",\n \"selectAllMatchingCapped\": \"Elegir todos los que coinciden\",\n \"onlyThisPage\": \"Elegir solo esta página\",\n \"clear\": \"Quitar selección\",\n \"summaryLabel\": \"Lo elegido\",\n \"actionsLabel\": \"Acciones de los elegidos\"\n },\n \"goToPage\": {\n \"page\": \"Página\",\n \"of_one\": \"de {{total}}\",\n \"of_other\": \"de {{total}}\",\n \"ariaLabel\": \"Ir a la página\"\n },\n \"quickFilters\": {\n \"all\": \"Todos\",\n \"countAriaLabel\": \"{{count}} registros\"\n },\n \"detail\": {\n \"tooltip\": \"Ver detalle\",\n \"ariaLabel\": \"Ver el detalle de este registro\"\n },\n \"error\": {\n \"generic\": \"No pudimos consultar la tabla.\"\n },\n \"dateRange\": {\n \"label\": \"Personalizado\",\n \"title\": \"Rango de fechas\",\n \"from\": \"Desde\",\n \"to\": \"Hasta\",\n \"fromHelp\": \"Desde el inicio de ese día\",\n \"toHelp\": \"Hasta el final de ese día\",\n \"invalid\": \"«Hasta» no puede ser antes de «Desde»\",\n \"summary\": \"{{from}} – {{to}}\",\n \"today\": \"hoy\",\n \"clear\": \"Quitar\",\n \"apply\": \"Aplicar\"\n },\n \"audit\": {\n \"columns\": {\n \"occurredAt\": \"Fecha y hora\",\n \"event\": \"Qué pasó\",\n \"result\": \"Resultado\",\n \"actor\": \"Quién\"\n },\n \"systemActor\": \"Proceso automático\",\n \"eventFilterCaption\": \"Filtrar por evento\",\n \"count_one\": \"{{count}} evento\",\n \"count_other\": \"{{count}} eventos\",\n \"empty\": \"Todavía no hay eventos registrados.\"\n }\n },\n \"common\": {\n \"actions\": {\n \"cancel\": \"Cancelar\",\n \"confirm\": \"Confirmar\",\n \"retry\": \"Intentar de nuevo\",\n \"download\": \"Descargar\",\n \"close\": \"Cerrar\",\n \"back\": \"Regresar\",\n \"reload\": \"Recargar la página\"\n },\n \"status\": {\n \"loading\": \"Cargando…\",\n \"noData\": \"Sin datos\"\n },\n \"form\": {\n \"showPassword\": \"Mostrar contraseña\",\n \"hidePassword\": \"Ocultar contraseña\",\n \"clear\": \"Borrar el texto\",\n \"selectPlaceholder\": \"Elija una opción\",\n \"copy\": \"Copiar\",\n \"copied\": \"Copiado\",\n \"noOptions\": \"Ninguna opción coincide\",\n \"loadingOptions\": \"Cargando opciones…\",\n \"pickColor\": \"Elegir el color\",\n \"colorContrast\": \"Contraste sobre blanco: {{ratio}}:1\",\n \"colorLowContrast\": \"Con ese color el texto casi no se leería sobre blanco. {{suggestion}} es el mismo tono, más oscuro.\",\n \"colorUseSuggestion\": \"Usar {{color}}\"\n },\n \"selection\": {\n \"clear\": \"Quitar selección\",\n \"actionsLabel\": \"Acciones de los elegidos\",\n \"summaryLabel\": \"Lo elegido\"\n },\n \"wizard\": {\n \"next\": \"Siguiente\",\n \"back\": \"Anterior\",\n \"skip\": \"Omitir este paso\",\n \"optional\": \"Opcional\",\n \"skipped\": \"Omitido\",\n \"stepOf\": \"Paso {{current}} de {{total}}\"\n },\n \"language\": {\n \"switchTo\": {\n \"es\": \"Cambiar a español\",\n \"en\": \"Cambiar a inglés\"\n },\n \"switchToNamed\": \"Cambiar a {{name}}\",\n \"choose\": \"Idioma: {{name}}. Elegir otro\"\n },\n \"colorScheme\": {\n \"label\": \"Claro u oscuro\",\n \"switchTo\": {\n \"light\": \"Cambiar a modo claro\",\n \"dark\": \"Cambiar a modo oscuro\"\n }\n },\n \"toast\": {\n \"done\": \"Listo\",\n \"error\": \"Ocurrió un error\",\n \"warning\": \"Atención\",\n \"info\": \"Aviso\",\n \"working\": \"Procesando…\"\n },\n \"waiting\": {\n \"title\": \"Un momento\",\n \"text\": \"Estamos procesando su solicitud. No cierre esta ventana.\"\n },\n \"newBuild\": {\n \"message\": \"Hay una versión nueva del sistema. Recargue la página para usarla.\",\n \"short\": \"Versión nueva disponible\",\n \"reload\": \"Recargar\"\n },\n \"install\": {\n \"banner\": \"Instale esta aplicación en su equipo para abrirla más rápido\",\n \"action\": \"Instalar\",\n \"howTo\": \"Cómo instalar\",\n \"dismiss\": \"Ahora no\",\n \"gotIt\": \"Entendido\",\n \"menuLabel\": \"Instalar la app\",\n \"iosModern\": {\n \"title\": \"Instalar en su iPhone o iPad\",\n \"step1\": \"Toque ⋯ (los tres puntos) junto a la barra de direcciones.\",\n \"step2\": \"Toque «Compartir».\",\n \"step3\": \"Toque «Agregar a inicio».\",\n \"step4\": \"Deje activado «Abrir como app web» y toque «Agregar».\"\n },\n \"iosClassic\": {\n \"title\": \"Instalar en su iPhone\",\n \"step1\": \"Toque el botón Compartir (el cuadro con una flecha hacia arriba).\",\n \"step2\": \"Toque «Agregar a inicio».\",\n \"step3\": \"Toque «Agregar».\"\n },\n \"androidFirefox\": {\n \"title\": \"Instalar en Firefox\",\n \"step1\": \"Toque el menú ⋮.\",\n \"step2\": \"Toque «Instalar» o «Agregar a pantalla de inicio».\",\n \"step3\": \"Confirme.\"\n }\n },\n \"upload\": {\n \"hint\": \"Arrastre aquí su archivo\",\n \"hintMultiple\": \"Arrastre aquí sus archivos\",\n \"choose\": \"Elegir archivo\",\n \"chooseMultiple\": \"Elegir archivos\",\n \"remove\": \"Quitar {{name}}\",\n \"invalidTitle\": \"Archivo no permitido\",\n \"invalidType\": \"«{{name}}» no es de un tipo permitido. Se aceptan: {{accept}}.\",\n \"tooLarge\": \"«{{name}}» pesa más de {{max}}.\",\n \"tooLargeShort\": \"Pesa más de lo permitido\",\n \"totalTooLargeShort\": \"Entre todos pesan más de lo permitido\",\n \"tooManyFiles_one\": \"Se puede subir {{count}} archivo como máximo.\",\n \"tooManyFiles_other\": \"Se pueden subir {{count}} archivos como máximo.\",\n \"maxSizeHint\": \"Hasta {{max}} por archivo\",\n \"maxTotalSizeHint\": \"Hasta {{max}} entre todos\",\n \"maxFilesHint_one\": \"Hasta {{count}} archivo\",\n \"maxFilesHint_other\": \"Hasta {{count}} archivos\",\n \"summary_one\": \"{{count}} archivo · {{total}}\",\n \"summary_other\": \"{{count}} archivos · {{total}}\",\n \"summaryOf_one\": \"{{count}} archivo · {{total}} de {{max}}\",\n \"summaryOf_other\": \"{{count}} archivos · {{total}} de {{max}}\",\n \"pond\": {\n \"loading\": \"Cargando\",\n \"loadError\": \"No se pudo cargar\",\n \"waitingForSize\": \"Calculando el peso\",\n \"sizeNotAvailable\": \"Peso no disponible\",\n \"invalidField\": \"Hay archivos que no son válidos\",\n \"processing\": \"Subiendo\",\n \"processingComplete\": \"Subido\",\n \"processingAborted\": \"Subida cancelada\",\n \"processingError\": \"No se pudo subir\",\n \"revertError\": \"No se pudo deshacer\",\n \"removeError\": \"No se pudo quitar\",\n \"tapToCancel\": \"toque para cancelar\",\n \"tapToRetry\": \"toque para reintentar\",\n \"tapToUndo\": \"toque para deshacer\",\n \"remove\": \"Quitar\",\n \"abortLoad\": \"Cancelar\",\n \"retryLoad\": \"Reintentar\",\n \"abortProcessing\": \"Cancelar\",\n \"undoProcessing\": \"Deshacer\",\n \"retryProcessing\": \"Reintentar\",\n \"processItem\": \"Subir\"\n }\n },\n \"download\": {\n \"formats\": {\n \"pdf\": {\n \"label\": \"PDF\",\n \"hint\": \"Para leer, imprimir o archivar\"\n },\n \"xlsx\": {\n \"label\": \"Excel\",\n \"hint\": \"Para filtrar y cruzar con otros datos\"\n },\n \"csv\": {\n \"label\": \"CSV\",\n \"hint\": \"Texto plano, para importar a otro sistema\"\n }\n }\n },\n \"downloads\": {\n \"title\": \"Descargas\",\n \"summaryDownloading_one\": \"Descargando {{count}} archivo…\",\n \"summaryDownloading_other\": \"Descargando {{count}} archivos…\",\n \"summaryCompleted_one\": \"{{count}} descarga lista\",\n \"summaryCompleted_other\": \"{{count}} descargas listas\",\n \"summaryFailed_one\": \"{{count}} descarga no se pudo completar\",\n \"summaryFailed_other\": \"{{count}} descargas no se pudieron completar\",\n \"collapse\": \"Minimizar\",\n \"expand\": \"Ver descargas\",\n \"close\": \"Cerrar\",\n \"cancel\": \"Cancelar descarga\",\n \"cancelOf\": \"Cancelar la descarga de {{name}}\",\n \"completedOf\": \"{{name}} descargado\",\n \"failedOf\": \"No se pudo descargar {{name}}\",\n \"canceledOf\": \"Se canceló la descarga de {{name}}\",\n \"preparing\": \"Preparando el archivo…\",\n \"progressOf\": \"{{loaded}} de {{total}}\",\n \"progressLoaded\": \"{{loaded}} descargados\",\n \"failed\": \"No se pudo descargar\",\n \"canceled\": \"Cancelada\"\n },\n \"charts\": {\n \"viewAsTable\": \"Ver como tabla\",\n \"legend\": \"Qué es cada serie\",\n \"viewAsChart\": \"Ver como gráfica\",\n \"less\": \"Menos\",\n \"more\": \"Más\",\n \"day\": \"Día\"\n }\n },\n \"layout\": {\n \"skipToContent\": \"Saltar al contenido\",\n \"barActions\": {\n \"more\": \"Más acciones\"\n },\n \"drawer\": {\n \"open\": \"Abrir el menú\",\n \"ariaLabel\": \"Menú principal\",\n \"expand\": \"Abrir el menú lateral\",\n \"collapse\": \"Encoger el menú lateral\",\n \"more\": \"Más\",\n \"showTabs\": \"Ver las pestañas\",\n \"editTabs\": \"Editar la barra\",\n \"editTabsHint\": \"Elija hasta {{count}} pantallas para la barra de abajo; las demás quedan en «Más».\",\n \"tabInBar\": \"{{label}} en la barra\",\n \"resetTabs\": \"Como venía\",\n \"doneEditing\": \"Listo\",\n \"scrollDown\": \"Ver más del menú\",\n \"scrollUp\": \"Ver lo de arriba del menú\"\n },\n \"account\": {\n \"open\": \"Abrir el menú de su cuenta\",\n \"myProfile\": \"Mi perfil\"\n },\n \"settings\": {\n \"open\": \"Ajustes\",\n \"language\": \"Idioma\",\n \"colorScheme\": \"Claro u oscuro\",\n \"light\": \"Claro\",\n \"dark\": \"Oscuro\",\n \"system\": \"Automático\"\n },\n \"fontSize\": {\n \"label\": \"Tamaño de letra\",\n \"normal\": \"Normal\",\n \"large\": \"Grande\",\n \"xLarge\": \"Muy grande\"\n },\n \"languageName\": {\n \"es\": \"Español\",\n \"en\": \"English\"\n },\n \"breadcrumbs\": \"Dónde está\",\n \"signOut\": \"Salir\",\n \"navigating\": \"Cargando la pantalla\"\n },\n \"auth\": {\n \"signIn\": {\n \"title\": \"Iniciar sesión\",\n \"subtitle\": \"Entre con su correo y su contraseña.\",\n \"email\": \"Correo electrónico\",\n \"password\": \"Contraseña\",\n \"remember\": \"Mantener la sesión abierta en este equipo\",\n \"submit\": \"Entrar\",\n \"forgot\": \"¿Olvidó su contraseña?\"\n },\n \"forgotPassword\": {\n \"title\": \"Recuperar su contraseña\",\n \"subtitle\": \"Escriba el correo con el que entra y le enviaremos un enlace para elegir una contraseña nueva.\",\n \"email\": \"Correo electrónico\",\n \"submit\": \"Enviar el enlace\",\n \"sentTitle\": \"Revise su correo\",\n \"sent\": \"Si {{email}} tiene una cuenta, le llegará un enlace en unos minutos. Si no lo ve, revise el correo no deseado.\",\n \"backToSignIn\": \"Regresar a iniciar sesión\"\n },\n \"changePassword\": {\n \"title\": \"Cambiar contraseña\",\n \"current\": \"Contraseña actual\",\n \"next\": \"Contraseña nueva\",\n \"confirm\": \"Repita la contraseña nueva\",\n \"submit\": \"Cambiar contraseña\",\n \"mismatch\": \"Las dos contraseñas nuevas no son iguales.\",\n \"sameAsCurrent\": \"La contraseña nueva debe ser distinta de la actual.\",\n \"notAccepted\": \"La contraseña nueva no cumple con lo que se pide abajo.\",\n \"done\": \"Su contraseña cambió. La próxima vez entre con la nueva.\"\n },\n \"passwordRules\": {\n \"title\": \"La contraseña nueva debe tener\",\n \"minLength\": \"Al menos {{count}} caracteres\",\n \"lowercase\": \"Una letra minúscula\",\n \"uppercase\": \"Una letra mayúscula\",\n \"number\": \"Un número\",\n \"symbol\": \"Un símbolo, por ejemplo ! ? # -\",\n \"met\": \"ya cumple\",\n \"missing\": \"falta\"\n }\n },\n \"access\": {\n \"permissions\": {\n \"countOf\": \"{{count}} de {{total}}\",\n \"allOf\": \"Todos los permisos de {{group}}\"\n }\n },\n \"metricCard\": {\n \"trend\": {\n \"up\": \"Subió\",\n \"down\": \"Bajó\",\n \"flat\": \"Sin cambio\"\n }\n },\n \"errorPage\": {\n \"goHome\": \"Ir al inicio\",\n \"retry\": \"Intentar de nuevo\",\n \"reload\": \"Recargar\",\n \"newVersion\": {\n \"title\": \"Hay una versión nueva\",\n \"text\": \"Se publicó una actualización mientras tenía la página abierta. Recargue para seguir donde estaba.\"\n },\n \"notFound\": {\n \"title\": \"Esta página no existe\",\n \"text\": \"La dirección no corresponde a ninguna pantalla. Puede que el enlace esté incompleto o que la página ya no exista.\"\n },\n \"forbidden\": {\n \"title\": \"No tiene permiso para ver esta pantalla\",\n \"text\": \"Su usuario no tiene acceso a esta información. Si considera que es un error, comuníquese con el administrador.\"\n },\n \"serverError\": {\n \"title\": \"Algo falló de nuestro lado\",\n \"text\": \"No pudimos mostrar esta pantalla. Inténtelo de nuevo en un momento; si el problema continúa, comuníquese con soporte.\"\n }\n },\n \"problems\": {\n \"offline\": {\n \"title\": \"Sin conexión\",\n \"detail\": \"No pudimos comunicarnos con el servidor. Revise su conexión e inténtelo de nuevo.\"\n },\n \"unauthenticated\": {\n \"title\": \"Necesita iniciar sesión\",\n \"detail\": \"Su sesión no es válida o ya terminó. Inicie sesión de nuevo para continuar.\"\n },\n \"forbidden\": {\n \"title\": \"No tiene permiso para realizar esta acción\",\n \"detail\": \"Su usuario no tiene acceso a esta información u operación. Si considera que es un error, comuníquese con el administrador.\"\n },\n \"notFound\": {\n \"title\": \"No encontramos lo que busca\",\n \"detail\": \"La dirección o el registro que solicitó no existe o ya no está disponible.\"\n },\n \"conflict\": {\n \"title\": \"No se puede realizar en este momento\",\n \"detail\": \"El registro cambió o no está en el estado que se necesita. Actualice la pantalla e inténtelo de nuevo.\"\n },\n \"payloadTooLarge\": {\n \"title\": \"Lo que envió es demasiado grande\",\n \"detail\": \"El archivo o los datos superan el tamaño máximo permitido.\"\n },\n \"csrfTokenMismatch\": {\n \"title\": \"La página necesita actualizarse\",\n \"detail\": \"Pasó demasiado tiempo o la página quedó desactualizada. Recárguela e inténtelo de nuevo.\"\n },\n \"validation\": {\n \"title\": \"Los datos enviados no son válidos\",\n \"detail\": \"Revise los campos marcados e inténtelo de nuevo.\"\n },\n \"tooManyRequests\": {\n \"title\": \"Demasiados intentos seguidos\",\n \"detail\": \"Hizo muchas solicitudes en poco tiempo. Espere un momento e inténtelo de nuevo.\"\n },\n \"serverError\": {\n \"title\": \"No pudimos completar su solicitud\",\n \"detail\": \"Ocurrió un problema en el servidor. Inténtelo en un momento; si el problema continúa, comuníquese con soporte.\"\n },\n \"serviceUnavailable\": {\n \"title\": \"El servicio no está disponible\",\n \"detail\": \"El servidor no está respondiendo en este momento. Inténtelo más tarde.\"\n },\n \"generic\": {\n \"title\": \"No pudimos completar su solicitud\",\n \"detail\": \"Ocurrió un problema con su solicitud. Si continúa, comuníquese con soporte.\"\n },\n \"gone\": {\n \"title\": \"Esto ya no está disponible\",\n \"detail\": \"El enlace o el registro venció o ya se usó.\"\n }\n },\n \"validation\": {\n \"default\": \"El valor no es válido.\",\n \"required\": \"Este campo es obligatorio.\",\n \"notType\": \"El valor no tiene el formato esperado.\",\n \"oneOf\": \"Elija una de las opciones.\",\n \"notOneOf\": \"Ese valor no está permitido.\",\n \"email\": \"Escriba un correo válido, por ejemplo nombre@empresa.com.\",\n \"url\": \"Escriba una dirección web válida.\",\n \"uuid\": \"El identificador no es válido.\",\n \"stringLength_one\": \"Escriba exactamente {{count}} carácter.\",\n \"stringLength_other\": \"Escriba exactamente {{count}} caracteres.\",\n \"stringMin_one\": \"Escriba al menos {{count}} carácter.\",\n \"stringMin_other\": \"Escriba al menos {{count}} caracteres.\",\n \"stringMax_one\": \"Escriba como máximo {{count}} carácter.\",\n \"stringMax_other\": \"Escriba como máximo {{count}} caracteres.\",\n \"matches\": \"El formato no es válido.\",\n \"trim\": \"Quite los espacios al inicio y al final.\",\n \"lowercase\": \"Escríbalo en minúsculas.\",\n \"uppercase\": \"Escríbalo en mayúsculas.\",\n \"numberMin\": \"No puede ser menor que {{min}}.\",\n \"numberMax\": \"No puede ser mayor que {{max}}.\",\n \"lessThan\": \"Debe ser menor que {{less}}.\",\n \"moreThan\": \"Debe ser mayor que {{more}}.\",\n \"positive\": \"Debe ser un número positivo.\",\n \"negative\": \"Debe ser un número negativo.\",\n \"integer\": \"Debe ser un número entero.\",\n \"dateMin\": \"La fecha no puede ser anterior a {{min}}.\",\n \"dateMax\": \"La fecha no puede ser posterior a {{max}}.\",\n \"arrayMin_one\": \"Elija al menos {{count}} opción.\",\n \"arrayMin_other\": \"Elija al menos {{count}} opciones.\",\n \"arrayMax_one\": \"Elija como máximo {{count}} opción.\",\n \"arrayMax_other\": \"Elija como máximo {{count}} opciones.\",\n \"arrayLength_one\": \"Elija exactamente {{count}} opción.\",\n \"arrayLength_other\": \"Elija exactamente {{count}} opciones.\"\n },\n \"dictionaries\": {\n \"unknown\": {\n \"label\": \"Sin estatus\",\n \"tooltip\": \"\"\n }\n },\n \"security\": {\n \"passkeys\": {\n \"cancelled\": \"No se usó ninguna llave de acceso. Puede intentarlo de nuevo.\",\n \"alreadyRegistered\": \"Esa llave de acceso ya está registrada en su cuenta.\",\n \"wrongDomain\": \"Las llaves de acceso solo funcionan en la dirección oficial del sistema.\",\n \"failed\": \"El navegador no pudo usar la llave de acceso.\",\n \"unsupported\": \"Este navegador no admite llaves de acceso.\"\n },\n \"twoStep\": {\n \"title\": \"Verificación en dos pasos\",\n \"description\": \"Además de su contraseña, un segundo paso al entrar. Si alguien obtiene su contraseña, no podrá entrar sin él.\",\n \"active\": \"Activa\",\n \"activeSince\": \"Desde {{date}}\",\n \"inactive\": \"Sin activar\",\n \"inactiveTooltip\": \"Su cuenta solo está protegida por la contraseña.\",\n \"passkeysTitle\": \"Llaves de acceso\",\n \"add\": \"Agregar\",\n \"passkeysEmpty\": \"La forma más segura: entra con la huella, el rostro o el PIN de su equipo.\",\n \"passkeyUsed\": \"Usada por última vez {{date}}\",\n \"passkeyCreated\": \"Creada {{date}}\",\n \"removePasskey\": \"Quitar {{name}}\",\n \"removePasskeyTooltip\": \"Quitar esta llave\",\n \"appTitle\": \"App autenticadora\",\n \"appActiveSince\": \"Activa desde {{date}}\",\n \"appDescription\": \"Un código de 6 dígitos que cambia cada 30 segundos.\",\n \"activate\": \"Activar\",\n \"deactivate\": \"Desactivar\",\n \"codesTitle\": \"Códigos de recuperación\",\n \"codesRemaining_one\": \"Le queda {{count}} código sin usar.\",\n \"codesRemaining_other\": \"Le quedan {{count}} códigos sin usar.\",\n \"codesNone\": \"Ya no le quedan códigos: genere otros.\",\n \"regenerate\": \"Generar nuevos\",\n \"passwordLabel\": \"Su contraseña actual\",\n \"passwordRequired\": \"Escriba su contraseña.\",\n \"disableTitle\": \"¿Desactivar la app autenticadora?\",\n \"disableText\": \"Si no tiene una llave de acceso, su cuenta quedará protegida solo por la contraseña y sus códigos de recuperación dejarán de servir.\",\n \"removeTitle\": \"¿Quitar «{{name}}»?\",\n \"removeText\": \"Ya no podrá entrar con esta llave. Bórrela también de su equipo o de su gestor de contraseñas.\",\n \"remove\": \"Quitar\",\n \"regenerateTitle\": \"¿Generar códigos nuevos?\",\n \"regenerateText\": \"Los códigos que tenga ahora dejarán de servir.\",\n \"generate\": \"Generar\",\n \"passkeyDialogTitle\": \"Agregar una llave de acceso\",\n \"passkeyDialogText\": \"Una llave de acceso usa la huella, el rostro o el PIN de este equipo o de su teléfono. No se puede robar con una página falsa y le permite entrar sin escribir su contraseña.\",\n \"passkeyName\": \"Nombre para reconocerla (opcional)\",\n \"passkeyNamePlaceholder\": \"Por ejemplo: MacBook del trabajo\",\n \"createPasskey\": \"Crear llave\",\n \"totpDialogTitle\": \"Activar la app autenticadora\",\n \"totpStep1\": \"1. Abra su app (Google Authenticator, Microsoft Authenticator, 1Password…) y escanee este código.\",\n \"totpQrAlt\": \"Código QR para la app autenticadora\",\n \"totpCantScan\": \"¿No puede escanear? Escriba esta clave en su app:\",\n \"totpStep2\": \"2. Escriba el código de 6 dígitos que muestra la app.\",\n \"codeLabel\": \"Código\",\n \"codeRequired\": \"Escriba el código de 6 dígitos.\",\n \"codeFormat\": \"Son 6 dígitos, como aparecen en su app.\",\n \"passkeyAdded\": \"Llave de acceso agregada\",\n \"passkeyRemoved\": \"Llave de acceso quitada\",\n \"appActivated\": \"App autenticadora activada\",\n \"appDeactivated\": \"App autenticadora desactivada\"\n },\n \"recoveryCodes\": {\n \"title\": \"Guarde sus códigos de recuperación\",\n \"warning\": \"Es la única vez que los verá. Con uno de ellos podrá entrar si pierde su teléfono o su llave de acceso; cada uno sirve una sola vez.\",\n \"copyAll\": \"Copiar todos\",\n \"download\": \"Descargar .txt\",\n \"saved\": \"Ya los guardé en un lugar seguro\",\n \"done\": \"Listo\",\n \"fileTitle\": \"{{appName}} · códigos de recuperación\",\n \"fileAccount\": \"Cuenta: {{account}}\",\n \"fileGenerated\": \"Generados: {{date}}\",\n \"fileHowTo\": \"Cada código sirve UNA sola vez para entrar si no tiene su teléfono o su llave de acceso.\",\n \"fileKeepSafe\": \"Guárdelos en un lugar seguro (un gestor de contraseñas o impresos bajo llave).\",\n \"fileName\": \"codigos-recuperacion-{{date}}.txt\"\n },\n \"secondStep\": {\n \"intro\": \"Su cuenta tiene verificación en dos pasos. Confirme que es usted para terminar de entrar.\",\n \"usePasskey\": \"Usar mi llave de acceso\",\n \"or\": \"o\",\n \"appCodeLabel\": \"Código de su app autenticadora\",\n \"appCodeHelp\": \"Ábrala (Google Authenticator, Microsoft Authenticator, 1Password…) y escriba los 6 dígitos.\",\n \"recoveryCodeLabel\": \"Código de recuperación\",\n \"recoveryCodeHelp\": \"Uno de los códigos que guardó al activar la verificación. Cada uno sirve una sola vez.\",\n \"recoveryCodeRequired\": \"Escriba uno de sus códigos de recuperación.\",\n \"recoveryCodeFormat\": \"Tienen la forma ABCDE-FGHJK.\",\n \"confirm\": \"Confirmar\",\n \"useRecovery\": \"No tengo mi teléfono: usar un código de recuperación\",\n \"useApp\": \"Usar el código de mi app autenticadora\",\n \"otherAccount\": \"Entrar con otra cuenta\",\n \"remainingAttempts_one\": \"Le queda {{count}} intento.\",\n \"remainingAttempts_other\": \"Le quedan {{count}} intentos.\"\n },\n \"sessions\": {\n \"title\": \"Mis sesiones\",\n \"description\": \"Dónde tiene la cuenta abierta. Si no reconoce un equipo, cierre la sesión en los demás y cambie su contraseña.\",\n \"current\": \"Este equipo\",\n \"device\": \"{{browser}} en {{platform}}\",\n \"otherBrowser\": \"Otro navegador\",\n \"otherPlatform\": \"otro sistema\",\n \"since\": \"Desde {{date}}\",\n \"network\": \"red {{network}}\",\n \"onlyThis\": \"Solo tiene la sesión abierta en este equipo.\",\n \"closeOthers\": \"Cerrar la sesión en los demás equipos\",\n \"confirmTitle\": \"¿Cerrar la sesión en los demás equipos?\",\n \"confirmText_one\": \"Se cerrará en {{count}} equipo. Este sigue dentro, y en el otro tendrá que volver a entrar con su contraseña.\",\n \"confirmText_other\": \"Se cerrará en {{count}} equipos. Este sigue dentro, y en los demás tendrá que volver a entrar con su contraseña.\",\n \"confirm\": \"Cerrar las demás\",\n \"closed_one\": \"Se cerró la sesión en {{count}} equipo\",\n \"closed_other\": \"Se cerró la sesión en {{count}} equipos\",\n \"noneClosed\": \"No había sesiones abiertas en otros equipos\"\n },\n \"activity\": {\n \"title\": \"Actividad de la cuenta\",\n \"description\": \"Lo último que pasó con su cuenta. Si ve algo que no fue usted, cambie su contraseña y cierre la sesión en los demás equipos.\",\n \"empty\": \"Todavía no hay actividad.\",\n \"from\": \"{{device}} · red {{network}}\",\n \"kinds\": {\n \"signedIn\": \"Entró\",\n \"signInFailed\": \"Intento de entrar con contraseña equivocada\",\n \"signedOut\": \"Salió\",\n \"passwordChanged\": \"Cambió su contraseña\",\n \"twoStepEnabled\": \"Activó la verificación en dos pasos\",\n \"twoStepDisabled\": \"Desactivó la verificación en dos pasos\",\n \"passkeyAdded\": \"Agregó una llave de acceso\",\n \"passkeyRemoved\": \"Quitó una llave de acceso\",\n \"recoveryCodesGenerated\": \"Generó códigos de recuperación nuevos\",\n \"recoveryCodeUsed\": \"Entró con un código de recuperación\",\n \"sessionsClosed\": \"Cerró la sesión en los demás equipos\"\n }\n }\n },\n \"calendar\": {\n \"details\": {\n \"when\": \"Cuándo\",\n \"timeRange\": \"{{date}}, de {{start}} a {{end}}\",\n \"allDay\": \"{{date}}, todo el día\",\n \"location\": \"Dónde\",\n \"meeting\": \"Reunión en línea\",\n \"join\": \"Unirse\",\n \"attendees\": \"Invitados\",\n \"attendeesCount_one\": \"{{count}} invitado\",\n \"attendeesCount_other\": \"{{count}} invitados\",\n \"response\": {\"accepted\": \"Va\", \"declined\": \"No va\", \"pending\": \"Sin responder\"},\n \"reminder\": \"Recordatorio\",\n \"reminderUnit\": {\n \"atStart\": \"Al empezar\",\n \"minutes_one\": \"{{count}} minuto antes\",\n \"minutes_other\": \"{{count}} minutos antes\",\n \"hours_one\": \"{{count}} hora antes\",\n \"hours_other\": \"{{count}} horas antes\",\n \"days_one\": \"{{count}} día antes\",\n \"days_other\": \"{{count}} días antes\"\n },\n \"notes\": \"Notas\"\n },\n \"previous\": \"Anterior\",\n \"next\": \"Siguiente\",\n \"today\": \"Hoy\",\n \"view\": \"Vista del calendario\",\n \"views\": {\n \"month\": \"Mes\",\n \"week\": \"Semana\",\n \"day\": \"Día\",\n \"list\": \"Lista\"\n }\n },\n \"kanban\": {\n \"dueCompleted\": \"Era para el {{date}}\",\n \"complete\": \"Terminar «{{title}}»\",\n \"reopen\": \"Reabrir «{{title}}»\",\n \"completed\": \"Terminada\",\n \"collapseColumn\": \"Encoger «{{column}}»\",\n \"expandColumn\": \"Abrir «{{column}}»\",\n \"addCard\": \"Agregar una tarjeta en {{column}}\",\n \"addCardPlaceholder\": \"Título de la tarjeta (Enter para agregar)\",\n \"cardActions\": \"Acciones de «{{title}}»\",\n \"columnActions\": \"Acciones de {{column}}\",\n \"dueOverdue\": \"Venció el {{date}}\",\n \"dueToday\": \"Vence hoy\",\n \"dueOn\": \"Vence el {{date}}\",\n \"checklist\": \"{{done}} de {{total}} pendientes hechos\",\n \"comments_one\": \"{{count}} comentario\",\n \"comments_other\": \"{{count}} comentarios\",\n \"attachments_one\": \"{{count}} adjunto\",\n \"attachments_other\": \"{{count}} adjuntos\",\n \"assignees\": \"Responsables: {{names}}\",\n \"instructions\": \"Para mover una tarjeta con el teclado: espacio para levantarla, flechas para moverla y espacio para soltarla. Escape la deja donde estaba.\",\n \"lifted\": \"Levantó «{{title}}», en {{column}}, posición {{position}}.\",\n \"moving\": \"Va a {{column}}, posición {{position}}.\",\n \"dropped\": \"Soltó «{{title}}» en {{column}}, posición {{position}}.\",\n \"cancelled\": \"«{{title}}» se quedó donde estaba.\",\n \"overLimit\": \"Pasó el tope de {{limit}} tarjetas.\",\n \"emptyFiltered\": \"Ninguna tarjeta de aquí coincide con la búsqueda.\",\n \"empty\": \"Sin tarjetas. Arrastre una aquí.\"\n },\n \"inbox\": {\n \"labels\": \"Etiquetas\",\n \"select\": \"Elegir «{{subject}}»\",\n \"messageActions\": \"Acciones de «{{subject}}»\",\n \"threadCount_one\": \"{{count}} mensaje en la conversación\",\n \"threadCount_other\": \"{{count}} mensajes en la conversación\",\n \"cc\": \"Con copia: {{cc}}\",\n \"openAttachment\": \"Abrir {{name}}\",\n \"expandMessage\": \"Abrir el mensaje de {{name}} ({{date}})\",\n \"listLabel\": \"Mensajes\",\n \"folders\": \"Carpetas\",\n \"empty\": \"No hay mensajes aquí.\",\n \"noMessageSelected\": \"Elija un mensaje para leerlo.\",\n \"star\": \"Destacar\",\n \"unstar\": \"Quitar de destacados\",\n \"unread\": \"Sin leer\",\n \"attachments\": \"Archivos adjuntos\",\n \"to\": \"Para: {{to}}\",\n \"back\": \"Regresar\",\n \"unreadCount_one\": \"{{count}} sin leer\",\n \"unreadCount_other\": \"{{count}} sin leer\"\n },\n \"account\": {\n \"reset\": {\n \"title\": \"Elegir una contraseña nueva\",\n \"subtitle\": \"Llegó aquí desde el enlace del correo. Elija la contraseña con la que va a entrar.\",\n \"done\": \"Ya puede entrar con su contraseña nueva.\",\n \"goToSignIn\": \"Ir a iniciar sesión\",\n \"missingToken\": \"Este enlace no sirve: le falta su clave. Pida uno nuevo desde «¿Olvidó su contraseña?».\",\n \"askAgain\": \"Pedir otro enlace\"\n },\n \"profile\": {\n \"tabs\": {\n \"label\": \"Partes de su perfil\",\n \"data\": \"Sus datos\",\n \"security\": \"Seguridad\",\n \"preferences\": \"Preferencias\"\n },\n \"data\": {\n \"title\": \"Sus datos\",\n \"text\": \"Así le ven las demás personas en la app.\",\n \"name\": \"Nombre\",\n \"email\": \"Correo\",\n \"emailHelp\": \"Es el correo con el que entra; para cambiarlo, pídalo a quien administra la app.\",\n \"phone\": \"Teléfono (opcional)\",\n \"phoneInvalid\": \"Escriba solo dígitos (de 7 a 15), con + al inicio si es de otro país.\",\n \"save\": \"Guardar\",\n \"saved\": \"Se guardaron sus datos.\"\n },\n \"password\": {\n \"title\": \"Contraseña\",\n \"text\": \"Use una contraseña que no use en otros sitios. Al cambiarla, la próxima vez entra con la nueva.\"\n },\n \"preferences\": {\n \"title\": \"Apariencia\",\n \"text\": \"Cómo se ve la app para usted: el tamaño de letra, el idioma y claro u oscuro se recuerdan en este navegador.\"\n }\n },\n \"demo\": {\n \"totpCode\": \"Usar el código de ejemplo\",\n \"totpCodeHelp\": \"Solo en la demostración: llena el código que enseñaría su app ahorita, por si no la tiene a la mano.\",\n \"passkeyNote\": \"En la demostración la llave se guarda de verdad en su llavero (iCloud, Google o su gestor de contraseñas), pero esta página la olvida al recargar. Cuando termine de probar, bórrela también de su llavero.\",\n \"securityNote\": \"Servidor de demostración: la verificación funciona con su teléfono de verdad (escanee el QR o cree una llave con su huella), pero vive en la memoria de la pestaña: al recargar se apaga. Salga y vuelva a entrar para ver el segundo paso.\",\n \"server\": {\n \"wrongCredentialsTitle\": \"No pudo entrar\",\n \"wrongCredentials\": \"En la demostración se entra con {{email}} y cualquier contraseña.\",\n \"noSessionTitle\": \"Su sesión terminó\",\n \"noSession\": \"Vuelva a entrar.\",\n \"validationTitle\": \"Revise los datos\",\n \"validationDetail\": \"Hay campos por corregir.\",\n \"passwordRequired\": \"Escriba su contraseña para confirmar.\",\n \"nameRequired\": \"Escriba su nombre.\",\n \"wrongCodeTitle\": \"El código no coincide\",\n \"wrongCode\": \"Revise que sea el código que enseña su app ahorita.\",\n \"expiredTitle\": \"Se acabó el tiempo\",\n \"expired\": \"Pasaron más de 5 minutos: vuelva a escribir su contraseña.\",\n \"lockedTitle\": \"Demasiados intentos\",\n \"locked\": \"Por seguridad hay que empezar de nuevo: vuelva a escribir su contraseña.\",\n \"defaultPasskeyName\": \"Llave {{number}}\",\n \"profileSaved\": \"Se guardaron sus datos.\"\n }\n }\n }\n});\n"],"names":[],"mappings":"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"}
@@ -1,9 +1,9 @@
1
1
  "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
3
3
  import "leaflet/dist/leaflet.css";
4
4
  import { useRef, useMemo, useEffect } from "react";
5
5
  import L from "leaflet";
6
- import { MapContainer, TileLayer, Marker, Popup, useMap } from "react-leaflet";
6
+ import { MapContainer, TileLayer, Marker, Popup, useMapEvents, useMap } from "react-leaflet";
7
7
  import Box from "@mui/material/Box";
8
8
  import Typography from "@mui/material/Typography";
9
9
  import { useTheme } from "@mui/material/styles";
@@ -40,7 +40,28 @@ function FlyToSelected({ selectedMarker, markerRefs }) {
40
40
  }, [map, selectedMarker, markerRefs]);
41
41
  return null;
42
42
  }
43
- function MapView({ markers, selectedId = null, onSelect, ariaLabel, height = DEFAULT_HEIGHT_PIXELS, tileLayer = OPEN_STREET_MAP_TILES }) {
43
+ function MapClicks({ onMapClick }) {
44
+ useMapEvents({ click: (event) => onMapClick([event.latlng.lat, event.latlng.lng]) });
45
+ return null;
46
+ }
47
+ function DefaultPopupContent({ marker }) {
48
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
49
+ /* @__PURE__ */ jsx(Typography, { variant: "subtitle2", component: "p", children: marker.title }),
50
+ marker.description && /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", component: "p", sx: { m: 0 }, children: marker.description })
51
+ ] });
52
+ }
53
+ function MapView({
54
+ markers,
55
+ selectedId = null,
56
+ onSelect,
57
+ ariaLabel,
58
+ height = DEFAULT_HEIGHT_PIXELS,
59
+ tileLayer = OPEN_STREET_MAP_TILES,
60
+ renderPopup,
61
+ onMapClick,
62
+ children,
63
+ mapProps
64
+ }) {
44
65
  const theme = useTheme();
45
66
  const palette = paletteOf(theme);
46
67
  const markerRefs = useRef(/* @__PURE__ */ new Map());
@@ -66,8 +87,10 @@ function MapView({ markers, selectedId = null, onSelect, ariaLabel, height = DEF
66
87
  "& .leaflet-control-attribution": { bgcolor: "background.paper", color: "text.secondary", "& a": { color: "inherit" } },
67
88
  // OpenStreetMap solo da mosaicos claros: en oscuro se invierten y se regresa el tono (el agua sigue azul)
68
89
  ...currentTheme.applyStyles("dark", { "& .leaflet-tile-pane": { filter: "invert(1) hue-rotate(180deg) brightness(0.95) contrast(0.9)" } })
69
- }), children: /* @__PURE__ */ jsxs(MapContainer, { center: markers[0]?.position ?? DEFAULT_CENTER, zoom: DEFAULT_ZOOM, scrollWheelZoom: false, children: [
90
+ }), children: /* @__PURE__ */ jsxs(MapContainer, { center: markers[0]?.position ?? DEFAULT_CENTER, zoom: DEFAULT_ZOOM, scrollWheelZoom: false, ...mapProps, children: [
70
91
  /* @__PURE__ */ jsx(TileLayer, { url: tileLayer.url, attribution: tileLayer.attribution }),
92
+ onMapClick && /* @__PURE__ */ jsx(MapClicks, { onMapClick }),
93
+ children,
71
94
  /* @__PURE__ */ jsx(FitToMarkers, { bounds }),
72
95
  /* @__PURE__ */ jsx(FlyToSelected, { selectedMarker, markerRefs }),
73
96
  markers.map((marker) => /* @__PURE__ */ jsx(
@@ -80,10 +103,7 @@ function MapView({ markers, selectedId = null, onSelect, ariaLabel, height = DEF
80
103
  zIndexOffset: marker.id === selectedId ? 1e3 : 0,
81
104
  ref: (leafletMarker) => leafletMarker ? markerRefs.current.set(marker.id, leafletMarker) : markerRefs.current.delete(marker.id),
82
105
  eventHandlers: { click: () => onSelect?.(marker.id) },
83
- children: /* @__PURE__ */ jsxs(Popup, { children: [
84
- /* @__PURE__ */ jsx(Typography, { variant: "subtitle2", component: "p", children: marker.title }),
85
- marker.description && /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", component: "p", sx: { m: 0 }, children: marker.description })
86
- ] })
106
+ children: /* @__PURE__ */ jsx(Popup, { children: renderPopup ? renderPopup(marker) : /* @__PURE__ */ jsx(DefaultPopupContent, { marker }) })
87
107
  },
88
108
  marker.id
89
109
  ))
@@ -1 +1 @@
1
- {"version":3,"file":"MapView.js","sources":["../../src/maps/MapView.jsx"],"sourcesContent":["// Un mapa con marcadores (@stackcraftmx/calcita/maps): Leaflet con los mosaicos de OpenStreetMap. Cada marcador es un\n// alfiler del color del tema (mapMarkers.js); el elegido va más grande, el mapa vuela a él y abre su globo. Al cambiar los\n// marcadores, el mapa se acomoda para que se vean todos.\n//\n// <MapView markers={[{id: 'gdl', position: [20.67, -103.35], title: 'Sucursal Guadalajara', tone: 'success'}]}\n// selectedId={selectedId} onSelect={setSelectedId} ariaLabel=\"Mapa de sucursales\" />\n//\n// En oscuro los mosaicos se oscurecen con un filtro (OpenStreetMap solo los da claros). Los mosaicos públicos de\n// OpenStreetMap son para poco tráfico y piden su crédito: para mucho uso, un proveedor propio en tileLayer.\n//\n// OJO, Next.js: Leaflet usa window al cargarse; en Next se importa con next/dynamic y ssr: false.\n//\n// Genérico del paquete: function (regla de la casa).\nimport 'leaflet/dist/leaflet.css';\nimport {useEffect, useMemo, useRef} from 'react';\nimport L from 'leaflet';\nimport {MapContainer, Marker, Popup, TileLayer, useMap} from 'react-leaflet';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport {useTheme} from '@mui/material/styles';\n\nimport {MAP_PIN_SIZE, boundsOfMarkers, mapPinHtmlOf} from '@/maps/mapMarkers.js';\nimport {paletteOf} from '@/theme/components/paletteOf.js';\n\n/** Los mosaicos de OpenStreetMap con su crédito (lo pide su política de uso). */\nexport const OPEN_STREET_MAP_TILES = Object.freeze({\n url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',\n attribution: '&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a>',\n});\n\n// México completo cuando no hay marcadores\nconst DEFAULT_CENTER = Object.freeze([23.6, -102.5]);\nconst DEFAULT_ZOOM = 5;\n// al volar a un marcador elegido, al menos este acercamiento\nconst SELECTED_ZOOM = 13;\n// al acomodar el mapa a los marcadores: el margen (px) y que no se acerque de más con uno solo\nconst FIT_PADDING_PIXELS = 48;\nconst FIT_MAX_ZOOM = 13;\nconst DEFAULT_HEIGHT_PIXELS = 420;\n\n/**\n * Acomoda el mapa para que se vean todos los marcadores cada vez que cambian.\n *\n * @param {{bounds: [[number, number], [number, number]]|null}} props\n */\nfunction FitToMarkers({bounds}) {\n const map = useMap();\n const boundsKey = JSON.stringify(bounds);\n useEffect(() => {\n if (bounds) {\n map.fitBounds(bounds, {padding: [FIT_PADDING_PIXELS, FIT_PADDING_PIXELS], maxZoom: FIT_MAX_ZOOM});\n }\n // OJO: depende del texto del recuadro y no del arreglo: el arreglo es nuevo en cada pintada y el mapa se movería solo\n }, [map, boundsKey]);\n return null;\n}\n\n/**\n * Vuela al marcador elegido y abre su globo.\n *\n * @param {{selectedMarker: object|undefined, markerRefs: object}} props\n */\nfunction FlyToSelected({selectedMarker, markerRefs}) {\n const map = useMap();\n useEffect(() => {\n if (!selectedMarker) {\n return;\n }\n map.flyTo(selectedMarker.position, Math.max(map.getZoom(), SELECTED_ZOOM));\n markerRefs.current.get(selectedMarker.id)?.openPopup();\n }, [map, selectedMarker, markerRefs]);\n return null;\n}\n\n/**\n * @param {object} props\n * @param {Array<{id: string, position: [number, number], title: string, description?: string, tone?: string}>} props.markers\n * tone: un color del tema (primary, success, warning, error, info…); por omisión primary\n * @param {string|null} [props.selectedId]\n * @param {(markerId: string) => void} [props.onSelect] al picar un marcador\n * @param {string} props.ariaLabel ya traducido: qué enseña el mapa\n * @param {number} [props.height] px\n * @param {{url: string, attribution: string}} [props.tileLayer] por omisión OpenStreetMap\n */\nexport default function MapView({markers, selectedId = null, onSelect, ariaLabel, height = DEFAULT_HEIGHT_PIXELS, tileLayer = OPEN_STREET_MAP_TILES}) {\n const theme = useTheme();\n const palette = paletteOf(theme);\n const markerRefs = useRef(new Map());\n const bounds = useMemo(() => boundsOfMarkers(markers), [markers]);\n const selectedMarker = markers.find((marker) => marker.id === selectedId);\n\n // el ícono de cada marcador: se arma de nuevo solo si cambia su color o si se elige\n const iconOf = (marker) => {\n const isSelected = marker.id === selectedId;\n const size = isSelected ? MAP_PIN_SIZE.selected : MAP_PIN_SIZE.normal;\n const color = (palette[marker.tone] ?? palette.primary).main;\n return L.divIcon({html: mapPinHtmlOf(color, isSelected), className: '', iconSize: [size, size], iconAnchor: [size / 2, size], popupAnchor: [0, -size]});\n };\n\n return (\n <Box role=\"region\" aria-label={ariaLabel} sx={(currentTheme) => ({\n height, borderRadius: 3, overflow: 'hidden', position: 'relative', zIndex: 0,\n '& .leaflet-container': {height: '100%', width: '100%', fontFamily: 'inherit', bgcolor: 'action.hover'},\n '& .leaflet-bar': {border: 0, borderRadius: '10px', overflow: 'hidden', boxShadow: currentTheme.shadows[2]},\n '& .leaflet-bar a': {bgcolor: 'background.paper', color: 'text.primary', borderBottomColor: 'divider'},\n '& .leaflet-popup-content-wrapper, & .leaflet-popup-tip': {bgcolor: 'background.paper', color: 'text.primary'},\n '& .leaflet-popup-content-wrapper': {borderRadius: '12px'},\n '& .leaflet-control-attribution': {bgcolor: 'background.paper', color: 'text.secondary', '& a': {color: 'inherit'}},\n // OpenStreetMap solo da mosaicos claros: en oscuro se invierten y se regresa el tono (el agua sigue azul)\n ...currentTheme.applyStyles('dark', {'& .leaflet-tile-pane': {filter: 'invert(1) hue-rotate(180deg) brightness(0.95) contrast(0.9)'}}),\n })}>\n <MapContainer center={markers[0]?.position ?? DEFAULT_CENTER} zoom={DEFAULT_ZOOM} scrollWheelZoom={false}>\n <TileLayer url={tileLayer.url} attribution={tileLayer.attribution} />\n <FitToMarkers bounds={bounds} />\n <FlyToSelected selectedMarker={selectedMarker} markerRefs={markerRefs} />\n {markers.map((marker) => (\n <Marker key={marker.id} position={marker.position} icon={iconOf(marker)} title={marker.title} alt={marker.title}\n zIndexOffset={marker.id === selectedId ? 1000 : 0}\n ref={(leafletMarker) => (leafletMarker ? markerRefs.current.set(marker.id, leafletMarker) : markerRefs.current.delete(marker.id))}\n eventHandlers={{click: () => onSelect?.(marker.id)}}>\n <Popup>\n <Typography variant=\"subtitle2\" component=\"p\">{marker.title}</Typography>\n {marker.description && <Typography variant=\"body2\" color=\"text.secondary\" component=\"p\" sx={{m: 0}}>{marker.description}</Typography>}\n </Popup>\n </Marker>\n ))}\n </MapContainer>\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MapView.js","sources":["../../src/maps/MapView.jsx"],"sourcesContent":["// Un mapa con marcadores (@stackcraftmx/calcita/maps): Leaflet con los mosaicos de OpenStreetMap. Cada marcador es un\n// alfiler del color del tema (mapMarkers.js); el elegido va más grande, el mapa vuela a él y abre su globo. Al cambiar los\n// marcadores, el mapa se acomoda para que se vean todos.\n//\n// <MapView markers={[{id: 'gdl', position: [20.67, -103.35], title: 'Sucursal Guadalajara', tone: 'success'}]}\n// selectedId={selectedId} onSelect={setSelectedId} ariaLabel=\"Mapa de sucursales\" />\n//\n// En oscuro los mosaicos se oscurecen con un filtro (OpenStreetMap solo los da claros). Los mosaicos públicos de\n// OpenStreetMap son para poco tráfico y piden su crédito: para mucho uso, un proveedor propio en tileLayer.\n//\n// Se extiende sin tocar el framework: cualquier contenido en el globo (renderPopup: un estado, un botón, una foto, «Cómo\n// llegar»), capas propias de react-leaflet adentro (children: zonas de entrega, un radio), el clic en el mapa (onMapClick:\n// agregar un punto) y lo demás de MapContainer de Leaflet (mapProps).\n//\n// OJO, Next.js: Leaflet usa window al cargarse; en Next se importa con next/dynamic y ssr: false.\n//\n// Genérico del paquete: function (regla de la casa).\nimport 'leaflet/dist/leaflet.css';\nimport {useEffect, useMemo, useRef} from 'react';\nimport L from 'leaflet';\nimport {MapContainer, Marker, Popup, TileLayer, useMap, useMapEvents} from 'react-leaflet';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport {useTheme} from '@mui/material/styles';\n\nimport {MAP_PIN_SIZE, boundsOfMarkers, mapPinHtmlOf} from '@/maps/mapMarkers.js';\nimport {paletteOf} from '@/theme/components/paletteOf.js';\n\n/** Los mosaicos de OpenStreetMap con su crédito (lo pide su política de uso). */\nexport const OPEN_STREET_MAP_TILES = Object.freeze({\n url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',\n attribution: '&copy; <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a>',\n});\n\n// México completo cuando no hay marcadores\nconst DEFAULT_CENTER = Object.freeze([23.6, -102.5]);\nconst DEFAULT_ZOOM = 5;\n// al volar a un marcador elegido, al menos este acercamiento\nconst SELECTED_ZOOM = 13;\n// al acomodar el mapa a los marcadores: el margen (px) y que no se acerque de más con uno solo\nconst FIT_PADDING_PIXELS = 48;\nconst FIT_MAX_ZOOM = 13;\nconst DEFAULT_HEIGHT_PIXELS = 420;\n\n/**\n * Acomoda el mapa para que se vean todos los marcadores cada vez que cambian.\n *\n * @param {{bounds: [[number, number], [number, number]]|null}} props\n */\nfunction FitToMarkers({bounds}) {\n const map = useMap();\n const boundsKey = JSON.stringify(bounds);\n useEffect(() => {\n if (bounds) {\n map.fitBounds(bounds, {padding: [FIT_PADDING_PIXELS, FIT_PADDING_PIXELS], maxZoom: FIT_MAX_ZOOM});\n }\n // OJO: depende del texto del recuadro y no del arreglo: el arreglo es nuevo en cada pintada y el mapa se movería solo\n }, [map, boundsKey]);\n return null;\n}\n\n/**\n * Vuela al marcador elegido y abre su globo.\n *\n * @param {{selectedMarker: object|undefined, markerRefs: object}} props\n */\nfunction FlyToSelected({selectedMarker, markerRefs}) {\n const map = useMap();\n useEffect(() => {\n if (!selectedMarker) {\n return;\n }\n map.flyTo(selectedMarker.position, Math.max(map.getZoom(), SELECTED_ZOOM));\n markerRefs.current.get(selectedMarker.id)?.openPopup();\n }, [map, selectedMarker, markerRefs]);\n return null;\n}\n\n/**\n * Avisa cada clic en el mapa (fuera de un marcador) con su posición.\n *\n * @param {{onMapClick: (position: [number, number]) => void}} props\n */\nfunction MapClicks({onMapClick}) {\n useMapEvents({click: (event) => onMapClick([event.latlng.lat, event.latlng.lng])});\n return null;\n}\n\n/**\n * Lo que dice el globo de un marcador cuando la pantalla no da el suyo: su título y su descripción.\n *\n * @param {{marker: {title: string, description?: string}}} props\n */\nfunction DefaultPopupContent({marker}) {\n return (\n <>\n <Typography variant=\"subtitle2\" component=\"p\">{marker.title}</Typography>\n {marker.description && <Typography variant=\"body2\" color=\"text.secondary\" component=\"p\" sx={{m: 0}}>{marker.description}</Typography>}\n </>\n );\n}\n\n/**\n * @param {object} props\n * @param {Array<{id: string, position: [number, number], title: string, description?: string, tone?: string} & Record<string, any>>} props.markers\n * tone: un color del tema (primary, success, warning, error, info…); por omisión primary\n * @param {string|null} [props.selectedId]\n * @param {(markerId: string) => void} [props.onSelect] al picar un marcador\n * @param {string} props.ariaLabel ya traducido: qué enseña el mapa\n * @param {number} [props.height] px\n * @param {{url: string, attribution: string}} [props.tileLayer] por omisión OpenStreetMap\n * @param {(marker: any) => import('react').ReactNode} [props.renderPopup] lo que dice el globo de un marcador (recibe el\n * marcador tal cual, con sus campos propios); por omisión su título y su descripción\n * @param {(position: [number, number]) => void} [props.onMapClick] al picar el mapa fuera de un marcador\n * @param {import('react').ReactNode} [props.children] capas propias de react-leaflet (Circle, Polygon, GeoJSON…)\n * @param {object} [props.mapProps] lo demás de MapContainer de react-leaflet (scrollWheelZoom, minZoom…)\n */\nexport default function MapView({\n markers, selectedId = null, onSelect, ariaLabel, height = DEFAULT_HEIGHT_PIXELS, tileLayer = OPEN_STREET_MAP_TILES, renderPopup, onMapClick,\n children, mapProps,\n}) {\n const theme = useTheme();\n const palette = paletteOf(theme);\n const markerRefs = useRef(new Map());\n const bounds = useMemo(() => boundsOfMarkers(markers), [markers]);\n const selectedMarker = markers.find((marker) => marker.id === selectedId);\n\n // el ícono de cada marcador: se arma de nuevo solo si cambia su color o si se elige\n const iconOf = (marker) => {\n const isSelected = marker.id === selectedId;\n const size = isSelected ? MAP_PIN_SIZE.selected : MAP_PIN_SIZE.normal;\n const color = (palette[marker.tone] ?? palette.primary).main;\n return L.divIcon({html: mapPinHtmlOf(color, isSelected), className: '', iconSize: [size, size], iconAnchor: [size / 2, size], popupAnchor: [0, -size]});\n };\n\n return (\n <Box role=\"region\" aria-label={ariaLabel} sx={(currentTheme) => ({\n height, borderRadius: 3, overflow: 'hidden', position: 'relative', zIndex: 0,\n '& .leaflet-container': {height: '100%', width: '100%', fontFamily: 'inherit', bgcolor: 'action.hover'},\n '& .leaflet-bar': {border: 0, borderRadius: '10px', overflow: 'hidden', boxShadow: currentTheme.shadows[2]},\n '& .leaflet-bar a': {bgcolor: 'background.paper', color: 'text.primary', borderBottomColor: 'divider'},\n '& .leaflet-popup-content-wrapper, & .leaflet-popup-tip': {bgcolor: 'background.paper', color: 'text.primary'},\n '& .leaflet-popup-content-wrapper': {borderRadius: '12px'},\n '& .leaflet-control-attribution': {bgcolor: 'background.paper', color: 'text.secondary', '& a': {color: 'inherit'}},\n // OpenStreetMap solo da mosaicos claros: en oscuro se invierten y se regresa el tono (el agua sigue azul)\n ...currentTheme.applyStyles('dark', {'& .leaflet-tile-pane': {filter: 'invert(1) hue-rotate(180deg) brightness(0.95) contrast(0.9)'}}),\n })}>\n <MapContainer center={markers[0]?.position ?? DEFAULT_CENTER} zoom={DEFAULT_ZOOM} scrollWheelZoom={false} {...mapProps}>\n <TileLayer url={tileLayer.url} attribution={tileLayer.attribution} />\n {onMapClick && <MapClicks onMapClick={onMapClick} />}\n {children}\n <FitToMarkers bounds={bounds} />\n <FlyToSelected selectedMarker={selectedMarker} markerRefs={markerRefs} />\n {markers.map((marker) => (\n <Marker key={marker.id} position={marker.position} icon={iconOf(marker)} title={marker.title} alt={marker.title}\n zIndexOffset={marker.id === selectedId ? 1000 : 0}\n ref={(leafletMarker) => (leafletMarker ? markerRefs.current.set(marker.id, leafletMarker) : markerRefs.current.delete(marker.id))}\n eventHandlers={{click: () => onSelect?.(marker.id)}}>\n <Popup>\n {renderPopup ? renderPopup(marker) : <DefaultPopupContent marker={marker} />}\n </Popup>\n </Marker>\n ))}\n </MapContainer>\n </Box>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -13,6 +13,7 @@ function reloadPage() {
13
13
  }
14
14
  function usePublishedBuildWatch({
15
15
  url = null,
16
+ buildId,
16
17
  checkEveryMinutes = DEFAULT_CHECK_EVERY_MINUTES,
17
18
  reloadAfterHiddenMinutes = DEFAULT_RELOAD_AFTER_HIDDEN_MINUTES,
18
19
  onReload = reloadPage
@@ -32,7 +33,7 @@ function usePublishedBuildWatch({
32
33
  const response = await fetch(url, { cache: "no-store", headers: { Accept: "application/json" } });
33
34
  const publishedBuildId = response.ok ? publishedBuildIdOf(await response.json()) : null;
34
35
  const action = buildWatchActionOf({
35
- runningBuildId: toolkitSettings().buildId,
36
+ runningBuildId: buildId ?? toolkitSettings().buildId,
36
37
  publishedBuildId,
37
38
  hiddenMilliseconds,
38
39
  reloadAfterHiddenMilliseconds: reloadAfterHiddenMinutes === null ? null : reloadAfterHiddenMinutes * MILLISECONDS_PER_MINUTE
@@ -40,7 +41,7 @@ function usePublishedBuildWatch({
40
41
  if (action === BUILD_WATCH_ACTION.reload) {
41
42
  onReload();
42
43
  } else if (action === BUILD_WATCH_ACTION.notice) {
43
- reportPublishedBuild(publishedBuildId);
44
+ reportPublishedBuild(publishedBuildId, buildId ?? toolkitSettings().buildId);
44
45
  }
45
46
  } catch (error) {
46
47
  log.info("No se pudo revisar la versión publicada", { url, reason: error.message });
@@ -68,7 +69,7 @@ function usePublishedBuildWatch({
68
69
  window.clearInterval(timer);
69
70
  document.removeEventListener("visibilitychange", handleVisibilityChange);
70
71
  };
71
- }, [url, checkEveryMinutes, reloadAfterHiddenMinutes, onReload]);
72
+ }, [url, buildId, checkEveryMinutes, reloadAfterHiddenMinutes, onReload]);
72
73
  }
73
74
  export {
74
75
  usePublishedBuildWatch
@@ -1 +1 @@
1
- {"version":3,"file":"usePublishedBuildWatch.js","sources":["../../src/observability/usePublishedBuildWatch.js"],"sourcesContent":["// Que la app se entere sola de que se publicó otra versión del front, sin depender del API. Hace falta sobre todo con la\n// app anclada al inicio del iPhone: al abrirla, el iPhone NO vuelve a pedir la página, retoma la que tenía en memoria (aunque\n// haya pasado un día), así que la persona se quedaba con la versión vieja hasta cerrarla a la fuerza.\n//\n// Cómo: al construir, el proyecto deja un archivo con su versión ({\"buildId\": \"…\"}, por omisión /version.json) y la misma\n// versión en ToolkitProvider (buildId). Esta app vuelve a leer el archivo:\n// - cada vez que regresa del segundo plano (justo cuando el iPhone la despierta), y\n// - cada tanto mientras se usa (checkEveryMinutes).\n// Si ya hay otra (buildWatchActionOf): si estuvo fuera al menos reloadAfterHiddenMinutes, se recarga sola; si no, sale el\n// aviso «Hay una versión nueva · Actualizar» (NewBuildNotice, que el marco ya pinta) para no borrar lo que llevaba escrito.\n//\n// Se monta UNA vez, en la raíz de la app:\n// usePublishedBuildWatch({url: import.meta.env.PROD ? '/version.json' : null});\n// Sin url no hace nada (en desarrollo no hay versión que comparar).\n//\n// OJO: el archivo se pide con cache 'no-store' y el servidor no debe guardarlo (en el nginx de los ejemplos, «location /»\n// ya va con no-cache). Sin red (el teléfono en el metro) no pasa nada: se vuelve a intentar en la siguiente revisión.\n//\n// Gancho genérico del paquete: function (regla de la casa).\nimport {useEffect} from 'react';\n\nimport {BUILD_WATCH_ACTION, buildWatchActionOf, publishedBuildIdOf} from '@/observability/buildWatch.js';\nimport {createLogger} from '@/observability/logger.js';\nimport {reportPublishedBuild} from '@/observability/publishedBuild.js';\nimport {toolkitSettings} from '@/toolkit/toolkitSettings.js';\n\nconst log = createLogger('build-watch');\nconst MILLISECONDS_PER_MINUTE = 60 * 1000;\n// por omisión: revisar cada 5 minutos mientras se usa, y recargar sola si estuvo fuera 15 minutos o más\nconst DEFAULT_CHECK_EVERY_MINUTES = 5;\nconst DEFAULT_RELOAD_AFTER_HIDDEN_MINUTES = 15;\n\n/** Lo que hace si el proyecto no dice otra cosa: recargar la página, que trae la versión nueva. */\nfunction reloadPage() {\n window.location.reload();\n}\n\n/**\n * @param {object} [options]\n * @param {string|null} [options.url] dónde está el archivo de versión ({\"buildId\": \"…\"}); null: no vigila\n * @param {number} [options.checkEveryMinutes] cada cuánto revisa mientras se usa; por omisión 5\n * @param {number|null} [options.reloadAfterHiddenMinutes] desde cuántos minutos fuera se recarga sola al volver; por\n * omisión 15. null: nunca se recarga sola, siempre el aviso\n * @param {() => void} [options.onReload] cómo recargar (p. ej. guardar un borrador antes). OJO: con useCallback; una\n * función nueva en cada pintada volvería a armar la vigilancia\n * @returns {void}\n */\nexport function usePublishedBuildWatch({\n url = null, checkEveryMinutes = DEFAULT_CHECK_EVERY_MINUTES, reloadAfterHiddenMinutes = DEFAULT_RELOAD_AFTER_HIDDEN_MINUTES, onReload = reloadPage,\n} = {}) {\n useEffect(() => {\n if (!url || typeof document === 'undefined') {\n return undefined;\n }\n let hiddenSince = null;\n let isChecking = false;\n\n const check = async (hiddenMilliseconds = 0) => {\n // una revisión a la vez: al volver del segundo plano pueden llegar dos avisos del navegador juntos\n if (isChecking) {\n return;\n }\n isChecking = true;\n try {\n const response = await fetch(url, {cache: 'no-store', headers: {Accept: 'application/json'}});\n const publishedBuildId = response.ok ? publishedBuildIdOf(await response.json()) : null;\n const action = buildWatchActionOf({\n runningBuildId: toolkitSettings().buildId,\n publishedBuildId,\n hiddenMilliseconds,\n reloadAfterHiddenMilliseconds: reloadAfterHiddenMinutes === null ? null : reloadAfterHiddenMinutes * MILLISECONDS_PER_MINUTE,\n });\n if (action === BUILD_WATCH_ACTION.reload) {\n onReload();\n } else if (action === BUILD_WATCH_ACTION.notice) {\n reportPublishedBuild(publishedBuildId);\n }\n } catch (error) {\n // sin red o con un archivo que no es JSON: no es algo que la persona pueda arreglar; queda en el registro\n log.info('No se pudo revisar la versión publicada', {url, reason: error.message});\n } finally {\n isChecking = false;\n }\n };\n\n // al irse a segundo plano se anota la hora; al volver se revisa con cuánto tiempo estuvo fuera\n const handleVisibilityChange = () => {\n if (document.visibilityState === 'hidden') {\n hiddenSince = Date.now();\n return;\n }\n const hiddenMilliseconds = hiddenSince === null ? 0 : Date.now() - hiddenSince;\n hiddenSince = null;\n check(hiddenMilliseconds);\n };\n // mientras se usa (en segundo plano el teléfono detiene los relojes de la página de todos modos)\n const timer = window.setInterval(() => {\n if (document.visibilityState === 'visible') {\n check();\n }\n }, checkEveryMinutes * MILLISECONDS_PER_MINUTE);\n\n check();\n document.addEventListener('visibilitychange', handleVisibilityChange);\n return () => {\n window.clearInterval(timer);\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n };\n }, [url, checkEveryMinutes, reloadAfterHiddenMinutes, onReload]);\n}\n"],"names":[],"mappings":";;;;;;AA0BA,MAAM,MAAM,aAAa,aAAa;AACtC,MAAM,0BAA0B,KAAK;AAErC,MAAM,8BAA8B;AACpC,MAAM,sCAAsC;AAG5C,SAAS,aAAa;AAClB,SAAO,SAAS,OAAA;AACpB;AAYO,SAAS,uBAAuB;AAAA,EACnC,MAAM;AAAA,EAAM,oBAAoB;AAAA,EAA6B,2BAA2B;AAAA,EAAqC,WAAW;AAC5I,IAAI,IAAI;AACJ,YAAU,MAAM;AACZ,QAAI,CAAC,OAAO,OAAO,aAAa,aAAa;AACzC,aAAO;AAAA,IACX;AACA,QAAI,cAAc;AAClB,QAAI,aAAa;AAEjB,UAAM,QAAQ,OAAO,qBAAqB,MAAM;AAE5C,UAAI,YAAY;AACZ;AAAA,MACJ;AACA,mBAAa;AACb,UAAI;AACA,cAAM,WAAW,MAAM,MAAM,KAAK,EAAC,OAAO,YAAY,SAAS,EAAC,QAAQ,mBAAA,EAAkB,CAAE;AAC5F,cAAM,mBAAmB,SAAS,KAAK,mBAAmB,MAAM,SAAS,KAAA,CAAM,IAAI;AACnF,cAAM,SAAS,mBAAmB;AAAA,UAC9B,gBAAgB,kBAAkB;AAAA,UAClC;AAAA,UACA;AAAA,UACA,+BAA+B,6BAA6B,OAAO,OAAO,2BAA2B;AAAA,QAAA,CACxG;AACD,YAAI,WAAW,mBAAmB,QAAQ;AACtC,mBAAA;AAAA,QACJ,WAAW,WAAW,mBAAmB,QAAQ;AAC7C,+BAAqB,gBAAgB;AAAA,QACzC;AAAA,MACJ,SAAS,OAAO;AAEZ,YAAI,KAAK,2CAA2C,EAAC,KAAK,QAAQ,MAAM,SAAQ;AAAA,MACpF,UAAA;AACI,qBAAa;AAAA,MACjB;AAAA,IACJ;AAGA,UAAM,yBAAyB,MAAM;AACjC,UAAI,SAAS,oBAAoB,UAAU;AACvC,sBAAc,KAAK,IAAA;AACnB;AAAA,MACJ;AACA,YAAM,qBAAqB,gBAAgB,OAAO,IAAI,KAAK,QAAQ;AACnE,oBAAc;AACd,YAAM,kBAAkB;AAAA,IAC5B;AAEA,UAAM,QAAQ,OAAO,YAAY,MAAM;AACnC,UAAI,SAAS,oBAAoB,WAAW;AACxC,cAAA;AAAA,MACJ;AAAA,IACJ,GAAG,oBAAoB,uBAAuB;AAE9C,UAAA;AACA,aAAS,iBAAiB,oBAAoB,sBAAsB;AACpE,WAAO,MAAM;AACT,aAAO,cAAc,KAAK;AAC1B,eAAS,oBAAoB,oBAAoB,sBAAsB;AAAA,IAC3E;AAAA,EACJ,GAAG,CAAC,KAAK,mBAAmB,0BAA0B,QAAQ,CAAC;AACnE;"}
1
+ {"version":3,"file":"usePublishedBuildWatch.js","sources":["../../src/observability/usePublishedBuildWatch.js"],"sourcesContent":["// Que la app se entere sola de que se publicó otra versión del front, sin depender del API. Hace falta sobre todo con la\n// app anclada al inicio del iPhone: al abrirla, el iPhone NO vuelve a pedir la página, retoma la que tenía en memoria (aunque\n// haya pasado un día), así que la persona se quedaba con la versión vieja hasta cerrarla a la fuerza.\n//\n// Cómo: al construir, el proyecto deja un archivo con su versión ({\"buildId\": \"…\"}, por omisión /version.json) y la misma\n// versión en ToolkitProvider (buildId). Esta app vuelve a leer el archivo:\n// - cada vez que regresa del segundo plano (justo cuando el iPhone la despierta), y\n// - cada tanto mientras se usa (checkEveryMinutes).\n// Si ya hay otra (buildWatchActionOf): si estuvo fuera al menos reloadAfterHiddenMinutes, se recarga sola; si no, sale el\n// aviso «Hay una versión nueva · Actualizar» (NewBuildNotice, que el marco ya pinta) para no borrar lo que llevaba escrito.\n//\n// Se monta UNA vez, en la raíz de la app, con la versión de la pestaña (la misma que va a ToolkitProvider buildId):\n// usePublishedBuildWatch({url: import.meta.env.PROD ? '/version.json' : null, buildId: APP_BUILD_ID});\n// Sin url no hace nada (en desarrollo no hay versión que comparar).\n//\n// OJO buildId: sin él se toma el de ToolkitProvider, pero la raíz suele montar este gancho ANTES de que ToolkitProvider se\n// pinte (AccountProvider lo pinta hasta tener la sesión): la primera revisión no tenía con qué comparar y, al abrir la app\n// en la pantalla de entrar, el aviso no salía (medido en el proyecto que arma calcita new).\n//\n// OJO: el archivo se pide con cache 'no-store' y el servidor no debe guardarlo (en el nginx de los ejemplos, «location /»\n// ya va con no-cache). Sin red (el teléfono en el metro) no pasa nada: se vuelve a intentar en la siguiente revisión.\n//\n// Gancho genérico del paquete: function (regla de la casa).\nimport {useEffect} from 'react';\n\nimport {BUILD_WATCH_ACTION, buildWatchActionOf, publishedBuildIdOf} from '@/observability/buildWatch.js';\nimport {createLogger} from '@/observability/logger.js';\nimport {reportPublishedBuild} from '@/observability/publishedBuild.js';\nimport {toolkitSettings} from '@/toolkit/toolkitSettings.js';\n\nconst log = createLogger('build-watch');\nconst MILLISECONDS_PER_MINUTE = 60 * 1000;\n// por omisión: revisar cada 5 minutos mientras se usa, y recargar sola si estuvo fuera 15 minutos o más\nconst DEFAULT_CHECK_EVERY_MINUTES = 5;\nconst DEFAULT_RELOAD_AFTER_HIDDEN_MINUTES = 15;\n\n/** Lo que hace si el proyecto no dice otra cosa: recargar la página, que trae la versión nueva. */\nfunction reloadPage() {\n window.location.reload();\n}\n\n/**\n * @param {object} [options]\n * @param {string|null} [options.url] dónde está el archivo de versión ({\"buildId\": \"…\"}); null: no vigila\n * @param {string} [options.buildId] la versión de esta pestaña; por omisión el buildId de ToolkitProvider (ver el OJO)\n * @param {number} [options.checkEveryMinutes] cada cuánto revisa mientras se usa; por omisión 5\n * @param {number|null} [options.reloadAfterHiddenMinutes] desde cuántos minutos fuera se recarga sola al volver; por\n * omisión 15. null: nunca se recarga sola, siempre el aviso\n * @param {() => void} [options.onReload] cómo recargar (p. ej. guardar un borrador antes). OJO: con useCallback; una\n * función nueva en cada pintada volvería a armar la vigilancia\n * @returns {void}\n */\nexport function usePublishedBuildWatch({\n url = null, buildId, checkEveryMinutes = DEFAULT_CHECK_EVERY_MINUTES, reloadAfterHiddenMinutes = DEFAULT_RELOAD_AFTER_HIDDEN_MINUTES, onReload = reloadPage,\n} = {}) {\n useEffect(() => {\n if (!url || typeof document === 'undefined') {\n return undefined;\n }\n let hiddenSince = null;\n let isChecking = false;\n\n const check = async (hiddenMilliseconds = 0) => {\n // una revisión a la vez: al volver del segundo plano pueden llegar dos avisos del navegador juntos\n if (isChecking) {\n return;\n }\n isChecking = true;\n try {\n const response = await fetch(url, {cache: 'no-store', headers: {Accept: 'application/json'}});\n const publishedBuildId = response.ok ? publishedBuildIdOf(await response.json()) : null;\n const action = buildWatchActionOf({\n runningBuildId: buildId ?? toolkitSettings().buildId,\n publishedBuildId,\n hiddenMilliseconds,\n reloadAfterHiddenMilliseconds: reloadAfterHiddenMinutes === null ? null : reloadAfterHiddenMinutes * MILLISECONDS_PER_MINUTE,\n });\n if (action === BUILD_WATCH_ACTION.reload) {\n onReload();\n } else if (action === BUILD_WATCH_ACTION.notice) {\n reportPublishedBuild(publishedBuildId, buildId ?? toolkitSettings().buildId);\n }\n } catch (error) {\n // sin red o con un archivo que no es JSON: no es algo que la persona pueda arreglar; queda en el registro\n log.info('No se pudo revisar la versión publicada', {url, reason: error.message});\n } finally {\n isChecking = false;\n }\n };\n\n // al irse a segundo plano se anota la hora; al volver se revisa con cuánto tiempo estuvo fuera\n const handleVisibilityChange = () => {\n if (document.visibilityState === 'hidden') {\n hiddenSince = Date.now();\n return;\n }\n const hiddenMilliseconds = hiddenSince === null ? 0 : Date.now() - hiddenSince;\n hiddenSince = null;\n check(hiddenMilliseconds);\n };\n // mientras se usa (en segundo plano el teléfono detiene los relojes de la página de todos modos)\n const timer = window.setInterval(() => {\n if (document.visibilityState === 'visible') {\n check();\n }\n }, checkEveryMinutes * MILLISECONDS_PER_MINUTE);\n\n check();\n document.addEventListener('visibilitychange', handleVisibilityChange);\n return () => {\n window.clearInterval(timer);\n document.removeEventListener('visibilitychange', handleVisibilityChange);\n };\n }, [url, buildId, checkEveryMinutes, reloadAfterHiddenMinutes, onReload]);\n}\n"],"names":[],"mappings":";;;;;;AA8BA,MAAM,MAAM,aAAa,aAAa;AACtC,MAAM,0BAA0B,KAAK;AAErC,MAAM,8BAA8B;AACpC,MAAM,sCAAsC;AAG5C,SAAS,aAAa;AAClB,SAAO,SAAS,OAAA;AACpB;AAaO,SAAS,uBAAuB;AAAA,EACnC,MAAM;AAAA,EAAM;AAAA,EAAS,oBAAoB;AAAA,EAA6B,2BAA2B;AAAA,EAAqC,WAAW;AACrJ,IAAI,IAAI;AACJ,YAAU,MAAM;AACZ,QAAI,CAAC,OAAO,OAAO,aAAa,aAAa;AACzC,aAAO;AAAA,IACX;AACA,QAAI,cAAc;AAClB,QAAI,aAAa;AAEjB,UAAM,QAAQ,OAAO,qBAAqB,MAAM;AAE5C,UAAI,YAAY;AACZ;AAAA,MACJ;AACA,mBAAa;AACb,UAAI;AACA,cAAM,WAAW,MAAM,MAAM,KAAK,EAAC,OAAO,YAAY,SAAS,EAAC,QAAQ,mBAAA,EAAkB,CAAE;AAC5F,cAAM,mBAAmB,SAAS,KAAK,mBAAmB,MAAM,SAAS,KAAA,CAAM,IAAI;AACnF,cAAM,SAAS,mBAAmB;AAAA,UAC9B,gBAAgB,WAAW,gBAAA,EAAkB;AAAA,UAC7C;AAAA,UACA;AAAA,UACA,+BAA+B,6BAA6B,OAAO,OAAO,2BAA2B;AAAA,QAAA,CACxG;AACD,YAAI,WAAW,mBAAmB,QAAQ;AACtC,mBAAA;AAAA,QACJ,WAAW,WAAW,mBAAmB,QAAQ;AAC7C,+BAAqB,kBAAkB,WAAW,gBAAA,EAAkB,OAAO;AAAA,QAC/E;AAAA,MACJ,SAAS,OAAO;AAEZ,YAAI,KAAK,2CAA2C,EAAC,KAAK,QAAQ,MAAM,SAAQ;AAAA,MACpF,UAAA;AACI,qBAAa;AAAA,MACjB;AAAA,IACJ;AAGA,UAAM,yBAAyB,MAAM;AACjC,UAAI,SAAS,oBAAoB,UAAU;AACvC,sBAAc,KAAK,IAAA;AACnB;AAAA,MACJ;AACA,YAAM,qBAAqB,gBAAgB,OAAO,IAAI,KAAK,QAAQ;AACnE,oBAAc;AACd,YAAM,kBAAkB;AAAA,IAC5B;AAEA,UAAM,QAAQ,OAAO,YAAY,MAAM;AACnC,UAAI,SAAS,oBAAoB,WAAW;AACxC,cAAA;AAAA,MACJ;AAAA,IACJ,GAAG,oBAAoB,uBAAuB;AAE9C,UAAA;AACA,aAAS,iBAAiB,oBAAoB,sBAAsB;AACpE,WAAO,MAAM;AACT,aAAO,cAAc,KAAK;AAC1B,eAAS,oBAAoB,oBAAoB,sBAAsB;AAAA,IAC3E;AAAA,EACJ,GAAG,CAAC,KAAK,SAAS,mBAAmB,0BAA0B,QAAQ,CAAC;AAC5E;"}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useState } from "react";
4
4
  import Box from "@mui/material/Box";
5
5
  import Button from "@mui/material/Button";
@@ -8,8 +8,9 @@ import { useToolkitTranslation } from "../toolkit/useToolkitTranslation.js";
8
8
  import { INSTALL_VARIANT } from "./installInstructions.js";
9
9
  import InstallInstructionsDialog from "./InstallInstructionsDialog.js";
10
10
  import { useInstallPrompt } from "./useInstallPrompt.js";
11
- function InstallAppSetting() {
12
- const { t } = useToolkitTranslation("common");
11
+ import ComponentTexts from "../toolkit/ComponentTexts.js";
12
+ function InstallAppSetting({ texts } = {}) {
13
+ const { t } = useToolkitTranslation("common", texts);
13
14
  const { variant, promptInstall } = useInstallPrompt();
14
15
  const [stepsOpen, setStepsOpen] = useState(false);
15
16
  if (!variant) {
@@ -22,10 +23,10 @@ function InstallAppSetting() {
22
23
  setStepsOpen(true);
23
24
  }
24
25
  };
25
- return /* @__PURE__ */ jsxs(Box, { sx: { px: 1, py: 0.5 }, children: [
26
+ return /* @__PURE__ */ jsx(ComponentTexts, { namespace: "common", texts, children: /* @__PURE__ */ jsxs(Box, { sx: { px: 1, py: 0.5 }, children: [
26
27
  /* @__PURE__ */ jsx(Button, { fullWidth: true, variant: "outlined", startIcon: /* @__PURE__ */ jsx(InstallMobileRoundedIcon, {}), onClick: handleClick, children: t("install.menuLabel") }),
27
28
  /* @__PURE__ */ jsx(InstallInstructionsDialog, { variant, open: stepsOpen, onClose: () => setStepsOpen(false) })
28
- ] });
29
+ ] }) });
29
30
  }
30
31
  export {
31
32
  InstallAppSetting as default
@@ -1 +1 @@
1
- {"version":3,"file":"InstallAppSetting.js","sources":["../../src/pwa/InstallAppSetting.jsx"],"sourcesContent":["// «Instalar la app» dentro del menú de la cuenta (accountSettings de AppLayout): para quien dijo «Ahora no» a la invitación\n// y después sí la quiere. No respeta el «Ahora no» (aquí la persona la busca a propósito). Ya instalada o sin manera de\n// instalar en ese equipo, no pinta nada.\n//\n// El diálogo de los pasos va aquí mismo: el menú de la cuenta se queda abierto mientras se ve, y al cerrarlo se regresa al\n// menú.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport InstallMobileRoundedIcon from '@mui/icons-material/InstallMobileRounded';\n\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {INSTALL_VARIANT} from '@/pwa/installInstructions.js';\nimport InstallInstructionsDialog from '@/pwa/InstallInstructionsDialog.jsx';\nimport {useInstallPrompt} from '@/pwa/useInstallPrompt.js';\n\nexport default function InstallAppSetting() {\n const {t} = useToolkitTranslation('common');\n const {variant, promptInstall} = useInstallPrompt();\n const [stepsOpen, setStepsOpen] = useState(false);\n\n if (!variant) {\n return null;\n }\n\n const handleClick = () => {\n if (variant === INSTALL_VARIANT.native) {\n promptInstall();\n } else {\n setStepsOpen(true);\n }\n };\n\n return (\n <Box sx={{px: 1, py: 0.5}}>\n <Button fullWidth variant=\"outlined\" startIcon={<InstallMobileRoundedIcon />} onClick={handleClick}>\n {t('install.menuLabel')}\n </Button>\n <InstallInstructionsDialog variant={variant} open={stepsOpen} onClose={() => setStepsOpen(false)} />\n </Box>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;AAkBA,SAAwB,oBAAoB;AACxC,QAAM,EAAC,EAAA,IAAK,sBAAsB,QAAQ;AAC1C,QAAM,EAAC,SAAS,cAAA,IAAiB,iBAAA;AACjC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAEhD,MAAI,CAAC,SAAS;AACV,WAAO;AAAA,EACX;AAEA,QAAM,cAAc,MAAM;AACtB,QAAI,YAAY,gBAAgB,QAAQ;AACpC,oBAAA;AAAA,IACJ,OAAO;AACH,mBAAa,IAAI;AAAA,IACrB;AAAA,EACJ;AAEA,SACI,qBAAC,OAAI,IAAI,EAAC,IAAI,GAAG,IAAI,OACjB,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAO,WAAS,MAAC,SAAQ,YAAW,WAAW,oBAAC,0BAAA,CAAA,CAAyB,GAAI,SAAS,aAClF,UAAA,EAAE,mBAAmB,GAC1B;AAAA,IACA,oBAAC,6BAA0B,SAAkB,MAAM,WAAW,SAAS,MAAM,aAAa,KAAK,EAAA,CAAG;AAAA,EAAA,GACtG;AAER;"}
1
+ {"version":3,"file":"InstallAppSetting.js","sources":["../../src/pwa/InstallAppSetting.jsx"],"sourcesContent":["// «Instalar la app» dentro del menú de la cuenta (accountSettings de AppLayout): para quien dijo «Ahora no» a la invitación\n// y después sí la quiere. No respeta el «Ahora no» (aquí la persona la busca a propósito). Ya instalada o sin manera de\n// instalar en ese equipo, no pinta nada.\n//\n// El diálogo de los pasos va aquí mismo: el menú de la cuenta se queda abierto mientras se ve, y al cerrarlo se regresa al\n// menú.\n//\n// Genérico del paquete: function (regla de la casa).\nimport {useState} from 'react';\nimport Box from '@mui/material/Box';\nimport Button from '@mui/material/Button';\nimport InstallMobileRoundedIcon from '@mui/icons-material/InstallMobileRounded';\n\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {INSTALL_VARIANT} from '@/pwa/installInstructions.js';\nimport InstallInstructionsDialog from '@/pwa/InstallInstructionsDialog.jsx';\nimport {useInstallPrompt} from '@/pwa/useInstallPrompt.js';\nimport ComponentTexts from '@/toolkit/ComponentTexts.jsx';\n\n/**\n * @param {object} [props]\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nexport default function InstallAppSetting({texts} = {}) {\n const {t} = useToolkitTranslation('common', texts);\n const {variant, promptInstall} = useInstallPrompt();\n const [stepsOpen, setStepsOpen] = useState(false);\n\n if (!variant) {\n return null;\n }\n\n const handleClick = () => {\n if (variant === INSTALL_VARIANT.native) {\n promptInstall();\n } else {\n setStepsOpen(true);\n }\n };\n\n return (\n <ComponentTexts namespace=\"common\" texts={texts}>\n <Box sx={{px: 1, py: 0.5}}>\n <Button fullWidth variant=\"outlined\" startIcon={<InstallMobileRoundedIcon />} onClick={handleClick}>\n {t('install.menuLabel')}\n </Button>\n <InstallInstructionsDialog variant={variant} open={stepsOpen} onClose={() => setStepsOpen(false)} />\n </Box>\n </ComponentTexts>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;;AAuBA,SAAwB,kBAAkB,EAAC,MAAA,IAAS,IAAI;AACpD,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,EAAC,SAAS,cAAA,IAAiB,iBAAA;AACjC,QAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAEhD,MAAI,CAAC,SAAS;AACV,WAAO;AAAA,EACX;AAEA,QAAM,cAAc,MAAM;AACtB,QAAI,YAAY,gBAAgB,QAAQ;AACpC,oBAAA;AAAA,IACJ,OAAO;AACH,mBAAa,IAAI;AAAA,IACrB;AAAA,EACJ;AAEA,SACI,oBAAC,gBAAA,EAAe,WAAU,UAAS,OAC/B,UAAA,qBAAC,KAAA,EAAI,IAAI,EAAC,IAAI,GAAG,IAAI,OACjB,UAAA;AAAA,IAAA,oBAAC,QAAA,EAAO,WAAS,MAAC,SAAQ,YAAW,WAAW,oBAAC,0BAAA,CAAA,CAAyB,GAAI,SAAS,aAClF,UAAA,EAAE,mBAAmB,GAC1B;AAAA,IACA,oBAAC,6BAA0B,SAAkB,MAAM,WAAW,SAAS,MAAM,aAAa,KAAK,EAAA,CAAG;AAAA,EAAA,EAAA,CACtG,EAAA,CACJ;AAER;"}
@@ -16,8 +16,8 @@ const STEPS_BY_VARIANT = Object.freeze({
16
16
  function variantHasInstructions(variant) {
17
17
  return Boolean(STEPS_BY_VARIANT[variant]);
18
18
  }
19
- function InstallInstructionsDialog({ variant, open, onClose }) {
20
- const { t } = useToolkitTranslation("common");
19
+ function InstallInstructionsDialog({ variant, open, onClose, texts }) {
20
+ const { t } = useToolkitTranslation("common", texts);
21
21
  const steps = STEPS_BY_VARIANT[variant];
22
22
  if (!steps) {
23
23
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"InstallInstructionsDialog.js","sources":["../../src/pwa/InstallInstructionsDialog.jsx"],"sourcesContent":["// Los pasos para instalar la app a mano, según el equipo (iOS 26 cambió el camino; Firefox usa su propio menú). Lo usan la\n// invitación (InstallPromptBanner) y la entrada del menú de la cuenta (InstallAppSetting): los dos abren el mismo diálogo.\n// Si la variante no lleva pasos (el navegador tiene su propio diálogo, o no hay nada que ofrecer) no pinta nada.\n//\n// OJO, para quien lo monte: NO dentro de un Menu de MUI que se cierra; el Menu quita a sus hijos al cerrarse y el diálogo\n// nunca aparecería. Va junto al Menu o en un lugar que se quede pintado.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Button from '@mui/material/Button';\nimport Dialog from '@mui/material/Dialog';\nimport DialogActions from '@mui/material/DialogActions';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport Typography from '@mui/material/Typography';\n\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {INSTALL_VARIANT} from '@/pwa/installInstructions.js';\n\n// cada variante con pasos a mano → su título y sus pasos en los textos del paquete (common:install.<variante>)\nconst STEPS_BY_VARIANT = Object.freeze({\n [INSTALL_VARIANT.iosModern]: ['step1', 'step2', 'step3', 'step4'],\n [INSTALL_VARIANT.iosClassic]: ['step1', 'step2', 'step3'],\n [INSTALL_VARIANT.androidFirefox]: ['step1', 'step2', 'step3'],\n});\n\n/**\n * ¿Esta variante se instala con pasos a mano (y no con el diálogo del navegador)?\n *\n * @param {string|null} variant\n * @returns {boolean}\n */\nexport function variantHasInstructions(variant) {\n return Boolean(STEPS_BY_VARIANT[variant]);\n}\n\n/**\n * @param {object} props\n * @param {string|null} props.variant una de INSTALL_VARIANT (useInstallPrompt)\n * @param {boolean} props.open\n * @param {() => void} props.onClose\n */\nexport default function InstallInstructionsDialog({variant, open, onClose}) {\n const {t} = useToolkitTranslation('common');\n const steps = STEPS_BY_VARIANT[variant];\n if (!steps) {\n return null;\n }\n\n return (\n <Dialog open={open} onClose={onClose} maxWidth=\"xs\" fullWidth>\n <DialogTitle>{t(`install.${variant}.title`)}</DialogTitle>\n <DialogContent>\n {/* pasos numerados con palabras, sin dibujar los íconos del sistema: cambian entre versiones */}\n <Typography component=\"ol\" sx={{m: 0, pl: 3, display: 'grid', gap: 1.25}}>\n {steps.map((step) => (\n <Typography key={step} component=\"li\" variant=\"body1\">{t(`install.${variant}.${step}`)}</Typography>\n ))}\n </Typography>\n </DialogContent>\n <DialogActions>\n <Button variant=\"contained\" onClick={onClose}>{t('install.gotIt')}</Button>\n </DialogActions>\n </Dialog>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;AAmBA,MAAM,mBAAmB,OAAO,OAAO;AAAA,EACnC,CAAC,gBAAgB,SAAS,GAAG,CAAC,SAAS,SAAS,SAAS,OAAO;AAAA,EAChE,CAAC,gBAAgB,UAAU,GAAG,CAAC,SAAS,SAAS,OAAO;AAAA,EACxD,CAAC,gBAAgB,cAAc,GAAG,CAAC,SAAS,SAAS,OAAO;AAChE,CAAC;AAQM,SAAS,uBAAuB,SAAS;AAC5C,SAAO,QAAQ,iBAAiB,OAAO,CAAC;AAC5C;AAQA,SAAwB,0BAA0B,EAAC,SAAS,MAAM,WAAU;AACxE,QAAM,EAAC,EAAA,IAAK,sBAAsB,QAAQ;AAC1C,QAAM,QAAQ,iBAAiB,OAAO;AACtC,MAAI,CAAC,OAAO;AACR,WAAO;AAAA,EACX;AAEA,8BACK,QAAA,EAAO,MAAY,SAAkB,UAAS,MAAK,WAAS,MACzD,UAAA;AAAA,IAAA,oBAAC,aAAA,EAAa,UAAA,EAAE,WAAW,OAAO,QAAQ,GAAE;AAAA,wBAC3C,eAAA,EAEG,UAAA,oBAAC,YAAA,EAAW,WAAU,MAAK,IAAI,EAAC,GAAG,GAAG,IAAI,GAAG,SAAS,QAAQ,KAAK,QAC9D,UAAA,MAAM,IAAI,CAAC,SACR,oBAAC,YAAA,EAAsB,WAAU,MAAK,SAAQ,SAAS,UAAA,EAAE,WAAW,OAAO,IAAI,IAAI,EAAE,KAApE,IAAsE,CAC1F,GACL,GACJ;AAAA,IACA,oBAAC,eAAA,EACG,UAAA,oBAAC,QAAA,EAAO,SAAQ,aAAY,SAAS,SAAU,UAAA,EAAE,eAAe,EAAA,CAAE,EAAA,CACtE;AAAA,EAAA,GACJ;AAER;"}
1
+ {"version":3,"file":"InstallInstructionsDialog.js","sources":["../../src/pwa/InstallInstructionsDialog.jsx"],"sourcesContent":["// Los pasos para instalar la app a mano, según el equipo (iOS 26 cambió el camino; Firefox usa su propio menú). Lo usan la\n// invitación (InstallPromptBanner) y la entrada del menú de la cuenta (InstallAppSetting): los dos abren el mismo diálogo.\n// Si la variante no lleva pasos (el navegador tiene su propio diálogo, o no hay nada que ofrecer) no pinta nada.\n//\n// OJO, para quien lo monte: NO dentro de un Menu de MUI que se cierra; el Menu quita a sus hijos al cerrarse y el diálogo\n// nunca aparecería. Va junto al Menu o en un lugar que se quede pintado.\n//\n// Genérico del paquete: function (regla de la casa).\nimport Button from '@mui/material/Button';\nimport Dialog from '@mui/material/Dialog';\nimport DialogActions from '@mui/material/DialogActions';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport Typography from '@mui/material/Typography';\n\nimport {useToolkitTranslation} from '@/toolkit/useToolkitTranslation.js';\nimport {INSTALL_VARIANT} from '@/pwa/installInstructions.js';\n\n// cada variante con pasos a mano → su título y sus pasos en los textos del paquete (common:install.<variante>)\nconst STEPS_BY_VARIANT = Object.freeze({\n [INSTALL_VARIANT.iosModern]: ['step1', 'step2', 'step3', 'step4'],\n [INSTALL_VARIANT.iosClassic]: ['step1', 'step2', 'step3'],\n [INSTALL_VARIANT.androidFirefox]: ['step1', 'step2', 'step3'],\n});\n\n/**\n * ¿Esta variante se instala con pasos a mano (y no con el diálogo del navegador)?\n *\n * @param {string|null} variant\n * @returns {boolean}\n */\nexport function variantHasInstructions(variant) {\n return Boolean(STEPS_BY_VARIANT[variant]);\n}\n\n/**\n * @param {object} props\n * @param {string|null} props.variant una de INSTALL_VARIANT (useInstallPrompt)\n * @param {boolean} props.open\n * @param {() => void} props.onClose\n * @param {object} [props.texts] los textos que cambian, con la forma de `common` en los textos del paquete\n */\nexport default function InstallInstructionsDialog({variant, open, onClose, texts}) {\n const {t} = useToolkitTranslation('common', texts);\n const steps = STEPS_BY_VARIANT[variant];\n if (!steps) {\n return null;\n }\n\n return (\n <Dialog open={open} onClose={onClose} maxWidth=\"xs\" fullWidth>\n <DialogTitle>{t(`install.${variant}.title`)}</DialogTitle>\n <DialogContent>\n {/* pasos numerados con palabras, sin dibujar los íconos del sistema: cambian entre versiones */}\n <Typography component=\"ol\" sx={{m: 0, pl: 3, display: 'grid', gap: 1.25}}>\n {steps.map((step) => (\n <Typography key={step} component=\"li\" variant=\"body1\">{t(`install.${variant}.${step}`)}</Typography>\n ))}\n </Typography>\n </DialogContent>\n <DialogActions>\n <Button variant=\"contained\" onClick={onClose}>{t('install.gotIt')}</Button>\n </DialogActions>\n </Dialog>\n );\n}\n"],"names":[],"mappings":";;;;;;;;;;AAmBA,MAAM,mBAAmB,OAAO,OAAO;AAAA,EACnC,CAAC,gBAAgB,SAAS,GAAG,CAAC,SAAS,SAAS,SAAS,OAAO;AAAA,EAChE,CAAC,gBAAgB,UAAU,GAAG,CAAC,SAAS,SAAS,OAAO;AAAA,EACxD,CAAC,gBAAgB,cAAc,GAAG,CAAC,SAAS,SAAS,OAAO;AAChE,CAAC;AAQM,SAAS,uBAAuB,SAAS;AAC5C,SAAO,QAAQ,iBAAiB,OAAO,CAAC;AAC5C;AASA,SAAwB,0BAA0B,EAAC,SAAS,MAAM,SAAS,SAAQ;AAC/E,QAAM,EAAC,EAAA,IAAK,sBAAsB,UAAU,KAAK;AACjD,QAAM,QAAQ,iBAAiB,OAAO;AACtC,MAAI,CAAC,OAAO;AACR,WAAO;AAAA,EACX;AAEA,8BACK,QAAA,EAAO,MAAY,SAAkB,UAAS,MAAK,WAAS,MACzD,UAAA;AAAA,IAAA,oBAAC,aAAA,EAAa,UAAA,EAAE,WAAW,OAAO,QAAQ,GAAE;AAAA,wBAC3C,eAAA,EAEG,UAAA,oBAAC,YAAA,EAAW,WAAU,MAAK,IAAI,EAAC,GAAG,GAAG,IAAI,GAAG,SAAS,QAAQ,KAAK,QAC9D,UAAA,MAAM,IAAI,CAAC,SACR,oBAAC,YAAA,EAAsB,WAAU,MAAK,SAAQ,SAAS,UAAA,EAAE,WAAW,OAAO,IAAI,IAAI,EAAE,KAApE,IAAsE,CAC1F,GACL,GACJ;AAAA,IACA,oBAAC,eAAA,EACG,UAAA,oBAAC,QAAA,EAAO,SAAQ,aAAY,SAAS,SAAU,UAAA,EAAE,eAAe,EAAA,CAAE,EAAA,CACtE;AAAA,EAAA,GACJ;AAER;"}