@redacto.io/consent-sdk-react-native 5.1.0 → 6.0.1-beta.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.
@@ -0,0 +1,556 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/shared/idempotency.ts
9
+ var MAX_PENDING = 16;
10
+ var pending = /* @__PURE__ */ new Map();
11
+ var toHex = (bytes) => Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
12
+ var mintIdempotencyKey = (source = globalThis.crypto) => {
13
+ if (source && typeof source.randomUUID === "function") {
14
+ return source.randomUUID();
15
+ }
16
+ if (source && typeof source.getRandomValues === "function") {
17
+ return toHex(source.getRandomValues(new Uint8Array(16)));
18
+ }
19
+ return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 14)}-${Math.random().toString(36).slice(2, 14)}`;
20
+ };
21
+ var statusOf = (outcome) => {
22
+ if (typeof Response !== "undefined" && outcome instanceof Response) {
23
+ return outcome.status;
24
+ }
25
+ if (outcome && typeof outcome === "object" && "status" in outcome) {
26
+ const status = outcome.status;
27
+ if (typeof status === "number") return status;
28
+ }
29
+ return void 0;
30
+ };
31
+ var settledOnResolve = (result) => {
32
+ const status = statusOf(result);
33
+ return status === void 0 || status < 500;
34
+ };
35
+ var settledOnReject = (error) => {
36
+ const status = statusOf(error);
37
+ return status !== void 0 && status < 500;
38
+ };
39
+ var withIdempotencyKey = async (url, body, send) => {
40
+ const signature = `${url}
41
+ ${body}`;
42
+ let entry = pending.get(signature);
43
+ if (!entry) {
44
+ entry = { key: mintIdempotencyKey(), inFlight: 0, keep: false };
45
+ if (pending.size >= MAX_PENDING) {
46
+ const oldest = pending.keys().next().value;
47
+ if (oldest !== void 0) pending.delete(oldest);
48
+ }
49
+ pending.set(signature, entry);
50
+ } else if (entry.inFlight === 0) {
51
+ entry.keep = false;
52
+ }
53
+ entry.inFlight += 1;
54
+ const held = entry;
55
+ const settle = (settled) => {
56
+ held.inFlight -= 1;
57
+ if (!settled) held.keep = true;
58
+ if (held.inFlight === 0 && !held.keep) pending.delete(signature);
59
+ };
60
+ try {
61
+ const result = await send(held.key);
62
+ settle(settledOnResolve(result));
63
+ return result;
64
+ } catch (error) {
65
+ settle(settledOnReject(error));
66
+ throw error;
67
+ }
68
+ };
69
+
70
+ // src/shared/languages.ts
71
+ var languageOptions = [
72
+ { value: "en", label: "English" },
73
+ { value: "hi", label: "\u0939\u093F\u0928\u094D\u0926\u0940 (Hindi)" },
74
+ { value: "te", label: "\u0C24\u0C46\u0C32\u0C41\u0C17\u0C41 (Telugu)" },
75
+ { value: "mr", label: "\u092E\u0930\u093E\u0920\u0940 (Marathi)" },
76
+ { value: "ta", label: "\u0BA4\u0BAE\u0BBF\u0BB4\u0BCD (Tamil)" },
77
+ { value: "ur", label: "\u0627\u0631\u062F\u0648 (Urdu)" },
78
+ { value: "gu", label: "\u0A97\u0AC1\u0A9C\u0AB0\u0ABE\u0AA4\u0AC0 (Gujarati)" },
79
+ { value: "kn", label: "\u0C95\u0CA8\u0CCD\u0CA8\u0CA1 (Kannada)" },
80
+ { value: "ml", label: "\u0D2E\u0D32\u0D2F\u0D3E\u0D33\u0D02 (Malayalam)" },
81
+ { value: "pa", label: "\u0A2A\u0A70\u0A1C\u0A3E\u0A2C\u0A40 (Punjabi)" },
82
+ { value: "or", label: "\u0B13\u0B21\u0B3C\u0B3F\u0B06 (Odia)" },
83
+ { value: "as", label: "\u0985\u09B8\u09AE\u09C0\u09AF\u09BC\u09BE (Assamese)" },
84
+ { value: "bn", label: "\u09AC\u09BE\u0982\u09B2\u09BE (Bengali)" },
85
+ { value: "mai", label: "\u092E\u0948\u0925\u093F\u0932\u0940 (Maithili)" },
86
+ { value: "ne", label: "\u0928\u0947\u092A\u093E\u0932\u0940 (Nepali)" },
87
+ { value: "sd", label: "\u0633\u0646\u068C\u064A (Sindhi)" },
88
+ { value: "doi", label: "\u0921\u094B\u0917\u0930\u0940 (Dogri)" },
89
+ { value: "mni-Mtei", label: "\uABC3\uABE9\uABC7\uABE9\uABC2\uABE3\uABDF (Manipuri)" },
90
+ { value: "gom", label: "\u0915\u094B\u0902\u0915\u0923\u0940 (Goan Konkani)" },
91
+ { value: "sa", label: "\u0938\u0902\u0938\u094D\u0915\u0943\u0924\u092E\u094D (Sanskrit)" },
92
+ { value: "brx", label: "\u092C\u0921\u093C\u094B (Bodo)" },
93
+ { value: "ks", label: "\u0643\u0672\u0634\u064F\u0631 (Kashmiri)" },
94
+ { value: "sat", label: "\u1C65\u1C5F\u1C71\u1C5B\u1C5F\u1C72\u1C64 (Santali)" }
95
+ ];
96
+ var codeByLabel = new Map(languageOptions.map((o) => [o.label, o.value]));
97
+ var codeByLower = new Map(languageOptions.map((o) => [o.value.toLowerCase(), o.value]));
98
+ var englishName = (label) => {
99
+ var _a, _b;
100
+ return (_b = (_a = label.match(/\(([^)]+)\)\s*$/)) == null ? void 0 : _a[1]) != null ? _b : label;
101
+ };
102
+ var codeByName = new Map(
103
+ languageOptions.map((o) => [englishName(o.label).toLowerCase(), o.value])
104
+ );
105
+ function toLanguageCode(lang) {
106
+ var _a, _b, _c;
107
+ if (!lang) return void 0;
108
+ const trimmed = lang.trim();
109
+ if (!trimmed) return void 0;
110
+ const lower = trimmed.toLowerCase();
111
+ return (_c = (_b = (_a = codeByLabel.get(trimmed)) != null ? _a : codeByName.get(lower)) != null ? _b : codeByLower.get(lower)) != null ? _c : trimmed;
112
+ }
113
+ var nativeLabelByName = new Map(languageOptions.map((o) => [englishName(o.label), o.label]));
114
+ function toNativeLabel(name) {
115
+ var _a;
116
+ return (_a = nativeLabelByName.get(name)) != null ? _a : name;
117
+ }
118
+
119
+ // src/shared/NoticeText.tsx
120
+ import { createContext, forwardRef, useContext, useMemo } from "react";
121
+ import { Text as NativeText, TextInput as NativeTextInput, View } from "react-native";
122
+ import { jsx } from "react/jsx-runtime";
123
+ var NoticeFontContext = createContext(null);
124
+ var useTextDefaults = () => {
125
+ const defaults = useContext(NoticeFontContext);
126
+ if (!defaults) {
127
+ return null;
128
+ }
129
+ const style = {};
130
+ if (defaults.fontFamily) {
131
+ style.fontFamily = defaults.fontFamily;
132
+ }
133
+ if (defaults.writingDirection) {
134
+ style.writingDirection = defaults.writingDirection;
135
+ }
136
+ return Object.keys(style).length > 0 ? style : null;
137
+ };
138
+ var NoticeFontProvider = ({ fontFamily, writingDirection, onInput, children }) => {
139
+ const outer = useContext(NoticeFontContext);
140
+ const value = useMemo(
141
+ () => ({
142
+ fontFamily: fontFamily != null ? fontFamily : outer == null ? void 0 : outer.fontFamily,
143
+ writingDirection: writingDirection != null ? writingDirection : outer == null ? void 0 : outer.writingDirection,
144
+ onInput: onInput != null ? onInput : outer == null ? void 0 : outer.onInput
145
+ }),
146
+ [fontFamily, writingDirection, onInput, outer]
147
+ );
148
+ return /* @__PURE__ */ jsx(NoticeFontContext.Provider, { value, children });
149
+ };
150
+ var NoticeFontView = ({ fontFamily, ...viewProps }) => /* @__PURE__ */ jsx(NoticeFontProvider, { fontFamily, children: /* @__PURE__ */ jsx(View, { ...viewProps }) });
151
+ var Text = forwardRef(
152
+ function NoticeText({ style, ...rest }, ref) {
153
+ const defaults = useTextDefaults();
154
+ return /* @__PURE__ */ jsx(NativeText, { ref, ...rest, style: defaults ? [defaults, style] : style });
155
+ }
156
+ );
157
+ var TextInput = forwardRef(
158
+ function NoticeTextInput({ style, onChangeText, ...rest }, ref) {
159
+ var _a;
160
+ const defaults = useTextDefaults();
161
+ const onInput = (_a = useContext(NoticeFontContext)) == null ? void 0 : _a.onInput;
162
+ const handleChangeText = useMemo(
163
+ () => onInput ? (text) => {
164
+ onInput();
165
+ onChangeText == null ? void 0 : onChangeText(text);
166
+ } : onChangeText,
167
+ [onInput, onChangeText]
168
+ );
169
+ return /* @__PURE__ */ jsx(
170
+ NativeTextInput,
171
+ {
172
+ ref,
173
+ ...rest,
174
+ onChangeText: handleChangeText,
175
+ style: defaults ? [defaults, style] : style
176
+ }
177
+ );
178
+ }
179
+ );
180
+
181
+ // src/shared/appearance/constants.ts
182
+ var NOTICE_COLOR_KEYS = [
183
+ "background",
184
+ "surface",
185
+ "heading",
186
+ "text",
187
+ "muted_text",
188
+ "link",
189
+ "border",
190
+ "overlay",
191
+ "accept_all_bg",
192
+ "accept_all_text",
193
+ "accept_bg",
194
+ "accept_text",
195
+ "decline_bg",
196
+ "decline_text",
197
+ "decline_border",
198
+ "language_bg",
199
+ "language_text",
200
+ "language_selected_bg",
201
+ "language_selected_text",
202
+ "toggle_on",
203
+ "toggle_off",
204
+ "toggle_knob",
205
+ "tts_highlight_bg",
206
+ "tts_highlight_text"
207
+ ];
208
+ var NOTICE_SELECTION_CONTROLS = ["checkbox", "radio", "dropdown"];
209
+ var NOTICE_CONTROL_STYLES = ["checkbox", "switch"];
210
+ var NOTICE_RADIUS_MIN = 0;
211
+ var NOTICE_RADIUS_MAX = 28;
212
+ var NOTICE_MOBILE_LAYOUTS = ["modal", "sheet"];
213
+ var NOTICE_DESKTOP_POSITIONS = [
214
+ "center",
215
+ "bottom-right",
216
+ "bottom-left",
217
+ "bottom-bar"
218
+ ];
219
+ var NOTICE_BACKDROPS = ["dim", "none"];
220
+ var NOTICE_PHONE_FOOTERS = ["stacked", "paired"];
221
+ var NOTICE_TEXT_SCALES = ["sm", "md", "lg"];
222
+ var DEFAULT_TEXT_SCALE = "md";
223
+ var DEFAULT_DESKTOP_POSITION = "center";
224
+ var NOTICE_TEXT_SCALE_FACTORS = {
225
+ sm: 0.92,
226
+ md: 1,
227
+ lg: 1.1
228
+ };
229
+ var NOTICE_WIDTH_MIN = 320;
230
+ var NOTICE_WIDTH_MAX = 960;
231
+ var NOTICE_LOGO_SIZE_MIN = 16;
232
+ var NOTICE_LOGO_SIZE_MAX = 96;
233
+ var NOTICE_HEX_COLOR_RE = /^#(?:[0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
234
+ var DEFAULT_TTS_HIGHLIGHT_BG = "#FFF9C4";
235
+ var PX_LENGTH_RE = /^\s*(\d+(?:\.\d+)?)(?:px)?\s*$/i;
236
+
237
+ // src/shared/appearance/registry.ts
238
+ var DEFAULT_APPEARANCE = "classic";
239
+ var CLASSIC_LAYOUT = {
240
+ sheet: false,
241
+ collapsibleSections: false,
242
+ switchControl: false,
243
+ pairedFooter: false,
244
+ loaderPill: false,
245
+ sheetOverlays: false
246
+ };
247
+ var APPEARANCES = {
248
+ classic: { layout: CLASSIC_LAYOUT },
249
+ // Minimal and soft restyle classic's surfaces and keep its layout.
250
+ minimal: { layout: CLASSIC_LAYOUT },
251
+ soft: { layout: CLASSIC_LAYOUT },
252
+ glass: {
253
+ layout: {
254
+ sheet: true,
255
+ collapsibleSections: true,
256
+ // Checkboxes until the admin (or the host) picks switches, in every style.
257
+ switchControl: false,
258
+ pairedFooter: true,
259
+ loaderPill: true,
260
+ sheetOverlays: true
261
+ }
262
+ }
263
+ };
264
+ var isAppearance = (value) => typeof value === "string" && Object.prototype.hasOwnProperty.call(APPEARANCES, value);
265
+ var resolveAppearance = (value) => isAppearance(value) ? value : DEFAULT_APPEARANCE;
266
+ var getAppearanceLayout = (appearance) => APPEARANCES[appearance].layout;
267
+
268
+ // src/shared/appearance/layout.ts
269
+ var resolveNoticeLayout = (appearance) => {
270
+ var _a, _b, _c;
271
+ const defaults = getAppearanceLayout(appearance.style);
272
+ return {
273
+ mobileSheet: appearance.mobileLayout ? appearance.mobileLayout === "sheet" : defaults.sheet,
274
+ desktopPosition: (_a = appearance.desktopPosition) != null ? _a : DEFAULT_DESKTOP_POSITION,
275
+ dimBackdrop: appearance.backdrop !== "none",
276
+ collapsibleSections: (_b = appearance.collapsibleSections) != null ? _b : defaults.collapsibleSections,
277
+ pairedFooter: appearance.phoneFooter ? appearance.phoneFooter === "paired" : defaults.pairedFooter,
278
+ switchControl: appearance.controlStyle ? appearance.controlStyle === "switch" : defaults.switchControl,
279
+ motion: (_c = appearance.motion) != null ? _c : true
280
+ };
281
+ };
282
+
283
+ // src/shared/appearance/resolve.ts
284
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
285
+ var pickColors = (raw) => {
286
+ if (!isRecord(raw)) {
287
+ return {};
288
+ }
289
+ const colors = {};
290
+ for (const key of NOTICE_COLOR_KEYS) {
291
+ const value = raw[key];
292
+ if (typeof value === "string" && NOTICE_HEX_COLOR_RE.test(value)) {
293
+ colors[key] = value;
294
+ }
295
+ }
296
+ return colors;
297
+ };
298
+ var pickPx = (raw, min, max) => {
299
+ if (typeof raw !== "number" || !Number.isFinite(raw)) {
300
+ return void 0;
301
+ }
302
+ return Math.min(max, Math.max(min, Math.round(raw)));
303
+ };
304
+ var pickOption = (options, raw) => options.find((option) => option === raw);
305
+ var pickBoolean = (raw) => typeof raw === "boolean" ? raw : void 0;
306
+ var resolveNoticeAppearance = (raw) => {
307
+ const appearance = isRecord(raw) ? raw : {};
308
+ return {
309
+ style: resolveAppearance(appearance.style),
310
+ colors: pickColors(appearance.colors),
311
+ radius: pickPx(appearance.border_radius, NOTICE_RADIUS_MIN, NOTICE_RADIUS_MAX),
312
+ selectionControl: pickOption(NOTICE_SELECTION_CONTROLS, appearance.selection_control),
313
+ controlStyle: pickOption(NOTICE_CONTROL_STYLES, appearance.control_style),
314
+ confirmBeforeSubmit: appearance.confirm_before_submit === true,
315
+ mobileLayout: pickOption(NOTICE_MOBILE_LAYOUTS, appearance.mobile_layout),
316
+ desktopPosition: pickOption(NOTICE_DESKTOP_POSITIONS, appearance.desktop_position),
317
+ backdrop: pickOption(NOTICE_BACKDROPS, appearance.backdrop),
318
+ collapsibleSections: pickBoolean(appearance.collapsible_sections),
319
+ phoneFooter: pickOption(NOTICE_PHONE_FOOTERS, appearance.phone_footer),
320
+ autoDark: appearance.auto_dark === true,
321
+ darkColors: pickColors(appearance.dark_colors),
322
+ maxWidth: pickPx(appearance.max_width, NOTICE_WIDTH_MIN, NOTICE_WIDTH_MAX),
323
+ logoSize: pickPx(appearance.logo_size, NOTICE_LOGO_SIZE_MIN, NOTICE_LOGO_SIZE_MAX),
324
+ textScale: pickOption(NOTICE_TEXT_SCALES, appearance.text_scale),
325
+ motion: pickBoolean(appearance.motion)
326
+ };
327
+ };
328
+ var withColorScheme = (appearance, prefersDark) => appearance.autoDark && prefersDark && Object.keys(appearance.darkColors).length > 0 ? { ...appearance, colors: appearance.darkColors } : appearance;
329
+
330
+ // src/shared/appearance/color.ts
331
+ var HEX_RE = /^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i;
332
+ var NUM = String.raw`(\d+(?:\.\d+)?|\.\d+)`;
333
+ var RGB_RE = new RegExp(
334
+ String.raw`^rgba?\(\s*${NUM}(%?)[\s,]+${NUM}(%?)[\s,]+${NUM}(%?)(?:[\s,/]+${NUM}(%?))?\s*\)$`,
335
+ "i"
336
+ );
337
+ var BYTE_MAX = 255;
338
+ var PERCENT_MAX = 100;
339
+ var clampByte = (n) => Math.min(255, Math.max(0, Math.round(n)));
340
+ var clampUnit = (n) => Math.min(1, Math.max(0, n));
341
+ var parseColor = (input) => {
342
+ if (!input) {
343
+ return null;
344
+ }
345
+ const value = input.trim();
346
+ const hex = HEX_RE.exec(value);
347
+ if (hex) {
348
+ let digits = hex[1];
349
+ if (digits.length <= 4) {
350
+ digits = digits.split("").map((d) => d + d).join("");
351
+ }
352
+ const n = (i) => parseInt(digits.slice(i, i + 2), 16);
353
+ return {
354
+ r: n(0),
355
+ g: n(2),
356
+ b: n(4),
357
+ a: digits.length === 8 ? n(6) / 255 : 1
358
+ };
359
+ }
360
+ const rgb = RGB_RE.exec(value);
361
+ if (rgb) {
362
+ const channel = (raw, unit) => unit ? Number(raw) * BYTE_MAX / PERCENT_MAX : Number(raw);
363
+ const alpha = rgb[7];
364
+ const a = alpha === void 0 ? 1 : Number(alpha) / (rgb[8] ? 100 : 1);
365
+ return {
366
+ r: clampByte(channel(rgb[1], rgb[2])),
367
+ g: clampByte(channel(rgb[3], rgb[4])),
368
+ b: clampByte(channel(rgb[5], rgb[6])),
369
+ a: clampUnit(a)
370
+ };
371
+ }
372
+ return null;
373
+ };
374
+ var NAMED_COLORS = new Set(
375
+ "aliceblue antiquewhite aqua aquamarine azure beige bisque black blanchedalmond blue blueviolet brown burlywood cadetblue chartreuse chocolate coral cornflowerblue cornsilk crimson cyan darkblue darkcyan darkgoldenrod darkgray darkgreen darkgrey darkkhaki darkmagenta darkolivegreen darkorange darkorchid darkred darksalmon darkseagreen darkslateblue darkslategray darkslategrey darkturquoise darkviolet deeppink deepskyblue dimgray dimgrey dodgerblue firebrick floralwhite forestgreen fuchsia gainsboro ghostwhite gold goldenrod gray green greenyellow grey honeydew hotpink indianred indigo ivory khaki lavender lavenderblush lawngreen lemonchiffon lightblue lightcoral lightcyan lightgoldenrodyellow lightgray lightgreen lightgrey lightpink lightsalmon lightseagreen lightskyblue lightslategray lightslategrey lightsteelblue lightyellow lime limegreen linen magenta maroon mediumaquamarine mediumblue mediumorchid mediumpurple mediumseagreen mediumslateblue mediumspringgreen mediumturquoise mediumvioletred midnightblue mintcream mistyrose moccasin navajowhite navy oldlace olive olivedrab orange orangered orchid palegoldenrod palegreen paleturquoise palevioletred papayawhip peachpuff peru pink plum powderblue purple rebeccapurple red rosybrown royalblue saddlebrown salmon sandybrown seagreen seashell sienna silver skyblue slateblue slategray slategrey snow springgreen steelblue tan teal thistle tomato turquoise violet wheat white whitesmoke yellow yellowgreen transparent".split(" ")
376
+ );
377
+ var NATIVE_COLOR_FUNCTION_RE = /^(?:hsla?|hwb)\([^();{}<>"'\\]*\)$/i;
378
+ var isPassthroughColor = (value) => NAMED_COLORS.has(value.toLowerCase()) || NATIVE_COLOR_FUNCTION_RE.test(value);
379
+ var paintableColor = (color, fallback) => {
380
+ const value = color == null ? void 0 : color.trim();
381
+ if (!value) {
382
+ return fallback;
383
+ }
384
+ return parseColor(value) || isPassthroughColor(value) ? value : fallback;
385
+ };
386
+ var format = ({ r, g, b, a }) => `rgba(${clampByte(r)}, ${clampByte(g)}, ${clampByte(b)}, ${Number(clampUnit(a).toFixed(3))})`;
387
+ var withAlpha = (color, alpha) => {
388
+ const parsed = parseColor(color);
389
+ return parsed ? format({ ...parsed, a: parsed.a * alpha }) : color;
390
+ };
391
+ var mix = (a, b, t) => {
392
+ const pa = parseColor(a);
393
+ const pb = parseColor(b);
394
+ if (!pa || !pb) {
395
+ return a;
396
+ }
397
+ const k = clampUnit(t);
398
+ return format({
399
+ r: pa.r + (pb.r - pa.r) * k,
400
+ g: pa.g + (pb.g - pa.g) * k,
401
+ b: pa.b + (pb.b - pa.b) * k,
402
+ a: 1
403
+ });
404
+ };
405
+ var opaqueOver = (color, base) => {
406
+ const pc = parseColor(color);
407
+ const pb = parseColor(base);
408
+ if (!pc || !pb) {
409
+ return color;
410
+ }
411
+ return mix(base, format({ ...pc, a: 1 }), pc.a);
412
+ };
413
+
414
+ // src/shared/appearance/glass.ts
415
+ var SHADE_BASE = "#05050f";
416
+ var GLASS_DEFAULT_TINT = "#ffffff";
417
+ var GLASS_RADIUS = {
418
+ sheet: 28,
419
+ panel: 20,
420
+ control: 12,
421
+ row: 10,
422
+ pill: 999
423
+ };
424
+ var nativeShadow = (color, offsetY, blur, opacity, elevation) => ({
425
+ shadowColor: color,
426
+ shadowOffset: { width: 0, height: offsetY },
427
+ shadowOpacity: opacity,
428
+ shadowRadius: blur / 2,
429
+ elevation
430
+ });
431
+ var glassPalette = ({
432
+ accent,
433
+ tint = GLASS_DEFAULT_TINT
434
+ }) => {
435
+ const shade = mix(accent, SHADE_BASE, 0.7);
436
+ const sheetDense = withAlpha(tint, 0.86);
437
+ return {
438
+ accent,
439
+ sheet: sheetDense,
440
+ sheetDense,
441
+ sheetEdge: withAlpha(tint, 0.6),
442
+ panel: withAlpha(tint, 0.5),
443
+ panelEdge: withAlpha(tint, 0.55),
444
+ inset: withAlpha(tint, 0.55),
445
+ control: withAlpha(tint, 0.72),
446
+ footer: withAlpha(tint, 0.9),
447
+ accentFaint: withAlpha(accent, 0.04),
448
+ accentWash: withAlpha(accent, 0.08),
449
+ accentWashStrong: withAlpha(accent, 0.22),
450
+ hairline: withAlpha(shade, 0.08),
451
+ outline: withAlpha(shade, 0.14),
452
+ dim: withAlpha(shade, 0.3),
453
+ shadow: nativeShadow(shade, -18, 50, 0.35, 12),
454
+ floatShadow: nativeShadow(shade, 24, 60, 0.45, 16),
455
+ primaryShadow: nativeShadow(accent, 10, 24, 0.6, 6)
456
+ };
457
+ };
458
+
459
+ // src/shared/endpoints.ts
460
+ var CONSENT_SERVICE_PATH = "/consent";
461
+ var LEDGER_SERVICE_PATH = "/consent-ledger";
462
+ var ABSOLUTE_HTTP_URL = /^https?:\/\/(?:\[[0-9a-f:.]+\]|[^\s/?#@:[\]]+)(?::\d+)?(?:\/[^\s?#]*)?$/i;
463
+ var CONSENT_SUFFIX = /\/consent$/i;
464
+ var LEDGER_SUFFIX = /\/consent-ledger$/i;
465
+ var trimUrl = (value) => (value != null ? value : "").trim().replace(/\/+$/, "");
466
+ var isApiHost = (trimmed) => ABSOLUTE_HTTP_URL.test(trimmed) && !CONSENT_SUFFIX.test(trimmed);
467
+ function resolveBaseUrls(baseUrl, ledgerBaseUrl) {
468
+ const trimmed = trimUrl(baseUrl);
469
+ if (!isApiHost(trimmed)) {
470
+ return { mode: "legacy", baseUrl, ledgerBaseUrl };
471
+ }
472
+ const apiHost = trimUrl(trimmed.replace(LEDGER_SUFFIX, ""));
473
+ return {
474
+ mode: "host",
475
+ apiHost,
476
+ baseUrl: `${apiHost}${CONSENT_SERVICE_PATH}`,
477
+ ledgerBaseUrl: `${apiHost}${LEDGER_SERVICE_PATH}`
478
+ };
479
+ }
480
+ var BASE_URL_WARNINGS = {
481
+ omitted: "[Redacto] baseUrl was not passed, so the SDK is using its built-in production default. Pass baseUrl, the API host of your environment.",
482
+ consentPath: "[Redacto] A baseUrl ending in /consent is deprecated. Pass the API host instead (the same URL without /consent); the SDK derives the consent server and the ledger from it.",
483
+ ledgerBaseUrl: "[Redacto] ledgerBaseUrl is deprecated. Pass the Redacto API host as baseUrl instead; the SDK then reaches the consent server and the ledger under it.",
484
+ ledgerIgnored: "[Redacto] ledgerBaseUrl is ignored because baseUrl is the API host; the SDK reaches the ledger under that host. Remove ledgerBaseUrl.",
485
+ slugIgnored: "[Redacto] slug is deprecated and ignored. The Privacy Center reads the organisation from the access token, or from organisationUuid and workspaceUuid. Remove slug."
486
+ };
487
+ var issuedWarnings = /* @__PURE__ */ new Set();
488
+ var warnOnce = (warning) => {
489
+ if (issuedWarnings.has(warning)) return;
490
+ issuedWarnings.add(warning);
491
+ console.warn(BASE_URL_WARNINGS[warning]);
492
+ };
493
+ var warnSlugDeprecated = () => {
494
+ warnOnce("slugIgnored");
495
+ };
496
+ var warnDeprecatedBaseUrls = (baseUrl, ledgerBaseUrl, { hasDefaultHost }) => {
497
+ const trimmed = trimUrl(baseUrl);
498
+ if (!trimmed) {
499
+ if (hasDefaultHost) warnOnce("omitted");
500
+ } else if (CONSENT_SUFFIX.test(trimmed)) {
501
+ warnOnce("consentPath");
502
+ }
503
+ if (trimUrl(ledgerBaseUrl)) {
504
+ warnOnce(isApiHost(trimmed) ? "ledgerIgnored" : "ledgerBaseUrl");
505
+ }
506
+ };
507
+ var resolveNoticeBaseUrls = (baseUrl, ledgerBaseUrl) => {
508
+ warnDeprecatedBaseUrls(baseUrl, ledgerBaseUrl, { hasDefaultHost: true });
509
+ return resolveBaseUrls(baseUrl, ledgerBaseUrl);
510
+ };
511
+
512
+ // src/shared/sandbox.ts
513
+ var SANDBOX_TOKEN_HEADER = "X-Consent-Token";
514
+
515
+ // src/constants.ts
516
+ var DEFAULT_CONSENT_API_BASE_URL = "https://api.redacto.io/consent";
517
+ var REQUIRED_MARKER_GLYPH = " *";
518
+ var REQUIRED_MARKER_COLOR = "red";
519
+ var USER_SERVICE_PATH = "/user/api/0";
520
+
521
+ export {
522
+ __require,
523
+ SANDBOX_TOKEN_HEADER,
524
+ DEFAULT_CONSENT_API_BASE_URL,
525
+ REQUIRED_MARKER_GLYPH,
526
+ REQUIRED_MARKER_COLOR,
527
+ USER_SERVICE_PATH,
528
+ withIdempotencyKey,
529
+ languageOptions,
530
+ toLanguageCode,
531
+ toNativeLabel,
532
+ NoticeFontProvider,
533
+ NoticeFontView,
534
+ Text,
535
+ TextInput,
536
+ DEFAULT_TEXT_SCALE,
537
+ NOTICE_TEXT_SCALE_FACTORS,
538
+ DEFAULT_TTS_HIGHLIGHT_BG,
539
+ PX_LENGTH_RE,
540
+ isAppearance,
541
+ resolveAppearance,
542
+ getAppearanceLayout,
543
+ resolveNoticeLayout,
544
+ resolveNoticeAppearance,
545
+ withColorScheme,
546
+ paintableColor,
547
+ withAlpha,
548
+ opaqueOver,
549
+ GLASS_DEFAULT_TINT,
550
+ GLASS_RADIUS,
551
+ glassPalette,
552
+ resolveBaseUrls,
553
+ warnSlugDeprecated,
554
+ warnDeprecatedBaseUrls,
555
+ resolveNoticeBaseUrls
556
+ };