@everfur/sdk 0.1.1 → 0.4.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 (219) hide show
  1. package/CHANGELOG.md +703 -4
  2. package/README.md +63 -23
  3. package/consent/package.json +8 -0
  4. package/dist/Chat-BZZ-Py5l.d.ts +128 -0
  5. package/dist/Chat-Dq4fffIO.d.cts +128 -0
  6. package/dist/DepthViews-BG3E25MD.d.ts +16 -0
  7. package/dist/DepthViews-B_hIypI6.d.cts +19 -0
  8. package/dist/DepthViews-CL75jyRA.d.cts +16 -0
  9. package/dist/DepthViews-CkYri51q.d.ts +19 -0
  10. package/dist/ErrorPolicyPort-CNf4uQZP.d.cts +22 -0
  11. package/dist/ErrorPolicyPort-CwbfmxzJ.d.ts +22 -0
  12. package/dist/{EverfurResult-D92-uL82.d.cts → EverfurResult-DN9pL2Ab.d.cts} +11 -10
  13. package/dist/{EverfurResult-D92-uL82.d.ts → EverfurResult-DN9pL2Ab.d.ts} +11 -10
  14. package/dist/{PhotoController-BItt5M7u.d.cts → PhotoController-3l7MT9jA.d.cts} +1 -1
  15. package/dist/{PhotoController-D8zMTdcW.d.ts → PhotoController-vzY5bfY_.d.ts} +1 -1
  16. package/dist/animations/index.cjs +1 -1997
  17. package/dist/animations/index.d.cts +35 -35
  18. package/dist/animations/index.d.ts +35 -35
  19. package/dist/animations/index.js +1 -1972
  20. package/dist/attachments-BorG422I.d.cts +146 -0
  21. package/dist/attachments-BrUWQYNK.d.ts +257 -0
  22. package/dist/attachments-D_SECjr1.d.cts +257 -0
  23. package/dist/attachments-DpldrvIW.d.ts +146 -0
  24. package/dist/bookingCopy-CqtDYvCR.d.ts +732 -0
  25. package/dist/bookingCopy-SREvkG19.d.cts +732 -0
  26. package/dist/branding-CsRdeNwK.d.cts +566 -0
  27. package/dist/branding-CsRdeNwK.d.ts +566 -0
  28. package/dist/callCopy-DoQKG3-L.d.cts +40 -0
  29. package/dist/callCopy-DoQKG3-L.d.ts +40 -0
  30. package/dist/casesRepository-DwtZVsbj.d.cts +51 -0
  31. package/dist/casesRepository-v6QczS9N.d.ts +51 -0
  32. package/dist/chat/index.cjs +1 -1170
  33. package/dist/chat/index.d.cts +32 -53
  34. package/dist/chat/index.d.ts +32 -53
  35. package/dist/chat/index.js +1 -1167
  36. package/dist/client/index.cjs +9 -2315
  37. package/dist/client/index.d.cts +80 -16
  38. package/dist/client/index.d.ts +80 -16
  39. package/dist/client/index.js +9 -2215
  40. package/dist/{config-CiJ0PVBB.d.ts → config--Wu1Umhd.d.cts} +64 -26
  41. package/dist/{config-BSjBdxrZ.d.cts → config-C7eb_IMD.d.ts} +64 -26
  42. package/dist/consent/index.cjs +1 -0
  43. package/dist/consent/index.d.cts +33 -0
  44. package/dist/consent/index.d.ts +33 -0
  45. package/dist/consent/index.js +1 -0
  46. package/dist/context-CL3lyuy1.d.cts +159 -0
  47. package/dist/context-CahAEha8.d.ts +159 -0
  48. package/dist/copy-DdVFDL01.d.ts +198 -0
  49. package/dist/copy-UeUJVk8X.d.cts +198 -0
  50. package/dist/core/index.cjs +13 -3178
  51. package/dist/core/index.d.cts +164 -29
  52. package/dist/core/index.d.ts +164 -29
  53. package/dist/core/index.js +13 -3166
  54. package/dist/depth-D5HwcvKC.d.cts +533 -0
  55. package/dist/depth-DvPwPuT_.d.ts +533 -0
  56. package/dist/entitlementRepository-B7egEdW6.d.ts +43 -0
  57. package/dist/entitlementRepository-BpJ7tiwl.d.cts +43 -0
  58. package/dist/{identity-Brl-lDd6.d.cts → identity-C2-08BZW.d.cts} +20 -7
  59. package/dist/{identity-DK9zORrG.d.ts → identity-CEi9GRFZ.d.ts} +20 -7
  60. package/dist/{ids-CJ1S6adf.d.cts → ids-B2GAAifq.d.cts} +1 -1
  61. package/dist/{ids-CJ1S6adf.d.ts → ids-B2GAAifq.d.ts} +1 -1
  62. package/dist/index.cjs +12 -4494
  63. package/dist/index.d.cts +30 -121
  64. package/dist/index.d.ts +30 -121
  65. package/dist/index.js +12 -4470
  66. package/dist/models-B-Uh2LTf.d.ts +214 -0
  67. package/dist/models-D2EUxPZY.d.cts +214 -0
  68. package/dist/notifications/index.cjs +2 -0
  69. package/dist/notifications/index.d.cts +17 -0
  70. package/dist/notifications/index.d.ts +17 -0
  71. package/dist/notifications/index.js +2 -0
  72. package/dist/optionalModule-DbJmsq5f.d.cts +21 -0
  73. package/dist/optionalModule-DbJmsq5f.d.ts +21 -0
  74. package/dist/pets-DJv2sj2H.d.ts +92 -0
  75. package/dist/pets-JVCXgRgR.d.cts +92 -0
  76. package/dist/petsRepository-B_gKbAzJ.d.cts +142 -0
  77. package/dist/petsRepository-Bk6GDwLs.d.ts +142 -0
  78. package/dist/photo/index.cjs +1 -2189
  79. package/dist/photo/index.d.cts +6 -6
  80. package/dist/photo/index.d.ts +6 -6
  81. package/dist/photo/index.js +1 -2186
  82. package/dist/ports-BN6RHF9W.d.cts +48 -0
  83. package/dist/ports-BN6RHF9W.d.ts +48 -0
  84. package/dist/ports-BY2ph0_y.d.cts +376 -0
  85. package/dist/ports-D7YW8qz9.d.ts +376 -0
  86. package/dist/profile-CSs1wlXT.d.cts +93 -0
  87. package/dist/profile-CSs1wlXT.d.ts +93 -0
  88. package/dist/records/depth/index.cjs +2 -0
  89. package/dist/records/depth/index.d.cts +13 -0
  90. package/dist/records/depth/index.d.ts +13 -0
  91. package/dist/records/depth/index.js +2 -0
  92. package/dist/records/index.cjs +3 -2839
  93. package/dist/records/index.d.cts +137 -203
  94. package/dist/records/index.d.ts +137 -203
  95. package/dist/records/index.js +3 -2833
  96. package/dist/requestFunnel-BjDpqqvm.d.cts +110 -0
  97. package/dist/requestFunnel-DFMGcluw.d.ts +110 -0
  98. package/dist/{resolve-Dq_4_agU.d.ts → resolve-D4Ywz5OS.d.cts} +10 -4
  99. package/dist/{resolve-Dq_4_agU.d.cts → resolve-D4Ywz5OS.d.ts} +10 -4
  100. package/dist/{runtime-Bvr8yqXm.d.cts → runtimeTypes-gZEJu-da.d.cts} +104 -132
  101. package/dist/{runtime-BIYzf9cK.d.ts → runtimeTypes-w5KqBMcs.d.ts} +104 -132
  102. package/dist/server/events/index.cjs +2 -0
  103. package/dist/server/events/index.d.cts +550 -0
  104. package/dist/server/events/index.d.ts +550 -0
  105. package/dist/server/events/index.js +2 -0
  106. package/dist/server/index.cjs +2 -533
  107. package/dist/server/index.d.cts +73 -18
  108. package/dist/server/index.d.ts +73 -18
  109. package/dist/server/index.js +2 -530
  110. package/dist/species-BXAIMh7I.d.cts +9 -0
  111. package/dist/species-BXAIMh7I.d.ts +9 -0
  112. package/dist/televet/booking/index.cjs +1 -0
  113. package/dist/televet/booking/index.d.cts +294 -0
  114. package/dist/televet/booking/index.d.ts +294 -0
  115. package/dist/televet/booking/index.js +1 -0
  116. package/dist/televet/call/index.cjs +1 -0
  117. package/dist/televet/call/index.d.cts +141 -0
  118. package/dist/televet/call/index.d.ts +141 -0
  119. package/dist/televet/call/index.js +1 -0
  120. package/dist/televet/index.cjs +1 -0
  121. package/dist/televet/index.d.cts +142 -0
  122. package/dist/televet/index.d.ts +142 -0
  123. package/dist/televet/index.js +1 -0
  124. package/dist/testing/index.cjs +5 -823
  125. package/dist/testing/index.d.cts +18 -4
  126. package/dist/testing/index.d.ts +18 -4
  127. package/dist/testing/index.js +5 -820
  128. package/dist/testing/rn/index.cjs +1 -449
  129. package/dist/testing/rn/index.d.cts +18 -29
  130. package/dist/testing/rn/index.d.ts +18 -29
  131. package/dist/testing/rn/index.js +1 -444
  132. package/dist/testing/web/index.cjs +1 -0
  133. package/dist/testing/web/index.d.cts +132 -0
  134. package/dist/testing/web/index.d.ts +132 -0
  135. package/dist/testing/web/index.js +1 -0
  136. package/dist/timelineRows-C15jxFFH.d.ts +19 -0
  137. package/dist/timelineRows-odO8g9r2.d.cts +19 -0
  138. package/dist/typeStyle-CKqVYD6L.d.cts +111 -0
  139. package/dist/typeStyle-DmoyacDG.d.ts +111 -0
  140. package/dist/uploadTransport-D0M0T4hN.d.ts +38 -0
  141. package/dist/uploadTransport-DKJHs3Yj.d.cts +38 -0
  142. package/dist/useRecordsDepth-C6rjEaLn.d.cts +237 -0
  143. package/dist/useRecordsDepth-crhBllQK.d.ts +237 -0
  144. package/dist/useVetVisit-Bc84hWUU.d.cts +187 -0
  145. package/dist/useVetVisit-CjmMa896.d.ts +187 -0
  146. package/dist/video/index.cjs +1 -1941
  147. package/dist/video/index.d.cts +4 -4
  148. package/dist/video/index.d.ts +4 -4
  149. package/dist/video/index.js +1 -1938
  150. package/dist/view-Bxwxp4xD.d.ts +310 -0
  151. package/dist/view-DyitEO0m.d.cts +310 -0
  152. package/dist/visitIntent-D7_yVp1I.d.cts +8 -0
  153. package/dist/visitIntent-D7_yVp1I.d.ts +8 -0
  154. package/dist/web/consent/index.cjs +1 -0
  155. package/dist/web/consent/index.d.cts +34 -0
  156. package/dist/web/consent/index.d.ts +34 -0
  157. package/dist/web/consent/index.js +1 -0
  158. package/dist/web/index.cjs +14 -0
  159. package/dist/web/index.d.cts +218 -0
  160. package/dist/web/index.d.ts +218 -0
  161. package/dist/web/index.js +14 -0
  162. package/dist/web/notifications/index.cjs +2 -0
  163. package/dist/web/notifications/index.d.cts +213 -0
  164. package/dist/web/notifications/index.d.ts +213 -0
  165. package/dist/web/notifications/index.js +2 -0
  166. package/dist/web/records/depth/index.cjs +2 -0
  167. package/dist/web/records/depth/index.d.cts +12 -0
  168. package/dist/web/records/depth/index.d.ts +12 -0
  169. package/dist/web/records/depth/index.js +2 -0
  170. package/dist/web/records/index.cjs +4 -0
  171. package/dist/web/records/index.d.cts +285 -0
  172. package/dist/web/records/index.d.ts +285 -0
  173. package/dist/web/records/index.js +4 -0
  174. package/dist/web/televet/booking/index.cjs +1 -0
  175. package/dist/web/televet/booking/index.d.cts +349 -0
  176. package/dist/web/televet/booking/index.d.ts +349 -0
  177. package/dist/web/televet/booking/index.js +1 -0
  178. package/dist/web/televet/call/index.cjs +1 -0
  179. package/dist/web/televet/call/index.d.cts +142 -0
  180. package/dist/web/televet/call/index.d.ts +142 -0
  181. package/dist/web/televet/call/index.js +1 -0
  182. package/dist/web/televet/index.cjs +1 -0
  183. package/dist/web/televet/index.d.cts +136 -0
  184. package/dist/web/televet/index.d.ts +136 -0
  185. package/dist/web/televet/index.js +1 -0
  186. package/notifications/package.json +8 -0
  187. package/package.json +266 -10
  188. package/records/depth/package.json +8 -0
  189. package/server/events/device-blocked.cjs +15 -0
  190. package/server/events/package.json +9 -0
  191. package/televet/booking/package.json +8 -0
  192. package/televet/call/package.json +8 -0
  193. package/televet/package.json +8 -0
  194. package/testing/web/native-blocked.cjs +12 -0
  195. package/testing/web/package.json +8 -0
  196. package/web/consent/native-blocked.cjs +12 -0
  197. package/web/consent/package.json +8 -0
  198. package/web/native-blocked.cjs +12 -0
  199. package/web/notifications/native-blocked.cjs +12 -0
  200. package/web/notifications/package.json +8 -0
  201. package/web/package.json +8 -0
  202. package/web/records/depth/native-blocked.cjs +12 -0
  203. package/web/records/depth/package.json +8 -0
  204. package/web/records/native-blocked.cjs +12 -0
  205. package/web/records/package.json +8 -0
  206. package/web/televet/booking/native-blocked.cjs +12 -0
  207. package/web/televet/booking/package.json +8 -0
  208. package/web/televet/call/native-blocked.cjs +12 -0
  209. package/web/televet/call/package.json +8 -0
  210. package/web/televet/native-blocked.cjs +12 -0
  211. package/web/televet/package.json +8 -0
  212. package/dist/ChatController-CKdBvPj2.d.ts +0 -146
  213. package/dist/ChatController-CpUMvvZf.d.cts +0 -146
  214. package/dist/FilePort-BabWrv7I.d.cts +0 -22
  215. package/dist/FilePort-BabWrv7I.d.ts +0 -22
  216. package/dist/petsRepository-BEGb97M9.d.cts +0 -326
  217. package/dist/petsRepository-Bu18r2kK.d.ts +0 -326
  218. package/dist/requestFunnel-DuUH-kAe.d.cts +0 -28
  219. package/dist/requestFunnel-dio5OmR9.d.ts +0 -28
@@ -0,0 +1,566 @@
1
+ /** The fixed set of slot names, in the order the surfaces list them. */
2
+ declare const THEME_SLOT_NAMES: readonly ["composerInput", "sendButton", "userBubble", "assistantBubble", "recordCard", "vetVisitButton", "primaryButton", "link"];
3
+ type EverfurThemeSlotName = (typeof THEME_SLOT_NAMES)[number];
4
+ /** The allow-listed paint keys a slot accepts. */
5
+ declare const THEME_SLOT_KEYS: readonly ["backgroundColor", "borderColor", "borderRadius", "textColor"];
6
+ type EverfurThemeSlotKey = (typeof THEME_SLOT_KEYS)[number];
7
+ /** One slot's paint: every key optional; a key that is absent keeps the surface's own token. */
8
+ interface EverfurThemeSlot {
9
+ /** Normalized colour (`#RRGGBB` or `rgba(...)`). */
10
+ readonly backgroundColor?: string;
11
+ readonly borderColor?: string;
12
+ /** A corner radius in dp/px; never negative. */
13
+ readonly borderRadius?: number;
14
+ /**
15
+ * Normalized colour; guarded at 4.5:1 against `backgroundColor`, or against the slot's default ground when the
16
+ * slot sets no background (see `guardSlotContrast`).
17
+ */
18
+ readonly textColor?: string;
19
+ }
20
+ /** The slot map a resolved theme carries: only the slots that were set, each frozen. */
21
+ type EverfurThemeSlots = Readonly<Partial<Record<EverfurThemeSlotName, EverfurThemeSlot>>>;
22
+ /** The minimum text-on-background ratio a slot may paint (WCAG AA body text). */
23
+ declare const SLOT_MIN_CONTRAST = 4.5;
24
+ /**
25
+ * Parse an untrusted `slots` blob into the typed slot map. Unknown slot names and unknown keys are ignored, a
26
+ * malformed colour or radius is dropped, and a slot left with no valid key is dropped. Returns null when nothing
27
+ * valid remains (callers read null as "unset"). Never throws.
28
+ */
29
+ declare function parseThemeSlots(json: unknown): EverfurThemeSlots | null;
30
+ /**
31
+ * Overlay `over` onto `base` slot by slot: a slot the overlay names REPLACES the base slot whole (the backend's
32
+ * overlay unit, so `slots.<name>` locks and overlays agree); a slot it does not name is kept. Either side may be
33
+ * null. Returns a frozen map (the same reference when one side is null or empty).
34
+ */
35
+ declare function mergeThemeSlots(base: EverfurThemeSlots | null, over: EverfurThemeSlots | null): EverfurThemeSlots;
36
+ /** The minimum ratio a slot's edge may reach on its ground (WCAG 1.4.11, the boundary of a control). */
37
+ declare const SLOT_MIN_BORDER_CONTRAST = 3;
38
+ /**
39
+ * The ground each slot's text sits on when the slot sets no background of its own: the surface's default paint
40
+ * at that place, as the resolver knows it. Every slot lists at least one ground; a text colour must read on all
41
+ * of them (the link list names every ground a text link is drawn on).
42
+ */
43
+ type SlotGrounds = Readonly<Record<EverfurThemeSlotName, readonly string[]>>;
44
+ /**
45
+ * The contrast guard: every text colour a slot paints must reach `SLOT_MIN_CONTRAST` on the ground it is drawn on,
46
+ * and every edge `SLOT_MIN_BORDER_CONTRAST` on the fill it bounds.
47
+ * - A TRANSLUCENT background whose seats straddle the white/black crossover is collapsed to the opaque colour
48
+ * it shows over the slot's primary ground FIRST (`collapseUnsatisfiableFill`), because such a slot has no
49
+ * readable ink while it means two colours at once. Everything below then measures against one seat.
50
+ * - A slot that supplies a background: its ink is measured on that fill AS THE EYE SEES IT (`seatsOf`, the fill
51
+ * composited onto the surface's default ground at that slot), and a missing or failing one is replaced by the
52
+ * ink that fill is guaranteed to carry (`legibleOn`), then pushed until it reads on every seat.
53
+ * - A slot without one: its `textColor` is measured on the slot's DEFAULT ground (`grounds`, the surface's own
54
+ * paint there) and, when it fails, pushed toward the legible pole of that ground until it reads, so a text-only
55
+ * slot can never paint invisible text either. Without `grounds` such a slot keeps its colour as supplied.
56
+ * - An edge (`borderColor`) is measured on the fill it bounds (the same seats) and pushed the same way when it
57
+ * reads below 3:1.
58
+ * Returns the same reference when nothing changes.
59
+ */
60
+ declare function guardSlotContrast(slots: EverfurThemeSlots, grounds?: SlotGrounds): EverfurThemeSlots;
61
+
62
+ /**
63
+ * One slot's paint on the `theme` prop; colours in any form `parseColor` reads, the radius in dp/px. The console's
64
+ * snake_case wire keys are accepted beside the camelCase ones.
65
+ */
66
+ interface EverfurThemeSlotInput {
67
+ readonly backgroundColor?: string | number;
68
+ readonly background_color?: string | number;
69
+ readonly borderColor?: string | number;
70
+ readonly border_color?: string | number;
71
+ readonly borderRadius?: number | string;
72
+ readonly border_radius?: number | string;
73
+ readonly textColor?: string | number;
74
+ readonly text_color?: string | number;
75
+ }
76
+ /** The `slots` map on the `theme` prop: any subset of the eight slot names. */
77
+ type EverfurThemeSlotsInput = Readonly<Partial<Record<EverfurThemeSlotName, EverfurThemeSlotInput>>>;
78
+ /**
79
+ * The faces a theme names: the three text weights and the three mono weights (`EverfurFontFaceKey` on the tokens).
80
+ * A missing weight falls back along its chain: bold -> medium -> regular, monoBold -> monoMedium -> mono.
81
+ */
82
+ type EverfurThemeFontFaceKey = 'regular' | 'medium' | 'bold' | 'mono' | 'monoMedium' | 'monoBold';
83
+ /** The `fonts` map on the `theme` prop: a registered family name per face, any subset. */
84
+ type EverfurThemeFontsInput = Readonly<Partial<Record<EverfurThemeFontFaceKey, string>>>;
85
+ /** The `font_urls` map on the `theme` prop (web only): a brand-font URL per face, any subset. */
86
+ type EverfurThemeFontUrlsInput = Readonly<Partial<Record<EverfurThemeFontFaceKey, string>>>;
87
+ /**
88
+ * The client `theme` prop. Any shape is tolerated (unknown keys are ignored, malformed values are dropped); the
89
+ * named keys are the ones the resolver reads, in the console's snake_case with camelCase twins.
90
+ */
91
+ interface EverfurThemeInput {
92
+ readonly display_name?: string;
93
+ readonly displayName?: string;
94
+ readonly logo_url?: string;
95
+ readonly logoUrl?: string;
96
+ /** The logo shown on the dark palette; absent, `logo_url` is shown on both. */
97
+ readonly logo_url_dark?: string;
98
+ readonly logoUrlDark?: string;
99
+ readonly primary_color?: string | number;
100
+ readonly primaryColor?: string | number;
101
+ readonly accent_color?: string | number;
102
+ readonly accentColor?: string | number;
103
+ /** The primary fill on the dark palette; absent, it is derived from `primary_color` (`deriveDarkVariant`). */
104
+ readonly primary_color_dark?: string | number;
105
+ readonly primaryColorDark?: string | number;
106
+ readonly accent_color_dark?: string | number;
107
+ readonly accentColorDark?: string | number;
108
+ /**
109
+ * `light` or `dark` pins the palette; `auto` follows the device's scheme. Absent (here and in the console), the
110
+ * theme is LIGHT, as Everfur's own apps are: the device scheme is never read unless someone chose `auto`.
111
+ */
112
+ readonly brightness?: string;
113
+ /** The console's name for `brightness` (`light`, `dark` or `auto`); `brightness` wins when both are set. */
114
+ readonly color_scheme?: string;
115
+ readonly colorScheme?: string;
116
+ readonly font_family?: string;
117
+ readonly fontFamily?: string;
118
+ readonly font_url?: string;
119
+ readonly fontUrl?: string;
120
+ /**
121
+ * The family per face. Two conventions, the same rendering on React Native and the web:
122
+ * - one registered face per weight, the way the Everfur app maps weight to family (`Azeret-Regular`,
123
+ * `Azeret-Medium`, `Azeret-Bold`, `AzeretMono-Regular`): a name no other weight of its group uses is a NAMED
124
+ * face, rendered with no weight of its own (React Native) or at the normal weight (the web);
125
+ * - one family for every weight (`Azeret`): a name shared across the weights of a group is a BASE family, and
126
+ * every face takes its numeric weight on both hosts.
127
+ * A missing weight falls back along its chain (regular -> medium -> bold, mono -> monoMedium -> monoBold). The host
128
+ * registers the faces itself (the native font files, or a web `@font-face`) and passes the NAMES only: the SDK
129
+ * bundles no font. Beats `font_family` for the weights it names. On React Native, when the app's font registry can
130
+ * tell (expo-font's), a named face that is not registered falls back to the platform font at its weight, with a
131
+ * development warning.
132
+ */
133
+ readonly fonts?: EverfurThemeFontsInput;
134
+ /**
135
+ * Web only: the woff2 URL per face, loaded through the SDK's brand-font allow-list (a woff2 under `/fonts/`
136
+ * on the Everfur SDK CDN). A URL on any other origin is refused, so a host that serves its own licensed
137
+ * faces loads them with its own `@font-face` and passes `fonts` names only.
138
+ */
139
+ readonly font_urls?: EverfurThemeFontUrlsInput;
140
+ readonly fontUrls?: EverfurThemeFontUrlsInput;
141
+ readonly chat_placeholder?: string;
142
+ readonly chatPlaceholder?: string;
143
+ readonly placeholder?: string;
144
+ /** Typed for completeness; INERT on the client. The server decides the attribution from the plan. */
145
+ readonly hide_powered_by?: boolean;
146
+ readonly hidePoweredBy?: boolean;
147
+ /** `white`, `cream` or `subtle`. */
148
+ readonly surface_style?: string;
149
+ readonly surfaceStyle?: string;
150
+ /** `sharp`, `default` or `round`. */
151
+ readonly radius_scale?: string;
152
+ readonly radiusScale?: string;
153
+ /**
154
+ * The cap on the CHROME text tiers (headings, controls, chips, badges): 1 to 3.1, or 0 for none (the default,
155
+ * the tiers alone: headings 2, controls 1.8, chips 1.5, badges 1.3). Flowing content is never capped.
156
+ */
157
+ readonly accessibility_max_font_scale?: number | string;
158
+ readonly accessibilityMaxFontScale?: number | string;
159
+ /** Paint overrides at the named slots. */
160
+ readonly slots?: EverfurThemeSlotsInput;
161
+ /** Tolerated for any other key; ignored by the resolver. */
162
+ readonly [key: string]: unknown;
163
+ }
164
+
165
+ /** Recursively freeze a plain object/array tree in place and return it (typed as the input). */
166
+ declare function deepFreeze<T>(value: T): T;
167
+ /** Foreground text tokens; the semantic text ramp over surfaces. */
168
+ interface EverfurTextColorTokens {
169
+ readonly primary: string;
170
+ readonly secondary: string;
171
+ readonly muted: string;
172
+ /** The composer placeholder ink (the Everfur app's `rgba(61,61,61,0.75)`, 5:1 on cream; a lifted twin on dark). */
173
+ readonly placeholder: string;
174
+ /** Text drawn on the brand fill (a compiled default; resolve recomputes onPrimary/onAccent via WCAG). */
175
+ readonly onBrand: string;
176
+ readonly metaCool: string;
177
+ /** The message timestamp and copy glyph under a bubble (the Everfur app's footer ink; a lifted twin on dark). */
178
+ readonly timestamp: string;
179
+ }
180
+ /** The Everfur color system: brand + surfaces + text ramp + semantic palette + component washes. */
181
+ interface EverfurColorTokens {
182
+ readonly brand: string;
183
+ readonly brandSoft: string;
184
+ readonly brandSofter: string;
185
+ readonly brandBorder: string;
186
+ readonly borderHairlineGreen: string;
187
+ /** The brand at 55%: the edge of a floating card over the chat (the attachment popover, the Everfur app's). */
188
+ readonly brandBorderStrong: string;
189
+ /**
190
+ * The brand as TEXT or ICON ink. The resolver derives it from `brand`, pushed toward black (light palette) or
191
+ * white (dark palette) until it reads at 4.5:1 on every ground of the palette, so a light partner colour
192
+ * (yellow, mint, sky) keeps its hue as a fill and still reads as a label. Never use `brand` itself as ink.
193
+ */
194
+ readonly brandInk: string;
195
+ /**
196
+ * The ink of a TEXT LINK (citation titles, the disclaimer's links, "earlier messages", record document
197
+ * links): the `link` slot's text colour, else `accent`, guarded by the resolver at 4.5:1 on every ground a
198
+ * link sits on. `accent` is the link and highlight colour; this is its legible ink.
199
+ */
200
+ readonly linkInk: string;
201
+ readonly surface: string;
202
+ readonly surfaceCream: string;
203
+ readonly surfaceSubtle: string;
204
+ readonly background: string;
205
+ readonly borderRingCream: string;
206
+ /**
207
+ * The chat ground: the surface the thread, the empty state and the composer sit on. White by default (the
208
+ * Everfur app's shell); `surface_style` picks it. Kept apart from `surfaceCream` so choosing a ground never
209
+ * repaints the composer or the record cards.
210
+ */
211
+ readonly chatGround: string;
212
+ /** The composer pill's fill: the Everfur app's fixed cream, whatever `surface_style` picks for the ground. */
213
+ readonly composerFill: string;
214
+ /** The composer pill's edge: the brand at 75% (the Everfur app's, 5:1 on white). */
215
+ readonly composerBorder: string;
216
+ /** The colour of the soft lift under a floating control (the composer, the popover): the Everfur app's. */
217
+ readonly shadow: string;
218
+ readonly text: EverfurTextColorTokens;
219
+ /** The primary CTA fill (server-overridable via primary_color). Foreground is `onPrimary`. */
220
+ readonly primary: string;
221
+ /** WCAG-legible foreground for `primary` (computed by resolveTheme, never passed through). */
222
+ readonly onPrimary: string;
223
+ /** The user/CTA accent fill (server-overridable via accent_color). Foreground is `onAccent`. */
224
+ readonly accent: string;
225
+ /** WCAG-legible foreground for `accent` (computed by resolveTheme). */
226
+ readonly onAccent: string;
227
+ /** The 0.5px bubble edge (a lightened brand / success green for the default). */
228
+ readonly accentEdge: string;
229
+ readonly success: string;
230
+ readonly danger: string;
231
+ readonly errorRed: string;
232
+ readonly warningStrong: string;
233
+ readonly cautionAccent: string;
234
+ readonly riskConcern: string;
235
+ /**
236
+ * The three feedback thumbs under an assistant reply, the Everfur app's Figma strokes: `up` (helpful) green,
237
+ * `neutral` amber, `down` (not helpful) red. The stroke at rest and the fill once recorded.
238
+ */
239
+ readonly sentiment: {
240
+ readonly up: string;
241
+ readonly neutral: string;
242
+ readonly down: string;
243
+ };
244
+ readonly badgeBgPositive: string;
245
+ readonly badgeBgCaution: string;
246
+ readonly badgeBgCritical: string;
247
+ readonly badgeBgNeutral: string;
248
+ /** user bubble = accent fill; assistant bubble = bare surface (the mobile/Flutter asymmetry). */
249
+ readonly bubbleUser: string;
250
+ readonly bubbleAssistant: string;
251
+ readonly skeleton: string;
252
+ readonly scanButtonPink: string;
253
+ readonly checkupCardLowRiskBg: string;
254
+ readonly checkupCardConcernBg: string;
255
+ }
256
+ /** Spacing scale (dp). */
257
+ interface EverfurSpaceTokens {
258
+ readonly xs: number;
259
+ readonly sm: number;
260
+ readonly md: number;
261
+ readonly lg: number;
262
+ readonly xl: number;
263
+ readonly xxl: number;
264
+ }
265
+ /** Corner-radius scale (dp); `pill` is an effectively-infinite radius. */
266
+ interface EverfurRadiusTokens {
267
+ readonly tile: number;
268
+ readonly xs: number;
269
+ readonly sm: number;
270
+ readonly md: number;
271
+ readonly lg: number;
272
+ readonly xl: number;
273
+ readonly pill: number;
274
+ }
275
+ interface EverfurTypeSizeTokens {
276
+ readonly nano: number;
277
+ readonly small: number;
278
+ readonly micro: number;
279
+ readonly tiny: number;
280
+ readonly caption: number;
281
+ readonly bodyTight: number;
282
+ readonly body: number;
283
+ readonly subtitle: number;
284
+ readonly heading: number;
285
+ readonly verdict: number;
286
+ }
287
+ /** Line-height multipliers (applied to a size to derive an absolute lineHeight). */
288
+ interface EverfurLineHeightTokens {
289
+ readonly tight: number;
290
+ readonly snug: number;
291
+ readonly normal: number;
292
+ readonly relaxed: number;
293
+ }
294
+ /**
295
+ * RN-assignable font-weight literals. Typed as the exact string literals we ship (not bare `string`) so a
296
+ * consumer can spread a weight token straight into a `Text` style: React Native's `TextStyle['fontWeight']`
297
+ * accepts these, but rejects `string`. Kept framework-free (no react-native import) to hold the client layer's
298
+ * no-framework boundary - these three literals are a subset of RN's fontWeight union.
299
+ */
300
+ type EverfurFontWeight = '400' | '500' | '700';
301
+ /** RN fontWeight tokens. */
302
+ interface EverfurWeightTokens {
303
+ readonly regular: EverfurFontWeight;
304
+ readonly medium: EverfurFontWeight;
305
+ readonly bold: EverfurFontWeight;
306
+ }
307
+ interface EverfurLetterSpacingTokens {
308
+ readonly eyebrow: number;
309
+ readonly monoWide: number;
310
+ readonly headerBrand: number;
311
+ readonly tight: number;
312
+ }
313
+ /**
314
+ * The faces a theme names: the three text weights and the three mono weights (the Everfur app registers
315
+ * `AzeretMono-Regular`, `-Medium` and `-Bold`). A missing weight falls back along its chain: bold -> medium ->
316
+ * regular, monoBold -> monoMedium -> mono.
317
+ */
318
+ type EverfurFontFaceKey = 'regular' | 'medium' | 'bold' | 'mono' | 'monoMedium' | 'monoBold';
319
+ /**
320
+ * The text-scale tiers of the Everfur app (`fontScaling.ts`): how far a class of text may follow the user's text
321
+ * size. Flowing `content` (message bodies, card bodies, list rows) is never capped; the bounded chrome is:
322
+ * `heading` 2x, `control` (buttons) 1.8x, `compact` (chips, pills, inline meta) 1.5x, `badge` 1.3x.
323
+ */
324
+ type EverfurTextScaleTier = 'content' | 'heading' | 'control' | 'compact' | 'badge';
325
+ /**
326
+ * The cap of each tier, React Native's `maxFontSizeMultiplier` semantics: 0 means no maximum. The Everfur app's
327
+ * values, verbatim. A tenant's `accessibility_max_font_scale` may lower the chrome tiers further, never content.
328
+ */
329
+ declare const TEXT_SCALE_TIER_CAPS: Readonly<Record<EverfurTextScaleTier, number>>;
330
+ /** The family rendered at each face. Every entry is populated (the compiled default is the platform font). */
331
+ type EverfurFontFamilies = Readonly<Record<EverfurFontFaceKey, string>>;
332
+ /**
333
+ * Typography tokens. `families` is the family per face; a branding sets them through `fonts` (one registered
334
+ * face per weight, the Everfur app's own scheme) or the legacy single `font_family`, else the platform font.
335
+ * `family` / `mono` / `fontUrl` are aliases of the regular and mono entries, kept for every reader of the
336
+ * pre-`families` shape. A surface never reads these raw: `face(theme, weight)` (typeStyle.ts) picks the
337
+ * family and decides whether a numeric `fontWeight` belongs beside it.
338
+ */
339
+ interface EverfurTypeTokens {
340
+ /** Alias of `families.regular`. */
341
+ readonly family: string;
342
+ /** Alias of `families.mono`. */
343
+ readonly mono: string;
344
+ /** Alias of `fontUrls.regular`; null unless an override supplies an https URL. */
345
+ readonly fontUrl: string | null;
346
+ readonly families: EverfurFontFamilies;
347
+ /**
348
+ * Per face: true when `families[face]` is a NAMED face from a `fonts` map (the weight is baked into the
349
+ * registered face, so `face()` sets no `fontWeight`); false when it is a base family (`font_family` or the
350
+ * platform font) that carries every weight and takes the numeric `weight` token.
351
+ */
352
+ readonly namedFaces: Readonly<Record<EverfurFontFaceKey, boolean>>;
353
+ /** The brand-font URL per face (web only, `font_urls` / `font_url`); absent or null when none applies. */
354
+ readonly fontUrls: Readonly<Partial<Record<EverfurFontFaceKey, string | null>>>;
355
+ /**
356
+ * The type scale. On the web it ALREADY carries `scale` (CSS px do not follow the user's text setting on their
357
+ * own); on React Native it is the authored size, which the platform scales natively up to `maxScale`.
358
+ */
359
+ readonly size: EverfurTypeSizeTokens;
360
+ readonly lineHeight: EverfurLineHeightTokens;
361
+ readonly weight: EverfurWeightTokens;
362
+ readonly letterSpacing: EverfurLetterSpacingTokens;
363
+ /**
364
+ * `size` per text-scale tier (`EverfurTextScaleTier`). On the web each tier carries the user's scale up to that
365
+ * tier's cap (`content` is `size` itself, uncapped); on React Native every tier is the authored `size` and the
366
+ * platform scales it natively under the tier's `maxFontSizeMultiplier` (`scaleCaps`, applied by the SDK's `Text`).
367
+ */
368
+ readonly tierSizes: Readonly<Record<'content' | 'heading' | 'control' | 'compact' | 'badge', EverfurTypeSizeTokens>>;
369
+ /** The end user's effective text scale (their device setting, floored at `TEXT_SCALE_FLOOR`); 1 when unknown. */
370
+ readonly scale: number;
371
+ /**
372
+ * The tenant's cap on the CHROME tiers (`accessibility_max_font_scale`): 0 means none (the default), so the
373
+ * tier caps alone bound headings, controls, chips and badges. Flowing content is never capped.
374
+ */
375
+ readonly maxScale: number;
376
+ /**
377
+ * The effective cap of each tier (`EverfurTextScaleTier`): the tier's own cap, lowered by `maxScale` for the
378
+ * chrome tiers; 0 means none (React Native's `maxFontSizeMultiplier` semantics).
379
+ */
380
+ readonly scaleCaps: Readonly<Record<'content' | 'heading' | 'control' | 'compact' | 'badge', number>>;
381
+ }
382
+ interface EverfurSpringToken {
383
+ readonly damping: number;
384
+ readonly stiffness: number;
385
+ }
386
+ interface EverfurMotionDurationTokens {
387
+ readonly instant: number;
388
+ readonly fast: number;
389
+ readonly normal: number;
390
+ readonly slow: number;
391
+ }
392
+ /** Motion tokens. Under reduced-motion, resolveTheme collapses durations to 0 and stiffens the spring. */
393
+ interface EverfurMotionTokens {
394
+ readonly duration: EverfurMotionDurationTokens;
395
+ readonly spring: {
396
+ readonly gentle: EverfurSpringToken;
397
+ };
398
+ /**
399
+ * The Everfur app's curves as CSS `cubic-bezier()` values: `standard` for most transitions, `emphasized` for an
400
+ * entrance that should draw the eye, `exit` for a leave. `EASING_CURVES` holds the same curves as numbers.
401
+ */
402
+ readonly easing: {
403
+ readonly standard: string;
404
+ readonly emphasized: string;
405
+ readonly exit: string;
406
+ };
407
+ /** true when the resolved theme has collapsed motion (AccessibilityInfo reduced-motion). */
408
+ readonly reducedMotion: boolean;
409
+ }
410
+ /** Non-visual identity + partner copy carried on the theme (server display_name/logo_url/placeholder overlay). */
411
+ interface EverfurThemeMeta {
412
+ readonly displayName: string;
413
+ readonly logoUrl: string | null;
414
+ /** Server-overridable composer placeholder (chat_placeholder/placeholder); null keeps Everfur's neutral default. */
415
+ readonly placeholder: string | null;
416
+ /** White-label switch (hide_powered_by): drop the "powered by everfur" attribution. Default false (shown). */
417
+ readonly hidePoweredBy: boolean;
418
+ }
419
+ /**
420
+ * The frozen, never-null theme the rn layer renders. Read a token as `theme.color.brand`,
421
+ * `theme.space.md`, `theme.type.size.body`, `theme.radius.lg`, `theme.motion.duration.fast`; a slot's paint
422
+ * as `theme.slots.userBubble?.backgroundColor`.
423
+ */
424
+ interface EverfurTheme {
425
+ readonly brightness: 'light' | 'dark';
426
+ /** true when the user asked for more contrast (`prefers-contrast: more`) and the palette was derived for it. */
427
+ readonly highContrast: boolean;
428
+ readonly meta: EverfurThemeMeta;
429
+ readonly color: EverfurColorTokens;
430
+ readonly space: EverfurSpaceTokens;
431
+ readonly radius: EverfurRadiusTokens;
432
+ readonly type: EverfurTypeTokens;
433
+ readonly motion: EverfurMotionTokens;
434
+ /** Paint overrides at the named slots (empty by default); each text colour is contrast-guarded. */
435
+ readonly slots: EverfurThemeSlots;
436
+ }
437
+ /**
438
+ * The tenant's chrome cap when it sets none (`accessibility_max_font_scale`): 0, no cap beyond the tiers of
439
+ * `TEXT_SCALE_TIER_CAPS`, the Everfur app's own policy.
440
+ */
441
+ declare const DEFAULT_MAX_FONT_SCALE = 0;
442
+ /** The RN token that means "the platform font"; every face of the compiled default. */
443
+ declare const SYSTEM_FONT_FAMILY = "System";
444
+ /**
445
+ * The generic mono keyword of the compiled default. React Native on iOS has no family of that name, so the
446
+ * React Native host maps it per platform (Menlo on iOS); the web host maps it to its mono stack.
447
+ */
448
+ declare const SYSTEM_MONO_FAMILY = "monospace";
449
+ /** A cubic-bezier as its four control values (`[x1, y1, x2, y2]`). */
450
+ type EverfurEasingCurve = readonly [number, number, number, number];
451
+ /** The Everfur app's easing curves (`src/motion/tokens.ts`), as numbers; `motion.easing` holds them as CSS. */
452
+ declare const EASING_CURVES: Readonly<Record<'standard' | 'emphasized' | 'exit', EverfurEasingCurve>>;
453
+ /** `cubic-bezier(x1, y1, x2, y2)` for a curve. */
454
+ declare function cssCubicBezier(curve: EverfurEasingCurve): string;
455
+ /** The compiled LIGHT default (deeply frozen). */
456
+ declare const EVERFUR_LIGHT: EverfurTheme;
457
+ /** The compiled DARK default (deeply frozen). */
458
+ declare const EVERFUR_DARK: EverfurTheme;
459
+
460
+ interface ClientBranding {
461
+ readonly displayName: string | null;
462
+ /** normalized (https-hardened downstream) logo URL */
463
+ readonly logoUrl: string | null;
464
+ /** normalized color string (#RRGGBB or rgba(...)) or null */
465
+ readonly primaryColor: string | null;
466
+ readonly accentColor: string | null;
467
+ /**
468
+ * `light` or `dark` pins the palette; `auto` follows the device's scheme (an explicit opt-in). null (absent)
469
+ * resolves to LIGHT, as Everfur's own apps render. Read from `brightness`, or its console alias `color_scheme`
470
+ * (`colorScheme`).
471
+ */
472
+ readonly brightness: 'light' | 'dark' | 'auto' | null;
473
+ readonly fontFamily: string | null;
474
+ readonly fontUrl: string | null;
475
+ /**
476
+ * fonts: one registered family per face (`regular` / `medium` / `bold` / `mono` / `monoMedium` / `monoBold`),
477
+ * any subset. A name used by one face of its group only is a named face, rendered without a synthetic
478
+ * `fontWeight`; a name repeated across the weights of a group is a base family and takes the numeric weights.
479
+ * Absent/null names none (the base families stand).
480
+ */
481
+ readonly fonts?: Readonly<Partial<Record<EverfurFontFaceKey, string>>> | null;
482
+ /** font_urls: the brand-font URL per face (web only), any subset; hardened https-only downstream. */
483
+ readonly fontUrls?: Readonly<Partial<Record<EverfurFontFaceKey, string>>> | null;
484
+ /** composer placeholder override (chat_placeholder/placeholder); null keeps the base. */
485
+ readonly placeholder: string | null;
486
+ /**
487
+ * white-label switch (hide_powered_by): hide the powered-by attribution. null = unset (keep the base). Honoured
488
+ * from SERVER branding only: `resolveTheme` ignores it on the client override (attribution is server-only).
489
+ */
490
+ readonly hidePoweredBy: boolean | null;
491
+ /** primary_color_dark: the primary fill used when the resolved palette is dark. Absent/null derives one. */
492
+ readonly primaryColorDark?: string | null;
493
+ /** accent_color_dark: the accent fill used when the resolved palette is dark. Absent/null derives one. */
494
+ readonly accentColorDark?: string | null;
495
+ /**
496
+ * surface_style: which compiled surface the chat ground (`chatGround`) uses. Absent/null keeps the palette's
497
+ * white ground (the Everfur app's shell). The composer and the record cards keep their cream either way.
498
+ */
499
+ readonly surfaceStyle?: SurfaceStyle | null;
500
+ /** radius_scale: scales the corner radii (the pill radius is never scaled). Absent/null keeps the palette radii. */
501
+ readonly radiusScale?: RadiusScale | null;
502
+ /** logo_url_dark: the logo shown on the dark palette. Absent/null keeps logoUrl on both palettes. */
503
+ readonly logoUrlDark?: string | null;
504
+ /** slots: paint overrides at the named slots (schema 2). Absent/null paints none. */
505
+ readonly slots?: EverfurThemeSlots | null;
506
+ /**
507
+ * accessibility_max_font_scale: the tenant's cap on the CHROME text tiers (headings, controls, chips, badges),
508
+ * 1..3.1, or 0 for none. Flowing content is never capped. Absent/null keeps the default (0, the tiers alone).
509
+ */
510
+ readonly accessibilityMaxFontScale?: number | null;
511
+ /**
512
+ * locked_fields: the wire names the tenant keeps server-wins (schema 2): a field, `slots` (every slot) or
513
+ * `slots.<name>` (one slot); the wire also lists `hide_powered_by`, which is locked whether listed or not.
514
+ * Meaningful on SERVER branding only; ignored on the client override. Absent/null locks nothing beyond the
515
+ * attribution.
516
+ */
517
+ readonly lockedFields?: readonly ThemeLockName[] | null;
518
+ /**
519
+ * schema_version: the wire version the branding was written for. null when absent (schema 1); 0 when present but
520
+ * not a positive integer. A version this SDK does not know (`THEME_SCHEMA_VERSIONS`) drops the server branding.
521
+ */
522
+ readonly schemaVersion?: number | null;
523
+ }
524
+ /** The compiled surface a branding may pick for the chat ground (`surface_style`). */
525
+ type SurfaceStyle = 'white' | 'cream' | 'subtle';
526
+ /** The corner-radius scale a branding may pick (`radius_scale`). */
527
+ type RadiusScale = 'sharp' | 'default' | 'round';
528
+ /**
529
+ * The wire names a tenant may list in `locked_fields` (every cosmetic field). `hide_powered_by` is not listed:
530
+ * it is server-wins unconditionally, so locking it is meaningless.
531
+ */
532
+ declare const LOCKABLE_THEME_FIELDS: readonly ["display_name", "logo_url", "logo_url_dark", "primary_color", "accent_color", "primary_color_dark", "accent_color_dark", "brightness", "color_scheme", "font_family", "font_url", "fonts", "font_urls", "chat_placeholder", "surface_style", "radius_scale", "accessibility_max_font_scale", "slots"];
533
+ type LockableThemeField = (typeof LOCKABLE_THEME_FIELDS)[number];
534
+ /** The `locked_fields` key that locks one slot (`slots.<name>`), as EFBackend branding_slots.py emits it. */
535
+ declare const SLOT_LOCK_PREFIX = "slots.";
536
+ type SlotLockName = `${typeof SLOT_LOCK_PREFIX}${EverfurThemeSlotName}`;
537
+ /** Everything `locked_fields` may name: a cosmetic field, one slot, or the (always locked) attribution. */
538
+ type ThemeLockName = LockableThemeField | SlotLockName | 'hide_powered_by';
539
+ /** The branding wire versions this SDK reads: 1 (absent on the wire) and 2 (the 18 Sep 2026 fields). */
540
+ declare const THEME_SCHEMA_VERSIONS: readonly number[];
541
+ /**
542
+ * true when every field is null (no config) - treated by callers as "absent". The version stamp alone is not a
543
+ * value: a branding that carries only `schema_version` is empty.
544
+ */
545
+ declare function isEmptyBranding(b: ClientBranding): boolean;
546
+ /** true when the branding is absent or written for a wire version this SDK knows. */
547
+ declare function isKnownBrandingSchema(b: ClientBranding | null): boolean;
548
+ /** The names a server branding keeps server-wins: its `locked_fields`, plus the attribution always. */
549
+ declare function lockedFieldsOf(b: ClientBranding | null): ReadonlySet<string>;
550
+ /**
551
+ * Parse an untrusted branding blob (from the entitlements render_hints, or the client `theme` prop) into a
552
+ * normalized `ClientBranding`. Accepts BOTH snake_case and camelCase keys. Returns null when the input is not
553
+ * an object OR when the result is empty (all fields null) - callers read null as "no config" (fail-closed to
554
+ * the compiled default). Never throws.
555
+ */
556
+ declare function parseClientBranding(json: unknown): ClientBranding | null;
557
+ /** The largest cap a tenant may set on the chrome tiers: iOS's largest accessibility text size (AX5, 310%). */
558
+ declare const MAX_FONT_SCALE_CEILING = 3.1;
559
+ /**
560
+ * Return the URL only if it is an https URL with no embedded whitespace, else null (security invariant:
561
+ * https-only; rejects http:, javascript:, data:, etc.). Uses a protocol-locked regex rather than the URL
562
+ * constructor so it is portable + total on React Native (whose URL global is incomplete) and never throws.
563
+ */
564
+ declare function hardenHttpsUrl(url: string | null): string | null;
565
+
566
+ export { guardSlotContrast as $, THEME_SLOT_NAMES as A, EASING_CURVES as B, type ClientBranding as C, DEFAULT_MAX_FONT_SCALE as D, type EverfurThemeInput as E, EVERFUR_DARK as F, EVERFUR_LIGHT as G, type EverfurEasingCurve as H, type EverfurTextScaleTier as I, type LockableThemeField as J, SLOT_LOCK_PREFIX as K, LOCKABLE_THEME_FIELDS as L, MAX_FONT_SCALE_CEILING as M, SLOT_MIN_BORDER_CONTRAST as N, SLOT_MIN_CONTRAST as O, SYSTEM_FONT_FAMILY as P, SYSTEM_MONO_FAMILY as Q, type RadiusScale as R, type SurfaceStyle as S, THEME_SLOT_KEYS as T, type SlotGrounds as U, type SlotLockName as V, TEXT_SCALE_TIER_CAPS as W, THEME_SCHEMA_VERSIONS as X, type ThemeLockName as Y, cssCubicBezier as Z, deepFreeze as _, type EverfurTheme as a, hardenHttpsUrl as a0, isEmptyBranding as a1, isKnownBrandingSchema as a2, lockedFieldsOf as a3, mergeThemeSlots as a4, parseClientBranding as a5, parseThemeSlots as a6, type EverfurFontWeight as b, type EverfurFontFaceKey as c, type EverfurColorTokens as d, type EverfurFontFamilies as e, type EverfurLetterSpacingTokens as f, type EverfurLineHeightTokens as g, type EverfurMotionDurationTokens as h, type EverfurMotionTokens as i, type EverfurRadiusTokens as j, type EverfurSpaceTokens as k, type EverfurSpringToken as l, type EverfurTextColorTokens as m, type EverfurThemeFontFaceKey as n, type EverfurThemeFontUrlsInput as o, type EverfurThemeFontsInput as p, type EverfurThemeMeta as q, type EverfurThemeSlot as r, type EverfurThemeSlotInput as s, type EverfurThemeSlotKey as t, type EverfurThemeSlotName as u, type EverfurThemeSlots as v, type EverfurThemeSlotsInput as w, type EverfurTypeSizeTokens as x, type EverfurTypeTokens as y, type EverfurWeightTokens as z };
@@ -0,0 +1,40 @@
1
+ /** The phases the in-app call surface moves through. The consumer app's `CallPhase`, verbatim. */
2
+ type VetCallPhase = 'joining' | 'joined' | 'left' | 'error';
3
+ /**
4
+ * Refuses anything that is not an https room.
5
+ *
6
+ * NEVER THROWS and never echoes the input: an unparseable value returns false rather than raising, because
7
+ * the caller is already on a failure path when it asks.
8
+ */
9
+ declare function isSafeRoomUrl(url: string): boolean;
10
+ /**
11
+ * The whole credential floor: an https room AND a non-empty join token. The call surface renders nothing and
12
+ * creates no call object unless this is true.
13
+ */
14
+ declare function isUsableRoomCredential(roomUrl: string, token: string): boolean;
15
+
16
+ /** The consult length the lobby quotes, in minutes. everfur-mobile-2026-7 televetTime.ts:85 `CONSULT_MINUTES`. */
17
+ declare const VET_CALL_CONSULT_MINUTES = 10;
18
+ declare const VET_CALL_COPY: Readonly<{
19
+ /** Controls, shared by the lobby and the live call. */
20
+ muteCta: "Mute";
21
+ unmuteCta: "Unmute";
22
+ cameraOffCta: "Camera off";
23
+ cameraOnCta: "Camera on";
24
+ leaveCta: "Leave";
25
+ /** The lobby: the member is in the room and the clinician is not. */
26
+ lobbyTitleNoName: "Your vet is joining";
27
+ lobbySubtitle: "Usually under a minute";
28
+ lobbyPrepLabel: "WHILE YOU WAIT";
29
+ lobbyPrepNoPet: "Have your pet nearby and somewhere well lit.";
30
+ /** `{name}` is DATA from the consult, never a key. Absent, `lobbyTitleNoName` is used instead. */
31
+ lobbyTitle: (clinicianName: string | null | undefined) => string;
32
+ /** `{pet}` is DATA from the roster. Absent, the pet-free form is used instead. */
33
+ lobbyPrep: (petName: string | null | undefined) => string;
34
+ /** `{n}` is `VET_CALL_CONSULT_MINUTES`, never a hardcoded number. */
35
+ lobbyDuration: (minutes: number) => string;
36
+ /** The consumer app's `visit.joinFailedReason` (:735), shown when the call object errors. */
37
+ joinFailedReason: "That did not open. Try again.";
38
+ }>;
39
+
40
+ export { VET_CALL_CONSULT_MINUTES as V, VET_CALL_COPY as a, type VetCallPhase as b, isUsableRoomCredential as c, isSafeRoomUrl as i };
@@ -0,0 +1,40 @@
1
+ /** The phases the in-app call surface moves through. The consumer app's `CallPhase`, verbatim. */
2
+ type VetCallPhase = 'joining' | 'joined' | 'left' | 'error';
3
+ /**
4
+ * Refuses anything that is not an https room.
5
+ *
6
+ * NEVER THROWS and never echoes the input: an unparseable value returns false rather than raising, because
7
+ * the caller is already on a failure path when it asks.
8
+ */
9
+ declare function isSafeRoomUrl(url: string): boolean;
10
+ /**
11
+ * The whole credential floor: an https room AND a non-empty join token. The call surface renders nothing and
12
+ * creates no call object unless this is true.
13
+ */
14
+ declare function isUsableRoomCredential(roomUrl: string, token: string): boolean;
15
+
16
+ /** The consult length the lobby quotes, in minutes. everfur-mobile-2026-7 televetTime.ts:85 `CONSULT_MINUTES`. */
17
+ declare const VET_CALL_CONSULT_MINUTES = 10;
18
+ declare const VET_CALL_COPY: Readonly<{
19
+ /** Controls, shared by the lobby and the live call. */
20
+ muteCta: "Mute";
21
+ unmuteCta: "Unmute";
22
+ cameraOffCta: "Camera off";
23
+ cameraOnCta: "Camera on";
24
+ leaveCta: "Leave";
25
+ /** The lobby: the member is in the room and the clinician is not. */
26
+ lobbyTitleNoName: "Your vet is joining";
27
+ lobbySubtitle: "Usually under a minute";
28
+ lobbyPrepLabel: "WHILE YOU WAIT";
29
+ lobbyPrepNoPet: "Have your pet nearby and somewhere well lit.";
30
+ /** `{name}` is DATA from the consult, never a key. Absent, `lobbyTitleNoName` is used instead. */
31
+ lobbyTitle: (clinicianName: string | null | undefined) => string;
32
+ /** `{pet}` is DATA from the roster. Absent, the pet-free form is used instead. */
33
+ lobbyPrep: (petName: string | null | undefined) => string;
34
+ /** `{n}` is `VET_CALL_CONSULT_MINUTES`, never a hardcoded number. */
35
+ lobbyDuration: (minutes: number) => string;
36
+ /** The consumer app's `visit.joinFailedReason` (:735), shown when the call object errors. */
37
+ joinFailedReason: "That did not open. Try again.";
38
+ }>;
39
+
40
+ export { VET_CALL_CONSULT_MINUTES as V, VET_CALL_COPY as a, type VetCallPhase as b, isUsableRoomCredential as c, isSafeRoomUrl as i };