@everfur/sdk 0.1.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.
- package/CHANGELOG.md +74 -0
- package/LICENSE +21 -0
- package/README.md +161 -0
- package/animations/package.json +8 -0
- package/chat/package.json +8 -0
- package/client/package.json +8 -0
- package/core/package.json +8 -0
- package/dist/CameraPort-Cv31Pz7g.d.cts +29 -0
- package/dist/CameraPort-Cv31Pz7g.d.ts +29 -0
- package/dist/ChatController-CKdBvPj2.d.ts +146 -0
- package/dist/ChatController-CpUMvvZf.d.cts +146 -0
- package/dist/EverfurResult-D92-uL82.d.cts +240 -0
- package/dist/EverfurResult-D92-uL82.d.ts +240 -0
- package/dist/FilePort-BabWrv7I.d.cts +22 -0
- package/dist/FilePort-BabWrv7I.d.ts +22 -0
- package/dist/PhotoController-BItt5M7u.d.cts +43 -0
- package/dist/PhotoController-D8zMTdcW.d.ts +43 -0
- package/dist/TelemetryPort-BDNr00hu.d.cts +12 -0
- package/dist/TelemetryPort-BDNr00hu.d.ts +12 -0
- package/dist/animations/index.cjs +1997 -0
- package/dist/animations/index.d.cts +517 -0
- package/dist/animations/index.d.ts +517 -0
- package/dist/animations/index.js +1972 -0
- package/dist/cacheEpoch-DknKn3S0.d.cts +36 -0
- package/dist/cacheEpoch-DknKn3S0.d.ts +36 -0
- package/dist/chat/index.cjs +1170 -0
- package/dist/chat/index.d.cts +59 -0
- package/dist/chat/index.d.ts +59 -0
- package/dist/chat/index.js +1167 -0
- package/dist/client/index.cjs +2317 -0
- package/dist/client/index.d.cts +65 -0
- package/dist/client/index.d.ts +65 -0
- package/dist/client/index.js +2217 -0
- package/dist/config-BSjBdxrZ.d.cts +501 -0
- package/dist/config-CiJ0PVBB.d.ts +501 -0
- package/dist/core/index.cjs +3175 -0
- package/dist/core/index.d.cts +70 -0
- package/dist/core/index.d.ts +70 -0
- package/dist/core/index.js +3163 -0
- package/dist/identity-Brl-lDd6.d.cts +91 -0
- package/dist/identity-DK9zORrG.d.ts +91 -0
- package/dist/ids-CJ1S6adf.d.cts +46 -0
- package/dist/ids-CJ1S6adf.d.ts +46 -0
- package/dist/index.cjs +4488 -0
- package/dist/index.d.cts +156 -0
- package/dist/index.d.ts +156 -0
- package/dist/index.js +4464 -0
- package/dist/petsRepository-BEGb97M9.d.cts +326 -0
- package/dist/petsRepository-Bu18r2kK.d.ts +326 -0
- package/dist/photo/index.cjs +2189 -0
- package/dist/photo/index.d.cts +43 -0
- package/dist/photo/index.d.ts +43 -0
- package/dist/photo/index.js +2186 -0
- package/dist/projection-CeIUsbSk.d.cts +8 -0
- package/dist/projection-CeIUsbSk.d.ts +8 -0
- package/dist/records/index.cjs +2840 -0
- package/dist/records/index.d.cts +224 -0
- package/dist/records/index.d.ts +224 -0
- package/dist/records/index.js +2834 -0
- package/dist/requestFunnel-DuUH-kAe.d.cts +28 -0
- package/dist/requestFunnel-dio5OmR9.d.ts +28 -0
- package/dist/resolve-Dq_4_agU.d.cts +86 -0
- package/dist/resolve-Dq_4_agU.d.ts +86 -0
- package/dist/runtime-BgQnA594.d.cts +349 -0
- package/dist/runtime-CBA-LvdM.d.ts +349 -0
- package/dist/server/index.cjs +533 -0
- package/dist/server/index.d.cts +48 -0
- package/dist/server/index.d.ts +48 -0
- package/dist/server/index.js +530 -0
- package/dist/testing/index.cjs +825 -0
- package/dist/testing/index.d.cts +113 -0
- package/dist/testing/index.d.ts +113 -0
- package/dist/testing/index.js +822 -0
- package/dist/testing/rn/index.cjs +449 -0
- package/dist/testing/rn/index.d.cts +49 -0
- package/dist/testing/rn/index.d.ts +49 -0
- package/dist/testing/rn/index.js +444 -0
- package/dist/video/index.cjs +1941 -0
- package/dist/video/index.d.cts +66 -0
- package/dist/video/index.d.ts +66 -0
- package/dist/video/index.js +1938 -0
- package/package.json +311 -0
- package/photo/package.json +8 -0
- package/records/package.json +8 -0
- package/server/device-blocked.cjs +15 -0
- package/server/package.json +9 -0
- package/testing/package.json +8 -0
- package/testing/rn/package.json +8 -0
- package/video/package.json +8 -0
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var react = require('react');
|
|
4
|
+
require('react-native-safe-area-context');
|
|
5
|
+
var reactNative = require('react-native');
|
|
6
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
+
|
|
8
|
+
// src/rn/testing.ts
|
|
9
|
+
|
|
10
|
+
// src/client/errors/EverfurResult.ts
|
|
11
|
+
var EverfurConfigError = class _EverfurConfigError extends Error {
|
|
12
|
+
constructor(kind, message) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = "EverfurConfigError";
|
|
15
|
+
this.kind = kind;
|
|
16
|
+
Object.setPrototypeOf(this, _EverfurConfigError.prototype);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// src/client/theme/tokens.ts
|
|
21
|
+
function deepFreeze(value) {
|
|
22
|
+
if (value !== null && typeof value === "object" && !Object.isFrozen(value)) {
|
|
23
|
+
Object.freeze(value);
|
|
24
|
+
for (const key of Object.keys(value)) {
|
|
25
|
+
deepFreeze(value[key]);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
var SPACE = { xs: 4, sm: 8, md: 12, lg: 16, xl: 24, xxl: 32 };
|
|
31
|
+
var RADIUS = { tile: 5, xs: 6, sm: 10, md: 14, lg: 20, xl: 28, pill: 500 };
|
|
32
|
+
var TYPE_SIZE = {
|
|
33
|
+
nano: 8,
|
|
34
|
+
small: 9,
|
|
35
|
+
micro: 10,
|
|
36
|
+
tiny: 11,
|
|
37
|
+
caption: 12,
|
|
38
|
+
bodyTight: 13,
|
|
39
|
+
body: 14,
|
|
40
|
+
subtitle: 16,
|
|
41
|
+
heading: 18,
|
|
42
|
+
verdict: 24
|
|
43
|
+
};
|
|
44
|
+
var LINE_HEIGHT = { tight: 1.15, snug: 1.3, normal: 1.4, relaxed: 1.55 };
|
|
45
|
+
var WEIGHT = { regular: "400", medium: "500", bold: "700" };
|
|
46
|
+
var LETTER_SPACING = {
|
|
47
|
+
eyebrow: 1,
|
|
48
|
+
monoWide: 0.9,
|
|
49
|
+
headerBrand: -0.42,
|
|
50
|
+
tight: -0.35
|
|
51
|
+
};
|
|
52
|
+
function baseType() {
|
|
53
|
+
return {
|
|
54
|
+
family: "System",
|
|
55
|
+
mono: "monospace",
|
|
56
|
+
fontUrl: null,
|
|
57
|
+
size: TYPE_SIZE,
|
|
58
|
+
lineHeight: LINE_HEIGHT,
|
|
59
|
+
weight: WEIGHT,
|
|
60
|
+
letterSpacing: LETTER_SPACING
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
var MOTION = {
|
|
64
|
+
duration: { instant: 80, fast: 140, normal: 220, slow: 320 },
|
|
65
|
+
spring: { gentle: { damping: 18, stiffness: 200 } },
|
|
66
|
+
easing: { standard: "cubic-bezier(0.4, 0, 0.2, 1)" },
|
|
67
|
+
reducedMotion: false
|
|
68
|
+
};
|
|
69
|
+
var LIGHT_COLOR = {
|
|
70
|
+
brand: "#10462E",
|
|
71
|
+
brandSoft: "rgba(16,70,46,0.10)",
|
|
72
|
+
brandSofter: "rgba(16,70,46,0.15)",
|
|
73
|
+
brandBorder: "rgba(16,70,46,0.18)",
|
|
74
|
+
borderHairlineGreen: "rgba(16,70,46,0.25)",
|
|
75
|
+
surface: "#FFFFFF",
|
|
76
|
+
surfaceCream: "#FDFBF8",
|
|
77
|
+
surfaceSubtle: "#EFE9E3",
|
|
78
|
+
background: "#FFFFFF",
|
|
79
|
+
borderRingCream: "#D8D2C8",
|
|
80
|
+
text: {
|
|
81
|
+
primary: "#111111",
|
|
82
|
+
secondary: "#0E462E",
|
|
83
|
+
muted: "#6E6660",
|
|
84
|
+
placeholder: "rgba(0,0,0,0.30)",
|
|
85
|
+
onBrand: "#FFFFFF",
|
|
86
|
+
metaCool: "#3D3D3D"
|
|
87
|
+
},
|
|
88
|
+
primary: "#10462E",
|
|
89
|
+
onPrimary: "#FFFFFF",
|
|
90
|
+
accent: "#10462E",
|
|
91
|
+
onAccent: "#FFFFFF",
|
|
92
|
+
accentEdge: "#07C168",
|
|
93
|
+
success: "#07C168",
|
|
94
|
+
danger: "#B91C1C",
|
|
95
|
+
errorRed: "#FF1B00",
|
|
96
|
+
warningStrong: "#A45610",
|
|
97
|
+
cautionAccent: "#D9821D",
|
|
98
|
+
riskConcern: "#EFA700",
|
|
99
|
+
badgeBgPositive: "rgba(7,193,104,0.12)",
|
|
100
|
+
badgeBgCaution: "rgba(217,130,29,0.14)",
|
|
101
|
+
badgeBgCritical: "rgba(185,28,28,0.12)",
|
|
102
|
+
badgeBgNeutral: "rgba(110,102,96,0.12)",
|
|
103
|
+
bubbleUser: "#10462E",
|
|
104
|
+
bubbleAssistant: "#FFFFFF",
|
|
105
|
+
skeleton: "#EFE9E3",
|
|
106
|
+
scanButtonPink: "#FFC3BC",
|
|
107
|
+
checkupCardLowRiskBg: "rgba(7,193,104,0.10)",
|
|
108
|
+
checkupCardConcernBg: "rgba(239,167,0,0.10)"
|
|
109
|
+
};
|
|
110
|
+
var EVERFUR_LIGHT = deepFreeze({
|
|
111
|
+
brightness: "light",
|
|
112
|
+
meta: { displayName: "Everfur", logoUrl: null, placeholder: null, hidePoweredBy: false },
|
|
113
|
+
color: LIGHT_COLOR,
|
|
114
|
+
space: SPACE,
|
|
115
|
+
radius: RADIUS,
|
|
116
|
+
type: baseType(),
|
|
117
|
+
motion: MOTION
|
|
118
|
+
});
|
|
119
|
+
var DARK_COLOR = {
|
|
120
|
+
brand: "#6BD39A",
|
|
121
|
+
brandSoft: "rgba(107,211,154,0.12)",
|
|
122
|
+
brandSofter: "rgba(107,211,154,0.18)",
|
|
123
|
+
brandBorder: "rgba(107,211,154,0.22)",
|
|
124
|
+
borderHairlineGreen: "rgba(107,211,154,0.28)",
|
|
125
|
+
surface: "#1C1F23",
|
|
126
|
+
surfaceCream: "#23272C",
|
|
127
|
+
surfaceSubtle: "#23272C",
|
|
128
|
+
background: "#15171A",
|
|
129
|
+
borderRingCream: "#3A3F45",
|
|
130
|
+
text: {
|
|
131
|
+
primary: "#F5F3F0",
|
|
132
|
+
secondary: "#A9E4C4",
|
|
133
|
+
muted: "#9A938C",
|
|
134
|
+
placeholder: "rgba(255,255,255,0.35)",
|
|
135
|
+
onBrand: "#0E1F17",
|
|
136
|
+
metaCool: "#C9C9C9"
|
|
137
|
+
},
|
|
138
|
+
primary: "#6BD39A",
|
|
139
|
+
onPrimary: "#0E1F17",
|
|
140
|
+
accent: "#6BD39A",
|
|
141
|
+
onAccent: "#0E1F17",
|
|
142
|
+
accentEdge: "#34D888",
|
|
143
|
+
success: "#07C168",
|
|
144
|
+
danger: "#B91C1C",
|
|
145
|
+
errorRed: "#FF1B00",
|
|
146
|
+
warningStrong: "#A45610",
|
|
147
|
+
cautionAccent: "#D9821D",
|
|
148
|
+
riskConcern: "#EFA700",
|
|
149
|
+
badgeBgPositive: "rgba(7,193,104,0.18)",
|
|
150
|
+
badgeBgCaution: "rgba(217,130,29,0.20)",
|
|
151
|
+
badgeBgCritical: "rgba(185,28,28,0.22)",
|
|
152
|
+
badgeBgNeutral: "rgba(255,255,255,0.10)",
|
|
153
|
+
bubbleUser: "#6BD39A",
|
|
154
|
+
bubbleAssistant: "#1C1F23",
|
|
155
|
+
skeleton: "#23272C",
|
|
156
|
+
scanButtonPink: "#FFC3BC",
|
|
157
|
+
checkupCardLowRiskBg: "rgba(7,193,104,0.16)",
|
|
158
|
+
checkupCardConcernBg: "rgba(239,167,0,0.16)"
|
|
159
|
+
};
|
|
160
|
+
deepFreeze({
|
|
161
|
+
brightness: "dark",
|
|
162
|
+
meta: { displayName: "Everfur", logoUrl: null, placeholder: null, hidePoweredBy: false },
|
|
163
|
+
color: DARK_COLOR,
|
|
164
|
+
space: SPACE,
|
|
165
|
+
radius: RADIUS,
|
|
166
|
+
type: baseType(),
|
|
167
|
+
motion: MOTION
|
|
168
|
+
});
|
|
169
|
+
var EVERFUR_THEME_CONTEXT_SYMBOL = /* @__PURE__ */ Symbol.for("@everfur/sdk#EverfurThemeContext@v1");
|
|
170
|
+
var globalThemeHost = globalThis;
|
|
171
|
+
var EverfurThemeContext = globalThemeHost[EVERFUR_THEME_CONTEXT_SYMBOL] ?? (globalThemeHost[EVERFUR_THEME_CONTEXT_SYMBOL] = react.createContext(EVERFUR_LIGHT));
|
|
172
|
+
EverfurThemeContext.displayName ??= "EverfurThemeContext";
|
|
173
|
+
function useEverfurTheme() {
|
|
174
|
+
return react.useContext(EverfurThemeContext);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// src/rn/facade.ts
|
|
178
|
+
var EVERFUR_CONTEXT_SYMBOL = /* @__PURE__ */ Symbol.for("@everfur/sdk#EverfurContext@v1");
|
|
179
|
+
var globalContextHost = globalThis;
|
|
180
|
+
var EverfurContext = globalContextHost[EVERFUR_CONTEXT_SYMBOL] ?? (globalContextHost[EVERFUR_CONTEXT_SYMBOL] = react.createContext(null));
|
|
181
|
+
EverfurContext.displayName ??= "EverfurContext";
|
|
182
|
+
function useEverfurContext() {
|
|
183
|
+
const ctx = react.useContext(EverfurContext);
|
|
184
|
+
if (ctx === null) {
|
|
185
|
+
throw new EverfurConfigError(
|
|
186
|
+
"not-initialized",
|
|
187
|
+
"Everfur hooks must be called inside <EverfurProvider>. Wrap your tree once, high."
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
return ctx;
|
|
191
|
+
}
|
|
192
|
+
var DOT_SIZE = 6;
|
|
193
|
+
var LOOP_MS = 520;
|
|
194
|
+
var STAGGER_MS = Math.round(LOOP_MS * 0.18);
|
|
195
|
+
var OPACITY_REST = 0.44;
|
|
196
|
+
var OPACITY_STATIC = 0.5;
|
|
197
|
+
var TRI_IN = [0, 0.5, 1];
|
|
198
|
+
var DOT_INDICES = [0, 1, 2];
|
|
199
|
+
function TypingIndicator() {
|
|
200
|
+
const theme = useEverfurTheme();
|
|
201
|
+
const styles = react.useMemo(() => makeStyles(theme), [theme]);
|
|
202
|
+
const animate = !theme.motion.reducedMotion;
|
|
203
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
204
|
+
reactNative.View,
|
|
205
|
+
{
|
|
206
|
+
style: styles.card,
|
|
207
|
+
accessible: true,
|
|
208
|
+
accessibilityRole: "text",
|
|
209
|
+
accessibilityLabel: "Assistant is typing",
|
|
210
|
+
accessibilityLiveRegion: "polite",
|
|
211
|
+
accessibilityState: { busy: true },
|
|
212
|
+
children: DOT_INDICES.map(
|
|
213
|
+
(index) => animate ? /* @__PURE__ */ jsxRuntime.jsx(AnimatedDot, { index, style: styles.dot }, index) : /* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles.dot, styles.dotStatic] }, index)
|
|
214
|
+
)
|
|
215
|
+
}
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
function AnimatedDot({ index, style }) {
|
|
219
|
+
const t = react.useRef(new reactNative.Animated.Value(0)).current;
|
|
220
|
+
react.useEffect(() => {
|
|
221
|
+
const anim = reactNative.Animated.sequence([
|
|
222
|
+
reactNative.Animated.delay(index * STAGGER_MS),
|
|
223
|
+
reactNative.Animated.loop(reactNative.Animated.timing(t, { toValue: 1, duration: LOOP_MS, useNativeDriver: true }))
|
|
224
|
+
]);
|
|
225
|
+
anim.start();
|
|
226
|
+
return () => anim.stop();
|
|
227
|
+
}, [t, index]);
|
|
228
|
+
const opacity = t.interpolate({ inputRange: TRI_IN, outputRange: [OPACITY_REST, 1, OPACITY_REST] });
|
|
229
|
+
const translateY = t.interpolate({ inputRange: TRI_IN, outputRange: [0, -3.5, 0] });
|
|
230
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactNative.Animated.View, { style: [style, { opacity, transform: [{ translateY }] }] });
|
|
231
|
+
}
|
|
232
|
+
function makeStyles(theme) {
|
|
233
|
+
const c = theme.color;
|
|
234
|
+
const s = theme.space;
|
|
235
|
+
const r = theme.radius;
|
|
236
|
+
return reactNative.StyleSheet.create({
|
|
237
|
+
card: {
|
|
238
|
+
alignSelf: "flex-start",
|
|
239
|
+
flexDirection: "row",
|
|
240
|
+
alignItems: "center",
|
|
241
|
+
gap: s.xs,
|
|
242
|
+
paddingHorizontal: s.md,
|
|
243
|
+
paddingVertical: s.sm,
|
|
244
|
+
backgroundColor: c.surfaceCream,
|
|
245
|
+
borderRadius: r.md,
|
|
246
|
+
borderWidth: reactNative.StyleSheet.hairlineWidth,
|
|
247
|
+
borderColor: c.brandBorder
|
|
248
|
+
},
|
|
249
|
+
dot: { width: DOT_SIZE, height: DOT_SIZE, borderRadius: r.pill, backgroundColor: c.brand },
|
|
250
|
+
dotStatic: { opacity: OPACITY_STATIC }
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
var ROTATION_PERIOD_MS = 1400;
|
|
254
|
+
var REVEAL_DELAY_MS = 300;
|
|
255
|
+
function AnalyzingIndicator() {
|
|
256
|
+
const theme = useEverfurTheme();
|
|
257
|
+
const styles = react.useMemo(() => makeStyles2(theme), [theme]);
|
|
258
|
+
const reduced = theme.motion.reducedMotion;
|
|
259
|
+
const [visible, setVisible] = react.useState(false);
|
|
260
|
+
react.useEffect(() => {
|
|
261
|
+
const id = setTimeout(() => setVisible(true), REVEAL_DELAY_MS);
|
|
262
|
+
return () => clearTimeout(id);
|
|
263
|
+
}, []);
|
|
264
|
+
const spin = react.useRef(new reactNative.Animated.Value(0)).current;
|
|
265
|
+
react.useEffect(() => {
|
|
266
|
+
if (reduced || !visible) return;
|
|
267
|
+
const loop = reactNative.Animated.loop(
|
|
268
|
+
reactNative.Animated.timing(spin, {
|
|
269
|
+
toValue: 1,
|
|
270
|
+
duration: ROTATION_PERIOD_MS,
|
|
271
|
+
easing: reactNative.Easing.linear,
|
|
272
|
+
useNativeDriver: true
|
|
273
|
+
})
|
|
274
|
+
);
|
|
275
|
+
loop.start();
|
|
276
|
+
return () => loop.stop();
|
|
277
|
+
}, [reduced, visible, spin]);
|
|
278
|
+
const arcMotionStyle = reduced ? null : { transform: [{ rotate: spin.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "360deg"] }) }] };
|
|
279
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
280
|
+
reactNative.View,
|
|
281
|
+
{
|
|
282
|
+
style: styles.wrap,
|
|
283
|
+
accessible: true,
|
|
284
|
+
accessibilityState: { busy: true },
|
|
285
|
+
accessibilityLabel: "Analyzing photo",
|
|
286
|
+
children: visible ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
287
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Animated.View, { style: [styles.ring, arcMotionStyle] }),
|
|
288
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: styles.statusLine, children: "Analyzing" })
|
|
289
|
+
] }) : null
|
|
290
|
+
}
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
function makeStyles2(theme) {
|
|
294
|
+
const { color, space, radius, type } = theme;
|
|
295
|
+
const medium = type.weight.medium;
|
|
296
|
+
const ringSize = space.xxl * 2;
|
|
297
|
+
const ringThickness = space.xs;
|
|
298
|
+
return reactNative.StyleSheet.create({
|
|
299
|
+
wrap: {
|
|
300
|
+
flexGrow: 1,
|
|
301
|
+
alignItems: "center",
|
|
302
|
+
justifyContent: "center",
|
|
303
|
+
padding: space.xl,
|
|
304
|
+
gap: space.md
|
|
305
|
+
},
|
|
306
|
+
// One rotating ring: success on the top/right, cream on the remainder. Only the success sweep is perceptible
|
|
307
|
+
// (the cream half is uniform), so this reads as a cream ring with a rotating success arc - the mobile look.
|
|
308
|
+
ring: {
|
|
309
|
+
width: ringSize,
|
|
310
|
+
height: ringSize,
|
|
311
|
+
borderRadius: radius.pill,
|
|
312
|
+
borderWidth: ringThickness,
|
|
313
|
+
borderTopColor: color.success,
|
|
314
|
+
borderRightColor: color.success,
|
|
315
|
+
borderBottomColor: color.borderRingCream,
|
|
316
|
+
borderLeftColor: color.borderRingCream
|
|
317
|
+
},
|
|
318
|
+
// Neutral SDK-owned structural status word (not clinical / product copy), on the brand-green secondary ramp
|
|
319
|
+
// so it sits in the same family as the verdict hero. Legible in both themes via the token.
|
|
320
|
+
statusLine: {
|
|
321
|
+
color: color.text.secondary,
|
|
322
|
+
fontFamily: type.family,
|
|
323
|
+
fontSize: type.size.subtitle,
|
|
324
|
+
lineHeight: type.size.subtitle * type.lineHeight.snug,
|
|
325
|
+
fontWeight: medium,
|
|
326
|
+
letterSpacing: type.letterSpacing.tight,
|
|
327
|
+
textAlign: "center"
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
var PULSE_PERIOD_MS = 1100;
|
|
332
|
+
var PULSE_MAX_SCALE = 1.6;
|
|
333
|
+
var PULSE_START_OPACITY = 0.35;
|
|
334
|
+
function toneSpec(theme, tier) {
|
|
335
|
+
const { color } = theme;
|
|
336
|
+
switch (tier) {
|
|
337
|
+
case "low_risk":
|
|
338
|
+
return { accent: color.success, wash: color.badgeBgPositive, label: "Low risk", pulse: false };
|
|
339
|
+
case "concern":
|
|
340
|
+
return { accent: color.cautionAccent, wash: color.badgeBgCaution, label: "Concern", pulse: true };
|
|
341
|
+
case "uncertain":
|
|
342
|
+
return { accent: color.text.muted, wash: color.badgeBgNeutral, label: "Uncertain", pulse: false };
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function SeverityBadge({ riskTier }) {
|
|
346
|
+
const theme = useEverfurTheme();
|
|
347
|
+
const styles = react.useMemo(() => makeStyles3(theme), [theme]);
|
|
348
|
+
const pulse = react.useRef(new reactNative.Animated.Value(0)).current;
|
|
349
|
+
const spec = riskTier === null ? null : toneSpec(theme, riskTier);
|
|
350
|
+
const shouldPulse = spec !== null && spec.pulse && !theme.motion.reducedMotion;
|
|
351
|
+
react.useEffect(() => {
|
|
352
|
+
if (!shouldPulse) return;
|
|
353
|
+
const loop = reactNative.Animated.loop(
|
|
354
|
+
reactNative.Animated.timing(pulse, {
|
|
355
|
+
toValue: 1,
|
|
356
|
+
duration: PULSE_PERIOD_MS,
|
|
357
|
+
easing: reactNative.Easing.out(reactNative.Easing.quad),
|
|
358
|
+
useNativeDriver: true
|
|
359
|
+
})
|
|
360
|
+
);
|
|
361
|
+
loop.start();
|
|
362
|
+
return () => loop.stop();
|
|
363
|
+
}, [shouldPulse, pulse]);
|
|
364
|
+
if (spec === null) return null;
|
|
365
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
366
|
+
reactNative.View,
|
|
367
|
+
{
|
|
368
|
+
style: [styles.pill, { backgroundColor: spec.wash }],
|
|
369
|
+
accessible: true,
|
|
370
|
+
accessibilityRole: "text",
|
|
371
|
+
accessibilityLabel: spec.label,
|
|
372
|
+
children: [
|
|
373
|
+
/* @__PURE__ */ jsxRuntime.jsxs(reactNative.View, { style: styles.dotWrap, children: [
|
|
374
|
+
shouldPulse ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
375
|
+
reactNative.Animated.View,
|
|
376
|
+
{
|
|
377
|
+
pointerEvents: "none",
|
|
378
|
+
style: [
|
|
379
|
+
styles.dotRing,
|
|
380
|
+
{
|
|
381
|
+
backgroundColor: spec.accent,
|
|
382
|
+
opacity: pulse.interpolate({ inputRange: [0, 1], outputRange: [PULSE_START_OPACITY, 0] }),
|
|
383
|
+
transform: [{ scale: pulse.interpolate({ inputRange: [0, 1], outputRange: [1, PULSE_MAX_SCALE] }) }]
|
|
384
|
+
}
|
|
385
|
+
]
|
|
386
|
+
}
|
|
387
|
+
) : null,
|
|
388
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.View, { style: [styles.dot, { backgroundColor: spec.accent }] })
|
|
389
|
+
] }),
|
|
390
|
+
/* @__PURE__ */ jsxRuntime.jsx(reactNative.Text, { style: [styles.label, { color: spec.accent }], children: spec.label })
|
|
391
|
+
]
|
|
392
|
+
}
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
function makeStyles3(theme) {
|
|
396
|
+
const { space, radius, type } = theme;
|
|
397
|
+
const bold = type.weight.bold;
|
|
398
|
+
const dotSize = space.sm;
|
|
399
|
+
return reactNative.StyleSheet.create({
|
|
400
|
+
pill: {
|
|
401
|
+
alignSelf: "flex-start",
|
|
402
|
+
flexDirection: "row",
|
|
403
|
+
alignItems: "center",
|
|
404
|
+
gap: space.sm,
|
|
405
|
+
paddingHorizontal: space.md,
|
|
406
|
+
paddingVertical: space.xs,
|
|
407
|
+
borderRadius: radius.pill
|
|
408
|
+
},
|
|
409
|
+
dotWrap: {
|
|
410
|
+
width: dotSize,
|
|
411
|
+
height: dotSize,
|
|
412
|
+
alignItems: "center",
|
|
413
|
+
justifyContent: "center"
|
|
414
|
+
},
|
|
415
|
+
dot: {
|
|
416
|
+
width: dotSize,
|
|
417
|
+
height: dotSize,
|
|
418
|
+
borderRadius: radius.pill
|
|
419
|
+
},
|
|
420
|
+
// The pulsing attention ring behind the dot (concern only). backgroundColor + animated opacity/scale set inline.
|
|
421
|
+
dotRing: {
|
|
422
|
+
position: "absolute",
|
|
423
|
+
width: dotSize,
|
|
424
|
+
height: dotSize,
|
|
425
|
+
borderRadius: radius.pill
|
|
426
|
+
},
|
|
427
|
+
label: {
|
|
428
|
+
fontFamily: type.family,
|
|
429
|
+
fontSize: type.size.caption,
|
|
430
|
+
lineHeight: type.size.caption * type.lineHeight.snug,
|
|
431
|
+
fontWeight: bold,
|
|
432
|
+
letterSpacing: type.letterSpacing.eyebrow
|
|
433
|
+
}
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// src/rn/testing.ts
|
|
438
|
+
function useEverfurTestEntitlements() {
|
|
439
|
+
const { runtime } = useEverfurContext();
|
|
440
|
+
return react.useMemo(
|
|
441
|
+
() => ({ apply: (snapshot) => runtime.updateEntitlements(snapshot) }),
|
|
442
|
+
[runtime]
|
|
443
|
+
);
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
exports.AnalyzingIndicator = AnalyzingIndicator;
|
|
447
|
+
exports.SeverityBadge = SeverityBadge;
|
|
448
|
+
exports.TypingIndicator = TypingIndicator;
|
|
449
|
+
exports.useEverfurTestEntitlements = useEverfurTestEntitlements;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { h as EntitlementSnapshot } from '../../runtime-BgQnA594.cjs';
|
|
2
|
+
export { C as ClientBranding } from '../../petsRepository-BEGb97M9.cjs';
|
|
3
|
+
export { a as CapabilityDisabled, c as DisabledLevel, E as EntitlementDecision } from '../../resolve-Dq_4_agU.cjs';
|
|
4
|
+
import { ReactNode } from 'react';
|
|
5
|
+
import { R as RiskTier } from '../../PhotoController-BItt5M7u.cjs';
|
|
6
|
+
import '../../EverfurResult-D92-uL82.cjs';
|
|
7
|
+
import '../../identity-Brl-lDd6.cjs';
|
|
8
|
+
import '../../ids-CJ1S6adf.cjs';
|
|
9
|
+
import '../../config-BSjBdxrZ.cjs';
|
|
10
|
+
import '../../cacheEpoch-DknKn3S0.cjs';
|
|
11
|
+
import '../../TelemetryPort-BDNr00hu.cjs';
|
|
12
|
+
import '../../ChatController-CpUMvvZf.cjs';
|
|
13
|
+
import '../../requestFunnel-DuUH-kAe.cjs';
|
|
14
|
+
import '../../FilePort-BabWrv7I.cjs';
|
|
15
|
+
import '../../CameraPort-Cv31Pz7g.cjs';
|
|
16
|
+
import '../../projection-CeIUsbSk.cjs';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The streaming "assistant is thinking" indicator: animated three-dot bounce under normal motion, three
|
|
20
|
+
* static dots under reduced motion. Pure / presentational -- takes no data, reads only theme tokens.
|
|
21
|
+
*/
|
|
22
|
+
declare function TypingIndicator(): ReactNode;
|
|
23
|
+
|
|
24
|
+
/** The busy analyzing indicator: a rotating success arc over a cream ring + a neutral SDK status line. */
|
|
25
|
+
declare function AnalyzingIndicator(): ReactNode;
|
|
26
|
+
|
|
27
|
+
/** A tone-driven severity pill for the BE-owned riskTier. Renders nothing when the tier is null. */
|
|
28
|
+
declare function SeverityBadge({ riskTier }: {
|
|
29
|
+
readonly riskTier: RiskTier | null;
|
|
30
|
+
}): ReactNode;
|
|
31
|
+
|
|
32
|
+
/** The testing seam handle: apply a resolved verdict to THIS provider's runtime. */
|
|
33
|
+
interface EverfurTestEntitlements {
|
|
34
|
+
/**
|
|
35
|
+
* Replace the entitlement verdict the current <EverfurProvider>'s runtime renders. Drives the SDK's own
|
|
36
|
+
* `useCapability` / `CapabilityGate` across every subpath (they read this one store), so a test/demo can
|
|
37
|
+
* flip a capability on or off and watch the real gates react. Render-only: the server stays authoritative.
|
|
38
|
+
*/
|
|
39
|
+
apply(snapshot: EntitlementSnapshot): void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* TEST / DEMO ONLY. Obtain a handle to push a simulated server entitlement verdict into the enclosing
|
|
43
|
+
* <EverfurProvider>'s runtime. Must be called inside an <EverfurProvider>.
|
|
44
|
+
*
|
|
45
|
+
* @throws {EverfurConfigError} kind 'not-initialized' when called outside an <EverfurProvider>.
|
|
46
|
+
*/
|
|
47
|
+
declare function useEverfurTestEntitlements(): EverfurTestEntitlements;
|
|
48
|
+
|
|
49
|
+
export { AnalyzingIndicator, EntitlementSnapshot, type EverfurTestEntitlements, RiskTier, SeverityBadge, TypingIndicator, useEverfurTestEntitlements };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { h as EntitlementSnapshot } from '../../runtime-CBA-LvdM.js';
|
|
2
|
+
export { C as ClientBranding } from '../../petsRepository-Bu18r2kK.js';
|
|
3
|
+
export { a as CapabilityDisabled, c as DisabledLevel, E as EntitlementDecision } from '../../resolve-Dq_4_agU.js';
|
|
4
|
+
import { ReactNode } from 'react';
|
|
5
|
+
import { R as RiskTier } from '../../PhotoController-D8zMTdcW.js';
|
|
6
|
+
import '../../EverfurResult-D92-uL82.js';
|
|
7
|
+
import '../../identity-DK9zORrG.js';
|
|
8
|
+
import '../../ids-CJ1S6adf.js';
|
|
9
|
+
import '../../config-CiJ0PVBB.js';
|
|
10
|
+
import '../../cacheEpoch-DknKn3S0.js';
|
|
11
|
+
import '../../TelemetryPort-BDNr00hu.js';
|
|
12
|
+
import '../../ChatController-CKdBvPj2.js';
|
|
13
|
+
import '../../requestFunnel-dio5OmR9.js';
|
|
14
|
+
import '../../FilePort-BabWrv7I.js';
|
|
15
|
+
import '../../CameraPort-Cv31Pz7g.js';
|
|
16
|
+
import '../../projection-CeIUsbSk.js';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The streaming "assistant is thinking" indicator: animated three-dot bounce under normal motion, three
|
|
20
|
+
* static dots under reduced motion. Pure / presentational -- takes no data, reads only theme tokens.
|
|
21
|
+
*/
|
|
22
|
+
declare function TypingIndicator(): ReactNode;
|
|
23
|
+
|
|
24
|
+
/** The busy analyzing indicator: a rotating success arc over a cream ring + a neutral SDK status line. */
|
|
25
|
+
declare function AnalyzingIndicator(): ReactNode;
|
|
26
|
+
|
|
27
|
+
/** A tone-driven severity pill for the BE-owned riskTier. Renders nothing when the tier is null. */
|
|
28
|
+
declare function SeverityBadge({ riskTier }: {
|
|
29
|
+
readonly riskTier: RiskTier | null;
|
|
30
|
+
}): ReactNode;
|
|
31
|
+
|
|
32
|
+
/** The testing seam handle: apply a resolved verdict to THIS provider's runtime. */
|
|
33
|
+
interface EverfurTestEntitlements {
|
|
34
|
+
/**
|
|
35
|
+
* Replace the entitlement verdict the current <EverfurProvider>'s runtime renders. Drives the SDK's own
|
|
36
|
+
* `useCapability` / `CapabilityGate` across every subpath (they read this one store), so a test/demo can
|
|
37
|
+
* flip a capability on or off and watch the real gates react. Render-only: the server stays authoritative.
|
|
38
|
+
*/
|
|
39
|
+
apply(snapshot: EntitlementSnapshot): void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* TEST / DEMO ONLY. Obtain a handle to push a simulated server entitlement verdict into the enclosing
|
|
43
|
+
* <EverfurProvider>'s runtime. Must be called inside an <EverfurProvider>.
|
|
44
|
+
*
|
|
45
|
+
* @throws {EverfurConfigError} kind 'not-initialized' when called outside an <EverfurProvider>.
|
|
46
|
+
*/
|
|
47
|
+
declare function useEverfurTestEntitlements(): EverfurTestEntitlements;
|
|
48
|
+
|
|
49
|
+
export { AnalyzingIndicator, EntitlementSnapshot, type EverfurTestEntitlements, RiskTier, SeverityBadge, TypingIndicator, useEverfurTestEntitlements };
|