kaafil-react-uikit 0.1.0-beta.1

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 (79) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/LICENSE +21 -0
  3. package/README.md +187 -0
  4. package/dist/OfflineFallbackScreen-B5dfaJBN.d.ts +37 -0
  5. package/dist/OfflineFallbackScreen-Ctm7nBa-.d.cts +37 -0
  6. package/dist/SessionExpiredScreen-CytQNuak.d.cts +50 -0
  7. package/dist/SessionExpiredScreen-D8GHyZc3.d.ts +50 -0
  8. package/dist/admin/index.cjs +23779 -0
  9. package/dist/admin/index.cjs.map +1 -0
  10. package/dist/admin/index.d.cts +1157 -0
  11. package/dist/admin/index.d.ts +1157 -0
  12. package/dist/admin/index.js +23724 -0
  13. package/dist/admin/index.js.map +1 -0
  14. package/dist/chunk-6FPAGGFL.js +6028 -0
  15. package/dist/chunk-6FPAGGFL.js.map +1 -0
  16. package/dist/chunk-ACVU55PZ.cjs +294 -0
  17. package/dist/chunk-ACVU55PZ.cjs.map +1 -0
  18. package/dist/chunk-EM7JV3D7.cjs +6051 -0
  19. package/dist/chunk-EM7JV3D7.cjs.map +1 -0
  20. package/dist/chunk-IIPQ4JNC.js +287 -0
  21. package/dist/chunk-IIPQ4JNC.js.map +1 -0
  22. package/dist/chunk-LL243STJ.cjs +2195 -0
  23. package/dist/chunk-LL243STJ.cjs.map +1 -0
  24. package/dist/chunk-PJRZCOFF.cjs +958 -0
  25. package/dist/chunk-PJRZCOFF.cjs.map +1 -0
  26. package/dist/chunk-PTQ2CJKE.cjs +40 -0
  27. package/dist/chunk-PTQ2CJKE.cjs.map +1 -0
  28. package/dist/chunk-PZKXLQSU.js +10 -0
  29. package/dist/chunk-PZKXLQSU.js.map +1 -0
  30. package/dist/chunk-QHUDOVKW.cjs +111 -0
  31. package/dist/chunk-QHUDOVKW.cjs.map +1 -0
  32. package/dist/chunk-TOBZFADB.cjs +12 -0
  33. package/dist/chunk-TOBZFADB.cjs.map +1 -0
  34. package/dist/chunk-UUGMNP27.js +936 -0
  35. package/dist/chunk-UUGMNP27.js.map +1 -0
  36. package/dist/chunk-UYJ6LIWP.js +2154 -0
  37. package/dist/chunk-UYJ6LIWP.js.map +1 -0
  38. package/dist/chunk-VHTSTUCJ.cjs +346 -0
  39. package/dist/chunk-VHTSTUCJ.cjs.map +1 -0
  40. package/dist/chunk-WUAFL77X.js +340 -0
  41. package/dist/chunk-WUAFL77X.js.map +1 -0
  42. package/dist/chunk-XI7MK4Y7.js +38 -0
  43. package/dist/chunk-XI7MK4Y7.js.map +1 -0
  44. package/dist/chunk-YDGR7JSY.js +107 -0
  45. package/dist/chunk-YDGR7JSY.js.map +1 -0
  46. package/dist/core/index.cjs +1254 -0
  47. package/dist/core/index.cjs.map +1 -0
  48. package/dist/core/index.d.cts +1267 -0
  49. package/dist/core/index.d.ts +1267 -0
  50. package/dist/core/index.js +995 -0
  51. package/dist/core/index.js.map +1 -0
  52. package/dist/index.css +1 -0
  53. package/dist/manager/index.cjs +13562 -0
  54. package/dist/manager/index.cjs.map +1 -0
  55. package/dist/manager/index.d.cts +1054 -0
  56. package/dist/manager/index.d.ts +1054 -0
  57. package/dist/manager/index.js +13518 -0
  58. package/dist/manager/index.js.map +1 -0
  59. package/dist/testing/index.cjs +221 -0
  60. package/dist/testing/index.cjs.map +1 -0
  61. package/dist/testing/index.d.cts +269 -0
  62. package/dist/testing/index.d.ts +269 -0
  63. package/dist/testing/index.js +208 -0
  64. package/dist/testing/index.js.map +1 -0
  65. package/dist/tokenStyle-CToG5oOS.d.cts +3 -0
  66. package/dist/tokenStyle-CToG5oOS.d.ts +3 -0
  67. package/dist/traveller/index.cjs +1799 -0
  68. package/dist/traveller/index.cjs.map +1 -0
  69. package/dist/traveller/index.d.cts +58 -0
  70. package/dist/traveller/index.d.ts +58 -0
  71. package/dist/traveller/index.js +1789 -0
  72. package/dist/traveller/index.js.map +1 -0
  73. package/dist/useAgencyTrip-BUYSIaC2.d.cts +454 -0
  74. package/dist/useAgencyTrip-BzyJB1D9.d.ts +454 -0
  75. package/dist/useNotifications-BZW1Z_ur.d.cts +356 -0
  76. package/dist/useNotifications-D262i5BQ.d.ts +356 -0
  77. package/dist/useVendors-DXOuZWhZ.d.cts +784 -0
  78. package/dist/useVendors-DXOuZWhZ.d.ts +784 -0
  79. package/package.json +95 -0
@@ -0,0 +1,1254 @@
1
+ 'use strict';
2
+
3
+ var chunkQHUDOVKW_cjs = require('../chunk-QHUDOVKW.cjs');
4
+ var chunkPJRZCOFF_cjs = require('../chunk-PJRZCOFF.cjs');
5
+ var chunkLL243STJ_cjs = require('../chunk-LL243STJ.cjs');
6
+ var chunkVHTSTUCJ_cjs = require('../chunk-VHTSTUCJ.cjs');
7
+ var chunkTOBZFADB_cjs = require('../chunk-TOBZFADB.cjs');
8
+ var chunkPTQ2CJKE_cjs = require('../chunk-PTQ2CJKE.cjs');
9
+ var chunkEM7JV3D7_cjs = require('../chunk-EM7JV3D7.cjs');
10
+ var client = require('kaafil-js/client');
11
+ var react = require('react');
12
+ var reactDom = require('react-dom');
13
+ var jsxRuntime = require('react/jsx-runtime');
14
+
15
+ var NotImplementedError = class _NotImplementedError extends Error {
16
+ hookName;
17
+ specSection;
18
+ constructor(hookName, specSection) {
19
+ super(
20
+ `${hookName}() has no implementation in this build yet \u2014 see 08-core-hooks.md ${specSection} for its full signature and SDK binding.`
21
+ );
22
+ this.name = "NotImplementedError";
23
+ Object.setPrototypeOf(this, _NotImplementedError.prototype);
24
+ this.hookName = hookName;
25
+ this.specSection = specSection;
26
+ }
27
+ };
28
+ function useBlobStatus(blobId) {
29
+ const engine = react.useContext(chunkEM7JV3D7_cjs.OfflineEngineContext);
30
+ const [, forceRefresh] = react.useState(0);
31
+ chunkEM7JV3D7_cjs.useOfflineEvent("sync.drained", () => forceRefresh((tick) => tick + 1));
32
+ chunkEM7JV3D7_cjs.useOfflineEvent("sync.error", () => forceRefresh((tick) => tick + 1));
33
+ const record = engine?.blobs?.all().find((candidate) => candidate.id === blobId);
34
+ if (record === void 0) {
35
+ return { status: "pending", progress: void 0 };
36
+ }
37
+ const status = record.status === "confirmed" ? "ready" : record.status === "parked" ? "orphaned" : record.attemptCount > 0 ? "uploading" : "pending";
38
+ return { status, progress: void 0 };
39
+ }
40
+ function useFeedbackNps(scope) {
41
+ const client$1 = chunkEM7JV3D7_cjs.useKaafilClient();
42
+ const [summary, setSummary] = react.useState(void 0);
43
+ const [definitions, setDefinitions] = react.useState([]);
44
+ const [loaded, setLoaded] = react.useState(false);
45
+ const [lastFetchFailed, setLastFetchFailed] = react.useState(false);
46
+ const [syncedAt, setSyncedAt] = react.useState(void 0);
47
+ const formIdRef = react.useRef(void 0);
48
+ const refresh = react.useCallback(async () => {
49
+ try {
50
+ if (scope.kind === "trip") {
51
+ const response = await client$1.feedbackNps.trip({ tripRef: scope.tripRef });
52
+ setSummary(response.data);
53
+ formIdRef.current = response.data.configured ? response.data.formId : void 0;
54
+ setLoaded(true);
55
+ setLastFetchFailed(false);
56
+ setSyncedAt(response.meta.serverTime);
57
+ } else {
58
+ const response = await client$1.feedbackNps.agency({});
59
+ setDefinitions(response.data.definitions);
60
+ setLoaded(true);
61
+ setLastFetchFailed(false);
62
+ setSyncedAt(response.meta.serverTime);
63
+ }
64
+ } catch {
65
+ setLastFetchFailed(true);
66
+ }
67
+ }, [client$1, scope.kind, scope.kind === "trip" ? scope.tripRef : scope.agencyRef]);
68
+ react.useEffect(() => {
69
+ void refresh();
70
+ }, [refresh]);
71
+ const dispatchMutation = chunkEM7JV3D7_cjs.useOfflineMutation({
72
+ tripRef: scope.kind === "trip" ? scope.tripRef : "",
73
+ enqueue: (engine, input) => {
74
+ const formId = formIdRef.current;
75
+ if (formId === void 0 || scope.kind !== "trip") {
76
+ throw new Error("useFeedbackNps: cannot dispatch before a feedback form is resolved");
77
+ }
78
+ return engine.enqueue({
79
+ tripRef: scope.tripRef,
80
+ method: client.SyncOpMethod.Post,
81
+ path: `/api/v1/trips/${scope.tripRef}/forms/${formId}/dispatch`,
82
+ // Hardcoded literal, not imported: `OperationId` is not exported
83
+ // from `kaafil-js/client`'s public surface — same convention as
84
+ // `useRooming.ts`'s own `'assignRoomingBed' as never`. Verified
85
+ // against `kaafil-js/src/generated/security.ts`
86
+ // (`OPERATION_SECURITY.dispatchForm`) this session.
87
+ operationId: "dispatchForm",
88
+ body: input ?? {}
89
+ });
90
+ }
91
+ });
92
+ const dispatchMutate = dispatchMutation.mutate;
93
+ const dispatch = react.useCallback(
94
+ async (input) => {
95
+ const op = await dispatchMutate(input ?? {});
96
+ void refresh();
97
+ return op;
98
+ },
99
+ [dispatchMutate, refresh]
100
+ );
101
+ return {
102
+ kind: scope.kind,
103
+ summary,
104
+ definitions,
105
+ loaded,
106
+ lastFetchFailed,
107
+ syncedAt,
108
+ refresh,
109
+ dispatch,
110
+ dispatchStatus: dispatchMutation.status,
111
+ dispatchOp: dispatchMutation.op
112
+ };
113
+ }
114
+ function useJourney(tripRef) {
115
+ const client = chunkEM7JV3D7_cjs.useKaafilClient();
116
+ const persona = chunkEM7JV3D7_cjs.usePersona();
117
+ const { rows } = chunkEM7JV3D7_cjs.useCapabilityRows(tripRef);
118
+ const [read, setRead] = react.useState(void 0);
119
+ const [liveRows, setLiveRows] = react.useState(void 0);
120
+ react.useEffect(() => {
121
+ if (persona === "share") {
122
+ if (chunkEM7JV3D7_cjs.isDevelopment()) {
123
+ throw new Error(
124
+ "useJourney() was called from a share session \u2014 it is manager/agencyAdmin only (08-core-hooks.md \xA73.2)."
125
+ );
126
+ }
127
+ return;
128
+ }
129
+ let cancelled = false;
130
+ void client.journey.get({ tripRef }).then((response) => {
131
+ if (!cancelled) {
132
+ setRead(response);
133
+ }
134
+ });
135
+ return () => {
136
+ cancelled = true;
137
+ };
138
+ }, [client, persona, tripRef]);
139
+ const refreshCapabilities = react.useCallback(async () => {
140
+ const response = await client.journey.capabilities({ tripRef, live: true });
141
+ setLiveRows(response);
142
+ }, [client, tripRef]);
143
+ const effectiveRows = liveRows ?? rows;
144
+ const capabilities = /* @__PURE__ */ new Map();
145
+ for (const row of effectiveRows) {
146
+ capabilities.set(row.capability, chunkEM7JV3D7_cjs.deriveCapabilityTriple(row));
147
+ }
148
+ return {
149
+ read,
150
+ capabilities,
151
+ refreshCapabilities,
152
+ triggers: {
153
+ list: (options) => client.journey.triggers.list(options),
154
+ patch: (options) => client.journey.triggers.patch(options)
155
+ }
156
+ };
157
+ }
158
+
159
+ // src/core/hooks/useResolvedSetting.ts
160
+ function useResolvedSetting(key) {
161
+ const config = chunkEM7JV3D7_cjs.useRequiredContext(chunkEM7JV3D7_cjs.ConfigContext, "useResolvedSetting", "ConfigShell");
162
+ return config.resolveSetting(key);
163
+ }
164
+ function useSnapshotEntity(tripRef, listName, id) {
165
+ const engine = react.useContext(chunkEM7JV3D7_cjs.OfflineEngineContext);
166
+ const { rows } = chunkLL243STJ_cjs.useSnapshotList(tripRef, listName);
167
+ const row = rows.find((candidate) => candidate.id === id);
168
+ const syncedAt = engine === null ? void 0 : engine.snapshot.syncedAt(tripRef, listName, id);
169
+ return { row, syncedAt };
170
+ }
171
+
172
+ // src/core/hooks/useStaleness.ts
173
+ function useStaleness(tripRef, listName) {
174
+ const { syncedAt } = chunkLL243STJ_cjs.useSnapshotList(tripRef, listName);
175
+ const { now } = chunkPTQ2CJKE_cjs.useServerTime();
176
+ const thresholdSeconds = useResolvedSetting("stale.thresholdSeconds.default");
177
+ if (syncedAt === void 0) {
178
+ return { syncedAt: void 0, ageSeconds: void 0, isStale: false };
179
+ }
180
+ let ageSeconds;
181
+ try {
182
+ ageSeconds = (Date.parse(now()) - Date.parse(syncedAt)) / 1e3;
183
+ } catch {
184
+ ageSeconds = void 0;
185
+ }
186
+ const isStale = ageSeconds !== void 0 && thresholdSeconds !== void 0 && ageSeconds > thresholdSeconds;
187
+ return { syncedAt, ageSeconds, isStale };
188
+ }
189
+ var WALK_INS_PAGE_SIZE = 25;
190
+ var useTreksInternal = chunkLL243STJ_cjs.createDomainHook("treks", (tripRef) => {
191
+ const client$1 = chunkEM7JV3D7_cjs.useKaafilClient();
192
+ const [boardData, setBoardData] = react.useState(void 0);
193
+ const [boardLoaded, setBoardLoaded] = react.useState(false);
194
+ const [boardFetchFailed, setBoardFetchFailed] = react.useState(false);
195
+ const [boardFetchedAt, setBoardFetchedAt] = react.useState(void 0);
196
+ const refreshBoard = react.useCallback(async () => {
197
+ try {
198
+ const response = await client$1.treks.board({ trekRef: tripRef });
199
+ setBoardData(response);
200
+ setBoardLoaded(true);
201
+ setBoardFetchFailed(false);
202
+ setBoardFetchedAt(response.meta.serverTime);
203
+ } catch {
204
+ setBoardFetchFailed(true);
205
+ }
206
+ }, [client$1, tripRef]);
207
+ react.useEffect(() => {
208
+ void refreshBoard();
209
+ }, [refreshBoard]);
210
+ const [walkInRows, setWalkInRows] = react.useState([]);
211
+ const [walkInsLoaded, setWalkInsLoaded] = react.useState(false);
212
+ const [walkInsFetchFailed, setWalkInsFetchFailed] = react.useState(false);
213
+ const [walkInsFetchedAt, setWalkInsFetchedAt] = react.useState(void 0);
214
+ const [walkInsCursor, setWalkInsCursor] = react.useState(void 0);
215
+ const [walkInsHasNext, setWalkInsHasNext] = react.useState(false);
216
+ const refreshWalkIns = react.useCallback(async () => {
217
+ try {
218
+ const page = await client$1.treks.walkIns.listPage({
219
+ trekRef: tripRef,
220
+ limit: WALK_INS_PAGE_SIZE
221
+ });
222
+ setWalkInRows(page);
223
+ setWalkInsLoaded(true);
224
+ setWalkInsFetchFailed(false);
225
+ setWalkInsFetchedAt(page.meta.serverTime);
226
+ setWalkInsCursor(page.meta.page.cursor ?? void 0);
227
+ setWalkInsHasNext(page.meta.page.hasNext);
228
+ } catch {
229
+ setWalkInsFetchFailed(true);
230
+ }
231
+ }, [client$1, tripRef]);
232
+ const loadMoreWalkIns = react.useCallback(async () => {
233
+ if (walkInsCursor === void 0 || !walkInsHasNext) {
234
+ return;
235
+ }
236
+ try {
237
+ const page = await client$1.treks.walkIns.listPage({
238
+ trekRef: tripRef,
239
+ cursor: walkInsCursor,
240
+ limit: WALK_INS_PAGE_SIZE
241
+ });
242
+ setWalkInRows((existing) => [...existing, ...page]);
243
+ setWalkInsFetchedAt(page.meta.serverTime);
244
+ setWalkInsCursor(page.meta.page.cursor ?? void 0);
245
+ setWalkInsHasNext(page.meta.page.hasNext);
246
+ } catch {
247
+ setWalkInsFetchFailed(true);
248
+ }
249
+ }, [client$1, tripRef, walkInsCursor, walkInsHasNext]);
250
+ react.useEffect(() => {
251
+ void refreshWalkIns();
252
+ }, [refreshWalkIns]);
253
+ const [metaData, setMetaData] = react.useState(void 0);
254
+ const [metaLoaded, setMetaLoaded] = react.useState(false);
255
+ const [metaFetchFailed, setMetaFetchFailed] = react.useState(false);
256
+ const refreshMeta = react.useCallback(async () => {
257
+ try {
258
+ const response = await client$1.treks.walkIns.meta({ trekRef: tripRef });
259
+ setMetaData(response);
260
+ setMetaLoaded(true);
261
+ setMetaFetchFailed(false);
262
+ } catch {
263
+ setMetaFetchFailed(true);
264
+ }
265
+ }, [client$1, tripRef]);
266
+ react.useEffect(() => {
267
+ void refreshMeta();
268
+ }, [refreshMeta]);
269
+ const createWalkInMutation = chunkEM7JV3D7_cjs.useOfflineMutation({
270
+ tripRef,
271
+ enqueue: (engine, input) => engine.enqueue({
272
+ tripRef,
273
+ method: client.SyncOpMethod.Post,
274
+ path: `/api/v1/treks/${tripRef}/walk-ins`,
275
+ // `OperationId` is not exported from `kaafil-js/client`'s public
276
+ // surface — same documented gap `useFloat.ts`/`useRooming.ts` cast
277
+ // around for their own literal `operationId`s.
278
+ operationId: "createTrekWalkIn",
279
+ body: input
280
+ })
281
+ });
282
+ const postponeMutation = chunkEM7JV3D7_cjs.useOfflineMutation({
283
+ tripRef,
284
+ enqueue: (engine, input) => engine.enqueue({
285
+ tripRef,
286
+ method: client.SyncOpMethod.Post,
287
+ path: `/api/v1/treks/${tripRef}/postpone`,
288
+ operationId: "postponeTrek",
289
+ body: input
290
+ })
291
+ });
292
+ const reconcileMutation = chunkEM7JV3D7_cjs.useOfflineMutation({
293
+ tripRef,
294
+ enqueue: (engine, { walkInId, input }) => engine.enqueue({
295
+ tripRef,
296
+ method: client.SyncOpMethod.Post,
297
+ path: `/api/v1/treks/${tripRef}/walk-ins/${walkInId}/reconcile`,
298
+ operationId: "reconcileTrekWalkIn",
299
+ body: input
300
+ })
301
+ });
302
+ const createWalkInMutate = createWalkInMutation.mutate;
303
+ const createWalkIn = react.useCallback(
304
+ async (input) => {
305
+ const op = await createWalkInMutate(input);
306
+ void refreshBoard();
307
+ void refreshWalkIns();
308
+ return op;
309
+ },
310
+ [createWalkInMutate, refreshBoard, refreshWalkIns]
311
+ );
312
+ const postponeMutate = postponeMutation.mutate;
313
+ const postpone = react.useCallback(
314
+ async (input) => {
315
+ const op = await postponeMutate(input);
316
+ void refreshBoard();
317
+ return op;
318
+ },
319
+ [postponeMutate, refreshBoard]
320
+ );
321
+ const reconcileMutate = reconcileMutation.mutate;
322
+ const reconcileWalkIn = react.useCallback(
323
+ async (walkInId, input) => {
324
+ const op = await reconcileMutate({ walkInId, input });
325
+ void refreshWalkIns();
326
+ return op;
327
+ },
328
+ [reconcileMutate, refreshWalkIns]
329
+ );
330
+ return {
331
+ board: {
332
+ data: boardData,
333
+ loaded: boardLoaded,
334
+ lastFetchFailed: boardFetchFailed,
335
+ fetchedAt: boardFetchedAt,
336
+ refresh: refreshBoard
337
+ },
338
+ walkIns: {
339
+ rows: walkInRows,
340
+ loaded: walkInsLoaded,
341
+ lastFetchFailed: walkInsFetchFailed,
342
+ fetchedAt: walkInsFetchedAt,
343
+ hasMore: walkInsHasNext,
344
+ refresh: refreshWalkIns,
345
+ loadMore: loadMoreWalkIns
346
+ },
347
+ walkInMeta: {
348
+ data: metaData,
349
+ loaded: metaLoaded,
350
+ lastFetchFailed: metaFetchFailed,
351
+ refresh: refreshMeta
352
+ },
353
+ createWalkIn,
354
+ postpone,
355
+ reconcileWalkIn
356
+ };
357
+ });
358
+ function useTreks(tripRef) {
359
+ return useTreksInternal(tripRef);
360
+ }
361
+ var ThemeAttributesContext = react.createContext(null);
362
+ var FAMILY_DEFAULT_FRAME = {
363
+ admin: "desk",
364
+ manager: "field",
365
+ traveller: "document"
366
+ };
367
+ var DESK_MINIMUM_CONTAINER_WIDTH_PX = 640;
368
+ function ShadowIsolationBoundary({
369
+ className,
370
+ children
371
+ }) {
372
+ const hostRef = react.useRef(null);
373
+ const [shadowContainer, setShadowContainer] = react.useState(null);
374
+ react.useEffect(() => {
375
+ const host = hostRef.current;
376
+ if (host === null) {
377
+ return;
378
+ }
379
+ const shadow = host.shadowRoot ?? host.attachShadow({ mode: "open" });
380
+ let container = shadow.querySelector("div[data-kf-shadow-content]");
381
+ if (container === null) {
382
+ container = document.createElement("div");
383
+ container.setAttribute("data-kf-shadow-content", "");
384
+ shadow.appendChild(container);
385
+ }
386
+ setShadowContainer(container);
387
+ }, []);
388
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: hostRef, className, "data-kf-isolation": "shadow", children: shadowContainer !== null ? reactDom.createPortal(children, shadowContainer) : null });
389
+ }
390
+ function useDeskMinimumWidthWarning(rootRef, frame) {
391
+ react.useEffect(() => {
392
+ if (frame !== "desk" || !chunkEM7JV3D7_cjs.isDevelopment() || typeof ResizeObserver === "undefined") {
393
+ return;
394
+ }
395
+ const node = rootRef.current;
396
+ if (node === null) {
397
+ return;
398
+ }
399
+ let warned = false;
400
+ const observer = new ResizeObserver((entries) => {
401
+ const entry = entries[0];
402
+ if (entry === void 0 || warned) {
403
+ return;
404
+ }
405
+ if (entry.contentRect.width < DESK_MINIMUM_CONTAINER_WIDTH_PX) {
406
+ warned = true;
407
+ console.warn(
408
+ `kaafil-react-uikit: the 'desk' frame's .kf-root is narrower than the stated minimum container width (05-theming-and-branding.md \xA74.4). AppShell never auto-swaps frames \u2014 mount the manager family, or pass frame="field" explicitly, for this container.`
409
+ );
410
+ }
411
+ });
412
+ observer.observe(node);
413
+ return () => observer.disconnect();
414
+ }, [rootRef, frame]);
415
+ }
416
+ function useUnfilledConnectivitySlotWarning(frame, connectivitySlot) {
417
+ react.useEffect(() => {
418
+ if (frame === "field" && connectivitySlot === void 0 && chunkEM7JV3D7_cjs.isDevelopment()) {
419
+ console.warn(
420
+ `kaafil-react-uikit: AppShell's "field" frame has no connectivitySlot filled \u2014 the permanently-visible connectivity/sync region this frame reserves is empty (01-app-shell.md, briefing \xA727.2).`
421
+ );
422
+ }
423
+ }, [frame, connectivitySlot]);
424
+ }
425
+ function AppShell({
426
+ frame,
427
+ family,
428
+ isolation = "scoped",
429
+ navSlot,
430
+ actionBarSlot,
431
+ connectivitySlot,
432
+ children,
433
+ style
434
+ }) {
435
+ const themeAttributes = react.useContext(ThemeAttributesContext);
436
+ const rootRef = react.useRef(null);
437
+ const resolvedFrame = frame ?? (family !== void 0 ? FAMILY_DEFAULT_FRAME[family] : "document");
438
+ useDeskMinimumWidthWarning(rootRef, resolvedFrame);
439
+ useUnfilledConnectivitySlotWarning(resolvedFrame, connectivitySlot);
440
+ const dataAttributes = {
441
+ "data-kf-frame": resolvedFrame
442
+ };
443
+ if (family !== void 0) {
444
+ dataAttributes["data-kf-family"] = family;
445
+ }
446
+ if (themeAttributes !== null) {
447
+ dataAttributes["data-kf-theme"] = themeAttributes.theme;
448
+ if (themeAttributes.density !== void 0) {
449
+ dataAttributes["data-kf-density"] = themeAttributes.density;
450
+ }
451
+ }
452
+ const content = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
453
+ resolvedFrame === "desk" && navSlot !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "kf-app-shell__nav", children: navSlot }) : null,
454
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "kf-app-shell__content", children }),
455
+ resolvedFrame === "field" && actionBarSlot !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "kf-app-shell__action-bar", children: actionBarSlot }) : null,
456
+ resolvedFrame === "field" && connectivitySlot !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "kf-app-shell__connectivity", children: connectivitySlot }) : null,
457
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "kf-app-shell__live-region", role: "status", "aria-live": "polite" })
458
+ ] });
459
+ if (isolation === "shadow") {
460
+ return /* @__PURE__ */ jsxRuntime.jsx(
461
+ "div",
462
+ {
463
+ ref: rootRef,
464
+ className: "kf-root",
465
+ "data-kf-isolation": "shadow",
466
+ ...dataAttributes,
467
+ style: chunkEM7JV3D7_cjs.tokenStyle(style),
468
+ children: /* @__PURE__ */ jsxRuntime.jsx(ShadowIsolationBoundary, { className: "kf-app-shell__shadow-host", children: content })
469
+ }
470
+ );
471
+ }
472
+ return /* @__PURE__ */ jsxRuntime.jsx(
473
+ "div",
474
+ {
475
+ ref: rootRef,
476
+ className: "kf-root",
477
+ "data-kf-isolation": "scoped",
478
+ ...dataAttributes,
479
+ style: chunkEM7JV3D7_cjs.tokenStyle(style),
480
+ children: content
481
+ }
482
+ );
483
+ }
484
+ function ConfigShell({ seedConfig = {}, children }) {
485
+ const value = react.useMemo(
486
+ () => ({
487
+ resolveSetting(key) {
488
+ const agencyValue = seedConfig.agency?.[key];
489
+ if (agencyValue !== void 0) {
490
+ return agencyValue;
491
+ }
492
+ const tenantValue = seedConfig.tenant?.[key];
493
+ return tenantValue === void 0 ? void 0 : tenantValue;
494
+ }
495
+ }),
496
+ [seedConfig.agency, seedConfig.tenant]
497
+ );
498
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkEM7JV3D7_cjs.ConfigContext.Provider, { value, children });
499
+ }
500
+ function classifyForFallback(error) {
501
+ const classification = chunkLL243STJ_cjs.classifyError(error);
502
+ if (classification.code === "RESOURCE_NOT_FOUND") {
503
+ return { classification: "isolation", code: classification.code };
504
+ }
505
+ if (classification.path === "parked" || classification.unsatisfiableScheme) {
506
+ return { classification: "parked", code: classification.code };
507
+ }
508
+ return { classification: "retryable", code: classification.code };
509
+ }
510
+ var FALLBACK_STYLE = {
511
+ fontFamily: "system-ui, sans-serif",
512
+ padding: "1.5rem",
513
+ border: "1px solid #999",
514
+ borderRadius: "4px",
515
+ color: "#1a1a1a",
516
+ background: "#fff"
517
+ };
518
+ function DefaultFallback({
519
+ ctx,
520
+ onRetry
521
+ }) {
522
+ const role = ctx.classification === "retryable" ? "status" : "alert";
523
+ const ariaLive = ctx.classification === "retryable" ? "polite" : "assertive";
524
+ const message = ctx.classification === "isolation" ? "Not found." : ctx.classification === "parked" ? "This action can't be completed right now." : "Something went wrong.";
525
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: FALLBACK_STYLE, role, "aria-live": ariaLive, children: [
526
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0 }, children: message }),
527
+ ctx.classification === "retryable" ? /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", onClick: onRetry, style: { marginTop: "0.75rem" }, children: "Try again" }) : null
528
+ ] });
529
+ }
530
+ var ErrorShell = class extends react.Component {
531
+ state = { caught: null, retryKey: 0 };
532
+ static getDerivedStateFromError(error) {
533
+ return { caught: { error } };
534
+ }
535
+ handleRetry = () => {
536
+ this.setState((current) => ({ caught: null, retryKey: current.retryKey + 1 }));
537
+ };
538
+ render() {
539
+ if (this.state.caught !== null) {
540
+ const ctx = classifyForFallback(this.state.caught.error);
541
+ if (this.props.fallbackSlot !== void 0) {
542
+ return this.props.fallbackSlot(ctx);
543
+ }
544
+ return /* @__PURE__ */ jsxRuntime.jsx(DefaultFallback, { ctx, onRetry: this.handleRetry });
545
+ }
546
+ return /* @__PURE__ */ jsxRuntime.jsx(react.Fragment, { children: this.props.children }, this.state.retryKey);
547
+ }
548
+ };
549
+ var SessionExpiryBridgeContext = react.createContext(void 0);
550
+ function OfflineShell({
551
+ storage,
552
+ blob,
553
+ conflictResolver,
554
+ readEntity,
555
+ scope,
556
+ children
557
+ }) {
558
+ const client = react.useContext(chunkEM7JV3D7_cjs.KaafilClientContext);
559
+ const persona = chunkEM7JV3D7_cjs.usePersona();
560
+ const session = chunkEM7JV3D7_cjs.useSession();
561
+ const reportExpired = react.useContext(SessionExpiryBridgeContext);
562
+ const [engine, setEngine] = react.useState(null);
563
+ const engineRef = react.useRef(null);
564
+ const derivedScope = scope ?? `${persona}:${session.agencyRef ?? "share"}`;
565
+ react.useEffect(() => {
566
+ if (session.status !== "authenticated" || client === null) {
567
+ return;
568
+ }
569
+ const newEngine = client.openOffline({
570
+ storage,
571
+ scope: derivedScope,
572
+ ...readEntity !== void 0 ? { readEntity } : {},
573
+ ...conflictResolver !== void 0 ? { conflictResolver } : {},
574
+ ...blob !== void 0 ? { blob } : {}
575
+ // GAP flagged in this phase's report: a share session's local
576
+ // `expiresAt` enforcement (`OpenOfflineOptions.share`,
577
+ // `07-offline-and-sync.md §8`) needs an `expiresAt` this shell has no
578
+ // source for yet — it is not on `useSession()`'s derived shape and no
579
+ // prop carries it. Omitted here rather than guessed; a share engine
580
+ // opens without the local expiry/grace/purge enforcement until that
581
+ // value has a wire source.
582
+ });
583
+ engineRef.current = newEngine;
584
+ setEngine(newEngine);
585
+ const unsubscribeSessionExpired = persona !== "share" ? newEngine.events.on("session.expired", () => reportExpired?.("session")) : void 0;
586
+ const unsubscribeShareExpired = persona === "share" ? newEngine.events.on("share.expired", () => reportExpired?.("share")) : void 0;
587
+ const unsubscribeShareRevoked = persona === "share" ? newEngine.events.on("share.revoked", () => reportExpired?.("share")) : void 0;
588
+ return () => {
589
+ unsubscribeSessionExpired?.();
590
+ unsubscribeShareExpired?.();
591
+ unsubscribeShareRevoked?.();
592
+ newEngine.close();
593
+ if (engineRef.current === newEngine) {
594
+ engineRef.current = null;
595
+ }
596
+ };
597
+ }, [client, derivedScope, session.status, persona, reportExpired]);
598
+ return /* @__PURE__ */ jsxRuntime.jsx(chunkEM7JV3D7_cjs.OfflineEngineContext.Provider, { value: engine, children });
599
+ }
600
+
601
+ // src/core/shells/internal/jwtKind.ts
602
+ function base64UrlDecode(segment) {
603
+ const padded = segment.replace(/-/g, "+").replace(/_/g, "/");
604
+ const withPadding = padded + "=".repeat((4 - padded.length % 4) % 4);
605
+ return atob(withPadding);
606
+ }
607
+ function decodeManagerOrAgencyAdminKind(accessToken) {
608
+ const segments = accessToken.split(".");
609
+ const payloadSegment = segments[1];
610
+ if (segments.length !== 3 || payloadSegment === void 0) {
611
+ throw new Error(
612
+ 'SessionShell could not parse "accessToken" as a JWT \u2014 it does not have the three dot-separated segments every manager/agencyAdmin session token has.'
613
+ );
614
+ }
615
+ let claim;
616
+ try {
617
+ claim = JSON.parse(base64UrlDecode(payloadSegment));
618
+ } catch {
619
+ throw new Error(
620
+ `SessionShell could not decode "accessToken"'s payload segment as JSON \u2014 the value handed to <KaafilUIKitProvider accessToken> is not a well-formed JWT.`
621
+ );
622
+ }
623
+ const kind = claim.kind;
624
+ if (kind === "agencyAdmin") {
625
+ return "agencyAdmin";
626
+ }
627
+ if (kind === "managerSession" || kind === "manager") {
628
+ return "managerSession";
629
+ }
630
+ throw new Error(
631
+ `SessionShell read an unrecognised "kind" claim ("${String(kind)}") off "accessToken" \u2014 expected the manager or agencyAdmin session JWT shape (00-decisions.md U-003).`
632
+ );
633
+ }
634
+ async function resolveCredential(props) {
635
+ if (props.credentialResolver !== void 0) {
636
+ const resolved = await props.credentialResolver();
637
+ if ("shareToken" in resolved) {
638
+ return { kind: "share", shareToken: resolved.shareToken };
639
+ }
640
+ const kind2 = decodeManagerOrAgencyAdminKind(resolved.accessToken) === "agencyAdmin" ? "agencyAdmin" : "manager";
641
+ return { kind: kind2, ...resolved };
642
+ }
643
+ if (props.shareToken !== void 0) {
644
+ return { kind: "share", shareToken: props.shareToken };
645
+ }
646
+ const kind = decodeManagerOrAgencyAdminKind(props.accessToken) === "agencyAdmin" ? "agencyAdmin" : "manager";
647
+ return {
648
+ kind,
649
+ accessToken: props.accessToken,
650
+ refreshToken: props.refreshToken,
651
+ agencyRef: props.agencyRef
652
+ };
653
+ }
654
+ function SessionShell(props) {
655
+ const { environment = "live", onRefresh, onSessionExpired, children } = props;
656
+ const [state, setState] = react.useState(null);
657
+ const expiredCallbackFiredRef = react.useRef(false);
658
+ const currentPersonaRef = react.useRef("manager");
659
+ const reportExpired = react.useCallback(() => {
660
+ if (expiredCallbackFiredRef.current) {
661
+ return;
662
+ }
663
+ expiredCallbackFiredRef.current = true;
664
+ onSessionExpired?.(currentPersonaRef.current);
665
+ setState(
666
+ (current) => current === null ? current : { ...current, session: { ...current.session, status: "expired" } }
667
+ );
668
+ }, [onSessionExpired]);
669
+ const accessTokenDep = "accessToken" in props ? props.accessToken : void 0;
670
+ const refreshTokenDep = "refreshToken" in props ? props.refreshToken : void 0;
671
+ const agencyRefDep = "agencyRef" in props ? props.agencyRef : void 0;
672
+ const shareTokenDep = "shareToken" in props ? props.shareToken : void 0;
673
+ react.useEffect(() => {
674
+ let cancelled = false;
675
+ const client$1 = new client.KaafilClient({ environment });
676
+ expiredCallbackFiredRef.current = false;
677
+ async function open() {
678
+ const credential = await resolveCredential(props);
679
+ if (cancelled) {
680
+ return;
681
+ }
682
+ currentPersonaRef.current = credential.kind;
683
+ if (credential.kind === "share") {
684
+ client$1.share.open({ token: credential.shareToken });
685
+ } else if (credential.kind === "agencyAdmin") {
686
+ client$1.admin.open({
687
+ accessToken: credential.accessToken,
688
+ refreshToken: credential.refreshToken,
689
+ agencyRef: credential.agencyRef,
690
+ ...onRefresh !== void 0 ? { onRefresh } : {}
691
+ });
692
+ } else {
693
+ client$1.session.open({
694
+ accessToken: credential.accessToken,
695
+ refreshToken: credential.refreshToken,
696
+ agencyRef: credential.agencyRef,
697
+ ...onRefresh !== void 0 ? { onRefresh } : {}
698
+ });
699
+ }
700
+ setState({
701
+ client: client$1,
702
+ session: {
703
+ status: "authenticated",
704
+ persona: credential.kind,
705
+ agencyRef: credential.agencyRef,
706
+ environment
707
+ }
708
+ });
709
+ }
710
+ void open();
711
+ return () => {
712
+ cancelled = true;
713
+ client$1.close();
714
+ };
715
+ }, [environment, accessTokenDep, refreshTokenDep, agencyRefDep, shareTokenDep]);
716
+ if (state === null) {
717
+ return /* @__PURE__ */ jsxRuntime.jsx(SessionExpiryBridgeContext.Provider, { value: reportExpired, children: /* @__PURE__ */ jsxRuntime.jsx(
718
+ chunkEM7JV3D7_cjs.SessionContext.Provider,
719
+ {
720
+ value: { status: "opening", persona: "manager", agencyRef: void 0, environment },
721
+ children
722
+ }
723
+ ) });
724
+ }
725
+ return /* @__PURE__ */ jsxRuntime.jsx(SessionExpiryBridgeContext.Provider, { value: reportExpired, children: /* @__PURE__ */ jsxRuntime.jsx(chunkEM7JV3D7_cjs.KaafilClientContext.Provider, { value: state.client, children: /* @__PURE__ */ jsxRuntime.jsx(chunkEM7JV3D7_cjs.SessionContext.Provider, { value: state.session, children }) }) });
726
+ }
727
+ function emit(onEvent, event) {
728
+ if (onEvent === void 0) {
729
+ return;
730
+ }
731
+ try {
732
+ onEvent(event);
733
+ } catch {
734
+ }
735
+ }
736
+ function TelemetryShell({ onEvent, children }) {
737
+ const session = chunkEM7JV3D7_cjs.useSession();
738
+ const serverTime = chunkPTQ2CJKE_cjs.useServerTime();
739
+ const previousStatusRef = react.useRef(void 0);
740
+ react.useEffect(() => {
741
+ const previousStatus = previousStatusRef.current;
742
+ if (serverTime.sinceLastSync !== void 0) {
743
+ if (session.status === "authenticated" && previousStatus !== "authenticated") {
744
+ emit(onEvent, {
745
+ type: "session.opened",
746
+ timestamp: serverTime.now(),
747
+ persona: session.persona
748
+ });
749
+ }
750
+ if (session.status === "expired" && previousStatus !== "expired") {
751
+ emit(onEvent, {
752
+ type: "session.expired",
753
+ timestamp: serverTime.now(),
754
+ persona: session.persona
755
+ });
756
+ }
757
+ }
758
+ previousStatusRef.current = session.status;
759
+ }, [session.status, serverTime.sinceLastSync]);
760
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
761
+ }
762
+ function resolveSystemTheme() {
763
+ if (typeof window === "undefined" || typeof window.matchMedia !== "function") {
764
+ return "light";
765
+ }
766
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
767
+ }
768
+ function ThemeShell({ theme = "system", density, children }) {
769
+ const [systemTheme, setSystemTheme] = react.useState(
770
+ () => theme === "system" ? resolveSystemTheme() : theme
771
+ );
772
+ react.useEffect(() => {
773
+ if (theme !== "system" || typeof window === "undefined" || typeof window.matchMedia !== "function") {
774
+ return;
775
+ }
776
+ const query = window.matchMedia("(prefers-color-scheme: dark)");
777
+ const listener = (event) => {
778
+ setSystemTheme(event.matches ? "dark" : "light");
779
+ };
780
+ query.addEventListener("change", listener);
781
+ return () => query.removeEventListener("change", listener);
782
+ }, [theme]);
783
+ const resolvedTheme = theme === "system" ? systemTheme : theme;
784
+ const value = react.useMemo(() => ({ theme: resolvedTheme, density }), [resolvedTheme, density]);
785
+ return /* @__PURE__ */ jsxRuntime.jsx(ThemeAttributesContext.Provider, { value, children });
786
+ }
787
+ var DefaultCapabilityViewsContext = react.createContext({});
788
+ function useDefaultCapabilityViews() {
789
+ return react.useContext(DefaultCapabilityViewsContext);
790
+ }
791
+ function KaafilUIKitProvider(props) {
792
+ const {
793
+ environment,
794
+ onSessionExpired,
795
+ density,
796
+ theme,
797
+ brand,
798
+ locale,
799
+ isolation,
800
+ onEvent,
801
+ storage,
802
+ blob,
803
+ conflictResolver,
804
+ readEntity,
805
+ offlineScope,
806
+ seedConfig,
807
+ defaultCapabilityViews,
808
+ children,
809
+ ...credential
810
+ } = props;
811
+ const inner = /* @__PURE__ */ jsxRuntime.jsx(DefaultCapabilityViewsContext.Provider, { value: defaultCapabilityViews ?? {}, children: /* @__PURE__ */ jsxRuntime.jsx(ConfigShell, { seedConfig, children: /* @__PURE__ */ jsxRuntime.jsx(
812
+ chunkVHTSTUCJ_cjs.BrandShell,
813
+ {
814
+ appName: brand?.appName,
815
+ logo: brand?.logo,
816
+ logoMark: brand?.logoMark,
817
+ favicon: brand?.favicon,
818
+ headStrategy: brand?.headStrategy,
819
+ children: /* @__PURE__ */ jsxRuntime.jsx(TelemetryShell, { onEvent, children })
820
+ }
821
+ ) }) });
822
+ return /* @__PURE__ */ jsxRuntime.jsx(ErrorShell, { children: /* @__PURE__ */ jsxRuntime.jsx(ThemeShell, { theme, density, children: /* @__PURE__ */ jsxRuntime.jsx(chunkEM7JV3D7_cjs.I18nShell, { locale, children: /* @__PURE__ */ jsxRuntime.jsx(AppShell, { isolation, children: /* @__PURE__ */ jsxRuntime.jsx(
823
+ SessionShell,
824
+ {
825
+ ...credential,
826
+ environment,
827
+ onSessionExpired,
828
+ children: storage !== void 0 ? /* @__PURE__ */ jsxRuntime.jsx(
829
+ OfflineShell,
830
+ {
831
+ storage,
832
+ blob,
833
+ conflictResolver,
834
+ readEntity,
835
+ scope: offlineScope,
836
+ children: inner
837
+ }
838
+ ) : inner
839
+ }
840
+ ) }) }) }) });
841
+ }
842
+ var HAZARD_LABELS = {
843
+ "global-box-sizing-reset": "A global box-sizing reset escapes this widget's scope.",
844
+ "global-button-input-unset": "A global button/input unset rule is active.",
845
+ "tailwind-preflight-after-ours": "A Tailwind preflight is loaded after this widget's CSS.",
846
+ "global-margin-padding-reset": "A global margin/padding reset is active.",
847
+ "conflicting-layer-order": "A conflicting @layer declaration order was detected.",
848
+ "global-img-max-width": "A global img max-width rule fights this widget's media components.",
849
+ "host-css-reset-library": "A host-level CSS reset library (e.g. normalize.css) loads after this widget's CSS.",
850
+ "global-focus-outline-removed": "A global :focus outline removal defeats this widget's focus-visible ring."
851
+ };
852
+ function detectHazards() {
853
+ if (typeof document === "undefined") {
854
+ return [];
855
+ }
856
+ const probe = document.createElement("div");
857
+ probe.setAttribute("data-kf-host-css-probe", "");
858
+ probe.style.position = "absolute";
859
+ probe.style.visibility = "hidden";
860
+ probe.style.pointerEvents = "none";
861
+ document.body.appendChild(probe);
862
+ const button = document.createElement("button");
863
+ probe.appendChild(button);
864
+ const img = document.createElement("img");
865
+ probe.appendChild(img);
866
+ const buttonStyle = getComputedStyle(button);
867
+ const imgStyle = getComputedStyle(img);
868
+ const probeStyle = getComputedStyle(probe);
869
+ const hazards = [];
870
+ if (probeStyle.boxSizing !== "border-box" && probeStyle.boxSizing !== "content-box") {
871
+ hazards.push("global-box-sizing-reset");
872
+ }
873
+ if (buttonStyle.appearance === "none" && buttonStyle.border === "0px none") {
874
+ hazards.push("global-button-input-unset");
875
+ }
876
+ if (probeStyle.margin !== "" && probeStyle.margin === "0px" && probeStyle.padding === "0px") {
877
+ hazards.push("global-margin-padding-reset");
878
+ }
879
+ if (imgStyle.maxWidth === "100%") {
880
+ hazards.push("global-img-max-width");
881
+ }
882
+ if (buttonStyle.outlineStyle === "none") {
883
+ hazards.push("global-focus-outline-removed");
884
+ }
885
+ document.body.removeChild(probe);
886
+ return hazards;
887
+ }
888
+ function HostCssCompatibilityProbe({
889
+ style
890
+ } = {}) {
891
+ const chrome = chunkEM7JV3D7_cjs.useKaafilChrome();
892
+ const [hazards, setHazards] = react.useState(null);
893
+ react.useEffect(() => {
894
+ if (chunkEM7JV3D7_cjs.isDevelopment()) {
895
+ setHazards(detectHazards());
896
+ }
897
+ }, []);
898
+ if (!chunkEM7JV3D7_cjs.isDevelopment() || hazards === null) {
899
+ return null;
900
+ }
901
+ return /* @__PURE__ */ jsxRuntime.jsxs(
902
+ "div",
903
+ {
904
+ style: chunkEM7JV3D7_cjs.tokenStyle(style, {
905
+ border: "1px solid #999",
906
+ padding: "0.75rem",
907
+ borderRadius: "4px"
908
+ }),
909
+ children: [
910
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, fontWeight: 600 }, children: chrome.t("probe.hostCss.title") }),
911
+ hazards.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: "0.5rem 0 0" }, children: chrome.t("probe.hostCss.clean") }) : /* @__PURE__ */ jsxRuntime.jsx("ul", { style: { margin: "0.5rem 0 0" }, children: hazards.map((hazard) => /* @__PURE__ */ jsxRuntime.jsx("li", { children: HAZARD_LABELS[hazard] }, hazard)) }),
912
+ hazards.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs("p", { style: { margin: "0.5rem 0 0" }, children: [
913
+ "Recommended: pass ",
914
+ /* @__PURE__ */ jsxRuntime.jsx("code", { children: 'isolation="shadow"' }),
915
+ " to <KaafilUIKitProvider> (05-theming-and-branding.md \xA77, rung 2)."
916
+ ] }) : null
917
+ ]
918
+ }
919
+ );
920
+ }
921
+ function KaafilSessionProbe({
922
+ expectedEnvironment,
923
+ style
924
+ }) {
925
+ const session = chunkEM7JV3D7_cjs.useSession();
926
+ const chrome = chunkEM7JV3D7_cjs.useKaafilChrome();
927
+ if (session.status === "expired") {
928
+ return /* @__PURE__ */ jsxRuntime.jsx(
929
+ "div",
930
+ {
931
+ role: "status",
932
+ style: chunkEM7JV3D7_cjs.tokenStyle(style, {
933
+ border: "1px solid #c00",
934
+ padding: "0.75rem",
935
+ borderRadius: "4px"
936
+ }),
937
+ children: "Tokens invalid or already expired at mount \u2014 the values handed to <KaafilUIKitProvider> were rejected before a successful open (00-decisions.md U-014)."
938
+ }
939
+ );
940
+ }
941
+ if (expectedEnvironment !== void 0 && session.status === "authenticated" && session.environment !== expectedEnvironment) {
942
+ return /* @__PURE__ */ jsxRuntime.jsxs(
943
+ "div",
944
+ {
945
+ role: "status",
946
+ style: chunkEM7JV3D7_cjs.tokenStyle(style, {
947
+ border: "1px solid #c00",
948
+ padding: "0.75rem",
949
+ borderRadius: "4px"
950
+ }),
951
+ children: [
952
+ 'Wrong environment \u2014 expected "',
953
+ expectedEnvironment,
954
+ '" but the opened credential is "',
955
+ session.environment,
956
+ '"',
957
+ session.environment === "test" && expectedEnvironment === "live" ? " (test key on live)." : "."
958
+ ]
959
+ }
960
+ );
961
+ }
962
+ if (session.status === "opening") {
963
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "status", style: chunkEM7JV3D7_cjs.tokenStyle(style), children: chrome.t("chrome.loading") });
964
+ }
965
+ return /* @__PURE__ */ jsxRuntime.jsxs(
966
+ "div",
967
+ {
968
+ style: chunkEM7JV3D7_cjs.tokenStyle(style, {
969
+ border: "1px solid #0a0",
970
+ padding: "0.75rem",
971
+ borderRadius: "4px"
972
+ }),
973
+ children: [
974
+ /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0 }, children: chrome.t("probe.session.ok") }),
975
+ /* @__PURE__ */ jsxRuntime.jsxs("dl", { style: { margin: "0.5rem 0 0" }, children: [
976
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: chrome.t("probe.session.credentialKind") }),
977
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: session.persona }),
978
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: chrome.t("probe.session.environment") }),
979
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: session.environment }),
980
+ session.agencyRef !== void 0 ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
981
+ /* @__PURE__ */ jsxRuntime.jsx("dt", { children: chrome.t("probe.session.agency") }),
982
+ /* @__PURE__ */ jsxRuntime.jsx("dd", { children: session.agencyRef })
983
+ ] }) : null
984
+ ] })
985
+ ]
986
+ }
987
+ );
988
+ }
989
+
990
+ Object.defineProperty(exports, "useConflicts", {
991
+ enumerable: true,
992
+ get: function () { return chunkQHUDOVKW_cjs.useConflicts; }
993
+ });
994
+ Object.defineProperty(exports, "useManagerMe", {
995
+ enumerable: true,
996
+ get: function () { return chunkQHUDOVKW_cjs.useManagerMe; }
997
+ });
998
+ Object.defineProperty(exports, "useNotifications", {
999
+ enumerable: true,
1000
+ get: function () { return chunkQHUDOVKW_cjs.useNotifications; }
1001
+ });
1002
+ Object.defineProperty(exports, "CLOSEOUT_ACTION_TAB", {
1003
+ enumerable: true,
1004
+ get: function () { return chunkPJRZCOFF_cjs.CLOSEOUT_ACTION_TAB; }
1005
+ });
1006
+ Object.defineProperty(exports, "fromSearchParams", {
1007
+ enumerable: true,
1008
+ get: function () { return chunkPJRZCOFF_cjs.fromSearchParams; }
1009
+ });
1010
+ Object.defineProperty(exports, "isTripTabKey", {
1011
+ enumerable: true,
1012
+ get: function () { return chunkPJRZCOFF_cjs.isTripTabKey; }
1013
+ });
1014
+ Object.defineProperty(exports, "resolveBlockerDeepLink", {
1015
+ enumerable: true,
1016
+ get: function () { return chunkPJRZCOFF_cjs.resolveBlockerDeepLink; }
1017
+ });
1018
+ Object.defineProperty(exports, "toSearchParams", {
1019
+ enumerable: true,
1020
+ get: function () { return chunkPJRZCOFF_cjs.toSearchParams; }
1021
+ });
1022
+ Object.defineProperty(exports, "useAgencyAdminMe", {
1023
+ enumerable: true,
1024
+ get: function () { return chunkPJRZCOFF_cjs.useAgencyAdminMe; }
1025
+ });
1026
+ Object.defineProperty(exports, "useAgencyChecklistTemplates", {
1027
+ enumerable: true,
1028
+ get: function () { return chunkPJRZCOFF_cjs.useAgencyChecklistTemplates; }
1029
+ });
1030
+ Object.defineProperty(exports, "useAgencyForms", {
1031
+ enumerable: true,
1032
+ get: function () { return chunkPJRZCOFF_cjs.useAgencyForms; }
1033
+ });
1034
+ Object.defineProperty(exports, "useAgencyJourneyTriggers", {
1035
+ enumerable: true,
1036
+ get: function () { return chunkPJRZCOFF_cjs.useAgencyJourneyTriggers; }
1037
+ });
1038
+ Object.defineProperty(exports, "useAgencyManagerProfile", {
1039
+ enumerable: true,
1040
+ get: function () { return chunkPJRZCOFF_cjs.useAgencyManagerProfile; }
1041
+ });
1042
+ Object.defineProperty(exports, "useAgencySettings", {
1043
+ enumerable: true,
1044
+ get: function () { return chunkPJRZCOFF_cjs.useAgencySettings; }
1045
+ });
1046
+ Object.defineProperty(exports, "useAgencyTrip", {
1047
+ enumerable: true,
1048
+ get: function () { return chunkPJRZCOFF_cjs.useAgencyTrip; }
1049
+ });
1050
+ Object.defineProperty(exports, "useAgencyTripManifest", {
1051
+ enumerable: true,
1052
+ get: function () { return chunkPJRZCOFF_cjs.useAgencyTripManifest; }
1053
+ });
1054
+ Object.defineProperty(exports, "useAgencyTrips", {
1055
+ enumerable: true,
1056
+ get: function () { return chunkPJRZCOFF_cjs.useAgencyTrips; }
1057
+ });
1058
+ Object.defineProperty(exports, "useBookings", {
1059
+ enumerable: true,
1060
+ get: function () { return chunkPJRZCOFF_cjs.useBookings; }
1061
+ });
1062
+ Object.defineProperty(exports, "useCapabilityStatuses", {
1063
+ enumerable: true,
1064
+ get: function () { return chunkPJRZCOFF_cjs.useCapabilityStatuses; }
1065
+ });
1066
+ Object.defineProperty(exports, "useDirectories", {
1067
+ enumerable: true,
1068
+ get: function () { return chunkPJRZCOFF_cjs.useDirectories; }
1069
+ });
1070
+ Object.defineProperty(exports, "usePaginatedList", {
1071
+ enumerable: true,
1072
+ get: function () { return chunkPJRZCOFF_cjs.usePaginatedList; }
1073
+ });
1074
+ Object.defineProperty(exports, "useShareLinks", {
1075
+ enumerable: true,
1076
+ get: function () { return chunkPJRZCOFF_cjs.useShareLinks; }
1077
+ });
1078
+ Object.defineProperty(exports, "useTravellerFormResponses", {
1079
+ enumerable: true,
1080
+ get: function () { return chunkPJRZCOFF_cjs.useTravellerFormResponses; }
1081
+ });
1082
+ Object.defineProperty(exports, "ERROR_HANDLING_PATH", {
1083
+ enumerable: true,
1084
+ get: function () { return chunkLL243STJ_cjs.ERROR_HANDLING_PATH; }
1085
+ });
1086
+ Object.defineProperty(exports, "classifyError", {
1087
+ enumerable: true,
1088
+ get: function () { return chunkLL243STJ_cjs.classifyError; }
1089
+ });
1090
+ Object.defineProperty(exports, "useChecklists", {
1091
+ enumerable: true,
1092
+ get: function () { return chunkLL243STJ_cjs.useChecklists; }
1093
+ });
1094
+ Object.defineProperty(exports, "useCloseout", {
1095
+ enumerable: true,
1096
+ get: function () { return chunkLL243STJ_cjs.useCloseout; }
1097
+ });
1098
+ Object.defineProperty(exports, "useCollections", {
1099
+ enumerable: true,
1100
+ get: function () { return chunkLL243STJ_cjs.useCollections; }
1101
+ });
1102
+ Object.defineProperty(exports, "useExpenses", {
1103
+ enumerable: true,
1104
+ get: function () { return chunkLL243STJ_cjs.useExpenses; }
1105
+ });
1106
+ Object.defineProperty(exports, "useFiles", {
1107
+ enumerable: true,
1108
+ get: function () { return chunkLL243STJ_cjs.useFiles; }
1109
+ });
1110
+ Object.defineProperty(exports, "useFloat", {
1111
+ enumerable: true,
1112
+ get: function () { return chunkLL243STJ_cjs.useFloat; }
1113
+ });
1114
+ Object.defineProperty(exports, "useForms", {
1115
+ enumerable: true,
1116
+ get: function () { return chunkLL243STJ_cjs.useForms; }
1117
+ });
1118
+ Object.defineProperty(exports, "useItinerary", {
1119
+ enumerable: true,
1120
+ get: function () { return chunkLL243STJ_cjs.useItinerary; }
1121
+ });
1122
+ Object.defineProperty(exports, "useManagerToday", {
1123
+ enumerable: true,
1124
+ get: function () { return chunkLL243STJ_cjs.useManagerToday; }
1125
+ });
1126
+ Object.defineProperty(exports, "useManagers", {
1127
+ enumerable: true,
1128
+ get: function () { return chunkLL243STJ_cjs.useManagers; }
1129
+ });
1130
+ Object.defineProperty(exports, "useParties", {
1131
+ enumerable: true,
1132
+ get: function () { return chunkLL243STJ_cjs.useParties; }
1133
+ });
1134
+ Object.defineProperty(exports, "usePickups", {
1135
+ enumerable: true,
1136
+ get: function () { return chunkLL243STJ_cjs.usePickups; }
1137
+ });
1138
+ Object.defineProperty(exports, "useRooming", {
1139
+ enumerable: true,
1140
+ get: function () { return chunkLL243STJ_cjs.useRooming; }
1141
+ });
1142
+ Object.defineProperty(exports, "useSeating", {
1143
+ enumerable: true,
1144
+ get: function () { return chunkLL243STJ_cjs.useSeating; }
1145
+ });
1146
+ Object.defineProperty(exports, "useSnapshotList", {
1147
+ enumerable: true,
1148
+ get: function () { return chunkLL243STJ_cjs.useSnapshotList; }
1149
+ });
1150
+ Object.defineProperty(exports, "useTravellerProfile", {
1151
+ enumerable: true,
1152
+ get: function () { return chunkLL243STJ_cjs.useTravellerProfile; }
1153
+ });
1154
+ Object.defineProperty(exports, "useVendors", {
1155
+ enumerable: true,
1156
+ get: function () { return chunkLL243STJ_cjs.useVendors; }
1157
+ });
1158
+ Object.defineProperty(exports, "BrandShell", {
1159
+ enumerable: true,
1160
+ get: function () { return chunkVHTSTUCJ_cjs.BrandShell; }
1161
+ });
1162
+ Object.defineProperty(exports, "useKaafilBrand", {
1163
+ enumerable: true,
1164
+ get: function () { return chunkVHTSTUCJ_cjs.useKaafilBrand; }
1165
+ });
1166
+ Object.defineProperty(exports, "useKaafilShareMeta", {
1167
+ enumerable: true,
1168
+ get: function () { return chunkVHTSTUCJ_cjs.useKaafilShareMeta; }
1169
+ });
1170
+ Object.defineProperty(exports, "useShareForms", {
1171
+ enumerable: true,
1172
+ get: function () { return chunkVHTSTUCJ_cjs.useShareForms; }
1173
+ });
1174
+ Object.defineProperty(exports, "useShareSnapshot", {
1175
+ enumerable: true,
1176
+ get: function () { return chunkVHTSTUCJ_cjs.useShareSnapshot; }
1177
+ });
1178
+ Object.defineProperty(exports, "useOfflineEngine", {
1179
+ enumerable: true,
1180
+ get: function () { return chunkTOBZFADB_cjs.useOfflineEngine; }
1181
+ });
1182
+ Object.defineProperty(exports, "useServerTime", {
1183
+ enumerable: true,
1184
+ get: function () { return chunkPTQ2CJKE_cjs.useServerTime; }
1185
+ });
1186
+ Object.defineProperty(exports, "I18nShell", {
1187
+ enumerable: true,
1188
+ get: function () { return chunkEM7JV3D7_cjs.I18nShell; }
1189
+ });
1190
+ Object.defineProperty(exports, "createRegistry", {
1191
+ enumerable: true,
1192
+ get: function () { return chunkEM7JV3D7_cjs.createRegistry; }
1193
+ });
1194
+ Object.defineProperty(exports, "useCapabilities", {
1195
+ enumerable: true,
1196
+ get: function () { return chunkEM7JV3D7_cjs.useCapabilities; }
1197
+ });
1198
+ Object.defineProperty(exports, "useCapability", {
1199
+ enumerable: true,
1200
+ get: function () { return chunkEM7JV3D7_cjs.useCapability; }
1201
+ });
1202
+ Object.defineProperty(exports, "useKaafilChrome", {
1203
+ enumerable: true,
1204
+ get: function () { return chunkEM7JV3D7_cjs.useKaafilChrome; }
1205
+ });
1206
+ Object.defineProperty(exports, "useKaafilClient", {
1207
+ enumerable: true,
1208
+ get: function () { return chunkEM7JV3D7_cjs.useKaafilClient; }
1209
+ });
1210
+ Object.defineProperty(exports, "useOfflineEvent", {
1211
+ enumerable: true,
1212
+ get: function () { return chunkEM7JV3D7_cjs.useOfflineEvent; }
1213
+ });
1214
+ Object.defineProperty(exports, "useOfflineMutation", {
1215
+ enumerable: true,
1216
+ get: function () { return chunkEM7JV3D7_cjs.useOfflineMutation; }
1217
+ });
1218
+ Object.defineProperty(exports, "useOutboxStatus", {
1219
+ enumerable: true,
1220
+ get: function () { return chunkEM7JV3D7_cjs.useOutboxStatus; }
1221
+ });
1222
+ Object.defineProperty(exports, "usePersona", {
1223
+ enumerable: true,
1224
+ get: function () { return chunkEM7JV3D7_cjs.usePersona; }
1225
+ });
1226
+ Object.defineProperty(exports, "useSession", {
1227
+ enumerable: true,
1228
+ get: function () { return chunkEM7JV3D7_cjs.useSession; }
1229
+ });
1230
+ Object.defineProperty(exports, "UnsatisfiableSchemeError", {
1231
+ enumerable: true,
1232
+ get: function () { return client.UnsatisfiableSchemeError; }
1233
+ });
1234
+ exports.AppShell = AppShell;
1235
+ exports.ConfigShell = ConfigShell;
1236
+ exports.ErrorShell = ErrorShell;
1237
+ exports.HostCssCompatibilityProbe = HostCssCompatibilityProbe;
1238
+ exports.KaafilSessionProbe = KaafilSessionProbe;
1239
+ exports.KaafilUIKitProvider = KaafilUIKitProvider;
1240
+ exports.NotImplementedError = NotImplementedError;
1241
+ exports.OfflineShell = OfflineShell;
1242
+ exports.SessionShell = SessionShell;
1243
+ exports.TelemetryShell = TelemetryShell;
1244
+ exports.ThemeShell = ThemeShell;
1245
+ exports.useBlobStatus = useBlobStatus;
1246
+ exports.useDefaultCapabilityViews = useDefaultCapabilityViews;
1247
+ exports.useFeedbackNps = useFeedbackNps;
1248
+ exports.useJourney = useJourney;
1249
+ exports.useResolvedSetting = useResolvedSetting;
1250
+ exports.useSnapshotEntity = useSnapshotEntity;
1251
+ exports.useStaleness = useStaleness;
1252
+ exports.useTreks = useTreks;
1253
+ //# sourceMappingURL=index.cjs.map
1254
+ //# sourceMappingURL=index.cjs.map