@marinoscar/platform-web 0.1.0-next.16 → 0.1.0-next.18

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 (298) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +3 -2
  3. package/dist/ai/headless/schema-presets.js +1 -1
  4. package/dist/ai/headless/schema-presets.js.map +1 -1
  5. package/dist/ai/ui/AiConfigPage.d.ts.map +1 -1
  6. package/dist/ai/ui/AiConfigPage.js +3 -2
  7. package/dist/ai/ui/AiConfigPage.js.map +1 -1
  8. package/dist/ai/ui/AiModelsPage.d.ts.map +1 -1
  9. package/dist/ai/ui/AiModelsPage.js +4 -2
  10. package/dist/ai/ui/AiModelsPage.js.map +1 -1
  11. package/dist/ai/ui/OrgAiKeysPage.d.ts.map +1 -1
  12. package/dist/ai/ui/OrgAiKeysPage.js +3 -2
  13. package/dist/ai/ui/OrgAiKeysPage.js.map +1 -1
  14. package/dist/ai/ui/admin/AiGenericProviderCard.d.ts.map +1 -1
  15. package/dist/ai/ui/admin/AiGenericProviderCard.js +2 -0
  16. package/dist/ai/ui/admin/AiGenericProviderCard.js.map +1 -1
  17. package/dist/ai/ui/admin/AiProviderCard.d.ts.map +1 -1
  18. package/dist/ai/ui/admin/AiProviderCard.js +2 -0
  19. package/dist/ai/ui/admin/AiProviderCard.js.map +1 -1
  20. package/dist/ai/ui/admin/AiProviderKeyActions.d.ts.map +1 -1
  21. package/dist/ai/ui/admin/AiProviderKeyActions.js +2 -1
  22. package/dist/ai/ui/admin/AiProviderKeyActions.js.map +1 -1
  23. package/dist/ai/ui/admin/aiModelColumns.d.ts.map +1 -1
  24. package/dist/ai/ui/admin/aiModelColumns.js +2 -1
  25. package/dist/ai/ui/admin/aiModelColumns.js.map +1 -1
  26. package/dist/ai/ui/user/UserAiKeyCard.d.ts.map +1 -1
  27. package/dist/ai/ui/user/UserAiKeyCard.js +6 -4
  28. package/dist/ai/ui/user/UserAiKeyCard.js.map +1 -1
  29. package/dist/android-app/ui/AndroidAppPage.d.ts.map +1 -1
  30. package/dist/android-app/ui/AndroidAppPage.js +3 -2
  31. package/dist/android-app/ui/AndroidAppPage.js.map +1 -1
  32. package/dist/core/host.d.ts +2 -2
  33. package/dist/core/host.js +2 -2
  34. package/dist/core/index.d.ts +3 -0
  35. package/dist/core/index.d.ts.map +1 -1
  36. package/dist/core/index.js +6 -0
  37. package/dist/core/index.js.map +1 -1
  38. package/dist/core/time-zone/format.d.ts +135 -0
  39. package/dist/core/time-zone/format.d.ts.map +1 -0
  40. package/dist/core/time-zone/format.js +228 -0
  41. package/dist/core/time-zone/format.js.map +1 -0
  42. package/dist/core/time-zone/store.d.ts +93 -0
  43. package/dist/core/time-zone/store.d.ts.map +1 -0
  44. package/dist/core/time-zone/store.js +170 -0
  45. package/dist/core/time-zone/store.js.map +1 -0
  46. package/dist/credentials/headless/saved-secret.d.ts +1 -1
  47. package/dist/credentials/headless/saved-secret.d.ts.map +1 -1
  48. package/dist/credentials/headless/saved-secret.js +2 -1
  49. package/dist/credentials/headless/saved-secret.js.map +1 -1
  50. package/dist/credentials/ui/secret-field.d.ts +1 -1
  51. package/dist/credentials/ui/secret-field.d.ts.map +1 -1
  52. package/dist/credentials/ui/secret-field.js +2 -0
  53. package/dist/credentials/ui/secret-field.js.map +1 -1
  54. package/dist/db-backup/internal/format.d.ts +4 -1
  55. package/dist/db-backup/internal/format.d.ts.map +1 -1
  56. package/dist/db-backup/internal/format.js +6 -2
  57. package/dist/db-backup/internal/format.js.map +1 -1
  58. package/dist/db-backup/ui/DbBackupConfigPanel.d.ts.map +1 -1
  59. package/dist/db-backup/ui/DbBackupConfigPanel.js +4 -1
  60. package/dist/db-backup/ui/DbBackupConfigPanel.js.map +1 -1
  61. package/dist/db-backup/ui/DbBackupPage.d.ts.map +1 -1
  62. package/dist/db-backup/ui/DbBackupPage.js +7 -4
  63. package/dist/db-backup/ui/DbBackupPage.js.map +1 -1
  64. package/dist/db-backup/ui/DbBackupRestoreDialog.d.ts.map +1 -1
  65. package/dist/db-backup/ui/DbBackupRestoreDialog.js +4 -1
  66. package/dist/db-backup/ui/DbBackupRestoreDialog.js.map +1 -1
  67. package/dist/email/ui/EmailSettingsPage.d.ts.map +1 -1
  68. package/dist/email/ui/EmailSettingsPage.js +3 -2
  69. package/dist/email/ui/EmailSettingsPage.js.map +1 -1
  70. package/dist/email/ui/SesTransportPanel.d.ts.map +1 -1
  71. package/dist/email/ui/SesTransportPanel.js +3 -1
  72. package/dist/email/ui/SesTransportPanel.js.map +1 -1
  73. package/dist/email/ui/SmtpTransportPanel.d.ts.map +1 -1
  74. package/dist/email/ui/SmtpTransportPanel.js +3 -1
  75. package/dist/email/ui/SmtpTransportPanel.js.map +1 -1
  76. package/dist/exports/ui/ExportsList.d.ts.map +1 -1
  77. package/dist/exports/ui/ExportsList.js +5 -2
  78. package/dist/exports/ui/ExportsList.js.map +1 -1
  79. package/dist/host/ui/about-page.d.ts.map +1 -1
  80. package/dist/host/ui/about-page.js +7 -5
  81. package/dist/host/ui/about-page.js.map +1 -1
  82. package/dist/host/ui/maintenance-page.d.ts.map +1 -1
  83. package/dist/host/ui/maintenance-page.js +3 -2
  84. package/dist/host/ui/maintenance-page.js.map +1 -1
  85. package/dist/identity/index.d.ts +1 -1
  86. package/dist/identity/index.d.ts.map +1 -1
  87. package/dist/identity/index.js +3 -2
  88. package/dist/identity/index.js.map +1 -1
  89. package/dist/identity/ui/org/OrgInvitesPanel.d.ts.map +1 -1
  90. package/dist/identity/ui/org/OrgInvitesPanel.js +2 -0
  91. package/dist/identity/ui/org/OrgInvitesPanel.js.map +1 -1
  92. package/dist/identity/ui/org/OrgMembersPanel.d.ts.map +1 -1
  93. package/dist/identity/ui/org/OrgMembersPanel.js +2 -0
  94. package/dist/identity/ui/org/OrgMembersPanel.js.map +1 -1
  95. package/dist/identity/ui/org/orgLabels.d.ts +1 -1
  96. package/dist/identity/ui/org/orgLabels.d.ts.map +1 -1
  97. package/dist/identity/ui/org/orgLabels.js +3 -5
  98. package/dist/identity/ui/org/orgLabels.js.map +1 -1
  99. package/dist/identity/ui/tokens/CreatePatDialog.d.ts.map +1 -1
  100. package/dist/identity/ui/tokens/CreatePatDialog.js +3 -1
  101. package/dist/identity/ui/tokens/CreatePatDialog.js.map +1 -1
  102. package/dist/identity/ui/tokens/PersonalAccessTokens.d.ts.map +1 -1
  103. package/dist/identity/ui/tokens/PersonalAccessTokens.js +4 -1
  104. package/dist/identity/ui/tokens/PersonalAccessTokens.js.map +1 -1
  105. package/dist/identity/ui/tokens/patColumns.d.ts.map +1 -1
  106. package/dist/identity/ui/tokens/patColumns.js +7 -5
  107. package/dist/identity/ui/tokens/patColumns.js.map +1 -1
  108. package/dist/identity/ui/users/AllowlistTable.d.ts.map +1 -1
  109. package/dist/identity/ui/users/AllowlistTable.js +4 -1
  110. package/dist/identity/ui/users/AllowlistTable.js.map +1 -1
  111. package/dist/identity/ui/users/UserList.d.ts.map +1 -1
  112. package/dist/identity/ui/users/UserList.js +4 -2
  113. package/dist/identity/ui/users/UserList.js.map +1 -1
  114. package/dist/identity/ui/users/allowlistColumns.d.ts.map +1 -1
  115. package/dist/identity/ui/users/allowlistColumns.js +5 -3
  116. package/dist/identity/ui/users/allowlistColumns.js.map +1 -1
  117. package/dist/identity/ui/users/userListColumns.d.ts.map +1 -1
  118. package/dist/identity/ui/users/userListColumns.js +5 -3
  119. package/dist/identity/ui/users/userListColumns.js.map +1 -1
  120. package/dist/jobs/headless/format.d.ts +4 -1
  121. package/dist/jobs/headless/format.d.ts.map +1 -1
  122. package/dist/jobs/headless/format.js +6 -2
  123. package/dist/jobs/headless/format.js.map +1 -1
  124. package/dist/jobs/ui/JobInsightsPage.d.ts.map +1 -1
  125. package/dist/jobs/ui/JobInsightsPage.js +2 -1
  126. package/dist/jobs/ui/JobInsightsPage.js.map +1 -1
  127. package/dist/jobs/ui/JobsPage.d.ts.map +1 -1
  128. package/dist/jobs/ui/JobsPage.js +4 -2
  129. package/dist/jobs/ui/JobsPage.js.map +1 -1
  130. package/dist/nodes/headless/format.d.ts +4 -1
  131. package/dist/nodes/headless/format.d.ts.map +1 -1
  132. package/dist/nodes/headless/format.js +6 -2
  133. package/dist/nodes/headless/format.js.map +1 -1
  134. package/dist/nodes/ui/NodeCredentialRevealDialog.d.ts.map +1 -1
  135. package/dist/nodes/ui/NodeCredentialRevealDialog.js +3 -1
  136. package/dist/nodes/ui/NodeCredentialRevealDialog.js.map +1 -1
  137. package/dist/nodes/ui/NodeCredentials.d.ts.map +1 -1
  138. package/dist/nodes/ui/NodeCredentials.js +4 -1
  139. package/dist/nodes/ui/NodeCredentials.js.map +1 -1
  140. package/dist/nodes/ui/NodeVitalsDialog.d.ts.map +1 -1
  141. package/dist/nodes/ui/NodeVitalsDialog.js +2 -0
  142. package/dist/nodes/ui/NodeVitalsDialog.js.map +1 -1
  143. package/dist/nodes/ui/WorkersPage.d.ts.map +1 -1
  144. package/dist/nodes/ui/WorkersPage.js +4 -2
  145. package/dist/nodes/ui/WorkersPage.js.map +1 -1
  146. package/dist/notifications/headless/broadcasts.d.ts +26 -17
  147. package/dist/notifications/headless/broadcasts.d.ts.map +1 -1
  148. package/dist/notifications/headless/broadcasts.js +76 -36
  149. package/dist/notifications/headless/broadcasts.js.map +1 -1
  150. package/dist/notifications/ui/BroadcastComposer.d.ts.map +1 -1
  151. package/dist/notifications/ui/BroadcastComposer.js +11 -6
  152. package/dist/notifications/ui/BroadcastComposer.js.map +1 -1
  153. package/dist/notifications/ui/BroadcastDetailDialog.d.ts.map +1 -1
  154. package/dist/notifications/ui/BroadcastDetailDialog.js +2 -0
  155. package/dist/notifications/ui/BroadcastDetailDialog.js.map +1 -1
  156. package/dist/notifications/ui/BroadcastsPage.d.ts.map +1 -1
  157. package/dist/notifications/ui/BroadcastsPage.js +4 -2
  158. package/dist/notifications/ui/BroadcastsPage.js.map +1 -1
  159. package/dist/notifications/ui/NotificationBell.d.ts.map +1 -1
  160. package/dist/notifications/ui/NotificationBell.js +3 -1
  161. package/dist/notifications/ui/NotificationBell.js.map +1 -1
  162. package/dist/notifications/ui/PushConfigPage.d.ts.map +1 -1
  163. package/dist/notifications/ui/PushConfigPage.js +4 -3
  164. package/dist/notifications/ui/PushConfigPage.js.map +1 -1
  165. package/dist/notifications/ui/PushTestPanel.d.ts.map +1 -1
  166. package/dist/notifications/ui/PushTestPanel.js +6 -3
  167. package/dist/notifications/ui/PushTestPanel.js.map +1 -1
  168. package/dist/notifications/ui/SystemSettingsSection.d.ts.map +1 -1
  169. package/dist/notifications/ui/SystemSettingsSection.js +3 -2
  170. package/dist/notifications/ui/SystemSettingsSection.js.map +1 -1
  171. package/dist/notifications/ui/broadcastsTable.d.ts +4 -1
  172. package/dist/notifications/ui/broadcastsTable.d.ts.map +1 -1
  173. package/dist/notifications/ui/broadcastsTable.js +6 -2
  174. package/dist/notifications/ui/broadcastsTable.js.map +1 -1
  175. package/dist/settings/headless/use-user-settings.d.ts +7 -0
  176. package/dist/settings/headless/use-user-settings.d.ts.map +1 -1
  177. package/dist/settings/headless/use-user-settings.js +12 -4
  178. package/dist/settings/headless/use-user-settings.js.map +1 -1
  179. package/dist/settings/ui/ProfileSettings.d.ts +13 -4
  180. package/dist/settings/ui/ProfileSettings.d.ts.map +1 -1
  181. package/dist/settings/ui/ProfileSettings.js +15 -2
  182. package/dist/settings/ui/ProfileSettings.js.map +1 -1
  183. package/dist/settings/ui/UserProfilePage.d.ts +2 -2
  184. package/dist/settings/ui/UserProfilePage.js +3 -3
  185. package/dist/settings/ui/UserProfilePage.js.map +1 -1
  186. package/dist/settings/ui/UserSettingsSection.d.ts +5 -2
  187. package/dist/settings/ui/UserSettingsSection.d.ts.map +1 -1
  188. package/dist/settings/ui/UserSettingsSection.js.map +1 -1
  189. package/dist/sharing/internal/format.d.ts +1 -0
  190. package/dist/sharing/internal/format.d.ts.map +1 -1
  191. package/dist/sharing/internal/format.js +3 -6
  192. package/dist/sharing/internal/format.js.map +1 -1
  193. package/dist/sharing/ui/GroupDetailPage.d.ts.map +1 -1
  194. package/dist/sharing/ui/GroupDetailPage.js +2 -0
  195. package/dist/sharing/ui/GroupDetailPage.js.map +1 -1
  196. package/dist/sharing/ui/PendingGroupInvites.d.ts.map +1 -1
  197. package/dist/sharing/ui/PendingGroupInvites.js +2 -0
  198. package/dist/sharing/ui/PendingGroupInvites.js.map +1 -1
  199. package/dist/sharing/ui/ShareDialog.d.ts.map +1 -1
  200. package/dist/sharing/ui/ShareDialog.js +2 -0
  201. package/dist/sharing/ui/ShareDialog.js.map +1 -1
  202. package/dist/sharing/ui/SharedWithMeList.d.ts.map +1 -1
  203. package/dist/sharing/ui/SharedWithMeList.js +2 -0
  204. package/dist/sharing/ui/SharedWithMeList.js.map +1 -1
  205. package/dist/storage/ui/S3FamilyDriverPanel.d.ts.map +1 -1
  206. package/dist/storage/ui/S3FamilyDriverPanel.js +3 -1
  207. package/dist/storage/ui/S3FamilyDriverPanel.js.map +1 -1
  208. package/dist/storage/ui/StorageConfigPage.d.ts.map +1 -1
  209. package/dist/storage/ui/StorageConfigPage.js +3 -2
  210. package/dist/storage/ui/StorageConfigPage.js.map +1 -1
  211. package/dist/telemetry/headless/hooks/useTelemetryDashboard.d.ts +1 -1
  212. package/dist/telemetry/headless/lib/format.d.ts +4 -2
  213. package/dist/telemetry/headless/lib/format.d.ts.map +1 -1
  214. package/dist/telemetry/headless/lib/format.js +8 -6
  215. package/dist/telemetry/headless/lib/format.js.map +1 -1
  216. package/dist/telemetry/ui/components/TelemetryConnectionSection.d.ts.map +1 -1
  217. package/dist/telemetry/ui/components/TelemetryConnectionSection.js +3 -1
  218. package/dist/telemetry/ui/components/TelemetryConnectionSection.js.map +1 -1
  219. package/dist/telemetry/ui/components/dashboard/ApiTimelineChart.d.ts.map +1 -1
  220. package/dist/telemetry/ui/components/dashboard/ApiTimelineChart.js +2 -0
  221. package/dist/telemetry/ui/components/dashboard/ApiTimelineChart.js.map +1 -1
  222. package/dist/telemetry/ui/components/dashboard/DashboardFilterBar.d.ts.map +1 -1
  223. package/dist/telemetry/ui/components/dashboard/DashboardFilterBar.js +2 -0
  224. package/dist/telemetry/ui/components/dashboard/DashboardFilterBar.js.map +1 -1
  225. package/dist/telemetry/ui/components/dashboard/EventsFeed.d.ts.map +1 -1
  226. package/dist/telemetry/ui/components/dashboard/EventsFeed.js +3 -0
  227. package/dist/telemetry/ui/components/dashboard/EventsFeed.js.map +1 -1
  228. package/dist/telemetry/ui/components/dashboard/KpiTiles.d.ts.map +1 -1
  229. package/dist/telemetry/ui/components/dashboard/KpiTiles.js +2 -0
  230. package/dist/telemetry/ui/components/dashboard/KpiTiles.js.map +1 -1
  231. package/dist/telemetry/ui/components/dashboard/LogSeverityChart.d.ts.map +1 -1
  232. package/dist/telemetry/ui/components/dashboard/LogSeverityChart.js +2 -0
  233. package/dist/telemetry/ui/components/dashboard/LogSeverityChart.js.map +1 -1
  234. package/dist/telemetry/ui/components/dashboard/TopProblems.d.ts.map +1 -1
  235. package/dist/telemetry/ui/components/dashboard/TopProblems.js +2 -0
  236. package/dist/telemetry/ui/components/dashboard/TopProblems.js.map +1 -1
  237. package/dist/telemetry/ui/components/dashboard/metrics/MetricSeriesChart.d.ts.map +1 -1
  238. package/dist/telemetry/ui/components/dashboard/metrics/MetricSeriesChart.js +2 -0
  239. package/dist/telemetry/ui/components/dashboard/metrics/MetricSeriesChart.js.map +1 -1
  240. package/dist/telemetry/ui/components/dashboard/metrics/MetricTable.d.ts.map +1 -1
  241. package/dist/telemetry/ui/components/dashboard/metrics/MetricTable.js +2 -0
  242. package/dist/telemetry/ui/components/dashboard/metrics/MetricTable.js.map +1 -1
  243. package/dist/telemetry/ui/pages/TelemetrySettingsPage.d.ts.map +1 -1
  244. package/dist/telemetry/ui/pages/TelemetrySettingsPage.js +3 -2
  245. package/dist/telemetry/ui/pages/TelemetrySettingsPage.js.map +1 -1
  246. package/dist/timezone/headless/catalog.d.ts +82 -0
  247. package/dist/timezone/headless/catalog.d.ts.map +1 -0
  248. package/dist/timezone/headless/catalog.js +192 -0
  249. package/dist/timezone/headless/catalog.js.map +1 -0
  250. package/dist/timezone/headless/format.d.ts +3 -0
  251. package/dist/timezone/headless/format.d.ts.map +1 -0
  252. package/dist/timezone/headless/format.js +5 -0
  253. package/dist/timezone/headless/format.js.map +1 -0
  254. package/dist/timezone/headless/index.d.ts +10 -0
  255. package/dist/timezone/headless/index.d.ts.map +1 -0
  256. package/dist/timezone/headless/index.js +10 -0
  257. package/dist/timezone/headless/index.js.map +1 -0
  258. package/dist/timezone/headless/map-data.d.ts +13 -0
  259. package/dist/timezone/headless/map-data.d.ts.map +1 -0
  260. package/dist/timezone/headless/map-data.js +530 -0
  261. package/dist/timezone/headless/map-data.js.map +1 -0
  262. package/dist/timezone/headless/map-geometry.d.ts +77 -0
  263. package/dist/timezone/headless/map-geometry.d.ts.map +1 -0
  264. package/dist/timezone/headless/map-geometry.js +104 -0
  265. package/dist/timezone/headless/map-geometry.js.map +1 -0
  266. package/dist/timezone/headless/store.d.ts +2 -0
  267. package/dist/timezone/headless/store.d.ts.map +1 -0
  268. package/dist/timezone/headless/store.js +6 -0
  269. package/dist/timezone/headless/store.js.map +1 -0
  270. package/dist/timezone/headless/sync.d.ts +39 -0
  271. package/dist/timezone/headless/sync.d.ts.map +1 -0
  272. package/dist/timezone/headless/sync.js +66 -0
  273. package/dist/timezone/headless/sync.js.map +1 -0
  274. package/dist/timezone/index.d.ts +4 -0
  275. package/dist/timezone/index.d.ts.map +1 -0
  276. package/dist/timezone/index.js +11 -0
  277. package/dist/timezone/index.js.map +1 -0
  278. package/dist/timezone/internal/use-now.d.ts +3 -0
  279. package/dist/timezone/internal/use-now.d.ts.map +1 -0
  280. package/dist/timezone/internal/use-now.js +13 -0
  281. package/dist/timezone/internal/use-now.js.map +1 -0
  282. package/dist/timezone/ui/TimeZoneField.d.ts +33 -0
  283. package/dist/timezone/ui/TimeZoneField.d.ts.map +1 -0
  284. package/dist/timezone/ui/TimeZoneField.js +50 -0
  285. package/dist/timezone/ui/TimeZoneField.js.map +1 -0
  286. package/dist/timezone/ui/TimeZoneMap.d.ts +38 -0
  287. package/dist/timezone/ui/TimeZoneMap.d.ts.map +1 -0
  288. package/dist/timezone/ui/TimeZoneMap.js +231 -0
  289. package/dist/timezone/ui/TimeZoneMap.js.map +1 -0
  290. package/dist/timezone/ui/TimeZonePickerDialog.d.ts +34 -0
  291. package/dist/timezone/ui/TimeZonePickerDialog.d.ts.map +1 -0
  292. package/dist/timezone/ui/TimeZonePickerDialog.js +85 -0
  293. package/dist/timezone/ui/TimeZonePickerDialog.js.map +1 -0
  294. package/dist/timezone/ui/index.d.ts +7 -0
  295. package/dist/timezone/ui/index.d.ts.map +1 -0
  296. package/dist/timezone/ui/index.js +7 -0
  297. package/dist/timezone/ui/index.js.map +1 -0
  298. package/package.json +10 -2
@@ -0,0 +1,228 @@
1
+ // Date and time formatting in the display zone. Every formatter defaults
2
+ // `timeZone` to `getDisplayTimeZone()`; a caller passes an explicit
3
+ // `timeZone` (often `'UTC'`) for a server fact that is defined in one zone.
4
+ // In `core` with the store (see ./store.ts); re-exported by the timezone slice.
5
+ import { getDisplayTimeZone } from './store.js';
6
+ /**
7
+ * The fields `Date.prototype.toLocaleString()` renders (`1/15/2026, 6:30:00 PM`
8
+ * in `en-US`), for a page that keeps that look while rendering in the display
9
+ * zone: `formatDateTime(value, NUMERIC_DATE_TIME)`.
10
+ *
11
+ * @stability experimental
12
+ */
13
+ export const NUMERIC_DATE_TIME = Object.freeze({
14
+ year: 'numeric',
15
+ month: 'numeric',
16
+ day: 'numeric',
17
+ hour: 'numeric',
18
+ minute: 'numeric',
19
+ second: 'numeric',
20
+ });
21
+ /**
22
+ * The fields `Date.prototype.toLocaleDateString()` renders (`1/15/2026`):
23
+ * `formatDate(value, NUMERIC_DATE)`.
24
+ *
25
+ * @stability experimental
26
+ */
27
+ export const NUMERIC_DATE = Object.freeze({
28
+ year: 'numeric',
29
+ month: 'numeric',
30
+ day: 'numeric',
31
+ });
32
+ /**
33
+ * The fields `Date.prototype.toLocaleTimeString()` renders (`6:30:00 PM`):
34
+ * `formatTime(value, NUMERIC_TIME)`.
35
+ *
36
+ * @stability experimental
37
+ */
38
+ export const NUMERIC_TIME = Object.freeze({
39
+ hour: 'numeric',
40
+ minute: 'numeric',
41
+ second: 'numeric',
42
+ });
43
+ /** What an empty or invalid date renders across the packaged pages. */
44
+ const DEFAULT_FALLBACK = '—';
45
+ const CACHE_LIMIT = 200;
46
+ const cache = new Map();
47
+ /** Options that pick date or time fields one by one (they cannot mix with `dateStyle`/`timeStyle`). */
48
+ const FIELD_KEYS = [
49
+ 'dateStyle',
50
+ 'timeStyle',
51
+ 'weekday',
52
+ 'era',
53
+ 'year',
54
+ 'month',
55
+ 'day',
56
+ 'dayPeriod',
57
+ 'hour',
58
+ 'minute',
59
+ 'second',
60
+ 'fractionalSecondDigits',
61
+ 'timeZoneName',
62
+ ];
63
+ /**
64
+ * The value as a valid `Date`, or `null`.
65
+ *
66
+ * @param value - see {@link DateInput}.
67
+ * @returns the date, or `null` for an empty or invalid value.
68
+ *
69
+ * @stability experimental
70
+ */
71
+ export function toValidDate(value) {
72
+ if (value === null || value === undefined || value === '')
73
+ return null;
74
+ const date = value instanceof Date ? value : new Date(value);
75
+ return Number.isNaN(date.getTime()) ? null : date;
76
+ }
77
+ function cachedFormatter(locale, options) {
78
+ const key = JSON.stringify([locale ?? null, Object.entries(options).sort(([a], [b]) => a.localeCompare(b))]);
79
+ let formatter = cache.get(key);
80
+ if (!formatter) {
81
+ if (cache.size >= CACHE_LIMIT)
82
+ cache.clear();
83
+ formatter = new Intl.DateTimeFormat(locale, options);
84
+ cache.set(key, formatter);
85
+ }
86
+ return formatter;
87
+ }
88
+ /**
89
+ * A cached `Intl.DateTimeFormat` for the options, in the display zone unless
90
+ * `options.timeZone` says otherwise. An unknown zone falls back to UTC.
91
+ *
92
+ * @param options - format options; `locale` picks the locale.
93
+ * @returns the formatter.
94
+ *
95
+ * @stability experimental
96
+ */
97
+ export function getDateTimeFormat(options = {}) {
98
+ const { locale, ...intl } = options;
99
+ const resolved = { ...intl, timeZone: intl.timeZone ?? getDisplayTimeZone() };
100
+ try {
101
+ return cachedFormatter(locale, resolved);
102
+ }
103
+ catch {
104
+ return cachedFormatter(locale, { ...resolved, timeZone: 'UTC' });
105
+ }
106
+ }
107
+ function format(value, options, defaults) {
108
+ const { fallback = DEFAULT_FALLBACK, ...rest } = options ?? {};
109
+ const date = toValidDate(value);
110
+ if (!date)
111
+ return fallback;
112
+ const picksFields = FIELD_KEYS.some((key) => rest[key] !== undefined);
113
+ return getDateTimeFormat(picksFields ? rest : { ...defaults, ...rest }).format(date);
114
+ }
115
+ /**
116
+ * A date and time in the display zone (`Oct 26, 2026, 10:42 AM`).
117
+ *
118
+ * @param value - see {@link DateInput}.
119
+ * @param options - default `{ dateStyle: 'medium', timeStyle: 'short' }`; any field option replaces the defaults.
120
+ * @returns the formatted text, or the fallback (`'—'`).
121
+ *
122
+ * @example
123
+ * ```ts
124
+ * formatDateTime(job.createdAt); // in the user's zone
125
+ * formatDateTime(backup.scheduledAt, { timeZone: 'UTC' });
126
+ * ```
127
+ *
128
+ * @stability experimental
129
+ */
130
+ export function formatDateTime(value, options) {
131
+ return format(value, options, { dateStyle: 'medium', timeStyle: 'short' });
132
+ }
133
+ /**
134
+ * A calendar date in the display zone (`Oct 26, 2026`).
135
+ *
136
+ * @param value - see {@link DateInput}.
137
+ * @param options - default `{ dateStyle: 'medium' }`.
138
+ * @returns the formatted text, or the fallback (`'—'`).
139
+ *
140
+ * @stability experimental
141
+ */
142
+ export function formatDate(value, options) {
143
+ return format(value, options, { dateStyle: 'medium' });
144
+ }
145
+ /**
146
+ * A time of day in the display zone (`10:42 AM`).
147
+ *
148
+ * @param value - see {@link DateInput}.
149
+ * @param options - default `{ timeStyle: 'short' }`.
150
+ * @returns the formatted text, or the fallback (`'—'`).
151
+ *
152
+ * @stability experimental
153
+ */
154
+ export function formatTime(value, options) {
155
+ return format(value, options, { timeStyle: 'short' });
156
+ }
157
+ function zonedParts(date, timeZone) {
158
+ const parts = getDateTimeFormat({
159
+ locale: 'en-US',
160
+ timeZone,
161
+ hourCycle: 'h23',
162
+ year: 'numeric',
163
+ month: '2-digit',
164
+ day: '2-digit',
165
+ hour: '2-digit',
166
+ minute: '2-digit',
167
+ second: '2-digit',
168
+ }).formatToParts(date);
169
+ const out = {};
170
+ for (const part of parts)
171
+ if (part.type !== 'literal')
172
+ out[part.type] = Number(part.value);
173
+ return out;
174
+ }
175
+ /**
176
+ * The calendar day of a moment in a zone, as `YYYY-MM-DD`: the key to group
177
+ * rows by day or to tell "Today" from "Yesterday".
178
+ *
179
+ * @param value - see {@link DateInput}.
180
+ * @param timeZone - default: the display zone.
181
+ * @returns the key, or `null` for an empty or invalid value.
182
+ *
183
+ * @example
184
+ * ```ts
185
+ * const isToday = zonedDateKey(row.createdAt) === zonedDateKey(new Date());
186
+ * ```
187
+ *
188
+ * @stability experimental
189
+ */
190
+ export function zonedDateKey(value, timeZone) {
191
+ const date = toValidDate(value);
192
+ if (!date)
193
+ return null;
194
+ const { year = 0, month = 0, day = 0 } = zonedParts(date, timeZone ?? getDisplayTimeZone());
195
+ return `${String(year).padStart(4, '0')}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
196
+ }
197
+ /**
198
+ * The zone's offset from UTC at a moment, in minutes (`-360` for Costa Rica,
199
+ * `330` for India); daylight saving time included.
200
+ *
201
+ * @param timeZone - an IANA zone id.
202
+ * @param at - the moment; default now.
203
+ * @returns minutes east of UTC.
204
+ *
205
+ * @stability experimental
206
+ */
207
+ export function getTimeZoneOffsetMinutes(timeZone, at = new Date()) {
208
+ const p = zonedParts(at, timeZone);
209
+ const asUtc = Date.UTC(p.year ?? 1970, (p.month ?? 1) - 1, p.day ?? 1, (p.hour ?? 0) % 24, p.minute ?? 0, p.second ?? 0);
210
+ const whole = Math.floor(at.getTime() / 1000) * 1000;
211
+ return Math.round((asUtc - whole) / 60_000);
212
+ }
213
+ /**
214
+ * An offset as `UTC−06:00`, `UTC+05:30` or `UTC` (with the minus sign U+2212).
215
+ *
216
+ * @param minutes - minutes east of UTC.
217
+ * @returns the label.
218
+ *
219
+ * @stability experimental
220
+ */
221
+ export function formatUtcOffset(minutes) {
222
+ if (!Number.isFinite(minutes) || minutes === 0)
223
+ return 'UTC';
224
+ const sign = minutes < 0 ? '−' : '+';
225
+ const abs = Math.abs(Math.round(minutes));
226
+ return `UTC${sign}${String(Math.floor(abs / 60)).padStart(2, '0')}:${String(abs % 60).padStart(2, '0')}`;
227
+ }
228
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/core/time-zone/format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * The `localStorage` key the chosen zone is cached under, so a reload renders
3
+ * in the right zone before the settings fetch lands.
4
+ *
5
+ * @stability experimental
6
+ */
7
+ export declare const TIME_ZONE_STORAGE_KEY = "platform.timezone";
8
+ /**
9
+ * The IANA zone this device reports (`Europe/Paris`), or `'UTC'` when the
10
+ * runtime does not say.
11
+ *
12
+ * @returns the device's zone id.
13
+ *
14
+ * @stability experimental
15
+ */
16
+ export declare function deviceTimeZone(): string;
17
+ /**
18
+ * The zone the user chose (`profile.timezone`), or `null` when they follow the
19
+ * device.
20
+ *
21
+ * @returns the stored choice.
22
+ *
23
+ * @stability experimental
24
+ */
25
+ export declare function getPreferredTimeZone(): string | null;
26
+ /**
27
+ * The zone every packaged time is rendered in: the user's choice, else the
28
+ * device's zone, else `'UTC'`.
29
+ *
30
+ * @returns an IANA zone id.
31
+ *
32
+ * @stability experimental
33
+ */
34
+ export declare function getDisplayTimeZone(): string;
35
+ /**
36
+ * Sets the user's choice (`null` follows the device again) and notifies every
37
+ * subscriber. An id the runtime does not know is ignored. The value is cached
38
+ * in `localStorage` (`platform.timezone`) when the browser allows it.
39
+ *
40
+ * @param id - an IANA zone id, or `null`.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * setPreferredTimeZone(settings.profile.timezone ?? null);
45
+ * ```
46
+ *
47
+ * @stability experimental
48
+ */
49
+ export declare function setPreferredTimeZone(id: string | null): void;
50
+ /**
51
+ * Calls `listener` whenever the display zone may have changed.
52
+ *
53
+ * @param listener - called with no argument.
54
+ * @returns the unsubscribe function.
55
+ *
56
+ * @stability experimental
57
+ */
58
+ export declare function subscribeDisplayTimeZone(listener: () => void): () => void;
59
+ /**
60
+ * The display zone, re-rendering the component when it changes. Use it in a
61
+ * component that formats times, so a saved profile re-renders them.
62
+ *
63
+ * @returns the effective IANA zone id ({@link getDisplayTimeZone}).
64
+ *
65
+ * @example
66
+ * ```tsx
67
+ * const zone = useDisplayTimeZone();
68
+ * return <span>{formatDateTime(job.createdAt, { timeZone: zone })}</span>;
69
+ * ```
70
+ *
71
+ * @extensionPoint hook
72
+ * @stability experimental
73
+ */
74
+ export declare function useDisplayTimeZone(): string;
75
+ /**
76
+ * The user's stored choice, re-rendering on change (`null`: follow the device).
77
+ *
78
+ * @returns the choice ({@link getPreferredTimeZone}).
79
+ *
80
+ * @stability experimental
81
+ */
82
+ export declare function usePreferredTimeZone(): string | null;
83
+ /**
84
+ * `profile.timezone` out of a settings profile: the id when it is a valid zone,
85
+ * else `null`.
86
+ *
87
+ * @param profile - a stored profile (any shape).
88
+ * @returns the zone id, or `null`.
89
+ *
90
+ * @stability experimental
91
+ */
92
+ export declare function timeZoneFromProfile(profile: unknown): string | null;
93
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../../src/core/time-zone/store.ts"],"names":[],"mappings":"AAYA;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,sBAAsB,CAAC;AA2BzD;;;;;;;GAOG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAWvC;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,IAAI,CAEpD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAM5D;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAKzE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,GAAG,IAAI,CAEpD;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAInE"}
@@ -0,0 +1,170 @@
1
+ // The display time zone: one module-level store, so a pure formatter, a hook
2
+ // and code outside React all read the same answer. The user's choice comes
3
+ // from `profile.timezone` (pushed here by `UserTimeZoneSync` of the timezone
4
+ // slice and by `useUserSettings` of the settings slice); without one, the
5
+ // device's zone. It lives in `core`, not in the timezone slice, because every
6
+ // slice renders dates (identity included, which the timezone slice depends
7
+ // on): core is the one place all of them may import without a cycle. The
8
+ // timezone slice re-exports it from `/timezone/headless`.
9
+ import { isValidTimeZone } from '@marinoscar/platform-contract/settings';
10
+ import { useSyncExternalStore } from 'react';
11
+ /**
12
+ * The `localStorage` key the chosen zone is cached under, so a reload renders
13
+ * in the right zone before the settings fetch lands.
14
+ *
15
+ * @stability experimental
16
+ */
17
+ export const TIME_ZONE_STORAGE_KEY = 'platform.timezone';
18
+ const listeners = new Set();
19
+ function readCache() {
20
+ try {
21
+ const cached = globalThis.localStorage?.getItem(TIME_ZONE_STORAGE_KEY) ?? null;
22
+ return isValidTimeZone(cached) ? cached : null;
23
+ }
24
+ catch {
25
+ return null;
26
+ }
27
+ }
28
+ function writeCache(id) {
29
+ try {
30
+ const storage = globalThis.localStorage;
31
+ if (!storage)
32
+ return;
33
+ if (id === null)
34
+ storage.removeItem(TIME_ZONE_STORAGE_KEY);
35
+ else
36
+ storage.setItem(TIME_ZONE_STORAGE_KEY, id);
37
+ }
38
+ catch {
39
+ // Private mode or blocked storage: the choice still applies to this page.
40
+ }
41
+ }
42
+ let preferred = readCache();
43
+ let device;
44
+ /**
45
+ * The IANA zone this device reports (`Europe/Paris`), or `'UTC'` when the
46
+ * runtime does not say.
47
+ *
48
+ * @returns the device's zone id.
49
+ *
50
+ * @stability experimental
51
+ */
52
+ export function deviceTimeZone() {
53
+ if (device !== undefined)
54
+ return device;
55
+ let zone = 'UTC';
56
+ try {
57
+ const resolved = new Intl.DateTimeFormat().resolvedOptions().timeZone;
58
+ if (isValidTimeZone(resolved))
59
+ zone = resolved;
60
+ }
61
+ catch {
62
+ // An engine without Intl time zone support: UTC.
63
+ }
64
+ device = zone;
65
+ return zone;
66
+ }
67
+ /**
68
+ * The zone the user chose (`profile.timezone`), or `null` when they follow the
69
+ * device.
70
+ *
71
+ * @returns the stored choice.
72
+ *
73
+ * @stability experimental
74
+ */
75
+ export function getPreferredTimeZone() {
76
+ return preferred;
77
+ }
78
+ /**
79
+ * The zone every packaged time is rendered in: the user's choice, else the
80
+ * device's zone, else `'UTC'`.
81
+ *
82
+ * @returns an IANA zone id.
83
+ *
84
+ * @stability experimental
85
+ */
86
+ export function getDisplayTimeZone() {
87
+ return preferred ?? deviceTimeZone();
88
+ }
89
+ /**
90
+ * Sets the user's choice (`null` follows the device again) and notifies every
91
+ * subscriber. An id the runtime does not know is ignored. The value is cached
92
+ * in `localStorage` (`platform.timezone`) when the browser allows it.
93
+ *
94
+ * @param id - an IANA zone id, or `null`.
95
+ *
96
+ * @example
97
+ * ```ts
98
+ * setPreferredTimeZone(settings.profile.timezone ?? null);
99
+ * ```
100
+ *
101
+ * @stability experimental
102
+ */
103
+ export function setPreferredTimeZone(id) {
104
+ if (id !== null && !isValidTimeZone(id))
105
+ return;
106
+ if (id === preferred)
107
+ return;
108
+ preferred = id;
109
+ writeCache(id);
110
+ for (const listener of [...listeners])
111
+ listener();
112
+ }
113
+ /**
114
+ * Calls `listener` whenever the display zone may have changed.
115
+ *
116
+ * @param listener - called with no argument.
117
+ * @returns the unsubscribe function.
118
+ *
119
+ * @stability experimental
120
+ */
121
+ export function subscribeDisplayTimeZone(listener) {
122
+ listeners.add(listener);
123
+ return () => {
124
+ listeners.delete(listener);
125
+ };
126
+ }
127
+ /**
128
+ * The display zone, re-rendering the component when it changes. Use it in a
129
+ * component that formats times, so a saved profile re-renders them.
130
+ *
131
+ * @returns the effective IANA zone id ({@link getDisplayTimeZone}).
132
+ *
133
+ * @example
134
+ * ```tsx
135
+ * const zone = useDisplayTimeZone();
136
+ * return <span>{formatDateTime(job.createdAt, { timeZone: zone })}</span>;
137
+ * ```
138
+ *
139
+ * @extensionPoint hook
140
+ * @stability experimental
141
+ */
142
+ export function useDisplayTimeZone() {
143
+ return useSyncExternalStore(subscribeDisplayTimeZone, getDisplayTimeZone, getDisplayTimeZone);
144
+ }
145
+ /**
146
+ * The user's stored choice, re-rendering on change (`null`: follow the device).
147
+ *
148
+ * @returns the choice ({@link getPreferredTimeZone}).
149
+ *
150
+ * @stability experimental
151
+ */
152
+ export function usePreferredTimeZone() {
153
+ return useSyncExternalStore(subscribeDisplayTimeZone, getPreferredTimeZone, getPreferredTimeZone);
154
+ }
155
+ /**
156
+ * `profile.timezone` out of a settings profile: the id when it is a valid zone,
157
+ * else `null`.
158
+ *
159
+ * @param profile - a stored profile (any shape).
160
+ * @returns the zone id, or `null`.
161
+ *
162
+ * @stability experimental
163
+ */
164
+ export function timeZoneFromProfile(profile) {
165
+ if (!profile || typeof profile !== 'object')
166
+ return null;
167
+ const value = profile.timezone;
168
+ return isValidTimeZone(value) ? value : null;
169
+ }
170
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/core/time-zone/store.ts"],"names":[],"mappings":"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"}
@@ -31,7 +31,7 @@ export interface SavedSecretHelperTextOptions {
31
31
  /**
32
32
  * Formats the last-change date.
33
33
  *
34
- * @defaultValue `date.toLocaleDateString()`
34
+ * @defaultValue the numeric date (`toLocaleDateString()`'s fields) in the display time zone
35
35
  */
36
36
  readonly formatDate?: (date: Date) => string;
37
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"saved-secret.d.ts","sourceRoot":"","sources":["../../../src/credentials/headless/saved-secret.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAEnF;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,GAC3D,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC,GAAG;IAC1C,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;CAC3C,CAAC;AAEJ;;;;GAIG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;CAC9C;AAOD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,EACxC,OAAO,GAAE,4BAAiC,GACzC,MAAM,CASR;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEjE"}
1
+ {"version":3,"file":"saved-secret.d.ts","sourceRoot":"","sources":["../../../src/credentials/headless/saved-secret.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,2CAA2C,CAAC;AAGnF;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,iBAAiB,EAAE,MAAM,CAAC,GAC3D,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC,GAAG;IAC1C,2DAA2D;IAC3D,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC;CAC3C,CAAC;AAEJ;;;;GAIG;AACH,MAAM,WAAW,4BAA4B;IAC3C;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,MAAM,CAAC;CAC9C;AAOD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,EACxC,OAAO,GAAE,4BAAiC,GACzC,MAAM,CASR;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEjE"}
@@ -12,6 +12,7 @@
12
12
  // stored", which is what the sentence tells the user and what
13
13
  // `secretForSubmit` sends.
14
14
  // =============================================================================
15
+ import { NUMERIC_DATE, formatDate } from '../../core/index.js';
15
16
  /** `a key`, `an access key`. */
16
17
  function withArticle(noun) {
17
18
  return /^[aeiou]/i.test(noun) ? `An ${noun}` : `A ${noun}`;
@@ -41,7 +42,7 @@ export function savedSecretHelperText(info, options = {}) {
41
42
  return options.emptyHelp ?? `No ${noun} is saved yet.`;
42
43
  const which = info.hint ? ` (${info.hint})` : '';
43
44
  const date = info.updatedAt ? new Date(info.updatedAt) : null;
44
- const format = options.formatDate ?? ((d) => d.toLocaleDateString());
45
+ const format = options.formatDate ?? ((d) => formatDate(d, NUMERIC_DATE));
45
46
  const when = date && !Number.isNaN(date.getTime()) ? `, updated ${format(date)}` : '';
46
47
  return `${withArticle(noun)} is saved${which}${when}. Leave this blank to keep it, or type a new one to replace it.`;
47
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"saved-secret.js","sourceRoot":"","sources":["../../../src/credentials/headless/saved-secret.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,wDAAwD;AACxD,gFAAgF;AAChF,EAAE;AACF,8EAA8E;AAC9E,0EAA0E;AAC1E,gFAAgF;AAChF,oEAAoE;AACpE,EAAE;AACF,sEAAsE;AACtE,8EAA8E;AAC9E,8DAA8D;AAC9D,2BAA2B;AAC3B,gFAAgF;AA2ChF,gCAAgC;AAChC,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;AAC7D,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAwC,EACxC,UAAwC,EAAE;IAE1C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC;IACnC,IAAI,CAAC,IAAI;QAAE,OAAO,OAAO,CAAC,SAAS,IAAI,MAAM,IAAI,gBAAgB,CAAC;IAElE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9D,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC,CAAO,EAAE,EAAE,CAAC,CAAC,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAC3E,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACtF,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,YAAY,KAAK,GAAG,IAAI,iEAAiE,CAAC;AACvH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"saved-secret.js","sourceRoot":"","sources":["../../../src/credentials/headless/saved-secret.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,wDAAwD;AACxD,gFAAgF;AAChF,EAAE;AACF,8EAA8E;AAC9E,0EAA0E;AAC1E,gFAAgF;AAChF,oEAAoE;AACpE,EAAE;AACF,sEAAsE;AACtE,8EAA8E;AAC9E,8DAA8D;AAC9D,2BAA2B;AAC3B,gFAAgF;AAGhF,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAyC/D,gCAAgC;AAChC,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;AAC7D,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAwC,EACxC,UAAwC,EAAE;IAE1C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC;IACnC,IAAI,CAAC,IAAI;QAAE,OAAO,OAAO,CAAC,SAAS,IAAI,MAAM,IAAI,gBAAgB,CAAC;IAElE,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IACjD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9D,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,IAAI,CAAC,CAAC,CAAO,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;IAChF,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,aAAa,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACtF,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,YAAY,KAAK,GAAG,IAAI,iEAAiE,CAAC;AACvH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;AAC1C,CAAC"}
@@ -20,7 +20,7 @@ export interface SecretFieldProps {
20
20
  emptyHelp?: string;
21
21
  /** What the secret is called in the helper text; default `'key'`. */
22
22
  noun?: string;
23
- /** Formats the last-change date; default `toLocaleDateString()`. */
23
+ /** Formats the last-change date; default the numeric date in the display time zone. */
24
24
  formatDate?: SavedSecretHelperTextOptions['formatDate'];
25
25
  /** Disables the input (a viewer without the write permission). */
26
26
  disabled?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"secret-field.d.ts","sourceRoot":"","sources":["../../../src/credentials/ui/secret-field.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAG1C,OAAO,KAAK,EAAE,4BAA4B,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE1F;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,wFAAwF;IACxF,KAAK,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,UAAU,CAAC,EAAE,4BAA4B,CAAC,YAAY,CAAC,CAAC;IACxD,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,mCAAmC;IACnC,EAAE,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACpB;;;OAGG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4EAA4E;IAC5E,SAAS,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC;CAC1E;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,CA4BjE"}
1
+ {"version":3,"file":"secret-field.d.ts","sourceRoot":"","sources":["../../../src/credentials/ui/secret-field.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAEpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAG1C,OAAO,KAAK,EAAE,4BAA4B,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG1F;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yBAAyB;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAC;IACd,iDAAiD;IACjD,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,wFAAwF;IACxF,KAAK,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uFAAuF;IACvF,UAAU,CAAC,EAAE,4BAA4B,CAAC,YAAY,CAAC,CAAC;IACxD,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,mCAAmC;IACnC,EAAE,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACpB;;;OAGG;IACH,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4EAA4E;IAC5E,SAAS,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC;CAC1E;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,YAAY,CA6BjE"}
@@ -13,6 +13,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
13
13
  import { TextField } from '@mui/material';
14
14
  import { useId } from 'react';
15
15
  import { savedSecretHelperText } from '../headless/index.js';
16
+ import { useDisplayTimeZone } from '../../core/index.js';
16
17
  /**
17
18
  * A write-only secret input with the unified "saved secret" helper text.
18
19
  *
@@ -34,6 +35,7 @@ import { savedSecretHelperText } from '../headless/index.js';
34
35
  * @stability experimental
35
36
  */
36
37
  export function SecretField(props) {
38
+ useDisplayTimeZone(); // "updated" renders in the display zone.
37
39
  const generatedId = useId();
38
40
  const id = props.id ?? `secret-field-${generatedId.replace(/[^A-Za-z0-9_-]/g, '')}`;
39
41
  const helper = props.error ??
@@ -1 +1 @@
1
- {"version":3,"file":"secret-field.js","sourceRoot":"","sources":["../../../src/credentials/ui/secret-field.tsx"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,8DAA8D;AAC9D,gFAAgF;AAChF,EAAE;AACF,0EAA0E;AAC1E,+EAA+E;AAC/E,wEAAwE;AACxE,8EAA8E;AAC9E,4EAA4E;AAC5E,4DAA4D;AAC5D,gFAAgF;AAEhF,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAG9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAmD7D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,MAAM,WAAW,GAAG,KAAK,EAAE,CAAC;IAC5B,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,IAAI,gBAAgB,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,EAAE,CAAC;IACpF,MAAM,MAAM,GACV,KAAK,CAAC,KAAK;QACX,qBAAqB,CAAC,KAAK,CAAC,KAAK,EAAE;YACjC,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzD,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxE,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5E,CAAC,CAAC;IAEL,OAAO,CACL,KAAC,SAAS,IACR,EAAE,EAAE,EAAE,EACN,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAC3B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAC,cAAc,EAC3B,SAAS,QACT,EAAE,EAAE,KAAK,CAAC,EAAE,KACR,KAAK,CAAC,KAAK,EAAE,SAAS,EAC1B,IAAI,EAAC,UAAU,EACf,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GACvD,CACH,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"secret-field.js","sourceRoot":"","sources":["../../../src/credentials/ui/secret-field.tsx"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,8DAA8D;AAC9D,gFAAgF;AAChF,EAAE;AACF,0EAA0E;AAC1E,+EAA+E;AAC/E,wEAAwE;AACxE,8EAA8E;AAC9E,4EAA4E;AAC5E,4DAA4D;AAC5D,gFAAgF;AAEhF,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAG9B,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAkDzD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,kBAAkB,EAAE,CAAC,CAAC,yCAAyC;IAC/D,MAAM,WAAW,GAAG,KAAK,EAAE,CAAC;IAC5B,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,IAAI,gBAAgB,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,EAAE,CAAC;IACpF,MAAM,MAAM,GACV,KAAK,CAAC,KAAK;QACX,qBAAqB,CAAC,KAAK,CAAC,KAAK,EAAE;YACjC,GAAG,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzD,GAAG,CAAC,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACxE,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC5E,CAAC,CAAC;IAEL,OAAO,CACL,KAAC,SAAS,IACR,EAAE,EAAE,EAAE,EACN,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAC3B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAC,cAAc,EAC3B,SAAS,QACT,EAAE,EAAE,KAAK,CAAC,EAAE,KACR,KAAK,CAAC,KAAK,EAAE,SAAS,EAC1B,IAAI,EAAC,UAAU,EACf,KAAK,EAAE,KAAK,CAAC,KAAK,EAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GACvD,CACH,CAAC;AACJ,CAAC"}
@@ -13,7 +13,10 @@
13
13
  */
14
14
  export declare function formatDuration(ms: number | null | undefined): string;
15
15
  /**
16
- * A timestamp in the viewer's locale, or an em dash when the API sent `null`.
16
+ * A timestamp in the viewer's locale and display time zone (the user's
17
+ * `profile.timezone`, else the device's), or an em dash when the API sent `null`.
18
+ * A component that renders it calls `useDisplayTimeZone()` so a zone change
19
+ * re-renders it.
17
20
  *
18
21
  * @param value - an ISO 8601 timestamp, or `null`.
19
22
  * @returns the localized date and time, or an em dash.
@@ -1 +1 @@
1
- {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/db-backup/internal/format.ts"],"names":[],"mappings":"AAcA;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAiBpE;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAEvE;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE1C"}
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../../src/db-backup/internal/format.ts"],"names":[],"mappings":"AAgBA;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAiBpE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAEvE;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE1C"}
@@ -11,6 +11,7 @@
11
11
  // page never reads "1500ms" beside one reading "1.5 s" for the same number.
12
12
  // Pure functions, no markup, so they live in the headless entry.
13
13
  // =============================================================================
14
+ import { NUMERIC_DATE_TIME, formatDateTime as formatZonedDateTime } from '../../core/index.js';
14
15
  /**
15
16
  * A duration, in the largest unit that still says something: `850 ms`,
16
17
  * `1.5 s`, `4m 05s`, `2h 03m`, `3d 4h`.
@@ -44,7 +45,10 @@ export function formatDuration(ms) {
44
45
  return `${days}d ${hours % 24}h`;
45
46
  }
46
47
  /**
47
- * A timestamp in the viewer's locale, or an em dash when the API sent `null`.
48
+ * A timestamp in the viewer's locale and display time zone (the user's
49
+ * `profile.timezone`, else the device's), or an em dash when the API sent `null`.
50
+ * A component that renders it calls `useDisplayTimeZone()` so a zone change
51
+ * re-renders it.
48
52
  *
49
53
  * @param value - an ISO 8601 timestamp, or `null`.
50
54
  * @returns the localized date and time, or an em dash.
@@ -52,7 +56,7 @@ export function formatDuration(ms) {
52
56
  * @stability experimental
53
57
  */
54
58
  export function formatDateTime(value) {
55
- return value ? new Date(value).toLocaleString() : '—';
59
+ return formatZonedDateTime(value, NUMERIC_DATE_TIME);
56
60
  }
57
61
  /**
58
62
  * The first 8 characters of a UUID: enough to tell two rows apart by eye.
@@ -1 +1 @@
1
- {"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/db-backup/internal/format.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,+EAA+E;AAC/E,kDAAkD;AAClD,gFAAgF;AAChF,mDAAmD;AACnD,gFAAgF;AAChF,EAAE;AACF,4EAA4E;AAC5E,4EAA4E;AAC5E,2EAA2E;AAC3E,4EAA4E;AAC5E,iEAAiE;AACjE,gFAAgF;AAEhF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAC,EAA6B;IAC1D,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QAAE,OAAO,GAAG,CAAC;IACxE,IAAI,EAAE,GAAG,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC;IAE7C,MAAM,YAAY,GAAG,EAAE,GAAG,IAAI,CAAC;IAC/B,IAAI,YAAY,GAAG,EAAE;QAAE,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAE7D,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;IAC9C,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IAE5E,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACvC,MAAM,gBAAgB,GAAG,OAAO,GAAG,EAAE,CAAC;IACtC,IAAI,KAAK,GAAG,EAAE;QAAE,OAAO,GAAG,KAAK,KAAK,MAAM,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IAEjF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACpC,OAAO,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE,GAAG,CAAC;AACnC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,KAAgC;IAC7D,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;AACxD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAC,EAAU;IAChC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACxB,CAAC"}
1
+ {"version":3,"file":"format.js","sourceRoot":"","sources":["../../../src/db-backup/internal/format.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,+EAA+E;AAC/E,kDAAkD;AAClD,gFAAgF;AAChF,mDAAmD;AACnD,gFAAgF;AAChF,EAAE;AACF,4EAA4E;AAC5E,4EAA4E;AAC5E,2EAA2E;AAC3E,4EAA4E;AAC5E,iEAAiE;AACjE,gFAAgF;AAEhF,OAAO,EAAE,iBAAiB,EAAE,cAAc,IAAI,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE/F;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,cAAc,CAAC,EAA6B;IAC1D,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;QAAE,OAAO,GAAG,CAAC;IACxE,IAAI,EAAE,GAAG,IAAI;QAAE,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC;IAE7C,MAAM,YAAY,GAAG,EAAE,GAAG,IAAI,CAAC;IAC/B,IAAI,YAAY,GAAG,EAAE;QAAE,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;IAE7D,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,EAAE,CAAC,CAAC;IAC9C,IAAI,OAAO,GAAG,EAAE;QAAE,OAAO,GAAG,OAAO,KAAK,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IAE5E,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACvC,MAAM,gBAAgB,GAAG,OAAO,GAAG,EAAE,CAAC;IACtC,IAAI,KAAK,GAAG,EAAE;QAAE,OAAO,GAAG,KAAK,KAAK,MAAM,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC;IAEjF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACpC,OAAO,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE,GAAG,CAAC;AACnC,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,KAAgC;IAC7D,OAAO,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,OAAO,CAAC,EAAU;IAChC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACxB,CAAC"}